diff mbox series

[3/3] mmc: sdhci-cadence: Add debug option in sdhci-cadence driver

Message ID 20230605135821.4213-4-pmalgujar@marvell.com
State New
Delegated to: Jaehoon Chung
Headers show
Series mmc: sdhci-cadence: SD6 controller support | expand

Commit Message

Piyush Malgujar June 5, 2023, 1:58 p.m. UTC
From: Dhananjay Kangude <dkangude@cadence.com>

Additional debug information is printed if MMC_SDHCI_CADENCE_DEBUG
is enabled.

Signed-off-by: Dhananjay Kangude <dkangude@cadence.com>
Co-developed-by: Jayanthi Annadurai <jannadurai@marvell.com>
Signed-off-by: Jayanthi Annadurai <jannadurai@marvell.com>
Signed-off-by: Piyush Malgujar <pmalgujar@marvell.com>
---
 drivers/mmc/Kconfig         |  8 +++
 drivers/mmc/sdhci-cadence.c | 97 +++++++++++++++++++++++++++++++++++++
 2 files changed, 105 insertions(+)
diff mbox series

Patch

diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index 6b724f1d1ed050b49e31a6cbe5f898b4b636c330..8177a83e492087f5e30844f0290a1ee85ae02511 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -574,6 +574,14 @@  config MMC_SDHCI_CADENCE
 
 	  If unsure, say N.
 
+config MMC_SDHCI_CADENCE_DEBUG
+	bool "Debug support for the Cadence SD/SDIO/eMMC controller"
+	depends on MMC_SDHCI_CADENCE
+	default n
+	help
+	  This enables additional debug messages from cadence SDHCI
+	  driver.
+
 config MMC_SDHCI_AM654
 	bool "SDHCI Controller on TI's Am654 devices"
 	depends on ARCH_K3
diff --git a/drivers/mmc/sdhci-cadence.c b/drivers/mmc/sdhci-cadence.c
index 1d8e8e177eeeb6464ba9ade5fd63c1cca4554bb6..90607d4d802d07be3b1c840143141931f10f9126 100644
--- a/drivers/mmc/sdhci-cadence.c
+++ b/drivers/mmc/sdhci-cadence.c
@@ -18,6 +18,11 @@ 
 #include <linux/libfdt.h>
 #include <mmc.h>
 #include <sdhci.h>
