summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDeepak Katragadda <dkatraga@codeaurora.org>2016-01-21 12:26:55 -0800
committerKyle Yan <kyan@codeaurora.org>2016-06-02 16:14:05 -0700
commit587539cd1fb40d4126a925e7040e684f123425a2 (patch)
tree96d59fcf5414356ac576034ec0150e196141f789
parentcdd6e17060c924df2caf410029445fab820f8502 (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.txt4
-rw-r--r--arch/arm/boot/dts/qcom/msm8996.dtsi10
-rw-r--r--drivers/clk/msm/clock-mmss-8996.c89
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" },
{},
};