aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
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 /drivers/gpu
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>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/tegra/dc.c41
1 files changed, 39 insertions, 2 deletions
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");