--- /dev/null
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2024 PHYTEC Messtechnik GmbH
+ * Author: Wadim Egorov <w.egorov@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;
+}
--- /dev/null
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2024 PHYTEC Messtechnik GmbH
+ * Author: Wadim Egorov <w.egorov@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 */