blob: e40ac360e860eeae24a5110b3a47e89992586917 [file] [log] [blame]
Lukasz Majewski9e1ac3d2019-06-24 15:50:35 +02001Introduction:
2=============
3
Sean Andersoncfc2f022020-06-24 06:41:06 -04004This documentation entry describes the Common Clock Framework [CCF] port from
5Linux kernel (v5.1.12) to U-Boot.
Lukasz Majewski9e1ac3d2019-06-24 15:50:35 +02006
Sean Andersoncfc2f022020-06-24 06:41:06 -04007This code is supposed to bring CCF to IMX based devices (imx6q, imx7 imx8).
8Moreover, it also provides some common clock code, which would allow easy
9porting of CCF Linux code to other platforms.
Lukasz Majewski9e1ac3d2019-06-24 15:50:35 +020010
11Design decisions:
12=================
13
Sean Andersoncfc2f022020-06-24 06:41:06 -040014* U-Boot's driver model [DM] for clk differs from Linux CCF. The most notably
15 difference is the lack of support for hierarchical clocks and "clock as a
16 manager driver" (single clock DTS node acts as a starting point for all other
17 clocks).
Lukasz Majewski9e1ac3d2019-06-24 15:50:35 +020018
Sean Andersoncfc2f022020-06-24 06:41:06 -040019* The clk_get_rate() caches the previously read data if CLK_GET_RATE_NOCACHE is
20 not set (no need for recursive access).
Lukasz Majewski9e1ac3d2019-06-24 15:50:35 +020021
Sean Andersoncfc2f022020-06-24 06:41:06 -040022* On purpose the "manager" clk driver (clk-imx6q.c) is not using large table to
23 store pointers to clocks - e.g. clk[IMX6QDL_CLK_USDHC2_SEL] = .... Instead we
24 use udevice's linked list for the same class (UCLASS_CLK).
Lukasz Majewski9e1ac3d2019-06-24 15:50:35 +020025
26 Rationale:
27 ----------
Sean Andersoncfc2f022020-06-24 06:41:06 -040028 When porting the code as is from Linux, one would need ~1KiB of RAM to store
29 it. This is way too much if we do plan to use this driver in SPL.
Lukasz Majewski9e1ac3d2019-06-24 15:50:35 +020030
31* The "central" structure of this patch series is struct udevice and its
32 uclass_priv field contains the struct clk pointer (to the originally created
33 one).
34
Lukasz Majewski9e1ac3d2019-06-24 15:50:35 +020035* To keep things simple the struct udevice's uclass_priv pointer is used to
36 store back pointer to corresponding struct clk. However, it is possible to
37 modify clk-uclass.c file and add there struct uc_clk_priv, which would have
38 clock related members (like pointer to clk). As of this writing there is no
39 such need, so to avoid extra allocations (as it can be auto allocated by
40 setting .per_device_auto_alloc_size = sizeof(struct uc_clk_priv)) the
41 uclass_priv stores the pointer to struct clk.
42
Sean Andersoncfc2f022020-06-24 06:41:06 -040043* Non-CCF clocks do not have a pointer to a clock in clk->dev->priv. In the case
44 of composite clocks, clk->dev->priv may not match clk. Drivers should always
45 use the struct clk which is passed to them, and not clk->dev->priv.
46
Lukasz Majewski9e1ac3d2019-06-24 15:50:35 +020047* It is advised to add common clock code (like already added rate and flags) to
48 the struct clk, which is a top level description of the clock.
49
50* U-Boot's driver model already provides the facility to automatically allocate
Sean Andersoncfc2f022020-06-24 06:41:06 -040051 (via private_alloc_size) device private data (accessible via dev->priv). It
52 may look appealing to use this feature to allocate private structures for CCF
53 clk devices e.g. divider (struct clk_divider *divider) for IMX6Q clock.
Lukasz Majewski9e1ac3d2019-06-24 15:50:35 +020054
55 The above feature had not been used for following reasons:
56 - The original CCF Linux kernel driver is the "manager" for clocks - it
57 decides when clock is instantiated (and when memory for it is allocated).
58
59 - Using it would change the original structure of the CCF code.
60
61 - To bind (via clk_register()) the clock device with U-Boot driver model we
62 first need udevice for it (the "chicken and egg problem").
63
64* I've added the clk_get_parent(), which reads parent's dev->uclass_priv to
65 provide parent's struct clk pointer. This seems the easiest way to get
Sean Andersoncfc2f022020-06-24 06:41:06 -040066 child/parent relationship for struct clk in U-Boot's udevice based clocks. In
67 the future arbitrary parents may be supported by adding a get_parent function
68 to clk_ops.
Lukasz Majewski9e1ac3d2019-06-24 15:50:35 +020069
70* Linux's CCF 'struct clk_core' corresponds to U-Boot's udevice in 'struct clk'.
71 Clock IP block agnostic flags from 'struct clk_core' (e.g. NOCACHE) have been
Sean Andersoncfc2f022020-06-24 06:41:06 -040072 moved from this struct one level up to 'struct clk'. Many flags are
73 unimplemented at the moment.
Lukasz Majewski9e1ac3d2019-06-24 15:50:35 +020074
75* For tests the new ./test/dm/clk_ccf.c and ./drivers/clk/clk_sandbox_ccf.c
76 files have been introduced. The latter setups the CCF clock structure for
Sean Andersoncfc2f022020-06-24 06:41:06 -040077 sandbox by reusing, if possible, generic clock primitives - like divier and
78 mux. The former file provides code to tests this setup.
Lukasz Majewski9e1ac3d2019-06-24 15:50:35 +020079
80 For sandbox new CONFIG_SANDBOX_CLK_CCF Kconfig define has been introduced.
Sean Andersoncfc2f022020-06-24 06:41:06 -040081 All new primitives added for new architectures must have corresponding test in
82 the two aforementioned files.
Lukasz Majewski9e1ac3d2019-06-24 15:50:35 +020083
84Testing (sandbox):
85==================
86
87make mrproper; make sandbox_defconfig; make -j4
88./u-boot -i -d arch/sandbox/dts/test.dtb
89=> ut dm clk
90
91or in a more "scriptable" way (with -v to print debug output):
92./u-boot --fdt arch/sandbox/dts/test.dtb --command "ut dm clk_ccf" -v
93
94To do:
95------
96
97* Use of OF_PLATDATA in the SPL setup for CCF - as it is now - the SPL grows
98 considerably and using CCF in boards with tiny resources (OCRAM) is
99 problematic.
100
101* On demand port other parts of CCF to U-Boot - as now only features _really_
102 needed by DM/DTS converted drivers are used.