From 89117ef05c2d4accf05dc590c7d82f763e84f709 Mon Sep 17 00:00:00 2001
From: Timothy Pearson <tpearson@raptorengineeringinc.com>
Date: Mon, 18 Apr 2016 16:51:49 +0000
Subject: [PATCH 15/15] chromebook_speedy: Add 4GB Veyron Speedy Chromebook

Tested and working in secure mode.  Non-secure mode partially works
but is disabled by default due to the GIC being completely inaccessible
from the non-secure world.  If Rockchip cannot provide a method to access
the GIC from the non-secure world then the RK3288-based machines are
currently usesless for virtualization.

Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
---
 arch/arm/dts/Makefile                           |   1 +
 arch/arm/dts/rk3288-speedy-4g.dts               |  11 +-
 arch/arm/dts/rk3288-veyron-lpddr-elpida-4g.dtsi |  10 ++
 arch/arm/include/asm/arch-rockchip/gpio.h       |   3 +
 arch/arm/include/asm/arch-rockchip/tzpc.h       |  16 +--
 arch/arm/mach-rockchip/rk3288/Kconfig           |   9 ++
 board/google/chromebook_speedy/speedy.c         | 157 ++++++++++++++++++++++++
 7 files changed, 189 insertions(+), 18 deletions(-)

diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 578038b..6dde853 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -22,6 +22,7 @@ dtb-$(CONFIG_EXYNOS5) += exynos5250-arndale.dtb \
 dtb-$(CONFIG_ARCH_ROCKCHIP) += \
 	rk3288-firefly.dtb \
 	rk3288-jerry.dtb \
+	rk3288-speedy-4g.dtb \
 	rk3288-rock2-square.dtb \
 	rk3036-sdk.dtb
 dtb-$(CONFIG_TEGRA) += tegra20-harmony.dtb \
diff --git a/arch/arm/dts/rk3288-speedy-4g.dts b/arch/arm/dts/rk3288-speedy-4g.dts
index db71863..239cdc6 100644
--- a/arch/arm/dts/rk3288-speedy-4g.dts
+++ b/arch/arm/dts/rk3288-speedy-4g.dts
@@ -2,6 +2,7 @@
  * Google Veyron Speedy Rev 1+ board device tree source
  *
  * Copyright 2015 Google, Inc
+ * Copyright 2016 Raptor Engineering, LLC
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -10,7 +11,7 @@
 
 /dts-v1/;
 #include "rk3288-veyron-chromebook.dtsi"
