From 089a70dc9c5edb424a6392259129016435acf162 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 6 May 2015 12:31:56 -0700 Subject: [PATCH 01/20] i.MX: Move UART definitions into a separate file Move UART definitions into a separate file to avoid redefinition in and magical constants in low level UART initialization code. Signed-off-by: Andrey Smirnov Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/include/mach/debug_ll.h | 10 +- drivers/serial/serial_imx.c | 108 +-------------------- include/serial/imx-uart.h | 112 ++++++++++++++++++++++ 3 files changed, 115 insertions(+), 115 deletions(-) create mode 100644 include/serial/imx-uart.h diff --git a/arch/arm/mach-imx/include/mach/debug_ll.h b/arch/arm/mach-imx/include/mach/debug_ll.h index f34eaa139..31371e2bb 100644 --- a/arch/arm/mach-imx/include/mach/debug_ll.h +++ b/arch/arm/mach-imx/include/mach/debug_ll.h @@ -13,6 +13,8 @@ #include #include +#include + #ifdef CONFIG_DEBUG_LL #ifdef CONFIG_DEBUG_IMX1_UART @@ -40,14 +42,6 @@ #define __IMX_UART_BASE(soc, num) soc##_UART##num##_BASE_ADDR #define IMX_UART_BASE(soc, num) __IMX_UART_BASE(soc, num) -#define URTX0 0x40 /* Transmitter Register */ - -#define UCR1 0x80 /* Control Register 1 */ -#define UCR1_UARTEN (1 << 0) /* UART enabled */ - -#define USR2 0x98 /* Status Register 2 */ -#define USR2_TXDC (1 << 3) /* Transmitter complete */ - static inline void PUTC_LL(int c) { void __iomem *base = (void *)IMX_UART_BASE(IMX_DEBUG_SOC, diff --git a/drivers/serial/serial_imx.c b/drivers/serial/serial_imx.c index f075c50fc..5b9b0d6ca 100644 --- a/drivers/serial/serial_imx.c +++ b/drivers/serial/serial_imx.c @@ -23,113 +23,7 @@ #include #include #include - -#define URXD0 0x0 /* Receiver Register */ -#define URTX0 0x40 /* Transmitter Register */ -#define UCR1 0x80 /* Control Register 1 */ -#define UCR2 0x84 /* Control Register 2 */ -#define UCR3 0x88 /* Control Register 3 */ -#define UCR4 0x8c /* Control Register 4 */ -#define UFCR 0x90 /* FIFO Control Register */ -#define USR1 0x94 /* Status Register 1 */ -#define USR2 0x98 /* Status Register 2 */ -#define UESC 0x9c /* Escape Character Register */ -#define UTIM 0xa0 /* Escape Timer Register */ -#define UBIR 0xa4 /* BRM Incremental Register */ -#define UBMR 0xa8 /* BRM Modulator Register */ -#define UBRC 0xac /* Baud Rate Count Register */ - -/* UART Control Register Bit Fields.*/ -#define URXD_CHARRDY (1<<15) -#define URXD_ERR (1<<14) -#define URXD_OVRRUN (1<<13) -#define URXD_FRMERR (1<<12) -#define URXD_BRK (1<<11) -#define URXD_PRERR (1<<10) -#define UCR1_ADEN (1<<15) /* Auto dectect interrupt */ -#define UCR1_ADBR (1<<14) /* Auto detect baud rate */ -#define UCR1_TRDYEN (1<<13) /* Transmitter ready interrupt enable */ -#define UCR1_IDEN (1<<12) /* Idle condition interrupt */ -#define UCR1_RRDYEN (1<<9) /* Recv ready interrupt enable */ -#define UCR1_RDMAEN (1<<8) /* Recv ready DMA enable */ -#define UCR1_IREN (1<<7) /* Infrared interface enable */ -#define UCR1_TXMPTYEN (1<<6) /* Transimitter empty interrupt enable */ -#define UCR1_RTSDEN (1<<5) /* RTS delta interrupt enable */ -#define UCR1_SNDBRK (1<<4) /* Send break */ -#define UCR1_TDMAEN (1<<3) /* Transmitter ready DMA enable */ -#define UCR1_UARTCLKEN (1<<2) /* UART clock enabled */ -#define UCR1_DOZE (1<<1) /* Doze */ -#define UCR1_UARTEN (1<<0) /* UART enabled */ -#define UCR2_ESCI (1<<15) /* Escape seq interrupt enable */ -#define UCR2_IRTS (1<<14) /* Ignore RTS pin */ -#define UCR2_CTSC (1<<13) /* CTS pin control */ -#define UCR2_CTS (1<<12) /* Clear to send */ -#define UCR2_ESCEN (1<<11) /* Escape enable */ -#define UCR2_PREN (1<<8) /* Parity enable */ -#define UCR2_PROE (1<<7) /* Parity odd/even */ -#define UCR2_STPB (1<<6) /* Stop */ -#define UCR2_WS (1<<5) /* Word size */ -#define UCR2_RTSEN (1<<4) /* Request to send interrupt enable */ -#define UCR2_TXEN (1<<2) /* Transmitter enabled */ -#define UCR2_RXEN (1<<1) /* Receiver enabled */ -#define UCR2_SRST (1<<0) /* SW reset */ -#define UCR3_DTREN (1<<13) /* DTR interrupt enable */ -#define UCR3_PARERREN (1<<12) /* Parity enable */ -#define UCR3_FRAERREN (1<<11) /* Frame error interrupt enable */ -#define UCR3_DSR (1<<10) /* Data set ready */ -#define UCR3_DCD (1<<9) /* Data carrier detect */ -#define UCR3_RI (1<<8) /* Ring indicator */ -#define UCR3_ADNIMP (1<<7) /* Autobaud Detection Not Improved */ -#define UCR3_RXDSEN (1<<6) /* Receive status interrupt enable */ -#define UCR3_AIRINTEN (1<<5) /* Async IR wake interrupt enable */ -#define UCR3_AWAKEN (1<<4) /* Async wake interrupt enable */ -#define UCR3_REF25 (1<<3) /* Ref freq 25 MHz (i.MXL / i.MX1) */ -#define UCR3_REF30 (1<<2) /* Ref Freq 30 MHz (i.MXL / i.MX1) */ -#define UCR3_RXDMUXSEL (1<<2) /* RXD Muxed input select (i.MX27) */ -#define UCR3_INVT (1<<1) /* Inverted Infrared transmission */ -#define UCR3_BPEN (1<<0) /* Preset registers enable */ -#define UCR4_CTSTL_32 (32<<10) /* CTS trigger level (32 chars) */ -#define UCR4_INVR (1<<9) /* Inverted infrared reception */ -#define UCR4_ENIRI (1<<8) /* Serial infrared interrupt enable */ -#define UCR4_WKEN (1<<7) /* Wake interrupt enable */ -#define UCR4_REF16 (1<<6) /* Ref freq 16 MHz */ -#define UCR4_IRSC (1<<5) /* IR special case */ -#define UCR4_TCEN (1<<3) /* Transmit complete interrupt enable */ -#define UCR4_BKEN (1<<2) /* Break condition interrupt enable */ -#define UCR4_OREN (1<<1) /* Receiver overrun interrupt enable */ -#define UCR4_DREN (1<<0) /* Recv data ready interrupt enable */ -#define UFCR_RXTL_SHF 0 /* Receiver trigger level shift */ -#define UFCR_RFDIV (7<<7) /* Reference freq divider mask */ -#define UFCR_TXTL_SHF 10 /* Transmitter trigger level shift */ -#define USR1_PARITYERR (1<<15) /* Parity error interrupt flag */ -#define USR1_RTSS (1<<14) /* RTS pin status */ -#define USR1_TRDY (1<<13) /* Transmitter ready interrupt/dma flag */ -#define USR1_RTSD (1<<12) /* RTS delta */ -#define USR1_ESCF (1<<11) /* Escape seq interrupt flag */ -#define USR1_FRAMERR (1<<10) /* Frame error interrupt flag */ -#define USR1_RRDY (1<<9) /* Receiver ready interrupt/dma flag */ -#define USR1_TIMEOUT (1<<7) /* Receive timeout interrupt status */ -#define USR1_RXDS (1<<6) /* Receiver idle interrupt flag */ -#define USR1_AIRINT (1<<5) /* Async IR wake interrupt flag */ -#define USR1_AWAKE (1<<4) /* Aysnc wake interrupt flag */ -#define USR2_ADET (1<<15) /* Auto baud rate detect complete */ -#define USR2_TXFE (1<<14) /* Transmit buffer FIFO empty */ -#define USR2_DTRF (1<<13) /* DTR edge interrupt flag */ -#define USR2_IDLE (1<<12) /* Idle condition */ -#define USR2_IRINT (1<<8) /* Serial infrared interrupt flag */ -#define USR2_WAKE (1<<7) /* Wake */ -#define USR2_RTSF (1<<4) /* RTS edge interrupt flag */ -#define USR2_TXDC (1<<3) /* Transmitter complete */ -#define USR2_BRCD (1<<2) /* Break condition */ -#define USR2_ORE (1<<1) /* Overrun error */ -#define USR2_RDR (1<<0) /* Recv data ready */ -#define UTS_FRCPERR (1<<13) /* Force parity error */ -#define UTS_LOOP (1<<12) /* Loop tx and rx */ -#define UTS_TXEMPTY (1<<6) /* TxFIFO empty */ -#define UTS_RXEMPTY (1<<5) /* RxFIFO empty */ -#define UTS_TXFULL (1<<4) /* TxFIFO full */ -#define UTS_RXFULL (1<<3) /* RxFIFO full */ -#define UTS_SOFTRST (1<<0) /* Software reset */ +#include /* * create default values for different platforms diff --git a/include/serial/imx-uart.h b/include/serial/imx-uart.h new file mode 100644 index 000000000..e40843d43 --- /dev/null +++ b/include/serial/imx-uart.h @@ -0,0 +1,112 @@ +#ifndef __IMX_UART_H__ +#define __IMX_UART_H__ + +#define URXD0 0x0 /* Receiver Register */ +#define URTX0 0x40 /* Transmitter Register */ +#define UCR1 0x80 /* Control Register 1 */ +#define UCR2 0x84 /* Control Register 2 */ +#define UCR3 0x88 /* Control Register 3 */ +#define UCR4 0x8c /* Control Register 4 */ +#define UFCR 0x90 /* FIFO Control Register */ +#define USR1 0x94 /* Status Register 1 */ +#define USR2 0x98 /* Status Register 2 */ +#define UESC 0x9c /* Escape Character Register */ +#define UTIM 0xa0 /* Escape Timer Register */ +#define UBIR 0xa4 /* BRM Incremental Register */ +#define UBMR 0xa8 /* BRM Modulator Register */ +#define UBRC 0xac /* Baud Rate Count Register */ + +/* UART Control Register Bit Fields.*/ +#define URXD_CHARRDY (1<<15) +#define URXD_ERR (1<<14) +#define URXD_OVRRUN (1<<13) +#define URXD_FRMERR (1<<12) +#define URXD_BRK (1<<11) +#define URXD_PRERR (1<<10) +#define UCR1_ADEN (1<<15) /* Auto dectect interrupt */ +#define UCR1_ADBR (1<<14) /* Auto detect baud rate */ +#define UCR1_TRDYEN (1<<13) /* Transmitter ready interrupt enable */ +#define UCR1_IDEN (1<<12) /* Idle condition interrupt */ +#define UCR1_RRDYEN (1<<9) /* Recv ready interrupt enable */ +#define UCR1_RDMAEN (1<<8) /* Recv ready DMA enable */ +#define UCR1_IREN (1<<7) /* Infrared interface enable */ +#define UCR1_TXMPTYEN (1<<6) /* Transimitter empty interrupt enable */ +#define UCR1_RTSDEN (1<<5) /* RTS delta interrupt enable */ +#define UCR1_SNDBRK (1<<4) /* Send break */ +#define UCR1_TDMAEN (1<<3) /* Transmitter ready DMA enable */ +#define UCR1_UARTCLKEN (1<<2) /* UART clock enabled */ +#define UCR1_DOZE (1<<1) /* Doze */ +#define UCR1_UARTEN (1<<0) /* UART enabled */ +#define UCR2_ESCI (1<<15) /* Escape seq interrupt enable */ +#define UCR2_IRTS (1<<14) /* Ignore RTS pin */ +#define UCR2_CTSC (1<<13) /* CTS pin control */ +#define UCR2_CTS (1<<12) /* Clear to send */ +#define UCR2_ESCEN (1<<11) /* Escape enable */ +#define UCR2_PREN (1<<8) /* Parity enable */ +#define UCR2_PROE (1<<7) /* Parity odd/even */ +#define UCR2_STPB (1<<6) /* Stop */ +#define UCR2_WS (1<<5) /* Word size */ +#define UCR2_RTSEN (1<<4) /* Request to send interrupt enable */ +#define UCR2_TXEN (1<<2) /* Transmitter enabled */ +#define UCR2_RXEN (1<<1) /* Receiver enabled */ +#define UCR2_SRST (1<<0) /* SW reset */ +#define UCR3_DTREN (1<<13) /* DTR interrupt enable */ +#define UCR3_PARERREN (1<<12) /* Parity enable */ +#define UCR3_FRAERREN (1<<11) /* Frame error interrupt enable */ +#define UCR3_DSR (1<<10) /* Data set ready */ +#define UCR3_DCD (1<<9) /* Data carrier detect */ +#define UCR3_RI (1<<8) /* Ring indicator */ +#define UCR3_ADNIMP (1<<7) /* Autobaud Detection Not Improved */ +#define UCR3_RXDSEN (1<<6) /* Receive status interrupt enable */ +#define UCR3_AIRINTEN (1<<5) /* Async IR wake interrupt enable */ +#define UCR3_AWAKEN (1<<4) /* Async wake interrupt enable */ +#define UCR3_REF25 (1<<3) /* Ref freq 25 MHz (i.MXL / i.MX1) */ +#define UCR3_REF30 (1<<2) /* Ref Freq 30 MHz (i.MXL / i.MX1) */ +#define UCR3_RXDMUXSEL (1<<2) /* RXD Muxed input select (i.MX27) */ +#define UCR3_INVT (1<<1) /* Inverted Infrared transmission */ +#define UCR3_BPEN (1<<0) /* Preset registers enable */ +#define UCR4_CTSTL_32 (32<<10) /* CTS trigger level (32 chars) */ +#define UCR4_INVR (1<<9) /* Inverted infrared reception */ +#define UCR4_ENIRI (1<<8) /* Serial infrared interrupt enable */ +#define UCR4_WKEN (1<<7) /* Wake interrupt enable */ +#define UCR4_REF16 (1<<6) /* Ref freq 16 MHz */ +#define UCR4_IRSC (1<<5) /* IR special case */ +#define UCR4_TCEN (1<<3) /* Transmit complete interrupt enable */ +#define UCR4_BKEN (1<<2) /* Break condition interrupt enable */ +#define UCR4_OREN (1<<1) /* Receiver overrun interrupt enable */ +#define UCR4_DREN (1<<0) /* Recv data ready interrupt enable */ +#define UFCR_RXTL_SHF 0 /* Receiver trigger level shift */ +#define UFCR_RFDIV (7<<7) /* Reference freq divider mask */ +#define UFCR_TXTL_SHF 10 /* Transmitter trigger level shift */ +#define USR1_PARITYERR (1<<15) /* Parity error interrupt flag */ +#define USR1_RTSS (1<<14) /* RTS pin status */ +#define USR1_TRDY (1<<13) /* Transmitter ready interrupt/dma flag */ +#define USR1_RTSD (1<<12) /* RTS delta */ +#define USR1_ESCF (1<<11) /* Escape seq interrupt flag */ +#define USR1_FRAMERR (1<<10) /* Frame error interrupt flag */ +#define USR1_RRDY (1<<9) /* Receiver ready interrupt/dma flag */ +#define USR1_TIMEOUT (1<<7) /* Receive timeout interrupt status */ +#define USR1_RXDS (1<<6) /* Receiver idle interrupt flag */ +#define USR1_AIRINT (1<<5) /* Async IR wake interrupt flag */ +#define USR1_AWAKE (1<<4) /* Aysnc wake interrupt flag */ +#define USR2_ADET (1<<15) /* Auto baud rate detect complete */ +#define USR2_TXFE (1<<14) /* Transmit buffer FIFO empty */ +#define USR2_DTRF (1<<13) /* DTR edge interrupt flag */ +#define USR2_IDLE (1<<12) /* Idle condition */ +#define USR2_IRINT (1<<8) /* Serial infrared interrupt flag */ +#define USR2_WAKE (1<<7) /* Wake */ +#define USR2_RTSF (1<<4) /* RTS edge interrupt flag */ +#define USR2_TXDC (1<<3) /* Transmitter complete */ +#define USR2_BRCD (1<<2) /* Break condition */ +#define USR2_ORE (1<<1) /* Overrun error */ +#define USR2_RDR (1<<0) /* Recv data ready */ +#define UTS_FRCPERR (1<<13) /* Force parity error */ +#define UTS_LOOP (1<<12) /* Loop tx and rx */ +#define UTS_TXEMPTY (1<<6) /* TxFIFO empty */ +#define UTS_RXEMPTY (1<<5) /* RxFIFO empty */ +#define UTS_TXFULL (1<<4) /* TxFIFO full */ +#define UTS_RXFULL (1<<3) /* RxFIFO full */ +#define UTS_SOFTRST (1<<0) /* Software reset */ + + +#endif /* __IMX_UART_H__ */ From 18a5a9b969cf9af5d3668bd6e5918554369439d3 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 6 May 2015 12:31:57 -0700 Subject: [PATCH 02/20] i.MX: serial: Add constants for UART clock divisor Signed-off-by: Andrey Smirnov Signed-off-by: Sascha Hauer --- include/serial/imx-uart.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/serial/imx-uart.h b/include/serial/imx-uart.h index e40843d43..0a0178882 100644 --- a/include/serial/imx-uart.h +++ b/include/serial/imx-uart.h @@ -77,6 +77,13 @@ #define UCR4_DREN (1<<0) /* Recv data ready interrupt enable */ #define UFCR_RXTL_SHF 0 /* Receiver trigger level shift */ #define UFCR_RFDIV (7<<7) /* Reference freq divider mask */ +#define UFCR_RFDIV6 (0b000<<7) /* Reference freq divider mask */ +#define UFCR_RFDIV5 (0b001<<7) /* Reference freq divider mask */ +#define UFCR_RFDIV4 (0b010<<7) /* Reference freq divider mask */ +#define UFCR_RFDIV3 (0b011<<7) /* Reference freq divider mask */ +#define UFCR_RFDIV2 (0b100<<7) /* Reference freq divider mask */ +#define UFCR_RFDIV1 (0b101<<7) /* Reference freq divider mask */ +#define UFCR_RFDIV7 (0b110<<7) /* Reference freq divider mask */ #define UFCR_TXTL_SHF 10 /* Transmitter trigger level shift */ #define USR1_PARITYERR (1<<15) /* Parity error interrupt flag */ #define USR1_RTSS (1<<14) /* RTS pin status */ From 7aca256facf543162e2718091d69e1a61b62bc61 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 6 May 2015 12:31:58 -0700 Subject: [PATCH 03/20] i.MX: serial: Add baud rate calculation convenience functions Add two functions to calculate values for UBMR and UBIR registers. This way both early serial initalization code and serial_imx.c can use them and not duplicate the code. Singed-off-by: Andrey Smirnov Signed-off-by: Sascha Hauer --- drivers/serial/serial_imx.c | 4 ++-- include/serial/imx-uart.h | 9 +++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/serial/serial_imx.c b/drivers/serial/serial_imx.c index 5b9b0d6ca..ed00a91b8 100644 --- a/drivers/serial/serial_imx.c +++ b/drivers/serial/serial_imx.c @@ -178,9 +178,9 @@ static int imx_serial_setbaudrate(struct console_device *cdev, int baudrate) writel(val, regs + UCR1); /* Set the numerator value minus one of the BRM ratio */ - writel((baudrate / 100) - 1, regs + UBIR); + writel(baudrate_to_ubir(baudrate), regs + UBIR); /* Set the denominator value minus one of the BRM ratio */ - writel((imx_serial_reffreq(priv) / 1600) - 1, regs + UBMR); + writel(refclock_to_ubmr(imx_serial_reffreq(priv)), regs + UBMR); writel(ucr1, regs + UCR1); diff --git a/include/serial/imx-uart.h b/include/serial/imx-uart.h index 0a0178882..7275e6ac3 100644 --- a/include/serial/imx-uart.h +++ b/include/serial/imx-uart.h @@ -115,5 +115,14 @@ #define UTS_RXFULL (1<<3) /* RxFIFO full */ #define UTS_SOFTRST (1<<0) /* Software reset */ +static inline int baudrate_to_ubir(int baudrate) +{ + return baudrate / 100 - 1; +} + +static inline int refclock_to_ubmr(int clock_hz) +{ + return clock_hz / 1600 - 1; +} #endif /* __IMX_UART_H__ */ From 031111d0bc5aab9348d5e4e14cdac0a5d982df67 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 6 May 2015 12:31:59 -0700 Subject: [PATCH 04/20] i.MX: serial: Add UART init functions for DEBUG_LL It appears that all i.MX51 and i.MX6 based boards that support early debug output inevitably do exactly the same thing with the registers of the UART peripheral. So to avoid code duplication three new subroutines are introduced: - imx_uart_setup_ll() that allows user to perform aforementioned "same thing" on any arbitrary UART at 'uartbase' and clocked at 'refclock' Hz. - imx6_uart_setup_ll() and imx5_uart_setup_ll() that do those actions assuming UART to be the one specified in configuration and 'refclock' to be equal to what it is when SoC comes out of reset. NOTE: Please note that 'imx*_uart_setup_ll' functions do add a slight difference in behaviour by dropping the initialization of ONEMS and UESC registers since those do not seem to be needed for early UART functionality Signed-off-by: Andrey Smirnov Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/include/mach/debug_ll.h | 51 ++++++++++++++++++++++- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-imx/include/mach/debug_ll.h b/arch/arm/mach-imx/include/mach/debug_ll.h index 31371e2bb..c2f454a7e 100644 --- a/arch/arm/mach-imx/include/mach/debug_ll.h +++ b/arch/arm/mach-imx/include/mach/debug_ll.h @@ -3,6 +3,7 @@ #include #include +#include #include #include #include @@ -17,6 +18,36 @@ #ifdef CONFIG_DEBUG_LL +#define __IMX_UART_BASE(soc, num) soc##_UART##num##_BASE_ADDR +#define IMX_UART_BASE(soc, num) __IMX_UART_BASE(soc, num) + +static inline void imx_uart_setup_ll(void __iomem *uartbase, + unsigned int refclock) +{ + writel(0x00000000, uartbase + UCR1); + + writel(UCR2_IRTS | UCR2_WS | UCR2_TXEN | UCR2_RXEN | UCR2_SRST, + uartbase + UCR2); + writel(UCR3_DSR | UCR3_DCD | UCR3_RI | UCR3_ADNIMP | UCR3_RXDMUXSEL, + uartbase + UCR3); + writel((0b10 << UFCR_TXTL_SHF) | UFCR_RFDIV1 | (1 << UFCR_RXTL_SHF), + uartbase + UFCR); + + writel(baudrate_to_ubir(CONFIG_BAUDRATE), + uartbase + UBIR); + writel(refclock_to_ubmr(refclock), + uartbase + UBMR); + + writel(UCR1_UARTEN, uartbase + UCR1); +} + +#define __imx_uart_setup_ll(refclock) \ + do { \ + imx_uart_setup_ll(IOMEM(IMX_UART_BASE(IMX_DEBUG_SOC, \ + CONFIG_DEBUG_IMX_UART_PORT)), \ + refclock); \ + } while(0) + #ifdef CONFIG_DEBUG_IMX1_UART #define IMX_DEBUG_SOC MX1 #elif defined CONFIG_DEBUG_IMX21_UART @@ -39,8 +70,15 @@ #error "unknown i.MX debug uart soc type" #endif -#define __IMX_UART_BASE(soc, num) soc##_UART##num##_BASE_ADDR -#define IMX_UART_BASE(soc, num) __IMX_UART_BASE(soc, num) +static inline void imx51_uart_setup_ll(void) +{ + __imx_uart_setup_ll(54000000); +} + +static inline void imx6_uart_setup_ll(void) +{ + __imx_uart_setup_ll(80000000); +} static inline void PUTC_LL(int c) { @@ -57,5 +95,14 @@ static inline void PUTC_LL(int c) writel(c, base + URTX0); } +#else + +static inline void imx_uart_setup_ll(void __iomem *uartbase, + unsigned int refclock) +{ +} +static inline void imx51_uart_setup_ll(void) {} +static inline void imx6_uart_setup_ll(void) {} + #endif /* CONFIG_DEBUG_LL */ #endif /* __MACH_DEBUG_LL_H__ */ From 95df4587ef57428b4459ba97fb9a7b890f0c1a86 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 6 May 2015 12:32:00 -0700 Subject: [PATCH 05/20] i.MX: serial: Convert PUTC_LL to use IOMEM Convert PUTC_LL to use IOMEM instead of explicit casting to 'void *', since the former seem to be more appropriate to the situation. Signed-off-by: Andrey Smirnov Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/include/mach/debug_ll.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-imx/include/mach/debug_ll.h b/arch/arm/mach-imx/include/mach/debug_ll.h index c2f454a7e..1f35e8153 100644 --- a/arch/arm/mach-imx/include/mach/debug_ll.h +++ b/arch/arm/mach-imx/include/mach/debug_ll.h @@ -82,8 +82,8 @@ static inline void imx6_uart_setup_ll(void) static inline void PUTC_LL(int c) { - void __iomem *base = (void *)IMX_UART_BASE(IMX_DEBUG_SOC, - CONFIG_DEBUG_IMX_UART_PORT); + void __iomem *base = IOMEM(IMX_UART_BASE(IMX_DEBUG_SOC, + CONFIG_DEBUG_IMX_UART_PORT)); if (!base) return; From 5887b0701baab73fcc008daf1e5a48e49879d4e9 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 6 May 2015 12:32:01 -0700 Subject: [PATCH 06/20] i.MX: serial: Convert i.MX51 and i.MX6 to use 'imx*_uart_setup_ll' NOTE: Boards 'karo-tx25' and 'tqma53' can benefit from this refactoring as well, but they were not converted because of the lack of i.MX25 or i.MX53 based hardware to test on. Signed-off-by: Andrey Smirnov Signed-off-by: Sascha Hauer --- arch/arm/boards/eltec-hipercam/lowlevel.c | 18 ++++++------------ arch/arm/boards/embest-riotboard/lowlevel.c | 16 +--------------- .../freescale-mx6sx-sabresdb/lowlevel.c | 11 +---------- arch/arm/boards/guf-santaro/lowlevel.c | 19 ++++++------------- arch/arm/boards/karo-tx6x/lowlevel.c | 11 +---------- .../arm/boards/phytec-phycard-imx6/lowlevel.c | 11 +---------- .../arm/boards/phytec-phyflex-imx6/lowlevel.c | 11 +---------- arch/arm/boards/tqma6x/lowlevel.c | 18 ++---------------- arch/arm/boards/variscite-mx6/lowlevel.c | 11 +---------- 9 files changed, 20 insertions(+), 106 deletions(-) diff --git a/arch/arm/boards/eltec-hipercam/lowlevel.c b/arch/arm/boards/eltec-hipercam/lowlevel.c index 8f11f6796..21542e49e 100644 --- a/arch/arm/boards/eltec-hipercam/lowlevel.c +++ b/arch/arm/boards/eltec-hipercam/lowlevel.c @@ -24,18 +24,10 @@ static void setup_uart(void) { - void __iomem *uart_base = (void *)0x02020000; - writel(0x1, 0x020e0330); - writel(0x00000000, uart_base + 0x80); - writel(0x00004027, uart_base + 0x84); - writel(0x00000704, uart_base + 0x88); - writel(0x00000a81, uart_base + 0x90); - writel(0x0000002b, uart_base + 0x9c); - writel(0x00013880, uart_base + 0xb0); - writel(0x0000047f, uart_base + 0xa4); - writel(0x0000c34f, uart_base + 0xa8); - writel(0x00000001, uart_base + 0x80); + + imx6_uart_setup_ll(); + putc_ll('>'); } @@ -48,7 +40,9 @@ ENTRY_FUNCTION(start_imx6dl_eltec_hipercam, r0, r1, r2) imx6_cpu_lowlevel_init(); arm_setup_stack(0x00940000 - 8); - setup_uart(); + + if (IS_ENABLED(CONFIG_DEBUG_LL)) + setup_uart(); fdt = __dtb_imx6dl_eltec_hipercam_start - get_runtime_offset(); diff --git a/arch/arm/boards/embest-riotboard/lowlevel.c b/arch/arm/boards/embest-riotboard/lowlevel.c index fe21b9aad..59010da51 100644 --- a/arch/arm/boards/embest-riotboard/lowlevel.c +++ b/arch/arm/boards/embest-riotboard/lowlevel.c @@ -10,20 +10,6 @@ #include #include -static inline void setup_uart(void) -{ - /* Enable UART for lowlevel debugging purposes */ - writel(0x00000000, 0x021e8080); - writel(0x00004027, 0x021e8084); - writel(0x00000704, 0x021e8088); - writel(0x00000a81, 0x021e8090); - writel(0x0000002b, 0x021e809c); - writel(0x00013880, 0x021e80b0); - writel(0x0000047f, 0x021e80a4); - writel(0x0000c34f, 0x021e80a8); - writel(0x00000001, 0x021e8080); -} - extern char __dtb_imx6s_riotboard_start[]; ENTRY_FUNCTION(start_imx6s_riotboard, r0, r1, r2) @@ -34,7 +20,7 @@ ENTRY_FUNCTION(start_imx6s_riotboard, r0, r1, r2) if (IS_ENABLED(CONFIG_DEBUG_LL)) { writel(0x4, 0x020e016c); - setup_uart(); + imx6_uart_setup_ll(); putc_ll('a'); } diff --git a/arch/arm/boards/freescale-mx6sx-sabresdb/lowlevel.c b/arch/arm/boards/freescale-mx6sx-sabresdb/lowlevel.c index 4c5a74ea6..5fdd9df88 100644 --- a/arch/arm/boards/freescale-mx6sx-sabresdb/lowlevel.c +++ b/arch/arm/boards/freescale-mx6sx-sabresdb/lowlevel.c @@ -22,7 +22,6 @@ static inline void setup_uart(void) { void __iomem *ccmbase = (void *)MX6_CCM_BASE_ADDR; - void __iomem *uartbase = (void *)MX6_UART1_BASE_ADDR; void __iomem *iomuxbase = (void *)MX6_IOMUXC_BASE_ADDR; writel(0xffffffff, ccmbase + 0x68); @@ -38,15 +37,7 @@ static inline void setup_uart(void) writel(0x0, iomuxbase + 0x28); writel(0x1b0b1, iomuxbase + 0x0370); - writel(0x00000000, uartbase + 0x80); - writel(0x00004027, uartbase + 0x84); - writel(0x00000784, uartbase + 0x88); - writel(0x00000a81, uartbase + 0x90); - writel(0x0000002b, uartbase + 0x9c); - writel(0x0001b0b0, uartbase + 0xb0); - writel(0x0000047f, uartbase + 0xa4); - writel(0x0000c34f, uartbase + 0xa8); - writel(0x00000001, uartbase + 0x80); + imx6_uart_setup_ll(); putc_ll('>'); } diff --git a/arch/arm/boards/guf-santaro/lowlevel.c b/arch/arm/boards/guf-santaro/lowlevel.c index 7753cea4e..3ccabf40a 100644 --- a/arch/arm/boards/guf-santaro/lowlevel.c +++ b/arch/arm/boards/guf-santaro/lowlevel.c @@ -9,20 +9,11 @@ static inline void setup_uart(void) { - void __iomem *uartbase = (void *)MX6_UART2_BASE_ADDR; void __iomem *iomuxbase = (void *)MX6_IOMUXC_BASE_ADDR; writel(0x1, iomuxbase + 0x2b0); - writel(0x00000000, uartbase + 0x80); - writel(0x00004027, uartbase + 0x84); - writel(0x00000704, uartbase + 0x88); - writel(0x00000a81, uartbase + 0x90); - writel(0x0000002b, uartbase + 0x9c); - writel(0x00013880, uartbase + 0xb0); - writel(0x0000047f, uartbase + 0xa4); - writel(0x0000c34f, uartbase + 0xa8); - writel(0x00000001, uartbase + 0x80); + imx6_uart_setup_ll(); putc_ll('>'); } @@ -38,10 +29,12 @@ ENTRY_FUNCTION(start_imx6q_guf_santaro, r0, r1, r2) arm_setup_stack(0x00920000 - 8); - for (i = 0x68; i <= 0x80; i += 4) - writel(0xffffffff, MX6_CCM_BASE_ADDR + i); + if (IS_ENABLED(CONFIG_DEBUG_LL)) { + for (i = 0x68; i <= 0x80; i += 4) + writel(0xffffffff, MX6_CCM_BASE_ADDR + i); - setup_uart(); + setup_uart(); + } fdt = __dtb_imx6q_guf_santaro_start - get_runtime_offset(); diff --git a/arch/arm/boards/karo-tx6x/lowlevel.c b/arch/arm/boards/karo-tx6x/lowlevel.c index cd4be5e9e..cb9d4c553 100644 --- a/arch/arm/boards/karo-tx6x/lowlevel.c +++ b/arch/arm/boards/karo-tx6x/lowlevel.c @@ -23,7 +23,6 @@ static inline void setup_uart(void) { void __iomem *ccmbase = (void *)MX6_CCM_BASE_ADDR; - void __iomem *uartbase = (void *)MX6_UART1_BASE_ADDR; void __iomem *iomuxbase = (void *)MX6_IOMUXC_BASE_ADDR; writel(0x1, iomuxbase + 0x0314); @@ -39,15 +38,7 @@ static inline void setup_uart(void) writel(0xffffffff, ccmbase + 0x7c); writel(0xffffffff, ccmbase + 0x80); - writel(0x00000000, uartbase + 0x80); - writel(0x00004027, uartbase + 0x84); - writel(0x00000784, uartbase + 0x88); - writel(0x00000a81, uartbase + 0x90); - writel(0x0000002b, uartbase + 0x9c); - writel(0x0001b0b0, uartbase + 0xb0); - writel(0x0000047f, uartbase + 0xa4); - writel(0x0000c34f, uartbase + 0xa8); - writel(0x00000001, uartbase + 0x80); + imx6_uart_setup_ll(); putc_ll('>'); } diff --git a/arch/arm/boards/phytec-phycard-imx6/lowlevel.c b/arch/arm/boards/phytec-phycard-imx6/lowlevel.c index dc106490e..1b8dca44d 100644 --- a/arch/arm/boards/phytec-phycard-imx6/lowlevel.c +++ b/arch/arm/boards/phytec-phycard-imx6/lowlevel.c @@ -27,7 +27,6 @@ static inline void setup_uart(void) { void __iomem *ccmbase = IOMEM(MX6_CCM_BASE_ADDR); - void __iomem *uartbase = IOMEM(MX6_UART3_BASE_ADDR); void __iomem *iomuxbase = IOMEM(MX6_IOMUXC_BASE_ADDR); writel(0x4, iomuxbase + 0x01f8); @@ -40,15 +39,7 @@ static inline void setup_uart(void) writel(0xffffffff, ccmbase + 0x7c); writel(0xffffffff, ccmbase + 0x80); - writel(0x00000000, uartbase + 0x80); - writel(0x00004027, uartbase + 0x84); - writel(0x00000704, uartbase + 0x88); - writel(0x00000a81, uartbase + 0x90); - writel(0x0000002b, uartbase + 0x9c); - writel(0x00013880, uartbase + 0xb0); - writel(0x0000047f, uartbase + 0xa4); - writel(0x0000c34f, uartbase + 0xa8); - writel(0x00000001, uartbase + 0x80); + imx6_uart_setup_ll(); putc_ll('>'); } diff --git a/arch/arm/boards/phytec-phyflex-imx6/lowlevel.c b/arch/arm/boards/phytec-phyflex-imx6/lowlevel.c index ee6d7fb26..51a2aa855 100644 --- a/arch/arm/boards/phytec-phyflex-imx6/lowlevel.c +++ b/arch/arm/boards/phytec-phyflex-imx6/lowlevel.c @@ -28,7 +28,6 @@ static inline void setup_uart(void) { void __iomem *ccmbase = (void *)MX6_CCM_BASE_ADDR; - void __iomem *uartbase = (void *)MX6_UART4_BASE_ADDR; void __iomem *iomuxbase = (void *)MX6_IOMUXC_BASE_ADDR; writel(0x4, iomuxbase + 0x01f8); @@ -41,15 +40,7 @@ static inline void setup_uart(void) writel(0xffffffff, ccmbase + 0x7c); writel(0xffffffff, ccmbase + 0x80); - writel(0x00000000, uartbase + 0x80); - writel(0x00004027, uartbase + 0x84); - writel(0x00000704, uartbase + 0x88); - writel(0x00000a81, uartbase + 0x90); - writel(0x0000002b, uartbase + 0x9c); - writel(0x00013880, uartbase + 0xb0); - writel(0x0000047f, uartbase + 0xa4); - writel(0x0000c34f, uartbase + 0xa8); - writel(0x00000001, uartbase + 0x80); + imx6_uart_setup_ll(); putc_ll('>'); } diff --git a/arch/arm/boards/tqma6x/lowlevel.c b/arch/arm/boards/tqma6x/lowlevel.c index 23f3407c0..aec84b176 100644 --- a/arch/arm/boards/tqma6x/lowlevel.c +++ b/arch/arm/boards/tqma6x/lowlevel.c @@ -24,20 +24,6 @@ #include #include -static inline void setup_uart(void) -{ - /* Enable UART for lowlevel debugging purposes */ - writel(0x00000000, 0x021e8080); - writel(0x00004027, 0x021e8084); - writel(0x00000704, 0x021e8088); - writel(0x00000a81, 0x021e8090); - writel(0x0000002b, 0x021e809c); - writel(0x00013880, 0x021e80b0); - writel(0x0000047f, 0x021e80a4); - writel(0x0000c34f, 0x021e80a8); - writel(0x00000001, 0x021e8080); -} - extern char __dtb_imx6q_mba6x_start[]; extern char __dtb_imx6dl_mba6x_start[]; @@ -51,7 +37,7 @@ ENTRY_FUNCTION(start_imx6q_mba6x, r0, r1, r2) if (IS_ENABLED(CONFIG_DEBUG_LL)) { writel(0x2, 0x020e0338); - setup_uart(); + imx6_uart_setup_ll(); putc_ll('a'); } @@ -72,7 +58,7 @@ ENTRY_FUNCTION(start_imx6dl_mba6x, r0, r1, r2) if (IS_ENABLED(CONFIG_DEBUG_LL)) { writel(0x2, 0x020e035c); - setup_uart(); + imx6_uart_setup_ll(); putc_ll('a'); } diff --git a/arch/arm/boards/variscite-mx6/lowlevel.c b/arch/arm/boards/variscite-mx6/lowlevel.c index 22e7eae32..7b1b4abd9 100644 --- a/arch/arm/boards/variscite-mx6/lowlevel.c +++ b/arch/arm/boards/variscite-mx6/lowlevel.c @@ -29,7 +29,6 @@ static inline void setup_uart(void) { void __iomem *ccmbase = (void *)MX6_CCM_BASE_ADDR; - void __iomem *uartbase = (void *)MX6_UART1_BASE_ADDR; void __iomem *iomuxbase = (void *)MX6_IOMUXC_BASE_ADDR; writel(0x03, iomuxbase + 0x0280); @@ -43,15 +42,7 @@ static inline void setup_uart(void) writel(0xffffffff, ccmbase + 0x7c); writel(0xffffffff, ccmbase + 0x80); - writel(0x00000000, uartbase + 0x80); - writel(0x00004027, uartbase + 0x84); - writel(0x00000704, uartbase + 0x88); - writel(0x00000a81, uartbase + 0x90); - writel(0x0000002b, uartbase + 0x9c); - writel(0x00013880, uartbase + 0xb0); - writel(0x0000047f, uartbase + 0xa4); - writel(0x0000c34f, uartbase + 0xa8); - writel(0x00000001, uartbase + 0x80); + imx6_uart_setup_ll(); putc_ll('>'); } From 5b7def7b68f46ed4ec9979865ff9187e465eed4e Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 6 May 2015 12:32:02 -0700 Subject: [PATCH 07/20] i.MX51: babbage: Implement CONFIG_DEBUG_LL Implement bits of configuraion needed to configure early debug output support. Signed-off-by: Andrey Smirnov Signed-off-by: Sascha Hauer --- .../boards/freescale-mx51-babbage/lowlevel.c | 36 +++++++++++++++++++ .../mach-imx/include/mach/clock-imx51_53.h | 5 +-- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/arch/arm/boards/freescale-mx51-babbage/lowlevel.c b/arch/arm/boards/freescale-mx51-babbage/lowlevel.c index 0f453f336..1355d259a 100644 --- a/arch/arm/boards/freescale-mx51-babbage/lowlevel.c +++ b/arch/arm/boards/freescale-mx51-babbage/lowlevel.c @@ -1,9 +1,41 @@ +#include +#include #include #include #include #include #include +static inline void setup_uart(void) +{ + void __iomem *iomuxbase = IOMEM(MX51_IOMUXC_BASE_ADDR); + void __iomem *ccmbase = IOMEM(MX51_CCM_BASE_ADDR); + + /* + * Restore CCM values that might be changed by the Mask ROM + * code. + * + * Source: RealView debug scripts provided by Freescale + */ + writel(MX5_CCM_CBCDR_RESET_VALUE, ccmbase + MX5_CCM_CBCDR); + writel(MX5_CCM_CSCMR1_RESET_VALUE, ccmbase + MX5_CCM_CSCMR1); + writel(MX5_CCM_CSCDR1_RESET_VALUE, ccmbase + MX5_CCM_CSCDR1); + + /* + * The code below should be more or less a "moral equivalent" + * of: + * MX51_PAD_UART1_TXD__UART1_TXD 0x1c5 + * + * in device tree + */ + writel(0x00000000, iomuxbase + 0x022c); + writel(0x000001c5, iomuxbase + 0x061c); + + imx51_uart_setup_ll(); + + putc_ll('>'); +} + extern char __dtb_imx51_babbage_start[]; ENTRY_FUNCTION(start_imx51_babbage, r0, r1, r2) @@ -11,6 +43,10 @@ ENTRY_FUNCTION(start_imx51_babbage, r0, r1, r2) void *fdt; imx5_cpu_lowlevel_init(); + + if (IS_ENABLED(CONFIG_DEBUG_LL)) + setup_uart(); + arm_setup_stack(0x20000000 - 16); fdt = __dtb_imx51_babbage_start - get_runtime_offset(); diff --git a/arch/arm/mach-imx/include/mach/clock-imx51_53.h b/arch/arm/mach-imx/include/mach/clock-imx51_53.h index 6004a6d36..0f25dfbf2 100644 --- a/arch/arm/mach-imx/include/mach/clock-imx51_53.h +++ b/arch/arm/mach-imx/include/mach/clock-imx51_53.h @@ -149,6 +149,7 @@ #define MX5_CCM_CACRR_ARM_PODF_MASK (0x7) /* Define the bits in register CBCDR */ +#define MX5_CCM_CBCDR_RESET_VALUE (0x19239145) #define MX5_CCM_CBCDR_EMI_CLK_SEL (0x1 << 26) #define MX5_CCM_CBCDR_PERIPH_CLK_SEL (0x1 << 25) #define MX5_CCM_CBCDR_DDR_HF_SEL_OFFSET (30) @@ -193,6 +194,7 @@ #define MX5_CCM_CBCMR_PERCLK_IPG_CLK_SEL (0x1 << 0) /* Define the bits in register CSCMR1 */ +#define MX5_CCM_CSCMR1_RESET_VALUE (0xa6a2a020) #define MX5_CCM_CSCMR1_SSI_EXT2_CLK_SEL_OFFSET (30) #define MX5_CCM_CSCMR1_SSI_EXT2_CLK_SEL_MASK (0x3 << 30) #define MX5_CCM_CSCMR1_SSI_EXT1_CLK_SEL_OFFSET (28) @@ -259,6 +261,7 @@ #define MX5_CCM_CSCMR2_SPDIF0_CLK_SEL_MASK (0x3) /* Define the bits in register CSCDR1 */ +#define MX5_CCM_CSCDR1_RESET_VALUE (0x00c30318) #define MX5_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PRED_OFFSET (22) #define MX5_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PRED_MASK (0x7 << 22) #define MX5_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PODF_OFFSET (19) @@ -585,5 +588,3 @@ #define MX5_SRPGC_EMI_PDNSCR (MX5_SRPGC_EMI_BASE + 0x8) #endif /* __ARCH_ARM_MACH_MX51_CRM_REGS_H__ */ - - From 059098fe07e06d5ebec484a5b4747197955b53ce Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 6 May 2015 12:32:03 -0700 Subject: [PATCH 08/20] i.MX: serial: Distil common clock ungating code Move all of the common clock ungating code in early UART initialization into a dedicated subroutine that can be shared by all of the users. Signed-off-by: Andrey Smirnov Signed-off-by: Sascha Hauer --- .../arm/boards/freescale-mx6sx-sabresdb/lowlevel.c | 9 +-------- arch/arm/boards/guf-santaro/lowlevel.c | 8 ++------ arch/arm/boards/karo-tx6x/lowlevel.c | 10 +--------- arch/arm/boards/phytec-phycard-imx6/lowlevel.c | 10 +--------- arch/arm/boards/phytec-phyflex-imx6/lowlevel.c | 10 +--------- arch/arm/boards/variscite-mx6/lowlevel.c | 10 +--------- arch/arm/mach-imx/include/mach/debug_ll.h | 14 ++++++++++++++ 7 files changed, 21 insertions(+), 50 deletions(-) diff --git a/arch/arm/boards/freescale-mx6sx-sabresdb/lowlevel.c b/arch/arm/boards/freescale-mx6sx-sabresdb/lowlevel.c index 5fdd9df88..af26557e9 100644 --- a/arch/arm/boards/freescale-mx6sx-sabresdb/lowlevel.c +++ b/arch/arm/boards/freescale-mx6sx-sabresdb/lowlevel.c @@ -21,16 +21,9 @@ static inline void setup_uart(void) { - void __iomem *ccmbase = (void *)MX6_CCM_BASE_ADDR; void __iomem *iomuxbase = (void *)MX6_IOMUXC_BASE_ADDR; - writel(0xffffffff, ccmbase + 0x68); - writel(0xffffffff, ccmbase + 0x6c); - writel(0xffffffff, ccmbase + 0x70); - writel(0xffffffff, ccmbase + 0x74); - writel(0xffffffff, ccmbase + 0x78); - writel(0xffffffff, ccmbase + 0x7c); - writel(0xffffffff, ccmbase + 0x80); + imx6_ungate_all_peripherals(); writel(0x0, iomuxbase + 0x24); writel(0x1b0b1, iomuxbase + 0x036C); diff --git a/arch/arm/boards/guf-santaro/lowlevel.c b/arch/arm/boards/guf-santaro/lowlevel.c index 3ccabf40a..e2b6df583 100644 --- a/arch/arm/boards/guf-santaro/lowlevel.c +++ b/arch/arm/boards/guf-santaro/lowlevel.c @@ -13,6 +13,7 @@ static inline void setup_uart(void) writel(0x1, iomuxbase + 0x2b0); + imx6_ungate_all_peripherals(); imx6_uart_setup_ll(); putc_ll('>'); @@ -23,18 +24,13 @@ extern char __dtb_imx6q_guf_santaro_start[]; ENTRY_FUNCTION(start_imx6q_guf_santaro, r0, r1, r2) { void *fdt; - int i; imx6_cpu_lowlevel_init(); arm_setup_stack(0x00920000 - 8); - if (IS_ENABLED(CONFIG_DEBUG_LL)) { - for (i = 0x68; i <= 0x80; i += 4) - writel(0xffffffff, MX6_CCM_BASE_ADDR + i); - + if (IS_ENABLED(CONFIG_DEBUG_LL)) setup_uart(); - } fdt = __dtb_imx6q_guf_santaro_start - get_runtime_offset(); diff --git a/arch/arm/boards/karo-tx6x/lowlevel.c b/arch/arm/boards/karo-tx6x/lowlevel.c index cb9d4c553..1e44b1b38 100644 --- a/arch/arm/boards/karo-tx6x/lowlevel.c +++ b/arch/arm/boards/karo-tx6x/lowlevel.c @@ -22,7 +22,6 @@ static inline void setup_uart(void) { - void __iomem *ccmbase = (void *)MX6_CCM_BASE_ADDR; void __iomem *iomuxbase = (void *)MX6_IOMUXC_BASE_ADDR; writel(0x1, iomuxbase + 0x0314); @@ -30,14 +29,7 @@ static inline void setup_uart(void) writel(0x1, iomuxbase + 0x0330); writel(0x1, iomuxbase + 0x032c); - writel(0xffffffff, ccmbase + 0x68); - writel(0xffffffff, ccmbase + 0x6c); - writel(0xffffffff, ccmbase + 0x70); - writel(0xffffffff, ccmbase + 0x74); - writel(0xffffffff, ccmbase + 0x78); - writel(0xffffffff, ccmbase + 0x7c); - writel(0xffffffff, ccmbase + 0x80); - + imx6_ungate_all_peripherals(); imx6_uart_setup_ll(); putc_ll('>'); diff --git a/arch/arm/boards/phytec-phycard-imx6/lowlevel.c b/arch/arm/boards/phytec-phycard-imx6/lowlevel.c index 1b8dca44d..d85a1ab0a 100644 --- a/arch/arm/boards/phytec-phycard-imx6/lowlevel.c +++ b/arch/arm/boards/phytec-phycard-imx6/lowlevel.c @@ -26,19 +26,11 @@ static inline void setup_uart(void) { - void __iomem *ccmbase = IOMEM(MX6_CCM_BASE_ADDR); void __iomem *iomuxbase = IOMEM(MX6_IOMUXC_BASE_ADDR); writel(0x4, iomuxbase + 0x01f8); - writel(0xffffffff, ccmbase + 0x68); - writel(0xffffffff, ccmbase + 0x6c); - writel(0xffffffff, ccmbase + 0x70); - writel(0xffffffff, ccmbase + 0x74); - writel(0xffffffff, ccmbase + 0x78); - writel(0xffffffff, ccmbase + 0x7c); - writel(0xffffffff, ccmbase + 0x80); - + imx6_ungate_all_peripherals(); imx6_uart_setup_ll(); putc_ll('>'); diff --git a/arch/arm/boards/phytec-phyflex-imx6/lowlevel.c b/arch/arm/boards/phytec-phyflex-imx6/lowlevel.c index 51a2aa855..cd37f88e0 100644 --- a/arch/arm/boards/phytec-phyflex-imx6/lowlevel.c +++ b/arch/arm/boards/phytec-phyflex-imx6/lowlevel.c @@ -27,19 +27,11 @@ static inline void setup_uart(void) { - void __iomem *ccmbase = (void *)MX6_CCM_BASE_ADDR; void __iomem *iomuxbase = (void *)MX6_IOMUXC_BASE_ADDR; writel(0x4, iomuxbase + 0x01f8); - writel(0xffffffff, ccmbase + 0x68); - writel(0xffffffff, ccmbase + 0x6c); - writel(0xffffffff, ccmbase + 0x70); - writel(0xffffffff, ccmbase + 0x74); - writel(0xffffffff, ccmbase + 0x78); - writel(0xffffffff, ccmbase + 0x7c); - writel(0xffffffff, ccmbase + 0x80); - + imx6_ungate_all_peripherals(); imx6_uart_setup_ll(); putc_ll('>'); diff --git a/arch/arm/boards/variscite-mx6/lowlevel.c b/arch/arm/boards/variscite-mx6/lowlevel.c index 7b1b4abd9..b0b930d43 100644 --- a/arch/arm/boards/variscite-mx6/lowlevel.c +++ b/arch/arm/boards/variscite-mx6/lowlevel.c @@ -28,20 +28,12 @@ static inline void setup_uart(void) { - void __iomem *ccmbase = (void *)MX6_CCM_BASE_ADDR; void __iomem *iomuxbase = (void *)MX6_IOMUXC_BASE_ADDR; writel(0x03, iomuxbase + 0x0280); writel(0x03, iomuxbase + 0x0284); - writel(0xffffffff, ccmbase + 0x68); - writel(0xffffffff, ccmbase + 0x6c); - writel(0xffffffff, ccmbase + 0x70); - writel(0xffffffff, ccmbase + 0x74); - writel(0xffffffff, ccmbase + 0x78); - writel(0xffffffff, ccmbase + 0x7c); - writel(0xffffffff, ccmbase + 0x80); - + imx6_ungate_all_peripherals(); imx6_uart_setup_ll(); putc_ll('>'); diff --git a/arch/arm/mach-imx/include/mach/debug_ll.h b/arch/arm/mach-imx/include/mach/debug_ll.h index 1f35e8153..ab939b3a8 100644 --- a/arch/arm/mach-imx/include/mach/debug_ll.h +++ b/arch/arm/mach-imx/include/mach/debug_ll.h @@ -101,8 +101,22 @@ static inline void imx_uart_setup_ll(void __iomem *uartbase, unsigned int refclock) { } + static inline void imx51_uart_setup_ll(void) {} static inline void imx6_uart_setup_ll(void) {} #endif /* CONFIG_DEBUG_LL */ + +static inline void imx_ungate_all_peripherals(void __iomem *ccmbase) +{ + int i; + for (i = 0x68; i <= 0x80; i += 4) + writel(0xffffffff, ccmbase + i); +} + +static inline void imx6_ungate_all_peripherals(void) +{ + imx_ungate_all_peripherals(IOMEM(MX6_CCM_BASE_ADDR)); +} + #endif /* __MACH_DEBUG_LL_H__ */ From c66574342dacbdb755ac8193057fc34e9b175c0b Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 6 May 2015 12:32:04 -0700 Subject: [PATCH 09/20] Makefile.lib: Make 'check_file_size' more flexible Make 'check_file_size' more flexible by not hardcoding the file whose size is going to be checked to '$@'. This way it is possible to use this subroutine to check the size of files other than the target of the rule. Signed-off-by: Andrey Smirnov Signed-off-by: Sascha Hauer --- Makefile | 2 +- arch/arm/pbl/Makefile | 2 +- arch/mips/pbl/Makefile | 2 +- scripts/Makefile.lib | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 3cea2fa1e..979baf6fb 100644 --- a/Makefile +++ b/Makefile @@ -700,7 +700,7 @@ OBJCOPYFLAGS_barebox.bin = -O binary barebox.bin: barebox FORCE $(call if_changed,objcopy) ifndef CONFIG_PBL_IMAGE - $(call cmd,check_file_size,$(CONFIG_BAREBOX_MAX_IMAGE_SIZE)) + $(call cmd,check_file_size,$@,$(CONFIG_BAREBOX_MAX_IMAGE_SIZE)) endif # By default the uImage load address is 2MB below CONFIG_TEXT_BASE, diff --git a/arch/arm/pbl/Makefile b/arch/arm/pbl/Makefile index 4c1788dd9..1ff39dbdf 100644 --- a/arch/arm/pbl/Makefile +++ b/arch/arm/pbl/Makefile @@ -22,7 +22,7 @@ endif $(obj)/zbarebox.bin: $(obj)/zbarebox FORCE $(call if_changed,objcopy) - $(call cmd,check_file_size,$(CONFIG_BAREBOX_MAX_IMAGE_SIZE)) + $(call cmd,check_file_size,$@,$(CONFIG_BAREBOX_MAX_IMAGE_SIZE)) $(Q)$(kecho) ' Barebox: fix size' $(Q)$(objtree)/scripts/fix_size -i -f $(objtree)/$@ $(FIX_SIZE) $(Q)$(kecho) ' Barebox: $@ is ready' diff --git a/arch/mips/pbl/Makefile b/arch/mips/pbl/Makefile index fea1f249b..b03bca125 100644 --- a/arch/mips/pbl/Makefile +++ b/arch/mips/pbl/Makefile @@ -15,7 +15,7 @@ extra-y += piggy.gzip piggy.lz4 piggy.lzo piggy.lzma piggy.xzkern piggy.sh $(obj)/zbarebox.bin: $(obj)/zbarebox FORCE $(call if_changed,objcopy) - $(call cmd,check_file_size,$(CONFIG_BAREBOX_MAX_IMAGE_SIZE)) + $(call cmd,check_file_size,$@,$(CONFIG_BAREBOX_MAX_IMAGE_SIZE)) $(Q)$(kecho) ' Barebox: $@ is ready' $(obj)/zbarebox.S: $(obj)/zbarebox FORCE diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 57426d030..e991f3369 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -388,10 +388,10 @@ quiet_cmd_ln = LN $@ cmd_ln = ln -sf $< $@ # Check size of a file -quiet_cmd_check_file_size = CHKSIZE $@ +quiet_cmd_check_file_size = CHKSIZE $2 cmd_check_file_size = set -e; \ - size=`stat -c%s $@`; \ - max_size=`printf "%d" $2`; \ + size=`stat -c%s $2`; \ + max_size=`printf "%d" $3`; \ if [ $$size -gt $$max_size ] ; \ then \ echo "$@ size $$size > of the maximum size $$max_size" >&2; \ From 903c9477a08c5655161779ef4144886928ecc7d1 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 6 May 2015 12:32:05 -0700 Subject: [PATCH 10/20] i.MX: Add provisions to boot from IRAM This commit add a very basic code to allow Barebox to be booted from IRAM. Given that the amount of IRAM on most i.MX variants is insufficient to contain a copy of Barebox with any reasonable degree of functionality this code uses IRAM only as a temporary location and eventually bootstraps from DRAM. But the presense of the intermediate IRAM-only stage allows to add provisions to test the area of DRAM that Barebox would be using to facilitate various testing scenarious. Signed-off-by: Andrey Smirnov Signed-off-by: Sascha Hauer --- Documentation/boards/imx.rst | 27 +++++++++ .../boards/freescale-mx51-babbage/Makefile | 3 + .../arm/boards/freescale-mx51-babbage/board.c | 60 +++++++++++++++++++ .../flash-header-common.imxcfg | 58 ++++++++++++++++++ .../flash-header-imx51-babbage-xload.imxcfg | 3 + .../flash-header-imx51-babbage.imxcfg | 60 +------------------ .../boards/freescale-mx51-babbage/lowlevel.c | 25 ++++++++ arch/arm/configs/imx_v7-xload_defconfig | 52 ++++++++++++++++ arch/arm/mach-imx/Kconfig | 15 +++++ arch/arm/mach-imx/Makefile | 1 + arch/arm/mach-imx/xload.c | 52 ++++++++++++++++ images/Makefile.imx | 20 ++++++- 12 files changed, 317 insertions(+), 59 deletions(-) create mode 100644 arch/arm/boards/freescale-mx51-babbage/flash-header-common.imxcfg create mode 100644 arch/arm/boards/freescale-mx51-babbage/flash-header-imx51-babbage-xload.imxcfg create mode 100644 arch/arm/configs/imx_v7-xload_defconfig create mode 100644 arch/arm/mach-imx/xload.c diff --git a/Documentation/boards/imx.rst b/Documentation/boards/imx.rst index 466f69c5b..ef1a6a507 100644 --- a/Documentation/boards/imx.rst +++ b/Documentation/boards/imx.rst @@ -46,6 +46,33 @@ The images can also always be started second stage:: bootm /mnt/tftp/barebox-freescale-imx51-babbage.img +Internal Boot Mode Through Internal RAM(IRAM) +--------------------------------------- + +The Internal Boot Mode Through Internal RAM is supported on: + +* i.MX51 + +As can be easily deduced from its name, the Internal Boot Mode Through +Internal RAM is just a variant of Internal Boot Mode so all of the +stated above still applies in this case. What it differs in is the following: + +* Boot process is done in two stages(First stage binary can be + produced with ``imx_v7-xload_defconfig``) +* DCD of the first stage image is set such that the image is fetched + into an unoccupied area or IRAM +* First stage image once uncompressed and set up will look for a + second stage bootloader on the same media it booted from and start + it(see mach-imx/xload.c for more details) +* Second stage images are just regular i.MX boot images + +Since on a typical i.MX SoC unused IRAM area is not enough to run +anything but a PBL this mode, due to its very limited usability, +serves only one purpose -- allow for a portion of a bootloader to be +executed without depending on DRAM to be functional. This peculiarity +of the mode can be used to implement various memory testing +scenarious. + USB Boot ^^^^^^^^ diff --git a/arch/arm/boards/freescale-mx51-babbage/Makefile b/arch/arm/boards/freescale-mx51-babbage/Makefile index 6252c8863..31b8fcd8a 100644 --- a/arch/arm/boards/freescale-mx51-babbage/Makefile +++ b/arch/arm/boards/freescale-mx51-babbage/Makefile @@ -1,3 +1,6 @@ obj-y += board.o flash-header-imx51-babbage.dcd.o extra-y += flash-header-imx51-babbage.dcd.S flash-header-imx51-babbage.dcd lwl-y += lowlevel.o + +obj-$(CONFIG_ARCH_IMX_XLOAD) += flash-header-imx51-babbage-xload.dcd.o +extra-$(CONFIG_ARCH_IMX_XLOAD) += flash-header-imx51-babbage-xload.dcd.S flash-header-imx51-babbage-xload.dcd diff --git a/arch/arm/boards/freescale-mx51-babbage/board.c b/arch/arm/boards/freescale-mx51-babbage/board.c index 001873b01..6650ff340 100644 --- a/arch/arm/boards/freescale-mx51-babbage/board.c +++ b/arch/arm/boards/freescale-mx51-babbage/board.c @@ -169,3 +169,63 @@ static int imx51_babbage_init(void) return 0; } coredevice_initcall(imx51_babbage_init); + +#ifdef CONFIG_ARCH_IMX_XLOAD + +static int imx51_babbage_xload_init_pinmux(void) +{ + static const iomux_v3_cfg_t pinmux[] = { + /* (e)CSPI */ + MX51_PAD_CSPI1_MOSI__ECSPI1_MOSI, + MX51_PAD_CSPI1_MISO__ECSPI1_MISO, + MX51_PAD_CSPI1_SCLK__ECSPI1_SCLK, + + /* (e)CSPI chip select lines */ + MX51_PAD_CSPI1_SS1__GPIO4_25, + + + /* eSDHC 1 */ + MX51_PAD_SD1_CMD__SD1_CMD, + MX51_PAD_SD1_CLK__SD1_CLK, + MX51_PAD_SD1_DATA0__SD1_DATA0, + MX51_PAD_SD1_DATA1__SD1_DATA1, + MX51_PAD_SD1_DATA2__SD1_DATA2, + MX51_PAD_SD1_DATA3__SD1_DATA3, + }; + + mxc_iomux_v3_setup_multiple_pads(ARRAY_AND_SIZE(pinmux)); + + return 0; +} +coredevice_initcall(imx51_babbage_xload_init_pinmux); + +static int imx51_babbage_xload_init_devices(void) +{ + static int spi0_chipselects[] = { + IMX_GPIO_NR(4, 25), + }; + + static struct spi_imx_master spi0_pdata = { + .chipselect = spi0_chipselects, + .num_chipselect = ARRAY_SIZE(spi0_chipselects), + }; + + static const struct spi_board_info spi0_devices[] = { + { + .name = "mtd_dataflash", + .chip_select = 0, + .max_speed_hz = 25 * 1000 * 1000, + .bus_num = 0, + }, + }; + + imx51_add_mmc0(NULL); + + spi_register_board_info(ARRAY_AND_SIZE(spi0_devices)); + imx51_add_spi0(&spi0_pdata); + + return 0; +} +device_initcall(imx51_babbage_xload_init_devices); + +#endif diff --git a/arch/arm/boards/freescale-mx51-babbage/flash-header-common.imxcfg b/arch/arm/boards/freescale-mx51-babbage/flash-header-common.imxcfg new file mode 100644 index 000000000..1332b7470 --- /dev/null +++ b/arch/arm/boards/freescale-mx51-babbage/flash-header-common.imxcfg @@ -0,0 +1,58 @@ +soc imx51 +dcdofs 0x400 +wm 32 0x73fa88a0 0x00000200 +wm 32 0x73fa850c 0x000020c5 +wm 32 0x73fa8510 0x000020c5 +wm 32 0x73fa883c 0x00000002 +wm 32 0x73fa8848 0x00000002 +wm 32 0x73fa84b8 0x000000e7 +wm 32 0x73fa84bc 0x00000045 +wm 32 0x73fa84c0 0x00000045 +wm 32 0x73fa84c4 0x00000045 +wm 32 0x73fa84c8 0x00000045 +wm 32 0x73fa8820 0x00000000 +wm 32 0x73fa84a4 0x00000003 +wm 32 0x73fa84a8 0x00000003 +wm 32 0x73fa84ac 0x000000e3 +wm 32 0x73fa84b0 0x000000e3 +wm 32 0x73fa84b4 0x000000e3 +wm 32 0x73fa84cc 0x000000e3 +wm 32 0x73fa84d0 0x000000e2 +wm 32 0x73fa882c 0x00000004 +wm 32 0x73fa88a4 0x00000004 +wm 32 0x73fa88ac 0x00000004 +wm 32 0x73fa88b8 0x00000004 +wm 32 0x83fd9000 0x82a20000 +wm 32 0x83fd9008 0x82a20000 +wm 32 0x83fd9010 0x000ad0d0 +wm 32 0x83fd9004 0x3f3584ab +wm 32 0x83fd900c 0x3f3584ab +wm 32 0x83fd9014 0x04008008 +wm 32 0x83fd9014 0x0000801a +wm 32 0x83fd9014 0x0000801b +wm 32 0x83fd9014 0x00448019 +wm 32 0x83fd9014 0x07328018 +wm 32 0x83fd9014 0x04008008 +wm 32 0x83fd9014 0x00008010 +wm 32 0x83fd9014 0x00008010 +wm 32 0x83fd9014 0x06328018 +wm 32 0x83fd9014 0x03808019 +wm 32 0x83fd9014 0x00408019 +wm 32 0x83fd9014 0x00008000 +wm 32 0x83fd9014 0x0400800c +wm 32 0x83fd9014 0x0000801e +wm 32 0x83fd9014 0x0000801f +wm 32 0x83fd9014 0x0000801d +wm 32 0x83fd9014 0x0732801c +wm 32 0x83fd9014 0x0400800c +wm 32 0x83fd9014 0x00008014 +wm 32 0x83fd9014 0x00008014 +wm 32 0x83fd9014 0x0632801c +wm 32 0x83fd9014 0x0380801d +wm 32 0x83fd9014 0x0040801d +wm 32 0x83fd9014 0x00008004 +wm 32 0x83fd9000 0xb2a20000 +wm 32 0x83fd9008 0xb2a20000 +wm 32 0x83fd9010 0x000ad6d0 +wm 32 0x83fd9034 0x90000000 +wm 32 0x83fd9014 0x00000000 diff --git a/arch/arm/boards/freescale-mx51-babbage/flash-header-imx51-babbage-xload.imxcfg b/arch/arm/boards/freescale-mx51-babbage/flash-header-imx51-babbage-xload.imxcfg new file mode 100644 index 000000000..b249a7d4b --- /dev/null +++ b/arch/arm/boards/freescale-mx51-babbage/flash-header-imx51-babbage-xload.imxcfg @@ -0,0 +1,3 @@ +loadaddr CONFIG_ARCH_IMX_UNUSED_IRAM_BASE + +#include "flash-header-common.imxcfg" \ No newline at end of file diff --git a/arch/arm/boards/freescale-mx51-babbage/flash-header-imx51-babbage.imxcfg b/arch/arm/boards/freescale-mx51-babbage/flash-header-imx51-babbage.imxcfg index bac6816fe..cb60e4752 100644 --- a/arch/arm/boards/freescale-mx51-babbage/flash-header-imx51-babbage.imxcfg +++ b/arch/arm/boards/freescale-mx51-babbage/flash-header-imx51-babbage.imxcfg @@ -1,59 +1,3 @@ loadaddr 0x90000000 -soc imx51 -dcdofs 0x400 -wm 32 0x73fa88a0 0x00000200 -wm 32 0x73fa850c 0x000020c5 -wm 32 0x73fa8510 0x000020c5 -wm 32 0x73fa883c 0x00000002 -wm 32 0x73fa8848 0x00000002 -wm 32 0x73fa84b8 0x000000e7 -wm 32 0x73fa84bc 0x00000045 -wm 32 0x73fa84c0 0x00000045 -wm 32 0x73fa84c4 0x00000045 -wm 32 0x73fa84c8 0x00000045 -wm 32 0x73fa8820 0x00000000 -wm 32 0x73fa84a4 0x00000003 -wm 32 0x73fa84a8 0x00000003 -wm 32 0x73fa84ac 0x000000e3 -wm 32 0x73fa84b0 0x000000e3 -wm 32 0x73fa84b4 0x000000e3 -wm 32 0x73fa84cc 0x000000e3 -wm 32 0x73fa84d0 0x000000e2 -wm 32 0x73fa882c 0x00000004 -wm 32 0x73fa88a4 0x00000004 -wm 32 0x73fa88ac 0x00000004 -wm 32 0x73fa88b8 0x00000004 -wm 32 0x83fd9000 0x82a20000 -wm 32 0x83fd9008 0x82a20000 -wm 32 0x83fd9010 0x000ad0d0 -wm 32 0x83fd9004 0x3f3584ab -wm 32 0x83fd900c 0x3f3584ab -wm 32 0x83fd9014 0x04008008 -wm 32 0x83fd9014 0x0000801a -wm 32 0x83fd9014 0x0000801b -wm 32 0x83fd9014 0x00448019 -wm 32 0x83fd9014 0x07328018 -wm 32 0x83fd9014 0x04008008 -wm 32 0x83fd9014 0x00008010 -wm 32 0x83fd9014 0x00008010 -wm 32 0x83fd9014 0x06328018 -wm 32 0x83fd9014 0x03808019 -wm 32 0x83fd9014 0x00408019 -wm 32 0x83fd9014 0x00008000 -wm 32 0x83fd9014 0x0400800c -wm 32 0x83fd9014 0x0000801e -wm 32 0x83fd9014 0x0000801f -wm 32 0x83fd9014 0x0000801d -wm 32 0x83fd9014 0x0732801c -wm 32 0x83fd9014 0x0400800c -wm 32 0x83fd9014 0x00008014 -wm 32 0x83fd9014 0x00008014 -wm 32 0x83fd9014 0x0632801c -wm 32 0x83fd9014 0x0380801d -wm 32 0x83fd9014 0x0040801d -wm 32 0x83fd9014 0x00008004 -wm 32 0x83fd9000 0xb2a20000 -wm 32 0x83fd9008 0xb2a20000 -wm 32 0x83fd9010 0x000ad6d0 -wm 32 0x83fd9034 0x90000000 -wm 32 0x83fd9014 0x00000000 + +#include "flash-header-common.imxcfg" \ No newline at end of file diff --git a/arch/arm/boards/freescale-mx51-babbage/lowlevel.c b/arch/arm/boards/freescale-mx51-babbage/lowlevel.c index 1355d259a..af40f4405 100644 --- a/arch/arm/boards/freescale-mx51-babbage/lowlevel.c +++ b/arch/arm/boards/freescale-mx51-babbage/lowlevel.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -53,3 +54,27 @@ ENTRY_FUNCTION(start_imx51_babbage, r0, r1, r2) imx51_barebox_entry(fdt); } + +static noinline void babbage_entry(void) +{ + arm_early_mmu_cache_invalidate(); + + relocate_to_current_adr(); + setup_c(); + + puts_ll("lowlevel init done\n"); + + imx51_barebox_entry(NULL); +} + +ENTRY_FUNCTION(start_imx51_babbage_xload, r0, r1, r2) +{ + imx5_cpu_lowlevel_init(); + + if (IS_ENABLED(CONFIG_DEBUG_LL)) + setup_uart(); + + arm_setup_stack(0x20000000 - 16); + + babbage_entry(); +} diff --git a/arch/arm/configs/imx_v7-xload_defconfig b/arch/arm/configs/imx_v7-xload_defconfig new file mode 100644 index 000000000..1d82f98f4 --- /dev/null +++ b/arch/arm/configs/imx_v7-xload_defconfig @@ -0,0 +1,52 @@ +CONFIG_ARCH_IMX=y +CONFIG_ARCH_IMX_IMXIMAGE=y +CONFIG_ARCH_IMX_XLOAD=y + +CONFIG_ARCH_IMX51=y +CONFIG_IMX_MULTI_BOARDS=y +CONFIG_MACH_FREESCALE_MX51_PDK=y + +CONFIG_THUMB2_BAREBOX=y +# CONFIG_CMD_ARM_CPUINFO is not set +CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y +CONFIG_MMU=y +CONFIG_TEXT_BASE=0x0 +CONFIG_MALLOC_SIZE=0x0 +CONFIG_MALLOC_DUMMY=y +CONFIG_RELOCATABLE=y +CONFIG_BAUDRATE=115200 +CONFIG_SHELL_NONE=y + +CONFIG_DEBUG_LL=y +CONFIG_DEBUG_IMX51_UART=y +CONFIG_DEBUG_IMX_UART_PORT=1 + +CONFIG_HAS_DEBUG_LL=y + +CONFIG_MTD=y +# CONFIG_MTD_WRITE is not set +CONFIG_MTD_DATAFLASH=y + +# CONFIG_ERRNO_MESSAGES is not set +# CONFIG_TIMESTAMP is not set +# CONFIG_DEFAULT_ENVIRONMENT is not set +CONFIG_DRIVER_SERIAL_IMX=y + +CONFIG_MCI=y +CONFIG_MCI_STARTUP=y +# CONFIG_MCI_WRITE is not set + +CONFIG_MCI_IMX_ESDHC=y + +CONFIG_EEPROM_AT25=y + +CONFIG_WATCHDOG_IMX_RESET_SOURCE=y +CONFIG_WATCHDOG=y +CONFIG_WATCHDOG_IMX=y + +# CONFIG_FS_RAMFS is not set +# CONFIG_FS_DEVFS is not set +CONFIG_FS_FAT=y +CONFIG_BOOTSTRAP=y +CONFIG_BOOTSTRAP_DISK=y +CONFIG_BOOTSTRAP_DEVFS=y diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index c71347770..3ccd060a5 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -68,6 +68,21 @@ config ARCH_IMX_IMXIMAGE help if enabled the imx-image tool is compiled +config ARCH_IMX_XLOAD + bool + depends on ARCH_IMX51 + prompt "Build preloader image" + +config ARCH_IMX_UNUSED_IRAM_BASE + hex + depends on ARCH_IMX_XLOAD + default 0x1ffe2000 if ARCH_IMX51 + +config ARCH_IMX_UNUSED_IRAM_SIZE + hex + depends on ARCH_IMX_XLOAD + default 0x16000 if ARCH_IMX51 + choice depends on ARCH_IMX_INTERNAL_BOOT prompt "Internal boot source" diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index ae953b1bf..0320d1c2e 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -12,6 +12,7 @@ pbl-$(CONFIG_ARCH_IMX53) += imx53.o imx5.o esdctl-v4.o obj-$(CONFIG_ARCH_IMX6) += imx6.o usb-imx6.o clk-imx6.o lwl-$(CONFIG_ARCH_IMX6) += imx6-mmdc.o obj-$(CONFIG_ARCH_IMX6SX) += clk-imx6sx.o +obj-$(CONFIG_ARCH_IMX_XLOAD) += xload.o obj-$(CONFIG_IMX_IIM) += iim.o obj-$(CONFIG_IMX_OCOTP) += ocotp.o obj-$(CONFIG_NAND_IMX) += nand.o diff --git a/arch/arm/mach-imx/xload.c b/arch/arm/mach-imx/xload.c new file mode 100644 index 000000000..16d56ab28 --- /dev/null +++ b/arch/arm/mach-imx/xload.c @@ -0,0 +1,52 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +static __noreturn int imx_xload(void) +{ + enum bootsource bootsource = bootsource_get(); + void *buf; + + switch (bootsource) { + case BOOTSOURCE_MMC: + pr_info("booting from MMC\n"); + buf = bootstrap_read_disk("disk0.0", "fat"); + break; + case BOOTSOURCE_SPI: + pr_info("booting from SPI\n"); + buf = bootstrap_read_devfs("dataflash0", false, + SZ_256K, SZ_1M, SZ_1M); + break; + default: + pr_err("unknown bootsource %d\n", bootsource); + hang(); + } + + if (!buf) { + pr_err("failed to load barebox.bin\n"); + hang(); + } + + bootstrap_boot(buf, 0); + + hang(); +} + +static int imx_devices_init(void) +{ + barebox_main = imx_xload; + return 0; +} +coredevice_initcall(imx_devices_init); diff --git a/images/Makefile.imx b/images/Makefile.imx index 415b294e8..6b4495815 100644 --- a/images/Makefile.imx +++ b/images/Makefile.imx @@ -4,8 +4,15 @@ # %.imximg - convert into i.MX image # ---------------------------------------------------------------- + +ifdef CONFIG_ARCH_IMX_XLOAD +$(obj)/%.imximg: $(obj)/% FORCE + $(call cmd,check_file_size,$<,$(CONFIG_ARCH_IMX_UNUSED_IRAM_SIZE)) + $(call if_changed,imx_image) +else $(obj)/%.imximg: $(obj)/% FORCE $(call if_changed,imx_image) +endif # ----------------------- i.MX25 based boards --------------------------- pblx-$(CONFIG_MACH_TX25) += start_imx25_karo_tx25 @@ -29,7 +36,18 @@ image-$(CONFIG_MACH_PCM038) += barebox-phytec-phycore-imx27.img pblx-$(CONFIG_MACH_FREESCALE_MX51_PDK) += start_imx51_babbage CFG_start_imx51_babbage.pblx.imximg = $(board)/freescale-mx51-babbage/flash-header-imx51-babbage.imxcfg FILE_barebox-freescale-imx51-babbage.img = start_imx51_babbage.pblx.imximg -image-$(CONFIG_MACH_FREESCALE_MX51_PDK) += barebox-freescale-imx51-babbage.img +imx-barebox-$(CONFIG_MACH_FREESCALE_MX51_PDK) += barebox-freescale-imx51-babbage.img + +pblx-$(CONFIG_MACH_FREESCALE_MX51_PDK) += start_imx51_babbage_xload +CFG_start_imx51_babbage_xload.pblx.imximg = $(board)/freescale-mx51-babbage/flash-header-imx51-babbage-xload.imxcfg +FILE_barebox-freescale-imx51-babbage-xload.img = start_imx51_babbage_xload.pblx.imximg +imx-xload-$(CONFIG_MACH_FREESCALE_MX51_PDK) += barebox-freescale-imx51-babbage-xload.img + +ifdef CONFIG_ARCH_IMX_XLOAD +image-y += $(imx-xload-y) +else +image-y += $(imx-barebox-y) +endif pblx-$(CONFIG_MACH_EFIKA_MX_SMARTBOOK) += start_imx51_genesi_efikasb CFG_start_imx51_genesi_efikasb.pblx.imximg = $(board)/efika-mx-smartbook/flash-header-imx51-genesi-efikasb.imxcfg From 6f1d94b8892ffa995b2e0ca716d82fd7efaeea18 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 6 May 2015 12:32:06 -0700 Subject: [PATCH 11/20] imx-image: Correctly fill image size in prepended header If called with '-b' option 'imx-image' tool prepends barebox header to the image, but the tool does not fill the data at image size offset correctly. Fix that. Signed-off-by: Andrey Smirnov Signed-off-by: Sascha Hauer --- scripts/imx/Makefile | 2 ++ scripts/imx/imx-image.c | 11 ++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/scripts/imx/Makefile b/scripts/imx/Makefile index be0b49010..ee0acc151 100644 --- a/scripts/imx/Makefile +++ b/scripts/imx/Makefile @@ -6,5 +6,7 @@ always := $(hostprogs-y) HOSTCFLAGS_imx-usb-loader.o = `pkg-config --cflags libusb-1.0` HOSTLOADLIBES_imx-usb-loader = `pkg-config --libs libusb-1.0` +HOSTCFLAGS_imx-image.o = -I$(srctree) + imx-usb-loader-objs := imx-usb-loader.o imx-image-objs := imx-image.o diff --git a/scripts/imx/imx-image.c b/scripts/imx/imx-image.c index 25ea4d8d1..e765c1d3d 100644 --- a/scripts/imx/imx-image.c +++ b/scripts/imx/imx-image.c @@ -27,6 +27,8 @@ #include #include +#include + #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) #define offsetof(TYPE, MEMBER) __builtin_offsetof(TYPE, MEMBER) #define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y)) @@ -91,9 +93,12 @@ static int add_header_v1(void *buf, int offset, uint32_t loadaddr, uint32_t imag { struct imx_flash_header *hdr; int dcdsize = curdcd * sizeof(uint32_t); + uint32_t *psize = buf + ARM_HEAD_SIZE_OFFSET; - if (add_barebox_header) + if (add_barebox_header) { memcpy(buf, bb_header, sizeof(bb_header)); + *psize = imagesize; + } buf += offset; hdr = buf; @@ -177,6 +182,7 @@ static int add_header_v2(void *buf, int offset, uint32_t loadaddr, uint32_t imag { struct imx_flash_header_v2 *hdr; int dcdsize = curdcd * sizeof(uint32_t); + uint32_t *psize = buf + ARM_HEAD_SIZE_OFFSET; if (add_barebox_header) memcpy(buf, bb_header, sizeof(bb_header)); @@ -201,6 +207,9 @@ static int add_header_v2(void *buf, int offset, uint32_t loadaddr, uint32_t imag hdr->boot_data.size += CSF_LEN; } + if (add_barebox_header) + *psize = hdr->boot_data.size; + hdr->dcd_header.tag = TAG_DCD_HEADER; hdr->dcd_header.length = htobe16(sizeof(uint32_t) + dcdsize); hdr->dcd_header.version = DCD_VERSION; From 49673cfc5f67f229c80807cf582ff3f3f09b639b Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 6 May 2015 12:32:07 -0700 Subject: [PATCH 12/20] bootstrap: Fix potential memory leak in 'read_image_head' Original version of 'read_image_head' would not free the memory allocated for barebox header in cases of any failure. Fix this by adding a dedicated resourse de-allocation code path. Signed-off-by: Andrey Smirnov Signed-off-by: Sascha Hauer --- lib/bootstrap/devfs.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/bootstrap/devfs.c b/lib/bootstrap/devfs.c index 704680a4c..82c7d219a 100644 --- a/lib/bootstrap/devfs.c +++ b/lib/bootstrap/devfs.c @@ -35,7 +35,7 @@ static void *read_image_head(const char *name) cdev = cdev_open(name, O_RDONLY); if (!cdev) { bootstrap_err("failed to open partition\n"); - return NULL; + goto free_header; } ret = cdev_read(cdev, header, BAREBOX_HEAD_SIZE, 0, 0); @@ -43,10 +43,14 @@ static void *read_image_head(const char *name) if (ret != BAREBOX_HEAD_SIZE) { bootstrap_err("failed to read from partition\n"); - return NULL; + goto free_header; } return header; + +free_header: + free(header); + return NULL; } static unsigned int get_image_size(void *head) From a11d0e04c831f6af0c36b3137d304b538bc86654 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 6 May 2015 12:32:08 -0700 Subject: [PATCH 13/20] bootstrap_read_devfs(): Check for errors from devfs_add_partition() Check for errors returned by devfs_add_partition() and bail if there are any. Signed-off-by: Andrey Smirnov Signed-off-by: Sascha Hauer --- lib/bootstrap/devfs.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/bootstrap/devfs.c b/lib/bootstrap/devfs.c index 82c7d219a..0c47cd27c 100644 --- a/lib/bootstrap/devfs.c +++ b/lib/bootstrap/devfs.c @@ -82,10 +82,17 @@ void* bootstrap_read_devfs(char *devname, bool use_bb, int offset, int ret; int size = 0; void *to, *header; - struct cdev *cdev; + struct cdev *cdev, *partition; char *partname = "x"; - devfs_add_partition(devname, offset, max_size, DEVFS_PARTITION_FIXED, partname); + partition = devfs_add_partition(devname, offset, max_size, + DEVFS_PARTITION_FIXED, partname); + if (IS_ERR(partition)) { + bootstrap_err("%s: failed to add partition (%ld)\n", + devname, PTR_ERR(partition)); + return NULL; + } + if (use_bb) { dev_add_bb_dev(partname, "bbx"); partname = "bbx"; From d26ed41facc4c18d33730ad935531aebc0d1fa71 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 6 May 2015 12:32:09 -0700 Subject: [PATCH 14/20] bootstrap_read_devfs(): Close file after we are done with it Signed-off-by: Andrey Smirnov Signed-off-by: Sascha Hauer --- lib/bootstrap/devfs.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/bootstrap/devfs.c b/lib/bootstrap/devfs.c index 0c47cd27c..5693431a9 100644 --- a/lib/bootstrap/devfs.c +++ b/lib/bootstrap/devfs.c @@ -120,6 +120,8 @@ void* bootstrap_read_devfs(char *devname, bool use_bb, int offset, } ret = cdev_read(cdev, to, size, 0, 0); + cdev_close(cdev); + if (ret != size) { bootstrap_err("%s: failed to read from %s\n", devname, partname); return NULL; From 065d75c341ed473f51c7f7e486f09419387d9894 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 6 May 2015 12:32:10 -0700 Subject: [PATCH 15/20] bootstrap_read_devfs(): Fix potential memory leak In case of a failure in one of the cdev_* functions original version of bootstrap_read_devfs would not release memory allocated for barebox header or memory allocated for the image. This commit fixes this by adding resource deallocation code. Signed-off-by: Andrey Smirnov Signed-off-by: Sascha Hauer --- lib/bootstrap/devfs.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/lib/bootstrap/devfs.c b/lib/bootstrap/devfs.c index 5693431a9..576f15159 100644 --- a/lib/bootstrap/devfs.c +++ b/lib/bootstrap/devfs.c @@ -81,7 +81,7 @@ void* bootstrap_read_devfs(char *devname, bool use_bb, int offset, { int ret; int size = 0; - void *to, *header; + void *to, *header, *result = NULL; struct cdev *cdev, *partition; char *partname = "x"; @@ -116,16 +116,21 @@ void* bootstrap_read_devfs(char *devname, bool use_bb, int offset, cdev = cdev_open(partname, O_RDONLY); if (!cdev) { bootstrap_err("%s: failed to open %s\n", devname, partname); - return NULL; + goto free_memory; } ret = cdev_read(cdev, to, size, 0, 0); cdev_close(cdev); - if (ret != size) { + if (ret != size) bootstrap_err("%s: failed to read from %s\n", devname, partname); - return NULL; - } + else + result = to; - return to; +free_memory: + free(header); + if (!result) + free(to); + + return result; } From 835ffe76c46cdd97a3d1f1d75bca593185db083a Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 6 May 2015 12:32:11 -0700 Subject: [PATCH 16/20] bootstrap_read_devfs(): Check for errors from dev_add_bb_dev() Check for errors returned by dev_add_bb_dev() and bail if there are any. Signed-off-by: Andrey Smirnov Signed-off-by: Sascha Hauer --- lib/bootstrap/devfs.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/bootstrap/devfs.c b/lib/bootstrap/devfs.c index 576f15159..48b74f9fe 100644 --- a/lib/bootstrap/devfs.c +++ b/lib/bootstrap/devfs.c @@ -94,7 +94,14 @@ void* bootstrap_read_devfs(char *devname, bool use_bb, int offset, } if (use_bb) { - dev_add_bb_dev(partname, "bbx"); + ret = dev_add_bb_dev(partname, "bbx"); + if (ret) { + bootstrap_err( + "%s: failed to add bad block aware partition (%d)\n", + devname, ret); + goto exit; + } + partname = "bbx"; } @@ -131,6 +138,6 @@ free_memory: free(header); if (!result) free(to); - +exit: return result; } From e5dda9d5e2f27bc8cabf8f4915fadad8112e5f8b Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 6 May 2015 12:32:12 -0700 Subject: [PATCH 17/20] bootstrap_read_devfs(): Remove all partitions upon function completion Bootstrap_read_devfs does not remove the devices it creates during the course of its execution which might be considered as a resource leak. Remedy that by adding the code to remove those devices upon function completion. Signed-off-by: Andrey Smirnov Signed-off-by: Sascha Hauer --- lib/bootstrap/devfs.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/lib/bootstrap/devfs.c b/lib/bootstrap/devfs.c index 48b74f9fe..b6edec7e2 100644 --- a/lib/bootstrap/devfs.c +++ b/lib/bootstrap/devfs.c @@ -99,7 +99,7 @@ void* bootstrap_read_devfs(char *devname, bool use_bb, int offset, bootstrap_err( "%s: failed to add bad block aware partition (%d)\n", devname, ret); - goto exit; + goto delete_devfs_partition; } partname = "bbx"; @@ -138,6 +138,14 @@ free_memory: free(header); if (!result) free(to); -exit: + + if (use_bb) { + dev_remove_bb_dev(partname); + partname = "x"; + } + +delete_devfs_partition: + devfs_del_partition(partname); + return result; } From 435aaf62799d029d1d6d6da643fdc01fc981feff Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 6 May 2015 12:32:13 -0700 Subject: [PATCH 18/20] bootstrap: Warn if image size in BB header is zero Signed-off-by: Andrey Smirnov Signed-off-by: Sascha Hauer --- lib/bootstrap/devfs.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/bootstrap/devfs.c b/lib/bootstrap/devfs.c index b6edec7e2..5a64477ee 100644 --- a/lib/bootstrap/devfs.c +++ b/lib/bootstrap/devfs.c @@ -58,8 +58,12 @@ static unsigned int get_image_size(void *head) unsigned int ret = 0; unsigned int *psize = head + BAREBOX_HEAD_SIZE_OFFSET; - if (is_barebox_head(head)) + if (is_barebox_head(head)) { ret = *psize; + if (!ret) + bootstrap_err( + "image has correct magic, but the length is zero\n"); + } debug("Detected barebox image size %u\n", ret); return ret; From a66596282413ddf9a438c36da97fa6050f1851e8 Mon Sep 17 00:00:00 2001 From: Markus Pargmann Date: Fri, 8 May 2015 10:49:14 +0200 Subject: [PATCH 19/20] imx6: lowlevel_init: Fix workaround for new i.MX6s chips This errata workaround was introduced for i.MX6Q, i.MX6D and i.MX6SL. Old revisions of i.MX6s chips had no problems with the PFD resets. In a newer i.MX6s revision I had issues with this code when booting in internal boot mode from NAND or in serial downloader mode. FUSE mode worked fine although it jumped directly to serial downloader mode. This patch executes the PFD workaround only for i.MX6Q and i.MX6D which fixes the issues I saw. Signed-off-by: Markus Pargmann Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/imx6.c | 46 +++++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/arch/arm/mach-imx/imx6.c b/arch/arm/mach-imx/imx6.c index 73630e709..7508964bf 100644 --- a/arch/arm/mach-imx/imx6.c +++ b/arch/arm/mach-imx/imx6.c @@ -30,7 +30,8 @@ void imx6_init_lowlevel(void) void __iomem *aips1 = (void *)MX6_AIPS1_ON_BASE_ADDR; void __iomem *aips2 = (void *)MX6_AIPS2_ON_BASE_ADDR; void __iomem *iomux = (void *)MX6_IOMUXC_BASE_ADDR; - int is_imx6q = __imx6_cpu_type() == IMX6_CPUTYPE_IMX6Q; + bool is_imx6q = __imx6_cpu_type() == IMX6_CPUTYPE_IMX6Q; + bool is_imx6d = __imx6_cpu_type() == IMX6_CPUTYPE_IMX6D; uint32_t val; /* @@ -67,28 +68,29 @@ void imx6_init_lowlevel(void) * not output clock after reset, MX6DL and MX6SL have added 396M pfd * workaround in ROM code, as bus clock need it */ - writel(BM_ANADIG_PFD_480_PFD3_CLKGATE | - BM_ANADIG_PFD_480_PFD2_CLKGATE | - BM_ANADIG_PFD_480_PFD1_CLKGATE | - BM_ANADIG_PFD_480_PFD0_CLKGATE, - MX6_ANATOP_BASE_ADDR + HW_ANADIG_PFD_480_SET); - writel(BM_ANADIG_PFD_528_PFD3_CLKGATE | - (is_imx6q ? BM_ANADIG_PFD_528_PFD2_CLKGATE : 0) | - BM_ANADIG_PFD_528_PFD1_CLKGATE | - BM_ANADIG_PFD_528_PFD0_CLKGATE, - MX6_ANATOP_BASE_ADDR + HW_ANADIG_PFD_528_SET); + if (is_imx6q || is_imx6d) { + writel(BM_ANADIG_PFD_480_PFD3_CLKGATE | + BM_ANADIG_PFD_480_PFD2_CLKGATE | + BM_ANADIG_PFD_480_PFD1_CLKGATE | + BM_ANADIG_PFD_480_PFD0_CLKGATE, + MX6_ANATOP_BASE_ADDR + HW_ANADIG_PFD_480_SET); + writel(BM_ANADIG_PFD_528_PFD3_CLKGATE | + (is_imx6q ? BM_ANADIG_PFD_528_PFD2_CLKGATE : 0) | + BM_ANADIG_PFD_528_PFD1_CLKGATE | + BM_ANADIG_PFD_528_PFD0_CLKGATE, + MX6_ANATOP_BASE_ADDR + HW_ANADIG_PFD_528_SET); - writel(BM_ANADIG_PFD_480_PFD3_CLKGATE | - BM_ANADIG_PFD_480_PFD2_CLKGATE | - BM_ANADIG_PFD_480_PFD1_CLKGATE | - BM_ANADIG_PFD_480_PFD0_CLKGATE, - MX6_ANATOP_BASE_ADDR + HW_ANADIG_PFD_480_CLR); - writel(BM_ANADIG_PFD_528_PFD3_CLKGATE | - (is_imx6q ? BM_ANADIG_PFD_528_PFD2_CLKGATE : 0) | - BM_ANADIG_PFD_528_PFD2_CLKGATE | - BM_ANADIG_PFD_528_PFD1_CLKGATE | - BM_ANADIG_PFD_528_PFD0_CLKGATE, - MX6_ANATOP_BASE_ADDR + HW_ANADIG_PFD_528_CLR); + writel(BM_ANADIG_PFD_480_PFD3_CLKGATE | + BM_ANADIG_PFD_480_PFD2_CLKGATE | + BM_ANADIG_PFD_480_PFD1_CLKGATE | + BM_ANADIG_PFD_480_PFD0_CLKGATE, + MX6_ANATOP_BASE_ADDR + HW_ANADIG_PFD_480_CLR); + writel(BM_ANADIG_PFD_528_PFD3_CLKGATE | + (is_imx6q ? BM_ANADIG_PFD_528_PFD2_CLKGATE : 0) | + BM_ANADIG_PFD_528_PFD1_CLKGATE | + BM_ANADIG_PFD_528_PFD0_CLKGATE, + MX6_ANATOP_BASE_ADDR + HW_ANADIG_PFD_528_CLR); + } val = readl(iomux + IOMUXC_GPR4); val |= IMX6Q_GPR4_VPU_WR_CACHE_SEL | IMX6Q_GPR4_VPU_RD_CACHE_SEL | From 7f9b96cd96332b7a569e21612d3b905b7691c637 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 13 May 2015 19:54:22 -0700 Subject: [PATCH 20/20] serial: i.MX: Write settings to a correct register Fix what looks like a copy and past error, where settings for USR1 register were being written to USR2. Signed-off-by: Andrey Smirnov Signed-off-by: Sascha Hauer --- drivers/serial/serial_imx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/serial/serial_imx.c b/drivers/serial/serial_imx.c index ed00a91b8..68b438b0b 100644 --- a/drivers/serial/serial_imx.c +++ b/drivers/serial/serial_imx.c @@ -113,10 +113,10 @@ static int imx_serial_init_port(struct console_device *cdev) writel(val, regs + USR2); /* Clear status flags */ - val = readl(regs + USR2); + val = readl(regs + USR1); val |= USR1_PARITYERR | USR1_RTSD | USR1_ESCF | USR1_FRAMERR | USR1_AIRINT | USR1_AWAKE; - writel(val, regs + USR2); + writel(val, regs + USR1); return 0; }