Parametrize baudrate and UART clock during console_init()

This patch adds baud rate and UART clock frequency as parameters
to the pl011 driver api console_init(). This allows each platform
to specify UART clock and baud rate according to their specific
hardware implementation.

Fixes ARM-software/tf-issues#215

Change-Id: Id13eef70a1c530e709b34dd1e6eb84db0797ced2
diff --git a/drivers/arm/pl011/pl011_console.S b/drivers/arm/pl011/pl011_console.S
index bf26b6b..5ff1582 100644
--- a/drivers/arm/pl011/pl011_console.S
+++ b/drivers/arm/pl011/pl011_console.S
@@ -47,53 +47,56 @@
 .section .data.console_base ; .align 3
 	console_base: .quad 0x0
 
-	/* ---------------------------------------------
-	 * int console_init(unsigned long base_addr)
+	/* -----------------------------------------------
+	 * int console_init(unsigned long base_addr,
+	 * unsigned int uart_clk, unsigned int baud_rate)
 	 * Function to initialize the console without a
 	 * C Runtime to print debug information. It saves
 	 * the console base to the data section.
 	 * In: x0 - console base address
+	 *     w1 - Uart clock in Hz
+	 *     w2 - Baud rate
 	 * out: return 1 on success.
-	 * Clobber list : x1, x2
-	 * ---------------------------------------------
+	 * Clobber list : x1 - x3
+	 * -----------------------------------------------
 	 */
 func console_init
-	adrp	x1, console_base
-	str	x0, [x1, :lo12:console_base]
+	adrp	x3, console_base
+	str	x0, [x3, :lo12:console_base]
 	b	console_core_init
 
-	/* ---------------------------------------------
-	 * int console_core_init(unsigned long base_addr)
+	/* -----------------------------------------------
+	 * int console_core_init(unsigned long base_addr,
+	 * unsigned int uart_clk, unsigned int baud_rate)
 	 * Function to initialize the console without a
 	 * C Runtime to print debug information. This
 	 * function will be accessed by console_init and
 	 * crash reporting.
 	 * In: x0 - console base address
+	 *     w1 - Uart clock in Hz
+	 *     w2 - Baud rate
 	 * Out: return 1 on success
 	 * Clobber list : x1, x2
-	 * ---------------------------------------------
+	 * -----------------------------------------------
 	 */
 func console_core_init
 	/* Check the input base address */
 	cbz	x0, init_fail
+	/* Check baud rate and uart clock for sanity */
+	cbz	w1, init_fail
+	cbz	w2, init_fail
 	/* Program the baudrate */
