[coreboot-gerrit] New patch to review for coreboot: rockchip/rk3399: Add pwm_regulator.c for pwm then ramp boot up cpu

Martin Roth (martinroth@google.com) gerrit at coreboot.org
Tue Aug 30 18:25:54 CEST 2016


Martin Roth (martinroth at google.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/16368

-gerrit

commit c3883d9706820bf1cceb60a7cf392b3f45a65017
Author: Eric Gao <eric.gao at rock-chips.com>
Date:   Fri Jul 29 12:34:32 2016 +0800

    rockchip/rk3399: Add pwm_regulator.c for pwm then ramp boot up cpu
    
    Before, we calculate the pwm duties for cpu cores and centerlogic by
    hand, adding pwm_regulator.c to handle this. The default pwm design
    min/max voltage may be different between revs.
    
    With the pwm regulator, this patch changes the little cpu frequency from
    600M to 1512M, and raises CPU voltage to 1.2V correspondingly.
    
    This also means we decide to drop the ES1 because it may fail to
    bootup with 1.5G ~ 1.2v.
    
    BRANCH=none
    BUG=chrome-os-partner:54376,chrome-os-partner:54862
    TEST=Bootup on kevin board
    
    Change-Id: Id04c176bddfb9cdf3d25b65736e40249a85f6aa1
    Signed-off-by: Martin Roth <martinroth at chromium.org>
    Original-Commit-Id: ee4365c787ec523b7ee1028ea100dcfbb331b3a9
    Original-Change-Id: Ide75bbd92d1cbb14f934baeec0e38862bc08402b
    Original-Signed-off-by: Eric Gao <eric.gao at rock-chips.com>
    Original-Signed-off-by: Shunqian Zheng <zhengsq at rock-chips.com>
    Original-Reviewed-on: https://chromium-review.googlesource.com/364410
    Original-Reviewed-by: Julius Werner <jwerner at chromium.org>
---
 src/mainboard/google/gru/Makefile.inc       |  3 ++
 src/mainboard/google/gru/bootblock.c        | 17 +++++-
 src/mainboard/google/gru/pwm_regulator.c    | 82 +++++++++++++++++++++++++++++
 src/mainboard/google/gru/pwm_regulator.h    | 28 ++++++++++
 src/mainboard/google/gru/romstage.c         | 72 ++-----------------------
 src/soc/rockchip/rk3399/Makefile.inc        |  2 +
 src/soc/rockchip/rk3399/bootblock.c         |  1 -
 src/soc/rockchip/rk3399/clock.c             |  6 +--
 src/soc/rockchip/rk3399/include/soc/clock.h |  2 +-
 9 files changed, 140 insertions(+), 73 deletions(-)

diff --git a/src/mainboard/google/gru/Makefile.inc b/src/mainboard/google/gru/Makefile.inc
index e1ba56a..9e07a6c 100644
--- a/src/mainboard/google/gru/Makefile.inc
+++ b/src/mainboard/google/gru/Makefile.inc
@@ -18,6 +18,8 @@ subdirs-y += sdram_params/
 bootblock-y += bootblock.c
 bootblock-y += chromeos.c
 bootblock-y += memlayout.ld
+bootblock-y += pwm_regulator.c
+bootblock-y += boardid.c
 
 verstage-y += chromeos.c
 verstage-y += memlayout.ld
@@ -26,6 +28,7 @@ verstage-y += reset.c
 romstage-y += boardid.c
 romstage-y += chromeos.c
 romstage-y += memlayout.ld
+romstage-y += pwm_regulator.c
 romstage-y += romstage.c
 romstage-y += sdram_configs.c
 
diff --git a/src/mainboard/google/gru/bootblock.c b/src/mainboard/google/gru/bootblock.c
index e80f4a3..ff91e1a 100644
--- a/src/mainboard/google/gru/bootblock.c
+++ b/src/mainboard/google/gru/bootblock.c
@@ -16,13 +16,17 @@
 
 #include <arch/io.h>
 #include <bootblock_common.h>
+#include <console/console.h>
+#include <delay.h>
 #include <soc/grf.h>
 #include <gpio.h>
+#include <soc/clock.h>
 #include <soc/i2c.h>
+#include <soc/pwm.h>
 #include <soc/spi.h>
-#include <console/console.h>
 
 #include "board.h"
+#include "pwm_regulator.h"
 
 void bootblock_mainboard_early_init(void)
 {
@@ -58,8 +62,19 @@ void bootblock_mainboard_early_init(void)
 #endif
 }
 
+static void speed_up_boot_cpu(void)
+{
+	pwm_regulator_configure(PWM_REGULATOR_LIT, 1200);
+
+	udelay(200);
+
+	rkclk_configure_cpu(APLL_1512_MHZ, false);
+}
+
 void bootblock_mainboard_init(void)
 {
+	speed_up_boot_cpu();
+
 	/* Set pinmux and configure spi flashrom. */
 	write32(&rk3399_pmugrf->spi1_rxd, IOMUX_SPI1_RX);
 	write32(&rk3399_pmugrf->spi1_csclktx, IOMUX_SPI1_CSCLKTX);
diff --git a/src/mainboard/google/gru/pwm_regulator.c b/src/mainboard/google/gru/pwm_regulator.c
new file mode 100644
index 0000000..f382b2b
--- /dev/null
+++ b/src/mainboard/google/gru/pwm_regulator.c
@@ -0,0 +1,82 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2016 Rockchip Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <arch/io.h>
+#include <assert.h>
+#include <boardid.h>
+#include <console/console.h>
+#include <soc/grf.h>
+#include <soc/pwm.h>
+
+#include "pwm_regulator.h"
+
+/*
+ * Apparently a period of 3333 is determined by EEs to be ideal for our
+ * board design / resistors / capacitors / regulators but due to
+ * clock dividers we actually get 3337.
+ */
+#define PWM_PERIOD		3337
+#define PWM_DESIGN_VOLTAGE_MIN	8000
+#define PWM_DESIGN_VOLTAGE_MAX	15000
+
+/* The min & max design voltages are different after kevin-r6 */
+int kevin_voltage_min_max_r6[][2] = {
+	[PWM_REGULATOR_GPU] = {7910, 12139},
+	[PWM_REGULATOR_BIG] = {7986, 13057},
+	[PWM_REGULATOR_LIT] = {7997, 13002},
+	[PWM_REGULATOR_CENTERLOG] = {7996, 10507}
+};
+
+void pwm_regulator_configure(enum pwm_regulator pwm, int millivolt)
+{
+	int duty_ns, voltage_max, voltage_min;
+	int voltage = millivolt * 10; /* for higer calculation accuracy */
+
+	switch (pwm) {
+	case PWM_REGULATOR_GPU:
+		write32(&rk3399_grf->iomux_pwm_0, IOMUX_PWM_0);
+		break;
+	case PWM_REGULATOR_BIG:
+		write32(&rk3399_grf->iomux_pwm_1, IOMUX_PWM_1);
+		break;
+	case PWM_REGULATOR_LIT:
+		write32(&rk3399_pmugrf->iomux_pwm_2, IOMUX_PWM_2);
+		break;
+	case PWM_REGULATOR_CENTERLOG:
+		write32(&rk3399_pmugrf->iomux_pwm_3a, IOMUX_PWM_3_A);
+		break;
+	}
+
+	voltage_min = PWM_DESIGN_VOLTAGE_MIN;
+	voltage_max = PWM_DESIGN_VOLTAGE_MAX;
+	if (IS_ENABLED(CONFIG_BOARD_GOOGLE_KEVIN) && board_id() >= 6) {
+		voltage_min = kevin_voltage_min_max_r6[pwm][0];
+		voltage_max = kevin_voltage_min_max_r6[pwm][1];
+	}
+
+	assert(voltage <= voltage_max && voltage >= voltage_min);
+
+	/*
+	 * Intentionally round down (higher volt) to be safe.
+	 * eg, for the default min & max design voltage:
+	 *    period = 3337, volt = 1.1: 1906
+	 *    period = 3337, volt = 1.0: 2383
+	 *    period = 3337, volt = 0.9: 2860
+	 */
+	duty_ns = PWM_PERIOD * (voltage_max - voltage)
+			     / (voltage_max - voltage_min);
+
+	pwm_init(pwm, PWM_PERIOD, duty_ns);
+}
diff --git a/src/mainboard/google/gru/pwm_regulator.h b/src/mainboard/google/gru/pwm_regulator.h
new file mode 100644
index 0000000..6ef0c59
--- /dev/null
+++ b/src/mainboard/google/gru/pwm_regulator.h
@@ -0,0 +1,28 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2016 Rockchip Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __COREBOOT_SRC_MAINBOARD_GOOGLE_GRU_PWM_REGULATOR_H
+#define __COREBOOT_SRC_MAINBOARD_GOOGLE_GRU_PWM_REGULATOR_H
+
+enum pwm_regulator {
+	PWM_REGULATOR_GPU = 0,
+	PWM_REGULATOR_BIG,
+	PWM_REGULATOR_LIT,
+	PWM_REGULATOR_CENTERLOG
+};
+
+void pwm_regulator_configure(enum pwm_regulator pwm, int millivolt);
+
+#endif /* ! __COREBOOT_SRC_MAINBOARD_GOOGLE_GRU_PWM_REGULATOR_H */
diff --git a/src/mainboard/google/gru/romstage.c b/src/mainboard/google/gru/romstage.c
index ccf42b9..1e2507a 100644
--- a/src/mainboard/google/gru/romstage.c
+++ b/src/mainboard/google/gru/romstage.c
@@ -17,90 +17,28 @@
 #include <arch/cache.h>
 #include <arch/cpu.h>
 #include <arch/exception.h>
-#include <arch/io.h>
 #include <arch/mmu.h>
-#include <boardid.h>
 #include <cbfs.h>
 #include <console/console.h>
-#include <delay.h>
 #include <program_loading.h>
 #include <romstage_handoff.h>
 #include <soc/addressmap.h>
-#include <soc/grf.h>
 #include <soc/mmu_operations.h>
-#include <soc/pwm.h>
 #include <soc/tsadc.h>
 #include <soc/sdram.h>
 #include <symbols.h>
 #include <soc/usb.h>
 
+#include "pwm_regulator.h"
+
 static const uint64_t dram_size =
 	(uint64_t)min((uint64_t)CONFIG_DRAM_SIZE_MB * MiB, MAX_DRAM_ADDRESS);
 
 static void init_dvs_outputs(void)
 {
-	int duty_ns;
-	uint32_t i;
-	uint32_t id;
-
-	write32(&rk3399_grf->iomux_pwm_0, IOMUX_PWM_0);		/* GPU */
-	write32(&rk3399_grf->iomux_pwm_1, IOMUX_PWM_1);		/* Big */
-	write32(&rk3399_pmugrf->iomux_pwm_2, IOMUX_PWM_2);	/* Little */
-	write32(&rk3399_pmugrf->iomux_pwm_3a, IOMUX_PWM_3_A);	/* Centerlog */
-
-	/*
-	 * Set up voltages for all DVS rails.
-	 *
-	 * LITTLE CPU: At the speed we're running at right now and on the
-	 * early silicon, .9V is sane.  If/when we run faster, let's bump this.
-	 *
-	 * CENTER LOGIC: There are some claims that this should simply always
-	 * be .9 V.  There are other claims that say that we need to adjust this
-	 * dynamically depending on the memory frequency.  Until this is sorted
-	 * out, it appears that .9 V works for the 800 MHz.
-	 *
-	 * BIG CPU / GPU: These aren't used in coreboot.  Init to .9V which is
-	 * supposed to be a good default.
-	 *
-	 * Details:
-	 *   design_min = 0.8
-	 *   design_max = 1.5
-	 *   period = 3337     # 300 kHz
-	 *   volt = 1.1
-	 *   # Intentionally round down (higher volt) to be safe.
-	 *   int((period / (design_max - design_min)) * (design_max - volt))
-	 *
-	 * Apparently a period of 3333 is determined by EEs to be ideal for our
-	 * board design / resistors / capacitors / regulators but due to
-	 * clock dividers we actually get 3337.  Solving, we get:
-	 *   period = 3337, volt = 1.1: 1906
-	 *   period = 3337, volt = 1.0: 2383
-	 *   period = 3337, volt = 0.9: 2860
-	 */
-	duty_ns = 2860; /* 0.9v */
-
-	/* TODO: Clean all this up, implement proper pwm_regulator driver. */
-	if (IS_ENABLED(CONFIG_BOARD_GOOGLE_KEVIN)) {
-		id = board_id();
-		if (id <= 2)
-			duty_ns = 1906; /* 1.1v */
-		else if (id == 3)
-			duty_ns = 2621; /* 0.95v */
-		else if (id >= 6) {
-			/* GPU: 3337 * (12043 - 9000) / (12043 - 7984) = 2501 */
-			pwm_init(0, 3337, 2501);
-			/* BIG: 3337 * (12837 - 9000) / (12837 - 7985) = 2638 */
-			pwm_init(1, 3337, 2638);
-			/* LIT: 3337 * (12807 - 9000) / (12807 - 8009) = 2647 */
-			pwm_init(2, 3337, 2647);
-			/* CTR: 3337 * (10507 - 9500) / (10507 - 7996) = 1338 */
-			pwm_init(3, 3337, 1338);
-			return;
-		}
-	}
-
-	for (i = 0; i < 4; i++)
-		pwm_init(i, 3337, duty_ns);
+	pwm_regulator_configure(PWM_REGULATOR_GPU, 900);
+	pwm_regulator_configure(PWM_REGULATOR_BIG, 900);
+	pwm_regulator_configure(PWM_REGULATOR_CENTERLOG, 950);
 }
 
 static void prepare_usb(void)
diff --git a/src/soc/rockchip/rk3399/Makefile.inc b/src/soc/rockchip/rk3399/Makefile.inc
index 6e75278..ceec7bc 100644
--- a/src/soc/rockchip/rk3399/Makefile.inc
+++ b/src/soc/rockchip/rk3399/Makefile.inc
@@ -23,10 +23,12 @@ ifeq ($(CONFIG_BOOTBLOCK_CONSOLE),y)
 bootblock-$(CONFIG_DRIVERS_UART) += ../common/uart.c
 endif
 bootblock-y += ../common/gpio.c
+bootblock-y += ../common/pwm.c
 bootblock-y += bootblock.c
 bootblock-y += clock.c
 bootblock-y += gpio.c
 bootblock-y += mmu_operations.c
+bootblock-y += saradc.c
 bootblock-y += timer.c
 
 verstage-y += ../common/cbmem.c
diff --git a/src/soc/rockchip/rk3399/bootblock.c b/src/soc/rockchip/rk3399/bootblock.c
index 4f85e94..7b80a75 100644
--- a/src/soc/rockchip/rk3399/bootblock.c
+++ b/src/soc/rockchip/rk3399/bootblock.c
@@ -22,7 +22,6 @@
 void bootblock_soc_init(void)
 {
 	rkclk_init();
-	rkclk_configure_cpu(APLL_600_MHZ, false);
 
 	/* all ddr range non-secure */
 	write32(&rk3399_pmusgrf->ddr_rgn_con[16], 0xff << 16 | 0);
diff --git a/src/soc/rockchip/rk3399/clock.c b/src/soc/rockchip/rk3399/clock.c
index ed9afda..428a210 100644
--- a/src/soc/rockchip/rk3399/clock.c
+++ b/src/soc/rockchip/rk3399/clock.c
@@ -47,11 +47,11 @@ static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 2, 2, 1);
 static const struct pll_div cpll_init_cfg = PLL_DIVISORS(CPLL_HZ, 1, 2, 2);
 static const struct pll_div ppll_init_cfg = PLL_DIVISORS(PPLL_HZ, 2, 2, 1);
 
-static const struct pll_div apll_1600_cfg = PLL_DIVISORS(1600*MHz, 3, 1, 1);
-static const struct pll_div apll_600_cfg = PLL_DIVISORS(600*MHz, 1, 2, 1);
+static const struct pll_div apll_1512_cfg = PLL_DIVISORS(1512*MHz, 1, 1, 1);
+static const struct pll_div apll_600_cfg = PLL_DIVISORS(600*MHz, 1, 3, 1);
 
 static const struct pll_div *apll_cfgs[] = {
-	[APLL_1600_MHZ] = &apll_1600_cfg,
+	[APLL_1512_MHZ] = &apll_1512_cfg,
 	[APLL_600_MHZ] = &apll_600_cfg,
 };
 
diff --git a/src/soc/rockchip/rk3399/include/soc/clock.h b/src/soc/rockchip/rk3399/include/soc/clock.h
index 19e315b..de86ed4 100644
--- a/src/soc/rockchip/rk3399/include/soc/clock.h
+++ b/src/soc/rockchip/rk3399/include/soc/clock.h
@@ -97,7 +97,7 @@ static struct rk3399_cru_reg * const cru_ptr = (void *)CRU_BASE;
 #define PWM_CLOCK_HZ    PMU_PCLK_HZ
 
 enum apll_frequencies {
-	APLL_1600_MHZ,
+	APLL_1512_MHZ,
 	APLL_600_MHZ,
 };
 



More information about the coreboot-gerrit mailing list