summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilippe Schenker <philippe.schenker@toradex.com>2022-05-09 16:15:09 +0200
committerPhilippe Schenker <philippe.schenker@toradex.com>2022-05-09 16:15:09 +0200
commit44d5a7a61b4dacb105afb5bd1cd30036ba603581 (patch)
tree698ad72d9619c0b80e78d518031903e3e8bd75a6
parentfa06f0bc4b997f780385b75a652165d8a54f0174 (diff)
board: apalis-imx8: add new 8gb product variant
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@toradex.com>
-rw-r--r--board/toradex/apalis-imx8/apalis-imx8.c81
1 files changed, 77 insertions, 4 deletions
diff --git a/board/toradex/apalis-imx8/apalis-imx8.c b/board/toradex/apalis-imx8/apalis-imx8.c
index 7d9dbcb6b0..b9e390003c 100644
--- a/board/toradex/apalis-imx8/apalis-imx8.c
+++ b/board/toradex/apalis-imx8/apalis-imx8.c
@@ -17,6 +17,7 @@
#include <env.h>
#include <errno.h>
#include <linux/libfdt.h>
+#include <linux/bitops.h>
#include <mmc.h>
#include <power-domain.h>
@@ -44,11 +45,22 @@ DECLARE_GLOBAL_DATA_PTR;
(SC_PAD_28FDSOI_PS_PD << PADRING_PULL_SHIFT) | \
(SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_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
+
typedef enum {
PCB_VERSION_1_0,
PCB_VERSION_1_1
} pcb_rev_t;
+struct tdx_user_fuses {
+ uint16_t pid4;
+ uint16_t vers;
+ uint8_t ramid;
+};
+
static iomux_cfg_t pcb_vers_detect[] = {
SC_P_MIPI_DSI0_GPIO0_00 | MUX_MODE_ALT(3) | MUX_PAD_CTRL(PCB_VERS_DETECT),
SC_P_MIPI_DSI0_GPIO0_01 | MUX_MODE_ALT(3) | MUX_PAD_CTRL(PCB_VERS_DETECT),
@@ -69,12 +81,54 @@ 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;
+ uint32_t val_a = 0;
+ uint32_t 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)
+{
+ uint32_t 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(uint64_t *phys_sdram_1_start,
uint64_t *phys_sdram_1_size,
uint64_t *phys_sdram_2_start,
uint64_t *phys_sdram_2_size)
{
uint32_t 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) {
@@ -82,14 +136,33 @@ void board_mem_get_layout(uint64_t *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)