18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Alchemy Db1550/Pb1550 board support 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * (c) 2011 Manuel Lauss <manuel.lauss@googlemail.com> 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#include <linux/clk.h> 98c2ecf20Sopenharmony_ci#include <linux/dma-mapping.h> 108c2ecf20Sopenharmony_ci#include <linux/gpio.h> 118c2ecf20Sopenharmony_ci#include <linux/i2c.h> 128c2ecf20Sopenharmony_ci#include <linux/init.h> 138c2ecf20Sopenharmony_ci#include <linux/io.h> 148c2ecf20Sopenharmony_ci#include <linux/interrupt.h> 158c2ecf20Sopenharmony_ci#include <linux/mtd/mtd.h> 168c2ecf20Sopenharmony_ci#include <linux/mtd/platnand.h> 178c2ecf20Sopenharmony_ci#include <linux/platform_device.h> 188c2ecf20Sopenharmony_ci#include <linux/pm.h> 198c2ecf20Sopenharmony_ci#include <linux/spi/spi.h> 208c2ecf20Sopenharmony_ci#include <linux/spi/flash.h> 218c2ecf20Sopenharmony_ci#include <asm/bootinfo.h> 228c2ecf20Sopenharmony_ci#include <asm/mach-au1x00/au1000.h> 238c2ecf20Sopenharmony_ci#include <asm/mach-au1x00/gpio-au1000.h> 248c2ecf20Sopenharmony_ci#include <asm/mach-au1x00/au1xxx_eth.h> 258c2ecf20Sopenharmony_ci#include <asm/mach-au1x00/au1xxx_dbdma.h> 268c2ecf20Sopenharmony_ci#include <asm/mach-au1x00/au1xxx_psc.h> 278c2ecf20Sopenharmony_ci#include <asm/mach-au1x00/au1550_spi.h> 288c2ecf20Sopenharmony_ci#include <asm/mach-au1x00/au1550nd.h> 298c2ecf20Sopenharmony_ci#include <asm/mach-db1x00/bcsr.h> 308c2ecf20Sopenharmony_ci#include <prom.h> 318c2ecf20Sopenharmony_ci#include "platform.h" 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_cistatic void __init db1550_hw_setup(void) 348c2ecf20Sopenharmony_ci{ 358c2ecf20Sopenharmony_ci void __iomem *base; 368c2ecf20Sopenharmony_ci unsigned long v; 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_ci /* complete pin setup: assign GPIO16 to PSC0_SYNC1 (SPI cs# line) 398c2ecf20Sopenharmony_ci * as well as PSC1_SYNC for AC97 on PB1550. 408c2ecf20Sopenharmony_ci */ 418c2ecf20Sopenharmony_ci v = alchemy_rdsys(AU1000_SYS_PINFUNC); 428c2ecf20Sopenharmony_ci alchemy_wrsys(v | 1 | SYS_PF_PSC1_S1, AU1000_SYS_PINFUNC); 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci /* reset the AC97 codec now, the reset time in the psc-ac97 driver 458c2ecf20Sopenharmony_ci * is apparently too short although it's ridiculous as it is. 468c2ecf20Sopenharmony_ci */ 478c2ecf20Sopenharmony_ci base = (void __iomem *)KSEG1ADDR(AU1550_PSC1_PHYS_ADDR); 488c2ecf20Sopenharmony_ci __raw_writel(PSC_SEL_CLK_SERCLK | PSC_SEL_PS_AC97MODE, 498c2ecf20Sopenharmony_ci base + PSC_SEL_OFFSET); 508c2ecf20Sopenharmony_ci __raw_writel(PSC_CTRL_DISABLE, base + PSC_CTRL_OFFSET); 518c2ecf20Sopenharmony_ci wmb(); 528c2ecf20Sopenharmony_ci __raw_writel(PSC_AC97RST_RST, base + PSC_AC97RST_OFFSET); 538c2ecf20Sopenharmony_ci wmb(); 548c2ecf20Sopenharmony_ci} 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ciint __init db1550_board_setup(void) 578c2ecf20Sopenharmony_ci{ 588c2ecf20Sopenharmony_ci unsigned short whoami; 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_ci bcsr_init(DB1550_BCSR_PHYS_ADDR, 618c2ecf20Sopenharmony_ci DB1550_BCSR_PHYS_ADDR + DB1550_BCSR_HEXLED_OFS); 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_ci whoami = bcsr_read(BCSR_WHOAMI); /* PB1550 hexled offset differs */ 648c2ecf20Sopenharmony_ci switch (BCSR_WHOAMI_BOARD(whoami)) { 658c2ecf20Sopenharmony_ci case BCSR_WHOAMI_PB1550_SDR: 668c2ecf20Sopenharmony_ci case BCSR_WHOAMI_PB1550_DDR: 678c2ecf20Sopenharmony_ci bcsr_init(PB1550_BCSR_PHYS_ADDR, 688c2ecf20Sopenharmony_ci PB1550_BCSR_PHYS_ADDR + PB1550_BCSR_HEXLED_OFS); 698c2ecf20Sopenharmony_ci case BCSR_WHOAMI_DB1550: 708c2ecf20Sopenharmony_ci break; 718c2ecf20Sopenharmony_ci default: 728c2ecf20Sopenharmony_ci return -ENODEV; 738c2ecf20Sopenharmony_ci } 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_ci pr_info("Alchemy/AMD %s Board, CPLD Rev %d Board-ID %d " \ 768c2ecf20Sopenharmony_ci "Daughtercard ID %d\n", get_system_type(), 778c2ecf20Sopenharmony_ci (whoami >> 4) & 0xf, (whoami >> 8) & 0xf, whoami & 0xf); 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_ci db1550_hw_setup(); 808c2ecf20Sopenharmony_ci return 0; 818c2ecf20Sopenharmony_ci} 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_ci/*****************************************************************************/ 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_cistatic u64 au1550_all_dmamask = DMA_BIT_MASK(32); 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_cistatic struct mtd_partition db1550_spiflash_parts[] = { 888c2ecf20Sopenharmony_ci { 898c2ecf20Sopenharmony_ci .name = "spi_flash", 908c2ecf20Sopenharmony_ci .offset = 0, 918c2ecf20Sopenharmony_ci .size = MTDPART_SIZ_FULL, 928c2ecf20Sopenharmony_ci }, 938c2ecf20Sopenharmony_ci}; 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_cistatic struct flash_platform_data db1550_spiflash_data = { 968c2ecf20Sopenharmony_ci .name = "s25fl010", 978c2ecf20Sopenharmony_ci .parts = db1550_spiflash_parts, 988c2ecf20Sopenharmony_ci .nr_parts = ARRAY_SIZE(db1550_spiflash_parts), 998c2ecf20Sopenharmony_ci .type = "m25p10", 1008c2ecf20Sopenharmony_ci}; 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_cistatic struct spi_board_info db1550_spi_devs[] __initdata = { 1038c2ecf20Sopenharmony_ci { 1048c2ecf20Sopenharmony_ci /* TI TMP121AIDBVR temp sensor */ 1058c2ecf20Sopenharmony_ci .modalias = "tmp121", 1068c2ecf20Sopenharmony_ci .max_speed_hz = 2400000, 1078c2ecf20Sopenharmony_ci .bus_num = 0, 1088c2ecf20Sopenharmony_ci .chip_select = 0, 1098c2ecf20Sopenharmony_ci .mode = SPI_MODE_0, 1108c2ecf20Sopenharmony_ci }, 1118c2ecf20Sopenharmony_ci { 1128c2ecf20Sopenharmony_ci /* Spansion S25FL001D0FMA SPI flash */ 1138c2ecf20Sopenharmony_ci .modalias = "m25p80", 1148c2ecf20Sopenharmony_ci .max_speed_hz = 2400000, 1158c2ecf20Sopenharmony_ci .bus_num = 0, 1168c2ecf20Sopenharmony_ci .chip_select = 1, 1178c2ecf20Sopenharmony_ci .mode = SPI_MODE_0, 1188c2ecf20Sopenharmony_ci .platform_data = &db1550_spiflash_data, 1198c2ecf20Sopenharmony_ci }, 1208c2ecf20Sopenharmony_ci}; 1218c2ecf20Sopenharmony_ci 1228c2ecf20Sopenharmony_cistatic struct i2c_board_info db1550_i2c_devs[] __initdata = { 1238c2ecf20Sopenharmony_ci { I2C_BOARD_INFO("24c04", 0x52),}, /* AT24C04-10 I2C eeprom */ 1248c2ecf20Sopenharmony_ci { I2C_BOARD_INFO("ne1619", 0x2d),}, /* adm1025-compat hwmon */ 1258c2ecf20Sopenharmony_ci { I2C_BOARD_INFO("wm8731", 0x1b),}, /* I2S audio codec WM8731 */ 1268c2ecf20Sopenharmony_ci}; 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_ci/**********************************************************************/ 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_cistatic void au1550_nand_cmd_ctrl(struct nand_chip *this, int cmd, 1318c2ecf20Sopenharmony_ci unsigned int ctrl) 1328c2ecf20Sopenharmony_ci{ 1338c2ecf20Sopenharmony_ci unsigned long ioaddr = (unsigned long)this->legacy.IO_ADDR_W; 1348c2ecf20Sopenharmony_ci 1358c2ecf20Sopenharmony_ci ioaddr &= 0xffffff00; 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_ci if (ctrl & NAND_CLE) { 1388c2ecf20Sopenharmony_ci ioaddr += MEM_STNAND_CMD; 1398c2ecf20Sopenharmony_ci } else if (ctrl & NAND_ALE) { 1408c2ecf20Sopenharmony_ci ioaddr += MEM_STNAND_ADDR; 1418c2ecf20Sopenharmony_ci } else { 1428c2ecf20Sopenharmony_ci /* assume we want to r/w real data by default */ 1438c2ecf20Sopenharmony_ci ioaddr += MEM_STNAND_DATA; 1448c2ecf20Sopenharmony_ci } 1458c2ecf20Sopenharmony_ci this->legacy.IO_ADDR_R = this->legacy.IO_ADDR_W = (void __iomem *)ioaddr; 1468c2ecf20Sopenharmony_ci if (cmd != NAND_CMD_NONE) { 1478c2ecf20Sopenharmony_ci __raw_writeb(cmd, this->legacy.IO_ADDR_W); 1488c2ecf20Sopenharmony_ci wmb(); 1498c2ecf20Sopenharmony_ci } 1508c2ecf20Sopenharmony_ci} 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_cistatic int au1550_nand_device_ready(struct nand_chip *this) 1538c2ecf20Sopenharmony_ci{ 1548c2ecf20Sopenharmony_ci return alchemy_rdsmem(AU1000_MEM_STSTAT) & 1; 1558c2ecf20Sopenharmony_ci} 1568c2ecf20Sopenharmony_ci 1578c2ecf20Sopenharmony_cistatic struct mtd_partition db1550_nand_parts[] = { 1588c2ecf20Sopenharmony_ci { 1598c2ecf20Sopenharmony_ci .name = "NAND FS 0", 1608c2ecf20Sopenharmony_ci .offset = 0, 1618c2ecf20Sopenharmony_ci .size = 8 * 1024 * 1024, 1628c2ecf20Sopenharmony_ci }, 1638c2ecf20Sopenharmony_ci { 1648c2ecf20Sopenharmony_ci .name = "NAND FS 1", 1658c2ecf20Sopenharmony_ci .offset = MTDPART_OFS_APPEND, 1668c2ecf20Sopenharmony_ci .size = MTDPART_SIZ_FULL 1678c2ecf20Sopenharmony_ci }, 1688c2ecf20Sopenharmony_ci}; 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_cistruct platform_nand_data db1550_nand_platdata = { 1718c2ecf20Sopenharmony_ci .chip = { 1728c2ecf20Sopenharmony_ci .nr_chips = 1, 1738c2ecf20Sopenharmony_ci .chip_offset = 0, 1748c2ecf20Sopenharmony_ci .nr_partitions = ARRAY_SIZE(db1550_nand_parts), 1758c2ecf20Sopenharmony_ci .partitions = db1550_nand_parts, 1768c2ecf20Sopenharmony_ci .chip_delay = 20, 1778c2ecf20Sopenharmony_ci }, 1788c2ecf20Sopenharmony_ci .ctrl = { 1798c2ecf20Sopenharmony_ci .dev_ready = au1550_nand_device_ready, 1808c2ecf20Sopenharmony_ci .cmd_ctrl = au1550_nand_cmd_ctrl, 1818c2ecf20Sopenharmony_ci }, 1828c2ecf20Sopenharmony_ci}; 1838c2ecf20Sopenharmony_ci 1848c2ecf20Sopenharmony_cistatic struct resource db1550_nand_res[] = { 1858c2ecf20Sopenharmony_ci [0] = { 1868c2ecf20Sopenharmony_ci .start = 0x20000000, 1878c2ecf20Sopenharmony_ci .end = 0x200000ff, 1888c2ecf20Sopenharmony_ci .flags = IORESOURCE_MEM, 1898c2ecf20Sopenharmony_ci }, 1908c2ecf20Sopenharmony_ci}; 1918c2ecf20Sopenharmony_ci 1928c2ecf20Sopenharmony_cistatic struct platform_device db1550_nand_dev = { 1938c2ecf20Sopenharmony_ci .name = "gen_nand", 1948c2ecf20Sopenharmony_ci .num_resources = ARRAY_SIZE(db1550_nand_res), 1958c2ecf20Sopenharmony_ci .resource = db1550_nand_res, 1968c2ecf20Sopenharmony_ci .id = -1, 1978c2ecf20Sopenharmony_ci .dev = { 1988c2ecf20Sopenharmony_ci .platform_data = &db1550_nand_platdata, 1998c2ecf20Sopenharmony_ci } 2008c2ecf20Sopenharmony_ci}; 2018c2ecf20Sopenharmony_ci 2028c2ecf20Sopenharmony_cistatic struct au1550nd_platdata pb1550_nand_pd = { 2038c2ecf20Sopenharmony_ci .parts = db1550_nand_parts, 2048c2ecf20Sopenharmony_ci .num_parts = ARRAY_SIZE(db1550_nand_parts), 2058c2ecf20Sopenharmony_ci .devwidth = 0, /* x8 NAND default, needs fixing up */ 2068c2ecf20Sopenharmony_ci}; 2078c2ecf20Sopenharmony_ci 2088c2ecf20Sopenharmony_cistatic struct platform_device pb1550_nand_dev = { 2098c2ecf20Sopenharmony_ci .name = "au1550-nand", 2108c2ecf20Sopenharmony_ci .id = -1, 2118c2ecf20Sopenharmony_ci .resource = db1550_nand_res, 2128c2ecf20Sopenharmony_ci .num_resources = ARRAY_SIZE(db1550_nand_res), 2138c2ecf20Sopenharmony_ci .dev = { 2148c2ecf20Sopenharmony_ci .platform_data = &pb1550_nand_pd, 2158c2ecf20Sopenharmony_ci }, 2168c2ecf20Sopenharmony_ci}; 2178c2ecf20Sopenharmony_ci 2188c2ecf20Sopenharmony_cistatic void __init pb1550_nand_setup(void) 2198c2ecf20Sopenharmony_ci{ 2208c2ecf20Sopenharmony_ci int boot_swapboot = (alchemy_rdsmem(AU1000_MEM_STSTAT) & (0x7 << 1)) | 2218c2ecf20Sopenharmony_ci ((bcsr_read(BCSR_STATUS) >> 6) & 0x1); 2228c2ecf20Sopenharmony_ci 2238c2ecf20Sopenharmony_ci gpio_direction_input(206); /* de-assert NAND CS# */ 2248c2ecf20Sopenharmony_ci switch (boot_swapboot) { 2258c2ecf20Sopenharmony_ci case 0: case 2: case 8: case 0xC: case 0xD: 2268c2ecf20Sopenharmony_ci /* x16 NAND Flash */ 2278c2ecf20Sopenharmony_ci pb1550_nand_pd.devwidth = 1; 2288c2ecf20Sopenharmony_ci fallthrough; 2298c2ecf20Sopenharmony_ci case 1: case 3: case 9: case 0xE: case 0xF: 2308c2ecf20Sopenharmony_ci /* x8 NAND, already set up */ 2318c2ecf20Sopenharmony_ci platform_device_register(&pb1550_nand_dev); 2328c2ecf20Sopenharmony_ci } 2338c2ecf20Sopenharmony_ci} 2348c2ecf20Sopenharmony_ci 2358c2ecf20Sopenharmony_ci/**********************************************************************/ 2368c2ecf20Sopenharmony_ci 2378c2ecf20Sopenharmony_cistatic struct resource au1550_psc0_res[] = { 2388c2ecf20Sopenharmony_ci [0] = { 2398c2ecf20Sopenharmony_ci .start = AU1550_PSC0_PHYS_ADDR, 2408c2ecf20Sopenharmony_ci .end = AU1550_PSC0_PHYS_ADDR + 0xfff, 2418c2ecf20Sopenharmony_ci .flags = IORESOURCE_MEM, 2428c2ecf20Sopenharmony_ci }, 2438c2ecf20Sopenharmony_ci [1] = { 2448c2ecf20Sopenharmony_ci .start = AU1550_PSC0_INT, 2458c2ecf20Sopenharmony_ci .end = AU1550_PSC0_INT, 2468c2ecf20Sopenharmony_ci .flags = IORESOURCE_IRQ, 2478c2ecf20Sopenharmony_ci }, 2488c2ecf20Sopenharmony_ci [2] = { 2498c2ecf20Sopenharmony_ci .start = AU1550_DSCR_CMD0_PSC0_TX, 2508c2ecf20Sopenharmony_ci .end = AU1550_DSCR_CMD0_PSC0_TX, 2518c2ecf20Sopenharmony_ci .flags = IORESOURCE_DMA, 2528c2ecf20Sopenharmony_ci }, 2538c2ecf20Sopenharmony_ci [3] = { 2548c2ecf20Sopenharmony_ci .start = AU1550_DSCR_CMD0_PSC0_RX, 2558c2ecf20Sopenharmony_ci .end = AU1550_DSCR_CMD0_PSC0_RX, 2568c2ecf20Sopenharmony_ci .flags = IORESOURCE_DMA, 2578c2ecf20Sopenharmony_ci }, 2588c2ecf20Sopenharmony_ci}; 2598c2ecf20Sopenharmony_ci 2608c2ecf20Sopenharmony_cistatic void db1550_spi_cs_en(struct au1550_spi_info *spi, int cs, int pol) 2618c2ecf20Sopenharmony_ci{ 2628c2ecf20Sopenharmony_ci if (cs) 2638c2ecf20Sopenharmony_ci bcsr_mod(BCSR_BOARD, 0, BCSR_BOARD_SPISEL); 2648c2ecf20Sopenharmony_ci else 2658c2ecf20Sopenharmony_ci bcsr_mod(BCSR_BOARD, BCSR_BOARD_SPISEL, 0); 2668c2ecf20Sopenharmony_ci} 2678c2ecf20Sopenharmony_ci 2688c2ecf20Sopenharmony_cistatic struct au1550_spi_info db1550_spi_platdata = { 2698c2ecf20Sopenharmony_ci .mainclk_hz = 48000000, /* PSC0 clock: max. 2.4MHz SPI clk */ 2708c2ecf20Sopenharmony_ci .num_chipselect = 2, 2718c2ecf20Sopenharmony_ci .activate_cs = db1550_spi_cs_en, 2728c2ecf20Sopenharmony_ci}; 2738c2ecf20Sopenharmony_ci 2748c2ecf20Sopenharmony_ci 2758c2ecf20Sopenharmony_cistatic struct platform_device db1550_spi_dev = { 2768c2ecf20Sopenharmony_ci .dev = { 2778c2ecf20Sopenharmony_ci .dma_mask = &au1550_all_dmamask, 2788c2ecf20Sopenharmony_ci .coherent_dma_mask = DMA_BIT_MASK(32), 2798c2ecf20Sopenharmony_ci .platform_data = &db1550_spi_platdata, 2808c2ecf20Sopenharmony_ci }, 2818c2ecf20Sopenharmony_ci .name = "au1550-spi", 2828c2ecf20Sopenharmony_ci .id = 0, /* bus number */ 2838c2ecf20Sopenharmony_ci .num_resources = ARRAY_SIZE(au1550_psc0_res), 2848c2ecf20Sopenharmony_ci .resource = au1550_psc0_res, 2858c2ecf20Sopenharmony_ci}; 2868c2ecf20Sopenharmony_ci 2878c2ecf20Sopenharmony_ci/**********************************************************************/ 2888c2ecf20Sopenharmony_ci 2898c2ecf20Sopenharmony_cistatic struct resource au1550_psc1_res[] = { 2908c2ecf20Sopenharmony_ci [0] = { 2918c2ecf20Sopenharmony_ci .start = AU1550_PSC1_PHYS_ADDR, 2928c2ecf20Sopenharmony_ci .end = AU1550_PSC1_PHYS_ADDR + 0xfff, 2938c2ecf20Sopenharmony_ci .flags = IORESOURCE_MEM, 2948c2ecf20Sopenharmony_ci }, 2958c2ecf20Sopenharmony_ci [1] = { 2968c2ecf20Sopenharmony_ci .start = AU1550_PSC1_INT, 2978c2ecf20Sopenharmony_ci .end = AU1550_PSC1_INT, 2988c2ecf20Sopenharmony_ci .flags = IORESOURCE_IRQ, 2998c2ecf20Sopenharmony_ci }, 3008c2ecf20Sopenharmony_ci [2] = { 3018c2ecf20Sopenharmony_ci .start = AU1550_DSCR_CMD0_PSC1_TX, 3028c2ecf20Sopenharmony_ci .end = AU1550_DSCR_CMD0_PSC1_TX, 3038c2ecf20Sopenharmony_ci .flags = IORESOURCE_DMA, 3048c2ecf20Sopenharmony_ci }, 3058c2ecf20Sopenharmony_ci [3] = { 3068c2ecf20Sopenharmony_ci .start = AU1550_DSCR_CMD0_PSC1_RX, 3078c2ecf20Sopenharmony_ci .end = AU1550_DSCR_CMD0_PSC1_RX, 3088c2ecf20Sopenharmony_ci .flags = IORESOURCE_DMA, 3098c2ecf20Sopenharmony_ci }, 3108c2ecf20Sopenharmony_ci}; 3118c2ecf20Sopenharmony_ci 3128c2ecf20Sopenharmony_cistatic struct platform_device db1550_ac97_dev = { 3138c2ecf20Sopenharmony_ci .name = "au1xpsc_ac97", 3148c2ecf20Sopenharmony_ci .id = 1, /* PSC ID */ 3158c2ecf20Sopenharmony_ci .num_resources = ARRAY_SIZE(au1550_psc1_res), 3168c2ecf20Sopenharmony_ci .resource = au1550_psc1_res, 3178c2ecf20Sopenharmony_ci}; 3188c2ecf20Sopenharmony_ci 3198c2ecf20Sopenharmony_ci 3208c2ecf20Sopenharmony_cistatic struct resource au1550_psc2_res[] = { 3218c2ecf20Sopenharmony_ci [0] = { 3228c2ecf20Sopenharmony_ci .start = AU1550_PSC2_PHYS_ADDR, 3238c2ecf20Sopenharmony_ci .end = AU1550_PSC2_PHYS_ADDR + 0xfff, 3248c2ecf20Sopenharmony_ci .flags = IORESOURCE_MEM, 3258c2ecf20Sopenharmony_ci }, 3268c2ecf20Sopenharmony_ci [1] = { 3278c2ecf20Sopenharmony_ci .start = AU1550_PSC2_INT, 3288c2ecf20Sopenharmony_ci .end = AU1550_PSC2_INT, 3298c2ecf20Sopenharmony_ci .flags = IORESOURCE_IRQ, 3308c2ecf20Sopenharmony_ci }, 3318c2ecf20Sopenharmony_ci [2] = { 3328c2ecf20Sopenharmony_ci .start = AU1550_DSCR_CMD0_PSC2_TX, 3338c2ecf20Sopenharmony_ci .end = AU1550_DSCR_CMD0_PSC2_TX, 3348c2ecf20Sopenharmony_ci .flags = IORESOURCE_DMA, 3358c2ecf20Sopenharmony_ci }, 3368c2ecf20Sopenharmony_ci [3] = { 3378c2ecf20Sopenharmony_ci .start = AU1550_DSCR_CMD0_PSC2_RX, 3388c2ecf20Sopenharmony_ci .end = AU1550_DSCR_CMD0_PSC2_RX, 3398c2ecf20Sopenharmony_ci .flags = IORESOURCE_DMA, 3408c2ecf20Sopenharmony_ci }, 3418c2ecf20Sopenharmony_ci}; 3428c2ecf20Sopenharmony_ci 3438c2ecf20Sopenharmony_cistatic struct platform_device db1550_i2c_dev = { 3448c2ecf20Sopenharmony_ci .name = "au1xpsc_smbus", 3458c2ecf20Sopenharmony_ci .id = 0, /* bus number */ 3468c2ecf20Sopenharmony_ci .num_resources = ARRAY_SIZE(au1550_psc2_res), 3478c2ecf20Sopenharmony_ci .resource = au1550_psc2_res, 3488c2ecf20Sopenharmony_ci}; 3498c2ecf20Sopenharmony_ci 3508c2ecf20Sopenharmony_ci/**********************************************************************/ 3518c2ecf20Sopenharmony_ci 3528c2ecf20Sopenharmony_cistatic struct resource au1550_psc3_res[] = { 3538c2ecf20Sopenharmony_ci [0] = { 3548c2ecf20Sopenharmony_ci .start = AU1550_PSC3_PHYS_ADDR, 3558c2ecf20Sopenharmony_ci .end = AU1550_PSC3_PHYS_ADDR + 0xfff, 3568c2ecf20Sopenharmony_ci .flags = IORESOURCE_MEM, 3578c2ecf20Sopenharmony_ci }, 3588c2ecf20Sopenharmony_ci [1] = { 3598c2ecf20Sopenharmony_ci .start = AU1550_PSC3_INT, 3608c2ecf20Sopenharmony_ci .end = AU1550_PSC3_INT, 3618c2ecf20Sopenharmony_ci .flags = IORESOURCE_IRQ, 3628c2ecf20Sopenharmony_ci }, 3638c2ecf20Sopenharmony_ci [2] = { 3648c2ecf20Sopenharmony_ci .start = AU1550_DSCR_CMD0_PSC3_TX, 3658c2ecf20Sopenharmony_ci .end = AU1550_DSCR_CMD0_PSC3_TX, 3668c2ecf20Sopenharmony_ci .flags = IORESOURCE_DMA, 3678c2ecf20Sopenharmony_ci }, 3688c2ecf20Sopenharmony_ci [3] = { 3698c2ecf20Sopenharmony_ci .start = AU1550_DSCR_CMD0_PSC3_RX, 3708c2ecf20Sopenharmony_ci .end = AU1550_DSCR_CMD0_PSC3_RX, 3718c2ecf20Sopenharmony_ci .flags = IORESOURCE_DMA, 3728c2ecf20Sopenharmony_ci }, 3738c2ecf20Sopenharmony_ci}; 3748c2ecf20Sopenharmony_ci 3758c2ecf20Sopenharmony_cistatic struct platform_device db1550_i2s_dev = { 3768c2ecf20Sopenharmony_ci .name = "au1xpsc_i2s", 3778c2ecf20Sopenharmony_ci .id = 3, /* PSC ID */ 3788c2ecf20Sopenharmony_ci .num_resources = ARRAY_SIZE(au1550_psc3_res), 3798c2ecf20Sopenharmony_ci .resource = au1550_psc3_res, 3808c2ecf20Sopenharmony_ci}; 3818c2ecf20Sopenharmony_ci 3828c2ecf20Sopenharmony_ci/**********************************************************************/ 3838c2ecf20Sopenharmony_ci 3848c2ecf20Sopenharmony_cistatic struct platform_device db1550_stac_dev = { 3858c2ecf20Sopenharmony_ci .name = "ac97-codec", 3868c2ecf20Sopenharmony_ci .id = 1, /* on PSC1 */ 3878c2ecf20Sopenharmony_ci}; 3888c2ecf20Sopenharmony_ci 3898c2ecf20Sopenharmony_cistatic struct platform_device db1550_ac97dma_dev = { 3908c2ecf20Sopenharmony_ci .name = "au1xpsc-pcm", 3918c2ecf20Sopenharmony_ci .id = 1, /* on PSC3 */ 3928c2ecf20Sopenharmony_ci}; 3938c2ecf20Sopenharmony_ci 3948c2ecf20Sopenharmony_cistatic struct platform_device db1550_i2sdma_dev = { 3958c2ecf20Sopenharmony_ci .name = "au1xpsc-pcm", 3968c2ecf20Sopenharmony_ci .id = 3, /* on PSC3 */ 3978c2ecf20Sopenharmony_ci}; 3988c2ecf20Sopenharmony_ci 3998c2ecf20Sopenharmony_cistatic struct platform_device db1550_sndac97_dev = { 4008c2ecf20Sopenharmony_ci .name = "db1550-ac97", 4018c2ecf20Sopenharmony_ci .dev = { 4028c2ecf20Sopenharmony_ci .dma_mask = &au1550_all_dmamask, 4038c2ecf20Sopenharmony_ci .coherent_dma_mask = DMA_BIT_MASK(32), 4048c2ecf20Sopenharmony_ci }, 4058c2ecf20Sopenharmony_ci}; 4068c2ecf20Sopenharmony_ci 4078c2ecf20Sopenharmony_cistatic struct platform_device db1550_sndi2s_dev = { 4088c2ecf20Sopenharmony_ci .name = "db1550-i2s", 4098c2ecf20Sopenharmony_ci .dev = { 4108c2ecf20Sopenharmony_ci .dma_mask = &au1550_all_dmamask, 4118c2ecf20Sopenharmony_ci .coherent_dma_mask = DMA_BIT_MASK(32), 4128c2ecf20Sopenharmony_ci }, 4138c2ecf20Sopenharmony_ci}; 4148c2ecf20Sopenharmony_ci 4158c2ecf20Sopenharmony_ci/**********************************************************************/ 4168c2ecf20Sopenharmony_ci 4178c2ecf20Sopenharmony_cistatic int db1550_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin) 4188c2ecf20Sopenharmony_ci{ 4198c2ecf20Sopenharmony_ci if ((slot < 11) || (slot > 13) || pin == 0) 4208c2ecf20Sopenharmony_ci return -1; 4218c2ecf20Sopenharmony_ci if (slot == 11) 4228c2ecf20Sopenharmony_ci return (pin == 1) ? AU1550_PCI_INTC : 0xff; 4238c2ecf20Sopenharmony_ci if (slot == 12) { 4248c2ecf20Sopenharmony_ci switch (pin) { 4258c2ecf20Sopenharmony_ci case 1: return AU1550_PCI_INTB; 4268c2ecf20Sopenharmony_ci case 2: return AU1550_PCI_INTC; 4278c2ecf20Sopenharmony_ci case 3: return AU1550_PCI_INTD; 4288c2ecf20Sopenharmony_ci case 4: return AU1550_PCI_INTA; 4298c2ecf20Sopenharmony_ci } 4308c2ecf20Sopenharmony_ci } 4318c2ecf20Sopenharmony_ci if (slot == 13) { 4328c2ecf20Sopenharmony_ci switch (pin) { 4338c2ecf20Sopenharmony_ci case 1: return AU1550_PCI_INTA; 4348c2ecf20Sopenharmony_ci case 2: return AU1550_PCI_INTB; 4358c2ecf20Sopenharmony_ci case 3: return AU1550_PCI_INTC; 4368c2ecf20Sopenharmony_ci case 4: return AU1550_PCI_INTD; 4378c2ecf20Sopenharmony_ci } 4388c2ecf20Sopenharmony_ci } 4398c2ecf20Sopenharmony_ci return -1; 4408c2ecf20Sopenharmony_ci} 4418c2ecf20Sopenharmony_ci 4428c2ecf20Sopenharmony_cistatic int pb1550_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin) 4438c2ecf20Sopenharmony_ci{ 4448c2ecf20Sopenharmony_ci if ((slot < 12) || (slot > 13) || pin == 0) 4458c2ecf20Sopenharmony_ci return -1; 4468c2ecf20Sopenharmony_ci if (slot == 12) { 4478c2ecf20Sopenharmony_ci switch (pin) { 4488c2ecf20Sopenharmony_ci case 1: return AU1500_PCI_INTB; 4498c2ecf20Sopenharmony_ci case 2: return AU1500_PCI_INTC; 4508c2ecf20Sopenharmony_ci case 3: return AU1500_PCI_INTD; 4518c2ecf20Sopenharmony_ci case 4: return AU1500_PCI_INTA; 4528c2ecf20Sopenharmony_ci } 4538c2ecf20Sopenharmony_ci } 4548c2ecf20Sopenharmony_ci if (slot == 13) { 4558c2ecf20Sopenharmony_ci switch (pin) { 4568c2ecf20Sopenharmony_ci case 1: return AU1500_PCI_INTA; 4578c2ecf20Sopenharmony_ci case 2: return AU1500_PCI_INTB; 4588c2ecf20Sopenharmony_ci case 3: return AU1500_PCI_INTC; 4598c2ecf20Sopenharmony_ci case 4: return AU1500_PCI_INTD; 4608c2ecf20Sopenharmony_ci } 4618c2ecf20Sopenharmony_ci } 4628c2ecf20Sopenharmony_ci return -1; 4638c2ecf20Sopenharmony_ci} 4648c2ecf20Sopenharmony_ci 4658c2ecf20Sopenharmony_cistatic struct resource alchemy_pci_host_res[] = { 4668c2ecf20Sopenharmony_ci [0] = { 4678c2ecf20Sopenharmony_ci .start = AU1500_PCI_PHYS_ADDR, 4688c2ecf20Sopenharmony_ci .end = AU1500_PCI_PHYS_ADDR + 0xfff, 4698c2ecf20Sopenharmony_ci .flags = IORESOURCE_MEM, 4708c2ecf20Sopenharmony_ci }, 4718c2ecf20Sopenharmony_ci}; 4728c2ecf20Sopenharmony_ci 4738c2ecf20Sopenharmony_cistatic struct alchemy_pci_platdata db1550_pci_pd = { 4748c2ecf20Sopenharmony_ci .board_map_irq = db1550_map_pci_irq, 4758c2ecf20Sopenharmony_ci}; 4768c2ecf20Sopenharmony_ci 4778c2ecf20Sopenharmony_cistatic struct platform_device db1550_pci_host_dev = { 4788c2ecf20Sopenharmony_ci .dev.platform_data = &db1550_pci_pd, 4798c2ecf20Sopenharmony_ci .name = "alchemy-pci", 4808c2ecf20Sopenharmony_ci .id = 0, 4818c2ecf20Sopenharmony_ci .num_resources = ARRAY_SIZE(alchemy_pci_host_res), 4828c2ecf20Sopenharmony_ci .resource = alchemy_pci_host_res, 4838c2ecf20Sopenharmony_ci}; 4848c2ecf20Sopenharmony_ci 4858c2ecf20Sopenharmony_ci/**********************************************************************/ 4868c2ecf20Sopenharmony_ci 4878c2ecf20Sopenharmony_cistatic struct platform_device *db1550_devs[] __initdata = { 4888c2ecf20Sopenharmony_ci &db1550_i2c_dev, 4898c2ecf20Sopenharmony_ci &db1550_ac97_dev, 4908c2ecf20Sopenharmony_ci &db1550_spi_dev, 4918c2ecf20Sopenharmony_ci &db1550_i2s_dev, 4928c2ecf20Sopenharmony_ci &db1550_stac_dev, 4938c2ecf20Sopenharmony_ci &db1550_ac97dma_dev, 4948c2ecf20Sopenharmony_ci &db1550_i2sdma_dev, 4958c2ecf20Sopenharmony_ci &db1550_sndac97_dev, 4968c2ecf20Sopenharmony_ci &db1550_sndi2s_dev, 4978c2ecf20Sopenharmony_ci}; 4988c2ecf20Sopenharmony_ci 4998c2ecf20Sopenharmony_ci/* must be arch_initcall; MIPS PCI scans busses in a subsys_initcall */ 5008c2ecf20Sopenharmony_ciint __init db1550_pci_setup(int id) 5018c2ecf20Sopenharmony_ci{ 5028c2ecf20Sopenharmony_ci if (id) 5038c2ecf20Sopenharmony_ci db1550_pci_pd.board_map_irq = pb1550_map_pci_irq; 5048c2ecf20Sopenharmony_ci return platform_device_register(&db1550_pci_host_dev); 5058c2ecf20Sopenharmony_ci} 5068c2ecf20Sopenharmony_ci 5078c2ecf20Sopenharmony_cistatic void __init db1550_devices(void) 5088c2ecf20Sopenharmony_ci{ 5098c2ecf20Sopenharmony_ci alchemy_gpio_direction_output(203, 0); /* red led on */ 5108c2ecf20Sopenharmony_ci 5118c2ecf20Sopenharmony_ci irq_set_irq_type(AU1550_GPIO0_INT, IRQ_TYPE_EDGE_BOTH); /* CD0# */ 5128c2ecf20Sopenharmony_ci irq_set_irq_type(AU1550_GPIO1_INT, IRQ_TYPE_EDGE_BOTH); /* CD1# */ 5138c2ecf20Sopenharmony_ci irq_set_irq_type(AU1550_GPIO3_INT, IRQ_TYPE_LEVEL_LOW); /* CARD0# */ 5148c2ecf20Sopenharmony_ci irq_set_irq_type(AU1550_GPIO5_INT, IRQ_TYPE_LEVEL_LOW); /* CARD1# */ 5158c2ecf20Sopenharmony_ci irq_set_irq_type(AU1550_GPIO21_INT, IRQ_TYPE_LEVEL_LOW); /* STSCHG0# */ 5168c2ecf20Sopenharmony_ci irq_set_irq_type(AU1550_GPIO22_INT, IRQ_TYPE_LEVEL_LOW); /* STSCHG1# */ 5178c2ecf20Sopenharmony_ci 5188c2ecf20Sopenharmony_ci db1x_register_pcmcia_socket( 5198c2ecf20Sopenharmony_ci AU1000_PCMCIA_ATTR_PHYS_ADDR, 5208c2ecf20Sopenharmony_ci AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1, 5218c2ecf20Sopenharmony_ci AU1000_PCMCIA_MEM_PHYS_ADDR, 5228c2ecf20Sopenharmony_ci AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1, 5238c2ecf20Sopenharmony_ci AU1000_PCMCIA_IO_PHYS_ADDR, 5248c2ecf20Sopenharmony_ci AU1000_PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1, 5258c2ecf20Sopenharmony_ci AU1550_GPIO3_INT, 0, 5268c2ecf20Sopenharmony_ci /*AU1550_GPIO21_INT*/0, 0, 0); 5278c2ecf20Sopenharmony_ci 5288c2ecf20Sopenharmony_ci db1x_register_pcmcia_socket( 5298c2ecf20Sopenharmony_ci AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x004000000, 5308c2ecf20Sopenharmony_ci AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x004400000 - 1, 5318c2ecf20Sopenharmony_ci AU1000_PCMCIA_MEM_PHYS_ADDR + 0x004000000, 5328c2ecf20Sopenharmony_ci AU1000_PCMCIA_MEM_PHYS_ADDR + 0x004400000 - 1, 5338c2ecf20Sopenharmony_ci AU1000_PCMCIA_IO_PHYS_ADDR + 0x004000000, 5348c2ecf20Sopenharmony_ci AU1000_PCMCIA_IO_PHYS_ADDR + 0x004010000 - 1, 5358c2ecf20Sopenharmony_ci AU1550_GPIO5_INT, 1, 5368c2ecf20Sopenharmony_ci /*AU1550_GPIO22_INT*/0, 0, 1); 5378c2ecf20Sopenharmony_ci 5388c2ecf20Sopenharmony_ci platform_device_register(&db1550_nand_dev); 5398c2ecf20Sopenharmony_ci 5408c2ecf20Sopenharmony_ci alchemy_gpio_direction_output(202, 0); /* green led on */ 5418c2ecf20Sopenharmony_ci} 5428c2ecf20Sopenharmony_ci 5438c2ecf20Sopenharmony_cistatic void __init pb1550_devices(void) 5448c2ecf20Sopenharmony_ci{ 5458c2ecf20Sopenharmony_ci irq_set_irq_type(AU1550_GPIO0_INT, IRQ_TYPE_LEVEL_LOW); 5468c2ecf20Sopenharmony_ci irq_set_irq_type(AU1550_GPIO1_INT, IRQ_TYPE_LEVEL_LOW); 5478c2ecf20Sopenharmony_ci irq_set_irq_type(AU1550_GPIO201_205_INT, IRQ_TYPE_LEVEL_HIGH); 5488c2ecf20Sopenharmony_ci 5498c2ecf20Sopenharmony_ci /* enable both PCMCIA card irqs in the shared line */ 5508c2ecf20Sopenharmony_ci alchemy_gpio2_enable_int(201); /* socket 0 card irq */ 5518c2ecf20Sopenharmony_ci alchemy_gpio2_enable_int(202); /* socket 1 card irq */ 5528c2ecf20Sopenharmony_ci 5538c2ecf20Sopenharmony_ci /* Pb1550, like all others, also has statuschange irqs; however they're 5548c2ecf20Sopenharmony_ci * wired up on one of the Au1550's shared GPIO201_205 line, which also 5558c2ecf20Sopenharmony_ci * services the PCMCIA card interrupts. So we ignore statuschange and 5568c2ecf20Sopenharmony_ci * use the GPIO201_205 exclusively for card interrupts, since a) pcmcia 5578c2ecf20Sopenharmony_ci * drivers are used to shared irqs and b) statuschange isn't really use- 5588c2ecf20Sopenharmony_ci * ful anyway. 5598c2ecf20Sopenharmony_ci */ 5608c2ecf20Sopenharmony_ci db1x_register_pcmcia_socket( 5618c2ecf20Sopenharmony_ci AU1000_PCMCIA_ATTR_PHYS_ADDR, 5628c2ecf20Sopenharmony_ci AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1, 5638c2ecf20Sopenharmony_ci AU1000_PCMCIA_MEM_PHYS_ADDR, 5648c2ecf20Sopenharmony_ci AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1, 5658c2ecf20Sopenharmony_ci AU1000_PCMCIA_IO_PHYS_ADDR, 5668c2ecf20Sopenharmony_ci AU1000_PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1, 5678c2ecf20Sopenharmony_ci AU1550_GPIO201_205_INT, AU1550_GPIO0_INT, 0, 0, 0); 5688c2ecf20Sopenharmony_ci 5698c2ecf20Sopenharmony_ci db1x_register_pcmcia_socket( 5708c2ecf20Sopenharmony_ci AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x008000000, 5718c2ecf20Sopenharmony_ci AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x008400000 - 1, 5728c2ecf20Sopenharmony_ci AU1000_PCMCIA_MEM_PHYS_ADDR + 0x008000000, 5738c2ecf20Sopenharmony_ci AU1000_PCMCIA_MEM_PHYS_ADDR + 0x008400000 - 1, 5748c2ecf20Sopenharmony_ci AU1000_PCMCIA_IO_PHYS_ADDR + 0x008000000, 5758c2ecf20Sopenharmony_ci AU1000_PCMCIA_IO_PHYS_ADDR + 0x008010000 - 1, 5768c2ecf20Sopenharmony_ci AU1550_GPIO201_205_INT, AU1550_GPIO1_INT, 0, 0, 1); 5778c2ecf20Sopenharmony_ci 5788c2ecf20Sopenharmony_ci pb1550_nand_setup(); 5798c2ecf20Sopenharmony_ci} 5808c2ecf20Sopenharmony_ci 5818c2ecf20Sopenharmony_ciint __init db1550_dev_setup(void) 5828c2ecf20Sopenharmony_ci{ 5838c2ecf20Sopenharmony_ci int swapped, id; 5848c2ecf20Sopenharmony_ci struct clk *c; 5858c2ecf20Sopenharmony_ci 5868c2ecf20Sopenharmony_ci id = (BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI)) != BCSR_WHOAMI_DB1550); 5878c2ecf20Sopenharmony_ci 5888c2ecf20Sopenharmony_ci i2c_register_board_info(0, db1550_i2c_devs, 5898c2ecf20Sopenharmony_ci ARRAY_SIZE(db1550_i2c_devs)); 5908c2ecf20Sopenharmony_ci spi_register_board_info(db1550_spi_devs, 5918c2ecf20Sopenharmony_ci ARRAY_SIZE(db1550_spi_devs)); 5928c2ecf20Sopenharmony_ci 5938c2ecf20Sopenharmony_ci c = clk_get(NULL, "psc0_intclk"); 5948c2ecf20Sopenharmony_ci if (!IS_ERR(c)) { 5958c2ecf20Sopenharmony_ci clk_set_rate(c, 50000000); 5968c2ecf20Sopenharmony_ci clk_prepare_enable(c); 5978c2ecf20Sopenharmony_ci clk_put(c); 5988c2ecf20Sopenharmony_ci } 5998c2ecf20Sopenharmony_ci c = clk_get(NULL, "psc2_intclk"); 6008c2ecf20Sopenharmony_ci if (!IS_ERR(c)) { 6018c2ecf20Sopenharmony_ci clk_set_rate(c, db1550_spi_platdata.mainclk_hz); 6028c2ecf20Sopenharmony_ci clk_prepare_enable(c); 6038c2ecf20Sopenharmony_ci clk_put(c); 6048c2ecf20Sopenharmony_ci } 6058c2ecf20Sopenharmony_ci 6068c2ecf20Sopenharmony_ci /* Audio PSC clock is supplied by codecs (PSC1, 3) FIXME: platdata!! */ 6078c2ecf20Sopenharmony_ci __raw_writel(PSC_SEL_CLK_SERCLK, 6088c2ecf20Sopenharmony_ci (void __iomem *)KSEG1ADDR(AU1550_PSC1_PHYS_ADDR) + PSC_SEL_OFFSET); 6098c2ecf20Sopenharmony_ci wmb(); 6108c2ecf20Sopenharmony_ci __raw_writel(PSC_SEL_CLK_SERCLK, 6118c2ecf20Sopenharmony_ci (void __iomem *)KSEG1ADDR(AU1550_PSC3_PHYS_ADDR) + PSC_SEL_OFFSET); 6128c2ecf20Sopenharmony_ci wmb(); 6138c2ecf20Sopenharmony_ci /* SPI/I2C use internally supplied 50MHz source */ 6148c2ecf20Sopenharmony_ci __raw_writel(PSC_SEL_CLK_INTCLK, 6158c2ecf20Sopenharmony_ci (void __iomem *)KSEG1ADDR(AU1550_PSC0_PHYS_ADDR) + PSC_SEL_OFFSET); 6168c2ecf20Sopenharmony_ci wmb(); 6178c2ecf20Sopenharmony_ci __raw_writel(PSC_SEL_CLK_INTCLK, 6188c2ecf20Sopenharmony_ci (void __iomem *)KSEG1ADDR(AU1550_PSC2_PHYS_ADDR) + PSC_SEL_OFFSET); 6198c2ecf20Sopenharmony_ci wmb(); 6208c2ecf20Sopenharmony_ci 6218c2ecf20Sopenharmony_ci id ? pb1550_devices() : db1550_devices(); 6228c2ecf20Sopenharmony_ci 6238c2ecf20Sopenharmony_ci swapped = bcsr_read(BCSR_STATUS) & 6248c2ecf20Sopenharmony_ci (id ? BCSR_STATUS_PB1550_SWAPBOOT : BCSR_STATUS_DB1000_SWAPBOOT); 6258c2ecf20Sopenharmony_ci db1x_register_norflash(128 << 20, 4, swapped); 6268c2ecf20Sopenharmony_ci 6278c2ecf20Sopenharmony_ci return platform_add_devices(db1550_devs, ARRAY_SIZE(db1550_devs)); 6288c2ecf20Sopenharmony_ci} 629