18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Renesas - AP-325RXA
48c2ecf20Sopenharmony_ci * (Compatible with Algo System ., LTD. - AP-320A)
58c2ecf20Sopenharmony_ci *
68c2ecf20Sopenharmony_ci * Copyright (C) 2008 Renesas Solutions Corp.
78c2ecf20Sopenharmony_ci * Author : Yusuke Goda <goda.yuske@renesas.com>
88c2ecf20Sopenharmony_ci */
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci#include <asm/clock.h>
118c2ecf20Sopenharmony_ci#include <asm/io.h>
128c2ecf20Sopenharmony_ci#include <asm/suspend.h>
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ci#include <cpu/sh7723.h>
158c2ecf20Sopenharmony_ci
168c2ecf20Sopenharmony_ci#include <linux/dma-map-ops.h>
178c2ecf20Sopenharmony_ci#include <linux/clkdev.h>
188c2ecf20Sopenharmony_ci#include <linux/delay.h>
198c2ecf20Sopenharmony_ci#include <linux/device.h>
208c2ecf20Sopenharmony_ci#include <linux/gpio.h>
218c2ecf20Sopenharmony_ci#include <linux/gpio/machine.h>
228c2ecf20Sopenharmony_ci#include <linux/i2c.h>
238c2ecf20Sopenharmony_ci#include <linux/init.h>
248c2ecf20Sopenharmony_ci#include <linux/interrupt.h>
258c2ecf20Sopenharmony_ci#include <linux/memblock.h>
268c2ecf20Sopenharmony_ci#include <linux/mfd/tmio.h>
278c2ecf20Sopenharmony_ci#include <linux/mmc/host.h>
288c2ecf20Sopenharmony_ci#include <linux/mtd/physmap.h>
298c2ecf20Sopenharmony_ci#include <linux/mtd/sh_flctl.h>
308c2ecf20Sopenharmony_ci#include <linux/platform_device.h>
318c2ecf20Sopenharmony_ci#include <linux/regulator/fixed.h>
328c2ecf20Sopenharmony_ci#include <linux/regulator/machine.h>
338c2ecf20Sopenharmony_ci#include <linux/sh_intc.h>
348c2ecf20Sopenharmony_ci#include <linux/smsc911x.h>
358c2ecf20Sopenharmony_ci#include <linux/videodev2.h>
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ci#include <media/drv-intf/renesas-ceu.h>
388c2ecf20Sopenharmony_ci#include <media/i2c/ov772x.h>
398c2ecf20Sopenharmony_ci
408c2ecf20Sopenharmony_ci#include <video/sh_mobile_lcdc.h>
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ci#define CEU_BUFFER_MEMORY_SIZE		(4 << 20)
438c2ecf20Sopenharmony_cistatic phys_addr_t ceu_dma_membase;
448c2ecf20Sopenharmony_ci
458c2ecf20Sopenharmony_ci/* Dummy supplies, where voltage doesn't matter */
468c2ecf20Sopenharmony_cistatic struct regulator_consumer_supply dummy_supplies[] = {
478c2ecf20Sopenharmony_ci	REGULATOR_SUPPLY("vddvario", "smsc911x"),
488c2ecf20Sopenharmony_ci	REGULATOR_SUPPLY("vdd33a", "smsc911x"),
498c2ecf20Sopenharmony_ci};
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_cistatic struct smsc911x_platform_config smsc911x_config = {
528c2ecf20Sopenharmony_ci	.phy_interface	= PHY_INTERFACE_MODE_MII,
538c2ecf20Sopenharmony_ci	.irq_polarity	= SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
548c2ecf20Sopenharmony_ci	.irq_type	= SMSC911X_IRQ_TYPE_OPEN_DRAIN,
558c2ecf20Sopenharmony_ci	.flags		= SMSC911X_USE_32BIT,
568c2ecf20Sopenharmony_ci};
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_cistatic struct resource smsc9118_resources[] = {
598c2ecf20Sopenharmony_ci	[0] = {
608c2ecf20Sopenharmony_ci		.start	= 0xb6080000,
618c2ecf20Sopenharmony_ci		.end	= 0xb60fffff,
628c2ecf20Sopenharmony_ci		.flags	= IORESOURCE_MEM,
638c2ecf20Sopenharmony_ci	},
648c2ecf20Sopenharmony_ci	[1] = {
658c2ecf20Sopenharmony_ci		.start	= evt2irq(0x660),
668c2ecf20Sopenharmony_ci		.end	= evt2irq(0x660),
678c2ecf20Sopenharmony_ci		.flags	= IORESOURCE_IRQ,
688c2ecf20Sopenharmony_ci	}
698c2ecf20Sopenharmony_ci};
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_cistatic struct platform_device smsc9118_device = {
728c2ecf20Sopenharmony_ci	.name		= "smsc911x",
738c2ecf20Sopenharmony_ci	.id		= -1,
748c2ecf20Sopenharmony_ci	.num_resources	= ARRAY_SIZE(smsc9118_resources),
758c2ecf20Sopenharmony_ci	.resource	= smsc9118_resources,
768c2ecf20Sopenharmony_ci	.dev		= {
778c2ecf20Sopenharmony_ci		.platform_data = &smsc911x_config,
788c2ecf20Sopenharmony_ci	},
798c2ecf20Sopenharmony_ci};
808c2ecf20Sopenharmony_ci
818c2ecf20Sopenharmony_ci/*
828c2ecf20Sopenharmony_ci * AP320 and AP325RXA has CPLD data in NOR Flash(0xA80000-0xABFFFF).
838c2ecf20Sopenharmony_ci * If this area erased, this board can not boot.
848c2ecf20Sopenharmony_ci */
858c2ecf20Sopenharmony_cistatic struct mtd_partition ap325rxa_nor_flash_partitions[] = {
868c2ecf20Sopenharmony_ci	{
878c2ecf20Sopenharmony_ci		.name = "uboot",
888c2ecf20Sopenharmony_ci		.offset = 0,
898c2ecf20Sopenharmony_ci		.size = (1 * 1024 * 1024),
908c2ecf20Sopenharmony_ci		.mask_flags = MTD_WRITEABLE,	/* Read-only */
918c2ecf20Sopenharmony_ci	}, {
928c2ecf20Sopenharmony_ci		.name = "kernel",
938c2ecf20Sopenharmony_ci		.offset = MTDPART_OFS_APPEND,
948c2ecf20Sopenharmony_ci		.size = (2 * 1024 * 1024),
958c2ecf20Sopenharmony_ci	}, {
968c2ecf20Sopenharmony_ci		.name = "free-area0",
978c2ecf20Sopenharmony_ci		.offset = MTDPART_OFS_APPEND,
988c2ecf20Sopenharmony_ci		.size = ((7 * 1024 * 1024) + (512 * 1024)),
998c2ecf20Sopenharmony_ci	}, {
1008c2ecf20Sopenharmony_ci		.name = "CPLD-Data",
1018c2ecf20Sopenharmony_ci		.offset = MTDPART_OFS_APPEND,
1028c2ecf20Sopenharmony_ci		.mask_flags = MTD_WRITEABLE,	/* Read-only */
1038c2ecf20Sopenharmony_ci		.size = (1024 * 128 * 2),
1048c2ecf20Sopenharmony_ci	}, {
1058c2ecf20Sopenharmony_ci		.name = "free-area1",
1068c2ecf20Sopenharmony_ci		.offset = MTDPART_OFS_APPEND,
1078c2ecf20Sopenharmony_ci		.size = MTDPART_SIZ_FULL,
1088c2ecf20Sopenharmony_ci	},
1098c2ecf20Sopenharmony_ci};
1108c2ecf20Sopenharmony_ci
1118c2ecf20Sopenharmony_cistatic struct physmap_flash_data ap325rxa_nor_flash_data = {
1128c2ecf20Sopenharmony_ci	.width		= 2,
1138c2ecf20Sopenharmony_ci	.parts		= ap325rxa_nor_flash_partitions,
1148c2ecf20Sopenharmony_ci	.nr_parts	= ARRAY_SIZE(ap325rxa_nor_flash_partitions),
1158c2ecf20Sopenharmony_ci};
1168c2ecf20Sopenharmony_ci
1178c2ecf20Sopenharmony_cistatic struct resource ap325rxa_nor_flash_resources[] = {
1188c2ecf20Sopenharmony_ci	[0] = {
1198c2ecf20Sopenharmony_ci		.name	= "NOR Flash",
1208c2ecf20Sopenharmony_ci		.start	= 0x00000000,
1218c2ecf20Sopenharmony_ci		.end	= 0x00ffffff,
1228c2ecf20Sopenharmony_ci		.flags	= IORESOURCE_MEM,
1238c2ecf20Sopenharmony_ci	}
1248c2ecf20Sopenharmony_ci};
1258c2ecf20Sopenharmony_ci
1268c2ecf20Sopenharmony_cistatic struct platform_device ap325rxa_nor_flash_device = {
1278c2ecf20Sopenharmony_ci	.name		= "physmap-flash",
1288c2ecf20Sopenharmony_ci	.resource	= ap325rxa_nor_flash_resources,
1298c2ecf20Sopenharmony_ci	.num_resources	= ARRAY_SIZE(ap325rxa_nor_flash_resources),
1308c2ecf20Sopenharmony_ci	.dev		= {
1318c2ecf20Sopenharmony_ci		.platform_data = &ap325rxa_nor_flash_data,
1328c2ecf20Sopenharmony_ci	},
1338c2ecf20Sopenharmony_ci};
1348c2ecf20Sopenharmony_ci
1358c2ecf20Sopenharmony_cistatic struct mtd_partition nand_partition_info[] = {
1368c2ecf20Sopenharmony_ci	{
1378c2ecf20Sopenharmony_ci		.name	= "nand_data",
1388c2ecf20Sopenharmony_ci		.offset	= 0,
1398c2ecf20Sopenharmony_ci		.size	= MTDPART_SIZ_FULL,
1408c2ecf20Sopenharmony_ci	},
1418c2ecf20Sopenharmony_ci};
1428c2ecf20Sopenharmony_ci
1438c2ecf20Sopenharmony_cistatic struct resource nand_flash_resources[] = {
1448c2ecf20Sopenharmony_ci	[0] = {
1458c2ecf20Sopenharmony_ci		.start	= 0xa4530000,
1468c2ecf20Sopenharmony_ci		.end	= 0xa45300ff,
1478c2ecf20Sopenharmony_ci		.flags	= IORESOURCE_MEM,
1488c2ecf20Sopenharmony_ci	}
1498c2ecf20Sopenharmony_ci};
1508c2ecf20Sopenharmony_ci
1518c2ecf20Sopenharmony_cistatic struct sh_flctl_platform_data nand_flash_data = {
1528c2ecf20Sopenharmony_ci	.parts		= nand_partition_info,
1538c2ecf20Sopenharmony_ci	.nr_parts	= ARRAY_SIZE(nand_partition_info),
1548c2ecf20Sopenharmony_ci	.flcmncr_val	= FCKSEL_E | TYPESEL_SET | NANWF_E,
1558c2ecf20Sopenharmony_ci	.has_hwecc	= 1,
1568c2ecf20Sopenharmony_ci};
1578c2ecf20Sopenharmony_ci
1588c2ecf20Sopenharmony_cistatic struct platform_device nand_flash_device = {
1598c2ecf20Sopenharmony_ci	.name		= "sh_flctl",
1608c2ecf20Sopenharmony_ci	.resource	= nand_flash_resources,
1618c2ecf20Sopenharmony_ci	.num_resources	= ARRAY_SIZE(nand_flash_resources),
1628c2ecf20Sopenharmony_ci	.dev		= {
1638c2ecf20Sopenharmony_ci		.platform_data = &nand_flash_data,
1648c2ecf20Sopenharmony_ci	},
1658c2ecf20Sopenharmony_ci};
1668c2ecf20Sopenharmony_ci
1678c2ecf20Sopenharmony_ci#define FPGA_LCDREG	0xB4100180
1688c2ecf20Sopenharmony_ci#define FPGA_BKLREG	0xB4100212
1698c2ecf20Sopenharmony_ci#define FPGA_LCDREG_VAL	0x0018
1708c2ecf20Sopenharmony_ci#define PORT_MSELCRB	0xA4050182
1718c2ecf20Sopenharmony_ci#define PORT_HIZCRC	0xA405015C
1728c2ecf20Sopenharmony_ci#define PORT_DRVCRA	0xA405018A
1738c2ecf20Sopenharmony_ci#define PORT_DRVCRB	0xA405018C
1748c2ecf20Sopenharmony_ci
1758c2ecf20Sopenharmony_cistatic int ap320_wvga_set_brightness(int brightness)
1768c2ecf20Sopenharmony_ci{
1778c2ecf20Sopenharmony_ci	if (brightness) {
1788c2ecf20Sopenharmony_ci		gpio_set_value(GPIO_PTS3, 0);
1798c2ecf20Sopenharmony_ci		__raw_writew(0x100, FPGA_BKLREG);
1808c2ecf20Sopenharmony_ci	} else {
1818c2ecf20Sopenharmony_ci		__raw_writew(0, FPGA_BKLREG);
1828c2ecf20Sopenharmony_ci		gpio_set_value(GPIO_PTS3, 1);
1838c2ecf20Sopenharmony_ci	}
1848c2ecf20Sopenharmony_ci
1858c2ecf20Sopenharmony_ci	return 0;
1868c2ecf20Sopenharmony_ci}
1878c2ecf20Sopenharmony_ci
1888c2ecf20Sopenharmony_cistatic void ap320_wvga_power_on(void)
1898c2ecf20Sopenharmony_ci{
1908c2ecf20Sopenharmony_ci	msleep(100);
1918c2ecf20Sopenharmony_ci
1928c2ecf20Sopenharmony_ci	/* ASD AP-320/325 LCD ON */
1938c2ecf20Sopenharmony_ci	__raw_writew(FPGA_LCDREG_VAL, FPGA_LCDREG);
1948c2ecf20Sopenharmony_ci}
1958c2ecf20Sopenharmony_ci
1968c2ecf20Sopenharmony_cistatic void ap320_wvga_power_off(void)
1978c2ecf20Sopenharmony_ci{
1988c2ecf20Sopenharmony_ci	/* ASD AP-320/325 LCD OFF */
1998c2ecf20Sopenharmony_ci	__raw_writew(0, FPGA_LCDREG);
2008c2ecf20Sopenharmony_ci}
2018c2ecf20Sopenharmony_ci
2028c2ecf20Sopenharmony_cistatic const struct fb_videomode ap325rxa_lcdc_modes[] = {
2038c2ecf20Sopenharmony_ci	{
2048c2ecf20Sopenharmony_ci		.name = "LB070WV1",
2058c2ecf20Sopenharmony_ci		.xres = 800,
2068c2ecf20Sopenharmony_ci		.yres = 480,
2078c2ecf20Sopenharmony_ci		.left_margin = 32,
2088c2ecf20Sopenharmony_ci		.right_margin = 160,
2098c2ecf20Sopenharmony_ci		.hsync_len = 8,
2108c2ecf20Sopenharmony_ci		.upper_margin = 63,
2118c2ecf20Sopenharmony_ci		.lower_margin = 80,
2128c2ecf20Sopenharmony_ci		.vsync_len = 1,
2138c2ecf20Sopenharmony_ci		.sync = 0, /* hsync and vsync are active low */
2148c2ecf20Sopenharmony_ci	},
2158c2ecf20Sopenharmony_ci};
2168c2ecf20Sopenharmony_ci
2178c2ecf20Sopenharmony_cistatic struct sh_mobile_lcdc_info lcdc_info = {
2188c2ecf20Sopenharmony_ci	.clock_source = LCDC_CLK_EXTERNAL,
2198c2ecf20Sopenharmony_ci	.ch[0] = {
2208c2ecf20Sopenharmony_ci		.chan = LCDC_CHAN_MAINLCD,
2218c2ecf20Sopenharmony_ci		.fourcc = V4L2_PIX_FMT_RGB565,
2228c2ecf20Sopenharmony_ci		.interface_type = RGB18,
2238c2ecf20Sopenharmony_ci		.clock_divider = 1,
2248c2ecf20Sopenharmony_ci		.lcd_modes = ap325rxa_lcdc_modes,
2258c2ecf20Sopenharmony_ci		.num_modes = ARRAY_SIZE(ap325rxa_lcdc_modes),
2268c2ecf20Sopenharmony_ci		.panel_cfg = {
2278c2ecf20Sopenharmony_ci			.width = 152,	/* 7.0 inch */
2288c2ecf20Sopenharmony_ci			.height = 91,
2298c2ecf20Sopenharmony_ci			.display_on = ap320_wvga_power_on,
2308c2ecf20Sopenharmony_ci			.display_off = ap320_wvga_power_off,
2318c2ecf20Sopenharmony_ci		},
2328c2ecf20Sopenharmony_ci		.bl_info = {
2338c2ecf20Sopenharmony_ci			.name = "sh_mobile_lcdc_bl",
2348c2ecf20Sopenharmony_ci			.max_brightness = 1,
2358c2ecf20Sopenharmony_ci			.set_brightness = ap320_wvga_set_brightness,
2368c2ecf20Sopenharmony_ci		},
2378c2ecf20Sopenharmony_ci	}
2388c2ecf20Sopenharmony_ci};
2398c2ecf20Sopenharmony_ci
2408c2ecf20Sopenharmony_cistatic struct resource lcdc_resources[] = {
2418c2ecf20Sopenharmony_ci	[0] = {
2428c2ecf20Sopenharmony_ci		.name	= "LCDC",
2438c2ecf20Sopenharmony_ci		.start	= 0xfe940000, /* P4-only space */
2448c2ecf20Sopenharmony_ci		.end	= 0xfe942fff,
2458c2ecf20Sopenharmony_ci		.flags	= IORESOURCE_MEM,
2468c2ecf20Sopenharmony_ci	},
2478c2ecf20Sopenharmony_ci	[1] = {
2488c2ecf20Sopenharmony_ci		.start	= evt2irq(0x580),
2498c2ecf20Sopenharmony_ci		.flags	= IORESOURCE_IRQ,
2508c2ecf20Sopenharmony_ci	},
2518c2ecf20Sopenharmony_ci};
2528c2ecf20Sopenharmony_ci
2538c2ecf20Sopenharmony_cistatic struct platform_device lcdc_device = {
2548c2ecf20Sopenharmony_ci	.name		= "sh_mobile_lcdc_fb",
2558c2ecf20Sopenharmony_ci	.num_resources	= ARRAY_SIZE(lcdc_resources),
2568c2ecf20Sopenharmony_ci	.resource	= lcdc_resources,
2578c2ecf20Sopenharmony_ci	.dev		= {
2588c2ecf20Sopenharmony_ci		.platform_data	= &lcdc_info,
2598c2ecf20Sopenharmony_ci	},
2608c2ecf20Sopenharmony_ci};
2618c2ecf20Sopenharmony_ci
2628c2ecf20Sopenharmony_ci/* Powerdown/reset gpios for CEU image sensors */
2638c2ecf20Sopenharmony_cistatic struct gpiod_lookup_table ov7725_gpios = {
2648c2ecf20Sopenharmony_ci	.dev_id		= "0-0021",
2658c2ecf20Sopenharmony_ci	.table		= {
2668c2ecf20Sopenharmony_ci		GPIO_LOOKUP("sh7723_pfc", GPIO_PTZ5, "reset", GPIO_ACTIVE_LOW),
2678c2ecf20Sopenharmony_ci	},
2688c2ecf20Sopenharmony_ci};
2698c2ecf20Sopenharmony_ci
2708c2ecf20Sopenharmony_cistatic struct ceu_platform_data ceu0_pdata = {
2718c2ecf20Sopenharmony_ci	.num_subdevs			= 1,
2728c2ecf20Sopenharmony_ci	.subdevs = {
2738c2ecf20Sopenharmony_ci		{ /* [0] = ov7725  */
2748c2ecf20Sopenharmony_ci			.flags		= 0,
2758c2ecf20Sopenharmony_ci			.bus_width	= 8,
2768c2ecf20Sopenharmony_ci			.bus_shift	= 0,
2778c2ecf20Sopenharmony_ci			.i2c_adapter_id	= 0,
2788c2ecf20Sopenharmony_ci			.i2c_address	= 0x21,
2798c2ecf20Sopenharmony_ci		},
2808c2ecf20Sopenharmony_ci	},
2818c2ecf20Sopenharmony_ci};
2828c2ecf20Sopenharmony_ci
2838c2ecf20Sopenharmony_cistatic struct resource ceu_resources[] = {
2848c2ecf20Sopenharmony_ci	[0] = {
2858c2ecf20Sopenharmony_ci		.name	= "CEU",
2868c2ecf20Sopenharmony_ci		.start	= 0xfe910000,
2878c2ecf20Sopenharmony_ci		.end	= 0xfe91009f,
2888c2ecf20Sopenharmony_ci		.flags	= IORESOURCE_MEM,
2898c2ecf20Sopenharmony_ci	},
2908c2ecf20Sopenharmony_ci	[1] = {
2918c2ecf20Sopenharmony_ci		.start  = evt2irq(0x880),
2928c2ecf20Sopenharmony_ci		.flags  = IORESOURCE_IRQ,
2938c2ecf20Sopenharmony_ci	},
2948c2ecf20Sopenharmony_ci};
2958c2ecf20Sopenharmony_ci
2968c2ecf20Sopenharmony_cistatic struct platform_device ap325rxa_ceu_device = {
2978c2ecf20Sopenharmony_ci	.name		= "renesas-ceu",
2988c2ecf20Sopenharmony_ci	.id             = 0, /* "ceu.0" clock */
2998c2ecf20Sopenharmony_ci	.num_resources	= ARRAY_SIZE(ceu_resources),
3008c2ecf20Sopenharmony_ci	.resource	= ceu_resources,
3018c2ecf20Sopenharmony_ci	.dev		= {
3028c2ecf20Sopenharmony_ci		.platform_data	= &ceu0_pdata,
3038c2ecf20Sopenharmony_ci	},
3048c2ecf20Sopenharmony_ci};
3058c2ecf20Sopenharmony_ci
3068c2ecf20Sopenharmony_ci/* Fixed 3.3V regulators to be used by SDHI0, SDHI1 */
3078c2ecf20Sopenharmony_cistatic struct regulator_consumer_supply fixed3v3_power_consumers[] =
3088c2ecf20Sopenharmony_ci{
3098c2ecf20Sopenharmony_ci	REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"),
3108c2ecf20Sopenharmony_ci	REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.0"),
3118c2ecf20Sopenharmony_ci	REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.1"),
3128c2ecf20Sopenharmony_ci	REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.1"),
3138c2ecf20Sopenharmony_ci};
3148c2ecf20Sopenharmony_ci
3158c2ecf20Sopenharmony_cistatic struct resource sdhi0_cn3_resources[] = {
3168c2ecf20Sopenharmony_ci	[0] = {
3178c2ecf20Sopenharmony_ci		.name	= "SDHI0",
3188c2ecf20Sopenharmony_ci		.start	= 0x04ce0000,
3198c2ecf20Sopenharmony_ci		.end	= 0x04ce00ff,
3208c2ecf20Sopenharmony_ci		.flags	= IORESOURCE_MEM,
3218c2ecf20Sopenharmony_ci	},
3228c2ecf20Sopenharmony_ci	[1] = {
3238c2ecf20Sopenharmony_ci		.start	= evt2irq(0xe80),
3248c2ecf20Sopenharmony_ci		.flags  = IORESOURCE_IRQ,
3258c2ecf20Sopenharmony_ci	},
3268c2ecf20Sopenharmony_ci};
3278c2ecf20Sopenharmony_ci
3288c2ecf20Sopenharmony_cistatic struct tmio_mmc_data sdhi0_cn3_data = {
3298c2ecf20Sopenharmony_ci	.capabilities	= MMC_CAP_SDIO_IRQ,
3308c2ecf20Sopenharmony_ci};
3318c2ecf20Sopenharmony_ci
3328c2ecf20Sopenharmony_cistatic struct platform_device sdhi0_cn3_device = {
3338c2ecf20Sopenharmony_ci	.name		= "sh_mobile_sdhi",
3348c2ecf20Sopenharmony_ci	.id             = 0, /* "sdhi0" clock */
3358c2ecf20Sopenharmony_ci	.num_resources	= ARRAY_SIZE(sdhi0_cn3_resources),
3368c2ecf20Sopenharmony_ci	.resource	= sdhi0_cn3_resources,
3378c2ecf20Sopenharmony_ci	.dev = {
3388c2ecf20Sopenharmony_ci		.platform_data = &sdhi0_cn3_data,
3398c2ecf20Sopenharmony_ci	},
3408c2ecf20Sopenharmony_ci};
3418c2ecf20Sopenharmony_ci
3428c2ecf20Sopenharmony_cistatic struct resource sdhi1_cn7_resources[] = {
3438c2ecf20Sopenharmony_ci	[0] = {
3448c2ecf20Sopenharmony_ci		.name	= "SDHI1",
3458c2ecf20Sopenharmony_ci		.start	= 0x04cf0000,
3468c2ecf20Sopenharmony_ci		.end	= 0x04cf00ff,
3478c2ecf20Sopenharmony_ci		.flags	= IORESOURCE_MEM,
3488c2ecf20Sopenharmony_ci	},
3498c2ecf20Sopenharmony_ci	[1] = {
3508c2ecf20Sopenharmony_ci		.start	= evt2irq(0x4e0),
3518c2ecf20Sopenharmony_ci		.flags  = IORESOURCE_IRQ,
3528c2ecf20Sopenharmony_ci	},
3538c2ecf20Sopenharmony_ci};
3548c2ecf20Sopenharmony_ci
3558c2ecf20Sopenharmony_cistatic struct tmio_mmc_data sdhi1_cn7_data = {
3568c2ecf20Sopenharmony_ci	.capabilities	= MMC_CAP_SDIO_IRQ,
3578c2ecf20Sopenharmony_ci};
3588c2ecf20Sopenharmony_ci
3598c2ecf20Sopenharmony_cistatic struct platform_device sdhi1_cn7_device = {
3608c2ecf20Sopenharmony_ci	.name		= "sh_mobile_sdhi",
3618c2ecf20Sopenharmony_ci	.id             = 1, /* "sdhi1" clock */
3628c2ecf20Sopenharmony_ci	.num_resources	= ARRAY_SIZE(sdhi1_cn7_resources),
3638c2ecf20Sopenharmony_ci	.resource	= sdhi1_cn7_resources,
3648c2ecf20Sopenharmony_ci	.dev = {
3658c2ecf20Sopenharmony_ci		.platform_data = &sdhi1_cn7_data,
3668c2ecf20Sopenharmony_ci	},
3678c2ecf20Sopenharmony_ci};
3688c2ecf20Sopenharmony_ci
3698c2ecf20Sopenharmony_cistatic struct ov772x_camera_info ov7725_info = {
3708c2ecf20Sopenharmony_ci	.flags		= OV772X_FLAG_VFLIP | OV772X_FLAG_HFLIP,
3718c2ecf20Sopenharmony_ci	.edgectrl	= OV772X_AUTO_EDGECTRL(0xf, 0),
3728c2ecf20Sopenharmony_ci};
3738c2ecf20Sopenharmony_ci
3748c2ecf20Sopenharmony_cistatic struct i2c_board_info ap325rxa_i2c_devices[] __initdata = {
3758c2ecf20Sopenharmony_ci	{
3768c2ecf20Sopenharmony_ci		I2C_BOARD_INFO("pcf8563", 0x51),
3778c2ecf20Sopenharmony_ci	},
3788c2ecf20Sopenharmony_ci	{
3798c2ecf20Sopenharmony_ci		I2C_BOARD_INFO("ov772x", 0x21),
3808c2ecf20Sopenharmony_ci		.platform_data = &ov7725_info,
3818c2ecf20Sopenharmony_ci	},
3828c2ecf20Sopenharmony_ci};
3838c2ecf20Sopenharmony_ci
3848c2ecf20Sopenharmony_cistatic struct platform_device *ap325rxa_devices[] __initdata = {
3858c2ecf20Sopenharmony_ci	&smsc9118_device,
3868c2ecf20Sopenharmony_ci	&ap325rxa_nor_flash_device,
3878c2ecf20Sopenharmony_ci	&lcdc_device,
3888c2ecf20Sopenharmony_ci	&nand_flash_device,
3898c2ecf20Sopenharmony_ci	&sdhi0_cn3_device,
3908c2ecf20Sopenharmony_ci	&sdhi1_cn7_device,
3918c2ecf20Sopenharmony_ci};
3928c2ecf20Sopenharmony_ci
3938c2ecf20Sopenharmony_ciextern char ap325rxa_sdram_enter_start;
3948c2ecf20Sopenharmony_ciextern char ap325rxa_sdram_enter_end;
3958c2ecf20Sopenharmony_ciextern char ap325rxa_sdram_leave_start;
3968c2ecf20Sopenharmony_ciextern char ap325rxa_sdram_leave_end;
3978c2ecf20Sopenharmony_ci
3988c2ecf20Sopenharmony_cistatic int __init ap325rxa_devices_setup(void)
3998c2ecf20Sopenharmony_ci{
4008c2ecf20Sopenharmony_ci	/* register board specific self-refresh code */
4018c2ecf20Sopenharmony_ci	sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF,
4028c2ecf20Sopenharmony_ci					&ap325rxa_sdram_enter_start,
4038c2ecf20Sopenharmony_ci					&ap325rxa_sdram_enter_end,
4048c2ecf20Sopenharmony_ci					&ap325rxa_sdram_leave_start,
4058c2ecf20Sopenharmony_ci					&ap325rxa_sdram_leave_end);
4068c2ecf20Sopenharmony_ci
4078c2ecf20Sopenharmony_ci	regulator_register_always_on(0, "fixed-3.3V", fixed3v3_power_consumers,
4088c2ecf20Sopenharmony_ci				     ARRAY_SIZE(fixed3v3_power_consumers), 3300000);
4098c2ecf20Sopenharmony_ci	regulator_register_fixed(1, dummy_supplies, ARRAY_SIZE(dummy_supplies));
4108c2ecf20Sopenharmony_ci
4118c2ecf20Sopenharmony_ci	/* LD3 and LD4 LEDs */
4128c2ecf20Sopenharmony_ci	gpio_request(GPIO_PTX5, NULL); /* RUN */
4138c2ecf20Sopenharmony_ci	gpio_direction_output(GPIO_PTX5, 1);
4148c2ecf20Sopenharmony_ci	gpio_export(GPIO_PTX5, 0);
4158c2ecf20Sopenharmony_ci
4168c2ecf20Sopenharmony_ci	gpio_request(GPIO_PTX4, NULL); /* INDICATOR */
4178c2ecf20Sopenharmony_ci	gpio_direction_output(GPIO_PTX4, 0);
4188c2ecf20Sopenharmony_ci	gpio_export(GPIO_PTX4, 0);
4198c2ecf20Sopenharmony_ci
4208c2ecf20Sopenharmony_ci	/* SW1 input */
4218c2ecf20Sopenharmony_ci	gpio_request(GPIO_PTF7, NULL); /* MODE */
4228c2ecf20Sopenharmony_ci	gpio_direction_input(GPIO_PTF7);
4238c2ecf20Sopenharmony_ci	gpio_export(GPIO_PTF7, 0);
4248c2ecf20Sopenharmony_ci
4258c2ecf20Sopenharmony_ci	/* LCDC */
4268c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_LCDD15, NULL);
4278c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_LCDD14, NULL);
4288c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_LCDD13, NULL);
4298c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_LCDD12, NULL);
4308c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_LCDD11, NULL);
4318c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_LCDD10, NULL);
4328c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_LCDD9, NULL);
4338c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_LCDD8, NULL);
4348c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_LCDD7, NULL);
4358c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_LCDD6, NULL);
4368c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_LCDD5, NULL);
4378c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_LCDD4, NULL);
4388c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_LCDD3, NULL);
4398c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_LCDD2, NULL);
4408c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_LCDD1, NULL);
4418c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_LCDD0, NULL);
4428c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_LCDLCLK_PTR, NULL);
4438c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_LCDDCK, NULL);
4448c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_LCDVEPWC, NULL);
4458c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_LCDVCPWC, NULL);
4468c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_LCDVSYN, NULL);
4478c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_LCDHSYN, NULL);
4488c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_LCDDISP, NULL);
4498c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_LCDDON, NULL);
4508c2ecf20Sopenharmony_ci
4518c2ecf20Sopenharmony_ci	/* LCD backlight */
4528c2ecf20Sopenharmony_ci	gpio_request(GPIO_PTS3, NULL);
4538c2ecf20Sopenharmony_ci	gpio_direction_output(GPIO_PTS3, 1);
4548c2ecf20Sopenharmony_ci
4558c2ecf20Sopenharmony_ci	/* CEU */
4568c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_VIO_CLK2, NULL);
4578c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_VIO_VD2, NULL);
4588c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_VIO_HD2, NULL);
4598c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_VIO_FLD, NULL);
4608c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_VIO_CKO, NULL);
4618c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_VIO_D15, NULL);
4628c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_VIO_D14, NULL);
4638c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_VIO_D13, NULL);
4648c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_VIO_D12, NULL);
4658c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_VIO_D11, NULL);
4668c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_VIO_D10, NULL);
4678c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_VIO_D9, NULL);
4688c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_VIO_D8, NULL);
4698c2ecf20Sopenharmony_ci
4708c2ecf20Sopenharmony_ci	gpio_request(GPIO_PTZ7, NULL);
4718c2ecf20Sopenharmony_ci	gpio_direction_output(GPIO_PTZ7, 0); /* OE_CAM */
4728c2ecf20Sopenharmony_ci	gpio_request(GPIO_PTZ6, NULL);
4738c2ecf20Sopenharmony_ci	gpio_direction_output(GPIO_PTZ6, 0); /* STBY_CAM */
4748c2ecf20Sopenharmony_ci	gpio_request(GPIO_PTZ5, NULL);
4758c2ecf20Sopenharmony_ci	gpio_direction_output(GPIO_PTZ5, 0); /* RST_CAM */
4768c2ecf20Sopenharmony_ci	gpio_request(GPIO_PTZ4, NULL);
4778c2ecf20Sopenharmony_ci	gpio_direction_output(GPIO_PTZ4, 0); /* SADDR */
4788c2ecf20Sopenharmony_ci
4798c2ecf20Sopenharmony_ci	__raw_writew(__raw_readw(PORT_MSELCRB) & ~0x0001, PORT_MSELCRB);
4808c2ecf20Sopenharmony_ci
4818c2ecf20Sopenharmony_ci	/* FLCTL */
4828c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_FCE, NULL);
4838c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_NAF7, NULL);
4848c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_NAF6, NULL);
4858c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_NAF5, NULL);
4868c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_NAF4, NULL);
4878c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_NAF3, NULL);
4888c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_NAF2, NULL);
4898c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_NAF1, NULL);
4908c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_NAF0, NULL);
4918c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_FCDE, NULL);
4928c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_FOE, NULL);
4938c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_FSC, NULL);
4948c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_FWE, NULL);
4958c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_FRB, NULL);
4968c2ecf20Sopenharmony_ci
4978c2ecf20Sopenharmony_ci	__raw_writew(0, PORT_HIZCRC);
4988c2ecf20Sopenharmony_ci	__raw_writew(0xFFFF, PORT_DRVCRA);
4998c2ecf20Sopenharmony_ci	__raw_writew(0xFFFF, PORT_DRVCRB);
5008c2ecf20Sopenharmony_ci
5018c2ecf20Sopenharmony_ci	/* SDHI0 - CN3 - SD CARD */
5028c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_SDHI0CD_PTD, NULL);
5038c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_SDHI0WP_PTD, NULL);
5048c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_SDHI0D3_PTD, NULL);
5058c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_SDHI0D2_PTD, NULL);
5068c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_SDHI0D1_PTD, NULL);
5078c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_SDHI0D0_PTD, NULL);
5088c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_SDHI0CMD_PTD, NULL);
5098c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_SDHI0CLK_PTD, NULL);
5108c2ecf20Sopenharmony_ci
5118c2ecf20Sopenharmony_ci	/* SDHI1 - CN7 - MICRO SD CARD */
5128c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_SDHI1CD, NULL);
5138c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_SDHI1D3, NULL);
5148c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_SDHI1D2, NULL);
5158c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_SDHI1D1, NULL);
5168c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_SDHI1D0, NULL);
5178c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_SDHI1CMD, NULL);
5188c2ecf20Sopenharmony_ci	gpio_request(GPIO_FN_SDHI1CLK, NULL);
5198c2ecf20Sopenharmony_ci
5208c2ecf20Sopenharmony_ci	/* Add a clock alias for ov7725 xclk source. */
5218c2ecf20Sopenharmony_ci	clk_add_alias(NULL, "0-0021", "video_clk", NULL);
5228c2ecf20Sopenharmony_ci
5238c2ecf20Sopenharmony_ci	/* Register RSTB gpio for ov7725 camera sensor. */
5248c2ecf20Sopenharmony_ci	gpiod_add_lookup_table(&ov7725_gpios);
5258c2ecf20Sopenharmony_ci
5268c2ecf20Sopenharmony_ci	i2c_register_board_info(0, ap325rxa_i2c_devices,
5278c2ecf20Sopenharmony_ci				ARRAY_SIZE(ap325rxa_i2c_devices));
5288c2ecf20Sopenharmony_ci
5298c2ecf20Sopenharmony_ci	/* Initialize CEU platform device separately to map memory first */
5308c2ecf20Sopenharmony_ci	device_initialize(&ap325rxa_ceu_device.dev);
5318c2ecf20Sopenharmony_ci	dma_declare_coherent_memory(&ap325rxa_ceu_device.dev,
5328c2ecf20Sopenharmony_ci			ceu_dma_membase, ceu_dma_membase,
5338c2ecf20Sopenharmony_ci			CEU_BUFFER_MEMORY_SIZE);
5348c2ecf20Sopenharmony_ci
5358c2ecf20Sopenharmony_ci	platform_device_add(&ap325rxa_ceu_device);
5368c2ecf20Sopenharmony_ci
5378c2ecf20Sopenharmony_ci	return platform_add_devices(ap325rxa_devices,
5388c2ecf20Sopenharmony_ci				ARRAY_SIZE(ap325rxa_devices));
5398c2ecf20Sopenharmony_ci}
5408c2ecf20Sopenharmony_ciarch_initcall(ap325rxa_devices_setup);
5418c2ecf20Sopenharmony_ci
5428c2ecf20Sopenharmony_ci/* Return the board specific boot mode pin configuration */
5438c2ecf20Sopenharmony_cistatic int ap325rxa_mode_pins(void)
5448c2ecf20Sopenharmony_ci{
5458c2ecf20Sopenharmony_ci	/* MD0=0, MD1=0, MD2=0: Clock Mode 0
5468c2ecf20Sopenharmony_ci	 * MD3=0: 16-bit Area0 Bus Width
5478c2ecf20Sopenharmony_ci	 * MD5=1: Little Endian
5488c2ecf20Sopenharmony_ci	 * TSTMD=1, MD8=1: Test Mode Disabled
5498c2ecf20Sopenharmony_ci	 */
5508c2ecf20Sopenharmony_ci	return MODE_PIN5 | MODE_PIN8;
5518c2ecf20Sopenharmony_ci}
5528c2ecf20Sopenharmony_ci
5538c2ecf20Sopenharmony_ci/* Reserve a portion of memory for CEU buffers */
5548c2ecf20Sopenharmony_cistatic void __init ap325rxa_mv_mem_reserve(void)
5558c2ecf20Sopenharmony_ci{
5568c2ecf20Sopenharmony_ci	phys_addr_t phys;
5578c2ecf20Sopenharmony_ci	phys_addr_t size = CEU_BUFFER_MEMORY_SIZE;
5588c2ecf20Sopenharmony_ci
5598c2ecf20Sopenharmony_ci	phys = memblock_phys_alloc(size, PAGE_SIZE);
5608c2ecf20Sopenharmony_ci	if (!phys)
5618c2ecf20Sopenharmony_ci		panic("Failed to allocate CEU memory\n");
5628c2ecf20Sopenharmony_ci
5638c2ecf20Sopenharmony_ci	memblock_free(phys, size);
5648c2ecf20Sopenharmony_ci	memblock_remove(phys, size);
5658c2ecf20Sopenharmony_ci
5668c2ecf20Sopenharmony_ci	ceu_dma_membase = phys;
5678c2ecf20Sopenharmony_ci}
5688c2ecf20Sopenharmony_ci
5698c2ecf20Sopenharmony_cistatic struct sh_machine_vector mv_ap325rxa __initmv = {
5708c2ecf20Sopenharmony_ci	.mv_name = "AP-325RXA",
5718c2ecf20Sopenharmony_ci	.mv_mode_pins = ap325rxa_mode_pins,
5728c2ecf20Sopenharmony_ci	.mv_mem_reserve	= ap325rxa_mv_mem_reserve,
5738c2ecf20Sopenharmony_ci};
574