summaryrefslogtreecommitdiffstats
path: root/drivers/video/tegra/dc/dsi.c
diff options
context:
space:
mode:
authorUjwal Patel <ujwalp@nvidia.com>2017-02-28 13:59:52 -0500
committermobile promotions <svcmobile_promotions@nvidia.com>2017-04-12 09:59:51 -0400
commit46649461900fd7f03aae5b7bb2a3803993f3c00b (patch)
treef485c57ca6019768973d3d209b9d2c3c9fdf0dbe /drivers/video/tegra/dc/dsi.c
parentcb090673ebbef604abed5bac9948d57c8d0fe8a5 (diff)
dc: redesign topology setup and panel selection
Current driver is cluttered with hard-coded logic with respect to topology setup and panel selection. This makes driver very rigid and difficult to scale. Redesign the driver such that topology setup and panel selection is defined by device-tree. During probe, driver will be initialized as per device-tree configuration. To achieve this remove dependence on "nvidia,dc-or-node" property and introduce other mandatory properties as described below. - nvidia,dc-connector: this property points to output resource node. i.e. dsi/sor0/sor1 etc. - nvidia,active-panel: this property points to connected panel. i.e. "dp-display", "hdmi-display", "panel_s_4kuhd_5_46" etc. - nvidia,dpaux: this property points to dpaux node - nvidia,sor-ctrlnum: this property identifies sor instance - nvidia,dpaux-ctrlnum: this property identifies dpaux instance Topology setup: Since topology is described through device-tree, driver doesn't need to hard-code absolute paths for devices, i.e. /host1x/sor, /host1x/sor1 etc. Since head(dc), SOR, DPAUX device-tree node contains a property to identify instance number, driver doesn't hard-code logic with respect to identifying HW instance number. Panel selection: Current panel selection logic is distributed across various files and there is a hard-coded logic for 1st/2nd/3rd display. This is not scalable if number of displays and panels supported increases. Clean-up this logic to have two-step panel selection logic. In the first-step, panel is selected based on display board-id and if no panel is found then 2nd step selects panel based on "nvidia,active-panel". Example device-tree layout: head0: nvdisplay@15200000 { compatible = "nvidia,tegra186-dc"; ... ... nvidia,dc-ctrlnum = <0x0>; nvidia,dc-connector = <&dsi>; ... }; head_1: nvdisplay@15210000 { compatible = "nvidia,tegra186-dc"; ... nvidia,dc-ctrlnum = <0x1>; nvidia,dc-connector = <&sor1>; ... }; head_2: nvdisplay@15220000 { compatible = "nvidia,tegra186-dc"; ... nvidia,dc-ctrlnum = <0x2>; nvidia,dc-connector = <&sor0>; ... }; dsi: dsi { compatible = "nvidia,tegra186-dsi"; ... nvidia,active-panel = <&panel_s_wuxga_8_0>; ... panel_s_wuxga_8_0: panel-s-wuxga-8-0 { status = “okay”; ... }; panel_s_wuxga_8_0_mods: panel-s-wuxga-8-0-mods { status = “disabled”; ... }; }; sor0: sor { compatible = "nvidia,tegra186-sor"; ... nvidia,sor-ctrlnum = <0x0>; nvidia,dpaux = <&dpaux0>; nvidia,active-panel = <&sor0_hdmi_display>; ... sor0_hdmi_display: hdmi-display { status = “okay”; ... }; sor0_dp_display: dp-display { status = “disabled”; ... }; }; sor1: sor1 { compatible = "nvidia,tegra186-sor"; ... nvidia,sor-ctrlnum = <0x1>; nvidia,dpaux = <&dpaux1>; nvidia,active-panel = <&panel_s_edp_uhdtv>; ... sor1_dp_display: dp-display { status = “disabled”; ... }; panel_s_edp_uhdtv: panel-s-edp-uhdtv-15-6 { status = “okay”; ... }; }; dpaux0: dpaux@155C0000 { compatible = "nvidia,tegra186-dpaux"; ... nvidia,dpaux-ctrlnum = <0>; ... }; dpaux1: dpaux@15040000 { compatible = "nvidia,tegra186-dpaux"; ... nvidia,dpaux-ctrlnum = <1>; ... }; TDS-757 TDS-1544 TDS-1631 Change-Id: I0007eb56e4ccfbfa58491792cc8233ffaedeedfb Signed-off-by: Ujwal Patel <ujwalp@nvidia.com> Reviewed-on: http://git-master/r/1319184 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers/video/tegra/dc/dsi.c')
-rw-r--r--drivers/video/tegra/dc/dsi.c17
1 files changed, 5 insertions, 12 deletions
diff --git a/drivers/video/tegra/dc/dsi.c b/drivers/video/tegra/dc/dsi.c
index 67076eb85..bb6050ba3 100644
--- a/drivers/video/tegra/dc/dsi.c
+++ b/drivers/video/tegra/dc/dsi.c
@@ -2359,13 +2359,12 @@ static void tegra_dsi_pad_enable(struct tegra_dc_dsi_data *dsi)
2359 } 2359 }
2360} 2360}
2361 2361
2362#if defined(CONFIG_ARCH_TEGRA_210_SOC) || defined(CONFIG_TEGRA_NVDISPLAY) 2362static void tegra_dsi_mipi_calibration(struct tegra_dc_dsi_data *dsi)
2363static void tegra_dsi_mipi_calibration_21x(struct tegra_dc_dsi_data *dsi)
2364{ 2363{
2365 u32 val = 0; 2364 u32 val = 0;
2366#if !defined(CONFIG_TEGRA_NVDISPLAY) 2365#if !defined(CONFIG_TEGRA_NVDISPLAY)
2367 struct clk *clk72mhz = NULL; 2366 struct clk *clk72mhz = NULL;
2368 struct device_node *np_dsi = of_find_node_by_path(DSI_NODE); 2367 struct device_node *np_dsi = tegra_dc_get_conn_np(dsi->dc);
2369 clk72mhz = tegra_disp_of_clk_get_by_name(np_dsi, "clk72mhz"); 2368 clk72mhz = tegra_disp_of_clk_get_by_name(np_dsi, "clk72mhz");
2370 if (IS_ERR_OR_NULL(clk72mhz)) { 2369 if (IS_ERR_OR_NULL(clk72mhz)) {
2371 dev_err(&dsi->dc->ndev->dev, "dsi: can't get clk72mhz clock\n"); 2370 dev_err(&dsi->dc->ndev->dev, "dsi: can't get clk72mhz clock\n");
@@ -2400,7 +2399,6 @@ static void tegra_dsi_mipi_calibration_21x(struct tegra_dc_dsi_data *dsi)
2400 clk_put(clk72mhz); 2399 clk_put(clk72mhz);
2401#endif 2400#endif
2402} 2401}
2403#endif
2404 2402
2405static void tegra_dsi_pad_calibration(struct tegra_dc_dsi_data *dsi) 2403static void tegra_dsi_pad_calibration(struct tegra_dc_dsi_data *dsi)
2406{ 2404{
@@ -2410,7 +2408,7 @@ static void tegra_dsi_pad_calibration(struct tegra_dc_dsi_data *dsi)
2410 tegra_dsi_pad_disable(dsi); 2408 tegra_dsi_pad_disable(dsi);
2411 2409
2412 if (dsi->info.controller_vs == DSI_VS_1) 2410 if (dsi->info.controller_vs == DSI_VS_1)
2413 tegra_dsi_mipi_calibration_21x(dsi); 2411 tegra_dsi_mipi_calibration(dsi);
2414} 2412}
2415 2413
2416#if !defined(CONFIG_TEGRA_NVDISPLAY) && !defined(CONFIG_ARCH_TEGRA_210_SOC) 2414#if !defined(CONFIG_TEGRA_NVDISPLAY) && !defined(CONFIG_ARCH_TEGRA_210_SOC)
@@ -4359,8 +4357,7 @@ static int _tegra_dc_dsi_init(struct tegra_dc *dc)
4359#else 4357#else
4360 char *dsi_fixed_clk_name = "pll_p_out3"; 4358 char *dsi_fixed_clk_name = "pll_p_out3";
4361#endif 4359#endif
4362 struct device_node *np_dsi = 4360 struct device_node *np_dsi = tegra_dc_get_conn_np(dc);
4363 of_find_node_by_path(DSI_NODE);
4364 4361
4365 if (!np_dsi || !of_device_is_available(np_dsi)) { 4362 if (!np_dsi || !of_device_is_available(np_dsi)) {
4366 dev_err(&dc->ndev->dev, "dsi not available\n"); 4363 dev_err(&dc->ndev->dev, "dsi not available\n");
@@ -4368,10 +4365,8 @@ static int _tegra_dc_dsi_init(struct tegra_dc *dc)
4368 } 4365 }
4369 4366
4370 dsi = kzalloc(sizeof(*dsi), GFP_KERNEL); 4367 dsi = kzalloc(sizeof(*dsi), GFP_KERNEL);
4371 if (!dsi) { 4368 if (!dsi)
4372 of_node_put(np_dsi);
4373 return -ENOMEM; 4369 return -ENOMEM;
4374 }
4375 4370
4376 dsi->max_instances = is_simple_dsi(dc->out->dsi) ? 1 : MAX_DSI_INSTANCE; 4371 dsi->max_instances = is_simple_dsi(dc->out->dsi) ? 1 : MAX_DSI_INSTANCE;
4377 dsi_instance = (int)dc->out->dsi->dsi_instance; 4372 dsi_instance = (int)dc->out->dsi->dsi_instance;
@@ -4520,7 +4515,6 @@ static int _tegra_dc_dsi_init(struct tegra_dc *dc)
4520 goto err_dc_clk_put; 4515 goto err_dc_clk_put;
4521 } 4516 }
4522 4517
4523 of_node_put(np_dsi);
4524 return 0; 4518 return 0;
4525 4519
4526err_dc_clk_put: 4520err_dc_clk_put:
@@ -4539,7 +4533,6 @@ err_dsi_clk_put:
4539err_free_dsi: 4533err_free_dsi:
4540 kfree(dsi); 4534 kfree(dsi);
4541 4535
4542 of_node_put(np_dsi);
4543 return err; 4536 return err;
4544} 4537}
4545 4538