aboutsummaryrefslogtreecommitdiff
path: root/arch/powerpc/cpu/mpc8xxx/ddr/main.c
diff options
context:
space:
mode:
authorKumar Gala <galak@kernel.crashing.org>2011-01-31 22:18:47 -0600
committerKumar Gala <galak@kernel.crashing.org>2011-04-04 09:24:41 -0500
commitc39f44dc6f5ae843d5def511f6e71d4b012dc598 (patch)
treed863c3a3e87967d01e4de1021bd20abe3b57af7a /arch/powerpc/cpu/mpc8xxx/ddr/main.c
parent5df4b0ad0dff3cef1bd6660bcc8cba028c80adcb (diff)
powerpc/8xxx: Refactor fsl_ddr_get_spd into common code from board
Move fsl_ddr_get_spd into common mpc8xxx/ddr/main.c as most boards pretty much do the same thing. The only variations are in how many controllers or DIMMs per controller exist. To make this work we standardize on the names of the SPD_EEPROM_ADDRESS defines based on the use case of the board. We allow boards to override get_spd to either do board specific fixups to the SPD data or deal with any unique behavior of how the SPD eeproms are wired up. Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/cpu/mpc8xxx/ddr/main.c')
-rw-r--r--arch/powerpc/cpu/mpc8xxx/ddr/main.c63
1 files changed, 60 insertions, 3 deletions
diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/main.c b/arch/powerpc/cpu/mpc8xxx/ddr/main.c
index bb96d66a9..c8fa12353 100644
--- a/arch/powerpc/cpu/mpc8xxx/ddr/main.c
+++ b/arch/powerpc/cpu/mpc8xxx/ddr/main.c
@@ -13,6 +13,7 @@
*/
#include <common.h>
+#include <i2c.h>
#include <asm/fsl_ddr_sdram.h>
#include "ddr.h"
@@ -26,9 +27,65 @@ extern void fsl_ddr_set_lawbar(
extern void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
unsigned int ctrl_num);
-/* Board-specific functions defined in each board's ddr.c */
-extern void fsl_ddr_get_spd(generic_spd_eeprom_t *ctrl_dimms_spd,
- unsigned int ctrl_num);
+#if defined(SPD_EEPROM_ADDRESS) || \
+ defined(SPD_EEPROM_ADDRESS1) || defined(SPD_EEPROM_ADDRESS2) || \
+ defined(SPD_EEPROM_ADDRESS3) || defined(SPD_EEPROM_ADDRESS4)
+#if (CONFIG_NUM_DDR_CONTROLLERS == 1) && (CONFIG_DIMM_SLOTS_PER_CTLR == 1)
+u8 spd_i2c_addr[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR] = {
+ [0][0] = SPD_EEPROM_ADDRESS,
+};
+#endif
+#if (CONFIG_NUM_DDR_CONTROLLERS == 2) && (CONFIG_DIMM_SLOTS_PER_CTLR == 1)
+u8 spd_i2c_addr[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR] = {
+ [0][0] = SPD_EEPROM_ADDRESS1, /* controller 1 */
+ [1][0] = SPD_EEPROM_ADDRESS2, /* controller 2 */
+};
+#endif
+#if (CONFIG_NUM_DDR_CONTROLLERS == 2) && (CONFIG_DIMM_SLOTS_PER_CTLR == 2)
+u8 spd_i2c_addr[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR] = {
+ [0][0] = SPD_EEPROM_ADDRESS1, /* controller 1 */
+ [0][1] = SPD_EEPROM_ADDRESS2, /* controller 1 */
+ [1][0] = SPD_EEPROM_ADDRESS3, /* controller 2 */
+ [1][1] = SPD_EEPROM_ADDRESS4, /* controller 2 */
+};
+#endif
+
+static void __get_spd(generic_spd_eeprom_t *spd, u8 i2c_address)
+{
+ int ret = i2c_read(i2c_address, 0, 1, (uchar *)spd,
+ sizeof(generic_spd_eeprom_t));
+
+ if (ret) {
+ printf("DDR: failed to read SPD from address %u\n", i2c_address);
+ memset(spd, 0, sizeof(generic_spd_eeprom_t));
+ }
+}
+
+__attribute__((weak, alias("__get_spd")))
+void get_spd(generic_spd_eeprom_t *spd, u8 i2c_address);
+
+void fsl_ddr_get_spd(generic_spd_eeprom_t *ctrl_dimms_spd,
+ unsigned int ctrl_num)
+{
+ unsigned int i;
+ unsigned int i2c_address = 0;
+
+ if (ctrl_num >= CONFIG_NUM_DDR_CONTROLLERS) {
+ printf("%s unexpected ctrl_num = %u\n", __FUNCTION__, ctrl_num);
+ return;
+ }
+
+ for (i = 0; i < CONFIG_DIMM_SLOTS_PER_CTLR; i++) {
+ i2c_address = spd_i2c_addr[ctrl_num][i];
+ get_spd(&(ctrl_dimms_spd[i]), i2c_address);
+ }
+}
+#else
+void fsl_ddr_get_spd(generic_spd_eeprom_t *ctrl_dimms_spd,
+ unsigned int ctrl_num)
+{
+}
+#endif /* SPD_EEPROM_ADDRESSx */
/*
* ASSUMPTIONS: