15 Commits
Author SHA1 Message Date
Yao ZiandStephen Boyd 74743c53a1 clk: loongson2: Add clock definitions for Loongson-2K0300 SoC
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@disroot.org>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2025-09-21 12:48:51 -07:00
Yao ZiandStephen Boyd 158ddb87b1 clk: loongson2: Avoid hardcoding firmware name of the reference clock
Loongson-2K0300 requires a reference clock with a frequency different
from previous SoCs (120MHz v.s. 100MHz), thus hardcoding the firmware
name of the reference clock as ref_100m isn't a good idea.

This patch retrives the clock name of the reference clock dynamically
during probe, avoiding the hardcoded pdata structure and preparing for
support of future SoCs.

Signed-off-by: Yao Zi <ziyao@disroot.org>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2025-09-21 12:48:49 -07:00
Yao ZiandStephen Boyd 1ba5395c6a clk: loongson2: Allow zero divisors for dividers
LS2K0300 and LS2K0500 ship divider clocks which allows zero divisors,
in which case the divider acts the same as one is specified.

Let's pass CLK_DIVIDER_ALLOW_ZERO when registering divider clocks to
prepare for future introduction of these clocks.

Signed-off-by: Yao Zi <ziyao@disroot.org>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2025-09-21 12:48:48 -07:00
Yao ZiandStephen Boyd 897117e35e clk: loongson2: Support scale clocks with an alternative mode
LS2K0300 and LS2K1500 ship scale clocks with an alternative mode.
There's one mode bit in clock configuration register indicating the
operation mode.

When mode bit is unset, the scale clock acts the same as previous
generation of scale clocks. When it's set, a different equation for
calculating result frequency, Fout = Fin / (scale + 1), is used.

This patch adds frequency calculation support for the scale clock
variant. A helper macro, CLK_SCALE_MODE, is added to simplify
definitions.

Signed-off-by: Yao Zi <ziyao@disroot.org>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2025-09-21 12:48:46 -07:00
Yao ZiandStephen Boyd 499f81848e clk: loongson2: Allow specifying clock flags for gate clock
Some gate clocks need to be supplied with flags, e.g., it may be
required to specify CLK_IS_CRTICAL for CPU clocks.

Add a field to loongson2_clk_board_info for representing clock flags,
and specify it when registering gate clocks. A new helper macro,
CLK_GATE_FLAGS, is added to simplify definitions.

Signed-off-by: Yao Zi <ziyao@disroot.org>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2025-09-21 12:48:45 -07:00
Stephen Boyd 53c9c27672 Merge branch 'clk-fixes' into clk-next
* clk-fixes:
  clk: clk-loongson2: Fix the number count of clk provider
  clk: mmp2: call pm_genpd_init() only after genpd.name is set
  clk: sunxi-ng: a100: enable MMC clock reparenting
  clk: clk-imx8mp-audiomix: fix function signature
  clk: thead: Fix TH1520 emmc and shdci clock rate
