imx: mx7: default enable MDIO open drain
Subsystems (3)
PATCH 1/2 imx: mx7: default enable MDIO open drain
The management data input/output (MDIO) requires open-drain, i.MX7D TO1.0 ENET MDIO pin has no open drain, but TO1.1 supports this feature. So to TO1.1, need to enable open drain by setting bits GPR0[8:7] for TO1.1.
--- arch/arm/cpu/armv7/mx7/soc.c | 20 ++++++++++++++++++++ arch/arm/include/asm/arch-mx7/imx-regs.h | 2 ++ 2 files changed, 22 insertions(+)
arch/arm/cpu/armv7/mx7/soc.c +20 -0
@@ -130,6 +130,24 @@ static void init_csu(void)writel (CSU_INIT_SEC_LEVEL0 ,CSU_IPS_BASE_ADDR + i *4 ); } +static void imx_enet_mdio_fixup (void ) +{ +struct iomuxc_gpr_base_regs *gpr_regs = + (struct iomuxc_gpr_base_regs *)IOMUXC_GPR_BASE_ADDR ; + +/* +* The management data input/output (MDIO) requires open-drain, +* i.MX7D TO1.0 ENET MDIO pin has no open drain, but TO1.1 supports +* this feature. So to TO1.1, need to enable open drain by setting +* bits GPR0[8:7]. +*/ + +if (soc_rev () >=CHIP_REV_1_1 ) { +setbits_le32 (&gpr_regs->gpr[0 ], +IOMUXC_GPR_GPR0_ENET_MDIO_OPEN_DRAIN_MASK ); + } +} +int arch_cpu_init (void ) {init_aips ();
@@ -138,6 +156,8 @@ int arch_cpu_init(void)/* Disable PDE bit of WMCR register */ imx_set_wdog_powerdown (false); +imx_enet_mdio_fixup (); +#ifdef CONFIG_APBH_DMA /* Start APBH DMA */ mxs_dma_init ();
arch/arm/include/asm/arch-mx7/imx-regs.h +2 -0
@@ -272,6 +272,8 @@ struct src {#define IOMUXC_GPR_GPR0_DMAREQ_MUX_SEL5_SHIFT 5#define IOMUXC_GPR_GPR0_DMAREQ_MUX_SEL6_MASK 0x40u#define IOMUXC_GPR_GPR0_DMAREQ_MUX_SEL6_SHIFT 6 +#define IOMUXC_GPR_GPR0_ENET_MDIO_OPEN_DRAIN_MASK (3 << 7) +#define IOMUXC_GPR_GPR0_ENET_MDIO_OPEN_DRAIN_SHIFT 7/* GPR1 Bit Fields */ #define IOMUXC_GPR_GPR1_GPR_WEIM_ACT_CS0_MASK 0x1u#define IOMUXC_GPR_GPR1_GPR_WEIM_ACT_CS0_SHIFT 0
Signature · 1 line
2.6.2
PATCH 2/2 imx: mx7: fix the temperature checking for Rev1.1
To TO1.0, we can not rely on finish bit to read temperature. But to TO1.1, the issue was fixed by IC, we can rely on finish bit for temperature reading for TO1.1.
--- drivers/thermal/imx_thermal.c | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-)
drivers/thermal/imx_thermal.c +21 -9
@@ -169,18 +169,30 @@ static int read_cpu_temperature(struct udevice *dev)writel (TEMPMON_HW_ANADIG_TEMPSENSE1_FINISHED_MASK , &ccm_anatop->tempsense1_clr);writel (TEMPMON_HW_ANADIG_TEMPSENSE1_MEASURE_TEMP_MASK , &ccm_anatop->tempsense1_set); - start =get_timer (0 ); -/* Wait max 100ms */ -do { -/* -* Since we can not rely on finish bit, use 1ms delay to get -* temperature. From RM, 17us is enough to get data, but -* to gurantee to get the data, delay 100ms here. -*/ +if (soc_rev () >=CHIP_REV_1_1 ) { +/* make sure that the latest temp is valid */ +while ((readl (&ccm_anatop->tempsense1) & +TEMPMON_HW_ANADIG_TEMPSENSE1_FINISHED_MASK ) ==0 ) +udelay (10000 ); reg =readl (&ccm_anatop->tempsense1); tmp = (reg &TEMPMON_HW_ANADIG_TEMPSENSE1_TEMP_VALUE_MASK ) >>TEMPMON_HW_ANADIG_TEMPSENSE1_TEMP_VALUE_SHIFT ; - }while (get_timer (0 ) < (start +100 )); + }else { + start =get_timer (0 ); +/* Wait max 100ms */ +do { +/* +* Since we can not rely on finish bit, use 100ms +* delay to get temperature. From RM, 17us is +* enough to get data, but to gurantee to get +* the data, delay 100ms here. +*/ + reg =readl (&ccm_anatop->tempsense1); + tmp = (reg & +TEMPMON_HW_ANADIG_TEMPSENSE1_TEMP_VALUE_MASK ) + >>TEMPMON_HW_ANADIG_TEMPSENSE1_TEMP_VALUE_SHIFT ; + }while (get_timer (0 ) < (start +100 )); + }writel (TEMPMON_HW_ANADIG_TEMPSENSE1_FINISHED_MASK , &ccm_anatop->tempsense1_clr);
Signature · 1 line
2.6.2
PATCH 2/2 imx: mx7: fix the temperature checking for Rev1.1
Hi Peng,
Quoted 24 lines · Peng Fan
To TO1.0, we can not rely on finish bit to read temperature. But to TO1.1, the issue was fixed by IC, we can rely on finish bit for temperature reading for TO1.1.
Signed-off-by Peng Fan <[email protected]>Cc Stefano Babic <[email protected]>Cc Tim Harvey <[email protected]>Cc Fabio Estevam <[email protected]>Cc Adrian Alonso <[email protected]>--- drivers/thermal/imx_thermal.c | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-)drivers/thermal/imx_thermal.c +0
-3@@ -169,18 +169,30 @@ static int read_cpu_temperature(struct udevice *dev)writel (TEMPMON_HW_ANADIG_TEMPSENSE1_FINISHED_MASK , &ccm_anatop->tempsense1_clr);writel (TEMPMON_HW_ANADIG_TEMPSENSE1_MEASURE_TEMP_MASK , &ccm_anatop->tempsense1_set); - start =get_timer (0 ); -/* Wait max 100ms */ - do {
drivers/thermal/imx_thermal.c static int read_cpu_temperature(struct udevice *dev) · line 176
Quoted 10 lines
drivers/thermal/imx_thermal.c +5
-5-/* -* Since we can not rely on finish bit, use 1ms delay to get -* temperature. From RM, 17us is enough to get data, but -* to gurantee to get the data, delay 100ms here. -*/ +if (soc_rev () >=CHIP_REV_1_1 ) { +/* make sure that the latest temp is valid */ +while ((readl (&ccm_anatop->tempsense1) & +TEMPMON_HW_ANADIG_TEMPSENSE1_FINISHED_MASK ) ==0 ) +udelay (10000 );
If 10ms is the minimal time, you should poll with a timer < 10mS, else you go out after 20mS. Processor is not doing anything, you can simply poll the register more often.
Quoted 10 lines
drivers/thermal/imx_thermal.c +6
-1reg =readl (&ccm_anatop->tempsense1); tmp = (reg &TEMPMON_HW_ANADIG_TEMPSENSE1_TEMP_VALUE_MASK ) >>TEMPMON_HW_ANADIG_TEMPSENSE1_TEMP_VALUE_SHIFT ; - }while (get_timer (0 ) < (start +100 )); + }else { + start =get_timer (0 ); +/* Wait max 100ms */ + do { + /* + * Since we can not rely on finish bit, use 100ms
drivers/thermal/imx_thermal.c static int read_cpu_temperature(struct udevice *dev) · line 195
Quoted 10 lines
drivers/thermal/imx_thermal.c +10
-0+* delay to get temperature. From RM, 17us is +* enough to get data, but to gurantee to get +* the data, delay 100ms here. +*/ + reg =readl (&ccm_anatop->tempsense1); + tmp = (reg & +TEMPMON_HW_ANADIG_TEMPSENSE1_TEMP_VALUE_MASK ) + >>TEMPMON_HW_ANADIG_TEMPSENSE1_TEMP_VALUE_SHIFT ; + }while (get_timer (0 ) < (start +100 )); + }
This is nasty. You read the register, but you do not evaluate the result and you wait always 100mS. This has drawbacks for the boottime, because it is not so negligible. What is the reason to poll the register if you simply wait for timeout ?
Best regards,
Stefano Babic
Signature · 5 lines
===================================================================== DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de =====================================================================
PATCH 2/2 imx: mx7: fix the temperature checking for Rev1.1
Hi Stefano,
Quoted 33 lines · Stefano Babic
Hi Peng,
Quoted 30 lines · Peng Fan
To TO1.0, we can not rely on finish bit to read temperature. But to TO1.1, the issue was fixed by IC, we can rely on finish bit for temperature reading for TO1.1.
Signed-off-by Peng Fan <[email protected]>Cc Stefano Babic <[email protected]>Cc Tim Harvey <[email protected]>Cc Fabio Estevam <[email protected]>Cc Adrian Alonso <[email protected]>--- drivers/thermal/imx_thermal.c | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-)drivers/thermal/imx_thermal.c +1
-8@@ -169,18 +169,30 @@ static int read_cpu_temperature(struct udevice *dev)writel (TEMPMON_HW_ANADIG_TEMPSENSE1_FINISHED_MASK , &ccm_anatop->tempsense1_clr);writel (TEMPMON_HW_ANADIG_TEMPSENSE1_MEASURE_TEMP_MASK , &ccm_anatop->tempsense1_set); - start =get_timer (0 ); -/* Wait max 100ms */ - do { - /* - * Since we can not rely on finish bit, use 1ms delay to get - * temperature. From RM, 17us is enough to get data, but - * to gurantee to get the data, delay 100ms here. - */ +if (soc_rev () >=CHIP_REV_1_1 ) {
Quoted 8 lines
drivers/thermal/imx_thermal.c static int read_cpu_temperature(struct udevice *dev) · line 176
Quoted 4 lines
drivers/thermal/imx_thermal.c +4
-0+/* make sure that the latest temp is valid */ +while ((readl (&ccm_anatop->tempsense1) & +TEMPMON_HW_ANADIG_TEMPSENSE1_FINISHED_MASK ) ==0 ) +udelay (10000 );If 10ms is the minimal time, you should poll with a timer < 10mS, else you go out after 20mS. Processor is not doing anything, you can simply poll the register more often.
Will use timeout method. Thanks.
Quoted 18 lines
Quoted 18 lines
drivers/thermal/imx_thermal.c +13
-1reg =readl (&ccm_anatop->tempsense1); tmp = (reg &TEMPMON_HW_ANADIG_TEMPSENSE1_TEMP_VALUE_MASK ) >>TEMPMON_HW_ANADIG_TEMPSENSE1_TEMP_VALUE_SHIFT ; - }while (get_timer (0 ) < (start +100 )); + }else { + start =get_timer (0 ); +/* Wait max 100ms */ + do { + /* + * Since we can not rely on finish bit, use 100ms + * delay to get temperature. From RM, 17us is + * enough to get data, but to gurantee to get + * the data, delay 100ms here. + */ + reg = readl(&ccm_anatop->tempsense1); + tmp = (reg & + TEMPMON_HW_ANADIG_TEMPSENSE1_TEMP_VALUE_MASK)
Quoted 8 lines
drivers/thermal/imx_thermal.c static int read_cpu_temperature(struct udevice *dev) · line 195
Quoted 3 lines
drivers/thermal/imx_thermal.c +3
-0+ >> TEMPMON_HW_ANADIG_TEMPSENSE1_TEMP_VALUE_SHIFT; + }while (get_timer (0 ) < (start +100 )); + }This is nasty. You read the register, but you do not evaluate the result and you wait always 100mS. This has drawbacks for the boottime, because it is not so negligible. What is the reason to poll the register if you simply wait for timeout ?
Actually after temperature sensor finished sampling the temperature, it will output a singal to a register, the finish bit in the register is for this. But to TO1.0, we can not rely on finish bit, since it's value is not correct because of IC logic issue. So I add 100ms here.
I may can use this way:
1. delay [xx]ms
2. read register value
Thanks,
Peng.
Quoted 10 lines
Best regards,
Stefano BabicSignature · 5 lines
===================================================================== DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de =====================================================================
PATCH 1/2 imx: mx7: default enable MDIO open drain
In reply to Peng FanQuoted 8 lines · Peng Fan
The management data input/output (MDIO) requires open-drain, i.MX7D TO1.0 ENET MDIO pin has no open drain, but TO1.1 supports this feature. So to TO1.1, need to enable open drain by setting bits GPR0[8:7] for TO1.1.
Signed-off-by Peng Fan <[email protected]>Cc Stefano Babic <[email protected]>---
Applied to u-boot-imx, thanks!
Best regards,
Stefano Babic
Signature · 5 lines
===================================================================== DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de =====================================================================