Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 17162b5f authored by Clarence Ip's avatar Clarence Ip Committed by Narendra Muppalla
Browse files

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: default avatarClarence Ip <cip@codeaurora.org>
parent aa0dce92
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -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;
}
+7 −1
Original line number Diff line number Diff line
@@ -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 */
+152 −119
Original line number Diff line number Diff line
@@ -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 @@ static int _sde_kms_drm_obj_init(struct sde_kms *sde_kms)
	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);
	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 @@ static int _sde_kms_mmu_init(struct sde_kms *sde_kms)
	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 = 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(pdev, "mdp_phys", "SDE");
	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;
}
+1 −0
Original line number Diff line number Diff line
@@ -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;