blob: dc95e52f83ec0d064c4345ff26c89ded86b178ee [file] [log] [blame]
Angel Ponscc98db32020-04-05 13:22:27 +02001/* SPDX-License-Identifier: GPL-2.0-only */
2/* This file is part of the coreboot project. */
Gabe Blackd3163ab2013-05-16 05:53:40 -07003
Julius Werner80af4422014-10-20 13:18:56 -07004#include <arch/exception.h>
Gabe Blackd3163ab2013-05-16 05:53:40 -07005#include <armv7.h>
Aaron Durbin899d13d2015-05-15 23:39:23 -05006#include <boot_device.h>
Stefan Reinauer80e62932013-07-29 15:52:23 -07007#include <cbmem.h>
Aaron Durbindc9f5cd2015-09-08 13:34:43 -05008#include <commonlib/region.h>
Gabe Blackd3163ab2013-05-16 05:53:40 -07009#include <console/console.h>
Nico Huber0f2dd1e2017-08-01 14:02:40 +020010#include <device/i2c_simple.h>
Julius Werner80af4422014-10-20 13:18:56 -070011#include <drivers/maxim/max77802/max77802.h>
12#include <program_loading.h>
13#include <soc/clk.h>
14#include <soc/cpu.h>
15#include <soc/dmc.h>
16#include <soc/gpio.h>
17#include <soc/i2c.h>
18#include <soc/periph.h>
19#include <soc/power.h>
20#include <soc/setup.h>
21#include <soc/trustzone.h>
22#include <soc/wakeup.h>
Julius Werner80af4422014-10-20 13:18:56 -070023#include <timestamp.h>
24#include <types.h>
Gabe Blackd3163ab2013-05-16 05:53:40 -070025
David Hendricks77acf422013-08-05 21:04:16 -070026#define PMIC_I2C_BUS 4
27
David Hendricks1e3e2c52013-06-14 16:08:05 -070028struct pmic_write
29{
30 int or_orig; // Whether to or in the original value.
31 uint8_t reg; // Register to write.
32 uint8_t val; // Value to write.
33};
34
35/*
36 * Use read-modify-write for MAX77802 control registers and clobber the
37 * output voltage setting (BUCK?DVS?) registers.
38 */
39struct pmic_write pmic_writes[] =
40{
41 { 1, MAX77802_REG_PMIC_32KHZ, MAX77802_32KHCP_EN },
42 { 0, MAX77802_REG_PMIC_BUCK1DVS1, MAX77802_BUCK1DVS1_1V },
43 { 1, MAX77802_REG_PMIC_BUCK1CTRL, MAX77802_BUCK_TYPE1_ON |
44 MAX77802_BUCK_TYPE1_IGNORE_PWRREQ },
David Hendricks1f9f04e2013-08-01 18:57:52 -070045 { 0, MAX77802_REG_PMIC_BUCK2DVS1, MAX77802_BUCK2DVS1_1_2625V },
David Hendricks1e3e2c52013-06-14 16:08:05 -070046 { 1, MAX77802_REG_PMIC_BUCK2CTRL1, MAX77802_BUCK_TYPE2_ON |
47 MAX77802_BUCK_TYPE2_IGNORE_PWRREQ },
48 { 0, MAX77802_REG_PMIC_BUCK3DVS1, MAX77802_BUCK3DVS1_1V },
49 { 1, MAX77802_REG_PMIC_BUCK3CTRL1, MAX77802_BUCK_TYPE2_ON |
50 MAX77802_BUCK_TYPE2_IGNORE_PWRREQ },
51 { 0, MAX77802_REG_PMIC_BUCK4DVS1, MAX77802_BUCK4DVS1_1V },
52 { 1, MAX77802_REG_PMIC_BUCK4CTRL1, MAX77802_BUCK_TYPE2_ON |
53 MAX77802_BUCK_TYPE2_IGNORE_PWRREQ },
54 { 0, MAX77802_REG_PMIC_BUCK6DVS1, MAX77802_BUCK6DVS1_1V },
55 { 1, MAX77802_REG_PMIC_BUCK6CTRL, MAX77802_BUCK_TYPE1_ON |
Ronald G. Minnich88ac9b52013-06-26 17:28:52 -070056 MAX77802_BUCK_TYPE1_IGNORE_PWRREQ },
David Hendricks1f9f04e2013-08-01 18:57:52 -070057 /* Disable Boost(bypass) OUTPUT */
58 { 0, MAX77802_REG_PMIC_BOOSTCTRL, MAX77802_BOOSTCTRL_OFF},
David Hendricks1e3e2c52013-06-14 16:08:05 -070059};
60
David Hendricks77acf422013-08-05 21:04:16 -070061static int setup_power(int is_resume)
Gabe Blackd3163ab2013-05-16 05:53:40 -070062{
63 int error = 0;
David Hendricks1e3e2c52013-06-14 16:08:05 -070064 int i;
Gabe Blackd3163ab2013-05-16 05:53:40 -070065
66 power_init();
67
Hung-Te Linda7b8e42013-06-28 17:27:17 +080068 if (is_resume) {
David Hendricks77acf422013-08-05 21:04:16 -070069 return 0;
Hung-Te Linda7b8e42013-06-28 17:27:17 +080070 }
71
Gabe Blackd3163ab2013-05-16 05:53:40 -070072 /* Initialize I2C bus to configure PMIC. */
David Hendricks1e3e2c52013-06-14 16:08:05 -070073 exynos_pinmux_i2c4();
David Hendricks77acf422013-08-05 21:04:16 -070074 i2c_init(PMIC_I2C_BUS, 1000000, 0x00); /* 1MHz */
Gabe Blackd3163ab2013-05-16 05:53:40 -070075
David Hendricks1e3e2c52013-06-14 16:08:05 -070076 for (i = 0; i < ARRAY_SIZE(pmic_writes); i++) {
77 uint8_t data = 0;
78 uint8_t reg = pmic_writes[i].reg;
Gabe Blackd3163ab2013-05-16 05:53:40 -070079
David Hendricks1e3e2c52013-06-14 16:08:05 -070080 if (pmic_writes[i].or_orig)
Gabe Blackcdb61a62014-04-07 18:45:14 -070081 error |= i2c_readb(4, MAX77802_I2C_ADDR, reg, &data);
82
David Hendricks1e3e2c52013-06-14 16:08:05 -070083 data |= pmic_writes[i].val;
Gabe Blackcdb61a62014-04-07 18:45:14 -070084 error |= i2c_writeb(4, MAX77802_I2C_ADDR, reg, data);
Gabe Blackd3163ab2013-05-16 05:53:40 -070085 }
David Hendricks1e3e2c52013-06-14 16:08:05 -070086
David Hendricks77acf422013-08-05 21:04:16 -070087 return error;
Gabe Blackd3163ab2013-05-16 05:53:40 -070088}
89
Hung-Te Linc357aed2013-06-24 20:02:01 +080090static void setup_ec(void)
91{
92 /* SPI2 (EC) is slower and needs to work in half-duplex mode with
93 * single byte bus width. */
Gabe Black98018092013-07-24 06:18:20 -070094 clock_set_rate(PERIPH_ID_SPI2, 5000000);
Hung-Te Linc357aed2013-06-24 20:02:01 +080095 exynos_pinmux_spi2();
96}
97
Gabe Blackd3163ab2013-05-16 05:53:40 -070098static void setup_gpio(void)
99{
Gabe Black63bb6102013-06-19 03:29:45 -0700100 gpio_direction_input(GPIO_X30); // WP_GPIO
101 gpio_set_pull(GPIO_X30, GPIO_PULL_NONE);
Gabe Blackd3163ab2013-05-16 05:53:40 -0700102
Gabe Black63bb6102013-06-19 03:29:45 -0700103 gpio_direction_input(GPIO_X07); // RECMODE_GPIO
104 gpio_set_pull(GPIO_X07, GPIO_PULL_NONE);
Gabe Blackd3163ab2013-05-16 05:53:40 -0700105
Gabe Black63bb6102013-06-19 03:29:45 -0700106 gpio_direction_input(GPIO_X34); // LID_GPIO
107 gpio_set_pull(GPIO_X34, GPIO_PULL_NONE);
Gabe Blackd3163ab2013-05-16 05:53:40 -0700108
Gabe Black63bb6102013-06-19 03:29:45 -0700109 gpio_direction_input(GPIO_X12); // POWER_GPIO
110 gpio_set_pull(GPIO_X12, GPIO_PULL_NONE);
Gabe Blackd3163ab2013-05-16 05:53:40 -0700111}
112
113static void setup_memory(struct mem_timings *mem, int is_resume)
114{
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700115 printk(BIOS_SPEW, "manufacturer: 0x%x type: 0x%x, div: 0x%x, mhz: %d\n",
Gabe Blackd3163ab2013-05-16 05:53:40 -0700116 mem->mem_manuf,
117 mem->mem_type,
118 mem->mpll_mdiv,
119 mem->frequency_mhz);
120
Gabe Blackd3163ab2013-05-16 05:53:40 -0700121 if (ddr3_mem_ctrl_init(mem, DMC_INTERLEAVE_SIZE, !is_resume)) {
122 die("Failed to initialize memory controller.\n");
123 }
124}
125
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700126#define PRIMITIVE_MEM_TEST 0
127#if PRIMITIVE_MEM_TEST
128static unsigned long primitive_mem_test(void)
Gabe Blackd3163ab2013-05-16 05:53:40 -0700129{
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700130 unsigned long *l = (void *)0x40000000;
131 int bad = 0;
132 unsigned long i;
133 for(i = 0; i < 256*1048576; i++){
134 if (! (i%1048576))
135 printk(BIOS_SPEW, "%lu ...", i);
136 l[i] = 0xffffffff - i;
Gabe Blackd3163ab2013-05-16 05:53:40 -0700137 }
Gabe Black5420e092013-05-17 11:29:22 -0700138
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700139 for(i = 0; i < 256*1048576; i++){
140 if (! (i%1048576))
141 printk(BIOS_SPEW, "%lu ...", i);
142 if (l[i] != (0xffffffff - i)){
143 printk(BIOS_SPEW, "%p: want %08lx got %08lx\n", l, l[i], 0xffffffff - i);
144 bad++;
145 }
146 }
Gabe Black5420e092013-05-17 11:29:22 -0700147
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700148 printk(BIOS_SPEW, "%d errors\n", bad);
149
150 return bad;
Gabe Blackd3163ab2013-05-16 05:53:40 -0700151}
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700152#else
153#define primitive_mem_test()
154#endif
155
156#define SIMPLE_SPI_TEST 0
157#if SIMPLE_SPI_TEST
158/* here is a simple SPI debug test, known to fid trouble */
159static void simple_spi_test(void)
160{
Aaron Durbin899d13d2015-05-15 23:39:23 -0500161 const struct region_device *boot_dev;
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700162 int i, amt = 4 * MiB, errors = 0;
163 //u32 *data = (void *)0x40000000;
164 u32 data[1024];
165 u32 in;
166
Aaron Durbin899d13d2015-05-15 23:39:23 -0500167 boot_device_init();
168 boot_dev = boot_device_ro();
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700169 amt = sizeof(data);
Aaron Durbin899d13d2015-05-15 23:39:23 -0500170 if (boot_dev == NULL) {
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700171 printk(BIOS_SPEW, "Failed to initialize default media.\n");
172 return;
173 }
174
Aaron Durbin899d13d2015-05-15 23:39:23 -0500175 if (rdev_readat(boot_dev, data, 0, amt) < amt) {
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700176 printk(BIOS_SPEW, "simple_spi_test fails\n");
177 return;
178 }
179
180
181 for(i = 0; i < amt; i += 4){
Aaron Durbin899d13d2015-05-15 23:39:23 -0500182 if (rdev_readat(boot_dev, &in, i, 4) < 4) {
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700183 printk(BIOS_SPEW, "simple_spi_test fails at %d\n", i);
184 return;
185 }
186 if (data[i/4] != in){
187 errors++;
188 printk(BIOS_SPEW, "BAD at %d(%p):\nRAM %08lx\nSPI %08lx\n",
189 i, &data[i/4], (unsigned long)data[i/4], (unsigned long)in);
190 /* reread it to see which is wrong. */
Aaron Durbin899d13d2015-05-15 23:39:23 -0500191 if (rdev_readat(boot_dev, &in, i, 4) < 4) {
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700192 printk(BIOS_SPEW, "simple_spi_test fails at %d\n", i);
193 return;
194 }
195 printk(BIOS_SPEW, "RTRY at %d(%p):\nRAM %08lx\nSPI %08lx\n",
196 i, &data[i/4], (unsigned long)data[i/4], (unsigned long)in);
197 }
198
199 }
200 printk(BIOS_SPEW, "%d errors\n", errors);
201}
202#else
203#define simple_spi_test()
204#endif
Gabe Blackd3163ab2013-05-16 05:53:40 -0700205
206void main(void)
207{
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700208
209 extern struct mem_timings mem_timings;
Gabe Blackd3163ab2013-05-16 05:53:40 -0700210 int is_resume = (get_wakeup_state() != IS_NOT_WAKEUP);
David Hendricks77acf422013-08-05 21:04:16 -0700211 int power_init_failed;
212
Hung-Te Lin0682cfe2013-08-06 20:37:55 +0800213 exynos5420_config_smp();
David Hendricks77acf422013-08-05 21:04:16 -0700214 power_init_failed = setup_power(is_resume);
Gabe Blackd3163ab2013-05-16 05:53:40 -0700215
Kyösti Mälkkif48b38b2014-12-31 08:50:36 +0200216 timestamp_init(timestamp_get());
217 timestamp_add_now(TS_START_ROMSTAGE);
218
Gabe Blackd3163ab2013-05-16 05:53:40 -0700219 /* Clock must be initialized before console_init, otherwise you may need
220 * to re-initialize serial console drivers again. */
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700221 system_clock_init();
Gabe Blackd3163ab2013-05-16 05:53:40 -0700222
Gabe Black136e7092013-08-09 00:31:09 -0700223 exynos_pinmux_uart3();
Stefan Reinauer998ab0d2013-05-20 12:29:37 -0700224 console_init();
Julius Werner85620db2013-11-13 18:22:15 -0800225 exception_init();
Stefan Reinauer998ab0d2013-05-20 12:29:37 -0700226
David Hendricks77acf422013-08-05 21:04:16 -0700227 if (power_init_failed)
Elyes HAOUAS08fc8ff2018-08-07 12:19:10 +0200228 die("Failed to initialize power.\n");
David Hendricks77acf422013-08-05 21:04:16 -0700229
230 /* re-initialize PMIC I2C channel after (re-)setting system clocks */
231 i2c_init(PMIC_I2C_BUS, 1000000, 0x00); /* 1MHz */
232
Kyösti Mälkkif48b38b2014-12-31 08:50:36 +0200233 timestamp_add_now(TS_BEFORE_INITRAM);
234
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700235 setup_memory(&mem_timings, is_resume);
236
Kyösti Mälkkif48b38b2014-12-31 08:50:36 +0200237 timestamp_add_now(TS_AFTER_INITRAM);
238
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700239 primitive_mem_test();
Gabe Blackd3163ab2013-05-16 05:53:40 -0700240
Gabe Black8128a562013-09-18 05:48:37 -0700241 trustzone_init();
242
Gabe Blackd3163ab2013-05-16 05:53:40 -0700243 if (is_resume) {
244 wakeup();
245 }
246
Gabe Blackd3163ab2013-05-16 05:53:40 -0700247 setup_gpio();
Hung-Te Linc357aed2013-06-24 20:02:01 +0800248 setup_ec();
Gabe Blackd3163ab2013-05-16 05:53:40 -0700249
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700250 simple_spi_test();
Gabe Blackd3163ab2013-05-16 05:53:40 -0700251 /* Set SPI (primary CBFS media) clock to 50MHz. */
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700252 /* if this is uncommented SPI will not work correctly. */
Gabe Blackd3163ab2013-05-16 05:53:40 -0700253 clock_set_rate(PERIPH_ID_SPI1, 50000000);
Julius Werner45d2ff32013-08-12 18:04:06 -0700254 exynos_pinmux_spi1();
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700255 simple_spi_test();
Stefan Reinauer80e62932013-07-29 15:52:23 -0700256
257 cbmem_initialize_empty();
258
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700259 simple_spi_test();
Kyösti Mälkkif48b38b2014-12-31 08:50:36 +0200260
Aaron Durbine4f3e7a2015-03-17 13:25:19 -0500261 run_ramstage();
Gabe Blackd3163ab2013-05-16 05:53:40 -0700262}