[U-Boot] [PATCH v5 01/18] clk: doc: Add documentation entry for Common Clock Framework [CCF] (i.MX)

Lukasz Majewski lukma at denx.de
Mon Jun 24 13:50:35 UTC 2019

This patch describes the design decisions considerations and taken approach
for porting in a separate documentation entry.

Signed-off-by: Lukasz Majewski <lukma at denx.de>


Changes in v6: None
Changes in v5:
- s/U-boot/U-Boot/g
- Update Linux version to 5.1.12
- Add paragraph regarding sandbox CCF testing (common uclass code)

Changes in v4:
- New patch

Changes in v3: None

 doc/imx/clk/ccf.txt | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 101 insertions(+)
 create mode 100644 doc/imx/clk/ccf.txt

diff --git a/doc/imx/clk/ccf.txt b/doc/imx/clk/ccf.txt
new file mode 100644
index 0000000000..36b60dc438
--- /dev/null
+++ b/doc/imx/clk/ccf.txt
@@ -0,0 +1,101 @@
+This documentation entry describes the Common Clock Framework [CCF]
+port from Linux kernel (v5.1.12) to U-Boot.
+This code is supposed to bring CCF to IMX based devices (imx6q, imx7
+imx8). Moreover, it also provides some common clock code, which would
+allow easy porting of CCF Linux code to other platforms.
+Design decisions:
+* U-Boot's driver model [DM] for clk differs from Linux CCF. The most
+  notably difference is the lack of support for hierarchical clocks and
+  "clock as a manager driver" (single clock DTS node acts as a starting
+  point for all other clocks).
+* The clk_get_rate() caches the previously read data if CLK_GET_RATE_NOCACHE
+  is not set (no need for recursive access).
+* On purpose the "manager" clk driver (clk-imx6q.c) is not using large
+  table to store pointers to clocks - e.g. clk[IMX6QDL_CLK_USDHC2_SEL] = ....
+  Instead we use udevice's linked list for the same class (UCLASS_CLK).
+  Rationale:
+  ----------
+    When porting the code as is from Linux, one would need ~1KiB of RAM to
+    store it. This is way too much if we do plan to use this driver in SPL.
+* The "central" structure of this patch series is struct udevice and its
+  uclass_priv field contains the struct clk pointer (to the originally created
+  one).
+* Up till now U-Boot's driver model (DM) CLK operates on udevice (main
+  access to clock is by udevice ops)
+  In the CCF the access to struct clk (embodying pointer to *dev) is
+  possible via dev_get_clk_ptr() (it is a wrapper on dev_get_uclass_priv()).
+* To keep things simple the struct udevice's uclass_priv pointer is used to
+  store back pointer to corresponding struct clk. However, it is possible to
+  modify clk-uclass.c file and add there struct uc_clk_priv, which would have
+  clock related members (like pointer to clk). As of this writing there is no
+  such need, so to avoid extra allocations (as it can be auto allocated by
+  setting .per_device_auto_alloc_size = sizeof(struct uc_clk_priv)) the
+  uclass_priv stores the pointer to struct clk.
+* It is advised to add common clock code (like already added rate and flags) to
+  the struct clk, which is a top level description of the clock.
+* U-Boot's driver model already provides the facility to automatically allocate
+  (via private_alloc_size) device private data (accessible via dev->priv).
+  It may look appealing to use this feature to allocate private structures for
+  CCF clk devices e.g. divider (struct clk_divider *divider) for IMX6Q clock.
+  The above feature had not been used for following reasons:
+  - The original CCF Linux kernel driver is the "manager" for clocks - it
+    decides when clock is instantiated (and when memory for it is allocated).
+  - Using it would change the original structure of the CCF code.
+  - To bind (via clk_register()) the clock device with U-Boot driver model we
+    first need udevice for it (the "chicken and egg problem").
+* I've added the clk_get_parent(), which reads parent's dev->uclass_priv to
+  provide parent's struct clk pointer. This seems the easiest way to get
+  child/parent relationship for struct clk in U-Boot's udevice based clocks.
+* Linux's CCF 'struct clk_core' corresponds to U-Boot's udevice in 'struct clk'.
+  Clock IP block agnostic flags from 'struct clk_core' (e.g. NOCACHE) have been
+  moved from this struct one level up to 'struct clk'.
+* For tests the new ./test/dm/clk_ccf.c and ./drivers/clk/clk_sandbox_ccf.c
+  files have been introduced. The latter setups the CCF clock structure for
+  sandbox by reusing, if possible, generic clock primitives - like divier
+  and mux. The former file provides code to tests this setup.
+  For sandbox new CONFIG_SANDBOX_CLK_CCF Kconfig define has been introduced.
+  All new primitives added for new architectures must have corresponding test
+  in the two aforementioned files.
+Testing (sandbox):
+make mrproper; make sandbox_defconfig; make -j4
+./u-boot -i -d arch/sandbox/dts/test.dtb
+=> ut dm clk
+or in a more "scriptable" way (with -v to print debug output):
+./u-boot --fdt arch/sandbox/dts/test.dtb --command "ut dm clk_ccf" -v
+To do:
+* Use of OF_PLATDATA in the SPL setup for CCF - as it is now - the SPL grows
+  considerably and using CCF in boards with tiny resources (OCRAM) is
+  problematic.
+* On demand port other parts of CCF to U-Boot - as now only features _really_
+  needed by DM/DTS converted drivers are used.

More information about the U-Boot mailing list