diff options
| author | Deepak Katragadda <dkatraga@codeaurora.org> | 2016-01-21 12:26:55 -0800 |
|---|---|---|
| committer | Kyle Yan <kyan@codeaurora.org> | 2016-06-02 16:14:05 -0700 |
| commit | 587539cd1fb40d4126a925e7040e684f123425a2 (patch) | |
| tree | 96d59fcf5414356ac576034ec0150e196141f789 | |
| parent | cdd6e17060c924df2caf410029445fab820f8502 (diff) | |
clk: msm: clock-mmss-8996: Add graphics clocks support on msm8996 Pro
The graphics clock frequencies need to be updated for
msm8996 Pro. Add support for doing the same using the
bin fuse values.
CRs-Fixed: 1022663
Change-Id: I60185482ae9b5364e297370593d95cce056b314e
Signed-off-by: Deepak Katragadda <dkatraga@codeaurora.org>
| -rw-r--r-- | Documentation/devicetree/bindings/arm/msm/clock-controller.txt | 4 | ||||
| -rw-r--r-- | arch/arm/boot/dts/qcom/msm8996.dtsi | 10 | ||||
| -rw-r--r-- | drivers/clk/msm/clock-mmss-8996.c | 89 |
3 files changed, 67 insertions, 36 deletions
diff --git a/Documentation/devicetree/bindings/arm/msm/clock-controller.txt b/Documentation/devicetree/bindings/arm/msm/clock-controller.txt index 0f6175897d27..20506e132727 100644 --- a/Documentation/devicetree/bindings/arm/msm/clock-controller.txt +++ b/Documentation/devicetree/bindings/arm/msm/clock-controller.txt @@ -54,10 +54,12 @@ Required properties: "qcom,mmsscc-8996" "qcom,mmsscc-8996-v2" "qcom,mmsscc-8996-v3" + "qcom,mmsscc-8996-pro" "qcom,gpucc-8996" "qcom,gpucc-8996-v2" "qcom,gpucc-8996-v3" "qcom,gpucc-8996-v3.0" + "qcom,gpucc-8996-pro" "qcom,gcc-gfx-titanium" "qcom,gcc-californium" "qcom,cc-debug-californium" @@ -83,7 +85,7 @@ Required properties: there is one expected base: "cc_base". Optional reg-names are "apcs_base", "meas", "mmss_base", "lpass_base", "apcs_c0_base", "apcs_c1_base", - "apcs_cci_base". + "apcs_cci_base", "efuse". Optional properties: - vdd_dig-supply: The digital logic rail supply. diff --git a/arch/arm/boot/dts/qcom/msm8996.dtsi b/arch/arm/boot/dts/qcom/msm8996.dtsi index e0bd005f8b76..70f98c3b98c7 100644 --- a/arch/arm/boot/dts/qcom/msm8996.dtsi +++ b/arch/arm/boot/dts/qcom/msm8996.dtsi @@ -787,8 +787,9 @@ clock_mmss: qcom,mmsscc@8c0000 { compatible = "qcom,mmsscc-8996"; - reg = <0x8c0000 0xb00c>; - reg-names = "cc_base"; + reg = <0x8c0000 0xb00c>, + <0x74130 0x8>; + reg-names = "cc_base", "efuse"; vdd_dig-supply = <&pm8994_s1_corner>; mmpll4_dig-supply = <&pm8994_s1_corner>; mmpll4_analog-supply = <&pm8994_l12>; @@ -812,9 +813,8 @@ clock_gpu: qcom,gpucc@8c0000 { compatible = "qcom,gpucc-8996"; - reg = <0x8c0000 0xb00c>, - <0x74130 0x8>; - reg-names = "cc_base", "efuse"; + reg = <0x8c0000 0xb00c>; + reg-names = "cc_base"; vdd_gfx-supply = <&gfx_vreg>; qcom,gfx3d_clk_src-opp-handle = <&msm_gpu>; vdd_mx-supply = <&pm8994_s2_corner>; diff --git a/drivers/clk/msm/clock-mmss-8996.c b/drivers/clk/msm/clock-mmss-8996.c index 2b8a2d2edcbc..ba81731ce1cb 100644 --- a/drivers/clk/msm/clock-mmss-8996.c +++ b/drivers/clk/msm/clock-mmss-8996.c @@ -68,8 +68,10 @@ static void __iomem *virt_base_gpu; #define GFX_MIN_SVS_LEVEL 2 #define GPU_REQ_ID 0x3 -#define EFUSE_SHIFT 29 -#define EFUSE_MASK 0x7 +#define EFUSE_SHIFT_v3 29 +#define EFUSE_MASK_v3 0x7 +#define EFUSE_SHIFT_PRO 28 +#define EFUSE_MASK_PRO 0x3 static struct clk_ops clk_ops_gpu; @@ -404,9 +406,9 @@ static struct mux_div_clk gfx3d_clk_src_v2 = { .max_div = 1, }, .parents = (struct clk_src[]) { + {&mmpll9_postdiv_clk.c, 2}, {&mmpll2_postdiv_clk.c, 3}, {&mmpll8_postdiv_clk.c, 4}, - {&mmpll9_postdiv_clk.c, 2}, }, .num_parents = 3, .c = { @@ -3516,6 +3518,19 @@ static void msm_mmsscc_8996_v3_fixup(void) video_subcore1_clk_src.c.fmax[VDD_DIG_HIGH] = 520000000; } +static void msm_mmsscc_8996_pro_fixup(void) +{ + mmpll9.c.rate = 0; + mmpll9.c.fmax[VDD_DIG_LOWER] = 652800000; + mmpll9.c.fmax[VDD_DIG_LOW] = 652800000; + mmpll9.c.fmax[VDD_DIG_NOMINAL] = 1305600000; + mmpll9.c.fmax[VDD_DIG_HIGH] = 1305600000; + mmpll9.c.ops = &clk_ops_alpha_pll; + mmpll9.min_supported_freq = 1248000000; + + mmpll9_postdiv_clk.c.ops = &clk_ops_div; +} + static int is_v3_gpu; static int gpu_pre_set_rate(struct clk *clk, unsigned long new_rate) { @@ -3614,6 +3629,10 @@ static int of_get_fmax_vdd_class(struct platform_device *pdev, struct clk *c, } static struct platform_driver msm_clock_gpu_driver; +struct resource *efuse_res; +void __iomem *gpu_base; +u64 efuse; +int gpu_speed_bin; int msm_mmsscc_8996_probe(struct platform_device *pdev) { @@ -3622,19 +3641,33 @@ int msm_mmsscc_8996_probe(struct platform_device *pdev) struct clk *tmp; struct regulator *reg; u32 regval; - int is_v2, is_v3 = 0; + int is_pro, is_v2, is_v3 = 0; res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cc_base"); if (!res) { dev_err(&pdev->dev, "Unable to retrieve register base.\n"); return -ENOMEM; } + + efuse_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "efuse"); + if (!efuse_res) { + dev_err(&pdev->dev, "Unable to retrieve efuse register base.\n"); + return -ENOMEM; + } + virt_base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); if (!virt_base) { dev_err(&pdev->dev, "Failed to map CC registers\n"); return -ENOMEM; } + gpu_base = devm_ioremap(&pdev->dev, efuse_res->start, + resource_size(efuse_res)); + if (!gpu_base) { + dev_err(&pdev->dev, "Unable to map in efuse base\n"); + return -ENOMEM; + } + /* Clear the DBG_CLK_DIV bits of the MMSS debug register */ regval = readl_relaxed(virt_base + mmss_gcc_dbg_clk.offset); regval &= ~BM(18, 17); @@ -3710,6 +3743,9 @@ int msm_mmsscc_8996_probe(struct platform_device *pdev) ext_extpclk_clk_src.dev = &pdev->dev; ext_extpclk_clk_src.clk_id = "extpclk_src"; + efuse = readl_relaxed(gpu_base); + gpu_speed_bin = ((efuse >> EFUSE_SHIFT_v3) & EFUSE_MASK_v3); + is_v2 = of_device_is_compatible(pdev->dev.of_node, "qcom,mmsscc-8996-v2"); if (is_v2) @@ -3720,14 +3756,22 @@ int msm_mmsscc_8996_probe(struct platform_device *pdev) if (is_v3) msm_mmsscc_8996_v3_fixup(); + is_pro = of_device_is_compatible(pdev->dev.of_node, + "qcom,mmsscc-8996-pro"); + if (is_pro) { + gpu_speed_bin = ((efuse >> EFUSE_SHIFT_PRO) & EFUSE_MASK_PRO); + msm_mmsscc_8996_v3_fixup(); + if (!gpu_speed_bin) + msm_mmsscc_8996_pro_fixup(); + } rc = of_msm_clock_register(pdev->dev.of_node, msm_clocks_mmss_8996, ARRAY_SIZE(msm_clocks_mmss_8996)); if (rc) return rc; - /* Register v2/v3 specific clocks */ - if (is_v2 || is_v3) { + /* Register v2/v3/pro specific clocks */ + if (is_v2 || is_v3 || is_pro) { rc = of_msm_clock_register(pdev->dev.of_node, msm_clocks_mmsscc_8996_v2, ARRAY_SIZE(msm_clocks_mmsscc_8996_v2)); @@ -3743,6 +3787,7 @@ static struct of_device_id msm_clock_mmss_match_table[] = { { .compatible = "qcom,mmsscc-8996" }, { .compatible = "qcom,mmsscc-8996-v2" }, { .compatible = "qcom,mmsscc-8996-v3" }, + { .compatible = "qcom,mmsscc-8996-pro" }, {}, }; @@ -3807,14 +3852,11 @@ static void msm_gpucc_8996_v2_fixup(void) int msm_gpucc_8996_probe(struct platform_device *pdev) { - struct resource *res, *efuse_res; + struct resource *res; struct device_node *of_node = pdev->dev.of_node; - void __iomem *base; int rc; struct regulator *reg; - u64 efuse; - int speed_bin; - int is_v2_gpu, is_v3_0_gpu; + int is_v2_gpu, is_v3_0_gpu, is_pro_gpu; char speedbin_str[] = "qcom,gfxfreq-speedbin0"; char mx_speedbin_str[] = "qcom,gfxfreq-mx-speedbin0"; @@ -3827,12 +3869,6 @@ int msm_gpucc_8996_probe(struct platform_device *pdev) return -ENOMEM; } - efuse_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "efuse"); - if (!efuse_res) { - dev_err(&pdev->dev, "Unable to retrieve efuse register base.\n"); - return -ENOMEM; - } - gfx3d_clk_src_v2.base = virt_base_gpu = devm_ioremap(&pdev->dev, res->start, resource_size(res)); if (!virt_base_gpu) { @@ -3840,13 +3876,6 @@ int msm_gpucc_8996_probe(struct platform_device *pdev) return -ENOMEM; } - base = devm_ioremap(&pdev->dev, efuse_res->start, - resource_size(efuse_res)); - if (!base) { - dev_err(&pdev->dev, "Unable to map in efuse base\n"); - return -ENOMEM; - } - reg = vdd_gfx.regulator[0] = devm_regulator_get(&pdev->dev, "vdd_gfx"); if (IS_ERR(reg)) { if (PTR_ERR(reg) != -EPROBE_DEFER) @@ -3874,14 +3903,13 @@ int msm_gpucc_8996_probe(struct platform_device *pdev) is_v2_gpu = of_device_is_compatible(of_node, "qcom,gpucc-8996-v2"); is_v3_gpu = of_device_is_compatible(of_node, "qcom,gpucc-8996-v3"); is_v3_0_gpu = of_device_is_compatible(of_node, "qcom,gpucc-8996-v3.0"); + is_pro_gpu = of_device_is_compatible(of_node, "qcom,gpucc-8996-pro"); - efuse = readl_relaxed(base); - speed_bin = ((efuse >> EFUSE_SHIFT) & EFUSE_MASK); - dev_info(&pdev->dev, "using speed bin %u\n", speed_bin); + dev_info(&pdev->dev, "using speed bin %u\n", gpu_speed_bin); snprintf(speedbin_str, ARRAY_SIZE(speedbin_str), - "qcom,gfxfreq-speedbin%d", speed_bin); + "qcom,gfxfreq-speedbin%d", gpu_speed_bin); snprintf(mx_speedbin_str, ARRAY_SIZE(mx_speedbin_str), - "qcom,gfxfreq-mx-speedbin%d", speed_bin); + "qcom,gfxfreq-mx-speedbin%d", gpu_speed_bin); rc = of_get_fmax_vdd_class(pdev, &gpu_mx_clk.c, mx_speedbin_str); if (rc) { @@ -3894,7 +3922,7 @@ int msm_gpucc_8996_probe(struct platform_device *pdev) } } - if (!is_v2_gpu && !is_v3_gpu && !is_v3_0_gpu) { + if (!is_v2_gpu && !is_v3_gpu && !is_v3_0_gpu && !is_pro_gpu) { rc = of_get_fmax_vdd_class(pdev, &gfx3d_clk_src.c, speedbin_str); if (rc) { @@ -3946,6 +3974,7 @@ static struct of_device_id msm_clock_gpu_match_table[] = { { .compatible = "qcom,gpucc-8996-v2" }, { .compatible = "qcom,gpucc-8996-v3" }, { .compatible = "qcom,gpucc-8996-v3.0" }, + { .compatible = "qcom,gpucc-8996-pro" }, {}, }; |
