/*
 * PXA270-based Intel Mainstone platforms.
 *
 * Copyright (c) 2007 by Armin Kuster <akuster@kama-aina.net> or
 *                                    <akuster@mvista.com>
 *
 * Code based on spitz platform by Andrzej Zaborowski <balrog@zabor.org>
 *
 * This code is licensed under the GNU GPL v2.
 */
#include "hw.h"
#include "pxa.h"
#include "arm-misc.h"
#include "net.h"
#include "devices.h"
#include "boards.h"
#include "mainstone.h"
#include "sysemu.h"
#include "flash.h"

static struct keymap map[0xE0] = {
    [0 ... 0xDF] = { -1, -1 },
    [0x1e] = {0,0}, /* a */
    [0x30] = {0,1}, /* b */
    [0x2e] = {0,2}, /* c */
    [0x20] = {0,3}, /* d */
    [0x12] = {0,4}, /* e */
    [0x21] = {0,5}, /* f */
    [0x22] = {1,0}, /* g */
    [0x23] = {1,1}, /* h */
    [0x17] = {1,2}, /* i */
    [0x24] = {1,3}, /* j */
    [0x25] = {1,4}, /* k */
    [0x26] = {1,5}, /* l */
    [0x32] = {2,0}, /* m */
    [0x31] = {2,1}, /* n */
    [0x18] = {2,2}, /* o */
    [0x19] = {2,3}, /* p */
    [0x10] = {2,4}, /* q */
    [0x13] = {2,5}, /* r */
    [0x1f] = {3,0}, /* s */
    [0x14] = {3,1}, /* t */
    [0x16] = {3,2}, /* u */
    [0x2f] = {3,3}, /* v */
    [0x11] = {3,4}, /* w */
    [0x2d] = {3,5}, /* x */
    [0x15] = {4,2}, /* y */
    [0x2c] = {4,3}, /* z */
    [0xc7] = {5,0}, /* Home */
    [0x2a] = {5,1}, /* shift */
    [0x39] = {5,2}, /* space */
    [0x39] = {5,3}, /* space */
    [0x1c] = {5,5}, /*  enter */
    [0xc8] = {6,0}, /* up */
    [0xd0] = {6,1}, /* down */
    [0xcb] = {6,2}, /* left */
    [0xcd] = {6,3}, /* right */
};

enum mainstone_model_e { mainstone };

#define MAINSTONE_RAM	0x04000000
#define MAINSTONE_ROM	0x00800000
#define MAINSTONE_FLASH	0x02000000

static struct arm_boot_info mainstone_binfo = {
    .loader_start = PXA2XX_SDRAM_BASE,
    .ram_size = 0x04000000,
};

static void mainstone_common_init(ram_addr_t ram_size,
                const char *kernel_filename,
                const char *kernel_cmdline, const char *initrd_filename,
                const char *cpu_model, enum mainstone_model_e model, int arm_id)
{
    uint32_t sector_len = 256 * 1024;
    target_phys_addr_t mainstone_flash_base[] = { MST_FLASH_0, MST_FLASH_1 };
    PXA2xxState *cpu;
    qemu_irq *mst_irq;
    DriveInfo *dinfo;
    int i;
    int be;

    if (!cpu_model)
        cpu_model = "pxa270-c5";

    /* Setup CPU & memory */
    cpu = pxa270_init(mainstone_binfo.ram_size, cpu_model);
    cpu_register_physical_memory(0, MAINSTONE_ROM,
                    qemu_ram_alloc(NULL, "mainstone.rom",
                                   MAINSTONE_ROM) | IO_MEM_ROM);

#ifdef TARGET_WORDS_BIGENDIAN
    be = 1;
#else
    be = 0;
#endif
    /* There are two 32MiB flash devices on the board */
    for (i = 0; i < 2; i ++) {
        dinfo = drive_get(IF_PFLASH, 0, i);
        if (!dinfo) {
            fprintf(stderr, "Two flash images must be given with the "
                    "'pflash' parameter\n");
            exit(1);
        }

        if (!pflash_cfi01_register(mainstone_flash_base[i],
                                   qemu_ram_alloc(NULL, "mainstone.flash",
                                                  MAINSTONE_FLASH),
                                   dinfo->bdrv, sector_len,
                                   MAINSTONE_FLASH / sector_len, 4, 0, 0, 0, 0,
                                   be)) {
            fprintf(stderr, "qemu: Error registering flash memory.\n");
            exit(1);
        }
    }

    mst_irq = mst_irq_init(cpu, MST_FPGA_PHYS, PXA2XX_PIC_GPIO_0);

    /* setup keypad */
    printf("map addr %p\n", &map);
    pxa27x_register_keypad(cpu->kp, map, 0xe0);

    /* MMC/SD host */
    pxa2xx_mmci_handlers(cpu->mmc, NULL, mst_irq[MMC_IRQ]);

    smc91c111_init(&nd_table[0], MST_ETH_PHYS, mst_irq[ETHERNET_IRQ]);

    mainstone_binfo.kernel_filename = kernel_filename;
    mainstone_binfo.kernel_cmdline = kernel_cmdline;
    mainstone_binfo.initrd_filename = initrd_filename;
    mainstone_binfo.board_id = arm_id;
    arm_load_kernel(cpu->env, &mainstone_binfo);
}

static void mainstone_init(ram_addr_t ram_size,
                const char *boot_device,
                const char *kernel_filename, const char *kernel_cmdline,
                const char *initrd_filename, const char *cpu_model)
{
    mainstone_common_init(ram_size, kernel_filename,
                kernel_cmdline, initrd_filename, cpu_model, mainstone, 0x196);
}

static QEMUMachine mainstone2_machine = {
    .name = "mainstone",
    .desc = "Mainstone II (PXA27x)",
    .init = mainstone_init,
};

static void mainstone_machine_init(void)
{
    qemu_register_machine(&mainstone2_machine);
}

machine_init(mainstone_machine_init);