-#include "rk3288-veyron-lpddr.dtsi"
+#include "rk3288-veyron-lpddr-elpida-4g.dtsi"
 #include "cros-ec-sbs.dtsi"
 
 / {
@@ -21,6 +22,10 @@
 		     "google,veyron-speedy-rev3", "google,veyron-speedy-rev2",
 		     "google,veyron-speedy", "google,veyron", "rockchip,rk3288";
 
+	chosen {
+		stdout-path = &uart2;
+	};
+
 	panel_regulator: panel-regulator {
 		compatible = "regulator-fixed";
 		enable-active-high;
@@ -77,10 +82,6 @@
 	disable-wp;
 };
 
-&thermal {
-	#include "rk3288-speedy-thermal.dtsi"
-};
-
 &vcc_5v {
 	enable-active-high;
 	gpio = <&gpio7 21 GPIO_ACTIVE_HIGH>;
diff --git a/arch/arm/dts/rk3288-veyron-lpddr-elpida-4g.dtsi b/arch/arm/dts/rk3288-veyron-lpddr-elpida-4g.dtsi
index be88077..c43cffb 100644
--- a/arch/arm/dts/rk3288-veyron-lpddr-elpida-4g.dtsi
+++ b/arch/arm/dts/rk3288-veyron-lpddr-elpida-4g.dtsi
@@ -2,6 +2,7 @@
  * Google Veyron (and derivatives) fragment for lpddr ddrfreq settings
  *
  * Copyright 2015 Google, Inc
+ * Copyright 2016 Raptor Engineering, LLC
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -12,6 +13,15 @@
 	status = "okay";
 	rockchip,odt-disable-freq = <666000000>;
 	rockchip,pd-enable-freq = <333000000>;
+	rockchip,sdram-channel = /bits/ 8 <0x2 0xb 0x3 0x2 0x2 0x0 0xe 0xe>;
+	rockchip,sdram-params = <0x20D266A4 0x5B6 6 533000000 6 13 0>;
+	rockchip,phy-timing = <0x48d7dd93 0x187008d8 0x121076
+		0x0 0xc3 0x6 0x1>;
+	rockchip,pctl-timing = <0x215 0xc8 0x0 0x35 0x26 0x2 0x70 0x2000d
+		0x6 0x0 0x8 0x4 0x17 0x24 0xd 0x6
+		0x4 0x8 0x4 0x76 0x4 0x0 0x30 0x0
+		0x1 0x2 0x2 0x4 0x0 0x0 0xc0 0x4
+		0x8 0x1f4>;
 	operating-points = <
 		/* KHz    uV */
 		200000 1050000
diff --git a/arch/arm/include/asm/arch-rockchip/gpio.h b/arch/arm/include/asm/arch-rockchip/gpio.h
index e39218d..52749fc 100644
--- a/arch/arm/include/asm/arch-rockchip/gpio.h
+++ b/arch/arm/include/asm/arch-rockchip/gpio.h
@@ -1,4 +1,5 @@
 /*
+ * (C) Copyright 2016 Raptor Engineering, LLC
  * (C) Copyright 2015 Google, Inc
  *
  * SPDX-License-Identifier:     GPL-2.0+
@@ -25,4 +26,6 @@ struct rockchip_gpio_regs {
 };
 check_member(rockchip_gpio_regs, ls_sync, 0x60);
 
+#define ROCKCHIP_GPIO_NR(bank, port, index)		(((bank)*32)+(((((port)-'A')*8)+index)&31))
+
 #endif
diff --git a/arch/arm/include/asm/arch-rockchip/tzpc.h b/arch/arm/include/asm/arch-rockchip/tzpc.h
index 0a4be23..3096446 100644
--- a/arch/arm/include/asm/arch-rockchip/tzpc.h
+++ b/arch/arm/include/asm/arch-rockchip/tzpc.h
@@ -8,7 +8,7 @@
 #define __TZPC_H_
 
 #ifndef __ASSEMBLY__
-struct exynos_tzpc {
+struct rockchip_tzpc {
 	unsigned int r0size;
 	char res1[0x7FC];
 	unsigned int decprot0stat;
@@ -34,24 +34,14 @@ struct exynos_tzpc {
 	unsigned int pcellid3;
 };
 
-#define EXYNOS4_NR_TZPC_BANKS		6
-#define EXYNOS5_NR_TZPC_BANKS		10
-
 /* TZPC : Register Offsets */
-#define TZPC_BASE_OFFSET		0x10000
+#define TZPC_BASE_OFFSET		0xffb00000
 
 /*
  * TZPC Register Value :
  * R0SIZE: 0x0 : Size of secured ram
  */
-#define R0SIZE			0x0
-
-/*
- * TZPC Decode Protection Register Value :
- * DECPROTXSET: 0xFF : Set Decode region to non-secure
- */
-#define DECPROTXSET		0xFF
-void tzpc_init(void);
+#define R0SIZE				0x0
 
 #endif
 
diff --git a/arch/arm/mach-rockchip/rk3288/Kconfig b/arch/arm/mach-rockchip/rk3288/Kconfig
index 7215624..c3045ae 100644
--- a/arch/arm/mach-rockchip/rk3288/Kconfig
+++ b/arch/arm/mach-rockchip/rk3288/Kconfig
@@ -16,6 +16,14 @@ config TARGET_CHROMEBOOK_JERRY
 	  WiFi. It includes a Chrome OS EC (Cortex-M3) to provide access to
 	  the keyboard and battery functions.
 
+config TARGET_CHROMEBOOK_SPEEDY
+	bool "Google/Rockchip Veyron-Speedy Chromebook"
+	help
+	  Speedy is a RK3288-based clamshell device with 2 USB 2.0 ports,
+	  HDMI, an 11.9 inch EDP display, micro-SD card, touchpad, speaker jack,
+	  and WiFi. It includes a Chrome OS EC (Cortex-M3) to provide access to
+	  the keyboard and battery functions.
+
 config TARGET_ROCK2
 	bool "Radxa Rock 2"
 	help
@@ -40,6 +48,7 @@ config SYS_MALLOC_F_LEN
 	default 0x0800
 
 source "board/google/chromebook_jerry/Kconfig"
+source "board/google/chromebook_speedy/Kconfig"
 
 source "board/firefly/firefly-rk3288/Kconfig"
 
diff --git a/board/google/chromebook_speedy/speedy.c b/board/google/chromebook_speedy/speedy.c
index 5119e95..46c987e 100644
--- a/board/google/chromebook_speedy/speedy.c
+++ b/board/google/chromebook_speedy/speedy.c
@@ -1,7 +1,164 @@
 /*
+ * (C) Copyright 2016 Raptor Engineering, LLC
  * (C) Copyright 2015 Google, Inc
  *
  * SPDX-License-Identifier:     GPL-2.0+
  */
 
 #include <common.h>
+#include <syscon.h>
+#include <asm/io.h>
+#include <asm-generic/gpio.h>
+#include <asm/arch/grf_rk3288.h>
+#include <asm/arch/pmu_rk3288.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/gpio.h>
+#include <asm/arch-rockchip/tzpc.h>
+#include <power/pmic.h>
+#include <power/regulator.h>
+
+static int control_usb_power(bool on)
+{
+	int ret;
+
+	debug("%s: turn on: %d\n", __func__, on);
+
+	ret = gpio_request(ROCKCHIP_GPIO_NR(0, 'B', 3), "host1_power_en");
+	if (ret) {
+		error("Unable to request HOST1 power enable GPIO.  Error: %d\n", ret);
+		return ret;
+	}
+	ret = gpio_request(ROCKCHIP_GPIO_NR(0, 'B', 4), "usb_otg_power_en");
+	if (ret) {
+		error("Unable to request USB OTG power enable GPIO.  Error: %d\n", ret);
+		return ret;
+	}
+	ret = gpio_request(ROCKCHIP_GPIO_NR(7, 'C', 5), "5v_drive_enable");
+	if (ret) {
+		error("Unable to request 5V drive enable GPIO.  Error: %d\n", ret);
+		return ret;
+	}
+
+	gpio_direction_output(ROCKCHIP_GPIO_NR(0, 'B', 3), on);	/* HOST1 power enable */
+	gpio_direction_output(ROCKCHIP_GPIO_NR(0, 'B', 4), on);	/* USB OTG power enable */
+	gpio_direction_output(ROCKCHIP_GPIO_NR(7, 'C', 5), on);	/* 5V drive enable */
+
+	return 0;
+}
+
+static int control_sdcard_power(bool on)
+{
+	struct udevice *vccio_dev;
+	struct udevice *vcc33_dev;
+	int ret;
+
+	debug("%s: turn on: %d\n", __func__, on);
+
+	ret = regulator_get_by_platname("vccio_sd", &vccio_dev);
+	if (ret) {
+		error("Unable to locate IO Vcc regulator.  Error: %d\n", ret);
+		return ret;
+	}
+	ret = regulator_get_by_platname("vcc33_sd", &vcc33_dev);
+	if (ret) {
+		error("Unable to locate main Vcc regulator.  Error: %d\n", ret);
+		return ret;
+	}
+
+	if (on) {
+		ret = regulator_set_enable(vccio_dev, true);
+		if (!ret)
+			ret = regulator_set_value(vccio_dev, 3300000);
+		if (!ret)
+			ret = regulator_set_enable(vcc33_dev, true);
+		if (!ret)
+			ret = regulator_set_value(vcc33_dev, 3300000);
+		if (ret)
+			error("Unable to configure regulator(s)!  Error: %d\n", ret);
+	} else {
+		ret = regulator_set_enable(vccio_dev, false);
+		if (!ret)
+			ret = regulator_set_enable(vcc33_dev, false);
+		if (ret)
+			error("Unable to deactivate regulator(s)!  Error: %d\n", ret);
+	}
+
+	debug("%s: current IO Vcc status: %d %d\n", __func__, regulator_get_value(vccio_dev), regulator_get_enable(vccio_dev));
+	debug("%s: current main Vcc status: %d %d\n", __func__, regulator_get_value(vcc33_dev), regulator_get_enable(vcc33_dev));
+
+	return ret;
+}
+
+static int board_sdcard_init(void)
+{
+	int ret;
+
+	/* Enable main USB power rails (SD power is derived from USB power) */
+	ret = control_usb_power(true);
+	if (ret) {
+		debug("%s: board_sdcard_init() failed with error code %d\n", __func__, ret);
+		return ret;
+	}
+
+	/* Enable SD card slot power */
+	return control_sdcard_power(true);
+}
+
+int power_init_board(void)
+{
+	int ret;
+
+	ret = board_sdcard_init();
+	if (ret)
+		debug("%s: board_sdcard_init() failed with error code %d\n", __func__, ret);
+
+	return ret;
+}
+
+#ifdef CONFIG_ARMV7_NONSEC
+void armv7_nonsec_tzpc_init(void)
+{
+	struct rockchip_tzpc *tzpc;
+	tzpc = (struct rockchip_tzpc *)TZPC_BASE_OFFSET;
+
+	debug("%s: Using TZPC base address of %08x to initialize non-secure peripheral access\n", __func__, TZPC_BASE_OFFSET);
+
+	writel(R0SIZE, &tzpc->r0size);
+
+	writel(0xff, &tzpc->decprot0set);
+	writel(0xff, &tzpc->decprot1set);
+	writel(0xff, &tzpc->decprot2set);
+
+	debug("%s: PERIPHID0/PCELLID0: %08x/%08x (TZPCDECPROT0STAT: %08x)\n", __func__, readl(&tzpc->periphid0), readl(&tzpc->pcellid0), readl(&tzpc->decprot0stat));
+	debug("%s: PERIPHID1/PCELLID1: %08x/%08x (TZPCDECPROT1STAT: %08x)\n", __func__, readl(&tzpc->periphid1), readl(&tzpc->pcellid1), readl(&tzpc->decprot1stat));
+	debug("%s: PERIPHID2/PCELLID2: %08x/%08x (TZPCDECPROT2STAT: %08x)\n", __func__, readl(&tzpc->periphid2), readl(&tzpc->pcellid2), readl(&tzpc->decprot2stat));
+	debug("%s: PERIPHID3/PCELLID3: %08x/%08x\n", __func__, readl(&tzpc->periphid3), readl(&tzpc->pcellid3));
+}
+
+void smp_set_core_boot_addr(unsigned long addr, int corenr)
+{
+	uint32_t val;
+	struct rk3288_pmu *pmu;
+	phys_addr_t regs = 0xff700000;
+
+	debug("%s: Using SMP base RAM address of %08x to configure CPU %d start vector %08x\n", __func__, (unsigned int)regs, corenr, (unsigned int)addr);
+
+	/* Turn on core power */
+	pmu = syscon_get_first_range(ROCKCHIP_SYSCON_PMU);
+
+	debug("%s: Enabling core power via PMU at %08x\n", __func__, (unsigned int)&pmu->pwrdn_con);
+
+	val = readl(&pmu->pwrdn_con);
+	val &= ~0xe;	/* Enable all three secondary cores */
+	writel(val, &pmu->pwrdn_con);
+
+	/* Write SMP start address */
+	writel(addr, regs + 8);
+	writel(0xdeadbeaf, regs + 4);
+
+	/* make sure this write is really executed */
+	__asm__ volatile ("dsb\n");
+
+	debug("%s: Done\n", __func__);
+}
+#endif
-- 
1.9.1

