diff options
author | Ingo Molnar <mingo@kernel.org> | 2017-09-04 12:01:18 +0300 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2017-09-04 12:01:18 +0300 |
commit | edc2988c548db05e33b921fed15821010bc74895 (patch) | |
tree | b35860428acea35e5866d4cf007519ed943a85de /drivers/gpu/drm/nouveau/dispnv04 | |
parent | d82fed75294229abc9d757f08a4817febae6c4f4 (diff) | |
parent | 81a84ad3cb5711cec79f4dd53a4ce026b092c432 (diff) | |
download | linux-edc2988c548db05e33b921fed15821010bc74895.tar.xz |
Merge branch 'linus' into locking/core, to fix up conflicts
Conflicts:
mm/page_alloc.c
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'drivers/gpu/drm/nouveau/dispnv04')
-rw-r--r-- | drivers/gpu/drm/nouveau/dispnv04/crtc.c | 62 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/dispnv04/overlay.c | 71 |
2 files changed, 84 insertions, 49 deletions
diff --git a/drivers/gpu/drm/nouveau/dispnv04/crtc.c b/drivers/gpu/drm/nouveau/dispnv04/crtc.c index 4b4b0b496262..6aa6ee16dcbd 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/crtc.c +++ b/drivers/gpu/drm/nouveau/dispnv04/crtc.c @@ -764,13 +764,18 @@ nv_crtc_gamma_load(struct drm_crtc *crtc) struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); struct drm_device *dev = nv_crtc->base.dev; struct rgb { uint8_t r, g, b; } __attribute__((packed)) *rgbs; + u16 *r, *g, *b; int i; rgbs = (struct rgb *)nv04_display(dev)->mode_reg.crtc_reg[nv_crtc->index].DAC; + r = crtc->gamma_store; + g = r + crtc->gamma_size; + b = g + crtc->gamma_size; + for (i = 0; i < 256; i++) { - rgbs[i].r = nv_crtc->lut.r[i] >> 8; - rgbs[i].g = nv_crtc->lut.g[i] >> 8; - rgbs[i].b = nv_crtc->lut.b[i] >> 8; + rgbs[i].r = *r++ >> 8; + rgbs[i].g = *g++ >> 8; + rgbs[i].b = *b++ >> 8; } nouveau_hw_load_state_palette(dev, nv_crtc->index, &nv04_display(dev)->mode_reg); @@ -792,13 +797,6 @@ nv_crtc_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b, struct drm_modeset_acquire_ctx *ctx) { struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - int i; - - for (i = 0; i < size; i++) { - nv_crtc->lut.r[i] = r[i]; - nv_crtc->lut.g[i] = g[i]; - nv_crtc->lut.b[i] = b[i]; - } /* We need to know the depth before we upload, but it's possible to * get called before a framebuffer is bound. If this is the case, @@ -1095,25 +1093,51 @@ static const struct drm_crtc_helper_funcs nv04_crtc_helper_funcs = { .mode_set = nv_crtc_mode_set, .mode_set_base = nv04_crtc_mode_set_base, .mode_set_base_atomic = nv04_crtc_mode_set_base_atomic, - .load_lut = nv_crtc_gamma_load, .disable = nv_crtc_disable, }; +static const uint32_t modeset_formats[] = { + DRM_FORMAT_XRGB8888, + DRM_FORMAT_RGB565, + DRM_FORMAT_XRGB1555, +}; + +static struct drm_plane * +create_primary_plane(struct drm_device *dev) +{ + struct drm_plane *primary; + int ret; + + primary = kzalloc(sizeof(*primary), GFP_KERNEL); + if (primary == NULL) { + DRM_DEBUG_KMS("Failed to allocate primary plane\n"); + return NULL; + } + + /* possible_crtc's will be filled in later by crtc_init */ + ret = drm_universal_plane_init(dev, primary, 0, + &drm_primary_helper_funcs, + modeset_formats, + ARRAY_SIZE(modeset_formats), NULL, + DRM_PLANE_TYPE_PRIMARY, NULL); + if (ret) { + kfree(primary); + primary = NULL; + } + + return primary; +} + int nv04_crtc_create(struct drm_device *dev, int crtc_num) { struct nouveau_crtc *nv_crtc; - int ret, i; + int ret; nv_crtc = kzalloc(sizeof(*nv_crtc), GFP_KERNEL); if (!nv_crtc) return -ENOMEM; - for (i = 0; i < 256; i++) { - nv_crtc->lut.r[i] = i << 8; - nv_crtc->lut.g[i] = i << 8; - nv_crtc->lut.b[i] = i << 8; - } nv_crtc->lut.depth = 0; nv_crtc->index = crtc_num; @@ -1122,7 +1146,9 @@ nv04_crtc_create(struct drm_device *dev, int crtc_num) nv_crtc->save = nv_crtc_save; nv_crtc->restore = nv_crtc_restore; - drm_crtc_init(dev, &nv_crtc->base, &nv04_crtc_funcs); + drm_crtc_init_with_planes(dev, &nv_crtc->base, + create_primary_plane(dev), NULL, + &nv04_crtc_funcs, NULL); drm_crtc_helper_add(&nv_crtc->base, &nv04_crtc_helper_funcs); drm_mode_crtc_set_gamma_size(&nv_crtc->base, 256); diff --git a/drivers/gpu/drm/nouveau/dispnv04/overlay.c b/drivers/gpu/drm/nouveau/dispnv04/overlay.c index e54944d23268..c8c2333f24ee 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/overlay.c +++ b/drivers/gpu/drm/nouveau/dispnv04/overlay.c @@ -63,6 +63,7 @@ static uint32_t formats[] = { DRM_FORMAT_YUYV, DRM_FORMAT_UYVY, DRM_FORMAT_NV12, + DRM_FORMAT_NV21, }; /* Sine can be approximated with @@ -90,6 +91,26 @@ cos_mul(int degrees, int factor) } static int +verify_scaling(const struct drm_framebuffer *fb, uint8_t shift, + uint32_t src_x, uint32_t src_y, uint32_t src_w, uint32_t src_h, + uint32_t crtc_w, uint32_t crtc_h) +{ + if (crtc_w < (src_w >> shift) || crtc_h < (src_h >> shift)) { + DRM_DEBUG_KMS("Unsuitable framebuffer scaling: %dx%d -> %dx%d\n", + src_w, src_h, crtc_w, crtc_h); + return -ERANGE; + } + + if (src_x != 0 || src_y != 0) { + DRM_DEBUG_KMS("Unsuitable framebuffer offset: %d,%d\n", + src_x, src_y); + return -ERANGE; + } + + return 0; +} + +static int nv10_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, struct drm_framebuffer *fb, int crtc_x, int crtc_y, unsigned int crtc_w, unsigned int crtc_h, @@ -107,7 +128,9 @@ nv10_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, bool flip = nv_plane->flip; int soff = NV_PCRTC0_SIZE * nv_crtc->index; int soff2 = NV_PCRTC0_SIZE * !nv_crtc->index; - int format, ret; + unsigned shift = drm->client.device.info.chipset >= 0x30 ? 1 : 3; + unsigned format = 0; + int ret; /* Source parameters given in 16.16 fixed point, ignore fractional. */ src_x >>= 16; @@ -115,18 +138,9 @@ nv10_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, src_w >>= 16; src_h >>= 16; - format = ALIGN(src_w * 4, 0x100); - - if (format > 0xffff) - return -ERANGE; - - if (drm->client.device.info.chipset >= 0x30) { - if (crtc_w < (src_w >> 1) || crtc_h < (src_h >> 1)) - return -ERANGE; - } else { - if (crtc_w < (src_w >> 3) || crtc_h < (src_h >> 3)) - return -ERANGE; - } + ret = verify_scaling(fb, shift, 0, 0, src_w, src_h, crtc_w, crtc_h); + if (ret) + return ret; ret = nouveau_bo_pin(nv_fb->nvbo, TTM_PL_FLAG_VRAM, false); if (ret) @@ -146,21 +160,23 @@ nv10_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, nvif_wr32(dev, NV_PVIDEO_POINT_OUT(flip), crtc_y << 16 | crtc_x); nvif_wr32(dev, NV_PVIDEO_SIZE_OUT(flip), crtc_h << 16 | crtc_w); - if (fb->format->format != DRM_FORMAT_UYVY) + if (fb->format->format == DRM_FORMAT_YUYV || + fb->format->format == DRM_FORMAT_NV12) format |= NV_PVIDEO_FORMAT_COLOR_LE_CR8YB8CB8YA8; - if (fb->format->format == DRM_FORMAT_NV12) + if (fb->format->format == DRM_FORMAT_NV12 || + fb->format->format == DRM_FORMAT_NV21) format |= NV_PVIDEO_FORMAT_PLANAR; if (nv_plane->iturbt_709) format |= NV_PVIDEO_FORMAT_MATRIX_ITURBT709; if (nv_plane->colorkey & (1 << 24)) format |= NV_PVIDEO_FORMAT_DISPLAY_COLOR_KEY; - if (fb->format->format == DRM_FORMAT_NV12) { + if (format & NV_PVIDEO_FORMAT_PLANAR) { nvif_wr32(dev, NV_PVIDEO_UVPLANE_BASE(flip), 0); nvif_wr32(dev, NV_PVIDEO_UVPLANE_OFFSET_BUFF(flip), nv_fb->nvbo->bo.offset + fb->offsets[1]); } - nvif_wr32(dev, NV_PVIDEO_FORMAT(flip), format); + nvif_wr32(dev, NV_PVIDEO_FORMAT(flip), format | fb->pitches[0]); nvif_wr32(dev, NV_PVIDEO_STOP, 0); /* TODO: wait for vblank? */ nvif_wr32(dev, NV_PVIDEO_BUFFER, flip ? 0x10 : 0x1); @@ -357,7 +373,7 @@ nv04_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, struct nouveau_bo *cur = nv_plane->cur; uint32_t overlay = 1; int brightness = (nv_plane->brightness - 512) * 62 / 512; - int pitch, ret, i; + int ret, i; /* Source parameters given in 16.16 fixed point, ignore fractional. */ src_x >>= 16; @@ -365,17 +381,9 @@ nv04_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, src_w >>= 16; src_h >>= 16; - pitch = ALIGN(src_w * 4, 0x100); - - if (pitch > 0xffff) - return -ERANGE; - - /* TODO: Compute an offset? Not sure how to do this for YUYV. */ - if (src_x != 0 || src_y != 0) - return -ERANGE; - - if (crtc_w < src_w || crtc_h < src_h) - return -ERANGE; + ret = verify_scaling(fb, 0, src_x, src_y, src_w, src_h, crtc_w, crtc_h); + if (ret) + return ret; ret = nouveau_bo_pin(nv_fb->nvbo, TTM_PL_FLAG_VRAM, false); if (ret) @@ -389,8 +397,9 @@ nv04_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, for (i = 0; i < 2; i++) { nvif_wr32(dev, NV_PVIDEO_BUFF0_START_ADDRESS + 4 * i, - nv_fb->nvbo->bo.offset); - nvif_wr32(dev, NV_PVIDEO_BUFF0_PITCH_LENGTH + 4 * i, pitch); + nv_fb->nvbo->bo.offset); + nvif_wr32(dev, NV_PVIDEO_BUFF0_PITCH_LENGTH + 4 * i, + fb->pitches[0]); nvif_wr32(dev, NV_PVIDEO_BUFF0_OFFSET + 4 * i, 0); } nvif_wr32(dev, NV_PVIDEO_WINDOW_START, crtc_y << 16 | crtc_x); |