Commit 5e90470a866875984820dbc48c9b881e0ce773ba
Committed by
Tom Rini
1 parent
8f0b1e24e2
Exists in
v2017.01-smarct4x
and in
34 other branches
pepper: Implement Board Detection mechanism
AM335x-based 'Gumstix Pepper' SBCs and variants use different types of RAM (DDR2 vs DDR3 with DDR3 being the default). Detect the board type by reading the factory-programmed EEPROM [1] and use this to select any runtime boot options such as RAM type. [1] http://elinux.org/BeagleBoardPinMux#List_of_Vendor_and_Device_IDs Signed-off-by: Adam YH Lee <adam.yh.lee@gmail.com> Signed-off-by: Ash Charles <ashcharles@gmail.com>
Showing 4 changed files with 124 additions and 20 deletions Side-by-side Diff
board/gumstix/pepper/board.c
... | ... | @@ -33,6 +33,46 @@ |
33 | 33 | DECLARE_GLOBAL_DATA_PTR; |
34 | 34 | |
35 | 35 | #ifdef CONFIG_SPL_BUILD |
36 | +#define OSC (V_OSCK/1000000) | |
37 | + | |
38 | +static const struct ddr_data ddr3_data = { | |
39 | + .datardsratio0 = MT41K256M16HA125E_RD_DQS, | |
40 | + .datawdsratio0 = MT41K256M16HA125E_WR_DQS, | |
41 | + .datafwsratio0 = MT41K256M16HA125E_PHY_FIFO_WE, | |
42 | + .datawrsratio0 = MT41K256M16HA125E_PHY_WR_DATA, | |
43 | +}; | |
44 | + | |
45 | +static const struct cmd_control ddr3_cmd_ctrl_data = { | |
46 | + .cmd0csratio = MT41K256M16HA125E_RATIO, | |
47 | + .cmd0iclkout = MT41K256M16HA125E_INVERT_CLKOUT, | |
48 | + | |
49 | + .cmd1csratio = MT41K256M16HA125E_RATIO, | |
50 | + .cmd1iclkout = MT41K256M16HA125E_INVERT_CLKOUT, | |
51 | + | |
52 | + .cmd2csratio = MT41K256M16HA125E_RATIO, | |
53 | + .cmd2iclkout = MT41K256M16HA125E_INVERT_CLKOUT, | |
54 | +}; | |
55 | + | |
56 | +static struct emif_regs ddr3_emif_reg_data = { | |
57 | + .sdram_config = MT41K256M16HA125E_EMIF_SDCFG, | |
58 | + .ref_ctrl = MT41K256M16HA125E_EMIF_SDREF, | |
59 | + .sdram_tim1 = MT41K256M16HA125E_EMIF_TIM1, | |
60 | + .sdram_tim2 = MT41K256M16HA125E_EMIF_TIM2, | |
61 | + .sdram_tim3 = MT41K256M16HA125E_EMIF_TIM3, | |
62 | + .zq_config = MT41K256M16HA125E_ZQ_CFG, | |
63 | + .emif_ddr_phy_ctlr_1 = MT41K256M16HA125E_EMIF_READ_LATENCY, | |
64 | +}; | |
65 | + | |
66 | +const struct dpll_params dpll_ddr3 = {400, OSC-1, 1, -1, -1, -1, -1}; | |
67 | + | |
68 | +const struct ctrl_ioregs ioregs_ddr3 = { | |
69 | + .cm0ioctl = MT41K256M16HA125E_IOCTRL_VALUE, | |
70 | + .cm1ioctl = MT41K256M16HA125E_IOCTRL_VALUE, | |
71 | + .cm2ioctl = MT41K256M16HA125E_IOCTRL_VALUE, | |
72 | + .dt0ioctl = MT41K256M16HA125E_IOCTRL_VALUE, | |
73 | + .dt1ioctl = MT41K256M16HA125E_IOCTRL_VALUE, | |
74 | +}; | |
75 | + | |
36 | 76 | static const struct ddr_data ddr2_data = { |
37 | 77 | .datardsratio0 = MT47H128M16RT25E_RD_DQS, |
38 | 78 | .datafwsratio0 = MT47H128M16RT25E_PHY_FIFO_WE, |
... | ... | @@ -56,6 +96,70 @@ |
56 | 96 | .emif_ddr_phy_ctlr_1 = MT47H128M16RT25E_EMIF_READ_LATENCY, |
57 | 97 | }; |
58 | 98 | |
99 | +const struct dpll_params dpll_ddr2 = {266, OSC-1, 1, -1, -1, -1, -1}; | |
100 | + | |
101 | +const struct ctrl_ioregs ioregs_ddr2 = { | |
102 | + .cm0ioctl = MT47H128M16RT25E_IOCTRL_VALUE, | |
103 | + .cm1ioctl = MT47H128M16RT25E_IOCTRL_VALUE, | |
104 | + .cm2ioctl = MT47H128M16RT25E_IOCTRL_VALUE, | |
105 | + .dt0ioctl = MT47H128M16RT25E_IOCTRL_VALUE, | |
106 | + .dt1ioctl = MT47H128M16RT25E_IOCTRL_VALUE, | |
107 | +}; | |
108 | + | |
109 | +static int read_eeprom(struct pepper_board_id *header) | |
110 | +{ | |
111 | + if (i2c_probe(CONFIG_SYS_I2C_EEPROM_ADDR)) { | |
112 | + return -ENODEV; | |
113 | + } | |
114 | + | |
115 | + if (i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0, 1, (uchar *)header, | |
116 | + sizeof(struct pepper_board_id))) { | |
117 | + return -EIO; | |
118 | + } | |
119 | + | |
120 | + return 0; | |
121 | +} | |
122 | + | |
123 | +const struct dpll_params *get_dpll_ddr_params(void) | |
124 | +{ | |
125 | + struct pepper_board_id header; | |
126 | + | |
127 | + enable_i2c0_pin_mux(); | |
128 | + i2c_set_bus_num(0); | |
129 | + | |
130 | + if (read_eeprom(&header) < 0) | |
131 | + return &dpll_ddr3; | |
132 | + | |
133 | + switch (header.device_vendor) { | |
134 | + case GUMSTIX_PEPPER: | |
135 | + return &dpll_ddr2; | |
136 | + case GUMSTIX_PEPPER_DVI: | |
137 | + return &dpll_ddr3; | |
138 | + default: | |
139 | + return &dpll_ddr3; | |
140 | + } | |
141 | +} | |
142 | + | |
143 | +void sdram_init(void) | |
144 | +{ | |
145 | + const struct dpll_params *dpll = get_dpll_ddr_params(); | |
146 | + | |
147 | + /* | |
148 | + * Here we are assuming PLL clock reveals the type of RAM. | |
149 | + * DDR2 = 266 | |
150 | + * DDR3 = 400 | |
151 | + * Note that DDR3 is the default. | |
152 | + */ | |
153 | + if (dpll->m == 266) { | |
154 | + config_ddr(dpll->m, &ioregs_ddr2, &ddr2_data, | |
155 | + &ddr2_cmd_ctrl_data, &ddr2_emif_reg_data, 0); | |
156 | + } | |
157 | + else if (dpll->m == 400) { | |
158 | + config_ddr(dpll->m, &ioregs_ddr3, &ddr3_data, | |
159 | + &ddr3_cmd_ctrl_data, &ddr3_emif_reg_data, 0); | |
160 | + } | |
161 | +} | |
162 | + | |
59 | 163 | #ifdef CONFIG_SPL_OS_BOOT |
60 | 164 | int spl_start_uboot(void) |
61 | 165 | { |
... | ... | @@ -64,14 +168,6 @@ |
64 | 168 | } |
65 | 169 | #endif |
66 | 170 | |
67 | -#define OSC (V_OSCK/1000000) | |
68 | -const struct dpll_params dpll_ddr = {266, OSC-1, 1, -1, -1, -1, -1}; | |
69 | - | |
70 | -const struct dpll_params *get_dpll_ddr_params(void) | |
71 | -{ | |
72 | - return &dpll_ddr; | |
73 | -} | |
74 | - | |
75 | 171 | void set_uart_mux_conf(void) |
76 | 172 | { |
77 | 173 | enable_uart0_pin_mux(); |
78 | 174 | |
... | ... | @@ -82,19 +178,7 @@ |
82 | 178 | enable_board_pin_mux(); |
83 | 179 | } |
84 | 180 | |
85 | -const struct ctrl_ioregs ioregs = { | |
86 | - .cm0ioctl = MT47H128M16RT25E_IOCTRL_VALUE, | |
87 | - .cm1ioctl = MT47H128M16RT25E_IOCTRL_VALUE, | |
88 | - .cm2ioctl = MT47H128M16RT25E_IOCTRL_VALUE, | |
89 | - .dt0ioctl = MT47H128M16RT25E_IOCTRL_VALUE, | |
90 | - .dt1ioctl = MT47H128M16RT25E_IOCTRL_VALUE, | |
91 | -}; | |
92 | 181 | |
93 | -void sdram_init(void) | |
94 | -{ | |
95 | - config_ddr(266, &ioregs, &ddr2_data, | |
96 | - &ddr2_cmd_ctrl_data, &ddr2_emif_reg_data, 0); | |
97 | -} | |
98 | 182 | #endif |
99 | 183 | |
100 | 184 | int board_init(void) |
board/gumstix/pepper/board.h
... | ... | @@ -9,6 +9,18 @@ |
9 | 9 | #ifndef _BOARD_H_ |
10 | 10 | #define _BOARD_H_ |
11 | 11 | |
12 | +#define GUMSTIX_PEPPER 0x30000200 | |
13 | +#define GUMSTIX_PEPPER_DVI 0x31000200 | |
14 | + | |
15 | +struct pepper_board_id { | |
16 | + unsigned int device_vendor; | |
17 | + unsigned char revision; | |
18 | + unsigned char content; | |
19 | + char fab_revision[8]; | |
20 | + char env_var[16]; | |
21 | + char en_setting[64]; | |
22 | +}; | |
23 | + | |
12 | 24 | /* |
13 | 25 | * We must be able to enable uart0, for initial output. We then have a |
14 | 26 | * main pinmux function that can be overridden to enable all other pinmux that |
... | ... | @@ -16,5 +28,6 @@ |
16 | 28 | */ |
17 | 29 | void enable_uart0_pin_mux(void); |
18 | 30 | void enable_board_pin_mux(void); |
31 | +void enable_i2c0_pin_mux(void); | |
19 | 32 | #endif |
board/gumstix/pepper/mux.c
include/configs/pepper.h