blob: 3509a457777c139ec8ae0dbd2c33f789dddf5cab [file] [log] [blame]
Angel Ponscc98db32020-04-05 13:22:27 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Gabe Blackd3163ab2013-05-16 05:53:40 -07002
Julius Werner80af4422014-10-20 13:18:56 -07003#include <arch/exception.h>
Gabe Blackd3163ab2013-05-16 05:53:40 -07004#include <armv7.h>
Aaron Durbin899d13d2015-05-15 23:39:23 -05005#include <boot_device.h>
Stefan Reinauer80e62932013-07-29 15:52:23 -07006#include <cbmem.h>
Aaron Durbindc9f5cd2015-09-08 13:34:43 -05007#include <commonlib/region.h>
Gabe Blackd3163ab2013-05-16 05:53:40 -07008#include <console/console.h>
Nico Huber0f2dd1e2017-08-01 14:02:40 +02009#include <device/i2c_simple.h>
Julius Werner80af4422014-10-20 13:18:56 -070010#include <drivers/maxim/max77802/max77802.h>
11#include <program_loading.h>
12#include <soc/clk.h>
13#include <soc/cpu.h>
14#include <soc/dmc.h>
15#include <soc/gpio.h>
16#include <soc/i2c.h>
17#include <soc/periph.h>
18#include <soc/power.h>
19#include <soc/setup.h>
20#include <soc/trustzone.h>
21#include <soc/wakeup.h>
Julius Werner80af4422014-10-20 13:18:56 -070022#include <timestamp.h>
23#include <types.h>
Gabe Blackd3163ab2013-05-16 05:53:40 -070024
David Hendricks77acf422013-08-05 21:04:16 -070025#define PMIC_I2C_BUS 4
26
David Hendricks1e3e2c52013-06-14 16:08:05 -070027struct pmic_write
28{
29 int or_orig; // Whether to or in the original value.
30 uint8_t reg; // Register to write.
31 uint8_t val; // Value to write.
32};
33
34/*
35 * Use read-modify-write for MAX77802 control registers and clobber the
36 * output voltage setting (BUCK?DVS?) registers.
37 */
38struct pmic_write pmic_writes[] =
39{
40 { 1, MAX77802_REG_PMIC_32KHZ, MAX77802_32KHCP_EN },
41 { 0, MAX77802_REG_PMIC_BUCK1DVS1, MAX77802_BUCK1DVS1_1V },
42 { 1, MAX77802_REG_PMIC_BUCK1CTRL, MAX77802_BUCK_TYPE1_ON |
43 MAX77802_BUCK_TYPE1_IGNORE_PWRREQ },
David Hendricks1f9f04e2013-08-01 18:57:52 -070044 { 0, MAX77802_REG_PMIC_BUCK2DVS1, MAX77802_BUCK2DVS1_1_2625V },
David Hendricks1e3e2c52013-06-14 16:08:05 -070045 { 1, MAX77802_REG_PMIC_BUCK2CTRL1, MAX77802_BUCK_TYPE2_ON |
46 MAX77802_BUCK_TYPE2_IGNORE_PWRREQ },
47 { 0, MAX77802_REG_PMIC_BUCK3DVS1, MAX77802_BUCK3DVS1_1V },
48 { 1, MAX77802_REG_PMIC_BUCK3CTRL1, MAX77802_BUCK_TYPE2_ON |
49 MAX77802_BUCK_TYPE2_IGNORE_PWRREQ },
50 { 0, MAX77802_REG_PMIC_BUCK4DVS1, MAX77802_BUCK4DVS1_1V },
51 { 1, MAX77802_REG_PMIC_BUCK4CTRL1, MAX77802_BUCK_TYPE2_ON |
52 MAX77802_BUCK_TYPE2_IGNORE_PWRREQ },
53 { 0, MAX77802_REG_PMIC_BUCK6DVS1, MAX77802_BUCK6DVS1_1V },
54 { 1, MAX77802_REG_PMIC_BUCK6CTRL, MAX77802_BUCK_TYPE1_ON |
Ronald G. Minnich88ac9b52013-06-26 17:28:52 -070055 MAX77802_BUCK_TYPE1_IGNORE_PWRREQ },
David Hendricks1f9f04e2013-08-01 18:57:52 -070056 /* Disable Boost(bypass) OUTPUT */
57 { 0, MAX77802_REG_PMIC_BOOSTCTRL, MAX77802_BOOSTCTRL_OFF},
David Hendricks1e3e2c52013-06-14 16:08:05 -070058};
59
David Hendricks77acf422013-08-05 21:04:16 -070060static int setup_power(int is_resume)
Gabe Blackd3163ab2013-05-16 05:53:40 -070061{
62 int error = 0;
David Hendricks1e3e2c52013-06-14 16:08:05 -070063 int i;
Gabe Blackd3163ab2013-05-16 05:53:40 -070064
65 power_init();
66
Hung-Te Linda7b8e42013-06-28 17:27:17 +080067 if (is_resume) {
David Hendricks77acf422013-08-05 21:04:16 -070068 return 0;
Hung-Te Linda7b8e42013-06-28 17:27:17 +080069 }
70
Gabe Blackd3163ab2013-05-16 05:53:40 -070071 /* Initialize I2C bus to configure PMIC. */
David Hendricks1e3e2c52013-06-14 16:08:05 -070072 exynos_pinmux_i2c4();
David Hendricks77acf422013-08-05 21:04:16 -070073 i2c_init(PMIC_I2C_BUS, 1000000, 0x00); /* 1MHz */
Gabe Blackd3163ab2013-05-16 05:53:40 -070074
David Hendricks1e3e2c52013-06-14 16:08:05 -070075 for (i = 0; i < ARRAY_SIZE(pmic_writes); i++) {
76 uint8_t data = 0;
77 uint8_t reg = pmic_writes[i].reg;
Gabe Blackd3163ab2013-05-16 05:53:40 -070078
David Hendricks1e3e2c52013-06-14 16:08:05 -070079 if (pmic_writes[i].or_orig)
Gabe Blackcdb61a62014-04-07 18:45:14 -070080 error |= i2c_readb(4, MAX77802_I2C_ADDR, reg, &data);
81
David Hendricks1e3e2c52013-06-14 16:08:05 -070082 data |= pmic_writes[i].val;
Gabe Blackcdb61a62014-04-07 18:45:14 -070083 error |= i2c_writeb(4, MAX77802_I2C_ADDR, reg, data);
Gabe Blackd3163ab2013-05-16 05:53:40 -070084 }
David Hendricks1e3e2c52013-06-14 16:08:05 -070085
David Hendricks77acf422013-08-05 21:04:16 -070086 return error;
Gabe Blackd3163ab2013-05-16 05:53:40 -070087}
88
Hung-Te Linc357aed2013-06-24 20:02:01 +080089static void setup_ec(void)
90{
91 /* SPI2 (EC) is slower and needs to work in half-duplex mode with
92 * single byte bus width. */
Gabe Black98018092013-07-24 06:18:20 -070093 clock_set_rate(PERIPH_ID_SPI2, 5000000);
Hung-Te Linc357aed2013-06-24 20:02:01 +080094 exynos_pinmux_spi2();
95}
96
Gabe Blackd3163ab2013-05-16 05:53:40 -070097static void setup_gpio(void)
98{
Gabe Black63bb6102013-06-19 03:29:45 -070099 gpio_direction_input(GPIO_X30); // WP_GPIO
100 gpio_set_pull(GPIO_X30, GPIO_PULL_NONE);
Gabe Blackd3163ab2013-05-16 05:53:40 -0700101
Gabe Black63bb6102013-06-19 03:29:45 -0700102 gpio_direction_input(GPIO_X07); // RECMODE_GPIO
103 gpio_set_pull(GPIO_X07, GPIO_PULL_NONE);
Gabe Blackd3163ab2013-05-16 05:53:40 -0700104
Gabe Black63bb6102013-06-19 03:29:45 -0700105 gpio_direction_input(GPIO_X34); // LID_GPIO
106 gpio_set_pull(GPIO_X34, GPIO_PULL_NONE);
Gabe Blackd3163ab2013-05-16 05:53:40 -0700107
Gabe Black63bb6102013-06-19 03:29:45 -0700108 gpio_direction_input(GPIO_X12); // POWER_GPIO
109 gpio_set_pull(GPIO_X12, GPIO_PULL_NONE);
Gabe Blackd3163ab2013-05-16 05:53:40 -0700110}
111
112static void setup_memory(struct mem_timings *mem, int is_resume)
113{
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700114 printk(BIOS_SPEW, "manufacturer: 0x%x type: 0x%x, div: 0x%x, mhz: %d\n",
Gabe Blackd3163ab2013-05-16 05:53:40 -0700115 mem->mem_manuf,
116 mem->mem_type,
117 mem->mpll_mdiv,
118 mem->frequency_mhz);
119
Gabe Blackd3163ab2013-05-16 05:53:40 -0700120 if (ddr3_mem_ctrl_init(mem, DMC_INTERLEAVE_SIZE, !is_resume)) {
121 die("Failed to initialize memory controller.\n");
122 }
123}
124
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700125#define PRIMITIVE_MEM_TEST 0
126#if PRIMITIVE_MEM_TEST
127static unsigned long primitive_mem_test(void)
Gabe Blackd3163ab2013-05-16 05:53:40 -0700128{
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700129 unsigned long *l = (void *)0x40000000;
130 int bad = 0;
131 unsigned long i;
Elyes HAOUAS5ba154a2020-08-04 13:27:52 +0200132 for (i = 0; i < 256*1048576; i++){
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700133 if (! (i%1048576))
134 printk(BIOS_SPEW, "%lu ...", i);
135 l[i] = 0xffffffff - i;
Gabe Blackd3163ab2013-05-16 05:53:40 -0700136 }
Gabe Black5420e092013-05-17 11:29:22 -0700137
Elyes HAOUAS5ba154a2020-08-04 13:27:52 +0200138 for (i = 0; i < 256*1048576; i++){
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700139 if (! (i%1048576))
140 printk(BIOS_SPEW, "%lu ...", i);
141 if (l[i] != (0xffffffff - i)){
142 printk(BIOS_SPEW, "%p: want %08lx got %08lx\n", l, l[i], 0xffffffff - i);
143 bad++;
144 }
145 }
Gabe Black5420e092013-05-17 11:29:22 -0700146
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700147 printk(BIOS_SPEW, "%d errors\n", bad);
148
149 return bad;
Gabe Blackd3163ab2013-05-16 05:53:40 -0700150}
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700151#else
152#define primitive_mem_test()
153#endif
154
155#define SIMPLE_SPI_TEST 0
156#if SIMPLE_SPI_TEST
157/* here is a simple SPI debug test, known to fid trouble */
158static void simple_spi_test(void)
159{
Aaron Durbin899d13d2015-05-15 23:39:23 -0500160 const struct region_device *boot_dev;
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700161 int i, amt = 4 * MiB, errors = 0;
162 //u32 *data = (void *)0x40000000;
163 u32 data[1024];
164 u32 in;
165
Aaron Durbin899d13d2015-05-15 23:39:23 -0500166 boot_device_init();
167 boot_dev = boot_device_ro();
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700168 amt = sizeof(data);
Aaron Durbin899d13d2015-05-15 23:39:23 -0500169 if (boot_dev == NULL) {
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700170 printk(BIOS_SPEW, "Failed to initialize default media.\n");
171 return;
172 }
173
Aaron Durbin899d13d2015-05-15 23:39:23 -0500174 if (rdev_readat(boot_dev, data, 0, amt) < amt) {
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700175 printk(BIOS_SPEW, "simple_spi_test fails\n");
176 return;
177 }
178
Elyes HAOUAS5ba154a2020-08-04 13:27:52 +0200179 for (i = 0; i < amt; i += 4){
Aaron Durbin899d13d2015-05-15 23:39:23 -0500180 if (rdev_readat(boot_dev, &in, i, 4) < 4) {
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700181 printk(BIOS_SPEW, "simple_spi_test fails at %d\n", i);
182 return;
183 }
184 if (data[i/4] != in){
185 errors++;
186 printk(BIOS_SPEW, "BAD at %d(%p):\nRAM %08lx\nSPI %08lx\n",
187 i, &data[i/4], (unsigned long)data[i/4], (unsigned long)in);
188 /* reread it to see which is wrong. */
Aaron Durbin899d13d2015-05-15 23:39:23 -0500189 if (rdev_readat(boot_dev, &in, i, 4) < 4) {
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700190 printk(BIOS_SPEW, "simple_spi_test fails at %d\n", i);
191 return;
192 }
193 printk(BIOS_SPEW, "RTRY at %d(%p):\nRAM %08lx\nSPI %08lx\n",
194 i, &data[i/4], (unsigned long)data[i/4], (unsigned long)in);
195 }
196
197 }
198 printk(BIOS_SPEW, "%d errors\n", errors);
199}
200#else
201#define simple_spi_test()
202#endif
Gabe Blackd3163ab2013-05-16 05:53:40 -0700203
204void main(void)
205{
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700206
207 extern struct mem_timings mem_timings;
Gabe Blackd3163ab2013-05-16 05:53:40 -0700208 int is_resume = (get_wakeup_state() != IS_NOT_WAKEUP);
David Hendricks77acf422013-08-05 21:04:16 -0700209 int power_init_failed;
210
Hung-Te Lin0682cfe2013-08-06 20:37:55 +0800211 exynos5420_config_smp();
David Hendricks77acf422013-08-05 21:04:16 -0700212 power_init_failed = setup_power(is_resume);
Gabe Blackd3163ab2013-05-16 05:53:40 -0700213
Kyösti Mälkkif48b38b2014-12-31 08:50:36 +0200214 timestamp_init(timestamp_get());
Jakub Czapigaad6157e2022-02-15 11:50:31 +0100215 timestamp_add_now(TS_ROMSTAGE_START);
Kyösti Mälkkif48b38b2014-12-31 08:50:36 +0200216
Gabe Blackd3163ab2013-05-16 05:53:40 -0700217 /* Clock must be initialized before console_init, otherwise you may need
218 * to re-initialize serial console drivers again. */
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700219 system_clock_init();
Gabe Blackd3163ab2013-05-16 05:53:40 -0700220
Gabe Black136e7092013-08-09 00:31:09 -0700221 exynos_pinmux_uart3();
Stefan Reinauer998ab0d2013-05-20 12:29:37 -0700222 console_init();
Julius Werner85620db2013-11-13 18:22:15 -0800223 exception_init();
Stefan Reinauer998ab0d2013-05-20 12:29:37 -0700224
David Hendricks77acf422013-08-05 21:04:16 -0700225 if (power_init_failed)
Elyes HAOUAS08fc8ff2018-08-07 12:19:10 +0200226 die("Failed to initialize power.\n");
David Hendricks77acf422013-08-05 21:04:16 -0700227
228 /* re-initialize PMIC I2C channel after (re-)setting system clocks */
229 i2c_init(PMIC_I2C_BUS, 1000000, 0x00); /* 1MHz */
230
Jakub Czapigaad6157e2022-02-15 11:50:31 +0100231 timestamp_add_now(TS_INITRAM_START);
Kyösti Mälkkif48b38b2014-12-31 08:50:36 +0200232
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700233 setup_memory(&mem_timings, is_resume);
234
Jakub Czapigaad6157e2022-02-15 11:50:31 +0100235 timestamp_add_now(TS_INITRAM_END);
Kyösti Mälkkif48b38b2014-12-31 08:50:36 +0200236
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700237 primitive_mem_test();
Gabe Blackd3163ab2013-05-16 05:53:40 -0700238
Gabe Black8128a562013-09-18 05:48:37 -0700239 trustzone_init();
240
Gabe Blackd3163ab2013-05-16 05:53:40 -0700241 if (is_resume) {
242 wakeup();
243 }
244
Gabe Blackd3163ab2013-05-16 05:53:40 -0700245 setup_gpio();
Hung-Te Linc357aed2013-06-24 20:02:01 +0800246 setup_ec();
Gabe Blackd3163ab2013-05-16 05:53:40 -0700247
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700248 simple_spi_test();
Gabe Blackd3163ab2013-05-16 05:53:40 -0700249 /* Set SPI (primary CBFS media) clock to 50MHz. */
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700250 /* if this is uncommented SPI will not work correctly. */
Gabe Blackd3163ab2013-05-16 05:53:40 -0700251 clock_set_rate(PERIPH_ID_SPI1, 50000000);
Julius Werner45d2ff32013-08-12 18:04:06 -0700252 exynos_pinmux_spi1();
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700253 simple_spi_test();
Stefan Reinauer80e62932013-07-29 15:52:23 -0700254
255 cbmem_initialize_empty();
256
Ronald G. Minniche6af9292013-06-03 13:03:50 -0700257 simple_spi_test();
Kyösti Mälkkif48b38b2014-12-31 08:50:36 +0200258
Aaron Durbine4f3e7a2015-03-17 13:25:19 -0500259 run_ramstage();
Gabe Blackd3163ab2013-05-16 05:53:40 -0700260}