diff options
| author | Clarence Ip <cip@codeaurora.org> | 2016-11-24 17:06:29 -0500 |
|---|---|---|
| committer | Clarence Ip <cip@codeaurora.org> | 2016-11-25 13:33:39 -0500 |
| commit | 3537e5234a9cc8ce5a0dc970e2db87d06f423074 (patch) | |
| tree | feccda09187f0c658ca589ccf79c5b0b7a17d21d /drivers/gpu | |
| parent | 857addaf00d0b9ead743bd434e8785fd41f20c19 (diff) | |
drm/msm/sde: move sde hw init to hw_init callback
Callbacks from the upper layer expect hardware initialization
logic to reside within the hw_init callback. Consolidate all hw
initialization to the hw_init callback and update the deinit and
destroy callbacks to match it.
Change-Id: I2ab32edae0e8586ddb4701b3d8c5cfde9e611cad
Signed-off-by: Clarence Ip <cip@codeaurora.org>
Diffstat (limited to 'drivers/gpu')
| -rw-r--r-- | drivers/gpu/drm/msm/msm_drv.c | 18 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_hw_catalog.c | 4 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_hw_catalog.h | 8 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_kms.c | 271 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/sde/sde_kms.h | 1 |
5 files changed, 171 insertions, 131 deletions
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index fb03350e0132..7ed00ea06b2a 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -490,6 +490,15 @@ static int msm_load(struct drm_device *dev, unsigned long flags) } priv->kms = kms; + pm_runtime_enable(dev->dev); + + if (kms && kms->funcs && kms->funcs->hw_init) { + ret = kms->funcs->hw_init(kms); + if (ret) { + dev_err(dev->dev, "kms hw init failed: %d\n", ret); + goto fail; + } + } /* initialize commit thread structure */ for (i = 0; i < priv->num_crtcs; i++) { @@ -514,15 +523,6 @@ static int msm_load(struct drm_device *dev, unsigned long flags) } } - if (kms) { - pm_runtime_enable(dev->dev); - ret = kms->funcs->hw_init(kms); - if (ret) { - dev_err(dev->dev, "kms hw init failed: %d\n", ret); - goto fail; - } - } - dev->mode_config.funcs = &mode_config_funcs; ret = drm_vblank_init(dev, priv->num_crtcs); diff --git a/drivers/gpu/drm/msm/sde/sde_hw_catalog.c b/drivers/gpu/drm/msm/sde/sde_hw_catalog.c index f8c753d2a8dd..cc2bf7234999 100644 --- a/drivers/gpu/drm/msm/sde/sde_hw_catalog.c +++ b/drivers/gpu/drm/msm/sde/sde_hw_catalog.c @@ -1822,7 +1822,7 @@ static void sde_hardware_caps(struct sde_mdss_cfg *sde_cfg, uint32_t hw_rev) } } -static void sde_hw_catalog_deinit(struct sde_mdss_cfg *sde_cfg) +void sde_hw_catalog_deinit(struct sde_mdss_cfg *sde_cfg) { int i; @@ -1848,6 +1848,7 @@ static void sde_hw_catalog_deinit(struct sde_mdss_cfg *sde_cfg) kfree(sde_cfg->vbif[i].dynamic_ot_rd_tbl.cfg); kfree(sde_cfg->vbif[i].dynamic_ot_wr_tbl.cfg); } + kfree(sde_cfg); } /************************************************************* @@ -1913,6 +1914,5 @@ struct sde_mdss_cfg *sde_hw_catalog_init(struct drm_device *dev, u32 hw_rev) end: sde_hw_catalog_deinit(sde_cfg); - kfree(sde_cfg); return NULL; } diff --git a/drivers/gpu/drm/msm/sde/sde_hw_catalog.h b/drivers/gpu/drm/msm/sde/sde_hw_catalog.h index 5ca297a46b26..26bb832b5fa3 100644 --- a/drivers/gpu/drm/msm/sde/sde_hw_catalog.h +++ b/drivers/gpu/drm/msm/sde/sde_hw_catalog.h @@ -681,7 +681,7 @@ struct sde_mdss_hw_cfg_handler { #define BLK_AD(s) ((s)->ad) /** - * sde_hw_catalog_init() - sde hardware catalog init API parses dtsi property + * sde_hw_catalog_init - sde hardware catalog init API parses dtsi property * and stores all parsed offset, hardware capabilities in config structure. * @dev: drm device node. * @hw_rev: caller needs provide the hardware revision before parsing. @@ -690,4 +690,10 @@ struct sde_mdss_hw_cfg_handler { */ struct sde_mdss_cfg *sde_hw_catalog_init(struct drm_device *dev, u32 hw_rev); +/** + * sde_hw_catalog_deinit - sde hardware catalog cleanup + * @sde_cfg: pointer returned from init function + */ +void sde_hw_catalog_deinit(struct sde_mdss_cfg *sde_cfg); + #endif /* _SDE_HW_CATALOG_H */ diff --git a/drivers/gpu/drm/msm/sde/sde_kms.c b/drivers/gpu/drm/msm/sde/sde_kms.c index c834f6dad83a..1b523767f523 100644 --- a/drivers/gpu/drm/msm/sde/sde_kms.c +++ b/drivers/gpu/drm/msm/sde/sde_kms.c @@ -70,6 +70,9 @@ static bool sdecustom = true; module_param(sdecustom, bool, 0400); MODULE_PARM_DESC(sdecustom, "Enable customizations for sde clients"); +static int sde_kms_hw_init(struct msm_kms *kms); +static int _sde_kms_mmu_destroy(struct sde_kms *sde_kms); + bool sde_is_custom_client(void) { return sdecustom; @@ -567,15 +570,21 @@ static void _sde_kms_drm_obj_destroy(struct sde_kms *sde_kms) for (i = 0; i < priv->num_crtcs; i++) priv->crtcs[i]->funcs->destroy(priv->crtcs[i]); + priv->num_crtcs = 0; for (i = 0; i < priv->num_planes; i++) priv->planes[i]->funcs->destroy(priv->planes[i]); + priv->num_planes = 0; for (i = 0; i < priv->num_connectors; i++) priv->connectors[i]->funcs->destroy(priv->connectors[i]); + priv->num_connectors = 0; for (i = 0; i < priv->num_encoders; i++) priv->encoders[i]->funcs->destroy(priv->encoders[i]); + priv->num_encoders = 0; + + _sde_kms_release_displays(sde_kms); } static int _sde_kms_drm_obj_init(struct sde_kms *sde_kms) @@ -660,11 +669,6 @@ fail: return ret; } -static int sde_kms_hw_init(struct msm_kms *kms) -{ - return 0; -} - static int sde_kms_postinit(struct msm_kms *kms) { struct sde_kms *sde_kms = to_sde_kms(kms); @@ -691,11 +695,34 @@ static long sde_kms_round_pixclk(struct msm_kms *kms, unsigned long rate, return rate; } -static void sde_kms_destroy(struct msm_kms *kms) +static void _sde_kms_hw_destroy(struct sde_kms *sde_kms, + struct platform_device *pdev) { - struct sde_kms *sde_kms = to_sde_kms(kms); + struct drm_device *dev; + struct msm_drm_private *priv; int i; + if (!sde_kms || !pdev) + return; + + dev = sde_kms->dev; + if (!dev) + return; + + priv = dev->dev_private; + if (!priv) + return; + + if (sde_kms->hw_intr) + sde_hw_intr_destroy(sde_kms->hw_intr); + sde_kms->hw_intr = NULL; + + _sde_kms_release_displays(sde_kms); + + /* safe to call these more than once during shutdown */ + _sde_debugfs_destroy(sde_kms); + _sde_kms_mmu_destroy(sde_kms); + for (i = 0; i < sde_kms->catalog->vbif_count; i++) { u32 vbif_idx = sde_kms->catalog->vbif[i].id; @@ -703,10 +730,49 @@ static void sde_kms_destroy(struct msm_kms *kms) sde_hw_vbif_destroy(sde_kms->hw_vbif[vbif_idx]); } - _sde_kms_release_displays(sde_kms); - _sde_debugfs_destroy(sde_kms); - sde_hw_intr_destroy(sde_kms->hw_intr); - sde_rm_destroy(&sde_kms->rm); + if (sde_kms->rm_init) + sde_rm_destroy(&sde_kms->rm); + sde_kms->rm_init = false; + + if (sde_kms->catalog) + sde_hw_catalog_deinit(sde_kms->catalog); + sde_kms->catalog = NULL; + + if (sde_kms->core_client) + sde_power_client_destroy(&priv->phandle, sde_kms->core_client); + sde_kms->core_client = NULL; + + if (sde_kms->vbif[VBIF_NRT]) + msm_iounmap(pdev, sde_kms->vbif[VBIF_NRT]); + sde_kms->vbif[VBIF_NRT] = NULL; + + if (sde_kms->vbif[VBIF_RT]) + msm_iounmap(pdev, sde_kms->vbif[VBIF_RT]); + sde_kms->vbif[VBIF_RT] = NULL; + + if (sde_kms->mmio) + msm_iounmap(pdev, sde_kms->mmio); + sde_kms->mmio = NULL; +} + +static void sde_kms_destroy(struct msm_kms *kms) +{ + struct sde_kms *sde_kms; + struct drm_device *dev; + + if (!kms) { + SDE_ERROR("invalid kms\n"); + return; + } + + sde_kms = to_sde_kms(kms); + dev = sde_kms->dev; + if (!dev) { + SDE_ERROR("invalid device\n"); + return; + } + + _sde_kms_hw_destroy(sde_kms, dev->platformdev); kfree(sde_kms); } @@ -743,7 +809,7 @@ static const struct msm_kms_funcs kms_funcs = { }; /* the caller api needs to turn on clock before calling it */ -static void _sde_kms_core_hw_rev_init(struct sde_kms *sde_kms) +static inline void _sde_kms_core_hw_rev_init(struct sde_kms *sde_kms) { sde_kms->core_rev = readl_relaxed(sde_kms->mmio + 0x0); } @@ -811,112 +877,69 @@ fail: return ret; } -static struct sde_kms *_sde_kms_hw_setup(struct platform_device *pdev) +static int sde_kms_hw_init(struct msm_kms *kms) { struct sde_kms *sde_kms; - int ret = 0; + struct drm_device *dev; + struct msm_drm_private *priv; + int i, rc = -EINVAL; - sde_kms = kzalloc(sizeof(*sde_kms), GFP_KERNEL); - if (!sde_kms) - return ERR_PTR(-ENOMEM); + if (!kms) { + SDE_ERROR("invalid kms\n"); + goto end; + } - sde_kms->mmio = msm_ioremap(pdev, "mdp_phys", "SDE"); + sde_kms = to_sde_kms(kms); + dev = sde_kms->dev; + if (!dev || !dev->platformdev) { + SDE_ERROR("invalid device\n"); + goto end; + } + + priv = dev->dev_private; + if (!priv) { + SDE_ERROR("invalid private data\n"); + goto end; + } + + sde_kms->mmio = msm_ioremap(dev->platformdev, "mdp_phys", "SDE"); if (IS_ERR(sde_kms->mmio)) { - ret = PTR_ERR(sde_kms->mmio); - SDE_ERROR("mdp register memory map failed: %d\n", ret); + rc = PTR_ERR(sde_kms->mmio); + SDE_ERROR("mdp register memory map failed: %d\n", rc); sde_kms->mmio = NULL; - goto err; + goto error; } DRM_INFO("mapped mdp address space @%p\n", sde_kms->mmio); - sde_kms->vbif[VBIF_RT] = msm_ioremap(pdev, "vbif_phys", "VBIF"); + sde_kms->vbif[VBIF_RT] = msm_ioremap(dev->platformdev, + "vbif_phys", "VBIF"); if (IS_ERR(sde_kms->vbif[VBIF_RT])) { - ret = PTR_ERR(sde_kms->vbif[VBIF_RT]); - SDE_ERROR("vbif register memory map failed: %d\n", ret); + rc = PTR_ERR(sde_kms->vbif[VBIF_RT]); + SDE_ERROR("vbif register memory map failed: %d\n", rc); sde_kms->vbif[VBIF_RT] = NULL; - goto vbif_map_err; + goto error; } - sde_kms->vbif[VBIF_NRT] = msm_ioremap(pdev, "vbif_nrt_phys", - "VBIF_NRT"); + sde_kms->vbif[VBIF_NRT] = msm_ioremap(dev->platformdev, + "vbif_nrt_phys", "VBIF_NRT"); if (IS_ERR(sde_kms->vbif[VBIF_NRT])) { sde_kms->vbif[VBIF_NRT] = NULL; SDE_DEBUG("VBIF NRT is not defined"); } - /* junk API - no error return for init api */ - msm_kms_init(&sde_kms->base, &kms_funcs); - if (ret) { - SDE_ERROR("mdp/kms hw init failed\n"); - goto kms_init_err; - } - - SDE_DEBUG("sde hw setup successful\n"); - - return sde_kms; - -kms_init_err: - if (sde_kms->vbif[VBIF_NRT]) - msm_iounmap(pdev, sde_kms->vbif[VBIF_NRT]); - if (sde_kms->vbif[VBIF_RT]) - msm_iounmap(pdev, sde_kms->vbif[VBIF_RT]); -vbif_map_err: - if (sde_kms->mmio) - msm_iounmap(pdev, sde_kms->mmio); -err: - kfree(sde_kms); - return ERR_PTR(ret); -} - -static void _sde_kms_hw_destroy(struct sde_kms *sde_kms, - struct platform_device *pdev) -{ - if (sde_kms->vbif[VBIF_NRT]) - msm_iounmap(pdev, sde_kms->vbif[VBIF_NRT]); - if (sde_kms->vbif[VBIF_RT]) - msm_iounmap(pdev, sde_kms->vbif[VBIF_RT]); - if (sde_kms->mmio) - msm_iounmap(pdev, sde_kms->mmio); - kfree(sde_kms); -} - -struct msm_kms *sde_kms_init(struct drm_device *dev) -{ - struct msm_drm_private *priv; - struct sde_kms *sde_kms; - int i; - int rc; - - if (!dev) { - SDE_ERROR("drm device node invalid\n"); - rc = -EINVAL; - goto end; - } - - priv = dev->dev_private; - sde_kms = _sde_kms_hw_setup(dev->platformdev); - if (IS_ERR_OR_NULL(sde_kms)) { - rc = PTR_ERR(sde_kms); - SDE_ERROR("sde hw setup failed: %d\n", rc); - goto end; - } - - sde_kms->dev = dev; - priv->kms = &sde_kms->base; - sde_kms->core_client = sde_power_client_create(&priv->phandle, "core"); if (IS_ERR_OR_NULL(sde_kms->core_client)) { rc = PTR_ERR(sde_kms->core_client); SDE_ERROR("sde power client create failed: %d\n", rc); sde_kms->core_client = NULL; - goto kms_destroy; + goto error; } rc = sde_power_resource_enable(&priv->phandle, sde_kms->core_client, true); if (rc) { SDE_ERROR("resource enable failed: %d\n", rc); - goto clk_enable_err; + goto error; } _sde_kms_core_hw_rev_init(sde_kms); @@ -928,20 +951,24 @@ struct msm_kms *sde_kms_init(struct drm_device *dev) rc = PTR_ERR(sde_kms->catalog); SDE_ERROR("catalog init failed: %d\n", rc); sde_kms->catalog = NULL; - goto catalog_err; + goto power_error; } rc = sde_rm_init(&sde_kms->rm, sde_kms->catalog, sde_kms->mmio, sde_kms->dev); - if (rc) - goto rm_init_err; + if (rc) { + SDE_ERROR("rm init failed: %d\n", rc); + goto power_error; + } + + sde_kms->rm_init = true; sde_kms->hw_mdp = sde_rm_get_mdp(&sde_kms->rm); if (IS_ERR_OR_NULL(sde_kms->hw_mdp)) { rc = PTR_ERR(sde_kms->hw_mdp); SDE_ERROR("failed to get hw_mdp: %d\n", rc); sde_kms->hw_mdp = NULL; - goto mdp_top_init_err; + goto power_error; } for (i = 0; i < sde_kms->catalog->vbif_count; i++) { @@ -953,7 +980,7 @@ struct msm_kms *sde_kms_init(struct drm_device *dev) rc = PTR_ERR(sde_kms->hw_vbif[vbif_idx]); SDE_ERROR("failed to init vbif %d: %d\n", vbif_idx, rc); sde_kms->hw_vbif[vbif_idx] = NULL; - goto vbif_init_err; + goto power_error; } } @@ -964,7 +991,7 @@ struct msm_kms *sde_kms_init(struct drm_device *dev) rc = _sde_kms_mmu_init(sde_kms); if (rc) { SDE_ERROR("sde_kms_mmu_init failed: %d\n", rc); - goto mmu_init_err; + goto power_error; } /* @@ -974,7 +1001,7 @@ struct msm_kms *sde_kms_init(struct drm_device *dev) rc = _sde_debugfs_init(sde_kms); if (rc) { SDE_ERROR("sde_debugfs init failed: %d\n", rc); - goto debugfs_init_err; + goto power_error; } /* @@ -984,7 +1011,7 @@ struct msm_kms *sde_kms_init(struct drm_device *dev) rc = _sde_kms_drm_obj_init(sde_kms); if (rc) { SDE_ERROR("modeset init failed: %d\n", rc); - goto drm_obj_init_err; + goto power_error; } dev->mode_config.min_width = 0; @@ -1011,32 +1038,38 @@ struct msm_kms *sde_kms_init(struct drm_device *dev) } sde_power_resource_enable(&priv->phandle, sde_kms->core_client, false); - - return &sde_kms->base; + return 0; hw_intr_init_err: _sde_kms_drm_obj_destroy(sde_kms); -drm_obj_init_err: - _sde_debugfs_destroy(sde_kms); -debugfs_init_err: -mmu_init_err: - _sde_kms_mmu_destroy(sde_kms); -vbif_init_err: - for (i = 0; i < sde_kms->catalog->vbif_count; i++) { - u32 vbif_idx = sde_kms->catalog->vbif[i].id; - - if ((vbif_idx < VBIF_MAX) && sde_kms->hw_vbif[vbif_idx]) - sde_hw_vbif_destroy(sde_kms->hw_vbif[vbif_idx]); - } -mdp_top_init_err: - sde_rm_destroy(&sde_kms->rm); -rm_init_err: -catalog_err: +power_error: sde_power_resource_enable(&priv->phandle, sde_kms->core_client, false); -clk_enable_err: - sde_power_client_destroy(&priv->phandle, sde_kms->core_client); -kms_destroy: +error: _sde_kms_hw_destroy(sde_kms, dev->platformdev); end: - return ERR_PTR(rc); + return rc; +} + +struct msm_kms *sde_kms_init(struct drm_device *dev) +{ + struct msm_drm_private *priv; + struct sde_kms *sde_kms; + + if (!dev || !dev->dev_private) { + SDE_ERROR("drm device node invalid\n"); + return ERR_PTR(-EINVAL); + } + + priv = dev->dev_private; + + sde_kms = kzalloc(sizeof(*sde_kms), GFP_KERNEL); + if (!sde_kms) { + SDE_ERROR("failed to allocate sde kms\n"); + return ERR_PTR(-ENOMEM); + } + + msm_kms_init(&sde_kms->base, &kms_funcs); + sde_kms->dev = dev; + + return &sde_kms->base; } diff --git a/drivers/gpu/drm/msm/sde/sde_kms.h b/drivers/gpu/drm/msm/sde/sde_kms.h index af5c9538f75b..ea2d6841d11c 100644 --- a/drivers/gpu/drm/msm/sde/sde_kms.h +++ b/drivers/gpu/drm/msm/sde/sde_kms.h @@ -135,6 +135,7 @@ struct sde_kms { struct sde_irq irq_obj; struct sde_rm rm; + bool rm_init; struct sde_hw_vbif *hw_vbif[VBIF_MAX]; struct sde_hw_mdp *hw_mdp; |
