15fff610bSJohn Crispin /* 25fff610bSJohn Crispin * This program is free software; you can redistribute it and/or modify it 35fff610bSJohn Crispin * under the terms of the GNU General Public License version 2 as published 45fff610bSJohn Crispin * by the Free Software Foundation. 55fff610bSJohn Crispin * 65fff610bSJohn Crispin * Copyright (C) 2011-2012 Gabor Juhos <juhosg@openwrt.org> 75fff610bSJohn Crispin */ 85fff610bSJohn Crispin 95fff610bSJohn Crispin #include <linux/io.h> 105fff610bSJohn Crispin #include <linux/serial_reg.h> 115fff610bSJohn Crispin 125fff610bSJohn Crispin #include <asm/addrspace.h> 135c93316cSAlexander Sverdlin #include <asm/setup.h> 145fff610bSJohn Crispin 155b4500d1SJohn Crispin #ifdef CONFIG_SOC_RT288X 165b4500d1SJohn Crispin #define EARLY_UART_BASE 0x300c00 17a097b13cSJohn Crispin #define CHIPID_BASE 0x300004 18a097b13cSJohn Crispin #elif defined(CONFIG_SOC_MT7621) 19a097b13cSJohn Crispin #define EARLY_UART_BASE 0x1E000c00 20a097b13cSJohn Crispin #define CHIPID_BASE 0x1E000004 215b4500d1SJohn Crispin #else 225fff610bSJohn Crispin #define EARLY_UART_BASE 0x10000c00 23a097b13cSJohn Crispin #define CHIPID_BASE 0x10000004 245b4500d1SJohn Crispin #endif 255fff610bSJohn Crispin 26a097b13cSJohn Crispin #define MT7628_CHIP_NAME1 0x20203832 27a097b13cSJohn Crispin 285fff610bSJohn Crispin #define UART_REG_TX 0x04 2973afa6c4SJohn Crispin #define UART_REG_LCR 0x0c 30a097b13cSJohn Crispin #define UART_REG_LSR 0x14 31a097b13cSJohn Crispin #define UART_REG_LSR_RT2880 0x1c 325fff610bSJohn Crispin 335fff610bSJohn Crispin static __iomem void *uart_membase = (__iomem void *) KSEG1ADDR(EARLY_UART_BASE); 34a097b13cSJohn Crispin static __iomem void *chipid_membase = (__iomem void *) KSEG1ADDR(CHIPID_BASE); 3573afa6c4SJohn Crispin static int init_complete; 365fff610bSJohn Crispin 375fff610bSJohn Crispin static inline void uart_w32(u32 val, unsigned reg) 385fff610bSJohn Crispin { 395fff610bSJohn Crispin __raw_writel(val, uart_membase + reg); 405fff610bSJohn Crispin } 415fff610bSJohn Crispin 425fff610bSJohn Crispin static inline u32 uart_r32(unsigned reg) 435fff610bSJohn Crispin { 445fff610bSJohn Crispin return __raw_readl(uart_membase + reg); 455fff610bSJohn Crispin } 465fff610bSJohn Crispin 47a097b13cSJohn Crispin static inline int soc_is_mt7628(void) 48a097b13cSJohn Crispin { 49a097b13cSJohn Crispin return IS_ENABLED(CONFIG_SOC_MT7620) && 50a097b13cSJohn Crispin (__raw_readl(chipid_membase) == MT7628_CHIP_NAME1); 51a097b13cSJohn Crispin } 52a097b13cSJohn Crispin 5373afa6c4SJohn Crispin static void find_uart_base(void) 5473afa6c4SJohn Crispin { 5573afa6c4SJohn Crispin int i; 5673afa6c4SJohn Crispin 5773afa6c4SJohn Crispin if (!soc_is_mt7628()) 5873afa6c4SJohn Crispin return; 5973afa6c4SJohn Crispin 6073afa6c4SJohn Crispin for (i = 0; i < 3; i++) { 6173afa6c4SJohn Crispin u32 reg = uart_r32(UART_REG_LCR + (0x100 * i)); 6273afa6c4SJohn Crispin 6373afa6c4SJohn Crispin if (!reg) 6473afa6c4SJohn Crispin continue; 6573afa6c4SJohn Crispin 6673afa6c4SJohn Crispin uart_membase = (__iomem void *) KSEG1ADDR(EARLY_UART_BASE + 6773afa6c4SJohn Crispin (0x100 * i)); 6873afa6c4SJohn Crispin break; 6973afa6c4SJohn Crispin } 7073afa6c4SJohn Crispin } 7173afa6c4SJohn Crispin 725c93316cSAlexander Sverdlin void prom_putchar(char ch) 735fff610bSJohn Crispin { 7473afa6c4SJohn Crispin if (!init_complete) { 7573afa6c4SJohn Crispin find_uart_base(); 7673afa6c4SJohn Crispin init_complete = 1; 7773afa6c4SJohn Crispin } 7873afa6c4SJohn Crispin 79a097b13cSJohn Crispin if (IS_ENABLED(CONFIG_SOC_MT7621) || soc_is_mt7628()) { 805c93316cSAlexander Sverdlin uart_w32((unsigned char)ch, UART_TX); 815fff610bSJohn Crispin while ((uart_r32(UART_REG_LSR) & UART_LSR_THRE) == 0) 825fff610bSJohn Crispin ; 83a097b13cSJohn Crispin } else { 84a097b13cSJohn Crispin while ((uart_r32(UART_REG_LSR_RT2880) & UART_LSR_THRE) == 0) 85a097b13cSJohn Crispin ; 865c93316cSAlexander Sverdlin uart_w32((unsigned char)ch, UART_REG_TX); 87a097b13cSJohn Crispin while ((uart_r32(UART_REG_LSR_RT2880) & UART_LSR_THRE) == 0) 885fff610bSJohn Crispin ; 895fff610bSJohn Crispin } 90a097b13cSJohn Crispin } 91