aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThierry Reding <treding@nvidia.com>2014-01-09 11:08:36 -0500
committerThierry Reding <treding@nvidia.com>2014-01-23 09:51:32 -0500
commit13411ddd319057ae334a4084ebcf2c741b317f34 (patch)
tree9915698fb7fe169acd53b9b7f75347524ed04a98
parent70bf6878a874523e4b62992d07b5739298f8c1eb (diff)
drm/tegra: Obtain head number from DT
The head number of a given display controller is fixed in hardware and required to program outputs appropriately. Relying on the driver probe order to determine this number will not work, since that could yield a situation where the second head was probed first and would be assigned head number 0 instead of 1. By explicitly specifying the head number in the device tree, it is no longer necessary to rely on these assumptions. As a fallback, if the property isn't available, derive the head number from the display controller node's position in the device tree. That's somewhat more reliable than the previous default but not a proper solution. Tested-by: Stephen Warren <swarren@nvidia.com> Signed-off-by: Thierry Reding <treding@nvidia.com>
-rw-r--r--Documentation/devicetree/bindings/gpu/nvidia,tegra20-host1x.txt3
-rw-r--r--drivers/gpu/drm/tegra/dc.c41
2 files changed, 42 insertions, 2 deletions
diff --git a/Documentation/devicetree/bindings/gpu/nvidia,tegra20-host1x.txt b/Documentation/devicetree/bindings/gpu/nvidia,tegra20-host1x.txt
index 9e9008f8fa32..efaeec8961b6 100644
--- a/Documentation/devicetree/bindings/gpu/nvidia,tegra20-host1x.txt
+++ b/Documentation/devicetree/bindings/gpu/nvidia,tegra20-host1x.txt
@@ -118,6 +118,9 @@ of the following host1x client modules:
118 See ../reset/reset.txt for details. 118 See ../reset/reset.txt for details.
119 - reset-names: Must include the following entries: 119 - reset-names: Must include the following entries:
120 - dc 120 - dc
121 - nvidia,head: The number of the display controller head. This is used to
122 setup the various types of output to receive video data from the given
123 head.
121 124
122 Each display controller node has a child node, named "rgb", that represents 125 Each display controller node has a child node, named "rgb", that represents
123 the RGB output associated with the controller. It can take the following 126 the RGB output associated with the controller. It can take the following
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index 386f3b4b0094..9336006b475d 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -1100,8 +1100,6 @@ static int tegra_dc_init(struct host1x_client *client)
1100 struct tegra_dc *dc = host1x_client_to_dc(client); 1100 struct tegra_dc *dc = host1x_client_to_dc(client);
1101 int err; 1101 int err;
1102 1102
1103 dc->pipe = tegra->drm->mode_config.num_crtc;
1104
1105 drm_crtc_init(tegra->drm, &dc->base, &tegra_crtc_funcs); 1103 drm_crtc_init(tegra->drm, &dc->base, &tegra_crtc_funcs);
1106 drm_mode_crtc_set_gamma_size(&dc->base, 256); 1104 drm_mode_crtc_set_gamma_size(&dc->base, 256);
1107 drm_crtc_helper_add(&dc->base, &tegra_crtc_helper_funcs); 1105 drm_crtc_helper_add(&dc->base, &tegra_crtc_helper_funcs);
@@ -1187,6 +1185,41 @@ static const struct of_device_id tegra_dc_of_match[] = {
1187 } 1185 }
1188}; 1186};
1189 1187
1188static int tegra_dc_parse_dt(struct tegra_dc *dc)
1189{
1190 struct device_node *np;
1191 u32 value = 0;
1192 int err;
1193
1194 err = of_property_read_u32(dc->dev->of_node, "nvidia,head", &value);
1195 if (err < 0) {
1196 dev_err(dc->dev, "missing \"nvidia,head\" property\n");
1197
1198 /*
1199 * If the nvidia,head property isn't present, try to find the
1200 * correct head number by looking up the position of this
1201 * display controller's node within the device tree. Assuming
1202 * that the nodes are ordered properly in the DTS file and
1203 * that the translation into a flattened device tree blob
1204 * preserves that ordering this will actually yield the right
1205 * head number.
1206 *
1207 * If those assumptions don't hold, this will still work for
1208 * cases where only a single display controller is used.
1209 */
1210 for_each_matching_node(np, tegra_dc_of_match) {
1211 if (np == dc->dev->of_node)
1212 break;
1213
1214 value++;
1215 }
1216 }
1217
1218 dc->pipe = value;
1219
1220 return 0;
1221}
1222
1190static int tegra_dc_probe(struct platform_device *pdev) 1223static int tegra_dc_probe(struct platform_device *pdev)
1191{ 1224{
1192 const struct of_device_id *id; 1225 const struct of_device_id *id;
@@ -1207,6 +1240,10 @@ static int tegra_dc_probe(struct platform_device *pdev)
1207 dc->dev = &pdev->dev; 1240 dc->dev = &pdev->dev;
1208 dc->soc = id->data; 1241 dc->soc = id->data;
1209 1242
1243 err = tegra_dc_parse_dt(dc);
1244 if (err < 0)
1245 return err;
1246
1210 dc->clk = devm_clk_get(&pdev->dev, NULL); 1247 dc->clk = devm_clk_get(&pdev->dev, NULL);
1211 if (IS_ERR(dc->clk)) { 1248 if (IS_ERR(dc->clk)) {
1212 dev_err(&pdev->dev, "failed to get clock\n"); 1249 dev_err(&pdev->dev, "failed to get clock\n");