@@ -57,11 +57,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;
}
@@ -106,8 +119,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");
@@ -140,9 +152,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;
@@ -154,8 +167,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;
@@ -163,7 +175,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) {
@@ -177,10 +188,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);
@@ -287,7 +297,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,
@@ -296,26 +306,27 @@ 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;
- DRM_DEBUG("kmb_bind : ENTER\n");
+ DRM_DEBUG("%s : ENTER", __func__);
drm = drm_dev_alloc(&kmb_driver, dev);
if (IS_ERR(drm))
return PTR_ERR(drm);
- DRM_DEBUG("kmb_bind : after alloc drm\n");
+ DRM_DEBUG("%s : after alloc drm", __func__);
lcd = devm_kzalloc(dev, sizeof(*lcd), GFP_KERNEL);
if (!lcd)
return -ENOMEM;
- DRM_DEBUG("kmb_bind : after alloc lcd\n");
+ DRM_DEBUG("%s : after alloc lcd", __func__);
drm->dev_private = lcd;
- 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) {
@@ -356,7 +367,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);
@@ -374,9 +384,9 @@ static void kmb_drm_unbind(struct device *dev)
struct drm_device *drm = dev_get_drvdata(dev);
struct kmb_drm_private *dev_p = drm->dev_private;
+ 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);
@@ -384,12 +394,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);
}
@@ -397,6 +410,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);
@@ -408,32 +422,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;
}
@@ -79,6 +79,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,
@@ -293,33 +296,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,
@@ -682,7 +720,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)
@@ -693,6 +732,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)
@@ -704,6 +744,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)
@@ -722,7 +763,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);
}
@@ -1304,8 +1347,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;
@@ -1313,10 +1356,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");
@@ -1330,52 +1372,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");
@@ -1383,14 +1417,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;
}
@@ -42,7 +42,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;
};
@@ -329,8 +329,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);
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@intel.com> --- drivers/gpu/drm/kmb/kmb_drv.c | 81 ++++++++++++++---------- drivers/gpu/drm/kmb/kmb_dsi.c | 144 ++++++++++++++++++++++++++---------------- drivers/gpu/drm/kmb/kmb_dsi.h | 6 +- 3 files changed, 141 insertions(+), 90 deletions(-)