diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c index 7884b2b03d..037f3a26f2 100644 --- a/hw/arm/npcm7xx.c +++ b/hw/arm/npcm7xx.c @@ -55,6 +55,13 @@ #define NPCM7XX_ROM_BA (0xffff0000) #define NPCM7XX_ROM_SZ (64 * KiB) +/* Clock configuration values to be fixed up when bypassing bootloader */ + +/* Run PLL1 at 1600 MHz */ +#define NPCM7XX_PLLCON1_FIXUP_VAL (0x00402101) +/* Run the CPU from PLL1 and UART from PLL2 */ +#define NPCM7XX_CLKSEL_FIXUP_VAL (0x004aaba9) + /* * Interrupt lines going into the GIC. This does not include internal Cortex-A9 * interrupts. @@ -132,6 +139,29 @@ static const struct { }, }; +static void npcm7xx_write_board_setup(ARMCPU *cpu, + const struct arm_boot_info *info) +{ + uint32_t board_setup[] = { + 0xe59f0010, /* ldr r0, clk_base_addr */ + 0xe59f1010, /* ldr r1, pllcon1_value */ + 0xe5801010, /* str r1, [r0, #16] */ + 0xe59f100c, /* ldr r1, clksel_value */ + 0xe5801004, /* str r1, [r0, #4] */ + 0xe12fff1e, /* bx lr */ + NPCM7XX_CLK_BA, + NPCM7XX_PLLCON1_FIXUP_VAL, + NPCM7XX_CLKSEL_FIXUP_VAL, + }; + int i; + + for (i = 0; i < ARRAY_SIZE(board_setup); i++) { + board_setup[i] = tswap32(board_setup[i]); + } + rom_add_blob_fixed("board-setup", board_setup, sizeof(board_setup), + info->board_setup_addr); +} + static void npcm7xx_write_secondary_boot(ARMCPU *cpu, const struct arm_boot_info *info) { @@ -170,6 +200,8 @@ static struct arm_boot_info npcm7xx_binfo = { .gic_cpu_if_addr = NPCM7XX_GIC_CPU_IF_ADDR, .write_secondary_boot = npcm7xx_write_secondary_boot, .board_id = -1, + .board_setup_addr = NPCM7XX_BOARD_SETUP_ADDR, + .write_board_setup = npcm7xx_write_board_setup, }; void npcm7xx_load_kernel(MachineState *machine, NPCM7xxState *soc) diff --git a/include/hw/arm/npcm7xx.h b/include/hw/arm/npcm7xx.h index 78d0d78c52..13106af215 100644 --- a/include/hw/arm/npcm7xx.h +++ b/include/hw/arm/npcm7xx.h @@ -37,6 +37,7 @@ #define NPCM7XX_SMP_LOADER_START (0xffff0000) /* Boot ROM */ #define NPCM7XX_SMP_BOOTREG_ADDR (0xf080013c) /* GCR.SCRPAD */ #define NPCM7XX_GIC_CPU_IF_ADDR (0xf03fe100) /* GIC within A9 */ +#define NPCM7XX_BOARD_SETUP_ADDR (0xffff1000) /* Boot ROM */ typedef struct NPCM7xxMachine { MachineState parent;