1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2011 by Vladimir Zapolskiy <vz@mleia.com> 4 */ 5 6 #include <common.h> 7 #include <dm.h> 8 #include <ns16550.h> 9 #include <dm/platform_data/lpc32xx_hsuart.h> 10 11 #include <asm/arch/clk.h> 12 #include <asm/arch/uart.h> 13 #include <asm/arch/mux.h> 14 #include <asm/io.h> 15 16 static struct clk_pm_regs *clk = (struct clk_pm_regs *)CLK_PM_BASE; 17 static struct uart_ctrl_regs *ctrl = (struct uart_ctrl_regs *)UART_CTRL_BASE; 18 static struct mux_regs *mux = (struct mux_regs *)MUX_BASE; 19 20 void lpc32xx_uart_init(unsigned int uart_id) 21 { 22 if (uart_id < 1 || uart_id > 7) 23 return; 24 25 /* Disable loopback mode, if it is set by S1L bootloader */ 26 clrbits_le32(&ctrl->loop, 27 UART_LOOPBACK(CONFIG_SYS_LPC32XX_UART)); 28 29 if (uart_id < 3 || uart_id > 6) 30 return; 31 32 /* Enable UART system clock */ 33 setbits_le32(&clk->uartclk_ctrl, CLK_UART(uart_id)); 34 35 /* Set UART into autoclock mode */ 36 clrsetbits_le32(&ctrl->clkmode, 37 UART_CLKMODE_MASK(uart_id), 38 UART_CLKMODE_AUTO(uart_id)); 39 40 /* Bypass pre-divider of UART clock */ 41 writel(CLK_UART_X_DIV(1) | CLK_UART_Y_DIV(1), 42 &clk->u3clk + (uart_id - 3)); 43 } 44 45 #if !CONFIG_IS_ENABLED(OF_CONTROL) 46 static const struct ns16550_platdata lpc32xx_uart[] = { 47 { .base = UART3_BASE, .reg_shift = 2, 48 .clock = CONFIG_SYS_NS16550_CLK, .fcr = UART_FCR_DEFVAL, }, 49 { .base = UART4_BASE, .reg_shift = 2, 50 .clock = CONFIG_SYS_NS16550_CLK, .fcr = UART_FCR_DEFVAL, }, 51 { .base = UART5_BASE, .reg_shift = 2, 52 .clock = CONFIG_SYS_NS16550_CLK, .fcr = UART_FCR_DEFVAL, }, 53 { .base = UART6_BASE, .reg_shift = 2, 54 .clock = CONFIG_SYS_NS16550_CLK, .fcr = UART_FCR_DEFVAL, }, 55 }; 56 57 #if defined(CONFIG_LPC32XX_HSUART) 58 static const struct lpc32xx_hsuart_platdata lpc32xx_hsuart[] = { 59 { HS_UART1_BASE, }, 60 { HS_UART2_BASE, }, 61 { HS_UART7_BASE, }, 62 }; 63 #endif 64 65 U_BOOT_DEVICES(lpc32xx_uarts) = { 66 #if defined(CONFIG_LPC32XX_HSUART) 67 { "lpc32xx_hsuart", &lpc32xx_hsuart[0], }, 68 { "lpc32xx_hsuart", &lpc32xx_hsuart[1], }, 69 #endif 70 { "ns16550_serial", &lpc32xx_uart[0], }, 71 { "ns16550_serial", &lpc32xx_uart[1], }, 72 { "ns16550_serial", &lpc32xx_uart[2], }, 73 { "ns16550_serial", &lpc32xx_uart[3], }, 74 #if defined(CONFIG_LPC32XX_HSUART) 75 { "lpc32xx_hsuart", &lpc32xx_hsuart[2], }, 76 #endif 77 }; 78 #endif 79 80 void lpc32xx_dma_init(void) 81 { 82 /* Enable DMA interface */ 83 writel(CLK_DMA_ENABLE, &clk->dmaclk_ctrl); 84 } 85 86 void lpc32xx_mac_init(void) 87 { 88 /* Enable MAC interface */ 89 writel(CLK_MAC_REG | CLK_MAC_SLAVE | CLK_MAC_MASTER 90 #if defined(CONFIG_RMII) 91 | CLK_MAC_RMII, 92 #else 93 | CLK_MAC_MII, 94 #endif 95 &clk->macclk_ctrl); 96 } 97 98 void lpc32xx_mlc_nand_init(void) 99 { 100 /* Enable NAND interface */ 101 writel(CLK_NAND_MLC | CLK_NAND_MLC_INT, &clk->flashclk_ctrl); 102 } 103 104 void lpc32xx_slc_nand_init(void) 105 { 106 /* Enable SLC NAND interface */ 107 writel(CLK_NAND_SLC | CLK_NAND_SLC_SELECT, &clk->flashclk_ctrl); 108 } 109 110 void lpc32xx_usb_init(void) 111 { 112 /* Do not route the UART 5 Tx/Rx pins to the USB D+ and USB D- pins. */ 113 clrbits_le32(&ctrl->ctrl, UART_CTRL_UART5_USB_MODE); 114 } 115 116 void lpc32xx_i2c_init(unsigned int devnum) 117 { 118 /* Enable I2C interface */ 119 uint32_t ctrl = readl(&clk->i2cclk_ctrl); 120 if (devnum == 1) 121 ctrl |= CLK_I2C1_ENABLE; 122 if (devnum == 2) 123 ctrl |= CLK_I2C2_ENABLE; 124 writel(ctrl, &clk->i2cclk_ctrl); 125 } 126 127 U_BOOT_DEVICE(lpc32xx_gpios) = { 128 .name = "gpio_lpc32xx" 129 }; 130 131 /* Mux for SCK0, MISO0, MOSI0. We do not use SSEL0. */ 132 133 #define P_MUX_SET_SSP0 0x1600 134 135 void lpc32xx_ssp_init(void) 136 { 137 /* Enable SSP0 interface */ 138 writel(CLK_SSP0_ENABLE_CLOCK, &clk->ssp_ctrl); 139 /* Mux SSP0 pins */ 140 writel(P_MUX_SET_SSP0, &mux->p_mux_set); 141 } 142