/*
 * 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.
 *
 * Contributions after 2012-01-13 are licensed under the terms of the
 * GNU GPL, version 2 or (at your option) any later version.
 */
#include "qemu/osdep.h"
#include "qemu/error-report.h"
#include "qapi/error.h"
#include "hw/hw.h"
#include "hw/arm/pxa.h"
#include "hw/arm/arm.h"
#include "net/net.h"
#include "hw/devices.h"
#include "hw/boards.h"
#include "hw/block/flash.h"
#include "sysemu/block-backend.h"
#include "hw/sysbus.h"
#include "exec/address-spaces.h"
#include "sysemu/qtest.h"
#include "cpu.h"

/* Device addresses */
#define MST_FPGA_PHYS	0x08000000
#define MST_ETH_PHYS	0x10000300
#define MST_FLASH_0		0x00000000
#define MST_FLASH_1		0x04000000

/* IRQ definitions */
#define MMC_IRQ       0
#define USIM_IRQ      1
#define USBC_IRQ      2
#define ETHERNET_IRQ  3
#define AC97_IRQ      4
#define PEN_IRQ       5
#define MSINS_IRQ     6
#define EXBRD_IRQ     7
#define S0_CD_IRQ     9
#define S0_STSCHG_IRQ 10
#define S0_IRQ        11
#define S1_CD_IRQ     13
#define S1_STSCHG_IRQ 14
#define S1_IRQ        15

static const 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 */
    [0x34] = {4,0}, /* . */
    [0x15] = {4,2}, /* y */
    [0x2c] = {4,3}, /* z */
    [0x35] = {4,4}, /* / */
    [0xc7] = {5,0}, /* Home */
    [0x2a] = {5,1}, /* shift */
    /*
     * There are two matrix positions which map to space,
     * but QEMU can only use one of them for the reverse
     * mapping, so simply use the second one.
     */
    /* [0x39] = {5,2}, space */
    [0x39] = {5,3}, /* space */
    /*
     * Matrix position {5,4} and other keys are missing here.
     * TODO: Compare with Linux code and test real hardware.
     */
    [0x1c] = {5,4}, /* enter */
    [0x0e] = {5,5}, /* backspace */
    [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(MemoryRegion *address_space_mem,
                                  MachineState *machine,
                                  enum mainstone_model_e model, int arm_id)
{
    uint32_t sector_len = 256 * 1024;
    hwaddr mainstone_flash_base[] = { MST_FLASH_0, MST_FLASH_1 };
    PXA2xxState *mpu;
    DeviceState *mst_irq;
    DriveInfo *dinfo;
    int i;
    int be;
    MemoryRegion *rom = g_new(MemoryRegion, 1);

    /* Setup CPU & memory */
    mpu = pxa270_init(address_space_mem, mainstone_binfo.ram_size,
                      machine->cpu_type);
    memory_region_init_ram(rom, NULL, "mainstone.rom", MAINSTONE_ROM,
                           &error_fatal);
    memory_region_set_readonly(rom, true);
    memory_region_add_subregion(address_space_mem, 0, 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) {
            if (qtest_enabled()) {
                break;
            }
            error_report("Two flash images must be given with the "
                         "'pflash' parameter");
            exit(1);
        }

        if (!pflash_cfi01_register(mainstone_flash_base[i], NULL,
                                   i ? "mainstone.flash1" : "mainstone.flash0",
                                   MAINSTONE_FLASH,
                                   blk_by_legacy_dinfo(dinfo),
                                   sector_len, MAINSTONE_FLASH / sector_len,
                                   4, 0, 0, 0, 0, be)) {
            error_report("Error registering flash memory");
            exit(1);
        }
    }

    mst_irq = sysbus_create_simple("mainstone-fpga", MST_FPGA_PHYS,
                    qdev_get_gpio_in(mpu->gpio, 0));

    /* setup keypad */
    pxa27x_register_keypad(mpu->kp, map, 0xe0);

    /* MMC/SD host */
    pxa2xx_mmci_handlers(mpu->mmc, NULL, qdev_get_gpio_in(mst_irq, MMC_IRQ));

    pxa2xx_pcmcia_set_irq_cb(mpu->pcmcia[0],
            qdev_get_gpio_in(mst_irq, S0_IRQ),
            qdev_get_gpio_in(mst_irq, S0_CD_IRQ));
    pxa2xx_pcmcia_set_irq_cb(mpu->pcmcia[1],
            qdev_get_gpio_in(mst_irq, S1_IRQ),
            qdev_get_gpio_in(mst_irq, S1_CD_IRQ));

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

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

static void mainstone_init(MachineState *machine)
{
    mainstone_common_init(get_system_memory(), machine, mainstone, 0x196);
}

static void mainstone2_machine_init(MachineClass *mc)
{
    mc->desc = "Mainstone II (PXA27x)";
    mc->init = mainstone_init;
    mc->ignore_memory_transaction_failures = true;
    mc->default_cpu_type = ARM_CPU_TYPE_NAME("pxa270-c5");
}

DEFINE_MACHINE("mainstone", mainstone2_machine_init)
