Skip to contentSkip to conversation

drm/msm/mdp4: only use lut_clk on mdp4.2+

PATCH In review Jonathan Marek 3 participants 13 messages Nov 22, 2018 – Dec 2, 2018

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

PATCH v2 1/9 drm/msm/mdp4: only use lut_clk on mdp4.2+

---
 drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c | 22 +++++++++++++---------
 1 file changed, 13 insertions(+), 9 deletions(-)
drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c +13 -9
index ae25d763cd8c..8f765f284d11 100644
@@ -206,7 +206,8 @@ int mdp4_disable(struct mdp4_kms *mdp4_kms)
 	clk_disable_unprepare(mdp4_kms->clk);
 	if (mdp4_kms->pclk)
 		clk_disable_unprepare(mdp4_kms->pclk);
-	clk_disable_unprepare(mdp4_kms->lut_clk);
+	if (mdp4_kms->lut_clk)
+		clk_disable_unprepare(mdp4_kms->lut_clk);
 	if (mdp4_kms->axi_clk)
 		clk_disable_unprepare(mdp4_kms->axi_clk);
 
@@ -220,7 +221,8 @@ int mdp4_enable(struct mdp4_kms *mdp4_kms)
 	clk_prepare_enable(mdp4_kms->clk);
 	if (mdp4_kms->pclk)
 		clk_prepare_enable(mdp4_kms->pclk);
-	clk_prepare_enable(mdp4_kms->lut_clk);
+	if (mdp4_kms->lut_clk)
+		clk_prepare_enable(mdp4_kms->lut_clk);
 	if (mdp4_kms->axi_clk)
 		clk_prepare_enable(mdp4_kms->axi_clk);
 
@@ -472,12 +474,13 @@ struct msm_kms *mdp4_kms_init(struct drm_device *dev)
 	if (IS_ERR(mdp4_kms->pclk))
 		mdp4_kms->pclk = NULL;
 
-	// XXX if (rev >= MDP_REV_42) { ???
-	mdp4_kms->lut_clk = devm_clk_get(&pdev->dev, "lut_clk");
-	if (IS_ERR(mdp4_kms->lut_clk)) {
-		dev_err(dev->dev, "failed to get lut_clk\n");
-		ret = PTR_ERR(mdp4_kms->lut_clk);
-		goto fail;
+	if (mdp4_kms->rev >= 2) {
+		mdp4_kms->lut_clk = devm_clk_get(&pdev->dev, "lut_clk");
+		if (IS_ERR(mdp4_kms->lut_clk)) {
+			dev_err(dev->dev, "failed to get lut_clk\n");
+			ret = PTR_ERR(mdp4_kms->lut_clk);
+			goto fail;
+		}
 	}
 
 	mdp4_kms->axi_clk = devm_clk_get(&pdev->dev, "bus_clk");
@@ -488,7 +491,8 @@ struct msm_kms *mdp4_kms_init(struct drm_device *dev)
 	}
 
 	clk_set_rate(mdp4_kms->clk, config->max_clk);
-	clk_set_rate(mdp4_kms->lut_clk, config->max_clk);
+	if (mdp4_kms->lut_clk)
+		clk_set_rate(mdp4_kms->lut_clk, config->max_clk);
 
 	pm_runtime_enable(dev->dev);
 	mdp4_kms->rpm_enabled = true;
Signature · 6 lines
2.17.1

_______________________________________________
Freedreno mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/freedreno
#1 lore raw

PATCH v2 2/9 drm/msm/mdp4: allocate blank_cursor_no with MSM_BO_SCANOUT flag

For allocation in contiguous memory when the GPU has MMU but not mdp4.

---
 drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c +1 -1
index 8f765f284d11..484d2fc2f415 100644
@@ -534,7 +534,7 @@ struct msm_kms *mdp4_kms_init(struct drm_device *dev)
 		goto fail;
 	}
 
