diff options
author | Rob Clark <robdclark@gmail.com> | 2013-12-15 16:23:05 -0500 |
---|---|---|
committer | Rob Clark <robdclark@gmail.com> | 2014-08-04 11:55:28 -0400 |
commit | 41e69778c80764c12683beff5ebef12298a5d16b (patch) | |
tree | 494c91f5bdc4ec1ff86fbf59944f856867bb5edd /drivers/gpu/drm/msm | |
parent | 8f67da335d08bc06d3333f4bd46b96e6cc096d94 (diff) |
drm/msm: DT support for 8960/8064 (v3)
Now that we (almost) have enough dependencies in place (MMCC, RPM, etc),
add necessary DT support so that we can use drm/msm on upstream kernel.
v2: update for review comments
v3: rebase on component helper changes
Signed-off-by: Rob Clark <robdclark@gmail.com>
Diffstat (limited to 'drivers/gpu/drm/msm')
-rw-r--r-- | drivers/gpu/drm/msm/adreno/a3xx_gpu.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/hdmi/hdmi.c | 68 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c | 10 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/msm_drv.c | 39 |
4 files changed, 77 insertions, 42 deletions
diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c index a2cee0645336..2773600c9488 100644 --- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c | |||
@@ -680,6 +680,8 @@ static int a3xx_remove(struct platform_device *pdev) | |||
680 | } | 680 | } |
681 | 681 | ||
682 | static const struct of_device_id dt_match[] = { | 682 | static const struct of_device_id dt_match[] = { |
683 | { .compatible = "qcom,adreno-3xx" }, | ||
684 | /* for backwards compat w/ downstream kgsl DT files: */ | ||
683 | { .compatible = "qcom,kgsl-3d0" }, | 685 | { .compatible = "qcom,kgsl-3d0" }, |
684 | {} | 686 | {} |
685 | }; | 687 | }; |
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c index 7f7aadef8a82..041c2fca2225 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi.c | |||
@@ -123,7 +123,8 @@ struct hdmi *hdmi_init(struct drm_device *dev, struct drm_encoder *encoder) | |||
123 | for (i = 0; i < config->hpd_reg_cnt; i++) { | 123 | for (i = 0; i < config->hpd_reg_cnt; i++) { |
124 | struct regulator *reg; | 124 | struct regulator *reg; |
125 | 125 | ||
126 | reg = devm_regulator_get(&pdev->dev, config->hpd_reg_names[i]); | 126 | reg = devm_regulator_get_exclusive(&pdev->dev, |
127 | config->hpd_reg_names[i]); | ||
127 | if (IS_ERR(reg)) { | 128 | if (IS_ERR(reg)) { |
128 | ret = PTR_ERR(reg); | 129 | ret = PTR_ERR(reg); |
129 | dev_err(dev->dev, "failed to get hpd regulator: %s (%d)\n", | 130 | dev_err(dev->dev, "failed to get hpd regulator: %s (%d)\n", |
@@ -138,7 +139,8 @@ struct hdmi *hdmi_init(struct drm_device *dev, struct drm_encoder *encoder) | |||
138 | for (i = 0; i < config->pwr_reg_cnt; i++) { | 139 | for (i = 0; i < config->pwr_reg_cnt; i++) { |
139 | struct regulator *reg; | 140 | struct regulator *reg; |
140 | 141 | ||
141 | reg = devm_regulator_get(&pdev->dev, config->pwr_reg_names[i]); | 142 | reg = devm_regulator_get_exclusive(&pdev->dev, |
143 | config->pwr_reg_names[i]); | ||
142 | if (IS_ERR(reg)) { | 144 | if (IS_ERR(reg)) { |
143 | ret = PTR_ERR(reg); | 145 | ret = PTR_ERR(reg); |
144 | dev_err(dev->dev, "failed to get pwr regulator: %s (%d)\n", | 146 | dev_err(dev->dev, "failed to get pwr regulator: %s (%d)\n", |
@@ -266,37 +268,55 @@ static int hdmi_bind(struct device *dev, struct device *master, void *data) | |||
266 | { | 268 | { |
267 | int gpio = of_get_named_gpio(of_node, name, 0); | 269 | int gpio = of_get_named_gpio(of_node, name, 0); |
268 | if (gpio < 0) { | 270 | if (gpio < 0) { |
269 | dev_err(dev, "failed to get gpio: %s (%d)\n", | 271 | char name2[32]; |
270 | name, gpio); | 272 | snprintf(name2, sizeof(name2), "%s-gpio", name); |
271 | gpio = -1; | 273 | gpio = of_get_named_gpio(of_node, name2, 0); |
274 | if (gpio < 0) { | ||
275 | dev_err(dev, "failed to get gpio: %s (%d)\n", | ||
276 | name, gpio); | ||
277 | gpio = -1; | ||
278 | } | ||
272 | } | 279 | } |
273 | return gpio; | 280 | return gpio; |
274 | } | 281 | } |
275 | 282 | ||
276 | /* TODO actually use DT.. */ | 283 | if (of_device_is_compatible(of_node, "qcom,hdmi-tx-8074")) { |
277 | static const char *hpd_reg_names[] = {"hpd-gdsc", "hpd-5v"}; | 284 | static const char *hpd_reg_names[] = {"hpd-gdsc", "hpd-5v"}; |
278 | static const char *pwr_reg_names[] = {"core-vdda", "core-vcc"}; | 285 | static const char *pwr_reg_names[] = {"core-vdda", "core-vcc"}; |
279 | static const char *hpd_clk_names[] = {"iface_clk", "core_clk", "mdp_core_clk"}; | 286 | static const char *hpd_clk_names[] = {"iface_clk", "core_clk", "mdp_core_clk"}; |
280 | static unsigned long hpd_clk_freq[] = {0, 19200000, 0}; | 287 | static unsigned long hpd_clk_freq[] = {0, 19200000, 0}; |
281 | static const char *pwr_clk_names[] = {"extp_clk", "alt_iface_clk"}; | 288 | static const char *pwr_clk_names[] = {"extp_clk", "alt_iface_clk"}; |
289 | config.phy_init = hdmi_phy_8x74_init; | ||
290 | config.hpd_reg_names = hpd_reg_names; | ||
291 | config.hpd_reg_cnt = ARRAY_SIZE(hpd_reg_names); | ||
292 | config.pwr_reg_names = pwr_reg_names; | ||
293 | config.pwr_reg_cnt = ARRAY_SIZE(pwr_reg_names); | ||
294 | config.hpd_clk_names = hpd_clk_names; | ||
295 | config.hpd_freq = hpd_clk_freq; | ||
296 | config.hpd_clk_cnt = ARRAY_SIZE(hpd_clk_names); | ||
297 | config.pwr_clk_names = pwr_clk_names; | ||
298 | config.pwr_clk_cnt = ARRAY_SIZE(pwr_clk_names); | ||
299 | config.shared_irq = true; | ||
300 | } else if (of_device_is_compatible(of_node, "qcom,hdmi-tx-8960")) { | ||
301 | static const char *hpd_clk_names[] = {"core_clk", "master_iface_clk", "slave_iface_clk"}; | ||
302 | static const char *hpd_reg_names[] = {"core-vdda", "hdmi-mux"}; | ||
303 | config.phy_init = hdmi_phy_8960_init; | ||
304 | config.hpd_reg_names = hpd_reg_names; | ||
305 | config.hpd_reg_cnt = ARRAY_SIZE(hpd_reg_names); | ||
306 | config.hpd_clk_names = hpd_clk_names; | ||
307 | config.hpd_clk_cnt = ARRAY_SIZE(hpd_clk_names); | ||
308 | } else if (of_device_is_compatible(of_node, "qcom,hdmi-tx-8660")) { | ||
309 | config.phy_init = hdmi_phy_8x60_init; | ||
310 | } else { | ||
311 | dev_err(dev, "unknown phy: %s\n", of_node->name); | ||
312 | } | ||
282 | 313 | ||
283 | config.phy_init = hdmi_phy_8x74_init; | ||
284 | config.mmio_name = "core_physical"; | 314 | config.mmio_name = "core_physical"; |
285 | config.hpd_reg_names = hpd_reg_names; | ||
286 | config.hpd_reg_cnt = ARRAY_SIZE(hpd_reg_names); | ||
287 | config.pwr_reg_names = pwr_reg_names; | ||
288 | config.pwr_reg_cnt = ARRAY_SIZE(pwr_reg_names); | ||
289 | config.hpd_clk_names = hpd_clk_names; | ||
290 | config.hpd_freq = hpd_clk_freq; | ||
291 | config.hpd_clk_cnt = ARRAY_SIZE(hpd_clk_names); | ||
292 | config.pwr_clk_names = pwr_clk_names; | ||
293 | config.pwr_clk_cnt = ARRAY_SIZE(pwr_clk_names); | ||
294 | config.ddc_clk_gpio = get_gpio("qcom,hdmi-tx-ddc-clk"); | 315 | config.ddc_clk_gpio = get_gpio("qcom,hdmi-tx-ddc-clk"); |
295 | config.ddc_data_gpio = get_gpio("qcom,hdmi-tx-ddc-data"); | 316 | config.ddc_data_gpio = get_gpio("qcom,hdmi-tx-ddc-data"); |
296 | config.hpd_gpio = get_gpio("qcom,hdmi-tx-hpd"); | 317 | config.hpd_gpio = get_gpio("qcom,hdmi-tx-hpd"); |
297 | config.mux_en_gpio = get_gpio("qcom,hdmi-tx-mux-en"); | 318 | config.mux_en_gpio = get_gpio("qcom,hdmi-tx-mux-en"); |
298 | config.mux_sel_gpio = get_gpio("qcom,hdmi-tx-mux-sel"); | 319 | config.mux_sel_gpio = get_gpio("qcom,hdmi-tx-mux-sel"); |
299 | config.shared_irq = true; | ||
300 | 320 | ||
301 | #else | 321 | #else |
302 | static const char *hpd_clk_names[] = { | 322 | static const char *hpd_clk_names[] = { |
@@ -373,7 +393,9 @@ static int hdmi_dev_remove(struct platform_device *pdev) | |||
373 | } | 393 | } |
374 | 394 | ||
375 | static const struct of_device_id dt_match[] = { | 395 | static const struct of_device_id dt_match[] = { |
376 | { .compatible = "qcom,hdmi-tx" }, | 396 | { .compatible = "qcom,hdmi-tx-8074" }, |
397 | { .compatible = "qcom,hdmi-tx-8960" }, | ||
398 | { .compatible = "qcom,hdmi-tx-8660" }, | ||
377 | {} | 399 | {} |
378 | }; | 400 | }; |
379 | 401 | ||
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c index 0bb4faa17523..5a7bfd452252 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c | |||
@@ -294,15 +294,17 @@ struct msm_kms *mdp4_kms_init(struct drm_device *dev) | |||
294 | goto fail; | 294 | goto fail; |
295 | } | 295 | } |
296 | 296 | ||
297 | mdp4_kms->dsi_pll_vdda = devm_regulator_get(&pdev->dev, "dsi_pll_vdda"); | 297 | mdp4_kms->dsi_pll_vdda = |
298 | devm_regulator_get_optional(&pdev->dev, "dsi_pll_vdda"); | ||
298 | if (IS_ERR(mdp4_kms->dsi_pll_vdda)) | 299 | if (IS_ERR(mdp4_kms->dsi_pll_vdda)) |
299 | mdp4_kms->dsi_pll_vdda = NULL; | 300 | mdp4_kms->dsi_pll_vdda = NULL; |
300 | 301 | ||
301 | mdp4_kms->dsi_pll_vddio = devm_regulator_get(&pdev->dev, "dsi_pll_vddio"); | 302 | mdp4_kms->dsi_pll_vddio = |
303 | devm_regulator_get_optional(&pdev->dev, "dsi_pll_vddio"); | ||
302 | if (IS_ERR(mdp4_kms->dsi_pll_vddio)) | 304 | if (IS_ERR(mdp4_kms->dsi_pll_vddio)) |
303 | mdp4_kms->dsi_pll_vddio = NULL; | 305 | mdp4_kms->dsi_pll_vddio = NULL; |
304 | 306 | ||
305 | mdp4_kms->vdd = devm_regulator_get(&pdev->dev, "vdd"); | 307 | mdp4_kms->vdd = devm_regulator_get_exclusive(&pdev->dev, "vdd"); |
306 | if (IS_ERR(mdp4_kms->vdd)) | 308 | if (IS_ERR(mdp4_kms->vdd)) |
307 | mdp4_kms->vdd = NULL; | 309 | mdp4_kms->vdd = NULL; |
308 | 310 | ||
@@ -406,6 +408,8 @@ static struct mdp4_platform_config *mdp4_get_config(struct platform_device *dev) | |||
406 | static struct mdp4_platform_config config = {}; | 408 | static struct mdp4_platform_config config = {}; |
407 | #ifdef CONFIG_OF | 409 | #ifdef CONFIG_OF |
408 | /* TODO */ | 410 | /* TODO */ |
411 | config.max_clk = 266667000; | ||
412 | config.iommu = iommu_domain_alloc(&platform_bus_type); | ||
409 | #else | 413 | #else |
410 | if (cpu_is_apq8064()) | 414 | if (cpu_is_apq8064()) |
411 | config.max_clk = 266667000; | 415 | config.max_clk = 266667000; |
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index a322029983ce..a2f5bf6da6f3 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c | |||
@@ -905,6 +905,25 @@ static int compare_of(struct device *dev, void *data) | |||
905 | { | 905 | { |
906 | return dev->of_node == data; | 906 | return dev->of_node == data; |
907 | } | 907 | } |
908 | |||
909 | static int add_components(struct device *dev, struct component_match **matchptr, | ||
910 | const char *name) | ||
911 | { | ||
912 | struct device_node *np = dev->of_node; | ||
913 | unsigned i; | ||
914 | |||
915 | for (i = 0; ; i++) { | ||
916 | struct device_node *node; | ||
917 | |||
918 | node = of_parse_phandle(np, name, i); | ||
919 | if (!node) | ||
920 | break; | ||
921 | |||
922 | component_match_add(dev, matchptr, compare_of, node); | ||
923 | } | ||
924 | |||
925 | return 0; | ||
926 | } | ||
908 | #else | 927 | #else |
909 | static int compare_dev(struct device *dev, void *data) | 928 | static int compare_dev(struct device *dev, void *data) |
910 | { | 929 | { |
@@ -935,21 +954,8 @@ static int msm_pdev_probe(struct platform_device *pdev) | |||
935 | { | 954 | { |
936 | struct component_match *match = NULL; | 955 | struct component_match *match = NULL; |
937 | #ifdef CONFIG_OF | 956 | #ifdef CONFIG_OF |
938 | /* NOTE: the CONFIG_OF case duplicates the same code as exynos or imx | 957 | add_components(&pdev->dev, &match, "connectors"); |
939 | * (or probably any other).. so probably some room for some helpers | 958 | add_components(&pdev->dev, &match, "gpus"); |
940 | */ | ||
941 | struct device_node *np = pdev->dev.of_node; | ||
942 | unsigned i; | ||
943 | |||
944 | for (i = 0; ; i++) { | ||
945 | struct device_node *node; | ||
946 | |||
947 | node = of_parse_phandle(np, "connectors", i); | ||
948 | if (!node) | ||
949 | break; | ||
950 | |||
951 | component_match_add(&pdev->dev, &match, compare_of, node); | ||
952 | } | ||
953 | #else | 959 | #else |
954 | /* For non-DT case, it kinda sucks. We don't actually have a way | 960 | /* For non-DT case, it kinda sucks. We don't actually have a way |
955 | * to know whether or not we are waiting for certain devices (or if | 961 | * to know whether or not we are waiting for certain devices (or if |
@@ -995,7 +1001,8 @@ static const struct platform_device_id msm_id[] = { | |||
995 | }; | 1001 | }; |
996 | 1002 | ||
997 | static const struct of_device_id dt_match[] = { | 1003 | static const struct of_device_id dt_match[] = { |
998 | { .compatible = "qcom,mdss_mdp" }, | 1004 | { .compatible = "qcom,mdp" }, /* mdp4 */ |
1005 | { .compatible = "qcom,mdss_mdp" }, /* mdp5 */ | ||
999 | {} | 1006 | {} |
1000 | }; | 1007 | }; |
1001 | MODULE_DEVICE_TABLE(of, dt_match); | 1008 | MODULE_DEVICE_TABLE(of, dt_match); |