Introduce fdt_apply_ddrss_timings_patch() to allow board code to
override DDR settings in the device tree prior to DDRSS driver probing.

Signed-off-by: Wadim Egorov <w.ego...@phytec.de>
Tested-by: John Ma <j...@phytec.com>
---
v2:
  - Make board/phytec/common/k3 always compile for CONFIG_ARCH_K3
---
 board/phytec/common/Makefile            |  4 +-
 board/phytec/common/k3/Makefile         |  1 +
 board/phytec/common/k3/k3_ddrss_patch.c | 68 +++++++++++++++++++++++++
 board/phytec/common/k3/k3_ddrss_patch.h | 28 ++++++++++
 board/phytec/phycore_am62x/MAINTAINERS  |  1 +
 5 files changed, 99 insertions(+), 3 deletions(-)
 create mode 100644 board/phytec/common/k3/k3_ddrss_patch.c
 create mode 100644 board/phytec/common/k3/k3_ddrss_patch.h

diff --git a/board/phytec/common/Makefile b/board/phytec/common/Makefile
index c34fc503059..988c5742db5 100644
--- a/board/phytec/common/Makefile
+++ b/board/phytec/common/Makefile
@@ -5,10 +5,8 @@
 ifdef CONFIG_SPL_BUILD
 # necessary to create built-in.o
 obj- := __dummy__.o
-else
-obj-$(CONFIG_ARCH_K3) += k3/
 endif
 
 obj-y += phytec_som_detection.o
-obj-$(CONFIG_ARCH_K3) += am6_som_detection.o
+obj-$(CONFIG_ARCH_K3) += am6_som_detection.o k3/
 obj-$(CONFIG_ARCH_IMX8M) += imx8m_som_detection.o
diff --git a/board/phytec/common/k3/Makefile b/board/phytec/common/k3/Makefile
index bcca1a9f846..40e91a43e99 100644
--- a/board/phytec/common/k3/Makefile
+++ b/board/phytec/common/k3/Makefile
@@ -1,2 +1,3 @@
 # SPDX-License-Identifier: GPL-2.0+
 obj-y += board.o
+obj-$(CONFIG_K3_DDRSS) += k3_ddrss_patch.o
diff --git a/board/phytec/common/k3/k3_ddrss_patch.c 
b/board/phytec/common/k3/k3_ddrss_patch.c
new file mode 100644
index 00000000000..39f7be8dc92
--- /dev/null
+++ b/board/phytec/common/k3/k3_ddrss_patch.c
@@ -0,0 +1,68 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2024 PHYTEC Messtechnik GmbH
+ * Author: Wadim Egorov <w.ego...@phytec.de>
+ */
+
+#include "k3_ddrss_patch.h"
+
+#include <fdt_support.h>
+#include <linux/errno.h>
+
+#ifdef CONFIG_K3_AM64_DDRSS
+#define LPDDR4_INTR_CTL_REG_COUNT (423U)
+#define LPDDR4_INTR_PHY_INDEP_REG_COUNT (345U)
+#endif
+
+static int fdt_setprop_inplace_idx_u32(void *fdt, int nodeoffset,
+                                      const char *name, uint32_t idx, u32 val)
+{
+       val = cpu_to_be32(val);
+       return fdt_setprop_inplace_namelen_partial(fdt, nodeoffset, name,
+                                                  strlen(name),
+                                                  idx * sizeof(val), &val,
+                                                  sizeof(val));
+}
+
+int fdt_apply_ddrss_timings_patch(void *fdt, struct ddrss *ddrss)
+{
+       int i, j;
+       int ret;
+       int mem_offset;
+
+       mem_offset = fdt_path_offset(fdt, "/memorycontroller@f300000");
+       if (mem_offset < 0)
+               return -ENODEV;
+
+       for (i = 0; i < LPDDR4_INTR_CTL_REG_COUNT; i++)
+               for (j = 0; j < ddrss->ctl_regs_num; j++)
+                       if (i == ddrss->ctl_regs[j].off) {
+                               ret = fdt_setprop_inplace_idx_u32(fdt,
+                                               mem_offset, "ti,ctl-data", i,
+                                               ddrss->ctl_regs[j].val);
+                               if (ret)
+                                       return ret;
+                       }
+
+       for (i = 0; i < LPDDR4_INTR_PHY_INDEP_REG_COUNT; i++)
+               for (j = 0; j < ddrss->pi_regs_num; j++)
+                       if (i == ddrss->pi_regs[j].off) {
+                               ret = fdt_setprop_inplace_idx_u32(fdt,
+                                               mem_offset, "ti,pi-data", i,
+                                               ddrss->pi_regs[j].val);
+                               if (ret)
+                                       return ret;
+                       }
+
+       for (i = 0; i < LPDDR4_INTR_PHY_INDEP_REG_COUNT; i++)
+               for (j = 0; j < ddrss->phy_regs_num; j++)
+                       if (i == ddrss->phy_regs[j].off) {
+                               ret = fdt_setprop_inplace_idx_u32(fdt,
+                                               mem_offset, "ti,phy-data", i,
+                                               ddrss->phy_regs[j].val);
+                               if (ret)
+                                       return ret;
+                       }
+
+       return 0;
+}
diff --git a/board/phytec/common/k3/k3_ddrss_patch.h 
b/board/phytec/common/k3/k3_ddrss_patch.h
new file mode 100644
index 00000000000..0a47c85116a
--- /dev/null
+++ b/board/phytec/common/k3/k3_ddrss_patch.h
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2024 PHYTEC Messtechnik GmbH
+ * Author: Wadim Egorov <w.ego...@phytec.de>
+ */
+
+#ifndef K3_DDRSS_PATCH
+#define K3_DDRSS_PATCH
+
+#include <linux/types.h>
+
+struct ddr_reg {
+       u32 off;
+       u32 val;
+};
+
+struct ddrss {
+       struct ddr_reg *ctl_regs;
+       u32 ctl_regs_num;
+       struct ddr_reg *pi_regs;
+       u32 pi_regs_num;
+       struct ddr_reg *phy_regs;
+       u32 phy_regs_num;
+};
+
+int fdt_apply_ddrss_timings_patch(void *fdt, struct ddrss *ddrss);
+
+#endif /* K3_DDRSS_PATCH */
diff --git a/board/phytec/phycore_am62x/MAINTAINERS 
b/board/phytec/phycore_am62x/MAINTAINERS
index 02ac88e58a4..42463ad054e 100644
--- a/board/phytec/phycore_am62x/MAINTAINERS
+++ b/board/phytec/phycore_am62x/MAINTAINERS
@@ -11,3 +11,4 @@ F:    configs/phycore_am62x_a53_defconfig
 F:     configs/phycore_am62x_r5_defconfig
 F:     include/configs/phycore_am62x.h
 F:     doc/board/phytec/phycore-am62x.rst
+F:     board/phytec/common/k3
-- 
2.34.1

Reply via email to