18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * linux/arch/arm/mach-mmp/ttc_dkb.c 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Support for the Marvell PXA910-based TTC_DKB Development Platform. 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#include <linux/init.h> 98c2ecf20Sopenharmony_ci#include <linux/kernel.h> 108c2ecf20Sopenharmony_ci#include <linux/platform_device.h> 118c2ecf20Sopenharmony_ci#include <linux/mtd/mtd.h> 128c2ecf20Sopenharmony_ci#include <linux/mtd/partitions.h> 138c2ecf20Sopenharmony_ci#include <linux/mtd/onenand.h> 148c2ecf20Sopenharmony_ci#include <linux/interrupt.h> 158c2ecf20Sopenharmony_ci#include <linux/platform_data/pca953x.h> 168c2ecf20Sopenharmony_ci#include <linux/gpio.h> 178c2ecf20Sopenharmony_ci#include <linux/gpio-pxa.h> 188c2ecf20Sopenharmony_ci#include <linux/mfd/88pm860x.h> 198c2ecf20Sopenharmony_ci#include <linux/platform_data/mv_usb.h> 208c2ecf20Sopenharmony_ci#include <linux/spi/spi.h> 218c2ecf20Sopenharmony_ci#include <linux/delay.h> 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci#include <asm/mach-types.h> 248c2ecf20Sopenharmony_ci#include <asm/mach/arch.h> 258c2ecf20Sopenharmony_ci#include <asm/mach/flash.h> 268c2ecf20Sopenharmony_ci#include "addr-map.h" 278c2ecf20Sopenharmony_ci#include "mfp-pxa910.h" 288c2ecf20Sopenharmony_ci#include "pxa910.h" 298c2ecf20Sopenharmony_ci#include "irqs.h" 308c2ecf20Sopenharmony_ci#include "regs-usb.h" 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci#include "common.h" 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci#define TTCDKB_GPIO_EXT0(x) (MMP_NR_BUILTIN_GPIO + ((x < 0) ? 0 : \ 358c2ecf20Sopenharmony_ci ((x < 16) ? x : 15))) 368c2ecf20Sopenharmony_ci#define TTCDKB_GPIO_EXT1(x) (MMP_NR_BUILTIN_GPIO + 16 + ((x < 0) ? 0 : \ 378c2ecf20Sopenharmony_ci ((x < 16) ? x : 15))) 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci/* 408c2ecf20Sopenharmony_ci * 16 board interrupts -- MAX7312 GPIO expander 418c2ecf20Sopenharmony_ci * 16 board interrupts -- PCA9575 GPIO expander 428c2ecf20Sopenharmony_ci * 24 board interrupts -- 88PM860x PMIC 438c2ecf20Sopenharmony_ci */ 448c2ecf20Sopenharmony_ci#define TTCDKB_NR_IRQS (MMP_NR_IRQS + 16 + 16 + 24) 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_cistatic unsigned long ttc_dkb_pin_config[] __initdata = { 478c2ecf20Sopenharmony_ci /* UART2 */ 488c2ecf20Sopenharmony_ci GPIO47_UART2_RXD, 498c2ecf20Sopenharmony_ci GPIO48_UART2_TXD, 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci /* DFI */ 528c2ecf20Sopenharmony_ci DF_IO0_ND_IO0, 538c2ecf20Sopenharmony_ci DF_IO1_ND_IO1, 548c2ecf20Sopenharmony_ci DF_IO2_ND_IO2, 558c2ecf20Sopenharmony_ci DF_IO3_ND_IO3, 568c2ecf20Sopenharmony_ci DF_IO4_ND_IO4, 578c2ecf20Sopenharmony_ci DF_IO5_ND_IO5, 588c2ecf20Sopenharmony_ci DF_IO6_ND_IO6, 598c2ecf20Sopenharmony_ci DF_IO7_ND_IO7, 608c2ecf20Sopenharmony_ci DF_IO8_ND_IO8, 618c2ecf20Sopenharmony_ci DF_IO9_ND_IO9, 628c2ecf20Sopenharmony_ci DF_IO10_ND_IO10, 638c2ecf20Sopenharmony_ci DF_IO11_ND_IO11, 648c2ecf20Sopenharmony_ci DF_IO12_ND_IO12, 658c2ecf20Sopenharmony_ci DF_IO13_ND_IO13, 668c2ecf20Sopenharmony_ci DF_IO14_ND_IO14, 678c2ecf20Sopenharmony_ci DF_IO15_ND_IO15, 688c2ecf20Sopenharmony_ci DF_nCS0_SM_nCS2_nCS0, 698c2ecf20Sopenharmony_ci DF_ALE_SM_WEn_ND_ALE, 708c2ecf20Sopenharmony_ci DF_CLE_SM_OEn_ND_CLE, 718c2ecf20Sopenharmony_ci DF_WEn_DF_WEn, 728c2ecf20Sopenharmony_ci DF_REn_DF_REn, 738c2ecf20Sopenharmony_ci DF_RDY0_DF_RDY0, 748c2ecf20Sopenharmony_ci}; 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_cistatic struct pxa_gpio_platform_data pxa910_gpio_pdata = { 778c2ecf20Sopenharmony_ci .irq_base = MMP_GPIO_TO_IRQ(0), 788c2ecf20Sopenharmony_ci}; 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_cistatic struct mtd_partition ttc_dkb_onenand_partitions[] = { 818c2ecf20Sopenharmony_ci { 828c2ecf20Sopenharmony_ci .name = "bootloader", 838c2ecf20Sopenharmony_ci .offset = 0, 848c2ecf20Sopenharmony_ci .size = SZ_1M, 858c2ecf20Sopenharmony_ci .mask_flags = MTD_WRITEABLE, 868c2ecf20Sopenharmony_ci }, { 878c2ecf20Sopenharmony_ci .name = "reserved", 888c2ecf20Sopenharmony_ci .offset = MTDPART_OFS_APPEND, 898c2ecf20Sopenharmony_ci .size = SZ_128K, 908c2ecf20Sopenharmony_ci .mask_flags = MTD_WRITEABLE, 918c2ecf20Sopenharmony_ci }, { 928c2ecf20Sopenharmony_ci .name = "reserved", 938c2ecf20Sopenharmony_ci .offset = MTDPART_OFS_APPEND, 948c2ecf20Sopenharmony_ci .size = SZ_8M, 958c2ecf20Sopenharmony_ci .mask_flags = MTD_WRITEABLE, 968c2ecf20Sopenharmony_ci }, { 978c2ecf20Sopenharmony_ci .name = "kernel", 988c2ecf20Sopenharmony_ci .offset = MTDPART_OFS_APPEND, 998c2ecf20Sopenharmony_ci .size = (SZ_2M + SZ_1M), 1008c2ecf20Sopenharmony_ci .mask_flags = 0, 1018c2ecf20Sopenharmony_ci }, { 1028c2ecf20Sopenharmony_ci .name = "filesystem", 1038c2ecf20Sopenharmony_ci .offset = MTDPART_OFS_APPEND, 1048c2ecf20Sopenharmony_ci .size = SZ_32M + SZ_16M, 1058c2ecf20Sopenharmony_ci .mask_flags = 0, 1068c2ecf20Sopenharmony_ci } 1078c2ecf20Sopenharmony_ci}; 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_cistatic struct onenand_platform_data ttc_dkb_onenand_info = { 1108c2ecf20Sopenharmony_ci .parts = ttc_dkb_onenand_partitions, 1118c2ecf20Sopenharmony_ci .nr_parts = ARRAY_SIZE(ttc_dkb_onenand_partitions), 1128c2ecf20Sopenharmony_ci}; 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_cistatic struct resource ttc_dkb_resource_onenand[] = { 1158c2ecf20Sopenharmony_ci [0] = { 1168c2ecf20Sopenharmony_ci .start = SMC_CS0_PHYS_BASE, 1178c2ecf20Sopenharmony_ci .end = SMC_CS0_PHYS_BASE + SZ_1M, 1188c2ecf20Sopenharmony_ci .flags = IORESOURCE_MEM, 1198c2ecf20Sopenharmony_ci }, 1208c2ecf20Sopenharmony_ci}; 1218c2ecf20Sopenharmony_ci 1228c2ecf20Sopenharmony_cistatic struct platform_device ttc_dkb_device_onenand = { 1238c2ecf20Sopenharmony_ci .name = "onenand-flash", 1248c2ecf20Sopenharmony_ci .id = -1, 1258c2ecf20Sopenharmony_ci .resource = ttc_dkb_resource_onenand, 1268c2ecf20Sopenharmony_ci .num_resources = ARRAY_SIZE(ttc_dkb_resource_onenand), 1278c2ecf20Sopenharmony_ci .dev = { 1288c2ecf20Sopenharmony_ci .platform_data = &ttc_dkb_onenand_info, 1298c2ecf20Sopenharmony_ci }, 1308c2ecf20Sopenharmony_ci}; 1318c2ecf20Sopenharmony_ci 1328c2ecf20Sopenharmony_cistatic struct platform_device *ttc_dkb_devices[] = { 1338c2ecf20Sopenharmony_ci &pxa910_device_gpio, 1348c2ecf20Sopenharmony_ci &pxa910_device_rtc, 1358c2ecf20Sopenharmony_ci &ttc_dkb_device_onenand, 1368c2ecf20Sopenharmony_ci}; 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_cistatic struct pca953x_platform_data max7312_data[] = { 1398c2ecf20Sopenharmony_ci { 1408c2ecf20Sopenharmony_ci .gpio_base = TTCDKB_GPIO_EXT0(0), 1418c2ecf20Sopenharmony_ci .irq_base = MMP_NR_IRQS, 1428c2ecf20Sopenharmony_ci }, 1438c2ecf20Sopenharmony_ci}; 1448c2ecf20Sopenharmony_ci 1458c2ecf20Sopenharmony_cistatic struct pm860x_platform_data ttc_dkb_pm8607_info = { 1468c2ecf20Sopenharmony_ci .irq_base = IRQ_BOARD_START, 1478c2ecf20Sopenharmony_ci}; 1488c2ecf20Sopenharmony_ci 1498c2ecf20Sopenharmony_cistatic struct i2c_board_info ttc_dkb_i2c_info[] = { 1508c2ecf20Sopenharmony_ci { 1518c2ecf20Sopenharmony_ci .type = "88PM860x", 1528c2ecf20Sopenharmony_ci .addr = 0x34, 1538c2ecf20Sopenharmony_ci .platform_data = &ttc_dkb_pm8607_info, 1548c2ecf20Sopenharmony_ci .irq = IRQ_PXA910_PMIC_INT, 1558c2ecf20Sopenharmony_ci }, 1568c2ecf20Sopenharmony_ci { 1578c2ecf20Sopenharmony_ci .type = "max7312", 1588c2ecf20Sopenharmony_ci .addr = 0x23, 1598c2ecf20Sopenharmony_ci .irq = MMP_GPIO_TO_IRQ(80), 1608c2ecf20Sopenharmony_ci .platform_data = &max7312_data, 1618c2ecf20Sopenharmony_ci }, 1628c2ecf20Sopenharmony_ci}; 1638c2ecf20Sopenharmony_ci 1648c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_USB_SUPPORT) 1658c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_USB_MV_UDC) || IS_ENABLED(CONFIG_USB_EHCI_MV_U2O) 1668c2ecf20Sopenharmony_ci 1678c2ecf20Sopenharmony_cistatic struct mv_usb_platform_data ttc_usb_pdata = { 1688c2ecf20Sopenharmony_ci .vbus = NULL, 1698c2ecf20Sopenharmony_ci .mode = MV_USB_MODE_OTG, 1708c2ecf20Sopenharmony_ci .otg_force_a_bus_req = 1, 1718c2ecf20Sopenharmony_ci .phy_init = pxa_usb_phy_init, 1728c2ecf20Sopenharmony_ci .phy_deinit = pxa_usb_phy_deinit, 1738c2ecf20Sopenharmony_ci .set_vbus = NULL, 1748c2ecf20Sopenharmony_ci}; 1758c2ecf20Sopenharmony_ci#endif 1768c2ecf20Sopenharmony_ci#endif 1778c2ecf20Sopenharmony_ci 1788c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_MTD_NAND_MARVELL) 1798c2ecf20Sopenharmony_cistatic struct pxa3xx_nand_platform_data dkb_nand_info = {}; 1808c2ecf20Sopenharmony_ci#endif 1818c2ecf20Sopenharmony_ci 1828c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_MMP_DISP) 1838c2ecf20Sopenharmony_ci/* path config */ 1848c2ecf20Sopenharmony_ci#define CFG_IOPADMODE(iopad) (iopad) /* 0x0 ~ 0xd */ 1858c2ecf20Sopenharmony_ci#define SCLK_SOURCE_SELECT(x) (x << 30) /* 0x0 ~ 0x3 */ 1868c2ecf20Sopenharmony_ci/* link config */ 1878c2ecf20Sopenharmony_ci#define CFG_DUMBMODE(mode) (mode << 28) /* 0x0 ~ 0x6*/ 1888c2ecf20Sopenharmony_cistatic struct mmp_mach_path_config dkb_disp_config[] = { 1898c2ecf20Sopenharmony_ci [0] = { 1908c2ecf20Sopenharmony_ci .name = "mmp-parallel", 1918c2ecf20Sopenharmony_ci .overlay_num = 2, 1928c2ecf20Sopenharmony_ci .output_type = PATH_OUT_PARALLEL, 1938c2ecf20Sopenharmony_ci .path_config = CFG_IOPADMODE(0x1) 1948c2ecf20Sopenharmony_ci | SCLK_SOURCE_SELECT(0x1), 1958c2ecf20Sopenharmony_ci .link_config = CFG_DUMBMODE(0x2), 1968c2ecf20Sopenharmony_ci }, 1978c2ecf20Sopenharmony_ci}; 1988c2ecf20Sopenharmony_ci 1998c2ecf20Sopenharmony_cistatic struct mmp_mach_plat_info dkb_disp_info = { 2008c2ecf20Sopenharmony_ci .name = "mmp-disp", 2018c2ecf20Sopenharmony_ci .clk_name = "disp0", 2028c2ecf20Sopenharmony_ci .path_num = 1, 2038c2ecf20Sopenharmony_ci .paths = dkb_disp_config, 2048c2ecf20Sopenharmony_ci}; 2058c2ecf20Sopenharmony_ci 2068c2ecf20Sopenharmony_cistatic struct mmp_buffer_driver_mach_info dkb_fb_info = { 2078c2ecf20Sopenharmony_ci .name = "mmp-fb", 2088c2ecf20Sopenharmony_ci .path_name = "mmp-parallel", 2098c2ecf20Sopenharmony_ci .overlay_id = 0, 2108c2ecf20Sopenharmony_ci .dmafetch_id = 1, 2118c2ecf20Sopenharmony_ci .default_pixfmt = PIXFMT_RGB565, 2128c2ecf20Sopenharmony_ci}; 2138c2ecf20Sopenharmony_ci 2148c2ecf20Sopenharmony_cistatic void dkb_tpo_panel_power(int on) 2158c2ecf20Sopenharmony_ci{ 2168c2ecf20Sopenharmony_ci int err; 2178c2ecf20Sopenharmony_ci u32 spi_reset = mfp_to_gpio(MFP_PIN_GPIO106); 2188c2ecf20Sopenharmony_ci 2198c2ecf20Sopenharmony_ci if (on) { 2208c2ecf20Sopenharmony_ci err = gpio_request(spi_reset, "TPO_LCD_SPI_RESET"); 2218c2ecf20Sopenharmony_ci if (err) { 2228c2ecf20Sopenharmony_ci pr_err("failed to request GPIO for TPO LCD RESET\n"); 2238c2ecf20Sopenharmony_ci return; 2248c2ecf20Sopenharmony_ci } 2258c2ecf20Sopenharmony_ci gpio_direction_output(spi_reset, 0); 2268c2ecf20Sopenharmony_ci udelay(100); 2278c2ecf20Sopenharmony_ci gpio_set_value(spi_reset, 1); 2288c2ecf20Sopenharmony_ci gpio_free(spi_reset); 2298c2ecf20Sopenharmony_ci } else { 2308c2ecf20Sopenharmony_ci err = gpio_request(spi_reset, "TPO_LCD_SPI_RESET"); 2318c2ecf20Sopenharmony_ci if (err) { 2328c2ecf20Sopenharmony_ci pr_err("failed to request LCD RESET gpio\n"); 2338c2ecf20Sopenharmony_ci return; 2348c2ecf20Sopenharmony_ci } 2358c2ecf20Sopenharmony_ci gpio_set_value(spi_reset, 0); 2368c2ecf20Sopenharmony_ci gpio_free(spi_reset); 2378c2ecf20Sopenharmony_ci } 2388c2ecf20Sopenharmony_ci} 2398c2ecf20Sopenharmony_ci 2408c2ecf20Sopenharmony_cistatic struct mmp_mach_panel_info dkb_tpo_panel_info = { 2418c2ecf20Sopenharmony_ci .name = "tpo-hvga", 2428c2ecf20Sopenharmony_ci .plat_path_name = "mmp-parallel", 2438c2ecf20Sopenharmony_ci .plat_set_onoff = dkb_tpo_panel_power, 2448c2ecf20Sopenharmony_ci}; 2458c2ecf20Sopenharmony_ci 2468c2ecf20Sopenharmony_cistatic struct spi_board_info spi_board_info[] __initdata = { 2478c2ecf20Sopenharmony_ci { 2488c2ecf20Sopenharmony_ci .modalias = "tpo-hvga", 2498c2ecf20Sopenharmony_ci .platform_data = &dkb_tpo_panel_info, 2508c2ecf20Sopenharmony_ci .bus_num = 5, 2518c2ecf20Sopenharmony_ci } 2528c2ecf20Sopenharmony_ci}; 2538c2ecf20Sopenharmony_ci 2548c2ecf20Sopenharmony_cistatic void __init add_disp(void) 2558c2ecf20Sopenharmony_ci{ 2568c2ecf20Sopenharmony_ci pxa_register_device(&pxa910_device_disp, 2578c2ecf20Sopenharmony_ci &dkb_disp_info, sizeof(dkb_disp_info)); 2588c2ecf20Sopenharmony_ci spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info)); 2598c2ecf20Sopenharmony_ci pxa_register_device(&pxa910_device_fb, 2608c2ecf20Sopenharmony_ci &dkb_fb_info, sizeof(dkb_fb_info)); 2618c2ecf20Sopenharmony_ci pxa_register_device(&pxa910_device_panel, 2628c2ecf20Sopenharmony_ci &dkb_tpo_panel_info, sizeof(dkb_tpo_panel_info)); 2638c2ecf20Sopenharmony_ci} 2648c2ecf20Sopenharmony_ci#endif 2658c2ecf20Sopenharmony_ci 2668c2ecf20Sopenharmony_cistatic void __init ttc_dkb_init(void) 2678c2ecf20Sopenharmony_ci{ 2688c2ecf20Sopenharmony_ci mfp_config(ARRAY_AND_SIZE(ttc_dkb_pin_config)); 2698c2ecf20Sopenharmony_ci 2708c2ecf20Sopenharmony_ci /* on-chip devices */ 2718c2ecf20Sopenharmony_ci pxa910_add_uart(1); 2728c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_MTD_NAND_MARVELL) 2738c2ecf20Sopenharmony_ci pxa910_add_nand(&dkb_nand_info); 2748c2ecf20Sopenharmony_ci#endif 2758c2ecf20Sopenharmony_ci 2768c2ecf20Sopenharmony_ci /* off-chip devices */ 2778c2ecf20Sopenharmony_ci pxa910_add_twsi(0, NULL, ARRAY_AND_SIZE(ttc_dkb_i2c_info)); 2788c2ecf20Sopenharmony_ci platform_device_add_data(&pxa910_device_gpio, &pxa910_gpio_pdata, 2798c2ecf20Sopenharmony_ci sizeof(struct pxa_gpio_platform_data)); 2808c2ecf20Sopenharmony_ci platform_add_devices(ARRAY_AND_SIZE(ttc_dkb_devices)); 2818c2ecf20Sopenharmony_ci 2828c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_USB_SUPPORT) 2838c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_PHY_PXA_USB) 2848c2ecf20Sopenharmony_ci platform_device_register(&pxa168_device_usb_phy); 2858c2ecf20Sopenharmony_ci#endif 2868c2ecf20Sopenharmony_ci 2878c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_USB_MV_UDC) 2888c2ecf20Sopenharmony_ci pxa168_device_u2o.dev.platform_data = &ttc_usb_pdata; 2898c2ecf20Sopenharmony_ci platform_device_register(&pxa168_device_u2o); 2908c2ecf20Sopenharmony_ci#endif 2918c2ecf20Sopenharmony_ci 2928c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_USB_EHCI_MV_U2O) 2938c2ecf20Sopenharmony_ci pxa168_device_u2oehci.dev.platform_data = &ttc_usb_pdata; 2948c2ecf20Sopenharmony_ci platform_device_register(&pxa168_device_u2oehci); 2958c2ecf20Sopenharmony_ci#endif 2968c2ecf20Sopenharmony_ci 2978c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_USB_MV_OTG) 2988c2ecf20Sopenharmony_ci pxa168_device_u2ootg.dev.platform_data = &ttc_usb_pdata; 2998c2ecf20Sopenharmony_ci platform_device_register(&pxa168_device_u2ootg); 3008c2ecf20Sopenharmony_ci#endif 3018c2ecf20Sopenharmony_ci#endif 3028c2ecf20Sopenharmony_ci 3038c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_MMP_DISP) 3048c2ecf20Sopenharmony_ci add_disp(); 3058c2ecf20Sopenharmony_ci#endif 3068c2ecf20Sopenharmony_ci} 3078c2ecf20Sopenharmony_ci 3088c2ecf20Sopenharmony_ciMACHINE_START(TTC_DKB, "PXA910-based TTC_DKB Development Platform") 3098c2ecf20Sopenharmony_ci .map_io = mmp_map_io, 3108c2ecf20Sopenharmony_ci .nr_irqs = TTCDKB_NR_IRQS, 3118c2ecf20Sopenharmony_ci .init_irq = pxa910_init_irq, 3128c2ecf20Sopenharmony_ci .init_time = pxa910_timer_init, 3138c2ecf20Sopenharmony_ci .init_machine = ttc_dkb_init, 3148c2ecf20Sopenharmony_ci .restart = mmp_restart, 3158c2ecf20Sopenharmony_ciMACHINE_END 316