This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TDA4VM: Activate Clocks/Devices in Linux Kernel

Part Number: TDA4VM

Posting on behalf of

Where is the place to activate Clocks/Devices in Linux Kernel? I think this is most probably done in the Device Tree files. PCIE1 Module for instance has the following entry in arch/arm64/boot/dts/ti/k3-j721e-main.dtsi:

pcie1_rc: pcie@2910000 {
		compatible = "ti,j721e-pcie-host";
		reg = <0x00 0x02910000 0x00 0x1000>,
		      <0x00 0x02917000 0x00 0x400>,
		      <0x00 0x0d800000 0x00 0x00800000>,
		      <0x00 0x18000000 0x00 0x00001000>;
		reg-names = "intd_cfg", "user_cfg", "reg", "cfg";
		ti,syscon-pcie-ctrl = <&pcie1_ctrl>;
		max-link-speed = <3>;
		num-lanes = <2>;
		power-domains = <&k3_pds 240 TI_SCI_PD_EXCLUSIVE>;
		clocks = <&k3_clks 240 1>;
		clock-names = "fck";
		#address-cells = <3>;
		#size-cells = <2>;
		bus-range = <0x0 0xf>;
		cdns,max-outbound-regions = <16>;
		cdns,no-bar-match-nbits = <64>;
		vendor-id = /bits/ 16 <0x104c>;
		device-id = /bits/ 16 <0xb00d>;
		msi-map = <0x0 &gic_its 0x10000 0x10000>;
		dma-coherent;
		ranges = <0x01000000 0x0 0x18001000  0x00 0x18001000  0x0 0x0010000>,
			 <0x02000000 0x0 0x18011000  0x00 0x18011000  0x0 0x7fef000>;
		#interrupt-cells = <1>;
		interrupt-map-mask = <0 0 0 7>;
		interrupt-map = <0 0 0 1 &pcie1_intc 0>, /* INT A */
				<0 0 0 2 &pcie1_intc 0>, /* INT B */
				<0 0 0 3 &pcie1_intc 0>, /* INT C */
				<0 0 0 4 &pcie1_intc 0>; /* INT D */

		pcie1_intc: legacy-interrupt-controller {
			interrupt-controller;
			#interrupt-cells = <2>;
			interrupt-parent = <&gic500>;
			interrupts = <GIC_SPI 324 IRQ_TYPE_EDGE_RISING>;
		};
	};

the field "clocks" would match with the already mentioned device list (https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/j721e/devices.html), because of the Device ID 240. If this is the correct place to activate Modules in Linux, then there is still a missing link to how Linux knows the correct frequency to power up this module? Can you point me to the right direction where this is done?

For context: J721E_DEV_PCIE1 for instance is neither activated in R5 SPL, nor in U-Boot. I verified this by using an Baremetal application for MCU2_0, which consumes J721E_DEV_PCIE1. This application throws errors, when executed after U-Boot boot (The corresponding option to activate the Clocks is not passed to theBoard_init() function). After Linux has booted, J721E_DEV_PCIE1 is enabled and this previous mentioned application works as expected.

