diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-09 16:04:31 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-09 16:04:31 -0700 |
| commit | 2e17c5a97e231f3cb426f4b7895eab5be5c5442e (patch) | |
| tree | 80871817427250200d6931a45ccb4833c4add74a /drivers/gpu/drm/drm_rect.c | |
| parent | 5f097cd249f00683442c3e265d6f27d80fc83563 (diff) | |
| parent | 774d8e34e46506222bb5e2888e3ef42b2775715f (diff) | |
Merge branch 'drm-next' of git://people.freedesktop.org/~airlied/linux
Pull drm updates from Dave Airlie:
"Okay this is the big one, I was stalled on the fbdev pull req as I
stupidly let fbdev guys merge a patch I required to fix a warning with
some patches I had, they ended up merging the patch from the wrong
place, but the warning should be fixed. In future I'll just take the
patch myself!
Outside drm:
There are some snd changes for the HDMI audio interactions on haswell,
they've been acked for inclusion via my tree. This relies on the
wound/wait tree from Ingo which is already merged.
Major changes:
AMD finally released the dynamic power management code for all their
GPUs from r600->present day, this is great, off by default for now but
also a huge amount of code, in fact it is most of this pull request.
Since it landed there has been a lot of community testing and Alex has
sent a lot of fixes for any bugs found so far. I suspect radeon might
now be the biggest kernel driver ever :-P p.s. radeon.dpm=1 to enable
dynamic powermanagement for anyone.
New drivers:
Renesas r-car display unit.
Other highlights:
- core: GEM CMA prime support, use new w/w mutexs for TTM
reservations, cursor hotspot, doc updates
- dvo chips: chrontel 7010B support
- i915: Haswell (fbc, ips, vecs, watermarks, audio powerwell),
Valleyview (enabled by default, rc6), lots of pll reworking, 30bpp
support (this time for sure)
- nouveau: async buffer object deletion, context/register init
updates, kernel vp2 engine support, GF117 support, GK110 accel
support (with external nvidia ucode), context cleanups.
- exynos: memory leak fixes, Add S3C64XX SoC series support, device
tree updates, common clock framework support,
- qxl: cursor hotspot support, multi-monitor support, suspend/resume
support
- mgag200: hw cursor support, g200 mode limiting
- shmobile: prime support
- tegra: fixes mostly
I've been banging on this quite a lot due to the size of it, and it
seems to okay on everything I've tested it on."
* 'drm-next' of git://people.freedesktop.org/~airlied/linux: (811 commits)
drm/radeon/dpm: implement vblank_too_short callback for si
drm/radeon/dpm: implement vblank_too_short callback for cayman
drm/radeon/dpm: implement vblank_too_short callback for btc
drm/radeon/dpm: implement vblank_too_short callback for evergreen
drm/radeon/dpm: implement vblank_too_short callback for 7xx
drm/radeon/dpm: add checks against vblank time
drm/radeon/dpm: add helper to calculate vblank time
drm/radeon: remove stray line in old pm code
drm/radeon/dpm: fix display_gap programming on rv7xx
drm/nvc0/gr: fix gpc firmware regression
drm/nouveau: fix minor thinko causing bo moves to not be async on kepler
drm/radeon/dpm: implement force performance level for TN
drm/radeon/dpm: implement force performance level for ON/LN
drm/radeon/dpm: implement force performance level for SI
drm/radeon/dpm: implement force performance level for cayman
drm/radeon/dpm: implement force performance levels for 7xx/eg/btc
drm/radeon/dpm: add infrastructure to force performance levels
drm/radeon: fix surface setup on r1xx
drm/radeon: add support for 3d perf states on older asics
drm/radeon: set default clocks for SI when DPM is disabled
...
Diffstat (limited to 'drivers/gpu/drm/drm_rect.c')
| -rw-r--r-- | drivers/gpu/drm/drm_rect.c | 295 |
1 files changed, 295 insertions, 0 deletions
diff --git a/drivers/gpu/drm/drm_rect.c b/drivers/gpu/drm/drm_rect.c new file mode 100644 index 000000000000..7047ca025787 --- /dev/null +++ b/drivers/gpu/drm/drm_rect.c @@ -0,0 +1,295 @@ +/* + * Copyright (C) 2011-2013 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include <linux/errno.h> +#include <linux/export.h> +#include <linux/kernel.h> +#include <drm/drmP.h> +#include <drm/drm_rect.h> + +/** + * drm_rect_intersect - intersect two rectangles + * @r1: first rectangle + * @r2: second rectangle + * + * Calculate the intersection of rectangles @r1 and @r2. + * @r1 will be overwritten with the intersection. + * + * RETURNS: + * %true if rectangle @r1 is still visible after the operation, + * %false otherwise. + */ +bool drm_rect_intersect(struct drm_rect *r1, const struct drm_rect *r2) +{ + r1->x1 = max(r1->x1, r2->x1); + r1->y1 = max(r1->y1, r2->y1); + r1->x2 = min(r1->x2, r2->x2); + r1->y2 = min(r1->y2, r2->y2); + + return drm_rect_visible(r1); +} +EXPORT_SYMBOL(drm_rect_intersect); + +/** + * drm_rect_clip_scaled - perform a scaled clip operation + * @src: source window rectangle + * @dst: destination window rectangle + * @clip: clip rectangle + * @hscale: horizontal scaling factor + * @vscale: vertical scaling factor + * + * Clip rectangle @dst by rectangle @clip. Clip rectangle @src by the + * same amounts multiplied by @hscale and @vscale. + * + * RETURNS: + * %true if rectangle @dst is still visible after being clipped, + * %false otherwise + */ +bool drm_rect_clip_scaled(struct drm_rect *src, struct drm_rect *dst, + const struct drm_rect *clip, + int hscale, int vscale) +{ + int diff; + + diff = clip->x1 - dst->x1; + if (diff > 0) { + int64_t tmp = src->x1 + (int64_t) diff * hscale; + src->x1 = clamp_t(int64_t, tmp, INT_MIN, INT_MAX); + } + diff = clip->y1 - dst->y1; + if (diff > 0) { + int64_t tmp = src->y1 + (int64_t) diff * vscale; + src->y1 = clamp_t(int64_t, tmp, INT_MIN, INT_MAX); + } + diff = dst->x2 - clip->x2; + if (diff > 0) { + int64_t tmp = src->x2 - (int64_t) diff * hscale; + src->x2 = clamp_t(int64_t, tmp, INT_MIN, INT_MAX); + } + diff = dst->y2 - clip->y2; + if (diff > 0) { + int64_t tmp = src->y2 - (int64_t) diff * vscale; + src->y2 = clamp_t(int64_t, tmp, INT_MIN, INT_MAX); + } + + return drm_rect_intersect(dst, clip); +} +EXPORT_SYMBOL(drm_rect_clip_scaled); + +static int drm_calc_scale(int src, int dst) +{ + int scale = 0; + + if (src < 0 || dst < 0) + return -EINVAL; + + if (dst == 0) + return 0; + + scale = src / dst; + + return scale; +} + +/** + * drm_rect_calc_hscale - calculate the horizontal scaling factor + * @src: source window rectangle + * @dst: destination window rectangle + * @min_hscale: minimum allowed horizontal scaling factor + * @max_hscale: maximum allowed horizontal scaling factor + * + * Calculate the horizontal scaling factor as + * (@src width) / (@dst width). + * + * RETURNS: + * The horizontal scaling factor, or errno of out of limits. + */ +int drm_rect_calc_hscale(const struct drm_rect *src, + const struct drm_rect *dst, + int min_hscale, int max_hscale) +{ + int src_w = drm_rect_width(src); + int dst_w = drm_rect_width(dst); + int hscale = drm_calc_scale(src_w, dst_w); + + if (hscale < 0 || dst_w == 0) + return hscale; + + if (hscale < min_hscale || hscale > max_hscale) + return -ERANGE; + + return hscale; +} +EXPORT_SYMBOL(drm_rect_calc_hscale); + +/** + * drm_rect_calc_vscale - calculate the vertical scaling factor + * @src: source window rectangle + * @dst: destination window rectangle + * @min_vscale: minimum allowed vertical scaling factor + * @max_vscale: maximum allowed vertical scaling factor + * + * Calculate the vertical scaling factor as + * (@src height) / (@dst height). + * + * RETURNS: + * The vertical scaling factor, or errno of out of limits. + */ +int drm_rect_calc_vscale(const struct drm_rect *src, + const struct drm_rect *dst, + int min_vscale, int max_vscale) +{ + int src_h = drm_rect_height(src); + int dst_h = drm_rect_height(dst); + int vscale = drm_calc_scale(src_h, dst_h); + + if (vscale < 0 || dst_h == 0) + return vscale; + + if (vscale < min_vscale || vscale > max_vscale) + return -ERANGE; + + return vscale; +} +EXPORT_SYMBOL(drm_rect_calc_vscale); + +/** + * drm_calc_hscale_relaxed - calculate the horizontal scaling factor + * @src: source window rectangle + * @dst: destination window rectangle + * @min_hscale: minimum allowed horizontal scaling factor + * @max_hscale: maximum allowed horizontal scaling factor + * + * Calculate the horizontal scaling factor as + * (@src width) / (@dst width). + * + * If the calculated scaling factor is below @min_vscale, + * decrease the height of rectangle @dst to compensate. + * + * If the calculated scaling factor is above @max_vscale, + * decrease the height of rectangle @src to compensate. + * + * RETURNS: + * The horizontal scaling factor. + */ +int drm_rect_calc_hscale_relaxed(struct drm_rect *src, + struct drm_rect *dst, + int min_hscale, int max_hscale) +{ + int src_w = drm_rect_width(src); + int dst_w = drm_rect_width(dst); + int hscale = drm_calc_scale(src_w, dst_w); + + if (hscale < 0 || dst_w == 0) + return hscale; + + if (hscale < min_hscale) { + int max_dst_w = src_w / min_hscale; + + drm_rect_adjust_size(dst, max_dst_w - dst_w, 0); + + return min_hscale; + } + + if (hscale > max_hscale) { + int max_src_w = dst_w * max_hscale; + + drm_rect_adjust_size(src, max_src_w - src_w, 0); + + return max_hscale; + } + + return hscale; +} +EXPORT_SYMBOL(drm_rect_calc_hscale_relaxed); + +/** + * drm_rect_calc_vscale_relaxed - calculate the vertical scaling factor + * @src: source window rectangle + * @dst: destination window rectangle + * @min_vscale: minimum allowed vertical scaling factor + * @max_vscale: maximum allowed vertical scaling factor + * + * Calculate the vertical scaling factor as + * (@src height) / (@dst height). + * + * If the calculated scaling factor is below @min_vscale, + * decrease the height of rectangle @dst to compensate. + * + * If the calculated scaling factor is above @max_vscale, + * decrease the height of rectangle @src to compensate. + * + * RETURNS: + * The vertical scaling factor. + */ +int drm_rect_calc_vscale_relaxed(struct drm_rect *src, + struct drm_rect *dst, + int min_vscale, int max_vscale) +{ + int src_h = drm_rect_height(src); + int dst_h = drm_rect_height(dst); + int vscale = drm_calc_scale(src_h, dst_h); + + if (vscale < 0 || dst_h == 0) + return vscale; + + if (vscale < min_vscale) { + int max_dst_h = src_h / min_vscale; + + drm_rect_adjust_size(dst, 0, max_dst_h - dst_h); + + return min_vscale; + } + + if (vscale > max_vscale) { + int max_src_h = dst_h * max_vscale; + + drm_rect_adjust_size(src, 0, max_src_h - src_h); + + return max_vscale; + } + + return vscale; +} +EXPORT_SYMBOL(drm_rect_calc_vscale_relaxed); + +/** + * drm_rect_debug_print - print the rectangle information + * @r: rectangle to print + * @fixed_point: rectangle is in 16.16 fixed point format + */ +void drm_rect_debug_print(const struct drm_rect *r, bool fixed_point) +{ + int w = drm_rect_width(r); + int h = drm_rect_height(r); + + if (fixed_point) + DRM_DEBUG_KMS("%d.%06ux%d.%06u%+d.%06u%+d.%06u\n", + w >> 16, ((w & 0xffff) * 15625) >> 10, + h >> 16, ((h & 0xffff) * 15625) >> 10, + r->x1 >> 16, ((r->x1 & 0xffff) * 15625) >> 10, + r->y1 >> 16, ((r->y1 & 0xffff) * 15625) >> 10); + else + DRM_DEBUG_KMS("%dx%d%+d%+d\n", w, h, r->x1, r->y1); +} +EXPORT_SYMBOL(drm_rect_debug_print); |
