[PATCH v2 30/59] drm/kmb: call bridge init in the very beginning

Anitha Chrisanthus anitha.chrisanthus at intel.com
Tue Jul 14 20:57:16 UTC 2020


of probe and return probe_defer early on, so that all the other
initializations can be done after adv driver is loaded successfully.

Signed-off-by: Anitha Chrisanthus <anitha.chrisanthus at intel.com>
---
 drivers/gpu/drm/kmb/kmb_drv.c |  74 +++++++++++++---------
 drivers/gpu/drm/kmb/kmb_dsi.c | 144 ++++++++++++++++++++++++++----------------
 drivers/gpu/drm/kmb/kmb_dsi.h |   6 +-
 3 files changed, 138 insertions(+), 86 deletions(-)

diff --git a/drivers/gpu/drm/kmb/kmb_drv.c b/drivers/gpu/drm/kmb/kmb_drv.c
index 36edfbf..76f3c43 100644
--- a/drivers/gpu/drm/kmb/kmb_drv.c
+++ b/drivers/gpu/drm/kmb/kmb_drv.c
@@ -37,11 +37,24 @@ static struct clk *clk_lcd;
 static struct clk *clk_mipi;
 
 static int probe_deferred;
+struct drm_bridge *adv_bridge;
 
 static int kmb_display_clk_enable(void)
 {
-	clk_prepare_enable(clk_lcd);
-	clk_prepare_enable(clk_mipi);
+	int ret;
+
+	ret = clk_prepare_enable(clk_lcd);
+	if (ret) {
+		DRM_ERROR("Failed to enable LCD clock: %d\n", ret);
+		return ret;
+	}
+
+	ret = clk_prepare_enable(clk_mipi);
+	if (ret) {
+		DRM_ERROR("Failed to enable MIPI clock: %d\n", ret);
+		return ret;
+	}
+	DRM_INFO("SUCCESS : enabled LCD MIPI clocks\n");
 	return 0;
 }
 
@@ -86,8 +99,7 @@ static int kmb_load(struct drm_device *drm, unsigned long flags)
 	 *}
 	 */
 	/* LCD mmio */
-	if (!probe_deferred) {
-		probe_deferred = 1;
+	probe_deferred = 1;
 
 	if (!request_mem_region(LCD_BASE_ADDR, LCD_MMIO_SIZE, "kmb-lcd")) {
 		DRM_ERROR("failed to reserve LCD registers\n");
@@ -120,9 +132,10 @@ static int kmb_load(struct drm_device *drm, unsigned long flags)
 	 * lists LCD at 79 and 82 for MIPI under MSS CPU -
 	 * firmware has to redirect it to A53
 	 */
-/*TBD read and check for correct product version here */
 
-	/* Get the optional framebuffer memory resource */
+		/*TBD read and check for correct product version here */
+
+		/* Get the optional framebuffer memory resource */
 	ret = of_reserved_mem_device_init(drm->dev);
 	if (ret && ret != -ENODEV)
 		return ret;
@@ -134,8 +147,7 @@ static int kmb_load(struct drm_device *drm, unsigned long flags)
 		goto setup_fail;
 	}
 
-/*	ret = kmb_dsi_init(drm, bridge);*/
-	ret = kmb_dsi_init(drm);
+	ret = kmb_dsi_init(drm, adv_bridge);
 	if (ret == -EPROBE_DEFER) {
 		DRM_INFO("%s: wait for external bridge driver DT", __func__);
 		return -EPROBE_DEFER;
@@ -143,7 +155,6 @@ static int kmb_load(struct drm_device *drm, unsigned long flags)
 		DRM_ERROR("failed to initialize DSI\n");
 		goto setup_fail;
 	}
-}
 	/* enable display clocks*/
 	clk_lcd = clk_get(&pdev->dev, "clk_lcd");
 	if (!clk_lcd) {
@@ -157,10 +168,9 @@ static int kmb_load(struct drm_device *drm, unsigned long flags)
 		goto setup_fail;
 	}
 	DRM_INFO("%s : %d\n", __func__, __LINE__);
