162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Renesas Technology Sales RTS7751R2D Support. 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 2002 - 2006 Atom Create Engineering Co., Ltd. 662306a36Sopenharmony_ci * Copyright (C) 2004 - 2007 Paul Mundt 762306a36Sopenharmony_ci */ 862306a36Sopenharmony_ci#include <linux/init.h> 962306a36Sopenharmony_ci#include <linux/platform_device.h> 1062306a36Sopenharmony_ci#include <linux/mtd/mtd.h> 1162306a36Sopenharmony_ci#include <linux/mtd/partitions.h> 1262306a36Sopenharmony_ci#include <linux/mtd/physmap.h> 1362306a36Sopenharmony_ci#include <linux/ata_platform.h> 1462306a36Sopenharmony_ci#include <linux/sm501.h> 1562306a36Sopenharmony_ci#include <linux/sm501-regs.h> 1662306a36Sopenharmony_ci#include <linux/pm.h> 1762306a36Sopenharmony_ci#include <linux/fb.h> 1862306a36Sopenharmony_ci#include <linux/spi/spi.h> 1962306a36Sopenharmony_ci#include <linux/spi/spi_bitbang.h> 2062306a36Sopenharmony_ci#include <asm/machvec.h> 2162306a36Sopenharmony_ci#include <mach/r2d.h> 2262306a36Sopenharmony_ci#include <asm/io.h> 2362306a36Sopenharmony_ci#include <asm/io_trapped.h> 2462306a36Sopenharmony_ci#include <asm/spi.h> 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_cistatic struct resource cf_ide_resources[] = { 2762306a36Sopenharmony_ci [0] = { 2862306a36Sopenharmony_ci .start = PA_AREA5_IO + 0x1000, 2962306a36Sopenharmony_ci .end = PA_AREA5_IO + 0x1000 + 0x10 - 0x2, 3062306a36Sopenharmony_ci .flags = IORESOURCE_MEM, 3162306a36Sopenharmony_ci }, 3262306a36Sopenharmony_ci [1] = { 3362306a36Sopenharmony_ci .start = PA_AREA5_IO + 0x80c, 3462306a36Sopenharmony_ci .end = PA_AREA5_IO + 0x80c, 3562306a36Sopenharmony_ci .flags = IORESOURCE_MEM, 3662306a36Sopenharmony_ci }, 3762306a36Sopenharmony_ci#ifndef CONFIG_RTS7751R2D_1 /* For R2D-1 polling is preferred */ 3862306a36Sopenharmony_ci [2] = { 3962306a36Sopenharmony_ci .start = IRQ_CF_IDE, 4062306a36Sopenharmony_ci .flags = IORESOURCE_IRQ, 4162306a36Sopenharmony_ci }, 4262306a36Sopenharmony_ci#endif 4362306a36Sopenharmony_ci}; 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_cistatic struct pata_platform_info pata_info = { 4662306a36Sopenharmony_ci .ioport_shift = 1, 4762306a36Sopenharmony_ci}; 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_cistatic struct platform_device cf_ide_device = { 5062306a36Sopenharmony_ci .name = "pata_platform", 5162306a36Sopenharmony_ci .id = -1, 5262306a36Sopenharmony_ci .num_resources = ARRAY_SIZE(cf_ide_resources), 5362306a36Sopenharmony_ci .resource = cf_ide_resources, 5462306a36Sopenharmony_ci .dev = { 5562306a36Sopenharmony_ci .platform_data = &pata_info, 5662306a36Sopenharmony_ci }, 5762306a36Sopenharmony_ci}; 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_cistatic struct spi_board_info spi_bus[] = { 6062306a36Sopenharmony_ci { 6162306a36Sopenharmony_ci .modalias = "rtc-r9701", 6262306a36Sopenharmony_ci .max_speed_hz = 1000000, 6362306a36Sopenharmony_ci .mode = SPI_MODE_3, 6462306a36Sopenharmony_ci }, 6562306a36Sopenharmony_ci}; 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_cistatic void r2d_chip_select(struct sh_spi_info *spi, int cs, int state) 6862306a36Sopenharmony_ci{ 6962306a36Sopenharmony_ci BUG_ON(cs != 0); /* Single Epson RTC-9701JE attached on CS0 */ 7062306a36Sopenharmony_ci __raw_writew(state == BITBANG_CS_ACTIVE, PA_RTCCE); 7162306a36Sopenharmony_ci} 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_cistatic struct sh_spi_info spi_info = { 7462306a36Sopenharmony_ci .num_chipselect = 1, 7562306a36Sopenharmony_ci .chip_select = r2d_chip_select, 7662306a36Sopenharmony_ci}; 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_cistatic struct resource spi_sh_sci_resources[] = { 7962306a36Sopenharmony_ci { 8062306a36Sopenharmony_ci .start = 0xffe00000, 8162306a36Sopenharmony_ci .end = 0xffe0001f, 8262306a36Sopenharmony_ci .flags = IORESOURCE_MEM, 8362306a36Sopenharmony_ci }, 8462306a36Sopenharmony_ci}; 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_cistatic struct platform_device spi_sh_sci_device = { 8762306a36Sopenharmony_ci .name = "spi_sh_sci", 8862306a36Sopenharmony_ci .id = -1, 8962306a36Sopenharmony_ci .num_resources = ARRAY_SIZE(spi_sh_sci_resources), 9062306a36Sopenharmony_ci .resource = spi_sh_sci_resources, 9162306a36Sopenharmony_ci .dev = { 9262306a36Sopenharmony_ci .platform_data = &spi_info, 9362306a36Sopenharmony_ci }, 9462306a36Sopenharmony_ci}; 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_cistatic struct resource heartbeat_resources[] = { 9762306a36Sopenharmony_ci [0] = { 9862306a36Sopenharmony_ci .start = PA_OUTPORT, 9962306a36Sopenharmony_ci .end = PA_OUTPORT, 10062306a36Sopenharmony_ci .flags = IORESOURCE_MEM, 10162306a36Sopenharmony_ci }, 10262306a36Sopenharmony_ci}; 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_cistatic struct platform_device heartbeat_device = { 10562306a36Sopenharmony_ci .name = "heartbeat", 10662306a36Sopenharmony_ci .id = -1, 10762306a36Sopenharmony_ci .num_resources = ARRAY_SIZE(heartbeat_resources), 10862306a36Sopenharmony_ci .resource = heartbeat_resources, 10962306a36Sopenharmony_ci}; 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_cistatic struct resource sm501_resources[] = { 11262306a36Sopenharmony_ci [0] = { 11362306a36Sopenharmony_ci .start = 0x10000000, 11462306a36Sopenharmony_ci .end = 0x13e00000 - 1, 11562306a36Sopenharmony_ci .flags = IORESOURCE_MEM, 11662306a36Sopenharmony_ci }, 11762306a36Sopenharmony_ci [1] = { 11862306a36Sopenharmony_ci .start = 0x13e00000, 11962306a36Sopenharmony_ci .end = 0x13ffffff, 12062306a36Sopenharmony_ci .flags = IORESOURCE_MEM, 12162306a36Sopenharmony_ci }, 12262306a36Sopenharmony_ci [2] = { 12362306a36Sopenharmony_ci .start = IRQ_VOYAGER, 12462306a36Sopenharmony_ci .flags = IORESOURCE_IRQ, 12562306a36Sopenharmony_ci }, 12662306a36Sopenharmony_ci}; 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_cistatic struct fb_videomode sm501_default_mode = { 12962306a36Sopenharmony_ci .pixclock = 35714, 13062306a36Sopenharmony_ci .xres = 640, 13162306a36Sopenharmony_ci .yres = 480, 13262306a36Sopenharmony_ci .left_margin = 105, 13362306a36Sopenharmony_ci .right_margin = 50, 13462306a36Sopenharmony_ci .upper_margin = 35, 13562306a36Sopenharmony_ci .lower_margin = 0, 13662306a36Sopenharmony_ci .hsync_len = 96, 13762306a36Sopenharmony_ci .vsync_len = 2, 13862306a36Sopenharmony_ci .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 13962306a36Sopenharmony_ci}; 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_cistatic struct sm501_platdata_fbsub sm501_pdata_fbsub_pnl = { 14262306a36Sopenharmony_ci .def_bpp = 16, 14362306a36Sopenharmony_ci .def_mode = &sm501_default_mode, 14462306a36Sopenharmony_ci .flags = SM501FB_FLAG_USE_INIT_MODE | 14562306a36Sopenharmony_ci SM501FB_FLAG_USE_HWCURSOR | 14662306a36Sopenharmony_ci SM501FB_FLAG_USE_HWACCEL | 14762306a36Sopenharmony_ci SM501FB_FLAG_DISABLE_AT_EXIT, 14862306a36Sopenharmony_ci}; 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_cistatic struct sm501_platdata_fbsub sm501_pdata_fbsub_crt = { 15162306a36Sopenharmony_ci .flags = (SM501FB_FLAG_USE_INIT_MODE | 15262306a36Sopenharmony_ci SM501FB_FLAG_USE_HWCURSOR | 15362306a36Sopenharmony_ci SM501FB_FLAG_USE_HWACCEL | 15462306a36Sopenharmony_ci SM501FB_FLAG_DISABLE_AT_EXIT), 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_ci}; 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_cistatic struct sm501_platdata_fb sm501_fb_pdata = { 15962306a36Sopenharmony_ci .fb_route = SM501_FB_OWN, 16062306a36Sopenharmony_ci .fb_crt = &sm501_pdata_fbsub_crt, 16162306a36Sopenharmony_ci .fb_pnl = &sm501_pdata_fbsub_pnl, 16262306a36Sopenharmony_ci .flags = SM501_FBPD_SWAP_FB_ENDIAN, 16362306a36Sopenharmony_ci}; 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_cistatic struct sm501_initdata sm501_initdata = { 16662306a36Sopenharmony_ci .devices = SM501_USE_USB_HOST | SM501_USE_UART0, 16762306a36Sopenharmony_ci}; 16862306a36Sopenharmony_ci 16962306a36Sopenharmony_cistatic struct sm501_platdata sm501_platform_data = { 17062306a36Sopenharmony_ci .init = &sm501_initdata, 17162306a36Sopenharmony_ci .fb = &sm501_fb_pdata, 17262306a36Sopenharmony_ci}; 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_cistatic struct platform_device sm501_device = { 17562306a36Sopenharmony_ci .name = "sm501", 17662306a36Sopenharmony_ci .id = -1, 17762306a36Sopenharmony_ci .dev = { 17862306a36Sopenharmony_ci .platform_data = &sm501_platform_data, 17962306a36Sopenharmony_ci }, 18062306a36Sopenharmony_ci .num_resources = ARRAY_SIZE(sm501_resources), 18162306a36Sopenharmony_ci .resource = sm501_resources, 18262306a36Sopenharmony_ci}; 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_cistatic struct mtd_partition r2d_partitions[] = { 18562306a36Sopenharmony_ci { 18662306a36Sopenharmony_ci .name = "U-Boot", 18762306a36Sopenharmony_ci .offset = 0x00000000, 18862306a36Sopenharmony_ci .size = 0x00040000, 18962306a36Sopenharmony_ci .mask_flags = MTD_WRITEABLE, 19062306a36Sopenharmony_ci }, { 19162306a36Sopenharmony_ci .name = "Environment", 19262306a36Sopenharmony_ci .offset = MTDPART_OFS_NXTBLK, 19362306a36Sopenharmony_ci .size = 0x00040000, 19462306a36Sopenharmony_ci .mask_flags = MTD_WRITEABLE, 19562306a36Sopenharmony_ci }, { 19662306a36Sopenharmony_ci .name = "Kernel", 19762306a36Sopenharmony_ci .offset = MTDPART_OFS_NXTBLK, 19862306a36Sopenharmony_ci .size = 0x001c0000, 19962306a36Sopenharmony_ci }, { 20062306a36Sopenharmony_ci .name = "Flash_FS", 20162306a36Sopenharmony_ci .offset = MTDPART_OFS_NXTBLK, 20262306a36Sopenharmony_ci .size = MTDPART_SIZ_FULL, 20362306a36Sopenharmony_ci } 20462306a36Sopenharmony_ci}; 20562306a36Sopenharmony_ci 20662306a36Sopenharmony_cistatic struct physmap_flash_data flash_data = { 20762306a36Sopenharmony_ci .width = 2, 20862306a36Sopenharmony_ci .nr_parts = ARRAY_SIZE(r2d_partitions), 20962306a36Sopenharmony_ci .parts = r2d_partitions, 21062306a36Sopenharmony_ci}; 21162306a36Sopenharmony_ci 21262306a36Sopenharmony_cistatic struct resource flash_resource = { 21362306a36Sopenharmony_ci .start = 0x00000000, 21462306a36Sopenharmony_ci .end = 0x02000000, 21562306a36Sopenharmony_ci .flags = IORESOURCE_MEM, 21662306a36Sopenharmony_ci}; 21762306a36Sopenharmony_ci 21862306a36Sopenharmony_cistatic struct platform_device flash_device = { 21962306a36Sopenharmony_ci .name = "physmap-flash", 22062306a36Sopenharmony_ci .id = -1, 22162306a36Sopenharmony_ci .resource = &flash_resource, 22262306a36Sopenharmony_ci .num_resources = 1, 22362306a36Sopenharmony_ci .dev = { 22462306a36Sopenharmony_ci .platform_data = &flash_data, 22562306a36Sopenharmony_ci }, 22662306a36Sopenharmony_ci}; 22762306a36Sopenharmony_ci 22862306a36Sopenharmony_cistatic struct platform_device *rts7751r2d_devices[] __initdata = { 22962306a36Sopenharmony_ci &sm501_device, 23062306a36Sopenharmony_ci &heartbeat_device, 23162306a36Sopenharmony_ci &spi_sh_sci_device, 23262306a36Sopenharmony_ci}; 23362306a36Sopenharmony_ci 23462306a36Sopenharmony_ci/* 23562306a36Sopenharmony_ci * The CF is connected with a 16-bit bus where 8-bit operations are 23662306a36Sopenharmony_ci * unsupported. The linux ata driver is however using 8-bit operations, so 23762306a36Sopenharmony_ci * insert a trapped io filter to convert 8-bit operations into 16-bit. 23862306a36Sopenharmony_ci */ 23962306a36Sopenharmony_cistatic struct trapped_io cf_trapped_io = { 24062306a36Sopenharmony_ci .resource = cf_ide_resources, 24162306a36Sopenharmony_ci .num_resources = 2, 24262306a36Sopenharmony_ci .minimum_bus_width = 16, 24362306a36Sopenharmony_ci}; 24462306a36Sopenharmony_ci 24562306a36Sopenharmony_cistatic int __init rts7751r2d_devices_setup(void) 24662306a36Sopenharmony_ci{ 24762306a36Sopenharmony_ci if (register_trapped_io(&cf_trapped_io) == 0) 24862306a36Sopenharmony_ci platform_device_register(&cf_ide_device); 24962306a36Sopenharmony_ci 25062306a36Sopenharmony_ci if (mach_is_r2d_plus()) 25162306a36Sopenharmony_ci platform_device_register(&flash_device); 25262306a36Sopenharmony_ci 25362306a36Sopenharmony_ci spi_register_board_info(spi_bus, ARRAY_SIZE(spi_bus)); 25462306a36Sopenharmony_ci 25562306a36Sopenharmony_ci return platform_add_devices(rts7751r2d_devices, 25662306a36Sopenharmony_ci ARRAY_SIZE(rts7751r2d_devices)); 25762306a36Sopenharmony_ci} 25862306a36Sopenharmony_cidevice_initcall(rts7751r2d_devices_setup); 25962306a36Sopenharmony_ci 26062306a36Sopenharmony_cistatic void rts7751r2d_power_off(void) 26162306a36Sopenharmony_ci{ 26262306a36Sopenharmony_ci __raw_writew(0x0001, PA_POWOFF); 26362306a36Sopenharmony_ci} 26462306a36Sopenharmony_ci 26562306a36Sopenharmony_ci/* 26662306a36Sopenharmony_ci * Initialize the board 26762306a36Sopenharmony_ci */ 26862306a36Sopenharmony_cistatic void __init rts7751r2d_setup(char **cmdline_p) 26962306a36Sopenharmony_ci{ 27062306a36Sopenharmony_ci void __iomem *sm501_reg; 27162306a36Sopenharmony_ci u16 ver = __raw_readw(PA_VERREG); 27262306a36Sopenharmony_ci 27362306a36Sopenharmony_ci printk(KERN_INFO "Renesas Technology Sales RTS7751R2D support.\n"); 27462306a36Sopenharmony_ci 27562306a36Sopenharmony_ci printk(KERN_INFO "FPGA version:%d (revision:%d)\n", 27662306a36Sopenharmony_ci (ver >> 4) & 0xf, ver & 0xf); 27762306a36Sopenharmony_ci 27862306a36Sopenharmony_ci __raw_writew(0x0000, PA_OUTPORT); 27962306a36Sopenharmony_ci pm_power_off = rts7751r2d_power_off; 28062306a36Sopenharmony_ci 28162306a36Sopenharmony_ci /* sm501 dram configuration: 28262306a36Sopenharmony_ci * ColSizeX = 11 - External Memory Column Size: 256 words. 28362306a36Sopenharmony_ci * APX = 1 - External Memory Active to Pre-Charge Delay: 7 clocks. 28462306a36Sopenharmony_ci * RstX = 1 - External Memory Reset: Normal. 28562306a36Sopenharmony_ci * Rfsh = 1 - Local Memory Refresh to Command Delay: 12 clocks. 28662306a36Sopenharmony_ci * BwC = 1 - Local Memory Block Write Cycle Time: 2 clocks. 28762306a36Sopenharmony_ci * BwP = 1 - Local Memory Block Write to Pre-Charge Delay: 1 clock. 28862306a36Sopenharmony_ci * AP = 1 - Internal Memory Active to Pre-Charge Delay: 7 clocks. 28962306a36Sopenharmony_ci * Rst = 1 - Internal Memory Reset: Normal. 29062306a36Sopenharmony_ci * RA = 1 - Internal Memory Remain in Active State: Do not remain. 29162306a36Sopenharmony_ci */ 29262306a36Sopenharmony_ci 29362306a36Sopenharmony_ci sm501_reg = (void __iomem *)0xb3e00000 + SM501_DRAM_CONTROL; 29462306a36Sopenharmony_ci writel(readl(sm501_reg) | 0x00f107c0, sm501_reg); 29562306a36Sopenharmony_ci} 29662306a36Sopenharmony_ci 29762306a36Sopenharmony_ci/* 29862306a36Sopenharmony_ci * The Machine Vector 29962306a36Sopenharmony_ci */ 30062306a36Sopenharmony_cistatic struct sh_machine_vector mv_rts7751r2d __initmv = { 30162306a36Sopenharmony_ci .mv_name = "RTS7751R2D", 30262306a36Sopenharmony_ci .mv_setup = rts7751r2d_setup, 30362306a36Sopenharmony_ci .mv_init_irq = init_rts7751r2d_IRQ, 30462306a36Sopenharmony_ci .mv_irq_demux = rts7751r2d_irq_demux, 30562306a36Sopenharmony_ci}; 306