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>
This commit is contained in:
parent
857addaf00
commit
3537e5234a
5 changed files with 177 additions and 137 deletions
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
||||
sde_kms = kzalloc(sizeof(*sde_kms), GFP_KERNEL);
|
||||
if (!sde_kms)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
sde_kms->mmio = msm_ioremap(pdev, "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);
|
||||
sde_kms->mmio = NULL;
|
||||
goto err;
|
||||
}
|
||||
DRM_INFO("mapped mdp address space @%p\n", sde_kms->mmio);
|
||||
|
||||
sde_kms->vbif[VBIF_RT] = msm_ioremap(pdev, "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);
|
||||
sde_kms->vbif[VBIF_RT] = NULL;
|
||||
goto vbif_map_err;
|
||||
}
|
||||
|
||||
sde_kms->vbif[VBIF_NRT] = msm_ioremap(pdev, "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 drm_device *dev;
|
||||
struct msm_drm_private *priv;
|
||||
struct sde_kms *sde_kms;
|
||||
int i;
|
||||
int rc;
|
||||
int i, rc = -EINVAL;
|
||||
|
||||
if (!dev) {
|
||||
SDE_ERROR("drm device node invalid\n");
|
||||
rc = -EINVAL;
|
||||
if (!kms) {
|
||||
SDE_ERROR("invalid kms\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
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;
|
||||
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);
|
||||
if (!priv) {
|
||||
SDE_ERROR("invalid private data\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
sde_kms->dev = dev;
|
||||
priv->kms = &sde_kms->base;
|
||||
sde_kms->mmio = msm_ioremap(dev->platformdev, "mdp_phys", "SDE");
|
||||
if (IS_ERR(sde_kms->mmio)) {
|
||||
rc = PTR_ERR(sde_kms->mmio);
|
||||
SDE_ERROR("mdp register memory map failed: %d\n", rc);
|
||||
sde_kms->mmio = NULL;
|
||||
goto error;
|
||||
}
|
||||
DRM_INFO("mapped mdp address space @%p\n", sde_kms->mmio);
|
||||
|
||||
sde_kms->vbif[VBIF_RT] = msm_ioremap(dev->platformdev,
|
||||
"vbif_phys", "VBIF");
|
||||
if (IS_ERR(sde_kms->vbif[VBIF_RT])) {
|
||||
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 error;
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue