Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

clk: rockchip: Support MMC clocks in GRF region

Registers of MMC drive/sample clocks in Rockchip RV1106 and RK3528
locate in GRF regions. Adjust MMC clock code to support register
operations through regmap.

Signed-off-by: Yao Zi <ziyao@disroot.org>
Link: https://lore.kernel.org/r/20250506092206.46143-3-ziyao@disroot.org
Signed-off-by: Heiko Stuebner <heiko@sntech.de>

authored by

Yao Zi and committed by
Heiko Stuebner
621ba4d9 58883d58

+50 -7
+20 -4
drivers/clk/rockchip/clk-mmc-phase.c
··· 9 9 #include <linux/clk-provider.h> 10 10 #include <linux/io.h> 11 11 #include <linux/kernel.h> 12 + #include <linux/regmap.h> 12 13 #include "clk.h" 13 14 14 15 struct rockchip_mmc_clock { 15 16 struct clk_hw hw; 16 17 void __iomem *reg; 18 + struct regmap *grf; 19 + int grf_reg; 17 20 int shift; 18 21 int cached_phase; 19 22 struct notifier_block clk_rate_change_nb; ··· 57 54 if (!rate) 58 55 return 0; 59 56 60 - raw_value = readl(mmc_clock->reg) >> (mmc_clock->shift); 57 + if (mmc_clock->grf) 58 + regmap_read(mmc_clock->grf, mmc_clock->grf_reg, &raw_value); 59 + else 60 + raw_value = readl(mmc_clock->reg); 61 + 62 + raw_value >>= mmc_clock->shift; 61 63 62 64 degrees = (raw_value & ROCKCHIP_MMC_DEGREE_MASK) * 90; 63 65 ··· 142 134 raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0; 143 135 raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET; 144 136 raw_value |= nineties; 145 - writel(HIWORD_UPDATE(raw_value, 0x07ff, mmc_clock->shift), 146 - mmc_clock->reg); 137 + raw_value = HIWORD_UPDATE(raw_value, 0x07ff, mmc_clock->shift); 138 + 139 + if (mmc_clock->grf) 140 + regmap_write(mmc_clock->grf, mmc_clock->grf_reg, raw_value); 141 + else 142 + writel(raw_value, mmc_clock->reg); 147 143 148 144 pr_debug("%s->set_phase(%d) delay_nums=%u reg[0x%p]=0x%03x actual_degrees=%d\n", 149 145 clk_hw_get_name(hw), degrees, delay_num, ··· 201 189 202 190 struct clk *rockchip_clk_register_mmc(const char *name, 203 191 const char *const *parent_names, u8 num_parents, 204 - void __iomem *reg, int shift) 192 + void __iomem *reg, 193 + struct regmap *grf, int grf_reg, 194 + int shift) 205 195 { 206 196 struct clk_init_data init; 207 197 struct rockchip_mmc_clock *mmc_clock; ··· 222 208 223 209 mmc_clock->hw.init = &init; 224 210 mmc_clock->reg = reg; 211 + mmc_clock->grf = grf; 212 + mmc_clock->grf_reg = grf_reg; 225 213 mmc_clock->shift = shift; 226 214 227 215 clk = clk_register(NULL, &mmc_clock->hw);
+14 -2
drivers/clk/rockchip/clk.c
··· 509 509 clk = NULL; 510 510 511 511 /* for GRF-dependent branches, choose the right grf first */ 512 - if ((list->branch_type == branch_muxgrf || list->branch_type == branch_grf_gate) && 513 - list->grf_type != grf_type_sys) { 512 + if ((list->branch_type == branch_muxgrf || 513 + list->branch_type == branch_grf_gate || 514 + list->branch_type == branch_grf_mmc) && 515 + list->grf_type != grf_type_sys) { 514 516 hash_for_each_possible(ctx->aux_grf_table, agrf, node, list->grf_type) { 515 517 if (agrf->type == list->grf_type) { 516 518 grf = agrf->grf; ··· 614 612 list->name, 615 613 list->parent_names, list->num_parents, 616 614 ctx->reg_base + list->muxdiv_offset, 615 + NULL, 0, 616 + list->div_shift 617 + ); 618 + break; 619 + case branch_grf_mmc: 620 + clk = rockchip_clk_register_mmc( 621 + list->name, 622 + list->parent_names, list->num_parents, 623 + 0, 624 + grf, list->muxdiv_offset, 617 625 list->div_shift 618 626 ); 619 627 break;
+16 -1
drivers/clk/rockchip/clk.h
··· 619 619 620 620 struct clk *rockchip_clk_register_mmc(const char *name, 621 621 const char *const *parent_names, u8 num_parents, 622 - void __iomem *reg, int shift); 622 + void __iomem *reg, 623 + struct regmap *grf, int grf_reg, 624 + int shift); 623 625 624 626 /* 625 627 * DDRCLK flags, including method of setting the rate ··· 666 664 branch_grf_gate, 667 665 branch_linked_gate, 668 666 branch_mmc, 667 + branch_grf_mmc, 669 668 branch_inverter, 670 669 branch_factor, 671 670 branch_ddrclk, ··· 1031 1028 .num_parents = 1, \ 1032 1029 .muxdiv_offset = offset, \ 1033 1030 .div_shift = shift, \ 1031 + } 1032 + 1033 + #define MMC_GRF(_id, cname, pname, offset, shift, grftype) \ 1034 + { \ 1035 + .id = _id, \ 1036 + .branch_type = branch_grf_mmc, \ 1037 + .name = cname, \ 1038 + .parent_names = (const char *[]){ pname }, \ 1039 + .num_parents = 1, \ 1040 + .muxdiv_offset = offset, \ 1041 + .div_shift = shift, \ 1042 + .grf_type = grftype, \ 1034 1043 } 1035 1044 1036 1045 #define INVERTER(_id, cname, pname, io, is, if) \