blob: fa660c82f54aa0ae7ce4f9f3e5311fb7c54151ad [file] [log] [blame]
Alexandru Gagniuc14964dd2013-12-13 20:25:04 -06001/*
Alexandru Gagniuc93b600d2014-01-03 01:27:23 -05002 * Basic romstage for Cubieboard
3 *
4 * Set up system voltages, then increase the CPU clock, before turning control
5 * to ramstage. The CPU VDD needs to be properly set before it can run at full
6 * speed. Setting the CPU at full speed helps lzma-decompress ramstage a lot
7 * faster.
Alexandru Gagniuc14964dd2013-12-13 20:25:04 -06008 *
9 * Copyright (C) 2013 Alexandru Gagniuc <mr.nuke.me@gmail.com>
10 * Subject to the GNU GPL v2, or (at your option) any later version.
11 */
12
Alexandru Gagniuc93b600d2014-01-03 01:27:23 -050013#include <arch/stages.h>
14#include <cbfs.h>
Alexandru Gagniuc14964dd2013-12-13 20:25:04 -060015#include <console/console.h>
Alexandru Gagniuc8e053af2014-01-09 20:45:21 -060016#include <cpu/allwinner/a10/clock.h>
17#include <cpu/allwinner/a10/gpio.h>
18#include <cpu/allwinner/a10/twi.h>
Aaron Durbine4f3e7a2015-03-17 13:25:19 -050019#include <program_loading.h>
Alexandru Gagniuc8e053af2014-01-09 20:45:21 -060020#define __SIMPLE_DEVICE__
21#include <device/device.h>
22#include <drivers/xpowers/axp209/axp209.h>
23#include <drivers/xpowers/axp209/chip.h>
24
25
26#define GPB_TWI0_FUNC 2
27#define GPB_TWI0_PINS ((1 << 0) | (1 << 1))
28
29#define AXP209_BUS 0
30
31static enum cb_err cubieboard_setup_power(void)
32{
33 enum cb_err err;
34 const struct device * pmu;
35 const struct drivers_xpowers_axp209_config *cfg;
36
37 /* Find the AXP209 in devicetree */
38 pmu = dev_find_slot_on_smbus(AXP209_BUS, AXP209_I2C_ADDR);
39 if (!pmu) {
40 printk(BIOS_ERR, "AXP209 not found in devicetree.cb\n");
41 return CB_ERR;
42 }
43
44 cfg = pmu->chip_info;
45
46 /* Mux TWI0 pins */
47 gpio_set_multipin_func(GPB, GPB_TWI0_PINS, GPB_TWI0_FUNC);
48 /* Enable TWI0 */
49 a1x_periph_clock_enable(A1X_CLKEN_TWI0);
50 a1x_twi_init(AXP209_BUS, 400000);
51
52 if ((err = axp209_init(AXP209_BUS)) != CB_SUCCESS) {
53 printk(BIOS_ERR, "PMU initialization failed\n");
54 return err;
55 }
56
57 if ((err = axp209_set_voltages(AXP209_BUS, cfg)) != CB_SUCCESS) {
58 printk(BIOS_WARNING, "Power setup incomplete: "
59 "CPU may hang when increasing clock\n");
60 return err;
61 }
62
63 printk(BIOS_SPEW, "VDD CPU (DCDC2): %imv\n", cfg->dcdc2_voltage_mv);
64 printk(BIOS_SPEW, "VDD DLL (DCDC3): %imv\n", cfg->dcdc3_voltage_mv);
65 printk(BIOS_SPEW, "AVCC (LDO2) : %imv\n", cfg->ldo2_voltage_mv);
66 printk(BIOS_SPEW, "CSI1-IO (LDO4) : %imv\n", cfg->ldo4_voltage_mv);
67 printk(BIOS_SPEW, "(LDO3) : %imv\n", cfg->ldo3_voltage_mv);
68
69 return CB_SUCCESS;
70}
Alexandru Gagniuc14964dd2013-12-13 20:25:04 -060071
72void main(void)
73{
Alexandru Gagniuc93b600d2014-01-03 01:27:23 -050074 enum cb_err err;
75
Alexandru Gagniuc14964dd2013-12-13 20:25:04 -060076 console_init();
Alexandru Gagniuc8e053af2014-01-09 20:45:21 -060077
78 /* Configure power rails */
Alexandru Gagniuc93b600d2014-01-03 01:27:23 -050079 err = cubieboard_setup_power();
Alexandru Gagniuc8e053af2014-01-09 20:45:21 -060080
Alexandru Gagniuc93b600d2014-01-03 01:27:23 -050081 if (err == CB_SUCCESS) {
82 /* TODO: Get this clock from devicetree.cb */
83 a1x_set_cpu_clock(1008);
84 } else {
85 /* cubieboard_setup_power() prints more details */
86 printk(BIOS_WARNING, "Will run CPU at reduced speed\n");
87 a1x_set_cpu_clock(384);
88 }
89
Aaron Durbine4f3e7a2015-03-17 13:25:19 -050090 run_ramstage();
Alexandru Gagniuc14964dd2013-12-13 20:25:04 -060091}