diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2014-10-05 09:16:36 +1100 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2014-10-05 09:16:36 +1100 |
commit | b33fd8dc893e2ea65ceef5dad2fa8173932443e5 (patch) | |
tree | 8fbf5bfd56914848ea0369f67fb4438916576ceb /hw/ast-bmc | |
parent | 5876e124399cc2e4961020f22b28bfc9abdae3bb (diff) | |
download | skiboot-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.c | 110 |
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); +} |