[PATCH v7 3/3] clk: aspeed: add AST2700 clock driver.

Ryan Chen ryan_chen at aspeedtech.com
Mon Dec 9 12:49:24 AEDT 2024


> Subject: RE: [PATCH v7 3/3] clk: aspeed: add AST2700 clock driver.
> 
> Quoting Ryan Chen (2024-12-04 16:48:42)
> > > > struct ast2700_clk_info {
> > > >         const char *name;
> > > >         u8 clk_idx;
> > > >         u32 reg;
> > > >         u32 type;
> > > >         union {
> > > >                 struct ast2700_clk_fixed_factor_data factor;
> > > >                 struct ast2700_clk_fixed_rate_data rate;
> > > >                 struct ast2700_clk_gate_data gate;
> > > >                 struct ast2700_clk_div_data div;
> > > >                 struct ast2700_clk_pll_data pll;
> > > >                 struct ast2700_clk_mux_data mux;
> > > >         } data;
> > > > };
> > > >
> > > > struct ast2700_clk_div_data {
> > > >         const struct clk_div_table *div_table;
> > > >         const struct clk_parent_data *parent;
> > > >         u8 bit_shift;
> > > >         u8 bit_width;
> > > >         u32 reg;
> > > > };
> > > >
> > > > static const struct ast2700_clk_info ast2700_scu0_clk_info[]
> > > > __initconst = { ...........................
> > > >         DIVIDER_CLK(SCU0_CLK_AHB, "soc0-ahb", soc0_ahbmux,
> > >
> > > Can you also show what soc0_ahbmux is?
> > It will be following.
> >
> > static const struct clk_parent_data soc0_ahbmux[] = {
> >         { .fw_name = "soc0-ahbmux", .name = "soc0-ahbmux" }, };
> 
> Instead of that, please use only the index.
> 
>  static const struct clk_parent_data soc0_ahbmux[] = {
>          { .index = <number from DT binding> },  };

Sorry, if I use index instead, It can’t get parent data name for devm_clk_hw_register_fixed_factor parent_name parameters.
Does there have reference driver use index implement?

In probe function I implement for function for each clk register.
For example CLK_DIVIDER
Use div->parent->name get parent name for parameter.
			hws[i] = devm_clk_hw_register_divider_table(dev, clk->name,
								    div->parent->name, 0,
								    reg, div->bit_shift,
								    div->bit_width, 0,
								    div->div_table,
								    &clk_ctrl->lock);

Full implement is following.

	for (i = 0; i < clk_data->nr_clks; i++) {
		const struct ast2700_clk_info *clk = &clk_data->clk_info[i];
		void __iomem *reg = clk_ctrl->base + clk->reg;

		if (clk->type == CLK_FIXED) {
			const struct ast2700_clk_fixed_rate_data *fixed_rate = &clk->data.rate;

			hws[i] = devm_clk_hw_register_fixed_rate(dev, clk->name, NULL, 0,
								 fixed_rate->fixed_rate);
		} else if (clk->type == CLK_FIXED_FACTOR) {
			const struct ast2700_clk_fixed_factor_data *factor = &clk->data.factor;

			hws[i] = devm_clk_hw_register_fixed_factor(dev, clk->name,
								   factor->parent->name,
								   0, factor->mult, factor->div);
		} else if (clk->type == DCLK_FIXED) {
			const struct ast2700_clk_pll_data *pll = &clk->data.pll;

			reg = clk_ctrl->base + pll->reg;
			hws[i] = ast2700_clk_hw_register_dclk(i, reg, clk->name, clk_ctrl);
		} else if (clk->type == CLK_HPLL) {
			const struct ast2700_clk_pll_data *pll = &clk->data.pll;

			reg = clk_ctrl->base + pll->reg;
			hws[i] = ast2700_clk_hw_register_hpll(i, reg, clk->name,
							      pll->parent->name, clk_ctrl);
		} else if (clk->type == CLK_PLL) {
			const struct ast2700_clk_pll_data *pll = &clk->data.pll;

			reg = clk_ctrl->base + pll->reg;
			hws[i] = ast2700_clk_hw_register_pll(i, reg, clk->name,
							     pll->parent->name, clk_ctrl);
		} else if (clk->type == CLK_UART_PLL) {
			const struct ast2700_clk_pll_data *pll = &clk->data.pll;

			reg = clk_ctrl->base + pll->reg;
			hws[i] = ast2700_clk_hw_register_uartpll(i, reg, clk->name,
								 pll->parent->name, clk_ctrl);
		} else if (clk->type == CLK_MUX) {
			const struct ast2700_clk_mux_data *mux = &clk->data.mux;

			reg = clk_ctrl->base + mux->reg;
			hws[i] = devm_clk_hw_register_mux_parent_data_table(dev, clk->name,
									    mux->parents,
									    mux->num_parents, 0,
									    reg, mux->bit_shift,
									    mux->bit_width, 0,
									    NULL, &clk_ctrl->lock);
		} else if (clk->type == CLK_MISC) {
			const struct ast2700_clk_pll_data *misc = &clk->data.pll;

			reg = clk_ctrl->base + misc->reg;
			hws[i] = ast2700_clk_hw_register_misc(i, reg, clk->name,
							      misc->parent->name, clk_ctrl);
		} else if (clk->type == CLK_DIVIDER) {
			const struct ast2700_clk_div_data *div = &clk->data.div;

			reg = clk_ctrl->base + div->reg;
			hws[i] = devm_clk_hw_register_divider_table(dev, clk->name,
								    div->parent->name, 0,
								    reg, div->bit_shift,
								    div->bit_width, 0,
								    div->div_table,
								    &clk_ctrl->lock);
		} else if (clk->type == CLK_GATE_ASPEED) {
			const struct ast2700_clk_gate_data *gate = &clk->data.gate;

			reg = clk_ctrl->base + gate->reg;
			hws[i] = ast2700_clk_hw_register_gate(dev, clk->name, gate->parent,
							      reg, gate->bit, gate->flags, 0);

		} else {
			const struct ast2700_clk_gate_data *gate = &clk->data.gate;

			reg = clk_ctrl->base + gate->reg;
			hws[i] = devm_clk_hw_register_gate_parent_data(dev, clk->name, gate->parent,
								       0, reg, clk->clk_idx, 0,
								       &clk_ctrl->lock);
		}

		if (IS_ERR(hws[i]))
			return PTR_ERR(hws[i]);
	}


More information about the Linux-aspeed mailing list