Loading Documentation/devicetree/bindings/arm/msm/clock-cpu-8939.txt +3 −1 Original line number Diff line number Diff line Loading @@ -7,7 +7,7 @@ fmax tables, avs settings table, etc. Required properties: - compatible: Must be one of "qcom,clock-cpu-8939" or "qcom,cpu-clock-8952" "qcom,cpu-clock-8952", "qcom,cpu-clock-gold". - reg: Pairs of physical base addresses and region sizes of memory mapped registers. - reg-names: Names of the bases for the above registers. Expected Loading @@ -33,6 +33,8 @@ Required properties: Optional properties: - qcom,cpu-pcnoc-vote: Boolean to indicate cpu clocks would need to keep active pcnoc vote. - qcom,num-cluster: Boolean to indicate cpu clock code is used for single cluster. Example: clock_cpu: qcom,cpu-clock-8939@f9015000 { compatible = "qcom,cpu-clock-8939"; Loading arch/arm/boot/dts/qcom/msm8937.dtsi +6 −6 Original line number Diff line number Diff line Loading @@ -566,11 +566,11 @@ clock_gcc: qcom,gcc@1800000 { compatible = "qcom,gcc-8937"; reg = <0x1800000 0x80000>, <0xb116000 0x00040>, <0xb016000 0x00040>, <0xb116000 0x00040>, <0xb1d0000 0x00040>; reg-names = "cc_base", "apcs_c0_base", "apcs_c1_base", "apcs_cci_base"; reg-names = "cc_base", "apcs_c1_base", "apcs_c0_base", "apcs_cci_base"; vdd_dig-supply = <&pm8937_s2_level>; vdd_sr2_dig-supply = <&pm8937_s2_level_ao>; vdd_sr2_pll-supply = <&pm8937_l7_ao>; Loading Loading @@ -607,11 +607,11 @@ clock_cpu: qcom,cpu-clock-8939@b111050 { compatible = "qcom,cpu-clock-8939"; reg = <0xb111050 0x8>, <0xb011050 0x8>, reg = <0xb011050 0x8>, <0xb111050 0x8>, <0xb1d1050 0x8>, <0x00a412c 0x8>; reg-names = "apcs-c0-rcg-base", "apcs-c1-rcg-base", reg-names = "apcs-c1-rcg-base", "apcs-c0-rcg-base", "apcs-cci-rcg-base", "efuse"; vdd-c0-supply = <&apc_vreg_corner>; vdd-c1-supply = <&apc_vreg_corner>; Loading arch/arm/boot/dts/qcom/msm8952.dtsi +6 −6 Original line number Diff line number Diff line Loading @@ -145,11 +145,11 @@ #size-cells = <1>; compatible = "qcom,gcc-8952"; reg = <0x1800000 0x80000>, <0xb116000 0x00040>, <0xb016000 0x00040>, <0xb116000 0x00040>, <0xb1d0000 0x00040>; reg-names = "cc_base", "apcs_c0_base", "apcs_c1_base", "apcs_cci_base"; reg-names = "cc_base", "apcs_c1_base", "apcs_c0_base", "apcs_cci_base"; vdd_dig-supply = <&pm8950_s2_level>; vdd_sr2_dig-supply = <&pm8950_s2_level_ao>; vdd_sr2_pll-supply = <&pm8950_l7_ao>; Loading Loading @@ -185,11 +185,11 @@ clock_cpu: qcom,cpu-clock-8939@b111050 { compatible = "qcom,cpu-clock-8939"; reg = <0xb111050 0x8>, <0xb011050 0x8>, reg = <0xb011050 0x8>, <0xb111050 0x8>, <0xb1d1050 0x8>, <0x005c00c 0x8>; reg-names = "apcs-c0-rcg-base", "apcs-c1-rcg-base", reg-names = "apcs-c1-rcg-base", "apcs-c0-rcg-base", "apcs-cci-rcg-base", "efuse"; vdd-c0-supply = <&apc_vreg_corner>; vdd-c1-supply = <&apc_vreg_corner>; Loading drivers/clk/msm/clock-cpu-8939.c +86 −30 Original line number Diff line number Diff line Loading @@ -203,6 +203,12 @@ static struct clk_lookup cpu_clocks_8939[] = { CLK_LIST(cci_clk), }; static struct clk_lookup cpu_clocks_8939_single_cluster[] = { CLK_LIST(a53ssmux_bc), CLK_LIST(a53_bc_clk), }; static struct mux_div_clk *a53ssmux[] = {&a53ssmux_bc, &a53ssmux_lc, &a53ssmux_cci}; Loading Loading @@ -516,30 +522,33 @@ static int add_opp(struct clk *c, struct device *cpudev, struct device *vregdev, return 0; } static void print_opp_table(int a53_c0_cpu, int a53_c1_cpu) static void print_opp_table(int a53_c0_cpu, int a53_c1_cpu, bool single_cluster) { struct dev_pm_opp *oppfmax, *oppfmin; unsigned long apc0_fmax, apc1_fmax, apc0_fmin, apc1_fmin; if (!single_cluster) { apc0_fmax = a53_lc_clk.c.fmax[a53_lc_clk.c.num_fmax - 1]; apc1_fmax = a53_bc_clk.c.fmax[a53_bc_clk.c.num_fmax - 1]; apc0_fmin = a53_lc_clk.c.fmax[1]; } apc1_fmax = a53_bc_clk.c.fmax[a53_bc_clk.c.num_fmax - 1]; apc1_fmin = a53_bc_clk.c.fmax[1]; rcu_read_lock(); if (!single_cluster) { oppfmax = dev_pm_opp_find_freq_exact(get_cpu_device(a53_c0_cpu), apc0_fmax, true); oppfmin = dev_pm_opp_find_freq_exact(get_cpu_device(a53_c0_cpu), apc0_fmin, true); /* * One time information during boot. Important to know that this looks * sane since it can eventually make its way to the scheduler. * One time information during boot. Important to know that this * looks sane since it can eventually make its way to the * scheduler. */ pr_info("clock_cpu: a53_c0: OPP voltage for %lu: %ld\n", apc0_fmin, dev_pm_opp_get_voltage(oppfmin)); pr_info("clock_cpu: a53_c0: OPP voltage for %lu: %ld\n", apc0_fmax, dev_pm_opp_get_voltage(oppfmax)); pr_info("clock_cpu: a53_c0: OPP voltage for %lu: %ld\n", apc0_fmin, dev_pm_opp_get_voltage(oppfmin)); pr_info("clock_cpu: a53_c0: OPP voltage for %lu: %ld\n", apc0_fmax, dev_pm_opp_get_voltage(oppfmax)); } oppfmax = dev_pm_opp_find_freq_exact(get_cpu_device(a53_c1_cpu), apc1_fmax, true); oppfmin = dev_pm_opp_find_freq_exact(get_cpu_device(a53_c1_cpu), Loading @@ -551,16 +560,19 @@ static void print_opp_table(int a53_c0_cpu, int a53_c1_cpu) rcu_read_unlock(); } static void populate_opp_table(struct platform_device *pdev) static void populate_opp_table(struct platform_device *pdev, bool single_cluster) { struct platform_device *apc0_dev, *apc1_dev; struct device_node *apc0_node, *apc1_node; unsigned long apc0_fmax, apc1_fmax; int cpu, a53_c0_cpu, a53_c1_cpu; apc0_node = of_parse_phandle(pdev->dev.of_node, "vdd-c0-supply", 0); if (!single_cluster) apc0_node = of_parse_phandle(pdev->dev.of_node, "vdd-c0-supply", 0); apc1_node = of_parse_phandle(pdev->dev.of_node, "vdd-c1-supply", 0); if (!apc0_node) { if (!apc0_node && !single_cluster) { pr_err("can't find the apc0 dt node.\n"); return; } Loading @@ -568,10 +580,11 @@ static void populate_opp_table(struct platform_device *pdev) pr_err("can't find the apc1 dt node.\n"); return; } if (!single_cluster) apc0_dev = of_find_device_by_node(apc0_node); apc1_dev = of_find_device_by_node(apc1_node); if (!apc0_dev) { if (!apc1_dev && !single_cluster) { pr_err("can't find the apc0 device node.\n"); return; } Loading @@ -580,7 +593,9 @@ static void populate_opp_table(struct platform_device *pdev) return; } if (!single_cluster) apc0_fmax = a53_lc_clk.c.fmax[a53_lc_clk.c.num_fmax - 1]; apc1_fmax = a53_bc_clk.c.fmax[a53_bc_clk.c.num_fmax - 1]; for_each_possible_cpu(cpu) { Loading @@ -590,7 +605,7 @@ static void populate_opp_table(struct platform_device *pdev) WARN(add_opp(&a53_bc_clk.c, get_cpu_device(cpu), &apc1_dev->dev, apc1_fmax), "Failed to add OPP levels for A53 big cluster\n"); } else if (cpu/4 == 1) { } else if (cpu/4 == 1 && !single_cluster) { a53_c0_cpu = cpu; WARN(add_opp(&a53_lc_clk.c, get_cpu_device(cpu), &apc0_dev->dev, apc0_fmax), Loading @@ -602,7 +617,8 @@ static void populate_opp_table(struct platform_device *pdev) pr_info("clock-cpu-8939: OPP tables populated (cpu %d and %d)", a53_c0_cpu, a53_c1_cpu); print_opp_table(a53_c0_cpu, a53_c1_cpu); print_opp_table(a53_c0_cpu, a53_c1_cpu, single_cluster); } static void config_pll(int mux_id) Loading Loading @@ -644,18 +660,47 @@ static int clock_8939_pm_event(struct notifier_block *this, return NOTIFY_DONE; } static int clock_8939_pm_event_single_cluster(struct notifier_block *this, unsigned long event, void *ptr) { switch (event) { case PM_POST_HIBERNATION: case PM_POST_SUSPEND: clk_unprepare(&a53_bc_clk.c); break; case PM_HIBERNATION_PREPARE: case PM_SUSPEND_PREPARE: clk_prepare(&a53_bc_clk.c); break; default: break; } return NOTIFY_DONE; } static struct notifier_block clock_8939_pm_notifier = { .notifier_call = clock_8939_pm_event, }; static struct notifier_block clock_8939_pm_notifier_single_cluster = { .notifier_call = clock_8939_pm_event_single_cluster, }; static int clock_a53_probe(struct platform_device *pdev) { int speed_bin, version, rc, cpu, mux_id, rate; char prop_name[] = "qcom,speedX-bin-vX-XXX"; int mux_num; bool single_cluster; single_cluster = of_property_read_bool(pdev->dev.of_node, "qcom,num-cluster"); get_speed_bin(pdev, &speed_bin, &version); for (mux_id = 0; mux_id < A53SS_MUX_NUM; mux_id++) { mux_num = single_cluster ? A53SS_MUX_LC:A53SS_MUX_NUM; for (mux_id = 0; mux_id < mux_num; mux_id++) { rc = cpu_parse_devicetree(pdev, mux_id); if (rc) return rc; Loading Loading @@ -683,16 +728,23 @@ static int clock_a53_probe(struct platform_device *pdev) dev_info(&pdev->dev, "Safe voltage plan loaded.\n"); } } if (single_cluster) rc = of_msm_clock_register(pdev->dev.of_node, cpu_clocks_8939_single_cluster, ARRAY_SIZE(cpu_clocks_8939_single_cluster)); else rc = of_msm_clock_register(pdev->dev.of_node, cpu_clocks_8939, ARRAY_SIZE(cpu_clocks_8939)); if (rc) { dev_err(&pdev->dev, "msm_clock_register failed\n"); return rc; } if (!single_cluster) { rate = clk_get_rate(&cci_clk.c); clk_set_rate(&cci_clk.c, rate); } for (mux_id = 0; mux_id < A53SS_MUX_CCI; mux_id++) { /* Force a PLL reconfiguration */ Loading Loading @@ -724,15 +776,19 @@ static int clock_a53_probe(struct platform_device *pdev) a53_lc_clk.hw_low_power_ctrl = true; a53_bc_clk.hw_low_power_ctrl = true; if (single_cluster) register_pm_notifier(&clock_8939_pm_notifier_single_cluster); else register_pm_notifier(&clock_8939_pm_notifier); populate_opp_table(pdev); populate_opp_table(pdev, single_cluster); return 0; } static struct of_device_id clock_a53_match_table[] = { {.compatible = "qcom,cpu-clock-8939"}, {.compatible = "qcom,cpu-clock-gold"}, {} }; Loading Loading
Documentation/devicetree/bindings/arm/msm/clock-cpu-8939.txt +3 −1 Original line number Diff line number Diff line Loading @@ -7,7 +7,7 @@ fmax tables, avs settings table, etc. Required properties: - compatible: Must be one of "qcom,clock-cpu-8939" or "qcom,cpu-clock-8952" "qcom,cpu-clock-8952", "qcom,cpu-clock-gold". - reg: Pairs of physical base addresses and region sizes of memory mapped registers. - reg-names: Names of the bases for the above registers. Expected Loading @@ -33,6 +33,8 @@ Required properties: Optional properties: - qcom,cpu-pcnoc-vote: Boolean to indicate cpu clocks would need to keep active pcnoc vote. - qcom,num-cluster: Boolean to indicate cpu clock code is used for single cluster. Example: clock_cpu: qcom,cpu-clock-8939@f9015000 { compatible = "qcom,cpu-clock-8939"; Loading
arch/arm/boot/dts/qcom/msm8937.dtsi +6 −6 Original line number Diff line number Diff line Loading @@ -566,11 +566,11 @@ clock_gcc: qcom,gcc@1800000 { compatible = "qcom,gcc-8937"; reg = <0x1800000 0x80000>, <0xb116000 0x00040>, <0xb016000 0x00040>, <0xb116000 0x00040>, <0xb1d0000 0x00040>; reg-names = "cc_base", "apcs_c0_base", "apcs_c1_base", "apcs_cci_base"; reg-names = "cc_base", "apcs_c1_base", "apcs_c0_base", "apcs_cci_base"; vdd_dig-supply = <&pm8937_s2_level>; vdd_sr2_dig-supply = <&pm8937_s2_level_ao>; vdd_sr2_pll-supply = <&pm8937_l7_ao>; Loading Loading @@ -607,11 +607,11 @@ clock_cpu: qcom,cpu-clock-8939@b111050 { compatible = "qcom,cpu-clock-8939"; reg = <0xb111050 0x8>, <0xb011050 0x8>, reg = <0xb011050 0x8>, <0xb111050 0x8>, <0xb1d1050 0x8>, <0x00a412c 0x8>; reg-names = "apcs-c0-rcg-base", "apcs-c1-rcg-base", reg-names = "apcs-c1-rcg-base", "apcs-c0-rcg-base", "apcs-cci-rcg-base", "efuse"; vdd-c0-supply = <&apc_vreg_corner>; vdd-c1-supply = <&apc_vreg_corner>; Loading
arch/arm/boot/dts/qcom/msm8952.dtsi +6 −6 Original line number Diff line number Diff line Loading @@ -145,11 +145,11 @@ #size-cells = <1>; compatible = "qcom,gcc-8952"; reg = <0x1800000 0x80000>, <0xb116000 0x00040>, <0xb016000 0x00040>, <0xb116000 0x00040>, <0xb1d0000 0x00040>; reg-names = "cc_base", "apcs_c0_base", "apcs_c1_base", "apcs_cci_base"; reg-names = "cc_base", "apcs_c1_base", "apcs_c0_base", "apcs_cci_base"; vdd_dig-supply = <&pm8950_s2_level>; vdd_sr2_dig-supply = <&pm8950_s2_level_ao>; vdd_sr2_pll-supply = <&pm8950_l7_ao>; Loading Loading @@ -185,11 +185,11 @@ clock_cpu: qcom,cpu-clock-8939@b111050 { compatible = "qcom,cpu-clock-8939"; reg = <0xb111050 0x8>, <0xb011050 0x8>, reg = <0xb011050 0x8>, <0xb111050 0x8>, <0xb1d1050 0x8>, <0x005c00c 0x8>; reg-names = "apcs-c0-rcg-base", "apcs-c1-rcg-base", reg-names = "apcs-c1-rcg-base", "apcs-c0-rcg-base", "apcs-cci-rcg-base", "efuse"; vdd-c0-supply = <&apc_vreg_corner>; vdd-c1-supply = <&apc_vreg_corner>; Loading
drivers/clk/msm/clock-cpu-8939.c +86 −30 Original line number Diff line number Diff line Loading @@ -203,6 +203,12 @@ static struct clk_lookup cpu_clocks_8939[] = { CLK_LIST(cci_clk), }; static struct clk_lookup cpu_clocks_8939_single_cluster[] = { CLK_LIST(a53ssmux_bc), CLK_LIST(a53_bc_clk), }; static struct mux_div_clk *a53ssmux[] = {&a53ssmux_bc, &a53ssmux_lc, &a53ssmux_cci}; Loading Loading @@ -516,30 +522,33 @@ static int add_opp(struct clk *c, struct device *cpudev, struct device *vregdev, return 0; } static void print_opp_table(int a53_c0_cpu, int a53_c1_cpu) static void print_opp_table(int a53_c0_cpu, int a53_c1_cpu, bool single_cluster) { struct dev_pm_opp *oppfmax, *oppfmin; unsigned long apc0_fmax, apc1_fmax, apc0_fmin, apc1_fmin; if (!single_cluster) { apc0_fmax = a53_lc_clk.c.fmax[a53_lc_clk.c.num_fmax - 1]; apc1_fmax = a53_bc_clk.c.fmax[a53_bc_clk.c.num_fmax - 1]; apc0_fmin = a53_lc_clk.c.fmax[1]; } apc1_fmax = a53_bc_clk.c.fmax[a53_bc_clk.c.num_fmax - 1]; apc1_fmin = a53_bc_clk.c.fmax[1]; rcu_read_lock(); if (!single_cluster) { oppfmax = dev_pm_opp_find_freq_exact(get_cpu_device(a53_c0_cpu), apc0_fmax, true); oppfmin = dev_pm_opp_find_freq_exact(get_cpu_device(a53_c0_cpu), apc0_fmin, true); /* * One time information during boot. Important to know that this looks * sane since it can eventually make its way to the scheduler. * One time information during boot. Important to know that this * looks sane since it can eventually make its way to the * scheduler. */ pr_info("clock_cpu: a53_c0: OPP voltage for %lu: %ld\n", apc0_fmin, dev_pm_opp_get_voltage(oppfmin)); pr_info("clock_cpu: a53_c0: OPP voltage for %lu: %ld\n", apc0_fmax, dev_pm_opp_get_voltage(oppfmax)); pr_info("clock_cpu: a53_c0: OPP voltage for %lu: %ld\n", apc0_fmin, dev_pm_opp_get_voltage(oppfmin)); pr_info("clock_cpu: a53_c0: OPP voltage for %lu: %ld\n", apc0_fmax, dev_pm_opp_get_voltage(oppfmax)); } oppfmax = dev_pm_opp_find_freq_exact(get_cpu_device(a53_c1_cpu), apc1_fmax, true); oppfmin = dev_pm_opp_find_freq_exact(get_cpu_device(a53_c1_cpu), Loading @@ -551,16 +560,19 @@ static void print_opp_table(int a53_c0_cpu, int a53_c1_cpu) rcu_read_unlock(); } static void populate_opp_table(struct platform_device *pdev) static void populate_opp_table(struct platform_device *pdev, bool single_cluster) { struct platform_device *apc0_dev, *apc1_dev; struct device_node *apc0_node, *apc1_node; unsigned long apc0_fmax, apc1_fmax; int cpu, a53_c0_cpu, a53_c1_cpu; apc0_node = of_parse_phandle(pdev->dev.of_node, "vdd-c0-supply", 0); if (!single_cluster) apc0_node = of_parse_phandle(pdev->dev.of_node, "vdd-c0-supply", 0); apc1_node = of_parse_phandle(pdev->dev.of_node, "vdd-c1-supply", 0); if (!apc0_node) { if (!apc0_node && !single_cluster) { pr_err("can't find the apc0 dt node.\n"); return; } Loading @@ -568,10 +580,11 @@ static void populate_opp_table(struct platform_device *pdev) pr_err("can't find the apc1 dt node.\n"); return; } if (!single_cluster) apc0_dev = of_find_device_by_node(apc0_node); apc1_dev = of_find_device_by_node(apc1_node); if (!apc0_dev) { if (!apc1_dev && !single_cluster) { pr_err("can't find the apc0 device node.\n"); return; } Loading @@ -580,7 +593,9 @@ static void populate_opp_table(struct platform_device *pdev) return; } if (!single_cluster) apc0_fmax = a53_lc_clk.c.fmax[a53_lc_clk.c.num_fmax - 1]; apc1_fmax = a53_bc_clk.c.fmax[a53_bc_clk.c.num_fmax - 1]; for_each_possible_cpu(cpu) { Loading @@ -590,7 +605,7 @@ static void populate_opp_table(struct platform_device *pdev) WARN(add_opp(&a53_bc_clk.c, get_cpu_device(cpu), &apc1_dev->dev, apc1_fmax), "Failed to add OPP levels for A53 big cluster\n"); } else if (cpu/4 == 1) { } else if (cpu/4 == 1 && !single_cluster) { a53_c0_cpu = cpu; WARN(add_opp(&a53_lc_clk.c, get_cpu_device(cpu), &apc0_dev->dev, apc0_fmax), Loading @@ -602,7 +617,8 @@ static void populate_opp_table(struct platform_device *pdev) pr_info("clock-cpu-8939: OPP tables populated (cpu %d and %d)", a53_c0_cpu, a53_c1_cpu); print_opp_table(a53_c0_cpu, a53_c1_cpu); print_opp_table(a53_c0_cpu, a53_c1_cpu, single_cluster); } static void config_pll(int mux_id) Loading Loading @@ -644,18 +660,47 @@ static int clock_8939_pm_event(struct notifier_block *this, return NOTIFY_DONE; } static int clock_8939_pm_event_single_cluster(struct notifier_block *this, unsigned long event, void *ptr) { switch (event) { case PM_POST_HIBERNATION: case PM_POST_SUSPEND: clk_unprepare(&a53_bc_clk.c); break; case PM_HIBERNATION_PREPARE: case PM_SUSPEND_PREPARE: clk_prepare(&a53_bc_clk.c); break; default: break; } return NOTIFY_DONE; } static struct notifier_block clock_8939_pm_notifier = { .notifier_call = clock_8939_pm_event, }; static struct notifier_block clock_8939_pm_notifier_single_cluster = { .notifier_call = clock_8939_pm_event_single_cluster, }; static int clock_a53_probe(struct platform_device *pdev) { int speed_bin, version, rc, cpu, mux_id, rate; char prop_name[] = "qcom,speedX-bin-vX-XXX"; int mux_num; bool single_cluster; single_cluster = of_property_read_bool(pdev->dev.of_node, "qcom,num-cluster"); get_speed_bin(pdev, &speed_bin, &version); for (mux_id = 0; mux_id < A53SS_MUX_NUM; mux_id++) { mux_num = single_cluster ? A53SS_MUX_LC:A53SS_MUX_NUM; for (mux_id = 0; mux_id < mux_num; mux_id++) { rc = cpu_parse_devicetree(pdev, mux_id); if (rc) return rc; Loading Loading @@ -683,16 +728,23 @@ static int clock_a53_probe(struct platform_device *pdev) dev_info(&pdev->dev, "Safe voltage plan loaded.\n"); } } if (single_cluster) rc = of_msm_clock_register(pdev->dev.of_node, cpu_clocks_8939_single_cluster, ARRAY_SIZE(cpu_clocks_8939_single_cluster)); else rc = of_msm_clock_register(pdev->dev.of_node, cpu_clocks_8939, ARRAY_SIZE(cpu_clocks_8939)); if (rc) { dev_err(&pdev->dev, "msm_clock_register failed\n"); return rc; } if (!single_cluster) { rate = clk_get_rate(&cci_clk.c); clk_set_rate(&cci_clk.c, rate); } for (mux_id = 0; mux_id < A53SS_MUX_CCI; mux_id++) { /* Force a PLL reconfiguration */ Loading Loading @@ -724,15 +776,19 @@ static int clock_a53_probe(struct platform_device *pdev) a53_lc_clk.hw_low_power_ctrl = true; a53_bc_clk.hw_low_power_ctrl = true; if (single_cluster) register_pm_notifier(&clock_8939_pm_notifier_single_cluster); else register_pm_notifier(&clock_8939_pm_notifier); populate_opp_table(pdev); populate_opp_table(pdev, single_cluster); return 0; } static struct of_device_id clock_a53_match_table[] = { {.compatible = "qcom,cpu-clock-8939"}, {.compatible = "qcom,cpu-clock-gold"}, {} }; Loading