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

master
Tom Rini 7 years ago
commit 16d4ff76c5
  1. 3
      arch/arm/Kconfig
  2. 1
      arch/arm/dts/rk3229-evb.dts
  3. 4
      arch/arm/dts/rk3288-popmetal.dtsi
  4. 122
      arch/arm/dts/rk3328-evb.dts
  5. 4
      arch/arm/dts/rk3368-px5-evb.dts
  6. 4
      arch/arm/dts/rk3368-sheep.dts
  7. 4
      arch/arm/dts/rk3399-evb.dts
  8. 33
      arch/arm/dts/rk3399-puma.dtsi
  9. 4
      arch/arm/dts/rv1108-evb.dts
  10. 11
      arch/arm/dts/rv1108.dtsi
  11. 18
      arch/arm/include/asm/arch-rockchip/bootrom.h
  12. 5
      arch/arm/include/asm/arch-rockchip/cru_rk3368.h
  13. 5
      arch/arm/include/asm/arch-rockchip/cru_rv1108.h
  14. 4
      arch/arm/include/asm/arch-rockchip/grf_rk3036.h
  15. 581
      arch/arm/include/asm/arch-rockchip/sdram_rk322x.h
  16. 23
      arch/arm/include/asm/arch-rockchip/sys_proto.h
  17. 21
      arch/arm/include/asm/armv7.h
  18. 1
      arch/arm/mach-rockchip/Makefile
  19. 1
      arch/arm/mach-rockchip/rk3188/Makefile
  20. 4
      arch/arm/mach-rockchip/rk322x-board.c
  21. 61
      arch/arm/mach-rockchip/rk3288-board-spl.c
  22. 84
      arch/arm/mach-rockchip/rk3288-board-tpl.c
  23. 16
      arch/arm/mach-rockchip/rk3288/Kconfig
  24. 1
      arch/arm/mach-rockchip/rk3288/Makefile
  25. 1
      arch/arm/mach-rockchip/rk3328/Makefile
  26. 69
      arch/arm/mach-rockchip/rk3399-board-spl.c
  27. 1
      arch/arm/mach-rockchip/rk3399/Makefile
  28. 48
      arch/arm/mach-rockchip/spl-boot-order.c
  29. 13
      board/amarula/vyasa-rk3288/vyasa-rk3288.c
  30. 30
      board/rockchip/evb_rk3399/evb-rk3399.c
  31. 4
      board/theobroma-systems/lion_rk3368/fit_spl_atf.its
  32. 56
      board/theobroma-systems/puma_rk3399/puma-rk3399.c
  33. 6
      configs/evb-rk3328_defconfig
  34. 1
      configs/lion-rk3368_defconfig
  35. 7
      configs/puma-rk3399_defconfig
  36. 3
      configs/vyasa-rk3288_defconfig
  37. 18
      doc/README.rockchip
  38. 12
      doc/device-tree-bindings/chosen.txt
  39. 9
      drivers/adc/Kconfig
  40. 1
      drivers/adc/Makefile
  41. 183
      drivers/adc/rockchip-saradc.c
  42. 8
      drivers/clk/rockchip/clk_rk322x.c
  43. 41
      drivers/clk/rockchip/clk_rk3288.c
  44. 35
      drivers/clk/rockchip/clk_rk3328.c
  45. 32
      drivers/clk/rockchip/clk_rk3368.c
  46. 36
      drivers/clk/rockchip/clk_rk3399.c
  47. 33
      drivers/clk/rockchip/clk_rv1108.c
  48. 1
      drivers/i2c/rk_i2c.c
  49. 39
      drivers/pinctrl/rockchip/pinctrl_rk3368.c
  50. 7
      drivers/power/regulator/Kconfig
  51. 5
      drivers/ram/rockchip/Makefile
  52. 11
      drivers/ram/rockchip/sdram_rk3188.c
  53. 855
      drivers/ram/rockchip/sdram_rk322x.c
  54. 0
      drivers/ram/rockchip/sdram_rk3288.c
  55. 0
      drivers/ram/rockchip/sdram_rk3328.c
  56. 0
      drivers/ram/rockchip/sdram_rk3399.c
  57. 6
      include/configs/evb_rk3399.h
  58. 6
      include/configs/rk3288_common.h
  59. 17
      include/configs/vyasa-rk3288.h
  60. 2
      include/dt-bindings/clock/rv1108-cru.h
  61. 1
      tools/rkcommon.c

@ -1115,6 +1115,9 @@ config ARCH_ROCKCHIP
imply FAT_WRITE
imply USB_FUNCTION_FASTBOOT
imply SPL_SYSRESET
imply TPL_SYSRESET
imply ADC
imply SARADC_ROCKCHIP
config TARGET_THUNDERX_88XX
bool "Support ThunderX 88xx"

@ -40,7 +40,6 @@
};
&dmc {
rockchip,sdram-channel = /bits/ 8 <1 10 3 2 1 0 15 15>;
rockchip,pctl-timing = <0x96 0xC8 0x1F3 0xF 0x8000004D 0x4 0x4E 0x6 0x3
0x0 0x6 0x5 0xC 0x10 0x6 0x4 0x4
0x5 0x4 0x200 0x3 0xA 0x40 0x0 0x1

@ -491,6 +491,10 @@
};
};
&saradc {
status = "okay";
};
&tsadc {
rockchip,hw-tshut-mode = <0>;
rockchip,hw-tshut-polarity = <0>;

@ -42,6 +42,10 @@
};
};
&saradc {
status = "okay";
};
&uart2 {
status = "okay";
};
@ -87,3 +91,121 @@
vbus-supply = <&vcc5v0_host_xhci>;
status = "okay";
};
&i2c1 {
clock-frequency = <400000>;
i2c-scl-rising-time-ns = <168>;
i2c-scl-falling-time-ns = <4>;
status = "okay";
rk805: pmic@18 {
compatible = "rockchip,rk805";
status = "okay";
reg = <0x18>;
interrupt-parent = <&gpio2>;
interrupts = <6 IRQ_TYPE_LEVEL_LOW>;
pinctrl-names = "default";
pinctrl-0 = <&pmic_int_l>;
rockchip,system-power-controller;
wakeup-source;
gpio-controller;
#gpio-cells = <2>;
#clock-cells = <1>;
clock-output-names = "xin32k", "rk805-clkout2";
regulators {
vdd_logic: DCDC_REG1 {
regulator-name = "vdd_logic";
regulator-min-microvolt = <712500>;
regulator-max-microvolt = <1450000>;
regulator-ramp-delay = <6001>;
regulator-boot-on;
regulator-always-on;
regulator-state-mem {
regulator-on-in-suspend;
regulator-suspend-microvolt = <1000000>;
};
};
vdd_arm: DCDC_REG2 {
regulator-name = "vdd_arm";
regulator-min-microvolt = <712500>;
regulator-max-microvolt = <1450000>;
regulator-ramp-delay = <6001>;
regulator-boot-on;
regulator-always-on;
regulator-state-mem {
regulator-on-in-suspend;
regulator-suspend-microvolt = <1000000>;
};
};
vcc_ddr: DCDC_REG3 {
regulator-name = "vcc_ddr";
regulator-boot-on;
regulator-always-on;
regulator-state-mem {
regulator-on-in-suspend;
};
};
vcc_io: DCDC_REG4 {
regulator-name = "vcc_io";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-boot-on;
regulator-always-on;
regulator-state-mem {
regulator-on-in-suspend;
regulator-suspend-microvolt = <3300000>;
};
};
vdd_18: LDO_REG1 {
regulator-name = "vdd_18";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-boot-on;
regulator-always-on;
regulator-state-mem {
regulator-on-in-suspend;
regulator-suspend-microvolt = <1800000>;
};
};
vcc_18emmc: LDO_REG2 {
regulator-name = "vcc_18emmc";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-boot-on;
regulator-always-on;
regulator-state-mem {
regulator-on-in-suspend;
regulator-suspend-microvolt = <1800000>;
};
};
vdd_10: LDO_REG3 {
regulator-name = "vdd_10";
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1000000>;
regulator-boot-on;
regulator-always-on;
regulator-state-mem {
regulator-on-in-suspend;
regulator-suspend-microvolt = <1000000>;
};
};
};
};
};
&pinctrl {
pmic {
pmic_int_l: pmic-int-l {
rockchip,pins =
<2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>; /* gpio2_a6 */
};
};
};

