summaryrefslogtreecommitdiffstats
path: root/recipes-kernel
diff options
context:
space:
mode:
authorKoen Kooi <koen@dominion.thruhere.net>2012-07-13 12:19:44 +0200
committerDenys Dmytriyenko <denys@ti.com>2012-07-25 20:35:56 -0400
commitcb872e3786ec7c08375257c534a38a5eff0bfff9 (patch)
tree2e04ad637010907fdf0c3711f717aaab2623bd6f /recipes-kernel
parente1b4ab72cfb3ea4599701d1600c44fe3c5f8ba66 (diff)
downloadmeta-ti-cb872e3786ec7c08375257c534a38a5eff0bfff9.tar.gz
linux-ti33x-psp 3.2: add fixed for cssp, fbset and OPP50
Signed-off-by: Koen Kooi <koen@dominion.thruhere.net> Signed-off-by: Denys Dmytriyenko <denys@ti.com>
Diffstat (limited to 'recipes-kernel')
-rw-r--r--recipes-kernel/linux/linux-ti33x-psp-3.2/beaglebone/0066-beaglebone-disable-OPP-for-275MHz-due-to-silicon-err.patch28
-rw-r--r--recipes-kernel/linux/linux-ti33x-psp-3.2/beaglebone/0073-beaglebone-add-support-for-QuickLogic-Camera-interfa.patch1612
-rw-r--r--recipes-kernel/linux/linux-ti33x-psp-3.2/beaglebone/0075-video-da8xx-fb-calculate-pixel-clock-period-for-the-.patch73
-rw-r--r--recipes-kernel/linux/linux-ti33x-psp-3.2/beaglebone/0076-beaglebone-improve-GPMC-bus-timings-for-camera-cape.patch105
-rw-r--r--recipes-kernel/linux/linux-ti33x-psp-3.2/beaglebone/0077-beaglebone-disable-UYVY-VYUY-and-YVYU-modes-in-camer.patch39
-rw-r--r--recipes-kernel/linux/linux-ti33x-psp-3.2/beaglebone/0078-beaglebone-error-handling-for-DMA-completion-in-cssp.patch49
-rw-r--r--recipes-kernel/linux/linux-ti33x-psp-3.2/beaglebone/0079-AM335X-errata-OPP50-on-MPU-domain-is-not-supported.patch52
-rw-r--r--recipes-kernel/linux/linux-ti33x-psp_3.2.bb8
8 files changed, 1936 insertions, 30 deletions
diff --git a/recipes-kernel/linux/linux-ti33x-psp-3.2/beaglebone/0066-beaglebone-disable-OPP-for-275MHz-due-to-silicon-err.patch b/recipes-kernel/linux/linux-ti33x-psp-3.2/beaglebone/0066-beaglebone-disable-OPP-for-275MHz-due-to-silicon-err.patch
deleted file mode 100644
index aae97bbe..00000000
--- a/recipes-kernel/linux/linux-ti33x-psp-3.2/beaglebone/0066-beaglebone-disable-OPP-for-275MHz-due-to-silicon-err.patch
+++ /dev/null
@@ -1,28 +0,0 @@
1From 954d199a0e9aaa4d7dbc7215cea0225cd3ffe186 Mon Sep 17 00:00:00 2001
2From: Koen Kooi <koen@dominion.thruhere.net>
3Date: Mon, 28 May 2012 18:54:57 +0200
4Subject: [PATCH 66/68] beaglebone: disable OPP for 275MHz due to silicon
5 errata
6
7Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
8---
9 arch/arm/mach-omap2/board-am335xevm.c | 3 +++
10 1 files changed, 3 insertions(+), 0 deletions(-)
11
12diff --git a/arch/arm/mach-omap2/board-am335xevm.c b/arch/arm/mach-omap2/board-am335xevm.c
13index da6020b..58c2754 100644
14--- a/arch/arm/mach-omap2/board-am335xevm.c
15+++ b/arch/arm/mach-omap2/board-am335xevm.c
16@@ -2975,6 +2975,9 @@ static void tps65217_init(int evm_id, int profile)
17 return;
18 }
19
20+ pr_info("Disabling OPP for 275MHz due to silicon errata");
21+ opp_disable(mpu_dev, 275000000);
22+
23 if (!(val & TPS65217_STATUS_ACPWR)) {
24 /* If powered by USB then disable OPP120 and OPPTURBO */
25 pr_info("Maximum current provided by the USB port is 500mA"
26--
271.7.7.6
28
diff --git a/recipes-kernel/linux/linux-ti33x-psp-3.2/beaglebone/0073-beaglebone-add-support-for-QuickLogic-Camera-interfa.patch b/recipes-kernel/linux/linux-ti33x-psp-3.2/beaglebone/0073-beaglebone-add-support-for-QuickLogic-Camera-interfa.patch
new file mode 100644
index 00000000..48ac34b9
--- /dev/null
+++ b/recipes-kernel/linux/linux-ti33x-psp-3.2/beaglebone/0073-beaglebone-add-support-for-QuickLogic-Camera-interfa.patch
@@ -0,0 +1,1612 @@
1From cf35e6b861c3c7d4d9c9db1557ba27b5578e8aa2 Mon Sep 17 00:00:00 2001
2From: Dan Aizenstros <daizenstros@quicklogic.com>
3Date: Fri, 29 Jun 2012 13:57:49 -0400
4Subject: [PATCH] beaglebone: add support for QuickLogic Camera interface on
5 camera cape
6
7Signed-off-by: Dan Aizenstros <daizenstros@quicklogic.com>
8---
9 arch/arm/mach-omap2/board-am335xevm.c | 205 ++++-
10 arch/arm/mach-omap2/devices.c | 2 +-
11 arch/arm/plat-omap/include/plat/dma-33xx.h | 1 +
12 drivers/media/video/Kconfig | 7 +
13 drivers/media/video/Makefile | 2 +
14 drivers/media/video/cssp_camera/Makefile | 3 +
15 drivers/media/video/cssp_camera/cssp_camera.c | 1119 +++++++++++++++++++++++++
16 drivers/media/video/cssp_camera/cssp_camera.h | 148 ++++
17 8 files changed, 1478 insertions(+), 9 deletions(-)
18 create mode 100644 drivers/media/video/cssp_camera/Makefile
19 create mode 100644 drivers/media/video/cssp_camera/cssp_camera.c
20 create mode 100644 drivers/media/video/cssp_camera/cssp_camera.h
21
22diff --git a/arch/arm/mach-omap2/board-am335xevm.c b/arch/arm/mach-omap2/board-am335xevm.c
23index dc78b4a..1680612 100644
24--- a/arch/arm/mach-omap2/board-am335xevm.c
25+++ b/arch/arm/mach-omap2/board-am335xevm.c
26@@ -66,6 +66,10 @@
27 #include <plat/mmc.h>
28 #include <plat/emif.h>
29 #include <plat/nand.h>
30+#include <plat/dma-33xx.h>
31+
32+#include <media/soc_camera.h>
33+#include <media/mt9t112.h>
34
35 #include "board-flash.h"
36 #include "cpuidle33xx.h"
37@@ -804,6 +808,42 @@ static struct pinmux_config i2c1_pin_mux[] = {
38 {NULL, 0},
39 };
40
41+/* Pin mux for GPMC bus */
42+static struct pinmux_config gpmc_pin_mux[] = {
43+ {"gpmc_ad0.gpmc_ad0", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLUP},
44+ {"gpmc_ad1.gpmc_ad1", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLUP},
45+ {"gpmc_ad2.gpmc_ad2", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLUP},
46+ {"gpmc_ad3.gpmc_ad3", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLUP},
47+ {"gpmc_ad4.gpmc_ad4", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLUP},
48+ {"gpmc_ad5.gpmc_ad5", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLUP},
49+ {"gpmc_ad6.gpmc_ad6", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLUP},
50+ {"gpmc_ad7.gpmc_ad7", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLUP},
51+ {"gpmc_ad8.gpmc_ad8", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLUP},
52+ {"gpmc_ad9.gpmc_ad9", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLUP},
53+ {"gpmc_ad10.gpmc_ad10", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLUP},
54+ {"gpmc_ad11.gpmc_ad11", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLUP},
55+ {"gpmc_ad12.gpmc_ad12", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLUP},
56+ {"gpmc_ad13.gpmc_ad13", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLUP},
57+ {"gpmc_ad14.gpmc_ad14", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLUP},
58+ {"gpmc_ad15.gpmc_ad15", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLUP},
59+ {"gpmc_wait0.gpmc_wait0", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLUP},
60+ {"gpmc_wpn.gpmc_wpn", OMAP_MUX_MODE7 | AM33XX_PIN_INPUT_PULLUP},
61+ {"gpmc_csn1.gpmc_csn1", OMAP_MUX_MODE0 | AM33XX_PULL_DISA},
62+ {"gpmc_advn_ale.gpmc_advn_ale", OMAP_MUX_MODE0 | AM33XX_PULL_DISA},
63+ {"gpmc_oen_ren.gpmc_oen_ren", OMAP_MUX_MODE0 | AM33XX_PULL_DISA},
64+ {"gpmc_wen.gpmc_wen", OMAP_MUX_MODE0 | AM33XX_PULL_DISA},
65+ {"gpmc_ben0_cle.gpmc_ben0_cle", OMAP_MUX_MODE0 | AM33XX_PULL_DISA},
66+ {"gpmc_clk.gpmc_clk", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT},
67+ {"ecap0_in_pwm0_out.xdma_event_intr2", OMAP_MUX_MODE6 | AM33XX_PIN_INPUT}, // DMAREQ
68+ {NULL, 0},
69+};
70+
71+static struct pinmux_config camera_cape_pin_mux[] = {
72+ {"spi0_d1.gpio0_4", OMAP_MUX_MODE7 | AM33XX_PIN_OUTPUT }, // QL CSSP and Camera Sensor Reset
73+ {"spi0_cs0.gpio0_5", OMAP_MUX_MODE7 | AM33XX_PIN_OUTPUT_PULLUP }, // 1V8 and 2V8 Power Enable
74+ {NULL, 0},
75+};
76+
77 static struct pinmux_config i2c2_pin_mux[] = {
78 {"uart1_ctsn.i2c2_sda", OMAP_MUX_MODE3 | AM33XX_SLEWCTRL_SLOW |
79 AM33XX_PIN_INPUT_PULLUP},
80@@ -1803,6 +1843,156 @@ static void dvileds_init(int evm_id, int profile )
81 pr_err("failed to register BeagleBone DVI cape LEDS\n");
82 }
83
84+static struct resource cssp_camera_resources[] = {
85+ {
86+ .name = "gpmc_phys_mem_slot",
87+ .flags = IORESOURCE_MEM,
88+ },
89+};
90+
91+static struct mt9t112_camera_info mt9t111_cam_info = {
92+ /* divider calculated for 32Mhz CAM_MCLK */
93+ .divider = {
94+ .m = 24, .n = 1,
95+ .p1 = 0, .p2 = 7, .p3 = 0, .p4 = 11, .p5 = 15, .p6 = 7, .p7 = 0,
96+ },
97+};
98+
99+static struct soc_camera_link mt9t111_camera_link = {
100+ .priv = &mt9t111_cam_info,
101+ .i2c_adapter_id = 3,
102+};
103+
104+static struct i2c_board_info i2c_camera = {
105+ I2C_BOARD_INFO("mt9t112", 0x3c),
106+ .platform_data = &mt9t111_camera_link,
107+};
108+
109+struct cssp_cam_platform_data {
110+ struct i2c_board_info *cam_i2c_board_info;
111+ const char *cam_clk_name;
112+ int dma_ch;
113+ int cssp_reset_pin;
114+};
115+
116+static struct cssp_cam_platform_data cssp_cam_platform_data = {
117+ .cam_i2c_board_info = &i2c_camera,
118+ .cam_clk_name = "clkout2_ck",
119+ .dma_ch = AM33XX_DMA_XDMA_EVENT_INTR2,
120+ .cssp_reset_pin = GPIO_TO_PIN(0, 4),
121+};
122+
123+static struct platform_device cssp_camera = {
124+ .name = "cssp-camera",
125+ .id = -1,
126+ .dev = {
127+ .platform_data = &cssp_cam_platform_data,
128+ },
129+ .num_resources = sizeof(cssp_camera_resources) / sizeof(cssp_camera_resources[0]),
130+ .resource = cssp_camera_resources,
131+};
132+
133+static struct gpmc_timings cssp_timings = {
134+ /* Minimum clock period for synchronous mode (in picoseconds) */
135+ .sync_clk = 10000,
136+
137+ .cs_on = 0,
138+ .cs_rd_off = 23 * 10, /* Read deassertion time */
139+ .cs_wr_off = 23 * 10, /* Write deassertion time */
140+
141+ /* ADV signal timings corresponding to GPMC_CONFIG3 */
142+ .adv_on = 0, /* Assertion time */
143+ .adv_rd_off = 2 * 10, /* Read deassertion time */
144+ .adv_wr_off = 2 * 10, /* Write deassertion time */
145+
146+ /* WE signals timings corresponding to GPMC_CONFIG4 */
147+ .we_on = 3 * 10, /* WE assertion time */
148+ .we_off = 23 * 10, /* WE deassertion time */
149+
150+ /* OE signals timings corresponding to GPMC_CONFIG4 */
151+ .oe_on = 3 * 10, /* OE assertion time */
152+ .oe_off = 23 * 10, /* OE deassertion time */
153+
154+ /* Access time and cycle time timings corresponding to GPMC_CONFIG5 */
155+ .page_burst_access = 1 * 10, /* Multiple access word delay */
156+ .access = 7 * 10, /* Start-cycle to first data valid delay */
157+ .rd_cycle = 23 * 10, /* Total read cycle time */
158+ .wr_cycle = 23 * 10, /* Total write cycle time */
159+
160+ /* The following are only on OMAP3430 */
161+ .wr_access = 7 * 10, /* WRACCESSTIME */
162+ .wr_data_mux_bus = 3 * 10, /* WRDATAONADMUXBUS */
163+};
164+
165+static int gpmc_cssp_init(void)
166+{
167+ int cs = 1; /* Chip Select on GPMC bus */
168+ int val;
169+ long unsigned int cssp_gpmc_mem_base_phys;
170+
171+ if (gpmc_cs_request(cs, SZ_16M, &cssp_gpmc_mem_base_phys) < 0) {
172+ printk(KERN_ERR "[cssp_cam platform init]: gpmc_cs_request failed\n");
173+ return -1;
174+ }
175+
176+ cssp_camera_resources[0].start = cssp_gpmc_mem_base_phys;
177+ cssp_camera_resources[0].end = cssp_gpmc_mem_base_phys + 0x1ffff;
178+
179+ if (gpmc_cs_configure(cs, GPMC_CONFIG_DEV_TYPE, GPMC_DEVICETYPE_NOR) < 0) {
180+ printk(KERN_ERR "[cssp_cam platform init]: gpmc_cs_configure failed\n");
181+ return -1;
182+ }
183+
184+ val = GPMC_CONFIG1_READMULTIPLE_SUPP;
185+ val |= GPMC_CONFIG1_READTYPE_SYNC;
186+ val |= GPMC_CONFIG1_WRITETYPE_SYNC;
187+ val |= GPMC_CONFIG1_CLKACTIVATIONTIME(1);
188+ val |= GPMC_CONFIG1_PAGE_LEN(2);
189+ val |= GPMC_CONFIG1_DEVICESIZE_16;
190+ val |= GPMC_CONFIG1_DEVICETYPE_NOR;
191+ val |= GPMC_CONFIG1_MUXADDDATA;
192+ gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, val);
193+
194+ if (gpmc_cs_set_timings(cs, &cssp_timings) < 0) {
195+ printk(KERN_ERR "Failed gpmc_cs_set_timings for QuickLogic CAMIF device\n");
196+ goto free;
197+ }
198+
199+ val = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG6);
200+ val &= 0xe0f0f030;
201+ val |= 0x07030481;
202+ gpmc_cs_write_reg(cs, GPMC_CS_CONFIG6, val);
203+
204+ printk(KERN_INFO "gpmc_cssp_init for QuickLogic CAMIF device succeeded\n");
205+
206+ return 0;
207+
208+free:
209+ gpmc_cs_free(cs);
210+
211+ printk(KERN_ERR "Could not initialize QuickLogic CAMIF device\n");
212+
213+ return -1;
214+}
215+
216+static void cssp_gpmc_init(void)
217+{
218+ struct gpmc_devices_info gpmc_device[2] = {
219+ { NULL, GPMC_DEVICE_NOR },
220+ };
221+
222+ setup_pin_mux(camera_cape_pin_mux);
223+ setup_pin_mux(gpmc_pin_mux);
224+
225+ omap_init_gpmc(gpmc_device, sizeof(gpmc_device));
226+ gpmc_cssp_init();
227+
228+ platform_device_register(&cssp_camera);
229+
230+ printk(KERN_INFO "[cssp_cam platform init]: cssp_gpmc_init: DONE\n");
231+}
232+
233+
234 static void lcd3leds_init(int evm_id, int profile )
235 {
236 int err;
237@@ -2851,6 +3041,7 @@ static void beaglebone_cape_setup(struct memory_accessor *mem_acc, void *context
238 if (!strncmp("BB-BONE-CAM-01", cape_config.partnumber, 14)) {
239 pr_info("BeagleBone cape: recognized Camera cape\n");
240 beaglebone_w1gpio_free = 0;
241+ cssp_gpmc_init();
242 }
243
244 goto out2;
245@@ -3762,15 +3953,13 @@ static struct pinmux_config clkout2_pin_mux[] = {
246
247 static void __init clkout2_enable(void)
248 {
249- struct clk *ck_32;
250-
251- ck_32 = clk_get(NULL, "clkout2_ck");
252- if (IS_ERR(ck_32)) {
253- pr_err("Cannot clk_get ck_32\n");
254- return;
255- }
256+ void __iomem *base;
257+ unsigned int val;
258
259- clk_enable(ck_32);
260+ base = ioremap(0x44E00700, SZ_4K);
261+ val = (5 << 3) | (3 << 0); //32 MHz
262+ writel(val, base);
263+ iounmap(base);
264
265 setup_pin_mux(clkout2_pin_mux);
266 }
267diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
268index 41c9b0f..3ef045e 100644
269--- a/arch/arm/mach-omap2/devices.c
270+++ b/arch/arm/mach-omap2/devices.c
271@@ -968,7 +968,7 @@ static struct event_to_channel_map am33xx_xbar_event_mapping[] = {
272 {27, -1},
273 {28, -1},
274 {29, -1},
275- {30, -1},
276+ {30, 20}, /* XDMA_EVENT_INTR2 */
277 {31, -1},
278 {-1, -1}
279 };
280diff --git a/arch/arm/plat-omap/include/plat/dma-33xx.h b/arch/arm/plat-omap/include/plat/dma-33xx.h
281index bebdaa7..ded00aa 100644
282--- a/arch/arm/plat-omap/include/plat/dma-33xx.h
283+++ b/arch/arm/plat-omap/include/plat/dma-33xx.h
284@@ -83,5 +83,6 @@
285 #define AM33XX_DMA_PWMSS2_EPW 63
286 #define AM33XX_DMA_MMCHS2_W 64 /* xBar */
287 #define AM33XX_DMA_MMCHS2_R 65 /* xBar */
288+#define AM33XX_DMA_XDMA_EVENT_INTR2 93 /* xBar */
289
290 #endif
291diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
292index b303a3f..a31723f 100644
293--- a/drivers/media/video/Kconfig
294+++ b/drivers/media/video/Kconfig
295@@ -1002,6 +1002,13 @@ config VIDEO_S5P_MIPI_CSIS
296
297 source "drivers/media/video/s5p-tv/Kconfig"
298
299+config VIDEO_QL_CAMIF
300+ tristate "QuickLogic Camera Interface support (EXPERIMENTAL)"
301+ depends on VIDEO_DEV && SOC_CAMERA && SOC_OMAPAM33XX && EXPERIMENTAL
302+ select VIDEOBUF2_DMA_CONTIG
303+ ---help---
304+ This is a v4l2 driver for the QuickLogic CAMIF controller.
305+
306 #
307 # USB Multimedia device configuration
308 #
309diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
310index 117f9c4..af7af692 100644
311--- a/drivers/media/video/Makefile
312+++ b/drivers/media/video/Makefile
313@@ -195,6 +195,8 @@ obj-y += davinci/
314
315 obj-$(CONFIG_ARCH_OMAP) += omap/
316
317+obj-$(CONFIG_VIDEO_QL_CAMIF) += cssp_camera/
318+
319 ccflags-y += -Idrivers/media/dvb/dvb-core
320 ccflags-y += -Idrivers/media/dvb/frontends
321 ccflags-y += -Idrivers/media/common/tuners
322diff --git a/drivers/media/video/cssp_camera/Makefile b/drivers/media/video/cssp_camera/Makefile
323new file mode 100644
324index 0000000..d85a84e
325--- /dev/null
326+++ b/drivers/media/video/cssp_camera/Makefile
327@@ -0,0 +1,3 @@
328+# cssp_camera
329+
330+obj-$(CONFIG_VIDEO_QL_CAMIF) += cssp_camera.o
331diff --git a/drivers/media/video/cssp_camera/cssp_camera.c b/drivers/media/video/cssp_camera/cssp_camera.c
332new file mode 100644
333index 0000000..39aa003
334--- /dev/null
335+++ b/drivers/media/video/cssp_camera/cssp_camera.c
336@@ -0,0 +1,1119 @@
337+/*
338+ * cssp-camera driver
339+ *
340+ * Based on Vivi driver
341+ *
342+ * Copyright (C) 2012 QuickLogic Corp.
343+ *
344+ * Developed for QuickLogic by:
345+ * Damian Eppel <damian.eppel@teleca.com>
346+ * Przemek Szewczyk <przemek.szewczyk@teleca.com>
347+ * Dan Aizenstros <daizenstros@quicklogic.com>
348+ *
349+ * This program is free software; you can redistribute it and/or modify
350+ * it under the terms of the GNU General Public License version 2 as
351+ * published by the Free Software Foundation.
352+ *
353+ */
354+
355+
356+#include <linux/init.h>
357+#include <linux/module.h>
358+#include <linux/gpio.h>
359+#include <linux/i2c.h>
360+#include <linux/delay.h>
361+#include <linux/spinlock.h>
362+#include <linux/dma-mapping.h>
363+#include <linux/interrupt.h>
364+#include <mach/edma.h>
365+#include <linux/clk.h>
366+// V4L2 Interface *********************
367+#include <media/soc_camera.h>
368+#include <media/v4l2-mediabus.h>
369+#include <media/videobuf2-dma-contig.h>
370+#include <media/v4l2-ioctl.h>
371+#include <media/v4l2-event.h>
372+//*************************************
373+#include "cssp_camera.h"
374+
375+
376+/*
377+ * ---------------------------------------------------------------------------
378+ * QuickLoigc Camera Interface registers
379+ * ---------------------------------------------------------------------------
380+ */
381+
382+#define REG_MODE 0x00000
383+#define REG_DATA 0x10000
384+
385+/* MODE bit shifts */
386+#define FMT_2X8_EN BIT(15) /* Enable 2 byte format on CAMIF bus (0 - 10 bit, 1 - 16 bit 2x8) */
387+#define PCLK_POL BIT(14) /* PCLK polarity (0 - rising edge, 1 - falling edge */
388+#define HS_EN BIT(13) /* High speed bus (0 =< 50 MHz, 1 > 50 MHz) */
389+#define ENABLE BIT(12)
390+
391+
392+static struct cssp_cam_fmt formats[] = {
393+ {
394+ .name = "4:2:2, packed, YUYV",
395+ .fourcc = V4L2_PIX_FMT_YUYV,
396+ .depth = 16,
397+ .code = V4L2_MBUS_FMT_YUYV8_2X8,
398+ },
399+ {
400+ .name = "4:2:2, packed, UYVY",
401+ .fourcc = V4L2_PIX_FMT_UYVY,
402+ .depth = 16,
403+ .code = V4L2_MBUS_FMT_UYVY8_2X8,
404+ },
405+ {
406+ .name = "4:2:2, packed, VYUY",
407+ .fourcc = V4L2_PIX_FMT_VYUY,
408+ .depth = 16,
409+ .code = V4L2_MBUS_FMT_VYUY8_2X8,
410+ },
411+ {
412+ .name = "4:2:2, packed, YVYU",
413+ .fourcc = V4L2_PIX_FMT_YVYU,
414+ .depth = 16,
415+ .code = V4L2_MBUS_FMT_YVYU8_2X8,
416+ },
417+ {
418+ .name = "RGB565 (LE)",
419+ .fourcc = V4L2_PIX_FMT_RGB565,
420+ .depth = 16,
421+ .code = V4L2_MBUS_FMT_RGB565_2X8_LE,
422+ },
423+ {
424+ .name = "RGB555 (LE)",
425+ .fourcc = V4L2_PIX_FMT_RGB555,
426+ .depth = 16,
427+ .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE,
428+ },
429+};
430+
431+
432+/***************************************************************************/
433+
434+
435+static int configure_gpio(int nr, int val, const char *name)
436+{
437+ unsigned long flags = val ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
438+ int ret;
439+ if (!gpio_is_valid(nr))
440+ return 0;
441+ ret = gpio_request_one(nr, flags, name);
442+ if (!ret)
443+ gpio_export(nr, 0);
444+ return ret;
445+}
446+
447+static int reset_cssp(struct cssp_cam_dev *cam)
448+{
449+ struct platform_device *pdev = cam->pdev;
450+ int err;
451+
452+ cam->reset_pin = ((struct cssp_cam_platform_data *)pdev->dev.platform_data)->gpio_reset_pin;
453+
454+ err = configure_gpio(cam->reset_pin, 0, "cssp_reset");
455+ if (err) {
456+ printk(KERN_ERR "[%s]: failed to configure cssp reset pin\n", pdev->name);
457+ return -1;
458+ }
459+
460+ mdelay(1);
461+
462+ gpio_direction_output(cam->reset_pin, 1);
463+
464+ return err;
465+}
466+
467+static int trigger_dma_transfer_to_buf(struct cssp_cam_dev *dev, struct vb2_buffer *vb)
468+{
469+ dma_addr_t dma_buf = vb2_dma_contig_plane_dma_addr(vb, 0);
470+
471+ if (!dma_buf) {
472+ /* Is this possible? Release the vb2_buffer with an error here, */
473+ vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
474+ dev->current_vb = NULL;
475+ return -ENOMEM;
476+ }
477+
478+ dev->dma_tr_params.dst = dma_buf;
479+
480+ // Enable DMA
481+ edma_write_slot(dev->dma_ch, &dev->dma_tr_params);
482+
483+ // Enable data capture
484+ dev->mode |= ENABLE;
485+ writew(dev->mode, dev->reg_base_virt + REG_MODE);
486+ readw(dev->reg_base_virt + REG_MODE);
487+
488+ dev->current_vb = vb;
489+
490+ return 0;
491+}
492+
493+static void dequeue_buffer_for_dma(struct cssp_cam_dev *dev)
494+{
495+ struct cssp_cam_dmaqueue *dma_q = &dev->vidq;
496+ unsigned long flags = 0;
497+
498+ spin_lock_irqsave(&dev->slock, flags);
499+ if (!list_empty(&dma_q->active)) {
500+ struct cssp_cam_buffer *buf;
501+
502+ buf = list_entry(dma_q->active.next, struct cssp_cam_buffer, list);
503+ list_del(&buf->list);
504+ spin_unlock_irqrestore(&dev->slock, flags);
505+
506+ buf->fmt = dev->fmt;
507+
508+ trigger_dma_transfer_to_buf(dev, &buf->vb);
509+ } else {
510+ spin_unlock_irqrestore(&dev->slock, flags);
511+ }
512+}
513+
514+static void dma_callback(unsigned lch, u16 ch_status, void *data)
515+{
516+ struct cssp_cam_dev *dev = (struct cssp_cam_dev *)data;
517+
518+ // Disable data capture
519+ dev->mode &= ~ENABLE;
520+ writew(dev->mode, dev->reg_base_virt + REG_MODE);
521+ readw(dev->reg_base_virt + REG_MODE);
522+
523+ if (ch_status == DMA_COMPLETE) {
524+ struct vb2_buffer *vb = dev->current_vb;
525+ struct timeval ts;
526+
527+ vb->v4l2_buf.field = dev->field;
528+ dev->field_count++;
529+ vb->v4l2_buf.sequence = dev->field_count >> 1;
530+ do_gettimeofday(&ts);
531+ vb->v4l2_buf.timestamp = ts;
532+ vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
533+ dev->current_vb = NULL;
534+ dev->frame_cnt++;
535+
536+ /* check if we have new buffer queued */
537+ dequeue_buffer_for_dma(dev);
538+ } else {
539+ printk(KERN_ERR "[cssp_camera]: EDMA error (ch_status = %d)\n", ch_status);
540+ /* we got a missed interrupt so just start a new DMA with the existing buffer */
541+ if (dev->current_vb != NULL)
542+ trigger_dma_transfer_to_buf(dev, dev->current_vb);
543+ }
544+}
545+
546+static int configure_edma(struct cssp_cam_dev *cam)
547+{
548+ struct platform_device *pdev = cam->pdev;
549+ int dma_channel;
550+
551+ dma_channel = ((struct cssp_cam_platform_data *)pdev->dev.platform_data)->dma_ch;
552+
553+ pdev->dev.dma_mask = &cam->dma_mask;
554+
555+ pdev->dev.coherent_dma_mask = (u32)~0;
556+
557+ if (dma_set_mask(&pdev->dev, (u32)~0)) {
558+ printk(KERN_ERR "[%s]: failed setting mask for DMA\n", pdev->name);
559+ return -1;
560+ }
561+
562+ cam->dma_ch = edma_alloc_channel(dma_channel, dma_callback, cam, EVENTQ_1);
563+ if (cam->dma_ch < 0) {
564+ printk(KERN_ERR "[%s]: allocating channel for DMA failed\n", pdev->name);
565+ return -EBUSY;
566+ } else {
567+ printk(KERN_ERR "[%s]: allocating channel for DMA succeeded, chan=%d\n", pdev->name, cam->dma_ch);
568+ }
569+
570+ cam->dma_tr_params.opt = TCINTEN | TCC(cam->dma_ch);
571+ cam->dma_tr_params.src = cam->reg_base_phys + REG_DATA;
572+ cam->dma_tr_params.a_b_cnt = ACNT(BYTES_PER_DMA_EVT) | BCNT((VGA_WIDTH * BYTES_PER_PIXEL) / BYTES_PER_DMA_EVT);
573+ cam->dma_tr_params.src_dst_bidx = SRCBIDX(0) | DSTBIDX(BYTES_PER_DMA_EVT);
574+ cam->dma_tr_params.link_bcntrld = BCNTRLD((VGA_WIDTH * BYTES_PER_PIXEL) / BYTES_PER_DMA_EVT) | LINK(0xffff);
575+ cam->dma_tr_params.src_dst_cidx = SRCCIDX(0) | DSTCIDX(BYTES_PER_DMA_EVT);
576+ cam->dma_tr_params.ccnt = CCNT(VGA_HEIGHT);
577+
578+ return 0;
579+}
580+
581+static int configure_cssp(struct cssp_cam_dev *cam)
582+{
583+ struct platform_device *pdev = cam->pdev;
584+ int ret = 0;
585+ unsigned int val;
586+ struct resource *res;
587+
588+ ret = reset_cssp(cam);
589+ if (ret)
590+ return ret;
591+
592+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "gpmc_phys_mem_slot");
593+ if (res == NULL) {
594+ printk(KERN_ERR "[%s]: failed to get gpmc_phys_mem_slot resource\n", pdev->name);
595+ return -ENODEV;
596+ }
597+
598+ /*
599+ * Request the region.
600+ */
601+ if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
602+ return -EBUSY;
603+ }
604+
605+ cam->reg_base_phys = res->start;
606+ cam->reg_size = resource_size(res);
607+
608+ cam->reg_base_virt = (unsigned int)ioremap(cam->reg_base_phys, cam->reg_size);
609+ if (cam->reg_base_virt == 0) {
610+ printk(KERN_ERR "[%s]: ioremap of registers region failed\n", pdev->name);
611+ release_mem_region(cam->reg_base_phys, cam->reg_size);
612+ return -ENOMEM;
613+ }
614+
615+ printk(KERN_INFO "[%s]: reg_base_virt = 0x%x\n", pdev->name, cam->reg_base_virt);
616+
617+ val = readw(cam->reg_base_virt + REG_MODE);
618+ printk(KERN_INFO "[%s]: reading register address=0x0 returns 0x%x\n", pdev->name, val);
619+
620+ return 0;
621+}
622+
623+static int configure_camera_sensor(struct cssp_cam_dev *cam)
624+{
625+ struct i2c_board_info *info = cam->camera_board_info;
626+ struct i2c_client *client;
627+ struct i2c_adapter *adapter;
628+ struct v4l2_subdev *subdev;
629+ struct v4l2_mbus_framefmt f_format = {
630+ .width = VGA_WIDTH,
631+ .height = VGA_HEIGHT,
632+ .code = V4L2_MBUS_FMT_YUYV8_2X8,
633+ .colorspace = V4L2_COLORSPACE_JPEG,
634+ };
635+
636+ /* Enable the clock just for the time of loading the camera driver and disable after that */
637+ /* It is going to be be re-enabled later, when camera will be in use */
638+ clk_enable(cam->camera_clk);
639+ udelay(5); // let the clock stabilize
640+
641+ adapter = i2c_get_adapter(((struct soc_camera_link *)(info->platform_data))->i2c_adapter_id);
642+ if (!adapter) {
643+ printk(KERN_INFO "[%s]: failed to get adapter...\n", __func__);
644+ return -ENODEV;
645+ }
646+
647+ client = i2c_new_device(adapter, info);
648+ i2c_put_adapter(adapter);
649+
650+ if (client == NULL) {
651+ return -ENODEV;
652+ }
653+
654+ printk(KERN_INFO "[%s]: client's name is: %s\n", __func__, client->name);
655+
656+ subdev = (struct v4l2_subdev *)i2c_get_clientdata(client);
657+ if (subdev == NULL) {
658+ i2c_unregister_device(client);
659+ return -ENODEV;
660+ }
661+
662+ cam->subdev = subdev;
663+
664+ v4l2_subdev_call(subdev, video, s_mbus_fmt, &f_format);
665+
666+ clk_disable(cam->camera_clk);
667+
668+ return 0;
669+}
670+
671+static int start_camera_sensor(struct cssp_cam_dev *cam)
672+{
673+ clk_enable(cam->camera_clk);
674+ udelay(5); /* let the clock stabilize */
675+
676+ v4l2_subdev_call(cam->subdev, video, s_stream, 1);
677+
678+ return 0;
679+}
680+
681+static void stop_camera_sensor(struct cssp_cam_dev *cam)
682+{
683+ v4l2_subdev_call(cam->subdev, video, s_stream, 0);
684+
685+ clk_disable(cam->camera_clk);
686+
687+ return;
688+}
689+
690+
691+/************************************************
692+ * Video4Linux2
693+ */
694+
695+static struct cssp_cam_fmt *get_format(struct v4l2_format *f)
696+{
697+ struct cssp_cam_fmt *fmt;
698+ unsigned int k;
699+
700+ for (k = 0; k < ARRAY_SIZE(formats); k++) {
701+ fmt = &formats[k];
702+ if (fmt->fourcc == f->fmt.pix.pixelformat)
703+ break;
704+ }
705+
706+ if (k == ARRAY_SIZE(formats))
707+ return NULL;
708+
709+ return &formats[k];
710+}
711+
712+
713+/* ------------------------------------------------------------------
714+ Videobuf operations
715+ ------------------------------------------------------------------*/
716+
717+static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
718+ unsigned int *nbuffers, unsigned int *nplanes,
719+ unsigned int sizes[], void *alloc_ctxs[])
720+{
721+ struct cssp_cam_dev *dev = vb2_get_drv_priv(vq);
722+ unsigned long size;
723+
724+ size = dev->sizeimage;
725+
726+ if (0 == *nbuffers)
727+ *nbuffers = 32;
728+
729+ while (size * *nbuffers > vid_limit * 1024 * 1024)
730+ (*nbuffers)--;
731+
732+ *nplanes = 1;
733+
734+ sizes[0] = size;
735+
736+ alloc_ctxs[0] = dev->dma_cont_ctx;
737+
738+ dprintk(dev, 1, "%s, count=%d, size=%ld\n", __func__, *nbuffers, size);
739+
740+ return 0;
741+}
742+
743+static int buffer_init(struct vb2_buffer *vb)
744+{
745+ struct cssp_cam_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
746+
747+ BUG_ON(NULL == dev->fmt);
748+
749+ /*
750+ * This callback is called once per buffer, after its allocation.
751+ *
752+ * Vivi does not allow changing format during streaming, but it is
753+ * possible to do so when streaming is paused (i.e. in streamoff state).
754+ * Buffers however are not freed when going into streamoff and so
755+ * buffer size verification has to be done in buffer_prepare, on each
756+ * qbuf.
757+ * It would be best to move verification code here to buf_init and
758+ * s_fmt though.
759+ */
760+
761+ return 0;
762+}
763+
764+static int buffer_prepare(struct vb2_buffer *vb)
765+{
766+ struct cssp_cam_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
767+ struct cssp_cam_buffer *buf = container_of(vb, struct cssp_cam_buffer, vb);
768+ unsigned long size;
769+
770+ dprintk(dev, 1, "%s, field=%d\n", __func__, vb->v4l2_buf.field);
771+
772+ BUG_ON(NULL == dev->fmt);
773+
774+ /*
775+ * Theses properties only change when queue is idle, see s_fmt.
776+ * The below checks should not be performed here, on each
777+ * buffer_prepare (i.e. on each qbuf). Most of the code in this function
778+ * should thus be moved to buffer_init and s_fmt.
779+ */
780+ if (dev->width < 48 || dev->width > MAX_WIDTH ||
781+ dev->height < 32 || dev->height > MAX_HEIGHT)
782+ return -EINVAL;
783+
784+ size = dev->sizeimage;
785+ if (vb2_plane_size(vb, 0) < size) {
786+ dprintk(dev, 1, "%s data will not fit into plane (%lu < %lu)\n",
787+ __func__, vb2_plane_size(vb, 0), size);
788+ return -EINVAL;
789+ }
790+
791+ vb2_set_plane_payload(&buf->vb, 0, size);
792+
793+ buf->fmt = dev->fmt;
794+
795+ return 0;
796+}
797+
798+static int buffer_finish(struct vb2_buffer *vb)
799+{
800+ struct cssp_cam_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
801+ dprintk(dev, 1, "%s\n", __func__);
802+ return 0;
803+}
804+
805+static void buffer_cleanup(struct vb2_buffer *vb)
806+{
807+ struct cssp_cam_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
808+ dprintk(dev, 1, "%s\n", __func__);
809+}
810+
811+static void buffer_queue(struct vb2_buffer *vb)
812+{
813+ struct cssp_cam_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
814+ struct cssp_cam_buffer *buf = container_of(vb, struct cssp_cam_buffer, vb);
815+ struct cssp_cam_dmaqueue *vidq = &dev->vidq;
816+ unsigned long flags = 0;
817+
818+ dprintk(dev, 1, "%s\n", __func__);
819+
820+ if (dev->streaming_started && !dev->current_vb) {
821+ trigger_dma_transfer_to_buf(dev, &buf->vb);
822+ } else {
823+ spin_lock_irqsave(&dev->slock, flags);
824+ list_add_tail(&buf->list, &vidq->active);
825+ spin_unlock_irqrestore(&dev->slock, flags);
826+ }
827+}
828+
829+static int start_streaming(struct vb2_queue *vq, unsigned int count)
830+{
831+ struct cssp_cam_dev *dev = vb2_get_drv_priv(vq);
832+ int ret;
833+
834+ dprintk(dev, 1, "%s\n", __func__);
835+
836+ ret = start_camera_sensor(dev);
837+ if (ret != 0)
838+ return ret;
839+
840+ // Enable DMA
841+ edma_start(dev->dma_ch);
842+
843+ dev->streaming_started = 1;
844+
845+ /* check if we have new buffer queued */
846+ dequeue_buffer_for_dma(dev);
847+
848+ return 0;
849+}
850+
851+/* abort streaming and wait for last buffer */
852+static int stop_streaming(struct vb2_queue *vq)
853+{
854+ struct cssp_cam_dev *dev = vb2_get_drv_priv(vq);
855+ struct cssp_cam_dmaqueue *dma_q = &dev->vidq;
856+
857+ dprintk(dev, 1, "%s\n", __func__);
858+
859+ // Disable DMA
860+ edma_stop(dev->dma_ch);
861+
862+ // Disable data capture
863+ dev->mode &= ~ENABLE;
864+ writew(dev->mode, dev->reg_base_virt + REG_MODE);
865+ readw(dev->reg_base_virt + REG_MODE);
866+
867+ stop_camera_sensor(dev);
868+
869+ dev->streaming_started = 0;
870+
871+ /* Release all active buffers */
872+ while (!list_empty(&dma_q->active)) {
873+ struct cssp_cam_buffer *buf;
874+
875+ buf = list_entry(dma_q->active.next, struct cssp_cam_buffer, list);
876+ list_del(&buf->list);
877+ vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
878+ dprintk(dev, 2, "[%p/%d] done\n", buf, buf->vb.v4l2_buf.index);
879+ }
880+
881+ dev->current_vb = NULL;
882+
883+ return 0;
884+}
885+
886+static void cssp_cam_lock(struct vb2_queue *vq)
887+{
888+ struct cssp_cam_dev *dev = vb2_get_drv_priv(vq);
889+ mutex_lock(&dev->mutex);
890+}
891+
892+static void cssp_cam_unlock(struct vb2_queue *vq)
893+{
894+ struct cssp_cam_dev *dev = vb2_get_drv_priv(vq);
895+ mutex_unlock(&dev->mutex);
896+}
897+
898+static struct vb2_ops cssp_cam_video_qops = {
899+ .queue_setup = queue_setup,
900+ .buf_init = buffer_init,
901+ .buf_prepare = buffer_prepare,
902+ .buf_finish = buffer_finish,
903+ .buf_cleanup = buffer_cleanup,
904+ .buf_queue = buffer_queue,
905+ .start_streaming = start_streaming,
906+ .stop_streaming = stop_streaming,
907+ .wait_prepare = cssp_cam_unlock,
908+ .wait_finish = cssp_cam_lock,
909+};
910+
911+
912+/* ------------------------------------------------------------------
913+ IOCTL vidioc handling
914+ ------------------------------------------------------------------*/
915+
916+static int vidioc_querycap(struct file *file, void *priv,
917+ struct v4l2_capability *cap)
918+{
919+ struct cssp_cam_dev *dev = video_drvdata(file);
920+
921+ strcpy(cap->driver, "cssp_camera");
922+ strcpy(cap->card, "cssp_camera");
923+ strlcpy(cap->bus_info, dev->v4l2_dev.name, sizeof(cap->bus_info));
924+ cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
925+ V4L2_CAP_READWRITE;
926+ return 0;
927+}
928+
929+static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
930+ struct v4l2_fmtdesc *f)
931+{
932+ struct cssp_cam_fmt *fmt;
933+
934+ if (f->index >= ARRAY_SIZE(formats))
935+ return -EINVAL;
936+
937+ fmt = &formats[f->index];
938+
939+ strlcpy(f->description, fmt->name, sizeof(f->description));
940+ f->pixelformat = fmt->fourcc;
941+ return 0;
942+}
943+
944+static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
945+ struct v4l2_format *f)
946+{
947+ struct cssp_cam_dev *dev = video_drvdata(file);
948+
949+ f->fmt.pix.width = dev->width;
950+ f->fmt.pix.height = dev->height;
951+ f->fmt.pix.field = dev->field;
952+ f->fmt.pix.pixelformat = dev->fmt->fourcc;
953+ f->fmt.pix.bytesperline = dev->bytesperline;
954+ f->fmt.pix.sizeimage = dev->sizeimage;
955+ f->fmt.pix.colorspace = dev->colorspace;
956+
957+ return 0;
958+}
959+
960+static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
961+ struct v4l2_format *f)
962+{
963+ struct cssp_cam_dev *dev = video_drvdata(file);
964+ struct cssp_cam_fmt *fmt;
965+ struct v4l2_mbus_framefmt mbus_fmt;
966+ struct v4l2_pix_format *pix = &f->fmt.pix;
967+
968+ fmt = get_format(f);
969+ if (!fmt) {
970+ dprintk(dev, 1, "Fourcc format (0x%08x) invalid.\n",
971+ f->fmt.pix.pixelformat);
972+ return -EINVAL;
973+ }
974+
975+ v4l2_fill_mbus_format(&mbus_fmt, pix, fmt->code);
976+ v4l2_subdev_call(dev->subdev, video, try_mbus_fmt, &mbus_fmt);
977+ v4l2_fill_pix_format(pix, &mbus_fmt);
978+ pix->bytesperline = (pix->width * fmt->depth) >> 3;
979+ pix->sizeimage = pix->height * pix->bytesperline;
980+
981+ return 0;
982+}
983+
984+static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
985+ struct v4l2_format *f)
986+{
987+ struct cssp_cam_dev *dev = video_drvdata(file);
988+ struct vb2_queue *q = &dev->vb_vidq;
989+ struct v4l2_pix_format *pix = &f->fmt.pix;
990+ struct v4l2_mbus_framefmt mbus_fmt;
991+
992+ int ret = vidioc_try_fmt_vid_cap(file, priv, f);
993+ if (ret < 0)
994+ return ret;
995+
996+ if (vb2_is_streaming(q)) {
997+ dprintk(dev, 1, "%s device busy\n", __func__);
998+ return -EBUSY;
999+ }
1000+
1001+ dev->fmt = get_format(f);
1002+ dev->width = f->fmt.pix.width;
1003+ dev->height = f->fmt.pix.height;
1004+ dev->field = f->fmt.pix.field;
1005+ dev->colorspace = f->fmt.pix.colorspace;
1006+ dev->bytesperline = f->fmt.pix.bytesperline;
1007+ dev->sizeimage = f->fmt.pix.sizeimage;
1008+
1009+ /* Set the sensor into the new format */
1010+ v4l2_fill_mbus_format(&mbus_fmt, pix, dev->fmt->code);
1011+ v4l2_subdev_call(dev->subdev, video, s_mbus_fmt, &mbus_fmt);
1012+
1013+ /* Set the EDMA for the new resolution */
1014+ dev->dma_tr_params.a_b_cnt = ACNT(BYTES_PER_DMA_EVT) | BCNT(dev->bytesperline / BYTES_PER_DMA_EVT);
1015+ dev->dma_tr_params.link_bcntrld = BCNTRLD(dev->bytesperline / BYTES_PER_DMA_EVT) | LINK(0xffff);
1016+ dev->dma_tr_params.ccnt = CCNT(dev->height);
1017+
1018+ return 0;
1019+}
1020+
1021+static int vidioc_reqbufs(struct file *file, void *priv,
1022+ struct v4l2_requestbuffers *p)
1023+{
1024+ struct cssp_cam_dev *dev = video_drvdata(file);
1025+ return vb2_reqbufs(&dev->vb_vidq, p);
1026+}
1027+
1028+static int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p)
1029+{
1030+ struct cssp_cam_dev *dev = video_drvdata(file);
1031+ return vb2_querybuf(&dev->vb_vidq, p);
1032+}
1033+
1034+static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
1035+{
1036+ struct cssp_cam_dev *dev = video_drvdata(file);
1037+ return vb2_qbuf(&dev->vb_vidq, p);
1038+}
1039+
1040+static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
1041+{
1042+ struct cssp_cam_dev *dev = video_drvdata(file);
1043+ return vb2_dqbuf(&dev->vb_vidq, p, file->f_flags & O_NONBLOCK);
1044+}
1045+
1046+static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
1047+{
1048+ struct cssp_cam_dev *dev = video_drvdata(file);
1049+ return vb2_streamon(&dev->vb_vidq, i);
1050+}
1051+
1052+static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
1053+{
1054+ struct cssp_cam_dev *dev = video_drvdata(file);
1055+ return vb2_streamoff(&dev->vb_vidq, i);
1056+}
1057+
1058+static int vidioc_log_status(struct file *file, void *priv)
1059+{
1060+ struct cssp_cam_dev *dev = video_drvdata(file);
1061+
1062+ v4l2_ctrl_handler_log_status(&dev->ctrl_handler, dev->v4l2_dev.name);
1063+ return 0;
1064+}
1065+
1066+static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *i)
1067+{
1068+ return 0;
1069+}
1070+
1071+/* only one input in this sample driver */
1072+static int vidioc_enum_input(struct file *file, void *priv,
1073+ struct v4l2_input *inp)
1074+{
1075+ return -EINVAL;
1076+
1077+ inp->type = V4L2_INPUT_TYPE_CAMERA;
1078+ inp->std = V4L2_STD_525_60;
1079+ sprintf(inp->name, "Camera %u", inp->index);
1080+ return 0;
1081+}
1082+
1083+static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
1084+{
1085+ struct cssp_cam_dev *dev = video_drvdata(file);
1086+
1087+ *i = dev->input;
1088+
1089+ return 0;
1090+}
1091+
1092+static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
1093+{
1094+ struct cssp_cam_dev *dev = video_drvdata(file);
1095+
1096+ return -EINVAL;
1097+
1098+ if (i == dev->input)
1099+ return 0;
1100+
1101+ dev->input = i;
1102+
1103+ return 0;
1104+}
1105+
1106+static int vidioc_subscribe_event(struct v4l2_fh *fh,
1107+ struct v4l2_event_subscription *sub)
1108+{
1109+ switch (sub->type) {
1110+ case V4L2_EVENT_CTRL:
1111+ return v4l2_event_subscribe(fh, sub, 0);
1112+ default:
1113+ return -EINVAL;
1114+ }
1115+}
1116+
1117+static const struct v4l2_ioctl_ops cssp_cam_ioctl_ops = {
1118+ .vidioc_querycap = vidioc_querycap,
1119+ .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
1120+ .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
1121+ .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
1122+ .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
1123+ .vidioc_reqbufs = vidioc_reqbufs,
1124+ .vidioc_querybuf = vidioc_querybuf,
1125+ .vidioc_qbuf = vidioc_qbuf,
1126+ .vidioc_dqbuf = vidioc_dqbuf,
1127+ .vidioc_s_std = vidioc_s_std,
1128+ .vidioc_enum_input = vidioc_enum_input,
1129+ .vidioc_g_input = vidioc_g_input,
1130+ .vidioc_s_input = vidioc_s_input,
1131+ .vidioc_streamon = vidioc_streamon,
1132+ .vidioc_streamoff = vidioc_streamoff,
1133+ .vidioc_log_status = vidioc_log_status,
1134+ .vidioc_subscribe_event = vidioc_subscribe_event,
1135+ .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
1136+};
1137+
1138+
1139+/* ------------------------------------------------------------------
1140+ File operations
1141+ ------------------------------------------------------------------*/
1142+
1143+static unsigned int video_poll(struct file *file, struct poll_table_struct *wait)
1144+{
1145+ struct cssp_cam_dev *dev = video_drvdata(file);
1146+ struct v4l2_fh *fh = file->private_data;
1147+ struct vb2_queue *q = &dev->vb_vidq;
1148+ unsigned int res;
1149+
1150+ dprintk(dev, 1, "%s\n", __func__);
1151+ res = vb2_poll(q, file, wait);
1152+ if (v4l2_event_pending(fh))
1153+ res |= POLLPRI;
1154+ else
1155+ poll_wait(file, &fh->wait, wait);
1156+ return res;
1157+}
1158+
1159+static int video_mmap(struct file *file, struct vm_area_struct *vma)
1160+{
1161+ struct cssp_cam_dev *dev = video_drvdata(file);
1162+ int ret;
1163+
1164+ dprintk(dev, 1, "mmap called, vma=0x%08lx\n", (unsigned long)vma);
1165+
1166+ ret = vb2_mmap(&dev->vb_vidq, vma);
1167+ dprintk(dev, 1, "vma start=0x%08lx, size=%ld, ret=%d\n",
1168+ (unsigned long)vma->vm_start,
1169+ (unsigned long)vma->vm_end - (unsigned long)vma->vm_start,
1170+ ret);
1171+ return ret;
1172+}
1173+
1174+static ssize_t video_read(struct file *file, char __user *buf, size_t size, loff_t *offset)
1175+{
1176+ struct cssp_cam_dev *cam_dev = video_drvdata(file);
1177+
1178+ dprintk(cam_dev, 1, "read called\n");
1179+ return vb2_read(&cam_dev->vb_vidq, buf, size, offset, file->f_flags & O_NONBLOCK);
1180+}
1181+
1182+static int video_close(struct file *file)
1183+{
1184+ struct video_device *vdev = video_devdata(file);
1185+ struct cssp_cam_dev *cam_dev = video_drvdata(file);
1186+
1187+ dprintk(cam_dev, 1, "close called (dev=%s), file %p\n",
1188+ video_device_node_name(vdev), file);
1189+
1190+ if (v4l2_fh_is_singular_file(file))
1191+ vb2_queue_release(&cam_dev->vb_vidq);
1192+ return v4l2_fh_release(file);
1193+}
1194+
1195+static const struct v4l2_file_operations cssp_cam_fops = {
1196+ .owner = THIS_MODULE,
1197+ .open = v4l2_fh_open,
1198+ .release = video_close,
1199+ .read = video_read,
1200+ .poll = video_poll,
1201+ .unlocked_ioctl = video_ioctl2,
1202+ .mmap = video_mmap,
1203+};
1204+
1205+
1206+/* ------------------------------------------------------------------
1207+ Driver initialization
1208+ ------------------------------------------------------------------*/
1209+
1210+static struct video_device cssp_cam_template = {
1211+ .name = "cssp_camera",
1212+ .fops = &cssp_cam_fops,
1213+ .ioctl_ops = &cssp_cam_ioctl_ops,
1214+ .minor = -1,
1215+ .release = video_device_release,
1216+ .tvnorms = V4L2_STD_525_60,
1217+ .current_norm = V4L2_STD_NTSC_M,
1218+};
1219+
1220+static int __init video_probe(struct cssp_cam_dev *cam_dev)
1221+{
1222+ struct video_device *vfd;
1223+ struct v4l2_ctrl_handler *hdl;
1224+ struct vb2_queue *q;
1225+ int ret = 0;
1226+
1227+ snprintf(cam_dev->v4l2_dev.name, sizeof(cam_dev->v4l2_dev.name),
1228+ "%s-%03d", "cssp_camera", 0);
1229+ ret = v4l2_device_register(NULL, &cam_dev->v4l2_dev);
1230+ if (ret)
1231+ goto free_dev;
1232+
1233+ cam_dev->fmt = &formats[0];
1234+ cam_dev->width = VGA_WIDTH;
1235+ cam_dev->height = VGA_HEIGHT;
1236+ cam_dev->sizeimage = VGA_WIDTH * VGA_HEIGHT * BYTES_PER_PIXEL;
1237+ hdl = &cam_dev->ctrl_handler;
1238+ v4l2_ctrl_handler_init(hdl, 0);
1239+
1240+ if (hdl->error) {
1241+ ret = hdl->error;
1242+ goto unreg_dev;
1243+ }
1244+ cam_dev->v4l2_dev.ctrl_handler = hdl;
1245+
1246+ /* initialize locks */
1247+ spin_lock_init(&cam_dev->slock);
1248+
1249+ /* initialize queue */
1250+ q = &cam_dev->vb_vidq;
1251+ memset(q, 0, sizeof(cam_dev->vb_vidq));
1252+ q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1253+ q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
1254+ q->drv_priv = cam_dev;
1255+ q->buf_struct_size = sizeof(struct cssp_cam_buffer);
1256+ q->ops = &cssp_cam_video_qops;
1257+ q->mem_ops = &vb2_dma_contig_memops;
1258+
1259+ vb2_queue_init(q);
1260+
1261+ mutex_init(&cam_dev->mutex);
1262+
1263+ /* init video dma queues */
1264+ INIT_LIST_HEAD(&cam_dev->vidq.active);
1265+
1266+ ret = -ENOMEM;
1267+ vfd = video_device_alloc();
1268+ if (!vfd)
1269+ goto unreg_dev;
1270+
1271+ *vfd = cssp_cam_template;
1272+ vfd->debug = debug;
1273+ vfd->v4l2_dev = &cam_dev->v4l2_dev;
1274+ set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags);
1275+
1276+ /*
1277+ * Provide a mutex to v4l2 core. It will be used to protect
1278+ * all fops and v4l2 ioctls.
1279+ */
1280+ vfd->lock = &cam_dev->mutex;
1281+
1282+ ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr);
1283+ if (ret < 0)
1284+ goto rel_vdev;
1285+
1286+ video_set_drvdata(vfd, cam_dev);
1287+
1288+ if (video_nr != -1)
1289+ video_nr++;
1290+
1291+ cam_dev->vdev = vfd;
1292+ v4l2_info(&cam_dev->v4l2_dev, "V4L2 device registered as %s\n",
1293+ video_device_node_name(vfd));
1294+
1295+ return 0;
1296+
1297+rel_vdev:
1298+ video_device_release(vfd);
1299+unreg_dev:
1300+ v4l2_ctrl_handler_free(hdl);
1301+ v4l2_device_unregister(&cam_dev->v4l2_dev);
1302+free_dev:
1303+ return ret;
1304+}
1305+
1306+static int video_remove(struct cssp_cam_dev *cam_dev)
1307+{
1308+ if (cam_dev->dma_cont_ctx != NULL)
1309+ vb2_dma_contig_cleanup_ctx(cam_dev->dma_cont_ctx);
1310+
1311+ v4l2_info(&cam_dev->v4l2_dev, "unregistering %s\n",
1312+ video_device_node_name(cam_dev->vdev));
1313+ video_unregister_device(cam_dev->vdev);
1314+ v4l2_device_unregister(&cam_dev->v4l2_dev);
1315+ v4l2_ctrl_handler_free(&cam_dev->ctrl_handler);
1316+
1317+ return 0;
1318+}
1319+
1320+static int __init cssp_cam_probe(struct platform_device *pdev)
1321+{
1322+ struct cssp_cam_dev *cam_dev;
1323+ int ret = 0;
1324+ struct cssp_cam_platform_data *cssp_cam_platform_data;
1325+
1326+ cssp_cam_platform_data = (struct cssp_cam_platform_data *) pdev->dev.platform_data;
1327+ if (cssp_cam_platform_data == NULL) {
1328+ printk(KERN_ERR "[%s]: missing platform data\n", pdev->name);
1329+ return -ENODEV;
1330+ }
1331+
1332+ if (cssp_cam_platform_data->cam_i2c_board_info == NULL) {
1333+ printk(KERN_ERR "[%s]: missing camera i2c board info\n", pdev->name);
1334+ return -ENODEV;
1335+ }
1336+
1337+ cam_dev = kzalloc(sizeof(*cam_dev), GFP_KERNEL);
1338+ if (!cam_dev)
1339+ return -ENOMEM;
1340+
1341+ cam_dev->pdev = pdev;
1342+ platform_set_drvdata(pdev, cam_dev);
1343+
1344+ cam_dev->camera_board_info = cssp_cam_platform_data->cam_i2c_board_info;
1345+
1346+ cam_dev->camera_clk = clk_get(&pdev->dev, cssp_cam_platform_data->cam_clk_name);
1347+ if (IS_ERR(cam_dev->camera_clk)) {
1348+ ret = PTR_ERR(cam_dev->camera_clk);
1349+ printk(KERN_ERR "[%s]: cannot clk_get %s\n", pdev->name, cssp_cam_platform_data->cam_clk_name);
1350+ goto fail0;
1351+ }
1352+
1353+ ret = configure_cssp(cam_dev);
1354+ if (ret)
1355+ goto fail1;
1356+
1357+ ret = configure_edma(cam_dev);
1358+ if (ret)
1359+ goto fail2;
1360+
1361+ cam_dev->mode = FMT_2X8_EN | PCLK_POL | HS_EN;
1362+
1363+ ret = configure_camera_sensor(cam_dev);
1364+ if (ret) {
1365+ printk(KERN_ERR "[%s]: camera sensor configuration failed\n", pdev->name);
1366+ goto fail3;
1367+ }
1368+
1369+ cam_dev->dma_cont_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
1370+ if (IS_ERR(cam_dev->dma_cont_ctx)) {
1371+ ret = PTR_ERR(cam_dev->dma_cont_ctx);
1372+ goto fail3;
1373+ }
1374+
1375+ ret = video_probe(cam_dev);
1376+ if (ret)
1377+ goto fail4;
1378+
1379+ return ret;
1380+
1381+fail4:
1382+ vb2_dma_contig_cleanup_ctx(cam_dev->dma_cont_ctx);
1383+
1384+fail3:
1385+ edma_free_channel(cam_dev->dma_ch);
1386+
1387+fail2:
1388+ gpio_free(cam_dev->reset_pin);
1389+ iounmap((void *)cam_dev->reg_base_virt);
1390+ release_mem_region(cam_dev->reg_base_phys, cam_dev->reg_size);
1391+
1392+fail1:
1393+ clk_put(cam_dev->camera_clk);
1394+
1395+fail0:
1396+ kfree(cam_dev);
1397+
1398+ return ret;
1399+}
1400+
1401+static int cssp_cam_remove(struct platform_device *pdev)
1402+{
1403+ struct cssp_cam_dev *cam = platform_get_drvdata(pdev);
1404+
1405+ iounmap((void *)cam->reg_base_virt);
1406+
1407+ release_mem_region(cam->reg_base_phys, cam->reg_size);
1408+
1409+ gpio_free(cam->reset_pin);
1410+
1411+ edma_free_channel(cam->dma_ch);
1412+
1413+ video_remove(cam);
1414+
1415+ clk_put(cam->camera_clk);
1416+
1417+ kfree(cam);
1418+
1419+ printk(KERN_INFO "[%s]: removed\n", pdev->name);
1420+
1421+ return 0;
1422+}
1423+
1424+
1425+static struct platform_driver cssp_cam_driver = {
1426+ .probe = cssp_cam_probe,
1427+ .remove = __devexit_p(cssp_cam_remove),
1428+ .driver = {
1429+ .name = "cssp-camera",
1430+ .owner = THIS_MODULE,
1431+ },
1432+};
1433+
1434+
1435+static int __init cssp_cam_init(void)
1436+{
1437+ return platform_driver_register(&cssp_cam_driver);
1438+}
1439+
1440+static void __exit cssp_cam_exit(void)
1441+{
1442+ platform_driver_unregister(&cssp_cam_driver);
1443+}
1444+
1445+
1446+module_init(cssp_cam_init);
1447+module_exit(cssp_cam_exit);
1448+
1449+/*
1450+ * Macros sets license, author and description
1451+ */
1452+MODULE_LICENSE("GPLv2");
1453+MODULE_AUTHOR("Dan Aizenstros, Damian Eppel, Przemek Szewczyk");
1454+MODULE_DESCRIPTION("QuickLogic Camera Interface driver");
1455+
1456diff --git a/drivers/media/video/cssp_camera/cssp_camera.h b/drivers/media/video/cssp_camera/cssp_camera.h
1457new file mode 100644
1458index 0000000..d018ca1
1459--- /dev/null
1460+++ b/drivers/media/video/cssp_camera/cssp_camera.h
1461@@ -0,0 +1,148 @@
1462+/*
1463+ * cssp-camera driver
1464+ *
1465+ * Based on Vivi driver
1466+ *
1467+ * Copyright (C) 2012 QuickLogic Corp.
1468+ *
1469+ * Developed for QuickLogic by:
1470+ * Damian Eppel <damian.eppel@teleca.com>
1471+ * Przemek Szewczyk <przemek.szewczyk@teleca.com>
1472+ * Dan Aizenstros <daizenstros@quicklogic.com>
1473+ *
1474+ * This program is free software; you can redistribute it and/or modify
1475+ * it under the terms of the GNU General Public License version 2 as
1476+ * published by the Free Software Foundation.
1477+ *
1478+ */
1479+
1480+#ifndef CSSP_CAMERA_H
1481+#define CSSP_CAMERA_H
1482+
1483+
1484+static unsigned video_nr = -1;
1485+module_param(video_nr, uint, 0644);
1486+MODULE_PARM_DESC(video_nr, "videoX start number, -1 is autodetect");
1487+
1488+static unsigned debug;
1489+module_param(debug, uint, 0644);
1490+MODULE_PARM_DESC(debug, "activates debug info");
1491+
1492+static unsigned int vid_limit = 1;
1493+module_param(vid_limit, uint, 0644);
1494+MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes");
1495+
1496+#define dprintk(dev, level, fmt, arg...) \
1497+ v4l2_dbg(level, debug, &dev->v4l2_dev, fmt, ## arg)
1498+
1499+#define VGA_WIDTH 640
1500+#define VGA_HEIGHT 480
1501+
1502+#define MAX_WIDTH 2048
1503+#define MAX_HEIGHT 1536
1504+
1505+#define VGA_RES (VGA_WIDTH * VGA_HEIGHT)
1506+#define BYTES_PER_PIXEL 2
1507+#define BYTES_PER_DMA_EVT 32
1508+
1509+/* PaRAM.opt: */
1510+#define TCC(v) (((v) & 0x3f) << 12)
1511+/* PaRAM.a_b_cnt: */
1512+#define ACNT(v) ((v) & 0xffff)
1513+#define BCNT(v) (((v) & 0xffff) << 16)
1514+/* PaRAM.src_dst_bidx: */
1515+#define SRCBIDX(v) ((v) & 0xffff)
1516+#define DSTBIDX(v) (((v) & 0xffff) << 16)
1517+/* PaRAM.link_bcntrld: */
1518+#define LINK(v) ((v) & 0xffff)
1519+#define BCNTRLD(v) (((v) & 0xffff) << 16)
1520+/* PaRAM.src_dst_cidx: */
1521+#define SRCCIDX(v) ((v) & 0xffff)
1522+#define DSTCIDX(v) (((v) & 0xffff) << 16)
1523+/* PaRAM.ccnt: */
1524+#define CCNT(v) ((v) & 0xffff)
1525+
1526+
1527+struct cssp_cam_platform_data {
1528+ struct i2c_board_info *cam_i2c_board_info;
1529+ const char *cam_clk_name;
1530+ int dma_ch;
1531+ int gpio_reset_pin;
1532+};
1533+
1534+
1535+/* ------------------------------------------------------------------
1536+ video Basic structures
1537+ ------------------------------------------------------------------*/
1538+
1539+struct cssp_cam_fmt {
1540+ char *name;
1541+ u32 fourcc; /* v4l2 format id */
1542+ int depth;
1543+ enum v4l2_mbus_pixelcode code;
1544+};
1545+
1546+/* buffer for one video frame */
1547+struct cssp_cam_buffer {
1548+ /* common v4l buffer stuff -- must be first */
1549+ struct vb2_buffer vb;
1550+ struct list_head list;
1551+ struct cssp_cam_fmt *fmt;
1552+};
1553+
1554+struct cssp_cam_dmaqueue {
1555+ struct list_head active;
1556+};
1557+
1558+struct cssp_cam_dev {
1559+ struct v4l2_device v4l2_dev;
1560+ struct v4l2_ctrl_handler ctrl_handler;
1561+ struct v4l2_subdev *subdev;
1562+
1563+ spinlock_t slock;
1564+ struct mutex mutex;
1565+
1566+ /* various device info */
1567+ struct video_device *vdev;
1568+ struct platform_device *pdev;
1569+
1570+ struct cssp_cam_dmaqueue vidq;
1571+ void *dma_cont_ctx;
1572+ int streaming_started;
1573+ struct vb2_buffer *current_vb;
1574+
1575+ /* Input Number */
1576+ int input;
1577+
1578+ /* video capture */
1579+ struct cssp_cam_fmt *fmt;
1580+ u32 width;
1581+ u32 height;
1582+ u32 bytesperline;
1583+ u32 sizeimage;
1584+ enum v4l2_colorspace colorspace;
1585+ struct vb2_queue vb_vidq;
1586+ enum v4l2_field field;
1587+ unsigned int field_count;
1588+
1589+
1590+ /* Camera Sensor */
1591+ struct i2c_board_info *camera_board_info;
1592+ struct clk *camera_clk;
1593+
1594+ unsigned int reg_base_virt;
1595+ unsigned int reg_base_phys;
1596+ resource_size_t reg_size;
1597+ u16 mode;
1598+
1599+ struct edmacc_param dma_tr_params;
1600+ int dma_ch;
1601+ u64 dma_mask;
1602+
1603+ int frame_cnt;
1604+
1605+ int reset_pin;
1606+};
1607+
1608+
1609+#endif /* CSSP_CAMERA_H */
1610--
16111.7.10
1612
diff --git a/recipes-kernel/linux/linux-ti33x-psp-3.2/beaglebone/0075-video-da8xx-fb-calculate-pixel-clock-period-for-the-.patch b/recipes-kernel/linux/linux-ti33x-psp-3.2/beaglebone/0075-video-da8xx-fb-calculate-pixel-clock-period-for-the-.patch
new file mode 100644
index 00000000..face34b4
--- /dev/null
+++ b/recipes-kernel/linux/linux-ti33x-psp-3.2/beaglebone/0075-video-da8xx-fb-calculate-pixel-clock-period-for-the-.patch
@@ -0,0 +1,73 @@
1From e12d15eadf15f8119729a65ecca79529b4fe3863 Mon Sep 17 00:00:00 2001
2From: "Manjunathappa, Prakash" <prakash.pm@ti.com>
3Date: Wed, 4 Jul 2012 17:10:16 +0530
4Subject: [PATCH 75/79] video:da8xx-fb: calculate pixel clock period for the
5 panel
6
7Patch calculates pixel clock period in pico seconds and updates
8the same in variable screen information structure. fbset utility
9uses this information.
10This patch is from upstream backport, bearing commit id
1112fa8350244d73b6111ec9bc6c2fd5d49fa601b5.
12
13Signed-off-by: Manjunathappa, Prakash <prakash.pm@ti.com>
14Signed-off-by: Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
15Signed-off-by: Patil, Rachna <rachna@ti.com>
16---
17 drivers/video/da8xx-fb.c | 19 ++++++++++++++++++-
18 1 file changed, 18 insertions(+), 1 deletion(-)
19
20diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
21index 010a8bc..ddc251e 100644
22--- a/drivers/video/da8xx-fb.c
23+++ b/drivers/video/da8xx-fb.c
24@@ -37,6 +37,7 @@
25 #include <linux/lcm.h>
26 #include <video/da8xx-fb.h>
27 #include <asm/mach-types.h>
28+#include <asm/div64.h>
29
30 #define DRIVER_NAME "da8xx_lcdc"
31
32@@ -192,7 +193,6 @@ static struct fb_var_screeninfo da8xx_fb_var __devinitdata = {
33 .activate = 0,
34 .height = -1,
35 .width = -1,
36- .pixclock = 33333,/*Pico Sec*/
37 .accel_flags = 0,
38 .left_margin = LEFT_MARGIN,
39 .right_margin = RIGHT_MARGIN,
40@@ -1267,6 +1267,22 @@ static struct fb_ops da8xx_fb_ops = {
41 .fb_blank = cfb_blank,
42 };
43
44+/* Calculate and return pixel clock period in pico seconds */
45+static unsigned int da8xxfb_pixel_clk_period(struct da8xx_fb_par *par)
46+{
47+ unsigned int lcd_clk, div;
48+ unsigned int configured_pix_clk;
49+ unsigned long long pix_clk_period_picosec = 1000000000000ULL;
50+
51+ lcd_clk = clk_get_rate(par->lcdc_clk);
52+ div = lcd_clk / par->pxl_clk;
53+ configured_pix_clk = (lcd_clk / div);
54+
55+ do_div(pix_clk_period_picosec, configured_pix_clk);
56+
57+ return pix_clk_period_picosec;
58+}
59+
60 static int __devinit fb_probe(struct platform_device *device)
61 {
62 struct da8xx_lcdc_platform_data *fb_pdata =
63@@ -1437,6 +1453,7 @@ static int __devinit fb_probe(struct platform_device *device)
64
65 da8xx_fb_var.hsync_len = lcdc_info->hsw;
66 da8xx_fb_var.vsync_len = lcdc_info->vsw;
67+ da8xx_fb_var.pixclock = da8xxfb_pixel_clk_period(par);
68
69 da8xx_fb_var.right_margin = lcdc_info->hfp;
70 da8xx_fb_var.left_margin = lcdc_info->hbp;
71--
721.7.10
73
diff --git a/recipes-kernel/linux/linux-ti33x-psp-3.2/beaglebone/0076-beaglebone-improve-GPMC-bus-timings-for-camera-cape.patch b/recipes-kernel/linux/linux-ti33x-psp-3.2/beaglebone/0076-beaglebone-improve-GPMC-bus-timings-for-camera-cape.patch
new file mode 100644
index 00000000..5997367f
--- /dev/null
+++ b/recipes-kernel/linux/linux-ti33x-psp-3.2/beaglebone/0076-beaglebone-improve-GPMC-bus-timings-for-camera-cape.patch
@@ -0,0 +1,105 @@
1From e81c7627c3d90209271a0f1e7486d0f779f05289 Mon Sep 17 00:00:00 2001
2From: Dan Aizenstros <daizenstros@quicklogic.com>
3Date: Thu, 12 Jul 2012 12:31:08 -0400
4Subject: [PATCH 76/79] beaglebone: improve GPMC bus timings for camera cape
5
6Signed-off-by: Dan Aizenstros <daizenstros@quicklogic.com>
7Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
8---
9 arch/arm/mach-omap2/board-am335xevm.c | 13 +++++++------
10 drivers/media/video/cssp_camera/cssp_camera.c | 5 +----
11 drivers/media/video/cssp_camera/cssp_camera.h | 2 +-
12 3 files changed, 9 insertions(+), 11 deletions(-)
13
14diff --git a/arch/arm/mach-omap2/board-am335xevm.c b/arch/arm/mach-omap2/board-am335xevm.c
15index 6b4539e..82020fc 100644
16--- a/arch/arm/mach-omap2/board-am335xevm.c
17+++ b/arch/arm/mach-omap2/board-am335xevm.c
18@@ -1895,9 +1895,10 @@ static struct gpmc_timings cssp_timings = {
19 /* Minimum clock period for synchronous mode (in picoseconds) */
20 .sync_clk = 10000,
21
22+ /* CS signal timings corresponding to GPMC_CONFIG2 */
23 .cs_on = 0,
24- .cs_rd_off = 23 * 10, /* Read deassertion time */
25- .cs_wr_off = 23 * 10, /* Write deassertion time */
26+ .cs_rd_off = 8 * 10, /* Read deassertion time */
27+ .cs_wr_off = 20 * 10, /* Write deassertion time */
28
29 /* ADV signal timings corresponding to GPMC_CONFIG3 */
30 .adv_on = 0, /* Assertion time */
31@@ -1906,17 +1907,17 @@ static struct gpmc_timings cssp_timings = {
32
33 /* WE signals timings corresponding to GPMC_CONFIG4 */
34 .we_on = 3 * 10, /* WE assertion time */
35- .we_off = 23 * 10, /* WE deassertion time */
36+ .we_off = 8 * 10, /* WE deassertion time */
37
38 /* OE signals timings corresponding to GPMC_CONFIG4 */
39 .oe_on = 3 * 10, /* OE assertion time */
40- .oe_off = 23 * 10, /* OE deassertion time */
41+ .oe_off = 8 * 10, /* OE deassertion time */
42
43 /* Access time and cycle time timings corresponding to GPMC_CONFIG5 */
44 .page_burst_access = 1 * 10, /* Multiple access word delay */
45 .access = 7 * 10, /* Start-cycle to first data valid delay */
46- .rd_cycle = 23 * 10, /* Total read cycle time */
47- .wr_cycle = 23 * 10, /* Total write cycle time */
48+ .rd_cycle = 8 * 10, /* Total read cycle time */
49+ .wr_cycle = 20 * 10, /* Total write cycle time */
50
51 /* The following are only on OMAP3430 */
52 .wr_access = 7 * 10, /* WRACCESSTIME */
53diff --git a/drivers/media/video/cssp_camera/cssp_camera.c b/drivers/media/video/cssp_camera/cssp_camera.c
54index 39aa003..34a36d7 100644
55--- a/drivers/media/video/cssp_camera/cssp_camera.c
56+++ b/drivers/media/video/cssp_camera/cssp_camera.c
57@@ -147,7 +147,6 @@ static int trigger_dma_transfer_to_buf(struct cssp_cam_dev *dev, struct vb2_buff
58 // Enable data capture
59 dev->mode |= ENABLE;
60 writew(dev->mode, dev->reg_base_virt + REG_MODE);
61- readw(dev->reg_base_virt + REG_MODE);
62
63 dev->current_vb = vb;
64
65@@ -182,7 +181,6 @@ static void dma_callback(unsigned lch, u16 ch_status, void *data)
66 // Disable data capture
67 dev->mode &= ~ENABLE;
68 writew(dev->mode, dev->reg_base_virt + REG_MODE);
69- readw(dev->reg_base_virt + REG_MODE);
70
71 if (ch_status == DMA_COMPLETE) {
72 struct vb2_buffer *vb = dev->current_vb;
73@@ -223,7 +221,7 @@ static int configure_edma(struct cssp_cam_dev *cam)
74 return -1;
75 }
76
77- cam->dma_ch = edma_alloc_channel(dma_channel, dma_callback, cam, EVENTQ_1);
78+ cam->dma_ch = edma_alloc_channel(dma_channel, dma_callback, cam, EVENTQ_0);
79 if (cam->dma_ch < 0) {
80 printk(KERN_ERR "[%s]: allocating channel for DMA failed\n", pdev->name);
81 return -EBUSY;
82@@ -526,7 +524,6 @@ static int stop_streaming(struct vb2_queue *vq)
83 // Disable data capture
84 dev->mode &= ~ENABLE;
85 writew(dev->mode, dev->reg_base_virt + REG_MODE);
86- readw(dev->reg_base_virt + REG_MODE);
87
88 stop_camera_sensor(dev);
89
90diff --git a/drivers/media/video/cssp_camera/cssp_camera.h b/drivers/media/video/cssp_camera/cssp_camera.h
91index d018ca1..8eb5f83 100644
92--- a/drivers/media/video/cssp_camera/cssp_camera.h
93+++ b/drivers/media/video/cssp_camera/cssp_camera.h
94@@ -28,7 +28,7 @@ static unsigned debug;
95 module_param(debug, uint, 0644);
96 MODULE_PARM_DESC(debug, "activates debug info");
97
98-static unsigned int vid_limit = 1;
99+static unsigned int vid_limit = 6;
100 module_param(vid_limit, uint, 0644);
101 MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes");
102
103--
1041.7.10
105
diff --git a/recipes-kernel/linux/linux-ti33x-psp-3.2/beaglebone/0077-beaglebone-disable-UYVY-VYUY-and-YVYU-modes-in-camer.patch b/recipes-kernel/linux/linux-ti33x-psp-3.2/beaglebone/0077-beaglebone-disable-UYVY-VYUY-and-YVYU-modes-in-camer.patch
new file mode 100644
index 00000000..cc824168
--- /dev/null
+++ b/recipes-kernel/linux/linux-ti33x-psp-3.2/beaglebone/0077-beaglebone-disable-UYVY-VYUY-and-YVYU-modes-in-camer.patch
@@ -0,0 +1,39 @@
1From 850bc72301ae8eae6e9d11a9ec4d64bc683410fe Mon Sep 17 00:00:00 2001
2From: Dan Aizenstros <daizenstros@quicklogic.com>
3Date: Wed, 11 Jul 2012 12:29:29 -0400
4Subject: [PATCH 77/79] beaglebone: disable UYVY, VYUY and YVYU modes in
5 camera_cssp.c
6
7Signed-off-by: Dan Aizenstros <daizenstros@quicklogic.com>
8Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
9---
10 drivers/media/video/cssp_camera/cssp_camera.c | 6 ++++++
11 1 file changed, 6 insertions(+)
12
13diff --git a/drivers/media/video/cssp_camera/cssp_camera.c b/drivers/media/video/cssp_camera/cssp_camera.c
14index 34a36d7..acd38ee 100644
15--- a/drivers/media/video/cssp_camera/cssp_camera.c
16+++ b/drivers/media/video/cssp_camera/cssp_camera.c
17@@ -60,6 +60,11 @@ static struct cssp_cam_fmt formats[] = {
18 .depth = 16,
19 .code = V4L2_MBUS_FMT_YUYV8_2X8,
20 },
21+/*
22+ * UYVY doesn't work properly. VYUY and YVYU are not tested.
23+ * So disable the UYVY, VYUY and YVYU modes for now
24+ */
25+#if 0
26 {
27 .name = "4:2:2, packed, UYVY",
28 .fourcc = V4L2_PIX_FMT_UYVY,
29@@ -78,6 +83,7 @@ static struct cssp_cam_fmt formats[] = {
30 .depth = 16,
31 .code = V4L2_MBUS_FMT_YVYU8_2X8,
32 },
33+#endif
34 {
35 .name = "RGB565 (LE)",
36 .fourcc = V4L2_PIX_FMT_RGB565,
37--
381.7.10
39
diff --git a/recipes-kernel/linux/linux-ti33x-psp-3.2/beaglebone/0078-beaglebone-error-handling-for-DMA-completion-in-cssp.patch b/recipes-kernel/linux/linux-ti33x-psp-3.2/beaglebone/0078-beaglebone-error-handling-for-DMA-completion-in-cssp.patch
new file mode 100644
index 00000000..cc678ba9
--- /dev/null
+++ b/recipes-kernel/linux/linux-ti33x-psp-3.2/beaglebone/0078-beaglebone-error-handling-for-DMA-completion-in-cssp.patch
@@ -0,0 +1,49 @@
1From 823d8b7b4a1dcfefc7260110a3acada0d1f45695 Mon Sep 17 00:00:00 2001
2From: Dan Aizenstros <daizenstros@quicklogic.com>
3Date: Thu, 12 Jul 2012 16:52:21 -0400
4Subject: [PATCH 78/79] beaglebone: error handling for DMA completion in
5 cssp_camera.c
6
7Signed-off-by: Dan Aizenstros <daizenstros@quicklogic.com>
8Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
9---
10 drivers/media/video/cssp_camera/cssp_camera.c | 16 +++++++++++++++-
11 1 file changed, 15 insertions(+), 1 deletion(-)
12
13diff --git a/drivers/media/video/cssp_camera/cssp_camera.c b/drivers/media/video/cssp_camera/cssp_camera.c
14index acd38ee..fca199b 100644
15--- a/drivers/media/video/cssp_camera/cssp_camera.c
16+++ b/drivers/media/video/cssp_camera/cssp_camera.c
17@@ -191,6 +191,21 @@ static void dma_callback(unsigned lch, u16 ch_status, void *data)
18 if (ch_status == DMA_COMPLETE) {
19 struct vb2_buffer *vb = dev->current_vb;
20 struct timeval ts;
21+ struct edmacc_param dma_tr_params;
22+
23+ edma_read_slot(dev->dma_ch, &dma_tr_params);
24+ if ((dma_tr_params.opt != 0) ||
25+ (dma_tr_params.src != 0) ||
26+ (dma_tr_params.a_b_cnt != 0) ||
27+ (dma_tr_params.dst != 0) ||
28+ (dma_tr_params.src_dst_bidx != 0) ||
29+ (dma_tr_params.link_bcntrld != 0xffff) ||
30+ (dma_tr_params.src_dst_cidx != 0) ||
31+ (dma_tr_params.ccnt != 0)) {
32+
33+ trigger_dma_transfer_to_buf(dev, dev->current_vb);
34+ return;
35+ }
36
37 vb->v4l2_buf.field = dev->field;
38 dev->field_count++;
39@@ -204,7 +219,6 @@ static void dma_callback(unsigned lch, u16 ch_status, void *data)
40 /* check if we have new buffer queued */
41 dequeue_buffer_for_dma(dev);
42 } else {
43- printk(KERN_ERR "[cssp_camera]: EDMA error (ch_status = %d)\n", ch_status);
44 /* we got a missed interrupt so just start a new DMA with the existing buffer */
45 if (dev->current_vb != NULL)
46 trigger_dma_transfer_to_buf(dev, dev->current_vb);
47--
481.7.10
49
diff --git a/recipes-kernel/linux/linux-ti33x-psp-3.2/beaglebone/0079-AM335X-errata-OPP50-on-MPU-domain-is-not-supported.patch b/recipes-kernel/linux/linux-ti33x-psp-3.2/beaglebone/0079-AM335X-errata-OPP50-on-MPU-domain-is-not-supported.patch
new file mode 100644
index 00000000..c50abbf6
--- /dev/null
+++ b/recipes-kernel/linux/linux-ti33x-psp-3.2/beaglebone/0079-AM335X-errata-OPP50-on-MPU-domain-is-not-supported.patch
@@ -0,0 +1,52 @@
1From 662134c1007cc275193737dd11ea4b77f47256a7 Mon Sep 17 00:00:00 2001
2From: AnilKumar Ch <anilkumar@ti.com>
3Date: Tue, 26 Jun 2012 15:41:51 +0530
4Subject: [PATCH 79/79] AM335X: errata: OPP50 on MPU domain is not supported
5
6This patch implements a workaround for OPP50 erratum, Advisory
71.0.15 at http://www.ti.com/lit/er/sprz360b/sprz360b.pdf
8
9OPP50 Operation on MPU Domain is Not Supported. This issue seen with
10reliability tests running on MPU. To minimize power consumption, the
11ARM Cortex-A8 may be operated at the lower frequency defined by OPP50,
12but the respective power terminal VDD_MPU must be operated as defined
13by OPP100. So MPU OPP50 modified to <275MHz, 1.1V>.
14
15Power consumption as seen on AM335x EVM:
16OPP50 <275MHz, 0.95> - 40.5 mW
17OPP50 <275MHz, 1.10> - 55.5 mW
18OPP100 <500MHz, 1.10> - 98.5 mW
19
20Based on the above data we can see 43mW power savings compared to
21OPP100. This is the reason for keeping OPP50 alive instead of
22shutting down completely.
23
24Signed-off-by: AnilKumar Ch <anilkumar@ti.com>
25---
26 arch/arm/mach-omap2/opp3xxx_data.c | 10 +++++++++-
27 1 file changed, 9 insertions(+), 1 deletion(-)
28
29diff --git a/arch/arm/mach-omap2/opp3xxx_data.c b/arch/arm/mach-omap2/opp3xxx_data.c
30index 0e540c8..9fbcfc3 100644
31--- a/arch/arm/mach-omap2/opp3xxx_data.c
32+++ b/arch/arm/mach-omap2/opp3xxx_data.c
33@@ -154,7 +154,15 @@ static struct omap_opp_def __initdata omap36xx_opp_def_list[] = {
34
35 /* VDD1 */
36
37-#define AM33XX_VDD_MPU_OPP50_UV 950000
38+/*
39+ * Errata 1.0.15: OPP50 Operation on MPU Domain is Not Supported.
40+ *
41+ * To minimize power consumption, the ARM Cortex-A8 may be operated at
42+ * the lower frequency defined by OPP50, but the respective voltage
43+ * domain VDD_MPU must be operated as defined by OPP100. So MPU OPP50
44+ * definition is modified to 275MHz, 1.1V.
45+ */
46+#define AM33XX_VDD_MPU_OPP50_UV 1100000
47 #define AM33XX_VDD_MPU_OPP100_UV 1100000
48 #define AM33XX_VDD_MPU_OPP120_UV 1200000
49 #define AM33XX_VDD_MPU_OPPTURBO_UV 1260000
50--
511.7.10
52
diff --git a/recipes-kernel/linux/linux-ti33x-psp_3.2.bb b/recipes-kernel/linux/linux-ti33x-psp_3.2.bb
index 01bfc233..083f36a3 100644
--- a/recipes-kernel/linux/linux-ti33x-psp_3.2.bb
+++ b/recipes-kernel/linux/linux-ti33x-psp_3.2.bb
@@ -15,7 +15,7 @@ PV = "${@base_contains('DISTRO_FEATURES', 'tipspkernel', "3.2", "3.2.21", d)}"
15 15
16BRANCH = "v3.2-staging" 16BRANCH = "v3.2-staging"
17SRCREV = "720e07b4c1f687b61b147b31c698cb6816d72f01" 17SRCREV = "720e07b4c1f687b61b147b31c698cb6816d72f01"
18MACHINE_KERNEL_PR_append = "f+gitr${SRCREV}" 18MACHINE_KERNEL_PR_append = "g+gitr${SRCREV}"
19 19
20COMPATIBLE_MACHINE = "(ti33x)" 20COMPATIBLE_MACHINE = "(ti33x)"
21 21
@@ -1530,7 +1530,6 @@ PATCHES_OVER_PSP = " \
1530 file://beaglebone/0063-beaglebone-dvi-cape-audio-hacks.patch \ 1530 file://beaglebone/0063-beaglebone-dvi-cape-audio-hacks.patch \
1531 file://beaglebone/0064-beaglebone-always-execute-the-pin-free-checks.patch \ 1531 file://beaglebone/0064-beaglebone-always-execute-the-pin-free-checks.patch \
1532 file://beaglebone/0065-ti_tscadc-switch-to-16x-averaging.patch \ 1532 file://beaglebone/0065-ti_tscadc-switch-to-16x-averaging.patch \
1533 file://beaglebone/0066-beaglebone-disable-OPP-for-275MHz-due-to-silicon-err.patch \
1534 file://beaglebone/0067-video-da8xx-fb-Add-Newhaven-LCD-Panel-details.patch \ 1533 file://beaglebone/0067-video-da8xx-fb-Add-Newhaven-LCD-Panel-details.patch \
1535 file://beaglebone/0068-beaglebone-add-support-for-the-4.3-lcd-cape-with-res.patch \ 1534 file://beaglebone/0068-beaglebone-add-support-for-the-4.3-lcd-cape-with-res.patch \
1536 file://beaglebone/0069-beaglebone-add-support-for-LCD3-rev-A1.patch \ 1535 file://beaglebone/0069-beaglebone-add-support-for-LCD3-rev-A1.patch \
@@ -1540,4 +1539,9 @@ PATCHES_OVER_PSP = " \
1540 file://beaglebone/0073-beaglebone-add-support-for-QuickLogic-Camera-interfa.patch \ 1539 file://beaglebone/0073-beaglebone-add-support-for-QuickLogic-Camera-interfa.patch \
1541 file://beaglebone/0074-beaglebone-add-support-for-DVI-audio-and-audio-only-.patch \ 1540 file://beaglebone/0074-beaglebone-add-support-for-DVI-audio-and-audio-only-.patch \
1542 file://beaglebone/0075-beaglebone-disable-LBO-GPIO-for-battery-cape.patch \ 1541 file://beaglebone/0075-beaglebone-disable-LBO-GPIO-for-battery-cape.patch \
1542 file://beaglebone/0075-video-da8xx-fb-calculate-pixel-clock-period-for-the-.patch \
1543 file://beaglebone/0076-beaglebone-improve-GPMC-bus-timings-for-camera-cape.patch \
1544 file://beaglebone/0077-beaglebone-disable-UYVY-VYUY-and-YVYU-modes-in-camer.patch \
1545 file://beaglebone/0078-beaglebone-error-handling-for-DMA-completion-in-cssp.patch \
1546 file://beaglebone/0079-AM335X-errata-OPP50-on-MPU-domain-is-not-supported.patch \
1543" 1547"