Loading arch/arm/configs/vendor/sdxnightjar-debug.config +1 −0 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ CONFIG_IIO=y CONFIG_QCOM_CLK_SMD_RPM=y CONFIG_SDX_DEBUGCC_NIGHTJAR=y CONFIG_COMMON_CLK_QCOM_DEBUG=y CONFIG_CLOCK_CPU_SDXLEMUR=y CONFIG_MSM_RPM_SMD=y # CONFIG_GENERIC_ADC_BATTERY is not set # CONFIG_BATTERY_LEGO_EV3 is not set Loading arch/arm/configs/vendor/sdxnightjar.config +1 −0 Original line number Diff line number Diff line Loading @@ -72,6 +72,7 @@ CONFIG_IIO=y CONFIG_QCOM_CLK_SMD_RPM=y CONFIG_SDX_DEBUGCC_NIGHTJAR=y CONFIG_COMMON_CLK_QCOM_DEBUG=y CONFIG_CLOCK_CPU_SDXLEMUR=y CONFIG_MSM_RPM_SMD=y # CONFIG_GENERIC_ADC_BATTERY is not set # CONFIG_BATTERY_LEGO_EV3 is not set Loading drivers/clk/qcom/clk-cpu-sdxlemur.c +129 −17 Original line number Diff line number Diff line Loading @@ -88,26 +88,50 @@ cpucc_calc_rate(unsigned long rate, u32 m, u32 n, u32 mode, u32 hid_div) return tmp; } static int cpucc_clk_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) static int cpucc_clk_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) { struct clk_hw *apcs_cpu_pll_hw; struct clk_hw *xo_hw, *gpll0_hw; struct clk_rate_request parent_req = { }; struct clk_regmap_mux_div *cpuclk = to_clk_regmap_mux_div(hw); unsigned long rate = req->rate, rrate; u32 div; int ret; apcs_cpu_pll_hw = clk_hw_get_parent_by_index(hw, P_APCS_CPU_PLL); xo_hw = clk_hw_get_parent_by_index(hw, P_BI_TCXO); if (rate == clk_hw_get_rate(xo_hw)) { req->best_parent_hw = xo_hw; req->best_parent_rate = rate; cpuclk->div = 1; cpuclk->src = cpuclk->parent_map[P_BI_TCXO].cfg; return 0; } gpll0_hw = clk_hw_get_parent_by_index(hw, P_GPLL0); div = DIV_ROUND_UP((2 * (clk_hw_get_rate(gpll0_hw))), rate) - 1; rrate = cpucc_calc_rate(clk_hw_get_rate(gpll0_hw), 0, 0, 0, div); /* Use the GPLL0 source */ if (rate <= rrate) { parent_req.best_parent_hw = gpll0_hw; req->best_parent_hw = gpll0_hw; req->best_parent_rate = clk_hw_get_rate(gpll0_hw); req->rate = rrate; cpuclk->src = cpuclk->parent_map[P_GPLL0].cfg; } else { /* Use the APCS PLL source */ parent_req.rate = req->rate; parent_req.best_parent_hw = apcs_cpu_pll_hw; req->best_parent_hw = apcs_cpu_pll_hw; parent_req.best_parent_hw = clk_hw_get_parent_by_index(hw, P_APCS_CPU_PLL); req->best_parent_hw = parent_req.best_parent_hw; ret = __clk_determine_rate(req->best_parent_hw, &parent_req); if (ret) return ret; req->best_parent_rate = parent_req.rate; cpuclk->src = cpuclk->parent_map[P_APCS_CPU_PLL].cfg; cpuclk->div = 1; div = 1; } cpuclk->div = div; return 0; } Loading Loading @@ -187,6 +211,28 @@ static u8 cpucc_clk_get_parent(struct clk_hw *hw) return clk_regmap_mux_div_ops.get_parent(hw); } /* * We use the notifier function for switching to a temporary safe configuration * (mux and divider), while the APSS pll is reconfigured. */ static int cpucc_notifier_cb(struct notifier_block *nb, unsigned long event, void *data) { struct clk_regmap_mux_div *cpuclk = container_of(nb, struct clk_regmap_mux_div, clk_nb); int ret = 0; if (event == PRE_RATE_CHANGE) /* set the mux to safe source(gpll0) & div */ ret = mux_div_set_src_div(cpuclk, cpuclk->safe_src, 1); if (event == ABORT_RATE_CHANGE) pr_err("Error in configuring PLL - stay at safe src only\n"); return notifier_from_errno(ret); } static const struct clk_ops cpucc_clk_ops = { .enable = cpucc_clk_enable, .disable = cpucc_clk_disable, Loading @@ -204,6 +250,11 @@ static struct pll_vco lucid_5lpe_vco[] = { { 249600000, 2000000000, 0 }, }; static struct pll_vco alpha_pll_vco[] = { { 250000000, 500000000, 3 }, { 750000000, 1500000000, 1 }, }; /* Initial configuration for 1094.4 */ static const struct alpha_pll_config apcs_cpu_pll_config = { .l = 0x4E, Loading @@ -220,6 +271,25 @@ static const struct alpha_pll_config apcs_cpu_pll_config = { .user_ctl_hi1_val = 0x00000000, }; /* Initial configuration for 1190.4 MHz */ static struct alpha_pll_config apcs_cpu_alpha_pll_config = { .l = 0x3E, .config_ctl_val = 0x4001055b, .test_ctl_hi_val = 0x0, .vco_val = BIT(20), .vco_mask = 0x3 << 20, .main_output_mask = BIT(0), }; static struct clk_init_data apcs_cpu_pll_sdxnightjar = { .name = "apcs_cpu_pll", .parent_data = &(const struct clk_parent_data){ .fw_name = "bi_tcxo_ao", }, .num_parents = 1, .ops = &clk_alpha_pll_ops, }; static struct clk_alpha_pll apcs_cpu_pll = { .offset = 0x0, .vco_table = lucid_5lpe_vco, Loading Loading @@ -279,6 +349,7 @@ static struct clk_regmap_mux_div apcs_mux_clk = { static const struct of_device_id match_table[] = { { .compatible = "qcom,sdxlemur-apsscc" }, { .compatible = "qcom,sdxnightjar-apsscc" }, {} }; Loading Loading @@ -487,6 +558,28 @@ static void cpucc_clk_populate_opp_table(struct platform_device *pdev) cpucc_clk_print_opp_table(final_cpu); } static void cpucc_sdxnightjar_fixup(void) { apcs_cpu_pll.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT]; apcs_cpu_pll.vco_table = alpha_pll_vco; apcs_cpu_pll.num_vco = sizeof(alpha_pll_vco); apcs_cpu_pll.clkr.hw.init = &apcs_cpu_pll_sdxnightjar; apcs_cpu_pll.clkr.vdd_data.rate_max[VDD_MIN] = 0; apcs_cpu_pll.clkr.vdd_data.rate_max[VDD_LOW] = 1000000000; apcs_cpu_pll.clkr.vdd_data.rate_max[VDD_LOW_L1] = 0; apcs_cpu_pll.clkr.vdd_data.rate_max[VDD_NOMINAL] = 2000000000; /* GPLL0 as safe source Index */ apcs_mux_clk.safe_src = 1; apcs_mux_clk.safe_div = 1; apcs_mux_clk.clk_nb.notifier_call = cpucc_notifier_cb; clk_alpha_pll_configure(&apcs_cpu_pll, apcs_cpu_pll.clkr.regmap, &apcs_cpu_alpha_pll_config); } static int cpucc_get_and_parse_dt_resource(struct platform_device *pdev, unsigned long *xo_rate) { Loading Loading @@ -597,6 +690,7 @@ static int cpucc_driver_probe(struct platform_device *pdev) struct clk_hw_onecell_data *data; struct device *dev = &pdev->dev; int i, ret, cpu; bool is_sdxnightjar; unsigned long xo_rate; u32 l_val; Loading @@ -604,9 +698,17 @@ static int cpucc_driver_probe(struct platform_device *pdev) if (ret < 0) return ret; is_sdxnightjar = of_device_is_compatible(pdev->dev.of_node, "qcom,sdxnightjar-apsscc"); if (is_sdxnightjar) { l_val = apcs_cpu_alpha_pll_config.l; cpucc_sdxnightjar_fixup(); } else { l_val = apcs_cpu_pll_config.l; clk_lucid_5lpe_pll_configure(&apcs_cpu_pll, apcs_cpu_pll.clkr.regmap, &apcs_cpu_pll_config); } data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); if (!data) Loading @@ -631,6 +733,16 @@ static int cpucc_driver_probe(struct platform_device *pdev) return ret; } if (is_sdxnightjar) { ret = clk_notifier_register(apcs_mux_clk.clkr.hw.clk, &apcs_mux_clk.clk_nb); if (ret) { dev_err(&pdev->dev, "failed to register clock notifier: %d\n", ret); return ret; } } /* Set to boot frequency */ ret = clk_set_rate(apcs_mux_clk.clkr.hw.clk, l_val * xo_rate); if (ret) { Loading Loading
arch/arm/configs/vendor/sdxnightjar-debug.config +1 −0 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ CONFIG_IIO=y CONFIG_QCOM_CLK_SMD_RPM=y CONFIG_SDX_DEBUGCC_NIGHTJAR=y CONFIG_COMMON_CLK_QCOM_DEBUG=y CONFIG_CLOCK_CPU_SDXLEMUR=y CONFIG_MSM_RPM_SMD=y # CONFIG_GENERIC_ADC_BATTERY is not set # CONFIG_BATTERY_LEGO_EV3 is not set Loading
arch/arm/configs/vendor/sdxnightjar.config +1 −0 Original line number Diff line number Diff line Loading @@ -72,6 +72,7 @@ CONFIG_IIO=y CONFIG_QCOM_CLK_SMD_RPM=y CONFIG_SDX_DEBUGCC_NIGHTJAR=y CONFIG_COMMON_CLK_QCOM_DEBUG=y CONFIG_CLOCK_CPU_SDXLEMUR=y CONFIG_MSM_RPM_SMD=y # CONFIG_GENERIC_ADC_BATTERY is not set # CONFIG_BATTERY_LEGO_EV3 is not set Loading
drivers/clk/qcom/clk-cpu-sdxlemur.c +129 −17 Original line number Diff line number Diff line Loading @@ -88,26 +88,50 @@ cpucc_calc_rate(unsigned long rate, u32 m, u32 n, u32 mode, u32 hid_div) return tmp; } static int cpucc_clk_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) static int cpucc_clk_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) { struct clk_hw *apcs_cpu_pll_hw; struct clk_hw *xo_hw, *gpll0_hw; struct clk_rate_request parent_req = { }; struct clk_regmap_mux_div *cpuclk = to_clk_regmap_mux_div(hw); unsigned long rate = req->rate, rrate; u32 div; int ret; apcs_cpu_pll_hw = clk_hw_get_parent_by_index(hw, P_APCS_CPU_PLL); xo_hw = clk_hw_get_parent_by_index(hw, P_BI_TCXO); if (rate == clk_hw_get_rate(xo_hw)) { req->best_parent_hw = xo_hw; req->best_parent_rate = rate; cpuclk->div = 1; cpuclk->src = cpuclk->parent_map[P_BI_TCXO].cfg; return 0; } gpll0_hw = clk_hw_get_parent_by_index(hw, P_GPLL0); div = DIV_ROUND_UP((2 * (clk_hw_get_rate(gpll0_hw))), rate) - 1; rrate = cpucc_calc_rate(clk_hw_get_rate(gpll0_hw), 0, 0, 0, div); /* Use the GPLL0 source */ if (rate <= rrate) { parent_req.best_parent_hw = gpll0_hw; req->best_parent_hw = gpll0_hw; req->best_parent_rate = clk_hw_get_rate(gpll0_hw); req->rate = rrate; cpuclk->src = cpuclk->parent_map[P_GPLL0].cfg; } else { /* Use the APCS PLL source */ parent_req.rate = req->rate; parent_req.best_parent_hw = apcs_cpu_pll_hw; req->best_parent_hw = apcs_cpu_pll_hw; parent_req.best_parent_hw = clk_hw_get_parent_by_index(hw, P_APCS_CPU_PLL); req->best_parent_hw = parent_req.best_parent_hw; ret = __clk_determine_rate(req->best_parent_hw, &parent_req); if (ret) return ret; req->best_parent_rate = parent_req.rate; cpuclk->src = cpuclk->parent_map[P_APCS_CPU_PLL].cfg; cpuclk->div = 1; div = 1; } cpuclk->div = div; return 0; } Loading Loading @@ -187,6 +211,28 @@ static u8 cpucc_clk_get_parent(struct clk_hw *hw) return clk_regmap_mux_div_ops.get_parent(hw); } /* * We use the notifier function for switching to a temporary safe configuration * (mux and divider), while the APSS pll is reconfigured. */ static int cpucc_notifier_cb(struct notifier_block *nb, unsigned long event, void *data) { struct clk_regmap_mux_div *cpuclk = container_of(nb, struct clk_regmap_mux_div, clk_nb); int ret = 0; if (event == PRE_RATE_CHANGE) /* set the mux to safe source(gpll0) & div */ ret = mux_div_set_src_div(cpuclk, cpuclk->safe_src, 1); if (event == ABORT_RATE_CHANGE) pr_err("Error in configuring PLL - stay at safe src only\n"); return notifier_from_errno(ret); } static const struct clk_ops cpucc_clk_ops = { .enable = cpucc_clk_enable, .disable = cpucc_clk_disable, Loading @@ -204,6 +250,11 @@ static struct pll_vco lucid_5lpe_vco[] = { { 249600000, 2000000000, 0 }, }; static struct pll_vco alpha_pll_vco[] = { { 250000000, 500000000, 3 }, { 750000000, 1500000000, 1 }, }; /* Initial configuration for 1094.4 */ static const struct alpha_pll_config apcs_cpu_pll_config = { .l = 0x4E, Loading @@ -220,6 +271,25 @@ static const struct alpha_pll_config apcs_cpu_pll_config = { .user_ctl_hi1_val = 0x00000000, }; /* Initial configuration for 1190.4 MHz */ static struct alpha_pll_config apcs_cpu_alpha_pll_config = { .l = 0x3E, .config_ctl_val = 0x4001055b, .test_ctl_hi_val = 0x0, .vco_val = BIT(20), .vco_mask = 0x3 << 20, .main_output_mask = BIT(0), }; static struct clk_init_data apcs_cpu_pll_sdxnightjar = { .name = "apcs_cpu_pll", .parent_data = &(const struct clk_parent_data){ .fw_name = "bi_tcxo_ao", }, .num_parents = 1, .ops = &clk_alpha_pll_ops, }; static struct clk_alpha_pll apcs_cpu_pll = { .offset = 0x0, .vco_table = lucid_5lpe_vco, Loading Loading @@ -279,6 +349,7 @@ static struct clk_regmap_mux_div apcs_mux_clk = { static const struct of_device_id match_table[] = { { .compatible = "qcom,sdxlemur-apsscc" }, { .compatible = "qcom,sdxnightjar-apsscc" }, {} }; Loading Loading @@ -487,6 +558,28 @@ static void cpucc_clk_populate_opp_table(struct platform_device *pdev) cpucc_clk_print_opp_table(final_cpu); } static void cpucc_sdxnightjar_fixup(void) { apcs_cpu_pll.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT]; apcs_cpu_pll.vco_table = alpha_pll_vco; apcs_cpu_pll.num_vco = sizeof(alpha_pll_vco); apcs_cpu_pll.clkr.hw.init = &apcs_cpu_pll_sdxnightjar; apcs_cpu_pll.clkr.vdd_data.rate_max[VDD_MIN] = 0; apcs_cpu_pll.clkr.vdd_data.rate_max[VDD_LOW] = 1000000000; apcs_cpu_pll.clkr.vdd_data.rate_max[VDD_LOW_L1] = 0; apcs_cpu_pll.clkr.vdd_data.rate_max[VDD_NOMINAL] = 2000000000; /* GPLL0 as safe source Index */ apcs_mux_clk.safe_src = 1; apcs_mux_clk.safe_div = 1; apcs_mux_clk.clk_nb.notifier_call = cpucc_notifier_cb; clk_alpha_pll_configure(&apcs_cpu_pll, apcs_cpu_pll.clkr.regmap, &apcs_cpu_alpha_pll_config); } static int cpucc_get_and_parse_dt_resource(struct platform_device *pdev, unsigned long *xo_rate) { Loading Loading @@ -597,6 +690,7 @@ static int cpucc_driver_probe(struct platform_device *pdev) struct clk_hw_onecell_data *data; struct device *dev = &pdev->dev; int i, ret, cpu; bool is_sdxnightjar; unsigned long xo_rate; u32 l_val; Loading @@ -604,9 +698,17 @@ static int cpucc_driver_probe(struct platform_device *pdev) if (ret < 0) return ret; is_sdxnightjar = of_device_is_compatible(pdev->dev.of_node, "qcom,sdxnightjar-apsscc"); if (is_sdxnightjar) { l_val = apcs_cpu_alpha_pll_config.l; cpucc_sdxnightjar_fixup(); } else { l_val = apcs_cpu_pll_config.l; clk_lucid_5lpe_pll_configure(&apcs_cpu_pll, apcs_cpu_pll.clkr.regmap, &apcs_cpu_pll_config); } data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); if (!data) Loading @@ -631,6 +733,16 @@ static int cpucc_driver_probe(struct platform_device *pdev) return ret; } if (is_sdxnightjar) { ret = clk_notifier_register(apcs_mux_clk.clkr.hw.clk, &apcs_mux_clk.clk_nb); if (ret) { dev_err(&pdev->dev, "failed to register clock notifier: %d\n", ret); return ret; } } /* Set to boot frequency */ ret = clk_set_rate(apcs_mux_clk.clkr.hw.clk, l_val * xo_rate); if (ret) { Loading