1+ // SPDX-License-Identifier: GPL-2.0
12/*
23 * KFR2R09 board support code
34 *
45 * Copyright (C) 2009 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.
96 */
10- #include <linux/init.h>
11- #include <linux/platform_device.h>
12- #include <linux/interrupt.h>
13- #include <linux/mmc/host.h>
14- #include <linux/mfd/tmio.h>
15- #include <linux/mtd/physmap.h>
16- #include <linux/mtd/onenand.h>
7+
8+ #include <asm/clock.h>
9+ #include <asm/io.h>
10+ #include <asm/machvec.h>
11+ #include <asm/suspend.h>
12+
13+ #include <cpu/sh7724.h>
14+
15+ #include <linux/clkdev.h>
1716#include <linux/delay.h>
18- #include <linux/clk .h>
17+ #include <linux/dma-mapping .h>
1918#include <linux/gpio.h>
19+ #include <linux/gpio/machine.h>
20+ #include <linux/i2c.h>
21+ #include <linux/init.h>
2022#include <linux/input.h>
2123#include <linux/input/sh_keysc.h>
22- #include <linux/i2c.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/onenand.h>
29+ #include <linux/mtd/physmap.h>
2330#include <linux/platform_data/lv5207lp.h>
31+ #include <linux/platform_device.h>
2432#include <linux/regulator/fixed.h>
2533#include <linux/regulator/machine.h>
34+ #include <linux/sh_intc.h>
2635#include <linux/usb/r8a66597.h>
2736#include <linux/videodev2.h>
28- #include <linux/sh_intc.h>
37+
38+ #include <mach/kfr2r09.h>
39+
40+ #include <media/drv-intf/renesas-ceu.h>
2941#include <media/i2c/rj54n1cb0c.h>
30- #include <media/soc_camera.h>
31- #include <media/drv-intf/sh_mobile_ceu.h>
42+
3243#include <video/sh_mobile_lcdc.h>
33- #include <asm/suspend.h>
34- #include <asm/clock.h>
35- #include <asm/machvec.h>
36- #include <asm/io.h>
37- #include <cpu/sh7724.h>
38- #include <mach/kfr2r09.h>
44+
45+ #define CEU_BUFFER_MEMORY_SIZE (4 << 20)
46+ static phys_addr_t ceu_dma_membase ;
47+
48+ /* set VIO_CKO clock to 25MHz */
49+ #define CEU_MCLK_FREQ 25000000
50+ #define DRVCRB 0xA405018C
3951
4052static struct mtd_partition kfr2r09_nor_flash_partitions [] =
4153{
@@ -230,8 +242,17 @@ static struct platform_device kfr2r09_usb0_gadget_device = {
230242 .resource = kfr2r09_usb0_gadget_resources ,
231243};
232244
233- static struct sh_mobile_ceu_info sh_mobile_ceu_info = {
234- .flags = SH_CEU_FLAG_USE_8BIT_BUS ,
245+ static struct ceu_platform_data ceu_pdata = {
246+ .num_subdevs = 1 ,
247+ .subdevs = {
248+ { /* [0] = rj54n1cb0c */
249+ .flags = 0 ,
250+ .bus_width = 8 ,
251+ .bus_shift = 0 ,
252+ .i2c_adapter_id = 1 ,
253+ .i2c_address = 0x50 ,
254+ },
255+ },
235256};
236257
237258static struct resource kfr2r09_ceu_resources [] = {
@@ -246,109 +267,35 @@ static struct resource kfr2r09_ceu_resources[] = {
246267 .end = evt2irq (0x880 ),
247268 .flags = IORESOURCE_IRQ ,
248269 },
249- [2 ] = {
250- /* place holder for contiguous memory */
251- },
252270};
253271
254272static struct platform_device kfr2r09_ceu_device = {
255- .name = "sh_mobile_ceu " ,
273+ .name = "renesas-ceu " ,
256274 .id = 0 , /* "ceu0" clock */
257275 .num_resources = ARRAY_SIZE (kfr2r09_ceu_resources ),
258276 .resource = kfr2r09_ceu_resources ,
259277 .dev = {
260- .platform_data = & sh_mobile_ceu_info ,
278+ .platform_data = & ceu_pdata ,
261279 },
262280};
263281
264- static struct i2c_board_info kfr2r09_i2c_camera = {
265- I2C_BOARD_INFO ("rj54n1cb0c" , 0x50 ),
266- };
267-
268- static struct clk * camera_clk ;
269-
270- /* set VIO_CKO clock to 25MHz */
271- #define CEU_MCLK_FREQ 25000000
272-
273- #define DRVCRB 0xA405018C
274- static int camera_power (struct device * dev , int mode )
275- {
276- int ret ;
277-
278- if (mode ) {
279- long rate ;
280-
281- camera_clk = clk_get (NULL , "video_clk" );
282- if (IS_ERR (camera_clk ))
283- return PTR_ERR (camera_clk );
284-
285- rate = clk_round_rate (camera_clk , CEU_MCLK_FREQ );
286- ret = clk_set_rate (camera_clk , rate );
287- if (ret < 0 )
288- goto eclkrate ;
289-
290- /* set DRVCRB
291- *
292- * use 1.8 V for VccQ_VIO
293- * use 2.85V for VccQ_SR
294- */
295- __raw_writew ((__raw_readw (DRVCRB ) & ~0x0003 ) | 0x0001 , DRVCRB );
296-
297- /* reset clear */
298- ret = gpio_request (GPIO_PTB4 , NULL );
299- if (ret < 0 )
300- goto eptb4 ;
301- ret = gpio_request (GPIO_PTB7 , NULL );
302- if (ret < 0 )
303- goto eptb7 ;
304-
305- ret = gpio_direction_output (GPIO_PTB4 , 1 );
306- if (!ret )
307- ret = gpio_direction_output (GPIO_PTB7 , 1 );
308- if (ret < 0 )
309- goto egpioout ;
310- msleep (1 );
311-
312- ret = clk_enable (camera_clk ); /* start VIO_CKO */
313- if (ret < 0 )
314- goto eclkon ;
315-
316- return 0 ;
317- }
318-
319- ret = 0 ;
320-
321- clk_disable (camera_clk );
322- eclkon :
323- gpio_set_value (GPIO_PTB7 , 0 );
324- egpioout :
325- gpio_set_value (GPIO_PTB4 , 0 );
326- gpio_free (GPIO_PTB7 );
327- eptb7 :
328- gpio_free (GPIO_PTB4 );
329- eptb4 :
330- eclkrate :
331- clk_put (camera_clk );
332- return ret ;
333- }
334-
335282static struct rj54n1_pdata rj54n1_priv = {
336283 .mclk_freq = CEU_MCLK_FREQ ,
337284 .ioctl_high = false,
338285};
339286
340- static struct soc_camera_link rj54n1_link = {
341- .power = camera_power ,
342- .board_info = & kfr2r09_i2c_camera ,
343- .i2c_adapter_id = 1 ,
344- .priv = & rj54n1_priv ,
287+ static struct i2c_board_info kfr2r09_i2c_camera = {
288+ I2C_BOARD_INFO ("rj54n1cb0c" , 0x50 ),
289+ .platform_data = & rj54n1_priv ,
345290};
346291
347- static struct platform_device kfr2r09_camera = {
348- .name = "soc-camera-pdrv" ,
349- .id = 0 ,
350- .dev = {
351- .platform_data = & rj54n1_link ,
292+ static struct gpiod_lookup_table rj54n1_gpios = {
293+ .dev_id = "1-0050" ,
294+ .table = {
295+ GPIO_LOOKUP ("sh7724_pfc" , GPIO_PTB4 , "poweron" ,
296+ GPIO_ACTIVE_HIGH ),
297+ GPIO_LOOKUP ("sh7724_pfc" , GPIO_PTB7 , "enable" ,
298+ GPIO_ACTIVE_HIGH ),
352299 },
353300};
354301
@@ -393,8 +340,6 @@ static struct platform_device *kfr2r09_devices[] __initdata = {
393340 & kfr2r09_nand_flash_device ,
394341 & kfr2r09_sh_keysc_device ,
395342 & kfr2r09_sh_lcdc_device ,
396- & kfr2r09_ceu_device ,
397- & kfr2r09_camera ,
398343 & kfr2r09_sh_sdhi0_device ,
399344};
400345
@@ -533,6 +478,8 @@ extern char kfr2r09_sdram_leave_end;
533478
534479static int __init kfr2r09_devices_setup (void )
535480{
481+ static struct clk * camera_clk ;
482+
536483 /* register board specific self-refresh code */
537484 sh_mobile_register_self_refresh (SUSP_SH_STANDBY | SUSP_SH_SF |
538485 SUSP_SH_RSTANDBY ,
@@ -622,8 +569,6 @@ static int __init kfr2r09_devices_setup(void)
622569 gpio_request (GPIO_FN_VIO0_D1 , NULL );
623570 gpio_request (GPIO_FN_VIO0_D0 , NULL );
624571
625- platform_resource_setup_memory (& kfr2r09_ceu_device , "ceu" , 4 << 20 );
626-
627572 /* SDHI0 connected to yc304 */
628573 gpio_request (GPIO_FN_SDHI0CD , NULL );
629574 gpio_request (GPIO_FN_SDHI0D3 , NULL );
@@ -635,6 +580,36 @@ static int __init kfr2r09_devices_setup(void)
635580
636581 i2c_register_board_info (0 , & kfr2r09_backlight_board_info , 1 );
637582
583+ /* Set camera clock frequency and register and alias for rj54n1. */
584+ camera_clk = clk_get (NULL , "video_clk" );
585+ if (!IS_ERR (camera_clk )) {
586+ clk_set_rate (camera_clk ,
587+ clk_round_rate (camera_clk , CEU_MCLK_FREQ ));
588+ clk_put (camera_clk );
589+ }
590+ clk_add_alias (NULL , "1-0050" , "video_clk" , NULL );
591+
592+ /* set DRVCRB
593+ *
594+ * use 1.8 V for VccQ_VIO
595+ * use 2.85V for VccQ_SR
596+ */
597+ __raw_writew ((__raw_readw (DRVCRB ) & ~0x0003 ) | 0x0001 , DRVCRB );
598+
599+ gpiod_add_lookup_table (& rj54n1_gpios );
600+
601+ i2c_register_board_info (1 , & kfr2r09_i2c_camera , 1 );
602+
603+ /* Initialize CEU platform device separately to map memory first */
604+ device_initialize (& kfr2r09_ceu_device .dev );
605+ arch_setup_pdev_archdata (& kfr2r09_ceu_device );
606+ dma_declare_coherent_memory (& kfr2r09_ceu_device .dev ,
607+ ceu_dma_membase , ceu_dma_membase ,
608+ ceu_dma_membase + CEU_BUFFER_MEMORY_SIZE - 1 ,
609+ DMA_MEMORY_EXCLUSIVE );
610+
611+ platform_device_add (& kfr2r09_ceu_device );
612+
638613 return platform_add_devices (kfr2r09_devices ,
639614 ARRAY_SIZE (kfr2r09_devices ));
640615}
@@ -651,10 +626,24 @@ static int kfr2r09_mode_pins(void)
651626 return MODE_PIN0 | MODE_PIN1 | MODE_PIN5 | MODE_PIN8 ;
652627}
653628
629+ /* Reserve a portion of memory for CEU buffers */
630+ static void __init kfr2r09_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+
654642/*
655643 * The Machine Vector
656644 */
657645static struct sh_machine_vector mv_kfr2r09 __initmv = {
658646 .mv_name = "kfr2r09" ,
659647 .mv_mode_pins = kfr2r09_mode_pins ,
648+ .mv_mem_reserve = kfr2r09_mv_mem_reserve ,
660649};
0 commit comments