-#if defined(PL011_INTEGER) && defined(PL011_FRACTIONAL)
-	mov	w1, #PL011_INTEGER
-	str	w1, [x0, #UARTIBRD]
-	mov	w1, #PL011_FRACTIONAL
-	str	w1, [x0, #UARTFBRD]
-#else
-.set BRD, ((PL011_CLK_IN_HZ << 2) / PL011_BAUDRATE)
+	/* Divisor =  (Uart clock * 4) / baudrate */
+	lsl	w1, w1, #2
+	udiv	w2, w1, w2
+	/* IBRD = Divisor >> 6 */
+	lsr	w1, w2, #6
 	/* Write the IBRD */
-	mov	w1, #((BRD >> 6) & 0xffff)
-.if BRD>=0x400000
-	movk	w1, #(BRD >> 22), LSL #16
-.endif
 	str	w1, [x0, #UARTIBRD]
+	/* FBRD = Divisor & 0x3F */
+	and	w1, w2, #0x3f
 	/* Write the FBRD */
-	mov	w1, #(BRD & 0x3f)
 	str	w1, [x0, #UARTFBRD]
-#endif
 	mov	w1, #PL011_LINE_CONTROL
 	str	w1, [x0, #UARTLCR_H]
 	/* Clear any pending errors */
@@ -121,10 +124,10 @@
 	b	console_core_putc
 
 	/* --------------------------------------------------------
-	 * int console_core_putc(int c, unsigned long base_addr)
+	 * int console_core_putc(int c, unsigned int base_addr)
 	 * Function to output a character over the console. It
 	 * returns the character printed on success or -1 on error.
-	 * In : x0 - character to be printed
+	 * In : w0 - character to be printed
 	 *      x1 - console base address
 	 * Out : return -1 on error else return character.
 	 * Clobber list : x2
@@ -134,7 +137,7 @@
 	/* Check the input parameter */
 	cbz	x1, putc_error
 	/* Prepend '\r' to '\n' */
-	cmp	x0, #0xA
+	cmp	w0, #0xA
 	b.ne	2f
 1:
 	/* Check if the transmit FIFO is full */
diff --git a/include/drivers/arm/pl011.h b/include/drivers/arm/pl011.h
index e01d8b2..7c4df62 100644
--- a/include/drivers/arm/pl011.h
+++ b/include/drivers/arm/pl011.h
@@ -78,14 +78,6 @@
 #define PL011_UARTCR_LBE          (1 << 7)	/* Loopback enable */
 #define PL011_UARTCR_UARTEN       (1 << 0)	/* UART Enable */
 
-#if !defined(PL011_BAUDRATE)
-#define PL011_BAUDRATE  115200
-#endif
-
-#if !defined(PL011_CLK_IN_HZ)
-#define PL011_CLK_IN_HZ 24000000
-#endif
-
 #if !defined(PL011_LINE_CONTROL)
 /* FIFO Enabled / No Parity / 8 Data bit / One Stop Bit */
 #define PL011_LINE_CONTROL  (PL011_UARTLCR_H_FEN | PL011_UARTLCR_H_WLEN_8)
diff --git a/include/drivers/console.h b/include/drivers/console.h
index e285909..f144ab9 100644
--- a/include/drivers/console.h
+++ b/include/drivers/console.h
@@ -31,7 +31,8 @@
 #ifndef __CONSOLE_H__
 #define __CONSOLE_H__
 
-void console_init(unsigned long base_addr);
+int console_init(unsigned long base_addr,
+		unsigned int uart_clk, unsigned int baud_rate);
 int console_putc(int c);
 int console_getc(void);
 
diff --git a/plat/fvp/bl1_fvp_setup.c b/plat/fvp/bl1_fvp_setup.c
index bfd0f55..b146fdb 100644
--- a/plat/fvp/bl1_fvp_setup.c
+++ b/plat/fvp/bl1_fvp_setup.c
@@ -73,7 +73,7 @@
 	const size_t bl1_size = BL1_RAM_LIMIT - BL1_RAM_BASE;
 
 	/* Initialize the console to provide early debug support */
-	console_init(PL011_UART0_BASE);
+	console_init(PL011_UART0_BASE, PL011_UART0_CLK_IN_HZ, PL011_BAUDRATE);
 
 	/* Allow BL1 to see the whole Trusted RAM */
 	bl1_tzram_layout.total_base = TZRAM_BASE;
diff --git a/plat/fvp/bl2_fvp_setup.c b/plat/fvp/bl2_fvp_setup.c
index beba804..c0ad340 100644
--- a/plat/fvp/bl2_fvp_setup.c
+++ b/plat/fvp/bl2_fvp_setup.c
@@ -168,7 +168,7 @@
 void bl2_early_platform_setup(meminfo_t *mem_layout)
 {
 	/* Initialize the console to provide early debug support */
-	console_init(PL011_UART0_BASE);
+	console_init(PL011_UART0_BASE, PL011_UART0_CLK_IN_HZ, PL011_BAUDRATE);
 
 	/* Setup the BL2 memory layout */
 	bl2_tzram_layout = *mem_layout;
diff --git a/plat/fvp/bl31_fvp_setup.c b/plat/fvp/bl31_fvp_setup.c
index 96f4772..ca72aa9 100644
--- a/plat/fvp/bl31_fvp_setup.c
+++ b/plat/fvp/bl31_fvp_setup.c
@@ -143,7 +143,7 @@
 				void *plat_params_from_bl2)
 {
 	/* Initialize the console to provide early debug support */
-	console_init(PL011_UART0_BASE);
+	console_init(PL011_UART0_BASE, PL011_UART0_CLK_IN_HZ, PL011_BAUDRATE);
 
 	/* Initialize the platform config for future decision making */
 	fvp_config_setup();
diff --git a/plat/fvp/bl32_fvp_setup.c b/plat/fvp/bl32_fvp_setup.c
index 901c585..aa49ff3 100644
--- a/plat/fvp/bl32_fvp_setup.c
+++ b/plat/fvp/bl32_fvp_setup.c
@@ -72,7 +72,7 @@
 	 * Initialize a different console than already in use to display
 	 * messages from TSP
 	 */
-	console_init(PL011_UART1_BASE);
+	console_init(PL011_UART1_BASE, PL011_UART1_CLK_IN_HZ, PL011_BAUDRATE);
 
 	/* Initialize the platform config for future decision making */
 	fvp_config_setup();
diff --git a/plat/fvp/fvp_def.h b/plat/fvp/fvp_def.h
index 89c8b02..21edb3b 100644
--- a/plat/fvp/fvp_def.h
+++ b/plat/fvp/fvp_def.h
@@ -198,6 +198,13 @@
 #define PL011_UART2_BASE		0x1c0b0000
 #define PL011_UART3_BASE		0x1c0c0000
 
+#define PL011_BAUDRATE  115200
+
+#define PL011_UART0_CLK_IN_HZ 24000000
+#define PL011_UART1_CLK_IN_HZ 24000000
+#define PL011_UART2_CLK_IN_HZ 24000000
+#define PL011_UART3_CLK_IN_HZ 24000000
+
 /*******************************************************************************
  * TrustZone address space controller related constants
  ******************************************************************************/