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

Configure Feed

Select the types of activity you want to include in your feed.

clk: rockchip: introduce auxiliary GRFs

The MUXGRF clock branch type depends on having access to some sort of
GRF as a regmap to be registered. So far, we could easily get away with
only ever having one GRF stowed away in the context.

However, newer Rockchip SoCs, such as the RK3576, have several GRFs
which are relevant for clock purposes. It already depends on the pmu0
GRF for MUXGRF reasons, but could get away with not refactoring this
because it didn't need the sysgrf at all, so could overwrite the pointer
in the clock provider to the pmu0 grf regmap handle.

In preparation for needing to finally access more than one GRF per SoC,
let's untangle this. Introduce an auxiliary GRF hashmap, and a GRF type
enum. The hashmap is keyed by the enum, and clock branches now have a
struct member to store the value of that enum, which defaults to the
system GRF.

The SoC-specific _clk_init function can then insert pointers to GRF
regmaps into the hashmap based on the grf type.

During clock branch registration, we then pick the right GRF for each
branch from the hashmap if something other than the sys GRF is
requested.

The reason for doing it with this grf type indirection in the clock
branches is so that we don't need to define the MUXGRF branches in a
separate step, just to have a direct pointer to a regmap available
already.

Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
Link: https://lore.kernel.org/r/20250502-rk3576-sai-v3-2-376cef19dd7c@collabora.com
Signed-off-by: Heiko Stuebner <heiko@sntech.de>

authored by

Nicolas Frattaroli and committed by
Heiko Stuebner
70a114da 6657acc8

