From a69a902ce02ec29dd14c034e3fcdf1bc06b5aa86 Mon Sep 17 00:00:00 2001
From: James Doublesin <doublesin@ti.com>
Date: Wed, 26 Jun 2024 16:18:05 -0500
Subject: [PATCH] regdump patch files

---
 drivers/ram/k3-ddrss/Makefile         |   1 +
 drivers/ram/k3-ddrss/k3-ddr_regdump.c | 238 ++++++++++++++++++++++++++
 drivers/ram/k3-ddrss/k3-ddr_regdump.h |   7 +
 drivers/ram/k3-ddrss/k3-ddrss.c       |   6 +-
 4 files changed, 251 insertions(+), 1 deletion(-)
 create mode 100644 drivers/ram/k3-ddrss/k3-ddr_regdump.c
 create mode 100644 drivers/ram/k3-ddrss/k3-ddr_regdump.h

diff --git a/drivers/ram/k3-ddrss/Makefile b/drivers/ram/k3-ddrss/Makefile
index ba5d9a2f..742b6849 100644
--- a/drivers/ram/k3-ddrss/Makefile
+++ b/drivers/ram/k3-ddrss/Makefile
@@ -3,6 +3,7 @@
 # Copyright (C) 2019-2022 Texas Instruments Incorporated - http://www.ti.com/
 #
 
+obj-$(CONFIG_K3_DDRSS) += k3-ddr_regdump.o
 obj-$(CONFIG_K3_DDRSS) += k3-ddrss.o
 obj-$(CONFIG_K3_DDRSS) += lpddr4_obj_if.o
 obj-$(CONFIG_K3_DDRSS) += lpddr4.o
