1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright 2011 Freescale Semiconductor
4 * Author: Shengzhou Liu <Shengzhou.Liu@freescale.com>
6 * This file provides support for the QIXIS of some Freescale reference boards.
12 #include <linux/compiler.h>
13 #include <linux/time.h>
17 #ifndef QIXIS_LBMAP_BRDCFG_REG
19 * For consistency with existing platforms
21 #define QIXIS_LBMAP_BRDCFG_REG 0x00
24 #ifndef QIXIS_RCFG_CTL_RECONFIG_IDLE
25 #define QIXIS_RCFG_CTL_RECONFIG_IDLE 0x20
27 #ifndef QIXIS_RCFG_CTL_RECONFIG_START
28 #define QIXIS_RCFG_CTL_RECONFIG_START 0x21
31 #ifdef CONFIG_SYS_I2C_FPGA_ADDR
32 u8
qixis_read_i2c(unsigned int reg
)
34 return i2c_reg_read(CONFIG_SYS_I2C_FPGA_ADDR
, reg
);
37 void qixis_write_i2c(unsigned int reg
, u8 value
)
40 i2c_reg_write(CONFIG_SYS_I2C_FPGA_ADDR
, reg
, val
);
45 u8
qixis_read(unsigned int reg
)
47 void *p
= (void *)QIXIS_BASE
;
52 void qixis_write(unsigned int reg
, u8 value
)
54 void *p
= (void *)QIXIS_BASE
;
56 out_8(p
+ reg
, value
);
60 u16
qixis_read_minor(void)
64 /* this data is in little endian */
65 QIXIS_WRITE(tagdata
, 5);
66 minor
= QIXIS_READ(tagdata
);
67 QIXIS_WRITE(tagdata
, 6);
68 minor
+= QIXIS_READ(tagdata
) << 8;
73 char *qixis_read_time(char *result
)
78 /* timestamp is in 32-bit big endian */
79 for (i
= 8; i
<= 11; i
++) {
80 QIXIS_WRITE(tagdata
, i
);
81 time
= (time
<< 8) + QIXIS_READ(tagdata
);
84 return ctime_r(&time
, result
);
87 char *qixis_read_tag(char *buf
)
92 for (i
= 16; i
<= 63; i
++) {
93 QIXIS_WRITE(tagdata
, i
);
94 tag
= QIXIS_READ(tagdata
);
106 * return the string of binary of u8 in the format of
107 * 1010 10_0. The masked bit is filled as underscore.
109 const char *byte_to_binary_mask(u8 val
, u8 mask
, char *buf
)
115 for (i
= 0x80; i
> 0x08 ; i
>>= 1, ptr
++)
116 *ptr
= (val
& i
) ? '1' : ((mask
& i
) ? '_' : '0');
118 for (i
= 0x08; i
> 0 ; i
>>= 1, ptr
++)
119 *ptr
= (val
& i
) ? '1' : ((mask
& i
) ? '_' : '0');
126 #ifdef QIXIS_RST_FORCE_MEM
127 void board_assert_mem_reset(void)
131 rst
= QIXIS_READ(rst_frc
[0]);
132 if (!(rst
& QIXIS_RST_FORCE_MEM
))
133 QIXIS_WRITE(rst_frc
[0], rst
| QIXIS_RST_FORCE_MEM
);
136 void board_deassert_mem_reset(void)
140 rst
= QIXIS_READ(rst_frc
[0]);
141 if (rst
& QIXIS_RST_FORCE_MEM
)
142 QIXIS_WRITE(rst_frc
[0], rst
& ~QIXIS_RST_FORCE_MEM
);
146 #ifndef CONFIG_SPL_BUILD
147 static void qixis_reset(void)
149 QIXIS_WRITE(rst_ctl
, QIXIS_RST_CTL_RESET
);
152 #ifdef QIXIS_LBMAP_ALTBANK
153 static void qixis_bank_reset(void)
155 QIXIS_WRITE(rcfg_ctl
, QIXIS_RCFG_CTL_RECONFIG_IDLE
);
156 QIXIS_WRITE(rcfg_ctl
, QIXIS_RCFG_CTL_RECONFIG_START
);
160 static void __maybe_unused
set_lbmap(int lbmap
)
164 reg
= QIXIS_READ(brdcfg
[QIXIS_LBMAP_BRDCFG_REG
]);
165 reg
= (reg
& ~QIXIS_LBMAP_MASK
) | lbmap
;
166 QIXIS_WRITE(brdcfg
[QIXIS_LBMAP_BRDCFG_REG
], reg
);
169 static void __maybe_unused
set_rcw_src(int rcw_src
)
171 #ifdef CONFIG_NXP_LSCH3_2
172 QIXIS_WRITE(dutcfg
[0], (rcw_src
& 0xff));
176 reg
= QIXIS_READ(dutcfg
[1]);
177 reg
= (reg
& ~1) | (rcw_src
& 1);
178 QIXIS_WRITE(dutcfg
[1], reg
);
179 QIXIS_WRITE(dutcfg
[0], (rcw_src
>> 1) & 0xff);
183 static void qixis_dump_regs(void)
187 printf("id = %02x\n", QIXIS_READ(id
));
188 printf("arch = %02x\n", QIXIS_READ(arch
));
189 printf("scver = %02x\n", QIXIS_READ(scver
));
190 printf("model = %02x\n", QIXIS_READ(model
));
191 printf("rst_ctl = %02x\n", QIXIS_READ(rst_ctl
));
192 printf("aux = %02x\n", QIXIS_READ(aux
));
193 for (i
= 0; i
< 16; i
++)
194 printf("brdcfg%02d = %02x\n", i
, QIXIS_READ(brdcfg
[i
]));
195 for (i
= 0; i
< 16; i
++)
196 printf("dutcfg%02d = %02x\n", i
, QIXIS_READ(dutcfg
[i
]));
197 printf("sclk = %02x%02x%02x\n", QIXIS_READ(sclk
[0]),
198 QIXIS_READ(sclk
[1]), QIXIS_READ(sclk
[2]));
199 printf("dclk = %02x%02x%02x\n", QIXIS_READ(dclk
[0]),
200 QIXIS_READ(dclk
[1]), QIXIS_READ(dclk
[2]));
201 printf("aux = %02x\n", QIXIS_READ(aux
));
202 printf("watch = %02x\n", QIXIS_READ(watch
));
203 printf("ctl_sys = %02x\n", QIXIS_READ(ctl_sys
));
204 printf("rcw_ctl = %02x\n", QIXIS_READ(rcw_ctl
));
205 printf("present = %02x\n", QIXIS_READ(present
));
206 printf("present2 = %02x\n", QIXIS_READ(present2
));
207 printf("clk_spd = %02x\n", QIXIS_READ(clk_spd
));
208 printf("stat_dut = %02x\n", QIXIS_READ(stat_dut
));
209 printf("stat_sys = %02x\n", QIXIS_READ(stat_sys
));
210 printf("stat_alrm = %02x\n", QIXIS_READ(stat_alrm
));
213 void __weak
qixis_dump_switch(void)
215 puts("Reverse engineering switch is not implemented for this board\n");
218 static int qixis_reset_cmd(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char * const argv
[])
223 set_lbmap(QIXIS_LBMAP_DFLTBANK
);
225 } else if (strcmp(argv
[1], "altbank") == 0) {
226 #ifdef QIXIS_LBMAP_ALTBANK
227 set_lbmap(QIXIS_LBMAP_ALTBANK
);
230 printf("No Altbank!\n");
232 } else if (strcmp(argv
[1], "nand") == 0) {
233 #ifdef QIXIS_LBMAP_NAND
234 QIXIS_WRITE(rst_ctl
, 0x30);
235 QIXIS_WRITE(rcfg_ctl
, 0);
236 set_lbmap(QIXIS_LBMAP_NAND
);
237 set_rcw_src(QIXIS_RCW_SRC_NAND
);
238 QIXIS_WRITE(rcfg_ctl
, QIXIS_RCFG_CTL_RECONFIG_IDLE
);
239 QIXIS_WRITE(rcfg_ctl
, QIXIS_RCFG_CTL_RECONFIG_START
);
241 printf("Not implemented\n");
243 } else if (strcmp(argv
[1], "sd") == 0) {
244 #ifdef QIXIS_LBMAP_SD
245 QIXIS_WRITE(rst_ctl
, 0x30);
246 QIXIS_WRITE(rcfg_ctl
, 0);
247 #ifdef NON_EXTENDED_DUTCFG
248 QIXIS_WRITE(dutcfg
[0], QIXIS_RCW_SRC_SD
);
250 set_lbmap(QIXIS_LBMAP_SD
);
251 set_rcw_src(QIXIS_RCW_SRC_SD
);
253 QIXIS_WRITE(rcfg_ctl
, QIXIS_RCFG_CTL_RECONFIG_IDLE
);
254 QIXIS_WRITE(rcfg_ctl
, QIXIS_RCFG_CTL_RECONFIG_START
);
256 printf("Not implemented\n");
258 } else if (strcmp(argv
[1], "ifc") == 0) {
259 #ifdef QIXIS_LBMAP_IFC
260 QIXIS_WRITE(rst_ctl
, 0x30);
261 QIXIS_WRITE(rcfg_ctl
, 0);
262 set_lbmap(QIXIS_LBMAP_IFC
);
263 set_rcw_src(QIXIS_RCW_SRC_IFC
);
264 QIXIS_WRITE(rcfg_ctl
, QIXIS_RCFG_CTL_RECONFIG_IDLE
);
265 QIXIS_WRITE(rcfg_ctl
, QIXIS_RCFG_CTL_RECONFIG_START
);
267 printf("Not implemented\n");
269 } else if (strcmp(argv
[1], "emmc") == 0) {
270 #ifdef QIXIS_LBMAP_EMMC
271 QIXIS_WRITE(rst_ctl
, 0x30);
272 QIXIS_WRITE(rcfg_ctl
, 0);
273 set_lbmap(QIXIS_LBMAP_EMMC
);
274 set_rcw_src(QIXIS_RCW_SRC_EMMC
);
275 QIXIS_WRITE(rcfg_ctl
, QIXIS_RCFG_CTL_RECONFIG_IDLE
);
276 QIXIS_WRITE(rcfg_ctl
, QIXIS_RCFG_CTL_RECONFIG_START
);
278 printf("Not implemented\n");
280 } else if (strcmp(argv
[1], "sd_qspi") == 0) {
281 #ifdef QIXIS_LBMAP_SD_QSPI
282 QIXIS_WRITE(rst_ctl
, 0x30);
283 QIXIS_WRITE(rcfg_ctl
, 0);
284 set_lbmap(QIXIS_LBMAP_SD_QSPI
);
285 set_rcw_src(QIXIS_RCW_SRC_SD
);
286 qixis_write_i2c(offsetof(struct qixis
, rcfg_ctl
),
287 QIXIS_RCFG_CTL_RECONFIG_IDLE
);
288 qixis_write_i2c(offsetof(struct qixis
, rcfg_ctl
),
289 QIXIS_RCFG_CTL_RECONFIG_START
);
291 printf("Not implemented\n");
293 } else if (strcmp(argv
[1], "qspi") == 0) {
294 #ifdef QIXIS_LBMAP_QSPI
295 QIXIS_WRITE(rst_ctl
, 0x30);
296 QIXIS_WRITE(rcfg_ctl
, 0);
297 set_lbmap(QIXIS_LBMAP_QSPI
);
298 set_rcw_src(QIXIS_RCW_SRC_QSPI
);
299 qixis_write_i2c(offsetof(struct qixis
, rcfg_ctl
),
300 QIXIS_RCFG_CTL_RECONFIG_IDLE
);
301 qixis_write_i2c(offsetof(struct qixis
, rcfg_ctl
),
302 QIXIS_RCFG_CTL_RECONFIG_START
);
304 printf("Not implemented\n");
306 } else if (strcmp(argv
[1], "watchdog") == 0) {
307 static char *period
[9] = {"2s", "4s", "8s", "16s", "32s",
308 "1min", "2min", "4min", "8min"};
309 u8 rcfg
= QIXIS_READ(rcfg_ctl
);
311 if (argv
[2] == NULL
) {
312 printf("qixis watchdog <watchdog_period>\n");
315 for (i
= 0; i
< ARRAY_SIZE(period
); i
++) {
316 if (strcmp(argv
[2], period
[i
]) == 0) {
317 /* disable watchdog */
318 QIXIS_WRITE(rcfg_ctl
,
319 rcfg
& ~QIXIS_RCFG_CTL_WATCHDOG_ENBLE
);
320 QIXIS_WRITE(watch
, ((i
<<2) - 1));
321 QIXIS_WRITE(rcfg_ctl
, rcfg
);
325 } else if (strcmp(argv
[1], "dump") == 0) {
328 } else if (strcmp(argv
[1], "switch") == 0) {
332 printf("Invalid option: %s\n", argv
[1]);
340 qixis_reset
, CONFIG_SYS_MAXARGS
, 1, qixis_reset_cmd
,
341 "Reset the board using the FPGA sequencer",
342 "- hard reset to default bank\n"
343 "qixis_reset altbank - reset to alternate bank\n"
344 "qixis_reset nand - reset to nand\n"
345 "qixis_reset sd - reset to sd\n"
346 "qixis_reset sd_qspi - reset to sd with qspi support\n"
347 "qixis_reset qspi - reset to qspi\n"
348 "qixis watchdog <watchdog_period> - set the watchdog period\n"
349 " period: 1s 2s 4s 8s 16s 32s 1min 2min 4min 8min\n"
350 "qixis_reset dump - display the QIXIS registers\n"
351 "qixis_reset switch - display switch\n"