/* * Minimal bootblock for Cubieboard * It sets up CPU clock, and enables the bootblock console. * * Copyright (C) 2013 Alexandru Gagniuc * Subject to the GNU GPL v2, or (at your option) any later version. */ #include #include #include #include #include #include #include #define CPU_AHB_APB0_DEFAULT \ CPU_CLK_SRC_OSC24M \ | APB0_DIV_1 \ | AHB_DIV_2 \ | AXI_DIV_1 #define GPH_STATUS_LEDS (1 << 20) | (1 << 21) #define GPH_LED1_PIN_NO 21 #define GPH_LED2_PIN_NO 20 #define GPB_UART0_FUNC 2 #define GPB_UART0_PINS ((1 << 22) | (1 << 23)) static void cubieboard_set_sys_clock(void) { u32 reg32; struct a10_ccm *ccm = (void *)A1X_CCM_BASE; /* Switch CPU clock to main oscillator */ write32(CPU_AHB_APB0_DEFAULT, &ccm->cpu_ahb_apb0_cfg); /* Configure the PLL1. The value is the same one used by u-boot * P = 1, N = 16, K = 1, M = 1 --> Output = 384 MHz */ write32(0xa1005000, &ccm->pll1_cfg); /* FIXME: Delay to wait for PLL to lock */ u32 wait = 1000; while (--wait); /* Switch CPU to PLL clock */ reg32 = read32(&ccm->cpu_ahb_apb0_cfg); reg32 &= ~CPU_CLK_SRC_MASK; reg32 |= CPU_CLK_SRC_PLL1; write32(reg32, &ccm->cpu_ahb_apb0_cfg); } static void cubieboard_setup_clocks(void) { struct a10_ccm *ccm = (void *)A1X_CCM_BASE; cubieboard_set_sys_clock(); /* Configure the clock source for APB1. This drives our UART */ write32(APB1_CLK_SRC_OSC24M | APB1_RAT_N(0) | APB1_RAT_M(0), &ccm->apb1_clk_div_cfg); } static void cubieboard_setup_gpios(void) { /* Mux Status LED pins */ gpio_set_multipin_func(GPH, GPH_STATUS_LEDS, GPIO_PIN_FUNC_OUTPUT); /* Turn on green LED to let user know we're executing coreboot code */ gpio_set(GPH, GPH_LED2_PIN_NO); /* Mux UART pins */ gpio_set_multipin_func(GPB, GPB_UART0_PINS, GPB_UART0_FUNC); } static void cubieboard_enable_uart(void) { a1x_periph_clock_enable(A1X_CLKEN_UART0); } static void cubieboard_raminit(void) { struct dram_para dram_para = { .clock = 480, .type = 3, .rank_num = 1, .density = 4096, .io_width = 16, .bus_width = 32, .cas = 6, .zq = 123, .odt_en = 0, .size = 1024, .tpr0 = 0x30926692, .tpr1 = 0x1090, .tpr2 = 0x1a0c8, .tpr3 = 0, .tpr4 = 0, .tpr5 = 0, .emr1 = 0, .emr2 = 0, .emr3 = 0, }; dramc_init(&dram_para); /* FIXME: ram_check does not compile for ARM, * and we didn't init console yet */ ////void *const test_base = (void *)A1X_DRAM_BASE; ////ram_check((u32)test_base, (u32)test_base + 0x1000); } void bootblock_mainboard_init(void); void bootblock_mainboard_init(void) { /* A10 Timer init uses the 24MHz clock, not PLLs, so we can init it very * early on to get udelay, which is used almost everywhere else. */ init_timer(); cubieboard_setup_clocks(); cubieboard_setup_gpios(); cubieboard_enable_uart(); cubieboard_raminit(); }