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

Commit aec095ec authored by Archit Taneja's avatar Archit Taneja Committed by Rob Clark
Browse files

drm/msm/mdp5: Prepare new kms_init funcs



With MDP5 as a new device, we need to do less for MDP when initializing
modeset after all the components are bound.

Create mdp5_kms_init2/destroy2 funcs that inits modeset. These will
eventually replace the older kms_init/destroy funcs.

In the new kms_init2, the platform_device used is the one corresponding
to the new MDP5 platform_device. The new change here is that the irq is
now retrieved using irq_of_parse_and_map(), since MDP5 is a child interrupt
of the MDSS interrupt controller.

Signed-off-by: default avatarArchit Taneja <architt@codeaurora.org>
Signed-off-by: default avatarRob Clark <robdclark@gmail.com>
parent 1dd0a0b1
Loading
Loading
Loading
Loading
+115 −0
Original line number Original line Diff line number Diff line
@@ -16,6 +16,7 @@
 * this program.  If not, see <http://www.gnu.org/licenses/>.
 * this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 */


#include <linux/of_irq.h>


#include "msm_drv.h"
#include "msm_drv.h"
#include "msm_mmu.h"
#include "msm_mmu.h"
@@ -133,6 +134,17 @@ static void mdp5_kms_destroy(struct msm_kms *kms)
	kfree(mdp5_kms);
	kfree(mdp5_kms);
}
}


static void mdp5_kms_destroy2(struct msm_kms *kms)
{
	struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
	struct msm_mmu *mmu = mdp5_kms->mmu;

	if (mmu) {
		mmu->funcs->detach(mmu, iommu_ports, ARRAY_SIZE(iommu_ports));
		mmu->funcs->destroy(mmu);
	}
}

static const struct mdp_kms_funcs kms_funcs = {
static const struct mdp_kms_funcs kms_funcs = {
	.base = {
	.base = {
		.hw_init         = mdp5_hw_init,
		.hw_init         = mdp5_hw_init,
@@ -776,6 +788,109 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev)
	return ERR_PTR(ret);
	return ERR_PTR(ret);
}
}


struct msm_kms *mdp5_kms_init2(struct drm_device *dev)
{
	struct msm_drm_private *priv = dev->dev_private;
	struct platform_device *pdev;
	struct mdp5_kms *mdp5_kms;
	struct mdp5_cfg *config;
	struct msm_kms *kms;
	struct msm_mmu *mmu;
	int irq, i, ret;

	/* priv->kms would have been populated by the MDP5 driver */
	kms = priv->kms;
	if (!kms)
		return NULL;

	mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));

	mdp_kms_init(&mdp5_kms->base, &kms_funcs);

	pdev = mdp5_kms->pdev;

	irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
	if (irq < 0) {
		ret = irq;
		dev_err(&pdev->dev, "failed to get irq: %d\n", ret);
		goto fail;
	}

	kms->irq = irq;

	config = mdp5_cfg_get_config(mdp5_kms->cfg);

	/* make sure things are off before attaching iommu (bootloader could
	 * have left things on, in which case we'll start getting faults if
	 * we don't disable):
	 */
	mdp5_enable(mdp5_kms);
	for (i = 0; i < MDP5_INTF_NUM_MAX; i++) {
		if (mdp5_cfg_intf_is_virtual(config->hw->intf.connect[i]) ||
		    !config->hw->intf.base[i])
			continue;
		mdp5_write(mdp5_kms, REG_MDP5_INTF_TIMING_ENGINE_EN(i), 0);

		mdp5_write(mdp5_kms, REG_MDP5_INTF_FRAME_LINE_COUNT_EN(i), 0x3);
	}
	mdp5_disable(mdp5_kms);
	mdelay(16);

	if (config->platform.iommu) {
		mmu = msm_iommu_new(&pdev->dev, config->platform.iommu);
		if (IS_ERR(mmu)) {
			ret = PTR_ERR(mmu);
			dev_err(&pdev->dev, "failed to init iommu: %d\n", ret);
			iommu_domain_free(config->platform.iommu);
			goto fail;
		}

		ret = mmu->funcs->attach(mmu, iommu_ports,
				ARRAY_SIZE(iommu_ports));
		if (ret) {
			dev_err(&pdev->dev, "failed to attach iommu: %d\n",
				ret);
			mmu->funcs->destroy(mmu);
			goto fail;
		}
	} else {
		dev_info(&pdev->dev,
			 "no iommu, fallback to phys contig buffers for scanout\n");
		mmu = NULL;
	}
	mdp5_kms->mmu = mmu;

	mdp5_kms->id = msm_register_mmu(dev, mmu);
	if (mdp5_kms->id < 0) {
		ret = mdp5_kms->id;
		dev_err(&pdev->dev, "failed to register mdp5 iommu: %d\n", ret);
		goto fail;
	}

	ret = modeset_init(mdp5_kms);
	if (ret) {
		dev_err(&pdev->dev, "modeset_init failed: %d\n", ret);
		goto fail;
	}

	dev->mode_config.min_width = 0;
	dev->mode_config.min_height = 0;
	dev->mode_config.max_width = config->hw->lm.max_width;
	dev->mode_config.max_height = config->hw->lm.max_height;

	dev->driver->get_vblank_timestamp = mdp5_get_vblank_timestamp;
	dev->driver->get_scanout_position = mdp5_get_scanoutpos;
	dev->driver->get_vblank_counter = mdp5_get_vblank_counter;
	dev->max_vblank_count = 0xffffffff;
	dev->vblank_disable_immediate = true;

	return kms;
fail:
	if (kms)
		mdp5_kms_destroy2(kms);
	return ERR_PTR(ret);
}

static void mdp5_destroy(struct platform_device *pdev)
static void mdp5_destroy(struct platform_device *pdev)
{
{
	struct mdp5_kms *mdp5_kms = platform_get_drvdata(pdev);
	struct mdp5_kms *mdp5_kms = platform_get_drvdata(pdev);
+1 −0
Original line number Original line Diff line number Diff line
@@ -73,6 +73,7 @@ static inline void msm_kms_init(struct msm_kms *kms,


struct msm_kms *mdp4_kms_init(struct drm_device *dev);
struct msm_kms *mdp4_kms_init(struct drm_device *dev);
struct msm_kms *mdp5_kms_init(struct drm_device *dev);
struct msm_kms *mdp5_kms_init(struct drm_device *dev);
struct msm_kms *mdp5_kms_init2(struct drm_device *dev);
int msm_mdss_init(struct drm_device *dev);
int msm_mdss_init(struct drm_device *dev);
void msm_mdss_destroy(struct drm_device *dev);
void msm_mdss_destroy(struct drm_device *dev);