blob: 8e2bbe8a255e951d0c906c2a25d105d75709dd30 [file] [log] [blame]
Angel Ponse3218a22020-04-05 13:21:04 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Ronald G. Minnichf89e6b22012-12-10 16:13:43 -08002
Julius Werner1ed0c8c2014-10-20 13:16:29 -07003#include <arch/cache.h>
4#include <boot/coreboot_tables.h>
David Hendricks50c0a502013-01-31 17:05:50 -08005#include <console/console.h>
Julius Werner1ed0c8c2014-10-20 13:16:29 -07006#include <delay.h>
Stefan Reinauer2ae6d6f2013-05-09 16:16:13 -07007#include <device/device.h>
Nico Huber0f2dd1e2017-08-01 14:02:40 +02008#include <device/i2c_simple.h>
Stefan Reinauer2ae6d6f2013-05-09 16:16:13 -07009#include <drivers/ti/tps65090/tps65090.h>
Julius Werner1ed0c8c2014-10-20 13:16:29 -070010#include <soc/clk.h>
11#include <soc/dp.h>
12#include <soc/dp-core.h>
13#include <soc/gpio.h>
14#include <soc/i2c.h>
15#include <soc/periph.h>
16#include <soc/power.h>
17#include <soc/tmu.h>
18#include <soc/usb.h>
Julius Wernerec5e5e02014-08-20 15:29:56 -070019#include <symbols.h>
Patrick Rudolph8b56c8c2020-02-19 12:57:00 +010020#include <framebuffer_info.h>
David Hendricks0d4f97e2013-02-03 18:09:58 -080021
Stefan Reinauer043eb0e2013-05-10 16:21:58 -070022#include "exynos5250.h"
David Hendricks0d4f97e2013-02-03 18:09:58 -080023
Julius Wernerad4556f22013-08-21 17:33:31 -070024#define MMC0_GPIO_PIN (58)
25
Stefan Reinauer2ae6d6f2013-05-09 16:16:13 -070026/* convenient shorthand (in MB) */
Julius Wernerec5e5e02014-08-20 15:29:56 -070027#define DRAM_START ((uintptr_t)_dram/MiB)
Stefan Reinauer2ae6d6f2013-05-09 16:16:13 -070028#define DRAM_SIZE CONFIG_DRAM_SIZE_MB
29#define DRAM_END (DRAM_START + DRAM_SIZE) /* plus one... */
30
Stefan Reinauer2ae6d6f2013-05-09 16:16:13 -070031/* TODO: transplanted DP stuff, clean up once we have something that works */
32static enum exynos5_gpio_pin dp_pd_l = GPIO_Y25; /* active low */
33static enum exynos5_gpio_pin dp_rst_l = GPIO_X15; /* active low */
34static enum exynos5_gpio_pin dp_hpd = GPIO_X07; /* active high */
35
36static void exynos_dp_bridge_setup(void)
Ronald G. Minnichf89e6b22012-12-10 16:13:43 -080037{
Gabe Blackfe640602013-06-15 20:33:05 -070038 exynos_pinmux_dphpd();
David Hendricks0d4f97e2013-02-03 18:09:58 -080039
Stefan Reinauer2ae6d6f2013-05-09 16:16:13 -070040 gpio_set_value(dp_pd_l, 1);
Stefan Reinauerdc006c12013-05-15 14:54:07 -070041 gpio_cfg_pin(dp_pd_l, GPIO_OUTPUT);
42 gpio_set_pull(dp_pd_l, GPIO_PULL_NONE);
David Hendricks0d4f97e2013-02-03 18:09:58 -080043
Stefan Reinauer2ae6d6f2013-05-09 16:16:13 -070044 gpio_set_value(dp_rst_l, 0);
Stefan Reinauerdc006c12013-05-15 14:54:07 -070045 gpio_cfg_pin(dp_rst_l, GPIO_OUTPUT);
46 gpio_set_pull(dp_rst_l, GPIO_PULL_NONE);
Stefan Reinauer2ae6d6f2013-05-09 16:16:13 -070047 udelay(10);
48 gpio_set_value(dp_rst_l, 1);
Ronald G. Minnichf89e6b22012-12-10 16:13:43 -080049}
50
Stefan Reinauer2ae6d6f2013-05-09 16:16:13 -070051static void exynos_dp_bridge_init(void)
52{
53 /* De-assert PD (and possibly RST) to power up the bridge */
54 gpio_set_value(dp_pd_l, 1);
55 gpio_set_value(dp_rst_l, 1);
56
57 /*
58 * We need to wait for 90ms after bringing up the bridge since
59 * there is a phantom "high" on the HPD chip during its
60 * bootup. The phantom high comes within 7ms of de-asserting
61 * PD and persists for at least 15ms. The real high comes
62 * roughly 50ms after PD is de-asserted. The phantom high
63 * makes it hard for us to know when the NXP chip is up.
64 */
65 udelay(90000);
66}
67
68static int exynos_dp_hotplug(void)
69{
70 /* Check HPD. If it's high, we're all good. */
71 return gpio_get_value(dp_hpd) ? 0 : 1;
72}
73
74static void exynos_dp_reset(void)
75{
76 gpio_set_value(dp_pd_l, 0);
77 gpio_set_value(dp_rst_l, 0);
78 /* paranoid delay period (300ms) */
79 udelay(300 * 1000);
80}
81
82/*
83 * This delay is T3 in the LCD timing spec (defined as >200ms). We set
84 * this down to 60ms since that's the approximate maximum amount of time
85 * it'll take a bridge to start outputting LVDS data. The delay of
86 * >200ms is just a conservative value to avoid turning on the backlight
87 * when there's random LCD data on the screen. Shaving 140ms off the
88 * boot is an acceptable trade-off.
89 */
90#define LCD_T3_DELAY_MS 60
91
92#define LCD_T5_DELAY_MS 10
93#define LCD_T6_DELAY_MS 10
94
Stefan Reinauer043eb0e2013-05-10 16:21:58 -070095static void backlight_pwm(void)
Stefan Reinauer2ae6d6f2013-05-09 16:16:13 -070096{
97 /*Configure backlight PWM as a simple output high (100% brightness) */
98 gpio_direction_output(GPIO_B20, 1);
99 udelay(LCD_T6_DELAY_MS * 1000);
100}
101
Stefan Reinauer043eb0e2013-05-10 16:21:58 -0700102static void backlight_en(void)
Stefan Reinauer2ae6d6f2013-05-09 16:16:13 -0700103{
Stefan Reinauerdc006c12013-05-15 14:54:07 -0700104 /* Configure GPIO for LCD_BL_EN */
Stefan Reinauer2ae6d6f2013-05-09 16:16:13 -0700105 gpio_direction_output(GPIO_X30, 1);
106}
107
Gabe Black49c98dc2014-01-22 21:06:32 -0800108#define TPS65090_BUS 4 /* Daisy-specific */
Stefan Reinauer2ae6d6f2013-05-09 16:16:13 -0700109
110#define FET1_CTRL 0x0f
Julius Wernerad4556f22013-08-21 17:33:31 -0700111#define FET4_CTRL 0x12
Stefan Reinauer2ae6d6f2013-05-09 16:16:13 -0700112#define FET6_CTRL 0x14
113
Stefan Reinauer043eb0e2013-05-10 16:21:58 -0700114static void lcd_vdd(void)
Stefan Reinauer2ae6d6f2013-05-09 16:16:13 -0700115{
116 /* Enable FET6, lcd panel */
David Hendricks8ccabb62013-08-01 19:12:56 -0700117 tps65090_fet_enable(TPS65090_BUS, FET6_CTRL);
Stefan Reinauer2ae6d6f2013-05-09 16:16:13 -0700118}
119
Stefan Reinauer043eb0e2013-05-10 16:21:58 -0700120static void backlight_vdd(void)
Stefan Reinauer2ae6d6f2013-05-09 16:16:13 -0700121{
122 /* Enable FET1, backlight */
David Hendricks8ccabb62013-08-01 19:12:56 -0700123 tps65090_fet_enable(TPS65090_BUS, FET1_CTRL);
Stefan Reinauer2ae6d6f2013-05-09 16:16:13 -0700124 udelay(LCD_T5_DELAY_MS * 1000);
125}
126
Julius Wernerad4556f22013-08-21 17:33:31 -0700127static void sdmmc_vdd(void)
128{
129 /* Enable FET4, P3.3V_SDCARD */
130 tps65090_fet_enable(TPS65090_BUS, FET4_CTRL);
131}
132
Julius Werner79bff702013-08-15 17:34:45 -0700133static enum exynos5_gpio_pin usb_host_vbus = GPIO_X11;
134static enum exynos5_gpio_pin usb_drd_vbus = GPIO_X27;
135/* static enum exynos5_gpio_pin hsic_reset_l = GPIO_E10; */
136
Julius Werner68aef112013-09-03 15:07:31 -0700137static void prepare_usb(void)
138{
139 /* Kick this reset off early so it gets at least 100ms to settle */
140 reset_usb_drd_dwc3();
141}
142
Julius Werner79bff702013-08-15 17:34:45 -0700143static void setup_usb(void)
144{
145 /* HSIC not needed in firmware on this board */
Julius Werner68aef112013-09-03 15:07:31 -0700146 setup_usb_drd_phy();
147 setup_usb_drd_dwc3();
Julius Werner79bff702013-08-15 17:34:45 -0700148 setup_usb_host_phy(0);
149
150 gpio_direction_output(usb_host_vbus, 1);
151 gpio_direction_output(usb_drd_vbus, 1);
152}
153
Stefan Reinauer2ae6d6f2013-05-09 16:16:13 -0700154//static struct video_info smdk5250_dp_config = {
Stefan Reinauer043eb0e2013-05-10 16:21:58 -0700155static struct video_info dp_video_info = {
Stefan Reinauer2ae6d6f2013-05-09 16:16:13 -0700156 /* FIXME: fix video_info struct to use const for name */
157 .name = (char *)"eDP-LVDS NXP PTN3460",
158
159 .h_sync_polarity = 0,
160 .v_sync_polarity = 0,
161 .interlaced = 0,
162
163 .color_space = COLOR_RGB,
164 .dynamic_range = VESA,
165 .ycbcr_coeff = COLOR_YCBCR601,
166 .color_depth = COLOR_8,
167
168 .link_rate = LINK_RATE_2_70GBPS,
169 .lane_count = LANE_COUNT2,
170};
171
172/* FIXME: move some place more appropriate */
Stefan Reinauer043eb0e2013-05-10 16:21:58 -0700173#define MAX_DP_TRIES 5
Stefan Reinauer2ae6d6f2013-05-09 16:16:13 -0700174
175/*
176 * This function disables the USB3.0 PLL to save power
177 */
178static void disable_usb30_pll(void)
179{
180 enum exynos5_gpio_pin usb3_pll_l = GPIO_Y11;
181
182 gpio_direction_output(usb3_pll_l, 0);
183}
184
Julius Wernerad4556f22013-08-21 17:33:31 -0700185static void setup_storage(void)
186{
187 /* MMC0: Fixed, 8 bit mode, connected with GPIO. */
188 if (clock_set_mshci(PERIPH_ID_SDMMC0))
189 printk(BIOS_CRIT, "%s: Failed to set MMC0 clock.\n", __func__);
190 if (gpio_direction_output(MMC0_GPIO_PIN, 1)) {
191 printk(BIOS_CRIT, "%s: Unable to power on MMC0.\n", __func__);
192 }
193 gpio_set_pull(MMC0_GPIO_PIN, GPIO_PULL_NONE);
194 gpio_set_drv(MMC0_GPIO_PIN, GPIO_DRV_4X);
195 exynos_pinmux_sdmmc0();
196
197 /* MMC2: Removable, 4 bit mode, no GPIO. */
198 /* (Must be after romstage to avoid breaking SDMMC boot.) */
199 clock_set_mshci(PERIPH_ID_SDMMC2);
200 exynos_pinmux_sdmmc2();
201}
202
Gabe Black1387b432013-05-18 15:55:47 -0700203static void gpio_init(void)
204{
Martin Roth50863da2021-10-01 14:37:30 -0600205 /* Set up the I2C buses. */
Gabe Blackfe640602013-06-15 20:33:05 -0700206 exynos_pinmux_i2c0();
207 exynos_pinmux_i2c1();
208 exynos_pinmux_i2c2();
209 exynos_pinmux_i2c3();
210 exynos_pinmux_i2c4();
211 exynos_pinmux_i2c7();
Gabe Black1387b432013-05-18 15:55:47 -0700212
213 /* Set up the GPIOs used to arbitrate for I2C bus 4. */
214 gpio_set_pull(GPIO_F03, GPIO_PULL_NONE);
215 gpio_set_pull(GPIO_E04, GPIO_PULL_NONE);
216 gpio_direction_output(GPIO_F03, 1);
217 gpio_direction_input(GPIO_E04);
218
219 /* Set up the GPIO used to enable the audio codec. */
220 gpio_set_pull(GPIO_X17, GPIO_PULL_NONE);
221 gpio_set_pull(GPIO_X15, GPIO_PULL_NONE);
222 gpio_direction_output(GPIO_X17, 1);
223 gpio_direction_output(GPIO_X15, 1);
224
Martin Roth50863da2021-10-01 14:37:30 -0600225 /* Set up the I2S buses. */
Gabe Blacke6789c12013-08-05 22:19:36 -0700226 exynos_pinmux_i2s0();
Gabe Blackfe640602013-06-15 20:33:05 -0700227 exynos_pinmux_i2s1();
Gabe Black1387b432013-05-18 15:55:47 -0700228}
229
Stefan Reinauer2ae6d6f2013-05-09 16:16:13 -0700230/* this happens after cpu_init where exynos resources are set */
Elyes HAOUASd129d432018-05-04 20:23:33 +0200231static void mainboard_init(struct device *dev)
Stefan Reinauer2ae6d6f2013-05-09 16:16:13 -0700232{
233 int dp_tries;
234 struct s5p_dp_device dp_device = {
Julius Wernerfa938c72013-08-29 14:17:36 -0700235 .base = exynos_dp1,
Stefan Reinauer043eb0e2013-05-10 16:21:58 -0700236 .video_info = &dp_video_info,
Stefan Reinauer2ae6d6f2013-05-09 16:16:13 -0700237 };
Stefan Reinauer66287442013-06-19 15:54:19 -0700238 void *fb_addr = (void *)(get_fb_base_kb() * KiB);
Stefan Reinauer2ae6d6f2013-05-09 16:16:13 -0700239
Julius Werner68aef112013-09-03 15:07:31 -0700240 prepare_usb();
Gabe Black1387b432013-05-18 15:55:47 -0700241 gpio_init();
Julius Wernerad4556f22013-08-21 17:33:31 -0700242 setup_storage();
Gabe Black1387b432013-05-18 15:55:47 -0700243
David Hendricks8ccabb62013-08-01 19:12:56 -0700244 i2c_init(TPS65090_BUS, I2C_0_SPEED, I2C_SLAVE);
Stefan Reinauer043eb0e2013-05-10 16:21:58 -0700245 i2c_init(7, I2C_0_SPEED, I2C_SLAVE);
Stefan Reinauer2ae6d6f2013-05-09 16:16:13 -0700246
247 tmu_init(&exynos5250_tmu_info);
248
249 /* Clock Gating all the unused IP's to save power */
250 clock_gate();
251
252 /* Disable USB3.0 PLL to save 250mW of power */
253 disable_usb30_pll();
254
Julius Wernerad4556f22013-08-21 17:33:31 -0700255 sdmmc_vdd();
256
Patrick Rudolph8b56c8c2020-02-19 12:57:00 +0100257 fb_add_framebuffer_info((uintptr_t)fb_addr, 1366, 768, 2 * 1366, 16);
Stefan Reinauer2ae6d6f2013-05-09 16:16:13 -0700258
Stefan Reinauer043eb0e2013-05-10 16:21:58 -0700259 lcd_vdd();
Stefan Reinauera86c33a2013-05-17 10:34:25 -0700260
261 // FIXME: should timeout
Stefan Reinauer2ae6d6f2013-05-09 16:16:13 -0700262 do {
263 udelay(50);
264 } while (!exynos_dp_hotplug());
265
266 exynos_dp_bridge_setup();
Stefan Reinauer043eb0e2013-05-10 16:21:58 -0700267 for (dp_tries = 1; dp_tries <= MAX_DP_TRIES; dp_tries++) {
Stefan Reinauer2ae6d6f2013-05-09 16:16:13 -0700268 exynos_dp_bridge_init();
269 if (exynos_dp_hotplug()) {
270 exynos_dp_reset();
271 continue;
272 }
273
274 if (dp_controller_init(&dp_device))
275 continue;
276
277 udelay(LCD_T3_DELAY_MS * 1000);
278
Stefan Reinauer043eb0e2013-05-10 16:21:58 -0700279 backlight_vdd();
280 backlight_pwm();
281 backlight_en();
Stefan Reinauer2ae6d6f2013-05-09 16:16:13 -0700282 /* if we're here, we're successful */
283 break;
284 }
285
Stefan Reinauer043eb0e2013-05-10 16:21:58 -0700286 if (dp_tries > MAX_DP_TRIES)
Stefan Reinauer2ae6d6f2013-05-09 16:16:13 -0700287 printk(BIOS_ERR, "%s: Failed to set up displayport\n", __func__);
Stefan Reinauerdc006c12013-05-15 14:54:07 -0700288
Julius Werner68aef112013-09-03 15:07:31 -0700289 setup_usb();
290
Stefan Reinauera86c33a2013-05-17 10:34:25 -0700291 // Uncomment to get excessive GPIO output:
292 // gpio_info();
Stefan Reinauer2ae6d6f2013-05-09 16:16:13 -0700293}
294
Elyes HAOUASd129d432018-05-04 20:23:33 +0200295static void mainboard_enable(struct device *dev)
Stefan Reinauer2ae6d6f2013-05-09 16:16:13 -0700296{
297 dev->ops->init = &mainboard_init;
298
Stefan Reinauer2ae6d6f2013-05-09 16:16:13 -0700299 /* set up dcache and MMU */
300 /* FIXME: this should happen via resource allocator */
301 exynos5250_config_l2_cache();
302 mmu_init();
303 mmu_config_range(0, DRAM_START, DCACHE_OFF);
304 mmu_config_range(DRAM_START, DRAM_SIZE, DCACHE_WRITEBACK);
Julius Wernerec5e5e02014-08-20 15:29:56 -0700305 mmu_config_range((uintptr_t)_dma_coherent/MiB,
Julius Werner7e0dea62019-02-20 18:39:22 -0800306 REGION_SIZE(dma_coherent)/MiB, DCACHE_OFF);
Stefan Reinauer2ae6d6f2013-05-09 16:16:13 -0700307 mmu_config_range(DRAM_END, 4096 - DRAM_END, DCACHE_OFF);
Stefan Reinauer2ae6d6f2013-05-09 16:16:13 -0700308 dcache_mmu_enable();
309
Martin Rothad0f4852019-10-23 21:41:43 -0600310 const unsigned int epll_hz = 192000000;
311 const unsigned int sample_rate = 48000;
312 const unsigned int lr_frame_size = 256;
Stefan Reinauer2ae6d6f2013-05-09 16:16:13 -0700313 clock_epll_set_rate(epll_hz);
314 clock_select_i2s_clk_source();
315 clock_set_i2s_clk_prescaler(epll_hz, sample_rate * lr_frame_size);
316
317 power_enable_xclkout();
318}
319
Ronald G. Minnichf89e6b22012-12-10 16:13:43 -0800320struct chip_operations mainboard_ops = {
David Hendricks054c83a2015-01-09 11:46:43 -0800321 .name = "daisy",
322 .enable_dev = mainboard_enable,
Ronald G. Minnichf89e6b22012-12-10 16:13:43 -0800323};
Julius Wernerb8fad3d2013-08-27 15:48:32 -0700324
325void lb_board(struct lb_header *header)
326{
327 struct lb_range *dma;
328
329 dma = (struct lb_range *)lb_new_record(header);
Patrick Georgi68999a82019-05-23 12:44:00 +0200330 dma->tag = LB_TAG_DMA;
Julius Wernerb8fad3d2013-08-27 15:48:32 -0700331 dma->size = sizeof(*dma);
Julius Wernerec5e5e02014-08-20 15:29:56 -0700332 dma->range_start = (uintptr_t)_dma_coherent;
Julius Werner7e0dea62019-02-20 18:39:22 -0800333 dma->range_size = REGION_SIZE(dma_coherent);
Julius Wernerb8fad3d2013-08-27 15:48:32 -0700334}