2025-01-21 11:22:46 -08:00
Binbin ZhouandStephen Boyd 5fb33b6797 clk: clk-loongson2: Fix the number count of clk provider
Since commit 02fb4f0084 ("clk: clk-loongson2: Fix potential buffer
overflow in flexible-array member access"), the clk provider register is
failed.

The count of `clks_num` is shown below:

	for (p = data; p->name; p++)
		clks_num++;

In fact, `clks_num` represents the number of SoC clocks and should be
expressed as the maximum value of the clock binding id in use (p->id + 1).

Now we fix it to avoid the following error when trying to register a clk
provider:

[ 13.409595] of_clk_hw_onecell_get: invalid index 17

Cc: stable@vger.kernel.org
Cc: Gustavo A. R. Silva <gustavoars@kernel.org>
Fixes: 02fb4f0084 ("clk: clk-loongson2: Fix potential buffer overflow in flexible-array member access")
Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn>
Link: https://lore.kernel.org/r/82e43d89a9a6791129cf8ea14f4eeb666cd87be4.1736856470.git.zhoubinbin@loongson.cn
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2025-01-14 11:14:33 -08:00
Binbin ZhouandStephen Boyd 54e020bd11 clk: clk-loongson2: Switch to use devm_clk_hw_register_fixed_rate_parent_data()
Since commit 706ae64464 ("clk: fixed-rate: add
devm_clk_hw_register_fixed_rate_parent_data()"), we can use the
devm_clk_hw_register_fixed_rate_parent_data() helper and from then on
there is no need to manually unregister the fixed rate hw.

Since clk_hw_unregister_fixed_rate() was not called before, we also fix
the memory leak that was present.

Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn>
Link: https://lore.kernel.org/r/8733a7485619bdb791de25201a3d7984d1849c9f.1736856470.git.zhoubinbin@loongson.cn
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2025-01-14 11:14:06 -08:00
Gustavo A. R. SilvaandStephen Boyd 02fb4f0084 clk: clk-loongson2: Fix potential buffer overflow in flexible-array member access
Flexible-array member `hws` in `struct clk_hw_onecell_data` is annotated
with the `counted_by()` attribute. This means that when memory is
allocated for this array, the _counter_, which in this case is member
`num` in the flexible structure, should be set to the maximum number of
elements the flexible array can contain, or fewer.

In this case, the total number of elements for the flexible array is
determined by variable `clks_num` when allocating heap space via
`devm_kzalloc()`, as shown below:

289         struct loongson2_clk_provider *clp;
	...
296         for (p = data; p->name; p++)
297                 clks_num++;
298
299         clp = devm_kzalloc(dev, struct_size(clp, clk_data.hws, clks_num),
300                            GFP_KERNEL);

So, `clp->clk_data.num` should be set to `clks_num` or less, and not
exceed `clks_num`, as is currently the case. Otherwise, if data is
written into `clp->clk_data.hws[clks_num]`, the instrumentation
provided by the compiler won't detect the overflow, leading to a
memory corruption bug at runtime.

Fix this issue by setting `clp->clk_data.num` to `clks_num`.

Fixes: 9796ec0bd0 ("clk: clk-loongson2: Refactor driver for adding new platforms")
Cc: stable@vger.kernel.org
Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
Link: https://lore.kernel.org/r/ZzaN5MpmMr0hwHw9@kspp
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2024-11-18 19:51:28 -08:00
Gustavo A. R. SilvaandStephen Boyd 6e4bf018bb clk: clk-loongson2: Fix memory corruption bug in struct loongson2_clk_provider
Some heap space is allocated for the flexible structure `struct
clk_hw_onecell_data` and its flexible-array member `hws` through
the composite structure `struct loongson2_clk_provider` in function
`loongson2_clk_probe()`, as shown below:

289         struct loongson2_clk_provider *clp;
	...
296         for (p = data; p->name; p++)
297                 clks_num++;
298
299         clp = devm_kzalloc(dev, struct_size(clp, clk_data.hws, clks_num),
300                            GFP_KERNEL);

Then some data is written into the flexible array:

350                 clp->clk_data.hws[p->id] = hw;

This corrupts `clk_lock`, which is the spinlock variable immediately
following the `clk_data` member in `struct loongson2_clk_provider`:

struct loongson2_clk_provider {
	void __iomem *base;
	struct device *dev;
	struct clk_hw_onecell_data clk_data;
	spinlock_t clk_lock;	/* protect access to DIV registers */
};

The problem is that the flexible structure is currently placed in the
middle of `struct loongson2_clk_provider` instead of at the end.

Fix this by moving `struct clk_hw_onecell_data clk_data;` to the end of
`struct loongson2_clk_provider`. Also, add a code comment to help
prevent this from happening again in case new members are added to the
structure in the future.

This change also fixes the following -Wflex-array-member-not-at-end
warning:

drivers/clk/clk-loongson2.c:32:36: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end]

Fixes: 9796ec0bd0 ("clk: clk-loongson2: Refactor driver for adding new platforms")
Cc: stable@vger.kernel.org
Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
Link: https://lore.kernel.org/r/ZzZ-cd_EFXs6qFaH@kspp
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2024-11-18 19:51:27 -08:00
Binbin ZhouandStephen Boyd 4f149dd478 clk: clk-loongson2: Add Loongson-2K2000 clock support
The Loongson-2K2000 and Loongson-2K1000 clock is similar, we add its
support by different configurations.

Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn>
Link: https://lore.kernel.org/r/8b0b5851783acf8ebe13b50391d15b58cc181613.1712731524.git.zhoubinbin@loongson.cn
Acked-by: Huacai Chen <chenhuacai@loongson.cn>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2024-04-11 00:30:13 -07:00
Binbin ZhouandStephen Boyd 85d4daa595 clk: clk-loongson2: Add Loongson-2K0500 clock support
The Loongson-2K0500 and Loongson-2K1000 clock is similar, we add its
support by different configurations.

Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn>
Link: https://lore.kernel.org/r/f767a1783dc590fcd31ff7d4459df2cf80196de1.1712731524.git.zhoubinbin@loongson.cn
Acked-by: Huacai Chen <chenhuacai@loongson.cn>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2024-04-11 00:30:08 -07:00
Binbin ZhouandStephen Boyd 9796ec0bd0 clk: clk-loongson2: Refactor driver for adding new platforms
The driver only supported loongson-2K1000 at first, but the clock
structure of loongson-2K0500 and loongson-2K2000 are actually similar,
and I tried to refactor the whole driver to adjust to the addition of
the new platform.

Briefly, I have divided all clocks into three categories according to
their properties and their parent clocks: Independent PLLs, clocks based
on frequency scales, and clock dividers.

Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn>
Link: https://lore.kernel.org/r/fb020d1ca19e6f4cdcc95c87b2748869ca76b8ec.1712731524.git.zhoubinbin@loongson.cn
Acked-by: Huacai Chen <chenhuacai@loongson.cn>
[sboyd@kernel.org: Drop clk.h include]
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2024-04-11 00:30:00 -07:00
Binbin ZhouandStephen Boyd 2a809ddca0 clk: clk-loongson2: Zero init clk_init_data
As clk_core_populate_parent_map() checks clk_init_data.num_parents
first, and checks clk_init_data.parent_names[] before
clk_init_data.parent_data[] and clk_init_data.parent_hws[].

Therefore the clk_init_data structure needs to be explicitly initialised
to prevent an unexpected crash if clk_init_data.parent_names[] is a
random value.

 CPU 0 Unable to handle kernel paging request at virtual address 0000000000000dc0, era == 9000000002986290, ra == 900000000298624c
 Oops[#1]:
 CPU: 0 PID: 1 Comm: swapper/0 Not tainted 6.4.0-rc2+ #4582
 pc 9000000002986290 ra 900000000298624c tp 9000000100094000 sp 9000000100097a60
 a0 9000000104541e00 a1 0000000000000000 a2 0000000000000dc0 a3 0000000000000001
 a4 90000001000979f0 a5 90000001800977d7 a6 0000000000000000 a7 900000000362a000
 t0 90000000034f3548 t1 6f8c2a9cb5ab5f64 t2 0000000000011340 t3 90000000031cf5b0
 t4 0000000000000dc0 t5 0000000000000004 t6 0000000000011300 t7 9000000104541e40
 t8 000000000005a4f8 u0 9000000104541e00 s9 9000000104541e00 s0 9000000104bc4700
 s1 9000000104541da8 s2 0000000000000001 s3 900000000356f9d8 s4 ffffffffffffffff
 s5 0000000000000000 s6 0000000000000dc0 s7 90000000030d0a88 s8 0000000000000000
    ra: 900000000298624c __clk_register+0x228/0x84c
   ERA: 9000000002986290 __clk_register+0x26c/0x84c
  CRMD: 000000b0 (PLV0 -IE -DA +PG DACF=CC DACM=CC -WE)
  PRMD: 00000004 (PPLV0 +PIE -PWE)
  EUEN: 00000000 (-FPE -SXE -ASXE -BTE)
  ECFG: 00071c1c (LIE=2-4,10-12 VS=7)
 ESTAT: 00010000 [PIL] (IS= ECode=1 EsubCode=0)
  BADV: 0000000000000dc0
  PRID: 0014a000 (Loongson-64bit, )
 Modules linked in:
 Process swapper/0 (pid: 1, threadinfo=(____ptrval____), task=(____ptrval____))
 Stack : 90000000031c1810 90000000030d0a88 900000000325bac0 90000000034f3548
         90000001002ab410 9000000104541e00 0000000000000dc0 9000000003150098
         90000000031c1810 90000000031a0460 900000000362a000 90000001002ab410
         900000000362a000 9000000104541da8 9000000104541de8 90000001002ab410
         900000000362a000 9000000002986a68 90000000034f3ed8 90000000030d0aa8
         9000000104541da8 900000000298d3b8 90000000031c1810 0000000000000000
         90000000034f3ed8 90000000030d0aa8 0000000000000dc0 90000000030d0a88
         90000001002ab410 900000000298d401 0000000000000000 6f8c2a9cb5ab5f64
         90000000034f4000 90000000030d0a88 9000000003a48a58 90000001002ab410
         9000000104bd81a8 900000000298d484 9000000100020260 0000000000000000
         ...
 Call Trace:
 [<9000000002986290>] __clk_register+0x26c/0x84c
 [<9000000002986a68>] devm_clk_hw_register+0x5c/0xe0
 [<900000000298d3b8>] loongson2_clk_register.constprop.0+0xdc/0x10c
 [<900000000298d484>] loongson2_clk_probe+0x9c/0x4ac
 [<9000000002a4eba4>] platform_probe+0x68/0xc8
 [<9000000002a4bf80>] really_probe+0xbc/0x2f0
 [<9000000002a4c23c>] __driver_probe_device+0x88/0x128
 [<9000000002a4c318>] driver_probe_device+0x3c/0x11c
 [<9000000002a4c5dc>] __driver_attach+0x98/0x18c
 [<9000000002a49ca0>] bus_for_each_dev+0x80/0xe0
 [<9000000002a4b0dc>] bus_add_driver+0xfc/0x1ec
 [<9000000002a4d4a8>] driver_register+0x68/0x134
 [<90000000020f0110>] do_one_initcall+0x50/0x188
 [<9000000003150f00>] kernel_init_freeable+0x224/0x294
 [<90000000030240fc>] kernel_init+0x20/0x110
 [<90000000020f1568>] ret_from_kernel_thread+0xc/0xa4

Fixes: acc0ccffec ("clk: clk-loongson2: add clock controller driver support")
Cc: stable@vger.kernel.org
Cc: Yinbo Zhu <zhuyinbo@loongson.cn>
Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn>
Link: https://lore.kernel.org/r/20230524014924.2869051-1-zhoubinbin@loongson.cn
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2023-06-12 18:30:46 -07:00
Yinbo ZhuandStephen Boyd acc0ccffec clk: clk-loongson2: add clock controller driver support
This driver provides support for clock controller on Loongson-2 SoC,
the Loongson-2 SoC uses a 100MHz clock as the PLL reference clock,
there are five independent PLLs inside, each of which PLL can
provide up to three sets of frequency dependent clock outputs.

Signed-off-by: Yinbo Zhu <zhuyinbo@loongson.cn>
Link: https://lore.kernel.org/r/20230323025229.2971-2-zhuyinbo@loongson.cn
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2023-03-27 12:15:26 -07:00