From 5abdf26312114ca86734285ad915ee471530393d Mon Sep 17 00:00:00 2001
From: James Doublesin <doublesin@ti.com>
Date: Tue, 11 Jun 2024 14:51:04 -0500
Subject: [PATCH] added regdump code

---
 drivers/ram/k3-ddrss/Makefile         |   2 +-
 drivers/ram/k3-ddrss/k3-ddr_regdump.c | 195 ++++++++++++++++++++++++++
 drivers/ram/k3-ddrss/k3-ddr_regdump.h |   7 +
 drivers/ram/k3-ddrss/k3-ddrss.c       |   3 +
 4 files changed, 206 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..6b032063 100644
--- a/drivers/ram/k3-ddrss/Makefile
+++ b/drivers/ram/k3-ddrss/Makefile
@@ -2,7 +2,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..d13451d3
--- /dev/null
+++ b/drivers/ram/k3-ddrss/k3-ddr_regdump.c
@@ -0,0 +1,195 @@
+
+#define DEBUG 
+#include <common.h>
+#include <asm/io.h>
+#include <k3-ddr_regdump.h>
+
+
+void read_phy_regs_dataslice(u32 freq_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\n",(0x0F30C000 + (slice*0x400) + (i*4)),readl(0x0F30C000 + (slice*0x400) + (i*4)),i+(slice*0x100),freq_set);
+}
+
+void read_phy_regs_addrslice(u32 freq_set,u32 slice,u32 num_of_regs)	
+{	 
+	u32 i;
+	//PHY: address_slice_registers
+	for(i=0;i<=num_of_regs;i++)
+		debug("0x%08x 0x%08x  //DDRSS_PHY_%d_DATA_F%d\n",(0x0F30C800 + (slice*0x400) + (i*4)),readl(0x0F30C800 + (slice*0x400) + (i*4)),i+512+(slice*0x100),freq_set);
+
+}	
+
+void read_phy_regs_core(u32 freq_set,u32 num_of_regs) 
+{	
+	u32 i;
+	for(i=0;i<=num_of_regs;i++)   
+		debug("0x%08x 0x%08x  //DDRSS_PHY_%d_DATA_F%d\n",(0x0F30D400 + (i*4)),readl(0x0F30D400 + (i*4)),i+0x500,freq_set);
+
+}	
+
+void k3_ddrss_reg_dump(void)
+{
+	u32 i,freq_idx,rank_idx;
+	u32 dram_class;
+	u32 phy_1281,phy_1793,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;
+	
+	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;
+		phy_regs = 125;
+		
+	}
+		
+	else if (pi_version == 0xB0BD08BA)
+	{ //AM62A/AM62P
+		ctrl_regs = 434;
+		pi_regs = 423;
+		data_slice_regs = 136;
+		addr_slice_regs = 48;
+		phy_regs = 131;
+		
+	}
+	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) & 0xF00) >> 8;
+	if(dram_class == 0xA)
+	{//DDR4
+		//Set FREQ_SEL_INDEX = 0 to read F0
+		writel(0x0F30D404,readl(0x0F30D404) & ~0x30000);  //PHY_1281
+		read_phy_regs_dataslice(0,0,data_slice_regs);
+		read_phy_regs_dataslice(0,1,data_slice_regs);
+		read_phy_regs_addrslice(0,0,addr_slice_regs);
+		read_phy_regs_addrslice(0,1,addr_slice_regs);
+		read_phy_regs_addrslice(0,2,addr_slice_regs);
+        read_phy_regs_core(0,phy_regs);
+	}
+	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(i = 1;i <= 2;i++)
+			{
+				freq_map = 1 << i; 
+				//if the frequency is active
+				if(((readl(0x0F30A030)) & freq_map) == freq_map)  //PI_12
+				{
+					//set PHY_FREQ_SEL_INDEX to choose the frequency set  (in PHY, freq0 corresponds to F1, freq1 corresponds to F2)
+					writel(0x0F30D404,(readl(0x0F30D404) & ~0x30000) | ((i-1)<<16));
+		
+					//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
+					read_phy_regs_dataslice(i,0,data_slice_regs);
+					read_phy_regs_dataslice(i,1,data_slice_regs);
+					read_phy_regs_dataslice(i,2,data_slice_regs);
+					read_phy_regs_dataslice(i,3,data_slice_regs);
+					read_phy_regs_addrslice(i,0,addr_slice_regs);
+					read_phy_regs_core(i,phy_regs);
+				
+				}
+			}
+			//put the regs back the way they were
+			writel(0x0F30D404,phy_1281);	
+		}
+		else if (pi_version == 0xB0BD08BA)
+		{ //AM62A/AM62P
+			//save off regs that are written
+			phy_1793 = readl(0x0F30DC04);
+			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(0x0F30DC04,(readl(0x0F30DC04) & ~0x30100) | ((freq_idx-1)<<16)); 
+					
+					//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) & (1<<24)) == (1<<24))  //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++)
+						{
+							rank_map = 0x5 << rank_idx;
+							if((readl(0x0F30A034) & (rank_map<<16)) == (rank_map<<16)) //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
+								writel(0x0F30C018,(readl(0x0F30C018) & ~0x1) | rank_idx);
+								writel(0x0F30C018,(readl(0x0F30C418) & ~0x1) | rank_idx);
+								writel(0x0F30C018,(readl(0x0F30C818) & ~0x1) | rank_idx);
+								writel(0x0F30C018,(readl(0x0F30CC18) & ~0x1) | rank_idx);
+								read_phy_regs_dataslice(freq_idx,rank_idx,data_slice_regs);
+							}
+						}
+					}
+					{//if 16bit data
+						for(rank_idx = 0;rank_idx <= 1;rank_idx++)
+						{
+							rank_map = 0x1 << rank_idx;
+							if((readl(0x0F30A034) & (rank_map<<16)) == (rank_map<<16)) //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
+								writel(0x0F30C018,(readl(0x0F30C018) & ~0x1) | rank_idx);
+								writel(0x0F30C018,(readl(0x0F30C418) & ~0x1) | rank_idx);
+								writel(0x0F30C018,(readl(0x0F30C818) & ~0x1) | rank_idx);
+								writel(0x0F30C018,(readl(0x0F30CC18) & ~0x1) | rank_idx);
+								
+								read_phy_regs_dataslice(freq_idx,rank_idx,data_slice_regs);
+							}
+						}
+					}
+				}
+				read_phy_regs_addrslice(freq_idx,0,addr_slice_regs);
+				read_phy_regs_core(freq_idx,phy_regs);				
+			} //end of frequency set loop
+			//put the regs back the way they were
+			writel(0x0F30DC04,phy_1793);
+			writel(0x0F30C018,phy_6);
+			writel(0x0F30C418,phy_262);
+			writel(0x0F30C818,phy_518);
+			writel(0x0F30CC18,phy_774);
+		}//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..1c66eb7c
--- /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 slice, u32 num_of_regs);
+void read_phy_regs_addrslice(u32 freq_set,u32 slice, u32 num_of_regs);
+void read_phy_regs_core(u32 freq_set,u32 num_of_regs);
+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..4cffb665 100644
--- a/drivers/ram/k3-ddrss/k3-ddrss.c
+++ b/drivers/ram/k3-ddrss/k3-ddrss.c
@@ -5,7 +5,9 @@
  * Copyright (C) 2020-2021 Texas Instruments Incorporated - http://www.ti.com/
  */
 
+#define DEBUG
 #include <common.h>
+#include <k3-ddr_regdump.h>
 #include <config.h>
 #include <time.h>
 #include <clk.h>
@@ -558,6 +560,7 @@ void k3_lpddr4_start(struct k3_ddrss_desc *ddrss)
 	} else {
 		debug("%s: Post start PASS\n", __func__);
 	}
+	k3_ddrss_reg_dump();
 }
 
 static void k3_ddrss_set_ecc_range_r0(u32 base, u64 start_address, u64 size)
-- 
2.34.1

