[PATCH 2/2] board: apalis-imx8: add new 8gb product variant
Marcel Ziswiler
marcel.ziswiler at toradex.com
Tue May 10 17:39:21 CEST 2022
On Mon, 2022-05-09 at 18:58 +0200, Philippe Schenker wrote:
> From: Philippe Schenker <philippe.schenker at toradex.com>
>
> Add the new Apalis iMX8 product variant
>
> 0067: Apalis iMX8 QuadMax 8GB Wi-Fi / BT IT
>
> the only difference to the product
>
> 0037 Apalis iMX8 QuadMax 4GB Wi-Fi / BT IT
>
> is the 8gb of RAM. Toradex strategy to choose the correct RAM timing in
> SCFW is by fuses in the user area telling which RAM timing to load.
>
> This commit makes use of this information to set the correct size of
> the RAM and therefore distinguish between the new 0067 and 0037 product
>
> Signed-off-by: Philippe Schenker <philippe.schenker at toradex.com>
> Reviewed-by: Francesco Dolcini <francesco.dolcini at toradex.com>
Acked-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
> ---
>
> board/toradex/apalis-imx8/apalis-imx8.c | 81 +++++++++++++++++++++++--
> 1 file changed, 77 insertions(+), 4 deletions(-)
>
> diff --git a/board/toradex/apalis-imx8/apalis-imx8.c b/board/toradex/apalis-imx8/apalis-imx8.c
> index 04877fcd94..408198843f 100644
> --- a/board/toradex/apalis-imx8/apalis-imx8.c
> +++ b/board/toradex/apalis-imx8/apalis-imx8.c
> @@ -18,6 +18,7 @@
> #include <env.h>
> #include <errno.h>
> #include <linux/libfdt.h>
> +#include <linux/bitops.h>
>
> #include "../common/tdx-cfg-block.h"
>
> @@ -28,22 +29,75 @@ DECLARE_GLOBAL_DATA_PTR;
> (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | \
> (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT))
>
> +#define TDX_USER_FUSE_BLOCK1_A 276
> +#define TDX_USER_FUSE_BLOCK1_B 277
> +#define TDX_USER_FUSE_BLOCK2_A 278
> +#define TDX_USER_FUSE_BLOCK2_B 279
> +
> static iomux_cfg_t uart1_pads[] = {
> SC_P_UART1_RX | MUX_PAD_CTRL(UART_PAD_CTRL),
> SC_P_UART1_TX | MUX_PAD_CTRL(UART_PAD_CTRL),
> };
>
> +struct tdx_user_fuses {
> + u16 pid4;
> + u16 vers;
> + u8 ramid;
> +};
> +
> static void setup_iomux_uart(void)
> {
> imx8_iomux_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads));
> }
>
> +static uint32_t do_get_tdx_user_fuse(int a, int b)
> +{
> + sc_err_t sciErr;
> + u32 val_a = 0;
> + u32 val_b = 0;
> +
> + sciErr = sc_misc_otp_fuse_read(-1, a, &val_a);
> + if (sciErr != SC_ERR_NONE) {
> + printf("Error reading out user fuse %d\n", a);
> + return 0;
> + }
> +
> + sciErr = sc_misc_otp_fuse_read(-1, b, &val_b);
> + if (sciErr != SC_ERR_NONE) {
> + printf("Error reading out user fuse %d\n", b);
> + return 0;
> + }
> +
> + return ((val_a & 0xffff) << 16) | (val_b & 0xffff);
> +}
> +
> +static void get_tdx_user_fuse(struct tdx_user_fuses *tdxuserfuse)
> +{
> + u32 fuse_block;
> +
> + fuse_block = do_get_tdx_user_fuse(TDX_USER_FUSE_BLOCK2_A,
> + TDX_USER_FUSE_BLOCK2_B);
> +
> + /*
> + * Fuse block 2 acts as a backup area, if this reads 0 we want to
> + * use fuse block 1
> + */
> + if (fuse_block == 0)
> + fuse_block = do_get_tdx_user_fuse(TDX_USER_FUSE_BLOCK1_A,
> + TDX_USER_FUSE_BLOCK1_B);
> +
> + tdxuserfuse->pid4 = (fuse_block >> 18) & GENMASK(13, 0);
> + tdxuserfuse->vers = (fuse_block >> 4) & GENMASK(13, 0);
> + tdxuserfuse->ramid = fuse_block & GENMASK(3, 0);
> +}
> +
> void board_mem_get_layout(u64 *phys_sdram_1_start,
> u64 *phys_sdram_1_size,
> u64 *phys_sdram_2_start,
> u64 *phys_sdram_2_size)
> {
> u32 is_quadplus = 0, val = 0;
> + struct tdx_user_fuses tdxramfuses;
> sc_err_t scierr = sc_misc_otp_fuse_read(-1, 6, &val);
>
> if (scierr == SC_ERR_NONE) {
> @@ -51,14 +105,33 @@ void board_mem_get_layout(u64 *phys_sdram_1_start,
> is_quadplus = ((val >> 4) & 0x3) != 0x0;
> }
>
> + get_tdx_user_fuse(&tdxramfuses);
> +
> *phys_sdram_1_start = PHYS_SDRAM_1;
> *phys_sdram_1_size = PHYS_SDRAM_1_SIZE;
> *phys_sdram_2_start = PHYS_SDRAM_2;
> - if (is_quadplus)
> - /* Our QP based SKUs only have 2 GB RAM (PHYS_SDRAM_1_SIZE) */
> +
> + switch (tdxramfuses.ramid) {
> + case 1:
> + *phys_sdram_2_size = SZ_2G;
> + break;
> + case 2:
> *phys_sdram_2_size = 0x0UL;
> - else
> - *phys_sdram_2_size = PHYS_SDRAM_2_SIZE;
> + break;
> + case 3:
> + *phys_sdram_2_size = SZ_2G;
> + break;
> + case 4:
> + *phys_sdram_2_size = SZ_4G + SZ_2G;
> + break;
> + default:
> + if (is_quadplus)
> + /* Our QP based SKUs only have 2 GB RAM (PHYS_SDRAM_1_SIZE) */
> + *phys_sdram_2_size = 0x0UL;
> + else
> + *phys_sdram_2_size = PHYS_SDRAM_2_SIZE;
> + break;
> + }
> }
>
> int board_early_init_f(void)
More information about the U-Boot
mailing list