blob: 238b9637badd03aea3ddd1055715f6f91d3564d3 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Pali Rohár248ef0a2012-10-29 07:54:01 +00002/*
3 * (C) Copyright 2012
4 * Ивайло Димитров <freemangordon@abv.bg>
5 *
6 * (C) Copyright 2011-2012
Pali Rohár10a953d2020-04-01 00:35:08 +02007 * Pali Rohár <pali@kernel.org>
Pali Rohár248ef0a2012-10-29 07:54:01 +00008 *
9 * (C) Copyright 2010
10 * Alistair Buxton <a.j.buxton@gmail.com>
11 *
12 * Derived from Beagle Board and 3430 SDP code:
13 * (C) Copyright 2004-2008
14 * Texas Instruments, <www.ti.com>
15 *
16 * Author :
17 * Sunil Kumar <sunilsaini05@gmail.com>
18 * Shashi Ranjan <shashiranjanmca05@gmail.com>
19 *
20 * Richard Woodruff <r-woodruff2@ti.com>
21 * Syed Mohammed Khasim <khasim@ti.com>
Pali Rohár248ef0a2012-10-29 07:54:01 +000022 */
23
24#include <common.h>
Pali Rohárd73afb22020-10-26 23:45:11 +010025#include <dm.h>
Simon Glass5e6201b2019-08-01 09:46:51 -060026#include <env.h>
Simon Glass97589732020-05-10 11:40:02 -060027#include <init.h>
Pali Rohár248ef0a2012-10-29 07:54:01 +000028#include <watchdog.h>
Pali Rohár126038a2021-03-09 21:19:15 +010029#include <wdt.h>
Pali Rohár248ef0a2012-10-29 07:54:01 +000030#include <malloc.h>
31#include <twl4030.h>
32#include <i2c.h>
Pali Rohár1d701a52022-03-09 20:46:01 +010033#include <video.h>
Pali Rohár54a30142022-02-03 19:38:50 +010034#include <keyboard.h>
Pali Rohárbf961ad2022-04-13 21:34:14 +020035#include <ns16550.h>
Simon Glass3ba929a2020-10-30 21:38:53 -060036#include <asm/global_data.h>
Pali Rohár248ef0a2012-10-29 07:54:01 +000037#include <asm/io.h>
38#include <asm/setup.h>
39#include <asm/bitops.h>
40#include <asm/mach-types.h>
Pali Rohárd73afb22020-10-26 23:45:11 +010041#include <asm/omap_i2c.h>
Pali Rohár248ef0a2012-10-29 07:54:01 +000042#include <asm/arch/mux.h>
43#include <asm/arch/sys_proto.h>
44#include <asm/arch/mmc_host_def.h>
45
Pali Rohár248ef0a2012-10-29 07:54:01 +000046#include "tag_omap.h"
47
Pali Rohár9157a8c2021-02-07 14:50:15 +010048/* Needed for ROM SMC call */
49struct emu_hal_params_rx51 {
50 u32 num_params;
51 u32 param1;
52 u32 param2;
53 u32 param3;
54 u32 param4;
55};
56
57#define ONENAND_GPMC_CONFIG1_RX51 0xfb001202
58#define ONENAND_GPMC_CONFIG2_RX51 0x00111100
59#define ONENAND_GPMC_CONFIG3_RX51 0x00020200
60#define ONENAND_GPMC_CONFIG4_RX51 0x11001102
61#define ONENAND_GPMC_CONFIG5_RX51 0x03101616
62#define ONENAND_GPMC_CONFIG6_RX51 0x90060000
63
Pali Rohár248ef0a2012-10-29 07:54:01 +000064DECLARE_GLOBAL_DATA_PTR;
65
Pali Rohár248ef0a2012-10-29 07:54:01 +000066const omap3_sysinfo sysinfo = {
67 DDR_STACKED,
68 "Nokia RX-51",
69 "OneNAND"
70};
71
72/* This structure contains default omap tags needed for booting Maemo 5 */
73static struct tag_omap omap[] = {
74 OMAP_TAG_UART_CONFIG(0x04),
75 OMAP_TAG_SERIAL_CONSOLE_CONFIG(0x03, 0x01C200),
76 OMAP_TAG_LCD_CONFIG("acx565akm", "internal", 90, 0x18),
77 OMAP_TAG_GPIO_SWITCH_CONFIG("cam_focus", 0x44, 0x1, 0x2, 0x0),
78 OMAP_TAG_GPIO_SWITCH_CONFIG("cam_launch", 0x45, 0x1, 0x2, 0x0),
79 OMAP_TAG_GPIO_SWITCH_CONFIG("cam_shutter", 0x6e, 0x1, 0x0, 0x0),
80 OMAP_TAG_GPIO_SWITCH_CONFIG("cmt_apeslpx", 0x46, 0x2, 0x2, 0x0),
81 OMAP_TAG_GPIO_SWITCH_CONFIG("cmt_bsi", 0x9d, 0x2, 0x2, 0x0),
82 OMAP_TAG_GPIO_SWITCH_CONFIG("cmt_en", 0x4a, 0x2, 0x2, 0x0),
83 OMAP_TAG_GPIO_SWITCH_CONFIG("cmt_rst", 0x4b, 0x6, 0x2, 0x0),
84 OMAP_TAG_GPIO_SWITCH_CONFIG("cmt_rst_rq", 0x49, 0x6, 0x2, 0x0),
85 OMAP_TAG_GPIO_SWITCH_CONFIG("cmt_wddis", 0x0d, 0x2, 0x2, 0x0),
86 OMAP_TAG_GPIO_SWITCH_CONFIG("headphone", 0xb1, 0x1, 0x1, 0x0),
87 OMAP_TAG_GPIO_SWITCH_CONFIG("kb_lock", 0x71, 0x1, 0x0, 0x0),
88 OMAP_TAG_GPIO_SWITCH_CONFIG("proximity", 0x59, 0x0, 0x0, 0x0),
89 OMAP_TAG_GPIO_SWITCH_CONFIG("sleep_ind", 0xa2, 0x2, 0x2, 0x0),
90 OMAP_TAG_GPIO_SWITCH_CONFIG("slide", GPIO_SLIDE, 0x0, 0x0, 0x0),
91 OMAP_TAG_WLAN_CX3110X_CONFIG(0x25, 0xff, 87, 42, -1),
Pali Rohár7ce37522020-04-01 00:35:13 +020092 OMAP_TAG_PARTITION_CONFIG("bootloader", 128 * 1024, 0x00000000, 0x00000003),
93 OMAP_TAG_PARTITION_CONFIG("config", 384 * 1024, 0x00020000, 0x00000000),
94 OMAP_TAG_PARTITION_CONFIG("log", 256 * 1024, 0x00080000, 0x00000000),
95 OMAP_TAG_PARTITION_CONFIG("kernel", 2 * 1024*1024, 0x000c0000, 0x00000000),
96 OMAP_TAG_PARTITION_CONFIG("initfs", 2 * 1024*1024, 0x002c0000, 0x00000000),
97 OMAP_TAG_PARTITION_CONFIG("rootfs", 257280 * 1024, 0x004c0000, 0x00000000),
Pali Rohár248ef0a2012-10-29 07:54:01 +000098 OMAP_TAG_BOOT_REASON_CONFIG("pwr_key"),
99 OMAP_TAG_VERSION_STR_CONFIG("product", "RX-51"),
100 OMAP_TAG_VERSION_STR_CONFIG("hw-build", "2101"),
101 OMAP_TAG_VERSION_STR_CONFIG("nolo", "1.4.14"),
102 OMAP_TAG_VERSION_STR_CONFIG("boot-mode", "normal"),
103 { }
104};
105
106static char *boot_reason_ptr;
107static char *hw_build_ptr;
108static char *nolo_version_ptr;
109static char *boot_mode_ptr;
Pali Rohár02f45842020-04-01 00:35:14 +0200110static int serial_was_console_enabled;
Pali Rohár248ef0a2012-10-29 07:54:01 +0000111
112/*
113 * Routine: init_omap_tags
114 * Description: Initialize pointers to values in tag_omap
115 */
116static void init_omap_tags(void)
117{
118 char *component;
119 char *version;
120 int i = 0;
121 while (omap[i].hdr.tag) {
122 switch (omap[i].hdr.tag) {
123 case OMAP_TAG_BOOT_REASON:
124 boot_reason_ptr = omap[i].u.boot_reason.reason_str;
125 break;
126 case OMAP_TAG_VERSION_STR:
127 component = omap[i].u.version.component;
128 version = omap[i].u.version.version;
129 if (strcmp(component, "hw-build") == 0)
130 hw_build_ptr = version;
131 else if (strcmp(component, "nolo") == 0)
132 nolo_version_ptr = version;
133 else if (strcmp(component, "boot-mode") == 0)
134 boot_mode_ptr = version;
135 break;
136 default:
137 break;
138 }
139 i++;
140 }
141}
142
143static void reuse_omap_atags(struct tag_omap *t)
144{
145 char *component;
146 char *version;
147 while (t->hdr.tag) {
148 switch (t->hdr.tag) {
149 case OMAP_TAG_BOOT_REASON:
150 memset(boot_reason_ptr, 0, 12);
151 strcpy(boot_reason_ptr, t->u.boot_reason.reason_str);
152 break;
153 case OMAP_TAG_VERSION_STR:
154 component = t->u.version.component;
155 version = t->u.version.version;
156 if (strcmp(component, "hw-build") == 0) {
157 memset(hw_build_ptr, 0, 12);
158 strcpy(hw_build_ptr, version);
159 } else if (strcmp(component, "nolo") == 0) {
160 memset(nolo_version_ptr, 0, 12);
161 strcpy(nolo_version_ptr, version);
162 } else if (strcmp(component, "boot-mode") == 0) {
163 memset(boot_mode_ptr, 0, 12);
164 strcpy(boot_mode_ptr, version);
165 }
166 break;
Pali Rohár02f45842020-04-01 00:35:14 +0200167 case OMAP_TAG_UART:
Pali Roháre01ae762020-06-01 00:29:10 +0200168 if (t->u.uart.enabled_uarts)
Pali Rohár02f45842020-04-01 00:35:14 +0200169 serial_was_console_enabled = 1;
170 break;
171 case OMAP_TAG_SERIAL_CONSOLE:
172 serial_was_console_enabled = 1;
173 break;
Pali Rohár248ef0a2012-10-29 07:54:01 +0000174 default:
175 break;
176 }
177 t = tag_omap_next(t);
178 }
179}
180
181/*
182 * Routine: reuse_atags
183 * Description: Reuse atags from previous bootloader.
184 * Reuse only only HW build, boot reason, boot mode and nolo
185 */
186static void reuse_atags(void)
187{
188 struct tag *t = (struct tag *)gd->bd->bi_boot_params;
189
190 /* First tag must be ATAG_CORE */
191 if (t->hdr.tag != ATAG_CORE)
192 return;
193
194 if (!boot_reason_ptr || !hw_build_ptr)
195 return;
196
197 /* Last tag must be ATAG_NONE */
198 while (t->hdr.tag != ATAG_NONE) {
199 switch (t->hdr.tag) {
200 case ATAG_REVISION:
201 memset(hw_build_ptr, 0, 12);
202 sprintf(hw_build_ptr, "%x", t->u.revision.rev);
203 break;
204 case ATAG_BOARD:
205 reuse_omap_atags((struct tag_omap *)&t->u);
206 break;
207 default:
208 break;
209 }
210 t = tag_next(t);
211 }
212}
213
214/*
215 * Routine: board_init
216 * Description: Early hardware init.
217 */
218int board_init(void)
219{
Ivaylo Dimitrovbe2ff862020-10-31 17:32:49 +0100220#if defined(CONFIG_CMD_ONENAND)
221 const u32 gpmc_regs_onenandrx51[GPMC_MAX_REG] = {
222 ONENAND_GPMC_CONFIG1_RX51,
223 ONENAND_GPMC_CONFIG2_RX51,
224 ONENAND_GPMC_CONFIG3_RX51,
225 ONENAND_GPMC_CONFIG4_RX51,
226 ONENAND_GPMC_CONFIG5_RX51,
227 ONENAND_GPMC_CONFIG6_RX51,
228 0
229 };
230#endif
Pali Rohár248ef0a2012-10-29 07:54:01 +0000231 /* in SRAM or SDRAM, finish GPMC */
232 gpmc_init();
Ivaylo Dimitrovbe2ff862020-10-31 17:32:49 +0100233#if defined(CONFIG_CMD_ONENAND)
234 enable_gpmc_cs_config(gpmc_regs_onenandrx51, &gpmc_cfg->cs[0],
Tom Rini6a5dccc2022-11-16 13:10:41 -0500235 CFG_SYS_ONENAND_BASE, GPMC_SIZE_256M);
Ivaylo Dimitrovbe2ff862020-10-31 17:32:49 +0100236#endif
Pali Rohár6327bac2020-10-31 17:32:46 +0100237 /* Enable the clks & power */
238 per_clocks_enable();
Pali Rohár248ef0a2012-10-29 07:54:01 +0000239 /* boot param addr */
240 gd->bd->bi_boot_params = OMAP34XX_SDRC_CS0 + 0x100;
241 return 0;
242}
243
Tom Rini4cc38852021-08-30 09:16:30 -0400244#ifdef CONFIG_REVISION_TAG
Pali Rohár248ef0a2012-10-29 07:54:01 +0000245/*
246 * Routine: get_board_revision
247 * Description: Return board revision.
248 */
249u32 get_board_rev(void)
250{
251 return simple_strtol(hw_build_ptr, NULL, 16);
252}
Tom Rini4cc38852021-08-30 09:16:30 -0400253#endif
Pali Rohár248ef0a2012-10-29 07:54:01 +0000254
255/*
256 * Routine: setup_board_tags
257 * Description: Append board specific boot tags.
258 */
259void setup_board_tags(struct tag **in_params)
260{
261 int setup_console_atag;
262 char *setup_boot_reason_atag;
263 char *setup_boot_mode_atag;
264 char *str;
265 int i;
266 int size;
267 int total_size;
268 struct tag *params;
269 struct tag_omap *t;
270
271 params = (struct tag *)gd->bd->bi_boot_params;
272
273 params->u.core.flags = 0x0;
274 params->u.core.pagesize = 0x1000;
275 params->u.core.rootdev = 0x0;
276
277 /* append omap atag only if env setup_omap_atag is set to 1 */
Simon Glass64b723f2017-08-03 12:22:12 -0600278 str = env_get("setup_omap_atag");
Pali Rohár248ef0a2012-10-29 07:54:01 +0000279 if (!str || str[0] != '1')
280 return;
281
Simon Glass64b723f2017-08-03 12:22:12 -0600282 str = env_get("setup_console_atag");
Pali Rohár02f45842020-04-01 00:35:14 +0200283 if (str && str[0]) {
284 if (str[0] == '1')
285 setup_console_atag = 1;
286 else
287 setup_console_atag = 0;
288 } else {
289 if (serial_was_console_enabled)
290 setup_console_atag = 1;
291 else
292 setup_console_atag = 0;
293 }
Pali Rohár248ef0a2012-10-29 07:54:01 +0000294
Simon Glass64b723f2017-08-03 12:22:12 -0600295 setup_boot_reason_atag = env_get("setup_boot_reason_atag");
296 setup_boot_mode_atag = env_get("setup_boot_mode_atag");
Pali Rohár248ef0a2012-10-29 07:54:01 +0000297
298 params = *in_params;
299 t = (struct tag_omap *)&params->u;
300 total_size = sizeof(struct tag_header);
301
302 for (i = 0; omap[i].hdr.tag; i++) {
303
304 /* skip serial console tag */
305 if (!setup_console_atag &&
306 omap[i].hdr.tag == OMAP_TAG_SERIAL_CONSOLE)
307 continue;
308
309 size = omap[i].hdr.size + sizeof(struct tag_omap_header);
310 memcpy(t, &omap[i], size);
311
312 /* set uart tag to 0 - disable serial console */
313 if (!setup_console_atag && omap[i].hdr.tag == OMAP_TAG_UART)
314 t->u.uart.enabled_uarts = 0;
315
316 /* change boot reason */
317 if (setup_boot_reason_atag &&
318 omap[i].hdr.tag == OMAP_TAG_BOOT_REASON) {
319 memset(t->u.boot_reason.reason_str, 0, 12);
320 strcpy(t->u.boot_reason.reason_str,
321 setup_boot_reason_atag);
322 }
323
324 /* change boot mode */
325 if (setup_boot_mode_atag &&
326 omap[i].hdr.tag == OMAP_TAG_VERSION_STR &&
327 strcmp(omap[i].u.version.component, "boot-mode") == 0) {
328 memset(t->u.version.version, 0, 12);
329 strcpy(t->u.version.version, setup_boot_mode_atag);
330 }
331
332 total_size += size;
333 t = tag_omap_next(t);
334
335 }
336
337 params->hdr.tag = ATAG_BOARD;
338 params->hdr.size = total_size >> 2;
339 params = tag_next(params);
340
341 *in_params = params;
342}
343
Pali Rohár1d701a52022-03-09 20:46:01 +0100344static int rx51_video_probe(struct udevice *dev)
Pali Rohár248ef0a2012-10-29 07:54:01 +0000345{
Pali Rohár1d701a52022-03-09 20:46:01 +0100346 struct video_uc_plat *uc_plat = dev_get_uclass_plat(dev);
347 struct video_priv *uc_priv = dev_get_uclass_priv(dev);
348
349 uc_plat->base = 0x8f9c0000;
350 uc_plat->size = 800 * 480 * sizeof(u16);
351 uc_priv->xsize = 800;
352 uc_priv->ysize = 480;
353 uc_priv->bpix = VIDEO_BPP16;
354
355 video_set_flush_dcache(dev, true);
356
357 return 0;
Pali Rohár248ef0a2012-10-29 07:54:01 +0000358}
359
Pali Rohár1d701a52022-03-09 20:46:01 +0100360U_BOOT_DRIVER(rx51_video) = {
361 .name = "rx51_video",
362 .id = UCLASS_VIDEO,
363 .probe = rx51_video_probe,
364};
365
Pali Rohár248ef0a2012-10-29 07:54:01 +0000366/*
367 * Routine: twl4030_regulator_set_mode
368 * Description: Set twl4030 regulator mode over i2c powerbus.
369 */
370static void twl4030_regulator_set_mode(u8 id, u8 mode)
371{
372 u16 msg = MSG_SINGULAR(DEV_GRP_P1, id, mode);
Nishanth Menond26a1062013-03-26 05:20:49 +0000373 twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER,
374 TWL4030_PM_MASTER_PB_WORD_MSB, msg >> 8);
375 twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER,
376 TWL4030_PM_MASTER_PB_WORD_LSB, msg & 0xff);
Pali Rohár248ef0a2012-10-29 07:54:01 +0000377}
378
379static void omap3_emu_romcode_call(u32 service_id, u32 *parameters)
380{
381 u32 i, num_params = *parameters;
382 u32 *sram_scratch_space = (u32 *)OMAP3_PUBLIC_SRAM_SCRATCH_AREA;
383
384 /*
385 * copy the parameters to an un-cached area to avoid coherency
386 * issues
387 */
388 for (i = 0; i < num_params; i++) {
389 __raw_writel(*parameters, sram_scratch_space);
390 parameters++;
391 sram_scratch_space++;
392 }
393
394 /* Now make the PPA call */
395 do_omap3_emu_romcode_call(service_id, OMAP3_PUBLIC_SRAM_SCRATCH_AREA);
396}
397
Nishanth Menon53fee1e2015-03-09 17:12:09 -0500398void omap3_set_aux_cr_secure(u32 acr)
399{
400 struct emu_hal_params_rx51 emu_romcode_params = { 0, };
401
402 emu_romcode_params.num_params = 2;
403 emu_romcode_params.param1 = acr;
404
405 omap3_emu_romcode_call(OMAP3_EMU_HAL_API_WRITE_ACR,
406 (u32 *)&emu_romcode_params);
407}
408
Pali Rohár248ef0a2012-10-29 07:54:01 +0000409/*
410 * Routine: omap3_update_aux_cr_secure_rx51
411 * Description: Modify the contents Auxiliary Control Register.
412 * Parameters:
413 * set_bits - bits to set in ACR
414 * clr_bits - bits to clear in ACR
415 */
416static void omap3_update_aux_cr_secure_rx51(u32 set_bits, u32 clear_bits)
417{
Pali Rohár248ef0a2012-10-29 07:54:01 +0000418 u32 acr;
419
420 /* Read ACR */
421 asm volatile ("mrc p15, 0, %0, c1, c0, 1" : "=r" (acr));
422 acr &= ~clear_bits;
423 acr |= set_bits;
Nishanth Menon53fee1e2015-03-09 17:12:09 -0500424 omap3_set_aux_cr_secure(acr);
Pali Rohár248ef0a2012-10-29 07:54:01 +0000425}
426
427/*
428 * Routine: misc_init_r
429 * Description: Configure board specific parts.
430 */
431int misc_init_r(void)
432{
Pali Rohárd73afb22020-10-26 23:45:11 +0100433 struct udevice *dev;
Pali Rohár248ef0a2012-10-29 07:54:01 +0000434 char buf[12];
435 u8 state;
436
Pali Rohár977229b2020-10-31 17:32:47 +0100437 /* disable lp5523 led */
Pali Rohárd73afb22020-10-26 23:45:11 +0100438 if (i2c_get_chip_for_busnum(1, 0x32, 1, &dev) == 0)
Pali Rohár977229b2020-10-31 17:32:47 +0100439 dm_i2c_reg_write(dev, 0x00, 0x00);
Pali Rohár248ef0a2012-10-29 07:54:01 +0000440
441 /* initialize twl4030 power managment */
442 twl4030_power_init();
Pali Rohárcc58d292021-01-16 01:04:54 +0100443 twl4030_power_mmc_init(0);
444 twl4030_power_mmc_init(1);
Pali Rohár248ef0a2012-10-29 07:54:01 +0000445
446 /* set VSIM to 1.8V */
447 twl4030_pmrecv_vsel_cfg(TWL4030_PM_RECEIVER_VSIM_DEDICATED,
448 TWL4030_PM_RECEIVER_VSIM_VSEL_18,
449 TWL4030_PM_RECEIVER_VSIM_DEV_GRP,
450 TWL4030_PM_RECEIVER_DEV_GRP_P1);
451
452 /* store I2C access state */
Nishanth Menon5d9d6f72013-03-26 05:20:50 +0000453 twl4030_i2c_read_u8(TWL4030_CHIP_PM_MASTER, TWL4030_PM_MASTER_PB_CFG,
454 &state);
Pali Rohár248ef0a2012-10-29 07:54:01 +0000455
456 /* enable I2C access to powerbus (needed for twl4030 regulator) */
Nishanth Menond26a1062013-03-26 05:20:49 +0000457 twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER, TWL4030_PM_MASTER_PB_CFG,
458 0x02);
Pali Rohár248ef0a2012-10-29 07:54:01 +0000459
460 /* set VAUX3, VSIM and VMMC1 state to active - enable eMMC memory */
461 twl4030_regulator_set_mode(RES_VAUX3, RES_STATE_ACTIVE);
462 twl4030_regulator_set_mode(RES_VSIM, RES_STATE_ACTIVE);
463 twl4030_regulator_set_mode(RES_VMMC1, RES_STATE_ACTIVE);
464
465 /* restore I2C access state */
Nishanth Menond26a1062013-03-26 05:20:49 +0000466 twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER, TWL4030_PM_MASTER_PB_CFG,
467 state);
Pali Rohár248ef0a2012-10-29 07:54:01 +0000468
469 /* set env variable attkernaddr for relocated kernel */
470 sprintf(buf, "%#x", KERNEL_ADDRESS);
Simon Glass6a38e412017-08-03 12:22:09 -0600471 env_set("attkernaddr", buf);
Pali Rohár248ef0a2012-10-29 07:54:01 +0000472
473 /* initialize omap tags */
474 init_omap_tags();
475
476 /* reuse atags from previous bootloader */
477 reuse_atags();
478
Paul Kocialkowski6bc318e2015-08-27 19:37:13 +0200479 omap_die_id_display();
Pali Rohár248ef0a2012-10-29 07:54:01 +0000480 print_cpuinfo();
481
482 /*
483 * Cortex-A8(r1p0..r1p2) errata 430973 workaround
484 * Set IBE bit in Auxiliary Control Register
Pali Rohár415b8042015-01-08 10:11:40 +0100485 *
486 * Call this routine only on real secure device
487 * Qemu does not implement secure PPA and crash
Pali Rohár248ef0a2012-10-29 07:54:01 +0000488 */
Pali Rohár415b8042015-01-08 10:11:40 +0100489 if (get_device_type() == HS_DEVICE)
490 omap3_update_aux_cr_secure_rx51(1 << 6, 0);
Pali Rohár248ef0a2012-10-29 07:54:01 +0000491
492 return 0;
493}
494
Pali Rohár248ef0a2012-10-29 07:54:01 +0000495static unsigned long int twl_wd_time; /* last time of watchdog reset */
496static unsigned long int twl_i2c_lock;
497
498/*
Pali Rohár126038a2021-03-09 21:19:15 +0100499 * Routine: rx51_watchdog_reset
Pali Rohár248ef0a2012-10-29 07:54:01 +0000500 * Description: Reset timeout of twl4030 watchdog.
501 */
Pali Rohár126038a2021-03-09 21:19:15 +0100502static int rx51_watchdog_reset(struct udevice *dev)
Pali Rohár248ef0a2012-10-29 07:54:01 +0000503{
504 u8 timeout = 0;
505
506 /* do not reset watchdog too often - max every 4s */
507 if (get_timer(twl_wd_time) < 4 * CONFIG_SYS_HZ)
Pali Rohár126038a2021-03-09 21:19:15 +0100508 return 0;
Pali Rohár248ef0a2012-10-29 07:54:01 +0000509
510 /* localy lock twl4030 i2c bus */
511 if (test_and_set_bit(0, &twl_i2c_lock))
Pali Rohár126038a2021-03-09 21:19:15 +0100512 return 0;
Pali Rohár248ef0a2012-10-29 07:54:01 +0000513
514 /* read actual watchdog timeout */
Nishanth Menon5d9d6f72013-03-26 05:20:50 +0000515 twl4030_i2c_read_u8(TWL4030_CHIP_PM_RECEIVER,
516 TWL4030_PM_RECEIVER_WATCHDOG_CFG, &timeout);
Pali Rohár248ef0a2012-10-29 07:54:01 +0000517
518 /* timeout 0 means watchdog is disabled */
519 /* reset watchdog timeout to 31s (maximum) */
520 if (timeout != 0)
Nishanth Menond26a1062013-03-26 05:20:49 +0000521 twl4030_i2c_write_u8(TWL4030_CHIP_PM_RECEIVER,
522 TWL4030_PM_RECEIVER_WATCHDOG_CFG, 31);
Pali Rohár248ef0a2012-10-29 07:54:01 +0000523
524 /* store last watchdog reset time */
525 twl_wd_time = get_timer(0);
526
527 /* localy unlock twl4030 i2c bus */
528 test_and_clear_bit(0, &twl_i2c_lock);
Pali Rohár126038a2021-03-09 21:19:15 +0100529
530 return 0;
531}
532
533static int rx51_watchdog_start(struct udevice *dev, u64 timeout_ms, ulong flags)
534{
535 return 0;
Pali Rohár248ef0a2012-10-29 07:54:01 +0000536}
537
Pali Rohár126038a2021-03-09 21:19:15 +0100538static int rx51_watchdog_probe(struct udevice *dev)
539{
540 return 0;
541}
542
543static const struct wdt_ops rx51_watchdog_ops = {
544 .start = rx51_watchdog_start,
545 .reset = rx51_watchdog_reset,
546};
547
548U_BOOT_DRIVER(rx51_watchdog) = {
549 .name = "rx51_watchdog",
550 .id = UCLASS_WDT,
551 .ops = &rx51_watchdog_ops,
552 .probe = rx51_watchdog_probe,
553};
554
Pali Rohár248ef0a2012-10-29 07:54:01 +0000555/*
556 * TWL4030 keypad handler for cfb_console
557 */
558
559static const char keymap[] = {
560 /* normal */
561 'q', 'o', 'p', ',', '\b', 0, 'a', 's',
562 'w', 'd', 'f', 'g', 'h', 'j', 'k', 'l',
563 'e', '.', 0, '\r', 0, 'z', 'x', 'c',
Pali Rohárb91575c2022-10-09 21:38:25 +0200564 'r', 'v', 'b', 'n', 'm', ' ', 0, 0,
Pali Rohár248ef0a2012-10-29 07:54:01 +0000565 't', 0, 0, 0, 0, 0, 0, 0,
566 'y', 0, 0, 0, 0, 0, 0, 0,
567 'u', 0, 0, 0, 0, 0, 0, 0,
568 'i', 5, 6, 0, 0, 0, 0, 0,
569 /* fn */
570 '1', '9', '0', '=', '\b', 0, '*', '+',
571 '2', '#', '-', '_', '(', ')', '&', '!',
572 '3', '?', '^', '\r', 0, 156, '$', 238,
573 '4', '/', '\\', '"', '\'', '@', 0, '<',
574 '5', '|', '>', 0, 0, 0, 0, 0,
575 '6', 0, 0, 0, 0, 0, 0, 0,
576 '7', 0, 0, 0, 0, 0, 0, 0,
577 '8', 16, 17, 0, 0, 0, 0, 0,
578};
579
580static u8 keys[8];
581static u8 old_keys[8] = {0, 0, 0, 0, 0, 0, 0, 0};
582#define KEYBUF_SIZE 32
583static u8 keybuf[KEYBUF_SIZE];
584static u8 keybuf_head;
585static u8 keybuf_tail;
586
587/*
Pali Rohár54a30142022-02-03 19:38:50 +0100588 * Routine: rx51_kp_start
Pali Rohár248ef0a2012-10-29 07:54:01 +0000589 * Description: Initialize HW keyboard.
590 */
Pali Rohár54a30142022-02-03 19:38:50 +0100591static int rx51_kp_start(struct udevice *dev)
Pali Rohár248ef0a2012-10-29 07:54:01 +0000592{
593 int ret = 0;
594 u8 ctrl;
Nishanth Menon5d9d6f72013-03-26 05:20:50 +0000595 ret = twl4030_i2c_read_u8(TWL4030_CHIP_KEYPAD,
596 TWL4030_KEYPAD_KEYP_CTRL_REG, &ctrl);
Pali Rohár248ef0a2012-10-29 07:54:01 +0000597
598 if (ret)
599 return ret;
600
601 /* turn on keyboard and use hardware scanning */
602 ctrl |= TWL4030_KEYPAD_CTRL_KBD_ON;
603 ctrl |= TWL4030_KEYPAD_CTRL_SOFT_NRST;
604 ctrl |= TWL4030_KEYPAD_CTRL_SOFTMODEN;
Nishanth Menond26a1062013-03-26 05:20:49 +0000605 ret |= twl4030_i2c_write_u8(TWL4030_CHIP_KEYPAD,
606 TWL4030_KEYPAD_KEYP_CTRL_REG, ctrl);
Pali Rohár248ef0a2012-10-29 07:54:01 +0000607 /* enable key event status */
Nishanth Menond26a1062013-03-26 05:20:49 +0000608 ret |= twl4030_i2c_write_u8(TWL4030_CHIP_KEYPAD,
609 TWL4030_KEYPAD_KEYP_IMR1, 0xfe);
Pali Rohár248ef0a2012-10-29 07:54:01 +0000610 /* enable interrupt generation on rising and falling */
611 /* this is a workaround for qemu twl4030 emulation */
Nishanth Menond26a1062013-03-26 05:20:49 +0000612 ret |= twl4030_i2c_write_u8(TWL4030_CHIP_KEYPAD,
613 TWL4030_KEYPAD_KEYP_EDR, 0x57);
Pali Rohár248ef0a2012-10-29 07:54:01 +0000614 /* enable ISR clear on read */
Nishanth Menond26a1062013-03-26 05:20:49 +0000615 ret |= twl4030_i2c_write_u8(TWL4030_CHIP_KEYPAD,
616 TWL4030_KEYPAD_KEYP_SIH_CTRL, 0x05);
Pali Rohár248ef0a2012-10-29 07:54:01 +0000617 return 0;
618}
619
620static void rx51_kp_fill(u8 k, u8 mods)
621{
622 /* check if some cursor key without meta fn key was pressed */
623 if (!(mods & 2) && (k == 18 || k == 31 || k == 33 || k == 34)) {
624 keybuf[keybuf_tail++] = '\e';
625 keybuf_tail %= KEYBUF_SIZE;
626 keybuf[keybuf_tail++] = '[';
627 keybuf_tail %= KEYBUF_SIZE;
628 if (k == 18) /* up */
629 keybuf[keybuf_tail++] = 'A';
630 else if (k == 31) /* left */
631 keybuf[keybuf_tail++] = 'D';
632 else if (k == 33) /* down */
633 keybuf[keybuf_tail++] = 'B';
634 else if (k == 34) /* right */
635 keybuf[keybuf_tail++] = 'C';
636 keybuf_tail %= KEYBUF_SIZE;
637 return;
638 }
639
640 if (mods & 2) { /* fn meta key was pressed */
641 k = keymap[k+64];
642 } else {
643 k = keymap[k];
644 if (mods & 1) { /* ctrl key was pressed */
645 if (k >= 'a' && k <= 'z')
646 k -= 'a' - 1;
647 }
648 if (mods & 4) { /* shift key was pressed */
649 if (k >= 'a' && k <= 'z')
650 k += 'A' - 'a';
651 else if (k == '.')
652 k = ':';
653 else if (k == ',')
654 k = ';';
655 }
656 }
657 keybuf[keybuf_tail++] = k;
658 keybuf_tail %= KEYBUF_SIZE;
659}
660
661/*
662 * Routine: rx51_kp_tstc
663 * Description: Test if key was pressed (from buffer).
664 */
Pali Rohár54a30142022-02-03 19:38:50 +0100665static int rx51_kp_tstc(struct udevice *dev)
Pali Rohár248ef0a2012-10-29 07:54:01 +0000666{
667 u8 c, r, dk, i;
668 u8 intr;
669 u8 mods;
670
671 /* localy lock twl4030 i2c bus */
672 if (test_and_set_bit(0, &twl_i2c_lock))
673 return 0;
674
675 /* twl4030 remembers up to 2 events */
676 for (i = 0; i < 2; i++) {
677
678 /* check interrupt register for events */
Nishanth Menon5d9d6f72013-03-26 05:20:50 +0000679 twl4030_i2c_read_u8(TWL4030_CHIP_KEYPAD,
680 TWL4030_KEYPAD_KEYP_ISR1 + (2 * i), &intr);
Pali Rohár248ef0a2012-10-29 07:54:01 +0000681
682 /* no event */
683 if (!(intr&1))
684 continue;
685
686 /* read the key state */
Pali Rohárd73afb22020-10-26 23:45:11 +0100687 twl4030_i2c_read(TWL4030_CHIP_KEYPAD,
688 TWL4030_KEYPAD_FULL_CODE_7_0, keys, 8);
Pali Rohár248ef0a2012-10-29 07:54:01 +0000689
690 /* cut out modifier keys from the keystate */
691 mods = keys[4] >> 4;
692 keys[4] &= 0x0f;
693
Pali Rohárb91575c2022-10-09 21:38:25 +0200694 /* space key is indicated by two different bits */
695 keys[3] |= (keys[3] & (1 << 6)) >> 1;
696 keys[3] &= ~(1 << 6);
697
Pali Rohár248ef0a2012-10-29 07:54:01 +0000698 for (c = 0; c < 8; c++) {
699
700 /* get newly pressed keys only */
701 dk = ((keys[c] ^ old_keys[c])&keys[c]);
702 old_keys[c] = keys[c];
703
704 /* fill the keybuf */
705 for (r = 0; r < 8; r++) {
706 if (dk&1)
707 rx51_kp_fill((c*8)+r, mods);
708 dk = dk >> 1;
709 }
710
711 }
712
713 }
714
715 /* localy unlock twl4030 i2c bus */
716 test_and_clear_bit(0, &twl_i2c_lock);
717
718 return (KEYBUF_SIZE + keybuf_tail - keybuf_head)%KEYBUF_SIZE;
719}
720
721/*
722 * Routine: rx51_kp_getc
723 * Description: Get last pressed key (from buffer).
724 */
Pali Rohár54a30142022-02-03 19:38:50 +0100725static int rx51_kp_getc(struct udevice *dev)
Pali Rohár248ef0a2012-10-29 07:54:01 +0000726{
727 keybuf_head %= KEYBUF_SIZE;
Pali Rohár54a30142022-02-03 19:38:50 +0100728 while (!rx51_kp_tstc(dev))
Stefan Roese80877fa2022-09-02 14:10:46 +0200729 schedule();
Pali Rohár248ef0a2012-10-29 07:54:01 +0000730 return keybuf[keybuf_head++];
731}
732
Pali Rohár54a30142022-02-03 19:38:50 +0100733static int rx51_kp_probe(struct udevice *dev)
734{
735 struct keyboard_priv *uc_priv = dev_get_uclass_priv(dev);
736 struct stdio_dev *sdev = &uc_priv->sdev;
737
738 strcpy(sdev->name, "keyboard");
739 return input_stdio_register(sdev);
740}
741
742static const struct keyboard_ops rx51_kp_ops = {
743 .start = rx51_kp_start,
744 .tstc = rx51_kp_tstc,
745 .getc = rx51_kp_getc,
746};
747
748U_BOOT_DRIVER(rx51_kp) = {
749 .name = "rx51_kp",
750 .id = UCLASS_KEYBOARD,
751 .probe = rx51_kp_probe,
752 .ops = &rx51_kp_ops,
753};
754
Pali Rohárcc58d292021-01-16 01:04:54 +0100755static const struct mmc_config rx51_mmc_cfg = {
756 .host_caps = MMC_MODE_4BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS,
757 .f_min = 400000,
758 .f_max = 52000000,
759 .b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT,
760 .voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195,
761};
Paul Kocialkowski69559892014-11-08 20:55:47 +0100762
Pali Rohárcc58d292021-01-16 01:04:54 +0100763static const struct omap_hsmmc_plat rx51_mmc[] = {
764 { rx51_mmc_cfg, (struct hsmmc *)OMAP_HSMMC1_BASE },
765 { rx51_mmc_cfg, (struct hsmmc *)OMAP_HSMMC2_BASE },
766};
767
768U_BOOT_DRVINFOS(rx51_mmc) = {
769 { "omap_hsmmc", &rx51_mmc[0] },
770 { "omap_hsmmc", &rx51_mmc[1] },
771};
Pali Rohárd73afb22020-10-26 23:45:11 +0100772
Simon Glassb75b15b2020-12-03 16:55:23 -0700773static const struct omap_i2c_plat rx51_i2c[] = {
Pali Rohárde39c112020-11-21 23:30:11 +0100774 { I2C_BASE1, 100000, OMAP_I2C_REV_V1 },
Pali Rohárd73afb22020-10-26 23:45:11 +0100775 { I2C_BASE2, 100000, OMAP_I2C_REV_V1 },
Pali Rohárde39c112020-11-21 23:30:11 +0100776 { I2C_BASE3, 100000, OMAP_I2C_REV_V1 },
Pali Rohárd73afb22020-10-26 23:45:11 +0100777};
778
Simon Glass1d8364a2020-12-28 20:34:54 -0700779U_BOOT_DRVINFOS(rx51_i2c) = {
Pali Rohárd73afb22020-10-26 23:45:11 +0100780 { "i2c_omap", &rx51_i2c[0] },
781 { "i2c_omap", &rx51_i2c[1] },
782 { "i2c_omap", &rx51_i2c[2] },
783};
Pali Rohár126038a2021-03-09 21:19:15 +0100784
785U_BOOT_DRVINFOS(rx51_watchdog) = {
786 { "rx51_watchdog" },
787};
Pali Rohár54a30142022-02-03 19:38:50 +0100788
Pali Rohár1d701a52022-03-09 20:46:01 +0100789U_BOOT_DRVINFOS(rx51_video) = {
790 { "rx51_video" },
791};
792
Pali Rohár54a30142022-02-03 19:38:50 +0100793U_BOOT_DRVINFOS(rx51_kp) = {
794 { "rx51_kp" },
795};
Pali Rohárbf961ad2022-04-13 21:34:14 +0200796
797static const struct ns16550_plat rx51_serial = {
Tom Rinidf6a2152022-11-16 13:10:28 -0500798 .base = CFG_SYS_NS16550_COM3,
Pali Rohárbf961ad2022-04-13 21:34:14 +0200799 .reg_shift = 2,
Tom Rinidf6a2152022-11-16 13:10:28 -0500800 .clock = CFG_SYS_NS16550_CLK,
Pali Rohárbf961ad2022-04-13 21:34:14 +0200801 .fcr = UART_FCR_DEFVAL,
802};
803
804U_BOOT_DRVINFOS(rx51_uart) = {
805 { "omap_serial", &rx51_serial },
806};