[U-Boot] [PATCH] hikey: Take peripherals out of reset during board init

Peripherals like I2C and SPI needs to be taken out of reset during board init for functioning properly. Hence, add `hi6220_periph_reset` function for doing the same. For instance without this function, I2C will fail like below while booting linux:
[ 0.608033] i2c_designware f7100000.i2c: Unknown Synopsys component type: 0x00000000 [ 0.621378] i2c_designware f7101000.i2c: Unknown Synopsys component type: 0x00000000 [ 0.633818] i2c_designware f7102000.i2c: Unknown Synopsys component type: 0x00000000
Signed-off-by: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org --- board/hisilicon/hikey/hikey.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
diff --git a/board/hisilicon/hikey/hikey.c b/board/hisilicon/hikey/hikey.c index 940ae82c45b..f8b8c372bfd 100644 --- a/board/hisilicon/hikey/hikey.c +++ b/board/hisilicon/hikey/hikey.c @@ -364,6 +364,20 @@ static void hi6220_pmussi_init(void) gpio_direction_output(0, 1); }
+static void hi6220_periph_reset(void) +{ + u32 data, bits; + + /* Bring I2C0/I2C1/I2C2/SPI0 out of reset */ + bits = PERI_RST3_I2C0 | PERI_RST3_I2C1 | PERI_RST3_I2C2 | PERI_RST3_SSP; + writel(bits, &peri_sc->rst3_dis); + + /* Wait until the peripherals are out of reset */ + do { + data = readl(&peri_sc->rst3_dis); + } while (data & bits); +} + int misc_init_r(void) { return 0; @@ -371,6 +385,8 @@ int misc_init_r(void)
int board_init(void) { + hi6220_periph_reset(); + return 0; }

Hi Mani,
This looks like a bug in the Linux kernel. The kernel driver should be correctly handling the reset lines of the I2C or SPI peripheral rather than replying on the bootloader to have already taken it out of reset.
Peter.
On Fri, 8 Mar 2019 at 08:57, Manivannan Sadhasivam < manivannan.sadhasivam@linaro.org> wrote:
Peripherals like I2C and SPI needs to be taken out of reset during board init for functioning properly. Hence, add `hi6220_periph_reset` function for doing the same. For instance without this function, I2C will fail like below while booting linux:
[ 0.608033] i2c_designware f7100000.i2c: Unknown Synopsys component type: 0x00000000 [ 0.621378] i2c_designware f7101000.i2c: Unknown Synopsys component type: 0x00000000 [ 0.633818] i2c_designware f7102000.i2c: Unknown Synopsys component type: 0x00000000
Signed-off-by: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org
board/hisilicon/hikey/hikey.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
diff --git a/board/hisilicon/hikey/hikey.c b/board/hisilicon/hikey/hikey.c index 940ae82c45b..f8b8c372bfd 100644 --- a/board/hisilicon/hikey/hikey.c +++ b/board/hisilicon/hikey/hikey.c @@ -364,6 +364,20 @@ static void hi6220_pmussi_init(void) gpio_direction_output(0, 1); }
+static void hi6220_periph_reset(void) +{
u32 data, bits;
/* Bring I2C0/I2C1/I2C2/SPI0 out of reset */
bits = PERI_RST3_I2C0 | PERI_RST3_I2C1 | PERI_RST3_I2C2 |
PERI_RST3_SSP;
writel(bits, &peri_sc->rst3_dis);
/* Wait until the peripherals are out of reset */
do {
data = readl(&peri_sc->rst3_dis);
} while (data & bits);
+}
int misc_init_r(void) { return 0; @@ -371,6 +385,8 @@ int misc_init_r(void)
int board_init(void) {
hi6220_periph_reset();
return 0;
}
-- 2.17.1

Hi Peter,
On Tue, Mar 19, 2019 at 11:29:01AM +0000, Peter Griffin wrote:
Hi Mani,
This looks like a bug in the Linux kernel. The kernel driver should be correctly handling the reset lines of the I2C or SPI peripheral rather than replying on the bootloader to have already taken it out of reset.
Correct. After sending this patch out, I sent a patchset to LKML [1] for fixing the issue in Linux kernel (thanks to Daniel for suggesting the change). But, we might need this hack in u-boot to make the old kernel/dts to work properly. And that's the reason I didn't abandon this patch.
Thanks, Mani
[1] https://lkml.org/lkml/2019/3/8/878
Peter.
On Fri, 8 Mar 2019 at 08:57, Manivannan Sadhasivam < manivannan.sadhasivam@linaro.org> wrote:
Peripherals like I2C and SPI needs to be taken out of reset during board init for functioning properly. Hence, add `hi6220_periph_reset` function for doing the same. For instance without this function, I2C will fail like below while booting linux:
[ 0.608033] i2c_designware f7100000.i2c: Unknown Synopsys component type: 0x00000000 [ 0.621378] i2c_designware f7101000.i2c: Unknown Synopsys component type: 0x00000000 [ 0.633818] i2c_designware f7102000.i2c: Unknown Synopsys component type: 0x00000000
Signed-off-by: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org
board/hisilicon/hikey/hikey.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
diff --git a/board/hisilicon/hikey/hikey.c b/board/hisilicon/hikey/hikey.c index 940ae82c45b..f8b8c372bfd 100644 --- a/board/hisilicon/hikey/hikey.c +++ b/board/hisilicon/hikey/hikey.c @@ -364,6 +364,20 @@ static void hi6220_pmussi_init(void) gpio_direction_output(0, 1); }
+static void hi6220_periph_reset(void) +{
u32 data, bits;
/* Bring I2C0/I2C1/I2C2/SPI0 out of reset */
bits = PERI_RST3_I2C0 | PERI_RST3_I2C1 | PERI_RST3_I2C2 |
PERI_RST3_SSP;
writel(bits, &peri_sc->rst3_dis);
/* Wait until the peripherals are out of reset */
do {
data = readl(&peri_sc->rst3_dis);
} while (data & bits);
+}
int misc_init_r(void) { return 0; @@ -371,6 +385,8 @@ int misc_init_r(void)
int board_init(void) {
hi6220_periph_reset();
return 0;
}
-- 2.17.1

On Wed, Mar 20, 2019 at 11:56:58AM +0530, Manivannan Sadhasivam wrote:
Hi Peter,
On Tue, Mar 19, 2019 at 11:29:01AM +0000, Peter Griffin wrote:
Hi Mani,
This looks like a bug in the Linux kernel. The kernel driver should be correctly handling the reset lines of the I2C or SPI peripheral rather than replying on the bootloader to have already taken it out of reset.
Correct. After sending this patch out, I sent a patchset to LKML [1] for fixing the issue in Linux kernel (thanks to Daniel for suggesting the change). But, we might need this hack in u-boot to make the old kernel/dts to work properly. And that's the reason I didn't abandon this patch.
Hacks like this develop a lot of legacy.
To be honest I don't really have much skin in the game here but even so I'd prefer to see kernel patches back ported to keep any old kernels running.
Daniel.
Thanks, Mani
[1] https://lkml.org/lkml/2019/3/8/878
Peter.
On Fri, 8 Mar 2019 at 08:57, Manivannan Sadhasivam < manivannan.sadhasivam@linaro.org> wrote:
Peripherals like I2C and SPI needs to be taken out of reset during board init for functioning properly. Hence, add `hi6220_periph_reset` function for doing the same. For instance without this function, I2C will fail like below while booting linux:
[ 0.608033] i2c_designware f7100000.i2c: Unknown Synopsys component type: 0x00000000 [ 0.621378] i2c_designware f7101000.i2c: Unknown Synopsys component type: 0x00000000 [ 0.633818] i2c_designware f7102000.i2c: Unknown Synopsys component type: 0x00000000
Signed-off-by: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org
board/hisilicon/hikey/hikey.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
diff --git a/board/hisilicon/hikey/hikey.c b/board/hisilicon/hikey/hikey.c index 940ae82c45b..f8b8c372bfd 100644 --- a/board/hisilicon/hikey/hikey.c +++ b/board/hisilicon/hikey/hikey.c @@ -364,6 +364,20 @@ static void hi6220_pmussi_init(void) gpio_direction_output(0, 1); }
+static void hi6220_periph_reset(void) +{
u32 data, bits;
/* Bring I2C0/I2C1/I2C2/SPI0 out of reset */
bits = PERI_RST3_I2C0 | PERI_RST3_I2C1 | PERI_RST3_I2C2 |
PERI_RST3_SSP;
writel(bits, &peri_sc->rst3_dis);
/* Wait until the peripherals are out of reset */
do {
data = readl(&peri_sc->rst3_dis);
} while (data & bits);
+}
int misc_init_r(void) { return 0; @@ -371,6 +385,8 @@ int misc_init_r(void)
int board_init(void) {
hi6220_periph_reset();
return 0;
}
-- 2.17.1
participants (3)
-
Daniel Thompson
-
Manivannan Sadhasivam
-
Peter Griffin