aboutsummaryrefslogtreecommitdiff
path: root/hw/ast-bmc
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2014-10-05 09:16:36 +1100
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2014-10-05 09:16:36 +1100
commitb33fd8dc893e2ea65ceef5dad2fa8173932443e5 (patch)
tree8fbf5bfd56914848ea0369f67fb4438916576ceb /hw/ast-bmc
parent5876e124399cc2e4961020f22b28bfc9abdae3bb (diff)
downloadskiboot-b33fd8dc893e2ea65ceef5dad2fa8173932443e5.zip
skiboot-b33fd8dc893e2ea65ceef5dad2fa8173932443e5.tar.gz
skiboot-b33fd8dc893e2ea65ceef5dad2fa8173932443e5.tar.bz2
plat/palmetto: Fix SIO UART vs UART setup and iBT setup
The AMI images use the virtual UART, not the SIO UART, so configuring the SIO the way we do is incorrect. Additionally, they don't configure the interrupts properly (bad polarity for VUART and bad number for iBT). This reworks the inits to fix that up: - All SIO interrupts are set to level low - Check if VUART is enabled. If yes, configure and use it (and disable SIO UART which hostboot might have left enabled). - Else, reconfigure VUART LPC address and IRQ properly - Configure iBT LPC address and IRQ properly Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'hw/ast-bmc')
-rw-r--r--hw/ast-bmc/ast-io.c110
1 files changed, 107 insertions, 3 deletions
diff --git a/hw/ast-bmc/ast-io.c b/hw/ast-bmc/ast-io.c
index e89bf7f..e8bad14 100644
--- a/hw/ast-bmc/ast-io.c
+++ b/hw/ast-bmc/ast-io.c
@@ -286,6 +286,53 @@ int ast_copy_from_ahb(void *dst, uint32_t reg, uint32_t len)
return -EINVAL;
}
+static void ast_setup_sio_irq_polarity(void)
+{
+ /* Send SuperIO password */
+ lpc_outb(0xa5, 0x2e);
+ lpc_outb(0xa5, 0x2e);
+
+ /* Select logical dev 2 */
+ bmc_sio_outb(0x02, 0x07);
+ bmc_sio_outb(0x01, 0x71); /* level low */
+
+ /* Select logical dev 3 */
+ bmc_sio_outb(0x03, 0x07);
+ bmc_sio_outb(0x01, 0x71); /* irq level low */
+
+ /* Select logical dev 4 */
+ bmc_sio_outb(0x04, 0x07);
+ bmc_sio_outb(0x01, 0x71); /* irq level low */
+
+ /* Select logical dev 5 */
+ bmc_sio_outb(0x05, 0x07);
+ bmc_sio_outb(0x01, 0x71); /* irq level low */
+ bmc_sio_outb(0x01, 0x73); /* irq level low */
+
+ /* Select logical dev 7 */
+ bmc_sio_outb(0x07, 0x07);
+ bmc_sio_outb(0x01, 0x71); /* irq level low */
+
+ /* Select logical dev d */
+ bmc_sio_outb(0x0b, 0x07);
+ bmc_sio_outb(0x01, 0x71); /* irq level low */
+
+ /* Select logical dev c */
+ bmc_sio_outb(0x0c, 0x07);
+ bmc_sio_outb(0x01, 0x71); /* irq level low */
+
+ /* Select logical dev d */
+ bmc_sio_outb(0x0d, 0x07);
+ bmc_sio_outb(0x01, 0x71); /* irq level low */
+
+ /* Select logical dev e */
+ bmc_sio_outb(0x0e, 0x07);
+ bmc_sio_outb(0x01, 0x71); /* irq level low */
+
+ /* Re-lock SuperIO */
+ lpc_outb(0xaa, 0x2e);
+}
+
void ast_io_init(void)
{
/* Initialize iLPC->AHB bridge */
@@ -295,10 +342,51 @@ void ast_io_init(void)
bmc_sio_ahb_writel(0x30000e00, LPC_HICR7);
bmc_sio_ahb_writel(0xfe0001ff, LPC_HICR8);
bmc_sio_ahb_writel(0x00000500, LPC_HICR6);
+
+ /* Configure all AIO interrupts to level low */
+ ast_setup_sio_irq_polarity();
+}
+
+void ast_setup_ibt(uint16_t io_base, uint8_t irq)
+{
+ uint32_t v;
+
+ v = bmc_sio_ahb_readl(LPC_iBTCR0);
+ v = v & ~(0xfffffc00u);
+ v = v | (((uint32_t)io_base) << 16);
+ v = v | (((uint32_t)irq) << 12);
+ bmc_sio_ahb_writel(v, LPC_iBTCR0);
+}
+
+bool ast_is_vuart1_enabled(void)
+{
+ uint32_t v;
+
+ v = bmc_sio_ahb_readl(VUART1_GCTRLA);
+ return !!(v & 1);
+}
+
+void ast_setup_vuart1(uint16_t io_base, uint8_t irq)
+{
+ uint32_t v;
+
+ /* IRQ level low */
+ v = bmc_sio_ahb_readl(VUART1_GCTRLA);
+ v = v & ~2u;
+ bmc_sio_ahb_writel(v, VUART1_GCTRLA);
+
+ /* IRQ number */
+ v = bmc_sio_ahb_readl(VUART1_GCTRLB);
+ v = (v & ~0xf0u) | (irq << 4);
+ bmc_sio_ahb_writel(v, VUART1_GCTRLB);
+
+ /* Address */
+ bmc_sio_ahb_writel(io_base & 0xff, VUART1_ADDRL);
+ bmc_sio_ahb_writel(io_base >> 8, VUART1_ADDRH);
}
-/* Setup SuperIO UART 1*/
-void ast_setup_uart1(uint16_t io_base, uint8_t irq)
+/* Setup SuperIO UART 1 */
+void ast_setup_sio_uart1(uint16_t io_base, uint8_t irq)
{
/* Send SuperIO password */
lpc_outb(0xa5, 0x2e);
@@ -308,7 +396,7 @@ void ast_setup_uart1(uint16_t io_base, uint8_t irq)
bmc_sio_outb(0x02, 0x07);
/* Disable UART1 for configuration */
- bmc_sio_outb(0x01, 0x30);
+ bmc_sio_outb(0x00, 0x30);
/* Configure base and interrupt */
bmc_sio_outb(io_base >> 8, 0x60);
@@ -322,3 +410,19 @@ void ast_setup_uart1(uint16_t io_base, uint8_t irq)
/* Re-lock SuperIO */
lpc_outb(0xaa, 0x2e);
}
+
+void ast_disable_sio_uart1(void)
+{
+ /* Send SuperIO password */
+ lpc_outb(0xa5, 0x2e);
+ lpc_outb(0xa5, 0x2e);
+
+ /* Select logical dev 2 */
+ bmc_sio_outb(0x02, 0x07);
+
+ /* Disable UART1 */
+ bmc_sio_outb(0x00, 0x30);
+
+ /* Re-lock SuperIO */
+ lpc_outb(0xaa, 0x2e);
+}