diff options
| -rw-r--r-- | drivers/gpu/drm/arm/hdlcd_crtc.c | 47 |
1 files changed, 31 insertions, 16 deletions
diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c index 20ebfb4fbdfa..c65116348281 100644 --- a/drivers/gpu/drm/arm/hdlcd_crtc.c +++ b/drivers/gpu/drm/arm/hdlcd_crtc.c | |||
| @@ -10,6 +10,7 @@ | |||
| 10 | */ | 10 | */ |
| 11 | 11 | ||
| 12 | #include <drm/drmP.h> | 12 | #include <drm/drmP.h> |
| 13 | #include <drm/drm_atomic.h> | ||
| 13 | #include <drm/drm_atomic_helper.h> | 14 | #include <drm/drm_atomic_helper.h> |
| 14 | #include <drm/drm_crtc.h> | 15 | #include <drm/drm_crtc.h> |
| 15 | #include <drm/drm_crtc_helper.h> | 16 | #include <drm/drm_crtc_helper.h> |
| @@ -206,16 +207,33 @@ static const struct drm_crtc_helper_funcs hdlcd_crtc_helper_funcs = { | |||
| 206 | static int hdlcd_plane_atomic_check(struct drm_plane *plane, | 207 | static int hdlcd_plane_atomic_check(struct drm_plane *plane, |
| 207 | struct drm_plane_state *state) | 208 | struct drm_plane_state *state) |
| 208 | { | 209 | { |
| 209 | u32 src_w, src_h; | 210 | struct drm_rect clip = { 0 }; |
| 211 | struct drm_crtc_state *crtc_state; | ||
| 212 | u32 src_h = state->src_h >> 16; | ||
| 210 | 213 | ||
| 211 | src_w = state->src_w >> 16; | 214 | /* only the HDLCD_REG_FB_LINE_COUNT register has a limit */ |
| 212 | src_h = state->src_h >> 16; | 215 | if (src_h >= HDLCD_MAX_YRES) { |
| 216 | DRM_DEBUG_KMS("Invalid source width: %d\n", src_h); | ||
| 217 | return -EINVAL; | ||
| 218 | } | ||
| 219 | |||
| 220 | if (!state->fb || !state->crtc) | ||
| 221 | return 0; | ||
| 213 | 222 | ||
| 214 | /* we can't do any scaling of the plane source */ | 223 | crtc_state = drm_atomic_get_existing_crtc_state(state->state, |
| 215 | if ((src_w != state->crtc_w) || (src_h != state->crtc_h)) | 224 | state->crtc); |
| 225 | if (!crtc_state) { | ||
| 226 | DRM_DEBUG_KMS("Invalid crtc state\n"); | ||
| 216 | return -EINVAL; | 227 | return -EINVAL; |
| 228 | } | ||
| 217 | 229 | ||
| 218 | return 0; | 230 | clip.x2 = crtc_state->adjusted_mode.hdisplay; |
| 231 | clip.y2 = crtc_state->adjusted_mode.vdisplay; | ||
| 232 | |||
| 233 | return drm_plane_helper_check_state(state, &clip, | ||
| 234 | DRM_PLANE_HELPER_NO_SCALING, | ||
| 235 | DRM_PLANE_HELPER_NO_SCALING, | ||
| 236 | false, true); | ||
| 219 | } | 237 | } |
| 220 | 238 | ||
| 221 | static void hdlcd_plane_atomic_update(struct drm_plane *plane, | 239 | static void hdlcd_plane_atomic_update(struct drm_plane *plane, |
| @@ -224,21 +242,20 @@ static void hdlcd_plane_atomic_update(struct drm_plane *plane, | |||
| 224 | struct drm_framebuffer *fb = plane->state->fb; | 242 | struct drm_framebuffer *fb = plane->state->fb; |
| 225 | struct hdlcd_drm_private *hdlcd; | 243 | struct hdlcd_drm_private *hdlcd; |
| 226 | struct drm_gem_cma_object *gem; | 244 | struct drm_gem_cma_object *gem; |
| 227 | u32 src_w, src_h, dest_w, dest_h; | 245 | u32 src_x, src_y, dest_h; |
| 228 | dma_addr_t scanout_start; | 246 | dma_addr_t scanout_start; |
| 229 | 247 | ||
| 230 | if (!fb) | 248 | if (!fb) |
| 231 | return; | 249 | return; |
| 232 | 250 | ||
| 233 | src_w = plane->state->src_w >> 16; | 251 | src_x = plane->state->src.x1 >> 16; |
| 234 | src_h = plane->state->src_h >> 16; | 252 | src_y = plane->state->src.y1 >> 16; |
| 235 | dest_w = plane->state->crtc_w; | 253 | dest_h = drm_rect_height(&plane->state->dst); |
| 236 | dest_h = plane->state->crtc_h; | ||
| 237 | gem = drm_fb_cma_get_gem_obj(fb, 0); | 254 | gem = drm_fb_cma_get_gem_obj(fb, 0); |
| 255 | |||
| 238 | scanout_start = gem->paddr + fb->offsets[0] + | 256 | scanout_start = gem->paddr + fb->offsets[0] + |
| 239 | plane->state->crtc_y * fb->pitches[0] + | 257 | src_y * fb->pitches[0] + |
| 240 | plane->state->crtc_x * | 258 | src_x * fb->format->cpp[0]; |
| 241 | fb->format->cpp[0]; | ||
| 242 | 259 | ||
| 243 | hdlcd = plane->dev->dev_private; | 260 | hdlcd = plane->dev->dev_private; |
| 244 | hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_LENGTH, fb->pitches[0]); | 261 | hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_LENGTH, fb->pitches[0]); |
| @@ -285,7 +302,6 @@ static struct drm_plane *hdlcd_plane_init(struct drm_device *drm) | |||
| 285 | formats, ARRAY_SIZE(formats), | 302 | formats, ARRAY_SIZE(formats), |
| 286 | DRM_PLANE_TYPE_PRIMARY, NULL); | 303 | DRM_PLANE_TYPE_PRIMARY, NULL); |
| 287 | if (ret) { | 304 | if (ret) { |
| 288 | devm_kfree(drm->dev, plane); | ||
| 289 | return ERR_PTR(ret); | 305 | return ERR_PTR(ret); |
| 290 | } | 306 | } |
| 291 | 307 | ||
| @@ -309,7 +325,6 @@ int hdlcd_setup_crtc(struct drm_device *drm) | |||
| 309 | &hdlcd_crtc_funcs, NULL); | 325 | &hdlcd_crtc_funcs, NULL); |
| 310 | if (ret) { | 326 | if (ret) { |
| 311 | hdlcd_plane_destroy(primary); | 327 | hdlcd_plane_destroy(primary); |
| 312 | devm_kfree(drm->dev, primary); | ||
| 313 | return ret; | 328 | return ret; |
| 314 | } | 329 | } |
| 315 | 330 | ||
