* [PATCH 1/9] ARM: i.MX8M: move TF-A chainload functions in <mach/xload.h>
2022-08-05 12:54 [PATCH 0/9] ARM: i.MX8MN: clean up and enable imx-usb-loader Ahmad Fatoum
@ 2022-08-05 12:54 ` Ahmad Fatoum
2022-08-05 12:54 ` [PATCH 2/9] ARM: i.MX8M: imx8mn-evk: use generic imx8mn_load_and_start_image_via_tfa Ahmad Fatoum
` (9 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Ahmad Fatoum @ 2022-08-05 12:54 UTC (permalink / raw)
To: barebox; +Cc: mfe, Ahmad Fatoum
We already have <mach/xload.h> with related functions, so reuse that
header instead of adding a new one.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
arch/arm/boards/nxp-imx8mm-evk/lowlevel.c | 2 +-
arch/arm/boards/nxp-imx8mp-evk/lowlevel.c | 1 -
arch/arm/boards/protonic-imx8m/lowlevel-prt8mm.c | 1 -
arch/arm/mach-imx/atf.c | 1 -
arch/arm/mach-imx/include/mach/xload.h | 3 +++
include/soc/imx8m.h | 9 ---------
6 files changed, 4 insertions(+), 13 deletions(-)
delete mode 100644 include/soc/imx8m.h
diff --git a/arch/arm/boards/nxp-imx8mm-evk/lowlevel.c b/arch/arm/boards/nxp-imx8mm-evk/lowlevel.c
index d13474602cb2..888bdd079083 100644
--- a/arch/arm/boards/nxp-imx8mm-evk/lowlevel.c
+++ b/arch/arm/boards/nxp-imx8mm-evk/lowlevel.c
@@ -15,7 +15,7 @@
#include <mach/iomux-mx8mm.h>
#include <mach/imx8m-ccm-regs.h>
#include <mfd/bd71837.h>
-#include <soc/imx8m.h>
+#include <mach/xload.h>
#include <soc/imx8m/ddr.h>
#include <image-metadata.h>
diff --git a/arch/arm/boards/nxp-imx8mp-evk/lowlevel.c b/arch/arm/boards/nxp-imx8mp-evk/lowlevel.c
index df4925f533e7..338c8024c4a1 100644
--- a/arch/arm/boards/nxp-imx8mp-evk/lowlevel.c
+++ b/arch/arm/boards/nxp-imx8mp-evk/lowlevel.c
@@ -22,7 +22,6 @@
#include <mfd/pca9450.h>
#include <soc/imx8m/ddr.h>
#include <soc/fsl/fsl_udc.h>
-#include <soc/imx8m.h>
extern char __dtb_z_imx8mp_evk_start[];
diff --git a/arch/arm/boards/protonic-imx8m/lowlevel-prt8mm.c b/arch/arm/boards/protonic-imx8m/lowlevel-prt8mm.c
index c3272654265a..bfae39ea522e 100644
--- a/arch/arm/boards/protonic-imx8m/lowlevel-prt8mm.c
+++ b/arch/arm/boards/protonic-imx8m/lowlevel-prt8mm.c
@@ -14,7 +14,6 @@
#include <mach/xload.h>
#include <soc/fsl/fsl_udc.h>
#include <soc/imx8m/ddr.h>
-#include <soc/imx8m.h>
extern char __dtb_z_imx8mm_prt8mm_start[];
diff --git a/arch/arm/mach-imx/atf.c b/arch/arm/mach-imx/atf.c
index d9aaee1bc621..8fc523d3de61 100644
--- a/arch/arm/mach-imx/atf.c
+++ b/arch/arm/mach-imx/atf.c
@@ -7,7 +7,6 @@
#include <mach/generic.h>
#include <mach/xload.h>
#include <mach/romapi.h>
-#include <soc/imx8m.h>
#include <soc/fsl/fsl_udc.h>
/**
diff --git a/arch/arm/mach-imx/include/mach/xload.h b/arch/arm/mach-imx/include/mach/xload.h
index 03ec23ebbdb0..cfc52a94879d 100644
--- a/arch/arm/mach-imx/include/mach/xload.h
+++ b/arch/arm/mach-imx/include/mach/xload.h
@@ -13,6 +13,9 @@ int imx8m_esdhc_load_image(int instance, bool start);
int imx8mn_esdhc_load_image(int instance, bool start);
int imx8mp_esdhc_load_image(int instance, bool start);
+void imx8mm_load_and_start_image_via_tfa(void);
+void imx8mp_load_and_start_image_via_tfa(void);
+
int imx_image_size(void);
int piggydata_size(void);
diff --git a/include/soc/imx8m.h b/include/soc/imx8m.h
deleted file mode 100644
index 15f7a4c2c001..000000000000
--- a/include/soc/imx8m.h
+++ /dev/null
@@ -1,9 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-
-#ifndef __MACH_IMX8M_H__
-#define __MACH_IMX8M_H__
-
-void imx8mm_load_and_start_image_via_tfa(void);
-void imx8mp_load_and_start_image_via_tfa(void);
-
-#endif
--
2.30.2
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 2/9] ARM: i.MX8M: imx8mn-evk: use generic imx8mn_load_and_start_image_via_tfa
2022-08-05 12:54 [PATCH 0/9] ARM: i.MX8MN: clean up and enable imx-usb-loader Ahmad Fatoum
2022-08-05 12:54 ` [PATCH 1/9] ARM: i.MX8M: move TF-A chainload functions in <mach/xload.h> Ahmad Fatoum
@ 2022-08-05 12:54 ` Ahmad Fatoum
2022-08-05 12:54 ` [PATCH 3/9] ARM: i.MX8MN: add SDPS barebox-side support Ahmad Fatoum
` (8 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Ahmad Fatoum @ 2022-08-05 12:54 UTC (permalink / raw)
To: barebox; +Cc: mfe, Ahmad Fatoum
Like already done for i.MX8MM and i.MX8MP, we can considerably reduce
i.MX8MN board code duplication by moving the TF-A loading and jumping
code into common helpers.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
arch/arm/boards/nxp-imx8mn-evk/lowlevel.c | 31 +------------------
arch/arm/mach-imx/atf.c | 36 +++++++++++++++++++++++
arch/arm/mach-imx/include/mach/xload.h | 1 +
3 files changed, 38 insertions(+), 30 deletions(-)
diff --git a/arch/arm/boards/nxp-imx8mn-evk/lowlevel.c b/arch/arm/boards/nxp-imx8mn-evk/lowlevel.c
index 9e44d343b7ed..ddc6e4fd2b29 100644
--- a/arch/arm/boards/nxp-imx8mn-evk/lowlevel.c
+++ b/arch/arm/boards/nxp-imx8mn-evk/lowlevel.c
@@ -132,11 +132,7 @@ extern struct dram_timing_info imx8mn_evk_ddr4_timing, imx8mn_evk_lpddr4_timing;
static void start_atf(void)
{
struct dram_timing_info *dram_timing = &imx8mn_evk_lpddr4_timing;
- size_t bl31_size;
- const u8 *bl31;
- enum bootsource src;
void *i2c;
- int instance;
int ret;
/*
@@ -163,32 +159,7 @@ static void start_atf(void)
imx8mn_ddr_init(dram_timing, dram_timing->dram_type);
- imx8mn_get_boot_source(&src, &instance);
- switch (src) {
- case BOOTSOURCE_MMC:
- imx8mn_esdhc_load_image(instance, false);
- break;
- default:
- printf("Unhandled bootsource BOOTSOURCE_%d\n", src);
- hang();
- }
-
- /*
- * On completion the TF-A will jump to MX8M_ATF_BL33_BASE_ADDR
- * in EL2. Copy the image there, but replace the PBL part of
- * that image with ourselves. On a high assurance boot only the
- * currently running code is validated and contains the checksum
- * for the piggy data, so we need to ensure that we are running
- * the same code in DRAM.
- */
- memcpy((void *)MX8M_ATF_BL33_BASE_ADDR,
- __image_start, barebox_pbl_size);
-
- get_builtin_firmware(imx8mn_bl31_bin, &bl31, &bl31_size);
-
- imx8mn_atf_load_bl31(bl31, bl31_size);
-
- /* not reached */
+ imx8mn_load_and_start_image_via_tfa();
}
/*
diff --git a/arch/arm/mach-imx/atf.c b/arch/arm/mach-imx/atf.c
index 8fc523d3de61..bb9e04c9746b 100644
--- a/arch/arm/mach-imx/atf.c
+++ b/arch/arm/mach-imx/atf.c
@@ -168,3 +168,39 @@ void imx8mp_load_and_start_image_via_tfa(void)
/* not reached */
}
+
+void imx8mn_load_and_start_image_via_tfa(void)
+{
+ size_t bl31_size;
+ const u8 *bl31;
+ enum bootsource src;
+ int instance;
+
+ imx8mn_get_boot_source(&src, &instance);
+ switch (src) {
+ case BOOTSOURCE_MMC:
+ imx8mn_esdhc_load_image(instance, false);
+ break;
+ default:
+ printf("Unhandled bootsource BOOTSOURCE_%d\n", src);
+ hang();
+ }
+
+
+ /*
+ * On completion the TF-A will jump to MX8M_ATF_BL33_BASE_ADDR
+ * in EL2. Copy the image there, but replace the PBL part of
+ * that image with ourselves. On a high assurance boot only the
+ * currently running code is validated and contains the checksum
+ * for the piggy data, so we need to ensure that we are running
+ * the same code in DRAM.
+ */
+ memcpy((void *)MX8M_ATF_BL33_BASE_ADDR,
+ __image_start, barebox_pbl_size);
+
+ get_builtin_firmware(imx8mn_bl31_bin, &bl31, &bl31_size);
+
+ imx8mn_atf_load_bl31(bl31, bl31_size);
+
+ /* not reached */
+}
diff --git a/arch/arm/mach-imx/include/mach/xload.h b/arch/arm/mach-imx/include/mach/xload.h
index cfc52a94879d..3090c9c83bd7 100644
--- a/arch/arm/mach-imx/include/mach/xload.h
+++ b/arch/arm/mach-imx/include/mach/xload.h
@@ -14,6 +14,7 @@ int imx8mn_esdhc_load_image(int instance, bool start);
int imx8mp_esdhc_load_image(int instance, bool start);
void imx8mm_load_and_start_image_via_tfa(void);
+void imx8mn_load_and_start_image_via_tfa(void);
void imx8mp_load_and_start_image_via_tfa(void);
int imx_image_size(void);
--
2.30.2
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 3/9] ARM: i.MX8MN: add SDPS barebox-side support
2022-08-05 12:54 [PATCH 0/9] ARM: i.MX8MN: clean up and enable imx-usb-loader Ahmad Fatoum
2022-08-05 12:54 ` [PATCH 1/9] ARM: i.MX8M: move TF-A chainload functions in <mach/xload.h> Ahmad Fatoum
2022-08-05 12:54 ` [PATCH 2/9] ARM: i.MX8M: imx8mn-evk: use generic imx8mn_load_and_start_image_via_tfa Ahmad Fatoum
@ 2022-08-05 12:54 ` Ahmad Fatoum
2022-08-05 12:54 ` [PATCH 4/9] ARM: i.MX8MN: evk: simplify DDR4/LPDDR4 selection code Ahmad Fatoum
` (7 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Ahmad Fatoum @ 2022-08-05 12:54 UTC (permalink / raw)
To: barebox; +Cc: mfe, Ahmad Fatoum
i.MX8MN SoCs offer the same boot ROM API as the i.MX8MP and we already
have an imx8mn_bootrom_load_image() providing access to it. Wire it in
to allow using SDPS with barebox.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
arch/arm/mach-imx/atf.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/arch/arm/mach-imx/atf.c b/arch/arm/mach-imx/atf.c
index bb9e04c9746b..a4c658283006 100644
--- a/arch/arm/mach-imx/atf.c
+++ b/arch/arm/mach-imx/atf.c
@@ -181,6 +181,9 @@ void imx8mn_load_and_start_image_via_tfa(void)
case BOOTSOURCE_MMC:
imx8mn_esdhc_load_image(instance, false);
break;
+ case BOOTSOURCE_SERIAL:
+ imx8mn_bootrom_load_image();
+ break;
default:
printf("Unhandled bootsource BOOTSOURCE_%d\n", src);
hang();
--
2.30.2
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 4/9] ARM: i.MX8MN: evk: simplify DDR4/LPDDR4 selection code
2022-08-05 12:54 [PATCH 0/9] ARM: i.MX8MN: clean up and enable imx-usb-loader Ahmad Fatoum
` (2 preceding siblings ...)
2022-08-05 12:54 ` [PATCH 3/9] ARM: i.MX8MN: add SDPS barebox-side support Ahmad Fatoum
@ 2022-08-05 12:54 ` Ahmad Fatoum
2022-08-05 12:54 ` [PATCH 5/9] ddr: imx8m: rename type to more fitting ddrc|dram_type Ahmad Fatoum
` (6 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Ahmad Fatoum @ 2022-08-05 12:54 UTC (permalink / raw)
To: barebox; +Cc: mfe, Ahmad Fatoum
The code selecting either DDR4 or LPDDR4 would be easier to follow with
symmetric if and else clauses. Factor out an i2c_dev_detect function
that can move into common pbl code in the future and refactor the code
accordingly.
With this change, we also remove use of dram_timing->dram_type,
which comes in handy in a follow-up commit that retires that struct
member.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
arch/arm/boards/nxp-imx8mn-evk/lowlevel.c | 26 ++++++++++-------------
1 file changed, 11 insertions(+), 15 deletions(-)
diff --git a/arch/arm/boards/nxp-imx8mn-evk/lowlevel.c b/arch/arm/boards/nxp-imx8mn-evk/lowlevel.c
index ddc6e4fd2b29..f53f9c1c6172 100644
--- a/arch/arm/boards/nxp-imx8mn-evk/lowlevel.c
+++ b/arch/arm/boards/nxp-imx8mn-evk/lowlevel.c
@@ -57,7 +57,7 @@ static void pmic_reg_write(void *i2c, int addr, int reg, uint8_t val)
pr_err("Failed to write to pmic@%x: %d\n", addr, ret);
}
-static int power_init_board_pca9450(void *i2c, int addr)
+static int i2c_dev_detect(void *i2c, int addr)
{
u8 buf[1];
struct i2c_msg msgs[] = {
@@ -69,9 +69,11 @@ static int power_init_board_pca9450(void *i2c, int addr)
},
};
- if (i2c_fsl_xfer(i2c, msgs, 1) != 1)
- return -ENODEV;
+ return i2c_fsl_xfer(i2c, msgs, 1) == 1 ? 0 : -ENODEV;
+}
+static void power_init_board_pca9450(void *i2c, int addr)
+{
/* BUCKxOUT_DVS0/1 control BUCK123 output */
pmic_reg_write(i2c, addr, PCA9450_BUCK123_DVS, 0x29);
@@ -96,11 +98,9 @@ static int power_init_board_pca9450(void *i2c, int addr)
/* set WDOG_B_CFG to cold reset */
pmic_reg_write(i2c, addr, PCA9450_RESET_CTRL, 0xA1);
-
- return 0;
}
-static int power_init_board_bd71837(void *i2c, int addr)
+static void power_init_board_bd71837(void *i2c, int addr)
{
/* decrease RESET key long push time from the default 10s to 10ms */
pmic_reg_write(i2c, addr, BD718XX_PWRONCONFIG1, 0x0);
@@ -123,17 +123,13 @@ static int power_init_board_bd71837(void *i2c, int addr)
/* lock the PMIC regs */
pmic_reg_write(i2c, addr, BD718XX_REGLOCK, 0x11);
-
- return 0;
}
extern struct dram_timing_info imx8mn_evk_ddr4_timing, imx8mn_evk_lpddr4_timing;
static void start_atf(void)
{
- struct dram_timing_info *dram_timing = &imx8mn_evk_lpddr4_timing;
void *i2c;
- int ret;
/*
* If we are in EL3 we are running for the first time and need to
@@ -151,14 +147,14 @@ static void start_atf(void)
i2c = imx8m_i2c_early_init(IOMEM(MX8MN_I2C1_BASE_ADDR));
- ret = power_init_board_pca9450(i2c, 0x25);
- if (ret) {
+ if (i2c_dev_detect(i2c, 0x25) == 0) {
+ power_init_board_pca9450(i2c, 0x25);
+ imx8mn_ddr_init(&imx8mn_evk_lpddr4_timing, DRAM_TYPE_LPDDR4);
+ } else {
power_init_board_bd71837(i2c, 0x4b);
- dram_timing = &imx8mn_evk_ddr4_timing;
+ imx8mn_ddr_init(&imx8mn_evk_ddr4_timing, DRAM_TYPE_DDR4);
}
- imx8mn_ddr_init(dram_timing, dram_timing->dram_type);
-
imx8mn_load_and_start_image_via_tfa();
}
--
2.30.2
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 5/9] ddr: imx8m: rename type to more fitting ddrc|dram_type
2022-08-05 12:54 [PATCH 0/9] ARM: i.MX8MN: clean up and enable imx-usb-loader Ahmad Fatoum
` (3 preceding siblings ...)
2022-08-05 12:54 ` [PATCH 4/9] ARM: i.MX8MN: evk: simplify DDR4/LPDDR4 selection code Ahmad Fatoum
@ 2022-08-05 12:54 ` Ahmad Fatoum
2022-08-05 12:54 ` [PATCH 6/9] ARM: i.MX8M: remove struct dram_timing_info::dram_type again Ahmad Fatoum
` (5 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Ahmad Fatoum @ 2022-08-05 12:54 UTC (permalink / raw)
To: barebox; +Cc: mfe, Ahmad Fatoum
type is ambiguous and can mean either DDR controller (SoC) type, DRAM
type or firmware (1D/2D) type. Replace variables called type plainly,
with more descriptive ddrc_type, dram_type and fw_type.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
drivers/ddr/imx8m/ddr_init.c | 12 +++----
drivers/ddr/imx8m/ddrphy_train.c | 4 +--
include/soc/imx8m/ddr.h | 54 ++++++++++++++++----------------
3 files changed, 35 insertions(+), 35 deletions(-)
diff --git a/drivers/ddr/imx8m/ddr_init.c b/drivers/ddr/imx8m/ddr_init.c
index 41e1fba38a52..f046ea52df7f 100644
--- a/drivers/ddr/imx8m/ddr_init.c
+++ b/drivers/ddr/imx8m/ddr_init.c
@@ -50,7 +50,7 @@ static void ddr_cfg_umctl2(struct dram_cfg_param *ddrc_cfg, int num)
#define IMX8M_SAVED_DRAM_TIMING_BASE 0x180000
int imx8m_ddr_init(struct dram_timing_info *dram_timing,
- enum ddrc_type type)
+ enum ddrc_type ddrc_type)
{
unsigned long src_ddrc_rcr = MX8M_SRC_DDRC_RCR_ADDR;
unsigned int tmp, initial_drate, target_freq;
@@ -59,7 +59,7 @@ int imx8m_ddr_init(struct dram_timing_info *dram_timing,
pr_debug("start DRAM init\n");
/* Step1: Follow the power up procedure */
- switch (type) {
+ switch (ddrc_type) {
case DDRC_TYPE_MQ:
reg32_write(src_ddrc_rcr + 0x04, 0x8f00000f);
reg32_write(src_ddrc_rcr, 0x8f00000f);
@@ -81,7 +81,7 @@ int imx8m_ddr_init(struct dram_timing_info *dram_timing,
initial_drate = dram_timing->fsp_msg[0].drate;
/* default to the frequency point 0 clock */
- ddrphy_init_set_dfi_clk(initial_drate, type);
+ ddrphy_init_set_dfi_clk(initial_drate, ddrc_type);
/* D-aasert the presetn */
reg32_write(src_ddrc_rcr, 0x8F000006);
@@ -107,7 +107,7 @@ int imx8m_ddr_init(struct dram_timing_info *dram_timing,
/* if ddr type is LPDDR4, do it */
tmp = reg32_read(DDRC_MSTR(0));
- if (tmp & (0x1 << 5) && type != DDRC_TYPE_MN)
+ if (tmp & (0x1 << 5) && ddrc_type != DDRC_TYPE_MN)
reg32_write(DDRC_DDR_SS_GPR0, 0x01); /* LPDDR4 mode */
/* determine the initial boot frequency */
@@ -134,7 +134,7 @@ int imx8m_ddr_init(struct dram_timing_info *dram_timing,
*/
pr_debug("ddrphy config start\n");
- ret = ddr_cfg_phy(dram_timing, type);
+ ret = ddr_cfg_phy(dram_timing, ddrc_type);
if (ret)
return ret;
@@ -154,7 +154,7 @@ int imx8m_ddr_init(struct dram_timing_info *dram_timing,
reg32_write(DDRC_SWCTL(0), 0x00000000);
/* Apply rank-to-rank workaround */
- update_umctl2_rank_space_setting(dram_timing->fsp_msg_num - 1, type);
+ update_umctl2_rank_space_setting(dram_timing->fsp_msg_num - 1, ddrc_type);
/* Step16: Set DFIMISC.dfi_init_start to 1 */
setbits_le32(DDRC_DFIMISC(0), (0x1 << 5));
diff --git a/drivers/ddr/imx8m/ddrphy_train.c b/drivers/ddr/imx8m/ddrphy_train.c
index 2190b5341307..f739c6510703 100644
--- a/drivers/ddr/imx8m/ddrphy_train.c
+++ b/drivers/ddr/imx8m/ddrphy_train.c
@@ -93,7 +93,7 @@ void ddr_load_train_code(enum dram_type dram_type, enum fw_type fw_type)
DDRC_PHY_DMEM, dmem, dsize);
}
-int ddr_cfg_phy(struct dram_timing_info *dram_timing, enum ddrc_type type)
+int ddr_cfg_phy(struct dram_timing_info *dram_timing, enum ddrc_type ddrc_type)
{
struct dram_cfg_param *dram_cfg;
struct dram_fsp_msg *fsp_msg;
@@ -116,7 +116,7 @@ int ddr_cfg_phy(struct dram_timing_info *dram_timing, enum ddrc_type type)
for (i = 0; i < dram_timing->fsp_msg_num; i++) {
pr_debug("DRAM PHY training for %dMTS\n", fsp_msg->drate);
/* set dram PHY input clocks to desired frequency */
- ddrphy_init_set_dfi_clk(fsp_msg->drate, type);
+ ddrphy_init_set_dfi_clk(fsp_msg->drate, ddrc_type);
/* load the dram training firmware image */
dwc_ddrphy_apb_wr(0xd0000, 0x0);
diff --git a/include/soc/imx8m/ddr.h b/include/soc/imx8m/ddr.h
index ad13632d28d9..e90adc37df87 100644
--- a/include/soc/imx8m/ddr.h
+++ b/include/soc/imx8m/ddr.h
@@ -333,6 +333,13 @@ enum dram_type {
DRAM_TYPE_DDR4,
};
+enum ddrc_type {
+ DDRC_TYPE_MM,
+ DDRC_TYPE_MN,
+ DDRC_TYPE_MQ,
+ DDRC_TYPE_MP,
+};
+
struct dram_cfg_param {
unsigned int reg;
unsigned int val;
@@ -368,71 +375,64 @@ struct dram_timing_info {
extern struct dram_timing_info dram_timing;
-enum ddrc_type {
- DDRC_TYPE_MM,
- DDRC_TYPE_MN,
- DDRC_TYPE_MQ,
- DDRC_TYPE_MP,
-};
-
void ddr_get_firmware_lpddr4(void);
void ddr_get_firmware_ddr(void);
-static void ddr_get_firmware(enum dram_type type)
+static void ddr_get_firmware(enum dram_type dram_type)
{
- if (type == DRAM_TYPE_LPDDR4)
+ if (dram_type == DRAM_TYPE_LPDDR4)
ddr_get_firmware_lpddr4();
else
ddr_get_firmware_ddr();
}
int imx8m_ddr_init(struct dram_timing_info *dram_timing,
- enum ddrc_type type);
+ enum ddrc_type ddrc_type);
static inline int imx8mm_ddr_init(struct dram_timing_info *dram_timing,
- enum dram_type type)
+ enum dram_type dram_type)
{
- ddr_get_firmware(type);
+ ddr_get_firmware(dram_type);
return imx8m_ddr_init(dram_timing, DDRC_TYPE_MM);
}
static inline int imx8mn_ddr_init(struct dram_timing_info *dram_timing,
- enum dram_type type)
+ enum dram_type dram_type)
{
- ddr_get_firmware(type);
+ ddr_get_firmware(dram_type);
return imx8m_ddr_init(dram_timing, DDRC_TYPE_MN);
}
static inline int imx8mq_ddr_init(struct dram_timing_info *dram_timing,
- enum dram_type type)
+ enum dram_type dram_type)
{
- ddr_get_firmware(type);
+ ddr_get_firmware(dram_type);
return imx8m_ddr_init(dram_timing, DDRC_TYPE_MQ);
}
static inline int imx8mp_ddr_init(struct dram_timing_info *dram_timing,
- enum dram_type type)
+ enum dram_type dram_type)
{
- ddr_get_firmware(type);
+ ddr_get_firmware(dram_type);
return imx8m_ddr_init(dram_timing, DDRC_TYPE_MP);
}
-int ddr_cfg_phy(struct dram_timing_info *timing_info, enum ddrc_type type);
+int ddr_cfg_phy(struct dram_timing_info *timing_info, enum ddrc_type ddrc_type);
void load_lpddr4_phy_pie(void);
void ddrphy_trained_csr_save(struct dram_cfg_param *param, unsigned int num);
void dram_config_save(struct dram_timing_info *info, unsigned long base);
/* utils function for ddr phy training */
int wait_ddrphy_training_complete(void);
-void ddrphy_init_set_dfi_clk(unsigned int drate, enum ddrc_type type);
-void ddrphy_init_read_msg_block(enum fw_type type);
+void ddrphy_init_set_dfi_clk(unsigned int drate, enum ddrc_type ddrc_type);
+void ddrphy_init_read_msg_block(enum fw_type fw_type);
void update_umctl2_rank_space_setting(unsigned int pstat_num,
- enum ddrc_type type);
+ enum ddrc_type ddrc_type);
void get_trained_CDD(unsigned int fsp);
#define reg32_write(a, v) writel(v, a)
@@ -457,22 +457,22 @@ enum ddrc_phy_firmware_offset {
DDRC_PHY_DMEM = 0x00054000U,
};
-void ddr_load_train_code(enum dram_type dram_type, enum fw_type type);
+void ddr_load_train_code(enum dram_type dram_type, enum fw_type fw_type);
void ddrc_phy_load_firmware(void __iomem *,
enum ddrc_phy_firmware_offset,
const u16 *, size_t);
-static inline bool dram_is_lpddr4(enum dram_type type)
+static inline bool dram_is_lpddr4(enum dram_type dram_type)
{
return IS_ENABLED(CONFIG_FIRMWARE_IMX_LPDDR4_PMU_TRAIN) &&
- type == DRAM_TYPE_LPDDR4;
+ dram_type == DRAM_TYPE_LPDDR4;
}
-static inline bool dram_is_ddr4(enum dram_type type)
+static inline bool dram_is_ddr4(enum dram_type dram_type)
{
return IS_ENABLED(CONFIG_FIRMWARE_IMX_DDR4_PMU_TRAIN) &&
- type == DRAM_TYPE_DDR4;
+ dram_type == DRAM_TYPE_DDR4;
}
#define DDRC_PHY_REG(x) ((x) * 4)
--
2.30.2
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 6/9] ARM: i.MX8M: remove struct dram_timing_info::dram_type again
2022-08-05 12:54 [PATCH 0/9] ARM: i.MX8MN: clean up and enable imx-usb-loader Ahmad Fatoum
` (4 preceding siblings ...)
2022-08-05 12:54 ` [PATCH 5/9] ddr: imx8m: rename type to more fitting ddrc|dram_type Ahmad Fatoum
@ 2022-08-05 12:54 ` Ahmad Fatoum
2022-08-05 12:54 ` [PATCH 7/9] pbl: generalize fsl i2c_early API into pbl_i2c Ahmad Fatoum
` (4 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Ahmad Fatoum @ 2022-08-05 12:54 UTC (permalink / raw)
To: barebox; +Cc: mfe, Ahmad Fatoum
We had added dram_timing_info::dram_type to allow the same build to
support both DDR4 and LPDDR4. Since then imx8m_ddr_init has gained a new
member describing the DRAM type, so we can just use that instead of the
struct member. The benefit of that is that we can keep the DRAM timing
code resulting from the generator unchanged.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
arch/arm/boards/mnt-reform/lpddr4-timing.c | 1 -
.../arm/boards/nxp-imx8mm-evk/lpddr4-timing.c | 1 -
arch/arm/boards/nxp-imx8mn-evk/ddr4-timing.c | 1 -
.../arm/boards/nxp-imx8mn-evk/lpddr4-timing.c | 1 -
.../arm/boards/nxp-imx8mp-evk/lpddr4-timing.c | 1 -
.../protonic-imx8m/lpddr4-timing-prt8mm.c | 1 -
drivers/ddr/imx8m/ddr_init.c | 5 +--
drivers/ddr/imx8m/ddrphy_train.c | 6 ++--
include/soc/imx8m/ddr.h | 35 ++++++++++++-------
9 files changed, 30 insertions(+), 22 deletions(-)
diff --git a/arch/arm/boards/mnt-reform/lpddr4-timing.c b/arch/arm/boards/mnt-reform/lpddr4-timing.c
index 0e962890fde2..0b5853000d03 100644
--- a/arch/arm/boards/mnt-reform/lpddr4-timing.c
+++ b/arch/arm/boards/mnt-reform/lpddr4-timing.c
@@ -1000,7 +1000,6 @@ static struct dram_fsp_msg mnt_reform_lpddr4_dram_fsp_msg[] = {
/* ddr timing config params */
struct dram_timing_info mnt_reform_dram_timing = {
- .dram_type = DRAM_TYPE_LPDDR4,
.ddrc_cfg = mnt_reform_lpddr4_ddrc_cfg,
.ddrc_cfg_num = ARRAY_SIZE(mnt_reform_lpddr4_ddrc_cfg),
.ddrphy_cfg = mnt_reform_lpddr4_ddrphy_cfg,
diff --git a/arch/arm/boards/nxp-imx8mm-evk/lpddr4-timing.c b/arch/arm/boards/nxp-imx8mm-evk/lpddr4-timing.c
index 68efbbdf917b..e7c01f9cc9a0 100644
--- a/arch/arm/boards/nxp-imx8mm-evk/lpddr4-timing.c
+++ b/arch/arm/boards/nxp-imx8mm-evk/lpddr4-timing.c
@@ -1965,7 +1965,6 @@ static struct dram_fsp_msg lpddr4_dram_fsp_msg[] = {
/* lpddr4 timing config params on EVK board */
struct dram_timing_info imx8mm_evk_dram_timing = {
- .dram_type = DRAM_TYPE_LPDDR4,
.ddrc_cfg = lpddr4_ddrc_cfg,
.ddrc_cfg_num = ARRAY_SIZE(lpddr4_ddrc_cfg),
.ddrphy_cfg = lpddr4_ddrphy_cfg,
diff --git a/arch/arm/boards/nxp-imx8mn-evk/ddr4-timing.c b/arch/arm/boards/nxp-imx8mn-evk/ddr4-timing.c
index 7ce371384ea7..131a63156ef7 100644
--- a/arch/arm/boards/nxp-imx8mn-evk/ddr4-timing.c
+++ b/arch/arm/boards/nxp-imx8mn-evk/ddr4-timing.c
@@ -1040,7 +1040,6 @@ static struct dram_fsp_msg ddr_dram_fsp_msg[] = {
/* ddr timing config params */
struct dram_timing_info imx8mn_evk_ddr4_timing = {
- .dram_type = DRAM_TYPE_DDR4,
.ddrc_cfg = ddr_ddrc_cfg,
.ddrc_cfg_num = ARRAY_SIZE(ddr_ddrc_cfg),
.ddrphy_cfg = ddr_ddrphy_cfg,
diff --git a/arch/arm/boards/nxp-imx8mn-evk/lpddr4-timing.c b/arch/arm/boards/nxp-imx8mn-evk/lpddr4-timing.c
index c53bcc705d2b..940b21cedb03 100644
--- a/arch/arm/boards/nxp-imx8mn-evk/lpddr4-timing.c
+++ b/arch/arm/boards/nxp-imx8mn-evk/lpddr4-timing.c
@@ -1576,7 +1576,6 @@ static struct dram_fsp_msg ddr_dram_fsp_msg[] = {
/* ddr timing config params */
struct dram_timing_info imx8mn_evk_lpddr4_timing = {
- .dram_type = DRAM_TYPE_LPDDR4,
.ddrc_cfg = ddr_ddrc_cfg,
.ddrc_cfg_num = ARRAY_SIZE(ddr_ddrc_cfg),
.ddrphy_cfg = ddr_ddrphy_cfg,
diff --git a/arch/arm/boards/nxp-imx8mp-evk/lpddr4-timing.c b/arch/arm/boards/nxp-imx8mp-evk/lpddr4-timing.c
index 681e70d06022..3028bc084c73 100644
--- a/arch/arm/boards/nxp-imx8mp-evk/lpddr4-timing.c
+++ b/arch/arm/boards/nxp-imx8mp-evk/lpddr4-timing.c
@@ -1834,7 +1834,6 @@ static struct dram_fsp_msg ddr_dram_fsp_msg[] = {
/* ddr timing config params */
struct dram_timing_info imx8mp_evk_dram_timing = {
- .dram_type = DRAM_TYPE_LPDDR4,
.ddrc_cfg = ddr_ddrc_cfg,
.ddrc_cfg_num = ARRAY_SIZE(ddr_ddrc_cfg),
.ddrphy_cfg = ddr_ddrphy_cfg,
diff --git a/arch/arm/boards/protonic-imx8m/lpddr4-timing-prt8mm.c b/arch/arm/boards/protonic-imx8m/lpddr4-timing-prt8mm.c
index ea5c0b915437..2c55e7d45144 100644
--- a/arch/arm/boards/protonic-imx8m/lpddr4-timing-prt8mm.c
+++ b/arch/arm/boards/protonic-imx8m/lpddr4-timing-prt8mm.c
@@ -1981,7 +1981,6 @@ static struct dram_fsp_msg lpddr4_dram_fsp_msg[] = {
/* lpddr4 timing config params on EVK board */
struct dram_timing_info prt8mm_dram_timing = {
- .dram_type = DRAM_TYPE_LPDDR4,
.ddrc_cfg = lpddr4_ddrc_cfg,
.ddrc_cfg_num = ARRAY_SIZE(lpddr4_ddrc_cfg),
.ddrphy_cfg = lpddr4_ddrphy_cfg,
diff --git a/drivers/ddr/imx8m/ddr_init.c b/drivers/ddr/imx8m/ddr_init.c
index f046ea52df7f..18969ddb53d3 100644
--- a/drivers/ddr/imx8m/ddr_init.c
+++ b/drivers/ddr/imx8m/ddr_init.c
@@ -50,10 +50,11 @@ static void ddr_cfg_umctl2(struct dram_cfg_param *ddrc_cfg, int num)
#define IMX8M_SAVED_DRAM_TIMING_BASE 0x180000
int imx8m_ddr_init(struct dram_timing_info *dram_timing,
- enum ddrc_type ddrc_type)
+ unsigned type)
{
unsigned long src_ddrc_rcr = MX8M_SRC_DDRC_RCR_ADDR;
unsigned int tmp, initial_drate, target_freq;
+ enum ddrc_type ddrc_type = get_ddrc_type(type);
int ret;
pr_debug("start DRAM init\n");
@@ -134,7 +135,7 @@ int imx8m_ddr_init(struct dram_timing_info *dram_timing,
*/
pr_debug("ddrphy config start\n");
- ret = ddr_cfg_phy(dram_timing, ddrc_type);
+ ret = ddr_cfg_phy(dram_timing, type);
if (ret)
return ret;
diff --git a/drivers/ddr/imx8m/ddrphy_train.c b/drivers/ddr/imx8m/ddrphy_train.c
index f739c6510703..e9d35afdfb16 100644
--- a/drivers/ddr/imx8m/ddrphy_train.c
+++ b/drivers/ddr/imx8m/ddrphy_train.c
@@ -93,8 +93,10 @@ void ddr_load_train_code(enum dram_type dram_type, enum fw_type fw_type)
DDRC_PHY_DMEM, dmem, dsize);
}
-int ddr_cfg_phy(struct dram_timing_info *dram_timing, enum ddrc_type ddrc_type)
+int ddr_cfg_phy(struct dram_timing_info *dram_timing, unsigned type)
{
+ enum ddrc_type ddrc_type = get_ddrc_type(type);
+ enum dram_type dram_type = get_dram_type(type);
struct dram_cfg_param *dram_cfg;
struct dram_fsp_msg *fsp_msg;
unsigned int num;
@@ -120,7 +122,7 @@ int ddr_cfg_phy(struct dram_timing_info *dram_timing, enum ddrc_type ddrc_type)
/* load the dram training firmware image */
dwc_ddrphy_apb_wr(0xd0000, 0x0);
- ddr_load_train_code(dram_timing->dram_type, fsp_msg->fw_type);
+ ddr_load_train_code(dram_type, fsp_msg->fw_type);
/* load the frequency set point message block parameter */
dram_cfg = fsp_msg->fsp_cfg;
diff --git a/include/soc/imx8m/ddr.h b/include/soc/imx8m/ddr.h
index e90adc37df87..2149ae432554 100644
--- a/include/soc/imx8m/ddr.h
+++ b/include/soc/imx8m/ddr.h
@@ -329,17 +329,29 @@ enum fw_type {
};
enum dram_type {
- DRAM_TYPE_LPDDR4,
- DRAM_TYPE_DDR4,
+#define DRAM_TYPE_MASK 0x00ff
+ DRAM_TYPE_LPDDR4 = 0 << 0,
+ DRAM_TYPE_DDR4 = 1 << 0,
};
+static inline enum dram_type get_dram_type(unsigned type)
+{
+ return type & DRAM_TYPE_MASK;
+}
+
enum ddrc_type {
- DDRC_TYPE_MM,
- DDRC_TYPE_MN,
- DDRC_TYPE_MQ,
- DDRC_TYPE_MP,
+#define DDRC_TYPE_MASK 0xff00
+ DDRC_TYPE_MM = 0 << 8,
+ DDRC_TYPE_MN = 1 << 8,
+ DDRC_TYPE_MQ = 2 << 8,
+ DDRC_TYPE_MP = 3 << 8,
};
+static inline enum ddrc_type get_ddrc_type(unsigned type)
+{
+ return type & DDRC_TYPE_MASK;
+}
+
struct dram_cfg_param {
unsigned int reg;
unsigned int val;
@@ -353,7 +365,6 @@ struct dram_fsp_msg {
};
struct dram_timing_info {
- enum dram_type dram_type;
/* umctl2 config */
struct dram_cfg_param *ddrc_cfg;
unsigned int ddrc_cfg_num;
@@ -387,14 +398,14 @@ static void ddr_get_firmware(enum dram_type dram_type)
}
int imx8m_ddr_init(struct dram_timing_info *dram_timing,
- enum ddrc_type ddrc_type);
+ unsigned type);
static inline int imx8mm_ddr_init(struct dram_timing_info *dram_timing,
enum dram_type dram_type)
{
ddr_get_firmware(dram_type);
- return imx8m_ddr_init(dram_timing, DDRC_TYPE_MM);
+ return imx8m_ddr_init(dram_timing, DDRC_TYPE_MM | dram_type);
}
static inline int imx8mn_ddr_init(struct dram_timing_info *dram_timing,
@@ -402,7 +413,7 @@ static inline int imx8mn_ddr_init(struct dram_timing_info *dram_timing,
{
ddr_get_firmware(dram_type);
- return imx8m_ddr_init(dram_timing, DDRC_TYPE_MN);
+ return imx8m_ddr_init(dram_timing, DDRC_TYPE_MN | dram_type);
}
static inline int imx8mq_ddr_init(struct dram_timing_info *dram_timing,
@@ -410,7 +421,7 @@ static inline int imx8mq_ddr_init(struct dram_timing_info *dram_timing,
{
ddr_get_firmware(dram_type);
- return imx8m_ddr_init(dram_timing, DDRC_TYPE_MQ);
+ return imx8m_ddr_init(dram_timing, DDRC_TYPE_MQ | dram_type);
}
static inline int imx8mp_ddr_init(struct dram_timing_info *dram_timing,
@@ -418,7 +429,7 @@ static inline int imx8mp_ddr_init(struct dram_timing_info *dram_timing,
{
ddr_get_firmware(dram_type);
- return imx8m_ddr_init(dram_timing, DDRC_TYPE_MP);
+ return imx8m_ddr_init(dram_timing, DDRC_TYPE_MP | dram_type);
}
int ddr_cfg_phy(struct dram_timing_info *timing_info, enum ddrc_type ddrc_type);
--
2.30.2
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 7/9] pbl: generalize fsl i2c_early API into pbl_i2c
2022-08-05 12:54 [PATCH 0/9] ARM: i.MX8MN: clean up and enable imx-usb-loader Ahmad Fatoum
` (5 preceding siblings ...)
2022-08-05 12:54 ` [PATCH 6/9] ARM: i.MX8M: remove struct dram_timing_info::dram_type again Ahmad Fatoum
@ 2022-08-05 12:54 ` Ahmad Fatoum
2022-08-08 8:44 ` Ahmad Fatoum
2022-08-05 12:54 ` [PATCH 8/9] i2c: add <pbl/pmic.h> for PBL use Ahmad Fatoum
` (3 subsequent siblings)
10 siblings, 1 reply; 13+ messages in thread
From: Ahmad Fatoum @ 2022-08-05 12:54 UTC (permalink / raw)
To: barebox; +Cc: mfe
The prebootloader is inherently board-specific, so it's natural to
hardcode the i2c driver used and we only support fsl_i2c at the moment
anyway. For abstractions used by different prebootloaders though
(e.g. PMIC writing, SPD EEPROM decoding), it would be good for generic
code to use a pbl_i2c abstraction, so it can be reused across PBLs using
different I2C controllers. Add such an abstraction and use it where
appropriate.
---
arch/arm/boards/ls1046ardb/lowlevel.c | 6 +++---
arch/arm/boards/mnt-reform/lowlevel.c | 12 ++++++------
arch/arm/boards/nxp-imx8mm-evk/lowlevel.c | 8 ++++----
arch/arm/boards/nxp-imx8mn-evk/lowlevel.c | 16 +++++++--------
arch/arm/boards/nxp-imx8mp-evk/lowlevel.c | 8 ++++----
common/ddr_spd.c | 24 ++++++++++-------------
drivers/i2c/busses/i2c-imx-early.c | 21 ++++++++++++--------
include/ddr_spd.h | 5 ++---
include/i2c/i2c-early.h | 13 ------------
include/pbl/i2c.h | 21 ++++++++++++++++++++
10 files changed, 71 insertions(+), 63 deletions(-)
delete mode 100644 include/i2c/i2c-early.h
create mode 100644 include/pbl/i2c.h
diff --git a/arch/arm/boards/ls1046ardb/lowlevel.c b/arch/arm/boards/ls1046ardb/lowlevel.c
index 0a30f05aa2cb..055e5f4c9995 100644
--- a/arch/arm/boards/ls1046ardb/lowlevel.c
+++ b/arch/arm/boards/ls1046ardb/lowlevel.c
@@ -5,7 +5,7 @@
#include <ddr_spd.h>
#include <image-metadata.h>
#include <platform_data/mmc-esdhc-imx.h>
-#include <i2c/i2c-early.h>
+#include <pbl/i2c.h>
#include <soc/fsl/fsl_ddr_sdram.h>
#include <soc/fsl/immap_lsch2.h>
#include <asm/barebox-arm-head.h>
@@ -187,7 +187,7 @@ static struct fsl_ddr_info ls1046a_info = {
static noinline __noreturn void ls1046ardb_r_entry(unsigned long memsize)
{
unsigned long membase = LS1046A_DDR_SDRAM_BASE;
- struct fsl_i2c *i2c;
+ struct pbl_i2c *i2c;
int ret;
if (get_pc() >= membase) {
@@ -205,7 +205,7 @@ static noinline __noreturn void ls1046ardb_r_entry(unsigned long memsize)
IMD_USED_OF(fsl_ls1046a_rdb);
i2c = ls1046_i2c_init(IOMEM(LSCH2_I2C1_BASE_ADDR));
- ret = spd_read_eeprom(i2c, i2c_fsl_xfer, 0x51, &spd_eeprom);
+ ret = spd_read_eeprom(i2c, 0x51, &spd_eeprom);
if (ret) {
pr_err("Cannot read SPD EEPROM: %d\n", ret);
goto err;
diff --git a/arch/arm/boards/mnt-reform/lowlevel.c b/arch/arm/boards/mnt-reform/lowlevel.c
index 644c42269d79..a845d36263fe 100644
--- a/arch/arm/boards/mnt-reform/lowlevel.c
+++ b/arch/arm/boards/mnt-reform/lowlevel.c
@@ -7,7 +7,7 @@
#include <common.h>
#include <debug_ll.h>
#include <firmware.h>
-#include <i2c/i2c-early.h>
+#include <pbl/i2c.h>
#include <mach/atf.h>
#include <mach/esdctl.h>
#include <mach/generic.h>
@@ -36,7 +36,7 @@ static void mnt_reform_setup_uart(void)
putc_ll('>');
}
-static void i2c_mux_set(void *i2c, u8 channel)
+static void i2c_mux_set(struct pbl_i2c *i2c, u8 channel)
{
int ret;
u8 buf[1];
@@ -50,12 +50,12 @@ static void i2c_mux_set(void *i2c, u8 channel)
buf[0] = 1 << channel;
- ret = i2c_fsl_xfer(i2c, msgs, ARRAY_SIZE(msgs));
+ ret = pbl_i2c_xfer(i2c, msgs, ARRAY_SIZE(msgs));
if (ret != 1)
pr_err("failed to set i2c mux\n");
}
-static void i2c_regulator_set_voltage(void *i2c, u8 reg, u8 voffs)
+static void i2c_regulator_set_voltage(struct pbl_i2c *i2c, u8 reg, u8 voffs)
{
int ret;
u8 buf[2];
@@ -70,7 +70,7 @@ static void i2c_regulator_set_voltage(void *i2c, u8 reg, u8 voffs)
buf[0] = reg;
buf[1] = 0x80 + voffs;
- ret = i2c_fsl_xfer(i2c, msgs, ARRAY_SIZE(msgs));
+ ret = pbl_i2c_xfer(i2c, msgs, ARRAY_SIZE(msgs));
if (ret != 1)
pr_err("failed to set voltage\n");
}
@@ -81,7 +81,7 @@ static void i2c_regulator_set_voltage(void *i2c, u8 reg, u8 voffs)
static void mnt_reform_init_power(void)
{
- void *i2c;
+ struct pbl_i2c *i2c;
imx8mq_setup_pad(IMX8MQ_PAD_I2C1_SCL__I2C1_SCL | I2C_PAD_CTRL);
imx8mq_setup_pad(IMX8MQ_PAD_I2C1_SDA__I2C1_SDA | I2C_PAD_CTRL);
diff --git a/arch/arm/boards/nxp-imx8mm-evk/lowlevel.c b/arch/arm/boards/nxp-imx8mm-evk/lowlevel.c
index 888bdd079083..e52d0f29a4c9 100644
--- a/arch/arm/boards/nxp-imx8mm-evk/lowlevel.c
+++ b/arch/arm/boards/nxp-imx8mm-evk/lowlevel.c
@@ -7,7 +7,7 @@
#include <asm/cache.h>
#include <asm/barebox-arm.h>
#include <asm/barebox-arm-head.h>
-#include <i2c/i2c-early.h>
+#include <pbl/i2c.h>
#include <linux/sizes.h>
#include <mach/esdctl.h>
#include <mach/generic.h>
@@ -37,7 +37,7 @@ static void setup_uart(void)
putc_ll('>');
}
-static void pmic_reg_write(void *i2c, int reg, uint8_t val)
+static void pmic_reg_write(struct pbl_i2c *i2c, int reg, uint8_t val)
{
int ret;
u8 buf[32];
@@ -53,14 +53,14 @@ static void pmic_reg_write(void *i2c, int reg, uint8_t val)
msgs[0].len = 2;
- ret = i2c_fsl_xfer(i2c, msgs, ARRAY_SIZE(msgs));
+ ret = pbl_i2c_xfer(i2c, msgs, ARRAY_SIZE(msgs));
if (ret != 1)
pr_err("Failed to write to pmic\n");
}
static int power_init_board(void)
{
- void *i2c;
+ struct pbl_i2c *i2c;
imx8mm_setup_pad(IMX8MM_PAD_I2C1_SCL_I2C1_SCL);
imx8mm_setup_pad(IMX8MM_PAD_I2C1_SDA_I2C1_SDA);
diff --git a/arch/arm/boards/nxp-imx8mn-evk/lowlevel.c b/arch/arm/boards/nxp-imx8mn-evk/lowlevel.c
index f53f9c1c6172..37b983f6387a 100644
--- a/arch/arm/boards/nxp-imx8mn-evk/lowlevel.c
+++ b/arch/arm/boards/nxp-imx8mn-evk/lowlevel.c
@@ -9,7 +9,7 @@
#include <asm/sections.h>
#include <asm/barebox-arm.h>
#include <asm/barebox-arm-head.h>
-#include <i2c/i2c-early.h>
+#include <pbl/i2c.h>
#include <linux/sizes.h>
#include <mach/atf.h>
#include <mach/xload.h>
@@ -36,7 +36,7 @@ static void setup_uart(void)
putc_ll('>');
}
-static void pmic_reg_write(void *i2c, int addr, int reg, uint8_t val)
+static void pmic_reg_write(struct pbl_i2c *i2c, int addr, int reg, uint8_t val)
{
int ret;
u8 buf[32];
@@ -52,12 +52,12 @@ static void pmic_reg_write(void *i2c, int addr, int reg, uint8_t val)
msgs[0].len = 2;
- ret = i2c_fsl_xfer(i2c, msgs, ARRAY_SIZE(msgs));
+ ret = pbl_i2c_xfer(i2c, msgs, ARRAY_SIZE(msgs));
if (ret != 1)
pr_err("Failed to write to pmic@%x: %d\n", addr, ret);
}
-static int i2c_dev_detect(void *i2c, int addr)
+static int i2c_dev_detect(struct pbl_i2c *i2c, int addr)
{
u8 buf[1];
struct i2c_msg msgs[] = {
@@ -69,10 +69,10 @@ static int i2c_dev_detect(void *i2c, int addr)
},
};
- return i2c_fsl_xfer(i2c, msgs, 1) == 1 ? 0 : -ENODEV;
+ return pbl_i2c_xfer(i2c, msgs, 1) == 1 ? 0 : -ENODEV;
}
-static void power_init_board_pca9450(void *i2c, int addr)
+static void power_init_board_pca9450(struct pbl_i2c *i2c, int addr)
{
/* BUCKxOUT_DVS0/1 control BUCK123 output */
pmic_reg_write(i2c, addr, PCA9450_BUCK123_DVS, 0x29);
@@ -100,7 +100,7 @@ static void power_init_board_pca9450(void *i2c, int addr)
pmic_reg_write(i2c, addr, PCA9450_RESET_CTRL, 0xA1);
}
-static void power_init_board_bd71837(void *i2c, int addr)
+static void power_init_board_bd71837(struct pbl_i2c *i2c, int addr)
{
/* decrease RESET key long push time from the default 10s to 10ms */
pmic_reg_write(i2c, addr, BD718XX_PWRONCONFIG1, 0x0);
@@ -129,7 +129,7 @@ extern struct dram_timing_info imx8mn_evk_ddr4_timing, imx8mn_evk_lpddr4_timing;
static void start_atf(void)
{
- void *i2c;
+ struct pbl_i2c *i2c;
/*
* If we are in EL3 we are running for the first time and need to
diff --git a/arch/arm/boards/nxp-imx8mp-evk/lowlevel.c b/arch/arm/boards/nxp-imx8mp-evk/lowlevel.c
index 338c8024c4a1..43f7d194d806 100644
--- a/arch/arm/boards/nxp-imx8mp-evk/lowlevel.c
+++ b/arch/arm/boards/nxp-imx8mp-evk/lowlevel.c
@@ -10,7 +10,7 @@
#include <asm/sections.h>
#include <asm/barebox-arm.h>
#include <asm/barebox-arm-head.h>
-#include <i2c/i2c-early.h>
+#include <pbl/i2c.h>
#include <linux/sizes.h>
#include <mach/atf.h>
#include <mach/xload.h>
@@ -48,7 +48,7 @@ static void setup_uart(void)
putc_ll('>');
}
-static void pmic_reg_write(void *i2c, int reg, uint8_t val)
+static void pmic_reg_write(struct pbl_i2c *i2c, int reg, uint8_t val)
{
int ret;
u8 buf[32];
@@ -64,14 +64,14 @@ static void pmic_reg_write(void *i2c, int reg, uint8_t val)
msgs[0].len = 2;
- ret = i2c_fsl_xfer(i2c, msgs, ARRAY_SIZE(msgs));
+ ret = pbl_i2c_xfer(i2c, msgs, ARRAY_SIZE(msgs));
if (ret != 1)
pr_err("Failed to write to pmic\n");
}
static int power_init_board(void)
{
- void *i2c;
+ struct pbl_i2c *i2c;
imx8mp_setup_pad(MX8MP_PAD_I2C1_SCL__I2C1_SCL | I2C_PAD_CTRL);
imx8mp_setup_pad(MX8MP_PAD_I2C1_SDA__I2C1_SDA | I2C_PAD_CTRL);
diff --git a/common/ddr_spd.c b/common/ddr_spd.c
index 7089923afb94..52773178e78e 100644
--- a/common/ddr_spd.c
+++ b/common/ddr_spd.c
@@ -6,6 +6,7 @@
#include <common.h>
#include <crc.h>
#include <ddr_spd.h>
+#include <pbl/i2c.h>
/* used for ddr1 and ddr2 spd */
static int spd_check(const u8 *buf, u8 spd_rev, u8 spd_cksum)
@@ -430,9 +431,7 @@ void ddr_spd_print(uint8_t *record)
#define SPD_SPA0_ADDRESS 0x36
#define SPD_SPA1_ADDRESS 0x37
-static int select_page(void *ctx,
- int (*xfer)(void *ctx, struct i2c_msg *msgs, int num),
- uint8_t addr)
+static int select_page(struct pbl_i2c *i2c, uint8_t addr)
{
struct i2c_msg msg = {
.addr = addr,
@@ -440,15 +439,14 @@ static int select_page(void *ctx,
};
int ret;
- ret = xfer(ctx, &msg, 1);
+ ret = pbl_i2c_xfer(i2c, &msg, 1);
if (ret < 0)
return ret;
return 0;
}
-static int read_buf(void *ctx,
- int (*xfer)(void *ctx, struct i2c_msg *msgs, int num),
+static int read_buf(struct pbl_i2c *i2c,
uint8_t addr, int page, void *buf)
{
uint8_t pos = 0;
@@ -466,11 +464,11 @@ static int read_buf(void *ctx,
}
};
- ret = select_page(ctx, xfer, page);
+ ret = select_page(i2c, page);
if (ret < 0)
return ret;
- ret = xfer(ctx, msg, 2);
+ ret = pbl_i2c_xfer(i2c, msg, 2);
if (ret < 0)
return ret;
@@ -479,8 +477,7 @@ static int read_buf(void *ctx,
/**
* spd_read_eeprom - Read contents of a SPD EEPROM
- * @ctx: Context pointer for the xfer function
- * @xfer: I2C message transfer function
+ * @i2c: I2C controller handle
* @addr: I2C bus address for the EEPROM
* @buf: buffer to read the SPD data to
*
@@ -489,19 +486,18 @@ static int read_buf(void *ctx,
* have a size of 512 bytes. Returns 0 for success or a negative error code
* otherwise.
*/
-int spd_read_eeprom(void *ctx,
- int (*xfer)(void *ctx, struct i2c_msg *msgs, int num),
+int spd_read_eeprom(struct pbl_i2c *i2c,
uint8_t addr, void *buf)
{
unsigned char *buf8 = buf;
int ret;
- ret = read_buf(ctx, xfer, addr, SPD_SPA0_ADDRESS, buf);
+ ret = read_buf(i2c, addr, SPD_SPA0_ADDRESS, buf);
if (ret < 0)
return ret;
if (buf8[2] == SPD_MEMTYPE_DDR4) {
- ret = read_buf(ctx, xfer, addr, SPD_SPA1_ADDRESS, buf + 256);
+ ret = read_buf(i2c, addr, SPD_SPA1_ADDRESS, buf + 256);
if (ret < 0)
return ret;
}
diff --git a/drivers/i2c/busses/i2c-imx-early.c b/drivers/i2c/busses/i2c-imx-early.c
index a79d7bd88ce1..4e0f7e517d01 100644
--- a/drivers/i2c/busses/i2c-imx-early.c
+++ b/drivers/i2c/busses/i2c-imx-early.c
@@ -9,11 +9,12 @@
*/
#include <common.h>
#include <i2c/i2c.h>
-#include <i2c/i2c-early.h>
+#include <pbl/i2c.h>
#include "i2c-imx.h"
struct fsl_i2c {
+ struct pbl_i2c i2c;
void __iomem *regs;
unsigned int i2cr_ien_opcode;
unsigned int i2sr_clr_opcode;
@@ -170,7 +171,7 @@ static int i2c_fsl_write(struct fsl_i2c *fsl_i2c, struct i2c_msg *msg)
/* write data */
for (i = 0; i < msg->len; i++) {
ret = i2c_fsl_send(fsl_i2c, msg->buf[i]);
- if (ret)
+ if (ret)
return ret;
}
@@ -229,9 +230,9 @@ static int i2c_fsl_read(struct fsl_i2c *fsl_i2c, struct i2c_msg *msg)
* If successful returns the number of messages transferred, otherwise a negative
* error code is returned.
*/
-int i2c_fsl_xfer(void *ctx, struct i2c_msg *msgs, int num)
+static int i2c_fsl_xfer(struct pbl_i2c *i2c, struct i2c_msg *msgs, int num)
{
- struct fsl_i2c *fsl_i2c = ctx;
+ struct fsl_i2c *fsl_i2c = container_of(i2c, struct fsl_i2c, i2c);
unsigned int i, temp;
int ret;
@@ -288,7 +289,7 @@ static struct fsl_i2c fsl_i2c;
* This function returns a context pointer suitable to transfer I2C messages
* using i2c_fsl_xfer.
*/
-void *ls1046_i2c_init(void __iomem *regs)
+struct pbl_i2c *ls1046_i2c_init(void __iomem *regs)
{
fsl_i2c.regs = regs;
fsl_i2c.regshift = 0;
@@ -297,10 +298,12 @@ void *ls1046_i2c_init(void __iomem *regs)
/* Divider for ~100kHz when coming from the ROM */
fsl_i2c.ifdr = 0x3e;
- return &fsl_i2c;
+ fsl_i2c.i2c.xfer = i2c_fsl_xfer;
+
+ return &fsl_i2c.i2c;
}
-void *imx8m_i2c_early_init(void __iomem *regs)
+struct pbl_i2c *imx8m_i2c_early_init(void __iomem *regs)
{
fsl_i2c.regs = regs;
fsl_i2c.regshift = 2;
@@ -309,5 +312,7 @@ void *imx8m_i2c_early_init(void __iomem *regs)
/* Divider for ~100kHz when coming from the ROM */
fsl_i2c.ifdr = 0x0f;
- return &fsl_i2c;
+ fsl_i2c.i2c.xfer = i2c_fsl_xfer;
+
+ return &fsl_i2c.i2c;
}
diff --git a/include/ddr_spd.h b/include/ddr_spd.h
index 6e63d90e5e20..bcc2171d2a50 100644
--- a/include/ddr_spd.h
+++ b/include/ddr_spd.h
@@ -6,7 +6,7 @@
#ifndef _DDR_SPD_H_
#define _DDR_SPD_H_
-#include <i2c/i2c.h>
+#include <pbl/i2c.h>
/*
* Format from "JEDEC Standard No. 21-C,
@@ -574,8 +574,7 @@ void ddr2_spd_dump(const struct ddr2_spd_eeprom *spd);
int ddr3_spd_check(const struct ddr3_spd_eeprom *spd);
int ddr4_spd_check(const struct ddr4_spd_eeprom *spd);
-int spd_read_eeprom(void *ctx,
- int (*xfer)(void *ctx, struct i2c_msg *msgs, int num),
+int spd_read_eeprom(struct pbl_i2c *i2c,
uint8_t addr, void *buf);
#endif /* _DDR_SPD_H_ */
diff --git a/include/i2c/i2c-early.h b/include/i2c/i2c-early.h
deleted file mode 100644
index fa93656e28e8..000000000000
--- a/include/i2c/i2c-early.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-
-#ifndef __I2C_EARLY_H
-#define __I2C_EARLY_H
-
-#include <i2c/i2c.h>
-
-int i2c_fsl_xfer(void *ctx, struct i2c_msg *msgs, int num);
-
-void *imx8m_i2c_early_init(void __iomem *regs);
-void *ls1046_i2c_init(void __iomem *regs);
-
-#endif /* __I2C_EARLY_H */
diff --git a/include/pbl/i2c.h b/include/pbl/i2c.h
new file mode 100644
index 000000000000..1f26e3dfc6ca
--- /dev/null
+++ b/include/pbl/i2c.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef __PBL_I2C_H
+#define __PBL_I2C_H
+
+#include <i2c/i2c.h>
+
+struct pbl_i2c {
+ int (*xfer)(struct pbl_i2c *, struct i2c_msg *msgs, int num);
+};
+
+static inline int pbl_i2c_xfer(struct pbl_i2c *i2c,
+ struct i2c_msg *msgs, int num)
+{
+ return i2c->xfer(i2c, msgs, num);
+}
+
+struct pbl_i2c *imx8m_i2c_early_init(void __iomem *regs);
+struct pbl_i2c *ls1046_i2c_init(void __iomem *regs);
+
+#endif /* __I2C_EARLY_H */
--
2.30.2
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 7/9] pbl: generalize fsl i2c_early API into pbl_i2c
2022-08-05 12:54 ` [PATCH 7/9] pbl: generalize fsl i2c_early API into pbl_i2c Ahmad Fatoum
@ 2022-08-08 8:44 ` Ahmad Fatoum
0 siblings, 0 replies; 13+ messages in thread
From: Ahmad Fatoum @ 2022-08-08 8:44 UTC (permalink / raw)
To: barebox; +Cc: mfe
On 05.08.22 14:54, Ahmad Fatoum wrote:
> The prebootloader is inherently board-specific, so it's natural to
> hardcode the i2c driver used and we only support fsl_i2c at the moment
> anyway. For abstractions used by different prebootloaders though
> (e.g. PMIC writing, SPD EEPROM decoding), it would be good for generic
> code to use a pbl_i2c abstraction, so it can be reused across PBLs using
> different I2C controllers. Add such an abstraction and use it where
> appropriate.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
> ---
> arch/arm/boards/ls1046ardb/lowlevel.c | 6 +++---
> arch/arm/boards/mnt-reform/lowlevel.c | 12 ++++++------
> arch/arm/boards/nxp-imx8mm-evk/lowlevel.c | 8 ++++----
> arch/arm/boards/nxp-imx8mn-evk/lowlevel.c | 16 +++++++--------
> arch/arm/boards/nxp-imx8mp-evk/lowlevel.c | 8 ++++----
> common/ddr_spd.c | 24 ++++++++++-------------
> drivers/i2c/busses/i2c-imx-early.c | 21 ++++++++++++--------
> include/ddr_spd.h | 5 ++---
> include/i2c/i2c-early.h | 13 ------------
> include/pbl/i2c.h | 21 ++++++++++++++++++++
> 10 files changed, 71 insertions(+), 63 deletions(-)
> delete mode 100644 include/i2c/i2c-early.h
> create mode 100644 include/pbl/i2c.h
>
> diff --git a/arch/arm/boards/ls1046ardb/lowlevel.c b/arch/arm/boards/ls1046ardb/lowlevel.c
> index 0a30f05aa2cb..055e5f4c9995 100644
> --- a/arch/arm/boards/ls1046ardb/lowlevel.c
> +++ b/arch/arm/boards/ls1046ardb/lowlevel.c
> @@ -5,7 +5,7 @@
> #include <ddr_spd.h>
> #include <image-metadata.h>
> #include <platform_data/mmc-esdhc-imx.h>
> -#include <i2c/i2c-early.h>
> +#include <pbl/i2c.h>
> #include <soc/fsl/fsl_ddr_sdram.h>
> #include <soc/fsl/immap_lsch2.h>
> #include <asm/barebox-arm-head.h>
> @@ -187,7 +187,7 @@ static struct fsl_ddr_info ls1046a_info = {
> static noinline __noreturn void ls1046ardb_r_entry(unsigned long memsize)
> {
> unsigned long membase = LS1046A_DDR_SDRAM_BASE;
> - struct fsl_i2c *i2c;
> + struct pbl_i2c *i2c;
> int ret;
>
> if (get_pc() >= membase) {
> @@ -205,7 +205,7 @@ static noinline __noreturn void ls1046ardb_r_entry(unsigned long memsize)
> IMD_USED_OF(fsl_ls1046a_rdb);
>
> i2c = ls1046_i2c_init(IOMEM(LSCH2_I2C1_BASE_ADDR));
> - ret = spd_read_eeprom(i2c, i2c_fsl_xfer, 0x51, &spd_eeprom);
> + ret = spd_read_eeprom(i2c, 0x51, &spd_eeprom);
> if (ret) {
> pr_err("Cannot read SPD EEPROM: %d\n", ret);
> goto err;
> diff --git a/arch/arm/boards/mnt-reform/lowlevel.c b/arch/arm/boards/mnt-reform/lowlevel.c
> index 644c42269d79..a845d36263fe 100644
> --- a/arch/arm/boards/mnt-reform/lowlevel.c
> +++ b/arch/arm/boards/mnt-reform/lowlevel.c
> @@ -7,7 +7,7 @@
> #include <common.h>
> #include <debug_ll.h>
> #include <firmware.h>
> -#include <i2c/i2c-early.h>
> +#include <pbl/i2c.h>
> #include <mach/atf.h>
> #include <mach/esdctl.h>
> #include <mach/generic.h>
> @@ -36,7 +36,7 @@ static void mnt_reform_setup_uart(void)
> putc_ll('>');
> }
>
> -static void i2c_mux_set(void *i2c, u8 channel)
> +static void i2c_mux_set(struct pbl_i2c *i2c, u8 channel)
> {
> int ret;
> u8 buf[1];
> @@ -50,12 +50,12 @@ static void i2c_mux_set(void *i2c, u8 channel)
>
> buf[0] = 1 << channel;
>
> - ret = i2c_fsl_xfer(i2c, msgs, ARRAY_SIZE(msgs));
> + ret = pbl_i2c_xfer(i2c, msgs, ARRAY_SIZE(msgs));
> if (ret != 1)
> pr_err("failed to set i2c mux\n");
> }
>
> -static void i2c_regulator_set_voltage(void *i2c, u8 reg, u8 voffs)
> +static void i2c_regulator_set_voltage(struct pbl_i2c *i2c, u8 reg, u8 voffs)
> {
> int ret;
> u8 buf[2];
> @@ -70,7 +70,7 @@ static void i2c_regulator_set_voltage(void *i2c, u8 reg, u8 voffs)
> buf[0] = reg;
> buf[1] = 0x80 + voffs;
>
> - ret = i2c_fsl_xfer(i2c, msgs, ARRAY_SIZE(msgs));
> + ret = pbl_i2c_xfer(i2c, msgs, ARRAY_SIZE(msgs));
> if (ret != 1)
> pr_err("failed to set voltage\n");
> }
> @@ -81,7 +81,7 @@ static void i2c_regulator_set_voltage(void *i2c, u8 reg, u8 voffs)
>
> static void mnt_reform_init_power(void)
> {
> - void *i2c;
> + struct pbl_i2c *i2c;
>
> imx8mq_setup_pad(IMX8MQ_PAD_I2C1_SCL__I2C1_SCL | I2C_PAD_CTRL);
> imx8mq_setup_pad(IMX8MQ_PAD_I2C1_SDA__I2C1_SDA | I2C_PAD_CTRL);
> diff --git a/arch/arm/boards/nxp-imx8mm-evk/lowlevel.c b/arch/arm/boards/nxp-imx8mm-evk/lowlevel.c
> index 888bdd079083..e52d0f29a4c9 100644
> --- a/arch/arm/boards/nxp-imx8mm-evk/lowlevel.c
> +++ b/arch/arm/boards/nxp-imx8mm-evk/lowlevel.c
> @@ -7,7 +7,7 @@
> #include <asm/cache.h>
> #include <asm/barebox-arm.h>
> #include <asm/barebox-arm-head.h>
> -#include <i2c/i2c-early.h>
> +#include <pbl/i2c.h>
> #include <linux/sizes.h>
> #include <mach/esdctl.h>
> #include <mach/generic.h>
> @@ -37,7 +37,7 @@ static void setup_uart(void)
> putc_ll('>');
> }
>
> -static void pmic_reg_write(void *i2c, int reg, uint8_t val)
> +static void pmic_reg_write(struct pbl_i2c *i2c, int reg, uint8_t val)
> {
> int ret;
> u8 buf[32];
> @@ -53,14 +53,14 @@ static void pmic_reg_write(void *i2c, int reg, uint8_t val)
>
> msgs[0].len = 2;
>
> - ret = i2c_fsl_xfer(i2c, msgs, ARRAY_SIZE(msgs));
> + ret = pbl_i2c_xfer(i2c, msgs, ARRAY_SIZE(msgs));
> if (ret != 1)
> pr_err("Failed to write to pmic\n");
> }
>
> static int power_init_board(void)
> {
> - void *i2c;
> + struct pbl_i2c *i2c;
>
> imx8mm_setup_pad(IMX8MM_PAD_I2C1_SCL_I2C1_SCL);
> imx8mm_setup_pad(IMX8MM_PAD_I2C1_SDA_I2C1_SDA);
> diff --git a/arch/arm/boards/nxp-imx8mn-evk/lowlevel.c b/arch/arm/boards/nxp-imx8mn-evk/lowlevel.c
> index f53f9c1c6172..37b983f6387a 100644
> --- a/arch/arm/boards/nxp-imx8mn-evk/lowlevel.c
> +++ b/arch/arm/boards/nxp-imx8mn-evk/lowlevel.c
> @@ -9,7 +9,7 @@
> #include <asm/sections.h>
> #include <asm/barebox-arm.h>
> #include <asm/barebox-arm-head.h>
> -#include <i2c/i2c-early.h>
> +#include <pbl/i2c.h>
> #include <linux/sizes.h>
> #include <mach/atf.h>
> #include <mach/xload.h>
> @@ -36,7 +36,7 @@ static void setup_uart(void)
> putc_ll('>');
> }
>
> -static void pmic_reg_write(void *i2c, int addr, int reg, uint8_t val)
> +static void pmic_reg_write(struct pbl_i2c *i2c, int addr, int reg, uint8_t val)
> {
> int ret;
> u8 buf[32];
> @@ -52,12 +52,12 @@ static void pmic_reg_write(void *i2c, int addr, int reg, uint8_t val)
>
> msgs[0].len = 2;
>
> - ret = i2c_fsl_xfer(i2c, msgs, ARRAY_SIZE(msgs));
> + ret = pbl_i2c_xfer(i2c, msgs, ARRAY_SIZE(msgs));
> if (ret != 1)
> pr_err("Failed to write to pmic@%x: %d\n", addr, ret);
> }
>
> -static int i2c_dev_detect(void *i2c, int addr)
> +static int i2c_dev_detect(struct pbl_i2c *i2c, int addr)
> {
> u8 buf[1];
> struct i2c_msg msgs[] = {
> @@ -69,10 +69,10 @@ static int i2c_dev_detect(void *i2c, int addr)
> },
> };
>
> - return i2c_fsl_xfer(i2c, msgs, 1) == 1 ? 0 : -ENODEV;
> + return pbl_i2c_xfer(i2c, msgs, 1) == 1 ? 0 : -ENODEV;
> }
>
> -static void power_init_board_pca9450(void *i2c, int addr)
> +static void power_init_board_pca9450(struct pbl_i2c *i2c, int addr)
> {
> /* BUCKxOUT_DVS0/1 control BUCK123 output */
> pmic_reg_write(i2c, addr, PCA9450_BUCK123_DVS, 0x29);
> @@ -100,7 +100,7 @@ static void power_init_board_pca9450(void *i2c, int addr)
> pmic_reg_write(i2c, addr, PCA9450_RESET_CTRL, 0xA1);
> }
>
> -static void power_init_board_bd71837(void *i2c, int addr)
> +static void power_init_board_bd71837(struct pbl_i2c *i2c, int addr)
> {
> /* decrease RESET key long push time from the default 10s to 10ms */
> pmic_reg_write(i2c, addr, BD718XX_PWRONCONFIG1, 0x0);
> @@ -129,7 +129,7 @@ extern struct dram_timing_info imx8mn_evk_ddr4_timing, imx8mn_evk_lpddr4_timing;
>
> static void start_atf(void)
> {
> - void *i2c;
> + struct pbl_i2c *i2c;
>
> /*
> * If we are in EL3 we are running for the first time and need to
> diff --git a/arch/arm/boards/nxp-imx8mp-evk/lowlevel.c b/arch/arm/boards/nxp-imx8mp-evk/lowlevel.c
> index 338c8024c4a1..43f7d194d806 100644
> --- a/arch/arm/boards/nxp-imx8mp-evk/lowlevel.c
> +++ b/arch/arm/boards/nxp-imx8mp-evk/lowlevel.c
> @@ -10,7 +10,7 @@
> #include <asm/sections.h>
> #include <asm/barebox-arm.h>
> #include <asm/barebox-arm-head.h>
> -#include <i2c/i2c-early.h>
> +#include <pbl/i2c.h>
> #include <linux/sizes.h>
> #include <mach/atf.h>
> #include <mach/xload.h>
> @@ -48,7 +48,7 @@ static void setup_uart(void)
> putc_ll('>');
> }
>
> -static void pmic_reg_write(void *i2c, int reg, uint8_t val)
> +static void pmic_reg_write(struct pbl_i2c *i2c, int reg, uint8_t val)
> {
> int ret;
> u8 buf[32];
> @@ -64,14 +64,14 @@ static void pmic_reg_write(void *i2c, int reg, uint8_t val)
>
> msgs[0].len = 2;
>
> - ret = i2c_fsl_xfer(i2c, msgs, ARRAY_SIZE(msgs));
> + ret = pbl_i2c_xfer(i2c, msgs, ARRAY_SIZE(msgs));
> if (ret != 1)
> pr_err("Failed to write to pmic\n");
> }
>
> static int power_init_board(void)
> {
> - void *i2c;
> + struct pbl_i2c *i2c;
>
> imx8mp_setup_pad(MX8MP_PAD_I2C1_SCL__I2C1_SCL | I2C_PAD_CTRL);
> imx8mp_setup_pad(MX8MP_PAD_I2C1_SDA__I2C1_SDA | I2C_PAD_CTRL);
> diff --git a/common/ddr_spd.c b/common/ddr_spd.c
> index 7089923afb94..52773178e78e 100644
> --- a/common/ddr_spd.c
> +++ b/common/ddr_spd.c
> @@ -6,6 +6,7 @@
> #include <common.h>
> #include <crc.h>
> #include <ddr_spd.h>
> +#include <pbl/i2c.h>
>
> /* used for ddr1 and ddr2 spd */
> static int spd_check(const u8 *buf, u8 spd_rev, u8 spd_cksum)
> @@ -430,9 +431,7 @@ void ddr_spd_print(uint8_t *record)
> #define SPD_SPA0_ADDRESS 0x36
> #define SPD_SPA1_ADDRESS 0x37
>
> -static int select_page(void *ctx,
> - int (*xfer)(void *ctx, struct i2c_msg *msgs, int num),
> - uint8_t addr)
> +static int select_page(struct pbl_i2c *i2c, uint8_t addr)
> {
> struct i2c_msg msg = {
> .addr = addr,
> @@ -440,15 +439,14 @@ static int select_page(void *ctx,
> };
> int ret;
>
> - ret = xfer(ctx, &msg, 1);
> + ret = pbl_i2c_xfer(i2c, &msg, 1);
> if (ret < 0)
> return ret;
>
> return 0;
> }
>
> -static int read_buf(void *ctx,
> - int (*xfer)(void *ctx, struct i2c_msg *msgs, int num),
> +static int read_buf(struct pbl_i2c *i2c,
> uint8_t addr, int page, void *buf)
> {
> uint8_t pos = 0;
> @@ -466,11 +464,11 @@ static int read_buf(void *ctx,
> }
> };
>
> - ret = select_page(ctx, xfer, page);
> + ret = select_page(i2c, page);
> if (ret < 0)
> return ret;
>
> - ret = xfer(ctx, msg, 2);
> + ret = pbl_i2c_xfer(i2c, msg, 2);
> if (ret < 0)
> return ret;
>
> @@ -479,8 +477,7 @@ static int read_buf(void *ctx,
>
> /**
> * spd_read_eeprom - Read contents of a SPD EEPROM
> - * @ctx: Context pointer for the xfer function
> - * @xfer: I2C message transfer function
> + * @i2c: I2C controller handle
> * @addr: I2C bus address for the EEPROM
> * @buf: buffer to read the SPD data to
> *
> @@ -489,19 +486,18 @@ static int read_buf(void *ctx,
> * have a size of 512 bytes. Returns 0 for success or a negative error code
> * otherwise.
> */
> -int spd_read_eeprom(void *ctx,
> - int (*xfer)(void *ctx, struct i2c_msg *msgs, int num),
> +int spd_read_eeprom(struct pbl_i2c *i2c,
> uint8_t addr, void *buf)
> {
> unsigned char *buf8 = buf;
> int ret;
>
> - ret = read_buf(ctx, xfer, addr, SPD_SPA0_ADDRESS, buf);
> + ret = read_buf(i2c, addr, SPD_SPA0_ADDRESS, buf);
> if (ret < 0)
> return ret;
>
> if (buf8[2] == SPD_MEMTYPE_DDR4) {
> - ret = read_buf(ctx, xfer, addr, SPD_SPA1_ADDRESS, buf + 256);
> + ret = read_buf(i2c, addr, SPD_SPA1_ADDRESS, buf + 256);
> if (ret < 0)
> return ret;
> }
> diff --git a/drivers/i2c/busses/i2c-imx-early.c b/drivers/i2c/busses/i2c-imx-early.c
> index a79d7bd88ce1..4e0f7e517d01 100644
> --- a/drivers/i2c/busses/i2c-imx-early.c
> +++ b/drivers/i2c/busses/i2c-imx-early.c
> @@ -9,11 +9,12 @@
> */
> #include <common.h>
> #include <i2c/i2c.h>
> -#include <i2c/i2c-early.h>
> +#include <pbl/i2c.h>
>
> #include "i2c-imx.h"
>
> struct fsl_i2c {
> + struct pbl_i2c i2c;
> void __iomem *regs;
> unsigned int i2cr_ien_opcode;
> unsigned int i2sr_clr_opcode;
> @@ -170,7 +171,7 @@ static int i2c_fsl_write(struct fsl_i2c *fsl_i2c, struct i2c_msg *msg)
> /* write data */
> for (i = 0; i < msg->len; i++) {
> ret = i2c_fsl_send(fsl_i2c, msg->buf[i]);
> - if (ret)
> + if (ret)
> return ret;
> }
>
> @@ -229,9 +230,9 @@ static int i2c_fsl_read(struct fsl_i2c *fsl_i2c, struct i2c_msg *msg)
> * If successful returns the number of messages transferred, otherwise a negative
> * error code is returned.
> */
> -int i2c_fsl_xfer(void *ctx, struct i2c_msg *msgs, int num)
> +static int i2c_fsl_xfer(struct pbl_i2c *i2c, struct i2c_msg *msgs, int num)
> {
> - struct fsl_i2c *fsl_i2c = ctx;
> + struct fsl_i2c *fsl_i2c = container_of(i2c, struct fsl_i2c, i2c);
> unsigned int i, temp;
> int ret;
>
> @@ -288,7 +289,7 @@ static struct fsl_i2c fsl_i2c;
> * This function returns a context pointer suitable to transfer I2C messages
> * using i2c_fsl_xfer.
> */
> -void *ls1046_i2c_init(void __iomem *regs)
> +struct pbl_i2c *ls1046_i2c_init(void __iomem *regs)
> {
> fsl_i2c.regs = regs;
> fsl_i2c.regshift = 0;
> @@ -297,10 +298,12 @@ void *ls1046_i2c_init(void __iomem *regs)
> /* Divider for ~100kHz when coming from the ROM */
> fsl_i2c.ifdr = 0x3e;
>
> - return &fsl_i2c;
> + fsl_i2c.i2c.xfer = i2c_fsl_xfer;
> +
> + return &fsl_i2c.i2c;
> }
>
> -void *imx8m_i2c_early_init(void __iomem *regs)
> +struct pbl_i2c *imx8m_i2c_early_init(void __iomem *regs)
> {
> fsl_i2c.regs = regs;
> fsl_i2c.regshift = 2;
> @@ -309,5 +312,7 @@ void *imx8m_i2c_early_init(void __iomem *regs)
> /* Divider for ~100kHz when coming from the ROM */
> fsl_i2c.ifdr = 0x0f;
>
> - return &fsl_i2c;
> + fsl_i2c.i2c.xfer = i2c_fsl_xfer;
> +
> + return &fsl_i2c.i2c;
> }
> diff --git a/include/ddr_spd.h b/include/ddr_spd.h
> index 6e63d90e5e20..bcc2171d2a50 100644
> --- a/include/ddr_spd.h
> +++ b/include/ddr_spd.h
> @@ -6,7 +6,7 @@
> #ifndef _DDR_SPD_H_
> #define _DDR_SPD_H_
>
> -#include <i2c/i2c.h>
> +#include <pbl/i2c.h>
>
> /*
> * Format from "JEDEC Standard No. 21-C,
> @@ -574,8 +574,7 @@ void ddr2_spd_dump(const struct ddr2_spd_eeprom *spd);
> int ddr3_spd_check(const struct ddr3_spd_eeprom *spd);
> int ddr4_spd_check(const struct ddr4_spd_eeprom *spd);
>
> -int spd_read_eeprom(void *ctx,
> - int (*xfer)(void *ctx, struct i2c_msg *msgs, int num),
> +int spd_read_eeprom(struct pbl_i2c *i2c,
> uint8_t addr, void *buf);
>
> #endif /* _DDR_SPD_H_ */
> diff --git a/include/i2c/i2c-early.h b/include/i2c/i2c-early.h
> deleted file mode 100644
> index fa93656e28e8..000000000000
> --- a/include/i2c/i2c-early.h
> +++ /dev/null
> @@ -1,13 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0-only */
> -
> -#ifndef __I2C_EARLY_H
> -#define __I2C_EARLY_H
> -
> -#include <i2c/i2c.h>
> -
> -int i2c_fsl_xfer(void *ctx, struct i2c_msg *msgs, int num);
> -
> -void *imx8m_i2c_early_init(void __iomem *regs);
> -void *ls1046_i2c_init(void __iomem *regs);
> -
> -#endif /* __I2C_EARLY_H */
> diff --git a/include/pbl/i2c.h b/include/pbl/i2c.h
> new file mode 100644
> index 000000000000..1f26e3dfc6ca
> --- /dev/null
> +++ b/include/pbl/i2c.h
> @@ -0,0 +1,21 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +
> +#ifndef __PBL_I2C_H
> +#define __PBL_I2C_H
> +
> +#include <i2c/i2c.h>
> +
> +struct pbl_i2c {
> + int (*xfer)(struct pbl_i2c *, struct i2c_msg *msgs, int num);
> +};
> +
> +static inline int pbl_i2c_xfer(struct pbl_i2c *i2c,
> + struct i2c_msg *msgs, int num)
> +{
> + return i2c->xfer(i2c, msgs, num);
> +}
> +
> +struct pbl_i2c *imx8m_i2c_early_init(void __iomem *regs);
> +struct pbl_i2c *ls1046_i2c_init(void __iomem *regs);
> +
> +#endif /* __I2C_EARLY_H */
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 8/9] i2c: add <pbl/pmic.h> for PBL use
2022-08-05 12:54 [PATCH 0/9] ARM: i.MX8MN: clean up and enable imx-usb-loader Ahmad Fatoum
` (6 preceding siblings ...)
2022-08-05 12:54 ` [PATCH 7/9] pbl: generalize fsl i2c_early API into pbl_i2c Ahmad Fatoum
@ 2022-08-05 12:54 ` Ahmad Fatoum
2022-08-05 12:54 ` [PATCH 9/9] ARM: i.MX8M: use new pbl/pmic.h API Ahmad Fatoum
` (2 subsequent siblings)
10 siblings, 0 replies; 13+ messages in thread
From: Ahmad Fatoum @ 2022-08-05 12:54 UTC (permalink / raw)
To: barebox; +Cc: mfe, Ahmad Fatoum
We have much duplication in the i.MX8M boards related to PMIC setup,
add a common header to cut down on it.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
include/pbl/i2c.h | 16 ++++++++++++++++
include/pbl/pmic.h | 41 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 57 insertions(+)
create mode 100644 include/pbl/pmic.h
diff --git a/include/pbl/i2c.h b/include/pbl/i2c.h
index 1f26e3dfc6ca..d9910f531f53 100644
--- a/include/pbl/i2c.h
+++ b/include/pbl/i2c.h
@@ -18,4 +18,20 @@ static inline int pbl_i2c_xfer(struct pbl_i2c *i2c,
struct pbl_i2c *imx8m_i2c_early_init(void __iomem *regs);
struct pbl_i2c *ls1046_i2c_init(void __iomem *regs);
+static inline int i2c_dev_probe(struct pbl_i2c *i2c, int addr, bool onebyte)
+{
+ u8 buf[1];
+ struct i2c_msg msgs[] = {
+ {
+ .addr = addr,
+ .buf = buf,
+ .flags = I2C_M_RD,
+ .len = onebyte,
+ },
+ };
+
+ return pbl_i2c_xfer(i2c, msgs, 1) == 1 ? 0 : -ENODEV;
+}
+
+
#endif /* __I2C_EARLY_H */
diff --git a/include/pbl/pmic.h b/include/pbl/pmic.h
new file mode 100644
index 000000000000..0f882c5649d9
--- /dev/null
+++ b/include/pbl/pmic.h
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __PBL_PMIC_H_
+#define __PBL_PMIC_H_
+
+#include <pbl/i2c.h>
+
+struct pmic_config {
+ u8 reg;
+ u8 val;
+};
+
+static void pmic_reg_write(struct pbl_i2c *i2c, int addr, u8 reg, u8 val)
+{
+ int ret;
+ u8 buf[32];
+ struct i2c_msg msgs[] = {
+ {
+ .addr = addr,
+ .buf = buf,
+ },
+ };
+
+ buf[0] = reg;
+ buf[1] = val;
+
+ msgs[0].len = 2;
+
+ ret = pbl_i2c_xfer(i2c, msgs, ARRAY_SIZE(msgs));
+ if (ret != 1)
+ pr_err("Failed to write to pmic@%x: %d\n", addr, ret);
+}
+
+static inline void pmic_configure(struct pbl_i2c *i2c, u8 addr,
+ const struct pmic_config *config,
+ size_t config_len)
+{
+ for (; config_len--; config++)
+ pmic_reg_write(i2c, addr, config->reg, config->val);
+}
+
+#endif
--
2.30.2
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 9/9] ARM: i.MX8M: use new pbl/pmic.h API
2022-08-05 12:54 [PATCH 0/9] ARM: i.MX8MN: clean up and enable imx-usb-loader Ahmad Fatoum
` (7 preceding siblings ...)
2022-08-05 12:54 ` [PATCH 8/9] i2c: add <pbl/pmic.h> for PBL use Ahmad Fatoum
@ 2022-08-05 12:54 ` Ahmad Fatoum
2022-08-08 8:30 ` [PATCH 0/9] ARM: i.MX8MN: clean up and enable imx-usb-loader Marco Felsch
2022-08-08 12:32 ` Sascha Hauer
10 siblings, 0 replies; 13+ messages in thread
From: Ahmad Fatoum @ 2022-08-05 12:54 UTC (permalink / raw)
To: barebox; +Cc: mfe, Ahmad Fatoum
This cuts down on code size a bit and removes the i2c xfer boilerplate
out of the drivers.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
arch/arm/boards/mnt-reform/lowlevel.c | 18 +----
arch/arm/boards/nxp-imx8mm-evk/lowlevel.c | 52 ++++---------
arch/arm/boards/nxp-imx8mn-evk/lowlevel.c | 95 ++++++-----------------
arch/arm/boards/nxp-imx8mp-evk/lowlevel.c | 56 +++++--------
4 files changed, 58 insertions(+), 163 deletions(-)
diff --git a/arch/arm/boards/mnt-reform/lowlevel.c b/arch/arm/boards/mnt-reform/lowlevel.c
index a845d36263fe..d22c8b8a7494 100644
--- a/arch/arm/boards/mnt-reform/lowlevel.c
+++ b/arch/arm/boards/mnt-reform/lowlevel.c
@@ -8,6 +8,7 @@
#include <debug_ll.h>
#include <firmware.h>
#include <pbl/i2c.h>
+#include <pbl/pmic.h>
#include <mach/atf.h>
#include <mach/esdctl.h>
#include <mach/generic.h>
@@ -57,22 +58,7 @@ static void i2c_mux_set(struct pbl_i2c *i2c, u8 channel)
static void i2c_regulator_set_voltage(struct pbl_i2c *i2c, u8 reg, u8 voffs)
{
- int ret;
- u8 buf[2];
- struct i2c_msg msgs[] = {
- {
- .addr = 0x60,
- .buf = buf,
- .len = 2,
- },
- };
-
- buf[0] = reg;
- buf[1] = 0x80 + voffs;
-
- ret = pbl_i2c_xfer(i2c, msgs, ARRAY_SIZE(msgs));
- if (ret != 1)
- pr_err("failed to set voltage\n");
+ pmic_reg_write(i2c, 0x60, reg, 0x80 + voffs);
}
#define I2C_PAD_CTRL MUX_PAD_CTRL(MX8MQ_PAD_CTL_DSE_45R | \
diff --git a/arch/arm/boards/nxp-imx8mm-evk/lowlevel.c b/arch/arm/boards/nxp-imx8mm-evk/lowlevel.c
index e52d0f29a4c9..6132df53ec75 100644
--- a/arch/arm/boards/nxp-imx8mm-evk/lowlevel.c
+++ b/arch/arm/boards/nxp-imx8mm-evk/lowlevel.c
@@ -8,6 +8,7 @@
#include <asm/barebox-arm.h>
#include <asm/barebox-arm-head.h>
#include <pbl/i2c.h>
+#include <pbl/pmic.h>
#include <linux/sizes.h>
#include <mach/esdctl.h>
#include <mach/generic.h>
@@ -37,28 +38,20 @@ static void setup_uart(void)
putc_ll('>');
}
-static void pmic_reg_write(struct pbl_i2c *i2c, int reg, uint8_t val)
-{
- int ret;
- u8 buf[32];
- struct i2c_msg msgs[] = {
- {
- .addr = 0x4b,
- .buf = buf,
- },
- };
-
- buf[0] = reg;
- buf[1] = val;
-
- msgs[0].len = 2;
-
- ret = pbl_i2c_xfer(i2c, msgs, ARRAY_SIZE(msgs));
- if (ret != 1)
- pr_err("Failed to write to pmic\n");
-}
+static struct pmic_config bd71837_cfg[] = {
+ /* decrease RESET key long push time from the default 10s to 10ms */
+ { BD718XX_PWRONCONFIG1, 0x0 },
+ /* unlock the PMIC regs */
+ { BD718XX_REGLOCK, 0x1 },
+ /* increase VDD_SOC to typical value 0.85v before first DRAM access */
+ { BD718XX_BUCK1_VOLT_RUN, 0x0f },
+ /* increase VDD_DRAM to 0.975v for 3Ghz DDR */
+ { BD718XX_1ST_NODVS_BUCK_VOLT, 0x83 },
+ /* lock the PMIC regs */
+ { BD718XX_REGLOCK, 0x11 },
+};
-static int power_init_board(void)
+static void power_init_board(void)
{
struct pbl_i2c *i2c;
@@ -70,22 +63,7 @@ static int power_init_board(void)
i2c = imx8m_i2c_early_init(IOMEM(MX8MQ_I2C1_BASE_ADDR));
- /* decrease RESET key long push time from the default 10s to 10ms */
- pmic_reg_write(i2c, BD718XX_PWRONCONFIG1, 0x0);
-
- /* unlock the PMIC regs */
- pmic_reg_write(i2c, BD718XX_REGLOCK, 0x1);
-
- /* increase VDD_SOC to typical value 0.85v before first DRAM access */
- pmic_reg_write(i2c, BD718XX_BUCK1_VOLT_RUN, 0x0f);
-
- /* increase VDD_DRAM to 0.975v for 3Ghz DDR */
- pmic_reg_write(i2c, BD718XX_1ST_NODVS_BUCK_VOLT, 0x83);
-
- /* lock the PMIC regs */
- pmic_reg_write(i2c, BD718XX_REGLOCK, 0x11);
-
- return 0;
+ pmic_configure(i2c, 0x4b, bd71837_cfg, ARRAY_SIZE(bd71837_cfg));
}
extern struct dram_timing_info imx8mm_evk_dram_timing;
diff --git a/arch/arm/boards/nxp-imx8mn-evk/lowlevel.c b/arch/arm/boards/nxp-imx8mn-evk/lowlevel.c
index 37b983f6387a..7da9c3356573 100644
--- a/arch/arm/boards/nxp-imx8mn-evk/lowlevel.c
+++ b/arch/arm/boards/nxp-imx8mn-evk/lowlevel.c
@@ -10,6 +10,7 @@
#include <asm/barebox-arm.h>
#include <asm/barebox-arm-head.h>
#include <pbl/i2c.h>
+#include <pbl/pmic.h>
#include <linux/sizes.h>
#include <mach/atf.h>
#include <mach/xload.h>
@@ -36,94 +37,44 @@ static void setup_uart(void)
putc_ll('>');
}
-static void pmic_reg_write(struct pbl_i2c *i2c, int addr, int reg, uint8_t val)
-{
- int ret;
- u8 buf[32];
- struct i2c_msg msgs[] = {
- {
- .addr = addr,
- .buf = buf,
- },
- };
-
- buf[0] = reg;
- buf[1] = val;
-
- msgs[0].len = 2;
-
- ret = pbl_i2c_xfer(i2c, msgs, ARRAY_SIZE(msgs));
- if (ret != 1)
- pr_err("Failed to write to pmic@%x: %d\n", addr, ret);
-}
-
-static int i2c_dev_detect(struct pbl_i2c *i2c, int addr)
-{
- u8 buf[1];
- struct i2c_msg msgs[] = {
- {
- .addr = addr,
- .buf = buf,
- .flags = I2C_M_RD,
- .len = 1,
- },
- };
-
- return pbl_i2c_xfer(i2c, msgs, 1) == 1 ? 0 : -ENODEV;
-}
-
-static void power_init_board_pca9450(struct pbl_i2c *i2c, int addr)
-{
+static struct pmic_config pca9450_cfg[] = {
/* BUCKxOUT_DVS0/1 control BUCK123 output */
- pmic_reg_write(i2c, addr, PCA9450_BUCK123_DVS, 0x29);
-
+ { PCA9450_BUCK123_DVS, 0x29 },
/*
* increase VDD_SOC to typical value 0.95V before first
* DRAM access, set DVS1 to 0.85v for suspend.
* Enable DVS control through PMIC_STBY_REQ and
* set B1_ENMODE=1 (ON by PMIC_ON_REQ=H)
*/
- pmic_reg_write(i2c, addr, PCA9450_BUCK1OUT_DVS0, 0x1C);
-
+ { PCA9450_BUCK1OUT_DVS0, 0x1C },
/* Set DVS1 to 0.85v for suspend */
/* Enable DVS control through PMIC_STBY_REQ and set B1_ENMODE=1 (ON by PMIC_ON_REQ=H) */
- pmic_reg_write(i2c, addr, PCA9450_BUCK1OUT_DVS1, 0x14);
- pmic_reg_write(i2c, addr, PCA9450_BUCK1CTRL, 0x59);
-
+ { PCA9450_BUCK1OUT_DVS1, 0x14 },
+ { PCA9450_BUCK1CTRL, 0x59 },
/* set VDD_SNVS_0V8 from default 0.85V */
- pmic_reg_write(i2c, addr, PCA9450_LDO2CTRL, 0xC0);
-
+ { PCA9450_LDO2CTRL, 0xC0 },
/* enable LDO4 to 1.2v */
- pmic_reg_write(i2c, addr, PCA9450_LDO4CTRL, 0x44);
-
+ { PCA9450_LDO4CTRL, 0x44 },
/* set WDOG_B_CFG to cold reset */
- pmic_reg_write(i2c, addr, PCA9450_RESET_CTRL, 0xA1);
-}
+ { PCA9450_RESET_CTRL, 0xA1 },
+};
-static void power_init_board_bd71837(struct pbl_i2c *i2c, int addr)
-{
+static struct pmic_config bd71837_cfg[] = {
/* decrease RESET key long push time from the default 10s to 10ms */
- pmic_reg_write(i2c, addr, BD718XX_PWRONCONFIG1, 0x0);
-
+ { BD718XX_PWRONCONFIG1, 0x0 },
/* unlock the PMIC regs */
- pmic_reg_write(i2c, addr, BD718XX_REGLOCK, 0x1);
-
+ { BD718XX_REGLOCK, 0x1 },
/* Set VDD_ARM to typical value 0.85v for 1.2Ghz */
- pmic_reg_write(i2c, addr, BD718XX_BUCK2_VOLT_RUN, 0xf);
-
+ { BD718XX_BUCK2_VOLT_RUN, 0xf },
/* Set VDD_SOC/VDD_DRAM to typical value 0.85v for nominal mode */
- pmic_reg_write(i2c, addr, BD718XX_BUCK1_VOLT_RUN, 0xf);
-
+ { BD718XX_BUCK1_VOLT_RUN, 0xf },
/* Set VDD_SOC 0.85v for suspend */
- pmic_reg_write(i2c, addr, BD718XX_BUCK1_VOLT_SUSP, 0xf);
-
- /* increase NVCC_DRAM_1V2 to 1.2v for DDR4
- * */
- pmic_reg_write(i2c, addr, BD718XX_4TH_NODVS_BUCK_CTRL, 0x28);
-
+ { BD718XX_BUCK1_VOLT_SUSP, 0xf },
+ /* increase NVCC_DRAM_1V2 to 1.2v for DDR4 */
+ { BD718XX_4TH_NODVS_BUCK_CTRL, 0x28 },
/* lock the PMIC regs */
- pmic_reg_write(i2c, addr, BD718XX_REGLOCK, 0x11);
-}
+ { BD718XX_REGLOCK, 0x11 },
+};
extern struct dram_timing_info imx8mn_evk_ddr4_timing, imx8mn_evk_lpddr4_timing;
@@ -147,11 +98,11 @@ static void start_atf(void)
i2c = imx8m_i2c_early_init(IOMEM(MX8MN_I2C1_BASE_ADDR));
- if (i2c_dev_detect(i2c, 0x25) == 0) {
- power_init_board_pca9450(i2c, 0x25);
+ if (i2c_dev_probe(i2c, 0x25, true) == 0) {
+ pmic_configure(i2c, 0x25, pca9450_cfg, ARRAY_SIZE(pca9450_cfg));
imx8mn_ddr_init(&imx8mn_evk_lpddr4_timing, DRAM_TYPE_LPDDR4);
} else {
- power_init_board_bd71837(i2c, 0x4b);
+ pmic_configure(i2c, 0x4b, bd71837_cfg, ARRAY_SIZE(bd71837_cfg));
imx8mn_ddr_init(&imx8mn_evk_ddr4_timing, DRAM_TYPE_DDR4);
}
diff --git a/arch/arm/boards/nxp-imx8mp-evk/lowlevel.c b/arch/arm/boards/nxp-imx8mp-evk/lowlevel.c
index 43f7d194d806..4f24dd4cd426 100644
--- a/arch/arm/boards/nxp-imx8mp-evk/lowlevel.c
+++ b/arch/arm/boards/nxp-imx8mp-evk/lowlevel.c
@@ -11,6 +11,7 @@
#include <asm/barebox-arm.h>
#include <asm/barebox-arm-head.h>
#include <pbl/i2c.h>
+#include <pbl/pmic.h>
#include <linux/sizes.h>
#include <mach/atf.h>
#include <mach/xload.h>
@@ -48,28 +49,23 @@ static void setup_uart(void)
putc_ll('>');
}
-static void pmic_reg_write(struct pbl_i2c *i2c, int reg, uint8_t val)
-{
- int ret;
- u8 buf[32];
- struct i2c_msg msgs[] = {
- {
- .addr = 0x25,
- .buf = buf,
- },
- };
-
- buf[0] = reg;
- buf[1] = val;
-
- msgs[0].len = 2;
-
- ret = pbl_i2c_xfer(i2c, msgs, ARRAY_SIZE(msgs));
- if (ret != 1)
- pr_err("Failed to write to pmic\n");
-}
+static struct pmic_config pca9450_cfg[] = {
+ /* BUCKxOUT_DVS0/1 control BUCK123 output */
+ { PCA9450_BUCK123_DVS, 0x29 },
+ /*
+ * increase VDD_SOC to typical value 0.95V before first
+ * DRAM access, set DVS1 to 0.85v for suspend.
+ * Enable DVS control through PMIC_STBY_REQ and
+ * set B1_ENMODE=1 (ON by PMIC_ON_REQ=H)
+ */
+ { PCA9450_BUCK1OUT_DVS0, 0x1C },
+ { PCA9450_BUCK1OUT_DVS1, 0x14 },
+ { PCA9450_BUCK1CTRL, 0x59 },
+ /* set WDOG_B_CFG to cold reset */
+ { PCA9450_RESET_CTRL, 0xA1 },
+};
-static int power_init_board(void)
+static void power_init_board(void)
{
struct pbl_i2c *i2c;
@@ -81,23 +77,7 @@ static int power_init_board(void)
i2c = imx8m_i2c_early_init(IOMEM(MX8MP_I2C1_BASE_ADDR));
- /* BUCKxOUT_DVS0/1 control BUCK123 output */
- pmic_reg_write(i2c, PCA9450_BUCK123_DVS, 0x29);
-
- /*
- * increase VDD_SOC to typical value 0.95V before first
- * DRAM access, set DVS1 to 0.85v for suspend.
- * Enable DVS control through PMIC_STBY_REQ and
- * set B1_ENMODE=1 (ON by PMIC_ON_REQ=H)
- */
- pmic_reg_write(i2c, PCA9450_BUCK1OUT_DVS0, 0x1C);
- pmic_reg_write(i2c, PCA9450_BUCK1OUT_DVS1, 0x14);
- pmic_reg_write(i2c, PCA9450_BUCK1CTRL, 0x59);
-
- /* set WDOG_B_CFG to cold reset */
- pmic_reg_write(i2c, PCA9450_RESET_CTRL, 0xA1);
-
- return 0;
+ pmic_configure(i2c, 0x25, pca9450_cfg, ARRAY_SIZE(pca9450_cfg));
}
extern struct dram_timing_info imx8mp_evk_dram_timing;
--
2.30.2
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 0/9] ARM: i.MX8MN: clean up and enable imx-usb-loader
2022-08-05 12:54 [PATCH 0/9] ARM: i.MX8MN: clean up and enable imx-usb-loader Ahmad Fatoum
` (8 preceding siblings ...)
2022-08-05 12:54 ` [PATCH 9/9] ARM: i.MX8M: use new pbl/pmic.h API Ahmad Fatoum
@ 2022-08-08 8:30 ` Marco Felsch
2022-08-08 12:32 ` Sascha Hauer
10 siblings, 0 replies; 13+ messages in thread
From: Marco Felsch @ 2022-08-08 8:30 UTC (permalink / raw)
To: Ahmad Fatoum; +Cc: barebox
On 22-08-05, Ahmad Fatoum wrote:
> This series applies on top of <20220714072722.2863571-1-s.hauer@pengutronix.de>
>
> Ahmad Fatoum (9):
> ARM: i.MX8M: move TF-A chainload functions in <mach/xload.h>
> ARM: i.MX8M: imx8mn-evk: use generic
> imx8mn_load_and_start_image_via_tfa
> ARM: i.MX8MN: add SDPS barebox-side support
> ARM: i.MX8MN: evk: simplify DDR4/LPDDR4 selection code
> ddr: imx8m: rename type to more fitting ddrc|dram_type
> ARM: i.MX8M: remove struct dram_timing_info::dram_type again
> pbl: generalize fsl i2c_early API into pbl_i2c
> i2c: add <pbl/pmic.h> for PBL use
> ARM: i.MX8M: use new pbl/pmic.h API
Hi Ahmad,
whole series LGTM.
Reviewed-by: Marco Felsch <m.felsch@pengutronix.de>
>
> arch/arm/boards/ls1046ardb/lowlevel.c | 6 +-
> arch/arm/boards/mnt-reform/lowlevel.c | 28 +---
> arch/arm/boards/mnt-reform/lpddr4-timing.c | 1 -
> arch/arm/boards/nxp-imx8mm-evk/lowlevel.c | 58 +++-----
> .../arm/boards/nxp-imx8mm-evk/lpddr4-timing.c | 1 -
> arch/arm/boards/nxp-imx8mn-evk/ddr4-timing.c | 1 -
> arch/arm/boards/nxp-imx8mn-evk/lowlevel.c | 140 ++++--------------
> .../arm/boards/nxp-imx8mn-evk/lpddr4-timing.c | 1 -
> arch/arm/boards/nxp-imx8mp-evk/lowlevel.c | 61 +++-----
> .../arm/boards/nxp-imx8mp-evk/lpddr4-timing.c | 1 -
> .../boards/protonic-imx8m/lowlevel-prt8mm.c | 1 -
> .../protonic-imx8m/lpddr4-timing-prt8mm.c | 1 -
> arch/arm/mach-imx/atf.c | 40 ++++-
> arch/arm/mach-imx/include/mach/xload.h | 4 +
> common/ddr_spd.c | 24 ++-
> drivers/ddr/imx8m/ddr_init.c | 11 +-
> drivers/ddr/imx8m/ddrphy_train.c | 8 +-
> drivers/i2c/busses/i2c-imx-early.c | 21 ++-
> include/ddr_spd.h | 5 +-
> include/i2c/i2c-early.h | 13 --
> include/pbl/i2c.h | 37 +++++
> include/pbl/pmic.h | 41 +++++
> include/soc/imx8m.h | 9 --
> include/soc/imx8m/ddr.h | 79 +++++-----
> 24 files changed, 279 insertions(+), 313 deletions(-)
> delete mode 100644 include/i2c/i2c-early.h
> create mode 100644 include/pbl/i2c.h
> create mode 100644 include/pbl/pmic.h
> delete mode 100644 include/soc/imx8m.h
>
> --
> 2.30.2
>
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 0/9] ARM: i.MX8MN: clean up and enable imx-usb-loader
2022-08-05 12:54 [PATCH 0/9] ARM: i.MX8MN: clean up and enable imx-usb-loader Ahmad Fatoum
` (9 preceding siblings ...)
2022-08-08 8:30 ` [PATCH 0/9] ARM: i.MX8MN: clean up and enable imx-usb-loader Marco Felsch
@ 2022-08-08 12:32 ` Sascha Hauer
10 siblings, 0 replies; 13+ messages in thread
From: Sascha Hauer @ 2022-08-08 12:32 UTC (permalink / raw)
To: Ahmad Fatoum; +Cc: barebox, mfe
On Fri, Aug 05, 2022 at 02:54:04PM +0200, Ahmad Fatoum wrote:
> This series applies on top of <20220714072722.2863571-1-s.hauer@pengutronix.de>
>
> Ahmad Fatoum (9):
> ARM: i.MX8M: move TF-A chainload functions in <mach/xload.h>
> ARM: i.MX8M: imx8mn-evk: use generic
> imx8mn_load_and_start_image_via_tfa
> ARM: i.MX8MN: add SDPS barebox-side support
> ARM: i.MX8MN: evk: simplify DDR4/LPDDR4 selection code
> ddr: imx8m: rename type to more fitting ddrc|dram_type
> ARM: i.MX8M: remove struct dram_timing_info::dram_type again
> pbl: generalize fsl i2c_early API into pbl_i2c
> i2c: add <pbl/pmic.h> for PBL use
> ARM: i.MX8M: use new pbl/pmic.h API
Applied, thanks
Sascha
>
> arch/arm/boards/ls1046ardb/lowlevel.c | 6 +-
> arch/arm/boards/mnt-reform/lowlevel.c | 28 +---
> arch/arm/boards/mnt-reform/lpddr4-timing.c | 1 -
> arch/arm/boards/nxp-imx8mm-evk/lowlevel.c | 58 +++-----
> .../arm/boards/nxp-imx8mm-evk/lpddr4-timing.c | 1 -
> arch/arm/boards/nxp-imx8mn-evk/ddr4-timing.c | 1 -
> arch/arm/boards/nxp-imx8mn-evk/lowlevel.c | 140 ++++--------------
> .../arm/boards/nxp-imx8mn-evk/lpddr4-timing.c | 1 -
> arch/arm/boards/nxp-imx8mp-evk/lowlevel.c | 61 +++-----
> .../arm/boards/nxp-imx8mp-evk/lpddr4-timing.c | 1 -
> .../boards/protonic-imx8m/lowlevel-prt8mm.c | 1 -
> .../protonic-imx8m/lpddr4-timing-prt8mm.c | 1 -
> arch/arm/mach-imx/atf.c | 40 ++++-
> arch/arm/mach-imx/include/mach/xload.h | 4 +
> common/ddr_spd.c | 24 ++-
> drivers/ddr/imx8m/ddr_init.c | 11 +-
> drivers/ddr/imx8m/ddrphy_train.c | 8 +-
> drivers/i2c/busses/i2c-imx-early.c | 21 ++-
> include/ddr_spd.h | 5 +-
> include/i2c/i2c-early.h | 13 --
> include/pbl/i2c.h | 37 +++++
> include/pbl/pmic.h | 41 +++++
> include/soc/imx8m.h | 9 --
> include/soc/imx8m/ddr.h | 79 +++++-----
> 24 files changed, 279 insertions(+), 313 deletions(-)
> delete mode 100644 include/i2c/i2c-early.h
> create mode 100644 include/pbl/i2c.h
> create mode 100644 include/pbl/pmic.h
> delete mode 100644 include/soc/imx8m.h
>
> --
> 2.30.2
>
>
>
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply [flat|nested] 13+ messages in thread