+#ifdef CONFIG_MMC_SDHCI_CADENCE_DEBUG
+#define DEBUG_DRV(fmt, ...)	\
+	if (1) \
+		printf(fmt, ##__VA_ARGS__)
+#endif
 
 #define SDHCI_CDNS_SD6_MAXCLK		200000000
 
@@ -492,6 +497,72 @@  static u32 sdhci_cdns_sd6_read_phy_reg(struct sdhci_cdns_plat *plat,
 	return readl(plat->hrs_addr + SDHCI_CDNS_HRS05);
 }
 
+#ifdef CONFIG_MMC_SDHCI_CADENCE_DEBUG
+void sdhci_cdns_sd6_dump(struct sdhci_cdns_plat *plat)
+{
+	int i;
+
+	for (i = 0; i < 14; i++)
+		DEBUG_DRV("HRS%d 0x%x\n", i, readl(plat->hrs_addr + (i * 4)));
+
+	for (i = 0; i < 27; i++)
+		DEBUG_DRV("SRS%d 0x%x\n", i, readl(plat->hrs_addr + 0x200 + (i * 4)));
+
+	DEBUG_DRV("SDHCI_CDNS_SD6_PHY_DLL_SLAVE 0x%x\n",
+		  sdhci_cdns_sd6_read_phy_reg(plat, SDHCI_CDNS_SD6_PHY_DLL_SLAVE));
+	DEBUG_DRV("SDHCI_CDNS_SD6_PHY_CTRL 0x%x\n",
+		  sdhci_cdns_sd6_read_phy_reg(plat, SDHCI_CDNS_SD6_PHY_CTRL));
+	DEBUG_DRV("SDHCI_CDNS_SD6_PHY_DLL_MASTER 0x%x\n",
+		  sdhci_cdns_sd6_read_phy_reg(plat, SDHCI_CDNS_SD6_PHY_DLL_MASTER));
+	DEBUG_DRV("SDHCI_CDNS_SD6_PHY_GATE_LPBK 0x%x\n",
+		  sdhci_cdns_sd6_read_phy_reg(plat, SDHCI_CDNS_SD6_PHY_GATE_LPBK));
+	DEBUG_DRV("SDHCI_CDNS_SD6_PHY_DQS_TIMING 0x%x\n",
+		  sdhci_cdns_sd6_read_phy_reg(plat, SDHCI_CDNS_SD6_PHY_DQS_TIMING));
+}
+
+static void sdhci_cdns_sd6_phy_dump(struct sdhci_cdns_sd6_phy *phy)
+{
+	DEBUG_DRV("sdhci_cdns_sd6_phy_init mode %d t_sdclk %d\n", phy->mode, phy->t_sdclk);
+	DEBUG_DRV("cp_clk_wr_delay %d\n", phy->settings.cp_clk_wr_delay);
+	DEBUG_DRV("cp_clk_wrdqs_delay %d\n", phy->settings.cp_clk_wrdqs_delay);
+	DEBUG_DRV("cp_data_select_oe_end %d\n", phy->settings.cp_data_select_oe_end);
+	DEBUG_DRV("cp_dll_bypass_mode %d\n", phy->settings.cp_dll_bypass_mode);
+	DEBUG_DRV("cp_dll_locked_mode %d\n", phy->settings.cp_dll_locked_mode);
+	DEBUG_DRV("cp_dll_start_point %d\n", phy->settings.cp_dll_start_point);
+	DEBUG_DRV("cp_io_mask_always_on %d\n", phy->settings.cp_io_mask_always_on);
+	DEBUG_DRV("cp_io_mask_end %d\n", phy->settings.cp_io_mask_end);
+	DEBUG_DRV("cp_io_mask_start %d\n", phy->settings.cp_io_mask_start);
+	DEBUG_DRV("cp_rd_del_sel %d\n", phy->settings.cp_rd_del_sel);
+	DEBUG_DRV("cp_read_dqs_cmd_delay %d\n", phy->settings.cp_read_dqs_cmd_delay);
+	DEBUG_DRV("cp_read_dqs_delay %d\n", phy->settings.cp_read_dqs_delay);
+	DEBUG_DRV("cp_sw_half_cycle_shift %d\n", phy->settings.cp_sw_half_cycle_shift);
+	DEBUG_DRV("cp_sync_method %d\n", phy->settings.cp_sync_method);
+	DEBUG_DRV("cp_use_ext_lpbk_dqs %d\n", phy->settings.cp_use_ext_lpbk_dqs);
+	DEBUG_DRV("cp_use_lpbk_dqs %d\n", phy->settings.cp_use_lpbk_dqs);
+	DEBUG_DRV("cp_use_phony_dqs %d\n", phy->settings.cp_use_phony_dqs);
+	DEBUG_DRV("cp_use_phony_dqs_cmd %d\n", phy->settings.cp_use_phony_dqs_cmd);
+	DEBUG_DRV("sdhc_extended_rd_mode %d\n", phy->settings.sdhc_extended_rd_mode);
+	DEBUG_DRV("sdhc_extended_wr_mode %d\n", phy->settings.sdhc_extended_wr_mode);
+	DEBUG_DRV("sdhc_hcsdclkadj %d\n", phy->settings.sdhc_hcsdclkadj);
+	DEBUG_DRV("sdhc_idelay_val %d\n", phy->settings.sdhc_idelay_val);
+	DEBUG_DRV("sdhc_rdcmd_en %d\n", phy->settings.sdhc_rdcmd_en);
+	DEBUG_DRV("sdhc_rddata_en %d\n", phy->settings.sdhc_rddata_en);
+	DEBUG_DRV("sdhc_rw_compensate %d\n", phy->settings.sdhc_rw_compensate);
+	DEBUG_DRV("sdhc_sdcfsh %d\n", phy->settings.sdhc_sdcfsh);
+	DEBUG_DRV("sdhc_sdcfsl %d\n", phy->settings.sdhc_sdcfsl);
+	DEBUG_DRV("sdhc_wrcmd0_dly %d %d\n", phy->settings.sdhc_wrcmd0_dly,
+		  phy->settings.sdhc_wrcmd0_sdclk_dly);
+	DEBUG_DRV("sdhc_wrcmd1_dly %d %d\n", phy->settings.sdhc_wrcmd1_dly,
+		  phy->settings.sdhc_wrcmd1_sdclk_dly);
+	DEBUG_DRV("sdhc_wrdata0_dly %d %d\n", phy->settings.sdhc_wrdata0_dly,
+		  phy->settings.sdhc_wrdata0_sdclk_dly);
+
+	DEBUG_DRV("sdhc_wrdata1_dly %d %d\n", phy->settings.sdhc_wrdata1_dly,
+		  phy->settings.sdhc_wrdata1_sdclk_dly);
+	DEBUG_DRV("hs200_tune_val %d\n", phy->settings.hs200_tune_val);
+}
+#endif
+
 static void sdhci_cdns_sd6_writel(struct sdhci_host *host, u32 val, int reg)
 {
 	writel(val, host->ioaddr + reg);
@@ -579,6 +650,16 @@  static void sdhci_cdns_set_emmc_mode(struct sdhci_cdns_plat *priv, u32 mode)
 }
 #endif
 
+#ifdef CONFIG_MMC_SDHCI_CADENCE_DEBUG
+static u32 sdhci_cdns_get_emmc_mode(struct sdhci_cdns_plat *priv)
+{
+	u32 tmp;
+
+	tmp = readl(priv->hrs_addr + SDHCI_CDNS_HRS06);
+	return FIELD_GET(SDHCI_CDNS_HRS06_MODE, tmp);
+}
+#endif
+
 void sdhci_cdns_sd6_fullsw_reset(struct sdhci_cdns_plat *plat)
 {
 	u32 regval;
@@ -1334,6 +1415,18 @@  static int sdhci_cdns_sd6_phy_update_timings(struct sdhci_cdns_plat *plat)
 	return 0;
 }
 
+#ifdef CONFIG_MMC_SDHCI_CADENCE_DEBUG
+void dump_sdhci_regs(struct sdhci_host *host)
+{
+	struct udevice *dev = host->mmc->dev;
+	struct sdhci_cdns_plat *plat = dev_get_plat(dev);
+	struct sdhci_cdns_sd6_phy *phy = plat->priv;
+
+	sdhci_cdns_sd6_phy_dump(phy);
+	sdhci_cdns_sd6_dump(plat);
+}
+#endif
+
 static void sdhci_cdns_sd6_set_clock(struct sdhci_host *host, unsigned int div)
 {
 	struct udevice *dev = host->mmc->dev;
@@ -1359,6 +1452,10 @@  static void sdhci_cdns_sd6_set_clock(struct sdhci_host *host, unsigned int div)
 
 	if (sdhci_cdns_sd6_phy_init(dev, plat))
 		debug("%s: phy init failed\n", __func__);
+#ifdef CONFIG_MMC_SDHCI_CADENCE_DEBUG
+	dump_sdhci_regs(host);
+	DEBUG_DRV("%s sdhci mode %d\n", __func__, sdhci_cdns_get_emmc_mode(plat));
+#endif
 }
 
 static int sdhci_cdns_sd6_plat_init(struct udevice *dev, struct sdhci_cdns_plat *plat)