@ -296,6 +296,10 @@
};
};
&saradc {
status = "okay";
};
&tsadc {
status = "okay";
rockchip,hw-tshut-mode = <0>; /* CRU */

@ -260,6 +260,10 @@
};
};
&saradc {
status = "okay";
};
&tsadc {
status = "okay";
rockchip,hw-tshut-mode = <0>; /* CRU */

@ -149,6 +149,10 @@
status = "okay";
};
&saradc {
status = "okay";
};
&sdmmc {
bus-width = <4>;
status = "okay";

@ -20,7 +20,8 @@
chosen {
stdout-path = "serial0:115200n8";
u-boot,spl-boot-order = &spiflash, &sdhci, &sdmmc;
u-boot,spl-boot-order = \
"same-as-spl", &spiflash, &sdhci, &sdmmc;
};
aliases {
@ -100,6 +101,24 @@
regulator-max-microvolt = <3300000>;
};
/*
* The Qseven BIOS_DISABLE signal on the RK3399-Q7 keeps the on-module
* eMMC and SPI flash powered-down initially (in fact it keeps the
* reset signal asserted). Even though it is an enable signal, we
* model this as a regulator.
*/
bios_enable: bios_enable {
compatible = "regulator-fixed";
u-boot,dm-pre-reloc;
regulator-name = "bios_enable";
enable-active-low;
gpio = <&gpio3 29 GPIO_ACTIVE_HIGH>;
regulator-always-on;
regulator-boot-on;
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
};
vccadc_ref: vccadc-ref {
compatible = "regulator-fixed";
regulator-name = "vcc1v8_sys";
@ -458,7 +477,7 @@
};
&pcie_phy {
status = "okay";
status = "okay";
};
&pmu_io_domains {
@ -485,7 +504,7 @@
};
&sdmmc {
u-boot,dm-pre-reloc;
u-boot,dm-pre-reloc;
clock-frequency = <150000000>;
clock-freq-min-max = <100000 150000000>;
supports-sd;
@ -532,10 +551,15 @@
status = "okay";
};
&gpio3 {
u-boot,dm-pre-reloc;
};
&pinctrl {
/* Pins that are not explicitely used by any devices */
pinctrl-names = "default";
pinctrl-0 = <&puma_pin_hog>;
hog {
puma_pin_hog: puma_pin_hog {
rockchip,pins =
@ -575,7 +599,7 @@
i2c8 {
i2c8_xfer_a: i2c8-xfer {
rockchip,pins = <1 21 RK_FUNC_1 &pcfg_pull_up>,
<1 20 RK_FUNC_1 &pcfg_pull_up>;
<1 20 RK_FUNC_1 &pcfg_pull_up>;
};
};
};
@ -651,4 +675,3 @@
&spi5 {
status = "okay";
};

@ -39,6 +39,10 @@
snps,reset-gpio = <&gpio1 RK_PC1 GPIO_ACTIVE_LOW>;
};
&saradc {
status = "okay";
};
&sfc {
status = "okay";
flash@0 {

@ -126,6 +126,17 @@
reg = <0x10300000 0x1000>;
};
saradc: saradc@1038c000 {
compatible = "rockchip,rv1108-saradc", "rockchip,rk3399-saradc";
reg = <0x1038c000 0x100>;
interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
#io-channel-cells = <1>;
clock-frequency = <1000000>;
clocks = <&cru SCLK_SARADC>, <&cru PCLK_SARADC>;
clock-names = "saradc", "apb_pclk";
status = "disabled";
};
pmugrf: syscon@20060000 {
compatible = "rockchip,rv1108-pmugrf", "syscon";
reg = <0x20060000 0x1000>;

@ -24,4 +24,22 @@ void back_to_bootrom(void);
*/
void _back_to_bootrom_s(void);
/**
* Boot-device identifiers as used by the BROM
*/
enum {
BROM_BOOTSOURCE_NAND = 1,
BROM_BOOTSOURCE_EMMC = 2,
BROM_BOOTSOURCE_SPINOR = 3,
BROM_BOOTSOURCE_SPINAND = 4,
BROM_BOOTSOURCE_SD = 5,
BROM_BOOTSOURCE_USB = 10,
BROM_LAST_BOOTSOURCE = BROM_BOOTSOURCE_USB
};
/**
* Locations of the boot-device identifier in SRAM
*/
#define RK3399_BROM_BOOTSOURCE_ID_ADDR 0xff8c0010
#endif

@ -89,6 +89,11 @@ enum {
MCU_CLK_DIV_SHIFT = 0,
MCU_CLK_DIV_MASK = GENMASK(4, 0),
/* CLKSEL_CON25 */
CLK_SARADC_DIV_CON_SHIFT = 8,
CLK_SARADC_DIV_CON_MASK = GENMASK(15, 8),
CLK_SARADC_DIV_CON_WIDTH = 8,
/* CLKSEL43_CON */
GMAC_MUX_SEL_EXTCLK = BIT(8),

@ -90,6 +90,11 @@ enum {
CORE_CLK_DIV_SHIFT = 0,
CORE_CLK_DIV_MASK = 0x1f << CORE_CLK_DIV_SHIFT,
/* CLKSEL_CON22 */
CLK_SARADC_DIV_CON_SHIFT= 0,
CLK_SARADC_DIV_CON_MASK = GENMASK(9, 0),
CLK_SARADC_DIV_CON_WIDTH= 10,
/* CLKSEL24_CON */
MAC_PLL_SEL_SHIFT = 12,
MAC_PLL_SEL_MASK = 1 << MAC_PLL_SEL_SHIFT,

@ -209,10 +209,10 @@ enum {
GPIO1A3_I2S_LRCKTX,
GPIO1A2_SHIFT = 4,
GPIO1A2_MASK = 6 << GPIO1A2_SHIFT,
GPIO1A2_MASK = 3 << GPIO1A2_SHIFT,
GPIO1A2_GPIO = 0,
GPIO1A2_I2S_LRCKRX,
GPIO1A2_I2S_PWM1_0,
GPIO1A2_PWM1_0,
GPIO1A1_SHIFT = 2,
GPIO1A1_MASK = 1 << GPIO1A1_SHIFT,

@ -0,0 +1,581 @@
/*
* (C) Copyright 2017 Rockchip Electronics Co., Ltd
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _ASM_ARCH_SDRAM_RK322X_H
#define _ASM_ARCH_SDRAM_RK322X_H
#include <common.h>
enum {
DDR3 = 3,
LPDDR2 = 5,
LPDDR3 = 6,
UNUSED = 0xFF,
};
struct rk322x_sdram_channel {
/*
* bit width in address, eg:
* 8 banks using 3 bit to address,
* 2 cs using 1 bit to address.
*/
u8 rank;
u8 col;
u8 bk;
u8 bw;
u8 dbw;
u8 row_3_4;
u8 cs0_row;
u8 cs1_row;
#if CONFIG_IS_ENABLED(OF_PLATDATA)
/*
* For of-platdata, which would otherwise convert this into two
* byte-swapped integers. With a size of 9 bytes, this struct will
* appear in of-platdata as a byte array.
*
* If OF_PLATDATA enabled, need to add a dummy byte in dts.(i.e 0xff)
*/
u8 dummy;
#endif
};
struct rk322x_ddr_pctl {
u32 scfg;
u32 sctl;
u32 stat;
u32 intrstat;
u32 reserved0[(0x40 - 0x10) / 4];
u32 mcmd;
u32 powctl;
u32 powstat;
u32 cmdtstat;
u32 cmdtstaten;
u32 reserved1[(0x60 - 0x54) / 4];
u32 mrrcfg0;
u32 mrrstat0;
u32 mrrstat1;
u32 reserved2[(0x7c - 0x6c) / 4];
u32 mcfg1;
u32 mcfg;
u32 ppcfg;
u32 mstat;
u32 lpddr2zqcfg;
u32 reserved3;
u32 dtupdes;
u32 dtuna;
u32 dtune;
u32 dtuprd0;
u32 dtuprd1;
u32 dtuprd2;
u32 dtuprd3;
u32 dtuawdt;
u32 reserved4[(0xc0 - 0xb4) / 4];
u32 togcnt1u;
u32 tinit;
u32 trsth;
u32 togcnt100n;
u32 trefi;
u32 tmrd;
u32 trfc;
u32 trp;
u32 trtw;
u32 tal;
u32 tcl;
u32 tcwl;
u32 tras;
u32 trc;
u32 trcd;
u32 trrd;
u32 trtp;
u32 twr;
u32 twtr;
u32 texsr;
u32 txp;
u32 txpdll;
u32 tzqcs;
u32 tzqcsi;
u32 tdqs;
u32 tcksre;
u32 tcksrx;
u32 tcke;
u32 tmod;
u32 trstl;
u32 tzqcl;
u32 tmrr;
u32 tckesr;
u32 tdpd;
u32 tref_mem_ddr3;
u32 reserved5[(0x180 - 0x14c) / 4];
u32 ecccfg;
u32 ecctst;
u32 eccclr;
u32 ecclog;
u32 reserved6[(0x200 - 0x190) / 4];
u32 dtuwactl;
u32 dturactl;
u32 dtucfg;
u32 dtuectl;
u32 dtuwd0;
u32 dtuwd1;
u32 dtuwd2;
u32 dtuwd3;
u32 dtuwdm;
u32 dturd0;
u32 dturd1;
u32 dturd2;
u32 dturd3;
u32 dtulfsrwd;
u32 dtulfsrrd;
u32 dtueaf;
/* dfi control registers */
u32 dfitctrldelay;
u32 dfiodtcfg;
u32 dfiodtcfg1;
u32 dfiodtrankmap;
/* dfi write data registers */
u32 dfitphywrdata;
u32 dfitphywrlat;
u32 reserved7[(0x260 - 0x258) / 4];
u32 dfitrddataen;
u32 dfitphyrdlat;
u32 reserved8[(0x270 - 0x268) / 4];
u32 dfitphyupdtype0;
u32 dfitphyupdtype1;
u32 dfitphyupdtype2;
u32 dfitphyupdtype3;
u32 dfitctrlupdmin;
u32 dfitctrlupdmax;
u32 dfitctrlupddly;
u32 reserved9;
u32 dfiupdcfg;
u32 dfitrefmski;
u32 dfitctrlupdi;
u32 reserved10[(0x2ac - 0x29c) / 4];
u32 dfitrcfg0;
u32 dfitrstat0;
u32 dfitrwrlvlen;
u32 dfitrrdlvlen;
u32 dfitrrdlvlgateen;
u32 dfiststat0;
u32 dfistcfg0;
u32 dfistcfg1;
u32 reserved11;
u32 dfitdramclken;
u32 dfitdramclkdis;
u32 dfistcfg2;
u32 dfistparclr;
u32 dfistparlog;
u32 reserved12[(0x2f0 - 0x2e4) / 4];
u32 dfilpcfg0;
u32 reserved13[(0x300 - 0x2f4) / 4];
u32 dfitrwrlvlresp0;
u32 dfitrwrlvlresp1;
u32 dfitrwrlvlresp2;
u32 dfitrrdlvlresp0;
u32 dfitrrdlvlresp1;
u32 dfitrrdlvlresp2;
u32 dfitrwrlvldelay0;
u32 dfitrwrlvldelay1;
u32 dfitrwrlvldelay2;
u32 dfitrrdlvldelay0;
u32 dfitrrdlvldelay1;
u32 dfitrrdlvldelay2;
u32 dfitrrdlvlgatedelay0;
u32 dfitrrdlvlgatedelay1;
u32 dfitrrdlvlgatedelay2;
u32 dfitrcmd;
u32 reserved14[(0x3f8 - 0x340) / 4];
u32 ipvr;
u32 iptr;
};
check_member(rk322x_ddr_pctl, iptr, 0x03fc);
struct rk322x_ddr_phy {
u32 ddrphy_reg[0x100];
};
struct rk322x_pctl_timing {
u32 togcnt1u;
u32 tinit;
u32 trsth;
u32 togcnt100n;
u32 trefi;
u32 tmrd;
u32 trfc;
u32 trp;
u32 trtw;
u32 tal;
u32 tcl;
u32 tcwl;
u32 tras;
u32 trc;
u32 trcd;
u32 trrd;
u32 trtp;
u32 twr;
u32 twtr;
u32 texsr;
u32 txp;
u32 txpdll;
u32 tzqcs;
u32 tzqcsi;
u32 tdqs;
u32 tcksre;
u32 tcksrx;
u32 tcke;
u32 tmod;
u32 trstl;
u32 tzqcl;
u32 tmrr;
u32 tckesr;
u32 tdpd;
u32 trefi_mem_ddr3;
};
struct rk322x_phy_timing {
u32 mr[4];
u32 mr11;
u32 bl;
u32 cl_al;
};
struct rk322x_msch_timings {
u32 ddrtiming;
u32 ddrmode;
u32 readlatency;
u32 activate;
u32 devtodev;
};
struct rk322x_service_sys {
u32 id_coreid;
u32 id_revisionid;
u32 ddrconf;
u32 ddrtiming;
u32 ddrmode;
u32 readlatency;
u32 activate;
u32 devtodev;
};
struct rk322x_base_params {
struct rk322x_msch_timings noc_timing;
u32 ddrconfig;
u32 ddr_freq;
u32 dramtype;
/*
* unused for rk322x
*/
u32 stride;
u32 odt;
};
/* PCT_DFISTCFG0 */
#define DFI_INIT_START BIT(0)
#define DFI_DATA_BYTE_DISABLE_EN BIT(2)
/* PCT_DFISTCFG1 */
#define DFI_DRAM_CLK_SR_EN BIT(0)
#define DFI_DRAM_CLK_DPD_EN BIT(1)
/* PCT_DFISTCFG2 */
#define DFI_PARITY_INTR_EN BIT(0)
#define DFI_PARITY_EN BIT(1)
/* PCT_DFILPCFG0 */
#define TLP_RESP_TIME_SHIFT 16
#define LP_SR_EN BIT(8)
#define LP_PD_EN BIT(0)
/* PCT_DFITCTRLDELAY */
#define TCTRL_DELAY_TIME_SHIFT 0
/* PCT_DFITPHYWRDATA */
#define TPHY_WRDATA_TIME_SHIFT 0
/* PCT_DFITPHYRDLAT */
#define TPHY_RDLAT_TIME_SHIFT 0
/* PCT_DFITDRAMCLKDIS */
#define TDRAM_CLK_DIS_TIME_SHIFT 0
/* PCT_DFITDRAMCLKEN */
#define TDRAM_CLK_EN_TIME_SHIFT 0
/* PCTL_DFIODTCFG */
#define RANK0_ODT_WRITE_SEL BIT(3)
#define RANK1_ODT_WRITE_SEL BIT(11)
/* PCTL_DFIODTCFG1 */
#define ODT_LEN_BL8_W_SHIFT 16
/* PUBL_ACDLLCR */
#define ACDLLCR_DLLDIS BIT(31)
#define ACDLLCR_DLLSRST BIT(30)
/* PUBL_DXDLLCR */
#define DXDLLCR_DLLDIS BIT(31)
#define DXDLLCR_DLLSRST BIT(30)
/* PUBL_DLLGCR */
#define DLLGCR_SBIAS BIT(30)
/* PUBL_DXGCR */
#define DQSRTT BIT(9)
#define DQRTT BIT(10)
/* PIR */
#define PIR_INIT BIT(0)
#define PIR_DLLSRST BIT(1)
#define PIR_DLLLOCK BIT(2)
#define PIR_ZCAL BIT(3)
#define PIR_ITMSRST BIT(4)
#define PIR_DRAMRST BIT(5)
#define PIR_DRAMINIT BIT(6)
#define PIR_QSTRN BIT(7)
#define PIR_RVTRN BIT(8)
#define PIR_ICPC BIT(16)
#define PIR_DLLBYP BIT(17)
#define PIR_CTLDINIT BIT(18)
#define PIR_CLRSR BIT(28)
#define PIR_LOCKBYP BIT(29)
#define PIR_ZCALBYP BIT(30)
#define PIR_INITBYP BIT(31)
/* PGCR */
#define PGCR_DFTLMT_SHIFT 3
#define PGCR_DFTCMP_SHIFT 2
#define PGCR_DQSCFG_SHIFT 1
#define PGCR_ITMDMD_SHIFT 0
/* PGSR */
#define PGSR_IDONE BIT(0)
#define PGSR_DLDONE BIT(1)
#define PGSR_ZCDONE BIT(2)
#define PGSR_DIDONE BIT(3)
#define PGSR_DTDONE BIT(4)
#define PGSR_DTERR BIT(5)
#define PGSR_DTIERR BIT(6)
#define PGSR_DFTERR BIT(7)
#define PGSR_RVERR BIT(8)
#define PGSR_RVEIRR BIT(9)
/* PTR0 */
#define PRT_ITMSRST_SHIFT 18
#define PRT_DLLLOCK_SHIFT 6
#define PRT_DLLSRST_SHIFT 0
/* PTR1 */
#define PRT_DINIT0_SHIFT 0
#define PRT_DINIT1_SHIFT 19
/* PTR2 */
#define PRT_DINIT2_SHIFT 0
#define PRT_DINIT3_SHIFT 17
/* DCR */
#define DDRMD_LPDDR 0
#define DDRMD_DDR 1
#define DDRMD_DDR2 2
#define DDRMD_DDR3 3
#define DDRMD_LPDDR2_LPDDR3 4
#define DDRMD_MASK 7
#define DDRMD_SHIFT 0
#define PDQ_MASK 7
#define PDQ_SHIFT 4
/* DXCCR */
#define DQSNRES_MASK 0xf
#define DQSNRES_SHIFT 8
#define DQSRES_MASK 0xf
#define DQSRES_SHIFT 4
/* DTPR */
#define TDQSCKMAX_SHIFT 27
#define TDQSCKMAX_MASK 7
#define TDQSCK_SHIFT 24
#define TDQSCK_MASK 7
/* DSGCR */
#define DQSGX_SHIFT 5
#define DQSGX_MASK 7
#define DQSGE_SHIFT 8
#define DQSGE_MASK 7
/* SCTL */
#define INIT_STATE 0
#define CFG_STATE 1
#define GO_STATE 2
#define SLEEP_STATE 3
#define WAKEUP_STATE 4
/* STAT */
#define LP_TRIG_SHIFT 4
#define LP_TRIG_MASK 7
#define PCTL_STAT_MASK 7
#define INIT_MEM 0
#define CONFIG 1
#define CONFIG_REQ 2
#define ACCESS 3
#define ACCESS_REQ 4
#define LOW_POWER 5
#define LOW_POWER_ENTRY_REQ 6
#define LOW_POWER_EXIT_REQ 7
/* ZQCR*/
#define PD_OUTPUT_SHIFT 0
#define PU_OUTPUT_SHIFT 5
#define PD_ONDIE_SHIFT 10
#define PU_ONDIE_SHIFT 15
#define ZDEN_SHIFT 28
/* DDLGCR */
#define SBIAS_BYPASS BIT(23)
/* MCFG */
#define MDDR_LPDDR2_CLK_STOP_IDLE_SHIFT 24
#define PD_IDLE_SHIFT 8
#define MDDR_EN (2 << 22)
#define LPDDR2_EN (3 << 22)
#define LPDDR3_EN (1 << 22)
#define DDR2_EN (0 << 5)
#define DDR3_EN (1 << 5)
#define LPDDR2_S2 (0 << 6)
#define LPDDR2_S4 (1 << 6)
#define MDDR_LPDDR2_BL_2 (0 << 20)
#define MDDR_LPDDR2_BL_4 (1 << 20)
#define MDDR_LPDDR2_BL_8 (2 << 20)
#define MDDR_LPDDR2_BL_16 (3 << 20)
#define DDR2_DDR3_BL_4 0
#define DDR2_DDR3_BL_8 1
#define TFAW_SHIFT 18
#define PD_EXIT_SLOW (0 << 17)
#define PD_EXIT_FAST (1 << 17)
#define PD_TYPE_SHIFT 16
#define BURSTLENGTH_SHIFT 20
/* POWCTL */
#define POWER_UP_START BIT(0)
/* POWSTAT */
#define POWER_UP_DONE BIT(0)
/* MCMD */
enum {
DESELECT_CMD = 0,
PREA_CMD,
REF_CMD,
MRS_CMD,
ZQCS_CMD,
ZQCL_CMD,
RSTL_CMD,
MRR_CMD = 8,
DPDE_CMD,
};
#define BANK_ADDR_MASK 7
#define BANK_ADDR_SHIFT 17
#define CMD_ADDR_MASK 0x1fff
#define CMD_ADDR_SHIFT 4
#define LPDDR23_MA_SHIFT 4
#define LPDDR23_MA_MASK 0xff
#define LPDDR23_OP_SHIFT 12
#define LPDDR23_OP_MASK 0xff
#define START_CMD (1u << 31)
/* DDRPHY REG */
enum {
/* DDRPHY_REG0 */
SOFT_RESET_MASK = 3,
SOFT_DERESET_ANALOG = 1 << 2,
SOFT_DERESET_DIGITAL = 1 << 3,
SOFT_RESET_SHIFT = 2,
/* DDRPHY REG1 */
PHY_DDR3 = 0,
PHY_DDR2 = 1,
PHY_LPDDR3 = 2,
PHY_LPDDR2 = 3,
PHT_BL_8 = 1 << 2,
PHY_BL_4 = 0 << 2,
/* DDRPHY_REG2 */
MEMORY_SELECT_DDR3 = 0 << 0,
MEMORY_SELECT_LPDDR3 = 2 << 0,
MEMORY_SELECT_LPDDR2 = 3 << 0,
DQS_SQU_CAL_SEL_CS0_CS1 = 0 << 4,
DQS_SQU_CAL_SEL_CS1 = 1 << 4,
DQS_SQU_CAL_SEL_CS0 = 2 << 4,
DQS_SQU_CAL_NORMAL_MODE = 0 << 1,
DQS_SQU_CAL_BYPASS_MODE = 1 << 1,
DQS_SQU_CAL_START = 1 << 0,
DQS_SQU_NO_CAL = 0 << 0,
};
/* CK pull up/down driver strength control */
enum {
PHY_RON_RTT_DISABLE = 0,
PHY_RON_RTT_451OHM = 1,
PHY_RON_RTT_225OHM,
PHY_RON_RTT_150OHM,
PHY_RON_RTT_112OHM,
PHY_RON_RTT_90OHM,
PHY_RON_RTT_75OHM,
PHY_RON_RTT_64OHM = 7,
PHY_RON_RTT_56OHM = 16,
PHY_RON_RTT_50OHM,
PHY_RON_RTT_45OHM,
PHY_RON_RTT_41OHM,
PHY_RON_RTT_37OHM,
PHY_RON_RTT_34OHM,
PHY_RON_RTT_33OHM,
PHY_RON_RTT_30OHM = 23,
PHY_RON_RTT_28OHM = 24,
PHY_RON_RTT_26OHM,
PHY_RON_RTT_25OHM,
PHY_RON_RTT_23OHM,
PHY_RON_RTT_22OHM,
PHY_RON_RTT_21OHM,
PHY_RON_RTT_20OHM,
PHY_RON_RTT_19OHM = 31,
};
/* DQS squelch DLL delay */
enum {
DQS_DLL_NO_DELAY = 0,
DQS_DLL_22P5_DELAY,
DQS_DLL_45_DELAY,
DQS_DLL_67P5_DELAY,
DQS_DLL_90_DELAY,
DQS_DLL_112P5_DELAY,
DQS_DLL_135_DELAY,
DQS_DLL_157P5_DELAY,
};
/* GRF_SOC_CON0 */
#define GRF_DDR_16BIT_EN (((0x1 << 0) << 16) | (0x1 << 0))
#define GRF_DDR_32BIT_EN (((0x1 << 0) << 16) | (0x0 << 0))
#define GRF_MSCH_NOC_16BIT_EN (((0x1 << 7) << 16) | (0x1 << 7))
#define GRF_MSCH_NOC_32BIT_EN (((0x1 << 7) << 16) | (0x0 << 7))
#define GRF_DDRPHY_BUFFEREN_CORE_EN (((0x1 << 8) << 16) | (0x0 << 8))
#define GRF_DDRPHY_BUFFEREN_CORE_DIS (((0x1 << 8) << 16) | (0x1 << 8))
#define GRF_DDR3_EN (((0x1 << 6) << 16) | (0x1 << 6))
#define GRF_LPDDR2_3_EN (((0x1 << 6) << 16) | (0x0 << 6))
#define PHY_DRV_ODT_SET(n) (((n) << 4) | (n))
#define DDR3_DLL_RESET (1 << 8)
#endif /* _ASM_ARCH_SDRAM_RK322X_H */

@ -7,4 +7,27 @@
#ifndef _ASM_ARCH_SYS_PROTO_H
#define _ASM_ARCH_SYS_PROTO_H
#ifdef CONFIG_ROCKCHIP_RK3288
#include <asm/armv7.h>
static void configure_l2ctlr(void)
{
uint32_t l2ctlr;
l2ctlr = read_l2ctlr();
l2ctlr &= 0xfffc0000; /* clear bit0~bit17 */
/*
* Data RAM write latency: 2 cycles
* Data RAM read latency: 2 cycles
* Data RAM setup latency: 1 cycle
* Tag RAM write latency: 1 cycle
* Tag RAM read latency: 1 cycle
* Tag RAM setup latency: 1 cycle
*/
l2ctlr |= (1 << 3 | 1 << 0);
write_l2ctlr(l2ctlr);
}
#endif /* CONFIG_ROCKCHIP_RK3288 */
#endif /* _ASM_ARCH_SYS_PROTO_H */

@ -61,6 +61,27 @@
#include <asm/io.h>
#include <asm/barriers.h>
/* read L2 control register (L2CTLR) */
static inline uint32_t read_l2ctlr(void)
{
uint32_t val = 0;
asm volatile ("mrc p15, 1, %0, c9, c0, 2" : "=r" (val));
return val;
}
/* write L2 control register (L2CTLR) */
static inline void write_l2ctlr(uint32_t val)
{
/*
* Note: L2CTLR can only be written when the L2 memory system
* is idle, ie before the MMU is enabled.
*/
asm volatile("mcr p15, 1, %0, c9, c0, 2" : : "r" (val) : "memory");
isb();
}
/*
* Workaround for ARM errata # 798870
* Set L2ACTLR[7] to reissue any memory transaction in the L2 that has been

@ -12,6 +12,7 @@ obj-spl-$(CONFIG_ROCKCHIP_BROM_HELPER) += bootrom.o save_boot_param.o
obj-tpl-$(CONFIG_ROCKCHIP_BROM_HELPER) += bootrom.o save_boot_param.o
obj-tpl-$(CONFIG_ROCKCHIP_RK3188) += rk3188-board-tpl.o
obj-tpl-$(CONFIG_ROCKCHIP_RK3288) += rk3288-board-tpl.o
obj-tpl-$(CONFIG_ROCKCHIP_RK3368) += rk3368-board-tpl.o
obj-spl-$(CONFIG_ROCKCHIP_RK3036) += rk3036-board-spl.o

@ -6,6 +6,5 @@
ifndef CONFIG_TPL_BUILD
obj-y += clk_rk3188.o
obj-y += sdram_rk3188.o
obj-y += syscon_rk3188.o
endif

@ -21,12 +21,12 @@ DECLARE_GLOBAL_DATA_PTR;
static void setup_boot_mode(void)
{
struct rk322x_grf *const grf = (void *)GRF_BASE;
int boot_mode = readl(&grf->os_reg[4]);
int boot_mode = readl(&grf->os_reg[0]);
debug("boot mode %x.\n", boot_mode);
/* Clear boot mode */
writel(BOOT_NORMAL, &grf->os_reg[4]);
writel(BOOT_NORMAL, &grf->os_reg[0]);
switch (boot_mode) {
case BOOT_FASTBOOT:

@ -19,7 +19,10 @@
#include <asm/arch/clock.h>
#include <asm/arch/hardware.h>
#include <asm/arch/periph.h>
#include <asm/arch/pmu_rk3288.h>
#include <asm/arch/sdram.h>
#include <asm/arch/sdram_common.h>
#include <asm/arch/sys_proto.h>
#include <asm/arch/timer.h>
#include <dm/pinctrl.h>
#include <dm/root.h>
@ -80,46 +83,6 @@ u32 spl_boot_mode(const u32 boot_device)
return MMCSD_MODE_RAW;
}
/* read L2 control register (L2CTLR) */
static inline uint32_t read_l2ctlr(void)
{
uint32_t val = 0;
asm volatile ("mrc p15, 1, %0, c9, c0, 2" : "=r" (val));
return val;
}
/* write L2 control register (L2CTLR) */
static inline void write_l2ctlr(uint32_t val)
{
/*
* Note: L2CTLR can only be written when the L2 memory system
* is idle, ie before the MMU is enabled.
*/
asm volatile("mcr p15, 1, %0, c9, c0, 2" : : "r" (val) : "memory");
isb();
}
static void configure_l2ctlr(void)
{
uint32_t l2ctlr;
l2ctlr = read_l2ctlr();
l2ctlr &= 0xfffc0000; /* clear bit0~bit17 */
/*
* Data RAM write latency: 2 cycles
* Data RAM read latency: 2 cycles
* Data RAM setup latency: 1 cycle
* Tag RAM write latency: 1 cycle
* Tag RAM read latency: 1 cycle
* Tag RAM setup latency: 1 cycle
*/
l2ctlr |= (1 << 3 | 1 << 0);
write_l2ctlr(l2ctlr);
}
#ifdef CONFIG_SPL_MMC_SUPPORT
static int configure_emmc(struct udevice *pinctrl)
{
@ -243,12 +206,15 @@ void board_init_f(ulong dummy)
}
#endif
#if !defined(CONFIG_SUPPORT_TPL)
debug("\nspl:init dram\n");
ret = uclass_get_device(UCLASS_RAM, 0, &dev);
if (ret) {
debug("DRAM init failed: %d\n", ret);
return;
}
#endif
#if CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM) && !defined(CONFIG_SPL_BOARD_INIT)
back_to_bootrom();
#endif
@ -326,3 +292,18 @@ err:
/* No way to report error here */
hang();
}
#ifdef CONFIG_SPL_OS_BOOT
#define PMU_BASE 0xff730000
int dram_init_banksize(void)
{
struct rk3288_pmu *const pmu = (void *)PMU_BASE;
size_t size = rockchip_sdram_size((phys_addr_t)&pmu->sys_reg[2]);
gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
gd->bd->bi_dram[0].size = size;
return 0;
}
#endif

@ -0,0 +1,84 @@
/*
* Copyright (C) 2017 Amarula Solutions
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <debug_uart.h>
#include <dm.h>
#include <ram.h>
#include <spl.h>
#include <version.h>
#include <asm/io.h>
#include <asm/arch/bootrom.h>
#include <asm/arch/clock.h>
#include <asm/arch/grf_rk3288.h>
#include <asm/arch/periph.h>
#include <asm/arch/pmu_rk3288.h>
#include <asm/arch/sys_proto.h>
#include <asm/arch/timer.h>
DECLARE_GLOBAL_DATA_PTR;
#define GRF_BASE 0xff770000
void board_init_f(ulong dummy)
{
struct udevice *dev;
int ret;
/* Example code showing how to enable the debug UART on RK3288 */
/* Enable early UART on the RK3288 */
struct rk3288_grf * const grf = (void *)GRF_BASE;
rk_clrsetreg(&grf->gpio7ch_iomux, GPIO7C7_MASK << GPIO7C7_SHIFT |
GPIO7C6_MASK << GPIO7C6_SHIFT,
GPIO7C7_UART2DBG_SOUT << GPIO7C7_SHIFT |
GPIO7C6_UART2DBG_SIN << GPIO7C6_SHIFT);
/*
* Debug UART can be used from here if required:
*
* debug_uart_init();
* printch('a');
* printhex8(0x1234);
* printascii("string");
*/
debug_uart_init();
ret = spl_early_init();
if (ret) {
debug("spl_early_init() failed: %d\n", ret);
hang();
}
rockchip_timer_init();
configure_l2ctlr();
ret = rockchip_get_clk(&dev);
if (ret) {
debug("CLK 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 board_return_to_bootrom(void)
{
back_to_bootrom();
}
u32 spl_boot_device(void)
{
return BOOT_DEVICE_BOOTROM;
}
void spl_board_init(void)
{
puts("\nU-Boot TPL " PLAIN_VERSION " (" U_BOOT_DATE " - " \
U_BOOT_TIME ")\n");
}

@ -87,6 +87,22 @@ config TARGET_POPMETAL_RK3288
config TARGET_VYASA_RK3288
bool "Vyasa-RK3288"
select BOARD_LATE_INIT
select TPL
select SUPPORT_TPL
select TPL_DM
select TPL_REGMAP
select TPL_SYSCON
select TPL_CLK
select TPL_RAM
select TPL_OF_PLATDATA
select TPL_OF_CONTROL
select TPL_BOOTROM_SUPPORT
select TPL_NEEDS_SEPARATE_TEXT_BASE if SPL
select ROCKCHIP_BROM_HELPER
select TPL_DRIVERS_MISC_SUPPORT
select TPL_LIBCOMMON_SUPPORT
select TPL_LIBGENERIC_SUPPORT
select TPL_SERIAL_SUPPORT
help
Vyasa is a RK3288-based development board with 2 USB ports,
HDMI, VGA, micro-SD card, audio, WiFi and Gigabit Ethernet, It

@ -6,5 +6,4 @@
obj-y += clk_rk3288.o
obj-y += rk3288.o
obj-y += sdram_rk3288.o
obj-y += syscon_rk3288.o

@ -6,5 +6,4 @@
obj-y += clk_rk3328.o
obj-y += rk3328.o
obj-y += sdram_rk3328.o
obj-y += syscon_rk3328.o

@ -1,10 +1,12 @@
/*
* (C) Copyright 2016 Rockchip Electronics Co., Ltd
* (C) Copyright 2017 Theobroma Systems Design und Consulting GmbH
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <asm/arch/bootrom.h>
#include <asm/arch/clock.h>
#include <asm/arch/grf_rk3399.h>
#include <asm/arch/hardware.h>
@ -19,9 +21,43 @@
DECLARE_GLOBAL_DATA_PTR;
void board_return_to_bootrom(void)
{
back_to_bootrom();
}
static const char * const boot_devices[BROM_LAST_BOOTSOURCE + 1] = {
[BROM_BOOTSOURCE_EMMC] = "/sdhci@fe330000",
[BROM_BOOTSOURCE_SPINOR] = "/spi@ff1d0000",
[BROM_BOOTSOURCE_SD] = "/dwmmc@fe320000",
};
const char *board_spl_was_booted_from(void)
{
u32 bootdevice_brom_id = readl(RK3399_BROM_BOOTSOURCE_ID_ADDR);
const char *bootdevice_ofpath = NULL;
if (bootdevice_brom_id < ARRAY_SIZE(boot_devices))
bootdevice_ofpath = boot_devices[bootdevice_brom_id];
if (bootdevice_ofpath)
debug("%s: brom_bootdevice_id %x maps to '%s'\n",
__func__, bootdevice_brom_id, bootdevice_ofpath);
else
debug("%s: failed to resolve brom_bootdevice_id %x\n",
__func__, bootdevice_brom_id);
return bootdevice_ofpath;
}
u32 spl_boot_device(void)
{
return BOOT_DEVICE_MMC1;
u32 boot_device = BOOT_DEVICE_MMC1;
if (CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM))
return BOOT_DEVICE_BOOTROM;
return boot_device;
}
u32 spl_boot_mode(const u32 boot_device)
@ -137,37 +173,6 @@ void board_init_f(ulong dummy)
}
}
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();
#if CONFIG_IS_ENABLED(ROCKCHIP_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)
{

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

@ -10,6 +10,25 @@
#include <spl.h>
#if CONFIG_IS_ENABLED(OF_CONTROL)
/**
* spl_node_to_boot_device() - maps from a DT-node to a SPL boot device
* @node: of_offset of the node
*
* The SPL framework uses BOOT_DEVICE_... constants to identify its boot
* sources. These may take on a device-specific meaning, depending on
* what nodes are enabled in a DTS (e.g. BOOT_DEVICE_MMC1 may refer to
* different controllers/block-devices, depending on which SD/MMC controllers
* are enabled in any given DTS). This function maps from a DT-node back
* onto a BOOT_DEVICE_... constant, considering the currently active devices.
*
* Returns
* -ENOENT, if no device matching the node could be found
* -ENOSYS, if the device matching the node can not be mapped onto a
* SPL boot device (e.g. the third MMC device)
* -1, for unspecified failures
* a positive integer (from the BOOT_DEVICE_... family) on succes.
*/
static int spl_node_to_boot_device(int node)
{
struct udevice *parent;
@ -57,6 +76,24 @@ static int spl_node_to_boot_device(int node)
return -1;
}
/**
* board_spl_was_booted_from() - retrieves the of-path the SPL was loaded from
*
* To support a 'same-as-spl' specification in the search-order for the next
* stage, we need a SoC- or board-specific way to handshake with what 'came
* before us' (either a BROM or TPL stage) and map the info retrieved onto
* a OF path.
*
* Returns
* NULL, on failure or if the device could not be identified
* a of_path (a string), on success
*/
__weak const char *board_spl_was_booted_from(void)
{
debug("%s: no support for 'same-as-spl' for this board\n", __func__);
return NULL;
}
void board_boot_order(u32 *spl_boot_list)
{
const void *blob = gd->fdt_blob;
@ -78,8 +115,17 @@ void board_boot_order(u32 *spl_boot_list)
(conf = fdt_stringlist_get(blob, chosen_node,
"u-boot,spl-boot-order", elem, NULL));
elem++) {
const char *alias;
/* Handle the case of 'same device the SPL was loaded from' */
if (strncmp(conf, "same-as-spl", 11) == 0) {
conf = board_spl_was_booted_from();
if (!conf)
continue;
}
/* First check if the list element is an alias */
const char *alias = fdt_get_alias(blob, conf);
alias = fdt_get_alias(blob, conf);
if (alias)
conf = alias;

@ -5,3 +5,16 @@
*/
#include <common.h>
#ifndef CONFIG_TPL_BUILD
#include <spl.h>
int spl_start_uboot(void)
{
/* break into full u-boot on 'c' */
if (serial_tstc() && serial_getc() == 'c')
return 1;
return 0;
}
#endif

@ -3,13 +3,14 @@
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <dm.h>
#include <ram.h>
#include <dm/pinctrl.h>
#include <dm/uclass-internal.h>
#include <asm/arch/periph.h>
#include <power/regulator.h>
#include <spl.h>
DECLARE_GLOBAL_DATA_PTR;
@ -67,3 +68,30 @@ int board_init(void)
out:
return 0;
}
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();
return;
err:
printf("%s: Error %d\n", __func__, ret);
/* No way to report error here */
hang();
}

@ -27,8 +27,8 @@
type = "firmware";
arch = "arm64";
compression = "none";
load = <0x00010000>;
entry = <0x00010000>;
load = <0x00100000>;
entry = <0x00100000>;
};
fdt {

@ -3,60 +3,48 @@
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <dm.h>
#include <misc.h>
#include <ram.h>
#include <dm/pinctrl.h>
#include <dm/uclass-internal.h>
#include <asm/setup.h>
#include <asm/arch/periph.h>
#include <power/regulator.h>
#include <spl.h>
#include <u-boot/sha256.h>
DECLARE_GLOBAL_DATA_PTR;
int board_init(void)
{
struct udevice *pinctrl, *regulator;
int ret;
/*
* The PWM does not have decicated interrupt number in dts and can
* not get periph_id by pinctrl framework, so let's init them here.
* The PWM2 and PWM3 are for pwm regulators.
* We need to call into regulators_enable_boot_on() again, as the call
* during SPL may have not included all regulators.
*/
ret = uclass_get_device(UCLASS_PINCTRL, 0, &pinctrl);
if (ret) {
debug("%s: Cannot find pinctrl device\n", __func__);
goto out;
}
ret = pinctrl_request_noflags(pinctrl, PERIPH_ID_PWM2);
if (ret) {
debug("%s PWM2 pinctrl init fail!\n", __func__);
goto out;
}
/* rk3399 need to init vdd_center to get the correct output voltage */
ret = regulator_get_by_platname("vdd_center", &regulator);
ret = regulators_enable_boot_on(false);
if (ret)
debug("%s: Cannot get vdd_center regulator\n", __func__);
debug("%s: Cannot enable boot on regulator\n", __func__);
ret = regulator_get_by_platname("vcc5v0_host", &regulator);
if (ret) {
debug("%s vcc5v0_host init fail! ret %d\n", __func__, ret);
goto out;
}
return 0;
}
ret = regulator_set_enable(regulator, true);
if (ret) {
debug("%s vcc5v0-host-en set fail!\n", __func__);
goto out;
}
void spl_board_init(void)
{
int ret;
out:
return 0;
/*
* Turning the eMMC and SPI back on (if disabled via the Qseven
* BIOS_ENABLE) signal is done through a always-on regulator).
*/
ret = regulators_enable_boot_on(false);
if (ret)
debug("%s: Cannot enable boot on regulator\n", __func__);
preloader_console_init();
}
static void setup_macaddr(void)
@ -91,8 +79,6 @@ static void setup_macaddr(void)
mac_addr[0] |= 0x02; /* set local assignment bit (IEEE802) */
eth_env_set_enetaddr("ethaddr", mac_addr);
#endif
return;
}
static void setup_serial(void)
@ -147,8 +133,6 @@ static void setup_serial(void)
env_set("cpuid#", cpuid_str);
env_set("serial#", serialno_str);
#endif
return;
}
int misc_init_r(void)

@ -22,12 +22,18 @@ CONFIG_REGMAP=y
CONFIG_SYSCON=y
CONFIG_CLK=y
CONFIG_ROCKCHIP_GPIO=y
CONFIG_SYS_I2C_ROCKCHIP=y
CONFIG_MMC_DW=y
CONFIG_MMC_DW_ROCKCHIP=y
CONFIG_PINCTRL=y
CONFIG_PINCTRL_ROCKCHIP_RK3328=y
CONFIG_DM_PMIC=y
CONFIG_PMIC_RK8XX=y
CONFIG_DM_REGULATOR=y
CONFIG_REGULATOR_PWM=y
CONFIG_DM_REGULATOR_FIXED=y
CONFIG_REGULATOR_RK8XX=y
CONFIG_PWM_ROCKCHIP=y
CONFIG_RAM=y
CONFIG_BAUDRATE=1500000
CONFIG_DEBUG_UART_BASE=0xFF130000

@ -23,7 +23,6 @@ CONFIG_BOOTSTAGE=y
CONFIG_SPL_BOOTSTAGE=y
CONFIG_BOOTSTAGE_REPORT=y
CONFIG_BOOTSTAGE_FDT=y
CONFIG_ENV_IS_IN_MMC=y
# CONFIG_DISPLAY_CPUINFO is not set
CONFIG_ARCH_EARLY_INIT_R=y
CONFIG_SPL=y

@ -1,5 +1,6 @@
CONFIG_ARM=y
CONFIG_ARCH_ROCKCHIP=y
CONFIG_SPL_GPIO_SUPPORT=y
CONFIG_SPL_LIBCOMMON_SUPPORT=y
CONFIG_SPL_LIBGENERIC_SUPPORT=y
CONFIG_SYS_MALLOC_F_LEN=0x4000
@ -20,6 +21,8 @@ CONFIG_SPL_BOARD_INIT=y
CONFIG_SPL_STACK_R=y
CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x4000
CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x200
CONFIG_SPL_I2C_SUPPORT=y
CONFIG_SPL_POWER_SUPPORT=y
CONFIG_CMD_BOOTZ=y
# CONFIG_CMD_IMLS is not set
CONFIG_CMD_GPT=y
@ -63,8 +66,10 @@ CONFIG_SPL_PINCTRL=y
CONFIG_PINCTRL_ROCKCHIP_RK3399=y
CONFIG_DM_PMIC=y
CONFIG_PMIC_RK8XX=y
CONFIG_REGULATOR_PWM=y
CONFIG_SPL_DM_REGULATOR=y
CONFIG_DM_REGULATOR_FIXED=y
CONFIG_SPL_DM_REGULATOR_FIXED=y
CONFIG_DM_REGULATOR_GPIO=y
CONFIG_REGULATOR_RK8XX=y
CONFIG_PWM_ROCKCHIP=y
CONFIG_RAM=y

@ -1,8 +1,11 @@
CONFIG_ARM=y
# CONFIG_SPL_USE_ARCH_MEMCPY is not set
# CONFIG_SPL_USE_ARCH_MEMSET is not set
CONFIG_ARCH_ROCKCHIP=y
CONFIG_SYS_MALLOC_F_LEN=0x2000
CONFIG_ROCKCHIP_RK3288=y
CONFIG_TARGET_VYASA_RK3288=y
CONFIG_TPL_TEXT_BASE=0xff704004
CONFIG_SPL_STACK_R_ADDR=0x80000
CONFIG_DEFAULT_DEVICE_TREE="rk3288-vyasa"
CONFIG_DEBUG_UART=y

@ -150,6 +150,24 @@ Note: rk3036 SDMMC and debug uart use the same iomux, so if you boot from SD, th
debug uart must be disabled
Booting from an SD card on RK3288 with TPL
==========================================
Since the size of SPL can't be exceeded 0x8000 bytes in RK3288, it is not possible add
new SPL features like Falcon mode or etc.
So introduce TPL so-that adding new features to SPL is possible because now TPL should
run minimal with code like DDR, clock etc and rest of new features in SPL.
As of now TPL is added on Vyasa-RK3288 board.
To write an image that boots from an SD card (assumed to be /dev/mmcblk0):
./tools/mkimage -n rk3288 -T rksd -d ./tpl/u-boot-tpl.bin out &&
cat ./spl/u-boot-spl-dtb.bin >> out &&
sudo dd if=out of=/dev/mmcblk0 seek=64 &&
sudo dd if=u-boot-dtb.img of=/dev/mmcblk0 seek=256
Booting from an SD card on RK3188
=================================

@ -56,10 +56,20 @@ Each list element of the property should specify a device to be probed
in the order they are listed: references (i.e. implicit paths), a full
path or an alias is expected for each entry.
A special specifier "same-as-spl" can be used at any position in the
boot-order to direct U-Boot to insert the device the SPL was booted
from there. Whether this is indeed inserted or silently ignored (if
it is not supported on any given SoC/board or if the boot-device is
not available to continue booting from) is implementation-defined.
Note that if "same-as-spl" expands to an actual node for a given
board, the corresponding node may appear multiple times in the
boot-order (as there currently exists no mechanism to suppress
duplicates from the list).
Example
-------
/ {
chosen {
u-boot,spl-boot-order = &sdmmc, "/sdhci@fe330000";
u-boot,spl-boot-order = "same-as-spl", &sdmmc, "/sdhci@fe330000";
};
};

@ -28,3 +28,12 @@ config ADC_SANDBOX
- 4 analog input channels
- 16-bit resolution
- single and multi-channel conversion mode
config SARADC_ROCKCHIP
bool "Enable Rockchip SARADC driver"
help
This enables driver for Rockchip SARADC.
It provides:
- 2~6 analog input channels
- 1O or 12 bits resolution
- Up to 1MSPS of sample rate

@ -8,3 +8,4 @@
obj-$(CONFIG_ADC) += adc-uclass.o
obj-$(CONFIG_ADC_EXYNOS) += exynos-adc.o
obj-$(CONFIG_ADC_SANDBOX) += sandbox.o
obj-$(CONFIG_SARADC_ROCKCHIP) += rockchip-saradc.o

@ -0,0 +1,183 @@
/*
* (C) Copyright 2017, Fuzhou Rockchip Electronics Co., Ltd
*
* SPDX-License-Identifier: GPL-2.0+
*
* Rockchip SARADC driver for U-Boot
*/
#include <common.h>
#include <adc.h>
#include <clk.h>
#include <dm.h>
#include <errno.h>
#include <asm/io.h>
#define SARADC_CTRL_CHN_MASK GENMASK(2, 0)
#define SARADC_CTRL_POWER_CTRL BIT(3)
#define SARADC_CTRL_IRQ_ENABLE BIT(5)
#define SARADC_CTRL_IRQ_STATUS BIT(6)
#define SARADC_TIMEOUT (100 * 1000)
struct rockchip_saradc_regs {
unsigned int data;
unsigned int stas;
unsigned int ctrl;
unsigned int dly_pu_soc;
};
struct rockchip_saradc_data {
int num_bits;
int num_channels;
unsigned long clk_rate;
};
struct rockchip_saradc_priv {
struct rockchip_saradc_regs *regs;
int active_channel;
const struct rockchip_saradc_data *data;
};
int rockchip_saradc_channel_data(struct udevice *dev, int channel,
unsigned int *data)
{
struct rockchip_saradc_priv *priv = dev_get_priv(dev);
struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev);
if (channel != priv->active_channel) {
error("Requested channel is not active!");
return -EINVAL;
}
if ((readl(&priv->regs->ctrl) & SARADC_CTRL_IRQ_STATUS) !=
SARADC_CTRL_IRQ_STATUS)
return -EBUSY;
/* Read value */
*data = readl(&priv->regs->data);
*data &= uc_pdata->data_mask;
/* Power down adc */
writel(0, &priv->regs->ctrl);
return 0;
}
int rockchip_saradc_start_channel(struct udevice *dev, int channel)
{
struct rockchip_saradc_priv *priv = dev_get_priv(dev);
if (channel < 0 || channel >= priv->data->num_channels) {
error("Requested channel is invalid!");
return -EINVAL;
}
/* 8 clock periods as delay between power up and start cmd */
writel(8, &priv->regs->dly_pu_soc);
/* Select the channel to be used and trigger conversion */
writel(SARADC_CTRL_POWER_CTRL | (channel & SARADC_CTRL_CHN_MASK) |
SARADC_CTRL_IRQ_ENABLE, &priv->regs->ctrl);
priv->active_channel = channel;
return 0;
}
int rockchip_saradc_stop(struct udevice *dev)
{
struct rockchip_saradc_priv *priv = dev_get_priv(dev);
/* Power down adc */
writel(0, &priv->regs->ctrl);
priv->active_channel = -1;
return 0;
}
int rockchip_saradc_probe(struct udevice *dev)
{
struct rockchip_saradc_priv *priv = dev_get_priv(dev);
struct clk clk;
int ret;
ret = clk_get_by_index(dev, 0, &clk);
if (ret)
return ret;
ret = clk_set_rate(&clk, priv->data->clk_rate);
if (IS_ERR_VALUE(ret))
return ret;
priv->active_channel = -1;
return 0;
}
int rockchip_saradc_ofdata_to_platdata(struct udevice *dev)
{
struct adc_uclass_platdata *uc_pdata = dev_get_uclass_platdata(dev);
struct rockchip_saradc_priv *priv = dev_get_priv(dev);
struct rockchip_saradc_data *data;
data = (struct rockchip_saradc_data *)dev_get_driver_data(dev);
priv->regs = (struct rockchip_saradc_regs *)dev_read_addr(dev);
if (priv->regs == (struct rockchip_saradc_regs *)FDT_ADDR_T_NONE) {
error("Dev: %s - can't get address!", dev->name);
return -ENODATA;
}
priv->data = data;
uc_pdata->data_mask = (1 << priv->data->num_bits) - 1;;
uc_pdata->data_format = ADC_DATA_FORMAT_BIN;
uc_pdata->data_timeout_us = SARADC_TIMEOUT / 5;
uc_pdata->channel_mask = (1 << priv->data->num_channels) - 1;
return 0;
}
static const struct adc_ops rockchip_saradc_ops = {
.start_channel = rockchip_saradc_start_channel,
.channel_data = rockchip_saradc_channel_data,
.stop = rockchip_saradc_stop,
};
static const struct rockchip_saradc_data saradc_data = {
.num_bits = 10,
.num_channels = 3,
.clk_rate = 1000000,
};
static const struct rockchip_saradc_data rk3066_tsadc_data = {
.num_bits = 12,
.num_channels = 2,
.clk_rate = 50000,
};
static const struct rockchip_saradc_data rk3399_saradc_data = {
.num_bits = 10,
.num_channels = 6,
.clk_rate = 1000000,
};
static const struct udevice_id rockchip_saradc_ids[] = {
{ .compatible = "rockchip,saradc",
.data = (ulong)&saradc_data },
{ .compatible = "rockchip,rk3066-tsadc",
.data = (ulong)&rk3066_tsadc_data },
{ .compatible = "rockchip,rk3399-saradc",
.data = (ulong)&rk3399_saradc_data },
{ }
};
U_BOOT_DRIVER(rockchip_saradc) = {
.name = "rockchip_saradc",
.id = UCLASS_ADC,
.of_match = rockchip_saradc_ids,
.ops = &rockchip_saradc_ops,
.probe = rockchip_saradc_probe,
.ofdata_to_platdata = rockchip_saradc_ofdata_to_platdata,
.priv_auto_alloc_size = sizeof(struct rockchip_saradc_priv),
};

@ -117,16 +117,16 @@ static void rkclk_init(struct rk322x_cru *cru)
pclk_div << CORE_PERI_DIV_SHIFT);
/*
* select apll as pd_bus bus clock source and
* select gpll as pd_bus bus clock source and
* set up dependent divisors for PCLK/HCLK and ACLK clocks.
*/
aclk_div = GPLL_HZ / BUS_ACLK_HZ - 1;
assert((aclk_div + 1) * BUS_ACLK_HZ == GPLL_HZ && aclk_div <= 0x1f);
pclk_div = GPLL_HZ / BUS_PCLK_HZ - 1;
pclk_div = BUS_ACLK_HZ / BUS_PCLK_HZ - 1;
assert((pclk_div + 1) * BUS_PCLK_HZ == GPLL_HZ && pclk_div <= 0x7);
hclk_div = GPLL_HZ / BUS_HCLK_HZ - 1;
hclk_div = BUS_ACLK_HZ / BUS_HCLK_HZ - 1;
assert((hclk_div + 1) * BUS_HCLK_HZ == GPLL_HZ && hclk_div <= 0x3);
rk_clrsetreg(&cru->cru_clksel_con[0],
@ -389,7 +389,7 @@ static int rk322x_clk_bind(struct udevice *dev)
/* The reset driver does not have a device node, so bind it here */
ret = device_bind_driver(gd->dm_root, "rk322x_sysreset", "reset", &dev);
if (ret)
debug("Warning: No RK3036 reset driver: ret=%d\n", ret);
debug("Warning: No RK322x reset driver: ret=%d\n", ret);
return 0;
}

@ -5,6 +5,7 @@
*/
#include <common.h>
#include <bitfield.h>
#include <clk-uclass.h>
#include <dm.h>
#include <dt-structs.h>
@ -111,6 +112,15 @@ enum {
PERI_ACLK_DIV_SHIFT = 0,
PERI_ACLK_DIV_MASK = 0x1f << PERI_ACLK_DIV_SHIFT,
/*
* CLKSEL24
* saradc_div_con:
* clk_saradc=24MHz/(saradc_div_con+1)
*/
CLK_SARADC_DIV_CON_SHIFT = 8,
CLK_SARADC_DIV_CON_MASK = GENMASK(15, 8),
CLK_SARADC_DIV_CON_WIDTH = 8,
SOCSTS_DPLL_LOCK = 1 << 5,
SOCSTS_APLL_LOCK = 1 << 6,
SOCSTS_CPLL_LOCK = 1 << 7,
@ -634,6 +644,31 @@ static ulong rockchip_spi_set_clk(struct rk3288_cru *cru, uint gclk_rate,
return rockchip_spi_get_clk(cru, gclk_rate, periph);
}
static ulong rockchip_saradc_get_clk(struct rk3288_cru *cru)
{
u32 div, val;
val = readl(&cru->cru_clksel_con[24]);
div = bitfield_extract(val, CLK_SARADC_DIV_CON_SHIFT,
CLK_SARADC_DIV_CON_WIDTH);
return DIV_TO_RATE(OSC_HZ, div);
}
static ulong rockchip_saradc_set_clk(struct rk3288_cru *cru, uint hz)
{
int src_clk_div;
src_clk_div = DIV_ROUND_UP(OSC_HZ, hz) - 1;
assert(src_clk_div < 128);
rk_clrsetreg(&cru->cru_clksel_con[24],
CLK_SARADC_DIV_CON_MASK,
src_clk_div << CLK_SARADC_DIV_CON_SHIFT);
return rockchip_saradc_get_clk(cru);
}
static ulong rk3288_clk_get_rate(struct clk *clk)
{
struct rk3288_clk_priv *priv = dev_get_priv(clk->dev);
@ -666,6 +701,9 @@ static ulong rk3288_clk_get_rate(struct clk *clk)
return gclk_rate;
case PCLK_PWM:
return PD_BUS_PCLK_HZ;
case SCLK_SARADC:
new_rate = rockchip_saradc_get_clk(priv->cru);
break;
default:
return -ENOENT;
}
@ -756,6 +794,9 @@ static ulong rk3288_clk_set_rate(struct clk *clk, ulong rate)
new_rate = rate;
break;
#endif
case SCLK_SARADC:
new_rate = rockchip_saradc_set_clk(priv->cru, rate);
break;
default:
return -ENOENT;
}

@ -5,6 +5,7 @@
*/
#include <common.h>
#include <bitfield.h>
#include <clk-uclass.h>
#include <dm.h>
#include <errno.h>
@ -114,7 +115,8 @@ enum {
/* CLKSEL_CON23 */
CLK_SARADC_DIV_CON_SHIFT = 0,
CLK_SARADC_DIV_CON_MASK = 0x3ff << CLK_SARADC_DIV_CON_SHIFT,
CLK_SARADC_DIV_CON_MASK = GENMASK(9, 0),
CLK_SARADC_DIV_CON_WIDTH = 10,
/* CLKSEL_CON24 */
CLK_PWM_PLL_SEL_CPLL = 0,
@ -478,6 +480,31 @@ static ulong rk3328_pwm_set_clk(struct rk3328_cru *cru, uint hz)
return DIV_TO_RATE(GPLL_HZ, div);
}
static ulong rk3328_saradc_get_clk(struct rk3328_cru *cru)
{
u32 div, val;
val = readl(&cru->clksel_con[23]);
div = bitfield_extract(val, CLK_SARADC_DIV_CON_SHIFT,
CLK_SARADC_DIV_CON_WIDTH);
return DIV_TO_RATE(OSC_HZ, div);
}
static ulong rk3328_saradc_set_clk(struct rk3328_cru *cru, uint hz)
{
int src_clk_div;
src_clk_div = DIV_ROUND_UP(OSC_HZ, hz) - 1;
assert(src_clk_div < 128);
rk_clrsetreg(&cru->clksel_con[23],
CLK_SARADC_DIV_CON_MASK,
src_clk_div << CLK_SARADC_DIV_CON_SHIFT);
return rk3328_saradc_get_clk(cru);
}
static ulong rk3328_clk_get_rate(struct clk *clk)
{
struct rk3328_clk_priv *priv = dev_get_priv(clk->dev);
@ -501,6 +528,9 @@ static ulong rk3328_clk_get_rate(struct clk *clk)
case SCLK_PWM:
rate = rk3328_pwm_get_clk(priv->cru);
break;
case SCLK_SARADC:
rate = rk3328_saradc_get_clk(priv->cru);
break;
default:
return -ENOENT;
}
@ -531,6 +561,9 @@ static ulong rk3328_clk_set_rate(struct clk *clk, ulong rate)
case SCLK_PWM:
ret = rk3328_pwm_set_clk(priv->cru, rate);
break;
case SCLK_SARADC:
ret = rk3328_saradc_set_clk(priv->cru, rate);
break;
default:
return -ENOENT;
}

@ -12,6 +12,7 @@
#include <errno.h>
#include <mapmem.h>
#include <syscon.h>
#include <bitfield.h>
#include <asm/arch/clock.h>
#include <asm/arch/cru_rk3368.h>
#include <asm/arch/hardware.h>
@ -397,6 +398,31 @@ static ulong rk3368_spi_set_clk(struct rk3368_cru *cru, ulong clk_id, uint hz)
return rk3368_spi_get_clk(cru, clk_id);
}
static ulong rk3368_saradc_get_clk(struct rk3368_cru *cru)
{
u32 div, val;
val = readl(&cru->clksel_con[25]);
div = bitfield_extract(val, CLK_SARADC_DIV_CON_SHIFT,
CLK_SARADC_DIV_CON_WIDTH);
return DIV_TO_RATE(OSC_HZ, div);
}
static ulong rk3368_saradc_set_clk(struct rk3368_cru *cru, uint hz)
{
int src_clk_div;
src_clk_div = DIV_ROUND_UP(OSC_HZ, hz) - 1;
assert(src_clk_div < 128);
rk_clrsetreg(&cru->clksel_con[25],
CLK_SARADC_DIV_CON_MASK,
src_clk_div << CLK_SARADC_DIV_CON_SHIFT);
return rk3368_saradc_get_clk(cru);
}
static ulong rk3368_clk_get_rate(struct clk *clk)
{
struct rk3368_clk_priv *priv = dev_get_priv(clk->dev);
@ -419,6 +445,9 @@ static ulong rk3368_clk_get_rate(struct clk *clk)
rate = rk3368_mmc_get_clk(priv->cru, clk->id);
break;
#endif
case SCLK_SARADC:
rate = rk3368_saradc_get_clk(priv->cru);
break;
default:
return -ENOENT;
}
@ -453,6 +482,9 @@ static ulong rk3368_clk_set_rate(struct clk *clk, ulong rate)
ret = rk3368_gmac_set_clk(priv->cru, clk->id, rate);
break;
#endif
case SCLK_SARADC:
ret = rk3368_saradc_set_clk(priv->cru, rate);
break;
default:
return -ENOENT;
}

