1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Renesas - AP-325RXA
4  * (Compatible with Algo System ., LTD. - AP-320A)
5  *
6  * Copyright (C) 2008 Renesas Solutions Corp.
7  * Author : Yusuke Goda <goda.yuske@renesas.com>
8  */
9 
10 #include <asm/clock.h>
11 #include <asm/io.h>
12 #include <asm/suspend.h>
13 
14 #include <cpu/sh7723.h>
15 
16 #include <linux/dma-map-ops.h>
17 #include <linux/clkdev.h>
18 #include <linux/delay.h>
19 #include <linux/device.h>
20 #include <linux/gpio.h>
21 #include <linux/gpio/machine.h>
22 #include <linux/i2c.h>
23 #include <linux/init.h>
24 #include <linux/interrupt.h>
25 #include <linux/memblock.h>
26 #include <linux/mfd/tmio.h>
27 #include <linux/mmc/host.h>
28 #include <linux/mtd/physmap.h>
29 #include <linux/mtd/sh_flctl.h>
30 #include <linux/platform_device.h>
31 #include <linux/regulator/fixed.h>
32 #include <linux/regulator/machine.h>
33 #include <linux/sh_intc.h>
34 #include <linux/smsc911x.h>
35 #include <linux/videodev2.h>
36 
37 #include <media/drv-intf/renesas-ceu.h>
38 #include <media/i2c/ov772x.h>
39 
40 #include <video/sh_mobile_lcdc.h>
41 
42 #define CEU_BUFFER_MEMORY_SIZE		(4 << 20)
43 static phys_addr_t ceu_dma_membase;
44 
45 /* Dummy supplies, where voltage doesn't matter */
46 static struct regulator_consumer_supply dummy_supplies[] = {
47 	REGULATOR_SUPPLY("vddvario", "smsc911x"),
48 	REGULATOR_SUPPLY("vdd33a", "smsc911x"),
49 };
50 
51 static struct smsc911x_platform_config smsc911x_config = {
52 	.phy_interface	= PHY_INTERFACE_MODE_MII,
53 	.irq_polarity	= SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
54 	.irq_type	= SMSC911X_IRQ_TYPE_OPEN_DRAIN,
55 	.flags		= SMSC911X_USE_32BIT,
56 };
57 
58 static struct resource smsc9118_resources[] = {
59 	[0] = {
60 		.start	= 0xb6080000,
61 		.end	= 0xb60fffff,
62 		.flags	= IORESOURCE_MEM,
63 	},
64 	[1] = {
65 		.start	= evt2irq(0x660),
66 		.end	= evt2irq(0x660),
67 		.flags	= IORESOURCE_IRQ,
68 	}
69 };
70 
71 static struct platform_device smsc9118_device = {
72 	.name		= "smsc911x",
73 	.id		= -1,
74 	.num_resources	= ARRAY_SIZE(smsc9118_resources),
75 	.resource	= smsc9118_resources,
76 	.dev		= {
77 		.platform_data = &smsc911x_config,
78 	},
79 };
80 
81 /*
82  * AP320 and AP325RXA has CPLD data in NOR Flash(0xA80000-0xABFFFF).
83  * If this area erased, this board can not boot.
84  */
85 static struct mtd_partition ap325rxa_nor_flash_partitions[] = {
86 	{
87 		.name = "uboot",
88 		.offset = 0,
89 		.size = (1 * 1024 * 1024),
90 		.mask_flags = MTD_WRITEABLE,	/* Read-only */
91 	}, {
92 		.name = "kernel",
93 		.offset = MTDPART_OFS_APPEND,
94 		.size = (2 * 1024 * 1024),
95 	}, {
96 		.name = "free-area0",
97 		.offset = MTDPART_OFS_APPEND,
98 		.size = ((7 * 1024 * 1024) + (512 * 1024)),
99 	}, {
100 		.name = "CPLD-Data",
101 		.offset = MTDPART_OFS_APPEND,
102 		.mask_flags = MTD_WRITEABLE,	/* Read-only */
103 		.size = (1024 * 128 * 2),
104 	}, {
105 		.name = "free-area1",
106 		.offset = MTDPART_OFS_APPEND,
107 		.size = MTDPART_SIZ_FULL,
108 	},
109 };
110 
111 static struct physmap_flash_data ap325rxa_nor_flash_data = {
112 	.width		= 2,
113 	.parts		= ap325rxa_nor_flash_partitions,
114 	.nr_parts	= ARRAY_SIZE(ap325rxa_nor_flash_partitions),
115 };
116 
117 static struct resource ap325rxa_nor_flash_resources[] = {
118 	[0] = {
119 		.name	= "NOR Flash",
120 		.start	= 0x00000000,
121 		.end	= 0x00ffffff,
122 		.flags	= IORESOURCE_MEM,
123 	}
124 };
125 
126 static struct platform_device ap325rxa_nor_flash_device = {
127 	.name		= "physmap-flash",
128 	.resource	= ap325rxa_nor_flash_resources,
129 	.num_resources	= ARRAY_SIZE(ap325rxa_nor_flash_resources),
130 	.dev		= {
131 		.platform_data = &ap325rxa_nor_flash_data,
132 	},
133 };
134 
135 static struct mtd_partition nand_partition_info[] = {
136 	{
137 		.name	= "nand_data",
138 		.offset	= 0,
139 		.size	= MTDPART_SIZ_FULL,
140 	},
141 };
142 
143 static struct resource nand_flash_resources[] = {
144 	[0] = {
145 		.start	= 0xa4530000,
146 		.end	= 0xa45300ff,
147 		.flags	= IORESOURCE_MEM,
148 	}
149 };
150 
151 static struct sh_flctl_platform_data nand_flash_data = {
152 	.parts		= nand_partition_info,
153 	.nr_parts	= ARRAY_SIZE(nand_partition_info),
154 	.flcmncr_val	= FCKSEL_E | TYPESEL_SET | NANWF_E,
155 	.has_hwecc	= 1,
156 };
157 
158 static struct platform_device nand_flash_device = {
159 	.name		= "sh_flctl",
160 	.resource	= nand_flash_resources,
161 	.num_resources	= ARRAY_SIZE(nand_flash_resources),
162 	.dev		= {
163 		.platform_data = &nand_flash_data,
164 	},
165 };
166 
167 #define FPGA_LCDREG	0xB4100180
168 #define FPGA_BKLREG	0xB4100212
169 #define FPGA_LCDREG_VAL	0x0018
170 #define PORT_MSELCRB	0xA4050182
171 #define PORT_HIZCRC	0xA405015C
172 #define PORT_DRVCRA	0xA405018A
173 #define PORT_DRVCRB	0xA405018C
174 
175 static int ap320_wvga_set_brightness(int brightness)
176 {
177 	if (brightness) {
178 		gpio_set_value(GPIO_PTS3, 0);
179 		__raw_writew(0x100, FPGA_BKLREG);
180 	} else {
181 		__raw_writew(0, FPGA_BKLREG);
182 		gpio_set_value(GPIO_PTS3, 1);
183 	}
184 
185 	return 0;
186 }
187 
188 static void ap320_wvga_power_on(void)
189 {
190 	msleep(100);
191 
192 	/* ASD AP-320/325 LCD ON */
193 	__raw_writew(FPGA_LCDREG_VAL, FPGA_LCDREG);
194 }
195 
196 static void ap320_wvga_power_off(void)
197 {
198 	/* ASD AP-320/325 LCD OFF */
199 	__raw_writew(0, FPGA_LCDREG);
200 }
201 
202 static const struct fb_videomode ap325rxa_lcdc_modes[] = {
203 	{
204 		.name = "LB070WV1",
205 		.xres = 800,
206 		.yres = 480,
207 		.left_margin = 32,
208 		.right_margin = 160,
209 		.hsync_len = 8,
210 		.upper_margin = 63,
211 		.lower_margin = 80,
212 		.vsync_len = 1,
213 		.sync = 0, /* hsync and vsync are active low */
214 	},
215 };
216 
217 static struct sh_mobile_lcdc_info lcdc_info = {
218 	.clock_source = LCDC_CLK_EXTERNAL,
219 	.ch[0] = {
220 		.chan = LCDC_CHAN_MAINLCD,
221 		.fourcc = V4L2_PIX_FMT_RGB565,
222 		.interface_type = RGB18,
223 		.clock_divider = 1,
224 		.lcd_modes = ap325rxa_lcdc_modes,
225 		.num_modes = ARRAY_SIZE(ap325rxa_lcdc_modes),
226 		.panel_cfg = {
227 			.width = 152,	/* 7.0 inch */
228 			.height = 91,
229 			.display_on = ap320_wvga_power_on,
230 			.display_off = ap320_wvga_power_off,
231 		},
232 		.bl_info = {
233 			.name = "sh_mobile_lcdc_bl",
234 			.max_brightness = 1,
235 			.set_brightness = ap320_wvga_set_brightness,
236 		},
237 	}
238 };
239 
240 static struct resource lcdc_resources[] = {
241 	[0] = {
242 		.name	= "LCDC",
243 		.start	= 0xfe940000, /* P4-only space */
244 		.end	= 0xfe942fff,
245 		.flags	= IORESOURCE_MEM,
246 	},
247 	[1] = {
248 		.start	= evt2irq(0x580),
249 		.flags	= IORESOURCE_IRQ,
250 	},
251 };
252 
253 static struct platform_device lcdc_device = {
254 	.name		= "sh_mobile_lcdc_fb",
255 	.num_resources	= ARRAY_SIZE(lcdc_resources),
256 	.resource	= lcdc_resources,
257 	.dev		= {
258 		.platform_data	= &lcdc_info,
259 	},
260 };
261 
262 /* Powerdown/reset gpios for CEU image sensors */
263 static struct gpiod_lookup_table ov7725_gpios = {
264 	.dev_id		= "0-0021",
265 	.table		= {
266 		GPIO_LOOKUP("sh7723_pfc", GPIO_PTZ5, "reset", GPIO_ACTIVE_LOW),
267 	},
268 };
269 
270 static struct ceu_platform_data ceu0_pdata = {
271 	.num_subdevs			= 1,
272 	.subdevs = {
273 		{ /* [0] = ov7725  */
274 			.flags		= 0,
275 			.bus_width	= 8,
276 			.bus_shift	= 0,
277 			.i2c_adapter_id	= 0,
278 			.i2c_address	= 0x21,
279 		},
280 	},
281 };
282 
283 static struct resource ceu_resources[] = {
284 	[0] = {
285 		.name	= "CEU",
286 		.start	= 0xfe910000,
287 		.end	= 0xfe91009f,
288 		.flags	= IORESOURCE_MEM,
289 	},
290 	[1] = {
291 		.start  = evt2irq(0x880),
292 		.flags  = IORESOURCE_IRQ,
293 	},
294 };
295 
296 static struct platform_device ap325rxa_ceu_device = {
297 	.name		= "renesas-ceu",
298 	.id             = 0, /* "ceu.0" clock */
299 	.num_resources	= ARRAY_SIZE(ceu_resources),
300 	.resource	= ceu_resources,
301 	.dev		= {
302 		.platform_data	= &ceu0_pdata,
303 	},
304 };
305 
306 /* Fixed 3.3V regulators to be used by SDHI0, SDHI1 */
307 static struct regulator_consumer_supply fixed3v3_power_consumers[] =
308 {
309 	REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"),
310 	REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.0"),
311 	REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.1"),
312 	REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.1"),
313 };
314 
315 static struct resource sdhi0_cn3_resources[] = {
316 	[0] = {
317 		.name	= "SDHI0",
318 		.start	= 0x04ce0000,
319 		.end	= 0x04ce00ff,
320 		.flags	= IORESOURCE_MEM,
321 	},
322 	[1] = {
323 		.start	= evt2irq(0xe80),
324 		.flags  = IORESOURCE_IRQ,
325 	},
326 };
327 
328 static struct tmio_mmc_data sdhi0_cn3_data = {
329 	.capabilities	= MMC_CAP_SDIO_IRQ,
330 };
331 
332 static struct platform_device sdhi0_cn3_device = {
333 	.name		= "sh_mobile_sdhi",
334 	.id             = 0, /* "sdhi0" clock */
335 	.num_resources	= ARRAY_SIZE(sdhi0_cn3_resources),
336 	.resource	= sdhi0_cn3_resources,
337 	.dev = {
338 		.platform_data = &sdhi0_cn3_data,
339 	},
340 };
341 
342 static struct resource sdhi1_cn7_resources[] = {
343 	[0] = {
344 		.name	= "SDHI1",
345 		.start	= 0x04cf0000,
346 		.end	= 0x04cf00ff,
347 		.flags	= IORESOURCE_MEM,
348 	},
349 	[1] = {
350 		.start	= evt2irq(0x4e0),
351 		.flags  = IORESOURCE_IRQ,
352 	},
353 };
354 
355 static struct tmio_mmc_data sdhi1_cn7_data = {
356 	.capabilities	= MMC_CAP_SDIO_IRQ,
357 };
358 
359 static struct platform_device sdhi1_cn7_device = {
360 	.name		= "sh_mobile_sdhi",
361 	.id             = 1, /* "sdhi1" clock */
362 	.num_resources	= ARRAY_SIZE(sdhi1_cn7_resources),
363 	.resource	= sdhi1_cn7_resources,
364 	.dev = {
365 		.platform_data = &sdhi1_cn7_data,
366 	},
367 };
368 
369 static struct ov772x_camera_info ov7725_info = {
370 	.flags		= OV772X_FLAG_VFLIP | OV772X_FLAG_HFLIP,
371 	.edgectrl	= OV772X_AUTO_EDGECTRL(0xf, 0),
372 };
373 
374 static struct i2c_board_info ap325rxa_i2c_devices[] __initdata = {
375 	{
376 		I2C_BOARD_INFO("pcf8563", 0x51),
377 	},
378 	{
379 		I2C_BOARD_INFO("ov772x", 0x21),
380 		.platform_data = &ov7725_info,
381 	},
382 };
383 
384 static struct platform_device *ap325rxa_devices[] __initdata = {
385 	&smsc9118_device,
386 	&ap325rxa_nor_flash_device,
387 	&lcdc_device,
388 	&nand_flash_device,
389 	&sdhi0_cn3_device,
390 	&sdhi1_cn7_device,
391 };
392 
393 extern char ap325rxa_sdram_enter_start;
394 extern char ap325rxa_sdram_enter_end;
395 extern char ap325rxa_sdram_leave_start;
396 extern char ap325rxa_sdram_leave_end;
397 
398 static int __init ap325rxa_devices_setup(void)
399 {
400 	/* register board specific self-refresh code */
401 	sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF,
402 					&ap325rxa_sdram_enter_start,
403 					&ap325rxa_sdram_enter_end,
404 					&ap325rxa_sdram_leave_start,
405 					&ap325rxa_sdram_leave_end);
406 
407 	regulator_register_always_on(0, "fixed-3.3V", fixed3v3_power_consumers,
408 				     ARRAY_SIZE(fixed3v3_power_consumers), 3300000);
409 	regulator_register_fixed(1, dummy_supplies, ARRAY_SIZE(dummy_supplies));
410 
411 	/* LD3 and LD4 LEDs */
412 	gpio_request(GPIO_PTX5, NULL); /* RUN */
413 	gpio_direction_output(GPIO_PTX5, 1);
414 	gpio_export(GPIO_PTX5, 0);
415 
416 	gpio_request(GPIO_PTX4, NULL); /* INDICATOR */
417 	gpio_direction_output(GPIO_PTX4, 0);
418 	gpio_export(GPIO_PTX4, 0);
419 
420 	/* SW1 input */
421 	gpio_request(GPIO_PTF7, NULL); /* MODE */
422 	gpio_direction_input(GPIO_PTF7);
423 	gpio_export(GPIO_PTF7, 0);
424 
425 	/* LCDC */
426 	gpio_request(GPIO_FN_LCDD15, NULL);
427 	gpio_request(GPIO_FN_LCDD14, NULL);
428 	gpio_request(GPIO_FN_LCDD13, NULL);
429 	gpio_request(GPIO_FN_LCDD12, NULL);
430 	gpio_request(GPIO_FN_LCDD11, NULL);
431 	gpio_request(GPIO_FN_LCDD10, NULL);
432 	gpio_request(GPIO_FN_LCDD9, NULL);
433 	gpio_request(GPIO_FN_LCDD8, NULL);
434 	gpio_request(GPIO_FN_LCDD7, NULL);
435 	gpio_request(GPIO_FN_LCDD6, NULL);
436 	gpio_request(GPIO_FN_LCDD5, NULL);
437 	gpio_request(GPIO_FN_LCDD4, NULL);
438 	gpio_request(GPIO_FN_LCDD3, NULL);
439 	gpio_request(GPIO_FN_LCDD2, NULL);
440 	gpio_request(GPIO_FN_LCDD1, NULL);
441 	gpio_request(GPIO_FN_LCDD0, NULL);
442 	gpio_request(GPIO_FN_LCDLCLK_PTR, NULL);
443 	gpio_request(GPIO_FN_LCDDCK, NULL);
444 	gpio_request(GPIO_FN_LCDVEPWC, NULL);
445 	gpio_request(GPIO_FN_LCDVCPWC, NULL);
446 	gpio_request(GPIO_FN_LCDVSYN, NULL);
447 	gpio_request(GPIO_FN_LCDHSYN, NULL);
448 	gpio_request(GPIO_FN_LCDDISP, NULL);
449 	gpio_request(GPIO_FN_LCDDON, NULL);
450 
451 	/* LCD backlight */
452 	gpio_request(GPIO_PTS3, NULL);
453 	gpio_direction_output(GPIO_PTS3, 1);
454 
455 	/* CEU */
456 	gpio_request(GPIO_FN_VIO_CLK2, NULL);
457 	gpio_request(GPIO_FN_VIO_VD2, NULL);
458 	gpio_request(GPIO_FN_VIO_HD2, NULL);
459 	gpio_request(GPIO_FN_VIO_FLD, NULL);
460 	gpio_request(GPIO_FN_VIO_CKO, NULL);
461 	gpio_request(GPIO_FN_VIO_D15, NULL);
462 	gpio_request(GPIO_FN_VIO_D14, NULL);
463 	gpio_request(GPIO_FN_VIO_D13, NULL);
464 	gpio_request(GPIO_FN_VIO_D12, NULL);
465 	gpio_request(GPIO_FN_VIO_D11, NULL);
466 	gpio_request(GPIO_FN_VIO_D10, NULL);
467 	gpio_request(GPIO_FN_VIO_D9, NULL);
468 	gpio_request(GPIO_FN_VIO_D8, NULL);
469 
470 	gpio_request(GPIO_PTZ7, NULL);
471 	gpio_direction_output(GPIO_PTZ7, 0); /* OE_CAM */
472 	gpio_request(GPIO_PTZ6, NULL);
473 	gpio_direction_output(GPIO_PTZ6, 0); /* STBY_CAM */
474 	gpio_request(GPIO_PTZ5, NULL);
475 	gpio_direction_output(GPIO_PTZ5, 0); /* RST_CAM */
476 	gpio_request(GPIO_PTZ4, NULL);
477 	gpio_direction_output(GPIO_PTZ4, 0); /* SADDR */
478 
479 	__raw_writew(__raw_readw(PORT_MSELCRB) & ~0x0001, PORT_MSELCRB);
480 
481 	/* FLCTL */
482 	gpio_request(GPIO_FN_FCE, NULL);
483 	gpio_request(GPIO_FN_NAF7, NULL);
484 	gpio_request(GPIO_FN_NAF6, NULL);
485 	gpio_request(GPIO_FN_NAF5, NULL);
486 	gpio_request(GPIO_FN_NAF4, NULL);
487 	gpio_request(GPIO_FN_NAF3, NULL);
488 	gpio_request(GPIO_FN_NAF2, NULL);
489 	gpio_request(GPIO_FN_NAF1, NULL);
490 	gpio_request(GPIO_FN_NAF0, NULL);
491 	gpio_request(GPIO_FN_FCDE, NULL);
492 	gpio_request(GPIO_FN_FOE, NULL);
493 	gpio_request(GPIO_FN_FSC, NULL);
494 	gpio_request(GPIO_FN_FWE, NULL);
495 	gpio_request(GPIO_FN_FRB, NULL);
496 
497 	__raw_writew(0, PORT_HIZCRC);
498 	__raw_writew(0xFFFF, PORT_DRVCRA);
499 	__raw_writew(0xFFFF, PORT_DRVCRB);
500 
501 	/* SDHI0 - CN3 - SD CARD */
502 	gpio_request(GPIO_FN_SDHI0CD_PTD, NULL);
503 	gpio_request(GPIO_FN_SDHI0WP_PTD, NULL);
504 	gpio_request(GPIO_FN_SDHI0D3_PTD, NULL);
505 	gpio_request(GPIO_FN_SDHI0D2_PTD, NULL);
506 	gpio_request(GPIO_FN_SDHI0D1_PTD, NULL);
507 	gpio_request(GPIO_FN_SDHI0D0_PTD, NULL);
508 	gpio_request(GPIO_FN_SDHI0CMD_PTD, NULL);
509 	gpio_request(GPIO_FN_SDHI0CLK_PTD, NULL);
510 
511 	/* SDHI1 - CN7 - MICRO SD CARD */
512 	gpio_request(GPIO_FN_SDHI1CD, NULL);
513 	gpio_request(GPIO_FN_SDHI1D3, NULL);
514 	gpio_request(GPIO_FN_SDHI1D2, NULL);
515 	gpio_request(GPIO_FN_SDHI1D1, NULL);
516 	gpio_request(GPIO_FN_SDHI1D0, NULL);
517 	gpio_request(GPIO_FN_SDHI1CMD, NULL);
518 	gpio_request(GPIO_FN_SDHI1CLK, NULL);
519 
520 	/* Add a clock alias for ov7725 xclk source. */
521 	clk_add_alias(NULL, "0-0021", "video_clk", NULL);
522 
523 	/* Register RSTB gpio for ov7725 camera sensor. */
524 	gpiod_add_lookup_table(&ov7725_gpios);
525 
526 	i2c_register_board_info(0, ap325rxa_i2c_devices,
527 				ARRAY_SIZE(ap325rxa_i2c_devices));
528 
529 	/* Initialize CEU platform device separately to map memory first */
530 	device_initialize(&ap325rxa_ceu_device.dev);
531 	dma_declare_coherent_memory(&ap325rxa_ceu_device.dev,
532 			ceu_dma_membase, ceu_dma_membase,
533 			ceu_dma_membase + CEU_BUFFER_MEMORY_SIZE - 1);
534 
535 	platform_device_add(&ap325rxa_ceu_device);
536 
537 	return platform_add_devices(ap325rxa_devices,
538 				ARRAY_SIZE(ap325rxa_devices));
539 }
540 arch_initcall(ap325rxa_devices_setup);
541 
542 /* Return the board specific boot mode pin configuration */
543 static int ap325rxa_mode_pins(void)
544 {
545 	/* MD0=0, MD1=0, MD2=0: Clock Mode 0
546 	 * MD3=0: 16-bit Area0 Bus Width
547 	 * MD5=1: Little Endian
548 	 * TSTMD=1, MD8=1: Test Mode Disabled
549 	 */
550 	return MODE_PIN5 | MODE_PIN8;
551 }
552 
553 /* Reserve a portion of memory for CEU buffers */
554 static void __init ap325rxa_mv_mem_reserve(void)
555 {
556 	phys_addr_t phys;
557 	phys_addr_t size = CEU_BUFFER_MEMORY_SIZE;
558 
559 	phys = memblock_phys_alloc(size, PAGE_SIZE);
560 	if (!phys)
561 		panic("Failed to allocate CEU memory\n");
562 
563 	memblock_phys_free(phys, size);
564 	memblock_remove(phys, size);
565 
566 	ceu_dma_membase = phys;
567 }
568 
569 static struct sh_machine_vector mv_ap325rxa __initmv = {
570 	.mv_name = "AP-325RXA",
571 	.mv_mode_pins = ap325rxa_mode_pins,
572 	.mv_mem_reserve	= ap325rxa_mv_mem_reserve,
573 };
574