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 | |
parent | 8f67da335d08bc06d3333f4bd46b96e6cc096d94 (diff) | |
download | linux-41e69778c80764c12683beff5ebef12298a5d16b.tar.bz2 |
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')
-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) } static const struct of_device_id dt_match[] = { + { .compatible = "qcom,adreno-3xx" }, + /* for backwards compat w/ downstream kgsl DT files: */ { .compatible = "qcom,kgsl-3d0" }, {} }; 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) for (i = 0; i < config->hpd_reg_cnt; i++) { struct regulator *reg; - reg = devm_regulator_get(&pdev->dev, config->hpd_reg_names[i]); + reg = devm_regulator_get_exclusive(&pdev->dev, + config->hpd_reg_names[i]); if (IS_ERR(reg)) { ret = PTR_ERR(reg); 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) for (i = 0; i < config->pwr_reg_cnt; i++) { struct regulator *reg; - reg = devm_regulator_get(&pdev->dev, config->pwr_reg_names[i]); + reg = devm_regulator_get_exclusive(&pdev->dev, + config->pwr_reg_names[i]); if (IS_ERR(reg)) { ret = PTR_ERR(reg); 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) { int gpio = of_get_named_gpio(of_node, name, 0); if (gpio < 0) { - dev_err(dev, "failed to get gpio: %s (%d)\n", - name, gpio); - gpio = -1; + char name2[32]; + snprintf(name2, sizeof(name2), "%s-gpio", name); + gpio = of_get_named_gpio(of_node, name2, 0); + if (gpio < 0) { + dev_err(dev, "failed to get gpio: %s (%d)\n", + name, gpio); + gpio = -1; + } } return gpio; } - /* TODO actually use DT.. */ - static const char *hpd_reg_names[] = {"hpd-gdsc", "hpd-5v"}; - static const char *pwr_reg_names[] = {"core-vdda", "core-vcc"}; - static const char *hpd_clk_names[] = {"iface_clk", "core_clk", "mdp_core_clk"}; - static unsigned long hpd_clk_freq[] = {0, 19200000, 0}; - static const char *pwr_clk_names[] = {"extp_clk", "alt_iface_clk"}; + if (of_device_is_compatible(of_node, "qcom,hdmi-tx-8074")) { + static const char *hpd_reg_names[] = {"hpd-gdsc", "hpd-5v"}; + static const char *pwr_reg_names[] = {"core-vdda", "core-vcc"}; + static const char *hpd_clk_names[] = {"iface_clk", "core_clk", "mdp_core_clk"}; + static unsigned long hpd_clk_freq[] = {0, 19200000, 0}; + static const char *pwr_clk_names[] = {"extp_clk", "alt_iface_clk"}; + config.phy_init = hdmi_phy_8x74_init; + config.hpd_reg_names = hpd_reg_names; + config.hpd_reg_cnt = ARRAY_SIZE(hpd_reg_names); + config.pwr_reg_names = pwr_reg_names; + config.pwr_reg_cnt = ARRAY_SIZE(pwr_reg_names); + config.hpd_clk_names = hpd_clk_names; + config.hpd_freq = hpd_clk_freq; + config.hpd_clk_cnt = ARRAY_SIZE(hpd_clk_names); + config.pwr_clk_names = pwr_clk_names; + config.pwr_clk_cnt = ARRAY_SIZE(pwr_clk_names); + config.shared_irq = true; + } else if (of_device_is_compatible(of_node, "qcom,hdmi-tx-8960")) { + static const char *hpd_clk_names[] = {"core_clk", "master_iface_clk", "slave_iface_clk"}; + static const char *hpd_reg_names[] = {"core-vdda", "hdmi-mux"}; + config.phy_init = hdmi_phy_8960_init; + config.hpd_reg_names = hpd_reg_names; + config.hpd_reg_cnt = ARRAY_SIZE(hpd_reg_names); + config.hpd_clk_names = hpd_clk_names; + config.hpd_clk_cnt = ARRAY_SIZE(hpd_clk_names); + } else if (of_device_is_compatible(of_node, "qcom,hdmi-tx-8660")) { + config.phy_init = hdmi_phy_8x60_init; + } else { + dev_err(dev, "unknown phy: %s\n", of_node->name); + } - config.phy_init = hdmi_phy_8x74_init; config.mmio_name = "core_physical"; - config.hpd_reg_names = hpd_reg_names; - config.hpd_reg_cnt = ARRAY_SIZE(hpd_reg_names); - config.pwr_reg_names = pwr_reg_names; - config.pwr_reg_cnt = ARRAY_SIZE(pwr_reg_names); - config.hpd_clk_names = hpd_clk_names; - config.hpd_freq = hpd_clk_freq; - config.hpd_clk_cnt = ARRAY_SIZE(hpd_clk_names); - config.pwr_clk_names = pwr_clk_names; - config.pwr_clk_cnt = ARRAY_SIZE(pwr_clk_names); config.ddc_clk_gpio = get_gpio("qcom,hdmi-tx-ddc-clk"); config.ddc_data_gpio = get_gpio("qcom,hdmi-tx-ddc-data"); config.hpd_gpio = get_gpio("qcom,hdmi-tx-hpd"); config.mux_en_gpio = get_gpio("qcom,hdmi-tx-mux-en"); config.mux_sel_gpio = get_gpio("qcom,hdmi-tx-mux-sel"); - config.shared_irq = true; #else static const char *hpd_clk_names[] = { @@ -373,7 +393,9 @@ static int hdmi_dev_remove(struct platform_device *pdev) } static const struct of_device_id dt_match[] = { - { .compatible = "qcom,hdmi-tx" }, + { .compatible = "qcom,hdmi-tx-8074" }, + { .compatible = "qcom,hdmi-tx-8960" }, + { .compatible = "qcom,hdmi-tx-8660" }, {} }; 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) goto fail; } - mdp4_kms->dsi_pll_vdda = devm_regulator_get(&pdev->dev, "dsi_pll_vdda"); + mdp4_kms->dsi_pll_vdda = + devm_regulator_get_optional(&pdev->dev, "dsi_pll_vdda"); if (IS_ERR(mdp4_kms->dsi_pll_vdda)) mdp4_kms->dsi_pll_vdda = NULL; - mdp4_kms->dsi_pll_vddio = devm_regulator_get(&pdev->dev, "dsi_pll_vddio"); + mdp4_kms->dsi_pll_vddio = + devm_regulator_get_optional(&pdev->dev, "dsi_pll_vddio"); if (IS_ERR(mdp4_kms->dsi_pll_vddio)) mdp4_kms->dsi_pll_vddio = NULL; - mdp4_kms->vdd = devm_regulator_get(&pdev->dev, "vdd"); + mdp4_kms->vdd = devm_regulator_get_exclusive(&pdev->dev, "vdd"); if (IS_ERR(mdp4_kms->vdd)) mdp4_kms->vdd = NULL; @@ -406,6 +408,8 @@ static struct mdp4_platform_config *mdp4_get_config(struct platform_device *dev) static struct mdp4_platform_config config = {}; #ifdef CONFIG_OF /* TODO */ + config.max_clk = 266667000; + config.iommu = iommu_domain_alloc(&platform_bus_type); #else if (cpu_is_apq8064()) 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) { return dev->of_node == data; } + +static int add_components(struct device *dev, struct component_match **matchptr, + const char *name) +{ + struct device_node *np = dev->of_node; + unsigned i; + + for (i = 0; ; i++) { + struct device_node *node; + + node = of_parse_phandle(np, name, i); + if (!node) + break; + + component_match_add(dev, matchptr, compare_of, node); + } + + return 0; +} #else static int compare_dev(struct device *dev, void *data) { @@ -935,21 +954,8 @@ static int msm_pdev_probe(struct platform_device *pdev) { struct component_match *match = NULL; #ifdef CONFIG_OF - /* NOTE: the CONFIG_OF case duplicates the same code as exynos or imx - * (or probably any other).. so probably some room for some helpers - */ - struct device_node *np = pdev->dev.of_node; - unsigned i; - - for (i = 0; ; i++) { - struct device_node *node; - - node = of_parse_phandle(np, "connectors", i); - if (!node) - break; - - component_match_add(&pdev->dev, &match, compare_of, node); - } + add_components(&pdev->dev, &match, "connectors"); + add_components(&pdev->dev, &match, "gpus"); #else /* For non-DT case, it kinda sucks. We don't actually have a way * 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[] = { }; static const struct of_device_id dt_match[] = { - { .compatible = "qcom,mdss_mdp" }, + { .compatible = "qcom,mdp" }, /* mdp4 */ + { .compatible = "qcom,mdss_mdp" }, /* mdp5 */ {} }; MODULE_DEVICE_TABLE(of, dt_match); |