@ -12,6 +12,7 @@
#include <errno.h>
#include <mapmem.h>
#include <syscon.h>
#include <bitfield.h>
#include <asm/io.h>
#include <asm/arch/clock.h>
#include <asm/arch/cru_rk3399.h>
@ -181,7 +182,8 @@ enum {
/* CLKSEL_CON26 */
CLK_SARADC_DIV_CON_SHIFT = 8,
CLK_SARADC_DIV_CON_MASK = 0xff << CLK_SARADC_DIV_CON_SHIFT,
CLK_SARADC_DIV_CON_MASK = GENMASK(15, 8),
CLK_SARADC_DIV_CON_WIDTH = 8,
/* CLKSEL_CON27 */
CLK_TSADC_SEL_X24M = 0x0,
@ -860,6 +862,32 @@ static ulong rk3399_ddr_set_clk(struct rk3399_cru *cru,
return set_rate;
}
static ulong rk3399_saradc_get_clk(struct rk3399_cru *cru)
{
u32 div, val;
val = readl(&cru->clksel_con[26]);
div = bitfield_extract(val, CLK_SARADC_DIV_CON_SHIFT,
CLK_SARADC_DIV_CON_WIDTH);
return DIV_TO_RATE(OSC_HZ, div);
}
static ulong rk3399_saradc_set_clk(struct rk3399_cru *cru, uint hz)
{
int src_clk_div;
src_clk_div = DIV_ROUND_UP(OSC_HZ, hz) - 1;
assert(src_clk_div < 128);
rk_clrsetreg(&cru->clksel_con[26],
CLK_SARADC_DIV_CON_MASK,
src_clk_div << CLK_SARADC_DIV_CON_SHIFT);
return rk3399_saradc_get_clk(cru);
}
static ulong rk3399_clk_get_rate(struct clk *clk)
{
struct rk3399_clk_priv *priv = dev_get_priv(clk->dev);
@ -895,6 +923,9 @@ static ulong rk3399_clk_get_rate(struct clk *clk)
break;
case PCLK_EFUSE1024NS:
break;
case SCLK_SARADC:
rate = rk3399_saradc_get_clk(priv->cru);
break;
default:
return -ENOENT;
}
@ -943,6 +974,9 @@ static ulong rk3399_clk_set_rate(struct clk *clk, ulong rate)
break;
case PCLK_EFUSE1024NS:
break;
case SCLK_SARADC:
ret = rk3399_saradc_set_clk(priv->cru, rate);
break;
default:
return -ENOENT;
}

