[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CAAhV-H4=A=BaHsAKmTiS62gE6XQLD4rnYmU6snDFt1S0uMHr6A@mail.gmail.com>
Date: Thu, 7 Aug 2025 19:21:32 +0800
From: Huacai Chen <chenhuacai@...nel.org>
To: Yao Zi <ziyao@...root.org>
Cc: Yinbo Zhu <zhuyinbo@...ngson.cn>, Michael Turquette <mturquette@...libre.com>,
Stephen Boyd <sboyd@...nel.org>, Rob Herring <robh@...nel.org>,
Krzysztof Kozlowski <krzk+dt@...nel.org>, Conor Dooley <conor+dt@...nel.org>,
WANG Xuerui <kernel@...0n.name>, linux-clk@...r.kernel.org, devicetree@...r.kernel.org,
linux-kernel@...r.kernel.org, loongarch@...ts.linux.dev,
Mingcong Bai <jeffbai@...c.io>, Kexy Biscuit <kexybiscuit@...c.io>
Subject: Re: [PATCH v3 6/8] clk: loongson2: Add clock definitions for Loongson
2K0300 SoC
Hi, Yao,
On Tue, Aug 5, 2025 at 11:05 PM Yao Zi <ziyao@...root.org> wrote:
>
> The clock controller of Loongson 2K0300 consists of three PLLs, requires
> an 120MHz external reference clock to function, and generates clocks in
> various frequencies for SoC peripherals.
>
> Clock definitions for previous SoC generations could be reused for most
> clock hardwares. There're two gates marked as critical, clk_node_gate
> and clk_boot_gate, which supply the CPU cores and the system
> configuration bus. Disabling them leads to a SoC hang.
>
> Signed-off-by: Yao Zi <ziyao@...root.org>
> ---
> drivers/clk/clk-loongson2.c | 48 +++++++++++++++++++++++++++++++++++++
> 1 file changed, 48 insertions(+)
>
> diff --git a/drivers/clk/clk-loongson2.c b/drivers/clk/clk-loongson2.c
> index 52a9f1c2794a..1d210a7683ea 100644
> --- a/drivers/clk/clk-loongson2.c
> +++ b/drivers/clk/clk-loongson2.c
> @@ -12,6 +12,7 @@
> #include <linux/platform_device.h>
> #include <linux/io-64-nonatomic-lo-hi.h>
> #include <dt-bindings/clock/loongson,ls2k-clk.h>
> +#include <dt-bindings/clock/loongson,ls2k0300-clk.h>
>
> enum loongson2_clk_type {
> CLK_TYPE_PLL,
> @@ -137,6 +138,52 @@ struct loongson2_clk_board_info {
> .fixed_rate = _rate, \
> }
>
> +static const struct loongson2_clk_board_info ls2k0300_clks[] = {
> + /* Reference Clock */
> + CLK_PLL(LS2K0300_PLL_NODE, "pll_node", 0x00, 15, 9, 8, 7),
> + CLK_PLL(LS2K0300_PLL_DDR, "pll_ddr", 0x08, 15, 9, 8, 7),
> + CLK_PLL(LS2K0300_PLL_PIX, "pll_pix", 0x10, 15, 9, 8, 7),
> + CLK_FIXED(LS2K0300_CLK_STABLE, "clk_stable", NULL, 100000000),
> + CLK_FIXED(LS2K0300_CLK_THSENS, "clk_thsens", NULL, 10000000),
> + /* Node PLL */
> + CLK_DIV(LS2K0300_CLK_NODE_DIV, "clk_node_div", "pll_node", 0x00, 24, 7),
> + CLK_DIV(LS2K0300_CLK_GMAC_DIV, "clk_gmac_div", "pll_node", 0x04, 0, 7),
> + CLK_DIV(LS2K0300_CLK_I2S_DIV, "clk_i2s_div", "pll_node", 0x04, 8, 7),
> + CLK_GATE(LS2K0300_CLK_NODE_PLL_GATE, "clk_node_pll_gate", "clk_node_div", 0x00, 0),
> + CLK_GATE(LS2K0300_CLK_GMAC_GATE, "clk_gmac_gate", "clk_gmac_div", 0x00, 1),
> + CLK_GATE(LS2K0300_CLK_I2S_GATE, "clk_i2s_gate", "clk_i2s_div", 0x00, 2),
> + CLK_GATE_FLAGS(LS2K0300_CLK_NODE_GATE, "clk_node_gate", "clk_node_scale",
> + 0x24, 0, CLK_IS_CRITICAL),
There is no 80 chars limit now, so feel free to define a clock in one line.
> + CLK_SCALE_MODE(LS2K0300_CLK_NODE_SCALE, "clk_node_scale", "clk_node_pll_gate",
> + 0x20, 0, 3, 3),
The same.
> + /* DDR PLL */
> + CLK_DIV(LS2K0300_CLK_DDR_DIV, "clk_ddr_div", "pll_ddr", 0x08, 24, 7),
> + CLK_DIV(LS2K0300_CLK_NET_DIV, "clk_net_div", "pll_ddr", 0x0c, 0, 7),
> + CLK_DIV(LS2K0300_CLK_DEV_DIV, "clk_dev_div", "pll_ddr", 0x0c, 8, 7),
> + CLK_GATE(LS2K0300_CLK_NET_GATE, "clk_net_gate", "clk_net_div", 0x08, 1),
> + CLK_GATE(LS2K0300_CLK_DEV_GATE, "clk_dev_gate", "clk_dev_div", 0x08, 2),
> + CLK_GATE_FLAGS(LS2K0300_CLK_DDR_GATE, "clk_ddr_gate", "clk_ddr_div",
> + 0x08, 0, CLK_IS_CRITICAL),
The same.
> + /* PIX PLL */
> + CLK_DIV(LS2K0300_CLK_PIX_DIV, "clk_pix_div", "pll_pix", 0x10, 24, 7),
> + CLK_DIV(LS2K0300_CLK_GMACBP_DIV, "clk_gmacbp_div", "pll_pix", 0x14, 0, 7),
> + CLK_GATE(LS2K0300_CLK_PIX_PLL_GATE, "clk_pix_pll_gate", "clk_pix_div", 0x10, 0),
> + CLK_GATE(LS2K0300_CLK_PIX_GATE, "clk_pix_gate", "clk_pix_scale", 0x24, 6),
> + CLK_GATE(LS2K0300_CLK_GMACBP_GATE, "clk_gmacbp_gate", "clk_gmacbp_div", 0x10, 1),
> + CLK_SCALE_MODE(LS2K0300_CLK_PIX_SCALE, "clk_pix_scale", "clk_pix_pll_gate",
> + 0x20, 4, 3, 7),
The same.
> + /* clk_dev_gate */
> + CLK_DIV(LS2K0300_CLK_SDIO_SCALE, "clk_sdio_scale", "clk_dev_gate", 0x20, 24, 4),
> + CLK_GATE(LS2K0300_CLK_USB_GATE, "clk_usb_gate", "clk_usb_scale", 0x24, 2),
> + CLK_GATE(LS2K0300_CLK_SDIO_GATE, "clk_sdio_gate", "clk_sdio_scale", 0x24, 4),
> + CLK_GATE(LS2K0300_CLK_APB_GATE, "clk_apb_gate", "clk_apb_scale", 0x24, 3),
> + CLK_GATE_FLAGS(LS2K0300_CLK_BOOT_GATE, "clk_boot_gate", "clk_boot_scale",
> + 0x24, 1, CLK_IS_CRITICAL),
The same.
Huacai
> + CLK_SCALE_MODE(LS2K0300_CLK_USB_SCALE, "clk_usb_scale", "clk_dev_gate", 0x20, 12, 3, 15),
> + CLK_SCALE_MODE(LS2K0300_CLK_APB_SCALE, "clk_apb_scale", "clk_dev_gate", 0x20, 16, 3, 19),
> + CLK_SCALE_MODE(LS2K0300_CLK_BOOT_SCALE, "clk_boot_scale", "clk_dev_gate", 0x20, 8, 3, 11),
> +};
> +
> static const struct loongson2_clk_board_info ls2k0500_clks[] = {
> CLK_PLL(LOONGSON2_NODE_PLL, "pll_node", 0, 16, 8, 8, 6),
> CLK_PLL(LOONGSON2_DDR_PLL, "pll_ddr", 0x8, 16, 8, 8, 6),
> @@ -393,6 +440,7 @@ static int loongson2_clk_probe(struct platform_device *pdev)
> }
>
> static const struct of_device_id loongson2_clk_match_table[] = {
> + { .compatible = "loongson,ls2k0300-clk", .data = &ls2k0300_clks },
> { .compatible = "loongson,ls2k0500-clk", .data = &ls2k0500_clks },
> { .compatible = "loongson,ls2k-clk", .data = &ls2k1000_clks },
> { .compatible = "loongson,ls2k2000-clk", .data = &ls2k2000_clks },
> --
> 2.50.1
>
Powered by blists - more mailing lists