diff options
author | Thierry Reding <treding@nvidia.com> | 2014-01-09 11:08:36 -0500 |
---|---|---|
committer | Thierry Reding <treding@nvidia.com> | 2014-01-23 09:51:32 -0500 |
commit | 13411ddd319057ae334a4084ebcf2c741b317f34 (patch) | |
tree | 9915698fb7fe169acd53b9b7f75347524ed04a98 /drivers/gpu/drm/tegra | |
parent | 70bf6878a874523e4b62992d07b5739298f8c1eb (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/drm/tegra')
-rw-r--r-- | drivers/gpu/drm/tegra/dc.c | 41 |
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 | ||
1188 | static 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 | |||
1190 | static int tegra_dc_probe(struct platform_device *pdev) | 1223 | static 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"); |