-	mdp4_kms->blank_cursor_bo = msm_gem_new(dev, SZ_16K, MSM_BO_WC);
+	mdp4_kms->blank_cursor_bo = msm_gem_new(dev, SZ_16K, MSM_BO_WC | MSM_BO_SCANOUT);
 	if (IS_ERR(mdp4_kms->blank_cursor_bo)) {
 		ret = PTR_ERR(mdp4_kms->blank_cursor_bo);
 		dev_err(dev->dev, "could not allocate blank-cursor bo: %d\n", ret);
Signature · 6 lines
2.17.1

_______________________________________________
Freedreno mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/freedreno
#2 lore raw

PATCH v2 3/9 drm/msm/mdp4: add lcdc-align-lsb flag to control lane alignment

In reply to Jonathan Marek

Controls which of the 8 lanes are used for 6 bit color.

---
 .../gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c | 22 ++++++++++++-------
 1 file changed, 14 insertions(+), 8 deletions(-)
drivers/gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c +14 -8
index e19ab2ab63f7..7d8d11c8150a 100644
@@ -377,20 +377,26 @@ static void mdp4_lcdc_encoder_enable(struct drm_encoder *encoder)
 	unsigned long pc = mdp4_lcdc_encoder->pixclock;
 	struct mdp4_kms *mdp4_kms = get_kms(encoder);
 	struct drm_panel *panel;
+	uint32_t config;
 	int i, ret;
 
 	if (WARN_ON(mdp4_lcdc_encoder->enabled))
 		return;
 
 	/* TODO: hard-coded for 18bpp: */
-	mdp4_crtc_set_config(encoder->crtc,
-			MDP4_DMA_CONFIG_R_BPC(BPC6) |
-			MDP4_DMA_CONFIG_G_BPC(BPC6) |
-			MDP4_DMA_CONFIG_B_BPC(BPC6) |
-			MDP4_DMA_CONFIG_PACK_ALIGN_MSB |
-			MDP4_DMA_CONFIG_PACK(0x21) |
-			MDP4_DMA_CONFIG_DEFLKR_EN |
-			MDP4_DMA_CONFIG_DITHER_EN);
+	config =
+		MDP4_DMA_CONFIG_R_BPC(BPC6) |
+		MDP4_DMA_CONFIG_G_BPC(BPC6) |
+		MDP4_DMA_CONFIG_B_BPC(BPC6) |
+		MDP4_DMA_CONFIG_PACK(0x21) |
+		MDP4_DMA_CONFIG_DEFLKR_EN |
+		MDP4_DMA_CONFIG_DITHER_EN;
+
+	if (!of_find_property(dev->dev->of_node, "lcdc-align-lsb", NULL))
+		config |= MDP4_DMA_CONFIG_PACK_ALIGN_MSB;
+
+
+	mdp4_crtc_set_config(encoder->crtc, config);
 	mdp4_crtc_set_intf(encoder->crtc, INTF_LCDC_DTV, 0);
 
 	bs_set(mdp4_lcdc_encoder, 1);
Signature · 1 line
2.17.1
#3 lore raw

Re: [PATCH v2 3/9] drm/msm/mdp4: add lcdc-align-lsb flag to control lane alignment

Quoted 33 lines · Jonathan Marek

Controls which of the 8 lanes are used for 6 bit color.

---
 .../gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c | 22 ++++++++++++-------
 1 file changed, 14 insertions(+), 8 deletions(-)
drivers/gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c +3 -8
index e19ab2ab63f7..7d8d11c8150a 100644
@@ -377,20 +377,26 @@ static void mdp4_lcdc_encoder_enable(struct drm_encoder *encoder)
        unsigned long pc = mdp4_lcdc_encoder->pixclock;
        struct mdp4_kms *mdp4_kms = get_kms(encoder);
        struct drm_panel *panel;
+       uint32_t config;
        int i, ret;
 
        if (WARN_ON(mdp4_lcdc_encoder->enabled))
                return;
 
        /* TODO: hard-coded for 18bpp: */
-       mdp4_crtc_set_config(encoder->crtc,
-                       MDP4_DMA_CONFIG_R_BPC(BPC6) |
-                       MDP4_DMA_CONFIG_G_BPC(BPC6) |
-                       MDP4_DMA_CONFIG_B_BPC(BPC6) |
-                       MDP4_DMA_CONFIG_PACK_ALIGN_MSB |
-                       MDP4_DMA_CONFIG_PACK(0x21) |
-                       MDP4_DMA_CONFIG_DEFLKR_EN |
-                       MDP4_DMA_CONFIG_DITHER_EN);
+       config =
+               MDP4_DMA_CONFIG_R_BPC(BPC6) |

drivers/gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c static void mdp4_lcdc_encoder_enable(struct drm_encoder *encoder) · line 398

Quoted 10 lines
drivers/gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c +10 -0
+               MDP4_DMA_CONFIG_G_BPC(BPC6) |
+               MDP4_DMA_CONFIG_B_BPC(BPC6) |
+               MDP4_DMA_CONFIG_PACK(0x21) |
+               MDP4_DMA_CONFIG_DEFLKR_EN |
+               MDP4_DMA_CONFIG_DITHER_EN;
+
+       if (!of_find_property(dev->dev->of_node, "lcdc-align-lsb", NULL))
+               config |= MDP4_DMA_CONFIG_PACK_ALIGN_MSB;
+
+

looks reasonable, except extra newline (minor nit) and more importantly the new dt property needs to be documented (and cc'd to devicetree list)

BR,
-R

Quoted 7 lines
drivers/gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c +1 -1
+       mdp4_crtc_set_config(encoder->crtc, config);
        mdp4_crtc_set_intf(encoder->crtc, INTF_LCDC_DTV, 0);
 
        bs_set(mdp4_lcdc_encoder, 1);
--

2.17.1

_______________________________________________
Freedreno mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/freedreno

#4 lore raw

PATCH v2 4/9 drm/msm: use contiguous vram for MSM_BO_SCANOUT when possible

In reply to Jonathan Marek

Makes it possible to have MMU for GPU but not display.

---
 drivers/gpu/drm/msm/msm_gem.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/msm/msm_gem.c +1 -1
index d97f6ecb0531..6657453a3a58 100644
@@ -914,7 +914,7 @@ static struct drm_gem_object *_msm_gem_new(struct drm_device *dev,
 
 	if (!iommu_present(&platform_bus_type))
 		use_vram = true;
-	else if ((flags & MSM_BO_STOLEN) && priv->vram.size)
+	else if ((flags & (MSM_BO_STOLEN | MSM_BO_SCANOUT)) && priv->vram.size)
 		use_vram = true;
 
 	printk("_msm_gem_new %u bytes use_vram=%u\n", size, use_vram);
Signature · 6 lines
2.17.1

_______________________________________________
Freedreno mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/freedreno
#5 lore raw

PATCH v2 5/9 drm/msm: add headless gpu device (for imx5)

In reply to Jonathan Marek

This patch allows using drm/msm without qcom display hardware. This is especially useful for iMX5 hardware, which has a a2xx GPU but uses the imx-drm driver for display.

---
v2: added commit message and removed unnecessary comment

 drivers/gpu/drm/msm/Kconfig       |  4 ++--
 drivers/gpu/drm/msm/msm_debugfs.c |  2 +-
 drivers/gpu/drm/msm/msm_drv.c     | 21 +++++++++++----------
 3 files changed, 14 insertions(+), 13 deletions(-)
drivers/gpu/drm/msm/Kconfig +2 -2
index 843a9d40c05e..cf549f1ed403 100644
@@ -2,7 +2,7 @@
 config DRM_MSM
 	tristate "MSM DRM"
 	depends on DRM
-	depends on ARCH_QCOM || (ARM && COMPILE_TEST)
+	depends on ARCH_QCOM || SOC_IMX5 || (ARM && COMPILE_TEST)
 	depends on OF && COMMON_CLK
 	depends on MMU
 	select QCOM_MDT_LOADER if ARCH_QCOM
@@ -11,7 +11,7 @@ config DRM_MSM
 	select DRM_PANEL
 	select SHMEM
 	select TMPFS
-	select QCOM_SCM
+	select QCOM_SCM if ARCH_QCOM
 	select WANT_DEV_COREDUMP
 	select SND_SOC_HDMI_CODEC if SND_SOC
 	select SYNC_FILE
drivers/gpu/drm/msm/msm_debugfs.c +1 -1
index f0da0d3c8a80..1ca99ca356a4 100644
@@ -235,7 +235,7 @@ int msm_debugfs_init(struct drm_minor *minor)
 	debugfs_create_file("gpu", S_IRUSR, minor->debugfs_root,
 		dev, &msm_gpu_fops);
 
-	if (priv->kms->funcs->debugfs_init) {
+	if (priv->kms && priv->kms->funcs->debugfs_init) {
 		ret = priv->kms->funcs->debugfs_init(priv->kms, minor);
 		if (ret)
 			return ret;
drivers/gpu/drm/msm/msm_drv.c +11 -10
index 9f219e02f3c7..3f35e57202ef 100644
@@ -344,6 +344,7 @@ static int msm_drm_uninit(struct device *dev)
 	return 0;
 }
 
+#define KMS_HEADLESS 1
 #define KMS_MDP4 4
 #define KMS_MDP5 5
 #define KMS_DPU  3
@@ -495,6 +496,9 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
 	msm_gem_shrinker_init(ddev);
 
 	switch (get_mdp_ver(pdev)) {
+	case KMS_HEADLESS:
+		priv->kms = kms = NULL;
+		break;
 	case KMS_MDP4:
 		kms = mdp4_kms_init(ddev);
 		priv->kms = kms;
@@ -512,12 +516,6 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
 	}
 
 	if (IS_ERR(kms)) {
-		/*
-		 * NOTE: once we have GPU support, having no kms should not
-		 * be considered fatal.. ideally we would still support gpu
-		 * and (for example) use dmabuf/prime to share buffers with
-		 * imx drm driver on iMX5
-		 */
 		dev_err(dev, "failed to load kms\n");
 		ret = PTR_ERR(kms);
 		goto err_msm_uninit;
@@ -633,7 +631,7 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
 	drm_mode_config_reset(ddev);
 
 #ifdef CONFIG_DRM_FBDEV_EMULATION
-	if (fbdev)
+	if (kms && fbdev)
 		priv->fbdev = msm_fbdev_init(ddev);
 #endif
 
@@ -1315,9 +1313,11 @@ static int msm_pdev_probe(struct platform_device *pdev)
 	struct component_match *match = NULL;
 	int ret;
 
-	ret = add_display_components(&pdev->dev, &match);
-	if (ret)
-		return ret;
+	if (get_mdp_ver(pdev) != KMS_HEADLESS) {
+		ret = add_display_components(&pdev->dev, &match);
+		if (ret)
+			return ret;
+	}
 
 	ret = add_gpu_components(&pdev->dev, &match);
 	if (ret)
@@ -1342,6 +1342,7 @@ static int msm_pdev_remove(struct platform_device *pdev)
 }
 
 static const struct of_device_id dt_match[] = {
+	{ .compatible = "qcom,adreno-headless", .data = (void *)KMS_HEADLESS },
 	{ .compatible = "qcom,mdp4", .data = (void *)KMS_MDP4 },
 	{ .compatible = "qcom,mdss", .data = (void *)KMS_MDP5 },
 	{ .compatible = "qcom,sdm845-mdss", .data = (void *)KMS_DPU },
Signature · 1 line
2.17.1
#6 lore raw

Re: [Freedreno] [PATCH v2 5/9] drm/msm: add headless gpu device (for imx5)

Quoted 27 lines · Jonathan Marek

This patch allows using drm/msm without qcom display hardware. This is especially useful for iMX5 hardware, which has a a2xx GPU but uses the imx-drm driver for display.

---
v2: added commit message and removed unnecessary comment

 drivers/gpu/drm/msm/Kconfig       |  4 ++--
 drivers/gpu/drm/msm/msm_debugfs.c |  2 +-
 drivers/gpu/drm/msm/msm_drv.c     | 21 +++++++++++----------
 3 files changed, 14 insertions(+), 13 deletions(-)
drivers/gpu/drm/msm/Kconfig +1 -1
index 843a9d40c05e..cf549f1ed403 100644
@@ -2,7 +2,7 @@
 config DRM_MSM
 	tristate "MSM DRM"
 	depends on DRM
-	depends on ARCH_QCOM || (ARM && COMPILE_TEST)
+	depends on ARCH_QCOM || SOC_IMX5 || (ARM && COMPILE_TEST)
 	depends on OF && COMMON_CLK
 	depends on MMU
 	select QCOM_MDT_LOADER if ARCH_QCOM

drivers/gpu/drm/msm/Kconfig config DRM_MSM · line 17

Quoted 8 lines
drivers/gpu/drm/msm/Kconfig +1 -1
@@ -11,7 +11,7 @@ config DRM_MSM
 	select DRM_PANEL
 	select SHMEM
 	select TMPFS
-	select QCOM_SCM
+	select QCOM_SCM if ARCH_QCOM
 	select WANT_DEV_COREDUMP
 	select SND_SOC_HDMI_CODEC if SND_SOC
 	select SYNC_FILE

This is good - there are probably a handful of others you can add too - WANT_DEV_COREDUMP for example (at least for now) but you can audit those later as you try to cut down your binary size.

Also serves as an important reminder for the rest of us that Adreno just isn't for Snapdragon anymore.

Quoted 73 lines
drivers/gpu/drm/msm/msm_debugfs.c +1 -1
index f0da0d3c8a80..1ca99ca356a4 100644
@@ -235,7 +235,7 @@ int msm_debugfs_init(struct drm_minor *minor)
 	debugfs_create_file("gpu", S_IRUSR, minor->debugfs_root,
 		dev, &msm_gpu_fops);
 
-	if (priv->kms->funcs->debugfs_init) {
+	if (priv->kms && priv->kms->funcs->debugfs_init) {
 		ret = priv->kms->funcs->debugfs_init(priv->kms, minor);
 		if (ret)
 			return ret;
drivers/gpu/drm/msm/msm_drv.c +10 -10
index 9f219e02f3c7..3f35e57202ef 100644
@@ -344,6 +344,7 @@ static int msm_drm_uninit(struct device *dev)
 	return 0;
 }
 
+#define KMS_HEADLESS 1
 #define KMS_MDP4 4
 #define KMS_MDP5 5
 #define KMS_DPU  3
@@ -495,6 +496,9 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
 	msm_gem_shrinker_init(ddev);
 
 	switch (get_mdp_ver(pdev)) {
+	case KMS_HEADLESS:
+		priv->kms = kms = NULL;
+		break;
 	case KMS_MDP4:
 		kms = mdp4_kms_init(ddev);
 		priv->kms = kms;
@@ -512,12 +516,6 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
 	}
 
 	if (IS_ERR(kms)) {
-		/*
-		 * NOTE: once we have GPU support, having no kms should not
-		 * be considered fatal.. ideally we would still support gpu
-		 * and (for example) use dmabuf/prime to share buffers with
-		 * imx drm driver on iMX5
-		 */
 		dev_err(dev, "failed to load kms\n");
 		ret = PTR_ERR(kms);
 		goto err_msm_uninit;
@@ -633,7 +631,7 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
 	drm_mode_config_reset(ddev);
 
 #ifdef CONFIG_DRM_FBDEV_EMULATION
-	if (fbdev)
+	if (kms && fbdev)
 		priv->fbdev = msm_fbdev_init(ddev);
 #endif
 
@@ -1315,9 +1313,11 @@ static int msm_pdev_probe(struct platform_device *pdev)
 	struct component_match *match = NULL;
 	int ret;
 
-	ret = add_display_components(&pdev->dev, &match);
-	if (ret)
-		return ret;
+	if (get_mdp_ver(pdev) != KMS_HEADLESS) {
+		ret = add_display_components(&pdev->dev, &match);
+		if (ret)
+			return ret;
+	}
 
 	ret = add_gpu_components(&pdev->dev, &match);
 	if (ret)

drivers/gpu/drm/msm/msm_drv.c static int msm_pdev_remove(struct platform_device *pdev) · line 1345

Quoted 4 lines
drivers/gpu/drm/msm/msm_drv.c +1 -0
@@ -1342,6 +1342,7 @@ static int msm_pdev_remove(struct platform_device *pdev)
 }
 
 static const struct of_device_id dt_match[] = {
+	{ .compatible = "qcom,adreno-headless", .data = (void *)KMS_HEADLESS },

I feel that this should be more descriptive for your hardware and not just generic. You don't need to include the qcom, extension and you'll probably want to use a more descriptive vendor if you are adding imx5 specific data to the DT.

Quoted 5 lines
drivers/gpu/drm/msm/msm_drv.c +0 -0
 	{ .compatible = "qcom,mdp4", .data = (void *)KMS_MDP4 },
 	{ .compatible = "qcom,mdss", .data = (void *)KMS_MDP5 },
 	{ .compatible = "qcom,sdm845-mdss", .data = (void *)KMS_DPU },
Signature · 1 line
2.17.1
Signature · 6 lines
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
_______________________________________________
Freedreno mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/freedreno
#7 lore raw

Re: [Freedreno] [PATCH v2 5/9] drm/msm: add headless gpu device (for imx5)

Quoted 119 lines · Jordan Crouse
Quoted 27 lines · Jonathan Marek

This patch allows using drm/msm without qcom display hardware. This is especially useful for iMX5 hardware, which has a a2xx GPU but uses the imx-drm driver for display.

---
v2: added commit message and removed unnecessary comment

  drivers/gpu/drm/msm/Kconfig       |  4 ++--
  drivers/gpu/drm/msm/msm_debugfs.c |  2 +-
  drivers/gpu/drm/msm/msm_drv.c     | 21 +++++++++++----------
  3 files changed, 14 insertions(+), 13 deletions(-)
drivers/gpu/drm/msm/Kconfig +1 -1
index 843a9d40c05e..cf549f1ed403 100644
@@ -2,7 +2,7 @@
  config DRM_MSM
  	tristate "MSM DRM"
  	depends on DRM
-	depends on ARCH_QCOM || (ARM && COMPILE_TEST)
+	depends on ARCH_QCOM || SOC_IMX5 || (ARM && COMPILE_TEST)
  	depends on OF && COMMON_CLK
  	depends on MMU
  	select QCOM_MDT_LOADER if ARCH_QCOM

drivers/gpu/drm/msm/Kconfig config DRM_MSM · line 17

Quoted 8 lines
drivers/gpu/drm/msm/Kconfig +1 -1
@@ -11,7 +11,7 @@ config DRM_MSM
  	select DRM_PANEL
  	select SHMEM
  	select TMPFS
-	select QCOM_SCM
+	select QCOM_SCM if ARCH_QCOM
  	select WANT_DEV_COREDUMP
  	select SND_SOC_HDMI_CODEC if SND_SOC
  	select SYNC_FILE

This is good - there are probably a handful of others you can add too - WANT_DEV_COREDUMP for example (at least for now) but you can audit those later as you try to cut down your binary size.

Also serves as an important reminder for the rest of us that Adreno just isn't for Snapdragon anymore.

Quoted 75 lines
drivers/gpu/drm/msm/msm_debugfs.c +1 -1
index f0da0d3c8a80..1ca99ca356a4 100644
@@ -235,7 +235,7 @@ int msm_debugfs_init(struct drm_minor *minor)
  	debugfs_create_file("gpu", S_IRUSR, minor->debugfs_root,
  		dev, &msm_gpu_fops);
 
-	if (priv->kms->funcs->debugfs_init) {
+	if (priv->kms && priv->kms->funcs->debugfs_init) {
  		ret = priv->kms->funcs->debugfs_init(priv->kms, minor);
  		if (ret)
  			return ret;
drivers/gpu/drm/msm/msm_drv.c +10 -10
index 9f219e02f3c7..3f35e57202ef 100644
@@ -344,6 +344,7 @@ static int msm_drm_uninit(struct device *dev)
  	return 0;
  }
 
+#define KMS_HEADLESS 1
  #define KMS_MDP4 4
  #define KMS_MDP5 5
  #define KMS_DPU  3
@@ -495,6 +496,9 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
  	msm_gem_shrinker_init(ddev);
 
  	switch (get_mdp_ver(pdev)) {
+	case KMS_HEADLESS:
+		priv->kms = kms = NULL;
+		break;
  	case KMS_MDP4:
  		kms = mdp4_kms_init(ddev);
  		priv->kms = kms;
@@ -512,12 +516,6 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
  	}
 
  	if (IS_ERR(kms)) {
-		/*
-		 * NOTE: once we have GPU support, having no kms should not
-		 * be considered fatal.. ideally we would still support gpu
-		 * and (for example) use dmabuf/prime to share buffers with
-		 * imx drm driver on iMX5
-		 */
  		dev_err(dev, "failed to load kms\n");
  		ret = PTR_ERR(kms);
  		goto err_msm_uninit;
@@ -633,7 +631,7 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
  	drm_mode_config_reset(ddev);
 
  #ifdef CONFIG_DRM_FBDEV_EMULATION
-	if (fbdev)
+	if (kms && fbdev)
  		priv->fbdev = msm_fbdev_init(ddev);
  #endif
 
@@ -1315,9 +1313,11 @@ static int msm_pdev_probe(struct platform_device *pdev)
  	struct component_match *match = NULL;
  	int ret;
 
-	ret = add_display_components(&pdev->dev, &match);
-	if (ret)
-		return ret;
+	if (get_mdp_ver(pdev) != KMS_HEADLESS) {
+		ret = add_display_components(&pdev->dev, &match);
+		if (ret)
+			return ret;
+	}
 
  	ret = add_gpu_components(&pdev->dev, &match);
  	if (ret)
@@ -1342,6 +1342,7 @@ static int msm_pdev_remove(struct platform_device *pdev)
  }
 
Quoted 8 lines

drivers/gpu/drm/msm/msm_drv.c static int msm_pdev_remove(struct platform_device *pdev) · line 1345

Quoted 2 lines
drivers/gpu/drm/msm/msm_drv.c +1 -0
  static const struct of_device_id dt_match[] = {
+	{ .compatible = "qcom,adreno-headless", .data = (void *)KMS_HEADLESS },

I feel that this should be more descriptive for your hardware and not just generic. You don't need to include the qcom, extension and you'll probably want to use a more descriptive vendor if you are adding imx5 specific data to the DT.

Perhaps two entries, one for imx and one for qcom? This headless mode can be used with any adreno GPU.

Quoted 7 lines
Quoted 5 lines
drivers/gpu/drm/msm/msm_drv.c +0 -0
  	{ .compatible = "qcom,mdp4", .data = (void *)KMS_MDP4 },
  	{ .compatible = "qcom,mdss", .data = (void *)KMS_MDP5 },
  	{ .compatible = "qcom,sdm845-mdss", .data = (void *)KMS_DPU },
Signature · 1 line
2.17.1

_______________________________________________
Freedreno mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/freedreno

#8 lore raw

Re: [PATCH v2 5/9] drm/msm: add headless gpu device (for imx5)

In reply to Jonathan Marek
Quoted 109 lines · Jonathan Marek

This patch allows using drm/msm without qcom display hardware. This is especially useful for iMX5 hardware, which has a a2xx GPU but uses the imx-drm driver for display.

---
v2: added commit message and removed unnecessary comment

 drivers/gpu/drm/msm/Kconfig       |  4 ++--
 drivers/gpu/drm/msm/msm_debugfs.c |  2 +-
 drivers/gpu/drm/msm/msm_drv.c     | 21 +++++++++++----------
 3 files changed, 14 insertions(+), 13 deletions(-)
drivers/gpu/drm/msm/Kconfig +2 -2
index 843a9d40c05e..cf549f1ed403 100644
@@ -2,7 +2,7 @@
 config DRM_MSM
        tristate "MSM DRM"
        depends on DRM
-       depends on ARCH_QCOM || (ARM && COMPILE_TEST)
+       depends on ARCH_QCOM || SOC_IMX5 || (ARM && COMPILE_TEST)
        depends on OF && COMMON_CLK
        depends on MMU
        select QCOM_MDT_LOADER if ARCH_QCOM
@@ -11,7 +11,7 @@ config DRM_MSM
        select DRM_PANEL
        select SHMEM
        select TMPFS
-       select QCOM_SCM
+       select QCOM_SCM if ARCH_QCOM
        select WANT_DEV_COREDUMP
        select SND_SOC_HDMI_CODEC if SND_SOC
        select SYNC_FILE
drivers/gpu/drm/msm/msm_debugfs.c +1 -1
index f0da0d3c8a80..1ca99ca356a4 100644
@@ -235,7 +235,7 @@ int msm_debugfs_init(struct drm_minor *minor)
        debugfs_create_file("gpu", S_IRUSR, minor->debugfs_root,
                dev, &msm_gpu_fops);
 
-       if (priv->kms->funcs->debugfs_init) {
+       if (priv->kms && priv->kms->funcs->debugfs_init) {
                ret = priv->kms->funcs->debugfs_init(priv->kms, minor);
                if (ret)
                        return ret;
drivers/gpu/drm/msm/msm_drv.c +10 -10
index 9f219e02f3c7..3f35e57202ef 100644
@@ -344,6 +344,7 @@ static int msm_drm_uninit(struct device *dev)
        return 0;
 }
 
+#define KMS_HEADLESS 1
 #define KMS_MDP4 4
 #define KMS_MDP5 5
 #define KMS_DPU  3
@@ -495,6 +496,9 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
        msm_gem_shrinker_init(ddev);
 
        switch (get_mdp_ver(pdev)) {
+       case KMS_HEADLESS:
+               priv->kms = kms = NULL;
+               break;
        case KMS_MDP4:
                kms = mdp4_kms_init(ddev);
                priv->kms = kms;
@@ -512,12 +516,6 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
        }
 
        if (IS_ERR(kms)) {
-               /*
-                * NOTE: once we have GPU support, having no kms should not
-                * be considered fatal.. ideally we would still support gpu
-                * and (for example) use dmabuf/prime to share buffers with
-                * imx drm driver on iMX5
-                */
                dev_err(dev, "failed to load kms\n");
                ret = PTR_ERR(kms);
                goto err_msm_uninit;
@@ -633,7 +631,7 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
        drm_mode_config_reset(ddev);
 
 #ifdef CONFIG_DRM_FBDEV_EMULATION
-       if (fbdev)
+       if (kms && fbdev)
                priv->fbdev = msm_fbdev_init(ddev);
 #endif
 
@@ -1315,9 +1313,11 @@ static int msm_pdev_probe(struct platform_device *pdev)
        struct component_match *match = NULL;
        int ret;
 
-       ret = add_display_components(&pdev->dev, &match);
-       if (ret)
-               return ret;
+       if (get_mdp_ver(pdev) != KMS_HEADLESS) {
+               ret = add_display_components(&pdev->dev, &match);
+               if (ret)
+                       return ret;
+       }
 
        ret = add_gpu_components(&pdev->dev, &match);
        if (ret)

drivers/gpu/drm/msm/msm_drv.c static int msm_pdev_remove(struct platform_device *pdev) · line 1345

Quoted 4 lines
drivers/gpu/drm/msm/msm_drv.c +1 -0
@@ -1342,6 +1342,7 @@ static int msm_pdev_remove(struct platform_device *pdev)
 }
 
 static const struct of_device_id dt_match[] = {
+       { .compatible = "qcom,adreno-headless", .data = (void *)KMS_HEADLESS },

so, I don't really think we should have a "headless" dt node, because that doesn't really represent the hw. Maybe instead for the gpu device node, we could use a different compatible string like:

   gpu@xyz {
      compatible = "amd,imageon-205.0", "amd,imageon";
      ...
   };

(ie. amd,imageon instead of qcom,adreno)

Then in adreno_bind() (or somewhere around there), if we have the amd,imageon compat string instead of qcom,adreno, then programatically create a dummy "headless" device that the toplevel drm driver can bind to. I think something like this should be possible, and avoid needing a qcom,adreno-headless node in dt.

BR,
-R

Quoted 6 lines
drivers/gpu/drm/msm/msm_drv.c +0 -1
        { .compatible = "qcom,mdp4", .data = (void *)KMS_MDP4 },
        { .compatible = "qcom,mdss", .data = (void *)KMS_MDP5 },
        { .compatible = "qcom,sdm845-mdss", .data = (void *)KMS_DPU },
--

2.17.1

_______________________________________________
Freedreno mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/freedreno

#9 lore raw

PATCH v2 6/9 drm/msm/adreno: add a2xx

In reply to Jonathan Marek

derived from the a3xx driver and tested on the following hardware:
imx51-zii-rdu1 (a200 with 128kb gmem)
imx53-qsrb (a200)
msm8060-tenderloin (a220)

---
v2:
-fail when MMU is not present (instead of just a warning, matches a3xx) -removed whitespace and removed "XXX" in comments

 drivers/gpu/drm/msm/Makefile               |   1 +
 drivers/gpu/drm/msm/adreno/a2xx_gpu.c      | 446 +++++++++++++++++++++
 drivers/gpu/drm/msm/adreno/a2xx_gpu.h      |  21 +
 drivers/gpu/drm/msm/adreno/adreno_device.c |  33 ++
 drivers/gpu/drm/msm/adreno/adreno_gpu.c    |  27 +-
 drivers/gpu/drm/msm/adreno/adreno_gpu.h    |  15 +
 6 files changed, 535 insertions(+), 8 deletions(-)
 create mode 100644 drivers/gpu/drm/msm/adreno/a2xx_gpu.c
 create mode 100644 drivers/gpu/drm/msm/adreno/a2xx_gpu.h
drivers/gpu/drm/msm/Makefile +1 -0
index 19ab521d4c3a..0170766393ea 100644
@@ -6,6 +6,7 @@ ccflags-$(CONFIG_DRM_MSM_DSI) += -Idrivers/gpu/drm/msm/dsi
 msm-y := \
 	adreno/adreno_device.o \
 	adreno/adreno_gpu.o \
+	adreno/a2xx_gpu.o \
 	adreno/a3xx_gpu.o \
 	adreno/a4xx_gpu.o \
 	adreno/a5xx_gpu.o \
drivers/gpu/drm/msm/adreno/a2xx_gpu.c new file +446 -0

446 lines not on this page · raw message

drivers/gpu/drm/msm/adreno/a2xx_gpu.h new file +21 -0
new file mode 100644
index 000000000000..02fba2cb8932
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2018 The Linux Foundation. All rights reserved. */
+
+#ifndef __A2XX_GPU_H__
+#define __A2XX_GPU_H__
+
+#include "adreno_gpu.h"
+
+/* arrg, somehow fb.h is getting pulled in: */
+#undef ROP_COPY
+#undef ROP_XOR
+
+#include "a2xx.xml.h"
+
+struct a2xx_gpu {
+	struct adreno_gpu base;
+	bool pm_enabled;
+};
+#define to_a2xx_gpu(x) container_of(x, struct a2xx_gpu, base)
+
+#endif /* __A2XX_GPU_H__ */
drivers/gpu/drm/msm/adreno/adreno_device.c +33 -0
index 86abdb2b3a9c..6e3f78d4da5d 100644
@@ -27,6 +27,39 @@ module_param_named(hang_debug, hang_debug, bool, 0600);
 
 static const struct adreno_info gpulist[] = {
 	{
+		.rev   = ADRENO_REV(2, 0, 0, 0),
+		.revn  = 200,
+		.name  = "A200",
+		.fw = {
+			[ADRENO_FW_PM4] = "yamato_pm4.fw",
+			[ADRENO_FW_PFP] = "yamato_pfp.fw",
+		},
+		.gmem  = SZ_256K,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.init  = a2xx_gpu_init,
+	}, { /* a200 on i.mx51 has only 128kib gmem */
+		.rev   = ADRENO_REV(2, 0, 0, 1),
+		.revn  = 201,
+		.name  = "A200",
+		.fw = {
+			[ADRENO_FW_PM4] = "yamato_pm4.fw",
+			[ADRENO_FW_PFP] = "yamato_pfp.fw",
+		},
+		.gmem  = SZ_128K,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.init  = a2xx_gpu_init,
+	}, {
+		.rev   = ADRENO_REV(2, 2, 0, ANY_ID),
+		.revn  = 220,
+		.name  = "A220",
+		.fw = {
+			[ADRENO_FW_PM4] = "leia_pm4_470.fw",
+			[ADRENO_FW_PFP] = "leia_pfp_470.fw",
+		},
+		.gmem  = SZ_512K,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.init  = a2xx_gpu_init,
+	}, {
 		.rev   = ADRENO_REV(3, 0, 5, ANY_ID),
 		.revn  = 305,
 		.name  = "A305",
drivers/gpu/drm/msm/adreno/adreno_gpu.c +19 -8
index 93d70f4a2154..e09671324b05 100644
@@ -319,16 +319,27 @@ void adreno_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit,
 		 */
 		OUT_PKT3(ring, CP_EVENT_WRITE, 1);
 		OUT_RING(ring, HLSQ_FLUSH);
-
-		OUT_PKT3(ring, CP_WAIT_FOR_IDLE, 1);
-		OUT_RING(ring, 0x00000000);
 	}
 
-	/* BIT(31) of CACHE_FLUSH_TS triggers CACHE_FLUSH_TS IRQ from GPU */
-	OUT_PKT3(ring, CP_EVENT_WRITE, 3);
-	OUT_RING(ring, CACHE_FLUSH_TS | BIT(31));
-	OUT_RING(ring, rbmemptr(ring, fence));
-	OUT_RING(ring, submit->seqno);
+	/* wait for idle before cache flush/interrupt */
+	OUT_PKT3(ring, CP_WAIT_FOR_IDLE, 1);
+	OUT_RING(ring, 0x00000000);
+
+	if (!adreno_is_a2xx(adreno_gpu)) {
+		/* BIT(31) of CACHE_FLUSH_TS triggers CACHE_FLUSH_TS IRQ from GPU */
+		OUT_PKT3(ring, CP_EVENT_WRITE, 3);
+		OUT_RING(ring, CACHE_FLUSH_TS | BIT(31));
+		OUT_RING(ring, rbmemptr(ring, fence));
+		OUT_RING(ring, submit->seqno);
+	} else {
+		/* BIT(31) means something else on a2xx */
+		OUT_PKT3(ring, CP_EVENT_WRITE, 3);
+		OUT_RING(ring, CACHE_FLUSH_TS);
+		OUT_RING(ring, rbmemptr(ring, fence));
+		OUT_RING(ring, submit->seqno);
+		OUT_PKT3(ring, CP_INTERRUPT, 1);
+		OUT_RING(ring, 0x80000000);
+	}
 
 #if 0
 	if (adreno_is_a3xx(adreno_gpu)) {
drivers/gpu/drm/msm/adreno/adreno_gpu.h +15 -0
index de6e6ee42fba..4adc97a91e1d 100644
@@ -154,6 +154,20 @@ struct adreno_platform_config {
 	__ret;                                             \
 })
 
+static inline bool adreno_is_a2xx(struct adreno_gpu *gpu)
+{
+	return (gpu->revn < 300);
+}
+
+static inline bool adreno_is_a20x(struct adreno_gpu *gpu)
+{
+	return (gpu->revn < 210);
+}
+
+static inline bool adreno_is_a225(struct adreno_gpu *gpu)
+{
+	return gpu->revn == 225;
+}
 
 static inline bool adreno_is_a3xx(struct adreno_gpu *gpu)
 {
@@ -334,6 +348,7 @@ static inline void adreno_gpu_write(struct adreno_gpu *gpu,
 		gpu_write(&gpu->base, reg - 1, data);
 }
 
+struct msm_gpu *a2xx_gpu_init(struct drm_device *dev);
 struct msm_gpu *a3xx_gpu_init(struct drm_device *dev);
 struct msm_gpu *a4xx_gpu_init(struct drm_device *dev);
 struct msm_gpu *a5xx_gpu_init(struct drm_device *dev);
Signature · 6 lines
2.17.1

_______________________________________________
Freedreno mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/freedreno
#10 lore raw

PATCH v2 7/9 drm/msm: implement a2xx mmu

In reply to Jonathan Marek

A2XX has its own very simple MMU.

Added a msm_use_mmu() function because we can't rely on iommu_present to decide to use MMU or not.

---
v2:
-tlb flush from cpu every time the page table is updated -keep missing MMU error path, in case MMU init fails -small cleanup in msm_gpu_create_address_space changes -fixed whitespace issue

 drivers/gpu/drm/msm/Makefile               |   3 +-
 drivers/gpu/drm/msm/adreno/a2xx_gpu.c      |  50 ++++++++-
 drivers/gpu/drm/msm/adreno/adreno_device.c |   3 +
 drivers/gpu/drm/msm/adreno/adreno_gpu.c    |   3 +
 drivers/gpu/drm/msm/msm_drv.c              |  11 +-
 drivers/gpu/drm/msm/msm_drv.h              |   8 ++
 drivers/gpu/drm/msm/msm_gem.c              |   4 +-
 drivers/gpu/drm/msm/msm_gem_vma.c          |  23 ++++
 drivers/gpu/drm/msm/msm_gpu.c              |  31 ++++--
 drivers/gpu/drm/msm/msm_gpummu.c           | 122 +++++++++++++++++++++
 drivers/gpu/drm/msm/msm_mmu.h              |   3 +
 11 files changed, 241 insertions(+), 20 deletions(-)
 create mode 100644 drivers/gpu/drm/msm/msm_gpummu.c
drivers/gpu/drm/msm/Makefile +2 -1
index 0170766393ea..004574bc9bd3 100644
@@ -91,7 +91,8 @@ msm-y := \
 	msm_perf.o \
 	msm_rd.o \
 	msm_ringbuffer.o \
-	msm_submitqueue.o
+	msm_submitqueue.o \
+	msm_gpummu.o
 
 msm-$(CONFIG_DEBUG_FS) += adreno/a5xx_debugfs.o \
 			  disp/dpu1/dpu_dbg.o
drivers/gpu/drm/msm/adreno/a2xx_gpu.c +46 -4

79 lines not on this page · raw message

drivers/gpu/drm/msm/adreno/adreno_device.c +3 -0
index 6e3f78d4da5d..f651cd51449b 100644
@@ -307,6 +307,7 @@ static int adreno_bind(struct device *dev, struct device *master, void *data)
 	static struct adreno_platform_config config = {};
 	const struct adreno_info *info;
 	struct drm_device *drm = dev_get_drvdata(master);
+	struct msm_drm_private *priv = drm->dev_private;
 	struct msm_gpu *gpu;
 	int ret;
 
@@ -337,6 +338,8 @@ static int adreno_bind(struct device *dev, struct device *master, void *data)
 
 	dev_set_drvdata(dev, gpu);
 
+	priv->is_a2xx = config.rev.core == 2;
+
 	return 0;
 }
 
drivers/gpu/drm/msm/adreno/adreno_gpu.c +3 -0
index e09671324b05..e7848ab365bc 100644
@@ -728,6 +728,9 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,
 
 	adreno_gpu_config.va_start = SZ_16M;
 	adreno_gpu_config.va_end = 0xffffffff;
+	/* maximum range of a2xx mmu */
+	if (adreno_is_a2xx(adreno_gpu))
+		adreno_gpu_config.va_end = SZ_16M + 0xfff * SZ_64K;
 
 	adreno_gpu_config.nr_rings = nr_rings;
 
drivers/gpu/drm/msm/msm_drv.c +10 -1
index 3f35e57202ef..5d7304b5f399 100644
@@ -25,6 +25,7 @@
 #include "msm_fence.h"
 #include "msm_gpu.h"
 #include "msm_kms.h"
+#include "adreno/adreno_gpu.h"
 
 
 /*
@@ -358,6 +359,14 @@ static int get_mdp_ver(struct platform_device *pdev)
 
 #include <linux/of_address.h>
 
+bool msm_use_mmu(struct drm_device *dev)
+{
+	struct msm_drm_private *priv = dev->dev_private;
+
+	/* a2xx comes with its own MMU */
+	return priv->is_a2xx || iommu_present(&platform_bus_type);
+}
+
 static int msm_init_vram(struct drm_device *dev)
 {
 	struct msm_drm_private *priv = dev->dev_private;
@@ -396,7 +405,7 @@ static int msm_init_vram(struct drm_device *dev)
 		 * Grab the entire CMA chunk carved out in early startup in
 		 * mach-msm:
 		 */
-	} else if (!iommu_present(&platform_bus_type)) {
+	} else if (!msm_use_mmu(dev)) {
 		DRM_INFO("using %s VRAM carveout\n", vram);
 		size = memparse(vram, NULL);
 	}
drivers/gpu/drm/msm/msm_drv.h +8 -0
index 9d11f321f5a9..99a37962e92b 100644
@@ -179,6 +179,8 @@ struct msm_drm_private {
 	/* when we have more than one 'msm_gpu' these need to be an array: */
 	struct msm_gpu *gpu;
 	struct msm_file_private *lastctx;
+	/* gpu is only set on open(), but we need this info earlier */
+	bool is_a2xx;
 
 	struct drm_fb_helper *fbdev;
 
@@ -252,9 +254,15 @@ struct msm_gem_address_space *
 msm_gem_address_space_create(struct device *dev, struct iommu_domain *domain,
 		const char *name);
 
+struct msm_gem_address_space *
+msm_gem_address_space_create_a2xx(struct device *dev, struct msm_gpu *gpu,
+		const char *name, uint64_t va_start, uint64_t va_end);
+
 int msm_register_mmu(struct drm_device *dev, struct msm_mmu *mmu);
 void msm_unregister_mmu(struct drm_device *dev, struct msm_mmu *mmu);
 
+bool msm_use_mmu(struct drm_device *dev);
+
 void msm_gem_submit_free(struct msm_gem_submit *submit);
 int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
 		struct drm_file *file);
drivers/gpu/drm/msm/msm_gem.c +2 -2
index 6657453a3a58..c1ef8780f686 100644
@@ -912,7 +912,7 @@ static struct drm_gem_object *_msm_gem_new(struct drm_device *dev,
 
 	size = PAGE_ALIGN(size);
 
-	if (!iommu_present(&platform_bus_type))
+	if (!msm_use_mmu(dev))
 		use_vram = true;
 	else if ((flags & (MSM_BO_STOLEN | MSM_BO_SCANOUT)) && priv->vram.size)
 		use_vram = true;
@@ -991,7 +991,7 @@ struct drm_gem_object *msm_gem_import(struct drm_device *dev,
 	int ret, npages;
 
 	/* if we don't have IOMMU, don't bother pretending we can import: */
-	if (!iommu_present(&platform_bus_type)) {
+	if (!msm_use_mmu(dev)) {
 		dev_err(dev->dev, "cannot import without IOMMU\n");
 		return ERR_PTR(-EINVAL);
 	}
drivers/gpu/drm/msm/msm_gem_vma.c +23 -0
index ffbec224551b..8075fd699803 100644
@@ -114,3 +114,26 @@ msm_gem_address_space_create(struct device *dev, struct iommu_domain *domain,
 
 	return aspace;
 }
+
+struct msm_gem_address_space *
+msm_gem_address_space_create_a2xx(struct device *dev, struct msm_gpu *gpu,
+		const char *name, uint64_t va_start, uint64_t va_end)
+{
+	struct msm_gem_address_space *aspace;
+	u64 size = va_end - va_start;
+
+	aspace = kzalloc(sizeof(*aspace), GFP_KERNEL);
+	if (!aspace)
+		return ERR_PTR(-ENOMEM);
+
+	spin_lock_init(&aspace->lock);
+	aspace->name = name;
+	aspace->mmu = msm_gpummu_new(dev, gpu);
+
+	drm_mm_init(&aspace->mm, (va_start >> PAGE_SHIFT),
+		size >> PAGE_SHIFT);
+
+	kref_init(&aspace->kref);
+
+	return aspace;
+}
drivers/gpu/drm/msm/msm_gpu.c +19 -12
index 11aac8337066..0e08ac8160d2 100644
@@ -19,6 +19,7 @@
 #include "msm_gem.h"
 #include "msm_mmu.h"
 #include "msm_fence.h"
+#include "adreno/adreno_gpu.h"
 
 #include <generated/utsrelease.h>
 #include <linux/string_helpers.h>
@@ -800,7 +801,6 @@ static struct msm_gem_address_space *
 msm_gpu_create_address_space(struct msm_gpu *gpu, struct platform_device *pdev,
 		uint64_t va_start, uint64_t va_end)
 {
-	struct iommu_domain *iommu;
 	struct msm_gem_address_space *aspace;
 	int ret;
 
@@ -809,20 +809,27 @@ msm_gpu_create_address_space(struct msm_gpu *gpu, struct platform_device *pdev,
 	 * and have separate page tables per context.  For now, to keep things
 	 * simple and to get something working, just use a single address space:
 	 */
-	iommu = iommu_domain_alloc(&platform_bus_type);
-	if (!iommu)
-		return NULL;
-
-	iommu->geometry.aperture_start = va_start;
-	iommu->geometry.aperture_end = va_end;
-
-	dev_info(gpu->dev->dev, "%s: using IOMMU\n", gpu->name);
+	if (!adreno_is_a2xx(to_adreno_gpu(gpu))) {
+		struct iommu_domain *iommu = iommu_domain_alloc(&platform_bus_type);
+		if (!iommu)
+			return NULL;
+
+		iommu->geometry.aperture_start = va_start;
+		iommu->geometry.aperture_end = va_end;
+
+		dev_info(gpu->dev->dev, "%s: using IOMMU\n", gpu->name);
+
+		aspace = msm_gem_address_space_create(&pdev->dev, iommu, "gpu");
+		if (IS_ERR(aspace))
+			iommu_domain_free(iommu);
+	} else {
+		aspace = msm_gem_address_space_create_a2xx(&pdev->dev, gpu, "gpu",
+			va_start, va_end);
+	}
 
-	aspace = msm_gem_address_space_create(&pdev->dev, iommu, "gpu");
 	if (IS_ERR(aspace)) {
-		dev_err(gpu->dev->dev, "failed to init iommu: %ld\n",
+		dev_err(gpu->dev->dev, "failed to init mmu: %ld\n",
 			PTR_ERR(aspace));
-		iommu_domain_free(iommu);
 		return ERR_CAST(aspace);
 	}
 
drivers/gpu/drm/msm/msm_gpummu.c new file +122 -0

122 lines not on this page · raw message

drivers/gpu/drm/msm/msm_mmu.h +3 -0
index aa2c5d4580c8..c5bbb49dc1be 100644
@@ -54,4 +54,7 @@ static inline void msm_mmu_set_fault_handler(struct msm_mmu *mmu, void *arg,
 	mmu->handler = handler;
 }
 
+void msm_gpummu_params(struct msm_mmu *mmu, dma_addr_t *pt_base,
+		dma_addr_t *tran_error);
+
 #endif /* __MSM_MMU_H__ */
Signature · 6 lines
2.17.1

_______________________________________________
Freedreno mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/freedreno
#11 lore raw

PATCH v2 8/9 drm/msm/mdp5: add config for msm8917

In reply to Jonathan Marek

Add the mdp5_cfg_hw entry for MDP5 version v1.15 found on msm8917.

---
 drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c | 86 ++++++++++++++++++++++++
 1 file changed, 86 insertions(+)
drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.c +86 -0
index 824067d2d427..05ad159b6261 100644
@@ -553,6 +553,91 @@ const struct mdp5_cfg_hw msm8x96_config = {
 	.max_clk = 412500000,
 };
 
+const struct mdp5_cfg_hw msm8917_config = {
+	.name = "msm8917",
+	.mdp = {
+		.count = 1,
+		.caps = MDP_CAP_CDM,
+	},
+	.ctl = {
+		.count = 3,
+		.base = { 0x01000, 0x01200, 0x01400 },
+		.flush_hw_mask = 0xffffffff,
+	},
+	.pipe_vig = {
+		.count = 1,
+		.base = { 0x04000 },
+		.caps = MDP_PIPE_CAP_HFLIP	|
+			MDP_PIPE_CAP_VFLIP	|
+			MDP_PIPE_CAP_SCALE	|
+			MDP_PIPE_CAP_CSC	|
+			MDP_PIPE_CAP_DECIMATION	|
+			MDP_PIPE_CAP_SW_PIX_EXT	|
+			0,
+	},
+	.pipe_rgb = {
+		.count = 2,
+		.base = { 0x14000, 0x16000 },
+		.caps = MDP_PIPE_CAP_HFLIP	|
+			MDP_PIPE_CAP_VFLIP	|
+			MDP_PIPE_CAP_DECIMATION	|
+			MDP_PIPE_CAP_SW_PIX_EXT	|
+			0,
+	},
+	.pipe_dma = {
+		.count = 1,
+		.base = { 0x24000 },
+		.caps = MDP_PIPE_CAP_HFLIP	|
+			MDP_PIPE_CAP_VFLIP	|
+			MDP_PIPE_CAP_SW_PIX_EXT	|
+			0,
+	},
+	.pipe_cursor = {
+		.count = 1,
+		.base = { 0x34000 },
+		.caps = MDP_PIPE_CAP_HFLIP	|
+			MDP_PIPE_CAP_VFLIP	|
+			MDP_PIPE_CAP_SW_PIX_EXT	|
+			MDP_PIPE_CAP_CURSOR	|
+			0,
+	},
+
+	.lm = {
+		.count = 2,
+		.base = { 0x44000, 0x45000 },
+		.instances = {
+				{ .id = 0, .pp = 0, .dspp = 0,
+				  .caps = MDP_LM_CAP_DISPLAY, },
+				{ .id = 1, .pp = -1, .dspp = -1,
+				  .caps = MDP_LM_CAP_WB },
+			     },
+		.nb_stages = 8,
+		.max_width = 2048,
+		.max_height = 0xFFFF,
+	},
+	.dspp = {
+		.count = 1,
+		.base = { 0x54000 },
+
+	},
+	.pp = {
+		.count = 1,
+		.base = { 0x70000 },
+	},
+	.cdm = {
+		.count = 1,
+		.base = { 0x79200 },
+	},
+	.intf = {
+		.base = { 0x6a000, 0x6a800 },
+		.connect = {
+			[0] = INTF_DISABLED,
+			[1] = INTF_DSI,
+		},
+	},
+	.max_clk = 320000000,
+};
+
 static const struct mdp5_cfg_handler cfg_handlers[] = {
 	{ .revision = 0, .config = { .hw = &msm8x74v1_config } },
 	{ .revision = 2, .config = { .hw = &msm8x74v2_config } },
@@ -560,6 +645,7 @@ static const struct mdp5_cfg_handler cfg_handlers[] = {
 	{ .revision = 6, .config = { .hw = &msm8x16_config } },
 	{ .revision = 9, .config = { .hw = &msm8x94_config } },
 	{ .revision = 7, .config = { .hw = &msm8x96_config } },
+	{ .revision = 15, .config = { .hw = &msm8917_config } },
 };
 
 static struct mdp5_cfg_platform *mdp5_get_config(struct platform_device *dev);
Signature · 6 lines
2.17.1

_______________________________________________
Freedreno mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/freedreno
#12 lore raw

PATCH v2 9/9 drm/msm: set priv->kms to NULL before uninit

In reply to Jonathan Marek

otherwise, priv->kms is non-NULL and msm_drm_uninit will cause a panic.

---
 drivers/gpu/drm/msm/msm_drv.c | 1 +
 1 file changed, 1 insertion(+)
drivers/gpu/drm/msm/msm_drv.c +1 -0
index 5d7304b5f399..fd5769e4c42a 100644
@@ -527,6 +527,7 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
 	if (IS_ERR(kms)) {
 		dev_err(dev, "failed to load kms\n");
 		ret = PTR_ERR(kms);
+		priv->kms = NULL;
 		goto err_msm_uninit;
 	}
 
Signature · 6 lines
2.17.1

_______________________________________________
Freedreno mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/freedreno