1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * (C) Copyright 2015 Google, Inc
4 */
5
6#include <clk.h>
7#include <common.h>
8#include <dm.h>
9#include <init.h>
10#include <log.h>
11#include <asm/arch-rockchip/clock.h>
12#include <asm/global_data.h>
13#include <dt-bindings/clock/rk3288-cru.h>
14#include <linux/delay.h>
15#include <linux/err.h>
16#include <power/regulator.h>
17
18/*
19 * We should increase the DDR voltage to 1.2V using the PWM regulator.
20 * There is a U-Boot driver for this but it may need to add support for the
21 * 'voltage-table' property.
22 */
23#ifndef CONFIG_SPL_BUILD
24#if !CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM)
25static int veyron_init(void)
26{
27	struct udevice *dev;
28	struct clk clk;
29	int ret;
30
31	ret = regulator_get_by_platname("vdd_arm", &dev);
32	if (ret) {
33		debug("Cannot set regulator name\n");
34		return ret;
35	}
36
37	/* Slowly raise to max CPU voltage to prevent overshoot */
38	ret = regulator_set_value(dev, 1200000);
39	if (ret)
40		return ret;
41	udelay(175); /* Must wait for voltage to stabilize, 2mV/us */
42	ret = regulator_set_value(dev, 1400000);
43	if (ret)
44		return ret;
45	udelay(100); /* Must wait for voltage to stabilize, 2mV/us */
46
47	ret = rockchip_get_clk(&clk.dev);
48	if (ret)
49		return ret;
50	clk.id = PLL_APLL;
51	ret = clk_set_rate(&clk, 1800000000);
52	if (IS_ERR_VALUE(ret))
53		return ret;
54
55	ret = regulator_get_by_platname("vcc33_sd", &dev);
56	if (ret) {
57		debug("Cannot get regulator name\n");
58		return ret;
59	}
60
61	ret = regulator_set_value(dev, 3300000);
62	if (ret)
63		return ret;
64
65	ret = regulators_enable_boot_on(false);
66	if (ret) {
67		debug("%s: Cannot enable boot on regulators\n", __func__);
68		return ret;
69	}
70
71	return 0;
72}
73#endif
74
75int board_early_init_r(void)
76{
77	struct udevice *dev;
78	int ret;
79
80#if !CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM)
81	if (!fdt_node_check_compatible(gd->fdt_blob, 0, "google,veyron")) {
82		ret = veyron_init();
83		if (ret)
84			return ret;
85	}
86#endif
87	/*
88	 * This init is done in SPL, but when chain-loading U-Boot SPL will
89	 * have been skipped. Allow the clock driver to check if it needs
90	 * setting up.
91	 */
92	ret = rockchip_get_clk(&dev);
93	if (ret) {
94		debug("CLK init failed: %d\n", ret);
95		return ret;
96	}
97
98	return 0;
99}
100#endif
101