diff options
author | Takashi Iwai <tiwai@suse.de> | 2020-04-24 09:22:16 +0300 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2020-04-24 09:22:55 +0300 |
commit | 36dbae9945322e660795e73ffc8ed8ae4f25d13d (patch) | |
tree | 9e444e68380061dccfaa453d1f02cf21c5c986ef /drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c | |
parent | 14ff6c5546e7d98f8326d9ee7a75b79de9874efb (diff) | |
parent | 0d283287a42027e8a618bcdf17b79578041ebabd (diff) | |
download | linux-36dbae9945322e660795e73ffc8ed8ae4f25d13d.tar.xz |
Merge branch 'topic/nhlt' into for-next
Merge NHLT init cleanup.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c')
-rw-r--r-- | drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c | 129 |
1 files changed, 50 insertions, 79 deletions
diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c index a75fcb113172..059939789730 100644 --- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c +++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c @@ -14,7 +14,6 @@ #include <linux/phy/phy-mipi-dphy.h> #include <linux/phy/phy.h> #include <linux/platform_device.h> -#include <linux/pm_runtime.h> #include <linux/regmap.h> #include <linux/regulator/consumer.h> #include <linux/reset.h> @@ -27,7 +26,6 @@ #include <drm/drm_probe_helper.h> #include "sun4i_crtc.h" -#include "sun4i_drv.h" #include "sun4i_tcon.h" #include "sun6i_mipi_dsi.h" @@ -722,10 +720,31 @@ static void sun6i_dsi_encoder_enable(struct drm_encoder *encoder) union phy_configure_opts opts = { 0 }; struct phy_configure_opts_mipi_dphy *cfg = &opts.mipi_dphy; u16 delay; + int err; DRM_DEBUG_DRIVER("Enabling DSI output\n"); - pm_runtime_get_sync(dsi->dev); + err = regulator_enable(dsi->regulator); + if (err) + dev_warn(dsi->dev, "failed to enable VCC-DSI supply: %d\n", err); + + reset_control_deassert(dsi->reset); + clk_prepare_enable(dsi->mod_clk); + + /* + * Enable the DSI block. + */ + regmap_write(dsi->regs, SUN6I_DSI_CTL_REG, SUN6I_DSI_CTL_EN); + + regmap_write(dsi->regs, SUN6I_DSI_BASIC_CTL0_REG, + SUN6I_DSI_BASIC_CTL0_ECC_EN | SUN6I_DSI_BASIC_CTL0_CRC_EN); + + regmap_write(dsi->regs, SUN6I_DSI_TRANS_START_REG, 10); + regmap_write(dsi->regs, SUN6I_DSI_TRANS_ZERO_REG, 0); + + sun6i_dsi_inst_init(dsi, dsi->device); + + regmap_write(dsi->regs, SUN6I_DSI_DEBUG_DATA_REG, 0xff); delay = sun6i_dsi_get_video_start_delay(dsi, mode); regmap_write(dsi->regs, SUN6I_DSI_BASIC_CTL1_REG, @@ -749,7 +768,7 @@ static void sun6i_dsi_encoder_enable(struct drm_encoder *encoder) phy_configure(dsi->dphy, &opts); phy_power_on(dsi->dphy); - if (!IS_ERR(dsi->panel)) + if (dsi->panel) drm_panel_prepare(dsi->panel); /* @@ -764,7 +783,7 @@ static void sun6i_dsi_encoder_enable(struct drm_encoder *encoder) * ordering on the panels I've tested it with, so I guess this * will do for now, until that IP is better understood. */ - if (!IS_ERR(dsi->panel)) + if (dsi->panel) drm_panel_enable(dsi->panel); sun6i_dsi_start(dsi, DSI_START_HSC); @@ -780,7 +799,7 @@ static void sun6i_dsi_encoder_disable(struct drm_encoder *encoder) DRM_DEBUG_DRIVER("Disabling DSI output\n"); - if (!IS_ERR(dsi->panel)) { + if (dsi->panel) { drm_panel_disable(dsi->panel); drm_panel_unprepare(dsi->panel); } @@ -788,7 +807,9 @@ static void sun6i_dsi_encoder_disable(struct drm_encoder *encoder) phy_power_off(dsi->dphy); phy_exit(dsi->dphy); - pm_runtime_put(dsi->dev); + clk_disable_unprepare(dsi->mod_clk); + reset_control_assert(dsi->reset); + regulator_disable(dsi->regulator); } static int sun6i_dsi_get_modes(struct drm_connector *connector) @@ -805,7 +826,10 @@ static struct drm_connector_helper_funcs sun6i_dsi_connector_helper_funcs = { static enum drm_connector_status sun6i_dsi_connector_detect(struct drm_connector *connector, bool force) { - return connector_status_connected; + struct sun6i_dsi *dsi = connector_to_sun6i_dsi(connector); + + return dsi->panel ? connector_status_connected : + connector_status_disconnected; } static const struct drm_connector_funcs sun6i_dsi_connector_funcs = { @@ -942,11 +966,18 @@ static int sun6i_dsi_attach(struct mipi_dsi_host *host, struct mipi_dsi_device *device) { struct sun6i_dsi *dsi = host_to_sun6i_dsi(host); + struct drm_panel *panel = of_drm_find_panel(device->dev.of_node); + if (IS_ERR(panel)) + return PTR_ERR(panel); + if (!dsi->drm || !dsi->drm->registered) + return -EPROBE_DEFER; + + dsi->panel = panel; dsi->device = device; - dsi->panel = of_drm_find_panel(device->dev.of_node); - if (IS_ERR(dsi->panel)) - return PTR_ERR(dsi->panel); + + drm_panel_attach(dsi->panel, &dsi->connector); + drm_kms_helper_hotplug_event(dsi->drm); dev_info(host->dev, "Attached device %s\n", device->name); @@ -957,10 +988,14 @@ static int sun6i_dsi_detach(struct mipi_dsi_host *host, struct mipi_dsi_device *device) { struct sun6i_dsi *dsi = host_to_sun6i_dsi(host); + struct drm_panel *panel = dsi->panel; dsi->panel = NULL; dsi->device = NULL; + drm_panel_detach(panel); + drm_kms_helper_hotplug_event(dsi->drm); + return 0; } @@ -1022,15 +1057,9 @@ static int sun6i_dsi_bind(struct device *dev, struct device *master, void *data) { struct drm_device *drm = data; - struct sun4i_drv *drv = drm->dev_private; struct sun6i_dsi *dsi = dev_get_drvdata(dev); int ret; - if (!dsi->panel) - return -EPROBE_DEFER; - - dsi->drv = drv; - drm_encoder_helper_add(&dsi->encoder, &sun6i_dsi_enc_helper_funcs); ret = drm_encoder_init(drm, @@ -1056,7 +1085,8 @@ static int sun6i_dsi_bind(struct device *dev, struct device *master, } drm_connector_attach_encoder(&dsi->connector, &dsi->encoder); - drm_panel_attach(dsi->panel, &dsi->connector); + + dsi->drm = drm; return 0; @@ -1070,7 +1100,7 @@ static void sun6i_dsi_unbind(struct device *dev, struct device *master, { struct sun6i_dsi *dsi = dev_get_drvdata(dev); - drm_panel_detach(dsi->panel); + dsi->drm = NULL; } static const struct component_ops sun6i_dsi_ops = { @@ -1157,12 +1187,10 @@ static int sun6i_dsi_probe(struct platform_device *pdev) goto err_unprotect_clk; } - pm_runtime_enable(dev); - ret = mipi_dsi_host_register(&dsi->host); if (ret) { dev_err(dev, "Couldn't register MIPI-DSI host\n"); - goto err_pm_disable; + goto err_unprotect_clk; } ret = component_add(&pdev->dev, &sun6i_dsi_ops); @@ -1175,8 +1203,6 @@ static int sun6i_dsi_probe(struct platform_device *pdev) err_remove_dsi_host: mipi_dsi_host_unregister(&dsi->host); -err_pm_disable: - pm_runtime_disable(dev); err_unprotect_clk: clk_rate_exclusive_put(dsi->mod_clk); err_attach_clk: @@ -1192,7 +1218,6 @@ static int sun6i_dsi_remove(struct platform_device *pdev) component_del(&pdev->dev, &sun6i_dsi_ops); mipi_dsi_host_unregister(&dsi->host); - pm_runtime_disable(dev); clk_rate_exclusive_put(dsi->mod_clk); if (!IS_ERR(dsi->bus_clk)) @@ -1201,59 +1226,6 @@ static int sun6i_dsi_remove(struct platform_device *pdev) return 0; } -static int __maybe_unused sun6i_dsi_runtime_resume(struct device *dev) -{ - struct sun6i_dsi *dsi = dev_get_drvdata(dev); - int err; - - err = regulator_enable(dsi->regulator); - if (err) { - dev_err(dsi->dev, "failed to enable VCC-DSI supply: %d\n", err); - return err; - } - - reset_control_deassert(dsi->reset); - clk_prepare_enable(dsi->mod_clk); - - /* - * Enable the DSI block. - * - * Some part of it can only be done once we get a number of - * lanes, see sun6i_dsi_inst_init - */ - regmap_write(dsi->regs, SUN6I_DSI_CTL_REG, SUN6I_DSI_CTL_EN); - - regmap_write(dsi->regs, SUN6I_DSI_BASIC_CTL0_REG, - SUN6I_DSI_BASIC_CTL0_ECC_EN | SUN6I_DSI_BASIC_CTL0_CRC_EN); - - regmap_write(dsi->regs, SUN6I_DSI_TRANS_START_REG, 10); - regmap_write(dsi->regs, SUN6I_DSI_TRANS_ZERO_REG, 0); - - if (dsi->device) - sun6i_dsi_inst_init(dsi, dsi->device); - - regmap_write(dsi->regs, SUN6I_DSI_DEBUG_DATA_REG, 0xff); - - return 0; -} - -static int __maybe_unused sun6i_dsi_runtime_suspend(struct device *dev) -{ - struct sun6i_dsi *dsi = dev_get_drvdata(dev); - - clk_disable_unprepare(dsi->mod_clk); - reset_control_assert(dsi->reset); - regulator_disable(dsi->regulator); - - return 0; -} - -static const struct dev_pm_ops sun6i_dsi_pm_ops = { - SET_RUNTIME_PM_OPS(sun6i_dsi_runtime_suspend, - sun6i_dsi_runtime_resume, - NULL) -}; - static const struct of_device_id sun6i_dsi_of_table[] = { { .compatible = "allwinner,sun6i-a31-mipi-dsi" }, { .compatible = "allwinner,sun50i-a64-mipi-dsi" }, @@ -1267,7 +1239,6 @@ static struct platform_driver sun6i_dsi_platform_driver = { .driver = { .name = "sun6i-mipi-dsi", .of_match_table = sun6i_dsi_of_table, - .pm = &sun6i_dsi_pm_ops, }, }; module_platform_driver(sun6i_dsi_platform_driver); |