1f3a8e2b7SMingkai Hu /*
2f3a8e2b7SMingkai Hu * Copyright 2015 Freescale Semiconductor
3f3a8e2b7SMingkai Hu *
4f3a8e2b7SMingkai Hu * SPDX-License-Identifier: GPL-2.0+
5f3a8e2b7SMingkai Hu *
6f3a8e2b7SMingkai Hu * Freescale LS1043ARDB board-specific CPLD controlling supports.
7f3a8e2b7SMingkai Hu */
8f3a8e2b7SMingkai Hu
9f3a8e2b7SMingkai Hu #include <common.h>
10f3a8e2b7SMingkai Hu #include <command.h>
11f3a8e2b7SMingkai Hu #include <asm/io.h>
12f3a8e2b7SMingkai Hu #include "cpld.h"
13f3a8e2b7SMingkai Hu
cpld_read(unsigned int reg)14f3a8e2b7SMingkai Hu u8 cpld_read(unsigned int reg)
15f3a8e2b7SMingkai Hu {
16f3a8e2b7SMingkai Hu void *p = (void *)CONFIG_SYS_CPLD_BASE;
17f3a8e2b7SMingkai Hu
18f3a8e2b7SMingkai Hu return in_8(p + reg);
19f3a8e2b7SMingkai Hu }
20f3a8e2b7SMingkai Hu
cpld_write(unsigned int reg,u8 value)21f3a8e2b7SMingkai Hu void cpld_write(unsigned int reg, u8 value)
22f3a8e2b7SMingkai Hu {
23f3a8e2b7SMingkai Hu void *p = (void *)CONFIG_SYS_CPLD_BASE;
24f3a8e2b7SMingkai Hu
25f3a8e2b7SMingkai Hu out_8(p + reg, value);
26f3a8e2b7SMingkai Hu }
27f3a8e2b7SMingkai Hu
28f3a8e2b7SMingkai Hu /* Set the boot bank to the alternate bank */
cpld_set_altbank(void)29f3a8e2b7SMingkai Hu void cpld_set_altbank(void)
30f3a8e2b7SMingkai Hu {
31*869bf868SQianyu Gong u16 reg = CPLD_CFG_RCW_SRC_NOR;
32f3a8e2b7SMingkai Hu u8 reg4 = CPLD_READ(soft_mux_on);
33*869bf868SQianyu Gong u8 reg5 = (u8)(reg >> 1);
34*869bf868SQianyu Gong u8 reg6 = (u8)(reg & 1);
35f3a8e2b7SMingkai Hu u8 reg7 = CPLD_READ(vbank);
36f3a8e2b7SMingkai Hu
37*869bf868SQianyu Gong cpld_rev_bit(®5);
38*869bf868SQianyu Gong
39*869bf868SQianyu Gong CPLD_WRITE(soft_mux_on, reg4 | CPLD_SW_MUX_BANK_SEL | 1);
40*869bf868SQianyu Gong
41*869bf868SQianyu Gong CPLD_WRITE(cfg_rcw_src1, reg5);
42*869bf868SQianyu Gong CPLD_WRITE(cfg_rcw_src2, reg6);
43f3a8e2b7SMingkai Hu
44f3a8e2b7SMingkai Hu reg7 = (reg7 & ~CPLD_BANK_SEL_MASK) | CPLD_BANK_SEL_ALTBANK;
45f3a8e2b7SMingkai Hu CPLD_WRITE(vbank, reg7);
46f3a8e2b7SMingkai Hu
47f3a8e2b7SMingkai Hu CPLD_WRITE(system_rst, 1);
48f3a8e2b7SMingkai Hu }
49f3a8e2b7SMingkai Hu
50f3a8e2b7SMingkai Hu /* Set the boot bank to the default bank */
cpld_set_defbank(void)51f3a8e2b7SMingkai Hu void cpld_set_defbank(void)
52f3a8e2b7SMingkai Hu {
53*869bf868SQianyu Gong u16 reg = CPLD_CFG_RCW_SRC_NOR;
54*869bf868SQianyu Gong u8 reg4 = CPLD_READ(soft_mux_on);
55*869bf868SQianyu Gong u8 reg5 = (u8)(reg >> 1);
56*869bf868SQianyu Gong u8 reg6 = (u8)(reg & 1);
57*869bf868SQianyu Gong
58*869bf868SQianyu Gong cpld_rev_bit(®5);
59*869bf868SQianyu Gong
60*869bf868SQianyu Gong CPLD_WRITE(soft_mux_on, reg4 | CPLD_SW_MUX_BANK_SEL | 1);
61*869bf868SQianyu Gong
62*869bf868SQianyu Gong CPLD_WRITE(cfg_rcw_src1, reg5);
63*869bf868SQianyu Gong CPLD_WRITE(cfg_rcw_src2, reg6);
64*869bf868SQianyu Gong
65*869bf868SQianyu Gong CPLD_WRITE(vbank, 0);
66*869bf868SQianyu Gong
67*869bf868SQianyu Gong CPLD_WRITE(system_rst, 1);
68f3a8e2b7SMingkai Hu }
69f3a8e2b7SMingkai Hu
cpld_set_nand(void)703ad44729SGong Qianyu void cpld_set_nand(void)
713ad44729SGong Qianyu {
723ad44729SGong Qianyu u16 reg = CPLD_CFG_RCW_SRC_NAND;
733ad44729SGong Qianyu u8 reg5 = (u8)(reg >> 1);
743ad44729SGong Qianyu u8 reg6 = (u8)(reg & 1);
753ad44729SGong Qianyu
763ad44729SGong Qianyu cpld_rev_bit(®5);
773ad44729SGong Qianyu
783ad44729SGong Qianyu CPLD_WRITE(soft_mux_on, 1);
793ad44729SGong Qianyu
803ad44729SGong Qianyu CPLD_WRITE(cfg_rcw_src1, reg5);
813ad44729SGong Qianyu CPLD_WRITE(cfg_rcw_src2, reg6);
823ad44729SGong Qianyu
833ad44729SGong Qianyu CPLD_WRITE(system_rst, 1);
843ad44729SGong Qianyu }
853ad44729SGong Qianyu
cpld_set_sd(void)86c7ca8b07SGong Qianyu void cpld_set_sd(void)
87c7ca8b07SGong Qianyu {
88c7ca8b07SGong Qianyu u16 reg = CPLD_CFG_RCW_SRC_SD;
89c7ca8b07SGong Qianyu u8 reg5 = (u8)(reg >> 1);
90c7ca8b07SGong Qianyu u8 reg6 = (u8)(reg & 1);
91c7ca8b07SGong Qianyu
92c7ca8b07SGong Qianyu cpld_rev_bit(®5);
93c7ca8b07SGong Qianyu
94c7ca8b07SGong Qianyu CPLD_WRITE(soft_mux_on, 1);
95c7ca8b07SGong Qianyu
96c7ca8b07SGong Qianyu CPLD_WRITE(cfg_rcw_src1, reg5);
97c7ca8b07SGong Qianyu CPLD_WRITE(cfg_rcw_src2, reg6);
98c7ca8b07SGong Qianyu
99c7ca8b07SGong Qianyu CPLD_WRITE(system_rst, 1);
100c7ca8b07SGong Qianyu }
101f3a8e2b7SMingkai Hu #ifdef DEBUG
cpld_dump_regs(void)102f3a8e2b7SMingkai Hu static void cpld_dump_regs(void)
103f3a8e2b7SMingkai Hu {
104f3a8e2b7SMingkai Hu printf("cpld_ver = %x\n", CPLD_READ(cpld_ver));
105f3a8e2b7SMingkai Hu printf("cpld_ver_sub = %x\n", CPLD_READ(cpld_ver_sub));
106f3a8e2b7SMingkai Hu printf("pcba_ver = %x\n", CPLD_READ(pcba_ver));
107f3a8e2b7SMingkai Hu printf("soft_mux_on = %x\n", CPLD_READ(soft_mux_on));
108f3a8e2b7SMingkai Hu printf("cfg_rcw_src1 = %x\n", CPLD_READ(cfg_rcw_src1));
109f3a8e2b7SMingkai Hu printf("cfg_rcw_src2 = %x\n", CPLD_READ(cfg_rcw_src2));
110f3a8e2b7SMingkai Hu printf("vbank = %x\n", CPLD_READ(vbank));
111f3a8e2b7SMingkai Hu printf("sysclk_sel = %x\n", CPLD_READ(sysclk_sel));
112f3a8e2b7SMingkai Hu printf("uart_sel = %x\n", CPLD_READ(uart_sel));
113f3a8e2b7SMingkai Hu printf("sd1refclk_sel = %x\n", CPLD_READ(sd1refclk_sel));
114f3a8e2b7SMingkai Hu printf("tdmclk_mux_sel = %x\n", CPLD_READ(tdmclk_mux_sel));
115f3a8e2b7SMingkai Hu printf("sdhc_spics_sel = %x\n", CPLD_READ(sdhc_spics_sel));
116f3a8e2b7SMingkai Hu printf("status_led = %x\n", CPLD_READ(status_led));
117f3a8e2b7SMingkai Hu putc('\n');
118f3a8e2b7SMingkai Hu }
119f3a8e2b7SMingkai Hu #endif
120f3a8e2b7SMingkai Hu
cpld_rev_bit(unsigned char * value)121f3a8e2b7SMingkai Hu void cpld_rev_bit(unsigned char *value)
122f3a8e2b7SMingkai Hu {
123f3a8e2b7SMingkai Hu u8 rev_val, val;
124f3a8e2b7SMingkai Hu int i;
125f3a8e2b7SMingkai Hu
126f3a8e2b7SMingkai Hu val = *value;
127f3a8e2b7SMingkai Hu rev_val = val & 1;
128f3a8e2b7SMingkai Hu for (i = 1; i <= 7; i++) {
129f3a8e2b7SMingkai Hu val >>= 1;
130f3a8e2b7SMingkai Hu rev_val <<= 1;
131f3a8e2b7SMingkai Hu rev_val |= val & 1;
132f3a8e2b7SMingkai Hu }
133f3a8e2b7SMingkai Hu
134f3a8e2b7SMingkai Hu *value = rev_val;
135f3a8e2b7SMingkai Hu }
136f3a8e2b7SMingkai Hu
do_cpld(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])137f3a8e2b7SMingkai Hu int do_cpld(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
138f3a8e2b7SMingkai Hu {
139f3a8e2b7SMingkai Hu int rc = 0;
140f3a8e2b7SMingkai Hu
141f3a8e2b7SMingkai Hu if (argc <= 1)
142f3a8e2b7SMingkai Hu return cmd_usage(cmdtp);
143f3a8e2b7SMingkai Hu
144f3a8e2b7SMingkai Hu if (strcmp(argv[1], "reset") == 0) {
145f3a8e2b7SMingkai Hu if (strcmp(argv[2], "altbank") == 0)
146f3a8e2b7SMingkai Hu cpld_set_altbank();
1473ad44729SGong Qianyu else if (strcmp(argv[2], "nand") == 0)
1483ad44729SGong Qianyu cpld_set_nand();
149c7ca8b07SGong Qianyu else if (strcmp(argv[2], "sd") == 0)
150c7ca8b07SGong Qianyu cpld_set_sd();
151f3a8e2b7SMingkai Hu else
152f3a8e2b7SMingkai Hu cpld_set_defbank();
153f3a8e2b7SMingkai Hu #ifdef DEBUG
154f3a8e2b7SMingkai Hu } else if (strcmp(argv[1], "dump") == 0) {
155f3a8e2b7SMingkai Hu cpld_dump_regs();
156f3a8e2b7SMingkai Hu #endif
157f3a8e2b7SMingkai Hu } else {
158f3a8e2b7SMingkai Hu rc = cmd_usage(cmdtp);
159f3a8e2b7SMingkai Hu }
160f3a8e2b7SMingkai Hu
161f3a8e2b7SMingkai Hu return rc;
162f3a8e2b7SMingkai Hu }
163f3a8e2b7SMingkai Hu
164f3a8e2b7SMingkai Hu U_BOOT_CMD(
165f3a8e2b7SMingkai Hu cpld, CONFIG_SYS_MAXARGS, 1, do_cpld,
166f3a8e2b7SMingkai Hu "Reset the board or alternate bank",
167f3a8e2b7SMingkai Hu "reset: reset to default bank\n"
168f3a8e2b7SMingkai Hu "cpld reset altbank: reset to alternate bank\n"
1693ad44729SGong Qianyu "cpld reset nand: reset to boot from NAND flash\n"
170c7ca8b07SGong Qianyu "cpld reset sd: reset to boot from SD card\n"
171f3a8e2b7SMingkai Hu #ifdef DEBUG
172f3a8e2b7SMingkai Hu "cpld dump - display the CPLD registers\n"
173f3a8e2b7SMingkai Hu #endif
174f3a8e2b7SMingkai Hu );
175