18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci *  linux/arch/arm/mach-mmp/gplugd.c
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci *  Support for the Marvell PXA168-based GuruPlug Display (gplugD) Platform.
68c2ecf20Sopenharmony_ci */
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci#include <linux/init.h>
98c2ecf20Sopenharmony_ci#include <linux/platform_device.h>
108c2ecf20Sopenharmony_ci#include <linux/gpio.h>
118c2ecf20Sopenharmony_ci#include <linux/gpio-pxa.h>
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_ci#include <asm/mach/arch.h>
148c2ecf20Sopenharmony_ci#include <asm/mach-types.h>
158c2ecf20Sopenharmony_ci
168c2ecf20Sopenharmony_ci#include "irqs.h"
178c2ecf20Sopenharmony_ci#include "pxa168.h"
188c2ecf20Sopenharmony_ci#include "mfp-pxa168.h"
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_ci#include "common.h"
218c2ecf20Sopenharmony_ci
228c2ecf20Sopenharmony_cistatic unsigned long gplugd_pin_config[] __initdata = {
238c2ecf20Sopenharmony_ci	/* UART3 */
248c2ecf20Sopenharmony_ci	GPIO8_UART3_TXD,
258c2ecf20Sopenharmony_ci	GPIO9_UART3_RXD,
268c2ecf20Sopenharmony_ci	GPIO1O_UART3_CTS,
278c2ecf20Sopenharmony_ci	GPIO11_UART3_RTS,
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ci	/* USB OTG PEN */
308c2ecf20Sopenharmony_ci	GPIO18_GPIO,
318c2ecf20Sopenharmony_ci
328c2ecf20Sopenharmony_ci	/* MMC2 */
338c2ecf20Sopenharmony_ci	GPIO28_MMC2_CMD,
348c2ecf20Sopenharmony_ci	GPIO29_MMC2_CLK,
358c2ecf20Sopenharmony_ci	GPIO30_MMC2_DAT0,
368c2ecf20Sopenharmony_ci	GPIO31_MMC2_DAT1,
378c2ecf20Sopenharmony_ci	GPIO32_MMC2_DAT2,
388c2ecf20Sopenharmony_ci	GPIO33_MMC2_DAT3,
398c2ecf20Sopenharmony_ci
408c2ecf20Sopenharmony_ci	/* LCD & HDMI clock selection GPIO: 0: 74.176MHz, 1: 74.25 MHz */
418c2ecf20Sopenharmony_ci	GPIO35_GPIO,
428c2ecf20Sopenharmony_ci	GPIO36_GPIO, /* CEC Interrupt */
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ci	/* MMC1 */
458c2ecf20Sopenharmony_ci	GPIO43_MMC1_CLK,
468c2ecf20Sopenharmony_ci	GPIO49_MMC1_CMD,
478c2ecf20Sopenharmony_ci	GPIO41_MMC1_DAT0,
488c2ecf20Sopenharmony_ci	GPIO40_MMC1_DAT1,
498c2ecf20Sopenharmony_ci	GPIO52_MMC1_DAT2,
508c2ecf20Sopenharmony_ci	GPIO51_MMC1_DAT3,
518c2ecf20Sopenharmony_ci	GPIO53_MMC1_CD,
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_ci	/* LCD */
548c2ecf20Sopenharmony_ci	GPIO56_LCD_FCLK_RD,
558c2ecf20Sopenharmony_ci	GPIO57_LCD_LCLK_A0,
568c2ecf20Sopenharmony_ci	GPIO58_LCD_PCLK_WR,
578c2ecf20Sopenharmony_ci	GPIO59_LCD_DENA_BIAS,
588c2ecf20Sopenharmony_ci	GPIO60_LCD_DD0,
598c2ecf20Sopenharmony_ci	GPIO61_LCD_DD1,
608c2ecf20Sopenharmony_ci	GPIO62_LCD_DD2,
618c2ecf20Sopenharmony_ci	GPIO63_LCD_DD3,
628c2ecf20Sopenharmony_ci	GPIO64_LCD_DD4,
638c2ecf20Sopenharmony_ci	GPIO65_LCD_DD5,
648c2ecf20Sopenharmony_ci	GPIO66_LCD_DD6,
658c2ecf20Sopenharmony_ci	GPIO67_LCD_DD7,
668c2ecf20Sopenharmony_ci	GPIO68_LCD_DD8,
678c2ecf20Sopenharmony_ci	GPIO69_LCD_DD9,
688c2ecf20Sopenharmony_ci	GPIO70_LCD_DD10,
698c2ecf20Sopenharmony_ci	GPIO71_LCD_DD11,
708c2ecf20Sopenharmony_ci	GPIO72_LCD_DD12,
718c2ecf20Sopenharmony_ci	GPIO73_LCD_DD13,
728c2ecf20Sopenharmony_ci	GPIO74_LCD_DD14,
738c2ecf20Sopenharmony_ci	GPIO75_LCD_DD15,
748c2ecf20Sopenharmony_ci	GPIO76_LCD_DD16,
758c2ecf20Sopenharmony_ci	GPIO77_LCD_DD17,
768c2ecf20Sopenharmony_ci	GPIO78_LCD_DD18,
778c2ecf20Sopenharmony_ci	GPIO79_LCD_DD19,
788c2ecf20Sopenharmony_ci	GPIO80_LCD_DD20,
798c2ecf20Sopenharmony_ci	GPIO81_LCD_DD21,
808c2ecf20Sopenharmony_ci	GPIO82_LCD_DD22,
818c2ecf20Sopenharmony_ci	GPIO83_LCD_DD23,
828c2ecf20Sopenharmony_ci
838c2ecf20Sopenharmony_ci	/* GPIO */
848c2ecf20Sopenharmony_ci	GPIO84_GPIO,
858c2ecf20Sopenharmony_ci	GPIO85_GPIO,
868c2ecf20Sopenharmony_ci
878c2ecf20Sopenharmony_ci	/* Fast-Ethernet*/
888c2ecf20Sopenharmony_ci	GPIO86_TX_CLK,
898c2ecf20Sopenharmony_ci	GPIO87_TX_EN,
908c2ecf20Sopenharmony_ci	GPIO88_TX_DQ3,
918c2ecf20Sopenharmony_ci	GPIO89_TX_DQ2,
928c2ecf20Sopenharmony_ci	GPIO90_TX_DQ1,
938c2ecf20Sopenharmony_ci	GPIO91_TX_DQ0,
948c2ecf20Sopenharmony_ci	GPIO92_MII_CRS,
958c2ecf20Sopenharmony_ci	GPIO93_MII_COL,
968c2ecf20Sopenharmony_ci	GPIO94_RX_CLK,
978c2ecf20Sopenharmony_ci	GPIO95_RX_ER,
988c2ecf20Sopenharmony_ci	GPIO96_RX_DQ3,
998c2ecf20Sopenharmony_ci	GPIO97_RX_DQ2,
1008c2ecf20Sopenharmony_ci	GPIO98_RX_DQ1,
1018c2ecf20Sopenharmony_ci	GPIO99_RX_DQ0,
1028c2ecf20Sopenharmony_ci	GPIO100_MII_MDC,
1038c2ecf20Sopenharmony_ci	GPIO101_MII_MDIO,
1048c2ecf20Sopenharmony_ci	GPIO103_RX_DV,
1058c2ecf20Sopenharmony_ci	GPIO104_GPIO,     /* Reset PHY */
1068c2ecf20Sopenharmony_ci
1078c2ecf20Sopenharmony_ci	/* RTC interrupt */
1088c2ecf20Sopenharmony_ci	GPIO102_GPIO,
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_ci	/* I2C */
1118c2ecf20Sopenharmony_ci	GPIO105_CI2C_SDA,
1128c2ecf20Sopenharmony_ci	GPIO106_CI2C_SCL,
1138c2ecf20Sopenharmony_ci
1148c2ecf20Sopenharmony_ci	/* SPI NOR Flash on SSP2 */
1158c2ecf20Sopenharmony_ci	GPIO107_SSP2_RXD,
1168c2ecf20Sopenharmony_ci	GPIO108_SSP2_TXD,
1178c2ecf20Sopenharmony_ci	GPIO110_GPIO,     /* SPI_CSn */
1188c2ecf20Sopenharmony_ci	GPIO111_SSP2_CLK,
1198c2ecf20Sopenharmony_ci
1208c2ecf20Sopenharmony_ci	/* Select JTAG */
1218c2ecf20Sopenharmony_ci	GPIO109_GPIO,
1228c2ecf20Sopenharmony_ci
1238c2ecf20Sopenharmony_ci	/* I2S */
1248c2ecf20Sopenharmony_ci	GPIO114_I2S_FRM,
1258c2ecf20Sopenharmony_ci	GPIO115_I2S_BCLK,
1268c2ecf20Sopenharmony_ci	GPIO116_I2S_TXD
1278c2ecf20Sopenharmony_ci};
1288c2ecf20Sopenharmony_ci
1298c2ecf20Sopenharmony_cistatic struct pxa_gpio_platform_data pxa168_gpio_pdata = {
1308c2ecf20Sopenharmony_ci	.irq_base	= MMP_GPIO_TO_IRQ(0),
1318c2ecf20Sopenharmony_ci};
1328c2ecf20Sopenharmony_ci
1338c2ecf20Sopenharmony_cistatic struct i2c_board_info gplugd_i2c_board_info[] = {
1348c2ecf20Sopenharmony_ci	{
1358c2ecf20Sopenharmony_ci		.type = "isl1208",
1368c2ecf20Sopenharmony_ci		.addr = 0x6F,
1378c2ecf20Sopenharmony_ci	}
1388c2ecf20Sopenharmony_ci};
1398c2ecf20Sopenharmony_ci
1408c2ecf20Sopenharmony_ci/* Bring PHY out of reset by setting GPIO 104 */
1418c2ecf20Sopenharmony_cistatic int gplugd_eth_init(void)
1428c2ecf20Sopenharmony_ci{
1438c2ecf20Sopenharmony_ci	if (unlikely(gpio_request(104, "ETH_RESET_N"))) {
1448c2ecf20Sopenharmony_ci		printk(KERN_ERR "Can't get hold of GPIO 104 to bring Ethernet "
1458c2ecf20Sopenharmony_ci				"PHY out of reset\n");
1468c2ecf20Sopenharmony_ci		return -EIO;
1478c2ecf20Sopenharmony_ci	}
1488c2ecf20Sopenharmony_ci
1498c2ecf20Sopenharmony_ci	gpio_direction_output(104, 1);
1508c2ecf20Sopenharmony_ci	gpio_free(104);
1518c2ecf20Sopenharmony_ci	return 0;
1528c2ecf20Sopenharmony_ci}
1538c2ecf20Sopenharmony_ci
1548c2ecf20Sopenharmony_cistruct pxa168_eth_platform_data gplugd_eth_platform_data = {
1558c2ecf20Sopenharmony_ci	.port_number = 0,
1568c2ecf20Sopenharmony_ci	.phy_addr    = 0,
1578c2ecf20Sopenharmony_ci	.speed       = 0, /* Autonagotiation */
1588c2ecf20Sopenharmony_ci	.intf        = PHY_INTERFACE_MODE_RMII,
1598c2ecf20Sopenharmony_ci	.init        = gplugd_eth_init,
1608c2ecf20Sopenharmony_ci};
1618c2ecf20Sopenharmony_ci
1628c2ecf20Sopenharmony_cistatic void __init select_disp_freq(void)
1638c2ecf20Sopenharmony_ci{
1648c2ecf20Sopenharmony_ci	/* set GPIO 35 & clear GPIO 85 to set LCD External Clock to 74.25 MHz */
1658c2ecf20Sopenharmony_ci	if (unlikely(gpio_request(35, "DISP_FREQ_SEL"))) {
1668c2ecf20Sopenharmony_ci		printk(KERN_ERR "Can't get hold of GPIO 35 to select display "
1678c2ecf20Sopenharmony_ci				"frequency\n");
1688c2ecf20Sopenharmony_ci	} else {
1698c2ecf20Sopenharmony_ci		gpio_direction_output(35, 1);
1708c2ecf20Sopenharmony_ci		gpio_free(35);
1718c2ecf20Sopenharmony_ci	}
1728c2ecf20Sopenharmony_ci
1738c2ecf20Sopenharmony_ci	if (unlikely(gpio_request(85, "DISP_FREQ_SEL_2"))) {
1748c2ecf20Sopenharmony_ci		printk(KERN_ERR "Can't get hold of GPIO 85 to select display "
1758c2ecf20Sopenharmony_ci				"frequency\n");
1768c2ecf20Sopenharmony_ci	} else {
1778c2ecf20Sopenharmony_ci		gpio_direction_output(85, 0);
1788c2ecf20Sopenharmony_ci		gpio_free(85);
1798c2ecf20Sopenharmony_ci	}
1808c2ecf20Sopenharmony_ci}
1818c2ecf20Sopenharmony_ci
1828c2ecf20Sopenharmony_cistatic void __init gplugd_init(void)
1838c2ecf20Sopenharmony_ci{
1848c2ecf20Sopenharmony_ci	mfp_config(ARRAY_AND_SIZE(gplugd_pin_config));
1858c2ecf20Sopenharmony_ci
1868c2ecf20Sopenharmony_ci	select_disp_freq();
1878c2ecf20Sopenharmony_ci
1888c2ecf20Sopenharmony_ci	/* on-chip devices */
1898c2ecf20Sopenharmony_ci	pxa168_add_uart(3);
1908c2ecf20Sopenharmony_ci	pxa168_add_ssp(1);
1918c2ecf20Sopenharmony_ci	pxa168_add_twsi(0, NULL, ARRAY_AND_SIZE(gplugd_i2c_board_info));
1928c2ecf20Sopenharmony_ci	platform_device_add_data(&pxa168_device_gpio, &pxa168_gpio_pdata,
1938c2ecf20Sopenharmony_ci				 sizeof(struct pxa_gpio_platform_data));
1948c2ecf20Sopenharmony_ci	platform_device_register(&pxa168_device_gpio);
1958c2ecf20Sopenharmony_ci
1968c2ecf20Sopenharmony_ci	pxa168_add_eth(&gplugd_eth_platform_data);
1978c2ecf20Sopenharmony_ci}
1988c2ecf20Sopenharmony_ci
1998c2ecf20Sopenharmony_ciMACHINE_START(GPLUGD, "PXA168-based GuruPlug Display (gplugD) Platform")
2008c2ecf20Sopenharmony_ci	.map_io		= mmp_map_io,
2018c2ecf20Sopenharmony_ci	.nr_irqs	= MMP_NR_IRQS,
2028c2ecf20Sopenharmony_ci	.init_irq       = pxa168_init_irq,
2038c2ecf20Sopenharmony_ci	.init_time	= pxa168_timer_init,
2048c2ecf20Sopenharmony_ci	.init_machine   = gplugd_init,
2058c2ecf20Sopenharmony_ci	.restart	= pxa168_restart,
2068c2ecf20Sopenharmony_ciMACHINE_END
207