Thanks again and best regards

  • Hi Felix,

    For context: J721E_DEV_PCIE1 for instance is neither activated in R5 SPL, nor in U-Boot. I verified this by using an Baremetal application for MCU2_0, which consumes J721E_DEV_PCIE1. This application throws errors, when executed after U-Boot boot (The corresponding option to activate the Clocks is not passed to theBoard_init() function). After Linux has booted, J721E_DEV_PCIE1 is enabled and this previous mentioned application works as expected.

    That is a good way to test that PCIE is not enabled by R5 SPL and A72 SPL and u-boot. But there is a simpler method where you could just halt at u-boot w/o any baremetal app. When halted at u-boot just try to dump some PCIE registers from u-boot using "md" command.

    Where is the place to activate Clocks/Devices in Linux Kernel? I think this is most probably done in the Device Tree files. PCIE1 Module for instance has the following entry in arch/arm64/boot/dts/ti/k3-j721e-main.dtsi:
    the field "clocks" would match with the already mentioned device list (https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/j721e/devices.html), because of the Device ID 240. If this is the correct place to activate Modules in Linux, then there is still a missing link to how Linux knows the correct frequency to power up this module? Can you point me to the right direction where this is done?

    For Linux to power on a module, you need to have a node with status="okay" and a clocks field to it. This will then be picked up by the clock driver and the module will be powered on.

    Now what you mention here with pcie1_rc is clocks = <&k3_clks 240 1> meaning that you are selecting Clock ID = 1 for device ID = 240. See https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/j721e/clocks.html#clocks-for-pcie1-device for the exact clock (DEV_PCIE1_PCIE_CBA_CLK) being enabled by this.

    If this is the correct place to activate Modules in Linux, then there is still a missing link to how Linux knows the correct frequency to power up this module?

    Can you help me understand what is the missing link here? Do you want to know how Linux will know how what freq to configure the DEV_PCIE1_PCIE_CBA_CLK to?

    Regards,

    Karan

  • Hi Karan,

    When halted at u-boot just try to dump some PCIE registers from u-boot using "md" command.

    Thanks for the hint. That is indeed very convenient.

    For Linux to power on a module, you need to have a node with status="okay" and a clocks field to it. This will then be picked up by the clock driver and the module will be powered on.

    Ok that makes sense. I assume the clock driver for TDA4VM is linux/drivers/clk/keystone/sci-clk.c?

    Now what you mention here with pcie1_rc is clocks = <&k3_clks 240 1> meaning that you are selecting Clock ID = 1 for device ID = 240. See https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/j721e/clocks.html#clocks-for-pcie1-device for the exact clock (DEV_PCIE1_PCIE_CBA_CLK) being enabled by this.

    Thank you for conforming this. But I am still a little bit sceptical, since J721E_DEV_PCIE1 has got 31 possible clocks. Can you please confirm, that it is really sufficient to enable only Clock ID 1  (DEV_PCIE1_PCIE_CBA_CLK) to activate J721E_DEV_PCIE1 and all other clocks are optional?

    Do you want to know how Linux will know how what freq to configure the DEV_PCIE1_PCIE_CBA_CLK to?

    Yes that would be really helpful.

    Thanks again for you help. Your answers made things a lot clearer now.

    Best regards,

    Felix

  • Hi Felix,

    Thank you for conforming this. But I am still a little bit sceptical, since J721E_DEV_PCIE1 has got 31 possible clocks. Can you please confirm, that it is really sufficient to enable only Clock ID 1  (DEV_PCIE1_PCIE_CBA_CLK) to activate J721E_DEV_PCIE1 and all other clocks are optional?

    Let me check on this and get back to you.

    Regards,

    Karan

  • Hi Karan,

    using k3conf, I found out, that Clock ID 1 can not be the one clock, which is active for J721E_DEV_PCIE1.

    root@j7-evm:~# k3conf dump clock 240
    |--------------------------------------------------------------------------------|
    | VERSION INFO                                                                   |
    |--------------------------------------------------------------------------------|
    | K3CONF | (version v0.1-34-g1ff0c4f built Mon Jan 25 03:49:57 UTC 2021)         |
    | SoC    | J721E SR1.0                                                           |
    | SYSFW  | ABI: 3.1 (firmware version 0x0014 '20.8.5--v2020.08b (Terrific Lla)') |
    |--------------------------------------------------------------------------------|
    
    |------------------------------------------------------------------------------------------------------------------------------------------|
    | Device ID | Clock ID | Clock Name                                                                    | Status          | Clock Frequency |
    |------------------------------------------------------------------------------------------------------------------------------------------|
    |   240     |     0    | DEV_PCIE1_PCIE_LANE1_TXMCLK                                                   | CLK_STATE_READY | 0               |
    |   240     |     1    | DEV_PCIE1_PCIE_CBA_CLK                                                        | CLK_STATE_READY | 250000000       |
    |   240     |     2    | DEV_PCIE1_PCIE_LANE1_RXCLK                                                    | CLK_STATE_READY | 0               |
    |   240     |     3    | DEV_PCIE1_PCIE_CPTS_RCLK_CLK                                                  | CLK_STATE_READY | 200000000       |
    |   240     |     4    | DEV_PCIE1_PCIE_CPTS_RCLK_CLK_PARENT_HSDIV4_16FFT_MAIN_3_HSDIVOUT1_CLK         | CLK_STATE_READY | 200000000       |
    |   240     |     5    | DEV_PCIE1_PCIE_CPTS_RCLK_CLK_PARENT_POSTDIV3_16FFT_MAIN_0_HSDIVOUT6_CLK       | CLK_STATE_READY | 250000000       |
    |   240     |     6    | DEV_PCIE1_PCIE_CPTS_RCLK_CLK_PARENT_BOARD_0_MCU_CPTS0_RFT_CLK_OUT             | CLK_STATE_READY | 0               |
    |   240     |     7    | DEV_PCIE1_PCIE_CPTS_RCLK_CLK_PARENT_BOARD_0_CPTS0_RFT_CLK_OUT                 | CLK_STATE_READY | 0               |
    |   240     |     8    | DEV_PCIE1_PCIE_CPTS_RCLK_CLK_PARENT_BOARD_0_MCU_EXT_REFCLK0_OUT               | CLK_STATE_READY | 0               |
    |   240     |     9    | DEV_PCIE1_PCIE_CPTS_RCLK_CLK_PARENT_BOARD_0_EXT_REFCLK1_OUT                   | CLK_STATE_READY | 0               |
    |   240     |    10    | DEV_PCIE1_PCIE_CPTS_RCLK_CLK_PARENT_WIZ16B4M4CS_MAIN_0_IP2_LN0_TXMCLK         | CLK_STATE_READY | 0               |
    |   240     |    11    | DEV_PCIE1_PCIE_CPTS_RCLK_CLK_PARENT_WIZ16B4M4CS_MAIN_0_IP2_LN1_TXMCLK         | CLK_STATE_READY | 0               |
    |   240     |    12    | DEV_PCIE1_PCIE_CPTS_RCLK_CLK_PARENT_WIZ16B4M4CS_MAIN_1_IP2_LN0_TXMCLK         | CLK_STATE_READY | 0               |
    |   240     |    13    | DEV_PCIE1_PCIE_CPTS_RCLK_CLK_PARENT_WIZ16B4M4CS_MAIN_1_IP2_LN1_TXMCLK         | CLK_STATE_READY | 0               |
    |   240     |    14    | DEV_PCIE1_PCIE_CPTS_RCLK_CLK_PARENT_WIZ16B4M4CS_MAIN_2_IP2_LN0_TXMCLK         | CLK_STATE_READY | 0               |
    |   240     |    15    | DEV_PCIE1_PCIE_CPTS_RCLK_CLK_PARENT_WIZ16B4M4CS_MAIN_2_IP2_LN1_TXMCLK         | CLK_STATE_READY | 0               |
    |   240     |    16    | DEV_PCIE1_PCIE_CPTS_RCLK_CLK_PARENT_WIZ16B4M4CS_MAIN_2_IP2_LN0_TXMCLK_DUP0    | CLK_STATE_READY | 0               |
    |   240     |    17    | DEV_PCIE1_PCIE_CPTS_RCLK_CLK_PARENT_WIZ16B4M4CS_MAIN_2_IP2_LN1_TXMCLK_DUP0    | CLK_STATE_READY | 0               |
    |   240     |    18    | DEV_PCIE1_PCIE_CPTS_RCLK_CLK_PARENT_HSDIV4_16FFT_MCU_2_HSDIVOUT1_CLK          | CLK_STATE_READY | 500000000       |
    |   240     |    19    | DEV_PCIE1_PCIE_CPTS_RCLK_CLK_PARENT_K3_PLL_CTRL_WRAP_MAIN_0_CHIP_DIV1_CLK_CLK | CLK_STATE_READY | 500000000       |
    |   240     |    20    | DEV_PCIE1_PCIE_LANE1_TXFCLK                                                   | CLK_STATE_READY | 0               |
    |   240     |    21    | DEV_PCIE1_PCIE_LANE1_REFCLK                                                   | CLK_STATE_READY | 0               |
    |   240     |    22    | DEV_PCIE1_PCIE_LANE0_REFCLK                                                   | CLK_STATE_READY | 0               |
    |   240     |    23    | DEV_PCIE1_PCIE_LANE0_TXMCLK                                                   | CLK_STATE_READY | 0               |
    |   240     |    24    | DEV_PCIE1_PCIE_LANE0_TXFCLK                                                   | CLK_STATE_READY | 0               |
    |   240     |    25    | DEV_PCIE1_PCIE_PM_CLK                                                         | CLK_STATE_READY | 12500000        |
    |   240     |    26    | DEV_PCIE1_PCIE_LANE0_RXFCLK                                                   | CLK_STATE_READY | 0               |
    |   240     |    27    | DEV_PCIE1_PCIE_LANE1_RXFCLK                                                   | CLK_STATE_READY | 0               |
    |   240     |    28    | DEV_PCIE1_PCIE_LANE0_RXCLK                                                    | CLK_STATE_READY | 0               |
    |   240     |    29    | DEV_PCIE1_PCIE_LANE1_TXCLK                                                    | CLK_STATE_READY | 0               |
    |   240     |    30    | DEV_PCIE1_PCIE_LANE0_TXCLK                                                    | CLK_STATE_READY | 0               |
    |------------------------------------------------------------------------------------------------------------------------------------------|
    

    So is there maybe a dependency on Clock ID 1, through which the other mandatory clocks are also enabled?

    Also, I am a little bit confused about the concept of activating clocks in general:

    R5 SPL has the already mentioned list in clk-data.c (https://e2e.ti.com/support/processors-group/processors/f/processors-forum/993957/tda4vm-about-dmsc-rom-code-and-r5-rom-code) but also has a device tree. So which one of these is actually used for activating clocks? (The use case is, that I want to add an additional peripheral to R5 SPL and i am not sure which files I have to modify)

    Can this approach also be applied to activating clocks in linux? (So is there also such a list file like for R5 SPL?)

    Thanks again and best regards,

    Felix

  • Hi Felix,

    I have assigned this to our PCIE expert for PCIE specific questions.

    On the other questions:

    Also, I am a little bit confused about the concept of activating clocks in general:

    R5 SPL has the already mentioned list in clk-data.c (https://e2e.ti.com/support/processors-group/processors/f/processors-forum/993957/tda4vm-about-dmsc-rom-code-and-r5-rom-code) but also has a device tree. So which one of these is actually used for activating clocks? (The use case is, that I want to add an additional peripheral to R5 SPL and i am not sure which files I have to modify)

    Can this approach also be applied to activating clocks in linux? (So is there also such a list file like for R5 SPL?)

    From the device tree when you mention the relevant clocks for a peripheral then those are touched only when the driver probe happens. The data in the arch/arm/mach-k3/clk_data.c too goes to the device tree for R5 SPL.

    The clk_data.c defines the j721e_clk_platdata, now this is consumed in drivers/clk/clk-k3.c. This driver has the compatible ti,k2g-sci-clk which is then used in k3-j721e-mcu-wakeup.dtsi in the node k3_clks which then gets referenced in k3-j721e-r5-common-proc-board.dts in the node a72_0..

    The k3-j721e-r5-common-proc-board.dts is the device tree for R5 SPL.

    Hope this clarifies some confusion.

    Regards,

    Karan

  • Hi Karan,

    I have assigned this to our PCIE expert for PCIE specific questions.

    great, thank you.

    The clk_data.c defines the j721e_clk_platdata, now this is consumed in drivers/clk/clk-k3.c. This driver has the compatible ti,k2g-sci-clk which is then used in k3-j721e-mcu-wakeup.dtsi in the node k3_clks which then gets referenced in k3-j721e-r5-common-proc-board.dts in the node a72_0..

    Ok so to sum it up:

    the modules/clocks defined in j721e_clk_platdata are always activated, regardless of the nodes in the device tree. At least ti_clk_probe in clk-k3.c seems to iterate through the entire clk_list_cnt.

    There is a second mechanism to activate additional clocks using the clocks= <k3_clks DEV_ID CLOCK_ID>; field in the device tree. Here I can activate the suitable clocks for my desired module.

    To come back to the original question:

    In Linux, a similar mechanism to activate clocks applies. Here the k3_clocks node also has got the compatible field ti,k2g-sci-clk. This is consumed in the clock driver linux/drivers/clk/keystone/sci-clk.c. This driver does not have such a list as we have seen in the U-Boot code. So it does not activate clocks regardless of the Device Tree. But the same mechanism of using clocks= <k3_clks DEV_ID CLOCK_ID>; also applies here. So if I want to activate a module in the device tree, I can add the corresponding DEV_ID and CLOCK_ID to the clocks field.

    Can you please confirm if these assumptions are correct?

    Thanks again and best regards,

    Felix

  • Hi Felix,

    Generally if you have to enable any clock for any peripheral, you should add a device tree node for that and then enable it. In bot u-boot or Linux this can happen in the Device Tree.

    The initial set of clocks enabled by R5 SPL are generally not touched.

    Regards,

    Karan

  • Felix, 

    I think the missing link may be the system firmware (sysfw), there drivers call sysfw with the corresponding clock ID in the messages when calling sciclient APIs, which subsequently calls sysfw APIs to configure clocks, resolve dependencies, and setup the full clock path. You may refer to:

    https://software-dl.ti.com/tisci/esd/21_01_00/1_intro/TISCI.html#centralized-device-management

    for functional descriptions, then use the API reference for exact clock IDs. 

    please let us know if this helps to clarify the last maze you and Karan was discussing. 

    Jian 

  • Hi Jian,

    ok, so ti_sci_clk_probe from linux-kernel/drivers/clk/keystone/sci-clk.c takes care of resolving clock dependencies. Thanks for your help.

    Best regards,

    Felix