@ -5,6 +5,7 @@
*/
#include <common.h>
#include <bitfield.h>
#include <clk-uclass.h>
#include <dm.h>
#include <errno.h>
@ -36,7 +37,7 @@ enum {
#hz "Hz cannot be hit with PLL "\
"divisors on line " __stringify(__LINE__));
/* use interge mode*/
/* use integer mode */
static inline int rv1108_pll_id(enum rk_clk_id clk_id)
{
int id = 0;
@ -130,6 +131,31 @@ static int rv1108_sfc_set_clk(struct rv1108_cru *cru, uint rate)
return DIV_TO_RATE(pll_rate, div);
}
static ulong rv1108_saradc_get_clk(struct rv1108_cru *cru)
{
u32 div, val;
val = readl(&cru->clksel_con[22]);
div = bitfield_extract(val, CLK_SARADC_DIV_CON_SHIFT,
CLK_SARADC_DIV_CON_WIDTH);
return DIV_TO_RATE(OSC_HZ, div);
}
static ulong rv1108_saradc_set_clk(struct rv1108_cru *cru, uint hz)
{
int src_clk_div;
src_clk_div = DIV_ROUND_UP(OSC_HZ, hz) - 1;
assert(src_clk_div < 128);
rk_clrsetreg(&cru->clksel_con[22],
CLK_SARADC_DIV_CON_MASK,
src_clk_div << CLK_SARADC_DIV_CON_SHIFT);
return rv1108_saradc_get_clk(cru);
}
static ulong rv1108_clk_get_rate(struct clk *clk)
{
struct rv1108_clk_priv *priv = dev_get_priv(clk->dev);
@ -137,6 +163,8 @@ static ulong rv1108_clk_get_rate(struct clk *clk)
switch (clk->id) {
case 0 ... 63:
return rkclk_pll_get_rate(priv->cru, clk->id);
case SCLK_SARADC:
return rv1108_saradc_get_clk(priv->cru);
default:
return -ENOENT;
}
@ -154,6 +182,9 @@ static ulong rv1108_clk_set_rate(struct clk *clk, ulong rate)
case SCLK_SFC:
new_rate = rv1108_sfc_set_clk(priv->cru, rate);
break;
case SCLK_SARADC:
new_rate = rv1108_saradc_set_clk(priv->cru, rate);
break;
default:
return -ENOENT;
}