diff --git a/drivers/ram/k3-ddrss/k3-ddr_regdump.c b/drivers/ram/k3-ddrss/k3-ddr_regdump.c
new file mode 100644
index 00000000..32b16f1a
--- /dev/null
+++ b/drivers/ram/k3-ddrss/k3-ddr_regdump.c
@@ -0,0 +1,238 @@
+
+#define DEBUG 
+#include <common.h>
+#include <asm/io.h>
+#include <k3-ddr_regdump.h>
+
+
+void read_phy_regs_dataslice(u32 freq_set,u32 rank_set,u32 slice,u32 num_of_regs)
+{
+	u32 i;
+	//PHY: data_slice_registers
+	for(i=0;i<=num_of_regs;i++)
+		debug("0x%08x 0x%08x  //DDRSS_PHY_%d_DATA_F%d_R%d\n",(0x0F30C000 + (slice*0x400) + (i*4)),readl(0x0F30C000 + (slice*0x400) + (i*4)),i+(slice*0x100),freq_set,rank_set);
+}
+
+void read_phy_regs_addrslice(u32 freq_set,u32 slice,u32 num_of_regs,u32 base)	
+{	 
+	u32 i,index;
+	//PHY: address_slice_registers
+	if(base == 0x0F30C800)
+		index = 512;
+	else
+		index = 1024;
+	for(i=0;i<=num_of_regs;i++)
+		debug("0x%08x 0x%08x  //DDRSS_PHY_%d_DATA_F%d\n",(base + (slice*256) + (i*4)),readl(base + (slice*256) + (i*4)),index+i+(slice*256),freq_set);
+
+}	
+
+void read_phy_regs_core(u32 freq_set,u32 num_of_regs,u32 base) 
+{	
+	u32 i,index;
+	if(base == 0x0F30D400)
+		index = 1280;
+	else
+		index = 1792;
+	
+	for(i=0;i<=num_of_regs;i++)   
+		debug("0x%08x 0x%08x  //DDRSS_PHY_%d_DATA_F%d\n",base + (i*4),readl(base + (i*4)),index+i,freq_set);
+
+}	
+
+void k3_ddrss_reg_dump(void)
+{
+	u32 i,freq_idx,rank_idx;
+	u32 dram_class;
+	u32 phy_1281,phy_1793,phy_5,phy_6,phy_262,phy_518,phy_774;
+	u32 freq_map,rank_map;
+	u32 pi_version;
+	u32 ctrl_regs=0,pi_regs=0,data_slice_regs=0,addr_slice_regs=0,phy_regs=0,addr_slice_base=0,phy_core_base=0;
+	
+	printf("Begin DDR Register Dump\n");
+	//Which Sitara device?
+	pi_version = readl(0x0F30A004);
+	if(pi_version == 0xAE8D79E2)
+	{ //AM64x/AM62x
+		ctrl_regs = 422;
+		pi_regs = 344;
+		data_slice_regs = 125;
+		addr_slice_regs = 42;
+		addr_slice_base = 0x0F30C800;
+		phy_regs = 125;		
+		phy_core_base = 0xF30D400;
+	}
+		
+	else if (pi_version == 0xB0BD08BA)
+	{ //AM62A/AM62P
+		ctrl_regs = 434;
+		pi_regs = 423;
+		data_slice_regs = 136;
+		addr_slice_regs = 48;
+		addr_slice_base = 0x0F30D000;
+		phy_regs = 131;		
+		phy_core_base = 0xF30DC00;
+	}
+	else
+		debug("ERROR: Device not recognized.  Register dump skipped.");
+	
+	for(i=0;i<=ctrl_regs;i++)
+		debug("0x%08x 0x%08x  //DDRSS_CTL_%d_DATA\n",(0x0F308000 + (i*4) ),readl(0x0F308000 + (i*4)),i);
+
+	for(i=0;i<=pi_regs;i++)
+		debug("0x%08x 0x%08x  //DDRSS_PI_%d_DATA\n",(0x0F30A000 + (i*4) ),readl(0x0F30A000 + (i*4)),i);
+	
+	dram_class = (readl(0x0F308000) >> 8) & 0xF;
+	if(dram_class == 0xA)
+	{//DDR4
+		//Set FREQ_SEL_INDEX = 0 to read F0
+		//and set PHY_FREQ_SEL_MULTICAST_EN=0
+		writel(readl(0x0F30D404) & ~0x30100UL,0x0F30D404);  //PHY_1281
+		debug("data slice 0\n");
+		read_phy_regs_dataslice(0,0,0,data_slice_regs);
+		debug("data slice 1\n");
+		read_phy_regs_dataslice(0,0,1,data_slice_regs);
+		debug("addr slice 0\n");
+		read_phy_regs_addrslice(0,0,addr_slice_regs,addr_slice_base);
+		debug("data slice 1\n");
+		read_phy_regs_addrslice(0,1,addr_slice_regs,addr_slice_base);
+		debug("data slice 2\n");
+		read_phy_regs_addrslice(0,2,addr_slice_regs,addr_slice_base);
+        read_phy_regs_core(0,phy_regs,phy_core_base);
+	}
+	else if (dram_class == 0xB)
+	{//LPDDR4	
+		if(pi_version == 0xAE8D79E2)
+		{ //AM64x/AM62x
+			//save off regs that are written
+			phy_1281 = readl(0x0F30D404);
+			//cycle through the frequencies being used based on PI_FREQ_MAP
+			for(freq_idx = 1;freq_idx <= 2;freq_idx++)
+			{
+				freq_map = 1 << freq_idx; 
+				//if the frequency is active
+				if(((readl(0x0F30A030)) & freq_map) == freq_map)  //PI_12, PI_FREQ_MAP
+				{
+					//set PHY_1281,PHY_FREQ_SEL_INDEX to choose the frequency set  (in PHY, freq0 corresponds to F1, freq1 corresponds to F2)
+					//and set PHY_FREQ_SEL_MULTICAST_EN=0
+					writel((readl(0x0F30DC04) & ~0x30100UL) | ((freq_idx-1)<<16),0x0F30DC04);
+		
+					//cycle through each rank being used based on PI_CS_MAP 
+					//(PI_CS_MAP will be 0x5 for single rank x32, 0xF for dual rank x32)
+					//(PI_CS_MAP will be 0x1 for single rank x16, 0x3 for dual rank x16)
+					//so rank0 is 0x5 for x32, rank1 is 0xA for x32
+					//and rank0 is 0x1 for x16, rank1 is 0x2 for x16
+					//16bit data
+					debug("data slice 0\n");
+					read_phy_regs_dataslice(freq_idx,0,0,data_slice_regs);
+					debug("data slice 1\n");
+					read_phy_regs_dataslice(freq_idx,0,1,data_slice_regs);
+					debug("addr slice 0\n");
+					read_phy_regs_addrslice(freq_idx,0,addr_slice_regs,addr_slice_base);
+					debug("phy core regs\n");
+					read_phy_regs_core(freq_idx,phy_regs,phy_core_base);
+				}
+			}
+			//put the regs back the way they were
+			writel(phy_1281,0x0F30D404);	
+		}
+		else if (pi_version == 0xB0BD08BA)
+		{ //AM62A/AM62P
+			//save off regs that are written
+			phy_1793 = readl(0x0F30DC04);
+			phy_5 = readl(0x0F30C014);
+			phy_6 = readl(0x0F30C018);
+			phy_262 = readl(0x0F30C418);
+			phy_518 = readl(0x0F30C818);
+			phy_774 = readl(0x0F30CC18);
+			//cycle through the frequencies being used based on PI_FREQ_MAP
+			for(freq_idx = 1;freq_idx <= 2;freq_idx++)
+			{
+				freq_map = 1 << freq_idx; 
+				//if the frequency is active
+				if(((readl(0x0F30A030)) & freq_map) == freq_map)  //PI_12,PI_FREQ_MAP
+				{
+					//set PHY_1793,PHY_FREQ_SEL_INDEX to choose the frequency set  (in PHY, freq0 corresponds to F1, freq1 corresponds to F2)
+					//and set PHY_FREQ_SEL_MULTICAST_EN=0 (bit8)
+					writel((readl(0x0F30DC04) & ~0x30100UL) | ((freq_idx-1)<<16),0x0F30DC04); 
+					//cycle through each rank being used based on PI_CS_MAP 
+					//(PI_CS_MAP will be 0x5 for single rank x32, 0xF for dual rank x32)
+					//(PI_CS_MAP will be 0x1 for single rank x16, 0x3 for dual rank x16)
+					//so rank0 is 0x5 for x32, rank1 is 0xA for x32
+					//and rank0 is 0x1 for x16, rank1 is 0x2 for x16
+					if(((readl(0x0F30A068)>>24) & 0x1) == 0x1)  //PI_26, PI_16BIT_DRAM_CONNECT = 0 for 16bit, 1 for 32-bit
+					{//if 32bit data
+						for(rank_idx = 0;rank_idx <= 1;rank_idx++)
+						{
+							debug("32-bit data\n");
+							rank_map = 0x5 << rank_idx;
+							if(((readl(0x0F30A034)>>16) & rank_map) == rank_map) //PI_13, PI_CS_MAP, if CS is active
+							{
+								//Rank parameter index
+								//set PHY_PER_CS_TRAINING_INDEX to the rank for each data slice
+								//PHY only recognizes CS0 and CS1
+								//disable PER_CS_TRAINING_MULTICAST
+								writel(readl(0x0F30C014) & ~((1UL)<<24),0x0F30C014);
+								writel(readl(0x0F30C414) & ~((1UL)<<24),0x0F30C414);
+								writel(readl(0x0F30C814) & ~((1UL)<<24),0x0F30C814);
+								writel(readl(0x0F30CC14) & ~((1UL)<<24),0x0F30CC14);
+								writel((readl(0x0F30C018) & ~(0x1UL)) | rank_idx,0x0F30C018);
+								writel((readl(0x0F30C418) & ~(0x1UL)) | rank_idx,0x0F30C418);
+								writel((readl(0x0F30C818) & ~(0x1UL)) | rank_idx,0x0F30C818);
+								writel((readl(0x0F30CC18) & ~(0x1UL)) | rank_idx,0x0F30CC18);
+								debug("per_cs_training_index = %d\n",rank_idx);
+								debug("data slice 0\n");
+								read_phy_regs_dataslice(freq_idx,rank_idx,0,data_slice_regs);
+								debug("data slice 1\n");
+								read_phy_regs_dataslice(freq_idx,rank_idx,1,data_slice_regs);
+								debug("data slice 2\n");
+								read_phy_regs_dataslice(freq_idx,rank_idx,2,data_slice_regs);
+								debug("data slice 3\n");
+								read_phy_regs_dataslice(freq_idx,rank_idx,3,data_slice_regs);
+							}
+						}
+					}
+					else
+					{//if 16bit data
+						for(rank_idx = 0;rank_idx <= 1;rank_idx++)
+						{
+							debug("16-bit data\n");
+							rank_map = 0x1 << rank_idx;
+							if(((readl(0x0F30A034)>>16) & rank_map) == rank_map) //PI_13, PI_CS_MAP, if CS is active
+							{
+								//Rank parameter index
+								//set PHY_PER_CS_TRAINING_INDEX to the rank for each data slice
+								//PHY only recognizes CS0 and CS1
+								//disable PER_CS_TRAINING_MULTICAST
+								writel(readl(0x0F30C014) & ~((1UL)<<24),0x0F30C014);
+								writel(readl(0x0F30C414) & ~((1UL)<<24),0x0F30C414);
+														
+								writel((readl(0x0F30C018) & ~0x1UL) | rank_idx,0x0F30C018);
+								writel((readl(0x0F30C418) & ~0x1UL) | rank_idx,0x0F30C418);
+								debug("per_cs_training_index = %d\n",rank_idx);
+								debug("data slice 0\n");
+								read_phy_regs_dataslice(freq_idx,rank_idx,0,data_slice_regs);
+								debug("data slice 1\n");
+								read_phy_regs_dataslice(freq_idx,rank_idx,1,data_slice_regs);
+							}
+						}
+					}
+					debug("addr slice 0\n");
+					read_phy_regs_addrslice(freq_idx,0,addr_slice_regs,addr_slice_base);
+					debug("phy core regs\n");
+					read_phy_regs_core(freq_idx,phy_regs,phy_core_base);				
+				}
+			} //end of frequency set loop
+			//put the regs back the way they were
+			writel(phy_1793,0x0F30DC04);
+			writel(phy_5,0x0F30C014);
+			writel(phy_6,0x0F30C018);
+			writel(phy_262,0x0F30C418);
+			writel(phy_518,0x0F30C818);
+			writel(phy_774,0x0F30CC18);
+		}//end of AM62A/P dump
+	}
+	else
+		debug("ERROR: DDR type not recognized.  RegDump not executed\n");
+	
+	debug("End of DDR Register Dump\n\n");
+}
diff --git a/drivers/ram/k3-ddrss/k3-ddr_regdump.h b/drivers/ram/k3-ddrss/k3-ddr_regdump.h
new file mode 100644
index 00000000..3702cb1d
--- /dev/null
+++ b/drivers/ram/k3-ddrss/k3-ddr_regdump.h
@@ -0,0 +1,7 @@
+
+
+#include <common.h>
+void read_phy_regs_dataslice(u32 freq_set,u32 rank_set, u32 slice, u32 num_of_regs);
+void read_phy_regs_addrslice(u32 freq_set,u32 slice, u32 num_of_regs,u32 base);
+void read_phy_regs_core(u32 freq_set,u32 num_of_regs,u32 base);
+void k3_ddrss_reg_dump(void);
diff --git a/drivers/ram/k3-ddrss/k3-ddrss.c b/drivers/ram/k3-ddrss/k3-ddrss.c
index 322e8e86..db09dad5 100644
--- a/drivers/ram/k3-ddrss/k3-ddrss.c
+++ b/drivers/ram/k3-ddrss/k3-ddrss.c
@@ -4,7 +4,8 @@
  *
  * Copyright (C) 2020-2021 Texas Instruments Incorporated - http://www.ti.com/
  */
-
+#define DEBUG
+#include <k3-ddr_regdump.h>
 #include <common.h>
 #include <config.h>
 #include <time.h>
@@ -558,6 +559,9 @@ void k3_lpddr4_start(struct k3_ddrss_desc *ddrss)
 	} else {
 		debug("%s: Post start PASS\n", __func__);
 	}
+#ifdef DEBUG
+	k3_ddrss_reg_dump();
+#endif
 }
 
 static void k3_ddrss_set_ecc_range_r0(u32 base, u64 start_address, u64 size)
-- 
2.34.1

