diff options
Diffstat (limited to 'drivers/gpu/drm/arm')
-rw-r--r-- | drivers/gpu/drm/arm/hdlcd_crtc.c | 47 | ||||
-rw-r--r-- | drivers/gpu/drm/arm/malidp_crtc.c | 11 | ||||
-rw-r--r-- | drivers/gpu/drm/arm/malidp_hw.c | 19 | ||||
-rw-r--r-- | drivers/gpu/drm/arm/malidp_planes.c | 12 |
4 files changed, 57 insertions, 32 deletions
diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c index 798a3cc480a2..1a3359c0f6cd 100644 --- a/drivers/gpu/drm/arm/hdlcd_crtc.c +++ b/drivers/gpu/drm/arm/hdlcd_crtc.c @@ -10,6 +10,7 @@ */ #include <drm/drmP.h> +#include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_crtc.h> #include <drm/drm_crtc_helper.h> @@ -226,16 +227,33 @@ static const struct drm_crtc_helper_funcs hdlcd_crtc_helper_funcs = { static int hdlcd_plane_atomic_check(struct drm_plane *plane, struct drm_plane_state *state) { - u32 src_w, src_h; + struct drm_rect clip = { 0 }; + struct drm_crtc_state *crtc_state; + u32 src_h = state->src_h >> 16; - src_w = state->src_w >> 16; - src_h = state->src_h >> 16; + /* only the HDLCD_REG_FB_LINE_COUNT register has a limit */ + if (src_h >= HDLCD_MAX_YRES) { + DRM_DEBUG_KMS("Invalid source width: %d\n", src_h); + return -EINVAL; + } + + if (!state->fb || !state->crtc) + return 0; - /* we can't do any scaling of the plane source */ - if ((src_w != state->crtc_w) || (src_h != state->crtc_h)) + crtc_state = drm_atomic_get_existing_crtc_state(state->state, + state->crtc); + if (!crtc_state) { + DRM_DEBUG_KMS("Invalid crtc state\n"); return -EINVAL; + } - return 0; + clip.x2 = crtc_state->adjusted_mode.hdisplay; + clip.y2 = crtc_state->adjusted_mode.vdisplay; + + return drm_plane_helper_check_state(state, &clip, + DRM_PLANE_HELPER_NO_SCALING, + DRM_PLANE_HELPER_NO_SCALING, + false, true); } static void hdlcd_plane_atomic_update(struct drm_plane *plane, @@ -244,21 +262,20 @@ static void hdlcd_plane_atomic_update(struct drm_plane *plane, struct drm_framebuffer *fb = plane->state->fb; struct hdlcd_drm_private *hdlcd; struct drm_gem_cma_object *gem; - u32 src_w, src_h, dest_w, dest_h; + u32 src_x, src_y, dest_h; dma_addr_t scanout_start; if (!fb) return; - src_w = plane->state->src_w >> 16; - src_h = plane->state->src_h >> 16; - dest_w = plane->state->crtc_w; - dest_h = plane->state->crtc_h; + src_x = plane->state->src.x1 >> 16; + src_y = plane->state->src.y1 >> 16; + dest_h = drm_rect_height(&plane->state->dst); gem = drm_fb_cma_get_gem_obj(fb, 0); + scanout_start = gem->paddr + fb->offsets[0] + - plane->state->crtc_y * fb->pitches[0] + - plane->state->crtc_x * - fb->format->cpp[0]; + src_y * fb->pitches[0] + + src_x * fb->format->cpp[0]; hdlcd = plane->dev->dev_private; hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_LENGTH, fb->pitches[0]); @@ -305,7 +322,6 @@ static struct drm_plane *hdlcd_plane_init(struct drm_device *drm) formats, ARRAY_SIZE(formats), DRM_PLANE_TYPE_PRIMARY, NULL); if (ret) { - devm_kfree(drm->dev, plane); return ERR_PTR(ret); } @@ -329,7 +345,6 @@ int hdlcd_setup_crtc(struct drm_device *drm) &hdlcd_crtc_funcs, NULL); if (ret) { hdlcd_plane_destroy(primary); - devm_kfree(drm->dev, primary); return ret; } diff --git a/drivers/gpu/drm/arm/malidp_crtc.c b/drivers/gpu/drm/arm/malidp_crtc.c index 9446a673d469..4bb38a21efec 100644 --- a/drivers/gpu/drm/arm/malidp_crtc.c +++ b/drivers/gpu/drm/arm/malidp_crtc.c @@ -22,9 +22,8 @@ #include "malidp_drv.h" #include "malidp_hw.h" -static bool malidp_crtc_mode_fixup(struct drm_crtc *crtc, - const struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) +static enum drm_mode_status malidp_crtc_mode_valid(struct drm_crtc *crtc, + const struct drm_display_mode *mode) { struct malidp_drm *malidp = crtc_to_malidp_device(crtc); struct malidp_hw_device *hwdev = malidp->dev; @@ -40,11 +39,11 @@ static bool malidp_crtc_mode_fixup(struct drm_crtc *crtc, if (rate != req_rate) { DRM_DEBUG_DRIVER("pxlclk doesn't support %ld Hz\n", req_rate); - return false; + return MODE_NOCLOCK; } } - return true; + return MODE_OK; } static void malidp_crtc_enable(struct drm_crtc *crtc) @@ -408,7 +407,7 @@ static int malidp_crtc_atomic_check(struct drm_crtc *crtc, } static const struct drm_crtc_helper_funcs malidp_crtc_helper_funcs = { - .mode_fixup = malidp_crtc_mode_fixup, + .mode_valid = malidp_crtc_mode_valid, .enable = malidp_crtc_enable, .disable = malidp_crtc_disable, .atomic_check = malidp_crtc_atomic_check, diff --git a/drivers/gpu/drm/arm/malidp_hw.c b/drivers/gpu/drm/arm/malidp_hw.c index 28360b8542f7..17bca99e8ac8 100644 --- a/drivers/gpu/drm/arm/malidp_hw.c +++ b/drivers/gpu/drm/arm/malidp_hw.c @@ -766,12 +766,17 @@ static irqreturn_t malidp_de_irq(int irq, void *arg) u32 status, mask, dc_status; irqreturn_t ret = IRQ_NONE; - if (!drm->dev_private) - return IRQ_HANDLED; - hwdev = malidp->dev; de = &hwdev->map.de_irq_map; + /* + * if we are suspended it is likely that we were invoked because + * we share an interrupt line with some other driver, don't try + * to read the hardware registers + */ + if (hwdev->pm_suspended) + return IRQ_NONE; + /* first handle the config valid IRQ */ dc_status = malidp_hw_read(hwdev, hwdev->map.dc_base + MALIDP_REG_STATUS); if (dc_status & hwdev->map.dc_irq_map.vsync_irq) { @@ -854,6 +859,14 @@ static irqreturn_t malidp_se_irq(int irq, void *arg) struct malidp_hw_device *hwdev = malidp->dev; u32 status, mask; + /* + * if we are suspended it is likely that we were invoked because + * we share an interrupt line with some other driver, don't try + * to read the hardware registers + */ + if (hwdev->pm_suspended) + return IRQ_NONE; + status = malidp_hw_read(hwdev, hwdev->map.se_base + MALIDP_REG_STATUS); if (!(status & hwdev->map.se_irq_map.irq_mask)) return IRQ_NONE; diff --git a/drivers/gpu/drm/arm/malidp_planes.c b/drivers/gpu/drm/arm/malidp_planes.c index 063a8d2b0be3..600fa7bd7f52 100644 --- a/drivers/gpu/drm/arm/malidp_planes.c +++ b/drivers/gpu/drm/arm/malidp_planes.c @@ -264,11 +264,9 @@ static void malidp_de_set_plane_pitches(struct malidp_plane *mp, static void malidp_de_plane_update(struct drm_plane *plane, struct drm_plane_state *old_state) { - struct drm_gem_cma_object *obj; struct malidp_plane *mp; const struct malidp_hw_regmap *map; struct malidp_plane_state *ms = to_malidp_plane_state(plane->state); - u16 ptr; u32 src_w, src_h, dest_w, dest_h, val; int i; @@ -285,12 +283,12 @@ static void malidp_de_plane_update(struct drm_plane *plane, for (i = 0; i < ms->n_planes; i++) { /* calculate the offset for the layer's plane registers */ - ptr = mp->layer->ptr + (i << 4); + u16 ptr = mp->layer->ptr + (i << 4); + dma_addr_t fb_addr = drm_fb_cma_get_gem_addr(plane->state->fb, + plane->state, i); - obj = drm_fb_cma_get_gem_obj(plane->state->fb, i); - obj->paddr += plane->state->fb->offsets[i]; - malidp_hw_write(mp->hwdev, lower_32_bits(obj->paddr), ptr); - malidp_hw_write(mp->hwdev, upper_32_bits(obj->paddr), ptr + 4); + malidp_hw_write(mp->hwdev, lower_32_bits(fb_addr), ptr); + malidp_hw_write(mp->hwdev, upper_32_bits(fb_addr), ptr + 4); } malidp_de_set_plane_pitches(mp, ms->n_planes, plane->state->fb->pitches); |