@ -396,6 +396,7 @@ static const struct udevice_id rockchip_i2c_ids[] = {
{ .compatible = "rockchip,rk3066-i2c" },
{ .compatible = "rockchip,rk3188-i2c" },
{ .compatible = "rockchip,rk3288-i2c" },
{ .compatible = "rockchip,rk3328-i2c" },
{ .compatible = "rockchip,rk3399-i2c" },
{ }
};

@ -208,6 +208,29 @@ enum {
GPIO2A0_FLASH_CSN0 = (1 << GPIO2A0_SHIFT),
};
/*GRF_GPIO2B_IOMUX*/
enum {
GPIO2B3_SHIFT = 6,
GPIO2B3_MASK = GENMASK(GPIO2B3_SHIFT + 1, GPIO2B3_SHIFT),
GPIO2B3_GPIO = 0,
GPIO2B3_SDMMC0_DTECTN = (1 << GPIO2B3_SHIFT),
GPIO2B2_SHIFT = 4,
GPIO2B2_MASK = GENMASK(GPIO2B2_SHIFT + 1, GPIO2B2_SHIFT),
GPIO2B2_GPIO = 0,
GPIO2B2_SDMMC0_CMD = (1 << GPIO2B2_SHIFT),
GPIO2B1_SHIFT = 2,
GPIO2B1_MASK = GENMASK(GPIO2B1_SHIFT + 1, GPIO2B1_SHIFT),
GPIO2B1_GPIO = 0,
GPIO2B1_SDMMC0_CLKOUT = (1 << GPIO2B1_SHIFT),
GPIO2B0_SHIFT = 0,
GPIO2B0_MASK = GENMASK(GPIO2B0_SHIFT + 1, GPIO2B0_SHIFT),
GPIO2B0_GPIO = 0,
GPIO2B0_SDMMC0_D3 = (1 << GPIO2B0_SHIFT),
};
/*GRF_GPIO2D_IOMUX*/
enum {
GPIO2D7_SHIFT = 14,
@ -580,11 +603,17 @@ static void pinctrl_rk3368_sdmmc_config(struct rk3368_grf *grf, int mmc_id)
GPIO2A4_EMMC_CLKOUT);
break;
case PERIPH_ID_SDCARD:
/*
* We assume that the BROM has already set this up
* correctly for us and that there's nothing to do
* here.
*/
debug("mmc id = %d setting registers!\n", mmc_id);
rk_clrsetreg(&grf->gpio2a_iomux,
GPIO2A5_MASK | GPIO2A7_MASK |
GPIO2A7_MASK,
GPIO2A5_SDMMC0_D0 | GPIO2A6_SDMMC0_D1 |
GPIO2A7_SDMMC0_D2);
rk_clrsetreg(&grf->gpio2b_iomux,
GPIO2B0_MASK | GPIO2B1_MASK |
GPIO2B2_MASK | GPIO2B3_MASK,
GPIO2B0_SDMMC0_D3 | GPIO2B1_SDMMC0_CLKOUT |
GPIO2B2_SDMMC0_CMD | GPIO2B3_SDMMC0_DTECTN);
break;
default:
debug("mmc id = %d iomux error!\n", mmc_id);

