Re: [PATCH v2] abootimg: Add init_boot image support
чт, 23 мая 2024 г. в 09:41, Mattijs Korpershoek : > > Hi Roman, > > Thank you for the patch. > > On mer., mai 22, 2024 at 21:26, Roman Stratiienko > wrote: > > > Quote from [1]: > > > > "For devices launching with Android 13, the generic ramdisk is removed > > from the boot image and placed in a separate init_boot image. > > This change leaves the boot image with only the GKI kernel." > > > > While at it, update wrong error handling message when vendor_boot > > cannot be loaded. > > > > [1]: > > https://source.android.com/docs/core/architecture/partitions/generic-boot > > Signed-off-by: Roman Stratiienko > > Reviewed-by: Mattijs Korpershoek > > Note: this patch still does not apply on master nor next: > > $ ~/work/upstream/u-boot/ git show --pretty='%h ("%s")' HEAD --no-patch > a7f0154c4128 ("Prepare v2024.07-rc3") > > $ ~/work/upstream/u-boot/ b4 shazam -s -l > 20240522212645.87250-1-r.stratiie...@gmail.com > > [...] > > Total patches: 1 > --- > Applying: abootimg: Add init_boot image support > Patch failed at 0001 abootimg: Add init_boot image support > error: sha1 information is lacking or useless (cmd/abootimg.c). > error: could not build fake ancestor > hint: Use 'git am --show-current-patch=diff' to see the failed patch > hint: When you have resolved this problem, run "git am --continue". > hint: If you prefer to skip this patch, run "git am --skip" instead. > hint: To restore the original branch and stop patching, run "git am --abort". > hint: Disable this message with "git config advice.mergeConflict false" > > - master: a7f0154c4128 ("Prepare v2024.07-rc3") > - next: 377e91c162ab ("Merge patch series "Clean-up patch set for MbedTLS > integration"") > > Looking further down below, we can see that this patch has the "abootimg > load" command, which is introduced in these series: > https://lore.kernel.org/r/20240519191856.2582174-1-r.stratiie...@gmail.com > > Please consider rebasing on either master or next before sending. Ahh. I see. Sorry for the inconvenience. I will rebase and send v3. > > > > --- > > boot/image-board.c | 13 ++--- > > cmd/abootimg.c | 26 +- > > include/image.h| 7 +++ > > 3 files changed, 38 insertions(+), 8 deletions(-) > > [...] > > > > > > > static struct cmd_tbl cmd_abootimg_sub[] = { > > - U_BOOT_CMD_MKENT(addr, 3, 1, do_abootimg_addr, "", ""), > > + U_BOOT_CMD_MKENT(addr, 4, 1, do_abootimg_addr, "", ""), > > U_BOOT_CMD_MKENT(dump, 2, 1, do_abootimg_dump, "", ""), > > U_BOOT_CMD_MKENT(get, 5, 1, do_abootimg_get, "", ""), > > U_BOOT_CMD_MKENT(load, 5, 1, do_abootimg_load, "", ""), > > @@ -376,7 +392,7 @@ static int do_abootimg(struct cmd_tbl *cmdtp, int flag, > > int argc, > > U_BOOT_CMD( > > abootimg, CONFIG_SYS_MAXARGS, 0, do_abootimg, > > "manipulate Android Boot Image", > > - "addr []>\n" > > + "addr [ > > []]\n" > > "- set the address in RAM where boot image is located\n" > > " ($loadaddr is used by default)\n" > > "abootimg dump dtb\n" > > [...]
Re: [PATCH v2] abootimg: Add init_boot image support
Hi Roman, Thank you for the patch. On mer., mai 22, 2024 at 21:26, Roman Stratiienko wrote: > Quote from [1]: > > "For devices launching with Android 13, the generic ramdisk is removed > from the boot image and placed in a separate init_boot image. > This change leaves the boot image with only the GKI kernel." > > While at it, update wrong error handling message when vendor_boot > cannot be loaded. > > [1]: https://source.android.com/docs/core/architecture/partitions/generic-boot > Signed-off-by: Roman Stratiienko Reviewed-by: Mattijs Korpershoek Note: this patch still does not apply on master nor next: $ ~/work/upstream/u-boot/ git show --pretty='%h ("%s")' HEAD --no-patch a7f0154c4128 ("Prepare v2024.07-rc3") $ ~/work/upstream/u-boot/ b4 shazam -s -l 20240522212645.87250-1-r.stratiie...@gmail.com [...] Total patches: 1 --- Applying: abootimg: Add init_boot image support Patch failed at 0001 abootimg: Add init_boot image support error: sha1 information is lacking or useless (cmd/abootimg.c). error: could not build fake ancestor hint: Use 'git am --show-current-patch=diff' to see the failed patch hint: When you have resolved this problem, run "git am --continue". hint: If you prefer to skip this patch, run "git am --skip" instead. hint: To restore the original branch and stop patching, run "git am --abort". hint: Disable this message with "git config advice.mergeConflict false" - master: a7f0154c4128 ("Prepare v2024.07-rc3") - next: 377e91c162ab ("Merge patch series "Clean-up patch set for MbedTLS integration"") Looking further down below, we can see that this patch has the "abootimg load" command, which is introduced in these series: https://lore.kernel.org/r/20240519191856.2582174-1-r.stratiie...@gmail.com Please consider rebasing on either master or next before sending. > --- > boot/image-board.c | 13 ++--- > cmd/abootimg.c | 26 +- > include/image.h| 7 +++ > 3 files changed, 38 insertions(+), 8 deletions(-) [...] > > > static struct cmd_tbl cmd_abootimg_sub[] = { > - U_BOOT_CMD_MKENT(addr, 3, 1, do_abootimg_addr, "", ""), > + U_BOOT_CMD_MKENT(addr, 4, 1, do_abootimg_addr, "", ""), > U_BOOT_CMD_MKENT(dump, 2, 1, do_abootimg_dump, "", ""), > U_BOOT_CMD_MKENT(get, 5, 1, do_abootimg_get, "", ""), > U_BOOT_CMD_MKENT(load, 5, 1, do_abootimg_load, "", ""), > @@ -376,7 +392,7 @@ static int do_abootimg(struct cmd_tbl *cmdtp, int flag, > int argc, > U_BOOT_CMD( > abootimg, CONFIG_SYS_MAXARGS, 0, do_abootimg, > "manipulate Android Boot Image", > - "addr []>\n" > + "addr [ []]\n" > "- set the address in RAM where boot image is located\n" > " ($loadaddr is used by default)\n" > "abootimg dump dtb\n" [...]
[PATCH] doc: board: sophgo: milkv_duo: Update Milk-V Duo documentation
Add detailed steps for compiling U-Boot and OpenSBI, generating the firmware package with fiptool, and booting the board. Signed-off-by: Kongyang Liu --- doc/board/sophgo/milkv_duo.rst | 41 +- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/doc/board/sophgo/milkv_duo.rst b/doc/board/sophgo/milkv_duo.rst index cb2ed1ad98..a88db5b903 100644 --- a/doc/board/sophgo/milkv_duo.rst +++ b/doc/board/sophgo/milkv_duo.rst @@ -20,31 +20,50 @@ Building .. code-block:: console export CROSS_COMPILE= + +3. Compile U-Boot + +.. code-block:: console + cd make milkv_duo_defconfig make -This will generate u-boot-dtb.bin +This will generate u-boot.bin and u-boot.dtb -Booting -~~~ -Currently, we rely on vendor FSBL(First Stage Boot Loader) to initialize the -clock and load the u-boot image, then bootup from it. +4. Compile OpenSBI + +.. code-block:: console -Alternatively, to run u-boot-dtb.bin on top of FSBL, follow these steps: + cd + make PLATFORM=generic FW_FDT_PATH=/u-boot.dtb -1. Use the vendor-provided tool to create a unified fip.bin file containing - FSBL, OpenSBI, and U-Boot. +This will generate fw_dynamic.bin -2. Place the generated fip.bin file into the FAT partition of the SD card. +4. Generate firmware image package -3. Insert the SD card into the board and power it on. +Fiptool(https://github.com/sophgo/fiptool) is used to generate fip file. + +.. code-block:: console + + git clone https://github.com/sophgo/fiptool + cd fiptool + ./fiptool \ + --fsbl data/fsbl/cv180x.bin \ + --opensbi /fw_dynamic.bin \ + --uboot /u-boot.bin \ + +This will generate fip.bin + +Booting +~~~ +1. Place the generated fip.bin file into the FAT partition of the SD card. +2. Insert the SD card into the board and power it on. The board will automatically execute the FSBL from the fip.bin file. Subsequently, it will transition to OpenSBI, and finally, OpenSBI will invoke U-Boot. - Sample boot log from Milk-V Duo board ~ .. code-block:: none -- 2.41.0
Re: [PATCH 1/3] arm: dts: k3-am642-evm-u-boot: Add remoteproc-name for PRU cores
Hi Andrew, On 5/22/2024 9:38 PM, Andrew Davis wrote: > On 5/22/24 1:36 AM, MD Danish Anwar wrote: >> Add remoteproc-name property for PRU cores. >> >> Signed-off-by: MD Danish Anwar >> --- >> arch/arm/dts/k3-am642-evm-u-boot.dtsi | 44 +++ >> 1 file changed, 44 insertions(+) >> >> diff --git a/arch/arm/dts/k3-am642-evm-u-boot.dtsi >> b/arch/arm/dts/k3-am642-evm-u-boot.dtsi >> index 705b3baa81..25ddace74e 100644 >> --- a/arch/arm/dts/k3-am642-evm-u-boot.dtsi >> +++ b/arch/arm/dts/k3-am642-evm-u-boot.dtsi >> @@ -11,6 +11,50 @@ >> }; >> }; >> +&pru0_0 { >> + remoteproc-name = "pru0_0"; > > Why do we need all these? Looks like we fallback to using `dev->name` if > these are not set, does that not work for us here? > Yes we will fallback to `dev->name` if `remoteproc-name` is not set but in our case two different PRU cores will have same `dev->name`. As a result the API rproc_name_is_unique() will return false and as a result the probe will fail for the PRU cores. Example: In k3-am64-main.dtsi, both pru0_0 [1] and pru1_0 [2] will have dev->name as "pru@34000" same goes for rtu and txpru as well. pru0_0: pru@34000 { compatible = "ti,am642-pru"; reg = <0x34000 0x3000>, <0x22000 0x100>, <0x22400 0x100>; reg-names = "iram", "control", "debug"; firmware-name = "am64x-pru0_0-fw"; }; pru1_0: pru@34000 { compatible = "ti,am642-pru"; reg = <0x34000 0x4000>, <0x22000 0x100>, <0x22400 0x100>; reg-names = "iram", "control", "debug"; firmware-name = "am64x-pru1_0-fw"; }; To avoid this, we are setting the "remoteproc-name" property in -u-boot.dtsi. Same is done for AM65x as well [3]. [1] https://elixir.bootlin.com/u-boot/v2024.07-rc3/source/dts/upstream/src/arm64/ti/k3-am64-main.dtsi#L1276 [2] https://elixir.bootlin.com/u-boot/v2024.07-rc3/source/dts/upstream/src/arm64/ti/k3-am64-main.dtsi#L1417 [3] https://elixir.bootlin.com/u-boot/v2024.07-rc3/source/arch/arm/dts/k3-am654-base-board-u-boot.dtsi#L168 > Andrew > >> +}; >> + >> +&rtu0_0 { >> + remoteproc-name = "rtu0_0"; >> +}; >> + >> +&tx_pru0_0 { >> + remoteproc-name = "tx_pru0_0"; >> +}; >> + >> +&pru0_1 { >> + remoteproc-name = "pru0_1"; >> +}; >> + >> +&rtu0_1 { >> + remoteproc-name = "rtu0_1"; >> +}; >> + >> +&tx_pru0_1 { >> + remoteproc-name = "tx_pru0_1"; >> +}; >> + >> +&pru1_0 { >> + remoteproc-name = "pru1_0"; >> +}; >> + >> +&rtu1_0 { >> + remoteproc-name = "rtu1_0"; >> +}; >> + >> +&tx_pru1_0 { >> + remoteproc-name = "tx_pru1_0"; >> +}; >> + >> +&pru1_1 { >> + remoteproc-name = "pru1_1"; >> +}; >> + >> +&rtu1_1 { >> + remoteproc-name = "rtu1_1"; >> +}; >> + >> &main_timer0 { >> clock-frequency = <2>; >> }; -- Thanks and Regards, Md Danish Anwar
Re: [PATCH] abootimg: Add init_boot image support
Hi Roman, On jeu., mai 23, 2024 at 00:35, Roman Stratiienko wrote: [...] >> > >> > static struct cmd_tbl cmd_abootimg_sub[] = { >> > - U_BOOT_CMD_MKENT(addr, 3, 1, do_abootimg_addr, "", ""), >> > + U_BOOT_CMD_MKENT(addr, 4, 1, do_abootimg_addr, "", ""), >> > U_BOOT_CMD_MKENT(dump, 2, 1, do_abootimg_dump, "", ""), >> > U_BOOT_CMD_MKENT(get, 5, 1, do_abootimg_get, "", ""), >> > U_BOOT_CMD_MKENT(load, 5, 1, do_abootimg_load, "", ""), >> > @@ -375,7 +391,7 @@ static int do_abootimg(struct cmd_tbl *cmdtp, int >> > flag, int argc, >> > U_BOOT_CMD( >> > abootimg, CONFIG_SYS_MAXARGS, 0, do_abootimg, >> > "manipulate Android Boot Image", >> > - "addr []>\n" >> > + "addr [ >> > []]\n" >> > "- set the address in RAM where boot image is located\n" >> > " ($loadaddr is used by default)\n" >> >> Please include the help text update in the documentation: >> doc/android/boot-image.rst > > That documentation does not mention 'abootimg addr' command at the moment. > I do not see an easy way to add it in a way that makes sense. > I see. I will send a documentation update later then. >> >> > "abootimg dump dtb\n" >> > diff --git a/include/image.h b/include/image.h >> > index be3c73a72e..b1fd6b3149 100644 [...]
Re: [PATCH 2/4] clk: sophgo: cv1800b: Add clock controller driver for cv1800b SoC
Yixun Lan 于2024年5月23日周四 07:39写道: > > Hi Kongyang: > > I've got one compiling error > > On 23:07 Sun 19 May , Kongyang Liu wrote: > > Add clock controller driver for sophgo cv1800b SoC > > > > Signed-off-by: Kongyang Liu > > --- > > > > drivers/clk/Kconfig | 1 + > > drivers/clk/Makefile | 1 + > > drivers/clk/sophgo/Kconfig | 14 + > > drivers/clk/sophgo/Makefile | 6 + > > drivers/clk/sophgo/clk-common.h | 74 +++ > > drivers/clk/sophgo/clk-cv1800b.c | 794 +++ > > drivers/clk/sophgo/clk-cv1800b.h | 123 + > > drivers/clk/sophgo/clk-ip.c | 594 +++ > > drivers/clk/sophgo/clk-ip.h | 288 +++ > > drivers/clk/sophgo/clk-pll.c | 284 +++ > > drivers/clk/sophgo/clk-pll.h | 74 +++ > > 11 files changed, 2253 insertions(+) > > create mode 100644 drivers/clk/sophgo/Kconfig > > create mode 100644 drivers/clk/sophgo/Makefile > > create mode 100644 drivers/clk/sophgo/clk-common.h > > create mode 100644 drivers/clk/sophgo/clk-cv1800b.c > > create mode 100644 drivers/clk/sophgo/clk-cv1800b.h > > create mode 100644 drivers/clk/sophgo/clk-ip.c > > create mode 100644 drivers/clk/sophgo/clk-ip.h > > create mode 100644 drivers/clk/sophgo/clk-pll.c > > create mode 100644 drivers/clk/sophgo/clk-pll.h > > > > ... > > > +static ulong cv1800b_ipll_set_rate(struct clk *clk, ulong rate) > > +{ > > + struct cv1800b_clk_ipll *pll = to_clk_ipll(clk); > > + ulong parent_rate = clk_get_parent_rate(clk); > > + u32 pre_div, post_div, div; > > + u32 pre_div_sel, post_div_sel, div_sel; > > + ulong new_rate, best_rate = 0; > > + u32 mode, ictrl; > > + u32 test, val; > > + > > + FOR_RANGE(pre_div, PLL_PRE_DIV) > > + { > > + FOR_RANGE(post_div, PLL_POST_DIV) > > + { > > + FOR_RANGE(div, PLL_DIV) > > + { > > + new_rate = DIV_ROUND_DOWN_ULL(parent_rate * > > div > > ~~ > miss a comma here I will fix it. > > + pre_div * > > post_div); > > + if (rate - new_rate < rate - best_rate) { > > + best_rate = new_rate; > > + pre_div_sel = pre_div; > > + post_div_sel = post_div; > > + div_sel = div; > > + } > > + } > > + } > > + } > > + > > + FOR_RANGE(mode, PLL_MODE) > > -- > Yixun Lan (dlan) > Gentoo Linux Developer > GPG Key ID AABEFD55
[PATCH v3 8/8] arm: dts: k3-*-ddr: Add ss_cfg reg entry
Add ss_cfg memory region which maps the DDRSS configuration region for the memory controller node. Signed-off-by: Santhosh Kumar K Signed-off-by: Neha Malcom Francis --- arch/arm/dts/k3-am62a-ddr.dtsi | 7 --- arch/arm/dts/k3-j721s2-ddr.dtsi | 12 arch/arm/dts/k3-j784s4-ddr.dtsi | 24 3 files changed, 28 insertions(+), 15 deletions(-) diff --git a/arch/arm/dts/k3-am62a-ddr.dtsi b/arch/arm/dts/k3-am62a-ddr.dtsi index 8629ea45b847..42e41f78505a 100644 --- a/arch/arm/dts/k3-am62a-ddr.dtsi +++ b/arch/arm/dts/k3-am62a-ddr.dtsi @@ -4,11 +4,12 @@ */ / { - memorycontroller: memory-controller@f308000 { + memorycontroller: memory-controller@f30 { compatible = "ti,am62a-ddrss"; reg = <0x00 0x0f308000 0x00 0x4000>, - <0x00 0x43014000 0x00 0x100>; - reg-names = "cfg", "ctrl_mmr_lp4"; + <0x00 0x43014000 0x00 0x100>, + <0x00 0x0f30 0x00 0x200>; + reg-names = "cfg", "ctrl_mmr_lp4", "ss_cfg"; ti,ddr-freq1 = ; ti,ddr-freq2 = ; ti,ddr-fhs-cnt = ; diff --git a/arch/arm/dts/k3-j721s2-ddr.dtsi b/arch/arm/dts/k3-j721s2-ddr.dtsi index 345e2b84f9e8..9764085163c4 100644 --- a/arch/arm/dts/k3-j721s2-ddr.dtsi +++ b/arch/arm/dts/k3-j721s2-ddr.dtsi @@ -5,6 +5,8 @@ &main_navss { ranges = <0x00 0x00114000 0x00 0x00114000 0x00 0x0100>, // ctrl_mmr_lpr +<0x00 0x0298 0x00 0x0298 0x00 0x0200>, // ss cfg 0 +<0x00 0x029a 0x00 0x029a 0x00 0x0200>, // ss cfg 1 <0x00 0x0299 0x00 0x0299 0x00 0x4000>, // ddr0 cfg <0x00 0x029b 0x00 0x029b 0x00 0x4000>, // ddr1 cfg <0x00 0x3000 0x00 0x3000 0x00 0x0c40>; @@ -24,8 +26,9 @@ memorycontroller0: memorycontroller@299 { compatible = "ti,j721s2-ddrss"; reg = <0x0 0x0299 0x0 0x4000>, - <0x0 0x0114000 0x0 0x100>; - reg-names = "cfg", "ctrl_mmr_lp4"; + <0x0 0x0114000 0x0 0x100>, + <0x0 0x0298 0x0 0x200>; + reg-names = "cfg", "ctrl_mmr_lp4", "ss_cfg"; power-domains = <&k3_pds 138 TI_SCI_PD_SHARED>, <&k3_pds 96 TI_SCI_PD_SHARED>; clocks = <&k3_clks 138 0>, <&k3_clks 43 2>; @@ -2232,8 +2235,9 @@ memorycontroller1: memorycontroller@29b { compatible = "ti,j721s2-ddrss"; reg = <0x0 0x029b 0x0 0x4000>, - <0x0 0x0114000 0x0 0x100>; - reg-names = "cfg", "ctrl_mmr_lp4"; + <0x0 0x0114000 0x0 0x100>, + <0x0 0x029a 0x0 0x200>; + reg-names = "cfg", "ctrl_mmr_lp4", "ss_cfg"; power-domains = <&k3_pds 139 TI_SCI_PD_SHARED>, <&k3_pds 97 TI_SCI_PD_SHARED>; clocks = <&k3_clks 139 0>, <&k3_clks 43 2>; diff --git a/arch/arm/dts/k3-j784s4-ddr.dtsi b/arch/arm/dts/k3-j784s4-ddr.dtsi index 1c3242b0870c..fc74c539331e 100644 --- a/arch/arm/dts/k3-j784s4-ddr.dtsi +++ b/arch/arm/dts/k3-j784s4-ddr.dtsi @@ -9,6 +9,10 @@ <0x00 0x029b 0x00 0x029b 0x00 0x4000>, // ddr1 cfg <0x00 0x029d 0x00 0x029d 0x00 0x4000>, // ddr2 cfg <0x00 0x029f 0x00 0x029f 0x00 0x4000>, // ddr3 cfg +<0x00 0x0298 0x00 0x0298 0x00 0x0200>, // ss cfg 0 +<0x00 0x029a 0x00 0x029a 0x00 0x0200>, // ss cfg 1 +<0x00 0x029c 0x00 0x029c 0x00 0x0200>, // ss cfg 2 +<0x00 0x029e 0x00 0x029e 0x00 0x0200>, // ss cfg 3 <0x00 0x3000 0x00 0x3000 0x00 0x0c40>; msmc0: msmc { @@ -26,8 +30,9 @@ memorycontroller0: memorycontroller@299 { compatible = "ti,j721s2-ddrss"; reg = <0x0 0x0299 0x0 0x4000>, - <0x0 0x0114000 0x0 0x100>; - reg-names = "cfg", "ctrl_mmr_lp4"; + <0x0 0x0114000 0x0 0x100>, + <0x0 0x0298 0x0 0x200>; + reg-names = "cfg", "ctrl_mmr_lp4", "ss_cfg"; power-domains = <&k3_pds 191 TI_SCI_PD_SHARED>, <&k3_pds 131 TI_SCI_PD_SHARED>; clocks = <&k3_clks 191 1>, <&k3_clks 78 2>; @@ -2234,8 +2239,9 @@ memorycontroller1: memorycontroller@29b { compatible = "ti,j721s2-ddrss";
[PATCH v3 7/8] board: ti: Pull redundant DDR functions to a common location and Fixup DDR size when ECC is enabled
As there are few redundant functions in board/ti/*/evm.c files, pull them to a common location of access to reuse and include the common file to access the functions. Call k3-ddrss driver through fixup_ddr_driver_for_ecc() to fixup the device tree and resize the available amount of DDR, if ECC is enabled. Otherwise, fixup the device tree using the regular fdt_fixup_memory_banks(). Also call dram_init_banksize() after every call to fixup_ddr_driver_for_ecc() is made so that gd->bd is populated correctly. Ensure that fixup_ddr_driver_for_ecc() is agnostic to the number of DDR controllers present. Signed-off-by: Santhosh Kumar K Signed-off-by: Neha Malcom Francis --- board/ti/am62ax/evm.c | 17 --- board/ti/am62px/evm.c | 18 --- board/ti/am62x/evm.c | 63 - board/ti/am64x/evm.c | 73 +++- board/ti/am65x/evm.c | 29 +--- board/ti/common/Makefile | 1 + board/ti/common/k3-ddr-init.c | 89 +++ board/ti/common/k3-ddr-init.h | 15 ++ board/ti/j721e/evm.c | 29 +--- board/ti/j721s2/evm.c | 35 -- board/ti/j784s4/evm.c | 17 --- 11 files changed, 163 insertions(+), 223 deletions(-) create mode 100644 board/ti/common/k3-ddr-init.c create mode 100644 board/ti/common/k3-ddr-init.h diff --git a/board/ti/am62ax/evm.c b/board/ti/am62ax/evm.c index 62d3664936e7..3d7bd369a452 100644 --- a/board/ti/am62ax/evm.c +++ b/board/ti/am62ax/evm.c @@ -14,21 +14,24 @@ #include #include "../common/fdt_ops.h" +#include "../common/k3-ddr-init.h" int board_init(void) { return 0; } -int dram_init(void) +#if defined(CONFIG_SPL_BUILD) +void spl_perform_fixups(struct spl_image_info *spl_image) { - return fdtdec_setup_mem_size_base(); -} - -int dram_init_banksize(void) -{ - return fdtdec_setup_memory_banksize(); + if (IS_ENABLED(CONFIG_K3_DDRSS)) { + if (IS_ENABLED(CONFIG_K3_INLINE_ECC)) + fixup_ddr_driver_for_ecc(spl_image); + } else { + fixup_memory_node(spl_image); + } } +#endif #ifdef CONFIG_BOARD_LATE_INIT int board_late_init(void) diff --git a/board/ti/am62px/evm.c b/board/ti/am62px/evm.c index 97a95ce8cc2d..aa7db61eb411 100644 --- a/board/ti/am62px/evm.c +++ b/board/ti/am62px/evm.c @@ -13,17 +13,21 @@ #include #include +#include "../common/k3-ddr-init.h" + int board_init(void) { return 0; } -int dram_init(void) -{ - return fdtdec_setup_mem_size_base(); -} - -int dram_init_banksize(void) +#if defined(CONFIG_SPL_BUILD) +void spl_perform_fixups(struct spl_image_info *spl_image) { - return fdtdec_setup_memory_banksize(); + if (IS_ENABLED(CONFIG_K3_DDRSS)) { + if (IS_ENABLED(CONFIG_K3_INLINE_ECC)) + fixup_ddr_driver_for_ecc(spl_image); + } else { + fixup_memory_node(spl_image); + } } +#endif diff --git a/board/ti/am62x/evm.c b/board/ti/am62x/evm.c index b3e8680dfab2..32ba37963212 100644 --- a/board/ti/am62x/evm.c +++ b/board/ti/am62x/evm.c @@ -21,6 +21,8 @@ #include "../common/fdt_ops.h" +#include "../common/k3-ddr-init.h" + DECLARE_GLOBAL_DATA_PTR; #if CONFIG_IS_ENABLED(SPLASH_SCREEN) @@ -51,11 +53,6 @@ int board_init(void) return 0; } -int dram_init(void) -{ - return fdtdec_setup_mem_size_base(); -} - #ifdef CONFIG_BOARD_LATE_INIT int board_late_init(void) { @@ -64,11 +61,6 @@ int board_late_init(void) } #endif -int dram_init_banksize(void) -{ - return fdtdec_setup_memory_banksize(); -} - #if defined(CONFIG_SPL_BUILD) void spl_board_init(void) @@ -79,52 +71,13 @@ void spl_board_init(void) } -#if defined(CONFIG_K3_AM64_DDRSS) -static void fixup_ddr_driver_for_ecc(struct spl_image_info *spl_image) -{ - struct udevice *dev; - int ret; - - dram_init_banksize(); - - ret = uclass_get_device(UCLASS_RAM, 0, &dev); - if (ret) - panic("Cannot get RAM device for ddr size fixup: %d\n", ret); - - ret = k3_ddrss_ddr_fdt_fixup(dev, spl_image->fdt_addr, gd->bd); - if (ret) - printf("Error fixing up ddr node for ECC use! %d\n", ret); -} -#else -static void fixup_memory_node(struct spl_image_info *spl_image) -{ - u64 start[CONFIG_NR_DRAM_BANKS]; - u64 size[CONFIG_NR_DRAM_BANKS]; - int bank; - int ret; - - dram_init(); - dram_init_banksize(); - - for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) { - start[bank] = gd->bd->bi_dram[bank].start; - size[bank] = gd->bd->bi_dram[bank].size; - } - - /* dram_init functions use SPL fdt, and we must fixup u-boot fdt */ - ret = fdt_fixup_memory_banks(spl_image->fdt_addr, start, size, -CONFIG_NR_DRAM_BANKS); - if (ret) - printf("Error fixing up memory n
[PATCH v3 6/8] configs: j7*_evm_r5_defconfig: Set NR_DRAM_BANKS to 2
From: Neha Malcom Francis Set CONFIG_NR_DRAM_BANKS to 2 as we have two banks described in the memory/ node for lower and higher addressible DDR regions. This allows use of FDT functions from fdt_support.c to set up and fixup the memory/ node correctly. Signed-off-by: Neha Malcom Francis --- configs/j7200_evm_r5_defconfig | 1 + configs/j721e_evm_r5_defconfig | 1 + configs/j721s2_evm_r5_defconfig | 1 + configs/j784s4_evm_r5_defconfig | 1 + 4 files changed, 4 insertions(+) diff --git a/configs/j7200_evm_r5_defconfig b/configs/j7200_evm_r5_defconfig index e023af24674a..6494136d735a 100644 --- a/configs/j7200_evm_r5_defconfig +++ b/configs/j7200_evm_r5_defconfig @@ -5,6 +5,7 @@ CONFIG_SYS_MALLOC_F_LEN=0x7 CONFIG_SPL_GPIO=y CONFIG_SPL_LIBCOMMON_SUPPORT=y CONFIG_SPL_LIBGENERIC_SUPPORT=y +CONFIG_NR_DRAM_BANKS=2 CONFIG_SOC_K3_J721E=y CONFIG_K3_EARLY_CONS=y CONFIG_TARGET_J7200_R5_EVM=y diff --git a/configs/j721e_evm_r5_defconfig b/configs/j721e_evm_r5_defconfig index cea48b26136c..1c575e278c90 100644 --- a/configs/j721e_evm_r5_defconfig +++ b/configs/j721e_evm_r5_defconfig @@ -5,6 +5,7 @@ CONFIG_SYS_MALLOC_F_LEN=0x7 CONFIG_SPL_GPIO=y CONFIG_SPL_LIBCOMMON_SUPPORT=y CONFIG_SPL_LIBGENERIC_SUPPORT=y +CONFIG_NR_DRAM_BANKS=2 CONFIG_SOC_K3_J721E=y CONFIG_K3_EARLY_CONS=y CONFIG_TARGET_J721E_R5_EVM=y diff --git a/configs/j721s2_evm_r5_defconfig b/configs/j721s2_evm_r5_defconfig index 5ef5247a3e00..a6c2d7276e07 100644 --- a/configs/j721s2_evm_r5_defconfig +++ b/configs/j721s2_evm_r5_defconfig @@ -5,6 +5,7 @@ CONFIG_SYS_MALLOC_F_LEN=0x1 CONFIG_SPL_GPIO=y CONFIG_SPL_LIBCOMMON_SUPPORT=y CONFIG_SPL_LIBGENERIC_SUPPORT=y +CONFIG_NR_DRAM_BANKS=2 CONFIG_SOC_K3_J721S2=y CONFIG_K3_EARLY_CONS=y CONFIG_TARGET_J721S2_R5_EVM=y diff --git a/configs/j784s4_evm_r5_defconfig b/configs/j784s4_evm_r5_defconfig index f5fe7432206b..bdb4d10e2f84 100644 --- a/configs/j784s4_evm_r5_defconfig +++ b/configs/j784s4_evm_r5_defconfig @@ -4,6 +4,7 @@ CONFIG_SYS_MALLOC_F_LEN=0x1 CONFIG_SPL_GPIO=y CONFIG_SPL_LIBCOMMON_SUPPORT=y CONFIG_SPL_LIBGENERIC_SUPPORT=y +CONFIG_NR_DRAM_BANKS=2 CONFIG_SOC_K3_J784S4=y CONFIG_K3_EARLY_CONS=y CONFIG_TARGET_J784S4_R5_EVM=y -- 2.34.1
[PATCH v3 5/8] drivers: ram: Kconfig: Add CONFIG_K3_INLINE_ECC
From: Neha Malcom Francis Add CONFIG_K3_INLINE_ECC so that ECC functions can be compiled into R5 SPL only when the config has been enabled. Signed-off-by: Neha Malcom Francis --- drivers/ram/Kconfig | 10 ++ 1 file changed, 10 insertions(+) diff --git a/drivers/ram/Kconfig b/drivers/ram/Kconfig index 9838a2798f92..5cee93fe68c8 100644 --- a/drivers/ram/Kconfig +++ b/drivers/ram/Kconfig @@ -107,6 +107,16 @@ config IMXRT_SDRAM to support external memories like sdram, psram & nand. This driver is for the sdram memory interface with the SEMC. +config K3_INLINE_ECC + bool "Enable TI Inline ECC support" + depends on K3_DDRSS + help + Enable Inline ECC support on K3 platforms. 1/9th of the SDRAM space + is used for ECC storage and the rest 8/9th is available for system + use. Enabling ECC increases boot time as the ECC protected regions + need to be primed with a predefined value prior to enabling ECC + check. + source "drivers/ram/aspeed/Kconfig" source "drivers/ram/cadence/Kconfig" source "drivers/ram/octeon/Kconfig" -- 2.34.1
[PATCH v3 4/8] ram: k3-ddrss: Enable ECC interrupts
Enable ECC 1-bit error, 2-bit error, multiple 1-bit error interrupts by setting the respective bits in the DDRSS_V2A_INT_SET_REG register. Signed-off-by: Santhosh Kumar K --- drivers/ram/k3-ddrss/k3-ddrss.c | 8 1 file changed, 8 insertions(+) diff --git a/drivers/ram/k3-ddrss/k3-ddrss.c b/drivers/ram/k3-ddrss/k3-ddrss.c index 6cf680972808..5bc625fc2db6 100644 --- a/drivers/ram/k3-ddrss/k3-ddrss.c +++ b/drivers/ram/k3-ddrss/k3-ddrss.c @@ -46,6 +46,11 @@ #define DDRSS_ECC_R2_STR_ADDR_REG 0x0140 #define DDRSS_ECC_R2_END_ADDR_REG 0x0144 #define DDRSS_ECC_1B_ERR_CNT_REG 0x0150 +#define DDRSS_V2A_INT_SET_REG 0x00a8 + +#define DDRSS_V2A_INT_SET_REG_ECC1BERR_EN BIT(3) +#define DDRSS_V2A_INT_SET_REG_ECC2BERR_EN BIT(4) +#define DDRSS_V2A_INT_SET_REG_ECCM1BERR_EN BIT(5) #define SINGLE_DDR_SUBSYSTEM 0x1 #define MULTI_DDR_SUBSYSTEM0x2 @@ -748,6 +753,9 @@ static void k3_ddrss_lpddr4_ecc_init(struct k3_ddrss_desc *ddrss) /* Clear Error Count Register */ writel(0x1, base + DDRSS_ECC_1B_ERR_CNT_REG); + writel(DDRSS_V2A_INT_SET_REG_ECC1BERR_EN | DDRSS_V2A_INT_SET_REG_ECC2BERR_EN | + DDRSS_V2A_INT_SET_REG_ECCM1BERR_EN, base + DDRSS_V2A_INT_SET_REG); + /* Enable ECC Check */ val = readl(base + DDRSS_ECC_CTRL_REG); val |= DDRSS_ECC_CTRL_REG_ECC_CK; -- 2.34.1
[PATCH v3 3/8] ram: k3-ddrss: Setup ECC region start and range
Setup the ECC region's start and range using the device private data, ddrss->ddr_bank_base[0] and ddrss->ddr_ram_size. Also, move start and range of ECC regions from 32 bits to 64 bits to accommodate for DDR greater than or equal to 4GB. Signed-off-by: Santhosh Kumar K --- drivers/ram/k3-ddrss/k3-ddrss.c | 16 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/ram/k3-ddrss/k3-ddrss.c b/drivers/ram/k3-ddrss/k3-ddrss.c index 06c4dba4b857..6cf680972808 100644 --- a/drivers/ram/k3-ddrss/k3-ddrss.c +++ b/drivers/ram/k3-ddrss/k3-ddrss.c @@ -122,8 +122,8 @@ struct k3_msmc { #define K3_DDRSS_MAX_ECC_REGIONS 3 struct k3_ddrss_ecc_region { - u32 start; - u32 range; + u64 start; + u64 range; }; struct k3_ddrss_desc { @@ -552,7 +552,7 @@ void k3_lpddr4_start(struct k3_ddrss_desc *ddrss) } } -static void k3_ddrss_set_ecc_range_r0(u32 base, u32 start_address, u32 size) +static void k3_ddrss_set_ecc_range_r0(u32 base, u64 start_address, u64 size) { writel((start_address) >> 16, base + DDRSS_ECC_R0_STR_ADDR_REG); writel((start_address + size - 1) >> 16, base + DDRSS_ECC_R0_END_ADDR_REG); @@ -728,13 +728,13 @@ static void k3_ddrss_lpddr4_ecc_calc_reserved_mem(struct k3_ddrss_desc *ddrss) static void k3_ddrss_lpddr4_ecc_init(struct k3_ddrss_desc *ddrss) { - u32 ecc_region_start = ddrss->ecc_regions[0].start; - u32 ecc_range = ddrss->ecc_regions[0].range; + u64 ecc_region_start = ddrss->ecc_regions[0].start; + u64 ecc_range = ddrss->ecc_regions[0].range; u32 base = (u32)ddrss->ddrss_ss_cfg; u32 val; /* Only Program region 0 which covers full ddr space */ - k3_ddrss_set_ecc_range_r0(base, ecc_region_start - gd->ram_base, ecc_range); + k3_ddrss_set_ecc_range_r0(base, ecc_region_start - ddrss->ddr_bank_base[0], ecc_range); /* Enable ECC, RMW, WR_ALLOC */ writel(DDRSS_ECC_CTRL_REG_ECC_EN | DDRSS_ECC_CTRL_REG_RMW_EN | @@ -800,8 +800,8 @@ static int k3_ddrss_probe(struct udevice *dev) k3_ddrss_lpddr4_ecc_calc_reserved_mem(ddrss); /* Always configure one region that covers full DDR space */ - ddrss->ecc_regions[0].start = gd->ram_base; - ddrss->ecc_regions[0].range = gd->ram_size - ddrss->ecc_reserved_space; + ddrss->ecc_regions[0].start = ddrss->ddr_bank_base[0]; + ddrss->ecc_regions[0].range = ddrss->ddr_ram_size - ddrss->ecc_reserved_space; k3_ddrss_lpddr4_ecc_init(ddrss); } -- 2.34.1
[PATCH v3 2/8] ram: k3-ddrss: Add k3_ddrss_ddr_bank_base_size_calc() to solve 'calculations restricted to 32 bits' issue
As R5 is a 32 bit processor, the RAM banks' base and size calculation is restricted to 32 bits, which results in wrong values if bank's base is greater than 32 bits or bank's size is greater than or equal to 4GB. So, add k3_ddrss_ddr_bank_base_size_calc() to get the base address and size of RAM's banks from the device tree memory node, and store in a 64 bit device private data which can be used for ECC reserved memory calculation, Setting ECC range and Fixing up bank size in device tree when ECC is enabled. Signed-off-by: Santhosh Kumar K --- drivers/ram/k3-ddrss/k3-ddrss.c | 72 ++--- 1 file changed, 57 insertions(+), 15 deletions(-) diff --git a/drivers/ram/k3-ddrss/k3-ddrss.c b/drivers/ram/k3-ddrss/k3-ddrss.c index b656721e8e5b..06c4dba4b857 100644 --- a/drivers/ram/k3-ddrss/k3-ddrss.c +++ b/drivers/ram/k3-ddrss/k3-ddrss.c @@ -148,6 +148,9 @@ struct k3_ddrss_desc { struct k3_ddrss_ecc_region ecc_regions[K3_DDRSS_MAX_ECC_REGIONS]; u64 ecc_reserved_space; bool ti_ecc_enabled; + unsigned long long ddr_bank_base[CONFIG_NR_DRAM_BANKS]; + unsigned long long ddr_bank_size[CONFIG_NR_DRAM_BANKS]; + unsigned long long ddr_ram_size; }; struct reginitdata { @@ -669,11 +672,54 @@ static void k3_ddrss_lpddr4_preload_full_mem(struct k3_ddrss_desc *ddrss, printf("ECC: priming DDR completed in %lu msec\n", get_timer(done)); } +static void k3_ddrss_ddr_bank_base_size_calc(struct k3_ddrss_desc *ddrss) +{ + int bank, na, ns, len, parent; + const fdt32_t *ptr, *end; + + for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) { + ddrss->ddr_bank_base[bank] = 0; + ddrss->ddr_bank_size[bank] = 0; + } + + ofnode mem = ofnode_null(); + + do { + mem = ofnode_by_prop_value(mem, "device_type", "memory", 7); + } while (!ofnode_is_enabled(mem)); + + const void *fdt = ofnode_to_fdt(mem); + int node = ofnode_to_offset(mem); + const char *property = "reg"; + + parent = fdt_parent_offset(fdt, node); + na = fdt_address_cells(fdt, parent); + ns = fdt_size_cells(fdt, parent); + ptr = fdt_getprop(fdt, node, property, &len); + end = ptr + len / sizeof(*ptr); + + for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) { + if (ptr + na + ns <= end) { + if (CONFIG_IS_ENABLED(OF_TRANSLATE)) + ddrss->ddr_bank_base[bank] = fdt_translate_address(fdt, node, ptr); + else + ddrss->ddr_bank_base[bank] = fdtdec_get_number(ptr, na); + + ddrss->ddr_bank_size[bank] = fdtdec_get_number(&ptr[na], ns); + } + + ptr += na + ns; + } + + for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) + ddrss->ddr_ram_size += ddrss->ddr_bank_size[bank]; +} + static void k3_ddrss_lpddr4_ecc_calc_reserved_mem(struct k3_ddrss_desc *ddrss) { fdtdec_setup_mem_size_base_lowest(); - ddrss->ecc_reserved_space = gd->ram_size; + ddrss->ecc_reserved_space = ddrss->ddr_ram_size; do_div(ddrss->ecc_reserved_space, 9); /* Round to clean number */ @@ -697,7 +743,7 @@ static void k3_ddrss_lpddr4_ecc_init(struct k3_ddrss_desc *ddrss) /* Preload the full memory with 0's using the BIST engine of * the LPDDR4 controller. */ - k3_ddrss_lpddr4_preload_full_mem(ddrss, gd->ram_size, 0); + k3_ddrss_lpddr4_preload_full_mem(ddrss, ddrss->ddr_ram_size, 0); /* Clear Error Count Register */ writel(0x1, base + DDRSS_ECC_1B_ERR_CNT_REG); @@ -742,6 +788,8 @@ static int k3_ddrss_probe(struct udevice *dev) k3_lpddr4_start(ddrss); + k3_ddrss_ddr_bank_base_size_calc(ddrss); + if (ddrss->ti_ecc_enabled) { if (!ddrss->ddrss_ss_cfg) { printf("%s: ss_cfg is required if ecc is enabled but not provided.", @@ -762,30 +810,24 @@ static int k3_ddrss_probe(struct udevice *dev) int k3_ddrss_ddr_fdt_fixup(struct udevice *dev, void *blob, struct bd_info *bd) { - struct k3_ddrss_desc *ddrss = dev_get_priv(dev); - u64 start[CONFIG_NR_DRAM_BANKS]; - u64 size[CONFIG_NR_DRAM_BANKS]; int bank; + struct k3_ddrss_desc *ddrss = dev_get_priv(dev); if (ddrss->ecc_reserved_space == 0) return 0; for (bank = CONFIG_NR_DRAM_BANKS - 1; bank >= 0; bank--) { - if (ddrss->ecc_reserved_space > bd->bi_dram[bank].size) { - ddrss->ecc_reserved_space -= bd->bi_dram[bank].size; - bd->bi_dram[bank].size = 0; + if (ddrss->ecc_reserved_space > ddrss->ddr_bank_size[bank]) { + ddrss->ecc_reserved_space -= ddrss->ddr_bank_size[bank]; + ddrss->ddr_bank_size[bank] = 0; } else { -
[PATCH v3 1/8] ram: k3-ddrss: Use the DDR controller BIST engine for ECC priming
From: Georgi Vlaev The 1-bit inline ECC support in TI's DDRSS bridge requires the configured memory regions to be preloaded with a pattern before use. This is done by the k3-ddrss driver from the R5 SPL in a 'for' loop. It takes around 10 seconds to fill 2GB of memory, for example. Memset can cut the time in half and using DMA currently yields a similar result. The BIST engine of DDR controller provides support for initializing any memory region with a pattern. This bypasses the DDRSS bridge, so the required inline ECC data is not computed and populated in the memory. For some values like zero, the computed ECC syndrome is also zero and we can use these values to preload the memory from the DDR controller, without the assistance of the bridge. The registers involved in the process are described in the 'DDR controller registers' topic in [1] AM62 and [2] J721E reference manuals. The patch replaces the 'for' loop memory fill function with the BIST memory initialization procedure. This cuts the time to preload the 2GB memory from 10 seconds down to 1 second. The bist preload function uses the lpddr4 APIs in the k3-ddrss, so this is compatible with devices with both 16-bit LPDDR4 and 32-bit LPDDR4 interfaces (e.g J721E). [1] AM62x: https://www.ti.com/lit/pdf/spruiv7 [2] DRA829/TDA4VM: https://www.ti.com/lit/zip/spruil1 Signed-off-by: Georgi Vlaev Signed-off-by: Santhosh Kumar K --- drivers/ram/k3-ddrss/k3-ddrss.c | 122 +--- 1 file changed, 114 insertions(+), 8 deletions(-) diff --git a/drivers/ram/k3-ddrss/k3-ddrss.c b/drivers/ram/k3-ddrss/k3-ddrss.c index a5c9b82cf1da..b656721e8e5b 100644 --- a/drivers/ram/k3-ddrss/k3-ddrss.c +++ b/drivers/ram/k3-ddrss/k3-ddrss.c @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -554,14 +555,118 @@ static void k3_ddrss_set_ecc_range_r0(u32 base, u32 start_address, u32 size) writel((start_address + size - 1) >> 16, base + DDRSS_ECC_R0_END_ADDR_REG); } -static void k3_ddrss_preload_ecc_mem_region(u32 *addr, u32 size, u32 word) +#define BIST_MODE_MEM_INIT 4 +#define BIST_MEM_INIT_TIMEOUT 1 /* 1msec loops per block = 10s */ +static void k3_lpddr4_bist_init_mem_region(struct k3_ddrss_desc *ddrss, + u64 addr, u64 size, + u32 pattern) { - int i; + lpddr4_obj *driverdt = ddrss->driverdt; + lpddr4_privatedata *pd = &ddrss->pd; + u32 status, offset, regval; + bool int_status; + int i = 0; + + /* Set BIST_START_ADDR_0 [31:0] */ + regval = (u32)(addr & TH_FLD_MASK(LPDDR4__BIST_START_ADDRESS_0__FLD)); + TH_OFFSET_FROM_REG(LPDDR4__BIST_START_ADDRESS_0__REG, CTL_SHIFT, offset); + driverdt->writereg(pd, LPDDR4_CTL_REGS, offset, regval); + + /* Set BIST_START_ADDR_1 [32 or 34:32] */ + regval = (u32)(addr >> TH_FLD_WIDTH(LPDDR4__BIST_START_ADDRESS_0__FLD)); + regval &= TH_FLD_MASK(LPDDR4__BIST_START_ADDRESS_1__FLD); + TH_OFFSET_FROM_REG(LPDDR4__BIST_START_ADDRESS_1__REG, CTL_SHIFT, offset); + driverdt->writereg(pd, LPDDR4_CTL_REGS, offset, regval); + + /* Set ADDR_SPACE = log2(size) */ + regval = (u32)(ilog2(size) << TH_FLD_SHIFT(LPDDR4__ADDR_SPACE__FLD)); + TH_OFFSET_FROM_REG(LPDDR4__ADDR_SPACE__REG, CTL_SHIFT, offset); + driverdt->writereg(pd, LPDDR4_CTL_REGS, offset, regval); + + /* Enable the BIST data check. On 32bit lpddr4 (e.g J7) this shares a +* register with ADDR_SPACE and BIST_GO. +*/ + TH_OFFSET_FROM_REG(LPDDR4__BIST_DATA_CHECK__REG, CTL_SHIFT, offset); + driverdt->readreg(pd, LPDDR4_CTL_REGS, offset, ®val); + regval |= TH_FLD_MASK(LPDDR4__BIST_DATA_CHECK__FLD); + driverdt->writereg(pd, LPDDR4_CTL_REGS, offset, regval); + /* Clear the address check bit */ + TH_OFFSET_FROM_REG(LPDDR4__BIST_ADDR_CHECK__REG, CTL_SHIFT, offset); + driverdt->readreg(pd, LPDDR4_CTL_REGS, offset, ®val); + regval &= ~TH_FLD_MASK(LPDDR4__BIST_ADDR_CHECK__FLD); + driverdt->writereg(pd, LPDDR4_CTL_REGS, offset, regval); + + /* Set BIST_TEST_MODE[2:0] to memory initialize (4) */ + regval = BIST_MODE_MEM_INIT; + TH_OFFSET_FROM_REG(LPDDR4__BIST_TEST_MODE__REG, CTL_SHIFT, offset); + driverdt->writereg(pd, LPDDR4_CTL_REGS, offset, regval); + + /* Set BIST_DATA_PATTERN[31:0] */ + TH_OFFSET_FROM_REG(LPDDR4__BIST_DATA_PATTERN_0__REG, CTL_SHIFT, offset); + driverdt->writereg(pd, LPDDR4_CTL_REGS, offset, pattern); + + /* Set BIST_DATA_PATTERN[63:32] */ + TH_OFFSET_FROM_REG(LPDDR4__BIST_DATA_PATTERN_1__REG, CTL_SHIFT, offset); + driverdt->writereg(pd, LPDDR4_CTL_REGS, offset, pattern); + + udelay(1000); + + /* Enable the programmed BIST operation - BIST_GO = 1 */ + TH_OFFSET_FROM_REG(LPDDR4__BIST_GO__REG, CTL_SHIFT, offset); + driverdt->readreg(pd, LPDDR4
[PATCH v3 0/8] Inline ECC Series
Hello, This series is to: Add support for Inline ECC in DDR for AM64X, AM62X, AM62AX, AM62PX, J721S2 and J784S4 devices. (1/8) Enable ECC priming with BIST engine (2/8) Add a function to store base address and size of RAM's banks in a 64-bit device private data (3/8) Setup the ECC region start and range (4/8) Enable ECC 1-bit error, 2-bit error and multiple-bit error interrupts (5/8) Add CONFIG_K3_INLINE_ECC (6/8) Set NR_DRAM_BANKS to 2 (7/8) Pull Redundant DDR functions to a common location and Fixup DDR size when ECC is enabled (8/8) Add ss_cfg reg entry Changes since v2: Removed 'default n' in Kconfig as that is default setting v2: https://lore.kernel.org/u-boot/20240510084707.1903133-1-s...@ti.com/ Changes since v1: Add support for J7* devices. v1: https://lore.kernel.org/u-boot/20240131060213.1128024-1-s...@ti.com/ Test Results: https://gist.github.com/santhosh21/53c6f285640c4b6dfb3420d84975d12a This series contains changes that grab the memory node from the DTS to set/modify DRAM bank sizes. A kernel patch has been sent [1] setting the required nodes to be available at bootloader stage. This patch series can be merged only after the DTS changes have been reflected in U-Boot either via OF_UPSTREAM (for devices that have moved to it) or via a sync to U-Boot patch. [1] https://lore.kernel.org/all/20240506110203.3230255-1-n-fran...@ti.com/ Thanks and Regards, Santhosh. Georgi Vlaev (1): ram: k3-ddrss: Use the DDR controller BIST engine for ECC priming Neha Malcom Francis (2): drivers: ram: Kconfig: Add CONFIG_K3_INLINE_ECC configs: j7*_evm_r5_defconfig: Set NR_DRAM_BANKS to 2 Santhosh Kumar K (5): ram: k3-ddrss: Add k3_ddrss_ddr_bank_base_size_calc() to solve 'calculations restricted to 32 bits' issue ram: k3-ddrss: Setup ECC region start and range ram: k3-ddrss: Enable ECC interrupts board: ti: Pull redundant DDR functions to a common location and Fixup DDR size when ECC is enabled arm: dts: k3-*-ddr: Add ss_cfg reg entry arch/arm/dts/k3-am62a-ddr.dtsi | 7 +- arch/arm/dts/k3-j721s2-ddr.dtsi | 12 +- arch/arm/dts/k3-j784s4-ddr.dtsi | 24 ++-- board/ti/am62ax/evm.c | 17 +-- board/ti/am62px/evm.c | 18 +-- board/ti/am62x/evm.c| 63 ++ board/ti/am64x/evm.c| 73 ++- board/ti/am65x/evm.c| 29 + board/ti/common/Makefile| 1 + board/ti/common/k3-ddr-init.c | 89 + board/ti/common/k3-ddr-init.h | 15 +++ board/ti/j721e/evm.c| 29 + board/ti/j721s2/evm.c | 35 ++ board/ti/j784s4/evm.c | 17 +-- configs/j7200_evm_r5_defconfig | 1 + configs/j721e_evm_r5_defconfig | 1 + configs/j721s2_evm_r5_defconfig | 1 + configs/j784s4_evm_r5_defconfig | 1 + drivers/ram/Kconfig | 10 ++ drivers/ram/k3-ddrss/k3-ddrss.c | 214 +++- 20 files changed, 390 insertions(+), 267 deletions(-) create mode 100644 board/ti/common/k3-ddr-init.c create mode 100644 board/ti/common/k3-ddr-init.h -- 2.34.1
Re: [PATCH v2 4/7] dts: beagleplay: binman: Include firmware capsules binman nodes
Tom Rini writes: > On Tue, May 21, 2024 at 09:20:26PM -0500, Jon Humphreys wrote: >> Tom Rini writes: >> >> > On Fri, Apr 19, 2024 at 04:28:16PM -0500, Jonathan Humphreys wrote: >> > >> >> Fill in the BeaglePlay's capsule GUID properties of the base binman >> >> capsule >> >> nodes. >> >> >> >> Signed-off-by: Jonathan Humphreys >> >> --- >> >> arch/arm/dts/k3-am625-beagleplay-u-boot.dtsi | 27 >> >> arch/arm/dts/k3-am625-r5-beagleplay.dts | 15 +++ >> >> 2 files changed, 42 insertions(+) >> > >> > This series introduces failure to build in CI, and it's a little tricky >> > to replicate locally, depending on your environment. You first need to >> > NOT have BINMAN_INDIRS set and instead be using fake binaries. Second, >> > it seems python version dependent perhaps? I don't see this on my host, >> > but by: >> > - Using the CI container >> > - Setting up a virtualenv inside of it >> > - pip install -r tools/buildman/requirements.txt >> > I get: >> > $ ./tools/buildman/buildman --keep-outputs --reproducible-builds -dvel >> > --force-build -PEWM --output /tmp/am62x_beagleplay_r5 --board >> > am62x_beagleplay_r5 >> > Building current source for 1 boards (1 thread, 12 jobs per thread) >> >arm: + am62x_beagleplay_r5 >> > +(am62x_beagleplay_r5) Image 'tiboot3-am62x-gp-evm.bin' is missing >> > optional external blobs but is still functional: ti-fs-gp.bin >> > +(am62x_beagleplay_r5) >> > +(am62x_beagleplay_r5) /binman/tiboot3-am62x-gp-evm.bin/ti-fs-gp.bin >> > (ti-sysfw/ti-fs-firmware-am62x-gp.bin): >> > +(am62x_beagleplay_r5)Missing blob >> > +(am62x_beagleplay_r5) binman: object of type 'NoneType' has no len() >> > +(am62x_beagleplay_r5) make[1]: *** [Makefile:1126: .binman_stamp] Error 1 >> > +(am62x_beagleplay_r5) make: *** [Makefile:177: sub-make] Error 2 >> > 001 /1 am62x_beagleplay_r5 >> >> Tom, this is failing in the CI container because the container is missing >> the mkeficapsule tool. >> >> To solve this, we just need to add it to the CI container. >> >> My understanding of binman's handling of missing bintools is that it should >> gracefully continue with fake data, so that buildman can successfully test >> out builds for boards even when you don't have all the required bintools. >> If I have that correct, I can also create a patch to properly handle this >> when using mkeficapsule. But I want to verify this is the desired behavior, >> since mkeficapsule isn't a unique or vendor specific tool, so shouldn't we >> require it as part of the U-Boot build environment and err out if it is >> missing? > > Perhaps it's a binman issue since we build mkeficapsule or at least > should be? Neha? > Never mind - I figured it out. The mkeficapsule tools is built by u-boot if TOOLS_MKEFICAPSULE config is set. I didn't explicitly set it because it is implied by EFI_CAPSULE_ON_DISK config. But this is only set for the A core u-boot, as that is what would apply the capsules. SPL running on the R cores does not need this. But that then means that the R core u-boot builds don't have TOOLS_MKEFICAPSULE set and if that is all that is being built (as in the case of buildman), the mkeficapsule tool isn't built and so is missing. So I need to explicitly set TOOLS_MKEFICAPSULE in the R core defconfigs. I'll repost the patches. Thanks for catching the bug, Jon > -- > Tom
Re: [PATCH 09/10] rockchip: evb-px30: do not remove pinctrl nodes from SPL DTB
On 2024/5/22 01:40, Quentin Schulz wrote: From: Quentin Schulz In order to be able to properly mux UART on PX30 EVB, the pinmux needs to be done at runtime, so let's not remove the pinctrl nodes from the SPL DTB. Signed-off-by: Quentin Schulz Reviewed-by: Kever Yang Thanks, - Kever --- configs/evb-px30_defconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configs/evb-px30_defconfig b/configs/evb-px30_defconfig index 50ce1d7a9f3..a5833ad6d09 100644 --- a/configs/evb-px30_defconfig +++ b/configs/evb-px30_defconfig @@ -51,7 +51,7 @@ CONFIG_CMD_USB_MASS_STORAGE=y CONFIG_EFI_PARTITION_ENTRIES_NUMBERS=64 CONFIG_SPL_OF_CONTROL=y CONFIG_OF_LIVE=y -CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents" +CONFIG_OF_SPL_REMOVE_PROPS="interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents" CONFIG_ENV_IS_IN_MMC=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_REGMAP=y
Re: [PATCH 10/10] rockchip: evb-px30: make UART5 the debug UART
On 2024/5/22 01:40, Quentin Schulz wrote: From: Quentin Schulz In the Device Tree, UART5 is the system UART, but in the defconfig it currently is UART2. Let's sync the two by making the defconfig use UART5 as well. Signed-off-by: Quentin Schulz Reviewed-by: Kever Yang Thanks, - Kever --- configs/evb-px30_defconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configs/evb-px30_defconfig b/configs/evb-px30_defconfig index a5833ad6d09..abe545625a5 100644 --- a/configs/evb-px30_defconfig +++ b/configs/evb-px30_defconfig @@ -10,7 +10,7 @@ CONFIG_ROCKCHIP_PX30=y CONFIG_TARGET_EVB_PX30=y # CONFIG_TPL_LIBCOMMON_SUPPORT is not set CONFIG_SPL_DRIVERS_MISC=y -CONFIG_DEBUG_UART_BASE=0xFF16 +CONFIG_DEBUG_UART_BASE=0xff178000 CONFIG_DEBUG_UART_CLOCK=2400 CONFIG_SYS_LOAD_ADDR=0x800800 CONFIG_DEBUG_UART=y
Re: [PATCH 08/10] rockchip: px30: make UART pinmux accessible to TPL/SPL DTB
On 2024/5/22 01:40, Quentin Schulz wrote: From: Quentin Schulz This adds the default pinmux for UART2 and UART5 to the TPL/SPL DTB (if not removed through the CONFIG_OF_SPL_REMOVE_PROPS symbol) as those two controllers are always made available to all boards. Signed-off-by: Quentin Schulz Reviewed-by: Kever Yang Thanks, - Kever --- arch/arm/dts/px30-u-boot.dtsi | 16 1 file changed, 16 insertions(+) diff --git a/arch/arm/dts/px30-u-boot.dtsi b/arch/arm/dts/px30-u-boot.dtsi index 046da022ffe..59fa9f43a97 100644 --- a/arch/arm/dts/px30-u-boot.dtsi +++ b/arch/arm/dts/px30-u-boot.dtsi @@ -33,11 +33,27 @@ bootph-all; }; +&uart2m0_xfer { + bootph-all; +}; + &uart5 { clock-frequency = <2400>; bootph-all; }; +&uart5_cts { + bootph-all; +}; + +&uart5_rts { + bootph-all; +}; + +&uart5_xfer { + bootph-all; +}; + &sdmmc { bootph-all;
Re: [PATCH 07/10] rockchip: px30-core-*: Use common bss and stack addresses
On 2024/5/22 01:40, Quentin Schulz wrote: From: Quentin Schulz U-Boot proper pre-reloc is currently running out of memory on PX30 Ringneck and it is thus impossible to boot into U-Boot CLI. It is assumed the same problem can be seen on other PX30 boards though I cannot guarantee it since I don't have access to them. Fix this by migrating to the common bss and stack addresses for PX30, which drastically increases the size of the pre-reloc allocation pool (8 times bigger now). The memory layout in SPL and U-Boot proper now match the other SoCs' using ROCKCHIP_COMMON_STACK_ADDR. Signed-off-by: Quentin Schulz Reviewed-by: Kever Yang Thanks, - Kever --- configs/px30-core-ctouch2-of10-px30_defconfig | 18 +++--- configs/px30-core-ctouch2-px30_defconfig | 18 +++--- configs/px30-core-edimm2.2-px30_defconfig | 18 +++--- 3 files changed, 9 insertions(+), 45 deletions(-) diff --git a/configs/px30-core-ctouch2-of10-px30_defconfig b/configs/px30-core-ctouch2-of10-px30_defconfig index 87a39e115df..dd005f20ff8 100644 --- a/configs/px30-core-ctouch2-of10-px30_defconfig +++ b/configs/px30-core-ctouch2-of10-px30_defconfig @@ -2,27 +2,15 @@ CONFIG_ARM=y CONFIG_SKIP_LOWLEVEL_INIT=y CONFIG_COUNTER_FREQUENCY=2400 CONFIG_ARCH_ROCKCHIP=y -CONFIG_TEXT_BASE=0x0020 -CONFIG_SYS_MALLOC_F_LEN=0x2000 -CONFIG_SPL_LIBCOMMON_SUPPORT=y -CONFIG_SPL_LIBGENERIC_SUPPORT=y CONFIG_NR_DRAM_BANKS=1 -CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y -CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x40 CONFIG_DEFAULT_DEVICE_TREE="px30-engicam-px30-core-ctouch2-of10" -CONFIG_SPL_TEXT_BASE=0x CONFIG_DM_RESET=y CONFIG_ROCKCHIP_PX30=y +# CONFIG_TPL_ROCKCHIP_COMMON_BOARD is not set CONFIG_TARGET_PX30_CORE=y CONFIG_DEBUG_UART_CHANNEL=1 -CONFIG_TPL_LIBGENERIC_SUPPORT=y +# CONFIG_TPL_LIBCOMMON_SUPPORT is not set CONFIG_SPL_DRIVERS_MISC=y -CONFIG_SPL_STACK_R_ADDR=0x60 -CONFIG_SPL_STACK=0x40 -CONFIG_SPL_HAS_BSS_LINKER_SECTION=y -CONFIG_SPL_BSS_START_ADDR=0x400 -CONFIG_SPL_BSS_MAX_SIZE=0x4000 -CONFIG_SPL_STACK_R=y CONFIG_DEBUG_UART_BASE=0xFF16 CONFIG_DEBUG_UART_CLOCK=2400 CONFIG_SYS_LOAD_ADDR=0x800800 @@ -40,9 +28,9 @@ CONFIG_SPL_MAX_SIZE=0x2 CONFIG_SPL_PAD_TO=0x7f8000 CONFIG_SPL_BOOTROM_SUPPORT=y # CONFIG_SPL_RAW_IMAGE_SUPPORT is not set -# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set CONFIG_SPL_ATF=y # CONFIG_TPL_FRAMEWORK is not set +# CONFIG_TPL_SYS_MALLOC_SIMPLE is not set # CONFIG_TPL_BANNER_PRINT is not set # CONFIG_CMD_BOOTD is not set # CONFIG_CMD_ELF is not set diff --git a/configs/px30-core-ctouch2-px30_defconfig b/configs/px30-core-ctouch2-px30_defconfig index 7162c117beb..f6559fbae3a 100644 --- a/configs/px30-core-ctouch2-px30_defconfig +++ b/configs/px30-core-ctouch2-px30_defconfig @@ -2,27 +2,15 @@ CONFIG_ARM=y CONFIG_SKIP_LOWLEVEL_INIT=y CONFIG_COUNTER_FREQUENCY=2400 CONFIG_ARCH_ROCKCHIP=y -CONFIG_TEXT_BASE=0x0020 -CONFIG_SYS_MALLOC_F_LEN=0x2000 -CONFIG_SPL_LIBCOMMON_SUPPORT=y -CONFIG_SPL_LIBGENERIC_SUPPORT=y CONFIG_NR_DRAM_BANKS=1 -CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y -CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x40 CONFIG_DEFAULT_DEVICE_TREE="px30-engicam-px30-core-ctouch2" -CONFIG_SPL_TEXT_BASE=0x CONFIG_DM_RESET=y CONFIG_ROCKCHIP_PX30=y +# CONFIG_TPL_ROCKCHIP_COMMON_BOARD is not set CONFIG_TARGET_PX30_CORE=y CONFIG_DEBUG_UART_CHANNEL=1 -CONFIG_TPL_LIBGENERIC_SUPPORT=y +# CONFIG_TPL_LIBCOMMON_SUPPORT is not set CONFIG_SPL_DRIVERS_MISC=y -CONFIG_SPL_STACK_R_ADDR=0x60 -CONFIG_SPL_STACK=0x40 -CONFIG_SPL_HAS_BSS_LINKER_SECTION=y -CONFIG_SPL_BSS_START_ADDR=0x400 -CONFIG_SPL_BSS_MAX_SIZE=0x4000 -CONFIG_SPL_STACK_R=y CONFIG_DEBUG_UART_BASE=0xFF16 CONFIG_DEBUG_UART_CLOCK=2400 CONFIG_SYS_LOAD_ADDR=0x800800 @@ -40,9 +28,9 @@ CONFIG_SPL_MAX_SIZE=0x2 CONFIG_SPL_PAD_TO=0x7f8000 CONFIG_SPL_BOOTROM_SUPPORT=y # CONFIG_SPL_RAW_IMAGE_SUPPORT is not set -# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set CONFIG_SPL_ATF=y # CONFIG_TPL_FRAMEWORK is not set +# CONFIG_TPL_SYS_MALLOC_SIMPLE is not set # CONFIG_TPL_BANNER_PRINT is not set # CONFIG_CMD_BOOTD is not set # CONFIG_CMD_ELF is not set diff --git a/configs/px30-core-edimm2.2-px30_defconfig b/configs/px30-core-edimm2.2-px30_defconfig index 1182f60358f..a099e9378c9 100644 --- a/configs/px30-core-edimm2.2-px30_defconfig +++ b/configs/px30-core-edimm2.2-px30_defconfig @@ -2,27 +2,15 @@ CONFIG_ARM=y CONFIG_SKIP_LOWLEVEL_INIT=y CONFIG_COUNTER_FREQUENCY=2400 CONFIG_ARCH_ROCKCHIP=y -CONFIG_TEXT_BASE=0x0020 -CONFIG_SYS_MALLOC_F_LEN=0x2000 -CONFIG_SPL_LIBCOMMON_SUPPORT=y -CONFIG_SPL_LIBGENERIC_SUPPORT=y CONFIG_NR_DRAM_BANKS=1 -CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y -CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x40 CONFIG_DEFAULT_DEVICE_TREE="px30-engicam-px30-core-edimm2.2" -CONFIG_SPL_TEXT_BASE=0x CONFIG_DM_RESET=y CONFIG_ROCKCHIP_PX30=y +# CONFIG_TPL_ROCKCHIP_COMMON_BOARD is not set CONFIG_TARGET_PX30_CORE=y
Re: [PATCH 06/10] rockchip: odroid-go2: Use common bss and stack addresses
On 2024/5/22 01:39, Quentin Schulz wrote: From: Quentin Schulz U-Boot proper pre-reloc is currently running out of memory on PX30 Ringneck and it is thus impossible to boot into U-Boot CLI. It is assumed the same problem can be seen on other PX30 boards though I cannot guarantee it since I don't have access to them. Fix this by migrating to the common bss and stack addresses for PX30, which drastically increases the size of the pre-reloc allocation pool (8 times bigger now). The memory layout in SPL and U-Boot proper now match the other SoCs' using ROCKCHIP_COMMON_STACK_ADDR. Signed-off-by: Quentin Schulz Reviewed-by: Kever Yang Thanks, - Kever --- configs/odroid-go2_defconfig | 18 +++--- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/configs/odroid-go2_defconfig b/configs/odroid-go2_defconfig index 3c1abb83ed9..f4c9b02e12f 100644 --- a/configs/odroid-go2_defconfig +++ b/configs/odroid-go2_defconfig @@ -2,29 +2,17 @@ CONFIG_ARM=y CONFIG_SKIP_LOWLEVEL_INIT=y CONFIG_COUNTER_FREQUENCY=2400 CONFIG_ARCH_ROCKCHIP=y -CONFIG_TEXT_BASE=0x0020 -CONFIG_SYS_MALLOC_F_LEN=0x2000 -CONFIG_SPL_LIBCOMMON_SUPPORT=y -CONFIG_SPL_LIBGENERIC_SUPPORT=y CONFIG_NR_DRAM_BANKS=1 -CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y -CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x40 CONFIG_ENV_SIZE=0x4000 CONFIG_ENV_OFFSET=0x4000 CONFIG_DEFAULT_DEVICE_TREE="rk3326-odroid-go2" -CONFIG_SPL_TEXT_BASE=0x CONFIG_DM_RESET=y CONFIG_ROCKCHIP_PX30=y +# CONFIG_TPL_ROCKCHIP_COMMON_BOARD is not set CONFIG_TARGET_ODROID_GO2=y CONFIG_DEBUG_UART_CHANNEL=1 -CONFIG_TPL_LIBGENERIC_SUPPORT=y +# CONFIG_TPL_LIBCOMMON_SUPPORT is not set CONFIG_SPL_DRIVERS_MISC=y -CONFIG_SPL_STACK_R_ADDR=0x60 -CONFIG_SPL_STACK=0x40 -CONFIG_SPL_HAS_BSS_LINKER_SECTION=y -CONFIG_SPL_BSS_START_ADDR=0x400 -CONFIG_SPL_BSS_MAX_SIZE=0x4000 -CONFIG_SPL_STACK_R=y CONFIG_DEBUG_UART_BASE=0xFF16 CONFIG_DEBUG_UART_CLOCK=2400 CONFIG_SYS_LOAD_ADDR=0x800800 @@ -44,11 +32,11 @@ CONFIG_SPL_MAX_SIZE=0x2 CONFIG_SPL_PAD_TO=0x7f8000 CONFIG_SPL_BOOTROM_SUPPORT=y # CONFIG_SPL_RAW_IMAGE_SUPPORT is not set -# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set CONFIG_SPL_I2C=y CONFIG_SPL_POWER=y CONFIG_SPL_ATF=y # CONFIG_TPL_FRAMEWORK is not set +# CONFIG_TPL_SYS_MALLOC_SIMPLE is not set # CONFIG_TPL_BANNER_PRINT is not set # CONFIG_CMD_BOOTD is not set # CONFIG_CMD_ELF is not set
Re: [PATCH 04/10] rockchip: evb-px30: Use common bss and stack addresses
On 2024/5/22 01:39, Quentin Schulz wrote: From: Quentin Schulz U-Boot proper pre-reloc is currently running out of memory on PX30 Ringneck and it is thus impossible to boot into U-Boot CLI. It is assumed the same problem can be seen on other PX30 boards though I cannot guarantee it since I don't have access to them. Fix this by migrating to the common bss and stack addresses for PX30, which drastically increases the size of the pre-reloc allocation pool (8 times bigger now). The memory layout in SPL and U-Boot proper now match the other SoCs' using ROCKCHIP_COMMON_STACK_ADDR. Signed-off-by: Quentin Schulz Reviewed-by: Kever Yang Thanks, - Kever --- configs/evb-px30_defconfig | 18 +++--- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/configs/evb-px30_defconfig b/configs/evb-px30_defconfig index 73a3c6120e0..50ce1d7a9f3 100644 --- a/configs/evb-px30_defconfig +++ b/configs/evb-px30_defconfig @@ -2,26 +2,14 @@ CONFIG_ARM=y CONFIG_SKIP_LOWLEVEL_INIT=y CONFIG_COUNTER_FREQUENCY=2400 CONFIG_ARCH_ROCKCHIP=y -CONFIG_TEXT_BASE=0x0020 -CONFIG_SYS_MALLOC_F_LEN=0x2000 -CONFIG_SPL_LIBCOMMON_SUPPORT=y -CONFIG_SPL_LIBGENERIC_SUPPORT=y CONFIG_NR_DRAM_BANKS=1 -CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y -CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x40 CONFIG_DEFAULT_DEVICE_TREE="px30-evb" -CONFIG_SPL_TEXT_BASE=0x CONFIG_DM_RESET=y CONFIG_ROCKCHIP_PX30=y +# CONFIG_TPL_ROCKCHIP_COMMON_BOARD is not set CONFIG_TARGET_EVB_PX30=y -CONFIG_TPL_LIBGENERIC_SUPPORT=y +# CONFIG_TPL_LIBCOMMON_SUPPORT is not set CONFIG_SPL_DRIVERS_MISC=y -CONFIG_SPL_STACK_R_ADDR=0x60 -CONFIG_SPL_STACK=0x40 -CONFIG_SPL_HAS_BSS_LINKER_SECTION=y -CONFIG_SPL_BSS_START_ADDR=0x400 -CONFIG_SPL_BSS_MAX_SIZE=0x4000 -CONFIG_SPL_STACK_R=y CONFIG_DEBUG_UART_BASE=0xFF16 CONFIG_DEBUG_UART_CLOCK=2400 CONFIG_SYS_LOAD_ADDR=0x800800 @@ -39,9 +27,9 @@ CONFIG_SPL_MAX_SIZE=0x2 CONFIG_SPL_PAD_TO=0x7f8000 CONFIG_SPL_BOOTROM_SUPPORT=y # CONFIG_SPL_RAW_IMAGE_SUPPORT is not set -# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set CONFIG_SPL_ATF=y # CONFIG_TPL_FRAMEWORK is not set +# CONFIG_TPL_SYS_MALLOC_SIMPLE is not set # CONFIG_TPL_BANNER_PRINT is not set # CONFIG_CMD_BOOTD is not set # CONFIG_CMD_ELF is not set
Re: [PATCH 03/10] rockchip: ringneck_px30: Use common bss and stack addresses
On 2024/5/22 01:39, Quentin Schulz wrote: From: Quentin Schulz U-Boot proper pre-reloc is currently running out of memory and it is thus impossible to boot into U-Boot CLI. Fix this by migrating to the common bss and stack addresses for PX30, which drastically increases the size of the pre-reloc allocation pool (8 times bigger now). The memory layout in SPL and U-Boot proper now match the other SoCs' using ROCKCHIP_COMMON_STACK_ADDR. Signed-off-by: Quentin Schulz Reviewed-by: Kever Yang Thanks, - Kever --- configs/ringneck-px30_defconfig | 18 +++--- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/configs/ringneck-px30_defconfig b/configs/ringneck-px30_defconfig index 0df1b8a59ac..94179dca3ae 100644 --- a/configs/ringneck-px30_defconfig +++ b/configs/ringneck-px30_defconfig @@ -2,27 +2,15 @@ CONFIG_ARM=y CONFIG_SKIP_LOWLEVEL_INIT=y CONFIG_COUNTER_FREQUENCY=2400 CONFIG_ARCH_ROCKCHIP=y -CONFIG_TEXT_BASE=0x0020 -CONFIG_SYS_MALLOC_F_LEN=0x2000 CONFIG_SPL_GPIO=y -CONFIG_SPL_LIBCOMMON_SUPPORT=y -CONFIG_SPL_LIBGENERIC_SUPPORT=y CONFIG_NR_DRAM_BANKS=2 -CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y -CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x40 CONFIG_DEFAULT_DEVICE_TREE="px30-ringneck-haikou" -CONFIG_SPL_TEXT_BASE=0x CONFIG_DM_RESET=y CONFIG_ROCKCHIP_PX30=y +# CONFIG_TPL_ROCKCHIP_COMMON_BOARD is not set CONFIG_TARGET_RINGNECK_PX30=y -CONFIG_TPL_LIBGENERIC_SUPPORT=y +# CONFIG_TPL_LIBCOMMON_SUPPORT is not set CONFIG_SPL_DRIVERS_MISC=y -CONFIG_SPL_STACK_R_ADDR=0x60 -CONFIG_SPL_STACK=0x40 -CONFIG_SPL_HAS_BSS_LINKER_SECTION=y -CONFIG_SPL_BSS_START_ADDR=0x400 -CONFIG_SPL_BSS_MAX_SIZE=0x4000 -CONFIG_SPL_STACK_R=y CONFIG_DEBUG_UART_BASE=0xFF03 CONFIG_DEBUG_UART_CLOCK=2400 CONFIG_SYS_LOAD_ADDR=0x800800 @@ -41,11 +29,11 @@ CONFIG_SPL_PAD_TO=0x0 CONFIG_SPL_BOARD_INIT=y CONFIG_SPL_BOOTROM_SUPPORT=y # CONFIG_SPL_RAW_IMAGE_SUPPORT is not set -# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set CONFIG_SPL_SYS_MALLOC=y CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x200 CONFIG_SPL_ATF=y # CONFIG_TPL_FRAMEWORK is not set +# CONFIG_TPL_SYS_MALLOC_SIMPLE is not set # CONFIG_CMD_BOOTD is not set # CONFIG_CMD_ELF is not set # CONFIG_CMD_IMI is not set
Re: [PATCH 05/10] rockchip: firefly-px30: Use common bss and stack addresses
On 2024/5/22 01:39, Quentin Schulz wrote: From: Quentin Schulz U-Boot proper pre-reloc is currently running out of memory on PX30 Ringneck and it is thus impossible to boot into U-Boot CLI. It is assumed the same problem can be seen on other PX30 boards though I cannot guarantee it since I don't have access to them. Fix this by migrating to the common bss and stack addresses for PX30, which drastically increases the size of the pre-reloc allocation pool (8 times bigger now). The memory layout in SPL and U-Boot proper now match the other SoCs' using ROCKCHIP_COMMON_STACK_ADDR. Signed-off-by: Quentin Schulz Reviewed-by: Kever Yang Thanks, - Kever --- configs/firefly-px30_defconfig | 18 +++--- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/configs/firefly-px30_defconfig b/configs/firefly-px30_defconfig index 0a14b393667..063e4211fb7 100644 --- a/configs/firefly-px30_defconfig +++ b/configs/firefly-px30_defconfig @@ -2,27 +2,15 @@ CONFIG_ARM=y CONFIG_SKIP_LOWLEVEL_INIT=y CONFIG_COUNTER_FREQUENCY=2400 CONFIG_ARCH_ROCKCHIP=y -CONFIG_TEXT_BASE=0x0020 -CONFIG_SYS_MALLOC_F_LEN=0x2000 -CONFIG_SPL_LIBCOMMON_SUPPORT=y -CONFIG_SPL_LIBGENERIC_SUPPORT=y CONFIG_NR_DRAM_BANKS=1 -CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y -CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x40 CONFIG_DEFAULT_DEVICE_TREE="px30-firefly" -CONFIG_SPL_TEXT_BASE=0x CONFIG_DM_RESET=y CONFIG_ROCKCHIP_PX30=y +# CONFIG_TPL_ROCKCHIP_COMMON_BOARD is not set CONFIG_TARGET_EVB_PX30=y CONFIG_DEBUG_UART_CHANNEL=1 -CONFIG_TPL_LIBGENERIC_SUPPORT=y +# CONFIG_TPL_LIBCOMMON_SUPPORT is not set CONFIG_SPL_DRIVERS_MISC=y -CONFIG_SPL_STACK_R_ADDR=0x60 -CONFIG_SPL_STACK=0x40 -CONFIG_SPL_HAS_BSS_LINKER_SECTION=y -CONFIG_SPL_BSS_START_ADDR=0x400 -CONFIG_SPL_BSS_MAX_SIZE=0x4000 -CONFIG_SPL_STACK_R=y CONFIG_DEBUG_UART_BASE=0xFF16 CONFIG_DEBUG_UART_CLOCK=2400 CONFIG_SYS_LOAD_ADDR=0x800800 @@ -40,9 +28,9 @@ CONFIG_SPL_MAX_SIZE=0x2 CONFIG_SPL_PAD_TO=0x7f8000 CONFIG_SPL_BOOTROM_SUPPORT=y # CONFIG_SPL_RAW_IMAGE_SUPPORT is not set -# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set CONFIG_SPL_ATF=y # CONFIG_TPL_FRAMEWORK is not set +# CONFIG_TPL_SYS_MALLOC_SIMPLE is not set # CONFIG_TPL_BANNER_PRINT is not set # CONFIG_CMD_BOOTD is not set # CONFIG_CMD_ELF is not set
Re: [PATCH 02/10] rockchip: Use common bss and stack addresses on PX30
On 2024/5/22 01:39, Quentin Schulz wrote: From: Quentin Schulz See commit 008ba0d56d00 ("rockchip: Add common default bss and stack addresses") for memory layout. This migrates PX30 to use the new layout, except for TPL. Indeed, PX30 is extremely limited in SRAM, so we need to be extra careful about what goes into the TPL and how much we can allocate there, so let's keep the current value for TPL_SYS_MALLOC_F_LEN (already present in the PX30-specific Kconfig, from an earlier commit). This will allow us to use the same memory layout on one more Rockchip SoC, which is always a nice thing. Additionally, this will make it easier to fix U-Boot proper pre-reloc running out of memory on PX30 in a subsequent commit. Signed-off-by: Quentin Schulz Reviewed-by: Kever Yang Thanks, - Kever --- arch/arm/mach-rockchip/px30/Kconfig | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-rockchip/px30/Kconfig b/arch/arm/mach-rockchip/px30/Kconfig index e39472604c3..dcf9eb8144b 100644 --- a/arch/arm/mach-rockchip/px30/Kconfig +++ b/arch/arm/mach-rockchip/px30/Kconfig @@ -68,8 +68,11 @@ config ROCKCHIP_STIMER_BASE config SYS_SOC default "px30" +config ROCKCHIP_COMMON_STACK_ADDR + default y + config SYS_MALLOC_F_LEN - default 0x400 + default 0x400 if !SPL_SHARES_INIT_SP_ADDR config SPL_SERIAL default y
Re: [PATCH 01/10] rockchip: px30: default TPL_SYS_MALLOC_F_LEN to 0x600 on PX30 Kconfig level
On 2024/5/22 01:39, Quentin Schulz wrote: From: Quentin Schulz This is the kind of setting that typically doesn't need to be changed between boards based on the same SoC, so let's make it the default in PX30 Kconfig so we don't have to care about it in the defconfig if we don't want to. Signed-off-by: Quentin Schulz Reviewed-by: Kever Yang Thanks, - Kever --- arch/arm/mach-rockchip/px30/Kconfig | 3 +++ configs/evb-px30_defconfig| 1 - configs/firefly-px30_defconfig| 1 - configs/odroid-go2_defconfig | 1 - configs/px30-core-ctouch2-of10-px30_defconfig | 1 - configs/px30-core-ctouch2-px30_defconfig | 1 - configs/px30-core-edimm2.2-px30_defconfig | 1 - configs/ringneck-px30_defconfig | 1 - 8 files changed, 3 insertions(+), 7 deletions(-) diff --git a/arch/arm/mach-rockchip/px30/Kconfig b/arch/arm/mach-rockchip/px30/Kconfig index 23f8f430c4a..e39472604c3 100644 --- a/arch/arm/mach-rockchip/px30/Kconfig +++ b/arch/arm/mach-rockchip/px30/Kconfig @@ -83,6 +83,9 @@ config TPL_TEXT_BASE config TPL_STACK default 0xff0e4fff +config TPL_SYS_MALLOC_F_LEN + default 0x600 + config DEBUG_UART_CHANNEL int "Mux channel to use for debug UART2/UART3" depends on DEBUG_UART_BOARD_INIT diff --git a/configs/evb-px30_defconfig b/configs/evb-px30_defconfig index 07c56a45ec0..73a3c6120e0 100644 --- a/configs/evb-px30_defconfig +++ b/configs/evb-px30_defconfig @@ -16,7 +16,6 @@ CONFIG_ROCKCHIP_PX30=y CONFIG_TARGET_EVB_PX30=y CONFIG_TPL_LIBGENERIC_SUPPORT=y CONFIG_SPL_DRIVERS_MISC=y -CONFIG_TPL_SYS_MALLOC_F_LEN=0x600 CONFIG_SPL_STACK_R_ADDR=0x60 CONFIG_SPL_STACK=0x40 CONFIG_SPL_HAS_BSS_LINKER_SECTION=y diff --git a/configs/firefly-px30_defconfig b/configs/firefly-px30_defconfig index e5377dcdf3d..0a14b393667 100644 --- a/configs/firefly-px30_defconfig +++ b/configs/firefly-px30_defconfig @@ -17,7 +17,6 @@ CONFIG_TARGET_EVB_PX30=y CONFIG_DEBUG_UART_CHANNEL=1 CONFIG_TPL_LIBGENERIC_SUPPORT=y CONFIG_SPL_DRIVERS_MISC=y -CONFIG_TPL_SYS_MALLOC_F_LEN=0x600 CONFIG_SPL_STACK_R_ADDR=0x60 CONFIG_SPL_STACK=0x40 CONFIG_SPL_HAS_BSS_LINKER_SECTION=y diff --git a/configs/odroid-go2_defconfig b/configs/odroid-go2_defconfig index 99d7149a44c..3c1abb83ed9 100644 --- a/configs/odroid-go2_defconfig +++ b/configs/odroid-go2_defconfig @@ -19,7 +19,6 @@ CONFIG_TARGET_ODROID_GO2=y CONFIG_DEBUG_UART_CHANNEL=1 CONFIG_TPL_LIBGENERIC_SUPPORT=y CONFIG_SPL_DRIVERS_MISC=y -CONFIG_TPL_SYS_MALLOC_F_LEN=0x600 CONFIG_SPL_STACK_R_ADDR=0x60 CONFIG_SPL_STACK=0x40 CONFIG_SPL_HAS_BSS_LINKER_SECTION=y diff --git a/configs/px30-core-ctouch2-of10-px30_defconfig b/configs/px30-core-ctouch2-of10-px30_defconfig index a2801ec7796..87a39e115df 100644 --- a/configs/px30-core-ctouch2-of10-px30_defconfig +++ b/configs/px30-core-ctouch2-of10-px30_defconfig @@ -17,7 +17,6 @@ CONFIG_TARGET_PX30_CORE=y CONFIG_DEBUG_UART_CHANNEL=1 CONFIG_TPL_LIBGENERIC_SUPPORT=y CONFIG_SPL_DRIVERS_MISC=y -CONFIG_TPL_SYS_MALLOC_F_LEN=0x600 CONFIG_SPL_STACK_R_ADDR=0x60 CONFIG_SPL_STACK=0x40 CONFIG_SPL_HAS_BSS_LINKER_SECTION=y diff --git a/configs/px30-core-ctouch2-px30_defconfig b/configs/px30-core-ctouch2-px30_defconfig index cc33e275742..7162c117beb 100644 --- a/configs/px30-core-ctouch2-px30_defconfig +++ b/configs/px30-core-ctouch2-px30_defconfig @@ -17,7 +17,6 @@ CONFIG_TARGET_PX30_CORE=y CONFIG_DEBUG_UART_CHANNEL=1 CONFIG_TPL_LIBGENERIC_SUPPORT=y CONFIG_SPL_DRIVERS_MISC=y -CONFIG_TPL_SYS_MALLOC_F_LEN=0x600 CONFIG_SPL_STACK_R_ADDR=0x60 CONFIG_SPL_STACK=0x40 CONFIG_SPL_HAS_BSS_LINKER_SECTION=y diff --git a/configs/px30-core-edimm2.2-px30_defconfig b/configs/px30-core-edimm2.2-px30_defconfig index 99e1b2fc7ae..1182f60358f 100644 --- a/configs/px30-core-edimm2.2-px30_defconfig +++ b/configs/px30-core-edimm2.2-px30_defconfig @@ -17,7 +17,6 @@ CONFIG_TARGET_PX30_CORE=y CONFIG_DEBUG_UART_CHANNEL=1 CONFIG_TPL_LIBGENERIC_SUPPORT=y CONFIG_SPL_DRIVERS_MISC=y -CONFIG_TPL_SYS_MALLOC_F_LEN=0x600 CONFIG_SPL_STACK_R_ADDR=0x60 CONFIG_SPL_STACK=0x40 CONFIG_SPL_HAS_BSS_LINKER_SECTION=y diff --git a/configs/ringneck-px30_defconfig b/configs/ringneck-px30_defconfig index 67a44eda684..0df1b8a59ac 100644 --- a/configs/ringneck-px30_defconfig +++ b/configs/ringneck-px30_defconfig @@ -17,7 +17,6 @@ CONFIG_ROCKCHIP_PX30=y CONFIG_TARGET_RINGNECK_PX30=y CONFIG_TPL_LIBGENERIC_SUPPORT=y CONFIG_SPL_DRIVERS_MISC=y -CONFIG_TPL_SYS_MALLOC_F_LEN=0x600 CONFIG_SPL_STACK_R_ADDR=0x60 CONFIG_SPL_STACK=0x40 CONFIG_SPL_HAS_BSS_LINKER_SECTION=y
Re: [PATCH 1/2 V2] Revert "board: rockchip: Add early ADC button detect for RGxx3"
On 2024/5/21 23:45, Chris Morgan wrote: From: Chris Morgan This reverts commit 41a60d0e5cef54a59596a58940fa7c9cf071034b. On some of the supported devices the adc detect code always returns that the button has been pushed, and as a result the device will not boot normally. Have you check the key input voltage with voltameter which can identify is hardware issue or software issue. Thanks, - Kever Signed-off-by: Chris Morgan --- board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c | 64 -- 1 file changed, 64 deletions(-) diff --git a/board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c b/board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c index 099eea60c3..5c57b902d1 100644 --- a/board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c +++ b/board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c @@ -6,14 +6,12 @@ #include #include #include -#include #include #include #include #include #include #include -#include #include #include #include @@ -21,8 +19,6 @@ #include #include -#define BOOT_BROM_DOWNLOAD 0xef08a53c - #define GPIO0_BASE0xfdd6 #define GPIO4_BASE0xfe77 #define GPIO_SWPORT_DR_L 0x @@ -36,14 +32,6 @@ #define GPIO_WRITEMASK(bits) ((bits) << 16) -#define SARADC_BASE 0xfe72 -#define SARADC_DATA0x -#define SARADC_STAS0x0004 -#define SARADC_ADC_STATUS BIT(0) -#define SARADC_CTRL0x0008 -#define SARADC_INPUT_SRC_MSK 0x7 -#define SARADC_POWER_CTRL BIT(3) - #define DTB_DIR "rockchip/" struct rg3xx_model { @@ -169,64 +157,12 @@ static const struct rg353_panel rg353_panel_details[] = { }, }; -/* - * The device has internal eMMC, and while some devices have an exposed - * clk pin you can ground to force a bypass not all devices do. As a - * result it may be possible for some devices to become a perma-brick - * if a corrupted TPL or SPL stage with a valid header is flashed to - * the internal eMMC. Add functionality to read ADC channel 0 (the func - * button) as early as possible in the boot process to provide some - * protection against this. If we ever get an open TPL stage, we should - * consider moving this function there. - */ -void read_func_button(void) -{ - int ret; - u32 reg; - - /* Turn off SARADC to reset it. */ - writel(0, (SARADC_BASE + SARADC_CTRL)); - - /* Enable channel 0 and power on SARADC. */ - writel(((0 & SARADC_INPUT_SRC_MSK) | SARADC_POWER_CTRL), - (SARADC_BASE + SARADC_CTRL)); - - /* -* Wait for data to be ready. Use timeout of 2us from -* rockchip_saradc driver. -*/ - ret = readl_poll_timeout((SARADC_BASE + SARADC_STAS), reg, -!(reg & SARADC_ADC_STATUS), 2); - if (ret) { - printf("ADC Timeout"); - return; - } - - /* Read the data from the SARADC. */ - reg = readl((SARADC_BASE + SARADC_DATA)); - - /* Turn the SARADC back off so it's ready to be used again. */ - writel(0, (SARADC_BASE + SARADC_CTRL)); - - /* -* If the value is less than 30 the button is being pressed. -* Reset the device back into Rockchip download mode. -*/ - if (reg <= 30) { - printf("download key pressed, entering download mode..."); - writel(BOOT_BROM_DOWNLOAD, CONFIG_ROCKCHIP_BOOT_MODE_REG); - do_reset(NULL, 0, 0, NULL); - } -}; - /* * Start LED very early so user knows device is on. Set color * to red. */ void spl_board_init(void) { - read_func_button(); - /* Set GPIO0_C5, GPIO0_C6, and GPIO0_C7 to output. */ writel(GPIO_WRITEMASK(GPIO_C7 | GPIO_C6 | GPIO_C5) | \ (GPIO_C7 | GPIO_C6 | GPIO_C5),
Re: [PATCH 2/2 V2] board: rockchip: rgxx3: Use sdmmc0 as first device
On 2024/5/21 23:45, Chris Morgan wrote: From: Chris Morgan Some of the rgxx3 devices do not have a way to recover from a poor flash of a bootloader to eMMC. Set the device to always attempt to boot from sdmmc0 first which ensures that we can override the boot from emmc if we have a card present with a valid fit signature. The expectation is that this will protect from the very unlikely chance we have a valid FIT signature on the eMMC but the U-Boot stage fails for some other reason. Signed-off-by: Chris Morgan Reviewed-by: Kever Yang Thanks, - Kever --- arch/arm/dts/rk3566-anbernic-rgxx3-u-boot.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/dts/rk3566-anbernic-rgxx3-u-boot.dtsi b/arch/arm/dts/rk3566-anbernic-rgxx3-u-boot.dtsi index 793ed4ae8a..c7e849816a 100644 --- a/arch/arm/dts/rk3566-anbernic-rgxx3-u-boot.dtsi +++ b/arch/arm/dts/rk3566-anbernic-rgxx3-u-boot.dtsi @@ -4,7 +4,7 @@ / { chosen { - u-boot,spl-boot-order = "same-as-spl", &sdmmc1, &sdmmc0; + u-boot,spl-boot-order = &sdmmc0, &sdhci; }; };
Re: [PATCH 1/2 V2] Revert "board: rockchip: Add early ADC button detect for RGxx3"
On 2024/5/21 23:45, Chris Morgan wrote: From: Chris Morgan This reverts commit 41a60d0e5cef54a59596a58940fa7c9cf071034b. On some of the supported devices the adc detect code always returns that the button has been pushed, and as a result the device will not boot normally. Signed-off-by: Chris Morgan Reviewed-by: Kever Yang Thanks, - Kever --- board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c | 64 -- 1 file changed, 64 deletions(-) diff --git a/board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c b/board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c index 099eea60c3..5c57b902d1 100644 --- a/board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c +++ b/board/anbernic/rgxx3_rk3566/rgxx3-rk3566.c @@ -6,14 +6,12 @@ #include #include #include -#include #include #include #include #include #include #include -#include #include #include #include @@ -21,8 +19,6 @@ #include #include -#define BOOT_BROM_DOWNLOAD 0xef08a53c - #define GPIO0_BASE0xfdd6 #define GPIO4_BASE0xfe77 #define GPIO_SWPORT_DR_L 0x @@ -36,14 +32,6 @@ #define GPIO_WRITEMASK(bits) ((bits) << 16) -#define SARADC_BASE 0xfe72 -#define SARADC_DATA0x -#define SARADC_STAS0x0004 -#define SARADC_ADC_STATUS BIT(0) -#define SARADC_CTRL0x0008 -#define SARADC_INPUT_SRC_MSK 0x7 -#define SARADC_POWER_CTRL BIT(3) - #define DTB_DIR "rockchip/" struct rg3xx_model { @@ -169,64 +157,12 @@ static const struct rg353_panel rg353_panel_details[] = { }, }; -/* - * The device has internal eMMC, and while some devices have an exposed - * clk pin you can ground to force a bypass not all devices do. As a - * result it may be possible for some devices to become a perma-brick - * if a corrupted TPL or SPL stage with a valid header is flashed to - * the internal eMMC. Add functionality to read ADC channel 0 (the func - * button) as early as possible in the boot process to provide some - * protection against this. If we ever get an open TPL stage, we should - * consider moving this function there. - */ -void read_func_button(void) -{ - int ret; - u32 reg; - - /* Turn off SARADC to reset it. */ - writel(0, (SARADC_BASE + SARADC_CTRL)); - - /* Enable channel 0 and power on SARADC. */ - writel(((0 & SARADC_INPUT_SRC_MSK) | SARADC_POWER_CTRL), - (SARADC_BASE + SARADC_CTRL)); - - /* -* Wait for data to be ready. Use timeout of 2us from -* rockchip_saradc driver. -*/ - ret = readl_poll_timeout((SARADC_BASE + SARADC_STAS), reg, -!(reg & SARADC_ADC_STATUS), 2); - if (ret) { - printf("ADC Timeout"); - return; - } - - /* Read the data from the SARADC. */ - reg = readl((SARADC_BASE + SARADC_DATA)); - - /* Turn the SARADC back off so it's ready to be used again. */ - writel(0, (SARADC_BASE + SARADC_CTRL)); - - /* -* If the value is less than 30 the button is being pressed. -* Reset the device back into Rockchip download mode. -*/ - if (reg <= 30) { - printf("download key pressed, entering download mode..."); - writel(BOOT_BROM_DOWNLOAD, CONFIG_ROCKCHIP_BOOT_MODE_REG); - do_reset(NULL, 0, 0, NULL); - } -}; - /* * Start LED very early so user knows device is on. Set color * to red. */ void spl_board_init(void) { - read_func_button(); - /* Set GPIO0_C5, GPIO0_C6, and GPIO0_C7 to output. */ writel(GPIO_WRITEMASK(GPIO_C7 | GPIO_C6 | GPIO_C5) | \ (GPIO_C7 | GPIO_C6 | GPIO_C5),
Re: [PATCH v2] clk: rockchip: rk3588: Set SPLL frequency during SPL stage
On 2024/5/23 01:31, Heiko Stuebner wrote: From: Heiko Stuebner All parts expect the SPLL to run at 702MHz. In U-Boot it's the SPLL_HZ declaring this rate and in the kernel it's a fixed clock definition. While everything is expecting 702MHz, the SPLL is not running that frequency when coming from the bootrom though, instead it's running at 351MHz and the vendor-u-boot just sets it to the expected frequency. The SPLL itself is located inside the secure-BUSCRU and in theory accessible as an SCMI clock, though this requires an unknown amount of cooperation from trusted-firmware to set at a later stage, though during the SPL stage we can still access the relevant CRU directly. The SPLL is for example necessary for the DSI controllers to produce output. As the SPLL is "just" another rk3588 pll, just set the desired rate directly during the SPL stage. Tested on rk3588-rock5b and rk3588-tiger by reading back the PLL rate and also observing working DSI output with this change. Fixes: 6737771600d4 ("rockchip: rk3588: Add support for sdmmc clocks in SPL") Suggested-by: Andy Yan Signed-off-by: Heiko Stuebner Cc: Jonas Karlman Cc: Quentin Schulz Reviewed-by: Kever Yang Thanks, - Kever --- changes in v2: - use correct name for SBUSCRU - use dedicated constants for SBUSCRU registers - add comment to make it explicit that the SPLL is in a different CRU .../include/asm/arch-rockchip/cru_rk3588.h| 4 +++ drivers/clk/rockchip/clk_rk3588.c | 30 +-- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/arch/arm/include/asm/arch-rockchip/cru_rk3588.h b/arch/arm/include/asm/arch-rockchip/cru_rk3588.h index a4507e5fdd7..a0e54d39654 100644 --- a/arch/arm/include/asm/arch-rockchip/cru_rk3588.h +++ b/arch/arm/include/asm/arch-rockchip/cru_rk3588.h @@ -29,6 +29,7 @@ enum rk3588_pll_id { V0PLL, AUPLL, PPLL, + SPLL, PLL_COUNT, }; @@ -150,6 +151,9 @@ struct pll_rate_table { #define RK3588_DSU_CLKGATE_CON(x) ((x) * 0x4 + RK3588_DSU_CRU_BASE + 0x800) #define RK3588_DSU_SOFTRST_CON(x) ((x) * 0x4 + RK3588_DSU_CRU_BASE + 0xa00) +#define RK3588_SBUSCRU_SPLL_CON(x) ((x) * 0x4 + 0x220) +#define RK3588_SBUSCRU_MODE_CON0 0x280 + enum { /* CRU_CLK_SEL8_CON */ ACLK_LOW_TOP_ROOT_SRC_SEL_SHIFT = 14, diff --git a/drivers/clk/rockchip/clk_rk3588.c b/drivers/clk/rockchip/clk_rk3588.c index 4c611a39049..c41c9be6aa3 100644 --- a/drivers/clk/rockchip/clk_rk3588.c +++ b/drivers/clk/rockchip/clk_rk3588.c @@ -37,6 +37,7 @@ static struct rockchip_pll_rate_table rk3588_pll_rates[] = { RK3588_PLL_RATE(78600, 1, 131, 2, 0), RK3588_PLL_RATE(74250, 4, 495, 2, 0), RK3588_PLL_RATE(722534400, 8, 963, 2, 24850), + RK3588_PLL_RATE(70200, 3, 351, 2, 0), RK3588_PLL_RATE(6, 2, 200, 2, 0), RK3588_PLL_RATE(59400, 2, 198, 2, 0), RK3588_PLL_RATE(2, 3, 400, 4, 0), @@ -65,6 +66,15 @@ static struct rockchip_pll_clock rk3588_pll_clks[] = { RK3588_MODE_CON0, 0, 15, 0, rk3588_pll_rates), [PPLL] = PLL(pll_rk3588, PLL_PPLL, RK3588_PMU_PLL_CON(128), RK3588_MODE_CON0, 10, 15, 0, rk3588_pll_rates), +#ifdef CONFIG_SPL_BUILD + /* +* The SPLL is part of the SBUSCRU, not the main CRU and as +* such only directly accessible during the SPL stage. +*/ + [SPLL] = PLL(pll_rk3588, 0, RK3588_SBUSCRU_SPLL_CON(0), +RK3588_SBUSCRU_MODE_CON0, 0, 15, 0, rk3588_pll_rates), +#endif + }; #ifndef CONFIG_SPL_BUILD @@ -2044,6 +2054,7 @@ U_BOOT_DRIVER(rockchip_rk3588_cru) = { #ifdef CONFIG_SPL_BUILD #define SCRU_BASE 0xfd7d +#define SBUSCRU_BASE 0xfd7d8000 static ulong rk3588_scru_clk_get_rate(struct clk *clk) { @@ -2118,15 +2129,28 @@ static ulong rk3588_scru_clk_set_rate(struct clk *clk, ulong rate) return rk3588_scru_clk_get_rate(clk); } +static int rk3588_scru_clk_probe(struct udevice *dev) +{ + int ret; + + ret = rockchip_pll_set_rate(&rk3588_pll_clks[SPLL], + (void *)SBUSCRU_BASE, SPLL, SPLL_HZ); + if (ret) + debug("%s setting spll rate failed %d\n", __func__, ret); + + return 0; +} + static const struct clk_ops rk3588_scru_clk_ops = { .get_rate = rk3588_scru_clk_get_rate, .set_rate = rk3588_scru_clk_set_rate, }; U_BOOT_DRIVER(rockchip_rk3588_scru) = { - .name = "rockchip_rk3588_scru", - .id = UCLASS_CLK, - .ops = &rk3588_scru_clk_ops, + .name = "rockchip_rk3588_scru", + .id = UCLASS_CLK, + .ops= &rk3588_scru_clk_ops, + .probe = rk3588_scru_clk_probe, }; static int rk3588_scmi_spl_glue_bind(struct udevice *dev)
Re: [PATCH V3] board: rockchip: Add Indiedroid Nova
On 2024/5/21 23:33, Chris Morgan wrote: From: Chris Morgan The Indiedroid Nova is a Rockchip RK3588S based SBC from Indiedroid. Specifications: Rockchip RK3588S SoC 4x ARM Cortex-A76, 4x ARM Cortex-A55 4/8/16GB memory LPDDR4x Mali G610MC4 GPU Optional eMMC 2x USB 2.0, 2x USB 3.0, 1x USB 3.0 C port with DP Alt 1x MIPI-CSI Port (4-lane or 2x 2-lane) 1x MIPI-DSI 4-lane connector 1x Micro HDMI 2.1 output, 1x DP 1.4 output Gigabit Ethernet Realtek RTL8821CS WiFi 4 pin debug UART connector 40 pin GPIO header Size: 85mm x 56mm (Raspberry Pi Form Factor) Kernel commit: 3900160e164b ("arm64: dts: rockchip: Add Indiedroid Nova board") Signed-off-by: Chris Morgan Reviewed-by: Kever Yang Thanks, - Kever --- Changes since V2: - Corrected typo in the MAINTAINERS file. - Removed OF_UPSTREAM since it is now defined for all RK3588 boards. Changes since V1: - Refactored to use the upstream Linux device tree now that that is an option. - Added board to doc/board/rockchip/rockchip.rst. --- arch/arm/mach-rockchip/rk3588/Kconfig | 10 board/indiedroid/nova/Kconfig | 12 + board/indiedroid/nova/MAINTAINERS | 6 +++ configs/nova-rk3588s_defconfig| 69 +++ doc/board/rockchip/rockchip.rst | 1 + include/configs/nova-rk3588s.h| 15 ++ 6 files changed, 113 insertions(+) create mode 100644 board/indiedroid/nova/Kconfig create mode 100644 board/indiedroid/nova/MAINTAINERS create mode 100644 configs/nova-rk3588s_defconfig create mode 100644 include/configs/nova-rk3588s.h diff --git a/arch/arm/mach-rockchip/rk3588/Kconfig b/arch/arm/mach-rockchip/rk3588/Kconfig index 39049ab35a..820e979abb 100644 --- a/arch/arm/mach-rockchip/rk3588/Kconfig +++ b/arch/arm/mach-rockchip/rk3588/Kconfig @@ -78,6 +78,15 @@ config TARGET_NANOPCT6_RK3588 Power: 5.5*2.1mm DC Jack, 12VDC input Dimensions: 110x80x1.6mm (without case) / 86x114.5x30mm (with case) +config TARGET_NOVA_RK3588 + bool "Indiedroid Nova RK3588" + select BOARD_LATE_INIT + help + Indiedroid Nova is a Rockchip RK3588s based SBC by Indiedroid. + It comes in configurations from 4GB of RAM to 16GB of RAM, + includes socket for eMMC storage, an SDMMC slot, and a 40-pin + GPIO header for expansion. + config TARGET_RK3588_NEU6 bool "Edgeble Neural Compute Module 6(Neu6) SoM" select BOARD_LATE_INIT @@ -223,6 +232,7 @@ config TEXT_BASE source "board/edgeble/neural-compute-module-6/Kconfig" source "board/friendlyelec/nanopc-t6-rk3588/Kconfig" +source "board/indiedroid/nova/Kconfig" source "board/pine64/quartzpro64-rk3588/Kconfig" source "board/turing/turing-rk1-rk3588/Kconfig" source "board/radxa/rock5a-rk3588s/Kconfig" diff --git a/board/indiedroid/nova/Kconfig b/board/indiedroid/nova/Kconfig new file mode 100644 index 00..271d15a0ed --- /dev/null +++ b/board/indiedroid/nova/Kconfig @@ -0,0 +1,12 @@ +if TARGET_NOVA_RK3588 + +config SYS_BOARD + default "nova-rk3588s" + +config SYS_VENDOR + default "indiedroid" + +config SYS_CONFIG_NAME + default "nova-rk3588s" + +endif diff --git a/board/indiedroid/nova/MAINTAINERS b/board/indiedroid/nova/MAINTAINERS new file mode 100644 index 00..db40adf9ad --- /dev/null +++ b/board/indiedroid/nova/MAINTAINERS @@ -0,0 +1,6 @@ +INDIEDROID-NOVA-RK3588 +M: Chris Morgan +S: Maintained +F: board/indiedroid/nova +F: include/configs/nova-rk3588s.h +F: configs/indiedroid-nova-rk3588s_defconfig diff --git a/configs/nova-rk3588s_defconfig b/configs/nova-rk3588s_defconfig new file mode 100644 index 00..a2e2440359 --- /dev/null +++ b/configs/nova-rk3588s_defconfig @@ -0,0 +1,69 @@ +CONFIG_ARM=y +CONFIG_SKIP_LOWLEVEL_INIT=y +CONFIG_COUNTER_FREQUENCY=2400 +CONFIG_ARCH_ROCKCHIP=y +CONFIG_DEFAULT_DEVICE_TREE="rockchip/rk3588s-indiedroid-nova" +CONFIG_ROCKCHIP_RK3588=y +CONFIG_SPL_SERIAL=y +CONFIG_TARGET_NOVA_RK3588=y +CONFIG_DEBUG_UART_BASE=0xFEB5 +CONFIG_DEBUG_UART_CLOCK=2400 +CONFIG_SYS_LOAD_ADDR=0xc00800 +CONFIG_PCI=y +CONFIG_DEBUG_UART=y +CONFIG_FIT=y +CONFIG_FIT_VERBOSE=y +CONFIG_SPL_FIT_SIGNATURE=y +CONFIG_SPL_LOAD_FIT=y +CONFIG_LEGACY_IMAGE_FORMAT=y +CONFIG_DEFAULT_FDT_FILE="rockchip/rk3588s-indiedroid-nova.dtb" +# CONFIG_DISPLAY_CPUINFO is not set +CONFIG_DISPLAY_BOARDINFO_LATE=y +CONFIG_SPL_MAX_SIZE=0x4 +CONFIG_SPL_PAD_TO=0x7f8000 +# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set +CONFIG_SPL_ATF=y +CONFIG_CMD_GPIO=y +CONFIG_CMD_GPT=y +CONFIG_CMD_I2C=y +CONFIG_CMD_MMC=y +CONFIG_CMD_USB=y +# CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_REGULATOR=y +# CONFIG_SPL_DOS_PARTITION is not set +CONFIG_SPL_OF_CONTROL=y +CONFIG_OF_LIVE=y +CONFIG_OF_SPL_REMOVE_PROPS="clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents" +CONFIG_SPL_DM_SEQ_ALIAS=y +CONFIG_SPL_REGMAP=y +CONFIG_SPL_SYSCON=y +C
Re: [PATCH V4] board: rockchip: add Powkiddy X55
On 2024/5/21 23:25, Chris Morgan wrote: From: Chris Morgan The Powkiddy X55 is a Rockchip RK3566 based handheld gaming device. UART, ADC, eMMC, and SDMMC are tested to work in U-Boot and this successfully boots mainline Linux. Kernel commit: e99adc97e21a ("arm64: dts: rockchip: Add Powkiddy X55") Signed-off-by: Chris Morgan Reviewed-by: Kever Yang Thanks, - Kever --- Changes since V3: - Removed sdmmc1 from the SPL-> U-Boot path, as long as we have sdmmc0 we should be okay with recovery options. - Removed OF_UPSTREAM since that's now set across the board for RK3568 devices. Changes since V2: - Refactored to use the upstream device tree from Linux. - Removed logic for handling the adc button and instead simply try to boot from sdmmc0 as a valid target first. --- arch/arm/dts/rk3566-powkiddy-x55-u-boot.dtsi | 9 +++ arch/arm/mach-rockchip/rk3568/Kconfig| 6 ++ board/powkiddy/x55/Kconfig | 15 + board/powkiddy/x55/MAINTAINERS | 7 +++ board/powkiddy/x55/Makefile | 6 ++ board/powkiddy/x55/x55.c | 39 + configs/powkiddy-x55-rk3566_defconfig| 58 doc/board/rockchip/rockchip.rst | 1 + include/configs/powkiddy-x55-rk3566.h| 12 9 files changed, 153 insertions(+) create mode 100644 arch/arm/dts/rk3566-powkiddy-x55-u-boot.dtsi create mode 100644 board/powkiddy/x55/Kconfig create mode 100644 board/powkiddy/x55/MAINTAINERS create mode 100644 board/powkiddy/x55/Makefile create mode 100644 board/powkiddy/x55/x55.c create mode 100644 configs/powkiddy-x55-rk3566_defconfig create mode 100644 include/configs/powkiddy-x55-rk3566.h diff --git a/arch/arm/dts/rk3566-powkiddy-x55-u-boot.dtsi b/arch/arm/dts/rk3566-powkiddy-x55-u-boot.dtsi new file mode 100644 index 00..eadd3510fb --- /dev/null +++ b/arch/arm/dts/rk3566-powkiddy-x55-u-boot.dtsi @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) + +#include "rk356x-u-boot.dtsi" + +/ { + chosen { + u-boot,spl-boot-order = &sdmmc0, &sdhci; + }; +}; diff --git a/arch/arm/mach-rockchip/rk3568/Kconfig b/arch/arm/mach-rockchip/rk3568/Kconfig index af537d912a..014ebf9f0b 100644 --- a/arch/arm/mach-rockchip/rk3568/Kconfig +++ b/arch/arm/mach-rockchip/rk3568/Kconfig @@ -22,6 +22,11 @@ config TARGET_ODROID_M1_RK3568 help Hardkernel ODROID-M1 single board computer with a RK3568B2 SoC. +config TARGET_POWKIDDY_X55_RK3566 + bool "Powkiddy X55" + help + Powkiddy X55 handheld gaming console with an RK3566 SoC. + config TARGET_QUARTZ64_RK3566 bool "Pine64 Quartz64" help @@ -48,5 +53,6 @@ source "board/rockchip/evb_rk3568/Kconfig" source "board/anbernic/rgxx3_rk3566/Kconfig" source "board/hardkernel/odroid_m1/Kconfig" source "board/pine64/quartz64_rk3566/Kconfig" +source "board/powkiddy/x55/Kconfig" endif diff --git a/board/powkiddy/x55/Kconfig b/board/powkiddy/x55/Kconfig new file mode 100644 index 00..a7b3ed4d0d --- /dev/null +++ b/board/powkiddy/x55/Kconfig @@ -0,0 +1,15 @@ +if TARGET_POWKIDDY_X55_RK3566 + +config SYS_BOARD + default "x55" + +config SYS_VENDOR + default "powkiddy" + +config SYS_CONFIG_NAME + default "powkiddy-x55-rk3566" + +config BOARD_SPECIFIC_OPTIONS + def_bool y + +endif diff --git a/board/powkiddy/x55/MAINTAINERS b/board/powkiddy/x55/MAINTAINERS new file mode 100644 index 00..01ae8da19d --- /dev/null +++ b/board/powkiddy/x55/MAINTAINERS @@ -0,0 +1,7 @@ +X55 +M: Chris Morgan +S: Maintained +F: board/powkiddy/x55 +F: include/configs/powkiddy-x55-rk3566.h +F: configs/powkiddy-x55-rk3566_defconfig +F: arch/arm/dts/rk3566-powkiddy-x55-u-boot.dtsi diff --git a/board/powkiddy/x55/Makefile b/board/powkiddy/x55/Makefile new file mode 100644 index 00..55c8c16aa1 --- /dev/null +++ b/board/powkiddy/x55/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (c) 2023 Chris Morgan +# + +obj-y += x55.o diff --git a/board/powkiddy/x55/x55.c b/board/powkiddy/x55/x55.c new file mode 100644 index 00..b2703e6382 --- /dev/null +++ b/board/powkiddy/x55/x55.c @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2023 Chris Morgan + */ + +#include + +#define GPIO4_BASE 0xfe77 +#define GPIO_SWPORT_DR_L 0x +#define GPIO_SWPORT_DDR_L 0x0008 +#define GPIO_B4BIT(12) +#define GPIO_B5BIT(13) +#define GPIO_B6BIT(14) + +#define GPIO_WRITEMASK(bits) ((bits) << 16) + +/* + * Start LED very early so user knows device is on. Set color + * to red. + */ +void spl_board_init(void) +{ + /* Set GPIO4_B4, GPIO4_B5, and GPIO4_B6 to output. */ + writel(GPIO_WRITEMASK(GPIO_B6 | GPIO_B5 | GPIO_B4) | \ + (GPIO_B6 | GPIO_B5 | GPIO_B4),
[PATCH v1] ARM: dts: Revise the default baudrate
Revise the default baudrate to 57600 Signed-off-by: DelphineCCChiu --- configs/ast2600_openbmc_spl_defconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/configs/ast2600_openbmc_spl_defconfig b/configs/ast2600_openbmc_spl_defconfig index efd683570f..5e95780a9a 100644 --- a/configs/ast2600_openbmc_spl_defconfig +++ b/configs/ast2600_openbmc_spl_defconfig @@ -28,7 +28,8 @@ CONFIG_FIT_SIGNATURE=y CONFIG_SPL_FIT_SIGNATURE=y CONFIG_SPL_LOAD_FIT=y CONFIG_USE_BOOTARGS=y -CONFIG_BOOTARGS="console=ttyS4,115200n8 root=/dev/ram rw" +CONFIG_BOOTARGS="console=ttyS4,57600n8 root=/dev/ram rw" +CONFIG_BAUDRATE=57600 CONFIG_USE_BOOTCOMMAND=y CONFIG_BOOTCOMMAND="run bootspi" CONFIG_SYS_CONSOLE_ENV_OVERWRITE=y -- 2.25.1
Re: [PATCH v3 0/4] Clean-up patch set for MbedTLS integration
On Thu, 16 May 2024 14:11:48 -0700, Raymond Mao wrote: > This patch set is picked from the previously posted serie: > "[RFC] Integrate MbedTLS v3.6 LTS with U-Boot" > > They are not directly related to MbedTLS integration, but the > prerequisite for a few clean-up, refactoring and minor fixes. > > For V2, the linker script patch is dropped and added one patch > to move the snprintf to stdio.h > > [...] Applied to u-boot/next, thanks! -- Tom
Re: [PATCH 2/4] clk: sophgo: cv1800b: Add clock controller driver for cv1800b SoC
Hi Kongyang: I've got one compiling error On 23:07 Sun 19 May , Kongyang Liu wrote: > Add clock controller driver for sophgo cv1800b SoC > > Signed-off-by: Kongyang Liu > --- > > drivers/clk/Kconfig | 1 + > drivers/clk/Makefile | 1 + > drivers/clk/sophgo/Kconfig | 14 + > drivers/clk/sophgo/Makefile | 6 + > drivers/clk/sophgo/clk-common.h | 74 +++ > drivers/clk/sophgo/clk-cv1800b.c | 794 +++ > drivers/clk/sophgo/clk-cv1800b.h | 123 + > drivers/clk/sophgo/clk-ip.c | 594 +++ > drivers/clk/sophgo/clk-ip.h | 288 +++ > drivers/clk/sophgo/clk-pll.c | 284 +++ > drivers/clk/sophgo/clk-pll.h | 74 +++ > 11 files changed, 2253 insertions(+) > create mode 100644 drivers/clk/sophgo/Kconfig > create mode 100644 drivers/clk/sophgo/Makefile > create mode 100644 drivers/clk/sophgo/clk-common.h > create mode 100644 drivers/clk/sophgo/clk-cv1800b.c > create mode 100644 drivers/clk/sophgo/clk-cv1800b.h > create mode 100644 drivers/clk/sophgo/clk-ip.c > create mode 100644 drivers/clk/sophgo/clk-ip.h > create mode 100644 drivers/clk/sophgo/clk-pll.c > create mode 100644 drivers/clk/sophgo/clk-pll.h > ... > +static ulong cv1800b_ipll_set_rate(struct clk *clk, ulong rate) > +{ > + struct cv1800b_clk_ipll *pll = to_clk_ipll(clk); > + ulong parent_rate = clk_get_parent_rate(clk); > + u32 pre_div, post_div, div; > + u32 pre_div_sel, post_div_sel, div_sel; > + ulong new_rate, best_rate = 0; > + u32 mode, ictrl; > + u32 test, val; > + > + FOR_RANGE(pre_div, PLL_PRE_DIV) > + { > + FOR_RANGE(post_div, PLL_POST_DIV) > + { > + FOR_RANGE(div, PLL_DIV) > + { > + new_rate = DIV_ROUND_DOWN_ULL(parent_rate * div ~~ miss a comma here > + pre_div * > post_div); > + if (rate - new_rate < rate - best_rate) { > + best_rate = new_rate; > + pre_div_sel = pre_div; > + post_div_sel = post_div; > + div_sel = div; > + } > + } > + } > + } > + > + FOR_RANGE(mode, PLL_MODE) -- Yixun Lan (dlan) Gentoo Linux Developer GPG Key ID AABEFD55
[PATCH 42/42] doc: samsung: Mention enabled eMMC in E850-96 board doc
eMMC is enabled on E850-96 board now. Mention that in the board documentation. Signed-off-by: Sam Protsenko --- doc/board/samsung/e850-96.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/board/samsung/e850-96.rst b/doc/board/samsung/e850-96.rst index 0cb95473e536..0a7b6fc0c9dd 100644 --- a/doc/board/samsung/e850-96.rst +++ b/doc/board/samsung/e850-96.rst @@ -47,12 +47,13 @@ Build Procedure --- .. warning:: - At the moment both eMMC and USB features are not enabled in U-Boot. Flashing + At the moment USB is not enabled in U-Boot for this board. Although eMMC is + enabled, you won't be able to flash images over USB (fastboot). So flashing U-Boot binary **WILL** effectively brick your board. The ``dltool`` [8]_ can be used then to perform USB boot and flash LittleKernel bootloader binary [7]_ to unbrick and revive the board. Flashing U-Boot binary might be helpful for developers or anybody who want to check current state of U-Boot enablement on - E850-96 (which is mostly serial console and related blocks). + E850-96 (which is mostly serial console, eMMC and related blocks). Build U-Boot binary from source code (using AArch64 baremetal GCC toolchain): -- 2.39.2
[PATCH 41/42] configs: e850-96: Enable MMC
Enable MMC subsystem and DW MMC driver support to make eMMC functional. Also enable a couple of related commands so the user can make use of eMMC from U-Boot shell. Signed-off-by: Sam Protsenko --- configs/e850-96_defconfig | 10 +- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/configs/e850-96_defconfig b/configs/e850-96_defconfig index bb41635ff784..17054f25fe6b 100644 --- a/configs/e850-96_defconfig +++ b/configs/e850-96_defconfig @@ -9,11 +9,19 @@ CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xf8c0 CONFIG_DEFAULT_DEVICE_TREE="exynos850-e850-96" CONFIG_SYS_LOAD_ADDR=0x8000 +CONFIG_ANDROID_BOOT_IMAGE=y # CONFIG_AUTOBOOT is not set # CONFIG_DISPLAY_CPUINFO is not set +CONFIG_HUSH_PARSER=y +CONFIG_CMD_ABOOTIMG=y +CONFIG_CMD_CLK=y +CONFIG_CMD_GPT=y +CONFIG_CMD_MMC=y +CONFIG_CMD_PART=y +CONFIG_CMD_TIME=y # CONFIG_NET is not set CONFIG_CLK_EXYNOS850=y -# CONFIG_MMC is not set +CONFIG_MMC_DW=y CONFIG_SOC_SAMSUNG=y CONFIG_EXYNOS_PMU=y CONFIG_EXYNOS_USI=y -- 2.39.2
[PATCH 40/42] arm: dts: exynos: Remove outdated DW MMC properties in all Exynos dts
Upstream properties were added to device trees to follow current Linux kernel. DW MMC driver was updated accordingly. Safely remove outdated MMC properties. Details on removed properties are as follows: * samsung,removable: replaced by non-removable * samsung,bus-width: replaced by bus-width * samsung,timing: - replaced by samsung,dw-mshc-ciu-div and samsung,dw-mshc-sdr-timing in dw_mmc nodes - removed from sdhci nodes (it's neither described in bindings, nor it's used in s5p_sdhci.c driver) * fifoth_val: replaced by fifo-depth * bus_hz: replaced by clock-frequency * div: the fixed CIU clock divider value was moved to the chip data in exynos_dw_mmc.c driver No functional change. Signed-off-by: Sam Protsenko --- arch/arm/dts/exynos4210-origen.dts | 2 -- arch/arm/dts/exynos4210-trats.dts | 4 arch/arm/dts/exynos4210-universal_c210.dts | 4 arch/arm/dts/exynos4412-odroid.dts | 8 arch/arm/dts/exynos4412-trats2.dts | 12 arch/arm/dts/exynos5250-arndale.dts| 4 arch/arm/dts/exynos5250-smdk5250.dts | 6 -- arch/arm/dts/exynos5250-snow.dts | 6 -- arch/arm/dts/exynos5250-spring.dts | 3 --- arch/arm/dts/exynos5420-smdk5420.dts | 6 -- arch/arm/dts/exynos5422-odroidxu3.dts | 2 -- arch/arm/dts/exynos54xx.dtsi | 6 -- 12 files changed, 63 deletions(-) diff --git a/arch/arm/dts/exynos4210-origen.dts b/arch/arm/dts/exynos4210-origen.dts index a4915de2c49c..40289c8c4aaf 100644 --- a/arch/arm/dts/exynos4210-origen.dts +++ b/arch/arm/dts/exynos4210-origen.dts @@ -25,9 +25,7 @@ }; &sdhci2 { - samsung,bus-width = <4>; bus-width = <4>; - samsung,timing = <1 2 3>; cd-gpios = <&gpk2 2 0>; status = "okay"; }; diff --git a/arch/arm/dts/exynos4210-trats.dts b/arch/arm/dts/exynos4210-trats.dts index 4fbdf4730994..88e9c0ed2bb0 100644 --- a/arch/arm/dts/exynos4210-trats.dts +++ b/arch/arm/dts/exynos4210-trats.dts @@ -240,17 +240,13 @@ }; &sdhci0 { - samsung,bus-width = <8>; bus-width = <8>; - samsung,timing = <1 3 3>; pwr-gpios = <&gpk0 2 0>; status = "okay"; }; &sdhci2 { - samsung,bus-width = <4>; bus-width = <4>; - samsung,timing = <1 2 3>; cd-gpios = <&gpx3 4 0>; status = "okay"; }; diff --git a/arch/arm/dts/exynos4210-universal_c210.dts b/arch/arm/dts/exynos4210-universal_c210.dts index 1b3ac1fee15f..c87b92be609d 100644 --- a/arch/arm/dts/exynos4210-universal_c210.dts +++ b/arch/arm/dts/exynos4210-universal_c210.dts @@ -235,17 +235,13 @@ }; &sdhci0 { - samsung,bus-width = <8>; bus-width = <8>; - samsung,timing = <1 3 3>; pwr-gpios = <&gpk0 2 0>; status = "okay"; }; &sdhci2 { - samsung,bus-width = <4>; bus-width = <4>; - samsung,timing = <1 2 3>; cd-gpios = <&gpx3 4 0>; status = "okay"; }; diff --git a/arch/arm/dts/exynos4412-odroid.dts b/arch/arm/dts/exynos4412-odroid.dts index 24e96ed05868..6822c68a 100644 --- a/arch/arm/dts/exynos4412-odroid.dts +++ b/arch/arm/dts/exynos4412-odroid.dts @@ -234,26 +234,18 @@ }; &sdhci2 { - samsung,bus-width = <4>; - samsung,timing = <1 2 3>; cd-inverted; cd-gpios = <&gpk2 2 0>; status = "okay"; }; &mshc_0 { - samsung,bus-width = <8>; bus-width = <8>; - samsung,timing = <2 1 0>; samsung,dw-mshc-ciu-div = <0>; samsung,dw-mshc-sdr-timing = <2 1>; - samsung,removable = <0>; non-removable; - fifoth_val = <0x203f0040>; fifo-depth = <0x80>; clock-frequency = <4>; - bus_hz = <4>; - div = <0x3>; index = <4>; status = "okay"; }; diff --git a/arch/arm/dts/exynos4412-trats2.dts b/arch/arm/dts/exynos4412-trats2.dts index 30758ffa1ef9..2b71d328cd0e 100644 --- a/arch/arm/dts/exynos4412-trats2.dts +++ b/arch/arm/dts/exynos4412-trats2.dts @@ -108,9 +108,7 @@ }; sdhci@1251 { - samsung,bus-width = <8>; bus-width = <8>; - samsung,timing = <1 3 3>; pwr-gpios = <&gpk0 4 0>; status = "disabled"; }; @@ -432,33 +430,23 @@ }; &sdhci0 { - samsung,bus-width = <8>; bus-width = <8>; - samsung,timing = <1 3 3>; pwr-gpios = <&gpk0 4 0>; status = "disabled"; }; &sdhci2 { - samsung,bus-width = <4>; bus-width = <4>; - samsung,timing = <1 2 3>; cd-gpios = <&gpk2 2 0>; status = "okay"; }; &mshc_0 { - samsung,bus-width = <8>; bus-width = <8>; - samsung,timing = <2 1 0>; samsung,dw-mshc-ciu-div = <0>; samsung,dw-mshc-sdr-timing = <2 1>; - samsung,removable = <0>; non-removable; - fifoth_val = <0x203f0040>; clock-frequency = <4>; -
[PATCH 39/42] mmc: exynos_dw_mmc: Improve coding style
Fix most of checkpatch warnings and other obvious style issues. No functional change. Signed-off-by: Sam Protsenko --- arch/arm/mach-exynos/include/mach/dwmmc.h | 36 +-- drivers/mmc/exynos_dw_mmc.c | 26 ++-- 2 files changed, 29 insertions(+), 33 deletions(-) diff --git a/arch/arm/mach-exynos/include/mach/dwmmc.h b/arch/arm/mach-exynos/include/mach/dwmmc.h index 7cb71be0d9fd..75d84988b7d6 100644 --- a/arch/arm/mach-exynos/include/mach/dwmmc.h +++ b/arch/arm/mach-exynos/include/mach/dwmmc.h @@ -7,24 +7,28 @@ #ifndef __ASM_ARM_ARCH_DWMMC_H #define __ASM_ARM_ARCH_DWMMC_H -#define DWMCI_CLKSEL 0x09C -#define DWMCI_CLKSEL64 0x0a8 -#define DWMCI_SET_SAMPLE_CLK(x)(x) -#define DWMCI_SET_DRV_CLK(x) ((x) << 16) -#define DWMCI_SET_DIV_RATIO(x) ((x) << 24) +#include -#define EMMCP_MPSBEGIN00x1200 -#define EMMCP_SEND00x1204 -#define EMMCP_CTRL00x120C +#define DWMCI_CLKSEL 0x09c +#define DWMCI_CLKSEL64 0x0a8 +#define DWMCI_SET_SAMPLE_CLK(x)(x) +#define DWMCI_SET_DRV_CLK(x) ((x) << 16) +#define DWMCI_SET_DIV_RATIO(x) ((x) << 24) -#define MPSCTRL_SECURE_READ_BIT(0x1<<7) -#define MPSCTRL_SECURE_WRITE_BIT (0x1<<6) -#define MPSCTRL_NON_SECURE_READ_BIT(0x1<<5) -#define MPSCTRL_NON_SECURE_WRITE_BIT (0x1<<4) -#define MPSCTRL_USE_FUSE_KEY (0x1<<3) -#define MPSCTRL_ECB_MODE (0x1<<2) -#define MPSCTRL_ENCRYPTION (0x1<<1) -#define MPSCTRL_VALID (0x1<<0) +/* Protector Register */ +#define DWMCI_EMMCP_BASE 0x1000 +#define EMMCP_MPSBEGIN0(DWMCI_EMMCP_BASE + 0x0200) +#define EMMCP_SEND0(DWMCI_EMMCP_BASE + 0x0204) +#define EMMCP_CTRL0(DWMCI_EMMCP_BASE + 0x020c) + +#define MPSCTRL_SECURE_READ_BITBIT(7) +#define MPSCTRL_SECURE_WRITE_BIT BIT(6) +#define MPSCTRL_NON_SECURE_READ_BITBIT(5) +#define MPSCTRL_NON_SECURE_WRITE_BIT BIT(4) +#define MPSCTRL_USE_FUSE_KEY BIT(3) +#define MPSCTRL_ECB_MODE BIT(2) +#define MPSCTRL_ENCRYPTION BIT(1) +#define MPSCTRL_VALID BIT(0) /* CLKSEL Register */ #define DWMCI_DIVRATIO_BIT 24 diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c index 84a079256bca..9ac0c21216a1 100644 --- a/drivers/mmc/exynos_dw_mmc.c +++ b/drivers/mmc/exynos_dw_mmc.c @@ -45,7 +45,7 @@ struct exynos_dwmmc_variant { u32 quirks; /* quirk flags - see DWMCI_QUIRK_... */ }; -/* Exynos implmentation specific drver private data */ +/* Exynos implementation specific driver private data */ struct dwmci_exynos_priv_data { #if CONFIG_IS_ENABLED(DM_MMC) struct dwmci_host host; @@ -121,10 +121,7 @@ static int exynos_dwmmc_set_sclk(struct dwmci_host *host, unsigned long rate) return 0; } -/* - * Function used as callback function to initialise the - * CLKSEL register for every mmc channel. - */ +/* Configure CLKSEL register with chosen timing values */ static int exynos_dwmci_clksel(struct dwmci_host *host) { struct dwmci_exynos_priv_data *priv = exynos_dwmmc_get_priv(host); @@ -163,7 +160,7 @@ static u8 exynos_dwmmc_get_ciu_div(struct dwmci_host *host) & DWMCI_DIVRATIO_MASK) + 1; } -unsigned int exynos_dwmci_get_clk(struct dwmci_host *host, uint freq) +static unsigned int exynos_dwmci_get_clk(struct dwmci_host *host, uint freq) { unsigned long sclk; u8 clk_div; @@ -204,7 +201,6 @@ static void exynos_dwmci_board_init(struct dwmci_host *host) MPSCTRL_NON_SECURE_WRITE_BIT | MPSCTRL_VALID); } - /* Set to timing value at initial time */ if (priv->sdr_timing) exynos_dwmci_clksel(host); } @@ -213,8 +209,8 @@ static int exynos_dwmmc_of_to_plat(struct udevice *dev) { struct dwmci_exynos_priv_data *priv = dev_get_priv(dev); struct dwmci_host *host = &priv->host; - int err = 0; u32 div, timing[2]; + int err; priv->chip = (struct exynos_dwmmc_variant *)dev_get_driver_data(dev); @@ -222,9 +218,8 @@ static int exynos_dwmmc_of_to_plat(struct udevice *dev) const void *blob = gd->fdt_blob; int node = dev_of_offset(dev); - /* Extract device id for each mmc channel */ + /* Obtain device ID for current MMC channel */ host->dev_id = pinmux_decode_periph_id(blob, node); - host->dev_index = dev_read_u32_default(dev, "index", host->dev_id); if (host->dev_index == host->dev_id) host->dev_index = host->dev_id - PERIPH_ID_SDMMC0; @@ -240,10 +235,6 @@ static int exynos_dwmmc_of_to_plat(struct udevice *dev) host->dev_index = 2; /* SD card */ #endif - /* Get the bus width from the device node (Default
[PATCH 38/42] mmc: exynos_dw_mmc: Use dev->name as driver's displayed name
Reduce U-Boot footprint by reusing dev->name as a driver's displayed name. This changes boot device name (and "mmc info" output) from "EXYNOS DWMMC" to something like "mmc@1210". Signed-off-by: Sam Protsenko --- drivers/mmc/exynos_dw_mmc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c index 373dd2df206e..84a079256bca 100644 --- a/drivers/mmc/exynos_dw_mmc.c +++ b/drivers/mmc/exynos_dw_mmc.c @@ -327,7 +327,7 @@ static int exynos_dwmmc_probe(struct udevice *dev) "continue anyway\n", host->dev_index, err); } - host->name = "EXYNOS DWMMC"; + host->name = dev->name; host->board_init = exynos_dwmci_board_init; host->caps = MMC_MODE_DDR_52MHz; host->clksel = exynos_dwmci_clksel; -- 2.39.2
[PATCH 37/42] mmc: exynos_dw_mmc: Don't call dwmci_setup_cfg() after add_dwmci()
add_dwmci() is already calling dwmci_setup_cfg() internally, there is no needed to call dwmci_setup_cfg() again in case when add_dwmci() is used (for non-DM cases). Fix it by calling dwmci_setup_cfg() only in DM cases, when add_dwmci() wasn't called. Also, this assignment: host->mmc = &plat->mmc; is wrong in non-DM case when add_dwmci() was called, as it's creating mmc object internally. Fix that by pulling that assignment into DM case, when add_dwmci() isn't called. While at it, add also this missing assignment: host->mmc->dev = dev; Fixes: 3537ee879e04 ("mmc: exynos_dw_mmc: support the Driver mode for Exynos") Signed-off-by: Sam Protsenko --- drivers/mmc/exynos_dw_mmc.c | 16 +--- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c index 19793e7ad460..373dd2df206e 100644 --- a/drivers/mmc/exynos_dw_mmc.c +++ b/drivers/mmc/exynos_dw_mmc.c @@ -333,19 +333,21 @@ static int exynos_dwmmc_probe(struct udevice *dev) host->clksel = exynos_dwmci_clksel; host->get_mmc_clk = exynos_dwmci_get_clk; -#if !CONFIG_IS_ENABLED(DM_MMC) - /* Add the mmc channel to be registered with mmc core */ - if (add_dwmci(host, DWMMC_MAX_FREQ, DWMMC_MIN_FREQ)) { +#if CONFIG_IS_ENABLED(BLK) + dwmci_setup_cfg(&plat->cfg, host, DWMMC_MAX_FREQ, DWMMC_MIN_FREQ); + host->mmc = &plat->mmc; +#else + err = add_dwmci(host, DWMMC_MAX_FREQ, DWMMC_MIN_FREQ); + if (err) { printf("DWMMC%d registration failed\n", host->dev_index); - return -1; + return err; } #endif - dwmci_setup_cfg(&plat->cfg, host, DWMMC_MAX_FREQ, DWMMC_MIN_FREQ); - host->mmc = &plat->mmc; host->mmc->priv = &priv->host; - host->priv = dev; upriv->mmc = host->mmc; + host->mmc->dev = dev; + host->priv = dev; return dwmci_probe(dev); } -- 2.39.2
[PATCH 36/42] mmc: exynos_dw_mmc: Pull all init code into probe function
There is no logical sense to split the initialization code between multiple functions. Pull both do_dwmci_init() and exynos_dwmci_core_init() into exynos_dwmmc_probe() to make the code more simple and obvious. No functional change. Signed-off-by: Sam Protsenko --- drivers/mmc/exynos_dw_mmc.c | 86 +++-- 1 file changed, 35 insertions(+), 51 deletions(-) diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c index b7c3b356f0ac..19793e7ad460 100644 --- a/drivers/mmc/exynos_dw_mmc.c +++ b/drivers/mmc/exynos_dw_mmc.c @@ -209,55 +209,6 @@ static void exynos_dwmci_board_init(struct dwmci_host *host) exynos_dwmci_clksel(host); } -static int exynos_dwmci_core_init(struct dwmci_host *host) -{ - unsigned long freq; - int err; - - if (host->bus_hz) - freq = host->bus_hz; - else - freq = DWMMC_MAX_FREQ; - - err = exynos_dwmmc_set_sclk(host, freq); - if (err) { - printf("DWMMC%d: failed to set clock rate on probe (%d); " - "continue anyway\n", host->dev_index, err); - } - - host->name = "EXYNOS DWMMC"; - host->board_init = exynos_dwmci_board_init; - host->caps = MMC_MODE_DDR_52MHz; - host->clksel = exynos_dwmci_clksel; - host->get_mmc_clk = exynos_dwmci_get_clk; - -#if !CONFIG_IS_ENABLED(DM_MMC) - /* Add the mmc channel to be registered with mmc core */ - if (add_dwmci(host, DWMMC_MAX_FREQ, DWMMC_MIN_FREQ)) { - printf("DWMMC%d registration failed\n", host->dev_index); - return -1; - } -#endif - - return 0; -} - -static int do_dwmci_init(struct dwmci_host *host) -{ -#if CONFIG_IS_ENABLED(CPU_V7A) - int flag, err; - - flag = host->buswidth == 8 ? PINMUX_FLAG_8BIT_MODE : PINMUX_FLAG_NONE; - err = exynos_pinmux_config(host->dev_id, flag); - if (err) { - printf("DWMMC%d not configure\n", host->dev_index); - return err; - } -#endif - - return exynos_dwmci_core_init(host); -} - static int exynos_dwmmc_of_to_plat(struct udevice *dev) { struct dwmci_exynos_priv_data *priv = dev_get_priv(dev); @@ -345,6 +296,7 @@ static int exynos_dwmmc_probe(struct udevice *dev) struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); struct dwmci_exynos_priv_data *priv = dev_get_priv(dev); struct dwmci_host *host = &priv->host; + unsigned long freq; int err; #if !CONFIG_IS_ENABLED(CPU_V7A) @@ -353,9 +305,41 @@ static int exynos_dwmmc_probe(struct udevice *dev) return err; #endif - err = do_dwmci_init(host); - if (err) +#if CONFIG_IS_ENABLED(CPU_V7A) + int flag; + + flag = host->buswidth == 8 ? PINMUX_FLAG_8BIT_MODE : PINMUX_FLAG_NONE; + err = exynos_pinmux_config(host->dev_id, flag); + if (err) { + printf("DWMMC%d not configure\n", host->dev_index); return err; + } +#endif + + if (host->bus_hz) + freq = host->bus_hz; + else + freq = DWMMC_MAX_FREQ; + + err = exynos_dwmmc_set_sclk(host, freq); + if (err) { + printf("DWMMC%d: failed to set clock rate on probe (%d); " + "continue anyway\n", host->dev_index, err); + } + + host->name = "EXYNOS DWMMC"; + host->board_init = exynos_dwmci_board_init; + host->caps = MMC_MODE_DDR_52MHz; + host->clksel = exynos_dwmci_clksel; + host->get_mmc_clk = exynos_dwmci_get_clk; + +#if !CONFIG_IS_ENABLED(DM_MMC) + /* Add the mmc channel to be registered with mmc core */ + if (add_dwmci(host, DWMMC_MAX_FREQ, DWMMC_MIN_FREQ)) { + printf("DWMMC%d registration failed\n", host->dev_index); + return -1; + } +#endif dwmci_setup_cfg(&plat->cfg, host, DWMMC_MAX_FREQ, DWMMC_MIN_FREQ); host->mmc = &plat->mmc; -- 2.39.2
[PATCH 35/42] mmc: exynos_dw_mmc: Use CONFIG_IS_ENABLED() to check config options
Use CONFIG_IS_ENABLED() macro to check config options as recommended by checkpatch, instead of checking those with just #ifdef CONFIG_... No functional change. Signed-off-by: Sam Protsenko --- drivers/mmc/exynos_dw_mmc.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c index e416fbe5397a..b7c3b356f0ac 100644 --- a/drivers/mmc/exynos_dw_mmc.c +++ b/drivers/mmc/exynos_dw_mmc.c @@ -28,7 +28,7 @@ /* Quirks */ #define DWMCI_QUIRK_DISABLE_SMUBIT(0) -#ifdef CONFIG_DM_MMC +#if CONFIG_IS_ENABLED(DM_MMC) #include DECLARE_GLOBAL_DATA_PTR; @@ -47,7 +47,7 @@ struct exynos_dwmmc_variant { /* Exynos implmentation specific drver private data */ struct dwmci_exynos_priv_data { -#ifdef CONFIG_DM_MMC +#if CONFIG_IS_ENABLED(DM_MMC) struct dwmci_host host; #endif struct clk clk; @@ -59,7 +59,7 @@ struct dwmci_exynos_priv_data { static struct dwmci_exynos_priv_data *exynos_dwmmc_get_priv( struct dwmci_host *host) { -#ifdef CONFIG_DM_MMC +#if CONFIG_IS_ENABLED(DM_MMC) return container_of(host, struct dwmci_exynos_priv_data, host); #else return host->priv; @@ -231,7 +231,7 @@ static int exynos_dwmci_core_init(struct dwmci_host *host) host->clksel = exynos_dwmci_clksel; host->get_mmc_clk = exynos_dwmci_get_clk; -#ifndef CONFIG_DM_MMC +#if !CONFIG_IS_ENABLED(DM_MMC) /* Add the mmc channel to be registered with mmc core */ if (add_dwmci(host, DWMMC_MAX_FREQ, DWMMC_MIN_FREQ)) { printf("DWMMC%d registration failed\n", host->dev_index); @@ -338,7 +338,7 @@ static int exynos_dwmmc_of_to_plat(struct udevice *dev) return 0; } -#ifdef CONFIG_DM_MMC +#if CONFIG_IS_ENABLED(DM_MMC) static int exynos_dwmmc_probe(struct udevice *dev) { struct exynos_mmc_plat *plat = dev_get_plat(dev); -- 2.39.2
[PATCH 34/42] mmc: exynos_dw_mmc: Remove common.h
common.h header is marked for removal treewide and shouldn't be used. Remove it from Exynos DW MMC driver. No functional change. Signed-off-by: Sam Protsenko --- drivers/mmc/exynos_dw_mmc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c index ac1a1784b440..e416fbe5397a 100644 --- a/drivers/mmc/exynos_dw_mmc.c +++ b/drivers/mmc/exynos_dw_mmc.c @@ -5,7 +5,6 @@ */ #include -#include #include #include #include -- 2.39.2
[PATCH 33/42] mmc: exynos_dw_mmc: Add support for ARM64 Exynos chips
Add the compatible entry and corresponding chip data for Exynos7 compatible chips, which covers modern ARM64 based Exynos chips. They have some differences w.r.t. old ARM32 Exynos chips: - CLKSEL register offset is different - 64-bit IDMAC descriptor and 64-bit IDMAC registers are used (implemented in dw_mmc core driver) In terms of the driver implementation, the CIU clock is obtained via CCF framework (as opposed to ad-hoc clock driver implementation for ARM32 chips). Signed-off-by: Sam Protsenko --- arch/arm/mach-exynos/include/mach/dwmmc.h | 1 + drivers/mmc/exynos_dw_mmc.c | 8 2 files changed, 9 insertions(+) diff --git a/arch/arm/mach-exynos/include/mach/dwmmc.h b/arch/arm/mach-exynos/include/mach/dwmmc.h index 811e9a04c6e3..7cb71be0d9fd 100644 --- a/arch/arm/mach-exynos/include/mach/dwmmc.h +++ b/arch/arm/mach-exynos/include/mach/dwmmc.h @@ -8,6 +8,7 @@ #define __ASM_ARM_ARCH_DWMMC_H #define DWMCI_CLKSEL 0x09C +#define DWMCI_CLKSEL64 0x0a8 #define DWMCI_SET_SAMPLE_CLK(x)(x) #define DWMCI_SET_DRV_CLK(x) ((x) << 16) #define DWMCI_SET_DIV_RATIO(x) ((x) << 24) diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c index 938fd51a2ac6..ac1a1784b440 100644 --- a/drivers/mmc/exynos_dw_mmc.c +++ b/drivers/mmc/exynos_dw_mmc.c @@ -386,6 +386,11 @@ static const struct exynos_dwmmc_variant exynos5_drv_data = { #endif }; +static const struct exynos_dwmmc_variant exynos7_smu_drv_data = { + .clksel = DWMCI_CLKSEL64, + .quirks = DWMCI_QUIRK_DISABLE_SMU, +}; + static const struct udevice_id exynos_dwmmc_ids[] = { { .compatible = "samsung,exynos4412-dw-mshc", @@ -393,6 +398,9 @@ static const struct udevice_id exynos_dwmmc_ids[] = { }, { .compatible = "samsung,exynos-dwmmc", .data = (ulong)&exynos5_drv_data, + }, { + .compatible = "samsung,exynos7-dw-mshc-smu", + .data = (ulong)&exynos7_smu_drv_data, }, { } }; -- 2.39.2
[PATCH 32/42] mmc: exynos_dw_mmc: Set requested freq in get_mmc_clk() callback
By now exynos_dw_mmc driver was relying on the correct CIU clock frequency being set on driver init. But dw_mmc core is actually trying to change CIU clock rate dynamically, on init and in set_ios() callback, which it's requesting via host->get_mmc_clk() callback (the name is misleading: although it's called "get_mmc_clk()", it can actually request both get and set operations). Implement setting the requested rate for CIU clock in Exynos driver to achieve the correct dw_mmc core driver operation at all times. DDR mode requires the clock to be twice as fast (when 8 bit bus is used), so handle this too, to make DDR function properly. This change makes the eMMC throughput on E850-96 board twice as fast. That's because "clock-frequency" is set to 800 MHz in E850-96 device tree, but for DDR52 mode it should be 416 MHz (and TRM states it should be 400 MHz for DDR50/8bit mode). The dw_mmc core is requesting 52 MHz bus_hz for DDR52 mode, and DDR+8bit mode means it should be x2 fast, so: f_ciu = 2 * ciu_div * f_bus = 2 * 4 * 52e6 = 416 MHz, where f_ciu - freq of clock fed to DW MMC block from CMU (SDCLKIN), Hz f_bus - freq of clock fed to the card (CCLKIN), Hz ciu_div - value of internal divider (in DW MMC block). Another way to work that around would be overriding the "clock-frequency" property in corresponding dts. But setting the clock frequency dynamically as it's done here looks much neater. This implementation follows what's done in Linux kernel dw_mmc-exynos driver in .set_ios() callback for MMC_TIMING_MMC_DDR52 case. Signed-off-by: Sam Protsenko --- drivers/mmc/exynos_dw_mmc.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c index d3708ecb6407..938fd51a2ac6 100644 --- a/drivers/mmc/exynos_dw_mmc.c +++ b/drivers/mmc/exynos_dw_mmc.c @@ -170,7 +170,17 @@ unsigned int exynos_dwmci_get_clk(struct dwmci_host *host, uint freq) u8 clk_div; int err; + /* Should be double rate for DDR mode */ + if (host->mmc->selected_mode == MMC_DDR_52 && host->mmc->bus_width == 8) + freq *= 2; + clk_div = exynos_dwmmc_get_ciu_div(host); + err = exynos_dwmmc_set_sclk(host, freq * clk_div); + if (err) { + printf("DWMMC%d: failed to set clock rate (%d); " + "continue anyway\n", host->dev_index, err); + } + err = exynos_dwmmc_get_sclk(host, &sclk); if (err) { printf("DWMMC%d: failed to get clock rate (%d)\n", -- 2.39.2
[PATCH 31/42] mmc: exynos_dw_mmc: Read and use DDR timing when available
DDR timing values should be defined in "samsung,dw-mshc-ddr-timing" dts property, and used when DDR MMC mode is selected. Read that value from dts and use it. If it's not available, use SDR timing values instead. This change is following upstream Linux kernel implementation. Signed-off-by: Sam Protsenko --- drivers/mmc/exynos_dw_mmc.c | 20 +++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c index 91300f67b9fe..d3708ecb6407 100644 --- a/drivers/mmc/exynos_dw_mmc.c +++ b/drivers/mmc/exynos_dw_mmc.c @@ -53,6 +53,7 @@ struct dwmci_exynos_priv_data { #endif struct clk clk; u32 sdr_timing; + u32 ddr_timing; const struct exynos_dwmmc_variant *chip; }; @@ -128,8 +129,14 @@ static int exynos_dwmmc_set_sclk(struct dwmci_host *host, unsigned long rate) static int exynos_dwmci_clksel(struct dwmci_host *host) { struct dwmci_exynos_priv_data *priv = exynos_dwmmc_get_priv(host); + u32 timing; - dwmci_writel(host, priv->chip->clksel, priv->sdr_timing); + if (host->mmc->selected_mode == MMC_DDR_52) + timing = priv->ddr_timing; + else + timing = priv->sdr_timing; + + dwmci_writel(host, priv->chip->clksel, timing); return 0; } @@ -305,6 +312,17 @@ static int exynos_dwmmc_of_to_plat(struct udevice *dev) priv->sdr_timing = DWMMC_MMC2_SDR_TIMING_VAL; } + err = dev_read_u32_array(dev, "samsung,dw-mshc-ddr-timing", timing, 2); + if (err) { + debug("DWMMC%d: Can't get ddr-timings, using sdr-timings\n", + host->dev_index); + priv->ddr_timing = priv->sdr_timing; + } else { + priv->ddr_timing = DWMCI_SET_SAMPLE_CLK(timing[0]) | + DWMCI_SET_DRV_CLK(timing[1]) | + DWMCI_SET_DIV_RATIO(div); + } + host->fifo_depth = dev_read_u32_default(dev, "fifo-depth", 0); host->bus_hz = dev_read_u32_default(dev, "clock-frequency", 0); -- 2.39.2
[PATCH 30/42] mmc: exynos_dw_mmc: Move quirks from struct dwmci_host to chip data
host->quirks field is only used internally in exynos_dw_mmc.c driver. To avoid cluttering the scope of struct dwmci_host, move quirks field into Exynos driver's chip data, where it can be statically defined. No functional change. Signed-off-by: Sam Protsenko --- drivers/mmc/exynos_dw_mmc.c | 13 - include/dwmmc.h | 5 - 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c index 8a307c9c123b..91300f67b9fe 100644 --- a/drivers/mmc/exynos_dw_mmc.c +++ b/drivers/mmc/exynos_dw_mmc.c @@ -26,6 +26,9 @@ #define EXYNOS4412_FIXED_CIU_CLK_DIV 4 +/* Quirks */ +#define DWMCI_QUIRK_DISABLE_SMUBIT(0) + #ifdef CONFIG_DM_MMC #include DECLARE_GLOBAL_DATA_PTR; @@ -40,6 +43,7 @@ struct exynos_mmc_plat { struct exynos_dwmmc_variant { u32 clksel; /* CLKSEL register offset */ u8 div; /* (optional) fixed clock divider value: 0..7 */ + u32 quirks; /* quirk flags - see DWMCI_QUIRK_... */ }; /* Exynos implmentation specific drver private data */ @@ -174,7 +178,7 @@ static void exynos_dwmci_board_init(struct dwmci_host *host) { struct dwmci_exynos_priv_data *priv = exynos_dwmmc_get_priv(host); - if (host->quirks & DWMCI_QUIRK_DISABLE_SMU) { + if (priv->chip->quirks & DWMCI_QUIRK_DISABLE_SMU) { dwmci_writel(host, EMMCP_MPSBEGIN0, 0); dwmci_writel(host, EMMCP_SEND0, 0); dwmci_writel(host, EMMCP_CTRL0, @@ -206,11 +210,7 @@ static int exynos_dwmci_core_init(struct dwmci_host *host) } host->name = "EXYNOS DWMMC"; -#ifdef CONFIG_EXYNOS5420 - host->quirks = DWMCI_QUIRK_DISABLE_SMU; -#endif host->board_init = exynos_dwmci_board_init; - host->caps = MMC_MODE_DDR_52MHz; host->clksel = exynos_dwmci_clksel; host->get_mmc_clk = exynos_dwmci_get_clk; @@ -353,6 +353,9 @@ static const struct exynos_dwmmc_variant exynos4_drv_data = { static const struct exynos_dwmmc_variant exynos5_drv_data = { .clksel = DWMCI_CLKSEL, +#if CONFIG_IS_ENABLED(EXYNOS5420) + .quirks = DWMCI_QUIRK_DISABLE_SMU, +#endif }; static const struct udevice_id exynos_dwmmc_ids[] = { diff --git a/include/dwmmc.h b/include/dwmmc.h index c69c7952b930..a7e8709b7b05 100644 --- a/include/dwmmc.h +++ b/include/dwmmc.h @@ -149,9 +149,6 @@ #define DWMCI_IDINTEN_TI BIT(0) #define DWMCI_IDINTEN_MASK (DWMCI_IDINTEN_TI | DWMCI_IDINTEN_RI) -/* Quirks */ -#define DWMCI_QUIRK_DISABLE_SMUBIT(0) - /** * struct dwmci_idmac_regs - Offsets of IDMAC registers * @@ -180,7 +177,6 @@ struct dwmci_idmac_regs { * * @name: Device name * @ioaddr:Base I/O address of controller - * @quirks:Quick flags - see DWMCI_QUIRK_... * @caps: Capabilities - see MMC_MODE_... * @clock: Current clock frequency (after internal divider), Hz * @bus_hz:Bus speed in Hz, if @get_mmc_clk() is NULL @@ -200,7 +196,6 @@ struct dwmci_idmac_regs { struct dwmci_host { const char *name; void *ioaddr; - unsigned int quirks; unsigned int caps; unsigned int clock; unsigned int bus_hz; -- 2.39.2
[PATCH 29/42] mmc: exynos_dw_mmc: Read common clock-frequency property
Instead of using non-standard "bus_hz" dts property, read common "clock-frequency" property used in upstream Linux kernel. It's safe to do so, as "clock-frequency" property was already added to corresponding nodes in all affected Exynos device tree files. No functional change. Signed-off-by: Sam Protsenko --- drivers/mmc/exynos_dw_mmc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c index b046ac6c55ea..8a307c9c123b 100644 --- a/drivers/mmc/exynos_dw_mmc.c +++ b/drivers/mmc/exynos_dw_mmc.c @@ -306,7 +306,7 @@ static int exynos_dwmmc_of_to_plat(struct udevice *dev) } host->fifo_depth = dev_read_u32_default(dev, "fifo-depth", 0); - host->bus_hz = dev_read_u32_default(dev, "bus_hz", 0); + host->bus_hz = dev_read_u32_default(dev, "clock-frequency", 0); return 0; } -- 2.39.2
[PATCH 28/42] mmc: exynos_dw_mmc: Read common bus-width property
Instead of using non-standard "samsung,bus-width" dts property, read common "bus-width" property used in upstream Linux kernel. It's safe to do so, as "bus-width" property was already added to corresponding nodes in all affected Exynos device tree files. No functional change. Signed-off-by: Sam Protsenko --- drivers/mmc/exynos_dw_mmc.c | 2 +- drivers/mmc/s5p_sdhci.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c index 646302f54ae6..b046ac6c55ea 100644 --- a/drivers/mmc/exynos_dw_mmc.c +++ b/drivers/mmc/exynos_dw_mmc.c @@ -274,7 +274,7 @@ static int exynos_dwmmc_of_to_plat(struct udevice *dev) #endif /* Get the bus width from the device node (Default is 4bit buswidth) */ - host->buswidth = dev_read_u32_default(dev, "samsung,bus-width", 4); + host->buswidth = dev_read_u32_default(dev, "bus-width", 4); /* Set the base address from the device node */ host->ioaddr = dev_read_addr_ptr(dev); diff --git a/drivers/mmc/s5p_sdhci.c b/drivers/mmc/s5p_sdhci.c index 3b74feae68c7..0b49a9c5f2a9 100644 --- a/drivers/mmc/s5p_sdhci.c +++ b/drivers/mmc/s5p_sdhci.c @@ -167,7 +167,7 @@ static int sdhci_get_config(const void *blob, int node, struct sdhci_host *host) host->index = dev_id - PERIPH_ID_SDMMC0; /* Get bus width */ - bus_width = fdtdec_get_int(blob, node, "samsung,bus-width", 0); + bus_width = fdtdec_get_int(blob, node, "bus-width", 0); if (bus_width <= 0) { debug("MMC: Can't get bus-width\n"); return -EINVAL; -- 2.39.2
[PATCH 27/42] mmc: exynos_dw_mmc: Refactor fixed CIU clock divider
Some chips like Exynos4412 have fixed internal CIU clock divider. Instead of reading it from non-standard "div" dts property, store its value in the driver internally, in static chip data associated with corresponding compatible. This makes it possible to avoid using host->div for storing it, so the latter can be removed safely. Also create a helper function called exynos_dwmmc_get_ciu_div() for getting the current div value: in case the fixed div is provided in the chip data it will be used, otherwise the current div value is being read from CLKSEL register. The insights for this change were taken from dw_mmc-exynos.c driver in Linux kernel. No functional change. Signed-off-by: Sam Protsenko --- drivers/mmc/ca_dw_mmc.c | 2 +- drivers/mmc/exynos_dw_mmc.c | 43 + include/dwmmc.h | 2 -- 3 files changed, 30 insertions(+), 17 deletions(-) diff --git a/drivers/mmc/ca_dw_mmc.c b/drivers/mmc/ca_dw_mmc.c index a17ed8c11cbe..342e09d02306 100644 --- a/drivers/mmc/ca_dw_mmc.c +++ b/drivers/mmc/ca_dw_mmc.c @@ -87,7 +87,7 @@ unsigned int ca_dwmci_get_mmc_clock(struct dwmci_host *host, uint freq) clk_div = 1; } - return SD_SCLK_MAX / clk_div / (host->div + 1); + return SD_SCLK_MAX / clk_div; } static int ca_dwmmc_of_to_plat(struct udevice *dev) diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c index edf8fbc7d734..646302f54ae6 100644 --- a/drivers/mmc/exynos_dw_mmc.c +++ b/drivers/mmc/exynos_dw_mmc.c @@ -24,6 +24,8 @@ #defineDWMMC_MMC0_SDR_TIMING_VAL 0x03030001 #defineDWMMC_MMC2_SDR_TIMING_VAL 0x03020001 +#define EXYNOS4412_FIXED_CIU_CLK_DIV 4 + #ifdef CONFIG_DM_MMC #include DECLARE_GLOBAL_DATA_PTR; @@ -37,6 +39,7 @@ struct exynos_mmc_plat { /* Chip specific data */ struct exynos_dwmmc_variant { u32 clksel; /* CLKSEL register offset */ + u8 div; /* (optional) fixed clock divider value: 0..7 */ }; /* Exynos implmentation specific drver private data */ @@ -127,12 +130,18 @@ static int exynos_dwmci_clksel(struct dwmci_host *host) return 0; } -unsigned int exynos_dwmci_get_clk(struct dwmci_host *host, uint freq) +/** + * exynos_dwmmc_get_ciu_div - Get internal clock divider value + * @host: MMC controller object + * + * Returns: Divider value, in range of 1..8 + */ +static u8 exynos_dwmmc_get_ciu_div(struct dwmci_host *host) { struct dwmci_exynos_priv_data *priv = exynos_dwmmc_get_priv(host); - unsigned long sclk; - int8_t clk_div; - int err; + + if (priv->chip->div) + return priv->chip->div + 1; /* * Since SDCLKIN is divided inside controller by the DIVRATIO @@ -140,9 +149,17 @@ unsigned int exynos_dwmci_get_clk(struct dwmci_host *host, uint freq) * clock value to calculate the CLKDIV value. * as per user manual:cclk_in = SDCLKIN / (DIVRATIO + 1) */ - clk_div = ((dwmci_readl(host, priv->chip->clksel) >> DWMCI_DIVRATIO_BIT) - & DWMCI_DIVRATIO_MASK) + 1; + return ((dwmci_readl(host, priv->chip->clksel) >> DWMCI_DIVRATIO_BIT) + & DWMCI_DIVRATIO_MASK) + 1; +} +unsigned int exynos_dwmci_get_clk(struct dwmci_host *host, uint freq) +{ + unsigned long sclk; + u8 clk_div; + int err; + + clk_div = exynos_dwmmc_get_ciu_div(host); err = exynos_dwmmc_get_sclk(host, &sclk); if (err) { printf("DWMMC%d: failed to get clock rate (%d)\n", @@ -150,11 +167,7 @@ unsigned int exynos_dwmci_get_clk(struct dwmci_host *host, uint freq) return 0; } - /* -* Assume to know divider value. -* When clock unit is broken, need to set "host->div" -*/ - return sclk / clk_div / (host->div + 1); + return sclk / clk_div; } static void exynos_dwmci_board_init(struct dwmci_host *host) @@ -270,8 +283,10 @@ static int exynos_dwmmc_of_to_plat(struct udevice *dev) return -EINVAL; } - /* Extract the timing info from the node */ - div = dev_read_u32_default(dev, "samsung,dw-mshc-ciu-div", 0); + if (priv->chip->div) + div = priv->chip->div; + else + div = dev_read_u32_default(dev, "samsung,dw-mshc-ciu-div", 0); err = dev_read_u32_array(dev, "samsung,dw-mshc-sdr-timing", timing, 2); if (err) { printf("DWMMC%d: Can't get sdr-timings\n", host->dev_index); @@ -292,7 +307,6 @@ static int exynos_dwmmc_of_to_plat(struct udevice *dev) host->fifo_depth = dev_read_u32_default(dev, "fifo-depth", 0); host->bus_hz = dev_read_u32_default(dev, "bus_hz", 0); - host->div = dev_read_u32_default(dev, "div", 0); return 0; } @@ -334,6 +348,7 @@ static int exynos_dwmmc_bind(struct udevice *dev) static const struct exynos_dwmmc_variant exynos4_dr
[PATCH 26/42] mmc: exynos_dw_mmc: Abstract CLKSEL register
CLKSEL register offset may vary between different Exynos chips, e.g. on ARM64 vs ARM32 chips. Provide a way to specify its offset value for each compatible instead of hard-coding its value in read/write calls. No functional change. Signed-off-by: Sam Protsenko --- drivers/mmc/exynos_dw_mmc.c | 30 ++ 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c index 788587b622ca..edf8fbc7d734 100644 --- a/drivers/mmc/exynos_dw_mmc.c +++ b/drivers/mmc/exynos_dw_mmc.c @@ -34,6 +34,11 @@ struct exynos_mmc_plat { }; #endif +/* Chip specific data */ +struct exynos_dwmmc_variant { + u32 clksel; /* CLKSEL register offset */ +}; + /* Exynos implmentation specific drver private data */ struct dwmci_exynos_priv_data { #ifdef CONFIG_DM_MMC @@ -41,6 +46,7 @@ struct dwmci_exynos_priv_data { #endif struct clk clk; u32 sdr_timing; + const struct exynos_dwmmc_variant *chip; }; static struct dwmci_exynos_priv_data *exynos_dwmmc_get_priv( @@ -116,13 +122,14 @@ static int exynos_dwmci_clksel(struct dwmci_host *host) { struct dwmci_exynos_priv_data *priv = exynos_dwmmc_get_priv(host); - dwmci_writel(host, DWMCI_CLKSEL, priv->sdr_timing); + dwmci_writel(host, priv->chip->clksel, priv->sdr_timing); return 0; } unsigned int exynos_dwmci_get_clk(struct dwmci_host *host, uint freq) { + struct dwmci_exynos_priv_data *priv = exynos_dwmmc_get_priv(host); unsigned long sclk; int8_t clk_div; int err; @@ -133,7 +140,7 @@ unsigned int exynos_dwmci_get_clk(struct dwmci_host *host, uint freq) * clock value to calculate the CLKDIV value. * as per user manual:cclk_in = SDCLKIN / (DIVRATIO + 1) */ - clk_div = ((dwmci_readl(host, DWMCI_CLKSEL) >> DWMCI_DIVRATIO_BIT) + clk_div = ((dwmci_readl(host, priv->chip->clksel) >> DWMCI_DIVRATIO_BIT) & DWMCI_DIVRATIO_MASK) + 1; err = exynos_dwmmc_get_sclk(host, &sclk); @@ -229,6 +236,8 @@ static int exynos_dwmmc_of_to_plat(struct udevice *dev) int err = 0; u32 div, timing[2]; + priv->chip = (struct exynos_dwmmc_variant *)dev_get_driver_data(dev); + #if CONFIG_IS_ENABLED(CPU_V7A) const void *blob = gd->fdt_blob; int node = dev_of_offset(dev); @@ -323,9 +332,22 @@ static int exynos_dwmmc_bind(struct udevice *dev) return dwmci_bind(dev, &plat->mmc, &plat->cfg); } +static const struct exynos_dwmmc_variant exynos4_drv_data = { + .clksel = DWMCI_CLKSEL, +}; + +static const struct exynos_dwmmc_variant exynos5_drv_data = { + .clksel = DWMCI_CLKSEL, +}; + static const struct udevice_id exynos_dwmmc_ids[] = { - { .compatible = "samsung,exynos4412-dw-mshc" }, - { .compatible = "samsung,exynos-dwmmc" }, + { + .compatible = "samsung,exynos4412-dw-mshc", + .data = (ulong)&exynos4_drv_data, + }, { + .compatible = "samsung,exynos-dwmmc", + .data = (ulong)&exynos5_drv_data, + }, { } }; -- 2.39.2
[PATCH 24/42] mmc: exynos_dw_mmc: Convert to use livetree API
Update the driver to use livetree API instead of FDT one. No functional change. Signed-off-by: Sam Protsenko --- drivers/mmc/exynos_dw_mmc.c | 17 - 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c index 34485311c107..84382c606a1f 100644 --- a/drivers/mmc/exynos_dw_mmc.c +++ b/drivers/mmc/exynos_dw_mmc.c @@ -7,9 +7,7 @@ #include #include #include -#include #include -#include #include #include #include @@ -226,18 +224,19 @@ static int do_dwmci_init(struct dwmci_host *host) static int exynos_dwmmc_of_to_plat(struct udevice *dev) { - const void *blob = gd->fdt_blob; struct dwmci_exynos_priv_data *priv = dev_get_priv(dev); struct dwmci_host *host = &priv->host; - int node = dev_of_offset(dev); int err = 0; u32 timing[3]; #if CONFIG_IS_ENABLED(CPU_V7A) + const void *blob = gd->fdt_blob; + int node = dev_of_offset(dev); + /* Extract device id for each mmc channel */ host->dev_id = pinmux_decode_periph_id(blob, node); - host->dev_index = fdtdec_get_int(blob, node, "index", host->dev_id); + host->dev_index = dev_read_u32_default(dev, "index", host->dev_id); if (host->dev_index == host->dev_id) host->dev_index = host->dev_id - PERIPH_ID_SDMMC0; @@ -253,7 +252,7 @@ static int exynos_dwmmc_of_to_plat(struct udevice *dev) #endif /* Get the bus width from the device node (Default is 4bit buswidth) */ - host->buswidth = fdtdec_get_int(blob, node, "samsung,bus-width", 4); + host->buswidth = dev_read_u32_default(dev, "samsung,bus-width", 4); /* Set the base address from the device node */ host->ioaddr = dev_read_addr_ptr(dev); @@ -263,7 +262,7 @@ static int exynos_dwmmc_of_to_plat(struct udevice *dev) } /* Extract the timing info from the node */ - err = fdtdec_get_int_array(blob, node, "samsung,timing", timing, 3); + err = dev_read_u32_array(dev, "samsung,timing", timing, 3); if (err) { printf("DWMMC%d: Can't get sdr-timings for devider\n", host->dev_index); @@ -283,8 +282,8 @@ static int exynos_dwmmc_of_to_plat(struct udevice *dev) } host->fifo_depth = dev_read_u32_default(dev, "fifo-depth", 0); - host->bus_hz = fdtdec_get_int(blob, node, "bus_hz", 0); - host->div = fdtdec_get_int(blob, node, "div", 0); + host->bus_hz = dev_read_u32_default(dev, "bus_hz", 0); + host->div = dev_read_u32_default(dev, "div", 0); return 0; } -- 2.39.2
[PATCH 25/42] mmc: exynos_dw_mmc: Read upstream SDR timing properties
The obsolete "samsung,timing" dts property is now split into "samsung,dw-mshc-ciu-div" (for holding the internal DW MMC divider value) and "samsung,dw-mshc-sdr-timing" (for actual timing values) in upstream Linux kernel. Rework the driver to make use of new properties instead of the old one. All affected dts files were already updated accordingly. No functional change. Signed-off-by: Sam Protsenko --- drivers/mmc/exynos_dw_mmc.c | 14 +++--- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c index 84382c606a1f..788587b622ca 100644 --- a/drivers/mmc/exynos_dw_mmc.c +++ b/drivers/mmc/exynos_dw_mmc.c @@ -227,7 +227,7 @@ static int exynos_dwmmc_of_to_plat(struct udevice *dev) struct dwmci_exynos_priv_data *priv = dev_get_priv(dev); struct dwmci_host *host = &priv->host; int err = 0; - u32 timing[3]; + u32 div, timing[2]; #if CONFIG_IS_ENABLED(CPU_V7A) const void *blob = gd->fdt_blob; @@ -262,16 +262,16 @@ static int exynos_dwmmc_of_to_plat(struct udevice *dev) } /* Extract the timing info from the node */ - err = dev_read_u32_array(dev, "samsung,timing", timing, 3); + div = dev_read_u32_default(dev, "samsung,dw-mshc-ciu-div", 0); + err = dev_read_u32_array(dev, "samsung,dw-mshc-sdr-timing", timing, 2); if (err) { - printf("DWMMC%d: Can't get sdr-timings for devider\n", - host->dev_index); + printf("DWMMC%d: Can't get sdr-timings\n", host->dev_index); return -EINVAL; } - priv->sdr_timing = (DWMCI_SET_SAMPLE_CLK(timing[0]) | - DWMCI_SET_DRV_CLK(timing[1]) | - DWMCI_SET_DIV_RATIO(timing[2])); + priv->sdr_timing = DWMCI_SET_SAMPLE_CLK(timing[0]) | + DWMCI_SET_DRV_CLK(timing[1]) | + DWMCI_SET_DIV_RATIO(div); /* sdr_timing didn't assigned anything, use the default value */ if (!priv->sdr_timing) { -- 2.39.2
[PATCH 23/42] mmc: exynos_dw_mmc: Use .of_to_plat for device tree parsing
exynos_dwmci_get_config() is called from the probe function and used to read data from device tree. Make use of .of_to_plat driver callback instead, and convert exynos_dwmci_get_config() to match its signature. No functional change. Signed-off-by: Sam Protsenko --- drivers/mmc/exynos_dw_mmc.c | 13 ++--- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c index 8a3f73e3739c..34485311c107 100644 --- a/drivers/mmc/exynos_dw_mmc.c +++ b/drivers/mmc/exynos_dw_mmc.c @@ -224,10 +224,12 @@ static int do_dwmci_init(struct dwmci_host *host) return exynos_dwmci_core_init(host); } -static int exynos_dwmci_get_config(struct udevice *dev, const void *blob, - int node, struct dwmci_host *host, - struct dwmci_exynos_priv_data *priv) +static int exynos_dwmmc_of_to_plat(struct udevice *dev) { + const void *blob = gd->fdt_blob; + struct dwmci_exynos_priv_data *priv = dev_get_priv(dev); + struct dwmci_host *host = &priv->host; + int node = dev_of_offset(dev); int err = 0; u32 timing[3]; @@ -302,10 +304,6 @@ static int exynos_dwmmc_probe(struct udevice *dev) return err; #endif - err = exynos_dwmci_get_config(dev, gd->fdt_blob, dev_of_offset(dev), - host, priv); - if (err) - return err; err = do_dwmci_init(host); if (err) return err; @@ -336,6 +334,7 @@ U_BOOT_DRIVER(exynos_dwmmc_drv) = { .name = "exynos_dwmmc", .id = UCLASS_MMC, .of_match = exynos_dwmmc_ids, + .of_to_plat = exynos_dwmmc_of_to_plat, .bind = exynos_dwmmc_bind, .ops= &dm_dwmci_ops, .probe = exynos_dwmmc_probe, -- 2.39.2
[PATCH 19/42] mmc: exynos_dw_mmc: Fix obtaining the base address of controller
Getting the base address with outdated fdtdec_get_addr() API and further casting it to (void *) leads to next build warning on ARM64 platforms: In function 'exynos_dwmci_get_config': warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] host->ioaddr = (void *)base; Use livetree API instead (dev_read_addr_ptr()), which handles this correctly. Fixes: a082a2dde061 ("EXYNOS5: DWMMC: Added FDT support for DWMMC") Signed-off-by: Sam Protsenko --- drivers/mmc/exynos_dw_mmc.c | 7 +++ 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c index 14cb0c05cb55..1f69e193f601 100644 --- a/drivers/mmc/exynos_dw_mmc.c +++ b/drivers/mmc/exynos_dw_mmc.c @@ -156,7 +156,7 @@ static int exynos_dwmci_get_config(struct udevice *dev, const void *blob, struct dwmci_exynos_priv_data *priv) { int err = 0; - u32 base, timing[3]; + u32 timing[3]; /* Extract device id for each mmc channel */ host->dev_id = pinmux_decode_periph_id(blob, node); @@ -174,12 +174,11 @@ static int exynos_dwmci_get_config(struct udevice *dev, const void *blob, host->buswidth = fdtdec_get_int(blob, node, "samsung,bus-width", 4); /* Set the base address from the device node */ - base = fdtdec_get_addr(blob, node, "reg"); - if (!base) { + host->ioaddr = dev_read_addr_ptr(dev); + if (!host->ioaddr) { printf("DWMMC%d: Can't get base address\n", host->dev_index); return -EINVAL; } - host->ioaddr = (void *)base; /* Extract the timing info from the node */ err = fdtdec_get_int_array(blob, node, "samsung,timing", timing, 3); -- 2.39.2
[PATCH 18/42] arm: exynos: Add header guard for dwmmc.h
Add missing header guard to prevent possible build errors. Fixes: 77b55e8cfcee ("ARM: exynos: move SoC sources to mach-exynos") Signed-off-by: Sam Protsenko --- arch/arm/mach-exynos/include/mach/dwmmc.h | 5 + 1 file changed, 5 insertions(+) diff --git a/arch/arm/mach-exynos/include/mach/dwmmc.h b/arch/arm/mach-exynos/include/mach/dwmmc.h index 59c28ed54c58..811e9a04c6e3 100644 --- a/arch/arm/mach-exynos/include/mach/dwmmc.h +++ b/arch/arm/mach-exynos/include/mach/dwmmc.h @@ -4,6 +4,9 @@ * Jaehoon Chung */ +#ifndef __ASM_ARM_ARCH_DWMMC_H +#define __ASM_ARM_ARCH_DWMMC_H + #define DWMCI_CLKSEL 0x09C #define DWMCI_SET_SAMPLE_CLK(x)(x) #define DWMCI_SET_DRV_CLK(x) ((x) << 16) @@ -25,3 +28,5 @@ /* CLKSEL Register */ #define DWMCI_DIVRATIO_BIT 24 #define DWMCI_DIVRATIO_MASK0x7 + +#endif /* __ASM_ARM_ARCH_DWMMC_H */ -- 2.39.2
[PATCH 22/42] mmc: exynos_dw_mmc: Obtain and use CIU clock via CCF API
New Exynos chips should implement clock drivers using CCF framework. In that case corresponding CCF functions can be used to get/set the clock rates. Moreover, already existing get_mmc_clk() and set_mmc_clk() calls are only implemented for CONFIG_CPU_V7A (i.e. ARM32 chips). In case of ARM64 chips that config option is not defined, so build will crash on linking stage, with errors like these: ld: drivers/mmc/exynos_dw_mmc.o: in function `exynos_dwmci_get_sclk': undefined reference to `get_mmc_clk' ld: drivers/mmc/exynos_dw_mmc.o: in function `exynos_dwmci_set_sclk': undefined reference to `set_mmc_clk' Fix that issue by using CCF clocks API on ARM64 platforms for getting and setting the source clock (sclk = SDCLKIN = CIU) rate. To implement this, first extract the existing ARM32 clock control code into helper functions with more generic signatures to abstract getting/setting the sclk rate. Then add CCF clock support to those functions for ARM64 platforms. Fixes: a082a2dde061 ("EXYNOS5: DWMMC: Added FDT support for DWMMC") Signed-off-by: Sam Protsenko --- drivers/mmc/exynos_dw_mmc.c | 87 + 1 file changed, 79 insertions(+), 8 deletions(-) diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c index 6d0872e0df50..8a3f73e3739c 100644 --- a/drivers/mmc/exynos_dw_mmc.c +++ b/drivers/mmc/exynos_dw_mmc.c @@ -4,6 +4,7 @@ * Jaehoon Chung */ +#include #include #include #include @@ -16,6 +17,7 @@ #include #include #include +#include #include #defineDWMMC_MAX_CH_NUM4 @@ -39,6 +41,7 @@ struct dwmci_exynos_priv_data { #ifdef CONFIG_DM_MMC struct dwmci_host host; #endif + struct clk clk; u32 sdr_timing; }; @@ -52,6 +55,61 @@ static struct dwmci_exynos_priv_data *exynos_dwmmc_get_priv( #endif } +/** + * exynos_dwmmc_get_sclk - Get source clock (SDCLKIN) rate + * @host: MMC controller object + * @rate: Will contain clock rate, Hz + * + * Return: 0 on success or negative value on error + */ +static int exynos_dwmmc_get_sclk(struct dwmci_host *host, unsigned long *rate) +{ +#if CONFIG_IS_ENABLED(CPU_V7A) + *rate = get_mmc_clk(host->dev_index); +#else + struct dwmci_exynos_priv_data *priv = exynos_dwmmc_get_priv(host); + + *rate = clk_get_rate(&priv->clk); +#endif + + if (IS_ERR_VALUE(*rate)) + return *rate; + + return 0; +} + +/** + * exynos_dwmmc_set_sclk - Set source clock (SDCLKIN) rate + * @host: MMC controller object + * @rate: Desired clock rate, Hz + * + * Return: 0 on success or negative value on error + */ +static int exynos_dwmmc_set_sclk(struct dwmci_host *host, unsigned long rate) +{ + int err; + +#if CONFIG_IS_ENABLED(CPU_V7A) + unsigned long sclk; + unsigned int div; + + err = exynos_dwmmc_get_sclk(host, &sclk); + if (err) + return err; + + div = DIV_ROUND_UP(sclk, rate); + set_mmc_clk(host->dev_index, div); +#else + struct dwmci_exynos_priv_data *priv = exynos_dwmmc_get_priv(host); + + err = clk_set_rate(&priv->clk, rate); + if (err < 0) + return err; +#endif + + return 0; +} + /* * Function used as callback function to initialise the * CLKSEL register for every mmc channel. @@ -69,6 +127,7 @@ unsigned int exynos_dwmci_get_clk(struct dwmci_host *host, uint freq) { unsigned long sclk; int8_t clk_div; + int err; /* * Since SDCLKIN is divided inside controller by the DIVRATIO @@ -78,7 +137,13 @@ unsigned int exynos_dwmci_get_clk(struct dwmci_host *host, uint freq) */ clk_div = ((dwmci_readl(host, DWMCI_CLKSEL) >> DWMCI_DIVRATIO_BIT) & DWMCI_DIVRATIO_MASK) + 1; - sclk = get_mmc_clk(host->dev_index); + + err = exynos_dwmmc_get_sclk(host, &sclk); + if (err) { + printf("DWMMC%d: failed to get clock rate (%d)\n", + host->dev_index, err); + return 0; + } /* * Assume to know divider value. @@ -108,19 +173,19 @@ static void exynos_dwmci_board_init(struct dwmci_host *host) static int exynos_dwmci_core_init(struct dwmci_host *host) { - unsigned int div; - unsigned long freq, sclk; + unsigned long freq; + int err; if (host->bus_hz) freq = host->bus_hz; else freq = DWMMC_MAX_FREQ; - /* request mmc clock vlaue of 52MHz. */ - sclk = get_mmc_clk(host->dev_index); - div = DIV_ROUND_UP(sclk, freq); - /* set the clock divisor for mmc */ - set_mmc_clk(host->dev_index, div); + err = exynos_dwmmc_set_sclk(host, freq); + if (err) { + printf("DWMMC%d: failed to set clock rate on probe (%d); " + "continue anyway\n", host->dev_index, err); + } host->name = "EXYNOS DWMMC"; #ifdef CONFI
[PATCH 21/42] mmc: exynos_dw_mmc: Don't call pinmux functions on ARM64 chips
Pinmux configuration on ARM64 platforms must be performed during startup in pinctrl driver using info from device tree. exynos_pinmux_config() and pinmux_decode_periph_id() are only available on ARM32 platforms, so don't call those functions on ARM64 platforms. Instead of the latter function, use "non-removable" property from device tree to derive the dev_index value. This fixes next linking errors on ARM64 platforms: ld: drivers/mmc/exynos_dw_mmc.o: in function `exynos_dwmci_get_config': undefined reference to `pinmux_decode_periph_id' ld: drivers/mmc/exynos_dw_mmc.o: in function `do_dwmci_init': undefined reference to `exynos_pinmux_config' Fixes: a082a2dde061 ("EXYNOS5: DWMMC: Added FDT support for DWMMC") Signed-off-by: Sam Protsenko --- drivers/mmc/exynos_dw_mmc.c | 9 + 1 file changed, 9 insertions(+) diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c index 8e80bd6a059f..6d0872e0df50 100644 --- a/drivers/mmc/exynos_dw_mmc.c +++ b/drivers/mmc/exynos_dw_mmc.c @@ -145,6 +145,7 @@ static int exynos_dwmci_core_init(struct dwmci_host *host) static int do_dwmci_init(struct dwmci_host *host) { +#if CONFIG_IS_ENABLED(CPU_V7A) int flag, err; flag = host->buswidth == 8 ? PINMUX_FLAG_8BIT_MODE : PINMUX_FLAG_NONE; @@ -153,6 +154,7 @@ static int do_dwmci_init(struct dwmci_host *host) printf("DWMMC%d not configure\n", host->dev_index); return err; } +#endif return exynos_dwmci_core_init(host); } @@ -164,6 +166,7 @@ static int exynos_dwmci_get_config(struct udevice *dev, const void *blob, int err = 0; u32 timing[3]; +#if CONFIG_IS_ENABLED(CPU_V7A) /* Extract device id for each mmc channel */ host->dev_id = pinmux_decode_periph_id(blob, node); @@ -175,6 +178,12 @@ static int exynos_dwmci_get_config(struct udevice *dev, const void *blob, printf("DWMMC%d: Can't get the dev index\n", host->dev_index); return -EINVAL; } +#else + if (dev_read_bool(dev, "non-removable")) + host->dev_index = 0; /* eMMC */ + else + host->dev_index = 2; /* SD card */ +#endif /* Get the bus width from the device node (Default is 4bit buswidth) */ host->buswidth = fdtdec_get_int(blob, node, "samsung,bus-width", 4); -- 2.39.2
[PATCH 20/42] mmc: exynos_dw_mmc: Fix getting private data in exynos_dwmci_board_init()
In case of CONFIG_DM_MMC, host->priv actually holds (struct udevice *), and not (struct dwmci_exynos_priv_data *). This makes *priv pointer invalid and may lead to Synchronous Abort during its dereference later in exynos_dwmci_board_init(). Fix it by extracting exynos_dwmmc_get_priv() helper from exynos_dwmci_clksel() and using it for getting the private data in exynos_dwmci_board_init() Fixes: 3537ee879e04 ("mmc: exynos_dw_mmc: support the Driver mode for Exynos") Signed-off-by: Sam Protsenko --- drivers/mmc/exynos_dw_mmc.c | 20 +--- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c index 1f69e193f601..8e80bd6a059f 100644 --- a/drivers/mmc/exynos_dw_mmc.c +++ b/drivers/mmc/exynos_dw_mmc.c @@ -42,18 +42,24 @@ struct dwmci_exynos_priv_data { u32 sdr_timing; }; +static struct dwmci_exynos_priv_data *exynos_dwmmc_get_priv( + struct dwmci_host *host) +{ +#ifdef CONFIG_DM_MMC + return container_of(host, struct dwmci_exynos_priv_data, host); +#else + return host->priv; +#endif +} + /* * Function used as callback function to initialise the * CLKSEL register for every mmc channel. */ static int exynos_dwmci_clksel(struct dwmci_host *host) { -#ifdef CONFIG_DM_MMC - struct dwmci_exynos_priv_data *priv = - container_of(host, struct dwmci_exynos_priv_data, host); -#else - struct dwmci_exynos_priv_data *priv = host->priv; -#endif + struct dwmci_exynos_priv_data *priv = exynos_dwmmc_get_priv(host); + dwmci_writel(host, DWMCI_CLKSEL, priv->sdr_timing); return 0; @@ -83,7 +89,7 @@ unsigned int exynos_dwmci_get_clk(struct dwmci_host *host, uint freq) static void exynos_dwmci_board_init(struct dwmci_host *host) { - struct dwmci_exynos_priv_data *priv = host->priv; + struct dwmci_exynos_priv_data *priv = exynos_dwmmc_get_priv(host); if (host->quirks & DWMCI_QUIRK_DISABLE_SMU) { dwmci_writel(host, EMMCP_MPSBEGIN0, 0); -- 2.39.2
[PATCH 15/42] mmc: dw_mmc: Improve coding style
Fix most of checkpatch warnings and other obvious style issues. No functional change. Signed-off-by: Sam Protsenko --- drivers/mmc/dw_mmc.c | 69 ++-- include/dwmmc.h | 149 ++- 2 files changed, 110 insertions(+), 108 deletions(-) diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c index ebe239547a7d..d0331550ef6b 100644 --- a/drivers/mmc/dw_mmc.c +++ b/drivers/mmc/dw_mmc.c @@ -125,8 +125,9 @@ static void dwmci_prepare_desc(struct dwmci_host *host, struct mmc_data *data, if (blk_cnt <= 8) { flags |= DWMCI_IDMAC_LD; cnt = data->blocksize * blk_cnt; - } else + } else { cnt = data->blocksize * 8; + } if (host->dma_64bit_address) { dwmci_set_idma_desc64(desc64, flags, cnt, @@ -150,10 +151,8 @@ static void dwmci_prepare_desc(struct dwmci_host *host, struct mmc_data *data, flush_dcache_range(data_start, roundup(data_end, ARCH_DMA_MINALIGN)); } -static void dwmci_prepare_data(struct dwmci_host *host, - struct mmc_data *data, - void *cur_idmac, - void *bounce_buffer) +static void dwmci_prepare_data(struct dwmci_host *host, struct mmc_data *data, + void *cur_idmac, void *bounce_buffer) { const u32 idmacl = virt_to_phys(cur_idmac) & 0x; const u32 idmacu = (u64)virt_to_phys(cur_idmac) >> 32; @@ -277,7 +276,7 @@ static int dwmci_data_transfer(struct dwmci_host *host, struct mmc_data *data) for (;;) { mask = dwmci_readl(host, DWMCI_RINTSTS); - /* Error during data transfer. */ + /* Error during data transfer */ if (mask & (DWMCI_DATA_ERR | DWMCI_DATA_TOUT)) { debug("%s: DATA ERROR!\n", __func__); ret = -EINVAL; @@ -286,16 +285,15 @@ static int dwmci_data_transfer(struct dwmci_host *host, struct mmc_data *data) ret = dwmci_data_transfer_fifo(host, data, mask); - /* Data arrived correctly. */ + /* Data arrived correctly */ if (mask & DWMCI_INTMSK_DTO) { ret = 0; break; } - /* Check for timeout. */ + /* Check for timeout */ if (get_timer(start) > timeout) { - debug("%s: Timeout waiting for data!\n", - __func__); + debug("%s: Timeout waiting for data!\n", __func__); ret = -ETIMEDOUT; break; } @@ -317,8 +315,8 @@ static int dwmci_dma_transfer(struct dwmci_host *host, uint flags, else mask = DWMCI_IDINTEN_TI; - ret = wait_for_bit_le32(host->ioaddr + host->regs->idsts, - mask, true, 1000, false); + ret = wait_for_bit_le32(host->ioaddr + host->regs->idsts, mask, true, + 1000, false); if (ret) debug("%s: DWMCI_IDINTEN mask 0x%x timeout\n", __func__, mask); @@ -334,7 +332,7 @@ static int dwmci_dma_transfer(struct dwmci_host *host, uint flags, } static int dwmci_set_transfer_mode(struct dwmci_host *host, - struct mmc_data *data) + struct mmc_data *data) { unsigned long mode; @@ -380,12 +378,12 @@ static int dwmci_send_cmd_common(struct dwmci_host *host, struct mmc_cmd *cmd, } else { if (data->flags == MMC_DATA_READ) { ret = bounce_buffer_start(&bbstate, - (void*)data->dest, + (void *)data->dest, data->blocksize * data->blocks, GEN_BB_WRITE); } else { ret = bounce_buffer_start(&bbstate, - (void*)data->src, + (void *)data->src, data->blocksize * data->blocks, GEN_BB_READ); } @@ -420,9 +418,9 @@ static int dwmci_send_cmd_common(struct dwmci_host *host, struct mmc_cmd *cmd, if (cmd->resp_type & MMC_RSP_CRC) flags |= DWMCI_CMD_CHECK_CRC; - flags |= (cmd->cmdidx | DWMCI_CMD_START | DWMCI_CMD_USE_HOLD_REG); + flags |= cmd->cmdidx | DWMCI_CMD_START | DWMCI_CMD_USE_HOLD_REG; - debug("Sending CMD%d\n",cmd->cmdidx); + debug("Sending CMD%d\n", cmd->cmdidx); dwmci_w
[PATCH 17/42] dt-bindings: exynos: Update bindings doc for DW MMC controller
Update the bindings doc for Exynos DW MMC block to follow the upstream example and reflect the latest changes made in corresponding Linux kernel bindings. Signed-off-by: Sam Protsenko --- doc/device-tree-bindings/exynos/dwmmc.txt | 46 +-- 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/doc/device-tree-bindings/exynos/dwmmc.txt b/doc/device-tree-bindings/exynos/dwmmc.txt index 694d1959162c..d90792be8599 100644 --- a/doc/device-tree-bindings/exynos/dwmmc.txt +++ b/doc/device-tree-bindings/exynos/dwmmc.txt @@ -12,7 +12,9 @@ SOC specific and Board specific properties are channel specific. Required SoC Specific Properties: - compatible: should be - - samsung,exynos-dwmmc: for exynos platforms + - samsung,exynos4412-dw-mshc: for Exynos4 platforms + - samsung,exynos-dwmmc: for Exynos5 platforms + - samsung,exynos7-dw-mshc-smu: for Exynos7 platforms (with SMU block) - reg: physical base address of the controller and length of memory mapped region. @@ -23,32 +25,38 @@ Required Board Specific Properties: - #address-cells: should be 1. - #size-cells: should be 0. -- samsung,bus-width: The width of the bus used to interface the devices +- bus-width: The width of the bus used to interface the devices supported by DWC_mobile_storage (SD-MMC/EMMC/SDIO). . Typically the bus width is 4 or 8. -- samsung,timing: The timing values to be written into the - Drv/sample clock selection register of corresponding channel. - . It is comprised of 3 values corresponding to the 3 fileds - 'SelClk_sample', 'SelClk_drv' and 'DIVRATIO' of CLKSEL register. - . SelClk_sample: Select sample clock among 8 shifted clocks. - . SelClk_drv: Select drv clock among 8 shifted clocks. - . DIVRATIO: Clock Divide ratio select. - . The above 3 values are used by the clock phase shifter. +- samsung,dw-mshc-ciu-div: The divider value for the card interface unit (ciu) + clock (0..7). +- samsung,dw-mshc-sdr-timing: The timing values for single data rate (SDR) mode + operation. + . First value is CIU clock phase shift value for TX mode (0..7). + . Second value is CIU clock phase shift value for RX mode (0..7). +- samsung,dw-mshc-ddr-timing: The timing values for double data rate (DDR) mode + operation. If missing, values from samsung,dw-mshc-sdr-timing are used. + . First value is CIU clock phase shift value for TX mode (0..7). + . Second value is CIU clock phase shift value for RX mode (0..7). Example: mmc@1220 { - samsung,bus-width = <8>; - samsung,timing = <1 3 3>; - samsung,removable = <1>; -} + bus-width = <8>; + non-removable; + samsung,dw-mshc-ciu-div = <3>; + samsung,dw-mshc-sdr-timing = <1 3>; + samsung,dw-mshc-ddr-timing = <0 2>; +}; + In the above example, . The bus width is 8 - . Timing is comprised of 3 values as explained below + . Divider value for CLKSEL register is 3. The CIU clock rate will be + calculated as SDCLKIN / (3 + 1). + . SDR and DDR timings are comprised of 2 values as explained below 1 - SelClk_sample 3 - SelClk_drv - 3 - DIVRATIO - . The 'removable' flag indicates whether the the particilar device + . The 'non-removable' flag indicates whether the particular device cannot be removed (always present) or it is a removable device. - 1 - Indicates that the device is removable. - 0 - Indicates that the device cannot be removed. + Flag is present - Indicates that the device cannot be removed. + Flag is not present - Indicates that the device is removable. -- 2.39.2
[PATCH 16/42] arm: dts: exynos: Add upstream DW MMC properties to all Exynos dts
Some device tree properties for DW MMC block were updated in Linux kernel. Let's follow its example and rework corresponding properties in all Exynos device trees. Don't remove outdated properties yet, it'll be done later once DW MMC driver is updated accordingly to read the updated properties instead of outdated ones. Next properties are added: * samsung,dw-mshc-ciu-div and samsung,dw-mshc-sdr-timing: They were derived from outdated samsung,timing property. * fifo-depth (generic replacement for fifoth_val): FIFO depth was calculated from fifoth_val (using expressions from FIFOTH register description in TRM): fifo-depth = ((fifoth_val >> 16) + 1) * 2 * bus-width: generic replacement for samsung,bus-width * clock-frequency: generic replacement for bus_hz * non-removable: generic replacement for samsung,removable = <0> No functional change. Signed-off-by: Sam Protsenko --- arch/arm/dts/exynos4210-origen.dts | 1 + arch/arm/dts/exynos4210-trats.dts | 2 ++ arch/arm/dts/exynos4210-universal_c210.dts | 2 ++ arch/arm/dts/exynos4412-odroid.dts | 6 ++ arch/arm/dts/exynos4412-trats2.dts | 8 arch/arm/dts/exynos5250-arndale.dts| 6 ++ arch/arm/dts/exynos5250-smdk5250.dts | 7 +++ arch/arm/dts/exynos5250-snow.dts | 7 +++ arch/arm/dts/exynos5250-spring.dts | 4 arch/arm/dts/exynos5420-smdk5420.dts | 7 +++ arch/arm/dts/exynos5422-odroidxu3.dts | 2 ++ arch/arm/dts/exynos54xx.dtsi | 7 +++ 12 files changed, 59 insertions(+) diff --git a/arch/arm/dts/exynos4210-origen.dts b/arch/arm/dts/exynos4210-origen.dts index 65a5fcd67eff..a4915de2c49c 100644 --- a/arch/arm/dts/exynos4210-origen.dts +++ b/arch/arm/dts/exynos4210-origen.dts @@ -26,6 +26,7 @@ &sdhci2 { samsung,bus-width = <4>; + bus-width = <4>; samsung,timing = <1 2 3>; cd-gpios = <&gpk2 2 0>; status = "okay"; diff --git a/arch/arm/dts/exynos4210-trats.dts b/arch/arm/dts/exynos4210-trats.dts index 05989ee97e5b..4fbdf4730994 100644 --- a/arch/arm/dts/exynos4210-trats.dts +++ b/arch/arm/dts/exynos4210-trats.dts @@ -241,6 +241,7 @@ &sdhci0 { samsung,bus-width = <8>; + bus-width = <8>; samsung,timing = <1 3 3>; pwr-gpios = <&gpk0 2 0>; status = "okay"; @@ -248,6 +249,7 @@ &sdhci2 { samsung,bus-width = <4>; + bus-width = <4>; samsung,timing = <1 2 3>; cd-gpios = <&gpx3 4 0>; status = "okay"; diff --git a/arch/arm/dts/exynos4210-universal_c210.dts b/arch/arm/dts/exynos4210-universal_c210.dts index 610a8ad2e71e..1b3ac1fee15f 100644 --- a/arch/arm/dts/exynos4210-universal_c210.dts +++ b/arch/arm/dts/exynos4210-universal_c210.dts @@ -236,6 +236,7 @@ &sdhci0 { samsung,bus-width = <8>; + bus-width = <8>; samsung,timing = <1 3 3>; pwr-gpios = <&gpk0 2 0>; status = "okay"; @@ -243,6 +244,7 @@ &sdhci2 { samsung,bus-width = <4>; + bus-width = <4>; samsung,timing = <1 2 3>; cd-gpios = <&gpx3 4 0>; status = "okay"; diff --git a/arch/arm/dts/exynos4412-odroid.dts b/arch/arm/dts/exynos4412-odroid.dts index ce08e8dc1ebb..24e96ed05868 100644 --- a/arch/arm/dts/exynos4412-odroid.dts +++ b/arch/arm/dts/exynos4412-odroid.dts @@ -243,9 +243,15 @@ &mshc_0 { samsung,bus-width = <8>; + bus-width = <8>; samsung,timing = <2 1 0>; + samsung,dw-mshc-ciu-div = <0>; + samsung,dw-mshc-sdr-timing = <2 1>; samsung,removable = <0>; + non-removable; fifoth_val = <0x203f0040>; + fifo-depth = <0x80>; + clock-frequency = <4>; bus_hz = <4>; div = <0x3>; index = <4>; diff --git a/arch/arm/dts/exynos4412-trats2.dts b/arch/arm/dts/exynos4412-trats2.dts index c4db137e01f6..30758ffa1ef9 100644 --- a/arch/arm/dts/exynos4412-trats2.dts +++ b/arch/arm/dts/exynos4412-trats2.dts @@ -109,6 +109,7 @@ sdhci@1251 { samsung,bus-width = <8>; + bus-width = <8>; samsung,timing = <1 3 3>; pwr-gpios = <&gpk0 4 0>; status = "disabled"; @@ -432,6 +433,7 @@ &sdhci0 { samsung,bus-width = <8>; + bus-width = <8>; samsung,timing = <1 3 3>; pwr-gpios = <&gpk0 4 0>; status = "disabled"; @@ -439,6 +441,7 @@ &sdhci2 { samsung,bus-width = <4>; + bus-width = <4>; samsung,timing = <1 2 3>; cd-gpios = <&gpk2 2 0>; status = "okay"; @@ -446,9 +449,14 @@ &mshc_0 { samsung,bus-width = <8>; + bus-width = <8>; samsung,timing = <2 1 0>; + samsung,dw-mshc-ciu-div = <0>; + samsung,dw-mshc-sdr-timing = <2 1>; samsung,removable = <0>; + non-removable; fifoth_val = <0x203f0040>; + clock-frequency = <4>; bus_hz = <4>; div
[PATCH 12/42] mmc: dw_mmc: Replace fifoth_val property with fifo-depth
Replace fifoth_val property with its fifo-depth counterpart in all DW MMC drivers. fifo-depth is a common property used in upstream Linux kernel. The FIFOTH register value will be calculated using fifo-depth value in DW MMC core (dw_mmc.c). This change reduces code duplication in platform drivers, and pulls common FIFOTH register value calculation into core dw_mmc driver where it belongs. No functional change. Signed-off-by: Sam Protsenko --- drivers/mmc/dw_mmc.c | 21 + drivers/mmc/exynos_dw_mmc.c | 10 +- drivers/mmc/ftsdc010_mci.h| 1 - drivers/mmc/hi6220_dw_mmc.c | 7 +++ drivers/mmc/nexell_dw_mmc.c | 5 + drivers/mmc/rockchip_dw_mmc.c | 5 + drivers/mmc/snps_dw_mmc.c | 6 ++ drivers/mmc/socfpga_dw_mmc.c | 4 ++-- include/dwmmc.h | 4 ++-- 9 files changed, 29 insertions(+), 34 deletions(-) diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c index 32e0e730c77b..a1f06931b7ac 100644 --- a/drivers/mmc/dw_mmc.c +++ b/drivers/mmc/dw_mmc.c @@ -218,8 +218,6 @@ static unsigned int dwmci_get_timeout(struct mmc *mmc, const unsigned int size) static int dwmci_data_transfer_fifo(struct dwmci_host *host, struct mmc_data *data, u32 mask) { - const u32 fifo_depth = (((host->fifoth_val & RX_WMARK_MASK) >> -RX_WMARK_SHIFT) + 1) * 2; const u32 int_rx = mask & (DWMCI_INTMSK_RXDR | DWMCI_INTMSK_DTO); const u32 int_tx = mask & DWMCI_INTMSK_TXDR; int ret = 0; @@ -254,8 +252,8 @@ static int dwmci_data_transfer_fifo(struct dwmci_host *host, if (ret < 0) break; - len = fifo_depth - ((len >> DWMCI_FIFO_SHIFT) & - DWMCI_FIFO_MASK); + len = host->fifo_depth - ((len >> DWMCI_FIFO_SHIFT) & + DWMCI_FIFO_MASK); len = min(size, len); for (i = 0; i < len; i++) dwmci_writel(host, DWMCI_DATA, *buf++); @@ -643,16 +641,23 @@ static int dwmci_set_ios(struct mmc *mmc) static void dwmci_init_fifo(struct dwmci_host *host) { - if (!host->fifoth_val) { + u32 fifo_thr, fifoth_val; + + if (!host->fifo_depth) { u32 fifo_size; + /* +* Automatically detect FIFO depth from FIFOTH register. +* Power-on value of RX_WMark is FIFO_DEPTH-1. +*/ fifo_size = dwmci_readl(host, DWMCI_FIFOTH); fifo_size = ((fifo_size & RX_WMARK_MASK) >> RX_WMARK_SHIFT) + 1; - host->fifoth_val = MSIZE(0x2) | RX_WMARK(fifo_size / 2 - 1) | - TX_WMARK(fifo_size / 2); + host->fifo_depth = fifo_size; } - dwmci_writel(host, DWMCI_FIFOTH, host->fifoth_val); + fifo_thr = host->fifo_depth / 2; + fifoth_val = MSIZE(0x2) | RX_WMARK(fifo_thr - 1) | TX_WMARK(fifo_thr); + dwmci_writel(host, DWMCI_FIFOTH, fifoth_val); } static void dwmci_init_dma(struct dwmci_host *host) diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c index 2f849c43b129..14cb0c05cb55 100644 --- a/drivers/mmc/exynos_dw_mmc.c +++ b/drivers/mmc/exynos_dw_mmc.c @@ -151,8 +151,8 @@ static int do_dwmci_init(struct dwmci_host *host) return exynos_dwmci_core_init(host); } -static int exynos_dwmci_get_config(const void *blob, int node, - struct dwmci_host *host, +static int exynos_dwmci_get_config(struct udevice *dev, const void *blob, + int node, struct dwmci_host *host, struct dwmci_exynos_priv_data *priv) { int err = 0; @@ -201,7 +201,7 @@ static int exynos_dwmci_get_config(const void *blob, int node, priv->sdr_timing = DWMMC_MMC2_SDR_TIMING_VAL; } - host->fifoth_val = fdtdec_get_int(blob, node, "fifoth_val", 0); + host->fifo_depth = dev_read_u32_default(dev, "fifo-depth", 0); host->bus_hz = fdtdec_get_int(blob, node, "bus_hz", 0); host->div = fdtdec_get_int(blob, node, "div", 0); @@ -217,8 +217,8 @@ static int exynos_dwmmc_probe(struct udevice *dev) struct dwmci_host *host = &priv->host; int err; - err = exynos_dwmci_get_config(gd->fdt_blob, dev_of_offset(dev), host, - priv); + err = exynos_dwmci_get_config(dev, gd->fdt_blob, dev_of_offset(dev), + host, priv); if (err) return err; err = do_dwmci_init(host); diff --git a/drivers/mmc/ftsdc010_mci.h b/drivers/mmc/ftsdc010_mci.h index 782d92be2f5f..36187cfa04f6 100644 --- a/drivers/mmc/ftsdc010_mci.h +++ b/drivers/mmc/ftsdc010_mci.h @@ -28,7 +28,6 @@ struct f
[PATCH 14/42] mmc: dw_mmc: Use CONFIG_IS_ENABLED() to check config options
Use CONFIG_IS_ENABLED() macro to check config options as recommended by checkpatch, instead of checking those with just #ifdef CONFIG_... No functional change. Signed-off-by: Sam Protsenko --- drivers/mmc/dw_mmc.c | 6 +++--- include/dwmmc.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c index a1f06931b7ac..ebe239547a7d 100644 --- a/drivers/mmc/dw_mmc.c +++ b/drivers/mmc/dw_mmc.c @@ -573,7 +573,7 @@ static int dwmci_setup_bus(struct dwmci_host *host, u32 freq) return 0; } -#ifdef CONFIG_DM_MMC +#if CONFIG_IS_ENABLED(DM_MMC) static int dwmci_set_ios(struct udevice *dev) { struct mmc *mmc = mmc_get_mmc_dev(dev); @@ -713,7 +713,7 @@ static int dwmci_init(struct mmc *mmc) return 0; } -#ifdef CONFIG_DM_MMC +#if CONFIG_IS_ENABLED(DM_MMC) int dwmci_probe(struct udevice *dev) { struct mmc *mmc = mmc_get_mmc_dev(dev); @@ -738,7 +738,7 @@ void dwmci_setup_cfg(struct mmc_config *cfg, struct dwmci_host *host, u32 max_clk, u32 min_clk) { cfg->name = host->name; -#ifndef CONFIG_DM_MMC +#if !CONFIG_IS_ENABLED(DM_MMC) cfg->ops = &dwmci_ops; #endif cfg->f_min = min_clk; diff --git a/include/dwmmc.h b/include/dwmmc.h index 77c8989148a1..9252bef24329 100644 --- a/include/dwmmc.h +++ b/include/dwmmc.h @@ -268,7 +268,7 @@ static inline u8 dwmci_readb(struct dwmci_host *host, int reg) return readb(host->ioaddr + reg); } -#ifdef CONFIG_BLK +#if CONFIG_IS_ENABLED(BLK) /** * dwmci_setup_cfg() - Set up the configuration for DWMMC * @cfg: Configuration structure to fill in (generally &plat->mmc) @@ -334,7 +334,7 @@ int dwmci_bind(struct udevice *dev, struct mmc *mmc, struct mmc_config *cfg); int add_dwmci(struct dwmci_host *host, u32 max_clk, u32 min_clk); #endif /* !CONFIG_BLK */ -#ifdef CONFIG_DM_MMC +#if CONFIG_IS_ENABLED(DM_MMC) /* Export the operations to drivers */ int dwmci_probe(struct udevice *dev); extern const struct dm_mmc_ops dm_dwmci_ops; -- 2.39.2
[PATCH 13/42] mmc: dw_mmc: Fix kernel-doc comments in dwmmc.h
Rework kernel-doc comments in dwmmc.h header so it's actually possible to generate a proper documentation from it usin scripts/kernel-doc script, with no errors. No functional change. Signed-off-by: Sam Protsenko --- include/dwmmc.h | 41 ++--- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/include/dwmmc.h b/include/dwmmc.h index 7bb456e792b4..77c8989148a1 100644 --- a/include/dwmmc.h +++ b/include/dwmmc.h @@ -182,6 +182,7 @@ struct dwmci_idmac_regs { * @ioaddr:Base I/O address of controller * @quirks:Quick flags - see DWMCI_QUIRK_... * @caps: Capabilities - see MMC_MODE_... + * @clock: Current clock frequency (after internal divider), Hz * @bus_hz:Bus speed in Hz, if @get_mmc_clk() is NULL * @div: Arbitrary clock divider value for use by controller * @dev_index: Arbitrary device index for use by controller @@ -190,6 +191,10 @@ struct dwmci_idmac_regs { * @fifo_depth:Depth of FIFO, bytes (or 0 for automatic detection) * @mmc: Pointer to generic MMC structure for this device * @priv: Private pointer for use by controller + * @clksel:(Optional) Platform function to run when speed/width is changed + * @board_init:(Optional) Platform function to run on init + * @cfg: Internal MMC configuration, for !CONFIG_BLK cases + * @fifo_mode: Use FIFO mode (not DMA) to read and write data * @dma_64bit_address: Whether DMA supports 64-bit address mode or not * @regs: Registers that can vary for different DW MMC block versions */ @@ -210,9 +215,12 @@ struct dwmci_host { int (*clksel)(struct dwmci_host *host); void (*board_init)(struct dwmci_host *host); - /** -* Get / set a particular MMC clock frequency +* @get_mmc_clk: (Optional) Platform function to get/set a particular +* MMC clock frequency +* +* @host: DWMMC host +* @freq: Frequency the host is trying to achieve * * This is used to request the current clock frequency of the clock * that drives the DWMMC peripheral. The caller will then use this @@ -220,16 +228,12 @@ struct dwmci_host { * required MMC bus clock frequency. If you want to handle the * clock external to DWMMC, use @freq to select the frequency and * return that value too. Then DWMMC will put itself in bypass mode. -* -* @host: DWMMC host -* @freq: Frequency the host is trying to achieve */ unsigned int (*get_mmc_clk)(struct dwmci_host *host, uint freq); #ifndef CONFIG_BLK struct mmc_config cfg; #endif - /* use fifo mode to read and write data */ bool fifo_mode; bool dma_64bit_address; const struct dwmci_idmac_regs *regs; @@ -267,6 +271,10 @@ static inline u8 dwmci_readb(struct dwmci_host *host, int reg) #ifdef CONFIG_BLK /** * dwmci_setup_cfg() - Set up the configuration for DWMMC + * @cfg: Configuration structure to fill in (generally &plat->mmc) + * @host: DWMMC host + * @max_clk: Maximum supported clock speed in Hz (e.g. 15000) + * @min_clk: Minimum supported clock speed in Hz (e.g. 40) * * This is used to set up a DWMMC device when you are using CONFIG_BLK. * @@ -291,28 +299,23 @@ static inline u8 dwmci_readb(struct dwmci_host *host, int reg) * struct rockchip_mmc_plat *plat = dev_get_plat(dev); * * See rockchip_dw_mmc.c for an example. - * - * @cfg: Configuration structure to fill in (generally &plat->mmc) - * @host: DWMMC host - * @max_clk: Maximum supported clock speed in HZ (e.g. 15000) - * @min_clk: Minimum supported clock speed in HZ (e.g. 40) */ void dwmci_setup_cfg(struct mmc_config *cfg, struct dwmci_host *host, u32 max_clk, u32 min_clk); /** * dwmci_bind() - Set up a new MMC block device + * @dev: Device to set up + * @mmc: Pointer to mmc structure (normally &plat->mmc) + * @cfg: Empty configuration structure (generally &plat->cfg). This is + * normally all zeroes at this point. The only purpose of passing + * this in is to set mmc->cfg to it. * * This is used to set up a DWMMC block device when you are using CONFIG_BLK. * It should be called from your driver's bind() method. * * See rockchip_dw_mmc.c for an example. * - * @dev: Device to set up - * @mmc: Pointer to mmc structure (normally &plat->mmc) - * @cfg: Empty configuration structure (generally &plat->cfg). This is - * normally all zeroes at this point. The only purpose of passing - * this in is to set mmc->cfg to it. * Return: 0 if OK, -ve if the block device could not be created */ int dwmci_bind(struct udevice *dev, struct mmc *mmc, struct mmc_config *cfg); @@ -320,12 +323,12 @@ int dwmci_bind(struct udevice *dev, struct mmc *mmc, struct mmc_config *cfg); #else
[PATCH 11/42] mmc: dw_mmc: Add support for 64-bit IDMAC
Some DW MMC blocks (e.g. those on modern Exynos chips) support 64-bit DMA addressing mode. 64-bit DW MMC variants differ from their 32-bit counterparts: - the register layout is a bit different (because there are additional IDMAC registers present for storing upper part of 64-bit addresses) - DMA descriptor structure is bigger and different from 32-bit one Introduce all necessary changes to enable support for 64-bit DMA capable DW MMC blocks. Next changes were made: 1. Check which DMA address mode is supported in current IP-core version. HCON register (bit 27) indicates whether it's 32-bit or 64-bit addressing. Add boolean .dma_64bit_address field to struct dwmci_host and store the result there. dwmci_init_dma() function is introduced for doing so, which is called on driver's init. 2. Add 64-bit DMA descriptor (struct dwmci_idmac64) and use it in dwmci_prepare_desc() in case if .dma_64bit_address field is true. A new dwmci_set_idma_desc64() function was added for populating that descriptor. 3. Add registers for 64-bit DMA capable blocks. To make the access to IDMAC registers universal between 32-bit / 64-bit cases, a new struct dwmci_idmac_regs (and corresponding host->regs field) was introduced, which abstracts the hardware by being set to appropriate offset constants on init. All direct calls to IDMAC registers were correspondingly replaced by accessing host->regs. 4. Allocate and use 64-bit DMA descriptors buffer in case when IDMAC is 64-bit capable. Extract all the code (except for the IDMAC descriptors buffer allocation) from dwmci_send_cmd() to dwmci_send_cmd_common(), so that it's possible to keep IDMAC buffer (either 32-bit or 64-bit) on stack during send_cmd routine. The insights for this implementation were taken from Linux kernel DW MMC driver. Signed-off-by: Sam Protsenko --- drivers/mmc/dw_mmc.c | 152 ++- include/dwmmc.h | 39 ++- 2 files changed, 160 insertions(+), 31 deletions(-) diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c index 8e04ab39c2c5..32e0e730c77b 100644 --- a/drivers/mmc/dw_mmc.c +++ b/drivers/mmc/dw_mmc.c @@ -28,6 +28,39 @@ struct dwmci_idmac32 { u32 des3; /* Next descriptor physical address */ } __aligned(ARCH_DMA_MINALIGN); +/* Internal DMA Controller (IDMAC) descriptor for 64-bit addressing mode */ +struct dwmci_idmac64 { + u32 des0; /* Control descriptor */ + u32 des1; /* Reserved */ + u32 des2; /* Buffer sizes */ + u32 des3; /* Reserved */ + u32 des4; /* Lower 32-bits of Buffer Address Pointer 1 */ + u32 des5; /* Upper 32-bits of Buffer Address Pointer 1 */ + u32 des6; /* Lower 32-bits of Next Descriptor Address */ + u32 des7; /* Upper 32-bits of Next Descriptor Address */ +} __aligned(ARCH_DMA_MINALIGN); + +/* Register offsets for DW MMC blocks with 32-bit IDMAC */ +static const struct dwmci_idmac_regs dwmci_idmac_regs32 = { + .dbaddrl= DWMCI_DBADDR, + .idsts = DWMCI_IDSTS, + .idinten= DWMCI_IDINTEN, + .dscaddrl = DWMCI_DSCADDR, + .bufaddrl = DWMCI_BUFADDR, +}; + +/* Register offsets for DW MMC blocks with 64-bit IDMAC */ +static const struct dwmci_idmac_regs dwmci_idmac_regs64 = { + .dbaddrl= DWMCI_DBADDRL, + .dbaddru= DWMCI_DBADDRU, + .idsts = DWMCI_IDSTS64, + .idinten= DWMCI_IDINTEN64, + .dscaddrl = DWMCI_DSCADDRL, + .dscaddru = DWMCI_DSCADDRU, + .bufaddrl = DWMCI_BUFADDRL, + .bufaddru = DWMCI_BUFADDRU, +}; + static int dwmci_wait_reset(struct dwmci_host *host, u32 value) { unsigned long timeout = 1000; @@ -55,11 +88,27 @@ static void dwmci_set_idma_desc32(struct dwmci_idmac32 *desc, u32 control, desc->des3 = next_desc_phys; } -static void dwmci_prepare_desc(struct mmc_data *data, - struct dwmci_idmac32 *cur_idmac, - void *bounce_buffer) +static void dwmci_set_idma_desc64(struct dwmci_idmac64 *desc, u32 control, + u32 buf_size, u64 buf_addr) +{ + phys_addr_t desc_phys = virt_to_phys(desc); + u64 next_desc_phys = desc_phys + sizeof(struct dwmci_idmac64); + + desc->des0 = control; + desc->des1 = 0; + desc->des2 = buf_size; + desc->des3 = 0; + desc->des4 = buf_addr & 0x; + desc->des5 = buf_addr >> 32; + desc->des6 = next_desc_phys & 0x; + desc->des7 = next_desc_phys >> 32; +} + +static void dwmci_prepare_desc(struct dwmci_host *host, struct mmc_data *data, + void *cur_idmac, void *bounce_buffer) { struct dwmci_idmac32 *desc32 = cur_idmac; + struct dwmci_idmac64 *desc64 = cur_idmac; ulong da
[PATCH 10/42] mmc: dw_mmc: Improve 32-bit IDMAC descriptor namings
Prepare for adding 64-bit IDMAC descriptors by renaming current 32-bit descriptor and its fields accordingly. While at it, make use of virt_to_phys() to make it more obvious in which places the physical addresses have to be used. No functional change. Signed-off-by: Sam Protsenko --- drivers/mmc/dw_mmc.c | 43 +++ 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c index 16601cacfc00..8e04ab39c2c5 100644 --- a/drivers/mmc/dw_mmc.c +++ b/drivers/mmc/dw_mmc.c @@ -20,11 +20,12 @@ #define PAGE_SIZE 4096 -struct dwmci_idmac { - u32 flags; - u32 cnt; - u32 addr; - u32 next_addr; +/* Internal DMA Controller (IDMAC) descriptor for 32-bit addressing mode */ +struct dwmci_idmac32 { + u32 des0; /* Control descriptor */ + u32 des1; /* Buffer size */ + u32 des2; /* Buffer physical address */ + u32 des3; /* Next descriptor physical address */ } __aligned(ARCH_DMA_MINALIGN); static int dwmci_wait_reset(struct dwmci_host *host, u32 value) @@ -42,22 +43,23 @@ static int dwmci_wait_reset(struct dwmci_host *host, u32 value) return 0; } -static void dwmci_set_idma_desc(struct dwmci_idmac *idmac, - u32 desc0, u32 desc1, u32 desc2) +static void dwmci_set_idma_desc32(struct dwmci_idmac32 *desc, u32 control, + u32 buf_size, u32 buf_addr) { - struct dwmci_idmac *desc = idmac; + phys_addr_t desc_phys = virt_to_phys(desc); + u32 next_desc_phys = desc_phys + sizeof(struct dwmci_idmac32); - desc->flags = desc0; - desc->cnt = desc1; - desc->addr = desc2; - desc->next_addr = (ulong)desc + sizeof(struct dwmci_idmac); + desc->des0 = control; + desc->des1 = buf_size; + desc->des2 = buf_addr; + desc->des3 = next_desc_phys; } static void dwmci_prepare_desc(struct mmc_data *data, - struct dwmci_idmac *cur_idmac, + struct dwmci_idmac32 *cur_idmac, void *bounce_buffer) { - struct dwmci_idmac *desc = cur_idmac; + struct dwmci_idmac32 *desc32 = cur_idmac; ulong data_start, data_end; unsigned int blk_cnt, i; @@ -65,6 +67,7 @@ static void dwmci_prepare_desc(struct mmc_data *data, blk_cnt = data->blocks; for (i = 0;; i++) { + phys_addr_t buf_phys = virt_to_phys(bounce_buffer); unsigned int flags, cnt; flags = DWMCI_IDMAC_OWN | DWMCI_IDMAC_CH; @@ -76,22 +79,22 @@ static void dwmci_prepare_desc(struct mmc_data *data, } else cnt = data->blocksize * 8; - dwmci_set_idma_desc(desc, flags, cnt, - (ulong)bounce_buffer + i * PAGE_SIZE); - desc++; + dwmci_set_idma_desc32(desc32, flags, cnt, + buf_phys + i * PAGE_SIZE); + desc32++; if (blk_cnt <= 8) break; blk_cnt -= 8; } - data_end = (ulong)desc; + data_end = (ulong)desc32; flush_dcache_range(data_start, roundup(data_end, ARCH_DMA_MINALIGN)); } static void dwmci_prepare_data(struct dwmci_host *host, struct mmc_data *data, - struct dwmci_idmac *cur_idmac, + struct dwmci_idmac32 *cur_idmac, void *bounce_buffer) { unsigned long ctrl; @@ -308,7 +311,7 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, { #endif struct dwmci_host *host = mmc->priv; - ALLOC_CACHE_ALIGN_BUFFER(struct dwmci_idmac, cur_idmac, + ALLOC_CACHE_ALIGN_BUFFER(struct dwmci_idmac32, cur_idmac, data ? DIV_ROUND_UP(data->blocks, 8) : 0); int ret = 0, flags = 0, i; u32 retry = 10; -- 2.39.2
[PATCH 09/42] mmc: dw_mmc: Extract setting the DMA descriptor into a separate routine
Make dwmci_prepare_data() function easier to read by extracting the preparation of IDMAC descriptor into a dedicated function. No functional change. Signed-off-by: Sam Protsenko --- drivers/mmc/dw_mmc.c | 52 ++-- 1 file changed, 31 insertions(+), 21 deletions(-) diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c index 439f8eb3fb4c..16601cacfc00 100644 --- a/drivers/mmc/dw_mmc.c +++ b/drivers/mmc/dw_mmc.c @@ -53,47 +53,57 @@ static void dwmci_set_idma_desc(struct dwmci_idmac *idmac, desc->next_addr = (ulong)desc + sizeof(struct dwmci_idmac); } -static void dwmci_prepare_data(struct dwmci_host *host, - struct mmc_data *data, +static void dwmci_prepare_desc(struct mmc_data *data, struct dwmci_idmac *cur_idmac, void *bounce_buffer) { - unsigned long ctrl; - unsigned int i = 0, flags, cnt, blk_cnt; + struct dwmci_idmac *desc = cur_idmac; ulong data_start, data_end; + unsigned int blk_cnt, i; - + data_start = (ulong)cur_idmac; blk_cnt = data->blocks; - dwmci_wait_reset(host, DWMCI_CTRL_FIFO_RESET); + for (i = 0;; i++) { + unsigned int flags, cnt; - /* Clear IDMAC interrupt */ - dwmci_writel(host, DWMCI_IDSTS, 0x); - - data_start = (ulong)cur_idmac; - dwmci_writel(host, DWMCI_DBADDR, (ulong)cur_idmac); - - do { - flags = DWMCI_IDMAC_OWN | DWMCI_IDMAC_CH ; - flags |= (i == 0) ? DWMCI_IDMAC_FS : 0; + flags = DWMCI_IDMAC_OWN | DWMCI_IDMAC_CH; + if (i == 0) + flags |= DWMCI_IDMAC_FS; if (blk_cnt <= 8) { flags |= DWMCI_IDMAC_LD; cnt = data->blocksize * blk_cnt; } else cnt = data->blocksize * 8; - dwmci_set_idma_desc(cur_idmac, flags, cnt, - (ulong)bounce_buffer + (i * PAGE_SIZE)); + dwmci_set_idma_desc(desc, flags, cnt, + (ulong)bounce_buffer + i * PAGE_SIZE); + desc++; - cur_idmac++; if (blk_cnt <= 8) break; blk_cnt -= 8; - i++; - } while(1); + } - data_end = (ulong)cur_idmac; + data_end = (ulong)desc; flush_dcache_range(data_start, roundup(data_end, ARCH_DMA_MINALIGN)); +} + +static void dwmci_prepare_data(struct dwmci_host *host, + struct mmc_data *data, + struct dwmci_idmac *cur_idmac, + void *bounce_buffer) +{ + unsigned long ctrl; + + dwmci_wait_reset(host, DWMCI_CTRL_FIFO_RESET); + + /* Clear IDMAC interrupt */ + dwmci_writel(host, DWMCI_IDSTS, 0x); + + dwmci_writel(host, DWMCI_DBADDR, (ulong)cur_idmac); + + dwmci_prepare_desc(data, cur_idmac, bounce_buffer); ctrl = dwmci_readl(host, DWMCI_CTRL); ctrl |= DWMCI_IDMAC_EN | DWMCI_DMA_EN; -- 2.39.2
[PATCH 08/42] mmc: dw_mmc: Extract DMA transfer handling code into a separate routine
Make dwmci_send_cmd() easier to read by moving the DMA transfer handling code into a dedicated function. No functional change. Signed-off-by: Sam Protsenko --- drivers/mmc/dw_mmc.c | 51 ++-- 1 file changed, 30 insertions(+), 21 deletions(-) diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c index 144f29f09240..439f8eb3fb4c 100644 --- a/drivers/mmc/dw_mmc.c +++ b/drivers/mmc/dw_mmc.c @@ -233,6 +233,33 @@ static int dwmci_data_transfer(struct dwmci_host *host, struct mmc_data *data) return ret; } +static int dwmci_dma_transfer(struct dwmci_host *host, uint flags, + struct bounce_buffer *bbstate) +{ + int ret; + u32 mask, ctrl; + + if (flags == MMC_DATA_READ) + mask = DWMCI_IDINTEN_RI; + else + mask = DWMCI_IDINTEN_TI; + + ret = wait_for_bit_le32(host->ioaddr + DWMCI_IDSTS, + mask, true, 1000, false); + if (ret) + debug("%s: DWMCI_IDINTEN mask 0x%x timeout\n", __func__, mask); + + /* Clear interrupts */ + dwmci_writel(host, DWMCI_IDSTS, DWMCI_IDINTEN_MASK); + + ctrl = dwmci_readl(host, DWMCI_CTRL); + ctrl &= ~DWMCI_DMA_EN; + dwmci_writel(host, DWMCI_CTRL, ctrl); + + bounce_buffer_stop(bbstate); + return ret; +} + static int dwmci_set_transfer_mode(struct dwmci_host *host, struct mmc_data *data) { @@ -275,7 +302,7 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, data ? DIV_ROUND_UP(data->blocks, 8) : 0); int ret = 0, flags = 0, i; u32 retry = 10; - u32 mask, ctrl; + u32 mask; struct bounce_buffer bbstate; dwmci_wait_while_busy(host, cmd); @@ -384,26 +411,8 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, if (data) { ret = dwmci_data_transfer(host, data); - - /* only dma mode need it */ - if (!host->fifo_mode) { - if (data->flags == MMC_DATA_READ) - mask = DWMCI_IDINTEN_RI; - else - mask = DWMCI_IDINTEN_TI; - ret = wait_for_bit_le32(host->ioaddr + DWMCI_IDSTS, - mask, true, 1000, false); - if (ret) - debug("%s: DWMCI_IDINTEN mask 0x%x timeout.\n", - __func__, mask); - /* clear interrupts */ - dwmci_writel(host, DWMCI_IDSTS, DWMCI_IDINTEN_MASK); - - ctrl = dwmci_readl(host, DWMCI_CTRL); - ctrl &= ~(DWMCI_DMA_EN); - dwmci_writel(host, DWMCI_CTRL, ctrl); - bounce_buffer_stop(&bbstate); - } + if (!host->fifo_mode) + ret = dwmci_dma_transfer(host, data->flags, &bbstate); } udelay(100); -- 2.39.2
[PATCH 07/42] mmc: dw_mmc: Extract FIFO data transfer into a separate routine
FIFO data transfer is implemented as quite a massive chunk of code. Extract it into a dedicated function to make dwmci_data_transfer() easier to read and reduce the indentation level of the code. No functional change. Signed-off-by: Sam Protsenko --- drivers/mmc/dw_mmc.c | 107 +-- 1 file changed, 53 insertions(+), 54 deletions(-) diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c index 40b9b034f793..144f29f09240 100644 --- a/drivers/mmc/dw_mmc.c +++ b/drivers/mmc/dw_mmc.c @@ -140,25 +140,67 @@ static unsigned int dwmci_get_timeout(struct mmc *mmc, const unsigned int size) return timeout; } -static int dwmci_data_transfer(struct dwmci_host *host, struct mmc_data *data) +static int dwmci_data_transfer_fifo(struct dwmci_host *host, + struct mmc_data *data, u32 mask) { - struct mmc *mmc = host->mmc; + const u32 fifo_depth = (((host->fifoth_val & RX_WMARK_MASK) >> +RX_WMARK_SHIFT) + 1) * 2; + const u32 int_rx = mask & (DWMCI_INTMSK_RXDR | DWMCI_INTMSK_DTO); + const u32 int_tx = mask & DWMCI_INTMSK_TXDR; int ret = 0; - u32 timeout, mask, size, i, len = 0; - u32 *buf = NULL; - ulong start = get_timer(0); - u32 fifo_depth = (((host->fifoth_val & RX_WMARK_MASK) >> - RX_WMARK_SHIFT) + 1) * 2; + u32 len = 0, size, i; + u32 *buf; + + size = (data->blocksize * data->blocks) / 4; + if (!host->fifo_mode || !size) + return 0; - size = data->blocksize * data->blocks; if (data->flags == MMC_DATA_READ) buf = (unsigned int *)data->dest; else buf = (unsigned int *)data->src; - timeout = dwmci_get_timeout(mmc, size); + if (data->flags == MMC_DATA_READ && int_rx) { + dwmci_writel(host, DWMCI_RINTSTS, int_rx); + while (size) { + ret = dwmci_fifo_ready(host, DWMCI_FIFO_EMPTY, &len); + if (ret < 0) + break; + + len = (len >> DWMCI_FIFO_SHIFT) & DWMCI_FIFO_MASK; + len = min(size, len); + for (i = 0; i < len; i++) + *buf++ = dwmci_readl(host, DWMCI_DATA); + size = size > len ? (size - len) : 0; + } + } else if (data->flags == MMC_DATA_WRITE && int_tx) { + while (size) { + ret = dwmci_fifo_ready(host, DWMCI_FIFO_FULL, &len); + if (ret < 0) + break; + + len = fifo_depth - ((len >> DWMCI_FIFO_SHIFT) & + DWMCI_FIFO_MASK); + len = min(size, len); + for (i = 0; i < len; i++) + dwmci_writel(host, DWMCI_DATA, *buf++); + size = size > len ? (size - len) : 0; + } + dwmci_writel(host, DWMCI_RINTSTS, DWMCI_INTMSK_TXDR); + } - size /= 4; + return ret; +} + +static int dwmci_data_transfer(struct dwmci_host *host, struct mmc_data *data) +{ + struct mmc *mmc = host->mmc; + int ret = 0; + u32 timeout, mask, size; + ulong start = get_timer(0); + + size = data->blocksize * data->blocks; + timeout = dwmci_get_timeout(mmc, size); for (;;) { mask = dwmci_readl(host, DWMCI_RINTSTS); @@ -169,50 +211,7 @@ static int dwmci_data_transfer(struct dwmci_host *host, struct mmc_data *data) break; } - if (host->fifo_mode && size) { - len = 0; - if (data->flags == MMC_DATA_READ && - (mask & (DWMCI_INTMSK_RXDR | DWMCI_INTMSK_DTO))) { - dwmci_writel(host, DWMCI_RINTSTS, -mask & (DWMCI_INTMSK_RXDR | -DWMCI_INTMSK_DTO)); - while (size) { - ret = dwmci_fifo_ready(host, - DWMCI_FIFO_EMPTY, - &len); - if (ret < 0) - break; - - len = (len >> DWMCI_FIFO_SHIFT) & - DWMCI_FIFO_MASK; - len = min(size, len); - for (i = 0; i < len; i++) - *buf++ = - dwmci_readl(host, DWMCI_DATA); - size =
[PATCH 06/42] mmc: dw_mmc: Extract clock on/off code into a separate routine
Extract clock control code into a separate routine to avoid code duplication in dwmci_setup_bus(). No functional change. Signed-off-by: Sam Protsenko --- drivers/mmc/dw_mmc.c | 60 1 file changed, 33 insertions(+), 27 deletions(-) diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c index cbfb8d3b8683..40b9b034f793 100644 --- a/drivers/mmc/dw_mmc.c +++ b/drivers/mmc/dw_mmc.c @@ -412,11 +412,33 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, return ret; } -static int dwmci_setup_bus(struct dwmci_host *host, u32 freq) +static int dwmci_control_clken(struct dwmci_host *host, bool on) { - u32 div, status; + const u32 val = on ? DWMCI_CLKEN_ENABLE | DWMCI_CLKEN_LOW_PWR : 0; + const u32 cmd_only_clk = DWMCI_CMD_PRV_DAT_WAIT | DWMCI_CMD_UPD_CLK; int timeout = 1; + u32 status; + + dwmci_writel(host, DWMCI_CLKENA, val); + + /* Inform CIU */ + dwmci_writel(host, DWMCI_CMD, DWMCI_CMD_START | cmd_only_clk); + do { + status = dwmci_readl(host, DWMCI_CMD); + if (timeout-- < 0) { + debug("%s: Timeout!\n", __func__); + return -ETIMEDOUT; + } + } while (status & DWMCI_CMD_START); + + return 0; +} + +static int dwmci_setup_bus(struct dwmci_host *host, u32 freq) +{ + u32 div; unsigned long sclk; + int ret; if ((freq == host->clock) || (freq == 0)) return 0; @@ -439,35 +461,19 @@ static int dwmci_setup_bus(struct dwmci_host *host, u32 freq) else div = DIV_ROUND_UP(sclk, 2 * freq); - dwmci_writel(host, DWMCI_CLKENA, 0); + /* Disable clock */ dwmci_writel(host, DWMCI_CLKSRC, 0); + ret = dwmci_control_clken(host, false); + if (ret) + return ret; + /* Set clock to desired speed */ dwmci_writel(host, DWMCI_CLKDIV, div); - dwmci_writel(host, DWMCI_CMD, DWMCI_CMD_PRV_DAT_WAIT | - DWMCI_CMD_UPD_CLK | DWMCI_CMD_START); - do { - status = dwmci_readl(host, DWMCI_CMD); - if (timeout-- < 0) { - debug("%s: Timeout!\n", __func__); - return -ETIMEDOUT; - } - } while (status & DWMCI_CMD_START); - - dwmci_writel(host, DWMCI_CLKENA, DWMCI_CLKEN_ENABLE | - DWMCI_CLKEN_LOW_PWR); - - dwmci_writel(host, DWMCI_CMD, DWMCI_CMD_PRV_DAT_WAIT | - DWMCI_CMD_UPD_CLK | DWMCI_CMD_START); - - timeout = 1; - do { - status = dwmci_readl(host, DWMCI_CMD); - if (timeout-- < 0) { - debug("%s: Timeout!\n", __func__); - return -ETIMEDOUT; - } - } while (status & DWMCI_CMD_START); + /* Enable clock */ + ret = dwmci_control_clken(host, true); + if (ret) + return ret; host->clock = freq; -- 2.39.2
[PATCH 05/42] mmc: dw_mmc: Extract FIFO init into a separate routine
Move FIFO threshold initialization into a separate function to make dwmci_init() more readable. No functional change. Signed-off-by: Sam Protsenko --- drivers/mmc/dw_mmc.c | 25 +++-- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c index a82f6a96db39..cbfb8d3b8683 100644 --- a/drivers/mmc/dw_mmc.c +++ b/drivers/mmc/dw_mmc.c @@ -540,6 +540,20 @@ static int dwmci_set_ios(struct mmc *mmc) return 0; } +static void dwmci_init_fifo(struct dwmci_host *host) +{ + if (!host->fifoth_val) { + u32 fifo_size; + + fifo_size = dwmci_readl(host, DWMCI_FIFOTH); + fifo_size = ((fifo_size & RX_WMARK_MASK) >> RX_WMARK_SHIFT) + 1; + host->fifoth_val = MSIZE(0x2) | RX_WMARK(fifo_size / 2 - 1) | + TX_WMARK(fifo_size / 2); + } + + dwmci_writel(host, DWMCI_FIFOTH, host->fifoth_val); +} + static int dwmci_init(struct mmc *mmc) { struct dwmci_host *host = mmc->priv; @@ -564,16 +578,7 @@ static int dwmci_init(struct mmc *mmc) dwmci_writel(host, DWMCI_IDINTEN, 0); dwmci_writel(host, DWMCI_BMOD, 1); - - if (!host->fifoth_val) { - uint32_t fifo_size; - - fifo_size = dwmci_readl(host, DWMCI_FIFOTH); - fifo_size = ((fifo_size & RX_WMARK_MASK) >> RX_WMARK_SHIFT) + 1; - host->fifoth_val = MSIZE(0x2) | RX_WMARK(fifo_size / 2 - 1) | - TX_WMARK(fifo_size / 2); - } - dwmci_writel(host, DWMCI_FIFOTH, host->fifoth_val); + dwmci_init_fifo(host); dwmci_writel(host, DWMCI_CLKENA, 0); dwmci_writel(host, DWMCI_CLKSRC, 0); -- 2.39.2
[PATCH 04/42] mmc: dw_mmc: Extract waiting for data busy into a separate routine
Waiting for data busy is a logically separate operation and should be implemented as a separate routine. Follow Linux kernel example and extract it from dwmci_send_cmd(). This way it doesn't clutter dwmci_send_cmd() function, and can be reused later in other cases. No functional change. Signed-off-by: Sam Protsenko --- drivers/mmc/dw_mmc.c | 25 - 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c index 9d668b3d8813..a82f6a96db39 100644 --- a/drivers/mmc/dw_mmc.c +++ b/drivers/mmc/dw_mmc.c @@ -246,6 +246,21 @@ static int dwmci_set_transfer_mode(struct dwmci_host *host, return mode; } +static void dwmci_wait_while_busy(struct dwmci_host *host, struct mmc_cmd *cmd) +{ + unsigned int timeout = 500; /* msec */ + ulong start; + + start = get_timer(0); + while (dwmci_readl(host, DWMCI_STATUS) & DWMCI_BUSY) { + if (get_timer(start) > timeout) { + debug("%s: Timeout on data busy, continue anyway\n", + __func__); + break; + } + } +} + #ifdef CONFIG_DM_MMC static int dwmci_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, struct mmc_data *data) @@ -260,19 +275,11 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, ALLOC_CACHE_ALIGN_BUFFER(struct dwmci_idmac, cur_idmac, data ? DIV_ROUND_UP(data->blocks, 8) : 0); int ret = 0, flags = 0, i; - unsigned int timeout = 500; u32 retry = 10; u32 mask, ctrl; - ulong start = get_timer(0); struct bounce_buffer bbstate; - while (dwmci_readl(host, DWMCI_STATUS) & DWMCI_BUSY) { - if (get_timer(start) > timeout) { - debug("%s: Timeout on data busy, continue anyway\n", __func__); - break; - } - } - + dwmci_wait_while_busy(host, cmd); dwmci_writel(host, DWMCI_RINTSTS, DWMCI_INTMSK_ALL); if (data) { -- 2.39.2
[PATCH 03/42] mmc: dw_mmc: Move struct idmac to dw_mmc.c
struct idmac is only used in dw_mmc.c, so move it there from dwmmc.h to avoid cluttering the interface in the header. No functional change. Signed-off-by: Sam Protsenko --- drivers/mmc/dw_mmc.c | 7 +++ include/dwmmc.h | 7 --- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c index e6107c770fe3..9d668b3d8813 100644 --- a/drivers/mmc/dw_mmc.c +++ b/drivers/mmc/dw_mmc.c @@ -20,6 +20,13 @@ #define PAGE_SIZE 4096 +struct dwmci_idmac { + u32 flags; + u32 cnt; + u32 addr; + u32 next_addr; +} __aligned(ARCH_DMA_MINALIGN); + static int dwmci_wait_reset(struct dwmci_host *host, u32 value) { unsigned long timeout = 1000; diff --git a/include/dwmmc.h b/include/dwmmc.h index 39024fb38aaa..7e4acf096dce 100644 --- a/include/dwmmc.h +++ b/include/dwmmc.h @@ -198,13 +198,6 @@ struct dwmci_host { bool fifo_mode; }; -struct dwmci_idmac { - u32 flags; - u32 cnt; - u32 addr; - u32 next_addr; -} __aligned(ARCH_DMA_MINALIGN); - static inline void dwmci_writel(struct dwmci_host *host, int reg, u32 val) { writel(val, host->ioaddr + reg); -- 2.39.2
[PATCH 02/42] mmc: dw_mmc: Remove unused version field from struct dwmci_host
Nobody seems to use it, so just remove it. No functional change. Signed-off-by: Sam Protsenko --- include/dwmmc.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/dwmmc.h b/include/dwmmc.h index 136a95b8cdb6..39024fb38aaa 100644 --- a/include/dwmmc.h +++ b/include/dwmmc.h @@ -163,7 +163,6 @@ struct dwmci_host { void *ioaddr; unsigned int quirks; unsigned int caps; - unsigned int version; unsigned int clock; unsigned int bus_hz; unsigned int div; -- 2.39.2
[PATCH 01/42] mmc: dw_mmc: Remove common.h
common.h header is marked for removal treewide and shouldn't be used. Remove it from DW MMC driver. No functional change. Signed-off-by: Sam Protsenko --- drivers/mmc/dw_mmc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c index e1036641452a..e6107c770fe3 100644 --- a/drivers/mmc/dw_mmc.c +++ b/drivers/mmc/dw_mmc.c @@ -6,7 +6,6 @@ */ #include -#include #include #include #include -- 2.39.2
[PATCH 00/42] mmc: dw_mmc: Enable eMMC on E850-96 board
Bring 64-bit support to dw_mmc core and Exynos dw_mmc drivers, and enable it on E850-96 board. Additionally do some related cleanups and device tree updates. 64-bit version of DesignWare MMC can be often found on modern ARM64 chips. It's different from its older 32-bit version (which is already implemented in U-Boot): some new registers were added, existing register addresses are changed, DMA descriptor table is different, etc. Exynos DW MMC driver was updated too: ARM64 Exynos chips implement their clock drivers using CCF framework, pinmux configuration is done at startup in DM capable pinctrl drivers, device tree properties were changed w.r.t. their upstream (Linux kernel) counterparts. CLKSEL register address is also different on 64-bit Exynos platforms. The patch series was tested on E850-96 board by running mainline Linux kernel with Debian rootfs from eMMC ("boot" partition) with these commands: 8<>8 env set fdtaddr 0x8a00 env set bootaddr 0x9400 env set boot_kerneladdr 0x94000800 part start mmc 0 boot boot_start part size mmc 0 boot boot_size mmc read $bootaddr $boot_start $boot_size abootimg addr $bootaddr abootimg get dtb --index=0 dtb_start dtb_size cp.b $dtb_start $fdtaddr $dtb_size fdt addr $fdtaddr 0x10 cp.b $boot_kerneladdr $loadaddr 200 env set bootargs console=ttySAC0,115200n8 printk.devkmsg=on \ root=/dev/mmcblk0p12 rootwait rw booti $loadaddr - $fdtaddr 8<>8 For E850-96 eMMC to function properly in DDR mode, the pending patch [1] has to be applied. Otherwise it won't be possible for exynos_dw_mmc driver to change CIU clock rate from 200 MHz up to 400 MHz, and MMC will fall back to SDR mode, which makes eMMC throughput twice as slower. With patch [1] applied, 'mmc info' reports this: Bus Speed: 5200 Mode: MMC DDR52 (52MHz) and 'clk dump' shows CIU clock rate to be ~400 MHz (after first mmc operation, e.g. 'part start' or 'mmc read'): 39975gout_mmc_embd_sdclkin Which makes sense, because dw_mmc requests to set CCLKIN = 52 MHz (with DDR/8-bit mode), and exynos_dw_mmc tries to set CIU clock rate to: SDCLKIN = 2 * ciu_div * CCLKIN = 2 * 4 * 52 MHz = 416 MHz, and the closest possible value the clock driver can set is 399.75 MHz, which works just fine. For Exynos4 and Exynos5 (ARM32) boards, this patch series was only build tested (manually and with buildman). The build is clean (no errors or warnings), but I don't have any Exynos4/Exynos5 boards at my disposal, so I can't actually verify MMC operation there. [1] https://lists.denx.de/pipermail/u-boot/2024-March/547719.html Sam Protsenko (42): mmc: dw_mmc: Remove common.h mmc: dw_mmc: Remove unused version field from struct dwmci_host mmc: dw_mmc: Move struct idmac to dw_mmc.c mmc: dw_mmc: Extract waiting for data busy into a separate routine mmc: dw_mmc: Extract FIFO init into a separate routine mmc: dw_mmc: Extract clock on/off code into a separate routine mmc: dw_mmc: Extract FIFO data transfer into a separate routine mmc: dw_mmc: Extract DMA transfer handling code into a separate routine mmc: dw_mmc: Extract setting the DMA descriptor into a separate routine mmc: dw_mmc: Improve 32-bit IDMAC descriptor namings mmc: dw_mmc: Add support for 64-bit IDMAC mmc: dw_mmc: Replace fifoth_val property with fifo-depth mmc: dw_mmc: Fix kernel-doc comments in dwmmc.h mmc: dw_mmc: Use CONFIG_IS_ENABLED() to check config options mmc: dw_mmc: Improve coding style arm: dts: exynos: Add upstream DW MMC properties to all Exynos dts dt-bindings: exynos: Update bindings doc for DW MMC controller arm: exynos: Add header guard for dwmmc.h mmc: exynos_dw_mmc: Fix obtaining the base address of controller mmc: exynos_dw_mmc: Fix getting private data in exynos_dwmci_board_init() mmc: exynos_dw_mmc: Don't call pinmux functions on ARM64 chips mmc: exynos_dw_mmc: Obtain and use CIU clock via CCF API mmc: exynos_dw_mmc: Use .of_to_plat for device tree parsing mmc: exynos_dw_mmc: Convert to use livetree API mmc: exynos_dw_mmc: Read upstream SDR timing properties mmc: exynos_dw_mmc: Abstract CLKSEL register mmc: exynos_dw_mmc: Refactor fixed CIU clock divider mmc: exynos_dw_mmc: Read common bus-width property mmc: exynos_dw_mmc: Read common clock-frequency property mmc: exynos_dw_mmc: Move quirks from struct dwmci_host to chip data mmc: exynos_dw_mmc: Read and use DDR timing when available mmc: exynos_dw_mmc: Set requested freq in get_mmc_clk() callback mmc: exynos_dw_mmc: Add support for ARM64 Exynos chips mmc: exynos_dw_mmc: Remove common.h mmc: exynos_dw_mmc: Use CONFIG_IS_ENABLED() to check config options mmc: exynos_dw_mmc: Pull all init code into probe function mmc: exynos_dw_mmc: Don't call dwmci_setup_cfg() after add_dwmci() mmc: exynos_dw_mmc: Use dev->name as driver's di
Re: [PATCH 10/15] test: dm: dsa, eth: disable tests when CONFIG_NET_LWIP=y
On Wed, May 22, 2024 at 06:00:10PM +0200, Jerome Forissier wrote: > Some sandbox tests make strong assumptions on how the network stack is > implemented. For example, the ping tests assume that ARP resolution > occurs upon sending out the ICMP packet. This is not always the case > with the lwIP stack which can cache ARP information. > Therefore, disable these tests when CONFIG_NET_LWIP is enabled. > > Signed-off-by: Jerome Forissier > --- > test/dm/dsa.c | 2 ++ > test/dm/eth.c | 4 > 2 files changed, 6 insertions(+) > > diff --git a/test/dm/dsa.c b/test/dm/dsa.c > index c857106eaf..147e2a4afe 100644 > --- a/test/dm/dsa.c > +++ b/test/dm/dsa.c > @@ -59,6 +59,7 @@ static int dm_test_dsa_probe(struct unit_test_state *uts) > > DM_TEST(dm_test_dsa_probe, UT_TESTF_SCAN_FDT); > > +#if !defined(CONFIG_NET_LWIP) > /* This test sends ping requests with the local address through each DSA port > * via the sandbox DSA master Eth. > */ > @@ -80,3 +81,4 @@ static int dm_test_dsa(struct unit_test_state *uts) > } > > DM_TEST(dm_test_dsa, UT_TESTF_SCAN_FDT); > +#endif /* !defined(CONFIG_NET_LWIP) */ > diff --git a/test/dm/eth.c b/test/dm/eth.c > index bb3dcc6b95..cf97b1c1ab 100644 > --- a/test/dm/eth.c > +++ b/test/dm/eth.c > @@ -170,6 +170,7 @@ static int dm_test_ip6_make_lladdr(struct unit_test_state > *uts) > DM_TEST(dm_test_ip6_make_lladdr, UT_TESTF_SCAN_FDT); > #endif > > +#if !defined(CONFIG_NET_LWIP) > static int dm_test_eth(struct unit_test_state *uts) > { > net_ping_ip = string_to_ip("1.1.2.2"); > @@ -298,6 +299,7 @@ static int dm_test_eth_act(struct unit_test_state *uts) > return 0; > } > DM_TEST(dm_test_eth_act, UT_TESTF_SCAN_FDT); > +#endif /* !CONFIG_NET_LWIP */ > > /* Ensure that all addresses are loaded properly */ > static int dm_test_ethaddr(struct unit_test_state *uts) > @@ -332,6 +334,7 @@ static int dm_test_ethaddr(struct unit_test_state *uts) > } > DM_TEST(dm_test_ethaddr, UT_TESTF_SCAN_FDT); > > +#if !defined(CONFIG_NET_LWIP) > /* The asserts include a return on fail; cleanup in the caller */ > static int _dm_test_eth_rotate1(struct unit_test_state *uts) > { > @@ -616,6 +619,7 @@ static int dm_test_eth_async_ping_reply(struct > unit_test_state *uts) > } > > DM_TEST(dm_test_eth_async_ping_reply, UT_TESTF_SCAN_FDT); > +#endif /* !CONFIG_NET_LWIP */ > > #if IS_ENABLED(CONFIG_IPV6_ROUTER_DISCOVERY) This seems like a lot of test disabling to me. And since a medium term goal would be to then drop the old network stack, a more nuanced approach is needed here. If not if/else'ing within the test, rewriting tests to cover the concept being tested needs to be done I think. -- Tom signature.asc Description: PGP signature
Re: [PATCH 1/7] arm: mach-k3: am62a_qos: Move common bit MACROS to k3_qos header file
On Wed, May 22, 2024 at 10:21:28AM -0500, Andrew Davis wrote: > On 5/22/24 6:37 AM, Jayesh Choudhary wrote: > > QoS bit mapping are common across all K3 SoCs so move those defines > > to common header file (k3_qos.h). > > This ensures that we do not define these for each SoC. > > > > Signed-off-by: Jayesh Choudhary > > --- > > arch/arm/mach-k3/include/mach/k3-qos.h | 74 ++ > > arch/arm/mach-k3/r5/am62ax/am62a_qos.h | 74 -- > > 2 files changed, 74 insertions(+), 74 deletions(-) > > > > diff --git a/arch/arm/mach-k3/include/mach/k3-qos.h > > b/arch/arm/mach-k3/include/mach/k3-qos.h > > index e00e1de5b9..6ed5704803 100644 > > --- a/arch/arm/mach-k3/include/mach/k3-qos.h > > +++ b/arch/arm/mach-k3/include/mach/k3-qos.h > > @@ -9,6 +9,80 @@ > > #include > > +#define QOS_0 (0 << 0) > > +#define QOS_1 (1 << 0) > > +#define QOS_2 (2 << 0) > > +#define QOS_3 (3 << 0) > > +#define QOS_4 (4 << 0) > > +#define QOS_5 (5 << 0) > > +#define QOS_6 (6 << 0) > > +#define QOS_7 (7 << 0) > > + > > +#define ORDERID_0 (0 << 4) > > +#define ORDERID_1 (1 << 4) > > +#define ORDERID_2 (2 << 4) > > +#define ORDERID_3 (3 << 4) > > +#define ORDERID_4 (4 << 4) > > +#define ORDERID_5 (5 << 4) > > +#define ORDERID_6 (6 << 4) > > +#define ORDERID_7 (7 << 4) > > +#define ORDERID_8 (8 << 4) > > +#define ORDERID_9 (9 << 4) > > +#define ORDERID_10 (10 << 4) > > +#define ORDERID_11 (11 << 4) > > +#define ORDERID_12 (12 << 4) > > +#define ORDERID_13 (13 << 4) > > +#define ORDERID_14 (14 << 4) > > +#define ORDERID_15 (15 << 4) > > + > > +#define ASEL_0 (0 << 8) > > +#define ASEL_1 (1 << 8) > > +#define ASEL_2 (2 << 8) > > +#define ASEL_3 (3 << 8) > > +#define ASEL_4 (4 << 8) > > +#define ASEL_5 (5 << 8) > > +#define ASEL_6 (6 << 8) > > +#define ASEL_7 (7 << 8) > > +#define ASEL_8 (8 << 8) > > +#define ASEL_9 (9 << 8) > > +#define ASEL_10(10 << 8) > > +#define ASEL_11(11 << 8) > > +#define ASEL_12(12 << 8) > > +#define ASEL_13(13 << 8) > > +#define ASEL_14(14 << 8) > > +#define ASEL_15(15 << 8) > > + > > +#define EPRIORITY_0(0 << 12) > > +#define EPRIORITY_1(1 << 12) > > +#define EPRIORITY_2(2 << 12) > > +#define EPRIORITY_3(3 << 12) > > +#define EPRIORITY_4(4 << 12) > > +#define EPRIORITY_5(5 << 12) > > +#define EPRIORITY_6(6 << 12) > > +#define EPRIORITY_7(7 << 12) > > + > > +#define VIRTID_0 (0 << 16) > > +#define VIRTID_1 (1 << 16) > > +#define VIRTID_2 (2 << 16) > > +#define VIRTID_3 (3 << 16) > > +#define VIRTID_4 (4 << 16) > > +#define VIRTID_5 (5 << 16) > > +#define VIRTID_6 (6 << 16) > > +#define VIRTID_7 (7 << 16) > > +#define VIRTID_8 (8 << 16) > > +#define VIRTID_9 (9 << 16) > > +#define VIRTID_10 (10 << 16) > > +#define VIRTID_11 (11 << 16) > > +#define VIRTID_12 (12 << 16) > > +#define VIRTID_13 (13 << 16) > > +#define VIRTID_14 (14 << 16) > > +#define VIRTID_15 (15 << 16) > > > This all seem like it could be made into some macro, something like > > #define K3_QOS(qos, orderid, asel, epriority, virtid, atype) \ > (qos << 0 | \ >orderid << 4 | \ >asel<< 8 | \ > etc.. > > Then use that instead of raw values. That might also make it more clear > we are setting the other values to 0 when we are setting these registers: > > .val = K3_QOS(0, 15, 0, 0, 0, 3), This sounds good to me too and to be clear, move in one patch, clean up macro follow-up patch in this series. -- Tom signature.asc Description: PGP signature
[PATCH] arm: dts: mvebu: Migrate to upstream DT for Synology DS116 (Armada 385) board
Enable OF_UPSTREAM to use upstream DT and add marvell/ prefix to the DEFAULT_DEVICE_TREE in DS116 defconfig. Remove current DTS in arch/arm/dts/ directory. Signed-off-by: Tony Dinh --- arch/arm/dts/Makefile | 1 - arch/arm/dts/armada-385-synology-ds116.dts | 291 - configs/ds116_defconfig| 3 +- 3 files changed, 2 insertions(+), 293 deletions(-) delete mode 100644 arch/arm/dts/armada-385-synology-ds116.dts diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index a5c82ebf7a..75f7e616b4 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -155,7 +155,6 @@ dtb-$(CONFIG_ARCH_MVEBU) += \ armada-385-atl-x530.dtb \ armada-385-atl-x530DP.dtb \ armada-385-db-88f6820-amc.dtb \ - armada-385-synology-ds116.dtb \ armada-385-thecus-n2350.dtb \ armada-385-turris-omnia.dtb \ armada-388-clearfog.dtb \ diff --git a/arch/arm/dts/armada-385-synology-ds116.dts b/arch/arm/dts/armada-385-synology-ds116.dts deleted file mode 100644 index 82a0373f7f..00 --- a/arch/arm/dts/armada-385-synology-ds116.dts +++ /dev/null @@ -1,291 +0,0 @@ -// SPDX-License-Identifier: (GPL-2.0 OR MIT) -/* - * Device Tree file for Synology DS116 NAS - * - * Copyright (C) 2017 Willy Tarreau - */ - -/dts-v1/; -#include "armada-385.dtsi" -#include - -/ { - model = "Synology DS116"; - compatible = "marvell,a385-gp", "marvell,armada385", "marvell,armada380"; - - chosen { - stdout-path = "serial0:115200n8"; - }; - - memory { - device_type = "memory"; - reg = <0x 0x4000>; /* 1 GB */ - }; - - soc { - ranges = ; - - internal-regs { - i2c@11000 { - pinctrl-names = "default"; - pinctrl-0 = <&i2c0_pins>; - status = "okay"; - clock-frequency = <10>; - - eeprom@57 { - compatible = "atmel,24c64"; - reg = <0x57>; - }; - }; - - serial@12000 { - pinctrl-names = "default"; - pinctrl-0 = <&uart0_pins>; - status = "okay"; - }; - - serial@12100 { - /* A PIC16F1829 is connected to uart1 at 9600 bps, -* and takes single-character orders : -* "1" : power off // already handled by the poweroff node -* "2" : short beep -* "3" : long beep -* "4" : turn the power LED ON -* "5" : flash the power LED -* "6" : turn the power LED OFF -* "7" : turn the status LED OFF -* "8" : turn the status LED ON -* "9" : flash the status LED -* "A" : flash the motherboard LED (D8) -* "B" : turn the motherboard LED OFF -* "C" : hard reset -*/ - pinctrl-names = "default"; - pinctrl-0 = <&uart1_pins>; - status = "okay"; - }; - - poweroff@12100 { - compatible = "synology,power-off"; - reg = <0x12100 0x100>; - clocks = <&coreclk 0>; - }; - - ethernet@7 { - pinctrl-names = "default"; - phy = <&phy0>; - phy-mode = "sgmii"; - buffer-manager = <&bm>; - bm,pool-long = <0>; - status = "okay"; - }; - - mdio@72004 { - pinctrl-names = "default"; - pinctrl-0 = <&mdio_pins>; - - phy0: ethernet-phy@1 { - reg = <1>; - }; - }; - - sata@a8000 { - pinctrl-names = "default"; - pinctrl-0 = <&sata0_pins>; - status = "okay"; -
Re: [PATCH 2/2 v5] board: starfive: support Pine64 Star64 board
On Wed, May 22, 2024 at 12:13 PM H Bell wrote: > > Add documentation files > > Signed-off-by: Henry Bell > Cc: ycli...@andestech.com > Cc: heinrich.schucha...@canonical.com > --- > > Changes since v1 > > - New patch > > Changes since v2 > > - Remove extra params to > - Clarification on boot section > - Add entry on MAC adresses and how to correct them > > Changes since v3 > > - Rebase against d678a59d2d > > Changes since v4 > > - Rework and expand docs on boot selection switches and overriding > MAC addresses > - Fix warnings and underline width > --- > doc/board/starfive/index.rst | 1 + > doc/board/starfive/pine64_star64.rst | 201 +++ > 2 files changed, 202 insertions(+) > create mode 100644 doc/board/starfive/pine64_star64.rst > > diff --git a/doc/board/starfive/index.rst b/doc/board/starfive/index.rst > index d369b986cc..72ab6ddfbf 100644 > --- a/doc/board/starfive/index.rst > +++ b/doc/board/starfive/index.rst > @@ -8,4 +8,5 @@ StarFive > > milk-v_mars > milk-v_mars_cm > + pine64_star64 > visionfive2 > diff --git a/doc/board/starfive/pine64_star64.rst > b/doc/board/starfive/pine64_star64.rst > new file mode 100644 > index 00..52e9a90791 > --- /dev/null > +++ b/doc/board/starfive/pine64_star64.rst > @@ -0,0 +1,201 @@ > +.. SPDX-License-Identifier: GPL-2.0+ > + > +Pine64 Star64 > += > + > +U-Boot for the Star64 uses the same U-Boot binaries as the VisionFive 2 > board. > +In U-Boot SPL the actual board is detected and the device-tree patched > +accordingly. > + > +Building > + > + > +1. Add the RISC-V toolchain to your PATH. > +2. Setup ARCH & cross compilation environment variable: > + > +.. code-block:: none > + > + export CROSS_COMPILE= > + > +The M-mode software OpenSBI provides the supervisor binary interface (SBI) > and > +is responsible for the switch to S-Mode. It is a prerequisite to build > U-Boot. > +Support for the JH7110 was introduced in OpenSBI 1.2. It is recommended to > use > +a current release. > + > +.. code-block:: console > + > + git clone https://github.com/riscv/opensbi.git > + cd opensbi > + make PLATFORM=generic FW_TEXT_START=0x4000 > + > +Now build the U-Boot SPL and U-Boot proper. > + > +.. code-block:: console > + > + cd > + make starfive_visionfive2_defconfig > + make > OPENSBI=$(opensbi_dir)/build/platform/generic/firmware/fw_dynamic.bin > + > +This will generate the U-Boot SPL image (spl/u-boot-spl.bin.normal.out) as > well > +as the FIT image (u-boot.itb) with OpenSBI and U-Boot. > + > +Device-tree selection > +~ > + > +U-Boot will set variable $fdtfile to starfive/jh7110-pine64-star64.dtb. > + > +To overrule this selection the variable can be set manually and saved in the > +environment > + > +:: > + > +env set fdtfile my_device-tree.dtb > +env save > + > +or the configuration variable CONFIG_DEFAULT_FDT_FILE can be used to set to > +provide a default value. > + > +Boot source selection > +~ > + > +Boot mode is selected by an MSEL-DIP marked S1804 and GPIO_0 position > adjacent > +to the 40pin GPIO header. ON/ONKE and number markings of the MSEL-DIP are > +misleading; Instead refer to the ``L`` (0) and ``H`` (1) silkscreen for > +accurate selection. > + > ++ (QSPI) Flash: 00 > ++ SD: 01 > ++ EMMC: 10 > ++ UART: 11 > + > +Preparing the SD-Card > +~ > + > +The device firmware loads U-Boot SPL (u-boot-spl.bin.normal.out) from the > +partition with type GUID 2E54B353-1271-4842-806F-E436D6AF6985. You are free > +to choose any partition number. > + > +With the default configuration U-Boot SPL loads the U-Boot FIT image > +(u-boot.itb) from partition 2 > (CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION=0x2). > +When formatting it is recommended to use GUID > +BC13C2FF-59E6-4262-A352-B275FD6F7172 for this partition. > + > +The FIT image (u-boot.itb) is a combination of OpenSBI's fw_dynamic.bin, > +u-boot-nodtb.bin and the device tree blob. > + > +Format the SD card (make sure the disk has GPT, otherwise use gdisk to > switch) > + > +.. code-block:: bash > + > + sudo sgdisk --clear \ > + --set-alignment=2 \ > + --new=1:4096:8191 --change-name=1:spl > --typecode=1:2E54B353-1271-4842-806F-E436D6AF6985\ > + --new=2:8192:16383 --change-name=2:uboot > --typecode=2:BC13C2FF-59E6-4262-A352-B275FD6F7172 \ > + --new=3:16384:1654784 --change-name=3:system > --typecode=3:EBD0A0A2-B9E5-4433-87C0-68B6B72699C7 \ > + /dev/sdb > + > +Copy U-Boot to the SD card > + > +.. code-block:: bash > + > + sudo dd if=u-boot-spl.bin.normal.out of=/dev/sdb1 > + sudo dd if=u-boot.itb of=/dev/sdb2 > + > + sudo mount /dev/sdb3 /mnt/ > + sudo cp u-boot-spl.bin.normal.out /mnt/ > + sudo cp u-boot.itb /mnt/ > + sudo cp Image.gz /mnt/ > + sudo cp initramfs.cpio.gz /mnt/ > + sudo cp jh7110-starfive-visionfive-2.dtb /mnt/ > +
Re: [PATCH 1/2 v5] board: starfive: support Pine64 Star64 board
On Wed, May 22, 2024 at 12:13 PM H Bell wrote: > > Similar to the Milk-V Mars, The Star64 board contains few differences to the > VisionFive 2 boards, so can be part of the same U-boot build. > > Signed-off-by: Henry Bell > Cc: ycli...@andestech.com > Cc: heinrich.schucha...@canonical.com > --- > > Changes since v1 > > - Fix typos on naming > - Create pine64_star64 struct to be populated with PHY values once confirmed > > Changes since v2 > > - Set delays to 0 > - Add missing 10/100/1000 clocks across the two devices > - Set all uA values to 2910 > > Changes since v3 > > - Rebase against d678a59d2d > > Changes since v4 > > - Fix up delay values > --- > board/starfive/visionfive2/spl.c | 89 +++ > .../visionfive2/starfive_visionfive2.c| 4 + > 2 files changed, 93 insertions(+) > > diff --git a/board/starfive/visionfive2/spl.c > b/board/starfive/visionfive2/spl.c > index b555189556..b794b73b6b 100644 > --- a/board/starfive/visionfive2/spl.c > +++ b/board/starfive/visionfive2/spl.c > @@ -86,6 +86,43 @@ static const struct starfive_vf2_pro starfive_verb[] = { > "tx-internal-delay-ps", "0"}, > }; > > +static const struct starfive_vf2_pro star64_pine64[] = { > + {"/soc/ethernet@1603", "starfive,tx-use-rgmii-clk", NULL}, > + {"/soc/ethernet@1604", "starfive,tx-use-rgmii-clk", NULL}, > + > + {"/soc/ethernet@1603/mdio/ethernet-phy@0", > + "motorcomm,tx-clk-adj-enabled", NULL}, > + {"/soc/ethernet@1603/mdio/ethernet-phy@0", > + "motorcomm,tx-clk-10-inverted", NULL}, > + {"/soc/ethernet@1603/mdio/ethernet-phy@0", > + "motorcomm,tx-clk-100-inverted", NULL}, > + {"/soc/ethernet@1603/mdio/ethernet-phy@0", > + "motorcomm,tx-clk-1000-inverted", NULL}, > + {"/soc/ethernet@1603/mdio/ethernet-phy@0", > + "motorcomm,rx-clk-drv-microamp", "2910"}, > + {"/soc/ethernet@1603/mdio/ethernet-phy@0", > + "motorcomm,rx-data-drv-microamp", "2910"}, > + {"/soc/ethernet@1603/mdio/ethernet-phy@0", > + "rx-internal-delay-ps", "1900"}, > + {"/soc/ethernet@1603/mdio/ethernet-phy@0", > + "tx-internal-delay-ps", "1500"}, > + > + {"/soc/ethernet@1604/mdio/ethernet-phy@1", > + "motorcomm,tx-clk-adj-enabled", NULL}, > + {"/soc/ethernet@1604/mdio/ethernet-phy@1", > + "motorcomm,tx-clk-10-inverted", NULL}, > + {"/soc/ethernet@1604/mdio/ethernet-phy@1", > + "motorcomm,tx-clk-100-inverted", NULL}, > + {"/soc/ethernet@1604/mdio/ethernet-phy@1", > + "motorcomm,rx-clk-drv-microamp", "2910"}, > + {"/soc/ethernet@1604/mdio/ethernet-phy@1", > + "motorcomm,rx-data-drv-microamp", "2910"}, > + {"/soc/ethernet@1604/mdio/ethernet-phy@1", > + "rx-internal-delay-ps", "0"}, > + {"/soc/ethernet@1604/mdio/ethernet-phy@1", > + "tx-internal-delay-ps", "300"}, Note this 300uS value for tx-internal-delay-ps differs from pre-loaded firmware on Star64: ethernet-phy@1 tx_delay_sel = <0x00>; I would prefer to this (even if it is wrong) same as the pre-loaded firmware has done. Tuning patches can be applied in some future series. Is there a noticeable difference in function to change this value from how the pre-loaded firmware does this? > +}; > + > void spl_fdt_fixup_mars(void *fdt) > { > static const char compat[] = "milkv,mars\0starfive,jh7110"; > @@ -250,6 +287,56 @@ void spl_fdt_fixup_version_b(void *fdt) > } > } > > +void spl_fdt_fixup_star64(void *fdt) > +{ > + static const char compat[] = "pine64,star64\0starfive,jh7110"; > + u32 phandle; > + u8 i; > + int offset; > + int ret; > + > + fdt_setprop(fdt, fdt_path_offset(fdt, "/"), "compatible", compat, > sizeof(compat)); > + fdt_setprop_string(fdt, fdt_path_offset(fdt, "/"), "model", > + "Pine64 Star64"); > + > + /* gmac0 */ > + offset = fdt_path_offset(fdt, "/soc/clock-controller@1700"); > + phandle = fdt_get_phandle(fdt, offset); > + offset = fdt_path_offset(fdt, "/soc/ethernet@1603"); > + > + fdt_setprop_u32(fdt, offset, "assigned-clocks", phandle); > + fdt_appendprop_u32(fdt, offset, "assigned-clocks", > JH7110_AONCLK_GMAC0_TX); > + fdt_setprop_u32(fdt, offset, "assigned-clock-parents", phandle); > + fdt_appendprop_u32(fdt, offset, "assigned-clock-parents", > + JH7110_AONCLK_GMAC0_RMII_RTX); > + > + /* gmac1 */ > + offset = fdt_path_offset(fdt, "/soc/clock-controller@1302"); > + phandle = fdt_get_phandle(fdt, offset); > + offset = fdt_path_offset(fdt, "/soc/ethernet@1604"); > + > + fdt_setprop_u32(fdt, offset, "assigned-clocks", phandle); > + fdt_appendprop_u32(fdt, off
Re: [PATCH] abootimg: Add init_boot image support
Hi Mattijs, Thank you for your review. ср, 22 мая 2024 г. в 17:43, Mattijs Korpershoek : > > Hi Roman, > > Thank you for the patch. > > On dim., mai 19, 2024 at 12:53, Roman Stratiienko > wrote: > > > Quote from [1]: > > > > "For devices launching with Android 13, the generic ramdisk is removed > > from the boot image and placed in a separate init_boot image. > > This change leaves the boot image with only the GKI kernel." > > > > [1]: > > https://source.android.com/docs/core/architecture/partitions/generic-boot > > Signed-off-by: Roman Stratiienko > > --- > > boot/image-board.c | 5 - > > cmd/abootimg.c | 26 +- > > include/image.h| 7 +++ > > 3 files changed, 32 insertions(+), 6 deletions(-) > > This patch does not apply on: > - next: 7d24c3e06fa9 ("Merge patch series "scripts/setlocalversion sync with > linux 6.9"") > - master: a7f0154c4128 ("Prepare v2024.07-rc3") > > Please consider rebasing when resending. V2 Rebased > > More review below > > > > > diff --git a/boot/image-board.c b/boot/image-board.c > > index 75f6906cd5..715654ff01 100644 > > --- a/boot/image-board.c > > +++ b/boot/image-board.c > > @@ -414,9 +414,12 @@ static int select_ramdisk(struct bootm_headers > > *images, const char *select, u8 a > > int ret; > > if (IS_ENABLED(CONFIG_CMD_ABOOTIMG)) { > > void *boot_img = > > map_sysmem(get_abootimg_addr(), 0); > > + void *init_boot_img = > > map_sysmem(get_ainit_bootimg_addr(), 0); > > void *vendor_boot_img = > > map_sysmem(get_avendor_bootimg_addr(), 0); > > + void *ramdisk_img = (init_boot_img == -1) ? > > boot_img : > > + > > init_boot_img; > > This line introduces a build warning: > > ../boot/image-board.c: In function ‘select_ramdisk’: > ../boot/image-board.c:412:68: warning: comparison between pointer and integer > 412 | void *ramdisk_img = (init_boot_img == > -1) ? boot_img : > |^~ > > Can we please fix it in v2 ? Fixed > > > > > - ret = android_image_get_ramdisk(boot_img, > > vendor_boot_img, > > + ret = android_image_get_ramdisk(ramdisk_img, > > vendor_boot_img, > > rd_datap, > > rd_lenp); > > unmap_sysmem(vendor_boot_img); > > Can we please add unmap_sysmem(init_boot_img); here as well ? Done. > > > unmap_sysmem(boot_img); > > diff --git a/cmd/abootimg.c b/cmd/abootimg.c > > index e68c523705..7c450a3b2d 100644 > > --- a/cmd/abootimg.c > > +++ b/cmd/abootimg.c > > @@ -17,6 +17,7 @@ > > > > /* Please use abootimg_addr() macro to obtain the boot image address */ > > static ulong _abootimg_addr = -1; > > +static ulong _ainit_bootimg_addr = -1; > > static ulong _avendor_bootimg_addr = -1; > > > > ulong get_abootimg_addr(void) > > @@ -24,6 +25,11 @@ ulong get_abootimg_addr(void) > > return (_abootimg_addr == -1 ? image_load_addr : _abootimg_addr); > > } > > > > +ulong get_ainit_bootimg_addr(void) > > +{ > > + return _ainit_bootimg_addr; > > +} > > + > > ulong get_avendor_bootimg_addr(void) > > { > > return _avendor_bootimg_addr; > > @@ -209,7 +215,7 @@ static int do_abootimg_addr(struct cmd_tbl *cmdtp, int > > flag, int argc, > > char *endp; > > ulong img_addr; > > > > - if (argc < 2 || argc > 3) > > + if (argc < 2 || argc > 4) > > return CMD_RET_USAGE; > > > > img_addr = hextoul(argv[1], &endp); > > @@ -220,16 +226,26 @@ static int do_abootimg_addr(struct cmd_tbl *cmdtp, > > int flag, int argc, > > > > _abootimg_addr = img_addr; > > > > - if (argc == 3) { > > + if (argc > 2) { > > img_addr = simple_strtoul(argv[2], &endp, 16); > > if (*endp != '\0') { > > - printf("Error: Wrong vendor image address\n"); > > + printf("Error: Wrong vendor_boot image address\n"); > > Nitpick: this seems like a harmless change but could be done in a > separate patch. > > To me, it's fine to include this hunk, but can we mention it in the > commit message? > > Something along the lines as "While at it, update wrong error handling > message when vendor_boot cannot be loaded". Added. > > > return CMD_RET_FAILURE; > > } > > > > _avendor_bootimg_addr = img_addr; > > } > > > > + if (argc == 4) { > > + img_addr = simple_strtoul(argv[3], &endp, 16); > > + if (*endp != '\0') { > > + printf("Error: Wrong init_boot image address\n"); > > + return CMD_RET_FAILURE; > > +
[PATCH v2] abootimg: Add init_boot image support
Quote from [1]: "For devices launching with Android 13, the generic ramdisk is removed from the boot image and placed in a separate init_boot image. This change leaves the boot image with only the GKI kernel." While at it, update wrong error handling message when vendor_boot cannot be loaded. [1]: https://source.android.com/docs/core/architecture/partitions/generic-boot Signed-off-by: Roman Stratiienko --- boot/image-board.c | 13 ++--- cmd/abootimg.c | 26 +- include/image.h| 7 +++ 3 files changed, 38 insertions(+), 8 deletions(-) diff --git a/boot/image-board.c b/boot/image-board.c index b7884b8c5d..f212401304 100644 --- a/boot/image-board.c +++ b/boot/image-board.c @@ -406,13 +406,20 @@ static int select_ramdisk(struct bootm_headers *images, const char *select, u8 a if (IS_ENABLED(CONFIG_ANDROID_BOOT_IMAGE)) { int ret; if (IS_ENABLED(CONFIG_CMD_ABOOTIMG)) { - void *boot_img = map_sysmem(get_abootimg_addr(), 0); + ulong boot_img = get_abootimg_addr(); + ulong init_boot_img = get_ainit_bootimg_addr(); void *vendor_boot_img = map_sysmem(get_avendor_bootimg_addr(), 0); + void *ramdisk_img; - ret = android_image_get_ramdisk(boot_img, vendor_boot_img, + if (init_boot_img == -1) + ramdisk_img = map_sysmem(boot_img, 0); + else + ramdisk_img = map_sysmem(init_boot_img, 0); + + ret = android_image_get_ramdisk(ramdisk_img, vendor_boot_img, rd_datap, rd_lenp); unmap_sysmem(vendor_boot_img); - unmap_sysmem(boot_img); + unmap_sysmem(ramdisk_img); } else { void *ptr = map_sysmem(images->os.start, 0); diff --git a/cmd/abootimg.c b/cmd/abootimg.c index 69c7390dbe..9e965c1fb7 100644 --- a/cmd/abootimg.c +++ b/cmd/abootimg.c @@ -16,6 +16,7 @@ /* Please use abootimg_addr() macro to obtain the boot image address */ static ulong _abootimg_addr = -1; +static ulong _ainit_bootimg_addr = -1; static ulong _avendor_bootimg_addr = -1; ulong get_abootimg_addr(void) @@ -23,6 +24,11 @@ ulong get_abootimg_addr(void) return (_abootimg_addr == -1 ? image_load_addr : _abootimg_addr); } +ulong get_ainit_bootimg_addr(void) +{ + return _ainit_bootimg_addr; +} + ulong get_avendor_bootimg_addr(void) { return _avendor_bootimg_addr; @@ -210,7 +216,7 @@ static int do_abootimg_addr(struct cmd_tbl *cmdtp, int flag, int argc, char *endp; ulong img_addr; - if (argc < 2 || argc > 3) + if (argc < 2 || argc > 4) return CMD_RET_USAGE; img_addr = hextoul(argv[1], &endp); @@ -221,16 +227,26 @@ static int do_abootimg_addr(struct cmd_tbl *cmdtp, int flag, int argc, _abootimg_addr = img_addr; - if (argc == 3) { + if (argc > 2) { img_addr = simple_strtoul(argv[2], &endp, 16); if (*endp != '\0') { - printf("Error: Wrong vendor image address\n"); + printf("Error: Wrong vendor_boot image address\n"); return CMD_RET_FAILURE; } _avendor_bootimg_addr = img_addr; } + if (argc == 4) { + img_addr = simple_strtoul(argv[3], &endp, 16); + if (*endp != '\0') { + printf("Error: Wrong init_boot image address\n"); + return CMD_RET_FAILURE; + } + + _ainit_bootimg_addr = img_addr; + } + return CMD_RET_SUCCESS; } @@ -347,7 +363,7 @@ fail: } static struct cmd_tbl cmd_abootimg_sub[] = { - U_BOOT_CMD_MKENT(addr, 3, 1, do_abootimg_addr, "", ""), + U_BOOT_CMD_MKENT(addr, 4, 1, do_abootimg_addr, "", ""), U_BOOT_CMD_MKENT(dump, 2, 1, do_abootimg_dump, "", ""), U_BOOT_CMD_MKENT(get, 5, 1, do_abootimg_get, "", ""), U_BOOT_CMD_MKENT(load, 5, 1, do_abootimg_load, "", ""), @@ -376,7 +392,7 @@ static int do_abootimg(struct cmd_tbl *cmdtp, int flag, int argc, U_BOOT_CMD( abootimg, CONFIG_SYS_MAXARGS, 0, do_abootimg, "manipulate Android Boot Image", - "addr []>\n" + "addr [ []]\n" "- set the address in RAM where boot image is located\n" " ($loadaddr is used by default)\n" "abootimg dump dtb\n" diff --git a/include/image.h b/include/image.h index 96df2b99a7..7d8ff40c3f 100644 --- a/include/image.h +++ b/include/image.h @@ -1982,6 +1982,13 @
Re: [PATCH v2 06/10] arm: mach-k3: am625_init: Probe AM65 CPSW NUSS
On 21/05/2024 08:34, Chintan Vankar wrote: > > > On 20/05/24 17:42, Roger Quadros wrote: >> >> >> On 25/04/2024 15:59, Chintan Vankar wrote: >>> >>> >>> On 25/04/24 17:57, Roger Quadros wrote: On 25/04/2024 15:08, Chintan Vankar wrote: > From: Kishon Vijay Abraham I > > In order to support Ethernet boot on AM62x, probe AM65 CPSW NUSS > driver in board_init_f(). > > Signed-off-by: Kishon Vijay Abraham I > Signed-off-by: Siddharth Vadapalli > Signed-off-by: Chintan Vankar > --- > > Link to v1: > https://lore.kernel.org/r/20240112064759.1801600-8-s-vadapa...@ti.com/ > > Changes from v1 to v2: > - No changes. > > arch/arm/mach-k3/am625_init.c | 10 ++ > 1 file changed, 10 insertions(+) > > diff --git a/arch/arm/mach-k3/am625_init.c b/arch/arm/mach-k3/am625_init.c > index 668f9a51ef..9bf61b1e83 100644 > --- a/arch/arm/mach-k3/am625_init.c > +++ b/arch/arm/mach-k3/am625_init.c > @@ -277,6 +277,16 @@ void board_init_f(ulong dummy) > if (ret) > panic("DRAM init failed: %d\n", ret); > } > + > + if (IS_ENABLED(CONFIG_SPL_ETH) && > IS_ENABLED(CONFIG_TI_AM65_CPSW_NUSS) && > + spl_boot_device() == BOOT_DEVICE_ETHERNET) { > + struct udevice *cpswdev; > + > + if (uclass_get_device_by_driver(UCLASS_MISC, > DM_DRIVER_GET(am65_cpsw_nuss), > + &cpswdev)) > + printf("Failed to probe am65_cpsw_nuss driver\n"); > + } > + This looks like a HACK. The network driver should be probed only when the networking feature is actually required. >>> >>> Driver is probed only when the condition above >>> "spl_boot_device() == BOOT_DEVICE_ETHERNET" is true, which says Boot >>> device is Ethernet, and here we are booting with Ethernet so driver is >>> getting probed. >> >> I think you misunderstood what I was saying as am625_init.c is not using >> any Ethernet function it should not cause the Ethernet driver to probe. >> >> Instead it should be probed by the networking use case. >> >> What happens if you don't use this patch? Where is it failing? >> > > You are correct that it should be probed by the networking use case and > we are using networking functionality of "Booting via Ethernet". > Regarding its probing, I already had discussion that why do I have to > probe it explicitly at here: > https://lore.kernel.org/r/ee1d16fd-b99b-4b07-97bb-a896e1791...@ti.com/ > > Now if I don't use this patch then Ethernet will not get initialized at > SPL stage, and in "spl_net_load_image()" function, there will be an > error saying "No Ethernet Found", and since we selected booting via > Ethernet it will fail to boot. OK Now I see the problem. in am65-cpsw-nuss.c the following is defined: > U_BOOT_DRIVER(am65_cpsw_nuss) = { > .name = "am65_cpsw_nuss", > .id = UCLASS_MISC, > .of_match = am65_cpsw_nuss_ids, > .probe = am65_cpsw_probe_nuss, > .priv_auto = sizeof(struct am65_cpsw_common), > }; > > U_BOOT_DRIVER(am65_cpsw_nuss_port) = { > .name = "am65_cpsw_nuss_port", > .id = UCLASS_ETH, > .probe = am65_cpsw_port_probe, > .ops= &am65_cpsw_ops, > .priv_auto = sizeof(struct am65_cpsw_priv), > .plat_auto = sizeof(struct eth_pdata), > .flags = DM_FLAG_ALLOC_PRIV_DMA | DM_FLAG_OS_PREPARE, > }; Now I suppose spl_net_load_image() tries to probe all UCLASS_ETH devices which should call am65_cpsw_port_probe() but it fails to probe am65_cpsw_probe_nuss(). This limitation was introduced by commit 38922b1f4acc ("net: ti: am65-cpsw: Add support for multi port independent MAC mode") which says "Since top level driver is now UCLASS_MISC, board files would need to instantiate this driver explicitly. I wonder if there can be a better solution to this? -- cheers, -roger
Re: [PATCH 0/4] rockchip: Add gpio request() ops and drop PCIe reset-gpios workaround
Am 22.05.24 um 18:20 schrieb Jonas Karlman: On 2024-05-22 16:18, Alex Bee wrote: Am 13.05.24 um 01:22 schrieb Jonas Karlman: On 2024-05-13 00:34, Alex Bee wrote: Am 12.05.24 um 23:37 schrieb Jonas Karlman: Hi Alex, On 2024-05-12 21:49, Alex Bee wrote: Am 11.05.24 um 20:47 schrieb Jonas Karlman: Hi Alex, On 2024-05-11 19:44, Alex Bee wrote: Hi Jonas, Am 11.05.24 um 13:28 schrieb Jonas Karlman: This series add gpio request() and pinctrl gpio_request_enable() ops so that a gpio requested pin automatically use gpio pinmux and U-Boot behaves more similar to Linux kernel. I'm not sure that's a good idea. While linux does it the same way, we really shouldn't expect every software/os/ … which uses DT (now or in future) to implicitly switch the pin function when using a pin as gpio. So the real fix would probably be to add the the correct pinctrl settings to the upstream DT of those boards and sync it later on (not sure those if those SoCs already using OF_UPSTREAM) and leave the -u-boot.dtsi-"hack" alone for now. I fully agree that the pinctrl for the problematic boards should be corrected in upstream DT, but that is a separate issue and should not block adding support for the request()/gpio_request_enable() ops. While the pcie reset-gpios full board freeze that was my driving factor to fully implement the gpio request() ops it is not the only use case, using the gpio cmd on a pin that use a non-gpio pinmux is another. Or do you see any technical issue with having the gpio request() ops implemented and having it ensure gpio pinmux is used on a gpio requested pin? Similar to how gpio/pinctrl is behaving in Linux and on some other platforms in U-Boot? No, no general ("technical") issue with adding a .request hook to the gpio driver. But now you are now moving the original workaround to an even more invisible place which does things implicitly. Maybe just don't remove the pinctrl from the boards u-boot-dtsi's - just replace it with &pcie30x2m1_pins { rockchip,pins = <2 RK_PD4 4 &pcfg_pull_none>, <2 RK_PD6 RK_FUNC_GPIO &pcfg_pull_none>, <2 RK_PD5 4 &pcfg_pull_none>; }; Even if it would (now) work without. It, at least, documents that there are things left to do for the upstream DT. This is what I was doing when testing PCIe on ROCK 3B, I would still like to drop the "bad" workaround for ROCK 3A and E25 and have it fixed in upstream DT and let it trickle back now that RK356x use OF_UPSTREAM. I do not see the point of keeping a workaround that no longer is needed, especially when there is plans to also adjust upstream DT. Yeah, sure: but that certainly should be done/happen first, before it's removed here. Everybody knows how long that takes, patches being forgotten I am fully aware of patches being forgotten :-) Still, here I try to cleanup a bad workaround that I probably never should have added in the first place. Why is it bad? It's incomplete and the correct pin configuration should have been added to the upstream board DT in the first place. That's what *-u-boot.dtsi are doing at times :) It's not as worse as adding implicit pin function switching to a driver to compensate the incomplete/incorrect upstream board device tree, imho. From my point-of-view the upstream pinctrl is more correct and I wrongly added a patch that completely disregarded existing pinctrl just to fix pci enumeration in U-Boot when no pci device is connected without thinking of how it could affect linux/bsd, hence why I now think that old workaround/hack is something bad and something I want to cleanup/remove. Yeah, sure. That's why I suggested[0] to replace the current override like ... -&pcie3x2 { - pinctrl-0 = <&pcie3x2_reset_h>; -}; - -&pinctrl { - pcie { - pcie3x2_reset_h: pcie3x2-reset-h { - rockchip,pins = <2 RK_PD6 RK_FUNC_GPIO &pcfg_pull_none>; - }; - }; +&pcie30x2m1_pins { + rockchip,pins = + <2 RK_PD4 4 &pcfg_pull_none>, + <2 RK_PD6 RK_FUNC_GPIO &pcfg_pull_none>, + <2 RK_PD5 4 &pcfg_pull_none>; }; The proper upstream solution should probably add another pinctrl-set to rk3568-pinctrl.dtsi - someting like ... + /omit-if-no-ref/ + pcie30x2m1_ep_pins: pcie30x2m1-ep-pins { + rockchip,pins = + /* pcie30x2_clkreqnm1 */ + <2 RK_PD4 4 &pcfg_pull_none>, + /* pcie30x2_perstnm1 */ + <2 RK_PD6 RK_FUNC_GPIO &pcfg_pull_none>, + /* pcie30x2_wakenm1 */ + <2 RK_PD5 4 &pcfg_pull_none>; + }; + ... and boards needing this just switch from pcie30x2m1_pins to pcie30x2m1_ep_pins In my mind the current pinctrl use for pcie3 in U-Boot is describing the hw much worse than what is done in upstream Linux. No, not really. It describes pin settings wrong. The DT suggests GPIO2_D6 is used with func4, but in reality its used with func0 (gpio). The only reason that works correctly is probe order: if the pinctrl driver would probe after the gpio driver (which is sort of impossib
[PATCH 2/2 v5] board: starfive: support Pine64 Star64 board
Add documentation files Signed-off-by: Henry Bell Cc: ycli...@andestech.com Cc: heinrich.schucha...@canonical.com --- Changes since v1 - New patch Changes since v2 - Remove extra params to - Clarification on boot section - Add entry on MAC adresses and how to correct them Changes since v3 - Rebase against d678a59d2d Changes since v4 - Rework and expand docs on boot selection switches and overriding MAC addresses - Fix warnings and underline width --- doc/board/starfive/index.rst | 1 + doc/board/starfive/pine64_star64.rst | 201 +++ 2 files changed, 202 insertions(+) create mode 100644 doc/board/starfive/pine64_star64.rst diff --git a/doc/board/starfive/index.rst b/doc/board/starfive/index.rst index d369b986cc..72ab6ddfbf 100644 --- a/doc/board/starfive/index.rst +++ b/doc/board/starfive/index.rst @@ -8,4 +8,5 @@ StarFive milk-v_mars milk-v_mars_cm + pine64_star64 visionfive2 diff --git a/doc/board/starfive/pine64_star64.rst b/doc/board/starfive/pine64_star64.rst new file mode 100644 index 00..52e9a90791 --- /dev/null +++ b/doc/board/starfive/pine64_star64.rst @@ -0,0 +1,201 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +Pine64 Star64 += + +U-Boot for the Star64 uses the same U-Boot binaries as the VisionFive 2 board. +In U-Boot SPL the actual board is detected and the device-tree patched +accordingly. + +Building + + +1. Add the RISC-V toolchain to your PATH. +2. Setup ARCH & cross compilation environment variable: + +.. code-block:: none + + export CROSS_COMPILE= + +The M-mode software OpenSBI provides the supervisor binary interface (SBI) and +is responsible for the switch to S-Mode. It is a prerequisite to build U-Boot. +Support for the JH7110 was introduced in OpenSBI 1.2. It is recommended to use +a current release. + +.. code-block:: console + + git clone https://github.com/riscv/opensbi.git + cd opensbi + make PLATFORM=generic FW_TEXT_START=0x4000 + +Now build the U-Boot SPL and U-Boot proper. + +.. code-block:: console + + cd + make starfive_visionfive2_defconfig + make OPENSBI=$(opensbi_dir)/build/platform/generic/firmware/fw_dynamic.bin + +This will generate the U-Boot SPL image (spl/u-boot-spl.bin.normal.out) as well +as the FIT image (u-boot.itb) with OpenSBI and U-Boot. + +Device-tree selection +~ + +U-Boot will set variable $fdtfile to starfive/jh7110-pine64-star64.dtb. + +To overrule this selection the variable can be set manually and saved in the +environment + +:: + +env set fdtfile my_device-tree.dtb +env save + +or the configuration variable CONFIG_DEFAULT_FDT_FILE can be used to set to +provide a default value. + +Boot source selection +~ + +Boot mode is selected by an MSEL-DIP marked S1804 and GPIO_0 position adjacent +to the 40pin GPIO header. ON/ONKE and number markings of the MSEL-DIP are +misleading; Instead refer to the ``L`` (0) and ``H`` (1) silkscreen for +accurate selection. + ++ (QSPI) Flash: 00 ++ SD: 01 ++ EMMC: 10 ++ UART: 11 + +Preparing the SD-Card +~ + +The device firmware loads U-Boot SPL (u-boot-spl.bin.normal.out) from the +partition with type GUID 2E54B353-1271-4842-806F-E436D6AF6985. You are free +to choose any partition number. + +With the default configuration U-Boot SPL loads the U-Boot FIT image +(u-boot.itb) from partition 2 (CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION=0x2). +When formatting it is recommended to use GUID +BC13C2FF-59E6-4262-A352-B275FD6F7172 for this partition. + +The FIT image (u-boot.itb) is a combination of OpenSBI's fw_dynamic.bin, +u-boot-nodtb.bin and the device tree blob. + +Format the SD card (make sure the disk has GPT, otherwise use gdisk to switch) + +.. code-block:: bash + + sudo sgdisk --clear \ + --set-alignment=2 \ + --new=1:4096:8191 --change-name=1:spl --typecode=1:2E54B353-1271-4842-806F-E436D6AF6985\ + --new=2:8192:16383 --change-name=2:uboot --typecode=2:BC13C2FF-59E6-4262-A352-B275FD6F7172 \ + --new=3:16384:1654784 --change-name=3:system --typecode=3:EBD0A0A2-B9E5-4433-87C0-68B6B72699C7 \ + /dev/sdb + +Copy U-Boot to the SD card + +.. code-block:: bash + + sudo dd if=u-boot-spl.bin.normal.out of=/dev/sdb1 + sudo dd if=u-boot.itb of=/dev/sdb2 + + sudo mount /dev/sdb3 /mnt/ + sudo cp u-boot-spl.bin.normal.out /mnt/ + sudo cp u-boot.itb /mnt/ + sudo cp Image.gz /mnt/ + sudo cp initramfs.cpio.gz /mnt/ + sudo cp jh7110-starfive-visionfive-2.dtb /mnt/ + sudo umount /mnt + +Booting +~~~ + +Once you plugin the sdcard and power up, you should see the U-Boot prompt. + +Serial Number and MAC address issues + + +U-Boot requires valid EEPROM data to determine which board-specific fix-up to +apply at runtime. This affects the size of memory initialized, network mac +address numbering, and tuning
[PATCH 1/2 v5] board: starfive: support Pine64 Star64 board
Similar to the Milk-V Mars, The Star64 board contains few differences to the VisionFive 2 boards, so can be part of the same U-boot build. Signed-off-by: Henry Bell Cc: ycli...@andestech.com Cc: heinrich.schucha...@canonical.com --- Changes since v1 - Fix typos on naming - Create pine64_star64 struct to be populated with PHY values once confirmed Changes since v2 - Set delays to 0 - Add missing 10/100/1000 clocks across the two devices - Set all uA values to 2910 Changes since v3 - Rebase against d678a59d2d Changes since v4 - Fix up delay values --- board/starfive/visionfive2/spl.c | 89 +++ .../visionfive2/starfive_visionfive2.c| 4 + 2 files changed, 93 insertions(+) diff --git a/board/starfive/visionfive2/spl.c b/board/starfive/visionfive2/spl.c index b555189556..b794b73b6b 100644 --- a/board/starfive/visionfive2/spl.c +++ b/board/starfive/visionfive2/spl.c @@ -86,6 +86,43 @@ static const struct starfive_vf2_pro starfive_verb[] = { "tx-internal-delay-ps", "0"}, }; +static const struct starfive_vf2_pro star64_pine64[] = { + {"/soc/ethernet@1603", "starfive,tx-use-rgmii-clk", NULL}, + {"/soc/ethernet@1604", "starfive,tx-use-rgmii-clk", NULL}, + + {"/soc/ethernet@1603/mdio/ethernet-phy@0", + "motorcomm,tx-clk-adj-enabled", NULL}, + {"/soc/ethernet@1603/mdio/ethernet-phy@0", + "motorcomm,tx-clk-10-inverted", NULL}, + {"/soc/ethernet@1603/mdio/ethernet-phy@0", + "motorcomm,tx-clk-100-inverted", NULL}, + {"/soc/ethernet@1603/mdio/ethernet-phy@0", + "motorcomm,tx-clk-1000-inverted", NULL}, + {"/soc/ethernet@1603/mdio/ethernet-phy@0", + "motorcomm,rx-clk-drv-microamp", "2910"}, + {"/soc/ethernet@1603/mdio/ethernet-phy@0", + "motorcomm,rx-data-drv-microamp", "2910"}, + {"/soc/ethernet@1603/mdio/ethernet-phy@0", + "rx-internal-delay-ps", "1900"}, + {"/soc/ethernet@1603/mdio/ethernet-phy@0", + "tx-internal-delay-ps", "1500"}, + + {"/soc/ethernet@1604/mdio/ethernet-phy@1", + "motorcomm,tx-clk-adj-enabled", NULL}, + {"/soc/ethernet@1604/mdio/ethernet-phy@1", + "motorcomm,tx-clk-10-inverted", NULL}, + {"/soc/ethernet@1604/mdio/ethernet-phy@1", + "motorcomm,tx-clk-100-inverted", NULL}, + {"/soc/ethernet@1604/mdio/ethernet-phy@1", + "motorcomm,rx-clk-drv-microamp", "2910"}, + {"/soc/ethernet@1604/mdio/ethernet-phy@1", + "motorcomm,rx-data-drv-microamp", "2910"}, + {"/soc/ethernet@1604/mdio/ethernet-phy@1", + "rx-internal-delay-ps", "0"}, + {"/soc/ethernet@1604/mdio/ethernet-phy@1", + "tx-internal-delay-ps", "300"}, +}; + void spl_fdt_fixup_mars(void *fdt) { static const char compat[] = "milkv,mars\0starfive,jh7110"; @@ -250,6 +287,56 @@ void spl_fdt_fixup_version_b(void *fdt) } } +void spl_fdt_fixup_star64(void *fdt) +{ + static const char compat[] = "pine64,star64\0starfive,jh7110"; + u32 phandle; + u8 i; + int offset; + int ret; + + fdt_setprop(fdt, fdt_path_offset(fdt, "/"), "compatible", compat, sizeof(compat)); + fdt_setprop_string(fdt, fdt_path_offset(fdt, "/"), "model", + "Pine64 Star64"); + + /* gmac0 */ + offset = fdt_path_offset(fdt, "/soc/clock-controller@1700"); + phandle = fdt_get_phandle(fdt, offset); + offset = fdt_path_offset(fdt, "/soc/ethernet@1603"); + + fdt_setprop_u32(fdt, offset, "assigned-clocks", phandle); + fdt_appendprop_u32(fdt, offset, "assigned-clocks", JH7110_AONCLK_GMAC0_TX); + fdt_setprop_u32(fdt, offset, "assigned-clock-parents", phandle); + fdt_appendprop_u32(fdt, offset, "assigned-clock-parents", + JH7110_AONCLK_GMAC0_RMII_RTX); + + /* gmac1 */ + offset = fdt_path_offset(fdt, "/soc/clock-controller@1302"); + phandle = fdt_get_phandle(fdt, offset); + offset = fdt_path_offset(fdt, "/soc/ethernet@1604"); + + fdt_setprop_u32(fdt, offset, "assigned-clocks", phandle); + fdt_appendprop_u32(fdt, offset, "assigned-clocks", JH7110_SYSCLK_GMAC1_TX); + fdt_setprop_u32(fdt, offset, "assigned-clock-parents", phandle); + fdt_appendprop_u32(fdt, offset, "assigned-clock-parents", + JH7110_SYSCLK_GMAC1_RMII_RTX); + + for (i = 0; i < ARRAY_SIZE(star64_pine64); i++) { + offset = fdt_path_offset(fdt, star64_pine64[i].path); + + if (star64_pine64[i].value) + ret = fdt_setprop_u32(fdt, offset, star64_pine64[i].name, + dectoul(star64_pine64[i].value, NULL)); + else + ret = fdt_se
Re: [PATCH 10/15] test: dm: dsa, eth: disable tests when CONFIG_NET_LWIP=y
On 5/22/24 20:07, Ilias Apalodimas wrote: > Hi Jerome, > > On Wed, 22 May 2024 at 19:04, Jerome Forissier > wrote: >> >> Some sandbox tests make strong assumptions on how the network stack is >> implemented. For example, the ping tests assume that ARP resolution >> occurs upon sending out the ICMP packet. This is not always the case >> with the lwIP stack which can cache ARP information. >> Therefore, disable these tests when CONFIG_NET_LWIP is enabled. > > Is the ARP Caching the only issue? No, but I don't recall exactly what was wrong in addition to that. > U-Boot isn't supposed to use the network stack that much, so it might > be a better idea to disable arp-caching in LWIP (assuming it's > doable). We might even get a few size of bytes back If ARP_TABLE_SIZE is 0, there is no caching but in addition to that the lwIP stack does not work well. For example when requested to send an ICMP packet to an unknown IP (unknown as in "not yet resolved at the ethernet level" i.e., ARP) and assuming ARP_TABLE_SIZE is 1, it will automatically do the ARP request/response then proceed with ICMP send. However if ARP_TABLE_SIZE is 0, only the ARP resolution occurs and the ICMP packet won't go out. So I am not sure that 0 is a valid value. > > Cheers > /Ilias >> >> Signed-off-by: Jerome Forissier >> --- >> test/dm/dsa.c | 2 ++ >> test/dm/eth.c | 4 >> 2 files changed, 6 insertions(+) >> >> diff --git a/test/dm/dsa.c b/test/dm/dsa.c >> index c857106eaf..147e2a4afe 100644 >> --- a/test/dm/dsa.c >> +++ b/test/dm/dsa.c >> @@ -59,6 +59,7 @@ static int dm_test_dsa_probe(struct unit_test_state *uts) >> >> DM_TEST(dm_test_dsa_probe, UT_TESTF_SCAN_FDT); >> >> +#if !defined(CONFIG_NET_LWIP) >> /* This test sends ping requests with the local address through each DSA >> port >> * via the sandbox DSA master Eth. >> */ >> @@ -80,3 +81,4 @@ static int dm_test_dsa(struct unit_test_state *uts) >> } >> >> DM_TEST(dm_test_dsa, UT_TESTF_SCAN_FDT); >> +#endif /* !defined(CONFIG_NET_LWIP) */ >> diff --git a/test/dm/eth.c b/test/dm/eth.c >> index bb3dcc6b95..cf97b1c1ab 100644 >> --- a/test/dm/eth.c >> +++ b/test/dm/eth.c >> @@ -170,6 +170,7 @@ static int dm_test_ip6_make_lladdr(struct >> unit_test_state *uts) >> DM_TEST(dm_test_ip6_make_lladdr, UT_TESTF_SCAN_FDT); >> #endif >> >> +#if !defined(CONFIG_NET_LWIP) >> static int dm_test_eth(struct unit_test_state *uts) >> { >> net_ping_ip = string_to_ip("1.1.2.2"); >> @@ -298,6 +299,7 @@ static int dm_test_eth_act(struct unit_test_state *uts) >> return 0; >> } >> DM_TEST(dm_test_eth_act, UT_TESTF_SCAN_FDT); >> +#endif /* !CONFIG_NET_LWIP */ >> >> /* Ensure that all addresses are loaded properly */ >> static int dm_test_ethaddr(struct unit_test_state *uts) >> @@ -332,6 +334,7 @@ static int dm_test_ethaddr(struct unit_test_state *uts) >> } >> DM_TEST(dm_test_ethaddr, UT_TESTF_SCAN_FDT); >> >> +#if !defined(CONFIG_NET_LWIP) >> /* The asserts include a return on fail; cleanup in the caller */ >> static int _dm_test_eth_rotate1(struct unit_test_state *uts) >> { >> @@ -616,6 +619,7 @@ static int dm_test_eth_async_ping_reply(struct >> unit_test_state *uts) >> } >> >> DM_TEST(dm_test_eth_async_ping_reply, UT_TESTF_SCAN_FDT); >> +#endif /* !CONFIG_NET_LWIP */ >> >> #if IS_ENABLED(CONFIG_IPV6_ROUTER_DISCOVERY) >> >> -- >> 2.40.1 >>
[PATCH] xilinx: Add option to load environment from outside of boot media
From: Vasileios Amoiridis Currently, if the environment is not in the current boot media, the env_get_location() is returning ENVL_UNKNOWN or ENVL_NOWHERE which is not true (i.e booting from FLASH with environment in eMMC). This commit adds an extra check to find the environment in the other supported boot media, keeping the same priority as of now. Signed-off-by: Vasileios Amoiridis --- board/xilinx/versal-net/board.c | 21 +++-- board/xilinx/versal/board.c | 23 --- board/xilinx/zynq/board.c | 31 +++ board/xilinx/zynqmp/zynqmp.c| 31 +++ 4 files changed, 93 insertions(+), 13 deletions(-) diff --git a/board/xilinx/versal-net/board.c b/board/xilinx/versal-net/board.c index da03024e16..5648d6685e 100644 --- a/board/xilinx/versal-net/board.c +++ b/board/xilinx/versal-net/board.c @@ -372,6 +372,21 @@ void reset_cpu(void) { } +static enum env_location env_locations[] = { +#ifdef CONFIG_ENV_IS_IN_FAT + ENVL_FAT, +#endif +#ifdef CONFIG_ENV_IS_IN_EXT4 + ENVL_EXT4, +#endif +#ifdef CONFIG_ENV_IS_IN_SPI_FLASH + ENVL_SPI_FLASH, +#endif +#ifdef CONFIG_ENV_IS_NOWHERE + ENVL_NOWHERE, +#endif +}; + #if defined(CONFIG_ENV_IS_NOWHERE) enum env_location env_get_location(enum env_operation op, int prio) { @@ -389,17 +404,19 @@ enum env_location env_get_location(enum env_operation op, int prio) return ENVL_FAT; if (IS_ENABLED(CONFIG_ENV_IS_IN_EXT4)) return ENVL_EXT4; - return ENVL_NOWHERE; + break; case OSPI_MODE: case QSPI_MODE_24BIT: case QSPI_MODE_32BIT: if (IS_ENABLED(CONFIG_ENV_IS_IN_SPI_FLASH)) return ENVL_SPI_FLASH; - return ENVL_NOWHERE; + break; case JTAG_MODE: case SELECTMAP_MODE: default: return ENVL_NOWHERE; } + + return env_locations[prio]; } #endif diff --git a/board/xilinx/versal/board.c b/board/xilinx/versal/board.c index 4f6d56119d..8aed2e97df 100644 --- a/board/xilinx/versal/board.c +++ b/board/xilinx/versal/board.c @@ -291,12 +291,27 @@ void reset_cpu(void) { } +static enum env_location env_locations[] = { +#ifdef CONFIG_ENV_IS_IN_FAT + ENVL_FAT, +#endif +#ifdef CONFIG_ENV_IS_IN_EXT4 + ENVL_EXT4, +#endif +#ifdef CONFIG_ENV_IS_IN_SPI_FLASH + ENVL_SPI_FLASH, +#endif +#ifdef CONFIG_ENV_IS_NOWHERE + ENVL_NOWHERE, +#endif +}; + #if defined(CONFIG_ENV_IS_NOWHERE) enum env_location env_get_location(enum env_operation op, int prio) { u32 bootmode = versal_get_bootmode(); - if (prio) + if (prio >= ARRAY_SIZE(env_locations)) return ENVL_UNKNOWN; switch (bootmode) { @@ -308,17 +323,19 @@ enum env_location env_get_location(enum env_operation op, int prio) return ENVL_FAT; if (IS_ENABLED(CONFIG_ENV_IS_IN_EXT4)) return ENVL_EXT4; - return ENVL_NOWHERE; + break; case OSPI_MODE: case QSPI_MODE_24BIT: case QSPI_MODE_32BIT: if (IS_ENABLED(CONFIG_ENV_IS_IN_SPI_FLASH)) return ENVL_SPI_FLASH; - return ENVL_NOWHERE; + break; case JTAG_MODE: case SELECTMAP_MODE: default: return ENVL_NOWHERE; } + + return env_locations[prio]; } #endif diff --git a/board/xilinx/zynq/board.c b/board/xilinx/zynq/board.c index 6c36591001..6fa5016cdd 100644 --- a/board/xilinx/zynq/board.c +++ b/board/xilinx/zynq/board.c @@ -134,11 +134,32 @@ int dram_init(void) } #endif +static enum env_location env_locations[] = { +#ifdef CONFIG_ENV_IS_IN_FAT + ENVL_FAT, +#endif +#ifdef CONFIG_ENV_IS_IN_EXT4 + ENVL_EXT4, +#endif +#ifdef CONFIG_ENV_IS_IN_NAND + ENVL_NAND, +#endif +#ifdef CONFIG_ENV_IS_IN_UBI + ENVL_UBI, +#endif +#ifdef CONFIG_ENV_IS_IN_SPI_FLASH + ENVL_SPI_FLASH, +#endif +#ifdef CONFIG_ENV_IS_NOWHERE + ENVL_NOWHERE, +#endif +}; + enum env_location env_get_location(enum env_operation op, int prio) { u32 bootmode = zynq_slcr_get_boot_mode() & ZYNQ_BM_MASK; - if (prio) + if (prio >= ARRAY_SIZE(env_locations)) return ENVL_UNKNOWN; switch (bootmode) { @@ -147,22 +168,24 @@ enum env_location env_get_location(enum env_operation op, int prio) return ENVL_FAT; if (IS_ENABLED(CONFIG_ENV_IS_IN_EXT4)) return ENVL_EXT4; - return ENVL_NOWHERE; + break; case ZYNQ_BM_NAND: if (IS_ENABLED(CONFIG_ENV_IS_IN_NAND)) return ENVL_NAND; if (IS_ENABLED(CONFIG_ENV_IS_IN_UBI)) return ENVL_UBI; - return ENVL_
[PATCH v2] board: rockchip: add ArmSoM Sige7 Rk3588 board
ArmSoM Sige7 is a Rockchip RK3588 based SBC (Single Board Computer) by ArmSoM. There are two variants depending on the DRAM size : 8G and 16G. Specification: Rockchip Rk3588 SoC 4x ARM Cortex-A76, 4x ARM Cortex-A55 8/16GB memory LPDDR4x Mali G610MC4 GPU 2x MIPI CSI 2 multiple lanes connector 64GB/128GB on board eMMC uSD slot 1x USB 2.0 Type-A, 1x USB 3.0 Type-A, 1x USB 3.0 Type-C 1x HDMI 2.1 output 2x 2.5 Gbps Ethernet port 40-pin IO header including UART, SPI and I2C USB PD over USB Type-C Size: 92mm x 62mm Kernel commit: 81c828a67c78 (arm64: dts: rockchip: Add ArmSom Sige7 board) Note that these commits: - e18e5e8188f2 (arm64: dts: rockchip: add USBDP phys on rk3588) - 6fca4edb93d3 (arm64: dts: rockchip: Add rk3588 GPU node) are not synced to u-boot, so I remove usb3 drd nodes and gpu from kernel devicetree. Signed-off-by: Jianfeng Liu --- Changes in v2: - Fix alphabetical order of MAINTAINERS - Use arch/arm/dts/rk3588-armsom-sige7* in board MAINTAINERS - Remove spi flash related config - Move kernel dts to dts/upstream/src/arm64/rockchip/ MAINTAINERS | 1 + arch/arm/dts/rk3588-armsom-sige7-u-boot.dtsi | 28 + arch/arm/mach-rockchip/rk3588/Kconfig | 26 + board/armsom/sige7-rk3588/Kconfig | 12 + board/armsom/sige7-rk3588/MAINTAINERS | 7 + configs/sige7-rk3588_defconfig| 93 +++ doc/board/rockchip/rockchip.rst | 1 + .../arm64/rockchip/rk3588-armsom-sige7.dts| 691 ++ include/configs/sige7-rk3588.h| 15 + 9 files changed, 874 insertions(+) create mode 100644 arch/arm/dts/rk3588-armsom-sige7-u-boot.dtsi create mode 100644 board/armsom/sige7-rk3588/Kconfig create mode 100644 board/armsom/sige7-rk3588/MAINTAINERS create mode 100644 configs/sige7-rk3588_defconfig create mode 100644 dts/upstream/src/arm64/rockchip/rk3588-armsom-sige7.dts create mode 100644 include/configs/sige7-rk3588.h diff --git a/MAINTAINERS b/MAINTAINERS index 638b2fdd44..a2c799cb7d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -533,6 +533,7 @@ F: arch/arm/include/asm/arch-rockchip/ F: arch/arm/mach-rockchip/ F: board/amarula/vyasa-rk3288/ F: board/anbernic/rgxx3_rk3566/ +F: board/armsom/sige7-rk3588/ F: board/chipspark/popmetal_rk3288 F: board/engicam/px30_core/ F: board/firefly/ diff --git a/arch/arm/dts/rk3588-armsom-sige7-u-boot.dtsi b/arch/arm/dts/rk3588-armsom-sige7-u-boot.dtsi new file mode 100644 index 00..2c984d0147 --- /dev/null +++ b/arch/arm/dts/rk3588-armsom-sige7-u-boot.dtsi @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2024 ArmSoM Technology Co., Ltd. + */ + +#include "rk3588-u-boot.dtsi" + +&sdhci { + cap-mmc-highspeed; + mmc-hs200-1_8v; +}; + +&u2phy1 { + status = "okay"; +}; + +&u2phy1_otg { + status = "okay"; +}; + +&usbdp_phy1 { + status = "okay"; +}; + +&usb_host1_xhci { + dr_mode = "host"; + status = "okay"; +}; diff --git a/arch/arm/mach-rockchip/rk3588/Kconfig b/arch/arm/mach-rockchip/rk3588/Kconfig index 39049ab35a..4c14b0be1e 100644 --- a/arch/arm/mach-rockchip/rk3588/Kconfig +++ b/arch/arm/mach-rockchip/rk3588/Kconfig @@ -152,6 +152,31 @@ config TARGET_ROCK5B_RK3588 USB PD over USB Type-C Size: 100mm x 72mm (Pico-ITX form factor) +config TARGET_SIGE7_RK3588 + bool "ArmSoM Sige7 RK3588 board" + select BOARD_LATE_INIT + help + ArmSoM Sige7 is a Rockchip RK3588 based SBC (Single Board Computer) + by ArmSoM. + + There are two variants depending on the DRAM size : 8G and 16G. + + Specification: + + Rockchip Rk3588 SoC + 4x ARM Cortex-A76, 4x ARM Cortex-A55 + 8/16GB memory LPDDR4x + Mali G610MC4 GPU + 2x MIPI CSI 2 multiple lanes connector + 64GB/128GB on board eMMC + uSD slot + 1x USB 2.0 Type-A, 1x USB 3.0 Type-A, 1x USB 3.0 Type-C + 1x HDMI 2.1 output + 2x 2.5 Gbps Ethernet port + 40-pin IO header including UART, SPI and I2C + USB PD over USB Type-C + Size: 92mm x 62mm + config TARGET_QUARTZPRO64_RK3588 bool "Pine64 QuartzPro64 RK3588 board" select BOARD_LATE_INIT @@ -221,6 +246,7 @@ config ROCKCHIP_COMMON_STACK_ADDR config TEXT_BASE default 0x00a0 +source "board/armsom/sige7-rk3588/Kconfig" source "board/edgeble/neural-compute-module-6/Kconfig" source "board/friendlyelec/nanopc-t6-rk3588/Kconfig" source "board/pine64/quartzpro64-rk3588/Kconfig" diff --git a/board/armsom/sige7-rk3588/Kconfig b/board/armsom/sige7-rk3588/Kconfig new file mode 100644 index 00..793985f531 --- /dev/null +++ b/board/armsom/sige7-rk3588/Kconfig @@ -0,0 +1,12 @@ +if TARGET_SIGE7_RK3588 + +config SYS_BOARD + default "sige7-rk3588" + +config SYS_VENDOR + default "armsom" + +config SY
Re: [PATCH 14/15] MAINTAINERS: net-lwip: add myself as a maintainer
On Wed, 22 May 2024 at 19:04, Jerome Forissier wrote: > > Add myself as a maintainer for the lwIP network stack integration code > and network commands. The library code itself (i.e., most files under > lib/lwip/ except README, Makefile and integration files in u-boot) is > unmodified from upstream and therefore does not need a maintainer. > > Signed-off-by: Jerome Forissier > --- > MAINTAINERS | 11 +++ > 1 file changed, 11 insertions(+) > > diff --git a/MAINTAINERS b/MAINTAINERS > index 7a3b4d3712..0131f89ae3 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -1311,6 +1311,17 @@ F: drivers/net/ > F: include/net.h > F: net/ > > +NETWORK (LWIP) > +M: Jerome Forissier > +S: Maintained > +F: cmd/net-lwip.c > +F: configs/qemu_arm64_lwip_defconfig > +F: include/net-lwip.h > +F: lib/lwip/Makefile > +F: lib/lwip/README > +F: lib/lwip/u-boot/ > +F: net-lwip/ > + > NIOS > M: Thomas Chou > S: Maintained > -- > 2.40.1 > Reviewed-by: Ilias Apalodimas
Re: [PATCH 09/15] net-lwip: add support for EFI_HTTP_BOOT
Hi Jerome, On Wed, 22 May 2024 at 19:04, Jerome Forissier wrote: > > Implement the wget_with_dns() function which is needed by > CONFIG_EFI_HTTP_BOOT=y. Note that there is no dependency added on > CONFIG_CMD_DNS_LWIP because CONFIG_CMD_WGET_LWIP natively supports > hostname resolution. > > Signed-off-by: Jerome Forissier > --- > lib/efi_loader/Kconfig | 5 +++-- > net-lwip/wget.c| 16 > 2 files changed, 19 insertions(+), 2 deletions(-) > > diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig > index 430bb7f0f7..9d8dc8c756 100644 > --- a/lib/efi_loader/Kconfig > +++ b/lib/efi_loader/Kconfig > @@ -505,8 +505,9 @@ config EFI_RISCV_BOOT_PROTOCOL > > config EFI_HTTP_BOOT > bool "EFI HTTP Boot support" > - select CMD_DNS > - select CMD_WGET > + select CMD_DNS if NET > + select CMD_WGET if NET > + select CMD_WGET_LWIP if NET_LWIP > select BLKMAP > help > Enabling this option adds EFI HTTP Boot support. It allows to > diff --git a/net-lwip/wget.c b/net-lwip/wget.c > index 0ed8b77c47..a3e65dc80e 100644 > --- a/net-lwip/wget.c > +++ b/net-lwip/wget.c > @@ -166,3 +166,19 @@ int do_wget(struct cmd_tbl *cmdtp, int flag, int argc, > char * const argv[]) > > return CMD_RET_FAILURE; > } > + > +#if defined(CONFIG_EFI_HTTP_BOOT) > +int wget_with_dns(ulong dst_addr, char *uri) > +{ > + char addr_str[11]; > + struct cmd_tbl cmdtp = {}; > + char *argv[] = { "wget", addr_str, uri }; > + > + snprintf(addr_str, sizeof(addr_str), "0x%lx", dst_addr); > + > + if (do_wget(&cmdtp, 0, ARRAY_SIZE(argv), argv) == CMD_RET_SUCCESS) > + return 0; > + Calling a command directly feels a bit weird. Can we do this instead: - Split do_wget in patch #7 and carve out 2 functions. The first will prepare the arguments and the second will call httpc_get_file_dns() and run the loop - Once that's split you can use the newly split function here and avoid calling a command Thanks /Ilias > + return -1; > +} > +#endif > -- > 2.40.1 >
Re: [PATCH v2] board: rockchip: add ArmSoM Sige7 Rk3588 board
On 2024-05-22 20:03, Quentin Schulz wrote: > Hi Jianfeng Liu, > > On 5/22/24 6:58 PM, Jianfeng Liu wrote: > [...] >> Note that these commits: >> - e18e5e8188f2 (arm64: dts: rockchip: add USBDP phys on rk3588) >> - 6fca4edb93d3 (arm64: dts: rockchip: Add rk3588 GPU node) >> are not synced to u-boot, so I remove usb3 drd nodes and gpu from kernel >> devicetree. > [...]> diff --git > a/dts/upstream/src/arm64/rockchip/rk3588-armsom-sige7.dts > b/dts/upstream/src/arm64/rockchip/rk3588-armsom-sige7.dts >> new file mode 100644 >> index 00..c7b46536ec >> --- /dev/null >> +++ b/dts/upstream/src/arm64/rockchip/rk3588-armsom-sige7.dts > > Sorry, I failed to explain properly what was expected. > > dts/upstream should never be touched except with > dts/update-dts-subtree.sh script. > > Sadly, your board is not supported in v6.9 yet, only in the upcoming > v6.10 :/ > > So we have two options, we keep the dts in arch/arm/dts/ like you used > to do, until we merge v6.10 dts in U-Boot (probably for v2024.10?), or > we cherry-pick the changes for your board with dts/update-dts-subtree.sh > script, see the instructions in the docs Tom has started writing: > https://lore.kernel.org/u-boot/20240517174930.1028063-2-tr...@konsulko.com/ > I would very much like to see someone starting to look into the second > option :) > > However... it seems we'll likely need to also cherry-pick patches for > the GPU (should probably be straightforward as nothing would be using > the GPU anyway in U-Boot) and the USBDP PHY... but this one we would > need to update all -u-boot.dtsi for rk3588(s) boards that have it > already to make it use the new label/DT, make sure that the driver still > works... etc. Maybe not a small feat, but someone will have to do it at > some point anyway :) Thankfully updating the usb3 nodes and driver for RK3588 to match the versions used in v6.10 was already done as part of the "rockchip: Migrate RK3308, RK3328, RK356x and RK3588 to OF_UPSTREAM" series [1], in commit a129bbc77b6c ("rockchip: rk3588: Update USB3 related nodes in u-boot.dtsi") [2]. So the relevant nodes just needs to be removed from u-boot.dtsi files at some point after dts/upstream has been updated to match v6.10 :-) [1] https://patchwork.ozlabs.org/cover/1931378/ [2] https://source.denx.de/u-boot/u-boot/-/commit/a129bbc77b6cadc191d6f5d1fd8da96964baa029 Regards, Jonas > > You'd be the first one to do this cherry-picking into dts/upstream, so > it'd be really interesting to us if you could provide feedback on what > is unclear/not working, etc... so we can update the documentation or fix > tools if they were to be insufficient. > > Looking forward to your next patch, > Cheers, > Quentin
Re: [PATCH 10/15] test: dm: dsa, eth: disable tests when CONFIG_NET_LWIP=y
Hi Jerome, On Wed, 22 May 2024 at 19:04, Jerome Forissier wrote: > > Some sandbox tests make strong assumptions on how the network stack is > implemented. For example, the ping tests assume that ARP resolution > occurs upon sending out the ICMP packet. This is not always the case > with the lwIP stack which can cache ARP information. > Therefore, disable these tests when CONFIG_NET_LWIP is enabled. Is the ARP Caching the only issue? U-Boot isn't supposed to use the network stack that much, so it might be a better idea to disable arp-caching in LWIP (assuming it's doable). We might even get a few size of bytes back Cheers /Ilias > > Signed-off-by: Jerome Forissier > --- > test/dm/dsa.c | 2 ++ > test/dm/eth.c | 4 > 2 files changed, 6 insertions(+) > > diff --git a/test/dm/dsa.c b/test/dm/dsa.c > index c857106eaf..147e2a4afe 100644 > --- a/test/dm/dsa.c > +++ b/test/dm/dsa.c > @@ -59,6 +59,7 @@ static int dm_test_dsa_probe(struct unit_test_state *uts) > > DM_TEST(dm_test_dsa_probe, UT_TESTF_SCAN_FDT); > > +#if !defined(CONFIG_NET_LWIP) > /* This test sends ping requests with the local address through each DSA port > * via the sandbox DSA master Eth. > */ > @@ -80,3 +81,4 @@ static int dm_test_dsa(struct unit_test_state *uts) > } > > DM_TEST(dm_test_dsa, UT_TESTF_SCAN_FDT); > +#endif /* !defined(CONFIG_NET_LWIP) */ > diff --git a/test/dm/eth.c b/test/dm/eth.c > index bb3dcc6b95..cf97b1c1ab 100644 > --- a/test/dm/eth.c > +++ b/test/dm/eth.c > @@ -170,6 +170,7 @@ static int dm_test_ip6_make_lladdr(struct unit_test_state > *uts) > DM_TEST(dm_test_ip6_make_lladdr, UT_TESTF_SCAN_FDT); > #endif > > +#if !defined(CONFIG_NET_LWIP) > static int dm_test_eth(struct unit_test_state *uts) > { > net_ping_ip = string_to_ip("1.1.2.2"); > @@ -298,6 +299,7 @@ static int dm_test_eth_act(struct unit_test_state *uts) > return 0; > } > DM_TEST(dm_test_eth_act, UT_TESTF_SCAN_FDT); > +#endif /* !CONFIG_NET_LWIP */ > > /* Ensure that all addresses are loaded properly */ > static int dm_test_ethaddr(struct unit_test_state *uts) > @@ -332,6 +334,7 @@ static int dm_test_ethaddr(struct unit_test_state *uts) > } > DM_TEST(dm_test_ethaddr, UT_TESTF_SCAN_FDT); > > +#if !defined(CONFIG_NET_LWIP) > /* The asserts include a return on fail; cleanup in the caller */ > static int _dm_test_eth_rotate1(struct unit_test_state *uts) > { > @@ -616,6 +619,7 @@ static int dm_test_eth_async_ping_reply(struct > unit_test_state *uts) > } > > DM_TEST(dm_test_eth_async_ping_reply, UT_TESTF_SCAN_FDT); > +#endif /* !CONFIG_NET_LWIP */ > > #if IS_ENABLED(CONFIG_IPV6_ROUTER_DISCOVERY) > > -- > 2.40.1 >
Re: [PATCH v2] board: rockchip: add ArmSoM Sige7 Rk3588 board
Hi Jianfeng Liu, On 5/22/24 6:58 PM, Jianfeng Liu wrote: [...] Note that these commits: - e18e5e8188f2 (arm64: dts: rockchip: add USBDP phys on rk3588) - 6fca4edb93d3 (arm64: dts: rockchip: Add rk3588 GPU node) are not synced to u-boot, so I remove usb3 drd nodes and gpu from kernel devicetree. [...]> diff --git a/dts/upstream/src/arm64/rockchip/rk3588-armsom-sige7.dts b/dts/upstream/src/arm64/rockchip/rk3588-armsom-sige7.dts new file mode 100644 index 00..c7b46536ec --- /dev/null +++ b/dts/upstream/src/arm64/rockchip/rk3588-armsom-sige7.dts Sorry, I failed to explain properly what was expected. dts/upstream should never be touched except with dts/update-dts-subtree.sh script. Sadly, your board is not supported in v6.9 yet, only in the upcoming v6.10 :/ So we have two options, we keep the dts in arch/arm/dts/ like you used to do, until we merge v6.10 dts in U-Boot (probably for v2024.10?), or we cherry-pick the changes for your board with dts/update-dts-subtree.sh script, see the instructions in the docs Tom has started writing: https://lore.kernel.org/u-boot/20240517174930.1028063-2-tr...@konsulko.com/. I would very much like to see someone starting to look into the second option :) However... it seems we'll likely need to also cherry-pick patches for the GPU (should probably be straightforward as nothing would be using the GPU anyway in U-Boot) and the USBDP PHY... but this one we would need to update all -u-boot.dtsi for rk3588(s) boards that have it already to make it use the new label/DT, make sure that the driver still works... etc. Maybe not a small feat, but someone will have to do it at some point anyway :) You'd be the first one to do this cherry-picking into dts/upstream, so it'd be really interesting to us if you could provide feedback on what is unclear/not working, etc... so we can update the documentation or fix tools if they were to be insufficient. Looking forward to your next patch, Cheers, Quentin
[PATCH v2] clk: rockchip: rk3588: Set SPLL frequency during SPL stage
From: Heiko Stuebner All parts expect the SPLL to run at 702MHz. In U-Boot it's the SPLL_HZ declaring this rate and in the kernel it's a fixed clock definition. While everything is expecting 702MHz, the SPLL is not running that frequency when coming from the bootrom though, instead it's running at 351MHz and the vendor-u-boot just sets it to the expected frequency. The SPLL itself is located inside the secure-BUSCRU and in theory accessible as an SCMI clock, though this requires an unknown amount of cooperation from trusted-firmware to set at a later stage, though during the SPL stage we can still access the relevant CRU directly. The SPLL is for example necessary for the DSI controllers to produce output. As the SPLL is "just" another rk3588 pll, just set the desired rate directly during the SPL stage. Tested on rk3588-rock5b and rk3588-tiger by reading back the PLL rate and also observing working DSI output with this change. Fixes: 6737771600d4 ("rockchip: rk3588: Add support for sdmmc clocks in SPL") Suggested-by: Andy Yan Signed-off-by: Heiko Stuebner Cc: Jonas Karlman Cc: Quentin Schulz --- changes in v2: - use correct name for SBUSCRU - use dedicated constants for SBUSCRU registers - add comment to make it explicit that the SPLL is in a different CRU .../include/asm/arch-rockchip/cru_rk3588.h| 4 +++ drivers/clk/rockchip/clk_rk3588.c | 30 +-- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/arch/arm/include/asm/arch-rockchip/cru_rk3588.h b/arch/arm/include/asm/arch-rockchip/cru_rk3588.h index a4507e5fdd7..a0e54d39654 100644 --- a/arch/arm/include/asm/arch-rockchip/cru_rk3588.h +++ b/arch/arm/include/asm/arch-rockchip/cru_rk3588.h @@ -29,6 +29,7 @@ enum rk3588_pll_id { V0PLL, AUPLL, PPLL, + SPLL, PLL_COUNT, }; @@ -150,6 +151,9 @@ struct pll_rate_table { #define RK3588_DSU_CLKGATE_CON(x) ((x) * 0x4 + RK3588_DSU_CRU_BASE + 0x800) #define RK3588_DSU_SOFTRST_CON(x) ((x) * 0x4 + RK3588_DSU_CRU_BASE + 0xa00) +#define RK3588_SBUSCRU_SPLL_CON(x) ((x) * 0x4 + 0x220) +#define RK3588_SBUSCRU_MODE_CON0 0x280 + enum { /* CRU_CLK_SEL8_CON */ ACLK_LOW_TOP_ROOT_SRC_SEL_SHIFT = 14, diff --git a/drivers/clk/rockchip/clk_rk3588.c b/drivers/clk/rockchip/clk_rk3588.c index 4c611a39049..c41c9be6aa3 100644 --- a/drivers/clk/rockchip/clk_rk3588.c +++ b/drivers/clk/rockchip/clk_rk3588.c @@ -37,6 +37,7 @@ static struct rockchip_pll_rate_table rk3588_pll_rates[] = { RK3588_PLL_RATE(78600, 1, 131, 2, 0), RK3588_PLL_RATE(74250, 4, 495, 2, 0), RK3588_PLL_RATE(722534400, 8, 963, 2, 24850), + RK3588_PLL_RATE(70200, 3, 351, 2, 0), RK3588_PLL_RATE(6, 2, 200, 2, 0), RK3588_PLL_RATE(59400, 2, 198, 2, 0), RK3588_PLL_RATE(2, 3, 400, 4, 0), @@ -65,6 +66,15 @@ static struct rockchip_pll_clock rk3588_pll_clks[] = { RK3588_MODE_CON0, 0, 15, 0, rk3588_pll_rates), [PPLL] = PLL(pll_rk3588, PLL_PPLL, RK3588_PMU_PLL_CON(128), RK3588_MODE_CON0, 10, 15, 0, rk3588_pll_rates), +#ifdef CONFIG_SPL_BUILD + /* +* The SPLL is part of the SBUSCRU, not the main CRU and as +* such only directly accessible during the SPL stage. +*/ + [SPLL] = PLL(pll_rk3588, 0, RK3588_SBUSCRU_SPLL_CON(0), +RK3588_SBUSCRU_MODE_CON0, 0, 15, 0, rk3588_pll_rates), +#endif + }; #ifndef CONFIG_SPL_BUILD @@ -2044,6 +2054,7 @@ U_BOOT_DRIVER(rockchip_rk3588_cru) = { #ifdef CONFIG_SPL_BUILD #define SCRU_BASE 0xfd7d +#define SBUSCRU_BASE 0xfd7d8000 static ulong rk3588_scru_clk_get_rate(struct clk *clk) { @@ -2118,15 +2129,28 @@ static ulong rk3588_scru_clk_set_rate(struct clk *clk, ulong rate) return rk3588_scru_clk_get_rate(clk); } +static int rk3588_scru_clk_probe(struct udevice *dev) +{ + int ret; + + ret = rockchip_pll_set_rate(&rk3588_pll_clks[SPLL], + (void *)SBUSCRU_BASE, SPLL, SPLL_HZ); + if (ret) + debug("%s setting spll rate failed %d\n", __func__, ret); + + return 0; +} + static const struct clk_ops rk3588_scru_clk_ops = { .get_rate = rk3588_scru_clk_get_rate, .set_rate = rk3588_scru_clk_set_rate, }; U_BOOT_DRIVER(rockchip_rk3588_scru) = { - .name = "rockchip_rk3588_scru", - .id = UCLASS_CLK, - .ops = &rk3588_scru_clk_ops, + .name = "rockchip_rk3588_scru", + .id = UCLASS_CLK, + .ops= &rk3588_scru_clk_ops, + .probe = rk3588_scru_clk_probe, }; static int rk3588_scmi_spl_glue_bind(struct udevice *dev) -- 2.39.2
RE: [PATCH 1/1] Added arm64 assembly for examples/api crt0
Hi Tom, BLK is currently a dependency for EFI_LOADER as shown in the snippet from lib/efi_loader/Kconfig below. Perhaps the question is why EFI_LOADER requires a block device? If I remove this depends on BLK line, then I can enable EFI and successfully simulate the EFI hello world on my test design. config EFI_LOADER bool "Support running UEFI applications" depends on OF_LIBFDT && ( \ ARM && (SYS_CPU = arm1136 || \ SYS_CPU = arm1176 || \ SYS_CPU = armv7 || \ SYS_CPU = armv8) || \ X86 || RISCV || SANDBOX) # We need EFI_STUB_64BIT to be set on x86_64 with EFI_STUB depends on !EFI_STUB || !X86_64 || EFI_STUB_64BIT # We need EFI_STUB_32BIT to be set on x86_32 with EFI_STUB depends on !EFI_STUB || !X86 || X86_64 || EFI_STUB_32BIT depends on BLK depends on !EFI_APP default y if !ARM || SYS_CPU = armv7 || SYS_CPU = armv8 Thanks. -Original Message- From: Tom Rini Sent: Wednesday, May 22, 2024 10:39 AM To: Brunham, Kalen Cc: U-Boot@lists.denx.de; Heinrich Schuchardt Subject: Re: [PATCH 1/1] Added arm64 assembly for examples/api crt0 On Wed, May 22, 2024 at 01:25:51PM +, Brunham, Kalen wrote: > Hi Tom, > > I'm using a defconfig that does not enable any of the configs listed on the > default likes for config BLK (MMC, USB, SCSI, etc.), but I do have DM > enabled. I cannot however enable BLK as CONFIG_BLK=y is ignored. My current > hypothesis is that BLK is being forced to N by the select BLK in other > Kconfig files, but I'm not sure. > > Here's the Kconfig for drivers/block: > > config BLK > bool # "Support block devices" > depends on DM > default y if MMC || USB || SCSI || NVME || IDE || AHCI || SATA > default y if EFI_MEDIA || VIRTIO_BLK || PVBLOCK > > My current flow is: > make mrproper > make socfpga_agilex5_defconfig > ./scripts/kconfig/merge_config.sh -O ./ ./.config ../../my_uboot_config.txt > > Here my_uboot_config.txt hsd: > > CONFIG_MMC=n > CONFIG_USB=n > CONFIG_DM_MMC=n > CONFIG_SPL_DM_MMC=n > CONFIG_BLK=y > CONFIG_EFI_LOADER=y > CONFIG_CMD_BOOTEFI=y > CONFIG_EFI_LOADER=y > CONFIG_CMD_BOOTEFI_HELLO_COMPILE=y > CONFIG_CMD_BOOTEFI_HELLO=y > > The only way I was able to get BLK set to Y was to add another default like > || DM_SPI_FLASH, since I do enable SPI flash in this config. And why are you trying to enable BLK without any block devices? -- Tom
[PATCH v2 10/10] doc: New documentation for qemu-xtensa
Introduce the board and provide instructions on how to get it work. Signed-off-by: Jiaxun Yang --- doc/board/emulation/index.rst | 1 + doc/board/emulation/qemu-xtensa.rst | 33 + 2 files changed, 34 insertions(+) diff --git a/doc/board/emulation/index.rst b/doc/board/emulation/index.rst index d3d6b8f3d86b..98a0b26ad245 100644 --- a/doc/board/emulation/index.rst +++ b/doc/board/emulation/index.rst @@ -14,3 +14,4 @@ Emulation qemu-ppce500 qemu-riscv qemu-x86 + qemu-xtensa diff --git a/doc/board/emulation/qemu-xtensa.rst b/doc/board/emulation/qemu-xtensa.rst new file mode 100644 index ..fdab6d7c439d --- /dev/null +++ b/doc/board/emulation/qemu-xtensa.rst @@ -0,0 +1,33 @@ +.. SPDX-License-Identifier: GPL-2.0+ +.. Copyright (C) 2024 Jiaxun Yang + +QEMU Xtensa +=== + +QEMU for Xtensa supports a special 'virt' machine designed for emulation and +virtualization purposes. This document describes how to run U-Boot under it. + +The QEMU virt machine models a generic Xtensa virtual machine with PCI Bus +and Xtensa ISS simcall semihosting support. It supports many different Xtensa +CPU configuration. Currently, only dc232b variant is tested against U-Boot. + +Building U-Boot +--- +Set the CROSS_COMPILE environment variable as usual, and run: + +make qemu-xtensa-dc232b_defconfig +make + +Note that Xtensa's toolchain is bounded to CPU configuration, you must use +the toolchain built for exactly the same CPU configuration as you selected +in U-Boot. + +Running U-Boot +-- +The minimal QEMU command line to get U-Boot up and running is: + +qemu-system-xtensa -nographic -machine virt -cpu dc232b -semihosting -kernel ./u-boot.elf + +You many change cpu option to match your U-Boot CPU type configuration. +semihosting option is mandatory because this is the only way to interact +with U-Boot in command line. -- 2.43.0