+72 -18
+1 -1
drivers/clk/rockchip/clk-rk3288.c
··· 418 418 RK3288_CLKSEL_CON(32), 14, 2, MFLAGS, 8, 5, DFLAGS, 419 419 RK3288_CLKGATE_CON(3), 11, GFLAGS), 420 420 MUXGRF(0, "aclk_vcodec_pre", mux_aclk_vcodec_pre_p, CLK_SET_RATE_PARENT, 421 - RK3288_GRF_SOC_CON(0), 7, 1, MFLAGS), 421 + RK3288_GRF_SOC_CON(0), 7, 1, MFLAGS, grf_type_sys), 422 422 GATE(ACLK_VCODEC, "aclk_vcodec", "aclk_vcodec_pre", 0, 423 423 RK3288_CLKGATE_CON(9), 0, GFLAGS), 424 424
+3 -3
drivers/clk/rockchip/clk-rk3328.c
··· 677 677 RK3328_CLKSEL_CON(27), 15, 1, MFLAGS, 8, 5, DFLAGS, 678 678 RK3328_CLKGATE_CON(3), 5, GFLAGS), 679 679 MUXGRF(SCLK_MAC2IO, "clk_mac2io", mux_mac2io_src_p, CLK_SET_RATE_NO_REPARENT, 680 - RK3328_GRF_MAC_CON1, 10, 1, MFLAGS), 680 + RK3328_GRF_MAC_CON1, 10, 1, MFLAGS, grf_type_sys), 681 681 MUXGRF(SCLK_MAC2IO_EXT, "clk_mac2io_ext", mux_mac2io_ext_p, CLK_SET_RATE_NO_REPARENT, 682 - RK3328_GRF_SOC_CON4, 14, 1, MFLAGS), 682 + RK3328_GRF_SOC_CON4, 14, 1, MFLAGS, grf_type_sys), 683 683 684 684 COMPOSITE(SCLK_MAC2PHY_SRC, "clk_mac2phy_src", mux_2plls_p, 0, 685 685 RK3328_CLKSEL_CON(26), 7, 1, MFLAGS, 0, 5, DFLAGS, ··· 692 692 RK3328_CLKSEL_CON(26), 8, 2, DFLAGS, 693 693 RK3328_CLKGATE_CON(9), 2, GFLAGS), 694 694 MUXGRF(SCLK_MAC2PHY, "clk_mac2phy", mux_mac2phy_src_p, CLK_SET_RATE_NO_REPARENT, 695 - RK3328_GRF_MAC_CON2, 10, 1, MFLAGS), 695 + RK3328_GRF_MAC_CON2, 10, 1, MFLAGS, grf_type_sys), 696 696 697 697 FACTOR(0, "xin12m", "xin24m", 0, 1, 2), 698 698
+1 -1
drivers/clk/rockchip/clk-rk3568.c
··· 591 591 RK3568_CLKSEL_CON(9), 6, 2, MFLAGS, 0, 5, DFLAGS, 592 592 RK3568_CLKGATE_CON(4), 0, GFLAGS), 593 593 MUXGRF(CLK_DDR1X, "clk_ddr1x", clk_ddr1x_p, CLK_SET_RATE_PARENT, 594 - RK3568_CLKSEL_CON(9), 15, 1, MFLAGS), 594 + RK3568_CLKSEL_CON(9), 15, 1, MFLAGS, grf_type_sys), 595 595 596 596 COMPOSITE_NOMUX(CLK_MSCH, "clk_msch", "clk_ddr1x", CLK_IGNORE_UNUSED, 597 597 RK3568_CLKSEL_CON(10), 0, 2, DFLAGS,
+22 -10
drivers/clk/rockchip/clk-rk3576.c
··· 1676 1676 1677 1677 /* phy ref */ 1678 1678 MUXGRF(CLK_PHY_REF_SRC, "clk_phy_ref_src", clk_phy_ref_src_p, 0, 1679 - RK3576_PMU0_GRF_OSC_CON6, 4, 1, MFLAGS), 1679 + RK3576_PMU0_GRF_OSC_CON6, 4, 1, MFLAGS, grf_type_pmu0), 1680 1680 MUXGRF(CLK_USBPHY_REF_SRC, "clk_usbphy_ref_src", clk_usbphy_ref_src_p, 0, 1681 - RK3576_PMU0_GRF_OSC_CON6, 2, 1, MFLAGS), 1681 + RK3576_PMU0_GRF_OSC_CON6, 2, 1, MFLAGS, grf_type_pmu0), 1682 1682 MUXGRF(CLK_CPLL_REF_SRC, "clk_cpll_ref_src", clk_cpll_ref_src_p, 0, 1683 - RK3576_PMU0_GRF_OSC_CON6, 1, 1, MFLAGS), 1683 + RK3576_PMU0_GRF_OSC_CON6, 1, 1, MFLAGS, grf_type_pmu0), 1684 1684 MUXGRF(CLK_AUPLL_REF_SRC, "clk_aupll_ref_src", clk_aupll_ref_src_p, 0, 1685 - RK3576_PMU0_GRF_OSC_CON6, 0, 1, MFLAGS), 1685 + RK3576_PMU0_GRF_OSC_CON6, 0, 1, MFLAGS, grf_type_pmu0), 1686 1686 1687 1687 /* secure ns */ 1688 1688 COMPOSITE_NODIV(ACLK_SECURE_NS, "aclk_secure_ns", mux_350m_175m_116m_24m_p, CLK_IS_CRITICAL, ··· 1725 1725 struct rockchip_clk_provider *ctx; 1726 1726 unsigned long clk_nr_clks; 1727 1727 void __iomem *reg_base; 1728 - struct regmap *grf; 1728 + struct rockchip_aux_grf *pmu0_grf_e; 1729 + struct regmap *pmu0_grf; 1729 1730 1730 1731 clk_nr_clks = rockchip_clk_find_max_clk_id(rk3576_clk_branches, 1731 1732 ARRAY_SIZE(rk3576_clk_branches)) + 1; 1732 1733 1733 - grf = syscon_regmap_lookup_by_compatible("rockchip,rk3576-pmu0-grf"); 1734 - if (IS_ERR(grf)) { 1734 + pmu0_grf = syscon_regmap_lookup_by_compatible("rockchip,rk3576-pmu0-grf"); 1735 + if (IS_ERR(pmu0_grf)) { 1735 1736 pr_err("%s: could not get PMU0 GRF syscon\n", __func__); 1736 1737 return; 1737 1738 } ··· 1746 1745 ctx = rockchip_clk_init(np, reg_base, clk_nr_clks); 1747 1746 if (IS_ERR(ctx)) { 1748 1747 pr_err("%s: rockchip clk init failed\n", __func__); 1749 - iounmap(reg_base); 1750 - return; 1748 + goto err_unmap; 1751 1749 } 1752 1750 1753 - ctx->grf = grf; 1751 + pmu0_grf_e = kzalloc(sizeof(*pmu0_grf_e), GFP_KERNEL); 1752 + if (!pmu0_grf_e) 1753 + goto err_unmap; 1754 + 1755 + pmu0_grf_e->grf = pmu0_grf; 1756 + pmu0_grf_e->type = grf_type_pmu0; 1757 + hash_add(ctx->aux_grf_table, &pmu0_grf_e->node, grf_type_pmu0); 1754 1758 1755 1759 rockchip_clk_register_plls(ctx, rk3576_pll_clks, 1756 1760 ARRAY_SIZE(rk3576_pll_clks), ··· 1778 1772 rockchip_register_restart_notifier(ctx, RK3576_GLB_SRST_FST, NULL); 1779 1773 1780 1774 rockchip_clk_of_add_provider(np, ctx); 1775 + 1776 + return; 1777 + 1778 + err_unmap: 1779 + iounmap(reg_base); 1780 + return; 1781 1781 } 1782 1782 1783 1783 CLK_OF_DECLARE(rk3576_cru, "rockchip,rk3576-cru", rk3576_clk_init);
+1 -1
drivers/clk/rockchip/clk-rv1126.c
··· 857 857 RV1126_GMAC_CON, 5, 1, MFLAGS), 858 858 MUXGRF(CLK_GMAC_SRC, "clk_gmac_src", mux_clk_gmac_src_p, CLK_SET_RATE_PARENT | 859 859 CLK_SET_RATE_NO_REPARENT, 860 - RV1126_GRF_IOFUNC_CON1, 12, 1, MFLAGS), 860 + RV1126_GRF_IOFUNC_CON1, 12, 1, MFLAGS, grf_type_sys), 861 861 862 862 GATE(CLK_GMAC_REF, "clk_gmac_ref", "clk_gmac_src", 0, 863 863 RV1126_CLKGATE_CON(20), 7, GFLAGS),
+16 -1
drivers/clk/rockchip/clk.c
··· 382 382 ctx->cru_node = np; 383 383 spin_lock_init(&ctx->lock); 384 384 385 + hash_init(ctx->aux_grf_table); 386 + 385 387 ctx->grf = syscon_regmap_lookup_by_phandle(ctx->cru_node, 386 388 "rockchip,grf"); 387 389 ··· 498 496 struct rockchip_clk_branch *list, 499 497 unsigned int nr_clk) 500 498 { 499 + struct regmap *grf = ctx->grf; 500 + struct rockchip_aux_grf *agrf; 501 501 struct clk *clk; 502 502 unsigned int idx; 503 503 unsigned long flags; ··· 507 503 for (idx = 0; idx < nr_clk; idx++, list++) { 508 504 flags = list->flags; 509 505 clk = NULL; 506 + 507 + /* for GRF-dependent branches, choose the right grf first */ 508 + if (list->branch_type == branch_muxgrf && 509 + list->grf_type != grf_type_sys) { 510 + hash_for_each_possible(ctx->aux_grf_table, agrf, node, list->grf_type) { 511 + if (agrf->type == list->grf_type) { 512 + grf = agrf->grf; 513 + break; 514 + } 515 + } 516 + } 510 517 511 518 /* catch simple muxes */ 512 519 switch (list->branch_type) { ··· 541 526 case branch_muxgrf: 542 527 clk = rockchip_clk_register_muxgrf(list->name, 543 528 list->parent_names, list->num_parents, 544 - flags, ctx->grf, list->muxdiv_offset, 529 + flags, grf, list->muxdiv_offset, 545 530 list->mux_shift, list->mux_width, 546 531 list->mux_flags); 547 532 break;
+28 -1
drivers/clk/rockchip/clk.h
··· 19 19 20 20 #include <linux/io.h> 21 21 #include <linux/clk-provider.h> 22 + #include <linux/hashtable.h> 22 23 23 24 struct clk; 24 25 ··· 441 440 .k = _k, \ 442 441 } 443 442 443 + enum rockchip_grf_type { 444 + grf_type_sys = 0, 445 + grf_type_pmu0, 446 + grf_type_pmu1, 447 + grf_type_ioc, 448 + }; 449 + 450 + /* ceil(sqrt(enums in rockchip_grf_type - 1)) */ 451 + #define GRF_HASH_ORDER 2 452 + 453 + /** 454 + * struct rockchip_aux_grf - entry for the aux_grf_table hashtable 455 + * @grf: pointer to the grf this entry references 456 + * @type: what type of GRF this is 457 + * @node: hlist node 458 + */ 459 + struct rockchip_aux_grf { 460 + struct regmap *grf; 461 + enum rockchip_grf_type type; 462 + struct hlist_node node; 463 + }; 464 + 444 465 /** 445 466 * struct rockchip_clk_provider - information about clock provider 446 467 * @reg_base: virtual address for the register base. 447 468 * @clk_data: holds clock related data like clk* and number of clocks. 448 469 * @cru_node: device-node of the clock-provider 449 470 * @grf: regmap of the general-register-files syscon 471 + * @aux_grf_table: hashtable of auxiliary GRF regmaps, indexed by grf_type 450 472 * @lock: maintains exclusion between callbacks for a given clock-provider. 451 473 */ 452 474 struct rockchip_clk_provider { ··· 477 453 struct clk_onecell_data clk_data; 478 454 struct device_node *cru_node; 479 455 struct regmap *grf; 456 + DECLARE_HASHTABLE(aux_grf_table, GRF_HASH_ORDER); 480 457 spinlock_t lock; 481 458 }; 482 459 ··· 685 660 u8 gate_shift; 686 661 u8 gate_flags; 687 662 unsigned int linked_clk_id; 663 + enum rockchip_grf_type grf_type; 688 664 struct rockchip_clk_branch *child; 689 665 }; 690 666 ··· 926 900 .mux_table = mt, \ 927 901 } 928 902 929 - #define MUXGRF(_id, cname, pnames, f, o, s, w, mf) \ 903 + #define MUXGRF(_id, cname, pnames, f, o, s, w, mf, gt) \ 930 904 { \ 931 905 .id = _id, \ 932 906 .branch_type = branch_muxgrf, \ ··· 939 913 .mux_width = w, \ 940 914 .mux_flags = mf, \ 941 915 .gate_offset = -1, \ 916 + .grf_type = gt, \ 942 917 } 943 918 944 919 #define DIV(_id, cname, pname, f, o, s, w, df) \