@ -77,6 +77,13 @@ config DM_REGULATOR_FIXED
features for fixed value regulators. The driver implements get/set api
for enable and get only for voltage value.
config SPL_DM_REGULATOR_FIXED
bool "Enable Driver Model for REGULATOR Fixed value in SPL"
depends on DM_REGULATOR_FIXED
---help---
This config enables implementation of driver-model regulator uclass
features for fixed value regulators in SPL.
config DM_REGULATOR_GPIO
bool "Enable Driver Model for GPIO REGULATOR"
depends on DM_REGULATOR

@ -5,3 +5,8 @@
#
obj-$(CONFIG_ROCKCHIP_RK3368) = dmc-rk3368.o
obj-$(CONFIG_ROCKCHIP_RK3188) = sdram_rk3188.o
obj-$(CONFIG_ROCKCHIP_RK322X) = sdram_rk322x.o
obj-$(CONFIG_ROCKCHIP_RK3288) = sdram_rk3288.o
obj-$(CONFIG_ROCKCHIP_RK3328) = sdram_rk3328.o
obj-$(CONFIG_ROCKCHIP_RK3399) = sdram_rk3399.o

@ -682,11 +682,18 @@ out:
static int sdram_get_niu_config(struct rk3188_sdram_params *sdram_params)
{
int i, tmp, size, ret = 0;
int i, tmp, size, row, ret = 0;
row = sdram_params->ch[0].cs0_row;
/*
* RK3188 share the rank and row bit15, we use same ddr config for 15bit
* and 16bit row
*/
if (row == 16)
row = 15;
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);
tmp |= ((row - 13) << 4);
size = sizeof(ddrconf_table)/sizeof(ddrconf_table[0]);
for (i = 0; i < size; i++)
if (tmp == ddrconf_table[i])

