diff options
Diffstat (limited to 'drivers/gpu/drm/stm')
-rw-r--r-- | drivers/gpu/drm/stm/drv.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/stm/dw_mipi_dsi-stm.c | 28 | ||||
-rw-r--r-- | drivers/gpu/drm/stm/ltdc.c | 65 |
3 files changed, 82 insertions, 16 deletions
diff --git a/drivers/gpu/drm/stm/drv.c b/drivers/gpu/drm/stm/drv.c index 9dee4e430de5..5a9f9aca8bc2 100644 --- a/drivers/gpu/drm/stm/drv.c +++ b/drivers/gpu/drm/stm/drv.c @@ -54,8 +54,7 @@ static int stm_gem_cma_dumb_create(struct drm_file *file, DEFINE_DRM_GEM_CMA_FOPS(drv_driver_fops); static struct drm_driver drv_driver = { - .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME | - DRIVER_ATOMIC, + .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC, .name = "stm", .desc = "STMicroelectronics SoC DRM", .date = "20170330", @@ -68,8 +67,6 @@ static struct drm_driver drv_driver = { .prime_fd_to_handle = drm_gem_prime_fd_to_handle, .gem_free_object_unlocked = drm_gem_cma_free_object, .gem_vm_ops = &drm_gem_cma_vm_ops, - .gem_prime_export = drm_gem_prime_export, - .gem_prime_import = drm_gem_prime_import, .gem_prime_get_sg_table = drm_gem_cma_prime_get_sg_table, .gem_prime_import_sg_table = drm_gem_cma_prime_import_sg_table, .gem_prime_vmap = drm_gem_cma_prime_vmap, diff --git a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c index 0ab32fee6c1b..4b165635b2d4 100644 --- a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c +++ b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c @@ -8,13 +8,17 @@ #include <linux/clk.h> #include <linux/iopoll.h> +#include <linux/mod_devicetable.h> #include <linux/module.h> +#include <linux/platform_device.h> #include <linux/regulator/consumer.h> -#include <drm/drmP.h> -#include <drm/drm_mipi_dsi.h> -#include <drm/bridge/dw_mipi_dsi.h> + #include <video/mipi_display.h> +#include <drm/bridge/dw_mipi_dsi.h> +#include <drm/drm_mipi_dsi.h> +#include <drm/drm_print.h> + #define HWVER_130 0x31333000 /* IP version 1.30 */ #define HWVER_131 0x31333100 /* IP version 1.31 */ @@ -256,8 +260,11 @@ dw_mipi_dsi_get_lane_mbps(void *priv_data, const struct drm_display_mode *mode, /* Compute requested pll out */ bpp = mipi_dsi_pixel_format_to_bpp(format); pll_out_khz = mode->clock * bpp / lanes; + /* Add 20% to pll out to be higher than pixel bw (burst mode only) */ - pll_out_khz = (pll_out_khz * 12) / 10; + if (mode_flags & MIPI_DSI_MODE_VIDEO_BURST) + pll_out_khz = (pll_out_khz * 12) / 10; + if (pll_out_khz > dsi->lane_max_kbps) { pll_out_khz = dsi->lane_max_kbps; DRM_WARN("Warning max phy mbps is used\n"); @@ -302,11 +309,24 @@ dw_mipi_dsi_get_lane_mbps(void *priv_data, const struct drm_display_mode *mode, return 0; } +static int +dw_mipi_dsi_phy_get_timing(void *priv_data, unsigned int lane_mbps, + struct dw_mipi_dsi_dphy_timing *timing) +{ + timing->clk_hs2lp = 0x40; + timing->clk_lp2hs = 0x40; + timing->data_hs2lp = 0x40; + timing->data_lp2hs = 0x40; + + return 0; +} + static const struct dw_mipi_dsi_phy_ops dw_mipi_dsi_stm_phy_ops = { .init = dw_mipi_dsi_phy_init, .power_on = dw_mipi_dsi_phy_power_on, .power_off = dw_mipi_dsi_phy_power_off, .get_lane_mbps = dw_mipi_dsi_get_lane_mbps, + .get_timing = dw_mipi_dsi_phy_get_timing, }; static struct dw_mipi_dsi_plat_data dw_mipi_dsi_stm_plat_data = { diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c index 2fe6c4a8d915..c2815e8ae1da 100644 --- a/drivers/gpu/drm/stm/ltdc.c +++ b/drivers/gpu/drm/stm/ltdc.c @@ -15,6 +15,7 @@ #include <linux/module.h> #include <linux/of_address.h> #include <linux/of_graph.h> +#include <linux/pinctrl/consumer.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> #include <linux/reset.h> @@ -26,6 +27,7 @@ #include <drm/drm_fb_cma_helper.h> #include <drm/drm_fourcc.h> #include <drm/drm_gem_cma_helper.h> +#include <drm/drm_gem_framebuffer_helper.h> #include <drm/drm_of.h> #include <drm/drm_plane_helper.h> #include <drm/drm_probe_helper.h> @@ -435,9 +437,6 @@ static void ltdc_crtc_atomic_enable(struct drm_crtc *crtc, /* Commit shadow registers = update planes at next vblank */ reg_set(ldev->regs, LTDC_SRCR, SRCR_VBR); - /* Enable LTDC */ - reg_set(ldev->regs, LTDC_GCR, GCR_LTDCEN); - drm_crtc_vblank_on(crtc); } @@ -451,9 +450,6 @@ static void ltdc_crtc_atomic_disable(struct drm_crtc *crtc, drm_crtc_vblank_off(crtc); - /* disable LTDC */ - reg_clear(ldev->regs, LTDC_GCR, GCR_LTDCEN); - /* disable IRQ */ reg_clear(ldev->regs, LTDC_IER, IER_RRIE | IER_FUIE | IER_TERRIE); @@ -922,6 +918,7 @@ static const struct drm_plane_funcs ltdc_plane_funcs = { }; static const struct drm_plane_helper_funcs ltdc_plane_helper_funcs = { + .prepare_fb = drm_gem_fb_prepare_fb, .atomic_check = ltdc_plane_atomic_check, .atomic_update = ltdc_plane_atomic_update, .atomic_disable = ltdc_plane_atomic_disable, @@ -1038,6 +1035,54 @@ static const struct drm_encoder_funcs ltdc_encoder_funcs = { .destroy = drm_encoder_cleanup, }; +static void ltdc_encoder_disable(struct drm_encoder *encoder) +{ + struct drm_device *ddev = encoder->dev; + struct ltdc_device *ldev = ddev->dev_private; + + DRM_DEBUG_DRIVER("\n"); + + /* Disable LTDC */ + reg_clear(ldev->regs, LTDC_GCR, GCR_LTDCEN); + + /* Set to sleep state the pinctrl whatever type of encoder */ + pinctrl_pm_select_sleep_state(ddev->dev); +} + +static void ltdc_encoder_enable(struct drm_encoder *encoder) +{ + struct drm_device *ddev = encoder->dev; + struct ltdc_device *ldev = ddev->dev_private; + + DRM_DEBUG_DRIVER("\n"); + + /* Enable LTDC */ + reg_set(ldev->regs, LTDC_GCR, GCR_LTDCEN); +} + +static void ltdc_encoder_mode_set(struct drm_encoder *encoder, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + struct drm_device *ddev = encoder->dev; + + DRM_DEBUG_DRIVER("\n"); + + /* + * Set to default state the pinctrl only with DPI type. + * Others types like DSI, don't need pinctrl due to + * internal bridge (the signals do not come out of the chipset). + */ + if (encoder->encoder_type == DRM_MODE_ENCODER_DPI) + pinctrl_pm_select_default_state(ddev->dev); +} + +static const struct drm_encoder_helper_funcs ltdc_encoder_helper_funcs = { + .disable = ltdc_encoder_disable, + .enable = ltdc_encoder_enable, + .mode_set = ltdc_encoder_mode_set, +}; + static int ltdc_encoder_init(struct drm_device *ddev, struct drm_bridge *bridge) { struct drm_encoder *encoder; @@ -1053,6 +1098,8 @@ static int ltdc_encoder_init(struct drm_device *ddev, struct drm_bridge *bridge) drm_encoder_init(ddev, encoder, <dc_encoder_funcs, DRM_MODE_ENCODER_DPI, NULL); + drm_encoder_helper_add(encoder, <dc_encoder_helper_funcs); + ret = drm_bridge_attach(encoder, bridge, NULL); if (ret) { drm_encoder_cleanup(encoder); @@ -1234,8 +1281,8 @@ int ltdc_load(struct drm_device *ddev) /* Add endpoints panels or bridges if any */ for (i = 0; i < MAX_ENDPOINTS; i++) { if (panel[i]) { - bridge[i] = drm_panel_bridge_add(panel[i], - DRM_MODE_CONNECTOR_DPI); + bridge[i] = drm_panel_bridge_add_typed(panel[i], + DRM_MODE_CONNECTOR_DPI); if (IS_ERR(bridge[i])) { DRM_ERROR("panel-bridge endpoint %d\n", i); ret = PTR_ERR(bridge[i]); @@ -1278,6 +1325,8 @@ int ltdc_load(struct drm_device *ddev) clk_disable_unprepare(ldev->pixel_clk); + pinctrl_pm_select_sleep_state(ddev->dev); + pm_runtime_enable(ddev->dev); return 0; |