Merge branch 'master' of git://git.denx.de/u-boot-sunxi
[oweals/u-boot.git] / board / k+p / kp_imx53 / kp_imx53.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2018
4  * Lukasz Majewski, DENX Software Engineering, lukma@denx.de
5  */
6
7 #include <common.h>
8 #include <asm/io.h>
9 #include <asm/arch/imx-regs.h>
10 #include <asm/arch/sys_proto.h>
11 #include <asm/arch/crm_regs.h>
12 #include <asm/arch/clock.h>
13 #include <asm/arch/iomux-mx53.h>
14 #include <asm/arch/clock.h>
15 #include <asm/gpio.h>
16 #include <mmc.h>
17 #include <fsl_esdhc.h>
18 #include <power/pmic.h>
19 #include <fsl_pmic.h>
20 #include "kp_id_rev.h"
21
22 #define VBUS_PWR_EN IMX_GPIO_NR(7, 8)
23 #define PHY_nRST IMX_GPIO_NR(7, 6)
24 #define BOOSTER_OFF IMX_GPIO_NR(2, 23)
25 #define LCD_BACKLIGHT IMX_GPIO_NR(1, 1)
26 #define KEY1 IMX_GPIO_NR(2, 26)
27
28 DECLARE_GLOBAL_DATA_PTR;
29
30 int dram_init(void)
31 {
32         u32 size;
33
34         size = get_ram_size((void *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE);
35         gd->ram_size = size;
36
37         return 0;
38 }
39
40 int dram_init_banksize(void)
41 {
42         gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
43         gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
44
45         return 0;
46 }
47
48 #ifdef CONFIG_USB_EHCI_MX5
49 int board_ehci_hcd_init(int port)
50 {
51         gpio_request(VBUS_PWR_EN, "VBUS_PWR_EN");
52         gpio_direction_output(VBUS_PWR_EN, 1);
53         return 0;
54 }
55 #endif
56
57 #ifdef CONFIG_FSL_ESDHC
58 struct fsl_esdhc_cfg esdhc_cfg[] = {
59         {MMC_SDHC3_BASE_ADDR},
60 };
61
62 int board_mmc_getcd(struct mmc *mmc)
63 {
64         return 1; /* eMMC is always present */
65 }
66
67 #define SD_CMD_PAD_CTRL         (PAD_CTL_HYS | PAD_CTL_DSE_HIGH | \
68                                  PAD_CTL_PUS_100K_UP)
69 #define SD_PAD_CTRL             (PAD_CTL_HYS | PAD_CTL_PUS_47K_UP | \
70                                  PAD_CTL_DSE_HIGH)
71
72 int board_mmc_init(bd_t *bis)
73 {
74         int ret;
75
76         static const iomux_v3_cfg_t sd3_pads[] = {
77                 NEW_PAD_CTRL(MX53_PAD_PATA_RESET_B__ESDHC3_CMD,
78                              SD_CMD_PAD_CTRL),
79                 NEW_PAD_CTRL(MX53_PAD_PATA_IORDY__ESDHC3_CLK, SD_PAD_CTRL),
80                 NEW_PAD_CTRL(MX53_PAD_PATA_DATA8__ESDHC3_DAT0, SD_PAD_CTRL),
81                 NEW_PAD_CTRL(MX53_PAD_PATA_DATA9__ESDHC3_DAT1, SD_PAD_CTRL),
82                 NEW_PAD_CTRL(MX53_PAD_PATA_DATA10__ESDHC3_DAT2, SD_PAD_CTRL),
83                 NEW_PAD_CTRL(MX53_PAD_PATA_DATA11__ESDHC3_DAT3, SD_PAD_CTRL),
84                 NEW_PAD_CTRL(MX53_PAD_PATA_DATA0__ESDHC3_DAT4, SD_PAD_CTRL),
85                 NEW_PAD_CTRL(MX53_PAD_PATA_DATA1__ESDHC3_DAT5, SD_PAD_CTRL),
86                 NEW_PAD_CTRL(MX53_PAD_PATA_DATA2__ESDHC3_DAT6, SD_PAD_CTRL),
87                 NEW_PAD_CTRL(MX53_PAD_PATA_DATA3__ESDHC3_DAT7, SD_PAD_CTRL),
88         };
89
90         esdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
91         imx_iomux_v3_setup_multiple_pads(sd3_pads, ARRAY_SIZE(sd3_pads));
92
93         ret = fsl_esdhc_initialize(bis, &esdhc_cfg[0]);
94         if (ret)
95                 return ret;
96
97         return 0;
98 }
99 #endif
100
101 static int power_init(void)
102 {
103         struct udevice *dev;
104         int ret;
105
106         ret = pmic_get("mc34708", &dev);
107         if (ret) {
108                 printf("%s: mc34708 not found !\n", __func__);
109                 return ret;
110         }
111
112         /* Set VDDGP to 1.110V for 800 MHz on SW1 */
113         pmic_clrsetbits(dev, REG_SW_0, SWx_VOLT_MASK_MC34708,
114                         SWx_1_110V_MC34708);
115
116         /* Set VCC as 1.30V on SW2 */
117         pmic_clrsetbits(dev, REG_SW_1, SWx_VOLT_MASK_MC34708,
118                         SWx_1_300V_MC34708);
119
120         /* Set global reset timer to 4s */
121         pmic_clrsetbits(dev, REG_POWER_CTL2, TIMER_MASK_MC34708,
122                         TIMER_4S_MC34708);
123
124         return ret;
125 }
126
127 static void setup_clocks(void)
128 {
129         int ret;
130         u32 ref_clk = MXC_HCLK;
131         /*
132          * CPU clock set to 800MHz and DDR to 400MHz
133          */
134         ret = mxc_set_clock(ref_clk, 800, MXC_ARM_CLK);
135         if (ret)
136                 printf("CPU:   Switch CPU clock to 800MHZ failed\n");
137
138         ret = mxc_set_clock(ref_clk, 400, MXC_PERIPH_CLK);
139         ret |= mxc_set_clock(ref_clk, 400, MXC_DDR_CLK);
140         if (ret)
141                 printf("CPU:   Switch DDR clock to 400MHz failed\n");
142 }
143
144 static void setup_ups(void)
145 {
146         gpio_request(BOOSTER_OFF, "BOOSTER_OFF");
147         gpio_direction_output(BOOSTER_OFF, 0);
148 }
149
150 int board_early_init_f(void)
151 {
152         return 0;
153 }
154
155 /*
156  * Do not overwrite the console
157  * Use always serial for U-Boot console
158  */
159 int overwrite_console(void)
160 {
161         return 1;
162 }
163
164 int board_init(void)
165 {
166         gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
167
168         return 0;
169 }
170
171 void eth_phy_reset(void)
172 {
173         gpio_request(PHY_nRST, "PHY_nRST");
174         gpio_direction_output(PHY_nRST, 1);
175         udelay(50);
176         gpio_set_value(PHY_nRST, 0);
177         udelay(400);
178         gpio_set_value(PHY_nRST, 1);
179         udelay(50);
180 }
181
182 void board_disable_display(void)
183 {
184         gpio_request(LCD_BACKLIGHT, "LCD_BACKLIGHT");
185         gpio_direction_output(LCD_BACKLIGHT, 0);
186 }
187
188 void board_misc_setup(void)
189 {
190         gpio_request(KEY1, "KEY1_GPIO");
191         gpio_direction_input(KEY1);
192
193         if (gpio_get_value(KEY1))
194                 env_set("key1", "off");
195         else
196                 env_set("key1", "on");
197 }
198
199 int board_late_init(void)
200 {
201         int ret = 0;
202
203         board_disable_display();
204         setup_ups();
205
206         if (!power_init())
207                 setup_clocks();
208
209         ret = read_eeprom();
210         if (ret)
211                 printf("Error %d reading EEPROM content!\n", ret);
212
213         eth_phy_reset();
214
215         show_eeprom();
216         read_board_id();
217
218         board_misc_setup();
219
220         return ret;
221 }