diff options
Diffstat (limited to 'drivers/gpu/drm/stm')
-rw-r--r-- | drivers/gpu/drm/stm/drv.c | 13 | ||||
-rw-r--r-- | drivers/gpu/drm/stm/ltdc.c | 45 | ||||
-rw-r--r-- | drivers/gpu/drm/stm/ltdc.h | 5 |
3 files changed, 54 insertions, 9 deletions
diff --git a/drivers/gpu/drm/stm/drv.c b/drivers/gpu/drm/stm/drv.c index f2021b23554d..8dec001b9d37 100644 --- a/drivers/gpu/drm/stm/drv.c +++ b/drivers/gpu/drm/stm/drv.c @@ -26,7 +26,6 @@ static const struct drm_mode_config_funcs drv_mode_config_funcs = { .fb_create = drm_gem_fb_create, - .output_poll_changed = drm_fb_helper_output_poll_changed, .atomic_check = drm_atomic_helper_check, .atomic_commit = drm_atomic_helper_commit, }; @@ -52,7 +51,6 @@ DEFINE_DRM_GEM_CMA_FOPS(drv_driver_fops); static struct drm_driver drv_driver = { .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME | DRIVER_ATOMIC, - .lastclose = drm_fb_helper_lastclose, .name = "stm", .desc = "STMicroelectronics SoC DRM", .date = "20170330", @@ -72,6 +70,8 @@ static struct drm_driver drv_driver = { .gem_prime_vmap = drm_gem_cma_prime_vmap, .gem_prime_vunmap = drm_gem_cma_prime_vunmap, .gem_prime_mmap = drm_gem_cma_prime_mmap, + .get_scanout_position = ltdc_crtc_scanoutpos, + .get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos, }; static int drv_load(struct drm_device *ddev) @@ -108,12 +108,6 @@ static int drv_load(struct drm_device *ddev) drm_mode_config_reset(ddev); drm_kms_helper_poll_init(ddev); - if (ddev->mode_config.num_connector) { - ret = drm_fb_cma_fbdev_init(ddev, 16, 0); - if (ret) - DRM_DEBUG("Warning: fails to create fbdev\n"); - } - platform_set_drvdata(pdev, ddev); return 0; @@ -126,7 +120,6 @@ static void drv_unload(struct drm_device *ddev) { DRM_DEBUG("%s\n", __func__); - drm_fb_cma_fbdev_fini(ddev); drm_kms_helper_poll_fini(ddev); ltdc_unload(ddev); drm_mode_config_cleanup(ddev); @@ -154,6 +147,8 @@ static int stm_drm_platform_probe(struct platform_device *pdev) if (ret) goto err_put; + drm_fbdev_generic_setup(ddev, 16); + return 0; err_put: diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c index 808d9fb627e9..61dd661aa0ac 100644 --- a/drivers/gpu/drm/stm/ltdc.c +++ b/drivers/gpu/drm/stm/ltdc.c @@ -148,6 +148,8 @@ #define IER_TERRIE BIT(2) /* Transfer ERRor Interrupt Enable */ #define IER_RRIE BIT(3) /* Register Reload Interrupt enable */ +#define CPSR_CYPOS GENMASK(15, 0) /* Current Y position */ + #define ISR_LIF BIT(0) /* Line Interrupt Flag */ #define ISR_FUIF BIT(1) /* Fifo Underrun Interrupt Flag */ #define ISR_TERRIF BIT(2) /* Transfer ERRor Interrupt Flag */ @@ -626,6 +628,49 @@ static void ltdc_crtc_disable_vblank(struct drm_crtc *crtc) reg_clear(ldev->regs, LTDC_IER, IER_LIE); } +bool ltdc_crtc_scanoutpos(struct drm_device *ddev, unsigned int pipe, + bool in_vblank_irq, int *vpos, int *hpos, + ktime_t *stime, ktime_t *etime, + const struct drm_display_mode *mode) +{ + struct ltdc_device *ldev = ddev->dev_private; + int line, vactive_start, vactive_end, vtotal; + + if (stime) + *stime = ktime_get(); + + /* The active area starts after vsync + front porch and ends + * at vsync + front porc + display size. + * The total height also include back porch. + * We have 3 possible cases to handle: + * - line < vactive_start: vpos = line - vactive_start and will be + * negative + * - vactive_start < line < vactive_end: vpos = line - vactive_start + * and will be positive + * - line > vactive_end: vpos = line - vtotal - vactive_start + * and will negative + * + * Computation for the two first cases are identical so we can + * simplify the code and only test if line > vactive_end + */ + line = reg_read(ldev->regs, LTDC_CPSR) & CPSR_CYPOS; + vactive_start = reg_read(ldev->regs, LTDC_BPCR) & BPCR_AVBP; + vactive_end = reg_read(ldev->regs, LTDC_AWCR) & AWCR_AAH; + vtotal = reg_read(ldev->regs, LTDC_TWCR) & TWCR_TOTALH; + + if (line > vactive_end) + *vpos = line - vtotal - vactive_start; + else + *vpos = line - vactive_start; + + *hpos = 0; + + if (etime) + *etime = ktime_get(); + + return true; +} + static const struct drm_crtc_funcs ltdc_crtc_funcs = { .destroy = drm_crtc_cleanup, .set_config = drm_atomic_helper_set_config, diff --git a/drivers/gpu/drm/stm/ltdc.h b/drivers/gpu/drm/stm/ltdc.h index d5afb8960867..e46f477a8494 100644 --- a/drivers/gpu/drm/stm/ltdc.h +++ b/drivers/gpu/drm/stm/ltdc.h @@ -38,6 +38,11 @@ struct ltdc_device { struct fps_info plane_fpsi[LTDC_MAX_LAYER]; }; +bool ltdc_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, + bool in_vblank_irq, int *vpos, int *hpos, + ktime_t *stime, ktime_t *etime, + const struct drm_display_mode *mode); + int ltdc_load(struct drm_device *ddev); void ltdc_unload(struct drm_device *ddev); |