*/
int ddr3_init(void);
+/* Auto Voltage Scaling */
+#if defined(CONFIG_ARMADA_38X) || defined(CONFIG_ARMADA_39X)
+void mv_avs_init(void);
+#else
+static inline void mv_avs_init(void) {}
+#endif
+
/*
* get_ref_clk
*
value = reg_read(DEV_VERSION_ID_REG);
return (value & (REVISON_ID_MASK)) >> REVISON_ID_OFFS;
}
+
+void mv_avs_init(void)
+{
+ u32 sar_freq;
+
+ if (!(IS_ENABLED(CONFIG_ARMADA_38X) || IS_ENABLED(CONFIG_ARMADA_39X)))
+ return;
+
+ reg_write(AVS_DEBUG_CNTR_REG, AVS_DEBUG_CNTR_DEFAULT_VALUE);
+ reg_write(AVS_DEBUG_CNTR_REG, AVS_DEBUG_CNTR_DEFAULT_VALUE);
+
+ sar_freq = reg_read(DEVICE_SAMPLE_AT_RESET1_REG);
+ sar_freq = sar_freq >> SAR_FREQ_OFFSET & SAR_FREQ_MASK;
+
+ /* Set AVS value only for core frequency of 1600MHz or less.
+ * For higher frequency leave the default value.
+ */
+ if (sar_freq <= 0xd) {
+ u32 avs_reg_data = reg_read(AVS_ENABLED_CONTROL);
+
+ avs_reg_data &= ~(AVS_LOW_VDD_LIMIT_MASK
+ | AVS_HIGH_VDD_LIMIT_MASK);
+ avs_reg_data |= AVS_LOW_VDD_SLOW_VAL | AVS_HIGH_VDD_SLOW_VAL;
+ reg_write(AVS_ENABLED_CONTROL, avs_reg_data);
+ }
+}
#define DEV_ID_REG_DEVICE_ID_OFFS 16
#define DEV_ID_REG_DEVICE_ID_MASK 0xffff0000
+#define SAR_FREQ_OFFSET 10
+#define SAR_FREQ_MASK 0x1f
#define SAR_DEV_ID_OFFS 27
#define SAR_DEV_ID_MASK 0x7
#define AVS_LOW_VDD_LIMIT_OFFS 4
#define AVS_LOW_VDD_LIMIT_MASK (0xff << AVS_LOW_VDD_LIMIT_OFFS)
#define AVS_LOW_VDD_LIMIT_VAL (0x27 << AVS_LOW_VDD_LIMIT_OFFS)
+#define AVS_LOW_VDD_SLOW_VAL (0x23 << AVS_LOW_VDD_LIMIT_OFFS)
#define AVS_HIGH_VDD_LIMIT_OFFS 12
#define AVS_HIGH_VDD_LIMIT_MASK (0xff << AVS_HIGH_VDD_LIMIT_OFFS)
#define AVS_HIGH_VDD_LIMIT_VAL (0x27 << AVS_HIGH_VDD_LIMIT_OFFS)
+#define AVS_HIGH_VDD_SLOW_VAL (0x23 << AVS_HIGH_VDD_LIMIT_OFFS)
/* Board ID numbers */
#define MARVELL_BOARD_ID_MASK 0x10
ddr3_init();
#endif
+ /* Initialize Auto Voltage Scaling */
+ mv_avs_init();
+
/*
* Return to the BootROM to continue the Marvell xmodem
* UART boot protocol. As initiated by the kwboot tool.