Merge tag 'u-boot-rockchip-20211015' of https://source.denx.de/u-boot/custodians/u-boot-rockchip
- 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:
commit
d990f7d75d
@ -967,7 +967,7 @@
|
|||||||
clocks = <&cru SCLK_SFC>, <&cru HCLK_SFC>;
|
clocks = <&cru SCLK_SFC>, <&cru HCLK_SFC>;
|
||||||
clock-names = "clk_sfc", "hclk_sfc";
|
clock-names = "clk_sfc", "hclk_sfc";
|
||||||
pinctrl-names = "default";
|
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>;
|
power-domains = <&power PX30_PD_MMC_NAND>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
@ -1953,7 +1953,7 @@
|
|||||||
<1 RK_PA1 3 &pcfg_pull_none>;
|
<1 RK_PA1 3 &pcfg_pull_none>;
|
||||||
};
|
};
|
||||||
|
|
||||||
sfc_cs: sfc-cs {
|
sfc_cs0: sfc-cs0 {
|
||||||
rockchip,pins =
|
rockchip,pins =
|
||||||
<1 RK_PA4 3 &pcfg_pull_none>;
|
<1 RK_PA4 3 &pcfg_pull_none>;
|
||||||
};
|
};
|
||||||
|
@ -18,8 +18,18 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* U-Boot clk driver for px30 cannot set GPU_CLK */
|
||||||
&cru {
|
&cru {
|
||||||
u-boot,dm-pre-reloc;
|
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 {
|
&dmc {
|
||||||
@ -70,7 +80,7 @@
|
|||||||
u-boot,dm-pre-reloc;
|
u-boot,dm-pre-reloc;
|
||||||
};
|
};
|
||||||
|
|
||||||
&spi_flash {
|
&{/sfc@ff3a0000/flash@0} {
|
||||||
u-boot,dm-pre-reloc;
|
u-boot,dm-pre-reloc;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -618,18 +618,18 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
&sfc {
|
&sfc {
|
||||||
|
pinctrl-0 = <&sfc_clk &sfc_cs0 &sfc_bus2>;
|
||||||
|
pinctrl-names = "default";
|
||||||
#address-cells = <1>;
|
#address-cells = <1>;
|
||||||
#size-cells = <0>;
|
#size-cells = <0>;
|
||||||
pinctrl-names = "default";
|
|
||||||
pinctrl-0 = <&sfc_clk &sfc_cs &sfc_bus2>;
|
|
||||||
status = "okay";
|
status = "okay";
|
||||||
|
|
||||||
spi_flash: xt25f128b@0 {
|
flash@0 {
|
||||||
compatible = "jedec,spi-nor";
|
compatible = "jedec,spi-nor";
|
||||||
reg = <0>;
|
reg = <0>;
|
||||||
spi-max-frequency = <108000000>;
|
spi-max-frequency = <108000000>;
|
||||||
spi-rx-bus-width = <2>;
|
spi-rx-bus-width = <2>;
|
||||||
spi-tx-bus-width = <2>;
|
spi-tx-bus-width = <1>;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
#define APLL_HZ (816 * MHz)
|
#define APLL_HZ (816 * MHz)
|
||||||
#define GPLL_HZ (1188 * MHz)
|
#define GPLL_HZ (1188 * MHz)
|
||||||
#define CPLL_HZ (1000 * MHz)
|
#define CPLL_HZ (1000 * MHz)
|
||||||
#define PPLL_HZ (100 * MHz)
|
#define PPLL_HZ (200 * MHz)
|
||||||
|
|
||||||
/* RK3568 pll id */
|
/* RK3568 pll id */
|
||||||
enum rk3568_pll_id {
|
enum rk3568_pll_id {
|
||||||
|
@ -96,7 +96,6 @@ CONFIG_USB=y
|
|||||||
CONFIG_USB_EHCI_HCD=y
|
CONFIG_USB_EHCI_HCD=y
|
||||||
CONFIG_USB_EHCI_GENERIC=y
|
CONFIG_USB_EHCI_GENERIC=y
|
||||||
CONFIG_USB_DWC2=y
|
CONFIG_USB_DWC2=y
|
||||||
CONFIG_ROCKCHIP_USB2_PHY=y
|
|
||||||
CONFIG_USB_GADGET=y
|
CONFIG_USB_GADGET=y
|
||||||
CONFIG_USB_GADGET_DWC2_OTG=y
|
CONFIG_USB_GADGET_DWC2_OTG=y
|
||||||
CONFIG_SPL_TINY_MEMSET=y
|
CONFIG_SPL_TINY_MEMSET=y
|
||||||
|
@ -53,7 +53,6 @@ CONFIG_USB_XHCI_DWC3=y
|
|||||||
CONFIG_USB_EHCI_HCD=y
|
CONFIG_USB_EHCI_HCD=y
|
||||||
CONFIG_USB_EHCI_GENERIC=y
|
CONFIG_USB_EHCI_GENERIC=y
|
||||||
CONFIG_USB_DWC3=y
|
CONFIG_USB_DWC3=y
|
||||||
CONFIG_ROCKCHIP_USB2_PHY=y
|
|
||||||
CONFIG_USB_KEYBOARD=y
|
CONFIG_USB_KEYBOARD=y
|
||||||
CONFIG_USB_HOST_ETHER=y
|
CONFIG_USB_HOST_ETHER=y
|
||||||
CONFIG_USB_ETHER_ASIX=y
|
CONFIG_USB_ETHER_ASIX=y
|
||||||
|
@ -71,7 +71,6 @@ CONFIG_USB_EHCI_HCD=y
|
|||||||
CONFIG_USB_EHCI_GENERIC=y
|
CONFIG_USB_EHCI_GENERIC=y
|
||||||
CONFIG_USB_DWC3=y
|
CONFIG_USB_DWC3=y
|
||||||
CONFIG_USB_DWC3_GENERIC=y
|
CONFIG_USB_DWC3_GENERIC=y
|
||||||
CONFIG_ROCKCHIP_USB2_PHY=y
|
|
||||||
CONFIG_USB_KEYBOARD=y
|
CONFIG_USB_KEYBOARD=y
|
||||||
CONFIG_USB_HOST_ETHER=y
|
CONFIG_USB_HOST_ETHER=y
|
||||||
CONFIG_USB_ETHER_ASIX=y
|
CONFIG_USB_ETHER_ASIX=y
|
||||||
|
@ -68,7 +68,6 @@ CONFIG_USB_EHCI_HCD=y
|
|||||||
CONFIG_USB_EHCI_GENERIC=y
|
CONFIG_USB_EHCI_GENERIC=y
|
||||||
CONFIG_USB_DWC3=y
|
CONFIG_USB_DWC3=y
|
||||||
CONFIG_USB_DWC3_GENERIC=y
|
CONFIG_USB_DWC3_GENERIC=y
|
||||||
CONFIG_ROCKCHIP_USB2_PHY=y
|
|
||||||
CONFIG_USB_KEYBOARD=y
|
CONFIG_USB_KEYBOARD=y
|
||||||
CONFIG_USB_HOST_ETHER=y
|
CONFIG_USB_HOST_ETHER=y
|
||||||
CONFIG_USB_ETHER_ASIX=y
|
CONFIG_USB_ETHER_ASIX=y
|
||||||
|
@ -62,7 +62,6 @@ CONFIG_USB_EHCI_HCD=y
|
|||||||
CONFIG_USB_EHCI_GENERIC=y
|
CONFIG_USB_EHCI_GENERIC=y
|
||||||
CONFIG_USB_DWC3=y
|
CONFIG_USB_DWC3=y
|
||||||
CONFIG_USB_DWC3_GENERIC=y
|
CONFIG_USB_DWC3_GENERIC=y
|
||||||
CONFIG_ROCKCHIP_USB2_PHY=y
|
|
||||||
CONFIG_USB_KEYBOARD=y
|
CONFIG_USB_KEYBOARD=y
|
||||||
# CONFIG_USB_KEYBOARD_FN_KEYS is not set
|
# CONFIG_USB_KEYBOARD_FN_KEYS is not set
|
||||||
CONFIG_USB_GADGET=y
|
CONFIG_USB_GADGET=y
|
||||||
|
@ -16,16 +16,18 @@ Rockchip boards
|
|||||||
Rockchip is SoC solutions provider for tablets & PCs, streaming media
|
Rockchip is SoC solutions provider for tablets & PCs, streaming media
|
||||||
TV boxes, AI audio & vision, IoT hardware.
|
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.
|
mainline U-Boot.
|
||||||
|
|
||||||
List of mainline supported rockchip boards:
|
List of mainline supported Rockchip boards:
|
||||||
|
|
||||||
* rk3036
|
* rk3036
|
||||||
- Rockchip Evb-RK3036 (evb-rk3036)
|
- Rockchip Evb-RK3036 (evb-rk3036)
|
||||||
- Kylin (kylin_rk3036)
|
- Kylin (kylin_rk3036)
|
||||||
* rk3128
|
* rk3128
|
||||||
- Rockchip Evb-RK3128 (evb-rk3128)
|
- Rockchip Evb-RK3128 (evb-rk3128)
|
||||||
|
* rk3188
|
||||||
|
- Radxa Rock (rock)
|
||||||
* rk3229
|
* rk3229
|
||||||
- Rockchip Evb-RK3229 (evb-rk3229)
|
- Rockchip Evb-RK3229 (evb-rk3229)
|
||||||
* rk3288
|
* rk3288
|
||||||
@ -75,8 +77,6 @@ List of mainline supported rockchip boards:
|
|||||||
* rv1108
|
* rv1108
|
||||||
- Rockchip Evb-rv1108 (evb-rv1108)
|
- Rockchip Evb-rv1108 (evb-rv1108)
|
||||||
- Elgin-R1 (elgin-rv1108)
|
- Elgin-R1 (elgin-rv1108)
|
||||||
* rv3188
|
|
||||||
- Radxa Rock (rock)
|
|
||||||
|
|
||||||
Building
|
Building
|
||||||
--------
|
--------
|
||||||
@ -93,7 +93,7 @@ To build TF-A::
|
|||||||
make realclean
|
make realclean
|
||||||
make CROSS_COMPILE=aarch64-linux-gnu- PLAT=rk3399
|
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
|
U-Boot
|
||||||
^^^^^^
|
^^^^^^
|
||||||
@ -130,7 +130,7 @@ Flashing
|
|||||||
SD Card
|
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.
|
supporting single boot image using binman and pad_cat.
|
||||||
|
|
||||||
To write an image that boots from an SD card (assumed to be /dev/sda)::
|
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
|
||||||
^^^^
|
^^^^
|
||||||
|
|
||||||
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::
|
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 loader1 idbloader.img
|
||||||
sudo fastboot -i 0x2207 flash loader2 u-boot.itb
|
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
|
is u-boot-dtb.img
|
||||||
|
|
||||||
SPI
|
SPI
|
||||||
@ -227,8 +227,8 @@ Note:
|
|||||||
TODO
|
TODO
|
||||||
----
|
----
|
||||||
|
|
||||||
- Add rockchip idbloader image building
|
- Add Rockchip idbloader image building
|
||||||
- Add rockchip TPL image building
|
- Add Rockchip TPL image building
|
||||||
- Document SPI flash boot
|
- Document SPI flash boot
|
||||||
- Add missing SoC's with it boards list
|
- Add missing SoC's with it boards list
|
||||||
|
|
||||||
|
@ -1291,6 +1291,9 @@ static ulong px30_clk_set_rate(struct clk *clk, ulong rate)
|
|||||||
case PLL_NPLL:
|
case PLL_NPLL:
|
||||||
ret = px30_clk_set_pll_rate(priv, NPLL, rate);
|
ret = px30_clk_set_pll_rate(priv, NPLL, rate);
|
||||||
break;
|
break;
|
||||||
|
case PLL_CPLL:
|
||||||
|
ret = px30_clk_set_pll_rate(priv, CPLL, rate);
|
||||||
|
break;
|
||||||
case ARMCLK:
|
case ARMCLK:
|
||||||
ret = px30_armclk_set_clk(priv, rate);
|
ret = px30_armclk_set_clk(priv, rate);
|
||||||
break;
|
break;
|
||||||
|
@ -1441,6 +1441,7 @@ static ulong rk3568_sdmmc_set_clk(struct rk3568_clk_priv *priv,
|
|||||||
|
|
||||||
switch (rate) {
|
switch (rate) {
|
||||||
case OSC_HZ:
|
case OSC_HZ:
|
||||||
|
case 26 * MHz:
|
||||||
src_clk = CLK_SDMMC_SEL_24M;
|
src_clk = CLK_SDMMC_SEL_24M;
|
||||||
break;
|
break;
|
||||||
case 400 * MHz:
|
case 400 * MHz:
|
||||||
@ -1507,7 +1508,7 @@ static ulong rk3568_sfc_get_clk(struct rk3568_clk_priv *priv)
|
|||||||
case SCLK_SFC_SEL_125M:
|
case SCLK_SFC_SEL_125M:
|
||||||
return 125 * MHz;
|
return 125 * MHz;
|
||||||
case SCLK_SFC_SEL_150M:
|
case SCLK_SFC_SEL_150M:
|
||||||
return 150 * KHz;
|
return 150 * MHz;
|
||||||
default:
|
default:
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
@ -1534,7 +1535,7 @@ static ulong rk3568_sfc_set_clk(struct rk3568_clk_priv *priv, ulong rate)
|
|||||||
case 125 * MHz:
|
case 125 * MHz:
|
||||||
src_clk = SCLK_SFC_SEL_125M;
|
src_clk = SCLK_SFC_SEL_125M;
|
||||||
break;
|
break;
|
||||||
case 150 * KHz:
|
case 150 * MHz:
|
||||||
src_clk = SCLK_SFC_SEL_150M;
|
src_clk = SCLK_SFC_SEL_150M;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -2406,6 +2407,9 @@ static ulong rk3568_clk_get_rate(struct clk *clk)
|
|||||||
case BCLK_EMMC:
|
case BCLK_EMMC:
|
||||||
rate = rk3568_emmc_get_bclk(priv);
|
rate = rk3568_emmc_get_bclk(priv);
|
||||||
break;
|
break;
|
||||||
|
case TCLK_EMMC:
|
||||||
|
rate = OSC_HZ;
|
||||||
|
break;
|
||||||
#ifndef CONFIG_SPL_BUILD
|
#ifndef CONFIG_SPL_BUILD
|
||||||
case ACLK_VOP:
|
case ACLK_VOP:
|
||||||
rate = rk3568_aclk_vop_get_clk(priv);
|
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:
|
case BCLK_EMMC:
|
||||||
ret = rk3568_emmc_set_bclk(priv, rate);
|
ret = rk3568_emmc_set_bclk(priv, rate);
|
||||||
break;
|
break;
|
||||||
|
case TCLK_EMMC:
|
||||||
|
ret = OSC_HZ;
|
||||||
|
break;
|
||||||
#ifndef CONFIG_SPL_BUILD
|
#ifndef CONFIG_SPL_BUILD
|
||||||
case ACLK_VOP:
|
case ACLK_VOP:
|
||||||
ret = rk3568_aclk_vop_set_clk(priv, rate);
|
ret = rk3568_aclk_vop_set_clk(priv, rate);
|
||||||
|
@ -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(3 << 12, freqsel << 12), &phy->emmcphy_con[0]);
|
||||||
writel(RK_CLRSETBITS(1 << 1, 1 << 1), &phy->emmcphy_con[6]);
|
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,
|
read_poll_timeout(readl, &phy->emmcphy_status, dllrdy,
|
||||||
PHYCTRL_DLL_LOCK_WO_TMOUT(dllrdy), 1, 5000);
|
PHYCTRL_DLL_LOCK_WO_TMOUT(dllrdy), 1, 5000);
|
||||||
}
|
}
|
||||||
|
@ -116,6 +116,7 @@
|
|||||||
|
|
||||||
/* Master trigger */
|
/* Master trigger */
|
||||||
#define SFC_DMA_TRIGGER 0x80
|
#define SFC_DMA_TRIGGER 0x80
|
||||||
|
#define SFC_DMA_TRIGGER_START 1
|
||||||
|
|
||||||
/* Src or Dst addr for master */
|
/* Src or Dst addr for master */
|
||||||
#define SFC_DMA_ADDR 0x84
|
#define SFC_DMA_ADDR 0x84
|
||||||
@ -163,14 +164,12 @@
|
|||||||
#define SFC_DMA_TRANS_THRETHOLD (0x40)
|
#define SFC_DMA_TRANS_THRETHOLD (0x40)
|
||||||
|
|
||||||
/* Maximum clock values from datasheet suggest keeping clock value under
|
/* Maximum clock values from datasheet suggest keeping clock value under
|
||||||
* 150MHz. No minimum or average value is suggested, but the U-boot BSP driver
|
* 150MHz. No minimum or average value is suggested.
|
||||||
* has a minimum of 10MHz and a default of 80MHz which seems reasonable.
|
|
||||||
*/
|
*/
|
||||||
#define SFC_MIN_SPEED_HZ (10 * 1000 * 1000)
|
#define SFC_MAX_SPEED (150 * 1000 * 1000)
|
||||||
#define SFC_DEFAULT_SPEED_HZ (80 * 1000 * 1000)
|
|
||||||
#define SFC_MAX_SPEED_HZ (150 * 1000 * 1000)
|
|
||||||
|
|
||||||
struct rockchip_sfc {
|
struct rockchip_sfc {
|
||||||
|
struct udevice *dev;
|
||||||
void __iomem *regbase;
|
void __iomem *regbase;
|
||||||
struct clk hclk;
|
struct clk hclk;
|
||||||
struct clk clk;
|
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 */
|
/* Still need to clear the masked interrupt from RISR */
|
||||||
writel(0xFFFFFFFF, sfc->regbase + SFC_ICLR);
|
writel(0xFFFFFFFF, sfc->regbase + SFC_ICLR);
|
||||||
|
|
||||||
debug("reset\n");
|
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -261,15 +258,11 @@ static int rockchip_sfc_probe(struct udevice *bus)
|
|||||||
#if CONFIG_IS_ENABLED(CLK)
|
#if CONFIG_IS_ENABLED(CLK)
|
||||||
ret = clk_enable(&sfc->hclk);
|
ret = clk_enable(&sfc->hclk);
|
||||||
if (ret)
|
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);
|
ret = clk_enable(&sfc->clk);
|
||||||
if (ret)
|
if (ret)
|
||||||
debug("Enable clock fail for %s: %d\n", bus->name, ret);
|
dev_dbg(sfc->dev, "sfc 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);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ret = rockchip_sfc_init(sfc);
|
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->max_iosize = rockchip_sfc_get_max_iosize(sfc);
|
||||||
sfc->version = rockchip_sfc_get_version(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;
|
return 0;
|
||||||
|
|
||||||
@ -291,33 +285,38 @@ err_init:
|
|||||||
return ret;
|
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 ret = 0;
|
||||||
int level;
|
u32 status;
|
||||||
|
|
||||||
if (wr)
|
ret = readl_poll_timeout(sfc->regbase + SFC_FSR, status,
|
||||||
level = (fsr & SFC_FSR_TXLV_MASK) >> SFC_FSR_TXLV_SHIFT;
|
status & SFC_FSR_TXLV_MASK,
|
||||||
else
|
timeout_us);
|
||||||
level = (fsr & SFC_FSR_RXLV_MASK) >> SFC_FSR_RXLV_SHIFT;
|
if (ret) {
|
||||||
|
dev_dbg(sfc->dev, "sfc wait tx fifo timeout\n");
|
||||||
|
|
||||||
return level;
|
return -ETIMEDOUT;
|
||||||
}
|
|
||||||
|
|
||||||
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 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)
|
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;
|
ctrl |= SFC_CTRL_PHASE_SEL_NEGETIVE;
|
||||||
cmd |= plat->cs << SFC_CMD_CS_SHIFT;
|
cmd |= plat->cs << SFC_CMD_CS_SHIFT;
|
||||||
|
|
||||||
debug("addr.nbytes=%x(x%d) dummy.nbytes=%x(x%d)\n",
|
dev_dbg(sfc->dev, "sfc addr.nbytes=%x(x%d) dummy.nbytes=%x(x%d)\n",
|
||||||
op->addr.nbytes, op->addr.buswidth,
|
op->addr.nbytes, op->addr.buswidth,
|
||||||
op->dummy.nbytes, op->dummy.buswidth);
|
op->dummy.nbytes, op->dummy.buswidth);
|
||||||
debug("ctrl=%x cmd=%x addr=%llx len=%x\n",
|
dev_dbg(sfc->dev, "sfc ctrl=%x cmd=%x addr=%llx len=%x\n",
|
||||||
ctrl, cmd, op->addr.val, len);
|
ctrl, cmd, op->addr.val, len);
|
||||||
|
|
||||||
writel(ctrl, sfc->regbase + SFC_CTRL);
|
writel(ctrl, sfc->regbase + SFC_CTRL);
|
||||||
writel(cmd, sfc->regbase + SFC_CMD);
|
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;
|
dwords = len >> 2;
|
||||||
while (dwords) {
|
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)
|
if (tx_level < 0)
|
||||||
return tx_level;
|
return tx_level;
|
||||||
write_words = min_t(u32, tx_level, dwords);
|
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 */
|
/* write the rest non word aligned bytes */
|
||||||
if (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)
|
if (tx_level < 0)
|
||||||
return tx_level;
|
return tx_level;
|
||||||
memcpy(&tmp, buf, bytes);
|
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 */
|
/* word aligned access only */
|
||||||
dwords = len >> 2;
|
dwords = len >> 2;
|
||||||
while (dwords) {
|
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)
|
if (rx_level < 0)
|
||||||
return rx_level;
|
return rx_level;
|
||||||
read_words = min_t(u32, rx_level, dwords);
|
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 */
|
/* read the rest non word aligned bytes */
|
||||||
if (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)
|
if (rx_level < 0)
|
||||||
return rx_level;
|
return rx_level;
|
||||||
tmp = readl(sfc->regbase + SFC_DATA);
|
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(0xFFFFFFFF, sfc->regbase + SFC_ICLR);
|
||||||
writel((u32)dma_buf, sfc->regbase + SFC_DMA_ADDR);
|
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;
|
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,
|
static int rockchip_sfc_xfer_data_poll(struct rockchip_sfc *sfc,
|
||||||
const struct spi_mem_op *op, u32 len)
|
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)
|
if (op->data.dir == SPI_MEM_DATA_OUT)
|
||||||
return rockchip_sfc_write_fifo(sfc, op->data.buf.out, len);
|
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;
|
void *dma_buf;
|
||||||
int ret;
|
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) {
|
if (op->data.dir == SPI_MEM_DATA_OUT) {
|
||||||
dma_buf = (void *)op->data.buf.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)
|
static int rockchip_sfc_xfer_done(struct rockchip_sfc *sfc, u32 timeout_us)
|
||||||
{
|
{
|
||||||
unsigned long tbase = get_timer(0);
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
u32 timeout = timeout_us;
|
u32 status;
|
||||||
|
|
||||||
while (readl(sfc->regbase + SFC_SR) & SFC_SR_IS_BUSY) {
|
ret = readl_poll_timeout(sfc->regbase + SFC_SR, status,
|
||||||
if (get_timer(tbase) > timeout) {
|
!(status & SFC_SR_IS_BUSY),
|
||||||
printf("wait sfc idle timeout\n");
|
timeout_us);
|
||||||
rockchip_sfc_reset(sfc);
|
if (ret) {
|
||||||
|
dev_err(sfc->dev, "wait sfc idle timeout\n");
|
||||||
|
rockchip_sfc_reset(sfc);
|
||||||
|
|
||||||
return -ETIMEDOUT;
|
ret = -EIO;
|
||||||
}
|
|
||||||
|
|
||||||
udelay(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
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);
|
u32 len = min_t(u32, op->data.nbytes, sfc->max_iosize);
|
||||||
int ret;
|
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_adjust_op_work((struct spi_mem_op *)op);
|
||||||
|
|
||||||
rockchip_sfc_xfer_setup(sfc, mem, op, len);
|
rockchip_sfc_xfer_setup(sfc, mem, op, len);
|
||||||
if (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);
|
ret = rockchip_sfc_xfer_data_dma(sfc, op, len);
|
||||||
else
|
else
|
||||||
ret = rockchip_sfc_xfer_data_poll(sfc, op, len);
|
ret = rockchip_sfc_xfer_data_poll(sfc, op, len);
|
||||||
|
|
||||||
if (ret != 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;
|
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);
|
struct rockchip_sfc *sfc = dev_get_plat(mem->dev->parent);
|
||||||
|
|
||||||
op->data.nbytes = min(op->data.nbytes, sfc->max_iosize);
|
op->data.nbytes = min(op->data.nbytes, sfc->max_iosize);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rockchip_sfc_set_speed(struct udevice *bus, uint speed)
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user