uboot/board/nokia/rx51/rx51.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * (C) Copyright 2012
   4 * Ивайло Димитров <freemangordon@abv.bg>
   5 *
   6 * (C) Copyright 2011-2012
   7 * Pali Rohár <pali@kernel.org>
   8 *
   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>
  22 */
  23
  24#include <common.h>
  25#include <dm.h>
  26#include <env.h>
  27#include <init.h>
  28#include <watchdog.h>
  29#include <wdt.h>
  30#include <malloc.h>
  31#include <twl4030.h>
  32#include <i2c.h>
  33#include <video.h>
  34#include <keyboard.h>
  35#include <ns16550.h>
  36#include <asm/global_data.h>
  37#include <asm/io.h>
  38#include <asm/setup.h>
  39#include <asm/bitops.h>
  40#include <asm/mach-types.h>
  41#include <asm/omap_i2c.h>
  42#include <asm/arch/mux.h>
  43#include <asm/arch/sys_proto.h>
  44#include <asm/arch/mmc_host_def.h>
  45
  46#include "tag_omap.h"
  47
  48/* 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
  64DECLARE_GLOBAL_DATA_PTR;
  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),
  92        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),
  98        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;
 110static int serial_was_console_enabled;
 111
 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;
 167                case OMAP_TAG_UART:
 168                        if (t->u.uart.enabled_uarts)
 169                                serial_was_console_enabled = 1;
 170                        break;
 171                case OMAP_TAG_SERIAL_CONSOLE:
 172                        serial_was_console_enabled = 1;
 173                        break;
 174                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{
 220#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
 231        /* in SRAM or SDRAM, finish GPMC */
 232        gpmc_init();
 233#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
 237        /* Enable the clks & power */
 238        per_clocks_enable();
 239        /* boot param addr */
 240        gd->bd->bi_boot_params = OMAP34XX_SDRC_CS0 + 0x100;
 241        return 0;
 242}
 243
 244#ifdef CONFIG_REVISION_TAG
 245/*
 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}
 253#endif
 254
 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 */
 278        str = env_get("setup_omap_atag");
 279        if (!str || str[0] != '1')
 280                return;
 281
 282        str = env_get("setup_console_atag");
 283        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        }
 294
 295        setup_boot_reason_atag = env_get("setup_boot_reason_atag");
 296        setup_boot_mode_atag = env_get("setup_boot_mode_atag");
 297
 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
 344static int rx51_video_probe(struct udevice *dev)
 345{
 346        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;
 358}
 359
 360U_BOOT_DRIVER(rx51_video) = {
 361        .name = "rx51_video",
 362        .id = UCLASS_VIDEO,
 363        .probe = rx51_video_probe,
 364};
 365
 366/*
 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);
 373        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);
 377}
 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
 398void 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
 409/*
 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{
 418        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;
 424        omap3_set_aux_cr_secure(acr);
 425}
 426
 427/*
 428 * Routine: misc_init_r
 429 * Description: Configure board specific parts.
 430 */
 431int misc_init_r(void)
 432{
 433        struct udevice *dev;
 434        char buf[12];
 435        u8 state;
 436
 437        /* disable lp5523 led */
 438        if (i2c_get_chip_for_busnum(1, 0x32, 1, &dev) == 0)
 439                dm_i2c_reg_write(dev, 0x00, 0x00);
 440
 441        /* initialize twl4030 power managment */
 442        twl4030_power_init();
 443        twl4030_power_mmc_init(0);
 444        twl4030_power_mmc_init(1);
 445
 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 */
 453        twl4030_i2c_read_u8(TWL4030_CHIP_PM_MASTER, TWL4030_PM_MASTER_PB_CFG,
 454                            &state);
 455
 456        /* enable I2C access to powerbus (needed for twl4030 regulator) */
 457        twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER, TWL4030_PM_MASTER_PB_CFG,
 458                             0x02);
 459
 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 */
 466        twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER, TWL4030_PM_MASTER_PB_CFG,
 467                             state);
 468
 469        /* set env variable attkernaddr for relocated kernel */
 470        sprintf(buf, "%#x", KERNEL_ADDRESS);
 471        env_set("attkernaddr", buf);
 472
 473        /* initialize omap tags */
 474        init_omap_tags();
 475
 476        /* reuse atags from previous bootloader */
 477        reuse_atags();
 478
 479        omap_die_id_display();
 480        print_cpuinfo();
 481
 482        /*
 483         * Cortex-A8(r1p0..r1p2) errata 430973 workaround
 484         * Set IBE bit in Auxiliary Control Register
 485         *
 486         * Call this routine only on real secure device
 487         * Qemu does not implement secure PPA and crash
 488         */
 489        if (get_device_type() == HS_DEVICE)
 490                omap3_update_aux_cr_secure_rx51(1 << 6, 0);
 491
 492        return 0;
 493}
 494
 495static unsigned long int twl_wd_time; /* last time of watchdog reset */
 496static unsigned long int twl_i2c_lock;
 497
 498/*
 499 * Routine: rx51_watchdog_reset
 500 * Description: Reset timeout of twl4030 watchdog.
 501 */
 502static int rx51_watchdog_reset(struct udevice *dev)
 503{
 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)
 508                return 0;
 509
 510        /* localy lock twl4030 i2c bus */
 511        if (test_and_set_bit(0, &twl_i2c_lock))
 512                return 0;
 513
 514        /* read actual watchdog timeout */
 515        twl4030_i2c_read_u8(TWL4030_CHIP_PM_RECEIVER,
 516                            TWL4030_PM_RECEIVER_WATCHDOG_CFG, &timeout);
 517
 518        /* timeout 0 means watchdog is disabled */
 519        /* reset watchdog timeout to 31s (maximum) */
 520        if (timeout != 0)
 521                twl4030_i2c_write_u8(TWL4030_CHIP_PM_RECEIVER,
 522                                     TWL4030_PM_RECEIVER_WATCHDOG_CFG, 31);
 523
 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);
 529
 530        return 0;
 531}
 532
 533static int rx51_watchdog_start(struct udevice *dev, u64 timeout_ms, ulong flags)
 534{
 535        return 0;
 536}
 537
 538static 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
 555/*
 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',
 564        'r',  'v',  'b',  'n',  'm',  ' ',    0,    0,
 565        '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/*
 588 * Routine: rx51_kp_start
 589 * Description: Initialize HW keyboard.
 590 */
 591static int rx51_kp_start(struct udevice *dev)
 592{
 593        int ret = 0;
 594        u8 ctrl;
 595        ret = twl4030_i2c_read_u8(TWL4030_CHIP_KEYPAD,
 596                                  TWL4030_KEYPAD_KEYP_CTRL_REG, &ctrl);
 597
 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;
 605        ret |= twl4030_i2c_write_u8(TWL4030_CHIP_KEYPAD,
 606                                    TWL4030_KEYPAD_KEYP_CTRL_REG, ctrl);
 607        /* enable key event status */
 608        ret |= twl4030_i2c_write_u8(TWL4030_CHIP_KEYPAD,
 609                                    TWL4030_KEYPAD_KEYP_IMR1, 0xfe);
 610        /* enable interrupt generation on rising and falling */
 611        /* this is a workaround for qemu twl4030 emulation */
 612        ret |= twl4030_i2c_write_u8(TWL4030_CHIP_KEYPAD,
 613                                    TWL4030_KEYPAD_KEYP_EDR, 0x57);
 614        /* enable ISR clear on read */
 615        ret |= twl4030_i2c_write_u8(TWL4030_CHIP_KEYPAD,
 616                                    TWL4030_KEYPAD_KEYP_SIH_CTRL, 0x05);
 617        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 */
 665static int rx51_kp_tstc(struct udevice *dev)
 666{
 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 */
 679                twl4030_i2c_read_u8(TWL4030_CHIP_KEYPAD,
 680                                    TWL4030_KEYPAD_KEYP_ISR1 + (2 * i), &intr);
 681
 682                /* no event */
 683                if (!(intr&1))
 684                        continue;
 685
 686                /* read the key state */
 687                twl4030_i2c_read(TWL4030_CHIP_KEYPAD,
 688                                 TWL4030_KEYPAD_FULL_CODE_7_0, keys, 8);
 689
 690                /* cut out modifier keys from the keystate */
 691                mods = keys[4] >> 4;
 692                keys[4] &= 0x0f;
 693
 694                /* space key is indicated by two different bits */
 695                keys[3] |= (keys[3] & (1 << 6)) >> 1;
 696                keys[3] &= ~(1 << 6);
 697
 698                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 */
 725static int rx51_kp_getc(struct udevice *dev)
 726{
 727        keybuf_head %= KEYBUF_SIZE;
 728        while (!rx51_kp_tstc(dev))
 729                schedule();
 730        return keybuf[keybuf_head++];
 731}
 732
 733static 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
 755static 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};
 762
 763static 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};
 772
 773static const struct omap_i2c_plat rx51_i2c[] = {
 774        { I2C_BASE1, 100000, OMAP_I2C_REV_V1 },
 775        { I2C_BASE2, 100000, OMAP_I2C_REV_V1 },
 776        { I2C_BASE3, 100000, OMAP_I2C_REV_V1 },
 777};
 778
 779U_BOOT_DRVINFOS(rx51_i2c) = {
 780        { "i2c_omap", &rx51_i2c[0] },
 781        { "i2c_omap", &rx51_i2c[1] },
 782        { "i2c_omap", &rx51_i2c[2] },
 783};
 784
 785U_BOOT_DRVINFOS(rx51_watchdog) = {
 786        { "rx51_watchdog" },
 787};
 788
 789U_BOOT_DRVINFOS(rx51_video) = {
 790        { "rx51_video" },
 791};
 792
 793U_BOOT_DRVINFOS(rx51_kp) = {
 794        { "rx51_kp" },
 795};
 796
 797static const struct ns16550_plat rx51_serial = {
 798        .base = CONFIG_SYS_NS16550_COM3,
 799        .reg_shift = 2,
 800        .clock = CONFIG_SYS_NS16550_CLK,
 801        .fcr = UART_FCR_DEFVAL,
 802};
 803
 804U_BOOT_DRVINFOS(rx51_uart) = {
 805        { "omap_serial", &rx51_serial },
 806};
 807