blob: fd3cec8358aaf9ec798b749bc5de25722784f333 [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>
33#include <video_fb.h>
Simon Glass3ba929a2020-10-30 21:38:53 -060034#include <asm/global_data.h>
Pali Rohár248ef0a2012-10-29 07:54:01 +000035#include <asm/io.h>
36#include <asm/setup.h>
37#include <asm/bitops.h>
38#include <asm/mach-types.h>
Pali Rohárd73afb22020-10-26 23:45:11 +010039#include <asm/omap_i2c.h>
Pali Rohár248ef0a2012-10-29 07:54:01 +000040#include <asm/arch/mux.h>
41#include <asm/arch/sys_proto.h>
42#include <asm/arch/mmc_host_def.h>
43
Pali Rohár248ef0a2012-10-29 07:54:01 +000044#include "tag_omap.h"
45
Pali Rohár9157a8c2021-02-07 14:50:15 +010046/* Needed for ROM SMC call */
47struct emu_hal_params_rx51 {
48 u32 num_params;
49 u32 param1;
50 u32 param2;
51 u32 param3;
52 u32 param4;
53};
54
55#define ONENAND_GPMC_CONFIG1_RX51 0xfb001202
56#define ONENAND_GPMC_CONFIG2_RX51 0x00111100
57#define ONENAND_GPMC_CONFIG3_RX51 0x00020200
58#define ONENAND_GPMC_CONFIG4_RX51 0x11001102
59#define ONENAND_GPMC_CONFIG5_RX51 0x03101616
60#define ONENAND_GPMC_CONFIG6_RX51 0x90060000
61
Pali Rohár248ef0a2012-10-29 07:54:01 +000062DECLARE_GLOBAL_DATA_PTR;
63
64GraphicDevice gdev;
65
66const 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],
235 CONFIG_SYS_ONENAND_BASE, GPMC_SIZE_256M);
236#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
244/*
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}
252
253/*
254 * Routine: setup_board_tags
255 * Description: Append board specific boot tags.
256 */
257void setup_board_tags(struct tag **in_params)
258{
259 int setup_console_atag;
260 char *setup_boot_reason_atag;
261 char *setup_boot_mode_atag;
262 char *str;
263 int i;
264 int size;
265 int total_size;
266 struct tag *params;
267 struct tag_omap *t;
268
269 params = (struct tag *)gd->bd->bi_boot_params;
270
271 params->u.core.flags = 0x0;
272 params->u.core.pagesize = 0x1000;
273 params->u.core.rootdev = 0x0;
274
275 /* append omap atag only if env setup_omap_atag is set to 1 */
Simon Glass64b723f2017-08-03 12:22:12 -0600276 str = env_get("setup_omap_atag");
Pali Rohár248ef0a2012-10-29 07:54:01 +0000277 if (!str || str[0] != '1')
278 return;
279
Simon Glass64b723f2017-08-03 12:22:12 -0600280 str = env_get("setup_console_atag");
Pali Rohár02f45842020-04-01 00:35:14 +0200281 if (str && str[0]) {
282 if (str[0] == '1')
283 setup_console_atag = 1;
284 else
285 setup_console_atag = 0;
286 } else {
287 if (serial_was_console_enabled)
288 setup_console_atag = 1;
289 else
290 setup_console_atag = 0;
291 }
Pali Rohár248ef0a2012-10-29 07:54:01 +0000292
Simon Glass64b723f2017-08-03 12:22:12 -0600293 setup_boot_reason_atag = env_get("setup_boot_reason_atag");
294 setup_boot_mode_atag = env_get("setup_boot_mode_atag");
Pali Rohár248ef0a2012-10-29 07:54:01 +0000295
296 params = *in_params;
297 t = (struct tag_omap *)&params->u;
298 total_size = sizeof(struct tag_header);
299
300 for (i = 0; omap[i].hdr.tag; i++) {
301
302 /* skip serial console tag */
303 if (!setup_console_atag &&
304 omap[i].hdr.tag == OMAP_TAG_SERIAL_CONSOLE)
305 continue;
306
307 size = omap[i].hdr.size + sizeof(struct tag_omap_header);
308 memcpy(t, &omap[i], size);
309
310 /* set uart tag to 0 - disable serial console */
311 if (!setup_console_atag && omap[i].hdr.tag == OMAP_TAG_UART)
312 t->u.uart.enabled_uarts = 0;
313
314 /* change boot reason */
315 if (setup_boot_reason_atag &&
316 omap[i].hdr.tag == OMAP_TAG_BOOT_REASON) {
317 memset(t->u.boot_reason.reason_str, 0, 12);
318 strcpy(t->u.boot_reason.reason_str,
319 setup_boot_reason_atag);
320 }
321
322 /* change boot mode */
323 if (setup_boot_mode_atag &&
324 omap[i].hdr.tag == OMAP_TAG_VERSION_STR &&
325 strcmp(omap[i].u.version.component, "boot-mode") == 0) {
326 memset(t->u.version.version, 0, 12);
327 strcpy(t->u.version.version, setup_boot_mode_atag);
328 }
329
330 total_size += size;
331 t = tag_omap_next(t);
332
333 }
334
335 params->hdr.tag = ATAG_BOARD;
336 params->hdr.size = total_size >> 2;
337 params = tag_next(params);
338
339 *in_params = params;
340}
341
342/*
343 * Routine: video_hw_init
344 * Description: Set up the GraphicDevice depending on sys_boot.
345 */
346void *video_hw_init(void)
347{
348 /* fill in Graphic Device */
349 gdev.frameAdrs = 0x8f9c0000;
350 gdev.winSizeX = 800;
351 gdev.winSizeY = 480;
352 gdev.gdfBytesPP = 2;
353 gdev.gdfIndex = GDF_16BIT_565RGB;
354 memset((void *)gdev.frameAdrs, 0, 0xbb800);
355 return (void *) &gdev;
356}
357
358/*
359 * Routine: twl4030_regulator_set_mode
360 * Description: Set twl4030 regulator mode over i2c powerbus.
361 */
362static void twl4030_regulator_set_mode(u8 id, u8 mode)
363{
364 u16 msg = MSG_SINGULAR(DEV_GRP_P1, id, mode);
Nishanth Menond26a1062013-03-26 05:20:49 +0000365 twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER,
366 TWL4030_PM_MASTER_PB_WORD_MSB, msg >> 8);
367 twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER,
368 TWL4030_PM_MASTER_PB_WORD_LSB, msg & 0xff);
Pali Rohár248ef0a2012-10-29 07:54:01 +0000369}
370
371static void omap3_emu_romcode_call(u32 service_id, u32 *parameters)
372{
373 u32 i, num_params = *parameters;
374 u32 *sram_scratch_space = (u32 *)OMAP3_PUBLIC_SRAM_SCRATCH_AREA;
375
376 /*
377 * copy the parameters to an un-cached area to avoid coherency
378 * issues
379 */
380 for (i = 0; i < num_params; i++) {
381 __raw_writel(*parameters, sram_scratch_space);
382 parameters++;
383 sram_scratch_space++;
384 }
385
386 /* Now make the PPA call */
387 do_omap3_emu_romcode_call(service_id, OMAP3_PUBLIC_SRAM_SCRATCH_AREA);
388}
389
Nishanth Menon53fee1e2015-03-09 17:12:09 -0500390void omap3_set_aux_cr_secure(u32 acr)
391{
392 struct emu_hal_params_rx51 emu_romcode_params = { 0, };
393
394 emu_romcode_params.num_params = 2;
395 emu_romcode_params.param1 = acr;
396
397 omap3_emu_romcode_call(OMAP3_EMU_HAL_API_WRITE_ACR,
398 (u32 *)&emu_romcode_params);
399}
400
Pali Rohár248ef0a2012-10-29 07:54:01 +0000401/*
402 * Routine: omap3_update_aux_cr_secure_rx51
403 * Description: Modify the contents Auxiliary Control Register.
404 * Parameters:
405 * set_bits - bits to set in ACR
406 * clr_bits - bits to clear in ACR
407 */
408static void omap3_update_aux_cr_secure_rx51(u32 set_bits, u32 clear_bits)
409{
Pali Rohár248ef0a2012-10-29 07:54:01 +0000410 u32 acr;
411
412 /* Read ACR */
413 asm volatile ("mrc p15, 0, %0, c1, c0, 1" : "=r" (acr));
414 acr &= ~clear_bits;
415 acr |= set_bits;
Nishanth Menon53fee1e2015-03-09 17:12:09 -0500416 omap3_set_aux_cr_secure(acr);
Pali Rohár248ef0a2012-10-29 07:54:01 +0000417}
418
419/*
420 * Routine: misc_init_r
421 * Description: Configure board specific parts.
422 */
423int misc_init_r(void)
424{
Pali Rohárd73afb22020-10-26 23:45:11 +0100425 struct udevice *dev;
Pali Rohár248ef0a2012-10-29 07:54:01 +0000426 char buf[12];
427 u8 state;
428
Pali Rohár977229b2020-10-31 17:32:47 +0100429 /* disable lp5523 led */
Pali Rohárd73afb22020-10-26 23:45:11 +0100430 if (i2c_get_chip_for_busnum(1, 0x32, 1, &dev) == 0)
Pali Rohár977229b2020-10-31 17:32:47 +0100431 dm_i2c_reg_write(dev, 0x00, 0x00);
Pali Rohár248ef0a2012-10-29 07:54:01 +0000432
433 /* initialize twl4030 power managment */
434 twl4030_power_init();
Pali Rohárcc58d292021-01-16 01:04:54 +0100435 twl4030_power_mmc_init(0);
436 twl4030_power_mmc_init(1);
Pali Rohár248ef0a2012-10-29 07:54:01 +0000437
438 /* set VSIM to 1.8V */
439 twl4030_pmrecv_vsel_cfg(TWL4030_PM_RECEIVER_VSIM_DEDICATED,
440 TWL4030_PM_RECEIVER_VSIM_VSEL_18,
441 TWL4030_PM_RECEIVER_VSIM_DEV_GRP,
442 TWL4030_PM_RECEIVER_DEV_GRP_P1);
443
444 /* store I2C access state */
Nishanth Menon5d9d6f72013-03-26 05:20:50 +0000445 twl4030_i2c_read_u8(TWL4030_CHIP_PM_MASTER, TWL4030_PM_MASTER_PB_CFG,
446 &state);
Pali Rohár248ef0a2012-10-29 07:54:01 +0000447
448 /* enable I2C access to powerbus (needed for twl4030 regulator) */
Nishanth Menond26a1062013-03-26 05:20:49 +0000449 twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER, TWL4030_PM_MASTER_PB_CFG,
450 0x02);
Pali Rohár248ef0a2012-10-29 07:54:01 +0000451
452 /* set VAUX3, VSIM and VMMC1 state to active - enable eMMC memory */
453 twl4030_regulator_set_mode(RES_VAUX3, RES_STATE_ACTIVE);
454 twl4030_regulator_set_mode(RES_VSIM, RES_STATE_ACTIVE);
455 twl4030_regulator_set_mode(RES_VMMC1, RES_STATE_ACTIVE);
456
457 /* restore I2C access state */
Nishanth Menond26a1062013-03-26 05:20:49 +0000458 twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER, TWL4030_PM_MASTER_PB_CFG,
459 state);
Pali Rohár248ef0a2012-10-29 07:54:01 +0000460
461 /* set env variable attkernaddr for relocated kernel */
462 sprintf(buf, "%#x", KERNEL_ADDRESS);
Simon Glass6a38e412017-08-03 12:22:09 -0600463 env_set("attkernaddr", buf);
Pali Rohár248ef0a2012-10-29 07:54:01 +0000464
465 /* initialize omap tags */
466 init_omap_tags();
467
468 /* reuse atags from previous bootloader */
469 reuse_atags();
470
Paul Kocialkowski6bc318e2015-08-27 19:37:13 +0200471 omap_die_id_display();
Pali Rohár248ef0a2012-10-29 07:54:01 +0000472 print_cpuinfo();
473
474 /*
475 * Cortex-A8(r1p0..r1p2) errata 430973 workaround
476 * Set IBE bit in Auxiliary Control Register
Pali Rohár415b8042015-01-08 10:11:40 +0100477 *
478 * Call this routine only on real secure device
479 * Qemu does not implement secure PPA and crash
Pali Rohár248ef0a2012-10-29 07:54:01 +0000480 */
Pali Rohár415b8042015-01-08 10:11:40 +0100481 if (get_device_type() == HS_DEVICE)
482 omap3_update_aux_cr_secure_rx51(1 << 6, 0);
Pali Rohár248ef0a2012-10-29 07:54:01 +0000483
484 return 0;
485}
486
Pali Rohár248ef0a2012-10-29 07:54:01 +0000487static unsigned long int twl_wd_time; /* last time of watchdog reset */
488static unsigned long int twl_i2c_lock;
489
490/*
Pali Rohár126038a2021-03-09 21:19:15 +0100491 * Routine: rx51_watchdog_reset
Pali Rohár248ef0a2012-10-29 07:54:01 +0000492 * Description: Reset timeout of twl4030 watchdog.
493 */
Pali Rohár126038a2021-03-09 21:19:15 +0100494static int rx51_watchdog_reset(struct udevice *dev)
Pali Rohár248ef0a2012-10-29 07:54:01 +0000495{
496 u8 timeout = 0;
497
498 /* do not reset watchdog too often - max every 4s */
499 if (get_timer(twl_wd_time) < 4 * CONFIG_SYS_HZ)
Pali Rohár126038a2021-03-09 21:19:15 +0100500 return 0;
Pali Rohár248ef0a2012-10-29 07:54:01 +0000501
502 /* localy lock twl4030 i2c bus */
503 if (test_and_set_bit(0, &twl_i2c_lock))
Pali Rohár126038a2021-03-09 21:19:15 +0100504 return 0;
Pali Rohár248ef0a2012-10-29 07:54:01 +0000505
506 /* read actual watchdog timeout */
Nishanth Menon5d9d6f72013-03-26 05:20:50 +0000507 twl4030_i2c_read_u8(TWL4030_CHIP_PM_RECEIVER,
508 TWL4030_PM_RECEIVER_WATCHDOG_CFG, &timeout);
Pali Rohár248ef0a2012-10-29 07:54:01 +0000509
510 /* timeout 0 means watchdog is disabled */
511 /* reset watchdog timeout to 31s (maximum) */
512 if (timeout != 0)
Nishanth Menond26a1062013-03-26 05:20:49 +0000513 twl4030_i2c_write_u8(TWL4030_CHIP_PM_RECEIVER,
514 TWL4030_PM_RECEIVER_WATCHDOG_CFG, 31);
Pali Rohár248ef0a2012-10-29 07:54:01 +0000515
516 /* store last watchdog reset time */
517 twl_wd_time = get_timer(0);
518
519 /* localy unlock twl4030 i2c bus */
520 test_and_clear_bit(0, &twl_i2c_lock);
Pali Rohár126038a2021-03-09 21:19:15 +0100521
522 return 0;
523}
524
525static int rx51_watchdog_start(struct udevice *dev, u64 timeout_ms, ulong flags)
526{
527 return 0;
Pali Rohár248ef0a2012-10-29 07:54:01 +0000528}
529
Pali Rohár126038a2021-03-09 21:19:15 +0100530static int rx51_watchdog_probe(struct udevice *dev)
531{
532 return 0;
533}
534
535static const struct wdt_ops rx51_watchdog_ops = {
536 .start = rx51_watchdog_start,
537 .reset = rx51_watchdog_reset,
538};
539
540U_BOOT_DRIVER(rx51_watchdog) = {
541 .name = "rx51_watchdog",
542 .id = UCLASS_WDT,
543 .ops = &rx51_watchdog_ops,
544 .probe = rx51_watchdog_probe,
545};
546
Pali Rohár248ef0a2012-10-29 07:54:01 +0000547/*
548 * TWL4030 keypad handler for cfb_console
549 */
550
551static const char keymap[] = {
552 /* normal */
553 'q', 'o', 'p', ',', '\b', 0, 'a', 's',
554 'w', 'd', 'f', 'g', 'h', 'j', 'k', 'l',
555 'e', '.', 0, '\r', 0, 'z', 'x', 'c',
556 'r', 'v', 'b', 'n', 'm', ' ', ' ', 0,
557 't', 0, 0, 0, 0, 0, 0, 0,
558 'y', 0, 0, 0, 0, 0, 0, 0,
559 'u', 0, 0, 0, 0, 0, 0, 0,
560 'i', 5, 6, 0, 0, 0, 0, 0,
561 /* fn */
562 '1', '9', '0', '=', '\b', 0, '*', '+',
563 '2', '#', '-', '_', '(', ')', '&', '!',
564 '3', '?', '^', '\r', 0, 156, '$', 238,
565 '4', '/', '\\', '"', '\'', '@', 0, '<',
566 '5', '|', '>', 0, 0, 0, 0, 0,
567 '6', 0, 0, 0, 0, 0, 0, 0,
568 '7', 0, 0, 0, 0, 0, 0, 0,
569 '8', 16, 17, 0, 0, 0, 0, 0,
570};
571
572static u8 keys[8];
573static u8 old_keys[8] = {0, 0, 0, 0, 0, 0, 0, 0};
574#define KEYBUF_SIZE 32
575static u8 keybuf[KEYBUF_SIZE];
576static u8 keybuf_head;
577static u8 keybuf_tail;
578
579/*
580 * Routine: rx51_kp_init
581 * Description: Initialize HW keyboard.
582 */
583int rx51_kp_init(void)
584{
585 int ret = 0;
586 u8 ctrl;
Nishanth Menon5d9d6f72013-03-26 05:20:50 +0000587 ret = twl4030_i2c_read_u8(TWL4030_CHIP_KEYPAD,
588 TWL4030_KEYPAD_KEYP_CTRL_REG, &ctrl);
Pali Rohár248ef0a2012-10-29 07:54:01 +0000589
590 if (ret)
591 return ret;
592
593 /* turn on keyboard and use hardware scanning */
594 ctrl |= TWL4030_KEYPAD_CTRL_KBD_ON;
595 ctrl |= TWL4030_KEYPAD_CTRL_SOFT_NRST;
596 ctrl |= TWL4030_KEYPAD_CTRL_SOFTMODEN;
Nishanth Menond26a1062013-03-26 05:20:49 +0000597 ret |= twl4030_i2c_write_u8(TWL4030_CHIP_KEYPAD,
598 TWL4030_KEYPAD_KEYP_CTRL_REG, ctrl);
Pali Rohár248ef0a2012-10-29 07:54:01 +0000599 /* enable key event status */
Nishanth Menond26a1062013-03-26 05:20:49 +0000600 ret |= twl4030_i2c_write_u8(TWL4030_CHIP_KEYPAD,
601 TWL4030_KEYPAD_KEYP_IMR1, 0xfe);
Pali Rohár248ef0a2012-10-29 07:54:01 +0000602 /* enable interrupt generation on rising and falling */
603 /* this is a workaround for qemu twl4030 emulation */
Nishanth Menond26a1062013-03-26 05:20:49 +0000604 ret |= twl4030_i2c_write_u8(TWL4030_CHIP_KEYPAD,
605 TWL4030_KEYPAD_KEYP_EDR, 0x57);
Pali Rohár248ef0a2012-10-29 07:54:01 +0000606 /* enable ISR clear on read */
Nishanth Menond26a1062013-03-26 05:20:49 +0000607 ret |= twl4030_i2c_write_u8(TWL4030_CHIP_KEYPAD,
608 TWL4030_KEYPAD_KEYP_SIH_CTRL, 0x05);
Pali Rohár248ef0a2012-10-29 07:54:01 +0000609 return 0;
610}
611
612static void rx51_kp_fill(u8 k, u8 mods)
613{
614 /* check if some cursor key without meta fn key was pressed */
615 if (!(mods & 2) && (k == 18 || k == 31 || k == 33 || k == 34)) {
616 keybuf[keybuf_tail++] = '\e';
617 keybuf_tail %= KEYBUF_SIZE;
618 keybuf[keybuf_tail++] = '[';
619 keybuf_tail %= KEYBUF_SIZE;
620 if (k == 18) /* up */
621 keybuf[keybuf_tail++] = 'A';
622 else if (k == 31) /* left */
623 keybuf[keybuf_tail++] = 'D';
624 else if (k == 33) /* down */
625 keybuf[keybuf_tail++] = 'B';
626 else if (k == 34) /* right */
627 keybuf[keybuf_tail++] = 'C';
628 keybuf_tail %= KEYBUF_SIZE;
629 return;
630 }
631
632 if (mods & 2) { /* fn meta key was pressed */
633 k = keymap[k+64];
634 } else {
635 k = keymap[k];
636 if (mods & 1) { /* ctrl key was pressed */
637 if (k >= 'a' && k <= 'z')
638 k -= 'a' - 1;
639 }
640 if (mods & 4) { /* shift key was pressed */
641 if (k >= 'a' && k <= 'z')
642 k += 'A' - 'a';
643 else if (k == '.')
644 k = ':';
645 else if (k == ',')
646 k = ';';
647 }
648 }
649 keybuf[keybuf_tail++] = k;
650 keybuf_tail %= KEYBUF_SIZE;
651}
652
653/*
654 * Routine: rx51_kp_tstc
655 * Description: Test if key was pressed (from buffer).
656 */
Simon Glass0d1e1f72014-07-23 06:54:59 -0600657int rx51_kp_tstc(struct stdio_dev *sdev)
Pali Rohár248ef0a2012-10-29 07:54:01 +0000658{
659 u8 c, r, dk, i;
660 u8 intr;
661 u8 mods;
662
663 /* localy lock twl4030 i2c bus */
664 if (test_and_set_bit(0, &twl_i2c_lock))
665 return 0;
666
667 /* twl4030 remembers up to 2 events */
668 for (i = 0; i < 2; i++) {
669
670 /* check interrupt register for events */
Nishanth Menon5d9d6f72013-03-26 05:20:50 +0000671 twl4030_i2c_read_u8(TWL4030_CHIP_KEYPAD,
672 TWL4030_KEYPAD_KEYP_ISR1 + (2 * i), &intr);
Pali Rohár248ef0a2012-10-29 07:54:01 +0000673
674 /* no event */
675 if (!(intr&1))
676 continue;
677
678 /* read the key state */
Pali Rohárd73afb22020-10-26 23:45:11 +0100679 twl4030_i2c_read(TWL4030_CHIP_KEYPAD,
680 TWL4030_KEYPAD_FULL_CODE_7_0, keys, 8);
Pali Rohár248ef0a2012-10-29 07:54:01 +0000681
682 /* cut out modifier keys from the keystate */
683 mods = keys[4] >> 4;
684 keys[4] &= 0x0f;
685
686 for (c = 0; c < 8; c++) {
687
688 /* get newly pressed keys only */
689 dk = ((keys[c] ^ old_keys[c])&keys[c]);
690 old_keys[c] = keys[c];
691
692 /* fill the keybuf */
693 for (r = 0; r < 8; r++) {
694 if (dk&1)
695 rx51_kp_fill((c*8)+r, mods);
696 dk = dk >> 1;
697 }
698
699 }
700
701 }
702
703 /* localy unlock twl4030 i2c bus */
704 test_and_clear_bit(0, &twl_i2c_lock);
705
706 return (KEYBUF_SIZE + keybuf_tail - keybuf_head)%KEYBUF_SIZE;
707}
708
709/*
710 * Routine: rx51_kp_getc
711 * Description: Get last pressed key (from buffer).
712 */
Simon Glass0d1e1f72014-07-23 06:54:59 -0600713int rx51_kp_getc(struct stdio_dev *sdev)
Pali Rohár248ef0a2012-10-29 07:54:01 +0000714{
715 keybuf_head %= KEYBUF_SIZE;
Simon Glass0d1e1f72014-07-23 06:54:59 -0600716 while (!rx51_kp_tstc(sdev))
Pali Rohár248ef0a2012-10-29 07:54:01 +0000717 WATCHDOG_RESET();
718 return keybuf[keybuf_head++];
719}
720
Pali Rohárcc58d292021-01-16 01:04:54 +0100721static const struct mmc_config rx51_mmc_cfg = {
722 .host_caps = MMC_MODE_4BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS,
723 .f_min = 400000,
724 .f_max = 52000000,
725 .b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT,
726 .voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195,
727};
Paul Kocialkowski69559892014-11-08 20:55:47 +0100728
Pali Rohárcc58d292021-01-16 01:04:54 +0100729static const struct omap_hsmmc_plat rx51_mmc[] = {
730 { rx51_mmc_cfg, (struct hsmmc *)OMAP_HSMMC1_BASE },
731 { rx51_mmc_cfg, (struct hsmmc *)OMAP_HSMMC2_BASE },
732};
733
734U_BOOT_DRVINFOS(rx51_mmc) = {
735 { "omap_hsmmc", &rx51_mmc[0] },
736 { "omap_hsmmc", &rx51_mmc[1] },
737};
Pali Rohárd73afb22020-10-26 23:45:11 +0100738
Simon Glassb75b15b2020-12-03 16:55:23 -0700739static const struct omap_i2c_plat rx51_i2c[] = {
Pali Rohárde39c112020-11-21 23:30:11 +0100740 { I2C_BASE1, 100000, OMAP_I2C_REV_V1 },
Pali Rohárd73afb22020-10-26 23:45:11 +0100741 { I2C_BASE2, 100000, OMAP_I2C_REV_V1 },
Pali Rohárde39c112020-11-21 23:30:11 +0100742 { I2C_BASE3, 100000, OMAP_I2C_REV_V1 },
Pali Rohárd73afb22020-10-26 23:45:11 +0100743};
744
Simon Glass1d8364a2020-12-28 20:34:54 -0700745U_BOOT_DRVINFOS(rx51_i2c) = {
Pali Rohárd73afb22020-10-26 23:45:11 +0100746 { "i2c_omap", &rx51_i2c[0] },
747 { "i2c_omap", &rx51_i2c[1] },
748 { "i2c_omap", &rx51_i2c[2] },
749};
Pali Rohár126038a2021-03-09 21:19:15 +0100750
751U_BOOT_DRVINFOS(rx51_watchdog) = {
752 { "rx51_watchdog" },
753};