Skip to content

Commit 186c446

Browse files
Jacopo Mondimchehab
authored andcommitted
media: arch: sh: migor: Use new renesas-ceu camera driver
Migo-R platform uses sh_mobile_ceu camera driver, which is now being replaced by a proper V4L2 camera driver named 'renesas-ceu'. Move Migo-R platform to use the v4l2 renesas-ceu camera driver interface and get rid of soc_camera defined components used to register sensor drivers and of platform specific enable/disable routines. Register clock source and GPIOs for sensor drivers, so they can use clock and gpio APIs. Also, memory for CEU video buffers is now reserved with membocks APIs, and need to be declared as dma_coherent during machine initialization to remove that architecture specific part from CEU driver. Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
1 parent a57ffa4 commit 186c446

File tree

2 files changed

+101
-126
lines changed

2 files changed

+101
-126
lines changed

arch/sh/boards/mach-migor/setup.c

Lines changed: 100 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
1+
// SPDX-License-Identifier: GPL-2.0
12
/*
23
* Renesas System Solutions Asia Pte. Ltd - Migo-R
34
*
45
* 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.
96
*/
7+
#include <linux/clkdev.h>
108
#include <linux/init.h>
119
#include <linux/platform_device.h>
1210
#include <linux/interrupt.h>
1311
#include <linux/input.h>
1412
#include <linux/input/sh_keysc.h>
13+
#include <linux/memblock.h>
1514
#include <linux/mmc/host.h>
1615
#include <linux/mtd/physmap.h>
1716
#include <linux/mfd/tmio.h>
@@ -23,10 +22,11 @@
2322
#include <linux/delay.h>
2423
#include <linux/clk.h>
2524
#include <linux/gpio.h>
25+
#include <linux/gpio/machine.h>
2626
#include <linux/videodev2.h>
2727
#include <linux/sh_intc.h>
2828
#include <video/sh_mobile_lcdc.h>
29-
#include <media/drv-intf/sh_mobile_ceu.h>
29+
#include <media/drv-intf/renesas-ceu.h>
3030
#include <media/i2c/ov772x.h>
3131
#include <media/soc_camera.h>
3232
#include <media/i2c/tw9910.h>
@@ -45,6 +45,9 @@
4545
* 0x18000000 8GB 8 NAND Flash (K9K8G08U0A)
4646
*/
4747

48+
#define CEU_BUFFER_MEMORY_SIZE (4 << 20)
49+
static phys_addr_t ceu_dma_membase;
50+
4851
static struct smc91x_platdata smc91x_info = {
4952
.flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
5053
};
@@ -301,65 +304,24 @@ static struct platform_device migor_lcdc_device = {
301304
},
302305
};
303306

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+
},
363325
};
364326

365327
static struct resource migor_ceu_resources[] = {
@@ -373,18 +335,32 @@ static struct resource migor_ceu_resources[] = {
373335
.start = evt2irq(0x880),
374336
.flags = IORESOURCE_IRQ,
375337
},
376-
[2] = {
377-
/* place holder for contiguous memory */
378-
},
379338
};
380339

381340
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 */
384343
.num_resources = ARRAY_SIZE(migor_ceu_resources),
385344
.resource = migor_ceu_resources,
386345
.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),
388364
},
389365
};
390366

@@ -423,6 +399,15 @@ static struct platform_device sdhi_cn9_device = {
423399
},
424400
};
425401

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+
426411
static struct i2c_board_info migor_i2c_devices[] = {
427412
{
428413
I2C_BOARD_INFO("rs5c372b", 0x32),
@@ -434,64 +419,23 @@ static struct i2c_board_info migor_i2c_devices[] = {
434419
{
435420
I2C_BOARD_INFO("wm8978", 0x1a),
436421
},
437-
};
438-
439-
static struct i2c_board_info migor_i2c_camera[] = {
440422
{
441423
I2C_BOARD_INFO("ov772x", 0x21),
424+
.platform_data = &ov7725_info,
442425
},
443426
{
444427
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,
482429
},
483430
};
484431

485432
static struct platform_device *migor_devices[] __initdata = {
486433
&smc91x_eth_device,
487434
&sh_keysc_device,
488435
&migor_lcdc_device,
489-
&migor_ceu_device,
490436
&migor_nor_flash_device,
491437
&migor_nand_flash_device,
492438
&sdhi_cn9_device,
493-
&migor_camera[0],
494-
&migor_camera[1],
495439
};
496440

497441
extern char migor_sdram_enter_start;
@@ -501,6 +445,8 @@ extern char migor_sdram_leave_end;
501445

502446
static int __init migor_devices_setup(void)
503447
{
448+
struct clk *video_clk;
449+
504450
/* register board specific self-refresh code */
505451
sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF,
506452
&migor_sdram_enter_start,
@@ -620,20 +566,8 @@ static int __init migor_devices_setup(void)
620566
gpio_request(GPIO_FN_VIO_D9, NULL);
621567
gpio_request(GPIO_FN_VIO_D8, NULL);
622568

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
633569
__raw_writew(__raw_readw(PORT_MSELCRB) | 0x2000, PORT_MSELCRB); /* D15->D8 */
634570

635-
platform_resource_setup_memory(&migor_ceu_device, "ceu", 4 << 20);
636-
637571
/* SIU: Port B */
638572
gpio_request(GPIO_FN_SIUBOLR, NULL);
639573
gpio_request(GPIO_FN_SIUBOBT, NULL);
@@ -647,9 +581,36 @@ static int __init migor_devices_setup(void)
647581
*/
648582
__raw_writew(__raw_readw(PORT_MSELCRA) | 1, PORT_MSELCRA);
649583

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+
650601
i2c_register_board_info(0, migor_i2c_devices,
651602
ARRAY_SIZE(migor_i2c_devices));
652603

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+
653614
return platform_add_devices(migor_devices, ARRAY_SIZE(migor_devices));
654615
}
655616
arch_initcall(migor_devices_setup);
@@ -665,10 +626,24 @@ static int migor_mode_pins(void)
665626
return MODE_PIN0 | MODE_PIN1 | MODE_PIN5;
666627
}
667628

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+
668642
/*
669643
* The Machine Vector
670644
*/
671645
static struct sh_machine_vector mv_migor __initmv = {
672646
.mv_name = "Migo-R",
673647
.mv_mode_pins = migor_mode_pins,
648+
.mv_mem_reserve = migor_mv_mem_reserve,
674649
};

arch/sh/kernel/cpu/sh4a/clock-sh7722.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ static struct clk_lookup lookups[] = {
223223
CLKDEV_DEV_ID("sh-vou.0", &mstp_clks[HWBLK_VOU]),
224224
CLKDEV_CON_ID("jpu0", &mstp_clks[HWBLK_JPU]),
225225
CLKDEV_CON_ID("beu0", &mstp_clks[HWBLK_BEU]),
226-
CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[HWBLK_CEU]),
226+
CLKDEV_DEV_ID("renesas-ceu.0", &mstp_clks[HWBLK_CEU]),
227227
CLKDEV_CON_ID("veu0", &mstp_clks[HWBLK_VEU]),
228228
CLKDEV_CON_ID("vpu0", &mstp_clks[HWBLK_VPU]),
229229
CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[HWBLK_LCDC]),

0 commit comments

Comments
 (0)