diff options
Diffstat (limited to 'drivers/gpu/drm/sun4i')
-rw-r--r-- | drivers/gpu/drm/sun4i/Kconfig | 16 | ||||
-rw-r--r-- | drivers/gpu/drm/sun4i/sun4i_backend.c | 9 | ||||
-rw-r--r-- | drivers/gpu/drm/sun4i/sun4i_drv.c | 22 | ||||
-rw-r--r-- | drivers/gpu/drm/sun4i/sun4i_layer.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/sun4i/sun4i_lvds.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/sun4i/sun4i_rgb.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/sun4i/sun6i_drc.c | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c | 49 | ||||
-rw-r--r-- | drivers/gpu/drm/sun4i/sun8i_mixer.c | 8 |
9 files changed, 92 insertions, 28 deletions
diff --git a/drivers/gpu/drm/sun4i/Kconfig b/drivers/gpu/drm/sun4i/Kconfig index 37e90e42943f..5755f0432e77 100644 --- a/drivers/gpu/drm/sun4i/Kconfig +++ b/drivers/gpu/drm/sun4i/Kconfig @@ -17,18 +17,18 @@ config DRM_SUN4I if DRM_SUN4I config DRM_SUN4I_HDMI - tristate "Allwinner A10 HDMI Controller Support" - default DRM_SUN4I - help + tristate "Allwinner A10 HDMI Controller Support" + default DRM_SUN4I + help Choose this option if you have an Allwinner SoC with an HDMI controller. config DRM_SUN4I_HDMI_CEC - bool "Allwinner A10 HDMI CEC Support" - depends on DRM_SUN4I_HDMI - select CEC_CORE - select CEC_PIN - help + bool "Allwinner A10 HDMI CEC Support" + depends on DRM_SUN4I_HDMI + select CEC_CORE + select CEC_PIN + help Choose this option if you have an Allwinner SoC with an HDMI controller and want to use CEC. diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.c b/drivers/gpu/drm/sun4i/sun4i_backend.c index 4e29f4fe4a05..072ea113e6be 100644 --- a/drivers/gpu/drm/sun4i/sun4i_backend.c +++ b/drivers/gpu/drm/sun4i/sun4i_backend.c @@ -856,6 +856,13 @@ static int sun4i_backend_bind(struct device *dev, struct device *master, ret = PTR_ERR(backend->mod_clk); goto err_disable_bus_clk; } + + ret = clk_set_rate_exclusive(backend->mod_clk, 300000000); + if (ret) { + dev_err(dev, "Couldn't set the module clock frequency\n"); + goto err_disable_bus_clk; + } + clk_prepare_enable(backend->mod_clk); backend->ram_clk = devm_clk_get(dev, "ram"); @@ -932,6 +939,7 @@ static int sun4i_backend_bind(struct device *dev, struct device *master, err_disable_ram_clk: clk_disable_unprepare(backend->ram_clk); err_disable_mod_clk: + clk_rate_exclusive_put(backend->mod_clk); clk_disable_unprepare(backend->mod_clk); err_disable_bus_clk: clk_disable_unprepare(backend->bus_clk); @@ -952,6 +960,7 @@ static void sun4i_backend_unbind(struct device *dev, struct device *master, sun4i_backend_free_sat(dev); clk_disable_unprepare(backend->ram_clk); + clk_rate_exclusive_put(backend->mod_clk); clk_disable_unprepare(backend->mod_clk); clk_disable_unprepare(backend->bus_clk); reset_control_assert(backend->reset); diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c index 5b54eff12cc0..328272ff77d8 100644 --- a/drivers/gpu/drm/sun4i/sun4i_drv.c +++ b/drivers/gpu/drm/sun4i/sun4i_drv.c @@ -345,6 +345,27 @@ static int sun4i_drv_add_endpoints(struct device *dev, return count; } +#ifdef CONFIG_PM_SLEEP +static int sun4i_drv_drm_sys_suspend(struct device *dev) +{ + struct drm_device *drm = dev_get_drvdata(dev); + + return drm_mode_config_helper_suspend(drm); +} + +static int sun4i_drv_drm_sys_resume(struct device *dev) +{ + struct drm_device *drm = dev_get_drvdata(dev); + + return drm_mode_config_helper_resume(drm); +} +#endif + +static const struct dev_pm_ops sun4i_drv_drm_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(sun4i_drv_drm_sys_suspend, + sun4i_drv_drm_sys_resume) +}; + static int sun4i_drv_probe(struct platform_device *pdev) { struct component_match *match = NULL; @@ -417,6 +438,7 @@ static struct platform_driver sun4i_drv_platform_driver = { .driver = { .name = "sun4i-drm", .of_match_table = sun4i_drv_of_table, + .pm = &sun4i_drv_drm_pm_ops, }, }; module_platform_driver(sun4i_drv_platform_driver); diff --git a/drivers/gpu/drm/sun4i/sun4i_layer.c b/drivers/gpu/drm/sun4i/sun4i_layer.c index c04f4ba0d69d..acfbfd4463a1 100644 --- a/drivers/gpu/drm/sun4i/sun4i_layer.c +++ b/drivers/gpu/drm/sun4i/sun4i_layer.c @@ -250,11 +250,11 @@ struct drm_plane **sun4i_layers_init(struct drm_device *drm, dev_err(drm->dev, "Couldn't initialize %s plane\n", i ? "overlay" : "primary"); return ERR_CAST(layer); - }; + } layer->id = i; planes[i] = &layer->plane; - }; + } return planes; } diff --git a/drivers/gpu/drm/sun4i/sun4i_lvds.c b/drivers/gpu/drm/sun4i/sun4i_lvds.c index 25ab2ef6d545..65b7a8739666 100644 --- a/drivers/gpu/drm/sun4i/sun4i_lvds.c +++ b/drivers/gpu/drm/sun4i/sun4i_lvds.c @@ -43,7 +43,7 @@ static int sun4i_lvds_get_modes(struct drm_connector *connector) struct sun4i_lvds *lvds = drm_connector_to_sun4i_lvds(connector); - return drm_panel_get_modes(lvds->panel); + return drm_panel_get_modes(lvds->panel, connector); } static struct drm_connector_helper_funcs sun4i_lvds_con_helper_funcs = { diff --git a/drivers/gpu/drm/sun4i/sun4i_rgb.c b/drivers/gpu/drm/sun4i/sun4i_rgb.c index e74b9eddca01..b27f16af50f5 100644 --- a/drivers/gpu/drm/sun4i/sun4i_rgb.c +++ b/drivers/gpu/drm/sun4i/sun4i_rgb.c @@ -47,7 +47,7 @@ static int sun4i_rgb_get_modes(struct drm_connector *connector) struct sun4i_rgb *rgb = drm_connector_to_sun4i_rgb(connector); - return drm_panel_get_modes(rgb->panel); + return drm_panel_get_modes(rgb->panel, connector); } /* diff --git a/drivers/gpu/drm/sun4i/sun6i_drc.c b/drivers/gpu/drm/sun4i/sun6i_drc.c index f7ab72244796..4fbe9a6b5182 100644 --- a/drivers/gpu/drm/sun4i/sun6i_drc.c +++ b/drivers/gpu/drm/sun4i/sun6i_drc.c @@ -56,6 +56,13 @@ static int sun6i_drc_bind(struct device *dev, struct device *master, ret = PTR_ERR(drc->mod_clk); goto err_disable_bus_clk; } + + ret = clk_set_rate_exclusive(drc->mod_clk, 300000000); + if (ret) { + dev_err(dev, "Couldn't set the module clock frequency\n"); + goto err_disable_bus_clk; + } + clk_prepare_enable(drc->mod_clk); return 0; @@ -72,6 +79,7 @@ static void sun6i_drc_unbind(struct device *dev, struct device *master, { struct sun6i_drc *drc = dev_get_drvdata(dev); + clk_rate_exclusive_put(drc->mod_clk); clk_disable_unprepare(drc->mod_clk); clk_disable_unprepare(drc->bus_clk); reset_control_assert(drc->reset); diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c index c958ca9bae63..a75fcb113172 100644 --- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c +++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c @@ -795,7 +795,7 @@ static int sun6i_dsi_get_modes(struct drm_connector *connector) { struct sun6i_dsi *dsi = connector_to_sun6i_dsi(connector); - return drm_panel_get_modes(dsi->panel); + return drm_panel_get_modes(dsi->panel, connector); } static struct drm_connector_helper_funcs sun6i_dsi_connector_helper_funcs = { @@ -1081,6 +1081,7 @@ static const struct component_ops sun6i_dsi_ops = { static int sun6i_dsi_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; + const char *bus_clk_name = NULL; struct sun6i_dsi *dsi; struct resource *res; void __iomem *base; @@ -1094,6 +1095,10 @@ static int sun6i_dsi_probe(struct platform_device *pdev) dsi->host.ops = &sun6i_dsi_host_ops; dsi->host.dev = dev; + if (of_device_is_compatible(dev->of_node, + "allwinner,sun6i-a31-mipi-dsi")) + bus_clk_name = "bus"; + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); base = devm_ioremap_resource(dev, res); if (IS_ERR(base)) { @@ -1107,23 +1112,36 @@ static int sun6i_dsi_probe(struct platform_device *pdev) return PTR_ERR(dsi->regulator); } - dsi->regs = devm_regmap_init_mmio_clk(dev, "bus", base, - &sun6i_dsi_regmap_config); - if (IS_ERR(dsi->regs)) { - dev_err(dev, "Couldn't create the DSI encoder regmap\n"); - return PTR_ERR(dsi->regs); - } - dsi->reset = devm_reset_control_get_shared(dev, NULL); if (IS_ERR(dsi->reset)) { dev_err(dev, "Couldn't get our reset line\n"); return PTR_ERR(dsi->reset); } - dsi->mod_clk = devm_clk_get(dev, "mod"); - if (IS_ERR(dsi->mod_clk)) { - dev_err(dev, "Couldn't get the DSI mod clock\n"); - return PTR_ERR(dsi->mod_clk); + dsi->regs = devm_regmap_init_mmio(dev, base, &sun6i_dsi_regmap_config); + if (IS_ERR(dsi->regs)) { + dev_err(dev, "Couldn't init regmap\n"); + return PTR_ERR(dsi->regs); + } + + dsi->bus_clk = devm_clk_get(dev, bus_clk_name); + if (IS_ERR(dsi->bus_clk)) { + dev_err(dev, "Couldn't get the DSI bus clock\n"); + return PTR_ERR(dsi->bus_clk); + } + + ret = regmap_mmio_attach_clk(dsi->regs, dsi->bus_clk); + if (ret) + return ret; + + if (of_device_is_compatible(dev->of_node, + "allwinner,sun6i-a31-mipi-dsi")) { + dsi->mod_clk = devm_clk_get(dev, "mod"); + if (IS_ERR(dsi->mod_clk)) { + dev_err(dev, "Couldn't get the DSI mod clock\n"); + ret = PTR_ERR(dsi->mod_clk); + goto err_attach_clk; + } } /* @@ -1161,6 +1179,9 @@ err_pm_disable: pm_runtime_disable(dev); err_unprotect_clk: clk_rate_exclusive_put(dsi->mod_clk); +err_attach_clk: + if (!IS_ERR(dsi->bus_clk)) + regmap_mmio_detach_clk(dsi->regs); return ret; } @@ -1174,6 +1195,9 @@ static int sun6i_dsi_remove(struct platform_device *pdev) pm_runtime_disable(dev); clk_rate_exclusive_put(dsi->mod_clk); + if (!IS_ERR(dsi->bus_clk)) + regmap_mmio_detach_clk(dsi->regs); + return 0; } @@ -1232,6 +1256,7 @@ static const struct dev_pm_ops sun6i_dsi_pm_ops = { static const struct of_device_id sun6i_dsi_of_table[] = { { .compatible = "allwinner,sun6i-a31-mipi-dsi" }, + { .compatible = "allwinner,sun50i-a64-mipi-dsi" }, { } }; MODULE_DEVICE_TABLE(of, sun6i_dsi_of_table); diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c index 8b803eb903b8..7c24f8f832a5 100644 --- a/drivers/gpu/drm/sun4i/sun8i_mixer.c +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c @@ -286,10 +286,10 @@ static struct drm_plane **sun8i_layers_init(struct drm_device *drm, dev_err(drm->dev, "Couldn't initialize overlay plane\n"); return ERR_CAST(layer); - }; + } planes[i] = &layer->plane; - }; + } for (i = 0; i < mixer->cfg->ui_num; i++) { struct sun8i_ui_layer *layer; @@ -299,10 +299,10 @@ static struct drm_plane **sun8i_layers_init(struct drm_device *drm, dev_err(drm->dev, "Couldn't initialize %s plane\n", i ? "overlay" : "primary"); return ERR_CAST(layer); - }; + } planes[mixer->cfg->vi_num + i] = &layer->plane; - }; + } return planes; } |