blob: 621cff09561928756d269f44d85ce8fa7b9e3e9c [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>
Simon Glass3ba929a2020-10-30 21:38:53 -060035#include <asm/global_data.h>
Pali Rohár248ef0a2012-10-29 07:54:01 +000036#include <asm/io.h>
37#include <asm/setup.h>
38#include <asm/bitops.h>
39#include <asm/mach-types.h>
Pali Rohárd73afb22020-10-26 23:45:11 +010040#include <asm/omap_i2c.h>
Pali Rohár248ef0a2012-10-29 07:54:01 +000041#include <asm/arch/mux.h>
42#include <asm/arch/sys_proto.h>
43#include <asm/arch/mmc_host_def.h>
44
Pali Rohár248ef0a2012-10-29 07:54:01 +000045#include "tag_omap.h"
46
Pali Rohár9157a8c2021-02-07 14:50:15 +010047/* Needed for ROM SMC call */
48struct emu_hal_params_rx51 {
49 u32 num_params;
50 u32 param1;
51 u32 param2;
52 u32 param3;
53 u32 param4;
54};
55
56#define ONENAND_GPMC_CONFIG1_RX51 0xfb001202
57#define ONENAND_GPMC_CONFIG2_RX51 0x00111100
58#define ONENAND_GPMC_CONFIG3_RX51 0x00020200
59#define ONENAND_GPMC_CONFIG4_RX51 0x11001102
60#define ONENAND_GPMC_CONFIG5_RX51 0x03101616
61#define ONENAND_GPMC_CONFIG6_RX51 0x90060000
62
Pali Rohár248ef0a2012-10-29 07:54:01 +000063DECLARE_GLOBAL_DATA_PTR;
64
Pali Rohár248ef0a2012-10-29 07:54:01 +000065const omap3_sysinfo sysinfo = {
66 DDR_STACKED,
67 "Nokia RX-51",
68 "OneNAND"
69};
70
71/* This structure contains default omap tags needed for booting Maemo 5 */
72static struct tag_omap omap[] = {
73 OMAP_TAG_UART_CONFIG(0x04),
74 OMAP_TAG_SERIAL_CONSOLE_CONFIG(0x03, 0x01C200),
75 OMAP_TAG_LCD_CONFIG("acx565akm", "internal", 90, 0x18),
76 OMAP_TAG_GPIO_SWITCH_CONFIG("cam_focus", 0x44, 0x1, 0x2, 0x0),
77 OMAP_TAG_GPIO_SWITCH_CONFIG("cam_launch", 0x45, 0x1, 0x2, 0x0),
78 OMAP_TAG_GPIO_SWITCH_CONFIG("cam_shutter", 0x6e, 0x1, 0x0, 0x0),
79 OMAP_TAG_GPIO_SWITCH_CONFIG("cmt_apeslpx", 0x46, 0x2, 0x2, 0x0),
80 OMAP_TAG_GPIO_SWITCH_CONFIG("cmt_bsi", 0x9d, 0x2, 0x2, 0x0),
81 OMAP_TAG_GPIO_SWITCH_CONFIG("cmt_en", 0x4a, 0x2, 0x2, 0x0),
82 OMAP_TAG_GPIO_SWITCH_CONFIG("cmt_rst", 0x4b, 0x6, 0x2, 0x0),
83 OMAP_TAG_GPIO_SWITCH_CONFIG("cmt_rst_rq", 0x49, 0x6, 0x2, 0x0),
84 OMAP_TAG_GPIO_SWITCH_CONFIG("cmt_wddis", 0x0d, 0x2, 0x2, 0x0),
85 OMAP_TAG_GPIO_SWITCH_CONFIG("headphone", 0xb1, 0x1, 0x1, 0x0),
86 OMAP_TAG_GPIO_SWITCH_CONFIG("kb_lock", 0x71, 0x1, 0x0, 0x0),
87 OMAP_TAG_GPIO_SWITCH_CONFIG("proximity", 0x59, 0x0, 0x0, 0x0),
88 OMAP_TAG_GPIO_SWITCH_CONFIG("sleep_ind", 0xa2, 0x2, 0x2, 0x0),
89 OMAP_TAG_GPIO_SWITCH_CONFIG("slide", GPIO_SLIDE, 0x0, 0x0, 0x0),
90 OMAP_TAG_WLAN_CX3110X_CONFIG(0x25, 0xff, 87, 42, -1),
Pali Rohár7ce37522020-04-01 00:35:13 +020091 OMAP_TAG_PARTITION_CONFIG("bootloader", 128 * 1024, 0x00000000, 0x00000003),
92 OMAP_TAG_PARTITION_CONFIG("config", 384 * 1024, 0x00020000, 0x00000000),
93 OMAP_TAG_PARTITION_CONFIG("log", 256 * 1024, 0x00080000, 0x00000000),
94 OMAP_TAG_PARTITION_CONFIG("kernel", 2 * 1024*1024, 0x000c0000, 0x00000000),
95 OMAP_TAG_PARTITION_CONFIG("initfs", 2 * 1024*1024, 0x002c0000, 0x00000000),
96 OMAP_TAG_PARTITION_CONFIG("rootfs", 257280 * 1024, 0x004c0000, 0x00000000),
Pali Rohár248ef0a2012-10-29 07:54:01 +000097 OMAP_TAG_BOOT_REASON_CONFIG("pwr_key"),
98 OMAP_TAG_VERSION_STR_CONFIG("product", "RX-51"),
99 OMAP_TAG_VERSION_STR_CONFIG("hw-build", "2101"),
100 OMAP_TAG_VERSION_STR_CONFIG("nolo", "1.4.14"),
101 OMAP_TAG_VERSION_STR_CONFIG("boot-mode", "normal"),
102 { }
103};
104
105static char *boot_reason_ptr;
106static char *hw_build_ptr;
107static char *nolo_version_ptr;
108static char *boot_mode_ptr;
Pali Rohár02f45842020-04-01 00:35:14 +0200109static int serial_was_console_enabled;
Pali Rohár248ef0a2012-10-29 07:54:01 +0000110
111/*
112 * Routine: init_omap_tags
113 * Description: Initialize pointers to values in tag_omap
114 */
115static void init_omap_tags(void)
116{
117 char *component;
118 char *version;
119 int i = 0;
120 while (omap[i].hdr.tag) {
121 switch (omap[i].hdr.tag) {
122 case OMAP_TAG_BOOT_REASON:
123 boot_reason_ptr = omap[i].u.boot_reason.reason_str;
124 break;
125 case OMAP_TAG_VERSION_STR:
126 component = omap[i].u.version.component;
127 version = omap[i].u.version.version;
128 if (strcmp(component, "hw-build") == 0)
129 hw_build_ptr = version;
130 else if (strcmp(component, "nolo") == 0)
131 nolo_version_ptr = version;
132 else if (strcmp(component, "boot-mode") == 0)
133 boot_mode_ptr = version;
134 break;
135 default:
136 break;
137 }
138 i++;
139 }
140}
141
142static void reuse_omap_atags(struct tag_omap *t)
143{
144 char *component;
145 char *version;
146 while (t->hdr.tag) {
147 switch (t->hdr.tag) {
148 case OMAP_TAG_BOOT_REASON:
149 memset(boot_reason_ptr, 0, 12);
150 strcpy(boot_reason_ptr, t->u.boot_reason.reason_str);
151 break;
152 case OMAP_TAG_VERSION_STR:
153 component = t->u.version.component;
154 version = t->u.version.version;
155 if (strcmp(component, "hw-build") == 0) {
156 memset(hw_build_ptr, 0, 12);
157 strcpy(hw_build_ptr, version);
158 } else if (strcmp(component, "nolo") == 0) {
159 memset(nolo_version_ptr, 0, 12);
160 strcpy(nolo_version_ptr, version);
161 } else if (strcmp(component, "boot-mode") == 0) {
162 memset(boot_mode_ptr, 0, 12);
163 strcpy(boot_mode_ptr, version);
164 }
165 break;
Pali Rohár02f45842020-04-01 00:35:14 +0200166 case OMAP_TAG_UART:
Pali Roháre01ae762020-06-01 00:29:10 +0200167 if (t->u.uart.enabled_uarts)
Pali Rohár02f45842020-04-01 00:35:14 +0200168 serial_was_console_enabled = 1;
169 break;
170 case OMAP_TAG_SERIAL_CONSOLE:
171 serial_was_console_enabled = 1;
172 break;
Pali Rohár248ef0a2012-10-29 07:54:01 +0000173 default:
174 break;
175 }
176 t = tag_omap_next(t);
177 }
178}
179
180/*
181 * Routine: reuse_atags
182 * Description: Reuse atags from previous bootloader.
183 * Reuse only only HW build, boot reason, boot mode and nolo
184 */
185static void reuse_atags(void)
186{
187 struct tag *t = (struct tag *)gd->bd->bi_boot_params;
188
189 /* First tag must be ATAG_CORE */
190 if (t->hdr.tag != ATAG_CORE)
191 return;
192
193 if (!boot_reason_ptr || !hw_build_ptr)
194 return;
195
196 /* Last tag must be ATAG_NONE */
197 while (t->hdr.tag != ATAG_NONE) {
198 switch (t->hdr.tag) {
199 case ATAG_REVISION:
200 memset(hw_build_ptr, 0, 12);
201 sprintf(hw_build_ptr, "%x", t->u.revision.rev);
202 break;
203 case ATAG_BOARD:
204 reuse_omap_atags((struct tag_omap *)&t->u);
205 break;
206 default:
207 break;
208 }
209 t = tag_next(t);
210 }
211}
212
213/*
214 * Routine: board_init
215 * Description: Early hardware init.
216 */
217int board_init(void)
218{
Ivaylo Dimitrovbe2ff862020-10-31 17:32:49 +0100219#if defined(CONFIG_CMD_ONENAND)
220 const u32 gpmc_regs_onenandrx51[GPMC_MAX_REG] = {
221 ONENAND_GPMC_CONFIG1_RX51,
222 ONENAND_GPMC_CONFIG2_RX51,
223 ONENAND_GPMC_CONFIG3_RX51,
224 ONENAND_GPMC_CONFIG4_RX51,
225 ONENAND_GPMC_CONFIG5_RX51,
226 ONENAND_GPMC_CONFIG6_RX51,
227 0
228 };
229#endif
Pali Rohár248ef0a2012-10-29 07:54:01 +0000230 /* in SRAM or SDRAM, finish GPMC */
231 gpmc_init();
Ivaylo Dimitrovbe2ff862020-10-31 17:32:49 +0100232#if defined(CONFIG_CMD_ONENAND)
233 enable_gpmc_cs_config(gpmc_regs_onenandrx51, &gpmc_cfg->cs[0],
234 CONFIG_SYS_ONENAND_BASE, GPMC_SIZE_256M);
235#endif
Pali Rohár6327bac2020-10-31 17:32:46 +0100236 /* Enable the clks & power */
237 per_clocks_enable();
Pali Rohár248ef0a2012-10-29 07:54:01 +0000238 /* boot param addr */
239 gd->bd->bi_boot_params = OMAP34XX_SDRC_CS0 + 0x100;
240 return 0;
241}
242
Tom Rini4cc38852021-08-30 09:16:30 -0400243#ifdef CONFIG_REVISION_TAG
Pali Rohár248ef0a2012-10-29 07:54:01 +0000244/*
245 * Routine: get_board_revision
246 * Description: Return board revision.
247 */
248u32 get_board_rev(void)
249{
250 return simple_strtol(hw_build_ptr, NULL, 16);
251}
Tom Rini4cc38852021-08-30 09:16:30 -0400252#endif
Pali Rohár248ef0a2012-10-29 07:54:01 +0000253
254/*
255 * Routine: setup_board_tags
256 * Description: Append board specific boot tags.
257 */
258void setup_board_tags(struct tag **in_params)
259{
260 int setup_console_atag;
261 char *setup_boot_reason_atag;
262 char *setup_boot_mode_atag;
263 char *str;
264 int i;
265 int size;
266 int total_size;
267 struct tag *params;
268 struct tag_omap *t;
269
270 params = (struct tag *)gd->bd->bi_boot_params;
271
272 params->u.core.flags = 0x0;
273 params->u.core.pagesize = 0x1000;
274 params->u.core.rootdev = 0x0;
275
276 /* append omap atag only if env setup_omap_atag is set to 1 */
Simon Glass64b723f2017-08-03 12:22:12 -0600277 str = env_get("setup_omap_atag");
Pali Rohár248ef0a2012-10-29 07:54:01 +0000278 if (!str || str[0] != '1')
279 return;
280
Simon Glass64b723f2017-08-03 12:22:12 -0600281 str = env_get("setup_console_atag");
Pali Rohár02f45842020-04-01 00:35:14 +0200282 if (str && str[0]) {
283 if (str[0] == '1')
284 setup_console_atag = 1;
285 else
286 setup_console_atag = 0;
287 } else {
288 if (serial_was_console_enabled)
289 setup_console_atag = 1;
290 else
291 setup_console_atag = 0;
292 }
Pali Rohár248ef0a2012-10-29 07:54:01 +0000293
Simon Glass64b723f2017-08-03 12:22:12 -0600294 setup_boot_reason_atag = env_get("setup_boot_reason_atag");
295 setup_boot_mode_atag = env_get("setup_boot_mode_atag");
Pali Rohár248ef0a2012-10-29 07:54:01 +0000296
297 params = *in_params;
298 t = (struct tag_omap *)&params->u;
299 total_size = sizeof(struct tag_header);
300
301 for (i = 0; omap[i].hdr.tag; i++) {
302
303 /* skip serial console tag */
304 if (!setup_console_atag &&
305 omap[i].hdr.tag == OMAP_TAG_SERIAL_CONSOLE)
306 continue;
307
308 size = omap[i].hdr.size + sizeof(struct tag_omap_header);
309 memcpy(t, &omap[i], size);
310
311 /* set uart tag to 0 - disable serial console */
312 if (!setup_console_atag && omap[i].hdr.tag == OMAP_TAG_UART)
313 t->u.uart.enabled_uarts = 0;
314
315 /* change boot reason */
316 if (setup_boot_reason_atag &&
317 omap[i].hdr.tag == OMAP_TAG_BOOT_REASON) {
318 memset(t->u.boot_reason.reason_str, 0, 12);
319 strcpy(t->u.boot_reason.reason_str,
320 setup_boot_reason_atag);
321 }
322
323 /* change boot mode */
324 if (setup_boot_mode_atag &&
325 omap[i].hdr.tag == OMAP_TAG_VERSION_STR &&
326 strcmp(omap[i].u.version.component, "boot-mode") == 0) {
327 memset(t->u.version.version, 0, 12);
328 strcpy(t->u.version.version, setup_boot_mode_atag);
329 }
330
331 total_size += size;
332 t = tag_omap_next(t);
333
334 }
335
336 params->hdr.tag = ATAG_BOARD;
337 params->hdr.size = total_size >> 2;
338 params = tag_next(params);
339
340 *in_params = params;
341}
342
Pali Rohár1d701a52022-03-09 20:46:01 +0100343static int rx51_video_probe(struct udevice *dev)
Pali Rohár248ef0a2012-10-29 07:54:01 +0000344{
Pali Rohár1d701a52022-03-09 20:46:01 +0100345 struct video_uc_plat *uc_plat = dev_get_uclass_plat(dev);
346 struct video_priv *uc_priv = dev_get_uclass_priv(dev);
347
348 uc_plat->base = 0x8f9c0000;
349 uc_plat->size = 800 * 480 * sizeof(u16);
350 uc_priv->xsize = 800;
351 uc_priv->ysize = 480;
352 uc_priv->bpix = VIDEO_BPP16;
353
354 video_set_flush_dcache(dev, true);
355
356 return 0;
Pali Rohár248ef0a2012-10-29 07:54:01 +0000357}
358
Pali Rohár1d701a52022-03-09 20:46:01 +0100359U_BOOT_DRIVER(rx51_video) = {
360 .name = "rx51_video",
361 .id = UCLASS_VIDEO,
362 .probe = rx51_video_probe,
363};
364
Pali Rohár248ef0a2012-10-29 07:54:01 +0000365/*
366 * Routine: twl4030_regulator_set_mode
367 * Description: Set twl4030 regulator mode over i2c powerbus.
368 */
369static void twl4030_regulator_set_mode(u8 id, u8 mode)
370{
371 u16 msg = MSG_SINGULAR(DEV_GRP_P1, id, mode);
Nishanth Menond26a1062013-03-26 05:20:49 +0000372 twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER,
373 TWL4030_PM_MASTER_PB_WORD_MSB, msg >> 8);
374 twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER,
375 TWL4030_PM_MASTER_PB_WORD_LSB, msg & 0xff);
Pali Rohár248ef0a2012-10-29 07:54:01 +0000376}
377
378static void omap3_emu_romcode_call(u32 service_id, u32 *parameters)
379{
380 u32 i, num_params = *parameters;
381 u32 *sram_scratch_space = (u32 *)OMAP3_PUBLIC_SRAM_SCRATCH_AREA;
382
383 /*
384 * copy the parameters to an un-cached area to avoid coherency
385 * issues
386 */
387 for (i = 0; i < num_params; i++) {
388 __raw_writel(*parameters, sram_scratch_space);
389 parameters++;
390 sram_scratch_space++;
391 }
392
393 /* Now make the PPA call */
394 do_omap3_emu_romcode_call(service_id, OMAP3_PUBLIC_SRAM_SCRATCH_AREA);
395}
396
Nishanth Menon53fee1e2015-03-09 17:12:09 -0500397void omap3_set_aux_cr_secure(u32 acr)
398{
399 struct emu_hal_params_rx51 emu_romcode_params = { 0, };
400
401 emu_romcode_params.num_params = 2;
402 emu_romcode_params.param1 = acr;
403
404 omap3_emu_romcode_call(OMAP3_EMU_HAL_API_WRITE_ACR,
405 (u32 *)&emu_romcode_params);
406}
407
Pali Rohár248ef0a2012-10-29 07:54:01 +0000408/*
409 * Routine: omap3_update_aux_cr_secure_rx51
410 * Description: Modify the contents Auxiliary Control Register.
411 * Parameters:
412 * set_bits - bits to set in ACR
413 * clr_bits - bits to clear in ACR
414 */
415static void omap3_update_aux_cr_secure_rx51(u32 set_bits, u32 clear_bits)
416{
Pali Rohár248ef0a2012-10-29 07:54:01 +0000417 u32 acr;
418
419 /* Read ACR */
420 asm volatile ("mrc p15, 0, %0, c1, c0, 1" : "=r" (acr));
421 acr &= ~clear_bits;
422 acr |= set_bits;
Nishanth Menon53fee1e2015-03-09 17:12:09 -0500423 omap3_set_aux_cr_secure(acr);
Pali Rohár248ef0a2012-10-29 07:54:01 +0000424}
425
426/*
427 * Routine: misc_init_r
428 * Description: Configure board specific parts.
429 */
430int misc_init_r(void)
431{
Pali Rohárd73afb22020-10-26 23:45:11 +0100432 struct udevice *dev;
Pali Rohár248ef0a2012-10-29 07:54:01 +0000433 char buf[12];
434 u8 state;
435
Pali Rohár977229b2020-10-31 17:32:47 +0100436 /* disable lp5523 led */
Pali Rohárd73afb22020-10-26 23:45:11 +0100437 if (i2c_get_chip_for_busnum(1, 0x32, 1, &dev) == 0)
Pali Rohár977229b2020-10-31 17:32:47 +0100438 dm_i2c_reg_write(dev, 0x00, 0x00);
Pali Rohár248ef0a2012-10-29 07:54:01 +0000439
440 /* initialize twl4030 power managment */
441 twl4030_power_init();
Pali Rohárcc58d292021-01-16 01:04:54 +0100442 twl4030_power_mmc_init(0);
443 twl4030_power_mmc_init(1);
Pali Rohár248ef0a2012-10-29 07:54:01 +0000444
445 /* set VSIM to 1.8V */
446 twl4030_pmrecv_vsel_cfg(TWL4030_PM_RECEIVER_VSIM_DEDICATED,
447 TWL4030_PM_RECEIVER_VSIM_VSEL_18,
448 TWL4030_PM_RECEIVER_VSIM_DEV_GRP,
449 TWL4030_PM_RECEIVER_DEV_GRP_P1);
450
451 /* store I2C access state */
Nishanth Menon5d9d6f72013-03-26 05:20:50 +0000452 twl4030_i2c_read_u8(TWL4030_CHIP_PM_MASTER, TWL4030_PM_MASTER_PB_CFG,
453 &state);
Pali Rohár248ef0a2012-10-29 07:54:01 +0000454
455 /* enable I2C access to powerbus (needed for twl4030 regulator) */
Nishanth Menond26a1062013-03-26 05:20:49 +0000456 twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER, TWL4030_PM_MASTER_PB_CFG,
457 0x02);
Pali Rohár248ef0a2012-10-29 07:54:01 +0000458
459 /* set VAUX3, VSIM and VMMC1 state to active - enable eMMC memory */
460 twl4030_regulator_set_mode(RES_VAUX3, RES_STATE_ACTIVE);
461 twl4030_regulator_set_mode(RES_VSIM, RES_STATE_ACTIVE);
462 twl4030_regulator_set_mode(RES_VMMC1, RES_STATE_ACTIVE);
463
464 /* restore I2C access state */
Nishanth Menond26a1062013-03-26 05:20:49 +0000465 twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER, TWL4030_PM_MASTER_PB_CFG,
466 state);
Pali Rohár248ef0a2012-10-29 07:54:01 +0000467
468 /* set env variable attkernaddr for relocated kernel */
469 sprintf(buf, "%#x", KERNEL_ADDRESS);
Simon Glass6a38e412017-08-03 12:22:09 -0600470 env_set("attkernaddr", buf);
Pali Rohár248ef0a2012-10-29 07:54:01 +0000471
472 /* initialize omap tags */
473 init_omap_tags();
474
475 /* reuse atags from previous bootloader */
476 reuse_atags();
477
Paul Kocialkowski6bc318e2015-08-27 19:37:13 +0200478 omap_die_id_display();
Pali Rohár248ef0a2012-10-29 07:54:01 +0000479 print_cpuinfo();
480
481 /*
482 * Cortex-A8(r1p0..r1p2) errata 430973 workaround
483 * Set IBE bit in Auxiliary Control Register
Pali Rohár415b8042015-01-08 10:11:40 +0100484 *
485 * Call this routine only on real secure device
486 * Qemu does not implement secure PPA and crash
Pali Rohár248ef0a2012-10-29 07:54:01 +0000487 */
Pali Rohár415b8042015-01-08 10:11:40 +0100488 if (get_device_type() == HS_DEVICE)
489 omap3_update_aux_cr_secure_rx51(1 << 6, 0);
Pali Rohár248ef0a2012-10-29 07:54:01 +0000490
491 return 0;
492}
493
Pali Rohár248ef0a2012-10-29 07:54:01 +0000494static unsigned long int twl_wd_time; /* last time of watchdog reset */
495static unsigned long int twl_i2c_lock;
496
497/*
Pali Rohár126038a2021-03-09 21:19:15 +0100498 * Routine: rx51_watchdog_reset
Pali Rohár248ef0a2012-10-29 07:54:01 +0000499 * Description: Reset timeout of twl4030 watchdog.
500 */
Pali Rohár126038a2021-03-09 21:19:15 +0100501static int rx51_watchdog_reset(struct udevice *dev)
Pali Rohár248ef0a2012-10-29 07:54:01 +0000502{
503 u8 timeout = 0;
504
505 /* do not reset watchdog too often - max every 4s */
506 if (get_timer(twl_wd_time) < 4 * CONFIG_SYS_HZ)
Pali Rohár126038a2021-03-09 21:19:15 +0100507 return 0;
Pali Rohár248ef0a2012-10-29 07:54:01 +0000508
509 /* localy lock twl4030 i2c bus */
510 if (test_and_set_bit(0, &twl_i2c_lock))
Pali Rohár126038a2021-03-09 21:19:15 +0100511 return 0;
Pali Rohár248ef0a2012-10-29 07:54:01 +0000512
513 /* read actual watchdog timeout */
Nishanth Menon5d9d6f72013-03-26 05:20:50 +0000514 twl4030_i2c_read_u8(TWL4030_CHIP_PM_RECEIVER,
515 TWL4030_PM_RECEIVER_WATCHDOG_CFG, &timeout);
Pali Rohár248ef0a2012-10-29 07:54:01 +0000516
517 /* timeout 0 means watchdog is disabled */
518 /* reset watchdog timeout to 31s (maximum) */
519 if (timeout != 0)
Nishanth Menond26a1062013-03-26 05:20:49 +0000520 twl4030_i2c_write_u8(TWL4030_CHIP_PM_RECEIVER,
521 TWL4030_PM_RECEIVER_WATCHDOG_CFG, 31);
Pali Rohár248ef0a2012-10-29 07:54:01 +0000522
523 /* store last watchdog reset time */
524 twl_wd_time = get_timer(0);
525
526 /* localy unlock twl4030 i2c bus */
527 test_and_clear_bit(0, &twl_i2c_lock);
Pali Rohár126038a2021-03-09 21:19:15 +0100528
529 return 0;
530}
531
532static int rx51_watchdog_start(struct udevice *dev, u64 timeout_ms, ulong flags)
533{
534 return 0;
Pali Rohár248ef0a2012-10-29 07:54:01 +0000535}
536
Pali Rohár126038a2021-03-09 21:19:15 +0100537static int rx51_watchdog_probe(struct udevice *dev)
538{
539 return 0;
540}
541
542static const struct wdt_ops rx51_watchdog_ops = {
543 .start = rx51_watchdog_start,
544 .reset = rx51_watchdog_reset,
545};
546
547U_BOOT_DRIVER(rx51_watchdog) = {
548 .name = "rx51_watchdog",
549 .id = UCLASS_WDT,
550 .ops = &rx51_watchdog_ops,
551 .probe = rx51_watchdog_probe,
552};
553
Pali Rohár248ef0a2012-10-29 07:54:01 +0000554/*
555 * TWL4030 keypad handler for cfb_console
556 */
557
558static const char keymap[] = {
559 /* normal */
560 'q', 'o', 'p', ',', '\b', 0, 'a', 's',
561 'w', 'd', 'f', 'g', 'h', 'j', 'k', 'l',
562 'e', '.', 0, '\r', 0, 'z', 'x', 'c',
563 'r', 'v', 'b', 'n', 'm', ' ', ' ', 0,
564 't', 0, 0, 0, 0, 0, 0, 0,
565 'y', 0, 0, 0, 0, 0, 0, 0,
566 'u', 0, 0, 0, 0, 0, 0, 0,
567 'i', 5, 6, 0, 0, 0, 0, 0,
568 /* fn */
569 '1', '9', '0', '=', '\b', 0, '*', '+',
570 '2', '#', '-', '_', '(', ')', '&', '!',
571 '3', '?', '^', '\r', 0, 156, '$', 238,
572 '4', '/', '\\', '"', '\'', '@', 0, '<',
573 '5', '|', '>', 0, 0, 0, 0, 0,
574 '6', 0, 0, 0, 0, 0, 0, 0,
575 '7', 0, 0, 0, 0, 0, 0, 0,
576 '8', 16, 17, 0, 0, 0, 0, 0,
577};
578
579static u8 keys[8];
580static u8 old_keys[8] = {0, 0, 0, 0, 0, 0, 0, 0};
581#define KEYBUF_SIZE 32
582static u8 keybuf[KEYBUF_SIZE];
583static u8 keybuf_head;
584static u8 keybuf_tail;
585
586/*
Pali Rohár54a30142022-02-03 19:38:50 +0100587 * Routine: rx51_kp_start
Pali Rohár248ef0a2012-10-29 07:54:01 +0000588 * Description: Initialize HW keyboard.
589 */
Pali Rohár54a30142022-02-03 19:38:50 +0100590static int rx51_kp_start(struct udevice *dev)
Pali Rohár248ef0a2012-10-29 07:54:01 +0000591{
592 int ret = 0;
593 u8 ctrl;
Nishanth Menon5d9d6f72013-03-26 05:20:50 +0000594 ret = twl4030_i2c_read_u8(TWL4030_CHIP_KEYPAD,
595 TWL4030_KEYPAD_KEYP_CTRL_REG, &ctrl);
Pali Rohár248ef0a2012-10-29 07:54:01 +0000596
597 if (ret)
598 return ret;
599
600 /* turn on keyboard and use hardware scanning */
601 ctrl |= TWL4030_KEYPAD_CTRL_KBD_ON;
602 ctrl |= TWL4030_KEYPAD_CTRL_SOFT_NRST;
603 ctrl |= TWL4030_KEYPAD_CTRL_SOFTMODEN;
Nishanth Menond26a1062013-03-26 05:20:49 +0000604 ret |= twl4030_i2c_write_u8(TWL4030_CHIP_KEYPAD,
605 TWL4030_KEYPAD_KEYP_CTRL_REG, ctrl);
Pali Rohár248ef0a2012-10-29 07:54:01 +0000606 /* enable key event status */
Nishanth Menond26a1062013-03-26 05:20:49 +0000607 ret |= twl4030_i2c_write_u8(TWL4030_CHIP_KEYPAD,
608 TWL4030_KEYPAD_KEYP_IMR1, 0xfe);
Pali Rohár248ef0a2012-10-29 07:54:01 +0000609 /* enable interrupt generation on rising and falling */
610 /* this is a workaround for qemu twl4030 emulation */
Nishanth Menond26a1062013-03-26 05:20:49 +0000611 ret |= twl4030_i2c_write_u8(TWL4030_CHIP_KEYPAD,
612 TWL4030_KEYPAD_KEYP_EDR, 0x57);
Pali Rohár248ef0a2012-10-29 07:54:01 +0000613 /* enable ISR clear on read */
Nishanth Menond26a1062013-03-26 05:20:49 +0000614 ret |= twl4030_i2c_write_u8(TWL4030_CHIP_KEYPAD,
615 TWL4030_KEYPAD_KEYP_SIH_CTRL, 0x05);
Pali Rohár248ef0a2012-10-29 07:54:01 +0000616 return 0;
617}
618
619static void rx51_kp_fill(u8 k, u8 mods)
620{
621 /* check if some cursor key without meta fn key was pressed */
622 if (!(mods & 2) && (k == 18 || k == 31 || k == 33 || k == 34)) {
623 keybuf[keybuf_tail++] = '\e';
624 keybuf_tail %= KEYBUF_SIZE;
625 keybuf[keybuf_tail++] = '[';
626 keybuf_tail %= KEYBUF_SIZE;
627 if (k == 18) /* up */
628 keybuf[keybuf_tail++] = 'A';
629 else if (k == 31) /* left */
630 keybuf[keybuf_tail++] = 'D';
631 else if (k == 33) /* down */
632 keybuf[keybuf_tail++] = 'B';
633 else if (k == 34) /* right */
634 keybuf[keybuf_tail++] = 'C';
635 keybuf_tail %= KEYBUF_SIZE;
636 return;
637 }
638
639 if (mods & 2) { /* fn meta key was pressed */
640 k = keymap[k+64];
641 } else {
642 k = keymap[k];
643 if (mods & 1) { /* ctrl key was pressed */
644 if (k >= 'a' && k <= 'z')
645 k -= 'a' - 1;
646 }
647 if (mods & 4) { /* shift key was pressed */
648 if (k >= 'a' && k <= 'z')
649 k += 'A' - 'a';
650 else if (k == '.')
651 k = ':';
652 else if (k == ',')
653 k = ';';
654 }
655 }
656 keybuf[keybuf_tail++] = k;
657 keybuf_tail %= KEYBUF_SIZE;
658}
659
660/*
661 * Routine: rx51_kp_tstc
662 * Description: Test if key was pressed (from buffer).
663 */
Pali Rohár54a30142022-02-03 19:38:50 +0100664static int rx51_kp_tstc(struct udevice *dev)
Pali Rohár248ef0a2012-10-29 07:54:01 +0000665{
666 u8 c, r, dk, i;
667 u8 intr;
668 u8 mods;
669
670 /* localy lock twl4030 i2c bus */
671 if (test_and_set_bit(0, &twl_i2c_lock))
672 return 0;
673
674 /* twl4030 remembers up to 2 events */
675 for (i = 0; i < 2; i++) {
676
677 /* check interrupt register for events */
Nishanth Menon5d9d6f72013-03-26 05:20:50 +0000678 twl4030_i2c_read_u8(TWL4030_CHIP_KEYPAD,
679 TWL4030_KEYPAD_KEYP_ISR1 + (2 * i), &intr);
Pali Rohár248ef0a2012-10-29 07:54:01 +0000680
681 /* no event */
682 if (!(intr&1))
683 continue;
684
685 /* read the key state */
Pali Rohárd73afb22020-10-26 23:45:11 +0100686 twl4030_i2c_read(TWL4030_CHIP_KEYPAD,
687 TWL4030_KEYPAD_FULL_CODE_7_0, keys, 8);
Pali Rohár248ef0a2012-10-29 07:54:01 +0000688
689 /* cut out modifier keys from the keystate */
690 mods = keys[4] >> 4;
691 keys[4] &= 0x0f;
692
693 for (c = 0; c < 8; c++) {
694
695 /* get newly pressed keys only */
696 dk = ((keys[c] ^ old_keys[c])&keys[c]);
697 old_keys[c] = keys[c];
698
699 /* fill the keybuf */
700 for (r = 0; r < 8; r++) {
701 if (dk&1)
702 rx51_kp_fill((c*8)+r, mods);
703 dk = dk >> 1;
704 }
705
706 }
707
708 }
709
710 /* localy unlock twl4030 i2c bus */
711 test_and_clear_bit(0, &twl_i2c_lock);
712
713 return (KEYBUF_SIZE + keybuf_tail - keybuf_head)%KEYBUF_SIZE;
714}
715
716/*
717 * Routine: rx51_kp_getc
718 * Description: Get last pressed key (from buffer).
719 */
Pali Rohár54a30142022-02-03 19:38:50 +0100720static int rx51_kp_getc(struct udevice *dev)
Pali Rohár248ef0a2012-10-29 07:54:01 +0000721{
722 keybuf_head %= KEYBUF_SIZE;
Pali Rohár54a30142022-02-03 19:38:50 +0100723 while (!rx51_kp_tstc(dev))
Pali Rohár248ef0a2012-10-29 07:54:01 +0000724 WATCHDOG_RESET();
725 return keybuf[keybuf_head++];
726}
727
Pali Rohár54a30142022-02-03 19:38:50 +0100728static int rx51_kp_probe(struct udevice *dev)
729{
730 struct keyboard_priv *uc_priv = dev_get_uclass_priv(dev);
731 struct stdio_dev *sdev = &uc_priv->sdev;
732
733 strcpy(sdev->name, "keyboard");
734 return input_stdio_register(sdev);
735}
736
737static const struct keyboard_ops rx51_kp_ops = {
738 .start = rx51_kp_start,
739 .tstc = rx51_kp_tstc,
740 .getc = rx51_kp_getc,
741};
742
743U_BOOT_DRIVER(rx51_kp) = {
744 .name = "rx51_kp",
745 .id = UCLASS_KEYBOARD,
746 .probe = rx51_kp_probe,
747 .ops = &rx51_kp_ops,
748};
749
Pali Rohárcc58d292021-01-16 01:04:54 +0100750static const struct mmc_config rx51_mmc_cfg = {
751 .host_caps = MMC_MODE_4BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS,
752 .f_min = 400000,
753 .f_max = 52000000,
754 .b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT,
755 .voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195,
756};
Paul Kocialkowski69559892014-11-08 20:55:47 +0100757
Pali Rohárcc58d292021-01-16 01:04:54 +0100758static const struct omap_hsmmc_plat rx51_mmc[] = {
759 { rx51_mmc_cfg, (struct hsmmc *)OMAP_HSMMC1_BASE },
760 { rx51_mmc_cfg, (struct hsmmc *)OMAP_HSMMC2_BASE },
761};
762
763U_BOOT_DRVINFOS(rx51_mmc) = {
764 { "omap_hsmmc", &rx51_mmc[0] },
765 { "omap_hsmmc", &rx51_mmc[1] },
766};
Pali Rohárd73afb22020-10-26 23:45:11 +0100767
Simon Glassb75b15b2020-12-03 16:55:23 -0700768static const struct omap_i2c_plat rx51_i2c[] = {
Pali Rohárde39c112020-11-21 23:30:11 +0100769 { I2C_BASE1, 100000, OMAP_I2C_REV_V1 },
Pali Rohárd73afb22020-10-26 23:45:11 +0100770 { I2C_BASE2, 100000, OMAP_I2C_REV_V1 },
Pali Rohárde39c112020-11-21 23:30:11 +0100771 { I2C_BASE3, 100000, OMAP_I2C_REV_V1 },
Pali Rohárd73afb22020-10-26 23:45:11 +0100772};
773
Simon Glass1d8364a2020-12-28 20:34:54 -0700774U_BOOT_DRVINFOS(rx51_i2c) = {
Pali Rohárd73afb22020-10-26 23:45:11 +0100775 { "i2c_omap", &rx51_i2c[0] },
776 { "i2c_omap", &rx51_i2c[1] },
777 { "i2c_omap", &rx51_i2c[2] },
778};
Pali Rohár126038a2021-03-09 21:19:15 +0100779
780U_BOOT_DRVINFOS(rx51_watchdog) = {
781 { "rx51_watchdog" },
782};
Pali Rohár54a30142022-02-03 19:38:50 +0100783
Pali Rohár1d701a52022-03-09 20:46:01 +0100784U_BOOT_DRVINFOS(rx51_video) = {
785 { "rx51_video" },
786};
787
Pali Rohár54a30142022-02-03 19:38:50 +0100788U_BOOT_DRVINFOS(rx51_kp) = {
789 { "rx51_kp" },
790};