Adds SERDES voltage and reset SERDES lanes API and makes
enable/disable DDR controller support 0.9V API common.
Signed-off-by: Ashish Kumar
Signed-off-by: Rajesh Bhagat
---
Changes in v7:
- Used APIs clr/set/clrsetbits_le32() for code clarity
Changes in v6:
- Corrected indentation/alignment issues at various places
- Changed NULL ENTRY in srds_prctl_info array to id as zero
- Corrected the PLL Reset logic, moved code inside for loop
- Used error code(-EINVAL) in setup_serdes_volt API
Changes in v5:
- Moved local macros to static functions
- Used array to handle PRCTL mask and shift operations
Changes in v4:
- Added local macros instead of magical numbers
- Created macros to remove duplicate code
Changes in v3:
Restructured LS1088A VID support to use common VID driver
Cosmetic review comments fixed
Added __iomem for accessing registers
Changes in v2:
Checkpatch errors fixed
.../cpu/armv8/fsl-layerscape/fsl_lsch3_serdes.c| 286 +
arch/arm/cpu/armv8/fsl-layerscape/soc.c| 39 +++
.../include/asm/arch-fsl-layerscape/fsl_serdes.h | 2 +-
.../include/asm/arch-fsl-layerscape/immap_lsch3.h | 34 +++
arch/arm/include/asm/arch-fsl-layerscape/soc.h | 1 +
5 files changed, 361 insertions(+), 1 deletion(-)
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_serdes.c
b/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_serdes.c
index 179cac6..8dea8df 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_serdes.c
+++ b/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_serdes.c
@@ -158,6 +158,292 @@ void serdes_init(u32 sd, u32 sd_addr, u32 rcwsr, u32
sd_prctl_mask,
serdes_prtcl_map[NONE] = 1;
}
+__weak int get_serdes_volt(void)
+{
+ return -1;
+}
+
+__weak int set_serdes_volt(int svdd)
+{
+ return -1;
+}
+
+#define LNAGCR0_RT_RSTB0x0060
+
+#define RSTCTL_RESET_MASK 0x00E0
+
+#define RSTCTL_RSTREQ 0x8000
+#define RSTCTL_RST_DONE0x4000
+#define RSTCTL_RSTERR 0x2000
+
+#define RSTCTL_SDEN0x0020
+#define RSTCTL_SDRST_B 0x0040
+#define RSTCTL_PLLRST_B0x0080
+
+#define TCALCR_CALRST_B0x0800
+
+struct serdes_prctl_info {
+ u32 id;
+ u32 mask;
+ u32 shift;
+};
+
+struct serdes_prctl_info srds_prctl_info[] = {
+#ifdef CONFIG_SYS_FSL_SRDS_1
+ {.id = 1,
+.mask = FSL_CHASSIS3_SRDS1_PRTCL_MASK,
+.shift = FSL_CHASSIS3_SRDS1_PRTCL_SHIFT
+ },
+
+#endif
+#ifdef CONFIG_SYS_FSL_SRDS_2
+ {.id = 2,
+.mask = FSL_CHASSIS3_SRDS2_PRTCL_MASK,
+.shift = FSL_CHASSIS3_SRDS2_PRTCL_SHIFT
+ },
+#endif
+ {.id = 0, .mask = 0, .shift = 0} /* NULL ENTRY */
+};
+
+static int get_serdes_prctl_info_idx(u32 serdes_id)
+{
+ int pos = 0;
+ struct serdes_prctl_info *srds_info;
+
+ /* loop until NULL ENTRY defined by .id=0 */
+ for (srds_info = srds_prctl_info; srds_info->id != 0;
+srds_info++, pos++) {
+ if (srds_info->id == serdes_id)
+ return pos;
+ }
+
+ return -1;
+}
+
+static void do_enabled_lanes_reset(u32 serdes_id, u32 cfg,
+ struct ccsr_serdes __iomem *serdes_base,
+ bool cmplt)
+{
+ int i, pos;
+ u32 cfg_tmp;
+
+ pos = get_serdes_prctl_info_idx(serdes_id);
+ if (pos == -1) {
+ printf("invalid serdes_id %d\n", serdes_id);
+ return;
+ }
+
+ cfg_tmp = cfg & srds_prctl_info[pos].mask;
+ cfg_tmp >>= srds_prctl_info[pos].shift;
+
+ for (i = 0; i < 4 && cfg_tmp & (0xf << (3 - i)); i++) {
+ if (cmplt)
+ setbits_le32(&serdes_base->lane[i].gcr0,
+LNAGCR0_RT_RSTB);
+ else
+ clrbits_le32(&serdes_base->lane[i].gcr0,
+LNAGCR0_RT_RSTB);
+ }
+}
+
+static void do_pll_reset(u32 cfg,
+struct ccsr_serdes __iomem *serdes_base)
+{
+ int i;
+
+ for (i = 0; i < 2 && !(cfg & (0x1 << (1 - i))); i++) {
+ clrbits_le32(&serdes_base->bank[i].rstctl,
+RSTCTL_RESET_MASK);
+ udelay(1);
+
+ setbits_le32(&serdes_base->bank[i].rstctl,
+RSTCTL_RSTREQ);
+ }
+ udelay(1);
+}
+
+static void do_rx_tx_cal_reset(struct ccsr_serdes __iomem *serdes_base)
+{
+