1
+ // SPDX-License-Identifier: GPL-2.0
1
2
/*
2
3
* Renesas System Solutions Asia Pte. Ltd - Migo-R
3
4
*
4
5
* Copyright (C) 2008 Magnus Damm
5
- *
6
- * This file is subject to the terms and conditions of the GNU General Public
7
- * License. See the file "COPYING" in the main directory of this archive
8
- * for more details.
9
6
*/
7
+ #include <linux/clkdev.h>
10
8
#include <linux/init.h>
11
9
#include <linux/platform_device.h>
12
10
#include <linux/interrupt.h>
13
11
#include <linux/input.h>
14
12
#include <linux/input/sh_keysc.h>
13
+ #include <linux/memblock.h>
15
14
#include <linux/mmc/host.h>
16
15
#include <linux/mtd/physmap.h>
17
16
#include <linux/mfd/tmio.h>
23
22
#include <linux/delay.h>
24
23
#include <linux/clk.h>
25
24
#include <linux/gpio.h>
25
+ #include <linux/gpio/machine.h>
26
26
#include <linux/videodev2.h>
27
27
#include <linux/sh_intc.h>
28
28
#include <video/sh_mobile_lcdc.h>
29
- #include <media/drv-intf/sh_mobile_ceu .h>
29
+ #include <media/drv-intf/renesas-ceu .h>
30
30
#include <media/i2c/ov772x.h>
31
31
#include <media/soc_camera.h>
32
32
#include <media/i2c/tw9910.h>
45
45
* 0x18000000 8GB 8 NAND Flash (K9K8G08U0A)
46
46
*/
47
47
48
+ #define CEU_BUFFER_MEMORY_SIZE (4 << 20)
49
+ static phys_addr_t ceu_dma_membase ;
50
+
48
51
static struct smc91x_platdata smc91x_info = {
49
52
.flags = SMC91X_USE_16BIT | SMC91X_NOWAIT ,
50
53
};
@@ -301,65 +304,24 @@ static struct platform_device migor_lcdc_device = {
301
304
},
302
305
};
303
306
304
- static struct clk * camera_clk ;
305
- static DEFINE_MUTEX (camera_lock );
306
-
307
- static void camera_power_on (int is_tw )
308
- {
309
- mutex_lock (& camera_lock );
310
-
311
- /* Use 10 MHz VIO_CKO instead of 24 MHz to work
312
- * around signal quality issues on Panel Board V2.1.
313
- */
314
- camera_clk = clk_get (NULL , "video_clk" );
315
- clk_set_rate (camera_clk , 10000000 );
316
- clk_enable (camera_clk ); /* start VIO_CKO */
317
-
318
- /* use VIO_RST to take camera out of reset */
319
- mdelay (10 );
320
- if (is_tw ) {
321
- gpio_set_value (GPIO_PTT2 , 0 );
322
- gpio_set_value (GPIO_PTT0 , 0 );
323
- } else {
324
- gpio_set_value (GPIO_PTT0 , 1 );
325
- }
326
- gpio_set_value (GPIO_PTT3 , 0 );
327
- mdelay (10 );
328
- gpio_set_value (GPIO_PTT3 , 1 );
329
- mdelay (10 ); /* wait to let chip come out of reset */
330
- }
331
-
332
- static void camera_power_off (void )
333
- {
334
- clk_disable (camera_clk ); /* stop VIO_CKO */
335
- clk_put (camera_clk );
336
-
337
- gpio_set_value (GPIO_PTT3 , 0 );
338
- mutex_unlock (& camera_lock );
339
- }
340
-
341
- static int ov7725_power (struct device * dev , int mode )
342
- {
343
- if (mode )
344
- camera_power_on (0 );
345
- else
346
- camera_power_off ();
347
-
348
- return 0 ;
349
- }
350
-
351
- static int tw9910_power (struct device * dev , int mode )
352
- {
353
- if (mode )
354
- camera_power_on (1 );
355
- else
356
- camera_power_off ();
357
-
358
- return 0 ;
359
- }
360
-
361
- static struct sh_mobile_ceu_info sh_mobile_ceu_info = {
362
- .flags = SH_CEU_FLAG_USE_8BIT_BUS ,
307
+ static struct ceu_platform_data ceu_pdata = {
308
+ .num_subdevs = 2 ,
309
+ .subdevs = {
310
+ { /* [0] = ov772x */
311
+ .flags = 0 ,
312
+ .bus_width = 8 ,
313
+ .bus_shift = 0 ,
314
+ .i2c_adapter_id = 0 ,
315
+ .i2c_address = 0x21 ,
316
+ },
317
+ { /* [1] = tw9910 */
318
+ .flags = 0 ,
319
+ .bus_width = 8 ,
320
+ .bus_shift = 0 ,
321
+ .i2c_adapter_id = 0 ,
322
+ .i2c_address = 0x45 ,
323
+ },
324
+ },
363
325
};
364
326
365
327
static struct resource migor_ceu_resources [] = {
@@ -373,18 +335,32 @@ static struct resource migor_ceu_resources[] = {
373
335
.start = evt2irq (0x880 ),
374
336
.flags = IORESOURCE_IRQ ,
375
337
},
376
- [2 ] = {
377
- /* place holder for contiguous memory */
378
- },
379
338
};
380
339
381
340
static struct platform_device migor_ceu_device = {
382
- .name = "sh_mobile_ceu " ,
383
- .id = 0 , /* "ceu0" clock */
341
+ .name = "renesas-ceu " ,
342
+ .id = 0 , /* ceu.0 */
384
343
.num_resources = ARRAY_SIZE (migor_ceu_resources ),
385
344
.resource = migor_ceu_resources ,
386
345
.dev = {
387
- .platform_data = & sh_mobile_ceu_info ,
346
+ .platform_data = & ceu_pdata ,
347
+ },
348
+ };
349
+
350
+ /* Powerdown/reset gpios for CEU image sensors */
351
+ static struct gpiod_lookup_table ov7725_gpios = {
352
+ .dev_id = "0-0021" ,
353
+ .table = {
354
+ GPIO_LOOKUP ("sh7722_pfc" , GPIO_PTT0 , "pwdn" , GPIO_ACTIVE_HIGH ),
355
+ GPIO_LOOKUP ("sh7722_pfc" , GPIO_PTT3 , "rstb" , GPIO_ACTIVE_LOW ),
356
+ },
357
+ };
358
+
359
+ static struct gpiod_lookup_table tw9910_gpios = {
360
+ .dev_id = "0-0045" ,
361
+ .table = {
362
+ GPIO_LOOKUP ("sh7722_pfc" , GPIO_PTT2 , "pdn" , GPIO_ACTIVE_HIGH ),
363
+ GPIO_LOOKUP ("sh7722_pfc" , GPIO_PTT3 , "rstb" , GPIO_ACTIVE_LOW ),
388
364
},
389
365
};
390
366
@@ -423,6 +399,15 @@ static struct platform_device sdhi_cn9_device = {
423
399
},
424
400
};
425
401
402
+ static struct ov772x_camera_info ov7725_info = {
403
+ .flags = 0 ,
404
+ };
405
+
406
+ static struct tw9910_video_info tw9910_info = {
407
+ .buswidth = 8 ,
408
+ .mpout = TW9910_MPO_FIELD ,
409
+ };
410
+
426
411
static struct i2c_board_info migor_i2c_devices [] = {
427
412
{
428
413
I2C_BOARD_INFO ("rs5c372b" , 0x32 ),
@@ -434,64 +419,23 @@ static struct i2c_board_info migor_i2c_devices[] = {
434
419
{
435
420
I2C_BOARD_INFO ("wm8978" , 0x1a ),
436
421
},
437
- };
438
-
439
- static struct i2c_board_info migor_i2c_camera [] = {
440
422
{
441
423
I2C_BOARD_INFO ("ov772x" , 0x21 ),
424
+ .platform_data = & ov7725_info ,
442
425
},
443
426
{
444
427
I2C_BOARD_INFO ("tw9910" , 0x45 ),
445
- },
446
- };
447
-
448
- static struct ov772x_camera_info ov7725_info ;
449
-
450
- static struct soc_camera_link ov7725_link = {
451
- .power = ov7725_power ,
452
- .board_info = & migor_i2c_camera [0 ],
453
- .i2c_adapter_id = 0 ,
454
- .priv = & ov7725_info ,
455
- };
456
-
457
- static struct tw9910_video_info tw9910_info = {
458
- .buswidth = SOCAM_DATAWIDTH_8 ,
459
- .mpout = TW9910_MPO_FIELD ,
460
- };
461
-
462
- static struct soc_camera_link tw9910_link = {
463
- .power = tw9910_power ,
464
- .board_info = & migor_i2c_camera [1 ],
465
- .i2c_adapter_id = 0 ,
466
- .priv = & tw9910_info ,
467
- };
468
-
469
- static struct platform_device migor_camera [] = {
470
- {
471
- .name = "soc-camera-pdrv" ,
472
- .id = 0 ,
473
- .dev = {
474
- .platform_data = & ov7725_link ,
475
- },
476
- }, {
477
- .name = "soc-camera-pdrv" ,
478
- .id = 1 ,
479
- .dev = {
480
- .platform_data = & tw9910_link ,
481
- },
428
+ .platform_data = & tw9910_info ,
482
429
},
483
430
};
484
431
485
432
static struct platform_device * migor_devices [] __initdata = {
486
433
& smc91x_eth_device ,
487
434
& sh_keysc_device ,
488
435
& migor_lcdc_device ,
489
- & migor_ceu_device ,
490
436
& migor_nor_flash_device ,
491
437
& migor_nand_flash_device ,
492
438
& sdhi_cn9_device ,
493
- & migor_camera [0 ],
494
- & migor_camera [1 ],
495
439
};
496
440
497
441
extern char migor_sdram_enter_start ;
@@ -501,6 +445,8 @@ extern char migor_sdram_leave_end;
501
445
502
446
static int __init migor_devices_setup (void )
503
447
{
448
+ struct clk * video_clk ;
449
+
504
450
/* register board specific self-refresh code */
505
451
sh_mobile_register_self_refresh (SUSP_SH_STANDBY | SUSP_SH_SF ,
506
452
& migor_sdram_enter_start ,
@@ -620,20 +566,8 @@ static int __init migor_devices_setup(void)
620
566
gpio_request (GPIO_FN_VIO_D9 , NULL );
621
567
gpio_request (GPIO_FN_VIO_D8 , NULL );
622
568
623
- gpio_request (GPIO_PTT3 , NULL ); /* VIO_RST */
624
- gpio_direction_output (GPIO_PTT3 , 0 );
625
- gpio_request (GPIO_PTT2 , NULL ); /* TV_IN_EN */
626
- gpio_direction_output (GPIO_PTT2 , 1 );
627
- gpio_request (GPIO_PTT0 , NULL ); /* CAM_EN */
628
- #ifdef CONFIG_SH_MIGOR_RTA_WVGA
629
- gpio_direction_output (GPIO_PTT0 , 0 );
630
- #else
631
- gpio_direction_output (GPIO_PTT0 , 1 );
632
- #endif
633
569
__raw_writew (__raw_readw (PORT_MSELCRB ) | 0x2000 , PORT_MSELCRB ); /* D15->D8 */
634
570
635
- platform_resource_setup_memory (& migor_ceu_device , "ceu" , 4 << 20 );
636
-
637
571
/* SIU: Port B */
638
572
gpio_request (GPIO_FN_SIUBOLR , NULL );
639
573
gpio_request (GPIO_FN_SIUBOBT , NULL );
@@ -647,9 +581,36 @@ static int __init migor_devices_setup(void)
647
581
*/
648
582
__raw_writew (__raw_readw (PORT_MSELCRA ) | 1 , PORT_MSELCRA );
649
583
584
+ /*
585
+ * Use 10 MHz VIO_CKO instead of 24 MHz to work around signal quality
586
+ * issues on Panel Board V2.1.
587
+ */
588
+ video_clk = clk_get (NULL , "video_clk" );
589
+ if (!IS_ERR (video_clk )) {
590
+ clk_set_rate (video_clk , clk_round_rate (video_clk , 10000000 ));
591
+ clk_put (video_clk );
592
+ }
593
+
594
+ /* Add a clock alias for ov7725 xclk source. */
595
+ clk_add_alias ("xclk" , "0-0021" , "video_clk" , NULL );
596
+
597
+ /* Register GPIOs for video sources. */
598
+ gpiod_add_lookup_table (& ov7725_gpios );
599
+ gpiod_add_lookup_table (& tw9910_gpios );
600
+
650
601
i2c_register_board_info (0 , migor_i2c_devices ,
651
602
ARRAY_SIZE (migor_i2c_devices ));
652
603
604
+ /* Initialize CEU platform device separately to map memory first */
605
+ device_initialize (& migor_ceu_device .dev );
606
+ arch_setup_pdev_archdata (& migor_ceu_device );
607
+ dma_declare_coherent_memory (& migor_ceu_device .dev ,
608
+ ceu_dma_membase , ceu_dma_membase ,
609
+ ceu_dma_membase + CEU_BUFFER_MEMORY_SIZE - 1 ,
610
+ DMA_MEMORY_EXCLUSIVE );
611
+
612
+ platform_device_add (& migor_ceu_device );
613
+
653
614
return platform_add_devices (migor_devices , ARRAY_SIZE (migor_devices ));
654
615
}
655
616
arch_initcall (migor_devices_setup );
@@ -665,10 +626,24 @@ static int migor_mode_pins(void)
665
626
return MODE_PIN0 | MODE_PIN1 | MODE_PIN5 ;
666
627
}
667
628
629
+ /* Reserve a portion of memory for CEU buffers */
630
+ static void __init migor_mv_mem_reserve (void )
631
+ {
632
+ phys_addr_t phys ;
633
+ phys_addr_t size = CEU_BUFFER_MEMORY_SIZE ;
634
+
635
+ phys = memblock_alloc_base (size , PAGE_SIZE , MEMBLOCK_ALLOC_ANYWHERE );
636
+ memblock_free (phys , size );
637
+ memblock_remove (phys , size );
638
+
639
+ ceu_dma_membase = phys ;
640
+ }
641
+
668
642
/*
669
643
* The Machine Vector
670
644
*/
671
645
static struct sh_machine_vector mv_migor __initmv = {
672
646
.mv_name = "Migo-R" ,
673
647
.mv_mode_pins = migor_mode_pins ,
648
+ .mv_mem_reserve = migor_mv_mem_reserve ,
674
649
};
0 commit comments