@ -0,0 +1,855 @@
/*
* (C) Copyright 2017 Rockchip Electronics Co., Ltd
*
* SPDX-License-Identifier: GPL-2.0
*/
#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_rk322x.h>
#include <asm/arch/grf_rk322x.h>
#include <asm/arch/hardware.h>
#include <asm/arch/sdram_rk322x.h>
#include <asm/arch/timer.h>
#include <asm/arch/uart.h>
#include <asm/arch/sdram_common.h>
#include <asm/types.h>
#include <linux/err.h>
DECLARE_GLOBAL_DATA_PTR;
struct chan_info {
struct rk322x_ddr_pctl *pctl;
struct rk322x_ddr_phy *phy;
struct rk322x_service_sys *msch;
};
struct dram_info {
struct chan_info chan[1];
struct ram_info info;
struct clk ddr_clk;
struct rk322x_cru *cru;
struct rk322x_grf *grf;
};
struct rk322x_sdram_params {
#if CONFIG_IS_ENABLED(OF_PLATDATA)
struct dtd_rockchip_rk3228_dmc of_plat;
#endif
struct rk322x_sdram_channel ch[1];
struct rk322x_pctl_timing pctl_timing;
struct rk322x_phy_timing phy_timing;
struct rk322x_base_params base;
int num_channels;
struct regmap *map;
};
#ifdef CONFIG_TPL_BUILD
/*
* [7:6] bank(n:n bit bank)
* [5:4] row(13+n)
* [3] cs(0:1 cs, 1:2 cs)
* [2:1] bank(n:n bit bank)
* [0] col(10+n)
*/
const char ddr_cfg_2_rbc[] = {
((0 << 6) | (0 << 4) | (0 << 3) | (1 << 2) | 1),
((0 << 6) | (1 << 4) | (0 << 3) | (1 << 2) | 1),
((0 << 6) | (2 << 4) | (0 << 3) | (1 << 2) | 1),
((0 << 6) | (3 << 4) | (0 << 3) | (1 << 2) | 1),
((0 << 6) | (1 << 4) | (0 << 3) | (1 << 2) | 2),
((0 << 6) | (2 << 4) | (0 << 3) | (1 << 2) | 2),
((0 << 6) | (3 << 4) | (0 << 3) | (1 << 2) | 2),
((0 << 6) | (0 << 4) | (0 << 3) | (1 << 2) | 0),
((0 << 6) | (1 << 4) | (0 << 3) | (1 << 2) | 0),
((0 << 6) | (2 << 4) | (0 << 3) | (1 << 2) | 0),
((0 << 6) | (3 << 4) | (0 << 3) | (1 << 2) | 0),
((0 << 6) | (2 << 4) | (0 << 3) | (0 << 2) | 1),
((1 << 6) | (1 << 4) | (0 << 3) | (0 << 2) | 2),
((1 << 6) | (1 << 4) | (0 << 3) | (0 << 2) | 1),
((0 << 6) | (3 << 4) | (1 << 3) | (1 << 2) | 1),
((0 << 6) | (3 << 4) | (1 << 3) | (1 << 2) | 0),
};
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++;
}
}
void phy_pctrl_reset(struct rk322x_cru *cru,
struct rk322x_ddr_phy *ddr_phy)
{
rk_clrsetreg(&cru->cru_softrst_con[5], 1 << DDRCTRL_PSRST_SHIFT |
1 << DDRCTRL_SRST_SHIFT | 1 << DDRPHY_PSRST_SHIFT |
1 << DDRPHY_SRST_SHIFT,
1 << DDRCTRL_PSRST_SHIFT | 1 << DDRCTRL_SRST_SHIFT |
1 << DDRPHY_PSRST_SHIFT | 1 << DDRPHY_SRST_SHIFT);
rockchip_udelay(10);
rk_clrreg(&cru->cru_softrst_con[5], 1 << DDRPHY_PSRST_SHIFT |
1 << DDRPHY_SRST_SHIFT);
rockchip_udelay(10);
rk_clrreg(&cru->cru_softrst_con[5], 1 << DDRCTRL_PSRST_SHIFT |
1 << DDRCTRL_SRST_SHIFT);
rockchip_udelay(10);
clrbits_le32(&ddr_phy->ddrphy_reg[0],
SOFT_RESET_MASK << SOFT_RESET_SHIFT);
rockchip_udelay(10);
setbits_le32(&ddr_phy->ddrphy_reg[0],
SOFT_DERESET_ANALOG);
rockchip_udelay(5);
setbits_le32(&ddr_phy->ddrphy_reg[0],
SOFT_DERESET_DIGITAL);
rockchip_udelay(1);
}
void phy_dll_bypass_set(struct rk322x_ddr_phy *ddr_phy, u32 freq)
{
u32 tmp;
setbits_le32(&ddr_phy->ddrphy_reg[0x13], 0x10);
setbits_le32(&ddr_phy->ddrphy_reg[0x26], 0x10);
setbits_le32(&ddr_phy->ddrphy_reg[0x36], 0x10);
setbits_le32(&ddr_phy->ddrphy_reg[0x46], 0x10);
setbits_le32(&ddr_phy->ddrphy_reg[0x56], 0x10);
clrbits_le32(&ddr_phy->ddrphy_reg[0x14], 0x8);
clrbits_le32(&ddr_phy->ddrphy_reg[0x27], 0x8);
clrbits_le32(&ddr_phy->ddrphy_reg[0x37], 0x8);
clrbits_le32(&ddr_phy->ddrphy_reg[0x47], 0x8);
clrbits_le32(&ddr_phy->ddrphy_reg[0x57], 0x8);
if (freq <= 400)
setbits_le32(&ddr_phy->ddrphy_reg[0xa4], 0x1f);
else
clrbits_le32(&ddr_phy->ddrphy_reg[0xa4], 0x1f);
if (freq <= 680)
tmp = 3;
else
tmp = 2;
writel(tmp, &ddr_phy->ddrphy_reg[0x28]);
writel(tmp, &ddr_phy->ddrphy_reg[0x38]);
writel(tmp, &ddr_phy->ddrphy_reg[0x48]);
writel(tmp, &ddr_phy->ddrphy_reg[0x58]);
}
static void send_command(struct rk322x_ddr_pctl *pctl,
u32 rank, u32 cmd, u32 arg)
{
writel((START_CMD | (rank << 20) | arg | cmd), &pctl->mcmd);
rockchip_udelay(1);
while (readl(&pctl->mcmd) & START_CMD)
;
}
static void memory_init(struct chan_info *chan,
struct rk322x_sdram_params *sdram_params)
{
struct rk322x_ddr_pctl *pctl = chan->pctl;
u32 dramtype = sdram_params->base.dramtype;
if (dramtype == DDR3) {
send_command(pctl, 3, DESELECT_CMD, 0);
rockchip_udelay(1);
send_command(pctl, 3, PREA_CMD, 0);
send_command(pctl, 3, MRS_CMD,
(0x02 & BANK_ADDR_MASK) << BANK_ADDR_SHIFT |
(sdram_params->phy_timing.mr[2] & CMD_ADDR_MASK) <<
CMD_ADDR_SHIFT);
send_command(pctl, 3, MRS_CMD,
(0x03 & BANK_ADDR_MASK) << BANK_ADDR_SHIFT |
(sdram_params->phy_timing.mr[3] & CMD_ADDR_MASK) <<
CMD_ADDR_SHIFT);
send_command(pctl, 3, MRS_CMD,
(0x01 & BANK_ADDR_MASK) << BANK_ADDR_SHIFT |
(sdram_params->phy_timing.mr[1] & CMD_ADDR_MASK) <<
CMD_ADDR_SHIFT);
send_command(pctl, 3, MRS_CMD,
(0x00 & BANK_ADDR_MASK) << BANK_ADDR_SHIFT |
((sdram_params->phy_timing.mr[0] |
DDR3_DLL_RESET) &
CMD_ADDR_MASK) << CMD_ADDR_SHIFT);
send_command(pctl, 3, ZQCL_CMD, 0);
} else {
send_command(pctl, 3, MRS_CMD,
(0x63 & LPDDR23_MA_MASK) << LPDDR23_MA_SHIFT |
(0 & LPDDR23_OP_MASK) <<
LPDDR23_OP_SHIFT);
rockchip_udelay(10);
send_command(pctl, 3, MRS_CMD,
(0x10 & LPDDR23_MA_MASK) << LPDDR23_MA_SHIFT |
(0xff & LPDDR23_OP_MASK) <<
LPDDR23_OP_SHIFT);
rockchip_udelay(1);
send_command(pctl, 3, MRS_CMD,
(0x10 & LPDDR23_MA_MASK) << LPDDR23_MA_SHIFT |
(0xff & LPDDR23_OP_MASK) <<
LPDDR23_OP_SHIFT);
rockchip_udelay(1);
send_command(pctl, 3, MRS_CMD,
(1 & LPDDR23_MA_MASK) << LPDDR23_MA_SHIFT |
(sdram_params->phy_timing.mr[1] &
LPDDR23_OP_MASK) << LPDDR23_OP_SHIFT);
send_command(pctl, 3, MRS_CMD,
(2 & LPDDR23_MA_MASK) << LPDDR23_MA_SHIFT |
(sdram_params->phy_timing.mr[2] &
LPDDR23_OP_MASK) << LPDDR23_OP_SHIFT);
send_command(pctl, 3, MRS_CMD,
(3 & LPDDR23_MA_MASK) << LPDDR23_MA_SHIFT |
(sdram_params->phy_timing.mr[3] &
LPDDR23_OP_MASK) << LPDDR23_OP_SHIFT);
if (dramtype == LPDDR3)
send_command(pctl, 3, MRS_CMD, (11 & LPDDR23_MA_MASK) <<
LPDDR23_MA_SHIFT |
(sdram_params->phy_timing.mr11 &
LPDDR23_OP_MASK) << LPDDR23_OP_SHIFT);
}
}
static u32 data_training(struct chan_info *chan)
{
struct rk322x_ddr_phy *ddr_phy = chan->phy;
struct rk322x_ddr_pctl *pctl = chan->pctl;
u32 value;
u32 bw = (readl(&ddr_phy->ddrphy_reg[0]) >> 4) & 0xf;
u32 ret;
/* disable auto refresh */
value = readl(&pctl->trefi) | (1 << 31);
writel(1 << 31, &pctl->trefi);
clrsetbits_le32(&ddr_phy->ddrphy_reg[2], 0x30,
DQS_SQU_CAL_SEL_CS0);
setbits_le32(&ddr_phy->ddrphy_reg[2], DQS_SQU_CAL_START);
rockchip_udelay(30);
ret = readl(&ddr_phy->ddrphy_reg[0xff]);
clrbits_le32(&ddr_phy->ddrphy_reg[2],
DQS_SQU_CAL_START);
/*
* since data training will take about 20us, so send some auto
* refresh(about 7.8us) to complement the lost time
*/
send_command(pctl, 3, PREA_CMD, 0);
send_command(pctl, 3, REF_CMD, 0);
writel(value, &pctl->trefi);
if (ret & 0x10) {
ret = -1;
} else {
ret = (ret & 0xf) ^ bw;
ret = (ret == 0) ? 0 : -1;
}
return ret;
}
static void move_to_config_state(struct rk322x_ddr_pctl *pctl)
{
unsigned int state;
while (1) {
state = readl(&pctl->stat) & PCTL_STAT_MASK;
switch (state) {
case LOW_POWER:
writel(WAKEUP_STATE, &pctl->sctl);
while ((readl(&pctl->stat) & PCTL_STAT_MASK)
!= ACCESS)
;
/*
* 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_MASK) != CONFIG)
;
break;
case CONFIG:
return;
default:
break;
}
}
}
static void move_to_access_state(struct rk322x_ddr_pctl *pctl)
{
unsigned int state;
while (1) {
state = readl(&pctl->stat) & PCTL_STAT_MASK;
switch (state) {
case LOW_POWER:
writel(WAKEUP_STATE, &pctl->sctl);
while ((readl(&pctl->stat) & PCTL_STAT_MASK) != ACCESS)
;
break;
case INIT_MEM:
writel(CFG_STATE, &pctl->sctl);
while ((readl(&pctl->stat) & PCTL_STAT_MASK) != CONFIG)
;
/* fallthrough */
case CONFIG:
writel(GO_STATE, &pctl->sctl);
while ((readl(&pctl->stat) & PCTL_STAT_MASK) != ACCESS)
;
break;
case ACCESS:
return;
default:
break;
}
}
}
static void move_to_lowpower_state(struct rk322x_ddr_pctl *pctl)
{
unsigned int state;
while (1) {
state = readl(&pctl->stat) & PCTL_STAT_MASK;
switch (state) {
case INIT_MEM:
writel(CFG_STATE, &pctl->sctl);
while ((readl(&pctl->stat) & PCTL_STAT_MASK) != CONFIG)
;
/* fallthrough */
case CONFIG:
writel(GO_STATE, &pctl->sctl);
while ((readl(&pctl->stat) & PCTL_STAT_MASK) != ACCESS)
;
break;
case ACCESS:
writel(SLEEP_STATE, &pctl->sctl);
while ((readl(&pctl->stat) & PCTL_STAT_MASK) !=
LOW_POWER)
;
break;
case LOW_POWER:
return;
default:
break;
}
}
}
/* pctl should in low power mode when call this function */
static void phy_softreset(struct dram_info *dram)
{
struct rk322x_ddr_phy *ddr_phy = dram->chan[0].phy;
struct rk322x_grf *grf = dram->grf;
writel(GRF_DDRPHY_BUFFEREN_CORE_EN, &grf->soc_con[0]);
clrbits_le32(&ddr_phy->ddrphy_reg[0], 0x3 << 2);
rockchip_udelay(1);
setbits_le32(&ddr_phy->ddrphy_reg[0], 1 << 2);
rockchip_udelay(5);
setbits_le32(&ddr_phy->ddrphy_reg[0], 1 << 3);
writel(GRF_DDRPHY_BUFFEREN_CORE_DIS, &grf->soc_con[0]);
}
/* bw: 2: 32bit, 1:16bit */
static void set_bw(struct dram_info *dram, u32 bw)
{
struct rk322x_ddr_pctl *pctl = dram->chan[0].pctl;
struct rk322x_ddr_phy *ddr_phy = dram->chan[0].phy;
struct rk322x_grf *grf = dram->grf;
if (bw == 1) {
setbits_le32(&pctl->ppcfg, 1);
clrbits_le32(&ddr_phy->ddrphy_reg[0], 0xc << 4);
writel(GRF_MSCH_NOC_16BIT_EN, &grf->soc_con[0]);
clrbits_le32(&ddr_phy->ddrphy_reg[0x46], 0x8);
clrbits_le32(&ddr_phy->ddrphy_reg[0x56], 0x8);
} else {
clrbits_le32(&pctl->ppcfg, 1);
setbits_le32(&ddr_phy->ddrphy_reg[0], 0xf << 4);
writel(GRF_DDR_32BIT_EN | GRF_MSCH_NOC_32BIT_EN,
&grf->soc_con[0]);
setbits_le32(&ddr_phy->ddrphy_reg[0x46], 0x8);
setbits_le32(&ddr_phy->ddrphy_reg[0x56], 0x8);
}
}
static void pctl_cfg(struct rk322x_ddr_pctl *pctl,
struct rk322x_sdram_params *sdram_params,
struct rk322x_grf *grf)
{
u32 burst_len;
u32 bw;
u32 dramtype = sdram_params->base.dramtype;
if (sdram_params->ch[0].bw == 2)
bw = GRF_DDR_32BIT_EN | GRF_MSCH_NOC_32BIT_EN;
else
bw = GRF_MSCH_NOC_16BIT_EN;
writel(DFI_INIT_START | DFI_DATA_BYTE_DISABLE_EN, &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(0x51010, &pctl->dfilpcfg0);
writel(1, &pctl->dfitphyupdtype0);
writel(0x0d, &pctl->dfitphyrdlat);
writel(0, &pctl->dfitphywrdata);
writel(0, &pctl->dfiupdcfg);
copy_to_reg(&pctl->togcnt1u, &sdram_params->pctl_timing.togcnt1u,
sizeof(struct rk322x_pctl_timing));
if (dramtype == DDR3) {
writel((1 << 3) | (1 << 11),
&pctl->dfiodtcfg);
writel(7 << 16, &pctl->dfiodtcfg1);
writel((readl(&pctl->tcl) - 1) / 2 - 1, &pctl->dfitrddataen);
writel((readl(&pctl->tcwl) - 1) / 2 - 1, &pctl->dfitphywrlat);
writel(500, &pctl->trsth);
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);
writel(bw | GRF_DDR3_EN, &grf->soc_con[0]);
} else {
if (sdram_params->phy_timing.bl & PHT_BL_8)
burst_len = MDDR_LPDDR2_BL_8;
else
burst_len = MDDR_LPDDR2_BL_4;
writel(readl(&pctl->tcl) / 2 - 1, &pctl->dfitrddataen);
writel(readl(&pctl->tcwl) / 2 - 1, &pctl->dfitphywrlat);
writel(0, &pctl->trsth);
if (dramtype == LPDDR2) {
writel(0 << MDDR_LPDDR2_CLK_STOP_IDLE_SHIFT |
LPDDR2_S4 | LPDDR2_EN | burst_len |
(6 - 4) << TFAW_SHIFT | PD_EXIT_FAST |
1 << PD_TYPE_SHIFT | 0 << PD_IDLE_SHIFT,
&pctl->mcfg);
writel(0, &pctl->dfiodtcfg);
writel(0, &pctl->dfiodtcfg1);
} else {
writel(0 << MDDR_LPDDR2_CLK_STOP_IDLE_SHIFT |
LPDDR2_S4 | LPDDR3_EN | burst_len |
(6 - 4) << TFAW_SHIFT | PD_EXIT_FAST |
1 << PD_TYPE_SHIFT | 0 << PD_IDLE_SHIFT,
&pctl->mcfg);
writel((1 << 3) | (1 << 2), &pctl->dfiodtcfg);
writel((7 << 16) | 4, &pctl->dfiodtcfg1);
}
writel(bw | GRF_LPDDR2_3_EN, &grf->soc_con[0]);
}
setbits_le32(&pctl->scfg, 1);
}
static void phy_cfg(struct chan_info *chan,
struct rk322x_sdram_params *sdram_params)
{
struct rk322x_ddr_phy *ddr_phy = chan->phy;
struct rk322x_service_sys *axi_bus = chan->msch;
struct rk322x_msch_timings *noc_timing = &sdram_params->base.noc_timing;
struct rk322x_phy_timing *phy_timing = &sdram_params->phy_timing;
struct rk322x_pctl_timing *pctl_timing = &sdram_params->pctl_timing;
u32 cmd_drv, clk_drv, dqs_drv, dqs_odt;
writel(noc_timing->ddrtiming, &axi_bus->ddrtiming);
writel(noc_timing->ddrmode, &axi_bus->ddrmode);
writel(noc_timing->readlatency, &axi_bus->readlatency);
writel(noc_timing->activate, &axi_bus->activate);
writel(noc_timing->devtodev, &axi_bus->devtodev);
switch (sdram_params->base.dramtype) {
case DDR3:
writel(PHY_DDR3 | phy_timing->bl, &ddr_phy->ddrphy_reg[1]);
break;
case LPDDR2:
writel(PHY_LPDDR2 | phy_timing->bl, &ddr_phy->ddrphy_reg[1]);
break;
default:
writel(PHY_LPDDR2 | phy_timing->bl, &ddr_phy->ddrphy_reg[1]);
break;
}
writel(phy_timing->cl_al, &ddr_phy->ddrphy_reg[0xb]);
writel(pctl_timing->tcwl, &ddr_phy->ddrphy_reg[0xc]);
cmd_drv = PHY_RON_RTT_34OHM;
clk_drv = PHY_RON_RTT_45OHM;
dqs_drv = PHY_RON_RTT_34OHM;
if (sdram_params->base.dramtype == LPDDR2)
dqs_odt = PHY_RON_RTT_DISABLE;
else
dqs_odt = PHY_RON_RTT_225OHM;
writel(cmd_drv, &ddr_phy->ddrphy_reg[0x11]);
clrsetbits_le32(&ddr_phy->ddrphy_reg[0x12], (0x1f << 3), cmd_drv << 3);
writel(clk_drv, &ddr_phy->ddrphy_reg[0x16]);
writel(clk_drv, &ddr_phy->ddrphy_reg[0x18]);
writel(dqs_drv, &ddr_phy->ddrphy_reg[0x20]);
writel(dqs_drv, &ddr_phy->ddrphy_reg[0x2f]);
writel(dqs_drv, &ddr_phy->ddrphy_reg[0x30]);
writel(dqs_drv, &ddr_phy->ddrphy_reg[0x3f]);
writel(dqs_drv, &ddr_phy->ddrphy_reg[0x40]);
writel(dqs_drv, &ddr_phy->ddrphy_reg[0x4f]);
writel(dqs_drv, &ddr_phy->ddrphy_reg[0x50]);
writel(dqs_drv, &ddr_phy->ddrphy_reg[0x5f]);
writel(dqs_odt, &ddr_phy->ddrphy_reg[0x21]);
writel(dqs_odt, &ddr_phy->ddrphy_reg[0x2e]);
writel(dqs_odt, &ddr_phy->ddrphy_reg[0x31]);
writel(dqs_odt, &ddr_phy->ddrphy_reg[0x3e]);
writel(dqs_odt, &ddr_phy->ddrphy_reg[0x41]);
writel(dqs_odt, &ddr_phy->ddrphy_reg[0x4e]);
writel(dqs_odt, &ddr_phy->ddrphy_reg[0x51]);
writel(dqs_odt, &ddr_phy->ddrphy_reg[0x5e]);
}
void dram_cfg_rbc(struct chan_info *chan,
struct rk322x_sdram_params *sdram_params)
{
char noc_config;
int i = 0;
struct rk322x_sdram_channel *config = &sdram_params->ch[0];
struct rk322x_service_sys *axi_bus = chan->msch;
move_to_config_state(chan->pctl);
if ((config->rank == 2) && (config->cs1_row == config->cs0_row)) {
if ((config->col + config->bw) == 12) {
i = 14;
goto finish;
} else if ((config->col + config->bw) == 11) {
i = 15;
goto finish;
}
}
noc_config = ((config->cs0_row - 13) << 4) | ((config->bk - 2) << 2) |
(config->col + config->bw - 11);
for (i = 0; i < 11; i++) {
if (noc_config == ddr_cfg_2_rbc[i])
break;
}
if (i < 11)
goto finish;
noc_config = ((config->bk - 2) << 6) | ((config->cs0_row - 13) << 4) |
(config->col + config->bw - 11);
for (i = 11; i < 14; i++) {
if (noc_config == ddr_cfg_2_rbc[i])
break;
}
if (i < 14)
goto finish;
else
i = 0;
finish:
writel(i, &axi_bus->ddrconf);
move_to_access_state(chan->pctl);
}
static void dram_all_config(const struct dram_info *dram,
struct rk322x_sdram_params *sdram_params)
{
struct rk322x_sdram_channel *info = &sdram_params->ch[0];
u32 sys_reg = 0;
sys_reg |= sdram_params->base.dramtype << SYS_REG_DDRTYPE_SHIFT;
sys_reg |= (1 - 1) << SYS_REG_NUM_CH_SHIFT;
sys_reg |= info->row_3_4 << SYS_REG_ROW_3_4_SHIFT(0);
sys_reg |= 1 << SYS_REG_CHINFO_SHIFT(0);
sys_reg |= (info->rank - 1) << SYS_REG_RANK_SHIFT(0);
sys_reg |= (info->col - 9) << SYS_REG_COL_SHIFT(0);
sys_reg |= info->bk == 3 ? 0 : 1 << SYS_REG_BK_SHIFT(0);
sys_reg |= (info->cs0_row - 13) << SYS_REG_CS0_ROW_SHIFT(0);
sys_reg |= (info->cs1_row - 13) << SYS_REG_CS1_ROW_SHIFT(0);
sys_reg |= (2 >> info->bw) << SYS_REG_BW_SHIFT(0);
sys_reg |= (2 >> info->dbw) << SYS_REG_DBW_SHIFT(0);
writel(sys_reg, &dram->grf->os_reg[2]);
}
#define TEST_PATTEN 0x5aa5f00f
static int dram_cap_detect(struct dram_info *dram,
struct rk322x_sdram_params *sdram_params)
{
u32 bw, row, col, addr;
u32 ret = 0;
struct rk322x_service_sys *axi_bus = dram->chan[0].msch;
if (sdram_params->base.dramtype == DDR3)
sdram_params->ch[0].dbw = 1;
else
sdram_params->ch[0].dbw = 2;
move_to_config_state(dram->chan[0].pctl);
/* bw detect */
set_bw(dram, 2);
if (data_training(&dram->chan[0]) == 0) {
bw = 2;
} else {
bw = 1;
set_bw(dram, 1);
move_to_lowpower_state(dram->chan[0].pctl);
phy_softreset(dram);
move_to_config_state(dram->chan[0].pctl);
if (data_training(&dram->chan[0])) {
printf("BW detect error\n");
ret = -EINVAL;
}
}
sdram_params->ch[0].bw = bw;
sdram_params->ch[0].bk = 3;
if (bw == 2)
writel(6, &axi_bus->ddrconf);
else
writel(3, &axi_bus->ddrconf);
move_to_access_state(dram->chan[0].pctl);
for (col = 11; col >= 9; col--) {
writel(0, CONFIG_SYS_SDRAM_BASE);
addr = CONFIG_SYS_SDRAM_BASE +
(1 << (col + 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[0].col = col;
}
writel(10, &axi_bus->ddrconf);
/* Detect row*/
for (row = 16; row >= 12; row--) {
writel(0, CONFIG_SYS_SDRAM_BASE);
addr = CONFIG_SYS_SDRAM_BASE + (1u << (row + 11 + 3 - 1));
writel(TEST_PATTEN, addr);
if ((readl(addr) == TEST_PATTEN) &&
(readl(CONFIG_SYS_SDRAM_BASE) == 0))
break;
}
if (row == 11) {
printf("Row detect error\n");
ret = -EINVAL;
} else {
sdram_params->ch[0].cs1_row = row;
sdram_params->ch[0].row_3_4 = 0;
sdram_params->ch[0].cs0_row = row;
}
/* cs detect */
writel(0, CONFIG_SYS_SDRAM_BASE);
writel(TEST_PATTEN, CONFIG_SYS_SDRAM_BASE + (1u << 30));
writel(~TEST_PATTEN, CONFIG_SYS_SDRAM_BASE + (1u << 30) + 4);
if ((readl(CONFIG_SYS_SDRAM_BASE + (1u << 30)) == TEST_PATTEN) &&
(readl(CONFIG_SYS_SDRAM_BASE) == 0))
sdram_params->ch[0].rank = 2;
else
sdram_params->ch[0].rank = 1;
out:
return ret;
}
static int sdram_init(struct dram_info *dram,
struct rk322x_sdram_params *sdram_params)
{
int ret;
ret = clk_set_rate(&dram->ddr_clk,
sdram_params->base.ddr_freq * MHz * 2);
if (ret < 0) {
printf("Could not set DDR clock\n");
return ret;
}
phy_pctrl_reset(dram->cru, dram->chan[0].phy);
phy_dll_bypass_set(dram->chan[0].phy, sdram_params->base.ddr_freq);
pctl_cfg(dram->chan[0].pctl, sdram_params, dram->grf);
phy_cfg(&dram->chan[0], sdram_params);
writel(POWER_UP_START, &dram->chan[0].pctl->powctl);
while (!(readl(&dram->chan[0].pctl->powstat) & POWER_UP_DONE))
;
memory_init(&dram->chan[0], sdram_params);
move_to_access_state(dram->chan[0].pctl);
ret = dram_cap_detect(dram, sdram_params);
if (ret)
goto out;
dram_cfg_rbc(&dram->chan[0], sdram_params);
dram_all_config(dram, sdram_params);
out:
return ret;
}
static int rk322x_dmc_ofdata_to_platdata(struct udevice *dev)
{
#if !CONFIG_IS_ENABLED(OF_PLATDATA)
struct rk322x_sdram_params *params = dev_get_platdata(dev);
const void *blob = gd->fdt_blob;
int node = dev_of_offset(dev);
int ret;
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_TPL_BUILD */
#if CONFIG_IS_ENABLED(OF_PLATDATA)
static int conv_of_platdata(struct udevice *dev)
{
struct rk322x_sdram_params *plat = dev_get_platdata(dev);
struct dtd_rockchip_rk322x_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));
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 rk322x_dmc_probe(struct udevice *dev)
{
#ifdef CONFIG_TPL_BUILD
struct rk322x_sdram_params *plat = dev_get_platdata(dev);
int ret;
struct udevice *dev_clk;
#endif
struct dram_info *priv = dev_get_priv(dev);
priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
#ifdef CONFIG_TPL_BUILD
#if CONFIG_IS_ENABLED(OF_PLATDATA)
ret = conv_of_platdata(dev);
if (ret)
return ret;
#endif
priv->chan[0].msch = syscon_get_first_range(ROCKCHIP_SYSCON_MSCH);
priv->chan[0].pctl = regmap_get_range(plat->map, 0);
priv->chan[0].phy = regmap_get_range(plat->map, 1);
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);
ret = sdram_init(priv, plat);
if (ret)
return ret;
#else
priv->info.base = CONFIG_SYS_SDRAM_BASE;
priv->info.size = rockchip_sdram_size(
(phys_addr_t)&priv->grf->os_reg[2]);
#endif
return 0;
}
static int rk322x_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 rk322x_dmc_ops = {
.get_info = rk322x_dmc_get_info,
};
static const struct udevice_id rk322x_dmc_ids[] = {
{ .compatible = "rockchip,rk3228-dmc" },
{ }
};
U_BOOT_DRIVER(dmc_rk322x) = {
.name = "rockchip_rk322x_dmc",
.id = UCLASS_RAM,
.of_match = rk322x_dmc_ids,
.ops = &rk322x_dmc_ops,
#ifdef CONFIG_TPL_BUILD
.ofdata_to_platdata = rk322x_dmc_ofdata_to_platdata,
#endif
.probe = rk322x_dmc_probe,
.priv_auto_alloc_size = sizeof(struct dram_info),
#ifdef CONFIG_TPL_BUILD
.platdata_auto_alloc_size = sizeof(struct rk322x_sdram_params),
#endif
};

@ -10,12 +10,6 @@
#include <configs/rk3399_common.h>
#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)

@ -32,7 +32,11 @@
#define CONFIG_SYS_INIT_SP_ADDR 0x00100000
#define CONFIG_SYS_LOAD_ADDR 0x00800800
#define CONFIG_SPL_STACK 0xff718000
#define CONFIG_SPL_TEXT_BASE 0xff704004
#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_TPL_BOOTROM_SUPPORT)
# define CONFIG_SPL_TEXT_BASE 0x0
#else
# define CONFIG_SPL_TEXT_BASE 0xff704004
#endif
/* MMC/SD IP block */
#define CONFIG_BOUNCE_BUFFER

@ -20,4 +20,21 @@
#define CONFIG_SYS_MMC_ENV_DEV 1
#undef CONFIG_CMD_USB_MASS_STORAGE
#ifndef CONFIG_TPL_BUILD
#define CONFIG_SPL_OS_BOOT
/* Falcon Mode */
#define CONFIG_SPL_FS_LOAD_ARGS_NAME "args"
#define CONFIG_SPL_FS_LOAD_KERNEL_NAME "uImage"
#define CONFIG_CMD_SPL
#define CONFIG_SYS_SPL_ARGS_ADDR 0x0ffe5000
#define CONFIG_CMD_SPL_WRITE_SIZE (128 * SZ_1K)
/* Falcon Mode - MMC support: args@1MB kernel@2MB */
#define CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR 0x800 /* 1MB */
#define CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS (CONFIG_CMD_SPL_WRITE_SIZE / 512)
#define CONFIG_SYS_MMCSD_RAW_MODE_KERNEL_SECTOR 0x1000 /* 2MB */
#endif
#endif

@ -39,6 +39,7 @@
#define SCLK_MAC_TX 88
#define SCLK_MACREF 89
#define SCLK_MACREF_OUT 90
#define SCLK_SARADC 91
/* aclk gates */
@ -67,6 +68,7 @@
#define PCLK_TIMER 270
#define PCLK_PERI 271
#define PCLK_GMAC 272
#define PCLK_SARADC 273
/* hclk gates */
#define HCLK_I2S0_8CH 320

@ -73,6 +73,7 @@ struct spl_info {
static struct spl_info spl_infos[] = {
{ "rk3036", "RK30", 0x1000, false, false },
{ "rk3128", "RK31", 0x1800, false, false },
{ "rk3188", "RK31", 0x8000 - 0x800, true, false },
{ "rk322x", "RK32", 0x8000 - 0x1000, false, false },
{ "rk3288", "RK32", 0x8000, false, false },

Loading…
Cancel
Save