18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * mach-davinci/devices.c
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * DaVinci platform device setup/initialization
68c2ecf20Sopenharmony_ci */
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci#include <linux/init.h>
98c2ecf20Sopenharmony_ci#include <linux/platform_device.h>
108c2ecf20Sopenharmony_ci#include <linux/platform_data/i2c-davinci.h>
118c2ecf20Sopenharmony_ci#include <linux/platform_data/mmc-davinci.h>
128c2ecf20Sopenharmony_ci#include <linux/platform_data/edma.h>
138c2ecf20Sopenharmony_ci#include <linux/dma-mapping.h>
148c2ecf20Sopenharmony_ci#include <linux/io.h>
158c2ecf20Sopenharmony_ci#include <linux/reboot.h>
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_ci#include <mach/hardware.h>
188c2ecf20Sopenharmony_ci#include <mach/cputype.h>
198c2ecf20Sopenharmony_ci#include <mach/mux.h>
208c2ecf20Sopenharmony_ci
218c2ecf20Sopenharmony_ci#include "davinci.h"
228c2ecf20Sopenharmony_ci#include "irqs.h"
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_ci#define DAVINCI_I2C_BASE	     0x01C21000
258c2ecf20Sopenharmony_ci#define DAVINCI_ATA_BASE	     0x01C66000
268c2ecf20Sopenharmony_ci#define DAVINCI_MMCSD0_BASE	     0x01E10000
278c2ecf20Sopenharmony_ci#define DM355_MMCSD0_BASE	     0x01E11000
288c2ecf20Sopenharmony_ci#define DM355_MMCSD1_BASE	     0x01E00000
298c2ecf20Sopenharmony_ci#define DM365_MMCSD0_BASE	     0x01D11000
308c2ecf20Sopenharmony_ci#define DM365_MMCSD1_BASE	     0x01D00000
318c2ecf20Sopenharmony_ci
328c2ecf20Sopenharmony_civoid __iomem  *davinci_sysmod_base;
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_civoid davinci_map_sysmod(void)
358c2ecf20Sopenharmony_ci{
368c2ecf20Sopenharmony_ci	davinci_sysmod_base = ioremap(DAVINCI_SYSTEM_MODULE_BASE,
378c2ecf20Sopenharmony_ci					      0x800);
388c2ecf20Sopenharmony_ci	/*
398c2ecf20Sopenharmony_ci	 * Throw a bug since a lot of board initialization code depends
408c2ecf20Sopenharmony_ci	 * on system module availability. ioremap() failing this early
418c2ecf20Sopenharmony_ci	 * need careful looking into anyway.
428c2ecf20Sopenharmony_ci	 */
438c2ecf20Sopenharmony_ci	BUG_ON(!davinci_sysmod_base);
448c2ecf20Sopenharmony_ci}
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_cistatic struct resource i2c_resources[] = {
478c2ecf20Sopenharmony_ci	{
488c2ecf20Sopenharmony_ci		.start		= DAVINCI_I2C_BASE,
498c2ecf20Sopenharmony_ci		.end		= DAVINCI_I2C_BASE + 0x40,
508c2ecf20Sopenharmony_ci		.flags		= IORESOURCE_MEM,
518c2ecf20Sopenharmony_ci	},
528c2ecf20Sopenharmony_ci	{
538c2ecf20Sopenharmony_ci		.start		= DAVINCI_INTC_IRQ(IRQ_I2C),
548c2ecf20Sopenharmony_ci		.flags		= IORESOURCE_IRQ,
558c2ecf20Sopenharmony_ci	},
568c2ecf20Sopenharmony_ci};
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_cistatic struct platform_device davinci_i2c_device = {
598c2ecf20Sopenharmony_ci	.name           = "i2c_davinci",
608c2ecf20Sopenharmony_ci	.id             = 1,
618c2ecf20Sopenharmony_ci	.num_resources	= ARRAY_SIZE(i2c_resources),
628c2ecf20Sopenharmony_ci	.resource	= i2c_resources,
638c2ecf20Sopenharmony_ci};
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_civoid __init davinci_init_i2c(struct davinci_i2c_platform_data *pdata)
668c2ecf20Sopenharmony_ci{
678c2ecf20Sopenharmony_ci	if (cpu_is_davinci_dm644x())
688c2ecf20Sopenharmony_ci		davinci_cfg_reg(DM644X_I2C);
698c2ecf20Sopenharmony_ci
708c2ecf20Sopenharmony_ci	davinci_i2c_device.dev.platform_data = pdata;
718c2ecf20Sopenharmony_ci	(void) platform_device_register(&davinci_i2c_device);
728c2ecf20Sopenharmony_ci}
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_cistatic struct resource ide_resources[] = {
758c2ecf20Sopenharmony_ci	{
768c2ecf20Sopenharmony_ci		.start		= DAVINCI_ATA_BASE,
778c2ecf20Sopenharmony_ci		.end		= DAVINCI_ATA_BASE + 0x7ff,
788c2ecf20Sopenharmony_ci		.flags		= IORESOURCE_MEM,
798c2ecf20Sopenharmony_ci	},
808c2ecf20Sopenharmony_ci	{
818c2ecf20Sopenharmony_ci		.start		= DAVINCI_INTC_IRQ(IRQ_IDE),
828c2ecf20Sopenharmony_ci		.end		= DAVINCI_INTC_IRQ(IRQ_IDE),
838c2ecf20Sopenharmony_ci		.flags		= IORESOURCE_IRQ,
848c2ecf20Sopenharmony_ci	},
858c2ecf20Sopenharmony_ci};
868c2ecf20Sopenharmony_ci
878c2ecf20Sopenharmony_cistatic u64 ide_dma_mask = DMA_BIT_MASK(32);
888c2ecf20Sopenharmony_ci
898c2ecf20Sopenharmony_cistatic struct platform_device ide_device = {
908c2ecf20Sopenharmony_ci	.name           = "palm_bk3710",
918c2ecf20Sopenharmony_ci	.id             = -1,
928c2ecf20Sopenharmony_ci	.resource       = ide_resources,
938c2ecf20Sopenharmony_ci	.num_resources  = ARRAY_SIZE(ide_resources),
948c2ecf20Sopenharmony_ci	.dev = {
958c2ecf20Sopenharmony_ci		.dma_mask		= &ide_dma_mask,
968c2ecf20Sopenharmony_ci		.coherent_dma_mask      = DMA_BIT_MASK(32),
978c2ecf20Sopenharmony_ci	},
988c2ecf20Sopenharmony_ci};
998c2ecf20Sopenharmony_ci
1008c2ecf20Sopenharmony_civoid __init davinci_init_ide(void)
1018c2ecf20Sopenharmony_ci{
1028c2ecf20Sopenharmony_ci	if (cpu_is_davinci_dm644x()) {
1038c2ecf20Sopenharmony_ci		davinci_cfg_reg(DM644X_HPIEN_DISABLE);
1048c2ecf20Sopenharmony_ci		davinci_cfg_reg(DM644X_ATAEN);
1058c2ecf20Sopenharmony_ci		davinci_cfg_reg(DM644X_HDIREN);
1068c2ecf20Sopenharmony_ci	} else if (cpu_is_davinci_dm646x()) {
1078c2ecf20Sopenharmony_ci		/* IRQ_DM646X_IDE is the same as IRQ_IDE */
1088c2ecf20Sopenharmony_ci		davinci_cfg_reg(DM646X_ATAEN);
1098c2ecf20Sopenharmony_ci	} else {
1108c2ecf20Sopenharmony_ci		WARN_ON(1);
1118c2ecf20Sopenharmony_ci		return;
1128c2ecf20Sopenharmony_ci	}
1138c2ecf20Sopenharmony_ci
1148c2ecf20Sopenharmony_ci	platform_device_register(&ide_device);
1158c2ecf20Sopenharmony_ci}
1168c2ecf20Sopenharmony_ci
1178c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_MMC_DAVINCI)
1188c2ecf20Sopenharmony_ci
1198c2ecf20Sopenharmony_cistatic u64 mmcsd0_dma_mask = DMA_BIT_MASK(32);
1208c2ecf20Sopenharmony_ci
1218c2ecf20Sopenharmony_cistatic struct resource mmcsd0_resources[] = {
1228c2ecf20Sopenharmony_ci	{
1238c2ecf20Sopenharmony_ci		/* different on dm355 */
1248c2ecf20Sopenharmony_ci		.start = DAVINCI_MMCSD0_BASE,
1258c2ecf20Sopenharmony_ci		.end   = DAVINCI_MMCSD0_BASE + SZ_4K - 1,
1268c2ecf20Sopenharmony_ci		.flags = IORESOURCE_MEM,
1278c2ecf20Sopenharmony_ci	},
1288c2ecf20Sopenharmony_ci	/* IRQs:  MMC/SD, then SDIO */
1298c2ecf20Sopenharmony_ci	{
1308c2ecf20Sopenharmony_ci		.start = DAVINCI_INTC_IRQ(IRQ_MMCINT),
1318c2ecf20Sopenharmony_ci		.flags = IORESOURCE_IRQ,
1328c2ecf20Sopenharmony_ci	}, {
1338c2ecf20Sopenharmony_ci		/* different on dm355 */
1348c2ecf20Sopenharmony_ci		.start = DAVINCI_INTC_IRQ(IRQ_SDIOINT),
1358c2ecf20Sopenharmony_ci		.flags = IORESOURCE_IRQ,
1368c2ecf20Sopenharmony_ci	},
1378c2ecf20Sopenharmony_ci};
1388c2ecf20Sopenharmony_ci
1398c2ecf20Sopenharmony_cistatic struct platform_device davinci_mmcsd0_device = {
1408c2ecf20Sopenharmony_ci	.name = "dm6441-mmc",
1418c2ecf20Sopenharmony_ci	.id = 0,
1428c2ecf20Sopenharmony_ci	.dev = {
1438c2ecf20Sopenharmony_ci		.dma_mask = &mmcsd0_dma_mask,
1448c2ecf20Sopenharmony_ci		.coherent_dma_mask = DMA_BIT_MASK(32),
1458c2ecf20Sopenharmony_ci	},
1468c2ecf20Sopenharmony_ci	.num_resources = ARRAY_SIZE(mmcsd0_resources),
1478c2ecf20Sopenharmony_ci	.resource = mmcsd0_resources,
1488c2ecf20Sopenharmony_ci};
1498c2ecf20Sopenharmony_ci
1508c2ecf20Sopenharmony_cistatic u64 mmcsd1_dma_mask = DMA_BIT_MASK(32);
1518c2ecf20Sopenharmony_ci
1528c2ecf20Sopenharmony_cistatic struct resource mmcsd1_resources[] = {
1538c2ecf20Sopenharmony_ci	{
1548c2ecf20Sopenharmony_ci		.start = DM355_MMCSD1_BASE,
1558c2ecf20Sopenharmony_ci		.end   = DM355_MMCSD1_BASE + SZ_4K - 1,
1568c2ecf20Sopenharmony_ci		.flags = IORESOURCE_MEM,
1578c2ecf20Sopenharmony_ci	},
1588c2ecf20Sopenharmony_ci	/* IRQs:  MMC/SD, then SDIO */
1598c2ecf20Sopenharmony_ci	{
1608c2ecf20Sopenharmony_ci		.start = DAVINCI_INTC_IRQ(IRQ_DM355_MMCINT1),
1618c2ecf20Sopenharmony_ci		.flags = IORESOURCE_IRQ,
1628c2ecf20Sopenharmony_ci	}, {
1638c2ecf20Sopenharmony_ci		.start = DAVINCI_INTC_IRQ(IRQ_DM355_SDIOINT1),
1648c2ecf20Sopenharmony_ci		.flags = IORESOURCE_IRQ,
1658c2ecf20Sopenharmony_ci	},
1668c2ecf20Sopenharmony_ci};
1678c2ecf20Sopenharmony_ci
1688c2ecf20Sopenharmony_cistatic struct platform_device davinci_mmcsd1_device = {
1698c2ecf20Sopenharmony_ci	.name = "dm6441-mmc",
1708c2ecf20Sopenharmony_ci	.id = 1,
1718c2ecf20Sopenharmony_ci	.dev = {
1728c2ecf20Sopenharmony_ci		.dma_mask = &mmcsd1_dma_mask,
1738c2ecf20Sopenharmony_ci		.coherent_dma_mask = DMA_BIT_MASK(32),
1748c2ecf20Sopenharmony_ci	},
1758c2ecf20Sopenharmony_ci	.num_resources = ARRAY_SIZE(mmcsd1_resources),
1768c2ecf20Sopenharmony_ci	.resource = mmcsd1_resources,
1778c2ecf20Sopenharmony_ci};
1788c2ecf20Sopenharmony_ci
1798c2ecf20Sopenharmony_ci
1808c2ecf20Sopenharmony_civoid __init davinci_setup_mmc(int module, struct davinci_mmc_config *config)
1818c2ecf20Sopenharmony_ci{
1828c2ecf20Sopenharmony_ci	struct platform_device	*pdev = NULL;
1838c2ecf20Sopenharmony_ci
1848c2ecf20Sopenharmony_ci	if (WARN_ON(cpu_is_davinci_dm646x()))
1858c2ecf20Sopenharmony_ci		return;
1868c2ecf20Sopenharmony_ci
1878c2ecf20Sopenharmony_ci	/* REVISIT: update PINMUX, ARM_IRQMUX, and EDMA_EVTMUX here too;
1888c2ecf20Sopenharmony_ci	 * for example if MMCSD1 is used for SDIO, maybe DAT2 is unused.
1898c2ecf20Sopenharmony_ci	 *
1908c2ecf20Sopenharmony_ci	 * FIXME dm6441 (no MMC/SD), dm357 (one), and dm335 (two) are
1918c2ecf20Sopenharmony_ci	 * not handled right here ...
1928c2ecf20Sopenharmony_ci	 */
1938c2ecf20Sopenharmony_ci	switch (module) {
1948c2ecf20Sopenharmony_ci	case 1:
1958c2ecf20Sopenharmony_ci		if (cpu_is_davinci_dm355()) {
1968c2ecf20Sopenharmony_ci			/* REVISIT we may not need all these pins if e.g. this
1978c2ecf20Sopenharmony_ci			 * is a hard-wired SDIO device...
1988c2ecf20Sopenharmony_ci			 */
1998c2ecf20Sopenharmony_ci			davinci_cfg_reg(DM355_SD1_CMD);
2008c2ecf20Sopenharmony_ci			davinci_cfg_reg(DM355_SD1_CLK);
2018c2ecf20Sopenharmony_ci			davinci_cfg_reg(DM355_SD1_DATA0);
2028c2ecf20Sopenharmony_ci			davinci_cfg_reg(DM355_SD1_DATA1);
2038c2ecf20Sopenharmony_ci			davinci_cfg_reg(DM355_SD1_DATA2);
2048c2ecf20Sopenharmony_ci			davinci_cfg_reg(DM355_SD1_DATA3);
2058c2ecf20Sopenharmony_ci		} else if (cpu_is_davinci_dm365()) {
2068c2ecf20Sopenharmony_ci			/* Configure pull down control */
2078c2ecf20Sopenharmony_ci			unsigned v;
2088c2ecf20Sopenharmony_ci
2098c2ecf20Sopenharmony_ci			v = __raw_readl(DAVINCI_SYSMOD_VIRT(SYSMOD_PUPDCTL1));
2108c2ecf20Sopenharmony_ci			__raw_writel(v & ~0xfc0,
2118c2ecf20Sopenharmony_ci					DAVINCI_SYSMOD_VIRT(SYSMOD_PUPDCTL1));
2128c2ecf20Sopenharmony_ci
2138c2ecf20Sopenharmony_ci			mmcsd1_resources[0].start = DM365_MMCSD1_BASE;
2148c2ecf20Sopenharmony_ci			mmcsd1_resources[0].end = DM365_MMCSD1_BASE +
2158c2ecf20Sopenharmony_ci							SZ_4K - 1;
2168c2ecf20Sopenharmony_ci			mmcsd1_resources[2].start = DAVINCI_INTC_IRQ(
2178c2ecf20Sopenharmony_ci							IRQ_DM365_SDIOINT1);
2188c2ecf20Sopenharmony_ci			davinci_mmcsd1_device.name = "da830-mmc";
2198c2ecf20Sopenharmony_ci		} else
2208c2ecf20Sopenharmony_ci			break;
2218c2ecf20Sopenharmony_ci
2228c2ecf20Sopenharmony_ci		pdev = &davinci_mmcsd1_device;
2238c2ecf20Sopenharmony_ci		break;
2248c2ecf20Sopenharmony_ci	case 0:
2258c2ecf20Sopenharmony_ci		if (cpu_is_davinci_dm355()) {
2268c2ecf20Sopenharmony_ci			mmcsd0_resources[0].start = DM355_MMCSD0_BASE;
2278c2ecf20Sopenharmony_ci			mmcsd0_resources[0].end = DM355_MMCSD0_BASE + SZ_4K - 1;
2288c2ecf20Sopenharmony_ci			mmcsd0_resources[2].start = DAVINCI_INTC_IRQ(
2298c2ecf20Sopenharmony_ci							IRQ_DM355_SDIOINT0);
2308c2ecf20Sopenharmony_ci
2318c2ecf20Sopenharmony_ci			/* expose all 6 MMC0 signals:  CLK, CMD, DATA[0..3] */
2328c2ecf20Sopenharmony_ci			davinci_cfg_reg(DM355_MMCSD0);
2338c2ecf20Sopenharmony_ci
2348c2ecf20Sopenharmony_ci			/* enable RX EDMA */
2358c2ecf20Sopenharmony_ci			davinci_cfg_reg(DM355_EVT26_MMC0_RX);
2368c2ecf20Sopenharmony_ci		} else if (cpu_is_davinci_dm365()) {
2378c2ecf20Sopenharmony_ci			mmcsd0_resources[0].start = DM365_MMCSD0_BASE;
2388c2ecf20Sopenharmony_ci			mmcsd0_resources[0].end = DM365_MMCSD0_BASE +
2398c2ecf20Sopenharmony_ci							SZ_4K - 1;
2408c2ecf20Sopenharmony_ci			mmcsd0_resources[2].start = DAVINCI_INTC_IRQ(
2418c2ecf20Sopenharmony_ci							IRQ_DM365_SDIOINT0);
2428c2ecf20Sopenharmony_ci			davinci_mmcsd0_device.name = "da830-mmc";
2438c2ecf20Sopenharmony_ci		} else if (cpu_is_davinci_dm644x()) {
2448c2ecf20Sopenharmony_ci			/* REVISIT: should this be in board-init code? */
2458c2ecf20Sopenharmony_ci			/* Power-on 3.3V IO cells */
2468c2ecf20Sopenharmony_ci			__raw_writel(0,
2478c2ecf20Sopenharmony_ci				DAVINCI_SYSMOD_VIRT(SYSMOD_VDD3P3VPWDN));
2488c2ecf20Sopenharmony_ci			/*Set up the pull regiter for MMC */
2498c2ecf20Sopenharmony_ci			davinci_cfg_reg(DM644X_MSTK);
2508c2ecf20Sopenharmony_ci		}
2518c2ecf20Sopenharmony_ci
2528c2ecf20Sopenharmony_ci		pdev = &davinci_mmcsd0_device;
2538c2ecf20Sopenharmony_ci		break;
2548c2ecf20Sopenharmony_ci	}
2558c2ecf20Sopenharmony_ci
2568c2ecf20Sopenharmony_ci	if (WARN_ON(!pdev))
2578c2ecf20Sopenharmony_ci		return;
2588c2ecf20Sopenharmony_ci
2598c2ecf20Sopenharmony_ci	pdev->dev.platform_data = config;
2608c2ecf20Sopenharmony_ci	platform_device_register(pdev);
2618c2ecf20Sopenharmony_ci}
2628c2ecf20Sopenharmony_ci
2638c2ecf20Sopenharmony_ci#else
2648c2ecf20Sopenharmony_ci
2658c2ecf20Sopenharmony_civoid __init davinci_setup_mmc(int module, struct davinci_mmc_config *config)
2668c2ecf20Sopenharmony_ci{
2678c2ecf20Sopenharmony_ci}
2688c2ecf20Sopenharmony_ci
2698c2ecf20Sopenharmony_ci#endif
2708c2ecf20Sopenharmony_ci
2718c2ecf20Sopenharmony_ci/*-------------------------------------------------------------------------*/
2728c2ecf20Sopenharmony_ci
2738c2ecf20Sopenharmony_cistatic struct resource wdt_resources[] = {
2748c2ecf20Sopenharmony_ci	{
2758c2ecf20Sopenharmony_ci		.start	= DAVINCI_WDOG_BASE,
2768c2ecf20Sopenharmony_ci		.end	= DAVINCI_WDOG_BASE + SZ_1K - 1,
2778c2ecf20Sopenharmony_ci		.flags	= IORESOURCE_MEM,
2788c2ecf20Sopenharmony_ci	},
2798c2ecf20Sopenharmony_ci};
2808c2ecf20Sopenharmony_ci
2818c2ecf20Sopenharmony_cistatic struct platform_device davinci_wdt_device = {
2828c2ecf20Sopenharmony_ci	.name		= "davinci-wdt",
2838c2ecf20Sopenharmony_ci	.id		= -1,
2848c2ecf20Sopenharmony_ci	.num_resources	= ARRAY_SIZE(wdt_resources),
2858c2ecf20Sopenharmony_ci	.resource	= wdt_resources,
2868c2ecf20Sopenharmony_ci};
2878c2ecf20Sopenharmony_ci
2888c2ecf20Sopenharmony_ciint davinci_init_wdt(void)
2898c2ecf20Sopenharmony_ci{
2908c2ecf20Sopenharmony_ci	return platform_device_register(&davinci_wdt_device);
2918c2ecf20Sopenharmony_ci}
2928c2ecf20Sopenharmony_ci
2938c2ecf20Sopenharmony_cistatic struct platform_device davinci_gpio_device = {
2948c2ecf20Sopenharmony_ci	.name	= "davinci_gpio",
2958c2ecf20Sopenharmony_ci	.id	= -1,
2968c2ecf20Sopenharmony_ci};
2978c2ecf20Sopenharmony_ci
2988c2ecf20Sopenharmony_ciint davinci_gpio_register(struct resource *res, int size, void *pdata)
2998c2ecf20Sopenharmony_ci{
3008c2ecf20Sopenharmony_ci	davinci_gpio_device.resource = res;
3018c2ecf20Sopenharmony_ci	davinci_gpio_device.num_resources = size;
3028c2ecf20Sopenharmony_ci	davinci_gpio_device.dev.platform_data = pdata;
3038c2ecf20Sopenharmony_ci	return platform_device_register(&davinci_gpio_device);
3048c2ecf20Sopenharmony_ci}
305