diff options
| -rw-r--r-- | drivers/gpu/drm/drm_fb_cma_helper.c | 15 | ||||
| -rw-r--r-- | drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c | 21 | ||||
| -rw-r--r-- | drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c | 47 | ||||
| -rw-r--r-- | drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c | 16 | ||||
| -rw-r--r-- | drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.h | 1 | ||||
| -rw-r--r-- | include/drm/drm_fb_cma_helper.h | 1 |
7 files changed, 76 insertions, 27 deletions
diff --git a/drivers/gpu/drm/drm_fb_cma_helper.c b/drivers/gpu/drm/drm_fb_cma_helper.c index c0b0c718994a..1fd6eac1400c 100644 --- a/drivers/gpu/drm/drm_fb_cma_helper.c +++ b/drivers/gpu/drm/drm_fb_cma_helper.c | |||
| @@ -596,3 +596,18 @@ void drm_fbdev_cma_hotplug_event(struct drm_fbdev_cma *fbdev_cma) | |||
| 596 | drm_fb_helper_hotplug_event(&fbdev_cma->fb_helper); | 596 | drm_fb_helper_hotplug_event(&fbdev_cma->fb_helper); |
| 597 | } | 597 | } |
| 598 | EXPORT_SYMBOL_GPL(drm_fbdev_cma_hotplug_event); | 598 | EXPORT_SYMBOL_GPL(drm_fbdev_cma_hotplug_event); |
| 599 | |||
| 600 | /** | ||
| 601 | * drm_fbdev_cma_set_suspend - wrapper around drm_fb_helper_set_suspend | ||
| 602 | * @fbdev_cma: The drm_fbdev_cma struct, may be NULL | ||
| 603 | * @state: desired state, zero to resume, non-zero to suspend | ||
| 604 | * | ||
| 605 | * Calls drm_fb_helper_set_suspend, which is a wrapper around | ||
| 606 | * fb_set_suspend implemented by fbdev core. | ||
| 607 | */ | ||
| 608 | void drm_fbdev_cma_set_suspend(struct drm_fbdev_cma *fbdev_cma, int state) | ||
| 609 | { | ||
| 610 | if (fbdev_cma) | ||
| 611 | drm_fb_helper_set_suspend(&fbdev_cma->fb_helper, state); | ||
| 612 | } | ||
| 613 | EXPORT_SYMBOL(drm_fbdev_cma_set_suspend); | ||
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c index 706de3278f1c..3371635cd4d7 100644 --- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c +++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c | |||
| @@ -44,6 +44,8 @@ static void fsl_dcu_drm_disable_crtc(struct drm_crtc *crtc) | |||
| 44 | struct drm_device *dev = crtc->dev; | 44 | struct drm_device *dev = crtc->dev; |
| 45 | struct fsl_dcu_drm_device *fsl_dev = dev->dev_private; | 45 | struct fsl_dcu_drm_device *fsl_dev = dev->dev_private; |
| 46 | 46 | ||
| 47 | drm_crtc_vblank_off(crtc); | ||
| 48 | |||
| 47 | regmap_update_bits(fsl_dev->regmap, DCU_DCU_MODE, | 49 | regmap_update_bits(fsl_dev->regmap, DCU_DCU_MODE, |
| 48 | DCU_MODE_DCU_MODE_MASK, | 50 | DCU_MODE_DCU_MODE_MASK, |
| 49 | DCU_MODE_DCU_MODE(DCU_MODE_OFF)); | 51 | DCU_MODE_DCU_MODE(DCU_MODE_OFF)); |
| @@ -61,6 +63,8 @@ static void fsl_dcu_drm_crtc_enable(struct drm_crtc *crtc) | |||
| 61 | DCU_MODE_DCU_MODE(DCU_MODE_NORMAL)); | 63 | DCU_MODE_DCU_MODE(DCU_MODE_NORMAL)); |
| 62 | regmap_write(fsl_dev->regmap, DCU_UPDATE_MODE, | 64 | regmap_write(fsl_dev->regmap, DCU_UPDATE_MODE, |
| 63 | DCU_UPDATE_MODE_READREG); | 65 | DCU_UPDATE_MODE_READREG); |
| 66 | |||
| 67 | drm_crtc_vblank_on(crtc); | ||
| 64 | } | 68 | } |
| 65 | 69 | ||
| 66 | static void fsl_dcu_drm_crtc_mode_set_nofb(struct drm_crtc *crtc) | 70 | static void fsl_dcu_drm_crtc_mode_set_nofb(struct drm_crtc *crtc) |
| @@ -137,9 +141,10 @@ int fsl_dcu_drm_crtc_create(struct fsl_dcu_drm_device *fsl_dev) | |||
| 137 | { | 141 | { |
| 138 | struct drm_plane *primary; | 142 | struct drm_plane *primary; |
| 139 | struct drm_crtc *crtc = &fsl_dev->crtc; | 143 | struct drm_crtc *crtc = &fsl_dev->crtc; |
| 140 | unsigned int i, j, reg_num; | ||
| 141 | int ret; | 144 | int ret; |
| 142 | 145 | ||
| 146 | fsl_dcu_drm_init_planes(fsl_dev->drm); | ||
| 147 | |||
| 143 | primary = fsl_dcu_drm_primary_create_plane(fsl_dev->drm); | 148 | primary = fsl_dcu_drm_primary_create_plane(fsl_dev->drm); |
| 144 | if (!primary) | 149 | if (!primary) |
| 145 | return -ENOMEM; | 150 | return -ENOMEM; |
| @@ -153,19 +158,5 @@ int fsl_dcu_drm_crtc_create(struct fsl_dcu_drm_device *fsl_dev) | |||
| 153 | 158 | ||
| 154 | drm_crtc_helper_add(crtc, &fsl_dcu_drm_crtc_helper_funcs); | 159 | drm_crtc_helper_add(crtc, &fsl_dcu_drm_crtc_helper_funcs); |
| 155 | 160 | ||
| 156 | if (!strcmp(fsl_dev->soc->name, "ls1021a")) | ||
| 157 | reg_num = LS1021A_LAYER_REG_NUM; | ||
| 158 | else | ||
| 159 | reg_num = VF610_LAYER_REG_NUM; | ||
| 160 | for (i = 0; i < fsl_dev->soc->total_layer; i++) { | ||
| 161 | for (j = 1; j <= reg_num; j++) | ||
| 162 | regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN(i, j), 0); | ||
| 163 | } | ||
| 164 | regmap_update_bits(fsl_dev->regmap, DCU_DCU_MODE, | ||
| 165 | DCU_MODE_DCU_MODE_MASK, | ||
| 166 | DCU_MODE_DCU_MODE(DCU_MODE_OFF)); | ||
| 167 | regmap_write(fsl_dev->regmap, DCU_UPDATE_MODE, | ||
| 168 | DCU_UPDATE_MODE_READREG); | ||
| 169 | |||
| 170 | return 0; | 161 | return 0; |
| 171 | } | 162 | } |
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c index 7655c8c62c65..7882387f9bff 100644 --- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c +++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | 11 | ||
| 12 | #include <linux/clk.h> | 12 | #include <linux/clk.h> |
| 13 | #include <linux/clk-provider.h> | 13 | #include <linux/clk-provider.h> |
| 14 | #include <linux/console.h> | ||
| 14 | #include <linux/io.h> | 15 | #include <linux/io.h> |
| 15 | #include <linux/mfd/syscon.h> | 16 | #include <linux/mfd/syscon.h> |
| 16 | #include <linux/mm.h> | 17 | #include <linux/mm.h> |
| @@ -22,6 +23,7 @@ | |||
| 22 | #include <linux/regmap.h> | 23 | #include <linux/regmap.h> |
| 23 | 24 | ||
| 24 | #include <drm/drmP.h> | 25 | #include <drm/drmP.h> |
| 26 | #include <drm/drm_atomic_helper.h> | ||
| 25 | #include <drm/drm_crtc_helper.h> | 27 | #include <drm/drm_crtc_helper.h> |
| 26 | #include <drm/drm_fb_cma_helper.h> | 28 | #include <drm/drm_fb_cma_helper.h> |
| 27 | #include <drm/drm_gem_cma_helper.h> | 29 | #include <drm/drm_gem_cma_helper.h> |
| @@ -42,10 +44,8 @@ static const struct regmap_config fsl_dcu_regmap_config = { | |||
| 42 | .reg_bits = 32, | 44 | .reg_bits = 32, |
| 43 | .reg_stride = 4, | 45 | .reg_stride = 4, |
| 44 | .val_bits = 32, | 46 | .val_bits = 32, |
| 45 | .cache_type = REGCACHE_FLAT, | ||
| 46 | 47 | ||
| 47 | .volatile_reg = fsl_dcu_drm_is_volatile_reg, | 48 | .volatile_reg = fsl_dcu_drm_is_volatile_reg, |
| 48 | .max_register = 0x11fc, | ||
| 49 | }; | 49 | }; |
| 50 | 50 | ||
| 51 | static int fsl_dcu_drm_irq_init(struct drm_device *dev) | 51 | static int fsl_dcu_drm_irq_init(struct drm_device *dev) |
| @@ -229,11 +229,26 @@ static int fsl_dcu_drm_pm_suspend(struct device *dev) | |||
| 229 | if (!fsl_dev) | 229 | if (!fsl_dev) |
| 230 | return 0; | 230 | return 0; |
| 231 | 231 | ||
| 232 | disable_irq(fsl_dev->irq); | ||
| 232 | drm_kms_helper_poll_disable(fsl_dev->drm); | 233 | drm_kms_helper_poll_disable(fsl_dev->drm); |
| 233 | regcache_cache_only(fsl_dev->regmap, true); | 234 | |
| 234 | regcache_mark_dirty(fsl_dev->regmap); | 235 | console_lock(); |
| 235 | clk_disable(fsl_dev->clk); | 236 | drm_fbdev_cma_set_suspend(fsl_dev->fbdev, 1); |
| 236 | clk_unprepare(fsl_dev->clk); | 237 | console_unlock(); |
| 238 | |||
| 239 | fsl_dev->state = drm_atomic_helper_suspend(fsl_dev->drm); | ||
| 240 | if (IS_ERR(fsl_dev->state)) { | ||
| 241 | console_lock(); | ||
| 242 | drm_fbdev_cma_set_suspend(fsl_dev->fbdev, 0); | ||
| 243 | console_unlock(); | ||
| 244 | |||
| 245 | drm_kms_helper_poll_enable(fsl_dev->drm); | ||
| 246 | enable_irq(fsl_dev->irq); | ||
| 247 | return PTR_ERR(fsl_dev->state); | ||
| 248 | } | ||
| 249 | |||
| 250 | clk_disable_unprepare(fsl_dev->pix_clk); | ||
| 251 | clk_disable_unprepare(fsl_dev->clk); | ||
| 237 | 252 | ||
| 238 | return 0; | 253 | return 0; |
| 239 | } | 254 | } |
| @@ -246,21 +261,27 @@ static int fsl_dcu_drm_pm_resume(struct device *dev) | |||
| 246 | if (!fsl_dev) | 261 | if (!fsl_dev) |
| 247 | return 0; | 262 | return 0; |
| 248 | 263 | ||
| 249 | ret = clk_enable(fsl_dev->clk); | 264 | ret = clk_prepare_enable(fsl_dev->clk); |
| 250 | if (ret < 0) { | 265 | if (ret < 0) { |
| 251 | dev_err(dev, "failed to enable dcu clk\n"); | 266 | dev_err(dev, "failed to enable dcu clk\n"); |
| 252 | clk_unprepare(fsl_dev->clk); | ||
| 253 | return ret; | 267 | return ret; |
| 254 | } | 268 | } |
| 255 | ret = clk_prepare(fsl_dev->clk); | 269 | |
| 270 | ret = clk_prepare_enable(fsl_dev->pix_clk); | ||
| 256 | if (ret < 0) { | 271 | if (ret < 0) { |
| 257 | dev_err(dev, "failed to prepare dcu clk\n"); | 272 | dev_err(dev, "failed to enable pix clk\n"); |
| 258 | return ret; | 273 | return ret; |
| 259 | } | 274 | } |
| 260 | 275 | ||
| 276 | fsl_dcu_drm_init_planes(fsl_dev->drm); | ||
| 277 | drm_atomic_helper_resume(fsl_dev->drm, fsl_dev->state); | ||
| 278 | |||
| 279 | console_lock(); | ||
| 280 | drm_fbdev_cma_set_suspend(fsl_dev->fbdev, 0); | ||
| 281 | console_unlock(); | ||
| 282 | |||
| 261 | drm_kms_helper_poll_enable(fsl_dev->drm); | 283 | drm_kms_helper_poll_enable(fsl_dev->drm); |
| 262 | regcache_cache_only(fsl_dev->regmap, false); | 284 | enable_irq(fsl_dev->irq); |
| 263 | regcache_sync(fsl_dev->regmap); | ||
| 264 | 285 | ||
| 265 | return 0; | 286 | return 0; |
| 266 | } | 287 | } |
| @@ -274,12 +295,14 @@ static const struct fsl_dcu_soc_data fsl_dcu_ls1021a_data = { | |||
| 274 | .name = "ls1021a", | 295 | .name = "ls1021a", |
| 275 | .total_layer = 16, | 296 | .total_layer = 16, |
| 276 | .max_layer = 4, | 297 | .max_layer = 4, |
| 298 | .layer_regs = LS1021A_LAYER_REG_NUM, | ||
| 277 | }; | 299 | }; |
| 278 | 300 | ||
| 279 | static const struct fsl_dcu_soc_data fsl_dcu_vf610_data = { | 301 | static const struct fsl_dcu_soc_data fsl_dcu_vf610_data = { |
| 280 | .name = "vf610", | 302 | .name = "vf610", |
| 281 | .total_layer = 64, | 303 | .total_layer = 64, |
| 282 | .max_layer = 6, | 304 | .max_layer = 6, |
| 305 | .layer_regs = VF610_LAYER_REG_NUM, | ||
| 283 | }; | 306 | }; |
| 284 | 307 | ||
| 285 | static const struct of_device_id fsl_dcu_of_match[] = { | 308 | static const struct of_device_id fsl_dcu_of_match[] = { |
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h index c275f900ff23..3b371fe7491e 100644 --- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h +++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h | |||
| @@ -175,6 +175,7 @@ struct fsl_dcu_soc_data { | |||
| 175 | unsigned int total_layer; | 175 | unsigned int total_layer; |
| 176 | /*max layer number DCU supported*/ | 176 | /*max layer number DCU supported*/ |
| 177 | unsigned int max_layer; | 177 | unsigned int max_layer; |
| 178 | unsigned int layer_regs; | ||
| 178 | }; | 179 | }; |
| 179 | 180 | ||
| 180 | struct fsl_dcu_drm_device { | 181 | struct fsl_dcu_drm_device { |
| @@ -193,6 +194,7 @@ struct fsl_dcu_drm_device { | |||
| 193 | struct drm_encoder encoder; | 194 | struct drm_encoder encoder; |
| 194 | struct fsl_dcu_drm_connector connector; | 195 | struct fsl_dcu_drm_connector connector; |
| 195 | const struct fsl_dcu_soc_data *soc; | 196 | const struct fsl_dcu_soc_data *soc; |
| 197 | struct drm_atomic_state *state; | ||
| 196 | }; | 198 | }; |
| 197 | 199 | ||
| 198 | void fsl_dcu_fbdev_init(struct drm_device *dev); | 200 | void fsl_dcu_fbdev_init(struct drm_device *dev); |
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c index 274558b3b32b..e50467a0deb0 100644 --- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c +++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c | |||
| @@ -217,6 +217,22 @@ static const u32 fsl_dcu_drm_plane_formats[] = { | |||
| 217 | DRM_FORMAT_YUV422, | 217 | DRM_FORMAT_YUV422, |
| 218 | }; | 218 | }; |
| 219 | 219 | ||
| 220 | void fsl_dcu_drm_init_planes(struct drm_device *dev) | ||
| 221 | { | ||
| 222 | struct fsl_dcu_drm_device *fsl_dev = dev->dev_private; | ||
| 223 | int i, j; | ||
| 224 | |||
| 225 | for (i = 0; i < fsl_dev->soc->total_layer; i++) { | ||
| 226 | for (j = 1; j <= fsl_dev->soc->layer_regs; j++) | ||
| 227 | regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN(i, j), 0); | ||
| 228 | } | ||
| 229 | regmap_update_bits(fsl_dev->regmap, DCU_DCU_MODE, | ||
| 230 | DCU_MODE_DCU_MODE_MASK, | ||
| 231 | DCU_MODE_DCU_MODE(DCU_MODE_OFF)); | ||
| 232 | regmap_write(fsl_dev->regmap, DCU_UPDATE_MODE, | ||
| 233 | DCU_UPDATE_MODE_READREG); | ||
| 234 | } | ||
| 235 | |||
| 220 | struct drm_plane *fsl_dcu_drm_primary_create_plane(struct drm_device *dev) | 236 | struct drm_plane *fsl_dcu_drm_primary_create_plane(struct drm_device *dev) |
| 221 | { | 237 | { |
| 222 | struct drm_plane *primary; | 238 | struct drm_plane *primary; |
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.h b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.h index d657f088d859..8ee45f813ee8 100644 --- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.h +++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.h | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | #ifndef __FSL_DCU_DRM_PLANE_H__ | 12 | #ifndef __FSL_DCU_DRM_PLANE_H__ |
| 13 | #define __FSL_DCU_DRM_PLANE_H__ | 13 | #define __FSL_DCU_DRM_PLANE_H__ |
| 14 | 14 | ||
| 15 | void fsl_dcu_drm_init_planes(struct drm_device *dev); | ||
| 15 | struct drm_plane *fsl_dcu_drm_primary_create_plane(struct drm_device *dev); | 16 | struct drm_plane *fsl_dcu_drm_primary_create_plane(struct drm_device *dev); |
| 16 | 17 | ||
| 17 | #endif /* __FSL_DCU_DRM_PLANE_H__ */ | 18 | #endif /* __FSL_DCU_DRM_PLANE_H__ */ |
diff --git a/include/drm/drm_fb_cma_helper.h b/include/drm/drm_fb_cma_helper.h index fd0dde9f0a6d..f313211f8ed5 100644 --- a/include/drm/drm_fb_cma_helper.h +++ b/include/drm/drm_fb_cma_helper.h | |||
| @@ -23,6 +23,7 @@ void drm_fbdev_cma_fini(struct drm_fbdev_cma *fbdev_cma); | |||
| 23 | 23 | ||
| 24 | void drm_fbdev_cma_restore_mode(struct drm_fbdev_cma *fbdev_cma); | 24 | void drm_fbdev_cma_restore_mode(struct drm_fbdev_cma *fbdev_cma); |
| 25 | void drm_fbdev_cma_hotplug_event(struct drm_fbdev_cma *fbdev_cma); | 25 | void drm_fbdev_cma_hotplug_event(struct drm_fbdev_cma *fbdev_cma); |
| 26 | void drm_fbdev_cma_set_suspend(struct drm_fbdev_cma *fbdev_cma, int state); | ||
| 26 | int drm_fbdev_cma_create_with_funcs(struct drm_fb_helper *helper, | 27 | int drm_fbdev_cma_create_with_funcs(struct drm_fb_helper *helper, |
| 27 | struct drm_fb_helper_surface_size *sizes, | 28 | struct drm_fb_helper_surface_size *sizes, |
| 28 | const struct drm_framebuffer_funcs *funcs); | 29 | const struct drm_framebuffer_funcs *funcs); |
