Commit 2d9ca2c7 authored by Yangbo Lu's avatar Yangbo Lu Committed by York Sun

mmc: fsl_esdhc: Add peripheral clock support

The SD clock could be generated by platform clock or peripheral
clock for some platforms. This patch adds peripheral clock
support for T1024/T1040/T2080. To enable it, define
CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK.
Signed-off-by: default avatarYangbo Lu <yangbo.lu@freescale.com>
Cc: York Sun <yorksun@freescale.com>
Cc: Pantelis Antoniou <panto@antoniou-consulting.com>
Reviewed-by: default avatarYork Sun <yorksun@freescale.com>
parent b46cf1b1
......@@ -73,7 +73,8 @@ void get_sys_info(sys_info_t *sys_info)
[14] = 4, /* CC4 PPL / 4 */
};
uint i, freq_c_pll[CONFIG_SYS_FSL_NUM_CC_PLLS];
#if !defined(CONFIG_FM_PLAT_CLK_DIV) || !defined(CONFIG_PME_PLAT_CLK_DIV)
#if !defined(CONFIG_FM_PLAT_CLK_DIV) || !defined(CONFIG_PME_PLAT_CLK_DIV) || \
defined(CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK)
uint rcw_tmp;
#endif
uint ratio[CONFIG_SYS_FSL_NUM_CC_PLLS];
......@@ -453,6 +454,48 @@ void get_sys_info(sys_info_t *sys_info)
#endif
#endif
#ifdef CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK
#if defined(CONFIG_PPC_T2080)
#define ESDHC_CLK_SEL 0x00000007
#define ESDHC_CLK_SHIFT 0
#define ESDHC_CLK_RCWSR 15
#else /* Support T1040 T1024 by now */
#define ESDHC_CLK_SEL 0xe0000000
#define ESDHC_CLK_SHIFT 29
#define ESDHC_CLK_RCWSR 7
#endif
rcw_tmp = in_be32(&gur->rcwsr[ESDHC_CLK_RCWSR]);
switch ((rcw_tmp & ESDHC_CLK_SEL) >> ESDHC_CLK_SHIFT) {
case 1:
sys_info->freq_sdhc = freq_c_pll[CONFIG_SYS_SDHC_CLK];
break;
case 2:
sys_info->freq_sdhc = freq_c_pll[CONFIG_SYS_SDHC_CLK] / 2;
break;
case 3:
sys_info->freq_sdhc = freq_c_pll[CONFIG_SYS_SDHC_CLK] / 3;
break;
#if defined(CONFIG_SYS_SDHC_CLK_2_PLL)
case 4:
sys_info->freq_sdhc = freq_c_pll[CONFIG_SYS_SDHC_CLK] / 4;
break;
#if defined(CONFIG_PPC_T2080)
case 5:
sys_info->freq_sdhc = freq_c_pll[1 - CONFIG_SYS_SDHC_CLK];
break;
#endif
case 6:
sys_info->freq_sdhc = freq_c_pll[1 - CONFIG_SYS_SDHC_CLK] / 2;
break;
case 7:
sys_info->freq_sdhc = freq_c_pll[1 - CONFIG_SYS_SDHC_CLK] / 3;
break;
#endif
default:
sys_info->freq_sdhc = 0;
printf("Error: Unknown SDHC peripheral clock select!\n");
}
#endif
#else /* CONFIG_SYS_FSL_QORIQ_CHASSIS2 */
for_each_cpu(i, cpu, cpu_numcores(), cpu_mask()) {
......@@ -660,12 +703,16 @@ int get_clocks (void)
gd->arch.i2c2_clk = gd->arch.i2c1_clk;
#if defined(CONFIG_FSL_ESDHC)
#ifdef CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK
gd->arch.sdhc_clk = sys_info.freq_sdhc / 2;
#else
#if defined(CONFIG_MPC8569) || defined(CONFIG_P1010) ||\
defined(CONFIG_P1014)
gd->arch.sdhc_clk = gd->bus_clk;
#else
gd->arch.sdhc_clk = gd->bus_clk / 2;
#endif
#endif
#endif /* defined(CONFIG_FSL_ESDHC) */
#if defined(CONFIG_CPM2)
......
......@@ -775,7 +775,6 @@ defined(CONFIG_PPC_T1020) || defined(CONFIG_PPC_T1022)
#endif
#define CONFIG_SYS_FSL_NUM_CC_PLLS 2
#define CONFIG_SYS_FSL_CLUSTER_CLOCKS { 1, 1, 1, 1 }
#define CONFIG_SYS_SDHC_CLOCK 0
#define CONFIG_SYS_FSL_NUM_LAWS 16
#define CONFIG_SYS_FSL_SRDS_1
#define CONFIG_SYS_FSL_SEC_COMPAT 5
......@@ -791,6 +790,9 @@ defined(CONFIG_PPC_T1020) || defined(CONFIG_PPC_T1022)
#define CONFIG_SYS_FMAN_V3
#define CONFIG_FM_PLAT_CLK_DIV 1
#define CONFIG_SYS_FM1_CLK CONFIG_FM_PLAT_CLK_DIV
#define CONFIG_SYS_SDHC_CLK 0/* Select SDHC CLK begining from PLL1
per rcw field value */
#define CONFIG_SYS_SDHC_CLK_2_PLL /* Select SDHC CLK from 2 PLLs */
#define CONFIG_SYS_FM_MURAM_SIZE 0x30000
#define CONFIG_SYS_FSL_SINGLE_SOURCE_CLK
#define CONFIG_SYS_FSL_TBCLK_DIV 16
......@@ -823,7 +825,6 @@ defined(CONFIG_PPC_T1014) || defined(CONFIG_PPC_T1013)
#endif
#define CONFIG_SYS_FSL_NUM_CC_PLL 2
#define CONFIG_SYS_FSL_CLUSTER_CLOCKS { 1, 1, 1, 1 }
#define CONFIG_SYS_SDHC_CLOCK 0
#define CONFIG_SYS_FSL_NUM_LAWS 16
#define CONFIG_SYS_FSL_SRDS_1
#define CONFIG_SYS_FSL_SEC_COMPAT 5
......@@ -836,6 +837,8 @@ defined(CONFIG_PPC_T1014) || defined(CONFIG_PPC_T1013)
#define CONFIG_SYS_FSL_DDR_VER FSL_DDR_VER_5_0
#define CONFIG_SYS_FSL_IFC_BANK_COUNT 8
#define CONFIG_SYS_FM1_CLK 0
#define CONFIG_SYS_SDHC_CLK 0/* Select SDHC CLK begining from PLL1
per rcw field value */
#define CONFIG_QBMAN_CLK_DIV 1
#define CONFIG_SYS_FM_MURAM_SIZE 0x30000
#define CONFIG_SYS_FSL_SINGLE_SOURCE_CLK
......@@ -883,6 +886,9 @@ defined(CONFIG_PPC_T1014) || defined(CONFIG_PPC_T1013)
#define CONFIG_PME_PLAT_CLK_DIV 1
#define CONFIG_SYS_PME_CLK CONFIG_PME_PLAT_CLK_DIV
#define CONFIG_SYS_FM1_CLK 0
#define CONFIG_SYS_SDHC_CLK 1/* Select SDHC CLK begining from PLL2
per rcw field value */
#define CONFIG_SYS_SDHC_CLK_2_PLL /* Select SDHC CLK from 2 PLLs */
#define CONFIG_SYS_FSL_DDR_VER FSL_DDR_VER_4_7
#define CONFIG_SYS_FSL_IFC_BANK_COUNT 8
#define CONFIG_SYS_FMAN_V3
......
......@@ -506,11 +506,47 @@ static void set_sysctl(struct mmc *mmc, uint clock)
esdhc_setbits32(&regs->sysctl, clk);
}
#ifdef CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK
static void esdhc_clock_control(struct mmc *mmc, bool enable)
{
struct fsl_esdhc_cfg *cfg = mmc->priv;
struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base;
u32 value;
u32 time_out;
value = esdhc_read32(&regs->sysctl);
if (enable)
value |= SYSCTL_CKEN;
else
value &= ~SYSCTL_CKEN;
esdhc_write32(&regs->sysctl, value);
time_out = 20;
value = PRSSTAT_SDSTB;
while (!(esdhc_read32(&regs->prsstat) & value)) {
if (time_out == 0) {
printf("fsl_esdhc: Internal clock never stabilised.\n");
break;
}
time_out--;
mdelay(1);
}
}
#endif
static void esdhc_set_ios(struct mmc *mmc)
{
struct fsl_esdhc_cfg *cfg = mmc->priv;
struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base;
#ifdef CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK
/* Select to use peripheral clock */
esdhc_clock_control(mmc, false);
esdhc_setbits32(&regs->scr, ESDHCCTL_PCS);
esdhc_clock_control(mmc, true);
#endif
/* Set the clock speed */
set_sysctl(mmc, mmc->clock);
......@@ -740,8 +776,13 @@ void fdt_fixup_esdhc(void *blob, bd_t *bd)
}
#endif
#ifdef CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK
do_fixup_by_compat_u32(blob, compat, "peripheral-frequency",
gd->arch.sdhc_clk, 1);
#else
do_fixup_by_compat_u32(blob, compat, "clock-frequency",
gd->arch.sdhc_clk, 1);
#endif
#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
do_fixup_by_compat_u32(blob, compat, "adapter-type",
(u32)(gd->arch.sdhc_adapter), 1);
......
......@@ -18,6 +18,7 @@ typedef struct
unsigned long freq_ddrbus;
unsigned long freq_localbus;
unsigned long freq_qe;
unsigned long freq_sdhc;
#ifdef CONFIG_SYS_DPAA_FMAN
unsigned long freq_fman[CONFIG_SYS_NUM_FMAN];
#endif
......
......@@ -78,6 +78,9 @@
#define IRQSTATEN_TC (0x00000002)
#define IRQSTATEN_CC (0x00000001)
#define ESDHCCTL 0x0002e40c
#define ESDHCCTL_PCS (0x00080000)
#define PRSSTAT 0x0002e024
#define PRSSTAT_DAT0 (0x01000000)
#define PRSSTAT_CLSL (0x00800000)
......@@ -86,6 +89,7 @@
#define PRSSTAT_CINS (0x00010000)
#define PRSSTAT_BREN (0x00000800)
#define PRSSTAT_BWEN (0x00000400)
#define PRSSTAT_SDSTB (0X00000008)
#define PRSSTAT_DLA (0x00000004)
#define PRSSTAT_CICHB (0x00000002)
#define PRSSTAT_CIDHB (0x00000001)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment