diff options
| author | Dave Airlie <airlied@redhat.com> | 2016-06-08 21:01:49 -0400 |
|---|---|---|
| committer | Dave Airlie <airlied@redhat.com> | 2016-06-08 21:01:49 -0400 |
| commit | fa625c1956830c826ebf13324c2b33fcabef7db0 (patch) | |
| tree | 92c7f1272617c5c6a82478ba161af97eae0260cd /drivers/gpu/drm/arm | |
| parent | 66fd7a66e8b9e11e49f46ea77910f935c4dee5c3 (diff) | |
| parent | af8c34ce6ae32addda3788d54a7e340cad22516b (diff) | |
Backmerge tag 'v4.7-rc2' into drm-next
Daniel has a pull request that relies on stuff in fixes that are in rc2.
Diffstat (limited to 'drivers/gpu/drm/arm')
| -rw-r--r-- | drivers/gpu/drm/arm/hdlcd_crtc.c | 86 | ||||
| -rw-r--r-- | drivers/gpu/drm/arm/hdlcd_drv.c | 68 | ||||
| -rw-r--r-- | drivers/gpu/drm/arm/hdlcd_drv.h | 5 |
3 files changed, 78 insertions, 81 deletions
diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c index fef1b04c2aab..0813c2f06931 100644 --- a/drivers/gpu/drm/arm/hdlcd_crtc.c +++ b/drivers/gpu/drm/arm/hdlcd_crtc.c | |||
| @@ -33,8 +33,17 @@ | |||
| 33 | * | 33 | * |
| 34 | */ | 34 | */ |
| 35 | 35 | ||
| 36 | static void hdlcd_crtc_cleanup(struct drm_crtc *crtc) | ||
| 37 | { | ||
| 38 | struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc); | ||
| 39 | |||
| 40 | /* stop the controller on cleanup */ | ||
| 41 | hdlcd_write(hdlcd, HDLCD_REG_COMMAND, 0); | ||
| 42 | drm_crtc_cleanup(crtc); | ||
| 43 | } | ||
| 44 | |||
| 36 | static const struct drm_crtc_funcs hdlcd_crtc_funcs = { | 45 | static const struct drm_crtc_funcs hdlcd_crtc_funcs = { |
| 37 | .destroy = drm_crtc_cleanup, | 46 | .destroy = hdlcd_crtc_cleanup, |
| 38 | .set_config = drm_atomic_helper_set_config, | 47 | .set_config = drm_atomic_helper_set_config, |
| 39 | .page_flip = drm_atomic_helper_page_flip, | 48 | .page_flip = drm_atomic_helper_page_flip, |
| 40 | .reset = drm_atomic_helper_crtc_reset, | 49 | .reset = drm_atomic_helper_crtc_reset, |
| @@ -97,7 +106,7 @@ static void hdlcd_crtc_mode_set_nofb(struct drm_crtc *crtc) | |||
| 97 | struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc); | 106 | struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc); |
| 98 | struct drm_display_mode *m = &crtc->state->adjusted_mode; | 107 | struct drm_display_mode *m = &crtc->state->adjusted_mode; |
| 99 | struct videomode vm; | 108 | struct videomode vm; |
| 100 | unsigned int polarities, line_length, err; | 109 | unsigned int polarities, err; |
| 101 | 110 | ||
| 102 | vm.vfront_porch = m->crtc_vsync_start - m->crtc_vdisplay; | 111 | vm.vfront_porch = m->crtc_vsync_start - m->crtc_vdisplay; |
| 103 | vm.vback_porch = m->crtc_vtotal - m->crtc_vsync_end; | 112 | vm.vback_porch = m->crtc_vtotal - m->crtc_vsync_end; |
| @@ -113,23 +122,18 @@ static void hdlcd_crtc_mode_set_nofb(struct drm_crtc *crtc) | |||
| 113 | if (m->flags & DRM_MODE_FLAG_PVSYNC) | 122 | if (m->flags & DRM_MODE_FLAG_PVSYNC) |
| 114 | polarities |= HDLCD_POLARITY_VSYNC; | 123 | polarities |= HDLCD_POLARITY_VSYNC; |
| 115 | 124 | ||
| 116 | line_length = crtc->primary->state->fb->pitches[0]; | ||
| 117 | |||
| 118 | /* Allow max number of outstanding requests and largest burst size */ | 125 | /* Allow max number of outstanding requests and largest burst size */ |
| 119 | hdlcd_write(hdlcd, HDLCD_REG_BUS_OPTIONS, | 126 | hdlcd_write(hdlcd, HDLCD_REG_BUS_OPTIONS, |
| 120 | HDLCD_BUS_MAX_OUTSTAND | HDLCD_BUS_BURST_16); | 127 | HDLCD_BUS_MAX_OUTSTAND | HDLCD_BUS_BURST_16); |
| 121 | 128 | ||
| 122 | hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_LENGTH, line_length); | ||
| 123 | hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_PITCH, line_length); | ||
| 124 | hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_COUNT, m->crtc_vdisplay - 1); | ||
| 125 | hdlcd_write(hdlcd, HDLCD_REG_V_DATA, m->crtc_vdisplay - 1); | 129 | hdlcd_write(hdlcd, HDLCD_REG_V_DATA, m->crtc_vdisplay - 1); |
| 126 | hdlcd_write(hdlcd, HDLCD_REG_V_BACK_PORCH, vm.vback_porch - 1); | 130 | hdlcd_write(hdlcd, HDLCD_REG_V_BACK_PORCH, vm.vback_porch - 1); |
| 127 | hdlcd_write(hdlcd, HDLCD_REG_V_FRONT_PORCH, vm.vfront_porch - 1); | 131 | hdlcd_write(hdlcd, HDLCD_REG_V_FRONT_PORCH, vm.vfront_porch - 1); |
| 128 | hdlcd_write(hdlcd, HDLCD_REG_V_SYNC, vm.vsync_len - 1); | 132 | hdlcd_write(hdlcd, HDLCD_REG_V_SYNC, vm.vsync_len - 1); |
| 133 | hdlcd_write(hdlcd, HDLCD_REG_H_DATA, m->crtc_hdisplay - 1); | ||
| 129 | hdlcd_write(hdlcd, HDLCD_REG_H_BACK_PORCH, vm.hback_porch - 1); | 134 | hdlcd_write(hdlcd, HDLCD_REG_H_BACK_PORCH, vm.hback_porch - 1); |
| 130 | hdlcd_write(hdlcd, HDLCD_REG_H_FRONT_PORCH, vm.hfront_porch - 1); | 135 | hdlcd_write(hdlcd, HDLCD_REG_H_FRONT_PORCH, vm.hfront_porch - 1); |
| 131 | hdlcd_write(hdlcd, HDLCD_REG_H_SYNC, vm.hsync_len - 1); | 136 | hdlcd_write(hdlcd, HDLCD_REG_H_SYNC, vm.hsync_len - 1); |
| 132 | hdlcd_write(hdlcd, HDLCD_REG_H_DATA, m->crtc_hdisplay - 1); | ||
| 133 | hdlcd_write(hdlcd, HDLCD_REG_POLARITIES, polarities); | 137 | hdlcd_write(hdlcd, HDLCD_REG_POLARITIES, polarities); |
| 134 | 138 | ||
| 135 | err = hdlcd_set_pxl_fmt(crtc); | 139 | err = hdlcd_set_pxl_fmt(crtc); |
| @@ -144,20 +148,19 @@ static void hdlcd_crtc_enable(struct drm_crtc *crtc) | |||
| 144 | struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc); | 148 | struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc); |
| 145 | 149 | ||
| 146 | clk_prepare_enable(hdlcd->clk); | 150 | clk_prepare_enable(hdlcd->clk); |
| 151 | hdlcd_crtc_mode_set_nofb(crtc); | ||
| 147 | hdlcd_write(hdlcd, HDLCD_REG_COMMAND, 1); | 152 | hdlcd_write(hdlcd, HDLCD_REG_COMMAND, 1); |
| 148 | drm_crtc_vblank_on(crtc); | ||
| 149 | } | 153 | } |
| 150 | 154 | ||
| 151 | static void hdlcd_crtc_disable(struct drm_crtc *crtc) | 155 | static void hdlcd_crtc_disable(struct drm_crtc *crtc) |
| 152 | { | 156 | { |
| 153 | struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc); | 157 | struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc); |
| 154 | 158 | ||
| 155 | if (!crtc->primary->fb) | 159 | if (!crtc->state->active) |
| 156 | return; | 160 | return; |
| 157 | 161 | ||
| 158 | clk_disable_unprepare(hdlcd->clk); | ||
| 159 | hdlcd_write(hdlcd, HDLCD_REG_COMMAND, 0); | 162 | hdlcd_write(hdlcd, HDLCD_REG_COMMAND, 0); |
| 160 | drm_crtc_vblank_off(crtc); | 163 | clk_disable_unprepare(hdlcd->clk); |
| 161 | } | 164 | } |
| 162 | 165 | ||
| 163 | static int hdlcd_crtc_atomic_check(struct drm_crtc *crtc, | 166 | static int hdlcd_crtc_atomic_check(struct drm_crtc *crtc, |
| @@ -179,20 +182,17 @@ static int hdlcd_crtc_atomic_check(struct drm_crtc *crtc, | |||
| 179 | static void hdlcd_crtc_atomic_begin(struct drm_crtc *crtc, | 182 | static void hdlcd_crtc_atomic_begin(struct drm_crtc *crtc, |
| 180 | struct drm_crtc_state *state) | 183 | struct drm_crtc_state *state) |
| 181 | { | 184 | { |
| 182 | struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc); | 185 | struct drm_pending_vblank_event *event = crtc->state->event; |
| 183 | unsigned long flags; | ||
| 184 | |||
| 185 | if (crtc->state->event) { | ||
| 186 | struct drm_pending_vblank_event *event = crtc->state->event; | ||
| 187 | 186 | ||
| 187 | if (event) { | ||
| 188 | crtc->state->event = NULL; | 188 | crtc->state->event = NULL; |
| 189 | event->pipe = drm_crtc_index(crtc); | ||
| 190 | |||
| 191 | WARN_ON(drm_crtc_vblank_get(crtc) != 0); | ||
| 192 | 189 | ||
| 193 | spin_lock_irqsave(&crtc->dev->event_lock, flags); | 190 | spin_lock_irq(&crtc->dev->event_lock); |
| 194 | list_add_tail(&event->base.link, &hdlcd->event_list); | 191 | if (drm_crtc_vblank_get(crtc) == 0) |
| 195 | spin_unlock_irqrestore(&crtc->dev->event_lock, flags); | 192 | drm_crtc_arm_vblank_event(crtc, event); |
| 193 | else | ||
| 194 | drm_crtc_send_vblank_event(crtc, event); | ||
| 195 | spin_unlock_irq(&crtc->dev->event_lock); | ||
| 196 | } | 196 | } |
| 197 | } | 197 | } |
| 198 | 198 | ||
| @@ -225,6 +225,15 @@ static const struct drm_crtc_helper_funcs hdlcd_crtc_helper_funcs = { | |||
| 225 | static int hdlcd_plane_atomic_check(struct drm_plane *plane, | 225 | static int hdlcd_plane_atomic_check(struct drm_plane *plane, |
| 226 | struct drm_plane_state *state) | 226 | struct drm_plane_state *state) |
| 227 | { | 227 | { |
| 228 | u32 src_w, src_h; | ||
| 229 | |||
| 230 | src_w = state->src_w >> 16; | ||
| 231 | src_h = state->src_h >> 16; | ||
| 232 | |||
| 233 | /* we can't do any scaling of the plane source */ | ||
| 234 | if ((src_w != state->crtc_w) || (src_h != state->crtc_h)) | ||
| 235 | return -EINVAL; | ||
| 236 | |||
| 228 | return 0; | 237 | return 0; |
| 229 | } | 238 | } |
| 230 | 239 | ||
| @@ -233,20 +242,31 @@ static void hdlcd_plane_atomic_update(struct drm_plane *plane, | |||
| 233 | { | 242 | { |
| 234 | struct hdlcd_drm_private *hdlcd; | 243 | struct hdlcd_drm_private *hdlcd; |
| 235 | struct drm_gem_cma_object *gem; | 244 | struct drm_gem_cma_object *gem; |
| 245 | unsigned int depth, bpp; | ||
| 246 | u32 src_w, src_h, dest_w, dest_h; | ||
| 236 | dma_addr_t scanout_start; | 247 | dma_addr_t scanout_start; |
| 237 | 248 | ||
| 238 | if (!plane->state->crtc || !plane->state->fb) | 249 | if (!plane->state->fb) |
| 239 | return; | 250 | return; |
| 240 | 251 | ||
| 241 | hdlcd = crtc_to_hdlcd_priv(plane->state->crtc); | 252 | drm_fb_get_bpp_depth(plane->state->fb->pixel_format, &depth, &bpp); |
| 253 | src_w = plane->state->src_w >> 16; | ||
| 254 | src_h = plane->state->src_h >> 16; | ||
| 255 | dest_w = plane->state->crtc_w; | ||
| 256 | dest_h = plane->state->crtc_h; | ||
| 242 | gem = drm_fb_cma_get_gem_obj(plane->state->fb, 0); | 257 | gem = drm_fb_cma_get_gem_obj(plane->state->fb, 0); |
| 243 | scanout_start = gem->paddr; | 258 | scanout_start = gem->paddr + plane->state->fb->offsets[0] + |
| 259 | plane->state->crtc_y * plane->state->fb->pitches[0] + | ||
| 260 | plane->state->crtc_x * bpp / 8; | ||
| 261 | |||
| 262 | hdlcd = plane->dev->dev_private; | ||
| 263 | hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_LENGTH, plane->state->fb->pitches[0]); | ||
| 264 | hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_PITCH, plane->state->fb->pitches[0]); | ||
| 265 | hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_COUNT, dest_h - 1); | ||
| 244 | hdlcd_write(hdlcd, HDLCD_REG_FB_BASE, scanout_start); | 266 | hdlcd_write(hdlcd, HDLCD_REG_FB_BASE, scanout_start); |
| 245 | } | 267 | } |
| 246 | 268 | ||
| 247 | static const struct drm_plane_helper_funcs hdlcd_plane_helper_funcs = { | 269 | static const struct drm_plane_helper_funcs hdlcd_plane_helper_funcs = { |
| 248 | .prepare_fb = NULL, | ||
| 249 | .cleanup_fb = NULL, | ||
| 250 | .atomic_check = hdlcd_plane_atomic_check, | 270 | .atomic_check = hdlcd_plane_atomic_check, |
| 251 | .atomic_update = hdlcd_plane_atomic_update, | 271 | .atomic_update = hdlcd_plane_atomic_update, |
| 252 | }; | 272 | }; |
| @@ -294,16 +314,6 @@ static struct drm_plane *hdlcd_plane_init(struct drm_device *drm) | |||
| 294 | return plane; | 314 | return plane; |
| 295 | } | 315 | } |
| 296 | 316 | ||
| 297 | void hdlcd_crtc_suspend(struct drm_crtc *crtc) | ||
| 298 | { | ||
| 299 | hdlcd_crtc_disable(crtc); | ||
| 300 | } | ||
| 301 | |||
| 302 | void hdlcd_crtc_resume(struct drm_crtc *crtc) | ||
| 303 | { | ||
| 304 | hdlcd_crtc_enable(crtc); | ||
| 305 | } | ||
| 306 | |||
| 307 | int hdlcd_setup_crtc(struct drm_device *drm) | 317 | int hdlcd_setup_crtc(struct drm_device *drm) |
| 308 | { | 318 | { |
| 309 | struct hdlcd_drm_private *hdlcd = drm->dev_private; | 319 | struct hdlcd_drm_private *hdlcd = drm->dev_private; |
diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c index 4f909378d581..49e586d67595 100644 --- a/drivers/gpu/drm/arm/hdlcd_drv.c +++ b/drivers/gpu/drm/arm/hdlcd_drv.c | |||
| @@ -49,8 +49,6 @@ static int hdlcd_load(struct drm_device *drm, unsigned long flags) | |||
| 49 | atomic_set(&hdlcd->dma_end_count, 0); | 49 | atomic_set(&hdlcd->dma_end_count, 0); |
| 50 | #endif | 50 | #endif |
| 51 | 51 | ||
| 52 | INIT_LIST_HEAD(&hdlcd->event_list); | ||
| 53 | |||
| 54 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 52 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 55 | hdlcd->mmio = devm_ioremap_resource(drm->dev, res); | 53 | hdlcd->mmio = devm_ioremap_resource(drm->dev, res); |
| 56 | if (IS_ERR(hdlcd->mmio)) { | 54 | if (IS_ERR(hdlcd->mmio)) { |
| @@ -84,11 +82,7 @@ static int hdlcd_load(struct drm_device *drm, unsigned long flags) | |||
| 84 | goto setup_fail; | 82 | goto setup_fail; |
| 85 | } | 83 | } |
| 86 | 84 | ||
| 87 | pm_runtime_enable(drm->dev); | ||
| 88 | |||
| 89 | pm_runtime_get_sync(drm->dev); | ||
| 90 | ret = drm_irq_install(drm, platform_get_irq(pdev, 0)); | 85 | ret = drm_irq_install(drm, platform_get_irq(pdev, 0)); |
| 91 | pm_runtime_put_sync(drm->dev); | ||
| 92 | if (ret < 0) { | 86 | if (ret < 0) { |
| 93 | DRM_ERROR("failed to install IRQ handler\n"); | 87 | DRM_ERROR("failed to install IRQ handler\n"); |
| 94 | goto irq_fail; | 88 | goto irq_fail; |
| @@ -164,24 +158,9 @@ static irqreturn_t hdlcd_irq(int irq, void *arg) | |||
| 164 | atomic_inc(&hdlcd->vsync_count); | 158 | atomic_inc(&hdlcd->vsync_count); |
| 165 | 159 | ||
| 166 | #endif | 160 | #endif |
| 167 | if (irq_status & HDLCD_INTERRUPT_VSYNC) { | 161 | if (irq_status & HDLCD_INTERRUPT_VSYNC) |
| 168 | bool events_sent = false; | ||
| 169 | unsigned long flags; | ||
| 170 | struct drm_pending_vblank_event *e, *t; | ||
| 171 | |||
| 172 | drm_crtc_handle_vblank(&hdlcd->crtc); | 162 | drm_crtc_handle_vblank(&hdlcd->crtc); |
| 173 | 163 | ||
| 174 | spin_lock_irqsave(&drm->event_lock, flags); | ||
| 175 | list_for_each_entry_safe(e, t, &hdlcd->event_list, base.link) { | ||
| 176 | list_del(&e->base.link); | ||
| 177 | drm_crtc_send_vblank_event(&hdlcd->crtc, e); | ||
| 178 | events_sent = true; | ||
| 179 | } | ||
| 180 | if (events_sent) | ||
| 181 | drm_crtc_vblank_put(&hdlcd->crtc); | ||
| 182 | spin_unlock_irqrestore(&drm->event_lock, flags); | ||
| 183 | } | ||
| 184 | |||
| 185 | /* acknowledge interrupt(s) */ | 164 | /* acknowledge interrupt(s) */ |
| 186 | hdlcd_write(hdlcd, HDLCD_REG_INT_CLEAR, irq_status); | 165 | hdlcd_write(hdlcd, HDLCD_REG_INT_CLEAR, irq_status); |
| 187 | 166 | ||
| @@ -275,6 +254,7 @@ static int hdlcd_show_pxlclock(struct seq_file *m, void *arg) | |||
| 275 | static struct drm_info_list hdlcd_debugfs_list[] = { | 254 | static struct drm_info_list hdlcd_debugfs_list[] = { |
| 276 | { "interrupt_count", hdlcd_show_underrun_count, 0 }, | 255 | { "interrupt_count", hdlcd_show_underrun_count, 0 }, |
| 277 | { "clocks", hdlcd_show_pxlclock, 0 }, | 256 | { "clocks", hdlcd_show_pxlclock, 0 }, |
| 257 | { "fb", drm_fb_cma_debugfs_show, 0 }, | ||
| 278 | }; | 258 | }; |
| 279 | 259 | ||
| 280 | static int hdlcd_debugfs_init(struct drm_minor *minor) | 260 | static int hdlcd_debugfs_init(struct drm_minor *minor) |
| @@ -357,6 +337,8 @@ static int hdlcd_drm_bind(struct device *dev) | |||
| 357 | return -ENOMEM; | 337 | return -ENOMEM; |
| 358 | 338 | ||
| 359 | drm->dev_private = hdlcd; | 339 | drm->dev_private = hdlcd; |
| 340 | dev_set_drvdata(dev, drm); | ||
| 341 | |||
| 360 | hdlcd_setup_mode_config(drm); | 342 | hdlcd_setup_mode_config(drm); |
| 361 | ret = hdlcd_load(drm, 0); | 343 | ret = hdlcd_load(drm, 0); |
| 362 | if (ret) | 344 | if (ret) |
| @@ -366,14 +348,18 @@ static int hdlcd_drm_bind(struct device *dev) | |||
| 366 | if (ret) | 348 | if (ret) |
| 367 | goto err_unload; | 349 | goto err_unload; |
| 368 | 350 | ||
| 369 | dev_set_drvdata(dev, drm); | ||
| 370 | |||
| 371 | ret = component_bind_all(dev, drm); | 351 | ret = component_bind_all(dev, drm); |
| 372 | if (ret) { | 352 | if (ret) { |
| 373 | DRM_ERROR("Failed to bind all components\n"); | 353 | DRM_ERROR("Failed to bind all components\n"); |
| 374 | goto err_unregister; | 354 | goto err_unregister; |
| 375 | } | 355 | } |
| 376 | 356 | ||
| 357 | ret = pm_runtime_set_active(dev); | ||
| 358 | if (ret) | ||
| 359 | goto err_pm_active; | ||
| 360 | |||
| 361 | pm_runtime_enable(dev); | ||
| 362 | |||
| 377 | ret = drm_vblank_init(drm, drm->mode_config.num_crtc); | 363 | ret = drm_vblank_init(drm, drm->mode_config.num_crtc); |
| 378 | if (ret < 0) { | 364 | if (ret < 0) { |
| 379 | DRM_ERROR("failed to initialise vblank\n"); | 365 | DRM_ERROR("failed to initialise vblank\n"); |
| @@ -399,16 +385,16 @@ err_fbdev: | |||
| 399 | drm_mode_config_cleanup(drm); | 385 | drm_mode_config_cleanup(drm); |
| 400 | drm_vblank_cleanup(drm); | 386 | drm_vblank_cleanup(drm); |
| 401 | err_vblank: | 387 | err_vblank: |
| 388 | pm_runtime_disable(drm->dev); | ||
| 389 | err_pm_active: | ||
| 402 | component_unbind_all(dev, drm); | 390 | component_unbind_all(dev, drm); |
| 403 | err_unregister: | 391 | err_unregister: |
| 404 | drm_dev_unregister(drm); | 392 | drm_dev_unregister(drm); |
| 405 | err_unload: | 393 | err_unload: |
| 406 | pm_runtime_get_sync(drm->dev); | ||
| 407 | drm_irq_uninstall(drm); | 394 | drm_irq_uninstall(drm); |
| 408 | pm_runtime_put_sync(drm->dev); | ||
| 409 | pm_runtime_disable(drm->dev); | ||
| 410 | of_reserved_mem_device_release(drm->dev); | 395 | of_reserved_mem_device_release(drm->dev); |
| 411 | err_free: | 396 | err_free: |
| 397 | dev_set_drvdata(dev, NULL); | ||
| 412 | drm_dev_unref(drm); | 398 | drm_dev_unref(drm); |
| 413 | 399 | ||
| 414 | return ret; | 400 | return ret; |
| @@ -495,30 +481,34 @@ MODULE_DEVICE_TABLE(of, hdlcd_of_match); | |||
| 495 | static int __maybe_unused hdlcd_pm_suspend(struct device *dev) | 481 | static int __maybe_unused hdlcd_pm_suspend(struct device *dev) |
| 496 | { | 482 | { |
| 497 | struct drm_device *drm = dev_get_drvdata(dev); | 483 | struct drm_device *drm = dev_get_drvdata(dev); |
| 498 | struct drm_crtc *crtc; | 484 | struct hdlcd_drm_private *hdlcd = drm ? drm->dev_private : NULL; |
| 499 | 485 | ||
| 500 | if (pm_runtime_suspended(dev)) | 486 | if (!hdlcd) |
| 501 | return 0; | 487 | return 0; |
| 502 | 488 | ||
| 503 | drm_modeset_lock_all(drm); | 489 | drm_kms_helper_poll_disable(drm); |
| 504 | list_for_each_entry(crtc, &drm->mode_config.crtc_list, head) | 490 | |
| 505 | hdlcd_crtc_suspend(crtc); | 491 | hdlcd->state = drm_atomic_helper_suspend(drm); |
| 506 | drm_modeset_unlock_all(drm); | 492 | if (IS_ERR(hdlcd->state)) { |
| 493 | drm_kms_helper_poll_enable(drm); | ||
| 494 | return PTR_ERR(hdlcd->state); | ||
| 495 | } | ||
| 496 | |||
| 507 | return 0; | 497 | return 0; |
| 508 | } | 498 | } |
| 509 | 499 | ||
| 510 | static int __maybe_unused hdlcd_pm_resume(struct device *dev) | 500 | static int __maybe_unused hdlcd_pm_resume(struct device *dev) |
| 511 | { | 501 | { |
| 512 | struct drm_device *drm = dev_get_drvdata(dev); | 502 | struct drm_device *drm = dev_get_drvdata(dev); |
| 513 | struct drm_crtc *crtc; | 503 | struct hdlcd_drm_private *hdlcd = drm ? drm->dev_private : NULL; |
| 514 | 504 | ||
| 515 | if (!pm_runtime_suspended(dev)) | 505 | if (!hdlcd) |
| 516 | return 0; | 506 | return 0; |
| 517 | 507 | ||
| 518 | drm_modeset_lock_all(drm); | 508 | drm_atomic_helper_resume(drm, hdlcd->state); |
| 519 | list_for_each_entry(crtc, &drm->mode_config.crtc_list, head) | 509 | drm_kms_helper_poll_enable(drm); |
| 520 | hdlcd_crtc_resume(crtc); | 510 | pm_runtime_set_active(dev); |
| 521 | drm_modeset_unlock_all(drm); | 511 | |
| 522 | return 0; | 512 | return 0; |
| 523 | } | 513 | } |
| 524 | 514 | ||
diff --git a/drivers/gpu/drm/arm/hdlcd_drv.h b/drivers/gpu/drm/arm/hdlcd_drv.h index aa234784f053..e3950a071152 100644 --- a/drivers/gpu/drm/arm/hdlcd_drv.h +++ b/drivers/gpu/drm/arm/hdlcd_drv.h | |||
| @@ -9,10 +9,9 @@ struct hdlcd_drm_private { | |||
| 9 | void __iomem *mmio; | 9 | void __iomem *mmio; |
| 10 | struct clk *clk; | 10 | struct clk *clk; |
| 11 | struct drm_fbdev_cma *fbdev; | 11 | struct drm_fbdev_cma *fbdev; |
| 12 | struct drm_framebuffer *fb; | ||
| 13 | struct list_head event_list; | ||
| 14 | struct drm_crtc crtc; | 12 | struct drm_crtc crtc; |
| 15 | struct drm_plane *plane; | 13 | struct drm_plane *plane; |
| 14 | struct drm_atomic_state *state; | ||
| 16 | #ifdef CONFIG_DEBUG_FS | 15 | #ifdef CONFIG_DEBUG_FS |
| 17 | atomic_t buffer_underrun_count; | 16 | atomic_t buffer_underrun_count; |
| 18 | atomic_t bus_error_count; | 17 | atomic_t bus_error_count; |
| @@ -36,7 +35,5 @@ static inline u32 hdlcd_read(struct hdlcd_drm_private *hdlcd, unsigned int reg) | |||
| 36 | 35 | ||
| 37 | int hdlcd_setup_crtc(struct drm_device *dev); | 36 | int hdlcd_setup_crtc(struct drm_device *dev); |
| 38 | void hdlcd_set_scanout(struct hdlcd_drm_private *hdlcd); | 37 | void hdlcd_set_scanout(struct hdlcd_drm_private *hdlcd); |
| 39 | void hdlcd_crtc_suspend(struct drm_crtc *crtc); | ||
| 40 | void hdlcd_crtc_resume(struct drm_crtc *crtc); | ||
| 41 | 38 | ||
| 42 | #endif /* __HDLCD_DRV_H__ */ | 39 | #endif /* __HDLCD_DRV_H__ */ |