-	kmb_display_clk_enable();
-
-	DRM_INFO("%s : %d\n", __func__, __LINE__);
+	ret = kmb_display_clk_enable();
 
+	DRM_INFO("%s : %d clk enabling ret=%d\n", __func__, __LINE__, ret);
 	return 0;
 
 	drm_crtc_cleanup(&dev_p->crtc);
@@ -268,7 +278,7 @@ static struct drm_driver kmb_driver = {
 	.gem_prime_vunmap = drm_gem_cma_prime_vunmap,
 	.gem_prime_mmap = drm_gem_cma_prime_mmap,
 	.fops = &fops,
-	.name = "kmb",
+	.name = "kmb_display",
 	.desc = "KEEMBAY DISPLAY DRIVER ",
 	.date = "20190122",
 	.major = 1,
@@ -277,7 +287,7 @@ static struct drm_driver kmb_driver = {
 
 static int kmb_drm_bind(struct device *dev)
 {
-	struct drm_device *drm;
+	struct drm_device *drm = NULL;
 	struct kmb_drm_private *lcd;
 	int ret;
 
@@ -296,7 +306,9 @@ static int kmb_drm_bind(struct device *dev)
 	dev_set_drvdata(dev, drm);
 
 	kmb_setup_mode_config(drm);
-	DRM_DEBUG("kmb_bind : after kmb_setup_mode_config\n");
+	dev_set_drvdata(dev, drm);
+
+	/* load the driver */
 	ret = kmb_load(drm, 0);
 	DRM_INFO("%s : %d ret = %d\n", __func__, __LINE__, ret);
 	if (ret == -EPROBE_DEFER) {
@@ -337,7 +349,6 @@ static int kmb_drm_bind(struct device *dev)
 	drm_kms_helper_poll_fini(drm);
 err_vblank:
 	pm_runtime_disable(drm->dev);
-	component_unbind_all(dev, drm);
 	of_node_put(lcd->crtc.port);
 	lcd->crtc.port = NULL;
 	drm_irq_uninstall(drm);
@@ -355,9 +366,9 @@ static void kmb_drm_unbind(struct device *dev)
 	struct drm_device *drm = dev_get_drvdata(dev);
 	struct kmb_drm_private *dev_p = to_kmb(drm);
 
+	dump_stack();
 	drm_dev_unregister(drm);
 	drm_kms_helper_poll_fini(drm);
-	component_unbind_all(dev, drm);
 	of_node_put(dev_p->crtc.port);
 	dev_p->crtc.port = NULL;
 	pm_runtime_get_sync(drm->dev);
@@ -365,12 +376,15 @@ static void kmb_drm_unbind(struct device *dev)
 	pm_runtime_put_sync(drm->dev);
 	pm_runtime_disable(drm->dev);
 
+	DRM_INFO("%s : %d\n", __func__, __LINE__);
 	if (dev_p->lcd_mmio) {
+		DRM_INFO("%s : %d\n", __func__, __LINE__);
 		iounmap(dev_p->lcd_mmio);
 		release_mem_region(LCD_BASE_ADDR, LCD_MMIO_SIZE);
 	}
 
 	if (dev_p->mipi_mmio) {
+		DRM_INFO("%s : %d\n", __func__, __LINE__);
 		iounmap(dev_p->mipi_mmio);
 		release_mem_region(MIPI_BASE_ADDR, MIPI_MMIO_SIZE);
 	}
@@ -378,6 +392,7 @@ static void kmb_drm_unbind(struct device *dev)
 	if (dev_p->msscam_mmio)
 		iounmap(dev_p->msscam_mmio);
 
+	DRM_INFO("%s : %d\n", __func__, __LINE__);
 	of_reserved_mem_device_release(drm->dev);
 	drm_mode_config_cleanup(drm);
 
@@ -389,32 +404,31 @@ static void kmb_drm_unbind(struct device *dev)
 	drm_dev_put(drm);
 	drm->dev_private = NULL;
 	dev_set_drvdata(dev, NULL);
+	DRM_INFO("%s : %d\n", __func__, __LINE__);
 }
 
-static const struct component_master_ops kmb_master_ops = {
-	.bind = kmb_drm_bind,
-	.unbind = kmb_drm_unbind,
-};
-
 static int kmb_probe(struct platform_device *pdev)
 {
-	struct device_node *port;
-	int ret = 0;
+	struct device *device = get_device(&pdev->dev);
 
 	/* there is only one output port inside each device, find it */
 	DRM_DEBUG("%s : ENTER", __func__);
 
-	port = of_graph_get_remote_node(pdev->dev.of_node, 0, 0);
-	DRM_DEBUG("%s : port = 0x%pOF\n", __func__, port);
-	if (!port)
-		return -ENODEV;
-	DRM_DEBUG("%s : EXIT ret=%d\n", __func__, ret);
+	adv_bridge =  kmb_dsi_host_bridge_init(device);
+	if (adv_bridge == ERR_PTR(-EPROBE_DEFER))
+		return -EPROBE_DEFER;
+	else if (adv_bridge < 0) {
+		DRM_ERROR(" PROBE failed\n");
+		return -EINVAL;
+	}
+
 	return kmb_drm_bind(&pdev->dev);
 }
 
 static int kmb_remove(struct platform_device *pdev)
 {
-	component_master_del(&pdev->dev, &kmb_master_ops);
+//	component_master_del(&pdev->dev, &kmb_master_ops);
+	kmb_drm_unbind(&pdev->dev);
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/kmb/kmb_dsi.c b/drivers/gpu/drm/kmb/kmb_dsi.c
index 2bc63e2..6e4b8da 100644
--- a/drivers/gpu/drm/kmb/kmb_dsi.c
+++ b/drivers/gpu/drm/kmb/kmb_dsi.c
@@ -59,6 +59,9 @@
 #define PLL_M_MAX	623
 #define PLL_FVCO_MAX	1250
 
+static struct mipi_dsi_host *dsi_host;
+static struct mipi_dsi_device *dsi_device;
+
 /*
  * These are added here only temporarily for testing,
  * these will eventually go to the device tree sections,
@@ -273,33 +276,68 @@ static struct kmb_dsi_host *kmb_dsi_host_init(struct drm_device *drm,
 		struct kmb_dsi *kmb_dsi)
 {
 	struct kmb_dsi_host *host;
-	struct mipi_dsi_device *device;
-	int err;
 
 	host = kzalloc(sizeof(*host), GFP_KERNEL);
 	if (!host)
 		return NULL;
 
-	host->base.ops = &kmb_dsi_host_ops;
+	host->base = dsi_host;
+	host->base->ops = &kmb_dsi_host_ops;
 	host->kmb_dsi = kmb_dsi;
 
-	device = kzalloc(sizeof(*device), GFP_KERNEL);
-	if (!device) {
-		kfree(host);
-		return NULL;
-	}
+	host->base->dev = drm->dev;
+
+	dsi_device->host = host->base;
+	host->device = dsi_device;
+	return host;
+}
 
-	host->base.dev = drm->dev;
-	err = mipi_dsi_host_register(&host->base);
-	if (err < 0) {
-		DRM_ERROR("failed to register DSI host: %d\n", err);
-		kfree(host);
-		kfree(device);
+struct drm_bridge *kmb_dsi_host_bridge_init(struct device *dev)
+{
+	int ret;
+	struct device_node *encoder_node;
+	struct drm_bridge *bridge;
+
+	if (!dsi_host) {
+		dsi_host = kzalloc(sizeof(*dsi_host), GFP_KERNEL);
+		if (!dsi_host)
+			return ERR_PTR(-ENOMEM);
+
+		dsi_host->ops = &kmb_dsi_host_ops;
+
+		if (!dsi_device)
+			dsi_device = kzalloc(sizeof(*dsi_device), GFP_KERNEL);
+		if (!dsi_device) {
+			kfree(dsi_host);
+			return ERR_PTR(-ENOMEM);
+		}
+
+		dsi_host->dev = dev;
+		ret = mipi_dsi_host_register(dsi_host);
+		if (ret < 0) {
+			DRM_ERROR("failed to register DSI host: %d\n", ret);
+			kfree(dsi_host);
+			kfree(dsi_device);
+			return ERR_PTR(ret);
+		}
 	}
 
-	device->host = &host->base;
-	host->device = device;
-	return host;
+	/* find ADV7535 node and initialize it */
+	DRM_DEBUG("trying to get bridge info %pOF\n", dev->of_node);
+	encoder_node = of_parse_phandle(dev->of_node, "encoder-slave", 0);
+	DRM_DEBUG("encoder node =  %pOF\n", encoder_node);
+	if (!encoder_node) {
+		DRM_ERROR("failed to get bridge info from DT\n");
+		ret = -EINVAL;
+	}
+	/* Locate drm bridge from the hdmi encoder DT node */
+	bridge = of_drm_find_bridge(encoder_node);
+	of_node_put(encoder_node);
+	if (!bridge) {
+		DRM_INFO("wait for external bridge driver DT\n");
+		return ERR_PTR(-EPROBE_DEFER);
+	}
+	return bridge;
 }
 
 u32 mipi_get_datatype_params(u32 data_type, u32 data_mode,
@@ -662,7 +700,8 @@ static void mipi_tx_ctrl_cfg(struct kmb_drm_private *dev_p, u8 fg_id,
 	u32 sync_cfg = 0, ctrl = 0, fg_en;
 	u32 ctrl_no = MIPI_CTRL6;
 
-	/*MIPI_TX_HS_SYNC_CFG */
+	DRM_INFO("%s : %d\n", __func__, __LINE__);
+	/*MIPI_TX_HS_SYNC_CFG*/
 	if (ctrl_cfg->tx_ctrl_cfg.line_sync_pkt_en)
 		sync_cfg |= LINE_SYNC_PKT_ENABLE;
 	if (ctrl_cfg->tx_ctrl_cfg.frame_counter_active)
@@ -673,6 +712,7 @@ static void mipi_tx_ctrl_cfg(struct kmb_drm_private *dev_p, u8 fg_id,
 		sync_cfg |= DSI_V_BLANKING;
 	if (ctrl_cfg->tx_ctrl_cfg.tx_dsi_cfg->hsa_blanking)
 		sync_cfg |= DSI_HSA_BLANKING;
+	DRM_INFO("%s : %d\n", __func__, __LINE__);
 	if (ctrl_cfg->tx_ctrl_cfg.tx_dsi_cfg->hbp_blanking)
 		sync_cfg |= DSI_HBP_BLANKING;
 	if (ctrl_cfg->tx_ctrl_cfg.tx_dsi_cfg->hfp_blanking)
@@ -684,6 +724,7 @@ static void mipi_tx_ctrl_cfg(struct kmb_drm_private *dev_p, u8 fg_id,
 	if (ctrl_cfg->tx_ctrl_cfg.tx_dsi_cfg->lpm_last_vfp_line)
 		sync_cfg |= DSI_LPM_LAST_VFP_LINE;
 	/* enable frame generator */
+	DRM_INFO("%s : %d\n", __func__, __LINE__);
 	fg_en = 1 << fg_id;
 	sync_cfg |= FRAME_GEN_EN(fg_en);
 	if (ctrl_cfg->tx_ctrl_cfg.tx_always_use_hact)
@@ -702,7 +743,9 @@ static void mipi_tx_ctrl_cfg(struct kmb_drm_private *dev_p, u8 fg_id,
 	/*67 ns stop time */
 	ctrl |= HSEXIT_CNT(0x43);
 
+	DRM_INFO("%s : %d\n", __func__, __LINE__);
 	kmb_write_mipi(dev_p, MIPI_TXm_HS_SYNC_CFG(ctrl_no), sync_cfg);
+	DRM_INFO("%s : %d\n", __func__, __LINE__);
 	kmb_write_mipi(dev_p, MIPI_TXm_HS_CTRL(ctrl_no), ctrl);
 }
 
@@ -1284,8 +1327,8 @@ void mipi_tx_handle_irqs(struct kmb_drm_private *dev_p)
 
 }
 
-//int kmb_dsi_init(struct drm_device *dev, struct drm_bridge *bridge)
-int kmb_dsi_init(struct drm_device *dev)
+int kmb_dsi_init(struct drm_device *dev, struct drm_bridge *bridge)
+//int kmb_dsi_init(struct drm_device *dev)
 {
 	struct kmb_dsi *kmb_dsi;
 	struct drm_encoder *encoder;
@@ -1293,10 +1336,9 @@ int kmb_dsi_init(struct drm_device *dev)
 	struct drm_connector *connector;
 	struct kmb_dsi_host *host;
 	struct kmb_drm_private *dev_p = dev->dev_private;
-	struct device_node *encoder_node;
-	struct drm_bridge *bridge;
 	int ret = 0;
 
+	DRM_INFO("%s : %d\n", __func__, __LINE__);
 	kmb_dsi = kzalloc(sizeof(*kmb_dsi), GFP_KERNEL);
 	if (!kmb_dsi) {
 		DRM_ERROR("failed to allocate kmb_dsi\n");
@@ -1310,52 +1352,44 @@ int kmb_dsi_init(struct drm_device *dev)
 		return -ENOMEM;
 	}
 
+	DRM_INFO("%s : %d\n", __func__, __LINE__);
 	kmb_dsi->attached_connector = kmb_connector;
 
-	connector = &kmb_connector->base;
-	encoder = &kmb_dsi->base;
-	encoder->possible_crtcs = 1;
-	encoder->possible_clones = 0;
-	drm_encoder_init(dev, encoder, &kmb_dsi_funcs, DRM_MODE_ENCODER_DSI,
-			 "MIPI-DSI");
-
+	DRM_INFO("%s : %d\n", __func__, __LINE__);
 	host = kmb_dsi_host_init(dev, kmb_dsi);
+	DRM_INFO("%s : %d\n", __func__, __LINE__);
 	if (!host) {
-		drm_encoder_cleanup(encoder);
+		DRM_ERROR("Faile to allocate host\n");
+//		drm_encoder_cleanup(encoder);
 		kfree(kmb_dsi);
 		kfree(kmb_connector);
+		return -ENOMEM;
 	}
 
+	DRM_INFO("%s : %d\n", __func__, __LINE__);
+	connector = &kmb_connector->base;
+	DRM_INFO("%s : %d\n", __func__, __LINE__);
+	encoder = &kmb_dsi->base;
+	encoder->possible_crtcs = 1;
+	encoder->possible_clones = 0;
+	DRM_INFO("%s : %d\n", __func__, __LINE__);
+	drm_encoder_init(dev, encoder, &kmb_dsi_funcs, DRM_MODE_ENCODER_DSI,
+			"MIPI-DSI");
+	DRM_INFO("%s : %d\n", __func__, __LINE__);
+
 	drm_connector_init(dev, connector, &kmb_dsi_connector_funcs,
-			   DRM_MODE_CONNECTOR_DSI);
+						   DRM_MODE_CONNECTOR_DSI);
+	DRM_INFO("%s : %d\n", __func__, __LINE__);
 	drm_connector_helper_add(connector, &kmb_dsi_connector_helper_funcs);
 
+	DRM_INFO("%s : %d\n", __func__, __LINE__);
 //	connector->encoder = encoder;
-	DRM_INFO("%s : %d connector = %s encoder = %s\n", __func__, __LINE__,
-			connector->name, encoder->name);
-	DRM_INFO("%s : %d connector->encoder = 0x%p\n", __func__, __LINE__,
-			connector->encoder);
+	DRM_INFO("%s : %d connector = %s encoder = %s\n", __func__,
+			__LINE__, connector->name, encoder->name);
 
 	ret = drm_connector_attach_encoder(connector, encoder);
-	DRM_INFO("%s : %d ret = %d\n", __func__, __LINE__, ret);
-
-	/* find ADV7535 node and initialize it */
-	DRM_DEBUG("trying to get bridge info %pOF\n", dev->dev->of_node);
-	encoder_node = of_parse_phandle(dev->dev->of_node, "encoder-slave", 0);
-	DRM_DEBUG("encoder node =  %pOF\n", encoder_node);
-	if (!encoder_node) {
-		DRM_ERROR("failed to get bridge info from DT\n");
-		ret = -EINVAL;
-	}
-	/* Locate drm bridge from the hdmi encoder DT node */
-	bridge = of_drm_find_bridge(encoder_node);
-	of_node_put(encoder_node);
-	if (!bridge) {
-		DRM_INFO("wait for external bridge driver DT\n");
-		return -EPROBE_DEFER;
-	}
-
 	/* Link drm_bridge to encoder */
+	DRM_INFO("%s : %d\n", __func__, __LINE__);
 	ret = drm_bridge_attach(encoder, bridge, NULL, 0);
 	if (ret) {
 		DRM_ERROR("failed to attach bridge to MIPI\n");
@@ -1363,14 +1397,18 @@ int kmb_dsi_init(struct drm_device *dev)
 		return ret;
 	}
 
+	DRM_INFO("%s : %d\n", __func__, __LINE__);
 	/* initialize mipi controller */
 	mipi_tx_init_cntrl(dev_p, &mipi_tx_init_cfg);
+	DRM_INFO("%s : %d\n", __func__, __LINE__);
 
 	/*d-phy initialization */
 	mipi_tx_init_dphy(dev_p, &mipi_tx_init_cfg);
+	DRM_INFO("%s : %d\n", __func__, __LINE__);
 
 	/* irq initialization */
 	mipi_tx_init_irqs(dev_p, &int_cfg, &mipi_tx_init_cfg.tx_ctrl_cfg);
+	DRM_INFO("%s : %d\n", __func__, __LINE__);
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/kmb/kmb_dsi.h b/drivers/gpu/drm/kmb/kmb_dsi.h
index 5fc1547..e9bcc7e 100644
--- a/drivers/gpu/drm/kmb/kmb_dsi.h
+++ b/drivers/gpu/drm/kmb/kmb_dsi.h
@@ -22,7 +22,7 @@ struct kmb_dsi {
 };
 
 struct kmb_dsi_host {
-	struct mipi_dsi_host base;
+	struct mipi_dsi_host *base;
 	struct kmb_dsi *kmb_dsi;
 	struct mipi_dsi_device *device;
 };
@@ -309,8 +309,8 @@ union mipi_irq_cfg {
 	} irq_cfg;
 };
 
-//int kmb_dsi_init(struct drm_device *dev, struct drm_bridge *bridge);
-int kmb_dsi_init(struct drm_device *dev);
+struct drm_bridge *kmb_dsi_host_bridge_init(struct device *dev);
+int kmb_dsi_init(struct drm_device *dev, struct drm_bridge *bridge);
 void kmb_plane_destroy(struct drm_plane *plane);
 void mipi_tx_handle_irqs(struct kmb_drm_private *dev_p);
 
-- 
2.7.4



More information about the dri-devel mailing list