59feed7891b996f9ee73ac4334c138e63b650bb6
2 * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
3 * Copyright (c) 2018, Icenowy Zheng <icenowy@aosc.io>
5 * SPDX-License-Identifier: BSD-3-Clause
8 #include <allwinner/sunxi_rsb.h>
9 #include <arch_helpers.h>
11 #include <delay_timer.h>
15 #include <platform_def.h>
16 #include <sunxi_def.h>
17 #include <sunxi_mmap.h>
18 #include <sunxi_private.h>
20 static enum pmic_type
{
23 REF_DESIGN_H5
, /* regulators controlled by GPIO pins on port L */
24 AXP803_RSB
, /* PMIC connected via RSB on most A64 boards */
27 #define AXP803_HW_ADDR 0x3a3
28 #define AXP803_RT_ADDR 0x2d
31 * On boards without a proper PMIC we struggle to turn off the system properly.
32 * Try to turn off as much off the system as we can, to reduce power
33 * consumption. This should be entered with only one core running and SMP
35 * This function only cares about peripherals.
37 void sunxi_turn_off_soc(uint16_t socid
)
41 /** Turn off most peripherals, most importantly DRAM users. **/
42 /* Keep DRAM controller running for now. */
43 mmio_clrbits_32(SUNXI_CCU_BASE
+ 0x2c0, ~BIT_32(14));
44 mmio_clrbits_32(SUNXI_CCU_BASE
+ 0x60, ~BIT_32(14));
45 /* Contains msgbox (bit 21) and spinlock (bit 22) */
46 mmio_write_32(SUNXI_CCU_BASE
+ 0x2c4, 0);
47 mmio_write_32(SUNXI_CCU_BASE
+ 0x64, 0);
48 mmio_write_32(SUNXI_CCU_BASE
+ 0x2c8, 0);
49 /* Keep PIO controller running for now. */
50 mmio_clrbits_32(SUNXI_CCU_BASE
+ 0x68, ~(BIT_32(5)));
51 mmio_write_32(SUNXI_CCU_BASE
+ 0x2d0, 0);
52 /* Contains UART0 (bit 16) */
53 mmio_write_32(SUNXI_CCU_BASE
+ 0x2d8, 0);
54 mmio_write_32(SUNXI_CCU_BASE
+ 0x6c, 0);
55 mmio_write_32(SUNXI_CCU_BASE
+ 0x70, 0);
57 /** Turn off DRAM controller. **/
58 mmio_clrbits_32(SUNXI_CCU_BASE
+ 0x2c0, BIT_32(14));
59 mmio_clrbits_32(SUNXI_CCU_BASE
+ 0x60, BIT_32(14));
61 /** Migrate CPU and bus clocks away from the PLLs. **/
62 /* AHB1: use OSC24M/1, APB1 = AHB1 / 2 */
63 mmio_write_32(SUNXI_CCU_BASE
+ 0x54, 0x1000);
64 /* APB2: use OSC24M */
65 mmio_write_32(SUNXI_CCU_BASE
+ 0x58, 0x1000000);
66 /* AHB2: use AHB1 clock */
67 mmio_write_32(SUNXI_CCU_BASE
+ 0x5c, 0);
69 mmio_write_32(SUNXI_CCU_BASE
+ 0x50, 0x10000);
71 /** Turn off PLLs. **/
72 for (i
= 0; i
< 6; i
++)
73 mmio_clrbits_32(SUNXI_CCU_BASE
+ i
* 8, BIT(31));
76 mmio_clrbits_32(SUNXI_CCU_BASE
+ 0x44, BIT(31));
79 mmio_clrbits_32(SUNXI_CCU_BASE
+ 0x2c, BIT(31));
80 mmio_clrbits_32(SUNXI_CCU_BASE
+ 0x4c, BIT(31));
85 static int rsb_init(void)
89 ret
= rsb_init_controller();
93 /* Start with 400 KHz to issue the I2C->RSB switch command. */
94 ret
= rsb_set_bus_speed(SUNXI_OSC24M_CLK_IN_HZ
, 400000);
99 * Initiate an I2C transaction to write 0x7c into register 0x3e,
100 * switching the PMIC to RSB mode.
102 ret
= rsb_set_device_mode(0x7c3e00);
106 /* Now in RSB mode, switch to the recommended 3 MHz. */
107 ret
= rsb_set_bus_speed(SUNXI_OSC24M_CLK_IN_HZ
, 3000000);
111 /* Associate the 8-bit runtime address with the 12-bit bus address. */
112 return rsb_assign_runtime_address(AXP803_HW_ADDR
,
116 static int axp_write(uint8_t reg
, uint8_t val
)
118 return rsb_write(AXP803_RT_ADDR
, reg
, val
);
121 static int axp_clrsetbits(uint8_t reg
, uint8_t clr_mask
, uint8_t set_mask
)
126 ret
= rsb_read(AXP803_RT_ADDR
, reg
);
130 regval
= (ret
& ~clr_mask
) | set_mask
;
132 return rsb_write(AXP803_RT_ADDR
, reg
, regval
);
135 #define axp_clrbits(reg, clr_mask) axp_clrsetbits(reg, clr_mask, 0)
136 #define axp_setbits(reg, set_mask) axp_clrsetbits(reg, 0, set_mask)
138 static bool should_enable_regulator(const void *fdt
, int node
)
140 if (fdt_getprop(fdt
, node
, "phandle", NULL
) != NULL
)
142 if (fdt_getprop(fdt
, node
, "regulator-always-on", NULL
) != NULL
)
148 * Retrieve the voltage from a given regulator DTB node.
149 * Both the regulator-{min,max}-microvolt properties must be present and
150 * have the same value. Return that value in millivolts.
152 static int fdt_get_regulator_millivolt(const void *fdt
, int node
)
157 prop
= fdt_getprop(fdt
, node
, "regulator-min-microvolt", NULL
);
160 min_volt
= fdt32_to_cpu(*prop
);
162 prop
= fdt_getprop(fdt
, node
, "regulator-max-microvolt", NULL
);
166 if (fdt32_to_cpu(*prop
) != min_volt
)
169 return min_volt
/ 1000;
172 #define NO_SPLIT 0xff
174 struct axp_regulator
{
180 unsigned char volt_reg
;
181 unsigned char switch_reg
;
182 unsigned char switch_bit
;
184 {"dcdc1", 1600, 3400, 100, NO_SPLIT
, 0x20, 0x10, 0},
185 {"dcdc5", 800, 1840, 10, 32, 0x24, 0x10, 4},
186 {"dcdc6", 600, 1520, 10, 50, 0x25, 0x10, 5},
187 {"dldo1", 700, 3300, 100, NO_SPLIT
, 0x15, 0x12, 3},
188 {"dldo2", 700, 4200, 100, 27, 0x16, 0x12, 4},
189 {"dldo3", 700, 3300, 100, NO_SPLIT
, 0x17, 0x12, 5},
190 {"fldo1", 700, 1450, 50, NO_SPLIT
, 0x1c, 0x13, 2},
194 static int setup_regulator(const void *fdt
, int node
,
195 const struct axp_regulator
*reg
)
200 if (!should_enable_regulator(fdt
, node
))
203 mvolt
= fdt_get_regulator_millivolt(fdt
, node
);
204 if (mvolt
< reg
->min_volt
|| mvolt
> reg
->max_volt
)
207 regval
= (mvolt
/ reg
->step
) - (reg
->min_volt
/ reg
->step
);
208 if (regval
> reg
->split
)
209 regval
= ((regval
- reg
->split
) / 2) + reg
->split
;
211 axp_write(reg
->volt_reg
, regval
);
212 if (reg
->switch_reg
< 0xff)
213 axp_setbits(reg
->switch_reg
, BIT(reg
->switch_bit
));
215 INFO("PMIC: AXP803: %s voltage: %d.%03dV\n", reg
->dt_name
,
216 mvolt
/ 1000, mvolt
% 1000);
221 static void setup_axp803_rails(const void *fdt
)
226 /* locate the PMIC DT node, bail out if not found */
227 node
= fdt_node_offset_by_compatible(fdt
, -1, "x-powers,axp803");
228 if (node
== -FDT_ERR_NOTFOUND
) {
229 WARN("BL31: PMIC: No AXP803 DT node, skipping initial setup.\n");
233 if (fdt_getprop(fdt
, node
, "x-powers,drive-vbus-en", NULL
)) {
234 axp_clrbits(0x8f, BIT(4));
235 axp_setbits(0x30, BIT(2));
236 INFO("PMIC: AXP803: Enabling DRIVEVBUS\n");
239 /* descend into the "regulators" subnode */
240 node
= fdt_first_subnode(fdt
, node
);
242 /* iterate over all regulators to find used ones */
243 for (node
= fdt_first_subnode(fdt
, node
);
244 node
!= -FDT_ERR_NOTFOUND
;
245 node
= fdt_next_subnode(fdt
, node
)) {
246 struct axp_regulator
*reg
;
250 /* We only care if it's always on or referenced. */
251 if (!should_enable_regulator(fdt
, node
))
254 name
= fdt_get_name(fdt
, node
, &length
);
255 for (reg
= regulators
; reg
->dt_name
; reg
++) {
256 if (!strncmp(name
, reg
->dt_name
, length
)) {
257 setup_regulator(fdt
, node
, reg
);
262 if (!strncmp(name
, "dc1sw", length
)) {
263 /* Delay DC1SW enablement to avoid overheating. */
269 * If DLDO2 is enabled after DC1SW, the PMIC overheats and shuts
270 * down. So always enable DC1SW as the very last regulator.
273 INFO("PMIC: AXP803: Enabling DC1SW\n");
274 axp_setbits(0x12, BIT(7));
278 int sunxi_pmic_setup(uint16_t socid
, const void *fdt
)
284 pmic
= REF_DESIGN_H5
;
285 NOTICE("BL31: PMIC: Defaulting to PortL GPIO according to H5 reference design.\n");
289 ret
= sunxi_init_platform_r_twi(socid
, true);
298 NOTICE("BL31: PMIC: Detected AXP803 on RSB.\n");
301 setup_axp803_rails(fdt
);
305 NOTICE("BL31: PMIC: No support for Allwinner %x SoC.\n", socid
);
311 void __dead2
sunxi_power_down(void)
315 /* Turn off as many peripherals and clocks as we can. */
316 sunxi_turn_off_soc(SUNXI_SOC_H5
);
317 /* Turn off the pin controller now. */
318 mmio_write_32(SUNXI_CCU_BASE
+ 0x68, 0);
321 /* Turn off as many peripherals and clocks as we can. */
322 sunxi_turn_off_soc(SUNXI_SOC_A64
);
323 /* Turn off the pin controller now. */
324 mmio_write_32(SUNXI_CCU_BASE
+ 0x68, 0);
327 sunxi_turn_off_soc(SUNXI_SOC_H5
);
330 * Switch PL pins to power off the board:
331 * - PL5 (VCC_IO) -> high
332 * - PL8 (PWR-STB = CPU power supply) -> low
333 * - PL9 (PWR-DRAM) ->low
334 * - PL10 (power LED) -> low
335 * Note: Clearing PL8 will reset the board, so keep it up.
337 sunxi_set_gpio_out('L', 5, 1);
338 sunxi_set_gpio_out('L', 9, 0);
339 sunxi_set_gpio_out('L', 10, 0);
341 /* Turn off pin controller now. */
342 mmio_write_32(SUNXI_CCU_BASE
+ 0x68, 0);
346 /* (Re-)init RSB in case the rich OS has disabled it. */
347 sunxi_init_platform_r_twi(SUNXI_SOC_A64
, true);
350 /* Set "power disable control" bit */
351 axp_setbits(0x32, BIT(7));
358 ERROR("PSCI: Cannot turn off system, halting.\n");