mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-10 15:14:43 +00:00
Merge git://git.denx.de/u-boot-rockchip
This commit is contained in:
commit
16d4ff76c5
61 changed files with 2463 additions and 151 deletions
|
@ -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,
|
||||
|
|
581
arch/arm/include/asm/arch-rockchip/sdram_rk322x.h
Normal file
581
arch/arm/include/asm/arch-rockchip/sdram_rk322x.h
Normal file
|
@ -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
|
||||
|
|
84
arch/arm/mach-rockchip/rk3288-board-tpl.c
Normal file
84
arch/arm/mach-rockchip/rk3288-board-tpl.c
Normal file
|
@ -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,62 +3,50 @@
|
|||
*
|
||||
* 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", ®ulator);
|
||||
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", ®ulator);
|
||||
if (ret) {
|
||||
debug("%s vcc5v0_host init fail! ret %d\n", __func__, ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = regulator_set_enable(regulator, true);
|
||||
if (ret) {
|
||||
debug("%s vcc5v0-host-en set fail!\n", __func__);
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
return 0;
|
||||
}
|
||||
|
||||
void spl_board_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
#if CONFIG_IS_ENABLED(CMD_NET)
|
||||
|
@ -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
|
||||
|
|
183
drivers/adc/rockchip-saradc.c
Normal file
183
drivers/adc/rockchip-saradc.c
Normal file
|
@ -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])
|
855
drivers/ram/rockchip/sdram_rk322x.c
Normal file
855
drivers/ram/rockchip/sdram_rk322x.c
Normal file
|
@ -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 *)¶ms->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 *)¶ms->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 *)¶ms->base,
|
||||
sizeof(params->base) / sizeof(u32));
|
||||
if (ret) {
|
||||
printf("%s: Cannot read rockchip,sdram-params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
ret = regmap_init_mem(dev, ¶ms->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…
Reference in a new issue