- Fix for Rockchip mmc HS400 mode;
- Fix for px30 board Odroid Go;
- rockchip_sfc update;
- rk3568 clk update;
- doc fix;
This commit is contained in:
Tom Rini 2021-10-17 21:13:49 -04:00
commit d990f7d75d
14 changed files with 121 additions and 104 deletions

View File

@ -967,7 +967,7 @@
clocks = <&cru SCLK_SFC>, <&cru HCLK_SFC>;
clock-names = "clk_sfc", "hclk_sfc";
pinctrl-names = "default";
pinctrl-0 = <&sfc_clk &sfc_cs &sfc_bus4>;
pinctrl-0 = <&sfc_clk &sfc_cs0 &sfc_bus4>;
power-domains = <&power PX30_PD_MMC_NAND>;
status = "disabled";
};
@ -1953,7 +1953,7 @@
<1 RK_PA1 3 &pcfg_pull_none>;
};
sfc_cs: sfc-cs {
sfc_cs0: sfc-cs0 {
rockchip,pins =
<1 RK_PA4 3 &pcfg_pull_none>;
};

View File

@ -18,8 +18,18 @@
};
};
/* U-Boot clk driver for px30 cannot set GPU_CLK */
&cru {
u-boot,dm-pre-reloc;
assigned-clocks = <&cru PLL_NPLL>,
<&cru ACLK_BUS_PRE>, <&cru ACLK_PERI_PRE>,
<&cru HCLK_BUS_PRE>, <&cru HCLK_PERI_PRE>,
<&cru PCLK_BUS_PRE>, <&cru PLL_CPLL>;
assigned-clock-rates = <1188000000>,
<200000000>, <200000000>,
<150000000>, <150000000>,
<100000000>, <17000000>;
};
&dmc {
@ -70,7 +80,7 @@
u-boot,dm-pre-reloc;
};
&spi_flash {
&{/sfc@ff3a0000/flash@0} {
u-boot,dm-pre-reloc;
};

View File

@ -618,18 +618,18 @@
};
&sfc {
pinctrl-0 = <&sfc_clk &sfc_cs0 &sfc_bus2>;
pinctrl-names = "default";
#address-cells = <1>;
#size-cells = <0>;
pinctrl-names = "default";
pinctrl-0 = <&sfc_clk &sfc_cs &sfc_bus2>;
status = "okay";
spi_flash: xt25f128b@0 {
flash@0 {
compatible = "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <108000000>;
spi-rx-bus-width = <2>;
spi-tx-bus-width = <2>;
spi-tx-bus-width = <1>;
};
};

View File

@ -14,7 +14,7 @@
#define APLL_HZ (816 * MHz)
#define GPLL_HZ (1188 * MHz)
#define CPLL_HZ (1000 * MHz)
#define PPLL_HZ (100 * MHz)
#define PPLL_HZ (200 * MHz)
/* RK3568 pll id */
enum rk3568_pll_id {

View File

@ -96,7 +96,6 @@ CONFIG_USB=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_GENERIC=y
CONFIG_USB_DWC2=y
CONFIG_ROCKCHIP_USB2_PHY=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_DWC2_OTG=y
CONFIG_SPL_TINY_MEMSET=y

View File

@ -53,7 +53,6 @@ CONFIG_USB_XHCI_DWC3=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_GENERIC=y
CONFIG_USB_DWC3=y
CONFIG_ROCKCHIP_USB2_PHY=y
CONFIG_USB_KEYBOARD=y
CONFIG_USB_HOST_ETHER=y
CONFIG_USB_ETHER_ASIX=y

View File

@ -71,7 +71,6 @@ CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_GENERIC=y
CONFIG_USB_DWC3=y
CONFIG_USB_DWC3_GENERIC=y
CONFIG_ROCKCHIP_USB2_PHY=y
CONFIG_USB_KEYBOARD=y
CONFIG_USB_HOST_ETHER=y
CONFIG_USB_ETHER_ASIX=y

View File

@ -68,7 +68,6 @@ CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_GENERIC=y
CONFIG_USB_DWC3=y
CONFIG_USB_DWC3_GENERIC=y
CONFIG_ROCKCHIP_USB2_PHY=y
CONFIG_USB_KEYBOARD=y
CONFIG_USB_HOST_ETHER=y
CONFIG_USB_ETHER_ASIX=y

View File

@ -62,7 +62,6 @@ CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_GENERIC=y
CONFIG_USB_DWC3=y
CONFIG_USB_DWC3_GENERIC=y
CONFIG_ROCKCHIP_USB2_PHY=y
CONFIG_USB_KEYBOARD=y
# CONFIG_USB_KEYBOARD_FN_KEYS is not set
CONFIG_USB_GADGET=y

View File

@ -16,16 +16,18 @@ Rockchip boards
Rockchip is SoC solutions provider for tablets & PCs, streaming media
TV boxes, AI audio & vision, IoT hardware.
A wide range of Rockchip SoCs with associated boardsare supported in
A wide range of Rockchip SoCs with associated boards are supported in
mainline U-Boot.
List of mainline supported rockchip boards:
List of mainline supported Rockchip boards:
* rk3036
- Rockchip Evb-RK3036 (evb-rk3036)
- Kylin (kylin_rk3036)
* rk3128
- Rockchip Evb-RK3128 (evb-rk3128)
* rk3188
- Radxa Rock (rock)
* rk3229
- Rockchip Evb-RK3229 (evb-rk3229)
* rk3288
@ -75,8 +77,6 @@ List of mainline supported rockchip boards:
* rv1108
- Rockchip Evb-rv1108 (evb-rv1108)
- Elgin-R1 (elgin-rv1108)
* rv3188
- Radxa Rock (rock)
Building
--------
@ -93,7 +93,7 @@ To build TF-A::
make realclean
make CROSS_COMPILE=aarch64-linux-gnu- PLAT=rk3399
Specify the PLAT= with desired rockchip platform to build TF-A for.
Specify the PLAT= with desired Rockchip platform to build TF-A for.
U-Boot
^^^^^^
@ -130,7 +130,7 @@ Flashing
SD Card
^^^^^^^
All rockchip platforms, except rk3128 (which doesn't use SPL) are now
All Rockchip platforms, except rk3128 (which doesn't use SPL) are now
supporting single boot image using binman and pad_cat.
To write an image that boots from an SD card (assumed to be /dev/sda)::
@ -141,7 +141,7 @@ To write an image that boots from an SD card (assumed to be /dev/sda)::
eMMC
^^^^
eMMC flash would probe on mmc0 in most of the rockchip platforms.
eMMC flash would probe on mmc0 in most of the Rockchip platforms.
Create GPT partition layout as defined in configurations::
@ -164,7 +164,7 @@ Program the flash::
sudo fastboot -i 0x2207 flash loader1 idbloader.img
sudo fastboot -i 0x2207 flash loader2 u-boot.itb
Note: for rockchip 32-bit platforms the U-Boot proper image
Note: for Rockchip 32-bit platforms the U-Boot proper image
is u-boot-dtb.img
SPI
@ -227,8 +227,8 @@ Note:
TODO
----
- Add rockchip idbloader image building
- Add rockchip TPL image building
- Add Rockchip idbloader image building
- Add Rockchip TPL image building
- Document SPI flash boot
- Add missing SoC's with it boards list

View File

@ -1291,6 +1291,9 @@ static ulong px30_clk_set_rate(struct clk *clk, ulong rate)
case PLL_NPLL:
ret = px30_clk_set_pll_rate(priv, NPLL, rate);
break;
case PLL_CPLL:
ret = px30_clk_set_pll_rate(priv, CPLL, rate);
break;
case ARMCLK:
ret = px30_armclk_set_clk(priv, rate);
break;

View File

@ -1441,6 +1441,7 @@ static ulong rk3568_sdmmc_set_clk(struct rk3568_clk_priv *priv,
switch (rate) {
case OSC_HZ:
case 26 * MHz:
src_clk = CLK_SDMMC_SEL_24M;
break;
case 400 * MHz:
@ -1507,7 +1508,7 @@ static ulong rk3568_sfc_get_clk(struct rk3568_clk_priv *priv)
case SCLK_SFC_SEL_125M:
return 125 * MHz;
case SCLK_SFC_SEL_150M:
return 150 * KHz;
return 150 * MHz;
default:
return -ENOENT;
}
@ -1534,7 +1535,7 @@ static ulong rk3568_sfc_set_clk(struct rk3568_clk_priv *priv, ulong rate)
case 125 * MHz:
src_clk = SCLK_SFC_SEL_125M;
break;
case 150 * KHz:
case 150 * MHz:
src_clk = SCLK_SFC_SEL_150M;
break;
default:
@ -2406,6 +2407,9 @@ static ulong rk3568_clk_get_rate(struct clk *clk)
case BCLK_EMMC:
rate = rk3568_emmc_get_bclk(priv);
break;
case TCLK_EMMC:
rate = OSC_HZ;
break;
#ifndef CONFIG_SPL_BUILD
case ACLK_VOP:
rate = rk3568_aclk_vop_get_clk(priv);
@ -2582,6 +2586,9 @@ static ulong rk3568_clk_set_rate(struct clk *clk, ulong rate)
case BCLK_EMMC:
ret = rk3568_emmc_set_bclk(priv, rate);
break;
case TCLK_EMMC:
ret = OSC_HZ;
break;
#ifndef CONFIG_SPL_BUILD
case ACLK_VOP:
ret = rk3568_aclk_vop_set_clk(priv, rate);

View File

@ -143,6 +143,9 @@ static void rk3399_emmc_phy_power_on(struct rockchip_emmc_phy *phy, u32 clock)
writel(RK_CLRSETBITS(3 << 12, freqsel << 12), &phy->emmcphy_con[0]);
writel(RK_CLRSETBITS(1 << 1, 1 << 1), &phy->emmcphy_con[6]);
/* REN Enable on STRB Line for HS400 */
writel(RK_CLRSETBITS(0, 1 << 9), &phy->emmcphy_con[2]);
read_poll_timeout(readl, &phy->emmcphy_status, dllrdy,
PHYCTRL_DLL_LOCK_WO_TMOUT(dllrdy), 1, 5000);
}

View File

@ -116,6 +116,7 @@
/* Master trigger */
#define SFC_DMA_TRIGGER 0x80
#define SFC_DMA_TRIGGER_START 1
/* Src or Dst addr for master */
#define SFC_DMA_ADDR 0x84
@ -163,14 +164,12 @@
#define SFC_DMA_TRANS_THRETHOLD (0x40)
/* Maximum clock values from datasheet suggest keeping clock value under
* 150MHz. No minimum or average value is suggested, but the U-boot BSP driver
* has a minimum of 10MHz and a default of 80MHz which seems reasonable.
* 150MHz. No minimum or average value is suggested.
*/
#define SFC_MIN_SPEED_HZ (10 * 1000 * 1000)
#define SFC_DEFAULT_SPEED_HZ (80 * 1000 * 1000)
#define SFC_MAX_SPEED_HZ (150 * 1000 * 1000)
#define SFC_MAX_SPEED (150 * 1000 * 1000)
struct rockchip_sfc {
struct udevice *dev;
void __iomem *regbase;
struct clk hclk;
struct clk clk;
@ -197,8 +196,6 @@ static int rockchip_sfc_reset(struct rockchip_sfc *sfc)
/* Still need to clear the masked interrupt from RISR */
writel(0xFFFFFFFF, sfc->regbase + SFC_ICLR);
debug("reset\n");
return err;
}
@ -261,15 +258,11 @@ static int rockchip_sfc_probe(struct udevice *bus)
#if CONFIG_IS_ENABLED(CLK)
ret = clk_enable(&sfc->hclk);
if (ret)
debug("Enable ahb clock fail %s: %d\n", bus->name, ret);
dev_dbg(sfc->dev, "sfc Enable ahb clock fail %s: %d\n", bus->name, ret);
ret = clk_enable(&sfc->clk);
if (ret)
debug("Enable clock fail for %s: %d\n", bus->name, ret);
ret = clk_set_rate(&sfc->clk, SFC_DEFAULT_SPEED_HZ);
if (ret)
debug("Could not set sfc clock for %s: %d\n", bus->name, ret);
dev_dbg(sfc->dev, "sfc Enable clock fail for %s: %d\n", bus->name, ret);
#endif
ret = rockchip_sfc_init(sfc);
@ -278,7 +271,8 @@ static int rockchip_sfc_probe(struct udevice *bus)
sfc->max_iosize = rockchip_sfc_get_max_iosize(sfc);
sfc->version = rockchip_sfc_get_version(sfc);
sfc->speed = SFC_DEFAULT_SPEED_HZ;
sfc->max_freq = SFC_MAX_SPEED;
sfc->dev = bus;
return 0;
@ -291,33 +285,38 @@ err_init:
return ret;
}
static inline int rockchip_sfc_get_fifo_level(struct rockchip_sfc *sfc, int wr)
static int rockchip_sfc_wait_txfifo_ready(struct rockchip_sfc *sfc, u32 timeout_us)
{
u32 fsr = readl(sfc->regbase + SFC_FSR);
int level;
int ret = 0;
u32 status;
if (wr)
level = (fsr & SFC_FSR_TXLV_MASK) >> SFC_FSR_TXLV_SHIFT;
else
level = (fsr & SFC_FSR_RXLV_MASK) >> SFC_FSR_RXLV_SHIFT;
ret = readl_poll_timeout(sfc->regbase + SFC_FSR, status,
status & SFC_FSR_TXLV_MASK,
timeout_us);
if (ret) {
dev_dbg(sfc->dev, "sfc wait tx fifo timeout\n");
return level;
}
static int rockchip_sfc_wait_fifo_ready(struct rockchip_sfc *sfc, int wr, u32 timeout)
{
unsigned long tbase = get_timer(0);
int level;
while (!(level = rockchip_sfc_get_fifo_level(sfc, wr))) {
if (get_timer(tbase) > timeout) {
debug("%s fifo timeout\n", wr ? "write" : "read");
return -ETIMEDOUT;
}
udelay(1);
return -ETIMEDOUT;
}
return level;
return (status & SFC_FSR_TXLV_MASK) >> SFC_FSR_TXLV_SHIFT;
}
static int rockchip_sfc_wait_rxfifo_ready(struct rockchip_sfc *sfc, u32 timeout_us)
{
int ret = 0;
u32 status;
ret = readl_poll_timeout(sfc->regbase + SFC_FSR, status,
status & SFC_FSR_RXLV_MASK,
timeout_us);
if (ret) {
dev_dbg(sfc->dev, "sfc wait rx fifo timeout\n");
return -ETIMEDOUT;
}
return (status & SFC_FSR_RXLV_MASK) >> SFC_FSR_RXLV_SHIFT;
}
static void rockchip_sfc_adjust_op_work(struct spi_mem_op *op)
@ -411,11 +410,11 @@ static int rockchip_sfc_xfer_setup(struct rockchip_sfc *sfc,
ctrl |= SFC_CTRL_PHASE_SEL_NEGETIVE;
cmd |= plat->cs << SFC_CMD_CS_SHIFT;
debug("addr.nbytes=%x(x%d) dummy.nbytes=%x(x%d)\n",
op->addr.nbytes, op->addr.buswidth,
op->dummy.nbytes, op->dummy.buswidth);
debug("ctrl=%x cmd=%x addr=%llx len=%x\n",
ctrl, cmd, op->addr.val, len);
dev_dbg(sfc->dev, "sfc addr.nbytes=%x(x%d) dummy.nbytes=%x(x%d)\n",
op->addr.nbytes, op->addr.buswidth,
op->dummy.nbytes, op->dummy.buswidth);
dev_dbg(sfc->dev, "sfc ctrl=%x cmd=%x addr=%llx len=%x\n",
ctrl, cmd, op->addr.val, len);
writel(ctrl, sfc->regbase + SFC_CTRL);
writel(cmd, sfc->regbase + SFC_CMD);
@ -435,7 +434,7 @@ static int rockchip_sfc_write_fifo(struct rockchip_sfc *sfc, const u8 *buf, int
dwords = len >> 2;
while (dwords) {
tx_level = rockchip_sfc_wait_fifo_ready(sfc, SFC_CMD_DIR_WR, 1000);
tx_level = rockchip_sfc_wait_txfifo_ready(sfc, 1000);
if (tx_level < 0)
return tx_level;
write_words = min_t(u32, tx_level, dwords);
@ -446,7 +445,7 @@ static int rockchip_sfc_write_fifo(struct rockchip_sfc *sfc, const u8 *buf, int
/* write the rest non word aligned bytes */
if (bytes) {
tx_level = rockchip_sfc_wait_fifo_ready(sfc, SFC_CMD_DIR_WR, 1000);
tx_level = rockchip_sfc_wait_txfifo_ready(sfc, 1000);
if (tx_level < 0)
return tx_level;
memcpy(&tmp, buf, bytes);
@ -467,7 +466,7 @@ static int rockchip_sfc_read_fifo(struct rockchip_sfc *sfc, u8 *buf, int len)
/* word aligned access only */
dwords = len >> 2;
while (dwords) {
rx_level = rockchip_sfc_wait_fifo_ready(sfc, SFC_CMD_DIR_RD, 1000);
rx_level = rockchip_sfc_wait_rxfifo_ready(sfc, 1000);
if (rx_level < 0)
return rx_level;
read_words = min_t(u32, rx_level, dwords);
@ -478,7 +477,7 @@ static int rockchip_sfc_read_fifo(struct rockchip_sfc *sfc, u8 *buf, int len)
/* read the rest non word aligned bytes */
if (bytes) {
rx_level = rockchip_sfc_wait_fifo_ready(sfc, SFC_CMD_DIR_RD, 1000);
rx_level = rockchip_sfc_wait_rxfifo_ready(sfc, 1000);
if (rx_level < 0)
return rx_level;
tmp = readl(sfc->regbase + SFC_DATA);
@ -492,7 +491,7 @@ static int rockchip_sfc_fifo_transfer_dma(struct rockchip_sfc *sfc, dma_addr_t d
{
writel(0xFFFFFFFF, sfc->regbase + SFC_ICLR);
writel((u32)dma_buf, sfc->regbase + SFC_DMA_ADDR);
writel(0x1, sfc->regbase + SFC_DMA_TRIGGER);
writel(SFC_DMA_TRIGGER_START, sfc->regbase + SFC_DMA_TRIGGER);
return len;
}
@ -500,7 +499,7 @@ static int rockchip_sfc_fifo_transfer_dma(struct rockchip_sfc *sfc, dma_addr_t d
static int rockchip_sfc_xfer_data_poll(struct rockchip_sfc *sfc,
const struct spi_mem_op *op, u32 len)
{
debug("xfer_poll len=%x\n", len);
dev_dbg(sfc->dev, "sfc xfer_poll len=%x\n", len);
if (op->data.dir == SPI_MEM_DATA_OUT)
return rockchip_sfc_write_fifo(sfc, op->data.buf.out, len);
@ -516,7 +515,7 @@ static int rockchip_sfc_xfer_data_dma(struct rockchip_sfc *sfc,
void *dma_buf;
int ret;
debug("xfer_dma len=%x\n", len);
dev_dbg(sfc->dev, "sfc xfer_dma len=%x\n", len);
if (op->data.dir == SPI_MEM_DATA_OUT) {
dma_buf = (void *)op->data.buf.out;
@ -539,19 +538,17 @@ static int rockchip_sfc_xfer_data_dma(struct rockchip_sfc *sfc,
static int rockchip_sfc_xfer_done(struct rockchip_sfc *sfc, u32 timeout_us)
{
unsigned long tbase = get_timer(0);
int ret = 0;
u32 timeout = timeout_us;
u32 status;
while (readl(sfc->regbase + SFC_SR) & SFC_SR_IS_BUSY) {
if (get_timer(tbase) > timeout) {
printf("wait sfc idle timeout\n");
rockchip_sfc_reset(sfc);
ret = readl_poll_timeout(sfc->regbase + SFC_SR, status,
!(status & SFC_SR_IS_BUSY),
timeout_us);
if (ret) {
dev_err(sfc->dev, "wait sfc idle timeout\n");
rockchip_sfc_reset(sfc);
return -ETIMEDOUT;
}
udelay(1);
ret = -EIO;
}
return ret;
@ -564,33 +561,16 @@ static int rockchip_sfc_exec_op(struct spi_slave *mem,
u32 len = min_t(u32, op->data.nbytes, sfc->max_iosize);
int ret;
#if CONFIG_IS_ENABLED(CLK)
if (unlikely(mem->max_hz != sfc->speed)) {
ret = clk_set_rate(&sfc->clk, clamp(mem->max_hz, (uint)SFC_MIN_SPEED_HZ,
(uint)SFC_MAX_SPEED_HZ));
if (ret < 0) {
printf("set_freq=%dHz fail, check if it's the cru support level\n",
mem->max_hz);
return ret;
}
sfc->max_freq = mem->max_hz;
sfc->speed = mem->max_hz;
debug("set_freq=%dHz real_freq=%dHz\n", sfc->max_freq, sfc->speed);
}
#endif
rockchip_sfc_adjust_op_work((struct spi_mem_op *)op);
rockchip_sfc_xfer_setup(sfc, mem, op, len);
if (len) {
if (likely(sfc->use_dma) && !(len & 0x3) && len >= SFC_DMA_TRANS_THRETHOLD)
if (likely(sfc->use_dma) && len >= SFC_DMA_TRANS_THRETHOLD)
ret = rockchip_sfc_xfer_data_dma(sfc, op, len);
else
ret = rockchip_sfc_xfer_data_poll(sfc, op, len);
if (ret != len) {
printf("xfer data failed ret %d dir %d\n", ret, op->data.dir);
dev_err(sfc->dev, "xfer data failed ret %d dir %d\n", ret, op->data.dir);
return -EIO;
}
@ -604,13 +584,32 @@ static int rockchip_sfc_adjust_op_size(struct spi_slave *mem, struct spi_mem_op
struct rockchip_sfc *sfc = dev_get_plat(mem->dev->parent);
op->data.nbytes = min(op->data.nbytes, sfc->max_iosize);
return 0;
}
static int rockchip_sfc_set_speed(struct udevice *bus, uint speed)
{
/* We set up speed later for each transmission.
*/
struct rockchip_sfc *sfc = dev_get_plat(bus);
if (speed > sfc->max_freq)
speed = sfc->max_freq;
if (speed == sfc->speed)
return 0;
#if CONFIG_IS_ENABLED(CLK)
int ret = clk_set_rate(&sfc->clk, speed);
if (ret < 0) {
dev_err(sfc->dev, "set_freq=%dHz fail, check if it's the cru support level\n",
speed);
return ret;
}
sfc->speed = speed;
#else
dev_dbg(sfc->dev, "sfc failed, CLK not support\n");
#endif
return 0;
}