diff options
author | Ujwal Patel <ujwalp@nvidia.com> | 2017-02-28 13:59:52 -0500 |
---|---|---|
committer | mobile promotions <svcmobile_promotions@nvidia.com> | 2017-04-12 09:59:51 -0400 |
commit | 46649461900fd7f03aae5b7bb2a3803993f3c00b (patch) | |
tree | f485c57ca6019768973d3d209b9d2c3c9fdf0dbe /drivers/video/tegra/dc/dsi.c | |
parent | cb090673ebbef604abed5bac9948d57c8d0fe8a5 (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.c | 17 |
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) | 2362 | static void tegra_dsi_mipi_calibration(struct tegra_dc_dsi_data *dsi) |
2363 | static 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 | ||
2405 | static void tegra_dsi_pad_calibration(struct tegra_dc_dsi_data *dsi) | 2403 | static 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 | ||
4526 | err_dc_clk_put: | 4520 | err_dc_clk_put: |
@@ -4539,7 +4533,6 @@ err_dsi_clk_put: | |||
4539 | err_free_dsi: | 4533 | err_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 | ||