]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - rpmsg/rpmsg.git/commitdiff
soc: ti: pruss: Configure different internal ICSSG source clocks
authorSuman Anna <s-anna@ti.com>
Thu, 21 Feb 2019 02:47:05 +0000 (20:47 -0600)
committerSuman Anna <s-anna@ti.com>
Mon, 25 Feb 2019 19:31:39 +0000 (13:31 -0600)
The ICSSG processor subsystems has multiple functional and interface
clock inputs like CORE_CLK, IEP_CLK, UART_CLK, ICLK etc that are sourced
from different PLLs and run at different frequences. Some of these
input clocks are configurable through external muxes, while further
muxing can be achieved on the actual internal ICSSG Core and IEP clocks
used by the ICSSG sub-modules through registers in the CFG space to
choose between the different IP-level input clocks.

The default functional source clock for IEP module within ICSSG
instances on K3 AM65x SoCs is CPSWHWDIV_CLKOUT2, which runs at a
frequency of 200 MHz. The default CORE_CLK is derived from
PER1HSDIV_CLKOUT1 and runs at a frequency of 225 MHz. The ICLK
is derived from the SYSCLK0 and runs at a frequency of 250 MHz.

Configure the internal clock muxes so that both the internal ICSSG
Core Clock and the IEP functional clock are sourced from the ICLK
(VBUSP Clock) clock input so that they run at identical speeds and
at the highest frequency of 250 MHz. This one-time configuration is
performed during the probe (resetting would require a hardware reset
of the ICSSG). This is required to get the lowest latency and achieve
high speed for various ICSSG functionalities (eg: mandatory for
achieving 1G speeds on the ICSSG Ethernet ports).

Signed-off-by: Suman Anna <s-anna@ti.com>

index 770863040e2150abe3499ced4be75ac003fff659..31788db6424e13dcaa9903d14a7706979ace5e05 100644 (file)
@@ -231,6 +231,30 @@ int pruss_regmap_update(struct pruss *pruss, enum pruss_syscon mod,
+/* Custom configuration of couple of PRUSS clocks only on AM65x SoCs */
+static int pruss_configure_clocks(struct platform_device *pdev,
+                                 struct pruss *pruss)
+       int ret;
+       if (!of_device_is_compatible(pdev->dev.of_node, "ti,am654-icssg"))
+               return 0;
+       ret = pruss_regmap_update(pruss, PRUSS_SYSCON_CFG, ICSSG_CFG_CORE_SYNC,
+                                 ICSSG_CORE_VBUSP_SYNC_EN,
+                                 ICSSG_CORE_VBUSP_SYNC_EN);
+       if (ret)
+               return ret;
+       ret = pruss_regmap_update(pruss, PRUSS_SYSCON_CFG, PRUSS_CFG_IEPCLK,
+                                 PRUSS_IEPCLK_IEP_OCP_CLK_EN,
+                                 PRUSS_IEPCLK_IEP_OCP_CLK_EN);
+       if (ret)
+               return ret;
+       return 0;
 static const
 struct pruss_private_data *pruss_get_private_data(struct platform_device *pdev)
@@ -357,6 +381,12 @@ static int pruss_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, pruss);
+       ret = pruss_configure_clocks(pdev, pruss);
+       if (ret) {
+               dev_err(dev, "clock frequency config failed, ret = %d\n", ret);
+               return ret;
+       }
        dev_dbg(&pdev->dev, "creating PRU cores and other child platform devices\n");
        ret = of_platform_populate(node, NULL, NULL, &pdev->dev);
        if (ret)
index a50eeceb7a7b43fdaac9c8845cf7a1a4a5cf052a..6cfe5c673c4a3a04a0b0bdb178f4c88e8fdf93d7 100644 (file)
@@ -29,6 +29,8 @@
 #define PRUSS_CFG_SPP          0x34
 #define PRUSS_CFG_PIN_MX       0x40
+#define ICSSG_CFG_CORE_SYNC    0x3c
 /* PRUSS_GPCFG register bits */
 #define PRUSS_GPCFG_PRU_GPO_SH_SEL             BIT(25)
 #define PRUSS_SPP_XFER_SHIFT_EN                        BIT(1)
 #define PRUSS_SPP_PRU1_PAD_HP_EN               BIT(0)
+/* PRUSS_IEPCLK register bits */
+#define PRUSS_IEPCLK_IEP_OCP_CLK_EN            BIT(0)
+/* ICSSG CORE_SYNC register bits */
+#define ICSSG_CORE_VBUSP_SYNC_EN               BIT(0)
  * enum pruss_gp_mux_sel - PRUSS GPI/O Mux modes for the
  * PRUSS_GPCFG0/1 registers