M28EVK/i.MX28 improvements
Subsystems (4)
cover M28EVK/i.MX28 improvements
These are some improvements that were stuck in my tree for a while, time to expunge them, please consider applying.
Tested on:
* DENX M28EVK v2.0
* DENX M28EVK v1.1
* Mysterious board #1 ...
* Unnamed board #2 ...
Marek Vasut (13):
FEC: Abstract out register setup
M28EVK: Implement support for new board V2.0
M28EVK: Add SD update command
i.MX28: Improve passing of data from SPL to U-Boot i.MX28: Implement boot pads sampling and reporting i.MX28: Add LCDIF register definitions i.MX28: Shut down the LCD controller before reset i.MX28: Add LRADC register definitions i.MX28: Add LRADC init to i.MX28 SPL i.MX28: Reorder battery status functions in SPL i.MX28: Add battery boot components to SPL i.MX28: Check if WP detection is implemented at all i.MX28: Avoid redefining serial_put[cs]()
arch/arm/cpu/arm926ejs/mx28/Makefile | 2 +- arch/arm/cpu/arm926ejs/mx28/mx28.c | 29 +- arch/arm/cpu/arm926ejs/mx28/mx28_init.h | 4 + arch/arm/cpu/arm926ejs/mx28/spl_boot.c | 57 ++++ arch/arm/cpu/arm926ejs/mx28/spl_lradc_init.c | 86 ++++++ arch/arm/cpu/arm926ejs/mx28/spl_mem_init.c | 10 +- arch/arm/cpu/arm926ejs/mx28/spl_power_init.c | 224 ++++++++++----- arch/arm/include/asm/arch-mx28/imx-regs.h | 2 + arch/arm/include/asm/arch-mx28/regs-lcdif.h | 212 ++++++++++++++ arch/arm/include/asm/arch-mx28/regs-lradc.h | 400 ++++++++++++++++++++++++++ arch/arm/include/asm/arch-mx28/sys_proto.h | 30 ++ board/denx/m28evk/m28evk.c | 20 +- board/denx/m28evk/spl_boot.c | 8 +- drivers/mmc/mxsmmc.c | 3 +- drivers/net/fec_mxc.c | 84 +++--- include/configs/m28evk.h | 10 + include/configs/mx28evk.h | 1 + 17 files changed, 1043 insertions(+), 139 deletions(-) create mode 100644 arch/arm/cpu/arm926ejs/mx28/spl_lradc_init.c create mode 100644 arch/arm/include/asm/arch-mx28/regs-lcdif.h create mode 100644 arch/arm/include/asm/arch-mx28/regs-lradc.h
Signature · 1 line
1.7.10
PATCH 1/13 FEC: Abstract out register setup
Abstract out common register setup. This also configured r_cntrl to correct value at registration time.
--- drivers/net/fec_mxc.c | 84 ++++++++++++++++++++++--------------------------- 1 file changed, 38 insertions(+), 46 deletions(-)
drivers/net/fec_mxc.c +38 -46
@@ -398,6 +398,42 @@ static void fec_eth_phy_config(struct eth_device *dev)#endif } +/* +* Do initial configuration of the FEC registers +*/ +static void fec_reg_setup (struct fec_priv *fec) +{ +uint32_t rcntrl; + +/* +* Set interrupt mask register +*/ +writel (0x00000000 , &fec->eth->imask); + +/* +* Clear FEC-Lite interrupt event register(IEVENT) +*/ +writel (0xffffffff , &fec->eth->ievent); + + +/* +* Set FEC-Lite receive control register(R_CNTRL): +*/ + +/* Start with frame length = 1518, common for all modes. */ + rcntrl =PKTSIZE <<FEC_RCNTRL_MAX_FL_SHIFT ; +if (fec->xcv_type ==SEVENWIRE ) + rcntrl |=FEC_RCNTRL_FCE ; +else if (fec->xcv_type ==RGMII ) + rcntrl |=FEC_RCNTRL_RGMII ; +else if (fec->xcv_type ==RMII ) + rcntrl |=FEC_RCNTRL_RMII ; +else /* MII mode */ + rcntrl |=FEC_RCNTRL_FCE |FEC_RCNTRL_MII_MODE ; + +writel (rcntrl, &fec->eth->r_cntrl); +} +/** * Start the FEC engine * @param[in] dev Our device to handle
@@ -512,7 +548,6 @@ static int fec_init(struct eth_device *dev, bd_t* bd) {struct fec_priv *fec = (struct fec_priv *)dev->priv;uint32_t mib_ptr = (uint32_t )&fec->eth->rmon_t_drop; -uint32_t rcntrl;uint32_t size;int i, ret;
@@ -560,33 +595,7 @@ static int fec_init(struct eth_device *dev, bd_t* bd) (unsigned)fec->rbd_base + size); } -/* -* Set interrupt mask register -*/ -writel (0x00000000 , &fec->eth->imask); - -/* -* Clear FEC-Lite interrupt event register(IEVENT) -*/ -writel (0xffffffff , &fec->eth->ievent); - - -/* -* Set FEC-Lite receive control register(R_CNTRL): -*/ - -/* Start with frame length = 1518, common for all modes. */ - rcntrl =PKTSIZE <<FEC_RCNTRL_MAX_FL_SHIFT ; -if (fec->xcv_type ==SEVENWIRE ) - rcntrl |=FEC_RCNTRL_FCE ; -else if (fec->xcv_type ==RGMII ) - rcntrl |=FEC_RCNTRL_RGMII ; -else if (fec->xcv_type ==RMII ) - rcntrl |=FEC_RCNTRL_RMII ; -else /* MII mode */ - rcntrl |=FEC_RCNTRL_FCE |FEC_RCNTRL_MII_MODE ; - -writel (rcntrl, &fec->eth->r_cntrl); +fec_reg_setup (fec);if (fec->xcv_type ==MII10 || fec->xcv_type ==MII100 )fec_mii_setspeed (fec);
@@ -933,24 +942,7 @@ static int fec_probe(bd_t *bd, int dev_id, int phy_id, uint32_t base_addr)udelay (10 ); } -/* -* Set interrupt mask register -*/ -writel (0x00000000 , &fec->eth->imask); - -/* -* Clear FEC-Lite interrupt event register(IEVENT) -*/ -writel (0xffffffff , &fec->eth->ievent); - -/* -* Set FEC-Lite receive control register(R_CNTRL): -*/ -/* -* Frame length=1518; MII mode; -*/ -writel ((PKTSIZE <<FEC_RCNTRL_MAX_FL_SHIFT ) |FEC_RCNTRL_FCE | -FEC_RCNTRL_MII_MODE , &fec->eth->r_cntrl); +fec_reg_setup (fec);fec_mii_setspeed (fec);if (dev_id ==-1 ) {
Signature · 1 line
1.7.10
PATCH 2/13 M28EVK: Implement support for new board V2.0
In reply to Marek Vasut--- board/denx/m28evk/m28evk.c | 20 +++++++++++++++++++- board/denx/m28evk/spl_boot.c | 8 ++++++-- 2 files changed, 25 insertions(+), 3 deletions(-)
board/denx/m28evk/m28evk.c +19 -1
@@ -90,6 +90,8 @@ int board_mmc_init(bd_t *bis) {/* Configure WP as input. */ gpio_direction_input (MX28_PAD_AUART2_CTS__GPIO_3_10 ); +/* Turn on the power to the card. */ +gpio_direction_output (MX28_PAD_PWM3__GPIO_3_28 ,0 );return mxsmmc_initialize (bis,0 , m28_mmc_wp); }
@@ -103,10 +105,18 @@ int board_mmc_init(bd_t *bis)int fecmxc_mii_postcall (int phy) { +#if defined(CONFIG_DENX_M28_V11 ) || defined(CONFIG_DENX_M28_V10 ) +/* KZ8031 PHY on old boards. */ +const uint32_t freq =0x0080 ; +#else +/* KZ8021 PHY on new boards. */ +const uint32_t freq =0x0000 ; +#endif +miiphy_write ("FEC1" , phy,MII_BMCR ,0x9000 );miiphy_write ("FEC1" , phy,MII_OPMODE_STRAP_OVERRIDE ,0x0202 );if (phy ==3 ) -miiphy_write ("FEC1" ,3 ,MII_PHY_CTRL2 ,0x8180 ); +miiphy_write ("FEC1" ,3 ,MII_PHY_CTRL2 ,0x8100 | freq);return 0 ; }
@@ -123,6 +133,14 @@ int board_eth_init(bd_t *bis)CLKCTRL_ENET_TIME_SEL_MASK |CLKCTRL_ENET_CLK_OUT_EN , CLKCTRL_ENET_TIME_SEL_RMII_CLK); +#if !defined(CONFIG_DENX_M28_V11 ) && !defined(CONFIG_DENX_M28_V10 ) +/* Reset the new PHY */ +gpio_direction_output (MX28_PAD_AUART2_RTS__GPIO_3_11 ,0 ); +udelay (10000 ); +gpio_set_value (MX28_PAD_AUART2_RTS__GPIO_3_11 ,1 ); +udelay (10000 ); +#endif + ret =fecmxc_initialize_multi (bis,0 ,0 ,MXS_ENET0_BASE );if (ret) {printf ("FEC MXS: Unable to init FEC0\n" );
board/denx/m28evk/spl_boot.c +6 -2
@@ -109,8 +109,9 @@ const iomux_cfg_t iomux_setup[] = { (MXS_PAD_3V3 |MXS_PAD_12MA |MXS_PAD_NOPULL ),MX28_PAD_SSP0_SCK__SSP0_SCK | (MXS_PAD_3V3 |MXS_PAD_12MA |MXS_PAD_NOPULL ), -MX28_PAD_PWM3__GPIO_3_28 |MUX_CONFIG_SSP0 ,/* Power .. FIXME */ -MX28_PAD_AUART2_CTS__GPIO_3_10 ,/* WP ... FIXME */ +MX28_PAD_PWM3__GPIO_3_28 |MUX_CONFIG_SSP0 | + (MXS_PAD_3V3 |MXS_PAD_12MA |MXS_PAD_NOPULL ),/* Power */ +MX28_PAD_AUART2_CTS__GPIO_3_10 ,/* WP */ /* GPMI NAND */ MX28_PAD_GPMI_D00__GPMI_D0 | MUX_CONFIG_GPMI,
@@ -147,6 +148,9 @@ const iomux_cfg_t iomux_setup[] = {MX28_PAD_ENET0_RXD3__ENET1_RXD1 |MUX_CONFIG_ENET ,MX28_PAD_ENET0_TXD2__ENET1_TXD0 |MUX_CONFIG_ENET ,MX28_PAD_ENET0_TXD3__ENET1_TXD1 |MUX_CONFIG_ENET , +#if !defined(CONFIG_DENX_M28_V11) && !defined(CONFIG_DENX_M28_V10) +MX28_PAD_AUART2_RTS__GPIO_3_11 ,/* PHY reset */ +#endif/* I2C */ MX28_PAD_I2C0_SCL__I2C0_SCL,
Signature · 1 line
1.7.10
PATCH 3/13 M28EVK: Add SD update command
In reply to Marek VasutAdd "update_sd_firmware" command to easily reload the SD card of m28evk kit. This comes handy when the board boots from SD card.
--- include/configs/m28evk.h | 9 +++++++++ 1 file changed, 9 insertions(+)
include/configs/m28evk.h +9 -0
@@ -286,6 +286,7 @@#define CONFIG_EXTRA_ENV_SETTINGS \ "update_nand_full_filename=u-boot.nand\0" \ "update_nand_firmware_filename=u-boot.sb\0" \ + "update_sd_firmware_filename=u-boot.sd\0" \ "update_nand_firmware_maxsz=0x100000\0" \ "update_nand_stride=0x40\0"/* MX28 datasheet ch. 12.12 */ \"update_nand_count=0x4\0" /* MX28 datasheet ch. 12.12 */ \
@@ -312,6 +313,14 @@"nand erase ${fcb_sz} ${fw_sz} ; " \"nand write ${loadaddr} ${fcb_sz} ${filesize} ; " \"nand write ${loadaddr} ${fw_off} ${filesize} ; " \ +"fi\0" \ +"update_sd_firmware=" /* Update the SD firmware partition */ \ +"if mmc rescan ; then " \ +"if tftp ${update_sd_firmware_filename} ; then " \ +"setexpr fw_sz ${filesize} / 0x200 ; " /* SD block size */ \ +"setexpr fw_sz ${fw_sz} + 1 ; " \ +"mmc write ${loadaddr} 0x800 ${fw_sz} ; " \ +"fi ; " \ "fi\0"#endif /* __M28_H__ */
Signature · 1 line
1.7.10
PATCH 4/13 i.MX28: Improve passing of data from SPL to U-Boot
In reply to Marek VasutPass memory size from SPL via structure located in SRAM instead of SCRATCH registers. This allows passing more data about boot from SPL to U-Boot, like the boot mode pads configuration.
--- arch/arm/cpu/arm926ejs/mx28/mx28.c | 16 +++++----------- arch/arm/cpu/arm926ejs/mx28/mx28_init.h | 1 + arch/arm/cpu/arm926ejs/mx28/spl_boot.c | 7 +++++++ arch/arm/cpu/arm926ejs/mx28/spl_mem_init.c | 10 +++------- arch/arm/include/asm/arch-mx28/sys_proto.h | 4 ++++ 5 files changed, 20 insertions(+), 18 deletions(-)
arch/arm/cpu/arm926ejs/mx28/mx28.c +5 -11
@@ -279,22 +279,16 @@ void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)int mx28_dram_init (void ) { -struct mx28_digctl_regs *digctl_regs = - (struct mx28_digctl_regs *)MXS_DIGCTL_BASE ; -uint32_t sz[2 ]; +struct mx28_spl_data *data = (struct mx28_spl_data *) + ((CONFIG_SYS_TEXT_BASE -sizeof (struct mx28_spl_data )) & ~0xf ); - sz[0 ] =readl (&digctl_regs->hw_digctl_scratch0); - sz[1 ] =readl (&digctl_regs->hw_digctl_scratch1); - -if (sz[0 ] != sz[1 ]) { +if (data->mem_dram_size ==0 ) {printf ("MX28:\n" -"Error, the RAM size in HW_DIGCTRL_SCRATCH0 and\n" -"HW_DIGCTRL_SCRATCH1 is not the same. Please\n" -"verify these two registers contain valid RAM size!\n" ); +"Error, the RAM size passed up from SPL is 0!\n" );hang (); } - gd->ram_size = sz[0 ]; + gd->ram_size = data->mem_dram_size;return 0 ; }
arch/arm/cpu/arm926ejs/mx28/mx28_init.h +1 -0
@@ -37,5 +37,6 @@ static inline void mx28_power_wait_pswitch(void) { }#endif void mx28_mem_init (void ); +uint32_t mx28_mem_get_size (void );#endif /* __M28_INIT_H__ */
arch/arm/cpu/arm926ejs/mx28/spl_boot.c +7 -0
@@ -28,6 +28,7 @@#include <asm/io.h> #include <asm/arch/iomux-mx28.h> #include <asm/arch/imx-regs.h> +#include <asm/arch/sys_proto.h> #include "mx28_init.h"
@@ -49,9 +50,15 @@ void early_delay(int delay)void mx28_common_spl_init (const iomux_cfg_t *iomux_setup,const unsigned int iomux_size) { +struct mx28_spl_data *data = (struct mx28_spl_data *) + ((CONFIG_SYS_TEXT_BASE -sizeof (struct mx28_spl_data )) & ~0xf ); +mxs_iomux_setup_multiple_pads (iomux_setup, iomux_size);mx28_power_init (); +mx28_mem_init (); + data->mem_dram_size =mx28_mem_get_size (); +mx28_power_wait_pswitch (); }
arch/arm/cpu/arm926ejs/mx28/spl_mem_init.c +3 -7
@@ -173,10 +173,8 @@ void mx28_mem_setup_vddd(void) &power_regs->hw_power_vdddctrl); } -void mx28_mem_get_size (void ) +uint32_t mx28_mem_get_size (void ) { -struct mx28_digctl_regs *digctl_regs = - (struct mx28_digctl_regs *)MXS_DIGCTL_BASE ;uint32_t sz, da;uint32_t *vt = (uint32_t *)0x20 ;/* The following is "subs pc, r14, #4", used as return from DABT. */
@@ -187,11 +185,11 @@ void mx28_mem_get_size(void) vt[4 ] = data_abort_memdetect_handler; sz =get_ram_size ((long *)PHYS_SDRAM_1 ,PHYS_SDRAM_1_SIZE ); -writel (sz, &digctl_regs->hw_digctl_scratch0); -writel (sz, &digctl_regs->hw_digctl_scratch1);/* Restore the old DABT handler. */ vt[4 ] = da; + +return sz; }void mx28_mem_init (void )
@@ -239,6 +237,4 @@ void mx28_mem_init(void)early_delay (10000 );mx28_mem_setup_cpu_and_hbus (); - -mx28_mem_get_size (); }
arch/arm/include/asm/arch-mx28/sys_proto.h +4 -0
@@ -39,6 +39,10 @@ void mx28_common_spl_init(const iomux_cfg_t *iomux_setup, const unsigned int iomux_size);#endif +struct mx28_spl_data { +uint32_t mem_dram_size; +}; +int mx28_dram_init (void );#endif /* __MX28_H__ */
Signature · 1 line
1.7.10
PATCH 5/13 i.MX28: Implement boot pads sampling and reporting
In reply to Marek VasutThis patch implements code that samples i.MX28 boot pads and reports boot mode accordingly.
--- arch/arm/cpu/arm926ejs/mx28/mx28.c | 4 +++ arch/arm/cpu/arm926ejs/mx28/spl_boot.c | 48 ++++++++++++++++++++++++++++ arch/arm/include/asm/arch-mx28/sys_proto.h | 26 +++++++++++++++ include/configs/m28evk.h | 1 + include/configs/mx28evk.h | 1 + 5 files changed, 80 insertions(+)
arch/arm/cpu/arm926ejs/mx28/mx28.c +4 -0
@@ -185,8 +185,12 @@ int arch_cpu_init(void)#if defined(CONFIG_DISPLAY_CPUINFO )int print_cpuinfo (void ) { +struct mx28_spl_data *data = (struct mx28_spl_data *) + ((CONFIG_SYS_TEXT_BASE -sizeof (struct mx28_spl_data )) & ~0xf ); +printf ("Freescale i.MX28 family at %d MHz\n" ,mxc_get_clock (MXC_ARM_CLK ) /1000000 ); +printf ("BOOT: %s\n" , mx28_boot_modes[data->boot_mode_idx].mode);return 0 ; }#endif
arch/arm/cpu/arm926ejs/mx28/spl_boot.c +48 -0
71 lines not on this page · raw message
arch/arm/include/asm/arch-mx28/sys_proto.h +26 -0
@@ -39,7 +39,33 @@ void mx28_common_spl_init(const iomux_cfg_t *iomux_setup, const unsigned int iomux_size);#endif +struct mx28_pair { +uint8_t boot_pads; +uint8_t boot_mask; +const char *mode; +}; + +static const struct mx28_pair mx28_boot_modes[] = { + {0x00 ,0x0f ,"USB #0" }, + {0x01 ,0x1f ,"I2C #0, master, 3V3" }, + {0x11 ,0x1f ,"I2C #0, master, 1V8" }, + {0x02 ,0x1f ,"SSP SPI #2, master, 3V3 NOR" }, + {0x12 ,0x1f ,"SSP SPI #2, master, 1V8 NOR" }, + {0x03 ,0x1f ,"SSP SPI #3, master, 3V3 NOR" }, + {0x13 ,0x1f ,"SSP SPI #3, master, 1V8 NOR" }, + {0x04 ,0x1f ,"NAND, 3V3" }, + {0x14 ,0x1f ,"NAND, 1V8" }, + {0x08 ,0x1f ,"SSP SPI #3, master, 3V3 EEPROM" }, + {0x18 ,0x1f ,"SSP SPI #3, master, 1V8 EEPROM" }, + {0x09 ,0x1f ,"SSP SD/MMC #0, 3V3" }, + {0x19 ,0x1f ,"SSP SD/MMC #0, 1V8" }, + {0x0a ,0x1f ,"SSP SD/MMC #1, 3V3" }, + {0x1a ,0x1f ,"SSP SD/MMC #1, 1V8" }, + {0x00 ,0x00 ,"Reserved/Unknown/Wrong" }, +}; +struct mx28_spl_data { +uint8_t boot_mode_idx;uint32_t mem_dram_size; };
include/configs/m28evk.h +1 -0
@@ -52,6 +52,7 @@#define CONFIG_SPL_LDSCRIPT "arch/arm/cpu/arm926ejs/mx28/u-boot-spl.lds"#define CONFIG_SPL_LIBCOMMON_SUPPORT #define CONFIG_SPL_LIBGENERIC_SUPPORT +#define CONFIG_SPL_GPIO_SUPPORT /* * U-Boot Commands
include/configs/mx28evk.h +1 -0
@@ -46,6 +46,7 @@#define CONFIG_SPL_LDSCRIPT "arch/arm/cpu/arm926ejs/mx28/u-boot-spl.lds"#define CONFIG_SPL_LIBCOMMON_SUPPORT #define CONFIG_SPL_LIBGENERIC_SUPPORT +#define CONFIG_SPL_GPIO_SUPPORT /* * U-Boot Commands
Signature · 1 line
1.7.10
PATCH 6/13 i.MX28: Add LCDIF register definitions
In reply to Marek VasutFrom: Marek Vasut <[email protected]>
--- arch/arm/include/asm/arch-mx28/imx-regs.h | 1 + arch/arm/include/asm/arch-mx28/regs-lcdif.h | 212 +++++++++++++++++++++++++++ 2 files changed, 213 insertions(+) create mode 100644 arch/arm/include/asm/arch-mx28/regs-lcdif.h
arch/arm/include/asm/arch-mx28/imx-regs.h +1 -0
@@ -30,6 +30,7 @@#include <asm/arch/regs-digctl.h> #include <asm/arch/regs-gpmi.h> #include <asm/arch/regs-i2c.h> +#include <asm/arch/regs-lcdif.h> #include <asm/arch/regs-ocotp.h> #include <asm/arch/regs-pinctrl.h> #include <asm/arch/regs-power.h>
arch/arm/include/asm/arch-mx28/regs-lcdif.h new file +212 -0
212 lines not on this page · raw message
Signature · 1 line
1.7.10
PATCH 7/13 i.MX28: Shut down the LCD controller before reset
In reply to Marek VasutIf the LCD controller is on before the CPU goes into reset, the traffic on LCDIF data pins interferes with the BootROM's boot mode sampling. So shut the controller down.
--- arch/arm/cpu/arm926ejs/mx28/mx28.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
arch/arm/cpu/arm926ejs/mx28/mx28.c +8 -1
@@ -51,9 +51,16 @@ void reset_cpu(ulong ignored) __attribute__((noreturn));void reset_cpu (ulong ignored) { -struct mx28_rtc_regs *rtc_regs = (struct mx28_rtc_regs *)MXS_RTC_BASE ; +struct mx28_lcdif_regs *lcdif_regs = + (struct mx28_lcdif_regs *)MXS_LCDIF_BASE ; + +/* +* Shut down the LCD controller as it interferes with BootROM boot mode +* pads sampling. +*/ +writel (LCDIF_CTRL_RUN , &lcdif_regs->hw_lcdif_ctrl_clr);/* Wait 1 uS before doing the actual watchdog reset */ writel (1 , &rtc_regs->hw_rtc_watchdog);
Signature · 1 line
1.7.10
PATCH 8/13 i.MX28: Add LRADC register definitions
In reply to Marek VasutFrom: Marek Vasut <[email protected]>
--- arch/arm/include/asm/arch-mx28/imx-regs.h | 1 + arch/arm/include/asm/arch-mx28/regs-lradc.h | 400 +++++++++++++++++++++++++++ 2 files changed, 401 insertions(+) create mode 100644 arch/arm/include/asm/arch-mx28/regs-lradc.h
arch/arm/include/asm/arch-mx28/imx-regs.h +1 -0
@@ -31,6 +31,7 @@#include <asm/arch/regs-gpmi.h> #include <asm/arch/regs-i2c.h> #include <asm/arch/regs-lcdif.h> +#include <asm/arch/regs-lradc.h> #include <asm/arch/regs-ocotp.h> #include <asm/arch/regs-pinctrl.h> #include <asm/arch/regs-power.h>
arch/arm/include/asm/arch-mx28/regs-lradc.h new file +400 -0
400 lines not on this page · raw message
Signature · 1 line
1.7.10
PATCH 9/13 i.MX28: Add LRADC init to i.MX28 SPL
In reply to Marek VasutFrom: Marek Vasut <[email protected]>
This code is part of battery boot support for i.MX28.
--- arch/arm/cpu/arm926ejs/mx28/Makefile | 2 +- arch/arm/cpu/arm926ejs/mx28/mx28_init.h | 3 + arch/arm/cpu/arm926ejs/mx28/spl_lradc_init.c | 86 ++++++++++++++++++++++++++ arch/arm/cpu/arm926ejs/mx28/spl_power_init.c | 10 +++ 4 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 arch/arm/cpu/arm926ejs/mx28/spl_lradc_init.c
arch/arm/cpu/arm926ejs/mx28/Makefile +1 -1
@@ -28,7 +28,7 @@ LIB = $(obj)lib$(SOC).o COBJS = clock.o mx28.o iomux.o timer.o ifdef CONFIG_SPL_BUILD -COBJS += spl_boot.o spl_mem_init.o spl_power_init.o +COBJS += spl_boot.o spl_lradc_init.o spl_mem_init.o spl_power_init.o endif SRCS := $(START:.o=.S) $(COBJS:.o=.c)
arch/arm/cpu/arm926ejs/mx28/mx28_init.h +3 -0
@@ -39,4 +39,7 @@ static inline void mx28_power_wait_pswitch(void) { }void mx28_mem_init (void );uint32_t mx28_mem_get_size (void ); +void mx28_lradc_init (void ); +void mx28_lradc_enable_batt_measurement (void ); +#endif /* __M28_INIT_H__ */
arch/arm/cpu/arm926ejs/mx28/spl_lradc_init.c new file +86 -0
86 lines not on this page · raw message
arch/arm/cpu/arm926ejs/mx28/spl_power_init.c +10 -0
@@ -883,6 +883,13 @@ void mx28_power_set_vddd(uint32_t new_target, uint32_t new_brownout) new_brownout << POWER_VDDDCTRL_BO_OFFSET_OFFSET); } +void mx28_setup_batt_detect (void ) +{ +mx28_lradc_init (); +mx28_lradc_enable_batt_measurement (); +early_delay (10 ); +} +void mx28_power_init (void ) { struct mx28_power_regs *power_regs =
@@ -892,6 +899,9 @@ void mx28_power_init(void)mx28_power_clear_auto_restart ();mx28_power_set_linreg ();mx28_power_setup_5v_detect (); + +mx28_setup_batt_detect (); +mx28_power_configure_power_source ();mx28_enable_output_rail_protection ();
Signature · 1 line
1.7.10
PATCH 10/13 i.MX28: Reorder battery status functions in SPL
In reply to Marek VasutFrom: Marek Vasut <[email protected]>
--- arch/arm/cpu/arm926ejs/mx28/spl_power_init.c | 120 ++++++++++++-------------- 1 file changed, 56 insertions(+), 64 deletions(-)
arch/arm/cpu/arm926ejs/mx28/spl_power_init.c +56 -64
@@ -104,6 +104,62 @@ void mx28_power_set_linreg(void) POWER_VDDIOCTRL_LINREG_OFFSET_1STEPS_BELOW); } +int mx28_get_batt_volt (void ) +{ +struct mx28_power_regs *power_regs = + (struct mx28_power_regs *)MXS_POWER_BASE ; +uint32_t volt =readl (&power_regs->hw_power_battmonitor); + volt &=POWER_BATTMONITOR_BATT_VAL_MASK ; + volt >>=POWER_BATTMONITOR_BATT_VAL_OFFSET ; + volt *=8 ; +return volt; +} + +int mx28_is_batt_ready (void ) +{ +return (mx28_get_batt_volt () >=3600 ); +} + +int mx28_is_batt_good (void ) +{ +struct mx28_power_regs *power_regs = + (struct mx28_power_regs *)MXS_POWER_BASE ; +uint32_t volt =mx28_get_batt_volt (); + +if ((volt >=2400 ) && (volt <=4300 )) +return 1 ; + +clrsetbits_le32 (&power_regs->hw_power_5vctrl, +POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK , +0x3 <<POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET ); +writel (POWER_5VCTRL_PWD_CHARGE_4P2_MASK , + &power_regs->hw_power_5vctrl_clr); + +clrsetbits_le32 (&power_regs->hw_power_charge, +POWER_CHARGE_STOP_ILIMIT_MASK |POWER_CHARGE_BATTCHRG_I_MASK , +POWER_CHARGE_STOP_ILIMIT_10MA |0x3 ); + +writel (POWER_CHARGE_PWD_BATTCHRG , &power_regs->hw_power_charge_clr); +writel (POWER_5VCTRL_PWD_CHARGE_4P2_MASK , + &power_regs->hw_power_5vctrl_clr); + +early_delay (500000 ); + + volt =mx28_get_batt_volt (); + +if (volt >=3500 ) +return 0 ; + +if (volt >=2400 ) +return 1 ; + +writel (POWER_CHARGE_STOP_ILIMIT_MASK |POWER_CHARGE_BATTCHRG_I_MASK , + &power_regs->hw_power_charge_clr); +writel (POWER_CHARGE_PWD_BATTCHRG , &power_regs->hw_power_charge_set); + +return 0 ; +} +void mx28_power_setup_5v_detect (void ) { struct mx28_power_regs *power_regs =
@@ -486,22 +542,6 @@ void mx28_handle_5v_conflict(void) } } -int mx28_get_batt_volt (void ) -{ -struct mx28_power_regs *power_regs = - (struct mx28_power_regs *)MXS_POWER_BASE ; -uint32_t volt =readl (&power_regs->hw_power_battmonitor); - volt &=POWER_BATTMONITOR_BATT_VAL_MASK ; - volt >>=POWER_BATTMONITOR_BATT_VAL_OFFSET ; - volt *=8 ; -return volt; -} - -int mx28_is_batt_ready (void ) -{ -return (mx28_get_batt_volt () >=3600 ); -} -void mx28_5v_boot (void ) { struct mx28_power_regs *power_regs =
@@ -553,54 +593,6 @@ void mx28_switch_vddd_to_dcdc_source(void) POWER_VDDDCTRL_DISABLE_STEPPING); } -int mx28_is_batt_good (void ) -{ -struct mx28_power_regs *power_regs = - (struct mx28_power_regs *)MXS_POWER_BASE ; -uint32_t volt; - - volt =readl (&power_regs->hw_power_battmonitor); - volt &=POWER_BATTMONITOR_BATT_VAL_MASK ; - volt >>=POWER_BATTMONITOR_BATT_VAL_OFFSET ; - volt *=8 ; - -if ((volt >=2400 ) && (volt <=4300 )) -return 1 ; - -clrsetbits_le32 (&power_regs->hw_power_5vctrl, -POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK , -0x3 <<POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET ); -writel (POWER_5VCTRL_PWD_CHARGE_4P2_MASK , - &power_regs->hw_power_5vctrl_clr); - -clrsetbits_le32 (&power_regs->hw_power_charge, -POWER_CHARGE_STOP_ILIMIT_MASK |POWER_CHARGE_BATTCHRG_I_MASK , -POWER_CHARGE_STOP_ILIMIT_10MA |0x3 ); - -writel (POWER_CHARGE_PWD_BATTCHRG , &power_regs->hw_power_charge_clr); -writel (POWER_5VCTRL_PWD_CHARGE_4P2_MASK , - &power_regs->hw_power_5vctrl_clr); - -early_delay (500000 ); - - volt =readl (&power_regs->hw_power_battmonitor); - volt &=POWER_BATTMONITOR_BATT_VAL_MASK ; - volt >>=POWER_BATTMONITOR_BATT_VAL_OFFSET ; - volt *=8 ; - -if (volt >=3500 ) -return 0 ; - -if (volt >=2400 ) -return 1 ; - -writel (POWER_CHARGE_STOP_ILIMIT_MASK |POWER_CHARGE_BATTCHRG_I_MASK , - &power_regs->hw_power_charge_clr); -writel (POWER_CHARGE_PWD_BATTCHRG , &power_regs->hw_power_charge_set); - -return 0 ; -} -void mx28_power_configure_power_source (void ) {mx28_src_power_init ();
Signature · 1 line
1.7.10
PATCH 11/13 i.MX28: Add battery boot components to SPL
In reply to Marek VasutFrom: Marek Vasut <[email protected]>
--- arch/arm/cpu/arm926ejs/mx28/spl_power_init.c | 100 +++++++++++++++++++++++--- 1 file changed, 92 insertions(+), 8 deletions(-)
arch/arm/cpu/arm926ejs/mx28/spl_power_init.c +92 -8
@@ -45,11 +45,11 @@ void mx28_power_clock2pll(void)struct mx28_clkctrl_regs *clkctrl_regs = (struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE ; -writel (CLKCTRL_PLL0CTRL0_POWER , - &clkctrl_regs->hw_clkctrl_pll0ctrl0_set); +setbits_le32 (&clkctrl_regs->hw_clkctrl_pll0ctrl0, +CLKCTRL_PLL0CTRL0_POWER );early_delay (100 ); -writel (CLKCTRL_CLKSEQ_BYPASS_CPU , - &clkctrl_regs->hw_clkctrl_clkseq_clr); +setbits_le32 (&clkctrl_regs->hw_clkctrl_clkseq, +CLKCTRL_CLKSEQ_BYPASS_CPU ); }void mx28_power_clear_auto_restart (void )
@@ -455,9 +455,14 @@ void mx28_power_enable_4p2(void)mx28_power_init_4p2_regulator ();/* Shutdown battery (none present) */ -clrbits_le32 (&power_regs->hw_power_dcdc4p2,POWER_DCDC4P2_BO_MASK ); -writel (POWER_CTRL_DCDC4P2_BO_IRQ , &power_regs->hw_power_ctrl_clr); -writel (POWER_CTRL_ENIRQ_DCDC4P2_BO , &power_regs->hw_power_ctrl_clr); +if (!mx28_is_batt_ready ()) { +clrbits_le32 (&power_regs->hw_power_dcdc4p2, +POWER_DCDC4P2_BO_MASK ); +writel (POWER_CTRL_DCDC4P2_BO_IRQ , + &power_regs->hw_power_ctrl_clr); +writel (POWER_CTRL_ENIRQ_DCDC4P2_BO , + &power_regs->hw_power_ctrl_clr); + }mx28_power_init_dcdc_4p2_source ();
@@ -515,6 +520,50 @@ void mx28_powerdown(void) &power_regs->hw_power_reset); } +void mx28_batt_boot (void ) +{ +struct mx28_power_regs *power_regs = + (struct mx28_power_regs *)MXS_POWER_BASE ; + +clrbits_le32 (&power_regs->hw_power_5vctrl,POWER_5VCTRL_PWDN_5VBRNOUT ); +clrbits_le32 (&power_regs->hw_power_5vctrl,POWER_5VCTRL_ENABLE_DCDC ); + +clrbits_le32 (&power_regs->hw_power_dcdc4p2, +POWER_DCDC4P2_ENABLE_DCDC |POWER_DCDC4P2_ENABLE_4P2 ); +writel (POWER_CHARGE_ENABLE_LOAD , &power_regs->hw_power_charge_clr); + +/* 5V to battery handoff. */ +setbits_le32 (&power_regs->hw_power_5vctrl,POWER_5VCTRL_DCDC_XFER ); +early_delay (30 ); +clrbits_le32 (&power_regs->hw_power_5vctrl,POWER_5VCTRL_DCDC_XFER ); + +writel (POWER_CTRL_ENIRQ_DCDC4P2_BO , &power_regs->hw_power_ctrl_clr); + +clrsetbits_le32 (&power_regs->hw_power_minpwr, +POWER_MINPWR_HALFFETS ,POWER_MINPWR_DOUBLE_FETS ); + +mx28_power_set_linreg (); + +clrbits_le32 (&power_regs->hw_power_vdddctrl, +POWER_VDDDCTRL_DISABLE_FET |POWER_VDDDCTRL_ENABLE_LINREG ); + +clrbits_le32 (&power_regs->hw_power_vddactrl, +POWER_VDDACTRL_DISABLE_FET |POWER_VDDACTRL_ENABLE_LINREG ); + +clrbits_le32 (&power_regs->hw_power_vddioctrl, +POWER_VDDIOCTRL_DISABLE_FET ); + +setbits_le32 (&power_regs->hw_power_5vctrl, +POWER_5VCTRL_PWD_CHARGE_4P2_MASK ); + +setbits_le32 (&power_regs->hw_power_5vctrl, +POWER_5VCTRL_ENABLE_DCDC ); + +clrsetbits_le32 (&power_regs->hw_power_5vctrl, +POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK , +0x8 <<POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET ); +} +void mx28_handle_5v_conflict (void ) { struct mx28_power_regs *power_regs =
@@ -539,6 +588,11 @@ void mx28_handle_5v_conflict(void)mx28_powerdown ();break ; } + +if (tmp &POWER_STS_PSWITCH_MASK ) { +mx28_batt_boot (); +break ; + } } }
@@ -595,12 +649,42 @@ void mx28_switch_vddd_to_dcdc_source(void)void mx28_power_configure_power_source (void ) { +int batt_ready, batt_good; +struct mx28_power_regs *power_regs = + (struct mx28_power_regs *)MXS_POWER_BASE ; +struct mx28_lradc_regs *lradc_regs = + (struct mx28_lradc_regs *)MXS_LRADC_BASE ; +mx28_src_power_init (); -mx28_5v_boot (); + batt_ready =mx28_is_batt_ready (); + +if (readl (&power_regs->hw_power_sts) &POWER_STS_VDD5V_GT_VDDIO ) { + batt_good =mx28_is_batt_good (); +if (batt_ready) { +/* 5V source detected, good battery detected. */ +mx28_batt_boot (); + }else { +if (batt_good) { +/* 5V source detected, low battery detceted. */ + }else { +/* 5V source detected, bad battery detected. */ +writel (LRADC_CONVERSION_AUTOMATIC , + &lradc_regs->hw_lradc_conversion_clr); +clrbits_le32 (&power_regs->hw_power_battmonitor, +POWER_BATTMONITOR_BATT_VAL_MASK ); + } +mx28_5v_boot (); + } + }else { +/* 5V not detected, booting from battery. */ +mx28_batt_boot (); + } +mx28_power_clock2pll ();mx28_init_batt_bo (); +mx28_switch_vddd_to_dcdc_source (); }
Signature · 1 line
1.7.10
PATCH 12/13 i.MX28: Check if WP detection is implemented at all
In reply to Marek VasutIf the WP function is NULL, simply assume the card is always RW.
--- drivers/mmc/mxsmmc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/mmc/mxsmmc.c +2 -1
@@ -133,7 +133,8 @@ mxsmmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)/* READ or WRITE */ if (data->flags &MMC_DATA_READ ) { ctrl0 |=SSP_CTRL0_READ ; - }else if (priv->mmc_is_wp (mmc->block_dev.dev)) { + }else if (priv->mmc_is_wp && + priv->mmc_is_wp (mmc->block_dev.dev)) {printf ("MMC%d: Can not write a locked card!\n" , mmc->block_dev.dev);return UNUSABLE_ERR ;
Signature · 1 line
1.7.10
PATCH 13/13 i.MX28: Avoid redefining serial_put[cs]()
In reply to Marek VasutDo not define serial_putc() and serial_puts() calls if CONFIG_SPL_SERIAL_SUPPORT is set.
--- arch/arm/cpu/arm926ejs/mx28/spl_boot.c | 2 ++ 1 file changed, 2 insertions(+)
arch/arm/cpu/arm926ejs/mx28/spl_boot.c +2 -0
@@ -123,8 +123,10 @@ inline void board_init_r(gd_t *id, ulong dest_addr) ; } +#ifndef CONFIG_SPL_SERIAL_SUPPORT void serial_putc (const char c) {}void serial_puts (const char *s) {} +#endif void hang (void ) __attribute__ ((noreturn));void hang (void ) {
Signature · 1 line
1.7.10
cover M28EVK/i.MX28 improvements
In reply to Marek VasutQuoted 2 lines
These are some improvements that were stuck in my tree for a while, time to expunge them, please consider applying.
Ignore this series, typo mangled Stefano's address, will resend.
Quoted 45 lines
Tested on:
* DENX M28EVK v2.0
* DENX M28EVK v1.1
* Mysterious board #1 ...
* Unnamed board #2 ...Marek Vasut (13):
FEC: Abstract out register setup
M28EVK: Implement support for new board V2.0
M28EVK: Add SD update command
i.MX28: Improve passing of data from SPL to U-Boot i.MX28: Implement boot pads sampling and reporting i.MX28: Add LCDIF register definitions i.MX28: Shut down the LCD controller before reset i.MX28: Add LRADC register definitions i.MX28: Add LRADC init to i.MX28 SPL i.MX28: Reorder battery status functions in SPL i.MX28: Add battery boot components to SPL i.MX28: Check if WP detection is implemented at all i.MX28: Avoid redefining serial_put[cs]()arch/arm/cpu/arm926ejs/mx28/Makefile | 2 +- arch/arm/cpu/arm926ejs/mx28/mx28.c | 29 +- arch/arm/cpu/arm926ejs/mx28/mx28_init.h | 4 + arch/arm/cpu/arm926ejs/mx28/spl_boot.c | 57 ++++ arch/arm/cpu/arm926ejs/mx28/spl_lradc_init.c | 86 ++++++ arch/arm/cpu/arm926ejs/mx28/spl_mem_init.c | 10 +- arch/arm/cpu/arm926ejs/mx28/spl_power_init.c | 224 ++++++++++----- arch/arm/include/asm/arch-mx28/imx-regs.h | 2 + arch/arm/include/asm/arch-mx28/regs-lcdif.h | 212 ++++++++++++++ arch/arm/include/asm/arch-mx28/regs-lradc.h | 400 ++++++++++++++++++++++++++ arch/arm/include/asm/arch-mx28/sys_proto.h | 30 ++ board/denx/m28evk/m28evk.c | 20 +- board/denx/m28evk/spl_boot.c | 8 +- drivers/mmc/mxsmmc.c | 3 +- drivers/net/fec_mxc.c | 84 +++--- include/configs/m28evk.h | 10 + include/configs/mx28evk.h | 1 + 17 files changed, 1043 insertions(+), 139 deletions(-) create mode 100644 arch/arm/cpu/arm926ejs/mx28/spl_lradc_init.c create mode 100644 arch/arm/include/asm/arch-mx28/regs-lcdif.h create mode 100644 arch/arm/include/asm/arch-mx28/regs-lradc.h
Quoted 4 lines
Cc Detlev Zundel <[email protected]>Cc Fabio Estevam <[email protected]>Cc Stefano Babic <sbabic@denxde>Cc Wolfgang Denk <[email protected]>
Best regards,
Marek Vasut