[PATCH v15 4/5] clk: sophgo: Add SG2042 clock driver
Chen Wang
unicorn_wang at outlook.com
Wed Jun 5 22:57:08 PDT 2024
On 2024/4/30 15:48, Emil Renner Berthing wrote:
> Chen Wang wrote:
[......]
>> +#define R_MP14_CONTROL_REG (0x03F4 - R_SYSGATE_BEGIN)
>> +#define R_MP15_STATUS_REG (0x03F8 - R_SYSGATE_BEGIN)
>> +#define R_MP15_CONTROL_REG (0x03FC - R_SYSGATE_BEGIN)
> All these seem pretty regular to me. Couldn't they just be
> #define R_MP_STATUS_REG(x) (0x380 + 8*(x) - R_SYSGATE_BEGIN)
> #define R_MP_CONTROL_REG(x) (0x384 + 8*(x) - R_SYSGATE_BEGIN)
I still prefer to keep the original writing method, because using
immediate values can be consistent with the register description in
the chip technical manual, which is convenient for comparison and search.
Thanks anyway.
[......]
>> +#define R_CLKDIVREG29 0xB4
>> +#define R_CLKDIVREG30 0xB8
> #define R_CLKDIVREG(x) (0x40 + 4*(x))
Same reason as above.
[......]
>> +#define PLLCTRL_FBDIV_SHIFT 16
>> +#define PLLCTRL_FBDIV_MASK (GENMASK(27, 16) >> PLLCTRL_FBDIV_SHIFT)
>> +#define PLLCTRL_POSTDIV2_SHIFT 12
>> +#define PLLCTRL_POSTDIV2_MASK (GENMASK(14, 12) >> PLLCTRL_POSTDIV2_SHIFT)
>> +#define PLLCTRL_POSTDIV1_SHIFT 8
>> +#define PLLCTRL_POSTDIV1_MASK (GENMASK(10, 8) >> PLLCTRL_POSTDIV1_SHIFT)
>> +#define PLLCTRL_REFDIV_SHIFT 0
>> +#define PLLCTRL_REFDIV_MASK (GENMASK(5, 0) >> PLLCTRL_REFDIV_SHIFT)
> You'll only need half of these defines if you use..
Yes, great advice, will change it.
> +
> +static inline u32 sg2042_pll_ctrl_encode(struct sg2042_pll_ctrl *ctrl)
> +{
> + return ((ctrl->fbdiv & PLLCTRL_FBDIV_MASK) << PLLCTRL_FBDIV_SHIFT) |
> + ((ctrl->postdiv2 & PLLCTRL_POSTDIV2_MASK) << PLLCTRL_POSTDIV2_SHIFT) |
> + ((ctrl->postdiv1 & PLLCTRL_POSTDIV1_MASK) << PLLCTRL_POSTDIV1_SHIFT) |
> + ((ctrl->refdiv & PLLCTRL_REFDIV_MASK) << PLLCTRL_REFDIV_SHIFT);
> ..the FIELD_PREP macro here..
>
>> +}
>> +
>> +static inline void sg2042_pll_ctrl_decode(unsigned int reg_value,
>> + struct sg2042_pll_ctrl *ctrl)
>> +{
>> + ctrl->fbdiv = (reg_value >> PLLCTRL_FBDIV_SHIFT) & PLLCTRL_FBDIV_MASK;
>> + ctrl->refdiv = (reg_value >> PLLCTRL_REFDIV_SHIFT) & PLLCTRL_REFDIV_MASK;
>> + ctrl->postdiv1 = (reg_value >> PLLCTRL_POSTDIV1_SHIFT) & PLLCTRL_POSTDIV1_MASK;
>> + ctrl->postdiv2 = (reg_value >> PLLCTRL_POSTDIV2_SHIFT) & PLLCTRL_POSTDIV2_MASK;
> ..and the FIELD_GET macro here.
[......]
> +
> +#define SG2042_PLL_FW_RO(_id, _name, _parent, _r_stat, _r_enable, _r_ctrl, _shift) \
> + { \
> + .hw.init = CLK_HW_INIT_FW_NAME( \
> + _name, \
> + _parent, \
> + &sg2042_clk_pll_ro_ops, \
> + CLK_GET_RATE_NOCACHE | CLK_GET_ACCURACY_NOCACHE),\
> + .id = _id, \
> + .offset_ctrl = _r_ctrl, \
> + .offset_status = _r_stat, \
> + .offset_enable = _r_enable, \
> + .shift_status_lock = 8 + (_shift), \
> + .shift_status_updating = _shift, \
> + .shift_enable = _shift, \
> + }
> These macros are pretty confusing. Please at least try to keep the arguments
> and assignments in close to the same order.
Accept, thanks.
>
>> +
>> +static struct sg2042_pll_clock sg2042_pll_clks[] = {
>> + SG2042_PLL_FW(MPLL_CLK, "mpll_clock", "cgi_main",
>> + R_PLL_STAT, R_PLL_CLKEN_CONTROL, R_MPLL_CONTROL, 0),
>> + SG2042_PLL_FW_RO(FPLL_CLK, "fpll_clock", "cgi_main",
>> + R_PLL_STAT, R_PLL_CLKEN_CONTROL, R_FPLL_CONTROL, 3),
>> + SG2042_PLL_FW_RO(DPLL0_CLK, "dpll0_clock", "cgi_dpll0",
>> + R_PLL_STAT, R_PLL_CLKEN_CONTROL, R_DPLL0_CONTROL, 4),
>> + SG2042_PLL_FW_RO(DPLL1_CLK, "dpll1_clock", "cgi_dpll1",
>> + R_PLL_STAT, R_PLL_CLKEN_CONTROL, R_DPLL1_CONTROL, 5),
> Also the STAT and CLK_GEN_CONTROL registers seem to be the same offset for all
> the PLLs. Why do you need to store them in memory?
Yes, you are right, will correct this.
[......]
>> +static int sg2042_mux_notifier_cb(struct notifier_block *nb,
>> + unsigned long event,
>> + void *data)
>> +{
>> + int ret = 0;
>> + struct clk_notifier_data *ndata = data;
>> + struct clk_hw *hw = __clk_get_hw(ndata->clk);
>> + const struct clk_ops *ops = &clk_mux_ops;
>> + struct sg2042_mux_clock *mux = to_sg2042_mux_nb(nb);
> Please order these by line length where possible. That goes for the whole file.
>
> Eg. look up 'reverse xmas tree' in fx.
> Documentation/process/maintainer-netdev.rst
OK, will improve this.
[......]
>> +static int sg2042_clk_register_muxs(struct device *dev,
>> + struct sg2042_clk_data *clk_data,
>> + struct sg2042_mux_clock mux_clks[],
>> + int num_mux_clks)
>> +{
>> + struct clk_hw *hw;
>> + struct sg2042_mux_clock *mux;
>> + int i, ret = 0;
>> +
>> + for (i = 0; i < num_mux_clks; i++) {
>> + mux = &mux_clks[i];
>> +
>> + hw = __devm_clk_hw_register_mux
>> + (dev,
>> + NULL,
>> + mux->hw.init->name,
>> + mux->hw.init->num_parents,
>> + NULL,
>> + mux->hw.init->parent_hws,
>> + NULL,
>> + mux->hw.init->flags,
>> + clk_data->iobase + mux->offset_select,
>> + mux->shift,
>> + BIT(mux->width) - 1,
>> + 0,
>> + sg2042_mux_table,
>> + &sg2042_clk_lock);
> Does checkpatch.pl --strict not warn about this interesting indentation?
No, I always run checkpatch --strict before sending out and don't see
warn on this.
[......]
>> +static int sg2042_init_clkdata(struct platform_device *pdev,
>> + int num_clks,
>> + struct sg2042_clk_data **pp_clk_data)
>> +{
>> + struct sg2042_clk_data *clk_data = NULL;
> No need to initialize this. You're setting it on the line just below. There are
> many other instances of this throughout the file.
Accept,I will double check this.
[......]
>> +static const struct of_device_id sg2042_clkgen_match[] = {
>> + { .compatible = "sophgo,sg2042-clkgen" },
>> + { /* sentinel */ }
>> +};
>> +
>> +static struct platform_driver sg2042_clkgen_driver = {
>> + .probe = sg2042_clkgen_probe,
>> + .driver = {
>> + .name = "clk-sophgo-sg2042-clkgen",
>> + .of_match_table = sg2042_clkgen_match,
>> + .suppress_bind_attrs = true,
>> + },
>> +};
>> +builtin_platform_driver(sg2042_clkgen_driver);
>> +
>> +static const struct of_device_id sg2042_rpgate_match[] = {
>> + { .compatible = "sophgo,sg2042-rpgate" },
>> + { /* sentinel */ }
>> +};
>> +
>> +static struct platform_driver sg2042_rpgate_driver = {
>> + .probe = sg2042_rpgate_probe,
>> + .driver = {
>> + .name = "clk-sophgo-sg2042-rpgate",
>> + .of_match_table = sg2042_rpgate_match,
>> + .suppress_bind_attrs = true,
>> + },
>> +};
>> +builtin_platform_driver(sg2042_rpgate_driver);
>> +
>> +static const struct of_device_id sg2042_pll_match[] = {
>> + { .compatible = "sophgo,sg2042-pll" },
>> + { /* sentinel */ }
>> +};
>> +
>> +static struct platform_driver sg2042_pll_driver = {
>> + .probe = sg2042_pll_probe,
>> + .driver = {
>> + .name = "clk-sophgo-sg2042-pll",
>> + .of_match_table = sg2042_pll_match,
>> + .suppress_bind_attrs = true,
>> + },
>> +};
>> +builtin_platform_driver(sg2042_pll_driver);
> You have 3 different drivers in one file. Could this not be split into 3
> different modules? This file is almost 2k lines long already.
OK, splitting this file into 3 should be better.
>
> Also do they all need to be built in? Eg. could some of them not be loaded as a
> module later in the boot process or are they all critical to get to loading the
> initramfs?
It doesn't seem to be a built-in, I will modify it, thanks for your
suggestion.
Regards,
Chen
> /Emil
>
>> --
>> 2.25.1
>>
>>
>> _______________________________________________
>> linux-riscv mailing list
>> linux-riscv at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-riscv
More information about the linux-riscv
mailing list