Loading Documentation/devicetree/bindings/arm/msm/clock-krait-8974.txt +7 −2 Original line number Diff line number Diff line Loading @@ -12,7 +12,7 @@ Required properties: - reg-names: Names of the bases for the above registers. Expected bases are: "hfpll_l2_clk", "hfpll0_clk", ... "hfpllN_clk", "efuse", "meas" "efuse_svs", "meas" - cpuX-supply: The regulator powering the CPUX. - l2-dig-supply: The regulator powering the L2 digital logic. - hfpll-dig-supply: The regulator powering the HFPLL digital domains. Loading Loading @@ -44,6 +44,8 @@ Optional properties: bits in the user control register. - qcom,pvs-config-ver: The version of the data in qcom,speedX-pvsY-bin-vZ. - qcom,svs-fmax: The max frequency for the SVS voltage for Krait. Example: qcom,clock-krait@f9016000 { Loading @@ -53,10 +55,11 @@ Example: <0xf909a000 0x20>, <0xf90aa000 0x20>, <0xf90ba000 0x20>, <0xfc4b8458 0x04>, <0xfc4b80b0 0x08>; reg-names = "hfpll_l2_clk", "hfpll0_clk", "hfpll1_clk", "hfpll2_clk", "hfpll3_clk", "efuse"; "hfpll3_clk", "efuse", "efuse_svs"; cpu0-supply = <&krait0_vreg>; cpu1-supply = <&krait1_vreg>; cpu2-supply = <&krait2_vreg>; Loading @@ -70,6 +73,8 @@ Example: < 1036800000 5 /* normal */ >, < 1728000000 7 /* super_turbo */>; qcom,svs-fmax = <883200000>; qcom,avs-tbl = < 300000000 0xfa70054 >, < 1574400000 0xfa70100 >; Loading drivers/clk/qcom/clock-krait-8974.c +95 −6 Original line number Diff line number Diff line Loading @@ -490,15 +490,17 @@ static struct clk *cpu_clk[] = { }; static void get_krait_bin_format_b(struct platform_device *pdev, int *speed, int *pvs, int *pvs_ver) int *speed, int *pvs, int *svs_pvs, int *pvs_ver) { u32 pte_efuse, redundant_sel; struct resource *res; void __iomem *base; void __iomem *base_svs; *speed = 0; *pvs = 0; *pvs_ver = 0; *svs_pvs = -1; res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "efuse"); if (!res) { Loading Loading @@ -538,13 +540,40 @@ static void get_krait_bin_format_b(struct platform_device *pdev, *speed = 0; } /* Check SVS PVS bin */ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "efuse_svs"); if (res) { base_svs = devm_ioremap(&pdev->dev, res->start, resource_size(res)); /* Read the svs pvs value if status bit 28 is valid (set) */ if (!base_svs) { *svs_pvs = 0; dev_warn(&pdev->dev, "Unable to read svs efuse data. Defaulting to 0!\n"); } else { pte_efuse = readl_relaxed(base_svs); /* * Read the svs pvs value if status bit 28 is valid * 4 bits of SVS PVS are in efuse register bits 27-24 */ if (pte_efuse & BIT(28)) *svs_pvs = (pte_efuse >> 24) & 0xF; devm_iounmap(&pdev->dev, base_svs); } } /* Check PVS_BLOW_STATUS */ pte_efuse = readl_relaxed(base + 0x4) & BIT(21); if (pte_efuse) { dev_info(&pdev->dev, "PVS bin: %d\n", *pvs); if (*svs_pvs >= 0) dev_info(&pdev->dev, "SVS PVS bin: %d\n", *svs_pvs); } else { dev_warn(&pdev->dev, "PVS bin not set. Defaulting to 0!\n"); *pvs = 0; *svs_pvs = -1; } dev_info(&pdev->dev, "PVS version: %d\n", *pvs_ver); Loading Loading @@ -670,11 +699,11 @@ static int clock_krait_8974_driver_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct clk *c; int speed, pvs, pvs_ver, config_ver, rows, cpu; unsigned long *freq, cur_rate, aux_rate; int speed, pvs, svs_pvs, pvs_ver, config_ver, rows, cpu, svs_row = 0; unsigned long *freq, *svs_freq, cur_rate, aux_rate; struct resource *res; int *uv, *ua; u32 *dscr, vco_mask, config_val; int *uv, *ua, *svs_uv, *svs_ua; u32 *dscr, vco_mask, config_val, svs_fmax; int ret; vdd_l2.regulator[0] = devm_regulator_get(dev, "l2-dig"); Loading Loading @@ -761,7 +790,7 @@ static int clock_krait_8974_driver_probe(struct platform_device *pdev) dev_info(&pdev->dev, "PVS config version: %d\n", config_ver); } get_krait_bin_format_b(pdev, &speed, &pvs, &pvs_ver); get_krait_bin_format_b(pdev, &speed, &pvs, &svs_pvs, &pvs_ver); snprintf(table_name, ARRAY_SIZE(table_name), "qcom,speed%d-pvs%d-bin-v%d", speed, pvs, pvs_ver); Loading @@ -780,6 +809,66 @@ static int clock_krait_8974_driver_probe(struct platform_device *pdev) pvs = 0; rows = ret; } } else if (svs_pvs >= 0) { /* Find the split freq for svs fmax */ ret = of_property_read_u32(dev->of_node, "qcom,svs-fmax", &svs_fmax); if (ret) { dev_err(dev, "Unable to find krait fmax for svs\n"); return ret; } /* Find the svs fmax freq row */ while ((svs_row < rows) && (freq[svs_row] != svs_fmax)) svs_row++; if (svs_row == rows) { dev_err(dev, "Invalid krait fmax for svs\n"); return -EINVAL; } snprintf(table_name, ARRAY_SIZE(table_name), "qcom,speed%d-pvs%d-bin-v%d", speed, svs_pvs, pvs_ver); rows = parse_tbl(dev, table_name, 3, (u32 **) &svs_freq, (u32 **) &svs_uv, (u32 **) &svs_ua); if (rows > 0) { /* Use the svs voltage data for svs freqs */ while (svs_row >= 0) { uv[svs_row] = svs_uv[svs_row]; svs_row--; } devm_kfree(dev, svs_freq); devm_kfree(dev, svs_uv); devm_kfree(dev, svs_ua); } else { /* Fall back to most conservative svs pvs table */ dev_err(dev, "Unable to load svs voltage plan %s!\n", table_name); snprintf(table_name, ARRAY_SIZE(table_name), "qcom,speed0-pvs0-bin-v%d", pvs_ver); rows = parse_tbl(dev, table_name, 3, (u32 **) &svs_freq, (u32 **) &svs_uv, (u32 **) &svs_ua); if (rows < 0) { dev_err(dev, "Unable to load safe voltage plan.\n"); return rows; } else { dev_info(dev, "Safe svs voltage plan loaded.\n"); while (svs_row >= 0) { uv[svs_row] = svs_uv[svs_row]; svs_row--; } devm_kfree(dev, svs_freq); devm_kfree(dev, svs_uv); devm_kfree(dev, svs_ua); } } } krait_update_uv(uv, rows, pvs ? 25000 : 0); Loading Loading
Documentation/devicetree/bindings/arm/msm/clock-krait-8974.txt +7 −2 Original line number Diff line number Diff line Loading @@ -12,7 +12,7 @@ Required properties: - reg-names: Names of the bases for the above registers. Expected bases are: "hfpll_l2_clk", "hfpll0_clk", ... "hfpllN_clk", "efuse", "meas" "efuse_svs", "meas" - cpuX-supply: The regulator powering the CPUX. - l2-dig-supply: The regulator powering the L2 digital logic. - hfpll-dig-supply: The regulator powering the HFPLL digital domains. Loading Loading @@ -44,6 +44,8 @@ Optional properties: bits in the user control register. - qcom,pvs-config-ver: The version of the data in qcom,speedX-pvsY-bin-vZ. - qcom,svs-fmax: The max frequency for the SVS voltage for Krait. Example: qcom,clock-krait@f9016000 { Loading @@ -53,10 +55,11 @@ Example: <0xf909a000 0x20>, <0xf90aa000 0x20>, <0xf90ba000 0x20>, <0xfc4b8458 0x04>, <0xfc4b80b0 0x08>; reg-names = "hfpll_l2_clk", "hfpll0_clk", "hfpll1_clk", "hfpll2_clk", "hfpll3_clk", "efuse"; "hfpll3_clk", "efuse", "efuse_svs"; cpu0-supply = <&krait0_vreg>; cpu1-supply = <&krait1_vreg>; cpu2-supply = <&krait2_vreg>; Loading @@ -70,6 +73,8 @@ Example: < 1036800000 5 /* normal */ >, < 1728000000 7 /* super_turbo */>; qcom,svs-fmax = <883200000>; qcom,avs-tbl = < 300000000 0xfa70054 >, < 1574400000 0xfa70100 >; Loading
drivers/clk/qcom/clock-krait-8974.c +95 −6 Original line number Diff line number Diff line Loading @@ -490,15 +490,17 @@ static struct clk *cpu_clk[] = { }; static void get_krait_bin_format_b(struct platform_device *pdev, int *speed, int *pvs, int *pvs_ver) int *speed, int *pvs, int *svs_pvs, int *pvs_ver) { u32 pte_efuse, redundant_sel; struct resource *res; void __iomem *base; void __iomem *base_svs; *speed = 0; *pvs = 0; *pvs_ver = 0; *svs_pvs = -1; res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "efuse"); if (!res) { Loading Loading @@ -538,13 +540,40 @@ static void get_krait_bin_format_b(struct platform_device *pdev, *speed = 0; } /* Check SVS PVS bin */ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "efuse_svs"); if (res) { base_svs = devm_ioremap(&pdev->dev, res->start, resource_size(res)); /* Read the svs pvs value if status bit 28 is valid (set) */ if (!base_svs) { *svs_pvs = 0; dev_warn(&pdev->dev, "Unable to read svs efuse data. Defaulting to 0!\n"); } else { pte_efuse = readl_relaxed(base_svs); /* * Read the svs pvs value if status bit 28 is valid * 4 bits of SVS PVS are in efuse register bits 27-24 */ if (pte_efuse & BIT(28)) *svs_pvs = (pte_efuse >> 24) & 0xF; devm_iounmap(&pdev->dev, base_svs); } } /* Check PVS_BLOW_STATUS */ pte_efuse = readl_relaxed(base + 0x4) & BIT(21); if (pte_efuse) { dev_info(&pdev->dev, "PVS bin: %d\n", *pvs); if (*svs_pvs >= 0) dev_info(&pdev->dev, "SVS PVS bin: %d\n", *svs_pvs); } else { dev_warn(&pdev->dev, "PVS bin not set. Defaulting to 0!\n"); *pvs = 0; *svs_pvs = -1; } dev_info(&pdev->dev, "PVS version: %d\n", *pvs_ver); Loading Loading @@ -670,11 +699,11 @@ static int clock_krait_8974_driver_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct clk *c; int speed, pvs, pvs_ver, config_ver, rows, cpu; unsigned long *freq, cur_rate, aux_rate; int speed, pvs, svs_pvs, pvs_ver, config_ver, rows, cpu, svs_row = 0; unsigned long *freq, *svs_freq, cur_rate, aux_rate; struct resource *res; int *uv, *ua; u32 *dscr, vco_mask, config_val; int *uv, *ua, *svs_uv, *svs_ua; u32 *dscr, vco_mask, config_val, svs_fmax; int ret; vdd_l2.regulator[0] = devm_regulator_get(dev, "l2-dig"); Loading Loading @@ -761,7 +790,7 @@ static int clock_krait_8974_driver_probe(struct platform_device *pdev) dev_info(&pdev->dev, "PVS config version: %d\n", config_ver); } get_krait_bin_format_b(pdev, &speed, &pvs, &pvs_ver); get_krait_bin_format_b(pdev, &speed, &pvs, &svs_pvs, &pvs_ver); snprintf(table_name, ARRAY_SIZE(table_name), "qcom,speed%d-pvs%d-bin-v%d", speed, pvs, pvs_ver); Loading @@ -780,6 +809,66 @@ static int clock_krait_8974_driver_probe(struct platform_device *pdev) pvs = 0; rows = ret; } } else if (svs_pvs >= 0) { /* Find the split freq for svs fmax */ ret = of_property_read_u32(dev->of_node, "qcom,svs-fmax", &svs_fmax); if (ret) { dev_err(dev, "Unable to find krait fmax for svs\n"); return ret; } /* Find the svs fmax freq row */ while ((svs_row < rows) && (freq[svs_row] != svs_fmax)) svs_row++; if (svs_row == rows) { dev_err(dev, "Invalid krait fmax for svs\n"); return -EINVAL; } snprintf(table_name, ARRAY_SIZE(table_name), "qcom,speed%d-pvs%d-bin-v%d", speed, svs_pvs, pvs_ver); rows = parse_tbl(dev, table_name, 3, (u32 **) &svs_freq, (u32 **) &svs_uv, (u32 **) &svs_ua); if (rows > 0) { /* Use the svs voltage data for svs freqs */ while (svs_row >= 0) { uv[svs_row] = svs_uv[svs_row]; svs_row--; } devm_kfree(dev, svs_freq); devm_kfree(dev, svs_uv); devm_kfree(dev, svs_ua); } else { /* Fall back to most conservative svs pvs table */ dev_err(dev, "Unable to load svs voltage plan %s!\n", table_name); snprintf(table_name, ARRAY_SIZE(table_name), "qcom,speed0-pvs0-bin-v%d", pvs_ver); rows = parse_tbl(dev, table_name, 3, (u32 **) &svs_freq, (u32 **) &svs_uv, (u32 **) &svs_ua); if (rows < 0) { dev_err(dev, "Unable to load safe voltage plan.\n"); return rows; } else { dev_info(dev, "Safe svs voltage plan loaded.\n"); while (svs_row >= 0) { uv[svs_row] = svs_uv[svs_row]; svs_row--; } devm_kfree(dev, svs_freq); devm_kfree(dev, svs_uv); devm_kfree(dev, svs_ua); } } } krait_update_uv(uv, rows, pvs ? 25000 : 0); Loading