Merge git://git.denx.de/u-boot-rockchip

This includes support for rk3188 from Heiko Stübner and and rk3328 from
Kever Yang.  Also included is SPL support for rk3399 and a fix for
rk3288 to get it booting again (spl_early_init()).
This commit is contained in:
Tom Rini 2017-03-17 09:11:12 -04:00
commit f9515756b6
106 changed files with 12558 additions and 243 deletions

View file

@ -38,6 +38,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += \
rk3288-fennec.dtb \
rk3288-tinker.dtb \
rk3288-popmetal.dtb \
rk3328-evb.dtb \
rk3399-evb.dtb
dtb-$(CONFIG_ARCH_MESON) += \
meson-gxbb-odroidc2.dtb

View file

@ -51,10 +51,12 @@
};
&usb_host {
vbus-supply = <&vcc5v0_host>;
status = "okay";
};
&usb_otg {
vbus-supply = <&vcc5v0_otg>;
status = "okay";
};

View file

@ -23,6 +23,7 @@
serial1 = &uart1;
serial2 = &uart2;
mmc0 = &emmc;
mmc1 = &sdmmc;
};
memory {
@ -265,6 +266,18 @@
pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>;
};
sdmmc: dwmmc@10214000 {
compatible = "rockchip,rk3036-dw-mshc", "rockchip,rk3288-dw-mshc";
reg = <0x10214000 0x4000>;
clock-frequency = <37500000>;
max-frequency = <37500000>;
clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>;
clock-names = "biu", "ciu";
fifo-depth = <0x100>;
interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
pinctrl: pinctrl {
compatible = "rockchip,rk3036-pinctrl";
rockchip,grf = <&grf>;

601
arch/arm/dts/rk3188.dtsi Normal file
View file

@ -0,0 +1,601 @@
/*
* Copyright (c) 2013 MundoReader S.L.
* Author: Heiko Stuebner <heiko@sntech.de>
*
* SPDX-License-Identifier: GPL-2.0+ or X11
*/
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/pinctrl/rockchip.h>
#include <dt-bindings/clock/rk3188-cru.h>
#include "rk3xxx.dtsi"
/ {
compatible = "rockchip,rk3188";
cpus {
#address-cells = <1>;
#size-cells = <0>;
enable-method = "rockchip,rk3066-smp";
cpu0: cpu@0 {
device_type = "cpu";
compatible = "arm,cortex-a9";
next-level-cache = <&L2>;
reg = <0x0>;
operating-points = <
/* kHz uV */
1608000 1350000
1416000 1250000
1200000 1150000
1008000 1075000
816000 975000
600000 950000
504000 925000
312000 875000
>;
clock-latency = <40000>;
clocks = <&cru ARMCLK>;
};
cpu@1 {
device_type = "cpu";
compatible = "arm,cortex-a9";
next-level-cache = <&L2>;
reg = <0x1>;
};
cpu@2 {
device_type = "cpu";
compatible = "arm,cortex-a9";
next-level-cache = <&L2>;
reg = <0x2>;
};
cpu@3 {
device_type = "cpu";
compatible = "arm,cortex-a9";
next-level-cache = <&L2>;
reg = <0x3>;
};
};
sram: sram@10080000 {
compatible = "mmio-sram";
reg = <0x10080000 0x8000>;
#address-cells = <1>;
#size-cells = <1>;
ranges = <0 0x10080000 0x8000>;
smp-sram@0 {
compatible = "rockchip,rk3066-smp-sram";
reg = <0x0 0x50>;
};
};
i2s0: i2s@1011a000 {
compatible = "rockchip,rk3188-i2s", "rockchip,rk3066-i2s";
reg = <0x1011a000 0x2000>;
interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
pinctrl-names = "default";
pinctrl-0 = <&i2s0_bus>;
dmas = <&dmac1_s 6>, <&dmac1_s 7>;
dma-names = "tx", "rx";
clock-names = "i2s_hclk", "i2s_clk";
clocks = <&cru HCLK_I2S0>, <&cru SCLK_I2S0>;
rockchip,playback-channels = <2>;
rockchip,capture-channels = <2>;
status = "disabled";
};
spdif: sound@1011e000 {
compatible = "rockchip,rk3188-spdif", "rockchip,rk3066-spdif";
reg = <0x1011e000 0x2000>;
#sound-dai-cells = <0>;
clock-names = "hclk", "mclk";
clocks = <&cru HCLK_SPDIF>, <&cru SCLK_SPDIF>;
dmas = <&dmac1_s 8>;
dma-names = "tx";
interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&spdif_tx>;
status = "disabled";
};
cru: clock-controller@20000000 {
compatible = "rockchip,rk3188-cru";
reg = <0x20000000 0x1000>;
rockchip,grf = <&grf>;
u-boot,dm-spl;
#clock-cells = <1>;
#reset-cells = <1>;
};
efuse: efuse@20010000 {
compatible = "rockchip,rockchip-efuse";
reg = <0x20010000 0x4000>;
#address-cells = <1>;
#size-cells = <1>;
clocks = <&cru PCLK_EFUSE>;
clock-names = "pclk_efuse";
cpu_leakage: cpu_leakage@17 {
reg = <0x17 0x1>;
};
};
usbphy: phy {
compatible = "rockchip,rk3188-usb-phy", "rockchip,rk3288-usb-phy";
rockchip,grf = <&grf>;
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
usbphy0: usb-phy@10c {
#phy-cells = <0>;
reg = <0x10c>;
clocks = <&cru SCLK_OTGPHY0>;
clock-names = "phyclk";
#clock-cells = <0>;
};
usbphy1: usb-phy@11c {
#phy-cells = <0>;
reg = <0x11c>;
clocks = <&cru SCLK_OTGPHY1>;
clock-names = "phyclk";
#clock-cells = <0>;
};
};
pinctrl: pinctrl {
compatible = "rockchip,rk3188-pinctrl";
rockchip,grf = <&grf>;
rockchip,pmu = <&pmu>;
#address-cells = <1>;
#size-cells = <1>;
ranges;
u-boot,dm-spl;
gpio0: gpio0@2000a000 {
compatible = "rockchip,gpio-bank";
reg = <0x2000a000 0x100>;
interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru PCLK_GPIO0>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
};
gpio1: gpio1@2003c000 {
compatible = "rockchip,gpio-bank";
reg = <0x2003c000 0x100>;
interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru PCLK_GPIO1>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
};
gpio2: gpio2@2003e000 {
compatible = "rockchip,gpio-bank";
reg = <0x2003e000 0x100>;
interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru PCLK_GPIO2>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
};
gpio3: gpio3@20080000 {
compatible = "rockchip,gpio-bank";
reg = <0x20080000 0x100>;
interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru PCLK_GPIO3>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
};
pcfg_pull_up: pcfg_pull_up {
bias-pull-up;
};
pcfg_pull_down: pcfg_pull_down {
bias-pull-down;
};
pcfg_pull_none: pcfg_pull_none {
bias-disable;
};
emmc {
emmc_clk: emmc-clk {
rockchip,pins = <RK_GPIO0 24 RK_FUNC_2 &pcfg_pull_none>;
};
emmc_cmd: emmc-cmd {
rockchip,pins = <RK_GPIO0 26 RK_FUNC_2 &pcfg_pull_up>;
};
emmc_rst: emmc-rst {
rockchip,pins = <RK_GPIO0 27 RK_FUNC_2 &pcfg_pull_none>;
};
/*
* The data pins are shared between nandc and emmc and
* not accessible through pinctrl. Also they should've
* been already set correctly by firmware, as
* flash/emmc is the boot-device.
*/
};
emac {
emac_xfer: emac-xfer {
rockchip,pins = <RK_GPIO3 16 RK_FUNC_2 &pcfg_pull_none>, /* tx_en */
<RK_GPIO3 17 RK_FUNC_2 &pcfg_pull_none>, /* txd1 */
<RK_GPIO3 18 RK_FUNC_2 &pcfg_pull_none>, /* txd0 */
<RK_GPIO3 19 RK_FUNC_2 &pcfg_pull_none>, /* rxd0 */
<RK_GPIO3 20 RK_FUNC_2 &pcfg_pull_none>, /* rxd1 */
<RK_GPIO3 21 RK_FUNC_2 &pcfg_pull_none>, /* mac_clk */
<RK_GPIO3 22 RK_FUNC_2 &pcfg_pull_none>, /* rx_err */
<RK_GPIO3 23 RK_FUNC_2 &pcfg_pull_none>; /* crs_dvalid */
};
emac_mdio: emac-mdio {
rockchip,pins = <RK_GPIO3 24 RK_FUNC_2 &pcfg_pull_none>,
<RK_GPIO3 25 RK_FUNC_2 &pcfg_pull_none>;
};
};
i2c0 {
i2c0_xfer: i2c0-xfer {
rockchip,pins = <RK_GPIO1 24 RK_FUNC_1 &pcfg_pull_none>,
<RK_GPIO1 25 RK_FUNC_1 &pcfg_pull_none>;
};
};
i2c1 {
i2c1_xfer: i2c1-xfer {
rockchip,pins = <RK_GPIO1 26 RK_FUNC_1 &pcfg_pull_none>,
<RK_GPIO1 27 RK_FUNC_1 &pcfg_pull_none>;
};
};
i2c2 {
i2c2_xfer: i2c2-xfer {
rockchip,pins = <RK_GPIO1 28 RK_FUNC_1 &pcfg_pull_none>,
<RK_GPIO1 29 RK_FUNC_1 &pcfg_pull_none>;
};
};
i2c3 {
i2c3_xfer: i2c3-xfer {
rockchip,pins = <RK_GPIO3 14 RK_FUNC_2 &pcfg_pull_none>,
<RK_GPIO3 15 RK_FUNC_2 &pcfg_pull_none>;
};
};
i2c4 {
i2c4_xfer: i2c4-xfer {
rockchip,pins = <RK_GPIO1 30 RK_FUNC_1 &pcfg_pull_none>,
<RK_GPIO1 31 RK_FUNC_1 &pcfg_pull_none>;
};
};
pwm0 {
pwm0_out: pwm0-out {
rockchip,pins = <RK_GPIO3 27 RK_FUNC_1 &pcfg_pull_none>;
};
};
pwm1 {
pwm1_out: pwm1-out {
rockchip,pins = <RK_GPIO3 28 RK_FUNC_1 &pcfg_pull_none>;
};
};
pwm2 {
pwm2_out: pwm2-out {
rockchip,pins = <RK_GPIO3 29 RK_FUNC_1 &pcfg_pull_none>;
};
};
pwm3 {
pwm3_out: pwm3-out {
rockchip,pins = <RK_GPIO3 30 RK_FUNC_1 &pcfg_pull_none>;
};
};
spi0 {
spi0_clk: spi0-clk {
rockchip,pins = <RK_GPIO1 6 RK_FUNC_2 &pcfg_pull_up>;
};
spi0_cs0: spi0-cs0 {
rockchip,pins = <RK_GPIO1 7 RK_FUNC_2 &pcfg_pull_up>;
};
spi0_tx: spi0-tx {
rockchip,pins = <RK_GPIO1 5 RK_FUNC_2 &pcfg_pull_up>;
};
spi0_rx: spi0-rx {
rockchip,pins = <RK_GPIO1 4 RK_FUNC_2 &pcfg_pull_up>;
};
spi0_cs1: spi0-cs1 {
rockchip,pins = <RK_GPIO1 15 RK_FUNC_1 &pcfg_pull_up>;
};
};
spi1 {
spi1_clk: spi1-clk {
rockchip,pins = <RK_GPIO0 30 RK_FUNC_1 &pcfg_pull_up>;
};
spi1_cs0: spi1-cs0 {
rockchip,pins = <RK_GPIO0 31 RK_FUNC_1 &pcfg_pull_up>;
};
spi1_rx: spi1-rx {
rockchip,pins = <RK_GPIO0 28 RK_FUNC_1 &pcfg_pull_up>;
};
spi1_tx: spi1-tx {
rockchip,pins = <RK_GPIO0 29 RK_FUNC_1 &pcfg_pull_up>;
};
spi1_cs1: spi1-cs1 {
rockchip,pins = <RK_GPIO1 14 RK_FUNC_2 &pcfg_pull_up>;
};
};
uart0 {
uart0_xfer: uart0-xfer {
rockchip,pins = <RK_GPIO1 0 RK_FUNC_1 &pcfg_pull_up>,
<RK_GPIO1 1 RK_FUNC_1 &pcfg_pull_none>;
};
uart0_cts: uart0-cts {
rockchip,pins = <RK_GPIO1 2 RK_FUNC_1 &pcfg_pull_none>;
};
uart0_rts: uart0-rts {
rockchip,pins = <RK_GPIO1 3 RK_FUNC_1 &pcfg_pull_none>;
};
};
uart1 {
uart1_xfer: uart1-xfer {
rockchip,pins = <RK_GPIO1 4 RK_FUNC_1 &pcfg_pull_up>,
<RK_GPIO1 5 RK_FUNC_1 &pcfg_pull_none>;
};
uart1_cts: uart1-cts {
rockchip,pins = <RK_GPIO1 6 RK_FUNC_1 &pcfg_pull_none>;
};
uart1_rts: uart1-rts {
rockchip,pins = <RK_GPIO1 7 RK_FUNC_1 &pcfg_pull_none>;
};
};
uart2 {
uart2_xfer: uart2-xfer {
rockchip,pins = <RK_GPIO1 8 RK_FUNC_1 &pcfg_pull_up>,
<RK_GPIO1 9 RK_FUNC_1 &pcfg_pull_none>;
};
/* no rts / cts for uart2 */
};
uart3 {
uart3_xfer: uart3-xfer {
rockchip,pins = <RK_GPIO1 10 RK_FUNC_1 &pcfg_pull_up>,
<RK_GPIO1 11 RK_FUNC_1 &pcfg_pull_none>;
};
uart3_cts: uart3-cts {
rockchip,pins = <RK_GPIO1 12 RK_FUNC_1 &pcfg_pull_none>;
};
uart3_rts: uart3-rts {
rockchip,pins = <RK_GPIO1 13 RK_FUNC_1 &pcfg_pull_none>;
};
};
sd0 {
sd0_clk: sd0-clk {
rockchip,pins = <RK_GPIO3 2 RK_FUNC_1 &pcfg_pull_none>;
};
sd0_cmd: sd0-cmd {
rockchip,pins = <RK_GPIO3 3 RK_FUNC_1 &pcfg_pull_none>;
};
sd0_cd: sd0-cd {
rockchip,pins = <RK_GPIO3 8 RK_FUNC_1 &pcfg_pull_none>;
};
sd0_wp: sd0-wp {
rockchip,pins = <RK_GPIO3 9 RK_FUNC_1 &pcfg_pull_none>;
};
sd0_pwr: sd0-pwr {
rockchip,pins = <RK_GPIO3 1 RK_FUNC_1 &pcfg_pull_none>;
};
sd0_bus1: sd0-bus-width1 {
rockchip,pins = <RK_GPIO3 4 RK_FUNC_1 &pcfg_pull_none>;
};
sd0_bus4: sd0-bus-width4 {
rockchip,pins = <RK_GPIO3 4 RK_FUNC_1 &pcfg_pull_none>,
<RK_GPIO3 5 RK_FUNC_1 &pcfg_pull_none>,
<RK_GPIO3 6 RK_FUNC_1 &pcfg_pull_none>,
<RK_GPIO3 7 RK_FUNC_1 &pcfg_pull_none>;
};
};
sd1 {
sd1_clk: sd1-clk {
rockchip,pins = <RK_GPIO3 21 RK_FUNC_1 &pcfg_pull_none>;
};
sd1_cmd: sd1-cmd {
rockchip,pins = <RK_GPIO3 16 RK_FUNC_1 &pcfg_pull_none>;
};
sd1_cd: sd1-cd {
rockchip,pins = <RK_GPIO3 22 RK_FUNC_1 &pcfg_pull_none>;
};
sd1_wp: sd1-wp {
rockchip,pins = <RK_GPIO3 23 RK_FUNC_1 &pcfg_pull_none>;
};
sd1_bus1: sd1-bus-width1 {
rockchip,pins = <RK_GPIO3 17 RK_FUNC_1 &pcfg_pull_none>;
};
sd1_bus4: sd1-bus-width4 {
rockchip,pins = <RK_GPIO3 17 RK_FUNC_1 &pcfg_pull_none>,
<RK_GPIO3 18 RK_FUNC_1 &pcfg_pull_none>,
<RK_GPIO3 19 RK_FUNC_1 &pcfg_pull_none>,
<RK_GPIO3 20 RK_FUNC_1 &pcfg_pull_none>;
};
};
i2s0 {
i2s0_bus: i2s0-bus {
rockchip,pins = <RK_GPIO1 16 RK_FUNC_1 &pcfg_pull_none>,
<RK_GPIO1 17 RK_FUNC_1 &pcfg_pull_none>,
<RK_GPIO1 18 RK_FUNC_1 &pcfg_pull_none>,
<RK_GPIO1 19 RK_FUNC_1 &pcfg_pull_none>,
<RK_GPIO1 20 RK_FUNC_1 &pcfg_pull_none>,
<RK_GPIO1 21 RK_FUNC_1 &pcfg_pull_none>;
};
};
spdif {
spdif_tx: spdif-tx {
rockchip,pins = <RK_GPIO1 14 RK_FUNC_1 &pcfg_pull_none>;
};
};
};
};
&emac {
compatible = "rockchip,rk3188-emac";
};
&global_timer {
interrupts = <GIC_PPI 11 0xf04>;
};
&grf {
compatible = "rockchip,rk3188-grf", "syscon";
};
&local_timer {
interrupts = <GIC_PPI 13 0xf04>;
};
&i2c0 {
compatible = "rockchip,rk3188-i2c";
pinctrl-names = "default";
pinctrl-0 = <&i2c0_xfer>;
};
&i2c1 {
compatible = "rockchip,rk3188-i2c";
pinctrl-names = "default";
pinctrl-0 = <&i2c1_xfer>;
};
&i2c2 {
compatible = "rockchip,rk3188-i2c";
pinctrl-names = "default";
pinctrl-0 = <&i2c2_xfer>;
};
&i2c3 {
compatible = "rockchip,rk3188-i2c";
pinctrl-names = "default";
pinctrl-0 = <&i2c3_xfer>;
};
&i2c4 {
compatible = "rockchip,rk3188-i2c";
pinctrl-names = "default";
pinctrl-0 = <&i2c4_xfer>;
};
&pmu {
compatible = "rockchip,rk3188-pmu", "syscon";
};
&pwm0 {
pinctrl-names = "default";
pinctrl-0 = <&pwm0_out>;
};
&pwm1 {
pinctrl-names = "default";
pinctrl-0 = <&pwm1_out>;
};
&pwm2 {
pinctrl-names = "default";
pinctrl-0 = <&pwm2_out>;
};
&pwm3 {
pinctrl-names = "default";
pinctrl-0 = <&pwm3_out>;
};
&spi0 {
compatible = "rockchip,rk3188-spi", "rockchip,rk3066-spi";
pinctrl-names = "default";
pinctrl-0 = <&spi0_clk &spi0_tx &spi0_rx &spi0_cs0>;
};
&spi1 {
compatible = "rockchip,rk3188-spi", "rockchip,rk3066-spi";
pinctrl-names = "default";
pinctrl-0 = <&spi1_clk &spi1_tx &spi1_rx &spi1_cs0>;
};
&uart0 {
compatible = "rockchip,rk3188-uart", "snps,dw-apb-uart";
pinctrl-names = "default";
pinctrl-0 = <&uart0_xfer>;
};
&uart1 {
compatible = "rockchip,rk3188-uart", "snps,dw-apb-uart";
pinctrl-names = "default";
pinctrl-0 = <&uart1_xfer>;
};
&uart2 {
compatible = "rockchip,rk3188-uart", "snps,dw-apb-uart";
pinctrl-names = "default";
pinctrl-0 = <&uart2_xfer>;
};
&uart3 {
compatible = "rockchip,rk3188-uart", "snps,dw-apb-uart";
pinctrl-names = "default";
pinctrl-0 = <&uart3_xfer>;
};
&wdt {
compatible = "rockchip,rk3188-wdt", "snps,dw-wdt";
};

View file

@ -11,6 +11,13 @@
reg = <0 0x80000000>;
};
ext_gmac: external-gmac-clock {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <125000000>;
clock-output-names = "ext_gmac";
};
keys: gpio-keys {
compatible = "gpio-keys";
#address-cells = <1>;
@ -98,6 +105,21 @@
status = "okay";
};
&gmac {
phy-mode = "rgmii";
clock_in_out = "input";
snps,reset-gpio = <&gpio4 7 0>;
snps,reset-active-low;
snps,reset-delays-us = <0 10000 1000000>;
assigned-clocks = <&cru SCLK_MAC>;
assigned-clock-parents = <&ext_gmac>;
pinctrl-names = "default";
pinctrl-0 = <&rgmii_pins>;
tx_delay = <0x30>;
rx_delay = <0x10>;
status = "okay";
};
&hdmi {
ddc-i2c-bus = <&i2c5>;
status = "okay";

View file

@ -203,7 +203,7 @@
pinctrl-0 = <&rgmii_pins>;
tx_delay = <0x30>;
rx_delay = <0x10>;
status = "ok";
status = "okay";
};
&hdmi {

View file

@ -30,6 +30,12 @@
&pinctrl {
u-boot,dm-pre-reloc;
usb {
host_vbus_drv: host-vbus-drv {
rockchip,pins = <0 14 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
};
&pwm1 {
@ -41,6 +47,11 @@
reg-shift = <2>;
};
&usb_host1 {
vbus-supply = <&vcc5v0_host>;
status = "okay";
};
&sdmmc {
u-boot,dm-pre-reloc;
};

View file

@ -110,6 +110,18 @@
startup-delay-us = <100000>;
vin-supply = <&vcc_io>;
};
vcc5v0_host: usb-host-regulator {
compatible = "regulator-fixed";
enable-active-high;
gpio = <&gpio0 14 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&host_vbus_drv>;
regulator-name = "vcc5v0_host";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
regulator-always-on;
};
};
&cpu0 {
@ -149,7 +161,7 @@
pinctrl-0 = <&rgmii_pins>;
tx_delay = <0x30>;
rx_delay = <0x10>;
status = "ok";
status = "okay";
};
&hdmi {

View file

@ -0,0 +1,45 @@
/*
* (C) Copyright 2016 Rockchip Electronics Co., Ltd
*
* SPDX-License-Identifier: GPL-2.0+
*/
/dts-v1/;
#include "rk3328.dtsi"
/ {
model = "Rockchip RK3328 EVB";
compatible = "rockchip,rk3328-evb", "rockchip,rk3328";
chosen {
stdout-path = &uart2;
};
};
&uart2 {
status = "okay";
};
&sdmmc {
bus-width = <4>;
cap-mmc-highspeed;
cap-sd-highspeed;
card-detect-delay = <200>;
disable-wp;
num-slots = <1>;
pinctrl-names = "default";
pinctrl-0 = <&sdmmc0_clk>, <&sdmmc0_cmd>, <&sdmmc0_dectn>, <&sdmmc0_bus4>;
status = "okay";
};
&emmc {
bus-width = <8>;
cap-mmc-highspeed;
supports-emmc;
disable-wp;
non-removable;
num-slots = <1>;
pinctrl-names = "default";
pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>;
status = "okay";
};

1477
arch/arm/dts/rk3328.dtsi Normal file

File diff suppressed because it is too large Load diff

View file

@ -7,6 +7,7 @@
/dts-v1/;
#include <dt-bindings/pwm/pwm.h>
#include "rk3399.dtsi"
#include "rk3399-sdram-lpddr3-4GB-1600.dtsi"
/ {
model = "Rockchip RK3399 Evaluation Board";
@ -69,6 +70,7 @@
};
&sdmmc {
bus-width = <4>;
status = "okay";
};

File diff suppressed because it is too large Load diff

View file

@ -24,6 +24,8 @@
serial2 = &uart2;
serial3 = &uart3;
serial4 = &uart4;
mmc0 = &sdhci;
mmc1 = &sdmmc;
};
cpus {
@ -183,6 +185,7 @@
};
sdhci: sdhci@fe330000 {
u-boot,dm-pre-reloc;
compatible = "rockchip,rk3399-sdhci-5.1", "arasan,sdhci-5.1";
reg = <0x0 0xfe330000 0x0 0x10000>;
interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
@ -416,6 +419,7 @@
};
pmugrf: syscon@ff320000 {
u-boot,dm-pre-reloc;
compatible = "rockchip,rk3399-pmugrf", "syscon", "simple-mfd";
reg = <0x0 0xff320000 0x0 0x1000>;
#address-cells = <1>;
@ -427,6 +431,12 @@
};
};
pmusgrf: syscon@ff330000 {
u-boot,dm-pre-reloc;
compatible = "rockchip,rk3399-pmusgrf", "syscon";
reg = <0x0 0xff330000 0x0 0xe3d4>;
};
spi3: spi@ff350000 {
compatible = "rockchip,rk3399-spi", "rockchip,rk3066-spi";
reg = <0x0 0xff350000 0x0 0x1000>;
@ -497,7 +507,40 @@
status = "disabled";
};
cic: syscon@ff620000 {
u-boot,dm-pre-reloc;
compatible = "rockchip,rk3399-cic", "syscon";
reg = <0x0 0xff620000 0x0 0x100>;
};
dfi: dfi@ff630000 {
reg = <0x00 0xff630000 0x00 0x4000>;
compatible = "rockchip,rk3399-dfi";
rockchip,pmu = <&pmugrf>;
clocks = <&cru PCLK_DDR_MON>;
clock-names = "pclk_ddr_mon";
status = "disabled";
};
dmc: dmc {
u-boot,dm-pre-reloc;
compatible = "rockchip,rk3399-dmc";
devfreq-events = <&dfi>;
interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH 0>;
clocks = <&cru SCLK_DDRCLK>;
clock-names = "dmc_clk";
reg = <0x0 0xffa80000 0x0 0x0800
0x0 0xffa80800 0x0 0x1800
0x0 0xffa82000 0x0 0x2000
0x0 0xffa84000 0x0 0x1000
0x0 0xffa88000 0x0 0x0800
0x0 0xffa88800 0x0 0x1800
0x0 0xffa8a000 0x0 0x2000
0x0 0xffa8c000 0x0 0x1000>;
};
pmucru: pmu-clock-controller@ff750000 {
u-boot,dm-pre-reloc;
compatible = "rockchip,rk3399-pmucru";
reg = <0x0 0xff750000 0x0 0x1000>;
#clock-cells = <1>;
@ -507,6 +550,7 @@
};
cru: clock-controller@ff760000 {
u-boot,dm-pre-reloc;
compatible = "rockchip,rk3399-cru";
reg = <0x0 0xff760000 0x0 0x1000>;
#clock-cells = <1>;
@ -530,6 +574,7 @@
};
grf: syscon@ff770000 {
u-boot,dm-pre-reloc;
compatible = "rockchip,rk3399-grf", "syscon", "simple-mfd";
reg = <0x0 0xff770000 0x0 0x10000>;
#address-cells = <1>;
@ -607,6 +652,7 @@
};
pinctrl: pinctrl {
u-boot,dm-pre-reloc;
compatible = "rockchip,rk3399-pinctrl";
rockchip,grf = <&grf>;
rockchip,pmu = <&pmugrf>;

417
arch/arm/dts/rk3xxx.dtsi Normal file
View file

@ -0,0 +1,417 @@
/*
* Copyright (c) 2013 MundoReader S.L.
* Author: Heiko Stuebner <heiko@sntech.de>
*
* SPDX-License-Identifier: GPL-2.0+ or X11
*/
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include "skeleton.dtsi"
/ {
interrupt-parent = <&gic>;
aliases {
ethernet0 = &emac;
i2c0 = &i2c0;
i2c1 = &i2c1;
i2c2 = &i2c2;
i2c3 = &i2c3;
i2c4 = &i2c4;
mshc0 = &emmc;
mshc1 = &mmc0;
mshc2 = &mmc1;
serial0 = &uart0;
serial1 = &uart1;
serial2 = &uart2;
serial3 = &uart3;
spi0 = &spi0;
spi1 = &spi1;
};
amba {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
ranges;
dmac1_s: dma-controller@20018000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x20018000 0x4000>;
interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
#dma-cells = <1>;
arm,pl330-broken-no-flushp;
clocks = <&cru ACLK_DMA1>;
clock-names = "apb_pclk";
};
dmac1_ns: dma-controller@2001c000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x2001c000 0x4000>;
interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
#dma-cells = <1>;
arm,pl330-broken-no-flushp;
clocks = <&cru ACLK_DMA1>;
clock-names = "apb_pclk";
status = "disabled";
};
dmac2: dma-controller@20078000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x20078000 0x4000>;
interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
#dma-cells = <1>;
arm,pl330-broken-no-flushp;
clocks = <&cru ACLK_DMA2>;
clock-names = "apb_pclk";
};
};
xin24m: oscillator {
compatible = "fixed-clock";
clock-frequency = <24000000>;
#clock-cells = <0>;
clock-output-names = "xin24m";
};
L2: l2-cache-controller@10138000 {
compatible = "arm,pl310-cache";
reg = <0x10138000 0x1000>;
cache-unified;
cache-level = <2>;
};
scu@1013c000 {
compatible = "arm,cortex-a9-scu";
reg = <0x1013c000 0x100>;
};
global_timer: global-timer@1013c200 {
compatible = "arm,cortex-a9-global-timer";
reg = <0x1013c200 0x20>;
interrupts = <GIC_PPI 11 0x304>;
clocks = <&cru CORE_PERI>;
};
local_timer: local-timer@1013c600 {
compatible = "arm,cortex-a9-twd-timer";
reg = <0x1013c600 0x20>;
interrupts = <GIC_PPI 13 0x304>;
clocks = <&cru CORE_PERI>;
};
gic: interrupt-controller@1013d000 {
compatible = "arm,cortex-a9-gic";
interrupt-controller;
#interrupt-cells = <3>;
reg = <0x1013d000 0x1000>,
<0x1013c100 0x0100>;
};
uart0: serial@10124000 {
compatible = "snps,dw-apb-uart";
reg = <0x10124000 0x400>;
interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
reg-io-width = <1>;
clock-names = "baudclk", "apb_pclk";
clocks = <&cru SCLK_UART0>, <&cru PCLK_UART0>;
status = "disabled";
};
uart1: serial@10126000 {
compatible = "snps,dw-apb-uart";
reg = <0x10126000 0x400>;
interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
reg-io-width = <1>;
clock-names = "baudclk", "apb_pclk";
clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>;
status = "disabled";
};
noc: syscon@10128000 {
u-boot,dm-spl;
compatible = "rockchip,rk3188-noc", "syscon";
reg = <0x10128000 0x2000>;
};
usb_otg: usb@10180000 {
compatible = "rockchip,rk3066-usb", "snps,dwc2";
reg = <0x10180000 0x40000>;
interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru HCLK_OTG0>;
clock-names = "otg";
dr_mode = "otg";
g-np-tx-fifo-size = <16>;
g-rx-fifo-size = <275>;
g-tx-fifo-size = <256 128 128 64 64 32>;
g-use-dma;
phys = <&usbphy0>;
phy-names = "usb2-phy";
status = "disabled";
};
usb_host: usb@101c0000 {
compatible = "snps,dwc2";
reg = <0x101c0000 0x40000>;
interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru HCLK_OTG1>;
clock-names = "otg";
dr_mode = "host";
phys = <&usbphy1>;
phy-names = "usb2-phy";
status = "disabled";
};
emac: ethernet@10204000 {
compatible = "snps,arc-emac";
reg = <0x10204000 0x3c>;
interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
rockchip,grf = <&grf>;
clocks = <&cru HCLK_EMAC>, <&cru SCLK_MAC>;
clock-names = "hclk", "macref";
max-speed = <100>;
phy-mode = "rmii";
status = "disabled";
};
mmc0: dwmmc@10214000 {
compatible = "rockchip,rk2928-dw-mshc";
reg = <0x10214000 0x1000>;
interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>;
clock-names = "biu", "ciu";
fifo-depth = <256>;
status = "disabled";
};
mmc1: dwmmc@10218000 {
compatible = "rockchip,rk2928-dw-mshc";
reg = <0x10218000 0x1000>;
interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru HCLK_SDIO>, <&cru SCLK_SDIO>;
clock-names = "biu", "ciu";
fifo-depth = <256>;
status = "disabled";
};
emmc: dwmmc@1021c000 {
compatible = "rockchip,rk2928-dw-mshc";
reg = <0x1021c000 0x1000>;
interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>;
clock-names = "biu", "ciu";
fifo-depth = <256>;
status = "disabled";
};
pmu: pmu@20004000 {
compatible = "rockchip,rk3066-pmu", "syscon";
reg = <0x20004000 0x100>;
u-boot,dm-spl;
};
grf: grf@20008000 {
compatible = "syscon";
reg = <0x20008000 0x200>;
u-boot,dm-spl;
};
dmc: dmc@20020000 {
/* unreviewed u-boot-specific binding */
compatible = "rockchip,rk3188-dmc", "syscon";
rockchip,cru = <&cru>;
rockchip,grf = <&grf>;
rockchip,pmu = <&pmu>;
rockchip,noc = <&noc>;
reg = <0x20020000 0x3fc
0x20040000 0x294>;
clocks = <&cru PCLK_DDRUPCTL>, <&cru PCLK_PUBL>;
clock-names = "pclk_ddrupctl", "pclk_publ";
u-boot,dm-spl;
};
i2c0: i2c@2002d000 {
compatible = "rockchip,rk3066-i2c";
reg = <0x2002d000 0x1000>;
interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
rockchip,grf = <&grf>;
clock-names = "i2c";
clocks = <&cru PCLK_I2C0>;
status = "disabled";
};
i2c1: i2c@2002f000 {
compatible = "rockchip,rk3066-i2c";
reg = <0x2002f000 0x1000>;
interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
rockchip,grf = <&grf>;
clocks = <&cru PCLK_I2C1>;
clock-names = "i2c";
status = "disabled";
};
pwm0: pwm@20030000 {
compatible = "rockchip,rk2928-pwm";
reg = <0x20030000 0x10>;
#pwm-cells = <2>;
clocks = <&cru PCLK_PWM01>;
status = "disabled";
};
pwm1: pwm@20030010 {
compatible = "rockchip,rk2928-pwm";
reg = <0x20030010 0x10>;
#pwm-cells = <2>;
clocks = <&cru PCLK_PWM01>;
status = "disabled";
};
wdt: watchdog@2004c000 {
compatible = "snps,dw-wdt";
reg = <0x2004c000 0x100>;
clocks = <&cru PCLK_WDT>;
interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};
pwm2: pwm@20050020 {
compatible = "rockchip,rk2928-pwm";
reg = <0x20050020 0x10>;
#pwm-cells = <2>;
clocks = <&cru PCLK_PWM23>;
status = "disabled";
};
pwm3: pwm@20050030 {
compatible = "rockchip,rk2928-pwm";
reg = <0x20050030 0x10>;
#pwm-cells = <2>;
clocks = <&cru PCLK_PWM23>;
status = "disabled";
};
i2c2: i2c@20056000 {
compatible = "rockchip,rk3066-i2c";
reg = <0x20056000 0x1000>;
interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
rockchip,grf = <&grf>;
clocks = <&cru PCLK_I2C2>;
clock-names = "i2c";
status = "disabled";
};
i2c3: i2c@2005a000 {
compatible = "rockchip,rk3066-i2c";
reg = <0x2005a000 0x1000>;
interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
rockchip,grf = <&grf>;
clocks = <&cru PCLK_I2C3>;
clock-names = "i2c";
status = "disabled";
};
i2c4: i2c@2005e000 {
compatible = "rockchip,rk3066-i2c";
reg = <0x2005e000 0x1000>;
interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
rockchip,grf = <&grf>;
clocks = <&cru PCLK_I2C4>;
clock-names = "i2c";
status = "disabled";
};
uart2: serial@20064000 {
compatible = "snps,dw-apb-uart";
reg = <0x20064000 0x400>;
interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
reg-io-width = <1>;
clock-frequency = <24000000>;
clock-names = "baudclk", "apb_pclk";
clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>;
status = "disabled";
};
uart3: serial@20068000 {
compatible = "snps,dw-apb-uart";
reg = <0x20068000 0x400>;
interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
reg-io-width = <1>;
clock-names = "baudclk", "apb_pclk";
clocks = <&cru SCLK_UART3>, <&cru PCLK_UART3>;
status = "disabled";
};
saradc: saradc@2006c000 {
compatible = "rockchip,saradc";
reg = <0x2006c000 0x100>;
interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
#io-channel-cells = <1>;
clocks = <&cru SCLK_SARADC>, <&cru PCLK_SARADC>;
clock-names = "saradc", "apb_pclk";
status = "disabled";
};
spi0: spi@20070000 {
compatible = "rockchip,rk3066-spi";
clocks = <&cru SCLK_SPI0>, <&cru PCLK_SPI0>;
clock-names = "spiclk", "apb_pclk";
interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
reg = <0x20070000 0x1000>;
#address-cells = <1>;
#size-cells = <0>;
dmas = <&dmac2 10>, <&dmac2 11>;
dma-names = "tx", "rx";
status = "disabled";
};
spi1: spi@20074000 {
compatible = "rockchip,rk3066-spi";
clocks = <&cru SCLK_SPI1>, <&cru PCLK_SPI1>;
clock-names = "spiclk", "apb_pclk";
interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
reg = <0x20074000 0x1000>;
#address-cells = <1>;
#size-cells = <0>;
dmas = <&dmac2 12>, <&dmac2 13>;
dma-names = "tx", "rx";
status = "disabled";
};
};

View file

@ -0,0 +1,22 @@
/*
* (C) Copyright 2017 Heiko Stuebner <heiko@sntech.de>
*
* SPDX-License-Identifier: GPL-2.0
*/
#ifndef _ASM_ARCH_BOOTROM_H
#define _ASM_ARCH_BOOTROM_H
/*
* Saved Stack pointer address.
* Access might be needed in some special cases.
*/
extern u32 SAVE_SP_ADDR;
/*
* Hand control back to the bootrom to load another
* boot stage.
*/
extern void back_to_bootrom(void);
#endif

View file

@ -17,6 +17,8 @@ enum {
ROCKCHIP_SYSCON_SGRF,
ROCKCHIP_SYSCON_PMU,
ROCKCHIP_SYSCON_PMUGRF,
ROCKCHIP_SYSCON_PMUSGRF,
ROCKCHIP_SYSCON_CIC,
};
/* Standard Rockchip clock numbers */
@ -63,6 +65,13 @@ static inline u32 clk_get_divisor(ulong input_rate, uint output_rate)
*/
void *rockchip_get_cru(void);
/**
* rockchip_get_pmucru() - get a pointer to the clock/reset unit registers
*
* @return pointer to registers, or -ve error on error
*/
void *rockchip_get_pmucru(void);
struct rk3288_cru;
struct rk3288_grf;

View file

@ -0,0 +1,191 @@
/*
* (C) Copyright 2016 Heiko Stuebner <heiko@sntech.de>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _ASM_ARCH_CRU_RK3188_H
#define _ASM_ARCH_CRU_RK3188_H
#define OSC_HZ (24 * 1000 * 1000)
#define APLL_HZ (1608 * 1000000)
#define GPLL_HZ (594 * 1000000)
#define CPLL_HZ (384 * 1000000)
/* The SRAM is clocked off aclk_cpu, so we want to max it out for boot speed */
#define CPU_ACLK_HZ 297000000
#define CPU_HCLK_HZ 148500000
#define CPU_PCLK_HZ 74250000
#define CPU_H2P_HZ 74250000
#define PERI_ACLK_HZ 148500000
#define PERI_HCLK_HZ 148500000
#define PERI_PCLK_HZ 74250000
/* Private data for the clock driver - used by rockchip_get_cru() */
struct rk3188_clk_priv {
struct rk3188_grf *grf;
struct rk3188_cru *cru;
ulong rate;
bool has_bwadj;
};
struct rk3188_cru {
struct rk3188_pll {
u32 con0;
u32 con1;
u32 con2;
u32 con3;
} pll[4];
u32 cru_mode_con;
u32 cru_clksel_con[35];
u32 cru_clkgate_con[10];
u32 reserved1[2];
u32 cru_glb_srst_fst_value;
u32 cru_glb_srst_snd_value;
u32 reserved2[2];
u32 cru_softrst_con[9];
u32 cru_misc_con;
u32 reserved3[2];
u32 cru_glb_cnt_th;
};
check_member(rk3188_cru, cru_glb_cnt_th, 0x0140);
/* CRU_CLKSEL0_CON */
enum {
/* a9_core_div: core = core_src / (a9_core_div + 1) */
A9_CORE_DIV_SHIFT = 9,
A9_CORE_DIV_MASK = 0x1f,
CORE_PLL_SHIFT = 8,
CORE_PLL_MASK = 1,
CORE_PLL_SELECT_APLL = 0,
CORE_PLL_SELECT_GPLL,
/* core peri div: core:core_peri = 2:1, 4:1, 8:1 or 16:1 */
CORE_PERI_DIV_SHIFT = 6,
CORE_PERI_DIV_MASK = 3,
/* aclk_cpu pll selection */
CPU_ACLK_PLL_SHIFT = 5,
CPU_ACLK_PLL_MASK = 1,
CPU_ACLK_PLL_SELECT_APLL = 0,
CPU_ACLK_PLL_SELECT_GPLL,
/* a9_cpu_div: aclk_cpu = cpu_src / (a9_cpu_div + 1) */
A9_CPU_DIV_SHIFT = 0,
A9_CPU_DIV_MASK = 0x1f,
};
/* CRU_CLKSEL1_CON */
enum {
/* ahb2apb_pclk_div: hclk_cpu:pclk_cpu = 1:1, 2:1 or 4:1 */
AHB2APB_DIV_SHIFT = 14,
AHB2APB_DIV_MASK = 3,
/* cpu_pclk_div: aclk_cpu:pclk_cpu = 1:1, 2:1, 4:1 or 8:1 */
CPU_PCLK_DIV_SHIFT = 12,
CPU_PCLK_DIV_MASK = 3,
/* cpu_hclk_div: aclk_cpu:hclk_cpu = 1:1, 2:1 or 4:1 */
CPU_HCLK_DIV_SHIFT = 8,
CPU_HCLK_DIV_MASK = 3,
/* core_aclk_div: cire:aclk_core = 1:1, 2:1, 3:1, 4:1 or 8:1 */
CORE_ACLK_DIV_SHIFT = 3,
CORE_ACLK_DIV_MASK = 7,
};
/* CRU_CLKSEL10_CON */
enum {
PERI_SEL_PLL_MASK = 1,
PERI_SEL_PLL_SHIFT = 15,
PERI_SEL_CPLL = 0,
PERI_SEL_GPLL,
/* peri pclk div: aclk_bus:pclk_bus = 1:1, 2:1, 4:1 or 8:1 */
PERI_PCLK_DIV_SHIFT = 12,
PERI_PCLK_DIV_MASK = 3,
/* peripheral bus hclk div:aclk_bus: hclk_bus = 1:1, 2:1 or 4:1 */
PERI_HCLK_DIV_SHIFT = 8,
PERI_HCLK_DIV_MASK = 3,
/* peri aclk div: aclk_peri = periph_src / (peri_aclk_div + 1) */
PERI_ACLK_DIV_SHIFT = 0,
PERI_ACLK_DIV_MASK = 0x1f,
};
/* CRU_CLKSEL11_CON */
enum {
HSICPHY_DIV_SHIFT = 8,
HSICPHY_DIV_MASK = 0x3f,
MMC0_DIV_SHIFT = 0,
MMC0_DIV_MASK = 0x3f,
};
/* CRU_CLKSEL12_CON */
enum {
UART_PLL_SHIFT = 15,
UART_PLL_MASK = 1,
UART_PLL_SELECT_GENERAL = 0,
UART_PLL_SELECT_CODEC,
EMMC_DIV_SHIFT = 8,
EMMC_DIV_MASK = 0x3f,
SDIO_DIV_SHIFT = 0,
SDIO_DIV_MASK = 0x3f,
};
/* CRU_CLKSEL25_CON */
enum {
SPI1_DIV_SHIFT = 8,
SPI1_DIV_MASK = 0x7f,
SPI0_DIV_SHIFT = 0,
SPI0_DIV_MASK = 0x7f,
};
/* CRU_MODE_CON */
enum {
GPLL_MODE_SHIFT = 12,
GPLL_MODE_MASK = 3,
GPLL_MODE_SLOW = 0,
GPLL_MODE_NORMAL,
GPLL_MODE_DEEP,
CPLL_MODE_SHIFT = 8,
CPLL_MODE_MASK = 3,
CPLL_MODE_SLOW = 0,
CPLL_MODE_NORMAL,
CPLL_MODE_DEEP,
DPLL_MODE_SHIFT = 4,
DPLL_MODE_MASK = 3,
DPLL_MODE_SLOW = 0,
DPLL_MODE_NORMAL,
DPLL_MODE_DEEP,
APLL_MODE_SHIFT = 0,
APLL_MODE_MASK = 3,
APLL_MODE_SLOW = 0,
APLL_MODE_NORMAL,
APLL_MODE_DEEP,
};
/* CRU_APLL_CON0 */
enum {
CLKR_SHIFT = 8,
CLKR_MASK = 0x3f,
CLKOD_SHIFT = 0,
CLKOD_MASK = 0x3f,
};
/* CRU_APLL_CON1 */
enum {
CLKF_SHIFT = 0,
CLKF_MASK = 0x1fff,
};
#endif

View file

@ -0,0 +1,70 @@
/*
* (C) Copyright 2016 Rockchip Electronics Co., Ltd
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef __ASM_ARCH_CRU_RK3328_H_
#define __ASM_ARCH_CRU_RK3328_H_
#include <common.h>
struct rk3328_clk_priv {
struct rk3328_cru *cru;
ulong rate;
};
struct rk3328_cru {
u32 apll_con[5];
u32 reserved1[3];
u32 dpll_con[5];
u32 reserved2[3];
u32 cpll_con[5];
u32 reserved3[3];
u32 gpll_con[5];
u32 reserved4[3];
u32 mode_con;
u32 misc;
u32 reserved5[2];
u32 glb_cnt_th;
u32 glb_rst_st;
u32 glb_srst_snd_value;
u32 glb_srst_fst_value;
u32 npll_con[5];
u32 reserved6[(0x100 - 0xb4) / 4];
u32 clksel_con[53];
u32 reserved7[(0x200 - 0x1d4) / 4];
u32 clkgate_con[29];
u32 reserved8[3];
u32 ssgtbl[32];
u32 softrst_con[12];
u32 reserved9[(0x380 - 0x330) / 4];
u32 sdmmc_con[2];
u32 sdio_con[2];
u32 emmc_con[2];
u32 sdmmc_ext_con[2];
};
check_member(rk3328_cru, sdmmc_ext_con[1], 0x39c);
#define MHz 1000000
#define KHz 1000
#define OSC_HZ (24 * MHz)
#define APLL_HZ (600 * MHz)
#define GPLL_HZ (576 * MHz)
#define CPLL_HZ (594 * MHz)
#define CLK_CORE_HZ (600 * MHz)
#define ACLKM_CORE_HZ (300 * MHz)
#define PCLK_DBG_HZ (300 * MHz)
#define PERIHP_ACLK_HZ (144000 * KHz)
#define PERIHP_HCLK_HZ (72000 * KHz)
#define PERIHP_PCLK_HZ (72000 * KHz)
#define PWM_CLOCK_HZ (74 * MHz)
enum apll_frequencies {
APLL_816_MHZ,
APLL_600_MHZ,
};
#endif /* __ASM_ARCH_CRU_RK3328_H_ */

View file

@ -15,6 +15,11 @@ struct rk3399_clk_priv {
ulong rate;
};
struct rk3399_pmuclk_priv {
struct rk3399_pmucru *pmucru;
ulong rate;
};
struct rk3399_pmucru {
u32 ppll_con[6];
u32 reserved[0x1a];

View file

@ -0,0 +1,25 @@
/*
* (C) Copyright 2015 Google, Inc
*
* SPDX-License-Identifier: GPL-2.0
*/
#ifndef _ASM_ARCH_DDR_RK3188_H
#define _ASM_ARCH_DDR_RK3188_H
#include <asm/arch/ddr_rk3288.h>
/*
* RK3188 Memory scheduler register map.
*/
struct rk3188_msch {
u32 coreid;
u32 revisionid;
u32 ddrconf;
u32 ddrtiming;
u32 ddrmode;
u32 readlatency;
};
check_member(rk3188_msch, readlatency, 0x0014);
#endif

View file

@ -425,6 +425,14 @@ enum {
#define START_CMD (1u << 31)
/*
* DDRCONF
* [5:4] row(13+n)
* [1:0] col(9+n), assume bw=2
*/
#define DDRCONF_ROW_SHIFT 4
#define DDRCONF_COL_SHIFT 0
/* DEVTODEV */
#define BUSWRTORD_SHIFT 4
#define BUSRDTOWR_SHIFT 2

View file

@ -0,0 +1,589 @@
/*
* Copyright (c) 2016 Heiko Stuebner <heiko@sntech.de>
*
* SPDX-License-Identifier: GPL-2.0
*/
#ifndef _ASM_ARCH_GRF_RK3188_H
#define _ASM_ARCH_GRF_RK3188_H
struct rk3188_grf_gpio_lh {
u32 l;
u32 h;
};
struct rk3188_grf {
struct rk3188_grf_gpio_lh gpio_dir[4];
struct rk3188_grf_gpio_lh gpio_do[4];
struct rk3188_grf_gpio_lh gpio_en[4];
u32 reserved[2];
u32 gpio0c_iomux;
u32 gpio0d_iomux;
u32 gpio1a_iomux;
u32 gpio1b_iomux;
u32 gpio1c_iomux;
u32 gpio1d_iomux;
u32 gpio2a_iomux;
u32 gpio2b_iomux;
u32 gpio2c_iomux;
u32 gpio2d_iomux;
u32 gpio3a_iomux;
u32 gpio3b_iomux;
u32 gpio3c_iomux;
u32 gpio3d_iomux;
u32 soc_con0;
u32 soc_con1;
u32 soc_con2;
u32 soc_status0;
u32 busdmac_con[3];
u32 peridmac_con[4];
u32 cpu_con[6];
u32 reserved0[2];
u32 ddrc_con0;
u32 ddrc_stat;
u32 io_con[5];
u32 soc_status1;
u32 uoc0_con[4];
u32 uoc1_con[4];
u32 uoc2_con[2];
u32 reserved1;
u32 uoc3_con[2];
u32 hsic_stat;
u32 os_reg[8];
u32 gpio0_p[3];
u32 gpio1_p[3][4];
u32 flash_data_p;
u32 flash_cmd_p;
};
check_member(rk3188_grf, flash_cmd_p, 0x01a4);
/* GRF_GPIO0D_IOMUX */
enum {
GPIO0D7_SHIFT = 14,
GPIO0D7_MASK = 1,
GPIO0D7_GPIO = 0,
GPIO0D7_SPI1_CSN0,
GPIO0D6_SHIFT = 12,
GPIO0D6_MASK = 1,
GPIO0D6_GPIO = 0,
GPIO0D6_SPI1_CLK,
GPIO0D5_SHIFT = 10,
GPIO0D5_MASK = 1,
GPIO0D5_GPIO = 0,
GPIO0D5_SPI1_TXD,
GPIO0D4_SHIFT = 8,
GPIO0D4_MASK = 1,
GPIO0D4_GPIO = 0,
GPIO0D4_SPI0_RXD,
GPIO0D3_SHIFT = 6,
GPIO0D3_MASK = 3,
GPIO0D3_GPIO = 0,
GPIO0D3_FLASH_CSN3,
GPIO0D3_EMMC_RSTN_OUT,
GPIO0D2_SHIFT = 4,
GPIO0D2_MASK = 3,
GPIO0D2_GPIO = 0,
GPIO0D2_FLASH_CSN2,
GPIO0D2_EMMC_CMD,
GPIO0D1_SHIFT = 2,
GPIO0D1_MASK = 1,
GPIO0D1_GPIO = 0,
GPIO0D1_FLASH_CSN1,
GPIO0D0_SHIFT = 0,
GPIO0D0_MASK = 3,
GPIO0D0_GPIO = 0,
GPIO0D0_FLASH_DQS,
GPIO0D0_EMMC_CLKOUT
};
/* GRF_GPIO1A_IOMUX */
enum {
GPIO1A7_SHIFT = 14,
GPIO1A7_MASK = 3,
GPIO1A7_GPIO = 0,
GPIO1A7_UART1_RTS_N,
GPIO1A7_SPI0_CSN0,
GPIO1A6_SHIFT = 12,
GPIO1A6_MASK = 3,
GPIO1A6_GPIO = 0,
GPIO1A6_UART1_CTS_N,
GPIO1A6_SPI0_CLK,
GPIO1A5_SHIFT = 10,
GPIO1A5_MASK = 3,
GPIO1A5_GPIO = 0,
GPIO1A5_UART1_SOUT,
GPIO1A5_SPI0_TXD,
GPIO1A4_SHIFT = 8,
GPIO1A4_MASK = 3,
GPIO1A4_GPIO = 0,
GPIO1A4_UART1_SIN,
GPIO1A4_SPI0_RXD,
GPIO1A3_SHIFT = 6,
GPIO1A3_MASK = 1,
GPIO1A3_GPIO = 0,
GPIO1A3_UART0_RTS_N,
GPIO1A2_SHIFT = 4,
GPIO1A2_MASK = 1,
GPIO1A2_GPIO = 0,
GPIO1A2_UART0_CTS_N,
GPIO1A1_SHIFT = 2,
GPIO1A1_MASK = 1,
GPIO1A1_GPIO = 0,
GPIO1A1_UART0_SOUT,
GPIO1A0_SHIFT = 0,
GPIO1A0_MASK = 1,
GPIO1A0_GPIO = 0,
GPIO1A0_UART0_SIN,
};
/* GRF_GPIO1B_IOMUX */
enum {
GPIO1B7_SHIFT = 14,
GPIO1B7_MASK = 1,
GPIO1B7_GPIO = 0,
GPIO1B7_SPI0_CSN1,
GPIO1B6_SHIFT = 12,
GPIO1B6_MASK = 3,
GPIO1B6_GPIO = 0,
GPIO1B6_SPDIF_TX,
GPIO1B6_SPI1_CSN1,
GPIO1B5_SHIFT = 10,
GPIO1B5_MASK = 3,
GPIO1B5_GPIO = 0,
GPIO1B5_UART3_RTS_N,
GPIO1B5_RESERVED,
GPIO1B4_SHIFT = 8,
GPIO1B4_MASK = 3,
GPIO1B4_GPIO = 0,
GPIO1B4_UART3_CTS_N,
GPIO1B4_GPS_RFCLK,
GPIO1B3_SHIFT = 6,
GPIO1B3_MASK = 3,
GPIO1B3_GPIO = 0,
GPIO1B3_UART3_SOUT,
GPIO1B3_GPS_SIG,
GPIO1B2_SHIFT = 4,
GPIO1B2_MASK = 3,
GPIO1B2_GPIO = 0,
GPIO1B2_UART3_SIN,
GPIO1B2_GPS_MAG,
GPIO1B1_SHIFT = 2,
GPIO1B1_MASK = 3,
GPIO1B1_GPIO = 0,
GPIO1B1_UART2_SOUT,
GPIO1B1_JTAG_TDO,
GPIO1B0_SHIFT = 0,
GPIO1B0_MASK = 3,
GPIO1B0_GPIO = 0,
GPIO1B0_UART2_SIN,
GPIO1B0_JTAG_TDI,
};
/* GRF_GPIO1D_IOMUX */
enum {
GPIO1D7_SHIFT = 14,
GPIO1D7_MASK = 1,
GPIO1D7_GPIO = 0,
GPIO1D7_I2C4_SCL,
GPIO1D6_SHIFT = 12,
GPIO1D6_MASK = 1,
GPIO1D6_GPIO = 0,
GPIO1D6_I2C4_SDA,
GPIO1D5_SHIFT = 10,
GPIO1D5_MASK = 1,
GPIO1D5_GPIO = 0,
GPIO1D5_I2C2_SCL,
GPIO1D4_SHIFT = 8,
GPIO1D4_MASK = 1,
GPIO1D4_GPIO = 0,
GPIO1D4_I2C2_SDA,
GPIO1D3_SHIFT = 6,
GPIO1D3_MASK = 1,
GPIO1D3_GPIO = 0,
GPIO1D3_I2C1_SCL,
GPIO1D2_SHIFT = 4,
GPIO1D2_MASK = 1,
GPIO1D2_GPIO = 0,
GPIO1D2_I2C1_SDA,
GPIO1D1_SHIFT = 2,
GPIO1D1_MASK = 1,
GPIO1D1_GPIO = 0,
GPIO1D1_I2C0_SCL,
GPIO1D0_SHIFT = 0,
GPIO1D0_MASK = 1,
GPIO1D0_GPIO = 0,
GPIO1D0_I2C0_SDA,
};
/* GRF_GPIO3A_IOMUX */
enum {
GPIO3A7_SHIFT = 14,
GPIO3A7_MASK = 1,
GPIO3A7_GPIO = 0,
GPIO3A7_SDMMC0_DATA3,
GPIO3A6_SHIFT = 12,
GPIO3A6_MASK = 1,
GPIO3A6_GPIO = 0,
GPIO3A6_SDMMC0_DATA2,
GPIO3A5_SHIFT = 10,
GPIO3A5_MASK = 1,
GPIO3A5_GPIO = 0,
GPIO3A5_SDMMC0_DATA1,
GPIO3A4_SHIFT = 8,
GPIO3A4_MASK = 1,
GPIO3A4_GPIO = 0,
GPIO3A4_SDMMC0_DATA0,
GPIO3A3_SHIFT = 6,
GPIO3A3_MASK = 1,
GPIO3A3_GPIO = 0,
GPIO3A3_SDMMC0_CMD,
GPIO3A2_SHIFT = 4,
GPIO3A2_MASK = 1,
GPIO3A2_GPIO = 0,
GPIO3A2_SDMMC0_CLKOUT,
GPIO3A1_SHIFT = 2,
GPIO3A1_MASK = 1,
GPIO3A1_GPIO = 0,
GPIO3A1_SDMMC0_PWREN,
GPIO3A0_SHIFT = 0,
GPIO3A0_MASK = 1,
GPIO3A0_GPIO = 0,
GPIO3A0_SDMMC0_RSTN,
};
/* GRF_GPIO3B_IOMUX */
enum {
GPIO3B7_SHIFT = 14,
GPIO3B7_MASK = 3,
GPIO3B7_GPIO = 0,
GPIO3B7_CIF_DATA11,
GPIO3B7_I2C3_SCL,
GPIO3B6_SHIFT = 12,
GPIO3B6_MASK = 3,
GPIO3B6_GPIO = 0,
GPIO3B6_CIF_DATA10,
GPIO3B6_I2C3_SDA,
GPIO3B5_SHIFT = 10,
GPIO3B5_MASK = 3,
GPIO3B5_GPIO = 0,
GPIO3B5_CIF_DATA1,
GPIO3B5_HSADC_DATA9,
GPIO3B4_SHIFT = 8,
GPIO3B4_MASK = 3,
GPIO3B4_GPIO = 0,
GPIO3B4_CIF_DATA0,
GPIO3B4_HSADC_DATA8,
GPIO3B3_SHIFT = 6,
GPIO3B3_MASK = 1,
GPIO3B3_GPIO = 0,
GPIO3B3_CIF_CLKOUT,
GPIO3B2_SHIFT = 4,
GPIO3B2_MASK = 1,
GPIO3B2_GPIO = 0,
/* no muxes */
GPIO3B1_SHIFT = 2,
GPIO3B1_MASK = 1,
GPIO3B1_GPIO = 0,
GPIO3B1_SDMMC0_WRITE_PRT,
GPIO3B0_SHIFT = 0,
GPIO3B0_MASK = 1,
GPIO3B0_GPIO = 0,
GPIO3B0_SDMMC_DETECT_N,
};
/* GRF_GPIO3C_IOMUX */
enum {
GPIO3C7_SHIFT = 14,
GPIO3C7_MASK = 3,
GPIO3C7_GPIO = 0,
GPIO3C7_SDMMC1_WRITE_PRT,
GPIO3C7_RMII_CRS_DVALID,
GPIO3C7_RESERVED,
GPIO3C6_SHIFT = 12,
GPIO3C6_MASK = 3,
GPIO3C6_GPIO = 0,
GPIO3C6_SDMMC1_DECTN,
GPIO3C6_RMII_RX_ERR,
GPIO3C6_RESERVED,
GPIO3C5_SHIFT = 10,
GPIO3C5_MASK = 3,
GPIO3C5_GPIO = 0,
GPIO3C5_SDMMC1_CLKOUT,
GPIO3C5_RMII_CLKOUT,
GPIO3C5_RMII_CLKIN,
GPIO3C4_SHIFT = 8,
GPIO3C4_MASK = 3,
GPIO3C4_GPIO = 0,
GPIO3C4_SDMMC1_DATA3,
GPIO3C4_RMII_RXD1,
GPIO3C4_RESERVED,
GPIO3C3_SHIFT = 6,
GPIO3C3_MASK = 3,
GPIO3C3_GPIO = 0,
GPIO3C3_SDMMC1_DATA2,
GPIO3C3_RMII_RXD0,
GPIO3C3_RESERVED,
GPIO3C2_SHIFT = 4,
GPIO3C2_MASK = 3,
GPIO3C2_GPIO = 0,
GPIO3C2_SDMMC1_DATA1,
GPIO3C2_RMII_TXD0,
GPIO3C2_RESERVED,
GPIO3C1_SHIFT = 2,
GPIO3C1_MASK = 3,
GPIO3C1_GPIO = 0,
GPIO3C1_SDMMC1_DATA0,
GPIO3C1_RMII_TXD1,
GPIO3C1_RESERVED,
GPIO3C0_SHIFT = 0,
GPIO3C0_MASK = 3,
GPIO3C0_GPIO = 0,
GPIO3C0_SDMMC1_CMD,
GPIO3C0_RMII_TX_EN,
GPIO3C0_RESERVED,
};
/* GRF_GPIO3D_IOMUX */
enum {
GPIO3D6_SHIFT = 12,
GPIO3D6_MASK = 3,
GPIO3D6_GPIO = 0,
GPIO3D6_PWM_3,
GPIO3D6_JTAG_TMS,
GPIO3D6_HOST_DRV_VBUS,
GPIO3D5_SHIFT = 10,
GPIO3D5_MASK = 3,
GPIO3D5_GPIO = 0,
GPIO3D5_PWM_2,
GPIO3D5_JTAG_TCK,
GPIO3D5_OTG_DRV_VBUS,
GPIO3D4_SHIFT = 8,
GPIO3D4_MASK = 3,
GPIO3D4_GPIO = 0,
GPIO3D4_PWM_1,
GPIO3D4_JTAG_TRSTN,
GPIO3D3_SHIFT = 6,
GPIO3D3_MASK = 3,
GPIO3D3_GPIO = 0,
GPIO3D3_PWM_0,
GPIO3D2_SHIFT = 4,
GPIO3D2_MASK = 3,
GPIO3D2_GPIO = 0,
GPIO3D2_SDMMC1_INT_N,
GPIO3D1_SHIFT = 2,
GPIO3D1_MASK = 3,
GPIO3D1_GPIO = 0,
GPIO3D1_SDMMC1_BACKEND_PWR,
GPIO3D1_MII_MDCLK,
GPIO3D0_SHIFT = 0,
GPIO3D0_MASK = 3,
GPIO3D0_GPIO = 0,
GPIO3D0_SDMMC1_PWR_EN,
GPIO3D0_MII_MD,
};
/* GRF_SOC_CON0 */
enum {
HSADC_CLK_DIR_SHIFT = 15,
HSADC_CLK_DIR_MASK = 1,
HSADC_SEL_SHIFT = 14,
HSADC_SEL_MASK = 1,
NOC_REMAP_SHIFT = 12,
NOC_REMAP_MASK = 1,
EMMC_FLASH_SEL_SHIFT = 11,
EMMC_FLASH_SEL_MASK = 1,
TZPC_REVISION_SHIFT = 7,
TZPC_REVISION_MASK = 0xf,
L2CACHE_ACC_SHIFT = 5,
L2CACHE_ACC_MASK = 3,
L2RD_WAIT_SHIFT = 3,
L2RD_WAIT_MASK = 3,
IMEMRD_WAIT_SHIFT = 1,
IMEMRD_WAIT_MASK = 3,
};
/* GRF_SOC_CON1 */
enum {
RKI2C4_SEL_SHIFT = 15,
RKI2C4_SEL_MASK = 1,
RKI2C3_SEL_SHIFT = 14,
RKI2C3_SEL_MASK = 1,
RKI2C2_SEL_SHIFT = 13,
RKI2C2_SEL_MASK = 1,
RKI2C1_SEL_SHIFT = 12,
RKI2C1_SEL_MASK = 1,
RKI2C0_SEL_SHIFT = 11,
RKI2C0_SEL_MASK = 1,
VCODEC_SEL_SHIFT = 10,
VCODEC_SEL_MASK = 1,
PERI_EMEM_PAUSE_SHIFT = 9,
PERI_EMEM_PAUSE_MASK = 1,
PERI_USB_PAUSE_SHIFT = 8,
PERI_USB_PAUSE_MASK = 1,
SMC_MUX_MODE_0_SHIFT = 6,
SMC_MUX_MODE_0_MASK = 1,
SMC_SRAM_MW_0_SHIFT = 4,
SMC_SRAM_MW_0_MASK = 3,
SMC_REMAP_0_SHIFT = 3,
SMC_REMAP_0_MASK = 1,
SMC_A_GT_M0_SYNC_SHIFT = 2,
SMC_A_GT_M0_SYNC_MASK = 1,
EMAC_SPEED_SHIFT = 1,
EMAC_SPEEC_MASK = 1,
EMAC_MODE_SHIFT = 0,
EMAC_MODE_MASK = 1,
};
/* GRF_SOC_CON2 */
enum {
SDIO_CLK_OUT_SR_SHIFT = 15,
SDIO_CLK_OUT_SR_MASK = 1,
MEM_EMA_L2C_SHIFT = 11,
MEM_EMA_L2C_MASK = 7,
MEM_EMA_A9_SHIFT = 8,
MEM_EMA_A9_MASK = 7,
MSCH4_MAINDDR3_SHIFT = 7,
MSCH4_MAINDDR3_MASK = 1,
MSCH4_MAINDDR3_DDR3 = 1,
EMAC_NEWRCV_EN_SHIFT = 6,
EMAC_NEWRCV_EN_MASK = 1,
SW_ADDR15_EN_SHIFT = 5,
SW_ADDR15_EN_MASK = 1,
SW_ADDR16_EN_SHIFT = 4,
SW_ADDR16_EN_MASK = 1,
SW_ADDR17_EN_SHIFT = 3,
SW_ADDR17_EN_MASK = 1,
BANK2_TO_RANK_EN_SHIFT = 2,
BANK2_TO_RANK_EN_MASK = 1,
RANK_TO_ROW15_EN_SHIFT = 1,
RANK_TO_ROW15_EN_MASK = 1,
UPCTL_C_ACTIVE_IN_SHIFT = 0,
UPCTL_C_ACTIVE_IN_MASK = 1,
UPCTL_C_ACTIVE_IN_MAY = 0,
UPCTL_C_ACTIVE_IN_WILL,
};
/* GRF_DDRC_CON0 */
enum {
DDR_16BIT_EN_SHIFT = 15,
DDR_16BIT_EN_MASK = 1,
DTO_LB_SHIFT = 11,
DTO_LB_MASK = 3,
DTO_TE_SHIFT = 9,
DTO_TE_MASK = 3,
DTO_PDR_SHIFT = 7,
DTO_PDR_MASK = 3,
DTO_PDD_SHIFT = 5,
DTO_PDD_MASK = 3,
DTO_IOM_SHIFT = 3,
DTO_IOM_MASK = 3,
DTO_OE_SHIFT = 1,
DTO_OE_MASK = 3,
ATO_AE_SHIFT = 0,
ATO_AE_MASK = 1,
};
#endif

View file

@ -0,0 +1,134 @@
/*
* (C) Copyright 2016 Rockchip Electronics Co., Ltd
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef __SOC_ROCKCHIP_RK3328_GRF_H__
#define __SOC_ROCKCHIP_RK3328_GRF_H__
struct rk3328_grf_regs {
u32 gpio0a_iomux;
u32 gpio0b_iomux;
u32 gpio0c_iomux;
u32 gpio0d_iomux;
u32 gpio1a_iomux;
u32 gpio1b_iomux;
u32 gpio1c_iomux;
u32 gpio1d_iomux;
u32 gpio2a_iomux;
u32 gpio2bl_iomux;
u32 gpio2bh_iomux;
u32 gpio2cl_iomux;
u32 gpio2ch_iomux;
u32 gpio2d_iomux;
u32 gpio3al_iomux;
u32 gpio3ah_iomux;
u32 gpio3bl_iomux;
u32 gpio3bh_iomux;
u32 gpio3c_iomux;
u32 gpio3d_iomux;
u32 com_iomux;
u32 reserved1[(0x100 - 0x54) / 4];
u32 gpio0a_p;
u32 gpio0b_p;
u32 gpio0c_p;
u32 gpio0d_p;
u32 gpio1a_p;
u32 gpio1b_p;
u32 gpio1c_p;
u32 gpio1d_p;
u32 gpio2a_p;
u32 gpio2b_p;
u32 gpio2c_p;
u32 gpio2d_p;
u32 gpio3a_p;
u32 gpio3b_p;
u32 gpio3c_p;
u32 gpio3d_p;
u32 reserved2[(0x200 - 0x140) / 4];
u32 gpio0a_e;
u32 gpio0b_e;
u32 gpio0c_e;
u32 gpio0d_e;
u32 gpio1a_e;
u32 gpio1b_e;
u32 gpio1c_e;
u32 gpio1d_e;
u32 gpio2a_e;
u32 gpio2b_e;
u32 gpio2c_e;
u32 gpio2d_e;
u32 gpio3a_e;
u32 gpio3b_e;
u32 gpio3c_e;
u32 gpio3d_e;
u32 reserved3[(0x300 - 0x240) / 4];
u32 gpio0l_sr;
u32 gpio0h_sr;
u32 gpio1l_sr;
u32 gpio1h_sr;
u32 gpio2l_sr;
u32 gpio2h_sr;
u32 gpio3l_sr;
u32 gpio3h_sr;
u32 reserved4[(0x380 - 0x320) / 4];
u32 gpio0l_smt;
u32 gpio0h_smt;
u32 gpio1l_smt;
u32 gpio1h_smt;
u32 gpio2l_smt;
u32 gpio2h_smt;
u32 gpio3l_smt;
u32 gpio3h_smt;
u32 reserved5[(0x400 - 0x3a0) / 4];
u32 soc_con[11];
u32 reserved6[(0x480 - 0x42c) / 4];
u32 soc_status[5];
u32 reserved7[(0x4c0 - 0x494) / 4];
u32 otg3_con[2];
u32 reserved8[(0x500 - 0x4c8) / 4];
u32 cpu_con[2];
u32 reserved9[(0x520 - 0x508) / 4];
u32 cpu_status[2];
u32 reserved10[(0x5c8 - 0x528) / 4];
u32 os_reg[8];
u32 reserved11[(0x680 - 0x5e8) / 4];
u32 sig_detect_con;
u32 reserved12[3];
u32 sig_detect_status;
u32 reserved13[3];
u32 sig_detect_status_clr;
u32 reserved14[3];
u32 sdmmc_det_counter;
u32 reserved15[(0x700 - 0x6b4) / 4];
u32 host0_con[3];
u32 reserved16[(0x880 - 0x70c) / 4];
u32 otg_con0;
u32 reserved17[3];
u32 host0_status;
u32 reserved18[(0x900 - 0x894) / 4];
u32 mac_con[3];
u32 reserved19[(0xb00 - 0x90c) / 4];
u32 macphy_con[4];
u32 macphy_status;
};
check_member(rk3328_grf_regs, macphy_status, 0xb10);
struct rk3328_sgrf_regs {
u32 soc_con[6];
u32 reserved0[(0x100 - 0x18) / 4];
u32 dmac_con[6];
u32 reserved1[(0x180 - 0x118) / 4];
u32 fast_boot_addr;
u32 reserved2[(0x200 - 0x184) / 4];
u32 chip_fuse_con;
u32 reserved3[(0x280 - 0x204) / 4];
u32 hdcp_key_reg[8];
u32 hdcp_key_access_mask;
};
check_member(rk3328_sgrf_regs, hdcp_key_access_mask, 0x2a0);
#endif /* __SOC_ROCKCHIP_RK3328_GRF_H__ */

View file

@ -318,4 +318,122 @@ struct rk3399_pmusgrf_regs {
};
check_member(rk3399_pmusgrf_regs, slv_secure_con4, 0xe3d4);
enum {
/* GRF_GPIO2B_IOMUX */
GRF_GPIO2B1_SEL_SHIFT = 0,
GRF_GPIO2B1_SEL_MASK = 3 << GRF_GPIO2B1_SEL_SHIFT,
GRF_SPI2TPM_RXD = 1,
GRF_GPIO2B2_SEL_SHIFT = 2,
GRF_GPIO2B2_SEL_MASK = 3 << GRF_GPIO2B2_SEL_SHIFT,
GRF_SPI2TPM_TXD = 1,
GRF_GPIO2B3_SEL_SHIFT = 6,
GRF_GPIO2B3_SEL_MASK = 3 << GRF_GPIO2B3_SEL_SHIFT,
GRF_SPI2TPM_CLK = 1,
GRF_GPIO2B4_SEL_SHIFT = 8,
GRF_GPIO2B4_SEL_MASK = 3 << GRF_GPIO2B4_SEL_SHIFT,
GRF_SPI2TPM_CSN0 = 1,
/* GRF_GPIO3A_IOMUX */
GRF_GPIO3A4_SEL_SHIFT = 8,
GRF_GPIO3A4_SEL_MASK = 3 << GRF_GPIO3A4_SEL_SHIFT,
GRF_SPI0NORCODEC_RXD = 2,
GRF_GPIO3A5_SEL_SHIFT = 10,
GRF_GPIO3A5_SEL_MASK = 3 << GRF_GPIO3A5_SEL_SHIFT,
GRF_SPI0NORCODEC_TXD = 2,
GRF_GPIO3A6_SEL_SHIFT = 12,
GRF_GPIO3A6_SEL_MASK = 3 << GRF_GPIO3A6_SEL_SHIFT,
GRF_SPI0NORCODEC_CLK = 2,
GRF_GPIO3A7_SEL_SHIFT = 14,
GRF_GPIO3A7_SEL_MASK = 3 << GRF_GPIO3A7_SEL_SHIFT,
GRF_SPI0NORCODEC_CSN0 = 2,
/* GRF_GPIO3B_IOMUX */
GRF_GPIO3B0_SEL_SHIFT = 0,
GRF_GPIO3B0_SEL_MASK = 3 << GRF_GPIO3B0_SEL_SHIFT,
GRF_SPI0NORCODEC_CSN1 = 2,
/* GRF_GPIO4B_IOMUX */
GRF_GPIO4B0_SEL_SHIFT = 0,
GRF_GPIO4B0_SEL_MASK = 3 << GRF_GPIO4B0_SEL_SHIFT,
GRF_SDMMC_DATA0 = 1,
GRF_UART2DBGA_SIN = 2,
GRF_GPIO4B1_SEL_SHIFT = 2,
GRF_GPIO4B1_SEL_MASK = 3 << GRF_GPIO4B1_SEL_SHIFT,
GRF_SDMMC_DATA1 = 1,
GRF_UART2DBGA_SOUT = 2,
GRF_GPIO4B2_SEL_SHIFT = 4,
GRF_GPIO4B2_SEL_MASK = 3 << GRF_GPIO4B2_SEL_SHIFT,
GRF_SDMMC_DATA2 = 1,
GRF_GPIO4B3_SEL_SHIFT = 6,
GRF_GPIO4B3_SEL_MASK = 3 << GRF_GPIO4B3_SEL_SHIFT,
GRF_SDMMC_DATA3 = 1,
GRF_GPIO4B4_SEL_SHIFT = 8,
GRF_GPIO4B4_SEL_MASK = 3 << GRF_GPIO4B4_SEL_SHIFT,
GRF_SDMMC_CLKOUT = 1,
GRF_GPIO4B5_SEL_SHIFT = 10,
GRF_GPIO4B5_SEL_MASK = 3 << GRF_GPIO4B5_SEL_SHIFT,
GRF_SDMMC_CMD = 1,
/* GRF_GPIO4C_IOMUX */
GRF_GPIO4C0_SEL_SHIFT = 0,
GRF_GPIO4C0_SEL_MASK = 3 << GRF_GPIO4C0_SEL_SHIFT,
GRF_UART2DGBB_SIN = 2,
GRF_GPIO4C1_SEL_SHIFT = 2,
GRF_GPIO4C1_SEL_MASK = 3 << GRF_GPIO4C1_SEL_SHIFT,
GRF_UART2DGBB_SOUT = 2,
GRF_GPIO4C2_SEL_SHIFT = 4,
GRF_GPIO4C2_SEL_MASK = 3 << GRF_GPIO4C2_SEL_SHIFT,
GRF_PWM_0 = 1,
GRF_GPIO4C3_SEL_SHIFT = 6,
GRF_GPIO4C3_SEL_MASK = 3 << GRF_GPIO4C3_SEL_SHIFT,
GRF_UART2DGBC_SIN = 1,
GRF_GPIO4C4_SEL_SHIFT = 8,
GRF_GPIO4C4_SEL_MASK = 3 << GRF_GPIO4C4_SEL_SHIFT,
GRF_UART2DBGC_SOUT = 1,
GRF_GPIO4C6_SEL_SHIFT = 12,
GRF_GPIO4C6_SEL_MASK = 3 << GRF_GPIO4C6_SEL_SHIFT,
GRF_PWM_1 = 1,
/* GRF_SOC_CON7 */
GRF_UART_DBG_SEL_SHIFT = 10,
GRF_UART_DBG_SEL_MASK = 3 << GRF_UART_DBG_SEL_SHIFT,
GRF_UART_DBG_SEL_C = 2,
/* PMUGRF_GPIO0A_IOMUX */
PMUGRF_GPIO0A6_SEL_SHIFT = 12,
PMUGRF_GPIO0A6_SEL_MASK = 3 << PMUGRF_GPIO0A6_SEL_SHIFT,
PMUGRF_PWM_3A = 1,
/* PMUGRF_GPIO1A_IOMUX */
PMUGRF_GPIO1A7_SEL_SHIFT = 14,
PMUGRF_GPIO1A7_SEL_MASK = 3 << PMUGRF_GPIO1A7_SEL_SHIFT,
PMUGRF_SPI1EC_RXD = 2,
/* PMUGRF_GPIO1B_IOMUX */
PMUGRF_GPIO1B0_SEL_SHIFT = 0,
PMUGRF_GPIO1B0_SEL_MASK = 3 << PMUGRF_GPIO1B0_SEL_SHIFT,
PMUGRF_SPI1EC_TXD = 2,
PMUGRF_GPIO1B1_SEL_SHIFT = 2,
PMUGRF_GPIO1B1_SEL_MASK = 3 << PMUGRF_GPIO1B1_SEL_SHIFT,
PMUGRF_SPI1EC_CLK = 2,
PMUGRF_GPIO1B2_SEL_SHIFT = 4,
PMUGRF_GPIO1B2_SEL_MASK = 3 << PMUGRF_GPIO1B2_SEL_SHIFT,
PMUGRF_SPI1EC_CSN0 = 2,
PMUGRF_GPIO1B6_SEL_SHIFT = 12,
PMUGRF_GPIO1B6_SEL_MASK = 3 << PMUGRF_GPIO1B6_SEL_SHIFT,
PMUGRF_PWM_3B = 1,
PMUGRF_GPIO1B7_SEL_SHIFT = 14,
PMUGRF_GPIO1B7_SEL_MASK = 3 << PMUGRF_GPIO1B7_SEL_SHIFT,
PMUGRF_I2C0PMU_SDA = 2,
/* PMUGRF_GPIO1C_IOMUX */
PMUGRF_GPIO1C0_SEL_SHIFT = 0,
PMUGRF_GPIO1C0_SEL_MASK = 3 << PMUGRF_GPIO1C0_SEL_SHIFT,
PMUGRF_I2C0PMU_SCL = 2,
PMUGRF_GPIO1C3_SEL_SHIFT = 6,
PMUGRF_GPIO1C3_SEL_MASK = 3 << PMUGRF_GPIO1C3_SEL_SHIFT,
PMUGRF_PWM_2 = 1,
};
#endif /* __SOC_ROCKCHIP_RK3399_GRF_H__ */

View file

@ -0,0 +1,36 @@
/*
* Copyright (c) 2016 Heiko Stuebner <heiko@sntech.de>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _ASM_ARCH_PMU_RK3188_H
#define _ASM_ARCH_PMU_RK3188_H
struct rk3188_pmu {
u32 wakeup_cfg[2];
u32 pwrdn_con;
u32 pwrdn_st;
u32 int_con;
u32 int_st;
u32 misc_con;
u32 osc_cnt;
u32 pll_cnt;
u32 pmu_cnt;
u32 ddrio_pwron_cnt;
u32 wakeup_rst_clr_cnt;
u32 scu_pwrdwn_cnt;
u32 scu_pwrup_cnt;
u32 misc_con1;
u32 gpio0_con;
u32 sys_reg[4];
u32 reserved0[4];
u32 stop_int_dly;
u32 gpio0_p[2];
};
check_member(rk3188_pmu, gpio0_p[1], 0x0068);
#endif

View file

@ -0,0 +1,119 @@
/*
* Copyright (C) 2016-2017 Rockchip Electronics Co., Ltd
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _ASM_ARCH_SDRAM_RK3399_H
#define _ASM_ARCH_SDRAM_RK3399_H
enum {
DDR3 = 0x3,
LPDDR2 = 0x5,
LPDDR3 = 0x6,
LPDDR4 = 0x7,
UNUSED = 0xFF
};
struct rk3399_ddr_pctl_regs {
u32 denali_ctl[332];
};
struct rk3399_ddr_publ_regs {
u32 denali_phy[959];
};
struct rk3399_ddr_pi_regs {
u32 denali_pi[200];
};
struct rk3399_msch_regs {
u32 coreid;
u32 revisionid;
u32 ddrconf;
u32 ddrsize;
u32 ddrtiminga0;
u32 ddrtimingb0;
u32 ddrtimingc0;
u32 devtodev0;
u32 reserved0[(0x110 - 0x20) / 4];
u32 ddrmode;
u32 reserved1[(0x1000 - 0x114) / 4];
u32 agingx0;
};
struct rk3399_msch_timings {
u32 ddrtiminga0;
u32 ddrtimingb0;
u32 ddrtimingc0;
u32 devtodev0;
u32 ddrmode;
u32 agingx0;
};
struct rk3399_ddr_cic_regs {
u32 cic_ctrl0;
u32 cic_ctrl1;
u32 cic_idle_th;
u32 cic_cg_wait_th;
u32 cic_status0;
u32 cic_status1;
u32 cic_ctrl2;
u32 cic_ctrl3;
u32 cic_ctrl4;
};
/* DENALI_CTL_00 */
#define START 1
/* DENALI_CTL_68 */
#define PWRUP_SREFRESH_EXIT (1 << 16)
/* DENALI_CTL_274 */
#define MEM_RST_VALID 1
struct rk3399_sdram_channel {
unsigned int rank;
/* dram column number, 0 means this channel is invalid */
unsigned int col;
/* dram bank number, 3:8bank, 2:4bank */
unsigned int bk;
/* channel buswidth, 2:32bit, 1:16bit, 0:8bit */
unsigned int bw;
/* die buswidth, 2:32bit, 1:16bit, 0:8bit */
unsigned int dbw;
/*
* row_3_4 = 1: 6Gb or 12Gb die
* row_3_4 = 0: normal die, power of 2
*/
unsigned int row_3_4;
unsigned int cs0_row;
unsigned int cs1_row;
unsigned int ddrconfig;
struct rk3399_msch_timings noc_timings;
};
struct rk3399_base_params {
unsigned int ddr_freq;
unsigned int dramtype;
unsigned int num_channels;
unsigned int stride;
unsigned int odt;
};
struct rk3399_sdram_params {
struct rk3399_sdram_channel ch[2];
struct rk3399_base_params base;
struct rk3399_ddr_pctl_regs pctl_regs;
struct rk3399_ddr_pi_regs pi_regs;
struct rk3399_ddr_publ_regs phy_regs;
};
#define PI_CA_TRAINING (1 << 0)
#define PI_WRITE_LEVELING (1 << 1)
#define PI_READ_GATE_TRAINING (1 << 2)
#define PI_READ_LEVELING (1 << 3)
#define PI_WDQ_LEVELING (1 << 4)
#define PI_FULL_TRAINING 0xff
#endif

View file

@ -11,6 +11,21 @@ config ROCKCHIP_RK3036
and video codec support. Peripherals include Gigabit Ethernet,
USB2 host and OTG, SDIO, I2S, UART, SPI, I2C and PWMs.
config ROCKCHIP_RK3188
bool "Support Rockchip RK3188"
select CPU_V7
select SUPPORT_SPL
select SUPPORT_TPL
select SPL
select TPL
select ROCKCHIP_BROM_HELPER
help
The Rockchip RK3188 is a ARM-based SoC with a quad-core Cortex-A9
including NEON and GPU, 512KB L2 cache, Mali-400 graphics, two
video interfaces, several memory options and video codec support.
Peripherals include Fast Ethernet, USB2 host and OTG, SDIO, I2S,
UART, SPI, I2C and PWMs.
config ROCKCHIP_RK3288
bool "Support Rockchip RK3288"
select CPU_V7
@ -23,9 +38,22 @@ config ROCKCHIP_RK3288
and video codec support. Peripherals include Gigabit Ethernet,
USB2 host and OTG, SDIO, I2S, UARTs, SPI, I2C and PWMs.
config ROCKCHIP_RK3328
bool "Support Rockchip RK3328"
select ARM64
help
The Rockchip RK3328 is a ARM-based SoC with a quad-core Cortex-A53.
including NEON and GPU, 1MB L2 cache, Mali-T7 graphics, two
video interfaces supporting HDMI and eDP, several DDR3 options
and video codec support. Peripherals include Gigabit Ethernet,
USB2 host and OTG, SDIO, I2S, UARTs, SPI, I2C and PWMs.
config ROCKCHIP_RK3399
bool "Support Rockchip RK3399"
select ARM64
select SUPPORT_SPL
select SPL
select SPL_SEPARATE_BSS
help
The Rockchip RK3399 is a ARM-based SoC with a dual-core Cortex-A72
and quad-core Cortex-A53.
@ -37,15 +65,21 @@ config ROCKCHIP_RK3399
config ROCKCHIP_SPL_BACK_TO_BROM
bool "SPL returns to bootrom"
default y if ROCKCHIP_RK3036
select ROCKCHIP_BROM_HELPER
help
Rockchip SoCs have ability to load SPL & U-Boot binary. If enabled,
SPL will return to the boot rom, which will then load the U-Boot
binary to keep going on.
config ROCKCHIP_BROM_HELPER
bool
config SPL_MMC_SUPPORT
default y if !ROCKCHIP_SPL_BACK_TO_BROM
source "arch/arm/mach-rockchip/rk3036/Kconfig"
source "arch/arm/mach-rockchip/rk3188/Kconfig"
source "arch/arm/mach-rockchip/rk3288/Kconfig"
source "arch/arm/mach-rockchip/rk3328/Kconfig"
source "arch/arm/mach-rockchip/rk3399/Kconfig"
endif

View file

@ -4,11 +4,17 @@
# SPDX-License-Identifier: GPL-2.0+
#
ifdef CONFIG_SPL_BUILD
ifdef CONFIG_TPL_BUILD
obj-$(CONFIG_ROCKCHIP_RK3188) += rk3188-board-tpl.o
obj-$(CONFIG_ROCKCHIP_BROM_HELPER) += save_boot_param.o
else ifdef CONFIG_SPL_BUILD
obj-$(CONFIG_ROCKCHIP_RK3036) += rk3036-board-spl.o
obj-$(CONFIG_ROCKCHIP_RK3188) += rk3188-board-spl.o
obj-$(CONFIG_ROCKCHIP_RK3288) += rk3288-board-spl.o
obj-$(CONFIG_ROCKCHIP_SPL_BACK_TO_BROM) += save_boot_param.o
obj-$(CONFIG_ROCKCHIP_RK3399) += rk3399-board-spl.o
obj-$(CONFIG_ROCKCHIP_BROM_HELPER) += save_boot_param.o
else
obj-$(CONFIG_ROCKCHIP_RK3188) += rk3188-board.o
obj-$(CONFIG_ROCKCHIP_RK3288) += rk3288-board.o
obj-$(CONFIG_ROCKCHIP_RK3036) += rk3036-board.o
endif
@ -16,5 +22,11 @@ ifndef CONFIG_ARM64
obj-y += rk_timer.o
endif
obj-$(CONFIG_ROCKCHIP_RK3036) += rk3036/
ifndef CONFIG_TPL_BUILD
obj-$(CONFIG_ROCKCHIP_RK3188) += rk3188/
endif
obj-$(CONFIG_ROCKCHIP_RK3288) += rk3288/
obj-$(CONFIG_ROCKCHIP_RK3328) += rk3328/
obj-$(CONFIG_ROCKCHIP_RK3399) += rk3399/

View file

@ -7,6 +7,7 @@
#include <common.h>
#include <debug_uart.h>
#include <asm/io.h>
#include <asm/arch/bootrom.h>
#include <asm/arch/grf_rk3036.h>
#include <asm/arch/hardware.h>
#include <asm/arch/sdram_rk3036.h>
@ -20,8 +21,6 @@ static struct rk3036_grf * const grf = (void *)GRF_BASE;
#define DEBUG_UART_BASE 0x20068000
extern void back_to_bootrom(void);
void board_init_f(ulong dummy)
{
#ifdef EARLY_DEBUG

View file

@ -0,0 +1,218 @@
/*
* (C) Copyright 2015 Google, Inc
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <debug_uart.h>
#include <dm.h>
#include <fdtdec.h>
#include <led.h>
#include <malloc.h>
#include <ram.h>
#include <spl.h>
#include <asm/gpio.h>
#include <asm/io.h>
#include <asm/arch/bootrom.h>
#include <asm/arch/clock.h>
#include <asm/arch/hardware.h>
#include <asm/arch/periph.h>
#include <asm/arch/pmu_rk3188.h>
#include <asm/arch/sdram.h>
#include <asm/arch/timer.h>
#include <dm/pinctrl.h>
#include <dm/root.h>
#include <dm/test.h>
#include <dm/util.h>
#include <power/regulator.h>
#include <syscon.h>
DECLARE_GLOBAL_DATA_PTR;
u32 spl_boot_device(void)
{
#if !CONFIG_IS_ENABLED(OF_PLATDATA)
const void *blob = gd->fdt_blob;
struct udevice *dev;
const char *bootdev;
int node;
int ret;
bootdev = fdtdec_get_config_string(blob, "u-boot,boot0");
debug("Boot device %s\n", bootdev);
if (!bootdev)
goto fallback;
node = fdt_path_offset(blob, bootdev);
if (node < 0) {
debug("node=%d\n", node);
goto fallback;
}
ret = device_get_global_by_of_offset(node, &dev);
if (ret) {
debug("device at node %s/%d not found: %d\n", bootdev, node,
ret);
goto fallback;
}
debug("Found device %s\n", dev->name);
switch (device_get_uclass_id(dev)) {
case UCLASS_SPI_FLASH:
return BOOT_DEVICE_SPI;
case UCLASS_MMC:
return BOOT_DEVICE_MMC1;
default:
debug("Booting from device uclass '%s' not supported\n",
dev_get_uclass_name(dev));
}
fallback:
#endif
return BOOT_DEVICE_MMC1;
}
u32 spl_boot_mode(const u32 boot_device)
{
return MMCSD_MODE_RAW;
}
void board_init_f(ulong dummy)
{
struct udevice *pinctrl, *dev;
struct rk3188_pmu *pmu;
int ret;
/* Example code showing how to enable the debug UART on RK3188 */
#ifdef EARLY_UART
#include <asm/arch/grf_rk3188.h>
/* Enable early UART on the RK3188 */
#define GRF_BASE 0x20008000
struct rk3188_grf * const grf = (void *)GRF_BASE;
rk_clrsetreg(&grf->gpio1b_iomux,
GPIO1B1_MASK << GPIO1B1_SHIFT |
GPIO1B0_MASK << GPIO1B0_SHIFT,
GPIO1B1_UART2_SOUT << GPIO1B1_SHIFT |
GPIO1B0_UART2_SIN << GPIO1B0_SHIFT);
/*
* Debug UART can be used from here if required:
*
* debug_uart_init();
* printch('a');
* printhex8(0x1234);
* printascii("string");
*/
debug_uart_init();
printch('s');
printch('p');
printch('l');
printch('\n');
#endif
ret = spl_init();
if (ret) {
debug("spl_init() failed: %d\n", ret);
hang();
}
rockchip_timer_init();
ret = rockchip_get_clk(&dev);
if (ret) {
debug("CLK init failed: %d\n", ret);
return;
}
/*
* Recover the bootrom's stackpointer.
* For whatever reason needs to run after rockchip_get_clk.
*/
pmu = syscon_get_first_range(ROCKCHIP_SYSCON_PMU);
if (IS_ERR(pmu))
error("pmu syscon returned %ld\n", PTR_ERR(pmu));
SAVE_SP_ADDR = readl(&pmu->sys_reg[2]);
ret = uclass_get_device(UCLASS_PINCTRL, 0, &pinctrl);
if (ret) {
debug("Pinctrl init failed: %d\n", ret);
return;
}
ret = uclass_get_device(UCLASS_RAM, 0, &dev);
if (ret) {
debug("DRAM init failed: %d\n", ret);
return;
}
#if defined(CONFIG_ROCKCHIP_SPL_BACK_TO_BROM) && !defined(CONFIG_SPL_BOARD_INIT)
back_to_bootrom();
#endif
}
static int setup_led(void)
{
#ifdef CONFIG_SPL_LED
struct udevice *dev;
char *led_name;
int ret;
led_name = fdtdec_get_config_string(gd->fdt_blob, "u-boot,boot-led");
if (!led_name)
return 0;
ret = led_get_by_label(led_name, &dev);
if (ret) {
debug("%s: get=%d\n", __func__, ret);
return ret;
}
ret = led_set_on(dev, 1);
if (ret)
return ret;
#endif
return 0;
}
void spl_board_init(void)
{
struct udevice *pinctrl;
int ret;
ret = setup_led();
if (ret) {
debug("LED ret=%d\n", ret);
hang();
}
ret = uclass_get_device(UCLASS_PINCTRL, 0, &pinctrl);
if (ret) {
debug("%s: Cannot find pinctrl device\n", __func__);
goto err;
}
#ifdef CONFIG_SPL_MMC_SUPPORT
ret = pinctrl_request_noflags(pinctrl, PERIPH_ID_SDCARD);
if (ret) {
debug("%s: Failed to set up SD card\n", __func__);
goto err;
}
#endif
/* Enable debug UART */
ret = pinctrl_request_noflags(pinctrl, PERIPH_ID_UART_DBG);
if (ret) {
debug("%s: Failed to set up console UART\n", __func__);
goto err;
}
preloader_console_init();
#ifdef CONFIG_ROCKCHIP_SPL_BACK_TO_BROM
back_to_bootrom();
#endif
return;
err:
printf("spl_board_init: Error %d\n", ret);
/* No way to report error here */
hang();
}

View file

@ -0,0 +1,86 @@
/*
* (C) Copyright 2015 Google, Inc
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <debug_uart.h>
#include <spl.h>
#include <asm/io.h>
#include <asm/arch/bootrom.h>
#include <asm/arch/pmu_rk3188.h>
DECLARE_GLOBAL_DATA_PTR;
/* track how often we were entered */
static int rk3188_num_entries __attribute__ ((section(".data")));
#define PMU_BASE 0x20004000
#define TPL_ENTRY 0x10080C00
static void jump_to_spl(void)
{
typedef void __noreturn (*image_entry_noargs_t)(void);
struct rk3188_pmu * const pmu = (void *)PMU_BASE;
image_entry_noargs_t tpl_entry =
(image_entry_noargs_t)(unsigned long)TPL_ENTRY;
/* Store the SAVE_SP_ADDR in a location shared with TPL. */
writel(SAVE_SP_ADDR, &pmu->sys_reg[2]);
tpl_entry();
}
void board_init_f(ulong dummy)
{
/* Example code showing how to enable the debug UART on RK3188 */
#ifdef EARLY_UART
#include <asm/arch/grf_rk3188.h>
/* Enable early UART on the RK3188 */
#define GRF_BASE 0x20008000
struct rk3188_grf * const grf = (void *)GRF_BASE;
rk_clrsetreg(&grf->gpio1b_iomux,
GPIO1B1_MASK << GPIO1B1_SHIFT |
GPIO1B0_MASK << GPIO1B0_SHIFT,
GPIO1B1_UART2_SOUT << GPIO1B1_SHIFT |
GPIO1B0_UART2_SIN << GPIO1B0_SHIFT);
/*
* Debug UART can be used from here if required:
*
* debug_uart_init();
* printch('a');
* printhex8(0x1234);
* printascii("string");
*/
debug_uart_init();
printch('t');
printch('p');
printch('l');
printch('-');
printch(rk3188_num_entries + 1 + '0');
printch('\n');
#endif
rk3188_num_entries++;
if (rk3188_num_entries == 1) {
/*
* The original loader did some very basic integrity
* checking at this point, but the remaining few bytes
* could be used for any improvement making sense
* really early on.
*/
back_to_bootrom();
} else {
/*
* TPL part of the loader should now wait for us
* at offset 0xC00 in the sram. Should never return
* from there.
*/
jump_to_spl();
}
}

View file

@ -0,0 +1,71 @@
/*
* (C) Copyright 2015 Google, Inc
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <clk.h>
#include <dm.h>
#include <ram.h>
#include <syscon.h>
#include <asm/io.h>
#include <asm/arch/clock.h>
#include <asm/arch/periph.h>
#include <asm/arch/pmu_rk3288.h>
#include <asm/arch/boot_mode.h>
#include <asm/gpio.h>
#include <dm/pinctrl.h>
DECLARE_GLOBAL_DATA_PTR;
int board_init(void)
{
#if defined(CONFIG_ROCKCHIP_SPL_BACK_TO_BROM)
struct udevice *pinctrl;
int ret;
/*
* We need to implement sdcard iomux here for the further
* initialization, otherwise, it'll hit sdcard command sending
* timeout exception.
*/
ret = uclass_get_device(UCLASS_PINCTRL, 0, &pinctrl);
if (ret) {
debug("%s: Cannot find pinctrl device\n", __func__);
goto err;
}
ret = pinctrl_request_noflags(pinctrl, PERIPH_ID_SDCARD);
if (ret) {
debug("%s: Failed to set up SD card\n", __func__);
goto err;
}
return 0;
err:
printf("board_init: Error %d\n", ret);
/* No way to report error here */
hang();
return -1;
#else
return 0;
#endif
}
int dram_init(void)
{
/* FIXME: read back ram size from sys_reg2 */
gd->ram_size = 0x40000000;
return 0;
}
#ifndef CONFIG_SYS_DCACHE_OFF
void enable_caches(void)
{
/* Enable D-cache. I-cache is already enabled in start.S */
dcache_enable();
}
#endif

View file

@ -0,0 +1,24 @@
if ROCKCHIP_RK3188
config SYS_SOC
default "rockchip"
config SYS_MALLOC_F_LEN
default 0x0800
config SPL_LIBCOMMON_SUPPORT
default y
config SPL_LIBGENERIC_SUPPORT
default y
config SPL_SERIAL_SUPPORT
default y
config TPL_LIBCOMMON_SUPPORT
default y
config TPL_SERIAL_SUPPORT
default y
endif

View file

@ -0,0 +1,11 @@
#
# Copyright (c) 2015 Google, Inc
#
# SPDX-License-Identifier: GPL-2.0+
#
ifndef CONFIG_TPL_BUILD
obj-y += clk_rk3188.o
obj-y += sdram_rk3188.o
obj-y += syscon_rk3188.o
endif

View file

@ -0,0 +1,33 @@
/*
* Copyright (C) 2015 Google, Inc
* Written by Simon Glass <sjg@chromium.org>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <dm.h>
#include <syscon.h>
#include <asm/arch/clock.h>
#include <asm/arch/cru_rk3188.h>
int rockchip_get_clk(struct udevice **devp)
{
return uclass_get_device_by_driver(UCLASS_CLK,
DM_GET_DRIVER(rockchip_rk3188_cru), devp);
}
void *rockchip_get_cru(void)
{
struct rk3188_clk_priv *priv;
struct udevice *dev;
int ret;
ret = rockchip_get_clk(&dev);
if (ret)
return ERR_PTR(ret);
priv = dev_get_priv(dev);
return priv->cru;
}

View file

@ -0,0 +1,995 @@
/*
* (C) Copyright 2015 Google, Inc
* Copyright 2014 Rockchip Inc.
*
* SPDX-License-Identifier: GPL-2.0
*
* Adapted from the very similar rk3288 ddr init.
*/
#include <common.h>
#include <clk.h>
#include <dm.h>
#include <dt-structs.h>
#include <errno.h>
#include <ram.h>
#include <regmap.h>
#include <syscon.h>
#include <asm/io.h>
#include <asm/arch/clock.h>
#include <asm/arch/cru_rk3188.h>
#include <asm/arch/ddr_rk3188.h>
#include <asm/arch/grf_rk3188.h>
#include <asm/arch/pmu_rk3188.h>
#include <asm/arch/sdram.h>
#include <linux/err.h>
DECLARE_GLOBAL_DATA_PTR;
struct chan_info {
struct rk3288_ddr_pctl *pctl;
struct rk3288_ddr_publ *publ;
struct rk3188_msch *msch;
};
struct dram_info {
struct chan_info chan[1];
struct ram_info info;
struct clk ddr_clk;
struct rk3188_cru *cru;
struct rk3188_grf *grf;
struct rk3188_sgrf *sgrf;
struct rk3188_pmu *pmu;
};
struct rk3188_sdram_params {
#if CONFIG_IS_ENABLED(OF_PLATDATA)
struct dtd_rockchip_rk3188_dmc of_plat;
#endif
struct rk3288_sdram_channel ch[2];
struct rk3288_sdram_pctl_timing pctl_timing;
struct rk3288_sdram_phy_timing phy_timing;
struct rk3288_base_params base;
int num_channels;
struct regmap *map;
};
const int ddrconf_table[] = {
/*
* [5:4] row(13+n)
* [1:0] col(9+n), assume bw=2
* row col,bw
*/
0,
((2 << DDRCONF_ROW_SHIFT) | 1 << DDRCONF_COL_SHIFT),
((1 << DDRCONF_ROW_SHIFT) | 1 << DDRCONF_COL_SHIFT),
((0 << DDRCONF_ROW_SHIFT) | 1 << DDRCONF_COL_SHIFT),
((2 << DDRCONF_ROW_SHIFT) | 2 << DDRCONF_COL_SHIFT),
((1 << DDRCONF_ROW_SHIFT) | 2 << DDRCONF_COL_SHIFT),
((0 << DDRCONF_ROW_SHIFT) | 2 << DDRCONF_COL_SHIFT),
((1 << DDRCONF_ROW_SHIFT) | 0 << DDRCONF_COL_SHIFT),
((0 << DDRCONF_ROW_SHIFT) | 0 << DDRCONF_COL_SHIFT),
0,
0,
0,
0,
0,
0,
0,
};
#define TEST_PATTEN 0x5aa5f00f
#define DQS_GATE_TRAINING_ERROR_RANK0 (1 << 4)
#define DQS_GATE_TRAINING_ERROR_RANK1 (2 << 4)
#ifdef CONFIG_SPL_BUILD
static void copy_to_reg(u32 *dest, const u32 *src, u32 n)
{
int i;
for (i = 0; i < n / sizeof(u32); i++) {
writel(*src, dest);
src++;
dest++;
}
}
static void ddr_reset(struct rk3188_cru *cru, u32 ch, u32 ctl, u32 phy)
{
u32 phy_ctl_srstn_shift = 13;
u32 ctl_psrstn_shift = 11;
u32 ctl_srstn_shift = 10;
u32 phy_psrstn_shift = 9;
u32 phy_srstn_shift = 8;
rk_clrsetreg(&cru->cru_softrst_con[5],
1 << phy_ctl_srstn_shift | 1 << ctl_psrstn_shift |
1 << ctl_srstn_shift | 1 << phy_psrstn_shift |
1 << phy_srstn_shift,
phy << phy_ctl_srstn_shift | ctl << ctl_psrstn_shift |
ctl << ctl_srstn_shift | phy << phy_psrstn_shift |
phy << phy_srstn_shift);
}
static void ddr_phy_ctl_reset(struct rk3188_cru *cru, u32 ch, u32 n)
{
u32 phy_ctl_srstn_shift = 13;
rk_clrsetreg(&cru->cru_softrst_con[5],
1 << phy_ctl_srstn_shift, n << phy_ctl_srstn_shift);
}
static void phy_pctrl_reset(struct rk3188_cru *cru,
struct rk3288_ddr_publ *publ,
int channel)
{
int i;
ddr_reset(cru, channel, 1, 1);
udelay(1);
clrbits_le32(&publ->acdllcr, ACDLLCR_DLLSRST);
for (i = 0; i < 4; i++)
clrbits_le32(&publ->datx8[i].dxdllcr, DXDLLCR_DLLSRST);
udelay(10);
setbits_le32(&publ->acdllcr, ACDLLCR_DLLSRST);
for (i = 0; i < 4; i++)
setbits_le32(&publ->datx8[i].dxdllcr, DXDLLCR_DLLSRST);
udelay(10);
ddr_reset(cru, channel, 1, 0);
udelay(10);
ddr_reset(cru, channel, 0, 0);
udelay(10);
}
static void phy_dll_bypass_set(struct rk3288_ddr_publ *publ,
u32 freq)
{
int i;
if (freq <= 250000000) {
if (freq <= 150000000)
clrbits_le32(&publ->dllgcr, SBIAS_BYPASS);
else
setbits_le32(&publ->dllgcr, SBIAS_BYPASS);
setbits_le32(&publ->acdllcr, ACDLLCR_DLLDIS);
for (i = 0; i < 4; i++)
setbits_le32(&publ->datx8[i].dxdllcr,
DXDLLCR_DLLDIS);
setbits_le32(&publ->pir, PIR_DLLBYP);
} else {
clrbits_le32(&publ->dllgcr, SBIAS_BYPASS);
clrbits_le32(&publ->acdllcr, ACDLLCR_DLLDIS);
for (i = 0; i < 4; i++) {
clrbits_le32(&publ->datx8[i].dxdllcr,
DXDLLCR_DLLDIS);
}
clrbits_le32(&publ->pir, PIR_DLLBYP);
}
}
static void dfi_cfg(struct rk3288_ddr_pctl *pctl, u32 dramtype)
{
writel(DFI_INIT_START, &pctl->dfistcfg0);
writel(DFI_DRAM_CLK_SR_EN | DFI_DRAM_CLK_DPD_EN,
&pctl->dfistcfg1);
writel(DFI_PARITY_INTR_EN | DFI_PARITY_EN, &pctl->dfistcfg2);
writel(7 << TLP_RESP_TIME_SHIFT | LP_SR_EN | LP_PD_EN,
&pctl->dfilpcfg0);
writel(2 << TCTRL_DELAY_TIME_SHIFT, &pctl->dfitctrldelay);
writel(1 << TPHY_WRDATA_TIME_SHIFT, &pctl->dfitphywrdata);
writel(0xf << TPHY_RDLAT_TIME_SHIFT, &pctl->dfitphyrdlat);
writel(2 << TDRAM_CLK_DIS_TIME_SHIFT, &pctl->dfitdramclkdis);
writel(2 << TDRAM_CLK_EN_TIME_SHIFT, &pctl->dfitdramclken);
writel(1, &pctl->dfitphyupdtype0);
/* cs0 and cs1 write odt enable */
writel((RANK0_ODT_WRITE_SEL | RANK1_ODT_WRITE_SEL),
&pctl->dfiodtcfg);
/* odt write length */
writel(7 << ODT_LEN_BL8_W_SHIFT, &pctl->dfiodtcfg1);
/* phyupd and ctrlupd disabled */
writel(0, &pctl->dfiupdcfg);
}
static void ddr_set_enable(struct rk3188_grf *grf, uint channel, bool enable)
{
uint val = 0;
if (enable)
val = 1 << DDR_16BIT_EN_SHIFT;
rk_clrsetreg(&grf->ddrc_con0, 1 << DDR_16BIT_EN_SHIFT, val);
}
static void ddr_set_ddr3_mode(struct rk3188_grf *grf, uint channel,
bool ddr3_mode)
{
uint mask, val;
mask = MSCH4_MAINDDR3_MASK << MSCH4_MAINDDR3_SHIFT;
val = ddr3_mode << MSCH4_MAINDDR3_SHIFT;
rk_clrsetreg(&grf->soc_con2, mask, val);
}
static void ddr_rank_2_row15en(struct rk3188_grf *grf, bool enable)
{
uint mask, val;
mask = RANK_TO_ROW15_EN_MASK << RANK_TO_ROW15_EN_SHIFT;
val = enable << RANK_TO_ROW15_EN_SHIFT;
rk_clrsetreg(&grf->soc_con2, mask, val);
}
static void pctl_cfg(int channel, struct rk3288_ddr_pctl *pctl,
struct rk3188_sdram_params *sdram_params,
struct rk3188_grf *grf)
{
copy_to_reg(&pctl->togcnt1u, &sdram_params->pctl_timing.togcnt1u,
sizeof(sdram_params->pctl_timing));
switch (sdram_params->base.dramtype) {
case DDR3:
if (sdram_params->phy_timing.mr[1] & DDR3_DLL_DISABLE) {
writel(sdram_params->pctl_timing.tcl - 3,
&pctl->dfitrddataen);
} else {
writel(sdram_params->pctl_timing.tcl - 2,
&pctl->dfitrddataen);
}
writel(sdram_params->pctl_timing.tcwl - 1,
&pctl->dfitphywrlat);
writel(0 << MDDR_LPDDR2_CLK_STOP_IDLE_SHIFT | DDR3_EN |
DDR2_DDR3_BL_8 | (6 - 4) << TFAW_SHIFT | PD_EXIT_SLOW |
1 << PD_TYPE_SHIFT | 0 << PD_IDLE_SHIFT,
&pctl->mcfg);
ddr_set_ddr3_mode(grf, channel, true);
ddr_set_enable(grf, channel, true);
break;
}
setbits_le32(&pctl->scfg, 1);
}
static void phy_cfg(const struct chan_info *chan, int channel,
struct rk3188_sdram_params *sdram_params)
{
struct rk3288_ddr_publ *publ = chan->publ;
struct rk3188_msch *msch = chan->msch;
uint ddr_freq_mhz = sdram_params->base.ddr_freq / 1000000;
u32 dinit2;
int i;
dinit2 = DIV_ROUND_UP(ddr_freq_mhz * 200000, 1000);
/* DDR PHY Timing */
copy_to_reg(&publ->dtpr[0], &sdram_params->phy_timing.dtpr0,
sizeof(sdram_params->phy_timing));
writel(sdram_params->base.noc_timing, &msch->ddrtiming);
writel(0x3f, &msch->readlatency);
writel(DIV_ROUND_UP(ddr_freq_mhz * 5120, 1000) << PRT_DLLLOCK_SHIFT |
DIV_ROUND_UP(ddr_freq_mhz * 50, 1000) << PRT_DLLSRST_SHIFT |
8 << PRT_ITMSRST_SHIFT, &publ->ptr[0]);
writel(DIV_ROUND_UP(ddr_freq_mhz * 500000, 1000) << PRT_DINIT0_SHIFT |
DIV_ROUND_UP(ddr_freq_mhz * 400, 1000) << PRT_DINIT1_SHIFT,
&publ->ptr[1]);
writel(min(dinit2, 0x1ffffU) << PRT_DINIT2_SHIFT |
DIV_ROUND_UP(ddr_freq_mhz * 1000, 1000) << PRT_DINIT3_SHIFT,
&publ->ptr[2]);
switch (sdram_params->base.dramtype) {
case DDR3:
clrbits_le32(&publ->pgcr, 0x1f);
clrsetbits_le32(&publ->dcr, DDRMD_MASK << DDRMD_SHIFT,
DDRMD_DDR3 << DDRMD_SHIFT);
break;
}
if (sdram_params->base.odt) {
/*dynamic RTT enable */
for (i = 0; i < 4; i++)
setbits_le32(&publ->datx8[i].dxgcr, DQSRTT | DQRTT);
} else {
/*dynamic RTT disable */
for (i = 0; i < 4; i++)
clrbits_le32(&publ->datx8[i].dxgcr, DQSRTT | DQRTT);
}
}
static void phy_init(struct rk3288_ddr_publ *publ)
{
setbits_le32(&publ->pir, PIR_INIT | PIR_DLLSRST
| PIR_DLLLOCK | PIR_ZCAL | PIR_ITMSRST | PIR_CLRSR);
udelay(1);
while ((readl(&publ->pgsr) &
(PGSR_IDONE | PGSR_DLDONE | PGSR_ZCDONE)) !=
(PGSR_IDONE | PGSR_DLDONE | PGSR_ZCDONE))
;
}
static void send_command(struct rk3288_ddr_pctl *pctl, u32 rank,
u32 cmd, u32 arg)
{
writel((START_CMD | (rank << 20) | arg | cmd), &pctl->mcmd);
udelay(1);
while (readl(&pctl->mcmd) & START_CMD)
;
}
static inline void send_command_op(struct rk3288_ddr_pctl *pctl,
u32 rank, u32 cmd, u32 ma, u32 op)
{
send_command(pctl, rank, cmd, (ma & LPDDR2_MA_MASK) << LPDDR2_MA_SHIFT |
(op & LPDDR2_OP_MASK) << LPDDR2_OP_SHIFT);
}
static void memory_init(struct rk3288_ddr_publ *publ,
u32 dramtype)
{
setbits_le32(&publ->pir,
(PIR_INIT | PIR_DRAMINIT | PIR_LOCKBYP
| PIR_ZCALBYP | PIR_CLRSR | PIR_ICPC
| (dramtype == DDR3 ? PIR_DRAMRST : 0)));
udelay(1);
while ((readl(&publ->pgsr) & (PGSR_IDONE | PGSR_DLDONE))
!= (PGSR_IDONE | PGSR_DLDONE))
;
}
static void move_to_config_state(struct rk3288_ddr_publ *publ,
struct rk3288_ddr_pctl *pctl)
{
unsigned int state;
while (1) {
state = readl(&pctl->stat) & PCTL_STAT_MSK;
switch (state) {
case LOW_POWER:
writel(WAKEUP_STATE, &pctl->sctl);
while ((readl(&pctl->stat) & PCTL_STAT_MSK)
!= ACCESS)
;
/* wait DLL lock */
while ((readl(&publ->pgsr) & PGSR_DLDONE)
!= PGSR_DLDONE)
;
/*
* if at low power state,need wakeup first,
* and then enter the config, so
* fallthrough
*/
case ACCESS:
/* fallthrough */
case INIT_MEM:
writel(CFG_STATE, &pctl->sctl);
while ((readl(&pctl->stat) & PCTL_STAT_MSK) != CONFIG)
;
break;
case CONFIG:
return;
default:
break;
}
}
}
static void set_bandwidth_ratio(const struct chan_info *chan, int channel,
u32 n, struct rk3188_grf *grf)
{
struct rk3288_ddr_pctl *pctl = chan->pctl;
struct rk3288_ddr_publ *publ = chan->publ;
struct rk3188_msch *msch = chan->msch;
if (n == 1) {
setbits_le32(&pctl->ppcfg, 1);
ddr_set_enable(grf, channel, 1);
setbits_le32(&msch->ddrtiming, 1 << 31);
/* Data Byte disable*/
clrbits_le32(&publ->datx8[2].dxgcr, 1);
clrbits_le32(&publ->datx8[3].dxgcr, 1);
/* disable DLL */
setbits_le32(&publ->datx8[2].dxdllcr, DXDLLCR_DLLDIS);
setbits_le32(&publ->datx8[3].dxdllcr, DXDLLCR_DLLDIS);
} else {
clrbits_le32(&pctl->ppcfg, 1);
ddr_set_enable(grf, channel, 0);
clrbits_le32(&msch->ddrtiming, 1 << 31);
/* Data Byte enable*/
setbits_le32(&publ->datx8[2].dxgcr, 1);
setbits_le32(&publ->datx8[3].dxgcr, 1);
/* enable DLL */
clrbits_le32(&publ->datx8[2].dxdllcr, DXDLLCR_DLLDIS);
clrbits_le32(&publ->datx8[3].dxdllcr, DXDLLCR_DLLDIS);
/* reset DLL */
clrbits_le32(&publ->datx8[2].dxdllcr, DXDLLCR_DLLSRST);
clrbits_le32(&publ->datx8[3].dxdllcr, DXDLLCR_DLLSRST);
udelay(10);
setbits_le32(&publ->datx8[2].dxdllcr, DXDLLCR_DLLSRST);
setbits_le32(&publ->datx8[3].dxdllcr, DXDLLCR_DLLSRST);
}
setbits_le32(&pctl->dfistcfg0, 1 << 2);
}
static int data_training(const struct chan_info *chan, int channel,
struct rk3188_sdram_params *sdram_params)
{
unsigned int j;
int ret = 0;
u32 rank;
int i;
u32 step[2] = { PIR_QSTRN, PIR_RVTRN };
struct rk3288_ddr_publ *publ = chan->publ;
struct rk3288_ddr_pctl *pctl = chan->pctl;
/* disable auto refresh */
writel(0, &pctl->trefi);
if (sdram_params->base.dramtype != LPDDR3)
setbits_le32(&publ->pgcr, 1 << PGCR_DQSCFG_SHIFT);
rank = sdram_params->ch[channel].rank | 1;
for (j = 0; j < ARRAY_SIZE(step); j++) {
/*
* trigger QSTRN and RVTRN
* clear DTDONE status
*/
setbits_le32(&publ->pir, PIR_CLRSR);
/* trigger DTT */
setbits_le32(&publ->pir,
PIR_INIT | step[j] | PIR_LOCKBYP | PIR_ZCALBYP |
PIR_CLRSR);
udelay(1);
/* wait echo byte DTDONE */
while ((readl(&publ->datx8[0].dxgsr[0]) & rank)
!= rank)
;
while ((readl(&publ->datx8[1].dxgsr[0]) & rank)
!= rank)
;
if (!(readl(&pctl->ppcfg) & 1)) {
while ((readl(&publ->datx8[2].dxgsr[0])
& rank) != rank)
;
while ((readl(&publ->datx8[3].dxgsr[0])
& rank) != rank)
;
}
if (readl(&publ->pgsr) &
(PGSR_DTERR | PGSR_RVERR | PGSR_RVEIRR)) {
ret = -1;
break;
}
}
/* send some auto refresh to complement the lost while DTT */
for (i = 0; i < (rank > 1 ? 8 : 4); i++)
send_command(pctl, rank, REF_CMD, 0);
if (sdram_params->base.dramtype != LPDDR3)
clrbits_le32(&publ->pgcr, 1 << PGCR_DQSCFG_SHIFT);
/* resume auto refresh */
writel(sdram_params->pctl_timing.trefi, &pctl->trefi);
return ret;
}
static void move_to_access_state(const struct chan_info *chan)
{
struct rk3288_ddr_publ *publ = chan->publ;
struct rk3288_ddr_pctl *pctl = chan->pctl;
unsigned int state;
while (1) {
state = readl(&pctl->stat) & PCTL_STAT_MSK;
switch (state) {
case LOW_POWER:
if (((readl(&pctl->stat) >> LP_TRIG_SHIFT) &
LP_TRIG_MASK) == 1)
return;
writel(WAKEUP_STATE, &pctl->sctl);
while ((readl(&pctl->stat) & PCTL_STAT_MSK) != ACCESS)
;
/* wait DLL lock */
while ((readl(&publ->pgsr) & PGSR_DLDONE)
!= PGSR_DLDONE)
;
break;
case INIT_MEM:
writel(CFG_STATE, &pctl->sctl);
while ((readl(&pctl->stat) & PCTL_STAT_MSK) != CONFIG)
;
/* fallthrough */
case CONFIG:
writel(GO_STATE, &pctl->sctl);
while ((readl(&pctl->stat) & PCTL_STAT_MSK) == CONFIG)
;
break;
case ACCESS:
return;
default:
break;
}
}
}
static void dram_cfg_rbc(const struct chan_info *chan, u32 chnum,
struct rk3188_sdram_params *sdram_params)
{
struct rk3288_ddr_publ *publ = chan->publ;
if (sdram_params->ch[chnum].bk == 3)
clrsetbits_le32(&publ->dcr, PDQ_MASK << PDQ_SHIFT,
1 << PDQ_SHIFT);
else
clrbits_le32(&publ->dcr, PDQ_MASK << PDQ_SHIFT);
writel(sdram_params->base.ddrconfig, &chan->msch->ddrconf);
}
static void dram_all_config(const struct dram_info *dram,
struct rk3188_sdram_params *sdram_params)
{
unsigned int chan;
u32 sys_reg = 0;
sys_reg |= sdram_params->base.dramtype << SYS_REG_DDRTYPE_SHIFT;
sys_reg |= (sdram_params->num_channels - 1) << SYS_REG_NUM_CH_SHIFT;
for (chan = 0; chan < sdram_params->num_channels; chan++) {
const struct rk3288_sdram_channel *info =
&sdram_params->ch[chan];
sys_reg |= info->row_3_4 << SYS_REG_ROW_3_4_SHIFT(chan);
sys_reg |= 1 << SYS_REG_CHINFO_SHIFT(chan);
sys_reg |= (info->rank - 1) << SYS_REG_RANK_SHIFT(chan);
sys_reg |= (info->col - 9) << SYS_REG_COL_SHIFT(chan);
sys_reg |= info->bk == 3 ? 0 : 1 << SYS_REG_BK_SHIFT(chan);
sys_reg |= (info->cs0_row - 13) << SYS_REG_CS0_ROW_SHIFT(chan);
sys_reg |= (info->cs1_row - 13) << SYS_REG_CS1_ROW_SHIFT(chan);
sys_reg |= (2 >> info->bw) << SYS_REG_BW_SHIFT(chan);
sys_reg |= (2 >> info->dbw) << SYS_REG_DBW_SHIFT(chan);
dram_cfg_rbc(&dram->chan[chan], chan, sdram_params);
}
if (sdram_params->ch[0].rank == 2)
ddr_rank_2_row15en(dram->grf, 0);
else
ddr_rank_2_row15en(dram->grf, 1);
writel(sys_reg, &dram->pmu->sys_reg[2]);
}
static int sdram_rank_bw_detect(struct dram_info *dram, int channel,
struct rk3188_sdram_params *sdram_params)
{
int reg;
int need_trainig = 0;
const struct chan_info *chan = &dram->chan[channel];
struct rk3288_ddr_publ *publ = chan->publ;
ddr_rank_2_row15en(dram->grf, 0);
if (data_training(chan, channel, sdram_params) < 0) {
printf("first data training fail!\n");
reg = readl(&publ->datx8[0].dxgsr[0]);
/* Check the result for rank 0 */
if ((channel == 0) && (reg & DQS_GATE_TRAINING_ERROR_RANK0)) {
printf("data training fail!\n");
return -EIO;
}
/* Check the result for rank 1 */
if (reg & DQS_GATE_TRAINING_ERROR_RANK1) {
sdram_params->ch[channel].rank = 1;
clrsetbits_le32(&publ->pgcr, 0xF << 18,
sdram_params->ch[channel].rank << 18);
need_trainig = 1;
}
reg = readl(&publ->datx8[2].dxgsr[0]);
if (reg & (1 << 4)) {
sdram_params->ch[channel].bw = 1;
set_bandwidth_ratio(chan, channel,
sdram_params->ch[channel].bw,
dram->grf);
need_trainig = 1;
}
}
/* Assume the Die bit width are the same with the chip bit width */
sdram_params->ch[channel].dbw = sdram_params->ch[channel].bw;
if (need_trainig &&
(data_training(chan, channel, sdram_params) < 0)) {
if (sdram_params->base.dramtype == LPDDR3) {
ddr_phy_ctl_reset(dram->cru, channel, 1);
udelay(10);
ddr_phy_ctl_reset(dram->cru, channel, 0);
udelay(10);
}
printf("2nd data training failed!");
return -EIO;
}
return 0;
}
/*
* Detect ram columns and rows.
* @dram: dram info struct
* @channel: channel number to handle
* @sdram_params: sdram parameters, function will fill in col and row values
*
* Returns 0 or negative on error.
*/
static int sdram_col_row_detect(struct dram_info *dram, int channel,
struct rk3188_sdram_params *sdram_params)
{
int row, col;
unsigned int addr;
const struct chan_info *chan = &dram->chan[channel];
struct rk3288_ddr_pctl *pctl = chan->pctl;
struct rk3288_ddr_publ *publ = chan->publ;
int ret = 0;
/* Detect col */
for (col = 11; col >= 9; col--) {
writel(0, CONFIG_SYS_SDRAM_BASE);
addr = CONFIG_SYS_SDRAM_BASE +
(1 << (col + sdram_params->ch[channel].bw - 1));
writel(TEST_PATTEN, addr);
if ((readl(addr) == TEST_PATTEN) &&
(readl(CONFIG_SYS_SDRAM_BASE) == 0))
break;
}
if (col == 8) {
printf("Col detect error\n");
ret = -EINVAL;
goto out;
} else {
sdram_params->ch[channel].col = col;
}
ddr_rank_2_row15en(dram->grf, 1);
move_to_config_state(publ, pctl);
writel(1, &chan->msch->ddrconf);
move_to_access_state(chan);
/* Detect row, max 15,min13 in rk3188*/
for (row = 16; row >= 13; row--) {
writel(0, CONFIG_SYS_SDRAM_BASE);
addr = CONFIG_SYS_SDRAM_BASE + (1 << (row + 15 - 1));
writel(TEST_PATTEN, addr);
if ((readl(addr) == TEST_PATTEN) &&
(readl(CONFIG_SYS_SDRAM_BASE) == 0))
break;
}
if (row == 12) {
printf("Row detect error\n");
ret = -EINVAL;
} else {
sdram_params->ch[channel].cs1_row = row;
sdram_params->ch[channel].row_3_4 = 0;
debug("chn %d col %d, row %d\n", channel, col, row);
sdram_params->ch[channel].cs0_row = row;
}
out:
return ret;
}
static int sdram_get_niu_config(struct rk3188_sdram_params *sdram_params)
{
int i, tmp, size, ret = 0;
tmp = sdram_params->ch[0].col - 9;
tmp -= (sdram_params->ch[0].bw == 2) ? 0 : 1;
tmp |= ((sdram_params->ch[0].cs0_row - 13) << 4);
size = sizeof(ddrconf_table)/sizeof(ddrconf_table[0]);
for (i = 0; i < size; i++)
if (tmp == ddrconf_table[i])
break;
if (i >= size) {
printf("niu config not found\n");
ret = -EINVAL;
} else {
debug("niu config %d\n", i);
sdram_params->base.ddrconfig = i;
}
return ret;
}
static int sdram_init(struct dram_info *dram,
struct rk3188_sdram_params *sdram_params)
{
int channel;
int zqcr;
int ret;
if ((sdram_params->base.dramtype == DDR3 &&
sdram_params->base.ddr_freq > 800000000)) {
printf("SDRAM frequency is too high!");
return -E2BIG;
}
ret = clk_set_rate(&dram->ddr_clk, sdram_params->base.ddr_freq);
if (ret) {
printf("Could not set DDR clock\n");
return ret;
}
for (channel = 0; channel < 1; channel++) {
const struct chan_info *chan = &dram->chan[channel];
struct rk3288_ddr_pctl *pctl = chan->pctl;
struct rk3288_ddr_publ *publ = chan->publ;
phy_pctrl_reset(dram->cru, publ, channel);
phy_dll_bypass_set(publ, sdram_params->base.ddr_freq);
dfi_cfg(pctl, sdram_params->base.dramtype);
pctl_cfg(channel, pctl, sdram_params, dram->grf);
phy_cfg(chan, channel, sdram_params);
phy_init(publ);
writel(POWER_UP_START, &pctl->powctl);
while (!(readl(&pctl->powstat) & POWER_UP_DONE))
;
memory_init(publ, sdram_params->base.dramtype);
move_to_config_state(publ, pctl);
/* Using 32bit bus width for detect */
sdram_params->ch[channel].bw = 2;
set_bandwidth_ratio(chan, channel,
sdram_params->ch[channel].bw, dram->grf);
/*
* set cs, using n=3 for detect
* CS0, n=1
* CS1, n=2
* CS0 & CS1, n = 3
*/
sdram_params->ch[channel].rank = 2,
clrsetbits_le32(&publ->pgcr, 0xF << 18,
(sdram_params->ch[channel].rank | 1) << 18);
/* DS=40ohm,ODT=155ohm */
zqcr = 1 << ZDEN_SHIFT | 2 << PU_ONDIE_SHIFT |
2 << PD_ONDIE_SHIFT | 0x19 << PU_OUTPUT_SHIFT |
0x19 << PD_OUTPUT_SHIFT;
writel(zqcr, &publ->zq1cr[0]);
writel(zqcr, &publ->zq0cr[0]);
/* Detect the rank and bit-width with data-training */
writel(1, &chan->msch->ddrconf);
sdram_rank_bw_detect(dram, channel, sdram_params);
if (sdram_params->base.dramtype == LPDDR3) {
u32 i;
writel(0, &pctl->mrrcfg0);
for (i = 0; i < 17; i++)
send_command_op(pctl, 1, MRR_CMD, i, 0);
}
writel(4, &chan->msch->ddrconf);
move_to_access_state(chan);
/* DDR3 and LPDDR3 are always 8 bank, no need detect */
sdram_params->ch[channel].bk = 3;
/* Detect Col and Row number*/
ret = sdram_col_row_detect(dram, channel, sdram_params);
if (ret)
goto error;
}
/* Find NIU DDR configuration */
ret = sdram_get_niu_config(sdram_params);
if (ret)
goto error;
dram_all_config(dram, sdram_params);
debug("%s done\n", __func__);
return 0;
error:
printf("DRAM init failed!\n");
hang();
}
#endif /* CONFIG_SPL_BUILD */
size_t sdram_size_mb(struct rk3188_pmu *pmu)
{
u32 rank, col, bk, cs0_row, cs1_row, bw, row_3_4;
size_t chipsize_mb = 0;
size_t size_mb = 0;
u32 ch;
u32 sys_reg = readl(&pmu->sys_reg[2]);
u32 chans;
chans = 1 + ((sys_reg >> SYS_REG_NUM_CH_SHIFT) & SYS_REG_NUM_CH_MASK);
for (ch = 0; ch < chans; ch++) {
rank = 1 + (sys_reg >> SYS_REG_RANK_SHIFT(ch) &
SYS_REG_RANK_MASK);
col = 9 + (sys_reg >> SYS_REG_COL_SHIFT(ch) & SYS_REG_COL_MASK);
bk = 3 - ((sys_reg >> SYS_REG_BK_SHIFT(ch)) & SYS_REG_BK_MASK);
cs0_row = 13 + (sys_reg >> SYS_REG_CS0_ROW_SHIFT(ch) &
SYS_REG_CS0_ROW_MASK);
cs1_row = 13 + (sys_reg >> SYS_REG_CS1_ROW_SHIFT(ch) &
SYS_REG_CS1_ROW_MASK);
bw = (2 >> ((sys_reg >> SYS_REG_BW_SHIFT(ch)) &
SYS_REG_BW_MASK));
row_3_4 = sys_reg >> SYS_REG_ROW_3_4_SHIFT(ch) &
SYS_REG_ROW_3_4_MASK;
chipsize_mb = (1 << (cs0_row + col + bk + bw - 20));
if (rank > 1)
chipsize_mb += chipsize_mb >>
(cs0_row - cs1_row);
if (row_3_4)
chipsize_mb = chipsize_mb * 3 / 4;
size_mb += chipsize_mb;
}
/* there can be no more than 2gb of memory */
size_mb = min(size_mb, 0x80000000 >> 20);
return size_mb;
}
#ifdef CONFIG_SPL_BUILD
static int setup_sdram(struct udevice *dev)
{
struct dram_info *priv = dev_get_priv(dev);
struct rk3188_sdram_params *params = dev_get_platdata(dev);
return sdram_init(priv, params);
}
static int rk3188_dmc_ofdata_to_platdata(struct udevice *dev)
{
#if !CONFIG_IS_ENABLED(OF_PLATDATA)
struct rk3188_sdram_params *params = dev_get_platdata(dev);
const void *blob = gd->fdt_blob;
int node = dev->of_offset;
int ret;
/* rk3188 supports only one-channel */
params->num_channels = 1;
ret = fdtdec_get_int_array(blob, node, "rockchip,pctl-timing",
(u32 *)&params->pctl_timing,
sizeof(params->pctl_timing) / sizeof(u32));
if (ret) {
printf("%s: Cannot read rockchip,pctl-timing\n", __func__);
return -EINVAL;
}
ret = fdtdec_get_int_array(blob, node, "rockchip,phy-timing",
(u32 *)&params->phy_timing,
sizeof(params->phy_timing) / sizeof(u32));
if (ret) {
printf("%s: Cannot read rockchip,phy-timing\n", __func__);
return -EINVAL;
}
ret = fdtdec_get_int_array(blob, node, "rockchip,sdram-params",
(u32 *)&params->base,
sizeof(params->base) / sizeof(u32));
if (ret) {
printf("%s: Cannot read rockchip,sdram-params\n", __func__);
return -EINVAL;
}
ret = regmap_init_mem(dev, &params->map);
if (ret)
return ret;
#endif
return 0;
}
#endif /* CONFIG_SPL_BUILD */
#if CONFIG_IS_ENABLED(OF_PLATDATA)
static int conv_of_platdata(struct udevice *dev)
{
struct rk3188_sdram_params *plat = dev_get_platdata(dev);
struct dtd_rockchip_rk3188_dmc *of_plat = &plat->of_plat;
int ret;
memcpy(&plat->pctl_timing, of_plat->rockchip_pctl_timing,
sizeof(plat->pctl_timing));
memcpy(&plat->phy_timing, of_plat->rockchip_phy_timing,
sizeof(plat->phy_timing));
memcpy(&plat->base, of_plat->rockchip_sdram_params, sizeof(plat->base));
/* rk3188 supports dual-channel, set default channel num to 2 */
plat->num_channels = 1;
ret = regmap_init_mem_platdata(dev, of_plat->reg,
ARRAY_SIZE(of_plat->reg) / 2,
&plat->map);
if (ret)
return ret;
return 0;
}
#endif
static int rk3188_dmc_probe(struct udevice *dev)
{
#ifdef CONFIG_SPL_BUILD
struct rk3188_sdram_params *plat = dev_get_platdata(dev);
#endif
struct dram_info *priv = dev_get_priv(dev);
struct regmap *map;
int ret;
struct udevice *dev_clk;
#if CONFIG_IS_ENABLED(OF_PLATDATA)
ret = conv_of_platdata(dev);
if (ret)
return ret;
#endif
map = syscon_get_regmap_by_driver_data(ROCKCHIP_SYSCON_NOC);
if (IS_ERR(map))
return PTR_ERR(map);
priv->chan[0].msch = regmap_get_range(map, 0);
priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
priv->pmu = syscon_get_first_range(ROCKCHIP_SYSCON_PMU);
#ifdef CONFIG_SPL_BUILD
priv->chan[0].pctl = regmap_get_range(plat->map, 0);
priv->chan[0].publ = regmap_get_range(plat->map, 1);
#endif
ret = rockchip_get_clk(&dev_clk);
if (ret)
return ret;
priv->ddr_clk.id = CLK_DDR;
ret = clk_request(dev_clk, &priv->ddr_clk);
if (ret)
return ret;
priv->cru = rockchip_get_cru();
if (IS_ERR(priv->cru))
return PTR_ERR(priv->cru);
#ifdef CONFIG_SPL_BUILD
ret = setup_sdram(dev);
if (ret)
return ret;
#endif
priv->info.base = 0;
priv->info.size = sdram_size_mb(priv->pmu) << 20;
return 0;
}
static int rk3188_dmc_get_info(struct udevice *dev, struct ram_info *info)
{
struct dram_info *priv = dev_get_priv(dev);
*info = priv->info;
return 0;
}
static struct ram_ops rk3188_dmc_ops = {
.get_info = rk3188_dmc_get_info,
};
static const struct udevice_id rk3188_dmc_ids[] = {
{ .compatible = "rockchip,rk3188-dmc" },
{ }
};
U_BOOT_DRIVER(dmc_rk3188) = {
.name = "rockchip_rk3188_dmc",
.id = UCLASS_RAM,
.of_match = rk3188_dmc_ids,
.ops = &rk3188_dmc_ops,
#ifdef CONFIG_SPL_BUILD
.ofdata_to_platdata = rk3188_dmc_ofdata_to_platdata,
#endif
.probe = rk3188_dmc_probe,
.priv_auto_alloc_size = sizeof(struct dram_info),
#ifdef CONFIG_SPL_BUILD
.platdata_auto_alloc_size = sizeof(struct rk3188_sdram_params),
#endif
};

View file

@ -0,0 +1,55 @@
/*
* Copyright (C) 2015 Google, Inc
* Written by Simon Glass <sjg@chromium.org>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <dm.h>
#include <syscon.h>
#include <asm/arch/clock.h>
static const struct udevice_id rk3188_syscon_ids[] = {
{ .compatible = "rockchip,rk3188-noc", .data = ROCKCHIP_SYSCON_NOC },
{ .compatible = "rockchip,rk3188-grf", .data = ROCKCHIP_SYSCON_GRF },
{ .compatible = "rockchip,rk3188-pmu", .data = ROCKCHIP_SYSCON_PMU },
{ }
};
U_BOOT_DRIVER(syscon_rk3188) = {
.name = "rk3188_syscon",
.id = UCLASS_SYSCON,
.of_match = rk3188_syscon_ids,
};
#if CONFIG_IS_ENABLED(OF_PLATDATA)
static int rk3188_syscon_bind_of_platdata(struct udevice *dev)
{
dev->driver_data = dev->driver->of_match->data;
debug("syscon: %s %d\n", dev->name, (uint)dev->driver_data);
return 0;
}
U_BOOT_DRIVER(rockchip_rk3188_noc) = {
.name = "rockchip_rk3188_noc",
.id = UCLASS_SYSCON,
.of_match = rk3188_syscon_ids,
.bind = rk3188_syscon_bind_of_platdata,
};
U_BOOT_DRIVER(rockchip_rk3188_grf) = {
.name = "rockchip_rk3188_grf",
.id = UCLASS_SYSCON,
.of_match = rk3188_syscon_ids + 1,
.bind = rk3188_syscon_bind_of_platdata,
};
U_BOOT_DRIVER(rockchip_rk3188_pmu) = {
.name = "rockchip_rk3188_pmu",
.id = UCLASS_SYSCON,
.of_match = rk3188_syscon_ids + 2,
.bind = rk3188_syscon_bind_of_platdata,
};
#endif

View file

@ -14,6 +14,7 @@
#include <spl.h>
#include <asm/gpio.h>
#include <asm/io.h>
#include <asm/arch/bootrom.h>
#include <asm/arch/clock.h>
#include <asm/arch/hardware.h>
#include <asm/arch/periph.h>
@ -155,7 +156,7 @@ static int configure_emmc(struct udevice *pinctrl)
return 0;
}
#endif
extern void back_to_bootrom(void);
void board_init_f(ulong dummy)
{
struct udevice *pinctrl;
@ -184,9 +185,9 @@ void board_init_f(ulong dummy)
debug_uart_init();
#endif
ret = spl_init();
ret = spl_early_init();
if (ret) {
debug("spl_init() failed: %d\n", ret);
debug("spl_early_init() failed: %d\n", ret);
hang();
}

View file

@ -57,6 +57,26 @@ struct rk3288_sdram_params {
struct regmap *map;
};
const int ddrconf_table[] = {
/* row col,bw */
0,
((1 << DDRCONF_ROW_SHIFT) | 1 << DDRCONF_COL_SHIFT),
((2 << DDRCONF_ROW_SHIFT) | 1 << DDRCONF_COL_SHIFT),
((3 << DDRCONF_ROW_SHIFT) | 1 << DDRCONF_COL_SHIFT),
((4 << DDRCONF_ROW_SHIFT) | 1 << DDRCONF_COL_SHIFT),
((1 << DDRCONF_ROW_SHIFT) | 2 << DDRCONF_COL_SHIFT),
((2 << DDRCONF_ROW_SHIFT) | 2 << DDRCONF_COL_SHIFT),
((3 << DDRCONF_ROW_SHIFT) | 2 << DDRCONF_COL_SHIFT),
((1 << DDRCONF_ROW_SHIFT) | 0 << DDRCONF_COL_SHIFT),
((2 << DDRCONF_ROW_SHIFT) | 0 << DDRCONF_COL_SHIFT),
((3 << DDRCONF_ROW_SHIFT) | 0 << DDRCONF_COL_SHIFT),
0,
0,
0,
0,
((4 << 4) | 2),
};
#define TEST_PATTEN 0x5aa5f00f
#define DQS_GATE_TRAINING_ERROR_RANK0 (1 << 4)
#define DQS_GATE_TRAINING_ERROR_RANK1 (2 << 4)
@ -100,7 +120,7 @@ static void ddr_phy_ctl_reset(struct rk3288_cru *cru, u32 ch, u32 n)
static void phy_pctrl_reset(struct rk3288_cru *cru,
struct rk3288_ddr_publ *publ,
u32 channel)
int channel)
{
int i;
@ -126,6 +146,7 @@ static void phy_dll_bypass_set(struct rk3288_ddr_publ *publ,
u32 freq)
{
int i;
if (freq <= 250000000) {
if (freq <= 150000000)
clrbits_le32(&publ->dllgcr, SBIAS_BYPASS);
@ -217,7 +238,7 @@ static void ddr_set_en_bst_odt(struct rk3288_grf *grf, uint channel,
UPCTL0_LPDDR3_ODT_EN_SHIFT));
}
static void pctl_cfg(u32 channel, struct rk3288_ddr_pctl *pctl,
static void pctl_cfg(int channel, struct rk3288_ddr_pctl *pctl,
struct rk3288_sdram_params *sdram_params,
struct rk3288_grf *grf)
{
@ -267,7 +288,7 @@ static void pctl_cfg(u32 channel, struct rk3288_ddr_pctl *pctl,
setbits_le32(&pctl->scfg, 1);
}
static void phy_cfg(const struct chan_info *chan, u32 channel,
static void phy_cfg(const struct chan_info *chan, int channel,
struct rk3288_sdram_params *sdram_params)
{
struct rk3288_ddr_publ *publ = chan->publ;
@ -392,7 +413,8 @@ static void move_to_config_state(struct rk3288_ddr_publ *publ,
while ((readl(&publ->pgsr) & PGSR_DLDONE)
!= PGSR_DLDONE)
;
/* if at low power state,need wakeup first,
/*
* if at low power state,need wakeup first,
* and then enter the config
* so here no break.
*/
@ -411,7 +433,7 @@ static void move_to_config_state(struct rk3288_ddr_publ *publ,
}
}
static void set_bandwidth_ratio(const struct chan_info *chan, u32 channel,
static void set_bandwidth_ratio(const struct chan_info *chan, int channel,
u32 n, struct rk3288_grf *grf)
{
struct rk3288_ddr_pctl *pctl = chan->pctl;
@ -449,7 +471,7 @@ static void set_bandwidth_ratio(const struct chan_info *chan, u32 channel,
setbits_le32(&pctl->dfistcfg0, 1 << 2);
}
static int data_training(const struct chan_info *chan, u32 channel,
static int data_training(const struct chan_info *chan, int channel,
struct rk3288_sdram_params *sdram_params)
{
unsigned int j;
@ -593,25 +615,6 @@ static void dram_all_config(const struct dram_info *dram,
writel(sys_reg, &dram->pmu->sys_reg[2]);
rk_clrsetreg(&dram->sgrf->soc_con2, 0x1f, sdram_params->base.stride);
}
const int ddrconf_table[] = {
/* row col,bw */
0,
((1 << 4) | 1),
((2 << 4) | 1),
((3 << 4) | 1),
((4 << 4) | 1),
((1 << 4) | 2),
((2 << 4) | 2),
((3 << 4) | 2),
((1 << 4) | 0),
((2 << 4) | 0),
((3 << 4) | 0),
0,
0,
0,
0,
((4 << 4) | 2),
};
static int sdram_rank_bw_detect(struct dram_info *dram, int channel,
struct rk3288_sdram_params *sdram_params)
@ -621,7 +624,7 @@ static int sdram_rank_bw_detect(struct dram_info *dram, int channel,
const struct chan_info *chan = &dram->chan[channel];
struct rk3288_ddr_publ *publ = chan->publ;
if (-1 == data_training(chan, channel, sdram_params)) {
if (data_training(chan, channel, sdram_params) < 0) {
reg = readl(&publ->datx8[0].dxgsr[0]);
/* Check the result for rank 0 */
if ((channel == 0) && (reg & DQS_GATE_TRAINING_ERROR_RANK0)) {
@ -652,7 +655,7 @@ static int sdram_rank_bw_detect(struct dram_info *dram, int channel,
sdram_params->ch[channel].dbw = sdram_params->ch[channel].bw;
if (need_trainig &&
(-1 == data_training(chan, channel, sdram_params))) {
(data_training(chan, channel, sdram_params) < 0)) {
if (sdram_params->base.dramtype == LPDDR3) {
ddr_phy_ctl_reset(dram->cru, channel, 1);
udelay(10);

View file

@ -0,0 +1,23 @@
if ROCKCHIP_RK3328
choice
prompt "RK3328 board select"
config TARGET_EVB_RK3328
bool "RK3328 evaluation board"
help
RK3328evb is a evaluation board for Rockchip rk3328,
with full function and phisical connectors support like
usb2.0 host ports, LVDS, JTAG, MAC, SDcard, HDMI, USB-2-serial...
endchoice
config SYS_SOC
default "rockchip"
config SYS_MALLOC_F_LEN
default 0x0800
source "board/rockchip/evb_rk3328/Kconfig"
endif

View file

@ -0,0 +1,9 @@
#
# (C) Copyright 2016 Rockchip Electronics Co., Ltd
#
# SPDX-License-Identifier: GPL-2.0+
#
obj-y += clk_rk3328.o
obj-y += rk3328.o
obj-y += syscon_rk3328.o

View file

@ -0,0 +1,31 @@
/*
* (C) Copyright 2017 Rockchip Electronics Co., Ltd
*
* SPDX-License-Identifier: GPL-2.0
*/
#include <common.h>
#include <dm.h>
#include <asm/arch/clock.h>
#include <asm/arch/cru_rk3328.h>
int rockchip_get_clk(struct udevice **devp)
{
return uclass_get_device_by_driver(UCLASS_CLK,
DM_GET_DRIVER(rockchip_rk3328_cru), devp);
}
void *rockchip_get_cru(void)
{
struct rk3328_clk_priv *priv;
struct udevice *dev;
int ret;
ret = rockchip_get_clk(&dev);
if (ret)
return ERR_PTR(ret);
priv = dev_get_addr_ptr(dev);
return priv->cru;
}

View file

@ -0,0 +1,39 @@
/*
* Copyright (c) 2016 Rockchip Electronics Co., Ltd
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <asm/arch/hardware.h>
#include <asm/armv8/mmu.h>
#include <asm/io.h>
static struct mm_region rk3328_mem_map[] = {
{
.virt = 0x0UL,
.phys = 0x0UL,
.size = 0x80000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
PTE_BLOCK_INNER_SHARE
}, {
.virt = 0xf0000000UL,
.phys = 0xf0000000UL,
.size = 0x10000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE |
PTE_BLOCK_PXN | PTE_BLOCK_UXN
}, {
/* List terminator */
0,
}
};
struct mm_region *mem_map = rk3328_mem_map;
int arch_cpu_init(void)
{
/* We do some SoC one time setting here. */
return 0;
}

View file

@ -0,0 +1,20 @@
/*
* (C) Copyright 2016 Rockchip Electronics Co., Ltd
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <asm/arch/clock.h>
#include <dm.h>
#include <syscon.h>
static const struct udevice_id rk3328_syscon_ids[] = {
{ .compatible = "rockchip,rk3328-grf", .data = ROCKCHIP_SYSCON_GRF },
};
U_BOOT_DRIVER(syscon_rk3328) = {
.name = "rk3328_syscon",
.id = UCLASS_SYSCON,
.of_match = rk3328_syscon_ids,
};

View file

@ -0,0 +1,158 @@
/*
* (C) Copyright 2016 Rockchip Electronics Co., Ltd
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <debug_uart.h>
#include <dm.h>
#include <fdtdec.h>
#include <led.h>
#include <malloc.h>
#include <ram.h>
#include <spl.h>
#include <asm/gpio.h>
#include <asm/io.h>
#include <asm/arch/clock.h>
#include <asm/arch/hardware.h>
#include <asm/arch/periph.h>
#include <asm/arch/sdram.h>
#include <asm/arch/timer.h>
#include <dm/pinctrl.h>
#include <dm/root.h>
#include <dm/test.h>
#include <dm/util.h>
#include <power/regulator.h>
DECLARE_GLOBAL_DATA_PTR;
u32 spl_boot_device(void)
{
return BOOT_DEVICE_MMC1;
}
u32 spl_boot_mode(const u32 boot_device)
{
return MMCSD_MODE_RAW;
}
#define TIMER_CHN10_BASE 0xff8680a0
#define TIMER_END_COUNT_L 0x00
#define TIMER_END_COUNT_H 0x04
#define TIMER_INIT_COUNT_L 0x10
#define TIMER_INIT_COUNT_H 0x14
#define TIMER_CONTROL_REG 0x1c
#define TIMER_EN 0x1
#define TIMER_FMODE (0 << 1)
#define TIMER_RMODE (1 << 1)
void secure_timer_init(void)
{
writel(0xffffffff, TIMER_CHN10_BASE + TIMER_END_COUNT_L);
writel(0xffffffff, TIMER_CHN10_BASE + TIMER_END_COUNT_H);
writel(0, TIMER_CHN10_BASE + TIMER_INIT_COUNT_L);
writel(0, TIMER_CHN10_BASE + TIMER_INIT_COUNT_H);
writel(TIMER_EN | TIMER_FMODE, TIMER_CHN10_BASE + TIMER_CONTROL_REG);
}
#define GRF_EMMCCORE_CON11 0xff77f02c
void board_init_f(ulong dummy)
{
struct udevice *pinctrl;
struct udevice *dev;
int ret;
/* Example code showing how to enable the debug UART on RK3288 */
#include <asm/arch/grf_rk3399.h>
/* Enable early UART2 channel C on the RK3399 */
#define GRF_BASE 0xff770000
struct rk3399_grf_regs * const grf = (void *)GRF_BASE;
rk_clrsetreg(&grf->gpio4c_iomux,
GRF_GPIO4C3_SEL_MASK,
GRF_UART2DGBC_SIN << GRF_GPIO4C3_SEL_SHIFT);
rk_clrsetreg(&grf->gpio4c_iomux,
GRF_GPIO4C4_SEL_MASK,
GRF_UART2DBGC_SOUT << GRF_GPIO4C4_SEL_SHIFT);
/* Set channel C as UART2 input */
rk_clrsetreg(&grf->soc_con7,
GRF_UART_DBG_SEL_MASK,
GRF_UART_DBG_SEL_C << GRF_UART_DBG_SEL_SHIFT);
#define EARLY_UART
#ifdef EARLY_UART
/*
* Debug UART can be used from here if required:
*
* debug_uart_init();
* printch('a');
* printhex8(0x1234);
* printascii("string");
*/
debug_uart_init();
printascii("U-Boot SPL board init");
#endif
/* Emmc clock generator: disable the clock multipilier */
rk_clrreg(GRF_EMMCCORE_CON11, 0x0ff);
ret = spl_init();
if (ret) {
debug("spl_init() failed: %d\n", ret);
hang();
}
secure_timer_init();
ret = uclass_get_device(UCLASS_PINCTRL, 0, &pinctrl);
if (ret) {
debug("Pinctrl init failed: %d\n", ret);
return;
}
ret = uclass_get_device(UCLASS_RAM, 0, &dev);
if (ret) {
debug("DRAM init failed: %d\n", ret);
return;
}
}
void spl_board_init(void)
{
struct udevice *pinctrl;
int ret;
ret = uclass_get_device(UCLASS_PINCTRL, 0, &pinctrl);
if (ret) {
debug("%s: Cannot find pinctrl device\n", __func__);
goto err;
}
/* Enable debug UART */
ret = pinctrl_request_noflags(pinctrl, PERIPH_ID_UART_DBG);
if (ret) {
debug("%s: Failed to set up console UART\n", __func__);
goto err;
}
preloader_console_init();
#ifdef CONFIG_ROCKCHIP_SPL_BACK_TO_BROM
back_to_bootrom();
#endif
return;
err:
printf("spl_board_init: Error %d\n", ret);
/* No way to report error here */
hang();
}
#ifdef CONFIG_SPL_LOAD_FIT
int board_fit_config_name_match(const char *name)
{
/* Just empty function now - can't decide what to choose */
debug("%s: %s\n", __func__, name);
return 0;
}
#endif

View file

@ -6,4 +6,5 @@
obj-y += clk_rk3399.o
obj-y += rk3399.o
obj-y += sdram_rk3399.o
obj-y += syscon_rk3399.o

View file

@ -31,3 +31,24 @@ void *rockchip_get_cru(void)
return priv->cru;
}
static int rockchip_get_pmucruclk(struct udevice **devp)
{
return uclass_get_device_by_driver(UCLASS_CLK,
DM_GET_DRIVER(rockchip_rk3399_pmuclk), devp);
}
void *rockchip_get_pmucru(void)
{
struct rk3399_pmuclk_priv *priv;
struct udevice *dev;
int ret;
ret = rockchip_get_pmucruclk(&dev);
if (ret)
return ERR_PTR(ret);
priv = dev_get_priv(dev);
return priv->pmucru;
}

View file

@ -40,5 +40,6 @@ int arch_cpu_init(void)
/* Emmc clock generator: disable the clock multipilier */
rk_clrreg(GRF_EMMCCORE_CON11, 0x0ff);
printf("time %x, %x\n", readl(0xff8680a8), readl(0xff8680ac));
return 0;
}

File diff suppressed because it is too large Load diff

View file

@ -12,6 +12,8 @@
static const struct udevice_id rk3399_syscon_ids[] = {
{ .compatible = "rockchip,rk3399-grf", .data = ROCKCHIP_SYSCON_GRF },
{ .compatible = "rockchip,rk3399-pmugrf", .data = ROCKCHIP_SYSCON_PMUGRF },
{ .compatible = "rockchip,rk3399-pmusgrf", .data = ROCKCHIP_SYSCON_PMUSGRF },
{ .compatible = "rockchip,rk3399-cic", .data = ROCKCHIP_SYSCON_CIC },
};
U_BOOT_DRIVER(syscon_rk3399) = {
@ -19,3 +21,41 @@ U_BOOT_DRIVER(syscon_rk3399) = {
.id = UCLASS_SYSCON,
.of_match = rk3399_syscon_ids,
};
#if CONFIG_IS_ENABLED(OF_PLATDATA)
static int rk3399_syscon_bind_of_platdata(struct udevice *dev)
{
dev->driver_data = dev->driver->of_match->data;
debug("syscon: %s %d\n", dev->name, (uint)dev->driver_data);
return 0;
}
U_BOOT_DRIVER(rockchip_rk3399_grf) = {
.name = "rockchip_rk3399_grf",
.id = UCLASS_SYSCON,
.of_match = rk3399_syscon_ids,
.bind = rk3399_syscon_bind_of_platdata,
};
U_BOOT_DRIVER(rockchip_rk3399_pmugrf) = {
.name = "rockchip_rk3399_pmugrf",
.id = UCLASS_SYSCON,
.of_match = rk3399_syscon_ids + 1,
.bind = rk3399_syscon_bind_of_platdata,
};
U_BOOT_DRIVER(rockchip_rk3399_pmusgrf) = {
.name = "rockchip_rk3399_pmusgrf",
.id = UCLASS_SYSCON,
.of_match = rk3399_syscon_ids + 2,
.bind = rk3399_syscon_bind_of_platdata,
};
U_BOOT_DRIVER(rockchip_rk3399_cic) = {
.name = "rockchip_rk3399_cic",
.id = UCLASS_SYSCON,
.of_match = rk3399_syscon_ids + 3,
.bind = rk3399_syscon_bind_of_platdata,
};
#endif

View file

@ -0,0 +1,15 @@
if TARGET_EVB_RK3328
config SYS_BOARD
default "evb_rk3328"
config SYS_VENDOR
default "rockchip"
config SYS_CONFIG_NAME
default "evb_rk3328"
config BOARD_SPECIFIC_OPTIONS # dummy
def_bool y
endif

View file

@ -0,0 +1,6 @@
EVB-RK3328
M: William Zhang <william.zhang@rock-chips.com>
S: Maintained
F: board/rockchip/evb_rk3328
F: include/configs/evb_rk3328.h
F: configs/evb-rk3328_defconfig

View file

@ -0,0 +1,7 @@
#
# (C) Copyright 2016 Rockchip Electronics Co., Ltd
#
# SPDX-License-Identifier: GPL-2.0+
#
obj-y += evb-rk3328.o

View file

@ -0,0 +1,70 @@
Introduction
============
RK3328 key features we might use in U-Boot:
* CPU: ARMv8 64bit quad-core Cortex-A53
* IRAM: 36KB
* DRAM: 4GB-16MB dual-channel
* eMMC: support eMMC 5.0/5.1, suport HS400, HS200, DDR50
* SD/MMC: support SD 3.0, MMC 4.51
* USB: USB2.0 EHCI host port *2
* Display: RGB/HDMI/DP/MIPI/EDP
evb key features:
* regulator: pwm regulator for CPU B/L
* PMIC: rk808
* debug console: UART2
In order to support Arm Trust Firmware(ATF), we need to use the
miniloader from rockchip which:
* do DRAM init
* load and verify ATF image
* load and verify U-Boot image
Here is the step-by-step to boot to U-Boot on rk3328.
Get the Source and prebuild binary
==================================
> mkdir ~/evb_rk3328
> cd ~/evb_rk3328
> git clone https://github.com/ARM-software/arm-trusted-firmware.git
> git clone https://github.com/rockchip-linux/rkbin
> git clone https://github.com/rockchip-linux/rkflashtool
Compile ATF
===============
> cd arm-trusted-firmware
> make realclean
> make CROSS_COMPILE=aarch64-linux-gnu- PLAT=rk3328 bl31
Compile U-Boot
==================
> cd ../u-boot
> make CROSS_COMPILE=aarch64-linux-gnu- evb-rk3328_defconfig all
Compile rkflashtool
=======================
> cd ../rkflashtool
> make
Package image for miniloader
================================
> cd ..
> cp arm-trusted-firmware/build/rk3328/release/bl31.bin rkbin/rk33
> ./rkbin/tools/trust_merger rkbin/tools/RK3328TRUST.ini
> ./rkbin/tools/loaderimage --pack --uboot u-boot/u-boot-dtb.bin uboot.img
> mkdir image
> mv trust.img ./image/
> mv uboot.img ./image/rk3328evb-uboot.bin
Flash image
===============
Power on(or reset with RESET KEY) with MASKROM KEY preesed, and then:
> ./rkflashtool/rkflashloader rk3328evb
You should be able to get U-Boot log message in console/UART2 now.

View file

@ -0,0 +1,40 @@
/*
* (C) Copyright 2016 Rockchip Electronics Co., Ltd
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <asm/armv8/mmu.h>
#include <dwc3-uboot.h>
#include <usb.h>
DECLARE_GLOBAL_DATA_PTR;
int board_init(void)
{
return 0;
}
int dram_init(void)
{
gd->ram_size = 0x80000000;
return 0;
}
void dram_init_banksize(void)
{
/* Reserve 0x200000 for ATF bl31 */
gd->bd->bi_dram[0].start = 0x200000;
gd->bd->bi_dram[0].size = 0x7e000000;
}
int usb_gadget_handle_interrupts(void)
{
return 0;
}
int board_usb_init(int index, enum usb_init_type init)
{
return 0;
}

View file

@ -170,22 +170,20 @@ __weak void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
image_entry();
}
int spl_init(void)
static int spl_common_init(bool setup_malloc)
{
int ret;
debug("spl_init()\n");
/*
* with CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN we set malloc_base and
* malloc_limit in spl_relocate_stack_gd
*/
#if defined(CONFIG_SYS_MALLOC_F_LEN) && \
!defined(CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN)
debug("spl_early_init()\n");
#if defined(CONFIG_SYS_MALLOC_F_LEN)
if (setup_malloc) {
#ifdef CONFIG_MALLOC_F_ADDR
gd->malloc_base = CONFIG_MALLOC_F_ADDR;
#endif
gd->malloc_limit = CONFIG_SYS_MALLOC_F_LEN;
gd->malloc_ptr = 0;
}
#endif
if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) {
ret = fdtdec_setup();
@ -202,6 +200,32 @@ int spl_init(void)
return ret;
}
}
return 0;
}
int spl_early_init(void)
{
int ret;
ret = spl_common_init(true);
if (ret)
return ret;
gd->flags |= GD_FLG_SPL_EARLY_INIT;
return 0;
}
int spl_init(void)
{
int ret;
if (!(gd->flags & GD_FLG_SPL_EARLY_INIT)) {
ret = spl_common_init(
!IS_ENABLED(CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN));
if (ret)
return ret;
}
gd->flags |= GD_FLG_SPL_INIT;
return 0;

View file

@ -41,8 +41,11 @@ CONFIG_LED=y
CONFIG_LED_GPIO=y
CONFIG_MMC_DW=y
CONFIG_MMC_DW_ROCKCHIP=y
CONFIG_DM_ETH=y
CONFIG_NETDEVICES=y
CONFIG_ETH_DESIGNWARE=y
CONFIG_GMAC_ROCKCHIP=y
CONFIG_PINCTRL=y
# CONFIG_PINCTRL_FULL is not set
CONFIG_SPL_PINCTRL=y
# CONFIG_SPL_PINCTRL_FULL is not set
CONFIG_ROCKCHIP_RK3288_PINCTRL=y

View file

@ -0,0 +1,36 @@
CONFIG_ARM=y
CONFIG_ARCH_ROCKCHIP=y
CONFIG_ROCKCHIP_RK3328=y
CONFIG_DEFAULT_DEVICE_TREE="rk3328-evb"
CONFIG_FIT=y
# CONFIG_DISPLAY_CPUINFO is not set
CONFIG_CMD_BOOTZ=y
# CONFIG_CMD_IMLS is not set
CONFIG_CMD_GPT=y
CONFIG_CMD_MMC=y
CONFIG_CMD_SF=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_TIME=y
CONFIG_CMD_EXT2=y
CONFIG_CMD_EXT4=y
CONFIG_CMD_FAT=y
CONFIG_CMD_FS_GENERIC=y
CONFIG_REGMAP=y
CONFIG_SYSCON=y
CONFIG_CLK=y
CONFIG_ROCKCHIP_GPIO=y
CONFIG_MMC_DW=y
CONFIG_MMC_DW_ROCKCHIP=y
CONFIG_PINCTRL=y
CONFIG_ROCKCHIP_RK3328_PINCTRL=y
CONFIG_REGULATOR_PWM=y
CONFIG_DM_REGULATOR_FIXED=y
CONFIG_RAM=y
CONFIG_DEBUG_UART=y
CONFIG_DEBUG_UART_BASE=0xFF130000
CONFIG_DEBUG_UART_CLOCK=24000000
CONFIG_DEBUG_UART_SHIFT=2
CONFIG_SYS_NS16550=y
CONFIG_SYSRESET=y
CONFIG_USE_TINY_PRINTF=y
CONFIG_ERRNO_STR=y

View file

@ -3,7 +3,16 @@ CONFIG_ARCH_ROCKCHIP=y
CONFIG_ROCKCHIP_RK3399=y
CONFIG_DEFAULT_DEVICE_TREE="rk3399-evb"
CONFIG_FIT=y
CONFIG_SPL_LOAD_FIT=y
CONFIG_SPL_OF_LIBFDT=y
CONFIG_SPL_ATF_SUPPORT=y
CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x200
CONFIG_SPL_ATF_TEXT_BASE=0x00010000
# CONFIG_DISPLAY_CPUINFO is not set
CONFIG_SPL_STACK_R=y
CONFIG_SPL_STACK_R_ADDR=0x80000
CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x4000
CONFIG_SYS_MALLOC_F_LEN=0x4000
CONFIG_CMD_BOOTZ=y
# CONFIG_CMD_IMLS is not set
CONFIG_CMD_GPT=y
@ -12,20 +21,28 @@ CONFIG_CMD_SF=y
CONFIG_CMD_USB=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_TIME=y
CONFIG_CMD_PXE=y
CONFIG_SPL_OF_CONTROL=y
CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents"
CONFIG_SPL_OF_PLATDATA=y
CONFIG_REGMAP=y
CONFIG_SPL_REGMAP=y
CONFIG_SYSCON=y
CONFIG_SPL_SYSCON=y
CONFIG_CLK=y
CONFIG_SPL_CLK=y
CONFIG_ROCKCHIP_GPIO=y
CONFIG_MMC_DW=y
CONFIG_MMC_DW_ROCKCHIP=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_ROCKCHIP=y
CONFIG_PINCTRL=y
CONFIG_SPL_PINCTRL=y
CONFIG_ROCKCHIP_RK3399_PINCTRL=y
CONFIG_REGULATOR_PWM=y
CONFIG_DM_REGULATOR_FIXED=y
CONFIG_PWM_ROCKCHIP=y
CONFIG_RAM=y
CONFIG_SPL_RAM=y
CONFIG_DEBUG_UART=y
CONFIG_DEBUG_UART_BASE=0xFF1A0000
CONFIG_DEBUG_UART_CLOCK=24000000

View file

@ -17,6 +17,7 @@ CONFIG_CMD_MMC=y
CONFIG_CMD_SF=y
CONFIG_CMD_SPI=y
CONFIG_CMD_I2C=y
CONFIG_CMD_USB=y
CONFIG_CMD_GPIO=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_CACHE=y
@ -40,8 +41,11 @@ CONFIG_ROCKCHIP_GPIO=y
CONFIG_SYS_I2C_ROCKCHIP=y
CONFIG_MMC_DW=y
CONFIG_MMC_DW_ROCKCHIP=y
CONFIG_DM_ETH=y
CONFIG_NETDEVICES=y
CONFIG_ETH_DESIGNWARE=y
CONFIG_GMAC_ROCKCHIP=y
CONFIG_PINCTRL=y
# CONFIG_PINCTRL_FULL is not set
CONFIG_SPL_PINCTRL=y
# CONFIG_SPL_PINCTRL_FULL is not set
CONFIG_ROCKCHIP_RK3288_PINCTRL=y
@ -58,6 +62,8 @@ CONFIG_DEBUG_UART_CLOCK=24000000
CONFIG_DEBUG_UART_SHIFT=2
CONFIG_SYS_NS16550=y
CONFIG_SYSRESET=y
CONFIG_USB=y
CONFIG_USB_STORAGE=y
CONFIG_USE_TINY_PRINTF=y
CONFIG_CMD_DHRYSTONE=y
CONFIG_ERRNO_STR=y

View file

@ -16,6 +16,7 @@ CONFIG_CMD_MMC=y
CONFIG_CMD_SF=y
CONFIG_CMD_SPI=y
CONFIG_CMD_I2C=y
CONFIG_CMD_USB=y
CONFIG_CMD_GPIO=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_CACHE=y
@ -28,7 +29,6 @@ CONFIG_CMD_REGULATOR=y
CONFIG_SPL_PARTITION_UUIDS=y
CONFIG_SPL_OF_CONTROL=y
CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents"
CONFIG_SPL_OF_PLATDATA=y
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_REGMAP=y
CONFIG_SPL_REGMAP=y
@ -65,6 +65,8 @@ CONFIG_DEBUG_UART_SHIFT=2
CONFIG_SYS_NS16550=y
CONFIG_ROCKCHIP_SERIAL=y
CONFIG_SYSRESET=y
CONFIG_USB=y
CONFIG_USB_STORAGE=y
CONFIG_DM_VIDEO=y
CONFIG_DISPLAY=y
CONFIG_VIDEO_ROCKCHIP=y

View file

@ -41,6 +41,10 @@ CONFIG_ROCKCHIP_GPIO=y
CONFIG_SYS_I2C_ROCKCHIP=y
CONFIG_MMC_DW=y
CONFIG_MMC_DW_ROCKCHIP=y
CONFIG_DM_ETH=y
CONFIG_NETDEVICES=y
CONFIG_ETH_DESIGNWARE=y
CONFIG_GMAC_ROCKCHIP=y
CONFIG_PINCTRL=y
CONFIG_SPL_PINCTRL=y
# CONFIG_SPL_PINCTRL_FULL is not set

View file

@ -17,6 +17,7 @@ CONFIG_CMD_MMC=y
CONFIG_CMD_SF=y
CONFIG_CMD_SPI=y
CONFIG_CMD_I2C=y
CONFIG_CMD_USB=y
CONFIG_CMD_GPIO=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_CACHE=y
@ -40,6 +41,10 @@ CONFIG_ROCKCHIP_GPIO=y
CONFIG_SYS_I2C_ROCKCHIP=y
CONFIG_MMC_DW=y
CONFIG_MMC_DW_ROCKCHIP=y
CONFIG_DM_ETH=y
CONFIG_NETDEVICES=y
CONFIG_ETH_DESIGNWARE=y
CONFIG_GMAC_ROCKCHIP=y
CONFIG_PINCTRL=y
CONFIG_SPL_PINCTRL=y
# CONFIG_SPL_PINCTRL_FULL is not set
@ -57,6 +62,8 @@ CONFIG_DEBUG_UART_CLOCK=24000000
CONFIG_DEBUG_UART_SHIFT=2
CONFIG_SYS_NS16550=y
CONFIG_SYSRESET=y
CONFIG_USB=y
CONFIG_USB_STORAGE=y
CONFIG_USE_TINY_PRINTF=y
CONFIG_CMD_DHRYSTONE=y
CONFIG_ERRNO_STR=y

View file

@ -0,0 +1,42 @@
Rockchip Dynamic Memory Controller Driver
Required properties:
- compatible: "rockchip,rk3399-dmc", "syscon"
- rockchip,cru: this driver should access cru regs, so need get cru here
- rockchip,pmucru: this driver should access pmucru regs, so need get pmucru here
- rockchip,pmugrf: this driver should access pmugrf regs, so need get pmugrf here
- rockchip,pmusgrf: this driver should access pmusgrf regs, so need get pmusgrf here
- rockchip,cic: this driver should access cic regs, so need get cic here
- reg: dynamic ram protocol controller(PCTL) address, PHY Independent(PI) address, phy controller(PHYCTL) address and memory schedule(MSCH) address
- clock: must include clock specifiers corresponding to entries in the clock-names property.
Must contain
dmc_clk: for ddr working frequency
- rockchip,sdram-params: SDRAM parameters, including all the information by ddr driver:
Must contain
Genarate by vendor tool and adjust for U-Boot dtsi.
Example:
dmc: dmc {
u-boot,dm-pre-reloc;
compatible = "rockchip,rk3399-dmc";
devfreq-events = <&dfi>;
interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH 0>;
clocks = <&cru SCLK_DDRCLK>;
clock-names = "dmc_clk";
reg = <0x0 0xffa80000 0x0 0x0800
0x0 0xffa80800 0x0 0x1800
0x0 0xffa82000 0x0 0x2000
0x0 0xffa84000 0x0 0x1000
0x0 0xffa88000 0x0 0x0800
0x0 0xffa88800 0x0 0x1800
0x0 0xffa8a000 0x0 0x2000
0x0 0xffa8c000 0x0 0x1000>;
};
&dmc {
rockchip,sdram-params = <
0x2
0xa
0x3
...
>;
};

View file

@ -825,6 +825,10 @@ drivers marked with DM_FLAG_PRE_RELOC or the device tree
'u-boot,dm-pre-reloc' flag are initialised prior to relocation. This helps
to reduce the driver model overhead.
It is possible to limit this to specific relocation steps, by using
the more specialized 'u-boot,dm-spl' and 'u-boot,dm-tpl' flags
in the devicetree.
Then post relocation we throw that away and re-init driver model again.
For drivers which require some sort of continuity between pre- and
post-relocation devices, we can provide access to the pre-relocation

View file

@ -10,6 +10,7 @@
#include <dm/device.h>
#include <dm/lists.h>
#include <dm/root.h>
#include <dm/util.h>
#include "pmc.h"
DECLARE_GLOBAL_DATA_PTR;
@ -56,7 +57,7 @@ int at91_clk_sub_device_bind(struct udevice *dev, const char *drv_name)
offset > 0;
offset = fdt_next_subnode(fdt, offset)) {
if (pre_reloc_only &&
!fdt_getprop(fdt, offset, "u-boot,dm-pre-reloc", NULL))
!dm_fdt_pre_reloc(fdt, offset))
continue;
/*
* If this node has "compatible" property, this is not

View file

@ -5,5 +5,7 @@
#
obj-$(CONFIG_ROCKCHIP_RK3036) += clk_rk3036.o
obj-$(CONFIG_ROCKCHIP_RK3188) += clk_rk3188.o
obj-$(CONFIG_ROCKCHIP_RK3288) += clk_rk3288.o
obj-$(CONFIG_ROCKCHIP_RK3328) += clk_rk3328.o
obj-$(CONFIG_ROCKCHIP_RK3399) += clk_rk3399.o

View file

@ -0,0 +1,527 @@
/*
* (C) Copyright 2015 Google, Inc
* (C) Copyright 2016 Heiko Stuebner <heiko@sntech.de>
*
* SPDX-License-Identifier: GPL-2.0
*/
#include <common.h>
#include <clk-uclass.h>
#include <dm.h>
#include <dt-structs.h>
#include <errno.h>
#include <mapmem.h>
#include <syscon.h>
#include <asm/io.h>
#include <asm/arch/clock.h>
#include <asm/arch/cru_rk3188.h>
#include <asm/arch/grf_rk3188.h>
#include <asm/arch/hardware.h>
#include <dt-bindings/clock/rk3188-cru.h>
#include <dm/device-internal.h>
#include <dm/lists.h>
#include <dm/uclass-internal.h>
#include <linux/log2.h>
DECLARE_GLOBAL_DATA_PTR;
enum rk3188_clk_type {
RK3188_CRU,
RK3188A_CRU,
};
struct rk3188_clk_plat {
#if CONFIG_IS_ENABLED(OF_PLATDATA)
struct dtd_rockchip_rk3188_cru dtd;
#endif
};
struct pll_div {
u32 nr;
u32 nf;
u32 no;
};
enum {
VCO_MAX_HZ = 2200U * 1000000,
VCO_MIN_HZ = 440 * 1000000,
OUTPUT_MAX_HZ = 2200U * 1000000,
OUTPUT_MIN_HZ = 30 * 1000000,
FREF_MAX_HZ = 2200U * 1000000,
FREF_MIN_HZ = 30 * 1000,
};
enum {
/* PLL CON0 */
PLL_OD_MASK = 0x0f,
/* PLL CON1 */
PLL_NF_MASK = 0x1fff,
/* PLL CON2 */
PLL_BWADJ_MASK = 0x0fff,
/* PLL CON3 */
PLL_RESET_SHIFT = 5,
/* GRF_SOC_STATUS0 */
SOCSTS_DPLL_LOCK = 1 << 5,
SOCSTS_APLL_LOCK = 1 << 6,
SOCSTS_CPLL_LOCK = 1 << 7,
SOCSTS_GPLL_LOCK = 1 << 8,
};
#define RATE_TO_DIV(input_rate, output_rate) \
((input_rate) / (output_rate) - 1);
#define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1))
#define PLL_DIVISORS(hz, _nr, _no) {\
.nr = _nr, .nf = (u32)((u64)hz * _nr * _no / OSC_HZ), .no = _no};\
_Static_assert(((u64)hz * _nr * _no / OSC_HZ) * OSC_HZ /\
(_nr * _no) == hz, #hz "Hz cannot be hit with PLL "\
"divisors on line " __stringify(__LINE__));
/* Keep divisors as low as possible to reduce jitter and power usage */
#ifdef CONFIG_SPL_BUILD
static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 2, 2);
static const struct pll_div cpll_init_cfg = PLL_DIVISORS(CPLL_HZ, 1, 2);
#endif
static int rkclk_set_pll(struct rk3188_cru *cru, enum rk_clk_id clk_id,
const struct pll_div *div, bool has_bwadj)
{
int pll_id = rk_pll_id(clk_id);
struct rk3188_pll *pll = &cru->pll[pll_id];
/* All PLLs have same VCO and output frequency range restrictions. */
uint vco_hz = OSC_HZ / 1000 * div->nf / div->nr * 1000;
uint output_hz = vco_hz / div->no;
debug("PLL at %x: nf=%d, nr=%d, no=%d, vco=%u Hz, output=%u Hz\n",
(uint)pll, div->nf, div->nr, div->no, vco_hz, output_hz);
assert(vco_hz >= VCO_MIN_HZ && vco_hz <= VCO_MAX_HZ &&
output_hz >= OUTPUT_MIN_HZ && output_hz <= OUTPUT_MAX_HZ &&
(div->no == 1 || !(div->no % 2)));
/* enter reset */
rk_setreg(&pll->con3, 1 << PLL_RESET_SHIFT);
rk_clrsetreg(&pll->con0,
CLKR_MASK << CLKR_SHIFT | PLL_OD_MASK,
((div->nr - 1) << CLKR_SHIFT) | (div->no - 1));
rk_clrsetreg(&pll->con1, CLKF_MASK, div->nf - 1);
if (has_bwadj)
rk_clrsetreg(&pll->con2, PLL_BWADJ_MASK, (div->nf >> 1) - 1);
udelay(10);
/* return from reset */
rk_clrreg(&pll->con3, 1 << PLL_RESET_SHIFT);
return 0;
}
static int rkclk_configure_ddr(struct rk3188_cru *cru, struct rk3188_grf *grf,
unsigned int hz, bool has_bwadj)
{
static const struct pll_div dpll_cfg[] = {
{.nf = 25, .nr = 2, .no = 1},
{.nf = 400, .nr = 9, .no = 2},
{.nf = 500, .nr = 9, .no = 2},
{.nf = 100, .nr = 3, .no = 1},
};
int cfg;
switch (hz) {
case 300000000:
cfg = 0;
break;
case 533000000: /* actually 533.3P MHz */
cfg = 1;
break;
case 666000000: /* actually 666.6P MHz */
cfg = 2;
break;
case 800000000:
cfg = 3;
break;
default:
debug("Unsupported SDRAM frequency");
return -EINVAL;
}
/* pll enter slow-mode */
rk_clrsetreg(&cru->cru_mode_con, DPLL_MODE_MASK << DPLL_MODE_SHIFT,
DPLL_MODE_SLOW << DPLL_MODE_SHIFT);
rkclk_set_pll(cru, CLK_DDR, &dpll_cfg[cfg], has_bwadj);
/* wait for pll lock */
while (!(readl(&grf->soc_status0) & SOCSTS_DPLL_LOCK))
udelay(1);
/* PLL enter normal-mode */
rk_clrsetreg(&cru->cru_mode_con, DPLL_MODE_MASK << DPLL_MODE_SHIFT,
DPLL_MODE_NORMAL << DPLL_MODE_SHIFT);
return 0;
}
/* Get pll rate by id */
static uint32_t rkclk_pll_get_rate(struct rk3188_cru *cru,
enum rk_clk_id clk_id)
{
uint32_t nr, no, nf;
uint32_t con;
int pll_id = rk_pll_id(clk_id);
struct rk3188_pll *pll = &cru->pll[pll_id];
static u8 clk_shift[CLK_COUNT] = {
0xff, APLL_MODE_SHIFT, DPLL_MODE_SHIFT, CPLL_MODE_SHIFT,
GPLL_MODE_SHIFT
};
uint shift;
con = readl(&cru->cru_mode_con);
shift = clk_shift[clk_id];
switch ((con >> shift) & APLL_MODE_MASK) {
case APLL_MODE_SLOW:
return OSC_HZ;
case APLL_MODE_NORMAL:
/* normal mode */
con = readl(&pll->con0);
no = ((con >> CLKOD_SHIFT) & CLKOD_MASK) + 1;
nr = ((con >> CLKR_SHIFT) & CLKR_MASK) + 1;
con = readl(&pll->con1);
nf = ((con >> CLKF_SHIFT) & CLKF_MASK) + 1;
return (24 * nf / (nr * no)) * 1000000;
case APLL_MODE_DEEP:
default:
return 32768;
}
}
static ulong rockchip_mmc_get_clk(struct rk3188_cru *cru, uint gclk_rate,
int periph)
{
uint div;
u32 con;
switch (periph) {
case HCLK_EMMC:
con = readl(&cru->cru_clksel_con[12]);
div = (con >> EMMC_DIV_SHIFT) & EMMC_DIV_MASK;
break;
case HCLK_SDMMC:
con = readl(&cru->cru_clksel_con[11]);
div = (con >> MMC0_DIV_SHIFT) & MMC0_DIV_MASK;
break;
case HCLK_SDIO:
con = readl(&cru->cru_clksel_con[12]);
div = (con >> SDIO_DIV_SHIFT) & SDIO_DIV_MASK;
break;
default:
return -EINVAL;
}
return DIV_TO_RATE(gclk_rate, div);
}
static ulong rockchip_mmc_set_clk(struct rk3188_cru *cru, uint gclk_rate,
int periph, uint freq)
{
int src_clk_div;
debug("%s: gclk_rate=%u\n", __func__, gclk_rate);
src_clk_div = RATE_TO_DIV(gclk_rate, freq);
assert(src_clk_div <= 0x3f);
switch (periph) {
case HCLK_EMMC:
rk_clrsetreg(&cru->cru_clksel_con[12],
EMMC_DIV_MASK << EMMC_DIV_SHIFT,
src_clk_div << EMMC_DIV_SHIFT);
break;
case HCLK_SDMMC:
rk_clrsetreg(&cru->cru_clksel_con[11],
MMC0_DIV_MASK << MMC0_DIV_SHIFT,
src_clk_div << MMC0_DIV_SHIFT);
break;
case HCLK_SDIO:
rk_clrsetreg(&cru->cru_clksel_con[12],
SDIO_DIV_MASK << SDIO_DIV_SHIFT,
src_clk_div << SDIO_DIV_SHIFT);
break;
default:
return -EINVAL;
}
return rockchip_mmc_get_clk(cru, gclk_rate, periph);
}
static ulong rockchip_spi_get_clk(struct rk3188_cru *cru, uint gclk_rate,
int periph)
{
uint div;
u32 con;
switch (periph) {
case SCLK_SPI0:
con = readl(&cru->cru_clksel_con[25]);
div = (con >> SPI0_DIV_SHIFT) & SPI0_DIV_MASK;
break;
case SCLK_SPI1:
con = readl(&cru->cru_clksel_con[25]);
div = (con >> SPI1_DIV_SHIFT) & SPI1_DIV_MASK;
break;
default:
return -EINVAL;
}
return DIV_TO_RATE(gclk_rate, div);
}
static ulong rockchip_spi_set_clk(struct rk3188_cru *cru, uint gclk_rate,
int periph, uint freq)
{
int src_clk_div = RATE_TO_DIV(gclk_rate, freq);
switch (periph) {
case SCLK_SPI0:
assert(src_clk_div <= SPI0_DIV_MASK);
rk_clrsetreg(&cru->cru_clksel_con[25],
SPI0_DIV_MASK << SPI0_DIV_SHIFT,
src_clk_div << SPI0_DIV_SHIFT);
break;
case SCLK_SPI1:
assert(src_clk_div <= SPI1_DIV_MASK);
rk_clrsetreg(&cru->cru_clksel_con[25],
SPI1_DIV_MASK << SPI1_DIV_SHIFT,
src_clk_div << SPI1_DIV_SHIFT);
break;
default:
return -EINVAL;
}
return rockchip_spi_get_clk(cru, gclk_rate, periph);
}
#ifdef CONFIG_SPL_BUILD
static void rkclk_init(struct rk3188_cru *cru, struct rk3188_grf *grf,
bool has_bwadj)
{
u32 aclk_div, hclk_div, pclk_div, h2p_div;
/* pll enter slow-mode */
rk_clrsetreg(&cru->cru_mode_con,
GPLL_MODE_MASK << GPLL_MODE_SHIFT |
CPLL_MODE_MASK << CPLL_MODE_SHIFT,
GPLL_MODE_SLOW << GPLL_MODE_SHIFT |
CPLL_MODE_SLOW << CPLL_MODE_SHIFT);
/* init pll */
rkclk_set_pll(cru, CLK_GENERAL, &gpll_init_cfg, has_bwadj);
rkclk_set_pll(cru, CLK_CODEC, &cpll_init_cfg, has_bwadj);
/* waiting for pll lock */
while ((readl(&grf->soc_status0) &
(SOCSTS_CPLL_LOCK | SOCSTS_GPLL_LOCK)) !=
(SOCSTS_CPLL_LOCK | SOCSTS_GPLL_LOCK))
udelay(1);
/*
* cpu clock pll source selection and
* reparent aclk_cpu_pre from apll to gpll
* set up dependent divisors for PCLK/HCLK and ACLK clocks.
*/
aclk_div = RATE_TO_DIV(GPLL_HZ, CPU_ACLK_HZ);
assert((aclk_div + 1) * CPU_ACLK_HZ == GPLL_HZ && aclk_div < 0x1f);
rk_clrsetreg(&cru->cru_clksel_con[0],
CPU_ACLK_PLL_MASK << CPU_ACLK_PLL_SHIFT |
A9_CPU_DIV_MASK << A9_CPU_DIV_SHIFT,
CPU_ACLK_PLL_SELECT_GPLL << CPU_ACLK_PLL_SHIFT |
aclk_div << A9_CPU_DIV_SHIFT);
hclk_div = ilog2(CPU_ACLK_HZ / CPU_HCLK_HZ);
assert((1 << hclk_div) * CPU_HCLK_HZ == CPU_ACLK_HZ && hclk_div < 0x3);
pclk_div = ilog2(CPU_ACLK_HZ / CPU_PCLK_HZ);
assert((1 << pclk_div) * CPU_PCLK_HZ == CPU_ACLK_HZ && pclk_div < 0x4);
h2p_div = ilog2(CPU_HCLK_HZ / CPU_H2P_HZ);
assert((1 << h2p_div) * CPU_H2P_HZ == CPU_HCLK_HZ && pclk_div < 0x3);
rk_clrsetreg(&cru->cru_clksel_con[1],
AHB2APB_DIV_MASK << AHB2APB_DIV_SHIFT |
CPU_PCLK_DIV_MASK << CPU_PCLK_DIV_SHIFT |
CPU_HCLK_DIV_MASK << CPU_HCLK_DIV_SHIFT,
h2p_div << AHB2APB_DIV_SHIFT |
pclk_div << CPU_PCLK_DIV_SHIFT |
hclk_div << CPU_HCLK_DIV_SHIFT);
/*
* peri clock pll source selection and
* set up dependent divisors for PCLK/HCLK and ACLK clocks.
*/
aclk_div = GPLL_HZ / PERI_ACLK_HZ - 1;
assert((aclk_div + 1) * PERI_ACLK_HZ == GPLL_HZ && aclk_div < 0x1f);
hclk_div = ilog2(PERI_ACLK_HZ / PERI_HCLK_HZ);
assert((1 << hclk_div) * PERI_HCLK_HZ ==
PERI_ACLK_HZ && (hclk_div < 0x4));
pclk_div = ilog2(PERI_ACLK_HZ / PERI_PCLK_HZ);
assert((1 << pclk_div) * PERI_PCLK_HZ ==
PERI_ACLK_HZ && (pclk_div < 0x4));
rk_clrsetreg(&cru->cru_clksel_con[10],
PERI_PCLK_DIV_MASK << PERI_PCLK_DIV_SHIFT |
PERI_HCLK_DIV_MASK << PERI_HCLK_DIV_SHIFT |
PERI_ACLK_DIV_MASK << PERI_ACLK_DIV_SHIFT,
PERI_SEL_GPLL << PERI_SEL_PLL_SHIFT |
pclk_div << PERI_PCLK_DIV_SHIFT |
hclk_div << PERI_HCLK_DIV_SHIFT |
aclk_div << PERI_ACLK_DIV_SHIFT);
/* PLL enter normal-mode */
rk_clrsetreg(&cru->cru_mode_con,
GPLL_MODE_MASK << GPLL_MODE_SHIFT |
CPLL_MODE_MASK << CPLL_MODE_SHIFT,
GPLL_MODE_NORMAL << GPLL_MODE_SHIFT |
CPLL_MODE_NORMAL << CPLL_MODE_SHIFT);
rockchip_mmc_set_clk(cru, PERI_HCLK_HZ, HCLK_SDMMC, 16000000);
}
#endif
static ulong rk3188_clk_get_rate(struct clk *clk)
{
struct rk3188_clk_priv *priv = dev_get_priv(clk->dev);
ulong new_rate, gclk_rate;
gclk_rate = rkclk_pll_get_rate(priv->cru, CLK_GENERAL);
switch (clk->id) {
case 1 ... 4:
new_rate = rkclk_pll_get_rate(priv->cru, clk->id);
break;
case HCLK_EMMC:
case HCLK_SDMMC:
case HCLK_SDIO:
new_rate = rockchip_mmc_get_clk(priv->cru, PERI_HCLK_HZ,
clk->id);
break;
case SCLK_SPI0:
case SCLK_SPI1:
new_rate = rockchip_spi_get_clk(priv->cru, PERI_PCLK_HZ,
clk->id);
break;
case PCLK_I2C0:
case PCLK_I2C1:
case PCLK_I2C2:
case PCLK_I2C3:
case PCLK_I2C4:
return gclk_rate;
default:
return -ENOENT;
}
return new_rate;
}
static ulong rk3188_clk_set_rate(struct clk *clk, ulong rate)
{
struct rk3188_clk_priv *priv = dev_get_priv(clk->dev);
struct rk3188_cru *cru = priv->cru;
ulong new_rate;
switch (clk->id) {
case CLK_DDR:
new_rate = rkclk_configure_ddr(priv->cru, priv->grf, rate,
priv->has_bwadj);
break;
case HCLK_EMMC:
case HCLK_SDMMC:
case HCLK_SDIO:
new_rate = rockchip_mmc_set_clk(cru, PERI_HCLK_HZ,
clk->id, rate);
break;
case SCLK_SPI0:
case SCLK_SPI1:
new_rate = rockchip_spi_set_clk(cru, PERI_PCLK_HZ,
clk->id, rate);
break;
default:
return -ENOENT;
}
return new_rate;
}
static struct clk_ops rk3188_clk_ops = {
.get_rate = rk3188_clk_get_rate,
.set_rate = rk3188_clk_set_rate,
};
static int rk3188_clk_ofdata_to_platdata(struct udevice *dev)
{
#if !CONFIG_IS_ENABLED(OF_PLATDATA)
struct rk3188_clk_priv *priv = dev_get_priv(dev);
priv->cru = (struct rk3188_cru *)dev_get_addr(dev);
#endif
return 0;
}
static int rk3188_clk_probe(struct udevice *dev)
{
struct rk3188_clk_priv *priv = dev_get_priv(dev);
enum rk3188_clk_type type = dev_get_driver_data(dev);
priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
if (IS_ERR(priv->grf))
return PTR_ERR(priv->grf);
priv->has_bwadj = (type == RK3188A_CRU) ? 1 : 0;
#ifdef CONFIG_SPL_BUILD
#if CONFIG_IS_ENABLED(OF_PLATDATA)
struct rk3188_clk_plat *plat = dev_get_platdata(dev);
priv->cru = map_sysmem(plat->dtd.reg[0], plat->dtd.reg[1]);
#endif
rkclk_init(priv->cru, priv->grf, priv->has_bwadj);
#endif
return 0;
}
static int rk3188_clk_bind(struct udevice *dev)
{
int ret;
/* The reset driver does not have a device node, so bind it here */
ret = device_bind_driver(gd->dm_root, "rk3188_sysreset", "reset", &dev);
if (ret)
debug("Warning: No rk3188 reset driver: ret=%d\n", ret);
return 0;
}
static const struct udevice_id rk3188_clk_ids[] = {
{ .compatible = "rockchip,rk3188-cru", .data = RK3188_CRU },
{ .compatible = "rockchip,rk3188a-cru", .data = RK3188A_CRU },
{ }
};
U_BOOT_DRIVER(rockchip_rk3188_cru) = {
.name = "rockchip_rk3188_cru",
.id = UCLASS_CLK,
.of_match = rk3188_clk_ids,
.priv_auto_alloc_size = sizeof(struct rk3188_clk_priv),
.platdata_auto_alloc_size = sizeof(struct rk3188_clk_plat),
.ops = &rk3188_clk_ops,
.bind = rk3188_clk_bind,
.ofdata_to_platdata = rk3188_clk_ofdata_to_platdata,
.probe = rk3188_clk_probe,
};

View file

@ -131,8 +131,10 @@ enum {
/* Keep divisors as low as possible to reduce jitter and power usage */
static const struct pll_div apll_init_cfg = PLL_DIVISORS(APLL_HZ, 1, 1);
#ifdef CONFIG_SPL_BUILD
static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 2, 2);
static const struct pll_div cpll_init_cfg = PLL_DIVISORS(CPLL_HZ, 1, 2);
#endif
static int rkclk_set_pll(struct rk3288_cru *cru, enum rk_clk_id clk_id,
const struct pll_div *div)

View file

@ -0,0 +1,581 @@
/*
* (C) Copyright 2017 Rockchip Electronics Co., Ltd
*
* SPDX-License-Identifier: GPL-2.0
*/
#include <common.h>
#include <clk-uclass.h>
#include <dm.h>
#include <errno.h>
#include <syscon.h>
#include <asm/arch/clock.h>
#include <asm/arch/cru_rk3328.h>
#include <asm/arch/hardware.h>
#include <asm/io.h>
#include <dm/lists.h>
#include <dt-bindings/clock/rk3328-cru.h>
DECLARE_GLOBAL_DATA_PTR;
struct pll_div {
u32 refdiv;
u32 fbdiv;
u32 postdiv1;
u32 postdiv2;
u32 frac;
};
#define RATE_TO_DIV(input_rate, output_rate) \
((input_rate) / (output_rate) - 1);
#define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1))
#define PLL_DIVISORS(hz, _refdiv, _postdiv1, _postdiv2) {\
.refdiv = _refdiv,\
.fbdiv = (u32)((u64)hz * _refdiv * _postdiv1 * _postdiv2 / OSC_HZ),\
.postdiv1 = _postdiv1, .postdiv2 = _postdiv2};
static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 1, 4, 1);
static const struct pll_div cpll_init_cfg = PLL_DIVISORS(CPLL_HZ, 2, 2, 1);
static const struct pll_div apll_816_cfg = PLL_DIVISORS(816 * MHz, 1, 2, 1);
static const struct pll_div apll_600_cfg = PLL_DIVISORS(600 * MHz, 1, 3, 1);
static const struct pll_div *apll_cfgs[] = {
[APLL_816_MHZ] = &apll_816_cfg,
[APLL_600_MHZ] = &apll_600_cfg,
};
enum {
/* PLL_CON0 */
PLL_POSTDIV1_SHIFT = 12,
PLL_POSTDIV1_MASK = 0x7 << PLL_POSTDIV1_SHIFT,
PLL_FBDIV_SHIFT = 0,
PLL_FBDIV_MASK = 0xfff,
/* PLL_CON1 */
PLL_DSMPD_SHIFT = 12,
PLL_DSMPD_MASK = 1 << PLL_DSMPD_SHIFT,
PLL_INTEGER_MODE = 1,
PLL_LOCK_STATUS_SHIFT = 10,
PLL_LOCK_STATUS_MASK = 1 << PLL_LOCK_STATUS_SHIFT,
PLL_POSTDIV2_SHIFT = 6,
PLL_POSTDIV2_MASK = 0x7 << PLL_POSTDIV2_SHIFT,
PLL_REFDIV_SHIFT = 0,
PLL_REFDIV_MASK = 0x3f,
/* PLL_CON2 */
PLL_FRACDIV_SHIFT = 0,
PLL_FRACDIV_MASK = 0xffffff,
/* MODE_CON */
APLL_MODE_SHIFT = 0,
NPLL_MODE_SHIFT = 1,
DPLL_MODE_SHIFT = 4,
CPLL_MODE_SHIFT = 8,
GPLL_MODE_SHIFT = 12,
PLL_MODE_SLOW = 0,
PLL_MODE_NORM,
/* CLKSEL_CON0 */
CLK_CORE_PLL_SEL_APLL = 0,
CLK_CORE_PLL_SEL_GPLL,
CLK_CORE_PLL_SEL_DPLL,
CLK_CORE_PLL_SEL_NPLL,
CLK_CORE_PLL_SEL_SHIFT = 6,
CLK_CORE_PLL_SEL_MASK = 3 << CLK_CORE_PLL_SEL_SHIFT,
CLK_CORE_DIV_SHIFT = 0,
CLK_CORE_DIV_MASK = 0x1f,
/* CLKSEL_CON1 */
ACLKM_CORE_DIV_SHIFT = 4,
ACLKM_CORE_DIV_MASK = 0x7 << ACLKM_CORE_DIV_SHIFT,
PCLK_DBG_DIV_SHIFT = 0,
PCLK_DBG_DIV_MASK = 0xF << PCLK_DBG_DIV_SHIFT,
/* CLKSEL_CON28 */
ACLK_PERIHP_PLL_SEL_CPLL = 0,
ACLK_PERIHP_PLL_SEL_GPLL,
ACLK_PERIHP_PLL_SEL_HDMIPHY,
ACLK_PERIHP_PLL_SEL_SHIFT = 6,
ACLK_PERIHP_PLL_SEL_MASK = 3 << ACLK_PERIHP_PLL_SEL_SHIFT,
ACLK_PERIHP_DIV_CON_SHIFT = 0,
ACLK_PERIHP_DIV_CON_MASK = 0x1f,
/* CLKSEL_CON29 */
PCLK_PERIHP_DIV_CON_SHIFT = 4,
PCLK_PERIHP_DIV_CON_MASK = 0x7 << PCLK_PERIHP_DIV_CON_SHIFT,
HCLK_PERIHP_DIV_CON_SHIFT = 0,
HCLK_PERIHP_DIV_CON_MASK = 3 << HCLK_PERIHP_DIV_CON_SHIFT,
/* CLKSEL_CON22 */
CLK_TSADC_DIV_CON_SHIFT = 0,
CLK_TSADC_DIV_CON_MASK = 0x3ff,
/* CLKSEL_CON23 */
CLK_SARADC_DIV_CON_SHIFT = 0,
CLK_SARADC_DIV_CON_MASK = 0x3ff << CLK_SARADC_DIV_CON_SHIFT,
/* CLKSEL_CON24 */
CLK_PWM_PLL_SEL_CPLL = 0,
CLK_PWM_PLL_SEL_GPLL,
CLK_PWM_PLL_SEL_SHIFT = 15,
CLK_PWM_PLL_SEL_MASK = 1 << CLK_PWM_PLL_SEL_SHIFT,
CLK_PWM_DIV_CON_SHIFT = 8,
CLK_PWM_DIV_CON_MASK = 0x7f << CLK_PWM_DIV_CON_SHIFT,
CLK_SPI_PLL_SEL_CPLL = 0,
CLK_SPI_PLL_SEL_GPLL,
CLK_SPI_PLL_SEL_SHIFT = 7,
CLK_SPI_PLL_SEL_MASK = 1 << CLK_SPI_PLL_SEL_SHIFT,
CLK_SPI_DIV_CON_SHIFT = 0,
CLK_SPI_DIV_CON_MASK = 0x7f << CLK_SPI_DIV_CON_SHIFT,
/* CLKSEL_CON30 */
CLK_SDMMC_PLL_SEL_CPLL = 0,
CLK_SDMMC_PLL_SEL_GPLL,
CLK_SDMMC_PLL_SEL_24M,
CLK_SDMMC_PLL_SEL_USBPHY,
CLK_SDMMC_PLL_SHIFT = 8,
CLK_SDMMC_PLL_MASK = 0x3 << CLK_SDMMC_PLL_SHIFT,
CLK_SDMMC_DIV_CON_SHIFT = 0,
CLK_SDMMC_DIV_CON_MASK = 0xff << CLK_SDMMC_DIV_CON_SHIFT,
/* CLKSEL_CON32 */
CLK_EMMC_PLL_SEL_CPLL = 0,
CLK_EMMC_PLL_SEL_GPLL,
CLK_EMMC_PLL_SEL_24M,
CLK_EMMC_PLL_SEL_USBPHY,
CLK_EMMC_PLL_SHIFT = 8,
CLK_EMMC_PLL_MASK = 0x3 << CLK_EMMC_PLL_SHIFT,
CLK_EMMC_DIV_CON_SHIFT = 0,
CLK_EMMC_DIV_CON_MASK = 0xff << CLK_EMMC_DIV_CON_SHIFT,
/* CLKSEL_CON34 */
CLK_I2C_PLL_SEL_CPLL = 0,
CLK_I2C_PLL_SEL_GPLL,
CLK_I2C_DIV_CON_MASK = 0x7f,
CLK_I2C_PLL_SEL_MASK = 1,
CLK_I2C1_PLL_SEL_SHIFT = 15,
CLK_I2C1_DIV_CON_SHIFT = 8,
CLK_I2C0_PLL_SEL_SHIFT = 7,
CLK_I2C0_DIV_CON_SHIFT = 0,
/* CLKSEL_CON35 */
CLK_I2C3_PLL_SEL_SHIFT = 15,
CLK_I2C3_DIV_CON_SHIFT = 8,
CLK_I2C2_PLL_SEL_SHIFT = 7,
CLK_I2C2_DIV_CON_SHIFT = 0,
};
#define VCO_MAX_KHZ (3200 * (MHz / KHz))
#define VCO_MIN_KHZ (800 * (MHz / KHz))
#define OUTPUT_MAX_KHZ (3200 * (MHz / KHz))
#define OUTPUT_MIN_KHZ (16 * (MHz / KHz))
/*
* the div restructions of pll in integer mode, these are defined in
* * CRU_*PLL_CON0 or PMUCRU_*PLL_CON0
*/
#define PLL_DIV_MIN 16
#define PLL_DIV_MAX 3200
/*
* How to calculate the PLL(from TRM V0.3 Part 1 Page 63):
* Formulas also embedded within the Fractional PLL Verilog model:
* If DSMPD = 1 (DSM is disabled, "integer mode")
* FOUTVCO = FREF / REFDIV * FBDIV
* FOUTPOSTDIV = FOUTVCO / POSTDIV1 / POSTDIV2
* Where:
* FOUTVCO = Fractional PLL non-divided output frequency
* FOUTPOSTDIV = Fractional PLL divided output frequency
* (output of second post divider)
* FREF = Fractional PLL input reference frequency, (the OSC_HZ 24MHz input)
* REFDIV = Fractional PLL input reference clock divider
* FBDIV = Integer value programmed into feedback divide
*
*/
static void rkclk_set_pll(struct rk3328_cru *cru, enum rk_clk_id clk_id,
const struct pll_div *div)
{
u32 *pll_con;
u32 mode_shift, mode_mask;
pll_con = NULL;
mode_shift = 0;
switch (clk_id) {
case CLK_ARM:
pll_con = cru->apll_con;
mode_shift = APLL_MODE_SHIFT;
break;
case CLK_DDR:
pll_con = cru->dpll_con;
mode_shift = DPLL_MODE_SHIFT;
break;
case CLK_CODEC:
pll_con = cru->cpll_con;
mode_shift = CPLL_MODE_SHIFT;
break;
case CLK_GENERAL:
pll_con = cru->gpll_con;
mode_shift = GPLL_MODE_SHIFT;
break;
case CLK_NEW:
pll_con = cru->npll_con;
mode_shift = NPLL_MODE_SHIFT;
break;
default:
break;
}
mode_mask = 1 << mode_shift;
/* All 8 PLLs have same VCO and output frequency range restrictions. */
u32 vco_khz = OSC_HZ / 1000 * div->fbdiv / div->refdiv;
u32 output_khz = vco_khz / div->postdiv1 / div->postdiv2;
debug("PLL at %p: fbdiv=%d, refdiv=%d, postdiv1=%d, \
postdiv2=%d, vco=%u khz, output=%u khz\n",
pll_con, div->fbdiv, div->refdiv, div->postdiv1,
div->postdiv2, vco_khz, output_khz);
assert(vco_khz >= VCO_MIN_KHZ && vco_khz <= VCO_MAX_KHZ &&
output_khz >= OUTPUT_MIN_KHZ && output_khz <= OUTPUT_MAX_KHZ &&
div->fbdiv >= PLL_DIV_MIN && div->fbdiv <= PLL_DIV_MAX);
/*
* When power on or changing PLL setting,
* we must force PLL into slow mode to ensure output stable clock.
*/
rk_clrsetreg(&cru->mode_con, mode_mask, PLL_MODE_SLOW << mode_shift);
/* use integer mode */
rk_clrsetreg(&pll_con[1], PLL_DSMPD_MASK,
PLL_INTEGER_MODE << PLL_DSMPD_SHIFT);
rk_clrsetreg(&pll_con[0],
PLL_FBDIV_MASK | PLL_POSTDIV1_MASK,
(div->fbdiv << PLL_FBDIV_SHIFT) |
(div->postdiv1 << PLL_POSTDIV1_SHIFT));
rk_clrsetreg(&pll_con[1],
PLL_POSTDIV2_MASK | PLL_REFDIV_MASK,
(div->postdiv2 << PLL_POSTDIV2_SHIFT) |
(div->refdiv << PLL_REFDIV_SHIFT));
/* waiting for pll lock */
while (!(readl(&pll_con[1]) & (1 << PLL_LOCK_STATUS_SHIFT)))
udelay(1);
/* pll enter normal mode */
rk_clrsetreg(&cru->mode_con, mode_mask, PLL_MODE_NORM << mode_shift);
}
static void rkclk_init(struct rk3328_cru *cru)
{
u32 aclk_div;
u32 hclk_div;
u32 pclk_div;
/* configure gpll cpll */
rkclk_set_pll(cru, CLK_GENERAL, &gpll_init_cfg);
rkclk_set_pll(cru, CLK_CODEC, &cpll_init_cfg);
/* configure perihp aclk, hclk, pclk */
aclk_div = GPLL_HZ / PERIHP_ACLK_HZ - 1;
hclk_div = PERIHP_ACLK_HZ / PERIHP_HCLK_HZ - 1;
pclk_div = PERIHP_ACLK_HZ / PERIHP_PCLK_HZ - 1;
rk_clrsetreg(&cru->clksel_con[28],
ACLK_PERIHP_PLL_SEL_MASK | ACLK_PERIHP_DIV_CON_MASK,
ACLK_PERIHP_PLL_SEL_GPLL << ACLK_PERIHP_PLL_SEL_SHIFT |
aclk_div << ACLK_PERIHP_DIV_CON_SHIFT);
rk_clrsetreg(&cru->clksel_con[29],
PCLK_PERIHP_DIV_CON_MASK | HCLK_PERIHP_DIV_CON_MASK,
pclk_div << PCLK_PERIHP_DIV_CON_SHIFT |
hclk_div << HCLK_PERIHP_DIV_CON_SHIFT);
}
void rk3328_configure_cpu(struct rk3328_cru *cru,
enum apll_frequencies apll_freq)
{
u32 clk_core_div;
u32 aclkm_div;
u32 pclk_dbg_div;
rkclk_set_pll(cru, CLK_ARM, apll_cfgs[apll_freq]);
clk_core_div = APLL_HZ / CLK_CORE_HZ - 1;
aclkm_div = APLL_HZ / ACLKM_CORE_HZ / (clk_core_div + 1) - 1;
pclk_dbg_div = APLL_HZ / PCLK_DBG_HZ / (clk_core_div + 1) - 1;
rk_clrsetreg(&cru->clksel_con[0],
CLK_CORE_PLL_SEL_MASK | CLK_CORE_DIV_MASK,
CLK_CORE_PLL_SEL_APLL << CLK_CORE_PLL_SEL_SHIFT |
clk_core_div << CLK_CORE_DIV_SHIFT);
rk_clrsetreg(&cru->clksel_con[1],
PCLK_DBG_DIV_MASK | ACLKM_CORE_DIV_MASK,
pclk_dbg_div << PCLK_DBG_DIV_SHIFT |
aclkm_div << ACLKM_CORE_DIV_SHIFT);
}
static ulong rk3328_i2c_get_clk(struct rk3328_cru *cru, ulong clk_id)
{
u32 div, con;
switch (clk_id) {
case SCLK_I2C0:
con = readl(&cru->clksel_con[34]);
div = con >> CLK_I2C0_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK;
break;
case SCLK_I2C1:
con = readl(&cru->clksel_con[34]);
div = con >> CLK_I2C1_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK;
break;
case SCLK_I2C2:
con = readl(&cru->clksel_con[35]);
div = con >> CLK_I2C2_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK;
break;
case SCLK_I2C3:
con = readl(&cru->clksel_con[35]);
div = con >> CLK_I2C3_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK;
break;
default:
printf("do not support this i2c bus\n");
return -EINVAL;
}
return DIV_TO_RATE(GPLL_HZ, div);
}
static ulong rk3328_i2c_set_clk(struct rk3328_cru *cru, ulong clk_id, uint hz)
{
int src_clk_div;
src_clk_div = GPLL_HZ / hz;
assert(src_clk_div - 1 < 127);
switch (clk_id) {
case SCLK_I2C0:
rk_clrsetreg(&cru->clksel_con[34],
CLK_I2C_DIV_CON_MASK << CLK_I2C0_DIV_CON_SHIFT |
CLK_I2C_PLL_SEL_MASK << CLK_I2C0_PLL_SEL_SHIFT,
(src_clk_div - 1) << CLK_I2C0_DIV_CON_SHIFT |
CLK_I2C_PLL_SEL_GPLL << CLK_I2C0_PLL_SEL_SHIFT);
break;
case SCLK_I2C1:
rk_clrsetreg(&cru->clksel_con[34],
CLK_I2C_DIV_CON_MASK << CLK_I2C1_DIV_CON_SHIFT |
CLK_I2C_PLL_SEL_MASK << CLK_I2C1_PLL_SEL_SHIFT,
(src_clk_div - 1) << CLK_I2C1_DIV_CON_SHIFT |
CLK_I2C_PLL_SEL_GPLL << CLK_I2C1_PLL_SEL_SHIFT);
break;
case SCLK_I2C2:
rk_clrsetreg(&cru->clksel_con[35],
CLK_I2C_DIV_CON_MASK << CLK_I2C2_DIV_CON_SHIFT |
CLK_I2C_PLL_SEL_MASK << CLK_I2C2_PLL_SEL_SHIFT,
(src_clk_div - 1) << CLK_I2C2_DIV_CON_SHIFT |
CLK_I2C_PLL_SEL_GPLL << CLK_I2C2_PLL_SEL_SHIFT);
break;
case SCLK_I2C3:
rk_clrsetreg(&cru->clksel_con[35],
CLK_I2C_DIV_CON_MASK << CLK_I2C3_DIV_CON_SHIFT |
CLK_I2C_PLL_SEL_MASK << CLK_I2C3_PLL_SEL_SHIFT,
(src_clk_div - 1) << CLK_I2C3_DIV_CON_SHIFT |
CLK_I2C_PLL_SEL_GPLL << CLK_I2C3_PLL_SEL_SHIFT);
break;
default:
printf("do not support this i2c bus\n");
return -EINVAL;
}
return DIV_TO_RATE(GPLL_HZ, src_clk_div);
}
static ulong rk3328_mmc_get_clk(struct rk3328_cru *cru, uint clk_id)
{
u32 div, con, con_id;
switch (clk_id) {
case HCLK_SDMMC:
con_id = 30;
break;
case HCLK_EMMC:
con_id = 32;
break;
default:
return -EINVAL;
}
con = readl(&cru->clksel_con[con_id]);
div = (con & CLK_EMMC_DIV_CON_MASK) >> CLK_EMMC_DIV_CON_SHIFT;
if ((con & CLK_EMMC_PLL_MASK) >> CLK_EMMC_PLL_SHIFT
== CLK_EMMC_PLL_SEL_24M)
return DIV_TO_RATE(OSC_HZ, div);
else
return DIV_TO_RATE(GPLL_HZ, div);
}
static ulong rk3328_mmc_set_clk(struct rk3328_cru *cru,
ulong clk_id, ulong set_rate)
{
int src_clk_div;
u32 con_id;
switch (clk_id) {
case HCLK_SDMMC:
con_id = 30;
break;
case HCLK_EMMC:
con_id = 32;
break;
default:
return -EINVAL;
}
/* Select clk_sdmmc/emmc source from GPLL by default */
src_clk_div = GPLL_HZ / set_rate;
if (src_clk_div > 127) {
/* use 24MHz source for 400KHz clock */
src_clk_div = OSC_HZ / set_rate;
rk_clrsetreg(&cru->clksel_con[con_id],
CLK_EMMC_PLL_MASK | CLK_EMMC_DIV_CON_MASK,
CLK_EMMC_PLL_SEL_24M << CLK_EMMC_PLL_SHIFT |
(src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT);
} else {
rk_clrsetreg(&cru->clksel_con[con_id],
CLK_EMMC_PLL_MASK | CLK_EMMC_DIV_CON_MASK,
CLK_EMMC_PLL_SEL_GPLL << CLK_EMMC_PLL_SHIFT |
(src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT);
}
return rk3328_mmc_get_clk(cru, clk_id);
}
static ulong rk3328_pwm_get_clk(struct rk3328_cru *cru)
{
u32 div, con;
con = readl(&cru->clksel_con[24]);
div = (con & CLK_PWM_DIV_CON_MASK) >> CLK_PWM_DIV_CON_SHIFT;
return DIV_TO_RATE(GPLL_HZ, div);
}
static ulong rk3328_pwm_set_clk(struct rk3328_cru *cru, uint hz)
{
u32 div = GPLL_HZ / hz;
rk_clrsetreg(&cru->clksel_con[24],
CLK_PWM_PLL_SEL_MASK | CLK_PWM_DIV_CON_MASK,
CLK_PWM_PLL_SEL_GPLL << CLK_PWM_PLL_SEL_SHIFT |
(div - 1) << CLK_PWM_DIV_CON_SHIFT);
return DIV_TO_RATE(GPLL_HZ, div);
}
static ulong rk3328_clk_get_rate(struct clk *clk)
{
struct rk3328_clk_priv *priv = dev_get_priv(clk->dev);
ulong rate = 0;
switch (clk->id) {
case 0 ... 29:
return 0;
case HCLK_SDMMC:
case HCLK_EMMC:
rate = rk3328_mmc_get_clk(priv->cru, clk->id);
break;
case SCLK_I2C0:
case SCLK_I2C1:
case SCLK_I2C2:
case SCLK_I2C3:
rate = rk3328_i2c_get_clk(priv->cru, clk->id);
break;
case SCLK_PWM:
rate = rk3328_pwm_get_clk(priv->cru);
break;
default:
return -ENOENT;
}
return rate;
}
static ulong rk3328_clk_set_rate(struct clk *clk, ulong rate)
{
struct rk3328_clk_priv *priv = dev_get_priv(clk->dev);
ulong ret = 0;
switch (clk->id) {
case 0 ... 29:
return 0;
case HCLK_SDMMC:
case HCLK_EMMC:
ret = rk3328_mmc_set_clk(priv->cru, clk->id, rate);
break;
case SCLK_I2C0:
case SCLK_I2C1:
case SCLK_I2C2:
case SCLK_I2C3:
ret = rk3328_i2c_set_clk(priv->cru, clk->id, rate);
break;
case SCLK_PWM:
ret = rk3328_pwm_set_clk(priv->cru, rate);
break;
default:
return -ENOENT;
}
return ret;
}
static struct clk_ops rk3328_clk_ops = {
.get_rate = rk3328_clk_get_rate,
.set_rate = rk3328_clk_set_rate,
};
static int rk3328_clk_probe(struct udevice *dev)
{
struct rk3328_clk_priv *priv = dev_get_priv(dev);
rkclk_init(priv->cru);
return 0;
}
static int rk3328_clk_ofdata_to_platdata(struct udevice *dev)
{
struct rk3328_clk_priv *priv = dev_get_priv(dev);
priv->cru = (struct rk3328_cru *)dev_get_addr(dev);
return 0;
}
static int rk3328_clk_bind(struct udevice *dev)
{
int ret;
/* The reset driver does not have a device node, so bind it here */
ret = device_bind_driver(gd->dm_root, "rk3328_sysreset", "reset", &dev);
if (ret)
printf("Warning: No RK3328 reset driver: ret=%d\n", ret);
return ret;
}
static const struct udevice_id rk3328_clk_ids[] = {
{ .compatible = "rockchip,rk3328-cru" },
{ }
};
U_BOOT_DRIVER(rockchip_rk3328_cru) = {
.name = "rockchip_rk3328_cru",
.id = UCLASS_CLK,
.of_match = rk3328_clk_ids,
.priv_auto_alloc_size = sizeof(struct rk3328_clk_priv),
.ofdata_to_platdata = rk3328_clk_ofdata_to_platdata,
.ops = &rk3328_clk_ops,
.bind = rk3328_clk_bind,
.probe = rk3328_clk_probe,
};

View file

@ -7,7 +7,9 @@
#include <common.h>
#include <clk-uclass.h>
#include <dm.h>
#include <dt-structs.h>
#include <errno.h>
#include <mapmem.h>
#include <syscon.h>
#include <asm/io.h>
#include <asm/arch/clock.h>
@ -18,10 +20,16 @@
DECLARE_GLOBAL_DATA_PTR;
struct rk3399_pmuclk_priv {
struct rk3399_pmucru *pmucru;
#if CONFIG_IS_ENABLED(OF_PLATDATA)
struct rk3399_clk_plat {
struct dtd_rockchip_rk3399_cru dtd;
};
struct rk3399_pmuclk_plat {
struct dtd_rockchip_rk3399_pmucru dtd;
};
#endif
struct pll_div {
u32 refdiv;
u32 fbdiv;
@ -381,6 +389,7 @@ static int pll_para_config(u32 freq_hz, struct pll_div *div)
return 0;
}
#ifdef CONFIG_SPL_BUILD
static void rkclk_init(struct rk3399_cru *cru)
{
u32 aclk_div;
@ -456,6 +465,7 @@ static void rkclk_init(struct rk3399_cru *cru)
hclk_div << HCLK_PERILP1_DIV_CON_SHIFT |
HCLK_PERILP1_PLL_SEL_GPLL << HCLK_PERILP1_PLL_SEL_SHIFT);
}
#endif
void rk3399_configure_cpu(struct rk3399_cru *cru,
enum apll_l_frequencies apll_l_freq)
@ -709,6 +719,44 @@ static ulong rk3399_mmc_set_clk(struct rk3399_cru *cru,
return rk3399_mmc_get_clk(cru, clk_id);
}
#define PMUSGRF_DDR_RGN_CON16 0xff330040
static ulong rk3399_ddr_set_clk(struct rk3399_cru *cru,
ulong set_rate)
{
struct pll_div dpll_cfg;
/* IC ECO bug, need to set this register */
writel(0xc000c000, PMUSGRF_DDR_RGN_CON16);
/* clk_ddrc == DPLL = 24MHz / refdiv * fbdiv / postdiv1 / postdiv2 */
switch (set_rate) {
case 200*MHz:
dpll_cfg = (struct pll_div)
{.refdiv = 1, .fbdiv = 50, .postdiv1 = 6, .postdiv2 = 1};
break;
case 300*MHz:
dpll_cfg = (struct pll_div)
{.refdiv = 2, .fbdiv = 100, .postdiv1 = 4, .postdiv2 = 1};
break;
case 666*MHz:
dpll_cfg = (struct pll_div)
{.refdiv = 2, .fbdiv = 111, .postdiv1 = 2, .postdiv2 = 1};
break;
case 800*MHz:
dpll_cfg = (struct pll_div)
{.refdiv = 1, .fbdiv = 100, .postdiv1 = 3, .postdiv2 = 1};
break;
case 933*MHz:
dpll_cfg = (struct pll_div)
{.refdiv = 1, .fbdiv = 116, .postdiv1 = 3, .postdiv2 = 1};
break;
default:
error("Unsupported SDRAM frequency!,%ld\n", set_rate);
}
rkclk_set_pll(&cru->dpll_con[0], &dpll_cfg);
return set_rate;
}
static ulong rk3399_clk_get_rate(struct clk *clk)
{
struct rk3399_clk_priv *priv = dev_get_priv(clk->dev);
@ -763,6 +811,9 @@ static ulong rk3399_clk_set_rate(struct clk *clk, ulong rate)
case DCLK_VOP1:
ret = rk3399_vop_set_clk(priv->cru, clk->id, rate);
break;
case SCLK_DDRCLK:
ret = rk3399_ddr_set_clk(priv->cru, rate);
break;
default:
return -ENOENT;
}
@ -777,19 +828,26 @@ static struct clk_ops rk3399_clk_ops = {
static int rk3399_clk_probe(struct udevice *dev)
{
#ifdef CONFIG_SPL_BUILD
struct rk3399_clk_priv *priv = dev_get_priv(dev);
rkclk_init(priv->cru);
#if CONFIG_IS_ENABLED(OF_PLATDATA)
struct rk3399_clk_plat *plat = dev_get_platdata(dev);
priv->cru = map_sysmem(plat->dtd.reg[1], plat->dtd.reg[3]);
#endif
rkclk_init(priv->cru);
#endif
return 0;
}
static int rk3399_clk_ofdata_to_platdata(struct udevice *dev)
{
#if !CONFIG_IS_ENABLED(OF_PLATDATA)
struct rk3399_clk_priv *priv = dev_get_priv(dev);
priv->cru = (struct rk3399_cru *)dev_get_addr(dev);
#endif
return 0;
}
@ -811,7 +869,7 @@ static const struct udevice_id rk3399_clk_ids[] = {
};
U_BOOT_DRIVER(clk_rk3399) = {
.name = "clk_rk3399",
.name = "rockchip_rk3399_cru",
.id = UCLASS_CLK,
.of_match = rk3399_clk_ids,
.priv_auto_alloc_size = sizeof(struct rk3399_clk_priv),
@ -819,6 +877,9 @@ U_BOOT_DRIVER(clk_rk3399) = {
.ops = &rk3399_clk_ops,
.bind = rk3399_clk_bind,
.probe = rk3399_clk_probe,
#if CONFIG_IS_ENABLED(OF_PLATDATA)
.platdata_auto_alloc_size = sizeof(struct rk3399_clk_plat),
#endif
};
static ulong rk3399_i2c_get_pmuclk(struct rk3399_pmucru *pmucru, ulong clk_id)
@ -930,6 +991,7 @@ static struct clk_ops rk3399_pmuclk_ops = {
.set_rate = rk3399_pmuclk_set_rate,
};
#ifndef CONFIG_SPL_BUILD
static void pmuclk_init(struct rk3399_pmucru *pmucru)
{
u32 pclk_div;
@ -939,27 +1001,35 @@ static void pmuclk_init(struct rk3399_pmucru *pmucru)
/* configure pmu pclk */
pclk_div = PPLL_HZ / PMU_PCLK_HZ - 1;
assert((pclk_div + 1) * PMU_PCLK_HZ == PPLL_HZ && pclk_div < 0x1f);
rk_clrsetreg(&pmucru->pmucru_clksel[0],
PMU_PCLK_DIV_CON_MASK,
pclk_div << PMU_PCLK_DIV_CON_SHIFT);
}
#endif
static int rk3399_pmuclk_probe(struct udevice *dev)
{
struct rk3399_pmuclk_priv *priv = dev_get_priv(dev);
pmuclk_init(priv->pmucru);
#if CONFIG_IS_ENABLED(OF_PLATDATA)
struct rk3399_pmuclk_plat *plat = dev_get_platdata(dev);
priv->pmucru = map_sysmem(plat->dtd.reg[1], plat->dtd.reg[3]);
#endif
#ifndef CONFIG_SPL_BUILD
pmuclk_init(priv->pmucru);
#endif
return 0;
}
static int rk3399_pmuclk_ofdata_to_platdata(struct udevice *dev)
{
#if !CONFIG_IS_ENABLED(OF_PLATDATA)
struct rk3399_pmuclk_priv *priv = dev_get_priv(dev);
priv->pmucru = (struct rk3399_pmucru *)dev_get_addr(dev);
#endif
return 0;
}
@ -969,11 +1039,14 @@ static const struct udevice_id rk3399_pmuclk_ids[] = {
};
U_BOOT_DRIVER(rockchip_rk3399_pmuclk) = {
.name = "pmuclk_rk3399",
.name = "rockchip_rk3399_pmucru",
.id = UCLASS_CLK,
.of_match = rk3399_pmuclk_ids,
.priv_auto_alloc_size = sizeof(struct rk3399_pmuclk_priv),
.ofdata_to_platdata = rk3399_pmuclk_ofdata_to_platdata,
.ops = &rk3399_pmuclk_ops,
.probe = rk3399_pmuclk_probe,
#if CONFIG_IS_ENABLED(OF_PLATDATA)
.platdata_auto_alloc_size = sizeof(struct rk3399_pmuclk_plat),
#endif
};

View file

@ -205,7 +205,7 @@ int dm_scan_fdt_node(struct udevice *parent, const void *blob, int offset,
offset > 0;
offset = fdt_next_subnode(blob, offset)) {
if (pre_reloc_only &&
!fdt_getprop(blob, offset, "u-boot,dm-pre-reloc", NULL))
!dm_fdt_pre_reloc(blob, offset))
continue;
if (!fdtdec_get_is_enabled(blob, offset)) {
dm_dbg(" - ignoring disabled device\n");

View file

@ -5,6 +5,7 @@
*/
#include <common.h>
#include <libfdt.h>
#include <vsprintf.h>
void dm_warn(const char *fmt, ...)
@ -35,3 +36,27 @@ int list_count_items(struct list_head *head)
return count;
}
bool dm_fdt_pre_reloc(const void *blob, int offset)
{
if (fdt_getprop(blob, offset, "u-boot,dm-pre-reloc", NULL))
return true;
#ifdef CONFIG_TPL_BUILD
if (fdt_getprop(blob, offset, "u-boot,dm-tpl", NULL))
return true;
#elif defined(CONFIG_SPL_BUILD)
if (fdt_getprop(blob, offset, "u-boot,dm-spl", NULL))
return true;
#else
/*
* In regular builds individual spl and tpl handling both
* count as handled pre-relocation for later second init.
*/
if (fdt_getprop(blob, offset, "u-boot,dm-spl", NULL) ||
fdt_getprop(blob, offset, "u-boot,dm-tpl", NULL))
return true;
#endif
return false;
}

View file

@ -8,9 +8,11 @@
#include <common.h>
#include <dm.h>
#include <dt-structs.h>
#include <fdtdec.h>
#include <libfdt.h>
#include <malloc.h>
#include <mapmem.h>
#include <sdhci.h>
#include <clk.h>
@ -19,6 +21,9 @@ DECLARE_GLOBAL_DATA_PTR;
#define EMMC_MIN_FREQ 400000
struct rockchip_sdhc_plat {
#if CONFIG_IS_ENABLED(OF_PLATDATA)
struct dtd_rockchip_rk3399_sdhci_5_1 dtplat;
#endif
struct mmc_config cfg;
struct mmc mmc;
};
@ -37,10 +42,18 @@ static int arasan_sdhci_probe(struct udevice *dev)
int max_frequency, ret;
struct clk clk;
#if CONFIG_IS_ENABLED(OF_PLATDATA)
struct dtd_rockchip_rk3399_sdhci_5_1 *dtplat = &plat->dtplat;
host->name = dev->name;
host->ioaddr = map_sysmem(dtplat->reg[1], dtplat->reg[3]);
max_frequency = dtplat->max_frequency;
ret = clk_get_by_index_platdata(dev, 0, dtplat->clocks, &clk);
#else
max_frequency = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
"max-frequency", 0);
ret = clk_get_by_index(dev, 0, &clk);
#endif
if (!ret) {
ret = clk_set_rate(&clk, max_frequency);
if (IS_ERR_VALUE(ret))
@ -66,10 +79,12 @@ static int arasan_sdhci_probe(struct udevice *dev)
static int arasan_sdhci_ofdata_to_platdata(struct udevice *dev)
{
#if !CONFIG_IS_ENABLED(OF_PLATDATA)
struct sdhci_host *host = dev_get_priv(dev);
host->name = dev->name;
host->ioaddr = dev_get_addr_ptr(dev);
#endif
return 0;
}
@ -87,7 +102,7 @@ static const struct udevice_id arasan_sdhci_ids[] = {
};
U_BOOT_DRIVER(arasan_sdhci_drv) = {
.name = "arasan_sdhci",
.name = "rockchip_rk3399_sdhci_5_1",
.id = UCLASS_MMC,
.of_match = arasan_sdhci_ids,
.ofdata_to_platdata = arasan_sdhci_ofdata_to_platdata,

View file

@ -132,6 +132,15 @@ config ROCKCHIP_RK3036_PINCTRL
definitions and pin control functions for each available multiplex
function.
config ROCKCHIP_RK3188_PINCTRL
bool "Rockchip pin control driver"
depends on DM
help
Support pin multiplexing control on Rockchip rk3188 SoCs. The driver
is controlled by a device tree node which contains both the GPIO
definitions and pin control functions for each available multiplex
function.
config ROCKCHIP_RK3288_PINCTRL
bool "Rockchip pin control driver"
depends on DM
@ -148,6 +157,15 @@ config PINCTRL_AT91PIO4
This option is to enable the AT91 pinctrl driver for AT91 PIO4
controller which is available on SAMA5D2 SoC.
config ROCKCHIP_RK3328_PINCTRL
bool "Rockchip pin control driver"
depends on DM
help
Support pin multiplexing control on Rockchip rk3328 SoCs. The driver
is controlled by a device tree node which contains both the GPIO
definitions and pin control functions for each available multiplex
function.
config ROCKCHIP_RK3399_PINCTRL
bool "Rockchip pin control driver"
depends on DM

View file

@ -12,6 +12,7 @@
#include <dm/lists.h>
#include <dm/pinctrl.h>
#include <dm/uclass.h>
#include <dm/util.h>
DECLARE_GLOBAL_DATA_PTR;
@ -131,7 +132,7 @@ static int pinconfig_post_bind(struct udevice *dev)
offset > 0;
offset = fdt_next_subnode(fdt, offset)) {
if (pre_reloc_only &&
!fdt_getprop(fdt, offset, "u-boot,dm-pre-reloc", NULL))
!dm_fdt_pre_reloc(fdt, offset))
continue;
/*
* If this node has "compatible" property, this is not

View file

@ -6,5 +6,7 @@
#
obj-$(CONFIG_ROCKCHIP_RK3036_PINCTRL) += pinctrl_rk3036.o
obj-$(CONFIG_ROCKCHIP_RK3188_PINCTRL) += pinctrl_rk3188.o
obj-$(CONFIG_ROCKCHIP_RK3288_PINCTRL) += pinctrl_rk3288.o
obj-$(CONFIG_ROCKCHIP_RK3328_PINCTRL) += pinctrl_rk3328.o
obj-$(CONFIG_ROCKCHIP_RK3399_PINCTRL) += pinctrl_rk3399.o

View file

@ -0,0 +1,611 @@
/*
* Pinctrl driver for Rockchip RK3188 SoCs
* Copyright (c) 2016 Heiko Stuebner <heiko@sntech.de>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <dm.h>
#include <errno.h>
#include <syscon.h>
#include <asm/io.h>
#include <asm/arch/clock.h>
#include <asm/arch/grf_rk3188.h>
#include <asm/arch/hardware.h>
#include <asm/arch/periph.h>
#include <asm/arch/pmu_rk3188.h>
#include <dm/pinctrl.h>
#include <dm/root.h>
DECLARE_GLOBAL_DATA_PTR;
struct rk3188_pinctrl_priv {
struct rk3188_grf *grf;
struct rk3188_pmu *pmu;
int num_banks;
};
/**
* Encode variants of iomux registers into a type variable
*/
#define IOMUX_GPIO_ONLY BIT(0)
/**
* @type: iomux variant using IOMUX_* constants
* @offset: if initialized to -1 it will be autocalculated, by specifying
* an initial offset value the relevant source offset can be reset
* to a new value for autocalculating the following iomux registers.
*/
struct rockchip_iomux {
u8 type;
s16 offset;
};
/**
* @reg: register offset of the gpio bank
* @nr_pins: number of pins in this bank
* @bank_num: number of the bank, to account for holes
* @name: name of the bank
* @iomux: array describing the 4 iomux sources of the bank
*/
struct rockchip_pin_bank {
u16 reg;
u8 nr_pins;
u8 bank_num;
char *name;
struct rockchip_iomux iomux[4];
};
#define PIN_BANK(id, pins, label) \
{ \
.bank_num = id, \
.nr_pins = pins, \
.name = label, \
.iomux = { \
{ .offset = -1 }, \
{ .offset = -1 }, \
{ .offset = -1 }, \
{ .offset = -1 }, \
}, \
}
#define PIN_BANK_IOMUX_FLAGS(id, pins, label, iom0, iom1, iom2, iom3) \
{ \
.bank_num = id, \
.nr_pins = pins, \
.name = label, \
.iomux = { \
{ .type = iom0, .offset = -1 }, \
{ .type = iom1, .offset = -1 }, \
{ .type = iom2, .offset = -1 }, \
{ .type = iom3, .offset = -1 }, \
}, \
}
#ifndef CONFIG_SPL_BUILD
static struct rockchip_pin_bank rk3188_pin_banks[] = {
PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_GPIO_ONLY, 0, 0, 0),
PIN_BANK(1, 32, "gpio1"),
PIN_BANK(2, 32, "gpio2"),
PIN_BANK(3, 32, "gpio3"),
};
#endif
static void pinctrl_rk3188_pwm_config(struct rk3188_grf *grf, int pwm_id)
{
switch (pwm_id) {
case PERIPH_ID_PWM0:
rk_clrsetreg(&grf->gpio3d_iomux, GPIO3D3_MASK << GPIO3D3_SHIFT,
GPIO3D3_PWM_0 << GPIO3D3_SHIFT);
break;
case PERIPH_ID_PWM1:
rk_clrsetreg(&grf->gpio3d_iomux, GPIO3D4_MASK << GPIO3D4_SHIFT,
GPIO3D4_PWM_1 << GPIO3D4_SHIFT);
break;
case PERIPH_ID_PWM2:
rk_clrsetreg(&grf->gpio3d_iomux, GPIO3D5_MASK << GPIO3D5_SHIFT,
GPIO3D5_PWM_2 << GPIO3D5_SHIFT);
break;
case PERIPH_ID_PWM3:
rk_clrsetreg(&grf->gpio3d_iomux, GPIO3D6_MASK << GPIO3D6_SHIFT,
GPIO3D6_PWM_3 << GPIO3D6_SHIFT);
break;
default:
debug("pwm id = %d iomux error!\n", pwm_id);
break;
}
}
static void pinctrl_rk3188_i2c_config(struct rk3188_grf *grf,
struct rk3188_pmu *pmu, int i2c_id)
{
switch (i2c_id) {
case PERIPH_ID_I2C0:
rk_clrsetreg(&grf->gpio1d_iomux,
GPIO1D1_MASK << GPIO1D1_SHIFT |
GPIO1D0_MASK << GPIO1D0_SHIFT,
GPIO1D1_I2C0_SCL << GPIO1D1_SHIFT |
GPIO1D0_I2C0_SDA << GPIO1D0_SHIFT);
/* enable new i2c controller */
rk_clrsetreg(&grf->soc_con1, 1 << RKI2C0_SEL_SHIFT,
1 << RKI2C0_SEL_SHIFT);
break;
case PERIPH_ID_I2C1:
rk_clrsetreg(&grf->gpio1d_iomux,
GPIO1D3_MASK << GPIO1D3_SHIFT |
GPIO1D2_MASK << GPIO1D2_SHIFT,
GPIO1D3_I2C1_SCL << GPIO1D2_SHIFT |
GPIO1D2_I2C1_SDA << GPIO1D2_SHIFT);
rk_clrsetreg(&grf->soc_con1, 1 << RKI2C1_SEL_SHIFT,
1 << RKI2C1_SEL_SHIFT);
break;
case PERIPH_ID_I2C2:
rk_clrsetreg(&grf->gpio1d_iomux,
GPIO1D5_MASK << GPIO1D5_SHIFT |
GPIO1D4_MASK << GPIO1D4_SHIFT,
GPIO1D5_I2C2_SCL << GPIO1D5_SHIFT |
GPIO1D4_I2C2_SDA << GPIO1D4_SHIFT);
rk_clrsetreg(&grf->soc_con1, 1 << RKI2C2_SEL_SHIFT,
1 << RKI2C2_SEL_SHIFT);
break;
case PERIPH_ID_I2C3:
rk_clrsetreg(&grf->gpio3b_iomux,
GPIO3B7_MASK << GPIO3B7_SHIFT |
GPIO3B6_MASK << GPIO3B6_SHIFT,
GPIO3B7_I2C3_SCL << GPIO3B7_SHIFT |
GPIO3B6_I2C3_SDA << GPIO3B6_SHIFT);
rk_clrsetreg(&grf->soc_con1, 1 << RKI2C3_SEL_SHIFT,
1 << RKI2C3_SEL_SHIFT);
break;
case PERIPH_ID_I2C4:
rk_clrsetreg(&grf->gpio1d_iomux,
GPIO1D7_MASK << GPIO1D7_SHIFT |
GPIO1D6_MASK << GPIO1D6_SHIFT,
GPIO1D7_I2C4_SCL << GPIO1D7_SHIFT |
GPIO1D6_I2C4_SDA << GPIO1D6_SHIFT);
rk_clrsetreg(&grf->soc_con1, 1 << RKI2C4_SEL_SHIFT,
1 << RKI2C4_SEL_SHIFT);
break;
default:
debug("i2c id = %d iomux error!\n", i2c_id);
break;
}
}
static int pinctrl_rk3188_spi_config(struct rk3188_grf *grf,
enum periph_id spi_id, int cs)
{
switch (spi_id) {
case PERIPH_ID_SPI0:
switch (cs) {
case 0:
rk_clrsetreg(&grf->gpio1a_iomux,
GPIO1A7_MASK << GPIO1A7_SHIFT,
GPIO1A7_SPI0_CSN0 << GPIO1A7_SHIFT);
break;
case 1:
rk_clrsetreg(&grf->gpio1b_iomux,
GPIO1B7_MASK << GPIO1B7_SHIFT,
GPIO1B7_SPI0_CSN1 << GPIO1B7_SHIFT);
break;
default:
goto err;
}
rk_clrsetreg(&grf->gpio1a_iomux,
GPIO1A4_MASK << GPIO1A4_SHIFT |
GPIO1A5_MASK << GPIO1A5_SHIFT |
GPIO1A6_MASK << GPIO1A6_SHIFT,
GPIO1A4_SPI0_RXD << GPIO1A4_SHIFT |
GPIO1A5_SPI0_TXD << GPIO1A5_SHIFT |
GPIO1A6_SPI0_CLK << GPIO1A6_SHIFT);
break;
case PERIPH_ID_SPI1:
switch (cs) {
case 0:
rk_clrsetreg(&grf->gpio0d_iomux,
GPIO0D7_MASK << GPIO0D7_SHIFT,
GPIO0D7_SPI1_CSN0 << GPIO0D7_SHIFT);
break;
case 1:
rk_clrsetreg(&grf->gpio1b_iomux,
GPIO1B6_MASK << GPIO1B6_SHIFT,
GPIO1B6_SPI1_CSN1 << GPIO1B6_SHIFT);
break;
default:
goto err;
}
rk_clrsetreg(&grf->gpio0d_iomux,
GPIO0D4_MASK << GPIO0D4_SHIFT |
GPIO0D5_MASK << GPIO0D5_SHIFT |
GPIO0D6_MASK << GPIO0D6_SHIFT,
GPIO0D4_SPI0_RXD << GPIO0D4_SHIFT |
GPIO0D5_SPI1_TXD << GPIO0D5_SHIFT |
GPIO0D6_SPI1_CLK << GPIO0D6_SHIFT);
break;
default:
goto err;
}
return 0;
err:
debug("rkspi: periph%d cs=%d not supported", spi_id, cs);
return -ENOENT;
}
static void pinctrl_rk3188_uart_config(struct rk3188_grf *grf, int uart_id)
{
switch (uart_id) {
case PERIPH_ID_UART0:
rk_clrsetreg(&grf->gpio1a_iomux,
GPIO1A3_MASK << GPIO1A3_SHIFT |
GPIO1A2_MASK << GPIO1A2_SHIFT |
GPIO1A1_MASK << GPIO1A1_SHIFT |
GPIO1A0_MASK << GPIO1A0_SHIFT,
GPIO1A3_UART0_RTS_N << GPIO1A3_SHIFT |
GPIO1A2_UART0_CTS_N << GPIO1A2_SHIFT |
GPIO1A1_UART0_SOUT << GPIO1A1_SHIFT |
GPIO1A0_UART0_SIN << GPIO1A0_SHIFT);
break;
case PERIPH_ID_UART1:
rk_clrsetreg(&grf->gpio1a_iomux,
GPIO1A7_MASK << GPIO1A7_SHIFT |
GPIO1A6_MASK << GPIO1A6_SHIFT |
GPIO1A5_MASK << GPIO1A5_SHIFT |
GPIO1A4_MASK << GPIO1A4_SHIFT,
GPIO1A7_UART1_RTS_N << GPIO1A7_SHIFT |
GPIO1A6_UART1_CTS_N << GPIO1A6_SHIFT |
GPIO1A5_UART1_SOUT << GPIO1A5_SHIFT |
GPIO1A4_UART1_SIN << GPIO1A4_SHIFT);
break;
case PERIPH_ID_UART2:
rk_clrsetreg(&grf->gpio1b_iomux,
GPIO1B1_MASK << GPIO1B1_SHIFT |
GPIO1B0_MASK << GPIO1B0_SHIFT,
GPIO1B1_UART2_SOUT << GPIO1B1_SHIFT |
GPIO1B0_UART2_SIN << GPIO1B0_SHIFT);
break;
case PERIPH_ID_UART3:
rk_clrsetreg(&grf->gpio1b_iomux,
GPIO1B5_MASK << GPIO1B5_SHIFT |
GPIO1B4_MASK << GPIO1B4_SHIFT |
GPIO1B3_MASK << GPIO1B3_SHIFT |
GPIO1B2_MASK << GPIO1B2_SHIFT,
GPIO1B5_UART3_RTS_N << GPIO1B5_SHIFT |
GPIO1B4_UART3_CTS_N << GPIO1B4_SHIFT |
GPIO1B3_UART3_SOUT << GPIO1B3_SHIFT |
GPIO1B2_UART3_SIN << GPIO1B2_SHIFT);
break;
default:
debug("uart id = %d iomux error!\n", uart_id);
break;
}
}
static void pinctrl_rk3188_sdmmc_config(struct rk3188_grf *grf, int mmc_id)
{
switch (mmc_id) {
case PERIPH_ID_EMMC:
rk_clrsetreg(&grf->soc_con0, 1 << EMMC_FLASH_SEL_SHIFT,
1 << EMMC_FLASH_SEL_SHIFT);
rk_clrsetreg(&grf->gpio0d_iomux,
GPIO0D2_MASK << GPIO0D2_SHIFT |
GPIO0D0_MASK << GPIO0D0_SHIFT,
GPIO0D2_EMMC_CMD << GPIO0D2_SHIFT |
GPIO0D0_EMMC_CLKOUT << GPIO0D0_SHIFT);
break;
case PERIPH_ID_SDCARD:
rk_clrsetreg(&grf->gpio3b_iomux,
GPIO3B0_MASK << GPIO3B0_SHIFT,
GPIO3B0_SDMMC_DETECT_N << GPIO3B0_SHIFT);
rk_clrsetreg(&grf->gpio3a_iomux,
GPIO3A7_MASK << GPIO3A7_SHIFT |
GPIO3A6_MASK << GPIO3A6_SHIFT |
GPIO3A5_MASK << GPIO3A5_SHIFT |
GPIO3A4_MASK << GPIO3A4_SHIFT |
GPIO3A3_MASK << GPIO3A3_SHIFT |
GPIO3A3_MASK << GPIO3A2_SHIFT,
GPIO3A7_SDMMC0_DATA3 << GPIO3A7_SHIFT |
GPIO3A6_SDMMC0_DATA2 << GPIO3A6_SHIFT |
GPIO3A5_SDMMC0_DATA1 << GPIO3A5_SHIFT |
GPIO3A4_SDMMC0_DATA0 << GPIO3A4_SHIFT |
GPIO3A3_SDMMC0_CMD << GPIO3A3_SHIFT |
GPIO3A2_SDMMC0_CLKOUT << GPIO3A2_SHIFT);
break;
default:
debug("mmc id = %d iomux error!\n", mmc_id);
break;
}
}
static int rk3188_pinctrl_request(struct udevice *dev, int func, int flags)
{
struct rk3188_pinctrl_priv *priv = dev_get_priv(dev);
debug("%s: func=%x, flags=%x\n", __func__, func, flags);
switch (func) {
case PERIPH_ID_PWM0:
case PERIPH_ID_PWM1:
case PERIPH_ID_PWM2:
case PERIPH_ID_PWM3:
case PERIPH_ID_PWM4:
pinctrl_rk3188_pwm_config(priv->grf, func);
break;
case PERIPH_ID_I2C0:
case PERIPH_ID_I2C1:
case PERIPH_ID_I2C2:
case PERIPH_ID_I2C3:
case PERIPH_ID_I2C4:
case PERIPH_ID_I2C5:
pinctrl_rk3188_i2c_config(priv->grf, priv->pmu, func);
break;
case PERIPH_ID_SPI0:
case PERIPH_ID_SPI1:
case PERIPH_ID_SPI2:
pinctrl_rk3188_spi_config(priv->grf, func, flags);
break;
case PERIPH_ID_UART0:
case PERIPH_ID_UART1:
case PERIPH_ID_UART2:
case PERIPH_ID_UART3:
case PERIPH_ID_UART4:
pinctrl_rk3188_uart_config(priv->grf, func);
break;
break;
case PERIPH_ID_SDMMC0:
case PERIPH_ID_SDMMC1:
pinctrl_rk3188_sdmmc_config(priv->grf, func);
break;
default:
return -EINVAL;
}
return 0;
}
static int rk3188_pinctrl_get_periph_id(struct udevice *dev,
struct udevice *periph)
{
#if !CONFIG_IS_ENABLED(OF_PLATDATA)
u32 cell[3];
int ret;
ret = fdtdec_get_int_array(gd->fdt_blob, periph->of_offset,
"interrupts", cell, ARRAY_SIZE(cell));
if (ret < 0)
return -EINVAL;
switch (cell[1]) {
case 44:
return PERIPH_ID_SPI0;
case 45:
return PERIPH_ID_SPI1;
case 46:
return PERIPH_ID_SPI2;
case 60:
return PERIPH_ID_I2C0;
case 62: /* Note strange order */
return PERIPH_ID_I2C1;
case 61:
return PERIPH_ID_I2C2;
case 63:
return PERIPH_ID_I2C3;
case 64:
return PERIPH_ID_I2C4;
case 65:
return PERIPH_ID_I2C5;
}
#endif
return -ENOENT;
}
static int rk3188_pinctrl_set_state_simple(struct udevice *dev,
struct udevice *periph)
{
int func;
func = rk3188_pinctrl_get_periph_id(dev, periph);
if (func < 0)
return func;
return rk3188_pinctrl_request(dev, func, 0);
}
#ifndef CONFIG_SPL_BUILD
int rk3188_pinctrl_get_pin_info(struct rk3188_pinctrl_priv *priv,
int banknum, int ind, u32 **addrp, uint *shiftp,
uint *maskp)
{
struct rockchip_pin_bank *bank = &rk3188_pin_banks[banknum];
uint muxnum;
u32 *addr;
for (muxnum = 0; muxnum < 4; muxnum++) {
struct rockchip_iomux *mux = &bank->iomux[muxnum];
if (ind >= 8) {
ind -= 8;
continue;
}
addr = &priv->grf->gpio0c_iomux - 2;
addr += mux->offset;
*shiftp = ind & 7;
*maskp = 3;
*shiftp *= 2;
debug("%s: addr=%p, mask=%x, shift=%x\n", __func__, addr,
*maskp, *shiftp);
*addrp = addr;
return 0;
}
return -EINVAL;
}
static int rk3188_pinctrl_get_gpio_mux(struct udevice *dev, int banknum,
int index)
{
struct rk3188_pinctrl_priv *priv = dev_get_priv(dev);
uint shift;
uint mask;
u32 *addr;
int ret;
ret = rk3188_pinctrl_get_pin_info(priv, banknum, index, &addr, &shift,
&mask);
if (ret)
return ret;
return (readl(addr) & mask) >> shift;
}
static int rk3188_pinctrl_set_pins(struct udevice *dev, int banknum, int index,
int muxval, int flags)
{
struct rk3188_pinctrl_priv *priv = dev_get_priv(dev);
uint shift, ind = index;
uint mask;
u32 *addr;
int ret;
debug("%s: %x %x %x %x\n", __func__, banknum, index, muxval, flags);
ret = rk3188_pinctrl_get_pin_info(priv, banknum, index, &addr, &shift,
&mask);
if (ret)
return ret;
rk_clrsetreg(addr, mask << shift, muxval << shift);
/* Handle pullup/pulldown */
if (flags) {
uint val = 0;
if (flags & (1 << PIN_CONFIG_BIAS_PULL_UP))
val = 1;
else if (flags & (1 << PIN_CONFIG_BIAS_PULL_DOWN))
val = 2;
ind = index >> 3;
if (banknum == 0 && index < 12) {
addr = &priv->pmu->gpio0_p[ind];
shift = (index & 7) * 2;
} else if (banknum == 0 && index >= 12) {
addr = &priv->grf->gpio0_p[ind - 1];
/*
* The bits in the grf-registers have an inverse
* ordering with the lowest pin being in bits 15:14
* and the highest pin in bits 1:0 .
*/
shift = (7 - (index & 7)) * 2;
} else {
addr = &priv->grf->gpio1_p[banknum - 1][ind];
shift = (7 - (index & 7)) * 2;
}
debug("%s: addr=%p, val=%x, shift=%x\n", __func__, addr, val,
shift);
rk_clrsetreg(addr, 3 << shift, val << shift);
}
return 0;
}
static int rk3188_pinctrl_set_state(struct udevice *dev, struct udevice *config)
{
const void *blob = gd->fdt_blob;
int pcfg_node, ret, flags, count, i;
u32 cell[60], *ptr;
debug("%s: %s %s\n", __func__, dev->name, config->name);
ret = fdtdec_get_int_array_count(blob, config->of_offset,
"rockchip,pins", cell,
ARRAY_SIZE(cell));
if (ret < 0) {
debug("%s: bad array %d\n", __func__, ret);
return -EINVAL;
}
count = ret;
for (i = 0, ptr = cell; i < count; i += 4, ptr += 4) {
pcfg_node = fdt_node_offset_by_phandle(blob, ptr[3]);
if (pcfg_node < 0)
return -EINVAL;
flags = pinctrl_decode_pin_config(blob, pcfg_node);
if (flags < 0)
return flags;
ret = rk3188_pinctrl_set_pins(dev, ptr[0], ptr[1], ptr[2],
flags);
if (ret)
return ret;
}
return 0;
}
#endif
static struct pinctrl_ops rk3188_pinctrl_ops = {
#ifndef CONFIG_SPL_BUILD
.set_state = rk3188_pinctrl_set_state,
.get_gpio_mux = rk3188_pinctrl_get_gpio_mux,
#endif
.set_state_simple = rk3188_pinctrl_set_state_simple,
.request = rk3188_pinctrl_request,
.get_periph_id = rk3188_pinctrl_get_periph_id,
};
#ifndef CONFIG_SPL_BUILD
static int rk3188_pinctrl_parse_tables(struct rk3188_pinctrl_priv *priv,
struct rockchip_pin_bank *banks,
int count)
{
struct rockchip_pin_bank *bank;
uint reg, muxnum, banknum;
reg = 0;
for (banknum = 0; banknum < count; banknum++) {
bank = &banks[banknum];
bank->reg = reg;
debug("%s: bank %d, reg %x\n", __func__, banknum, reg * 4);
for (muxnum = 0; muxnum < 4; muxnum++) {
struct rockchip_iomux *mux = &bank->iomux[muxnum];
mux->offset = reg;
reg += 1;
}
}
return 0;
}
#endif
static int rk3188_pinctrl_probe(struct udevice *dev)
{
struct rk3188_pinctrl_priv *priv = dev_get_priv(dev);
int ret = 0;
priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
priv->pmu = syscon_get_first_range(ROCKCHIP_SYSCON_PMU);
debug("%s: grf=%p, pmu=%p\n", __func__, priv->grf, priv->pmu);
#ifndef CONFIG_SPL_BUILD
ret = rk3188_pinctrl_parse_tables(priv, rk3188_pin_banks,
ARRAY_SIZE(rk3188_pin_banks));
#endif
return ret;
}
static const struct udevice_id rk3188_pinctrl_ids[] = {
{ .compatible = "rockchip,rk3188-pinctrl" },
{ }
};
U_BOOT_DRIVER(pinctrl_rk3188) = {
.name = "rockchip_rk3188_pinctrl",
.id = UCLASS_PINCTRL,
.of_match = rk3188_pinctrl_ids,
.priv_auto_alloc_size = sizeof(struct rk3188_pinctrl_priv),
.ops = &rk3188_pinctrl_ops,
#if !CONFIG_IS_ENABLED(OF_PLATDATA)
.bind = dm_scan_fdt_dev,
#endif
.probe = rk3188_pinctrl_probe,
};

View file

@ -0,0 +1,419 @@
/*
* (C) Copyright 2016 Rockchip Electronics Co., Ltd
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <dm.h>
#include <errno.h>
#include <syscon.h>
#include <asm/arch/clock.h>
#include <asm/arch/hardware.h>
#include <asm/arch/grf_rk3328.h>
#include <asm/arch/periph.h>
#include <asm/io.h>
#include <dm/pinctrl.h>
DECLARE_GLOBAL_DATA_PTR;
struct rk3328_pinctrl_priv {
struct rk3328_grf_regs *grf;
};
enum {
/* GRF_GPIO0A_IOMUX */
GRF_GPIO0A5_SEL_SHIFT = 10,
GRF_GPIO0A5_SEL_MASK = 3 << GRF_GPIO0A5_SEL_SHIFT,
GRF_I2C3_SCL = 2,
GRF_GPIO0A6_SEL_SHIFT = 12,
GRF_GPIO0A6_SEL_MASK = 3 << GRF_GPIO0A6_SEL_SHIFT,
GRF_I2C3_SDA = 2,
GRF_GPIO0A7_SEL_SHIFT = 14,
GRF_GPIO0A7_SEL_MASK = 3 << GRF_GPIO0A7_SEL_SHIFT,
GRF_EMMC_DATA0 = 2,
/* GRF_GPIO1A_IOMUX */
GRF_GPIO1A0_SEL_SHIFT = 0,
GRF_GPIO1A0_SEL_MASK = 0x3fff << GRF_GPIO1A0_SEL_SHIFT,
GRF_CARD_DATA_CLK_CMD_DETN = 0x1555,
/* GRF_GPIO2A_IOMUX */
GRF_GPIO2A0_SEL_SHIFT = 0,
GRF_GPIO2A0_SEL_MASK = 3 << GRF_GPIO2A0_SEL_SHIFT,
GRF_UART2_TX_M1 = 1,
GRF_GPIO2A1_SEL_SHIFT = 2,
GRF_GPIO2A1_SEL_MASK = 3 << GRF_GPIO2A1_SEL_SHIFT,
GRF_UART2_RX_M1 = 1,
GRF_GPIO2A2_SEL_SHIFT = 4,
GRF_GPIO2A2_SEL_MASK = 3 << GRF_GPIO2A2_SEL_SHIFT,
GRF_PWM_IR = 1,
GRF_GPIO2A4_SEL_SHIFT = 8,
GRF_GPIO2A4_SEL_MASK = 3 << GRF_GPIO2A4_SEL_SHIFT,
GRF_PWM_0 = 1,
GRF_I2C1_SDA,
GRF_GPIO2A5_SEL_SHIFT = 10,
GRF_GPIO2A5_SEL_MASK = 3 << GRF_GPIO2A5_SEL_SHIFT,
GRF_PWM_1 = 1,
GRF_I2C1_SCL,
GRF_GPIO2A6_SEL_SHIFT = 12,
GRF_GPIO2A6_SEL_MASK = 3 << GRF_GPIO2A6_SEL_SHIFT,
GRF_PWM_2 = 1,
GRF_GPIO2A7_SEL_SHIFT = 14,
GRF_GPIO2A7_SEL_MASK = 3 << GRF_GPIO2A7_SEL_SHIFT,
GRF_CARD_PWR_EN_M0 = 1,
/* GRF_GPIO2BL_IOMUX */
GRF_GPIO2BL0_SEL_SHIFT = 0,
GRF_GPIO2BL0_SEL_MASK = 0x3f << GRF_GPIO2BL0_SEL_SHIFT,
GRF_SPI_CLK_TX_RX_M0 = 0x15,
GRF_GPIO2BL3_SEL_SHIFT = 6,
GRF_GPIO2BL3_SEL_MASK = 3 << GRF_GPIO2BL3_SEL_SHIFT,
GRF_SPI_CSN0_M0 = 1,
GRF_GPIO2BL4_SEL_SHIFT = 8,
GRF_GPIO2BL4_SEL_MASK = 3 << GRF_GPIO2BL4_SEL_SHIFT,
GRF_SPI_CSN1_M0 = 1,
GRF_GPIO2BL5_SEL_SHIFT = 10,
GRF_GPIO2BL5_SEL_MASK = 3 << GRF_GPIO2BL5_SEL_SHIFT,
GRF_I2C2_SDA = 1,
GRF_GPIO2BL6_SEL_SHIFT = 12,
GRF_GPIO2BL6_SEL_MASK = 3 << GRF_GPIO2BL6_SEL_SHIFT,
GRF_I2C2_SCL = 1,
/* GRF_GPIO2D_IOMUX */
GRF_GPIO2D0_SEL_SHIFT = 0,
GRF_GPIO2D0_SEL_MASK = 3 << GRF_GPIO2D0_SEL_SHIFT,
GRF_I2C0_SCL = 1,
GRF_GPIO2D1_SEL_SHIFT = 2,
GRF_GPIO2D1_SEL_MASK = 3 << GRF_GPIO2D1_SEL_SHIFT,
GRF_I2C0_SDA = 1,
GRF_GPIO2D4_SEL_SHIFT = 8,
GRF_GPIO2D4_SEL_MASK = 0xff << GRF_GPIO2D4_SEL_SHIFT,
GRF_EMMC_DATA123 = 0xaa,
/* GRF_GPIO3C_IOMUX */
GRF_GPIO3C0_SEL_SHIFT = 0,
GRF_GPIO3C0_SEL_MASK = 0x3fff << GRF_GPIO3C0_SEL_SHIFT,
GRF_EMMC_DATA567_PWR_CLK_RSTN_CMD = 0x2aaa,
/* GRF_COM_IOMUX */
GRF_UART2_IOMUX_SEL_SHIFT = 0,
GRF_UART2_IOMUX_SEL_MASK = 3 << GRF_UART2_IOMUX_SEL_SHIFT,
GRF_UART2_IOMUX_SEL_M0 = 0,
GRF_UART2_IOMUX_SEL_M1,
GRF_SPI_IOMUX_SEL_SHIFT = 4,
GRF_SPI_IOMUX_SEL_MASK = 3 << GRF_SPI_IOMUX_SEL_SHIFT,
GRF_SPI_IOMUX_SEL_M0 = 0,
GRF_SPI_IOMUX_SEL_M1,
GRF_SPI_IOMUX_SEL_M2,
GRF_CARD_IOMUX_SEL_SHIFT = 7,
GRF_CARD_IOMUX_SEL_MASK = 1 << GRF_CARD_IOMUX_SEL_SHIFT,
GRF_CARD_IOMUX_SEL_M0 = 0,
GRF_CARD_IOMUX_SEL_M1,
};
static void pinctrl_rk3328_pwm_config(struct rk3328_grf_regs *grf, int pwm_id)
{
switch (pwm_id) {
case PERIPH_ID_PWM0:
rk_clrsetreg(&grf->gpio2a_iomux,
GRF_GPIO2A4_SEL_MASK,
GRF_PWM_0 << GRF_GPIO2A4_SEL_SHIFT);
break;
case PERIPH_ID_PWM1:
rk_clrsetreg(&grf->gpio2a_iomux,
GRF_GPIO2A5_SEL_MASK,
GRF_PWM_1 << GRF_GPIO2A5_SEL_SHIFT);
break;
case PERIPH_ID_PWM2:
rk_clrsetreg(&grf->gpio2a_iomux,
GRF_GPIO2A6_SEL_MASK,
GRF_PWM_2 << GRF_GPIO2A6_SEL_SHIFT);
break;
case PERIPH_ID_PWM3:
rk_clrsetreg(&grf->gpio2a_iomux,
GRF_GPIO2A2_SEL_MASK,
GRF_PWM_IR << GRF_GPIO2A2_SEL_SHIFT);
break;
default:
debug("pwm id = %d iomux error!\n", pwm_id);
break;
}
}
static void pinctrl_rk3328_i2c_config(struct rk3328_grf_regs *grf, int i2c_id)
{
switch (i2c_id) {
case PERIPH_ID_I2C0:
rk_clrsetreg(&grf->gpio2d_iomux,
GRF_GPIO2D0_SEL_MASK | GRF_GPIO2D1_SEL_MASK,
GRF_I2C0_SCL << GRF_GPIO2D0_SEL_SHIFT
| GRF_I2C0_SDA << GRF_GPIO2D1_SEL_SHIFT);
break;
case PERIPH_ID_I2C1:
rk_clrsetreg(&grf->gpio2a_iomux,
GRF_GPIO2A4_SEL_MASK | GRF_GPIO2A5_SEL_MASK,
GRF_I2C1_SCL << GRF_GPIO2A5_SEL_SHIFT
| GRF_I2C1_SDA << GRF_GPIO2A4_SEL_SHIFT);
break;
case PERIPH_ID_I2C2:
rk_clrsetreg(&grf->gpio2bl_iomux,
GRF_GPIO2BL5_SEL_MASK | GRF_GPIO2BL6_SEL_MASK,
GRF_I2C2_SCL << GRF_GPIO2BL6_SEL_SHIFT
| GRF_I2C2_SDA << GRF_GPIO2BL6_SEL_SHIFT);
break;
case PERIPH_ID_I2C3:
rk_clrsetreg(&grf->gpio0a_iomux,
GRF_GPIO0A5_SEL_MASK | GRF_GPIO0A6_SEL_MASK,
GRF_I2C3_SCL << GRF_GPIO0A5_SEL_SHIFT
| GRF_I2C3_SDA << GRF_GPIO0A6_SEL_SHIFT);
break;
default:
debug("i2c id = %d iomux error!\n", i2c_id);
break;
}
}
static void pinctrl_rk3328_lcdc_config(struct rk3328_grf_regs *grf, int lcd_id)
{
switch (lcd_id) {
case PERIPH_ID_LCDC0:
break;
default:
debug("lcdc id = %d iomux error!\n", lcd_id);
break;
}
}
static int pinctrl_rk3328_spi_config(struct rk3328_grf_regs *grf,
enum periph_id spi_id, int cs)
{
rk_clrsetreg(&grf->com_iomux,
GRF_SPI_IOMUX_SEL_MASK,
GRF_SPI_IOMUX_SEL_M0 << GRF_SPI_IOMUX_SEL_SHIFT);
switch (spi_id) {
case PERIPH_ID_SPI0:
switch (cs) {
case 0:
rk_clrsetreg(&grf->gpio2bl_iomux,
GRF_GPIO2BL3_SEL_MASK,
GRF_SPI_CSN0_M0 << GRF_GPIO2BL3_SEL_SHIFT);
break;
case 1:
rk_clrsetreg(&grf->gpio2bl_iomux,
GRF_GPIO2BL4_SEL_MASK,
GRF_SPI_CSN1_M0 << GRF_GPIO2BL4_SEL_SHIFT);
break;
default:
goto err;
}
rk_clrsetreg(&grf->gpio2bl_iomux,
GRF_GPIO2BL0_SEL_MASK,
GRF_SPI_CLK_TX_RX_M0 << GRF_GPIO2BL0_SEL_SHIFT);
break;
default:
goto err;
}
return 0;
err:
debug("rkspi: periph%d cs=%d not supported", spi_id, cs);
return -ENOENT;
}
static void pinctrl_rk3328_uart_config(struct rk3328_grf_regs *grf, int uart_id)
{
switch (uart_id) {
case PERIPH_ID_UART2:
break;
/* uart2 iomux select m1 */
rk_clrsetreg(&grf->com_iomux,
GRF_UART2_IOMUX_SEL_MASK,
GRF_UART2_IOMUX_SEL_M1
<< GRF_UART2_IOMUX_SEL_SHIFT);
rk_clrsetreg(&grf->gpio2a_iomux,
GRF_GPIO2A0_SEL_MASK | GRF_GPIO2A1_SEL_MASK,
GRF_UART2_TX_M1 << GRF_GPIO2A0_SEL_SHIFT |
GRF_UART2_RX_M1 << GRF_GPIO2A1_SEL_SHIFT);
break;
case PERIPH_ID_UART0:
case PERIPH_ID_UART1:
case PERIPH_ID_UART3:
case PERIPH_ID_UART4:
default:
debug("uart id = %d iomux error!\n", uart_id);
break;
}
}
static void pinctrl_rk3328_sdmmc_config(struct rk3328_grf_regs *grf,
int mmc_id)
{
switch (mmc_id) {
case PERIPH_ID_EMMC:
rk_clrsetreg(&grf->gpio0a_iomux,
GRF_GPIO0A7_SEL_MASK,
GRF_EMMC_DATA0 << GRF_GPIO0A7_SEL_SHIFT);
rk_clrsetreg(&grf->gpio2d_iomux,
GRF_GPIO2D4_SEL_MASK,
GRF_EMMC_DATA123 << GRF_GPIO2D4_SEL_SHIFT);
rk_clrsetreg(&grf->gpio3c_iomux,
GRF_GPIO3C0_SEL_MASK,
GRF_EMMC_DATA567_PWR_CLK_RSTN_CMD
<< GRF_GPIO3C0_SEL_SHIFT);
break;
case PERIPH_ID_SDCARD:
/* sdcard iomux select m0 */
rk_clrsetreg(&grf->com_iomux,
GRF_CARD_IOMUX_SEL_MASK,
GRF_CARD_IOMUX_SEL_M0 << GRF_CARD_IOMUX_SEL_SHIFT);
rk_clrsetreg(&grf->gpio2a_iomux,
GRF_GPIO2A7_SEL_MASK,
GRF_CARD_PWR_EN_M0 << GRF_GPIO2A7_SEL_SHIFT);
rk_clrsetreg(&grf->gpio1a_iomux,
GRF_GPIO1A0_SEL_MASK,
GRF_CARD_DATA_CLK_CMD_DETN
<< GRF_GPIO1A0_SEL_SHIFT);
break;
default:
debug("mmc id = %d iomux error!\n", mmc_id);
break;
}
}
static int rk3328_pinctrl_request(struct udevice *dev, int func, int flags)
{
struct rk3328_pinctrl_priv *priv = dev_get_priv(dev);
debug("%s: func=%x, flags=%x\n", __func__, func, flags);
switch (func) {
case PERIPH_ID_PWM0:
case PERIPH_ID_PWM1:
case PERIPH_ID_PWM2:
case PERIPH_ID_PWM3:
pinctrl_rk3328_pwm_config(priv->grf, func);
break;
case PERIPH_ID_I2C0:
case PERIPH_ID_I2C1:
case PERIPH_ID_I2C2:
case PERIPH_ID_I2C3:
pinctrl_rk3328_i2c_config(priv->grf, func);
break;
case PERIPH_ID_SPI0:
pinctrl_rk3328_spi_config(priv->grf, func, flags);
break;
case PERIPH_ID_UART0:
case PERIPH_ID_UART1:
case PERIPH_ID_UART2:
case PERIPH_ID_UART3:
case PERIPH_ID_UART4:
pinctrl_rk3328_uart_config(priv->grf, func);
break;
case PERIPH_ID_LCDC0:
case PERIPH_ID_LCDC1:
pinctrl_rk3328_lcdc_config(priv->grf, func);
break;
case PERIPH_ID_SDMMC0:
case PERIPH_ID_SDMMC1:
pinctrl_rk3328_sdmmc_config(priv->grf, func);
break;
default:
return -EINVAL;
}
return 0;
}
static int rk3328_pinctrl_get_periph_id(struct udevice *dev,
struct udevice *periph)
{
u32 cell[3];
int ret;
ret = fdtdec_get_int_array(gd->fdt_blob, periph->of_offset,
"interrupts", cell, ARRAY_SIZE(cell));
if (ret < 0)
return -EINVAL;
switch (cell[1]) {
case 49:
return PERIPH_ID_SPI0;
case 50:
return PERIPH_ID_PWM0;
case 36:
return PERIPH_ID_I2C0;
case 37: /* Note strange order */
return PERIPH_ID_I2C1;
case 38:
return PERIPH_ID_I2C2;
case 39:
return PERIPH_ID_I2C3;
case 12:
return PERIPH_ID_SDCARD;
case 14:
return PERIPH_ID_EMMC;
}
return -ENOENT;
}
static int rk3328_pinctrl_set_state_simple(struct udevice *dev,
struct udevice *periph)
{
int func;
func = rk3328_pinctrl_get_periph_id(dev, periph);
if (func < 0)
return func;
return rk3328_pinctrl_request(dev, func, 0);
}
static struct pinctrl_ops rk3328_pinctrl_ops = {
.set_state_simple = rk3328_pinctrl_set_state_simple,
.request = rk3328_pinctrl_request,
.get_periph_id = rk3328_pinctrl_get_periph_id,
};
static int rk3328_pinctrl_probe(struct udevice *dev)
{
struct rk3328_pinctrl_priv *priv = dev_get_priv(dev);
int ret = 0;
priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
debug("%s: grf=%p\n", __func__, priv->grf);
return ret;
}
static const struct udevice_id rk3328_pinctrl_ids[] = {
{ .compatible = "rockchip,rk3328-pinctrl" },
{ }
};
U_BOOT_DRIVER(pinctrl_rk3328) = {
.name = "rockchip_rk3328_pinctrl",
.id = UCLASS_PINCTRL,
.of_match = rk3328_pinctrl_ids,
.priv_auto_alloc_size = sizeof(struct rk3328_pinctrl_priv),
.ops = &rk3328_pinctrl_ops,
.bind = dm_scan_fdt_dev,
.probe = rk3328_pinctrl_probe,
};

View file

@ -22,112 +22,6 @@ struct rk3399_pinctrl_priv {
struct rk3399_pmugrf_regs *pmugrf;
};
enum {
/* GRF_GPIO2B_IOMUX */
GRF_GPIO2B1_SEL_SHIFT = 0,
GRF_GPIO2B1_SEL_MASK = 3 << GRF_GPIO2B1_SEL_SHIFT,
GRF_SPI2TPM_RXD = 1,
GRF_GPIO2B2_SEL_SHIFT = 2,
GRF_GPIO2B2_SEL_MASK = 3 << GRF_GPIO2B2_SEL_SHIFT,
GRF_SPI2TPM_TXD = 1,
GRF_GPIO2B3_SEL_SHIFT = 6,
GRF_GPIO2B3_SEL_MASK = 3 << GRF_GPIO2B3_SEL_SHIFT,
GRF_SPI2TPM_CLK = 1,
GRF_GPIO2B4_SEL_SHIFT = 8,
GRF_GPIO2B4_SEL_MASK = 3 << GRF_GPIO2B4_SEL_SHIFT,
GRF_SPI2TPM_CSN0 = 1,
/* GRF_GPIO3A_IOMUX */
GRF_GPIO3A4_SEL_SHIFT = 8,
GRF_GPIO3A4_SEL_MASK = 3 << GRF_GPIO3A4_SEL_SHIFT,
GRF_SPI0NORCODEC_RXD = 2,
GRF_GPIO3A5_SEL_SHIFT = 10,
GRF_GPIO3A5_SEL_MASK = 3 << GRF_GPIO3A5_SEL_SHIFT,
GRF_SPI0NORCODEC_TXD = 2,
GRF_GPIO3A6_SEL_SHIFT = 12,
GRF_GPIO3A6_SEL_MASK = 3 << GRF_GPIO3A6_SEL_SHIFT,
GRF_SPI0NORCODEC_CLK = 2,
GRF_GPIO3A7_SEL_SHIFT = 14,
GRF_GPIO3A7_SEL_MASK = 3 << GRF_GPIO3A7_SEL_SHIFT,
GRF_SPI0NORCODEC_CSN0 = 2,
/* GRF_GPIO3B_IOMUX */
GRF_GPIO3B0_SEL_SHIFT = 0,
GRF_GPIO3B0_SEL_MASK = 3 << GRF_GPIO3B0_SEL_SHIFT,
GRF_SPI0NORCODEC_CSN1 = 2,
/* GRF_GPIO4B_IOMUX */
GRF_GPIO4B0_SEL_SHIFT = 0,
GRF_GPIO4B0_SEL_MASK = 3 << GRF_GPIO4B0_SEL_SHIFT,
GRF_SDMMC_DATA0 = 1,
GRF_UART2DBGA_SIN = 2,
GRF_GPIO4B1_SEL_SHIFT = 2,
GRF_GPIO4B1_SEL_MASK = 3 << GRF_GPIO4B1_SEL_SHIFT,
GRF_SDMMC_DATA1 = 1,
GRF_UART2DBGA_SOUT = 2,
GRF_GPIO4B2_SEL_SHIFT = 4,
GRF_GPIO4B2_SEL_MASK = 3 << GRF_GPIO4B2_SEL_SHIFT,
GRF_SDMMC_DATA2 = 1,
GRF_GPIO4B3_SEL_SHIFT = 6,
GRF_GPIO4B3_SEL_MASK = 3 << GRF_GPIO4B3_SEL_SHIFT,
GRF_SDMMC_DATA3 = 1,
GRF_GPIO4B4_SEL_SHIFT = 8,
GRF_GPIO4B4_SEL_MASK = 3 << GRF_GPIO4B4_SEL_SHIFT,
GRF_SDMMC_CLKOUT = 1,
GRF_GPIO4B5_SEL_SHIFT = 10,
GRF_GPIO4B5_SEL_MASK = 3 << GRF_GPIO4B5_SEL_SHIFT,
GRF_SDMMC_CMD = 1,
/* GRF_GPIO4C_IOMUX */
GRF_GPIO4C2_SEL_SHIFT = 4,
GRF_GPIO4C2_SEL_MASK = 3 << GRF_GPIO4C2_SEL_SHIFT,
GRF_PWM_0 = 1,
GRF_GPIO4C3_SEL_SHIFT = 6,
GRF_GPIO4C3_SEL_MASK = 3 << GRF_GPIO4C3_SEL_SHIFT,
GRF_UART2DGBC_SIN = 1,
GRF_GPIO4C4_SEL_SHIFT = 8,
GRF_GPIO4C4_SEL_MASK = 3 << GRF_GPIO4C4_SEL_SHIFT,
GRF_UART2DBGC_SOUT = 1,
GRF_GPIO4C6_SEL_SHIFT = 12,
GRF_GPIO4C6_SEL_MASK = 3 << GRF_GPIO4C6_SEL_SHIFT,
GRF_PWM_1 = 1,
/* PMUGRF_GPIO0A_IOMUX */
PMUGRF_GPIO0A6_SEL_SHIFT = 12,
PMUGRF_GPIO0A6_SEL_MASK = 3 << PMUGRF_GPIO0A6_SEL_SHIFT,
PMUGRF_PWM_3A = 1,
/* PMUGRF_GPIO1A_IOMUX */
PMUGRF_GPIO1A7_SEL_SHIFT = 14,
PMUGRF_GPIO1A7_SEL_MASK = 3 << PMUGRF_GPIO1A7_SEL_SHIFT,
PMUGRF_SPI1EC_RXD = 2,
/* PMUGRF_GPIO1B_IOMUX */
PMUGRF_GPIO1B0_SEL_SHIFT = 0,
PMUGRF_GPIO1B0_SEL_MASK = 3 << PMUGRF_GPIO1B0_SEL_SHIFT,
PMUGRF_SPI1EC_TXD = 2,
PMUGRF_GPIO1B1_SEL_SHIFT = 2,
PMUGRF_GPIO1B1_SEL_MASK = 3 << PMUGRF_GPIO1B1_SEL_SHIFT,
PMUGRF_SPI1EC_CLK = 2,
PMUGRF_GPIO1B2_SEL_SHIFT = 4,
PMUGRF_GPIO1B2_SEL_MASK = 3 << PMUGRF_GPIO1B2_SEL_SHIFT,
PMUGRF_SPI1EC_CSN0 = 2,
PMUGRF_GPIO1B6_SEL_SHIFT = 12,
PMUGRF_GPIO1B6_SEL_MASK = 3 << PMUGRF_GPIO1B6_SEL_SHIFT,
PMUGRF_PWM_3B = 1,
PMUGRF_GPIO1B7_SEL_SHIFT = 14,
PMUGRF_GPIO1B7_SEL_MASK = 3 << PMUGRF_GPIO1B7_SEL_SHIFT,
PMUGRF_I2C0PMU_SDA = 2,
/* PMUGRF_GPIO1C_IOMUX */
PMUGRF_GPIO1C0_SEL_SHIFT = 0,
PMUGRF_GPIO1C0_SEL_MASK = 3 << PMUGRF_GPIO1C0_SEL_SHIFT,
PMUGRF_I2C0PMU_SCL = 2,
PMUGRF_GPIO1C3_SEL_SHIFT = 6,
PMUGRF_GPIO1C3_SEL_MASK = 3 << PMUGRF_GPIO1C3_SEL_SHIFT,
PMUGRF_PWM_2 = 1,
};
static void pinctrl_rk3399_pwm_config(struct rk3399_grf_regs *grf,
struct rk3399_pmugrf_regs *pmugrf, int pwm_id)
{
@ -359,6 +253,7 @@ static int rk3399_pinctrl_request(struct udevice *dev, int func, int flags)
static int rk3399_pinctrl_get_periph_id(struct udevice *dev,
struct udevice *periph)
{
#if !CONFIG_IS_ENABLED(OF_PLATDATA)
u32 cell[3];
int ret;
@ -389,7 +284,7 @@ static int rk3399_pinctrl_get_periph_id(struct udevice *dev,
case 65:
return PERIPH_ID_SDMMC1;
}
#endif
return -ENOENT;
}
@ -434,6 +329,8 @@ U_BOOT_DRIVER(pinctrl_rk3399) = {
.of_match = rk3399_pinctrl_ids,
.priv_auto_alloc_size = sizeof(struct rk3399_pinctrl_priv),
.ops = &rk3399_pinctrl_ops,
#if !CONFIG_IS_ENABLED(OF_PLATDATA)
.bind = dm_scan_fdt_dev,
#endif
.probe = rk3399_pinctrl_probe,
};

View file

@ -12,12 +12,19 @@
#include <serial.h>
#include <asm/arch/clock.h>
#if defined(CONFIG_ROCKCHIP_RK3188)
struct rockchip_uart_platdata {
struct dtd_rockchip_rk3188_uart dtplat;
struct ns16550_platdata plat;
};
struct dtd_rockchip_rk3188_uart *dtplat, s_dtplat;
#elif defined(CONFIG_ROCKCHIP_RK3288)
struct rockchip_uart_platdata {
struct dtd_rockchip_rk3288_uart dtplat;
struct ns16550_platdata plat;
};
struct dtd_rockchip_rk3288_uart *dtplat, s_dtplat;
#endif
static int rockchip_serial_probe(struct udevice *dev)
{
@ -33,6 +40,16 @@ static int rockchip_serial_probe(struct udevice *dev)
return ns16550_serial_probe(dev);
}
U_BOOT_DRIVER(rockchip_rk3188_uart) = {
.name = "rockchip_rk3188_uart",
.id = UCLASS_SERIAL,
.priv_auto_alloc_size = sizeof(struct NS16550),
.platdata_auto_alloc_size = sizeof(struct rockchip_uart_platdata),
.probe = rockchip_serial_probe,
.ops = &ns16550_serial_ops,
.flags = DM_FLAG_PRE_RELOC,
};
U_BOOT_DRIVER(rockchip_rk3288_uart) = {
.name = "rockchip_rk3288_uart",
.id = UCLASS_SERIAL,

View file

@ -9,7 +9,9 @@ obj-$(CONFIG_SYSRESET) += sysreset-uclass.o
ifndef CONFIG_SPL_BUILD
obj-$(CONFIG_ROCKCHIP_RK3036) += sysreset_rk3036.o
endif
obj-$(CONFIG_ROCKCHIP_RK3188) += sysreset_rk3188.o
obj-$(CONFIG_ROCKCHIP_RK3288) += sysreset_rk3288.o
obj-$(CONFIG_ROCKCHIP_RK3328) += sysreset_rk3328.o
obj-$(CONFIG_ROCKCHIP_RK3399) += sysreset_rk3399.o
obj-$(CONFIG_SANDBOX) += sysreset_sandbox.o
obj-$(CONFIG_ARCH_SNAPDRAGON) += sysreset_snapdragon.o

View file

@ -0,0 +1,47 @@
/*
* (C) Copyright 2015 Google, Inc
*
* SPDX-License-Identifier: GPL-2.0
*/
#include <common.h>
#include <dm.h>
#include <errno.h>
#include <sysreset.h>
#include <asm/io.h>
#include <asm/arch/clock.h>
#include <asm/arch/cru_rk3188.h>
#include <asm/arch/hardware.h>
#include <linux/err.h>
int rk3188_sysreset_request(struct udevice *dev, enum sysreset_t type)
{
struct rk3188_cru *cru = rockchip_get_cru();
if (IS_ERR(cru))
return PTR_ERR(cru);
switch (type) {
case SYSRESET_WARM:
rk_clrreg(&cru->cru_mode_con, 0xffff);
writel(0xeca8, &cru->cru_glb_srst_snd_value);
break;
case SYSRESET_COLD:
rk_clrreg(&cru->cru_mode_con, 0xffff);
writel(0xfdb9, &cru->cru_glb_srst_fst_value);
break;
default:
return -EPROTONOSUPPORT;
}
return -EINPROGRESS;
}
static struct sysreset_ops rk3188_sysreset = {
.request = rk3188_sysreset_request,
};
U_BOOT_DRIVER(sysreset_rk3188) = {
.name = "rk3188_sysreset",
.id = UCLASS_SYSRESET,
.ops = &rk3188_sysreset,
};

View file

@ -0,0 +1,45 @@
/*
* (C) Copyright 2016 Rockchip Electronics Co., Ltd
*
* SPDX-License-Identifier: GPL-2.0
*/
#include <common.h>
#include <dm.h>
#include <errno.h>
#include <sysreset.h>
#include <asm/arch/clock.h>
#include <asm/arch/cru_rk3328.h>
#include <asm/arch/hardware.h>
#include <asm/io.h>
#include <linux/err.h>
int rk3328_sysreset_request(struct udevice *dev, enum sysreset_t type)
{
struct rk3328_cru *cru = rockchip_get_cru();
if (IS_ERR(cru))
return PTR_ERR(cru);
switch (type) {
case SYSRESET_WARM:
writel(0xeca8, &cru->glb_srst_snd_value);
break;
case SYSRESET_COLD:
writel(0xfdb9, &cru->glb_srst_fst_value);
break;
default:
return -EPROTONOSUPPORT;
}
return -EINPROGRESS;
}
static struct sysreset_ops rk3328_sysreset = {
.request = rk3328_sysreset_request,
};
U_BOOT_DRIVER(sysreset_rk3328) = {
.name = "rk3328_sysreset",
.id = UCLASS_SYSRESET,
.ops = &rk3328_sysreset,
};

View file

@ -32,37 +32,37 @@ struct rk_hdmi_priv {
static const struct tmds_n_cts n_cts_table[] = {
{
.tmds = 25175, .n = 6144, .cts = 25175,
.tmds = 25175000, .n = 6144, .cts = 25175,
}, {
.tmds = 25200, .n = 6144, .cts = 25200,
.tmds = 25200000, .n = 6144, .cts = 25200,
}, {
.tmds = 27000, .n = 6144, .cts = 27000,
.tmds = 27000000, .n = 6144, .cts = 27000,
}, {
.tmds = 27027, .n = 6144, .cts = 27027,
.tmds = 27027000, .n = 6144, .cts = 27027,
}, {
.tmds = 40000, .n = 6144, .cts = 40000,
.tmds = 40000000, .n = 6144, .cts = 40000,
}, {
.tmds = 54000, .n = 6144, .cts = 54000,
.tmds = 54000000, .n = 6144, .cts = 54000,
}, {
.tmds = 54054, .n = 6144, .cts = 54054,
.tmds = 54054000, .n = 6144, .cts = 54054,
}, {
.tmds = 65000, .n = 6144, .cts = 65000,
.tmds = 65000000, .n = 6144, .cts = 65000,
}, {
.tmds = 74176, .n = 11648, .cts = 140625,
.tmds = 74176000, .n = 11648, .cts = 140625,
}, {
.tmds = 74250, .n = 6144, .cts = 74250,
.tmds = 74250000, .n = 6144, .cts = 74250,
}, {
.tmds = 83500, .n = 6144, .cts = 83500,
.tmds = 83500000, .n = 6144, .cts = 83500,
}, {
.tmds = 106500, .n = 6144, .cts = 106500,
.tmds = 106500000, .n = 6144, .cts = 106500,
}, {
.tmds = 108000, .n = 6144, .cts = 108000,
.tmds = 108000000, .n = 6144, .cts = 108000,
}, {
.tmds = 148352, .n = 5824, .cts = 140625,
.tmds = 148352000, .n = 5824, .cts = 140625,
}, {
.tmds = 148500, .n = 6144, .cts = 148500,
.tmds = 148500000, .n = 6144, .cts = 148500,
}, {
.tmds = 297000, .n = 5120, .cts = 247500,
.tmds = 297000000, .n = 5120, .cts = 247500,
}
};
@ -124,12 +124,6 @@ static const struct hdmi_mpll_config rockchip_mpll_cfg[] = {
}
};
static const u32 csc_coeff_default[3][4] = {
{ 0x2000, 0x0000, 0x0000, 0x0000 },
{ 0x0000, 0x2000, 0x0000, 0x0000 },
{ 0x0000, 0x0000, 0x2000, 0x0000 }
};
static void hdmi_set_clock_regenerator(struct rk3288_hdmi *regs, u32 n, u32 cts)
{
uint cts3;
@ -220,37 +214,6 @@ static void hdmi_video_sample(struct rk3288_hdmi *regs)
writel(0x0, &regs->tx_bcbdata1);
}
static void hdmi_update_csc_coeffs(struct rk3288_hdmi *regs)
{
u32 i, j;
u32 csc_scale = 1;
/* the csc registers are sequential, alternating msb then lsb */
for (i = 0; i < ARRAY_SIZE(csc_coeff_default); i++) {
for (j = 0; j < ARRAY_SIZE(csc_coeff_default[0]); j++) {
u32 coeff = csc_coeff_default[i][j];
writel(coeff >> 8, &regs->csc_coef[i][j].msb);
writel(coeff && 0xff, &regs->csc_coef[i][j].lsb);
}
}
clrsetbits_le32(&regs->csc_scale, HDMI_CSC_SCALE_CSCSCALE_MASK,
csc_scale);
}
static void hdmi_video_csc(struct rk3288_hdmi *regs)
{
u32 color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_24BPP;
u32 interpolation = HDMI_CSC_CFG_INTMODE_DISABLE;
/* configure the csc registers */
writel(interpolation, &regs->csc_cfg);
clrsetbits_le32(&regs->csc_scale,
HDMI_CSC_SCALE_CSC_COLORDE_PTH_MASK, color_depth);
hdmi_update_csc_coeffs(regs);
}
static void hdmi_video_packetize(struct rk3288_hdmi *regs)
{
u32 output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS;
@ -467,7 +430,6 @@ static int hdmi_phy_init(struct rk3288_hdmi *regs, uint mpixelclock)
hdmi_phy_enable_tmds(regs, 0);
hdmi_phy_enable_power(regs, 0);
/* enable csc */
ret = hdmi_phy_configure(regs, mpixelclock);
if (ret) {
debug("hdmi phy config failure %d\n", ret);
@ -837,7 +799,6 @@ static int rk_hdmi_enable(struct udevice *dev, int panel_bpp,
hdmi_audio_set_samplerate(regs, edid->pixelclock.typ);
hdmi_video_packetize(regs);
hdmi_video_csc(regs);
hdmi_video_sample(regs);
hdmi_clear_overflow(regs);

View file

@ -127,5 +127,6 @@ typedef struct global_data {
#define GD_FLG_SKIP_RELOC 0x00800 /* Don't relocate */
#define GD_FLG_RECORD 0x01000 /* Record console */
#define GD_FLG_ENV_DEFAULT 0x02000 /* Default variable flag */
#define GD_FLG_SPL_EARLY_INIT 0x04000 /* Early SPL init is done */
#endif /* __ASM_GENERIC_GBL_DATA_H */

View file

@ -0,0 +1,26 @@
/*
* (C) Copyright 2016 Rockchip Electronics Co., Ltd
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef __EVB_RK3328_H
#define __EVB_RK3328_H
#include <configs/rk3328_common.h>
#define CONFIG_ENV_IS_IN_MMC
#define CONFIG_SYS_MMC_ENV_DEV 1
/*
* SPL @ 32k for ~36k
* ENV @ 96k
* u-boot @ 128K
*/
#define CONFIG_ENV_OFFSET (96 * 1024)
#define SDRAM_BANK_SIZE (2UL << 30)
#define CONFIG_SYS_WHITE_ON_BLACK
#define CONFIG_CONSOLE_SCROLL_LINES 10
#endif

View file

@ -0,0 +1,120 @@
/*
* (C) Copyright 2015 Google, Inc
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef __CONFIG_RK3188_COMMON_H
#define __CONFIG_RK3188_COMMON_H
#define CONFIG_SYS_CACHELINE_SIZE 64
#include <asm/arch/hardware.h>
#include "rockchip-common.h"
#define CONFIG_SKIP_LOWLEVEL_INIT_ONLY
#define CONFIG_NR_DRAM_BANKS 1
#define CONFIG_ENV_SIZE 0x2000
#define CONFIG_SYS_MAXARGS 16
#define CONFIG_BAUDRATE 115200
#define CONFIG_SYS_MALLOC_LEN (32 << 20)
#define CONFIG_SYS_CBSIZE 1024
#define CONFIG_SYS_THUMB_BUILD
#define CONFIG_SYS_TIMER_RATE (24 * 1000 * 1000)
#define CONFIG_SYS_TIMER_BASE 0x2000e000 /* TIMER3 */
#define CONFIG_SYS_TIMER_COUNTER (CONFIG_SYS_TIMER_BASE + 8)
#define CONFIG_SYS_TIMER_COUNTS_DOWN
#define CONFIG_SYS_NS16550_MEM32
#define CONFIG_SPL_BOARD_INIT
#ifdef CONFIG_ROCKCHIP_SPL_BACK_TO_BROM
/* Bootrom will load u-boot binary to 0x60000000 once return from SPL */
#define CONFIG_SYS_TEXT_BASE 0x60000000
#else
#define CONFIG_SYS_TEXT_BASE 0x60100000
#endif
#define CONFIG_SYS_INIT_SP_ADDR 0x60100000
#define CONFIG_SYS_LOAD_ADDR 0x60800800
#define CONFIG_ROCKCHIP_MAX_INIT_SIZE (0x8000 - 0x800)
#define CONFIG_ROCKCHIP_CHIP_TAG "RK31"
#ifdef CONFIG_TPL_BUILD
#define CONFIG_SPL_TEXT_BASE 0x10080804
/* tpl size 1kb - 4byte RK31 header */
#define CONFIG_SPL_MAX_SIZE (0x400 - 0x4)
#elif defined(CONFIG_SPL_BUILD)
/* spl size 32kb sram - 2kb bootrom - 1kb spl */
#define CONFIG_SPL_MAX_SIZE (0x8000 - 0xC00)
#define CONFIG_SPL_TEXT_BASE 0x10080C00
#define CONFIG_SPL_FRAMEWORK 1
#define CONFIG_SPL_CLK 1
#define CONFIG_SPL_PINCTRL 1
#define CONFIG_SPL_REGMAP 1
#define CONFIG_SPL_SYSCON 1
#define CONFIG_SPL_RAM 1
#define CONFIG_SPL_DRIVERS_MISC_SUPPORT 1
#define CONFIG_ROCKCHIP_SERIAL 1
#endif
#define CONFIG_SPL_STACK 0x10087fff
/* MMC/SD IP block */
#define CONFIG_BOUNCE_BUFFER
#define CONFIG_FAT_WRITE
#define CONFIG_SYS_SDRAM_BASE 0x60000000
#define CONFIG_NR_DRAM_BANKS 1
#define SDRAM_BANK_SIZE (2UL << 30)
#define CONFIG_SPI_FLASH
#define CONFIG_SPI
#define CONFIG_SF_DEFAULT_SPEED 20000000
#ifndef CONFIG_SPL_BUILD
/* usb otg */
#define CONFIG_USB_GADGET
#define CONFIG_USB_GADGET_DUALSPEED
#define CONFIG_USB_GADGET_DWC2_OTG
#define CONFIG_ROCKCHIP_USB2_PHY
#define CONFIG_USB_GADGET_VBUS_DRAW 0
#define CONFIG_USB_GADGET_DOWNLOAD
#define CONFIG_G_DNL_MANUFACTURER "Rockchip"
#define CONFIG_G_DNL_VENDOR_NUM 0x2207
#define CONFIG_G_DNL_PRODUCT_NUM 0x310a
/* usb host support */
#ifdef CONFIG_CMD_USB
#define CONFIG_USB_DWC2
#define CONFIG_USB_HOST_ETHER
#define CONFIG_USB_ETHER_SMSC95XX
#define CONFIG_USB_ETHER_ASIX
#endif
#define ENV_MEM_LAYOUT_SETTINGS \
"scriptaddr=0x60000000\0" \
"pxefile_addr_r=0x60100000\0" \
"fdt_addr_r=0x61f00000\0" \
"kernel_addr_r=0x62000000\0" \
"ramdisk_addr_r=0x64000000\0"
#include <config_distro_bootcmd.h>
/* Linux fails to load the fdt if it's loaded above 256M on a Rock board,
* so limit the fdt reallocation to that */
#define CONFIG_EXTRA_ENV_SETTINGS \
"fdt_high=0x6fffffff\0" \
"initrd_high=0x6fffffff\0" \
"partitions=" PARTS_DEFAULT \
ENV_MEM_LAYOUT_SETTINGS \
ROCKCHIP_DEVICE_SETTINGS \
BOOTENV
#endif /* CONFIG_SPL_BUILD */
#define CONFIG_PREBOOT
#endif

View file

@ -0,0 +1,65 @@
/*
* (C) Copyright 2016 Rockchip Electronics Co., Ltd
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef __CONFIG_RK3328_COMMON_H
#define __CONFIG_RK3328_COMMON_H
#include "rockchip-common.h"
#define CONFIG_NR_DRAM_BANKS 1
#define CONFIG_ENV_SIZE 0x2000
#define CONFIG_SYS_MAXARGS 16
#define CONFIG_BAUDRATE 1500000
#define CONFIG_SYS_MALLOC_LEN (32 << 20)
#define CONFIG_SYS_CBSIZE 1024
#define CONFIG_SKIP_LOWLEVEL_INIT
#define CONFIG_SYS_NS16550_MEM32
#define CONFIG_SYS_TEXT_BASE 0x00200000
#define CONFIG_SYS_INIT_SP_ADDR 0x00300000
#define CONFIG_SYS_LOAD_ADDR 0x00800800
#define CONFIG_SYS_BOOTM_LEN (64 << 20) /* 64M */
/* MMC/SD IP block */
#define CONFIG_BOUNCE_BUFFER
#define CONFIG_SUPPORT_VFAT
#define CONFIG_FS_FAT
#define CONFIG_FAT_WRITE
#define CONFIG_FS_EXT4
/* RAW SD card / eMMC locations. */
#define CONFIG_SYS_SPI_U_BOOT_OFFS (128 << 10)
/* FAT sd card locations. */
#define CONFIG_SYS_MMCSD_FS_BOOT_PARTITION 1
#define CONFIG_SYS_SDRAM_BASE 0
#define CONFIG_NR_DRAM_BANKS 1
#define CONFIG_SPI_FLASH
#define CONFIG_SPI
#define CONFIG_SF_DEFAULT_SPEED 20000000
#ifndef CONFIG_SPL_BUILD
#define ENV_MEM_LAYOUT_SETTINGS \
"scriptaddr=0x00500000\0" \
"pxefile_addr_r=0x00600000\0" \
"fdt_addr_r=0x01f00000\0" \
"kernel_addr_r=0x02000000\0" \
"ramdisk_addr_r=0x04000000\0"
#include <config_distro_bootcmd.h>
#define CONFIG_EXTRA_ENV_SETTINGS \
ENV_MEM_LAYOUT_SETTINGS \
"partitions=" PARTS_DEFAULT \
BOOTENV
#endif
#endif

View file

@ -16,12 +16,23 @@
#define CONFIG_SYS_MALLOC_LEN (32 << 20)
#define CONFIG_SYS_CBSIZE 1024
#define CONFIG_SKIP_LOWLEVEL_INIT
#define CONFIG_SPL_FRAMEWORK
#define CONFIG_SPL_DRIVERS_MISC_SUPPORT
#define CONFIG_SPL_LIBCOMMON_SUPPORT
#define CONFIG_SPL_LIBGENERIC_SUPPORT
#define CONFIG_SPL_SERIAL_SUPPORT
#define CONFIG_SYS_NS16550_MEM32
#define CONFIG_SYS_TEXT_BASE 0x00200000
#define CONFIG_SYS_INIT_SP_ADDR 0x00300000
#define CONFIG_SYS_LOAD_ADDR 0x00800800
#define CONFIG_SPL_STACK 0xff8effff
#define CONFIG_SPL_TEXT_BASE 0xff8c2008
#define CONFIG_SPL_MAX_SIZE 0x30000
/* BSS setup */
#define CONFIG_SPL_BSS_START_ADDR 0xff8e0000
#define CONFIG_SPL_BSS_MAX_SIZE 0x10000
#define CONFIG_SYS_BOOTM_LEN (64 << 20) /* 64M */

View file

@ -13,7 +13,7 @@
#undef BOOT_TARGET_DEVICES
#define BOOT_TARGET_DEVICES(func) \
func(MMC, mmc, 0)
func(MMC, mmc, 1)
#define CONFIG_ENV_IS_IN_MMC
#define CONFIG_SYS_MMC_ENV_DEV 0

View file

@ -48,4 +48,30 @@ static inline void dm_dump_devres(void)
}
#endif
/**
* Check if a dt node should be or was bound before relocation.
*
* Devicetree nodes can be marked as needed to be bound
* in the loader stages via special devicetree properties.
*
* Before relocation this function can be used to check if nodes
* are required in either SPL or TPL stages.
*
* After relocation and jumping into the real U-Boot binary
* it is possible to determine if a node was bound in one of
* SPL/TPL stages.
*
* There are 3 settings currently in use
* -
* - u-boot,dm-pre-reloc: legacy and indicates any of TPL or SPL
* Existing platforms only use it to indicate nodes needee in
* SPL. Should probably be replaced by u-boot,dm-spl for
* existing platforms.
* @blob: devicetree
* @offset: node offset
*
* Returns true if node is needed in SPL/TL, false otherwise.
*/
bool dm_fdt_pre_reloc(const void *blob, int offset);
#endif

View file

@ -0,0 +1,32 @@
/*
* Copyright (c) 2014 MundoReader S.L.
* Author: Heiko Stuebner <heiko@sntech.de>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RK3066A_H
#define _DT_BINDINGS_CLK_ROCKCHIP_RK3066A_H
#include <dt-bindings/clock/rk3188-cru-common.h>
/* soft-reset indices */
#define SRST_SRST1 0
#define SRST_SRST2 1
#define SRST_L2MEM 18
#define SRST_I2S0 23
#define SRST_I2S1 24
#define SRST_I2S2 25
#define SRST_TIMER2 29
#define SRST_GPIO4 36
#define SRST_GPIO6 38
#define SRST_TSADC 92
#define SRST_HDMI 96
#define SRST_HDMI_APB 97
#define SRST_CIF1 111
#endif

View file

@ -0,0 +1,256 @@
/*
* Copyright (c) 2014 MundoReader S.L.
* Author: Heiko Stuebner <heiko@sntech.de>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RK3188_COMMON_H
#define _DT_BINDINGS_CLK_ROCKCHIP_RK3188_COMMON_H
/* core clocks from */
#define PLL_APLL 1
#define PLL_DPLL 2
#define PLL_CPLL 3
#define PLL_GPLL 4
#define CORE_PERI 5
#define CORE_L2C 6
#define ARMCLK 7
/* sclk gates (special clocks) */
#define SCLK_UART0 64
#define SCLK_UART1 65
#define SCLK_UART2 66
#define SCLK_UART3 67
#define SCLK_MAC 68
#define SCLK_SPI0 69
#define SCLK_SPI1 70
#define SCLK_SARADC 71
#define SCLK_SDMMC 72
#define SCLK_SDIO 73
#define SCLK_EMMC 74
#define SCLK_I2S0 75
#define SCLK_I2S1 76
#define SCLK_I2S2 77
#define SCLK_SPDIF 78
#define SCLK_CIF0 79
#define SCLK_CIF1 80
#define SCLK_OTGPHY0 81
#define SCLK_OTGPHY1 82
#define SCLK_HSADC 83
#define SCLK_TIMER0 84
#define SCLK_TIMER1 85
#define SCLK_TIMER2 86
#define SCLK_TIMER3 87
#define SCLK_TIMER4 88
#define SCLK_TIMER5 89
#define SCLK_TIMER6 90
#define SCLK_JTAG 91
#define SCLK_SMC 92
#define SCLK_TSADC 93
#define DCLK_LCDC0 190
#define DCLK_LCDC1 191
/* aclk gates */
#define ACLK_DMA1 192
#define ACLK_DMA2 193
#define ACLK_GPS 194
#define ACLK_LCDC0 195
#define ACLK_LCDC1 196
#define ACLK_GPU 197
#define ACLK_SMC 198
#define ACLK_CIF 199
#define ACLK_IPP 200
#define ACLK_RGA 201
#define ACLK_CIF0 202
#define ACLK_CPU 203
#define ACLK_PERI 204
/* pclk gates */
#define PCLK_GRF 320
#define PCLK_PMU 321
#define PCLK_TIMER0 322
#define PCLK_TIMER1 323
#define PCLK_TIMER2 324
#define PCLK_TIMER3 325
#define PCLK_PWM01 326
#define PCLK_PWM23 327
#define PCLK_SPI0 328
#define PCLK_SPI1 329
#define PCLK_SARADC 330
#define PCLK_WDT 331
#define PCLK_UART0 332
#define PCLK_UART1 333
#define PCLK_UART2 334
#define PCLK_UART3 335
#define PCLK_I2C0 336
#define PCLK_I2C1 337
#define PCLK_I2C2 338
#define PCLK_I2C3 339
#define PCLK_I2C4 340
#define PCLK_GPIO0 341
#define PCLK_GPIO1 342
#define PCLK_GPIO2 343
#define PCLK_GPIO3 344
#define PCLK_GPIO4 345
#define PCLK_GPIO6 346
#define PCLK_EFUSE 347
#define PCLK_TZPC 348
#define PCLK_TSADC 349
#define PCLK_CPU 350
#define PCLK_PERI 351
#define PCLK_DDRUPCTL 352
#define PCLK_PUBL 353
/* hclk gates */
#define HCLK_SDMMC 448
#define HCLK_SDIO 449
#define HCLK_EMMC 450
#define HCLK_OTG0 451
#define HCLK_EMAC 452
#define HCLK_SPDIF 453
#define HCLK_I2S0 454
#define HCLK_I2S1 455
#define HCLK_I2S2 456
#define HCLK_OTG1 457
#define HCLK_HSIC 458
#define HCLK_HSADC 459
#define HCLK_PIDF 460
#define HCLK_LCDC0 461
#define HCLK_LCDC1 462
#define HCLK_ROM 463
#define HCLK_CIF0 464
#define HCLK_IPP 465
#define HCLK_RGA 466
#define HCLK_NANDC0 467
#define HCLK_CPU 468
#define HCLK_PERI 469
#define CLK_NR_CLKS (HCLK_PERI + 1)
/* soft-reset indices */
#define SRST_MCORE 2
#define SRST_CORE0 3
#define SRST_CORE1 4
#define SRST_MCORE_DBG 7
#define SRST_CORE0_DBG 8
#define SRST_CORE1_DBG 9
#define SRST_CORE0_WDT 12
#define SRST_CORE1_WDT 13
#define SRST_STRC_SYS 14
#define SRST_L2C 15
#define SRST_CPU_AHB 17
#define SRST_AHB2APB 19
#define SRST_DMA1 20
#define SRST_INTMEM 21
#define SRST_ROM 22
#define SRST_SPDIF 26
#define SRST_TIMER0 27
#define SRST_TIMER1 28
#define SRST_EFUSE 30
#define SRST_GPIO0 32
#define SRST_GPIO1 33
#define SRST_GPIO2 34
#define SRST_GPIO3 35
#define SRST_UART0 39
#define SRST_UART1 40
#define SRST_UART2 41
#define SRST_UART3 42
#define SRST_I2C0 43
#define SRST_I2C1 44
#define SRST_I2C2 45
#define SRST_I2C3 46
#define SRST_I2C4 47
#define SRST_PWM0 48
#define SRST_PWM1 49
#define SRST_DAP_PO 50
#define SRST_DAP 51
#define SRST_DAP_SYS 52
#define SRST_TPIU_ATB 53
#define SRST_PMU_APB 54
#define SRST_GRF 55
#define SRST_PMU 56
#define SRST_PERI_AXI 57
#define SRST_PERI_AHB 58
#define SRST_PERI_APB 59
#define SRST_PERI_NIU 60
#define SRST_CPU_PERI 61
#define SRST_EMEM_PERI 62
#define SRST_USB_PERI 63
#define SRST_DMA2 64
#define SRST_SMC 65
#define SRST_MAC 66
#define SRST_NANC0 68
#define SRST_USBOTG0 69
#define SRST_USBPHY0 70
#define SRST_OTGC0 71
#define SRST_USBOTG1 72
#define SRST_USBPHY1 73
#define SRST_OTGC1 74
#define SRST_HSADC 76
#define SRST_PIDFILTER 77
#define SRST_DDR_MSCH 79
#define SRST_TZPC 80
#define SRST_SDMMC 81
#define SRST_SDIO 82
#define SRST_EMMC 83
#define SRST_SPI0 84
#define SRST_SPI1 85
#define SRST_WDT 86
#define SRST_SARADC 87
#define SRST_DDRPHY 88
#define SRST_DDRPHY_APB 89
#define SRST_DDRCTL 90
#define SRST_DDRCTL_APB 91
#define SRST_DDRPUB 93
#define SRST_VIO0_AXI 98
#define SRST_VIO0_AHB 99
#define SRST_LCDC0_AXI 100
#define SRST_LCDC0_AHB 101
#define SRST_LCDC0_DCLK 102
#define SRST_LCDC1_AXI 103
#define SRST_LCDC1_AHB 104
#define SRST_LCDC1_DCLK 105
#define SRST_IPP_AXI 106
#define SRST_IPP_AHB 107
#define SRST_RGA_AXI 108
#define SRST_RGA_AHB 109
#define SRST_CIF0 110
#define SRST_VCODEC_AXI 112
#define SRST_VCODEC_AHB 113
#define SRST_VIO1_AXI 114
#define SRST_VCODEC_CPU 115
#define SRST_VCODEC_NIU 116
#define SRST_GPU 120
#define SRST_GPU_NIU 122
#define SRST_TFUN_ATB 125
#define SRST_TFUN_APB 126
#define SRST_CTI4_APB 127
#define SRST_TPIU_APB 128
#define SRST_TRACE 129
#define SRST_CORE_DBG 130
#define SRST_DBG_APB 131
#define SRST_CTI0 132
#define SRST_CTI0_APB 133
#define SRST_CTI1 134
#define SRST_CTI1_APB 135
#define SRST_PTM_CORE0 136
#define SRST_PTM_CORE1 137
#define SRST_PTM0 138
#define SRST_PTM0_ATB 139
#define SRST_PTM1 140
#define SRST_PTM1_ATB 141
#define SRST_CTM 142
#define SRST_TS 143
#endif

View file

@ -0,0 +1,48 @@
/*
* Copyright (c) 2014 MundoReader S.L.
* Author: Heiko Stuebner <heiko@sntech.de>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RK3188_H
#define _DT_BINDINGS_CLK_ROCKCHIP_RK3188_H
#include <dt-bindings/clock/rk3188-cru-common.h>
/* soft-reset indices */
#define SRST_PTM_CORE2 0
#define SRST_PTM_CORE3 1
#define SRST_CORE2 5
#define SRST_CORE3 6
#define SRST_CORE2_DBG 10
#define SRST_CORE3_DBG 11
#define SRST_TIMER2 16
#define SRST_TIMER4 23
#define SRST_I2S0 24
#define SRST_TIMER5 25
#define SRST_TIMER3 29
#define SRST_TIMER6 31
#define SRST_PTM3 36
#define SRST_PTM3_ATB 37
#define SRST_GPS 67
#define SRST_HSICPHY 75
#define SRST_TIMER 78
#define SRST_PTM2 92
#define SRST_CORE2_WDT 94
#define SRST_CORE3_WDT 95
#define SRST_PTM2_ATB 111
#define SRST_HSIC 117
#define SRST_CTI2 118
#define SRST_CTI2_APB 119
#define SRST_GPU_BRIDGE 121
#define SRST_CTI3 123
#define SRST_CTI3_APB 124
#endif

View file

@ -0,0 +1,394 @@
/*
* (C) Copyright 2016 Rockchip Electronics Co., Ltd
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RK3328_H
#define _DT_BINDINGS_CLK_ROCKCHIP_RK3328_H
/* core clocks */
#define PLL_APLL 1
#define PLL_DPLL 2
#define PLL_CPLL 3
#define PLL_GPLL 4
#define PLL_NPLL 5
#define ARMCLK 6
/* sclk gates (special clocks) */
#define SCLK_RTC32K 30
#define SCLK_SDMMC_EXT 31
#define SCLK_SPI 32
#define SCLK_SDMMC 33
#define SCLK_SDIO 34
#define SCLK_EMMC 35
#define SCLK_TSADC 36
#define SCLK_SARADC 37
#define SCLK_UART0 38
#define SCLK_UART1 39
#define SCLK_UART2 40
#define SCLK_I2S0 41
#define SCLK_I2S1 42
#define SCLK_I2S2 43
#define SCLK_I2S1_OUT 44
#define SCLK_I2S2_OUT 45
#define SCLK_SPDIF 46
#define SCLK_TIMER0 47
#define SCLK_TIMER1 48
#define SCLK_TIMER2 49
#define SCLK_TIMER3 50
#define SCLK_TIMER4 51
#define SCLK_TIMER5 52
#define SCLK_WIFI 53
#define SCLK_CIF_OUT 54
#define SCLK_I2C0 55
#define SCLK_I2C1 56
#define SCLK_I2C2 57
#define SCLK_I2C3 58
#define SCLK_CRYPTO 59
#define SCLK_PWM 60
#define SCLK_PDM 61
#define SCLK_EFUSE 62
#define SCLK_OTP 63
#define SCLK_DDRCLK 64
#define SCLK_VDEC_CABAC 65
#define SCLK_VDEC_CORE 66
#define SCLK_VENC_DSP 67
#define SCLK_VENC_CORE 68
#define SCLK_RGA 69
#define SCLK_HDMI_SFC 70
#define SCLK_HDMI_CEC 71
#define SCLK_USB3_REF 72
#define SCLK_USB3_SUSPEND 73
#define SCLK_SDMMC_DRV 74
#define SCLK_SDIO_DRV 75
#define SCLK_EMMC_DRV 76
#define SCLK_SDMMC_EXT_DRV 77
#define SCLK_SDMMC_SAMPLE 78
#define SCLK_SDIO_SAMPLE 79
#define SCLK_EMMC_SAMPLE 80
#define SCLK_SDMMC_EXT_SAMPLE 81
#define SCLK_VOP 82
#define SCLK_MAC2PHY_RXTX 83
#define SCLK_MAC2PHY_SRC 84
#define SCLK_MAC2PHY_REF 85
#define SCLK_MAC2PHY_OUT 86
#define SCLK_MAC2IO_RX 87
#define SCLK_MAC2IO_TX 88
#define SCLK_MAC2IO_REFOUT 89
#define SCLK_MAC2IO_REF 90
#define SCLK_MAC2IO_OUT 91
#define SCLK_TSP 92
#define SCLK_HSADC_TSP 93
#define SCLK_USB3PHY_REF 94
#define SCLK_REF_USB3OTG 95
#define SCLK_USB3OTG_REF 96
#define SCLK_USB3OTG_SUSPEND 97
#define SCLK_REF_USB3OTG_SRC 98
#define SCLK_MAC2IO_SRC 99
/* dclk gates */
#define DCLK_LCDC 180
#define DCLK_HDMIPHY 181
#define HDMIPHY 182
#define USB480M 183
#define DCLK_LCDC_SRC 184
/* aclk gates */
#define ACLK_AXISRAM 190
#define ACLK_VOP_PRE 191
#define ACLK_USB3OTG 192
#define ACLK_RGA_PRE 193
#define ACLK_DMAC 194
#define ACLK_GPU 195
#define ACLK_BUS_PRE 196
#define ACLK_PERI_PRE 197
#define ACLK_RKVDEC_PRE 198
#define ACLK_RKVDEC 199
#define ACLK_RKVENC 200
#define ACLK_VPU_PRE 201
#define ACLK_VIO_PRE 202
#define ACLK_VPU 203
#define ACLK_VIO 204
#define ACLK_VOP 205
#define ACLK_GMAC 206
#define ACLK_H265 207
#define ACLK_H264 208
#define ACLK_MAC2PHY 209
#define ACLK_MAC2IO 210
#define ACLK_DCF 211
#define ACLK_TSP 212
#define ACLK_PERI 213
#define ACLK_RGA 214
#define ACLK_IEP 215
#define ACLK_CIF 216
#define ACLK_HDCP 217
/* pclk gates */
#define PCLK_GPIO0 300
#define PCLK_GPIO1 301
#define PCLK_GPIO2 302
#define PCLK_GPIO3 303
#define PCLK_GRF 304
#define PCLK_I2C0 305
#define PCLK_I2C1 306
#define PCLK_I2C2 307
#define PCLK_I2C3 308
#define PCLK_SPI 309
#define PCLK_UART0 310
#define PCLK_UART1 311
#define PCLK_UART2 312
#define PCLK_TSADC 313
#define PCLK_PWM 314
#define PCLK_TIMER 315
#define PCLK_BUS_PRE 316
#define PCLK_PERI_PRE 317
#define PCLK_HDMI_CTRL 318
#define PCLK_HDMI_PHY 319
#define PCLK_GMAC 320
#define PCLK_H265 321
#define PCLK_MAC2PHY 322
#define PCLK_MAC2IO 323
#define PCLK_USB3PHY_OTG 324
#define PCLK_USB3PHY_PIPE 325
#define PCLK_USB3_GRF 326
#define PCLK_USB2_GRF 327
#define PCLK_HDMIPHY 328
#define PCLK_DDR 329
#define PCLK_PERI 330
#define PCLK_HDMI 331
#define PCLK_HDCP 332
#define PCLK_DCF 333
#define PCLK_SARADC 334
/* hclk gates */
#define HCLK_PERI 408
#define HCLK_TSP 409
#define HCLK_GMAC 410
#define HCLK_I2S0_8CH 411
#define HCLK_I2S1_8CH 413
#define HCLK_I2S2_2CH 413
#define HCLK_SPDIF_8CH 414
#define HCLK_VOP 415
#define HCLK_NANDC 416
#define HCLK_SDMMC 417
#define HCLK_SDIO 418
#define HCLK_EMMC 419
#define HCLK_SDMMC_EXT 420
#define HCLK_RKVDEC_PRE 421
#define HCLK_RKVDEC 422
#define HCLK_RKVENC 423
#define HCLK_VPU_PRE 424
#define HCLK_VIO_PRE 425
#define HCLK_VPU 426
#define HCLK_VIO 427
#define HCLK_BUS_PRE 428
#define HCLK_PERI_PRE 429
#define HCLK_H264 430
#define HCLK_CIF 431
#define HCLK_OTG_PMU 432
#define HCLK_OTG 433
#define HCLK_HOST0 434
#define HCLK_HOST0_ARB 435
#define HCLK_CRYPTO_MST 436
#define HCLK_CRYPTO_SLV 437
#define HCLK_PDM 438
#define HCLK_IEP 439
#define HCLK_RGA 440
#define HCLK_HDCP 441
#define CLK_NR_CLKS (HCLK_HDCP + 1)
#define SCLK_MAC2IO 0
#define SCLK_MAC2PHY 1
#define CLKGRF_NR_CLKS (SCLK_MAC2PHY + 1)
/* soft-reset indices */
#define SRST_CORE0_PO 0
#define SRST_CORE1_PO 1
#define SRST_CORE2_PO 2
#define SRST_CORE3_PO 3
#define SRST_CORE0 4
#define SRST_CORE1 5
#define SRST_CORE2 6
#define SRST_CORE3 7
#define SRST_CORE0_DBG 8
#define SRST_CORE1_DBG 9
#define SRST_CORE2_DBG 10
#define SRST_CORE3_DBG 11
#define SRST_TOPDBG 12
#define SRST_CORE_NIU 13
#define SRST_STRC_A 14
#define SRST_L2C 15
#define SRST_A53_GIC 18
#define SRST_DAP 19
#define SRST_PMU_P 21
#define SRST_EFUSE 22
#define SRST_BUSSYS_H 23
#define SRST_BUSSYS_P 24
#define SRST_SPDIF 25
#define SRST_INTMEM 26
#define SRST_ROM 27
#define SRST_GPIO0 28
#define SRST_GPIO1 29
#define SRST_GPIO2 30
#define SRST_GPIO3 31
#define SRST_I2S0 32
#define SRST_I2S1 33
#define SRST_I2S2 34
#define SRST_I2S0_H 35
#define SRST_I2S1_H 36
#define SRST_I2S2_H 37
#define SRST_UART0 38
#define SRST_UART1 39
#define SRST_UART2 40
#define SRST_UART0_P 41
#define SRST_UART1_P 42
#define SRST_UART2_P 43
#define SRST_I2C0 44
#define SRST_I2C1 45
#define SRST_I2C2 46
#define SRST_I2C3 47
#define SRST_I2C0_P 48
#define SRST_I2C1_P 49
#define SRST_I2C2_P 50
#define SRST_I2C3_P 51
#define SRST_EFUSE_SE_P 52
#define SRST_EFUSE_NS_P 53
#define SRST_PWM0 54
#define SRST_PWM0_P 55
#define SRST_DMA 56
#define SRST_TSP_A 57
#define SRST_TSP_H 58
#define SRST_TSP 59
#define SRST_TSP_HSADC 60
#define SRST_DCF_A 61
#define SRST_DCF_P 62
#define SRST_SCR 64
#define SRST_SPI 65
#define SRST_TSADC 66
#define SRST_TSADC_P 67
#define SRST_CRYPTO 68
#define SRST_SGRF 69
#define SRST_GRF 70
#define SRST_USB_GRF 71
#define SRST_TIMER_6CH_P 72
#define SRST_TIMER0 73
#define SRST_TIMER1 74
#define SRST_TIMER2 75
#define SRST_TIMER3 76
#define SRST_TIMER4 77
#define SRST_TIMER5 78
#define SRST_USB3GRF 79
#define SRST_PHYNIU 80
#define SRST_HDMIPHY 81
#define SRST_VDAC 82
#define SRST_ACODEC_p 83
#define SRST_SARADC 85
#define SRST_SARADC_P 86
#define SRST_GRF_DDR 87
#define SRST_DFIMON 88
#define SRST_MSCH 89
#define SRST_DDRMSCH 91
#define SRST_DDRCTRL 92
#define SRST_DDRCTRL_P 93
#define SRST_DDRPHY 94
#define SRST_DDRPHY_P 95
#define SRST_GMAC_NIU_A 96
#define SRST_GMAC_NIU_P 97
#define SRST_GMAC2PHY_A 98
#define SRST_GMAC2IO_A 99
#define SRST_MACPHY 100
#define SRST_OTP_PHY 101
#define SRST_GPU_A 102
#define SRST_GPU_NIU_A 103
#define SRST_SDMMCEXT 104
#define SRST_PERIPH_NIU_A 105
#define SRST_PERIHP_NIU_H 106
#define SRST_PERIHP_P 107
#define SRST_PERIPHSYS_H 108
#define SRST_MMC0 109
#define SRST_SDIO 110
#define SRST_EMMC 111
#define SRST_USB2OTG_H 112
#define SRST_USB2OTG 113
#define SRST_USB2OTG_ADP 114
#define SRST_USB2HOST_H 115
#define SRST_USB2HOST_ARB 116
#define SRST_USB2HOST_AUX 117
#define SRST_USB2HOST_EHCIPHY 118
#define SRST_USB2HOST_UTMI 119
#define SRST_USB3OTG 120
#define SRST_USBPOR 121
#define SRST_USB2OTG_UTMI 122
#define SRST_USB2HOST_PHY_UTMI 123
#define SRST_USB3OTG_UTMI 124
#define SRST_USB3PHY_U2 125
#define SRST_USB3PHY_U3 126
#define SRST_USB3PHY_PIPE 127
#define SRST_VIO_A 128
#define SRST_VIO_BUS_H 129
#define SRST_VIO_H2P_H 130
#define SRST_VIO_ARBI_H 131
#define SRST_VOP_NIU_A 132
#define SRST_VOP_A 133
#define SRST_VOP_H 134
#define SRST_VOP_D 135
#define SRST_RGA 136
#define SRST_RGA_NIU_A 137
#define SRST_RGA_A 138
#define SRST_RGA_H 139
#define SRST_IEP_A 140
#define SRST_IEP_H 141
#define SRST_HDMI 142
#define SRST_HDMI_P 143
#define SRST_HDCP_A 144
#define SRST_HDCP 145
#define SRST_HDCP_H 146
#define SRST_CIF_A 147
#define SRST_CIF_H 148
#define SRST_CIF_P 149
#define SRST_OTP_P 150
#define SRST_OTP_SBPI 151
#define SRST_OTP_USER 152
#define SRST_DDRCTRL_A 153
#define SRST_DDRSTDY_P 154
#define SRST_DDRSTDY 155
#define SRST_PDM_H 156
#define SRST_PDM 157
#define SRST_USB3PHY_OTG_P 158
#define SRST_USB3PHY_PIPE_P 159
#define SRST_VCODEC_A 160
#define SRST_VCODEC_NIU_A 161
#define SRST_VCODEC_H 162
#define SRST_VCODEC_NIU_H 163
#define SRST_VDEC_A 164
#define SRST_VDEC_NIU_A 165
#define SRST_VDEC_H 166
#define SRST_VDEC_NIU_H 167
#define SRST_VDEC_CORE 168
#define SRST_VDEC_CABAC 169
#define SRST_DDRPHYDIV 175
#define SRST_RKVENC_NIU_A 176
#define SRST_RKVENC_NIU_H 177
#define SRST_RKVENC_H265_A 178
#define SRST_RKVENC_H265_P 179
#define SRST_RKVENC_H265_CORE 180
#define SRST_RKVENC_H265_DSP 181
#define SRST_RKVENC_H264_A 182
#define SRST_RKVENC_H264_H 183
#define SRST_RKVENC_INTMEM 184
#endif

View file

@ -122,6 +122,10 @@
#define SCLK_DPHY_RX0_CFG 165
#define SCLK_RMII_SRC 166
#define SCLK_PCIEPHY_REF100M 167
#define SCLK_USBPHY0_480M_SRC 168
#define SCLK_USBPHY1_480M_SRC 169
#define SCLK_DDRCLK 170
#define SCLK_TESTOUT2 171
#define DCLK_VOP0 180
#define DCLK_VOP1 181
@ -589,13 +593,13 @@
#define SRST_P_SPI0 214
#define SRST_P_SPI1 215
#define SRST_P_SPI2 216
#define SRST_P_SPI3 217
#define SRST_P_SPI4 218
#define SRST_P_SPI4 217
#define SRST_P_SPI5 218
#define SRST_SPI0 219
#define SRST_SPI1 220
#define SRST_SPI2 221
#define SRST_SPI3 222
#define SRST_SPI4 223
#define SRST_SPI4 222
#define SRST_SPI5 223
/* cru_softrst_con14 */
#define SRST_I2S0_8CH 224
@ -717,8 +721,8 @@
#define SRST_H_CM0S_NOC 3
#define SRST_DBG_CM0S 4
#define SRST_PO_CM0S 5
#define SRST_P_SPI6 6
#define SRST_SPI6 7
#define SRST_P_SPI3 6
#define SRST_SPI3 7
#define SRST_P_TIMER_0_1 8
#define SRST_P_TIMER_0 9
#define SRST_P_TIMER_1 10

View file

@ -22,5 +22,7 @@
#define RK_FUNC_2 2
#define RK_FUNC_3 3
#define RK_FUNC_4 4
#define RK_FUNC_5 5
#define RK_FUNC_6 6
#endif

View file

@ -213,11 +213,29 @@ int spl_load_image_ext_os(struct spl_image_info *spl_image,
struct blk_desc *block_dev, int partition);
/**
* spl_init() - Set up device tree and driver model in SPL if enabled
* spl_early_init() - Set up device tree and driver model in SPL if enabled
*
* Call this function in board_init_f() if you want to use device tree and
* driver model early, before board_init_r() is called. This function will
* be called from board_init_r() if not called earlier.
* driver model early, before board_init_r() is called.
*
* If this is not called, then driver model will be inactive in SPL's
* board_init_f(), and no device tree will be available.
*/
int spl_early_init(void);
/**
* spl_init() - Set up device tree and driver model in SPL if enabled
*
* You can optionally call spl_early_init(), then optionally call spl_init().
* This function will be called from board_init_r() if not called earlier.
*
* Both spl_early_init() and spl_init() perform a similar function except that
* the latter will not set up the malloc() area if
* CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN is enabled, since it is assumed to
* already be done by a calll to spl_relocate_stack_gd() before board_init_r()
* is reached.
*
* This function will be called from board_init_r() if not called earlier.
*
* If this is not called, then driver model will be inactive in SPL's
* board_init_f(), and no device tree will be available.

View file

@ -215,8 +215,13 @@ $(obj)/$(SPL_BIN)-pad.bin: $(obj)/$(SPL_BIN)
# 'u-boot,dm-pre-reloc' property and thus are not needed by SPL. The second
# pass removes various unused properties from the remaining nodes.
# The output is typically a much smaller device tree file.
ifeq ($(CONFIG_TPL_BUILD),y)
fdtgrep_props := -b u-boot,dm-pre-reloc -b u-boot,dm-tpl
else
fdtgrep_props := -b u-boot,dm-pre-reloc -b u-boot,dm-spl
endif
quiet_cmd_fdtgrep = FDTGREP $@
cmd_fdtgrep = $(objtree)/tools/fdtgrep -b u-boot,dm-pre-reloc -RT $< \
cmd_fdtgrep = $(objtree)/tools/fdtgrep $(fdtgrep_props) -RT $< \
-n /chosen -O dtb | \
$(objtree)/tools/fdtgrep -r -O dtb - -o $@ \
$(addprefix -P ,$(subst $\",,$(CONFIG_OF_SPL_REMOVE_PROPS)))

Some files were not shown because too many files have changed in this diff Show more