aboutsummaryrefslogtreecommitdiff
path: root/hw/arm/npcm7xx.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/arm/npcm7xx.c')
-rw-r--r--hw/arm/npcm7xx.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
index 7884b2b..037f3a2 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)