aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video')
-rw-r--r--drivers/media/video/Kconfig297
-rw-r--r--drivers/media/video/Makefile66
-rw-r--r--drivers/media/video/arv.c885
-rw-r--r--drivers/media/video/atmel-isi.c1099
-rw-r--r--drivers/media/video/blackfin/Kconfig10
-rw-r--r--drivers/media/video/blackfin/Makefile2
-rw-r--r--drivers/media/video/blackfin/bfin_capture.c1068
-rw-r--r--drivers/media/video/blackfin/ppi.c271
-rw-r--r--drivers/media/video/coda.c1849
-rw-r--r--drivers/media/video/coda.h216
-rw-r--r--drivers/media/video/davinci/Kconfig121
-rw-r--r--drivers/media/video/davinci/Makefile20
-rw-r--r--drivers/media/video/davinci/ccdc_hw_device.h110
-rw-r--r--drivers/media/video/davinci/dm355_ccdc.c1072
-rw-r--r--drivers/media/video/davinci/dm355_ccdc_regs.h310
-rw-r--r--drivers/media/video/davinci/dm644x_ccdc.c1081
-rw-r--r--drivers/media/video/davinci/dm644x_ccdc_regs.h153
-rw-r--r--drivers/media/video/davinci/isif.c1162
-rw-r--r--drivers/media/video/davinci/isif_regs.h269
-rw-r--r--drivers/media/video/davinci/vpbe.c886
-rw-r--r--drivers/media/video/davinci/vpbe_display.c1838
-rw-r--r--drivers/media/video/davinci/vpbe_osd.c1605
-rw-r--r--drivers/media/video/davinci/vpbe_osd_regs.h364
-rw-r--r--drivers/media/video/davinci/vpbe_venc.c706
-rw-r--r--drivers/media/video/davinci/vpbe_venc_regs.h177
-rw-r--r--drivers/media/video/davinci/vpfe_capture.c2079
-rw-r--r--drivers/media/video/davinci/vpif.c514
-rw-r--r--drivers/media/video/davinci/vpif.h688
-rw-r--r--drivers/media/video/davinci/vpif_capture.c2456
-rw-r--r--drivers/media/video/davinci/vpif_capture.h170
-rw-r--r--drivers/media/video/davinci/vpif_display.c2010
-rw-r--r--drivers/media/video/davinci/vpif_display.h181
-rw-r--r--drivers/media/video/davinci/vpss.c482
-rw-r--r--drivers/media/video/fsl-viu.c1690
-rw-r--r--drivers/media/video/indycam.c390
-rw-r--r--drivers/media/video/indycam.h93
-rw-r--r--drivers/media/video/m2m-deinterlace.c1120
-rw-r--r--drivers/media/video/marvell-ccic/Kconfig23
-rw-r--r--drivers/media/video/marvell-ccic/Makefile6
-rw-r--r--drivers/media/video/marvell-ccic/cafe-driver.c654
-rw-r--r--drivers/media/video/marvell-ccic/mcam-core.c1878
-rw-r--r--drivers/media/video/marvell-ccic/mcam-core.h322
-rw-r--r--drivers/media/video/marvell-ccic/mmp-driver.c380
-rw-r--r--drivers/media/video/mem2mem_testdev.c1131
-rw-r--r--drivers/media/video/mx1_camera.c889
-rw-r--r--drivers/media/video/mx2_camera.c1869
-rw-r--r--drivers/media/video/mx2_emmaprp.c1037
-rw-r--r--drivers/media/video/mx3_camera.c1300
-rw-r--r--drivers/media/video/omap/Kconfig14
-rw-r--r--drivers/media/video/omap/Makefile8
-rw-r--r--drivers/media/video/omap/omap_vout.c2289
-rw-r--r--drivers/media/video/omap/omap_vout_vrfb.c390
-rw-r--r--drivers/media/video/omap/omap_vout_vrfb.h40
-rw-r--r--drivers/media/video/omap/omap_voutdef.h225
-rw-r--r--drivers/media/video/omap/omap_voutlib.c339
-rw-r--r--drivers/media/video/omap/omap_voutlib.h36
-rw-r--r--drivers/media/video/omap1_camera.c1723
-rw-r--r--drivers/media/video/omap24xxcam-dma.c601
-rw-r--r--drivers/media/video/omap24xxcam.c1881
-rw-r--r--drivers/media/video/omap24xxcam.h593
-rw-r--r--drivers/media/video/omap3isp/Makefile11
-rw-r--r--drivers/media/video/omap3isp/cfa_coef_table.h61
-rw-r--r--drivers/media/video/omap3isp/gamma_table.h90
-rw-r--r--drivers/media/video/omap3isp/isp.c2241
-rw-r--r--drivers/media/video/omap3isp/isp.h352
-rw-r--r--drivers/media/video/omap3isp/ispccdc.c2583
-rw-r--r--drivers/media/video/omap3isp/ispccdc.h172
-rw-r--r--drivers/media/video/omap3isp/ispccp2.c1171
-rw-r--r--drivers/media/video/omap3isp/ispccp2.h98
-rw-r--r--drivers/media/video/omap3isp/ispcsi2.c1328
-rw-r--r--drivers/media/video/omap3isp/ispcsi2.h165
-rw-r--r--drivers/media/video/omap3isp/ispcsiphy.c249
-rw-r--r--drivers/media/video/omap3isp/ispcsiphy.h63
-rw-r--r--drivers/media/video/omap3isp/isph3a.h117
-rw-r--r--drivers/media/video/omap3isp/isph3a_aewb.c368
-rw-r--r--drivers/media/video/omap3isp/isph3a_af.c423
-rw-r--r--drivers/media/video/omap3isp/isphist.c518
-rw-r--r--drivers/media/video/omap3isp/isphist.h40
-rw-r--r--drivers/media/video/omap3isp/isppreview.c2348
-rw-r--r--drivers/media/video/omap3isp/isppreview.h174
-rw-r--r--drivers/media/video/omap3isp/ispqueue.c1158
-rw-r--r--drivers/media/video/omap3isp/ispqueue.h187
-rw-r--r--drivers/media/video/omap3isp/ispreg.h1586
-rw-r--r--drivers/media/video/omap3isp/ispresizer.c1778
-rw-r--r--drivers/media/video/omap3isp/ispresizer.h146
-rw-r--r--drivers/media/video/omap3isp/ispstat.c1102
-rw-r--r--drivers/media/video/omap3isp/ispstat.h169
-rw-r--r--drivers/media/video/omap3isp/ispvideo.c1403
-rw-r--r--drivers/media/video/omap3isp/ispvideo.h216
-rw-r--r--drivers/media/video/omap3isp/luma_enhance_table.h42
-rw-r--r--drivers/media/video/omap3isp/noise_filter_table.h30
-rw-r--r--drivers/media/video/pxa_camera.c1852
-rw-r--r--drivers/media/video/s5p-fimc/Kconfig48
-rw-r--r--drivers/media/video/s5p-fimc/Makefile7
-rw-r--r--drivers/media/video/s5p-fimc/fimc-capture.c1738
-rw-r--r--drivers/media/video/s5p-fimc/fimc-core.c1239
-rw-r--r--drivers/media/video/s5p-fimc/fimc-core.h713
-rw-r--r--drivers/media/video/s5p-fimc/fimc-lite-reg.c300
-rw-r--r--drivers/media/video/s5p-fimc/fimc-lite-reg.h150
-rw-r--r--drivers/media/video/s5p-fimc/fimc-lite.c1606
-rw-r--r--drivers/media/video/s5p-fimc/fimc-lite.h213
-rw-r--r--drivers/media/video/s5p-fimc/fimc-m2m.c854
-rw-r--r--drivers/media/video/s5p-fimc/fimc-mdevice.c1037
-rw-r--r--drivers/media/video/s5p-fimc/fimc-mdevice.h120
-rw-r--r--drivers/media/video/s5p-fimc/fimc-reg.c775
-rw-r--r--drivers/media/video/s5p-fimc/fimc-reg.h326
-rw-r--r--drivers/media/video/s5p-fimc/mipi-csis.c722
-rw-r--r--drivers/media/video/s5p-fimc/mipi-csis.h25
-rw-r--r--drivers/media/video/s5p-g2d/Makefile3
-rw-r--r--drivers/media/video/s5p-g2d/g2d-hw.c109
-rw-r--r--drivers/media/video/s5p-g2d/g2d-regs.h115
-rw-r--r--drivers/media/video/s5p-g2d/g2d.c847
-rw-r--r--drivers/media/video/s5p-g2d/g2d.h86
-rw-r--r--drivers/media/video/s5p-jpeg/Makefile2
-rw-r--r--drivers/media/video/s5p-jpeg/jpeg-core.c1529
-rw-r--r--drivers/media/video/s5p-jpeg/jpeg-core.h150
-rw-r--r--drivers/media/video/s5p-jpeg/jpeg-hw.h357
-rw-r--r--drivers/media/video/s5p-jpeg/jpeg-regs.h170
-rw-r--r--drivers/media/video/s5p-mfc/Makefile5
-rw-r--r--drivers/media/video/s5p-mfc/regs-mfc.h418
-rw-r--r--drivers/media/video/s5p-mfc/s5p_mfc.c1230
-rw-r--r--drivers/media/video/s5p-mfc/s5p_mfc_cmd.c120
-rw-r--r--drivers/media/video/s5p-mfc/s5p_mfc_cmd.h30
-rw-r--r--drivers/media/video/s5p-mfc/s5p_mfc_common.h570
-rw-r--r--drivers/media/video/s5p-mfc/s5p_mfc_ctrl.c343
-rw-r--r--drivers/media/video/s5p-mfc/s5p_mfc_ctrl.h29
-rw-r--r--drivers/media/video/s5p-mfc/s5p_mfc_debug.h48
-rw-r--r--drivers/media/video/s5p-mfc/s5p_mfc_dec.c1044
-rw-r--r--drivers/media/video/s5p-mfc/s5p_mfc_dec.h23
-rw-r--r--drivers/media/video/s5p-mfc/s5p_mfc_enc.c1834
-rw-r--r--drivers/media/video/s5p-mfc/s5p_mfc_enc.h23
-rw-r--r--drivers/media/video/s5p-mfc/s5p_mfc_intr.c92
-rw-r--r--drivers/media/video/s5p-mfc/s5p_mfc_intr.h26
-rw-r--r--drivers/media/video/s5p-mfc/s5p_mfc_opr.c1397
-rw-r--r--drivers/media/video/s5p-mfc/s5p_mfc_opr.h93
-rw-r--r--drivers/media/video/s5p-mfc/s5p_mfc_pm.c137
-rw-r--r--drivers/media/video/s5p-mfc/s5p_mfc_pm.h24
-rw-r--r--drivers/media/video/s5p-mfc/s5p_mfc_shm.c47
-rw-r--r--drivers/media/video/s5p-mfc/s5p_mfc_shm.h90
-rw-r--r--drivers/media/video/s5p-tv/Kconfig86
-rw-r--r--drivers/media/video/s5p-tv/Makefile19
-rw-r--r--drivers/media/video/s5p-tv/hdmi_drv.c1007
-rw-r--r--drivers/media/video/s5p-tv/hdmiphy_drv.c329
-rw-r--r--drivers/media/video/s5p-tv/mixer.h365
-rw-r--r--drivers/media/video/s5p-tv/mixer_drv.c487
-rw-r--r--drivers/media/video/s5p-tv/mixer_grp_layer.c270
-rw-r--r--drivers/media/video/s5p-tv/mixer_reg.c553
-rw-r--r--drivers/media/video/s5p-tv/mixer_video.c1125
-rw-r--r--drivers/media/video/s5p-tv/mixer_vp_layer.c241
-rw-r--r--drivers/media/video/s5p-tv/regs-hdmi.h146
-rw-r--r--drivers/media/video/s5p-tv/regs-mixer.h122
-rw-r--r--drivers/media/video/s5p-tv/regs-sdo.h63
-rw-r--r--drivers/media/video/s5p-tv/regs-vp.h88
-rw-r--r--drivers/media/video/s5p-tv/sdo_drv.c452
-rw-r--r--drivers/media/video/s5p-tv/sii9234_drv.c422
-rw-r--r--drivers/media/video/sh_mobile_ceu_camera.c2331
-rw-r--r--drivers/media/video/sh_vou.c1510
-rw-r--r--drivers/media/video/soc_camera_platform.c197
-rw-r--r--drivers/media/video/soc_mediabus.c487
-rw-r--r--drivers/media/video/timblogiw.c880
-rw-r--r--drivers/media/video/via-camera.c1514
-rw-r--r--drivers/media/video/via-camera.h93
-rw-r--r--drivers/media/video/vino.c4349
-rw-r--r--drivers/media/video/vino.h138
-rw-r--r--drivers/media/video/vivi.c1409
165 files changed, 0 insertions, 106926 deletions
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
deleted file mode 100644
index 28b25bf35805..000000000000
--- a/drivers/media/video/Kconfig
+++ /dev/null
@@ -1,297 +0,0 @@
1if MEDIA_CAMERA_SUPPORT
2
3config VIDEO_VIVI
4 tristate "Virtual Video Driver"
5 depends on VIDEO_DEV && VIDEO_V4L2 && !SPARC32 && !SPARC64
6 depends on FRAMEBUFFER_CONSOLE || STI_CONSOLE
7 select FONT_8x16
8 select VIDEOBUF2_VMALLOC
9 default n
10 ---help---
11 Enables a virtual video driver. This device shows a color bar
12 and a timestamp, as a real device would generate by using V4L2
13 api.
14 Say Y here if you want to test video apps or debug V4L devices.
15 In doubt, say N.
16
17#
18# Platform drivers
19# All drivers here are currently for webcam support
20
21menuconfig V4L_PLATFORM_DRIVERS
22 bool "V4L platform devices"
23 depends on MEDIA_CAMERA_SUPPORT
24 default n
25 ---help---
26 Say Y here to enable support for platform-specific V4L drivers.
27
28if V4L_PLATFORM_DRIVERS
29
30source "drivers/media/video/marvell-ccic/Kconfig"
31
32config VIDEO_VIA_CAMERA
33 tristate "VIAFB camera controller support"
34 depends on FB_VIA
35 select VIDEOBUF_DMA_SG
36 select VIDEO_OV7670
37 help
38 Driver support for the integrated camera controller in VIA
39 Chrome9 chipsets. Currently only tested on OLPC xo-1.5 systems
40 with ov7670 sensors.
41
42#
43# Platform multimedia device configuration
44#
45
46source "drivers/media/video/davinci/Kconfig"
47
48source "drivers/media/video/omap/Kconfig"
49
50source "drivers/media/video/blackfin/Kconfig"
51
52config VIDEO_SH_VOU
53 tristate "SuperH VOU video output driver"
54 depends on VIDEO_DEV && ARCH_SHMOBILE
55 select VIDEOBUF_DMA_CONTIG
56 help
57 Support for the Video Output Unit (VOU) on SuperH SoCs.
58
59config VIDEO_VIU
60 tristate "Freescale VIU Video Driver"
61 depends on VIDEO_V4L2 && PPC_MPC512x
62 select VIDEOBUF_DMA_CONTIG
63 default y
64 ---help---
65 Support for Freescale VIU video driver. This device captures
66 video data, or overlays video on DIU frame buffer.
67
68 Say Y here if you want to enable VIU device on MPC5121e Rev2+.
69 In doubt, say N.
70
71config VIDEO_TIMBERDALE
72 tristate "Support for timberdale Video In/LogiWIN"
73 depends on VIDEO_V4L2 && I2C && DMADEVICES
74 select DMA_ENGINE
75 select TIMB_DMA
76 select VIDEO_ADV7180
77 select VIDEOBUF_DMA_CONTIG
78 ---help---
79 Add support for the Video In peripherial of the timberdale FPGA.
80
81config VIDEO_VINO
82 tristate "SGI Vino Video For Linux"
83 depends on I2C && SGI_IP22 && VIDEO_V4L2
84 select VIDEO_SAA7191 if VIDEO_HELPER_CHIPS_AUTO
85 help
86 Say Y here to build in support for the Vino video input system found
87 on SGI Indy machines.
88
89config VIDEO_M32R_AR
90 tristate "AR devices"
91 depends on M32R && VIDEO_V4L2
92 ---help---
93 This is a video4linux driver for the Renesas AR (Artificial Retina)
94 camera module.
95
96config VIDEO_M32R_AR_M64278
97 tristate "AR device with color module M64278(VGA)"
98 depends on PLAT_M32700UT
99 select VIDEO_M32R_AR
100 ---help---
101 This is a video4linux driver for the Renesas AR (Artificial
102 Retina) with M64278E-800 camera module.
103 This module supports VGA(640x480 pixels) resolutions.
104
105 To compile this driver as a module, choose M here: the
106 module will be called arv.
107
108config VIDEO_OMAP3
109 tristate "OMAP 3 Camera support (EXPERIMENTAL)"
110 depends on OMAP_IOVMM && VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API && ARCH_OMAP3 && EXPERIMENTAL
111 ---help---
112 Driver for an OMAP 3 camera controller.
113
114config VIDEO_OMAP3_DEBUG
115 bool "OMAP 3 Camera debug messages"
116 depends on VIDEO_OMAP3
117 ---help---
118 Enable debug messages on OMAP 3 camera controller driver.
119
120config SOC_CAMERA
121 tristate "SoC camera support"
122 depends on VIDEO_V4L2 && HAS_DMA && I2C
123 select VIDEOBUF_GEN
124 select VIDEOBUF2_CORE
125 help
126 SoC Camera is a common API to several cameras, not connecting
127 over a bus like PCI or USB. For example some i2c camera connected
128 directly to the data bus of an SoC.
129
130
131config SOC_CAMERA_PLATFORM
132 tristate "platform camera support"
133 depends on SOC_CAMERA
134 help
135 This is a generic SoC camera platform driver, useful for testing
136
137config MX1_VIDEO
138 bool
139
140config VIDEO_MX1
141 tristate "i.MX1/i.MXL CMOS Sensor Interface driver"
142 depends on VIDEO_DEV && ARCH_MX1 && SOC_CAMERA
143 select FIQ
144 select VIDEOBUF_DMA_CONTIG
145 select MX1_VIDEO
146 ---help---
147 This is a v4l2 driver for the i.MX1/i.MXL CMOS Sensor Interface
148
149config MX3_VIDEO
150 bool
151
152config VIDEO_MX3
153 tristate "i.MX3x Camera Sensor Interface driver"
154 depends on VIDEO_DEV && MX3_IPU && SOC_CAMERA
155 select VIDEOBUF2_DMA_CONTIG
156 select MX3_VIDEO
157 ---help---
158 This is a v4l2 driver for the i.MX3x Camera Sensor Interface
159
160config VIDEO_PXA27x
161 tristate "PXA27x Quick Capture Interface driver"
162 depends on VIDEO_DEV && PXA27x && SOC_CAMERA
163 select VIDEOBUF_DMA_SG
164 ---help---
165 This is a v4l2 driver for the PXA27x Quick Capture Interface
166
167config VIDEO_SH_MOBILE_CSI2
168 tristate "SuperH Mobile MIPI CSI-2 Interface driver"
169 depends on VIDEO_DEV && SOC_CAMERA && HAVE_CLK
170 ---help---
171 This is a v4l2 driver for the SuperH MIPI CSI-2 Interface
172
173config VIDEO_SH_MOBILE_CEU
174 tristate "SuperH Mobile CEU Interface driver"
175 depends on VIDEO_DEV && SOC_CAMERA && HAS_DMA && HAVE_CLK
176 select VIDEOBUF2_DMA_CONTIG
177 ---help---
178 This is a v4l2 driver for the SuperH Mobile CEU Interface
179
180config VIDEO_OMAP1
181 tristate "OMAP1 Camera Interface driver"
182 depends on VIDEO_DEV && ARCH_OMAP1 && SOC_CAMERA
183 select VIDEOBUF_DMA_CONTIG
184 select VIDEOBUF_DMA_SG
185 ---help---
186 This is a v4l2 driver for the TI OMAP1 camera interface
187
188config VIDEO_OMAP2
189 tristate "OMAP2 Camera Capture Interface driver"
190 depends on VIDEO_DEV && ARCH_OMAP2
191 select VIDEOBUF_DMA_SG
192 ---help---
193 This is a v4l2 driver for the TI OMAP2 camera capture interface
194
195config VIDEO_MX2_HOSTSUPPORT
196 bool
197
198config VIDEO_MX2
199 tristate "i.MX27/i.MX25 Camera Sensor Interface driver"
200 depends on VIDEO_DEV && SOC_CAMERA && (MACH_MX27 || (ARCH_MX25 && BROKEN))
201 select VIDEOBUF2_DMA_CONTIG
202 select VIDEO_MX2_HOSTSUPPORT
203 ---help---
204 This is a v4l2 driver for the i.MX27 and the i.MX25 Camera Sensor
205 Interface
206
207config VIDEO_ATMEL_ISI
208 tristate "ATMEL Image Sensor Interface (ISI) support"
209 depends on VIDEO_DEV && SOC_CAMERA && ARCH_AT91
210 select VIDEOBUF2_DMA_CONTIG
211 ---help---
212 This module makes the ATMEL Image Sensor Interface available
213 as a v4l2 device.
214
215source "drivers/media/video/s5p-fimc/Kconfig"
216source "drivers/media/video/s5p-tv/Kconfig"
217
218endif # V4L_PLATFORM_DRIVERS
219
220menuconfig V4L_MEM2MEM_DRIVERS
221 bool "Memory-to-memory multimedia devices"
222 depends on VIDEO_V4L2
223 default n
224 ---help---
225 Say Y here to enable selecting drivers for V4L devices that
226 use system memory for both source and destination buffers, as opposed
227 to capture and output drivers, which use memory buffers for just
228 one of those.
229
230if V4L_MEM2MEM_DRIVERS
231
232config VIDEO_MEM2MEM_TESTDEV
233 tristate "Virtual test device for mem2mem framework"
234 depends on VIDEO_DEV && VIDEO_V4L2
235 select VIDEOBUF2_VMALLOC
236 select V4L2_MEM2MEM_DEV
237 default n
238 ---help---
239 This is a virtual test device for the memory-to-memory driver
240 framework.
241
242config VIDEO_CODA
243 tristate "Chips&Media Coda multi-standard codec IP"
244 depends on VIDEO_DEV && VIDEO_V4L2
245 select VIDEOBUF2_DMA_CONTIG
246 select V4L2_MEM2MEM_DEV
247 ---help---
248 Coda is a range of video codec IPs that supports
249 H.264, MPEG-4, and other video formats.
250
251config VIDEO_MEM2MEM_DEINTERLACE
252 tristate "Deinterlace support"
253 depends on VIDEO_DEV && VIDEO_V4L2 && DMA_ENGINE
254 select VIDEOBUF2_DMA_CONTIG
255 select V4L2_MEM2MEM_DEV
256 help
257 Generic deinterlacing V4L2 driver.
258
259config VIDEO_SAMSUNG_S5P_G2D
260 tristate "Samsung S5P and EXYNOS4 G2D 2d graphics accelerator driver"
261 depends on VIDEO_DEV && VIDEO_V4L2 && PLAT_S5P
262 select VIDEOBUF2_DMA_CONTIG
263 select V4L2_MEM2MEM_DEV
264 default n
265 ---help---
266 This is a v4l2 driver for Samsung S5P and EXYNOS4 G2D
267 2d graphics accelerator.
268
269config VIDEO_SAMSUNG_S5P_JPEG
270 tristate "Samsung S5P/Exynos4 JPEG codec driver (EXPERIMENTAL)"
271 depends on VIDEO_DEV && VIDEO_V4L2 && PLAT_S5P && EXPERIMENTAL
272 select VIDEOBUF2_DMA_CONTIG
273 select V4L2_MEM2MEM_DEV
274 ---help---
275 This is a v4l2 driver for Samsung S5P and EXYNOS4 JPEG codec
276
277config VIDEO_SAMSUNG_S5P_MFC
278 tristate "Samsung S5P MFC 5.1 Video Codec"
279 depends on VIDEO_DEV && VIDEO_V4L2 && PLAT_S5P
280 select VIDEOBUF2_DMA_CONTIG
281 default n
282 help
283 MFC 5.1 driver for V4L2.
284
285config VIDEO_MX2_EMMAPRP
286 tristate "MX2 eMMa-PrP support"
287 depends on VIDEO_DEV && VIDEO_V4L2 && SOC_IMX27
288 select VIDEOBUF2_DMA_CONTIG
289 select V4L2_MEM2MEM_DEV
290 help
291 MX2X chips have a PrP that can be used to process buffers from
292 memory to memory. Operations include resizing and format
293 conversion.
294
295endif # V4L_MEM2MEM_DRIVERS
296
297endif # MEDIA_CAMERA_SUPPORT
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
deleted file mode 100644
index b3effdc65f76..000000000000
--- a/drivers/media/video/Makefile
+++ /dev/null
@@ -1,66 +0,0 @@
1#
2# Makefile for the video capture/playback device drivers.
3#
4
5omap2cam-objs := omap24xxcam.o omap24xxcam-dma.o
6
7obj-$(CONFIG_VIDEO_VINO) += indycam.o
8
9obj-$(CONFIG_VIDEO_VINO) += vino.o
10obj-$(CONFIG_VIDEO_TIMBERDALE) += timblogiw.o
11
12
13obj-$(CONFIG_VIDEO_M32R_AR_M64278) += arv.o
14
15
16obj-$(CONFIG_VIDEO_CAFE_CCIC) += marvell-ccic/
17obj-$(CONFIG_VIDEO_MMP_CAMERA) += marvell-ccic/
18
19obj-$(CONFIG_VIDEO_VIA_CAMERA) += via-camera.o
20
21obj-$(CONFIG_VIDEO_OMAP3) += omap3isp/
22
23obj-$(CONFIG_VIDEO_VIU) += fsl-viu.o
24obj-$(CONFIG_VIDEO_VIVI) += vivi.o
25obj-$(CONFIG_VIDEO_MEM2MEM_TESTDEV) += mem2mem_testdev.o
26
27
28obj-$(CONFIG_VIDEO_OMAP2) += omap2cam.o
29obj-$(CONFIG_SOC_CAMERA) += soc_camera.o soc_mediabus.o
30obj-$(CONFIG_SOC_CAMERA_PLATFORM) += soc_camera_platform.o
31# soc-camera host drivers have to be linked after camera drivers
32obj-$(CONFIG_VIDEO_MX1) += mx1_camera.o
33obj-$(CONFIG_VIDEO_MX2) += mx2_camera.o
34obj-$(CONFIG_VIDEO_MX3) += mx3_camera.o
35obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o
36obj-$(CONFIG_VIDEO_SH_MOBILE_CSI2) += sh_mobile_csi2.o
37obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o
38obj-$(CONFIG_VIDEO_OMAP1) += omap1_camera.o
39obj-$(CONFIG_VIDEO_ATMEL_ISI) += atmel-isi.o
40
41obj-$(CONFIG_VIDEO_MX2_EMMAPRP) += mx2_emmaprp.o
42obj-$(CONFIG_VIDEO_CODA) += coda.o
43
44obj-$(CONFIG_VIDEO_MEM2MEM_DEINTERLACE) += m2m-deinterlace.o
45
46obj-$(CONFIG_VIDEO_SAMSUNG_S5P_FIMC) += s5p-fimc/
47obj-$(CONFIG_VIDEO_SAMSUNG_S5P_JPEG) += s5p-jpeg/
48obj-$(CONFIG_VIDEO_SAMSUNG_S5P_MFC) += s5p-mfc/
49obj-$(CONFIG_VIDEO_SAMSUNG_S5P_TV) += s5p-tv/
50
51obj-$(CONFIG_VIDEO_SAMSUNG_S5P_G2D) += s5p-g2d/
52
53obj-$(CONFIG_BLACKFIN) += blackfin/
54
55obj-$(CONFIG_ARCH_DAVINCI) += davinci/
56
57obj-$(CONFIG_VIDEO_SH_VOU) += sh_vou.o
58
59obj-y += davinci/
60
61obj-$(CONFIG_ARCH_OMAP) += omap/
62
63ccflags-y += -I$(srctree)/drivers/media/dvb-core
64ccflags-y += -I$(srctree)/drivers/media/dvb-frontends
65ccflags-y += -I$(srctree)/drivers/media/tuners
66ccflags-y += -I$(srctree)/drivers/media/i2c/soc_camera
diff --git a/drivers/media/video/arv.c b/drivers/media/video/arv.c
deleted file mode 100644
index e346d32d08ce..000000000000
--- a/drivers/media/video/arv.c
+++ /dev/null
@@ -1,885 +0,0 @@
1/*
2 * Colour AR M64278(VGA) driver for Video4Linux
3 *
4 * Copyright (C) 2003 Takeo Takahashi <takahashi.takeo@renesas.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 *
11 * Some code is taken from AR driver sample program for M3T-M32700UT.
12 *
13 * AR driver sample (M32R SDK):
14 * Copyright (c) 2003 RENESAS TECHNOROGY CORPORATION
15 * AND RENESAS SOLUTIONS CORPORATION
16 * All Rights Reserved.
17 *
18 * 2003-09-01: Support w3cam by Takeo Takahashi
19 */
20
21#include <linux/init.h>
22#include <linux/module.h>
23#include <linux/delay.h>
24#include <linux/errno.h>
25#include <linux/fs.h>
26#include <linux/kernel.h>
27#include <linux/slab.h>
28#include <linux/mm.h>
29#include <linux/sched.h>
30#include <linux/videodev2.h>
31#include <media/v4l2-common.h>
32#include <media/v4l2-device.h>
33#include <media/v4l2-ioctl.h>
34#include <media/v4l2-fh.h>
35#include <linux/mutex.h>
36
37#include <asm/uaccess.h>
38#include <asm/m32r.h>
39#include <asm/io.h>
40#include <asm/dma.h>
41#include <asm/byteorder.h>
42
43#if 0
44#define DEBUG(n, args...) printk(KERN_INFO args)
45#define CHECK_LOST 1
46#else
47#define DEBUG(n, args...)
48#define CHECK_LOST 0
49#endif
50
51/*
52 * USE_INT is always 0, interrupt mode is not available
53 * on linux due to lack of speed
54 */
55#define USE_INT 0 /* Don't modify */
56
57#define VERSION "0.0.5"
58
59#define ar_inl(addr) inl((unsigned long)(addr))
60#define ar_outl(val, addr) outl((unsigned long)(val), (unsigned long)(addr))
61
62extern struct cpuinfo_m32r boot_cpu_data;
63
64/*
65 * CCD pixel size
66 * Note that M32700UT does not support CIF mode, but QVGA is
67 * supported by M32700UT hardware using VGA mode of AR LSI.
68 *
69 * Supported: VGA (Normal mode, Interlace mode)
70 * QVGA (Always Interlace mode of VGA)
71 *
72 */
73#define AR_WIDTH_VGA 640
74#define AR_HEIGHT_VGA 480
75#define AR_WIDTH_QVGA 320
76#define AR_HEIGHT_QVGA 240
77#define MIN_AR_WIDTH AR_WIDTH_QVGA
78#define MIN_AR_HEIGHT AR_HEIGHT_QVGA
79#define MAX_AR_WIDTH AR_WIDTH_VGA
80#define MAX_AR_HEIGHT AR_HEIGHT_VGA
81
82/* bits & bytes per pixel */
83#define AR_BITS_PER_PIXEL 16
84#define AR_BYTES_PER_PIXEL (AR_BITS_PER_PIXEL / 8)
85
86/* line buffer size */
87#define AR_LINE_BYTES_VGA (AR_WIDTH_VGA * AR_BYTES_PER_PIXEL)
88#define AR_LINE_BYTES_QVGA (AR_WIDTH_QVGA * AR_BYTES_PER_PIXEL)
89#define MAX_AR_LINE_BYTES AR_LINE_BYTES_VGA
90
91/* frame size & type */
92#define AR_FRAME_BYTES_VGA \
93 (AR_WIDTH_VGA * AR_HEIGHT_VGA * AR_BYTES_PER_PIXEL)
94#define AR_FRAME_BYTES_QVGA \
95 (AR_WIDTH_QVGA * AR_HEIGHT_QVGA * AR_BYTES_PER_PIXEL)
96#define MAX_AR_FRAME_BYTES \
97 (MAX_AR_WIDTH * MAX_AR_HEIGHT * AR_BYTES_PER_PIXEL)
98
99#define AR_MAX_FRAME 15
100
101/* capture size */
102#define AR_SIZE_VGA 0
103#define AR_SIZE_QVGA 1
104
105/* capture mode */
106#define AR_MODE_INTERLACE 0
107#define AR_MODE_NORMAL 1
108
109struct ar {
110 struct v4l2_device v4l2_dev;
111 struct video_device vdev;
112 unsigned int start_capture; /* duaring capture in INT. mode. */
113#if USE_INT
114 unsigned char *line_buff; /* DMA line buffer */
115#endif
116 unsigned char *frame[MAX_AR_HEIGHT]; /* frame data */
117 short size; /* capture size */
118 short mode; /* capture mode */
119 int width, height;
120 int frame_bytes, line_bytes;
121 wait_queue_head_t wait;
122 struct mutex lock;
123};
124
125static struct ar ardev;
126
127static int video_nr = -1; /* video device number (first free) */
128static unsigned char yuv[MAX_AR_FRAME_BYTES];
129
130/* module parameters */
131/* default frequency */
132#define DEFAULT_FREQ 50 /* 50 or 75 (MHz) is available as BCLK */
133static int freq = DEFAULT_FREQ; /* BCLK: available 50 or 70 (MHz) */
134static int vga; /* default mode(0:QVGA mode, other:VGA mode) */
135static int vga_interlace; /* 0 is normal mode for, else interlace mode */
136module_param(freq, int, 0);
137module_param(vga, int, 0);
138module_param(vga_interlace, int, 0);
139
140static void wait_for_vsync(void)
141{
142 while (ar_inl(ARVCR0) & ARVCR0_VDS) /* wait for VSYNC */
143 cpu_relax();
144 while (!(ar_inl(ARVCR0) & ARVCR0_VDS)) /* wait for VSYNC */
145 cpu_relax();
146}
147
148static void wait_acknowledge(void)
149{
150 int i;
151
152 for (i = 0; i < 1000; i++)
153 cpu_relax();
154 while (ar_inl(PLDI2CSTS) & PLDI2CSTS_NOACK)
155 cpu_relax();
156}
157
158/*******************************************************************
159 * I2C functions
160 *******************************************************************/
161static void iic(int n, unsigned long addr, unsigned long data1, unsigned long data2,
162 unsigned long data3)
163{
164 int i;
165
166 /* Slave Address */
167 ar_outl(addr, PLDI2CDATA);
168 wait_for_vsync();
169
170 /* Start */
171 ar_outl(1, PLDI2CCND);
172 wait_acknowledge();
173
174 /* Transfer data 1 */
175 ar_outl(data1, PLDI2CDATA);
176 wait_for_vsync();
177 ar_outl(PLDI2CSTEN_STEN, PLDI2CSTEN);
178 wait_acknowledge();
179
180 /* Transfer data 2 */
181 ar_outl(data2, PLDI2CDATA);
182 wait_for_vsync();
183 ar_outl(PLDI2CSTEN_STEN, PLDI2CSTEN);
184 wait_acknowledge();
185
186 if (n == 3) {
187 /* Transfer data 3 */
188 ar_outl(data3, PLDI2CDATA);
189 wait_for_vsync();
190 ar_outl(PLDI2CSTEN_STEN, PLDI2CSTEN);
191 wait_acknowledge();
192 }
193
194 /* Stop */
195 for (i = 0; i < 100; i++)
196 cpu_relax();
197 ar_outl(2, PLDI2CCND);
198 ar_outl(2, PLDI2CCND);
199
200 while (ar_inl(PLDI2CSTS) & PLDI2CSTS_BB)
201 cpu_relax();
202}
203
204
205static void init_iic(void)
206{
207 DEBUG(1, "init_iic:\n");
208
209 /*
210 * ICU Setting (iic)
211 */
212 /* I2C Setting */
213 ar_outl(0x0, PLDI2CCR); /* I2CCR Disable */
214 ar_outl(0x0300, PLDI2CMOD); /* I2CMOD ACK/8b-data/7b-addr/auto */
215 ar_outl(0x1, PLDI2CACK); /* I2CACK ACK */
216
217 /* I2C CLK */
218 /* 50MH-100k */
219 if (freq == 75)
220 ar_outl(369, PLDI2CFREQ); /* BCLK = 75MHz */
221 else if (freq == 50)
222 ar_outl(244, PLDI2CFREQ); /* BCLK = 50MHz */
223 else
224 ar_outl(244, PLDI2CFREQ); /* default: BCLK = 50MHz */
225 ar_outl(0x1, PLDI2CCR); /* I2CCR Enable */
226}
227
228/**************************************************************************
229 *
230 * Video4Linux Interface functions
231 *
232 **************************************************************************/
233
234static inline void disable_dma(void)
235{
236 ar_outl(0x8000, M32R_DMAEN_PORTL); /* disable DMA0 */
237}
238
239static inline void enable_dma(void)
240{
241 ar_outl(0x8080, M32R_DMAEN_PORTL); /* enable DMA0 */
242}
243
244static inline void clear_dma_status(void)
245{
246 ar_outl(0x8000, M32R_DMAEDET_PORTL); /* clear status */
247}
248
249static void wait_for_vertical_sync(struct ar *ar, int exp_line)
250{
251#if CHECK_LOST
252 int tmout = 10000; /* FIXME */
253 int l;
254
255 /*
256 * check HCOUNT because we cannot check vertical sync.
257 */
258 for (; tmout >= 0; tmout--) {
259 l = ar_inl(ARVHCOUNT);
260 if (l == exp_line)
261 break;
262 }
263 if (tmout < 0)
264 v4l2_err(&ar->v4l2_dev, "lost %d -> %d\n", exp_line, l);
265#else
266 while (ar_inl(ARVHCOUNT) != exp_line)
267 cpu_relax();
268#endif
269}
270
271static ssize_t ar_read(struct file *file, char *buf, size_t count, loff_t *ppos)
272{
273 struct ar *ar = video_drvdata(file);
274 long ret = ar->frame_bytes; /* return read bytes */
275 unsigned long arvcr1 = 0;
276 unsigned long flags;
277 unsigned char *p;
278 int h, w;
279 unsigned char *py, *pu, *pv;
280#if !USE_INT
281 int l;
282#endif
283
284 DEBUG(1, "ar_read()\n");
285
286 if (ar->size == AR_SIZE_QVGA)
287 arvcr1 |= ARVCR1_QVGA;
288 if (ar->mode == AR_MODE_NORMAL)
289 arvcr1 |= ARVCR1_NORMAL;
290
291 mutex_lock(&ar->lock);
292
293#if USE_INT
294 local_irq_save(flags);
295 disable_dma();
296 ar_outl(0xa1871300, M32R_DMA0CR0_PORTL);
297 ar_outl(0x01000000, M32R_DMA0CR1_PORTL);
298
299 /* set AR FIFO address as source(BSEL5) */
300 ar_outl(ARDATA32, M32R_DMA0CSA_PORTL);
301 ar_outl(ARDATA32, M32R_DMA0RSA_PORTL);
302 ar_outl(ar->line_buff, M32R_DMA0CDA_PORTL); /* destination addr. */
303 ar_outl(ar->line_buff, M32R_DMA0RDA_PORTL); /* reload address */
304 ar_outl(ar->line_bytes, M32R_DMA0CBCUT_PORTL); /* byte count (bytes) */
305 ar_outl(ar->line_bytes, M32R_DMA0RBCUT_PORTL); /* reload count (bytes) */
306
307 /*
308 * Okay, kick AR LSI to invoke an interrupt
309 */
310 ar->start_capture = 0;
311 ar_outl(arvcr1 | ARVCR1_HIEN, ARVCR1);
312 local_irq_restore(flags);
313 /* .... AR interrupts .... */
314 interruptible_sleep_on(&ar->wait);
315 if (signal_pending(current)) {
316 printk(KERN_ERR "arv: interrupted while get frame data.\n");
317 ret = -EINTR;
318 goto out_up;
319 }
320#else /* ! USE_INT */
321 /* polling */
322 ar_outl(arvcr1, ARVCR1);
323 disable_dma();
324 ar_outl(0x8000, M32R_DMAEDET_PORTL);
325 ar_outl(0xa0861300, M32R_DMA0CR0_PORTL);
326 ar_outl(0x01000000, M32R_DMA0CR1_PORTL);
327 ar_outl(ARDATA32, M32R_DMA0CSA_PORTL);
328 ar_outl(ARDATA32, M32R_DMA0RSA_PORTL);
329 ar_outl(ar->line_bytes, M32R_DMA0CBCUT_PORTL);
330 ar_outl(ar->line_bytes, M32R_DMA0RBCUT_PORTL);
331
332 local_irq_save(flags);
333 while (ar_inl(ARVHCOUNT) != 0) /* wait for 0 */
334 cpu_relax();
335 if (ar->mode == AR_MODE_INTERLACE && ar->size == AR_SIZE_VGA) {
336 for (h = 0; h < ar->height; h++) {
337 wait_for_vertical_sync(ar, h);
338 if (h < (AR_HEIGHT_VGA/2))
339 l = h << 1;
340 else
341 l = (((h - (AR_HEIGHT_VGA/2)) << 1) + 1);
342 ar_outl(virt_to_phys(ar->frame[l]), M32R_DMA0CDA_PORTL);
343 enable_dma();
344 while (!(ar_inl(M32R_DMAEDET_PORTL) & 0x8000))
345 cpu_relax();
346 disable_dma();
347 clear_dma_status();
348 ar_outl(0xa0861300, M32R_DMA0CR0_PORTL);
349 }
350 } else {
351 for (h = 0; h < ar->height; h++) {
352 wait_for_vertical_sync(ar, h);
353 ar_outl(virt_to_phys(ar->frame[h]), M32R_DMA0CDA_PORTL);
354 enable_dma();
355 while (!(ar_inl(M32R_DMAEDET_PORTL) & 0x8000))
356 cpu_relax();
357 disable_dma();
358 clear_dma_status();
359 ar_outl(0xa0861300, M32R_DMA0CR0_PORTL);
360 }
361 }
362 local_irq_restore(flags);
363#endif /* ! USE_INT */
364
365 /*
366 * convert YUV422 to YUV422P
367 * +--------------------+
368 * | Y0,Y1,... |
369 * | ..............Yn |
370 * +--------------------+
371 * | U0,U1,........Un |
372 * +--------------------+
373 * | V0,V1,........Vn |
374 * +--------------------+
375 */
376 py = yuv;
377 pu = py + (ar->frame_bytes / 2);
378 pv = pu + (ar->frame_bytes / 4);
379 for (h = 0; h < ar->height; h++) {
380 p = ar->frame[h];
381 for (w = 0; w < ar->line_bytes; w += 4) {
382 *py++ = *p++;
383 *pu++ = *p++;
384 *py++ = *p++;
385 *pv++ = *p++;
386 }
387 }
388 if (copy_to_user(buf, yuv, ar->frame_bytes)) {
389 v4l2_err(&ar->v4l2_dev, "failed while copy_to_user yuv.\n");
390 ret = -EFAULT;
391 goto out_up;
392 }
393 DEBUG(1, "ret = %d\n", ret);
394out_up:
395 mutex_unlock(&ar->lock);
396 return ret;
397}
398
399static int ar_querycap(struct file *file, void *priv,
400 struct v4l2_capability *vcap)
401{
402 struct ar *ar = video_drvdata(file);
403
404 strlcpy(vcap->driver, ar->vdev.name, sizeof(vcap->driver));
405 strlcpy(vcap->card, "Colour AR VGA", sizeof(vcap->card));
406 strlcpy(vcap->bus_info, "Platform", sizeof(vcap->bus_info));
407 vcap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE;
408 vcap->capabilities = vcap->device_caps | V4L2_CAP_DEVICE_CAPS;
409 return 0;
410}
411
412static int ar_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
413{
414 if (vin->index > 0)
415 return -EINVAL;
416 strlcpy(vin->name, "Camera", sizeof(vin->name));
417 vin->type = V4L2_INPUT_TYPE_CAMERA;
418 vin->audioset = 0;
419 vin->tuner = 0;
420 vin->std = V4L2_STD_ALL;
421 vin->status = 0;
422 return 0;
423}
424
425static int ar_g_input(struct file *file, void *fh, unsigned int *inp)
426{
427 *inp = 0;
428 return 0;
429}
430
431static int ar_s_input(struct file *file, void *fh, unsigned int inp)
432{
433 return inp ? -EINVAL : 0;
434}
435
436static int ar_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
437{
438 struct ar *ar = video_drvdata(file);
439 struct v4l2_pix_format *pix = &fmt->fmt.pix;
440
441 pix->width = ar->width;
442 pix->height = ar->height;
443 pix->pixelformat = V4L2_PIX_FMT_YUV422P;
444 pix->field = (ar->mode == AR_MODE_NORMAL) ? V4L2_FIELD_NONE : V4L2_FIELD_INTERLACED;
445 pix->bytesperline = ar->width;
446 pix->sizeimage = 2 * ar->width * ar->height;
447 /* Just a guess */
448 pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
449 return 0;
450}
451
452static int ar_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
453{
454 struct ar *ar = video_drvdata(file);
455 struct v4l2_pix_format *pix = &fmt->fmt.pix;
456
457 if (pix->height <= AR_HEIGHT_QVGA || pix->width <= AR_WIDTH_QVGA) {
458 pix->height = AR_HEIGHT_QVGA;
459 pix->width = AR_WIDTH_QVGA;
460 pix->field = V4L2_FIELD_INTERLACED;
461 } else {
462 pix->height = AR_HEIGHT_VGA;
463 pix->width = AR_WIDTH_VGA;
464 pix->field = vga_interlace ? V4L2_FIELD_INTERLACED : V4L2_FIELD_NONE;
465 }
466 pix->pixelformat = V4L2_PIX_FMT_YUV422P;
467 pix->bytesperline = ar->width;
468 pix->sizeimage = 2 * ar->width * ar->height;
469 /* Just a guess */
470 pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
471 return 0;
472}
473
474static int ar_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
475{
476 struct ar *ar = video_drvdata(file);
477 struct v4l2_pix_format *pix = &fmt->fmt.pix;
478 int ret = ar_try_fmt_vid_cap(file, fh, fmt);
479
480 if (ret)
481 return ret;
482 mutex_lock(&ar->lock);
483 ar->width = pix->width;
484 ar->height = pix->height;
485 if (ar->width == AR_WIDTH_VGA) {
486 ar->size = AR_SIZE_VGA;
487 ar->frame_bytes = AR_FRAME_BYTES_VGA;
488 ar->line_bytes = AR_LINE_BYTES_VGA;
489 if (vga_interlace)
490 ar->mode = AR_MODE_INTERLACE;
491 else
492 ar->mode = AR_MODE_NORMAL;
493 } else {
494 ar->size = AR_SIZE_QVGA;
495 ar->frame_bytes = AR_FRAME_BYTES_QVGA;
496 ar->line_bytes = AR_LINE_BYTES_QVGA;
497 ar->mode = AR_MODE_INTERLACE;
498 }
499 /* Ok we figured out what to use from our wide choice */
500 mutex_unlock(&ar->lock);
501 return 0;
502}
503
504static int ar_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
505{
506 static struct v4l2_fmtdesc formats[] = {
507 { 0, 0, 0,
508 "YUV 4:2:2 Planar", V4L2_PIX_FMT_YUV422P,
509 { 0, 0, 0, 0 }
510 },
511 };
512 enum v4l2_buf_type type = fmt->type;
513
514 if (fmt->index > 0)
515 return -EINVAL;
516
517 *fmt = formats[fmt->index];
518 fmt->type = type;
519 return 0;
520}
521
522#if USE_INT
523/*
524 * Interrupt handler
525 */
526static void ar_interrupt(int irq, void *dev)
527{
528 struct ar *ar = dev;
529 unsigned int line_count;
530 unsigned int line_number;
531 unsigned int arvcr1;
532
533 line_count = ar_inl(ARVHCOUNT); /* line number */
534 if (ar->mode == AR_MODE_INTERLACE && ar->size == AR_SIZE_VGA) {
535 /* operations for interlace mode */
536 if (line_count < (AR_HEIGHT_VGA / 2)) /* even line */
537 line_number = (line_count << 1);
538 else /* odd line */
539 line_number =
540 (((line_count - (AR_HEIGHT_VGA / 2)) << 1) + 1);
541 } else {
542 line_number = line_count;
543 }
544
545 if (line_number == 0) {
546 /*
547 * It is an interrupt for line 0.
548 * we have to start capture.
549 */
550 disable_dma();
551#if 0
552 ar_outl(ar->line_buff, M32R_DMA0CDA_PORTL); /* needless? */
553#endif
554 memcpy(ar->frame[0], ar->line_buff, ar->line_bytes);
555#if 0
556 ar_outl(0xa1861300, M32R_DMA0CR0_PORTL);
557#endif
558 enable_dma();
559 ar->start_capture = 1; /* during capture */
560 return;
561 }
562
563 if (ar->start_capture == 1 && line_number <= (ar->height - 1)) {
564 disable_dma();
565 memcpy(ar->frame[line_number], ar->line_buff, ar->line_bytes);
566
567 /*
568 * if captured all line of a frame, disable AR interrupt
569 * and wake a process up.
570 */
571 if (line_number == (ar->height - 1)) { /* end of line */
572
573 ar->start_capture = 0;
574
575 /* disable AR interrupt request */
576 arvcr1 = ar_inl(ARVCR1);
577 arvcr1 &= ~ARVCR1_HIEN; /* clear int. flag */
578 ar_outl(arvcr1, ARVCR1); /* disable */
579 wake_up_interruptible(&ar->wait);
580 } else {
581#if 0
582 ar_outl(ar->line_buff, M32R_DMA0CDA_PORTL);
583 ar_outl(0xa1861300, M32R_DMA0CR0_PORTL);
584#endif
585 enable_dma();
586 }
587 }
588}
589#endif
590
591/*
592 * ar_initialize()
593 * ar_initialize() is called by video_register_device() and
594 * initializes AR LSI and peripherals.
595 *
596 * -1 is returned in all failures.
597 * 0 is returned in success.
598 *
599 */
600static int ar_initialize(struct ar *ar)
601{
602 unsigned long cr = 0;
603 int i, found = 0;
604
605 DEBUG(1, "ar_initialize:\n");
606
607 /*
608 * initialize AR LSI
609 */
610 ar_outl(0, ARVCR0); /* assert reset of AR LSI */
611 for (i = 0; i < 0x18; i++) /* wait for over 10 cycles @ 27MHz */
612 cpu_relax();
613 ar_outl(ARVCR0_RST, ARVCR0); /* negate reset of AR LSI (enable) */
614 for (i = 0; i < 0x40d; i++) /* wait for over 420 cycles @ 27MHz */
615 cpu_relax();
616
617 /* AR uses INT3 of CPU as interrupt pin. */
618 ar_outl(ARINTSEL_INT3, ARINTSEL);
619
620 if (ar->size == AR_SIZE_QVGA)
621 cr |= ARVCR1_QVGA;
622 if (ar->mode == AR_MODE_NORMAL)
623 cr |= ARVCR1_NORMAL;
624 ar_outl(cr, ARVCR1);
625
626 /*
627 * Initialize IIC so that CPU can communicate with AR LSI,
628 * and send boot commands to AR LSI.
629 */
630 init_iic();
631
632 for (i = 0; i < 0x100000; i++) { /* > 0xa1d10, 56ms */
633 if ((ar_inl(ARVCR0) & ARVCR0_VDS)) { /* VSYNC */
634 found = 1;
635 break;
636 }
637 }
638
639 if (found == 0)
640 return -ENODEV;
641
642 v4l2_info(&ar->v4l2_dev, "Initializing ");
643
644 iic(2, 0x78, 0x11, 0x01, 0x00); /* start */
645 iic(3, 0x78, 0x12, 0x00, 0x06);
646 iic(3, 0x78, 0x12, 0x12, 0x30);
647 iic(3, 0x78, 0x12, 0x15, 0x58);
648 iic(3, 0x78, 0x12, 0x17, 0x30);
649 printk(KERN_CONT ".");
650 iic(3, 0x78, 0x12, 0x1a, 0x97);
651 iic(3, 0x78, 0x12, 0x1b, 0xff);
652 iic(3, 0x78, 0x12, 0x1c, 0xff);
653 iic(3, 0x78, 0x12, 0x26, 0x10);
654 iic(3, 0x78, 0x12, 0x27, 0x00);
655 printk(KERN_CONT ".");
656 iic(2, 0x78, 0x34, 0x02, 0x00);
657 iic(2, 0x78, 0x7a, 0x10, 0x00);
658 iic(2, 0x78, 0x80, 0x39, 0x00);
659 iic(2, 0x78, 0x81, 0xe6, 0x00);
660 iic(2, 0x78, 0x8d, 0x00, 0x00);
661 printk(KERN_CONT ".");
662 iic(2, 0x78, 0x8e, 0x0c, 0x00);
663 iic(2, 0x78, 0x8f, 0x00, 0x00);
664#if 0
665 iic(2, 0x78, 0x90, 0x00, 0x00); /* AWB on=1 off=0 */
666#endif
667 iic(2, 0x78, 0x93, 0x01, 0x00);
668 iic(2, 0x78, 0x94, 0xcd, 0x00);
669 iic(2, 0x78, 0x95, 0x00, 0x00);
670 printk(KERN_CONT ".");
671 iic(2, 0x78, 0x96, 0xa0, 0x00);
672 iic(2, 0x78, 0x97, 0x00, 0x00);
673 iic(2, 0x78, 0x98, 0x60, 0x00);
674 iic(2, 0x78, 0x99, 0x01, 0x00);
675 iic(2, 0x78, 0x9a, 0x19, 0x00);
676 printk(KERN_CONT ".");
677 iic(2, 0x78, 0x9b, 0x02, 0x00);
678 iic(2, 0x78, 0x9c, 0xe8, 0x00);
679 iic(2, 0x78, 0x9d, 0x02, 0x00);
680 iic(2, 0x78, 0x9e, 0x2e, 0x00);
681 iic(2, 0x78, 0xb8, 0x78, 0x00);
682 iic(2, 0x78, 0xba, 0x05, 0x00);
683#if 0
684 iic(2, 0x78, 0x83, 0x8c, 0x00); /* brightness */
685#endif
686 printk(KERN_CONT ".");
687
688 /* color correction */
689 iic(3, 0x78, 0x49, 0x00, 0x95); /* a */
690 iic(3, 0x78, 0x49, 0x01, 0x96); /* b */
691 iic(3, 0x78, 0x49, 0x03, 0x85); /* c */
692 iic(3, 0x78, 0x49, 0x04, 0x97); /* d */
693 iic(3, 0x78, 0x49, 0x02, 0x7e); /* e(Lo) */
694 iic(3, 0x78, 0x49, 0x05, 0xa4); /* f(Lo) */
695 iic(3, 0x78, 0x49, 0x06, 0x04); /* e(Hi) */
696 iic(3, 0x78, 0x49, 0x07, 0x04); /* e(Hi) */
697 iic(2, 0x78, 0x48, 0x01, 0x00); /* on=1 off=0 */
698
699 printk(KERN_CONT ".");
700 iic(2, 0x78, 0x11, 0x00, 0x00); /* end */
701 printk(KERN_CONT " done\n");
702 return 0;
703}
704
705
706/****************************************************************************
707 *
708 * Video4Linux Module functions
709 *
710 ****************************************************************************/
711
712static const struct v4l2_file_operations ar_fops = {
713 .owner = THIS_MODULE,
714 .open = v4l2_fh_open,
715 .release = v4l2_fh_release,
716 .read = ar_read,
717 .unlocked_ioctl = video_ioctl2,
718};
719
720static const struct v4l2_ioctl_ops ar_ioctl_ops = {
721 .vidioc_querycap = ar_querycap,
722 .vidioc_g_input = ar_g_input,
723 .vidioc_s_input = ar_s_input,
724 .vidioc_enum_input = ar_enum_input,
725 .vidioc_enum_fmt_vid_cap = ar_enum_fmt_vid_cap,
726 .vidioc_g_fmt_vid_cap = ar_g_fmt_vid_cap,
727 .vidioc_s_fmt_vid_cap = ar_s_fmt_vid_cap,
728 .vidioc_try_fmt_vid_cap = ar_try_fmt_vid_cap,
729};
730
731#define ALIGN4(x) ((((int)(x)) & 0x3) == 0)
732
733static int __init ar_init(void)
734{
735 struct ar *ar;
736 struct v4l2_device *v4l2_dev;
737 int ret;
738 int i;
739
740 ar = &ardev;
741 v4l2_dev = &ar->v4l2_dev;
742 strlcpy(v4l2_dev->name, "arv", sizeof(v4l2_dev->name));
743 v4l2_info(v4l2_dev, "Colour AR VGA driver %s\n", VERSION);
744
745 ret = v4l2_device_register(NULL, v4l2_dev);
746 if (ret < 0) {
747 v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
748 return ret;
749 }
750 ret = -EIO;
751
752#if USE_INT
753 /* allocate a DMA buffer for 1 line. */
754 ar->line_buff = kmalloc(MAX_AR_LINE_BYTES, GFP_KERNEL | GFP_DMA);
755 if (ar->line_buff == NULL || !ALIGN4(ar->line_buff)) {
756 v4l2_err(v4l2_dev, "buffer allocation failed for DMA.\n");
757 ret = -ENOMEM;
758 goto out_end;
759 }
760#endif
761 /* allocate buffers for a frame */
762 for (i = 0; i < MAX_AR_HEIGHT; i++) {
763 ar->frame[i] = kmalloc(MAX_AR_LINE_BYTES, GFP_KERNEL);
764 if (ar->frame[i] == NULL || !ALIGN4(ar->frame[i])) {
765 v4l2_err(v4l2_dev, "buffer allocation failed for frame.\n");
766 ret = -ENOMEM;
767 goto out_line_buff;
768 }
769 }
770
771 strlcpy(ar->vdev.name, "Colour AR VGA", sizeof(ar->vdev.name));
772 ar->vdev.v4l2_dev = v4l2_dev;
773 ar->vdev.fops = &ar_fops;
774 ar->vdev.ioctl_ops = &ar_ioctl_ops;
775 ar->vdev.release = video_device_release_empty;
776 set_bit(V4L2_FL_USE_FH_PRIO, &ar->vdev.flags);
777 video_set_drvdata(&ar->vdev, ar);
778
779 if (vga) {
780 ar->width = AR_WIDTH_VGA;
781 ar->height = AR_HEIGHT_VGA;
782 ar->size = AR_SIZE_VGA;
783 ar->frame_bytes = AR_FRAME_BYTES_VGA;
784 ar->line_bytes = AR_LINE_BYTES_VGA;
785 if (vga_interlace)
786 ar->mode = AR_MODE_INTERLACE;
787 else
788 ar->mode = AR_MODE_NORMAL;
789 } else {
790 ar->width = AR_WIDTH_QVGA;
791 ar->height = AR_HEIGHT_QVGA;
792 ar->size = AR_SIZE_QVGA;
793 ar->frame_bytes = AR_FRAME_BYTES_QVGA;
794 ar->line_bytes = AR_LINE_BYTES_QVGA;
795 ar->mode = AR_MODE_INTERLACE;
796 }
797 mutex_init(&ar->lock);
798 init_waitqueue_head(&ar->wait);
799
800#if USE_INT
801 if (request_irq(M32R_IRQ_INT3, ar_interrupt, 0, "arv", ar)) {
802 v4l2_err("request_irq(%d) failed.\n", M32R_IRQ_INT3);
803 ret = -EIO;
804 goto out_irq;
805 }
806#endif
807
808 if (ar_initialize(ar) != 0) {
809 v4l2_err(v4l2_dev, "M64278 not found.\n");
810 ret = -ENODEV;
811 goto out_dev;
812 }
813
814 /*
815 * ok, we can initialize h/w according to parameters,
816 * so register video device as a frame grabber type.
817 * device is named "video[0-64]".
818 * video_register_device() initializes h/w using ar_initialize().
819 */
820 if (video_register_device(&ar->vdev, VFL_TYPE_GRABBER, video_nr) != 0) {
821 /* return -1, -ENFILE(full) or others */
822 v4l2_err(v4l2_dev, "register video (Colour AR) failed.\n");
823 ret = -ENODEV;
824 goto out_dev;
825 }
826
827 v4l2_info(v4l2_dev, "%s: Found M64278 VGA (IRQ %d, Freq %dMHz).\n",
828 video_device_node_name(&ar->vdev), M32R_IRQ_INT3, freq);
829
830 return 0;
831
832out_dev:
833#if USE_INT
834 free_irq(M32R_IRQ_INT3, ar);
835
836out_irq:
837#endif
838 for (i = 0; i < MAX_AR_HEIGHT; i++)
839 kfree(ar->frame[i]);
840
841out_line_buff:
842#if USE_INT
843 kfree(ar->line_buff);
844
845out_end:
846#endif
847 v4l2_device_unregister(&ar->v4l2_dev);
848 return ret;
849}
850
851
852static int __init ar_init_module(void)
853{
854 freq = (boot_cpu_data.bus_clock / 1000000);
855 printk(KERN_INFO "arv: Bus clock %d\n", freq);
856 if (freq != 50 && freq != 75)
857 freq = DEFAULT_FREQ;
858 return ar_init();
859}
860
861static void __exit ar_cleanup_module(void)
862{
863 struct ar *ar;
864 int i;
865
866 ar = &ardev;
867 video_unregister_device(&ar->vdev);
868#if USE_INT
869 free_irq(M32R_IRQ_INT3, ar);
870#endif
871 for (i = 0; i < MAX_AR_HEIGHT; i++)
872 kfree(ar->frame[i]);
873#if USE_INT
874 kfree(ar->line_buff);
875#endif
876 v4l2_device_unregister(&ar->v4l2_dev);
877}
878
879module_init(ar_init_module);
880module_exit(ar_cleanup_module);
881
882MODULE_AUTHOR("Takeo Takahashi <takahashi.takeo@renesas.com>");
883MODULE_DESCRIPTION("Colour AR M64278(VGA) for Video4Linux");
884MODULE_LICENSE("GPL");
885MODULE_VERSION(VERSION);
diff --git a/drivers/media/video/atmel-isi.c b/drivers/media/video/atmel-isi.c
deleted file mode 100644
index 6274a91c25c7..000000000000
--- a/drivers/media/video/atmel-isi.c
+++ /dev/null
@@ -1,1099 +0,0 @@
1/*
2 * Copyright (c) 2011 Atmel Corporation
3 * Josh Wu, <josh.wu@atmel.com>
4 *
5 * Based on previous work by Lars Haring, <lars.haring@atmel.com>
6 * and Sedji Gaouaou
7 * Based on the bttv driver for Bt848 with respective copyright holders
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/clk.h>
15#include <linux/completion.h>
16#include <linux/delay.h>
17#include <linux/fs.h>
18#include <linux/init.h>
19#include <linux/interrupt.h>
20#include <linux/kernel.h>
21#include <linux/module.h>
22#include <linux/platform_device.h>
23#include <linux/slab.h>
24
25#include <media/atmel-isi.h>
26#include <media/soc_camera.h>
27#include <media/soc_mediabus.h>
28#include <media/videobuf2-dma-contig.h>
29
30#define MAX_BUFFER_NUM 32
31#define MAX_SUPPORT_WIDTH 2048
32#define MAX_SUPPORT_HEIGHT 2048
33#define VID_LIMIT_BYTES (16 * 1024 * 1024)
34#define MIN_FRAME_RATE 15
35#define FRAME_INTERVAL_MILLI_SEC (1000 / MIN_FRAME_RATE)
36
37/* ISI states */
38enum {
39 ISI_STATE_IDLE = 0,
40 ISI_STATE_READY,
41 ISI_STATE_WAIT_SOF,
42};
43
44/* Frame buffer descriptor */
45struct fbd {
46 /* Physical address of the frame buffer */
47 u32 fb_address;
48 /* DMA Control Register(only in HISI2) */
49 u32 dma_ctrl;
50 /* Physical address of the next fbd */
51 u32 next_fbd_address;
52};
53
54static void set_dma_ctrl(struct fbd *fb_desc, u32 ctrl)
55{
56 fb_desc->dma_ctrl = ctrl;
57}
58
59struct isi_dma_desc {
60 struct list_head list;
61 struct fbd *p_fbd;
62 u32 fbd_phys;
63};
64
65/* Frame buffer data */
66struct frame_buffer {
67 struct vb2_buffer vb;
68 struct isi_dma_desc *p_dma_desc;
69 struct list_head list;
70};
71
72struct atmel_isi {
73 /* Protects the access of variables shared with the ISR */
74 spinlock_t lock;
75 void __iomem *regs;
76
77 int sequence;
78 /* State of the ISI module in capturing mode */
79 int state;
80
81 /* Wait queue for waiting for SOF */
82 wait_queue_head_t vsync_wq;
83
84 struct vb2_alloc_ctx *alloc_ctx;
85
86 /* Allocate descriptors for dma buffer use */
87 struct fbd *p_fb_descriptors;
88 u32 fb_descriptors_phys;
89 struct list_head dma_desc_head;
90 struct isi_dma_desc dma_desc[MAX_BUFFER_NUM];
91
92 struct completion complete;
93 /* ISI peripherial clock */
94 struct clk *pclk;
95 /* ISI_MCK, feed to camera sensor to generate pixel clock */
96 struct clk *mck;
97 unsigned int irq;
98
99 struct isi_platform_data *pdata;
100 u16 width_flags; /* max 12 bits */
101
102 struct list_head video_buffer_list;
103 struct frame_buffer *active;
104
105 struct soc_camera_device *icd;
106 struct soc_camera_host soc_host;
107};
108
109static void isi_writel(struct atmel_isi *isi, u32 reg, u32 val)
110{
111 writel(val, isi->regs + reg);
112}
113static u32 isi_readl(struct atmel_isi *isi, u32 reg)
114{
115 return readl(isi->regs + reg);
116}
117
118static int configure_geometry(struct atmel_isi *isi, u32 width,
119 u32 height, enum v4l2_mbus_pixelcode code)
120{
121 u32 cfg2, cr;
122
123 switch (code) {
124 /* YUV, including grey */
125 case V4L2_MBUS_FMT_Y8_1X8:
126 cr = ISI_CFG2_GRAYSCALE;
127 break;
128 case V4L2_MBUS_FMT_UYVY8_2X8:
129 cr = ISI_CFG2_YCC_SWAP_MODE_3;
130 break;
131 case V4L2_MBUS_FMT_VYUY8_2X8:
132 cr = ISI_CFG2_YCC_SWAP_MODE_2;
133 break;
134 case V4L2_MBUS_FMT_YUYV8_2X8:
135 cr = ISI_CFG2_YCC_SWAP_MODE_1;
136 break;
137 case V4L2_MBUS_FMT_YVYU8_2X8:
138 cr = ISI_CFG2_YCC_SWAP_DEFAULT;
139 break;
140 /* RGB, TODO */
141 default:
142 return -EINVAL;
143 }
144
145 isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS);
146
147 cfg2 = isi_readl(isi, ISI_CFG2);
148 cfg2 |= cr;
149 /* Set width */
150 cfg2 &= ~(ISI_CFG2_IM_HSIZE_MASK);
151 cfg2 |= ((width - 1) << ISI_CFG2_IM_HSIZE_OFFSET) &
152 ISI_CFG2_IM_HSIZE_MASK;
153 /* Set height */
154 cfg2 &= ~(ISI_CFG2_IM_VSIZE_MASK);
155 cfg2 |= ((height - 1) << ISI_CFG2_IM_VSIZE_OFFSET)
156 & ISI_CFG2_IM_VSIZE_MASK;
157 isi_writel(isi, ISI_CFG2, cfg2);
158
159 return 0;
160}
161
162static irqreturn_t atmel_isi_handle_streaming(struct atmel_isi *isi)
163{
164 if (isi->active) {
165 struct vb2_buffer *vb = &isi->active->vb;
166 struct frame_buffer *buf = isi->active;
167
168 list_del_init(&buf->list);
169 do_gettimeofday(&vb->v4l2_buf.timestamp);
170 vb->v4l2_buf.sequence = isi->sequence++;
171 vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
172 }
173
174 if (list_empty(&isi->video_buffer_list)) {
175 isi->active = NULL;
176 } else {
177 /* start next dma frame. */
178 isi->active = list_entry(isi->video_buffer_list.next,
179 struct frame_buffer, list);
180 isi_writel(isi, ISI_DMA_C_DSCR,
181 isi->active->p_dma_desc->fbd_phys);
182 isi_writel(isi, ISI_DMA_C_CTRL,
183 ISI_DMA_CTRL_FETCH | ISI_DMA_CTRL_DONE);
184 isi_writel(isi, ISI_DMA_CHER, ISI_DMA_CHSR_C_CH);
185 }
186 return IRQ_HANDLED;
187}
188
189/* ISI interrupt service routine */
190static irqreturn_t isi_interrupt(int irq, void *dev_id)
191{
192 struct atmel_isi *isi = dev_id;
193 u32 status, mask, pending;
194 irqreturn_t ret = IRQ_NONE;
195
196 spin_lock(&isi->lock);
197
198 status = isi_readl(isi, ISI_STATUS);
199 mask = isi_readl(isi, ISI_INTMASK);
200 pending = status & mask;
201
202 if (pending & ISI_CTRL_SRST) {
203 complete(&isi->complete);
204 isi_writel(isi, ISI_INTDIS, ISI_CTRL_SRST);
205 ret = IRQ_HANDLED;
206 } else if (pending & ISI_CTRL_DIS) {
207 complete(&isi->complete);
208 isi_writel(isi, ISI_INTDIS, ISI_CTRL_DIS);
209 ret = IRQ_HANDLED;
210 } else {
211 if ((pending & ISI_SR_VSYNC) &&
212 (isi->state == ISI_STATE_IDLE)) {
213 isi->state = ISI_STATE_READY;
214 wake_up_interruptible(&isi->vsync_wq);
215 ret = IRQ_HANDLED;
216 }
217 if (likely(pending & ISI_SR_CXFR_DONE))
218 ret = atmel_isi_handle_streaming(isi);
219 }
220
221 spin_unlock(&isi->lock);
222 return ret;
223}
224
225#define WAIT_ISI_RESET 1
226#define WAIT_ISI_DISABLE 0
227static int atmel_isi_wait_status(struct atmel_isi *isi, int wait_reset)
228{
229 unsigned long timeout;
230 /*
231 * The reset or disable will only succeed if we have a
232 * pixel clock from the camera.
233 */
234 init_completion(&isi->complete);
235
236 if (wait_reset) {
237 isi_writel(isi, ISI_INTEN, ISI_CTRL_SRST);
238 isi_writel(isi, ISI_CTRL, ISI_CTRL_SRST);
239 } else {
240 isi_writel(isi, ISI_INTEN, ISI_CTRL_DIS);
241 isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS);
242 }
243
244 timeout = wait_for_completion_timeout(&isi->complete,
245 msecs_to_jiffies(100));
246 if (timeout == 0)
247 return -ETIMEDOUT;
248
249 return 0;
250}
251
252/* ------------------------------------------------------------------
253 Videobuf operations
254 ------------------------------------------------------------------*/
255static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
256 unsigned int *nbuffers, unsigned int *nplanes,
257 unsigned int sizes[], void *alloc_ctxs[])
258{
259 struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
260 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
261 struct atmel_isi *isi = ici->priv;
262 unsigned long size;
263 int ret;
264
265 /* Reset ISI */
266 ret = atmel_isi_wait_status(isi, WAIT_ISI_RESET);
267 if (ret < 0) {
268 dev_err(icd->parent, "Reset ISI timed out\n");
269 return ret;
270 }
271 /* Disable all interrupts */
272 isi_writel(isi, ISI_INTDIS, ~0UL);
273
274 size = icd->sizeimage;
275
276 if (!*nbuffers || *nbuffers > MAX_BUFFER_NUM)
277 *nbuffers = MAX_BUFFER_NUM;
278
279 if (size * *nbuffers > VID_LIMIT_BYTES)
280 *nbuffers = VID_LIMIT_BYTES / size;
281
282 *nplanes = 1;
283 sizes[0] = size;
284 alloc_ctxs[0] = isi->alloc_ctx;
285
286 isi->sequence = 0;
287 isi->active = NULL;
288
289 dev_dbg(icd->parent, "%s, count=%d, size=%ld\n", __func__,
290 *nbuffers, size);
291
292 return 0;
293}
294
295static int buffer_init(struct vb2_buffer *vb)
296{
297 struct frame_buffer *buf = container_of(vb, struct frame_buffer, vb);
298
299 buf->p_dma_desc = NULL;
300 INIT_LIST_HEAD(&buf->list);
301
302 return 0;
303}
304
305static int buffer_prepare(struct vb2_buffer *vb)
306{
307 struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
308 struct frame_buffer *buf = container_of(vb, struct frame_buffer, vb);
309 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
310 struct atmel_isi *isi = ici->priv;
311 unsigned long size;
312 struct isi_dma_desc *desc;
313
314 size = icd->sizeimage;
315
316 if (vb2_plane_size(vb, 0) < size) {
317 dev_err(icd->parent, "%s data will not fit into plane (%lu < %lu)\n",
318 __func__, vb2_plane_size(vb, 0), size);
319 return -EINVAL;
320 }
321
322 vb2_set_plane_payload(&buf->vb, 0, size);
323
324 if (!buf->p_dma_desc) {
325 if (list_empty(&isi->dma_desc_head)) {
326 dev_err(icd->parent, "Not enough dma descriptors.\n");
327 return -EINVAL;
328 } else {
329 /* Get an available descriptor */
330 desc = list_entry(isi->dma_desc_head.next,
331 struct isi_dma_desc, list);
332 /* Delete the descriptor since now it is used */
333 list_del_init(&desc->list);
334
335 /* Initialize the dma descriptor */
336 desc->p_fbd->fb_address =
337 vb2_dma_contig_plane_dma_addr(vb, 0);
338 desc->p_fbd->next_fbd_address = 0;
339 set_dma_ctrl(desc->p_fbd, ISI_DMA_CTRL_WB);
340
341 buf->p_dma_desc = desc;
342 }
343 }
344 return 0;
345}
346
347static void buffer_cleanup(struct vb2_buffer *vb)
348{
349 struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
350 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
351 struct atmel_isi *isi = ici->priv;
352 struct frame_buffer *buf = container_of(vb, struct frame_buffer, vb);
353
354 /* This descriptor is available now and we add to head list */
355 if (buf->p_dma_desc)
356 list_add(&buf->p_dma_desc->list, &isi->dma_desc_head);
357}
358
359static void start_dma(struct atmel_isi *isi, struct frame_buffer *buffer)
360{
361 u32 ctrl, cfg1;
362
363 cfg1 = isi_readl(isi, ISI_CFG1);
364 /* Enable irq: cxfr for the codec path, pxfr for the preview path */
365 isi_writel(isi, ISI_INTEN,
366 ISI_SR_CXFR_DONE | ISI_SR_PXFR_DONE);
367
368 /* Check if already in a frame */
369 if (isi_readl(isi, ISI_STATUS) & ISI_CTRL_CDC) {
370 dev_err(isi->icd->parent, "Already in frame handling.\n");
371 return;
372 }
373
374 isi_writel(isi, ISI_DMA_C_DSCR, buffer->p_dma_desc->fbd_phys);
375 isi_writel(isi, ISI_DMA_C_CTRL, ISI_DMA_CTRL_FETCH | ISI_DMA_CTRL_DONE);
376 isi_writel(isi, ISI_DMA_CHER, ISI_DMA_CHSR_C_CH);
377
378 /* Enable linked list */
379 cfg1 |= isi->pdata->frate | ISI_CFG1_DISCR;
380
381 /* Enable codec path and ISI */
382 ctrl = ISI_CTRL_CDC | ISI_CTRL_EN;
383 isi_writel(isi, ISI_CTRL, ctrl);
384 isi_writel(isi, ISI_CFG1, cfg1);
385}
386
387static void buffer_queue(struct vb2_buffer *vb)
388{
389 struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
390 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
391 struct atmel_isi *isi = ici->priv;
392 struct frame_buffer *buf = container_of(vb, struct frame_buffer, vb);
393 unsigned long flags = 0;
394
395 spin_lock_irqsave(&isi->lock, flags);
396 list_add_tail(&buf->list, &isi->video_buffer_list);
397
398 if (isi->active == NULL) {
399 isi->active = buf;
400 if (vb2_is_streaming(vb->vb2_queue))
401 start_dma(isi, buf);
402 }
403 spin_unlock_irqrestore(&isi->lock, flags);
404}
405
406static int start_streaming(struct vb2_queue *vq, unsigned int count)
407{
408 struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
409 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
410 struct atmel_isi *isi = ici->priv;
411
412 u32 sr = 0;
413 int ret;
414
415 spin_lock_irq(&isi->lock);
416 isi->state = ISI_STATE_IDLE;
417 /* Clear any pending SOF interrupt */
418 sr = isi_readl(isi, ISI_STATUS);
419 /* Enable VSYNC interrupt for SOF */
420 isi_writel(isi, ISI_INTEN, ISI_SR_VSYNC);
421 isi_writel(isi, ISI_CTRL, ISI_CTRL_EN);
422 spin_unlock_irq(&isi->lock);
423
424 dev_dbg(icd->parent, "Waiting for SOF\n");
425 ret = wait_event_interruptible(isi->vsync_wq,
426 isi->state != ISI_STATE_IDLE);
427 if (ret)
428 goto err;
429
430 if (isi->state != ISI_STATE_READY) {
431 ret = -EIO;
432 goto err;
433 }
434
435 spin_lock_irq(&isi->lock);
436 isi->state = ISI_STATE_WAIT_SOF;
437 isi_writel(isi, ISI_INTDIS, ISI_SR_VSYNC);
438 if (count)
439 start_dma(isi, isi->active);
440 spin_unlock_irq(&isi->lock);
441
442 return 0;
443err:
444 isi->active = NULL;
445 isi->sequence = 0;
446 INIT_LIST_HEAD(&isi->video_buffer_list);
447 return ret;
448}
449
450/* abort streaming and wait for last buffer */
451static int stop_streaming(struct vb2_queue *vq)
452{
453 struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
454 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
455 struct atmel_isi *isi = ici->priv;
456 struct frame_buffer *buf, *node;
457 int ret = 0;
458 unsigned long timeout;
459
460 spin_lock_irq(&isi->lock);
461 isi->active = NULL;
462 /* Release all active buffers */
463 list_for_each_entry_safe(buf, node, &isi->video_buffer_list, list) {
464 list_del_init(&buf->list);
465 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
466 }
467 spin_unlock_irq(&isi->lock);
468
469 timeout = jiffies + FRAME_INTERVAL_MILLI_SEC * HZ;
470 /* Wait until the end of the current frame. */
471 while ((isi_readl(isi, ISI_STATUS) & ISI_CTRL_CDC) &&
472 time_before(jiffies, timeout))
473 msleep(1);
474
475 if (time_after(jiffies, timeout)) {
476 dev_err(icd->parent,
477 "Timeout waiting for finishing codec request\n");
478 return -ETIMEDOUT;
479 }
480
481 /* Disable interrupts */
482 isi_writel(isi, ISI_INTDIS,
483 ISI_SR_CXFR_DONE | ISI_SR_PXFR_DONE);
484
485 /* Disable ISI and wait for it is done */
486 ret = atmel_isi_wait_status(isi, WAIT_ISI_DISABLE);
487 if (ret < 0)
488 dev_err(icd->parent, "Disable ISI timed out\n");
489
490 return ret;
491}
492
493static struct vb2_ops isi_video_qops = {
494 .queue_setup = queue_setup,
495 .buf_init = buffer_init,
496 .buf_prepare = buffer_prepare,
497 .buf_cleanup = buffer_cleanup,
498 .buf_queue = buffer_queue,
499 .start_streaming = start_streaming,
500 .stop_streaming = stop_streaming,
501 .wait_prepare = soc_camera_unlock,
502 .wait_finish = soc_camera_lock,
503};
504
505/* ------------------------------------------------------------------
506 SOC camera operations for the device
507 ------------------------------------------------------------------*/
508static int isi_camera_init_videobuf(struct vb2_queue *q,
509 struct soc_camera_device *icd)
510{
511 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
512 q->io_modes = VB2_MMAP;
513 q->drv_priv = icd;
514 q->buf_struct_size = sizeof(struct frame_buffer);
515 q->ops = &isi_video_qops;
516 q->mem_ops = &vb2_dma_contig_memops;
517
518 return vb2_queue_init(q);
519}
520
521static int isi_camera_set_fmt(struct soc_camera_device *icd,
522 struct v4l2_format *f)
523{
524 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
525 struct atmel_isi *isi = ici->priv;
526 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
527 const struct soc_camera_format_xlate *xlate;
528 struct v4l2_pix_format *pix = &f->fmt.pix;
529 struct v4l2_mbus_framefmt mf;
530 int ret;
531
532 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
533 if (!xlate) {
534 dev_warn(icd->parent, "Format %x not found\n",
535 pix->pixelformat);
536 return -EINVAL;
537 }
538
539 dev_dbg(icd->parent, "Plan to set format %dx%d\n",
540 pix->width, pix->height);
541
542 mf.width = pix->width;
543 mf.height = pix->height;
544 mf.field = pix->field;
545 mf.colorspace = pix->colorspace;
546 mf.code = xlate->code;
547
548 ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
549 if (ret < 0)
550 return ret;
551
552 if (mf.code != xlate->code)
553 return -EINVAL;
554
555 ret = configure_geometry(isi, pix->width, pix->height, xlate->code);
556 if (ret < 0)
557 return ret;
558
559 pix->width = mf.width;
560 pix->height = mf.height;
561 pix->field = mf.field;
562 pix->colorspace = mf.colorspace;
563 icd->current_fmt = xlate;
564
565 dev_dbg(icd->parent, "Finally set format %dx%d\n",
566 pix->width, pix->height);
567
568 return ret;
569}
570
571static int isi_camera_try_fmt(struct soc_camera_device *icd,
572 struct v4l2_format *f)
573{
574 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
575 const struct soc_camera_format_xlate *xlate;
576 struct v4l2_pix_format *pix = &f->fmt.pix;
577 struct v4l2_mbus_framefmt mf;
578 u32 pixfmt = pix->pixelformat;
579 int ret;
580
581 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
582 if (pixfmt && !xlate) {
583 dev_warn(icd->parent, "Format %x not found\n", pixfmt);
584 return -EINVAL;
585 }
586
587 /* limit to Atmel ISI hardware capabilities */
588 if (pix->height > MAX_SUPPORT_HEIGHT)
589 pix->height = MAX_SUPPORT_HEIGHT;
590 if (pix->width > MAX_SUPPORT_WIDTH)
591 pix->width = MAX_SUPPORT_WIDTH;
592
593 /* limit to sensor capabilities */
594 mf.width = pix->width;
595 mf.height = pix->height;
596 mf.field = pix->field;
597 mf.colorspace = pix->colorspace;
598 mf.code = xlate->code;
599
600 ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
601 if (ret < 0)
602 return ret;
603
604 pix->width = mf.width;
605 pix->height = mf.height;
606 pix->colorspace = mf.colorspace;
607
608 switch (mf.field) {
609 case V4L2_FIELD_ANY:
610 pix->field = V4L2_FIELD_NONE;
611 break;
612 case V4L2_FIELD_NONE:
613 break;
614 default:
615 dev_err(icd->parent, "Field type %d unsupported.\n",
616 mf.field);
617 ret = -EINVAL;
618 }
619
620 return ret;
621}
622
623static const struct soc_mbus_pixelfmt isi_camera_formats[] = {
624 {
625 .fourcc = V4L2_PIX_FMT_YUYV,
626 .name = "Packed YUV422 16 bit",
627 .bits_per_sample = 8,
628 .packing = SOC_MBUS_PACKING_2X8_PADHI,
629 .order = SOC_MBUS_ORDER_LE,
630 .layout = SOC_MBUS_LAYOUT_PACKED,
631 },
632};
633
634/* This will be corrected as we get more formats */
635static bool isi_camera_packing_supported(const struct soc_mbus_pixelfmt *fmt)
636{
637 return fmt->packing == SOC_MBUS_PACKING_NONE ||
638 (fmt->bits_per_sample == 8 &&
639 fmt->packing == SOC_MBUS_PACKING_2X8_PADHI) ||
640 (fmt->bits_per_sample > 8 &&
641 fmt->packing == SOC_MBUS_PACKING_EXTEND16);
642}
643
644#define ISI_BUS_PARAM (V4L2_MBUS_MASTER | \
645 V4L2_MBUS_HSYNC_ACTIVE_HIGH | \
646 V4L2_MBUS_HSYNC_ACTIVE_LOW | \
647 V4L2_MBUS_VSYNC_ACTIVE_HIGH | \
648 V4L2_MBUS_VSYNC_ACTIVE_LOW | \
649 V4L2_MBUS_PCLK_SAMPLE_RISING | \
650 V4L2_MBUS_PCLK_SAMPLE_FALLING | \
651 V4L2_MBUS_DATA_ACTIVE_HIGH)
652
653static int isi_camera_try_bus_param(struct soc_camera_device *icd,
654 unsigned char buswidth)
655{
656 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
657 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
658 struct atmel_isi *isi = ici->priv;
659 struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
660 unsigned long common_flags;
661 int ret;
662
663 ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
664 if (!ret) {
665 common_flags = soc_mbus_config_compatible(&cfg,
666 ISI_BUS_PARAM);
667 if (!common_flags) {
668 dev_warn(icd->parent,
669 "Flags incompatible: camera 0x%x, host 0x%x\n",
670 cfg.flags, ISI_BUS_PARAM);
671 return -EINVAL;
672 }
673 } else if (ret != -ENOIOCTLCMD) {
674 return ret;
675 }
676
677 if ((1 << (buswidth - 1)) & isi->width_flags)
678 return 0;
679 return -EINVAL;
680}
681
682
683static int isi_camera_get_formats(struct soc_camera_device *icd,
684 unsigned int idx,
685 struct soc_camera_format_xlate *xlate)
686{
687 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
688 int formats = 0, ret;
689 /* sensor format */
690 enum v4l2_mbus_pixelcode code;
691 /* soc camera host format */
692 const struct soc_mbus_pixelfmt *fmt;
693
694 ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code);
695 if (ret < 0)
696 /* No more formats */
697 return 0;
698
699 fmt = soc_mbus_get_fmtdesc(code);
700 if (!fmt) {
701 dev_err(icd->parent,
702 "Invalid format code #%u: %d\n", idx, code);
703 return 0;
704 }
705
706 /* This also checks support for the requested bits-per-sample */
707 ret = isi_camera_try_bus_param(icd, fmt->bits_per_sample);
708 if (ret < 0) {
709 dev_err(icd->parent,
710 "Fail to try the bus parameters.\n");
711 return 0;
712 }
713
714 switch (code) {
715 case V4L2_MBUS_FMT_UYVY8_2X8:
716 case V4L2_MBUS_FMT_VYUY8_2X8:
717 case V4L2_MBUS_FMT_YUYV8_2X8:
718 case V4L2_MBUS_FMT_YVYU8_2X8:
719 formats++;
720 if (xlate) {
721 xlate->host_fmt = &isi_camera_formats[0];
722 xlate->code = code;
723 xlate++;
724 dev_dbg(icd->parent, "Providing format %s using code %d\n",
725 isi_camera_formats[0].name, code);
726 }
727 break;
728 default:
729 if (!isi_camera_packing_supported(fmt))
730 return 0;
731 if (xlate)
732 dev_dbg(icd->parent,
733 "Providing format %s in pass-through mode\n",
734 fmt->name);
735 }
736
737 /* Generic pass-through */
738 formats++;
739 if (xlate) {
740 xlate->host_fmt = fmt;
741 xlate->code = code;
742 xlate++;
743 }
744
745 return formats;
746}
747
748/* Called with .video_lock held */
749static int isi_camera_add_device(struct soc_camera_device *icd)
750{
751 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
752 struct atmel_isi *isi = ici->priv;
753 int ret;
754
755 if (isi->icd)
756 return -EBUSY;
757
758 ret = clk_enable(isi->pclk);
759 if (ret)
760 return ret;
761
762 ret = clk_enable(isi->mck);
763 if (ret) {
764 clk_disable(isi->pclk);
765 return ret;
766 }
767
768 isi->icd = icd;
769 dev_dbg(icd->parent, "Atmel ISI Camera driver attached to camera %d\n",
770 icd->devnum);
771 return 0;
772}
773/* Called with .video_lock held */
774static void isi_camera_remove_device(struct soc_camera_device *icd)
775{
776 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
777 struct atmel_isi *isi = ici->priv;
778
779 BUG_ON(icd != isi->icd);
780
781 clk_disable(isi->mck);
782 clk_disable(isi->pclk);
783 isi->icd = NULL;
784
785 dev_dbg(icd->parent, "Atmel ISI Camera driver detached from camera %d\n",
786 icd->devnum);
787}
788
789static unsigned int isi_camera_poll(struct file *file, poll_table *pt)
790{
791 struct soc_camera_device *icd = file->private_data;
792
793 return vb2_poll(&icd->vb2_vidq, file, pt);
794}
795
796static int isi_camera_querycap(struct soc_camera_host *ici,
797 struct v4l2_capability *cap)
798{
799 strcpy(cap->driver, "atmel-isi");
800 strcpy(cap->card, "Atmel Image Sensor Interface");
801 cap->capabilities = (V4L2_CAP_VIDEO_CAPTURE |
802 V4L2_CAP_STREAMING);
803 return 0;
804}
805
806static int isi_camera_set_bus_param(struct soc_camera_device *icd)
807{
808 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
809 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
810 struct atmel_isi *isi = ici->priv;
811 struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
812 unsigned long common_flags;
813 int ret;
814 u32 cfg1 = 0;
815
816 ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
817 if (!ret) {
818 common_flags = soc_mbus_config_compatible(&cfg,
819 ISI_BUS_PARAM);
820 if (!common_flags) {
821 dev_warn(icd->parent,
822 "Flags incompatible: camera 0x%x, host 0x%x\n",
823 cfg.flags, ISI_BUS_PARAM);
824 return -EINVAL;
825 }
826 } else if (ret != -ENOIOCTLCMD) {
827 return ret;
828 } else {
829 common_flags = ISI_BUS_PARAM;
830 }
831 dev_dbg(icd->parent, "Flags cam: 0x%x host: 0x%x common: 0x%lx\n",
832 cfg.flags, ISI_BUS_PARAM, common_flags);
833
834 /* Make choises, based on platform preferences */
835 if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) &&
836 (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) {
837 if (isi->pdata->hsync_act_low)
838 common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH;
839 else
840 common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW;
841 }
842
843 if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) &&
844 (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) {
845 if (isi->pdata->vsync_act_low)
846 common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH;
847 else
848 common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW;
849 }
850
851 if ((common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) &&
852 (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)) {
853 if (isi->pdata->pclk_act_falling)
854 common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_RISING;
855 else
856 common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_FALLING;
857 }
858
859 cfg.flags = common_flags;
860 ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
861 if (ret < 0 && ret != -ENOIOCTLCMD) {
862 dev_dbg(icd->parent, "camera s_mbus_config(0x%lx) returned %d\n",
863 common_flags, ret);
864 return ret;
865 }
866
867 /* set bus param for ISI */
868 if (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
869 cfg1 |= ISI_CFG1_HSYNC_POL_ACTIVE_LOW;
870 if (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
871 cfg1 |= ISI_CFG1_VSYNC_POL_ACTIVE_LOW;
872 if (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
873 cfg1 |= ISI_CFG1_PIXCLK_POL_ACTIVE_FALLING;
874
875 if (isi->pdata->has_emb_sync)
876 cfg1 |= ISI_CFG1_EMB_SYNC;
877 if (isi->pdata->full_mode)
878 cfg1 |= ISI_CFG1_FULL_MODE;
879
880 isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS);
881 isi_writel(isi, ISI_CFG1, cfg1);
882
883 return 0;
884}
885
886static struct soc_camera_host_ops isi_soc_camera_host_ops = {
887 .owner = THIS_MODULE,
888 .add = isi_camera_add_device,
889 .remove = isi_camera_remove_device,
890 .set_fmt = isi_camera_set_fmt,
891 .try_fmt = isi_camera_try_fmt,
892 .get_formats = isi_camera_get_formats,
893 .init_videobuf2 = isi_camera_init_videobuf,
894 .poll = isi_camera_poll,
895 .querycap = isi_camera_querycap,
896 .set_bus_param = isi_camera_set_bus_param,
897};
898
899/* -----------------------------------------------------------------------*/
900static int __devexit atmel_isi_remove(struct platform_device *pdev)
901{
902 struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev);
903 struct atmel_isi *isi = container_of(soc_host,
904 struct atmel_isi, soc_host);
905
906 free_irq(isi->irq, isi);
907 soc_camera_host_unregister(soc_host);
908 vb2_dma_contig_cleanup_ctx(isi->alloc_ctx);
909 dma_free_coherent(&pdev->dev,
910 sizeof(struct fbd) * MAX_BUFFER_NUM,
911 isi->p_fb_descriptors,
912 isi->fb_descriptors_phys);
913
914 iounmap(isi->regs);
915 clk_unprepare(isi->mck);
916 clk_put(isi->mck);
917 clk_unprepare(isi->pclk);
918 clk_put(isi->pclk);
919 kfree(isi);
920
921 return 0;
922}
923
924static int __devinit atmel_isi_probe(struct platform_device *pdev)
925{
926 unsigned int irq;
927 struct atmel_isi *isi;
928 struct clk *pclk;
929 struct resource *regs;
930 int ret, i;
931 struct device *dev = &pdev->dev;
932 struct soc_camera_host *soc_host;
933 struct isi_platform_data *pdata;
934
935 pdata = dev->platform_data;
936 if (!pdata || !pdata->data_width_flags || !pdata->mck_hz) {
937 dev_err(&pdev->dev,
938 "No config available for Atmel ISI\n");
939 return -EINVAL;
940 }
941
942 regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
943 if (!regs)
944 return -ENXIO;
945
946 pclk = clk_get(&pdev->dev, "isi_clk");
947 if (IS_ERR(pclk))
948 return PTR_ERR(pclk);
949
950 ret = clk_prepare(pclk);
951 if (ret)
952 goto err_clk_prepare_pclk;
953
954 isi = kzalloc(sizeof(struct atmel_isi), GFP_KERNEL);
955 if (!isi) {
956 ret = -ENOMEM;
957 dev_err(&pdev->dev, "Can't allocate interface!\n");
958 goto err_alloc_isi;
959 }
960
961 isi->pclk = pclk;
962 isi->pdata = pdata;
963 isi->active = NULL;
964 spin_lock_init(&isi->lock);
965 init_waitqueue_head(&isi->vsync_wq);
966 INIT_LIST_HEAD(&isi->video_buffer_list);
967 INIT_LIST_HEAD(&isi->dma_desc_head);
968
969 /* Get ISI_MCK, provided by programmable clock or external clock */
970 isi->mck = clk_get(dev, "isi_mck");
971 if (IS_ERR(isi->mck)) {
972 dev_err(dev, "Failed to get isi_mck\n");
973 ret = PTR_ERR(isi->mck);
974 goto err_clk_get;
975 }
976
977 ret = clk_prepare(isi->mck);
978 if (ret)
979 goto err_clk_prepare_mck;
980
981 /* Set ISI_MCK's frequency, it should be faster than pixel clock */
982 ret = clk_set_rate(isi->mck, pdata->mck_hz);
983 if (ret < 0)
984 goto err_set_mck_rate;
985
986 isi->p_fb_descriptors = dma_alloc_coherent(&pdev->dev,
987 sizeof(struct fbd) * MAX_BUFFER_NUM,
988 &isi->fb_descriptors_phys,
989 GFP_KERNEL);
990 if (!isi->p_fb_descriptors) {
991 ret = -ENOMEM;
992 dev_err(&pdev->dev, "Can't allocate descriptors!\n");
993 goto err_alloc_descriptors;
994 }
995
996 for (i = 0; i < MAX_BUFFER_NUM; i++) {
997 isi->dma_desc[i].p_fbd = isi->p_fb_descriptors + i;
998 isi->dma_desc[i].fbd_phys = isi->fb_descriptors_phys +
999 i * sizeof(struct fbd);
1000 list_add(&isi->dma_desc[i].list, &isi->dma_desc_head);
1001 }
1002
1003 isi->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
1004 if (IS_ERR(isi->alloc_ctx)) {
1005 ret = PTR_ERR(isi->alloc_ctx);
1006 goto err_alloc_ctx;
1007 }
1008
1009 isi->regs = ioremap(regs->start, resource_size(regs));
1010 if (!isi->regs) {
1011 ret = -ENOMEM;
1012 goto err_ioremap;
1013 }
1014
1015 if (pdata->data_width_flags & ISI_DATAWIDTH_8)
1016 isi->width_flags = 1 << 7;
1017 if (pdata->data_width_flags & ISI_DATAWIDTH_10)
1018 isi->width_flags |= 1 << 9;
1019
1020 isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS);
1021
1022 irq = platform_get_irq(pdev, 0);
1023 if (irq < 0) {
1024 ret = irq;
1025 goto err_req_irq;
1026 }
1027
1028 ret = request_irq(irq, isi_interrupt, 0, "isi", isi);
1029 if (ret) {
1030 dev_err(&pdev->dev, "Unable to request irq %d\n", irq);
1031 goto err_req_irq;
1032 }
1033 isi->irq = irq;
1034
1035 soc_host = &isi->soc_host;
1036 soc_host->drv_name = "isi-camera";
1037 soc_host->ops = &isi_soc_camera_host_ops;
1038 soc_host->priv = isi;
1039 soc_host->v4l2_dev.dev = &pdev->dev;
1040 soc_host->nr = pdev->id;
1041
1042 ret = soc_camera_host_register(soc_host);
1043 if (ret) {
1044 dev_err(&pdev->dev, "Unable to register soc camera host\n");
1045 goto err_register_soc_camera_host;
1046 }
1047 return 0;
1048
1049err_register_soc_camera_host:
1050 free_irq(isi->irq, isi);
1051err_req_irq:
1052 iounmap(isi->regs);
1053err_ioremap:
1054 vb2_dma_contig_cleanup_ctx(isi->alloc_ctx);
1055err_alloc_ctx:
1056 dma_free_coherent(&pdev->dev,
1057 sizeof(struct fbd) * MAX_BUFFER_NUM,
1058 isi->p_fb_descriptors,
1059 isi->fb_descriptors_phys);
1060err_alloc_descriptors:
1061err_set_mck_rate:
1062 clk_unprepare(isi->mck);
1063err_clk_prepare_mck:
1064 clk_put(isi->mck);
1065err_clk_get:
1066 kfree(isi);
1067err_alloc_isi:
1068 clk_unprepare(pclk);
1069err_clk_prepare_pclk:
1070 clk_put(pclk);
1071
1072 return ret;
1073}
1074
1075static struct platform_driver atmel_isi_driver = {
1076 .probe = atmel_isi_probe,
1077 .remove = __devexit_p(atmel_isi_remove),
1078 .driver = {
1079 .name = "atmel_isi",
1080 .owner = THIS_MODULE,
1081 },
1082};
1083
1084static int __init atmel_isi_init_module(void)
1085{
1086 return platform_driver_probe(&atmel_isi_driver, &atmel_isi_probe);
1087}
1088
1089static void __exit atmel_isi_exit(void)
1090{
1091 platform_driver_unregister(&atmel_isi_driver);
1092}
1093module_init(atmel_isi_init_module);
1094module_exit(atmel_isi_exit);
1095
1096MODULE_AUTHOR("Josh Wu <josh.wu@atmel.com>");
1097MODULE_DESCRIPTION("The V4L2 driver for Atmel Linux");
1098MODULE_LICENSE("GPL");
1099MODULE_SUPPORTED_DEVICE("video");
diff --git a/drivers/media/video/blackfin/Kconfig b/drivers/media/video/blackfin/Kconfig
deleted file mode 100644
index ecd5323768b7..000000000000
--- a/drivers/media/video/blackfin/Kconfig
+++ /dev/null
@@ -1,10 +0,0 @@
1config VIDEO_BLACKFIN_CAPTURE
2 tristate "Blackfin Video Capture Driver"
3 depends on VIDEO_V4L2 && BLACKFIN && I2C
4 select VIDEOBUF2_DMA_CONTIG
5 help
6 V4L2 bridge driver for Blackfin video capture device.
7 Choose PPI or EPPI as its interface.
8
9 To compile this driver as a module, choose M here: the
10 module will be called bfin_video_capture.
diff --git a/drivers/media/video/blackfin/Makefile b/drivers/media/video/blackfin/Makefile
deleted file mode 100644
index aa3a0a216387..000000000000
--- a/drivers/media/video/blackfin/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
1bfin_video_capture-objs := bfin_capture.o ppi.o
2obj-$(CONFIG_VIDEO_BLACKFIN_CAPTURE) += bfin_video_capture.o
diff --git a/drivers/media/video/blackfin/bfin_capture.c b/drivers/media/video/blackfin/bfin_capture.c
deleted file mode 100644
index 1677623d8296..000000000000
--- a/drivers/media/video/blackfin/bfin_capture.c
+++ /dev/null
@@ -1,1068 +0,0 @@
1/*
2 * Analog Devices video capture driver
3 *
4 * Copyright (c) 2011 Analog Devices Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20#include <linux/completion.h>
21#include <linux/delay.h>
22#include <linux/errno.h>
23#include <linux/fs.h>
24#include <linux/i2c.h>
25#include <linux/init.h>
26#include <linux/interrupt.h>
27#include <linux/io.h>
28#include <linux/mm.h>
29#include <linux/module.h>
30#include <linux/platform_device.h>
31#include <linux/slab.h>
32#include <linux/time.h>
33#include <linux/types.h>
34
35#include <media/v4l2-chip-ident.h>
36#include <media/v4l2-common.h>
37#include <media/v4l2-ctrls.h>
38#include <media/v4l2-device.h>
39#include <media/v4l2-ioctl.h>
40#include <media/videobuf2-dma-contig.h>
41
42#include <asm/dma.h>
43
44#include <media/blackfin/bfin_capture.h>
45#include <media/blackfin/ppi.h>
46
47#define CAPTURE_DRV_NAME "bfin_capture"
48#define BCAP_MIN_NUM_BUF 2
49
50struct bcap_format {
51 char *desc;
52 u32 pixelformat;
53 enum v4l2_mbus_pixelcode mbus_code;
54 int bpp; /* bits per pixel */
55};
56
57struct bcap_buffer {
58 struct vb2_buffer vb;
59 struct list_head list;
60};
61
62struct bcap_device {
63 /* capture device instance */
64 struct v4l2_device v4l2_dev;
65 /* v4l2 control handler */
66 struct v4l2_ctrl_handler ctrl_handler;
67 /* device node data */
68 struct video_device *video_dev;
69 /* sub device instance */
70 struct v4l2_subdev *sd;
71 /* capture config */
72 struct bfin_capture_config *cfg;
73 /* ppi interface */
74 struct ppi_if *ppi;
75 /* current input */
76 unsigned int cur_input;
77 /* current selected standard */
78 v4l2_std_id std;
79 /* used to store pixel format */
80 struct v4l2_pix_format fmt;
81 /* bits per pixel*/
82 int bpp;
83 /* used to store sensor supported format */
84 struct bcap_format *sensor_formats;
85 /* number of sensor formats array */
86 int num_sensor_formats;
87 /* pointing to current video buffer */
88 struct bcap_buffer *cur_frm;
89 /* pointing to next video buffer */
90 struct bcap_buffer *next_frm;
91 /* buffer queue used in videobuf2 */
92 struct vb2_queue buffer_queue;
93 /* allocator-specific contexts for each plane */
94 struct vb2_alloc_ctx *alloc_ctx;
95 /* queue of filled frames */
96 struct list_head dma_queue;
97 /* used in videobuf2 callback */
98 spinlock_t lock;
99 /* used to access capture device */
100 struct mutex mutex;
101 /* used to wait ppi to complete one transfer */
102 struct completion comp;
103 /* prepare to stop */
104 bool stop;
105};
106
107struct bcap_fh {
108 struct v4l2_fh fh;
109 /* indicates whether this file handle is doing IO */
110 bool io_allowed;
111};
112
113static const struct bcap_format bcap_formats[] = {
114 {
115 .desc = "YCbCr 4:2:2 Interleaved UYVY",
116 .pixelformat = V4L2_PIX_FMT_UYVY,
117 .mbus_code = V4L2_MBUS_FMT_UYVY8_2X8,
118 .bpp = 16,
119 },
120 {
121 .desc = "YCbCr 4:2:2 Interleaved YUYV",
122 .pixelformat = V4L2_PIX_FMT_YUYV,
123 .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8,
124 .bpp = 16,
125 },
126 {
127 .desc = "RGB 565",
128 .pixelformat = V4L2_PIX_FMT_RGB565,
129 .mbus_code = V4L2_MBUS_FMT_RGB565_2X8_LE,
130 .bpp = 16,
131 },
132 {
133 .desc = "RGB 444",
134 .pixelformat = V4L2_PIX_FMT_RGB444,
135 .mbus_code = V4L2_MBUS_FMT_RGB444_2X8_PADHI_LE,
136 .bpp = 16,
137 },
138
139};
140#define BCAP_MAX_FMTS ARRAY_SIZE(bcap_formats)
141
142static irqreturn_t bcap_isr(int irq, void *dev_id);
143
144static struct bcap_buffer *to_bcap_vb(struct vb2_buffer *vb)
145{
146 return container_of(vb, struct bcap_buffer, vb);
147}
148
149static int bcap_init_sensor_formats(struct bcap_device *bcap_dev)
150{
151 enum v4l2_mbus_pixelcode code;
152 struct bcap_format *sf;
153 unsigned int num_formats = 0;
154 int i, j;
155
156 while (!v4l2_subdev_call(bcap_dev->sd, video,
157 enum_mbus_fmt, num_formats, &code))
158 num_formats++;
159 if (!num_formats)
160 return -ENXIO;
161
162 sf = kzalloc(num_formats * sizeof(*sf), GFP_KERNEL);
163 if (!sf)
164 return -ENOMEM;
165
166 for (i = 0; i < num_formats; i++) {
167 v4l2_subdev_call(bcap_dev->sd, video,
168 enum_mbus_fmt, i, &code);
169 for (j = 0; j < BCAP_MAX_FMTS; j++)
170 if (code == bcap_formats[j].mbus_code)
171 break;
172 if (j == BCAP_MAX_FMTS) {
173 /* we don't allow this sensor working with our bridge */
174 kfree(sf);
175 return -EINVAL;
176 }
177 sf[i] = bcap_formats[j];
178 }
179 bcap_dev->sensor_formats = sf;
180 bcap_dev->num_sensor_formats = num_formats;
181 return 0;
182}
183
184static void bcap_free_sensor_formats(struct bcap_device *bcap_dev)
185{
186 bcap_dev->num_sensor_formats = 0;
187 kfree(bcap_dev->sensor_formats);
188 bcap_dev->sensor_formats = NULL;
189}
190
191static int bcap_open(struct file *file)
192{
193 struct bcap_device *bcap_dev = video_drvdata(file);
194 struct video_device *vfd = bcap_dev->video_dev;
195 struct bcap_fh *bcap_fh;
196
197 if (!bcap_dev->sd) {
198 v4l2_err(&bcap_dev->v4l2_dev, "No sub device registered\n");
199 return -ENODEV;
200 }
201
202 bcap_fh = kzalloc(sizeof(*bcap_fh), GFP_KERNEL);
203 if (!bcap_fh) {
204 v4l2_err(&bcap_dev->v4l2_dev,
205 "unable to allocate memory for file handle object\n");
206 return -ENOMEM;
207 }
208
209 v4l2_fh_init(&bcap_fh->fh, vfd);
210
211 /* store pointer to v4l2_fh in private_data member of file */
212 file->private_data = &bcap_fh->fh;
213 v4l2_fh_add(&bcap_fh->fh);
214 bcap_fh->io_allowed = false;
215 return 0;
216}
217
218static int bcap_release(struct file *file)
219{
220 struct bcap_device *bcap_dev = video_drvdata(file);
221 struct v4l2_fh *fh = file->private_data;
222 struct bcap_fh *bcap_fh = container_of(fh, struct bcap_fh, fh);
223
224 /* if this instance is doing IO */
225 if (bcap_fh->io_allowed)
226 vb2_queue_release(&bcap_dev->buffer_queue);
227
228 file->private_data = NULL;
229 v4l2_fh_del(&bcap_fh->fh);
230 v4l2_fh_exit(&bcap_fh->fh);
231 kfree(bcap_fh);
232 return 0;
233}
234
235static int bcap_mmap(struct file *file, struct vm_area_struct *vma)
236{
237 struct bcap_device *bcap_dev = video_drvdata(file);
238 int ret;
239
240 if (mutex_lock_interruptible(&bcap_dev->mutex))
241 return -ERESTARTSYS;
242 ret = vb2_mmap(&bcap_dev->buffer_queue, vma);
243 mutex_unlock(&bcap_dev->mutex);
244 return ret;
245}
246
247#ifndef CONFIG_MMU
248static unsigned long bcap_get_unmapped_area(struct file *file,
249 unsigned long addr,
250 unsigned long len,
251 unsigned long pgoff,
252 unsigned long flags)
253{
254 struct bcap_device *bcap_dev = video_drvdata(file);
255
256 return vb2_get_unmapped_area(&bcap_dev->buffer_queue,
257 addr,
258 len,
259 pgoff,
260 flags);
261}
262#endif
263
264static unsigned int bcap_poll(struct file *file, poll_table *wait)
265{
266 struct bcap_device *bcap_dev = video_drvdata(file);
267 unsigned int res;
268
269 mutex_lock(&bcap_dev->mutex);
270 res = vb2_poll(&bcap_dev->buffer_queue, file, wait);
271 mutex_unlock(&bcap_dev->mutex);
272 return res;
273}
274
275static int bcap_queue_setup(struct vb2_queue *vq,
276 const struct v4l2_format *fmt,
277 unsigned int *nbuffers, unsigned int *nplanes,
278 unsigned int sizes[], void *alloc_ctxs[])
279{
280 struct bcap_device *bcap_dev = vb2_get_drv_priv(vq);
281
282 if (*nbuffers < BCAP_MIN_NUM_BUF)
283 *nbuffers = BCAP_MIN_NUM_BUF;
284
285 *nplanes = 1;
286 sizes[0] = bcap_dev->fmt.sizeimage;
287 alloc_ctxs[0] = bcap_dev->alloc_ctx;
288
289 return 0;
290}
291
292static int bcap_buffer_init(struct vb2_buffer *vb)
293{
294 struct bcap_buffer *buf = to_bcap_vb(vb);
295
296 INIT_LIST_HEAD(&buf->list);
297 return 0;
298}
299
300static int bcap_buffer_prepare(struct vb2_buffer *vb)
301{
302 struct bcap_device *bcap_dev = vb2_get_drv_priv(vb->vb2_queue);
303 struct bcap_buffer *buf = to_bcap_vb(vb);
304 unsigned long size;
305
306 size = bcap_dev->fmt.sizeimage;
307 if (vb2_plane_size(vb, 0) < size) {
308 v4l2_err(&bcap_dev->v4l2_dev, "buffer too small (%lu < %lu)\n",
309 vb2_plane_size(vb, 0), size);
310 return -EINVAL;
311 }
312 vb2_set_plane_payload(&buf->vb, 0, size);
313
314 return 0;
315}
316
317static void bcap_buffer_queue(struct vb2_buffer *vb)
318{
319 struct bcap_device *bcap_dev = vb2_get_drv_priv(vb->vb2_queue);
320 struct bcap_buffer *buf = to_bcap_vb(vb);
321 unsigned long flags;
322
323 spin_lock_irqsave(&bcap_dev->lock, flags);
324 list_add_tail(&buf->list, &bcap_dev->dma_queue);
325 spin_unlock_irqrestore(&bcap_dev->lock, flags);
326}
327
328static void bcap_buffer_cleanup(struct vb2_buffer *vb)
329{
330 struct bcap_device *bcap_dev = vb2_get_drv_priv(vb->vb2_queue);
331 struct bcap_buffer *buf = to_bcap_vb(vb);
332 unsigned long flags;
333
334 spin_lock_irqsave(&bcap_dev->lock, flags);
335 list_del_init(&buf->list);
336 spin_unlock_irqrestore(&bcap_dev->lock, flags);
337}
338
339static void bcap_lock(struct vb2_queue *vq)
340{
341 struct bcap_device *bcap_dev = vb2_get_drv_priv(vq);
342 mutex_lock(&bcap_dev->mutex);
343}
344
345static void bcap_unlock(struct vb2_queue *vq)
346{
347 struct bcap_device *bcap_dev = vb2_get_drv_priv(vq);
348 mutex_unlock(&bcap_dev->mutex);
349}
350
351static int bcap_start_streaming(struct vb2_queue *vq, unsigned int count)
352{
353 struct bcap_device *bcap_dev = vb2_get_drv_priv(vq);
354 struct ppi_if *ppi = bcap_dev->ppi;
355 struct ppi_params params;
356 int ret;
357
358 /* enable streamon on the sub device */
359 ret = v4l2_subdev_call(bcap_dev->sd, video, s_stream, 1);
360 if (ret && (ret != -ENOIOCTLCMD)) {
361 v4l2_err(&bcap_dev->v4l2_dev, "stream on failed in subdev\n");
362 return ret;
363 }
364
365 /* set ppi params */
366 params.width = bcap_dev->fmt.width;
367 params.height = bcap_dev->fmt.height;
368 params.bpp = bcap_dev->bpp;
369 params.ppi_control = bcap_dev->cfg->ppi_control;
370 params.int_mask = bcap_dev->cfg->int_mask;
371 params.blank_clocks = bcap_dev->cfg->blank_clocks;
372 ret = ppi->ops->set_params(ppi, &params);
373 if (ret < 0) {
374 v4l2_err(&bcap_dev->v4l2_dev,
375 "Error in setting ppi params\n");
376 return ret;
377 }
378
379 /* attach ppi DMA irq handler */
380 ret = ppi->ops->attach_irq(ppi, bcap_isr);
381 if (ret < 0) {
382 v4l2_err(&bcap_dev->v4l2_dev,
383 "Error in attaching interrupt handler\n");
384 return ret;
385 }
386
387 INIT_COMPLETION(bcap_dev->comp);
388 bcap_dev->stop = false;
389 return 0;
390}
391
392static int bcap_stop_streaming(struct vb2_queue *vq)
393{
394 struct bcap_device *bcap_dev = vb2_get_drv_priv(vq);
395 struct ppi_if *ppi = bcap_dev->ppi;
396 int ret;
397
398 if (!vb2_is_streaming(vq))
399 return 0;
400
401 bcap_dev->stop = true;
402 wait_for_completion(&bcap_dev->comp);
403 ppi->ops->stop(ppi);
404 ppi->ops->detach_irq(ppi);
405 ret = v4l2_subdev_call(bcap_dev->sd, video, s_stream, 0);
406 if (ret && (ret != -ENOIOCTLCMD))
407 v4l2_err(&bcap_dev->v4l2_dev,
408 "stream off failed in subdev\n");
409
410 /* release all active buffers */
411 while (!list_empty(&bcap_dev->dma_queue)) {
412 bcap_dev->next_frm = list_entry(bcap_dev->dma_queue.next,
413 struct bcap_buffer, list);
414 list_del(&bcap_dev->next_frm->list);
415 vb2_buffer_done(&bcap_dev->next_frm->vb, VB2_BUF_STATE_ERROR);
416 }
417 return 0;
418}
419
420static struct vb2_ops bcap_video_qops = {
421 .queue_setup = bcap_queue_setup,
422 .buf_init = bcap_buffer_init,
423 .buf_prepare = bcap_buffer_prepare,
424 .buf_cleanup = bcap_buffer_cleanup,
425 .buf_queue = bcap_buffer_queue,
426 .wait_prepare = bcap_unlock,
427 .wait_finish = bcap_lock,
428 .start_streaming = bcap_start_streaming,
429 .stop_streaming = bcap_stop_streaming,
430};
431
432static int bcap_reqbufs(struct file *file, void *priv,
433 struct v4l2_requestbuffers *req_buf)
434{
435 struct bcap_device *bcap_dev = video_drvdata(file);
436 struct vb2_queue *vq = &bcap_dev->buffer_queue;
437 struct v4l2_fh *fh = file->private_data;
438 struct bcap_fh *bcap_fh = container_of(fh, struct bcap_fh, fh);
439
440 if (vb2_is_busy(vq))
441 return -EBUSY;
442
443 bcap_fh->io_allowed = true;
444
445 return vb2_reqbufs(vq, req_buf);
446}
447
448static int bcap_querybuf(struct file *file, void *priv,
449 struct v4l2_buffer *buf)
450{
451 struct bcap_device *bcap_dev = video_drvdata(file);
452
453 return vb2_querybuf(&bcap_dev->buffer_queue, buf);
454}
455
456static int bcap_qbuf(struct file *file, void *priv,
457 struct v4l2_buffer *buf)
458{
459 struct bcap_device *bcap_dev = video_drvdata(file);
460 struct v4l2_fh *fh = file->private_data;
461 struct bcap_fh *bcap_fh = container_of(fh, struct bcap_fh, fh);
462
463 if (!bcap_fh->io_allowed)
464 return -EBUSY;
465
466 return vb2_qbuf(&bcap_dev->buffer_queue, buf);
467}
468
469static int bcap_dqbuf(struct file *file, void *priv,
470 struct v4l2_buffer *buf)
471{
472 struct bcap_device *bcap_dev = video_drvdata(file);
473 struct v4l2_fh *fh = file->private_data;
474 struct bcap_fh *bcap_fh = container_of(fh, struct bcap_fh, fh);
475
476 if (!bcap_fh->io_allowed)
477 return -EBUSY;
478
479 return vb2_dqbuf(&bcap_dev->buffer_queue,
480 buf, file->f_flags & O_NONBLOCK);
481}
482
483static irqreturn_t bcap_isr(int irq, void *dev_id)
484{
485 struct ppi_if *ppi = dev_id;
486 struct bcap_device *bcap_dev = ppi->priv;
487 struct timeval timevalue;
488 struct vb2_buffer *vb = &bcap_dev->cur_frm->vb;
489 dma_addr_t addr;
490
491 spin_lock(&bcap_dev->lock);
492
493 if (bcap_dev->cur_frm != bcap_dev->next_frm) {
494 do_gettimeofday(&timevalue);
495 vb->v4l2_buf.timestamp = timevalue;
496 vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
497 bcap_dev->cur_frm = bcap_dev->next_frm;
498 }
499
500 ppi->ops->stop(ppi);
501
502 if (bcap_dev->stop) {
503 complete(&bcap_dev->comp);
504 } else {
505 if (!list_empty(&bcap_dev->dma_queue)) {
506 bcap_dev->next_frm = list_entry(bcap_dev->dma_queue.next,
507 struct bcap_buffer, list);
508 list_del(&bcap_dev->next_frm->list);
509 addr = vb2_dma_contig_plane_dma_addr(&bcap_dev->next_frm->vb, 0);
510 ppi->ops->update_addr(ppi, (unsigned long)addr);
511 }
512 ppi->ops->start(ppi);
513 }
514
515 spin_unlock(&bcap_dev->lock);
516
517 return IRQ_HANDLED;
518}
519
520static int bcap_streamon(struct file *file, void *priv,
521 enum v4l2_buf_type buf_type)
522{
523 struct bcap_device *bcap_dev = video_drvdata(file);
524 struct bcap_fh *fh = file->private_data;
525 struct ppi_if *ppi = bcap_dev->ppi;
526 dma_addr_t addr;
527 int ret;
528
529 if (!fh->io_allowed)
530 return -EBUSY;
531
532 /* call streamon to start streaming in videobuf */
533 ret = vb2_streamon(&bcap_dev->buffer_queue, buf_type);
534 if (ret)
535 return ret;
536
537 /* if dma queue is empty, return error */
538 if (list_empty(&bcap_dev->dma_queue)) {
539 v4l2_err(&bcap_dev->v4l2_dev, "dma queue is empty\n");
540 ret = -EINVAL;
541 goto err;
542 }
543
544 /* get the next frame from the dma queue */
545 bcap_dev->next_frm = list_entry(bcap_dev->dma_queue.next,
546 struct bcap_buffer, list);
547 bcap_dev->cur_frm = bcap_dev->next_frm;
548 /* remove buffer from the dma queue */
549 list_del(&bcap_dev->cur_frm->list);
550 addr = vb2_dma_contig_plane_dma_addr(&bcap_dev->cur_frm->vb, 0);
551 /* update DMA address */
552 ppi->ops->update_addr(ppi, (unsigned long)addr);
553 /* enable ppi */
554 ppi->ops->start(ppi);
555
556 return 0;
557err:
558 vb2_streamoff(&bcap_dev->buffer_queue, buf_type);
559 return ret;
560}
561
562static int bcap_streamoff(struct file *file, void *priv,
563 enum v4l2_buf_type buf_type)
564{
565 struct bcap_device *bcap_dev = video_drvdata(file);
566 struct bcap_fh *fh = file->private_data;
567
568 if (!fh->io_allowed)
569 return -EBUSY;
570
571 return vb2_streamoff(&bcap_dev->buffer_queue, buf_type);
572}
573
574static int bcap_querystd(struct file *file, void *priv, v4l2_std_id *std)
575{
576 struct bcap_device *bcap_dev = video_drvdata(file);
577
578 return v4l2_subdev_call(bcap_dev->sd, video, querystd, std);
579}
580
581static int bcap_g_std(struct file *file, void *priv, v4l2_std_id *std)
582{
583 struct bcap_device *bcap_dev = video_drvdata(file);
584
585 *std = bcap_dev->std;
586 return 0;
587}
588
589static int bcap_s_std(struct file *file, void *priv, v4l2_std_id *std)
590{
591 struct bcap_device *bcap_dev = video_drvdata(file);
592 int ret;
593
594 if (vb2_is_busy(&bcap_dev->buffer_queue))
595 return -EBUSY;
596
597 ret = v4l2_subdev_call(bcap_dev->sd, core, s_std, *std);
598 if (ret < 0)
599 return ret;
600
601 bcap_dev->std = *std;
602 return 0;
603}
604
605static int bcap_enum_input(struct file *file, void *priv,
606 struct v4l2_input *input)
607{
608 struct bcap_device *bcap_dev = video_drvdata(file);
609 struct bfin_capture_config *config = bcap_dev->cfg;
610 int ret;
611 u32 status;
612
613 if (input->index >= config->num_inputs)
614 return -EINVAL;
615
616 *input = config->inputs[input->index];
617 /* get input status */
618 ret = v4l2_subdev_call(bcap_dev->sd, video, g_input_status, &status);
619 if (!ret)
620 input->status = status;
621 return 0;
622}
623
624static int bcap_g_input(struct file *file, void *priv, unsigned int *index)
625{
626 struct bcap_device *bcap_dev = video_drvdata(file);
627
628 *index = bcap_dev->cur_input;
629 return 0;
630}
631
632static int bcap_s_input(struct file *file, void *priv, unsigned int index)
633{
634 struct bcap_device *bcap_dev = video_drvdata(file);
635 struct bfin_capture_config *config = bcap_dev->cfg;
636 struct bcap_route *route;
637 int ret;
638
639 if (vb2_is_busy(&bcap_dev->buffer_queue))
640 return -EBUSY;
641
642 if (index >= config->num_inputs)
643 return -EINVAL;
644
645 route = &config->routes[index];
646 ret = v4l2_subdev_call(bcap_dev->sd, video, s_routing,
647 route->input, route->output, 0);
648 if ((ret < 0) && (ret != -ENOIOCTLCMD)) {
649 v4l2_err(&bcap_dev->v4l2_dev, "Failed to set input\n");
650 return ret;
651 }
652 bcap_dev->cur_input = index;
653 return 0;
654}
655
656static int bcap_try_format(struct bcap_device *bcap,
657 struct v4l2_pix_format *pixfmt,
658 enum v4l2_mbus_pixelcode *mbus_code,
659 int *bpp)
660{
661 struct bcap_format *sf = bcap->sensor_formats;
662 struct bcap_format *fmt = NULL;
663 struct v4l2_mbus_framefmt mbus_fmt;
664 int ret, i;
665
666 for (i = 0; i < bcap->num_sensor_formats; i++) {
667 fmt = &sf[i];
668 if (pixfmt->pixelformat == fmt->pixelformat)
669 break;
670 }
671 if (i == bcap->num_sensor_formats)
672 fmt = &sf[0];
673
674 if (mbus_code)
675 *mbus_code = fmt->mbus_code;
676 if (bpp)
677 *bpp = fmt->bpp;
678 v4l2_fill_mbus_format(&mbus_fmt, pixfmt, fmt->mbus_code);
679 ret = v4l2_subdev_call(bcap->sd, video,
680 try_mbus_fmt, &mbus_fmt);
681 if (ret < 0)
682 return ret;
683 v4l2_fill_pix_format(pixfmt, &mbus_fmt);
684 pixfmt->bytesperline = pixfmt->width * fmt->bpp / 8;
685 pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height;
686 return 0;
687}
688
689static int bcap_enum_fmt_vid_cap(struct file *file, void *priv,
690 struct v4l2_fmtdesc *fmt)
691{
692 struct bcap_device *bcap_dev = video_drvdata(file);
693 struct bcap_format *sf = bcap_dev->sensor_formats;
694
695 if (fmt->index >= bcap_dev->num_sensor_formats)
696 return -EINVAL;
697
698 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
699 strlcpy(fmt->description,
700 sf[fmt->index].desc,
701 sizeof(fmt->description));
702 fmt->pixelformat = sf[fmt->index].pixelformat;
703 return 0;
704}
705
706static int bcap_try_fmt_vid_cap(struct file *file, void *priv,
707 struct v4l2_format *fmt)
708{
709 struct bcap_device *bcap_dev = video_drvdata(file);
710 struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
711
712 return bcap_try_format(bcap_dev, pixfmt, NULL, NULL);
713}
714
715static int bcap_g_fmt_vid_cap(struct file *file, void *priv,
716 struct v4l2_format *fmt)
717{
718 struct bcap_device *bcap_dev = video_drvdata(file);
719
720 fmt->fmt.pix = bcap_dev->fmt;
721 return 0;
722}
723
724static int bcap_s_fmt_vid_cap(struct file *file, void *priv,
725 struct v4l2_format *fmt)
726{
727 struct bcap_device *bcap_dev = video_drvdata(file);
728 struct v4l2_mbus_framefmt mbus_fmt;
729 enum v4l2_mbus_pixelcode mbus_code;
730 struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
731 int ret, bpp;
732
733 if (vb2_is_busy(&bcap_dev->buffer_queue))
734 return -EBUSY;
735
736 /* see if format works */
737 ret = bcap_try_format(bcap_dev, pixfmt, &mbus_code, &bpp);
738 if (ret < 0)
739 return ret;
740
741 v4l2_fill_mbus_format(&mbus_fmt, pixfmt, mbus_code);
742 ret = v4l2_subdev_call(bcap_dev->sd, video, s_mbus_fmt, &mbus_fmt);
743 if (ret < 0)
744 return ret;
745 bcap_dev->fmt = *pixfmt;
746 bcap_dev->bpp = bpp;
747 return 0;
748}
749
750static int bcap_querycap(struct file *file, void *priv,
751 struct v4l2_capability *cap)
752{
753 struct bcap_device *bcap_dev = video_drvdata(file);
754
755 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
756 strlcpy(cap->driver, CAPTURE_DRV_NAME, sizeof(cap->driver));
757 strlcpy(cap->bus_info, "Blackfin Platform", sizeof(cap->bus_info));
758 strlcpy(cap->card, bcap_dev->cfg->card_name, sizeof(cap->card));
759 return 0;
760}
761
762static int bcap_g_parm(struct file *file, void *fh,
763 struct v4l2_streamparm *a)
764{
765 struct bcap_device *bcap_dev = video_drvdata(file);
766
767 if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
768 return -EINVAL;
769 return v4l2_subdev_call(bcap_dev->sd, video, g_parm, a);
770}
771
772static int bcap_s_parm(struct file *file, void *fh,
773 struct v4l2_streamparm *a)
774{
775 struct bcap_device *bcap_dev = video_drvdata(file);
776
777 if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
778 return -EINVAL;
779 return v4l2_subdev_call(bcap_dev->sd, video, s_parm, a);
780}
781
782static int bcap_g_chip_ident(struct file *file, void *priv,
783 struct v4l2_dbg_chip_ident *chip)
784{
785 struct bcap_device *bcap_dev = video_drvdata(file);
786
787 chip->ident = V4L2_IDENT_NONE;
788 chip->revision = 0;
789 if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER &&
790 chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
791 return -EINVAL;
792
793 return v4l2_subdev_call(bcap_dev->sd, core,
794 g_chip_ident, chip);
795}
796
797#ifdef CONFIG_VIDEO_ADV_DEBUG
798static int bcap_dbg_g_register(struct file *file, void *priv,
799 struct v4l2_dbg_register *reg)
800{
801 struct bcap_device *bcap_dev = video_drvdata(file);
802
803 return v4l2_subdev_call(bcap_dev->sd, core,
804 g_register, reg);
805}
806
807static int bcap_dbg_s_register(struct file *file, void *priv,
808 struct v4l2_dbg_register *reg)
809{
810 struct bcap_device *bcap_dev = video_drvdata(file);
811
812 return v4l2_subdev_call(bcap_dev->sd, core,
813 s_register, reg);
814}
815#endif
816
817static int bcap_log_status(struct file *file, void *priv)
818{
819 struct bcap_device *bcap_dev = video_drvdata(file);
820 /* status for sub devices */
821 v4l2_device_call_all(&bcap_dev->v4l2_dev, 0, core, log_status);
822 return 0;
823}
824
825static const struct v4l2_ioctl_ops bcap_ioctl_ops = {
826 .vidioc_querycap = bcap_querycap,
827 .vidioc_g_fmt_vid_cap = bcap_g_fmt_vid_cap,
828 .vidioc_enum_fmt_vid_cap = bcap_enum_fmt_vid_cap,
829 .vidioc_s_fmt_vid_cap = bcap_s_fmt_vid_cap,
830 .vidioc_try_fmt_vid_cap = bcap_try_fmt_vid_cap,
831 .vidioc_enum_input = bcap_enum_input,
832 .vidioc_g_input = bcap_g_input,
833 .vidioc_s_input = bcap_s_input,
834 .vidioc_querystd = bcap_querystd,
835 .vidioc_s_std = bcap_s_std,
836 .vidioc_g_std = bcap_g_std,
837 .vidioc_reqbufs = bcap_reqbufs,
838 .vidioc_querybuf = bcap_querybuf,
839 .vidioc_qbuf = bcap_qbuf,
840 .vidioc_dqbuf = bcap_dqbuf,
841 .vidioc_streamon = bcap_streamon,
842 .vidioc_streamoff = bcap_streamoff,
843 .vidioc_g_parm = bcap_g_parm,
844 .vidioc_s_parm = bcap_s_parm,
845 .vidioc_g_chip_ident = bcap_g_chip_ident,
846#ifdef CONFIG_VIDEO_ADV_DEBUG
847 .vidioc_g_register = bcap_dbg_g_register,
848 .vidioc_s_register = bcap_dbg_s_register,
849#endif
850 .vidioc_log_status = bcap_log_status,
851};
852
853static struct v4l2_file_operations bcap_fops = {
854 .owner = THIS_MODULE,
855 .open = bcap_open,
856 .release = bcap_release,
857 .unlocked_ioctl = video_ioctl2,
858 .mmap = bcap_mmap,
859#ifndef CONFIG_MMU
860 .get_unmapped_area = bcap_get_unmapped_area,
861#endif
862 .poll = bcap_poll
863};
864
865static int __devinit bcap_probe(struct platform_device *pdev)
866{
867 struct bcap_device *bcap_dev;
868 struct video_device *vfd;
869 struct i2c_adapter *i2c_adap;
870 struct bfin_capture_config *config;
871 struct vb2_queue *q;
872 int ret;
873
874 config = pdev->dev.platform_data;
875 if (!config) {
876 v4l2_err(pdev->dev.driver, "Unable to get board config\n");
877 return -ENODEV;
878 }
879
880 bcap_dev = kzalloc(sizeof(*bcap_dev), GFP_KERNEL);
881 if (!bcap_dev) {
882 v4l2_err(pdev->dev.driver, "Unable to alloc bcap_dev\n");
883 return -ENOMEM;
884 }
885
886 bcap_dev->cfg = config;
887
888 bcap_dev->ppi = ppi_create_instance(config->ppi_info);
889 if (!bcap_dev->ppi) {
890 v4l2_err(pdev->dev.driver, "Unable to create ppi\n");
891 ret = -ENODEV;
892 goto err_free_dev;
893 }
894 bcap_dev->ppi->priv = bcap_dev;
895
896 bcap_dev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
897 if (IS_ERR(bcap_dev->alloc_ctx)) {
898 ret = PTR_ERR(bcap_dev->alloc_ctx);
899 goto err_free_ppi;
900 }
901
902 vfd = video_device_alloc();
903 if (!vfd) {
904 ret = -ENOMEM;
905 v4l2_err(pdev->dev.driver, "Unable to alloc video device\n");
906 goto err_cleanup_ctx;
907 }
908
909 /* initialize field of video device */
910 vfd->release = video_device_release;
911 vfd->fops = &bcap_fops;
912 vfd->ioctl_ops = &bcap_ioctl_ops;
913 vfd->tvnorms = 0;
914 vfd->v4l2_dev = &bcap_dev->v4l2_dev;
915 set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags);
916 strncpy(vfd->name, CAPTURE_DRV_NAME, sizeof(vfd->name));
917 bcap_dev->video_dev = vfd;
918
919 ret = v4l2_device_register(&pdev->dev, &bcap_dev->v4l2_dev);
920 if (ret) {
921 v4l2_err(pdev->dev.driver,
922 "Unable to register v4l2 device\n");
923 goto err_release_vdev;
924 }
925 v4l2_info(&bcap_dev->v4l2_dev, "v4l2 device registered\n");
926
927 bcap_dev->v4l2_dev.ctrl_handler = &bcap_dev->ctrl_handler;
928 ret = v4l2_ctrl_handler_init(&bcap_dev->ctrl_handler, 0);
929 if (ret) {
930 v4l2_err(&bcap_dev->v4l2_dev,
931 "Unable to init control handler\n");
932 goto err_unreg_v4l2;
933 }
934
935 spin_lock_init(&bcap_dev->lock);
936 /* initialize queue */
937 q = &bcap_dev->buffer_queue;
938 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
939 q->io_modes = VB2_MMAP;
940 q->drv_priv = bcap_dev;
941 q->buf_struct_size = sizeof(struct bcap_buffer);
942 q->ops = &bcap_video_qops;
943 q->mem_ops = &vb2_dma_contig_memops;
944
945 vb2_queue_init(q);
946
947 mutex_init(&bcap_dev->mutex);
948 init_completion(&bcap_dev->comp);
949
950 /* init video dma queues */
951 INIT_LIST_HEAD(&bcap_dev->dma_queue);
952
953 vfd->lock = &bcap_dev->mutex;
954
955 /* register video device */
956 ret = video_register_device(bcap_dev->video_dev, VFL_TYPE_GRABBER, -1);
957 if (ret) {
958 v4l2_err(&bcap_dev->v4l2_dev,
959 "Unable to register video device\n");
960 goto err_free_handler;
961 }
962 video_set_drvdata(bcap_dev->video_dev, bcap_dev);
963 v4l2_info(&bcap_dev->v4l2_dev, "video device registered as: %s\n",
964 video_device_node_name(vfd));
965
966 /* load up the subdevice */
967 i2c_adap = i2c_get_adapter(config->i2c_adapter_id);
968 if (!i2c_adap) {
969 v4l2_err(&bcap_dev->v4l2_dev,
970 "Unable to find i2c adapter\n");
971 goto err_unreg_vdev;
972
973 }
974 bcap_dev->sd = v4l2_i2c_new_subdev_board(&bcap_dev->v4l2_dev,
975 i2c_adap,
976 &config->board_info,
977 NULL);
978 if (bcap_dev->sd) {
979 int i;
980 /* update tvnorms from the sub devices */
981 for (i = 0; i < config->num_inputs; i++)
982 vfd->tvnorms |= config->inputs[i].std;
983 } else {
984 v4l2_err(&bcap_dev->v4l2_dev,
985 "Unable to register sub device\n");
986 goto err_unreg_vdev;
987 }
988
989 v4l2_info(&bcap_dev->v4l2_dev, "v4l2 sub device registered\n");
990
991 /* now we can probe the default state */
992 if (vfd->tvnorms) {
993 v4l2_std_id std;
994 ret = v4l2_subdev_call(bcap_dev->sd, core, g_std, &std);
995 if (ret) {
996 v4l2_err(&bcap_dev->v4l2_dev,
997 "Unable to get std\n");
998 goto err_unreg_vdev;
999 }
1000 bcap_dev->std = std;
1001 }
1002 ret = bcap_init_sensor_formats(bcap_dev);
1003 if (ret) {
1004 v4l2_err(&bcap_dev->v4l2_dev,
1005 "Unable to create sensor formats table\n");
1006 goto err_unreg_vdev;
1007 }
1008 return 0;
1009err_unreg_vdev:
1010 video_unregister_device(bcap_dev->video_dev);
1011 bcap_dev->video_dev = NULL;
1012err_free_handler:
1013 v4l2_ctrl_handler_free(&bcap_dev->ctrl_handler);
1014err_unreg_v4l2:
1015 v4l2_device_unregister(&bcap_dev->v4l2_dev);
1016err_release_vdev:
1017 if (bcap_dev->video_dev)
1018 video_device_release(bcap_dev->video_dev);
1019err_cleanup_ctx:
1020 vb2_dma_contig_cleanup_ctx(bcap_dev->alloc_ctx);
1021err_free_ppi:
1022 ppi_delete_instance(bcap_dev->ppi);
1023err_free_dev:
1024 kfree(bcap_dev);
1025 return ret;
1026}
1027
1028static int __devexit bcap_remove(struct platform_device *pdev)
1029{
1030 struct v4l2_device *v4l2_dev = platform_get_drvdata(pdev);
1031 struct bcap_device *bcap_dev = container_of(v4l2_dev,
1032 struct bcap_device, v4l2_dev);
1033
1034 bcap_free_sensor_formats(bcap_dev);
1035 video_unregister_device(bcap_dev->video_dev);
1036 v4l2_ctrl_handler_free(&bcap_dev->ctrl_handler);
1037 v4l2_device_unregister(v4l2_dev);
1038 vb2_dma_contig_cleanup_ctx(bcap_dev->alloc_ctx);
1039 ppi_delete_instance(bcap_dev->ppi);
1040 kfree(bcap_dev);
1041 return 0;
1042}
1043
1044static struct platform_driver bcap_driver = {
1045 .driver = {
1046 .name = CAPTURE_DRV_NAME,
1047 .owner = THIS_MODULE,
1048 },
1049 .probe = bcap_probe,
1050 .remove = __devexit_p(bcap_remove),
1051};
1052
1053static __init int bcap_init(void)
1054{
1055 return platform_driver_register(&bcap_driver);
1056}
1057
1058static __exit void bcap_exit(void)
1059{
1060 platform_driver_unregister(&bcap_driver);
1061}
1062
1063module_init(bcap_init);
1064module_exit(bcap_exit);
1065
1066MODULE_DESCRIPTION("Analog Devices blackfin video capture driver");
1067MODULE_AUTHOR("Scott Jiang <Scott.Jiang.Linux@gmail.com>");
1068MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/blackfin/ppi.c b/drivers/media/video/blackfin/ppi.c
deleted file mode 100644
index d29592186b02..000000000000
--- a/drivers/media/video/blackfin/ppi.c
+++ /dev/null
@@ -1,271 +0,0 @@
1/*
2 * ppi.c Analog Devices Parallel Peripheral Interface driver
3 *
4 * Copyright (c) 2011 Analog Devices Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20#include <linux/slab.h>
21
22#include <asm/bfin_ppi.h>
23#include <asm/blackfin.h>
24#include <asm/cacheflush.h>
25#include <asm/dma.h>
26#include <asm/portmux.h>
27
28#include <media/blackfin/ppi.h>
29
30static int ppi_attach_irq(struct ppi_if *ppi, irq_handler_t handler);
31static void ppi_detach_irq(struct ppi_if *ppi);
32static int ppi_start(struct ppi_if *ppi);
33static int ppi_stop(struct ppi_if *ppi);
34static int ppi_set_params(struct ppi_if *ppi, struct ppi_params *params);
35static void ppi_update_addr(struct ppi_if *ppi, unsigned long addr);
36
37static const struct ppi_ops ppi_ops = {
38 .attach_irq = ppi_attach_irq,
39 .detach_irq = ppi_detach_irq,
40 .start = ppi_start,
41 .stop = ppi_stop,
42 .set_params = ppi_set_params,
43 .update_addr = ppi_update_addr,
44};
45
46static irqreturn_t ppi_irq_err(int irq, void *dev_id)
47{
48 struct ppi_if *ppi = dev_id;
49 const struct ppi_info *info = ppi->info;
50
51 switch (info->type) {
52 case PPI_TYPE_PPI:
53 {
54 struct bfin_ppi_regs *reg = info->base;
55 unsigned short status;
56
57 /* register on bf561 is cleared when read
58 * others are W1C
59 */
60 status = bfin_read16(&reg->status);
61 bfin_write16(&reg->status, 0xff00);
62 break;
63 }
64 case PPI_TYPE_EPPI:
65 {
66 struct bfin_eppi_regs *reg = info->base;
67 bfin_write16(&reg->status, 0xffff);
68 break;
69 }
70 default:
71 break;
72 }
73
74 return IRQ_HANDLED;
75}
76
77static int ppi_attach_irq(struct ppi_if *ppi, irq_handler_t handler)
78{
79 const struct ppi_info *info = ppi->info;
80 int ret;
81
82 ret = request_dma(info->dma_ch, "PPI_DMA");
83
84 if (ret) {
85 pr_err("Unable to allocate DMA channel for PPI\n");
86 return ret;
87 }
88 set_dma_callback(info->dma_ch, handler, ppi);
89
90 if (ppi->err_int) {
91 ret = request_irq(info->irq_err, ppi_irq_err, 0, "PPI ERROR", ppi);
92 if (ret) {
93 pr_err("Unable to allocate IRQ for PPI\n");
94 free_dma(info->dma_ch);
95 }
96 }
97 return ret;
98}
99
100static void ppi_detach_irq(struct ppi_if *ppi)
101{
102 const struct ppi_info *info = ppi->info;
103
104 if (ppi->err_int)
105 free_irq(info->irq_err, ppi);
106 free_dma(info->dma_ch);
107}
108
109static int ppi_start(struct ppi_if *ppi)
110{
111 const struct ppi_info *info = ppi->info;
112
113 /* enable DMA */
114 enable_dma(info->dma_ch);
115
116 /* enable PPI */
117 ppi->ppi_control |= PORT_EN;
118 switch (info->type) {
119 case PPI_TYPE_PPI:
120 {
121 struct bfin_ppi_regs *reg = info->base;
122 bfin_write16(&reg->control, ppi->ppi_control);
123 break;
124 }
125 case PPI_TYPE_EPPI:
126 {
127 struct bfin_eppi_regs *reg = info->base;
128 bfin_write32(&reg->control, ppi->ppi_control);
129 break;
130 }
131 default:
132 return -EINVAL;
133 }
134
135 SSYNC();
136 return 0;
137}
138
139static int ppi_stop(struct ppi_if *ppi)
140{
141 const struct ppi_info *info = ppi->info;
142
143 /* disable PPI */
144 ppi->ppi_control &= ~PORT_EN;
145 switch (info->type) {
146 case PPI_TYPE_PPI:
147 {
148 struct bfin_ppi_regs *reg = info->base;
149 bfin_write16(&reg->control, ppi->ppi_control);
150 break;
151 }
152 case PPI_TYPE_EPPI:
153 {
154 struct bfin_eppi_regs *reg = info->base;
155 bfin_write32(&reg->control, ppi->ppi_control);
156 break;
157 }
158 default:
159 return -EINVAL;
160 }
161
162 /* disable DMA */
163 clear_dma_irqstat(info->dma_ch);
164 disable_dma(info->dma_ch);
165
166 SSYNC();
167 return 0;
168}
169
170static int ppi_set_params(struct ppi_if *ppi, struct ppi_params *params)
171{
172 const struct ppi_info *info = ppi->info;
173 int dma32 = 0;
174 int dma_config, bytes_per_line, lines_per_frame;
175
176 bytes_per_line = params->width * params->bpp / 8;
177 lines_per_frame = params->height;
178 if (params->int_mask == 0xFFFFFFFF)
179 ppi->err_int = false;
180 else
181 ppi->err_int = true;
182
183 dma_config = (DMA_FLOW_STOP | WNR | RESTART | DMA2D | DI_EN);
184 ppi->ppi_control = params->ppi_control & ~PORT_EN;
185 switch (info->type) {
186 case PPI_TYPE_PPI:
187 {
188 struct bfin_ppi_regs *reg = info->base;
189
190 if (params->ppi_control & DMA32)
191 dma32 = 1;
192
193 bfin_write16(&reg->control, ppi->ppi_control);
194 bfin_write16(&reg->count, bytes_per_line - 1);
195 bfin_write16(&reg->frame, lines_per_frame);
196 break;
197 }
198 case PPI_TYPE_EPPI:
199 {
200 struct bfin_eppi_regs *reg = info->base;
201
202 if ((params->ppi_control & PACK_EN)
203 || (params->ppi_control & 0x38000) > DLEN_16)
204 dma32 = 1;
205
206 bfin_write32(&reg->control, ppi->ppi_control);
207 bfin_write16(&reg->line, bytes_per_line + params->blank_clocks);
208 bfin_write16(&reg->frame, lines_per_frame);
209 bfin_write16(&reg->hdelay, 0);
210 bfin_write16(&reg->vdelay, 0);
211 bfin_write16(&reg->hcount, bytes_per_line);
212 bfin_write16(&reg->vcount, lines_per_frame);
213 break;
214 }
215 default:
216 return -EINVAL;
217 }
218
219 if (dma32) {
220 dma_config |= WDSIZE_32;
221 set_dma_x_count(info->dma_ch, bytes_per_line >> 2);
222 set_dma_x_modify(info->dma_ch, 4);
223 set_dma_y_modify(info->dma_ch, 4);
224 } else {
225 dma_config |= WDSIZE_16;
226 set_dma_x_count(info->dma_ch, bytes_per_line >> 1);
227 set_dma_x_modify(info->dma_ch, 2);
228 set_dma_y_modify(info->dma_ch, 2);
229 }
230 set_dma_y_count(info->dma_ch, lines_per_frame);
231 set_dma_config(info->dma_ch, dma_config);
232
233 SSYNC();
234 return 0;
235}
236
237static void ppi_update_addr(struct ppi_if *ppi, unsigned long addr)
238{
239 set_dma_start_addr(ppi->info->dma_ch, addr);
240}
241
242struct ppi_if *ppi_create_instance(const struct ppi_info *info)
243{
244 struct ppi_if *ppi;
245
246 if (!info || !info->pin_req)
247 return NULL;
248
249 if (peripheral_request_list(info->pin_req, KBUILD_MODNAME)) {
250 pr_err("request peripheral failed\n");
251 return NULL;
252 }
253
254 ppi = kzalloc(sizeof(*ppi), GFP_KERNEL);
255 if (!ppi) {
256 peripheral_free_list(info->pin_req);
257 pr_err("unable to allocate memory for ppi handle\n");
258 return NULL;
259 }
260 ppi->ops = &ppi_ops;
261 ppi->info = info;
262
263 pr_info("ppi probe success\n");
264 return ppi;
265}
266
267void ppi_delete_instance(struct ppi_if *ppi)
268{
269 peripheral_free_list(ppi->info->pin_req);
270 kfree(ppi);
271}
diff --git a/drivers/media/video/coda.c b/drivers/media/video/coda.c
deleted file mode 100644
index 0d6e0a095607..000000000000
--- a/drivers/media/video/coda.c
+++ /dev/null
@@ -1,1849 +0,0 @@
1/*
2 * Coda multi-standard codec IP
3 *
4 * Copyright (C) 2012 Vista Silicon S.L.
5 * Javier Martin, <javier.martin@vista-silicon.com>
6 * Xavier Duret
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 */
13
14#include <linux/clk.h>
15#include <linux/delay.h>
16#include <linux/firmware.h>
17#include <linux/interrupt.h>
18#include <linux/io.h>
19#include <linux/irq.h>
20#include <linux/module.h>
21#include <linux/of_device.h>
22#include <linux/platform_device.h>
23#include <linux/slab.h>
24#include <linux/videodev2.h>
25#include <linux/of.h>
26
27#include <media/v4l2-ctrls.h>
28#include <media/v4l2-device.h>
29#include <media/v4l2-ioctl.h>
30#include <media/v4l2-mem2mem.h>
31#include <media/videobuf2-core.h>
32#include <media/videobuf2-dma-contig.h>
33
34#include "coda.h"
35
36#define CODA_NAME "coda"
37
38#define CODA_MAX_INSTANCES 4
39
40#define CODA_FMO_BUF_SIZE 32
41#define CODADX6_WORK_BUF_SIZE (288 * 1024 + CODA_FMO_BUF_SIZE * 8 * 1024)
42#define CODA7_WORK_BUF_SIZE (512 * 1024 + CODA_FMO_BUF_SIZE * 8 * 1024)
43#define CODA_PARA_BUF_SIZE (10 * 1024)
44#define CODA_ISRAM_SIZE (2048 * 2)
45
46#define CODA_OUTPUT_BUFS 4
47#define CODA_CAPTURE_BUFS 2
48
49#define MAX_W 720
50#define MAX_H 576
51#define CODA_MAX_FRAME_SIZE 0x90000
52#define FMO_SLICE_SAVE_BUF_SIZE (32)
53#define CODA_DEFAULT_GAMMA 4096
54
55#define MIN_W 176
56#define MIN_H 144
57#define MAX_W 720
58#define MAX_H 576
59
60#define S_ALIGN 1 /* multiple of 2 */
61#define W_ALIGN 1 /* multiple of 2 */
62#define H_ALIGN 1 /* multiple of 2 */
63
64#define fh_to_ctx(__fh) container_of(__fh, struct coda_ctx, fh)
65
66static int coda_debug;
67module_param(coda_debug, int, 0);
68MODULE_PARM_DESC(coda_debug, "Debug level (0-1)");
69
70enum {
71 V4L2_M2M_SRC = 0,
72 V4L2_M2M_DST = 1,
73};
74
75enum coda_fmt_type {
76 CODA_FMT_ENC,
77 CODA_FMT_RAW,
78};
79
80enum coda_inst_type {
81 CODA_INST_ENCODER,
82 CODA_INST_DECODER,
83};
84
85enum coda_product {
86 CODA_DX6 = 0xf001,
87};
88
89struct coda_fmt {
90 char *name;
91 u32 fourcc;
92 enum coda_fmt_type type;
93};
94
95struct coda_devtype {
96 char *firmware;
97 enum coda_product product;
98 struct coda_fmt *formats;
99 unsigned int num_formats;
100 size_t workbuf_size;
101};
102
103/* Per-queue, driver-specific private data */
104struct coda_q_data {
105 unsigned int width;
106 unsigned int height;
107 unsigned int sizeimage;
108 struct coda_fmt *fmt;
109};
110
111struct coda_aux_buf {
112 void *vaddr;
113 dma_addr_t paddr;
114 u32 size;
115};
116
117struct coda_dev {
118 struct v4l2_device v4l2_dev;
119 struct video_device vfd;
120 struct platform_device *plat_dev;
121 struct coda_devtype *devtype;
122
123 void __iomem *regs_base;
124 struct clk *clk_per;
125 struct clk *clk_ahb;
126
127 struct coda_aux_buf codebuf;
128 struct coda_aux_buf workbuf;
129
130 spinlock_t irqlock;
131 struct mutex dev_mutex;
132 struct v4l2_m2m_dev *m2m_dev;
133 struct vb2_alloc_ctx *alloc_ctx;
134 int instances;
135};
136
137struct coda_params {
138 u8 h264_intra_qp;
139 u8 h264_inter_qp;
140 u8 mpeg4_intra_qp;
141 u8 mpeg4_inter_qp;
142 u8 gop_size;
143 int codec_mode;
144 enum v4l2_mpeg_video_multi_slice_mode slice_mode;
145 u32 framerate;
146 u16 bitrate;
147 u32 slice_max_mb;
148};
149
150struct coda_ctx {
151 struct coda_dev *dev;
152 int aborting;
153 int rawstreamon;
154 int compstreamon;
155 u32 isequence;
156 struct coda_q_data q_data[2];
157 enum coda_inst_type inst_type;
158 enum v4l2_colorspace colorspace;
159 struct coda_params params;
160 struct v4l2_m2m_ctx *m2m_ctx;
161 struct v4l2_ctrl_handler ctrls;
162 struct v4l2_fh fh;
163 struct vb2_buffer *reference;
164 int gopcounter;
165 char vpu_header[3][64];
166 int vpu_header_size[3];
167 struct coda_aux_buf parabuf;
168 int idx;
169};
170
171static inline void coda_write(struct coda_dev *dev, u32 data, u32 reg)
172{
173 v4l2_dbg(1, coda_debug, &dev->v4l2_dev,
174 "%s: data=0x%x, reg=0x%x\n", __func__, data, reg);
175 writel(data, dev->regs_base + reg);
176}
177
178static inline unsigned int coda_read(struct coda_dev *dev, u32 reg)
179{
180 u32 data;
181 data = readl(dev->regs_base + reg);
182 v4l2_dbg(1, coda_debug, &dev->v4l2_dev,
183 "%s: data=0x%x, reg=0x%x\n", __func__, data, reg);
184 return data;
185}
186
187static inline unsigned long coda_isbusy(struct coda_dev *dev)
188{
189 return coda_read(dev, CODA_REG_BIT_BUSY);
190}
191
192static inline int coda_is_initialized(struct coda_dev *dev)
193{
194 return (coda_read(dev, CODA_REG_BIT_CUR_PC) != 0);
195}
196
197static int coda_wait_timeout(struct coda_dev *dev)
198{
199 unsigned long timeout = jiffies + msecs_to_jiffies(1000);
200
201 while (coda_isbusy(dev)) {
202 if (time_after(jiffies, timeout))
203 return -ETIMEDOUT;
204 }
205 return 0;
206}
207
208static void coda_command_async(struct coda_ctx *ctx, int cmd)
209{
210 struct coda_dev *dev = ctx->dev;
211 coda_write(dev, CODA_REG_BIT_BUSY_FLAG, CODA_REG_BIT_BUSY);
212
213 coda_write(dev, ctx->idx, CODA_REG_BIT_RUN_INDEX);
214 coda_write(dev, ctx->params.codec_mode, CODA_REG_BIT_RUN_COD_STD);
215 coda_write(dev, cmd, CODA_REG_BIT_RUN_COMMAND);
216}
217
218static int coda_command_sync(struct coda_ctx *ctx, int cmd)
219{
220 struct coda_dev *dev = ctx->dev;
221
222 coda_command_async(ctx, cmd);
223 return coda_wait_timeout(dev);
224}
225
226static struct coda_q_data *get_q_data(struct coda_ctx *ctx,
227 enum v4l2_buf_type type)
228{
229 switch (type) {
230 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
231 return &(ctx->q_data[V4L2_M2M_SRC]);
232 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
233 return &(ctx->q_data[V4L2_M2M_DST]);
234 default:
235 BUG();
236 }
237 return NULL;
238}
239
240/*
241 * Add one array of supported formats for each version of Coda:
242 * i.MX27 -> codadx6
243 * i.MX51 -> coda7
244 * i.MX6 -> coda960
245 */
246static struct coda_fmt codadx6_formats[] = {
247 {
248 .name = "YUV 4:2:0 Planar",
249 .fourcc = V4L2_PIX_FMT_YUV420,
250 .type = CODA_FMT_RAW,
251 },
252 {
253 .name = "H264 Encoded Stream",
254 .fourcc = V4L2_PIX_FMT_H264,
255 .type = CODA_FMT_ENC,
256 },
257 {
258 .name = "MPEG4 Encoded Stream",
259 .fourcc = V4L2_PIX_FMT_MPEG4,
260 .type = CODA_FMT_ENC,
261 },
262};
263
264static struct coda_fmt *find_format(struct coda_dev *dev, struct v4l2_format *f)
265{
266 struct coda_fmt *formats = dev->devtype->formats;
267 int num_formats = dev->devtype->num_formats;
268 unsigned int k;
269
270 for (k = 0; k < num_formats; k++) {
271 if (formats[k].fourcc == f->fmt.pix.pixelformat)
272 break;
273 }
274
275 if (k == num_formats)
276 return NULL;
277
278 return &formats[k];
279}
280
281/*
282 * V4L2 ioctl() operations.
283 */
284static int vidioc_querycap(struct file *file, void *priv,
285 struct v4l2_capability *cap)
286{
287 strlcpy(cap->driver, CODA_NAME, sizeof(cap->driver));
288 strlcpy(cap->card, CODA_NAME, sizeof(cap->card));
289 strlcpy(cap->bus_info, CODA_NAME, sizeof(cap->bus_info));
290 cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT
291 | V4L2_CAP_STREAMING;
292 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
293
294 return 0;
295}
296
297static int enum_fmt(void *priv, struct v4l2_fmtdesc *f,
298 enum coda_fmt_type type)
299{
300 struct coda_ctx *ctx = fh_to_ctx(priv);
301 struct coda_dev *dev = ctx->dev;
302 struct coda_fmt *formats = dev->devtype->formats;
303 struct coda_fmt *fmt;
304 int num_formats = dev->devtype->num_formats;
305 int i, num = 0;
306
307 for (i = 0; i < num_formats; i++) {
308 if (formats[i].type == type) {
309 if (num == f->index)
310 break;
311 ++num;
312 }
313 }
314
315 if (i < num_formats) {
316 fmt = &formats[i];
317 strlcpy(f->description, fmt->name, sizeof(f->description));
318 f->pixelformat = fmt->fourcc;
319 return 0;
320 }
321
322 /* Format not found */
323 return -EINVAL;
324}
325
326static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
327 struct v4l2_fmtdesc *f)
328{
329 return enum_fmt(priv, f, CODA_FMT_ENC);
330}
331
332static int vidioc_enum_fmt_vid_out(struct file *file, void *priv,
333 struct v4l2_fmtdesc *f)
334{
335 return enum_fmt(priv, f, CODA_FMT_RAW);
336}
337
338static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
339{
340 struct vb2_queue *vq;
341 struct coda_q_data *q_data;
342 struct coda_ctx *ctx = fh_to_ctx(priv);
343
344 vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
345 if (!vq)
346 return -EINVAL;
347
348 q_data = get_q_data(ctx, f->type);
349
350 f->fmt.pix.field = V4L2_FIELD_NONE;
351 f->fmt.pix.pixelformat = q_data->fmt->fourcc;
352 f->fmt.pix.width = q_data->width;
353 f->fmt.pix.height = q_data->height;
354 if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUV420)
355 f->fmt.pix.bytesperline = round_up(f->fmt.pix.width, 2);
356 else /* encoded formats h.264/mpeg4 */
357 f->fmt.pix.bytesperline = 0;
358
359 f->fmt.pix.sizeimage = q_data->sizeimage;
360 f->fmt.pix.colorspace = ctx->colorspace;
361
362 return 0;
363}
364
365static int vidioc_try_fmt(struct coda_dev *dev, struct v4l2_format *f)
366{
367 enum v4l2_field field;
368
369 field = f->fmt.pix.field;
370 if (field == V4L2_FIELD_ANY)
371 field = V4L2_FIELD_NONE;
372 else if (V4L2_FIELD_NONE != field)
373 return -EINVAL;
374
375 /* V4L2 specification suggests the driver corrects the format struct
376 * if any of the dimensions is unsupported */
377 f->fmt.pix.field = field;
378
379 if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUV420) {
380 v4l_bound_align_image(&f->fmt.pix.width, MIN_W, MAX_W,
381 W_ALIGN, &f->fmt.pix.height,
382 MIN_H, MAX_H, H_ALIGN, S_ALIGN);
383 f->fmt.pix.bytesperline = round_up(f->fmt.pix.width, 2);
384 f->fmt.pix.sizeimage = f->fmt.pix.height *
385 f->fmt.pix.bytesperline;
386 } else { /*encoded formats h.264/mpeg4 */
387 f->fmt.pix.bytesperline = 0;
388 f->fmt.pix.sizeimage = CODA_MAX_FRAME_SIZE;
389 }
390
391 return 0;
392}
393
394static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
395 struct v4l2_format *f)
396{
397 int ret;
398 struct coda_fmt *fmt;
399 struct coda_ctx *ctx = fh_to_ctx(priv);
400
401 fmt = find_format(ctx->dev, f);
402 /*
403 * Since decoding support is not implemented yet do not allow
404 * CODA_FMT_RAW formats in the capture interface.
405 */
406 if (!fmt || !(fmt->type == CODA_FMT_ENC))
407 f->fmt.pix.pixelformat = V4L2_PIX_FMT_H264;
408
409 f->fmt.pix.colorspace = ctx->colorspace;
410
411 ret = vidioc_try_fmt(ctx->dev, f);
412 if (ret < 0)
413 return ret;
414
415 return 0;
416}
417
418static int vidioc_try_fmt_vid_out(struct file *file, void *priv,
419 struct v4l2_format *f)
420{
421 struct coda_ctx *ctx = fh_to_ctx(priv);
422 struct coda_fmt *fmt;
423 int ret;
424
425 fmt = find_format(ctx->dev, f);
426 /*
427 * Since decoding support is not implemented yet do not allow
428 * CODA_FMT formats in the capture interface.
429 */
430 if (!fmt || !(fmt->type == CODA_FMT_RAW))
431 f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420;
432
433 if (!f->fmt.pix.colorspace)
434 f->fmt.pix.colorspace = V4L2_COLORSPACE_REC709;
435
436 ret = vidioc_try_fmt(ctx->dev, f);
437 if (ret < 0)
438 return ret;
439
440 return 0;
441}
442
443static int vidioc_s_fmt(struct coda_ctx *ctx, struct v4l2_format *f)
444{
445 struct coda_q_data *q_data;
446 struct vb2_queue *vq;
447 int ret;
448
449 vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
450 if (!vq)
451 return -EINVAL;
452
453 q_data = get_q_data(ctx, f->type);
454 if (!q_data)
455 return -EINVAL;
456
457 if (vb2_is_busy(vq)) {
458 v4l2_err(&ctx->dev->v4l2_dev, "%s queue busy\n", __func__);
459 return -EBUSY;
460 }
461
462 ret = vidioc_try_fmt(ctx->dev, f);
463 if (ret)
464 return ret;
465
466 q_data->fmt = find_format(ctx->dev, f);
467 q_data->width = f->fmt.pix.width;
468 q_data->height = f->fmt.pix.height;
469 if (q_data->fmt->fourcc == V4L2_PIX_FMT_YUV420) {
470 q_data->sizeimage = q_data->width * q_data->height * 3 / 2;
471 } else { /* encoded format h.264/mpeg-4 */
472 q_data->sizeimage = CODA_MAX_FRAME_SIZE;
473 }
474
475 v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
476 "Setting format for type %d, wxh: %dx%d, fmt: %d\n",
477 f->type, q_data->width, q_data->height, q_data->fmt->fourcc);
478
479 return 0;
480}
481
482static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
483 struct v4l2_format *f)
484{
485 int ret;
486
487 ret = vidioc_try_fmt_vid_cap(file, priv, f);
488 if (ret)
489 return ret;
490
491 return vidioc_s_fmt(fh_to_ctx(priv), f);
492}
493
494static int vidioc_s_fmt_vid_out(struct file *file, void *priv,
495 struct v4l2_format *f)
496{
497 struct coda_ctx *ctx = fh_to_ctx(priv);
498 int ret;
499
500 ret = vidioc_try_fmt_vid_out(file, priv, f);
501 if (ret)
502 return ret;
503
504 ret = vidioc_s_fmt(fh_to_ctx(priv), f);
505 if (ret)
506 ctx->colorspace = f->fmt.pix.colorspace;
507
508 return ret;
509}
510
511static int vidioc_reqbufs(struct file *file, void *priv,
512 struct v4l2_requestbuffers *reqbufs)
513{
514 struct coda_ctx *ctx = fh_to_ctx(priv);
515
516 return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs);
517}
518
519static int vidioc_querybuf(struct file *file, void *priv,
520 struct v4l2_buffer *buf)
521{
522 struct coda_ctx *ctx = fh_to_ctx(priv);
523
524 return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf);
525}
526
527static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
528{
529 struct coda_ctx *ctx = fh_to_ctx(priv);
530
531 return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
532}
533
534static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
535{
536 struct coda_ctx *ctx = fh_to_ctx(priv);
537
538 return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
539}
540
541static int vidioc_streamon(struct file *file, void *priv,
542 enum v4l2_buf_type type)
543{
544 struct coda_ctx *ctx = fh_to_ctx(priv);
545
546 return v4l2_m2m_streamon(file, ctx->m2m_ctx, type);
547}
548
549static int vidioc_streamoff(struct file *file, void *priv,
550 enum v4l2_buf_type type)
551{
552 struct coda_ctx *ctx = fh_to_ctx(priv);
553
554 return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type);
555}
556
557static const struct v4l2_ioctl_ops coda_ioctl_ops = {
558 .vidioc_querycap = vidioc_querycap,
559
560 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
561 .vidioc_g_fmt_vid_cap = vidioc_g_fmt,
562 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
563 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
564
565 .vidioc_enum_fmt_vid_out = vidioc_enum_fmt_vid_out,
566 .vidioc_g_fmt_vid_out = vidioc_g_fmt,
567 .vidioc_try_fmt_vid_out = vidioc_try_fmt_vid_out,
568 .vidioc_s_fmt_vid_out = vidioc_s_fmt_vid_out,
569
570 .vidioc_reqbufs = vidioc_reqbufs,
571 .vidioc_querybuf = vidioc_querybuf,
572
573 .vidioc_qbuf = vidioc_qbuf,
574 .vidioc_dqbuf = vidioc_dqbuf,
575
576 .vidioc_streamon = vidioc_streamon,
577 .vidioc_streamoff = vidioc_streamoff,
578};
579
580/*
581 * Mem-to-mem operations.
582 */
583static void coda_device_run(void *m2m_priv)
584{
585 struct coda_ctx *ctx = m2m_priv;
586 struct coda_q_data *q_data_src, *q_data_dst;
587 struct vb2_buffer *src_buf, *dst_buf;
588 struct coda_dev *dev = ctx->dev;
589 int force_ipicture;
590 int quant_param = 0;
591 u32 picture_y, picture_cb, picture_cr;
592 u32 pic_stream_buffer_addr, pic_stream_buffer_size;
593 u32 dst_fourcc;
594
595 src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
596 dst_buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
597 q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
598 q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
599 dst_fourcc = q_data_dst->fmt->fourcc;
600
601 src_buf->v4l2_buf.sequence = ctx->isequence;
602 dst_buf->v4l2_buf.sequence = ctx->isequence;
603 ctx->isequence++;
604
605 /*
606 * Workaround coda firmware BUG that only marks the first
607 * frame as IDR. This is a problem for some decoders that can't
608 * recover when a frame is lost.
609 */
610 if (src_buf->v4l2_buf.sequence % ctx->params.gop_size) {
611 src_buf->v4l2_buf.flags |= V4L2_BUF_FLAG_PFRAME;
612 src_buf->v4l2_buf.flags &= ~V4L2_BUF_FLAG_KEYFRAME;
613 } else {
614 src_buf->v4l2_buf.flags |= V4L2_BUF_FLAG_KEYFRAME;
615 src_buf->v4l2_buf.flags &= ~V4L2_BUF_FLAG_PFRAME;
616 }
617
618 /*
619 * Copy headers at the beginning of the first frame for H.264 only.
620 * In MPEG4 they are already copied by the coda.
621 */
622 if (src_buf->v4l2_buf.sequence == 0) {
623 pic_stream_buffer_addr =
624 vb2_dma_contig_plane_dma_addr(dst_buf, 0) +
625 ctx->vpu_header_size[0] +
626 ctx->vpu_header_size[1] +
627 ctx->vpu_header_size[2];
628 pic_stream_buffer_size = CODA_MAX_FRAME_SIZE -
629 ctx->vpu_header_size[0] -
630 ctx->vpu_header_size[1] -
631 ctx->vpu_header_size[2];
632 memcpy(vb2_plane_vaddr(dst_buf, 0),
633 &ctx->vpu_header[0][0], ctx->vpu_header_size[0]);
634 memcpy(vb2_plane_vaddr(dst_buf, 0) + ctx->vpu_header_size[0],
635 &ctx->vpu_header[1][0], ctx->vpu_header_size[1]);
636 memcpy(vb2_plane_vaddr(dst_buf, 0) + ctx->vpu_header_size[0] +
637 ctx->vpu_header_size[1], &ctx->vpu_header[2][0],
638 ctx->vpu_header_size[2]);
639 } else {
640 pic_stream_buffer_addr =
641 vb2_dma_contig_plane_dma_addr(dst_buf, 0);
642 pic_stream_buffer_size = CODA_MAX_FRAME_SIZE;
643 }
644
645 if (src_buf->v4l2_buf.flags & V4L2_BUF_FLAG_KEYFRAME) {
646 force_ipicture = 1;
647 switch (dst_fourcc) {
648 case V4L2_PIX_FMT_H264:
649 quant_param = ctx->params.h264_intra_qp;
650 break;
651 case V4L2_PIX_FMT_MPEG4:
652 quant_param = ctx->params.mpeg4_intra_qp;
653 break;
654 default:
655 v4l2_warn(&ctx->dev->v4l2_dev,
656 "cannot set intra qp, fmt not supported\n");
657 break;
658 }
659 } else {
660 force_ipicture = 0;
661 switch (dst_fourcc) {
662 case V4L2_PIX_FMT_H264:
663 quant_param = ctx->params.h264_inter_qp;
664 break;
665 case V4L2_PIX_FMT_MPEG4:
666 quant_param = ctx->params.mpeg4_inter_qp;
667 break;
668 default:
669 v4l2_warn(&ctx->dev->v4l2_dev,
670 "cannot set inter qp, fmt not supported\n");
671 break;
672 }
673 }
674
675 /* submit */
676 coda_write(dev, 0, CODA_CMD_ENC_PIC_ROT_MODE);
677 coda_write(dev, quant_param, CODA_CMD_ENC_PIC_QS);
678
679
680 picture_y = vb2_dma_contig_plane_dma_addr(src_buf, 0);
681 picture_cb = picture_y + q_data_src->width * q_data_src->height;
682 picture_cr = picture_cb + q_data_src->width / 2 *
683 q_data_src->height / 2;
684
685 coda_write(dev, picture_y, CODA_CMD_ENC_PIC_SRC_ADDR_Y);
686 coda_write(dev, picture_cb, CODA_CMD_ENC_PIC_SRC_ADDR_CB);
687 coda_write(dev, picture_cr, CODA_CMD_ENC_PIC_SRC_ADDR_CR);
688 coda_write(dev, force_ipicture << 1 & 0x2,
689 CODA_CMD_ENC_PIC_OPTION);
690
691 coda_write(dev, pic_stream_buffer_addr, CODA_CMD_ENC_PIC_BB_START);
692 coda_write(dev, pic_stream_buffer_size / 1024,
693 CODA_CMD_ENC_PIC_BB_SIZE);
694 coda_command_async(ctx, CODA_COMMAND_PIC_RUN);
695}
696
697static int coda_job_ready(void *m2m_priv)
698{
699 struct coda_ctx *ctx = m2m_priv;
700
701 /*
702 * For both 'P' and 'key' frame cases 1 picture
703 * and 1 frame are needed.
704 */
705 if (!v4l2_m2m_num_src_bufs_ready(ctx->m2m_ctx) ||
706 !v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx)) {
707 v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
708 "not ready: not enough video buffers.\n");
709 return 0;
710 }
711
712 /* For P frames a reference picture is needed too */
713 if ((ctx->gopcounter != (ctx->params.gop_size - 1)) &&
714 !ctx->reference) {
715 v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
716 "not ready: reference picture not available.\n");
717 return 0;
718 }
719
720 if (coda_isbusy(ctx->dev)) {
721 v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
722 "not ready: coda is still busy.\n");
723 return 0;
724 }
725
726 v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
727 "job ready\n");
728 return 1;
729}
730
731static void coda_job_abort(void *priv)
732{
733 struct coda_ctx *ctx = priv;
734 struct coda_dev *dev = ctx->dev;
735
736 ctx->aborting = 1;
737
738 v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
739 "Aborting task\n");
740
741 v4l2_m2m_job_finish(dev->m2m_dev, ctx->m2m_ctx);
742}
743
744static void coda_lock(void *m2m_priv)
745{
746 struct coda_ctx *ctx = m2m_priv;
747 struct coda_dev *pcdev = ctx->dev;
748 mutex_lock(&pcdev->dev_mutex);
749}
750
751static void coda_unlock(void *m2m_priv)
752{
753 struct coda_ctx *ctx = m2m_priv;
754 struct coda_dev *pcdev = ctx->dev;
755 mutex_unlock(&pcdev->dev_mutex);
756}
757
758static struct v4l2_m2m_ops coda_m2m_ops = {
759 .device_run = coda_device_run,
760 .job_ready = coda_job_ready,
761 .job_abort = coda_job_abort,
762 .lock = coda_lock,
763 .unlock = coda_unlock,
764};
765
766static void set_default_params(struct coda_ctx *ctx)
767{
768 struct coda_dev *dev = ctx->dev;
769
770 ctx->params.codec_mode = CODA_MODE_INVALID;
771 ctx->colorspace = V4L2_COLORSPACE_REC709;
772 ctx->params.framerate = 30;
773 ctx->reference = NULL;
774 ctx->aborting = 0;
775
776 /* Default formats for output and input queues */
777 ctx->q_data[V4L2_M2M_SRC].fmt = &dev->devtype->formats[0];
778 ctx->q_data[V4L2_M2M_DST].fmt = &dev->devtype->formats[1];
779 ctx->q_data[V4L2_M2M_SRC].width = MAX_W;
780 ctx->q_data[V4L2_M2M_SRC].height = MAX_H;
781 ctx->q_data[V4L2_M2M_SRC].sizeimage = (MAX_W * MAX_H * 3) / 2;
782 ctx->q_data[V4L2_M2M_DST].width = MAX_W;
783 ctx->q_data[V4L2_M2M_DST].height = MAX_H;
784 ctx->q_data[V4L2_M2M_DST].sizeimage = CODA_MAX_FRAME_SIZE;
785}
786
787/*
788 * Queue operations
789 */
790static int coda_queue_setup(struct vb2_queue *vq,
791 const struct v4l2_format *fmt,
792 unsigned int *nbuffers, unsigned int *nplanes,
793 unsigned int sizes[], void *alloc_ctxs[])
794{
795 struct coda_ctx *ctx = vb2_get_drv_priv(vq);
796 unsigned int size;
797
798 if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
799 *nbuffers = CODA_OUTPUT_BUFS;
800 if (fmt)
801 size = fmt->fmt.pix.width *
802 fmt->fmt.pix.height * 3 / 2;
803 else
804 size = MAX_W *
805 MAX_H * 3 / 2;
806 } else {
807 *nbuffers = CODA_CAPTURE_BUFS;
808 size = CODA_MAX_FRAME_SIZE;
809 }
810
811 *nplanes = 1;
812 sizes[0] = size;
813
814 alloc_ctxs[0] = ctx->dev->alloc_ctx;
815
816 v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
817 "get %d buffer(s) of size %d each.\n", *nbuffers, size);
818
819 return 0;
820}
821
822static int coda_buf_prepare(struct vb2_buffer *vb)
823{
824 struct coda_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
825 struct coda_q_data *q_data;
826
827 q_data = get_q_data(ctx, vb->vb2_queue->type);
828
829 if (vb2_plane_size(vb, 0) < q_data->sizeimage) {
830 v4l2_warn(&ctx->dev->v4l2_dev,
831 "%s data will not fit into plane (%lu < %lu)\n",
832 __func__, vb2_plane_size(vb, 0),
833 (long)q_data->sizeimage);
834 return -EINVAL;
835 }
836
837 vb2_set_plane_payload(vb, 0, q_data->sizeimage);
838
839 return 0;
840}
841
842static void coda_buf_queue(struct vb2_buffer *vb)
843{
844 struct coda_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
845 v4l2_m2m_buf_queue(ctx->m2m_ctx, vb);
846}
847
848static void coda_wait_prepare(struct vb2_queue *q)
849{
850 struct coda_ctx *ctx = vb2_get_drv_priv(q);
851 coda_unlock(ctx);
852}
853
854static void coda_wait_finish(struct vb2_queue *q)
855{
856 struct coda_ctx *ctx = vb2_get_drv_priv(q);
857 coda_lock(ctx);
858}
859
860static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
861{
862 struct coda_ctx *ctx = vb2_get_drv_priv(q);
863 struct v4l2_device *v4l2_dev = &ctx->dev->v4l2_dev;
864 u32 bitstream_buf, bitstream_size;
865 struct coda_dev *dev = ctx->dev;
866 struct coda_q_data *q_data_src, *q_data_dst;
867 u32 dst_fourcc;
868 struct vb2_buffer *buf;
869 struct vb2_queue *src_vq;
870 u32 value;
871 int i = 0;
872
873 if (count < 1)
874 return -EINVAL;
875
876 if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
877 ctx->rawstreamon = 1;
878 else
879 ctx->compstreamon = 1;
880
881 /* Don't start the coda unless both queues are on */
882 if (!(ctx->rawstreamon & ctx->compstreamon))
883 return 0;
884
885 ctx->gopcounter = ctx->params.gop_size - 1;
886
887 q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
888 buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
889 bitstream_buf = vb2_dma_contig_plane_dma_addr(buf, 0);
890 q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
891 bitstream_size = q_data_dst->sizeimage;
892 dst_fourcc = q_data_dst->fmt->fourcc;
893
894 /* Find out whether coda must encode or decode */
895 if (q_data_src->fmt->type == CODA_FMT_RAW &&
896 q_data_dst->fmt->type == CODA_FMT_ENC) {
897 ctx->inst_type = CODA_INST_ENCODER;
898 } else if (q_data_src->fmt->type == CODA_FMT_ENC &&
899 q_data_dst->fmt->type == CODA_FMT_RAW) {
900 ctx->inst_type = CODA_INST_DECODER;
901 v4l2_err(v4l2_dev, "decoding not supported.\n");
902 return -EINVAL;
903 } else {
904 v4l2_err(v4l2_dev, "couldn't tell instance type.\n");
905 return -EINVAL;
906 }
907
908 if (!coda_is_initialized(dev)) {
909 v4l2_err(v4l2_dev, "coda is not initialized.\n");
910 return -EFAULT;
911 }
912 coda_write(dev, ctx->parabuf.paddr, CODA_REG_BIT_PARA_BUF_ADDR);
913 coda_write(dev, bitstream_buf, CODA_REG_BIT_RD_PTR(ctx->idx));
914 coda_write(dev, bitstream_buf, CODA_REG_BIT_WR_PTR(ctx->idx));
915 switch (dev->devtype->product) {
916 case CODA_DX6:
917 coda_write(dev, CODADX6_STREAM_BUF_DYNALLOC_EN |
918 CODADX6_STREAM_BUF_PIC_RESET, CODA_REG_BIT_STREAM_CTRL);
919 break;
920 default:
921 coda_write(dev, CODA7_STREAM_BUF_DYNALLOC_EN |
922 CODA7_STREAM_BUF_PIC_RESET, CODA_REG_BIT_STREAM_CTRL);
923 }
924
925 /* Configure the coda */
926 coda_write(dev, 0xffff4c00, CODA_REG_BIT_SEARCH_RAM_BASE_ADDR);
927
928 /* Could set rotation here if needed */
929 switch (dev->devtype->product) {
930 case CODA_DX6:
931 value = (q_data_src->width & CODADX6_PICWIDTH_MASK) << CODADX6_PICWIDTH_OFFSET;
932 break;
933 default:
934 value = (q_data_src->width & CODA7_PICWIDTH_MASK) << CODA7_PICWIDTH_OFFSET;
935 }
936 value |= (q_data_src->height & CODA_PICHEIGHT_MASK) << CODA_PICHEIGHT_OFFSET;
937 coda_write(dev, value, CODA_CMD_ENC_SEQ_SRC_SIZE);
938 coda_write(dev, ctx->params.framerate,
939 CODA_CMD_ENC_SEQ_SRC_F_RATE);
940
941 switch (dst_fourcc) {
942 case V4L2_PIX_FMT_MPEG4:
943 if (dev->devtype->product == CODA_DX6)
944 ctx->params.codec_mode = CODADX6_MODE_ENCODE_MP4;
945 else
946 ctx->params.codec_mode = CODA7_MODE_ENCODE_MP4;
947
948 coda_write(dev, CODA_STD_MPEG4, CODA_CMD_ENC_SEQ_COD_STD);
949 coda_write(dev, 0, CODA_CMD_ENC_SEQ_MP4_PARA);
950 break;
951 case V4L2_PIX_FMT_H264:
952 if (dev->devtype->product == CODA_DX6)
953 ctx->params.codec_mode = CODADX6_MODE_ENCODE_H264;
954 else
955 ctx->params.codec_mode = CODA7_MODE_ENCODE_H264;
956
957 coda_write(dev, CODA_STD_H264, CODA_CMD_ENC_SEQ_COD_STD);
958 coda_write(dev, 0, CODA_CMD_ENC_SEQ_264_PARA);
959 break;
960 default:
961 v4l2_err(v4l2_dev,
962 "dst format (0x%08x) invalid.\n", dst_fourcc);
963 return -EINVAL;
964 }
965
966 value = (ctx->params.slice_max_mb & CODA_SLICING_SIZE_MASK) << CODA_SLICING_SIZE_OFFSET;
967 value |= (1 & CODA_SLICING_UNIT_MASK) << CODA_SLICING_UNIT_OFFSET;
968 if (ctx->params.slice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB)
969 value |= 1 & CODA_SLICING_MODE_MASK;
970 coda_write(dev, value, CODA_CMD_ENC_SEQ_SLICE_MODE);
971 value = ctx->params.gop_size & CODA_GOP_SIZE_MASK;
972 coda_write(dev, value, CODA_CMD_ENC_SEQ_GOP_SIZE);
973
974 if (ctx->params.bitrate) {
975 /* Rate control enabled */
976 value = (ctx->params.bitrate & CODA_RATECONTROL_BITRATE_MASK) << CODA_RATECONTROL_BITRATE_OFFSET;
977 value |= 1 & CODA_RATECONTROL_ENABLE_MASK;
978 } else {
979 value = 0;
980 }
981 coda_write(dev, value, CODA_CMD_ENC_SEQ_RC_PARA);
982
983 coda_write(dev, 0, CODA_CMD_ENC_SEQ_RC_BUF_SIZE);
984 coda_write(dev, 0, CODA_CMD_ENC_SEQ_INTRA_REFRESH);
985
986 coda_write(dev, bitstream_buf, CODA_CMD_ENC_SEQ_BB_START);
987 coda_write(dev, bitstream_size / 1024, CODA_CMD_ENC_SEQ_BB_SIZE);
988
989 /* set default gamma */
990 value = (CODA_DEFAULT_GAMMA & CODA_GAMMA_MASK) << CODA_GAMMA_OFFSET;
991 coda_write(dev, value, CODA_CMD_ENC_SEQ_RC_GAMMA);
992
993 value = (CODA_DEFAULT_GAMMA > 0) << CODA_OPTION_GAMMA_OFFSET;
994 value |= (0 & CODA_OPTION_SLICEREPORT_MASK) << CODA_OPTION_SLICEREPORT_OFFSET;
995 coda_write(dev, value, CODA_CMD_ENC_SEQ_OPTION);
996
997 if (dst_fourcc == V4L2_PIX_FMT_H264) {
998 value = (FMO_SLICE_SAVE_BUF_SIZE << 7);
999 value |= (0 & CODA_FMOPARAM_TYPE_MASK) << CODA_FMOPARAM_TYPE_OFFSET;
1000 value |= 0 & CODA_FMOPARAM_SLICENUM_MASK;
1001 coda_write(dev, value, CODA_CMD_ENC_SEQ_FMO);
1002 }
1003
1004 if (coda_command_sync(ctx, CODA_COMMAND_SEQ_INIT)) {
1005 v4l2_err(v4l2_dev, "CODA_COMMAND_SEQ_INIT timeout\n");
1006 return -ETIMEDOUT;
1007 }
1008
1009 if (coda_read(dev, CODA_RET_ENC_SEQ_SUCCESS) == 0)
1010 return -EFAULT;
1011
1012 /*
1013 * Walk the src buffer list and let the codec know the
1014 * addresses of the pictures.
1015 */
1016 src_vq = v4l2_m2m_get_vq(ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
1017 for (i = 0; i < src_vq->num_buffers; i++) {
1018 u32 *p;
1019
1020 buf = src_vq->bufs[i];
1021 p = ctx->parabuf.vaddr;
1022
1023 p[i * 3] = vb2_dma_contig_plane_dma_addr(buf, 0);
1024 p[i * 3 + 1] = p[i * 3] + q_data_src->width *
1025 q_data_src->height;
1026 p[i * 3 + 2] = p[i * 3 + 1] + q_data_src->width / 2 *
1027 q_data_src->height / 2;
1028 }
1029
1030 coda_write(dev, src_vq->num_buffers, CODA_CMD_SET_FRAME_BUF_NUM);
1031 coda_write(dev, q_data_src->width, CODA_CMD_SET_FRAME_BUF_STRIDE);
1032 if (coda_command_sync(ctx, CODA_COMMAND_SET_FRAME_BUF)) {
1033 v4l2_err(v4l2_dev, "CODA_COMMAND_SET_FRAME_BUF timeout\n");
1034 return -ETIMEDOUT;
1035 }
1036
1037 /* Save stream headers */
1038 buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
1039 switch (dst_fourcc) {
1040 case V4L2_PIX_FMT_H264:
1041 /*
1042 * Get SPS in the first frame and copy it to an
1043 * intermediate buffer.
1044 */
1045 coda_write(dev, vb2_dma_contig_plane_dma_addr(buf, 0), CODA_CMD_ENC_HEADER_BB_START);
1046 coda_write(dev, bitstream_size, CODA_CMD_ENC_HEADER_BB_SIZE);
1047 coda_write(dev, CODA_HEADER_H264_SPS, CODA_CMD_ENC_HEADER_CODE);
1048 if (coda_command_sync(ctx, CODA_COMMAND_ENCODE_HEADER)) {
1049 v4l2_err(v4l2_dev, "CODA_COMMAND_ENCODE_HEADER timeout\n");
1050 return -ETIMEDOUT;
1051 }
1052 ctx->vpu_header_size[0] = coda_read(dev, CODA_REG_BIT_WR_PTR(ctx->idx)) -
1053 coda_read(dev, CODA_CMD_ENC_HEADER_BB_START);
1054 memcpy(&ctx->vpu_header[0][0], vb2_plane_vaddr(buf, 0),
1055 ctx->vpu_header_size[0]);
1056
1057 /*
1058 * Get PPS in the first frame and copy it to an
1059 * intermediate buffer.
1060 */
1061 coda_write(dev, vb2_dma_contig_plane_dma_addr(buf, 0), CODA_CMD_ENC_HEADER_BB_START);
1062 coda_write(dev, bitstream_size, CODA_CMD_ENC_HEADER_BB_SIZE);
1063 coda_write(dev, CODA_HEADER_H264_PPS, CODA_CMD_ENC_HEADER_CODE);
1064 if (coda_command_sync(ctx, CODA_COMMAND_ENCODE_HEADER)) {
1065 v4l2_err(v4l2_dev, "CODA_COMMAND_ENCODE_HEADER timeout\n");
1066 return -ETIMEDOUT;
1067 }
1068 ctx->vpu_header_size[1] = coda_read(dev, CODA_REG_BIT_WR_PTR(ctx->idx)) -
1069 coda_read(dev, CODA_CMD_ENC_HEADER_BB_START);
1070 memcpy(&ctx->vpu_header[1][0], vb2_plane_vaddr(buf, 0),
1071 ctx->vpu_header_size[1]);
1072 ctx->vpu_header_size[2] = 0;
1073 break;
1074 case V4L2_PIX_FMT_MPEG4:
1075 /*
1076 * Get VOS in the first frame and copy it to an
1077 * intermediate buffer
1078 */
1079 coda_write(dev, vb2_dma_contig_plane_dma_addr(buf, 0), CODA_CMD_ENC_HEADER_BB_START);
1080 coda_write(dev, bitstream_size, CODA_CMD_ENC_HEADER_BB_SIZE);
1081 coda_write(dev, CODA_HEADER_MP4V_VOS, CODA_CMD_ENC_HEADER_CODE);
1082 if (coda_command_sync(ctx, CODA_COMMAND_ENCODE_HEADER)) {
1083 v4l2_err(v4l2_dev, "CODA_COMMAND_ENCODE_HEADER timeout\n");
1084 return -ETIMEDOUT;
1085 }
1086 ctx->vpu_header_size[0] = coda_read(dev, CODA_REG_BIT_WR_PTR(ctx->idx)) -
1087 coda_read(dev, CODA_CMD_ENC_HEADER_BB_START);
1088 memcpy(&ctx->vpu_header[0][0], vb2_plane_vaddr(buf, 0),
1089 ctx->vpu_header_size[0]);
1090
1091 coda_write(dev, vb2_dma_contig_plane_dma_addr(buf, 0), CODA_CMD_ENC_HEADER_BB_START);
1092 coda_write(dev, bitstream_size, CODA_CMD_ENC_HEADER_BB_SIZE);
1093 coda_write(dev, CODA_HEADER_MP4V_VIS, CODA_CMD_ENC_HEADER_CODE);
1094 if (coda_command_sync(ctx, CODA_COMMAND_ENCODE_HEADER)) {
1095 v4l2_err(v4l2_dev, "CODA_COMMAND_ENCODE_HEADER failed\n");
1096 return -ETIMEDOUT;
1097 }
1098 ctx->vpu_header_size[1] = coda_read(dev, CODA_REG_BIT_WR_PTR(ctx->idx)) -
1099 coda_read(dev, CODA_CMD_ENC_HEADER_BB_START);
1100 memcpy(&ctx->vpu_header[1][0], vb2_plane_vaddr(buf, 0),
1101 ctx->vpu_header_size[1]);
1102
1103 coda_write(dev, vb2_dma_contig_plane_dma_addr(buf, 0), CODA_CMD_ENC_HEADER_BB_START);
1104 coda_write(dev, bitstream_size, CODA_CMD_ENC_HEADER_BB_SIZE);
1105 coda_write(dev, CODA_HEADER_MP4V_VOL, CODA_CMD_ENC_HEADER_CODE);
1106 if (coda_command_sync(ctx, CODA_COMMAND_ENCODE_HEADER)) {
1107 v4l2_err(v4l2_dev, "CODA_COMMAND_ENCODE_HEADER failed\n");
1108 return -ETIMEDOUT;
1109 }
1110 ctx->vpu_header_size[2] = coda_read(dev, CODA_REG_BIT_WR_PTR(ctx->idx)) -
1111 coda_read(dev, CODA_CMD_ENC_HEADER_BB_START);
1112 memcpy(&ctx->vpu_header[2][0], vb2_plane_vaddr(buf, 0),
1113 ctx->vpu_header_size[2]);
1114 break;
1115 default:
1116 /* No more formats need to save headers at the moment */
1117 break;
1118 }
1119
1120 return 0;
1121}
1122
1123static int coda_stop_streaming(struct vb2_queue *q)
1124{
1125 struct coda_ctx *ctx = vb2_get_drv_priv(q);
1126
1127 if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
1128 v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
1129 "%s: output\n", __func__);
1130 ctx->rawstreamon = 0;
1131 } else {
1132 v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
1133 "%s: capture\n", __func__);
1134 ctx->compstreamon = 0;
1135 }
1136
1137 if (!ctx->rawstreamon && !ctx->compstreamon) {
1138 v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
1139 "%s: sent command 'SEQ_END' to coda\n", __func__);
1140 if (coda_command_sync(ctx, CODA_COMMAND_SEQ_END)) {
1141 v4l2_err(&ctx->dev->v4l2_dev,
1142 "CODA_COMMAND_SEQ_END failed\n");
1143 return -ETIMEDOUT;
1144 }
1145 }
1146
1147 return 0;
1148}
1149
1150static struct vb2_ops coda_qops = {
1151 .queue_setup = coda_queue_setup,
1152 .buf_prepare = coda_buf_prepare,
1153 .buf_queue = coda_buf_queue,
1154 .wait_prepare = coda_wait_prepare,
1155 .wait_finish = coda_wait_finish,
1156 .start_streaming = coda_start_streaming,
1157 .stop_streaming = coda_stop_streaming,
1158};
1159
1160static int coda_s_ctrl(struct v4l2_ctrl *ctrl)
1161{
1162 struct coda_ctx *ctx =
1163 container_of(ctrl->handler, struct coda_ctx, ctrls);
1164
1165 v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
1166 "s_ctrl: id = %d, val = %d\n", ctrl->id, ctrl->val);
1167
1168 switch (ctrl->id) {
1169 case V4L2_CID_MPEG_VIDEO_BITRATE:
1170 ctx->params.bitrate = ctrl->val / 1000;
1171 break;
1172 case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
1173 ctx->params.gop_size = ctrl->val;
1174 break;
1175 case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP:
1176 ctx->params.h264_intra_qp = ctrl->val;
1177 break;
1178 case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP:
1179 ctx->params.h264_inter_qp = ctrl->val;
1180 break;
1181 case V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP:
1182 ctx->params.mpeg4_intra_qp = ctrl->val;
1183 break;
1184 case V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP:
1185 ctx->params.mpeg4_inter_qp = ctrl->val;
1186 break;
1187 case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE:
1188 ctx->params.slice_mode = ctrl->val;
1189 break;
1190 case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB:
1191 ctx->params.slice_max_mb = ctrl->val;
1192 break;
1193 case V4L2_CID_MPEG_VIDEO_HEADER_MODE:
1194 break;
1195 default:
1196 v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
1197 "Invalid control, id=%d, val=%d\n",
1198 ctrl->id, ctrl->val);
1199 return -EINVAL;
1200 }
1201
1202 return 0;
1203}
1204
1205static struct v4l2_ctrl_ops coda_ctrl_ops = {
1206 .s_ctrl = coda_s_ctrl,
1207};
1208
1209static int coda_ctrls_setup(struct coda_ctx *ctx)
1210{
1211 v4l2_ctrl_handler_init(&ctx->ctrls, 9);
1212
1213 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops,
1214 V4L2_CID_MPEG_VIDEO_BITRATE, 0, 32767000, 1, 0);
1215 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops,
1216 V4L2_CID_MPEG_VIDEO_GOP_SIZE, 1, 60, 1, 16);
1217 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops,
1218 V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP, 1, 51, 1, 25);
1219 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops,
1220 V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP, 1, 51, 1, 25);
1221 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops,
1222 V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP, 1, 31, 1, 2);
1223 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops,
1224 V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP, 1, 31, 1, 2);
1225 v4l2_ctrl_new_std_menu(&ctx->ctrls, &coda_ctrl_ops,
1226 V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE,
1227 V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB, 0,
1228 V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB);
1229 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops,
1230 V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB, 1, 0x3fffffff, 1, 1);
1231 v4l2_ctrl_new_std_menu(&ctx->ctrls, &coda_ctrl_ops,
1232 V4L2_CID_MPEG_VIDEO_HEADER_MODE,
1233 V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME,
1234 (1 << V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE),
1235 V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME);
1236
1237 if (ctx->ctrls.error) {
1238 v4l2_err(&ctx->dev->v4l2_dev, "control initialization error (%d)",
1239 ctx->ctrls.error);
1240 return -EINVAL;
1241 }
1242
1243 return v4l2_ctrl_handler_setup(&ctx->ctrls);
1244}
1245
1246static int coda_queue_init(void *priv, struct vb2_queue *src_vq,
1247 struct vb2_queue *dst_vq)
1248{
1249 struct coda_ctx *ctx = priv;
1250 int ret;
1251
1252 memset(src_vq, 0, sizeof(*src_vq));
1253 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
1254 src_vq->io_modes = VB2_MMAP;
1255 src_vq->drv_priv = ctx;
1256 src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
1257 src_vq->ops = &coda_qops;
1258 src_vq->mem_ops = &vb2_dma_contig_memops;
1259
1260 ret = vb2_queue_init(src_vq);
1261 if (ret)
1262 return ret;
1263
1264 memset(dst_vq, 0, sizeof(*dst_vq));
1265 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1266 dst_vq->io_modes = VB2_MMAP;
1267 dst_vq->drv_priv = ctx;
1268 dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
1269 dst_vq->ops = &coda_qops;
1270 dst_vq->mem_ops = &vb2_dma_contig_memops;
1271
1272 return vb2_queue_init(dst_vq);
1273}
1274
1275static int coda_open(struct file *file)
1276{
1277 struct coda_dev *dev = video_drvdata(file);
1278 struct coda_ctx *ctx = NULL;
1279 int ret = 0;
1280
1281 if (dev->instances >= CODA_MAX_INSTANCES)
1282 return -EBUSY;
1283
1284 ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
1285 if (!ctx)
1286 return -ENOMEM;
1287
1288 v4l2_fh_init(&ctx->fh, video_devdata(file));
1289 file->private_data = &ctx->fh;
1290 v4l2_fh_add(&ctx->fh);
1291 ctx->dev = dev;
1292
1293 set_default_params(ctx);
1294 ctx->m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx,
1295 &coda_queue_init);
1296 if (IS_ERR(ctx->m2m_ctx)) {
1297 int ret = PTR_ERR(ctx->m2m_ctx);
1298
1299 v4l2_err(&dev->v4l2_dev, "%s return error (%d)\n",
1300 __func__, ret);
1301 goto err;
1302 }
1303 ret = coda_ctrls_setup(ctx);
1304 if (ret) {
1305 v4l2_err(&dev->v4l2_dev, "failed to setup coda controls\n");
1306 goto err;
1307 }
1308
1309 ctx->fh.ctrl_handler = &ctx->ctrls;
1310
1311 ctx->parabuf.vaddr = dma_alloc_coherent(&dev->plat_dev->dev,
1312 CODA_PARA_BUF_SIZE, &ctx->parabuf.paddr, GFP_KERNEL);
1313 if (!ctx->parabuf.vaddr) {
1314 v4l2_err(&dev->v4l2_dev, "failed to allocate parabuf");
1315 ret = -ENOMEM;
1316 goto err;
1317 }
1318
1319 coda_lock(ctx);
1320 ctx->idx = dev->instances++;
1321 coda_unlock(ctx);
1322
1323 clk_prepare_enable(dev->clk_per);
1324 clk_prepare_enable(dev->clk_ahb);
1325
1326 v4l2_dbg(1, coda_debug, &dev->v4l2_dev, "Created instance %d (%p)\n",
1327 ctx->idx, ctx);
1328
1329 return 0;
1330
1331err:
1332 v4l2_fh_del(&ctx->fh);
1333 v4l2_fh_exit(&ctx->fh);
1334 kfree(ctx);
1335 return ret;
1336}
1337
1338static int coda_release(struct file *file)
1339{
1340 struct coda_dev *dev = video_drvdata(file);
1341 struct coda_ctx *ctx = fh_to_ctx(file->private_data);
1342
1343 v4l2_dbg(1, coda_debug, &dev->v4l2_dev, "Releasing instance %p\n",
1344 ctx);
1345
1346 coda_lock(ctx);
1347 dev->instances--;
1348 coda_unlock(ctx);
1349
1350 dma_free_coherent(&dev->plat_dev->dev, CODA_PARA_BUF_SIZE,
1351 ctx->parabuf.vaddr, ctx->parabuf.paddr);
1352 v4l2_m2m_ctx_release(ctx->m2m_ctx);
1353 v4l2_ctrl_handler_free(&ctx->ctrls);
1354 clk_disable_unprepare(dev->clk_per);
1355 clk_disable_unprepare(dev->clk_ahb);
1356 v4l2_fh_del(&ctx->fh);
1357 v4l2_fh_exit(&ctx->fh);
1358 kfree(ctx);
1359
1360 return 0;
1361}
1362
1363static unsigned int coda_poll(struct file *file,
1364 struct poll_table_struct *wait)
1365{
1366 struct coda_ctx *ctx = fh_to_ctx(file->private_data);
1367 int ret;
1368
1369 coda_lock(ctx);
1370 ret = v4l2_m2m_poll(file, ctx->m2m_ctx, wait);
1371 coda_unlock(ctx);
1372 return ret;
1373}
1374
1375static int coda_mmap(struct file *file, struct vm_area_struct *vma)
1376{
1377 struct coda_ctx *ctx = fh_to_ctx(file->private_data);
1378
1379 return v4l2_m2m_mmap(file, ctx->m2m_ctx, vma);
1380}
1381
1382static const struct v4l2_file_operations coda_fops = {
1383 .owner = THIS_MODULE,
1384 .open = coda_open,
1385 .release = coda_release,
1386 .poll = coda_poll,
1387 .unlocked_ioctl = video_ioctl2,
1388 .mmap = coda_mmap,
1389};
1390
1391static irqreturn_t coda_irq_handler(int irq, void *data)
1392{
1393 struct vb2_buffer *src_buf, *dst_buf, *tmp_buf;
1394 struct coda_dev *dev = data;
1395 u32 wr_ptr, start_ptr;
1396 struct coda_ctx *ctx;
1397
1398 /* read status register to attend the IRQ */
1399 coda_read(dev, CODA_REG_BIT_INT_STATUS);
1400 coda_write(dev, CODA_REG_BIT_INT_CLEAR_SET,
1401 CODA_REG_BIT_INT_CLEAR);
1402
1403 ctx = v4l2_m2m_get_curr_priv(dev->m2m_dev);
1404 if (ctx == NULL) {
1405 v4l2_err(&dev->v4l2_dev, "Instance released before the end of transaction\n");
1406 return IRQ_HANDLED;
1407 }
1408
1409 if (ctx->aborting) {
1410 v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
1411 "task has been aborted\n");
1412 return IRQ_HANDLED;
1413 }
1414
1415 if (coda_isbusy(ctx->dev)) {
1416 v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
1417 "coda is still busy!!!!\n");
1418 return IRQ_NONE;
1419 }
1420
1421 src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
1422 dst_buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
1423
1424 /* Get results from the coda */
1425 coda_read(dev, CODA_RET_ENC_PIC_TYPE);
1426 start_ptr = coda_read(dev, CODA_CMD_ENC_PIC_BB_START);
1427 wr_ptr = coda_read(dev, CODA_REG_BIT_WR_PTR(ctx->idx));
1428 /* Calculate bytesused field */
1429 if (dst_buf->v4l2_buf.sequence == 0) {
1430 dst_buf->v4l2_planes[0].bytesused = (wr_ptr - start_ptr) +
1431 ctx->vpu_header_size[0] +
1432 ctx->vpu_header_size[1] +
1433 ctx->vpu_header_size[2];
1434 } else {
1435 dst_buf->v4l2_planes[0].bytesused = (wr_ptr - start_ptr);
1436 }
1437
1438 v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev, "frame size = %u\n",
1439 wr_ptr - start_ptr);
1440
1441 coda_read(dev, CODA_RET_ENC_PIC_SLICE_NUM);
1442 coda_read(dev, CODA_RET_ENC_PIC_FLAG);
1443
1444 if (src_buf->v4l2_buf.flags & V4L2_BUF_FLAG_KEYFRAME) {
1445 dst_buf->v4l2_buf.flags |= V4L2_BUF_FLAG_KEYFRAME;
1446 dst_buf->v4l2_buf.flags &= ~V4L2_BUF_FLAG_PFRAME;
1447 } else {
1448 dst_buf->v4l2_buf.flags |= V4L2_BUF_FLAG_PFRAME;
1449 dst_buf->v4l2_buf.flags &= ~V4L2_BUF_FLAG_KEYFRAME;
1450 }
1451
1452 /* Free previous reference picture if available */
1453 if (ctx->reference) {
1454 v4l2_m2m_buf_done(ctx->reference, VB2_BUF_STATE_DONE);
1455 ctx->reference = NULL;
1456 }
1457
1458 /*
1459 * For the last frame of the gop we don't need to save
1460 * a reference picture.
1461 */
1462 v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
1463 tmp_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
1464 if (ctx->gopcounter == 0)
1465 v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
1466 else
1467 ctx->reference = tmp_buf;
1468
1469 v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_DONE);
1470
1471 ctx->gopcounter--;
1472 if (ctx->gopcounter < 0)
1473 ctx->gopcounter = ctx->params.gop_size - 1;
1474
1475 v4l2_dbg(1, coda_debug, &dev->v4l2_dev,
1476 "job finished: encoding frame (%d) (%s)\n",
1477 dst_buf->v4l2_buf.sequence,
1478 (dst_buf->v4l2_buf.flags & V4L2_BUF_FLAG_KEYFRAME) ?
1479 "KEYFRAME" : "PFRAME");
1480
1481 v4l2_m2m_job_finish(ctx->dev->m2m_dev, ctx->m2m_ctx);
1482
1483 return IRQ_HANDLED;
1484}
1485
1486static u32 coda_supported_firmwares[] = {
1487 CODA_FIRMWARE_VERNUM(CODA_DX6, 2, 2, 5),
1488};
1489
1490static bool coda_firmware_supported(u32 vernum)
1491{
1492 int i;
1493
1494 for (i = 0; i < ARRAY_SIZE(coda_supported_firmwares); i++)
1495 if (vernum == coda_supported_firmwares[i])
1496 return true;
1497 return false;
1498}
1499
1500static char *coda_product_name(int product)
1501{
1502 static char buf[9];
1503
1504 switch (product) {
1505 case CODA_DX6:
1506 return "CodaDx6";
1507 default:
1508 snprintf(buf, sizeof(buf), "(0x%04x)", product);
1509 return buf;
1510 }
1511}
1512
1513static int coda_hw_init(struct coda_dev *dev, const struct firmware *fw)
1514{
1515 u16 product, major, minor, release;
1516 u32 data;
1517 u16 *p;
1518 int i;
1519
1520 clk_prepare_enable(dev->clk_per);
1521 clk_prepare_enable(dev->clk_ahb);
1522
1523 /* Copy the whole firmware image to the code buffer */
1524 memcpy(dev->codebuf.vaddr, fw->data, fw->size);
1525 /*
1526 * Copy the first CODA_ISRAM_SIZE in the internal SRAM.
1527 * This memory seems to be big-endian here, which is weird, since
1528 * the internal ARM processor of the coda is little endian.
1529 * Data in this SRAM survives a reboot.
1530 */
1531 p = (u16 *)fw->data;
1532 for (i = 0; i < (CODA_ISRAM_SIZE / 2); i++) {
1533 data = CODA_DOWN_ADDRESS_SET(i) |
1534 CODA_DOWN_DATA_SET(p[i ^ 1]);
1535 coda_write(dev, data, CODA_REG_BIT_CODE_DOWN);
1536 }
1537 release_firmware(fw);
1538
1539 /* Tell the BIT where to find everything it needs */
1540 coda_write(dev, dev->workbuf.paddr,
1541 CODA_REG_BIT_WORK_BUF_ADDR);
1542 coda_write(dev, dev->codebuf.paddr,
1543 CODA_REG_BIT_CODE_BUF_ADDR);
1544 coda_write(dev, 0, CODA_REG_BIT_CODE_RUN);
1545
1546 /* Set default values */
1547 switch (dev->devtype->product) {
1548 case CODA_DX6:
1549 coda_write(dev, CODADX6_STREAM_BUF_PIC_FLUSH, CODA_REG_BIT_STREAM_CTRL);
1550 break;
1551 default:
1552 coda_write(dev, CODA7_STREAM_BUF_PIC_FLUSH, CODA_REG_BIT_STREAM_CTRL);
1553 }
1554 coda_write(dev, 0, CODA_REG_BIT_FRAME_MEM_CTRL);
1555 coda_write(dev, CODA_INT_INTERRUPT_ENABLE,
1556 CODA_REG_BIT_INT_ENABLE);
1557
1558 /* Reset VPU and start processor */
1559 data = coda_read(dev, CODA_REG_BIT_CODE_RESET);
1560 data |= CODA_REG_RESET_ENABLE;
1561 coda_write(dev, data, CODA_REG_BIT_CODE_RESET);
1562 udelay(10);
1563 data &= ~CODA_REG_RESET_ENABLE;
1564 coda_write(dev, data, CODA_REG_BIT_CODE_RESET);
1565 coda_write(dev, CODA_REG_RUN_ENABLE, CODA_REG_BIT_CODE_RUN);
1566
1567 /* Load firmware */
1568 coda_write(dev, 0, CODA_CMD_FIRMWARE_VERNUM);
1569 coda_write(dev, CODA_REG_BIT_BUSY_FLAG, CODA_REG_BIT_BUSY);
1570 coda_write(dev, 0, CODA_REG_BIT_RUN_INDEX);
1571 coda_write(dev, 0, CODA_REG_BIT_RUN_COD_STD);
1572 coda_write(dev, CODA_COMMAND_FIRMWARE_GET, CODA_REG_BIT_RUN_COMMAND);
1573 if (coda_wait_timeout(dev)) {
1574 clk_disable_unprepare(dev->clk_per);
1575 clk_disable_unprepare(dev->clk_ahb);
1576 v4l2_err(&dev->v4l2_dev, "firmware get command error\n");
1577 return -EIO;
1578 }
1579
1580 /* Check we are compatible with the loaded firmware */
1581 data = coda_read(dev, CODA_CMD_FIRMWARE_VERNUM);
1582 product = CODA_FIRMWARE_PRODUCT(data);
1583 major = CODA_FIRMWARE_MAJOR(data);
1584 minor = CODA_FIRMWARE_MINOR(data);
1585 release = CODA_FIRMWARE_RELEASE(data);
1586
1587 clk_disable_unprepare(dev->clk_per);
1588 clk_disable_unprepare(dev->clk_ahb);
1589
1590 if (product != dev->devtype->product) {
1591 v4l2_err(&dev->v4l2_dev, "Wrong firmware. Hw: %s, Fw: %s,"
1592 " Version: %u.%u.%u\n",
1593 coda_product_name(dev->devtype->product),
1594 coda_product_name(product), major, minor, release);
1595 return -EINVAL;
1596 }
1597
1598 v4l2_info(&dev->v4l2_dev, "Initialized %s.\n",
1599 coda_product_name(product));
1600
1601 if (coda_firmware_supported(data)) {
1602 v4l2_info(&dev->v4l2_dev, "Firmware version: %u.%u.%u\n",
1603 major, minor, release);
1604 } else {
1605 v4l2_warn(&dev->v4l2_dev, "Unsupported firmware version: "
1606 "%u.%u.%u\n", major, minor, release);
1607 }
1608
1609 return 0;
1610}
1611
1612static void coda_fw_callback(const struct firmware *fw, void *context)
1613{
1614 struct coda_dev *dev = context;
1615 struct platform_device *pdev = dev->plat_dev;
1616 int ret;
1617
1618 if (!fw) {
1619 v4l2_err(&dev->v4l2_dev, "firmware request failed\n");
1620 return;
1621 }
1622
1623 /* allocate auxiliary per-device code buffer for the BIT processor */
1624 dev->codebuf.size = fw->size;
1625 dev->codebuf.vaddr = dma_alloc_coherent(&pdev->dev, fw->size,
1626 &dev->codebuf.paddr,
1627 GFP_KERNEL);
1628 if (!dev->codebuf.vaddr) {
1629 dev_err(&pdev->dev, "failed to allocate code buffer\n");
1630 return;
1631 }
1632
1633 ret = coda_hw_init(dev, fw);
1634 if (ret) {
1635 v4l2_err(&dev->v4l2_dev, "HW initialization failed\n");
1636 return;
1637 }
1638
1639 dev->vfd.fops = &coda_fops,
1640 dev->vfd.ioctl_ops = &coda_ioctl_ops;
1641 dev->vfd.release = video_device_release_empty,
1642 dev->vfd.lock = &dev->dev_mutex;
1643 dev->vfd.v4l2_dev = &dev->v4l2_dev;
1644 snprintf(dev->vfd.name, sizeof(dev->vfd.name), "%s", CODA_NAME);
1645 video_set_drvdata(&dev->vfd, dev);
1646
1647 dev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
1648 if (IS_ERR(dev->alloc_ctx)) {
1649 v4l2_err(&dev->v4l2_dev, "Failed to alloc vb2 context\n");
1650 return;
1651 }
1652
1653 dev->m2m_dev = v4l2_m2m_init(&coda_m2m_ops);
1654 if (IS_ERR(dev->m2m_dev)) {
1655 v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem device\n");
1656 goto rel_ctx;
1657 }
1658
1659 ret = video_register_device(&dev->vfd, VFL_TYPE_GRABBER, 0);
1660 if (ret) {
1661 v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");
1662 goto rel_m2m;
1663 }
1664 v4l2_info(&dev->v4l2_dev, "codec registered as /dev/video%d\n",
1665 dev->vfd.num);
1666
1667 return;
1668
1669rel_m2m:
1670 v4l2_m2m_release(dev->m2m_dev);
1671rel_ctx:
1672 vb2_dma_contig_cleanup_ctx(dev->alloc_ctx);
1673}
1674
1675static int coda_firmware_request(struct coda_dev *dev)
1676{
1677 char *fw = dev->devtype->firmware;
1678
1679 dev_dbg(&dev->plat_dev->dev, "requesting firmware '%s' for %s\n", fw,
1680 coda_product_name(dev->devtype->product));
1681
1682 return request_firmware_nowait(THIS_MODULE, true,
1683 fw, &dev->plat_dev->dev, GFP_KERNEL, dev, coda_fw_callback);
1684}
1685
1686enum coda_platform {
1687 CODA_IMX27,
1688};
1689
1690static struct coda_devtype coda_devdata[] = {
1691 [CODA_IMX27] = {
1692 .firmware = "v4l-codadx6-imx27.bin",
1693 .product = CODA_DX6,
1694 .formats = codadx6_formats,
1695 .num_formats = ARRAY_SIZE(codadx6_formats),
1696 },
1697};
1698
1699static struct platform_device_id coda_platform_ids[] = {
1700 { .name = "coda-imx27", .driver_data = CODA_IMX27 },
1701 { /* sentinel */ }
1702};
1703MODULE_DEVICE_TABLE(platform, coda_platform_ids);
1704
1705#ifdef CONFIG_OF
1706static const struct of_device_id coda_dt_ids[] = {
1707 { .compatible = "fsl,imx27-vpu", .data = &coda_platform_ids[CODA_IMX27] },
1708 { /* sentinel */ }
1709};
1710MODULE_DEVICE_TABLE(of, coda_dt_ids);
1711#endif
1712
1713static int __devinit coda_probe(struct platform_device *pdev)
1714{
1715 const struct of_device_id *of_id =
1716 of_match_device(of_match_ptr(coda_dt_ids), &pdev->dev);
1717 const struct platform_device_id *pdev_id;
1718 struct coda_dev *dev;
1719 struct resource *res;
1720 int ret, irq;
1721
1722 dev = devm_kzalloc(&pdev->dev, sizeof *dev, GFP_KERNEL);
1723 if (!dev) {
1724 dev_err(&pdev->dev, "Not enough memory for %s\n",
1725 CODA_NAME);
1726 return -ENOMEM;
1727 }
1728
1729 spin_lock_init(&dev->irqlock);
1730
1731 dev->plat_dev = pdev;
1732 dev->clk_per = devm_clk_get(&pdev->dev, "per");
1733 if (IS_ERR(dev->clk_per)) {
1734 dev_err(&pdev->dev, "Could not get per clock\n");
1735 return PTR_ERR(dev->clk_per);
1736 }
1737
1738 dev->clk_ahb = devm_clk_get(&pdev->dev, "ahb");
1739 if (IS_ERR(dev->clk_ahb)) {
1740 dev_err(&pdev->dev, "Could not get ahb clock\n");
1741 return PTR_ERR(dev->clk_ahb);
1742 }
1743
1744 /* Get memory for physical registers */
1745 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1746 if (res == NULL) {
1747 dev_err(&pdev->dev, "failed to get memory region resource\n");
1748 return -ENOENT;
1749 }
1750
1751 if (devm_request_mem_region(&pdev->dev, res->start,
1752 resource_size(res), CODA_NAME) == NULL) {
1753 dev_err(&pdev->dev, "failed to request memory region\n");
1754 return -ENOENT;
1755 }
1756 dev->regs_base = devm_ioremap(&pdev->dev, res->start,
1757 resource_size(res));
1758 if (!dev->regs_base) {
1759 dev_err(&pdev->dev, "failed to ioremap address region\n");
1760 return -ENOENT;
1761 }
1762
1763 /* IRQ */
1764 irq = platform_get_irq(pdev, 0);
1765 if (irq < 0) {
1766 dev_err(&pdev->dev, "failed to get irq resource\n");
1767 return -ENOENT;
1768 }
1769
1770 if (devm_request_irq(&pdev->dev, irq, coda_irq_handler,
1771 0, CODA_NAME, dev) < 0) {
1772 dev_err(&pdev->dev, "failed to request irq\n");
1773 return -ENOENT;
1774 }
1775
1776 ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
1777 if (ret)
1778 return ret;
1779
1780 mutex_init(&dev->dev_mutex);
1781
1782 pdev_id = of_id ? of_id->data : platform_get_device_id(pdev);
1783
1784 if (of_id) {
1785 dev->devtype = of_id->data;
1786 } else if (pdev_id) {
1787 dev->devtype = &coda_devdata[pdev_id->driver_data];
1788 } else {
1789 v4l2_device_unregister(&dev->v4l2_dev);
1790 return -EINVAL;
1791 }
1792
1793 /* allocate auxiliary per-device buffers for the BIT processor */
1794 switch (dev->devtype->product) {
1795 case CODA_DX6:
1796 dev->workbuf.size = CODADX6_WORK_BUF_SIZE;
1797 break;
1798 default:
1799 dev->workbuf.size = CODA7_WORK_BUF_SIZE;
1800 }
1801 dev->workbuf.vaddr = dma_alloc_coherent(&pdev->dev, dev->workbuf.size,
1802 &dev->workbuf.paddr,
1803 GFP_KERNEL);
1804 if (!dev->workbuf.vaddr) {
1805 dev_err(&pdev->dev, "failed to allocate work buffer\n");
1806 v4l2_device_unregister(&dev->v4l2_dev);
1807 return -ENOMEM;
1808 }
1809
1810 platform_set_drvdata(pdev, dev);
1811
1812 return coda_firmware_request(dev);
1813}
1814
1815static int coda_remove(struct platform_device *pdev)
1816{
1817 struct coda_dev *dev = platform_get_drvdata(pdev);
1818
1819 video_unregister_device(&dev->vfd);
1820 if (dev->m2m_dev)
1821 v4l2_m2m_release(dev->m2m_dev);
1822 if (dev->alloc_ctx)
1823 vb2_dma_contig_cleanup_ctx(dev->alloc_ctx);
1824 v4l2_device_unregister(&dev->v4l2_dev);
1825 if (dev->codebuf.vaddr)
1826 dma_free_coherent(&pdev->dev, dev->codebuf.size,
1827 &dev->codebuf.vaddr, dev->codebuf.paddr);
1828 if (dev->workbuf.vaddr)
1829 dma_free_coherent(&pdev->dev, dev->workbuf.size, &dev->workbuf.vaddr,
1830 dev->workbuf.paddr);
1831 return 0;
1832}
1833
1834static struct platform_driver coda_driver = {
1835 .probe = coda_probe,
1836 .remove = __devexit_p(coda_remove),
1837 .driver = {
1838 .name = CODA_NAME,
1839 .owner = THIS_MODULE,
1840 .of_match_table = of_match_ptr(coda_dt_ids),
1841 },
1842 .id_table = coda_platform_ids,
1843};
1844
1845module_platform_driver(coda_driver);
1846
1847MODULE_LICENSE("GPL");
1848MODULE_AUTHOR("Javier Martin <javier.martin@vista-silicon.com>");
1849MODULE_DESCRIPTION("Coda multi-standard codec V4L2 driver");
diff --git a/drivers/media/video/coda.h b/drivers/media/video/coda.h
deleted file mode 100644
index 4cf4a043186f..000000000000
--- a/drivers/media/video/coda.h
+++ /dev/null
@@ -1,216 +0,0 @@
1/*
2 * linux/drivers/media/video/coda/coda_regs.h
3 *
4 * Copyright (C) 2012 Vista Silicon SL
5 * Javier Martin <javier.martin@vista-silicon.com>
6 * Xavier Duret
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 */
13
14#ifndef _REGS_CODA_H_
15#define _REGS_CODA_H_
16
17/* HW registers */
18#define CODA_REG_BIT_CODE_RUN 0x000
19#define CODA_REG_RUN_ENABLE (1 << 0)
20#define CODA_REG_BIT_CODE_DOWN 0x004
21#define CODA_DOWN_ADDRESS_SET(x) (((x) & 0xffff) << 16)
22#define CODA_DOWN_DATA_SET(x) ((x) & 0xffff)
23#define CODA_REG_BIT_HOST_IN_REQ 0x008
24#define CODA_REG_BIT_INT_CLEAR 0x00c
25#define CODA_REG_BIT_INT_CLEAR_SET 0x1
26#define CODA_REG_BIT_INT_STATUS 0x010
27#define CODA_REG_BIT_CODE_RESET 0x014
28#define CODA_REG_RESET_ENABLE (1 << 0)
29#define CODA_REG_BIT_CUR_PC 0x018
30
31/* Static SW registers */
32#define CODA_REG_BIT_CODE_BUF_ADDR 0x100
33#define CODA_REG_BIT_WORK_BUF_ADDR 0x104
34#define CODA_REG_BIT_PARA_BUF_ADDR 0x108
35#define CODA_REG_BIT_STREAM_CTRL 0x10c
36#define CODA7_STREAM_BUF_PIC_RESET (1 << 4)
37#define CODADX6_STREAM_BUF_PIC_RESET (1 << 3)
38#define CODA7_STREAM_BUF_PIC_FLUSH (1 << 3)
39#define CODADX6_STREAM_BUF_PIC_FLUSH (1 << 2)
40#define CODA7_STREAM_BUF_DYNALLOC_EN (1 << 5)
41#define CODADX6_STREAM_BUF_DYNALLOC_EN (1 << 4)
42#define CODA_STREAM_CHKDIS_OFFSET (1 << 1)
43#define CODA_STREAM_ENDIAN_SELECT (1 << 0)
44#define CODA_REG_BIT_FRAME_MEM_CTRL 0x110
45#define CODA_IMAGE_ENDIAN_SELECT (1 << 0)
46#define CODA_REG_BIT_RD_PTR(x) (0x120 + 8 * (x))
47#define CODA_REG_BIT_WR_PTR(x) (0x124 + 8 * (x))
48#define CODA_REG_BIT_SEARCH_RAM_BASE_ADDR 0x140
49#define CODA_REG_BIT_BUSY 0x160
50#define CODA_REG_BIT_BUSY_FLAG 1
51#define CODA_REG_BIT_RUN_COMMAND 0x164
52#define CODA_COMMAND_SEQ_INIT 1
53#define CODA_COMMAND_SEQ_END 2
54#define CODA_COMMAND_PIC_RUN 3
55#define CODA_COMMAND_SET_FRAME_BUF 4
56#define CODA_COMMAND_ENCODE_HEADER 5
57#define CODA_COMMAND_ENC_PARA_SET 6
58#define CODA_COMMAND_DEC_PARA_SET 7
59#define CODA_COMMAND_DEC_BUF_FLUSH 8
60#define CODA_COMMAND_RC_CHANGE_PARAMETER 9
61#define CODA_COMMAND_FIRMWARE_GET 0xf
62#define CODA_REG_BIT_RUN_INDEX 0x168
63#define CODA_INDEX_SET(x) ((x) & 0x3)
64#define CODA_REG_BIT_RUN_COD_STD 0x16c
65#define CODADX6_MODE_DECODE_MP4 0
66#define CODADX6_MODE_ENCODE_MP4 1
67#define CODADX6_MODE_DECODE_H264 2
68#define CODADX6_MODE_ENCODE_H264 3
69#define CODA7_MODE_DECODE_H264 0
70#define CODA7_MODE_DECODE_VC1 1
71#define CODA7_MODE_DECODE_MP2 2
72#define CODA7_MODE_DECODE_MP4 3
73#define CODA7_MODE_DECODE_DV3 3
74#define CODA7_MODE_DECODE_RV 4
75#define CODA7_MODE_DECODE_MJPG 5
76#define CODA7_MODE_ENCODE_H264 8
77#define CODA7_MODE_ENCODE_MP4 11
78#define CODA7_MODE_ENCODE_MJPG 13
79#define CODA_MODE_INVALID 0xffff
80#define CODA_REG_BIT_INT_ENABLE 0x170
81#define CODA_INT_INTERRUPT_ENABLE (1 << 3)
82
83/*
84 * Commands' mailbox:
85 * registers with offsets in the range 0x180-0x1d0
86 * have different meaning depending on the command being
87 * issued.
88 */
89
90/* Encoder Sequence Initialization */
91#define CODA_CMD_ENC_SEQ_BB_START 0x180
92#define CODA_CMD_ENC_SEQ_BB_SIZE 0x184
93#define CODA_CMD_ENC_SEQ_OPTION 0x188
94#define CODA_OPTION_GAMMA_OFFSET 7
95#define CODA_OPTION_GAMMA_MASK 0x01
96#define CODA_OPTION_LIMITQP_OFFSET 6
97#define CODA_OPTION_LIMITQP_MASK 0x01
98#define CODA_OPTION_RCINTRAQP_OFFSET 5
99#define CODA_OPTION_RCINTRAQP_MASK 0x01
100#define CODA_OPTION_FMO_OFFSET 4
101#define CODA_OPTION_FMO_MASK 0x01
102#define CODA_OPTION_SLICEREPORT_OFFSET 1
103#define CODA_OPTION_SLICEREPORT_MASK 0x01
104#define CODA_CMD_ENC_SEQ_COD_STD 0x18c
105#define CODA_STD_MPEG4 0
106#define CODA_STD_H263 1
107#define CODA_STD_H264 2
108#define CODA_STD_MJPG 3
109#define CODA_CMD_ENC_SEQ_SRC_SIZE 0x190
110#define CODA7_PICWIDTH_OFFSET 16
111#define CODA7_PICWIDTH_MASK 0xffff
112#define CODADX6_PICWIDTH_OFFSET 10
113#define CODADX6_PICWIDTH_MASK 0x3ff
114#define CODA_PICHEIGHT_OFFSET 0
115#define CODA_PICHEIGHT_MASK 0x3ff
116#define CODA_CMD_ENC_SEQ_SRC_F_RATE 0x194
117#define CODA_CMD_ENC_SEQ_MP4_PARA 0x198
118#define CODA_MP4PARAM_VERID_OFFSET 6
119#define CODA_MP4PARAM_VERID_MASK 0x01
120#define CODA_MP4PARAM_INTRADCVLCTHR_OFFSET 2
121#define CODA_MP4PARAM_INTRADCVLCTHR_MASK 0x07
122#define CODA_MP4PARAM_REVERSIBLEVLCENABLE_OFFSET 1
123#define CODA_MP4PARAM_REVERSIBLEVLCENABLE_MASK 0x01
124#define CODA_MP4PARAM_DATAPARTITIONENABLE_OFFSET 0
125#define CODA_MP4PARAM_DATAPARTITIONENABLE_MASK 0x01
126#define CODA_CMD_ENC_SEQ_263_PARA 0x19c
127#define CODA_263PARAM_ANNEXJENABLE_OFFSET 2
128#define CODA_263PARAM_ANNEXJENABLE_MASK 0x01
129#define CODA_263PARAM_ANNEXKENABLE_OFFSET 1
130#define CODA_263PARAM_ANNEXKENABLE_MASK 0x01
131#define CODA_263PARAM_ANNEXTENABLE_OFFSET 0
132#define CODA_263PARAM_ANNEXTENABLE_MASK 0x01
133#define CODA_CMD_ENC_SEQ_264_PARA 0x1a0
134#define CODA_264PARAM_DEBLKFILTEROFFSETBETA_OFFSET 12
135#define CODA_264PARAM_DEBLKFILTEROFFSETBETA_MASK 0x0f
136#define CODA_264PARAM_DEBLKFILTEROFFSETALPHA_OFFSET 8
137#define CODA_264PARAM_DEBLKFILTEROFFSETALPHA_MASK 0x0f
138#define CODA_264PARAM_DISABLEDEBLK_OFFSET 6
139#define CODA_264PARAM_DISABLEDEBLK_MASK 0x01
140#define CODA_264PARAM_CONSTRAINEDINTRAPREDFLAG_OFFSET 5
141#define CODA_264PARAM_CONSTRAINEDINTRAPREDFLAG_MASK 0x01
142#define CODA_264PARAM_CHROMAQPOFFSET_OFFSET 0
143#define CODA_264PARAM_CHROMAQPOFFSET_MASK 0x1f
144#define CODA_CMD_ENC_SEQ_SLICE_MODE 0x1a4
145#define CODA_SLICING_SIZE_OFFSET 2
146#define CODA_SLICING_SIZE_MASK 0x3fffffff
147#define CODA_SLICING_UNIT_OFFSET 1
148#define CODA_SLICING_UNIT_MASK 0x01
149#define CODA_SLICING_MODE_OFFSET 0
150#define CODA_SLICING_MODE_MASK 0x01
151#define CODA_CMD_ENC_SEQ_GOP_SIZE 0x1a8
152#define CODA_GOP_SIZE_OFFSET 0
153#define CODA_GOP_SIZE_MASK 0x3f
154#define CODA_CMD_ENC_SEQ_RC_PARA 0x1ac
155#define CODA_RATECONTROL_AUTOSKIP_OFFSET 31
156#define CODA_RATECONTROL_AUTOSKIP_MASK 0x01
157#define CODA_RATECONTROL_INITIALDELAY_OFFSET 16
158#define CODA_RATECONTROL_INITIALDELAY_MASK 0x7f
159#define CODA_RATECONTROL_BITRATE_OFFSET 1
160#define CODA_RATECONTROL_BITRATE_MASK 0x7f
161#define CODA_RATECONTROL_ENABLE_OFFSET 0
162#define CODA_RATECONTROL_ENABLE_MASK 0x01
163#define CODA_CMD_ENC_SEQ_RC_BUF_SIZE 0x1b0
164#define CODA_CMD_ENC_SEQ_INTRA_REFRESH 0x1b4
165#define CODA_CMD_ENC_SEQ_FMO 0x1b8
166#define CODA_FMOPARAM_TYPE_OFFSET 4
167#define CODA_FMOPARAM_TYPE_MASK 1
168#define CODA_FMOPARAM_SLICENUM_OFFSET 0
169#define CODA_FMOPARAM_SLICENUM_MASK 0x0f
170#define CODA_CMD_ENC_SEQ_RC_QP_MAX 0x1c8
171#define CODA_QPMAX_OFFSET 0
172#define CODA_QPMAX_MASK 0x3f
173#define CODA_CMD_ENC_SEQ_RC_GAMMA 0x1cc
174#define CODA_GAMMA_OFFSET 0
175#define CODA_GAMMA_MASK 0xffff
176#define CODA_RET_ENC_SEQ_SUCCESS 0x1c0
177
178/* Encoder Picture Run */
179#define CODA_CMD_ENC_PIC_SRC_ADDR_Y 0x180
180#define CODA_CMD_ENC_PIC_SRC_ADDR_CB 0x184
181#define CODA_CMD_ENC_PIC_SRC_ADDR_CR 0x188
182#define CODA_CMD_ENC_PIC_QS 0x18c
183#define CODA_CMD_ENC_PIC_ROT_MODE 0x190
184#define CODA_CMD_ENC_PIC_OPTION 0x194
185#define CODA_CMD_ENC_PIC_BB_START 0x198
186#define CODA_CMD_ENC_PIC_BB_SIZE 0x19c
187#define CODA_RET_ENC_PIC_TYPE 0x1c4
188#define CODA_RET_ENC_PIC_SLICE_NUM 0x1cc
189#define CODA_RET_ENC_PIC_FLAG 0x1d0
190
191/* Set Frame Buffer */
192#define CODA_CMD_SET_FRAME_BUF_NUM 0x180
193#define CODA_CMD_SET_FRAME_BUF_STRIDE 0x184
194
195/* Encoder Header */
196#define CODA_CMD_ENC_HEADER_CODE 0x180
197#define CODA_GAMMA_OFFSET 0
198#define CODA_HEADER_H264_SPS 0
199#define CODA_HEADER_H264_PPS 1
200#define CODA_HEADER_MP4V_VOL 0
201#define CODA_HEADER_MP4V_VOS 1
202#define CODA_HEADER_MP4V_VIS 2
203#define CODA_CMD_ENC_HEADER_BB_START 0x184
204#define CODA_CMD_ENC_HEADER_BB_SIZE 0x188
205
206/* Get Version */
207#define CODA_CMD_FIRMWARE_VERNUM 0x1c0
208#define CODA_FIRMWARE_PRODUCT(x) (((x) >> 16) & 0xffff)
209#define CODA_FIRMWARE_MAJOR(x) (((x) >> 12) & 0x0f)
210#define CODA_FIRMWARE_MINOR(x) (((x) >> 8) & 0x0f)
211#define CODA_FIRMWARE_RELEASE(x) ((x) & 0xff)
212#define CODA_FIRMWARE_VERNUM(product, major, minor, release) \
213 ((product) << 16 | ((major) << 12) | \
214 ((minor) << 8) | (release))
215
216#endif
diff --git a/drivers/media/video/davinci/Kconfig b/drivers/media/video/davinci/Kconfig
deleted file mode 100644
index 52c5ca68cb3d..000000000000
--- a/drivers/media/video/davinci/Kconfig
+++ /dev/null
@@ -1,121 +0,0 @@
1config VIDEO_DAVINCI_VPIF_DISPLAY
2 tristate "DM646x/DA850/OMAPL138 EVM Video Display"
3 depends on VIDEO_DEV && (MACH_DAVINCI_DM6467_EVM || MACH_DAVINCI_DA850_EVM)
4 select VIDEOBUF2_DMA_CONTIG
5 select VIDEO_DAVINCI_VPIF
6 select VIDEO_ADV7343 if VIDEO_HELPER_CHIPS_AUTO
7 select VIDEO_THS7303 if VIDEO_HELPER_CHIPS_AUTO
8 help
9 Enables Davinci VPIF module used for display devices.
10 This module is common for following DM6467/DA850/OMAPL138
11 based display devices.
12
13 To compile this driver as a module, choose M here: the
14 module will be called vpif_display.
15
16config VIDEO_DAVINCI_VPIF_CAPTURE
17 tristate "DM646x/DA850/OMAPL138 EVM Video Capture"
18 depends on VIDEO_DEV && (MACH_DAVINCI_DM6467_EVM || MACH_DAVINCI_DA850_EVM)
19 select VIDEOBUF2_DMA_CONTIG
20 select VIDEO_DAVINCI_VPIF
21 help
22 Enables Davinci VPIF module used for captur devices.
23 This module is common for following DM6467/DA850/OMAPL138
24 based capture devices.
25
26 To compile this driver as a module, choose M here: the
27 module will be called vpif_capture.
28
29config VIDEO_DAVINCI_VPIF
30 tristate "DaVinci VPIF Driver"
31 depends on VIDEO_DAVINCI_VPIF_DISPLAY || VIDEO_DAVINCI_VPIF_CAPTURE
32 help
33 Support for DaVinci VPIF Driver.
34
35 To compile this driver as a module, choose M here: the
36 module will be called vpif.
37
38config VIDEO_VPSS_SYSTEM
39 tristate "VPSS System module driver"
40 depends on ARCH_DAVINCI
41 help
42 Support for vpss system module for video driver
43
44config VIDEO_VPFE_CAPTURE
45 tristate "VPFE Video Capture Driver"
46 depends on VIDEO_V4L2 && (ARCH_DAVINCI || ARCH_OMAP3)
47 depends on I2C
48 select VIDEOBUF_DMA_CONTIG
49 help
50 Support for DMx/AMx VPFE based frame grabber. This is the
51 common V4L2 module for following DMx/AMx SoCs from Texas
52 Instruments:- DM6446, DM365, DM355 & AM3517/05.
53
54 To compile this driver as a module, choose M here: the
55 module will be called vpfe-capture.
56
57config VIDEO_DM6446_CCDC
58 tristate "DM6446 CCDC HW module"
59 depends on VIDEO_VPFE_CAPTURE
60 select VIDEO_VPSS_SYSTEM
61 default y
62 help
63 Enables DaVinci CCD hw module. DaVinci CCDC hw interfaces
64 with decoder modules such as TVP5146 over BT656 or
65 sensor module such as MT9T001 over a raw interface. This
66 module configures the interface and CCDC/ISIF to do
67 video frame capture from slave decoders.
68
69 To compile this driver as a module, choose M here: the
70 module will be called vpfe.
71
72config VIDEO_DM355_CCDC
73 tristate "DM355 CCDC HW module"
74 depends on ARCH_DAVINCI_DM355 && VIDEO_VPFE_CAPTURE
75 select VIDEO_VPSS_SYSTEM
76 default y
77 help
78 Enables DM355 CCD hw module. DM355 CCDC hw interfaces
79 with decoder modules such as TVP5146 over BT656 or
80 sensor module such as MT9T001 over a raw interface. This
81 module configures the interface and CCDC/ISIF to do
82 video frame capture from a slave decoders
83
84 To compile this driver as a module, choose M here: the
85 module will be called vpfe.
86
87config VIDEO_ISIF
88 tristate "ISIF HW module"
89 depends on ARCH_DAVINCI_DM365 && VIDEO_VPFE_CAPTURE
90 select VIDEO_VPSS_SYSTEM
91 default y
92 help
93 Enables ISIF hw module. This is the hardware module for
94 configuring ISIF in VPFE to capture Raw Bayer RGB data from
95 a image sensor or YUV data from a YUV source.
96
97 To compile this driver as a module, choose M here: the
98 module will be called vpfe.
99
100config VIDEO_DM644X_VPBE
101 tristate "DM644X VPBE HW module"
102 depends on ARCH_DAVINCI_DM644x
103 select VIDEO_VPSS_SYSTEM
104 select VIDEOBUF_DMA_CONTIG
105 help
106 Enables VPBE modules used for display on a DM644x
107 SoC.
108
109 To compile this driver as a module, choose M here: the
110 module will be called vpbe.
111
112
113config VIDEO_VPBE_DISPLAY
114 tristate "VPBE V4L2 Display driver"
115 depends on ARCH_DAVINCI_DM644x
116 select VIDEO_DM644X_VPBE
117 help
118 Enables VPBE V4L2 Display driver on a DM644x device
119
120 To compile this driver as a module, choose M here: the
121 module will be called vpbe_display.
diff --git a/drivers/media/video/davinci/Makefile b/drivers/media/video/davinci/Makefile
deleted file mode 100644
index 74ed92d09257..000000000000
--- a/drivers/media/video/davinci/Makefile
+++ /dev/null
@@ -1,20 +0,0 @@
1#
2# Makefile for the davinci video device drivers.
3#
4
5# VPIF
6obj-$(CONFIG_VIDEO_DAVINCI_VPIF) += vpif.o
7
8#VPIF Display driver
9obj-$(CONFIG_VIDEO_DAVINCI_VPIF_DISPLAY) += vpif_display.o
10#VPIF Capture driver
11obj-$(CONFIG_VIDEO_DAVINCI_VPIF_CAPTURE) += vpif_capture.o
12
13# Capture: DM6446 and DM355
14obj-$(CONFIG_VIDEO_VPSS_SYSTEM) += vpss.o
15obj-$(CONFIG_VIDEO_VPFE_CAPTURE) += vpfe_capture.o
16obj-$(CONFIG_VIDEO_DM6446_CCDC) += dm644x_ccdc.o
17obj-$(CONFIG_VIDEO_DM355_CCDC) += dm355_ccdc.o
18obj-$(CONFIG_VIDEO_ISIF) += isif.o
19obj-$(CONFIG_VIDEO_DM644X_VPBE) += vpbe.o vpbe_osd.o vpbe_venc.o
20obj-$(CONFIG_VIDEO_VPBE_DISPLAY) += vpbe_display.o
diff --git a/drivers/media/video/davinci/ccdc_hw_device.h b/drivers/media/video/davinci/ccdc_hw_device.h
deleted file mode 100644
index 86b9b3518965..000000000000
--- a/drivers/media/video/davinci/ccdc_hw_device.h
+++ /dev/null
@@ -1,110 +0,0 @@
1/*
2 * Copyright (C) 2008-2009 Texas Instruments Inc
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * ccdc device API
19 */
20#ifndef _CCDC_HW_DEVICE_H
21#define _CCDC_HW_DEVICE_H
22
23#ifdef __KERNEL__
24#include <linux/videodev2.h>
25#include <linux/device.h>
26#include <media/davinci/vpfe_types.h>
27#include <media/davinci/ccdc_types.h>
28
29/*
30 * ccdc hw operations
31 */
32struct ccdc_hw_ops {
33 /* Pointer to initialize function to initialize ccdc device */
34 int (*open) (struct device *dev);
35 /* Pointer to deinitialize function */
36 int (*close) (struct device *dev);
37 /* set ccdc base address */
38 void (*set_ccdc_base)(void *base, int size);
39 /* Pointer to function to enable or disable ccdc */
40 void (*enable) (int en);
41 /* reset sbl. only for 6446 */
42 void (*reset) (void);
43 /* enable output to sdram */
44 void (*enable_out_to_sdram) (int en);
45 /* Pointer to function to set hw parameters */
46 int (*set_hw_if_params) (struct vpfe_hw_if_param *param);
47 /* get interface parameters */
48 int (*get_hw_if_params) (struct vpfe_hw_if_param *param);
49 /*
50 * Pointer to function to set parameters. Used
51 * for implementing VPFE_S_CCDC_PARAMS
52 */
53 int (*set_params) (void *params);
54 /*
55 * Pointer to function to get parameter. Used
56 * for implementing VPFE_G_CCDC_PARAMS
57 */
58 int (*get_params) (void *params);
59 /* Pointer to function to configure ccdc */
60 int (*configure) (void);
61
62 /* Pointer to function to set buffer type */
63 int (*set_buftype) (enum ccdc_buftype buf_type);
64 /* Pointer to function to get buffer type */
65 enum ccdc_buftype (*get_buftype) (void);
66 /* Pointer to function to set frame format */
67 int (*set_frame_format) (enum ccdc_frmfmt frm_fmt);
68 /* Pointer to function to get frame format */
69 enum ccdc_frmfmt (*get_frame_format) (void);
70 /* enumerate hw pix formats */
71 int (*enum_pix)(u32 *hw_pix, int i);
72 /* Pointer to function to set buffer type */
73 u32 (*get_pixel_format) (void);
74 /* Pointer to function to get pixel format. */
75 int (*set_pixel_format) (u32 pixfmt);
76 /* Pointer to function to set image window */
77 int (*set_image_window) (struct v4l2_rect *win);
78 /* Pointer to function to set image window */
79 void (*get_image_window) (struct v4l2_rect *win);
80 /* Pointer to function to get line length */
81 unsigned int (*get_line_length) (void);
82
83 /* Query CCDC control IDs */
84 int (*queryctrl)(struct v4l2_queryctrl *qctrl);
85 /* Set CCDC control */
86 int (*set_control)(struct v4l2_control *ctrl);
87 /* Get CCDC control */
88 int (*get_control)(struct v4l2_control *ctrl);
89
90 /* Pointer to function to set frame buffer address */
91 void (*setfbaddr) (unsigned long addr);
92 /* Pointer to function to get field id */
93 int (*getfid) (void);
94};
95
96struct ccdc_hw_device {
97 /* ccdc device name */
98 char name[32];
99 /* module owner */
100 struct module *owner;
101 /* hw ops */
102 struct ccdc_hw_ops hw_ops;
103};
104
105/* Used by CCDC module to register & unregister with vpfe capture driver */
106int vpfe_register_ccdc_device(struct ccdc_hw_device *dev);
107void vpfe_unregister_ccdc_device(struct ccdc_hw_device *dev);
108
109#endif
110#endif
diff --git a/drivers/media/video/davinci/dm355_ccdc.c b/drivers/media/video/davinci/dm355_ccdc.c
deleted file mode 100644
index ce0e4131c067..000000000000
--- a/drivers/media/video/davinci/dm355_ccdc.c
+++ /dev/null
@@ -1,1072 +0,0 @@
1/*
2 * Copyright (C) 2005-2009 Texas Instruments Inc
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * CCDC hardware module for DM355
19 * ------------------------------
20 *
21 * This module is for configuring DM355 CCD controller of VPFE to capture
22 * Raw yuv or Bayer RGB data from a decoder. CCDC has several modules
23 * such as Defect Pixel Correction, Color Space Conversion etc to
24 * pre-process the Bayer RGB data, before writing it to SDRAM. This
25 * module also allows application to configure individual
26 * module parameters through VPFE_CMD_S_CCDC_RAW_PARAMS IOCTL.
27 * To do so, application include dm355_ccdc.h and vpfe_capture.h header
28 * files. The setparams() API is called by vpfe_capture driver
29 * to configure module parameters
30 *
31 * TODO: 1) Raw bayer parameter settings and bayer capture
32 * 2) Split module parameter structure to module specific ioctl structs
33 * 3) add support for lense shading correction
34 * 4) investigate if enum used for user space type definition
35 * to be replaced by #defines or integer
36 */
37#include <linux/platform_device.h>
38#include <linux/uaccess.h>
39#include <linux/videodev2.h>
40#include <linux/clk.h>
41#include <linux/err.h>
42#include <linux/module.h>
43
44#include <media/davinci/dm355_ccdc.h>
45#include <media/davinci/vpss.h>
46
47#include "dm355_ccdc_regs.h"
48#include "ccdc_hw_device.h"
49
50MODULE_LICENSE("GPL");
51MODULE_DESCRIPTION("CCDC Driver for DM355");
52MODULE_AUTHOR("Texas Instruments");
53
54static struct ccdc_oper_config {
55 struct device *dev;
56 /* CCDC interface type */
57 enum vpfe_hw_if_type if_type;
58 /* Raw Bayer configuration */
59 struct ccdc_params_raw bayer;
60 /* YCbCr configuration */
61 struct ccdc_params_ycbcr ycbcr;
62 /* Master clock */
63 struct clk *mclk;
64 /* slave clock */
65 struct clk *sclk;
66 /* ccdc base address */
67 void __iomem *base_addr;
68} ccdc_cfg = {
69 /* Raw configurations */
70 .bayer = {
71 .pix_fmt = CCDC_PIXFMT_RAW,
72 .frm_fmt = CCDC_FRMFMT_PROGRESSIVE,
73 .win = CCDC_WIN_VGA,
74 .fid_pol = VPFE_PINPOL_POSITIVE,
75 .vd_pol = VPFE_PINPOL_POSITIVE,
76 .hd_pol = VPFE_PINPOL_POSITIVE,
77 .gain = {
78 .r_ye = 256,
79 .gb_g = 256,
80 .gr_cy = 256,
81 .b_mg = 256
82 },
83 .config_params = {
84 .datasft = 2,
85 .mfilt1 = CCDC_NO_MEDIAN_FILTER1,
86 .mfilt2 = CCDC_NO_MEDIAN_FILTER2,
87 .alaw = {
88 .gama_wd = 2,
89 },
90 .blk_clamp = {
91 .sample_pixel = 1,
92 .dc_sub = 25
93 },
94 .col_pat_field0 = {
95 .olop = CCDC_GREEN_BLUE,
96 .olep = CCDC_BLUE,
97 .elop = CCDC_RED,
98 .elep = CCDC_GREEN_RED
99 },
100 .col_pat_field1 = {
101 .olop = CCDC_GREEN_BLUE,
102 .olep = CCDC_BLUE,
103 .elop = CCDC_RED,
104 .elep = CCDC_GREEN_RED
105 },
106 },
107 },
108 /* YCbCr configuration */
109 .ycbcr = {
110 .win = CCDC_WIN_PAL,
111 .pix_fmt = CCDC_PIXFMT_YCBCR_8BIT,
112 .frm_fmt = CCDC_FRMFMT_INTERLACED,
113 .fid_pol = VPFE_PINPOL_POSITIVE,
114 .vd_pol = VPFE_PINPOL_POSITIVE,
115 .hd_pol = VPFE_PINPOL_POSITIVE,
116 .bt656_enable = 1,
117 .pix_order = CCDC_PIXORDER_CBYCRY,
118 .buf_type = CCDC_BUFTYPE_FLD_INTERLEAVED
119 },
120};
121
122
123/* Raw Bayer formats */
124static u32 ccdc_raw_bayer_pix_formats[] =
125 {V4L2_PIX_FMT_SBGGR8, V4L2_PIX_FMT_SBGGR16};
126
127/* Raw YUV formats */
128static u32 ccdc_raw_yuv_pix_formats[] =
129 {V4L2_PIX_FMT_UYVY, V4L2_PIX_FMT_YUYV};
130
131/* register access routines */
132static inline u32 regr(u32 offset)
133{
134 return __raw_readl(ccdc_cfg.base_addr + offset);
135}
136
137static inline void regw(u32 val, u32 offset)
138{
139 __raw_writel(val, ccdc_cfg.base_addr + offset);
140}
141
142static void ccdc_enable(int en)
143{
144 unsigned int temp;
145 temp = regr(SYNCEN);
146 temp &= (~CCDC_SYNCEN_VDHDEN_MASK);
147 temp |= (en & CCDC_SYNCEN_VDHDEN_MASK);
148 regw(temp, SYNCEN);
149}
150
151static void ccdc_enable_output_to_sdram(int en)
152{
153 unsigned int temp;
154 temp = regr(SYNCEN);
155 temp &= (~(CCDC_SYNCEN_WEN_MASK));
156 temp |= ((en << CCDC_SYNCEN_WEN_SHIFT) & CCDC_SYNCEN_WEN_MASK);
157 regw(temp, SYNCEN);
158}
159
160static void ccdc_config_gain_offset(void)
161{
162 /* configure gain */
163 regw(ccdc_cfg.bayer.gain.r_ye, RYEGAIN);
164 regw(ccdc_cfg.bayer.gain.gr_cy, GRCYGAIN);
165 regw(ccdc_cfg.bayer.gain.gb_g, GBGGAIN);
166 regw(ccdc_cfg.bayer.gain.b_mg, BMGGAIN);
167 /* configure offset */
168 regw(ccdc_cfg.bayer.ccdc_offset, OFFSET);
169}
170
171/*
172 * ccdc_restore_defaults()
173 * This function restore power on defaults in the ccdc registers
174 */
175static int ccdc_restore_defaults(void)
176{
177 int i;
178
179 dev_dbg(ccdc_cfg.dev, "\nstarting ccdc_restore_defaults...");
180 /* set all registers to zero */
181 for (i = 0; i <= CCDC_REG_LAST; i += 4)
182 regw(0, i);
183
184 /* now override the values with power on defaults in registers */
185 regw(MODESET_DEFAULT, MODESET);
186 /* no culling support */
187 regw(CULH_DEFAULT, CULH);
188 regw(CULV_DEFAULT, CULV);
189 /* Set default Gain and Offset */
190 ccdc_cfg.bayer.gain.r_ye = GAIN_DEFAULT;
191 ccdc_cfg.bayer.gain.gb_g = GAIN_DEFAULT;
192 ccdc_cfg.bayer.gain.gr_cy = GAIN_DEFAULT;
193 ccdc_cfg.bayer.gain.b_mg = GAIN_DEFAULT;
194 ccdc_config_gain_offset();
195 regw(OUTCLIP_DEFAULT, OUTCLIP);
196 regw(LSCCFG2_DEFAULT, LSCCFG2);
197 /* select ccdc input */
198 if (vpss_select_ccdc_source(VPSS_CCDCIN)) {
199 dev_dbg(ccdc_cfg.dev, "\ncouldn't select ccdc input source");
200 return -EFAULT;
201 }
202 /* select ccdc clock */
203 if (vpss_enable_clock(VPSS_CCDC_CLOCK, 1) < 0) {
204 dev_dbg(ccdc_cfg.dev, "\ncouldn't enable ccdc clock");
205 return -EFAULT;
206 }
207 dev_dbg(ccdc_cfg.dev, "\nEnd of ccdc_restore_defaults...");
208 return 0;
209}
210
211static int ccdc_open(struct device *device)
212{
213 return ccdc_restore_defaults();
214}
215
216static int ccdc_close(struct device *device)
217{
218 /* disable clock */
219 vpss_enable_clock(VPSS_CCDC_CLOCK, 0);
220 /* do nothing for now */
221 return 0;
222}
223/*
224 * ccdc_setwin()
225 * This function will configure the window size to
226 * be capture in CCDC reg.
227 */
228static void ccdc_setwin(struct v4l2_rect *image_win,
229 enum ccdc_frmfmt frm_fmt, int ppc)
230{
231 int horz_start, horz_nr_pixels;
232 int vert_start, vert_nr_lines;
233 int mid_img = 0;
234
235 dev_dbg(ccdc_cfg.dev, "\nStarting ccdc_setwin...");
236
237 /*
238 * ppc - per pixel count. indicates how many pixels per cell
239 * output to SDRAM. example, for ycbcr, it is one y and one c, so 2.
240 * raw capture this is 1
241 */
242 horz_start = image_win->left << (ppc - 1);
243 horz_nr_pixels = ((image_win->width) << (ppc - 1)) - 1;
244
245 /* Writing the horizontal info into the registers */
246 regw(horz_start, SPH);
247 regw(horz_nr_pixels, NPH);
248 vert_start = image_win->top;
249
250 if (frm_fmt == CCDC_FRMFMT_INTERLACED) {
251 vert_nr_lines = (image_win->height >> 1) - 1;
252 vert_start >>= 1;
253 /* Since first line doesn't have any data */
254 vert_start += 1;
255 /* configure VDINT0 and VDINT1 */
256 regw(vert_start, VDINT0);
257 } else {
258 /* Since first line doesn't have any data */
259 vert_start += 1;
260 vert_nr_lines = image_win->height - 1;
261 /* configure VDINT0 and VDINT1 */
262 mid_img = vert_start + (image_win->height / 2);
263 regw(vert_start, VDINT0);
264 regw(mid_img, VDINT1);
265 }
266 regw(vert_start & CCDC_START_VER_ONE_MASK, SLV0);
267 regw(vert_start & CCDC_START_VER_TWO_MASK, SLV1);
268 regw(vert_nr_lines & CCDC_NUM_LINES_VER, NLV);
269 dev_dbg(ccdc_cfg.dev, "\nEnd of ccdc_setwin...");
270}
271
272static int validate_ccdc_param(struct ccdc_config_params_raw *ccdcparam)
273{
274 if (ccdcparam->datasft < CCDC_DATA_NO_SHIFT ||
275 ccdcparam->datasft > CCDC_DATA_SHIFT_6BIT) {
276 dev_dbg(ccdc_cfg.dev, "Invalid value of data shift\n");
277 return -EINVAL;
278 }
279
280 if (ccdcparam->mfilt1 < CCDC_NO_MEDIAN_FILTER1 ||
281 ccdcparam->mfilt1 > CCDC_MEDIAN_FILTER1) {
282 dev_dbg(ccdc_cfg.dev, "Invalid value of median filter1\n");
283 return -EINVAL;
284 }
285
286 if (ccdcparam->mfilt2 < CCDC_NO_MEDIAN_FILTER2 ||
287 ccdcparam->mfilt2 > CCDC_MEDIAN_FILTER2) {
288 dev_dbg(ccdc_cfg.dev, "Invalid value of median filter2\n");
289 return -EINVAL;
290 }
291
292 if ((ccdcparam->med_filt_thres < 0) ||
293 (ccdcparam->med_filt_thres > CCDC_MED_FILT_THRESH)) {
294 dev_dbg(ccdc_cfg.dev,
295 "Invalid value of median filter threshold\n");
296 return -EINVAL;
297 }
298
299 if (ccdcparam->data_sz < CCDC_DATA_16BITS ||
300 ccdcparam->data_sz > CCDC_DATA_8BITS) {
301 dev_dbg(ccdc_cfg.dev, "Invalid value of data size\n");
302 return -EINVAL;
303 }
304
305 if (ccdcparam->alaw.enable) {
306 if (ccdcparam->alaw.gama_wd < CCDC_GAMMA_BITS_13_4 ||
307 ccdcparam->alaw.gama_wd > CCDC_GAMMA_BITS_09_0) {
308 dev_dbg(ccdc_cfg.dev, "Invalid value of ALAW\n");
309 return -EINVAL;
310 }
311 }
312
313 if (ccdcparam->blk_clamp.b_clamp_enable) {
314 if (ccdcparam->blk_clamp.sample_pixel < CCDC_SAMPLE_1PIXELS ||
315 ccdcparam->blk_clamp.sample_pixel > CCDC_SAMPLE_16PIXELS) {
316 dev_dbg(ccdc_cfg.dev,
317 "Invalid value of sample pixel\n");
318 return -EINVAL;
319 }
320 if (ccdcparam->blk_clamp.sample_ln < CCDC_SAMPLE_1LINES ||
321 ccdcparam->blk_clamp.sample_ln > CCDC_SAMPLE_16LINES) {
322 dev_dbg(ccdc_cfg.dev,
323 "Invalid value of sample lines\n");
324 return -EINVAL;
325 }
326 }
327 return 0;
328}
329
330/* Parameter operations */
331static int ccdc_set_params(void __user *params)
332{
333 struct ccdc_config_params_raw ccdc_raw_params;
334 int x;
335
336 /* only raw module parameters can be set through the IOCTL */
337 if (ccdc_cfg.if_type != VPFE_RAW_BAYER)
338 return -EINVAL;
339
340 x = copy_from_user(&ccdc_raw_params, params, sizeof(ccdc_raw_params));
341 if (x) {
342 dev_dbg(ccdc_cfg.dev, "ccdc_set_params: error in copying ccdc"
343 "params, %d\n", x);
344 return -EFAULT;
345 }
346
347 if (!validate_ccdc_param(&ccdc_raw_params)) {
348 memcpy(&ccdc_cfg.bayer.config_params,
349 &ccdc_raw_params,
350 sizeof(ccdc_raw_params));
351 return 0;
352 }
353 return -EINVAL;
354}
355
356/* This function will configure CCDC for YCbCr video capture */
357static void ccdc_config_ycbcr(void)
358{
359 struct ccdc_params_ycbcr *params = &ccdc_cfg.ycbcr;
360 u32 temp;
361
362 /* first set the CCDC power on defaults values in all registers */
363 dev_dbg(ccdc_cfg.dev, "\nStarting ccdc_config_ycbcr...");
364 ccdc_restore_defaults();
365
366 /* configure pixel format & video frame format */
367 temp = (((params->pix_fmt & CCDC_INPUT_MODE_MASK) <<
368 CCDC_INPUT_MODE_SHIFT) |
369 ((params->frm_fmt & CCDC_FRM_FMT_MASK) <<
370 CCDC_FRM_FMT_SHIFT));
371
372 /* setup BT.656 sync mode */
373 if (params->bt656_enable) {
374 regw(CCDC_REC656IF_BT656_EN, REC656IF);
375 /*
376 * configure the FID, VD, HD pin polarity fld,hd pol positive,
377 * vd negative, 8-bit pack mode
378 */
379 temp |= CCDC_VD_POL_NEGATIVE;
380 } else { /* y/c external sync mode */
381 temp |= (((params->fid_pol & CCDC_FID_POL_MASK) <<
382 CCDC_FID_POL_SHIFT) |
383 ((params->hd_pol & CCDC_HD_POL_MASK) <<
384 CCDC_HD_POL_SHIFT) |
385 ((params->vd_pol & CCDC_VD_POL_MASK) <<
386 CCDC_VD_POL_SHIFT));
387 }
388
389 /* pack the data to 8-bit */
390 temp |= CCDC_DATA_PACK_ENABLE;
391
392 regw(temp, MODESET);
393
394 /* configure video window */
395 ccdc_setwin(&params->win, params->frm_fmt, 2);
396
397 /* configure the order of y cb cr in SD-RAM */
398 temp = (params->pix_order << CCDC_Y8POS_SHIFT);
399 temp |= CCDC_LATCH_ON_VSYNC_DISABLE | CCDC_CCDCFG_FIDMD_NO_LATCH_VSYNC;
400 regw(temp, CCDCFG);
401
402 /*
403 * configure the horizontal line offset. This is done by rounding up
404 * width to a multiple of 16 pixels and multiply by two to account for
405 * y:cb:cr 4:2:2 data
406 */
407 regw(((params->win.width * 2 + 31) >> 5), HSIZE);
408
409 /* configure the memory line offset */
410 if (params->buf_type == CCDC_BUFTYPE_FLD_INTERLEAVED) {
411 /* two fields are interleaved in memory */
412 regw(CCDC_SDOFST_FIELD_INTERLEAVED, SDOFST);
413 }
414
415 dev_dbg(ccdc_cfg.dev, "\nEnd of ccdc_config_ycbcr...\n");
416}
417
418/*
419 * ccdc_config_black_clamp()
420 * configure parameters for Optical Black Clamp
421 */
422static void ccdc_config_black_clamp(struct ccdc_black_clamp *bclamp)
423{
424 u32 val;
425
426 if (!bclamp->b_clamp_enable) {
427 /* configure DCSub */
428 regw(bclamp->dc_sub & CCDC_BLK_DC_SUB_MASK, DCSUB);
429 regw(0x0000, CLAMP);
430 return;
431 }
432 /* Enable the Black clamping, set sample lines and pixels */
433 val = (bclamp->start_pixel & CCDC_BLK_ST_PXL_MASK) |
434 ((bclamp->sample_pixel & CCDC_BLK_SAMPLE_LN_MASK) <<
435 CCDC_BLK_SAMPLE_LN_SHIFT) | CCDC_BLK_CLAMP_ENABLE;
436 regw(val, CLAMP);
437
438 /* If Black clamping is enable then make dcsub 0 */
439 val = (bclamp->sample_ln & CCDC_NUM_LINE_CALC_MASK)
440 << CCDC_NUM_LINE_CALC_SHIFT;
441 regw(val, DCSUB);
442}
443
444/*
445 * ccdc_config_black_compense()
446 * configure parameters for Black Compensation
447 */
448static void ccdc_config_black_compense(struct ccdc_black_compensation *bcomp)
449{
450 u32 val;
451
452 val = (bcomp->b & CCDC_BLK_COMP_MASK) |
453 ((bcomp->gb & CCDC_BLK_COMP_MASK) <<
454 CCDC_BLK_COMP_GB_COMP_SHIFT);
455 regw(val, BLKCMP1);
456
457 val = ((bcomp->gr & CCDC_BLK_COMP_MASK) <<
458 CCDC_BLK_COMP_GR_COMP_SHIFT) |
459 ((bcomp->r & CCDC_BLK_COMP_MASK) <<
460 CCDC_BLK_COMP_R_COMP_SHIFT);
461 regw(val, BLKCMP0);
462}
463
464/*
465 * ccdc_write_dfc_entry()
466 * write an entry in the dfc table.
467 */
468int ccdc_write_dfc_entry(int index, struct ccdc_vertical_dft *dfc)
469{
470/* TODO This is to be re-visited and adjusted */
471#define DFC_WRITE_WAIT_COUNT 1000
472 u32 val, count = DFC_WRITE_WAIT_COUNT;
473
474 regw(dfc->dft_corr_vert[index], DFCMEM0);
475 regw(dfc->dft_corr_horz[index], DFCMEM1);
476 regw(dfc->dft_corr_sub1[index], DFCMEM2);
477 regw(dfc->dft_corr_sub2[index], DFCMEM3);
478 regw(dfc->dft_corr_sub3[index], DFCMEM4);
479 /* set WR bit to write */
480 val = regr(DFCMEMCTL) | CCDC_DFCMEMCTL_DFCMWR_MASK;
481 regw(val, DFCMEMCTL);
482
483 /*
484 * Assume, it is very short. If we get an error, we need to
485 * adjust this value
486 */
487 while (regr(DFCMEMCTL) & CCDC_DFCMEMCTL_DFCMWR_MASK)
488 count--;
489 /*
490 * TODO We expect the count to be non-zero to be successful. Adjust
491 * the count if write requires more time
492 */
493
494 if (count) {
495 dev_err(ccdc_cfg.dev, "defect table write timeout !!!\n");
496 return -1;
497 }
498 return 0;
499}
500
501/*
502 * ccdc_config_vdfc()
503 * configure parameters for Vertical Defect Correction
504 */
505static int ccdc_config_vdfc(struct ccdc_vertical_dft *dfc)
506{
507 u32 val;
508 int i;
509
510 /* Configure General Defect Correction. The table used is from IPIPE */
511 val = dfc->gen_dft_en & CCDC_DFCCTL_GDFCEN_MASK;
512
513 /* Configure Vertical Defect Correction if needed */
514 if (!dfc->ver_dft_en) {
515 /* Enable only General Defect Correction */
516 regw(val, DFCCTL);
517 return 0;
518 }
519
520 if (dfc->table_size > CCDC_DFT_TABLE_SIZE)
521 return -EINVAL;
522
523 val |= CCDC_DFCCTL_VDFC_DISABLE;
524 val |= (dfc->dft_corr_ctl.vdfcsl & CCDC_DFCCTL_VDFCSL_MASK) <<
525 CCDC_DFCCTL_VDFCSL_SHIFT;
526 val |= (dfc->dft_corr_ctl.vdfcuda & CCDC_DFCCTL_VDFCUDA_MASK) <<
527 CCDC_DFCCTL_VDFCUDA_SHIFT;
528 val |= (dfc->dft_corr_ctl.vdflsft & CCDC_DFCCTL_VDFLSFT_MASK) <<
529 CCDC_DFCCTL_VDFLSFT_SHIFT;
530 regw(val , DFCCTL);
531
532 /* clear address ptr to offset 0 */
533 val = CCDC_DFCMEMCTL_DFCMARST_MASK << CCDC_DFCMEMCTL_DFCMARST_SHIFT;
534
535 /* write defect table entries */
536 for (i = 0; i < dfc->table_size; i++) {
537 /* increment address for non zero index */
538 if (i != 0)
539 val = CCDC_DFCMEMCTL_INC_ADDR;
540 regw(val, DFCMEMCTL);
541 if (ccdc_write_dfc_entry(i, dfc) < 0)
542 return -EFAULT;
543 }
544
545 /* update saturation level and enable dfc */
546 regw(dfc->saturation_ctl & CCDC_VDC_DFCVSAT_MASK, DFCVSAT);
547 val = regr(DFCCTL) | (CCDC_DFCCTL_VDFCEN_MASK <<
548 CCDC_DFCCTL_VDFCEN_SHIFT);
549 regw(val, DFCCTL);
550 return 0;
551}
552
553/*
554 * ccdc_config_csc()
555 * configure parameters for color space conversion
556 * Each register CSCM0-7 has two values in S8Q5 format.
557 */
558static void ccdc_config_csc(struct ccdc_csc *csc)
559{
560 u32 val1, val2;
561 int i;
562
563 if (!csc->enable)
564 return;
565
566 /* Enable the CSC sub-module */
567 regw(CCDC_CSC_ENABLE, CSCCTL);
568
569 /* Converting the co-eff as per the format of the register */
570 for (i = 0; i < CCDC_CSC_COEFF_TABLE_SIZE; i++) {
571 if ((i % 2) == 0) {
572 /* CSCM - LSB */
573 val1 = (csc->coeff[i].integer &
574 CCDC_CSC_COEF_INTEG_MASK)
575 << CCDC_CSC_COEF_INTEG_SHIFT;
576 /*
577 * convert decimal part to binary. Use 2 decimal
578 * precision, user values range from .00 - 0.99
579 */
580 val1 |= (((csc->coeff[i].decimal &
581 CCDC_CSC_COEF_DECIMAL_MASK) *
582 CCDC_CSC_DEC_MAX) / 100);
583 } else {
584
585 /* CSCM - MSB */
586 val2 = (csc->coeff[i].integer &
587 CCDC_CSC_COEF_INTEG_MASK)
588 << CCDC_CSC_COEF_INTEG_SHIFT;
589 val2 |= (((csc->coeff[i].decimal &
590 CCDC_CSC_COEF_DECIMAL_MASK) *
591 CCDC_CSC_DEC_MAX) / 100);
592 val2 <<= CCDC_CSCM_MSB_SHIFT;
593 val2 |= val1;
594 regw(val2, (CSCM0 + ((i - 1) << 1)));
595 }
596 }
597}
598
599/*
600 * ccdc_config_color_patterns()
601 * configure parameters for color patterns
602 */
603static void ccdc_config_color_patterns(struct ccdc_col_pat *pat0,
604 struct ccdc_col_pat *pat1)
605{
606 u32 val;
607
608 val = (pat0->olop | (pat0->olep << 2) | (pat0->elop << 4) |
609 (pat0->elep << 6) | (pat1->olop << 8) | (pat1->olep << 10) |
610 (pat1->elop << 12) | (pat1->elep << 14));
611 regw(val, COLPTN);
612}
613
614/* This function will configure CCDC for Raw mode image capture */
615static int ccdc_config_raw(void)
616{
617 struct ccdc_params_raw *params = &ccdc_cfg.bayer;
618 struct ccdc_config_params_raw *config_params =
619 &ccdc_cfg.bayer.config_params;
620 unsigned int val;
621
622 dev_dbg(ccdc_cfg.dev, "\nStarting ccdc_config_raw...");
623
624 /* restore power on defaults to register */
625 ccdc_restore_defaults();
626
627 /* CCDCFG register:
628 * set CCD Not to swap input since input is RAW data
629 * set FID detection function to Latch at V-Sync
630 * set WENLOG - ccdc valid area to AND
631 * set TRGSEL to WENBIT
632 * set EXTRG to DISABLE
633 * disable latching function on VSYNC - shadowed registers
634 */
635 regw(CCDC_YCINSWP_RAW | CCDC_CCDCFG_FIDMD_LATCH_VSYNC |
636 CCDC_CCDCFG_WENLOG_AND | CCDC_CCDCFG_TRGSEL_WEN |
637 CCDC_CCDCFG_EXTRG_DISABLE | CCDC_LATCH_ON_VSYNC_DISABLE, CCDCFG);
638
639 /*
640 * Set VDHD direction to input, input type to raw input
641 * normal data polarity, do not use external WEN
642 */
643 val = (CCDC_VDHDOUT_INPUT | CCDC_RAW_IP_MODE | CCDC_DATAPOL_NORMAL |
644 CCDC_EXWEN_DISABLE);
645
646 /*
647 * Configure the vertical sync polarity (MODESET.VDPOL), horizontal
648 * sync polarity (MODESET.HDPOL), field id polarity (MODESET.FLDPOL),
649 * frame format(progressive or interlace), & pixel format (Input mode)
650 */
651 val |= (((params->vd_pol & CCDC_VD_POL_MASK) << CCDC_VD_POL_SHIFT) |
652 ((params->hd_pol & CCDC_HD_POL_MASK) << CCDC_HD_POL_SHIFT) |
653 ((params->fid_pol & CCDC_FID_POL_MASK) << CCDC_FID_POL_SHIFT) |
654 ((params->frm_fmt & CCDC_FRM_FMT_MASK) << CCDC_FRM_FMT_SHIFT) |
655 ((params->pix_fmt & CCDC_PIX_FMT_MASK) << CCDC_PIX_FMT_SHIFT));
656
657 /* set pack for alaw compression */
658 if ((config_params->data_sz == CCDC_DATA_8BITS) ||
659 config_params->alaw.enable)
660 val |= CCDC_DATA_PACK_ENABLE;
661
662 /* Configure for LPF */
663 if (config_params->lpf_enable)
664 val |= (config_params->lpf_enable & CCDC_LPF_MASK) <<
665 CCDC_LPF_SHIFT;
666
667 /* Configure the data shift */
668 val |= (config_params->datasft & CCDC_DATASFT_MASK) <<
669 CCDC_DATASFT_SHIFT;
670 regw(val , MODESET);
671 dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to MODESET...\n", val);
672
673 /* Configure the Median Filter threshold */
674 regw((config_params->med_filt_thres) & CCDC_MED_FILT_THRESH, MEDFILT);
675
676 /* Configure GAMMAWD register. defaur 11-2, and Mosaic cfa pattern */
677 val = CCDC_GAMMA_BITS_11_2 << CCDC_GAMMAWD_INPUT_SHIFT |
678 CCDC_CFA_MOSAIC;
679
680 /* Enable and configure aLaw register if needed */
681 if (config_params->alaw.enable) {
682 val |= (CCDC_ALAW_ENABLE |
683 ((config_params->alaw.gama_wd &
684 CCDC_ALAW_GAMA_WD_MASK) <<
685 CCDC_GAMMAWD_INPUT_SHIFT));
686 }
687
688 /* Configure Median filter1 & filter2 */
689 val |= ((config_params->mfilt1 << CCDC_MFILT1_SHIFT) |
690 (config_params->mfilt2 << CCDC_MFILT2_SHIFT));
691
692 regw(val, GAMMAWD);
693 dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to GAMMAWD...\n", val);
694
695 /* configure video window */
696 ccdc_setwin(&params->win, params->frm_fmt, 1);
697
698 /* Optical Clamp Averaging */
699 ccdc_config_black_clamp(&config_params->blk_clamp);
700
701 /* Black level compensation */
702 ccdc_config_black_compense(&config_params->blk_comp);
703
704 /* Vertical Defect Correction if needed */
705 if (ccdc_config_vdfc(&config_params->vertical_dft) < 0)
706 return -EFAULT;
707
708 /* color space conversion */
709 ccdc_config_csc(&config_params->csc);
710
711 /* color pattern */
712 ccdc_config_color_patterns(&config_params->col_pat_field0,
713 &config_params->col_pat_field1);
714
715 /* Configure the Gain & offset control */
716 ccdc_config_gain_offset();
717
718 dev_dbg(ccdc_cfg.dev, "\nWriting %x to COLPTN...\n", val);
719
720 /* Configure DATAOFST register */
721 val = (config_params->data_offset.horz_offset & CCDC_DATAOFST_MASK) <<
722 CCDC_DATAOFST_H_SHIFT;
723 val |= (config_params->data_offset.vert_offset & CCDC_DATAOFST_MASK) <<
724 CCDC_DATAOFST_V_SHIFT;
725 regw(val, DATAOFST);
726
727 /* configuring HSIZE register */
728 val = (params->horz_flip_enable & CCDC_HSIZE_FLIP_MASK) <<
729 CCDC_HSIZE_FLIP_SHIFT;
730
731 /* If pack 8 is enable then 1 pixel will take 1 byte */
732 if ((config_params->data_sz == CCDC_DATA_8BITS) ||
733 config_params->alaw.enable) {
734 val |= (((params->win.width) + 31) >> 5) &
735 CCDC_HSIZE_VAL_MASK;
736
737 /* adjust to multiple of 32 */
738 dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to HSIZE...\n",
739 (((params->win.width) + 31) >> 5) &
740 CCDC_HSIZE_VAL_MASK);
741 } else {
742 /* else one pixel will take 2 byte */
743 val |= (((params->win.width * 2) + 31) >> 5) &
744 CCDC_HSIZE_VAL_MASK;
745
746 dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to HSIZE...\n",
747 (((params->win.width * 2) + 31) >> 5) &
748 CCDC_HSIZE_VAL_MASK);
749 }
750 regw(val, HSIZE);
751
752 /* Configure SDOFST register */
753 if (params->frm_fmt == CCDC_FRMFMT_INTERLACED) {
754 if (params->image_invert_enable) {
755 /* For interlace inverse mode */
756 regw(CCDC_SDOFST_INTERLACE_INVERSE, SDOFST);
757 dev_dbg(ccdc_cfg.dev, "\nWriting %x to SDOFST...\n",
758 CCDC_SDOFST_INTERLACE_INVERSE);
759 } else {
760 /* For interlace non inverse mode */
761 regw(CCDC_SDOFST_INTERLACE_NORMAL, SDOFST);
762 dev_dbg(ccdc_cfg.dev, "\nWriting %x to SDOFST...\n",
763 CCDC_SDOFST_INTERLACE_NORMAL);
764 }
765 } else if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE) {
766 if (params->image_invert_enable) {
767 /* For progessive inverse mode */
768 regw(CCDC_SDOFST_PROGRESSIVE_INVERSE, SDOFST);
769 dev_dbg(ccdc_cfg.dev, "\nWriting %x to SDOFST...\n",
770 CCDC_SDOFST_PROGRESSIVE_INVERSE);
771 } else {
772 /* For progessive non inverse mode */
773 regw(CCDC_SDOFST_PROGRESSIVE_NORMAL, SDOFST);
774 dev_dbg(ccdc_cfg.dev, "\nWriting %x to SDOFST...\n",
775 CCDC_SDOFST_PROGRESSIVE_NORMAL);
776 }
777 }
778 dev_dbg(ccdc_cfg.dev, "\nend of ccdc_config_raw...");
779 return 0;
780}
781
782static int ccdc_configure(void)
783{
784 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
785 return ccdc_config_raw();
786 else
787 ccdc_config_ycbcr();
788 return 0;
789}
790
791static int ccdc_set_buftype(enum ccdc_buftype buf_type)
792{
793 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
794 ccdc_cfg.bayer.buf_type = buf_type;
795 else
796 ccdc_cfg.ycbcr.buf_type = buf_type;
797 return 0;
798}
799static enum ccdc_buftype ccdc_get_buftype(void)
800{
801 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
802 return ccdc_cfg.bayer.buf_type;
803 return ccdc_cfg.ycbcr.buf_type;
804}
805
806static int ccdc_enum_pix(u32 *pix, int i)
807{
808 int ret = -EINVAL;
809 if (ccdc_cfg.if_type == VPFE_RAW_BAYER) {
810 if (i < ARRAY_SIZE(ccdc_raw_bayer_pix_formats)) {
811 *pix = ccdc_raw_bayer_pix_formats[i];
812 ret = 0;
813 }
814 } else {
815 if (i < ARRAY_SIZE(ccdc_raw_yuv_pix_formats)) {
816 *pix = ccdc_raw_yuv_pix_formats[i];
817 ret = 0;
818 }
819 }
820 return ret;
821}
822
823static int ccdc_set_pixel_format(u32 pixfmt)
824{
825 struct ccdc_a_law *alaw = &ccdc_cfg.bayer.config_params.alaw;
826
827 if (ccdc_cfg.if_type == VPFE_RAW_BAYER) {
828 ccdc_cfg.bayer.pix_fmt = CCDC_PIXFMT_RAW;
829 if (pixfmt == V4L2_PIX_FMT_SBGGR8)
830 alaw->enable = 1;
831 else if (pixfmt != V4L2_PIX_FMT_SBGGR16)
832 return -EINVAL;
833 } else {
834 if (pixfmt == V4L2_PIX_FMT_YUYV)
835 ccdc_cfg.ycbcr.pix_order = CCDC_PIXORDER_YCBYCR;
836 else if (pixfmt == V4L2_PIX_FMT_UYVY)
837 ccdc_cfg.ycbcr.pix_order = CCDC_PIXORDER_CBYCRY;
838 else
839 return -EINVAL;
840 }
841 return 0;
842}
843static u32 ccdc_get_pixel_format(void)
844{
845 struct ccdc_a_law *alaw = &ccdc_cfg.bayer.config_params.alaw;
846 u32 pixfmt;
847
848 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
849 if (alaw->enable)
850 pixfmt = V4L2_PIX_FMT_SBGGR8;
851 else
852 pixfmt = V4L2_PIX_FMT_SBGGR16;
853 else {
854 if (ccdc_cfg.ycbcr.pix_order == CCDC_PIXORDER_YCBYCR)
855 pixfmt = V4L2_PIX_FMT_YUYV;
856 else
857 pixfmt = V4L2_PIX_FMT_UYVY;
858 }
859 return pixfmt;
860}
861static int ccdc_set_image_window(struct v4l2_rect *win)
862{
863 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
864 ccdc_cfg.bayer.win = *win;
865 else
866 ccdc_cfg.ycbcr.win = *win;
867 return 0;
868}
869
870static void ccdc_get_image_window(struct v4l2_rect *win)
871{
872 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
873 *win = ccdc_cfg.bayer.win;
874 else
875 *win = ccdc_cfg.ycbcr.win;
876}
877
878static unsigned int ccdc_get_line_length(void)
879{
880 struct ccdc_config_params_raw *config_params =
881 &ccdc_cfg.bayer.config_params;
882 unsigned int len;
883
884 if (ccdc_cfg.if_type == VPFE_RAW_BAYER) {
885 if ((config_params->alaw.enable) ||
886 (config_params->data_sz == CCDC_DATA_8BITS))
887 len = ccdc_cfg.bayer.win.width;
888 else
889 len = ccdc_cfg.bayer.win.width * 2;
890 } else
891 len = ccdc_cfg.ycbcr.win.width * 2;
892 return ALIGN(len, 32);
893}
894
895static int ccdc_set_frame_format(enum ccdc_frmfmt frm_fmt)
896{
897 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
898 ccdc_cfg.bayer.frm_fmt = frm_fmt;
899 else
900 ccdc_cfg.ycbcr.frm_fmt = frm_fmt;
901 return 0;
902}
903
904static enum ccdc_frmfmt ccdc_get_frame_format(void)
905{
906 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
907 return ccdc_cfg.bayer.frm_fmt;
908 else
909 return ccdc_cfg.ycbcr.frm_fmt;
910}
911
912static int ccdc_getfid(void)
913{
914 return (regr(MODESET) >> 15) & 1;
915}
916
917/* misc operations */
918static inline void ccdc_setfbaddr(unsigned long addr)
919{
920 regw((addr >> 21) & 0x007f, STADRH);
921 regw((addr >> 5) & 0x0ffff, STADRL);
922}
923
924static int ccdc_set_hw_if_params(struct vpfe_hw_if_param *params)
925{
926 ccdc_cfg.if_type = params->if_type;
927
928 switch (params->if_type) {
929 case VPFE_BT656:
930 case VPFE_YCBCR_SYNC_16:
931 case VPFE_YCBCR_SYNC_8:
932 ccdc_cfg.ycbcr.vd_pol = params->vdpol;
933 ccdc_cfg.ycbcr.hd_pol = params->hdpol;
934 break;
935 default:
936 /* TODO add support for raw bayer here */
937 return -EINVAL;
938 }
939 return 0;
940}
941
942static struct ccdc_hw_device ccdc_hw_dev = {
943 .name = "DM355 CCDC",
944 .owner = THIS_MODULE,
945 .hw_ops = {
946 .open = ccdc_open,
947 .close = ccdc_close,
948 .enable = ccdc_enable,
949 .enable_out_to_sdram = ccdc_enable_output_to_sdram,
950 .set_hw_if_params = ccdc_set_hw_if_params,
951 .set_params = ccdc_set_params,
952 .configure = ccdc_configure,
953 .set_buftype = ccdc_set_buftype,
954 .get_buftype = ccdc_get_buftype,
955 .enum_pix = ccdc_enum_pix,
956 .set_pixel_format = ccdc_set_pixel_format,
957 .get_pixel_format = ccdc_get_pixel_format,
958 .set_frame_format = ccdc_set_frame_format,
959 .get_frame_format = ccdc_get_frame_format,
960 .set_image_window = ccdc_set_image_window,
961 .get_image_window = ccdc_get_image_window,
962 .get_line_length = ccdc_get_line_length,
963 .setfbaddr = ccdc_setfbaddr,
964 .getfid = ccdc_getfid,
965 },
966};
967
968static int __devinit dm355_ccdc_probe(struct platform_device *pdev)
969{
970 void (*setup_pinmux)(void);
971 struct resource *res;
972 int status = 0;
973
974 /*
975 * first try to register with vpfe. If not correct platform, then we
976 * don't have to iomap
977 */
978 status = vpfe_register_ccdc_device(&ccdc_hw_dev);
979 if (status < 0)
980 return status;
981
982 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
983 if (!res) {
984 status = -ENODEV;
985 goto fail_nores;
986 }
987
988 res = request_mem_region(res->start, resource_size(res), res->name);
989 if (!res) {
990 status = -EBUSY;
991 goto fail_nores;
992 }
993
994 ccdc_cfg.base_addr = ioremap_nocache(res->start, resource_size(res));
995 if (!ccdc_cfg.base_addr) {
996 status = -ENOMEM;
997 goto fail_nomem;
998 }
999
1000 /* Get and enable Master clock */
1001 ccdc_cfg.mclk = clk_get(&pdev->dev, "master");
1002 if (IS_ERR(ccdc_cfg.mclk)) {
1003 status = PTR_ERR(ccdc_cfg.mclk);
1004 goto fail_nomap;
1005 }
1006 if (clk_enable(ccdc_cfg.mclk)) {
1007 status = -ENODEV;
1008 goto fail_mclk;
1009 }
1010
1011 /* Get and enable Slave clock */
1012 ccdc_cfg.sclk = clk_get(&pdev->dev, "slave");
1013 if (IS_ERR(ccdc_cfg.sclk)) {
1014 status = PTR_ERR(ccdc_cfg.sclk);
1015 goto fail_mclk;
1016 }
1017 if (clk_enable(ccdc_cfg.sclk)) {
1018 status = -ENODEV;
1019 goto fail_sclk;
1020 }
1021
1022 /* Platform data holds setup_pinmux function ptr */
1023 if (NULL == pdev->dev.platform_data) {
1024 status = -ENODEV;
1025 goto fail_sclk;
1026 }
1027 setup_pinmux = pdev->dev.platform_data;
1028 /*
1029 * setup Mux configuration for ccdc which may be different for
1030 * different SoCs using this CCDC
1031 */
1032 setup_pinmux();
1033 ccdc_cfg.dev = &pdev->dev;
1034 printk(KERN_NOTICE "%s is registered with vpfe.\n", ccdc_hw_dev.name);
1035 return 0;
1036fail_sclk:
1037 clk_put(ccdc_cfg.sclk);
1038fail_mclk:
1039 clk_put(ccdc_cfg.mclk);
1040fail_nomap:
1041 iounmap(ccdc_cfg.base_addr);
1042fail_nomem:
1043 release_mem_region(res->start, resource_size(res));
1044fail_nores:
1045 vpfe_unregister_ccdc_device(&ccdc_hw_dev);
1046 return status;
1047}
1048
1049static int dm355_ccdc_remove(struct platform_device *pdev)
1050{
1051 struct resource *res;
1052
1053 clk_put(ccdc_cfg.mclk);
1054 clk_put(ccdc_cfg.sclk);
1055 iounmap(ccdc_cfg.base_addr);
1056 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1057 if (res)
1058 release_mem_region(res->start, resource_size(res));
1059 vpfe_unregister_ccdc_device(&ccdc_hw_dev);
1060 return 0;
1061}
1062
1063static struct platform_driver dm355_ccdc_driver = {
1064 .driver = {
1065 .name = "dm355_ccdc",
1066 .owner = THIS_MODULE,
1067 },
1068 .remove = __devexit_p(dm355_ccdc_remove),
1069 .probe = dm355_ccdc_probe,
1070};
1071
1072module_platform_driver(dm355_ccdc_driver);
diff --git a/drivers/media/video/davinci/dm355_ccdc_regs.h b/drivers/media/video/davinci/dm355_ccdc_regs.h
deleted file mode 100644
index d6d2ef0533b5..000000000000
--- a/drivers/media/video/davinci/dm355_ccdc_regs.h
+++ /dev/null
@@ -1,310 +0,0 @@
1/*
2 * Copyright (C) 2005-2009 Texas Instruments Inc
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18#ifndef _DM355_CCDC_REGS_H
19#define _DM355_CCDC_REGS_H
20
21/**************************************************************************\
22* Register OFFSET Definitions
23\**************************************************************************/
24#define SYNCEN 0x00
25#define MODESET 0x04
26#define HDWIDTH 0x08
27#define VDWIDTH 0x0c
28#define PPLN 0x10
29#define LPFR 0x14
30#define SPH 0x18
31#define NPH 0x1c
32#define SLV0 0x20
33#define SLV1 0x24
34#define NLV 0x28
35#define CULH 0x2c
36#define CULV 0x30
37#define HSIZE 0x34
38#define SDOFST 0x38
39#define STADRH 0x3c
40#define STADRL 0x40
41#define CLAMP 0x44
42#define DCSUB 0x48
43#define COLPTN 0x4c
44#define BLKCMP0 0x50
45#define BLKCMP1 0x54
46#define MEDFILT 0x58
47#define RYEGAIN 0x5c
48#define GRCYGAIN 0x60
49#define GBGGAIN 0x64
50#define BMGGAIN 0x68
51#define OFFSET 0x6c
52#define OUTCLIP 0x70
53#define VDINT0 0x74
54#define VDINT1 0x78
55#define RSV0 0x7c
56#define GAMMAWD 0x80
57#define REC656IF 0x84
58#define CCDCFG 0x88
59#define FMTCFG 0x8c
60#define FMTPLEN 0x90
61#define FMTSPH 0x94
62#define FMTLNH 0x98
63#define FMTSLV 0x9c
64#define FMTLNV 0xa0
65#define FMTRLEN 0xa4
66#define FMTHCNT 0xa8
67#define FMT_ADDR_PTR_B 0xac
68#define FMT_ADDR_PTR(i) (FMT_ADDR_PTR_B + (i * 4))
69#define FMTPGM_VF0 0xcc
70#define FMTPGM_VF1 0xd0
71#define FMTPGM_AP0 0xd4
72#define FMTPGM_AP1 0xd8
73#define FMTPGM_AP2 0xdc
74#define FMTPGM_AP3 0xe0
75#define FMTPGM_AP4 0xe4
76#define FMTPGM_AP5 0xe8
77#define FMTPGM_AP6 0xec
78#define FMTPGM_AP7 0xf0
79#define LSCCFG1 0xf4
80#define LSCCFG2 0xf8
81#define LSCH0 0xfc
82#define LSCV0 0x100
83#define LSCKH 0x104
84#define LSCKV 0x108
85#define LSCMEMCTL 0x10c
86#define LSCMEMD 0x110
87#define LSCMEMQ 0x114
88#define DFCCTL 0x118
89#define DFCVSAT 0x11c
90#define DFCMEMCTL 0x120
91#define DFCMEM0 0x124
92#define DFCMEM1 0x128
93#define DFCMEM2 0x12c
94#define DFCMEM3 0x130
95#define DFCMEM4 0x134
96#define CSCCTL 0x138
97#define CSCM0 0x13c
98#define CSCM1 0x140
99#define CSCM2 0x144
100#define CSCM3 0x148
101#define CSCM4 0x14c
102#define CSCM5 0x150
103#define CSCM6 0x154
104#define CSCM7 0x158
105#define DATAOFST 0x15c
106#define CCDC_REG_LAST DATAOFST
107/**************************************************************
108* Define for various register bit mask and shifts for CCDC
109*
110**************************************************************/
111#define CCDC_RAW_IP_MODE 0
112#define CCDC_VDHDOUT_INPUT 0
113#define CCDC_YCINSWP_RAW (0 << 4)
114#define CCDC_EXWEN_DISABLE 0
115#define CCDC_DATAPOL_NORMAL 0
116#define CCDC_CCDCFG_FIDMD_LATCH_VSYNC 0
117#define CCDC_CCDCFG_FIDMD_NO_LATCH_VSYNC (1 << 6)
118#define CCDC_CCDCFG_WENLOG_AND 0
119#define CCDC_CCDCFG_TRGSEL_WEN 0
120#define CCDC_CCDCFG_EXTRG_DISABLE 0
121#define CCDC_CFA_MOSAIC 0
122#define CCDC_Y8POS_SHIFT 11
123
124#define CCDC_VDC_DFCVSAT_MASK 0x3fff
125#define CCDC_DATAOFST_MASK 0x0ff
126#define CCDC_DATAOFST_H_SHIFT 0
127#define CCDC_DATAOFST_V_SHIFT 8
128#define CCDC_GAMMAWD_CFA_MASK 1
129#define CCDC_GAMMAWD_CFA_SHIFT 5
130#define CCDC_GAMMAWD_INPUT_SHIFT 2
131#define CCDC_FID_POL_MASK 1
132#define CCDC_FID_POL_SHIFT 4
133#define CCDC_HD_POL_MASK 1
134#define CCDC_HD_POL_SHIFT 3
135#define CCDC_VD_POL_MASK 1
136#define CCDC_VD_POL_SHIFT 2
137#define CCDC_VD_POL_NEGATIVE (1 << 2)
138#define CCDC_FRM_FMT_MASK 1
139#define CCDC_FRM_FMT_SHIFT 7
140#define CCDC_DATA_SZ_MASK 7
141#define CCDC_DATA_SZ_SHIFT 8
142#define CCDC_VDHDOUT_MASK 1
143#define CCDC_VDHDOUT_SHIFT 0
144#define CCDC_EXWEN_MASK 1
145#define CCDC_EXWEN_SHIFT 5
146#define CCDC_INPUT_MODE_MASK 3
147#define CCDC_INPUT_MODE_SHIFT 12
148#define CCDC_PIX_FMT_MASK 3
149#define CCDC_PIX_FMT_SHIFT 12
150#define CCDC_DATAPOL_MASK 1
151#define CCDC_DATAPOL_SHIFT 6
152#define CCDC_WEN_ENABLE (1 << 1)
153#define CCDC_VDHDEN_ENABLE (1 << 16)
154#define CCDC_LPF_ENABLE (1 << 14)
155#define CCDC_ALAW_ENABLE 1
156#define CCDC_ALAW_GAMA_WD_MASK 7
157#define CCDC_REC656IF_BT656_EN 3
158
159#define CCDC_FMTCFG_FMTMODE_MASK 3
160#define CCDC_FMTCFG_FMTMODE_SHIFT 1
161#define CCDC_FMTCFG_LNUM_MASK 3
162#define CCDC_FMTCFG_LNUM_SHIFT 4
163#define CCDC_FMTCFG_ADDRINC_MASK 7
164#define CCDC_FMTCFG_ADDRINC_SHIFT 8
165
166#define CCDC_CCDCFG_FIDMD_SHIFT 6
167#define CCDC_CCDCFG_WENLOG_SHIFT 8
168#define CCDC_CCDCFG_TRGSEL_SHIFT 9
169#define CCDC_CCDCFG_EXTRG_SHIFT 10
170#define CCDC_CCDCFG_MSBINVI_SHIFT 13
171
172#define CCDC_HSIZE_FLIP_SHIFT 12
173#define CCDC_HSIZE_FLIP_MASK 1
174#define CCDC_HSIZE_VAL_MASK 0xFFF
175#define CCDC_SDOFST_FIELD_INTERLEAVED 0x249
176#define CCDC_SDOFST_INTERLACE_INVERSE 0x4B6D
177#define CCDC_SDOFST_INTERLACE_NORMAL 0x0B6D
178#define CCDC_SDOFST_PROGRESSIVE_INVERSE 0x4000
179#define CCDC_SDOFST_PROGRESSIVE_NORMAL 0
180#define CCDC_START_PX_HOR_MASK 0x7FFF
181#define CCDC_NUM_PX_HOR_MASK 0x7FFF
182#define CCDC_START_VER_ONE_MASK 0x7FFF
183#define CCDC_START_VER_TWO_MASK 0x7FFF
184#define CCDC_NUM_LINES_VER 0x7FFF
185
186#define CCDC_BLK_CLAMP_ENABLE (1 << 15)
187#define CCDC_BLK_SGAIN_MASK 0x1F
188#define CCDC_BLK_ST_PXL_MASK 0x1FFF
189#define CCDC_BLK_SAMPLE_LN_MASK 3
190#define CCDC_BLK_SAMPLE_LN_SHIFT 13
191
192#define CCDC_NUM_LINE_CALC_MASK 3
193#define CCDC_NUM_LINE_CALC_SHIFT 14
194
195#define CCDC_BLK_DC_SUB_MASK 0x3FFF
196#define CCDC_BLK_COMP_MASK 0xFF
197#define CCDC_BLK_COMP_GB_COMP_SHIFT 8
198#define CCDC_BLK_COMP_GR_COMP_SHIFT 0
199#define CCDC_BLK_COMP_R_COMP_SHIFT 8
200#define CCDC_LATCH_ON_VSYNC_DISABLE (1 << 15)
201#define CCDC_LATCH_ON_VSYNC_ENABLE (0 << 15)
202#define CCDC_FPC_ENABLE (1 << 15)
203#define CCDC_FPC_FPC_NUM_MASK 0x7FFF
204#define CCDC_DATA_PACK_ENABLE (1 << 11)
205#define CCDC_FMT_HORZ_FMTLNH_MASK 0x1FFF
206#define CCDC_FMT_HORZ_FMTSPH_MASK 0x1FFF
207#define CCDC_FMT_HORZ_FMTSPH_SHIFT 16
208#define CCDC_FMT_VERT_FMTLNV_MASK 0x1FFF
209#define CCDC_FMT_VERT_FMTSLV_MASK 0x1FFF
210#define CCDC_FMT_VERT_FMTSLV_SHIFT 16
211#define CCDC_VP_OUT_VERT_NUM_MASK 0x3FFF
212#define CCDC_VP_OUT_VERT_NUM_SHIFT 17
213#define CCDC_VP_OUT_HORZ_NUM_MASK 0x1FFF
214#define CCDC_VP_OUT_HORZ_NUM_SHIFT 4
215#define CCDC_VP_OUT_HORZ_ST_MASK 0xF
216
217#define CCDC_CSC_COEF_INTEG_MASK 7
218#define CCDC_CSC_COEF_DECIMAL_MASK 0x1f
219#define CCDC_CSC_COEF_INTEG_SHIFT 5
220#define CCDC_CSCM_MSB_SHIFT 8
221#define CCDC_CSC_ENABLE 1
222#define CCDC_CSC_DEC_MAX 32
223
224#define CCDC_MFILT1_SHIFT 10
225#define CCDC_MFILT2_SHIFT 8
226#define CCDC_MED_FILT_THRESH 0x3FFF
227#define CCDC_LPF_MASK 1
228#define CCDC_LPF_SHIFT 14
229#define CCDC_OFFSET_MASK 0x3FF
230#define CCDC_DATASFT_MASK 7
231#define CCDC_DATASFT_SHIFT 8
232
233#define CCDC_DF_ENABLE 1
234
235#define CCDC_FMTPLEN_P0_MASK 0xF
236#define CCDC_FMTPLEN_P1_MASK 0xF
237#define CCDC_FMTPLEN_P2_MASK 7
238#define CCDC_FMTPLEN_P3_MASK 7
239#define CCDC_FMTPLEN_P0_SHIFT 0
240#define CCDC_FMTPLEN_P1_SHIFT 4
241#define CCDC_FMTPLEN_P2_SHIFT 8
242#define CCDC_FMTPLEN_P3_SHIFT 12
243
244#define CCDC_FMTSPH_MASK 0x1FFF
245#define CCDC_FMTLNH_MASK 0x1FFF
246#define CCDC_FMTSLV_MASK 0x1FFF
247#define CCDC_FMTLNV_MASK 0x7FFF
248#define CCDC_FMTRLEN_MASK 0x1FFF
249#define CCDC_FMTHCNT_MASK 0x1FFF
250
251#define CCDC_ADP_INIT_MASK 0x1FFF
252#define CCDC_ADP_LINE_SHIFT 13
253#define CCDC_ADP_LINE_MASK 3
254#define CCDC_FMTPGN_APTR_MASK 7
255
256#define CCDC_DFCCTL_GDFCEN_MASK 1
257#define CCDC_DFCCTL_VDFCEN_MASK 1
258#define CCDC_DFCCTL_VDFC_DISABLE (0 << 4)
259#define CCDC_DFCCTL_VDFCEN_SHIFT 4
260#define CCDC_DFCCTL_VDFCSL_MASK 3
261#define CCDC_DFCCTL_VDFCSL_SHIFT 5
262#define CCDC_DFCCTL_VDFCUDA_MASK 1
263#define CCDC_DFCCTL_VDFCUDA_SHIFT 7
264#define CCDC_DFCCTL_VDFLSFT_MASK 3
265#define CCDC_DFCCTL_VDFLSFT_SHIFT 8
266#define CCDC_DFCMEMCTL_DFCMARST_MASK 1
267#define CCDC_DFCMEMCTL_DFCMARST_SHIFT 2
268#define CCDC_DFCMEMCTL_DFCMWR_MASK 1
269#define CCDC_DFCMEMCTL_DFCMWR_SHIFT 0
270#define CCDC_DFCMEMCTL_INC_ADDR (0 << 2)
271
272#define CCDC_LSCCFG_GFTSF_MASK 7
273#define CCDC_LSCCFG_GFTSF_SHIFT 1
274#define CCDC_LSCCFG_GFTINV_MASK 0xf
275#define CCDC_LSCCFG_GFTINV_SHIFT 4
276#define CCDC_LSC_GFTABLE_SEL_MASK 3
277#define CCDC_LSC_GFTABLE_EPEL_SHIFT 8
278#define CCDC_LSC_GFTABLE_OPEL_SHIFT 10
279#define CCDC_LSC_GFTABLE_EPOL_SHIFT 12
280#define CCDC_LSC_GFTABLE_OPOL_SHIFT 14
281#define CCDC_LSC_GFMODE_MASK 3
282#define CCDC_LSC_GFMODE_SHIFT 4
283#define CCDC_LSC_DISABLE 0
284#define CCDC_LSC_ENABLE 1
285#define CCDC_LSC_TABLE1_SLC 0
286#define CCDC_LSC_TABLE2_SLC 1
287#define CCDC_LSC_TABLE3_SLC 2
288#define CCDC_LSC_MEMADDR_RESET (1 << 2)
289#define CCDC_LSC_MEMADDR_INCR (0 << 2)
290#define CCDC_LSC_FRAC_MASK_T1 0xFF
291#define CCDC_LSC_INT_MASK 3
292#define CCDC_LSC_FRAC_MASK 0x3FFF
293#define CCDC_LSC_CENTRE_MASK 0x3FFF
294#define CCDC_LSC_COEF_MASK 0xff
295#define CCDC_LSC_COEFL_SHIFT 0
296#define CCDC_LSC_COEFU_SHIFT 8
297#define CCDC_GAIN_MASK 0x7FF
298#define CCDC_SYNCEN_VDHDEN_MASK (1 << 0)
299#define CCDC_SYNCEN_WEN_MASK (1 << 1)
300#define CCDC_SYNCEN_WEN_SHIFT 1
301
302/* Power on Defaults in hardware */
303#define MODESET_DEFAULT 0x200
304#define CULH_DEFAULT 0xFFFF
305#define CULV_DEFAULT 0xFF
306#define GAIN_DEFAULT 256
307#define OUTCLIP_DEFAULT 0x3FFF
308#define LSCCFG2_DEFAULT 0xE
309
310#endif
diff --git a/drivers/media/video/davinci/dm644x_ccdc.c b/drivers/media/video/davinci/dm644x_ccdc.c
deleted file mode 100644
index ee7942b1996e..000000000000
--- a/drivers/media/video/davinci/dm644x_ccdc.c
+++ /dev/null
@@ -1,1081 +0,0 @@
1/*
2 * Copyright (C) 2006-2009 Texas Instruments Inc
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * CCDC hardware module for DM6446
19 * ------------------------------
20 *
21 * This module is for configuring CCD controller of DM6446 VPFE to capture
22 * Raw yuv or Bayer RGB data from a decoder. CCDC has several modules
23 * such as Defect Pixel Correction, Color Space Conversion etc to
24 * pre-process the Raw Bayer RGB data, before writing it to SDRAM. This
25 * module also allows application to configure individual
26 * module parameters through VPFE_CMD_S_CCDC_RAW_PARAMS IOCTL.
27 * To do so, application includes dm644x_ccdc.h and vpfe_capture.h header
28 * files. The setparams() API is called by vpfe_capture driver
29 * to configure module parameters. This file is named DM644x so that other
30 * variants such DM6443 may be supported using the same module.
31 *
32 * TODO: Test Raw bayer parameter settings and bayer capture
33 * Split module parameter structure to module specific ioctl structs
34 * investigate if enum used for user space type definition
35 * to be replaced by #defines or integer
36 */
37#include <linux/platform_device.h>
38#include <linux/uaccess.h>
39#include <linux/videodev2.h>
40#include <linux/gfp.h>
41#include <linux/clk.h>
42#include <linux/err.h>
43#include <linux/module.h>
44
45#include <media/davinci/dm644x_ccdc.h>
46#include <media/davinci/vpss.h>
47
48#include "dm644x_ccdc_regs.h"
49#include "ccdc_hw_device.h"
50
51MODULE_LICENSE("GPL");
52MODULE_DESCRIPTION("CCDC Driver for DM6446");
53MODULE_AUTHOR("Texas Instruments");
54
55static struct ccdc_oper_config {
56 struct device *dev;
57 /* CCDC interface type */
58 enum vpfe_hw_if_type if_type;
59 /* Raw Bayer configuration */
60 struct ccdc_params_raw bayer;
61 /* YCbCr configuration */
62 struct ccdc_params_ycbcr ycbcr;
63 /* Master clock */
64 struct clk *mclk;
65 /* slave clock */
66 struct clk *sclk;
67 /* ccdc base address */
68 void __iomem *base_addr;
69} ccdc_cfg = {
70 /* Raw configurations */
71 .bayer = {
72 .pix_fmt = CCDC_PIXFMT_RAW,
73 .frm_fmt = CCDC_FRMFMT_PROGRESSIVE,
74 .win = CCDC_WIN_VGA,
75 .fid_pol = VPFE_PINPOL_POSITIVE,
76 .vd_pol = VPFE_PINPOL_POSITIVE,
77 .hd_pol = VPFE_PINPOL_POSITIVE,
78 .config_params = {
79 .data_sz = CCDC_DATA_10BITS,
80 },
81 },
82 .ycbcr = {
83 .pix_fmt = CCDC_PIXFMT_YCBCR_8BIT,
84 .frm_fmt = CCDC_FRMFMT_INTERLACED,
85 .win = CCDC_WIN_PAL,
86 .fid_pol = VPFE_PINPOL_POSITIVE,
87 .vd_pol = VPFE_PINPOL_POSITIVE,
88 .hd_pol = VPFE_PINPOL_POSITIVE,
89 .bt656_enable = 1,
90 .pix_order = CCDC_PIXORDER_CBYCRY,
91 .buf_type = CCDC_BUFTYPE_FLD_INTERLEAVED
92 },
93};
94
95#define CCDC_MAX_RAW_YUV_FORMATS 2
96
97/* Raw Bayer formats */
98static u32 ccdc_raw_bayer_pix_formats[] =
99 {V4L2_PIX_FMT_SBGGR8, V4L2_PIX_FMT_SBGGR16};
100
101/* Raw YUV formats */
102static u32 ccdc_raw_yuv_pix_formats[] =
103 {V4L2_PIX_FMT_UYVY, V4L2_PIX_FMT_YUYV};
104
105/* CCDC Save/Restore context */
106static u32 ccdc_ctx[CCDC_REG_END / sizeof(u32)];
107
108/* register access routines */
109static inline u32 regr(u32 offset)
110{
111 return __raw_readl(ccdc_cfg.base_addr + offset);
112}
113
114static inline void regw(u32 val, u32 offset)
115{
116 __raw_writel(val, ccdc_cfg.base_addr + offset);
117}
118
119static void ccdc_enable(int flag)
120{
121 regw(flag, CCDC_PCR);
122}
123
124static void ccdc_enable_vport(int flag)
125{
126 if (flag)
127 /* enable video port */
128 regw(CCDC_ENABLE_VIDEO_PORT, CCDC_FMTCFG);
129 else
130 regw(CCDC_DISABLE_VIDEO_PORT, CCDC_FMTCFG);
131}
132
133/*
134 * ccdc_setwin()
135 * This function will configure the window size
136 * to be capture in CCDC reg
137 */
138void ccdc_setwin(struct v4l2_rect *image_win,
139 enum ccdc_frmfmt frm_fmt,
140 int ppc)
141{
142 int horz_start, horz_nr_pixels;
143 int vert_start, vert_nr_lines;
144 int val = 0, mid_img = 0;
145
146 dev_dbg(ccdc_cfg.dev, "\nStarting ccdc_setwin...");
147 /*
148 * ppc - per pixel count. indicates how many pixels per cell
149 * output to SDRAM. example, for ycbcr, it is one y and one c, so 2.
150 * raw capture this is 1
151 */
152 horz_start = image_win->left << (ppc - 1);
153 horz_nr_pixels = (image_win->width << (ppc - 1)) - 1;
154 regw((horz_start << CCDC_HORZ_INFO_SPH_SHIFT) | horz_nr_pixels,
155 CCDC_HORZ_INFO);
156
157 vert_start = image_win->top;
158
159 if (frm_fmt == CCDC_FRMFMT_INTERLACED) {
160 vert_nr_lines = (image_win->height >> 1) - 1;
161 vert_start >>= 1;
162 /* Since first line doesn't have any data */
163 vert_start += 1;
164 /* configure VDINT0 */
165 val = (vert_start << CCDC_VDINT_VDINT0_SHIFT);
166 regw(val, CCDC_VDINT);
167
168 } else {
169 /* Since first line doesn't have any data */
170 vert_start += 1;
171 vert_nr_lines = image_win->height - 1;
172 /*
173 * configure VDINT0 and VDINT1. VDINT1 will be at half
174 * of image height
175 */
176 mid_img = vert_start + (image_win->height / 2);
177 val = (vert_start << CCDC_VDINT_VDINT0_SHIFT) |
178 (mid_img & CCDC_VDINT_VDINT1_MASK);
179 regw(val, CCDC_VDINT);
180
181 }
182 regw((vert_start << CCDC_VERT_START_SLV0_SHIFT) | vert_start,
183 CCDC_VERT_START);
184 regw(vert_nr_lines, CCDC_VERT_LINES);
185 dev_dbg(ccdc_cfg.dev, "\nEnd of ccdc_setwin...");
186}
187
188static void ccdc_readregs(void)
189{
190 unsigned int val = 0;
191
192 val = regr(CCDC_ALAW);
193 dev_notice(ccdc_cfg.dev, "\nReading 0x%x to ALAW...\n", val);
194 val = regr(CCDC_CLAMP);
195 dev_notice(ccdc_cfg.dev, "\nReading 0x%x to CLAMP...\n", val);
196 val = regr(CCDC_DCSUB);
197 dev_notice(ccdc_cfg.dev, "\nReading 0x%x to DCSUB...\n", val);
198 val = regr(CCDC_BLKCMP);
199 dev_notice(ccdc_cfg.dev, "\nReading 0x%x to BLKCMP...\n", val);
200 val = regr(CCDC_FPC_ADDR);
201 dev_notice(ccdc_cfg.dev, "\nReading 0x%x to FPC_ADDR...\n", val);
202 val = regr(CCDC_FPC);
203 dev_notice(ccdc_cfg.dev, "\nReading 0x%x to FPC...\n", val);
204 val = regr(CCDC_FMTCFG);
205 dev_notice(ccdc_cfg.dev, "\nReading 0x%x to FMTCFG...\n", val);
206 val = regr(CCDC_COLPTN);
207 dev_notice(ccdc_cfg.dev, "\nReading 0x%x to COLPTN...\n", val);
208 val = regr(CCDC_FMT_HORZ);
209 dev_notice(ccdc_cfg.dev, "\nReading 0x%x to FMT_HORZ...\n", val);
210 val = regr(CCDC_FMT_VERT);
211 dev_notice(ccdc_cfg.dev, "\nReading 0x%x to FMT_VERT...\n", val);
212 val = regr(CCDC_HSIZE_OFF);
213 dev_notice(ccdc_cfg.dev, "\nReading 0x%x to HSIZE_OFF...\n", val);
214 val = regr(CCDC_SDOFST);
215 dev_notice(ccdc_cfg.dev, "\nReading 0x%x to SDOFST...\n", val);
216 val = regr(CCDC_VP_OUT);
217 dev_notice(ccdc_cfg.dev, "\nReading 0x%x to VP_OUT...\n", val);
218 val = regr(CCDC_SYN_MODE);
219 dev_notice(ccdc_cfg.dev, "\nReading 0x%x to SYN_MODE...\n", val);
220 val = regr(CCDC_HORZ_INFO);
221 dev_notice(ccdc_cfg.dev, "\nReading 0x%x to HORZ_INFO...\n", val);
222 val = regr(CCDC_VERT_START);
223 dev_notice(ccdc_cfg.dev, "\nReading 0x%x to VERT_START...\n", val);
224 val = regr(CCDC_VERT_LINES);
225 dev_notice(ccdc_cfg.dev, "\nReading 0x%x to VERT_LINES...\n", val);
226}
227
228static int validate_ccdc_param(struct ccdc_config_params_raw *ccdcparam)
229{
230 if (ccdcparam->alaw.enable) {
231 if ((ccdcparam->alaw.gama_wd > CCDC_GAMMA_BITS_09_0) ||
232 (ccdcparam->alaw.gama_wd < CCDC_GAMMA_BITS_15_6) ||
233 (ccdcparam->alaw.gama_wd < ccdcparam->data_sz)) {
234 dev_dbg(ccdc_cfg.dev, "\nInvalid data line select");
235 return -1;
236 }
237 }
238 return 0;
239}
240
241static int ccdc_update_raw_params(struct ccdc_config_params_raw *raw_params)
242{
243 struct ccdc_config_params_raw *config_params =
244 &ccdc_cfg.bayer.config_params;
245 unsigned int *fpc_virtaddr = NULL;
246 unsigned int *fpc_physaddr = NULL;
247
248 memcpy(config_params, raw_params, sizeof(*raw_params));
249 /*
250 * allocate memory for fault pixel table and copy the user
251 * values to the table
252 */
253 if (!config_params->fault_pxl.enable)
254 return 0;
255
256 fpc_physaddr = (unsigned int *)config_params->fault_pxl.fpc_table_addr;
257 fpc_virtaddr = (unsigned int *)phys_to_virt(
258 (unsigned long)fpc_physaddr);
259 /*
260 * Allocate memory for FPC table if current
261 * FPC table buffer is not big enough to
262 * accommodate FPC Number requested
263 */
264 if (raw_params->fault_pxl.fp_num != config_params->fault_pxl.fp_num) {
265 if (fpc_physaddr != NULL) {
266 free_pages((unsigned long)fpc_physaddr,
267 get_order
268 (config_params->fault_pxl.fp_num *
269 FP_NUM_BYTES));
270 }
271
272 /* Allocate memory for FPC table */
273 fpc_virtaddr =
274 (unsigned int *)__get_free_pages(GFP_KERNEL | GFP_DMA,
275 get_order(raw_params->
276 fault_pxl.fp_num *
277 FP_NUM_BYTES));
278
279 if (fpc_virtaddr == NULL) {
280 dev_dbg(ccdc_cfg.dev,
281 "\nUnable to allocate memory for FPC");
282 return -EFAULT;
283 }
284 fpc_physaddr =
285 (unsigned int *)virt_to_phys((void *)fpc_virtaddr);
286 }
287
288 /* Copy number of fault pixels and FPC table */
289 config_params->fault_pxl.fp_num = raw_params->fault_pxl.fp_num;
290 if (copy_from_user(fpc_virtaddr,
291 (void __user *)raw_params->fault_pxl.fpc_table_addr,
292 config_params->fault_pxl.fp_num * FP_NUM_BYTES)) {
293 dev_dbg(ccdc_cfg.dev, "\n copy_from_user failed");
294 return -EFAULT;
295 }
296 config_params->fault_pxl.fpc_table_addr = (unsigned int)fpc_physaddr;
297 return 0;
298}
299
300static int ccdc_close(struct device *dev)
301{
302 struct ccdc_config_params_raw *config_params =
303 &ccdc_cfg.bayer.config_params;
304 unsigned int *fpc_physaddr = NULL, *fpc_virtaddr = NULL;
305
306 fpc_physaddr = (unsigned int *)config_params->fault_pxl.fpc_table_addr;
307
308 if (fpc_physaddr != NULL) {
309 fpc_virtaddr = (unsigned int *)
310 phys_to_virt((unsigned long)fpc_physaddr);
311 free_pages((unsigned long)fpc_virtaddr,
312 get_order(config_params->fault_pxl.fp_num *
313 FP_NUM_BYTES));
314 }
315 return 0;
316}
317
318/*
319 * ccdc_restore_defaults()
320 * This function will write defaults to all CCDC registers
321 */
322static void ccdc_restore_defaults(void)
323{
324 int i;
325
326 /* disable CCDC */
327 ccdc_enable(0);
328 /* set all registers to default value */
329 for (i = 4; i <= 0x94; i += 4)
330 regw(0, i);
331 regw(CCDC_NO_CULLING, CCDC_CULLING);
332 regw(CCDC_GAMMA_BITS_11_2, CCDC_ALAW);
333}
334
335static int ccdc_open(struct device *device)
336{
337 ccdc_restore_defaults();
338 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
339 ccdc_enable_vport(1);
340 return 0;
341}
342
343static void ccdc_sbl_reset(void)
344{
345 vpss_clear_wbl_overflow(VPSS_PCR_CCDC_WBL_O);
346}
347
348/* Parameter operations */
349static int ccdc_set_params(void __user *params)
350{
351 struct ccdc_config_params_raw ccdc_raw_params;
352 int x;
353
354 if (ccdc_cfg.if_type != VPFE_RAW_BAYER)
355 return -EINVAL;
356
357 x = copy_from_user(&ccdc_raw_params, params, sizeof(ccdc_raw_params));
358 if (x) {
359 dev_dbg(ccdc_cfg.dev, "ccdc_set_params: error in copying"
360 "ccdc params, %d\n", x);
361 return -EFAULT;
362 }
363
364 if (!validate_ccdc_param(&ccdc_raw_params)) {
365 if (!ccdc_update_raw_params(&ccdc_raw_params))
366 return 0;
367 }
368 return -EINVAL;
369}
370
371/*
372 * ccdc_config_ycbcr()
373 * This function will configure CCDC for YCbCr video capture
374 */
375void ccdc_config_ycbcr(void)
376{
377 struct ccdc_params_ycbcr *params = &ccdc_cfg.ycbcr;
378 u32 syn_mode;
379
380 dev_dbg(ccdc_cfg.dev, "\nStarting ccdc_config_ycbcr...");
381 /*
382 * first restore the CCDC registers to default values
383 * This is important since we assume default values to be set in
384 * a lot of registers that we didn't touch
385 */
386 ccdc_restore_defaults();
387
388 /*
389 * configure pixel format, frame format, configure video frame
390 * format, enable output to SDRAM, enable internal timing generator
391 * and 8bit pack mode
392 */
393 syn_mode = (((params->pix_fmt & CCDC_SYN_MODE_INPMOD_MASK) <<
394 CCDC_SYN_MODE_INPMOD_SHIFT) |
395 ((params->frm_fmt & CCDC_SYN_FLDMODE_MASK) <<
396 CCDC_SYN_FLDMODE_SHIFT) | CCDC_VDHDEN_ENABLE |
397 CCDC_WEN_ENABLE | CCDC_DATA_PACK_ENABLE);
398
399 /* setup BT.656 sync mode */
400 if (params->bt656_enable) {
401 regw(CCDC_REC656IF_BT656_EN, CCDC_REC656IF);
402
403 /*
404 * configure the FID, VD, HD pin polarity,
405 * fld,hd pol positive, vd negative, 8-bit data
406 */
407 syn_mode |= CCDC_SYN_MODE_VD_POL_NEGATIVE;
408 if (ccdc_cfg.if_type == VPFE_BT656_10BIT)
409 syn_mode |= CCDC_SYN_MODE_10BITS;
410 else
411 syn_mode |= CCDC_SYN_MODE_8BITS;
412 } else {
413 /* y/c external sync mode */
414 syn_mode |= (((params->fid_pol & CCDC_FID_POL_MASK) <<
415 CCDC_FID_POL_SHIFT) |
416 ((params->hd_pol & CCDC_HD_POL_MASK) <<
417 CCDC_HD_POL_SHIFT) |
418 ((params->vd_pol & CCDC_VD_POL_MASK) <<
419 CCDC_VD_POL_SHIFT));
420 }
421 regw(syn_mode, CCDC_SYN_MODE);
422
423 /* configure video window */
424 ccdc_setwin(&params->win, params->frm_fmt, 2);
425
426 /*
427 * configure the order of y cb cr in SDRAM, and disable latch
428 * internal register on vsync
429 */
430 if (ccdc_cfg.if_type == VPFE_BT656_10BIT)
431 regw((params->pix_order << CCDC_CCDCFG_Y8POS_SHIFT) |
432 CCDC_LATCH_ON_VSYNC_DISABLE | CCDC_CCDCFG_BW656_10BIT,
433 CCDC_CCDCFG);
434 else
435 regw((params->pix_order << CCDC_CCDCFG_Y8POS_SHIFT) |
436 CCDC_LATCH_ON_VSYNC_DISABLE, CCDC_CCDCFG);
437
438 /*
439 * configure the horizontal line offset. This should be a
440 * on 32 byte boundary. So clear LSB 5 bits
441 */
442 regw(((params->win.width * 2 + 31) & ~0x1f), CCDC_HSIZE_OFF);
443
444 /* configure the memory line offset */
445 if (params->buf_type == CCDC_BUFTYPE_FLD_INTERLEAVED)
446 /* two fields are interleaved in memory */
447 regw(CCDC_SDOFST_FIELD_INTERLEAVED, CCDC_SDOFST);
448
449 ccdc_sbl_reset();
450 dev_dbg(ccdc_cfg.dev, "\nEnd of ccdc_config_ycbcr...\n");
451}
452
453static void ccdc_config_black_clamp(struct ccdc_black_clamp *bclamp)
454{
455 u32 val;
456
457 if (!bclamp->enable) {
458 /* configure DCSub */
459 val = (bclamp->dc_sub) & CCDC_BLK_DC_SUB_MASK;
460 regw(val, CCDC_DCSUB);
461 dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to DCSUB...\n", val);
462 regw(CCDC_CLAMP_DEFAULT_VAL, CCDC_CLAMP);
463 dev_dbg(ccdc_cfg.dev, "\nWriting 0x0000 to CLAMP...\n");
464 return;
465 }
466 /*
467 * Configure gain, Start pixel, No of line to be avg,
468 * No of pixel/line to be avg, & Enable the Black clamping
469 */
470 val = ((bclamp->sgain & CCDC_BLK_SGAIN_MASK) |
471 ((bclamp->start_pixel & CCDC_BLK_ST_PXL_MASK) <<
472 CCDC_BLK_ST_PXL_SHIFT) |
473 ((bclamp->sample_ln & CCDC_BLK_SAMPLE_LINE_MASK) <<
474 CCDC_BLK_SAMPLE_LINE_SHIFT) |
475 ((bclamp->sample_pixel & CCDC_BLK_SAMPLE_LN_MASK) <<
476 CCDC_BLK_SAMPLE_LN_SHIFT) | CCDC_BLK_CLAMP_ENABLE);
477 regw(val, CCDC_CLAMP);
478 dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to CLAMP...\n", val);
479 /* If Black clamping is enable then make dcsub 0 */
480 regw(CCDC_DCSUB_DEFAULT_VAL, CCDC_DCSUB);
481 dev_dbg(ccdc_cfg.dev, "\nWriting 0x00000000 to DCSUB...\n");
482}
483
484static void ccdc_config_black_compense(struct ccdc_black_compensation *bcomp)
485{
486 u32 val;
487
488 val = ((bcomp->b & CCDC_BLK_COMP_MASK) |
489 ((bcomp->gb & CCDC_BLK_COMP_MASK) <<
490 CCDC_BLK_COMP_GB_COMP_SHIFT) |
491 ((bcomp->gr & CCDC_BLK_COMP_MASK) <<
492 CCDC_BLK_COMP_GR_COMP_SHIFT) |
493 ((bcomp->r & CCDC_BLK_COMP_MASK) <<
494 CCDC_BLK_COMP_R_COMP_SHIFT));
495 regw(val, CCDC_BLKCMP);
496}
497
498static void ccdc_config_fpc(struct ccdc_fault_pixel *fpc)
499{
500 u32 val;
501
502 /* Initially disable FPC */
503 val = CCDC_FPC_DISABLE;
504 regw(val, CCDC_FPC);
505
506 if (!fpc->enable)
507 return;
508
509 /* Configure Fault pixel if needed */
510 regw(fpc->fpc_table_addr, CCDC_FPC_ADDR);
511 dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to FPC_ADDR...\n",
512 (fpc->fpc_table_addr));
513 /* Write the FPC params with FPC disable */
514 val = fpc->fp_num & CCDC_FPC_FPC_NUM_MASK;
515 regw(val, CCDC_FPC);
516
517 dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to FPC...\n", val);
518 /* read the FPC register */
519 val = regr(CCDC_FPC) | CCDC_FPC_ENABLE;
520 regw(val, CCDC_FPC);
521 dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to FPC...\n", val);
522}
523
524/*
525 * ccdc_config_raw()
526 * This function will configure CCDC for Raw capture mode
527 */
528void ccdc_config_raw(void)
529{
530 struct ccdc_params_raw *params = &ccdc_cfg.bayer;
531 struct ccdc_config_params_raw *config_params =
532 &ccdc_cfg.bayer.config_params;
533 unsigned int syn_mode = 0;
534 unsigned int val;
535
536 dev_dbg(ccdc_cfg.dev, "\nStarting ccdc_config_raw...");
537
538 /* Reset CCDC */
539 ccdc_restore_defaults();
540
541 /* Disable latching function registers on VSYNC */
542 regw(CCDC_LATCH_ON_VSYNC_DISABLE, CCDC_CCDCFG);
543
544 /*
545 * Configure the vertical sync polarity(SYN_MODE.VDPOL),
546 * horizontal sync polarity (SYN_MODE.HDPOL), frame id polarity
547 * (SYN_MODE.FLDPOL), frame format(progressive or interlace),
548 * data size(SYNMODE.DATSIZ), &pixel format (Input mode), output
549 * SDRAM, enable internal timing generator
550 */
551 syn_mode =
552 (((params->vd_pol & CCDC_VD_POL_MASK) << CCDC_VD_POL_SHIFT) |
553 ((params->hd_pol & CCDC_HD_POL_MASK) << CCDC_HD_POL_SHIFT) |
554 ((params->fid_pol & CCDC_FID_POL_MASK) << CCDC_FID_POL_SHIFT) |
555 ((params->frm_fmt & CCDC_FRM_FMT_MASK) << CCDC_FRM_FMT_SHIFT) |
556 ((config_params->data_sz & CCDC_DATA_SZ_MASK) <<
557 CCDC_DATA_SZ_SHIFT) |
558 ((params->pix_fmt & CCDC_PIX_FMT_MASK) << CCDC_PIX_FMT_SHIFT) |
559 CCDC_WEN_ENABLE | CCDC_VDHDEN_ENABLE);
560
561 /* Enable and configure aLaw register if needed */
562 if (config_params->alaw.enable) {
563 val = ((config_params->alaw.gama_wd &
564 CCDC_ALAW_GAMA_WD_MASK) | CCDC_ALAW_ENABLE);
565 regw(val, CCDC_ALAW);
566 dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to ALAW...\n", val);
567 }
568
569 /* Configure video window */
570 ccdc_setwin(&params->win, params->frm_fmt, CCDC_PPC_RAW);
571
572 /* Configure Black Clamp */
573 ccdc_config_black_clamp(&config_params->blk_clamp);
574
575 /* Configure Black level compensation */
576 ccdc_config_black_compense(&config_params->blk_comp);
577
578 /* Configure Fault Pixel Correction */
579 ccdc_config_fpc(&config_params->fault_pxl);
580
581 /* If data size is 8 bit then pack the data */
582 if ((config_params->data_sz == CCDC_DATA_8BITS) ||
583 config_params->alaw.enable)
584 syn_mode |= CCDC_DATA_PACK_ENABLE;
585
586#ifdef CONFIG_DM644X_VIDEO_PORT_ENABLE
587 /* enable video port */
588 val = CCDC_ENABLE_VIDEO_PORT;
589#else
590 /* disable video port */
591 val = CCDC_DISABLE_VIDEO_PORT;
592#endif
593
594 if (config_params->data_sz == CCDC_DATA_8BITS)
595 val |= (CCDC_DATA_10BITS & CCDC_FMTCFG_VPIN_MASK)
596 << CCDC_FMTCFG_VPIN_SHIFT;
597 else
598 val |= (config_params->data_sz & CCDC_FMTCFG_VPIN_MASK)
599 << CCDC_FMTCFG_VPIN_SHIFT;
600 /* Write value in FMTCFG */
601 regw(val, CCDC_FMTCFG);
602
603 dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to FMTCFG...\n", val);
604 /* Configure the color pattern according to mt9t001 sensor */
605 regw(CCDC_COLPTN_VAL, CCDC_COLPTN);
606
607 dev_dbg(ccdc_cfg.dev, "\nWriting 0xBB11BB11 to COLPTN...\n");
608 /*
609 * Configure Data formatter(Video port) pixel selection
610 * (FMT_HORZ, FMT_VERT)
611 */
612 val = ((params->win.left & CCDC_FMT_HORZ_FMTSPH_MASK) <<
613 CCDC_FMT_HORZ_FMTSPH_SHIFT) |
614 (params->win.width & CCDC_FMT_HORZ_FMTLNH_MASK);
615 regw(val, CCDC_FMT_HORZ);
616
617 dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to FMT_HORZ...\n", val);
618 val = (params->win.top & CCDC_FMT_VERT_FMTSLV_MASK)
619 << CCDC_FMT_VERT_FMTSLV_SHIFT;
620 if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE)
621 val |= (params->win.height) & CCDC_FMT_VERT_FMTLNV_MASK;
622 else
623 val |= (params->win.height >> 1) & CCDC_FMT_VERT_FMTLNV_MASK;
624
625 dev_dbg(ccdc_cfg.dev, "\nparams->win.height 0x%x ...\n",
626 params->win.height);
627 regw(val, CCDC_FMT_VERT);
628
629 dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to FMT_VERT...\n", val);
630
631 dev_dbg(ccdc_cfg.dev, "\nbelow regw(val, FMT_VERT)...");
632
633 /*
634 * Configure Horizontal offset register. If pack 8 is enabled then
635 * 1 pixel will take 1 byte
636 */
637 if ((config_params->data_sz == CCDC_DATA_8BITS) ||
638 config_params->alaw.enable)
639 regw((params->win.width + CCDC_32BYTE_ALIGN_VAL) &
640 CCDC_HSIZE_OFF_MASK, CCDC_HSIZE_OFF);
641 else
642 /* else one pixel will take 2 byte */
643 regw(((params->win.width * CCDC_TWO_BYTES_PER_PIXEL) +
644 CCDC_32BYTE_ALIGN_VAL) & CCDC_HSIZE_OFF_MASK,
645 CCDC_HSIZE_OFF);
646
647 /* Set value for SDOFST */
648 if (params->frm_fmt == CCDC_FRMFMT_INTERLACED) {
649 if (params->image_invert_enable) {
650 /* For intelace inverse mode */
651 regw(CCDC_INTERLACED_IMAGE_INVERT, CCDC_SDOFST);
652 dev_dbg(ccdc_cfg.dev, "\nWriting 0x4B6D to SDOFST..\n");
653 }
654
655 else {
656 /* For intelace non inverse mode */
657 regw(CCDC_INTERLACED_NO_IMAGE_INVERT, CCDC_SDOFST);
658 dev_dbg(ccdc_cfg.dev, "\nWriting 0x0249 to SDOFST..\n");
659 }
660 } else if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE) {
661 regw(CCDC_PROGRESSIVE_NO_IMAGE_INVERT, CCDC_SDOFST);
662 dev_dbg(ccdc_cfg.dev, "\nWriting 0x0000 to SDOFST...\n");
663 }
664
665 /*
666 * Configure video port pixel selection (VPOUT)
667 * Here -1 is to make the height value less than FMT_VERT.FMTLNV
668 */
669 if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE)
670 val = (((params->win.height - 1) & CCDC_VP_OUT_VERT_NUM_MASK))
671 << CCDC_VP_OUT_VERT_NUM_SHIFT;
672 else
673 val =
674 ((((params->win.height >> CCDC_INTERLACED_HEIGHT_SHIFT) -
675 1) & CCDC_VP_OUT_VERT_NUM_MASK)) <<
676 CCDC_VP_OUT_VERT_NUM_SHIFT;
677
678 val |= ((((params->win.width))) & CCDC_VP_OUT_HORZ_NUM_MASK)
679 << CCDC_VP_OUT_HORZ_NUM_SHIFT;
680 val |= (params->win.left) & CCDC_VP_OUT_HORZ_ST_MASK;
681 regw(val, CCDC_VP_OUT);
682
683 dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to VP_OUT...\n", val);
684 regw(syn_mode, CCDC_SYN_MODE);
685 dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to SYN_MODE...\n", syn_mode);
686
687 ccdc_sbl_reset();
688 dev_dbg(ccdc_cfg.dev, "\nend of ccdc_config_raw...");
689 ccdc_readregs();
690}
691
692static int ccdc_configure(void)
693{
694 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
695 ccdc_config_raw();
696 else
697 ccdc_config_ycbcr();
698 return 0;
699}
700
701static int ccdc_set_buftype(enum ccdc_buftype buf_type)
702{
703 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
704 ccdc_cfg.bayer.buf_type = buf_type;
705 else
706 ccdc_cfg.ycbcr.buf_type = buf_type;
707 return 0;
708}
709
710static enum ccdc_buftype ccdc_get_buftype(void)
711{
712 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
713 return ccdc_cfg.bayer.buf_type;
714 return ccdc_cfg.ycbcr.buf_type;
715}
716
717static int ccdc_enum_pix(u32 *pix, int i)
718{
719 int ret = -EINVAL;
720 if (ccdc_cfg.if_type == VPFE_RAW_BAYER) {
721 if (i < ARRAY_SIZE(ccdc_raw_bayer_pix_formats)) {
722 *pix = ccdc_raw_bayer_pix_formats[i];
723 ret = 0;
724 }
725 } else {
726 if (i < ARRAY_SIZE(ccdc_raw_yuv_pix_formats)) {
727 *pix = ccdc_raw_yuv_pix_formats[i];
728 ret = 0;
729 }
730 }
731 return ret;
732}
733
734static int ccdc_set_pixel_format(u32 pixfmt)
735{
736 if (ccdc_cfg.if_type == VPFE_RAW_BAYER) {
737 ccdc_cfg.bayer.pix_fmt = CCDC_PIXFMT_RAW;
738 if (pixfmt == V4L2_PIX_FMT_SBGGR8)
739 ccdc_cfg.bayer.config_params.alaw.enable = 1;
740 else if (pixfmt != V4L2_PIX_FMT_SBGGR16)
741 return -EINVAL;
742 } else {
743 if (pixfmt == V4L2_PIX_FMT_YUYV)
744 ccdc_cfg.ycbcr.pix_order = CCDC_PIXORDER_YCBYCR;
745 else if (pixfmt == V4L2_PIX_FMT_UYVY)
746 ccdc_cfg.ycbcr.pix_order = CCDC_PIXORDER_CBYCRY;
747 else
748 return -EINVAL;
749 }
750 return 0;
751}
752
753static u32 ccdc_get_pixel_format(void)
754{
755 struct ccdc_a_law *alaw = &ccdc_cfg.bayer.config_params.alaw;
756 u32 pixfmt;
757
758 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
759 if (alaw->enable)
760 pixfmt = V4L2_PIX_FMT_SBGGR8;
761 else
762 pixfmt = V4L2_PIX_FMT_SBGGR16;
763 else {
764 if (ccdc_cfg.ycbcr.pix_order == CCDC_PIXORDER_YCBYCR)
765 pixfmt = V4L2_PIX_FMT_YUYV;
766 else
767 pixfmt = V4L2_PIX_FMT_UYVY;
768 }
769 return pixfmt;
770}
771
772static int ccdc_set_image_window(struct v4l2_rect *win)
773{
774 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
775 ccdc_cfg.bayer.win = *win;
776 else
777 ccdc_cfg.ycbcr.win = *win;
778 return 0;
779}
780
781static void ccdc_get_image_window(struct v4l2_rect *win)
782{
783 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
784 *win = ccdc_cfg.bayer.win;
785 else
786 *win = ccdc_cfg.ycbcr.win;
787}
788
789static unsigned int ccdc_get_line_length(void)
790{
791 struct ccdc_config_params_raw *config_params =
792 &ccdc_cfg.bayer.config_params;
793 unsigned int len;
794
795 if (ccdc_cfg.if_type == VPFE_RAW_BAYER) {
796 if ((config_params->alaw.enable) ||
797 (config_params->data_sz == CCDC_DATA_8BITS))
798 len = ccdc_cfg.bayer.win.width;
799 else
800 len = ccdc_cfg.bayer.win.width * 2;
801 } else
802 len = ccdc_cfg.ycbcr.win.width * 2;
803 return ALIGN(len, 32);
804}
805
806static int ccdc_set_frame_format(enum ccdc_frmfmt frm_fmt)
807{
808 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
809 ccdc_cfg.bayer.frm_fmt = frm_fmt;
810 else
811 ccdc_cfg.ycbcr.frm_fmt = frm_fmt;
812 return 0;
813}
814
815static enum ccdc_frmfmt ccdc_get_frame_format(void)
816{
817 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
818 return ccdc_cfg.bayer.frm_fmt;
819 else
820 return ccdc_cfg.ycbcr.frm_fmt;
821}
822
823static int ccdc_getfid(void)
824{
825 return (regr(CCDC_SYN_MODE) >> 15) & 1;
826}
827
828/* misc operations */
829static inline void ccdc_setfbaddr(unsigned long addr)
830{
831 regw(addr & 0xffffffe0, CCDC_SDR_ADDR);
832}
833
834static int ccdc_set_hw_if_params(struct vpfe_hw_if_param *params)
835{
836 ccdc_cfg.if_type = params->if_type;
837
838 switch (params->if_type) {
839 case VPFE_BT656:
840 case VPFE_YCBCR_SYNC_16:
841 case VPFE_YCBCR_SYNC_8:
842 case VPFE_BT656_10BIT:
843 ccdc_cfg.ycbcr.vd_pol = params->vdpol;
844 ccdc_cfg.ycbcr.hd_pol = params->hdpol;
845 break;
846 default:
847 /* TODO add support for raw bayer here */
848 return -EINVAL;
849 }
850 return 0;
851}
852
853static void ccdc_save_context(void)
854{
855 ccdc_ctx[CCDC_PCR >> 2] = regr(CCDC_PCR);
856 ccdc_ctx[CCDC_SYN_MODE >> 2] = regr(CCDC_SYN_MODE);
857 ccdc_ctx[CCDC_HD_VD_WID >> 2] = regr(CCDC_HD_VD_WID);
858 ccdc_ctx[CCDC_PIX_LINES >> 2] = regr(CCDC_PIX_LINES);
859 ccdc_ctx[CCDC_HORZ_INFO >> 2] = regr(CCDC_HORZ_INFO);
860 ccdc_ctx[CCDC_VERT_START >> 2] = regr(CCDC_VERT_START);
861 ccdc_ctx[CCDC_VERT_LINES >> 2] = regr(CCDC_VERT_LINES);
862 ccdc_ctx[CCDC_CULLING >> 2] = regr(CCDC_CULLING);
863 ccdc_ctx[CCDC_HSIZE_OFF >> 2] = regr(CCDC_HSIZE_OFF);
864 ccdc_ctx[CCDC_SDOFST >> 2] = regr(CCDC_SDOFST);
865 ccdc_ctx[CCDC_SDR_ADDR >> 2] = regr(CCDC_SDR_ADDR);
866 ccdc_ctx[CCDC_CLAMP >> 2] = regr(CCDC_CLAMP);
867 ccdc_ctx[CCDC_DCSUB >> 2] = regr(CCDC_DCSUB);
868 ccdc_ctx[CCDC_COLPTN >> 2] = regr(CCDC_COLPTN);
869 ccdc_ctx[CCDC_BLKCMP >> 2] = regr(CCDC_BLKCMP);
870 ccdc_ctx[CCDC_FPC >> 2] = regr(CCDC_FPC);
871 ccdc_ctx[CCDC_FPC_ADDR >> 2] = regr(CCDC_FPC_ADDR);
872 ccdc_ctx[CCDC_VDINT >> 2] = regr(CCDC_VDINT);
873 ccdc_ctx[CCDC_ALAW >> 2] = regr(CCDC_ALAW);
874 ccdc_ctx[CCDC_REC656IF >> 2] = regr(CCDC_REC656IF);
875 ccdc_ctx[CCDC_CCDCFG >> 2] = regr(CCDC_CCDCFG);
876 ccdc_ctx[CCDC_FMTCFG >> 2] = regr(CCDC_FMTCFG);
877 ccdc_ctx[CCDC_FMT_HORZ >> 2] = regr(CCDC_FMT_HORZ);
878 ccdc_ctx[CCDC_FMT_VERT >> 2] = regr(CCDC_FMT_VERT);
879 ccdc_ctx[CCDC_FMT_ADDR0 >> 2] = regr(CCDC_FMT_ADDR0);
880 ccdc_ctx[CCDC_FMT_ADDR1 >> 2] = regr(CCDC_FMT_ADDR1);
881 ccdc_ctx[CCDC_FMT_ADDR2 >> 2] = regr(CCDC_FMT_ADDR2);
882 ccdc_ctx[CCDC_FMT_ADDR3 >> 2] = regr(CCDC_FMT_ADDR3);
883 ccdc_ctx[CCDC_FMT_ADDR4 >> 2] = regr(CCDC_FMT_ADDR4);
884 ccdc_ctx[CCDC_FMT_ADDR5 >> 2] = regr(CCDC_FMT_ADDR5);
885 ccdc_ctx[CCDC_FMT_ADDR6 >> 2] = regr(CCDC_FMT_ADDR6);
886 ccdc_ctx[CCDC_FMT_ADDR7 >> 2] = regr(CCDC_FMT_ADDR7);
887 ccdc_ctx[CCDC_PRGEVEN_0 >> 2] = regr(CCDC_PRGEVEN_0);
888 ccdc_ctx[CCDC_PRGEVEN_1 >> 2] = regr(CCDC_PRGEVEN_1);
889 ccdc_ctx[CCDC_PRGODD_0 >> 2] = regr(CCDC_PRGODD_0);
890 ccdc_ctx[CCDC_PRGODD_1 >> 2] = regr(CCDC_PRGODD_1);
891 ccdc_ctx[CCDC_VP_OUT >> 2] = regr(CCDC_VP_OUT);
892}
893
894static void ccdc_restore_context(void)
895{
896 regw(ccdc_ctx[CCDC_SYN_MODE >> 2], CCDC_SYN_MODE);
897 regw(ccdc_ctx[CCDC_HD_VD_WID >> 2], CCDC_HD_VD_WID);
898 regw(ccdc_ctx[CCDC_PIX_LINES >> 2], CCDC_PIX_LINES);
899 regw(ccdc_ctx[CCDC_HORZ_INFO >> 2], CCDC_HORZ_INFO);
900 regw(ccdc_ctx[CCDC_VERT_START >> 2], CCDC_VERT_START);
901 regw(ccdc_ctx[CCDC_VERT_LINES >> 2], CCDC_VERT_LINES);
902 regw(ccdc_ctx[CCDC_CULLING >> 2], CCDC_CULLING);
903 regw(ccdc_ctx[CCDC_HSIZE_OFF >> 2], CCDC_HSIZE_OFF);
904 regw(ccdc_ctx[CCDC_SDOFST >> 2], CCDC_SDOFST);
905 regw(ccdc_ctx[CCDC_SDR_ADDR >> 2], CCDC_SDR_ADDR);
906 regw(ccdc_ctx[CCDC_CLAMP >> 2], CCDC_CLAMP);
907 regw(ccdc_ctx[CCDC_DCSUB >> 2], CCDC_DCSUB);
908 regw(ccdc_ctx[CCDC_COLPTN >> 2], CCDC_COLPTN);
909 regw(ccdc_ctx[CCDC_BLKCMP >> 2], CCDC_BLKCMP);
910 regw(ccdc_ctx[CCDC_FPC >> 2], CCDC_FPC);
911 regw(ccdc_ctx[CCDC_FPC_ADDR >> 2], CCDC_FPC_ADDR);
912 regw(ccdc_ctx[CCDC_VDINT >> 2], CCDC_VDINT);
913 regw(ccdc_ctx[CCDC_ALAW >> 2], CCDC_ALAW);
914 regw(ccdc_ctx[CCDC_REC656IF >> 2], CCDC_REC656IF);
915 regw(ccdc_ctx[CCDC_CCDCFG >> 2], CCDC_CCDCFG);
916 regw(ccdc_ctx[CCDC_FMTCFG >> 2], CCDC_FMTCFG);
917 regw(ccdc_ctx[CCDC_FMT_HORZ >> 2], CCDC_FMT_HORZ);
918 regw(ccdc_ctx[CCDC_FMT_VERT >> 2], CCDC_FMT_VERT);
919 regw(ccdc_ctx[CCDC_FMT_ADDR0 >> 2], CCDC_FMT_ADDR0);
920 regw(ccdc_ctx[CCDC_FMT_ADDR1 >> 2], CCDC_FMT_ADDR1);
921 regw(ccdc_ctx[CCDC_FMT_ADDR2 >> 2], CCDC_FMT_ADDR2);
922 regw(ccdc_ctx[CCDC_FMT_ADDR3 >> 2], CCDC_FMT_ADDR3);
923 regw(ccdc_ctx[CCDC_FMT_ADDR4 >> 2], CCDC_FMT_ADDR4);
924 regw(ccdc_ctx[CCDC_FMT_ADDR5 >> 2], CCDC_FMT_ADDR5);
925 regw(ccdc_ctx[CCDC_FMT_ADDR6 >> 2], CCDC_FMT_ADDR6);
926 regw(ccdc_ctx[CCDC_FMT_ADDR7 >> 2], CCDC_FMT_ADDR7);
927 regw(ccdc_ctx[CCDC_PRGEVEN_0 >> 2], CCDC_PRGEVEN_0);
928 regw(ccdc_ctx[CCDC_PRGEVEN_1 >> 2], CCDC_PRGEVEN_1);
929 regw(ccdc_ctx[CCDC_PRGODD_0 >> 2], CCDC_PRGODD_0);
930 regw(ccdc_ctx[CCDC_PRGODD_1 >> 2], CCDC_PRGODD_1);
931 regw(ccdc_ctx[CCDC_VP_OUT >> 2], CCDC_VP_OUT);
932 regw(ccdc_ctx[CCDC_PCR >> 2], CCDC_PCR);
933}
934static struct ccdc_hw_device ccdc_hw_dev = {
935 .name = "DM6446 CCDC",
936 .owner = THIS_MODULE,
937 .hw_ops = {
938 .open = ccdc_open,
939 .close = ccdc_close,
940 .reset = ccdc_sbl_reset,
941 .enable = ccdc_enable,
942 .set_hw_if_params = ccdc_set_hw_if_params,
943 .set_params = ccdc_set_params,
944 .configure = ccdc_configure,
945 .set_buftype = ccdc_set_buftype,
946 .get_buftype = ccdc_get_buftype,
947 .enum_pix = ccdc_enum_pix,
948 .set_pixel_format = ccdc_set_pixel_format,
949 .get_pixel_format = ccdc_get_pixel_format,
950 .set_frame_format = ccdc_set_frame_format,
951 .get_frame_format = ccdc_get_frame_format,
952 .set_image_window = ccdc_set_image_window,
953 .get_image_window = ccdc_get_image_window,
954 .get_line_length = ccdc_get_line_length,
955 .setfbaddr = ccdc_setfbaddr,
956 .getfid = ccdc_getfid,
957 },
958};
959
960static int __devinit dm644x_ccdc_probe(struct platform_device *pdev)
961{
962 struct resource *res;
963 int status = 0;
964
965 /*
966 * first try to register with vpfe. If not correct platform, then we
967 * don't have to iomap
968 */
969 status = vpfe_register_ccdc_device(&ccdc_hw_dev);
970 if (status < 0)
971 return status;
972
973 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
974 if (!res) {
975 status = -ENODEV;
976 goto fail_nores;
977 }
978
979 res = request_mem_region(res->start, resource_size(res), res->name);
980 if (!res) {
981 status = -EBUSY;
982 goto fail_nores;
983 }
984
985 ccdc_cfg.base_addr = ioremap_nocache(res->start, resource_size(res));
986 if (!ccdc_cfg.base_addr) {
987 status = -ENOMEM;
988 goto fail_nomem;
989 }
990
991 /* Get and enable Master clock */
992 ccdc_cfg.mclk = clk_get(&pdev->dev, "master");
993 if (IS_ERR(ccdc_cfg.mclk)) {
994 status = PTR_ERR(ccdc_cfg.mclk);
995 goto fail_nomap;
996 }
997 if (clk_enable(ccdc_cfg.mclk)) {
998 status = -ENODEV;
999 goto fail_mclk;
1000 }
1001
1002 /* Get and enable Slave clock */
1003 ccdc_cfg.sclk = clk_get(&pdev->dev, "slave");
1004 if (IS_ERR(ccdc_cfg.sclk)) {
1005 status = PTR_ERR(ccdc_cfg.sclk);
1006 goto fail_mclk;
1007 }
1008 if (clk_enable(ccdc_cfg.sclk)) {
1009 status = -ENODEV;
1010 goto fail_sclk;
1011 }
1012 ccdc_cfg.dev = &pdev->dev;
1013 printk(KERN_NOTICE "%s is registered with vpfe.\n", ccdc_hw_dev.name);
1014 return 0;
1015fail_sclk:
1016 clk_put(ccdc_cfg.sclk);
1017fail_mclk:
1018 clk_put(ccdc_cfg.mclk);
1019fail_nomap:
1020 iounmap(ccdc_cfg.base_addr);
1021fail_nomem:
1022 release_mem_region(res->start, resource_size(res));
1023fail_nores:
1024 vpfe_unregister_ccdc_device(&ccdc_hw_dev);
1025 return status;
1026}
1027
1028static int dm644x_ccdc_remove(struct platform_device *pdev)
1029{
1030 struct resource *res;
1031
1032 clk_put(ccdc_cfg.mclk);
1033 clk_put(ccdc_cfg.sclk);
1034 iounmap(ccdc_cfg.base_addr);
1035 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1036 if (res)
1037 release_mem_region(res->start, resource_size(res));
1038 vpfe_unregister_ccdc_device(&ccdc_hw_dev);
1039 return 0;
1040}
1041
1042static int dm644x_ccdc_suspend(struct device *dev)
1043{
1044 /* Save CCDC context */
1045 ccdc_save_context();
1046 /* Disable CCDC */
1047 ccdc_enable(0);
1048 /* Disable both master and slave clock */
1049 clk_disable(ccdc_cfg.mclk);
1050 clk_disable(ccdc_cfg.sclk);
1051
1052 return 0;
1053}
1054
1055static int dm644x_ccdc_resume(struct device *dev)
1056{
1057 /* Enable both master and slave clock */
1058 clk_enable(ccdc_cfg.mclk);
1059 clk_enable(ccdc_cfg.sclk);
1060 /* Restore CCDC context */
1061 ccdc_restore_context();
1062
1063 return 0;
1064}
1065
1066static const struct dev_pm_ops dm644x_ccdc_pm_ops = {
1067 .suspend = dm644x_ccdc_suspend,
1068 .resume = dm644x_ccdc_resume,
1069};
1070
1071static struct platform_driver dm644x_ccdc_driver = {
1072 .driver = {
1073 .name = "dm644x_ccdc",
1074 .owner = THIS_MODULE,
1075 .pm = &dm644x_ccdc_pm_ops,
1076 },
1077 .remove = __devexit_p(dm644x_ccdc_remove),
1078 .probe = dm644x_ccdc_probe,
1079};
1080
1081module_platform_driver(dm644x_ccdc_driver);
diff --git a/drivers/media/video/davinci/dm644x_ccdc_regs.h b/drivers/media/video/davinci/dm644x_ccdc_regs.h
deleted file mode 100644
index 90370e414e2c..000000000000
--- a/drivers/media/video/davinci/dm644x_ccdc_regs.h
+++ /dev/null
@@ -1,153 +0,0 @@
1/*
2 * Copyright (C) 2006-2009 Texas Instruments Inc
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18#ifndef _DM644X_CCDC_REGS_H
19#define _DM644X_CCDC_REGS_H
20
21/**************************************************************************\
22* Register OFFSET Definitions
23\**************************************************************************/
24#define CCDC_PID 0x0
25#define CCDC_PCR 0x4
26#define CCDC_SYN_MODE 0x8
27#define CCDC_HD_VD_WID 0xc
28#define CCDC_PIX_LINES 0x10
29#define CCDC_HORZ_INFO 0x14
30#define CCDC_VERT_START 0x18
31#define CCDC_VERT_LINES 0x1c
32#define CCDC_CULLING 0x20
33#define CCDC_HSIZE_OFF 0x24
34#define CCDC_SDOFST 0x28
35#define CCDC_SDR_ADDR 0x2c
36#define CCDC_CLAMP 0x30
37#define CCDC_DCSUB 0x34
38#define CCDC_COLPTN 0x38
39#define CCDC_BLKCMP 0x3c
40#define CCDC_FPC 0x40
41#define CCDC_FPC_ADDR 0x44
42#define CCDC_VDINT 0x48
43#define CCDC_ALAW 0x4c
44#define CCDC_REC656IF 0x50
45#define CCDC_CCDCFG 0x54
46#define CCDC_FMTCFG 0x58
47#define CCDC_FMT_HORZ 0x5c
48#define CCDC_FMT_VERT 0x60
49#define CCDC_FMT_ADDR0 0x64
50#define CCDC_FMT_ADDR1 0x68
51#define CCDC_FMT_ADDR2 0x6c
52#define CCDC_FMT_ADDR3 0x70
53#define CCDC_FMT_ADDR4 0x74
54#define CCDC_FMT_ADDR5 0x78
55#define CCDC_FMT_ADDR6 0x7c
56#define CCDC_FMT_ADDR7 0x80
57#define CCDC_PRGEVEN_0 0x84
58#define CCDC_PRGEVEN_1 0x88
59#define CCDC_PRGODD_0 0x8c
60#define CCDC_PRGODD_1 0x90
61#define CCDC_VP_OUT 0x94
62#define CCDC_REG_END 0x98
63
64/***************************************************************
65* Define for various register bit mask and shifts for CCDC
66****************************************************************/
67#define CCDC_FID_POL_MASK 1
68#define CCDC_FID_POL_SHIFT 4
69#define CCDC_HD_POL_MASK 1
70#define CCDC_HD_POL_SHIFT 3
71#define CCDC_VD_POL_MASK 1
72#define CCDC_VD_POL_SHIFT 2
73#define CCDC_HSIZE_OFF_MASK 0xffffffe0
74#define CCDC_32BYTE_ALIGN_VAL 31
75#define CCDC_FRM_FMT_MASK 0x1
76#define CCDC_FRM_FMT_SHIFT 7
77#define CCDC_DATA_SZ_MASK 7
78#define CCDC_DATA_SZ_SHIFT 8
79#define CCDC_PIX_FMT_MASK 3
80#define CCDC_PIX_FMT_SHIFT 12
81#define CCDC_VP2SDR_DISABLE 0xFFFBFFFF
82#define CCDC_WEN_ENABLE (1 << 17)
83#define CCDC_SDR2RSZ_DISABLE 0xFFF7FFFF
84#define CCDC_VDHDEN_ENABLE (1 << 16)
85#define CCDC_LPF_ENABLE (1 << 14)
86#define CCDC_ALAW_ENABLE (1 << 3)
87#define CCDC_ALAW_GAMA_WD_MASK 7
88#define CCDC_BLK_CLAMP_ENABLE (1 << 31)
89#define CCDC_BLK_SGAIN_MASK 0x1F
90#define CCDC_BLK_ST_PXL_MASK 0x7FFF
91#define CCDC_BLK_ST_PXL_SHIFT 10
92#define CCDC_BLK_SAMPLE_LN_MASK 7
93#define CCDC_BLK_SAMPLE_LN_SHIFT 28
94#define CCDC_BLK_SAMPLE_LINE_MASK 7
95#define CCDC_BLK_SAMPLE_LINE_SHIFT 25
96#define CCDC_BLK_DC_SUB_MASK 0x03FFF
97#define CCDC_BLK_COMP_MASK 0xFF
98#define CCDC_BLK_COMP_GB_COMP_SHIFT 8
99#define CCDC_BLK_COMP_GR_COMP_SHIFT 16
100#define CCDC_BLK_COMP_R_COMP_SHIFT 24
101#define CCDC_LATCH_ON_VSYNC_DISABLE (1 << 15)
102#define CCDC_FPC_ENABLE (1 << 15)
103#define CCDC_FPC_DISABLE 0
104#define CCDC_FPC_FPC_NUM_MASK 0x7FFF
105#define CCDC_DATA_PACK_ENABLE (1 << 11)
106#define CCDC_FMTCFG_VPIN_MASK 7
107#define CCDC_FMTCFG_VPIN_SHIFT 12
108#define CCDC_FMT_HORZ_FMTLNH_MASK 0x1FFF
109#define CCDC_FMT_HORZ_FMTSPH_MASK 0x1FFF
110#define CCDC_FMT_HORZ_FMTSPH_SHIFT 16
111#define CCDC_FMT_VERT_FMTLNV_MASK 0x1FFF
112#define CCDC_FMT_VERT_FMTSLV_MASK 0x1FFF
113#define CCDC_FMT_VERT_FMTSLV_SHIFT 16
114#define CCDC_VP_OUT_VERT_NUM_MASK 0x3FFF
115#define CCDC_VP_OUT_VERT_NUM_SHIFT 17
116#define CCDC_VP_OUT_HORZ_NUM_MASK 0x1FFF
117#define CCDC_VP_OUT_HORZ_NUM_SHIFT 4
118#define CCDC_VP_OUT_HORZ_ST_MASK 0xF
119#define CCDC_HORZ_INFO_SPH_SHIFT 16
120#define CCDC_VERT_START_SLV0_SHIFT 16
121#define CCDC_VDINT_VDINT0_SHIFT 16
122#define CCDC_VDINT_VDINT1_MASK 0xFFFF
123#define CCDC_PPC_RAW 1
124#define CCDC_DCSUB_DEFAULT_VAL 0
125#define CCDC_CLAMP_DEFAULT_VAL 0
126#define CCDC_ENABLE_VIDEO_PORT 0x8000
127#define CCDC_DISABLE_VIDEO_PORT 0
128#define CCDC_COLPTN_VAL 0xBB11BB11
129#define CCDC_TWO_BYTES_PER_PIXEL 2
130#define CCDC_INTERLACED_IMAGE_INVERT 0x4B6D
131#define CCDC_INTERLACED_NO_IMAGE_INVERT 0x0249
132#define CCDC_PROGRESSIVE_IMAGE_INVERT 0x4000
133#define CCDC_PROGRESSIVE_NO_IMAGE_INVERT 0
134#define CCDC_INTERLACED_HEIGHT_SHIFT 1
135#define CCDC_SYN_MODE_INPMOD_SHIFT 12
136#define CCDC_SYN_MODE_INPMOD_MASK 3
137#define CCDC_SYN_MODE_8BITS (7 << 8)
138#define CCDC_SYN_MODE_10BITS (6 << 8)
139#define CCDC_SYN_MODE_11BITS (5 << 8)
140#define CCDC_SYN_MODE_12BITS (4 << 8)
141#define CCDC_SYN_MODE_13BITS (3 << 8)
142#define CCDC_SYN_MODE_14BITS (2 << 8)
143#define CCDC_SYN_MODE_15BITS (1 << 8)
144#define CCDC_SYN_MODE_16BITS (0 << 8)
145#define CCDC_SYN_FLDMODE_MASK 1
146#define CCDC_SYN_FLDMODE_SHIFT 7
147#define CCDC_REC656IF_BT656_EN 3
148#define CCDC_SYN_MODE_VD_POL_NEGATIVE (1 << 2)
149#define CCDC_CCDCFG_Y8POS_SHIFT 11
150#define CCDC_CCDCFG_BW656_10BIT (1 << 5)
151#define CCDC_SDOFST_FIELD_INTERLEAVED 0x249
152#define CCDC_NO_CULLING 0xffff00ff
153#endif
diff --git a/drivers/media/video/davinci/isif.c b/drivers/media/video/davinci/isif.c
deleted file mode 100644
index b99d5423e3a8..000000000000
--- a/drivers/media/video/davinci/isif.c
+++ /dev/null
@@ -1,1162 +0,0 @@
1/*
2 * Copyright (C) 2008-2009 Texas Instruments Inc
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Image Sensor Interface (ISIF) driver
19 *
20 * This driver is for configuring the ISIF IP available on DM365 or any other
21 * TI SoCs. This is used for capturing yuv or bayer video or image data
22 * from a decoder or sensor. This IP is similar to the CCDC IP on DM355
23 * and DM6446, but with enhanced or additional ip blocks. The driver
24 * configures the ISIF upon commands from the vpfe bridge driver through
25 * ccdc_hw_device interface.
26 *
27 * TODO: 1) Raw bayer parameter settings and bayer capture
28 * 2) Add support for control ioctl
29 */
30#include <linux/delay.h>
31#include <linux/platform_device.h>
32#include <linux/uaccess.h>
33#include <linux/io.h>
34#include <linux/videodev2.h>
35#include <linux/clk.h>
36#include <linux/err.h>
37#include <linux/module.h>
38
39#include <mach/mux.h>
40
41#include <media/davinci/isif.h>
42#include <media/davinci/vpss.h>
43
44#include "isif_regs.h"
45#include "ccdc_hw_device.h"
46
47/* Defaults for module configuration parameters */
48static struct isif_config_params_raw isif_config_defaults = {
49 .linearize = {
50 .en = 0,
51 .corr_shft = ISIF_NO_SHIFT,
52 .scale_fact = {1, 0},
53 },
54 .df_csc = {
55 .df_or_csc = 0,
56 .csc = {
57 .en = 0,
58 },
59 },
60 .dfc = {
61 .en = 0,
62 },
63 .bclamp = {
64 .en = 0,
65 },
66 .gain_offset = {
67 .gain = {
68 .r_ye = {1, 0},
69 .gr_cy = {1, 0},
70 .gb_g = {1, 0},
71 .b_mg = {1, 0},
72 },
73 },
74 .culling = {
75 .hcpat_odd = 0xff,
76 .hcpat_even = 0xff,
77 .vcpat = 0xff,
78 },
79 .compress = {
80 .alg = ISIF_ALAW,
81 },
82};
83
84/* ISIF operation configuration */
85static struct isif_oper_config {
86 struct device *dev;
87 enum vpfe_hw_if_type if_type;
88 struct isif_ycbcr_config ycbcr;
89 struct isif_params_raw bayer;
90 enum isif_data_pack data_pack;
91 /* Master clock */
92 struct clk *mclk;
93 /* ISIF base address */
94 void __iomem *base_addr;
95 /* ISIF Linear Table 0 */
96 void __iomem *linear_tbl0_addr;
97 /* ISIF Linear Table 1 */
98 void __iomem *linear_tbl1_addr;
99} isif_cfg = {
100 .ycbcr = {
101 .pix_fmt = CCDC_PIXFMT_YCBCR_8BIT,
102 .frm_fmt = CCDC_FRMFMT_INTERLACED,
103 .win = ISIF_WIN_NTSC,
104 .fid_pol = VPFE_PINPOL_POSITIVE,
105 .vd_pol = VPFE_PINPOL_POSITIVE,
106 .hd_pol = VPFE_PINPOL_POSITIVE,
107 .pix_order = CCDC_PIXORDER_CBYCRY,
108 .buf_type = CCDC_BUFTYPE_FLD_INTERLEAVED,
109 },
110 .bayer = {
111 .pix_fmt = CCDC_PIXFMT_RAW,
112 .frm_fmt = CCDC_FRMFMT_PROGRESSIVE,
113 .win = ISIF_WIN_VGA,
114 .fid_pol = VPFE_PINPOL_POSITIVE,
115 .vd_pol = VPFE_PINPOL_POSITIVE,
116 .hd_pol = VPFE_PINPOL_POSITIVE,
117 .gain = {
118 .r_ye = {1, 0},
119 .gr_cy = {1, 0},
120 .gb_g = {1, 0},
121 .b_mg = {1, 0},
122 },
123 .cfa_pat = ISIF_CFA_PAT_MOSAIC,
124 .data_msb = ISIF_BIT_MSB_11,
125 .config_params = {
126 .data_shift = ISIF_NO_SHIFT,
127 .col_pat_field0 = {
128 .olop = ISIF_GREEN_BLUE,
129 .olep = ISIF_BLUE,
130 .elop = ISIF_RED,
131 .elep = ISIF_GREEN_RED,
132 },
133 .col_pat_field1 = {
134 .olop = ISIF_GREEN_BLUE,
135 .olep = ISIF_BLUE,
136 .elop = ISIF_RED,
137 .elep = ISIF_GREEN_RED,
138 },
139 .test_pat_gen = 0,
140 },
141 },
142 .data_pack = ISIF_DATA_PACK8,
143};
144
145/* Raw Bayer formats */
146static const u32 isif_raw_bayer_pix_formats[] = {
147 V4L2_PIX_FMT_SBGGR8, V4L2_PIX_FMT_SBGGR16};
148
149/* Raw YUV formats */
150static const u32 isif_raw_yuv_pix_formats[] = {
151 V4L2_PIX_FMT_UYVY, V4L2_PIX_FMT_YUYV};
152
153/* register access routines */
154static inline u32 regr(u32 offset)
155{
156 return __raw_readl(isif_cfg.base_addr + offset);
157}
158
159static inline void regw(u32 val, u32 offset)
160{
161 __raw_writel(val, isif_cfg.base_addr + offset);
162}
163
164/* reg_modify() - read, modify and write register */
165static inline u32 reg_modify(u32 mask, u32 val, u32 offset)
166{
167 u32 new_val = (regr(offset) & ~mask) | (val & mask);
168
169 regw(new_val, offset);
170 return new_val;
171}
172
173static inline void regw_lin_tbl(u32 val, u32 offset, int i)
174{
175 if (!i)
176 __raw_writel(val, isif_cfg.linear_tbl0_addr + offset);
177 else
178 __raw_writel(val, isif_cfg.linear_tbl1_addr + offset);
179}
180
181static void isif_disable_all_modules(void)
182{
183 /* disable BC */
184 regw(0, CLAMPCFG);
185 /* disable vdfc */
186 regw(0, DFCCTL);
187 /* disable CSC */
188 regw(0, CSCCTL);
189 /* disable linearization */
190 regw(0, LINCFG0);
191 /* disable other modules here as they are supported */
192}
193
194static void isif_enable(int en)
195{
196 if (!en) {
197 /* Before disable isif, disable all ISIF modules */
198 isif_disable_all_modules();
199 /*
200 * wait for next VD. Assume lowest scan rate is 12 Hz. So
201 * 100 msec delay is good enough
202 */
203 msleep(100);
204 }
205 reg_modify(ISIF_SYNCEN_VDHDEN_MASK, en, SYNCEN);
206}
207
208static void isif_enable_output_to_sdram(int en)
209{
210 reg_modify(ISIF_SYNCEN_WEN_MASK, en << ISIF_SYNCEN_WEN_SHIFT, SYNCEN);
211}
212
213static void isif_config_culling(struct isif_cul *cul)
214{
215 u32 val;
216
217 /* Horizontal pattern */
218 val = (cul->hcpat_even << CULL_PAT_EVEN_LINE_SHIFT) | cul->hcpat_odd;
219 regw(val, CULH);
220
221 /* vertical pattern */
222 regw(cul->vcpat, CULV);
223
224 /* LPF */
225 reg_modify(ISIF_LPF_MASK << ISIF_LPF_SHIFT,
226 cul->en_lpf << ISIF_LPF_SHIFT, MODESET);
227}
228
229static void isif_config_gain_offset(void)
230{
231 struct isif_gain_offsets_adj *gain_off_p =
232 &isif_cfg.bayer.config_params.gain_offset;
233 u32 val;
234
235 val = (!!gain_off_p->gain_sdram_en << GAIN_SDRAM_EN_SHIFT) |
236 (!!gain_off_p->gain_ipipe_en << GAIN_IPIPE_EN_SHIFT) |
237 (!!gain_off_p->gain_h3a_en << GAIN_H3A_EN_SHIFT) |
238 (!!gain_off_p->offset_sdram_en << OFST_SDRAM_EN_SHIFT) |
239 (!!gain_off_p->offset_ipipe_en << OFST_IPIPE_EN_SHIFT) |
240 (!!gain_off_p->offset_h3a_en << OFST_H3A_EN_SHIFT);
241
242 reg_modify(GAIN_OFFSET_EN_MASK, val, CGAMMAWD);
243
244 val = (gain_off_p->gain.r_ye.integer << GAIN_INTEGER_SHIFT) |
245 gain_off_p->gain.r_ye.decimal;
246 regw(val, CRGAIN);
247
248 val = (gain_off_p->gain.gr_cy.integer << GAIN_INTEGER_SHIFT) |
249 gain_off_p->gain.gr_cy.decimal;
250 regw(val, CGRGAIN);
251
252 val = (gain_off_p->gain.gb_g.integer << GAIN_INTEGER_SHIFT) |
253 gain_off_p->gain.gb_g.decimal;
254 regw(val, CGBGAIN);
255
256 val = (gain_off_p->gain.b_mg.integer << GAIN_INTEGER_SHIFT) |
257 gain_off_p->gain.b_mg.decimal;
258 regw(val, CBGAIN);
259
260 regw(gain_off_p->offset, COFSTA);
261}
262
263static void isif_restore_defaults(void)
264{
265 enum vpss_ccdc_source_sel source = VPSS_CCDCIN;
266
267 dev_dbg(isif_cfg.dev, "\nstarting isif_restore_defaults...");
268 isif_cfg.bayer.config_params = isif_config_defaults;
269 /* Enable clock to ISIF, IPIPEIF and BL */
270 vpss_enable_clock(VPSS_CCDC_CLOCK, 1);
271 vpss_enable_clock(VPSS_IPIPEIF_CLOCK, 1);
272 vpss_enable_clock(VPSS_BL_CLOCK, 1);
273 /* Set default offset and gain */
274 isif_config_gain_offset();
275 vpss_select_ccdc_source(source);
276 dev_dbg(isif_cfg.dev, "\nEnd of isif_restore_defaults...");
277}
278
279static int isif_open(struct device *device)
280{
281 isif_restore_defaults();
282 return 0;
283}
284
285/* This function will configure the window size to be capture in ISIF reg */
286static void isif_setwin(struct v4l2_rect *image_win,
287 enum ccdc_frmfmt frm_fmt, int ppc)
288{
289 int horz_start, horz_nr_pixels;
290 int vert_start, vert_nr_lines;
291 int mid_img = 0;
292
293 dev_dbg(isif_cfg.dev, "\nStarting isif_setwin...");
294 /*
295 * ppc - per pixel count. indicates how many pixels per cell
296 * output to SDRAM. example, for ycbcr, it is one y and one c, so 2.
297 * raw capture this is 1
298 */
299 horz_start = image_win->left << (ppc - 1);
300 horz_nr_pixels = ((image_win->width) << (ppc - 1)) - 1;
301
302 /* Writing the horizontal info into the registers */
303 regw(horz_start & START_PX_HOR_MASK, SPH);
304 regw(horz_nr_pixels & NUM_PX_HOR_MASK, LNH);
305 vert_start = image_win->top;
306
307 if (frm_fmt == CCDC_FRMFMT_INTERLACED) {
308 vert_nr_lines = (image_win->height >> 1) - 1;
309 vert_start >>= 1;
310 /* To account for VD since line 0 doesn't have any data */
311 vert_start += 1;
312 } else {
313 /* To account for VD since line 0 doesn't have any data */
314 vert_start += 1;
315 vert_nr_lines = image_win->height - 1;
316 /* configure VDINT0 and VDINT1 */
317 mid_img = vert_start + (image_win->height / 2);
318 regw(mid_img, VDINT1);
319 }
320
321 regw(0, VDINT0);
322 regw(vert_start & START_VER_ONE_MASK, SLV0);
323 regw(vert_start & START_VER_TWO_MASK, SLV1);
324 regw(vert_nr_lines & NUM_LINES_VER, LNV);
325}
326
327static void isif_config_bclamp(struct isif_black_clamp *bc)
328{
329 u32 val;
330
331 /*
332 * DC Offset is always added to image data irrespective of bc enable
333 * status
334 */
335 regw(bc->dc_offset, CLDCOFST);
336
337 if (bc->en) {
338 val = bc->bc_mode_color << ISIF_BC_MODE_COLOR_SHIFT;
339
340 /* Enable BC and horizontal clamp caculation paramaters */
341 val = val | 1 | (bc->horz.mode << ISIF_HORZ_BC_MODE_SHIFT);
342
343 regw(val, CLAMPCFG);
344
345 if (bc->horz.mode != ISIF_HORZ_BC_DISABLE) {
346 /*
347 * Window count for calculation
348 * Base window selection
349 * pixel limit
350 * Horizontal size of window
351 * vertical size of the window
352 * Horizontal start position of the window
353 * Vertical start position of the window
354 */
355 val = bc->horz.win_count_calc |
356 ((!!bc->horz.base_win_sel_calc) <<
357 ISIF_HORZ_BC_WIN_SEL_SHIFT) |
358 ((!!bc->horz.clamp_pix_limit) <<
359 ISIF_HORZ_BC_PIX_LIMIT_SHIFT) |
360 (bc->horz.win_h_sz_calc <<
361 ISIF_HORZ_BC_WIN_H_SIZE_SHIFT) |
362 (bc->horz.win_v_sz_calc <<
363 ISIF_HORZ_BC_WIN_V_SIZE_SHIFT);
364 regw(val, CLHWIN0);
365
366 regw(bc->horz.win_start_h_calc, CLHWIN1);
367 regw(bc->horz.win_start_v_calc, CLHWIN2);
368 }
369
370 /* vertical clamp caculation paramaters */
371
372 /* Reset clamp value sel for previous line */
373 val |=
374 (bc->vert.reset_val_sel << ISIF_VERT_BC_RST_VAL_SEL_SHIFT) |
375 (bc->vert.line_ave_coef << ISIF_VERT_BC_LINE_AVE_COEF_SHIFT);
376 regw(val, CLVWIN0);
377
378 /* Optical Black horizontal start position */
379 regw(bc->vert.ob_start_h, CLVWIN1);
380 /* Optical Black vertical start position */
381 regw(bc->vert.ob_start_v, CLVWIN2);
382 /* Optical Black vertical size for calculation */
383 regw(bc->vert.ob_v_sz_calc, CLVWIN3);
384 /* Vertical start position for BC subtraction */
385 regw(bc->vert_start_sub, CLSV);
386 }
387}
388
389static void isif_config_linearization(struct isif_linearize *linearize)
390{
391 u32 val, i;
392
393 if (!linearize->en) {
394 regw(0, LINCFG0);
395 return;
396 }
397
398 /* shift value for correction & enable linearization (set lsb) */
399 val = (linearize->corr_shft << ISIF_LIN_CORRSFT_SHIFT) | 1;
400 regw(val, LINCFG0);
401
402 /* Scale factor */
403 val = ((!!linearize->scale_fact.integer) <<
404 ISIF_LIN_SCALE_FACT_INTEG_SHIFT) |
405 linearize->scale_fact.decimal;
406 regw(val, LINCFG1);
407
408 for (i = 0; i < ISIF_LINEAR_TAB_SIZE; i++) {
409 if (i % 2)
410 regw_lin_tbl(linearize->table[i], ((i >> 1) << 2), 1);
411 else
412 regw_lin_tbl(linearize->table[i], ((i >> 1) << 2), 0);
413 }
414}
415
416static int isif_config_dfc(struct isif_dfc *vdfc)
417{
418 /* initialize retries to loop for max ~ 250 usec */
419 u32 val, count, retries = loops_per_jiffy / (4000/HZ);
420 int i;
421
422 if (!vdfc->en)
423 return 0;
424
425 /* Correction mode */
426 val = (vdfc->corr_mode << ISIF_VDFC_CORR_MOD_SHIFT);
427
428 /* Correct whole line or partial */
429 if (vdfc->corr_whole_line)
430 val |= 1 << ISIF_VDFC_CORR_WHOLE_LN_SHIFT;
431
432 /* level shift value */
433 val |= vdfc->def_level_shift << ISIF_VDFC_LEVEL_SHFT_SHIFT;
434
435 regw(val, DFCCTL);
436
437 /* Defect saturation level */
438 regw(vdfc->def_sat_level, VDFSATLV);
439
440 regw(vdfc->table[0].pos_vert, DFCMEM0);
441 regw(vdfc->table[0].pos_horz, DFCMEM1);
442 if (vdfc->corr_mode == ISIF_VDFC_NORMAL ||
443 vdfc->corr_mode == ISIF_VDFC_HORZ_INTERPOL_IF_SAT) {
444 regw(vdfc->table[0].level_at_pos, DFCMEM2);
445 regw(vdfc->table[0].level_up_pixels, DFCMEM3);
446 regw(vdfc->table[0].level_low_pixels, DFCMEM4);
447 }
448
449 /* set DFCMARST and set DFCMWR */
450 val = regr(DFCMEMCTL) | (1 << ISIF_DFCMEMCTL_DFCMARST_SHIFT) | 1;
451 regw(val, DFCMEMCTL);
452
453 count = retries;
454 while (count && (regr(DFCMEMCTL) & 0x1))
455 count--;
456
457 if (!count) {
458 dev_dbg(isif_cfg.dev, "defect table write timeout !!!\n");
459 return -1;
460 }
461
462 for (i = 1; i < vdfc->num_vdefects; i++) {
463 regw(vdfc->table[i].pos_vert, DFCMEM0);
464 regw(vdfc->table[i].pos_horz, DFCMEM1);
465 if (vdfc->corr_mode == ISIF_VDFC_NORMAL ||
466 vdfc->corr_mode == ISIF_VDFC_HORZ_INTERPOL_IF_SAT) {
467 regw(vdfc->table[i].level_at_pos, DFCMEM2);
468 regw(vdfc->table[i].level_up_pixels, DFCMEM3);
469 regw(vdfc->table[i].level_low_pixels, DFCMEM4);
470 }
471 val = regr(DFCMEMCTL);
472 /* clear DFCMARST and set DFCMWR */
473 val &= ~BIT(ISIF_DFCMEMCTL_DFCMARST_SHIFT);
474 val |= 1;
475 regw(val, DFCMEMCTL);
476
477 count = retries;
478 while (count && (regr(DFCMEMCTL) & 0x1))
479 count--;
480
481 if (!count) {
482 dev_err(isif_cfg.dev,
483 "defect table write timeout !!!\n");
484 return -1;
485 }
486 }
487 if (vdfc->num_vdefects < ISIF_VDFC_TABLE_SIZE) {
488 /* Extra cycle needed */
489 regw(0, DFCMEM0);
490 regw(0x1FFF, DFCMEM1);
491 regw(1, DFCMEMCTL);
492 }
493
494 /* enable VDFC */
495 reg_modify((1 << ISIF_VDFC_EN_SHIFT), (1 << ISIF_VDFC_EN_SHIFT),
496 DFCCTL);
497 return 0;
498}
499
500static void isif_config_csc(struct isif_df_csc *df_csc)
501{
502 u32 val1 = 0, val2 = 0, i;
503
504 if (!df_csc->csc.en) {
505 regw(0, CSCCTL);
506 return;
507 }
508 for (i = 0; i < ISIF_CSC_NUM_COEFF; i++) {
509 if ((i % 2) == 0) {
510 /* CSCM - LSB */
511 val1 = (df_csc->csc.coeff[i].integer <<
512 ISIF_CSC_COEF_INTEG_SHIFT) |
513 df_csc->csc.coeff[i].decimal;
514 } else {
515
516 /* CSCM - MSB */
517 val2 = (df_csc->csc.coeff[i].integer <<
518 ISIF_CSC_COEF_INTEG_SHIFT) |
519 df_csc->csc.coeff[i].decimal;
520 val2 <<= ISIF_CSCM_MSB_SHIFT;
521 val2 |= val1;
522 regw(val2, (CSCM0 + ((i - 1) << 1)));
523 }
524 }
525
526 /* program the active area */
527 regw(df_csc->start_pix, FMTSPH);
528 /*
529 * one extra pixel as required for CSC. Actually number of
530 * pixel - 1 should be configured in this register. So we
531 * need to subtract 1 before writing to FMTSPH, but we will
532 * not do this since csc requires one extra pixel
533 */
534 regw(df_csc->num_pixels, FMTLNH);
535 regw(df_csc->start_line, FMTSLV);
536 /*
537 * one extra line as required for CSC. See reason documented for
538 * num_pixels
539 */
540 regw(df_csc->num_lines, FMTLNV);
541
542 /* Enable CSC */
543 regw(1, CSCCTL);
544}
545
546static int isif_config_raw(void)
547{
548 struct isif_params_raw *params = &isif_cfg.bayer;
549 struct isif_config_params_raw *module_params =
550 &isif_cfg.bayer.config_params;
551 struct vpss_pg_frame_size frame_size;
552 struct vpss_sync_pol sync;
553 u32 val;
554
555 dev_dbg(isif_cfg.dev, "\nStarting isif_config_raw..\n");
556
557 /*
558 * Configure CCDCFG register:-
559 * Set CCD Not to swap input since input is RAW data
560 * Set FID detection function to Latch at V-Sync
561 * Set WENLOG - isif valid area
562 * Set TRGSEL
563 * Set EXTRG
564 * Packed to 8 or 16 bits
565 */
566
567 val = ISIF_YCINSWP_RAW | ISIF_CCDCFG_FIDMD_LATCH_VSYNC |
568 ISIF_CCDCFG_WENLOG_AND | ISIF_CCDCFG_TRGSEL_WEN |
569 ISIF_CCDCFG_EXTRG_DISABLE | isif_cfg.data_pack;
570
571 dev_dbg(isif_cfg.dev, "Writing 0x%x to ...CCDCFG \n", val);
572 regw(val, CCDCFG);
573
574 /*
575 * Configure the vertical sync polarity(MODESET.VDPOL)
576 * Configure the horizontal sync polarity (MODESET.HDPOL)
577 * Configure frame id polarity (MODESET.FLDPOL)
578 * Configure data polarity
579 * Configure External WEN Selection
580 * Configure frame format(progressive or interlace)
581 * Configure pixel format (Input mode)
582 * Configure the data shift
583 */
584
585 val = ISIF_VDHDOUT_INPUT | (params->vd_pol << ISIF_VD_POL_SHIFT) |
586 (params->hd_pol << ISIF_HD_POL_SHIFT) |
587 (params->fid_pol << ISIF_FID_POL_SHIFT) |
588 (ISIF_DATAPOL_NORMAL << ISIF_DATAPOL_SHIFT) |
589 (ISIF_EXWEN_DISABLE << ISIF_EXWEN_SHIFT) |
590 (params->frm_fmt << ISIF_FRM_FMT_SHIFT) |
591 (params->pix_fmt << ISIF_INPUT_SHIFT) |
592 (params->config_params.data_shift << ISIF_DATASFT_SHIFT);
593
594 regw(val, MODESET);
595 dev_dbg(isif_cfg.dev, "Writing 0x%x to MODESET...\n", val);
596
597 /*
598 * Configure GAMMAWD register
599 * CFA pattern setting
600 */
601 val = params->cfa_pat << ISIF_GAMMAWD_CFA_SHIFT;
602
603 /* Gamma msb */
604 if (module_params->compress.alg == ISIF_ALAW)
605 val |= ISIF_ALAW_ENABLE;
606
607 val |= (params->data_msb << ISIF_ALAW_GAMA_WD_SHIFT);
608 regw(val, CGAMMAWD);
609
610 /* Configure DPCM compression settings */
611 if (module_params->compress.alg == ISIF_DPCM) {
612 val = BIT(ISIF_DPCM_EN_SHIFT) |
613 (module_params->compress.pred <<
614 ISIF_DPCM_PREDICTOR_SHIFT);
615 }
616
617 regw(val, MISC);
618
619 /* Configure Gain & Offset */
620 isif_config_gain_offset();
621
622 /* Configure Color pattern */
623 val = (params->config_params.col_pat_field0.olop) |
624 (params->config_params.col_pat_field0.olep << 2) |
625 (params->config_params.col_pat_field0.elop << 4) |
626 (params->config_params.col_pat_field0.elep << 6) |
627 (params->config_params.col_pat_field1.olop << 8) |
628 (params->config_params.col_pat_field1.olep << 10) |
629 (params->config_params.col_pat_field1.elop << 12) |
630 (params->config_params.col_pat_field1.elep << 14);
631 regw(val, CCOLP);
632 dev_dbg(isif_cfg.dev, "Writing %x to CCOLP ...\n", val);
633
634 /* Configure HSIZE register */
635 val = (!!params->horz_flip_en) << ISIF_HSIZE_FLIP_SHIFT;
636
637 /* calculate line offset in 32 bytes based on pack value */
638 if (isif_cfg.data_pack == ISIF_PACK_8BIT)
639 val |= ((params->win.width + 31) >> 5);
640 else if (isif_cfg.data_pack == ISIF_PACK_12BIT)
641 val |= (((params->win.width +
642 (params->win.width >> 2)) + 31) >> 5);
643 else
644 val |= (((params->win.width * 2) + 31) >> 5);
645 regw(val, HSIZE);
646
647 /* Configure SDOFST register */
648 if (params->frm_fmt == CCDC_FRMFMT_INTERLACED) {
649 if (params->image_invert_en) {
650 /* For interlace inverse mode */
651 regw(0x4B6D, SDOFST);
652 dev_dbg(isif_cfg.dev, "Writing 0x4B6D to SDOFST...\n");
653 } else {
654 /* For interlace non inverse mode */
655 regw(0x0B6D, SDOFST);
656 dev_dbg(isif_cfg.dev, "Writing 0x0B6D to SDOFST...\n");
657 }
658 } else if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE) {
659 if (params->image_invert_en) {
660 /* For progressive inverse mode */
661 regw(0x4000, SDOFST);
662 dev_dbg(isif_cfg.dev, "Writing 0x4000 to SDOFST...\n");
663 } else {
664 /* For progressive non inverse mode */
665 regw(0x0000, SDOFST);
666 dev_dbg(isif_cfg.dev, "Writing 0x0000 to SDOFST...\n");
667 }
668 }
669
670 /* Configure video window */
671 isif_setwin(&params->win, params->frm_fmt, 1);
672
673 /* Configure Black Clamp */
674 isif_config_bclamp(&module_params->bclamp);
675
676 /* Configure Vertical Defection Pixel Correction */
677 if (isif_config_dfc(&module_params->dfc) < 0)
678 return -EFAULT;
679
680 if (!module_params->df_csc.df_or_csc)
681 /* Configure Color Space Conversion */
682 isif_config_csc(&module_params->df_csc);
683
684 isif_config_linearization(&module_params->linearize);
685
686 /* Configure Culling */
687 isif_config_culling(&module_params->culling);
688
689 /* Configure horizontal and vertical offsets(DFC,LSC,Gain) */
690 regw(module_params->horz_offset, DATAHOFST);
691 regw(module_params->vert_offset, DATAVOFST);
692
693 /* Setup test pattern if enabled */
694 if (params->config_params.test_pat_gen) {
695 /* Use the HD/VD pol settings from user */
696 sync.ccdpg_hdpol = params->hd_pol;
697 sync.ccdpg_vdpol = params->vd_pol;
698 dm365_vpss_set_sync_pol(sync);
699 frame_size.hlpfr = isif_cfg.bayer.win.width;
700 frame_size.pplen = isif_cfg.bayer.win.height;
701 dm365_vpss_set_pg_frame_size(frame_size);
702 vpss_select_ccdc_source(VPSS_PGLPBK);
703 }
704
705 dev_dbg(isif_cfg.dev, "\nEnd of isif_config_ycbcr...\n");
706 return 0;
707}
708
709static int isif_set_buftype(enum ccdc_buftype buf_type)
710{
711 if (isif_cfg.if_type == VPFE_RAW_BAYER)
712 isif_cfg.bayer.buf_type = buf_type;
713 else
714 isif_cfg.ycbcr.buf_type = buf_type;
715
716 return 0;
717
718}
719static enum ccdc_buftype isif_get_buftype(void)
720{
721 if (isif_cfg.if_type == VPFE_RAW_BAYER)
722 return isif_cfg.bayer.buf_type;
723
724 return isif_cfg.ycbcr.buf_type;
725}
726
727static int isif_enum_pix(u32 *pix, int i)
728{
729 int ret = -EINVAL;
730
731 if (isif_cfg.if_type == VPFE_RAW_BAYER) {
732 if (i < ARRAY_SIZE(isif_raw_bayer_pix_formats)) {
733 *pix = isif_raw_bayer_pix_formats[i];
734 ret = 0;
735 }
736 } else {
737 if (i < ARRAY_SIZE(isif_raw_yuv_pix_formats)) {
738 *pix = isif_raw_yuv_pix_formats[i];
739 ret = 0;
740 }
741 }
742
743 return ret;
744}
745
746static int isif_set_pixel_format(unsigned int pixfmt)
747{
748 if (isif_cfg.if_type == VPFE_RAW_BAYER) {
749 if (pixfmt == V4L2_PIX_FMT_SBGGR8) {
750 if ((isif_cfg.bayer.config_params.compress.alg !=
751 ISIF_ALAW) &&
752 (isif_cfg.bayer.config_params.compress.alg !=
753 ISIF_DPCM)) {
754 dev_dbg(isif_cfg.dev,
755 "Either configure A-Law or DPCM\n");
756 return -EINVAL;
757 }
758 isif_cfg.data_pack = ISIF_PACK_8BIT;
759 } else if (pixfmt == V4L2_PIX_FMT_SBGGR16) {
760 isif_cfg.bayer.config_params.compress.alg =
761 ISIF_NO_COMPRESSION;
762 isif_cfg.data_pack = ISIF_PACK_16BIT;
763 } else
764 return -EINVAL;
765 isif_cfg.bayer.pix_fmt = CCDC_PIXFMT_RAW;
766 } else {
767 if (pixfmt == V4L2_PIX_FMT_YUYV)
768 isif_cfg.ycbcr.pix_order = CCDC_PIXORDER_YCBYCR;
769 else if (pixfmt == V4L2_PIX_FMT_UYVY)
770 isif_cfg.ycbcr.pix_order = CCDC_PIXORDER_CBYCRY;
771 else
772 return -EINVAL;
773 isif_cfg.data_pack = ISIF_PACK_8BIT;
774 }
775 return 0;
776}
777
778static u32 isif_get_pixel_format(void)
779{
780 u32 pixfmt;
781
782 if (isif_cfg.if_type == VPFE_RAW_BAYER)
783 if (isif_cfg.bayer.config_params.compress.alg == ISIF_ALAW ||
784 isif_cfg.bayer.config_params.compress.alg == ISIF_DPCM)
785 pixfmt = V4L2_PIX_FMT_SBGGR8;
786 else
787 pixfmt = V4L2_PIX_FMT_SBGGR16;
788 else {
789 if (isif_cfg.ycbcr.pix_order == CCDC_PIXORDER_YCBYCR)
790 pixfmt = V4L2_PIX_FMT_YUYV;
791 else
792 pixfmt = V4L2_PIX_FMT_UYVY;
793 }
794 return pixfmt;
795}
796
797static int isif_set_image_window(struct v4l2_rect *win)
798{
799 if (isif_cfg.if_type == VPFE_RAW_BAYER) {
800 isif_cfg.bayer.win.top = win->top;
801 isif_cfg.bayer.win.left = win->left;
802 isif_cfg.bayer.win.width = win->width;
803 isif_cfg.bayer.win.height = win->height;
804 } else {
805 isif_cfg.ycbcr.win.top = win->top;
806 isif_cfg.ycbcr.win.left = win->left;
807 isif_cfg.ycbcr.win.width = win->width;
808 isif_cfg.ycbcr.win.height = win->height;
809 }
810 return 0;
811}
812
813static void isif_get_image_window(struct v4l2_rect *win)
814{
815 if (isif_cfg.if_type == VPFE_RAW_BAYER)
816 *win = isif_cfg.bayer.win;
817 else
818 *win = isif_cfg.ycbcr.win;
819}
820
821static unsigned int isif_get_line_length(void)
822{
823 unsigned int len;
824
825 if (isif_cfg.if_type == VPFE_RAW_BAYER) {
826 if (isif_cfg.data_pack == ISIF_PACK_8BIT)
827 len = ((isif_cfg.bayer.win.width));
828 else if (isif_cfg.data_pack == ISIF_PACK_12BIT)
829 len = (((isif_cfg.bayer.win.width * 2) +
830 (isif_cfg.bayer.win.width >> 2)));
831 else
832 len = (((isif_cfg.bayer.win.width * 2)));
833 } else
834 len = (((isif_cfg.ycbcr.win.width * 2)));
835 return ALIGN(len, 32);
836}
837
838static int isif_set_frame_format(enum ccdc_frmfmt frm_fmt)
839{
840 if (isif_cfg.if_type == VPFE_RAW_BAYER)
841 isif_cfg.bayer.frm_fmt = frm_fmt;
842 else
843 isif_cfg.ycbcr.frm_fmt = frm_fmt;
844 return 0;
845}
846static enum ccdc_frmfmt isif_get_frame_format(void)
847{
848 if (isif_cfg.if_type == VPFE_RAW_BAYER)
849 return isif_cfg.bayer.frm_fmt;
850 return isif_cfg.ycbcr.frm_fmt;
851}
852
853static int isif_getfid(void)
854{
855 return (regr(MODESET) >> 15) & 0x1;
856}
857
858/* misc operations */
859static void isif_setfbaddr(unsigned long addr)
860{
861 regw((addr >> 21) & 0x07ff, CADU);
862 regw((addr >> 5) & 0x0ffff, CADL);
863}
864
865static int isif_set_hw_if_params(struct vpfe_hw_if_param *params)
866{
867 isif_cfg.if_type = params->if_type;
868
869 switch (params->if_type) {
870 case VPFE_BT656:
871 case VPFE_BT656_10BIT:
872 case VPFE_YCBCR_SYNC_8:
873 isif_cfg.ycbcr.pix_fmt = CCDC_PIXFMT_YCBCR_8BIT;
874 isif_cfg.ycbcr.pix_order = CCDC_PIXORDER_CBYCRY;
875 break;
876 case VPFE_BT1120:
877 case VPFE_YCBCR_SYNC_16:
878 isif_cfg.ycbcr.pix_fmt = CCDC_PIXFMT_YCBCR_16BIT;
879 isif_cfg.ycbcr.pix_order = CCDC_PIXORDER_CBYCRY;
880 break;
881 case VPFE_RAW_BAYER:
882 isif_cfg.bayer.pix_fmt = CCDC_PIXFMT_RAW;
883 break;
884 default:
885 dev_dbg(isif_cfg.dev, "Invalid interface type\n");
886 return -EINVAL;
887 }
888
889 return 0;
890}
891
892/* This function will configure ISIF for YCbCr parameters. */
893static int isif_config_ycbcr(void)
894{
895 struct isif_ycbcr_config *params = &isif_cfg.ycbcr;
896 struct vpss_pg_frame_size frame_size;
897 u32 modeset = 0, ccdcfg = 0;
898 struct vpss_sync_pol sync;
899
900 dev_dbg(isif_cfg.dev, "\nStarting isif_config_ycbcr...");
901
902 /* configure pixel format or input mode */
903 modeset = modeset | (params->pix_fmt << ISIF_INPUT_SHIFT) |
904 (params->frm_fmt << ISIF_FRM_FMT_SHIFT) |
905 (params->fid_pol << ISIF_FID_POL_SHIFT) |
906 (params->hd_pol << ISIF_HD_POL_SHIFT) |
907 (params->vd_pol << ISIF_VD_POL_SHIFT);
908
909 /* pack the data to 8-bit ISIFCFG */
910 switch (isif_cfg.if_type) {
911 case VPFE_BT656:
912 if (params->pix_fmt != CCDC_PIXFMT_YCBCR_8BIT) {
913 dev_dbg(isif_cfg.dev, "Invalid pix_fmt(input mode)\n");
914 return -EINVAL;
915 }
916 modeset |= (VPFE_PINPOL_NEGATIVE << ISIF_VD_POL_SHIFT);
917 regw(3, REC656IF);
918 ccdcfg = ccdcfg | ISIF_DATA_PACK8 | ISIF_YCINSWP_YCBCR;
919 break;
920 case VPFE_BT656_10BIT:
921 if (params->pix_fmt != CCDC_PIXFMT_YCBCR_8BIT) {
922 dev_dbg(isif_cfg.dev, "Invalid pix_fmt(input mode)\n");
923 return -EINVAL;
924 }
925 /* setup BT.656, embedded sync */
926 regw(3, REC656IF);
927 /* enable 10 bit mode in ccdcfg */
928 ccdcfg = ccdcfg | ISIF_DATA_PACK8 | ISIF_YCINSWP_YCBCR |
929 ISIF_BW656_ENABLE;
930 break;
931 case VPFE_BT1120:
932 if (params->pix_fmt != CCDC_PIXFMT_YCBCR_16BIT) {
933 dev_dbg(isif_cfg.dev, "Invalid pix_fmt(input mode)\n");
934 return -EINVAL;
935 }
936 regw(3, REC656IF);
937 break;
938
939 case VPFE_YCBCR_SYNC_8:
940 ccdcfg |= ISIF_DATA_PACK8;
941 ccdcfg |= ISIF_YCINSWP_YCBCR;
942 if (params->pix_fmt != CCDC_PIXFMT_YCBCR_8BIT) {
943 dev_dbg(isif_cfg.dev, "Invalid pix_fmt(input mode)\n");
944 return -EINVAL;
945 }
946 break;
947 case VPFE_YCBCR_SYNC_16:
948 if (params->pix_fmt != CCDC_PIXFMT_YCBCR_16BIT) {
949 dev_dbg(isif_cfg.dev, "Invalid pix_fmt(input mode)\n");
950 return -EINVAL;
951 }
952 break;
953 default:
954 /* should never come here */
955 dev_dbg(isif_cfg.dev, "Invalid interface type\n");
956 return -EINVAL;
957 }
958
959 regw(modeset, MODESET);
960
961 /* Set up pix order */
962 ccdcfg |= params->pix_order << ISIF_PIX_ORDER_SHIFT;
963
964 regw(ccdcfg, CCDCFG);
965
966 /* configure video window */
967 if ((isif_cfg.if_type == VPFE_BT1120) ||
968 (isif_cfg.if_type == VPFE_YCBCR_SYNC_16))
969 isif_setwin(&params->win, params->frm_fmt, 1);
970 else
971 isif_setwin(&params->win, params->frm_fmt, 2);
972
973 /*
974 * configure the horizontal line offset
975 * this is done by rounding up width to a multiple of 16 pixels
976 * and multiply by two to account for y:cb:cr 4:2:2 data
977 */
978 regw(((((params->win.width * 2) + 31) & 0xffffffe0) >> 5), HSIZE);
979
980 /* configure the memory line offset */
981 if ((params->frm_fmt == CCDC_FRMFMT_INTERLACED) &&
982 (params->buf_type == CCDC_BUFTYPE_FLD_INTERLEAVED))
983 /* two fields are interleaved in memory */
984 regw(0x00000249, SDOFST);
985
986 /* Setup test pattern if enabled */
987 if (isif_cfg.bayer.config_params.test_pat_gen) {
988 sync.ccdpg_hdpol = params->hd_pol;
989 sync.ccdpg_vdpol = params->vd_pol;
990 dm365_vpss_set_sync_pol(sync);
991 dm365_vpss_set_pg_frame_size(frame_size);
992 }
993 return 0;
994}
995
996static int isif_configure(void)
997{
998 if (isif_cfg.if_type == VPFE_RAW_BAYER)
999 return isif_config_raw();
1000 return isif_config_ycbcr();
1001}
1002
1003static int isif_close(struct device *device)
1004{
1005 /* copy defaults to module params */
1006 isif_cfg.bayer.config_params = isif_config_defaults;
1007 return 0;
1008}
1009
1010static struct ccdc_hw_device isif_hw_dev = {
1011 .name = "ISIF",
1012 .owner = THIS_MODULE,
1013 .hw_ops = {
1014 .open = isif_open,
1015 .close = isif_close,
1016 .enable = isif_enable,
1017 .enable_out_to_sdram = isif_enable_output_to_sdram,
1018 .set_hw_if_params = isif_set_hw_if_params,
1019 .configure = isif_configure,
1020 .set_buftype = isif_set_buftype,
1021 .get_buftype = isif_get_buftype,
1022 .enum_pix = isif_enum_pix,
1023 .set_pixel_format = isif_set_pixel_format,
1024 .get_pixel_format = isif_get_pixel_format,
1025 .set_frame_format = isif_set_frame_format,
1026 .get_frame_format = isif_get_frame_format,
1027 .set_image_window = isif_set_image_window,
1028 .get_image_window = isif_get_image_window,
1029 .get_line_length = isif_get_line_length,
1030 .setfbaddr = isif_setfbaddr,
1031 .getfid = isif_getfid,
1032 },
1033};
1034
1035static int __devinit isif_probe(struct platform_device *pdev)
1036{
1037 void (*setup_pinmux)(void);
1038 struct resource *res;
1039 void *__iomem addr;
1040 int status = 0, i;
1041
1042 /*
1043 * first try to register with vpfe. If not correct platform, then we
1044 * don't have to iomap
1045 */
1046 status = vpfe_register_ccdc_device(&isif_hw_dev);
1047 if (status < 0)
1048 return status;
1049
1050 /* Get and enable Master clock */
1051 isif_cfg.mclk = clk_get(&pdev->dev, "master");
1052 if (IS_ERR(isif_cfg.mclk)) {
1053 status = PTR_ERR(isif_cfg.mclk);
1054 goto fail_mclk;
1055 }
1056 if (clk_enable(isif_cfg.mclk)) {
1057 status = -ENODEV;
1058 goto fail_mclk;
1059 }
1060
1061 /* Platform data holds setup_pinmux function ptr */
1062 if (NULL == pdev->dev.platform_data) {
1063 status = -ENODEV;
1064 goto fail_mclk;
1065 }
1066 setup_pinmux = pdev->dev.platform_data;
1067 /*
1068 * setup Mux configuration for ccdc which may be different for
1069 * different SoCs using this CCDC
1070 */
1071 setup_pinmux();
1072
1073 i = 0;
1074 /* Get the ISIF base address, linearization table0 and table1 addr. */
1075 while (i < 3) {
1076 res = platform_get_resource(pdev, IORESOURCE_MEM, i);
1077 if (!res) {
1078 status = -ENODEV;
1079 goto fail_nobase_res;
1080 }
1081 res = request_mem_region(res->start, resource_size(res),
1082 res->name);
1083 if (!res) {
1084 status = -EBUSY;
1085 goto fail_nobase_res;
1086 }
1087 addr = ioremap_nocache(res->start, resource_size(res));
1088 if (!addr) {
1089 status = -ENOMEM;
1090 goto fail_base_iomap;
1091 }
1092 switch (i) {
1093 case 0:
1094 /* ISIF base address */
1095 isif_cfg.base_addr = addr;
1096 break;
1097 case 1:
1098 /* ISIF linear tbl0 address */
1099 isif_cfg.linear_tbl0_addr = addr;
1100 break;
1101 default:
1102 /* ISIF linear tbl0 address */
1103 isif_cfg.linear_tbl1_addr = addr;
1104 break;
1105 }
1106 i++;
1107 }
1108 isif_cfg.dev = &pdev->dev;
1109
1110 printk(KERN_NOTICE "%s is registered with vpfe.\n",
1111 isif_hw_dev.name);
1112 return 0;
1113fail_base_iomap:
1114 release_mem_region(res->start, resource_size(res));
1115 i--;
1116fail_nobase_res:
1117 if (isif_cfg.base_addr)
1118 iounmap(isif_cfg.base_addr);
1119 if (isif_cfg.linear_tbl0_addr)
1120 iounmap(isif_cfg.linear_tbl0_addr);
1121
1122 while (i >= 0) {
1123 res = platform_get_resource(pdev, IORESOURCE_MEM, i);
1124 release_mem_region(res->start, resource_size(res));
1125 i--;
1126 }
1127fail_mclk:
1128 clk_put(isif_cfg.mclk);
1129 vpfe_unregister_ccdc_device(&isif_hw_dev);
1130 return status;
1131}
1132
1133static int isif_remove(struct platform_device *pdev)
1134{
1135 struct resource *res;
1136 int i = 0;
1137
1138 iounmap(isif_cfg.base_addr);
1139 iounmap(isif_cfg.linear_tbl0_addr);
1140 iounmap(isif_cfg.linear_tbl1_addr);
1141 while (i < 3) {
1142 res = platform_get_resource(pdev, IORESOURCE_MEM, i);
1143 if (res)
1144 release_mem_region(res->start, resource_size(res));
1145 i++;
1146 }
1147 vpfe_unregister_ccdc_device(&isif_hw_dev);
1148 return 0;
1149}
1150
1151static struct platform_driver isif_driver = {
1152 .driver = {
1153 .name = "isif",
1154 .owner = THIS_MODULE,
1155 },
1156 .remove = __devexit_p(isif_remove),
1157 .probe = isif_probe,
1158};
1159
1160module_platform_driver(isif_driver);
1161
1162MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/davinci/isif_regs.h b/drivers/media/video/davinci/isif_regs.h
deleted file mode 100644
index aa69a463c122..000000000000
--- a/drivers/media/video/davinci/isif_regs.h
+++ /dev/null
@@ -1,269 +0,0 @@
1/*
2 * Copyright (C) 2008-2009 Texas Instruments Inc
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18#ifndef _ISIF_REGS_H
19#define _ISIF_REGS_H
20
21/* ISIF registers relative offsets */
22#define SYNCEN 0x00
23#define MODESET 0x04
24#define HDW 0x08
25#define VDW 0x0c
26#define PPLN 0x10
27#define LPFR 0x14
28#define SPH 0x18
29#define LNH 0x1c
30#define SLV0 0x20
31#define SLV1 0x24
32#define LNV 0x28
33#define CULH 0x2c
34#define CULV 0x30
35#define HSIZE 0x34
36#define SDOFST 0x38
37#define CADU 0x3c
38#define CADL 0x40
39#define LINCFG0 0x44
40#define LINCFG1 0x48
41#define CCOLP 0x4c
42#define CRGAIN 0x50
43#define CGRGAIN 0x54
44#define CGBGAIN 0x58
45#define CBGAIN 0x5c
46#define COFSTA 0x60
47#define FLSHCFG0 0x64
48#define FLSHCFG1 0x68
49#define FLSHCFG2 0x6c
50#define VDINT0 0x70
51#define VDINT1 0x74
52#define VDINT2 0x78
53#define MISC 0x7c
54#define CGAMMAWD 0x80
55#define REC656IF 0x84
56#define CCDCFG 0x88
57/*****************************************************
58* Defect Correction registers
59*****************************************************/
60#define DFCCTL 0x8c
61#define VDFSATLV 0x90
62#define DFCMEMCTL 0x94
63#define DFCMEM0 0x98
64#define DFCMEM1 0x9c
65#define DFCMEM2 0xa0
66#define DFCMEM3 0xa4
67#define DFCMEM4 0xa8
68/****************************************************
69* Black Clamp registers
70****************************************************/
71#define CLAMPCFG 0xac
72#define CLDCOFST 0xb0
73#define CLSV 0xb4
74#define CLHWIN0 0xb8
75#define CLHWIN1 0xbc
76#define CLHWIN2 0xc0
77#define CLVRV 0xc4
78#define CLVWIN0 0xc8
79#define CLVWIN1 0xcc
80#define CLVWIN2 0xd0
81#define CLVWIN3 0xd4
82/****************************************************
83* Lense Shading Correction
84****************************************************/
85#define DATAHOFST 0xd8
86#define DATAVOFST 0xdc
87#define LSCHVAL 0xe0
88#define LSCVVAL 0xe4
89#define TWODLSCCFG 0xe8
90#define TWODLSCOFST 0xec
91#define TWODLSCINI 0xf0
92#define TWODLSCGRBU 0xf4
93#define TWODLSCGRBL 0xf8
94#define TWODLSCGROF 0xfc
95#define TWODLSCORBU 0x100
96#define TWODLSCORBL 0x104
97#define TWODLSCOROF 0x108
98#define TWODLSCIRQEN 0x10c
99#define TWODLSCIRQST 0x110
100/****************************************************
101* Data formatter
102****************************************************/
103#define FMTCFG 0x114
104#define FMTPLEN 0x118
105#define FMTSPH 0x11c
106#define FMTLNH 0x120
107#define FMTSLV 0x124
108#define FMTLNV 0x128
109#define FMTRLEN 0x12c
110#define FMTHCNT 0x130
111#define FMTAPTR_BASE 0x134
112/* Below macro for addresses FMTAPTR0 - FMTAPTR15 */
113#define FMTAPTR(i) (FMTAPTR_BASE + (i * 4))
114#define FMTPGMVF0 0x174
115#define FMTPGMVF1 0x178
116#define FMTPGMAPU0 0x17c
117#define FMTPGMAPU1 0x180
118#define FMTPGMAPS0 0x184
119#define FMTPGMAPS1 0x188
120#define FMTPGMAPS2 0x18c
121#define FMTPGMAPS3 0x190
122#define FMTPGMAPS4 0x194
123#define FMTPGMAPS5 0x198
124#define FMTPGMAPS6 0x19c
125#define FMTPGMAPS7 0x1a0
126/************************************************
127* Color Space Converter
128************************************************/
129#define CSCCTL 0x1a4
130#define CSCM0 0x1a8
131#define CSCM1 0x1ac
132#define CSCM2 0x1b0
133#define CSCM3 0x1b4
134#define CSCM4 0x1b8
135#define CSCM5 0x1bc
136#define CSCM6 0x1c0
137#define CSCM7 0x1c4
138#define OBWIN0 0x1c8
139#define OBWIN1 0x1cc
140#define OBWIN2 0x1d0
141#define OBWIN3 0x1d4
142#define OBVAL0 0x1d8
143#define OBVAL1 0x1dc
144#define OBVAL2 0x1e0
145#define OBVAL3 0x1e4
146#define OBVAL4 0x1e8
147#define OBVAL5 0x1ec
148#define OBVAL6 0x1f0
149#define OBVAL7 0x1f4
150#define CLKCTL 0x1f8
151
152/* Masks & Shifts below */
153#define START_PX_HOR_MASK 0x7FFF
154#define NUM_PX_HOR_MASK 0x7FFF
155#define START_VER_ONE_MASK 0x7FFF
156#define START_VER_TWO_MASK 0x7FFF
157#define NUM_LINES_VER 0x7FFF
158
159/* gain - offset masks */
160#define GAIN_INTEGER_SHIFT 9
161#define OFFSET_MASK 0xFFF
162#define GAIN_SDRAM_EN_SHIFT 12
163#define GAIN_IPIPE_EN_SHIFT 13
164#define GAIN_H3A_EN_SHIFT 14
165#define OFST_SDRAM_EN_SHIFT 8
166#define OFST_IPIPE_EN_SHIFT 9
167#define OFST_H3A_EN_SHIFT 10
168#define GAIN_OFFSET_EN_MASK 0x7700
169
170/* Culling */
171#define CULL_PAT_EVEN_LINE_SHIFT 8
172
173/* CCDCFG register */
174#define ISIF_YCINSWP_RAW (0x00 << 4)
175#define ISIF_YCINSWP_YCBCR (0x01 << 4)
176#define ISIF_CCDCFG_FIDMD_LATCH_VSYNC (0x00 << 6)
177#define ISIF_CCDCFG_WENLOG_AND (0x00 << 8)
178#define ISIF_CCDCFG_TRGSEL_WEN (0x00 << 9)
179#define ISIF_CCDCFG_EXTRG_DISABLE (0x00 << 10)
180#define ISIF_LATCH_ON_VSYNC_DISABLE (0x01 << 15)
181#define ISIF_LATCH_ON_VSYNC_ENABLE (0x00 << 15)
182#define ISIF_DATA_PACK_MASK 3
183#define ISIF_DATA_PACK16 0
184#define ISIF_DATA_PACK12 1
185#define ISIF_DATA_PACK8 2
186#define ISIF_PIX_ORDER_SHIFT 11
187#define ISIF_BW656_ENABLE (0x01 << 5)
188
189/* MODESET registers */
190#define ISIF_VDHDOUT_INPUT (0x00 << 0)
191#define ISIF_INPUT_SHIFT 12
192#define ISIF_RAW_INPUT_MODE 0
193#define ISIF_FID_POL_SHIFT 4
194#define ISIF_HD_POL_SHIFT 3
195#define ISIF_VD_POL_SHIFT 2
196#define ISIF_DATAPOL_NORMAL 0
197#define ISIF_DATAPOL_SHIFT 6
198#define ISIF_EXWEN_DISABLE 0
199#define ISIF_EXWEN_SHIFT 5
200#define ISIF_FRM_FMT_SHIFT 7
201#define ISIF_DATASFT_SHIFT 8
202#define ISIF_LPF_SHIFT 14
203#define ISIF_LPF_MASK 1
204
205/* GAMMAWD registers */
206#define ISIF_ALAW_GAMA_WD_MASK 0xF
207#define ISIF_ALAW_GAMA_WD_SHIFT 1
208#define ISIF_ALAW_ENABLE 1
209#define ISIF_GAMMAWD_CFA_SHIFT 5
210
211/* HSIZE registers */
212#define ISIF_HSIZE_FLIP_MASK 1
213#define ISIF_HSIZE_FLIP_SHIFT 12
214
215/* MISC registers */
216#define ISIF_DPCM_EN_SHIFT 12
217#define ISIF_DPCM_PREDICTOR_SHIFT 13
218
219/* Black clamp related */
220#define ISIF_BC_MODE_COLOR_SHIFT 4
221#define ISIF_HORZ_BC_MODE_SHIFT 1
222#define ISIF_HORZ_BC_WIN_SEL_SHIFT 5
223#define ISIF_HORZ_BC_PIX_LIMIT_SHIFT 6
224#define ISIF_HORZ_BC_WIN_H_SIZE_SHIFT 8
225#define ISIF_HORZ_BC_WIN_V_SIZE_SHIFT 12
226#define ISIF_VERT_BC_RST_VAL_SEL_SHIFT 4
227#define ISIF_VERT_BC_LINE_AVE_COEF_SHIFT 8
228
229/* VDFC registers */
230#define ISIF_VDFC_EN_SHIFT 4
231#define ISIF_VDFC_CORR_MOD_SHIFT 5
232#define ISIF_VDFC_CORR_WHOLE_LN_SHIFT 7
233#define ISIF_VDFC_LEVEL_SHFT_SHIFT 8
234#define ISIF_VDFC_POS_MASK 0x1FFF
235#define ISIF_DFCMEMCTL_DFCMARST_SHIFT 2
236
237/* CSC registers */
238#define ISIF_CSC_COEF_INTEG_MASK 7
239#define ISIF_CSC_COEF_DECIMAL_MASK 0x1f
240#define ISIF_CSC_COEF_INTEG_SHIFT 5
241#define ISIF_CSCM_MSB_SHIFT 8
242#define ISIF_DF_CSC_SPH_MASK 0x1FFF
243#define ISIF_DF_CSC_LNH_MASK 0x1FFF
244#define ISIF_DF_CSC_SLV_MASK 0x1FFF
245#define ISIF_DF_CSC_LNV_MASK 0x1FFF
246#define ISIF_DF_NUMLINES 0x7FFF
247#define ISIF_DF_NUMPIX 0x1FFF
248
249/* Offsets for LSC/DFC/Gain */
250#define ISIF_DATA_H_OFFSET_MASK 0x1FFF
251#define ISIF_DATA_V_OFFSET_MASK 0x1FFF
252
253/* Linearization */
254#define ISIF_LIN_CORRSFT_SHIFT 4
255#define ISIF_LIN_SCALE_FACT_INTEG_SHIFT 10
256
257
258/* Pattern registers */
259#define ISIF_PG_EN (1 << 3)
260#define ISIF_SEL_PG_SRC (3 << 4)
261#define ISIF_PG_VD_POL_SHIFT 0
262#define ISIF_PG_HD_POL_SHIFT 1
263
264/*random other junk*/
265#define ISIF_SYNCEN_VDHDEN_MASK (1 << 0)
266#define ISIF_SYNCEN_WEN_MASK (1 << 1)
267#define ISIF_SYNCEN_WEN_SHIFT 1
268
269#endif
diff --git a/drivers/media/video/davinci/vpbe.c b/drivers/media/video/davinci/vpbe.c
deleted file mode 100644
index c4a82a1a8a97..000000000000
--- a/drivers/media/video/davinci/vpbe.c
+++ /dev/null
@@ -1,886 +0,0 @@
1/*
2 * Copyright (C) 2010 Texas Instruments Inc
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation version 2.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 */
17#include <linux/kernel.h>
18#include <linux/init.h>
19#include <linux/module.h>
20#include <linux/errno.h>
21#include <linux/fs.h>
22#include <linux/string.h>
23#include <linux/wait.h>
24#include <linux/time.h>
25#include <linux/platform_device.h>
26#include <linux/io.h>
27#include <linux/slab.h>
28#include <linux/clk.h>
29#include <linux/err.h>
30
31#include <media/v4l2-device.h>
32#include <media/davinci/vpbe_types.h>
33#include <media/davinci/vpbe.h>
34#include <media/davinci/vpss.h>
35#include <media/davinci/vpbe_venc.h>
36
37#define VPBE_DEFAULT_OUTPUT "Composite"
38#define VPBE_DEFAULT_MODE "ntsc"
39
40static char *def_output = VPBE_DEFAULT_OUTPUT;
41static char *def_mode = VPBE_DEFAULT_MODE;
42static int debug;
43
44module_param(def_output, charp, S_IRUGO);
45module_param(def_mode, charp, S_IRUGO);
46module_param(debug, int, 0644);
47
48MODULE_PARM_DESC(def_output, "vpbe output name (default:Composite)");
49MODULE_PARM_DESC(def_mode, "vpbe output mode name (default:ntsc");
50MODULE_PARM_DESC(debug, "Debug level 0-1");
51
52MODULE_DESCRIPTION("TI DMXXX VPBE Display controller");
53MODULE_LICENSE("GPL");
54MODULE_AUTHOR("Texas Instruments");
55
56/**
57 * vpbe_current_encoder_info - Get config info for current encoder
58 * @vpbe_dev - vpbe device ptr
59 *
60 * Return ptr to current encoder config info
61 */
62static struct encoder_config_info*
63vpbe_current_encoder_info(struct vpbe_device *vpbe_dev)
64{
65 struct vpbe_config *cfg = vpbe_dev->cfg;
66 int index = vpbe_dev->current_sd_index;
67
68 return ((index == 0) ? &cfg->venc :
69 &cfg->ext_encoders[index-1]);
70}
71
72/**
73 * vpbe_find_encoder_sd_index - Given a name find encoder sd index
74 *
75 * @vpbe_config - ptr to vpbe cfg
76 * @output_index - index used by application
77 *
78 * Return sd index of the encoder
79 */
80static int vpbe_find_encoder_sd_index(struct vpbe_config *cfg,
81 int index)
82{
83 char *encoder_name = cfg->outputs[index].subdev_name;
84 int i;
85
86 /* Venc is always first */
87 if (!strcmp(encoder_name, cfg->venc.module_name))
88 return 0;
89
90 for (i = 0; i < cfg->num_ext_encoders; i++) {
91 if (!strcmp(encoder_name,
92 cfg->ext_encoders[i].module_name))
93 return i+1;
94 }
95
96 return -EINVAL;
97}
98
99/**
100 * vpbe_g_cropcap - Get crop capabilities of the display
101 * @vpbe_dev - vpbe device ptr
102 * @cropcap - cropcap is a ptr to struct v4l2_cropcap
103 *
104 * Update the crop capabilities in crop cap for current
105 * mode
106 */
107static int vpbe_g_cropcap(struct vpbe_device *vpbe_dev,
108 struct v4l2_cropcap *cropcap)
109{
110 if (NULL == cropcap)
111 return -EINVAL;
112 cropcap->bounds.left = 0;
113 cropcap->bounds.top = 0;
114 cropcap->bounds.width = vpbe_dev->current_timings.xres;
115 cropcap->bounds.height = vpbe_dev->current_timings.yres;
116 cropcap->defrect = cropcap->bounds;
117
118 return 0;
119}
120
121/**
122 * vpbe_enum_outputs - enumerate outputs
123 * @vpbe_dev - vpbe device ptr
124 * @output - ptr to v4l2_output structure
125 *
126 * Enumerates the outputs available at the vpbe display
127 * returns the status, -EINVAL if end of output list
128 */
129static int vpbe_enum_outputs(struct vpbe_device *vpbe_dev,
130 struct v4l2_output *output)
131{
132 struct vpbe_config *cfg = vpbe_dev->cfg;
133 int temp_index = output->index;
134
135 if (temp_index >= cfg->num_outputs)
136 return -EINVAL;
137
138 *output = cfg->outputs[temp_index].output;
139 output->index = temp_index;
140
141 return 0;
142}
143
144static int vpbe_get_mode_info(struct vpbe_device *vpbe_dev, char *mode,
145 int output_index)
146{
147 struct vpbe_config *cfg = vpbe_dev->cfg;
148 struct vpbe_enc_mode_info var;
149 int curr_output = output_index;
150 int i;
151
152 if (NULL == mode)
153 return -EINVAL;
154
155 for (i = 0; i < cfg->outputs[curr_output].num_modes; i++) {
156 var = cfg->outputs[curr_output].modes[i];
157 if (!strcmp(mode, var.name)) {
158 vpbe_dev->current_timings = var;
159 return 0;
160 }
161 }
162
163 return -EINVAL;
164}
165
166static int vpbe_get_current_mode_info(struct vpbe_device *vpbe_dev,
167 struct vpbe_enc_mode_info *mode_info)
168{
169 if (NULL == mode_info)
170 return -EINVAL;
171
172 *mode_info = vpbe_dev->current_timings;
173
174 return 0;
175}
176
177static int vpbe_get_dv_preset_info(struct vpbe_device *vpbe_dev,
178 unsigned int dv_preset)
179{
180 struct vpbe_config *cfg = vpbe_dev->cfg;
181 struct vpbe_enc_mode_info var;
182 int curr_output = vpbe_dev->current_out_index;
183 int i;
184
185 for (i = 0; i < vpbe_dev->cfg->outputs[curr_output].num_modes; i++) {
186 var = cfg->outputs[curr_output].modes[i];
187 if ((var.timings_type & VPBE_ENC_DV_PRESET) &&
188 (var.timings.dv_preset == dv_preset)) {
189 vpbe_dev->current_timings = var;
190 return 0;
191 }
192 }
193
194 return -EINVAL;
195}
196
197/* Get std by std id */
198static int vpbe_get_std_info(struct vpbe_device *vpbe_dev,
199 v4l2_std_id std_id)
200{
201 struct vpbe_config *cfg = vpbe_dev->cfg;
202 struct vpbe_enc_mode_info var;
203 int curr_output = vpbe_dev->current_out_index;
204 int i;
205
206 for (i = 0; i < vpbe_dev->cfg->outputs[curr_output].num_modes; i++) {
207 var = cfg->outputs[curr_output].modes[i];
208 if ((var.timings_type & VPBE_ENC_STD) &&
209 (var.timings.std_id & std_id)) {
210 vpbe_dev->current_timings = var;
211 return 0;
212 }
213 }
214
215 return -EINVAL;
216}
217
218static int vpbe_get_std_info_by_name(struct vpbe_device *vpbe_dev,
219 char *std_name)
220{
221 struct vpbe_config *cfg = vpbe_dev->cfg;
222 struct vpbe_enc_mode_info var;
223 int curr_output = vpbe_dev->current_out_index;
224 int i;
225
226 for (i = 0; i < vpbe_dev->cfg->outputs[curr_output].num_modes; i++) {
227 var = cfg->outputs[curr_output].modes[i];
228 if (!strcmp(var.name, std_name)) {
229 vpbe_dev->current_timings = var;
230 return 0;
231 }
232 }
233
234 return -EINVAL;
235}
236
237/**
238 * vpbe_set_output - Set output
239 * @vpbe_dev - vpbe device ptr
240 * @index - index of output
241 *
242 * Set vpbe output to the output specified by the index
243 */
244static int vpbe_set_output(struct vpbe_device *vpbe_dev, int index)
245{
246 struct encoder_config_info *curr_enc_info =
247 vpbe_current_encoder_info(vpbe_dev);
248 struct vpbe_config *cfg = vpbe_dev->cfg;
249 struct venc_platform_data *venc_device = vpbe_dev->venc_device;
250 enum v4l2_mbus_pixelcode if_params;
251 int enc_out_index;
252 int sd_index;
253 int ret = 0;
254
255 if (index >= cfg->num_outputs)
256 return -EINVAL;
257
258 mutex_lock(&vpbe_dev->lock);
259
260 sd_index = vpbe_dev->current_sd_index;
261 enc_out_index = cfg->outputs[index].output.index;
262 /*
263 * Currently we switch the encoder based on output selected
264 * by the application. If media controller is implemented later
265 * there is will be an API added to setup_link between venc
266 * and external encoder. So in that case below comparison always
267 * match and encoder will not be switched. But if application
268 * chose not to use media controller, then this provides current
269 * way of switching encoder at the venc output.
270 */
271 if (strcmp(curr_enc_info->module_name,
272 cfg->outputs[index].subdev_name)) {
273 /* Need to switch the encoder at the output */
274 sd_index = vpbe_find_encoder_sd_index(cfg, index);
275 if (sd_index < 0) {
276 ret = -EINVAL;
277 goto out;
278 }
279
280 if_params = cfg->outputs[index].if_params;
281 venc_device->setup_if_config(if_params);
282 if (ret)
283 goto out;
284 }
285
286 /* Set output at the encoder */
287 ret = v4l2_subdev_call(vpbe_dev->encoders[sd_index], video,
288 s_routing, 0, enc_out_index, 0);
289 if (ret)
290 goto out;
291
292 /*
293 * It is assumed that venc or extenal encoder will set a default
294 * mode in the sub device. For external encoder or LCD pannel output,
295 * we also need to set up the lcd port for the required mode. So setup
296 * the lcd port for the default mode that is configured in the board
297 * arch/arm/mach-davinci/board-dm355-evm.setup file for the external
298 * encoder.
299 */
300 ret = vpbe_get_mode_info(vpbe_dev,
301 cfg->outputs[index].default_mode, index);
302 if (!ret) {
303 struct osd_state *osd_device = vpbe_dev->osd_device;
304
305 osd_device->ops.set_left_margin(osd_device,
306 vpbe_dev->current_timings.left_margin);
307 osd_device->ops.set_top_margin(osd_device,
308 vpbe_dev->current_timings.upper_margin);
309 vpbe_dev->current_sd_index = sd_index;
310 vpbe_dev->current_out_index = index;
311 }
312out:
313 mutex_unlock(&vpbe_dev->lock);
314 return ret;
315}
316
317static int vpbe_set_default_output(struct vpbe_device *vpbe_dev)
318{
319 struct vpbe_config *cfg = vpbe_dev->cfg;
320 int ret = 0;
321 int i;
322
323 for (i = 0; i < cfg->num_outputs; i++) {
324 if (!strcmp(def_output,
325 cfg->outputs[i].output.name)) {
326 ret = vpbe_set_output(vpbe_dev, i);
327 if (!ret)
328 vpbe_dev->current_out_index = i;
329 return ret;
330 }
331 }
332 return ret;
333}
334
335/**
336 * vpbe_get_output - Get output
337 * @vpbe_dev - vpbe device ptr
338 *
339 * return current vpbe output to the the index
340 */
341static unsigned int vpbe_get_output(struct vpbe_device *vpbe_dev)
342{
343 return vpbe_dev->current_out_index;
344}
345
346/**
347 * vpbe_s_dv_preset - Set the given preset timings in the encoder
348 *
349 * Sets the preset if supported by the current encoder. Return the status.
350 * 0 - success & -EINVAL on error
351 */
352static int vpbe_s_dv_preset(struct vpbe_device *vpbe_dev,
353 struct v4l2_dv_preset *dv_preset)
354{
355 struct vpbe_config *cfg = vpbe_dev->cfg;
356 int out_index = vpbe_dev->current_out_index;
357 int sd_index = vpbe_dev->current_sd_index;
358 int ret;
359
360
361 if (!(cfg->outputs[out_index].output.capabilities &
362 V4L2_OUT_CAP_PRESETS))
363 return -EINVAL;
364
365 ret = vpbe_get_dv_preset_info(vpbe_dev, dv_preset->preset);
366
367 if (ret)
368 return ret;
369
370 mutex_lock(&vpbe_dev->lock);
371
372
373 ret = v4l2_subdev_call(vpbe_dev->encoders[sd_index], video,
374 s_dv_preset, dv_preset);
375 if (!ret && (vpbe_dev->amp != NULL)) {
376 /* Call amplifier subdevice */
377 ret = v4l2_subdev_call(vpbe_dev->amp, video,
378 s_dv_preset, dv_preset);
379 }
380 /* set the lcd controller output for the given mode */
381 if (!ret) {
382 struct osd_state *osd_device = vpbe_dev->osd_device;
383
384 osd_device->ops.set_left_margin(osd_device,
385 vpbe_dev->current_timings.left_margin);
386 osd_device->ops.set_top_margin(osd_device,
387 vpbe_dev->current_timings.upper_margin);
388 }
389 mutex_unlock(&vpbe_dev->lock);
390
391 return ret;
392}
393
394/**
395 * vpbe_g_dv_preset - Get the preset in the current encoder
396 *
397 * Get the preset in the current encoder. Return the status. 0 - success
398 * -EINVAL on error
399 */
400static int vpbe_g_dv_preset(struct vpbe_device *vpbe_dev,
401 struct v4l2_dv_preset *dv_preset)
402{
403 if (vpbe_dev->current_timings.timings_type &
404 VPBE_ENC_DV_PRESET) {
405 dv_preset->preset = vpbe_dev->current_timings.timings.dv_preset;
406 return 0;
407 }
408
409 return -EINVAL;
410}
411
412/**
413 * vpbe_enum_dv_presets - Enumerate the dv presets in the current encoder
414 *
415 * Get the preset in the current encoder. Return the status. 0 - success
416 * -EINVAL on error
417 */
418static int vpbe_enum_dv_presets(struct vpbe_device *vpbe_dev,
419 struct v4l2_dv_enum_preset *preset_info)
420{
421 struct vpbe_config *cfg = vpbe_dev->cfg;
422 int out_index = vpbe_dev->current_out_index;
423 struct vpbe_output *output = &cfg->outputs[out_index];
424 int j = 0;
425 int i;
426
427 if (!(output->output.capabilities & V4L2_OUT_CAP_PRESETS))
428 return -EINVAL;
429
430 for (i = 0; i < output->num_modes; i++) {
431 if (output->modes[i].timings_type == VPBE_ENC_DV_PRESET) {
432 if (j == preset_info->index)
433 break;
434 j++;
435 }
436 }
437
438 if (i == output->num_modes)
439 return -EINVAL;
440
441 return v4l_fill_dv_preset_info(output->modes[i].timings.dv_preset,
442 preset_info);
443}
444
445/**
446 * vpbe_s_std - Set the given standard in the encoder
447 *
448 * Sets the standard if supported by the current encoder. Return the status.
449 * 0 - success & -EINVAL on error
450 */
451static int vpbe_s_std(struct vpbe_device *vpbe_dev, v4l2_std_id *std_id)
452{
453 struct vpbe_config *cfg = vpbe_dev->cfg;
454 int out_index = vpbe_dev->current_out_index;
455 int sd_index = vpbe_dev->current_sd_index;
456 int ret;
457
458 if (!(cfg->outputs[out_index].output.capabilities &
459 V4L2_OUT_CAP_STD))
460 return -EINVAL;
461
462 ret = vpbe_get_std_info(vpbe_dev, *std_id);
463 if (ret)
464 return ret;
465
466 mutex_lock(&vpbe_dev->lock);
467
468 ret = v4l2_subdev_call(vpbe_dev->encoders[sd_index], video,
469 s_std_output, *std_id);
470 /* set the lcd controller output for the given mode */
471 if (!ret) {
472 struct osd_state *osd_device = vpbe_dev->osd_device;
473
474 osd_device->ops.set_left_margin(osd_device,
475 vpbe_dev->current_timings.left_margin);
476 osd_device->ops.set_top_margin(osd_device,
477 vpbe_dev->current_timings.upper_margin);
478 }
479 mutex_unlock(&vpbe_dev->lock);
480
481 return ret;
482}
483
484/**
485 * vpbe_g_std - Get the standard in the current encoder
486 *
487 * Get the standard in the current encoder. Return the status. 0 - success
488 * -EINVAL on error
489 */
490static int vpbe_g_std(struct vpbe_device *vpbe_dev, v4l2_std_id *std_id)
491{
492 struct vpbe_enc_mode_info cur_timings = vpbe_dev->current_timings;
493
494 if (cur_timings.timings_type & VPBE_ENC_STD) {
495 *std_id = cur_timings.timings.std_id;
496 return 0;
497 }
498
499 return -EINVAL;
500}
501
502/**
503 * vpbe_set_mode - Set mode in the current encoder using mode info
504 *
505 * Use the mode string to decide what timings to set in the encoder
506 * This is typically useful when fbset command is used to change the current
507 * timings by specifying a string to indicate the timings.
508 */
509static int vpbe_set_mode(struct vpbe_device *vpbe_dev,
510 struct vpbe_enc_mode_info *mode_info)
511{
512 struct vpbe_enc_mode_info *preset_mode = NULL;
513 struct vpbe_config *cfg = vpbe_dev->cfg;
514 struct v4l2_dv_preset dv_preset;
515 struct osd_state *osd_device;
516 int out_index = vpbe_dev->current_out_index;
517 int ret = 0;
518 int i;
519
520 if ((NULL == mode_info) || (NULL == mode_info->name))
521 return -EINVAL;
522
523 for (i = 0; i < cfg->outputs[out_index].num_modes; i++) {
524 if (!strcmp(mode_info->name,
525 cfg->outputs[out_index].modes[i].name)) {
526 preset_mode = &cfg->outputs[out_index].modes[i];
527 /*
528 * it may be one of the 3 timings type. Check and
529 * invoke right API
530 */
531 if (preset_mode->timings_type & VPBE_ENC_STD)
532 return vpbe_s_std(vpbe_dev,
533 &preset_mode->timings.std_id);
534 if (preset_mode->timings_type & VPBE_ENC_DV_PRESET) {
535 dv_preset.preset =
536 preset_mode->timings.dv_preset;
537 return vpbe_s_dv_preset(vpbe_dev, &dv_preset);
538 }
539 }
540 }
541
542 /* Only custom timing should reach here */
543 if (preset_mode == NULL)
544 return -EINVAL;
545
546 mutex_lock(&vpbe_dev->lock);
547
548 osd_device = vpbe_dev->osd_device;
549 vpbe_dev->current_timings = *preset_mode;
550 osd_device->ops.set_left_margin(osd_device,
551 vpbe_dev->current_timings.left_margin);
552 osd_device->ops.set_top_margin(osd_device,
553 vpbe_dev->current_timings.upper_margin);
554
555 mutex_unlock(&vpbe_dev->lock);
556
557 return ret;
558}
559
560static int vpbe_set_default_mode(struct vpbe_device *vpbe_dev)
561{
562 int ret;
563
564 ret = vpbe_get_std_info_by_name(vpbe_dev, def_mode);
565 if (ret)
566 return ret;
567
568 /* set the default mode in the encoder */
569 return vpbe_set_mode(vpbe_dev, &vpbe_dev->current_timings);
570}
571
572static int platform_device_get(struct device *dev, void *data)
573{
574 struct platform_device *pdev = to_platform_device(dev);
575 struct vpbe_device *vpbe_dev = data;
576
577 if (strcmp("vpbe-osd", pdev->name) == 0)
578 vpbe_dev->osd_device = platform_get_drvdata(pdev);
579 if (strcmp("vpbe-venc", pdev->name) == 0)
580 vpbe_dev->venc_device = dev_get_platdata(&pdev->dev);
581
582 return 0;
583}
584
585/**
586 * vpbe_initialize() - Initialize the vpbe display controller
587 * @vpbe_dev - vpbe device ptr
588 *
589 * Master frame buffer device drivers calls this to initialize vpbe
590 * display controller. This will then registers v4l2 device and the sub
591 * devices and sets a current encoder sub device for display. v4l2 display
592 * device driver is the master and frame buffer display device driver is
593 * the slave. Frame buffer display driver checks the initialized during
594 * probe and exit if not initialized. Returns status.
595 */
596static int vpbe_initialize(struct device *dev, struct vpbe_device *vpbe_dev)
597{
598 struct encoder_config_info *enc_info;
599 struct amp_config_info *amp_info;
600 struct v4l2_subdev **enc_subdev;
601 struct osd_state *osd_device;
602 struct i2c_adapter *i2c_adap;
603 int output_index;
604 int num_encoders;
605 int ret = 0;
606 int err;
607 int i;
608
609 /*
610 * v4l2 abd FBDev frame buffer devices will get the vpbe_dev pointer
611 * from the platform device by iteration of platform drivers and
612 * matching with device name
613 */
614 if (NULL == vpbe_dev || NULL == dev) {
615 printk(KERN_ERR "Null device pointers.\n");
616 return -ENODEV;
617 }
618
619 if (vpbe_dev->initialized)
620 return 0;
621
622 mutex_lock(&vpbe_dev->lock);
623
624 if (strcmp(vpbe_dev->cfg->module_name, "dm644x-vpbe-display") != 0) {
625 /* We have dac clock available for platform */
626 vpbe_dev->dac_clk = clk_get(vpbe_dev->pdev, "vpss_dac");
627 if (IS_ERR(vpbe_dev->dac_clk)) {
628 ret = PTR_ERR(vpbe_dev->dac_clk);
629 goto vpbe_unlock;
630 }
631 if (clk_enable(vpbe_dev->dac_clk)) {
632 ret = -ENODEV;
633 goto vpbe_unlock;
634 }
635 }
636
637 /* first enable vpss clocks */
638 vpss_enable_clock(VPSS_VPBE_CLOCK, 1);
639
640 /* First register a v4l2 device */
641 ret = v4l2_device_register(dev, &vpbe_dev->v4l2_dev);
642 if (ret) {
643 v4l2_err(dev->driver,
644 "Unable to register v4l2 device.\n");
645 goto vpbe_fail_clock;
646 }
647 v4l2_info(&vpbe_dev->v4l2_dev, "vpbe v4l2 device registered\n");
648
649 err = bus_for_each_dev(&platform_bus_type, NULL, vpbe_dev,
650 platform_device_get);
651 if (err < 0)
652 return err;
653
654 vpbe_dev->venc = venc_sub_dev_init(&vpbe_dev->v4l2_dev,
655 vpbe_dev->cfg->venc.module_name);
656 /* register venc sub device */
657 if (vpbe_dev->venc == NULL) {
658 v4l2_err(&vpbe_dev->v4l2_dev,
659 "vpbe unable to init venc sub device\n");
660 ret = -ENODEV;
661 goto vpbe_fail_v4l2_device;
662 }
663 /* initialize osd device */
664 osd_device = vpbe_dev->osd_device;
665
666 if (NULL != osd_device->ops.initialize) {
667 err = osd_device->ops.initialize(osd_device);
668 if (err) {
669 v4l2_err(&vpbe_dev->v4l2_dev,
670 "unable to initialize the OSD device");
671 err = -ENOMEM;
672 goto vpbe_fail_v4l2_device;
673 }
674 }
675
676 /*
677 * Register any external encoders that are configured. At index 0 we
678 * store venc sd index.
679 */
680 num_encoders = vpbe_dev->cfg->num_ext_encoders + 1;
681 vpbe_dev->encoders = kmalloc(
682 sizeof(struct v4l2_subdev *)*num_encoders,
683 GFP_KERNEL);
684 if (NULL == vpbe_dev->encoders) {
685 v4l2_err(&vpbe_dev->v4l2_dev,
686 "unable to allocate memory for encoders sub devices");
687 ret = -ENOMEM;
688 goto vpbe_fail_v4l2_device;
689 }
690
691 i2c_adap = i2c_get_adapter(vpbe_dev->cfg->i2c_adapter_id);
692 for (i = 0; i < (vpbe_dev->cfg->num_ext_encoders + 1); i++) {
693 if (i == 0) {
694 /* venc is at index 0 */
695 enc_subdev = &vpbe_dev->encoders[i];
696 *enc_subdev = vpbe_dev->venc;
697 continue;
698 }
699 enc_info = &vpbe_dev->cfg->ext_encoders[i];
700 if (enc_info->is_i2c) {
701 enc_subdev = &vpbe_dev->encoders[i];
702 *enc_subdev = v4l2_i2c_new_subdev_board(
703 &vpbe_dev->v4l2_dev, i2c_adap,
704 &enc_info->board_info, NULL);
705 if (*enc_subdev)
706 v4l2_info(&vpbe_dev->v4l2_dev,
707 "v4l2 sub device %s registered\n",
708 enc_info->module_name);
709 else {
710 v4l2_err(&vpbe_dev->v4l2_dev, "encoder %s"
711 " failed to register",
712 enc_info->module_name);
713 ret = -ENODEV;
714 goto vpbe_fail_sd_register;
715 }
716 } else
717 v4l2_warn(&vpbe_dev->v4l2_dev, "non-i2c encoders"
718 " currently not supported");
719 }
720 /* Add amplifier subdevice for dm365 */
721 if ((strcmp(vpbe_dev->cfg->module_name, "dm365-vpbe-display") == 0) &&
722 vpbe_dev->cfg->amp != NULL) {
723 amp_info = vpbe_dev->cfg->amp;
724 if (amp_info->is_i2c) {
725 vpbe_dev->amp = v4l2_i2c_new_subdev_board(
726 &vpbe_dev->v4l2_dev, i2c_adap,
727 &amp_info->board_info, NULL);
728 if (!vpbe_dev->amp) {
729 v4l2_err(&vpbe_dev->v4l2_dev,
730 "amplifier %s failed to register",
731 amp_info->module_name);
732 ret = -ENODEV;
733 goto vpbe_fail_amp_register;
734 }
735 v4l2_info(&vpbe_dev->v4l2_dev,
736 "v4l2 sub device %s registered\n",
737 amp_info->module_name);
738 } else {
739 vpbe_dev->amp = NULL;
740 v4l2_warn(&vpbe_dev->v4l2_dev, "non-i2c amplifiers"
741 " currently not supported");
742 }
743 } else {
744 vpbe_dev->amp = NULL;
745 }
746
747 /* set the current encoder and output to that of venc by default */
748 vpbe_dev->current_sd_index = 0;
749 vpbe_dev->current_out_index = 0;
750 output_index = 0;
751
752 mutex_unlock(&vpbe_dev->lock);
753
754 printk(KERN_NOTICE "Setting default output to %s\n", def_output);
755 ret = vpbe_set_default_output(vpbe_dev);
756 if (ret) {
757 v4l2_err(&vpbe_dev->v4l2_dev, "Failed to set default output %s",
758 def_output);
759 return ret;
760 }
761
762 printk(KERN_NOTICE "Setting default mode to %s\n", def_mode);
763 ret = vpbe_set_default_mode(vpbe_dev);
764 if (ret) {
765 v4l2_err(&vpbe_dev->v4l2_dev, "Failed to set default mode %s",
766 def_mode);
767 return ret;
768 }
769 vpbe_dev->initialized = 1;
770 /* TBD handling of bootargs for default output and mode */
771 return 0;
772
773vpbe_fail_amp_register:
774 kfree(vpbe_dev->amp);
775vpbe_fail_sd_register:
776 kfree(vpbe_dev->encoders);
777vpbe_fail_v4l2_device:
778 v4l2_device_unregister(&vpbe_dev->v4l2_dev);
779vpbe_fail_clock:
780 if (strcmp(vpbe_dev->cfg->module_name, "dm644x-vpbe-display") != 0)
781 clk_put(vpbe_dev->dac_clk);
782vpbe_unlock:
783 mutex_unlock(&vpbe_dev->lock);
784 return ret;
785}
786
787/**
788 * vpbe_deinitialize() - de-initialize the vpbe display controller
789 * @dev - Master and slave device ptr
790 *
791 * vpbe_master and slave frame buffer devices calls this to de-initialize
792 * the display controller. It is called when master and slave device
793 * driver modules are removed and no longer requires the display controller.
794 */
795static void vpbe_deinitialize(struct device *dev, struct vpbe_device *vpbe_dev)
796{
797 v4l2_device_unregister(&vpbe_dev->v4l2_dev);
798 if (strcmp(vpbe_dev->cfg->module_name, "dm644x-vpbe-display") != 0)
799 clk_put(vpbe_dev->dac_clk);
800
801 kfree(vpbe_dev->amp);
802 kfree(vpbe_dev->encoders);
803 vpbe_dev->initialized = 0;
804 /* disable vpss clocks */
805 vpss_enable_clock(VPSS_VPBE_CLOCK, 0);
806}
807
808static struct vpbe_device_ops vpbe_dev_ops = {
809 .g_cropcap = vpbe_g_cropcap,
810 .enum_outputs = vpbe_enum_outputs,
811 .set_output = vpbe_set_output,
812 .get_output = vpbe_get_output,
813 .s_dv_preset = vpbe_s_dv_preset,
814 .g_dv_preset = vpbe_g_dv_preset,
815 .enum_dv_presets = vpbe_enum_dv_presets,
816 .s_std = vpbe_s_std,
817 .g_std = vpbe_g_std,
818 .initialize = vpbe_initialize,
819 .deinitialize = vpbe_deinitialize,
820 .get_mode_info = vpbe_get_current_mode_info,
821 .set_mode = vpbe_set_mode,
822};
823
824static __devinit int vpbe_probe(struct platform_device *pdev)
825{
826 struct vpbe_device *vpbe_dev;
827 struct vpbe_config *cfg;
828 int ret = -EINVAL;
829
830 if (pdev->dev.platform_data == NULL) {
831 v4l2_err(pdev->dev.driver, "No platform data\n");
832 return -ENODEV;
833 }
834 cfg = pdev->dev.platform_data;
835
836 if (!cfg->module_name[0] ||
837 !cfg->osd.module_name[0] ||
838 !cfg->venc.module_name[0]) {
839 v4l2_err(pdev->dev.driver, "vpbe display module names not"
840 " defined\n");
841 return ret;
842 }
843
844 vpbe_dev = kzalloc(sizeof(*vpbe_dev), GFP_KERNEL);
845 if (vpbe_dev == NULL) {
846 v4l2_err(pdev->dev.driver, "Unable to allocate memory"
847 " for vpbe_device\n");
848 return -ENOMEM;
849 }
850 vpbe_dev->cfg = cfg;
851 vpbe_dev->ops = vpbe_dev_ops;
852 vpbe_dev->pdev = &pdev->dev;
853
854 if (cfg->outputs->num_modes > 0)
855 vpbe_dev->current_timings = vpbe_dev->cfg->outputs[0].modes[0];
856 else {
857 kfree(vpbe_dev);
858 return -ENODEV;
859 }
860
861 /* set the driver data in platform device */
862 platform_set_drvdata(pdev, vpbe_dev);
863 mutex_init(&vpbe_dev->lock);
864
865 return 0;
866}
867
868static int vpbe_remove(struct platform_device *device)
869{
870 struct vpbe_device *vpbe_dev = platform_get_drvdata(device);
871
872 kfree(vpbe_dev);
873
874 return 0;
875}
876
877static struct platform_driver vpbe_driver = {
878 .driver = {
879 .name = "vpbe_controller",
880 .owner = THIS_MODULE,
881 },
882 .probe = vpbe_probe,
883 .remove = vpbe_remove,
884};
885
886module_platform_driver(vpbe_driver);
diff --git a/drivers/media/video/davinci/vpbe_display.c b/drivers/media/video/davinci/vpbe_display.c
deleted file mode 100644
index 9a05c817462c..000000000000
--- a/drivers/media/video/davinci/vpbe_display.c
+++ /dev/null
@@ -1,1838 +0,0 @@
1/*
2 * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation version 2.
7 *
8 * This program is distributed WITHOUT ANY WARRANTY of any
9 * kind, whether express or implied; without even the implied warranty
10 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13#include <linux/kernel.h>
14#include <linux/init.h>
15#include <linux/module.h>
16#include <linux/errno.h>
17#include <linux/interrupt.h>
18#include <linux/string.h>
19#include <linux/wait.h>
20#include <linux/time.h>
21#include <linux/platform_device.h>
22#include <linux/irq.h>
23#include <linux/mm.h>
24#include <linux/mutex.h>
25#include <linux/videodev2.h>
26#include <linux/slab.h>
27
28#include <asm/pgtable.h>
29#include <mach/cputype.h>
30
31#include <media/v4l2-dev.h>
32#include <media/v4l2-common.h>
33#include <media/v4l2-ioctl.h>
34#include <media/v4l2-device.h>
35#include <media/davinci/vpbe_display.h>
36#include <media/davinci/vpbe_types.h>
37#include <media/davinci/vpbe.h>
38#include <media/davinci/vpbe_venc.h>
39#include <media/davinci/vpbe_osd.h>
40#include "vpbe_venc_regs.h"
41
42#define VPBE_DISPLAY_DRIVER "vpbe-v4l2"
43
44static int debug;
45
46#define VPBE_DEFAULT_NUM_BUFS 3
47
48module_param(debug, int, 0644);
49
50static int venc_is_second_field(struct vpbe_display *disp_dev)
51{
52 struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
53 int ret;
54 int val;
55
56 ret = v4l2_subdev_call(vpbe_dev->venc,
57 core,
58 ioctl,
59 VENC_GET_FLD,
60 &val);
61 if (ret < 0) {
62 v4l2_err(&vpbe_dev->v4l2_dev,
63 "Error in getting Field ID 0\n");
64 }
65 return val;
66}
67
68static void vpbe_isr_even_field(struct vpbe_display *disp_obj,
69 struct vpbe_layer *layer)
70{
71 struct timespec timevalue;
72
73 if (layer->cur_frm == layer->next_frm)
74 return;
75 ktime_get_ts(&timevalue);
76 layer->cur_frm->ts.tv_sec = timevalue.tv_sec;
77 layer->cur_frm->ts.tv_usec = timevalue.tv_nsec / NSEC_PER_USEC;
78 layer->cur_frm->state = VIDEOBUF_DONE;
79 wake_up_interruptible(&layer->cur_frm->done);
80 /* Make cur_frm pointing to next_frm */
81 layer->cur_frm = layer->next_frm;
82}
83
84static void vpbe_isr_odd_field(struct vpbe_display *disp_obj,
85 struct vpbe_layer *layer)
86{
87 struct osd_state *osd_device = disp_obj->osd_device;
88 unsigned long addr;
89
90 spin_lock(&disp_obj->dma_queue_lock);
91 if (list_empty(&layer->dma_queue) ||
92 (layer->cur_frm != layer->next_frm)) {
93 spin_unlock(&disp_obj->dma_queue_lock);
94 return;
95 }
96 /*
97 * one field is displayed configure
98 * the next frame if it is available
99 * otherwise hold on current frame
100 * Get next from the buffer queue
101 */
102 layer->next_frm = list_entry(
103 layer->dma_queue.next,
104 struct videobuf_buffer,
105 queue);
106 /* Remove that from the buffer queue */
107 list_del(&layer->next_frm->queue);
108 spin_unlock(&disp_obj->dma_queue_lock);
109 /* Mark state of the frame to active */
110 layer->next_frm->state = VIDEOBUF_ACTIVE;
111 addr = videobuf_to_dma_contig(layer->next_frm);
112 osd_device->ops.start_layer(osd_device,
113 layer->layer_info.id,
114 addr,
115 disp_obj->cbcr_ofst);
116}
117
118/* interrupt service routine */
119static irqreturn_t venc_isr(int irq, void *arg)
120{
121 struct vpbe_display *disp_dev = (struct vpbe_display *)arg;
122 struct vpbe_layer *layer;
123 static unsigned last_event;
124 unsigned event = 0;
125 int fid;
126 int i;
127
128 if ((NULL == arg) || (NULL == disp_dev->dev[0]))
129 return IRQ_HANDLED;
130
131 if (venc_is_second_field(disp_dev))
132 event |= VENC_SECOND_FIELD;
133 else
134 event |= VENC_FIRST_FIELD;
135
136 if (event == (last_event & ~VENC_END_OF_FRAME)) {
137 /*
138 * If the display is non-interlaced, then we need to flag the
139 * end-of-frame event at every interrupt regardless of the
140 * value of the FIDST bit. We can conclude that the display is
141 * non-interlaced if the value of the FIDST bit is unchanged
142 * from the previous interrupt.
143 */
144 event |= VENC_END_OF_FRAME;
145 } else if (event == VENC_SECOND_FIELD) {
146 /* end-of-frame for interlaced display */
147 event |= VENC_END_OF_FRAME;
148 }
149 last_event = event;
150
151 for (i = 0; i < VPBE_DISPLAY_MAX_DEVICES; i++) {
152 layer = disp_dev->dev[i];
153 /* If streaming is started in this layer */
154 if (!layer->started)
155 continue;
156
157 if (layer->layer_first_int) {
158 layer->layer_first_int = 0;
159 continue;
160 }
161 /* Check the field format */
162 if ((V4L2_FIELD_NONE == layer->pix_fmt.field) &&
163 (event & VENC_END_OF_FRAME)) {
164 /* Progressive mode */
165
166 vpbe_isr_even_field(disp_dev, layer);
167 vpbe_isr_odd_field(disp_dev, layer);
168 } else {
169 /* Interlaced mode */
170
171 layer->field_id ^= 1;
172 if (event & VENC_FIRST_FIELD)
173 fid = 0;
174 else
175 fid = 1;
176
177 /*
178 * If field id does not match with store
179 * field id
180 */
181 if (fid != layer->field_id) {
182 /* Make them in sync */
183 layer->field_id = fid;
184 continue;
185 }
186 /*
187 * device field id and local field id are
188 * in sync. If this is even field
189 */
190 if (0 == fid)
191 vpbe_isr_even_field(disp_dev, layer);
192 else /* odd field */
193 vpbe_isr_odd_field(disp_dev, layer);
194 }
195 }
196
197 return IRQ_HANDLED;
198}
199
200/*
201 * vpbe_buffer_prepare()
202 * This is the callback function called from videobuf_qbuf() function
203 * the buffer is prepared and user space virtual address is converted into
204 * physical address
205 */
206static int vpbe_buffer_prepare(struct videobuf_queue *q,
207 struct videobuf_buffer *vb,
208 enum v4l2_field field)
209{
210 struct vpbe_fh *fh = q->priv_data;
211 struct vpbe_layer *layer = fh->layer;
212 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
213 unsigned long addr;
214 int ret;
215
216 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
217 "vpbe_buffer_prepare\n");
218
219 /* If buffer is not initialized, initialize it */
220 if (VIDEOBUF_NEEDS_INIT == vb->state) {
221 vb->width = layer->pix_fmt.width;
222 vb->height = layer->pix_fmt.height;
223 vb->size = layer->pix_fmt.sizeimage;
224 vb->field = field;
225
226 ret = videobuf_iolock(q, vb, NULL);
227 if (ret < 0) {
228 v4l2_err(&vpbe_dev->v4l2_dev, "Failed to map \
229 user address\n");
230 return -EINVAL;
231 }
232
233 addr = videobuf_to_dma_contig(vb);
234
235 if (q->streaming) {
236 if (!IS_ALIGNED(addr, 8)) {
237 v4l2_err(&vpbe_dev->v4l2_dev,
238 "buffer_prepare:offset is \
239 not aligned to 32 bytes\n");
240 return -EINVAL;
241 }
242 }
243 vb->state = VIDEOBUF_PREPARED;
244 }
245 return 0;
246}
247
248/*
249 * vpbe_buffer_setup()
250 * This function allocates memory for the buffers
251 */
252static int vpbe_buffer_setup(struct videobuf_queue *q,
253 unsigned int *count,
254 unsigned int *size)
255{
256 /* Get the file handle object and layer object */
257 struct vpbe_fh *fh = q->priv_data;
258 struct vpbe_layer *layer = fh->layer;
259 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
260
261 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_buffer_setup\n");
262
263 *size = layer->pix_fmt.sizeimage;
264
265 /* Store number of buffers allocated in numbuffer member */
266 if (*count < VPBE_DEFAULT_NUM_BUFS)
267 *count = layer->numbuffers = VPBE_DEFAULT_NUM_BUFS;
268
269 return 0;
270}
271
272/*
273 * vpbe_buffer_queue()
274 * This function adds the buffer to DMA queue
275 */
276static void vpbe_buffer_queue(struct videobuf_queue *q,
277 struct videobuf_buffer *vb)
278{
279 /* Get the file handle object and layer object */
280 struct vpbe_fh *fh = q->priv_data;
281 struct vpbe_layer *layer = fh->layer;
282 struct vpbe_display *disp = fh->disp_dev;
283 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
284 unsigned long flags;
285
286 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
287 "vpbe_buffer_queue\n");
288
289 /* add the buffer to the DMA queue */
290 spin_lock_irqsave(&disp->dma_queue_lock, flags);
291 list_add_tail(&vb->queue, &layer->dma_queue);
292 spin_unlock_irqrestore(&disp->dma_queue_lock, flags);
293 /* Change state of the buffer */
294 vb->state = VIDEOBUF_QUEUED;
295}
296
297/*
298 * vpbe_buffer_release()
299 * This function is called from the videobuf layer to free memory allocated to
300 * the buffers
301 */
302static void vpbe_buffer_release(struct videobuf_queue *q,
303 struct videobuf_buffer *vb)
304{
305 /* Get the file handle object and layer object */
306 struct vpbe_fh *fh = q->priv_data;
307 struct vpbe_layer *layer = fh->layer;
308 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
309
310 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
311 "vpbe_buffer_release\n");
312
313 if (V4L2_MEMORY_USERPTR != layer->memory)
314 videobuf_dma_contig_free(q, vb);
315
316 vb->state = VIDEOBUF_NEEDS_INIT;
317}
318
319static struct videobuf_queue_ops video_qops = {
320 .buf_setup = vpbe_buffer_setup,
321 .buf_prepare = vpbe_buffer_prepare,
322 .buf_queue = vpbe_buffer_queue,
323 .buf_release = vpbe_buffer_release,
324};
325
326static
327struct vpbe_layer*
328_vpbe_display_get_other_win_layer(struct vpbe_display *disp_dev,
329 struct vpbe_layer *layer)
330{
331 enum vpbe_display_device_id thiswin, otherwin;
332 thiswin = layer->device_id;
333
334 otherwin = (thiswin == VPBE_DISPLAY_DEVICE_0) ?
335 VPBE_DISPLAY_DEVICE_1 : VPBE_DISPLAY_DEVICE_0;
336 return disp_dev->dev[otherwin];
337}
338
339static int vpbe_set_osd_display_params(struct vpbe_display *disp_dev,
340 struct vpbe_layer *layer)
341{
342 struct osd_layer_config *cfg = &layer->layer_info.config;
343 struct osd_state *osd_device = disp_dev->osd_device;
344 struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
345 unsigned long addr;
346 int ret;
347
348 addr = videobuf_to_dma_contig(layer->cur_frm);
349 /* Set address in the display registers */
350 osd_device->ops.start_layer(osd_device,
351 layer->layer_info.id,
352 addr,
353 disp_dev->cbcr_ofst);
354
355 ret = osd_device->ops.enable_layer(osd_device,
356 layer->layer_info.id, 0);
357 if (ret < 0) {
358 v4l2_err(&vpbe_dev->v4l2_dev,
359 "Error in enabling osd window layer 0\n");
360 return -1;
361 }
362
363 /* Enable the window */
364 layer->layer_info.enable = 1;
365 if (cfg->pixfmt == PIXFMT_NV12) {
366 struct vpbe_layer *otherlayer =
367 _vpbe_display_get_other_win_layer(disp_dev, layer);
368
369 ret = osd_device->ops.enable_layer(osd_device,
370 otherlayer->layer_info.id, 1);
371 if (ret < 0) {
372 v4l2_err(&vpbe_dev->v4l2_dev,
373 "Error in enabling osd window layer 1\n");
374 return -1;
375 }
376 otherlayer->layer_info.enable = 1;
377 }
378 return 0;
379}
380
381static void
382vpbe_disp_calculate_scale_factor(struct vpbe_display *disp_dev,
383 struct vpbe_layer *layer,
384 int expected_xsize, int expected_ysize)
385{
386 struct display_layer_info *layer_info = &layer->layer_info;
387 struct v4l2_pix_format *pixfmt = &layer->pix_fmt;
388 struct osd_layer_config *cfg = &layer->layer_info.config;
389 struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
390 int calculated_xsize;
391 int h_exp = 0;
392 int v_exp = 0;
393 int h_scale;
394 int v_scale;
395
396 v4l2_std_id standard_id = vpbe_dev->current_timings.timings.std_id;
397
398 /*
399 * Application initially set the image format. Current display
400 * size is obtained from the vpbe display controller. expected_xsize
401 * and expected_ysize are set through S_CROP ioctl. Based on this,
402 * driver will calculate the scale factors for vertical and
403 * horizontal direction so that the image is displayed scaled
404 * and expanded. Application uses expansion to display the image
405 * in a square pixel. Otherwise it is displayed using displays
406 * pixel aspect ratio.It is expected that application chooses
407 * the crop coordinates for cropped or scaled display. if crop
408 * size is less than the image size, it is displayed cropped or
409 * it is displayed scaled and/or expanded.
410 *
411 * to begin with, set the crop window same as expected. Later we
412 * will override with scaled window size
413 */
414
415 cfg->xsize = pixfmt->width;
416 cfg->ysize = pixfmt->height;
417 layer_info->h_zoom = ZOOM_X1; /* no horizontal zoom */
418 layer_info->v_zoom = ZOOM_X1; /* no horizontal zoom */
419 layer_info->h_exp = H_EXP_OFF; /* no horizontal zoom */
420 layer_info->v_exp = V_EXP_OFF; /* no horizontal zoom */
421
422 if (pixfmt->width < expected_xsize) {
423 h_scale = vpbe_dev->current_timings.xres / pixfmt->width;
424 if (h_scale < 2)
425 h_scale = 1;
426 else if (h_scale >= 4)
427 h_scale = 4;
428 else
429 h_scale = 2;
430 cfg->xsize *= h_scale;
431 if (cfg->xsize < expected_xsize) {
432 if ((standard_id & V4L2_STD_525_60) ||
433 (standard_id & V4L2_STD_625_50)) {
434 calculated_xsize = (cfg->xsize *
435 VPBE_DISPLAY_H_EXP_RATIO_N) /
436 VPBE_DISPLAY_H_EXP_RATIO_D;
437 if (calculated_xsize <= expected_xsize) {
438 h_exp = 1;
439 cfg->xsize = calculated_xsize;
440 }
441 }
442 }
443 if (h_scale == 2)
444 layer_info->h_zoom = ZOOM_X2;
445 else if (h_scale == 4)
446 layer_info->h_zoom = ZOOM_X4;
447 if (h_exp)
448 layer_info->h_exp = H_EXP_9_OVER_8;
449 } else {
450 /* no scaling, only cropping. Set display area to crop area */
451 cfg->xsize = expected_xsize;
452 }
453
454 if (pixfmt->height < expected_ysize) {
455 v_scale = expected_ysize / pixfmt->height;
456 if (v_scale < 2)
457 v_scale = 1;
458 else if (v_scale >= 4)
459 v_scale = 4;
460 else
461 v_scale = 2;
462 cfg->ysize *= v_scale;
463 if (cfg->ysize < expected_ysize) {
464 if ((standard_id & V4L2_STD_625_50)) {
465 calculated_xsize = (cfg->ysize *
466 VPBE_DISPLAY_V_EXP_RATIO_N) /
467 VPBE_DISPLAY_V_EXP_RATIO_D;
468 if (calculated_xsize <= expected_ysize) {
469 v_exp = 1;
470 cfg->ysize = calculated_xsize;
471 }
472 }
473 }
474 if (v_scale == 2)
475 layer_info->v_zoom = ZOOM_X2;
476 else if (v_scale == 4)
477 layer_info->v_zoom = ZOOM_X4;
478 if (v_exp)
479 layer_info->h_exp = V_EXP_6_OVER_5;
480 } else {
481 /* no scaling, only cropping. Set display area to crop area */
482 cfg->ysize = expected_ysize;
483 }
484 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
485 "crop display xsize = %d, ysize = %d\n",
486 cfg->xsize, cfg->ysize);
487}
488
489static void vpbe_disp_adj_position(struct vpbe_display *disp_dev,
490 struct vpbe_layer *layer,
491 int top, int left)
492{
493 struct osd_layer_config *cfg = &layer->layer_info.config;
494 struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
495
496 cfg->xpos = min((unsigned int)left,
497 vpbe_dev->current_timings.xres - cfg->xsize);
498 cfg->ypos = min((unsigned int)top,
499 vpbe_dev->current_timings.yres - cfg->ysize);
500
501 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
502 "new xpos = %d, ypos = %d\n",
503 cfg->xpos, cfg->ypos);
504}
505
506static void vpbe_disp_check_window_params(struct vpbe_display *disp_dev,
507 struct v4l2_rect *c)
508{
509 struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
510
511 if ((c->width == 0) ||
512 ((c->width + c->left) > vpbe_dev->current_timings.xres))
513 c->width = vpbe_dev->current_timings.xres - c->left;
514
515 if ((c->height == 0) || ((c->height + c->top) >
516 vpbe_dev->current_timings.yres))
517 c->height = vpbe_dev->current_timings.yres - c->top;
518
519 /* window height must be even for interlaced display */
520 if (vpbe_dev->current_timings.interlaced)
521 c->height &= (~0x01);
522
523}
524
525/**
526 * vpbe_try_format()
527 * If user application provides width and height, and have bytesperline set
528 * to zero, driver calculates bytesperline and sizeimage based on hardware
529 * limits.
530 */
531static int vpbe_try_format(struct vpbe_display *disp_dev,
532 struct v4l2_pix_format *pixfmt, int check)
533{
534 struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
535 int min_height = 1;
536 int min_width = 32;
537 int max_height;
538 int max_width;
539 int bpp;
540
541 if ((pixfmt->pixelformat != V4L2_PIX_FMT_UYVY) &&
542 (pixfmt->pixelformat != V4L2_PIX_FMT_NV12))
543 /* choose default as V4L2_PIX_FMT_UYVY */
544 pixfmt->pixelformat = V4L2_PIX_FMT_UYVY;
545
546 /* Check the field format */
547 if ((pixfmt->field != V4L2_FIELD_INTERLACED) &&
548 (pixfmt->field != V4L2_FIELD_NONE)) {
549 if (vpbe_dev->current_timings.interlaced)
550 pixfmt->field = V4L2_FIELD_INTERLACED;
551 else
552 pixfmt->field = V4L2_FIELD_NONE;
553 }
554
555 if (pixfmt->field == V4L2_FIELD_INTERLACED)
556 min_height = 2;
557
558 if (pixfmt->pixelformat == V4L2_PIX_FMT_NV12)
559 bpp = 1;
560 else
561 bpp = 2;
562
563 max_width = vpbe_dev->current_timings.xres;
564 max_height = vpbe_dev->current_timings.yres;
565
566 min_width /= bpp;
567
568 if (!pixfmt->width || (pixfmt->width < min_width) ||
569 (pixfmt->width > max_width)) {
570 pixfmt->width = vpbe_dev->current_timings.xres;
571 }
572
573 if (!pixfmt->height || (pixfmt->height < min_height) ||
574 (pixfmt->height > max_height)) {
575 pixfmt->height = vpbe_dev->current_timings.yres;
576 }
577
578 if (pixfmt->bytesperline < (pixfmt->width * bpp))
579 pixfmt->bytesperline = pixfmt->width * bpp;
580
581 /* Make the bytesperline 32 byte aligned */
582 pixfmt->bytesperline = ((pixfmt->width * bpp + 31) & ~31);
583
584 if (pixfmt->pixelformat == V4L2_PIX_FMT_NV12)
585 pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height +
586 (pixfmt->bytesperline * pixfmt->height >> 1);
587 else
588 pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height;
589
590 return 0;
591}
592
593static int vpbe_display_g_priority(struct file *file, void *priv,
594 enum v4l2_priority *p)
595{
596 struct vpbe_fh *fh = file->private_data;
597 struct vpbe_layer *layer = fh->layer;
598
599 *p = v4l2_prio_max(&layer->prio);
600
601 return 0;
602}
603
604static int vpbe_display_s_priority(struct file *file, void *priv,
605 enum v4l2_priority p)
606{
607 struct vpbe_fh *fh = file->private_data;
608 struct vpbe_layer *layer = fh->layer;
609 int ret;
610
611 ret = v4l2_prio_change(&layer->prio, &fh->prio, p);
612
613 return ret;
614}
615
616static int vpbe_display_querycap(struct file *file, void *priv,
617 struct v4l2_capability *cap)
618{
619 struct vpbe_fh *fh = file->private_data;
620 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
621
622 cap->version = VPBE_DISPLAY_VERSION_CODE;
623 cap->capabilities = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
624 strlcpy(cap->driver, VPBE_DISPLAY_DRIVER, sizeof(cap->driver));
625 strlcpy(cap->bus_info, "platform", sizeof(cap->bus_info));
626 strlcpy(cap->card, vpbe_dev->cfg->module_name, sizeof(cap->card));
627
628 return 0;
629}
630
631static int vpbe_display_s_crop(struct file *file, void *priv,
632 struct v4l2_crop *crop)
633{
634 struct vpbe_fh *fh = file->private_data;
635 struct vpbe_layer *layer = fh->layer;
636 struct vpbe_display *disp_dev = fh->disp_dev;
637 struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
638 struct osd_layer_config *cfg = &layer->layer_info.config;
639 struct osd_state *osd_device = disp_dev->osd_device;
640 struct v4l2_rect *rect = &crop->c;
641 int ret;
642
643 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
644 "VIDIOC_S_CROP, layer id = %d\n", layer->device_id);
645
646 if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) {
647 v4l2_err(&vpbe_dev->v4l2_dev, "Invalid buf type\n");
648 return -EINVAL;
649 }
650
651 if (rect->top < 0)
652 rect->top = 0;
653 if (rect->left < 0)
654 rect->left = 0;
655
656 vpbe_disp_check_window_params(disp_dev, rect);
657
658 osd_device->ops.get_layer_config(osd_device,
659 layer->layer_info.id, cfg);
660
661 vpbe_disp_calculate_scale_factor(disp_dev, layer,
662 rect->width,
663 rect->height);
664 vpbe_disp_adj_position(disp_dev, layer, rect->top,
665 rect->left);
666 ret = osd_device->ops.set_layer_config(osd_device,
667 layer->layer_info.id, cfg);
668 if (ret < 0) {
669 v4l2_err(&vpbe_dev->v4l2_dev,
670 "Error in set layer config:\n");
671 return -EINVAL;
672 }
673
674 /* apply zooming and h or v expansion */
675 osd_device->ops.set_zoom(osd_device,
676 layer->layer_info.id,
677 layer->layer_info.h_zoom,
678 layer->layer_info.v_zoom);
679 ret = osd_device->ops.set_vid_expansion(osd_device,
680 layer->layer_info.h_exp,
681 layer->layer_info.v_exp);
682 if (ret < 0) {
683 v4l2_err(&vpbe_dev->v4l2_dev,
684 "Error in set vid expansion:\n");
685 return -EINVAL;
686 }
687
688 if ((layer->layer_info.h_zoom != ZOOM_X1) ||
689 (layer->layer_info.v_zoom != ZOOM_X1) ||
690 (layer->layer_info.h_exp != H_EXP_OFF) ||
691 (layer->layer_info.v_exp != V_EXP_OFF))
692 /* Enable expansion filter */
693 osd_device->ops.set_interpolation_filter(osd_device, 1);
694 else
695 osd_device->ops.set_interpolation_filter(osd_device, 0);
696
697 return 0;
698}
699
700static int vpbe_display_g_crop(struct file *file, void *priv,
701 struct v4l2_crop *crop)
702{
703 struct vpbe_fh *fh = file->private_data;
704 struct vpbe_layer *layer = fh->layer;
705 struct osd_layer_config *cfg = &layer->layer_info.config;
706 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
707 struct osd_state *osd_device = fh->disp_dev->osd_device;
708 struct v4l2_rect *rect = &crop->c;
709 int ret;
710
711 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
712 "VIDIOC_G_CROP, layer id = %d\n",
713 layer->device_id);
714
715 if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) {
716 v4l2_err(&vpbe_dev->v4l2_dev, "Invalid buf type\n");
717 ret = -EINVAL;
718 }
719 osd_device->ops.get_layer_config(osd_device,
720 layer->layer_info.id, cfg);
721 rect->top = cfg->ypos;
722 rect->left = cfg->xpos;
723 rect->width = cfg->xsize;
724 rect->height = cfg->ysize;
725
726 return 0;
727}
728
729static int vpbe_display_cropcap(struct file *file, void *priv,
730 struct v4l2_cropcap *cropcap)
731{
732 struct vpbe_fh *fh = file->private_data;
733 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
734
735 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_CROPCAP ioctl\n");
736
737 cropcap->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
738 cropcap->bounds.left = 0;
739 cropcap->bounds.top = 0;
740 cropcap->bounds.width = vpbe_dev->current_timings.xres;
741 cropcap->bounds.height = vpbe_dev->current_timings.yres;
742 cropcap->pixelaspect = vpbe_dev->current_timings.aspect;
743 cropcap->defrect = cropcap->bounds;
744 return 0;
745}
746
747static int vpbe_display_g_fmt(struct file *file, void *priv,
748 struct v4l2_format *fmt)
749{
750 struct vpbe_fh *fh = file->private_data;
751 struct vpbe_layer *layer = fh->layer;
752 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
753
754 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
755 "VIDIOC_G_FMT, layer id = %d\n",
756 layer->device_id);
757
758 /* If buffer type is video output */
759 if (V4L2_BUF_TYPE_VIDEO_OUTPUT != fmt->type) {
760 v4l2_err(&vpbe_dev->v4l2_dev, "invalid type\n");
761 return -EINVAL;
762 }
763 /* Fill in the information about format */
764 fmt->fmt.pix = layer->pix_fmt;
765
766 return 0;
767}
768
769static int vpbe_display_enum_fmt(struct file *file, void *priv,
770 struct v4l2_fmtdesc *fmt)
771{
772 struct vpbe_fh *fh = file->private_data;
773 struct vpbe_layer *layer = fh->layer;
774 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
775 unsigned int index = 0;
776
777 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
778 "VIDIOC_ENUM_FMT, layer id = %d\n",
779 layer->device_id);
780 if (fmt->index > 1) {
781 v4l2_err(&vpbe_dev->v4l2_dev, "Invalid format index\n");
782 return -EINVAL;
783 }
784
785 /* Fill in the information about format */
786 index = fmt->index;
787 memset(fmt, 0, sizeof(*fmt));
788 fmt->index = index;
789 fmt->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
790 if (index == 0) {
791 strcpy(fmt->description, "YUV 4:2:2 - UYVY");
792 fmt->pixelformat = V4L2_PIX_FMT_UYVY;
793 } else {
794 strcpy(fmt->description, "Y/CbCr 4:2:0");
795 fmt->pixelformat = V4L2_PIX_FMT_NV12;
796 }
797
798 return 0;
799}
800
801static int vpbe_display_s_fmt(struct file *file, void *priv,
802 struct v4l2_format *fmt)
803{
804 struct vpbe_fh *fh = file->private_data;
805 struct vpbe_layer *layer = fh->layer;
806 struct vpbe_display *disp_dev = fh->disp_dev;
807 struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
808 struct osd_layer_config *cfg = &layer->layer_info.config;
809 struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
810 struct osd_state *osd_device = disp_dev->osd_device;
811 int ret;
812
813 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
814 "VIDIOC_S_FMT, layer id = %d\n",
815 layer->device_id);
816
817 /* If streaming is started, return error */
818 if (layer->started) {
819 v4l2_err(&vpbe_dev->v4l2_dev, "Streaming is started\n");
820 return -EBUSY;
821 }
822 if (V4L2_BUF_TYPE_VIDEO_OUTPUT != fmt->type) {
823 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "invalid type\n");
824 return -EINVAL;
825 }
826 /* Check for valid pixel format */
827 ret = vpbe_try_format(disp_dev, pixfmt, 1);
828 if (ret)
829 return ret;
830
831 /* YUV420 is requested, check availability of the
832 other video window */
833
834 layer->pix_fmt = *pixfmt;
835
836 /* Get osd layer config */
837 osd_device->ops.get_layer_config(osd_device,
838 layer->layer_info.id, cfg);
839 /* Store the pixel format in the layer object */
840 cfg->xsize = pixfmt->width;
841 cfg->ysize = pixfmt->height;
842 cfg->line_length = pixfmt->bytesperline;
843 cfg->ypos = 0;
844 cfg->xpos = 0;
845 cfg->interlaced = vpbe_dev->current_timings.interlaced;
846
847 if (V4L2_PIX_FMT_UYVY == pixfmt->pixelformat)
848 cfg->pixfmt = PIXFMT_YCbCrI;
849
850 /* Change of the default pixel format for both video windows */
851 if (V4L2_PIX_FMT_NV12 == pixfmt->pixelformat) {
852 struct vpbe_layer *otherlayer;
853 cfg->pixfmt = PIXFMT_NV12;
854 otherlayer = _vpbe_display_get_other_win_layer(disp_dev,
855 layer);
856 otherlayer->layer_info.config.pixfmt = PIXFMT_NV12;
857 }
858
859 /* Set the layer config in the osd window */
860 ret = osd_device->ops.set_layer_config(osd_device,
861 layer->layer_info.id, cfg);
862 if (ret < 0) {
863 v4l2_err(&vpbe_dev->v4l2_dev,
864 "Error in S_FMT params:\n");
865 return -EINVAL;
866 }
867
868 /* Readback and fill the local copy of current pix format */
869 osd_device->ops.get_layer_config(osd_device,
870 layer->layer_info.id, cfg);
871
872 return 0;
873}
874
875static int vpbe_display_try_fmt(struct file *file, void *priv,
876 struct v4l2_format *fmt)
877{
878 struct vpbe_fh *fh = file->private_data;
879 struct vpbe_display *disp_dev = fh->disp_dev;
880 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
881 struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
882
883 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_TRY_FMT\n");
884
885 if (V4L2_BUF_TYPE_VIDEO_OUTPUT != fmt->type) {
886 v4l2_err(&vpbe_dev->v4l2_dev, "invalid type\n");
887 return -EINVAL;
888 }
889
890 /* Check for valid field format */
891 return vpbe_try_format(disp_dev, pixfmt, 0);
892
893}
894
895/**
896 * vpbe_display_s_std - Set the given standard in the encoder
897 *
898 * Sets the standard if supported by the current encoder. Return the status.
899 * 0 - success & -EINVAL on error
900 */
901static int vpbe_display_s_std(struct file *file, void *priv,
902 v4l2_std_id *std_id)
903{
904 struct vpbe_fh *fh = priv;
905 struct vpbe_layer *layer = fh->layer;
906 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
907 int ret;
908
909 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_S_STD\n");
910
911 /* If streaming is started, return error */
912 if (layer->started) {
913 v4l2_err(&vpbe_dev->v4l2_dev, "Streaming is started\n");
914 return -EBUSY;
915 }
916 if (NULL != vpbe_dev->ops.s_std) {
917 ret = vpbe_dev->ops.s_std(vpbe_dev, std_id);
918 if (ret) {
919 v4l2_err(&vpbe_dev->v4l2_dev,
920 "Failed to set standard for sub devices\n");
921 return -EINVAL;
922 }
923 } else {
924 return -EINVAL;
925 }
926
927 return 0;
928}
929
930/**
931 * vpbe_display_g_std - Get the standard in the current encoder
932 *
933 * Get the standard in the current encoder. Return the status. 0 - success
934 * -EINVAL on error
935 */
936static int vpbe_display_g_std(struct file *file, void *priv,
937 v4l2_std_id *std_id)
938{
939 struct vpbe_fh *fh = priv;
940 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
941
942 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_G_STD\n");
943
944 /* Get the standard from the current encoder */
945 if (vpbe_dev->current_timings.timings_type & VPBE_ENC_STD) {
946 *std_id = vpbe_dev->current_timings.timings.std_id;
947 return 0;
948 }
949
950 return -EINVAL;
951}
952
953/**
954 * vpbe_display_enum_output - enumerate outputs
955 *
956 * Enumerates the outputs available at the vpbe display
957 * returns the status, -EINVAL if end of output list
958 */
959static int vpbe_display_enum_output(struct file *file, void *priv,
960 struct v4l2_output *output)
961{
962 struct vpbe_fh *fh = priv;
963 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
964 int ret;
965
966 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_ENUM_OUTPUT\n");
967
968 /* Enumerate outputs */
969
970 if (NULL == vpbe_dev->ops.enum_outputs)
971 return -EINVAL;
972
973 ret = vpbe_dev->ops.enum_outputs(vpbe_dev, output);
974 if (ret) {
975 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
976 "Failed to enumerate outputs\n");
977 return -EINVAL;
978 }
979
980 return 0;
981}
982
983/**
984 * vpbe_display_s_output - Set output to
985 * the output specified by the index
986 */
987static int vpbe_display_s_output(struct file *file, void *priv,
988 unsigned int i)
989{
990 struct vpbe_fh *fh = priv;
991 struct vpbe_layer *layer = fh->layer;
992 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
993 int ret;
994
995 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_S_OUTPUT\n");
996 /* If streaming is started, return error */
997 if (layer->started) {
998 v4l2_err(&vpbe_dev->v4l2_dev, "Streaming is started\n");
999 return -EBUSY;
1000 }
1001 if (NULL == vpbe_dev->ops.set_output)
1002 return -EINVAL;
1003
1004 ret = vpbe_dev->ops.set_output(vpbe_dev, i);
1005 if (ret) {
1006 v4l2_err(&vpbe_dev->v4l2_dev,
1007 "Failed to set output for sub devices\n");
1008 return -EINVAL;
1009 }
1010
1011 return 0;
1012}
1013
1014/**
1015 * vpbe_display_g_output - Get output from subdevice
1016 * for a given by the index
1017 */
1018static int vpbe_display_g_output(struct file *file, void *priv,
1019 unsigned int *i)
1020{
1021 struct vpbe_fh *fh = priv;
1022 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
1023
1024 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_G_OUTPUT\n");
1025 /* Get the standard from the current encoder */
1026 *i = vpbe_dev->current_out_index;
1027
1028 return 0;
1029}
1030
1031/**
1032 * vpbe_display_enum_dv_presets - Enumerate the dv presets
1033 *
1034 * enum the preset in the current encoder. Return the status. 0 - success
1035 * -EINVAL on error
1036 */
1037static int
1038vpbe_display_enum_dv_presets(struct file *file, void *priv,
1039 struct v4l2_dv_enum_preset *preset)
1040{
1041 struct vpbe_fh *fh = priv;
1042 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
1043 int ret;
1044
1045 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_ENUM_DV_PRESETS\n");
1046
1047 /* Enumerate outputs */
1048 if (NULL == vpbe_dev->ops.enum_dv_presets)
1049 return -EINVAL;
1050
1051 ret = vpbe_dev->ops.enum_dv_presets(vpbe_dev, preset);
1052 if (ret) {
1053 v4l2_err(&vpbe_dev->v4l2_dev,
1054 "Failed to enumerate dv presets info\n");
1055 return -EINVAL;
1056 }
1057
1058 return 0;
1059}
1060
1061/**
1062 * vpbe_display_s_dv_preset - Set the dv presets
1063 *
1064 * Set the preset in the current encoder. Return the status. 0 - success
1065 * -EINVAL on error
1066 */
1067static int
1068vpbe_display_s_dv_preset(struct file *file, void *priv,
1069 struct v4l2_dv_preset *preset)
1070{
1071 struct vpbe_fh *fh = priv;
1072 struct vpbe_layer *layer = fh->layer;
1073 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
1074 int ret;
1075
1076 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_S_DV_PRESETS\n");
1077
1078
1079 /* If streaming is started, return error */
1080 if (layer->started) {
1081 v4l2_err(&vpbe_dev->v4l2_dev, "Streaming is started\n");
1082 return -EBUSY;
1083 }
1084
1085 /* Set the given standard in the encoder */
1086 if (!vpbe_dev->ops.s_dv_preset)
1087 return -EINVAL;
1088
1089 ret = vpbe_dev->ops.s_dv_preset(vpbe_dev, preset);
1090 if (ret) {
1091 v4l2_err(&vpbe_dev->v4l2_dev,
1092 "Failed to set the dv presets info\n");
1093 return -EINVAL;
1094 }
1095 /* set the current norm to zero to be consistent. If STD is used
1096 * v4l2 layer will set the norm properly on successful s_std call
1097 */
1098 layer->video_dev.current_norm = 0;
1099
1100 return 0;
1101}
1102
1103/**
1104 * vpbe_display_g_dv_preset - Set the dv presets
1105 *
1106 * Get the preset in the current encoder. Return the status. 0 - success
1107 * -EINVAL on error
1108 */
1109static int
1110vpbe_display_g_dv_preset(struct file *file, void *priv,
1111 struct v4l2_dv_preset *dv_preset)
1112{
1113 struct vpbe_fh *fh = priv;
1114 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
1115
1116 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_G_DV_PRESETS\n");
1117
1118 /* Get the given standard in the encoder */
1119
1120 if (vpbe_dev->current_timings.timings_type &
1121 VPBE_ENC_DV_PRESET) {
1122 dv_preset->preset =
1123 vpbe_dev->current_timings.timings.dv_preset;
1124 } else {
1125 return -EINVAL;
1126 }
1127
1128 return 0;
1129}
1130
1131static int vpbe_display_streamoff(struct file *file, void *priv,
1132 enum v4l2_buf_type buf_type)
1133{
1134 struct vpbe_fh *fh = file->private_data;
1135 struct vpbe_layer *layer = fh->layer;
1136 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
1137 struct osd_state *osd_device = fh->disp_dev->osd_device;
1138 int ret;
1139
1140 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
1141 "VIDIOC_STREAMOFF,layer id = %d\n",
1142 layer->device_id);
1143
1144 if (V4L2_BUF_TYPE_VIDEO_OUTPUT != buf_type) {
1145 v4l2_err(&vpbe_dev->v4l2_dev, "Invalid buffer type\n");
1146 return -EINVAL;
1147 }
1148
1149 /* If io is allowed for this file handle, return error */
1150 if (!fh->io_allowed) {
1151 v4l2_err(&vpbe_dev->v4l2_dev, "No io_allowed\n");
1152 return -EACCES;
1153 }
1154
1155 /* If streaming is not started, return error */
1156 if (!layer->started) {
1157 v4l2_err(&vpbe_dev->v4l2_dev, "streaming not started in layer"
1158 " id = %d\n", layer->device_id);
1159 return -EINVAL;
1160 }
1161
1162 osd_device->ops.disable_layer(osd_device,
1163 layer->layer_info.id);
1164 layer->started = 0;
1165 ret = videobuf_streamoff(&layer->buffer_queue);
1166
1167 return ret;
1168}
1169
1170static int vpbe_display_streamon(struct file *file, void *priv,
1171 enum v4l2_buf_type buf_type)
1172{
1173 struct vpbe_fh *fh = file->private_data;
1174 struct vpbe_layer *layer = fh->layer;
1175 struct vpbe_display *disp_dev = fh->disp_dev;
1176 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
1177 struct osd_state *osd_device = disp_dev->osd_device;
1178 int ret;
1179
1180 osd_device->ops.disable_layer(osd_device,
1181 layer->layer_info.id);
1182
1183 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_STREAMON, layerid=%d\n",
1184 layer->device_id);
1185
1186 if (V4L2_BUF_TYPE_VIDEO_OUTPUT != buf_type) {
1187 v4l2_err(&vpbe_dev->v4l2_dev, "Invalid buffer type\n");
1188 return -EINVAL;
1189 }
1190
1191 /* If file handle is not allowed IO, return error */
1192 if (!fh->io_allowed) {
1193 v4l2_err(&vpbe_dev->v4l2_dev, "No io_allowed\n");
1194 return -EACCES;
1195 }
1196 /* If Streaming is already started, return error */
1197 if (layer->started) {
1198 v4l2_err(&vpbe_dev->v4l2_dev, "layer is already streaming\n");
1199 return -EBUSY;
1200 }
1201
1202 /*
1203 * Call videobuf_streamon to start streaming
1204 * in videobuf
1205 */
1206 ret = videobuf_streamon(&layer->buffer_queue);
1207 if (ret) {
1208 v4l2_err(&vpbe_dev->v4l2_dev,
1209 "error in videobuf_streamon\n");
1210 return ret;
1211 }
1212 /* If buffer queue is empty, return error */
1213 if (list_empty(&layer->dma_queue)) {
1214 v4l2_err(&vpbe_dev->v4l2_dev, "buffer queue is empty\n");
1215 goto streamoff;
1216 }
1217 /* Get the next frame from the buffer queue */
1218 layer->next_frm = layer->cur_frm = list_entry(layer->dma_queue.next,
1219 struct videobuf_buffer, queue);
1220 /* Remove buffer from the buffer queue */
1221 list_del(&layer->cur_frm->queue);
1222 /* Mark state of the current frame to active */
1223 layer->cur_frm->state = VIDEOBUF_ACTIVE;
1224 /* Initialize field_id and started member */
1225 layer->field_id = 0;
1226
1227 /* Set parameters in OSD and VENC */
1228 ret = vpbe_set_osd_display_params(disp_dev, layer);
1229 if (ret < 0)
1230 goto streamoff;
1231
1232 /*
1233 * if request format is yuv420 semiplanar, need to
1234 * enable both video windows
1235 */
1236 layer->started = 1;
1237
1238 layer->layer_first_int = 1;
1239
1240 return ret;
1241streamoff:
1242 ret = videobuf_streamoff(&layer->buffer_queue);
1243 return ret;
1244}
1245
1246static int vpbe_display_dqbuf(struct file *file, void *priv,
1247 struct v4l2_buffer *buf)
1248{
1249 struct vpbe_fh *fh = file->private_data;
1250 struct vpbe_layer *layer = fh->layer;
1251 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
1252 int ret;
1253
1254 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
1255 "VIDIOC_DQBUF, layer id = %d\n",
1256 layer->device_id);
1257
1258 if (V4L2_BUF_TYPE_VIDEO_OUTPUT != buf->type) {
1259 v4l2_err(&vpbe_dev->v4l2_dev, "Invalid buffer type\n");
1260 return -EINVAL;
1261 }
1262 /* If this file handle is not allowed to do IO, return error */
1263 if (!fh->io_allowed) {
1264 v4l2_err(&vpbe_dev->v4l2_dev, "No io_allowed\n");
1265 return -EACCES;
1266 }
1267 if (file->f_flags & O_NONBLOCK)
1268 /* Call videobuf_dqbuf for non blocking mode */
1269 ret = videobuf_dqbuf(&layer->buffer_queue, buf, 1);
1270 else
1271 /* Call videobuf_dqbuf for blocking mode */
1272 ret = videobuf_dqbuf(&layer->buffer_queue, buf, 0);
1273
1274 return ret;
1275}
1276
1277static int vpbe_display_qbuf(struct file *file, void *priv,
1278 struct v4l2_buffer *p)
1279{
1280 struct vpbe_fh *fh = file->private_data;
1281 struct vpbe_layer *layer = fh->layer;
1282 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
1283
1284 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
1285 "VIDIOC_QBUF, layer id = %d\n",
1286 layer->device_id);
1287
1288 if (V4L2_BUF_TYPE_VIDEO_OUTPUT != p->type) {
1289 v4l2_err(&vpbe_dev->v4l2_dev, "Invalid buffer type\n");
1290 return -EINVAL;
1291 }
1292
1293 /* If this file handle is not allowed to do IO, return error */
1294 if (!fh->io_allowed) {
1295 v4l2_err(&vpbe_dev->v4l2_dev, "No io_allowed\n");
1296 return -EACCES;
1297 }
1298
1299 return videobuf_qbuf(&layer->buffer_queue, p);
1300}
1301
1302static int vpbe_display_querybuf(struct file *file, void *priv,
1303 struct v4l2_buffer *buf)
1304{
1305 struct vpbe_fh *fh = file->private_data;
1306 struct vpbe_layer *layer = fh->layer;
1307 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
1308 int ret;
1309
1310 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
1311 "VIDIOC_QUERYBUF, layer id = %d\n",
1312 layer->device_id);
1313
1314 if (V4L2_BUF_TYPE_VIDEO_OUTPUT != buf->type) {
1315 v4l2_err(&vpbe_dev->v4l2_dev, "Invalid buffer type\n");
1316 return -EINVAL;
1317 }
1318
1319 /* Call videobuf_querybuf to get information */
1320 ret = videobuf_querybuf(&layer->buffer_queue, buf);
1321
1322 return ret;
1323}
1324
1325static int vpbe_display_reqbufs(struct file *file, void *priv,
1326 struct v4l2_requestbuffers *req_buf)
1327{
1328 struct vpbe_fh *fh = file->private_data;
1329 struct vpbe_layer *layer = fh->layer;
1330 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
1331 int ret;
1332
1333 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_display_reqbufs\n");
1334
1335 if (V4L2_BUF_TYPE_VIDEO_OUTPUT != req_buf->type) {
1336 v4l2_err(&vpbe_dev->v4l2_dev, "Invalid buffer type\n");
1337 return -EINVAL;
1338 }
1339
1340 /* If io users of the layer is not zero, return error */
1341 if (0 != layer->io_usrs) {
1342 v4l2_err(&vpbe_dev->v4l2_dev, "not IO user\n");
1343 return -EBUSY;
1344 }
1345 /* Initialize videobuf queue as per the buffer type */
1346 videobuf_queue_dma_contig_init(&layer->buffer_queue,
1347 &video_qops,
1348 vpbe_dev->pdev,
1349 &layer->irqlock,
1350 V4L2_BUF_TYPE_VIDEO_OUTPUT,
1351 layer->pix_fmt.field,
1352 sizeof(struct videobuf_buffer),
1353 fh, NULL);
1354
1355 /* Set io allowed member of file handle to TRUE */
1356 fh->io_allowed = 1;
1357 /* Increment io usrs member of layer object to 1 */
1358 layer->io_usrs = 1;
1359 /* Store type of memory requested in layer object */
1360 layer->memory = req_buf->memory;
1361 /* Initialize buffer queue */
1362 INIT_LIST_HEAD(&layer->dma_queue);
1363 /* Allocate buffers */
1364 ret = videobuf_reqbufs(&layer->buffer_queue, req_buf);
1365
1366 return ret;
1367}
1368
1369/*
1370 * vpbe_display_mmap()
1371 * It is used to map kernel space buffers into user spaces
1372 */
1373static int vpbe_display_mmap(struct file *filep, struct vm_area_struct *vma)
1374{
1375 /* Get the layer object and file handle object */
1376 struct vpbe_fh *fh = filep->private_data;
1377 struct vpbe_layer *layer = fh->layer;
1378 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
1379 int ret;
1380
1381 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_display_mmap\n");
1382
1383 if (mutex_lock_interruptible(&layer->opslock))
1384 return -ERESTARTSYS;
1385 ret = videobuf_mmap_mapper(&layer->buffer_queue, vma);
1386 mutex_unlock(&layer->opslock);
1387 return ret;
1388}
1389
1390/* vpbe_display_poll(): It is used for select/poll system call
1391 */
1392static unsigned int vpbe_display_poll(struct file *filep, poll_table *wait)
1393{
1394 struct vpbe_fh *fh = filep->private_data;
1395 struct vpbe_layer *layer = fh->layer;
1396 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
1397 unsigned int err = 0;
1398
1399 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_display_poll\n");
1400 if (layer->started) {
1401 mutex_lock(&layer->opslock);
1402 err = videobuf_poll_stream(filep, &layer->buffer_queue, wait);
1403 mutex_unlock(&layer->opslock);
1404 }
1405 return err;
1406}
1407
1408/*
1409 * vpbe_display_open()
1410 * It creates object of file handle structure and stores it in private_data
1411 * member of filepointer
1412 */
1413static int vpbe_display_open(struct file *file)
1414{
1415 struct vpbe_fh *fh = NULL;
1416 struct vpbe_layer *layer = video_drvdata(file);
1417 struct vpbe_display *disp_dev = layer->disp_dev;
1418 struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
1419 struct osd_state *osd_device = disp_dev->osd_device;
1420 int err;
1421
1422 /* Allocate memory for the file handle object */
1423 fh = kmalloc(sizeof(struct vpbe_fh), GFP_KERNEL);
1424 if (fh == NULL) {
1425 v4l2_err(&vpbe_dev->v4l2_dev,
1426 "unable to allocate memory for file handle object\n");
1427 return -ENOMEM;
1428 }
1429 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
1430 "vpbe display open plane = %d\n",
1431 layer->device_id);
1432
1433 /* store pointer to fh in private_data member of filep */
1434 file->private_data = fh;
1435 fh->layer = layer;
1436 fh->disp_dev = disp_dev;
1437
1438 if (!layer->usrs) {
1439 if (mutex_lock_interruptible(&layer->opslock))
1440 return -ERESTARTSYS;
1441 /* First claim the layer for this device */
1442 err = osd_device->ops.request_layer(osd_device,
1443 layer->layer_info.id);
1444 mutex_unlock(&layer->opslock);
1445 if (err < 0) {
1446 /* Couldn't get layer */
1447 v4l2_err(&vpbe_dev->v4l2_dev,
1448 "Display Manager failed to allocate layer\n");
1449 kfree(fh);
1450 return -EINVAL;
1451 }
1452 }
1453 /* Increment layer usrs counter */
1454 layer->usrs++;
1455 /* Set io_allowed member to false */
1456 fh->io_allowed = 0;
1457 /* Initialize priority of this instance to default priority */
1458 fh->prio = V4L2_PRIORITY_UNSET;
1459 v4l2_prio_open(&layer->prio, &fh->prio);
1460 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
1461 "vpbe display device opened successfully\n");
1462 return 0;
1463}
1464
1465/*
1466 * vpbe_display_release()
1467 * This function deletes buffer queue, frees the buffers and the davinci
1468 * display file * handle
1469 */
1470static int vpbe_display_release(struct file *file)
1471{
1472 /* Get the layer object and file handle object */
1473 struct vpbe_fh *fh = file->private_data;
1474 struct vpbe_layer *layer = fh->layer;
1475 struct osd_layer_config *cfg = &layer->layer_info.config;
1476 struct vpbe_display *disp_dev = fh->disp_dev;
1477 struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
1478 struct osd_state *osd_device = disp_dev->osd_device;
1479
1480 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_display_release\n");
1481
1482 mutex_lock(&layer->opslock);
1483 /* if this instance is doing IO */
1484 if (fh->io_allowed) {
1485 /* Reset io_usrs member of layer object */
1486 layer->io_usrs = 0;
1487
1488 osd_device->ops.disable_layer(osd_device,
1489 layer->layer_info.id);
1490 layer->started = 0;
1491 /* Free buffers allocated */
1492 videobuf_queue_cancel(&layer->buffer_queue);
1493 videobuf_mmap_free(&layer->buffer_queue);
1494 }
1495
1496 /* Decrement layer usrs counter */
1497 layer->usrs--;
1498 /* If this file handle has initialize encoder device, reset it */
1499 if (!layer->usrs) {
1500 if (cfg->pixfmt == PIXFMT_NV12) {
1501 struct vpbe_layer *otherlayer;
1502 otherlayer =
1503 _vpbe_display_get_other_win_layer(disp_dev, layer);
1504 osd_device->ops.disable_layer(osd_device,
1505 otherlayer->layer_info.id);
1506 osd_device->ops.release_layer(osd_device,
1507 otherlayer->layer_info.id);
1508 }
1509 osd_device->ops.disable_layer(osd_device,
1510 layer->layer_info.id);
1511 osd_device->ops.release_layer(osd_device,
1512 layer->layer_info.id);
1513 }
1514 /* Close the priority */
1515 v4l2_prio_close(&layer->prio, fh->prio);
1516 file->private_data = NULL;
1517 mutex_unlock(&layer->opslock);
1518
1519 /* Free memory allocated to file handle object */
1520 kfree(fh);
1521
1522 disp_dev->cbcr_ofst = 0;
1523
1524 return 0;
1525}
1526
1527#ifdef CONFIG_VIDEO_ADV_DEBUG
1528static int vpbe_display_g_register(struct file *file, void *priv,
1529 struct v4l2_dbg_register *reg)
1530{
1531 struct v4l2_dbg_match *match = &reg->match;
1532 struct vpbe_fh *fh = file->private_data;
1533 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
1534
1535 if (match->type >= 2) {
1536 v4l2_subdev_call(vpbe_dev->venc,
1537 core,
1538 g_register,
1539 reg);
1540 }
1541
1542 return 0;
1543}
1544
1545static int vpbe_display_s_register(struct file *file, void *priv,
1546 struct v4l2_dbg_register *reg)
1547{
1548 return 0;
1549}
1550#endif
1551
1552/* vpbe capture ioctl operations */
1553static const struct v4l2_ioctl_ops vpbe_ioctl_ops = {
1554 .vidioc_querycap = vpbe_display_querycap,
1555 .vidioc_g_fmt_vid_out = vpbe_display_g_fmt,
1556 .vidioc_enum_fmt_vid_out = vpbe_display_enum_fmt,
1557 .vidioc_s_fmt_vid_out = vpbe_display_s_fmt,
1558 .vidioc_try_fmt_vid_out = vpbe_display_try_fmt,
1559 .vidioc_reqbufs = vpbe_display_reqbufs,
1560 .vidioc_querybuf = vpbe_display_querybuf,
1561 .vidioc_qbuf = vpbe_display_qbuf,
1562 .vidioc_dqbuf = vpbe_display_dqbuf,
1563 .vidioc_streamon = vpbe_display_streamon,
1564 .vidioc_streamoff = vpbe_display_streamoff,
1565 .vidioc_cropcap = vpbe_display_cropcap,
1566 .vidioc_g_crop = vpbe_display_g_crop,
1567 .vidioc_s_crop = vpbe_display_s_crop,
1568 .vidioc_g_priority = vpbe_display_g_priority,
1569 .vidioc_s_priority = vpbe_display_s_priority,
1570 .vidioc_s_std = vpbe_display_s_std,
1571 .vidioc_g_std = vpbe_display_g_std,
1572 .vidioc_enum_output = vpbe_display_enum_output,
1573 .vidioc_s_output = vpbe_display_s_output,
1574 .vidioc_g_output = vpbe_display_g_output,
1575 .vidioc_s_dv_preset = vpbe_display_s_dv_preset,
1576 .vidioc_g_dv_preset = vpbe_display_g_dv_preset,
1577 .vidioc_enum_dv_presets = vpbe_display_enum_dv_presets,
1578#ifdef CONFIG_VIDEO_ADV_DEBUG
1579 .vidioc_g_register = vpbe_display_g_register,
1580 .vidioc_s_register = vpbe_display_s_register,
1581#endif
1582};
1583
1584static struct v4l2_file_operations vpbe_fops = {
1585 .owner = THIS_MODULE,
1586 .open = vpbe_display_open,
1587 .release = vpbe_display_release,
1588 .unlocked_ioctl = video_ioctl2,
1589 .mmap = vpbe_display_mmap,
1590 .poll = vpbe_display_poll
1591};
1592
1593static int vpbe_device_get(struct device *dev, void *data)
1594{
1595 struct platform_device *pdev = to_platform_device(dev);
1596 struct vpbe_display *vpbe_disp = data;
1597
1598 if (strcmp("vpbe_controller", pdev->name) == 0)
1599 vpbe_disp->vpbe_dev = platform_get_drvdata(pdev);
1600
1601 if (strcmp("vpbe-osd", pdev->name) == 0)
1602 vpbe_disp->osd_device = platform_get_drvdata(pdev);
1603
1604 return 0;
1605}
1606
1607static __devinit int init_vpbe_layer(int i, struct vpbe_display *disp_dev,
1608 struct platform_device *pdev)
1609{
1610 struct vpbe_layer *vpbe_display_layer = NULL;
1611 struct video_device *vbd = NULL;
1612
1613 /* Allocate memory for four plane display objects */
1614
1615 disp_dev->dev[i] =
1616 kzalloc(sizeof(struct vpbe_layer), GFP_KERNEL);
1617
1618 /* If memory allocation fails, return error */
1619 if (!disp_dev->dev[i]) {
1620 printk(KERN_ERR "ran out of memory\n");
1621 return -ENOMEM;
1622 }
1623 spin_lock_init(&disp_dev->dev[i]->irqlock);
1624 mutex_init(&disp_dev->dev[i]->opslock);
1625
1626 /* Get the pointer to the layer object */
1627 vpbe_display_layer = disp_dev->dev[i];
1628 vbd = &vpbe_display_layer->video_dev;
1629 /* Initialize field of video device */
1630 vbd->release = video_device_release_empty;
1631 vbd->fops = &vpbe_fops;
1632 vbd->ioctl_ops = &vpbe_ioctl_ops;
1633 vbd->minor = -1;
1634 vbd->v4l2_dev = &disp_dev->vpbe_dev->v4l2_dev;
1635 vbd->lock = &vpbe_display_layer->opslock;
1636
1637 if (disp_dev->vpbe_dev->current_timings.timings_type &
1638 VPBE_ENC_STD) {
1639 vbd->tvnorms = (V4L2_STD_525_60 | V4L2_STD_625_50);
1640 vbd->current_norm =
1641 disp_dev->vpbe_dev->
1642 current_timings.timings.std_id;
1643 } else
1644 vbd->current_norm = 0;
1645
1646 snprintf(vbd->name, sizeof(vbd->name),
1647 "DaVinci_VPBE Display_DRIVER_V%d.%d.%d",
1648 (VPBE_DISPLAY_VERSION_CODE >> 16) & 0xff,
1649 (VPBE_DISPLAY_VERSION_CODE >> 8) & 0xff,
1650 (VPBE_DISPLAY_VERSION_CODE) & 0xff);
1651
1652 vpbe_display_layer->device_id = i;
1653
1654 vpbe_display_layer->layer_info.id =
1655 ((i == VPBE_DISPLAY_DEVICE_0) ? WIN_VID0 : WIN_VID1);
1656
1657 /* Initialize prio member of layer object */
1658 v4l2_prio_init(&vpbe_display_layer->prio);
1659
1660 return 0;
1661}
1662
1663static __devinit int register_device(struct vpbe_layer *vpbe_display_layer,
1664 struct vpbe_display *disp_dev,
1665 struct platform_device *pdev) {
1666 int err;
1667
1668 v4l2_info(&disp_dev->vpbe_dev->v4l2_dev,
1669 "Trying to register VPBE display device.\n");
1670 v4l2_info(&disp_dev->vpbe_dev->v4l2_dev,
1671 "layer=%x,layer->video_dev=%x\n",
1672 (int)vpbe_display_layer,
1673 (int)&vpbe_display_layer->video_dev);
1674
1675 err = video_register_device(&vpbe_display_layer->video_dev,
1676 VFL_TYPE_GRABBER,
1677 -1);
1678 if (err)
1679 return -ENODEV;
1680
1681 vpbe_display_layer->disp_dev = disp_dev;
1682 /* set the driver data in platform device */
1683 platform_set_drvdata(pdev, disp_dev);
1684 video_set_drvdata(&vpbe_display_layer->video_dev,
1685 vpbe_display_layer);
1686
1687 return 0;
1688}
1689
1690
1691
1692/*
1693 * vpbe_display_probe()
1694 * This function creates device entries by register itself to the V4L2 driver
1695 * and initializes fields of each layer objects
1696 */
1697static __devinit int vpbe_display_probe(struct platform_device *pdev)
1698{
1699 struct vpbe_layer *vpbe_display_layer;
1700 struct vpbe_display *disp_dev;
1701 struct resource *res = NULL;
1702 int k;
1703 int i;
1704 int err;
1705 int irq;
1706
1707 printk(KERN_DEBUG "vpbe_display_probe\n");
1708 /* Allocate memory for vpbe_display */
1709 disp_dev = kzalloc(sizeof(struct vpbe_display), GFP_KERNEL);
1710 if (!disp_dev) {
1711 printk(KERN_ERR "ran out of memory\n");
1712 return -ENOMEM;
1713 }
1714
1715 spin_lock_init(&disp_dev->dma_queue_lock);
1716 /*
1717 * Scan all the platform devices to find the vpbe
1718 * controller device and get the vpbe_dev object
1719 */
1720 err = bus_for_each_dev(&platform_bus_type, NULL, disp_dev,
1721 vpbe_device_get);
1722 if (err < 0)
1723 return err;
1724 /* Initialize the vpbe display controller */
1725 if (NULL != disp_dev->vpbe_dev->ops.initialize) {
1726 err = disp_dev->vpbe_dev->ops.initialize(&pdev->dev,
1727 disp_dev->vpbe_dev);
1728 if (err) {
1729 v4l2_err(&disp_dev->vpbe_dev->v4l2_dev,
1730 "Error initing vpbe\n");
1731 err = -ENOMEM;
1732 goto probe_out;
1733 }
1734 }
1735
1736 for (i = 0; i < VPBE_DISPLAY_MAX_DEVICES; i++) {
1737 if (init_vpbe_layer(i, disp_dev, pdev)) {
1738 err = -ENODEV;
1739 goto probe_out;
1740 }
1741 }
1742
1743 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
1744 if (!res) {
1745 v4l2_err(&disp_dev->vpbe_dev->v4l2_dev,
1746 "Unable to get VENC interrupt resource\n");
1747 err = -ENODEV;
1748 goto probe_out;
1749 }
1750
1751 irq = res->start;
1752 if (request_irq(irq, venc_isr, IRQF_DISABLED, VPBE_DISPLAY_DRIVER,
1753 disp_dev)) {
1754 v4l2_err(&disp_dev->vpbe_dev->v4l2_dev,
1755 "Unable to request interrupt\n");
1756 err = -ENODEV;
1757 goto probe_out;
1758 }
1759
1760 for (i = 0; i < VPBE_DISPLAY_MAX_DEVICES; i++) {
1761 if (register_device(disp_dev->dev[i], disp_dev, pdev)) {
1762 err = -ENODEV;
1763 goto probe_out_irq;
1764 }
1765 }
1766
1767 printk(KERN_DEBUG "Successfully completed the probing of vpbe v4l2 device\n");
1768 return 0;
1769
1770probe_out_irq:
1771 free_irq(res->start, disp_dev);
1772probe_out:
1773 for (k = 0; k < VPBE_DISPLAY_MAX_DEVICES; k++) {
1774 /* Get the pointer to the layer object */
1775 vpbe_display_layer = disp_dev->dev[k];
1776 /* Unregister video device */
1777 if (vpbe_display_layer) {
1778 video_unregister_device(
1779 &vpbe_display_layer->video_dev);
1780 kfree(disp_dev->dev[k]);
1781 }
1782 }
1783 kfree(disp_dev);
1784 return err;
1785}
1786
1787/*
1788 * vpbe_display_remove()
1789 * It un-register hardware layer from V4L2 driver
1790 */
1791static int vpbe_display_remove(struct platform_device *pdev)
1792{
1793 struct vpbe_layer *vpbe_display_layer;
1794 struct vpbe_display *disp_dev = platform_get_drvdata(pdev);
1795 struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
1796 struct resource *res;
1797 int i;
1798
1799 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_display_remove\n");
1800
1801 /* unregister irq */
1802 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
1803 free_irq(res->start, disp_dev);
1804
1805 /* deinitialize the vpbe display controller */
1806 if (NULL != vpbe_dev->ops.deinitialize)
1807 vpbe_dev->ops.deinitialize(&pdev->dev, vpbe_dev);
1808 /* un-register device */
1809 for (i = 0; i < VPBE_DISPLAY_MAX_DEVICES; i++) {
1810 /* Get the pointer to the layer object */
1811 vpbe_display_layer = disp_dev->dev[i];
1812 /* Unregister video device */
1813 video_unregister_device(&vpbe_display_layer->video_dev);
1814
1815 }
1816 for (i = 0; i < VPBE_DISPLAY_MAX_DEVICES; i++) {
1817 kfree(disp_dev->dev[i]);
1818 disp_dev->dev[i] = NULL;
1819 }
1820
1821 return 0;
1822}
1823
1824static struct platform_driver vpbe_display_driver = {
1825 .driver = {
1826 .name = VPBE_DISPLAY_DRIVER,
1827 .owner = THIS_MODULE,
1828 .bus = &platform_bus_type,
1829 },
1830 .probe = vpbe_display_probe,
1831 .remove = __devexit_p(vpbe_display_remove),
1832};
1833
1834module_platform_driver(vpbe_display_driver);
1835
1836MODULE_DESCRIPTION("TI DM644x/DM355/DM365 VPBE Display controller");
1837MODULE_LICENSE("GPL");
1838MODULE_AUTHOR("Texas Instruments");
diff --git a/drivers/media/video/davinci/vpbe_osd.c b/drivers/media/video/davinci/vpbe_osd.c
deleted file mode 100644
index bba299dbf396..000000000000
--- a/drivers/media/video/davinci/vpbe_osd.c
+++ /dev/null
@@ -1,1605 +0,0 @@
1/*
2 * Copyright (C) 2007-2010 Texas Instruments Inc
3 * Copyright (C) 2007 MontaVista Software, Inc.
4 *
5 * Andy Lowe (alowe@mvista.com), MontaVista Software
6 * - Initial version
7 * Murali Karicheri (mkaricheri@gmail.com), Texas Instruments Ltd.
8 * - ported to sub device interface
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation version 2.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 *
23 */
24#include <linux/module.h>
25#include <linux/kernel.h>
26#include <linux/interrupt.h>
27#include <linux/platform_device.h>
28#include <linux/clk.h>
29#include <linux/slab.h>
30
31#include <mach/cputype.h>
32#include <mach/hardware.h>
33
34#include <media/davinci/vpss.h>
35#include <media/v4l2-device.h>
36#include <media/davinci/vpbe_types.h>
37#include <media/davinci/vpbe_osd.h>
38
39#include <linux/io.h>
40#include "vpbe_osd_regs.h"
41
42#define MODULE_NAME VPBE_OSD_SUBDEV_NAME
43
44/* register access routines */
45static inline u32 osd_read(struct osd_state *sd, u32 offset)
46{
47 struct osd_state *osd = sd;
48
49 return readl(osd->osd_base + offset);
50}
51
52static inline u32 osd_write(struct osd_state *sd, u32 val, u32 offset)
53{
54 struct osd_state *osd = sd;
55
56 writel(val, osd->osd_base + offset);
57
58 return val;
59}
60
61static inline u32 osd_set(struct osd_state *sd, u32 mask, u32 offset)
62{
63 struct osd_state *osd = sd;
64
65 u32 addr = osd->osd_base + offset;
66 u32 val = readl(addr) | mask;
67
68 writel(val, addr);
69
70 return val;
71}
72
73static inline u32 osd_clear(struct osd_state *sd, u32 mask, u32 offset)
74{
75 struct osd_state *osd = sd;
76
77 u32 addr = osd->osd_base + offset;
78 u32 val = readl(addr) & ~mask;
79
80 writel(val, addr);
81
82 return val;
83}
84
85static inline u32 osd_modify(struct osd_state *sd, u32 mask, u32 val,
86 u32 offset)
87{
88 struct osd_state *osd = sd;
89
90 u32 addr = osd->osd_base + offset;
91 u32 new_val = (readl(addr) & ~mask) | (val & mask);
92
93 writel(new_val, addr);
94
95 return new_val;
96}
97
98/* define some macros for layer and pixfmt classification */
99#define is_osd_win(layer) (((layer) == WIN_OSD0) || ((layer) == WIN_OSD1))
100#define is_vid_win(layer) (((layer) == WIN_VID0) || ((layer) == WIN_VID1))
101#define is_rgb_pixfmt(pixfmt) \
102 (((pixfmt) == PIXFMT_RGB565) || ((pixfmt) == PIXFMT_RGB888))
103#define is_yc_pixfmt(pixfmt) \
104 (((pixfmt) == PIXFMT_YCbCrI) || ((pixfmt) == PIXFMT_YCrCbI) || \
105 ((pixfmt) == PIXFMT_NV12))
106#define MAX_WIN_SIZE OSD_VIDWIN0XP_V0X
107#define MAX_LINE_LENGTH (OSD_VIDWIN0OFST_V0LO << 5)
108
109/**
110 * _osd_dm6446_vid0_pingpong() - field inversion fix for DM6446
111 * @sd - ptr to struct osd_state
112 * @field_inversion - inversion flag
113 * @fb_base_phys - frame buffer address
114 * @lconfig - ptr to layer config
115 *
116 * This routine implements a workaround for the field signal inversion silicon
117 * erratum described in Advisory 1.3.8 for the DM6446. The fb_base_phys and
118 * lconfig parameters apply to the vid0 window. This routine should be called
119 * whenever the vid0 layer configuration or start address is modified, or when
120 * the OSD field inversion setting is modified.
121 * Returns: 1 if the ping-pong buffers need to be toggled in the vsync isr, or
122 * 0 otherwise
123 */
124static int _osd_dm6446_vid0_pingpong(struct osd_state *sd,
125 int field_inversion,
126 unsigned long fb_base_phys,
127 const struct osd_layer_config *lconfig)
128{
129 struct osd_platform_data *pdata;
130
131 pdata = (struct osd_platform_data *)sd->dev->platform_data;
132 if (pdata->field_inv_wa_enable) {
133
134 if (!field_inversion || !lconfig->interlaced) {
135 osd_write(sd, fb_base_phys & ~0x1F, OSD_VIDWIN0ADR);
136 osd_write(sd, fb_base_phys & ~0x1F, OSD_PPVWIN0ADR);
137 osd_modify(sd, OSD_MISCCTL_PPSW | OSD_MISCCTL_PPRV, 0,
138 OSD_MISCCTL);
139 return 0;
140 } else {
141 unsigned miscctl = OSD_MISCCTL_PPRV;
142
143 osd_write(sd,
144 (fb_base_phys & ~0x1F) - lconfig->line_length,
145 OSD_VIDWIN0ADR);
146 osd_write(sd,
147 (fb_base_phys & ~0x1F) + lconfig->line_length,
148 OSD_PPVWIN0ADR);
149 osd_modify(sd,
150 OSD_MISCCTL_PPSW | OSD_MISCCTL_PPRV, miscctl,
151 OSD_MISCCTL);
152
153 return 1;
154 }
155 }
156
157 return 0;
158}
159
160static void _osd_set_field_inversion(struct osd_state *sd, int enable)
161{
162 unsigned fsinv = 0;
163
164 if (enable)
165 fsinv = OSD_MODE_FSINV;
166
167 osd_modify(sd, OSD_MODE_FSINV, fsinv, OSD_MODE);
168}
169
170static void _osd_set_blink_attribute(struct osd_state *sd, int enable,
171 enum osd_blink_interval blink)
172{
173 u32 osdatrmd = 0;
174
175 if (enable) {
176 osdatrmd |= OSD_OSDATRMD_BLNK;
177 osdatrmd |= blink << OSD_OSDATRMD_BLNKINT_SHIFT;
178 }
179 /* caller must ensure that OSD1 is configured in attribute mode */
180 osd_modify(sd, OSD_OSDATRMD_BLNKINT | OSD_OSDATRMD_BLNK, osdatrmd,
181 OSD_OSDATRMD);
182}
183
184static void _osd_set_rom_clut(struct osd_state *sd,
185 enum osd_rom_clut rom_clut)
186{
187 if (rom_clut == ROM_CLUT0)
188 osd_clear(sd, OSD_MISCCTL_RSEL, OSD_MISCCTL);
189 else
190 osd_set(sd, OSD_MISCCTL_RSEL, OSD_MISCCTL);
191}
192
193static void _osd_set_palette_map(struct osd_state *sd,
194 enum osd_win_layer osdwin,
195 unsigned char pixel_value,
196 unsigned char clut_index,
197 enum osd_pix_format pixfmt)
198{
199 static const int map_2bpp[] = { 0, 5, 10, 15 };
200 static const int map_1bpp[] = { 0, 15 };
201 int bmp_offset;
202 int bmp_shift;
203 int bmp_mask;
204 int bmp_reg;
205
206 switch (pixfmt) {
207 case PIXFMT_1BPP:
208 bmp_reg = map_1bpp[pixel_value & 0x1];
209 break;
210 case PIXFMT_2BPP:
211 bmp_reg = map_2bpp[pixel_value & 0x3];
212 break;
213 case PIXFMT_4BPP:
214 bmp_reg = pixel_value & 0xf;
215 break;
216 default:
217 return;
218 }
219
220 switch (osdwin) {
221 case OSDWIN_OSD0:
222 bmp_offset = OSD_W0BMP01 + (bmp_reg >> 1) * sizeof(u32);
223 break;
224 case OSDWIN_OSD1:
225 bmp_offset = OSD_W1BMP01 + (bmp_reg >> 1) * sizeof(u32);
226 break;
227 default:
228 return;
229 }
230
231 if (bmp_reg & 1) {
232 bmp_shift = 8;
233 bmp_mask = 0xff << 8;
234 } else {
235 bmp_shift = 0;
236 bmp_mask = 0xff;
237 }
238
239 osd_modify(sd, bmp_mask, clut_index << bmp_shift, bmp_offset);
240}
241
242static void _osd_set_rec601_attenuation(struct osd_state *sd,
243 enum osd_win_layer osdwin, int enable)
244{
245 switch (osdwin) {
246 case OSDWIN_OSD0:
247 osd_modify(sd, OSD_OSDWIN0MD_ATN0E,
248 enable ? OSD_OSDWIN0MD_ATN0E : 0,
249 OSD_OSDWIN0MD);
250 if (sd->vpbe_type == VPBE_VERSION_1)
251 osd_modify(sd, OSD_OSDWIN0MD_ATN0E,
252 enable ? OSD_OSDWIN0MD_ATN0E : 0,
253 OSD_OSDWIN0MD);
254 else if ((sd->vpbe_type == VPBE_VERSION_3) ||
255 (sd->vpbe_type == VPBE_VERSION_2))
256 osd_modify(sd, OSD_EXTMODE_ATNOSD0EN,
257 enable ? OSD_EXTMODE_ATNOSD0EN : 0,
258 OSD_EXTMODE);
259 break;
260 case OSDWIN_OSD1:
261 osd_modify(sd, OSD_OSDWIN1MD_ATN1E,
262 enable ? OSD_OSDWIN1MD_ATN1E : 0,
263 OSD_OSDWIN1MD);
264 if (sd->vpbe_type == VPBE_VERSION_1)
265 osd_modify(sd, OSD_OSDWIN1MD_ATN1E,
266 enable ? OSD_OSDWIN1MD_ATN1E : 0,
267 OSD_OSDWIN1MD);
268 else if ((sd->vpbe_type == VPBE_VERSION_3) ||
269 (sd->vpbe_type == VPBE_VERSION_2))
270 osd_modify(sd, OSD_EXTMODE_ATNOSD1EN,
271 enable ? OSD_EXTMODE_ATNOSD1EN : 0,
272 OSD_EXTMODE);
273 break;
274 }
275}
276
277static void _osd_set_blending_factor(struct osd_state *sd,
278 enum osd_win_layer osdwin,
279 enum osd_blending_factor blend)
280{
281 switch (osdwin) {
282 case OSDWIN_OSD0:
283 osd_modify(sd, OSD_OSDWIN0MD_BLND0,
284 blend << OSD_OSDWIN0MD_BLND0_SHIFT, OSD_OSDWIN0MD);
285 break;
286 case OSDWIN_OSD1:
287 osd_modify(sd, OSD_OSDWIN1MD_BLND1,
288 blend << OSD_OSDWIN1MD_BLND1_SHIFT, OSD_OSDWIN1MD);
289 break;
290 }
291}
292
293static void _osd_enable_rgb888_pixblend(struct osd_state *sd,
294 enum osd_win_layer osdwin)
295{
296
297 osd_modify(sd, OSD_MISCCTL_BLDSEL, 0, OSD_MISCCTL);
298 switch (osdwin) {
299 case OSDWIN_OSD0:
300 osd_modify(sd, OSD_EXTMODE_OSD0BLDCHR,
301 OSD_EXTMODE_OSD0BLDCHR, OSD_EXTMODE);
302 break;
303 case OSDWIN_OSD1:
304 osd_modify(sd, OSD_EXTMODE_OSD1BLDCHR,
305 OSD_EXTMODE_OSD1BLDCHR, OSD_EXTMODE);
306 break;
307 }
308}
309
310static void _osd_enable_color_key(struct osd_state *sd,
311 enum osd_win_layer osdwin,
312 unsigned colorkey,
313 enum osd_pix_format pixfmt)
314{
315 switch (pixfmt) {
316 case PIXFMT_1BPP:
317 case PIXFMT_2BPP:
318 case PIXFMT_4BPP:
319 case PIXFMT_8BPP:
320 if (sd->vpbe_type == VPBE_VERSION_3) {
321 switch (osdwin) {
322 case OSDWIN_OSD0:
323 osd_modify(sd, OSD_TRANSPBMPIDX_BMP0,
324 colorkey <<
325 OSD_TRANSPBMPIDX_BMP0_SHIFT,
326 OSD_TRANSPBMPIDX);
327 break;
328 case OSDWIN_OSD1:
329 osd_modify(sd, OSD_TRANSPBMPIDX_BMP1,
330 colorkey <<
331 OSD_TRANSPBMPIDX_BMP1_SHIFT,
332 OSD_TRANSPBMPIDX);
333 break;
334 }
335 }
336 break;
337 case PIXFMT_RGB565:
338 if (sd->vpbe_type == VPBE_VERSION_1)
339 osd_write(sd, colorkey & OSD_TRANSPVAL_RGBTRANS,
340 OSD_TRANSPVAL);
341 else if (sd->vpbe_type == VPBE_VERSION_3)
342 osd_write(sd, colorkey & OSD_TRANSPVALL_RGBL,
343 OSD_TRANSPVALL);
344 break;
345 case PIXFMT_YCbCrI:
346 case PIXFMT_YCrCbI:
347 if (sd->vpbe_type == VPBE_VERSION_3)
348 osd_modify(sd, OSD_TRANSPVALU_Y, colorkey,
349 OSD_TRANSPVALU);
350 break;
351 case PIXFMT_RGB888:
352 if (sd->vpbe_type == VPBE_VERSION_3) {
353 osd_write(sd, colorkey & OSD_TRANSPVALL_RGBL,
354 OSD_TRANSPVALL);
355 osd_modify(sd, OSD_TRANSPVALU_RGBU, colorkey >> 16,
356 OSD_TRANSPVALU);
357 }
358 break;
359 default:
360 break;
361 }
362
363 switch (osdwin) {
364 case OSDWIN_OSD0:
365 osd_set(sd, OSD_OSDWIN0MD_TE0, OSD_OSDWIN0MD);
366 break;
367 case OSDWIN_OSD1:
368 osd_set(sd, OSD_OSDWIN1MD_TE1, OSD_OSDWIN1MD);
369 break;
370 }
371}
372
373static void _osd_disable_color_key(struct osd_state *sd,
374 enum osd_win_layer osdwin)
375{
376 switch (osdwin) {
377 case OSDWIN_OSD0:
378 osd_clear(sd, OSD_OSDWIN0MD_TE0, OSD_OSDWIN0MD);
379 break;
380 case OSDWIN_OSD1:
381 osd_clear(sd, OSD_OSDWIN1MD_TE1, OSD_OSDWIN1MD);
382 break;
383 }
384}
385
386static void _osd_set_osd_clut(struct osd_state *sd,
387 enum osd_win_layer osdwin,
388 enum osd_clut clut)
389{
390 u32 winmd = 0;
391
392 switch (osdwin) {
393 case OSDWIN_OSD0:
394 if (clut == RAM_CLUT)
395 winmd |= OSD_OSDWIN0MD_CLUTS0;
396 osd_modify(sd, OSD_OSDWIN0MD_CLUTS0, winmd, OSD_OSDWIN0MD);
397 break;
398 case OSDWIN_OSD1:
399 if (clut == RAM_CLUT)
400 winmd |= OSD_OSDWIN1MD_CLUTS1;
401 osd_modify(sd, OSD_OSDWIN1MD_CLUTS1, winmd, OSD_OSDWIN1MD);
402 break;
403 }
404}
405
406static void _osd_set_zoom(struct osd_state *sd, enum osd_layer layer,
407 enum osd_zoom_factor h_zoom,
408 enum osd_zoom_factor v_zoom)
409{
410 u32 winmd = 0;
411
412 switch (layer) {
413 case WIN_OSD0:
414 winmd |= (h_zoom << OSD_OSDWIN0MD_OHZ0_SHIFT);
415 winmd |= (v_zoom << OSD_OSDWIN0MD_OVZ0_SHIFT);
416 osd_modify(sd, OSD_OSDWIN0MD_OHZ0 | OSD_OSDWIN0MD_OVZ0, winmd,
417 OSD_OSDWIN0MD);
418 break;
419 case WIN_VID0:
420 winmd |= (h_zoom << OSD_VIDWINMD_VHZ0_SHIFT);
421 winmd |= (v_zoom << OSD_VIDWINMD_VVZ0_SHIFT);
422 osd_modify(sd, OSD_VIDWINMD_VHZ0 | OSD_VIDWINMD_VVZ0, winmd,
423 OSD_VIDWINMD);
424 break;
425 case WIN_OSD1:
426 winmd |= (h_zoom << OSD_OSDWIN1MD_OHZ1_SHIFT);
427 winmd |= (v_zoom << OSD_OSDWIN1MD_OVZ1_SHIFT);
428 osd_modify(sd, OSD_OSDWIN1MD_OHZ1 | OSD_OSDWIN1MD_OVZ1, winmd,
429 OSD_OSDWIN1MD);
430 break;
431 case WIN_VID1:
432 winmd |= (h_zoom << OSD_VIDWINMD_VHZ1_SHIFT);
433 winmd |= (v_zoom << OSD_VIDWINMD_VVZ1_SHIFT);
434 osd_modify(sd, OSD_VIDWINMD_VHZ1 | OSD_VIDWINMD_VVZ1, winmd,
435 OSD_VIDWINMD);
436 break;
437 }
438}
439
440static void _osd_disable_layer(struct osd_state *sd, enum osd_layer layer)
441{
442 switch (layer) {
443 case WIN_OSD0:
444 osd_clear(sd, OSD_OSDWIN0MD_OACT0, OSD_OSDWIN0MD);
445 break;
446 case WIN_VID0:
447 osd_clear(sd, OSD_VIDWINMD_ACT0, OSD_VIDWINMD);
448 break;
449 case WIN_OSD1:
450 /* disable attribute mode as well as disabling the window */
451 osd_clear(sd, OSD_OSDWIN1MD_OASW | OSD_OSDWIN1MD_OACT1,
452 OSD_OSDWIN1MD);
453 break;
454 case WIN_VID1:
455 osd_clear(sd, OSD_VIDWINMD_ACT1, OSD_VIDWINMD);
456 break;
457 }
458}
459
460static void osd_disable_layer(struct osd_state *sd, enum osd_layer layer)
461{
462 struct osd_state *osd = sd;
463 struct osd_window_state *win = &osd->win[layer];
464 unsigned long flags;
465
466 spin_lock_irqsave(&osd->lock, flags);
467
468 if (!win->is_enabled) {
469 spin_unlock_irqrestore(&osd->lock, flags);
470 return;
471 }
472 win->is_enabled = 0;
473
474 _osd_disable_layer(sd, layer);
475
476 spin_unlock_irqrestore(&osd->lock, flags);
477}
478
479static void _osd_enable_attribute_mode(struct osd_state *sd)
480{
481 /* enable attribute mode for OSD1 */
482 osd_set(sd, OSD_OSDWIN1MD_OASW, OSD_OSDWIN1MD);
483}
484
485static void _osd_enable_layer(struct osd_state *sd, enum osd_layer layer)
486{
487 switch (layer) {
488 case WIN_OSD0:
489 osd_set(sd, OSD_OSDWIN0MD_OACT0, OSD_OSDWIN0MD);
490 break;
491 case WIN_VID0:
492 osd_set(sd, OSD_VIDWINMD_ACT0, OSD_VIDWINMD);
493 break;
494 case WIN_OSD1:
495 /* enable OSD1 and disable attribute mode */
496 osd_modify(sd, OSD_OSDWIN1MD_OASW | OSD_OSDWIN1MD_OACT1,
497 OSD_OSDWIN1MD_OACT1, OSD_OSDWIN1MD);
498 break;
499 case WIN_VID1:
500 osd_set(sd, OSD_VIDWINMD_ACT1, OSD_VIDWINMD);
501 break;
502 }
503}
504
505static int osd_enable_layer(struct osd_state *sd, enum osd_layer layer,
506 int otherwin)
507{
508 struct osd_state *osd = sd;
509 struct osd_window_state *win = &osd->win[layer];
510 struct osd_layer_config *cfg = &win->lconfig;
511 unsigned long flags;
512
513 spin_lock_irqsave(&osd->lock, flags);
514
515 /*
516 * use otherwin flag to know this is the other vid window
517 * in YUV420 mode, if is, skip this check
518 */
519 if (!otherwin && (!win->is_allocated ||
520 !win->fb_base_phys ||
521 !cfg->line_length ||
522 !cfg->xsize ||
523 !cfg->ysize)) {
524 spin_unlock_irqrestore(&osd->lock, flags);
525 return -1;
526 }
527
528 if (win->is_enabled) {
529 spin_unlock_irqrestore(&osd->lock, flags);
530 return 0;
531 }
532 win->is_enabled = 1;
533
534 if (cfg->pixfmt != PIXFMT_OSD_ATTR)
535 _osd_enable_layer(sd, layer);
536 else {
537 _osd_enable_attribute_mode(sd);
538 _osd_set_blink_attribute(sd, osd->is_blinking, osd->blink);
539 }
540
541 spin_unlock_irqrestore(&osd->lock, flags);
542
543 return 0;
544}
545
546#define OSD_SRC_ADDR_HIGH4 0x7800000
547#define OSD_SRC_ADDR_HIGH7 0x7F0000
548#define OSD_SRCADD_OFSET_SFT 23
549#define OSD_SRCADD_ADD_SFT 16
550#define OSD_WINADL_MASK 0xFFFF
551#define OSD_WINOFST_MASK 0x1000
552#define VPBE_REG_BASE 0x80000000
553
554static void _osd_start_layer(struct osd_state *sd, enum osd_layer layer,
555 unsigned long fb_base_phys,
556 unsigned long cbcr_ofst)
557{
558
559 if (sd->vpbe_type == VPBE_VERSION_1) {
560 switch (layer) {
561 case WIN_OSD0:
562 osd_write(sd, fb_base_phys & ~0x1F, OSD_OSDWIN0ADR);
563 break;
564 case WIN_VID0:
565 osd_write(sd, fb_base_phys & ~0x1F, OSD_VIDWIN0ADR);
566 break;
567 case WIN_OSD1:
568 osd_write(sd, fb_base_phys & ~0x1F, OSD_OSDWIN1ADR);
569 break;
570 case WIN_VID1:
571 osd_write(sd, fb_base_phys & ~0x1F, OSD_VIDWIN1ADR);
572 break;
573 }
574 } else if (sd->vpbe_type == VPBE_VERSION_3) {
575 unsigned long fb_offset_32 =
576 (fb_base_phys - VPBE_REG_BASE) >> 5;
577
578 switch (layer) {
579 case WIN_OSD0:
580 osd_modify(sd, OSD_OSDWINADH_O0AH,
581 fb_offset_32 >> (OSD_SRCADD_ADD_SFT -
582 OSD_OSDWINADH_O0AH_SHIFT),
583 OSD_OSDWINADH);
584 osd_write(sd, fb_offset_32 & OSD_OSDWIN0ADL_O0AL,
585 OSD_OSDWIN0ADL);
586 break;
587 case WIN_VID0:
588 osd_modify(sd, OSD_VIDWINADH_V0AH,
589 fb_offset_32 >> (OSD_SRCADD_ADD_SFT -
590 OSD_VIDWINADH_V0AH_SHIFT),
591 OSD_VIDWINADH);
592 osd_write(sd, fb_offset_32 & OSD_VIDWIN0ADL_V0AL,
593 OSD_VIDWIN0ADL);
594 break;
595 case WIN_OSD1:
596 osd_modify(sd, OSD_OSDWINADH_O1AH,
597 fb_offset_32 >> (OSD_SRCADD_ADD_SFT -
598 OSD_OSDWINADH_O1AH_SHIFT),
599 OSD_OSDWINADH);
600 osd_write(sd, fb_offset_32 & OSD_OSDWIN1ADL_O1AL,
601 OSD_OSDWIN1ADL);
602 break;
603 case WIN_VID1:
604 osd_modify(sd, OSD_VIDWINADH_V1AH,
605 fb_offset_32 >> (OSD_SRCADD_ADD_SFT -
606 OSD_VIDWINADH_V1AH_SHIFT),
607 OSD_VIDWINADH);
608 osd_write(sd, fb_offset_32 & OSD_VIDWIN1ADL_V1AL,
609 OSD_VIDWIN1ADL);
610 break;
611 }
612 } else if (sd->vpbe_type == VPBE_VERSION_2) {
613 struct osd_window_state *win = &sd->win[layer];
614 unsigned long fb_offset_32, cbcr_offset_32;
615
616 fb_offset_32 = fb_base_phys - VPBE_REG_BASE;
617 if (cbcr_ofst)
618 cbcr_offset_32 = cbcr_ofst;
619 else
620 cbcr_offset_32 = win->lconfig.line_length *
621 win->lconfig.ysize;
622 cbcr_offset_32 += fb_offset_32;
623 fb_offset_32 = fb_offset_32 >> 5;
624 cbcr_offset_32 = cbcr_offset_32 >> 5;
625 /*
626 * DM365: start address is 27-bit long address b26 - b23 are
627 * in offset register b12 - b9, and * bit 26 has to be '1'
628 */
629 if (win->lconfig.pixfmt == PIXFMT_NV12) {
630 switch (layer) {
631 case WIN_VID0:
632 case WIN_VID1:
633 /* Y is in VID0 */
634 osd_modify(sd, OSD_VIDWIN0OFST_V0AH,
635 ((fb_offset_32 & OSD_SRC_ADDR_HIGH4) >>
636 (OSD_SRCADD_OFSET_SFT -
637 OSD_WINOFST_AH_SHIFT)) |
638 OSD_WINOFST_MASK, OSD_VIDWIN0OFST);
639 osd_modify(sd, OSD_VIDWINADH_V0AH,
640 (fb_offset_32 & OSD_SRC_ADDR_HIGH7) >>
641 (OSD_SRCADD_ADD_SFT -
642 OSD_VIDWINADH_V0AH_SHIFT),
643 OSD_VIDWINADH);
644 osd_write(sd, fb_offset_32 & OSD_WINADL_MASK,
645 OSD_VIDWIN0ADL);
646 /* CbCr is in VID1 */
647 osd_modify(sd, OSD_VIDWIN1OFST_V1AH,
648 ((cbcr_offset_32 &
649 OSD_SRC_ADDR_HIGH4) >>
650 (OSD_SRCADD_OFSET_SFT -
651 OSD_WINOFST_AH_SHIFT)) |
652 OSD_WINOFST_MASK, OSD_VIDWIN1OFST);
653 osd_modify(sd, OSD_VIDWINADH_V1AH,
654 (cbcr_offset_32 &
655 OSD_SRC_ADDR_HIGH7) >>
656 (OSD_SRCADD_ADD_SFT -
657 OSD_VIDWINADH_V1AH_SHIFT),
658 OSD_VIDWINADH);
659 osd_write(sd, cbcr_offset_32 & OSD_WINADL_MASK,
660 OSD_VIDWIN1ADL);
661 break;
662 default:
663 break;
664 }
665 }
666
667 switch (layer) {
668 case WIN_OSD0:
669 osd_modify(sd, OSD_OSDWIN0OFST_O0AH,
670 ((fb_offset_32 & OSD_SRC_ADDR_HIGH4) >>
671 (OSD_SRCADD_OFSET_SFT -
672 OSD_WINOFST_AH_SHIFT)) | OSD_WINOFST_MASK,
673 OSD_OSDWIN0OFST);
674 osd_modify(sd, OSD_OSDWINADH_O0AH,
675 (fb_offset_32 & OSD_SRC_ADDR_HIGH7) >>
676 (OSD_SRCADD_ADD_SFT -
677 OSD_OSDWINADH_O0AH_SHIFT), OSD_OSDWINADH);
678 osd_write(sd, fb_offset_32 & OSD_WINADL_MASK,
679 OSD_OSDWIN0ADL);
680 break;
681 case WIN_VID0:
682 if (win->lconfig.pixfmt != PIXFMT_NV12) {
683 osd_modify(sd, OSD_VIDWIN0OFST_V0AH,
684 ((fb_offset_32 & OSD_SRC_ADDR_HIGH4) >>
685 (OSD_SRCADD_OFSET_SFT -
686 OSD_WINOFST_AH_SHIFT)) |
687 OSD_WINOFST_MASK, OSD_VIDWIN0OFST);
688 osd_modify(sd, OSD_VIDWINADH_V0AH,
689 (fb_offset_32 & OSD_SRC_ADDR_HIGH7) >>
690 (OSD_SRCADD_ADD_SFT -
691 OSD_VIDWINADH_V0AH_SHIFT),
692 OSD_VIDWINADH);
693 osd_write(sd, fb_offset_32 & OSD_WINADL_MASK,
694 OSD_VIDWIN0ADL);
695 }
696 break;
697 case WIN_OSD1:
698 osd_modify(sd, OSD_OSDWIN1OFST_O1AH,
699 ((fb_offset_32 & OSD_SRC_ADDR_HIGH4) >>
700 (OSD_SRCADD_OFSET_SFT -
701 OSD_WINOFST_AH_SHIFT)) | OSD_WINOFST_MASK,
702 OSD_OSDWIN1OFST);
703 osd_modify(sd, OSD_OSDWINADH_O1AH,
704 (fb_offset_32 & OSD_SRC_ADDR_HIGH7) >>
705 (OSD_SRCADD_ADD_SFT -
706 OSD_OSDWINADH_O1AH_SHIFT),
707 OSD_OSDWINADH);
708 osd_write(sd, fb_offset_32 & OSD_WINADL_MASK,
709 OSD_OSDWIN1ADL);
710 break;
711 case WIN_VID1:
712 if (win->lconfig.pixfmt != PIXFMT_NV12) {
713 osd_modify(sd, OSD_VIDWIN1OFST_V1AH,
714 ((fb_offset_32 & OSD_SRC_ADDR_HIGH4) >>
715 (OSD_SRCADD_OFSET_SFT -
716 OSD_WINOFST_AH_SHIFT)) |
717 OSD_WINOFST_MASK, OSD_VIDWIN1OFST);
718 osd_modify(sd, OSD_VIDWINADH_V1AH,
719 (fb_offset_32 & OSD_SRC_ADDR_HIGH7) >>
720 (OSD_SRCADD_ADD_SFT -
721 OSD_VIDWINADH_V1AH_SHIFT),
722 OSD_VIDWINADH);
723 osd_write(sd, fb_offset_32 & OSD_WINADL_MASK,
724 OSD_VIDWIN1ADL);
725 }
726 break;
727 }
728 }
729}
730
731static void osd_start_layer(struct osd_state *sd, enum osd_layer layer,
732 unsigned long fb_base_phys,
733 unsigned long cbcr_ofst)
734{
735 struct osd_state *osd = sd;
736 struct osd_window_state *win = &osd->win[layer];
737 struct osd_layer_config *cfg = &win->lconfig;
738 unsigned long flags;
739
740 spin_lock_irqsave(&osd->lock, flags);
741
742 win->fb_base_phys = fb_base_phys & ~0x1F;
743 _osd_start_layer(sd, layer, fb_base_phys, cbcr_ofst);
744
745 if (layer == WIN_VID0) {
746 osd->pingpong =
747 _osd_dm6446_vid0_pingpong(sd, osd->field_inversion,
748 win->fb_base_phys,
749 cfg);
750 }
751
752 spin_unlock_irqrestore(&osd->lock, flags);
753}
754
755static void osd_get_layer_config(struct osd_state *sd, enum osd_layer layer,
756 struct osd_layer_config *lconfig)
757{
758 struct osd_state *osd = sd;
759 struct osd_window_state *win = &osd->win[layer];
760 unsigned long flags;
761
762 spin_lock_irqsave(&osd->lock, flags);
763
764 *lconfig = win->lconfig;
765
766 spin_unlock_irqrestore(&osd->lock, flags);
767}
768
769/**
770 * try_layer_config() - Try a specific configuration for the layer
771 * @sd - ptr to struct osd_state
772 * @layer - layer to configure
773 * @lconfig - layer configuration to try
774 *
775 * If the requested lconfig is completely rejected and the value of lconfig on
776 * exit is the current lconfig, then try_layer_config() returns 1. Otherwise,
777 * try_layer_config() returns 0. A return value of 0 does not necessarily mean
778 * that the value of lconfig on exit is identical to the value of lconfig on
779 * entry, but merely that it represents a change from the current lconfig.
780 */
781static int try_layer_config(struct osd_state *sd, enum osd_layer layer,
782 struct osd_layer_config *lconfig)
783{
784 struct osd_state *osd = sd;
785 struct osd_window_state *win = &osd->win[layer];
786 int bad_config = 0;
787
788 /* verify that the pixel format is compatible with the layer */
789 switch (lconfig->pixfmt) {
790 case PIXFMT_1BPP:
791 case PIXFMT_2BPP:
792 case PIXFMT_4BPP:
793 case PIXFMT_8BPP:
794 case PIXFMT_RGB565:
795 if (osd->vpbe_type == VPBE_VERSION_1)
796 bad_config = !is_vid_win(layer);
797 break;
798 case PIXFMT_YCbCrI:
799 case PIXFMT_YCrCbI:
800 bad_config = !is_vid_win(layer);
801 break;
802 case PIXFMT_RGB888:
803 if (osd->vpbe_type == VPBE_VERSION_1)
804 bad_config = !is_vid_win(layer);
805 else if ((osd->vpbe_type == VPBE_VERSION_3) ||
806 (osd->vpbe_type == VPBE_VERSION_2))
807 bad_config = !is_osd_win(layer);
808 break;
809 case PIXFMT_NV12:
810 if (osd->vpbe_type != VPBE_VERSION_2)
811 bad_config = 1;
812 else
813 bad_config = is_osd_win(layer);
814 break;
815 case PIXFMT_OSD_ATTR:
816 bad_config = (layer != WIN_OSD1);
817 break;
818 default:
819 bad_config = 1;
820 break;
821 }
822 if (bad_config) {
823 /*
824 * The requested pixel format is incompatible with the layer,
825 * so keep the current layer configuration.
826 */
827 *lconfig = win->lconfig;
828 return bad_config;
829 }
830
831 /* DM6446: */
832 /* only one OSD window at a time can use RGB pixel formats */
833 if ((osd->vpbe_type == VPBE_VERSION_1) &&
834 is_osd_win(layer) && is_rgb_pixfmt(lconfig->pixfmt)) {
835 enum osd_pix_format pixfmt;
836 if (layer == WIN_OSD0)
837 pixfmt = osd->win[WIN_OSD1].lconfig.pixfmt;
838 else
839 pixfmt = osd->win[WIN_OSD0].lconfig.pixfmt;
840
841 if (is_rgb_pixfmt(pixfmt)) {
842 /*
843 * The other OSD window is already configured for an
844 * RGB, so keep the current layer configuration.
845 */
846 *lconfig = win->lconfig;
847 return 1;
848 }
849 }
850
851 /* DM6446: only one video window at a time can use RGB888 */
852 if ((osd->vpbe_type == VPBE_VERSION_1) && is_vid_win(layer) &&
853 lconfig->pixfmt == PIXFMT_RGB888) {
854 enum osd_pix_format pixfmt;
855
856 if (layer == WIN_VID0)
857 pixfmt = osd->win[WIN_VID1].lconfig.pixfmt;
858 else
859 pixfmt = osd->win[WIN_VID0].lconfig.pixfmt;
860
861 if (pixfmt == PIXFMT_RGB888) {
862 /*
863 * The other video window is already configured for
864 * RGB888, so keep the current layer configuration.
865 */
866 *lconfig = win->lconfig;
867 return 1;
868 }
869 }
870
871 /* window dimensions must be non-zero */
872 if (!lconfig->line_length || !lconfig->xsize || !lconfig->ysize) {
873 *lconfig = win->lconfig;
874 return 1;
875 }
876
877 /* round line_length up to a multiple of 32 */
878 lconfig->line_length = ((lconfig->line_length + 31) / 32) * 32;
879 lconfig->line_length =
880 min(lconfig->line_length, (unsigned)MAX_LINE_LENGTH);
881 lconfig->xsize = min(lconfig->xsize, (unsigned)MAX_WIN_SIZE);
882 lconfig->ysize = min(lconfig->ysize, (unsigned)MAX_WIN_SIZE);
883 lconfig->xpos = min(lconfig->xpos, (unsigned)MAX_WIN_SIZE);
884 lconfig->ypos = min(lconfig->ypos, (unsigned)MAX_WIN_SIZE);
885 lconfig->interlaced = (lconfig->interlaced != 0);
886 if (lconfig->interlaced) {
887 /* ysize and ypos must be even for interlaced displays */
888 lconfig->ysize &= ~1;
889 lconfig->ypos &= ~1;
890 }
891
892 return 0;
893}
894
895static void _osd_disable_vid_rgb888(struct osd_state *sd)
896{
897 /*
898 * The DM6446 supports RGB888 pixel format in a single video window.
899 * This routine disables RGB888 pixel format for both video windows.
900 * The caller must ensure that neither video window is currently
901 * configured for RGB888 pixel format.
902 */
903 if (sd->vpbe_type == VPBE_VERSION_1)
904 osd_clear(sd, OSD_MISCCTL_RGBEN, OSD_MISCCTL);
905}
906
907static void _osd_enable_vid_rgb888(struct osd_state *sd,
908 enum osd_layer layer)
909{
910 /*
911 * The DM6446 supports RGB888 pixel format in a single video window.
912 * This routine enables RGB888 pixel format for the specified video
913 * window. The caller must ensure that the other video window is not
914 * currently configured for RGB888 pixel format, as this routine will
915 * disable RGB888 pixel format for the other window.
916 */
917 if (sd->vpbe_type == VPBE_VERSION_1) {
918 if (layer == WIN_VID0)
919 osd_modify(sd, OSD_MISCCTL_RGBEN | OSD_MISCCTL_RGBWIN,
920 OSD_MISCCTL_RGBEN, OSD_MISCCTL);
921 else if (layer == WIN_VID1)
922 osd_modify(sd, OSD_MISCCTL_RGBEN | OSD_MISCCTL_RGBWIN,
923 OSD_MISCCTL_RGBEN | OSD_MISCCTL_RGBWIN,
924 OSD_MISCCTL);
925 }
926}
927
928static void _osd_set_cbcr_order(struct osd_state *sd,
929 enum osd_pix_format pixfmt)
930{
931 /*
932 * The caller must ensure that all windows using YC pixfmt use the same
933 * Cb/Cr order.
934 */
935 if (pixfmt == PIXFMT_YCbCrI)
936 osd_clear(sd, OSD_MODE_CS, OSD_MODE);
937 else if (pixfmt == PIXFMT_YCrCbI)
938 osd_set(sd, OSD_MODE_CS, OSD_MODE);
939}
940
941static void _osd_set_layer_config(struct osd_state *sd, enum osd_layer layer,
942 const struct osd_layer_config *lconfig)
943{
944 u32 winmd = 0, winmd_mask = 0, bmw = 0;
945
946 _osd_set_cbcr_order(sd, lconfig->pixfmt);
947
948 switch (layer) {
949 case WIN_OSD0:
950 if (sd->vpbe_type == VPBE_VERSION_1) {
951 winmd_mask |= OSD_OSDWIN0MD_RGB0E;
952 if (lconfig->pixfmt == PIXFMT_RGB565)
953 winmd |= OSD_OSDWIN0MD_RGB0E;
954 } else if ((sd->vpbe_type == VPBE_VERSION_3) ||
955 (sd->vpbe_type == VPBE_VERSION_2)) {
956 winmd_mask |= OSD_OSDWIN0MD_BMP0MD;
957 switch (lconfig->pixfmt) {
958 case PIXFMT_RGB565:
959 winmd |= (1 <<
960 OSD_OSDWIN0MD_BMP0MD_SHIFT);
961 break;
962 case PIXFMT_RGB888:
963 winmd |= (2 << OSD_OSDWIN0MD_BMP0MD_SHIFT);
964 _osd_enable_rgb888_pixblend(sd, OSDWIN_OSD0);
965 break;
966 case PIXFMT_YCbCrI:
967 case PIXFMT_YCrCbI:
968 winmd |= (3 << OSD_OSDWIN0MD_BMP0MD_SHIFT);
969 break;
970 default:
971 break;
972 }
973 }
974
975 winmd_mask |= OSD_OSDWIN0MD_BMW0 | OSD_OSDWIN0MD_OFF0;
976
977 switch (lconfig->pixfmt) {
978 case PIXFMT_1BPP:
979 bmw = 0;
980 break;
981 case PIXFMT_2BPP:
982 bmw = 1;
983 break;
984 case PIXFMT_4BPP:
985 bmw = 2;
986 break;
987 case PIXFMT_8BPP:
988 bmw = 3;
989 break;
990 default:
991 break;
992 }
993 winmd |= (bmw << OSD_OSDWIN0MD_BMW0_SHIFT);
994
995 if (lconfig->interlaced)
996 winmd |= OSD_OSDWIN0MD_OFF0;
997
998 osd_modify(sd, winmd_mask, winmd, OSD_OSDWIN0MD);
999 osd_write(sd, lconfig->line_length >> 5, OSD_OSDWIN0OFST);
1000 osd_write(sd, lconfig->xpos, OSD_OSDWIN0XP);
1001 osd_write(sd, lconfig->xsize, OSD_OSDWIN0XL);
1002 if (lconfig->interlaced) {
1003 osd_write(sd, lconfig->ypos >> 1, OSD_OSDWIN0YP);
1004 osd_write(sd, lconfig->ysize >> 1, OSD_OSDWIN0YL);
1005 } else {
1006 osd_write(sd, lconfig->ypos, OSD_OSDWIN0YP);
1007 osd_write(sd, lconfig->ysize, OSD_OSDWIN0YL);
1008 }
1009 break;
1010 case WIN_VID0:
1011 winmd_mask |= OSD_VIDWINMD_VFF0;
1012 if (lconfig->interlaced)
1013 winmd |= OSD_VIDWINMD_VFF0;
1014
1015 osd_modify(sd, winmd_mask, winmd, OSD_VIDWINMD);
1016 osd_write(sd, lconfig->line_length >> 5, OSD_VIDWIN0OFST);
1017 osd_write(sd, lconfig->xpos, OSD_VIDWIN0XP);
1018 osd_write(sd, lconfig->xsize, OSD_VIDWIN0XL);
1019 /*
1020 * For YUV420P format the register contents are
1021 * duplicated in both VID registers
1022 */
1023 if ((sd->vpbe_type == VPBE_VERSION_2) &&
1024 (lconfig->pixfmt == PIXFMT_NV12)) {
1025 /* other window also */
1026 if (lconfig->interlaced) {
1027 winmd_mask |= OSD_VIDWINMD_VFF1;
1028 winmd |= OSD_VIDWINMD_VFF1;
1029 osd_modify(sd, winmd_mask, winmd,
1030 OSD_VIDWINMD);
1031 }
1032
1033 osd_modify(sd, OSD_MISCCTL_S420D,
1034 OSD_MISCCTL_S420D, OSD_MISCCTL);
1035 osd_write(sd, lconfig->line_length >> 5,
1036 OSD_VIDWIN1OFST);
1037 osd_write(sd, lconfig->xpos, OSD_VIDWIN1XP);
1038 osd_write(sd, lconfig->xsize, OSD_VIDWIN1XL);
1039 /*
1040 * if NV21 pixfmt and line length not 32B
1041 * aligned (e.g. NTSC), Need to set window
1042 * X pixel size to be 32B aligned as well
1043 */
1044 if (lconfig->xsize % 32) {
1045 osd_write(sd,
1046 ((lconfig->xsize + 31) & ~31),
1047 OSD_VIDWIN1XL);
1048 osd_write(sd,
1049 ((lconfig->xsize + 31) & ~31),
1050 OSD_VIDWIN0XL);
1051 }
1052 } else if ((sd->vpbe_type == VPBE_VERSION_2) &&
1053 (lconfig->pixfmt != PIXFMT_NV12)) {
1054 osd_modify(sd, OSD_MISCCTL_S420D, ~OSD_MISCCTL_S420D,
1055 OSD_MISCCTL);
1056 }
1057
1058 if (lconfig->interlaced) {
1059 osd_write(sd, lconfig->ypos >> 1, OSD_VIDWIN0YP);
1060 osd_write(sd, lconfig->ysize >> 1, OSD_VIDWIN0YL);
1061 if ((sd->vpbe_type == VPBE_VERSION_2) &&
1062 lconfig->pixfmt == PIXFMT_NV12) {
1063 osd_write(sd, lconfig->ypos >> 1,
1064 OSD_VIDWIN1YP);
1065 osd_write(sd, lconfig->ysize >> 1,
1066 OSD_VIDWIN1YL);
1067 }
1068 } else {
1069 osd_write(sd, lconfig->ypos, OSD_VIDWIN0YP);
1070 osd_write(sd, lconfig->ysize, OSD_VIDWIN0YL);
1071 if ((sd->vpbe_type == VPBE_VERSION_2) &&
1072 lconfig->pixfmt == PIXFMT_NV12) {
1073 osd_write(sd, lconfig->ypos, OSD_VIDWIN1YP);
1074 osd_write(sd, lconfig->ysize, OSD_VIDWIN1YL);
1075 }
1076 }
1077 break;
1078 case WIN_OSD1:
1079 /*
1080 * The caller must ensure that OSD1 is disabled prior to
1081 * switching from a normal mode to attribute mode or from
1082 * attribute mode to a normal mode.
1083 */
1084 if (lconfig->pixfmt == PIXFMT_OSD_ATTR) {
1085 if (sd->vpbe_type == VPBE_VERSION_1) {
1086 winmd_mask |= OSD_OSDWIN1MD_ATN1E |
1087 OSD_OSDWIN1MD_RGB1E | OSD_OSDWIN1MD_CLUTS1 |
1088 OSD_OSDWIN1MD_BLND1 | OSD_OSDWIN1MD_TE1;
1089 } else {
1090 winmd_mask |= OSD_OSDWIN1MD_BMP1MD |
1091 OSD_OSDWIN1MD_CLUTS1 | OSD_OSDWIN1MD_BLND1 |
1092 OSD_OSDWIN1MD_TE1;
1093 }
1094 } else {
1095 if (sd->vpbe_type == VPBE_VERSION_1) {
1096 winmd_mask |= OSD_OSDWIN1MD_RGB1E;
1097 if (lconfig->pixfmt == PIXFMT_RGB565)
1098 winmd |= OSD_OSDWIN1MD_RGB1E;
1099 } else if ((sd->vpbe_type == VPBE_VERSION_3)
1100 || (sd->vpbe_type == VPBE_VERSION_2)) {
1101 winmd_mask |= OSD_OSDWIN1MD_BMP1MD;
1102 switch (lconfig->pixfmt) {
1103 case PIXFMT_RGB565:
1104 winmd |=
1105 (1 << OSD_OSDWIN1MD_BMP1MD_SHIFT);
1106 break;
1107 case PIXFMT_RGB888:
1108 winmd |=
1109 (2 << OSD_OSDWIN1MD_BMP1MD_SHIFT);
1110 _osd_enable_rgb888_pixblend(sd,
1111 OSDWIN_OSD1);
1112 break;
1113 case PIXFMT_YCbCrI:
1114 case PIXFMT_YCrCbI:
1115 winmd |=
1116 (3 << OSD_OSDWIN1MD_BMP1MD_SHIFT);
1117 break;
1118 default:
1119 break;
1120 }
1121 }
1122
1123 winmd_mask |= OSD_OSDWIN1MD_BMW1;
1124 switch (lconfig->pixfmt) {
1125 case PIXFMT_1BPP:
1126 bmw = 0;
1127 break;
1128 case PIXFMT_2BPP:
1129 bmw = 1;
1130 break;
1131 case PIXFMT_4BPP:
1132 bmw = 2;
1133 break;
1134 case PIXFMT_8BPP:
1135 bmw = 3;
1136 break;
1137 default:
1138 break;
1139 }
1140 winmd |= (bmw << OSD_OSDWIN1MD_BMW1_SHIFT);
1141 }
1142
1143 winmd_mask |= OSD_OSDWIN1MD_OFF1;
1144 if (lconfig->interlaced)
1145 winmd |= OSD_OSDWIN1MD_OFF1;
1146
1147 osd_modify(sd, winmd_mask, winmd, OSD_OSDWIN1MD);
1148 osd_write(sd, lconfig->line_length >> 5, OSD_OSDWIN1OFST);
1149 osd_write(sd, lconfig->xpos, OSD_OSDWIN1XP);
1150 osd_write(sd, lconfig->xsize, OSD_OSDWIN1XL);
1151 if (lconfig->interlaced) {
1152 osd_write(sd, lconfig->ypos >> 1, OSD_OSDWIN1YP);
1153 osd_write(sd, lconfig->ysize >> 1, OSD_OSDWIN1YL);
1154 } else {
1155 osd_write(sd, lconfig->ypos, OSD_OSDWIN1YP);
1156 osd_write(sd, lconfig->ysize, OSD_OSDWIN1YL);
1157 }
1158 break;
1159 case WIN_VID1:
1160 winmd_mask |= OSD_VIDWINMD_VFF1;
1161 if (lconfig->interlaced)
1162 winmd |= OSD_VIDWINMD_VFF1;
1163
1164 osd_modify(sd, winmd_mask, winmd, OSD_VIDWINMD);
1165 osd_write(sd, lconfig->line_length >> 5, OSD_VIDWIN1OFST);
1166 osd_write(sd, lconfig->xpos, OSD_VIDWIN1XP);
1167 osd_write(sd, lconfig->xsize, OSD_VIDWIN1XL);
1168 /*
1169 * For YUV420P format the register contents are
1170 * duplicated in both VID registers
1171 */
1172 if (sd->vpbe_type == VPBE_VERSION_2) {
1173 if (lconfig->pixfmt == PIXFMT_NV12) {
1174 /* other window also */
1175 if (lconfig->interlaced) {
1176 winmd_mask |= OSD_VIDWINMD_VFF0;
1177 winmd |= OSD_VIDWINMD_VFF0;
1178 osd_modify(sd, winmd_mask, winmd,
1179 OSD_VIDWINMD);
1180 }
1181 osd_modify(sd, OSD_MISCCTL_S420D,
1182 OSD_MISCCTL_S420D, OSD_MISCCTL);
1183 osd_write(sd, lconfig->line_length >> 5,
1184 OSD_VIDWIN0OFST);
1185 osd_write(sd, lconfig->xpos, OSD_VIDWIN0XP);
1186 osd_write(sd, lconfig->xsize, OSD_VIDWIN0XL);
1187 } else {
1188 osd_modify(sd, OSD_MISCCTL_S420D,
1189 ~OSD_MISCCTL_S420D, OSD_MISCCTL);
1190 }
1191 }
1192
1193 if (lconfig->interlaced) {
1194 osd_write(sd, lconfig->ypos >> 1, OSD_VIDWIN1YP);
1195 osd_write(sd, lconfig->ysize >> 1, OSD_VIDWIN1YL);
1196 if ((sd->vpbe_type == VPBE_VERSION_2) &&
1197 lconfig->pixfmt == PIXFMT_NV12) {
1198 osd_write(sd, lconfig->ypos >> 1,
1199 OSD_VIDWIN0YP);
1200 osd_write(sd, lconfig->ysize >> 1,
1201 OSD_VIDWIN0YL);
1202 }
1203 } else {
1204 osd_write(sd, lconfig->ypos, OSD_VIDWIN1YP);
1205 osd_write(sd, lconfig->ysize, OSD_VIDWIN1YL);
1206 if ((sd->vpbe_type == VPBE_VERSION_2) &&
1207 lconfig->pixfmt == PIXFMT_NV12) {
1208 osd_write(sd, lconfig->ypos, OSD_VIDWIN0YP);
1209 osd_write(sd, lconfig->ysize, OSD_VIDWIN0YL);
1210 }
1211 }
1212 break;
1213 }
1214}
1215
1216static int osd_set_layer_config(struct osd_state *sd, enum osd_layer layer,
1217 struct osd_layer_config *lconfig)
1218{
1219 struct osd_state *osd = sd;
1220 struct osd_window_state *win = &osd->win[layer];
1221 struct osd_layer_config *cfg = &win->lconfig;
1222 unsigned long flags;
1223 int reject_config;
1224
1225 spin_lock_irqsave(&osd->lock, flags);
1226
1227 reject_config = try_layer_config(sd, layer, lconfig);
1228 if (reject_config) {
1229 spin_unlock_irqrestore(&osd->lock, flags);
1230 return reject_config;
1231 }
1232
1233 /* update the current Cb/Cr order */
1234 if (is_yc_pixfmt(lconfig->pixfmt))
1235 osd->yc_pixfmt = lconfig->pixfmt;
1236
1237 /*
1238 * If we are switching OSD1 from normal mode to attribute mode or from
1239 * attribute mode to normal mode, then we must disable the window.
1240 */
1241 if (layer == WIN_OSD1) {
1242 if (((lconfig->pixfmt == PIXFMT_OSD_ATTR) &&
1243 (cfg->pixfmt != PIXFMT_OSD_ATTR)) ||
1244 ((lconfig->pixfmt != PIXFMT_OSD_ATTR) &&
1245 (cfg->pixfmt == PIXFMT_OSD_ATTR))) {
1246 win->is_enabled = 0;
1247 _osd_disable_layer(sd, layer);
1248 }
1249 }
1250
1251 _osd_set_layer_config(sd, layer, lconfig);
1252
1253 if (layer == WIN_OSD1) {
1254 struct osd_osdwin_state *osdwin_state =
1255 &osd->osdwin[OSDWIN_OSD1];
1256
1257 if ((lconfig->pixfmt != PIXFMT_OSD_ATTR) &&
1258 (cfg->pixfmt == PIXFMT_OSD_ATTR)) {
1259 /*
1260 * We just switched OSD1 from attribute mode to normal
1261 * mode, so we must initialize the CLUT select, the
1262 * blend factor, transparency colorkey enable, and
1263 * attenuation enable (DM6446 only) bits in the
1264 * OSDWIN1MD register.
1265 */
1266 _osd_set_osd_clut(sd, OSDWIN_OSD1,
1267 osdwin_state->clut);
1268 _osd_set_blending_factor(sd, OSDWIN_OSD1,
1269 osdwin_state->blend);
1270 if (osdwin_state->colorkey_blending) {
1271 _osd_enable_color_key(sd, OSDWIN_OSD1,
1272 osdwin_state->
1273 colorkey,
1274 lconfig->pixfmt);
1275 } else
1276 _osd_disable_color_key(sd, OSDWIN_OSD1);
1277 _osd_set_rec601_attenuation(sd, OSDWIN_OSD1,
1278 osdwin_state->
1279 rec601_attenuation);
1280 } else if ((lconfig->pixfmt == PIXFMT_OSD_ATTR) &&
1281 (cfg->pixfmt != PIXFMT_OSD_ATTR)) {
1282 /*
1283 * We just switched OSD1 from normal mode to attribute
1284 * mode, so we must initialize the blink enable and
1285 * blink interval bits in the OSDATRMD register.
1286 */
1287 _osd_set_blink_attribute(sd, osd->is_blinking,
1288 osd->blink);
1289 }
1290 }
1291
1292 /*
1293 * If we just switched to a 1-, 2-, or 4-bits-per-pixel bitmap format
1294 * then configure a default palette map.
1295 */
1296 if ((lconfig->pixfmt != cfg->pixfmt) &&
1297 ((lconfig->pixfmt == PIXFMT_1BPP) ||
1298 (lconfig->pixfmt == PIXFMT_2BPP) ||
1299 (lconfig->pixfmt == PIXFMT_4BPP))) {
1300 enum osd_win_layer osdwin =
1301 ((layer == WIN_OSD0) ? OSDWIN_OSD0 : OSDWIN_OSD1);
1302 struct osd_osdwin_state *osdwin_state =
1303 &osd->osdwin[osdwin];
1304 unsigned char clut_index;
1305 unsigned char clut_entries = 0;
1306
1307 switch (lconfig->pixfmt) {
1308 case PIXFMT_1BPP:
1309 clut_entries = 2;
1310 break;
1311 case PIXFMT_2BPP:
1312 clut_entries = 4;
1313 break;
1314 case PIXFMT_4BPP:
1315 clut_entries = 16;
1316 break;
1317 default:
1318 break;
1319 }
1320 /*
1321 * The default palette map maps the pixel value to the clut
1322 * index, i.e. pixel value 0 maps to clut entry 0, pixel value
1323 * 1 maps to clut entry 1, etc.
1324 */
1325 for (clut_index = 0; clut_index < 16; clut_index++) {
1326 osdwin_state->palette_map[clut_index] = clut_index;
1327 if (clut_index < clut_entries) {
1328 _osd_set_palette_map(sd, osdwin, clut_index,
1329 clut_index,
1330 lconfig->pixfmt);
1331 }
1332 }
1333 }
1334
1335 *cfg = *lconfig;
1336 /* DM6446: configure the RGB888 enable and window selection */
1337 if (osd->win[WIN_VID0].lconfig.pixfmt == PIXFMT_RGB888)
1338 _osd_enable_vid_rgb888(sd, WIN_VID0);
1339 else if (osd->win[WIN_VID1].lconfig.pixfmt == PIXFMT_RGB888)
1340 _osd_enable_vid_rgb888(sd, WIN_VID1);
1341 else
1342 _osd_disable_vid_rgb888(sd);
1343
1344 if (layer == WIN_VID0) {
1345 osd->pingpong =
1346 _osd_dm6446_vid0_pingpong(sd, osd->field_inversion,
1347 win->fb_base_phys,
1348 cfg);
1349 }
1350
1351 spin_unlock_irqrestore(&osd->lock, flags);
1352
1353 return 0;
1354}
1355
1356static void osd_init_layer(struct osd_state *sd, enum osd_layer layer)
1357{
1358 struct osd_state *osd = sd;
1359 struct osd_window_state *win = &osd->win[layer];
1360 enum osd_win_layer osdwin;
1361 struct osd_osdwin_state *osdwin_state;
1362 struct osd_layer_config *cfg = &win->lconfig;
1363 unsigned long flags;
1364
1365 spin_lock_irqsave(&osd->lock, flags);
1366
1367 win->is_enabled = 0;
1368 _osd_disable_layer(sd, layer);
1369
1370 win->h_zoom = ZOOM_X1;
1371 win->v_zoom = ZOOM_X1;
1372 _osd_set_zoom(sd, layer, win->h_zoom, win->v_zoom);
1373
1374 win->fb_base_phys = 0;
1375 _osd_start_layer(sd, layer, win->fb_base_phys, 0);
1376
1377 cfg->line_length = 0;
1378 cfg->xsize = 0;
1379 cfg->ysize = 0;
1380 cfg->xpos = 0;
1381 cfg->ypos = 0;
1382 cfg->interlaced = 0;
1383 switch (layer) {
1384 case WIN_OSD0:
1385 case WIN_OSD1:
1386 osdwin = (layer == WIN_OSD0) ? OSDWIN_OSD0 : OSDWIN_OSD1;
1387 osdwin_state = &osd->osdwin[osdwin];
1388 /*
1389 * Other code relies on the fact that OSD windows default to a
1390 * bitmap pixel format when they are deallocated, so don't
1391 * change this default pixel format.
1392 */
1393 cfg->pixfmt = PIXFMT_8BPP;
1394 _osd_set_layer_config(sd, layer, cfg);
1395 osdwin_state->clut = RAM_CLUT;
1396 _osd_set_osd_clut(sd, osdwin, osdwin_state->clut);
1397 osdwin_state->colorkey_blending = 0;
1398 _osd_disable_color_key(sd, osdwin);
1399 osdwin_state->blend = OSD_8_VID_0;
1400 _osd_set_blending_factor(sd, osdwin, osdwin_state->blend);
1401 osdwin_state->rec601_attenuation = 0;
1402 _osd_set_rec601_attenuation(sd, osdwin,
1403 osdwin_state->
1404 rec601_attenuation);
1405 if (osdwin == OSDWIN_OSD1) {
1406 osd->is_blinking = 0;
1407 osd->blink = BLINK_X1;
1408 }
1409 break;
1410 case WIN_VID0:
1411 case WIN_VID1:
1412 cfg->pixfmt = osd->yc_pixfmt;
1413 _osd_set_layer_config(sd, layer, cfg);
1414 break;
1415 }
1416
1417 spin_unlock_irqrestore(&osd->lock, flags);
1418}
1419
1420static void osd_release_layer(struct osd_state *sd, enum osd_layer layer)
1421{
1422 struct osd_state *osd = sd;
1423 struct osd_window_state *win = &osd->win[layer];
1424 unsigned long flags;
1425
1426 spin_lock_irqsave(&osd->lock, flags);
1427
1428 if (!win->is_allocated) {
1429 spin_unlock_irqrestore(&osd->lock, flags);
1430 return;
1431 }
1432
1433 spin_unlock_irqrestore(&osd->lock, flags);
1434 osd_init_layer(sd, layer);
1435 spin_lock_irqsave(&osd->lock, flags);
1436
1437 win->is_allocated = 0;
1438
1439 spin_unlock_irqrestore(&osd->lock, flags);
1440}
1441
1442static int osd_request_layer(struct osd_state *sd, enum osd_layer layer)
1443{
1444 struct osd_state *osd = sd;
1445 struct osd_window_state *win = &osd->win[layer];
1446 unsigned long flags;
1447
1448 spin_lock_irqsave(&osd->lock, flags);
1449
1450 if (win->is_allocated) {
1451 spin_unlock_irqrestore(&osd->lock, flags);
1452 return -1;
1453 }
1454 win->is_allocated = 1;
1455
1456 spin_unlock_irqrestore(&osd->lock, flags);
1457
1458 return 0;
1459}
1460
1461static void _osd_init(struct osd_state *sd)
1462{
1463 osd_write(sd, 0, OSD_MODE);
1464 osd_write(sd, 0, OSD_VIDWINMD);
1465 osd_write(sd, 0, OSD_OSDWIN0MD);
1466 osd_write(sd, 0, OSD_OSDWIN1MD);
1467 osd_write(sd, 0, OSD_RECTCUR);
1468 osd_write(sd, 0, OSD_MISCCTL);
1469 if (sd->vpbe_type == VPBE_VERSION_3) {
1470 osd_write(sd, 0, OSD_VBNDRY);
1471 osd_write(sd, 0, OSD_EXTMODE);
1472 osd_write(sd, OSD_MISCCTL_DMANG, OSD_MISCCTL);
1473 }
1474}
1475
1476static void osd_set_left_margin(struct osd_state *sd, u32 val)
1477{
1478 osd_write(sd, val, OSD_BASEPX);
1479}
1480
1481static void osd_set_top_margin(struct osd_state *sd, u32 val)
1482{
1483 osd_write(sd, val, OSD_BASEPY);
1484}
1485
1486static int osd_initialize(struct osd_state *osd)
1487{
1488 if (osd == NULL)
1489 return -ENODEV;
1490 _osd_init(osd);
1491
1492 /* set default Cb/Cr order */
1493 osd->yc_pixfmt = PIXFMT_YCbCrI;
1494
1495 if (osd->vpbe_type == VPBE_VERSION_3) {
1496 /*
1497 * ROM CLUT1 on the DM355 is similar (identical?) to ROM CLUT0
1498 * on the DM6446, so make ROM_CLUT1 the default on the DM355.
1499 */
1500 osd->rom_clut = ROM_CLUT1;
1501 }
1502
1503 _osd_set_field_inversion(osd, osd->field_inversion);
1504 _osd_set_rom_clut(osd, osd->rom_clut);
1505
1506 osd_init_layer(osd, WIN_OSD0);
1507 osd_init_layer(osd, WIN_VID0);
1508 osd_init_layer(osd, WIN_OSD1);
1509 osd_init_layer(osd, WIN_VID1);
1510
1511 return 0;
1512}
1513
1514static const struct vpbe_osd_ops osd_ops = {
1515 .initialize = osd_initialize,
1516 .request_layer = osd_request_layer,
1517 .release_layer = osd_release_layer,
1518 .enable_layer = osd_enable_layer,
1519 .disable_layer = osd_disable_layer,
1520 .set_layer_config = osd_set_layer_config,
1521 .get_layer_config = osd_get_layer_config,
1522 .start_layer = osd_start_layer,
1523 .set_left_margin = osd_set_left_margin,
1524 .set_top_margin = osd_set_top_margin,
1525};
1526
1527static int osd_probe(struct platform_device *pdev)
1528{
1529 struct osd_platform_data *pdata;
1530 struct osd_state *osd;
1531 struct resource *res;
1532 int ret = 0;
1533
1534 osd = kzalloc(sizeof(struct osd_state), GFP_KERNEL);
1535 if (osd == NULL)
1536 return -ENOMEM;
1537
1538 osd->dev = &pdev->dev;
1539 pdata = (struct osd_platform_data *)pdev->dev.platform_data;
1540 osd->vpbe_type = (enum vpbe_version)pdata->vpbe_type;
1541 if (NULL == pdev->dev.platform_data) {
1542 dev_err(osd->dev, "No platform data defined for OSD"
1543 " sub device\n");
1544 ret = -ENOENT;
1545 goto free_mem;
1546 }
1547
1548 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1549 if (!res) {
1550 dev_err(osd->dev, "Unable to get OSD register address map\n");
1551 ret = -ENODEV;
1552 goto free_mem;
1553 }
1554 osd->osd_base_phys = res->start;
1555 osd->osd_size = resource_size(res);
1556 if (!request_mem_region(osd->osd_base_phys, osd->osd_size,
1557 MODULE_NAME)) {
1558 dev_err(osd->dev, "Unable to reserve OSD MMIO region\n");
1559 ret = -ENODEV;
1560 goto free_mem;
1561 }
1562 osd->osd_base = (unsigned long)ioremap_nocache(res->start,
1563 osd->osd_size);
1564 if (!osd->osd_base) {
1565 dev_err(osd->dev, "Unable to map the OSD region\n");
1566 ret = -ENODEV;
1567 goto release_mem_region;
1568 }
1569 spin_lock_init(&osd->lock);
1570 osd->ops = osd_ops;
1571 platform_set_drvdata(pdev, osd);
1572 dev_notice(osd->dev, "OSD sub device probe success\n");
1573 return ret;
1574
1575release_mem_region:
1576 release_mem_region(osd->osd_base_phys, osd->osd_size);
1577free_mem:
1578 kfree(osd);
1579 return ret;
1580}
1581
1582static int osd_remove(struct platform_device *pdev)
1583{
1584 struct osd_state *osd = platform_get_drvdata(pdev);
1585
1586 iounmap((void *)osd->osd_base);
1587 release_mem_region(osd->osd_base_phys, osd->osd_size);
1588 kfree(osd);
1589 return 0;
1590}
1591
1592static struct platform_driver osd_driver = {
1593 .probe = osd_probe,
1594 .remove = osd_remove,
1595 .driver = {
1596 .name = MODULE_NAME,
1597 .owner = THIS_MODULE,
1598 },
1599};
1600
1601module_platform_driver(osd_driver);
1602
1603MODULE_LICENSE("GPL");
1604MODULE_DESCRIPTION("DaVinci OSD Manager Driver");
1605MODULE_AUTHOR("Texas Instruments");
diff --git a/drivers/media/video/davinci/vpbe_osd_regs.h b/drivers/media/video/davinci/vpbe_osd_regs.h
deleted file mode 100644
index 584520f3af60..000000000000
--- a/drivers/media/video/davinci/vpbe_osd_regs.h
+++ /dev/null
@@ -1,364 +0,0 @@
1/*
2 * Copyright (C) 2006-2010 Texas Instruments Inc
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation version 2.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 */
17#ifndef _VPBE_OSD_REGS_H
18#define _VPBE_OSD_REGS_H
19
20/* VPBE Global Registers */
21#define VPBE_PID 0x0
22#define VPBE_PCR 0x4
23
24/* VPSS CLock Registers */
25#define VPSSCLK_PID 0x00
26#define VPSSCLK_CLKCTRL 0x04
27
28/* VPSS Buffer Logic Registers */
29#define VPSSBL_PID 0x00
30#define VPSSBL_PCR 0x04
31#define VPSSBL_BCR 0x08
32#define VPSSBL_INTSTAT 0x0C
33#define VPSSBL_INTSEL 0x10
34#define VPSSBL_EVTSEL 0x14
35#define VPSSBL_MEMCTRL 0x18
36#define VPSSBL_CCDCMUX 0x1C
37
38/* DM365 ISP5 system configuration */
39#define ISP5_PID 0x0
40#define ISP5_PCCR 0x4
41#define ISP5_BCR 0x8
42#define ISP5_INTSTAT 0xC
43#define ISP5_INTSEL1 0x10
44#define ISP5_INTSEL2 0x14
45#define ISP5_INTSEL3 0x18
46#define ISP5_EVTSEL 0x1c
47#define ISP5_CCDCMUX 0x20
48
49/* VPBE On-Screen Display Subsystem Registers (OSD) */
50#define OSD_MODE 0x00
51#define OSD_VIDWINMD 0x04
52#define OSD_OSDWIN0MD 0x08
53#define OSD_OSDWIN1MD 0x0C
54#define OSD_OSDATRMD 0x0C
55#define OSD_RECTCUR 0x10
56#define OSD_VIDWIN0OFST 0x18
57#define OSD_VIDWIN1OFST 0x1C
58#define OSD_OSDWIN0OFST 0x20
59#define OSD_OSDWIN1OFST 0x24
60#define OSD_VIDWINADH 0x28
61#define OSD_VIDWIN0ADL 0x2C
62#define OSD_VIDWIN0ADR 0x2C
63#define OSD_VIDWIN1ADL 0x30
64#define OSD_VIDWIN1ADR 0x30
65#define OSD_OSDWINADH 0x34
66#define OSD_OSDWIN0ADL 0x38
67#define OSD_OSDWIN0ADR 0x38
68#define OSD_OSDWIN1ADL 0x3C
69#define OSD_OSDWIN1ADR 0x3C
70#define OSD_BASEPX 0x40
71#define OSD_BASEPY 0x44
72#define OSD_VIDWIN0XP 0x48
73#define OSD_VIDWIN0YP 0x4C
74#define OSD_VIDWIN0XL 0x50
75#define OSD_VIDWIN0YL 0x54
76#define OSD_VIDWIN1XP 0x58
77#define OSD_VIDWIN1YP 0x5C
78#define OSD_VIDWIN1XL 0x60
79#define OSD_VIDWIN1YL 0x64
80#define OSD_OSDWIN0XP 0x68
81#define OSD_OSDWIN0YP 0x6C
82#define OSD_OSDWIN0XL 0x70
83#define OSD_OSDWIN0YL 0x74
84#define OSD_OSDWIN1XP 0x78
85#define OSD_OSDWIN1YP 0x7C
86#define OSD_OSDWIN1XL 0x80
87#define OSD_OSDWIN1YL 0x84
88#define OSD_CURXP 0x88
89#define OSD_CURYP 0x8C
90#define OSD_CURXL 0x90
91#define OSD_CURYL 0x94
92#define OSD_W0BMP01 0xA0
93#define OSD_W0BMP23 0xA4
94#define OSD_W0BMP45 0xA8
95#define OSD_W0BMP67 0xAC
96#define OSD_W0BMP89 0xB0
97#define OSD_W0BMPAB 0xB4
98#define OSD_W0BMPCD 0xB8
99#define OSD_W0BMPEF 0xBC
100#define OSD_W1BMP01 0xC0
101#define OSD_W1BMP23 0xC4
102#define OSD_W1BMP45 0xC8
103#define OSD_W1BMP67 0xCC
104#define OSD_W1BMP89 0xD0
105#define OSD_W1BMPAB 0xD4
106#define OSD_W1BMPCD 0xD8
107#define OSD_W1BMPEF 0xDC
108#define OSD_VBNDRY 0xE0
109#define OSD_EXTMODE 0xE4
110#define OSD_MISCCTL 0xE8
111#define OSD_CLUTRAMYCB 0xEC
112#define OSD_CLUTRAMCR 0xF0
113#define OSD_TRANSPVAL 0xF4
114#define OSD_TRANSPVALL 0xF4
115#define OSD_TRANSPVALU 0xF8
116#define OSD_TRANSPBMPIDX 0xFC
117#define OSD_PPVWIN0ADR 0xFC
118
119/* bit definitions */
120#define VPBE_PCR_VENC_DIV (1 << 1)
121#define VPBE_PCR_CLK_OFF (1 << 0)
122
123#define VPSSBL_INTSTAT_HSSIINT (1 << 14)
124#define VPSSBL_INTSTAT_CFALDINT (1 << 13)
125#define VPSSBL_INTSTAT_IPIPE_INT5 (1 << 12)
126#define VPSSBL_INTSTAT_IPIPE_INT4 (1 << 11)
127#define VPSSBL_INTSTAT_IPIPE_INT3 (1 << 10)
128#define VPSSBL_INTSTAT_IPIPE_INT2 (1 << 9)
129#define VPSSBL_INTSTAT_IPIPE_INT1 (1 << 8)
130#define VPSSBL_INTSTAT_IPIPE_INT0 (1 << 7)
131#define VPSSBL_INTSTAT_IPIPEIFINT (1 << 6)
132#define VPSSBL_INTSTAT_OSDINT (1 << 5)
133#define VPSSBL_INTSTAT_VENCINT (1 << 4)
134#define VPSSBL_INTSTAT_H3AINT (1 << 3)
135#define VPSSBL_INTSTAT_CCDC_VDINT2 (1 << 2)
136#define VPSSBL_INTSTAT_CCDC_VDINT1 (1 << 1)
137#define VPSSBL_INTSTAT_CCDC_VDINT0 (1 << 0)
138
139/* DM365 ISP5 bit definitions */
140#define ISP5_INTSTAT_VENCINT (1 << 21)
141#define ISP5_INTSTAT_OSDINT (1 << 20)
142
143/* VMOD TVTYP options for HDMD=0 */
144#define SDTV_NTSC 0
145#define SDTV_PAL 1
146/* VMOD TVTYP options for HDMD=1 */
147#define HDTV_525P 0
148#define HDTV_625P 1
149#define HDTV_1080I 2
150#define HDTV_720P 3
151
152#define OSD_MODE_CS (1 << 15)
153#define OSD_MODE_OVRSZ (1 << 14)
154#define OSD_MODE_OHRSZ (1 << 13)
155#define OSD_MODE_EF (1 << 12)
156#define OSD_MODE_VVRSZ (1 << 11)
157#define OSD_MODE_VHRSZ (1 << 10)
158#define OSD_MODE_FSINV (1 << 9)
159#define OSD_MODE_BCLUT (1 << 8)
160#define OSD_MODE_CABG_SHIFT 0
161#define OSD_MODE_CABG (0xff << 0)
162
163#define OSD_VIDWINMD_VFINV (1 << 15)
164#define OSD_VIDWINMD_V1EFC (1 << 14)
165#define OSD_VIDWINMD_VHZ1_SHIFT 12
166#define OSD_VIDWINMD_VHZ1 (3 << 12)
167#define OSD_VIDWINMD_VVZ1_SHIFT 10
168#define OSD_VIDWINMD_VVZ1 (3 << 10)
169#define OSD_VIDWINMD_VFF1 (1 << 9)
170#define OSD_VIDWINMD_ACT1 (1 << 8)
171#define OSD_VIDWINMD_V0EFC (1 << 6)
172#define OSD_VIDWINMD_VHZ0_SHIFT 4
173#define OSD_VIDWINMD_VHZ0 (3 << 4)
174#define OSD_VIDWINMD_VVZ0_SHIFT 2
175#define OSD_VIDWINMD_VVZ0 (3 << 2)
176#define OSD_VIDWINMD_VFF0 (1 << 1)
177#define OSD_VIDWINMD_ACT0 (1 << 0)
178
179#define OSD_OSDWIN0MD_ATN0E (1 << 14)
180#define OSD_OSDWIN0MD_RGB0E (1 << 13)
181#define OSD_OSDWIN0MD_BMP0MD_SHIFT 13
182#define OSD_OSDWIN0MD_BMP0MD (3 << 13)
183#define OSD_OSDWIN0MD_CLUTS0 (1 << 12)
184#define OSD_OSDWIN0MD_OHZ0_SHIFT 10
185#define OSD_OSDWIN0MD_OHZ0 (3 << 10)
186#define OSD_OSDWIN0MD_OVZ0_SHIFT 8
187#define OSD_OSDWIN0MD_OVZ0 (3 << 8)
188#define OSD_OSDWIN0MD_BMW0_SHIFT 6
189#define OSD_OSDWIN0MD_BMW0 (3 << 6)
190#define OSD_OSDWIN0MD_BLND0_SHIFT 3
191#define OSD_OSDWIN0MD_BLND0 (7 << 3)
192#define OSD_OSDWIN0MD_TE0 (1 << 2)
193#define OSD_OSDWIN0MD_OFF0 (1 << 1)
194#define OSD_OSDWIN0MD_OACT0 (1 << 0)
195
196#define OSD_OSDWIN1MD_OASW (1 << 15)
197#define OSD_OSDWIN1MD_ATN1E (1 << 14)
198#define OSD_OSDWIN1MD_RGB1E (1 << 13)
199#define OSD_OSDWIN1MD_BMP1MD_SHIFT 13
200#define OSD_OSDWIN1MD_BMP1MD (3 << 13)
201#define OSD_OSDWIN1MD_CLUTS1 (1 << 12)
202#define OSD_OSDWIN1MD_OHZ1_SHIFT 10
203#define OSD_OSDWIN1MD_OHZ1 (3 << 10)
204#define OSD_OSDWIN1MD_OVZ1_SHIFT 8
205#define OSD_OSDWIN1MD_OVZ1 (3 << 8)
206#define OSD_OSDWIN1MD_BMW1_SHIFT 6
207#define OSD_OSDWIN1MD_BMW1 (3 << 6)
208#define OSD_OSDWIN1MD_BLND1_SHIFT 3
209#define OSD_OSDWIN1MD_BLND1 (7 << 3)
210#define OSD_OSDWIN1MD_TE1 (1 << 2)
211#define OSD_OSDWIN1MD_OFF1 (1 << 1)
212#define OSD_OSDWIN1MD_OACT1 (1 << 0)
213
214#define OSD_OSDATRMD_OASW (1 << 15)
215#define OSD_OSDATRMD_OHZA_SHIFT 10
216#define OSD_OSDATRMD_OHZA (3 << 10)
217#define OSD_OSDATRMD_OVZA_SHIFT 8
218#define OSD_OSDATRMD_OVZA (3 << 8)
219#define OSD_OSDATRMD_BLNKINT_SHIFT 6
220#define OSD_OSDATRMD_BLNKINT (3 << 6)
221#define OSD_OSDATRMD_OFFA (1 << 1)
222#define OSD_OSDATRMD_BLNK (1 << 0)
223
224#define OSD_RECTCUR_RCAD_SHIFT 8
225#define OSD_RECTCUR_RCAD (0xff << 8)
226#define OSD_RECTCUR_CLUTSR (1 << 7)
227#define OSD_RECTCUR_RCHW_SHIFT 4
228#define OSD_RECTCUR_RCHW (7 << 4)
229#define OSD_RECTCUR_RCVW_SHIFT 1
230#define OSD_RECTCUR_RCVW (7 << 1)
231#define OSD_RECTCUR_RCACT (1 << 0)
232
233#define OSD_VIDWIN0OFST_V0LO (0x1ff << 0)
234
235#define OSD_VIDWIN1OFST_V1LO (0x1ff << 0)
236
237#define OSD_OSDWIN0OFST_O0LO (0x1ff << 0)
238
239#define OSD_OSDWIN1OFST_O1LO (0x1ff << 0)
240
241#define OSD_WINOFST_AH_SHIFT 9
242
243#define OSD_VIDWIN0OFST_V0AH (0xf << 9)
244#define OSD_VIDWIN1OFST_V1AH (0xf << 9)
245#define OSD_OSDWIN0OFST_O0AH (0xf << 9)
246#define OSD_OSDWIN1OFST_O1AH (0xf << 9)
247
248#define OSD_VIDWINADH_V1AH_SHIFT 8
249#define OSD_VIDWINADH_V1AH (0x7f << 8)
250#define OSD_VIDWINADH_V0AH_SHIFT 0
251#define OSD_VIDWINADH_V0AH (0x7f << 0)
252
253#define OSD_VIDWIN0ADL_V0AL (0xffff << 0)
254
255#define OSD_VIDWIN1ADL_V1AL (0xffff << 0)
256
257#define OSD_OSDWINADH_O1AH_SHIFT 8
258#define OSD_OSDWINADH_O1AH (0x7f << 8)
259#define OSD_OSDWINADH_O0AH_SHIFT 0
260#define OSD_OSDWINADH_O0AH (0x7f << 0)
261
262#define OSD_OSDWIN0ADL_O0AL (0xffff << 0)
263
264#define OSD_OSDWIN1ADL_O1AL (0xffff << 0)
265
266#define OSD_BASEPX_BPX (0x3ff << 0)
267
268#define OSD_BASEPY_BPY (0x1ff << 0)
269
270#define OSD_VIDWIN0XP_V0X (0x7ff << 0)
271
272#define OSD_VIDWIN0YP_V0Y (0x7ff << 0)
273
274#define OSD_VIDWIN0XL_V0W (0x7ff << 0)
275
276#define OSD_VIDWIN0YL_V0H (0x7ff << 0)
277
278#define OSD_VIDWIN1XP_V1X (0x7ff << 0)
279
280#define OSD_VIDWIN1YP_V1Y (0x7ff << 0)
281
282#define OSD_VIDWIN1XL_V1W (0x7ff << 0)
283
284#define OSD_VIDWIN1YL_V1H (0x7ff << 0)
285
286#define OSD_OSDWIN0XP_W0X (0x7ff << 0)
287
288#define OSD_OSDWIN0YP_W0Y (0x7ff << 0)
289
290#define OSD_OSDWIN0XL_W0W (0x7ff << 0)
291
292#define OSD_OSDWIN0YL_W0H (0x7ff << 0)
293
294#define OSD_OSDWIN1XP_W1X (0x7ff << 0)
295
296#define OSD_OSDWIN1YP_W1Y (0x7ff << 0)
297
298#define OSD_OSDWIN1XL_W1W (0x7ff << 0)
299
300#define OSD_OSDWIN1YL_W1H (0x7ff << 0)
301
302#define OSD_CURXP_RCSX (0x7ff << 0)
303
304#define OSD_CURYP_RCSY (0x7ff << 0)
305
306#define OSD_CURXL_RCSW (0x7ff << 0)
307
308#define OSD_CURYL_RCSH (0x7ff << 0)
309
310#define OSD_EXTMODE_EXPMDSEL (1 << 15)
311#define OSD_EXTMODE_SCRNHEXP_SHIFT 13
312#define OSD_EXTMODE_SCRNHEXP (3 << 13)
313#define OSD_EXTMODE_SCRNVEXP (1 << 12)
314#define OSD_EXTMODE_OSD1BLDCHR (1 << 11)
315#define OSD_EXTMODE_OSD0BLDCHR (1 << 10)
316#define OSD_EXTMODE_ATNOSD1EN (1 << 9)
317#define OSD_EXTMODE_ATNOSD0EN (1 << 8)
318#define OSD_EXTMODE_OSDHRSZ15 (1 << 7)
319#define OSD_EXTMODE_VIDHRSZ15 (1 << 6)
320#define OSD_EXTMODE_ZMFILV1HEN (1 << 5)
321#define OSD_EXTMODE_ZMFILV1VEN (1 << 4)
322#define OSD_EXTMODE_ZMFILV0HEN (1 << 3)
323#define OSD_EXTMODE_ZMFILV0VEN (1 << 2)
324#define OSD_EXTMODE_EXPFILHEN (1 << 1)
325#define OSD_EXTMODE_EXPFILVEN (1 << 0)
326
327#define OSD_MISCCTL_BLDSEL (1 << 15)
328#define OSD_MISCCTL_S420D (1 << 14)
329#define OSD_MISCCTL_BMAPT (1 << 13)
330#define OSD_MISCCTL_DM365M (1 << 12)
331#define OSD_MISCCTL_RGBEN (1 << 7)
332#define OSD_MISCCTL_RGBWIN (1 << 6)
333#define OSD_MISCCTL_DMANG (1 << 6)
334#define OSD_MISCCTL_TMON (1 << 5)
335#define OSD_MISCCTL_RSEL (1 << 4)
336#define OSD_MISCCTL_CPBSY (1 << 3)
337#define OSD_MISCCTL_PPSW (1 << 2)
338#define OSD_MISCCTL_PPRV (1 << 1)
339
340#define OSD_CLUTRAMYCB_Y_SHIFT 8
341#define OSD_CLUTRAMYCB_Y (0xff << 8)
342#define OSD_CLUTRAMYCB_CB_SHIFT 0
343#define OSD_CLUTRAMYCB_CB (0xff << 0)
344
345#define OSD_CLUTRAMCR_CR_SHIFT 8
346#define OSD_CLUTRAMCR_CR (0xff << 8)
347#define OSD_CLUTRAMCR_CADDR_SHIFT 0
348#define OSD_CLUTRAMCR_CADDR (0xff << 0)
349
350#define OSD_TRANSPVAL_RGBTRANS (0xffff << 0)
351
352#define OSD_TRANSPVALL_RGBL (0xffff << 0)
353
354#define OSD_TRANSPVALU_Y_SHIFT 8
355#define OSD_TRANSPVALU_Y (0xff << 8)
356#define OSD_TRANSPVALU_RGBU_SHIFT 0
357#define OSD_TRANSPVALU_RGBU (0xff << 0)
358
359#define OSD_TRANSPBMPIDX_BMP1_SHIFT 8
360#define OSD_TRANSPBMPIDX_BMP1 (0xff << 8)
361#define OSD_TRANSPBMPIDX_BMP0_SHIFT 0
362#define OSD_TRANSPBMPIDX_BMP0 0xff
363
364#endif /* _DAVINCI_VPBE_H_ */
diff --git a/drivers/media/video/davinci/vpbe_venc.c b/drivers/media/video/davinci/vpbe_venc.c
deleted file mode 100644
index b21ecc8d134d..000000000000
--- a/drivers/media/video/davinci/vpbe_venc.c
+++ /dev/null
@@ -1,706 +0,0 @@
1/*
2 * Copyright (C) 2010 Texas Instruments Inc
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation version 2.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 */
17#include <linux/module.h>
18#include <linux/kernel.h>
19#include <linux/init.h>
20#include <linux/ctype.h>
21#include <linux/delay.h>
22#include <linux/device.h>
23#include <linux/interrupt.h>
24#include <linux/platform_device.h>
25#include <linux/videodev2.h>
26#include <linux/slab.h>
27
28#include <mach/hardware.h>
29#include <mach/mux.h>
30#include <mach/i2c.h>
31
32#include <linux/io.h>
33
34#include <media/davinci/vpbe_types.h>
35#include <media/davinci/vpbe_venc.h>
36#include <media/davinci/vpss.h>
37#include <media/v4l2-device.h>
38
39#include "vpbe_venc_regs.h"
40
41#define MODULE_NAME VPBE_VENC_SUBDEV_NAME
42
43static int debug = 2;
44module_param(debug, int, 0644);
45MODULE_PARM_DESC(debug, "Debug level 0-2");
46
47struct venc_state {
48 struct v4l2_subdev sd;
49 struct venc_callback *callback;
50 struct venc_platform_data *pdata;
51 struct device *pdev;
52 u32 output;
53 v4l2_std_id std;
54 spinlock_t lock;
55 void __iomem *venc_base;
56 void __iomem *vdaccfg_reg;
57};
58
59static inline struct venc_state *to_state(struct v4l2_subdev *sd)
60{
61 return container_of(sd, struct venc_state, sd);
62}
63
64static inline u32 venc_read(struct v4l2_subdev *sd, u32 offset)
65{
66 struct venc_state *venc = to_state(sd);
67
68 return readl(venc->venc_base + offset);
69}
70
71static inline u32 venc_write(struct v4l2_subdev *sd, u32 offset, u32 val)
72{
73 struct venc_state *venc = to_state(sd);
74
75 writel(val, (venc->venc_base + offset));
76
77 return val;
78}
79
80static inline u32 venc_modify(struct v4l2_subdev *sd, u32 offset,
81 u32 val, u32 mask)
82{
83 u32 new_val = (venc_read(sd, offset) & ~mask) | (val & mask);
84
85 venc_write(sd, offset, new_val);
86
87 return new_val;
88}
89
90static inline u32 vdaccfg_write(struct v4l2_subdev *sd, u32 val)
91{
92 struct venc_state *venc = to_state(sd);
93
94 writel(val, venc->vdaccfg_reg);
95
96 val = readl(venc->vdaccfg_reg);
97
98 return val;
99}
100
101#define VDAC_COMPONENT 0x543
102#define VDAC_S_VIDEO 0x210
103/* This function sets the dac of the VPBE for various outputs
104 */
105static int venc_set_dac(struct v4l2_subdev *sd, u32 out_index)
106{
107 switch (out_index) {
108 case 0:
109 v4l2_dbg(debug, 1, sd, "Setting output to Composite\n");
110 venc_write(sd, VENC_DACSEL, 0);
111 break;
112 case 1:
113 v4l2_dbg(debug, 1, sd, "Setting output to Component\n");
114 venc_write(sd, VENC_DACSEL, VDAC_COMPONENT);
115 break;
116 case 2:
117 v4l2_dbg(debug, 1, sd, "Setting output to S-video\n");
118 venc_write(sd, VENC_DACSEL, VDAC_S_VIDEO);
119 break;
120 default:
121 return -EINVAL;
122 }
123
124 return 0;
125}
126
127static void venc_enabledigitaloutput(struct v4l2_subdev *sd, int benable)
128{
129 struct venc_state *venc = to_state(sd);
130 struct venc_platform_data *pdata = venc->pdata;
131 v4l2_dbg(debug, 2, sd, "venc_enabledigitaloutput\n");
132
133 if (benable) {
134 venc_write(sd, VENC_VMOD, 0);
135 venc_write(sd, VENC_CVBS, 0);
136 venc_write(sd, VENC_LCDOUT, 0);
137 venc_write(sd, VENC_HSPLS, 0);
138 venc_write(sd, VENC_HSTART, 0);
139 venc_write(sd, VENC_HVALID, 0);
140 venc_write(sd, VENC_HINT, 0);
141 venc_write(sd, VENC_VSPLS, 0);
142 venc_write(sd, VENC_VSTART, 0);
143 venc_write(sd, VENC_VVALID, 0);
144 venc_write(sd, VENC_VINT, 0);
145 venc_write(sd, VENC_YCCCTL, 0);
146 venc_write(sd, VENC_DACSEL, 0);
147
148 } else {
149 venc_write(sd, VENC_VMOD, 0);
150 /* disable VCLK output pin enable */
151 venc_write(sd, VENC_VIDCTL, 0x141);
152
153 /* Disable output sync pins */
154 venc_write(sd, VENC_SYNCCTL, 0);
155
156 /* Disable DCLOCK */
157 venc_write(sd, VENC_DCLKCTL, 0);
158 venc_write(sd, VENC_DRGBX1, 0x0000057C);
159
160 /* Disable LCD output control (accepting default polarity) */
161 venc_write(sd, VENC_LCDOUT, 0);
162 if (pdata->venc_type != VPBE_VERSION_3)
163 venc_write(sd, VENC_CMPNT, 0x100);
164 venc_write(sd, VENC_HSPLS, 0);
165 venc_write(sd, VENC_HINT, 0);
166 venc_write(sd, VENC_HSTART, 0);
167 venc_write(sd, VENC_HVALID, 0);
168
169 venc_write(sd, VENC_VSPLS, 0);
170 venc_write(sd, VENC_VINT, 0);
171 venc_write(sd, VENC_VSTART, 0);
172 venc_write(sd, VENC_VVALID, 0);
173
174 venc_write(sd, VENC_HSDLY, 0);
175 venc_write(sd, VENC_VSDLY, 0);
176
177 venc_write(sd, VENC_YCCCTL, 0);
178 venc_write(sd, VENC_VSTARTA, 0);
179
180 /* Set OSD clock and OSD Sync Adavance registers */
181 venc_write(sd, VENC_OSDCLK0, 1);
182 venc_write(sd, VENC_OSDCLK1, 2);
183 }
184}
185
186#define VDAC_CONFIG_SD_V3 0x0E21A6B6
187#define VDAC_CONFIG_SD_V2 0x081141CF
188/*
189 * setting NTSC mode
190 */
191static int venc_set_ntsc(struct v4l2_subdev *sd)
192{
193 u32 val;
194 struct venc_state *venc = to_state(sd);
195 struct venc_platform_data *pdata = venc->pdata;
196
197 v4l2_dbg(debug, 2, sd, "venc_set_ntsc\n");
198
199 /* Setup clock at VPSS & VENC for SD */
200 vpss_enable_clock(VPSS_VENC_CLOCK_SEL, 1);
201 if (pdata->setup_clock(VPBE_ENC_STD, V4L2_STD_525_60) < 0)
202 return -EINVAL;
203
204 venc_enabledigitaloutput(sd, 0);
205
206 if (pdata->venc_type == VPBE_VERSION_3) {
207 venc_write(sd, VENC_CLKCTL, 0x01);
208 venc_write(sd, VENC_VIDCTL, 0);
209 val = vdaccfg_write(sd, VDAC_CONFIG_SD_V3);
210 } else if (pdata->venc_type == VPBE_VERSION_2) {
211 venc_write(sd, VENC_CLKCTL, 0x01);
212 venc_write(sd, VENC_VIDCTL, 0);
213 vdaccfg_write(sd, VDAC_CONFIG_SD_V2);
214 } else {
215 /* to set VENC CLK DIV to 1 - final clock is 54 MHz */
216 venc_modify(sd, VENC_VIDCTL, 0, 1 << 1);
217 /* Set REC656 Mode */
218 venc_write(sd, VENC_YCCCTL, 0x1);
219 venc_modify(sd, VENC_VDPRO, 0, VENC_VDPRO_DAFRQ);
220 venc_modify(sd, VENC_VDPRO, 0, VENC_VDPRO_DAUPS);
221 }
222
223 venc_write(sd, VENC_VMOD, 0);
224 venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT),
225 VENC_VMOD_VIE);
226 venc_modify(sd, VENC_VMOD, (0 << VENC_VMOD_VMD), VENC_VMOD_VMD);
227 venc_modify(sd, VENC_VMOD, (0 << VENC_VMOD_TVTYP_SHIFT),
228 VENC_VMOD_TVTYP);
229 venc_write(sd, VENC_DACTST, 0x0);
230 venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC);
231
232 return 0;
233}
234
235/*
236 * setting PAL mode
237 */
238static int venc_set_pal(struct v4l2_subdev *sd)
239{
240 struct venc_state *venc = to_state(sd);
241 struct venc_platform_data *pdata = venc->pdata;
242
243 v4l2_dbg(debug, 2, sd, "venc_set_pal\n");
244
245 /* Setup clock at VPSS & VENC for SD */
246 vpss_enable_clock(VPSS_VENC_CLOCK_SEL, 1);
247 if (venc->pdata->setup_clock(VPBE_ENC_STD, V4L2_STD_625_50) < 0)
248 return -EINVAL;
249
250 venc_enabledigitaloutput(sd, 0);
251
252 if (pdata->venc_type == VPBE_VERSION_3) {
253 venc_write(sd, VENC_CLKCTL, 0x1);
254 venc_write(sd, VENC_VIDCTL, 0);
255 vdaccfg_write(sd, VDAC_CONFIG_SD_V3);
256 } else if (pdata->venc_type == VPBE_VERSION_2) {
257 venc_write(sd, VENC_CLKCTL, 0x1);
258 venc_write(sd, VENC_VIDCTL, 0);
259 vdaccfg_write(sd, VDAC_CONFIG_SD_V2);
260 } else {
261 /* to set VENC CLK DIV to 1 - final clock is 54 MHz */
262 venc_modify(sd, VENC_VIDCTL, 0, 1 << 1);
263 /* Set REC656 Mode */
264 venc_write(sd, VENC_YCCCTL, 0x1);
265 }
266
267 venc_modify(sd, VENC_SYNCCTL, 1 << VENC_SYNCCTL_OVD_SHIFT,
268 VENC_SYNCCTL_OVD);
269 venc_write(sd, VENC_VMOD, 0);
270 venc_modify(sd, VENC_VMOD,
271 (1 << VENC_VMOD_VIE_SHIFT),
272 VENC_VMOD_VIE);
273 venc_modify(sd, VENC_VMOD,
274 (0 << VENC_VMOD_VMD), VENC_VMOD_VMD);
275 venc_modify(sd, VENC_VMOD,
276 (1 << VENC_VMOD_TVTYP_SHIFT),
277 VENC_VMOD_TVTYP);
278 venc_write(sd, VENC_DACTST, 0x0);
279 venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC);
280
281 return 0;
282}
283
284#define VDAC_CONFIG_HD_V2 0x081141EF
285/*
286 * venc_set_480p59_94
287 *
288 * This function configures the video encoder to EDTV(525p) component setting.
289 */
290static int venc_set_480p59_94(struct v4l2_subdev *sd)
291{
292 struct venc_state *venc = to_state(sd);
293 struct venc_platform_data *pdata = venc->pdata;
294
295 v4l2_dbg(debug, 2, sd, "venc_set_480p59_94\n");
296 if ((pdata->venc_type != VPBE_VERSION_1) &&
297 (pdata->venc_type != VPBE_VERSION_2))
298 return -EINVAL;
299
300 /* Setup clock at VPSS & VENC for SD */
301 if (pdata->setup_clock(VPBE_ENC_DV_PRESET, V4L2_DV_480P59_94) < 0)
302 return -EINVAL;
303
304 venc_enabledigitaloutput(sd, 0);
305
306 if (pdata->venc_type == VPBE_VERSION_2)
307 vdaccfg_write(sd, VDAC_CONFIG_HD_V2);
308 venc_write(sd, VENC_OSDCLK0, 0);
309 venc_write(sd, VENC_OSDCLK1, 1);
310
311 if (pdata->venc_type == VPBE_VERSION_1) {
312 venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAFRQ,
313 VENC_VDPRO_DAFRQ);
314 venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAUPS,
315 VENC_VDPRO_DAUPS);
316 }
317
318 venc_write(sd, VENC_VMOD, 0);
319 venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT),
320 VENC_VMOD_VIE);
321 venc_modify(sd, VENC_VMOD, VENC_VMOD_HDMD, VENC_VMOD_HDMD);
322 venc_modify(sd, VENC_VMOD, (HDTV_525P << VENC_VMOD_TVTYP_SHIFT),
323 VENC_VMOD_TVTYP);
324 venc_modify(sd, VENC_VMOD, VENC_VMOD_VDMD_YCBCR8 <<
325 VENC_VMOD_VDMD_SHIFT, VENC_VMOD_VDMD);
326
327 venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC);
328
329 return 0;
330}
331
332/*
333 * venc_set_625p
334 *
335 * This function configures the video encoder to HDTV(625p) component setting
336 */
337static int venc_set_576p50(struct v4l2_subdev *sd)
338{
339 struct venc_state *venc = to_state(sd);
340 struct venc_platform_data *pdata = venc->pdata;
341
342 v4l2_dbg(debug, 2, sd, "venc_set_576p50\n");
343
344 if ((pdata->venc_type != VPBE_VERSION_1) &&
345 (pdata->venc_type != VPBE_VERSION_2))
346 return -EINVAL;
347 /* Setup clock at VPSS & VENC for SD */
348 if (pdata->setup_clock(VPBE_ENC_DV_PRESET, V4L2_DV_576P50) < 0)
349 return -EINVAL;
350
351 venc_enabledigitaloutput(sd, 0);
352
353 if (pdata->venc_type == VPBE_VERSION_2)
354 vdaccfg_write(sd, VDAC_CONFIG_HD_V2);
355
356 venc_write(sd, VENC_OSDCLK0, 0);
357 venc_write(sd, VENC_OSDCLK1, 1);
358
359 if (pdata->venc_type == VPBE_VERSION_1) {
360 venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAFRQ,
361 VENC_VDPRO_DAFRQ);
362 venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAUPS,
363 VENC_VDPRO_DAUPS);
364 }
365
366 venc_write(sd, VENC_VMOD, 0);
367 venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT),
368 VENC_VMOD_VIE);
369 venc_modify(sd, VENC_VMOD, VENC_VMOD_HDMD, VENC_VMOD_HDMD);
370 venc_modify(sd, VENC_VMOD, (HDTV_625P << VENC_VMOD_TVTYP_SHIFT),
371 VENC_VMOD_TVTYP);
372
373 venc_modify(sd, VENC_VMOD, VENC_VMOD_VDMD_YCBCR8 <<
374 VENC_VMOD_VDMD_SHIFT, VENC_VMOD_VDMD);
375 venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC);
376
377 return 0;
378}
379
380/*
381 * venc_set_720p60_internal - Setup 720p60 in venc for dm365 only
382 */
383static int venc_set_720p60_internal(struct v4l2_subdev *sd)
384{
385 struct venc_state *venc = to_state(sd);
386 struct venc_platform_data *pdata = venc->pdata;
387
388 if (pdata->setup_clock(VPBE_ENC_DV_PRESET, V4L2_DV_720P60) < 0)
389 return -EINVAL;
390
391 venc_enabledigitaloutput(sd, 0);
392
393 venc_write(sd, VENC_OSDCLK0, 0);
394 venc_write(sd, VENC_OSDCLK1, 1);
395
396 venc_write(sd, VENC_VMOD, 0);
397 /* DM365 component HD mode */
398 venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT),
399 VENC_VMOD_VIE);
400 venc_modify(sd, VENC_VMOD, VENC_VMOD_HDMD, VENC_VMOD_HDMD);
401 venc_modify(sd, VENC_VMOD, (HDTV_720P << VENC_VMOD_TVTYP_SHIFT),
402 VENC_VMOD_TVTYP);
403 venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC);
404 venc_write(sd, VENC_XHINTVL, 0);
405 return 0;
406}
407
408/*
409 * venc_set_1080i30_internal - Setup 1080i30 in venc for dm365 only
410 */
411static int venc_set_1080i30_internal(struct v4l2_subdev *sd)
412{
413 struct venc_state *venc = to_state(sd);
414 struct venc_platform_data *pdata = venc->pdata;
415
416 if (pdata->setup_clock(VPBE_ENC_DV_PRESET, V4L2_DV_1080P30) < 0)
417 return -EINVAL;
418
419 venc_enabledigitaloutput(sd, 0);
420
421 venc_write(sd, VENC_OSDCLK0, 0);
422 venc_write(sd, VENC_OSDCLK1, 1);
423
424
425 venc_write(sd, VENC_VMOD, 0);
426 /* DM365 component HD mode */
427 venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT),
428 VENC_VMOD_VIE);
429 venc_modify(sd, VENC_VMOD, VENC_VMOD_HDMD, VENC_VMOD_HDMD);
430 venc_modify(sd, VENC_VMOD, (HDTV_1080I << VENC_VMOD_TVTYP_SHIFT),
431 VENC_VMOD_TVTYP);
432 venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC);
433 venc_write(sd, VENC_XHINTVL, 0);
434 return 0;
435}
436
437static int venc_s_std_output(struct v4l2_subdev *sd, v4l2_std_id norm)
438{
439 v4l2_dbg(debug, 1, sd, "venc_s_std_output\n");
440
441 if (norm & V4L2_STD_525_60)
442 return venc_set_ntsc(sd);
443 else if (norm & V4L2_STD_625_50)
444 return venc_set_pal(sd);
445
446 return -EINVAL;
447}
448
449static int venc_s_dv_preset(struct v4l2_subdev *sd,
450 struct v4l2_dv_preset *dv_preset)
451{
452 struct venc_state *venc = to_state(sd);
453 int ret;
454
455 v4l2_dbg(debug, 1, sd, "venc_s_dv_preset\n");
456
457 if (dv_preset->preset == V4L2_DV_576P50)
458 return venc_set_576p50(sd);
459 else if (dv_preset->preset == V4L2_DV_480P59_94)
460 return venc_set_480p59_94(sd);
461 else if ((dv_preset->preset == V4L2_DV_720P60) &&
462 (venc->pdata->venc_type == VPBE_VERSION_2)) {
463 /* TBD setup internal 720p mode here */
464 ret = venc_set_720p60_internal(sd);
465 /* for DM365 VPBE, there is DAC inside */
466 vdaccfg_write(sd, VDAC_CONFIG_HD_V2);
467 return ret;
468 } else if ((dv_preset->preset == V4L2_DV_1080I30) &&
469 (venc->pdata->venc_type == VPBE_VERSION_2)) {
470 /* TBD setup internal 1080i mode here */
471 ret = venc_set_1080i30_internal(sd);
472 /* for DM365 VPBE, there is DAC inside */
473 vdaccfg_write(sd, VDAC_CONFIG_HD_V2);
474 return ret;
475 }
476 return -EINVAL;
477}
478
479static int venc_s_routing(struct v4l2_subdev *sd, u32 input, u32 output,
480 u32 config)
481{
482 struct venc_state *venc = to_state(sd);
483 int ret;
484
485 v4l2_dbg(debug, 1, sd, "venc_s_routing\n");
486
487 ret = venc_set_dac(sd, output);
488 if (!ret)
489 venc->output = output;
490
491 return ret;
492}
493
494static long venc_ioctl(struct v4l2_subdev *sd,
495 unsigned int cmd,
496 void *arg)
497{
498 u32 val;
499
500 switch (cmd) {
501 case VENC_GET_FLD:
502 val = venc_read(sd, VENC_VSTAT);
503 *((int *)arg) = ((val & VENC_VSTAT_FIDST) ==
504 VENC_VSTAT_FIDST);
505 break;
506 default:
507 v4l2_err(sd, "Wrong IOCTL cmd\n");
508 break;
509 }
510
511 return 0;
512}
513
514static const struct v4l2_subdev_core_ops venc_core_ops = {
515 .ioctl = venc_ioctl,
516};
517
518static const struct v4l2_subdev_video_ops venc_video_ops = {
519 .s_routing = venc_s_routing,
520 .s_std_output = venc_s_std_output,
521 .s_dv_preset = venc_s_dv_preset,
522};
523
524static const struct v4l2_subdev_ops venc_ops = {
525 .core = &venc_core_ops,
526 .video = &venc_video_ops,
527};
528
529static int venc_initialize(struct v4l2_subdev *sd)
530{
531 struct venc_state *venc = to_state(sd);
532 int ret;
533
534 /* Set default to output to composite and std to NTSC */
535 venc->output = 0;
536 venc->std = V4L2_STD_525_60;
537
538 ret = venc_s_routing(sd, 0, venc->output, 0);
539 if (ret < 0) {
540 v4l2_err(sd, "Error setting output during init\n");
541 return -EINVAL;
542 }
543
544 ret = venc_s_std_output(sd, venc->std);
545 if (ret < 0) {
546 v4l2_err(sd, "Error setting std during init\n");
547 return -EINVAL;
548 }
549
550 return ret;
551}
552
553static int venc_device_get(struct device *dev, void *data)
554{
555 struct platform_device *pdev = to_platform_device(dev);
556 struct venc_state **venc = data;
557
558 if (strcmp(MODULE_NAME, pdev->name) == 0)
559 *venc = platform_get_drvdata(pdev);
560
561 return 0;
562}
563
564struct v4l2_subdev *venc_sub_dev_init(struct v4l2_device *v4l2_dev,
565 const char *venc_name)
566{
567 struct venc_state *venc;
568 int err;
569
570 err = bus_for_each_dev(&platform_bus_type, NULL, &venc,
571 venc_device_get);
572 if (venc == NULL)
573 return NULL;
574
575 v4l2_subdev_init(&venc->sd, &venc_ops);
576
577 strcpy(venc->sd.name, venc_name);
578 if (v4l2_device_register_subdev(v4l2_dev, &venc->sd) < 0) {
579 v4l2_err(v4l2_dev,
580 "vpbe unable to register venc sub device\n");
581 return NULL;
582 }
583 if (venc_initialize(&venc->sd)) {
584 v4l2_err(v4l2_dev,
585 "vpbe venc initialization failed\n");
586 return NULL;
587 }
588
589 return &venc->sd;
590}
591EXPORT_SYMBOL(venc_sub_dev_init);
592
593static int venc_probe(struct platform_device *pdev)
594{
595 struct venc_state *venc;
596 struct resource *res;
597 int ret;
598
599 venc = kzalloc(sizeof(struct venc_state), GFP_KERNEL);
600 if (venc == NULL)
601 return -ENOMEM;
602
603 venc->pdev = &pdev->dev;
604 venc->pdata = pdev->dev.platform_data;
605 if (NULL == venc->pdata) {
606 dev_err(venc->pdev, "Unable to get platform data for"
607 " VENC sub device");
608 ret = -ENOENT;
609 goto free_mem;
610 }
611 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
612 if (!res) {
613 dev_err(venc->pdev,
614 "Unable to get VENC register address map\n");
615 ret = -ENODEV;
616 goto free_mem;
617 }
618
619 if (!request_mem_region(res->start, resource_size(res), "venc")) {
620 dev_err(venc->pdev, "Unable to reserve VENC MMIO region\n");
621 ret = -ENODEV;
622 goto free_mem;
623 }
624
625 venc->venc_base = ioremap_nocache(res->start, resource_size(res));
626 if (!venc->venc_base) {
627 dev_err(venc->pdev, "Unable to map VENC IO space\n");
628 ret = -ENODEV;
629 goto release_venc_mem_region;
630 }
631
632 if (venc->pdata->venc_type != VPBE_VERSION_1) {
633 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
634 if (!res) {
635 dev_err(venc->pdev,
636 "Unable to get VDAC_CONFIG address map\n");
637 ret = -ENODEV;
638 goto unmap_venc_io;
639 }
640
641 if (!request_mem_region(res->start,
642 resource_size(res), "venc")) {
643 dev_err(venc->pdev,
644 "Unable to reserve VDAC_CONFIG MMIO region\n");
645 ret = -ENODEV;
646 goto unmap_venc_io;
647 }
648
649 venc->vdaccfg_reg = ioremap_nocache(res->start,
650 resource_size(res));
651 if (!venc->vdaccfg_reg) {
652 dev_err(venc->pdev,
653 "Unable to map VDAC_CONFIG IO space\n");
654 ret = -ENODEV;
655 goto release_vdaccfg_mem_region;
656 }
657 }
658 spin_lock_init(&venc->lock);
659 platform_set_drvdata(pdev, venc);
660 dev_notice(venc->pdev, "VENC sub device probe success\n");
661 return 0;
662
663release_vdaccfg_mem_region:
664 release_mem_region(res->start, resource_size(res));
665unmap_venc_io:
666 iounmap(venc->venc_base);
667release_venc_mem_region:
668 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
669 release_mem_region(res->start, resource_size(res));
670free_mem:
671 kfree(venc);
672 return ret;
673}
674
675static int venc_remove(struct platform_device *pdev)
676{
677 struct venc_state *venc = platform_get_drvdata(pdev);
678 struct resource *res;
679
680 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
681 iounmap((void *)venc->venc_base);
682 release_mem_region(res->start, resource_size(res));
683 if (venc->pdata->venc_type != VPBE_VERSION_1) {
684 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
685 iounmap((void *)venc->vdaccfg_reg);
686 release_mem_region(res->start, resource_size(res));
687 }
688 kfree(venc);
689
690 return 0;
691}
692
693static struct platform_driver venc_driver = {
694 .probe = venc_probe,
695 .remove = venc_remove,
696 .driver = {
697 .name = MODULE_NAME,
698 .owner = THIS_MODULE,
699 },
700};
701
702module_platform_driver(venc_driver);
703
704MODULE_LICENSE("GPL");
705MODULE_DESCRIPTION("VPBE VENC Driver");
706MODULE_AUTHOR("Texas Instruments");
diff --git a/drivers/media/video/davinci/vpbe_venc_regs.h b/drivers/media/video/davinci/vpbe_venc_regs.h
deleted file mode 100644
index 947cb1510776..000000000000
--- a/drivers/media/video/davinci/vpbe_venc_regs.h
+++ /dev/null
@@ -1,177 +0,0 @@
1/*
2 * Copyright (C) 2006-2010 Texas Instruments Inc
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation version 2..
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 */
17#ifndef _VPBE_VENC_REGS_H
18#define _VPBE_VENC_REGS_H
19
20/* VPBE Video Encoder / Digital LCD Subsystem Registers (VENC) */
21#define VENC_VMOD 0x00
22#define VENC_VIDCTL 0x04
23#define VENC_VDPRO 0x08
24#define VENC_SYNCCTL 0x0C
25#define VENC_HSPLS 0x10
26#define VENC_VSPLS 0x14
27#define VENC_HINT 0x18
28#define VENC_HSTART 0x1C
29#define VENC_HVALID 0x20
30#define VENC_VINT 0x24
31#define VENC_VSTART 0x28
32#define VENC_VVALID 0x2C
33#define VENC_HSDLY 0x30
34#define VENC_VSDLY 0x34
35#define VENC_YCCCTL 0x38
36#define VENC_RGBCTL 0x3C
37#define VENC_RGBCLP 0x40
38#define VENC_LINECTL 0x44
39#define VENC_CULLLINE 0x48
40#define VENC_LCDOUT 0x4C
41#define VENC_BRTS 0x50
42#define VENC_BRTW 0x54
43#define VENC_ACCTL 0x58
44#define VENC_PWMP 0x5C
45#define VENC_PWMW 0x60
46#define VENC_DCLKCTL 0x64
47#define VENC_DCLKPTN0 0x68
48#define VENC_DCLKPTN1 0x6C
49#define VENC_DCLKPTN2 0x70
50#define VENC_DCLKPTN3 0x74
51#define VENC_DCLKPTN0A 0x78
52#define VENC_DCLKPTN1A 0x7C
53#define VENC_DCLKPTN2A 0x80
54#define VENC_DCLKPTN3A 0x84
55#define VENC_DCLKHS 0x88
56#define VENC_DCLKHSA 0x8C
57#define VENC_DCLKHR 0x90
58#define VENC_DCLKVS 0x94
59#define VENC_DCLKVR 0x98
60#define VENC_CAPCTL 0x9C
61#define VENC_CAPDO 0xA0
62#define VENC_CAPDE 0xA4
63#define VENC_ATR0 0xA8
64#define VENC_ATR1 0xAC
65#define VENC_ATR2 0xB0
66#define VENC_VSTAT 0xB8
67#define VENC_RAMADR 0xBC
68#define VENC_RAMPORT 0xC0
69#define VENC_DACTST 0xC4
70#define VENC_YCOLVL 0xC8
71#define VENC_SCPROG 0xCC
72#define VENC_CVBS 0xDC
73#define VENC_CMPNT 0xE0
74#define VENC_ETMG0 0xE4
75#define VENC_ETMG1 0xE8
76#define VENC_ETMG2 0xEC
77#define VENC_ETMG3 0xF0
78#define VENC_DACSEL 0xF4
79#define VENC_ARGBX0 0x100
80#define VENC_ARGBX1 0x104
81#define VENC_ARGBX2 0x108
82#define VENC_ARGBX3 0x10C
83#define VENC_ARGBX4 0x110
84#define VENC_DRGBX0 0x114
85#define VENC_DRGBX1 0x118
86#define VENC_DRGBX2 0x11C
87#define VENC_DRGBX3 0x120
88#define VENC_DRGBX4 0x124
89#define VENC_VSTARTA 0x128
90#define VENC_OSDCLK0 0x12C
91#define VENC_OSDCLK1 0x130
92#define VENC_HVLDCL0 0x134
93#define VENC_HVLDCL1 0x138
94#define VENC_OSDHADV 0x13C
95#define VENC_CLKCTL 0x140
96#define VENC_GAMCTL 0x144
97#define VENC_XHINTVL 0x174
98
99/* bit definitions */
100#define VPBE_PCR_VENC_DIV (1 << 1)
101#define VPBE_PCR_CLK_OFF (1 << 0)
102
103#define VENC_VMOD_VDMD_SHIFT 12
104#define VENC_VMOD_VDMD_YCBCR16 0
105#define VENC_VMOD_VDMD_YCBCR8 1
106#define VENC_VMOD_VDMD_RGB666 2
107#define VENC_VMOD_VDMD_RGB8 3
108#define VENC_VMOD_VDMD_EPSON 4
109#define VENC_VMOD_VDMD_CASIO 5
110#define VENC_VMOD_VDMD_UDISPQVGA 6
111#define VENC_VMOD_VDMD_STNLCD 7
112#define VENC_VMOD_VIE_SHIFT 1
113#define VENC_VMOD_VDMD (7 << 12)
114#define VENC_VMOD_ITLCL (1 << 11)
115#define VENC_VMOD_ITLC (1 << 10)
116#define VENC_VMOD_NSIT (1 << 9)
117#define VENC_VMOD_HDMD (1 << 8)
118#define VENC_VMOD_TVTYP_SHIFT 6
119#define VENC_VMOD_TVTYP (3 << 6)
120#define VENC_VMOD_SLAVE (1 << 5)
121#define VENC_VMOD_VMD (1 << 4)
122#define VENC_VMOD_BLNK (1 << 3)
123#define VENC_VMOD_VIE (1 << 1)
124#define VENC_VMOD_VENC (1 << 0)
125
126/* VMOD TVTYP options for HDMD=0 */
127#define SDTV_NTSC 0
128#define SDTV_PAL 1
129/* VMOD TVTYP options for HDMD=1 */
130#define HDTV_525P 0
131#define HDTV_625P 1
132#define HDTV_1080I 2
133#define HDTV_720P 3
134
135#define VENC_VIDCTL_VCLKP (1 << 14)
136#define VENC_VIDCTL_VCLKE_SHIFT 13
137#define VENC_VIDCTL_VCLKE (1 << 13)
138#define VENC_VIDCTL_VCLKZ_SHIFT 12
139#define VENC_VIDCTL_VCLKZ (1 << 12)
140#define VENC_VIDCTL_SYDIR_SHIFT 8
141#define VENC_VIDCTL_SYDIR (1 << 8)
142#define VENC_VIDCTL_DOMD_SHIFT 4
143#define VENC_VIDCTL_DOMD (3 << 4)
144#define VENC_VIDCTL_YCDIR_SHIFT 0
145#define VENC_VIDCTL_YCDIR (1 << 0)
146
147#define VENC_VDPRO_ATYCC_SHIFT 5
148#define VENC_VDPRO_ATYCC (1 << 5)
149#define VENC_VDPRO_ATCOM_SHIFT 4
150#define VENC_VDPRO_ATCOM (1 << 4)
151#define VENC_VDPRO_DAFRQ (1 << 3)
152#define VENC_VDPRO_DAUPS (1 << 2)
153#define VENC_VDPRO_CUPS (1 << 1)
154#define VENC_VDPRO_YUPS (1 << 0)
155
156#define VENC_SYNCCTL_VPL_SHIFT 3
157#define VENC_SYNCCTL_VPL (1 << 3)
158#define VENC_SYNCCTL_HPL_SHIFT 2
159#define VENC_SYNCCTL_HPL (1 << 2)
160#define VENC_SYNCCTL_SYEV_SHIFT 1
161#define VENC_SYNCCTL_SYEV (1 << 1)
162#define VENC_SYNCCTL_SYEH_SHIFT 0
163#define VENC_SYNCCTL_SYEH (1 << 0)
164#define VENC_SYNCCTL_OVD_SHIFT 14
165#define VENC_SYNCCTL_OVD (1 << 14)
166
167#define VENC_DCLKCTL_DCKEC_SHIFT 11
168#define VENC_DCLKCTL_DCKEC (1 << 11)
169#define VENC_DCLKCTL_DCKPW_SHIFT 0
170#define VENC_DCLKCTL_DCKPW (0x3f << 0)
171
172#define VENC_VSTAT_FIDST (1 << 4)
173
174#define VENC_CMPNT_MRGB_SHIFT 14
175#define VENC_CMPNT_MRGB (1 << 14)
176
177#endif /* _VPBE_VENC_REGS_H */
diff --git a/drivers/media/video/davinci/vpfe_capture.c b/drivers/media/video/davinci/vpfe_capture.c
deleted file mode 100644
index 843b138faabe..000000000000
--- a/drivers/media/video/davinci/vpfe_capture.c
+++ /dev/null
@@ -1,2079 +0,0 @@
1/*
2 * Copyright (C) 2008-2009 Texas Instruments Inc
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Driver name : VPFE Capture driver
19 * VPFE Capture driver allows applications to capture and stream video
20 * frames on DaVinci SoCs (DM6446, DM355 etc) from a YUV source such as
21 * TVP5146 or Raw Bayer RGB image data from an image sensor
22 * such as Microns' MT9T001, MT9T031 etc.
23 *
24 * These SoCs have, in common, a Video Processing Subsystem (VPSS) that
25 * consists of a Video Processing Front End (VPFE) for capturing
26 * video/raw image data and Video Processing Back End (VPBE) for displaying
27 * YUV data through an in-built analog encoder or Digital LCD port. This
28 * driver is for capture through VPFE. A typical EVM using these SoCs have
29 * following high level configuration.
30 *
31 *
32 * decoder(TVP5146/ YUV/
33 * MT9T001) --> Raw Bayer RGB ---> MUX -> VPFE (CCDC/ISIF)
34 * data input | |
35 * V |
36 * SDRAM |
37 * V
38 * Image Processor
39 * |
40 * V
41 * SDRAM
42 * The data flow happens from a decoder connected to the VPFE over a
43 * YUV embedded (BT.656/BT.1120) or separate sync or raw bayer rgb interface
44 * and to the input of VPFE through an optional MUX (if more inputs are
45 * to be interfaced on the EVM). The input data is first passed through
46 * CCDC (CCD Controller, a.k.a Image Sensor Interface, ISIF). The CCDC
47 * does very little or no processing on YUV data and does pre-process Raw
48 * Bayer RGB data through modules such as Defect Pixel Correction (DFC)
49 * Color Space Conversion (CSC), data gain/offset etc. After this, data
50 * can be written to SDRAM or can be connected to the image processing
51 * block such as IPIPE (on DM355 only).
52 *
53 * Features supported
54 * - MMAP IO
55 * - Capture using TVP5146 over BT.656
56 * - support for interfacing decoders using sub device model
57 * - Work with DM355 or DM6446 CCDC to do Raw Bayer RGB/YUV
58 * data capture to SDRAM.
59 * TODO list
60 * - Support multiple REQBUF after open
61 * - Support for de-allocating buffers through REQBUF
62 * - Support for Raw Bayer RGB capture
63 * - Support for chaining Image Processor
64 * - Support for static allocation of buffers
65 * - Support for USERPTR IO
66 * - Support for STREAMON before QBUF
67 * - Support for control ioctls
68 */
69#include <linux/module.h>
70#include <linux/slab.h>
71#include <linux/init.h>
72#include <linux/platform_device.h>
73#include <linux/interrupt.h>
74#include <media/v4l2-common.h>
75#include <linux/io.h>
76#include <media/davinci/vpfe_capture.h>
77#include "ccdc_hw_device.h"
78
79static int debug;
80static u32 numbuffers = 3;
81static u32 bufsize = (720 * 576 * 2);
82
83module_param(numbuffers, uint, S_IRUGO);
84module_param(bufsize, uint, S_IRUGO);
85module_param(debug, int, 0644);
86
87MODULE_PARM_DESC(numbuffers, "buffer count (default:3)");
88MODULE_PARM_DESC(bufsize, "buffer size in bytes (default:720 x 576 x 2)");
89MODULE_PARM_DESC(debug, "Debug level 0-1");
90
91MODULE_DESCRIPTION("VPFE Video for Linux Capture Driver");
92MODULE_LICENSE("GPL");
93MODULE_AUTHOR("Texas Instruments");
94
95/* standard information */
96struct vpfe_standard {
97 v4l2_std_id std_id;
98 unsigned int width;
99 unsigned int height;
100 struct v4l2_fract pixelaspect;
101 /* 0 - progressive, 1 - interlaced */
102 int frame_format;
103};
104
105/* ccdc configuration */
106struct ccdc_config {
107 /* This make sure vpfe is probed and ready to go */
108 int vpfe_probed;
109 /* name of ccdc device */
110 char name[32];
111};
112
113/* data structures */
114static struct vpfe_config_params config_params = {
115 .min_numbuffers = 3,
116 .numbuffers = 3,
117 .min_bufsize = 720 * 480 * 2,
118 .device_bufsize = 720 * 576 * 2,
119};
120
121/* ccdc device registered */
122static struct ccdc_hw_device *ccdc_dev;
123/* lock for accessing ccdc information */
124static DEFINE_MUTEX(ccdc_lock);
125/* ccdc configuration */
126static struct ccdc_config *ccdc_cfg;
127
128const struct vpfe_standard vpfe_standards[] = {
129 {V4L2_STD_525_60, 720, 480, {11, 10}, 1},
130 {V4L2_STD_625_50, 720, 576, {54, 59}, 1},
131};
132
133/* Used when raw Bayer image from ccdc is directly captured to SDRAM */
134static const struct vpfe_pixel_format vpfe_pix_fmts[] = {
135 {
136 .fmtdesc = {
137 .index = 0,
138 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
139 .description = "Bayer GrRBGb 8bit A-Law compr.",
140 .pixelformat = V4L2_PIX_FMT_SBGGR8,
141 },
142 .bpp = 1,
143 },
144 {
145 .fmtdesc = {
146 .index = 1,
147 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
148 .description = "Bayer GrRBGb - 16bit",
149 .pixelformat = V4L2_PIX_FMT_SBGGR16,
150 },
151 .bpp = 2,
152 },
153 {
154 .fmtdesc = {
155 .index = 2,
156 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
157 .description = "Bayer GrRBGb 8bit DPCM compr.",
158 .pixelformat = V4L2_PIX_FMT_SGRBG10DPCM8,
159 },
160 .bpp = 1,
161 },
162 {
163 .fmtdesc = {
164 .index = 3,
165 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
166 .description = "YCbCr 4:2:2 Interleaved UYVY",
167 .pixelformat = V4L2_PIX_FMT_UYVY,
168 },
169 .bpp = 2,
170 },
171 {
172 .fmtdesc = {
173 .index = 4,
174 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
175 .description = "YCbCr 4:2:2 Interleaved YUYV",
176 .pixelformat = V4L2_PIX_FMT_YUYV,
177 },
178 .bpp = 2,
179 },
180 {
181 .fmtdesc = {
182 .index = 5,
183 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
184 .description = "Y/CbCr 4:2:0 - Semi planar",
185 .pixelformat = V4L2_PIX_FMT_NV12,
186 },
187 .bpp = 1,
188 },
189};
190
191/*
192 * vpfe_lookup_pix_format()
193 * lookup an entry in the vpfe pix format table based on pix_format
194 */
195static const struct vpfe_pixel_format *vpfe_lookup_pix_format(u32 pix_format)
196{
197 int i;
198
199 for (i = 0; i < ARRAY_SIZE(vpfe_pix_fmts); i++) {
200 if (pix_format == vpfe_pix_fmts[i].fmtdesc.pixelformat)
201 return &vpfe_pix_fmts[i];
202 }
203 return NULL;
204}
205
206/*
207 * vpfe_register_ccdc_device. CCDC module calls this to
208 * register with vpfe capture
209 */
210int vpfe_register_ccdc_device(struct ccdc_hw_device *dev)
211{
212 int ret = 0;
213 printk(KERN_NOTICE "vpfe_register_ccdc_device: %s\n", dev->name);
214
215 BUG_ON(!dev->hw_ops.open);
216 BUG_ON(!dev->hw_ops.enable);
217 BUG_ON(!dev->hw_ops.set_hw_if_params);
218 BUG_ON(!dev->hw_ops.configure);
219 BUG_ON(!dev->hw_ops.set_buftype);
220 BUG_ON(!dev->hw_ops.get_buftype);
221 BUG_ON(!dev->hw_ops.enum_pix);
222 BUG_ON(!dev->hw_ops.set_frame_format);
223 BUG_ON(!dev->hw_ops.get_frame_format);
224 BUG_ON(!dev->hw_ops.get_pixel_format);
225 BUG_ON(!dev->hw_ops.set_pixel_format);
226 BUG_ON(!dev->hw_ops.set_image_window);
227 BUG_ON(!dev->hw_ops.get_image_window);
228 BUG_ON(!dev->hw_ops.get_line_length);
229 BUG_ON(!dev->hw_ops.getfid);
230
231 mutex_lock(&ccdc_lock);
232 if (NULL == ccdc_cfg) {
233 /*
234 * TODO. Will this ever happen? if so, we need to fix it.
235 * Proabably we need to add the request to a linked list and
236 * walk through it during vpfe probe
237 */
238 printk(KERN_ERR "vpfe capture not initialized\n");
239 ret = -EFAULT;
240 goto unlock;
241 }
242
243 if (strcmp(dev->name, ccdc_cfg->name)) {
244 /* ignore this ccdc */
245 ret = -EINVAL;
246 goto unlock;
247 }
248
249 if (ccdc_dev) {
250 printk(KERN_ERR "ccdc already registered\n");
251 ret = -EINVAL;
252 goto unlock;
253 }
254
255 ccdc_dev = dev;
256unlock:
257 mutex_unlock(&ccdc_lock);
258 return ret;
259}
260EXPORT_SYMBOL(vpfe_register_ccdc_device);
261
262/*
263 * vpfe_unregister_ccdc_device. CCDC module calls this to
264 * unregister with vpfe capture
265 */
266void vpfe_unregister_ccdc_device(struct ccdc_hw_device *dev)
267{
268 if (NULL == dev) {
269 printk(KERN_ERR "invalid ccdc device ptr\n");
270 return;
271 }
272
273 printk(KERN_NOTICE "vpfe_unregister_ccdc_device, dev->name = %s\n",
274 dev->name);
275
276 if (strcmp(dev->name, ccdc_cfg->name)) {
277 /* ignore this ccdc */
278 return;
279 }
280
281 mutex_lock(&ccdc_lock);
282 ccdc_dev = NULL;
283 mutex_unlock(&ccdc_lock);
284 return;
285}
286EXPORT_SYMBOL(vpfe_unregister_ccdc_device);
287
288/*
289 * vpfe_get_ccdc_image_format - Get image parameters based on CCDC settings
290 */
291static int vpfe_get_ccdc_image_format(struct vpfe_device *vpfe_dev,
292 struct v4l2_format *f)
293{
294 struct v4l2_rect image_win;
295 enum ccdc_buftype buf_type;
296 enum ccdc_frmfmt frm_fmt;
297
298 memset(f, 0, sizeof(*f));
299 f->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
300 ccdc_dev->hw_ops.get_image_window(&image_win);
301 f->fmt.pix.width = image_win.width;
302 f->fmt.pix.height = image_win.height;
303 f->fmt.pix.bytesperline = ccdc_dev->hw_ops.get_line_length();
304 f->fmt.pix.sizeimage = f->fmt.pix.bytesperline *
305 f->fmt.pix.height;
306 buf_type = ccdc_dev->hw_ops.get_buftype();
307 f->fmt.pix.pixelformat = ccdc_dev->hw_ops.get_pixel_format();
308 frm_fmt = ccdc_dev->hw_ops.get_frame_format();
309 if (frm_fmt == CCDC_FRMFMT_PROGRESSIVE)
310 f->fmt.pix.field = V4L2_FIELD_NONE;
311 else if (frm_fmt == CCDC_FRMFMT_INTERLACED) {
312 if (buf_type == CCDC_BUFTYPE_FLD_INTERLEAVED)
313 f->fmt.pix.field = V4L2_FIELD_INTERLACED;
314 else if (buf_type == CCDC_BUFTYPE_FLD_SEPARATED)
315 f->fmt.pix.field = V4L2_FIELD_SEQ_TB;
316 else {
317 v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buf_type\n");
318 return -EINVAL;
319 }
320 } else {
321 v4l2_err(&vpfe_dev->v4l2_dev, "Invalid frm_fmt\n");
322 return -EINVAL;
323 }
324 return 0;
325}
326
327/*
328 * vpfe_config_ccdc_image_format()
329 * For a pix format, configure ccdc to setup the capture
330 */
331static int vpfe_config_ccdc_image_format(struct vpfe_device *vpfe_dev)
332{
333 enum ccdc_frmfmt frm_fmt = CCDC_FRMFMT_INTERLACED;
334 int ret = 0;
335
336 if (ccdc_dev->hw_ops.set_pixel_format(
337 vpfe_dev->fmt.fmt.pix.pixelformat) < 0) {
338 v4l2_err(&vpfe_dev->v4l2_dev,
339 "couldn't set pix format in ccdc\n");
340 return -EINVAL;
341 }
342 /* configure the image window */
343 ccdc_dev->hw_ops.set_image_window(&vpfe_dev->crop);
344
345 switch (vpfe_dev->fmt.fmt.pix.field) {
346 case V4L2_FIELD_INTERLACED:
347 /* do nothing, since it is default */
348 ret = ccdc_dev->hw_ops.set_buftype(
349 CCDC_BUFTYPE_FLD_INTERLEAVED);
350 break;
351 case V4L2_FIELD_NONE:
352 frm_fmt = CCDC_FRMFMT_PROGRESSIVE;
353 /* buffer type only applicable for interlaced scan */
354 break;
355 case V4L2_FIELD_SEQ_TB:
356 ret = ccdc_dev->hw_ops.set_buftype(
357 CCDC_BUFTYPE_FLD_SEPARATED);
358 break;
359 default:
360 return -EINVAL;
361 }
362
363 /* set the frame format */
364 if (!ret)
365 ret = ccdc_dev->hw_ops.set_frame_format(frm_fmt);
366 return ret;
367}
368/*
369 * vpfe_config_image_format()
370 * For a given standard, this functions sets up the default
371 * pix format & crop values in the vpfe device and ccdc. It first
372 * starts with defaults based values from the standard table.
373 * It then checks if sub device support g_mbus_fmt and then override the
374 * values based on that.Sets crop values to match with scan resolution
375 * starting at 0,0. It calls vpfe_config_ccdc_image_format() set the
376 * values in ccdc
377 */
378static int vpfe_config_image_format(struct vpfe_device *vpfe_dev,
379 const v4l2_std_id *std_id)
380{
381 struct vpfe_subdev_info *sdinfo = vpfe_dev->current_subdev;
382 struct v4l2_mbus_framefmt mbus_fmt;
383 struct v4l2_pix_format *pix = &vpfe_dev->fmt.fmt.pix;
384 int i, ret = 0;
385
386 for (i = 0; i < ARRAY_SIZE(vpfe_standards); i++) {
387 if (vpfe_standards[i].std_id & *std_id) {
388 vpfe_dev->std_info.active_pixels =
389 vpfe_standards[i].width;
390 vpfe_dev->std_info.active_lines =
391 vpfe_standards[i].height;
392 vpfe_dev->std_info.frame_format =
393 vpfe_standards[i].frame_format;
394 vpfe_dev->std_index = i;
395 break;
396 }
397 }
398
399 if (i == ARRAY_SIZE(vpfe_standards)) {
400 v4l2_err(&vpfe_dev->v4l2_dev, "standard not supported\n");
401 return -EINVAL;
402 }
403
404 vpfe_dev->crop.top = 0;
405 vpfe_dev->crop.left = 0;
406 vpfe_dev->crop.width = vpfe_dev->std_info.active_pixels;
407 vpfe_dev->crop.height = vpfe_dev->std_info.active_lines;
408 pix->width = vpfe_dev->crop.width;
409 pix->height = vpfe_dev->crop.height;
410
411 /* first field and frame format based on standard frame format */
412 if (vpfe_dev->std_info.frame_format) {
413 pix->field = V4L2_FIELD_INTERLACED;
414 /* assume V4L2_PIX_FMT_UYVY as default */
415 pix->pixelformat = V4L2_PIX_FMT_UYVY;
416 v4l2_fill_mbus_format(&mbus_fmt, pix,
417 V4L2_MBUS_FMT_YUYV10_2X10);
418 } else {
419 pix->field = V4L2_FIELD_NONE;
420 /* assume V4L2_PIX_FMT_SBGGR8 */
421 pix->pixelformat = V4L2_PIX_FMT_SBGGR8;
422 v4l2_fill_mbus_format(&mbus_fmt, pix,
423 V4L2_MBUS_FMT_SBGGR8_1X8);
424 }
425
426 /* if sub device supports g_mbus_fmt, override the defaults */
427 ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev,
428 sdinfo->grp_id, video, g_mbus_fmt, &mbus_fmt);
429
430 if (ret && ret != -ENOIOCTLCMD) {
431 v4l2_err(&vpfe_dev->v4l2_dev,
432 "error in getting g_mbus_fmt from sub device\n");
433 return ret;
434 }
435 v4l2_fill_pix_format(pix, &mbus_fmt);
436 pix->bytesperline = pix->width * 2;
437 pix->sizeimage = pix->bytesperline * pix->height;
438
439 /* Sets the values in CCDC */
440 ret = vpfe_config_ccdc_image_format(vpfe_dev);
441 if (ret)
442 return ret;
443
444 /* Update the values of sizeimage and bytesperline */
445 if (!ret) {
446 pix->bytesperline = ccdc_dev->hw_ops.get_line_length();
447 pix->sizeimage = pix->bytesperline * pix->height;
448 }
449 return ret;
450}
451
452static int vpfe_initialize_device(struct vpfe_device *vpfe_dev)
453{
454 int ret = 0;
455
456 /* set first input of current subdevice as the current input */
457 vpfe_dev->current_input = 0;
458
459 /* set default standard */
460 vpfe_dev->std_index = 0;
461
462 /* Configure the default format information */
463 ret = vpfe_config_image_format(vpfe_dev,
464 &vpfe_standards[vpfe_dev->std_index].std_id);
465 if (ret)
466 return ret;
467
468 /* now open the ccdc device to initialize it */
469 mutex_lock(&ccdc_lock);
470 if (NULL == ccdc_dev) {
471 v4l2_err(&vpfe_dev->v4l2_dev, "ccdc device not registered\n");
472 ret = -ENODEV;
473 goto unlock;
474 }
475
476 if (!try_module_get(ccdc_dev->owner)) {
477 v4l2_err(&vpfe_dev->v4l2_dev, "Couldn't lock ccdc module\n");
478 ret = -ENODEV;
479 goto unlock;
480 }
481 ret = ccdc_dev->hw_ops.open(vpfe_dev->pdev);
482 if (!ret)
483 vpfe_dev->initialized = 1;
484
485 /* Clear all VPFE/CCDC interrupts */
486 if (vpfe_dev->cfg->clr_intr)
487 vpfe_dev->cfg->clr_intr(-1);
488
489unlock:
490 mutex_unlock(&ccdc_lock);
491 return ret;
492}
493
494/*
495 * vpfe_open : It creates object of file handle structure and
496 * stores it in private_data member of filepointer
497 */
498static int vpfe_open(struct file *file)
499{
500 struct vpfe_device *vpfe_dev = video_drvdata(file);
501 struct vpfe_fh *fh;
502
503 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_open\n");
504
505 if (!vpfe_dev->cfg->num_subdevs) {
506 v4l2_err(&vpfe_dev->v4l2_dev, "No decoder registered\n");
507 return -ENODEV;
508 }
509
510 /* Allocate memory for the file handle object */
511 fh = kmalloc(sizeof(struct vpfe_fh), GFP_KERNEL);
512 if (NULL == fh) {
513 v4l2_err(&vpfe_dev->v4l2_dev,
514 "unable to allocate memory for file handle object\n");
515 return -ENOMEM;
516 }
517 /* store pointer to fh in private_data member of file */
518 file->private_data = fh;
519 fh->vpfe_dev = vpfe_dev;
520 mutex_lock(&vpfe_dev->lock);
521 /* If decoder is not initialized. initialize it */
522 if (!vpfe_dev->initialized) {
523 if (vpfe_initialize_device(vpfe_dev)) {
524 mutex_unlock(&vpfe_dev->lock);
525 return -ENODEV;
526 }
527 }
528 /* Increment device usrs counter */
529 vpfe_dev->usrs++;
530 /* Set io_allowed member to false */
531 fh->io_allowed = 0;
532 /* Initialize priority of this instance to default priority */
533 fh->prio = V4L2_PRIORITY_UNSET;
534 v4l2_prio_open(&vpfe_dev->prio, &fh->prio);
535 mutex_unlock(&vpfe_dev->lock);
536 return 0;
537}
538
539static void vpfe_schedule_next_buffer(struct vpfe_device *vpfe_dev)
540{
541 unsigned long addr;
542
543 vpfe_dev->next_frm = list_entry(vpfe_dev->dma_queue.next,
544 struct videobuf_buffer, queue);
545 list_del(&vpfe_dev->next_frm->queue);
546 vpfe_dev->next_frm->state = VIDEOBUF_ACTIVE;
547 addr = videobuf_to_dma_contig(vpfe_dev->next_frm);
548
549 ccdc_dev->hw_ops.setfbaddr(addr);
550}
551
552static void vpfe_schedule_bottom_field(struct vpfe_device *vpfe_dev)
553{
554 unsigned long addr;
555
556 addr = videobuf_to_dma_contig(vpfe_dev->cur_frm);
557 addr += vpfe_dev->field_off;
558 ccdc_dev->hw_ops.setfbaddr(addr);
559}
560
561static void vpfe_process_buffer_complete(struct vpfe_device *vpfe_dev)
562{
563 struct timeval timevalue;
564
565 do_gettimeofday(&timevalue);
566 vpfe_dev->cur_frm->ts = timevalue;
567 vpfe_dev->cur_frm->state = VIDEOBUF_DONE;
568 vpfe_dev->cur_frm->size = vpfe_dev->fmt.fmt.pix.sizeimage;
569 wake_up_interruptible(&vpfe_dev->cur_frm->done);
570 vpfe_dev->cur_frm = vpfe_dev->next_frm;
571}
572
573/* ISR for VINT0*/
574static irqreturn_t vpfe_isr(int irq, void *dev_id)
575{
576 struct vpfe_device *vpfe_dev = dev_id;
577 enum v4l2_field field;
578 int fid;
579
580 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "\nStarting vpfe_isr...\n");
581 field = vpfe_dev->fmt.fmt.pix.field;
582
583 /* if streaming not started, don't do anything */
584 if (!vpfe_dev->started)
585 goto clear_intr;
586
587 /* only for 6446 this will be applicable */
588 if (NULL != ccdc_dev->hw_ops.reset)
589 ccdc_dev->hw_ops.reset();
590
591 if (field == V4L2_FIELD_NONE) {
592 /* handle progressive frame capture */
593 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
594 "frame format is progressive...\n");
595 if (vpfe_dev->cur_frm != vpfe_dev->next_frm)
596 vpfe_process_buffer_complete(vpfe_dev);
597 goto clear_intr;
598 }
599
600 /* interlaced or TB capture check which field we are in hardware */
601 fid = ccdc_dev->hw_ops.getfid();
602
603 /* switch the software maintained field id */
604 vpfe_dev->field_id ^= 1;
605 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "field id = %x:%x.\n",
606 fid, vpfe_dev->field_id);
607 if (fid == vpfe_dev->field_id) {
608 /* we are in-sync here,continue */
609 if (fid == 0) {
610 /*
611 * One frame is just being captured. If the next frame
612 * is available, release the current frame and move on
613 */
614 if (vpfe_dev->cur_frm != vpfe_dev->next_frm)
615 vpfe_process_buffer_complete(vpfe_dev);
616 /*
617 * based on whether the two fields are stored
618 * interleavely or separately in memory, reconfigure
619 * the CCDC memory address
620 */
621 if (field == V4L2_FIELD_SEQ_TB) {
622 vpfe_schedule_bottom_field(vpfe_dev);
623 }
624 goto clear_intr;
625 }
626 /*
627 * if one field is just being captured configure
628 * the next frame get the next frame from the empty
629 * queue if no frame is available hold on to the
630 * current buffer
631 */
632 spin_lock(&vpfe_dev->dma_queue_lock);
633 if (!list_empty(&vpfe_dev->dma_queue) &&
634 vpfe_dev->cur_frm == vpfe_dev->next_frm)
635 vpfe_schedule_next_buffer(vpfe_dev);
636 spin_unlock(&vpfe_dev->dma_queue_lock);
637 } else if (fid == 0) {
638 /*
639 * out of sync. Recover from any hardware out-of-sync.
640 * May loose one frame
641 */
642 vpfe_dev->field_id = fid;
643 }
644clear_intr:
645 if (vpfe_dev->cfg->clr_intr)
646 vpfe_dev->cfg->clr_intr(irq);
647
648 return IRQ_HANDLED;
649}
650
651/* vdint1_isr - isr handler for VINT1 interrupt */
652static irqreturn_t vdint1_isr(int irq, void *dev_id)
653{
654 struct vpfe_device *vpfe_dev = dev_id;
655
656 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "\nInside vdint1_isr...\n");
657
658 /* if streaming not started, don't do anything */
659 if (!vpfe_dev->started) {
660 if (vpfe_dev->cfg->clr_intr)
661 vpfe_dev->cfg->clr_intr(irq);
662 return IRQ_HANDLED;
663 }
664
665 spin_lock(&vpfe_dev->dma_queue_lock);
666 if ((vpfe_dev->fmt.fmt.pix.field == V4L2_FIELD_NONE) &&
667 !list_empty(&vpfe_dev->dma_queue) &&
668 vpfe_dev->cur_frm == vpfe_dev->next_frm)
669 vpfe_schedule_next_buffer(vpfe_dev);
670 spin_unlock(&vpfe_dev->dma_queue_lock);
671
672 if (vpfe_dev->cfg->clr_intr)
673 vpfe_dev->cfg->clr_intr(irq);
674
675 return IRQ_HANDLED;
676}
677
678static void vpfe_detach_irq(struct vpfe_device *vpfe_dev)
679{
680 enum ccdc_frmfmt frame_format;
681
682 frame_format = ccdc_dev->hw_ops.get_frame_format();
683 if (frame_format == CCDC_FRMFMT_PROGRESSIVE)
684 free_irq(vpfe_dev->ccdc_irq1, vpfe_dev);
685}
686
687static int vpfe_attach_irq(struct vpfe_device *vpfe_dev)
688{
689 enum ccdc_frmfmt frame_format;
690
691 frame_format = ccdc_dev->hw_ops.get_frame_format();
692 if (frame_format == CCDC_FRMFMT_PROGRESSIVE) {
693 return request_irq(vpfe_dev->ccdc_irq1, vdint1_isr,
694 IRQF_DISABLED, "vpfe_capture1",
695 vpfe_dev);
696 }
697 return 0;
698}
699
700/* vpfe_stop_ccdc_capture: stop streaming in ccdc/isif */
701static void vpfe_stop_ccdc_capture(struct vpfe_device *vpfe_dev)
702{
703 vpfe_dev->started = 0;
704 ccdc_dev->hw_ops.enable(0);
705 if (ccdc_dev->hw_ops.enable_out_to_sdram)
706 ccdc_dev->hw_ops.enable_out_to_sdram(0);
707}
708
709/*
710 * vpfe_release : This function deletes buffer queue, frees the
711 * buffers and the vpfe file handle
712 */
713static int vpfe_release(struct file *file)
714{
715 struct vpfe_device *vpfe_dev = video_drvdata(file);
716 struct vpfe_fh *fh = file->private_data;
717 struct vpfe_subdev_info *sdinfo;
718 int ret;
719
720 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_release\n");
721
722 /* Get the device lock */
723 mutex_lock(&vpfe_dev->lock);
724 /* if this instance is doing IO */
725 if (fh->io_allowed) {
726 if (vpfe_dev->started) {
727 sdinfo = vpfe_dev->current_subdev;
728 ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev,
729 sdinfo->grp_id,
730 video, s_stream, 0);
731 if (ret && (ret != -ENOIOCTLCMD))
732 v4l2_err(&vpfe_dev->v4l2_dev,
733 "stream off failed in subdev\n");
734 vpfe_stop_ccdc_capture(vpfe_dev);
735 vpfe_detach_irq(vpfe_dev);
736 videobuf_streamoff(&vpfe_dev->buffer_queue);
737 }
738 vpfe_dev->io_usrs = 0;
739 vpfe_dev->numbuffers = config_params.numbuffers;
740 }
741
742 /* Decrement device usrs counter */
743 vpfe_dev->usrs--;
744 /* Close the priority */
745 v4l2_prio_close(&vpfe_dev->prio, fh->prio);
746 /* If this is the last file handle */
747 if (!vpfe_dev->usrs) {
748 vpfe_dev->initialized = 0;
749 if (ccdc_dev->hw_ops.close)
750 ccdc_dev->hw_ops.close(vpfe_dev->pdev);
751 module_put(ccdc_dev->owner);
752 }
753 mutex_unlock(&vpfe_dev->lock);
754 file->private_data = NULL;
755 /* Free memory allocated to file handle object */
756 kfree(fh);
757 return 0;
758}
759
760/*
761 * vpfe_mmap : It is used to map kernel space buffers
762 * into user spaces
763 */
764static int vpfe_mmap(struct file *file, struct vm_area_struct *vma)
765{
766 /* Get the device object and file handle object */
767 struct vpfe_device *vpfe_dev = video_drvdata(file);
768
769 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_mmap\n");
770
771 return videobuf_mmap_mapper(&vpfe_dev->buffer_queue, vma);
772}
773
774/*
775 * vpfe_poll: It is used for select/poll system call
776 */
777static unsigned int vpfe_poll(struct file *file, poll_table *wait)
778{
779 struct vpfe_device *vpfe_dev = video_drvdata(file);
780
781 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_poll\n");
782
783 if (vpfe_dev->started)
784 return videobuf_poll_stream(file,
785 &vpfe_dev->buffer_queue, wait);
786 return 0;
787}
788
789/* vpfe capture driver file operations */
790static const struct v4l2_file_operations vpfe_fops = {
791 .owner = THIS_MODULE,
792 .open = vpfe_open,
793 .release = vpfe_release,
794 .unlocked_ioctl = video_ioctl2,
795 .mmap = vpfe_mmap,
796 .poll = vpfe_poll
797};
798
799/*
800 * vpfe_check_format()
801 * This function adjust the input pixel format as per hardware
802 * capabilities and update the same in pixfmt.
803 * Following algorithm used :-
804 *
805 * If given pixformat is not in the vpfe list of pix formats or not
806 * supported by the hardware, current value of pixformat in the device
807 * is used
808 * If given field is not supported, then current field is used. If field
809 * is different from current, then it is matched with that from sub device.
810 * Minimum height is 2 lines for interlaced or tb field and 1 line for
811 * progressive. Maximum height is clamped to active active lines of scan
812 * Minimum width is 32 bytes in memory and width is clamped to active
813 * pixels of scan.
814 * bytesperline is a multiple of 32.
815 */
816static const struct vpfe_pixel_format *
817 vpfe_check_format(struct vpfe_device *vpfe_dev,
818 struct v4l2_pix_format *pixfmt)
819{
820 u32 min_height = 1, min_width = 32, max_width, max_height;
821 const struct vpfe_pixel_format *vpfe_pix_fmt;
822 u32 pix;
823 int temp, found;
824
825 vpfe_pix_fmt = vpfe_lookup_pix_format(pixfmt->pixelformat);
826 if (NULL == vpfe_pix_fmt) {
827 /*
828 * use current pixel format in the vpfe device. We
829 * will find this pix format in the table
830 */
831 pixfmt->pixelformat = vpfe_dev->fmt.fmt.pix.pixelformat;
832 vpfe_pix_fmt = vpfe_lookup_pix_format(pixfmt->pixelformat);
833 }
834
835 /* check if hw supports it */
836 temp = 0;
837 found = 0;
838 while (ccdc_dev->hw_ops.enum_pix(&pix, temp) >= 0) {
839 if (vpfe_pix_fmt->fmtdesc.pixelformat == pix) {
840 found = 1;
841 break;
842 }
843 temp++;
844 }
845
846 if (!found) {
847 /* use current pixel format */
848 pixfmt->pixelformat = vpfe_dev->fmt.fmt.pix.pixelformat;
849 /*
850 * Since this is currently used in the vpfe device, we
851 * will find this pix format in the table
852 */
853 vpfe_pix_fmt = vpfe_lookup_pix_format(pixfmt->pixelformat);
854 }
855
856 /* check what field format is supported */
857 if (pixfmt->field == V4L2_FIELD_ANY) {
858 /* if field is any, use current value as default */
859 pixfmt->field = vpfe_dev->fmt.fmt.pix.field;
860 }
861
862 /*
863 * if field is not same as current field in the vpfe device
864 * try matching the field with the sub device field
865 */
866 if (vpfe_dev->fmt.fmt.pix.field != pixfmt->field) {
867 /*
868 * If field value is not in the supported fields, use current
869 * field used in the device as default
870 */
871 switch (pixfmt->field) {
872 case V4L2_FIELD_INTERLACED:
873 case V4L2_FIELD_SEQ_TB:
874 /* if sub device is supporting progressive, use that */
875 if (!vpfe_dev->std_info.frame_format)
876 pixfmt->field = V4L2_FIELD_NONE;
877 break;
878 case V4L2_FIELD_NONE:
879 if (vpfe_dev->std_info.frame_format)
880 pixfmt->field = V4L2_FIELD_INTERLACED;
881 break;
882
883 default:
884 /* use current field as default */
885 pixfmt->field = vpfe_dev->fmt.fmt.pix.field;
886 break;
887 }
888 }
889
890 /* Now adjust image resolutions supported */
891 if (pixfmt->field == V4L2_FIELD_INTERLACED ||
892 pixfmt->field == V4L2_FIELD_SEQ_TB)
893 min_height = 2;
894
895 max_width = vpfe_dev->std_info.active_pixels;
896 max_height = vpfe_dev->std_info.active_lines;
897 min_width /= vpfe_pix_fmt->bpp;
898
899 v4l2_info(&vpfe_dev->v4l2_dev, "width = %d, height = %d, bpp = %d\n",
900 pixfmt->width, pixfmt->height, vpfe_pix_fmt->bpp);
901
902 pixfmt->width = clamp((pixfmt->width), min_width, max_width);
903 pixfmt->height = clamp((pixfmt->height), min_height, max_height);
904
905 /* If interlaced, adjust height to be a multiple of 2 */
906 if (pixfmt->field == V4L2_FIELD_INTERLACED)
907 pixfmt->height &= (~1);
908 /*
909 * recalculate bytesperline and sizeimage since width
910 * and height might have changed
911 */
912 pixfmt->bytesperline = (((pixfmt->width * vpfe_pix_fmt->bpp) + 31)
913 & ~31);
914 if (pixfmt->pixelformat == V4L2_PIX_FMT_NV12)
915 pixfmt->sizeimage =
916 pixfmt->bytesperline * pixfmt->height +
917 ((pixfmt->bytesperline * pixfmt->height) >> 1);
918 else
919 pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height;
920
921 v4l2_info(&vpfe_dev->v4l2_dev, "adjusted width = %d, height ="
922 " %d, bpp = %d, bytesperline = %d, sizeimage = %d\n",
923 pixfmt->width, pixfmt->height, vpfe_pix_fmt->bpp,
924 pixfmt->bytesperline, pixfmt->sizeimage);
925 return vpfe_pix_fmt;
926}
927
928static int vpfe_querycap(struct file *file, void *priv,
929 struct v4l2_capability *cap)
930{
931 struct vpfe_device *vpfe_dev = video_drvdata(file);
932
933 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_querycap\n");
934
935 cap->version = VPFE_CAPTURE_VERSION_CODE;
936 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
937 strlcpy(cap->driver, CAPTURE_DRV_NAME, sizeof(cap->driver));
938 strlcpy(cap->bus_info, "VPFE", sizeof(cap->bus_info));
939 strlcpy(cap->card, vpfe_dev->cfg->card_name, sizeof(cap->card));
940 return 0;
941}
942
943static int vpfe_g_fmt_vid_cap(struct file *file, void *priv,
944 struct v4l2_format *fmt)
945{
946 struct vpfe_device *vpfe_dev = video_drvdata(file);
947 int ret = 0;
948
949 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_g_fmt_vid_cap\n");
950 /* Fill in the information about format */
951 *fmt = vpfe_dev->fmt;
952 return ret;
953}
954
955static int vpfe_enum_fmt_vid_cap(struct file *file, void *priv,
956 struct v4l2_fmtdesc *fmt)
957{
958 struct vpfe_device *vpfe_dev = video_drvdata(file);
959 const struct vpfe_pixel_format *pix_fmt;
960 int temp_index;
961 u32 pix;
962
963 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_enum_fmt_vid_cap\n");
964
965 if (ccdc_dev->hw_ops.enum_pix(&pix, fmt->index) < 0)
966 return -EINVAL;
967
968 /* Fill in the information about format */
969 pix_fmt = vpfe_lookup_pix_format(pix);
970 if (NULL != pix_fmt) {
971 temp_index = fmt->index;
972 *fmt = pix_fmt->fmtdesc;
973 fmt->index = temp_index;
974 return 0;
975 }
976 return -EINVAL;
977}
978
979static int vpfe_s_fmt_vid_cap(struct file *file, void *priv,
980 struct v4l2_format *fmt)
981{
982 struct vpfe_device *vpfe_dev = video_drvdata(file);
983 const struct vpfe_pixel_format *pix_fmts;
984 int ret = 0;
985
986 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_fmt_vid_cap\n");
987
988 /* If streaming is started, return error */
989 if (vpfe_dev->started) {
990 v4l2_err(&vpfe_dev->v4l2_dev, "Streaming is started\n");
991 return -EBUSY;
992 }
993
994 /* Check for valid frame format */
995 pix_fmts = vpfe_check_format(vpfe_dev, &fmt->fmt.pix);
996
997 if (NULL == pix_fmts)
998 return -EINVAL;
999
1000 /* store the pixel format in the device object */
1001 ret = mutex_lock_interruptible(&vpfe_dev->lock);
1002 if (ret)
1003 return ret;
1004
1005 /* First detach any IRQ if currently attached */
1006 vpfe_detach_irq(vpfe_dev);
1007 vpfe_dev->fmt = *fmt;
1008 /* set image capture parameters in the ccdc */
1009 ret = vpfe_config_ccdc_image_format(vpfe_dev);
1010 mutex_unlock(&vpfe_dev->lock);
1011 return ret;
1012}
1013
1014static int vpfe_try_fmt_vid_cap(struct file *file, void *priv,
1015 struct v4l2_format *f)
1016{
1017 struct vpfe_device *vpfe_dev = video_drvdata(file);
1018 const struct vpfe_pixel_format *pix_fmts;
1019
1020 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_try_fmt_vid_cap\n");
1021
1022 pix_fmts = vpfe_check_format(vpfe_dev, &f->fmt.pix);
1023 if (NULL == pix_fmts)
1024 return -EINVAL;
1025 return 0;
1026}
1027
1028/*
1029 * vpfe_get_subdev_input_index - Get subdev index and subdev input index for a
1030 * given app input index
1031 */
1032static int vpfe_get_subdev_input_index(struct vpfe_device *vpfe_dev,
1033 int *subdev_index,
1034 int *subdev_input_index,
1035 int app_input_index)
1036{
1037 struct vpfe_config *cfg = vpfe_dev->cfg;
1038 struct vpfe_subdev_info *sdinfo;
1039 int i, j = 0;
1040
1041 for (i = 0; i < cfg->num_subdevs; i++) {
1042 sdinfo = &cfg->sub_devs[i];
1043 if (app_input_index < (j + sdinfo->num_inputs)) {
1044 *subdev_index = i;
1045 *subdev_input_index = app_input_index - j;
1046 return 0;
1047 }
1048 j += sdinfo->num_inputs;
1049 }
1050 return -EINVAL;
1051}
1052
1053/*
1054 * vpfe_get_app_input - Get app input index for a given subdev input index
1055 * driver stores the input index of the current sub device and translate it
1056 * when application request the current input
1057 */
1058static int vpfe_get_app_input_index(struct vpfe_device *vpfe_dev,
1059 int *app_input_index)
1060{
1061 struct vpfe_config *cfg = vpfe_dev->cfg;
1062 struct vpfe_subdev_info *sdinfo;
1063 int i, j = 0;
1064
1065 for (i = 0; i < cfg->num_subdevs; i++) {
1066 sdinfo = &cfg->sub_devs[i];
1067 if (!strcmp(sdinfo->name, vpfe_dev->current_subdev->name)) {
1068 if (vpfe_dev->current_input >= sdinfo->num_inputs)
1069 return -1;
1070 *app_input_index = j + vpfe_dev->current_input;
1071 return 0;
1072 }
1073 j += sdinfo->num_inputs;
1074 }
1075 return -EINVAL;
1076}
1077
1078static int vpfe_enum_input(struct file *file, void *priv,
1079 struct v4l2_input *inp)
1080{
1081 struct vpfe_device *vpfe_dev = video_drvdata(file);
1082 struct vpfe_subdev_info *sdinfo;
1083 int subdev, index ;
1084
1085 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_enum_input\n");
1086
1087 if (vpfe_get_subdev_input_index(vpfe_dev,
1088 &subdev,
1089 &index,
1090 inp->index) < 0) {
1091 v4l2_err(&vpfe_dev->v4l2_dev, "input information not found"
1092 " for the subdev\n");
1093 return -EINVAL;
1094 }
1095 sdinfo = &vpfe_dev->cfg->sub_devs[subdev];
1096 memcpy(inp, &sdinfo->inputs[index], sizeof(struct v4l2_input));
1097 return 0;
1098}
1099
1100static int vpfe_g_input(struct file *file, void *priv, unsigned int *index)
1101{
1102 struct vpfe_device *vpfe_dev = video_drvdata(file);
1103
1104 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_g_input\n");
1105
1106 return vpfe_get_app_input_index(vpfe_dev, index);
1107}
1108
1109
1110static int vpfe_s_input(struct file *file, void *priv, unsigned int index)
1111{
1112 struct vpfe_device *vpfe_dev = video_drvdata(file);
1113 struct vpfe_subdev_info *sdinfo;
1114 int subdev_index, inp_index;
1115 struct vpfe_route *route;
1116 u32 input = 0, output = 0;
1117 int ret = -EINVAL;
1118
1119 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_input\n");
1120
1121 ret = mutex_lock_interruptible(&vpfe_dev->lock);
1122 if (ret)
1123 return ret;
1124
1125 /*
1126 * If streaming is started return device busy
1127 * error
1128 */
1129 if (vpfe_dev->started) {
1130 v4l2_err(&vpfe_dev->v4l2_dev, "Streaming is on\n");
1131 ret = -EBUSY;
1132 goto unlock_out;
1133 }
1134
1135 if (vpfe_get_subdev_input_index(vpfe_dev,
1136 &subdev_index,
1137 &inp_index,
1138 index) < 0) {
1139 v4l2_err(&vpfe_dev->v4l2_dev, "invalid input index\n");
1140 goto unlock_out;
1141 }
1142
1143 sdinfo = &vpfe_dev->cfg->sub_devs[subdev_index];
1144 route = &sdinfo->routes[inp_index];
1145 if (route && sdinfo->can_route) {
1146 input = route->input;
1147 output = route->output;
1148 }
1149
1150 ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
1151 video, s_routing, input, output, 0);
1152
1153 if (ret) {
1154 v4l2_err(&vpfe_dev->v4l2_dev,
1155 "vpfe_doioctl:error in setting input in decoder\n");
1156 ret = -EINVAL;
1157 goto unlock_out;
1158 }
1159 vpfe_dev->current_subdev = sdinfo;
1160 vpfe_dev->current_input = index;
1161 vpfe_dev->std_index = 0;
1162
1163 /* set the bus/interface parameter for the sub device in ccdc */
1164 ret = ccdc_dev->hw_ops.set_hw_if_params(&sdinfo->ccdc_if_params);
1165 if (ret)
1166 goto unlock_out;
1167
1168 /* set the default image parameters in the device */
1169 ret = vpfe_config_image_format(vpfe_dev,
1170 &vpfe_standards[vpfe_dev->std_index].std_id);
1171unlock_out:
1172 mutex_unlock(&vpfe_dev->lock);
1173 return ret;
1174}
1175
1176static int vpfe_querystd(struct file *file, void *priv, v4l2_std_id *std_id)
1177{
1178 struct vpfe_device *vpfe_dev = video_drvdata(file);
1179 struct vpfe_subdev_info *sdinfo;
1180 int ret = 0;
1181
1182 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_querystd\n");
1183
1184 ret = mutex_lock_interruptible(&vpfe_dev->lock);
1185 sdinfo = vpfe_dev->current_subdev;
1186 if (ret)
1187 return ret;
1188 /* Call querystd function of decoder device */
1189 ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
1190 video, querystd, std_id);
1191 mutex_unlock(&vpfe_dev->lock);
1192 return ret;
1193}
1194
1195static int vpfe_s_std(struct file *file, void *priv, v4l2_std_id *std_id)
1196{
1197 struct vpfe_device *vpfe_dev = video_drvdata(file);
1198 struct vpfe_subdev_info *sdinfo;
1199 int ret = 0;
1200
1201 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_std\n");
1202
1203 /* Call decoder driver function to set the standard */
1204 ret = mutex_lock_interruptible(&vpfe_dev->lock);
1205 if (ret)
1206 return ret;
1207
1208 sdinfo = vpfe_dev->current_subdev;
1209 /* If streaming is started, return device busy error */
1210 if (vpfe_dev->started) {
1211 v4l2_err(&vpfe_dev->v4l2_dev, "streaming is started\n");
1212 ret = -EBUSY;
1213 goto unlock_out;
1214 }
1215
1216 ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
1217 core, s_std, *std_id);
1218 if (ret < 0) {
1219 v4l2_err(&vpfe_dev->v4l2_dev, "Failed to set standard\n");
1220 goto unlock_out;
1221 }
1222 ret = vpfe_config_image_format(vpfe_dev, std_id);
1223
1224unlock_out:
1225 mutex_unlock(&vpfe_dev->lock);
1226 return ret;
1227}
1228
1229static int vpfe_g_std(struct file *file, void *priv, v4l2_std_id *std_id)
1230{
1231 struct vpfe_device *vpfe_dev = video_drvdata(file);
1232
1233 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_g_std\n");
1234
1235 *std_id = vpfe_standards[vpfe_dev->std_index].std_id;
1236 return 0;
1237}
1238/*
1239 * Videobuf operations
1240 */
1241static int vpfe_videobuf_setup(struct videobuf_queue *vq,
1242 unsigned int *count,
1243 unsigned int *size)
1244{
1245 struct vpfe_fh *fh = vq->priv_data;
1246 struct vpfe_device *vpfe_dev = fh->vpfe_dev;
1247
1248 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_buffer_setup\n");
1249 *size = vpfe_dev->fmt.fmt.pix.sizeimage;
1250 if (vpfe_dev->memory == V4L2_MEMORY_MMAP &&
1251 vpfe_dev->fmt.fmt.pix.sizeimage > config_params.device_bufsize)
1252 *size = config_params.device_bufsize;
1253
1254 if (*count < config_params.min_numbuffers)
1255 *count = config_params.min_numbuffers;
1256 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
1257 "count=%d, size=%d\n", *count, *size);
1258 return 0;
1259}
1260
1261static int vpfe_videobuf_prepare(struct videobuf_queue *vq,
1262 struct videobuf_buffer *vb,
1263 enum v4l2_field field)
1264{
1265 struct vpfe_fh *fh = vq->priv_data;
1266 struct vpfe_device *vpfe_dev = fh->vpfe_dev;
1267 unsigned long addr;
1268 int ret;
1269
1270 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_buffer_prepare\n");
1271
1272 /* If buffer is not initialized, initialize it */
1273 if (VIDEOBUF_NEEDS_INIT == vb->state) {
1274 vb->width = vpfe_dev->fmt.fmt.pix.width;
1275 vb->height = vpfe_dev->fmt.fmt.pix.height;
1276 vb->size = vpfe_dev->fmt.fmt.pix.sizeimage;
1277 vb->field = field;
1278
1279 ret = videobuf_iolock(vq, vb, NULL);
1280 if (ret < 0)
1281 return ret;
1282
1283 addr = videobuf_to_dma_contig(vb);
1284 /* Make sure user addresses are aligned to 32 bytes */
1285 if (!ALIGN(addr, 32))
1286 return -EINVAL;
1287
1288 vb->state = VIDEOBUF_PREPARED;
1289 }
1290 return 0;
1291}
1292
1293static void vpfe_videobuf_queue(struct videobuf_queue *vq,
1294 struct videobuf_buffer *vb)
1295{
1296 /* Get the file handle object and device object */
1297 struct vpfe_fh *fh = vq->priv_data;
1298 struct vpfe_device *vpfe_dev = fh->vpfe_dev;
1299 unsigned long flags;
1300
1301 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_buffer_queue\n");
1302
1303 /* add the buffer to the DMA queue */
1304 spin_lock_irqsave(&vpfe_dev->dma_queue_lock, flags);
1305 list_add_tail(&vb->queue, &vpfe_dev->dma_queue);
1306 spin_unlock_irqrestore(&vpfe_dev->dma_queue_lock, flags);
1307
1308 /* Change state of the buffer */
1309 vb->state = VIDEOBUF_QUEUED;
1310}
1311
1312static void vpfe_videobuf_release(struct videobuf_queue *vq,
1313 struct videobuf_buffer *vb)
1314{
1315 struct vpfe_fh *fh = vq->priv_data;
1316 struct vpfe_device *vpfe_dev = fh->vpfe_dev;
1317 unsigned long flags;
1318
1319 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_videobuf_release\n");
1320
1321 /*
1322 * We need to flush the buffer from the dma queue since
1323 * they are de-allocated
1324 */
1325 spin_lock_irqsave(&vpfe_dev->dma_queue_lock, flags);
1326 INIT_LIST_HEAD(&vpfe_dev->dma_queue);
1327 spin_unlock_irqrestore(&vpfe_dev->dma_queue_lock, flags);
1328 videobuf_dma_contig_free(vq, vb);
1329 vb->state = VIDEOBUF_NEEDS_INIT;
1330}
1331
1332static struct videobuf_queue_ops vpfe_videobuf_qops = {
1333 .buf_setup = vpfe_videobuf_setup,
1334 .buf_prepare = vpfe_videobuf_prepare,
1335 .buf_queue = vpfe_videobuf_queue,
1336 .buf_release = vpfe_videobuf_release,
1337};
1338
1339/*
1340 * vpfe_reqbufs. currently support REQBUF only once opening
1341 * the device.
1342 */
1343static int vpfe_reqbufs(struct file *file, void *priv,
1344 struct v4l2_requestbuffers *req_buf)
1345{
1346 struct vpfe_device *vpfe_dev = video_drvdata(file);
1347 struct vpfe_fh *fh = file->private_data;
1348 int ret = 0;
1349
1350 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_reqbufs\n");
1351
1352 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != req_buf->type) {
1353 v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buffer type\n");
1354 return -EINVAL;
1355 }
1356
1357 ret = mutex_lock_interruptible(&vpfe_dev->lock);
1358 if (ret)
1359 return ret;
1360
1361 if (vpfe_dev->io_usrs != 0) {
1362 v4l2_err(&vpfe_dev->v4l2_dev, "Only one IO user allowed\n");
1363 ret = -EBUSY;
1364 goto unlock_out;
1365 }
1366
1367 vpfe_dev->memory = req_buf->memory;
1368 videobuf_queue_dma_contig_init(&vpfe_dev->buffer_queue,
1369 &vpfe_videobuf_qops,
1370 vpfe_dev->pdev,
1371 &vpfe_dev->irqlock,
1372 req_buf->type,
1373 vpfe_dev->fmt.fmt.pix.field,
1374 sizeof(struct videobuf_buffer),
1375 fh, NULL);
1376
1377 fh->io_allowed = 1;
1378 vpfe_dev->io_usrs = 1;
1379 INIT_LIST_HEAD(&vpfe_dev->dma_queue);
1380 ret = videobuf_reqbufs(&vpfe_dev->buffer_queue, req_buf);
1381unlock_out:
1382 mutex_unlock(&vpfe_dev->lock);
1383 return ret;
1384}
1385
1386static int vpfe_querybuf(struct file *file, void *priv,
1387 struct v4l2_buffer *buf)
1388{
1389 struct vpfe_device *vpfe_dev = video_drvdata(file);
1390
1391 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_querybuf\n");
1392
1393 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != buf->type) {
1394 v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buf type\n");
1395 return -EINVAL;
1396 }
1397
1398 if (vpfe_dev->memory != V4L2_MEMORY_MMAP) {
1399 v4l2_err(&vpfe_dev->v4l2_dev, "Invalid memory\n");
1400 return -EINVAL;
1401 }
1402 /* Call videobuf_querybuf to get information */
1403 return videobuf_querybuf(&vpfe_dev->buffer_queue, buf);
1404}
1405
1406static int vpfe_qbuf(struct file *file, void *priv,
1407 struct v4l2_buffer *p)
1408{
1409 struct vpfe_device *vpfe_dev = video_drvdata(file);
1410 struct vpfe_fh *fh = file->private_data;
1411
1412 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_qbuf\n");
1413
1414 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != p->type) {
1415 v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buf type\n");
1416 return -EINVAL;
1417 }
1418
1419 /*
1420 * If this file handle is not allowed to do IO,
1421 * return error
1422 */
1423 if (!fh->io_allowed) {
1424 v4l2_err(&vpfe_dev->v4l2_dev, "fh->io_allowed\n");
1425 return -EACCES;
1426 }
1427 return videobuf_qbuf(&vpfe_dev->buffer_queue, p);
1428}
1429
1430static int vpfe_dqbuf(struct file *file, void *priv,
1431 struct v4l2_buffer *buf)
1432{
1433 struct vpfe_device *vpfe_dev = video_drvdata(file);
1434
1435 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_dqbuf\n");
1436
1437 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != buf->type) {
1438 v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buf type\n");
1439 return -EINVAL;
1440 }
1441 return videobuf_dqbuf(&vpfe_dev->buffer_queue,
1442 buf, file->f_flags & O_NONBLOCK);
1443}
1444
1445static int vpfe_queryctrl(struct file *file, void *priv,
1446 struct v4l2_queryctrl *qctrl)
1447{
1448 struct vpfe_device *vpfe_dev = video_drvdata(file);
1449 struct vpfe_subdev_info *sdinfo;
1450
1451 sdinfo = vpfe_dev->current_subdev;
1452
1453 return v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
1454 core, queryctrl, qctrl);
1455
1456}
1457
1458static int vpfe_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl)
1459{
1460 struct vpfe_device *vpfe_dev = video_drvdata(file);
1461 struct vpfe_subdev_info *sdinfo;
1462
1463 sdinfo = vpfe_dev->current_subdev;
1464
1465 return v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
1466 core, g_ctrl, ctrl);
1467}
1468
1469static int vpfe_s_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl)
1470{
1471 struct vpfe_device *vpfe_dev = video_drvdata(file);
1472 struct vpfe_subdev_info *sdinfo;
1473
1474 sdinfo = vpfe_dev->current_subdev;
1475
1476 return v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
1477 core, s_ctrl, ctrl);
1478}
1479
1480/*
1481 * vpfe_calculate_offsets : This function calculates buffers offset
1482 * for top and bottom field
1483 */
1484static void vpfe_calculate_offsets(struct vpfe_device *vpfe_dev)
1485{
1486 struct v4l2_rect image_win;
1487
1488 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_calculate_offsets\n");
1489
1490 ccdc_dev->hw_ops.get_image_window(&image_win);
1491 vpfe_dev->field_off = image_win.height * image_win.width;
1492}
1493
1494/* vpfe_start_ccdc_capture: start streaming in ccdc/isif */
1495static void vpfe_start_ccdc_capture(struct vpfe_device *vpfe_dev)
1496{
1497 ccdc_dev->hw_ops.enable(1);
1498 if (ccdc_dev->hw_ops.enable_out_to_sdram)
1499 ccdc_dev->hw_ops.enable_out_to_sdram(1);
1500 vpfe_dev->started = 1;
1501}
1502
1503/*
1504 * vpfe_streamon. Assume the DMA queue is not empty.
1505 * application is expected to call QBUF before calling
1506 * this ioctl. If not, driver returns error
1507 */
1508static int vpfe_streamon(struct file *file, void *priv,
1509 enum v4l2_buf_type buf_type)
1510{
1511 struct vpfe_device *vpfe_dev = video_drvdata(file);
1512 struct vpfe_fh *fh = file->private_data;
1513 struct vpfe_subdev_info *sdinfo;
1514 unsigned long addr;
1515 int ret = 0;
1516
1517 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_streamon\n");
1518
1519 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != buf_type) {
1520 v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buf type\n");
1521 return -EINVAL;
1522 }
1523
1524 /* If file handle is not allowed IO, return error */
1525 if (!fh->io_allowed) {
1526 v4l2_err(&vpfe_dev->v4l2_dev, "fh->io_allowed\n");
1527 return -EACCES;
1528 }
1529
1530 sdinfo = vpfe_dev->current_subdev;
1531 ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
1532 video, s_stream, 1);
1533
1534 if (ret && (ret != -ENOIOCTLCMD)) {
1535 v4l2_err(&vpfe_dev->v4l2_dev, "stream on failed in subdev\n");
1536 return -EINVAL;
1537 }
1538
1539 /* If buffer queue is empty, return error */
1540 if (list_empty(&vpfe_dev->buffer_queue.stream)) {
1541 v4l2_err(&vpfe_dev->v4l2_dev, "buffer queue is empty\n");
1542 return -EIO;
1543 }
1544
1545 /* Call videobuf_streamon to start streaming * in videobuf */
1546 ret = videobuf_streamon(&vpfe_dev->buffer_queue);
1547 if (ret)
1548 return ret;
1549
1550
1551 ret = mutex_lock_interruptible(&vpfe_dev->lock);
1552 if (ret)
1553 goto streamoff;
1554 /* Get the next frame from the buffer queue */
1555 vpfe_dev->next_frm = list_entry(vpfe_dev->dma_queue.next,
1556 struct videobuf_buffer, queue);
1557 vpfe_dev->cur_frm = vpfe_dev->next_frm;
1558 /* Remove buffer from the buffer queue */
1559 list_del(&vpfe_dev->cur_frm->queue);
1560 /* Mark state of the current frame to active */
1561 vpfe_dev->cur_frm->state = VIDEOBUF_ACTIVE;
1562 /* Initialize field_id and started member */
1563 vpfe_dev->field_id = 0;
1564 addr = videobuf_to_dma_contig(vpfe_dev->cur_frm);
1565
1566 /* Calculate field offset */
1567 vpfe_calculate_offsets(vpfe_dev);
1568
1569 if (vpfe_attach_irq(vpfe_dev) < 0) {
1570 v4l2_err(&vpfe_dev->v4l2_dev,
1571 "Error in attaching interrupt handle\n");
1572 ret = -EFAULT;
1573 goto unlock_out;
1574 }
1575 if (ccdc_dev->hw_ops.configure() < 0) {
1576 v4l2_err(&vpfe_dev->v4l2_dev,
1577 "Error in configuring ccdc\n");
1578 ret = -EINVAL;
1579 goto unlock_out;
1580 }
1581 ccdc_dev->hw_ops.setfbaddr((unsigned long)(addr));
1582 vpfe_start_ccdc_capture(vpfe_dev);
1583 mutex_unlock(&vpfe_dev->lock);
1584 return ret;
1585unlock_out:
1586 mutex_unlock(&vpfe_dev->lock);
1587streamoff:
1588 ret = videobuf_streamoff(&vpfe_dev->buffer_queue);
1589 return ret;
1590}
1591
1592static int vpfe_streamoff(struct file *file, void *priv,
1593 enum v4l2_buf_type buf_type)
1594{
1595 struct vpfe_device *vpfe_dev = video_drvdata(file);
1596 struct vpfe_fh *fh = file->private_data;
1597 struct vpfe_subdev_info *sdinfo;
1598 int ret = 0;
1599
1600 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_streamoff\n");
1601
1602 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != buf_type) {
1603 v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buf type\n");
1604 return -EINVAL;
1605 }
1606
1607 /* If io is allowed for this file handle, return error */
1608 if (!fh->io_allowed) {
1609 v4l2_err(&vpfe_dev->v4l2_dev, "fh->io_allowed\n");
1610 return -EACCES;
1611 }
1612
1613 /* If streaming is not started, return error */
1614 if (!vpfe_dev->started) {
1615 v4l2_err(&vpfe_dev->v4l2_dev, "device started\n");
1616 return -EINVAL;
1617 }
1618
1619 ret = mutex_lock_interruptible(&vpfe_dev->lock);
1620 if (ret)
1621 return ret;
1622
1623 vpfe_stop_ccdc_capture(vpfe_dev);
1624 vpfe_detach_irq(vpfe_dev);
1625
1626 sdinfo = vpfe_dev->current_subdev;
1627 ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
1628 video, s_stream, 0);
1629
1630 if (ret && (ret != -ENOIOCTLCMD))
1631 v4l2_err(&vpfe_dev->v4l2_dev, "stream off failed in subdev\n");
1632 ret = videobuf_streamoff(&vpfe_dev->buffer_queue);
1633 mutex_unlock(&vpfe_dev->lock);
1634 return ret;
1635}
1636
1637static int vpfe_cropcap(struct file *file, void *priv,
1638 struct v4l2_cropcap *crop)
1639{
1640 struct vpfe_device *vpfe_dev = video_drvdata(file);
1641
1642 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_cropcap\n");
1643
1644 if (vpfe_dev->std_index >= ARRAY_SIZE(vpfe_standards))
1645 return -EINVAL;
1646
1647 memset(crop, 0, sizeof(struct v4l2_cropcap));
1648 crop->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1649 crop->bounds.width = crop->defrect.width =
1650 vpfe_standards[vpfe_dev->std_index].width;
1651 crop->bounds.height = crop->defrect.height =
1652 vpfe_standards[vpfe_dev->std_index].height;
1653 crop->pixelaspect = vpfe_standards[vpfe_dev->std_index].pixelaspect;
1654 return 0;
1655}
1656
1657static int vpfe_g_crop(struct file *file, void *priv,
1658 struct v4l2_crop *crop)
1659{
1660 struct vpfe_device *vpfe_dev = video_drvdata(file);
1661
1662 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_g_crop\n");
1663
1664 crop->c = vpfe_dev->crop;
1665 return 0;
1666}
1667
1668static int vpfe_s_crop(struct file *file, void *priv,
1669 struct v4l2_crop *crop)
1670{
1671 struct vpfe_device *vpfe_dev = video_drvdata(file);
1672 int ret = 0;
1673
1674 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_crop\n");
1675
1676 if (vpfe_dev->started) {
1677 /* make sure streaming is not started */
1678 v4l2_err(&vpfe_dev->v4l2_dev,
1679 "Cannot change crop when streaming is ON\n");
1680 return -EBUSY;
1681 }
1682
1683 ret = mutex_lock_interruptible(&vpfe_dev->lock);
1684 if (ret)
1685 return ret;
1686
1687 if (crop->c.top < 0 || crop->c.left < 0) {
1688 v4l2_err(&vpfe_dev->v4l2_dev,
1689 "doesn't support negative values for top & left\n");
1690 ret = -EINVAL;
1691 goto unlock_out;
1692 }
1693
1694 /* adjust the width to 16 pixel boundary */
1695 crop->c.width = ((crop->c.width + 15) & ~0xf);
1696
1697 /* make sure parameters are valid */
1698 if ((crop->c.left + crop->c.width >
1699 vpfe_dev->std_info.active_pixels) ||
1700 (crop->c.top + crop->c.height >
1701 vpfe_dev->std_info.active_lines)) {
1702 v4l2_err(&vpfe_dev->v4l2_dev, "Error in S_CROP params\n");
1703 ret = -EINVAL;
1704 goto unlock_out;
1705 }
1706 ccdc_dev->hw_ops.set_image_window(&crop->c);
1707 vpfe_dev->fmt.fmt.pix.width = crop->c.width;
1708 vpfe_dev->fmt.fmt.pix.height = crop->c.height;
1709 vpfe_dev->fmt.fmt.pix.bytesperline =
1710 ccdc_dev->hw_ops.get_line_length();
1711 vpfe_dev->fmt.fmt.pix.sizeimage =
1712 vpfe_dev->fmt.fmt.pix.bytesperline *
1713 vpfe_dev->fmt.fmt.pix.height;
1714 vpfe_dev->crop = crop->c;
1715unlock_out:
1716 mutex_unlock(&vpfe_dev->lock);
1717 return ret;
1718}
1719
1720
1721static long vpfe_param_handler(struct file *file, void *priv,
1722 bool valid_prio, int cmd, void *param)
1723{
1724 struct vpfe_device *vpfe_dev = video_drvdata(file);
1725 int ret = 0;
1726
1727 v4l2_dbg(2, debug, &vpfe_dev->v4l2_dev, "vpfe_param_handler\n");
1728
1729 if (vpfe_dev->started) {
1730 /* only allowed if streaming is not started */
1731 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
1732 "device already started\n");
1733 return -EBUSY;
1734 }
1735
1736 ret = mutex_lock_interruptible(&vpfe_dev->lock);
1737 if (ret)
1738 return ret;
1739
1740 switch (cmd) {
1741 case VPFE_CMD_S_CCDC_RAW_PARAMS:
1742 v4l2_warn(&vpfe_dev->v4l2_dev,
1743 "VPFE_CMD_S_CCDC_RAW_PARAMS: experimental ioctl\n");
1744 if (ccdc_dev->hw_ops.set_params) {
1745 ret = ccdc_dev->hw_ops.set_params(param);
1746 if (ret) {
1747 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
1748 "Error setting parameters in CCDC\n");
1749 goto unlock_out;
1750 }
1751 if (vpfe_get_ccdc_image_format(vpfe_dev,
1752 &vpfe_dev->fmt) < 0) {
1753 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
1754 "Invalid image format at CCDC\n");
1755 goto unlock_out;
1756 }
1757 } else {
1758 ret = -EINVAL;
1759 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
1760 "VPFE_CMD_S_CCDC_RAW_PARAMS not supported\n");
1761 }
1762 break;
1763 default:
1764 ret = -ENOTTY;
1765 }
1766unlock_out:
1767 mutex_unlock(&vpfe_dev->lock);
1768 return ret;
1769}
1770
1771
1772/* vpfe capture ioctl operations */
1773static const struct v4l2_ioctl_ops vpfe_ioctl_ops = {
1774 .vidioc_querycap = vpfe_querycap,
1775 .vidioc_g_fmt_vid_cap = vpfe_g_fmt_vid_cap,
1776 .vidioc_enum_fmt_vid_cap = vpfe_enum_fmt_vid_cap,
1777 .vidioc_s_fmt_vid_cap = vpfe_s_fmt_vid_cap,
1778 .vidioc_try_fmt_vid_cap = vpfe_try_fmt_vid_cap,
1779 .vidioc_enum_input = vpfe_enum_input,
1780 .vidioc_g_input = vpfe_g_input,
1781 .vidioc_s_input = vpfe_s_input,
1782 .vidioc_querystd = vpfe_querystd,
1783 .vidioc_s_std = vpfe_s_std,
1784 .vidioc_g_std = vpfe_g_std,
1785 .vidioc_queryctrl = vpfe_queryctrl,
1786 .vidioc_g_ctrl = vpfe_g_ctrl,
1787 .vidioc_s_ctrl = vpfe_s_ctrl,
1788 .vidioc_reqbufs = vpfe_reqbufs,
1789 .vidioc_querybuf = vpfe_querybuf,
1790 .vidioc_qbuf = vpfe_qbuf,
1791 .vidioc_dqbuf = vpfe_dqbuf,
1792 .vidioc_streamon = vpfe_streamon,
1793 .vidioc_streamoff = vpfe_streamoff,
1794 .vidioc_cropcap = vpfe_cropcap,
1795 .vidioc_g_crop = vpfe_g_crop,
1796 .vidioc_s_crop = vpfe_s_crop,
1797 .vidioc_default = vpfe_param_handler,
1798};
1799
1800static struct vpfe_device *vpfe_initialize(void)
1801{
1802 struct vpfe_device *vpfe_dev;
1803
1804 /* Default number of buffers should be 3 */
1805 if ((numbuffers > 0) &&
1806 (numbuffers < config_params.min_numbuffers))
1807 numbuffers = config_params.min_numbuffers;
1808
1809 /*
1810 * Set buffer size to min buffers size if invalid buffer size is
1811 * given
1812 */
1813 if (bufsize < config_params.min_bufsize)
1814 bufsize = config_params.min_bufsize;
1815
1816 config_params.numbuffers = numbuffers;
1817
1818 if (numbuffers)
1819 config_params.device_bufsize = bufsize;
1820
1821 /* Allocate memory for device objects */
1822 vpfe_dev = kzalloc(sizeof(*vpfe_dev), GFP_KERNEL);
1823
1824 return vpfe_dev;
1825}
1826
1827/*
1828 * vpfe_probe : This function creates device entries by register
1829 * itself to the V4L2 driver and initializes fields of each
1830 * device objects
1831 */
1832static __devinit int vpfe_probe(struct platform_device *pdev)
1833{
1834 struct vpfe_subdev_info *sdinfo;
1835 struct vpfe_config *vpfe_cfg;
1836 struct resource *res1;
1837 struct vpfe_device *vpfe_dev;
1838 struct i2c_adapter *i2c_adap;
1839 struct video_device *vfd;
1840 int ret = -ENOMEM, i, j;
1841 int num_subdevs = 0;
1842
1843 /* Get the pointer to the device object */
1844 vpfe_dev = vpfe_initialize();
1845
1846 if (!vpfe_dev) {
1847 v4l2_err(pdev->dev.driver,
1848 "Failed to allocate memory for vpfe_dev\n");
1849 return ret;
1850 }
1851
1852 vpfe_dev->pdev = &pdev->dev;
1853
1854 if (NULL == pdev->dev.platform_data) {
1855 v4l2_err(pdev->dev.driver, "Unable to get vpfe config\n");
1856 ret = -ENODEV;
1857 goto probe_free_dev_mem;
1858 }
1859
1860 vpfe_cfg = pdev->dev.platform_data;
1861 vpfe_dev->cfg = vpfe_cfg;
1862 if (NULL == vpfe_cfg->ccdc ||
1863 NULL == vpfe_cfg->card_name ||
1864 NULL == vpfe_cfg->sub_devs) {
1865 v4l2_err(pdev->dev.driver, "null ptr in vpfe_cfg\n");
1866 ret = -ENOENT;
1867 goto probe_free_dev_mem;
1868 }
1869
1870 /* Allocate memory for ccdc configuration */
1871 ccdc_cfg = kmalloc(sizeof(struct ccdc_config), GFP_KERNEL);
1872 if (NULL == ccdc_cfg) {
1873 v4l2_err(pdev->dev.driver,
1874 "Memory allocation failed for ccdc_cfg\n");
1875 goto probe_free_lock;
1876 }
1877
1878 mutex_lock(&ccdc_lock);
1879
1880 strncpy(ccdc_cfg->name, vpfe_cfg->ccdc, 32);
1881 /* Get VINT0 irq resource */
1882 res1 = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
1883 if (!res1) {
1884 v4l2_err(pdev->dev.driver,
1885 "Unable to get interrupt for VINT0\n");
1886 ret = -ENODEV;
1887 goto probe_free_ccdc_cfg_mem;
1888 }
1889 vpfe_dev->ccdc_irq0 = res1->start;
1890
1891 /* Get VINT1 irq resource */
1892 res1 = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
1893 if (!res1) {
1894 v4l2_err(pdev->dev.driver,
1895 "Unable to get interrupt for VINT1\n");
1896 ret = -ENODEV;
1897 goto probe_free_ccdc_cfg_mem;
1898 }
1899 vpfe_dev->ccdc_irq1 = res1->start;
1900
1901 ret = request_irq(vpfe_dev->ccdc_irq0, vpfe_isr, IRQF_DISABLED,
1902 "vpfe_capture0", vpfe_dev);
1903
1904 if (0 != ret) {
1905 v4l2_err(pdev->dev.driver, "Unable to request interrupt\n");
1906 goto probe_free_ccdc_cfg_mem;
1907 }
1908
1909 /* Allocate memory for video device */
1910 vfd = video_device_alloc();
1911 if (NULL == vfd) {
1912 ret = -ENOMEM;
1913 v4l2_err(pdev->dev.driver, "Unable to alloc video device\n");
1914 goto probe_out_release_irq;
1915 }
1916
1917 /* Initialize field of video device */
1918 vfd->release = video_device_release;
1919 vfd->fops = &vpfe_fops;
1920 vfd->ioctl_ops = &vpfe_ioctl_ops;
1921 vfd->tvnorms = 0;
1922 vfd->current_norm = V4L2_STD_PAL;
1923 vfd->v4l2_dev = &vpfe_dev->v4l2_dev;
1924 snprintf(vfd->name, sizeof(vfd->name),
1925 "%s_V%d.%d.%d",
1926 CAPTURE_DRV_NAME,
1927 (VPFE_CAPTURE_VERSION_CODE >> 16) & 0xff,
1928 (VPFE_CAPTURE_VERSION_CODE >> 8) & 0xff,
1929 (VPFE_CAPTURE_VERSION_CODE) & 0xff);
1930 /* Set video_dev to the video device */
1931 vpfe_dev->video_dev = vfd;
1932
1933 ret = v4l2_device_register(&pdev->dev, &vpfe_dev->v4l2_dev);
1934 if (ret) {
1935 v4l2_err(pdev->dev.driver,
1936 "Unable to register v4l2 device.\n");
1937 goto probe_out_video_release;
1938 }
1939 v4l2_info(&vpfe_dev->v4l2_dev, "v4l2 device registered\n");
1940 spin_lock_init(&vpfe_dev->irqlock);
1941 spin_lock_init(&vpfe_dev->dma_queue_lock);
1942 mutex_init(&vpfe_dev->lock);
1943
1944 /* Initialize field of the device objects */
1945 vpfe_dev->numbuffers = config_params.numbuffers;
1946
1947 /* Initialize prio member of device object */
1948 v4l2_prio_init(&vpfe_dev->prio);
1949 /* register video device */
1950 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
1951 "trying to register vpfe device.\n");
1952 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
1953 "video_dev=%x\n", (int)&vpfe_dev->video_dev);
1954 vpfe_dev->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1955 ret = video_register_device(vpfe_dev->video_dev,
1956 VFL_TYPE_GRABBER, -1);
1957
1958 if (ret) {
1959 v4l2_err(pdev->dev.driver,
1960 "Unable to register video device.\n");
1961 goto probe_out_v4l2_unregister;
1962 }
1963
1964 v4l2_info(&vpfe_dev->v4l2_dev, "video device registered\n");
1965 /* set the driver data in platform device */
1966 platform_set_drvdata(pdev, vpfe_dev);
1967 /* set driver private data */
1968 video_set_drvdata(vpfe_dev->video_dev, vpfe_dev);
1969 i2c_adap = i2c_get_adapter(vpfe_cfg->i2c_adapter_id);
1970 num_subdevs = vpfe_cfg->num_subdevs;
1971 vpfe_dev->sd = kmalloc(sizeof(struct v4l2_subdev *) * num_subdevs,
1972 GFP_KERNEL);
1973 if (NULL == vpfe_dev->sd) {
1974 v4l2_err(&vpfe_dev->v4l2_dev,
1975 "unable to allocate memory for subdevice pointers\n");
1976 ret = -ENOMEM;
1977 goto probe_out_video_unregister;
1978 }
1979
1980 for (i = 0; i < num_subdevs; i++) {
1981 struct v4l2_input *inps;
1982
1983 sdinfo = &vpfe_cfg->sub_devs[i];
1984
1985 /* Load up the subdevice */
1986 vpfe_dev->sd[i] =
1987 v4l2_i2c_new_subdev_board(&vpfe_dev->v4l2_dev,
1988 i2c_adap,
1989 &sdinfo->board_info,
1990 NULL);
1991 if (vpfe_dev->sd[i]) {
1992 v4l2_info(&vpfe_dev->v4l2_dev,
1993 "v4l2 sub device %s registered\n",
1994 sdinfo->name);
1995 vpfe_dev->sd[i]->grp_id = sdinfo->grp_id;
1996 /* update tvnorms from the sub devices */
1997 for (j = 0; j < sdinfo->num_inputs; j++) {
1998 inps = &sdinfo->inputs[j];
1999 vfd->tvnorms |= inps->std;
2000 }
2001 } else {
2002 v4l2_info(&vpfe_dev->v4l2_dev,
2003 "v4l2 sub device %s register fails\n",
2004 sdinfo->name);
2005 goto probe_sd_out;
2006 }
2007 }
2008
2009 /* set first sub device as current one */
2010 vpfe_dev->current_subdev = &vpfe_cfg->sub_devs[0];
2011
2012 /* We have at least one sub device to work with */
2013 mutex_unlock(&ccdc_lock);
2014 return 0;
2015
2016probe_sd_out:
2017 kfree(vpfe_dev->sd);
2018probe_out_video_unregister:
2019 video_unregister_device(vpfe_dev->video_dev);
2020probe_out_v4l2_unregister:
2021 v4l2_device_unregister(&vpfe_dev->v4l2_dev);
2022probe_out_video_release:
2023 if (!video_is_registered(vpfe_dev->video_dev))
2024 video_device_release(vpfe_dev->video_dev);
2025probe_out_release_irq:
2026 free_irq(vpfe_dev->ccdc_irq0, vpfe_dev);
2027probe_free_ccdc_cfg_mem:
2028 kfree(ccdc_cfg);
2029probe_free_lock:
2030 mutex_unlock(&ccdc_lock);
2031probe_free_dev_mem:
2032 kfree(vpfe_dev);
2033 return ret;
2034}
2035
2036/*
2037 * vpfe_remove : It un-register device from V4L2 driver
2038 */
2039static int __devexit vpfe_remove(struct platform_device *pdev)
2040{
2041 struct vpfe_device *vpfe_dev = platform_get_drvdata(pdev);
2042
2043 v4l2_info(pdev->dev.driver, "vpfe_remove\n");
2044
2045 free_irq(vpfe_dev->ccdc_irq0, vpfe_dev);
2046 kfree(vpfe_dev->sd);
2047 v4l2_device_unregister(&vpfe_dev->v4l2_dev);
2048 video_unregister_device(vpfe_dev->video_dev);
2049 kfree(vpfe_dev);
2050 kfree(ccdc_cfg);
2051 return 0;
2052}
2053
2054static int vpfe_suspend(struct device *dev)
2055{
2056 return 0;
2057}
2058
2059static int vpfe_resume(struct device *dev)
2060{
2061 return 0;
2062}
2063
2064static const struct dev_pm_ops vpfe_dev_pm_ops = {
2065 .suspend = vpfe_suspend,
2066 .resume = vpfe_resume,
2067};
2068
2069static struct platform_driver vpfe_driver = {
2070 .driver = {
2071 .name = CAPTURE_DRV_NAME,
2072 .owner = THIS_MODULE,
2073 .pm = &vpfe_dev_pm_ops,
2074 },
2075 .probe = vpfe_probe,
2076 .remove = __devexit_p(vpfe_remove),
2077};
2078
2079module_platform_driver(vpfe_driver);
diff --git a/drivers/media/video/davinci/vpif.c b/drivers/media/video/davinci/vpif.c
deleted file mode 100644
index 9bd3caa34a3e..000000000000
--- a/drivers/media/video/davinci/vpif.c
+++ /dev/null
@@ -1,514 +0,0 @@
1/*
2 * vpif - Video Port Interface driver
3 * VPIF is a receiver and transmitter for video data. It has two channels(0, 1)
4 * that receiveing video byte stream and two channels(2, 3) for video output.
5 * The hardware supports SDTV, HDTV formats, raw data capture.
6 * Currently, the driver supports NTSC and PAL standards.
7 *
8 * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation version 2.
13 *
14 * This program is distributed .as is. WITHOUT ANY WARRANTY of any
15 * kind, whether express or implied; without even the implied warranty
16 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 */
19
20#include <linux/init.h>
21#include <linux/module.h>
22#include <linux/platform_device.h>
23#include <linux/spinlock.h>
24#include <linux/kernel.h>
25#include <linux/io.h>
26#include <linux/clk.h>
27#include <linux/err.h>
28#include <mach/hardware.h>
29
30#include "vpif.h"
31
32MODULE_DESCRIPTION("TI DaVinci Video Port Interface driver");
33MODULE_LICENSE("GPL");
34
35#define VPIF_CH0_MAX_MODES (22)
36#define VPIF_CH1_MAX_MODES (02)
37#define VPIF_CH2_MAX_MODES (15)
38#define VPIF_CH3_MAX_MODES (02)
39
40static resource_size_t res_len;
41static struct resource *res;
42spinlock_t vpif_lock;
43
44void __iomem *vpif_base;
45struct clk *vpif_clk;
46
47/**
48 * ch_params: video standard configuration parameters for vpif
49 * The table must include all presets from supported subdevices.
50 */
51const struct vpif_channel_config_params ch_params[] = {
52 /* HDTV formats */
53 {
54 .name = "480p59_94",
55 .width = 720,
56 .height = 480,
57 .frm_fmt = 1,
58 .ycmux_mode = 0,
59 .eav2sav = 138-8,
60 .sav2eav = 720,
61 .l1 = 1,
62 .l3 = 43,
63 .l5 = 523,
64 .vsize = 525,
65 .capture_format = 0,
66 .vbi_supported = 0,
67 .hd_sd = 1,
68 .dv_preset = V4L2_DV_480P59_94,
69 },
70 {
71 .name = "576p50",
72 .width = 720,
73 .height = 576,
74 .frm_fmt = 1,
75 .ycmux_mode = 0,
76 .eav2sav = 144-8,
77 .sav2eav = 720,
78 .l1 = 1,
79 .l3 = 45,
80 .l5 = 621,
81 .vsize = 625,
82 .capture_format = 0,
83 .vbi_supported = 0,
84 .hd_sd = 1,
85 .dv_preset = V4L2_DV_576P50,
86 },
87 {
88 .name = "720p50",
89 .width = 1280,
90 .height = 720,
91 .frm_fmt = 1,
92 .ycmux_mode = 0,
93 .eav2sav = 700-8,
94 .sav2eav = 1280,
95 .l1 = 1,
96 .l3 = 26,
97 .l5 = 746,
98 .vsize = 750,
99 .capture_format = 0,
100 .vbi_supported = 0,
101 .hd_sd = 1,
102 .dv_preset = V4L2_DV_720P50,
103 },
104 {
105 .name = "720p60",
106 .width = 1280,
107 .height = 720,
108 .frm_fmt = 1,
109 .ycmux_mode = 0,
110 .eav2sav = 370 - 8,
111 .sav2eav = 1280,
112 .l1 = 1,
113 .l3 = 26,
114 .l5 = 746,
115 .vsize = 750,
116 .capture_format = 0,
117 .vbi_supported = 0,
118 .hd_sd = 1,
119 .dv_preset = V4L2_DV_720P60,
120 },
121 {
122 .name = "1080I50",
123 .width = 1920,
124 .height = 1080,
125 .frm_fmt = 0,
126 .ycmux_mode = 0,
127 .eav2sav = 720 - 8,
128 .sav2eav = 1920,
129 .l1 = 1,
130 .l3 = 21,
131 .l5 = 561,
132 .l7 = 563,
133 .l9 = 584,
134 .l11 = 1124,
135 .vsize = 1125,
136 .capture_format = 0,
137 .vbi_supported = 0,
138 .hd_sd = 1,
139 .dv_preset = V4L2_DV_1080I50,
140 },
141 {
142 .name = "1080I60",
143 .width = 1920,
144 .height = 1080,
145 .frm_fmt = 0,
146 .ycmux_mode = 0,
147 .eav2sav = 280 - 8,
148 .sav2eav = 1920,
149 .l1 = 1,
150 .l3 = 21,
151 .l5 = 561,
152 .l7 = 563,
153 .l9 = 584,
154 .l11 = 1124,
155 .vsize = 1125,
156 .capture_format = 0,
157 .vbi_supported = 0,
158 .hd_sd = 1,
159 .dv_preset = V4L2_DV_1080I60,
160 },
161 {
162 .name = "1080p60",
163 .width = 1920,
164 .height = 1080,
165 .frm_fmt = 1,
166 .ycmux_mode = 0,
167 .eav2sav = 280 - 8,
168 .sav2eav = 1920,
169 .l1 = 1,
170 .l3 = 42,
171 .l5 = 1122,
172 .vsize = 1125,
173 .capture_format = 0,
174 .vbi_supported = 0,
175 .hd_sd = 1,
176 .dv_preset = V4L2_DV_1080P60,
177 },
178
179 /* SDTV formats */
180 {
181 .name = "NTSC_M",
182 .width = 720,
183 .height = 480,
184 .frm_fmt = 0,
185 .ycmux_mode = 1,
186 .eav2sav = 268,
187 .sav2eav = 1440,
188 .l1 = 1,
189 .l3 = 23,
190 .l5 = 263,
191 .l7 = 266,
192 .l9 = 286,
193 .l11 = 525,
194 .vsize = 525,
195 .capture_format = 0,
196 .vbi_supported = 1,
197 .hd_sd = 0,
198 .stdid = V4L2_STD_525_60,
199 },
200 {
201 .name = "PAL_BDGHIK",
202 .width = 720,
203 .height = 576,
204 .frm_fmt = 0,
205 .ycmux_mode = 1,
206 .eav2sav = 280,
207 .sav2eav = 1440,
208 .l1 = 1,
209 .l3 = 23,
210 .l5 = 311,
211 .l7 = 313,
212 .l9 = 336,
213 .l11 = 624,
214 .vsize = 625,
215 .capture_format = 0,
216 .vbi_supported = 1,
217 .hd_sd = 0,
218 .stdid = V4L2_STD_625_50,
219 },
220};
221
222const unsigned int vpif_ch_params_count = ARRAY_SIZE(ch_params);
223
224static inline void vpif_wr_bit(u32 reg, u32 bit, u32 val)
225{
226 if (val)
227 vpif_set_bit(reg, bit);
228 else
229 vpif_clr_bit(reg, bit);
230}
231
232/* This structure is used to keep track of VPIF size register's offsets */
233struct vpif_registers {
234 u32 h_cfg, v_cfg_00, v_cfg_01, v_cfg_02, v_cfg, ch_ctrl;
235 u32 line_offset, vanc0_strt, vanc0_size, vanc1_strt;
236 u32 vanc1_size, width_mask, len_mask;
237 u8 max_modes;
238};
239
240static const struct vpif_registers vpifregs[VPIF_NUM_CHANNELS] = {
241 /* Channel0 */
242 {
243 VPIF_CH0_H_CFG, VPIF_CH0_V_CFG_00, VPIF_CH0_V_CFG_01,
244 VPIF_CH0_V_CFG_02, VPIF_CH0_V_CFG_03, VPIF_CH0_CTRL,
245 VPIF_CH0_IMG_ADD_OFST, 0, 0, 0, 0, 0x1FFF, 0xFFF,
246 VPIF_CH0_MAX_MODES,
247 },
248 /* Channel1 */
249 {
250 VPIF_CH1_H_CFG, VPIF_CH1_V_CFG_00, VPIF_CH1_V_CFG_01,
251 VPIF_CH1_V_CFG_02, VPIF_CH1_V_CFG_03, VPIF_CH1_CTRL,
252 VPIF_CH1_IMG_ADD_OFST, 0, 0, 0, 0, 0x1FFF, 0xFFF,
253 VPIF_CH1_MAX_MODES,
254 },
255 /* Channel2 */
256 {
257 VPIF_CH2_H_CFG, VPIF_CH2_V_CFG_00, VPIF_CH2_V_CFG_01,
258 VPIF_CH2_V_CFG_02, VPIF_CH2_V_CFG_03, VPIF_CH2_CTRL,
259 VPIF_CH2_IMG_ADD_OFST, VPIF_CH2_VANC0_STRT, VPIF_CH2_VANC0_SIZE,
260 VPIF_CH2_VANC1_STRT, VPIF_CH2_VANC1_SIZE, 0x7FF, 0x7FF,
261 VPIF_CH2_MAX_MODES
262 },
263 /* Channel3 */
264 {
265 VPIF_CH3_H_CFG, VPIF_CH3_V_CFG_00, VPIF_CH3_V_CFG_01,
266 VPIF_CH3_V_CFG_02, VPIF_CH3_V_CFG_03, VPIF_CH3_CTRL,
267 VPIF_CH3_IMG_ADD_OFST, VPIF_CH3_VANC0_STRT, VPIF_CH3_VANC0_SIZE,
268 VPIF_CH3_VANC1_STRT, VPIF_CH3_VANC1_SIZE, 0x7FF, 0x7FF,
269 VPIF_CH3_MAX_MODES
270 },
271};
272
273/* vpif_set_mode_info:
274 * This function is used to set horizontal and vertical config parameters
275 * As per the standard in the channel, configure the values of L1, L3,
276 * L5, L7 L9, L11 in VPIF Register , also write width and height
277 */
278static void vpif_set_mode_info(const struct vpif_channel_config_params *config,
279 u8 channel_id, u8 config_channel_id)
280{
281 u32 value;
282
283 value = (config->eav2sav & vpifregs[config_channel_id].width_mask);
284 value <<= VPIF_CH_LEN_SHIFT;
285 value |= (config->sav2eav & vpifregs[config_channel_id].width_mask);
286 regw(value, vpifregs[channel_id].h_cfg);
287
288 value = (config->l1 & vpifregs[config_channel_id].len_mask);
289 value <<= VPIF_CH_LEN_SHIFT;
290 value |= (config->l3 & vpifregs[config_channel_id].len_mask);
291 regw(value, vpifregs[channel_id].v_cfg_00);
292
293 value = (config->l5 & vpifregs[config_channel_id].len_mask);
294 value <<= VPIF_CH_LEN_SHIFT;
295 value |= (config->l7 & vpifregs[config_channel_id].len_mask);
296 regw(value, vpifregs[channel_id].v_cfg_01);
297
298 value = (config->l9 & vpifregs[config_channel_id].len_mask);
299 value <<= VPIF_CH_LEN_SHIFT;
300 value |= (config->l11 & vpifregs[config_channel_id].len_mask);
301 regw(value, vpifregs[channel_id].v_cfg_02);
302
303 value = (config->vsize & vpifregs[config_channel_id].len_mask);
304 regw(value, vpifregs[channel_id].v_cfg);
305}
306
307/* config_vpif_params
308 * Function to set the parameters of a channel
309 * Mainly modifies the channel ciontrol register
310 * It sets frame format, yc mux mode
311 */
312static void config_vpif_params(struct vpif_params *vpifparams,
313 u8 channel_id, u8 found)
314{
315 const struct vpif_channel_config_params *config = &vpifparams->std_info;
316 u32 value, ch_nip, reg;
317 u8 start, end;
318 int i;
319
320 start = channel_id;
321 end = channel_id + found;
322
323 for (i = start; i < end; i++) {
324 reg = vpifregs[i].ch_ctrl;
325 if (channel_id < 2)
326 ch_nip = VPIF_CAPTURE_CH_NIP;
327 else
328 ch_nip = VPIF_DISPLAY_CH_NIP;
329
330 vpif_wr_bit(reg, ch_nip, config->frm_fmt);
331 vpif_wr_bit(reg, VPIF_CH_YC_MUX_BIT, config->ycmux_mode);
332 vpif_wr_bit(reg, VPIF_CH_INPUT_FIELD_FRAME_BIT,
333 vpifparams->video_params.storage_mode);
334
335 /* Set raster scanning SDR Format */
336 vpif_clr_bit(reg, VPIF_CH_SDR_FMT_BIT);
337 vpif_wr_bit(reg, VPIF_CH_DATA_MODE_BIT, config->capture_format);
338
339 if (channel_id > 1) /* Set the Pixel enable bit */
340 vpif_set_bit(reg, VPIF_DISPLAY_PIX_EN_BIT);
341 else if (config->capture_format) {
342 /* Set the polarity of various pins */
343 vpif_wr_bit(reg, VPIF_CH_FID_POLARITY_BIT,
344 vpifparams->iface.fid_pol);
345 vpif_wr_bit(reg, VPIF_CH_V_VALID_POLARITY_BIT,
346 vpifparams->iface.vd_pol);
347 vpif_wr_bit(reg, VPIF_CH_H_VALID_POLARITY_BIT,
348 vpifparams->iface.hd_pol);
349
350 value = regr(reg);
351 /* Set data width */
352 value &= ~(0x3u <<
353 VPIF_CH_DATA_WIDTH_BIT);
354 value |= ((vpifparams->params.data_sz) <<
355 VPIF_CH_DATA_WIDTH_BIT);
356 regw(value, reg);
357 }
358
359 /* Write the pitch in the driver */
360 regw((vpifparams->video_params.hpitch),
361 vpifregs[i].line_offset);
362 }
363}
364
365/* vpif_set_video_params
366 * This function is used to set video parameters in VPIF register
367 */
368int vpif_set_video_params(struct vpif_params *vpifparams, u8 channel_id)
369{
370 const struct vpif_channel_config_params *config = &vpifparams->std_info;
371 int found = 1;
372
373 vpif_set_mode_info(config, channel_id, channel_id);
374 if (!config->ycmux_mode) {
375 /* YC are on separate channels (HDTV formats) */
376 vpif_set_mode_info(config, channel_id + 1, channel_id);
377 found = 2;
378 }
379
380 config_vpif_params(vpifparams, channel_id, found);
381
382 regw(0x80, VPIF_REQ_SIZE);
383 regw(0x01, VPIF_EMULATION_CTRL);
384
385 return found;
386}
387EXPORT_SYMBOL(vpif_set_video_params);
388
389void vpif_set_vbi_display_params(struct vpif_vbi_params *vbiparams,
390 u8 channel_id)
391{
392 u32 value;
393
394 value = 0x3F8 & (vbiparams->hstart0);
395 value |= 0x3FFFFFF & ((vbiparams->vstart0) << 16);
396 regw(value, vpifregs[channel_id].vanc0_strt);
397
398 value = 0x3F8 & (vbiparams->hstart1);
399 value |= 0x3FFFFFF & ((vbiparams->vstart1) << 16);
400 regw(value, vpifregs[channel_id].vanc1_strt);
401
402 value = 0x3F8 & (vbiparams->hsize0);
403 value |= 0x3FFFFFF & ((vbiparams->vsize0) << 16);
404 regw(value, vpifregs[channel_id].vanc0_size);
405
406 value = 0x3F8 & (vbiparams->hsize1);
407 value |= 0x3FFFFFF & ((vbiparams->vsize1) << 16);
408 regw(value, vpifregs[channel_id].vanc1_size);
409
410}
411EXPORT_SYMBOL(vpif_set_vbi_display_params);
412
413int vpif_channel_getfid(u8 channel_id)
414{
415 return (regr(vpifregs[channel_id].ch_ctrl) & VPIF_CH_FID_MASK)
416 >> VPIF_CH_FID_SHIFT;
417}
418EXPORT_SYMBOL(vpif_channel_getfid);
419
420static int __devinit vpif_probe(struct platform_device *pdev)
421{
422 int status = 0;
423
424 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
425 if (!res)
426 return -ENOENT;
427
428 res_len = resource_size(res);
429
430 res = request_mem_region(res->start, res_len, res->name);
431 if (!res)
432 return -EBUSY;
433
434 vpif_base = ioremap(res->start, res_len);
435 if (!vpif_base) {
436 status = -EBUSY;
437 goto fail;
438 }
439
440 vpif_clk = clk_get(&pdev->dev, "vpif");
441 if (IS_ERR(vpif_clk)) {
442 status = PTR_ERR(vpif_clk);
443 goto clk_fail;
444 }
445 clk_enable(vpif_clk);
446
447 spin_lock_init(&vpif_lock);
448 dev_info(&pdev->dev, "vpif probe success\n");
449 return 0;
450
451clk_fail:
452 iounmap(vpif_base);
453fail:
454 release_mem_region(res->start, res_len);
455 return status;
456}
457
458static int __devexit vpif_remove(struct platform_device *pdev)
459{
460 if (vpif_clk) {
461 clk_disable(vpif_clk);
462 clk_put(vpif_clk);
463 }
464
465 iounmap(vpif_base);
466 release_mem_region(res->start, res_len);
467 return 0;
468}
469
470#ifdef CONFIG_PM
471static int vpif_suspend(struct device *dev)
472{
473 clk_disable(vpif_clk);
474 return 0;
475}
476
477static int vpif_resume(struct device *dev)
478{
479 clk_enable(vpif_clk);
480 return 0;
481}
482
483static const struct dev_pm_ops vpif_pm = {
484 .suspend = vpif_suspend,
485 .resume = vpif_resume,
486};
487
488#define vpif_pm_ops (&vpif_pm)
489#else
490#define vpif_pm_ops NULL
491#endif
492
493static struct platform_driver vpif_driver = {
494 .driver = {
495 .name = "vpif",
496 .owner = THIS_MODULE,
497 .pm = vpif_pm_ops,
498 },
499 .remove = __devexit_p(vpif_remove),
500 .probe = vpif_probe,
501};
502
503static void vpif_exit(void)
504{
505 platform_driver_unregister(&vpif_driver);
506}
507
508static int __init vpif_init(void)
509{
510 return platform_driver_register(&vpif_driver);
511}
512subsys_initcall(vpif_init);
513module_exit(vpif_exit);
514
diff --git a/drivers/media/video/davinci/vpif.h b/drivers/media/video/davinci/vpif.h
deleted file mode 100644
index c2ce4d97c279..000000000000
--- a/drivers/media/video/davinci/vpif.h
+++ /dev/null
@@ -1,688 +0,0 @@
1/*
2 * VPIF header file
3 *
4 * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation version 2.
9 *
10 * This program is distributed .as is. WITHOUT ANY WARRANTY of any
11 * kind, whether express or implied; without even the implied warranty
12 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#ifndef VPIF_H
17#define VPIF_H
18
19#include <linux/io.h>
20#include <linux/videodev2.h>
21#include <media/davinci/vpif_types.h>
22
23/* Maximum channel allowed */
24#define VPIF_NUM_CHANNELS (4)
25#define VPIF_CAPTURE_NUM_CHANNELS (2)
26#define VPIF_DISPLAY_NUM_CHANNELS (2)
27
28/* Macros to read/write registers */
29extern void __iomem *vpif_base;
30extern spinlock_t vpif_lock;
31
32#define regr(reg) readl((reg) + vpif_base)
33#define regw(value, reg) writel(value, (reg + vpif_base))
34
35/* Register Address Offsets */
36#define VPIF_PID (0x0000)
37#define VPIF_CH0_CTRL (0x0004)
38#define VPIF_CH1_CTRL (0x0008)
39#define VPIF_CH2_CTRL (0x000C)
40#define VPIF_CH3_CTRL (0x0010)
41
42#define VPIF_INTEN (0x0020)
43#define VPIF_INTEN_SET (0x0024)
44#define VPIF_INTEN_CLR (0x0028)
45#define VPIF_STATUS (0x002C)
46#define VPIF_STATUS_CLR (0x0030)
47#define VPIF_EMULATION_CTRL (0x0034)
48#define VPIF_REQ_SIZE (0x0038)
49
50#define VPIF_CH0_TOP_STRT_ADD_LUMA (0x0040)
51#define VPIF_CH0_BTM_STRT_ADD_LUMA (0x0044)
52#define VPIF_CH0_TOP_STRT_ADD_CHROMA (0x0048)
53#define VPIF_CH0_BTM_STRT_ADD_CHROMA (0x004c)
54#define VPIF_CH0_TOP_STRT_ADD_HANC (0x0050)
55#define VPIF_CH0_BTM_STRT_ADD_HANC (0x0054)
56#define VPIF_CH0_TOP_STRT_ADD_VANC (0x0058)
57#define VPIF_CH0_BTM_STRT_ADD_VANC (0x005c)
58#define VPIF_CH0_SP_CFG (0x0060)
59#define VPIF_CH0_IMG_ADD_OFST (0x0064)
60#define VPIF_CH0_HANC_ADD_OFST (0x0068)
61#define VPIF_CH0_H_CFG (0x006c)
62#define VPIF_CH0_V_CFG_00 (0x0070)
63#define VPIF_CH0_V_CFG_01 (0x0074)
64#define VPIF_CH0_V_CFG_02 (0x0078)
65#define VPIF_CH0_V_CFG_03 (0x007c)
66
67#define VPIF_CH1_TOP_STRT_ADD_LUMA (0x0080)
68#define VPIF_CH1_BTM_STRT_ADD_LUMA (0x0084)
69#define VPIF_CH1_TOP_STRT_ADD_CHROMA (0x0088)
70#define VPIF_CH1_BTM_STRT_ADD_CHROMA (0x008c)
71#define VPIF_CH1_TOP_STRT_ADD_HANC (0x0090)
72#define VPIF_CH1_BTM_STRT_ADD_HANC (0x0094)
73#define VPIF_CH1_TOP_STRT_ADD_VANC (0x0098)
74#define VPIF_CH1_BTM_STRT_ADD_VANC (0x009c)
75#define VPIF_CH1_SP_CFG (0x00a0)
76#define VPIF_CH1_IMG_ADD_OFST (0x00a4)
77#define VPIF_CH1_HANC_ADD_OFST (0x00a8)
78#define VPIF_CH1_H_CFG (0x00ac)
79#define VPIF_CH1_V_CFG_00 (0x00b0)
80#define VPIF_CH1_V_CFG_01 (0x00b4)
81#define VPIF_CH1_V_CFG_02 (0x00b8)
82#define VPIF_CH1_V_CFG_03 (0x00bc)
83
84#define VPIF_CH2_TOP_STRT_ADD_LUMA (0x00c0)
85#define VPIF_CH2_BTM_STRT_ADD_LUMA (0x00c4)
86#define VPIF_CH2_TOP_STRT_ADD_CHROMA (0x00c8)
87#define VPIF_CH2_BTM_STRT_ADD_CHROMA (0x00cc)
88#define VPIF_CH2_TOP_STRT_ADD_HANC (0x00d0)
89#define VPIF_CH2_BTM_STRT_ADD_HANC (0x00d4)
90#define VPIF_CH2_TOP_STRT_ADD_VANC (0x00d8)
91#define VPIF_CH2_BTM_STRT_ADD_VANC (0x00dc)
92#define VPIF_CH2_SP_CFG (0x00e0)
93#define VPIF_CH2_IMG_ADD_OFST (0x00e4)
94#define VPIF_CH2_HANC_ADD_OFST (0x00e8)
95#define VPIF_CH2_H_CFG (0x00ec)
96#define VPIF_CH2_V_CFG_00 (0x00f0)
97#define VPIF_CH2_V_CFG_01 (0x00f4)
98#define VPIF_CH2_V_CFG_02 (0x00f8)
99#define VPIF_CH2_V_CFG_03 (0x00fc)
100#define VPIF_CH2_HANC0_STRT (0x0100)
101#define VPIF_CH2_HANC0_SIZE (0x0104)
102#define VPIF_CH2_HANC1_STRT (0x0108)
103#define VPIF_CH2_HANC1_SIZE (0x010c)
104#define VPIF_CH2_VANC0_STRT (0x0110)
105#define VPIF_CH2_VANC0_SIZE (0x0114)
106#define VPIF_CH2_VANC1_STRT (0x0118)
107#define VPIF_CH2_VANC1_SIZE (0x011c)
108
109#define VPIF_CH3_TOP_STRT_ADD_LUMA (0x0140)
110#define VPIF_CH3_BTM_STRT_ADD_LUMA (0x0144)
111#define VPIF_CH3_TOP_STRT_ADD_CHROMA (0x0148)
112#define VPIF_CH3_BTM_STRT_ADD_CHROMA (0x014c)
113#define VPIF_CH3_TOP_STRT_ADD_HANC (0x0150)
114#define VPIF_CH3_BTM_STRT_ADD_HANC (0x0154)
115#define VPIF_CH3_TOP_STRT_ADD_VANC (0x0158)
116#define VPIF_CH3_BTM_STRT_ADD_VANC (0x015c)
117#define VPIF_CH3_SP_CFG (0x0160)
118#define VPIF_CH3_IMG_ADD_OFST (0x0164)
119#define VPIF_CH3_HANC_ADD_OFST (0x0168)
120#define VPIF_CH3_H_CFG (0x016c)
121#define VPIF_CH3_V_CFG_00 (0x0170)
122#define VPIF_CH3_V_CFG_01 (0x0174)
123#define VPIF_CH3_V_CFG_02 (0x0178)
124#define VPIF_CH3_V_CFG_03 (0x017c)
125#define VPIF_CH3_HANC0_STRT (0x0180)
126#define VPIF_CH3_HANC0_SIZE (0x0184)
127#define VPIF_CH3_HANC1_STRT (0x0188)
128#define VPIF_CH3_HANC1_SIZE (0x018c)
129#define VPIF_CH3_VANC0_STRT (0x0190)
130#define VPIF_CH3_VANC0_SIZE (0x0194)
131#define VPIF_CH3_VANC1_STRT (0x0198)
132#define VPIF_CH3_VANC1_SIZE (0x019c)
133
134#define VPIF_IODFT_CTRL (0x01c0)
135
136/* Functions for bit Manipulation */
137static inline void vpif_set_bit(u32 reg, u32 bit)
138{
139 regw((regr(reg)) | (0x01 << bit), reg);
140}
141
142static inline void vpif_clr_bit(u32 reg, u32 bit)
143{
144 regw(((regr(reg)) & ~(0x01 << bit)), reg);
145}
146
147/* Macro for Generating mask */
148#ifdef GENERATE_MASK
149#undef GENERATE_MASK
150#endif
151
152#define GENERATE_MASK(bits, pos) \
153 ((((0xFFFFFFFF) << (32 - bits)) >> (32 - bits)) << pos)
154
155/* Bit positions in the channel control registers */
156#define VPIF_CH_DATA_MODE_BIT (2)
157#define VPIF_CH_YC_MUX_BIT (3)
158#define VPIF_CH_SDR_FMT_BIT (4)
159#define VPIF_CH_HANC_EN_BIT (8)
160#define VPIF_CH_VANC_EN_BIT (9)
161
162#define VPIF_CAPTURE_CH_NIP (10)
163#define VPIF_DISPLAY_CH_NIP (11)
164
165#define VPIF_DISPLAY_PIX_EN_BIT (10)
166
167#define VPIF_CH_INPUT_FIELD_FRAME_BIT (12)
168
169#define VPIF_CH_FID_POLARITY_BIT (15)
170#define VPIF_CH_V_VALID_POLARITY_BIT (14)
171#define VPIF_CH_H_VALID_POLARITY_BIT (13)
172#define VPIF_CH_DATA_WIDTH_BIT (28)
173
174#define VPIF_CH_CLK_EDGE_CTRL_BIT (31)
175
176/* Mask various length */
177#define VPIF_CH_EAVSAV_MASK GENERATE_MASK(13, 0)
178#define VPIF_CH_LEN_MASK GENERATE_MASK(12, 0)
179#define VPIF_CH_WIDTH_MASK GENERATE_MASK(13, 0)
180#define VPIF_CH_LEN_SHIFT (16)
181
182/* VPIF masks for registers */
183#define VPIF_REQ_SIZE_MASK (0x1ff)
184
185/* bit posotion of interrupt vpif_ch_intr register */
186#define VPIF_INTEN_FRAME_CH0 (0x00000001)
187#define VPIF_INTEN_FRAME_CH1 (0x00000002)
188#define VPIF_INTEN_FRAME_CH2 (0x00000004)
189#define VPIF_INTEN_FRAME_CH3 (0x00000008)
190
191/* bit position of clock and channel enable in vpif_chn_ctrl register */
192
193#define VPIF_CH0_CLK_EN (0x00000002)
194#define VPIF_CH0_EN (0x00000001)
195#define VPIF_CH1_CLK_EN (0x00000002)
196#define VPIF_CH1_EN (0x00000001)
197#define VPIF_CH2_CLK_EN (0x00000002)
198#define VPIF_CH2_EN (0x00000001)
199#define VPIF_CH3_CLK_EN (0x00000002)
200#define VPIF_CH3_EN (0x00000001)
201#define VPIF_CH_CLK_EN (0x00000002)
202#define VPIF_CH_EN (0x00000001)
203
204#define VPIF_INT_TOP (0x00)
205#define VPIF_INT_BOTTOM (0x01)
206#define VPIF_INT_BOTH (0x02)
207
208#define VPIF_CH0_INT_CTRL_SHIFT (6)
209#define VPIF_CH1_INT_CTRL_SHIFT (6)
210#define VPIF_CH2_INT_CTRL_SHIFT (6)
211#define VPIF_CH3_INT_CTRL_SHIFT (6)
212#define VPIF_CH_INT_CTRL_SHIFT (6)
213
214#define VPIF_CH2_CLIP_ANC_EN 14
215#define VPIF_CH2_CLIP_ACTIVE_EN 13
216
217#define VPIF_CH3_CLIP_ANC_EN 14
218#define VPIF_CH3_CLIP_ACTIVE_EN 13
219
220/* enabled interrupt on both the fields on vpid_ch0_ctrl register */
221#define channel0_intr_assert() (regw((regr(VPIF_CH0_CTRL)|\
222 (VPIF_INT_BOTH << VPIF_CH0_INT_CTRL_SHIFT)), VPIF_CH0_CTRL))
223
224/* enabled interrupt on both the fields on vpid_ch1_ctrl register */
225#define channel1_intr_assert() (regw((regr(VPIF_CH1_CTRL)|\
226 (VPIF_INT_BOTH << VPIF_CH1_INT_CTRL_SHIFT)), VPIF_CH1_CTRL))
227
228/* enabled interrupt on both the fields on vpid_ch0_ctrl register */
229#define channel2_intr_assert() (regw((regr(VPIF_CH2_CTRL)|\
230 (VPIF_INT_BOTH << VPIF_CH2_INT_CTRL_SHIFT)), VPIF_CH2_CTRL))
231
232/* enabled interrupt on both the fields on vpid_ch1_ctrl register */
233#define channel3_intr_assert() (regw((regr(VPIF_CH3_CTRL)|\
234 (VPIF_INT_BOTH << VPIF_CH3_INT_CTRL_SHIFT)), VPIF_CH3_CTRL))
235
236#define VPIF_CH_FID_MASK (0x20)
237#define VPIF_CH_FID_SHIFT (5)
238
239#define VPIF_NTSC_VBI_START_FIELD0 (1)
240#define VPIF_NTSC_VBI_START_FIELD1 (263)
241#define VPIF_PAL_VBI_START_FIELD0 (624)
242#define VPIF_PAL_VBI_START_FIELD1 (311)
243
244#define VPIF_NTSC_HBI_START_FIELD0 (1)
245#define VPIF_NTSC_HBI_START_FIELD1 (263)
246#define VPIF_PAL_HBI_START_FIELD0 (624)
247#define VPIF_PAL_HBI_START_FIELD1 (311)
248
249#define VPIF_NTSC_VBI_COUNT_FIELD0 (20)
250#define VPIF_NTSC_VBI_COUNT_FIELD1 (19)
251#define VPIF_PAL_VBI_COUNT_FIELD0 (24)
252#define VPIF_PAL_VBI_COUNT_FIELD1 (25)
253
254#define VPIF_NTSC_HBI_COUNT_FIELD0 (263)
255#define VPIF_NTSC_HBI_COUNT_FIELD1 (262)
256#define VPIF_PAL_HBI_COUNT_FIELD0 (312)
257#define VPIF_PAL_HBI_COUNT_FIELD1 (313)
258
259#define VPIF_NTSC_VBI_SAMPLES_PER_LINE (720)
260#define VPIF_PAL_VBI_SAMPLES_PER_LINE (720)
261#define VPIF_NTSC_HBI_SAMPLES_PER_LINE (268)
262#define VPIF_PAL_HBI_SAMPLES_PER_LINE (280)
263
264#define VPIF_CH_VANC_EN (0x20)
265#define VPIF_DMA_REQ_SIZE (0x080)
266#define VPIF_EMULATION_DISABLE (0x01)
267
268extern u8 irq_vpif_capture_channel[VPIF_NUM_CHANNELS];
269
270/* inline function to enable/disable channel0 */
271static inline void enable_channel0(int enable)
272{
273 if (enable)
274 regw((regr(VPIF_CH0_CTRL) | (VPIF_CH0_EN)), VPIF_CH0_CTRL);
275 else
276 regw((regr(VPIF_CH0_CTRL) & (~VPIF_CH0_EN)), VPIF_CH0_CTRL);
277}
278
279/* inline function to enable/disable channel1 */
280static inline void enable_channel1(int enable)
281{
282 if (enable)
283 regw((regr(VPIF_CH1_CTRL) | (VPIF_CH1_EN)), VPIF_CH1_CTRL);
284 else
285 regw((regr(VPIF_CH1_CTRL) & (~VPIF_CH1_EN)), VPIF_CH1_CTRL);
286}
287
288/* inline function to enable interrupt for channel0 */
289static inline void channel0_intr_enable(int enable)
290{
291 unsigned long flags;
292
293 spin_lock_irqsave(&vpif_lock, flags);
294
295 if (enable) {
296 regw((regr(VPIF_INTEN) | 0x10), VPIF_INTEN);
297 regw((regr(VPIF_INTEN_SET) | 0x10), VPIF_INTEN_SET);
298
299 regw((regr(VPIF_INTEN) | VPIF_INTEN_FRAME_CH0), VPIF_INTEN);
300 regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH0),
301 VPIF_INTEN_SET);
302 } else {
303 regw((regr(VPIF_INTEN) & (~VPIF_INTEN_FRAME_CH0)), VPIF_INTEN);
304 regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH0),
305 VPIF_INTEN_SET);
306 }
307 spin_unlock_irqrestore(&vpif_lock, flags);
308}
309
310/* inline function to enable interrupt for channel1 */
311static inline void channel1_intr_enable(int enable)
312{
313 unsigned long flags;
314
315 spin_lock_irqsave(&vpif_lock, flags);
316
317 if (enable) {
318 regw((regr(VPIF_INTEN) | 0x10), VPIF_INTEN);
319 regw((regr(VPIF_INTEN_SET) | 0x10), VPIF_INTEN_SET);
320
321 regw((regr(VPIF_INTEN) | VPIF_INTEN_FRAME_CH1), VPIF_INTEN);
322 regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH1),
323 VPIF_INTEN_SET);
324 } else {
325 regw((regr(VPIF_INTEN) & (~VPIF_INTEN_FRAME_CH1)), VPIF_INTEN);
326 regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH1),
327 VPIF_INTEN_SET);
328 }
329 spin_unlock_irqrestore(&vpif_lock, flags);
330}
331
332/* inline function to set buffer addresses in case of Y/C non mux mode */
333static inline void ch0_set_videobuf_addr_yc_nmux(unsigned long top_strt_luma,
334 unsigned long btm_strt_luma,
335 unsigned long top_strt_chroma,
336 unsigned long btm_strt_chroma)
337{
338 regw(top_strt_luma, VPIF_CH0_TOP_STRT_ADD_LUMA);
339 regw(btm_strt_luma, VPIF_CH0_BTM_STRT_ADD_LUMA);
340 regw(top_strt_chroma, VPIF_CH1_TOP_STRT_ADD_CHROMA);
341 regw(btm_strt_chroma, VPIF_CH1_BTM_STRT_ADD_CHROMA);
342}
343
344/* inline function to set buffer addresses in VPIF registers for video data */
345static inline void ch0_set_videobuf_addr(unsigned long top_strt_luma,
346 unsigned long btm_strt_luma,
347 unsigned long top_strt_chroma,
348 unsigned long btm_strt_chroma)
349{
350 regw(top_strt_luma, VPIF_CH0_TOP_STRT_ADD_LUMA);
351 regw(btm_strt_luma, VPIF_CH0_BTM_STRT_ADD_LUMA);
352 regw(top_strt_chroma, VPIF_CH0_TOP_STRT_ADD_CHROMA);
353 regw(btm_strt_chroma, VPIF_CH0_BTM_STRT_ADD_CHROMA);
354}
355
356static inline void ch1_set_videobuf_addr(unsigned long top_strt_luma,
357 unsigned long btm_strt_luma,
358 unsigned long top_strt_chroma,
359 unsigned long btm_strt_chroma)
360{
361
362 regw(top_strt_luma, VPIF_CH1_TOP_STRT_ADD_LUMA);
363 regw(btm_strt_luma, VPIF_CH1_BTM_STRT_ADD_LUMA);
364 regw(top_strt_chroma, VPIF_CH1_TOP_STRT_ADD_CHROMA);
365 regw(btm_strt_chroma, VPIF_CH1_BTM_STRT_ADD_CHROMA);
366}
367
368static inline void ch0_set_vbi_addr(unsigned long top_vbi,
369 unsigned long btm_vbi, unsigned long a, unsigned long b)
370{
371 regw(top_vbi, VPIF_CH0_TOP_STRT_ADD_VANC);
372 regw(btm_vbi, VPIF_CH0_BTM_STRT_ADD_VANC);
373}
374
375static inline void ch0_set_hbi_addr(unsigned long top_vbi,
376 unsigned long btm_vbi, unsigned long a, unsigned long b)
377{
378 regw(top_vbi, VPIF_CH0_TOP_STRT_ADD_HANC);
379 regw(btm_vbi, VPIF_CH0_BTM_STRT_ADD_HANC);
380}
381
382static inline void ch1_set_vbi_addr(unsigned long top_vbi,
383 unsigned long btm_vbi, unsigned long a, unsigned long b)
384{
385 regw(top_vbi, VPIF_CH1_TOP_STRT_ADD_VANC);
386 regw(btm_vbi, VPIF_CH1_BTM_STRT_ADD_VANC);
387}
388
389static inline void ch1_set_hbi_addr(unsigned long top_vbi,
390 unsigned long btm_vbi, unsigned long a, unsigned long b)
391{
392 regw(top_vbi, VPIF_CH1_TOP_STRT_ADD_HANC);
393 regw(btm_vbi, VPIF_CH1_BTM_STRT_ADD_HANC);
394}
395
396/* Inline function to enable raw vbi in the given channel */
397static inline void disable_raw_feature(u8 channel_id, u8 index)
398{
399 u32 ctrl_reg;
400 if (0 == channel_id)
401 ctrl_reg = VPIF_CH0_CTRL;
402 else
403 ctrl_reg = VPIF_CH1_CTRL;
404
405 if (1 == index)
406 vpif_clr_bit(ctrl_reg, VPIF_CH_VANC_EN_BIT);
407 else
408 vpif_clr_bit(ctrl_reg, VPIF_CH_HANC_EN_BIT);
409}
410
411static inline void enable_raw_feature(u8 channel_id, u8 index)
412{
413 u32 ctrl_reg;
414 if (0 == channel_id)
415 ctrl_reg = VPIF_CH0_CTRL;
416 else
417 ctrl_reg = VPIF_CH1_CTRL;
418
419 if (1 == index)
420 vpif_set_bit(ctrl_reg, VPIF_CH_VANC_EN_BIT);
421 else
422 vpif_set_bit(ctrl_reg, VPIF_CH_HANC_EN_BIT);
423}
424
425/* inline function to enable/disable channel2 */
426static inline void enable_channel2(int enable)
427{
428 if (enable) {
429 regw((regr(VPIF_CH2_CTRL) | (VPIF_CH2_CLK_EN)), VPIF_CH2_CTRL);
430 regw((regr(VPIF_CH2_CTRL) | (VPIF_CH2_EN)), VPIF_CH2_CTRL);
431 } else {
432 regw((regr(VPIF_CH2_CTRL) & (~VPIF_CH2_CLK_EN)), VPIF_CH2_CTRL);
433 regw((regr(VPIF_CH2_CTRL) & (~VPIF_CH2_EN)), VPIF_CH2_CTRL);
434 }
435}
436
437/* inline function to enable/disable channel3 */
438static inline void enable_channel3(int enable)
439{
440 if (enable) {
441 regw((regr(VPIF_CH3_CTRL) | (VPIF_CH3_CLK_EN)), VPIF_CH3_CTRL);
442 regw((regr(VPIF_CH3_CTRL) | (VPIF_CH3_EN)), VPIF_CH3_CTRL);
443 } else {
444 regw((regr(VPIF_CH3_CTRL) & (~VPIF_CH3_CLK_EN)), VPIF_CH3_CTRL);
445 regw((regr(VPIF_CH3_CTRL) & (~VPIF_CH3_EN)), VPIF_CH3_CTRL);
446 }
447}
448
449/* inline function to enable interrupt for channel2 */
450static inline void channel2_intr_enable(int enable)
451{
452 unsigned long flags;
453
454 spin_lock_irqsave(&vpif_lock, flags);
455
456 if (enable) {
457 regw((regr(VPIF_INTEN) | 0x10), VPIF_INTEN);
458 regw((regr(VPIF_INTEN_SET) | 0x10), VPIF_INTEN_SET);
459 regw((regr(VPIF_INTEN) | VPIF_INTEN_FRAME_CH2), VPIF_INTEN);
460 regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH2),
461 VPIF_INTEN_SET);
462 } else {
463 regw((regr(VPIF_INTEN) & (~VPIF_INTEN_FRAME_CH2)), VPIF_INTEN);
464 regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH2),
465 VPIF_INTEN_SET);
466 }
467 spin_unlock_irqrestore(&vpif_lock, flags);
468}
469
470/* inline function to enable interrupt for channel3 */
471static inline void channel3_intr_enable(int enable)
472{
473 unsigned long flags;
474
475 spin_lock_irqsave(&vpif_lock, flags);
476
477 if (enable) {
478 regw((regr(VPIF_INTEN) | 0x10), VPIF_INTEN);
479 regw((regr(VPIF_INTEN_SET) | 0x10), VPIF_INTEN_SET);
480
481 regw((regr(VPIF_INTEN) | VPIF_INTEN_FRAME_CH3), VPIF_INTEN);
482 regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH3),
483 VPIF_INTEN_SET);
484 } else {
485 regw((regr(VPIF_INTEN) & (~VPIF_INTEN_FRAME_CH3)), VPIF_INTEN);
486 regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH3),
487 VPIF_INTEN_SET);
488 }
489 spin_unlock_irqrestore(&vpif_lock, flags);
490}
491
492/* inline function to enable raw vbi data for channel2 */
493static inline void channel2_raw_enable(int enable, u8 index)
494{
495 u32 mask;
496
497 if (1 == index)
498 mask = VPIF_CH_VANC_EN_BIT;
499 else
500 mask = VPIF_CH_HANC_EN_BIT;
501
502 if (enable)
503 vpif_set_bit(VPIF_CH2_CTRL, mask);
504 else
505 vpif_clr_bit(VPIF_CH2_CTRL, mask);
506}
507
508/* inline function to enable raw vbi data for channel3*/
509static inline void channel3_raw_enable(int enable, u8 index)
510{
511 u32 mask;
512
513 if (1 == index)
514 mask = VPIF_CH_VANC_EN_BIT;
515 else
516 mask = VPIF_CH_HANC_EN_BIT;
517
518 if (enable)
519 vpif_set_bit(VPIF_CH3_CTRL, mask);
520 else
521 vpif_clr_bit(VPIF_CH3_CTRL, mask);
522}
523
524/* function to enable clipping (for both active and blanking regions) on ch 2 */
525static inline void channel2_clipping_enable(int enable)
526{
527 if (enable) {
528 vpif_set_bit(VPIF_CH2_CTRL, VPIF_CH2_CLIP_ANC_EN);
529 vpif_set_bit(VPIF_CH2_CTRL, VPIF_CH2_CLIP_ACTIVE_EN);
530 } else {
531 vpif_clr_bit(VPIF_CH2_CTRL, VPIF_CH2_CLIP_ANC_EN);
532 vpif_clr_bit(VPIF_CH2_CTRL, VPIF_CH2_CLIP_ACTIVE_EN);
533 }
534}
535
536/* function to enable clipping (for both active and blanking regions) on ch 2 */
537static inline void channel3_clipping_enable(int enable)
538{
539 if (enable) {
540 vpif_set_bit(VPIF_CH3_CTRL, VPIF_CH3_CLIP_ANC_EN);
541 vpif_set_bit(VPIF_CH3_CTRL, VPIF_CH3_CLIP_ACTIVE_EN);
542 } else {
543 vpif_clr_bit(VPIF_CH3_CTRL, VPIF_CH3_CLIP_ANC_EN);
544 vpif_clr_bit(VPIF_CH3_CTRL, VPIF_CH3_CLIP_ACTIVE_EN);
545 }
546}
547
548/* inline function to set buffer addresses in case of Y/C non mux mode */
549static inline void ch2_set_videobuf_addr_yc_nmux(unsigned long top_strt_luma,
550 unsigned long btm_strt_luma,
551 unsigned long top_strt_chroma,
552 unsigned long btm_strt_chroma)
553{
554 regw(top_strt_luma, VPIF_CH2_TOP_STRT_ADD_LUMA);
555 regw(btm_strt_luma, VPIF_CH2_BTM_STRT_ADD_LUMA);
556 regw(top_strt_chroma, VPIF_CH3_TOP_STRT_ADD_CHROMA);
557 regw(btm_strt_chroma, VPIF_CH3_BTM_STRT_ADD_CHROMA);
558}
559
560/* inline function to set buffer addresses in VPIF registers for video data */
561static inline void ch2_set_videobuf_addr(unsigned long top_strt_luma,
562 unsigned long btm_strt_luma,
563 unsigned long top_strt_chroma,
564 unsigned long btm_strt_chroma)
565{
566 regw(top_strt_luma, VPIF_CH2_TOP_STRT_ADD_LUMA);
567 regw(btm_strt_luma, VPIF_CH2_BTM_STRT_ADD_LUMA);
568 regw(top_strt_chroma, VPIF_CH2_TOP_STRT_ADD_CHROMA);
569 regw(btm_strt_chroma, VPIF_CH2_BTM_STRT_ADD_CHROMA);
570}
571
572static inline void ch3_set_videobuf_addr(unsigned long top_strt_luma,
573 unsigned long btm_strt_luma,
574 unsigned long top_strt_chroma,
575 unsigned long btm_strt_chroma)
576{
577 regw(top_strt_luma, VPIF_CH3_TOP_STRT_ADD_LUMA);
578 regw(btm_strt_luma, VPIF_CH3_BTM_STRT_ADD_LUMA);
579 regw(top_strt_chroma, VPIF_CH3_TOP_STRT_ADD_CHROMA);
580 regw(btm_strt_chroma, VPIF_CH3_BTM_STRT_ADD_CHROMA);
581}
582
583/* inline function to set buffer addresses in VPIF registers for vbi data */
584static inline void ch2_set_vbi_addr(unsigned long top_strt_luma,
585 unsigned long btm_strt_luma,
586 unsigned long top_strt_chroma,
587 unsigned long btm_strt_chroma)
588{
589 regw(top_strt_luma, VPIF_CH2_TOP_STRT_ADD_VANC);
590 regw(btm_strt_luma, VPIF_CH2_BTM_STRT_ADD_VANC);
591}
592
593static inline void ch3_set_vbi_addr(unsigned long top_strt_luma,
594 unsigned long btm_strt_luma,
595 unsigned long top_strt_chroma,
596 unsigned long btm_strt_chroma)
597{
598 regw(top_strt_luma, VPIF_CH3_TOP_STRT_ADD_VANC);
599 regw(btm_strt_luma, VPIF_CH3_BTM_STRT_ADD_VANC);
600}
601
602static inline int vpif_intr_status(int channel)
603{
604 int status = 0;
605 int mask;
606
607 if (channel < 0 || channel > 3)
608 return 0;
609
610 mask = 1 << channel;
611 status = regr(VPIF_STATUS) & mask;
612 regw(status, VPIF_STATUS_CLR);
613
614 return status;
615}
616
617#define VPIF_MAX_NAME (30)
618
619/* This structure will store size parameters as per the mode selected by user */
620struct vpif_channel_config_params {
621 char name[VPIF_MAX_NAME]; /* Name of the mode */
622 u16 width; /* Indicates width of the image */
623 u16 height; /* Indicates height of the image */
624 u8 frm_fmt; /* Interlaced (0) or progressive (1) */
625 u8 ycmux_mode; /* This mode requires one (0) or two (1)
626 channels */
627 u16 eav2sav; /* length of eav 2 sav */
628 u16 sav2eav; /* length of sav 2 eav */
629 u16 l1, l3, l5, l7, l9, l11; /* Other parameter configurations */
630 u16 vsize; /* Vertical size of the image */
631 u8 capture_format; /* Indicates whether capture format
632 * is in BT or in CCD/CMOS */
633 u8 vbi_supported; /* Indicates whether this mode
634 * supports capturing vbi or not */
635 u8 hd_sd; /* HDTV (1) or SDTV (0) format */
636 v4l2_std_id stdid; /* SDTV format */
637 u32 dv_preset; /* HDTV format */
638};
639
640extern const unsigned int vpif_ch_params_count;
641extern const struct vpif_channel_config_params ch_params[];
642
643struct vpif_video_params;
644struct vpif_params;
645struct vpif_vbi_params;
646
647int vpif_set_video_params(struct vpif_params *vpifparams, u8 channel_id);
648void vpif_set_vbi_display_params(struct vpif_vbi_params *vbiparams,
649 u8 channel_id);
650int vpif_channel_getfid(u8 channel_id);
651
652enum data_size {
653 _8BITS = 0,
654 _10BITS,
655 _12BITS,
656};
657
658/* Structure for vpif parameters for raw vbi data */
659struct vpif_vbi_params {
660 __u32 hstart0; /* Horizontal start of raw vbi data for first field */
661 __u32 vstart0; /* Vertical start of raw vbi data for first field */
662 __u32 hsize0; /* Horizontal size of raw vbi data for first field */
663 __u32 vsize0; /* Vertical size of raw vbi data for first field */
664 __u32 hstart1; /* Horizontal start of raw vbi data for second field */
665 __u32 vstart1; /* Vertical start of raw vbi data for second field */
666 __u32 hsize1; /* Horizontal size of raw vbi data for second field */
667 __u32 vsize1; /* Vertical size of raw vbi data for second field */
668};
669
670/* structure for vpif parameters */
671struct vpif_video_params {
672 __u8 storage_mode; /* Indicates field or frame mode */
673 unsigned long hpitch;
674 v4l2_std_id stdid;
675};
676
677struct vpif_params {
678 struct vpif_interface iface;
679 struct vpif_video_params video_params;
680 struct vpif_channel_config_params std_info;
681 union param {
682 struct vpif_vbi_params vbi_params;
683 enum data_size data_sz;
684 } params;
685};
686
687#endif /* End of #ifndef VPIF_H */
688
diff --git a/drivers/media/video/davinci/vpif_capture.c b/drivers/media/video/davinci/vpif_capture.c
deleted file mode 100644
index 1b625b065c32..000000000000
--- a/drivers/media/video/davinci/vpif_capture.c
+++ /dev/null
@@ -1,2456 +0,0 @@
1/*
2 * Copyright (C) 2009 Texas Instruments Inc
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * TODO : add support for VBI & HBI data service
19 * add static buffer allocation
20 */
21#include <linux/kernel.h>
22#include <linux/init.h>
23#include <linux/module.h>
24#include <linux/errno.h>
25#include <linux/fs.h>
26#include <linux/mm.h>
27#include <linux/interrupt.h>
28#include <linux/workqueue.h>
29#include <linux/string.h>
30#include <linux/videodev2.h>
31#include <linux/wait.h>
32#include <linux/time.h>
33#include <linux/i2c.h>
34#include <linux/platform_device.h>
35#include <linux/io.h>
36#include <linux/slab.h>
37#include <media/v4l2-device.h>
38#include <media/v4l2-ioctl.h>
39#include <media/v4l2-chip-ident.h>
40
41#include "vpif_capture.h"
42#include "vpif.h"
43
44MODULE_DESCRIPTION("TI DaVinci VPIF Capture driver");
45MODULE_LICENSE("GPL");
46MODULE_VERSION(VPIF_CAPTURE_VERSION);
47
48#define vpif_err(fmt, arg...) v4l2_err(&vpif_obj.v4l2_dev, fmt, ## arg)
49#define vpif_dbg(level, debug, fmt, arg...) \
50 v4l2_dbg(level, debug, &vpif_obj.v4l2_dev, fmt, ## arg)
51
52static int debug = 1;
53static u32 ch0_numbuffers = 3;
54static u32 ch1_numbuffers = 3;
55static u32 ch0_bufsize = 1920 * 1080 * 2;
56static u32 ch1_bufsize = 720 * 576 * 2;
57
58module_param(debug, int, 0644);
59module_param(ch0_numbuffers, uint, S_IRUGO);
60module_param(ch1_numbuffers, uint, S_IRUGO);
61module_param(ch0_bufsize, uint, S_IRUGO);
62module_param(ch1_bufsize, uint, S_IRUGO);
63
64MODULE_PARM_DESC(debug, "Debug level 0-1");
65MODULE_PARM_DESC(ch2_numbuffers, "Channel0 buffer count (default:3)");
66MODULE_PARM_DESC(ch3_numbuffers, "Channel1 buffer count (default:3)");
67MODULE_PARM_DESC(ch2_bufsize, "Channel0 buffer size (default:1920 x 1080 x 2)");
68MODULE_PARM_DESC(ch3_bufsize, "Channel1 buffer size (default:720 x 576 x 2)");
69
70static struct vpif_config_params config_params = {
71 .min_numbuffers = 3,
72 .numbuffers[0] = 3,
73 .numbuffers[1] = 3,
74 .min_bufsize[0] = 720 * 480 * 2,
75 .min_bufsize[1] = 720 * 480 * 2,
76 .channel_bufsize[0] = 1920 * 1080 * 2,
77 .channel_bufsize[1] = 720 * 576 * 2,
78};
79
80/* global variables */
81static struct vpif_device vpif_obj = { {NULL} };
82static struct device *vpif_dev;
83static void vpif_calculate_offsets(struct channel_obj *ch);
84static void vpif_config_addr(struct channel_obj *ch, int muxmode);
85
86/**
87 * buffer_prepare : callback function for buffer prepare
88 * @vb: ptr to vb2_buffer
89 *
90 * This is the callback function for buffer prepare when vb2_qbuf()
91 * function is called. The buffer is prepared and user space virtual address
92 * or user address is converted into physical address
93 */
94static int vpif_buffer_prepare(struct vb2_buffer *vb)
95{
96 /* Get the file handle object and channel object */
97 struct vpif_fh *fh = vb2_get_drv_priv(vb->vb2_queue);
98 struct vb2_queue *q = vb->vb2_queue;
99 struct channel_obj *ch = fh->channel;
100 struct common_obj *common;
101 unsigned long addr;
102
103 vpif_dbg(2, debug, "vpif_buffer_prepare\n");
104
105 common = &ch->common[VPIF_VIDEO_INDEX];
106
107 if (vb->state != VB2_BUF_STATE_ACTIVE &&
108 vb->state != VB2_BUF_STATE_PREPARED) {
109 vb2_set_plane_payload(vb, 0, common->fmt.fmt.pix.sizeimage);
110 if (vb2_plane_vaddr(vb, 0) &&
111 vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0))
112 goto exit;
113 addr = vb2_dma_contig_plane_dma_addr(vb, 0);
114
115 if (q->streaming) {
116 if (!IS_ALIGNED((addr + common->ytop_off), 8) ||
117 !IS_ALIGNED((addr + common->ybtm_off), 8) ||
118 !IS_ALIGNED((addr + common->ctop_off), 8) ||
119 !IS_ALIGNED((addr + common->cbtm_off), 8))
120 goto exit;
121 }
122 }
123 return 0;
124exit:
125 vpif_dbg(1, debug, "buffer_prepare:offset is not aligned to 8 bytes\n");
126 return -EINVAL;
127}
128
129/**
130 * vpif_buffer_queue_setup : Callback function for buffer setup.
131 * @vq: vb2_queue ptr
132 * @fmt: v4l2 format
133 * @nbuffers: ptr to number of buffers requested by application
134 * @nplanes:: contains number of distinct video planes needed to hold a frame
135 * @sizes[]: contains the size (in bytes) of each plane.
136 * @alloc_ctxs: ptr to allocation context
137 *
138 * This callback function is called when reqbuf() is called to adjust
139 * the buffer count and buffer size
140 */
141static int vpif_buffer_queue_setup(struct vb2_queue *vq,
142 const struct v4l2_format *fmt,
143 unsigned int *nbuffers, unsigned int *nplanes,
144 unsigned int sizes[], void *alloc_ctxs[])
145{
146 /* Get the file handle object and channel object */
147 struct vpif_fh *fh = vb2_get_drv_priv(vq);
148 struct channel_obj *ch = fh->channel;
149 struct common_obj *common;
150 unsigned long size;
151
152 common = &ch->common[VPIF_VIDEO_INDEX];
153
154 vpif_dbg(2, debug, "vpif_buffer_setup\n");
155
156 /* If memory type is not mmap, return */
157 if (V4L2_MEMORY_MMAP == common->memory) {
158 /* Calculate the size of the buffer */
159 size = config_params.channel_bufsize[ch->channel_id];
160 /*
161 * Checking if the buffer size exceeds the available buffer
162 * ycmux_mode = 0 means 1 channel mode HD and
163 * ycmux_mode = 1 means 2 channels mode SD
164 */
165 if (ch->vpifparams.std_info.ycmux_mode == 0) {
166 if (config_params.video_limit[ch->channel_id])
167 while (size * *nbuffers >
168 (config_params.video_limit[0]
169 + config_params.video_limit[1]))
170 (*nbuffers)--;
171 } else {
172 if (config_params.video_limit[ch->channel_id])
173 while (size * *nbuffers >
174 config_params.video_limit[ch->channel_id])
175 (*nbuffers)--;
176 }
177
178 } else {
179 size = common->fmt.fmt.pix.sizeimage;
180 }
181
182 if (*nbuffers < config_params.min_numbuffers)
183 *nbuffers = config_params.min_numbuffers;
184
185 *nplanes = 1;
186 sizes[0] = size;
187 alloc_ctxs[0] = common->alloc_ctx;
188
189 return 0;
190}
191
192/**
193 * vpif_buffer_queue : Callback function to add buffer to DMA queue
194 * @vb: ptr to vb2_buffer
195 */
196static void vpif_buffer_queue(struct vb2_buffer *vb)
197{
198 /* Get the file handle object and channel object */
199 struct vpif_fh *fh = vb2_get_drv_priv(vb->vb2_queue);
200 struct channel_obj *ch = fh->channel;
201 struct vpif_cap_buffer *buf = container_of(vb,
202 struct vpif_cap_buffer, vb);
203 struct common_obj *common;
204
205 common = &ch->common[VPIF_VIDEO_INDEX];
206
207 vpif_dbg(2, debug, "vpif_buffer_queue\n");
208
209 /* add the buffer to the DMA queue */
210 list_add_tail(&buf->list, &common->dma_queue);
211}
212
213/**
214 * vpif_buf_cleanup : Callback function to free buffer
215 * @vb: ptr to vb2_buffer
216 *
217 * This function is called from the videobuf2 layer to free memory
218 * allocated to the buffers
219 */
220static void vpif_buf_cleanup(struct vb2_buffer *vb)
221{
222 /* Get the file handle object and channel object */
223 struct vpif_fh *fh = vb2_get_drv_priv(vb->vb2_queue);
224 struct vpif_cap_buffer *buf = container_of(vb,
225 struct vpif_cap_buffer, vb);
226 struct channel_obj *ch = fh->channel;
227 struct common_obj *common;
228 unsigned long flags;
229
230 common = &ch->common[VPIF_VIDEO_INDEX];
231
232 spin_lock_irqsave(&common->irqlock, flags);
233 if (vb->state == VB2_BUF_STATE_ACTIVE)
234 list_del_init(&buf->list);
235 spin_unlock_irqrestore(&common->irqlock, flags);
236
237}
238
239static void vpif_wait_prepare(struct vb2_queue *vq)
240{
241 struct vpif_fh *fh = vb2_get_drv_priv(vq);
242 struct channel_obj *ch = fh->channel;
243 struct common_obj *common;
244
245 common = &ch->common[VPIF_VIDEO_INDEX];
246 mutex_unlock(&common->lock);
247}
248
249static void vpif_wait_finish(struct vb2_queue *vq)
250{
251 struct vpif_fh *fh = vb2_get_drv_priv(vq);
252 struct channel_obj *ch = fh->channel;
253 struct common_obj *common;
254
255 common = &ch->common[VPIF_VIDEO_INDEX];
256 mutex_lock(&common->lock);
257}
258
259static int vpif_buffer_init(struct vb2_buffer *vb)
260{
261 struct vpif_cap_buffer *buf = container_of(vb,
262 struct vpif_cap_buffer, vb);
263
264 INIT_LIST_HEAD(&buf->list);
265
266 return 0;
267}
268
269static u8 channel_first_int[VPIF_NUMBER_OF_OBJECTS][2] =
270 { {1, 1} };
271
272static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
273{
274 struct vpif_capture_config *vpif_config_data =
275 vpif_dev->platform_data;
276 struct vpif_fh *fh = vb2_get_drv_priv(vq);
277 struct channel_obj *ch = fh->channel;
278 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
279 struct vpif_params *vpif = &ch->vpifparams;
280 unsigned long addr = 0;
281 int ret;
282
283 /* If buffer queue is empty, return error */
284 if (list_empty(&common->dma_queue)) {
285 vpif_dbg(1, debug, "buffer queue is empty\n");
286 return -EIO;
287 }
288
289 /* Get the next frame from the buffer queue */
290 common->cur_frm = common->next_frm = list_entry(common->dma_queue.next,
291 struct vpif_cap_buffer, list);
292 /* Remove buffer from the buffer queue */
293 list_del(&common->cur_frm->list);
294 /* Mark state of the current frame to active */
295 common->cur_frm->vb.state = VB2_BUF_STATE_ACTIVE;
296 /* Initialize field_id and started member */
297 ch->field_id = 0;
298 common->started = 1;
299 addr = vb2_dma_contig_plane_dma_addr(&common->cur_frm->vb, 0);
300
301 /* Calculate the offset for Y and C data in the buffer */
302 vpif_calculate_offsets(ch);
303
304 if ((vpif->std_info.frm_fmt &&
305 ((common->fmt.fmt.pix.field != V4L2_FIELD_NONE) &&
306 (common->fmt.fmt.pix.field != V4L2_FIELD_ANY))) ||
307 (!vpif->std_info.frm_fmt &&
308 (common->fmt.fmt.pix.field == V4L2_FIELD_NONE))) {
309 vpif_dbg(1, debug, "conflict in field format and std format\n");
310 return -EINVAL;
311 }
312
313 /* configure 1 or 2 channel mode */
314 ret = vpif_config_data->setup_input_channel_mode
315 (vpif->std_info.ycmux_mode);
316
317 if (ret < 0) {
318 vpif_dbg(1, debug, "can't set vpif channel mode\n");
319 return ret;
320 }
321
322 /* Call vpif_set_params function to set the parameters and addresses */
323 ret = vpif_set_video_params(vpif, ch->channel_id);
324
325 if (ret < 0) {
326 vpif_dbg(1, debug, "can't set video params\n");
327 return ret;
328 }
329
330 common->started = ret;
331 vpif_config_addr(ch, ret);
332
333 common->set_addr(addr + common->ytop_off,
334 addr + common->ybtm_off,
335 addr + common->ctop_off,
336 addr + common->cbtm_off);
337
338 /**
339 * Set interrupt for both the fields in VPIF Register enable channel in
340 * VPIF register
341 */
342 if ((VPIF_CHANNEL0_VIDEO == ch->channel_id)) {
343 channel0_intr_assert();
344 channel0_intr_enable(1);
345 enable_channel0(1);
346 }
347 if ((VPIF_CHANNEL1_VIDEO == ch->channel_id) ||
348 (common->started == 2)) {
349 channel1_intr_assert();
350 channel1_intr_enable(1);
351 enable_channel1(1);
352 }
353 channel_first_int[VPIF_VIDEO_INDEX][ch->channel_id] = 1;
354
355 return 0;
356}
357
358/* abort streaming and wait for last buffer */
359static int vpif_stop_streaming(struct vb2_queue *vq)
360{
361 struct vpif_fh *fh = vb2_get_drv_priv(vq);
362 struct channel_obj *ch = fh->channel;
363 struct common_obj *common;
364
365 if (!vb2_is_streaming(vq))
366 return 0;
367
368 common = &ch->common[VPIF_VIDEO_INDEX];
369
370 /* release all active buffers */
371 while (!list_empty(&common->dma_queue)) {
372 common->next_frm = list_entry(common->dma_queue.next,
373 struct vpif_cap_buffer, list);
374 list_del(&common->next_frm->list);
375 vb2_buffer_done(&common->next_frm->vb, VB2_BUF_STATE_ERROR);
376 }
377
378 return 0;
379}
380
381static struct vb2_ops video_qops = {
382 .queue_setup = vpif_buffer_queue_setup,
383 .wait_prepare = vpif_wait_prepare,
384 .wait_finish = vpif_wait_finish,
385 .buf_init = vpif_buffer_init,
386 .buf_prepare = vpif_buffer_prepare,
387 .start_streaming = vpif_start_streaming,
388 .stop_streaming = vpif_stop_streaming,
389 .buf_cleanup = vpif_buf_cleanup,
390 .buf_queue = vpif_buffer_queue,
391};
392
393/**
394 * vpif_process_buffer_complete: process a completed buffer
395 * @common: ptr to common channel object
396 *
397 * This function time stamp the buffer and mark it as DONE. It also
398 * wake up any process waiting on the QUEUE and set the next buffer
399 * as current
400 */
401static void vpif_process_buffer_complete(struct common_obj *common)
402{
403 do_gettimeofday(&common->cur_frm->vb.v4l2_buf.timestamp);
404 vb2_buffer_done(&common->cur_frm->vb,
405 VB2_BUF_STATE_DONE);
406 /* Make curFrm pointing to nextFrm */
407 common->cur_frm = common->next_frm;
408}
409
410/**
411 * vpif_schedule_next_buffer: set next buffer address for capture
412 * @common : ptr to common channel object
413 *
414 * This function will get next buffer from the dma queue and
415 * set the buffer address in the vpif register for capture.
416 * the buffer is marked active
417 */
418static void vpif_schedule_next_buffer(struct common_obj *common)
419{
420 unsigned long addr = 0;
421
422 common->next_frm = list_entry(common->dma_queue.next,
423 struct vpif_cap_buffer, list);
424 /* Remove that buffer from the buffer queue */
425 list_del(&common->next_frm->list);
426 common->next_frm->vb.state = VB2_BUF_STATE_ACTIVE;
427 addr = vb2_dma_contig_plane_dma_addr(&common->next_frm->vb, 0);
428
429 /* Set top and bottom field addresses in VPIF registers */
430 common->set_addr(addr + common->ytop_off,
431 addr + common->ybtm_off,
432 addr + common->ctop_off,
433 addr + common->cbtm_off);
434}
435
436/**
437 * vpif_channel_isr : ISR handler for vpif capture
438 * @irq: irq number
439 * @dev_id: dev_id ptr
440 *
441 * It changes status of the captured buffer, takes next buffer from the queue
442 * and sets its address in VPIF registers
443 */
444static irqreturn_t vpif_channel_isr(int irq, void *dev_id)
445{
446 struct vpif_device *dev = &vpif_obj;
447 struct common_obj *common;
448 struct channel_obj *ch;
449 enum v4l2_field field;
450 int channel_id = 0;
451 int fid = -1, i;
452
453 channel_id = *(int *)(dev_id);
454 if (!vpif_intr_status(channel_id))
455 return IRQ_NONE;
456
457 ch = dev->dev[channel_id];
458
459 field = ch->common[VPIF_VIDEO_INDEX].fmt.fmt.pix.field;
460
461 for (i = 0; i < VPIF_NUMBER_OF_OBJECTS; i++) {
462 common = &ch->common[i];
463 /* skip If streaming is not started in this channel */
464 if (0 == common->started)
465 continue;
466
467 /* Check the field format */
468 if (1 == ch->vpifparams.std_info.frm_fmt) {
469 /* Progressive mode */
470 if (list_empty(&common->dma_queue))
471 continue;
472
473 if (!channel_first_int[i][channel_id])
474 vpif_process_buffer_complete(common);
475
476 channel_first_int[i][channel_id] = 0;
477
478 vpif_schedule_next_buffer(common);
479
480
481 channel_first_int[i][channel_id] = 0;
482 } else {
483 /**
484 * Interlaced mode. If it is first interrupt, ignore
485 * it
486 */
487 if (channel_first_int[i][channel_id]) {
488 channel_first_int[i][channel_id] = 0;
489 continue;
490 }
491 if (0 == i) {
492 ch->field_id ^= 1;
493 /* Get field id from VPIF registers */
494 fid = vpif_channel_getfid(ch->channel_id);
495 if (fid != ch->field_id) {
496 /**
497 * If field id does not match stored
498 * field id, make them in sync
499 */
500 if (0 == fid)
501 ch->field_id = fid;
502 return IRQ_HANDLED;
503 }
504 }
505 /* device field id and local field id are in sync */
506 if (0 == fid) {
507 /* this is even field */
508 if (common->cur_frm == common->next_frm)
509 continue;
510
511 /* mark the current buffer as done */
512 vpif_process_buffer_complete(common);
513 } else if (1 == fid) {
514 /* odd field */
515 if (list_empty(&common->dma_queue) ||
516 (common->cur_frm != common->next_frm))
517 continue;
518
519 vpif_schedule_next_buffer(common);
520 }
521 }
522 }
523 return IRQ_HANDLED;
524}
525
526/**
527 * vpif_update_std_info() - update standard related info
528 * @ch: ptr to channel object
529 *
530 * For a given standard selected by application, update values
531 * in the device data structures
532 */
533static int vpif_update_std_info(struct channel_obj *ch)
534{
535 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
536 struct vpif_params *vpifparams = &ch->vpifparams;
537 const struct vpif_channel_config_params *config;
538 struct vpif_channel_config_params *std_info = &vpifparams->std_info;
539 struct video_obj *vid_ch = &ch->video;
540 int index;
541
542 vpif_dbg(2, debug, "vpif_update_std_info\n");
543
544 for (index = 0; index < vpif_ch_params_count; index++) {
545 config = &ch_params[index];
546 if (config->hd_sd == 0) {
547 vpif_dbg(2, debug, "SD format\n");
548 if (config->stdid & vid_ch->stdid) {
549 memcpy(std_info, config, sizeof(*config));
550 break;
551 }
552 } else {
553 vpif_dbg(2, debug, "HD format\n");
554 if (config->dv_preset == vid_ch->dv_preset) {
555 memcpy(std_info, config, sizeof(*config));
556 break;
557 }
558 }
559 }
560
561 /* standard not found */
562 if (index == vpif_ch_params_count)
563 return -EINVAL;
564
565 common->fmt.fmt.pix.width = std_info->width;
566 common->width = std_info->width;
567 common->fmt.fmt.pix.height = std_info->height;
568 common->height = std_info->height;
569 common->fmt.fmt.pix.bytesperline = std_info->width;
570 vpifparams->video_params.hpitch = std_info->width;
571 vpifparams->video_params.storage_mode = std_info->frm_fmt;
572
573 return 0;
574}
575
576/**
577 * vpif_calculate_offsets : This function calculates buffers offsets
578 * @ch : ptr to channel object
579 *
580 * This function calculates buffer offsets for Y and C in the top and
581 * bottom field
582 */
583static void vpif_calculate_offsets(struct channel_obj *ch)
584{
585 unsigned int hpitch, vpitch, sizeimage;
586 struct video_obj *vid_ch = &(ch->video);
587 struct vpif_params *vpifparams = &ch->vpifparams;
588 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
589 enum v4l2_field field = common->fmt.fmt.pix.field;
590
591 vpif_dbg(2, debug, "vpif_calculate_offsets\n");
592
593 if (V4L2_FIELD_ANY == field) {
594 if (vpifparams->std_info.frm_fmt)
595 vid_ch->buf_field = V4L2_FIELD_NONE;
596 else
597 vid_ch->buf_field = V4L2_FIELD_INTERLACED;
598 } else
599 vid_ch->buf_field = common->fmt.fmt.pix.field;
600
601 sizeimage = common->fmt.fmt.pix.sizeimage;
602
603 hpitch = common->fmt.fmt.pix.bytesperline;
604 vpitch = sizeimage / (hpitch * 2);
605
606 if ((V4L2_FIELD_NONE == vid_ch->buf_field) ||
607 (V4L2_FIELD_INTERLACED == vid_ch->buf_field)) {
608 /* Calculate offsets for Y top, Y Bottom, C top and C Bottom */
609 common->ytop_off = 0;
610 common->ybtm_off = hpitch;
611 common->ctop_off = sizeimage / 2;
612 common->cbtm_off = sizeimage / 2 + hpitch;
613 } else if (V4L2_FIELD_SEQ_TB == vid_ch->buf_field) {
614 /* Calculate offsets for Y top, Y Bottom, C top and C Bottom */
615 common->ytop_off = 0;
616 common->ybtm_off = sizeimage / 4;
617 common->ctop_off = sizeimage / 2;
618 common->cbtm_off = common->ctop_off + sizeimage / 4;
619 } else if (V4L2_FIELD_SEQ_BT == vid_ch->buf_field) {
620 /* Calculate offsets for Y top, Y Bottom, C top and C Bottom */
621 common->ybtm_off = 0;
622 common->ytop_off = sizeimage / 4;
623 common->cbtm_off = sizeimage / 2;
624 common->ctop_off = common->cbtm_off + sizeimage / 4;
625 }
626 if ((V4L2_FIELD_NONE == vid_ch->buf_field) ||
627 (V4L2_FIELD_INTERLACED == vid_ch->buf_field))
628 vpifparams->video_params.storage_mode = 1;
629 else
630 vpifparams->video_params.storage_mode = 0;
631
632 if (1 == vpifparams->std_info.frm_fmt)
633 vpifparams->video_params.hpitch =
634 common->fmt.fmt.pix.bytesperline;
635 else {
636 if ((field == V4L2_FIELD_ANY)
637 || (field == V4L2_FIELD_INTERLACED))
638 vpifparams->video_params.hpitch =
639 common->fmt.fmt.pix.bytesperline * 2;
640 else
641 vpifparams->video_params.hpitch =
642 common->fmt.fmt.pix.bytesperline;
643 }
644
645 ch->vpifparams.video_params.stdid = vpifparams->std_info.stdid;
646}
647
648/**
649 * vpif_config_format: configure default frame format in the device
650 * ch : ptr to channel object
651 */
652static void vpif_config_format(struct channel_obj *ch)
653{
654 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
655
656 vpif_dbg(2, debug, "vpif_config_format\n");
657
658 common->fmt.fmt.pix.field = V4L2_FIELD_ANY;
659 if (config_params.numbuffers[ch->channel_id] == 0)
660 common->memory = V4L2_MEMORY_USERPTR;
661 else
662 common->memory = V4L2_MEMORY_MMAP;
663
664 common->fmt.fmt.pix.sizeimage
665 = config_params.channel_bufsize[ch->channel_id];
666
667 if (ch->vpifparams.iface.if_type == VPIF_IF_RAW_BAYER)
668 common->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_SBGGR8;
669 else
670 common->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV422P;
671 common->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
672}
673
674/**
675 * vpif_get_default_field() - Get default field type based on interface
676 * @vpif_params - ptr to vpif params
677 */
678static inline enum v4l2_field vpif_get_default_field(
679 struct vpif_interface *iface)
680{
681 return (iface->if_type == VPIF_IF_RAW_BAYER) ? V4L2_FIELD_NONE :
682 V4L2_FIELD_INTERLACED;
683}
684
685/**
686 * vpif_check_format() - check given pixel format for compatibility
687 * @ch - channel ptr
688 * @pixfmt - Given pixel format
689 * @update - update the values as per hardware requirement
690 *
691 * Check the application pixel format for S_FMT and update the input
692 * values as per hardware limits for TRY_FMT. The default pixel and
693 * field format is selected based on interface type.
694 */
695static int vpif_check_format(struct channel_obj *ch,
696 struct v4l2_pix_format *pixfmt,
697 int update)
698{
699 struct common_obj *common = &(ch->common[VPIF_VIDEO_INDEX]);
700 struct vpif_params *vpif_params = &ch->vpifparams;
701 enum v4l2_field field = pixfmt->field;
702 u32 sizeimage, hpitch, vpitch;
703 int ret = -EINVAL;
704
705 vpif_dbg(2, debug, "vpif_check_format\n");
706 /**
707 * first check for the pixel format. If if_type is Raw bayer,
708 * only V4L2_PIX_FMT_SBGGR8 format is supported. Otherwise only
709 * V4L2_PIX_FMT_YUV422P is supported
710 */
711 if (vpif_params->iface.if_type == VPIF_IF_RAW_BAYER) {
712 if (pixfmt->pixelformat != V4L2_PIX_FMT_SBGGR8) {
713 if (!update) {
714 vpif_dbg(2, debug, "invalid pix format\n");
715 goto exit;
716 }
717 pixfmt->pixelformat = V4L2_PIX_FMT_SBGGR8;
718 }
719 } else {
720 if (pixfmt->pixelformat != V4L2_PIX_FMT_YUV422P) {
721 if (!update) {
722 vpif_dbg(2, debug, "invalid pixel format\n");
723 goto exit;
724 }
725 pixfmt->pixelformat = V4L2_PIX_FMT_YUV422P;
726 }
727 }
728
729 if (!(VPIF_VALID_FIELD(field))) {
730 if (!update) {
731 vpif_dbg(2, debug, "invalid field format\n");
732 goto exit;
733 }
734 /**
735 * By default use FIELD_NONE for RAW Bayer capture
736 * and FIELD_INTERLACED for other interfaces
737 */
738 field = vpif_get_default_field(&vpif_params->iface);
739 } else if (field == V4L2_FIELD_ANY)
740 /* unsupported field. Use default */
741 field = vpif_get_default_field(&vpif_params->iface);
742
743 /* validate the hpitch */
744 hpitch = pixfmt->bytesperline;
745 if (hpitch < vpif_params->std_info.width) {
746 if (!update) {
747 vpif_dbg(2, debug, "invalid hpitch\n");
748 goto exit;
749 }
750 hpitch = vpif_params->std_info.width;
751 }
752
753 sizeimage = pixfmt->sizeimage;
754
755 vpitch = sizeimage / (hpitch * 2);
756
757 /* validate the vpitch */
758 if (vpitch < vpif_params->std_info.height) {
759 if (!update) {
760 vpif_dbg(2, debug, "Invalid vpitch\n");
761 goto exit;
762 }
763 vpitch = vpif_params->std_info.height;
764 }
765
766 /* Check for 8 byte alignment */
767 if (!ALIGN(hpitch, 8)) {
768 if (!update) {
769 vpif_dbg(2, debug, "invalid pitch alignment\n");
770 goto exit;
771 }
772 /* adjust to next 8 byte boundary */
773 hpitch = (((hpitch + 7) / 8) * 8);
774 }
775 /* if update is set, modify the bytesperline and sizeimage */
776 if (update) {
777 pixfmt->bytesperline = hpitch;
778 pixfmt->sizeimage = hpitch * vpitch * 2;
779 }
780 /**
781 * Image width and height is always based on current standard width and
782 * height
783 */
784 pixfmt->width = common->fmt.fmt.pix.width;
785 pixfmt->height = common->fmt.fmt.pix.height;
786 return 0;
787exit:
788 return ret;
789}
790
791/**
792 * vpif_config_addr() - function to configure buffer address in vpif
793 * @ch - channel ptr
794 * @muxmode - channel mux mode
795 */
796static void vpif_config_addr(struct channel_obj *ch, int muxmode)
797{
798 struct common_obj *common;
799
800 vpif_dbg(2, debug, "vpif_config_addr\n");
801
802 common = &(ch->common[VPIF_VIDEO_INDEX]);
803
804 if (VPIF_CHANNEL1_VIDEO == ch->channel_id)
805 common->set_addr = ch1_set_videobuf_addr;
806 else if (2 == muxmode)
807 common->set_addr = ch0_set_videobuf_addr_yc_nmux;
808 else
809 common->set_addr = ch0_set_videobuf_addr;
810}
811
812/**
813 * vpif_mmap : It is used to map kernel space buffers into user spaces
814 * @filep: file pointer
815 * @vma: ptr to vm_area_struct
816 */
817static int vpif_mmap(struct file *filep, struct vm_area_struct *vma)
818{
819 /* Get the channel object and file handle object */
820 struct vpif_fh *fh = filep->private_data;
821 struct channel_obj *ch = fh->channel;
822 struct common_obj *common = &(ch->common[VPIF_VIDEO_INDEX]);
823 int ret;
824
825 vpif_dbg(2, debug, "vpif_mmap\n");
826
827 if (mutex_lock_interruptible(&common->lock))
828 return -ERESTARTSYS;
829 ret = vb2_mmap(&common->buffer_queue, vma);
830 mutex_unlock(&common->lock);
831 return ret;
832}
833
834/**
835 * vpif_poll: It is used for select/poll system call
836 * @filep: file pointer
837 * @wait: poll table to wait
838 */
839static unsigned int vpif_poll(struct file *filep, poll_table * wait)
840{
841 struct vpif_fh *fh = filep->private_data;
842 struct channel_obj *channel = fh->channel;
843 struct common_obj *common = &(channel->common[VPIF_VIDEO_INDEX]);
844 unsigned int res = 0;
845
846 vpif_dbg(2, debug, "vpif_poll\n");
847
848 if (common->started) {
849 mutex_lock(&common->lock);
850 res = vb2_poll(&common->buffer_queue, filep, wait);
851 mutex_unlock(&common->lock);
852 }
853 return res;
854}
855
856/**
857 * vpif_open : vpif open handler
858 * @filep: file ptr
859 *
860 * It creates object of file handle structure and stores it in private_data
861 * member of filepointer
862 */
863static int vpif_open(struct file *filep)
864{
865 struct vpif_capture_config *config = vpif_dev->platform_data;
866 struct video_device *vdev = video_devdata(filep);
867 struct common_obj *common;
868 struct video_obj *vid_ch;
869 struct channel_obj *ch;
870 struct vpif_fh *fh;
871 int i;
872
873 vpif_dbg(2, debug, "vpif_open\n");
874
875 ch = video_get_drvdata(vdev);
876
877 vid_ch = &ch->video;
878 common = &ch->common[VPIF_VIDEO_INDEX];
879
880 if (NULL == ch->curr_subdev_info) {
881 /**
882 * search through the sub device to see a registered
883 * sub device and make it as current sub device
884 */
885 for (i = 0; i < config->subdev_count; i++) {
886 if (vpif_obj.sd[i]) {
887 /* the sub device is registered */
888 ch->curr_subdev_info = &config->subdev_info[i];
889 /* make first input as the current input */
890 vid_ch->input_idx = 0;
891 break;
892 }
893 }
894 if (i == config->subdev_count) {
895 vpif_err("No sub device registered\n");
896 return -ENOENT;
897 }
898 }
899
900 /* Allocate memory for the file handle object */
901 fh = kzalloc(sizeof(struct vpif_fh), GFP_KERNEL);
902 if (NULL == fh) {
903 vpif_err("unable to allocate memory for file handle object\n");
904 return -ENOMEM;
905 }
906
907 if (mutex_lock_interruptible(&common->lock)) {
908 kfree(fh);
909 return -ERESTARTSYS;
910 }
911 /* store pointer to fh in private_data member of filep */
912 filep->private_data = fh;
913 fh->channel = ch;
914 fh->initialized = 0;
915 /* If decoder is not initialized. initialize it */
916 if (!ch->initialized) {
917 fh->initialized = 1;
918 ch->initialized = 1;
919 memset(&(ch->vpifparams), 0, sizeof(struct vpif_params));
920 }
921 /* Increment channel usrs counter */
922 ch->usrs++;
923 /* Set io_allowed member to false */
924 fh->io_allowed[VPIF_VIDEO_INDEX] = 0;
925 /* Initialize priority of this instance to default priority */
926 fh->prio = V4L2_PRIORITY_UNSET;
927 v4l2_prio_open(&ch->prio, &fh->prio);
928 mutex_unlock(&common->lock);
929 return 0;
930}
931
932/**
933 * vpif_release : function to clean up file close
934 * @filep: file pointer
935 *
936 * This function deletes buffer queue, frees the buffers and the vpif file
937 * handle
938 */
939static int vpif_release(struct file *filep)
940{
941 struct vpif_fh *fh = filep->private_data;
942 struct channel_obj *ch = fh->channel;
943 struct common_obj *common;
944
945 vpif_dbg(2, debug, "vpif_release\n");
946
947 common = &ch->common[VPIF_VIDEO_INDEX];
948
949 mutex_lock(&common->lock);
950 /* if this instance is doing IO */
951 if (fh->io_allowed[VPIF_VIDEO_INDEX]) {
952 /* Reset io_usrs member of channel object */
953 common->io_usrs = 0;
954 /* Disable channel as per its device type and channel id */
955 if (VPIF_CHANNEL0_VIDEO == ch->channel_id) {
956 enable_channel0(0);
957 channel0_intr_enable(0);
958 }
959 if ((VPIF_CHANNEL1_VIDEO == ch->channel_id) ||
960 (2 == common->started)) {
961 enable_channel1(0);
962 channel1_intr_enable(0);
963 }
964 common->started = 0;
965 /* Free buffers allocated */
966 vb2_queue_release(&common->buffer_queue);
967 vb2_dma_contig_cleanup_ctx(common->alloc_ctx);
968 }
969
970 /* Decrement channel usrs counter */
971 ch->usrs--;
972
973 /* Close the priority */
974 v4l2_prio_close(&ch->prio, fh->prio);
975
976 if (fh->initialized)
977 ch->initialized = 0;
978
979 mutex_unlock(&common->lock);
980 filep->private_data = NULL;
981 kfree(fh);
982 return 0;
983}
984
985/**
986 * vpif_reqbufs() - request buffer handler
987 * @file: file ptr
988 * @priv: file handle
989 * @reqbuf: request buffer structure ptr
990 */
991static int vpif_reqbufs(struct file *file, void *priv,
992 struct v4l2_requestbuffers *reqbuf)
993{
994 struct vpif_fh *fh = priv;
995 struct channel_obj *ch = fh->channel;
996 struct common_obj *common;
997 u8 index = 0;
998 struct vb2_queue *q;
999
1000 vpif_dbg(2, debug, "vpif_reqbufs\n");
1001
1002 /**
1003 * This file handle has not initialized the channel,
1004 * It is not allowed to do settings
1005 */
1006 if ((VPIF_CHANNEL0_VIDEO == ch->channel_id)
1007 || (VPIF_CHANNEL1_VIDEO == ch->channel_id)) {
1008 if (!fh->initialized) {
1009 vpif_dbg(1, debug, "Channel Busy\n");
1010 return -EBUSY;
1011 }
1012 }
1013
1014 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != reqbuf->type || !vpif_dev)
1015 return -EINVAL;
1016
1017 index = VPIF_VIDEO_INDEX;
1018
1019 common = &ch->common[index];
1020
1021 if (0 != common->io_usrs)
1022 return -EBUSY;
1023
1024 /* Initialize videobuf2 queue as per the buffer type */
1025 common->alloc_ctx = vb2_dma_contig_init_ctx(vpif_dev);
1026 if (!common->alloc_ctx) {
1027 vpif_err("Failed to get the context\n");
1028 return -EINVAL;
1029 }
1030 q = &common->buffer_queue;
1031 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1032 q->io_modes = VB2_MMAP | VB2_USERPTR;
1033 q->drv_priv = fh;
1034 q->ops = &video_qops;
1035 q->mem_ops = &vb2_dma_contig_memops;
1036 q->buf_struct_size = sizeof(struct vpif_cap_buffer);
1037
1038 vb2_queue_init(q);
1039
1040 /* Set io allowed member of file handle to TRUE */
1041 fh->io_allowed[index] = 1;
1042 /* Increment io usrs member of channel object to 1 */
1043 common->io_usrs = 1;
1044 /* Store type of memory requested in channel object */
1045 common->memory = reqbuf->memory;
1046 INIT_LIST_HEAD(&common->dma_queue);
1047
1048 /* Allocate buffers */
1049 return vb2_reqbufs(&common->buffer_queue, reqbuf);
1050}
1051
1052/**
1053 * vpif_querybuf() - query buffer handler
1054 * @file: file ptr
1055 * @priv: file handle
1056 * @buf: v4l2 buffer structure ptr
1057 */
1058static int vpif_querybuf(struct file *file, void *priv,
1059 struct v4l2_buffer *buf)
1060{
1061 struct vpif_fh *fh = priv;
1062 struct channel_obj *ch = fh->channel;
1063 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1064
1065 vpif_dbg(2, debug, "vpif_querybuf\n");
1066
1067 if (common->fmt.type != buf->type)
1068 return -EINVAL;
1069
1070 if (common->memory != V4L2_MEMORY_MMAP) {
1071 vpif_dbg(1, debug, "Invalid memory\n");
1072 return -EINVAL;
1073 }
1074
1075 return vb2_querybuf(&common->buffer_queue, buf);
1076}
1077
1078/**
1079 * vpif_qbuf() - query buffer handler
1080 * @file: file ptr
1081 * @priv: file handle
1082 * @buf: v4l2 buffer structure ptr
1083 */
1084static int vpif_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
1085{
1086
1087 struct vpif_fh *fh = priv;
1088 struct channel_obj *ch = fh->channel;
1089 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1090 struct v4l2_buffer tbuf = *buf;
1091
1092 vpif_dbg(2, debug, "vpif_qbuf\n");
1093
1094 if (common->fmt.type != tbuf.type) {
1095 vpif_err("invalid buffer type\n");
1096 return -EINVAL;
1097 }
1098
1099 if (!fh->io_allowed[VPIF_VIDEO_INDEX]) {
1100 vpif_err("fh io not allowed\n");
1101 return -EACCES;
1102 }
1103
1104 return vb2_qbuf(&common->buffer_queue, buf);
1105}
1106
1107/**
1108 * vpif_dqbuf() - query buffer handler
1109 * @file: file ptr
1110 * @priv: file handle
1111 * @buf: v4l2 buffer structure ptr
1112 */
1113static int vpif_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
1114{
1115 struct vpif_fh *fh = priv;
1116 struct channel_obj *ch = fh->channel;
1117 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1118
1119 vpif_dbg(2, debug, "vpif_dqbuf\n");
1120
1121 return vb2_dqbuf(&common->buffer_queue, buf,
1122 (file->f_flags & O_NONBLOCK));
1123}
1124
1125/**
1126 * vpif_streamon() - streamon handler
1127 * @file: file ptr
1128 * @priv: file handle
1129 * @buftype: v4l2 buffer type
1130 */
1131static int vpif_streamon(struct file *file, void *priv,
1132 enum v4l2_buf_type buftype)
1133{
1134
1135 struct vpif_fh *fh = priv;
1136 struct channel_obj *ch = fh->channel;
1137 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1138 struct channel_obj *oth_ch = vpif_obj.dev[!ch->channel_id];
1139 struct vpif_params *vpif;
1140 int ret = 0;
1141
1142 vpif_dbg(2, debug, "vpif_streamon\n");
1143
1144 vpif = &ch->vpifparams;
1145
1146 if (buftype != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1147 vpif_dbg(1, debug, "buffer type not supported\n");
1148 return -EINVAL;
1149 }
1150
1151 /* If file handle is not allowed IO, return error */
1152 if (!fh->io_allowed[VPIF_VIDEO_INDEX]) {
1153 vpif_dbg(1, debug, "io not allowed\n");
1154 return -EACCES;
1155 }
1156
1157 /* If Streaming is already started, return error */
1158 if (common->started) {
1159 vpif_dbg(1, debug, "channel->started\n");
1160 return -EBUSY;
1161 }
1162
1163 if ((ch->channel_id == VPIF_CHANNEL0_VIDEO &&
1164 oth_ch->common[VPIF_VIDEO_INDEX].started &&
1165 vpif->std_info.ycmux_mode == 0) ||
1166 ((ch->channel_id == VPIF_CHANNEL1_VIDEO) &&
1167 (2 == oth_ch->common[VPIF_VIDEO_INDEX].started))) {
1168 vpif_dbg(1, debug, "other channel is being used\n");
1169 return -EBUSY;
1170 }
1171
1172 ret = vpif_check_format(ch, &common->fmt.fmt.pix, 0);
1173 if (ret)
1174 return ret;
1175
1176 /* Enable streamon on the sub device */
1177 ret = v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], video,
1178 s_stream, 1);
1179
1180 if (ret && (ret != -ENOIOCTLCMD)) {
1181 vpif_dbg(1, debug, "stream on failed in subdev\n");
1182 return ret;
1183 }
1184
1185 /* Call vb2_streamon to start streaming in videobuf2 */
1186 ret = vb2_streamon(&common->buffer_queue, buftype);
1187 if (ret) {
1188 vpif_dbg(1, debug, "vb2_streamon\n");
1189 return ret;
1190 }
1191
1192 return ret;
1193}
1194
1195/**
1196 * vpif_streamoff() - streamoff handler
1197 * @file: file ptr
1198 * @priv: file handle
1199 * @buftype: v4l2 buffer type
1200 */
1201static int vpif_streamoff(struct file *file, void *priv,
1202 enum v4l2_buf_type buftype)
1203{
1204
1205 struct vpif_fh *fh = priv;
1206 struct channel_obj *ch = fh->channel;
1207 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1208 int ret;
1209
1210 vpif_dbg(2, debug, "vpif_streamoff\n");
1211
1212 if (buftype != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1213 vpif_dbg(1, debug, "buffer type not supported\n");
1214 return -EINVAL;
1215 }
1216
1217 /* If io is allowed for this file handle, return error */
1218 if (!fh->io_allowed[VPIF_VIDEO_INDEX]) {
1219 vpif_dbg(1, debug, "io not allowed\n");
1220 return -EACCES;
1221 }
1222
1223 /* If streaming is not started, return error */
1224 if (!common->started) {
1225 vpif_dbg(1, debug, "channel->started\n");
1226 return -EINVAL;
1227 }
1228
1229 /* disable channel */
1230 if (VPIF_CHANNEL0_VIDEO == ch->channel_id) {
1231 enable_channel0(0);
1232 channel0_intr_enable(0);
1233 } else {
1234 enable_channel1(0);
1235 channel1_intr_enable(0);
1236 }
1237
1238 common->started = 0;
1239
1240 ret = v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], video,
1241 s_stream, 0);
1242
1243 if (ret && (ret != -ENOIOCTLCMD))
1244 vpif_dbg(1, debug, "stream off failed in subdev\n");
1245
1246 return vb2_streamoff(&common->buffer_queue, buftype);
1247}
1248
1249/**
1250 * vpif_map_sub_device_to_input() - Maps sub device to input
1251 * @ch - ptr to channel
1252 * @config - ptr to capture configuration
1253 * @input_index - Given input index from application
1254 * @sub_device_index - index into sd table
1255 *
1256 * lookup the sub device information for a given input index.
1257 * we report all the inputs to application. inputs table also
1258 * has sub device name for the each input
1259 */
1260static struct vpif_subdev_info *vpif_map_sub_device_to_input(
1261 struct channel_obj *ch,
1262 struct vpif_capture_config *vpif_cfg,
1263 int input_index,
1264 int *sub_device_index)
1265{
1266 struct vpif_capture_chan_config *chan_cfg;
1267 struct vpif_subdev_info *subdev_info = NULL;
1268 const char *subdev_name = NULL;
1269 int i;
1270
1271 vpif_dbg(2, debug, "vpif_map_sub_device_to_input\n");
1272
1273 chan_cfg = &vpif_cfg->chan_config[ch->channel_id];
1274
1275 /**
1276 * search through the inputs to find the sub device supporting
1277 * the input
1278 */
1279 for (i = 0; i < chan_cfg->input_count; i++) {
1280 /* For each sub device, loop through input */
1281 if (i == input_index) {
1282 subdev_name = chan_cfg->inputs[i].subdev_name;
1283 break;
1284 }
1285 }
1286
1287 /* if reached maximum. return null */
1288 if (i == chan_cfg->input_count || (NULL == subdev_name))
1289 return subdev_info;
1290
1291 /* loop through the sub device list to get the sub device info */
1292 for (i = 0; i < vpif_cfg->subdev_count; i++) {
1293 subdev_info = &vpif_cfg->subdev_info[i];
1294 if (!strcmp(subdev_info->name, subdev_name))
1295 break;
1296 }
1297
1298 if (i == vpif_cfg->subdev_count)
1299 return subdev_info;
1300
1301 /* check if the sub device is registered */
1302 if (NULL == vpif_obj.sd[i])
1303 return NULL;
1304
1305 *sub_device_index = i;
1306 return subdev_info;
1307}
1308
1309/**
1310 * vpif_querystd() - querystd handler
1311 * @file: file ptr
1312 * @priv: file handle
1313 * @std_id: ptr to std id
1314 *
1315 * This function is called to detect standard at the selected input
1316 */
1317static int vpif_querystd(struct file *file, void *priv, v4l2_std_id *std_id)
1318{
1319 struct vpif_fh *fh = priv;
1320 struct channel_obj *ch = fh->channel;
1321 int ret = 0;
1322
1323 vpif_dbg(2, debug, "vpif_querystd\n");
1324
1325 /* Call querystd function of decoder device */
1326 ret = v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], video,
1327 querystd, std_id);
1328 if (ret < 0)
1329 vpif_dbg(1, debug, "Failed to set standard for sub devices\n");
1330
1331 return ret;
1332}
1333
1334/**
1335 * vpif_g_std() - get STD handler
1336 * @file: file ptr
1337 * @priv: file handle
1338 * @std_id: ptr to std id
1339 */
1340static int vpif_g_std(struct file *file, void *priv, v4l2_std_id *std)
1341{
1342 struct vpif_fh *fh = priv;
1343 struct channel_obj *ch = fh->channel;
1344
1345 vpif_dbg(2, debug, "vpif_g_std\n");
1346
1347 *std = ch->video.stdid;
1348 return 0;
1349}
1350
1351/**
1352 * vpif_s_std() - set STD handler
1353 * @file: file ptr
1354 * @priv: file handle
1355 * @std_id: ptr to std id
1356 */
1357static int vpif_s_std(struct file *file, void *priv, v4l2_std_id *std_id)
1358{
1359 struct vpif_fh *fh = priv;
1360 struct channel_obj *ch = fh->channel;
1361 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1362 int ret = 0;
1363
1364 vpif_dbg(2, debug, "vpif_s_std\n");
1365
1366 if (common->started) {
1367 vpif_err("streaming in progress\n");
1368 return -EBUSY;
1369 }
1370
1371 if ((VPIF_CHANNEL0_VIDEO == ch->channel_id) ||
1372 (VPIF_CHANNEL1_VIDEO == ch->channel_id)) {
1373 if (!fh->initialized) {
1374 vpif_dbg(1, debug, "Channel Busy\n");
1375 return -EBUSY;
1376 }
1377 }
1378
1379 ret = v4l2_prio_check(&ch->prio, fh->prio);
1380 if (0 != ret)
1381 return ret;
1382
1383 fh->initialized = 1;
1384
1385 /* Call encoder subdevice function to set the standard */
1386 ch->video.stdid = *std_id;
1387 ch->video.dv_preset = V4L2_DV_INVALID;
1388 memset(&ch->video.bt_timings, 0, sizeof(ch->video.bt_timings));
1389
1390 /* Get the information about the standard */
1391 if (vpif_update_std_info(ch)) {
1392 vpif_err("Error getting the standard info\n");
1393 return -EINVAL;
1394 }
1395
1396 /* Configure the default format information */
1397 vpif_config_format(ch);
1398
1399 /* set standard in the sub device */
1400 ret = v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], core,
1401 s_std, *std_id);
1402 if (ret < 0)
1403 vpif_dbg(1, debug, "Failed to set standard for sub devices\n");
1404 return ret;
1405}
1406
1407/**
1408 * vpif_enum_input() - ENUMINPUT handler
1409 * @file: file ptr
1410 * @priv: file handle
1411 * @input: ptr to input structure
1412 */
1413static int vpif_enum_input(struct file *file, void *priv,
1414 struct v4l2_input *input)
1415{
1416
1417 struct vpif_capture_config *config = vpif_dev->platform_data;
1418 struct vpif_capture_chan_config *chan_cfg;
1419 struct vpif_fh *fh = priv;
1420 struct channel_obj *ch = fh->channel;
1421
1422 chan_cfg = &config->chan_config[ch->channel_id];
1423
1424 if (input->index >= chan_cfg->input_count) {
1425 vpif_dbg(1, debug, "Invalid input index\n");
1426 return -EINVAL;
1427 }
1428
1429 memcpy(input, &chan_cfg->inputs[input->index].input,
1430 sizeof(*input));
1431 return 0;
1432}
1433
1434/**
1435 * vpif_g_input() - Get INPUT handler
1436 * @file: file ptr
1437 * @priv: file handle
1438 * @index: ptr to input index
1439 */
1440static int vpif_g_input(struct file *file, void *priv, unsigned int *index)
1441{
1442 struct vpif_fh *fh = priv;
1443 struct channel_obj *ch = fh->channel;
1444 struct video_obj *vid_ch = &ch->video;
1445
1446 *index = vid_ch->input_idx;
1447
1448 return 0;
1449}
1450
1451/**
1452 * vpif_s_input() - Set INPUT handler
1453 * @file: file ptr
1454 * @priv: file handle
1455 * @index: input index
1456 */
1457static int vpif_s_input(struct file *file, void *priv, unsigned int index)
1458{
1459 struct vpif_capture_config *config = vpif_dev->platform_data;
1460 struct vpif_capture_chan_config *chan_cfg;
1461 struct vpif_fh *fh = priv;
1462 struct channel_obj *ch = fh->channel;
1463 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1464 struct video_obj *vid_ch = &ch->video;
1465 struct vpif_subdev_info *subdev_info;
1466 int ret = 0, sd_index = 0;
1467 u32 input = 0, output = 0;
1468
1469 chan_cfg = &config->chan_config[ch->channel_id];
1470
1471 if (common->started) {
1472 vpif_err("Streaming in progress\n");
1473 return -EBUSY;
1474 }
1475
1476 if ((VPIF_CHANNEL0_VIDEO == ch->channel_id) ||
1477 (VPIF_CHANNEL1_VIDEO == ch->channel_id)) {
1478 if (!fh->initialized) {
1479 vpif_dbg(1, debug, "Channel Busy\n");
1480 return -EBUSY;
1481 }
1482 }
1483
1484 ret = v4l2_prio_check(&ch->prio, fh->prio);
1485 if (0 != ret)
1486 return ret;
1487
1488 fh->initialized = 1;
1489 subdev_info = vpif_map_sub_device_to_input(ch, config, index,
1490 &sd_index);
1491 if (NULL == subdev_info) {
1492 vpif_dbg(1, debug,
1493 "couldn't lookup sub device for the input index\n");
1494 return -EINVAL;
1495 }
1496
1497 /* first setup input path from sub device to vpif */
1498 if (config->setup_input_path) {
1499 ret = config->setup_input_path(ch->channel_id,
1500 subdev_info->name);
1501 if (ret < 0) {
1502 vpif_dbg(1, debug, "couldn't setup input path for the"
1503 " sub device %s, for input index %d\n",
1504 subdev_info->name, index);
1505 return ret;
1506 }
1507 }
1508
1509 if (subdev_info->can_route) {
1510 input = subdev_info->input;
1511 output = subdev_info->output;
1512 ret = v4l2_subdev_call(vpif_obj.sd[sd_index], video, s_routing,
1513 input, output, 0);
1514 if (ret < 0) {
1515 vpif_dbg(1, debug, "Failed to set input\n");
1516 return ret;
1517 }
1518 }
1519 vid_ch->input_idx = index;
1520 ch->curr_subdev_info = subdev_info;
1521 ch->curr_sd_index = sd_index;
1522 /* copy interface parameters to vpif */
1523 ch->vpifparams.iface = subdev_info->vpif_if;
1524
1525 /* update tvnorms from the sub device input info */
1526 ch->video_dev->tvnorms = chan_cfg->inputs[index].input.std;
1527 return ret;
1528}
1529
1530/**
1531 * vpif_enum_fmt_vid_cap() - ENUM_FMT handler
1532 * @file: file ptr
1533 * @priv: file handle
1534 * @index: input index
1535 */
1536static int vpif_enum_fmt_vid_cap(struct file *file, void *priv,
1537 struct v4l2_fmtdesc *fmt)
1538{
1539 struct vpif_fh *fh = priv;
1540 struct channel_obj *ch = fh->channel;
1541
1542 if (fmt->index != 0) {
1543 vpif_dbg(1, debug, "Invalid format index\n");
1544 return -EINVAL;
1545 }
1546
1547 /* Fill in the information about format */
1548 if (ch->vpifparams.iface.if_type == VPIF_IF_RAW_BAYER) {
1549 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1550 strcpy(fmt->description, "Raw Mode -Bayer Pattern GrRBGb");
1551 fmt->pixelformat = V4L2_PIX_FMT_SBGGR8;
1552 } else {
1553 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1554 strcpy(fmt->description, "YCbCr4:2:2 YC Planar");
1555 fmt->pixelformat = V4L2_PIX_FMT_YUV422P;
1556 }
1557 return 0;
1558}
1559
1560/**
1561 * vpif_try_fmt_vid_cap() - TRY_FMT handler
1562 * @file: file ptr
1563 * @priv: file handle
1564 * @fmt: ptr to v4l2 format structure
1565 */
1566static int vpif_try_fmt_vid_cap(struct file *file, void *priv,
1567 struct v4l2_format *fmt)
1568{
1569 struct vpif_fh *fh = priv;
1570 struct channel_obj *ch = fh->channel;
1571 struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
1572
1573 return vpif_check_format(ch, pixfmt, 1);
1574}
1575
1576
1577/**
1578 * vpif_g_fmt_vid_cap() - Set INPUT handler
1579 * @file: file ptr
1580 * @priv: file handle
1581 * @fmt: ptr to v4l2 format structure
1582 */
1583static int vpif_g_fmt_vid_cap(struct file *file, void *priv,
1584 struct v4l2_format *fmt)
1585{
1586 struct vpif_fh *fh = priv;
1587 struct channel_obj *ch = fh->channel;
1588 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1589
1590 /* Check the validity of the buffer type */
1591 if (common->fmt.type != fmt->type)
1592 return -EINVAL;
1593
1594 /* Fill in the information about format */
1595 *fmt = common->fmt;
1596 return 0;
1597}
1598
1599/**
1600 * vpif_s_fmt_vid_cap() - Set FMT handler
1601 * @file: file ptr
1602 * @priv: file handle
1603 * @fmt: ptr to v4l2 format structure
1604 */
1605static int vpif_s_fmt_vid_cap(struct file *file, void *priv,
1606 struct v4l2_format *fmt)
1607{
1608 struct vpif_fh *fh = priv;
1609 struct channel_obj *ch = fh->channel;
1610 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1611 struct v4l2_pix_format *pixfmt;
1612 int ret = 0;
1613
1614 vpif_dbg(2, debug, "%s\n", __func__);
1615
1616 /* If streaming is started, return error */
1617 if (common->started) {
1618 vpif_dbg(1, debug, "Streaming is started\n");
1619 return -EBUSY;
1620 }
1621
1622 if ((VPIF_CHANNEL0_VIDEO == ch->channel_id) ||
1623 (VPIF_CHANNEL1_VIDEO == ch->channel_id)) {
1624 if (!fh->initialized) {
1625 vpif_dbg(1, debug, "Channel Busy\n");
1626 return -EBUSY;
1627 }
1628 }
1629
1630 ret = v4l2_prio_check(&ch->prio, fh->prio);
1631 if (0 != ret)
1632 return ret;
1633
1634 fh->initialized = 1;
1635
1636 pixfmt = &fmt->fmt.pix;
1637 /* Check for valid field format */
1638 ret = vpif_check_format(ch, pixfmt, 0);
1639
1640 if (ret)
1641 return ret;
1642 /* store the format in the channel object */
1643 common->fmt = *fmt;
1644 return 0;
1645}
1646
1647/**
1648 * vpif_querycap() - QUERYCAP handler
1649 * @file: file ptr
1650 * @priv: file handle
1651 * @cap: ptr to v4l2_capability structure
1652 */
1653static int vpif_querycap(struct file *file, void *priv,
1654 struct v4l2_capability *cap)
1655{
1656 struct vpif_capture_config *config = vpif_dev->platform_data;
1657
1658 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
1659 strlcpy(cap->driver, "vpif capture", sizeof(cap->driver));
1660 strlcpy(cap->bus_info, "VPIF Platform", sizeof(cap->bus_info));
1661 strlcpy(cap->card, config->card_name, sizeof(cap->card));
1662
1663 return 0;
1664}
1665
1666/**
1667 * vpif_g_priority() - get priority handler
1668 * @file: file ptr
1669 * @priv: file handle
1670 * @prio: ptr to v4l2_priority structure
1671 */
1672static int vpif_g_priority(struct file *file, void *priv,
1673 enum v4l2_priority *prio)
1674{
1675 struct vpif_fh *fh = priv;
1676 struct channel_obj *ch = fh->channel;
1677
1678 *prio = v4l2_prio_max(&ch->prio);
1679
1680 return 0;
1681}
1682
1683/**
1684 * vpif_s_priority() - set priority handler
1685 * @file: file ptr
1686 * @priv: file handle
1687 * @prio: ptr to v4l2_priority structure
1688 */
1689static int vpif_s_priority(struct file *file, void *priv, enum v4l2_priority p)
1690{
1691 struct vpif_fh *fh = priv;
1692 struct channel_obj *ch = fh->channel;
1693
1694 return v4l2_prio_change(&ch->prio, &fh->prio, p);
1695}
1696
1697/**
1698 * vpif_cropcap() - cropcap handler
1699 * @file: file ptr
1700 * @priv: file handle
1701 * @crop: ptr to v4l2_cropcap structure
1702 */
1703static int vpif_cropcap(struct file *file, void *priv,
1704 struct v4l2_cropcap *crop)
1705{
1706 struct vpif_fh *fh = priv;
1707 struct channel_obj *ch = fh->channel;
1708 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1709
1710 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != crop->type)
1711 return -EINVAL;
1712
1713 crop->bounds.left = 0;
1714 crop->bounds.top = 0;
1715 crop->bounds.height = common->height;
1716 crop->bounds.width = common->width;
1717 crop->defrect = crop->bounds;
1718 return 0;
1719}
1720
1721/**
1722 * vpif_enum_dv_presets() - ENUM_DV_PRESETS handler
1723 * @file: file ptr
1724 * @priv: file handle
1725 * @preset: input preset
1726 */
1727static int vpif_enum_dv_presets(struct file *file, void *priv,
1728 struct v4l2_dv_enum_preset *preset)
1729{
1730 struct vpif_fh *fh = priv;
1731 struct channel_obj *ch = fh->channel;
1732
1733 return v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index],
1734 video, enum_dv_presets, preset);
1735}
1736
1737/**
1738 * vpif_query_dv_presets() - QUERY_DV_PRESET handler
1739 * @file: file ptr
1740 * @priv: file handle
1741 * @preset: input preset
1742 */
1743static int vpif_query_dv_preset(struct file *file, void *priv,
1744 struct v4l2_dv_preset *preset)
1745{
1746 struct vpif_fh *fh = priv;
1747 struct channel_obj *ch = fh->channel;
1748
1749 return v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index],
1750 video, query_dv_preset, preset);
1751}
1752/**
1753 * vpif_s_dv_presets() - S_DV_PRESETS handler
1754 * @file: file ptr
1755 * @priv: file handle
1756 * @preset: input preset
1757 */
1758static int vpif_s_dv_preset(struct file *file, void *priv,
1759 struct v4l2_dv_preset *preset)
1760{
1761 struct vpif_fh *fh = priv;
1762 struct channel_obj *ch = fh->channel;
1763 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1764 int ret = 0;
1765
1766 if (common->started) {
1767 vpif_dbg(1, debug, "streaming in progress\n");
1768 return -EBUSY;
1769 }
1770
1771 if ((VPIF_CHANNEL0_VIDEO == ch->channel_id) ||
1772 (VPIF_CHANNEL1_VIDEO == ch->channel_id)) {
1773 if (!fh->initialized) {
1774 vpif_dbg(1, debug, "Channel Busy\n");
1775 return -EBUSY;
1776 }
1777 }
1778
1779 ret = v4l2_prio_check(&ch->prio, fh->prio);
1780 if (ret)
1781 return ret;
1782
1783 fh->initialized = 1;
1784
1785 /* Call encoder subdevice function to set the standard */
1786 if (mutex_lock_interruptible(&common->lock))
1787 return -ERESTARTSYS;
1788
1789 ch->video.dv_preset = preset->preset;
1790 ch->video.stdid = V4L2_STD_UNKNOWN;
1791 memset(&ch->video.bt_timings, 0, sizeof(ch->video.bt_timings));
1792
1793 /* Get the information about the standard */
1794 if (vpif_update_std_info(ch)) {
1795 vpif_dbg(1, debug, "Error getting the standard info\n");
1796 ret = -EINVAL;
1797 } else {
1798 /* Configure the default format information */
1799 vpif_config_format(ch);
1800
1801 ret = v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index],
1802 video, s_dv_preset, preset);
1803 }
1804
1805 mutex_unlock(&common->lock);
1806
1807 return ret;
1808}
1809/**
1810 * vpif_g_dv_presets() - G_DV_PRESETS handler
1811 * @file: file ptr
1812 * @priv: file handle
1813 * @preset: input preset
1814 */
1815static int vpif_g_dv_preset(struct file *file, void *priv,
1816 struct v4l2_dv_preset *preset)
1817{
1818 struct vpif_fh *fh = priv;
1819 struct channel_obj *ch = fh->channel;
1820
1821 preset->preset = ch->video.dv_preset;
1822
1823 return 0;
1824}
1825
1826/**
1827 * vpif_s_dv_timings() - S_DV_TIMINGS handler
1828 * @file: file ptr
1829 * @priv: file handle
1830 * @timings: digital video timings
1831 */
1832static int vpif_s_dv_timings(struct file *file, void *priv,
1833 struct v4l2_dv_timings *timings)
1834{
1835 struct vpif_fh *fh = priv;
1836 struct channel_obj *ch = fh->channel;
1837 struct vpif_params *vpifparams = &ch->vpifparams;
1838 struct vpif_channel_config_params *std_info = &vpifparams->std_info;
1839 struct video_obj *vid_ch = &ch->video;
1840 struct v4l2_bt_timings *bt = &vid_ch->bt_timings;
1841 int ret;
1842
1843 if (timings->type != V4L2_DV_BT_656_1120) {
1844 vpif_dbg(2, debug, "Timing type not defined\n");
1845 return -EINVAL;
1846 }
1847
1848 /* Configure subdevice timings, if any */
1849 ret = v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index],
1850 video, s_dv_timings, timings);
1851 if (ret == -ENOIOCTLCMD) {
1852 vpif_dbg(2, debug, "Custom DV timings not supported by "
1853 "subdevice\n");
1854 return -EINVAL;
1855 }
1856 if (ret < 0) {
1857 vpif_dbg(2, debug, "Error setting custom DV timings\n");
1858 return ret;
1859 }
1860
1861 if (!(timings->bt.width && timings->bt.height &&
1862 (timings->bt.hbackporch ||
1863 timings->bt.hfrontporch ||
1864 timings->bt.hsync) &&
1865 timings->bt.vfrontporch &&
1866 (timings->bt.vbackporch ||
1867 timings->bt.vsync))) {
1868 vpif_dbg(2, debug, "Timings for width, height, "
1869 "horizontal back porch, horizontal sync, "
1870 "horizontal front porch, vertical back porch, "
1871 "vertical sync and vertical back porch "
1872 "must be defined\n");
1873 return -EINVAL;
1874 }
1875
1876 *bt = timings->bt;
1877
1878 /* Configure video port timings */
1879
1880 std_info->eav2sav = bt->hbackporch + bt->hfrontporch +
1881 bt->hsync - 8;
1882 std_info->sav2eav = bt->width;
1883
1884 std_info->l1 = 1;
1885 std_info->l3 = bt->vsync + bt->vbackporch + 1;
1886
1887 if (bt->interlaced) {
1888 if (bt->il_vbackporch || bt->il_vfrontporch || bt->il_vsync) {
1889 std_info->vsize = bt->height * 2 +
1890 bt->vfrontporch + bt->vsync + bt->vbackporch +
1891 bt->il_vfrontporch + bt->il_vsync +
1892 bt->il_vbackporch;
1893 std_info->l5 = std_info->vsize/2 -
1894 (bt->vfrontporch - 1);
1895 std_info->l7 = std_info->vsize/2 + 1;
1896 std_info->l9 = std_info->l7 + bt->il_vsync +
1897 bt->il_vbackporch + 1;
1898 std_info->l11 = std_info->vsize -
1899 (bt->il_vfrontporch - 1);
1900 } else {
1901 vpif_dbg(2, debug, "Required timing values for "
1902 "interlaced BT format missing\n");
1903 return -EINVAL;
1904 }
1905 } else {
1906 std_info->vsize = bt->height + bt->vfrontporch +
1907 bt->vsync + bt->vbackporch;
1908 std_info->l5 = std_info->vsize - (bt->vfrontporch - 1);
1909 }
1910 strncpy(std_info->name, "Custom timings BT656/1120", VPIF_MAX_NAME);
1911 std_info->width = bt->width;
1912 std_info->height = bt->height;
1913 std_info->frm_fmt = bt->interlaced ? 0 : 1;
1914 std_info->ycmux_mode = 0;
1915 std_info->capture_format = 0;
1916 std_info->vbi_supported = 0;
1917 std_info->hd_sd = 1;
1918 std_info->stdid = 0;
1919 std_info->dv_preset = V4L2_DV_INVALID;
1920
1921 vid_ch->stdid = 0;
1922 vid_ch->dv_preset = V4L2_DV_INVALID;
1923 return 0;
1924}
1925
1926/**
1927 * vpif_g_dv_timings() - G_DV_TIMINGS handler
1928 * @file: file ptr
1929 * @priv: file handle
1930 * @timings: digital video timings
1931 */
1932static int vpif_g_dv_timings(struct file *file, void *priv,
1933 struct v4l2_dv_timings *timings)
1934{
1935 struct vpif_fh *fh = priv;
1936 struct channel_obj *ch = fh->channel;
1937 struct video_obj *vid_ch = &ch->video;
1938 struct v4l2_bt_timings *bt = &vid_ch->bt_timings;
1939
1940 timings->bt = *bt;
1941
1942 return 0;
1943}
1944
1945/*
1946 * vpif_g_chip_ident() - Identify the chip
1947 * @file: file ptr
1948 * @priv: file handle
1949 * @chip: chip identity
1950 *
1951 * Returns zero or -EINVAL if read operations fails.
1952 */
1953static int vpif_g_chip_ident(struct file *file, void *priv,
1954 struct v4l2_dbg_chip_ident *chip)
1955{
1956 chip->ident = V4L2_IDENT_NONE;
1957 chip->revision = 0;
1958 if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER &&
1959 chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR) {
1960 vpif_dbg(2, debug, "match_type is invalid.\n");
1961 return -EINVAL;
1962 }
1963
1964 return v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 0, core,
1965 g_chip_ident, chip);
1966}
1967
1968#ifdef CONFIG_VIDEO_ADV_DEBUG
1969/*
1970 * vpif_dbg_g_register() - Read register
1971 * @file: file ptr
1972 * @priv: file handle
1973 * @reg: register to be read
1974 *
1975 * Debugging only
1976 * Returns zero or -EINVAL if read operations fails.
1977 */
1978static int vpif_dbg_g_register(struct file *file, void *priv,
1979 struct v4l2_dbg_register *reg){
1980 struct vpif_fh *fh = priv;
1981 struct channel_obj *ch = fh->channel;
1982
1983 return v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], core,
1984 g_register, reg);
1985}
1986
1987/*
1988 * vpif_dbg_s_register() - Write to register
1989 * @file: file ptr
1990 * @priv: file handle
1991 * @reg: register to be modified
1992 *
1993 * Debugging only
1994 * Returns zero or -EINVAL if write operations fails.
1995 */
1996static int vpif_dbg_s_register(struct file *file, void *priv,
1997 struct v4l2_dbg_register *reg){
1998 struct vpif_fh *fh = priv;
1999 struct channel_obj *ch = fh->channel;
2000
2001 return v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], core,
2002 s_register, reg);
2003}
2004#endif
2005
2006/*
2007 * vpif_log_status() - Status information
2008 * @file: file ptr
2009 * @priv: file handle
2010 *
2011 * Returns zero.
2012 */
2013static int vpif_log_status(struct file *filep, void *priv)
2014{
2015 /* status for sub devices */
2016 v4l2_device_call_all(&vpif_obj.v4l2_dev, 0, core, log_status);
2017
2018 return 0;
2019}
2020
2021/* vpif capture ioctl operations */
2022static const struct v4l2_ioctl_ops vpif_ioctl_ops = {
2023 .vidioc_querycap = vpif_querycap,
2024 .vidioc_g_priority = vpif_g_priority,
2025 .vidioc_s_priority = vpif_s_priority,
2026 .vidioc_enum_fmt_vid_cap = vpif_enum_fmt_vid_cap,
2027 .vidioc_g_fmt_vid_cap = vpif_g_fmt_vid_cap,
2028 .vidioc_s_fmt_vid_cap = vpif_s_fmt_vid_cap,
2029 .vidioc_try_fmt_vid_cap = vpif_try_fmt_vid_cap,
2030 .vidioc_enum_input = vpif_enum_input,
2031 .vidioc_s_input = vpif_s_input,
2032 .vidioc_g_input = vpif_g_input,
2033 .vidioc_reqbufs = vpif_reqbufs,
2034 .vidioc_querybuf = vpif_querybuf,
2035 .vidioc_querystd = vpif_querystd,
2036 .vidioc_s_std = vpif_s_std,
2037 .vidioc_g_std = vpif_g_std,
2038 .vidioc_qbuf = vpif_qbuf,
2039 .vidioc_dqbuf = vpif_dqbuf,
2040 .vidioc_streamon = vpif_streamon,
2041 .vidioc_streamoff = vpif_streamoff,
2042 .vidioc_cropcap = vpif_cropcap,
2043 .vidioc_enum_dv_presets = vpif_enum_dv_presets,
2044 .vidioc_s_dv_preset = vpif_s_dv_preset,
2045 .vidioc_g_dv_preset = vpif_g_dv_preset,
2046 .vidioc_query_dv_preset = vpif_query_dv_preset,
2047 .vidioc_s_dv_timings = vpif_s_dv_timings,
2048 .vidioc_g_dv_timings = vpif_g_dv_timings,
2049 .vidioc_g_chip_ident = vpif_g_chip_ident,
2050#ifdef CONFIG_VIDEO_ADV_DEBUG
2051 .vidioc_g_register = vpif_dbg_g_register,
2052 .vidioc_s_register = vpif_dbg_s_register,
2053#endif
2054 .vidioc_log_status = vpif_log_status,
2055};
2056
2057/* vpif file operations */
2058static struct v4l2_file_operations vpif_fops = {
2059 .owner = THIS_MODULE,
2060 .open = vpif_open,
2061 .release = vpif_release,
2062 .unlocked_ioctl = video_ioctl2,
2063 .mmap = vpif_mmap,
2064 .poll = vpif_poll
2065};
2066
2067/* vpif video template */
2068static struct video_device vpif_video_template = {
2069 .name = "vpif",
2070 .fops = &vpif_fops,
2071 .minor = -1,
2072 .ioctl_ops = &vpif_ioctl_ops,
2073};
2074
2075/**
2076 * initialize_vpif() - Initialize vpif data structures
2077 *
2078 * Allocate memory for data structures and initialize them
2079 */
2080static int initialize_vpif(void)
2081{
2082 int err = 0, i, j;
2083 int free_channel_objects_index;
2084
2085 /* Default number of buffers should be 3 */
2086 if ((ch0_numbuffers > 0) &&
2087 (ch0_numbuffers < config_params.min_numbuffers))
2088 ch0_numbuffers = config_params.min_numbuffers;
2089 if ((ch1_numbuffers > 0) &&
2090 (ch1_numbuffers < config_params.min_numbuffers))
2091 ch1_numbuffers = config_params.min_numbuffers;
2092
2093 /* Set buffer size to min buffers size if it is invalid */
2094 if (ch0_bufsize < config_params.min_bufsize[VPIF_CHANNEL0_VIDEO])
2095 ch0_bufsize =
2096 config_params.min_bufsize[VPIF_CHANNEL0_VIDEO];
2097 if (ch1_bufsize < config_params.min_bufsize[VPIF_CHANNEL1_VIDEO])
2098 ch1_bufsize =
2099 config_params.min_bufsize[VPIF_CHANNEL1_VIDEO];
2100
2101 config_params.numbuffers[VPIF_CHANNEL0_VIDEO] = ch0_numbuffers;
2102 config_params.numbuffers[VPIF_CHANNEL1_VIDEO] = ch1_numbuffers;
2103 if (ch0_numbuffers) {
2104 config_params.channel_bufsize[VPIF_CHANNEL0_VIDEO]
2105 = ch0_bufsize;
2106 }
2107 if (ch1_numbuffers) {
2108 config_params.channel_bufsize[VPIF_CHANNEL1_VIDEO]
2109 = ch1_bufsize;
2110 }
2111
2112 /* Allocate memory for six channel objects */
2113 for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {
2114 vpif_obj.dev[i] =
2115 kzalloc(sizeof(*vpif_obj.dev[i]), GFP_KERNEL);
2116 /* If memory allocation fails, return error */
2117 if (!vpif_obj.dev[i]) {
2118 free_channel_objects_index = i;
2119 err = -ENOMEM;
2120 goto vpif_init_free_channel_objects;
2121 }
2122 }
2123 return 0;
2124
2125vpif_init_free_channel_objects:
2126 for (j = 0; j < free_channel_objects_index; j++)
2127 kfree(vpif_obj.dev[j]);
2128 return err;
2129}
2130
2131/**
2132 * vpif_probe : This function probes the vpif capture driver
2133 * @pdev: platform device pointer
2134 *
2135 * This creates device entries by register itself to the V4L2 driver and
2136 * initializes fields of each channel objects
2137 */
2138static __init int vpif_probe(struct platform_device *pdev)
2139{
2140 struct vpif_subdev_info *subdevdata;
2141 struct vpif_capture_config *config;
2142 int i, j, k, m, q, err;
2143 struct i2c_adapter *i2c_adap;
2144 struct channel_obj *ch;
2145 struct common_obj *common;
2146 struct video_device *vfd;
2147 struct resource *res;
2148 int subdev_count;
2149 size_t size;
2150
2151 vpif_dev = &pdev->dev;
2152
2153 err = initialize_vpif();
2154 if (err) {
2155 v4l2_err(vpif_dev->driver, "Error initializing vpif\n");
2156 return err;
2157 }
2158
2159 err = v4l2_device_register(vpif_dev, &vpif_obj.v4l2_dev);
2160 if (err) {
2161 v4l2_err(vpif_dev->driver, "Error registering v4l2 device\n");
2162 return err;
2163 }
2164
2165 k = 0;
2166 while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, k))) {
2167 for (i = res->start; i <= res->end; i++) {
2168 if (request_irq(i, vpif_channel_isr, IRQF_SHARED,
2169 "VPIF_Capture",
2170 (void *)(&vpif_obj.dev[k]->channel_id))) {
2171 err = -EBUSY;
2172 i--;
2173 goto vpif_int_err;
2174 }
2175 }
2176 k++;
2177 }
2178
2179 for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {
2180 /* Get the pointer to the channel object */
2181 ch = vpif_obj.dev[i];
2182 /* Allocate memory for video device */
2183 vfd = video_device_alloc();
2184 if (NULL == vfd) {
2185 for (j = 0; j < i; j++) {
2186 ch = vpif_obj.dev[j];
2187 video_device_release(ch->video_dev);
2188 }
2189 err = -ENOMEM;
2190 goto vpif_dev_alloc_err;
2191 }
2192
2193 /* Initialize field of video device */
2194 *vfd = vpif_video_template;
2195 vfd->v4l2_dev = &vpif_obj.v4l2_dev;
2196 vfd->release = video_device_release;
2197 snprintf(vfd->name, sizeof(vfd->name),
2198 "VPIF_Capture_DRIVER_V%s",
2199 VPIF_CAPTURE_VERSION);
2200 /* Set video_dev to the video device */
2201 ch->video_dev = vfd;
2202 }
2203
2204 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2205 if (res) {
2206 size = resource_size(res);
2207 /* The resources are divided into two equal memory and when we
2208 * have HD output we can add them together
2209 */
2210 for (j = 0; j < VPIF_CAPTURE_MAX_DEVICES; j++) {
2211 ch = vpif_obj.dev[j];
2212 ch->channel_id = j;
2213 /* only enabled if second resource exists */
2214 config_params.video_limit[ch->channel_id] = 0;
2215 if (size)
2216 config_params.video_limit[ch->channel_id] =
2217 size/2;
2218 }
2219 }
2220
2221 for (j = 0; j < VPIF_CAPTURE_MAX_DEVICES; j++) {
2222 ch = vpif_obj.dev[j];
2223 ch->channel_id = j;
2224 common = &(ch->common[VPIF_VIDEO_INDEX]);
2225 spin_lock_init(&common->irqlock);
2226 mutex_init(&common->lock);
2227 ch->video_dev->lock = &common->lock;
2228 /* Initialize prio member of channel object */
2229 v4l2_prio_init(&ch->prio);
2230 err = video_register_device(ch->video_dev,
2231 VFL_TYPE_GRABBER, (j ? 1 : 0));
2232 if (err)
2233 goto probe_out;
2234
2235 video_set_drvdata(ch->video_dev, ch);
2236
2237 }
2238
2239 i2c_adap = i2c_get_adapter(1);
2240 config = pdev->dev.platform_data;
2241
2242 subdev_count = config->subdev_count;
2243 vpif_obj.sd = kzalloc(sizeof(struct v4l2_subdev *) * subdev_count,
2244 GFP_KERNEL);
2245 if (vpif_obj.sd == NULL) {
2246 vpif_err("unable to allocate memory for subdevice pointers\n");
2247 err = -ENOMEM;
2248 goto probe_out;
2249 }
2250
2251 for (i = 0; i < subdev_count; i++) {
2252 subdevdata = &config->subdev_info[i];
2253 vpif_obj.sd[i] =
2254 v4l2_i2c_new_subdev_board(&vpif_obj.v4l2_dev,
2255 i2c_adap,
2256 &subdevdata->board_info,
2257 NULL);
2258
2259 if (!vpif_obj.sd[i]) {
2260 vpif_err("Error registering v4l2 subdevice\n");
2261 goto probe_subdev_out;
2262 }
2263 v4l2_info(&vpif_obj.v4l2_dev, "registered sub device %s\n",
2264 subdevdata->name);
2265
2266 if (vpif_obj.sd[i])
2267 vpif_obj.sd[i]->grp_id = 1 << i;
2268 }
2269
2270 v4l2_info(&vpif_obj.v4l2_dev, "VPIF capture driver initialized\n");
2271 return 0;
2272
2273probe_subdev_out:
2274 /* free sub devices memory */
2275 kfree(vpif_obj.sd);
2276
2277 j = VPIF_CAPTURE_MAX_DEVICES;
2278probe_out:
2279 for (k = 0; k < j; k++) {
2280 /* Get the pointer to the channel object */
2281 ch = vpif_obj.dev[k];
2282 /* Unregister video device */
2283 video_unregister_device(ch->video_dev);
2284 }
2285
2286vpif_dev_alloc_err:
2287 k = VPIF_CAPTURE_MAX_DEVICES-1;
2288 res = platform_get_resource(pdev, IORESOURCE_IRQ, k);
2289 i = res->end;
2290
2291vpif_int_err:
2292 for (q = k; q >= 0; q--) {
2293 for (m = i; m >= (int)res->start; m--)
2294 free_irq(m, (void *)(&vpif_obj.dev[q]->channel_id));
2295
2296 res = platform_get_resource(pdev, IORESOURCE_IRQ, q-1);
2297 if (res)
2298 i = res->end;
2299 }
2300 v4l2_device_unregister(&vpif_obj.v4l2_dev);
2301 return err;
2302}
2303
2304/**
2305 * vpif_remove() - driver remove handler
2306 * @device: ptr to platform device structure
2307 *
2308 * The vidoe device is unregistered
2309 */
2310static int vpif_remove(struct platform_device *device)
2311{
2312 int i;
2313 struct channel_obj *ch;
2314
2315 v4l2_device_unregister(&vpif_obj.v4l2_dev);
2316
2317 /* un-register device */
2318 for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {
2319 /* Get the pointer to the channel object */
2320 ch = vpif_obj.dev[i];
2321 /* Unregister video device */
2322 video_unregister_device(ch->video_dev);
2323 }
2324 return 0;
2325}
2326
2327#ifdef CONFIG_PM
2328/**
2329 * vpif_suspend: vpif device suspend
2330 */
2331static int vpif_suspend(struct device *dev)
2332{
2333
2334 struct common_obj *common;
2335 struct channel_obj *ch;
2336 int i;
2337
2338 for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {
2339 /* Get the pointer to the channel object */
2340 ch = vpif_obj.dev[i];
2341 common = &ch->common[VPIF_VIDEO_INDEX];
2342 mutex_lock(&common->lock);
2343 if (ch->usrs && common->io_usrs) {
2344 /* Disable channel */
2345 if (ch->channel_id == VPIF_CHANNEL0_VIDEO) {
2346 enable_channel0(0);
2347 channel0_intr_enable(0);
2348 }
2349 if (ch->channel_id == VPIF_CHANNEL1_VIDEO ||
2350 common->started == 2) {
2351 enable_channel1(0);
2352 channel1_intr_enable(0);
2353 }
2354 }
2355 mutex_unlock(&common->lock);
2356 }
2357
2358 return 0;
2359}
2360
2361/*
2362 * vpif_resume: vpif device suspend
2363 */
2364static int vpif_resume(struct device *dev)
2365{
2366 struct common_obj *common;
2367 struct channel_obj *ch;
2368 int i;
2369
2370 for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {
2371 /* Get the pointer to the channel object */
2372 ch = vpif_obj.dev[i];
2373 common = &ch->common[VPIF_VIDEO_INDEX];
2374 mutex_lock(&common->lock);
2375 if (ch->usrs && common->io_usrs) {
2376 /* Disable channel */
2377 if (ch->channel_id == VPIF_CHANNEL0_VIDEO) {
2378 enable_channel0(1);
2379 channel0_intr_enable(1);
2380 }
2381 if (ch->channel_id == VPIF_CHANNEL1_VIDEO ||
2382 common->started == 2) {
2383 enable_channel1(1);
2384 channel1_intr_enable(1);
2385 }
2386 }
2387 mutex_unlock(&common->lock);
2388 }
2389
2390 return 0;
2391}
2392
2393static const struct dev_pm_ops vpif_dev_pm_ops = {
2394 .suspend = vpif_suspend,
2395 .resume = vpif_resume,
2396};
2397
2398#define vpif_pm_ops (&vpif_dev_pm_ops)
2399#else
2400#define vpif_pm_ops NULL
2401#endif
2402
2403static __refdata struct platform_driver vpif_driver = {
2404 .driver = {
2405 .name = "vpif_capture",
2406 .owner = THIS_MODULE,
2407 .pm = vpif_pm_ops,
2408 },
2409 .probe = vpif_probe,
2410 .remove = vpif_remove,
2411};
2412
2413/**
2414 * vpif_init: initialize the vpif driver
2415 *
2416 * This function registers device and driver to the kernel, requests irq
2417 * handler and allocates memory
2418 * for channel objects
2419 */
2420static __init int vpif_init(void)
2421{
2422 return platform_driver_register(&vpif_driver);
2423}
2424
2425/**
2426 * vpif_cleanup : This function clean up the vpif capture resources
2427 *
2428 * This will un-registers device and driver to the kernel, frees
2429 * requested irq handler and de-allocates memory allocated for channel
2430 * objects.
2431 */
2432static void vpif_cleanup(void)
2433{
2434 struct platform_device *pdev;
2435 struct resource *res;
2436 int irq_num;
2437 int i = 0;
2438
2439 pdev = container_of(vpif_dev, struct platform_device, dev);
2440 while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, i))) {
2441 for (irq_num = res->start; irq_num <= res->end; irq_num++)
2442 free_irq(irq_num,
2443 (void *)(&vpif_obj.dev[i]->channel_id));
2444 i++;
2445 }
2446
2447 platform_driver_unregister(&vpif_driver);
2448
2449 kfree(vpif_obj.sd);
2450 for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++)
2451 kfree(vpif_obj.dev[i]);
2452}
2453
2454/* Function for module initialization and cleanup */
2455module_init(vpif_init);
2456module_exit(vpif_cleanup);
diff --git a/drivers/media/video/davinci/vpif_capture.h b/drivers/media/video/davinci/vpif_capture.h
deleted file mode 100644
index 3511510f43ee..000000000000
--- a/drivers/media/video/davinci/vpif_capture.h
+++ /dev/null
@@ -1,170 +0,0 @@
1/*
2 * Copyright (C) 2009 Texas Instruments Inc
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18
19#ifndef VPIF_CAPTURE_H
20#define VPIF_CAPTURE_H
21
22#ifdef __KERNEL__
23
24/* Header files */
25#include <linux/videodev2.h>
26#include <media/v4l2-common.h>
27#include <media/v4l2-device.h>
28#include <media/videobuf-core.h>
29#include <media/videobuf2-dma-contig.h>
30#include <media/davinci/vpif_types.h>
31
32#include "vpif.h"
33
34/* Macros */
35#define VPIF_CAPTURE_VERSION "0.0.2"
36
37#define VPIF_VALID_FIELD(field) (((V4L2_FIELD_ANY == field) || \
38 (V4L2_FIELD_NONE == field)) || \
39 (((V4L2_FIELD_INTERLACED == field) || \
40 (V4L2_FIELD_SEQ_TB == field)) || \
41 (V4L2_FIELD_SEQ_BT == field)))
42
43#define VPIF_CAPTURE_MAX_DEVICES 2
44#define VPIF_VIDEO_INDEX 0
45#define VPIF_NUMBER_OF_OBJECTS 1
46
47/* Enumerated data type to give id to each device per channel */
48enum vpif_channel_id {
49 VPIF_CHANNEL0_VIDEO = 0,
50 VPIF_CHANNEL1_VIDEO,
51};
52
53struct video_obj {
54 enum v4l2_field buf_field;
55 /* Currently selected or default standard */
56 v4l2_std_id stdid;
57 u32 dv_preset;
58 struct v4l2_bt_timings bt_timings;
59 /* This is to track the last input that is passed to application */
60 u32 input_idx;
61};
62
63struct vpif_cap_buffer {
64 struct vb2_buffer vb;
65 struct list_head list;
66};
67
68struct common_obj {
69 /* Pointer pointing to current v4l2_buffer */
70 struct vpif_cap_buffer *cur_frm;
71 /* Pointer pointing to current v4l2_buffer */
72 struct vpif_cap_buffer *next_frm;
73 /*
74 * This field keeps track of type of buffer exchange mechanism
75 * user has selected
76 */
77 enum v4l2_memory memory;
78 /* Used to store pixel format */
79 struct v4l2_format fmt;
80 /* Buffer queue used in video-buf */
81 struct vb2_queue buffer_queue;
82 /* allocator-specific contexts for each plane */
83 struct vb2_alloc_ctx *alloc_ctx;
84 /* Queue of filled frames */
85 struct list_head dma_queue;
86 /* Used in video-buf */
87 spinlock_t irqlock;
88 /* lock used to access this structure */
89 struct mutex lock;
90 /* number of users performing IO */
91 u32 io_usrs;
92 /* Indicates whether streaming started */
93 u8 started;
94 /* Function pointer to set the addresses */
95 void (*set_addr) (unsigned long, unsigned long, unsigned long,
96 unsigned long);
97 /* offset where Y top starts from the starting of the buffer */
98 u32 ytop_off;
99 /* offset where Y bottom starts from the starting of the buffer */
100 u32 ybtm_off;
101 /* offset where C top starts from the starting of the buffer */
102 u32 ctop_off;
103 /* offset where C bottom starts from the starting of the buffer */
104 u32 cbtm_off;
105 /* Indicates width of the image data */
106 u32 width;
107 /* Indicates height of the image data */
108 u32 height;
109};
110
111struct channel_obj {
112 /* Identifies video device for this channel */
113 struct video_device *video_dev;
114 /* Used to keep track of state of the priority */
115 struct v4l2_prio_state prio;
116 /* number of open instances of the channel */
117 int usrs;
118 /* Indicates id of the field which is being displayed */
119 u32 field_id;
120 /* flag to indicate whether decoder is initialized */
121 u8 initialized;
122 /* Identifies channel */
123 enum vpif_channel_id channel_id;
124 /* index into sd table */
125 int curr_sd_index;
126 /* ptr to current sub device information */
127 struct vpif_subdev_info *curr_subdev_info;
128 /* vpif configuration params */
129 struct vpif_params vpifparams;
130 /* common object array */
131 struct common_obj common[VPIF_NUMBER_OF_OBJECTS];
132 /* video object */
133 struct video_obj video;
134};
135
136/* File handle structure */
137struct vpif_fh {
138 /* pointer to channel object for opened device */
139 struct channel_obj *channel;
140 /* Indicates whether this file handle is doing IO */
141 u8 io_allowed[VPIF_NUMBER_OF_OBJECTS];
142 /* Used to keep track priority of this instance */
143 enum v4l2_priority prio;
144 /* Used to indicate channel is initialize or not */
145 u8 initialized;
146};
147
148struct vpif_device {
149 struct v4l2_device v4l2_dev;
150 struct channel_obj *dev[VPIF_CAPTURE_NUM_CHANNELS];
151 struct v4l2_subdev **sd;
152};
153
154struct vpif_config_params {
155 u8 min_numbuffers;
156 u8 numbuffers[VPIF_CAPTURE_NUM_CHANNELS];
157 s8 device_type;
158 u32 min_bufsize[VPIF_CAPTURE_NUM_CHANNELS];
159 u32 channel_bufsize[VPIF_CAPTURE_NUM_CHANNELS];
160 u8 default_device[VPIF_CAPTURE_NUM_CHANNELS];
161 u32 video_limit[VPIF_CAPTURE_NUM_CHANNELS];
162 u8 max_device_type;
163};
164/* Struct which keeps track of the line numbers for the sliced vbi service */
165struct vpif_service_line {
166 u16 service_id;
167 u16 service_line[2];
168};
169#endif /* End of __KERNEL__ */
170#endif /* VPIF_CAPTURE_H */
diff --git a/drivers/media/video/davinci/vpif_display.c b/drivers/media/video/davinci/vpif_display.c
deleted file mode 100644
index 4a24848c1a66..000000000000
--- a/drivers/media/video/davinci/vpif_display.c
+++ /dev/null
@@ -1,2010 +0,0 @@
1/*
2 * vpif-display - VPIF display driver
3 * Display driver for TI DaVinci VPIF
4 *
5 * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation version 2.
10 *
11 * This program is distributed .as is. WITHOUT ANY WARRANTY of any
12 * kind, whether express or implied; without even the implied warranty
13 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#include <linux/kernel.h>
18#include <linux/init.h>
19#include <linux/module.h>
20#include <linux/errno.h>
21#include <linux/fs.h>
22#include <linux/mm.h>
23#include <linux/interrupt.h>
24#include <linux/workqueue.h>
25#include <linux/string.h>
26#include <linux/videodev2.h>
27#include <linux/wait.h>
28#include <linux/time.h>
29#include <linux/i2c.h>
30#include <linux/platform_device.h>
31#include <linux/io.h>
32#include <linux/slab.h>
33
34#include <asm/irq.h>
35#include <asm/page.h>
36
37#include <media/adv7343.h>
38#include <media/v4l2-device.h>
39#include <media/v4l2-ioctl.h>
40#include <media/v4l2-chip-ident.h>
41
42#include "vpif_display.h"
43#include "vpif.h"
44
45MODULE_DESCRIPTION("TI DaVinci VPIF Display driver");
46MODULE_LICENSE("GPL");
47MODULE_VERSION(VPIF_DISPLAY_VERSION);
48
49#define VPIF_V4L2_STD (V4L2_STD_525_60 | V4L2_STD_625_50)
50
51#define vpif_err(fmt, arg...) v4l2_err(&vpif_obj.v4l2_dev, fmt, ## arg)
52#define vpif_dbg(level, debug, fmt, arg...) \
53 v4l2_dbg(level, debug, &vpif_obj.v4l2_dev, fmt, ## arg)
54
55static int debug = 1;
56static u32 ch2_numbuffers = 3;
57static u32 ch3_numbuffers = 3;
58static u32 ch2_bufsize = 1920 * 1080 * 2;
59static u32 ch3_bufsize = 720 * 576 * 2;
60
61module_param(debug, int, 0644);
62module_param(ch2_numbuffers, uint, S_IRUGO);
63module_param(ch3_numbuffers, uint, S_IRUGO);
64module_param(ch2_bufsize, uint, S_IRUGO);
65module_param(ch3_bufsize, uint, S_IRUGO);
66
67MODULE_PARM_DESC(debug, "Debug level 0-1");
68MODULE_PARM_DESC(ch2_numbuffers, "Channel2 buffer count (default:3)");
69MODULE_PARM_DESC(ch3_numbuffers, "Channel3 buffer count (default:3)");
70MODULE_PARM_DESC(ch2_bufsize, "Channel2 buffer size (default:1920 x 1080 x 2)");
71MODULE_PARM_DESC(ch3_bufsize, "Channel3 buffer size (default:720 x 576 x 2)");
72
73static struct vpif_config_params config_params = {
74 .min_numbuffers = 3,
75 .numbuffers[0] = 3,
76 .numbuffers[1] = 3,
77 .min_bufsize[0] = 720 * 480 * 2,
78 .min_bufsize[1] = 720 * 480 * 2,
79 .channel_bufsize[0] = 1920 * 1080 * 2,
80 .channel_bufsize[1] = 720 * 576 * 2,
81};
82
83static struct vpif_device vpif_obj = { {NULL} };
84static struct device *vpif_dev;
85static void vpif_calculate_offsets(struct channel_obj *ch);
86static void vpif_config_addr(struct channel_obj *ch, int muxmode);
87
88/*
89 * buffer_prepare: This is the callback function called from vb2_qbuf()
90 * function the buffer is prepared and user space virtual address is converted
91 * into physical address
92 */
93static int vpif_buffer_prepare(struct vb2_buffer *vb)
94{
95 struct vpif_fh *fh = vb2_get_drv_priv(vb->vb2_queue);
96 struct vb2_queue *q = vb->vb2_queue;
97 struct common_obj *common;
98 unsigned long addr;
99
100 common = &fh->channel->common[VPIF_VIDEO_INDEX];
101 if (vb->state != VB2_BUF_STATE_ACTIVE &&
102 vb->state != VB2_BUF_STATE_PREPARED) {
103 vb2_set_plane_payload(vb, 0, common->fmt.fmt.pix.sizeimage);
104 if (vb2_plane_vaddr(vb, 0) &&
105 vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0))
106 goto buf_align_exit;
107
108 addr = vb2_dma_contig_plane_dma_addr(vb, 0);
109 if (q->streaming &&
110 (V4L2_BUF_TYPE_SLICED_VBI_OUTPUT != q->type)) {
111 if (!ISALIGNED(addr + common->ytop_off) ||
112 !ISALIGNED(addr + common->ybtm_off) ||
113 !ISALIGNED(addr + common->ctop_off) ||
114 !ISALIGNED(addr + common->cbtm_off))
115 goto buf_align_exit;
116 }
117 }
118 return 0;
119
120buf_align_exit:
121 vpif_err("buffer offset not aligned to 8 bytes\n");
122 return -EINVAL;
123}
124
125/*
126 * vpif_buffer_queue_setup: This function allocates memory for the buffers
127 */
128static int vpif_buffer_queue_setup(struct vb2_queue *vq,
129 const struct v4l2_format *fmt,
130 unsigned int *nbuffers, unsigned int *nplanes,
131 unsigned int sizes[], void *alloc_ctxs[])
132{
133 struct vpif_fh *fh = vb2_get_drv_priv(vq);
134 struct channel_obj *ch = fh->channel;
135 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
136 unsigned long size;
137
138 if (V4L2_MEMORY_MMAP == common->memory) {
139 size = config_params.channel_bufsize[ch->channel_id];
140 /*
141 * Checking if the buffer size exceeds the available buffer
142 * ycmux_mode = 0 means 1 channel mode HD and
143 * ycmux_mode = 1 means 2 channels mode SD
144 */
145 if (ch->vpifparams.std_info.ycmux_mode == 0) {
146 if (config_params.video_limit[ch->channel_id])
147 while (size * *nbuffers >
148 (config_params.video_limit[0]
149 + config_params.video_limit[1]))
150 (*nbuffers)--;
151 } else {
152 if (config_params.video_limit[ch->channel_id])
153 while (size * *nbuffers >
154 config_params.video_limit[ch->channel_id])
155 (*nbuffers)--;
156 }
157 } else {
158 size = common->fmt.fmt.pix.sizeimage;
159 }
160
161 if (*nbuffers < config_params.min_numbuffers)
162 *nbuffers = config_params.min_numbuffers;
163
164 *nplanes = 1;
165 sizes[0] = size;
166 alloc_ctxs[0] = common->alloc_ctx;
167 return 0;
168}
169
170/*
171 * vpif_buffer_queue: This function adds the buffer to DMA queue
172 */
173static void vpif_buffer_queue(struct vb2_buffer *vb)
174{
175 struct vpif_fh *fh = vb2_get_drv_priv(vb->vb2_queue);
176 struct vpif_disp_buffer *buf = container_of(vb,
177 struct vpif_disp_buffer, vb);
178 struct channel_obj *ch = fh->channel;
179 struct common_obj *common;
180
181 common = &ch->common[VPIF_VIDEO_INDEX];
182
183 /* add the buffer to the DMA queue */
184 list_add_tail(&buf->list, &common->dma_queue);
185}
186
187/*
188 * vpif_buf_cleanup: This function is called from the videobuf2 layer to
189 * free memory allocated to the buffers
190 */
191static void vpif_buf_cleanup(struct vb2_buffer *vb)
192{
193 struct vpif_fh *fh = vb2_get_drv_priv(vb->vb2_queue);
194 struct vpif_disp_buffer *buf = container_of(vb,
195 struct vpif_disp_buffer, vb);
196 struct channel_obj *ch = fh->channel;
197 struct common_obj *common;
198 unsigned long flags;
199
200 common = &ch->common[VPIF_VIDEO_INDEX];
201
202 spin_lock_irqsave(&common->irqlock, flags);
203 if (vb->state == VB2_BUF_STATE_ACTIVE)
204 list_del_init(&buf->list);
205 spin_unlock_irqrestore(&common->irqlock, flags);
206}
207
208static void vpif_wait_prepare(struct vb2_queue *vq)
209{
210 struct vpif_fh *fh = vb2_get_drv_priv(vq);
211 struct channel_obj *ch = fh->channel;
212 struct common_obj *common;
213
214 common = &ch->common[VPIF_VIDEO_INDEX];
215 mutex_unlock(&common->lock);
216}
217
218static void vpif_wait_finish(struct vb2_queue *vq)
219{
220 struct vpif_fh *fh = vb2_get_drv_priv(vq);
221 struct channel_obj *ch = fh->channel;
222 struct common_obj *common;
223
224 common = &ch->common[VPIF_VIDEO_INDEX];
225 mutex_lock(&common->lock);
226}
227
228static int vpif_buffer_init(struct vb2_buffer *vb)
229{
230 struct vpif_disp_buffer *buf = container_of(vb,
231 struct vpif_disp_buffer, vb);
232
233 INIT_LIST_HEAD(&buf->list);
234
235 return 0;
236}
237
238static u8 channel_first_int[VPIF_NUMOBJECTS][2] = { {1, 1} };
239
240static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
241{
242 struct vpif_display_config *vpif_config_data =
243 vpif_dev->platform_data;
244 struct vpif_fh *fh = vb2_get_drv_priv(vq);
245 struct channel_obj *ch = fh->channel;
246 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
247 struct vpif_params *vpif = &ch->vpifparams;
248 unsigned long addr = 0;
249 int ret;
250
251 /* If buffer queue is empty, return error */
252 if (list_empty(&common->dma_queue)) {
253 vpif_err("buffer queue is empty\n");
254 return -EIO;
255 }
256
257 /* Get the next frame from the buffer queue */
258 common->next_frm = common->cur_frm =
259 list_entry(common->dma_queue.next,
260 struct vpif_disp_buffer, list);
261
262 list_del(&common->cur_frm->list);
263 /* Mark state of the current frame to active */
264 common->cur_frm->vb.state = VB2_BUF_STATE_ACTIVE;
265
266 /* Initialize field_id and started member */
267 ch->field_id = 0;
268 common->started = 1;
269 addr = vb2_dma_contig_plane_dma_addr(&common->cur_frm->vb, 0);
270 /* Calculate the offset for Y and C data in the buffer */
271 vpif_calculate_offsets(ch);
272
273 if ((ch->vpifparams.std_info.frm_fmt &&
274 ((common->fmt.fmt.pix.field != V4L2_FIELD_NONE)
275 && (common->fmt.fmt.pix.field != V4L2_FIELD_ANY)))
276 || (!ch->vpifparams.std_info.frm_fmt
277 && (common->fmt.fmt.pix.field == V4L2_FIELD_NONE))) {
278 vpif_err("conflict in field format and std format\n");
279 return -EINVAL;
280 }
281
282 /* clock settings */
283 ret =
284 vpif_config_data->set_clock(ch->vpifparams.std_info.ycmux_mode,
285 ch->vpifparams.std_info.hd_sd);
286 if (ret < 0) {
287 vpif_err("can't set clock\n");
288 return ret;
289 }
290
291 /* set the parameters and addresses */
292 ret = vpif_set_video_params(vpif, ch->channel_id + 2);
293 if (ret < 0)
294 return ret;
295
296 common->started = ret;
297 vpif_config_addr(ch, ret);
298 common->set_addr((addr + common->ytop_off),
299 (addr + common->ybtm_off),
300 (addr + common->ctop_off),
301 (addr + common->cbtm_off));
302
303 /* Set interrupt for both the fields in VPIF
304 Register enable channel in VPIF register */
305 if (VPIF_CHANNEL2_VIDEO == ch->channel_id) {
306 channel2_intr_assert();
307 channel2_intr_enable(1);
308 enable_channel2(1);
309 if (vpif_config_data->ch2_clip_en)
310 channel2_clipping_enable(1);
311 }
312
313 if ((VPIF_CHANNEL3_VIDEO == ch->channel_id)
314 || (common->started == 2)) {
315 channel3_intr_assert();
316 channel3_intr_enable(1);
317 enable_channel3(1);
318 if (vpif_config_data->ch3_clip_en)
319 channel3_clipping_enable(1);
320 }
321 channel_first_int[VPIF_VIDEO_INDEX][ch->channel_id] = 1;
322
323 return 0;
324}
325
326/* abort streaming and wait for last buffer */
327static int vpif_stop_streaming(struct vb2_queue *vq)
328{
329 struct vpif_fh *fh = vb2_get_drv_priv(vq);
330 struct channel_obj *ch = fh->channel;
331 struct common_obj *common;
332
333 if (!vb2_is_streaming(vq))
334 return 0;
335
336 common = &ch->common[VPIF_VIDEO_INDEX];
337
338 /* release all active buffers */
339 while (!list_empty(&common->dma_queue)) {
340 common->next_frm = list_entry(common->dma_queue.next,
341 struct vpif_disp_buffer, list);
342 list_del(&common->next_frm->list);
343 vb2_buffer_done(&common->next_frm->vb, VB2_BUF_STATE_ERROR);
344 }
345
346 return 0;
347}
348
349static struct vb2_ops video_qops = {
350 .queue_setup = vpif_buffer_queue_setup,
351 .wait_prepare = vpif_wait_prepare,
352 .wait_finish = vpif_wait_finish,
353 .buf_init = vpif_buffer_init,
354 .buf_prepare = vpif_buffer_prepare,
355 .start_streaming = vpif_start_streaming,
356 .stop_streaming = vpif_stop_streaming,
357 .buf_cleanup = vpif_buf_cleanup,
358 .buf_queue = vpif_buffer_queue,
359};
360
361static void process_progressive_mode(struct common_obj *common)
362{
363 unsigned long addr = 0;
364
365 /* Get the next buffer from buffer queue */
366 common->next_frm = list_entry(common->dma_queue.next,
367 struct vpif_disp_buffer, list);
368 /* Remove that buffer from the buffer queue */
369 list_del(&common->next_frm->list);
370 /* Mark status of the buffer as active */
371 common->next_frm->vb.state = VB2_BUF_STATE_ACTIVE;
372
373 /* Set top and bottom field addrs in VPIF registers */
374 addr = vb2_dma_contig_plane_dma_addr(&common->next_frm->vb, 0);
375 common->set_addr(addr + common->ytop_off,
376 addr + common->ybtm_off,
377 addr + common->ctop_off,
378 addr + common->cbtm_off);
379}
380
381static void process_interlaced_mode(int fid, struct common_obj *common)
382{
383 /* device field id and local field id are in sync */
384 /* If this is even field */
385 if (0 == fid) {
386 if (common->cur_frm == common->next_frm)
387 return;
388
389 /* one frame is displayed If next frame is
390 * available, release cur_frm and move on */
391 /* Copy frame display time */
392 do_gettimeofday(&common->cur_frm->vb.v4l2_buf.timestamp);
393 /* Change status of the cur_frm */
394 vb2_buffer_done(&common->cur_frm->vb,
395 VB2_BUF_STATE_DONE);
396 /* Make cur_frm pointing to next_frm */
397 common->cur_frm = common->next_frm;
398
399 } else if (1 == fid) { /* odd field */
400 if (list_empty(&common->dma_queue)
401 || (common->cur_frm != common->next_frm)) {
402 return;
403 }
404 /* one field is displayed configure the next
405 * frame if it is available else hold on current
406 * frame */
407 /* Get next from the buffer queue */
408 process_progressive_mode(common);
409
410 }
411}
412
413/*
414 * vpif_channel_isr: It changes status of the displayed buffer, takes next
415 * buffer from the queue and sets its address in VPIF registers
416 */
417static irqreturn_t vpif_channel_isr(int irq, void *dev_id)
418{
419 struct vpif_device *dev = &vpif_obj;
420 struct channel_obj *ch;
421 struct common_obj *common;
422 enum v4l2_field field;
423 int fid = -1, i;
424 int channel_id = 0;
425
426 channel_id = *(int *)(dev_id);
427 if (!vpif_intr_status(channel_id + 2))
428 return IRQ_NONE;
429
430 ch = dev->dev[channel_id];
431 field = ch->common[VPIF_VIDEO_INDEX].fmt.fmt.pix.field;
432 for (i = 0; i < VPIF_NUMOBJECTS; i++) {
433 common = &ch->common[i];
434 /* If streaming is started in this channel */
435 if (0 == common->started)
436 continue;
437
438 if (1 == ch->vpifparams.std_info.frm_fmt) {
439 if (list_empty(&common->dma_queue))
440 continue;
441
442 /* Progressive mode */
443 if (!channel_first_int[i][channel_id]) {
444 /* Mark status of the cur_frm to
445 * done and unlock semaphore on it */
446 do_gettimeofday(&common->cur_frm->vb.
447 v4l2_buf.timestamp);
448 vb2_buffer_done(&common->cur_frm->vb,
449 VB2_BUF_STATE_DONE);
450 /* Make cur_frm pointing to next_frm */
451 common->cur_frm = common->next_frm;
452 }
453
454 channel_first_int[i][channel_id] = 0;
455 process_progressive_mode(common);
456 } else {
457 /* Interlaced mode */
458 /* If it is first interrupt, ignore it */
459
460 if (channel_first_int[i][channel_id]) {
461 channel_first_int[i][channel_id] = 0;
462 continue;
463 }
464
465 if (0 == i) {
466 ch->field_id ^= 1;
467 /* Get field id from VPIF registers */
468 fid = vpif_channel_getfid(ch->channel_id + 2);
469 /* If fid does not match with stored field id */
470 if (fid != ch->field_id) {
471 /* Make them in sync */
472 if (0 == fid)
473 ch->field_id = fid;
474
475 return IRQ_HANDLED;
476 }
477 }
478 process_interlaced_mode(fid, common);
479 }
480 }
481
482 return IRQ_HANDLED;
483}
484
485static int vpif_update_std_info(struct channel_obj *ch)
486{
487 struct video_obj *vid_ch = &ch->video;
488 struct vpif_params *vpifparams = &ch->vpifparams;
489 struct vpif_channel_config_params *std_info = &vpifparams->std_info;
490 const struct vpif_channel_config_params *config;
491
492 int i;
493
494 for (i = 0; i < vpif_ch_params_count; i++) {
495 config = &ch_params[i];
496 if (config->hd_sd == 0) {
497 vpif_dbg(2, debug, "SD format\n");
498 if (config->stdid & vid_ch->stdid) {
499 memcpy(std_info, config, sizeof(*config));
500 break;
501 }
502 } else {
503 vpif_dbg(2, debug, "HD format\n");
504 if (config->dv_preset == vid_ch->dv_preset) {
505 memcpy(std_info, config, sizeof(*config));
506 break;
507 }
508 }
509 }
510
511 if (i == vpif_ch_params_count) {
512 vpif_dbg(1, debug, "Format not found\n");
513 return -EINVAL;
514 }
515
516 return 0;
517}
518
519static int vpif_update_resolution(struct channel_obj *ch)
520{
521 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
522 struct video_obj *vid_ch = &ch->video;
523 struct vpif_params *vpifparams = &ch->vpifparams;
524 struct vpif_channel_config_params *std_info = &vpifparams->std_info;
525
526 if (!vid_ch->stdid && !vid_ch->dv_preset && !vid_ch->bt_timings.height)
527 return -EINVAL;
528
529 if (vid_ch->stdid || vid_ch->dv_preset) {
530 if (vpif_update_std_info(ch))
531 return -EINVAL;
532 }
533
534 common->fmt.fmt.pix.width = std_info->width;
535 common->fmt.fmt.pix.height = std_info->height;
536 vpif_dbg(1, debug, "Pixel details: Width = %d,Height = %d\n",
537 common->fmt.fmt.pix.width, common->fmt.fmt.pix.height);
538
539 /* Set height and width paramateres */
540 common->height = std_info->height;
541 common->width = std_info->width;
542
543 return 0;
544}
545
546/*
547 * vpif_calculate_offsets: This function calculates buffers offset for Y and C
548 * in the top and bottom field
549 */
550static void vpif_calculate_offsets(struct channel_obj *ch)
551{
552 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
553 struct vpif_params *vpifparams = &ch->vpifparams;
554 enum v4l2_field field = common->fmt.fmt.pix.field;
555 struct video_obj *vid_ch = &ch->video;
556 unsigned int hpitch, vpitch, sizeimage;
557
558 if (V4L2_FIELD_ANY == common->fmt.fmt.pix.field) {
559 if (ch->vpifparams.std_info.frm_fmt)
560 vid_ch->buf_field = V4L2_FIELD_NONE;
561 else
562 vid_ch->buf_field = V4L2_FIELD_INTERLACED;
563 } else {
564 vid_ch->buf_field = common->fmt.fmt.pix.field;
565 }
566
567 sizeimage = common->fmt.fmt.pix.sizeimage;
568
569 hpitch = common->fmt.fmt.pix.bytesperline;
570 vpitch = sizeimage / (hpitch * 2);
571 if ((V4L2_FIELD_NONE == vid_ch->buf_field) ||
572 (V4L2_FIELD_INTERLACED == vid_ch->buf_field)) {
573 common->ytop_off = 0;
574 common->ybtm_off = hpitch;
575 common->ctop_off = sizeimage / 2;
576 common->cbtm_off = sizeimage / 2 + hpitch;
577 } else if (V4L2_FIELD_SEQ_TB == vid_ch->buf_field) {
578 common->ytop_off = 0;
579 common->ybtm_off = sizeimage / 4;
580 common->ctop_off = sizeimage / 2;
581 common->cbtm_off = common->ctop_off + sizeimage / 4;
582 } else if (V4L2_FIELD_SEQ_BT == vid_ch->buf_field) {
583 common->ybtm_off = 0;
584 common->ytop_off = sizeimage / 4;
585 common->cbtm_off = sizeimage / 2;
586 common->ctop_off = common->cbtm_off + sizeimage / 4;
587 }
588
589 if ((V4L2_FIELD_NONE == vid_ch->buf_field) ||
590 (V4L2_FIELD_INTERLACED == vid_ch->buf_field)) {
591 vpifparams->video_params.storage_mode = 1;
592 } else {
593 vpifparams->video_params.storage_mode = 0;
594 }
595
596 if (ch->vpifparams.std_info.frm_fmt == 1) {
597 vpifparams->video_params.hpitch =
598 common->fmt.fmt.pix.bytesperline;
599 } else {
600 if ((field == V4L2_FIELD_ANY) ||
601 (field == V4L2_FIELD_INTERLACED))
602 vpifparams->video_params.hpitch =
603 common->fmt.fmt.pix.bytesperline * 2;
604 else
605 vpifparams->video_params.hpitch =
606 common->fmt.fmt.pix.bytesperline;
607 }
608
609 ch->vpifparams.video_params.stdid = ch->vpifparams.std_info.stdid;
610}
611
612static void vpif_config_format(struct channel_obj *ch)
613{
614 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
615
616 common->fmt.fmt.pix.field = V4L2_FIELD_ANY;
617 if (config_params.numbuffers[ch->channel_id] == 0)
618 common->memory = V4L2_MEMORY_USERPTR;
619 else
620 common->memory = V4L2_MEMORY_MMAP;
621
622 common->fmt.fmt.pix.sizeimage =
623 config_params.channel_bufsize[ch->channel_id];
624 common->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV422P;
625 common->fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
626}
627
628static int vpif_check_format(struct channel_obj *ch,
629 struct v4l2_pix_format *pixfmt)
630{
631 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
632 enum v4l2_field field = pixfmt->field;
633 u32 sizeimage, hpitch, vpitch;
634
635 if (pixfmt->pixelformat != V4L2_PIX_FMT_YUV422P)
636 goto invalid_fmt_exit;
637
638 if (!(VPIF_VALID_FIELD(field)))
639 goto invalid_fmt_exit;
640
641 if (pixfmt->bytesperline <= 0)
642 goto invalid_pitch_exit;
643
644 sizeimage = pixfmt->sizeimage;
645
646 if (vpif_update_resolution(ch))
647 return -EINVAL;
648
649 hpitch = pixfmt->bytesperline;
650 vpitch = sizeimage / (hpitch * 2);
651
652 /* Check for valid value of pitch */
653 if ((hpitch < ch->vpifparams.std_info.width) ||
654 (vpitch < ch->vpifparams.std_info.height))
655 goto invalid_pitch_exit;
656
657 /* Check for 8 byte alignment */
658 if (!ISALIGNED(hpitch)) {
659 vpif_err("invalid pitch alignment\n");
660 return -EINVAL;
661 }
662 pixfmt->width = common->fmt.fmt.pix.width;
663 pixfmt->height = common->fmt.fmt.pix.height;
664
665 return 0;
666
667invalid_fmt_exit:
668 vpif_err("invalid field format\n");
669 return -EINVAL;
670
671invalid_pitch_exit:
672 vpif_err("invalid pitch\n");
673 return -EINVAL;
674}
675
676static void vpif_config_addr(struct channel_obj *ch, int muxmode)
677{
678 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
679
680 if (VPIF_CHANNEL3_VIDEO == ch->channel_id) {
681 common->set_addr = ch3_set_videobuf_addr;
682 } else {
683 if (2 == muxmode)
684 common->set_addr = ch2_set_videobuf_addr_yc_nmux;
685 else
686 common->set_addr = ch2_set_videobuf_addr;
687 }
688}
689
690/*
691 * vpif_mmap: It is used to map kernel space buffers into user spaces
692 */
693static int vpif_mmap(struct file *filep, struct vm_area_struct *vma)
694{
695 struct vpif_fh *fh = filep->private_data;
696 struct channel_obj *ch = fh->channel;
697 struct common_obj *common = &(ch->common[VPIF_VIDEO_INDEX]);
698 int ret;
699
700 vpif_dbg(2, debug, "vpif_mmap\n");
701
702 if (mutex_lock_interruptible(&common->lock))
703 return -ERESTARTSYS;
704 ret = vb2_mmap(&common->buffer_queue, vma);
705 mutex_unlock(&common->lock);
706 return ret;
707}
708
709/*
710 * vpif_poll: It is used for select/poll system call
711 */
712static unsigned int vpif_poll(struct file *filep, poll_table *wait)
713{
714 struct vpif_fh *fh = filep->private_data;
715 struct channel_obj *ch = fh->channel;
716 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
717 unsigned int res = 0;
718
719 if (common->started) {
720 mutex_lock(&common->lock);
721 res = vb2_poll(&common->buffer_queue, filep, wait);
722 mutex_unlock(&common->lock);
723 }
724
725 return res;
726}
727
728/*
729 * vpif_open: It creates object of file handle structure and stores it in
730 * private_data member of filepointer
731 */
732static int vpif_open(struct file *filep)
733{
734 struct video_device *vdev = video_devdata(filep);
735 struct channel_obj *ch = video_get_drvdata(vdev);
736 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
737 struct vpif_fh *fh;
738
739 /* Allocate memory for the file handle object */
740 fh = kzalloc(sizeof(struct vpif_fh), GFP_KERNEL);
741 if (fh == NULL) {
742 vpif_err("unable to allocate memory for file handle object\n");
743 return -ENOMEM;
744 }
745
746 if (mutex_lock_interruptible(&common->lock)) {
747 kfree(fh);
748 return -ERESTARTSYS;
749 }
750 /* store pointer to fh in private_data member of filep */
751 filep->private_data = fh;
752 fh->channel = ch;
753 fh->initialized = 0;
754 if (!ch->initialized) {
755 fh->initialized = 1;
756 ch->initialized = 1;
757 memset(&ch->vpifparams, 0, sizeof(ch->vpifparams));
758 }
759
760 /* Increment channel usrs counter */
761 atomic_inc(&ch->usrs);
762 /* Set io_allowed[VPIF_VIDEO_INDEX] member to false */
763 fh->io_allowed[VPIF_VIDEO_INDEX] = 0;
764 /* Initialize priority of this instance to default priority */
765 fh->prio = V4L2_PRIORITY_UNSET;
766 v4l2_prio_open(&ch->prio, &fh->prio);
767 mutex_unlock(&common->lock);
768
769 return 0;
770}
771
772/*
773 * vpif_release: This function deletes buffer queue, frees the buffers and
774 * the vpif file handle
775 */
776static int vpif_release(struct file *filep)
777{
778 struct vpif_fh *fh = filep->private_data;
779 struct channel_obj *ch = fh->channel;
780 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
781
782 mutex_lock(&common->lock);
783 /* if this instance is doing IO */
784 if (fh->io_allowed[VPIF_VIDEO_INDEX]) {
785 /* Reset io_usrs member of channel object */
786 common->io_usrs = 0;
787 /* Disable channel */
788 if (VPIF_CHANNEL2_VIDEO == ch->channel_id) {
789 enable_channel2(0);
790 channel2_intr_enable(0);
791 }
792 if ((VPIF_CHANNEL3_VIDEO == ch->channel_id) ||
793 (2 == common->started)) {
794 enable_channel3(0);
795 channel3_intr_enable(0);
796 }
797 common->started = 0;
798
799 /* Free buffers allocated */
800 vb2_queue_release(&common->buffer_queue);
801 vb2_dma_contig_cleanup_ctx(common->alloc_ctx);
802
803 common->numbuffers =
804 config_params.numbuffers[ch->channel_id];
805 }
806
807 /* Decrement channel usrs counter */
808 atomic_dec(&ch->usrs);
809 /* If this file handle has initialize encoder device, reset it */
810 if (fh->initialized)
811 ch->initialized = 0;
812
813 /* Close the priority */
814 v4l2_prio_close(&ch->prio, fh->prio);
815 filep->private_data = NULL;
816 fh->initialized = 0;
817 mutex_unlock(&common->lock);
818 kfree(fh);
819
820 return 0;
821}
822
823/* functions implementing ioctls */
824/**
825 * vpif_querycap() - QUERYCAP handler
826 * @file: file ptr
827 * @priv: file handle
828 * @cap: ptr to v4l2_capability structure
829 */
830static int vpif_querycap(struct file *file, void *priv,
831 struct v4l2_capability *cap)
832{
833 struct vpif_display_config *config = vpif_dev->platform_data;
834
835 cap->capabilities = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
836 strlcpy(cap->driver, "vpif display", sizeof(cap->driver));
837 strlcpy(cap->bus_info, "Platform", sizeof(cap->bus_info));
838 strlcpy(cap->card, config->card_name, sizeof(cap->card));
839
840 return 0;
841}
842
843static int vpif_enum_fmt_vid_out(struct file *file, void *priv,
844 struct v4l2_fmtdesc *fmt)
845{
846 if (fmt->index != 0) {
847 vpif_err("Invalid format index\n");
848 return -EINVAL;
849 }
850
851 /* Fill in the information about format */
852 fmt->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
853 strcpy(fmt->description, "YCbCr4:2:2 YC Planar");
854 fmt->pixelformat = V4L2_PIX_FMT_YUV422P;
855
856 return 0;
857}
858
859static int vpif_g_fmt_vid_out(struct file *file, void *priv,
860 struct v4l2_format *fmt)
861{
862 struct vpif_fh *fh = priv;
863 struct channel_obj *ch = fh->channel;
864 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
865
866 /* Check the validity of the buffer type */
867 if (common->fmt.type != fmt->type)
868 return -EINVAL;
869
870 if (vpif_update_resolution(ch))
871 return -EINVAL;
872 *fmt = common->fmt;
873 return 0;
874}
875
876static int vpif_s_fmt_vid_out(struct file *file, void *priv,
877 struct v4l2_format *fmt)
878{
879 struct vpif_fh *fh = priv;
880 struct v4l2_pix_format *pixfmt;
881 struct channel_obj *ch = fh->channel;
882 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
883 int ret = 0;
884
885 if ((VPIF_CHANNEL2_VIDEO == ch->channel_id)
886 || (VPIF_CHANNEL3_VIDEO == ch->channel_id)) {
887 if (!fh->initialized) {
888 vpif_dbg(1, debug, "Channel Busy\n");
889 return -EBUSY;
890 }
891
892 /* Check for the priority */
893 ret = v4l2_prio_check(&ch->prio, fh->prio);
894 if (0 != ret)
895 return ret;
896 fh->initialized = 1;
897 }
898
899 if (common->started) {
900 vpif_dbg(1, debug, "Streaming in progress\n");
901 return -EBUSY;
902 }
903
904 pixfmt = &fmt->fmt.pix;
905 /* Check for valid field format */
906 ret = vpif_check_format(ch, pixfmt);
907 if (ret)
908 return ret;
909
910 /* store the pix format in the channel object */
911 common->fmt.fmt.pix = *pixfmt;
912 /* store the format in the channel object */
913 common->fmt = *fmt;
914 return 0;
915}
916
917static int vpif_try_fmt_vid_out(struct file *file, void *priv,
918 struct v4l2_format *fmt)
919{
920 struct vpif_fh *fh = priv;
921 struct channel_obj *ch = fh->channel;
922 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
923 struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
924 int ret = 0;
925
926 ret = vpif_check_format(ch, pixfmt);
927 if (ret) {
928 *pixfmt = common->fmt.fmt.pix;
929 pixfmt->sizeimage = pixfmt->width * pixfmt->height * 2;
930 }
931
932 return ret;
933}
934
935static int vpif_reqbufs(struct file *file, void *priv,
936 struct v4l2_requestbuffers *reqbuf)
937{
938 struct vpif_fh *fh = priv;
939 struct channel_obj *ch = fh->channel;
940 struct common_obj *common;
941 enum v4l2_field field;
942 struct vb2_queue *q;
943 u8 index = 0;
944
945 /* This file handle has not initialized the channel,
946 It is not allowed to do settings */
947 if ((VPIF_CHANNEL2_VIDEO == ch->channel_id)
948 || (VPIF_CHANNEL3_VIDEO == ch->channel_id)) {
949 if (!fh->initialized) {
950 vpif_err("Channel Busy\n");
951 return -EBUSY;
952 }
953 }
954
955 if (V4L2_BUF_TYPE_VIDEO_OUTPUT != reqbuf->type)
956 return -EINVAL;
957
958 index = VPIF_VIDEO_INDEX;
959
960 common = &ch->common[index];
961
962 if (common->fmt.type != reqbuf->type || !vpif_dev)
963 return -EINVAL;
964 if (0 != common->io_usrs)
965 return -EBUSY;
966
967 if (reqbuf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
968 if (common->fmt.fmt.pix.field == V4L2_FIELD_ANY)
969 field = V4L2_FIELD_INTERLACED;
970 else
971 field = common->fmt.fmt.pix.field;
972 } else {
973 field = V4L2_VBI_INTERLACED;
974 }
975 /* Initialize videobuf2 queue as per the buffer type */
976 common->alloc_ctx = vb2_dma_contig_init_ctx(vpif_dev);
977 if (!common->alloc_ctx) {
978 vpif_err("Failed to get the context\n");
979 return -EINVAL;
980 }
981 q = &common->buffer_queue;
982 q->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
983 q->io_modes = VB2_MMAP | VB2_USERPTR;
984 q->drv_priv = fh;
985 q->ops = &video_qops;
986 q->mem_ops = &vb2_dma_contig_memops;
987 q->buf_struct_size = sizeof(struct vpif_disp_buffer);
988
989 vb2_queue_init(q);
990
991 /* Set io allowed member of file handle to TRUE */
992 fh->io_allowed[index] = 1;
993 /* Increment io usrs member of channel object to 1 */
994 common->io_usrs = 1;
995 /* Store type of memory requested in channel object */
996 common->memory = reqbuf->memory;
997 INIT_LIST_HEAD(&common->dma_queue);
998 /* Allocate buffers */
999 return vb2_reqbufs(&common->buffer_queue, reqbuf);
1000}
1001
1002static int vpif_querybuf(struct file *file, void *priv,
1003 struct v4l2_buffer *tbuf)
1004{
1005 struct vpif_fh *fh = priv;
1006 struct channel_obj *ch = fh->channel;
1007 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1008
1009 if (common->fmt.type != tbuf->type)
1010 return -EINVAL;
1011
1012 return vb2_querybuf(&common->buffer_queue, tbuf);
1013}
1014
1015static int vpif_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
1016{
1017 struct vpif_fh *fh = NULL;
1018 struct channel_obj *ch = NULL;
1019 struct common_obj *common = NULL;
1020
1021 if (!buf || !priv)
1022 return -EINVAL;
1023
1024 fh = priv;
1025 ch = fh->channel;
1026 if (!ch)
1027 return -EINVAL;
1028
1029 common = &(ch->common[VPIF_VIDEO_INDEX]);
1030 if (common->fmt.type != buf->type)
1031 return -EINVAL;
1032
1033 if (!fh->io_allowed[VPIF_VIDEO_INDEX]) {
1034 vpif_err("fh->io_allowed\n");
1035 return -EACCES;
1036 }
1037
1038 return vb2_qbuf(&common->buffer_queue, buf);
1039}
1040
1041static int vpif_s_std(struct file *file, void *priv, v4l2_std_id *std_id)
1042{
1043 struct vpif_fh *fh = priv;
1044 struct channel_obj *ch = fh->channel;
1045 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1046 int ret = 0;
1047
1048 if (!(*std_id & VPIF_V4L2_STD))
1049 return -EINVAL;
1050
1051 if (common->started) {
1052 vpif_err("streaming in progress\n");
1053 return -EBUSY;
1054 }
1055
1056 /* Call encoder subdevice function to set the standard */
1057 ch->video.stdid = *std_id;
1058 ch->video.dv_preset = V4L2_DV_INVALID;
1059 memset(&ch->video.bt_timings, 0, sizeof(ch->video.bt_timings));
1060
1061 /* Get the information about the standard */
1062 if (vpif_update_resolution(ch))
1063 return -EINVAL;
1064
1065 if ((ch->vpifparams.std_info.width *
1066 ch->vpifparams.std_info.height * 2) >
1067 config_params.channel_bufsize[ch->channel_id]) {
1068 vpif_err("invalid std for this size\n");
1069 return -EINVAL;
1070 }
1071
1072 common->fmt.fmt.pix.bytesperline = common->fmt.fmt.pix.width;
1073 /* Configure the default format information */
1074 vpif_config_format(ch);
1075
1076 ret = v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 1, video,
1077 s_std_output, *std_id);
1078 if (ret < 0) {
1079 vpif_err("Failed to set output standard\n");
1080 return ret;
1081 }
1082
1083 ret = v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 1, core,
1084 s_std, *std_id);
1085 if (ret < 0)
1086 vpif_err("Failed to set standard for sub devices\n");
1087 return ret;
1088}
1089
1090static int vpif_g_std(struct file *file, void *priv, v4l2_std_id *std)
1091{
1092 struct vpif_fh *fh = priv;
1093 struct channel_obj *ch = fh->channel;
1094
1095 *std = ch->video.stdid;
1096 return 0;
1097}
1098
1099static int vpif_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
1100{
1101 struct vpif_fh *fh = priv;
1102 struct channel_obj *ch = fh->channel;
1103 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1104
1105 return vb2_dqbuf(&common->buffer_queue, p,
1106 (file->f_flags & O_NONBLOCK));
1107}
1108
1109static int vpif_streamon(struct file *file, void *priv,
1110 enum v4l2_buf_type buftype)
1111{
1112 struct vpif_fh *fh = priv;
1113 struct channel_obj *ch = fh->channel;
1114 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1115 struct channel_obj *oth_ch = vpif_obj.dev[!ch->channel_id];
1116 int ret = 0;
1117
1118 if (buftype != V4L2_BUF_TYPE_VIDEO_OUTPUT) {
1119 vpif_err("buffer type not supported\n");
1120 return -EINVAL;
1121 }
1122
1123 if (!fh->io_allowed[VPIF_VIDEO_INDEX]) {
1124 vpif_err("fh->io_allowed\n");
1125 return -EACCES;
1126 }
1127
1128 /* If Streaming is already started, return error */
1129 if (common->started) {
1130 vpif_err("channel->started\n");
1131 return -EBUSY;
1132 }
1133
1134 if ((ch->channel_id == VPIF_CHANNEL2_VIDEO
1135 && oth_ch->common[VPIF_VIDEO_INDEX].started &&
1136 ch->vpifparams.std_info.ycmux_mode == 0)
1137 || ((ch->channel_id == VPIF_CHANNEL3_VIDEO)
1138 && (2 == oth_ch->common[VPIF_VIDEO_INDEX].started))) {
1139 vpif_err("other channel is using\n");
1140 return -EBUSY;
1141 }
1142
1143 ret = vpif_check_format(ch, &common->fmt.fmt.pix);
1144 if (ret < 0)
1145 return ret;
1146
1147 /* Call vb2_streamon to start streaming in videobuf2 */
1148 ret = vb2_streamon(&common->buffer_queue, buftype);
1149 if (ret < 0) {
1150 vpif_err("vb2_streamon\n");
1151 return ret;
1152 }
1153
1154 return ret;
1155}
1156
1157static int vpif_streamoff(struct file *file, void *priv,
1158 enum v4l2_buf_type buftype)
1159{
1160 struct vpif_fh *fh = priv;
1161 struct channel_obj *ch = fh->channel;
1162 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1163 struct vpif_display_config *vpif_config_data =
1164 vpif_dev->platform_data;
1165
1166 if (buftype != V4L2_BUF_TYPE_VIDEO_OUTPUT) {
1167 vpif_err("buffer type not supported\n");
1168 return -EINVAL;
1169 }
1170
1171 if (!fh->io_allowed[VPIF_VIDEO_INDEX]) {
1172 vpif_err("fh->io_allowed\n");
1173 return -EACCES;
1174 }
1175
1176 if (!common->started) {
1177 vpif_err("channel->started\n");
1178 return -EINVAL;
1179 }
1180
1181 if (buftype == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
1182 /* disable channel */
1183 if (VPIF_CHANNEL2_VIDEO == ch->channel_id) {
1184 if (vpif_config_data->ch2_clip_en)
1185 channel2_clipping_enable(0);
1186 enable_channel2(0);
1187 channel2_intr_enable(0);
1188 }
1189 if ((VPIF_CHANNEL3_VIDEO == ch->channel_id) ||
1190 (2 == common->started)) {
1191 if (vpif_config_data->ch3_clip_en)
1192 channel3_clipping_enable(0);
1193 enable_channel3(0);
1194 channel3_intr_enable(0);
1195 }
1196 }
1197
1198 common->started = 0;
1199 return vb2_streamoff(&common->buffer_queue, buftype);
1200}
1201
1202static int vpif_cropcap(struct file *file, void *priv,
1203 struct v4l2_cropcap *crop)
1204{
1205 struct vpif_fh *fh = priv;
1206 struct channel_obj *ch = fh->channel;
1207 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1208 if (V4L2_BUF_TYPE_VIDEO_OUTPUT != crop->type)
1209 return -EINVAL;
1210
1211 crop->bounds.left = crop->bounds.top = 0;
1212 crop->defrect.left = crop->defrect.top = 0;
1213 crop->defrect.height = crop->bounds.height = common->height;
1214 crop->defrect.width = crop->bounds.width = common->width;
1215
1216 return 0;
1217}
1218
1219static int vpif_enum_output(struct file *file, void *fh,
1220 struct v4l2_output *output)
1221{
1222
1223 struct vpif_display_config *config = vpif_dev->platform_data;
1224
1225 if (output->index >= config->output_count) {
1226 vpif_dbg(1, debug, "Invalid output index\n");
1227 return -EINVAL;
1228 }
1229
1230 strcpy(output->name, config->output[output->index]);
1231 output->type = V4L2_OUTPUT_TYPE_ANALOG;
1232 output->std = VPIF_V4L2_STD;
1233
1234 return 0;
1235}
1236
1237static int vpif_s_output(struct file *file, void *priv, unsigned int i)
1238{
1239 struct vpif_fh *fh = priv;
1240 struct channel_obj *ch = fh->channel;
1241 struct video_obj *vid_ch = &ch->video;
1242 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1243 int ret = 0;
1244
1245 if (common->started) {
1246 vpif_err("Streaming in progress\n");
1247 return -EBUSY;
1248 }
1249
1250 ret = v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 1, video,
1251 s_routing, 0, i, 0);
1252
1253 if (ret < 0)
1254 vpif_err("Failed to set output standard\n");
1255
1256 vid_ch->output_id = i;
1257 return ret;
1258}
1259
1260static int vpif_g_output(struct file *file, void *priv, unsigned int *i)
1261{
1262 struct vpif_fh *fh = priv;
1263 struct channel_obj *ch = fh->channel;
1264 struct video_obj *vid_ch = &ch->video;
1265
1266 *i = vid_ch->output_id;
1267
1268 return 0;
1269}
1270
1271static int vpif_g_priority(struct file *file, void *priv, enum v4l2_priority *p)
1272{
1273 struct vpif_fh *fh = priv;
1274 struct channel_obj *ch = fh->channel;
1275
1276 *p = v4l2_prio_max(&ch->prio);
1277
1278 return 0;
1279}
1280
1281static int vpif_s_priority(struct file *file, void *priv, enum v4l2_priority p)
1282{
1283 struct vpif_fh *fh = priv;
1284 struct channel_obj *ch = fh->channel;
1285
1286 return v4l2_prio_change(&ch->prio, &fh->prio, p);
1287}
1288
1289/**
1290 * vpif_enum_dv_presets() - ENUM_DV_PRESETS handler
1291 * @file: file ptr
1292 * @priv: file handle
1293 * @preset: input preset
1294 */
1295static int vpif_enum_dv_presets(struct file *file, void *priv,
1296 struct v4l2_dv_enum_preset *preset)
1297{
1298 struct vpif_fh *fh = priv;
1299 struct channel_obj *ch = fh->channel;
1300 struct video_obj *vid_ch = &ch->video;
1301
1302 return v4l2_subdev_call(vpif_obj.sd[vid_ch->output_id],
1303 video, enum_dv_presets, preset);
1304}
1305
1306/**
1307 * vpif_s_dv_presets() - S_DV_PRESETS handler
1308 * @file: file ptr
1309 * @priv: file handle
1310 * @preset: input preset
1311 */
1312static int vpif_s_dv_preset(struct file *file, void *priv,
1313 struct v4l2_dv_preset *preset)
1314{
1315 struct vpif_fh *fh = priv;
1316 struct channel_obj *ch = fh->channel;
1317 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1318 struct video_obj *vid_ch = &ch->video;
1319 int ret = 0;
1320
1321 if (common->started) {
1322 vpif_dbg(1, debug, "streaming in progress\n");
1323 return -EBUSY;
1324 }
1325
1326 ret = v4l2_prio_check(&ch->prio, fh->prio);
1327 if (ret != 0)
1328 return ret;
1329
1330 fh->initialized = 1;
1331
1332 /* Call encoder subdevice function to set the standard */
1333 if (mutex_lock_interruptible(&common->lock))
1334 return -ERESTARTSYS;
1335
1336 ch->video.dv_preset = preset->preset;
1337 ch->video.stdid = V4L2_STD_UNKNOWN;
1338 memset(&ch->video.bt_timings, 0, sizeof(ch->video.bt_timings));
1339
1340 /* Get the information about the standard */
1341 if (vpif_update_resolution(ch)) {
1342 ret = -EINVAL;
1343 } else {
1344 /* Configure the default format information */
1345 vpif_config_format(ch);
1346
1347 ret = v4l2_subdev_call(vpif_obj.sd[vid_ch->output_id],
1348 video, s_dv_preset, preset);
1349 }
1350
1351 mutex_unlock(&common->lock);
1352
1353 return ret;
1354}
1355/**
1356 * vpif_g_dv_presets() - G_DV_PRESETS handler
1357 * @file: file ptr
1358 * @priv: file handle
1359 * @preset: input preset
1360 */
1361static int vpif_g_dv_preset(struct file *file, void *priv,
1362 struct v4l2_dv_preset *preset)
1363{
1364 struct vpif_fh *fh = priv;
1365 struct channel_obj *ch = fh->channel;
1366
1367 preset->preset = ch->video.dv_preset;
1368
1369 return 0;
1370}
1371/**
1372 * vpif_s_dv_timings() - S_DV_TIMINGS handler
1373 * @file: file ptr
1374 * @priv: file handle
1375 * @timings: digital video timings
1376 */
1377static int vpif_s_dv_timings(struct file *file, void *priv,
1378 struct v4l2_dv_timings *timings)
1379{
1380 struct vpif_fh *fh = priv;
1381 struct channel_obj *ch = fh->channel;
1382 struct vpif_params *vpifparams = &ch->vpifparams;
1383 struct vpif_channel_config_params *std_info = &vpifparams->std_info;
1384 struct video_obj *vid_ch = &ch->video;
1385 struct v4l2_bt_timings *bt = &vid_ch->bt_timings;
1386 int ret;
1387
1388 if (timings->type != V4L2_DV_BT_656_1120) {
1389 vpif_dbg(2, debug, "Timing type not defined\n");
1390 return -EINVAL;
1391 }
1392
1393 /* Configure subdevice timings, if any */
1394 ret = v4l2_subdev_call(vpif_obj.sd[vid_ch->output_id],
1395 video, s_dv_timings, timings);
1396 if (ret == -ENOIOCTLCMD) {
1397 vpif_dbg(2, debug, "Custom DV timings not supported by "
1398 "subdevice\n");
1399 return -EINVAL;
1400 }
1401 if (ret < 0) {
1402 vpif_dbg(2, debug, "Error setting custom DV timings\n");
1403 return ret;
1404 }
1405
1406 if (!(timings->bt.width && timings->bt.height &&
1407 (timings->bt.hbackporch ||
1408 timings->bt.hfrontporch ||
1409 timings->bt.hsync) &&
1410 timings->bt.vfrontporch &&
1411 (timings->bt.vbackporch ||
1412 timings->bt.vsync))) {
1413 vpif_dbg(2, debug, "Timings for width, height, "
1414 "horizontal back porch, horizontal sync, "
1415 "horizontal front porch, vertical back porch, "
1416 "vertical sync and vertical back porch "
1417 "must be defined\n");
1418 return -EINVAL;
1419 }
1420
1421 *bt = timings->bt;
1422
1423 /* Configure video port timings */
1424
1425 std_info->eav2sav = bt->hbackporch + bt->hfrontporch +
1426 bt->hsync - 8;
1427 std_info->sav2eav = bt->width;
1428
1429 std_info->l1 = 1;
1430 std_info->l3 = bt->vsync + bt->vbackporch + 1;
1431
1432 if (bt->interlaced) {
1433 if (bt->il_vbackporch || bt->il_vfrontporch || bt->il_vsync) {
1434 std_info->vsize = bt->height * 2 +
1435 bt->vfrontporch + bt->vsync + bt->vbackporch +
1436 bt->il_vfrontporch + bt->il_vsync +
1437 bt->il_vbackporch;
1438 std_info->l5 = std_info->vsize/2 -
1439 (bt->vfrontporch - 1);
1440 std_info->l7 = std_info->vsize/2 + 1;
1441 std_info->l9 = std_info->l7 + bt->il_vsync +
1442 bt->il_vbackporch + 1;
1443 std_info->l11 = std_info->vsize -
1444 (bt->il_vfrontporch - 1);
1445 } else {
1446 vpif_dbg(2, debug, "Required timing values for "
1447 "interlaced BT format missing\n");
1448 return -EINVAL;
1449 }
1450 } else {
1451 std_info->vsize = bt->height + bt->vfrontporch +
1452 bt->vsync + bt->vbackporch;
1453 std_info->l5 = std_info->vsize - (bt->vfrontporch - 1);
1454 }
1455 strncpy(std_info->name, "Custom timings BT656/1120",
1456 VPIF_MAX_NAME);
1457 std_info->width = bt->width;
1458 std_info->height = bt->height;
1459 std_info->frm_fmt = bt->interlaced ? 0 : 1;
1460 std_info->ycmux_mode = 0;
1461 std_info->capture_format = 0;
1462 std_info->vbi_supported = 0;
1463 std_info->hd_sd = 1;
1464 std_info->stdid = 0;
1465 std_info->dv_preset = V4L2_DV_INVALID;
1466
1467 vid_ch->stdid = 0;
1468 vid_ch->dv_preset = V4L2_DV_INVALID;
1469
1470 return 0;
1471}
1472
1473/**
1474 * vpif_g_dv_timings() - G_DV_TIMINGS handler
1475 * @file: file ptr
1476 * @priv: file handle
1477 * @timings: digital video timings
1478 */
1479static int vpif_g_dv_timings(struct file *file, void *priv,
1480 struct v4l2_dv_timings *timings)
1481{
1482 struct vpif_fh *fh = priv;
1483 struct channel_obj *ch = fh->channel;
1484 struct video_obj *vid_ch = &ch->video;
1485 struct v4l2_bt_timings *bt = &vid_ch->bt_timings;
1486
1487 timings->bt = *bt;
1488
1489 return 0;
1490}
1491
1492/*
1493 * vpif_g_chip_ident() - Identify the chip
1494 * @file: file ptr
1495 * @priv: file handle
1496 * @chip: chip identity
1497 *
1498 * Returns zero or -EINVAL if read operations fails.
1499 */
1500static int vpif_g_chip_ident(struct file *file, void *priv,
1501 struct v4l2_dbg_chip_ident *chip)
1502{
1503 chip->ident = V4L2_IDENT_NONE;
1504 chip->revision = 0;
1505 if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER &&
1506 chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR) {
1507 vpif_dbg(2, debug, "match_type is invalid.\n");
1508 return -EINVAL;
1509 }
1510
1511 return v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 0, core,
1512 g_chip_ident, chip);
1513}
1514
1515#ifdef CONFIG_VIDEO_ADV_DEBUG
1516/*
1517 * vpif_dbg_g_register() - Read register
1518 * @file: file ptr
1519 * @priv: file handle
1520 * @reg: register to be read
1521 *
1522 * Debugging only
1523 * Returns zero or -EINVAL if read operations fails.
1524 */
1525static int vpif_dbg_g_register(struct file *file, void *priv,
1526 struct v4l2_dbg_register *reg){
1527 struct vpif_fh *fh = priv;
1528 struct channel_obj *ch = fh->channel;
1529 struct video_obj *vid_ch = &ch->video;
1530
1531 return v4l2_subdev_call(vpif_obj.sd[vid_ch->output_id], core,
1532 g_register, reg);
1533}
1534
1535/*
1536 * vpif_dbg_s_register() - Write to register
1537 * @file: file ptr
1538 * @priv: file handle
1539 * @reg: register to be modified
1540 *
1541 * Debugging only
1542 * Returns zero or -EINVAL if write operations fails.
1543 */
1544static int vpif_dbg_s_register(struct file *file, void *priv,
1545 struct v4l2_dbg_register *reg){
1546 struct vpif_fh *fh = priv;
1547 struct channel_obj *ch = fh->channel;
1548 struct video_obj *vid_ch = &ch->video;
1549
1550 return v4l2_subdev_call(vpif_obj.sd[vid_ch->output_id], core,
1551 s_register, reg);
1552}
1553#endif
1554
1555/*
1556 * vpif_log_status() - Status information
1557 * @file: file ptr
1558 * @priv: file handle
1559 *
1560 * Returns zero.
1561 */
1562static int vpif_log_status(struct file *filep, void *priv)
1563{
1564 /* status for sub devices */
1565 v4l2_device_call_all(&vpif_obj.v4l2_dev, 0, core, log_status);
1566
1567 return 0;
1568}
1569
1570/* vpif display ioctl operations */
1571static const struct v4l2_ioctl_ops vpif_ioctl_ops = {
1572 .vidioc_querycap = vpif_querycap,
1573 .vidioc_g_priority = vpif_g_priority,
1574 .vidioc_s_priority = vpif_s_priority,
1575 .vidioc_enum_fmt_vid_out = vpif_enum_fmt_vid_out,
1576 .vidioc_g_fmt_vid_out = vpif_g_fmt_vid_out,
1577 .vidioc_s_fmt_vid_out = vpif_s_fmt_vid_out,
1578 .vidioc_try_fmt_vid_out = vpif_try_fmt_vid_out,
1579 .vidioc_reqbufs = vpif_reqbufs,
1580 .vidioc_querybuf = vpif_querybuf,
1581 .vidioc_qbuf = vpif_qbuf,
1582 .vidioc_dqbuf = vpif_dqbuf,
1583 .vidioc_streamon = vpif_streamon,
1584 .vidioc_streamoff = vpif_streamoff,
1585 .vidioc_s_std = vpif_s_std,
1586 .vidioc_g_std = vpif_g_std,
1587 .vidioc_enum_output = vpif_enum_output,
1588 .vidioc_s_output = vpif_s_output,
1589 .vidioc_g_output = vpif_g_output,
1590 .vidioc_cropcap = vpif_cropcap,
1591 .vidioc_enum_dv_presets = vpif_enum_dv_presets,
1592 .vidioc_s_dv_preset = vpif_s_dv_preset,
1593 .vidioc_g_dv_preset = vpif_g_dv_preset,
1594 .vidioc_s_dv_timings = vpif_s_dv_timings,
1595 .vidioc_g_dv_timings = vpif_g_dv_timings,
1596 .vidioc_g_chip_ident = vpif_g_chip_ident,
1597#ifdef CONFIG_VIDEO_ADV_DEBUG
1598 .vidioc_g_register = vpif_dbg_g_register,
1599 .vidioc_s_register = vpif_dbg_s_register,
1600#endif
1601 .vidioc_log_status = vpif_log_status,
1602};
1603
1604static const struct v4l2_file_operations vpif_fops = {
1605 .owner = THIS_MODULE,
1606 .open = vpif_open,
1607 .release = vpif_release,
1608 .unlocked_ioctl = video_ioctl2,
1609 .mmap = vpif_mmap,
1610 .poll = vpif_poll
1611};
1612
1613static struct video_device vpif_video_template = {
1614 .name = "vpif",
1615 .fops = &vpif_fops,
1616 .ioctl_ops = &vpif_ioctl_ops,
1617 .tvnorms = VPIF_V4L2_STD,
1618 .current_norm = V4L2_STD_625_50,
1619
1620};
1621
1622/*Configure the channels, buffer sizei, request irq */
1623static int initialize_vpif(void)
1624{
1625 int free_channel_objects_index;
1626 int free_buffer_channel_index;
1627 int free_buffer_index;
1628 int err = 0, i, j;
1629
1630 /* Default number of buffers should be 3 */
1631 if ((ch2_numbuffers > 0) &&
1632 (ch2_numbuffers < config_params.min_numbuffers))
1633 ch2_numbuffers = config_params.min_numbuffers;
1634 if ((ch3_numbuffers > 0) &&
1635 (ch3_numbuffers < config_params.min_numbuffers))
1636 ch3_numbuffers = config_params.min_numbuffers;
1637
1638 /* Set buffer size to min buffers size if invalid buffer size is
1639 * given */
1640 if (ch2_bufsize < config_params.min_bufsize[VPIF_CHANNEL2_VIDEO])
1641 ch2_bufsize =
1642 config_params.min_bufsize[VPIF_CHANNEL2_VIDEO];
1643 if (ch3_bufsize < config_params.min_bufsize[VPIF_CHANNEL3_VIDEO])
1644 ch3_bufsize =
1645 config_params.min_bufsize[VPIF_CHANNEL3_VIDEO];
1646
1647 config_params.numbuffers[VPIF_CHANNEL2_VIDEO] = ch2_numbuffers;
1648
1649 if (ch2_numbuffers) {
1650 config_params.channel_bufsize[VPIF_CHANNEL2_VIDEO] =
1651 ch2_bufsize;
1652 }
1653 config_params.numbuffers[VPIF_CHANNEL3_VIDEO] = ch3_numbuffers;
1654
1655 if (ch3_numbuffers) {
1656 config_params.channel_bufsize[VPIF_CHANNEL3_VIDEO] =
1657 ch3_bufsize;
1658 }
1659
1660 /* Allocate memory for six channel objects */
1661 for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) {
1662 vpif_obj.dev[i] =
1663 kzalloc(sizeof(struct channel_obj), GFP_KERNEL);
1664 /* If memory allocation fails, return error */
1665 if (!vpif_obj.dev[i]) {
1666 free_channel_objects_index = i;
1667 err = -ENOMEM;
1668 goto vpif_init_free_channel_objects;
1669 }
1670 }
1671
1672 free_channel_objects_index = VPIF_DISPLAY_MAX_DEVICES;
1673 free_buffer_channel_index = VPIF_DISPLAY_NUM_CHANNELS;
1674 free_buffer_index = config_params.numbuffers[i - 1];
1675
1676 return 0;
1677
1678vpif_init_free_channel_objects:
1679 for (j = 0; j < free_channel_objects_index; j++)
1680 kfree(vpif_obj.dev[j]);
1681 return err;
1682}
1683
1684/*
1685 * vpif_probe: This function creates device entries by register itself to the
1686 * V4L2 driver and initializes fields of each channel objects
1687 */
1688static __init int vpif_probe(struct platform_device *pdev)
1689{
1690 struct vpif_subdev_info *subdevdata;
1691 struct vpif_display_config *config;
1692 int i, j = 0, k, q, m, err = 0;
1693 struct i2c_adapter *i2c_adap;
1694 struct common_obj *common;
1695 struct channel_obj *ch;
1696 struct video_device *vfd;
1697 struct resource *res;
1698 int subdev_count;
1699 size_t size;
1700
1701 vpif_dev = &pdev->dev;
1702 err = initialize_vpif();
1703
1704 if (err) {
1705 v4l2_err(vpif_dev->driver, "Error initializing vpif\n");
1706 return err;
1707 }
1708
1709 err = v4l2_device_register(vpif_dev, &vpif_obj.v4l2_dev);
1710 if (err) {
1711 v4l2_err(vpif_dev->driver, "Error registering v4l2 device\n");
1712 return err;
1713 }
1714
1715 k = 0;
1716 while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, k))) {
1717 for (i = res->start; i <= res->end; i++) {
1718 if (request_irq(i, vpif_channel_isr, IRQF_SHARED,
1719 "VPIF_Display",
1720 (void *)(&vpif_obj.dev[k]->channel_id))) {
1721 err = -EBUSY;
1722 goto vpif_int_err;
1723 }
1724 }
1725 k++;
1726 }
1727
1728 for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) {
1729
1730 /* Get the pointer to the channel object */
1731 ch = vpif_obj.dev[i];
1732
1733 /* Allocate memory for video device */
1734 vfd = video_device_alloc();
1735 if (vfd == NULL) {
1736 for (j = 0; j < i; j++) {
1737 ch = vpif_obj.dev[j];
1738 video_device_release(ch->video_dev);
1739 }
1740 err = -ENOMEM;
1741 goto vpif_int_err;
1742 }
1743
1744 /* Initialize field of video device */
1745 *vfd = vpif_video_template;
1746 vfd->v4l2_dev = &vpif_obj.v4l2_dev;
1747 vfd->release = video_device_release;
1748 snprintf(vfd->name, sizeof(vfd->name),
1749 "VPIF_Display_DRIVER_V%s",
1750 VPIF_DISPLAY_VERSION);
1751
1752 /* Set video_dev to the video device */
1753 ch->video_dev = vfd;
1754 }
1755
1756 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1757 if (res) {
1758 size = resource_size(res);
1759 /* The resources are divided into two equal memory and when
1760 * we have HD output we can add them together
1761 */
1762 for (j = 0; j < VPIF_DISPLAY_MAX_DEVICES; j++) {
1763 ch = vpif_obj.dev[j];
1764 ch->channel_id = j;
1765
1766 /* only enabled if second resource exists */
1767 config_params.video_limit[ch->channel_id] = 0;
1768 if (size)
1769 config_params.video_limit[ch->channel_id] =
1770 size/2;
1771 }
1772 }
1773
1774 for (j = 0; j < VPIF_DISPLAY_MAX_DEVICES; j++) {
1775 ch = vpif_obj.dev[j];
1776 /* Initialize field of the channel objects */
1777 atomic_set(&ch->usrs, 0);
1778 for (k = 0; k < VPIF_NUMOBJECTS; k++) {
1779 ch->common[k].numbuffers = 0;
1780 common = &ch->common[k];
1781 common->io_usrs = 0;
1782 common->started = 0;
1783 spin_lock_init(&common->irqlock);
1784 mutex_init(&common->lock);
1785 common->numbuffers = 0;
1786 common->set_addr = NULL;
1787 common->ytop_off = common->ybtm_off = 0;
1788 common->ctop_off = common->cbtm_off = 0;
1789 common->cur_frm = common->next_frm = NULL;
1790 memset(&common->fmt, 0, sizeof(common->fmt));
1791 common->numbuffers = config_params.numbuffers[k];
1792
1793 }
1794 ch->initialized = 0;
1795 ch->channel_id = j;
1796 if (j < 2)
1797 ch->common[VPIF_VIDEO_INDEX].numbuffers =
1798 config_params.numbuffers[ch->channel_id];
1799 else
1800 ch->common[VPIF_VIDEO_INDEX].numbuffers = 0;
1801
1802 memset(&ch->vpifparams, 0, sizeof(ch->vpifparams));
1803
1804 /* Initialize prio member of channel object */
1805 v4l2_prio_init(&ch->prio);
1806 ch->common[VPIF_VIDEO_INDEX].fmt.type =
1807 V4L2_BUF_TYPE_VIDEO_OUTPUT;
1808 ch->video_dev->lock = &common->lock;
1809
1810 /* register video device */
1811 vpif_dbg(1, debug, "channel=%x,channel->video_dev=%x\n",
1812 (int)ch, (int)&ch->video_dev);
1813
1814 err = video_register_device(ch->video_dev,
1815 VFL_TYPE_GRABBER, (j ? 3 : 2));
1816 if (err < 0)
1817 goto probe_out;
1818
1819 video_set_drvdata(ch->video_dev, ch);
1820 }
1821
1822 i2c_adap = i2c_get_adapter(1);
1823 config = pdev->dev.platform_data;
1824 subdev_count = config->subdev_count;
1825 subdevdata = config->subdevinfo;
1826 vpif_obj.sd = kzalloc(sizeof(struct v4l2_subdev *) * subdev_count,
1827 GFP_KERNEL);
1828 if (vpif_obj.sd == NULL) {
1829 vpif_err("unable to allocate memory for subdevice pointers\n");
1830 err = -ENOMEM;
1831 goto probe_out;
1832 }
1833
1834 for (i = 0; i < subdev_count; i++) {
1835 vpif_obj.sd[i] = v4l2_i2c_new_subdev_board(&vpif_obj.v4l2_dev,
1836 i2c_adap,
1837 &subdevdata[i].board_info,
1838 NULL);
1839 if (!vpif_obj.sd[i]) {
1840 vpif_err("Error registering v4l2 subdevice\n");
1841 goto probe_subdev_out;
1842 }
1843
1844 if (vpif_obj.sd[i])
1845 vpif_obj.sd[i]->grp_id = 1 << i;
1846 }
1847
1848 v4l2_info(&vpif_obj.v4l2_dev,
1849 " VPIF display driver initialized\n");
1850 return 0;
1851
1852probe_subdev_out:
1853 kfree(vpif_obj.sd);
1854probe_out:
1855 for (k = 0; k < j; k++) {
1856 ch = vpif_obj.dev[k];
1857 video_unregister_device(ch->video_dev);
1858 video_device_release(ch->video_dev);
1859 ch->video_dev = NULL;
1860 }
1861vpif_int_err:
1862 v4l2_device_unregister(&vpif_obj.v4l2_dev);
1863 vpif_err("VPIF IRQ request failed\n");
1864 for (q = k; k >= 0; k--) {
1865 for (m = i; m >= res->start; m--)
1866 free_irq(m, (void *)(&vpif_obj.dev[k]->channel_id));
1867 res = platform_get_resource(pdev, IORESOURCE_IRQ, k-1);
1868 m = res->end;
1869 }
1870
1871 return err;
1872}
1873
1874/*
1875 * vpif_remove: It un-register channels from V4L2 driver
1876 */
1877static int vpif_remove(struct platform_device *device)
1878{
1879 struct channel_obj *ch;
1880 int i;
1881
1882 v4l2_device_unregister(&vpif_obj.v4l2_dev);
1883
1884 /* un-register device */
1885 for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) {
1886 /* Get the pointer to the channel object */
1887 ch = vpif_obj.dev[i];
1888 /* Unregister video device */
1889 video_unregister_device(ch->video_dev);
1890
1891 ch->video_dev = NULL;
1892 }
1893
1894 return 0;
1895}
1896
1897#ifdef CONFIG_PM
1898static int vpif_suspend(struct device *dev)
1899{
1900 struct common_obj *common;
1901 struct channel_obj *ch;
1902 int i;
1903
1904 for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) {
1905 /* Get the pointer to the channel object */
1906 ch = vpif_obj.dev[i];
1907 common = &ch->common[VPIF_VIDEO_INDEX];
1908 mutex_lock(&common->lock);
1909 if (atomic_read(&ch->usrs) && common->io_usrs) {
1910 /* Disable channel */
1911 if (ch->channel_id == VPIF_CHANNEL2_VIDEO) {
1912 enable_channel2(0);
1913 channel2_intr_enable(0);
1914 }
1915 if (ch->channel_id == VPIF_CHANNEL3_VIDEO ||
1916 common->started == 2) {
1917 enable_channel3(0);
1918 channel3_intr_enable(0);
1919 }
1920 }
1921 mutex_unlock(&common->lock);
1922 }
1923
1924 return 0;
1925}
1926
1927static int vpif_resume(struct device *dev)
1928{
1929
1930 struct common_obj *common;
1931 struct channel_obj *ch;
1932 int i;
1933
1934 for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) {
1935 /* Get the pointer to the channel object */
1936 ch = vpif_obj.dev[i];
1937 common = &ch->common[VPIF_VIDEO_INDEX];
1938 mutex_lock(&common->lock);
1939 if (atomic_read(&ch->usrs) && common->io_usrs) {
1940 /* Enable channel */
1941 if (ch->channel_id == VPIF_CHANNEL2_VIDEO) {
1942 enable_channel2(1);
1943 channel2_intr_enable(1);
1944 }
1945 if (ch->channel_id == VPIF_CHANNEL3_VIDEO ||
1946 common->started == 2) {
1947 enable_channel3(1);
1948 channel3_intr_enable(1);
1949 }
1950 }
1951 mutex_unlock(&common->lock);
1952 }
1953
1954 return 0;
1955}
1956
1957static const struct dev_pm_ops vpif_pm = {
1958 .suspend = vpif_suspend,
1959 .resume = vpif_resume,
1960};
1961
1962#define vpif_pm_ops (&vpif_pm)
1963#else
1964#define vpif_pm_ops NULL
1965#endif
1966
1967static __refdata struct platform_driver vpif_driver = {
1968 .driver = {
1969 .name = "vpif_display",
1970 .owner = THIS_MODULE,
1971 .pm = vpif_pm_ops,
1972 },
1973 .probe = vpif_probe,
1974 .remove = vpif_remove,
1975};
1976
1977static __init int vpif_init(void)
1978{
1979 return platform_driver_register(&vpif_driver);
1980}
1981
1982/*
1983 * vpif_cleanup: This function un-registers device and driver to the kernel,
1984 * frees requested irq handler and de-allocates memory allocated for channel
1985 * objects.
1986 */
1987static void vpif_cleanup(void)
1988{
1989 struct platform_device *pdev;
1990 struct resource *res;
1991 int irq_num;
1992 int i = 0;
1993
1994 pdev = container_of(vpif_dev, struct platform_device, dev);
1995
1996 while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, i))) {
1997 for (irq_num = res->start; irq_num <= res->end; irq_num++)
1998 free_irq(irq_num,
1999 (void *)(&vpif_obj.dev[i]->channel_id));
2000 i++;
2001 }
2002
2003 platform_driver_unregister(&vpif_driver);
2004 kfree(vpif_obj.sd);
2005 for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++)
2006 kfree(vpif_obj.dev[i]);
2007}
2008
2009module_init(vpif_init);
2010module_exit(vpif_cleanup);
diff --git a/drivers/media/video/davinci/vpif_display.h b/drivers/media/video/davinci/vpif_display.h
deleted file mode 100644
index 8967ffb44058..000000000000
--- a/drivers/media/video/davinci/vpif_display.h
+++ /dev/null
@@ -1,181 +0,0 @@
1/*
2 * VPIF display header file
3 *
4 * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation version 2.
9 *
10 * This program is distributed .as is. WITHOUT ANY WARRANTY of any
11 * kind, whether express or implied; without even the implied warranty
12 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#ifndef DAVINCIHD_DISPLAY_H
17#define DAVINCIHD_DISPLAY_H
18
19/* Header files */
20#include <linux/videodev2.h>
21#include <media/v4l2-common.h>
22#include <media/v4l2-device.h>
23#include <media/videobuf-core.h>
24#include <media/videobuf2-dma-contig.h>
25#include <media/davinci/vpif_types.h>
26
27#include "vpif.h"
28
29/* Macros */
30#define VPIF_DISPLAY_VERSION "0.0.2"
31
32#define VPIF_VALID_FIELD(field) \
33 (((V4L2_FIELD_ANY == field) || (V4L2_FIELD_NONE == field)) || \
34 (((V4L2_FIELD_INTERLACED == field) || (V4L2_FIELD_SEQ_TB == field)) || \
35 (V4L2_FIELD_SEQ_BT == field)))
36
37#define VPIF_DISPLAY_MAX_DEVICES (2)
38#define VPIF_SLICED_BUF_SIZE (256)
39#define VPIF_SLICED_MAX_SERVICES (3)
40#define VPIF_VIDEO_INDEX (0)
41#define VPIF_VBI_INDEX (1)
42#define VPIF_HBI_INDEX (2)
43
44/* Setting it to 1 as HBI/VBI support yet to be added , else 3*/
45#define VPIF_NUMOBJECTS (1)
46
47/* Macros */
48#define ISALIGNED(a) (0 == ((a) & 7))
49
50/* enumerated data types */
51/* Enumerated data type to give id to each device per channel */
52enum vpif_channel_id {
53 VPIF_CHANNEL2_VIDEO = 0, /* Channel2 Video */
54 VPIF_CHANNEL3_VIDEO, /* Channel3 Video */
55};
56
57/* structures */
58
59struct video_obj {
60 enum v4l2_field buf_field;
61 u32 latest_only; /* indicate whether to return
62 * most recent displayed frame only */
63 v4l2_std_id stdid; /* Currently selected or default
64 * standard */
65 u32 dv_preset;
66 struct v4l2_bt_timings bt_timings;
67 u32 output_id; /* Current output id */
68};
69
70struct vbi_obj {
71 int num_services;
72 struct vpif_vbi_params vbiparams; /* vpif parameters for the raw
73 * vbi data */
74};
75
76struct vpif_disp_buffer {
77 struct vb2_buffer vb;
78 struct list_head list;
79};
80
81struct common_obj {
82 /* Buffer specific parameters */
83 u8 *fbuffers[VIDEO_MAX_FRAME]; /* List of buffer pointers for
84 * storing frames */
85 u32 numbuffers; /* number of buffers */
86 struct vpif_disp_buffer *cur_frm; /* Pointer pointing to current
87 * vb2_buffer */
88 struct vpif_disp_buffer *next_frm; /* Pointer pointing to next
89 * vb2_buffer */
90 enum v4l2_memory memory; /* This field keeps track of
91 * type of buffer exchange
92 * method user has selected */
93 struct v4l2_format fmt; /* Used to store the format */
94 struct vb2_queue buffer_queue; /* Buffer queue used in
95 * video-buf */
96 /* allocator-specific contexts for each plane */
97 struct vb2_alloc_ctx *alloc_ctx;
98
99 struct list_head dma_queue; /* Queue of filled frames */
100 spinlock_t irqlock; /* Used in video-buf */
101
102 /* channel specific parameters */
103 struct mutex lock; /* lock used to access this
104 * structure */
105 u32 io_usrs; /* number of users performing
106 * IO */
107 u8 started; /* Indicates whether streaming
108 * started */
109 u32 ytop_off; /* offset of Y top from the
110 * starting of the buffer */
111 u32 ybtm_off; /* offset of Y bottom from the
112 * starting of the buffer */
113 u32 ctop_off; /* offset of C top from the
114 * starting of the buffer */
115 u32 cbtm_off; /* offset of C bottom from the
116 * starting of the buffer */
117 /* Function pointer to set the addresses */
118 void (*set_addr) (unsigned long, unsigned long,
119 unsigned long, unsigned long);
120 u32 height;
121 u32 width;
122};
123
124struct channel_obj {
125 /* V4l2 specific parameters */
126 struct video_device *video_dev; /* Identifies video device for
127 * this channel */
128 struct v4l2_prio_state prio; /* Used to keep track of state of
129 * the priority */
130 atomic_t usrs; /* number of open instances of
131 * the channel */
132 u32 field_id; /* Indicates id of the field
133 * which is being displayed */
134 u8 initialized; /* flag to indicate whether
135 * encoder is initialized */
136
137 enum vpif_channel_id channel_id;/* Identifies channel */
138 struct vpif_params vpifparams;
139 struct common_obj common[VPIF_NUMOBJECTS];
140 struct video_obj video;
141 struct vbi_obj vbi;
142};
143
144/* File handle structure */
145struct vpif_fh {
146 struct channel_obj *channel; /* pointer to channel object for
147 * opened device */
148 u8 io_allowed[VPIF_NUMOBJECTS]; /* Indicates whether this file handle
149 * is doing IO */
150 enum v4l2_priority prio; /* Used to keep track priority of
151 * this instance */
152 u8 initialized; /* Used to keep track of whether this
153 * file handle has initialized
154 * channel or not */
155};
156
157/* vpif device structure */
158struct vpif_device {
159 struct v4l2_device v4l2_dev;
160 struct channel_obj *dev[VPIF_DISPLAY_NUM_CHANNELS];
161 struct v4l2_subdev **sd;
162
163};
164
165struct vpif_config_params {
166 u32 min_bufsize[VPIF_DISPLAY_NUM_CHANNELS];
167 u32 channel_bufsize[VPIF_DISPLAY_NUM_CHANNELS];
168 u8 numbuffers[VPIF_DISPLAY_NUM_CHANNELS];
169 u32 video_limit[VPIF_DISPLAY_NUM_CHANNELS];
170 u8 min_numbuffers;
171};
172
173/* Struct which keeps track of the line numbers for the sliced vbi service */
174struct vpif_service_line {
175 u16 service_id;
176 u16 service_line[2];
177 u16 enc_service_id;
178 u8 bytestowrite;
179};
180
181#endif /* DAVINCIHD_DISPLAY_H */
diff --git a/drivers/media/video/davinci/vpss.c b/drivers/media/video/davinci/vpss.c
deleted file mode 100644
index 146e4b01ac17..000000000000
--- a/drivers/media/video/davinci/vpss.c
+++ /dev/null
@@ -1,482 +0,0 @@
1/*
2 * Copyright (C) 2009 Texas Instruments.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 *
18 * common vpss system module platform driver for all video drivers.
19 */
20#include <linux/kernel.h>
21#include <linux/sched.h>
22#include <linux/init.h>
23#include <linux/module.h>
24#include <linux/platform_device.h>
25#include <linux/spinlock.h>
26#include <linux/compiler.h>
27#include <linux/io.h>
28#include <mach/hardware.h>
29#include <media/davinci/vpss.h>
30
31MODULE_LICENSE("GPL");
32MODULE_DESCRIPTION("VPSS Driver");
33MODULE_AUTHOR("Texas Instruments");
34
35/* DM644x defines */
36#define DM644X_SBL_PCR_VPSS (4)
37
38#define DM355_VPSSBL_INTSEL 0x10
39#define DM355_VPSSBL_EVTSEL 0x14
40/* vpss BL register offsets */
41#define DM355_VPSSBL_CCDCMUX 0x1c
42/* vpss CLK register offsets */
43#define DM355_VPSSCLK_CLKCTRL 0x04
44/* masks and shifts */
45#define VPSS_HSSISEL_SHIFT 4
46/*
47 * VDINT0 - vpss_int0, VDINT1 - vpss_int1, H3A - vpss_int4,
48 * IPIPE_INT1_SDR - vpss_int5
49 */
50#define DM355_VPSSBL_INTSEL_DEFAULT 0xff83ff10
51/* VENCINT - vpss_int8 */
52#define DM355_VPSSBL_EVTSEL_DEFAULT 0x4
53
54#define DM365_ISP5_PCCR 0x04
55#define DM365_ISP5_INTSEL1 0x10
56#define DM365_ISP5_INTSEL2 0x14
57#define DM365_ISP5_INTSEL3 0x18
58#define DM365_ISP5_CCDCMUX 0x20
59#define DM365_ISP5_PG_FRAME_SIZE 0x28
60#define DM365_VPBE_CLK_CTRL 0x00
61/*
62 * vpss interrupts. VDINT0 - vpss_int0, VDINT1 - vpss_int1,
63 * AF - vpss_int3
64 */
65#define DM365_ISP5_INTSEL1_DEFAULT 0x0b1f0100
66/* AEW - vpss_int6, RSZ_INT_DMA - vpss_int5 */
67#define DM365_ISP5_INTSEL2_DEFAULT 0x1f0a0f1f
68/* VENC - vpss_int8 */
69#define DM365_ISP5_INTSEL3_DEFAULT 0x00000015
70
71/* masks and shifts for DM365*/
72#define DM365_CCDC_PG_VD_POL_SHIFT 0
73#define DM365_CCDC_PG_HD_POL_SHIFT 1
74
75#define CCD_SRC_SEL_MASK (BIT_MASK(5) | BIT_MASK(4))
76#define CCD_SRC_SEL_SHIFT 4
77
78/* Different SoC platforms supported by this driver */
79enum vpss_platform_type {
80 DM644X,
81 DM355,
82 DM365,
83};
84
85/*
86 * vpss operations. Depends on platform. Not all functions are available
87 * on all platforms. The api, first check if a functio is available before
88 * invoking it. In the probe, the function ptrs are initialized based on
89 * vpss name. vpss name can be "dm355_vpss", "dm644x_vpss" etc.
90 */
91struct vpss_hw_ops {
92 /* enable clock */
93 int (*enable_clock)(enum vpss_clock_sel clock_sel, int en);
94 /* select input to ccdc */
95 void (*select_ccdc_source)(enum vpss_ccdc_source_sel src_sel);
96 /* clear wbl overflow bit */
97 int (*clear_wbl_overflow)(enum vpss_wbl_sel wbl_sel);
98};
99
100/* vpss configuration */
101struct vpss_oper_config {
102 __iomem void *vpss_regs_base0;
103 __iomem void *vpss_regs_base1;
104 enum vpss_platform_type platform;
105 spinlock_t vpss_lock;
106 struct vpss_hw_ops hw_ops;
107};
108
109static struct vpss_oper_config oper_cfg;
110
111/* register access routines */
112static inline u32 bl_regr(u32 offset)
113{
114 return __raw_readl(oper_cfg.vpss_regs_base0 + offset);
115}
116
117static inline void bl_regw(u32 val, u32 offset)
118{
119 __raw_writel(val, oper_cfg.vpss_regs_base0 + offset);
120}
121
122static inline u32 vpss_regr(u32 offset)
123{
124 return __raw_readl(oper_cfg.vpss_regs_base1 + offset);
125}
126
127static inline void vpss_regw(u32 val, u32 offset)
128{
129 __raw_writel(val, oper_cfg.vpss_regs_base1 + offset);
130}
131
132/* For DM365 only */
133static inline u32 isp5_read(u32 offset)
134{
135 return __raw_readl(oper_cfg.vpss_regs_base0 + offset);
136}
137
138/* For DM365 only */
139static inline void isp5_write(u32 val, u32 offset)
140{
141 __raw_writel(val, oper_cfg.vpss_regs_base0 + offset);
142}
143
144static void dm365_select_ccdc_source(enum vpss_ccdc_source_sel src_sel)
145{
146 u32 temp = isp5_read(DM365_ISP5_CCDCMUX) & ~CCD_SRC_SEL_MASK;
147
148 /* if we are using pattern generator, enable it */
149 if (src_sel == VPSS_PGLPBK || src_sel == VPSS_CCDCPG)
150 temp |= 0x08;
151
152 temp |= (src_sel << CCD_SRC_SEL_SHIFT);
153 isp5_write(temp, DM365_ISP5_CCDCMUX);
154}
155
156static void dm355_select_ccdc_source(enum vpss_ccdc_source_sel src_sel)
157{
158 bl_regw(src_sel << VPSS_HSSISEL_SHIFT, DM355_VPSSBL_CCDCMUX);
159}
160
161int vpss_select_ccdc_source(enum vpss_ccdc_source_sel src_sel)
162{
163 if (!oper_cfg.hw_ops.select_ccdc_source)
164 return -EINVAL;
165
166 oper_cfg.hw_ops.select_ccdc_source(src_sel);
167 return 0;
168}
169EXPORT_SYMBOL(vpss_select_ccdc_source);
170
171static int dm644x_clear_wbl_overflow(enum vpss_wbl_sel wbl_sel)
172{
173 u32 mask = 1, val;
174
175 if (wbl_sel < VPSS_PCR_AEW_WBL_0 ||
176 wbl_sel > VPSS_PCR_CCDC_WBL_O)
177 return -EINVAL;
178
179 /* writing a 0 clear the overflow */
180 mask = ~(mask << wbl_sel);
181 val = bl_regr(DM644X_SBL_PCR_VPSS) & mask;
182 bl_regw(val, DM644X_SBL_PCR_VPSS);
183 return 0;
184}
185
186int vpss_clear_wbl_overflow(enum vpss_wbl_sel wbl_sel)
187{
188 if (!oper_cfg.hw_ops.clear_wbl_overflow)
189 return -EINVAL;
190
191 return oper_cfg.hw_ops.clear_wbl_overflow(wbl_sel);
192}
193EXPORT_SYMBOL(vpss_clear_wbl_overflow);
194
195/*
196 * dm355_enable_clock - Enable VPSS Clock
197 * @clock_sel: CLock to be enabled/disabled
198 * @en: enable/disable flag
199 *
200 * This is called to enable or disable a vpss clock
201 */
202static int dm355_enable_clock(enum vpss_clock_sel clock_sel, int en)
203{
204 unsigned long flags;
205 u32 utemp, mask = 0x1, shift = 0;
206
207 switch (clock_sel) {
208 case VPSS_VPBE_CLOCK:
209 /* nothing since lsb */
210 break;
211 case VPSS_VENC_CLOCK_SEL:
212 shift = 2;
213 break;
214 case VPSS_CFALD_CLOCK:
215 shift = 3;
216 break;
217 case VPSS_H3A_CLOCK:
218 shift = 4;
219 break;
220 case VPSS_IPIPE_CLOCK:
221 shift = 5;
222 break;
223 case VPSS_CCDC_CLOCK:
224 shift = 6;
225 break;
226 default:
227 printk(KERN_ERR "dm355_enable_clock:"
228 " Invalid selector: %d\n", clock_sel);
229 return -EINVAL;
230 }
231
232 spin_lock_irqsave(&oper_cfg.vpss_lock, flags);
233 utemp = vpss_regr(DM355_VPSSCLK_CLKCTRL);
234 if (!en)
235 utemp &= ~(mask << shift);
236 else
237 utemp |= (mask << shift);
238
239 vpss_regw(utemp, DM355_VPSSCLK_CLKCTRL);
240 spin_unlock_irqrestore(&oper_cfg.vpss_lock, flags);
241 return 0;
242}
243
244static int dm365_enable_clock(enum vpss_clock_sel clock_sel, int en)
245{
246 unsigned long flags;
247 u32 utemp, mask = 0x1, shift = 0, offset = DM365_ISP5_PCCR;
248 u32 (*read)(u32 offset) = isp5_read;
249 void(*write)(u32 val, u32 offset) = isp5_write;
250
251 switch (clock_sel) {
252 case VPSS_BL_CLOCK:
253 break;
254 case VPSS_CCDC_CLOCK:
255 shift = 1;
256 break;
257 case VPSS_H3A_CLOCK:
258 shift = 2;
259 break;
260 case VPSS_RSZ_CLOCK:
261 shift = 3;
262 break;
263 case VPSS_IPIPE_CLOCK:
264 shift = 4;
265 break;
266 case VPSS_IPIPEIF_CLOCK:
267 shift = 5;
268 break;
269 case VPSS_PCLK_INTERNAL:
270 shift = 6;
271 break;
272 case VPSS_PSYNC_CLOCK_SEL:
273 shift = 7;
274 break;
275 case VPSS_VPBE_CLOCK:
276 read = vpss_regr;
277 write = vpss_regw;
278 offset = DM365_VPBE_CLK_CTRL;
279 break;
280 case VPSS_VENC_CLOCK_SEL:
281 shift = 2;
282 read = vpss_regr;
283 write = vpss_regw;
284 offset = DM365_VPBE_CLK_CTRL;
285 break;
286 case VPSS_LDC_CLOCK:
287 shift = 3;
288 read = vpss_regr;
289 write = vpss_regw;
290 offset = DM365_VPBE_CLK_CTRL;
291 break;
292 case VPSS_FDIF_CLOCK:
293 shift = 4;
294 read = vpss_regr;
295 write = vpss_regw;
296 offset = DM365_VPBE_CLK_CTRL;
297 break;
298 case VPSS_OSD_CLOCK_SEL:
299 shift = 6;
300 read = vpss_regr;
301 write = vpss_regw;
302 offset = DM365_VPBE_CLK_CTRL;
303 break;
304 case VPSS_LDC_CLOCK_SEL:
305 shift = 7;
306 read = vpss_regr;
307 write = vpss_regw;
308 offset = DM365_VPBE_CLK_CTRL;
309 break;
310 default:
311 printk(KERN_ERR "dm365_enable_clock: Invalid selector: %d\n",
312 clock_sel);
313 return -1;
314 }
315
316 spin_lock_irqsave(&oper_cfg.vpss_lock, flags);
317 utemp = read(offset);
318 if (!en) {
319 mask = ~mask;
320 utemp &= (mask << shift);
321 } else
322 utemp |= (mask << shift);
323
324 write(utemp, offset);
325 spin_unlock_irqrestore(&oper_cfg.vpss_lock, flags);
326
327 return 0;
328}
329
330int vpss_enable_clock(enum vpss_clock_sel clock_sel, int en)
331{
332 if (!oper_cfg.hw_ops.enable_clock)
333 return -EINVAL;
334
335 return oper_cfg.hw_ops.enable_clock(clock_sel, en);
336}
337EXPORT_SYMBOL(vpss_enable_clock);
338
339void dm365_vpss_set_sync_pol(struct vpss_sync_pol sync)
340{
341 int val = 0;
342 val = isp5_read(DM365_ISP5_CCDCMUX);
343
344 val |= (sync.ccdpg_hdpol << DM365_CCDC_PG_HD_POL_SHIFT);
345 val |= (sync.ccdpg_vdpol << DM365_CCDC_PG_VD_POL_SHIFT);
346
347 isp5_write(val, DM365_ISP5_CCDCMUX);
348}
349EXPORT_SYMBOL(dm365_vpss_set_sync_pol);
350
351void dm365_vpss_set_pg_frame_size(struct vpss_pg_frame_size frame_size)
352{
353 int current_reg = ((frame_size.hlpfr >> 1) - 1) << 16;
354
355 current_reg |= (frame_size.pplen - 1);
356 isp5_write(current_reg, DM365_ISP5_PG_FRAME_SIZE);
357}
358EXPORT_SYMBOL(dm365_vpss_set_pg_frame_size);
359
360static int __devinit vpss_probe(struct platform_device *pdev)
361{
362 struct resource *r1, *r2;
363 char *platform_name;
364 int status;
365
366 if (!pdev->dev.platform_data) {
367 dev_err(&pdev->dev, "no platform data\n");
368 return -ENOENT;
369 }
370
371 platform_name = pdev->dev.platform_data;
372 if (!strcmp(platform_name, "dm355_vpss"))
373 oper_cfg.platform = DM355;
374 else if (!strcmp(platform_name, "dm365_vpss"))
375 oper_cfg.platform = DM365;
376 else if (!strcmp(platform_name, "dm644x_vpss"))
377 oper_cfg.platform = DM644X;
378 else {
379 dev_err(&pdev->dev, "vpss driver not supported on"
380 " this platform\n");
381 return -ENODEV;
382 }
383
384 dev_info(&pdev->dev, "%s vpss probed\n", platform_name);
385 r1 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
386 if (!r1)
387 return -ENOENT;
388
389 r1 = request_mem_region(r1->start, resource_size(r1), r1->name);
390 if (!r1)
391 return -EBUSY;
392
393 oper_cfg.vpss_regs_base0 = ioremap(r1->start, resource_size(r1));
394 if (!oper_cfg.vpss_regs_base0) {
395 status = -EBUSY;
396 goto fail1;
397 }
398
399 if (oper_cfg.platform == DM355 || oper_cfg.platform == DM365) {
400 r2 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
401 if (!r2) {
402 status = -ENOENT;
403 goto fail2;
404 }
405 r2 = request_mem_region(r2->start, resource_size(r2), r2->name);
406 if (!r2) {
407 status = -EBUSY;
408 goto fail2;
409 }
410
411 oper_cfg.vpss_regs_base1 = ioremap(r2->start,
412 resource_size(r2));
413 if (!oper_cfg.vpss_regs_base1) {
414 status = -EBUSY;
415 goto fail3;
416 }
417 }
418
419 if (oper_cfg.platform == DM355) {
420 oper_cfg.hw_ops.enable_clock = dm355_enable_clock;
421 oper_cfg.hw_ops.select_ccdc_source = dm355_select_ccdc_source;
422 /* Setup vpss interrupts */
423 bl_regw(DM355_VPSSBL_INTSEL_DEFAULT, DM355_VPSSBL_INTSEL);
424 bl_regw(DM355_VPSSBL_EVTSEL_DEFAULT, DM355_VPSSBL_EVTSEL);
425 } else if (oper_cfg.platform == DM365) {
426 oper_cfg.hw_ops.enable_clock = dm365_enable_clock;
427 oper_cfg.hw_ops.select_ccdc_source = dm365_select_ccdc_source;
428 /* Setup vpss interrupts */
429 isp5_write(DM365_ISP5_INTSEL1_DEFAULT, DM365_ISP5_INTSEL1);
430 isp5_write(DM365_ISP5_INTSEL2_DEFAULT, DM365_ISP5_INTSEL2);
431 isp5_write(DM365_ISP5_INTSEL3_DEFAULT, DM365_ISP5_INTSEL3);
432 } else
433 oper_cfg.hw_ops.clear_wbl_overflow = dm644x_clear_wbl_overflow;
434
435 spin_lock_init(&oper_cfg.vpss_lock);
436 dev_info(&pdev->dev, "%s vpss probe success\n", platform_name);
437 return 0;
438
439fail3:
440 release_mem_region(r2->start, resource_size(r2));
441fail2:
442 iounmap(oper_cfg.vpss_regs_base0);
443fail1:
444 release_mem_region(r1->start, resource_size(r1));
445 return status;
446}
447
448static int __devexit vpss_remove(struct platform_device *pdev)
449{
450 struct resource *res;
451
452 iounmap(oper_cfg.vpss_regs_base0);
453 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
454 release_mem_region(res->start, resource_size(res));
455 if (oper_cfg.platform == DM355 || oper_cfg.platform == DM365) {
456 iounmap(oper_cfg.vpss_regs_base1);
457 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
458 release_mem_region(res->start, resource_size(res));
459 }
460 return 0;
461}
462
463static struct platform_driver vpss_driver = {
464 .driver = {
465 .name = "vpss",
466 .owner = THIS_MODULE,
467 },
468 .remove = __devexit_p(vpss_remove),
469 .probe = vpss_probe,
470};
471
472static void vpss_exit(void)
473{
474 platform_driver_unregister(&vpss_driver);
475}
476
477static int __init vpss_init(void)
478{
479 return platform_driver_register(&vpss_driver);
480}
481subsys_initcall(vpss_init);
482module_exit(vpss_exit);
diff --git a/drivers/media/video/fsl-viu.c b/drivers/media/video/fsl-viu.c
deleted file mode 100644
index 20f981008faf..000000000000
--- a/drivers/media/video/fsl-viu.c
+++ /dev/null
@@ -1,1690 +0,0 @@
1/*
2 * Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved.
3 *
4 * Freescale VIU video driver
5 *
6 * Authors: Hongjun Chen <hong-jun.chen@freescale.com>
7 * Porting to 2.6.35 by DENX Software Engineering,
8 * Anatolij Gustschin <agust@denx.de>
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 *
15 */
16
17#include <linux/module.h>
18#include <linux/clk.h>
19#include <linux/kernel.h>
20#include <linux/i2c.h>
21#include <linux/init.h>
22#include <linux/interrupt.h>
23#include <linux/io.h>
24#include <linux/of_platform.h>
25#include <linux/slab.h>
26#include <media/v4l2-common.h>
27#include <media/v4l2-device.h>
28#include <media/v4l2-ioctl.h>
29#include <media/videobuf-dma-contig.h>
30
31#define DRV_NAME "fsl_viu"
32#define VIU_VERSION "0.5.1"
33
34#define BUFFER_TIMEOUT msecs_to_jiffies(500) /* 0.5 seconds */
35
36#define VIU_VID_MEM_LIMIT 4 /* Video memory limit, in Mb */
37
38/* I2C address of video decoder chip is 0x4A */
39#define VIU_VIDEO_DECODER_ADDR 0x25
40
41/* supported controls */
42static struct v4l2_queryctrl viu_qctrl[] = {
43 {
44 .id = V4L2_CID_BRIGHTNESS,
45 .type = V4L2_CTRL_TYPE_INTEGER,
46 .name = "Brightness",
47 .minimum = 0,
48 .maximum = 255,
49 .step = 1,
50 .default_value = 127,
51 .flags = 0,
52 }, {
53 .id = V4L2_CID_CONTRAST,
54 .type = V4L2_CTRL_TYPE_INTEGER,
55 .name = "Contrast",
56 .minimum = 0,
57 .maximum = 255,
58 .step = 0x1,
59 .default_value = 0x10,
60 .flags = 0,
61 }, {
62 .id = V4L2_CID_SATURATION,
63 .type = V4L2_CTRL_TYPE_INTEGER,
64 .name = "Saturation",
65 .minimum = 0,
66 .maximum = 255,
67 .step = 0x1,
68 .default_value = 127,
69 .flags = 0,
70 }, {
71 .id = V4L2_CID_HUE,
72 .type = V4L2_CTRL_TYPE_INTEGER,
73 .name = "Hue",
74 .minimum = -128,
75 .maximum = 127,
76 .step = 0x1,
77 .default_value = 0,
78 .flags = 0,
79 }
80};
81
82static int qctl_regs[ARRAY_SIZE(viu_qctrl)];
83
84static int info_level;
85
86#define dprintk(level, fmt, arg...) \
87 do { \
88 if (level <= info_level) \
89 printk(KERN_DEBUG "viu: " fmt , ## arg); \
90 } while (0)
91
92/*
93 * Basic structures
94 */
95struct viu_fmt {
96 char name[32];
97 u32 fourcc; /* v4l2 format id */
98 u32 pixelformat;
99 int depth;
100};
101
102static struct viu_fmt formats[] = {
103 {
104 .name = "RGB-16 (5/B-6/G-5/R)",
105 .fourcc = V4L2_PIX_FMT_RGB565,
106 .pixelformat = V4L2_PIX_FMT_RGB565,
107 .depth = 16,
108 }, {
109 .name = "RGB-32 (A-R-G-B)",
110 .fourcc = V4L2_PIX_FMT_RGB32,
111 .pixelformat = V4L2_PIX_FMT_RGB32,
112 .depth = 32,
113 }
114};
115
116struct viu_dev;
117struct viu_buf;
118
119/* buffer for one video frame */
120struct viu_buf {
121 /* common v4l buffer stuff -- must be first */
122 struct videobuf_buffer vb;
123 struct viu_fmt *fmt;
124};
125
126struct viu_dmaqueue {
127 struct viu_dev *dev;
128 struct list_head active;
129 struct list_head queued;
130 struct timer_list timeout;
131};
132
133struct viu_status {
134 u32 field_irq;
135 u32 vsync_irq;
136 u32 hsync_irq;
137 u32 vstart_irq;
138 u32 dma_end_irq;
139 u32 error_irq;
140};
141
142struct viu_reg {
143 u32 status_cfg;
144 u32 luminance;
145 u32 chroma_r;
146 u32 chroma_g;
147 u32 chroma_b;
148 u32 field_base_addr;
149 u32 dma_inc;
150 u32 picture_count;
151 u32 req_alarm;
152 u32 alpha;
153} __attribute__ ((packed));
154
155struct viu_dev {
156 struct v4l2_device v4l2_dev;
157 struct mutex lock;
158 spinlock_t slock;
159 int users;
160
161 struct device *dev;
162 /* various device info */
163 struct video_device *vdev;
164 struct viu_dmaqueue vidq;
165 enum v4l2_field capfield;
166 int field;
167 int first;
168 int dma_done;
169
170 /* Hardware register area */
171 struct viu_reg *vr;
172
173 /* Interrupt vector */
174 int irq;
175 struct viu_status irqs;
176
177 /* video overlay */
178 struct v4l2_framebuffer ovbuf;
179 struct viu_fmt *ovfmt;
180 unsigned int ovenable;
181 enum v4l2_field ovfield;
182
183 /* crop */
184 struct v4l2_rect crop_current;
185
186 /* clock pointer */
187 struct clk *clk;
188
189 /* decoder */
190 struct v4l2_subdev *decoder;
191
192 v4l2_std_id std;
193};
194
195struct viu_fh {
196 struct viu_dev *dev;
197
198 /* video capture */
199 struct videobuf_queue vb_vidq;
200 spinlock_t vbq_lock; /* spinlock for the videobuf queue */
201
202 /* video overlay */
203 struct v4l2_window win;
204 struct v4l2_clip clips[1];
205
206 /* video capture */
207 struct viu_fmt *fmt;
208 int width, height, sizeimage;
209 enum v4l2_buf_type type;
210};
211
212static struct viu_reg reg_val;
213
214/*
215 * Macro definitions of VIU registers
216 */
217
218/* STATUS_CONFIG register */
219enum status_config {
220 SOFT_RST = 1 << 0,
221
222 ERR_MASK = 0x0f << 4, /* Error code mask */
223 ERR_NO = 0x00, /* No error */
224 ERR_DMA_V = 0x01 << 4, /* DMA in vertical active */
225 ERR_DMA_VB = 0x02 << 4, /* DMA in vertical blanking */
226 ERR_LINE_TOO_LONG = 0x04 << 4, /* Line too long */
227 ERR_TOO_MANG_LINES = 0x05 << 4, /* Too many lines in field */
228 ERR_LINE_TOO_SHORT = 0x06 << 4, /* Line too short */
229 ERR_NOT_ENOUGH_LINE = 0x07 << 4, /* Not enough lines in field */
230 ERR_FIFO_OVERFLOW = 0x08 << 4, /* FIFO overflow */
231 ERR_FIFO_UNDERFLOW = 0x09 << 4, /* FIFO underflow */
232 ERR_1bit_ECC = 0x0a << 4, /* One bit ECC error */
233 ERR_MORE_ECC = 0x0b << 4, /* Two/more bits ECC error */
234
235 INT_FIELD_EN = 0x01 << 8, /* Enable field interrupt */
236 INT_VSYNC_EN = 0x01 << 9, /* Enable vsync interrupt */
237 INT_HSYNC_EN = 0x01 << 10, /* Enable hsync interrupt */
238 INT_VSTART_EN = 0x01 << 11, /* Enable vstart interrupt */
239 INT_DMA_END_EN = 0x01 << 12, /* Enable DMA end interrupt */
240 INT_ERROR_EN = 0x01 << 13, /* Enable error interrupt */
241 INT_ECC_EN = 0x01 << 14, /* Enable ECC interrupt */
242
243 INT_FIELD_STATUS = 0x01 << 16, /* field interrupt status */
244 INT_VSYNC_STATUS = 0x01 << 17, /* vsync interrupt status */
245 INT_HSYNC_STATUS = 0x01 << 18, /* hsync interrupt status */
246 INT_VSTART_STATUS = 0x01 << 19, /* vstart interrupt status */
247 INT_DMA_END_STATUS = 0x01 << 20, /* DMA end interrupt status */
248 INT_ERROR_STATUS = 0x01 << 21, /* error interrupt status */
249
250 DMA_ACT = 0x01 << 27, /* Enable DMA transfer */
251 FIELD_NO = 0x01 << 28, /* Field number */
252 DITHER_ON = 0x01 << 29, /* Dithering is on */
253 ROUND_ON = 0x01 << 30, /* Round is on */
254 MODE_32BIT = 0x01 << 31, /* Data in RGBa888,
255 * 0 in RGB565
256 */
257};
258
259#define norm_maxw() 720
260#define norm_maxh() 576
261
262#define INT_ALL_STATUS (INT_FIELD_STATUS | INT_VSYNC_STATUS | \
263 INT_HSYNC_STATUS | INT_VSTART_STATUS | \
264 INT_DMA_END_STATUS | INT_ERROR_STATUS)
265
266#define NUM_FORMATS ARRAY_SIZE(formats)
267
268static irqreturn_t viu_intr(int irq, void *dev_id);
269
270struct viu_fmt *format_by_fourcc(int fourcc)
271{
272 int i;
273
274 for (i = 0; i < NUM_FORMATS; i++) {
275 if (formats[i].pixelformat == fourcc)
276 return formats + i;
277 }
278
279 dprintk(0, "unknown pixelformat:'%4.4s'\n", (char *)&fourcc);
280 return NULL;
281}
282
283void viu_start_dma(struct viu_dev *dev)
284{
285 struct viu_reg *vr = dev->vr;
286
287 dev->field = 0;
288
289 /* Enable DMA operation */
290 out_be32(&vr->status_cfg, SOFT_RST);
291 out_be32(&vr->status_cfg, INT_FIELD_EN);
292}
293
294void viu_stop_dma(struct viu_dev *dev)
295{
296 struct viu_reg *vr = dev->vr;
297 int cnt = 100;
298 u32 status_cfg;
299
300 out_be32(&vr->status_cfg, 0);
301
302 /* Clear pending interrupts */
303 status_cfg = in_be32(&vr->status_cfg);
304 if (status_cfg & 0x3f0000)
305 out_be32(&vr->status_cfg, status_cfg & 0x3f0000);
306
307 if (status_cfg & DMA_ACT) {
308 do {
309 status_cfg = in_be32(&vr->status_cfg);
310 if (status_cfg & INT_DMA_END_STATUS)
311 break;
312 } while (cnt--);
313
314 if (cnt < 0) {
315 /* timed out, issue soft reset */
316 out_be32(&vr->status_cfg, SOFT_RST);
317 out_be32(&vr->status_cfg, 0);
318 } else {
319 /* clear DMA_END and other pending irqs */
320 out_be32(&vr->status_cfg, status_cfg & 0x3f0000);
321 }
322 }
323
324 dev->field = 0;
325}
326
327static int restart_video_queue(struct viu_dmaqueue *vidq)
328{
329 struct viu_buf *buf, *prev;
330
331 dprintk(1, "%s vidq=0x%08lx\n", __func__, (unsigned long)vidq);
332 if (!list_empty(&vidq->active)) {
333 buf = list_entry(vidq->active.next, struct viu_buf, vb.queue);
334 dprintk(2, "restart_queue [%p/%d]: restart dma\n",
335 buf, buf->vb.i);
336
337 viu_stop_dma(vidq->dev);
338
339 /* cancel all outstanding capture requests */
340 list_for_each_entry_safe(buf, prev, &vidq->active, vb.queue) {
341 list_del(&buf->vb.queue);
342 buf->vb.state = VIDEOBUF_ERROR;
343 wake_up(&buf->vb.done);
344 }
345 mod_timer(&vidq->timeout, jiffies+BUFFER_TIMEOUT);
346 return 0;
347 }
348
349 prev = NULL;
350 for (;;) {
351 if (list_empty(&vidq->queued))
352 return 0;
353 buf = list_entry(vidq->queued.next, struct viu_buf, vb.queue);
354 if (prev == NULL) {
355 list_del(&buf->vb.queue);
356 list_add_tail(&buf->vb.queue, &vidq->active);
357
358 dprintk(1, "Restarting video dma\n");
359 viu_stop_dma(vidq->dev);
360 viu_start_dma(vidq->dev);
361
362 buf->vb.state = VIDEOBUF_ACTIVE;
363 mod_timer(&vidq->timeout, jiffies+BUFFER_TIMEOUT);
364 dprintk(2, "[%p/%d] restart_queue - first active\n",
365 buf, buf->vb.i);
366
367 } else if (prev->vb.width == buf->vb.width &&
368 prev->vb.height == buf->vb.height &&
369 prev->fmt == buf->fmt) {
370 list_del(&buf->vb.queue);
371 list_add_tail(&buf->vb.queue, &vidq->active);
372 buf->vb.state = VIDEOBUF_ACTIVE;
373 dprintk(2, "[%p/%d] restart_queue - move to active\n",
374 buf, buf->vb.i);
375 } else {
376 return 0;
377 }
378 prev = buf;
379 }
380}
381
382static void viu_vid_timeout(unsigned long data)
383{
384 struct viu_dev *dev = (struct viu_dev *)data;
385 struct viu_buf *buf;
386 struct viu_dmaqueue *vidq = &dev->vidq;
387
388 while (!list_empty(&vidq->active)) {
389 buf = list_entry(vidq->active.next, struct viu_buf, vb.queue);
390 list_del(&buf->vb.queue);
391 buf->vb.state = VIDEOBUF_ERROR;
392 wake_up(&buf->vb.done);
393 dprintk(1, "viu/0: [%p/%d] timeout\n", buf, buf->vb.i);
394 }
395
396 restart_video_queue(vidq);
397}
398
399/*
400 * Videobuf operations
401 */
402static int buffer_setup(struct videobuf_queue *vq, unsigned int *count,
403 unsigned int *size)
404{
405 struct viu_fh *fh = vq->priv_data;
406
407 *size = fh->width * fh->height * fh->fmt->depth >> 3;
408 if (*count == 0)
409 *count = 32;
410
411 while (*size * *count > VIU_VID_MEM_LIMIT * 1024 * 1024)
412 (*count)--;
413
414 dprintk(1, "%s, count=%d, size=%d\n", __func__, *count, *size);
415 return 0;
416}
417
418static void free_buffer(struct videobuf_queue *vq, struct viu_buf *buf)
419{
420 struct videobuf_buffer *vb = &buf->vb;
421 void *vaddr = NULL;
422
423 BUG_ON(in_interrupt());
424
425 videobuf_waiton(vq, &buf->vb, 0, 0);
426
427 if (vq->int_ops && vq->int_ops->vaddr)
428 vaddr = vq->int_ops->vaddr(vb);
429
430 if (vaddr)
431 videobuf_dma_contig_free(vq, &buf->vb);
432
433 buf->vb.state = VIDEOBUF_NEEDS_INIT;
434}
435
436inline int buffer_activate(struct viu_dev *dev, struct viu_buf *buf)
437{
438 struct viu_reg *vr = dev->vr;
439 int bpp;
440
441 /* setup the DMA base address */
442 reg_val.field_base_addr = videobuf_to_dma_contig(&buf->vb);
443
444 dprintk(1, "buffer_activate [%p/%d]: dma addr 0x%lx\n",
445 buf, buf->vb.i, (unsigned long)reg_val.field_base_addr);
446
447 /* interlace is on by default, set horizontal DMA increment */
448 reg_val.status_cfg = 0;
449 bpp = buf->fmt->depth >> 3;
450 switch (bpp) {
451 case 2:
452 reg_val.status_cfg &= ~MODE_32BIT;
453 reg_val.dma_inc = buf->vb.width * 2;
454 break;
455 case 4:
456 reg_val.status_cfg |= MODE_32BIT;
457 reg_val.dma_inc = buf->vb.width * 4;
458 break;
459 default:
460 dprintk(0, "doesn't support color depth(%d)\n",
461 bpp * 8);
462 return -EINVAL;
463 }
464
465 /* setup picture_count register */
466 reg_val.picture_count = (buf->vb.height / 2) << 16 |
467 buf->vb.width;
468
469 reg_val.status_cfg |= DMA_ACT | INT_DMA_END_EN | INT_FIELD_EN;
470
471 buf->vb.state = VIDEOBUF_ACTIVE;
472 dev->capfield = buf->vb.field;
473
474 /* reset dma increment if needed */
475 if (!V4L2_FIELD_HAS_BOTH(buf->vb.field))
476 reg_val.dma_inc = 0;
477
478 out_be32(&vr->dma_inc, reg_val.dma_inc);
479 out_be32(&vr->picture_count, reg_val.picture_count);
480 out_be32(&vr->field_base_addr, reg_val.field_base_addr);
481 mod_timer(&dev->vidq.timeout, jiffies + BUFFER_TIMEOUT);
482 return 0;
483}
484
485static int buffer_prepare(struct videobuf_queue *vq,
486 struct videobuf_buffer *vb,
487 enum v4l2_field field)
488{
489 struct viu_fh *fh = vq->priv_data;
490 struct viu_buf *buf = container_of(vb, struct viu_buf, vb);
491 int rc;
492
493 BUG_ON(fh->fmt == NULL);
494
495 if (fh->width < 48 || fh->width > norm_maxw() ||
496 fh->height < 32 || fh->height > norm_maxh())
497 return -EINVAL;
498 buf->vb.size = (fh->width * fh->height * fh->fmt->depth) >> 3;
499 if (buf->vb.baddr != 0 && buf->vb.bsize < buf->vb.size)
500 return -EINVAL;
501
502 if (buf->fmt != fh->fmt ||
503 buf->vb.width != fh->width ||
504 buf->vb.height != fh->height ||
505 buf->vb.field != field) {
506 buf->fmt = fh->fmt;
507 buf->vb.width = fh->width;
508 buf->vb.height = fh->height;
509 buf->vb.field = field;
510 }
511
512 if (buf->vb.state == VIDEOBUF_NEEDS_INIT) {
513 rc = videobuf_iolock(vq, &buf->vb, NULL);
514 if (rc != 0)
515 goto fail;
516
517 buf->vb.width = fh->width;
518 buf->vb.height = fh->height;
519 buf->vb.field = field;
520 buf->fmt = fh->fmt;
521 }
522
523 buf->vb.state = VIDEOBUF_PREPARED;
524 return 0;
525
526fail:
527 free_buffer(vq, buf);
528 return rc;
529}
530
531static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
532{
533 struct viu_buf *buf = container_of(vb, struct viu_buf, vb);
534 struct viu_fh *fh = vq->priv_data;
535 struct viu_dev *dev = fh->dev;
536 struct viu_dmaqueue *vidq = &dev->vidq;
537 struct viu_buf *prev;
538
539 if (!list_empty(&vidq->queued)) {
540 dprintk(1, "adding vb queue=0x%08lx\n",
541 (unsigned long)&buf->vb.queue);
542 dprintk(1, "vidq pointer 0x%p, queued 0x%p\n",
543 vidq, &vidq->queued);
544 dprintk(1, "dev %p, queued: self %p, next %p, head %p\n",
545 dev, &vidq->queued, vidq->queued.next,
546 vidq->queued.prev);
547 list_add_tail(&buf->vb.queue, &vidq->queued);
548 buf->vb.state = VIDEOBUF_QUEUED;
549 dprintk(2, "[%p/%d] buffer_queue - append to queued\n",
550 buf, buf->vb.i);
551 } else if (list_empty(&vidq->active)) {
552 dprintk(1, "adding vb active=0x%08lx\n",
553 (unsigned long)&buf->vb.queue);
554 list_add_tail(&buf->vb.queue, &vidq->active);
555 buf->vb.state = VIDEOBUF_ACTIVE;
556 mod_timer(&vidq->timeout, jiffies+BUFFER_TIMEOUT);
557 dprintk(2, "[%p/%d] buffer_queue - first active\n",
558 buf, buf->vb.i);
559
560 buffer_activate(dev, buf);
561 } else {
562 dprintk(1, "adding vb queue2=0x%08lx\n",
563 (unsigned long)&buf->vb.queue);
564 prev = list_entry(vidq->active.prev, struct viu_buf, vb.queue);
565 if (prev->vb.width == buf->vb.width &&
566 prev->vb.height == buf->vb.height &&
567 prev->fmt == buf->fmt) {
568 list_add_tail(&buf->vb.queue, &vidq->active);
569 buf->vb.state = VIDEOBUF_ACTIVE;
570 dprintk(2, "[%p/%d] buffer_queue - append to active\n",
571 buf, buf->vb.i);
572 } else {
573 list_add_tail(&buf->vb.queue, &vidq->queued);
574 buf->vb.state = VIDEOBUF_QUEUED;
575 dprintk(2, "[%p/%d] buffer_queue - first queued\n",
576 buf, buf->vb.i);
577 }
578 }
579}
580
581static void buffer_release(struct videobuf_queue *vq,
582 struct videobuf_buffer *vb)
583{
584 struct viu_buf *buf = container_of(vb, struct viu_buf, vb);
585 struct viu_fh *fh = vq->priv_data;
586 struct viu_dev *dev = (struct viu_dev *)fh->dev;
587
588 viu_stop_dma(dev);
589 free_buffer(vq, buf);
590}
591
592static struct videobuf_queue_ops viu_video_qops = {
593 .buf_setup = buffer_setup,
594 .buf_prepare = buffer_prepare,
595 .buf_queue = buffer_queue,
596 .buf_release = buffer_release,
597};
598
599/*
600 * IOCTL vidioc handling
601 */
602static int vidioc_querycap(struct file *file, void *priv,
603 struct v4l2_capability *cap)
604{
605 strcpy(cap->driver, "viu");
606 strcpy(cap->card, "viu");
607 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
608 V4L2_CAP_STREAMING |
609 V4L2_CAP_VIDEO_OVERLAY |
610 V4L2_CAP_READWRITE;
611 return 0;
612}
613
614static int vidioc_enum_fmt(struct file *file, void *priv,
615 struct v4l2_fmtdesc *f)
616{
617 int index = f->index;
618
619 if (f->index > NUM_FORMATS)
620 return -EINVAL;
621
622 strlcpy(f->description, formats[index].name, sizeof(f->description));
623 f->pixelformat = formats[index].fourcc;
624 return 0;
625}
626
627static int vidioc_g_fmt_cap(struct file *file, void *priv,
628 struct v4l2_format *f)
629{
630 struct viu_fh *fh = priv;
631
632 f->fmt.pix.width = fh->width;
633 f->fmt.pix.height = fh->height;
634 f->fmt.pix.field = fh->vb_vidq.field;
635 f->fmt.pix.pixelformat = fh->fmt->pixelformat;
636 f->fmt.pix.bytesperline =
637 (f->fmt.pix.width * fh->fmt->depth) >> 3;
638 f->fmt.pix.sizeimage = fh->sizeimage;
639 return 0;
640}
641
642static int vidioc_try_fmt_cap(struct file *file, void *priv,
643 struct v4l2_format *f)
644{
645 struct viu_fmt *fmt;
646 enum v4l2_field field;
647 unsigned int maxw, maxh;
648
649 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
650 if (!fmt) {
651 dprintk(1, "Fourcc format (0x%08x) invalid.",
652 f->fmt.pix.pixelformat);
653 return -EINVAL;
654 }
655
656 field = f->fmt.pix.field;
657
658 if (field == V4L2_FIELD_ANY) {
659 field = V4L2_FIELD_INTERLACED;
660 } else if (field != V4L2_FIELD_INTERLACED) {
661 dprintk(1, "Field type invalid.\n");
662 return -EINVAL;
663 }
664
665 maxw = norm_maxw();
666 maxh = norm_maxh();
667
668 f->fmt.pix.field = field;
669 if (f->fmt.pix.height < 32)
670 f->fmt.pix.height = 32;
671 if (f->fmt.pix.height > maxh)
672 f->fmt.pix.height = maxh;
673 if (f->fmt.pix.width < 48)
674 f->fmt.pix.width = 48;
675 if (f->fmt.pix.width > maxw)
676 f->fmt.pix.width = maxw;
677 f->fmt.pix.width &= ~0x03;
678 f->fmt.pix.bytesperline =
679 (f->fmt.pix.width * fmt->depth) >> 3;
680
681 return 0;
682}
683
684static int vidioc_s_fmt_cap(struct file *file, void *priv,
685 struct v4l2_format *f)
686{
687 struct viu_fh *fh = priv;
688 int ret;
689
690 ret = vidioc_try_fmt_cap(file, fh, f);
691 if (ret < 0)
692 return ret;
693
694 fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
695 fh->width = f->fmt.pix.width;
696 fh->height = f->fmt.pix.height;
697 fh->sizeimage = f->fmt.pix.sizeimage;
698 fh->vb_vidq.field = f->fmt.pix.field;
699 fh->type = f->type;
700 dprintk(1, "set to pixelformat '%4.6s'\n", (char *)&fh->fmt->name);
701 return 0;
702}
703
704static int vidioc_g_fmt_overlay(struct file *file, void *priv,
705 struct v4l2_format *f)
706{
707 struct viu_fh *fh = priv;
708
709 f->fmt.win = fh->win;
710 return 0;
711}
712
713static int verify_preview(struct viu_dev *dev, struct v4l2_window *win)
714{
715 enum v4l2_field field;
716 int maxw, maxh;
717
718 if (dev->ovbuf.base == NULL)
719 return -EINVAL;
720 if (dev->ovfmt == NULL)
721 return -EINVAL;
722 if (win->w.width < 48 || win->w.height < 32)
723 return -EINVAL;
724
725 field = win->field;
726 maxw = dev->crop_current.width;
727 maxh = dev->crop_current.height;
728
729 if (field == V4L2_FIELD_ANY) {
730 field = (win->w.height > maxh/2)
731 ? V4L2_FIELD_INTERLACED
732 : V4L2_FIELD_TOP;
733 }
734 switch (field) {
735 case V4L2_FIELD_TOP:
736 case V4L2_FIELD_BOTTOM:
737 maxh = maxh / 2;
738 break;
739 case V4L2_FIELD_INTERLACED:
740 break;
741 default:
742 return -EINVAL;
743 }
744
745 win->field = field;
746 if (win->w.width > maxw)
747 win->w.width = maxw;
748 if (win->w.height > maxh)
749 win->w.height = maxh;
750 return 0;
751}
752
753inline void viu_activate_overlay(struct viu_reg *viu_reg)
754{
755 struct viu_reg *vr = viu_reg;
756
757 out_be32(&vr->field_base_addr, reg_val.field_base_addr);
758 out_be32(&vr->dma_inc, reg_val.dma_inc);
759 out_be32(&vr->picture_count, reg_val.picture_count);
760}
761
762static int viu_setup_preview(struct viu_dev *dev, struct viu_fh *fh)
763{
764 int bpp;
765
766 dprintk(1, "%s %dx%d %s\n", __func__,
767 fh->win.w.width, fh->win.w.height, dev->ovfmt->name);
768
769 reg_val.status_cfg = 0;
770
771 /* setup window */
772 reg_val.picture_count = (fh->win.w.height / 2) << 16 |
773 fh->win.w.width;
774
775 /* setup color depth and dma increment */
776 bpp = dev->ovfmt->depth / 8;
777 switch (bpp) {
778 case 2:
779 reg_val.status_cfg &= ~MODE_32BIT;
780 reg_val.dma_inc = fh->win.w.width * 2;
781 break;
782 case 4:
783 reg_val.status_cfg |= MODE_32BIT;
784 reg_val.dma_inc = fh->win.w.width * 4;
785 break;
786 default:
787 dprintk(0, "device doesn't support color depth(%d)\n",
788 bpp * 8);
789 return -EINVAL;
790 }
791
792 dev->ovfield = fh->win.field;
793 if (!V4L2_FIELD_HAS_BOTH(dev->ovfield))
794 reg_val.dma_inc = 0;
795
796 reg_val.status_cfg |= DMA_ACT | INT_DMA_END_EN | INT_FIELD_EN;
797
798 /* setup the base address of the overlay buffer */
799 reg_val.field_base_addr = (u32)dev->ovbuf.base;
800
801 return 0;
802}
803
804static int vidioc_s_fmt_overlay(struct file *file, void *priv,
805 struct v4l2_format *f)
806{
807 struct viu_fh *fh = priv;
808 struct viu_dev *dev = (struct viu_dev *)fh->dev;
809 unsigned long flags;
810 int err;
811
812 err = verify_preview(dev, &f->fmt.win);
813 if (err)
814 return err;
815
816 fh->win = f->fmt.win;
817
818 spin_lock_irqsave(&dev->slock, flags);
819 viu_setup_preview(dev, fh);
820 spin_unlock_irqrestore(&dev->slock, flags);
821 return 0;
822}
823
824static int vidioc_try_fmt_overlay(struct file *file, void *priv,
825 struct v4l2_format *f)
826{
827 return 0;
828}
829
830static int vidioc_overlay(struct file *file, void *priv, unsigned int on)
831{
832 struct viu_fh *fh = priv;
833 struct viu_dev *dev = (struct viu_dev *)fh->dev;
834 unsigned long flags;
835
836 if (on) {
837 spin_lock_irqsave(&dev->slock, flags);
838 viu_activate_overlay(dev->vr);
839 dev->ovenable = 1;
840
841 /* start dma */
842 viu_start_dma(dev);
843 spin_unlock_irqrestore(&dev->slock, flags);
844 } else {
845 viu_stop_dma(dev);
846 dev->ovenable = 0;
847 }
848
849 return 0;
850}
851
852int vidioc_g_fbuf(struct file *file, void *priv, struct v4l2_framebuffer *arg)
853{
854 struct viu_fh *fh = priv;
855 struct viu_dev *dev = fh->dev;
856 struct v4l2_framebuffer *fb = arg;
857
858 *fb = dev->ovbuf;
859 fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING;
860 return 0;
861}
862
863int vidioc_s_fbuf(struct file *file, void *priv, struct v4l2_framebuffer *arg)
864{
865 struct viu_fh *fh = priv;
866 struct viu_dev *dev = fh->dev;
867 struct v4l2_framebuffer *fb = arg;
868 struct viu_fmt *fmt;
869
870 if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RAWIO))
871 return -EPERM;
872
873 /* check args */
874 fmt = format_by_fourcc(fb->fmt.pixelformat);
875 if (fmt == NULL)
876 return -EINVAL;
877
878 /* ok, accept it */
879 dev->ovbuf = *fb;
880 dev->ovfmt = fmt;
881 if (dev->ovbuf.fmt.bytesperline == 0) {
882 dev->ovbuf.fmt.bytesperline =
883 dev->ovbuf.fmt.width * fmt->depth / 8;
884 }
885 return 0;
886}
887
888static int vidioc_reqbufs(struct file *file, void *priv,
889 struct v4l2_requestbuffers *p)
890{
891 struct viu_fh *fh = priv;
892
893 return videobuf_reqbufs(&fh->vb_vidq, p);
894}
895
896static int vidioc_querybuf(struct file *file, void *priv,
897 struct v4l2_buffer *p)
898{
899 struct viu_fh *fh = priv;
900
901 return videobuf_querybuf(&fh->vb_vidq, p);
902}
903
904static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
905{
906 struct viu_fh *fh = priv;
907
908 return videobuf_qbuf(&fh->vb_vidq, p);
909}
910
911static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
912{
913 struct viu_fh *fh = priv;
914
915 return videobuf_dqbuf(&fh->vb_vidq, p,
916 file->f_flags & O_NONBLOCK);
917}
918
919static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
920{
921 struct viu_fh *fh = priv;
922 struct viu_dev *dev = fh->dev;
923
924 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
925 return -EINVAL;
926 if (fh->type != i)
927 return -EINVAL;
928
929 if (dev->ovenable)
930 dev->ovenable = 0;
931
932 viu_start_dma(fh->dev);
933
934 return videobuf_streamon(&fh->vb_vidq);
935}
936
937static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
938{
939 struct viu_fh *fh = priv;
940
941 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
942 return -EINVAL;
943 if (fh->type != i)
944 return -EINVAL;
945
946 viu_stop_dma(fh->dev);
947
948 return videobuf_streamoff(&fh->vb_vidq);
949}
950
951#define decoder_call(viu, o, f, args...) \
952 v4l2_subdev_call(viu->decoder, o, f, ##args)
953
954static int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *std_id)
955{
956 struct viu_fh *fh = priv;
957
958 decoder_call(fh->dev, video, querystd, std_id);
959 return 0;
960}
961
962static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *id)
963{
964 struct viu_fh *fh = priv;
965
966 fh->dev->std = *id;
967 decoder_call(fh->dev, core, s_std, *id);
968 return 0;
969}
970
971static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *std_id)
972{
973 struct viu_fh *fh = priv;
974
975 *std_id = fh->dev->std;
976 return 0;
977}
978
979/* only one input in this driver */
980static int vidioc_enum_input(struct file *file, void *priv,
981 struct v4l2_input *inp)
982{
983 struct viu_fh *fh = priv;
984
985 if (inp->index != 0)
986 return -EINVAL;
987
988 inp->type = V4L2_INPUT_TYPE_CAMERA;
989 inp->std = fh->dev->vdev->tvnorms;
990 strcpy(inp->name, "Camera");
991 return 0;
992}
993
994static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
995{
996 *i = 0;
997 return 0;
998}
999
1000static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
1001{
1002 struct viu_fh *fh = priv;
1003
1004 if (i > 1)
1005 return -EINVAL;
1006
1007 decoder_call(fh->dev, video, s_routing, i, 0, 0);
1008 return 0;
1009}
1010
1011/* Controls */
1012static int vidioc_queryctrl(struct file *file, void *priv,
1013 struct v4l2_queryctrl *qc)
1014{
1015 int i;
1016
1017 for (i = 0; i < ARRAY_SIZE(viu_qctrl); i++) {
1018 if (qc->id && qc->id == viu_qctrl[i].id) {
1019 memcpy(qc, &(viu_qctrl[i]), sizeof(*qc));
1020 return 0;
1021 }
1022 }
1023 return -EINVAL;
1024}
1025
1026static int vidioc_g_ctrl(struct file *file, void *priv,
1027 struct v4l2_control *ctrl)
1028{
1029 int i;
1030
1031 for (i = 0; i < ARRAY_SIZE(viu_qctrl); i++) {
1032 if (ctrl->id == viu_qctrl[i].id) {
1033 ctrl->value = qctl_regs[i];
1034 return 0;
1035 }
1036 }
1037 return -EINVAL;
1038}
1039static int vidioc_s_ctrl(struct file *file, void *priv,
1040 struct v4l2_control *ctrl)
1041{
1042 int i;
1043
1044 for (i = 0; i < ARRAY_SIZE(viu_qctrl); i++) {
1045 if (ctrl->id == viu_qctrl[i].id) {
1046 if (ctrl->value < viu_qctrl[i].minimum
1047 || ctrl->value > viu_qctrl[i].maximum)
1048 return -ERANGE;
1049 qctl_regs[i] = ctrl->value;
1050 return 0;
1051 }
1052 }
1053 return -EINVAL;
1054}
1055
1056inline void viu_activate_next_buf(struct viu_dev *dev,
1057 struct viu_dmaqueue *viuq)
1058{
1059 struct viu_dmaqueue *vidq = viuq;
1060 struct viu_buf *buf;
1061
1062 /* launch another DMA operation for an active/queued buffer */
1063 if (!list_empty(&vidq->active)) {
1064 buf = list_entry(vidq->active.next, struct viu_buf,
1065 vb.queue);
1066 dprintk(1, "start another queued buffer: 0x%p\n", buf);
1067 buffer_activate(dev, buf);
1068 } else if (!list_empty(&vidq->queued)) {
1069 buf = list_entry(vidq->queued.next, struct viu_buf,
1070 vb.queue);
1071 list_del(&buf->vb.queue);
1072
1073 dprintk(1, "start another queued buffer: 0x%p\n", buf);
1074 list_add_tail(&buf->vb.queue, &vidq->active);
1075 buf->vb.state = VIDEOBUF_ACTIVE;
1076 buffer_activate(dev, buf);
1077 }
1078}
1079
1080inline void viu_default_settings(struct viu_reg *viu_reg)
1081{
1082 struct viu_reg *vr = viu_reg;
1083
1084 out_be32(&vr->luminance, 0x9512A254);
1085 out_be32(&vr->chroma_r, 0x03310000);
1086 out_be32(&vr->chroma_g, 0x06600F38);
1087 out_be32(&vr->chroma_b, 0x00000409);
1088 out_be32(&vr->alpha, 0x000000ff);
1089 out_be32(&vr->req_alarm, 0x00000090);
1090 dprintk(1, "status reg: 0x%08x, field base: 0x%08x\n",
1091 in_be32(&vr->status_cfg), in_be32(&vr->field_base_addr));
1092}
1093
1094static void viu_overlay_intr(struct viu_dev *dev, u32 status)
1095{
1096 struct viu_reg *vr = dev->vr;
1097
1098 if (status & INT_DMA_END_STATUS)
1099 dev->dma_done = 1;
1100
1101 if (status & INT_FIELD_STATUS) {
1102 if (dev->dma_done) {
1103 u32 addr = reg_val.field_base_addr;
1104
1105 dev->dma_done = 0;
1106 if (status & FIELD_NO)
1107 addr += reg_val.dma_inc;
1108
1109 out_be32(&vr->field_base_addr, addr);
1110 out_be32(&vr->dma_inc, reg_val.dma_inc);
1111 out_be32(&vr->status_cfg,
1112 (status & 0xffc0ffff) |
1113 (status & INT_ALL_STATUS) |
1114 reg_val.status_cfg);
1115 } else if (status & INT_VSYNC_STATUS) {
1116 out_be32(&vr->status_cfg,
1117 (status & 0xffc0ffff) |
1118 (status & INT_ALL_STATUS) |
1119 reg_val.status_cfg);
1120 }
1121 }
1122}
1123
1124static void viu_capture_intr(struct viu_dev *dev, u32 status)
1125{
1126 struct viu_dmaqueue *vidq = &dev->vidq;
1127 struct viu_reg *vr = dev->vr;
1128 struct viu_buf *buf;
1129 int field_num;
1130 int need_two;
1131 int dma_done = 0;
1132
1133 field_num = status & FIELD_NO;
1134 need_two = V4L2_FIELD_HAS_BOTH(dev->capfield);
1135
1136 if (status & INT_DMA_END_STATUS) {
1137 dma_done = 1;
1138 if (((field_num == 0) && (dev->field == 0)) ||
1139 (field_num && (dev->field == 1)))
1140 dev->field++;
1141 }
1142
1143 if (status & INT_FIELD_STATUS) {
1144 dprintk(1, "irq: field %d, done %d\n",
1145 !!field_num, dma_done);
1146 if (unlikely(dev->first)) {
1147 if (field_num == 0) {
1148 dev->first = 0;
1149 dprintk(1, "activate first buf\n");
1150 viu_activate_next_buf(dev, vidq);
1151 } else
1152 dprintk(1, "wait field 0\n");
1153 return;
1154 }
1155
1156 /* setup buffer address for next dma operation */
1157 if (!list_empty(&vidq->active)) {
1158 u32 addr = reg_val.field_base_addr;
1159
1160 if (field_num && need_two) {
1161 addr += reg_val.dma_inc;
1162 dprintk(1, "field 1, 0x%lx, dev field %d\n",
1163 (unsigned long)addr, dev->field);
1164 }
1165 out_be32(&vr->field_base_addr, addr);
1166 out_be32(&vr->dma_inc, reg_val.dma_inc);
1167 out_be32(&vr->status_cfg,
1168 (status & 0xffc0ffff) |
1169 (status & INT_ALL_STATUS) |
1170 reg_val.status_cfg);
1171 return;
1172 }
1173 }
1174
1175 if (dma_done && field_num && (dev->field == 2)) {
1176 dev->field = 0;
1177 buf = list_entry(vidq->active.next,
1178 struct viu_buf, vb.queue);
1179 dprintk(1, "viu/0: [%p/%d] 0x%lx/0x%lx: dma complete\n",
1180 buf, buf->vb.i,
1181 (unsigned long)videobuf_to_dma_contig(&buf->vb),
1182 (unsigned long)in_be32(&vr->field_base_addr));
1183
1184 if (waitqueue_active(&buf->vb.done)) {
1185 list_del(&buf->vb.queue);
1186 do_gettimeofday(&buf->vb.ts);
1187 buf->vb.state = VIDEOBUF_DONE;
1188 buf->vb.field_count++;
1189 wake_up(&buf->vb.done);
1190 }
1191 /* activate next dma buffer */
1192 viu_activate_next_buf(dev, vidq);
1193 }
1194}
1195
1196static irqreturn_t viu_intr(int irq, void *dev_id)
1197{
1198 struct viu_dev *dev = (struct viu_dev *)dev_id;
1199 struct viu_reg *vr = dev->vr;
1200 u32 status;
1201 u32 error;
1202
1203 status = in_be32(&vr->status_cfg);
1204
1205 if (status & INT_ERROR_STATUS) {
1206 dev->irqs.error_irq++;
1207 error = status & ERR_MASK;
1208 if (error)
1209 dprintk(1, "Err: error(%d), times:%d!\n",
1210 error >> 4, dev->irqs.error_irq);
1211 /* Clear interrupt error bit and error flags */
1212 out_be32(&vr->status_cfg,
1213 (status & 0xffc0ffff) | INT_ERROR_STATUS);
1214 }
1215
1216 if (status & INT_DMA_END_STATUS) {
1217 dev->irqs.dma_end_irq++;
1218 dev->dma_done = 1;
1219 dprintk(2, "VIU DMA end interrupt times: %d\n",
1220 dev->irqs.dma_end_irq);
1221 }
1222
1223 if (status & INT_HSYNC_STATUS)
1224 dev->irqs.hsync_irq++;
1225
1226 if (status & INT_FIELD_STATUS) {
1227 dev->irqs.field_irq++;
1228 dprintk(2, "VIU field interrupt times: %d\n",
1229 dev->irqs.field_irq);
1230 }
1231
1232 if (status & INT_VSTART_STATUS)
1233 dev->irqs.vstart_irq++;
1234
1235 if (status & INT_VSYNC_STATUS) {
1236 dev->irqs.vsync_irq++;
1237 dprintk(2, "VIU vsync interrupt times: %d\n",
1238 dev->irqs.vsync_irq);
1239 }
1240
1241 /* clear all pending irqs */
1242 status = in_be32(&vr->status_cfg);
1243 out_be32(&vr->status_cfg,
1244 (status & 0xffc0ffff) | (status & INT_ALL_STATUS));
1245
1246 if (dev->ovenable) {
1247 viu_overlay_intr(dev, status);
1248 return IRQ_HANDLED;
1249 }
1250
1251 /* Capture mode */
1252 viu_capture_intr(dev, status);
1253 return IRQ_HANDLED;
1254}
1255
1256/*
1257 * File operations for the device
1258 */
1259static int viu_open(struct file *file)
1260{
1261 struct video_device *vdev = video_devdata(file);
1262 struct viu_dev *dev = video_get_drvdata(vdev);
1263 struct viu_fh *fh;
1264 struct viu_reg *vr;
1265 int minor = vdev->minor;
1266 u32 status_cfg;
1267 int i;
1268
1269 dprintk(1, "viu: open (minor=%d)\n", minor);
1270
1271 dev->users++;
1272 if (dev->users > 1) {
1273 dev->users--;
1274 return -EBUSY;
1275 }
1276
1277 vr = dev->vr;
1278
1279 dprintk(1, "open minor=%d type=%s users=%d\n", minor,
1280 v4l2_type_names[V4L2_BUF_TYPE_VIDEO_CAPTURE], dev->users);
1281
1282 if (mutex_lock_interruptible(&dev->lock)) {
1283 dev->users--;
1284 return -ERESTARTSYS;
1285 }
1286
1287 /* allocate and initialize per filehandle data */
1288 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
1289 if (!fh) {
1290 dev->users--;
1291 mutex_unlock(&dev->lock);
1292 return -ENOMEM;
1293 }
1294
1295 file->private_data = fh;
1296 fh->dev = dev;
1297
1298 fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1299 fh->fmt = format_by_fourcc(V4L2_PIX_FMT_RGB32);
1300 fh->width = norm_maxw();
1301 fh->height = norm_maxh();
1302 dev->crop_current.width = fh->width;
1303 dev->crop_current.height = fh->height;
1304
1305 /* Put all controls at a sane state */
1306 for (i = 0; i < ARRAY_SIZE(viu_qctrl); i++)
1307 qctl_regs[i] = viu_qctrl[i].default_value;
1308
1309 dprintk(1, "Open: fh=0x%08lx, dev=0x%08lx, dev->vidq=0x%08lx\n",
1310 (unsigned long)fh, (unsigned long)dev,
1311 (unsigned long)&dev->vidq);
1312 dprintk(1, "Open: list_empty queued=%d\n",
1313 list_empty(&dev->vidq.queued));
1314 dprintk(1, "Open: list_empty active=%d\n",
1315 list_empty(&dev->vidq.active));
1316
1317 viu_default_settings(vr);
1318
1319 status_cfg = in_be32(&vr->status_cfg);
1320 out_be32(&vr->status_cfg,
1321 status_cfg & ~(INT_VSYNC_EN | INT_HSYNC_EN |
1322 INT_FIELD_EN | INT_VSTART_EN |
1323 INT_DMA_END_EN | INT_ERROR_EN | INT_ECC_EN));
1324
1325 status_cfg = in_be32(&vr->status_cfg);
1326 out_be32(&vr->status_cfg, status_cfg | INT_ALL_STATUS);
1327
1328 spin_lock_init(&fh->vbq_lock);
1329 videobuf_queue_dma_contig_init(&fh->vb_vidq, &viu_video_qops,
1330 dev->dev, &fh->vbq_lock,
1331 fh->type, V4L2_FIELD_INTERLACED,
1332 sizeof(struct viu_buf), fh,
1333 &fh->dev->lock);
1334 mutex_unlock(&dev->lock);
1335 return 0;
1336}
1337
1338static ssize_t viu_read(struct file *file, char __user *data, size_t count,
1339 loff_t *ppos)
1340{
1341 struct viu_fh *fh = file->private_data;
1342 struct viu_dev *dev = fh->dev;
1343 int ret = 0;
1344
1345 dprintk(2, "%s\n", __func__);
1346 if (dev->ovenable)
1347 dev->ovenable = 0;
1348
1349 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1350 if (mutex_lock_interruptible(&dev->lock))
1351 return -ERESTARTSYS;
1352 viu_start_dma(dev);
1353 ret = videobuf_read_stream(&fh->vb_vidq, data, count,
1354 ppos, 0, file->f_flags & O_NONBLOCK);
1355 mutex_unlock(&dev->lock);
1356 return ret;
1357 }
1358 return 0;
1359}
1360
1361static unsigned int viu_poll(struct file *file, struct poll_table_struct *wait)
1362{
1363 struct viu_fh *fh = file->private_data;
1364 struct videobuf_queue *q = &fh->vb_vidq;
1365 struct viu_dev *dev = fh->dev;
1366 unsigned int res;
1367
1368 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type)
1369 return POLLERR;
1370
1371 mutex_lock(&dev->lock);
1372 res = videobuf_poll_stream(file, q, wait);
1373 mutex_unlock(&dev->lock);
1374 return res;
1375}
1376
1377static int viu_release(struct file *file)
1378{
1379 struct viu_fh *fh = file->private_data;
1380 struct viu_dev *dev = fh->dev;
1381 int minor = video_devdata(file)->minor;
1382
1383 mutex_lock(&dev->lock);
1384 viu_stop_dma(dev);
1385 videobuf_stop(&fh->vb_vidq);
1386 videobuf_mmap_free(&fh->vb_vidq);
1387 mutex_unlock(&dev->lock);
1388
1389 kfree(fh);
1390
1391 dev->users--;
1392 dprintk(1, "close (minor=%d, users=%d)\n",
1393 minor, dev->users);
1394 return 0;
1395}
1396
1397void viu_reset(struct viu_reg *reg)
1398{
1399 out_be32(&reg->status_cfg, 0);
1400 out_be32(&reg->luminance, 0x9512a254);
1401 out_be32(&reg->chroma_r, 0x03310000);
1402 out_be32(&reg->chroma_g, 0x06600f38);
1403 out_be32(&reg->chroma_b, 0x00000409);
1404 out_be32(&reg->field_base_addr, 0);
1405 out_be32(&reg->dma_inc, 0);
1406 out_be32(&reg->picture_count, 0x01e002d0);
1407 out_be32(&reg->req_alarm, 0x00000090);
1408 out_be32(&reg->alpha, 0x000000ff);
1409}
1410
1411static int viu_mmap(struct file *file, struct vm_area_struct *vma)
1412{
1413 struct viu_fh *fh = file->private_data;
1414 struct viu_dev *dev = fh->dev;
1415 int ret;
1416
1417 dprintk(1, "mmap called, vma=0x%08lx\n", (unsigned long)vma);
1418
1419 if (mutex_lock_interruptible(&dev->lock))
1420 return -ERESTARTSYS;
1421 ret = videobuf_mmap_mapper(&fh->vb_vidq, vma);
1422 mutex_unlock(&dev->lock);
1423
1424 dprintk(1, "vma start=0x%08lx, size=%ld, ret=%d\n",
1425 (unsigned long)vma->vm_start,
1426 (unsigned long)vma->vm_end-(unsigned long)vma->vm_start,
1427 ret);
1428
1429 return ret;
1430}
1431
1432static struct v4l2_file_operations viu_fops = {
1433 .owner = THIS_MODULE,
1434 .open = viu_open,
1435 .release = viu_release,
1436 .read = viu_read,
1437 .poll = viu_poll,
1438 .unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */
1439 .mmap = viu_mmap,
1440};
1441
1442static const struct v4l2_ioctl_ops viu_ioctl_ops = {
1443 .vidioc_querycap = vidioc_querycap,
1444 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt,
1445 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_cap,
1446 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_cap,
1447 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_cap,
1448 .vidioc_enum_fmt_vid_overlay = vidioc_enum_fmt,
1449 .vidioc_g_fmt_vid_overlay = vidioc_g_fmt_overlay,
1450 .vidioc_try_fmt_vid_overlay = vidioc_try_fmt_overlay,
1451 .vidioc_s_fmt_vid_overlay = vidioc_s_fmt_overlay,
1452 .vidioc_overlay = vidioc_overlay,
1453 .vidioc_g_fbuf = vidioc_g_fbuf,
1454 .vidioc_s_fbuf = vidioc_s_fbuf,
1455 .vidioc_reqbufs = vidioc_reqbufs,
1456 .vidioc_querybuf = vidioc_querybuf,
1457 .vidioc_qbuf = vidioc_qbuf,
1458 .vidioc_dqbuf = vidioc_dqbuf,
1459 .vidioc_g_std = vidioc_g_std,
1460 .vidioc_s_std = vidioc_s_std,
1461 .vidioc_querystd = vidioc_querystd,
1462 .vidioc_enum_input = vidioc_enum_input,
1463 .vidioc_g_input = vidioc_g_input,
1464 .vidioc_s_input = vidioc_s_input,
1465 .vidioc_queryctrl = vidioc_queryctrl,
1466 .vidioc_g_ctrl = vidioc_g_ctrl,
1467 .vidioc_s_ctrl = vidioc_s_ctrl,
1468 .vidioc_streamon = vidioc_streamon,
1469 .vidioc_streamoff = vidioc_streamoff,
1470};
1471
1472static struct video_device viu_template = {
1473 .name = "FSL viu",
1474 .fops = &viu_fops,
1475 .minor = -1,
1476 .ioctl_ops = &viu_ioctl_ops,
1477 .release = video_device_release,
1478
1479 .tvnorms = V4L2_STD_NTSC_M | V4L2_STD_PAL,
1480 .current_norm = V4L2_STD_NTSC_M,
1481};
1482
1483static int __devinit viu_of_probe(struct platform_device *op)
1484{
1485 struct viu_dev *viu_dev;
1486 struct video_device *vdev;
1487 struct resource r;
1488 struct viu_reg __iomem *viu_regs;
1489 struct i2c_adapter *ad;
1490 int ret, viu_irq;
1491
1492 ret = of_address_to_resource(op->dev.of_node, 0, &r);
1493 if (ret) {
1494 dev_err(&op->dev, "Can't parse device node resource\n");
1495 return -ENODEV;
1496 }
1497
1498 viu_irq = irq_of_parse_and_map(op->dev.of_node, 0);
1499 if (viu_irq == NO_IRQ) {
1500 dev_err(&op->dev, "Error while mapping the irq\n");
1501 return -EINVAL;
1502 }
1503
1504 /* request mem region */
1505 if (!devm_request_mem_region(&op->dev, r.start,
1506 sizeof(struct viu_reg), DRV_NAME)) {
1507 dev_err(&op->dev, "Error while requesting mem region\n");
1508 ret = -EBUSY;
1509 goto err;
1510 }
1511
1512 /* remap registers */
1513 viu_regs = devm_ioremap(&op->dev, r.start, sizeof(struct viu_reg));
1514 if (!viu_regs) {
1515 dev_err(&op->dev, "Can't map register set\n");
1516 ret = -ENOMEM;
1517 goto err;
1518 }
1519
1520 /* Prepare our private structure */
1521 viu_dev = devm_kzalloc(&op->dev, sizeof(struct viu_dev), GFP_ATOMIC);
1522 if (!viu_dev) {
1523 dev_err(&op->dev, "Can't allocate private structure\n");
1524 ret = -ENOMEM;
1525 goto err;
1526 }
1527
1528 viu_dev->vr = viu_regs;
1529 viu_dev->irq = viu_irq;
1530 viu_dev->dev = &op->dev;
1531
1532 /* init video dma queues */
1533 INIT_LIST_HEAD(&viu_dev->vidq.active);
1534 INIT_LIST_HEAD(&viu_dev->vidq.queued);
1535
1536 snprintf(viu_dev->v4l2_dev.name,
1537 sizeof(viu_dev->v4l2_dev.name), "%s", "VIU");
1538 ret = v4l2_device_register(viu_dev->dev, &viu_dev->v4l2_dev);
1539 if (ret < 0) {
1540 dev_err(&op->dev, "v4l2_device_register() failed: %d\n", ret);
1541 goto err;
1542 }
1543
1544 ad = i2c_get_adapter(0);
1545 viu_dev->decoder = v4l2_i2c_new_subdev(&viu_dev->v4l2_dev, ad,
1546 "saa7113", VIU_VIDEO_DECODER_ADDR, NULL);
1547
1548 viu_dev->vidq.timeout.function = viu_vid_timeout;
1549 viu_dev->vidq.timeout.data = (unsigned long)viu_dev;
1550 init_timer(&viu_dev->vidq.timeout);
1551 viu_dev->first = 1;
1552
1553 /* Allocate memory for video device */
1554 vdev = video_device_alloc();
1555 if (vdev == NULL) {
1556 ret = -ENOMEM;
1557 goto err_vdev;
1558 }
1559
1560 memcpy(vdev, &viu_template, sizeof(viu_template));
1561
1562 vdev->v4l2_dev = &viu_dev->v4l2_dev;
1563
1564 viu_dev->vdev = vdev;
1565
1566 /* initialize locks */
1567 mutex_init(&viu_dev->lock);
1568 viu_dev->vdev->lock = &viu_dev->lock;
1569 spin_lock_init(&viu_dev->slock);
1570
1571 video_set_drvdata(viu_dev->vdev, viu_dev);
1572
1573 mutex_lock(&viu_dev->lock);
1574
1575 ret = video_register_device(viu_dev->vdev, VFL_TYPE_GRABBER, -1);
1576 if (ret < 0) {
1577 video_device_release(viu_dev->vdev);
1578 goto err_vdev;
1579 }
1580
1581 /* enable VIU clock */
1582 viu_dev->clk = clk_get(&op->dev, "viu_clk");
1583 if (IS_ERR(viu_dev->clk)) {
1584 dev_err(&op->dev, "failed to find the clock module!\n");
1585 ret = -ENODEV;
1586 goto err_clk;
1587 } else {
1588 clk_enable(viu_dev->clk);
1589 }
1590
1591 /* reset VIU module */
1592 viu_reset(viu_dev->vr);
1593
1594 /* install interrupt handler */
1595 if (request_irq(viu_dev->irq, viu_intr, 0, "viu", (void *)viu_dev)) {
1596 dev_err(&op->dev, "Request VIU IRQ failed.\n");
1597 ret = -ENODEV;
1598 goto err_irq;
1599 }
1600
1601 mutex_unlock(&viu_dev->lock);
1602
1603 dev_info(&op->dev, "Freescale VIU Video Capture Board\n");
1604 return ret;
1605
1606err_irq:
1607 clk_disable(viu_dev->clk);
1608 clk_put(viu_dev->clk);
1609err_clk:
1610 video_unregister_device(viu_dev->vdev);
1611err_vdev:
1612 mutex_unlock(&viu_dev->lock);
1613 i2c_put_adapter(ad);
1614 v4l2_device_unregister(&viu_dev->v4l2_dev);
1615err:
1616 irq_dispose_mapping(viu_irq);
1617 return ret;
1618}
1619
1620static int __devexit viu_of_remove(struct platform_device *op)
1621{
1622 struct v4l2_device *v4l2_dev = dev_get_drvdata(&op->dev);
1623 struct viu_dev *dev = container_of(v4l2_dev, struct viu_dev, v4l2_dev);
1624 struct v4l2_subdev *sdev = list_entry(v4l2_dev->subdevs.next,
1625 struct v4l2_subdev, list);
1626 struct i2c_client *client = v4l2_get_subdevdata(sdev);
1627
1628 free_irq(dev->irq, (void *)dev);
1629 irq_dispose_mapping(dev->irq);
1630
1631 clk_disable(dev->clk);
1632 clk_put(dev->clk);
1633
1634 video_unregister_device(dev->vdev);
1635 i2c_put_adapter(client->adapter);
1636 v4l2_device_unregister(&dev->v4l2_dev);
1637 return 0;
1638}
1639
1640#ifdef CONFIG_PM
1641static int viu_suspend(struct platform_device *op, pm_message_t state)
1642{
1643 struct v4l2_device *v4l2_dev = dev_get_drvdata(&op->dev);
1644 struct viu_dev *dev = container_of(v4l2_dev, struct viu_dev, v4l2_dev);
1645
1646 clk_disable(dev->clk);
1647 return 0;
1648}
1649
1650static int viu_resume(struct platform_device *op)
1651{
1652 struct v4l2_device *v4l2_dev = dev_get_drvdata(&op->dev);
1653 struct viu_dev *dev = container_of(v4l2_dev, struct viu_dev, v4l2_dev);
1654
1655 clk_enable(dev->clk);
1656 return 0;
1657}
1658#endif
1659
1660/*
1661 * Initialization and module stuff
1662 */
1663static struct of_device_id mpc512x_viu_of_match[] = {
1664 {
1665 .compatible = "fsl,mpc5121-viu",
1666 },
1667 {},
1668};
1669MODULE_DEVICE_TABLE(of, mpc512x_viu_of_match);
1670
1671static struct platform_driver viu_of_platform_driver = {
1672 .probe = viu_of_probe,
1673 .remove = __devexit_p(viu_of_remove),
1674#ifdef CONFIG_PM
1675 .suspend = viu_suspend,
1676 .resume = viu_resume,
1677#endif
1678 .driver = {
1679 .name = DRV_NAME,
1680 .owner = THIS_MODULE,
1681 .of_match_table = mpc512x_viu_of_match,
1682 },
1683};
1684
1685module_platform_driver(viu_of_platform_driver);
1686
1687MODULE_DESCRIPTION("Freescale Video-In(VIU)");
1688MODULE_AUTHOR("Hongjun Chen");
1689MODULE_LICENSE("GPL");
1690MODULE_VERSION(VIU_VERSION);
diff --git a/drivers/media/video/indycam.c b/drivers/media/video/indycam.c
deleted file mode 100644
index 548236333cce..000000000000
--- a/drivers/media/video/indycam.c
+++ /dev/null
@@ -1,390 +0,0 @@
1/*
2 * indycam.c - Silicon Graphics IndyCam digital camera driver
3 *
4 * Copyright (C) 2003 Ladislav Michl <ladis@linux-mips.org>
5 * Copyright (C) 2004,2005 Mikael Nousiainen <tmnousia@cc.hut.fi>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/delay.h>
13#include <linux/errno.h>
14#include <linux/fs.h>
15#include <linux/init.h>
16#include <linux/kernel.h>
17#include <linux/major.h>
18#include <linux/module.h>
19#include <linux/mm.h>
20#include <linux/slab.h>
21
22/* IndyCam decodes stream of photons into digital image representation ;-) */
23#include <linux/videodev2.h>
24#include <linux/i2c.h>
25#include <media/v4l2-device.h>
26#include <media/v4l2-chip-ident.h>
27
28#include "indycam.h"
29
30#define INDYCAM_MODULE_VERSION "0.0.5"
31
32MODULE_DESCRIPTION("SGI IndyCam driver");
33MODULE_VERSION(INDYCAM_MODULE_VERSION);
34MODULE_AUTHOR("Mikael Nousiainen <tmnousia@cc.hut.fi>");
35MODULE_LICENSE("GPL");
36
37
38// #define INDYCAM_DEBUG
39
40#ifdef INDYCAM_DEBUG
41#define dprintk(x...) printk("IndyCam: " x);
42#define indycam_regdump(client) indycam_regdump_debug(client)
43#else
44#define dprintk(x...)
45#define indycam_regdump(client)
46#endif
47
48struct indycam {
49 struct v4l2_subdev sd;
50 u8 version;
51};
52
53static inline struct indycam *to_indycam(struct v4l2_subdev *sd)
54{
55 return container_of(sd, struct indycam, sd);
56}
57
58static const u8 initseq[] = {
59 INDYCAM_CONTROL_AGCENA, /* INDYCAM_CONTROL */
60 INDYCAM_SHUTTER_60, /* INDYCAM_SHUTTER */
61 INDYCAM_GAIN_DEFAULT, /* INDYCAM_GAIN */
62 0x00, /* INDYCAM_BRIGHTNESS (read-only) */
63 INDYCAM_RED_BALANCE_DEFAULT, /* INDYCAM_RED_BALANCE */
64 INDYCAM_BLUE_BALANCE_DEFAULT, /* INDYCAM_BLUE_BALANCE */
65 INDYCAM_RED_SATURATION_DEFAULT, /* INDYCAM_RED_SATURATION */
66 INDYCAM_BLUE_SATURATION_DEFAULT,/* INDYCAM_BLUE_SATURATION */
67};
68
69/* IndyCam register handling */
70
71static int indycam_read_reg(struct v4l2_subdev *sd, u8 reg, u8 *value)
72{
73 struct i2c_client *client = v4l2_get_subdevdata(sd);
74 int ret;
75
76 if (reg == INDYCAM_REG_RESET) {
77 dprintk("indycam_read_reg(): "
78 "skipping write-only register %d\n", reg);
79 *value = 0;
80 return 0;
81 }
82
83 ret = i2c_smbus_read_byte_data(client, reg);
84
85 if (ret < 0) {
86 printk(KERN_ERR "IndyCam: indycam_read_reg(): read failed, "
87 "register = 0x%02x\n", reg);
88 return ret;
89 }
90
91 *value = (u8)ret;
92
93 return 0;
94}
95
96static int indycam_write_reg(struct v4l2_subdev *sd, u8 reg, u8 value)
97{
98 struct i2c_client *client = v4l2_get_subdevdata(sd);
99 int err;
100
101 if (reg == INDYCAM_REG_BRIGHTNESS || reg == INDYCAM_REG_VERSION) {
102 dprintk("indycam_write_reg(): "
103 "skipping read-only register %d\n", reg);
104 return 0;
105 }
106
107 dprintk("Writing Reg %d = 0x%02x\n", reg, value);
108 err = i2c_smbus_write_byte_data(client, reg, value);
109
110 if (err) {
111 printk(KERN_ERR "IndyCam: indycam_write_reg(): write failed, "
112 "register = 0x%02x, value = 0x%02x\n", reg, value);
113 }
114 return err;
115}
116
117static int indycam_write_block(struct v4l2_subdev *sd, u8 reg,
118 u8 length, u8 *data)
119{
120 int i, err;
121
122 for (i = 0; i < length; i++) {
123 err = indycam_write_reg(sd, reg + i, data[i]);
124 if (err)
125 return err;
126 }
127
128 return 0;
129}
130
131/* Helper functions */
132
133#ifdef INDYCAM_DEBUG
134static void indycam_regdump_debug(struct v4l2_subdev *sd)
135{
136 int i;
137 u8 val;
138
139 for (i = 0; i < 9; i++) {
140 indycam_read_reg(sd, i, &val);
141 dprintk("Reg %d = 0x%02x\n", i, val);
142 }
143}
144#endif
145
146static int indycam_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
147{
148 struct indycam *camera = to_indycam(sd);
149 u8 reg;
150 int ret = 0;
151
152 switch (ctrl->id) {
153 case V4L2_CID_AUTOGAIN:
154 case V4L2_CID_AUTO_WHITE_BALANCE:
155 ret = indycam_read_reg(sd, INDYCAM_REG_CONTROL, &reg);
156 if (ret)
157 return -EIO;
158 if (ctrl->id == V4L2_CID_AUTOGAIN)
159 ctrl->value = (reg & INDYCAM_CONTROL_AGCENA)
160 ? 1 : 0;
161 else
162 ctrl->value = (reg & INDYCAM_CONTROL_AWBCTL)
163 ? 1 : 0;
164 break;
165 case V4L2_CID_EXPOSURE:
166 ret = indycam_read_reg(sd, INDYCAM_REG_SHUTTER, &reg);
167 if (ret)
168 return -EIO;
169 ctrl->value = ((s32)reg == 0x00) ? 0xff : ((s32)reg - 1);
170 break;
171 case V4L2_CID_GAIN:
172 ret = indycam_read_reg(sd, INDYCAM_REG_GAIN, &reg);
173 if (ret)
174 return -EIO;
175 ctrl->value = (s32)reg;
176 break;
177 case V4L2_CID_RED_BALANCE:
178 ret = indycam_read_reg(sd, INDYCAM_REG_RED_BALANCE, &reg);
179 if (ret)
180 return -EIO;
181 ctrl->value = (s32)reg;
182 break;
183 case V4L2_CID_BLUE_BALANCE:
184 ret = indycam_read_reg(sd, INDYCAM_REG_BLUE_BALANCE, &reg);
185 if (ret)
186 return -EIO;
187 ctrl->value = (s32)reg;
188 break;
189 case INDYCAM_CONTROL_RED_SATURATION:
190 ret = indycam_read_reg(sd,
191 INDYCAM_REG_RED_SATURATION, &reg);
192 if (ret)
193 return -EIO;
194 ctrl->value = (s32)reg;
195 break;
196 case INDYCAM_CONTROL_BLUE_SATURATION:
197 ret = indycam_read_reg(sd,
198 INDYCAM_REG_BLUE_SATURATION, &reg);
199 if (ret)
200 return -EIO;
201 ctrl->value = (s32)reg;
202 break;
203 case V4L2_CID_GAMMA:
204 if (camera->version == CAMERA_VERSION_MOOSE) {
205 ret = indycam_read_reg(sd,
206 INDYCAM_REG_GAMMA, &reg);
207 if (ret)
208 return -EIO;
209 ctrl->value = (s32)reg;
210 } else {
211 ctrl->value = INDYCAM_GAMMA_DEFAULT;
212 }
213 break;
214 default:
215 ret = -EINVAL;
216 }
217
218 return ret;
219}
220
221static int indycam_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
222{
223 struct indycam *camera = to_indycam(sd);
224 u8 reg;
225 int ret = 0;
226
227 switch (ctrl->id) {
228 case V4L2_CID_AUTOGAIN:
229 case V4L2_CID_AUTO_WHITE_BALANCE:
230 ret = indycam_read_reg(sd, INDYCAM_REG_CONTROL, &reg);
231 if (ret)
232 break;
233
234 if (ctrl->id == V4L2_CID_AUTOGAIN) {
235 if (ctrl->value)
236 reg |= INDYCAM_CONTROL_AGCENA;
237 else
238 reg &= ~INDYCAM_CONTROL_AGCENA;
239 } else {
240 if (ctrl->value)
241 reg |= INDYCAM_CONTROL_AWBCTL;
242 else
243 reg &= ~INDYCAM_CONTROL_AWBCTL;
244 }
245
246 ret = indycam_write_reg(sd, INDYCAM_REG_CONTROL, reg);
247 break;
248 case V4L2_CID_EXPOSURE:
249 reg = (ctrl->value == 0xff) ? 0x00 : (ctrl->value + 1);
250 ret = indycam_write_reg(sd, INDYCAM_REG_SHUTTER, reg);
251 break;
252 case V4L2_CID_GAIN:
253 ret = indycam_write_reg(sd, INDYCAM_REG_GAIN, ctrl->value);
254 break;
255 case V4L2_CID_RED_BALANCE:
256 ret = indycam_write_reg(sd, INDYCAM_REG_RED_BALANCE,
257 ctrl->value);
258 break;
259 case V4L2_CID_BLUE_BALANCE:
260 ret = indycam_write_reg(sd, INDYCAM_REG_BLUE_BALANCE,
261 ctrl->value);
262 break;
263 case INDYCAM_CONTROL_RED_SATURATION:
264 ret = indycam_write_reg(sd, INDYCAM_REG_RED_SATURATION,
265 ctrl->value);
266 break;
267 case INDYCAM_CONTROL_BLUE_SATURATION:
268 ret = indycam_write_reg(sd, INDYCAM_REG_BLUE_SATURATION,
269 ctrl->value);
270 break;
271 case V4L2_CID_GAMMA:
272 if (camera->version == CAMERA_VERSION_MOOSE) {
273 ret = indycam_write_reg(sd, INDYCAM_REG_GAMMA,
274 ctrl->value);
275 }
276 break;
277 default:
278 ret = -EINVAL;
279 }
280
281 return ret;
282}
283
284/* I2C-interface */
285
286static int indycam_g_chip_ident(struct v4l2_subdev *sd,
287 struct v4l2_dbg_chip_ident *chip)
288{
289 struct i2c_client *client = v4l2_get_subdevdata(sd);
290 struct indycam *camera = to_indycam(sd);
291
292 return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_INDYCAM,
293 camera->version);
294}
295
296/* ----------------------------------------------------------------------- */
297
298static const struct v4l2_subdev_core_ops indycam_core_ops = {
299 .g_chip_ident = indycam_g_chip_ident,
300 .g_ctrl = indycam_g_ctrl,
301 .s_ctrl = indycam_s_ctrl,
302};
303
304static const struct v4l2_subdev_ops indycam_ops = {
305 .core = &indycam_core_ops,
306};
307
308static int indycam_probe(struct i2c_client *client,
309 const struct i2c_device_id *id)
310{
311 int err = 0;
312 struct indycam *camera;
313 struct v4l2_subdev *sd;
314
315 v4l_info(client, "chip found @ 0x%x (%s)\n",
316 client->addr << 1, client->adapter->name);
317
318 camera = kzalloc(sizeof(struct indycam), GFP_KERNEL);
319 if (!camera)
320 return -ENOMEM;
321
322 sd = &camera->sd;
323 v4l2_i2c_subdev_init(sd, client, &indycam_ops);
324
325 camera->version = i2c_smbus_read_byte_data(client,
326 INDYCAM_REG_VERSION);
327 if (camera->version != CAMERA_VERSION_INDY &&
328 camera->version != CAMERA_VERSION_MOOSE) {
329 kfree(camera);
330 return -ENODEV;
331 }
332
333 printk(KERN_INFO "IndyCam v%d.%d detected\n",
334 INDYCAM_VERSION_MAJOR(camera->version),
335 INDYCAM_VERSION_MINOR(camera->version));
336
337 indycam_regdump(sd);
338
339 // initialize
340 err = indycam_write_block(sd, 0, sizeof(initseq), (u8 *)&initseq);
341 if (err) {
342 printk(KERN_ERR "IndyCam initialization failed\n");
343 kfree(camera);
344 return -EIO;
345 }
346
347 indycam_regdump(sd);
348
349 // white balance
350 err = indycam_write_reg(sd, INDYCAM_REG_CONTROL,
351 INDYCAM_CONTROL_AGCENA | INDYCAM_CONTROL_AWBCTL);
352 if (err) {
353 printk(KERN_ERR "IndyCam: White balancing camera failed\n");
354 kfree(camera);
355 return -EIO;
356 }
357
358 indycam_regdump(sd);
359
360 printk(KERN_INFO "IndyCam initialized\n");
361
362 return 0;
363}
364
365static int indycam_remove(struct i2c_client *client)
366{
367 struct v4l2_subdev *sd = i2c_get_clientdata(client);
368
369 v4l2_device_unregister_subdev(sd);
370 kfree(to_indycam(sd));
371 return 0;
372}
373
374static const struct i2c_device_id indycam_id[] = {
375 { "indycam", 0 },
376 { }
377};
378MODULE_DEVICE_TABLE(i2c, indycam_id);
379
380static struct i2c_driver indycam_driver = {
381 .driver = {
382 .owner = THIS_MODULE,
383 .name = "indycam",
384 },
385 .probe = indycam_probe,
386 .remove = indycam_remove,
387 .id_table = indycam_id,
388};
389
390module_i2c_driver(indycam_driver);
diff --git a/drivers/media/video/indycam.h b/drivers/media/video/indycam.h
deleted file mode 100644
index 881f21c474c4..000000000000
--- a/drivers/media/video/indycam.h
+++ /dev/null
@@ -1,93 +0,0 @@
1/*
2 * indycam.h - Silicon Graphics IndyCam digital camera driver
3 *
4 * Copyright (C) 2003 Ladislav Michl <ladis@linux-mips.org>
5 * Copyright (C) 2004,2005 Mikael Nousiainen <tmnousia@cc.hut.fi>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef _INDYCAM_H_
13#define _INDYCAM_H_
14
15/* I2C address for the Guinness Camera */
16#define INDYCAM_ADDR 0x56
17
18/* Camera version */
19#define CAMERA_VERSION_INDY 0x10 /* v1.0 */
20#define CAMERA_VERSION_MOOSE 0x12 /* v1.2 */
21#define INDYCAM_VERSION_MAJOR(x) (((x) & 0xf0) >> 4)
22#define INDYCAM_VERSION_MINOR(x) ((x) & 0x0f)
23
24/* Register bus addresses */
25#define INDYCAM_REG_CONTROL 0x00
26#define INDYCAM_REG_SHUTTER 0x01
27#define INDYCAM_REG_GAIN 0x02
28#define INDYCAM_REG_BRIGHTNESS 0x03 /* read-only */
29#define INDYCAM_REG_RED_BALANCE 0x04
30#define INDYCAM_REG_BLUE_BALANCE 0x05
31#define INDYCAM_REG_RED_SATURATION 0x06
32#define INDYCAM_REG_BLUE_SATURATION 0x07
33#define INDYCAM_REG_GAMMA 0x08
34#define INDYCAM_REG_VERSION 0x0e /* read-only */
35#define INDYCAM_REG_RESET 0x0f /* write-only */
36
37#define INDYCAM_REG_LED 0x46
38#define INDYCAM_REG_ORIENTATION 0x47
39#define INDYCAM_REG_BUTTON 0x48
40
41/* Field definitions of registers */
42#define INDYCAM_CONTROL_AGCENA (1<<0) /* automatic gain control */
43#define INDYCAM_CONTROL_AWBCTL (1<<1) /* automatic white balance */
44 /* 2-3 are reserved */
45#define INDYCAM_CONTROL_EVNFLD (1<<4) /* read-only */
46
47#define INDYCAM_SHUTTER_10000 0x02 /* 1/10000 second */
48#define INDYCAM_SHUTTER_4000 0x04 /* 1/4000 second */
49#define INDYCAM_SHUTTER_2000 0x08 /* 1/2000 second */
50#define INDYCAM_SHUTTER_1000 0x10 /* 1/1000 second */
51#define INDYCAM_SHUTTER_500 0x20 /* 1/500 second */
52#define INDYCAM_SHUTTER_250 0x3f /* 1/250 second */
53#define INDYCAM_SHUTTER_125 0x7e /* 1/125 second */
54#define INDYCAM_SHUTTER_100 0x9e /* 1/100 second */
55#define INDYCAM_SHUTTER_60 0x00 /* 1/60 second */
56
57#define INDYCAM_LED_ACTIVE 0x10
58#define INDYCAM_LED_INACTIVE 0x30
59#define INDYCAM_ORIENTATION_BOTTOM_TO_TOP 0x40
60#define INDYCAM_BUTTON_RELEASED 0x10
61
62/* Values for controls */
63#define INDYCAM_SHUTTER_MIN 0x00
64#define INDYCAM_SHUTTER_MAX 0xff
65#define INDYCAM_GAIN_MIN 0x00
66#define INDYCAM_GAIN_MAX 0xff
67#define INDYCAM_RED_BALANCE_MIN 0x00
68#define INDYCAM_RED_BALANCE_MAX 0xff
69#define INDYCAM_BLUE_BALANCE_MIN 0x00
70#define INDYCAM_BLUE_BALANCE_MAX 0xff
71#define INDYCAM_RED_SATURATION_MIN 0x00
72#define INDYCAM_RED_SATURATION_MAX 0xff
73#define INDYCAM_BLUE_SATURATION_MIN 0x00
74#define INDYCAM_BLUE_SATURATION_MAX 0xff
75#define INDYCAM_GAMMA_MIN 0x00
76#define INDYCAM_GAMMA_MAX 0xff
77
78#define INDYCAM_AGC_DEFAULT 1
79#define INDYCAM_AWB_DEFAULT 0
80#define INDYCAM_SHUTTER_DEFAULT 0xff
81#define INDYCAM_GAIN_DEFAULT 0x80
82#define INDYCAM_RED_BALANCE_DEFAULT 0x18
83#define INDYCAM_BLUE_BALANCE_DEFAULT 0xa4
84#define INDYCAM_RED_SATURATION_DEFAULT 0x80
85#define INDYCAM_BLUE_SATURATION_DEFAULT 0xc0
86#define INDYCAM_GAMMA_DEFAULT 0x80
87
88/* Driver interface definitions */
89
90#define INDYCAM_CONTROL_RED_SATURATION (V4L2_CID_PRIVATE_BASE + 0)
91#define INDYCAM_CONTROL_BLUE_SATURATION (V4L2_CID_PRIVATE_BASE + 1)
92
93#endif
diff --git a/drivers/media/video/m2m-deinterlace.c b/drivers/media/video/m2m-deinterlace.c
deleted file mode 100644
index a38c15201d1d..000000000000
--- a/drivers/media/video/m2m-deinterlace.c
+++ /dev/null
@@ -1,1120 +0,0 @@
1/*
2 * V4L2 deinterlacing support.
3 *
4 * Copyright (c) 2012 Vista Silicon S.L.
5 * Javier Martin <javier.martin@vista-silicon.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the
10 * License, or (at your option) any later version
11 */
12
13#include <linux/module.h>
14#include <linux/slab.h>
15#include <linux/interrupt.h>
16#include <linux/dmaengine.h>
17#include <linux/platform_device.h>
18
19#include <media/v4l2-mem2mem.h>
20#include <media/v4l2-device.h>
21#include <media/v4l2-ioctl.h>
22#include <media/videobuf2-dma-contig.h>
23
24#define MEM2MEM_TEST_MODULE_NAME "mem2mem-deinterlace"
25
26MODULE_DESCRIPTION("mem2mem device which supports deinterlacing using dmaengine");
27MODULE_AUTHOR("Javier Martin <javier.martin@vista-silicon.com");
28MODULE_LICENSE("GPL");
29MODULE_VERSION("0.0.1");
30
31static bool debug = true;
32module_param(debug, bool, 0644);
33
34/* Flags that indicate a format can be used for capture/output */
35#define MEM2MEM_CAPTURE (1 << 0)
36#define MEM2MEM_OUTPUT (1 << 1)
37
38#define MEM2MEM_NAME "m2m-deinterlace"
39
40#define dprintk(dev, fmt, arg...) \
41 v4l2_dbg(1, debug, &dev->v4l2_dev, "%s: " fmt, __func__, ## arg)
42
43struct deinterlace_fmt {
44 char *name;
45 u32 fourcc;
46 /* Types the format can be used for */
47 u32 types;
48};
49
50static struct deinterlace_fmt formats[] = {
51 {
52 .name = "YUV 4:2:0 Planar",
53 .fourcc = V4L2_PIX_FMT_YUV420,
54 .types = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT,
55 },
56 {
57 .name = "YUYV 4:2:2",
58 .fourcc = V4L2_PIX_FMT_YUYV,
59 .types = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT,
60 },
61};
62
63#define NUM_FORMATS ARRAY_SIZE(formats)
64
65/* Per-queue, driver-specific private data */
66struct deinterlace_q_data {
67 unsigned int width;
68 unsigned int height;
69 unsigned int sizeimage;
70 struct deinterlace_fmt *fmt;
71 enum v4l2_field field;
72};
73
74enum {
75 V4L2_M2M_SRC = 0,
76 V4L2_M2M_DST = 1,
77};
78
79enum {
80 YUV420_DMA_Y_ODD,
81 YUV420_DMA_Y_EVEN,
82 YUV420_DMA_U_ODD,
83 YUV420_DMA_U_EVEN,
84 YUV420_DMA_V_ODD,
85 YUV420_DMA_V_EVEN,
86 YUV420_DMA_Y_ODD_DOUBLING,
87 YUV420_DMA_U_ODD_DOUBLING,
88 YUV420_DMA_V_ODD_DOUBLING,
89 YUYV_DMA_ODD,
90 YUYV_DMA_EVEN,
91 YUYV_DMA_EVEN_DOUBLING,
92};
93
94/* Source and destination queue data */
95static struct deinterlace_q_data q_data[2];
96
97static struct deinterlace_q_data *get_q_data(enum v4l2_buf_type type)
98{
99 switch (type) {
100 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
101 return &q_data[V4L2_M2M_SRC];
102 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
103 return &q_data[V4L2_M2M_DST];
104 default:
105 BUG();
106 }
107 return NULL;
108}
109
110static struct deinterlace_fmt *find_format(struct v4l2_format *f)
111{
112 struct deinterlace_fmt *fmt;
113 unsigned int k;
114
115 for (k = 0; k < NUM_FORMATS; k++) {
116 fmt = &formats[k];
117 if ((fmt->types & f->type) &&
118 (fmt->fourcc == f->fmt.pix.pixelformat))
119 break;
120 }
121
122 if (k == NUM_FORMATS)
123 return NULL;
124
125 return &formats[k];
126}
127
128struct deinterlace_dev {
129 struct v4l2_device v4l2_dev;
130 struct video_device *vfd;
131
132 atomic_t busy;
133 struct mutex dev_mutex;
134 spinlock_t irqlock;
135
136 struct dma_chan *dma_chan;
137
138 struct v4l2_m2m_dev *m2m_dev;
139 struct vb2_alloc_ctx *alloc_ctx;
140};
141
142struct deinterlace_ctx {
143 struct deinterlace_dev *dev;
144
145 /* Abort requested by m2m */
146 int aborting;
147 enum v4l2_colorspace colorspace;
148 dma_cookie_t cookie;
149 struct v4l2_m2m_ctx *m2m_ctx;
150 struct dma_interleaved_template *xt;
151};
152
153/*
154 * mem2mem callbacks
155 */
156static int deinterlace_job_ready(void *priv)
157{
158 struct deinterlace_ctx *ctx = priv;
159 struct deinterlace_dev *pcdev = ctx->dev;
160
161 if ((v4l2_m2m_num_src_bufs_ready(ctx->m2m_ctx) > 0)
162 && (v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx) > 0)
163 && (atomic_read(&ctx->dev->busy) == 0)) {
164 dprintk(pcdev, "Task ready\n");
165 return 1;
166 }
167
168 dprintk(pcdev, "Task not ready to run\n");
169
170 return 0;
171}
172
173static void deinterlace_job_abort(void *priv)
174{
175 struct deinterlace_ctx *ctx = priv;
176 struct deinterlace_dev *pcdev = ctx->dev;
177
178 ctx->aborting = 1;
179
180 dprintk(pcdev, "Aborting task\n");
181
182 v4l2_m2m_job_finish(pcdev->m2m_dev, ctx->m2m_ctx);
183}
184
185static void deinterlace_lock(void *priv)
186{
187 struct deinterlace_ctx *ctx = priv;
188 struct deinterlace_dev *pcdev = ctx->dev;
189 mutex_lock(&pcdev->dev_mutex);
190}
191
192static void deinterlace_unlock(void *priv)
193{
194 struct deinterlace_ctx *ctx = priv;
195 struct deinterlace_dev *pcdev = ctx->dev;
196 mutex_unlock(&pcdev->dev_mutex);
197}
198
199static void dma_callback(void *data)
200{
201 struct deinterlace_ctx *curr_ctx = data;
202 struct deinterlace_dev *pcdev = curr_ctx->dev;
203 struct vb2_buffer *src_vb, *dst_vb;
204
205 atomic_set(&pcdev->busy, 0);
206
207 src_vb = v4l2_m2m_src_buf_remove(curr_ctx->m2m_ctx);
208 dst_vb = v4l2_m2m_dst_buf_remove(curr_ctx->m2m_ctx);
209
210 v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_DONE);
211 v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_DONE);
212
213 v4l2_m2m_job_finish(pcdev->m2m_dev, curr_ctx->m2m_ctx);
214
215 dprintk(pcdev, "dma transfers completed.\n");
216}
217
218static void deinterlace_issue_dma(struct deinterlace_ctx *ctx, int op,
219 int do_callback)
220{
221 struct deinterlace_q_data *s_q_data, *d_q_data;
222 struct vb2_buffer *src_buf, *dst_buf;
223 struct deinterlace_dev *pcdev = ctx->dev;
224 struct dma_chan *chan = pcdev->dma_chan;
225 struct dma_device *dmadev = chan->device;
226 struct dma_async_tx_descriptor *tx;
227 unsigned int s_width, s_height;
228 unsigned int d_width, d_height;
229 unsigned int d_size, s_size;
230 dma_addr_t p_in, p_out;
231 enum dma_ctrl_flags flags;
232
233 src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
234 dst_buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
235
236 s_q_data = get_q_data(V4L2_BUF_TYPE_VIDEO_OUTPUT);
237 s_width = s_q_data->width;
238 s_height = s_q_data->height;
239 s_size = s_width * s_height;
240
241 d_q_data = get_q_data(V4L2_BUF_TYPE_VIDEO_CAPTURE);
242 d_width = d_q_data->width;
243 d_height = d_q_data->height;
244 d_size = d_width * d_height;
245
246 p_in = (dma_addr_t)vb2_dma_contig_plane_dma_addr(src_buf, 0);
247 p_out = (dma_addr_t)vb2_dma_contig_plane_dma_addr(dst_buf, 0);
248 if (!p_in || !p_out) {
249 v4l2_err(&pcdev->v4l2_dev,
250 "Acquiring kernel pointers to buffers failed\n");
251 return;
252 }
253
254 switch (op) {
255 case YUV420_DMA_Y_ODD:
256 ctx->xt->numf = s_height / 2;
257 ctx->xt->sgl[0].size = s_width;
258 ctx->xt->sgl[0].icg = s_width;
259 ctx->xt->src_start = p_in;
260 ctx->xt->dst_start = p_out;
261 break;
262 case YUV420_DMA_Y_EVEN:
263 ctx->xt->numf = s_height / 2;
264 ctx->xt->sgl[0].size = s_width;
265 ctx->xt->sgl[0].icg = s_width;
266 ctx->xt->src_start = p_in + s_size / 2;
267 ctx->xt->dst_start = p_out + s_width;
268 break;
269 case YUV420_DMA_U_ODD:
270 ctx->xt->numf = s_height / 4;
271 ctx->xt->sgl[0].size = s_width / 2;
272 ctx->xt->sgl[0].icg = s_width / 2;
273 ctx->xt->src_start = p_in + s_size;
274 ctx->xt->dst_start = p_out + s_size;
275 break;
276 case YUV420_DMA_U_EVEN:
277 ctx->xt->numf = s_height / 4;
278 ctx->xt->sgl[0].size = s_width / 2;
279 ctx->xt->sgl[0].icg = s_width / 2;
280 ctx->xt->src_start = p_in + (9 * s_size) / 8;
281 ctx->xt->dst_start = p_out + s_size + s_width / 2;
282 break;
283 case YUV420_DMA_V_ODD:
284 ctx->xt->numf = s_height / 4;
285 ctx->xt->sgl[0].size = s_width / 2;
286 ctx->xt->sgl[0].icg = s_width / 2;
287 ctx->xt->src_start = p_in + (5 * s_size) / 4;
288 ctx->xt->dst_start = p_out + (5 * s_size) / 4;
289 break;
290 case YUV420_DMA_V_EVEN:
291 ctx->xt->numf = s_height / 4;
292 ctx->xt->sgl[0].size = s_width / 2;
293 ctx->xt->sgl[0].icg = s_width / 2;
294 ctx->xt->src_start = p_in + (11 * s_size) / 8;
295 ctx->xt->dst_start = p_out + (5 * s_size) / 4 + s_width / 2;
296 break;
297 case YUV420_DMA_Y_ODD_DOUBLING:
298 ctx->xt->numf = s_height / 2;
299 ctx->xt->sgl[0].size = s_width;
300 ctx->xt->sgl[0].icg = s_width;
301 ctx->xt->src_start = p_in;
302 ctx->xt->dst_start = p_out + s_width;
303 break;
304 case YUV420_DMA_U_ODD_DOUBLING:
305 ctx->xt->numf = s_height / 4;
306 ctx->xt->sgl[0].size = s_width / 2;
307 ctx->xt->sgl[0].icg = s_width / 2;
308 ctx->xt->src_start = p_in + s_size;
309 ctx->xt->dst_start = p_out + s_size + s_width / 2;
310 break;
311 case YUV420_DMA_V_ODD_DOUBLING:
312 ctx->xt->numf = s_height / 4;
313 ctx->xt->sgl[0].size = s_width / 2;
314 ctx->xt->sgl[0].icg = s_width / 2;
315 ctx->xt->src_start = p_in + (5 * s_size) / 4;
316 ctx->xt->dst_start = p_out + (5 * s_size) / 4 + s_width / 2;
317 break;
318 case YUYV_DMA_ODD:
319 ctx->xt->numf = s_height / 2;
320 ctx->xt->sgl[0].size = s_width * 2;
321 ctx->xt->sgl[0].icg = s_width * 2;
322 ctx->xt->src_start = p_in;
323 ctx->xt->dst_start = p_out;
324 break;
325 case YUYV_DMA_EVEN:
326 ctx->xt->numf = s_height / 2;
327 ctx->xt->sgl[0].size = s_width * 2;
328 ctx->xt->sgl[0].icg = s_width * 2;
329 ctx->xt->src_start = p_in + s_size;
330 ctx->xt->dst_start = p_out + s_width * 2;
331 break;
332 case YUYV_DMA_EVEN_DOUBLING:
333 default:
334 ctx->xt->numf = s_height / 2;
335 ctx->xt->sgl[0].size = s_width * 2;
336 ctx->xt->sgl[0].icg = s_width * 2;
337 ctx->xt->src_start = p_in;
338 ctx->xt->dst_start = p_out + s_width * 2;
339 break;
340 }
341
342 /* Common parameters for al transfers */
343 ctx->xt->frame_size = 1;
344 ctx->xt->dir = DMA_MEM_TO_MEM;
345 ctx->xt->src_sgl = false;
346 ctx->xt->dst_sgl = true;
347 flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT |
348 DMA_COMPL_SKIP_DEST_UNMAP | DMA_COMPL_SKIP_SRC_UNMAP;
349
350 tx = dmadev->device_prep_interleaved_dma(chan, ctx->xt, flags);
351 if (tx == NULL) {
352 v4l2_warn(&pcdev->v4l2_dev, "DMA interleaved prep error\n");
353 return;
354 }
355
356 if (do_callback) {
357 tx->callback = dma_callback;
358 tx->callback_param = ctx;
359 }
360
361 ctx->cookie = dmaengine_submit(tx);
362 if (dma_submit_error(ctx->cookie)) {
363 v4l2_warn(&pcdev->v4l2_dev,
364 "DMA submit error %d with src=0x%x dst=0x%x len=0x%x\n",
365 ctx->cookie, (unsigned)p_in, (unsigned)p_out,
366 s_size * 3/2);
367 return;
368 }
369
370 dma_async_issue_pending(chan);
371}
372
373static void deinterlace_device_run(void *priv)
374{
375 struct deinterlace_ctx *ctx = priv;
376 struct deinterlace_q_data *dst_q_data;
377
378 atomic_set(&ctx->dev->busy, 1);
379
380 dprintk(ctx->dev, "%s: DMA try issue.\n", __func__);
381
382 dst_q_data = get_q_data(V4L2_BUF_TYPE_VIDEO_CAPTURE);
383
384 /*
385 * 4 possible field conversions are possible at the moment:
386 * V4L2_FIELD_SEQ_TB --> V4L2_FIELD_INTERLACED_TB:
387 * two separate fields in the same input buffer are interlaced
388 * in the output buffer using weaving. Top field comes first.
389 * V4L2_FIELD_SEQ_TB --> V4L2_FIELD_NONE:
390 * top field from the input buffer is copied to the output buffer
391 * using line doubling. Bottom field from the input buffer is discarded.
392 * V4L2_FIELD_SEQ_BT --> V4L2_FIELD_INTERLACED_BT:
393 * two separate fields in the same input buffer are interlaced
394 * in the output buffer using weaving. Bottom field comes first.
395 * V4L2_FIELD_SEQ_BT --> V4L2_FIELD_NONE:
396 * bottom field from the input buffer is copied to the output buffer
397 * using line doubling. Top field from the input buffer is discarded.
398 */
399 switch (dst_q_data->fmt->fourcc) {
400 case V4L2_PIX_FMT_YUV420:
401 switch (dst_q_data->field) {
402 case V4L2_FIELD_INTERLACED_TB:
403 case V4L2_FIELD_INTERLACED_BT:
404 dprintk(ctx->dev, "%s: yuv420 interlaced tb.\n",
405 __func__);
406 deinterlace_issue_dma(ctx, YUV420_DMA_Y_ODD, 0);
407 deinterlace_issue_dma(ctx, YUV420_DMA_Y_EVEN, 0);
408 deinterlace_issue_dma(ctx, YUV420_DMA_U_ODD, 0);
409 deinterlace_issue_dma(ctx, YUV420_DMA_U_EVEN, 0);
410 deinterlace_issue_dma(ctx, YUV420_DMA_V_ODD, 0);
411 deinterlace_issue_dma(ctx, YUV420_DMA_V_EVEN, 1);
412 break;
413 case V4L2_FIELD_NONE:
414 default:
415 dprintk(ctx->dev, "%s: yuv420 interlaced line doubling.\n",
416 __func__);
417 deinterlace_issue_dma(ctx, YUV420_DMA_Y_ODD, 0);
418 deinterlace_issue_dma(ctx, YUV420_DMA_Y_ODD_DOUBLING, 0);
419 deinterlace_issue_dma(ctx, YUV420_DMA_U_ODD, 0);
420 deinterlace_issue_dma(ctx, YUV420_DMA_U_ODD_DOUBLING, 0);
421 deinterlace_issue_dma(ctx, YUV420_DMA_V_ODD, 0);
422 deinterlace_issue_dma(ctx, YUV420_DMA_V_ODD_DOUBLING, 1);
423 break;
424 }
425 break;
426 case V4L2_PIX_FMT_YUYV:
427 default:
428 switch (dst_q_data->field) {
429 case V4L2_FIELD_INTERLACED_TB:
430 case V4L2_FIELD_INTERLACED_BT:
431 dprintk(ctx->dev, "%s: yuyv interlaced_tb.\n",
432 __func__);
433 deinterlace_issue_dma(ctx, YUYV_DMA_ODD, 0);
434 deinterlace_issue_dma(ctx, YUYV_DMA_EVEN, 1);
435 break;
436 case V4L2_FIELD_NONE:
437 default:
438 dprintk(ctx->dev, "%s: yuyv interlaced line doubling.\n",
439 __func__);
440 deinterlace_issue_dma(ctx, YUYV_DMA_ODD, 0);
441 deinterlace_issue_dma(ctx, YUYV_DMA_EVEN_DOUBLING, 1);
442 break;
443 }
444 break;
445 }
446
447 dprintk(ctx->dev, "%s: DMA issue done.\n", __func__);
448}
449
450/*
451 * video ioctls
452 */
453static int vidioc_querycap(struct file *file, void *priv,
454 struct v4l2_capability *cap)
455{
456 strlcpy(cap->driver, MEM2MEM_NAME, sizeof(cap->driver));
457 strlcpy(cap->card, MEM2MEM_NAME, sizeof(cap->card));
458 strlcpy(cap->bus_info, MEM2MEM_NAME, sizeof(cap->card));
459 cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT
460 | V4L2_CAP_STREAMING;
461 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
462
463 return 0;
464}
465
466static int enum_fmt(struct v4l2_fmtdesc *f, u32 type)
467{
468 int i, num;
469 struct deinterlace_fmt *fmt;
470
471 num = 0;
472
473 for (i = 0; i < NUM_FORMATS; ++i) {
474 if (formats[i].types & type) {
475 /* index-th format of type type found ? */
476 if (num == f->index)
477 break;
478 /* Correct type but haven't reached our index yet,
479 * just increment per-type index */
480 ++num;
481 }
482 }
483
484 if (i < NUM_FORMATS) {
485 /* Format found */
486 fmt = &formats[i];
487 strlcpy(f->description, fmt->name, sizeof(f->description));
488 f->pixelformat = fmt->fourcc;
489 return 0;
490 }
491
492 /* Format not found */
493 return -EINVAL;
494}
495
496static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
497 struct v4l2_fmtdesc *f)
498{
499 return enum_fmt(f, MEM2MEM_CAPTURE);
500}
501
502static int vidioc_enum_fmt_vid_out(struct file *file, void *priv,
503 struct v4l2_fmtdesc *f)
504{
505 return enum_fmt(f, MEM2MEM_OUTPUT);
506}
507
508static int vidioc_g_fmt(struct deinterlace_ctx *ctx, struct v4l2_format *f)
509{
510 struct vb2_queue *vq;
511 struct deinterlace_q_data *q_data;
512
513 vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
514 if (!vq)
515 return -EINVAL;
516
517 q_data = get_q_data(f->type);
518
519 f->fmt.pix.width = q_data->width;
520 f->fmt.pix.height = q_data->height;
521 f->fmt.pix.field = q_data->field;
522 f->fmt.pix.pixelformat = q_data->fmt->fourcc;
523
524 switch (q_data->fmt->fourcc) {
525 case V4L2_PIX_FMT_YUV420:
526 f->fmt.pix.bytesperline = q_data->width * 3 / 2;
527 break;
528 case V4L2_PIX_FMT_YUYV:
529 default:
530 f->fmt.pix.bytesperline = q_data->width * 2;
531 }
532
533 f->fmt.pix.sizeimage = q_data->sizeimage;
534 f->fmt.pix.colorspace = ctx->colorspace;
535
536 return 0;
537}
538
539static int vidioc_g_fmt_vid_out(struct file *file, void *priv,
540 struct v4l2_format *f)
541{
542 return vidioc_g_fmt(priv, f);
543}
544
545static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
546 struct v4l2_format *f)
547{
548 return vidioc_g_fmt(priv, f);
549}
550
551static int vidioc_try_fmt(struct v4l2_format *f, struct deinterlace_fmt *fmt)
552{
553 switch (f->fmt.pix.pixelformat) {
554 case V4L2_PIX_FMT_YUV420:
555 f->fmt.pix.bytesperline = f->fmt.pix.width * 3 / 2;
556 break;
557 case V4L2_PIX_FMT_YUYV:
558 default:
559 f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
560 }
561 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
562
563 return 0;
564}
565
566static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
567 struct v4l2_format *f)
568{
569 struct deinterlace_fmt *fmt;
570 struct deinterlace_ctx *ctx = priv;
571
572 fmt = find_format(f);
573 if (!fmt || !(fmt->types & MEM2MEM_CAPTURE))
574 f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420;
575
576 f->fmt.pix.colorspace = ctx->colorspace;
577
578 if (f->fmt.pix.field != V4L2_FIELD_INTERLACED_TB &&
579 f->fmt.pix.field != V4L2_FIELD_INTERLACED_BT &&
580 f->fmt.pix.field != V4L2_FIELD_NONE)
581 f->fmt.pix.field = V4L2_FIELD_INTERLACED_TB;
582
583 return vidioc_try_fmt(f, fmt);
584}
585
586static int vidioc_try_fmt_vid_out(struct file *file, void *priv,
587 struct v4l2_format *f)
588{
589 struct deinterlace_fmt *fmt;
590
591 fmt = find_format(f);
592 if (!fmt || !(fmt->types & MEM2MEM_OUTPUT))
593 f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420;
594
595 if (!f->fmt.pix.colorspace)
596 f->fmt.pix.colorspace = V4L2_COLORSPACE_REC709;
597
598 if (f->fmt.pix.field != V4L2_FIELD_SEQ_TB &&
599 f->fmt.pix.field != V4L2_FIELD_SEQ_BT)
600 f->fmt.pix.field = V4L2_FIELD_SEQ_TB;
601
602 return vidioc_try_fmt(f, fmt);
603}
604
605static int vidioc_s_fmt(struct deinterlace_ctx *ctx, struct v4l2_format *f)
606{
607 struct deinterlace_q_data *q_data;
608 struct vb2_queue *vq;
609
610 vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
611 if (!vq)
612 return -EINVAL;
613
614 q_data = get_q_data(f->type);
615 if (!q_data)
616 return -EINVAL;
617
618 if (vb2_is_busy(vq)) {
619 v4l2_err(&ctx->dev->v4l2_dev, "%s queue busy\n", __func__);
620 return -EBUSY;
621 }
622
623 q_data->fmt = find_format(f);
624 if (!q_data->fmt) {
625 v4l2_err(&ctx->dev->v4l2_dev,
626 "Couldn't set format type %d, wxh: %dx%d. fmt: %d, field: %d\n",
627 f->type, f->fmt.pix.width, f->fmt.pix.height,
628 f->fmt.pix.pixelformat, f->fmt.pix.field);
629 return -EINVAL;
630 }
631
632 q_data->width = f->fmt.pix.width;
633 q_data->height = f->fmt.pix.height;
634 q_data->field = f->fmt.pix.field;
635
636 switch (f->fmt.pix.pixelformat) {
637 case V4L2_PIX_FMT_YUV420:
638 f->fmt.pix.bytesperline = f->fmt.pix.width * 3 / 2;
639 q_data->sizeimage = (q_data->width * q_data->height * 3) / 2;
640 break;
641 case V4L2_PIX_FMT_YUYV:
642 default:
643 f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
644 q_data->sizeimage = q_data->width * q_data->height * 2;
645 }
646
647 dprintk(ctx->dev,
648 "Setting format for type %d, wxh: %dx%d, fmt: %d, field: %d\n",
649 f->type, q_data->width, q_data->height, q_data->fmt->fourcc,
650 q_data->field);
651
652 return 0;
653}
654
655static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
656 struct v4l2_format *f)
657{
658 int ret;
659
660 ret = vidioc_try_fmt_vid_cap(file, priv, f);
661 if (ret)
662 return ret;
663 return vidioc_s_fmt(priv, f);
664}
665
666static int vidioc_s_fmt_vid_out(struct file *file, void *priv,
667 struct v4l2_format *f)
668{
669 struct deinterlace_ctx *ctx = priv;
670 int ret;
671
672 ret = vidioc_try_fmt_vid_out(file, priv, f);
673 if (ret)
674 return ret;
675
676 ret = vidioc_s_fmt(priv, f);
677 if (!ret)
678 ctx->colorspace = f->fmt.pix.colorspace;
679
680 return ret;
681}
682
683static int vidioc_reqbufs(struct file *file, void *priv,
684 struct v4l2_requestbuffers *reqbufs)
685{
686 struct deinterlace_ctx *ctx = priv;
687
688 return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs);
689}
690
691static int vidioc_querybuf(struct file *file, void *priv,
692 struct v4l2_buffer *buf)
693{
694 struct deinterlace_ctx *ctx = priv;
695
696 return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf);
697}
698
699static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
700{
701 struct deinterlace_ctx *ctx = priv;
702
703 return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
704}
705
706static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
707{
708 struct deinterlace_ctx *ctx = priv;
709
710 return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
711}
712
713static int vidioc_streamon(struct file *file, void *priv,
714 enum v4l2_buf_type type)
715{
716 struct deinterlace_q_data *s_q_data, *d_q_data;
717 struct deinterlace_ctx *ctx = priv;
718
719 s_q_data = get_q_data(V4L2_BUF_TYPE_VIDEO_OUTPUT);
720 d_q_data = get_q_data(V4L2_BUF_TYPE_VIDEO_CAPTURE);
721
722 /* Check that src and dst queues have the same pix format */
723 if (s_q_data->fmt->fourcc != d_q_data->fmt->fourcc) {
724 v4l2_err(&ctx->dev->v4l2_dev,
725 "src and dst formats don't match.\n");
726 return -EINVAL;
727 }
728
729 /* Check that input and output deinterlacing types are compatible */
730 switch (s_q_data->field) {
731 case V4L2_FIELD_SEQ_BT:
732 if (d_q_data->field != V4L2_FIELD_NONE &&
733 d_q_data->field != V4L2_FIELD_INTERLACED_BT) {
734 v4l2_err(&ctx->dev->v4l2_dev,
735 "src and dst field conversion [(%d)->(%d)] not supported.\n",
736 s_q_data->field, d_q_data->field);
737 return -EINVAL;
738 }
739 break;
740 case V4L2_FIELD_SEQ_TB:
741 if (d_q_data->field != V4L2_FIELD_NONE &&
742 d_q_data->field != V4L2_FIELD_INTERLACED_TB) {
743 v4l2_err(&ctx->dev->v4l2_dev,
744 "src and dst field conversion [(%d)->(%d)] not supported.\n",
745 s_q_data->field, d_q_data->field);
746 return -EINVAL;
747 }
748 break;
749 default:
750 return -EINVAL;
751 }
752
753 return v4l2_m2m_streamon(file, ctx->m2m_ctx, type);
754}
755
756static int vidioc_streamoff(struct file *file, void *priv,
757 enum v4l2_buf_type type)
758{
759 struct deinterlace_ctx *ctx = priv;
760
761 return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type);
762}
763
764static const struct v4l2_ioctl_ops deinterlace_ioctl_ops = {
765 .vidioc_querycap = vidioc_querycap,
766
767 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
768 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
769 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
770 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
771
772 .vidioc_enum_fmt_vid_out = vidioc_enum_fmt_vid_out,
773 .vidioc_g_fmt_vid_out = vidioc_g_fmt_vid_out,
774 .vidioc_try_fmt_vid_out = vidioc_try_fmt_vid_out,
775 .vidioc_s_fmt_vid_out = vidioc_s_fmt_vid_out,
776
777 .vidioc_reqbufs = vidioc_reqbufs,
778 .vidioc_querybuf = vidioc_querybuf,
779
780 .vidioc_qbuf = vidioc_qbuf,
781 .vidioc_dqbuf = vidioc_dqbuf,
782
783 .vidioc_streamon = vidioc_streamon,
784 .vidioc_streamoff = vidioc_streamoff,
785};
786
787
788/*
789 * Queue operations
790 */
791struct vb2_dc_conf {
792 struct device *dev;
793};
794
795static int deinterlace_queue_setup(struct vb2_queue *vq,
796 const struct v4l2_format *fmt,
797 unsigned int *nbuffers, unsigned int *nplanes,
798 unsigned int sizes[], void *alloc_ctxs[])
799{
800 struct deinterlace_ctx *ctx = vb2_get_drv_priv(vq);
801 struct deinterlace_q_data *q_data;
802 unsigned int size, count = *nbuffers;
803
804 q_data = get_q_data(vq->type);
805
806 switch (q_data->fmt->fourcc) {
807 case V4L2_PIX_FMT_YUV420:
808 size = q_data->width * q_data->height * 3 / 2;
809 break;
810 case V4L2_PIX_FMT_YUYV:
811 default:
812 size = q_data->width * q_data->height * 2;
813 }
814
815 *nplanes = 1;
816 *nbuffers = count;
817 sizes[0] = size;
818
819 alloc_ctxs[0] = ctx->dev->alloc_ctx;
820
821 dprintk(ctx->dev, "get %d buffer(s) of size %d each.\n", count, size);
822
823 return 0;
824}
825
826static int deinterlace_buf_prepare(struct vb2_buffer *vb)
827{
828 struct deinterlace_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
829 struct deinterlace_q_data *q_data;
830
831 dprintk(ctx->dev, "type: %d\n", vb->vb2_queue->type);
832
833 q_data = get_q_data(vb->vb2_queue->type);
834
835 if (vb2_plane_size(vb, 0) < q_data->sizeimage) {
836 dprintk(ctx->dev, "%s data will not fit into plane (%lu < %lu)\n",
837 __func__, vb2_plane_size(vb, 0), (long)q_data->sizeimage);
838 return -EINVAL;
839 }
840
841 vb2_set_plane_payload(vb, 0, q_data->sizeimage);
842
843 return 0;
844}
845
846static void deinterlace_buf_queue(struct vb2_buffer *vb)
847{
848 struct deinterlace_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
849 v4l2_m2m_buf_queue(ctx->m2m_ctx, vb);
850}
851
852static struct vb2_ops deinterlace_qops = {
853 .queue_setup = deinterlace_queue_setup,
854 .buf_prepare = deinterlace_buf_prepare,
855 .buf_queue = deinterlace_buf_queue,
856};
857
858static int queue_init(void *priv, struct vb2_queue *src_vq,
859 struct vb2_queue *dst_vq)
860{
861 struct deinterlace_ctx *ctx = priv;
862 int ret;
863
864 memset(src_vq, 0, sizeof(*src_vq));
865 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
866 src_vq->io_modes = VB2_MMAP | VB2_USERPTR;
867 src_vq->drv_priv = ctx;
868 src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
869 src_vq->ops = &deinterlace_qops;
870 src_vq->mem_ops = &vb2_dma_contig_memops;
871 q_data[V4L2_M2M_SRC].fmt = &formats[0];
872 q_data[V4L2_M2M_SRC].width = 640;
873 q_data[V4L2_M2M_SRC].height = 480;
874 q_data[V4L2_M2M_SRC].sizeimage = (640 * 480 * 3) / 2;
875 q_data[V4L2_M2M_SRC].field = V4L2_FIELD_SEQ_TB;
876
877 ret = vb2_queue_init(src_vq);
878 if (ret)
879 return ret;
880
881 memset(dst_vq, 0, sizeof(*dst_vq));
882 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
883 dst_vq->io_modes = VB2_MMAP | VB2_USERPTR;
884 dst_vq->drv_priv = ctx;
885 dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
886 dst_vq->ops = &deinterlace_qops;
887 dst_vq->mem_ops = &vb2_dma_contig_memops;
888 q_data[V4L2_M2M_DST].fmt = &formats[0];
889 q_data[V4L2_M2M_DST].width = 640;
890 q_data[V4L2_M2M_DST].height = 480;
891 q_data[V4L2_M2M_DST].sizeimage = (640 * 480 * 3) / 2;
892 q_data[V4L2_M2M_SRC].field = V4L2_FIELD_INTERLACED_TB;
893
894 return vb2_queue_init(dst_vq);
895}
896
897/*
898 * File operations
899 */
900static int deinterlace_open(struct file *file)
901{
902 struct deinterlace_dev *pcdev = video_drvdata(file);
903 struct deinterlace_ctx *ctx = NULL;
904
905 ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
906 if (!ctx)
907 return -ENOMEM;
908
909 file->private_data = ctx;
910 ctx->dev = pcdev;
911
912 ctx->m2m_ctx = v4l2_m2m_ctx_init(pcdev->m2m_dev, ctx, &queue_init);
913 if (IS_ERR(ctx->m2m_ctx)) {
914 int ret = PTR_ERR(ctx->m2m_ctx);
915
916 kfree(ctx);
917 return ret;
918 }
919
920 ctx->xt = kzalloc(sizeof(struct dma_async_tx_descriptor) +
921 sizeof(struct data_chunk), GFP_KERNEL);
922 if (!ctx->xt) {
923 int ret = PTR_ERR(ctx->xt);
924
925 kfree(ctx);
926 return ret;
927 }
928
929 ctx->colorspace = V4L2_COLORSPACE_REC709;
930
931 dprintk(pcdev, "Created instance %p, m2m_ctx: %p\n", ctx, ctx->m2m_ctx);
932
933 return 0;
934}
935
936static int deinterlace_release(struct file *file)
937{
938 struct deinterlace_dev *pcdev = video_drvdata(file);
939 struct deinterlace_ctx *ctx = file->private_data;
940
941 dprintk(pcdev, "Releasing instance %p\n", ctx);
942
943 v4l2_m2m_ctx_release(ctx->m2m_ctx);
944 kfree(ctx->xt);
945 kfree(ctx);
946
947 return 0;
948}
949
950static unsigned int deinterlace_poll(struct file *file,
951 struct poll_table_struct *wait)
952{
953 struct deinterlace_ctx *ctx = file->private_data;
954 int ret;
955
956 deinterlace_lock(ctx);
957 ret = v4l2_m2m_poll(file, ctx->m2m_ctx, wait);
958 deinterlace_unlock(ctx);
959
960 return ret;
961}
962
963static int deinterlace_mmap(struct file *file, struct vm_area_struct *vma)
964{
965 struct deinterlace_ctx *ctx = file->private_data;
966
967 return v4l2_m2m_mmap(file, ctx->m2m_ctx, vma);
968}
969
970static const struct v4l2_file_operations deinterlace_fops = {
971 .owner = THIS_MODULE,
972 .open = deinterlace_open,
973 .release = deinterlace_release,
974 .poll = deinterlace_poll,
975 .unlocked_ioctl = video_ioctl2,
976 .mmap = deinterlace_mmap,
977};
978
979static struct video_device deinterlace_videodev = {
980 .name = MEM2MEM_NAME,
981 .fops = &deinterlace_fops,
982 .ioctl_ops = &deinterlace_ioctl_ops,
983 .minor = -1,
984 .release = video_device_release,
985};
986
987static struct v4l2_m2m_ops m2m_ops = {
988 .device_run = deinterlace_device_run,
989 .job_ready = deinterlace_job_ready,
990 .job_abort = deinterlace_job_abort,
991 .lock = deinterlace_lock,
992 .unlock = deinterlace_unlock,
993};
994
995static int deinterlace_probe(struct platform_device *pdev)
996{
997 struct deinterlace_dev *pcdev;
998 struct video_device *vfd;
999 dma_cap_mask_t mask;
1000 int ret = 0;
1001
1002 pcdev = kzalloc(sizeof *pcdev, GFP_KERNEL);
1003 if (!pcdev)
1004 return -ENOMEM;
1005
1006 spin_lock_init(&pcdev->irqlock);
1007
1008 dma_cap_zero(mask);
1009 dma_cap_set(DMA_INTERLEAVE, mask);
1010 pcdev->dma_chan = dma_request_channel(mask, NULL, pcdev);
1011 if (!pcdev->dma_chan)
1012 goto free_dev;
1013
1014 if (!dma_has_cap(DMA_INTERLEAVE, pcdev->dma_chan->device->cap_mask)) {
1015 v4l2_err(&pcdev->v4l2_dev, "DMA does not support INTERLEAVE\n");
1016 goto rel_dma;
1017 }
1018
1019 ret = v4l2_device_register(&pdev->dev, &pcdev->v4l2_dev);
1020 if (ret)
1021 goto rel_dma;
1022
1023 atomic_set(&pcdev->busy, 0);
1024 mutex_init(&pcdev->dev_mutex);
1025
1026 vfd = video_device_alloc();
1027 if (!vfd) {
1028 v4l2_err(&pcdev->v4l2_dev, "Failed to allocate video device\n");
1029 ret = -ENOMEM;
1030 goto unreg_dev;
1031 }
1032
1033 *vfd = deinterlace_videodev;
1034 vfd->lock = &pcdev->dev_mutex;
1035
1036 ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
1037 if (ret) {
1038 v4l2_err(&pcdev->v4l2_dev, "Failed to register video device\n");
1039 goto rel_vdev;
1040 }
1041
1042 video_set_drvdata(vfd, pcdev);
1043 snprintf(vfd->name, sizeof(vfd->name), "%s", deinterlace_videodev.name);
1044 pcdev->vfd = vfd;
1045 v4l2_info(&pcdev->v4l2_dev, MEM2MEM_TEST_MODULE_NAME
1046 " Device registered as /dev/video%d\n", vfd->num);
1047
1048 platform_set_drvdata(pdev, pcdev);
1049
1050 pcdev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
1051 if (IS_ERR(pcdev->alloc_ctx)) {
1052 v4l2_err(&pcdev->v4l2_dev, "Failed to alloc vb2 context\n");
1053 ret = PTR_ERR(pcdev->alloc_ctx);
1054 goto err_ctx;
1055 }
1056
1057 pcdev->m2m_dev = v4l2_m2m_init(&m2m_ops);
1058 if (IS_ERR(pcdev->m2m_dev)) {
1059 v4l2_err(&pcdev->v4l2_dev, "Failed to init mem2mem device\n");
1060 ret = PTR_ERR(pcdev->m2m_dev);
1061 goto err_m2m;
1062 }
1063
1064 return 0;
1065
1066 v4l2_m2m_release(pcdev->m2m_dev);
1067err_m2m:
1068 video_unregister_device(pcdev->vfd);
1069err_ctx:
1070 vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx);
1071rel_vdev:
1072 video_device_release(vfd);
1073unreg_dev:
1074 v4l2_device_unregister(&pcdev->v4l2_dev);
1075rel_dma:
1076 dma_release_channel(pcdev->dma_chan);
1077free_dev:
1078 kfree(pcdev);
1079
1080 return ret;
1081}
1082
1083static int deinterlace_remove(struct platform_device *pdev)
1084{
1085 struct deinterlace_dev *pcdev =
1086 (struct deinterlace_dev *)platform_get_drvdata(pdev);
1087
1088 v4l2_info(&pcdev->v4l2_dev, "Removing " MEM2MEM_TEST_MODULE_NAME);
1089 v4l2_m2m_release(pcdev->m2m_dev);
1090 video_unregister_device(pcdev->vfd);
1091 v4l2_device_unregister(&pcdev->v4l2_dev);
1092 vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx);
1093 dma_release_channel(pcdev->dma_chan);
1094 kfree(pcdev);
1095
1096 return 0;
1097}
1098
1099static struct platform_driver deinterlace_pdrv = {
1100 .probe = deinterlace_probe,
1101 .remove = deinterlace_remove,
1102 .driver = {
1103 .name = MEM2MEM_NAME,
1104 .owner = THIS_MODULE,
1105 },
1106};
1107
1108static void __exit deinterlace_exit(void)
1109{
1110 platform_driver_unregister(&deinterlace_pdrv);
1111}
1112
1113static int __init deinterlace_init(void)
1114{
1115 return platform_driver_register(&deinterlace_pdrv);
1116}
1117
1118module_init(deinterlace_init);
1119module_exit(deinterlace_exit);
1120
diff --git a/drivers/media/video/marvell-ccic/Kconfig b/drivers/media/video/marvell-ccic/Kconfig
deleted file mode 100644
index bf739e3b3398..000000000000
--- a/drivers/media/video/marvell-ccic/Kconfig
+++ /dev/null
@@ -1,23 +0,0 @@
1config VIDEO_CAFE_CCIC
2 tristate "Marvell 88ALP01 (Cafe) CMOS Camera Controller support"
3 depends on PCI && I2C && VIDEO_V4L2
4 select VIDEO_OV7670
5 select VIDEOBUF2_VMALLOC
6 select VIDEOBUF2_DMA_CONTIG
7 ---help---
8 This is a video4linux2 driver for the Marvell 88ALP01 integrated
9 CMOS camera controller. This is the controller found on first-
10 generation OLPC systems.
11
12config VIDEO_MMP_CAMERA
13 tristate "Marvell Armada 610 integrated camera controller support"
14 depends on ARCH_MMP && I2C && VIDEO_V4L2
15 select VIDEO_OV7670
16 select I2C_GPIO
17 select VIDEOBUF2_DMA_SG
18 ---help---
19 This is a Video4Linux2 driver for the integrated camera
20 controller found on Marvell Armada 610 application
21 processors (and likely beyond). This is the controller found
22 in OLPC XO 1.75 systems.
23
diff --git a/drivers/media/video/marvell-ccic/Makefile b/drivers/media/video/marvell-ccic/Makefile
deleted file mode 100644
index 05a792c579a2..000000000000
--- a/drivers/media/video/marvell-ccic/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
1obj-$(CONFIG_VIDEO_CAFE_CCIC) += cafe_ccic.o
2cafe_ccic-y := cafe-driver.o mcam-core.o
3
4obj-$(CONFIG_VIDEO_MMP_CAMERA) += mmp_camera.o
5mmp_camera-y := mmp-driver.o mcam-core.o
6
diff --git a/drivers/media/video/marvell-ccic/cafe-driver.c b/drivers/media/video/marvell-ccic/cafe-driver.c
deleted file mode 100644
index d030f9beae88..000000000000
--- a/drivers/media/video/marvell-ccic/cafe-driver.c
+++ /dev/null
@@ -1,654 +0,0 @@
1/*
2 * A driver for the CMOS camera controller in the Marvell 88ALP01 "cafe"
3 * multifunction chip. Currently works with the Omnivision OV7670
4 * sensor.
5 *
6 * The data sheet for this device can be found at:
7 * http://www.marvell.com/products/pc_connectivity/88alp01/
8 *
9 * Copyright 2006-11 One Laptop Per Child Association, Inc.
10 * Copyright 2006-11 Jonathan Corbet <corbet@lwn.net>
11 *
12 * Written by Jonathan Corbet, corbet@lwn.net.
13 *
14 * v4l2_device/v4l2_subdev conversion by:
15 * Copyright (C) 2009 Hans Verkuil <hverkuil@xs4all.nl>
16 *
17 * This file may be distributed under the terms of the GNU General
18 * Public License, version 2.
19 */
20#include <linux/kernel.h>
21#include <linux/module.h>
22#include <linux/init.h>
23#include <linux/pci.h>
24#include <linux/i2c.h>
25#include <linux/interrupt.h>
26#include <linux/spinlock.h>
27#include <linux/slab.h>
28#include <linux/videodev2.h>
29#include <media/v4l2-device.h>
30#include <media/v4l2-chip-ident.h>
31#include <linux/device.h>
32#include <linux/wait.h>
33#include <linux/delay.h>
34#include <linux/io.h>
35
36#include "mcam-core.h"
37
38#define CAFE_VERSION 0x000002
39
40
41/*
42 * Parameters.
43 */
44MODULE_AUTHOR("Jonathan Corbet <corbet@lwn.net>");
45MODULE_DESCRIPTION("Marvell 88ALP01 CMOS Camera Controller driver");
46MODULE_LICENSE("GPL");
47MODULE_SUPPORTED_DEVICE("Video");
48
49
50
51
52struct cafe_camera {
53 int registered; /* Fully initialized? */
54 struct mcam_camera mcam;
55 struct pci_dev *pdev;
56 wait_queue_head_t smbus_wait; /* Waiting on i2c events */
57};
58
59/*
60 * Most of the camera controller registers are defined in mcam-core.h,
61 * but the Cafe platform has some additional registers of its own;
62 * they are described here.
63 */
64
65/*
66 * "General purpose register" has a couple of GPIOs used for sensor
67 * power and reset on OLPC XO 1.0 systems.
68 */
69#define REG_GPR 0xb4
70#define GPR_C1EN 0x00000020 /* Pad 1 (power down) enable */
71#define GPR_C0EN 0x00000010 /* Pad 0 (reset) enable */
72#define GPR_C1 0x00000002 /* Control 1 value */
73/*
74 * Control 0 is wired to reset on OLPC machines. For ov7x sensors,
75 * it is active low.
76 */
77#define GPR_C0 0x00000001 /* Control 0 value */
78
79/*
80 * These registers control the SMBUS module for communicating
81 * with the sensor.
82 */
83#define REG_TWSIC0 0xb8 /* TWSI (smbus) control 0 */
84#define TWSIC0_EN 0x00000001 /* TWSI enable */
85#define TWSIC0_MODE 0x00000002 /* 1 = 16-bit, 0 = 8-bit */
86#define TWSIC0_SID 0x000003fc /* Slave ID */
87/*
88 * Subtle trickery: the slave ID field starts with bit 2. But the
89 * Linux i2c stack wants to treat the bottommost bit as a separate
90 * read/write bit, which is why slave ID's are usually presented
91 * >>1. For consistency with that behavior, we shift over three
92 * bits instead of two.
93 */
94#define TWSIC0_SID_SHIFT 3
95#define TWSIC0_CLKDIV 0x0007fc00 /* Clock divider */
96#define TWSIC0_MASKACK 0x00400000 /* Mask ack from sensor */
97#define TWSIC0_OVMAGIC 0x00800000 /* Make it work on OV sensors */
98
99#define REG_TWSIC1 0xbc /* TWSI control 1 */
100#define TWSIC1_DATA 0x0000ffff /* Data to/from camchip */
101#define TWSIC1_ADDR 0x00ff0000 /* Address (register) */
102#define TWSIC1_ADDR_SHIFT 16
103#define TWSIC1_READ 0x01000000 /* Set for read op */
104#define TWSIC1_WSTAT 0x02000000 /* Write status */
105#define TWSIC1_RVALID 0x04000000 /* Read data valid */
106#define TWSIC1_ERROR 0x08000000 /* Something screwed up */
107
108/*
109 * Here's the weird global control registers
110 */
111#define REG_GL_CSR 0x3004 /* Control/status register */
112#define GCSR_SRS 0x00000001 /* SW Reset set */
113#define GCSR_SRC 0x00000002 /* SW Reset clear */
114#define GCSR_MRS 0x00000004 /* Master reset set */
115#define GCSR_MRC 0x00000008 /* HW Reset clear */
116#define GCSR_CCIC_EN 0x00004000 /* CCIC Clock enable */
117#define REG_GL_IMASK 0x300c /* Interrupt mask register */
118#define GIMSK_CCIC_EN 0x00000004 /* CCIC Interrupt enable */
119
120#define REG_GL_FCR 0x3038 /* GPIO functional control register */
121#define GFCR_GPIO_ON 0x08 /* Camera GPIO enabled */
122#define REG_GL_GPIOR 0x315c /* GPIO register */
123#define GGPIO_OUT 0x80000 /* GPIO output */
124#define GGPIO_VAL 0x00008 /* Output pin value */
125
126#define REG_LEN (REG_GL_IMASK + 4)
127
128
129/*
130 * Debugging and related.
131 */
132#define cam_err(cam, fmt, arg...) \
133 dev_err(&(cam)->pdev->dev, fmt, ##arg);
134#define cam_warn(cam, fmt, arg...) \
135 dev_warn(&(cam)->pdev->dev, fmt, ##arg);
136
137/* -------------------------------------------------------------------- */
138/*
139 * The I2C/SMBUS interface to the camera itself starts here. The
140 * controller handles SMBUS itself, presenting a relatively simple register
141 * interface; all we have to do is to tell it where to route the data.
142 */
143#define CAFE_SMBUS_TIMEOUT (HZ) /* generous */
144
145static inline struct cafe_camera *to_cam(struct v4l2_device *dev)
146{
147 struct mcam_camera *m = container_of(dev, struct mcam_camera, v4l2_dev);
148 return container_of(m, struct cafe_camera, mcam);
149}
150
151
152static int cafe_smbus_write_done(struct mcam_camera *mcam)
153{
154 unsigned long flags;
155 int c1;
156
157 /*
158 * We must delay after the interrupt, or the controller gets confused
159 * and never does give us good status. Fortunately, we don't do this
160 * often.
161 */
162 udelay(20);
163 spin_lock_irqsave(&mcam->dev_lock, flags);
164 c1 = mcam_reg_read(mcam, REG_TWSIC1);
165 spin_unlock_irqrestore(&mcam->dev_lock, flags);
166 return (c1 & (TWSIC1_WSTAT|TWSIC1_ERROR)) != TWSIC1_WSTAT;
167}
168
169static int cafe_smbus_write_data(struct cafe_camera *cam,
170 u16 addr, u8 command, u8 value)
171{
172 unsigned int rval;
173 unsigned long flags;
174 struct mcam_camera *mcam = &cam->mcam;
175
176 spin_lock_irqsave(&mcam->dev_lock, flags);
177 rval = TWSIC0_EN | ((addr << TWSIC0_SID_SHIFT) & TWSIC0_SID);
178 rval |= TWSIC0_OVMAGIC; /* Make OV sensors work */
179 /*
180 * Marvell sez set clkdiv to all 1's for now.
181 */
182 rval |= TWSIC0_CLKDIV;
183 mcam_reg_write(mcam, REG_TWSIC0, rval);
184 (void) mcam_reg_read(mcam, REG_TWSIC1); /* force write */
185 rval = value | ((command << TWSIC1_ADDR_SHIFT) & TWSIC1_ADDR);
186 mcam_reg_write(mcam, REG_TWSIC1, rval);
187 spin_unlock_irqrestore(&mcam->dev_lock, flags);
188
189 /* Unfortunately, reading TWSIC1 too soon after sending a command
190 * causes the device to die.
191 * Use a busy-wait because we often send a large quantity of small
192 * commands at-once; using msleep() would cause a lot of context
193 * switches which take longer than 2ms, resulting in a noticeable
194 * boot-time and capture-start delays.
195 */
196 mdelay(2);
197
198 /*
199 * Another sad fact is that sometimes, commands silently complete but
200 * cafe_smbus_write_done() never becomes aware of this.
201 * This happens at random and appears to possible occur with any
202 * command.
203 * We don't understand why this is. We work around this issue
204 * with the timeout in the wait below, assuming that all commands
205 * complete within the timeout.
206 */
207 wait_event_timeout(cam->smbus_wait, cafe_smbus_write_done(mcam),
208 CAFE_SMBUS_TIMEOUT);
209
210 spin_lock_irqsave(&mcam->dev_lock, flags);
211 rval = mcam_reg_read(mcam, REG_TWSIC1);
212 spin_unlock_irqrestore(&mcam->dev_lock, flags);
213
214 if (rval & TWSIC1_WSTAT) {
215 cam_err(cam, "SMBUS write (%02x/%02x/%02x) timed out\n", addr,
216 command, value);
217 return -EIO;
218 }
219 if (rval & TWSIC1_ERROR) {
220 cam_err(cam, "SMBUS write (%02x/%02x/%02x) error\n", addr,
221 command, value);
222 return -EIO;
223 }
224 return 0;
225}
226
227
228
229static int cafe_smbus_read_done(struct mcam_camera *mcam)
230{
231 unsigned long flags;
232 int c1;
233
234 /*
235 * We must delay after the interrupt, or the controller gets confused
236 * and never does give us good status. Fortunately, we don't do this
237 * often.
238 */
239 udelay(20);
240 spin_lock_irqsave(&mcam->dev_lock, flags);
241 c1 = mcam_reg_read(mcam, REG_TWSIC1);
242 spin_unlock_irqrestore(&mcam->dev_lock, flags);
243 return c1 & (TWSIC1_RVALID|TWSIC1_ERROR);
244}
245
246
247
248static int cafe_smbus_read_data(struct cafe_camera *cam,
249 u16 addr, u8 command, u8 *value)
250{
251 unsigned int rval;
252 unsigned long flags;
253 struct mcam_camera *mcam = &cam->mcam;
254
255 spin_lock_irqsave(&mcam->dev_lock, flags);
256 rval = TWSIC0_EN | ((addr << TWSIC0_SID_SHIFT) & TWSIC0_SID);
257 rval |= TWSIC0_OVMAGIC; /* Make OV sensors work */
258 /*
259 * Marvel sez set clkdiv to all 1's for now.
260 */
261 rval |= TWSIC0_CLKDIV;
262 mcam_reg_write(mcam, REG_TWSIC0, rval);
263 (void) mcam_reg_read(mcam, REG_TWSIC1); /* force write */
264 rval = TWSIC1_READ | ((command << TWSIC1_ADDR_SHIFT) & TWSIC1_ADDR);
265 mcam_reg_write(mcam, REG_TWSIC1, rval);
266 spin_unlock_irqrestore(&mcam->dev_lock, flags);
267
268 wait_event_timeout(cam->smbus_wait,
269 cafe_smbus_read_done(mcam), CAFE_SMBUS_TIMEOUT);
270 spin_lock_irqsave(&mcam->dev_lock, flags);
271 rval = mcam_reg_read(mcam, REG_TWSIC1);
272 spin_unlock_irqrestore(&mcam->dev_lock, flags);
273
274 if (rval & TWSIC1_ERROR) {
275 cam_err(cam, "SMBUS read (%02x/%02x) error\n", addr, command);
276 return -EIO;
277 }
278 if (!(rval & TWSIC1_RVALID)) {
279 cam_err(cam, "SMBUS read (%02x/%02x) timed out\n", addr,
280 command);
281 return -EIO;
282 }
283 *value = rval & 0xff;
284 return 0;
285}
286
287/*
288 * Perform a transfer over SMBUS. This thing is called under
289 * the i2c bus lock, so we shouldn't race with ourselves...
290 */
291static int cafe_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
292 unsigned short flags, char rw, u8 command,
293 int size, union i2c_smbus_data *data)
294{
295 struct cafe_camera *cam = i2c_get_adapdata(adapter);
296 int ret = -EINVAL;
297
298 /*
299 * This interface would appear to only do byte data ops. OK
300 * it can do word too, but the cam chip has no use for that.
301 */
302 if (size != I2C_SMBUS_BYTE_DATA) {
303 cam_err(cam, "funky xfer size %d\n", size);
304 return -EINVAL;
305 }
306
307 if (rw == I2C_SMBUS_WRITE)
308 ret = cafe_smbus_write_data(cam, addr, command, data->byte);
309 else if (rw == I2C_SMBUS_READ)
310 ret = cafe_smbus_read_data(cam, addr, command, &data->byte);
311 return ret;
312}
313
314
315static void cafe_smbus_enable_irq(struct cafe_camera *cam)
316{
317 unsigned long flags;
318
319 spin_lock_irqsave(&cam->mcam.dev_lock, flags);
320 mcam_reg_set_bit(&cam->mcam, REG_IRQMASK, TWSIIRQS);
321 spin_unlock_irqrestore(&cam->mcam.dev_lock, flags);
322}
323
324static u32 cafe_smbus_func(struct i2c_adapter *adapter)
325{
326 return I2C_FUNC_SMBUS_READ_BYTE_DATA |
327 I2C_FUNC_SMBUS_WRITE_BYTE_DATA;
328}
329
330static struct i2c_algorithm cafe_smbus_algo = {
331 .smbus_xfer = cafe_smbus_xfer,
332 .functionality = cafe_smbus_func
333};
334
335static int cafe_smbus_setup(struct cafe_camera *cam)
336{
337 struct i2c_adapter *adap;
338 int ret;
339
340 adap = kzalloc(sizeof(*adap), GFP_KERNEL);
341 if (adap == NULL)
342 return -ENOMEM;
343 cam->mcam.i2c_adapter = adap;
344 cafe_smbus_enable_irq(cam);
345 adap->owner = THIS_MODULE;
346 adap->algo = &cafe_smbus_algo;
347 strcpy(adap->name, "cafe_ccic");
348 adap->dev.parent = &cam->pdev->dev;
349 i2c_set_adapdata(adap, cam);
350 ret = i2c_add_adapter(adap);
351 if (ret)
352 printk(KERN_ERR "Unable to register cafe i2c adapter\n");
353 return ret;
354}
355
356static void cafe_smbus_shutdown(struct cafe_camera *cam)
357{
358 i2c_del_adapter(cam->mcam.i2c_adapter);
359 kfree(cam->mcam.i2c_adapter);
360}
361
362
363/*
364 * Controller-level stuff
365 */
366
367static void cafe_ctlr_init(struct mcam_camera *mcam)
368{
369 unsigned long flags;
370
371 spin_lock_irqsave(&mcam->dev_lock, flags);
372 /*
373 * Added magic to bring up the hardware on the B-Test board
374 */
375 mcam_reg_write(mcam, 0x3038, 0x8);
376 mcam_reg_write(mcam, 0x315c, 0x80008);
377 /*
378 * Go through the dance needed to wake the device up.
379 * Note that these registers are global and shared
380 * with the NAND and SD devices. Interaction between the
381 * three still needs to be examined.
382 */
383 mcam_reg_write(mcam, REG_GL_CSR, GCSR_SRS|GCSR_MRS); /* Needed? */
384 mcam_reg_write(mcam, REG_GL_CSR, GCSR_SRC|GCSR_MRC);
385 mcam_reg_write(mcam, REG_GL_CSR, GCSR_SRC|GCSR_MRS);
386 /*
387 * Here we must wait a bit for the controller to come around.
388 */
389 spin_unlock_irqrestore(&mcam->dev_lock, flags);
390 msleep(5);
391 spin_lock_irqsave(&mcam->dev_lock, flags);
392
393 mcam_reg_write(mcam, REG_GL_CSR, GCSR_CCIC_EN|GCSR_SRC|GCSR_MRC);
394 mcam_reg_set_bit(mcam, REG_GL_IMASK, GIMSK_CCIC_EN);
395 /*
396 * Mask all interrupts.
397 */
398 mcam_reg_write(mcam, REG_IRQMASK, 0);
399 spin_unlock_irqrestore(&mcam->dev_lock, flags);
400}
401
402
403static void cafe_ctlr_power_up(struct mcam_camera *mcam)
404{
405 /*
406 * Part one of the sensor dance: turn the global
407 * GPIO signal on.
408 */
409 mcam_reg_write(mcam, REG_GL_FCR, GFCR_GPIO_ON);
410 mcam_reg_write(mcam, REG_GL_GPIOR, GGPIO_OUT|GGPIO_VAL);
411 /*
412 * Put the sensor into operational mode (assumes OLPC-style
413 * wiring). Control 0 is reset - set to 1 to operate.
414 * Control 1 is power down, set to 0 to operate.
415 */
416 mcam_reg_write(mcam, REG_GPR, GPR_C1EN|GPR_C0EN); /* pwr up, reset */
417 mcam_reg_write(mcam, REG_GPR, GPR_C1EN|GPR_C0EN|GPR_C0);
418}
419
420static void cafe_ctlr_power_down(struct mcam_camera *mcam)
421{
422 mcam_reg_write(mcam, REG_GPR, GPR_C1EN|GPR_C0EN|GPR_C1);
423 mcam_reg_write(mcam, REG_GL_FCR, GFCR_GPIO_ON);
424 mcam_reg_write(mcam, REG_GL_GPIOR, GGPIO_OUT);
425}
426
427
428
429/*
430 * The platform interrupt handler.
431 */
432static irqreturn_t cafe_irq(int irq, void *data)
433{
434 struct cafe_camera *cam = data;
435 struct mcam_camera *mcam = &cam->mcam;
436 unsigned int irqs, handled;
437
438 spin_lock(&mcam->dev_lock);
439 irqs = mcam_reg_read(mcam, REG_IRQSTAT);
440 handled = cam->registered && mccic_irq(mcam, irqs);
441 if (irqs & TWSIIRQS) {
442 mcam_reg_write(mcam, REG_IRQSTAT, TWSIIRQS);
443 wake_up(&cam->smbus_wait);
444 handled = 1;
445 }
446 spin_unlock(&mcam->dev_lock);
447 return IRQ_RETVAL(handled);
448}
449
450
451/* -------------------------------------------------------------------------- */
452/*
453 * PCI interface stuff.
454 */
455
456static int cafe_pci_probe(struct pci_dev *pdev,
457 const struct pci_device_id *id)
458{
459 int ret;
460 struct cafe_camera *cam;
461 struct mcam_camera *mcam;
462
463 /*
464 * Start putting together one of our big camera structures.
465 */
466 ret = -ENOMEM;
467 cam = kzalloc(sizeof(struct cafe_camera), GFP_KERNEL);
468 if (cam == NULL)
469 goto out;
470 cam->pdev = pdev;
471 mcam = &cam->mcam;
472 mcam->chip_id = V4L2_IDENT_CAFE;
473 spin_lock_init(&mcam->dev_lock);
474 init_waitqueue_head(&cam->smbus_wait);
475 mcam->plat_power_up = cafe_ctlr_power_up;
476 mcam->plat_power_down = cafe_ctlr_power_down;
477 mcam->dev = &pdev->dev;
478 /*
479 * Set the clock speed for the XO 1; I don't believe this
480 * driver has ever run anywhere else.
481 */
482 mcam->clock_speed = 45;
483 mcam->use_smbus = 1;
484 /*
485 * Vmalloc mode for buffers is traditional with this driver.
486 * We *might* be able to run DMA_contig, especially on a system
487 * with CMA in it.
488 */
489 mcam->buffer_mode = B_vmalloc;
490 /*
491 * Get set up on the PCI bus.
492 */
493 ret = pci_enable_device(pdev);
494 if (ret)
495 goto out_free;
496 pci_set_master(pdev);
497
498 ret = -EIO;
499 mcam->regs = pci_iomap(pdev, 0, 0);
500 if (!mcam->regs) {
501 printk(KERN_ERR "Unable to ioremap cafe-ccic regs\n");
502 goto out_disable;
503 }
504 ret = request_irq(pdev->irq, cafe_irq, IRQF_SHARED, "cafe-ccic", cam);
505 if (ret)
506 goto out_iounmap;
507
508 /*
509 * Initialize the controller and leave it powered up. It will
510 * stay that way until the sensor driver shows up.
511 */
512 cafe_ctlr_init(mcam);
513 cafe_ctlr_power_up(mcam);
514 /*
515 * Set up I2C/SMBUS communications. We have to drop the mutex here
516 * because the sensor could attach in this call chain, leading to
517 * unsightly deadlocks.
518 */
519 ret = cafe_smbus_setup(cam);
520 if (ret)
521 goto out_pdown;
522
523 ret = mccic_register(mcam);
524 if (ret == 0) {
525 cam->registered = 1;
526 return 0;
527 }
528
529 cafe_smbus_shutdown(cam);
530out_pdown:
531 cafe_ctlr_power_down(mcam);
532 free_irq(pdev->irq, cam);
533out_iounmap:
534 pci_iounmap(pdev, mcam->regs);
535out_disable:
536 pci_disable_device(pdev);
537out_free:
538 kfree(cam);
539out:
540 return ret;
541}
542
543
544/*
545 * Shut down an initialized device
546 */
547static void cafe_shutdown(struct cafe_camera *cam)
548{
549 mccic_shutdown(&cam->mcam);
550 cafe_smbus_shutdown(cam);
551 free_irq(cam->pdev->irq, cam);
552 pci_iounmap(cam->pdev, cam->mcam.regs);
553}
554
555
556static void cafe_pci_remove(struct pci_dev *pdev)
557{
558 struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev);
559 struct cafe_camera *cam = to_cam(v4l2_dev);
560
561 if (cam == NULL) {
562 printk(KERN_WARNING "pci_remove on unknown pdev %p\n", pdev);
563 return;
564 }
565 cafe_shutdown(cam);
566 kfree(cam);
567}
568
569
570#ifdef CONFIG_PM
571/*
572 * Basic power management.
573 */
574static int cafe_pci_suspend(struct pci_dev *pdev, pm_message_t state)
575{
576 struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev);
577 struct cafe_camera *cam = to_cam(v4l2_dev);
578 int ret;
579
580 ret = pci_save_state(pdev);
581 if (ret)
582 return ret;
583 mccic_suspend(&cam->mcam);
584 pci_disable_device(pdev);
585 return 0;
586}
587
588
589static int cafe_pci_resume(struct pci_dev *pdev)
590{
591 struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev);
592 struct cafe_camera *cam = to_cam(v4l2_dev);
593 int ret = 0;
594
595 pci_restore_state(pdev);
596 ret = pci_enable_device(pdev);
597
598 if (ret) {
599 cam_warn(cam, "Unable to re-enable device on resume!\n");
600 return ret;
601 }
602 cafe_ctlr_init(&cam->mcam);
603 return mccic_resume(&cam->mcam);
604}
605
606#endif /* CONFIG_PM */
607
608static struct pci_device_id cafe_ids[] = {
609 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL,
610 PCI_DEVICE_ID_MARVELL_88ALP01_CCIC) },
611 { 0, }
612};
613
614MODULE_DEVICE_TABLE(pci, cafe_ids);
615
616static struct pci_driver cafe_pci_driver = {
617 .name = "cafe1000-ccic",
618 .id_table = cafe_ids,
619 .probe = cafe_pci_probe,
620 .remove = cafe_pci_remove,
621#ifdef CONFIG_PM
622 .suspend = cafe_pci_suspend,
623 .resume = cafe_pci_resume,
624#endif
625};
626
627
628
629
630static int __init cafe_init(void)
631{
632 int ret;
633
634 printk(KERN_NOTICE "Marvell M88ALP01 'CAFE' Camera Controller version %d\n",
635 CAFE_VERSION);
636 ret = pci_register_driver(&cafe_pci_driver);
637 if (ret) {
638 printk(KERN_ERR "Unable to register cafe_ccic driver\n");
639 goto out;
640 }
641 ret = 0;
642
643out:
644 return ret;
645}
646
647
648static void __exit cafe_exit(void)
649{
650 pci_unregister_driver(&cafe_pci_driver);
651}
652
653module_init(cafe_init);
654module_exit(cafe_exit);
diff --git a/drivers/media/video/marvell-ccic/mcam-core.c b/drivers/media/video/marvell-ccic/mcam-core.c
deleted file mode 100644
index ce2b7b4788d6..000000000000
--- a/drivers/media/video/marvell-ccic/mcam-core.c
+++ /dev/null
@@ -1,1878 +0,0 @@
1/*
2 * The Marvell camera core. This device appears in a number of settings,
3 * so it needs platform-specific support outside of the core.
4 *
5 * Copyright 2011 Jonathan Corbet corbet@lwn.net
6 */
7#include <linux/kernel.h>
8#include <linux/module.h>
9#include <linux/fs.h>
10#include <linux/mm.h>
11#include <linux/i2c.h>
12#include <linux/interrupt.h>
13#include <linux/spinlock.h>
14#include <linux/slab.h>
15#include <linux/device.h>
16#include <linux/wait.h>
17#include <linux/list.h>
18#include <linux/dma-mapping.h>
19#include <linux/delay.h>
20#include <linux/vmalloc.h>
21#include <linux/io.h>
22#include <linux/videodev2.h>
23#include <media/v4l2-device.h>
24#include <media/v4l2-ioctl.h>
25#include <media/v4l2-chip-ident.h>
26#include <media/ov7670.h>
27#include <media/videobuf2-vmalloc.h>
28#include <media/videobuf2-dma-contig.h>
29#include <media/videobuf2-dma-sg.h>
30
31#include "mcam-core.h"
32
33/*
34 * Basic frame stats - to be deleted shortly
35 */
36static int frames;
37static int singles;
38static int delivered;
39
40#ifdef MCAM_MODE_VMALLOC
41/*
42 * Internal DMA buffer management. Since the controller cannot do S/G I/O,
43 * we must have physically contiguous buffers to bring frames into.
44 * These parameters control how many buffers we use, whether we
45 * allocate them at load time (better chance of success, but nails down
46 * memory) or when somebody tries to use the camera (riskier), and,
47 * for load-time allocation, how big they should be.
48 *
49 * The controller can cycle through three buffers. We could use
50 * more by flipping pointers around, but it probably makes little
51 * sense.
52 */
53
54static bool alloc_bufs_at_read;
55module_param(alloc_bufs_at_read, bool, 0444);
56MODULE_PARM_DESC(alloc_bufs_at_read,
57 "Non-zero value causes DMA buffers to be allocated when the "
58 "video capture device is read, rather than at module load "
59 "time. This saves memory, but decreases the chances of "
60 "successfully getting those buffers. This parameter is "
61 "only used in the vmalloc buffer mode");
62
63static int n_dma_bufs = 3;
64module_param(n_dma_bufs, uint, 0644);
65MODULE_PARM_DESC(n_dma_bufs,
66 "The number of DMA buffers to allocate. Can be either two "
67 "(saves memory, makes timing tighter) or three.");
68
69static int dma_buf_size = VGA_WIDTH * VGA_HEIGHT * 2; /* Worst case */
70module_param(dma_buf_size, uint, 0444);
71MODULE_PARM_DESC(dma_buf_size,
72 "The size of the allocated DMA buffers. If actual operating "
73 "parameters require larger buffers, an attempt to reallocate "
74 "will be made.");
75#else /* MCAM_MODE_VMALLOC */
76static const bool alloc_bufs_at_read = 0;
77static const int n_dma_bufs = 3; /* Used by S/G_PARM */
78#endif /* MCAM_MODE_VMALLOC */
79
80static bool flip;
81module_param(flip, bool, 0444);
82MODULE_PARM_DESC(flip,
83 "If set, the sensor will be instructed to flip the image "
84 "vertically.");
85
86static int buffer_mode = -1;
87module_param(buffer_mode, int, 0444);
88MODULE_PARM_DESC(buffer_mode,
89 "Set the buffer mode to be used; default is to go with what "
90 "the platform driver asks for. Set to 0 for vmalloc, 1 for "
91 "DMA contiguous.");
92
93/*
94 * Status flags. Always manipulated with bit operations.
95 */
96#define CF_BUF0_VALID 0 /* Buffers valid - first three */
97#define CF_BUF1_VALID 1
98#define CF_BUF2_VALID 2
99#define CF_DMA_ACTIVE 3 /* A frame is incoming */
100#define CF_CONFIG_NEEDED 4 /* Must configure hardware */
101#define CF_SINGLE_BUFFER 5 /* Running with a single buffer */
102#define CF_SG_RESTART 6 /* SG restart needed */
103
104#define sensor_call(cam, o, f, args...) \
105 v4l2_subdev_call(cam->sensor, o, f, ##args)
106
107static struct mcam_format_struct {
108 __u8 *desc;
109 __u32 pixelformat;
110 int bpp; /* Bytes per pixel */
111 enum v4l2_mbus_pixelcode mbus_code;
112} mcam_formats[] = {
113 {
114 .desc = "YUYV 4:2:2",
115 .pixelformat = V4L2_PIX_FMT_YUYV,
116 .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8,
117 .bpp = 2,
118 },
119 {
120 .desc = "RGB 444",
121 .pixelformat = V4L2_PIX_FMT_RGB444,
122 .mbus_code = V4L2_MBUS_FMT_RGB444_2X8_PADHI_LE,
123 .bpp = 2,
124 },
125 {
126 .desc = "RGB 565",
127 .pixelformat = V4L2_PIX_FMT_RGB565,
128 .mbus_code = V4L2_MBUS_FMT_RGB565_2X8_LE,
129 .bpp = 2,
130 },
131 {
132 .desc = "Raw RGB Bayer",
133 .pixelformat = V4L2_PIX_FMT_SBGGR8,
134 .mbus_code = V4L2_MBUS_FMT_SBGGR8_1X8,
135 .bpp = 1
136 },
137};
138#define N_MCAM_FMTS ARRAY_SIZE(mcam_formats)
139
140static struct mcam_format_struct *mcam_find_format(u32 pixelformat)
141{
142 unsigned i;
143
144 for (i = 0; i < N_MCAM_FMTS; i++)
145 if (mcam_formats[i].pixelformat == pixelformat)
146 return mcam_formats + i;
147 /* Not found? Then return the first format. */
148 return mcam_formats;
149}
150
151/*
152 * The default format we use until somebody says otherwise.
153 */
154static const struct v4l2_pix_format mcam_def_pix_format = {
155 .width = VGA_WIDTH,
156 .height = VGA_HEIGHT,
157 .pixelformat = V4L2_PIX_FMT_YUYV,
158 .field = V4L2_FIELD_NONE,
159 .bytesperline = VGA_WIDTH*2,
160 .sizeimage = VGA_WIDTH*VGA_HEIGHT*2,
161};
162
163static const enum v4l2_mbus_pixelcode mcam_def_mbus_code =
164 V4L2_MBUS_FMT_YUYV8_2X8;
165
166
167/*
168 * The two-word DMA descriptor format used by the Armada 610 and like. There
169 * Is a three-word format as well (set C1_DESC_3WORD) where the third
170 * word is a pointer to the next descriptor, but we don't use it. Two-word
171 * descriptors have to be contiguous in memory.
172 */
173struct mcam_dma_desc {
174 u32 dma_addr;
175 u32 segment_len;
176};
177
178/*
179 * Our buffer type for working with videobuf2. Note that the vb2
180 * developers have decreed that struct vb2_buffer must be at the
181 * beginning of this structure.
182 */
183struct mcam_vb_buffer {
184 struct vb2_buffer vb_buf;
185 struct list_head queue;
186 struct mcam_dma_desc *dma_desc; /* Descriptor virtual address */
187 dma_addr_t dma_desc_pa; /* Descriptor physical address */
188 int dma_desc_nent; /* Number of mapped descriptors */
189};
190
191static inline struct mcam_vb_buffer *vb_to_mvb(struct vb2_buffer *vb)
192{
193 return container_of(vb, struct mcam_vb_buffer, vb_buf);
194}
195
196/*
197 * Hand a completed buffer back to user space.
198 */
199static void mcam_buffer_done(struct mcam_camera *cam, int frame,
200 struct vb2_buffer *vbuf)
201{
202 vbuf->v4l2_buf.bytesused = cam->pix_format.sizeimage;
203 vbuf->v4l2_buf.sequence = cam->buf_seq[frame];
204 vb2_set_plane_payload(vbuf, 0, cam->pix_format.sizeimage);
205 vb2_buffer_done(vbuf, VB2_BUF_STATE_DONE);
206}
207
208
209
210/*
211 * Debugging and related.
212 */
213#define cam_err(cam, fmt, arg...) \
214 dev_err((cam)->dev, fmt, ##arg);
215#define cam_warn(cam, fmt, arg...) \
216 dev_warn((cam)->dev, fmt, ##arg);
217#define cam_dbg(cam, fmt, arg...) \
218 dev_dbg((cam)->dev, fmt, ##arg);
219
220
221/*
222 * Flag manipulation helpers
223 */
224static void mcam_reset_buffers(struct mcam_camera *cam)
225{
226 int i;
227
228 cam->next_buf = -1;
229 for (i = 0; i < cam->nbufs; i++)
230 clear_bit(i, &cam->flags);
231}
232
233static inline int mcam_needs_config(struct mcam_camera *cam)
234{
235 return test_bit(CF_CONFIG_NEEDED, &cam->flags);
236}
237
238static void mcam_set_config_needed(struct mcam_camera *cam, int needed)
239{
240 if (needed)
241 set_bit(CF_CONFIG_NEEDED, &cam->flags);
242 else
243 clear_bit(CF_CONFIG_NEEDED, &cam->flags);
244}
245
246/* ------------------------------------------------------------------- */
247/*
248 * Make the controller start grabbing images. Everything must
249 * be set up before doing this.
250 */
251static void mcam_ctlr_start(struct mcam_camera *cam)
252{
253 /* set_bit performs a read, so no other barrier should be
254 needed here */
255 mcam_reg_set_bit(cam, REG_CTRL0, C0_ENABLE);
256}
257
258static void mcam_ctlr_stop(struct mcam_camera *cam)
259{
260 mcam_reg_clear_bit(cam, REG_CTRL0, C0_ENABLE);
261}
262
263/* ------------------------------------------------------------------- */
264
265#ifdef MCAM_MODE_VMALLOC
266/*
267 * Code specific to the vmalloc buffer mode.
268 */
269
270/*
271 * Allocate in-kernel DMA buffers for vmalloc mode.
272 */
273static int mcam_alloc_dma_bufs(struct mcam_camera *cam, int loadtime)
274{
275 int i;
276
277 mcam_set_config_needed(cam, 1);
278 if (loadtime)
279 cam->dma_buf_size = dma_buf_size;
280 else
281 cam->dma_buf_size = cam->pix_format.sizeimage;
282 if (n_dma_bufs > 3)
283 n_dma_bufs = 3;
284
285 cam->nbufs = 0;
286 for (i = 0; i < n_dma_bufs; i++) {
287 cam->dma_bufs[i] = dma_alloc_coherent(cam->dev,
288 cam->dma_buf_size, cam->dma_handles + i,
289 GFP_KERNEL);
290 if (cam->dma_bufs[i] == NULL) {
291 cam_warn(cam, "Failed to allocate DMA buffer\n");
292 break;
293 }
294 (cam->nbufs)++;
295 }
296
297 switch (cam->nbufs) {
298 case 1:
299 dma_free_coherent(cam->dev, cam->dma_buf_size,
300 cam->dma_bufs[0], cam->dma_handles[0]);
301 cam->nbufs = 0;
302 case 0:
303 cam_err(cam, "Insufficient DMA buffers, cannot operate\n");
304 return -ENOMEM;
305
306 case 2:
307 if (n_dma_bufs > 2)
308 cam_warn(cam, "Will limp along with only 2 buffers\n");
309 break;
310 }
311 return 0;
312}
313
314static void mcam_free_dma_bufs(struct mcam_camera *cam)
315{
316 int i;
317
318 for (i = 0; i < cam->nbufs; i++) {
319 dma_free_coherent(cam->dev, cam->dma_buf_size,
320 cam->dma_bufs[i], cam->dma_handles[i]);
321 cam->dma_bufs[i] = NULL;
322 }
323 cam->nbufs = 0;
324}
325
326
327/*
328 * Set up DMA buffers when operating in vmalloc mode
329 */
330static void mcam_ctlr_dma_vmalloc(struct mcam_camera *cam)
331{
332 /*
333 * Store the first two Y buffers (we aren't supporting
334 * planar formats for now, so no UV bufs). Then either
335 * set the third if it exists, or tell the controller
336 * to just use two.
337 */
338 mcam_reg_write(cam, REG_Y0BAR, cam->dma_handles[0]);
339 mcam_reg_write(cam, REG_Y1BAR, cam->dma_handles[1]);
340 if (cam->nbufs > 2) {
341 mcam_reg_write(cam, REG_Y2BAR, cam->dma_handles[2]);
342 mcam_reg_clear_bit(cam, REG_CTRL1, C1_TWOBUFS);
343 } else
344 mcam_reg_set_bit(cam, REG_CTRL1, C1_TWOBUFS);
345 if (cam->chip_id == V4L2_IDENT_CAFE)
346 mcam_reg_write(cam, REG_UBAR, 0); /* 32 bits only */
347}
348
349/*
350 * Copy data out to user space in the vmalloc case
351 */
352static void mcam_frame_tasklet(unsigned long data)
353{
354 struct mcam_camera *cam = (struct mcam_camera *) data;
355 int i;
356 unsigned long flags;
357 struct mcam_vb_buffer *buf;
358
359 spin_lock_irqsave(&cam->dev_lock, flags);
360 for (i = 0; i < cam->nbufs; i++) {
361 int bufno = cam->next_buf;
362
363 if (cam->state != S_STREAMING || bufno < 0)
364 break; /* I/O got stopped */
365 if (++(cam->next_buf) >= cam->nbufs)
366 cam->next_buf = 0;
367 if (!test_bit(bufno, &cam->flags))
368 continue;
369 if (list_empty(&cam->buffers)) {
370 singles++;
371 break; /* Leave it valid, hope for better later */
372 }
373 delivered++;
374 clear_bit(bufno, &cam->flags);
375 buf = list_first_entry(&cam->buffers, struct mcam_vb_buffer,
376 queue);
377 list_del_init(&buf->queue);
378 /*
379 * Drop the lock during the big copy. This *should* be safe...
380 */
381 spin_unlock_irqrestore(&cam->dev_lock, flags);
382 memcpy(vb2_plane_vaddr(&buf->vb_buf, 0), cam->dma_bufs[bufno],
383 cam->pix_format.sizeimage);
384 mcam_buffer_done(cam, bufno, &buf->vb_buf);
385 spin_lock_irqsave(&cam->dev_lock, flags);
386 }
387 spin_unlock_irqrestore(&cam->dev_lock, flags);
388}
389
390
391/*
392 * Make sure our allocated buffers are up to the task.
393 */
394static int mcam_check_dma_buffers(struct mcam_camera *cam)
395{
396 if (cam->nbufs > 0 && cam->dma_buf_size < cam->pix_format.sizeimage)
397 mcam_free_dma_bufs(cam);
398 if (cam->nbufs == 0)
399 return mcam_alloc_dma_bufs(cam, 0);
400 return 0;
401}
402
403static void mcam_vmalloc_done(struct mcam_camera *cam, int frame)
404{
405 tasklet_schedule(&cam->s_tasklet);
406}
407
408#else /* MCAM_MODE_VMALLOC */
409
410static inline int mcam_alloc_dma_bufs(struct mcam_camera *cam, int loadtime)
411{
412 return 0;
413}
414
415static inline void mcam_free_dma_bufs(struct mcam_camera *cam)
416{
417 return;
418}
419
420static inline int mcam_check_dma_buffers(struct mcam_camera *cam)
421{
422 return 0;
423}
424
425
426
427#endif /* MCAM_MODE_VMALLOC */
428
429
430#ifdef MCAM_MODE_DMA_CONTIG
431/* ---------------------------------------------------------------------- */
432/*
433 * DMA-contiguous code.
434 */
435/*
436 * Set up a contiguous buffer for the given frame. Here also is where
437 * the underrun strategy is set: if there is no buffer available, reuse
438 * the buffer from the other BAR and set the CF_SINGLE_BUFFER flag to
439 * keep the interrupt handler from giving that buffer back to user
440 * space. In this way, we always have a buffer to DMA to and don't
441 * have to try to play games stopping and restarting the controller.
442 */
443static void mcam_set_contig_buffer(struct mcam_camera *cam, int frame)
444{
445 struct mcam_vb_buffer *buf;
446 /*
447 * If there are no available buffers, go into single mode
448 */
449 if (list_empty(&cam->buffers)) {
450 buf = cam->vb_bufs[frame ^ 0x1];
451 cam->vb_bufs[frame] = buf;
452 mcam_reg_write(cam, frame == 0 ? REG_Y0BAR : REG_Y1BAR,
453 vb2_dma_contig_plane_dma_addr(&buf->vb_buf, 0));
454 set_bit(CF_SINGLE_BUFFER, &cam->flags);
455 singles++;
456 return;
457 }
458 /*
459 * OK, we have a buffer we can use.
460 */
461 buf = list_first_entry(&cam->buffers, struct mcam_vb_buffer, queue);
462 list_del_init(&buf->queue);
463 mcam_reg_write(cam, frame == 0 ? REG_Y0BAR : REG_Y1BAR,
464 vb2_dma_contig_plane_dma_addr(&buf->vb_buf, 0));
465 cam->vb_bufs[frame] = buf;
466 clear_bit(CF_SINGLE_BUFFER, &cam->flags);
467}
468
469/*
470 * Initial B_DMA_contig setup.
471 */
472static void mcam_ctlr_dma_contig(struct mcam_camera *cam)
473{
474 mcam_reg_set_bit(cam, REG_CTRL1, C1_TWOBUFS);
475 cam->nbufs = 2;
476 mcam_set_contig_buffer(cam, 0);
477 mcam_set_contig_buffer(cam, 1);
478}
479
480/*
481 * Frame completion handling.
482 */
483static void mcam_dma_contig_done(struct mcam_camera *cam, int frame)
484{
485 struct mcam_vb_buffer *buf = cam->vb_bufs[frame];
486
487 if (!test_bit(CF_SINGLE_BUFFER, &cam->flags)) {
488 delivered++;
489 mcam_buffer_done(cam, frame, &buf->vb_buf);
490 }
491 mcam_set_contig_buffer(cam, frame);
492}
493
494#endif /* MCAM_MODE_DMA_CONTIG */
495
496#ifdef MCAM_MODE_DMA_SG
497/* ---------------------------------------------------------------------- */
498/*
499 * Scatter/gather-specific code.
500 */
501
502/*
503 * Set up the next buffer for S/G I/O; caller should be sure that
504 * the controller is stopped and a buffer is available.
505 */
506static void mcam_sg_next_buffer(struct mcam_camera *cam)
507{
508 struct mcam_vb_buffer *buf;
509
510 buf = list_first_entry(&cam->buffers, struct mcam_vb_buffer, queue);
511 list_del_init(&buf->queue);
512 /*
513 * Very Bad Not Good Things happen if you don't clear
514 * C1_DESC_ENA before making any descriptor changes.
515 */
516 mcam_reg_clear_bit(cam, REG_CTRL1, C1_DESC_ENA);
517 mcam_reg_write(cam, REG_DMA_DESC_Y, buf->dma_desc_pa);
518 mcam_reg_write(cam, REG_DESC_LEN_Y,
519 buf->dma_desc_nent*sizeof(struct mcam_dma_desc));
520 mcam_reg_write(cam, REG_DESC_LEN_U, 0);
521 mcam_reg_write(cam, REG_DESC_LEN_V, 0);
522 mcam_reg_set_bit(cam, REG_CTRL1, C1_DESC_ENA);
523 cam->vb_bufs[0] = buf;
524}
525
526/*
527 * Initial B_DMA_sg setup
528 */
529static void mcam_ctlr_dma_sg(struct mcam_camera *cam)
530{
531 /*
532 * The list-empty condition can hit us at resume time
533 * if the buffer list was empty when the system was suspended.
534 */
535 if (list_empty(&cam->buffers)) {
536 set_bit(CF_SG_RESTART, &cam->flags);
537 return;
538 }
539
540 mcam_reg_clear_bit(cam, REG_CTRL1, C1_DESC_3WORD);
541 mcam_sg_next_buffer(cam);
542 cam->nbufs = 3;
543}
544
545
546/*
547 * Frame completion with S/G is trickier. We can't muck with
548 * a descriptor chain on the fly, since the controller buffers it
549 * internally. So we have to actually stop and restart; Marvell
550 * says this is the way to do it.
551 *
552 * Of course, stopping is easier said than done; experience shows
553 * that the controller can start a frame *after* C0_ENABLE has been
554 * cleared. So when running in S/G mode, the controller is "stopped"
555 * on receipt of the start-of-frame interrupt. That means we can
556 * safely change the DMA descriptor array here and restart things
557 * (assuming there's another buffer waiting to go).
558 */
559static void mcam_dma_sg_done(struct mcam_camera *cam, int frame)
560{
561 struct mcam_vb_buffer *buf = cam->vb_bufs[0];
562
563 /*
564 * If we're no longer supposed to be streaming, don't do anything.
565 */
566 if (cam->state != S_STREAMING)
567 return;
568 /*
569 * If we have another buffer available, put it in and
570 * restart the engine.
571 */
572 if (!list_empty(&cam->buffers)) {
573 mcam_sg_next_buffer(cam);
574 mcam_ctlr_start(cam);
575 /*
576 * Otherwise set CF_SG_RESTART and the controller will
577 * be restarted once another buffer shows up.
578 */
579 } else {
580 set_bit(CF_SG_RESTART, &cam->flags);
581 singles++;
582 cam->vb_bufs[0] = NULL;
583 }
584 /*
585 * Now we can give the completed frame back to user space.
586 */
587 delivered++;
588 mcam_buffer_done(cam, frame, &buf->vb_buf);
589}
590
591
592/*
593 * Scatter/gather mode requires stopping the controller between
594 * frames so we can put in a new DMA descriptor array. If no new
595 * buffer exists at frame completion, the controller is left stopped;
596 * this function is charged with gettig things going again.
597 */
598static void mcam_sg_restart(struct mcam_camera *cam)
599{
600 mcam_ctlr_dma_sg(cam);
601 mcam_ctlr_start(cam);
602 clear_bit(CF_SG_RESTART, &cam->flags);
603}
604
605#else /* MCAM_MODE_DMA_SG */
606
607static inline void mcam_sg_restart(struct mcam_camera *cam)
608{
609 return;
610}
611
612#endif /* MCAM_MODE_DMA_SG */
613
614/* ---------------------------------------------------------------------- */
615/*
616 * Buffer-mode-independent controller code.
617 */
618
619/*
620 * Image format setup
621 */
622static void mcam_ctlr_image(struct mcam_camera *cam)
623{
624 int imgsz;
625 struct v4l2_pix_format *fmt = &cam->pix_format;
626
627 imgsz = ((fmt->height << IMGSZ_V_SHIFT) & IMGSZ_V_MASK) |
628 (fmt->bytesperline & IMGSZ_H_MASK);
629 mcam_reg_write(cam, REG_IMGSIZE, imgsz);
630 mcam_reg_write(cam, REG_IMGOFFSET, 0);
631 /* YPITCH just drops the last two bits */
632 mcam_reg_write_mask(cam, REG_IMGPITCH, fmt->bytesperline,
633 IMGP_YP_MASK);
634 /*
635 * Tell the controller about the image format we are using.
636 */
637 switch (cam->pix_format.pixelformat) {
638 case V4L2_PIX_FMT_YUYV:
639 mcam_reg_write_mask(cam, REG_CTRL0,
640 C0_DF_YUV|C0_YUV_PACKED|C0_YUVE_YUYV,
641 C0_DF_MASK);
642 break;
643
644 case V4L2_PIX_FMT_RGB444:
645 mcam_reg_write_mask(cam, REG_CTRL0,
646 C0_DF_RGB|C0_RGBF_444|C0_RGB4_XRGB,
647 C0_DF_MASK);
648 /* Alpha value? */
649 break;
650
651 case V4L2_PIX_FMT_RGB565:
652 mcam_reg_write_mask(cam, REG_CTRL0,
653 C0_DF_RGB|C0_RGBF_565|C0_RGB5_BGGR,
654 C0_DF_MASK);
655 break;
656
657 default:
658 cam_err(cam, "Unknown format %x\n", cam->pix_format.pixelformat);
659 break;
660 }
661 /*
662 * Make sure it knows we want to use hsync/vsync.
663 */
664 mcam_reg_write_mask(cam, REG_CTRL0, C0_SIF_HVSYNC,
665 C0_SIFM_MASK);
666}
667
668
669/*
670 * Configure the controller for operation; caller holds the
671 * device mutex.
672 */
673static int mcam_ctlr_configure(struct mcam_camera *cam)
674{
675 unsigned long flags;
676
677 spin_lock_irqsave(&cam->dev_lock, flags);
678 clear_bit(CF_SG_RESTART, &cam->flags);
679 cam->dma_setup(cam);
680 mcam_ctlr_image(cam);
681 mcam_set_config_needed(cam, 0);
682 spin_unlock_irqrestore(&cam->dev_lock, flags);
683 return 0;
684}
685
686static void mcam_ctlr_irq_enable(struct mcam_camera *cam)
687{
688 /*
689 * Clear any pending interrupts, since we do not
690 * expect to have I/O active prior to enabling.
691 */
692 mcam_reg_write(cam, REG_IRQSTAT, FRAMEIRQS);
693 mcam_reg_set_bit(cam, REG_IRQMASK, FRAMEIRQS);
694}
695
696static void mcam_ctlr_irq_disable(struct mcam_camera *cam)
697{
698 mcam_reg_clear_bit(cam, REG_IRQMASK, FRAMEIRQS);
699}
700
701
702
703static void mcam_ctlr_init(struct mcam_camera *cam)
704{
705 unsigned long flags;
706
707 spin_lock_irqsave(&cam->dev_lock, flags);
708 /*
709 * Make sure it's not powered down.
710 */
711 mcam_reg_clear_bit(cam, REG_CTRL1, C1_PWRDWN);
712 /*
713 * Turn off the enable bit. It sure should be off anyway,
714 * but it's good to be sure.
715 */
716 mcam_reg_clear_bit(cam, REG_CTRL0, C0_ENABLE);
717 /*
718 * Clock the sensor appropriately. Controller clock should
719 * be 48MHz, sensor "typical" value is half that.
720 */
721 mcam_reg_write_mask(cam, REG_CLKCTRL, 2, CLK_DIV_MASK);
722 spin_unlock_irqrestore(&cam->dev_lock, flags);
723}
724
725
726/*
727 * Stop the controller, and don't return until we're really sure that no
728 * further DMA is going on.
729 */
730static void mcam_ctlr_stop_dma(struct mcam_camera *cam)
731{
732 unsigned long flags;
733
734 /*
735 * Theory: stop the camera controller (whether it is operating
736 * or not). Delay briefly just in case we race with the SOF
737 * interrupt, then wait until no DMA is active.
738 */
739 spin_lock_irqsave(&cam->dev_lock, flags);
740 clear_bit(CF_SG_RESTART, &cam->flags);
741 mcam_ctlr_stop(cam);
742 cam->state = S_IDLE;
743 spin_unlock_irqrestore(&cam->dev_lock, flags);
744 /*
745 * This is a brutally long sleep, but experience shows that
746 * it can take the controller a while to get the message that
747 * it needs to stop grabbing frames. In particular, we can
748 * sometimes (on mmp) get a frame at the end WITHOUT the
749 * start-of-frame indication.
750 */
751 msleep(150);
752 if (test_bit(CF_DMA_ACTIVE, &cam->flags))
753 cam_err(cam, "Timeout waiting for DMA to end\n");
754 /* This would be bad news - what now? */
755 spin_lock_irqsave(&cam->dev_lock, flags);
756 mcam_ctlr_irq_disable(cam);
757 spin_unlock_irqrestore(&cam->dev_lock, flags);
758}
759
760/*
761 * Power up and down.
762 */
763static void mcam_ctlr_power_up(struct mcam_camera *cam)
764{
765 unsigned long flags;
766
767 spin_lock_irqsave(&cam->dev_lock, flags);
768 cam->plat_power_up(cam);
769 mcam_reg_clear_bit(cam, REG_CTRL1, C1_PWRDWN);
770 spin_unlock_irqrestore(&cam->dev_lock, flags);
771 msleep(5); /* Just to be sure */
772}
773
774static void mcam_ctlr_power_down(struct mcam_camera *cam)
775{
776 unsigned long flags;
777
778 spin_lock_irqsave(&cam->dev_lock, flags);
779 /*
780 * School of hard knocks department: be sure we do any register
781 * twiddling on the controller *before* calling the platform
782 * power down routine.
783 */
784 mcam_reg_set_bit(cam, REG_CTRL1, C1_PWRDWN);
785 cam->plat_power_down(cam);
786 spin_unlock_irqrestore(&cam->dev_lock, flags);
787}
788
789/* -------------------------------------------------------------------- */
790/*
791 * Communications with the sensor.
792 */
793
794static int __mcam_cam_reset(struct mcam_camera *cam)
795{
796 return sensor_call(cam, core, reset, 0);
797}
798
799/*
800 * We have found the sensor on the i2c. Let's try to have a
801 * conversation.
802 */
803static int mcam_cam_init(struct mcam_camera *cam)
804{
805 struct v4l2_dbg_chip_ident chip;
806 int ret;
807
808 mutex_lock(&cam->s_mutex);
809 if (cam->state != S_NOTREADY)
810 cam_warn(cam, "Cam init with device in funky state %d",
811 cam->state);
812 ret = __mcam_cam_reset(cam);
813 if (ret)
814 goto out;
815 chip.ident = V4L2_IDENT_NONE;
816 chip.match.type = V4L2_CHIP_MATCH_I2C_ADDR;
817 chip.match.addr = cam->sensor_addr;
818 ret = sensor_call(cam, core, g_chip_ident, &chip);
819 if (ret)
820 goto out;
821 cam->sensor_type = chip.ident;
822 if (cam->sensor_type != V4L2_IDENT_OV7670) {
823 cam_err(cam, "Unsupported sensor type 0x%x", cam->sensor_type);
824 ret = -EINVAL;
825 goto out;
826 }
827/* Get/set parameters? */
828 ret = 0;
829 cam->state = S_IDLE;
830out:
831 mcam_ctlr_power_down(cam);
832 mutex_unlock(&cam->s_mutex);
833 return ret;
834}
835
836/*
837 * Configure the sensor to match the parameters we have. Caller should
838 * hold s_mutex
839 */
840static int mcam_cam_set_flip(struct mcam_camera *cam)
841{
842 struct v4l2_control ctrl;
843
844 memset(&ctrl, 0, sizeof(ctrl));
845 ctrl.id = V4L2_CID_VFLIP;
846 ctrl.value = flip;
847 return sensor_call(cam, core, s_ctrl, &ctrl);
848}
849
850
851static int mcam_cam_configure(struct mcam_camera *cam)
852{
853 struct v4l2_mbus_framefmt mbus_fmt;
854 int ret;
855
856 v4l2_fill_mbus_format(&mbus_fmt, &cam->pix_format, cam->mbus_code);
857 ret = sensor_call(cam, core, init, 0);
858 if (ret == 0)
859 ret = sensor_call(cam, video, s_mbus_fmt, &mbus_fmt);
860 /*
861 * OV7670 does weird things if flip is set *before* format...
862 */
863 ret += mcam_cam_set_flip(cam);
864 return ret;
865}
866
867/*
868 * Get everything ready, and start grabbing frames.
869 */
870static int mcam_read_setup(struct mcam_camera *cam)
871{
872 int ret;
873 unsigned long flags;
874
875 /*
876 * Configuration. If we still don't have DMA buffers,
877 * make one last, desperate attempt.
878 */
879 if (cam->buffer_mode == B_vmalloc && cam->nbufs == 0 &&
880 mcam_alloc_dma_bufs(cam, 0))
881 return -ENOMEM;
882
883 if (mcam_needs_config(cam)) {
884 mcam_cam_configure(cam);
885 ret = mcam_ctlr_configure(cam);
886 if (ret)
887 return ret;
888 }
889
890 /*
891 * Turn it loose.
892 */
893 spin_lock_irqsave(&cam->dev_lock, flags);
894 clear_bit(CF_DMA_ACTIVE, &cam->flags);
895 mcam_reset_buffers(cam);
896 mcam_ctlr_irq_enable(cam);
897 cam->state = S_STREAMING;
898 if (!test_bit(CF_SG_RESTART, &cam->flags))
899 mcam_ctlr_start(cam);
900 spin_unlock_irqrestore(&cam->dev_lock, flags);
901 return 0;
902}
903
904/* ----------------------------------------------------------------------- */
905/*
906 * Videobuf2 interface code.
907 */
908
909static int mcam_vb_queue_setup(struct vb2_queue *vq,
910 const struct v4l2_format *fmt, unsigned int *nbufs,
911 unsigned int *num_planes, unsigned int sizes[],
912 void *alloc_ctxs[])
913{
914 struct mcam_camera *cam = vb2_get_drv_priv(vq);
915 int minbufs = (cam->buffer_mode == B_DMA_contig) ? 3 : 2;
916
917 sizes[0] = cam->pix_format.sizeimage;
918 *num_planes = 1; /* Someday we have to support planar formats... */
919 if (*nbufs < minbufs)
920 *nbufs = minbufs;
921 if (cam->buffer_mode == B_DMA_contig)
922 alloc_ctxs[0] = cam->vb_alloc_ctx;
923 return 0;
924}
925
926
927static void mcam_vb_buf_queue(struct vb2_buffer *vb)
928{
929 struct mcam_vb_buffer *mvb = vb_to_mvb(vb);
930 struct mcam_camera *cam = vb2_get_drv_priv(vb->vb2_queue);
931 unsigned long flags;
932 int start;
933
934 spin_lock_irqsave(&cam->dev_lock, flags);
935 start = (cam->state == S_BUFWAIT) && !list_empty(&cam->buffers);
936 list_add(&mvb->queue, &cam->buffers);
937 if (cam->state == S_STREAMING && test_bit(CF_SG_RESTART, &cam->flags))
938 mcam_sg_restart(cam);
939 spin_unlock_irqrestore(&cam->dev_lock, flags);
940 if (start)
941 mcam_read_setup(cam);
942}
943
944
945/*
946 * vb2 uses these to release the mutex when waiting in dqbuf. I'm
947 * not actually sure we need to do this (I'm not sure that vb2_dqbuf() needs
948 * to be called with the mutex held), but better safe than sorry.
949 */
950static void mcam_vb_wait_prepare(struct vb2_queue *vq)
951{
952 struct mcam_camera *cam = vb2_get_drv_priv(vq);
953
954 mutex_unlock(&cam->s_mutex);
955}
956
957static void mcam_vb_wait_finish(struct vb2_queue *vq)
958{
959 struct mcam_camera *cam = vb2_get_drv_priv(vq);
960
961 mutex_lock(&cam->s_mutex);
962}
963
964/*
965 * These need to be called with the mutex held from vb2
966 */
967static int mcam_vb_start_streaming(struct vb2_queue *vq, unsigned int count)
968{
969 struct mcam_camera *cam = vb2_get_drv_priv(vq);
970
971 if (cam->state != S_IDLE) {
972 INIT_LIST_HEAD(&cam->buffers);
973 return -EINVAL;
974 }
975 cam->sequence = 0;
976 /*
977 * Videobuf2 sneakily hoards all the buffers and won't
978 * give them to us until *after* streaming starts. But
979 * we can't actually start streaming until we have a
980 * destination. So go into a wait state and hope they
981 * give us buffers soon.
982 */
983 if (cam->buffer_mode != B_vmalloc && list_empty(&cam->buffers)) {
984 cam->state = S_BUFWAIT;
985 return 0;
986 }
987 return mcam_read_setup(cam);
988}
989
990static int mcam_vb_stop_streaming(struct vb2_queue *vq)
991{
992 struct mcam_camera *cam = vb2_get_drv_priv(vq);
993 unsigned long flags;
994
995 if (cam->state == S_BUFWAIT) {
996 /* They never gave us buffers */
997 cam->state = S_IDLE;
998 return 0;
999 }
1000 if (cam->state != S_STREAMING)
1001 return -EINVAL;
1002 mcam_ctlr_stop_dma(cam);
1003 /*
1004 * VB2 reclaims the buffers, so we need to forget
1005 * about them.
1006 */
1007 spin_lock_irqsave(&cam->dev_lock, flags);
1008 INIT_LIST_HEAD(&cam->buffers);
1009 spin_unlock_irqrestore(&cam->dev_lock, flags);
1010 return 0;
1011}
1012
1013
1014static const struct vb2_ops mcam_vb2_ops = {
1015 .queue_setup = mcam_vb_queue_setup,
1016 .buf_queue = mcam_vb_buf_queue,
1017 .start_streaming = mcam_vb_start_streaming,
1018 .stop_streaming = mcam_vb_stop_streaming,
1019 .wait_prepare = mcam_vb_wait_prepare,
1020 .wait_finish = mcam_vb_wait_finish,
1021};
1022
1023
1024#ifdef MCAM_MODE_DMA_SG
1025/*
1026 * Scatter/gather mode uses all of the above functions plus a
1027 * few extras to deal with DMA mapping.
1028 */
1029static int mcam_vb_sg_buf_init(struct vb2_buffer *vb)
1030{
1031 struct mcam_vb_buffer *mvb = vb_to_mvb(vb);
1032 struct mcam_camera *cam = vb2_get_drv_priv(vb->vb2_queue);
1033 int ndesc = cam->pix_format.sizeimage/PAGE_SIZE + 1;
1034
1035 mvb->dma_desc = dma_alloc_coherent(cam->dev,
1036 ndesc * sizeof(struct mcam_dma_desc),
1037 &mvb->dma_desc_pa, GFP_KERNEL);
1038 if (mvb->dma_desc == NULL) {
1039 cam_err(cam, "Unable to get DMA descriptor array\n");
1040 return -ENOMEM;
1041 }
1042 return 0;
1043}
1044
1045static int mcam_vb_sg_buf_prepare(struct vb2_buffer *vb)
1046{
1047 struct mcam_vb_buffer *mvb = vb_to_mvb(vb);
1048 struct mcam_camera *cam = vb2_get_drv_priv(vb->vb2_queue);
1049 struct vb2_dma_sg_desc *sgd = vb2_dma_sg_plane_desc(vb, 0);
1050 struct mcam_dma_desc *desc = mvb->dma_desc;
1051 struct scatterlist *sg;
1052 int i;
1053
1054 mvb->dma_desc_nent = dma_map_sg(cam->dev, sgd->sglist, sgd->num_pages,
1055 DMA_FROM_DEVICE);
1056 if (mvb->dma_desc_nent <= 0)
1057 return -EIO; /* Not sure what's right here */
1058 for_each_sg(sgd->sglist, sg, mvb->dma_desc_nent, i) {
1059 desc->dma_addr = sg_dma_address(sg);
1060 desc->segment_len = sg_dma_len(sg);
1061 desc++;
1062 }
1063 return 0;
1064}
1065
1066static int mcam_vb_sg_buf_finish(struct vb2_buffer *vb)
1067{
1068 struct mcam_camera *cam = vb2_get_drv_priv(vb->vb2_queue);
1069 struct vb2_dma_sg_desc *sgd = vb2_dma_sg_plane_desc(vb, 0);
1070
1071 dma_unmap_sg(cam->dev, sgd->sglist, sgd->num_pages, DMA_FROM_DEVICE);
1072 return 0;
1073}
1074
1075static void mcam_vb_sg_buf_cleanup(struct vb2_buffer *vb)
1076{
1077 struct mcam_camera *cam = vb2_get_drv_priv(vb->vb2_queue);
1078 struct mcam_vb_buffer *mvb = vb_to_mvb(vb);
1079 int ndesc = cam->pix_format.sizeimage/PAGE_SIZE + 1;
1080
1081 dma_free_coherent(cam->dev, ndesc * sizeof(struct mcam_dma_desc),
1082 mvb->dma_desc, mvb->dma_desc_pa);
1083}
1084
1085
1086static const struct vb2_ops mcam_vb2_sg_ops = {
1087 .queue_setup = mcam_vb_queue_setup,
1088 .buf_init = mcam_vb_sg_buf_init,
1089 .buf_prepare = mcam_vb_sg_buf_prepare,
1090 .buf_queue = mcam_vb_buf_queue,
1091 .buf_finish = mcam_vb_sg_buf_finish,
1092 .buf_cleanup = mcam_vb_sg_buf_cleanup,
1093 .start_streaming = mcam_vb_start_streaming,
1094 .stop_streaming = mcam_vb_stop_streaming,
1095 .wait_prepare = mcam_vb_wait_prepare,
1096 .wait_finish = mcam_vb_wait_finish,
1097};
1098
1099#endif /* MCAM_MODE_DMA_SG */
1100
1101static int mcam_setup_vb2(struct mcam_camera *cam)
1102{
1103 struct vb2_queue *vq = &cam->vb_queue;
1104
1105 memset(vq, 0, sizeof(*vq));
1106 vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1107 vq->drv_priv = cam;
1108 INIT_LIST_HEAD(&cam->buffers);
1109 switch (cam->buffer_mode) {
1110 case B_DMA_contig:
1111#ifdef MCAM_MODE_DMA_CONTIG
1112 vq->ops = &mcam_vb2_ops;
1113 vq->mem_ops = &vb2_dma_contig_memops;
1114 cam->vb_alloc_ctx = vb2_dma_contig_init_ctx(cam->dev);
1115 vq->io_modes = VB2_MMAP | VB2_USERPTR;
1116 cam->dma_setup = mcam_ctlr_dma_contig;
1117 cam->frame_complete = mcam_dma_contig_done;
1118#endif
1119 break;
1120 case B_DMA_sg:
1121#ifdef MCAM_MODE_DMA_SG
1122 vq->ops = &mcam_vb2_sg_ops;
1123 vq->mem_ops = &vb2_dma_sg_memops;
1124 vq->io_modes = VB2_MMAP | VB2_USERPTR;
1125 cam->dma_setup = mcam_ctlr_dma_sg;
1126 cam->frame_complete = mcam_dma_sg_done;
1127#endif
1128 break;
1129 case B_vmalloc:
1130#ifdef MCAM_MODE_VMALLOC
1131 tasklet_init(&cam->s_tasklet, mcam_frame_tasklet,
1132 (unsigned long) cam);
1133 vq->ops = &mcam_vb2_ops;
1134 vq->mem_ops = &vb2_vmalloc_memops;
1135 vq->buf_struct_size = sizeof(struct mcam_vb_buffer);
1136 vq->io_modes = VB2_MMAP;
1137 cam->dma_setup = mcam_ctlr_dma_vmalloc;
1138 cam->frame_complete = mcam_vmalloc_done;
1139#endif
1140 break;
1141 }
1142 return vb2_queue_init(vq);
1143}
1144
1145static void mcam_cleanup_vb2(struct mcam_camera *cam)
1146{
1147 vb2_queue_release(&cam->vb_queue);
1148#ifdef MCAM_MODE_DMA_CONTIG
1149 if (cam->buffer_mode == B_DMA_contig)
1150 vb2_dma_contig_cleanup_ctx(cam->vb_alloc_ctx);
1151#endif
1152}
1153
1154
1155/* ---------------------------------------------------------------------- */
1156/*
1157 * The long list of V4L2 ioctl() operations.
1158 */
1159
1160static int mcam_vidioc_streamon(struct file *filp, void *priv,
1161 enum v4l2_buf_type type)
1162{
1163 struct mcam_camera *cam = filp->private_data;
1164 int ret;
1165
1166 mutex_lock(&cam->s_mutex);
1167 ret = vb2_streamon(&cam->vb_queue, type);
1168 mutex_unlock(&cam->s_mutex);
1169 return ret;
1170}
1171
1172
1173static int mcam_vidioc_streamoff(struct file *filp, void *priv,
1174 enum v4l2_buf_type type)
1175{
1176 struct mcam_camera *cam = filp->private_data;
1177 int ret;
1178
1179 mutex_lock(&cam->s_mutex);
1180 ret = vb2_streamoff(&cam->vb_queue, type);
1181 mutex_unlock(&cam->s_mutex);
1182 return ret;
1183}
1184
1185
1186static int mcam_vidioc_reqbufs(struct file *filp, void *priv,
1187 struct v4l2_requestbuffers *req)
1188{
1189 struct mcam_camera *cam = filp->private_data;
1190 int ret;
1191
1192 mutex_lock(&cam->s_mutex);
1193 ret = vb2_reqbufs(&cam->vb_queue, req);
1194 mutex_unlock(&cam->s_mutex);
1195 return ret;
1196}
1197
1198
1199static int mcam_vidioc_querybuf(struct file *filp, void *priv,
1200 struct v4l2_buffer *buf)
1201{
1202 struct mcam_camera *cam = filp->private_data;
1203 int ret;
1204
1205 mutex_lock(&cam->s_mutex);
1206 ret = vb2_querybuf(&cam->vb_queue, buf);
1207 mutex_unlock(&cam->s_mutex);
1208 return ret;
1209}
1210
1211static int mcam_vidioc_qbuf(struct file *filp, void *priv,
1212 struct v4l2_buffer *buf)
1213{
1214 struct mcam_camera *cam = filp->private_data;
1215 int ret;
1216
1217 mutex_lock(&cam->s_mutex);
1218 ret = vb2_qbuf(&cam->vb_queue, buf);
1219 mutex_unlock(&cam->s_mutex);
1220 return ret;
1221}
1222
1223static int mcam_vidioc_dqbuf(struct file *filp, void *priv,
1224 struct v4l2_buffer *buf)
1225{
1226 struct mcam_camera *cam = filp->private_data;
1227 int ret;
1228
1229 mutex_lock(&cam->s_mutex);
1230 ret = vb2_dqbuf(&cam->vb_queue, buf, filp->f_flags & O_NONBLOCK);
1231 mutex_unlock(&cam->s_mutex);
1232 return ret;
1233}
1234
1235
1236
1237static int mcam_vidioc_queryctrl(struct file *filp, void *priv,
1238 struct v4l2_queryctrl *qc)
1239{
1240 struct mcam_camera *cam = priv;
1241 int ret;
1242
1243 mutex_lock(&cam->s_mutex);
1244 ret = sensor_call(cam, core, queryctrl, qc);
1245 mutex_unlock(&cam->s_mutex);
1246 return ret;
1247}
1248
1249
1250static int mcam_vidioc_g_ctrl(struct file *filp, void *priv,
1251 struct v4l2_control *ctrl)
1252{
1253 struct mcam_camera *cam = priv;
1254 int ret;
1255
1256 mutex_lock(&cam->s_mutex);
1257 ret = sensor_call(cam, core, g_ctrl, ctrl);
1258 mutex_unlock(&cam->s_mutex);
1259 return ret;
1260}
1261
1262
1263static int mcam_vidioc_s_ctrl(struct file *filp, void *priv,
1264 struct v4l2_control *ctrl)
1265{
1266 struct mcam_camera *cam = priv;
1267 int ret;
1268
1269 mutex_lock(&cam->s_mutex);
1270 ret = sensor_call(cam, core, s_ctrl, ctrl);
1271 mutex_unlock(&cam->s_mutex);
1272 return ret;
1273}
1274
1275
1276static int mcam_vidioc_querycap(struct file *file, void *priv,
1277 struct v4l2_capability *cap)
1278{
1279 strcpy(cap->driver, "marvell_ccic");
1280 strcpy(cap->card, "marvell_ccic");
1281 cap->version = 1;
1282 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
1283 V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
1284 return 0;
1285}
1286
1287
1288static int mcam_vidioc_enum_fmt_vid_cap(struct file *filp,
1289 void *priv, struct v4l2_fmtdesc *fmt)
1290{
1291 if (fmt->index >= N_MCAM_FMTS)
1292 return -EINVAL;
1293 strlcpy(fmt->description, mcam_formats[fmt->index].desc,
1294 sizeof(fmt->description));
1295 fmt->pixelformat = mcam_formats[fmt->index].pixelformat;
1296 return 0;
1297}
1298
1299static int mcam_vidioc_try_fmt_vid_cap(struct file *filp, void *priv,
1300 struct v4l2_format *fmt)
1301{
1302 struct mcam_camera *cam = priv;
1303 struct mcam_format_struct *f;
1304 struct v4l2_pix_format *pix = &fmt->fmt.pix;
1305 struct v4l2_mbus_framefmt mbus_fmt;
1306 int ret;
1307
1308 f = mcam_find_format(pix->pixelformat);
1309 pix->pixelformat = f->pixelformat;
1310 v4l2_fill_mbus_format(&mbus_fmt, pix, f->mbus_code);
1311 mutex_lock(&cam->s_mutex);
1312 ret = sensor_call(cam, video, try_mbus_fmt, &mbus_fmt);
1313 mutex_unlock(&cam->s_mutex);
1314 v4l2_fill_pix_format(pix, &mbus_fmt);
1315 pix->bytesperline = pix->width * f->bpp;
1316 pix->sizeimage = pix->height * pix->bytesperline;
1317 return ret;
1318}
1319
1320static int mcam_vidioc_s_fmt_vid_cap(struct file *filp, void *priv,
1321 struct v4l2_format *fmt)
1322{
1323 struct mcam_camera *cam = priv;
1324 struct mcam_format_struct *f;
1325 int ret;
1326
1327 /*
1328 * Can't do anything if the device is not idle
1329 * Also can't if there are streaming buffers in place.
1330 */
1331 if (cam->state != S_IDLE || cam->vb_queue.num_buffers > 0)
1332 return -EBUSY;
1333
1334 f = mcam_find_format(fmt->fmt.pix.pixelformat);
1335
1336 /*
1337 * See if the formatting works in principle.
1338 */
1339 ret = mcam_vidioc_try_fmt_vid_cap(filp, priv, fmt);
1340 if (ret)
1341 return ret;
1342 /*
1343 * Now we start to change things for real, so let's do it
1344 * under lock.
1345 */
1346 mutex_lock(&cam->s_mutex);
1347 cam->pix_format = fmt->fmt.pix;
1348 cam->mbus_code = f->mbus_code;
1349
1350 /*
1351 * Make sure we have appropriate DMA buffers.
1352 */
1353 if (cam->buffer_mode == B_vmalloc) {
1354 ret = mcam_check_dma_buffers(cam);
1355 if (ret)
1356 goto out;
1357 }
1358 mcam_set_config_needed(cam, 1);
1359out:
1360 mutex_unlock(&cam->s_mutex);
1361 return ret;
1362}
1363
1364/*
1365 * Return our stored notion of how the camera is/should be configured.
1366 * The V4l2 spec wants us to be smarter, and actually get this from
1367 * the camera (and not mess with it at open time). Someday.
1368 */
1369static int mcam_vidioc_g_fmt_vid_cap(struct file *filp, void *priv,
1370 struct v4l2_format *f)
1371{
1372 struct mcam_camera *cam = priv;
1373
1374 f->fmt.pix = cam->pix_format;
1375 return 0;
1376}
1377
1378/*
1379 * We only have one input - the sensor - so minimize the nonsense here.
1380 */
1381static int mcam_vidioc_enum_input(struct file *filp, void *priv,
1382 struct v4l2_input *input)
1383{
1384 if (input->index != 0)
1385 return -EINVAL;
1386
1387 input->type = V4L2_INPUT_TYPE_CAMERA;
1388 input->std = V4L2_STD_ALL; /* Not sure what should go here */
1389 strcpy(input->name, "Camera");
1390 return 0;
1391}
1392
1393static int mcam_vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
1394{
1395 *i = 0;
1396 return 0;
1397}
1398
1399static int mcam_vidioc_s_input(struct file *filp, void *priv, unsigned int i)
1400{
1401 if (i != 0)
1402 return -EINVAL;
1403 return 0;
1404}
1405
1406/* from vivi.c */
1407static int mcam_vidioc_s_std(struct file *filp, void *priv, v4l2_std_id *a)
1408{
1409 return 0;
1410}
1411
1412/*
1413 * G/S_PARM. Most of this is done by the sensor, but we are
1414 * the level which controls the number of read buffers.
1415 */
1416static int mcam_vidioc_g_parm(struct file *filp, void *priv,
1417 struct v4l2_streamparm *parms)
1418{
1419 struct mcam_camera *cam = priv;
1420 int ret;
1421
1422 mutex_lock(&cam->s_mutex);
1423 ret = sensor_call(cam, video, g_parm, parms);
1424 mutex_unlock(&cam->s_mutex);
1425 parms->parm.capture.readbuffers = n_dma_bufs;
1426 return ret;
1427}
1428
1429static int mcam_vidioc_s_parm(struct file *filp, void *priv,
1430 struct v4l2_streamparm *parms)
1431{
1432 struct mcam_camera *cam = priv;
1433 int ret;
1434
1435 mutex_lock(&cam->s_mutex);
1436 ret = sensor_call(cam, video, s_parm, parms);
1437 mutex_unlock(&cam->s_mutex);
1438 parms->parm.capture.readbuffers = n_dma_bufs;
1439 return ret;
1440}
1441
1442static int mcam_vidioc_g_chip_ident(struct file *file, void *priv,
1443 struct v4l2_dbg_chip_ident *chip)
1444{
1445 struct mcam_camera *cam = priv;
1446
1447 chip->ident = V4L2_IDENT_NONE;
1448 chip->revision = 0;
1449 if (v4l2_chip_match_host(&chip->match)) {
1450 chip->ident = cam->chip_id;
1451 return 0;
1452 }
1453 return sensor_call(cam, core, g_chip_ident, chip);
1454}
1455
1456static int mcam_vidioc_enum_framesizes(struct file *filp, void *priv,
1457 struct v4l2_frmsizeenum *sizes)
1458{
1459 struct mcam_camera *cam = priv;
1460 int ret;
1461
1462 mutex_lock(&cam->s_mutex);
1463 ret = sensor_call(cam, video, enum_framesizes, sizes);
1464 mutex_unlock(&cam->s_mutex);
1465 return ret;
1466}
1467
1468static int mcam_vidioc_enum_frameintervals(struct file *filp, void *priv,
1469 struct v4l2_frmivalenum *interval)
1470{
1471 struct mcam_camera *cam = priv;
1472 int ret;
1473
1474 mutex_lock(&cam->s_mutex);
1475 ret = sensor_call(cam, video, enum_frameintervals, interval);
1476 mutex_unlock(&cam->s_mutex);
1477 return ret;
1478}
1479
1480#ifdef CONFIG_VIDEO_ADV_DEBUG
1481static int mcam_vidioc_g_register(struct file *file, void *priv,
1482 struct v4l2_dbg_register *reg)
1483{
1484 struct mcam_camera *cam = priv;
1485
1486 if (v4l2_chip_match_host(&reg->match)) {
1487 reg->val = mcam_reg_read(cam, reg->reg);
1488 reg->size = 4;
1489 return 0;
1490 }
1491 return sensor_call(cam, core, g_register, reg);
1492}
1493
1494static int mcam_vidioc_s_register(struct file *file, void *priv,
1495 struct v4l2_dbg_register *reg)
1496{
1497 struct mcam_camera *cam = priv;
1498
1499 if (v4l2_chip_match_host(&reg->match)) {
1500 mcam_reg_write(cam, reg->reg, reg->val);
1501 return 0;
1502 }
1503 return sensor_call(cam, core, s_register, reg);
1504}
1505#endif
1506
1507static const struct v4l2_ioctl_ops mcam_v4l_ioctl_ops = {
1508 .vidioc_querycap = mcam_vidioc_querycap,
1509 .vidioc_enum_fmt_vid_cap = mcam_vidioc_enum_fmt_vid_cap,
1510 .vidioc_try_fmt_vid_cap = mcam_vidioc_try_fmt_vid_cap,
1511 .vidioc_s_fmt_vid_cap = mcam_vidioc_s_fmt_vid_cap,
1512 .vidioc_g_fmt_vid_cap = mcam_vidioc_g_fmt_vid_cap,
1513 .vidioc_enum_input = mcam_vidioc_enum_input,
1514 .vidioc_g_input = mcam_vidioc_g_input,
1515 .vidioc_s_input = mcam_vidioc_s_input,
1516 .vidioc_s_std = mcam_vidioc_s_std,
1517 .vidioc_reqbufs = mcam_vidioc_reqbufs,
1518 .vidioc_querybuf = mcam_vidioc_querybuf,
1519 .vidioc_qbuf = mcam_vidioc_qbuf,
1520 .vidioc_dqbuf = mcam_vidioc_dqbuf,
1521 .vidioc_streamon = mcam_vidioc_streamon,
1522 .vidioc_streamoff = mcam_vidioc_streamoff,
1523 .vidioc_queryctrl = mcam_vidioc_queryctrl,
1524 .vidioc_g_ctrl = mcam_vidioc_g_ctrl,
1525 .vidioc_s_ctrl = mcam_vidioc_s_ctrl,
1526 .vidioc_g_parm = mcam_vidioc_g_parm,
1527 .vidioc_s_parm = mcam_vidioc_s_parm,
1528 .vidioc_enum_framesizes = mcam_vidioc_enum_framesizes,
1529 .vidioc_enum_frameintervals = mcam_vidioc_enum_frameintervals,
1530 .vidioc_g_chip_ident = mcam_vidioc_g_chip_ident,
1531#ifdef CONFIG_VIDEO_ADV_DEBUG
1532 .vidioc_g_register = mcam_vidioc_g_register,
1533 .vidioc_s_register = mcam_vidioc_s_register,
1534#endif
1535};
1536
1537/* ---------------------------------------------------------------------- */
1538/*
1539 * Our various file operations.
1540 */
1541static int mcam_v4l_open(struct file *filp)
1542{
1543 struct mcam_camera *cam = video_drvdata(filp);
1544 int ret = 0;
1545
1546 filp->private_data = cam;
1547
1548 frames = singles = delivered = 0;
1549 mutex_lock(&cam->s_mutex);
1550 if (cam->users == 0) {
1551 ret = mcam_setup_vb2(cam);
1552 if (ret)
1553 goto out;
1554 mcam_ctlr_power_up(cam);
1555 __mcam_cam_reset(cam);
1556 mcam_set_config_needed(cam, 1);
1557 }
1558 (cam->users)++;
1559out:
1560 mutex_unlock(&cam->s_mutex);
1561 return ret;
1562}
1563
1564
1565static int mcam_v4l_release(struct file *filp)
1566{
1567 struct mcam_camera *cam = filp->private_data;
1568
1569 cam_dbg(cam, "Release, %d frames, %d singles, %d delivered\n", frames,
1570 singles, delivered);
1571 mutex_lock(&cam->s_mutex);
1572 (cam->users)--;
1573 if (cam->users == 0) {
1574 mcam_ctlr_stop_dma(cam);
1575 mcam_cleanup_vb2(cam);
1576 mcam_ctlr_power_down(cam);
1577 if (cam->buffer_mode == B_vmalloc && alloc_bufs_at_read)
1578 mcam_free_dma_bufs(cam);
1579 }
1580 mutex_unlock(&cam->s_mutex);
1581 return 0;
1582}
1583
1584static ssize_t mcam_v4l_read(struct file *filp,
1585 char __user *buffer, size_t len, loff_t *pos)
1586{
1587 struct mcam_camera *cam = filp->private_data;
1588 int ret;
1589
1590 mutex_lock(&cam->s_mutex);
1591 ret = vb2_read(&cam->vb_queue, buffer, len, pos,
1592 filp->f_flags & O_NONBLOCK);
1593 mutex_unlock(&cam->s_mutex);
1594 return ret;
1595}
1596
1597
1598
1599static unsigned int mcam_v4l_poll(struct file *filp,
1600 struct poll_table_struct *pt)
1601{
1602 struct mcam_camera *cam = filp->private_data;
1603 int ret;
1604
1605 mutex_lock(&cam->s_mutex);
1606 ret = vb2_poll(&cam->vb_queue, filp, pt);
1607 mutex_unlock(&cam->s_mutex);
1608 return ret;
1609}
1610
1611
1612static int mcam_v4l_mmap(struct file *filp, struct vm_area_struct *vma)
1613{
1614 struct mcam_camera *cam = filp->private_data;
1615 int ret;
1616
1617 mutex_lock(&cam->s_mutex);
1618 ret = vb2_mmap(&cam->vb_queue, vma);
1619 mutex_unlock(&cam->s_mutex);
1620 return ret;
1621}
1622
1623
1624
1625static const struct v4l2_file_operations mcam_v4l_fops = {
1626 .owner = THIS_MODULE,
1627 .open = mcam_v4l_open,
1628 .release = mcam_v4l_release,
1629 .read = mcam_v4l_read,
1630 .poll = mcam_v4l_poll,
1631 .mmap = mcam_v4l_mmap,
1632 .unlocked_ioctl = video_ioctl2,
1633};
1634
1635
1636/*
1637 * This template device holds all of those v4l2 methods; we
1638 * clone it for specific real devices.
1639 */
1640static struct video_device mcam_v4l_template = {
1641 .name = "mcam",
1642 .tvnorms = V4L2_STD_NTSC_M,
1643 .current_norm = V4L2_STD_NTSC_M, /* make mplayer happy */
1644
1645 .fops = &mcam_v4l_fops,
1646 .ioctl_ops = &mcam_v4l_ioctl_ops,
1647 .release = video_device_release_empty,
1648};
1649
1650/* ---------------------------------------------------------------------- */
1651/*
1652 * Interrupt handler stuff
1653 */
1654static void mcam_frame_complete(struct mcam_camera *cam, int frame)
1655{
1656 /*
1657 * Basic frame housekeeping.
1658 */
1659 set_bit(frame, &cam->flags);
1660 clear_bit(CF_DMA_ACTIVE, &cam->flags);
1661 cam->next_buf = frame;
1662 cam->buf_seq[frame] = ++(cam->sequence);
1663 frames++;
1664 /*
1665 * "This should never happen"
1666 */
1667 if (cam->state != S_STREAMING)
1668 return;
1669 /*
1670 * Process the frame and set up the next one.
1671 */
1672 cam->frame_complete(cam, frame);
1673}
1674
1675
1676/*
1677 * The interrupt handler; this needs to be called from the
1678 * platform irq handler with the lock held.
1679 */
1680int mccic_irq(struct mcam_camera *cam, unsigned int irqs)
1681{
1682 unsigned int frame, handled = 0;
1683
1684 mcam_reg_write(cam, REG_IRQSTAT, FRAMEIRQS); /* Clear'em all */
1685 /*
1686 * Handle any frame completions. There really should
1687 * not be more than one of these, or we have fallen
1688 * far behind.
1689 *
1690 * When running in S/G mode, the frame number lacks any
1691 * real meaning - there's only one descriptor array - but
1692 * the controller still picks a different one to signal
1693 * each time.
1694 */
1695 for (frame = 0; frame < cam->nbufs; frame++)
1696 if (irqs & (IRQ_EOF0 << frame)) {
1697 mcam_frame_complete(cam, frame);
1698 handled = 1;
1699 if (cam->buffer_mode == B_DMA_sg)
1700 break;
1701 }
1702 /*
1703 * If a frame starts, note that we have DMA active. This
1704 * code assumes that we won't get multiple frame interrupts
1705 * at once; may want to rethink that.
1706 */
1707 if (irqs & (IRQ_SOF0 | IRQ_SOF1 | IRQ_SOF2)) {
1708 set_bit(CF_DMA_ACTIVE, &cam->flags);
1709 handled = 1;
1710 if (cam->buffer_mode == B_DMA_sg)
1711 mcam_ctlr_stop(cam);
1712 }
1713 return handled;
1714}
1715
1716/* ---------------------------------------------------------------------- */
1717/*
1718 * Registration and such.
1719 */
1720static struct ov7670_config sensor_cfg = {
1721 /*
1722 * Exclude QCIF mode, because it only captures a tiny portion
1723 * of the sensor FOV
1724 */
1725 .min_width = 320,
1726 .min_height = 240,
1727};
1728
1729
1730int mccic_register(struct mcam_camera *cam)
1731{
1732 struct i2c_board_info ov7670_info = {
1733 .type = "ov7670",
1734 .addr = 0x42 >> 1,
1735 .platform_data = &sensor_cfg,
1736 };
1737 int ret;
1738
1739 /*
1740 * Validate the requested buffer mode.
1741 */
1742 if (buffer_mode >= 0)
1743 cam->buffer_mode = buffer_mode;
1744 if (cam->buffer_mode == B_DMA_sg &&
1745 cam->chip_id == V4L2_IDENT_CAFE) {
1746 printk(KERN_ERR "marvell-cam: Cafe can't do S/G I/O, "
1747 "attempting vmalloc mode instead\n");
1748 cam->buffer_mode = B_vmalloc;
1749 }
1750 if (!mcam_buffer_mode_supported(cam->buffer_mode)) {
1751 printk(KERN_ERR "marvell-cam: buffer mode %d unsupported\n",
1752 cam->buffer_mode);
1753 return -EINVAL;
1754 }
1755 /*
1756 * Register with V4L
1757 */
1758 ret = v4l2_device_register(cam->dev, &cam->v4l2_dev);
1759 if (ret)
1760 return ret;
1761
1762 mutex_init(&cam->s_mutex);
1763 cam->state = S_NOTREADY;
1764 mcam_set_config_needed(cam, 1);
1765 cam->pix_format = mcam_def_pix_format;
1766 cam->mbus_code = mcam_def_mbus_code;
1767 INIT_LIST_HEAD(&cam->buffers);
1768 mcam_ctlr_init(cam);
1769
1770 /*
1771 * Try to find the sensor.
1772 */
1773 sensor_cfg.clock_speed = cam->clock_speed;
1774 sensor_cfg.use_smbus = cam->use_smbus;
1775 cam->sensor_addr = ov7670_info.addr;
1776 cam->sensor = v4l2_i2c_new_subdev_board(&cam->v4l2_dev,
1777 cam->i2c_adapter, &ov7670_info, NULL);
1778 if (cam->sensor == NULL) {
1779 ret = -ENODEV;
1780 goto out_unregister;
1781 }
1782
1783 ret = mcam_cam_init(cam);
1784 if (ret)
1785 goto out_unregister;
1786 /*
1787 * Get the v4l2 setup done.
1788 */
1789 mutex_lock(&cam->s_mutex);
1790 cam->vdev = mcam_v4l_template;
1791 cam->vdev.debug = 0;
1792 cam->vdev.v4l2_dev = &cam->v4l2_dev;
1793 ret = video_register_device(&cam->vdev, VFL_TYPE_GRABBER, -1);
1794 if (ret)
1795 goto out;
1796 video_set_drvdata(&cam->vdev, cam);
1797
1798 /*
1799 * If so requested, try to get our DMA buffers now.
1800 */
1801 if (cam->buffer_mode == B_vmalloc && !alloc_bufs_at_read) {
1802 if (mcam_alloc_dma_bufs(cam, 1))
1803 cam_warn(cam, "Unable to alloc DMA buffers at load"
1804 " will try again later.");
1805 }
1806
1807out:
1808 mutex_unlock(&cam->s_mutex);
1809 return ret;
1810out_unregister:
1811 v4l2_device_unregister(&cam->v4l2_dev);
1812 return ret;
1813}
1814
1815
1816void mccic_shutdown(struct mcam_camera *cam)
1817{
1818 /*
1819 * If we have no users (and we really, really should have no
1820 * users) the device will already be powered down. Trying to
1821 * take it down again will wedge the machine, which is frowned
1822 * upon.
1823 */
1824 if (cam->users > 0) {
1825 cam_warn(cam, "Removing a device with users!\n");
1826 mcam_ctlr_power_down(cam);
1827 }
1828 vb2_queue_release(&cam->vb_queue);
1829 if (cam->buffer_mode == B_vmalloc)
1830 mcam_free_dma_bufs(cam);
1831 video_unregister_device(&cam->vdev);
1832 v4l2_device_unregister(&cam->v4l2_dev);
1833}
1834
1835/*
1836 * Power management
1837 */
1838#ifdef CONFIG_PM
1839
1840void mccic_suspend(struct mcam_camera *cam)
1841{
1842 mutex_lock(&cam->s_mutex);
1843 if (cam->users > 0) {
1844 enum mcam_state cstate = cam->state;
1845
1846 mcam_ctlr_stop_dma(cam);
1847 mcam_ctlr_power_down(cam);
1848 cam->state = cstate;
1849 }
1850 mutex_unlock(&cam->s_mutex);
1851}
1852
1853int mccic_resume(struct mcam_camera *cam)
1854{
1855 int ret = 0;
1856
1857 mutex_lock(&cam->s_mutex);
1858 if (cam->users > 0) {
1859 mcam_ctlr_power_up(cam);
1860 __mcam_cam_reset(cam);
1861 } else {
1862 mcam_ctlr_power_down(cam);
1863 }
1864 mutex_unlock(&cam->s_mutex);
1865
1866 set_bit(CF_CONFIG_NEEDED, &cam->flags);
1867 if (cam->state == S_STREAMING) {
1868 /*
1869 * If there was a buffer in the DMA engine at suspend
1870 * time, put it back on the queue or we'll forget about it.
1871 */
1872 if (cam->buffer_mode == B_DMA_sg && cam->vb_bufs[0])
1873 list_add(&cam->vb_bufs[0]->queue, &cam->buffers);
1874 ret = mcam_read_setup(cam);
1875 }
1876 return ret;
1877}
1878#endif /* CONFIG_PM */
diff --git a/drivers/media/video/marvell-ccic/mcam-core.h b/drivers/media/video/marvell-ccic/mcam-core.h
deleted file mode 100644
index bd6acba9fb37..000000000000
--- a/drivers/media/video/marvell-ccic/mcam-core.h
+++ /dev/null
@@ -1,322 +0,0 @@
1/*
2 * Marvell camera core structures.
3 *
4 * Copyright 2011 Jonathan Corbet corbet@lwn.net
5 */
6#ifndef _MCAM_CORE_H
7#define _MCAM_CORE_H
8
9#include <linux/list.h>
10#include <media/v4l2-common.h>
11#include <media/v4l2-dev.h>
12#include <media/videobuf2-core.h>
13
14/*
15 * Create our own symbols for the supported buffer modes, but, for now,
16 * base them entirely on which videobuf2 options have been selected.
17 */
18#if defined(CONFIG_VIDEOBUF2_VMALLOC) || defined(CONFIG_VIDEOBUF2_VMALLOC_MODULE)
19#define MCAM_MODE_VMALLOC 1
20#endif
21
22#if defined(CONFIG_VIDEOBUF2_DMA_CONTIG) || defined(CONFIG_VIDEOBUF2_DMA_CONTIG_MODULE)
23#define MCAM_MODE_DMA_CONTIG 1
24#endif
25
26#if defined(CONFIG_VIDEOBUF2_DMA_SG) || defined(CONFIG_VIDEOBUF2_DMA_SG_MODULE)
27#define MCAM_MODE_DMA_SG 1
28#endif
29
30#if !defined(MCAM_MODE_VMALLOC) && !defined(MCAM_MODE_DMA_CONTIG) && \
31 !defined(MCAM_MODE_DMA_SG)
32#error One of the videobuf buffer modes must be selected in the config
33#endif
34
35
36enum mcam_state {
37 S_NOTREADY, /* Not yet initialized */
38 S_IDLE, /* Just hanging around */
39 S_FLAKED, /* Some sort of problem */
40 S_STREAMING, /* Streaming data */
41 S_BUFWAIT /* streaming requested but no buffers yet */
42};
43#define MAX_DMA_BUFS 3
44
45/*
46 * Different platforms work best with different buffer modes, so we
47 * let the platform pick.
48 */
49enum mcam_buffer_mode {
50 B_vmalloc = 0,
51 B_DMA_contig = 1,
52 B_DMA_sg = 2
53};
54
55/*
56 * Is a given buffer mode supported by the current kernel configuration?
57 */
58static inline int mcam_buffer_mode_supported(enum mcam_buffer_mode mode)
59{
60 switch (mode) {
61#ifdef MCAM_MODE_VMALLOC
62 case B_vmalloc:
63#endif
64#ifdef MCAM_MODE_DMA_CONTIG
65 case B_DMA_contig:
66#endif
67#ifdef MCAM_MODE_DMA_SG
68 case B_DMA_sg:
69#endif
70 return 1;
71 default:
72 return 0;
73 }
74}
75
76
77/*
78 * A description of one of our devices.
79 * Locking: controlled by s_mutex. Certain fields, however, require
80 * the dev_lock spinlock; they are marked as such by comments.
81 * dev_lock is also required for access to device registers.
82 */
83struct mcam_camera {
84 /*
85 * These fields should be set by the platform code prior to
86 * calling mcam_register().
87 */
88 struct i2c_adapter *i2c_adapter;
89 unsigned char __iomem *regs;
90 spinlock_t dev_lock;
91 struct device *dev; /* For messages, dma alloc */
92 unsigned int chip_id;
93 short int clock_speed; /* Sensor clock speed, default 30 */
94 short int use_smbus; /* SMBUS or straight I2c? */
95 enum mcam_buffer_mode buffer_mode;
96 /*
97 * Callbacks from the core to the platform code.
98 */
99 void (*plat_power_up) (struct mcam_camera *cam);
100 void (*plat_power_down) (struct mcam_camera *cam);
101
102 /*
103 * Everything below here is private to the mcam core and
104 * should not be touched by the platform code.
105 */
106 struct v4l2_device v4l2_dev;
107 enum mcam_state state;
108 unsigned long flags; /* Buffer status, mainly (dev_lock) */
109 int users; /* How many open FDs */
110
111 /*
112 * Subsystem structures.
113 */
114 struct video_device vdev;
115 struct v4l2_subdev *sensor;
116 unsigned short sensor_addr;
117
118 /* Videobuf2 stuff */
119 struct vb2_queue vb_queue;
120 struct list_head buffers; /* Available frames */
121
122 unsigned int nbufs; /* How many are alloc'd */
123 int next_buf; /* Next to consume (dev_lock) */
124
125 /* DMA buffers - vmalloc mode */
126#ifdef MCAM_MODE_VMALLOC
127 unsigned int dma_buf_size; /* allocated size */
128 void *dma_bufs[MAX_DMA_BUFS]; /* Internal buffer addresses */
129 dma_addr_t dma_handles[MAX_DMA_BUFS]; /* Buffer bus addresses */
130 struct tasklet_struct s_tasklet;
131#endif
132 unsigned int sequence; /* Frame sequence number */
133 unsigned int buf_seq[MAX_DMA_BUFS]; /* Sequence for individual bufs */
134
135 /* DMA buffers - DMA modes */
136 struct mcam_vb_buffer *vb_bufs[MAX_DMA_BUFS];
137 struct vb2_alloc_ctx *vb_alloc_ctx;
138
139 /* Mode-specific ops, set at open time */
140 void (*dma_setup)(struct mcam_camera *cam);
141 void (*frame_complete)(struct mcam_camera *cam, int frame);
142
143 /* Current operating parameters */
144 u32 sensor_type; /* Currently ov7670 only */
145 struct v4l2_pix_format pix_format;
146 enum v4l2_mbus_pixelcode mbus_code;
147
148 /* Locks */
149 struct mutex s_mutex; /* Access to this structure */
150};
151
152
153/*
154 * Register I/O functions. These are here because the platform code
155 * may legitimately need to mess with the register space.
156 */
157/*
158 * Device register I/O
159 */
160static inline void mcam_reg_write(struct mcam_camera *cam, unsigned int reg,
161 unsigned int val)
162{
163 iowrite32(val, cam->regs + reg);
164}
165
166static inline unsigned int mcam_reg_read(struct mcam_camera *cam,
167 unsigned int reg)
168{
169 return ioread32(cam->regs + reg);
170}
171
172
173static inline void mcam_reg_write_mask(struct mcam_camera *cam, unsigned int reg,
174 unsigned int val, unsigned int mask)
175{
176 unsigned int v = mcam_reg_read(cam, reg);
177
178 v = (v & ~mask) | (val & mask);
179 mcam_reg_write(cam, reg, v);
180}
181
182static inline void mcam_reg_clear_bit(struct mcam_camera *cam,
183 unsigned int reg, unsigned int val)
184{
185 mcam_reg_write_mask(cam, reg, 0, val);
186}
187
188static inline void mcam_reg_set_bit(struct mcam_camera *cam,
189 unsigned int reg, unsigned int val)
190{
191 mcam_reg_write_mask(cam, reg, val, val);
192}
193
194/*
195 * Functions for use by platform code.
196 */
197int mccic_register(struct mcam_camera *cam);
198int mccic_irq(struct mcam_camera *cam, unsigned int irqs);
199void mccic_shutdown(struct mcam_camera *cam);
200#ifdef CONFIG_PM
201void mccic_suspend(struct mcam_camera *cam);
202int mccic_resume(struct mcam_camera *cam);
203#endif
204
205/*
206 * Register definitions for the m88alp01 camera interface. Offsets in bytes
207 * as given in the spec.
208 */
209#define REG_Y0BAR 0x00
210#define REG_Y1BAR 0x04
211#define REG_Y2BAR 0x08
212/* ... */
213
214#define REG_IMGPITCH 0x24 /* Image pitch register */
215#define IMGP_YP_SHFT 2 /* Y pitch params */
216#define IMGP_YP_MASK 0x00003ffc /* Y pitch field */
217#define IMGP_UVP_SHFT 18 /* UV pitch (planar) */
218#define IMGP_UVP_MASK 0x3ffc0000
219#define REG_IRQSTATRAW 0x28 /* RAW IRQ Status */
220#define IRQ_EOF0 0x00000001 /* End of frame 0 */
221#define IRQ_EOF1 0x00000002 /* End of frame 1 */
222#define IRQ_EOF2 0x00000004 /* End of frame 2 */
223#define IRQ_SOF0 0x00000008 /* Start of frame 0 */
224#define IRQ_SOF1 0x00000010 /* Start of frame 1 */
225#define IRQ_SOF2 0x00000020 /* Start of frame 2 */
226#define IRQ_OVERFLOW 0x00000040 /* FIFO overflow */
227#define IRQ_TWSIW 0x00010000 /* TWSI (smbus) write */
228#define IRQ_TWSIR 0x00020000 /* TWSI read */
229#define IRQ_TWSIE 0x00040000 /* TWSI error */
230#define TWSIIRQS (IRQ_TWSIW|IRQ_TWSIR|IRQ_TWSIE)
231#define FRAMEIRQS (IRQ_EOF0|IRQ_EOF1|IRQ_EOF2|IRQ_SOF0|IRQ_SOF1|IRQ_SOF2)
232#define ALLIRQS (TWSIIRQS|FRAMEIRQS|IRQ_OVERFLOW)
233#define REG_IRQMASK 0x2c /* IRQ mask - same bits as IRQSTAT */
234#define REG_IRQSTAT 0x30 /* IRQ status / clear */
235
236#define REG_IMGSIZE 0x34 /* Image size */
237#define IMGSZ_V_MASK 0x1fff0000
238#define IMGSZ_V_SHIFT 16
239#define IMGSZ_H_MASK 0x00003fff
240#define REG_IMGOFFSET 0x38 /* IMage offset */
241
242#define REG_CTRL0 0x3c /* Control 0 */
243#define C0_ENABLE 0x00000001 /* Makes the whole thing go */
244
245/* Mask for all the format bits */
246#define C0_DF_MASK 0x00fffffc /* Bits 2-23 */
247
248/* RGB ordering */
249#define C0_RGB4_RGBX 0x00000000
250#define C0_RGB4_XRGB 0x00000004
251#define C0_RGB4_BGRX 0x00000008
252#define C0_RGB4_XBGR 0x0000000c
253#define C0_RGB5_RGGB 0x00000000
254#define C0_RGB5_GRBG 0x00000004
255#define C0_RGB5_GBRG 0x00000008
256#define C0_RGB5_BGGR 0x0000000c
257
258/* Spec has two fields for DIN and DOUT, but they must match, so
259 combine them here. */
260#define C0_DF_YUV 0x00000000 /* Data is YUV */
261#define C0_DF_RGB 0x000000a0 /* ... RGB */
262#define C0_DF_BAYER 0x00000140 /* ... Bayer */
263/* 8-8-8 must be missing from the below - ask */
264#define C0_RGBF_565 0x00000000
265#define C0_RGBF_444 0x00000800
266#define C0_RGB_BGR 0x00001000 /* Blue comes first */
267#define C0_YUV_PLANAR 0x00000000 /* YUV 422 planar format */
268#define C0_YUV_PACKED 0x00008000 /* YUV 422 packed */
269#define C0_YUV_420PL 0x0000a000 /* YUV 420 planar */
270/* Think that 420 packed must be 111 - ask */
271#define C0_YUVE_YUYV 0x00000000 /* Y1CbY0Cr */
272#define C0_YUVE_YVYU 0x00010000 /* Y1CrY0Cb */
273#define C0_YUVE_VYUY 0x00020000 /* CrY1CbY0 */
274#define C0_YUVE_UYVY 0x00030000 /* CbY1CrY0 */
275#define C0_YUVE_XYUV 0x00000000 /* 420: .YUV */
276#define C0_YUVE_XYVU 0x00010000 /* 420: .YVU */
277#define C0_YUVE_XUVY 0x00020000 /* 420: .UVY */
278#define C0_YUVE_XVUY 0x00030000 /* 420: .VUY */
279/* Bayer bits 18,19 if needed */
280#define C0_HPOL_LOW 0x01000000 /* HSYNC polarity active low */
281#define C0_VPOL_LOW 0x02000000 /* VSYNC polarity active low */
282#define C0_VCLK_LOW 0x04000000 /* VCLK on falling edge */
283#define C0_DOWNSCALE 0x08000000 /* Enable downscaler */
284#define C0_SIFM_MASK 0xc0000000 /* SIF mode bits */
285#define C0_SIF_HVSYNC 0x00000000 /* Use H/VSYNC */
286#define CO_SOF_NOSYNC 0x40000000 /* Use inband active signaling */
287
288/* Bits below C1_444ALPHA are not present in Cafe */
289#define REG_CTRL1 0x40 /* Control 1 */
290#define C1_CLKGATE 0x00000001 /* Sensor clock gate */
291#define C1_DESC_ENA 0x00000100 /* DMA descriptor enable */
292#define C1_DESC_3WORD 0x00000200 /* Three-word descriptors used */
293#define C1_444ALPHA 0x00f00000 /* Alpha field in RGB444 */
294#define C1_ALPHA_SHFT 20
295#define C1_DMAB32 0x00000000 /* 32-byte DMA burst */
296#define C1_DMAB16 0x02000000 /* 16-byte DMA burst */
297#define C1_DMAB64 0x04000000 /* 64-byte DMA burst */
298#define C1_DMAB_MASK 0x06000000
299#define C1_TWOBUFS 0x08000000 /* Use only two DMA buffers */
300#define C1_PWRDWN 0x10000000 /* Power down */
301
302#define REG_CLKCTRL 0x88 /* Clock control */
303#define CLK_DIV_MASK 0x0000ffff /* Upper bits RW "reserved" */
304
305/* This appears to be a Cafe-only register */
306#define REG_UBAR 0xc4 /* Upper base address register */
307
308/* Armada 610 DMA descriptor registers */
309#define REG_DMA_DESC_Y 0x200
310#define REG_DMA_DESC_U 0x204
311#define REG_DMA_DESC_V 0x208
312#define REG_DESC_LEN_Y 0x20c /* Lengths are in bytes */
313#define REG_DESC_LEN_U 0x210
314#define REG_DESC_LEN_V 0x214
315
316/*
317 * Useful stuff that probably belongs somewhere global.
318 */
319#define VGA_WIDTH 640
320#define VGA_HEIGHT 480
321
322#endif /* _MCAM_CORE_H */
diff --git a/drivers/media/video/marvell-ccic/mmp-driver.c b/drivers/media/video/marvell-ccic/mmp-driver.c
deleted file mode 100644
index c4c17fe76c0d..000000000000
--- a/drivers/media/video/marvell-ccic/mmp-driver.c
+++ /dev/null
@@ -1,380 +0,0 @@
1/*
2 * Support for the camera device found on Marvell MMP processors; known
3 * to work with the Armada 610 as used in the OLPC 1.75 system.
4 *
5 * Copyright 2011 Jonathan Corbet <corbet@lwn.net>
6 *
7 * This file may be distributed under the terms of the GNU General
8 * Public License, version 2.
9 */
10
11#include <linux/init.h>
12#include <linux/kernel.h>
13#include <linux/module.h>
14#include <linux/i2c.h>
15#include <linux/i2c-gpio.h>
16#include <linux/interrupt.h>
17#include <linux/spinlock.h>
18#include <linux/slab.h>
19#include <linux/videodev2.h>
20#include <media/v4l2-device.h>
21#include <media/v4l2-chip-ident.h>
22#include <media/mmp-camera.h>
23#include <linux/device.h>
24#include <linux/platform_device.h>
25#include <linux/gpio.h>
26#include <linux/io.h>
27#include <linux/delay.h>
28#include <linux/list.h>
29#include <linux/pm.h>
30
31#include "mcam-core.h"
32
33MODULE_ALIAS("platform:mmp-camera");
34MODULE_AUTHOR("Jonathan Corbet <corbet@lwn.net>");
35MODULE_LICENSE("GPL");
36
37struct mmp_camera {
38 void *power_regs;
39 struct platform_device *pdev;
40 struct mcam_camera mcam;
41 struct list_head devlist;
42 int irq;
43};
44
45static inline struct mmp_camera *mcam_to_cam(struct mcam_camera *mcam)
46{
47 return container_of(mcam, struct mmp_camera, mcam);
48}
49
50/*
51 * A silly little infrastructure so we can keep track of our devices.
52 * Chances are that we will never have more than one of them, but
53 * the Armada 610 *does* have two controllers...
54 */
55
56static LIST_HEAD(mmpcam_devices);
57static struct mutex mmpcam_devices_lock;
58
59static void mmpcam_add_device(struct mmp_camera *cam)
60{
61 mutex_lock(&mmpcam_devices_lock);
62 list_add(&cam->devlist, &mmpcam_devices);
63 mutex_unlock(&mmpcam_devices_lock);
64}
65
66static void mmpcam_remove_device(struct mmp_camera *cam)
67{
68 mutex_lock(&mmpcam_devices_lock);
69 list_del(&cam->devlist);
70 mutex_unlock(&mmpcam_devices_lock);
71}
72
73/*
74 * Platform dev remove passes us a platform_device, and there's
75 * no handy unused drvdata to stash a backpointer in. So just
76 * dig it out of our list.
77 */
78static struct mmp_camera *mmpcam_find_device(struct platform_device *pdev)
79{
80 struct mmp_camera *cam;
81
82 mutex_lock(&mmpcam_devices_lock);
83 list_for_each_entry(cam, &mmpcam_devices, devlist) {
84 if (cam->pdev == pdev) {
85 mutex_unlock(&mmpcam_devices_lock);
86 return cam;
87 }
88 }
89 mutex_unlock(&mmpcam_devices_lock);
90 return NULL;
91}
92
93
94
95
96/*
97 * Power-related registers; this almost certainly belongs
98 * somewhere else.
99 *
100 * ARMADA 610 register manual, sec 7.2.1, p1842.
101 */
102#define CPU_SUBSYS_PMU_BASE 0xd4282800
103#define REG_CCIC_DCGCR 0x28 /* CCIC dyn clock gate ctrl reg */
104#define REG_CCIC_CRCR 0x50 /* CCIC clk reset ctrl reg */
105
106/*
107 * Power control.
108 */
109static void mmpcam_power_up_ctlr(struct mmp_camera *cam)
110{
111 iowrite32(0x3f, cam->power_regs + REG_CCIC_DCGCR);
112 iowrite32(0x3805b, cam->power_regs + REG_CCIC_CRCR);
113 mdelay(1);
114}
115
116static void mmpcam_power_up(struct mcam_camera *mcam)
117{
118 struct mmp_camera *cam = mcam_to_cam(mcam);
119 struct mmp_camera_platform_data *pdata;
120/*
121 * Turn on power and clocks to the controller.
122 */
123 mmpcam_power_up_ctlr(cam);
124/*
125 * Provide power to the sensor.
126 */
127 mcam_reg_write(mcam, REG_CLKCTRL, 0x60000002);
128 pdata = cam->pdev->dev.platform_data;
129 gpio_set_value(pdata->sensor_power_gpio, 1);
130 mdelay(5);
131 mcam_reg_clear_bit(mcam, REG_CTRL1, 0x10000000);
132 gpio_set_value(pdata->sensor_reset_gpio, 0); /* reset is active low */
133 mdelay(5);
134 gpio_set_value(pdata->sensor_reset_gpio, 1); /* reset is active low */
135 mdelay(5);
136}
137
138static void mmpcam_power_down(struct mcam_camera *mcam)
139{
140 struct mmp_camera *cam = mcam_to_cam(mcam);
141 struct mmp_camera_platform_data *pdata;
142/*
143 * Turn off clocks and set reset lines
144 */
145 iowrite32(0, cam->power_regs + REG_CCIC_DCGCR);
146 iowrite32(0, cam->power_regs + REG_CCIC_CRCR);
147/*
148 * Shut down the sensor.
149 */
150 pdata = cam->pdev->dev.platform_data;
151 gpio_set_value(pdata->sensor_power_gpio, 0);
152 gpio_set_value(pdata->sensor_reset_gpio, 0);
153}
154
155
156static irqreturn_t mmpcam_irq(int irq, void *data)
157{
158 struct mcam_camera *mcam = data;
159 unsigned int irqs, handled;
160
161 spin_lock(&mcam->dev_lock);
162 irqs = mcam_reg_read(mcam, REG_IRQSTAT);
163 handled = mccic_irq(mcam, irqs);
164 spin_unlock(&mcam->dev_lock);
165 return IRQ_RETVAL(handled);
166}
167
168
169static int mmpcam_probe(struct platform_device *pdev)
170{
171 struct mmp_camera *cam;
172 struct mcam_camera *mcam;
173 struct resource *res;
174 struct mmp_camera_platform_data *pdata;
175 int ret;
176
177 cam = kzalloc(sizeof(*cam), GFP_KERNEL);
178 if (cam == NULL)
179 return -ENOMEM;
180 cam->pdev = pdev;
181 INIT_LIST_HEAD(&cam->devlist);
182
183 mcam = &cam->mcam;
184 mcam->plat_power_up = mmpcam_power_up;
185 mcam->plat_power_down = mmpcam_power_down;
186 mcam->dev = &pdev->dev;
187 mcam->use_smbus = 0;
188 mcam->chip_id = V4L2_IDENT_ARMADA610;
189 mcam->buffer_mode = B_DMA_sg;
190 spin_lock_init(&mcam->dev_lock);
191 /*
192 * Get our I/O memory.
193 */
194 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
195 if (res == NULL) {
196 dev_err(&pdev->dev, "no iomem resource!\n");
197 ret = -ENODEV;
198 goto out_free;
199 }
200 mcam->regs = ioremap(res->start, resource_size(res));
201 if (mcam->regs == NULL) {
202 dev_err(&pdev->dev, "MMIO ioremap fail\n");
203 ret = -ENODEV;
204 goto out_free;
205 }
206 /*
207 * Power/clock memory is elsewhere; get it too. Perhaps this
208 * should really be managed outside of this driver?
209 */
210 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
211 if (res == NULL) {
212 dev_err(&pdev->dev, "no power resource!\n");
213 ret = -ENODEV;
214 goto out_unmap1;
215 }
216 cam->power_regs = ioremap(res->start, resource_size(res));
217 if (cam->power_regs == NULL) {
218 dev_err(&pdev->dev, "power MMIO ioremap fail\n");
219 ret = -ENODEV;
220 goto out_unmap1;
221 }
222 /*
223 * Find the i2c adapter. This assumes, of course, that the
224 * i2c bus is already up and functioning.
225 */
226 pdata = pdev->dev.platform_data;
227 mcam->i2c_adapter = platform_get_drvdata(pdata->i2c_device);
228 if (mcam->i2c_adapter == NULL) {
229 ret = -ENODEV;
230 dev_err(&pdev->dev, "No i2c adapter\n");
231 goto out_unmap2;
232 }
233 /*
234 * Sensor GPIO pins.
235 */
236 ret = gpio_request(pdata->sensor_power_gpio, "cam-power");
237 if (ret) {
238 dev_err(&pdev->dev, "Can't get sensor power gpio %d",
239 pdata->sensor_power_gpio);
240 goto out_unmap2;
241 }
242 gpio_direction_output(pdata->sensor_power_gpio, 0);
243 ret = gpio_request(pdata->sensor_reset_gpio, "cam-reset");
244 if (ret) {
245 dev_err(&pdev->dev, "Can't get sensor reset gpio %d",
246 pdata->sensor_reset_gpio);
247 goto out_gpio;
248 }
249 gpio_direction_output(pdata->sensor_reset_gpio, 0);
250 /*
251 * Power the device up and hand it off to the core.
252 */
253 mmpcam_power_up(mcam);
254 ret = mccic_register(mcam);
255 if (ret)
256 goto out_gpio2;
257 /*
258 * Finally, set up our IRQ now that the core is ready to
259 * deal with it.
260 */
261 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
262 if (res == NULL) {
263 ret = -ENODEV;
264 goto out_unregister;
265 }
266 cam->irq = res->start;
267 ret = request_irq(cam->irq, mmpcam_irq, IRQF_SHARED,
268 "mmp-camera", mcam);
269 if (ret == 0) {
270 mmpcam_add_device(cam);
271 return 0;
272 }
273
274out_unregister:
275 mccic_shutdown(mcam);
276out_gpio2:
277 mmpcam_power_down(mcam);
278 gpio_free(pdata->sensor_reset_gpio);
279out_gpio:
280 gpio_free(pdata->sensor_power_gpio);
281out_unmap2:
282 iounmap(cam->power_regs);
283out_unmap1:
284 iounmap(mcam->regs);
285out_free:
286 kfree(cam);
287 return ret;
288}
289
290
291static int mmpcam_remove(struct mmp_camera *cam)
292{
293 struct mcam_camera *mcam = &cam->mcam;
294 struct mmp_camera_platform_data *pdata;
295
296 mmpcam_remove_device(cam);
297 free_irq(cam->irq, mcam);
298 mccic_shutdown(mcam);
299 mmpcam_power_down(mcam);
300 pdata = cam->pdev->dev.platform_data;
301 gpio_free(pdata->sensor_reset_gpio);
302 gpio_free(pdata->sensor_power_gpio);
303 iounmap(cam->power_regs);
304 iounmap(mcam->regs);
305 kfree(cam);
306 return 0;
307}
308
309static int mmpcam_platform_remove(struct platform_device *pdev)
310{
311 struct mmp_camera *cam = mmpcam_find_device(pdev);
312
313 if (cam == NULL)
314 return -ENODEV;
315 return mmpcam_remove(cam);
316}
317
318/*
319 * Suspend/resume support.
320 */
321#ifdef CONFIG_PM
322
323static int mmpcam_suspend(struct platform_device *pdev, pm_message_t state)
324{
325 struct mmp_camera *cam = mmpcam_find_device(pdev);
326
327 if (state.event != PM_EVENT_SUSPEND)
328 return 0;
329 mccic_suspend(&cam->mcam);
330 return 0;
331}
332
333static int mmpcam_resume(struct platform_device *pdev)
334{
335 struct mmp_camera *cam = mmpcam_find_device(pdev);
336
337 /*
338 * Power up unconditionally just in case the core tries to
339 * touch a register even if nothing was active before; trust
340 * me, it's better this way.
341 */
342 mmpcam_power_up_ctlr(cam);
343 return mccic_resume(&cam->mcam);
344}
345
346#endif
347
348
349static struct platform_driver mmpcam_driver = {
350 .probe = mmpcam_probe,
351 .remove = mmpcam_platform_remove,
352#ifdef CONFIG_PM
353 .suspend = mmpcam_suspend,
354 .resume = mmpcam_resume,
355#endif
356 .driver = {
357 .name = "mmp-camera",
358 .owner = THIS_MODULE
359 }
360};
361
362
363static int __init mmpcam_init_module(void)
364{
365 mutex_init(&mmpcam_devices_lock);
366 return platform_driver_register(&mmpcam_driver);
367}
368
369static void __exit mmpcam_exit_module(void)
370{
371 platform_driver_unregister(&mmpcam_driver);
372 /*
373 * platform_driver_unregister() should have emptied the list
374 */
375 if (!list_empty(&mmpcam_devices))
376 printk(KERN_ERR "mmp_camera leaving devices behind\n");
377}
378
379module_init(mmpcam_init_module);
380module_exit(mmpcam_exit_module);
diff --git a/drivers/media/video/mem2mem_testdev.c b/drivers/media/video/mem2mem_testdev.c
deleted file mode 100644
index 6d0d2fb11bbe..000000000000
--- a/drivers/media/video/mem2mem_testdev.c
+++ /dev/null
@@ -1,1131 +0,0 @@
1/*
2 * A virtual v4l2-mem2mem example device.
3 *
4 * This is a virtual device driver for testing mem-to-mem videobuf framework.
5 * It simulates a device that uses memory buffers for both source and
6 * destination, processes the data and issues an "irq" (simulated by a timer).
7 * The device is capable of multi-instance, multi-buffer-per-transaction
8 * operation (via the mem2mem framework).
9 *
10 * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
11 * Pawel Osciak, <pawel@osciak.com>
12 * Marek Szyprowski, <m.szyprowski@samsung.com>
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by the
16 * Free Software Foundation; either version 2 of the
17 * License, or (at your option) any later version
18 */
19#include <linux/module.h>
20#include <linux/delay.h>
21#include <linux/fs.h>
22#include <linux/timer.h>
23#include <linux/sched.h>
24#include <linux/slab.h>
25
26#include <linux/platform_device.h>
27#include <media/v4l2-mem2mem.h>
28#include <media/v4l2-device.h>
29#include <media/v4l2-ioctl.h>
30#include <media/v4l2-ctrls.h>
31#include <media/v4l2-event.h>
32#include <media/videobuf2-vmalloc.h>
33
34#define MEM2MEM_TEST_MODULE_NAME "mem2mem-testdev"
35
36MODULE_DESCRIPTION("Virtual device for mem2mem framework testing");
37MODULE_AUTHOR("Pawel Osciak, <pawel@osciak.com>");
38MODULE_LICENSE("GPL");
39MODULE_VERSION("0.1.1");
40
41#define MIN_W 32
42#define MIN_H 32
43#define MAX_W 640
44#define MAX_H 480
45#define DIM_ALIGN_MASK 7 /* 8-byte alignment for line length */
46
47/* Flags that indicate a format can be used for capture/output */
48#define MEM2MEM_CAPTURE (1 << 0)
49#define MEM2MEM_OUTPUT (1 << 1)
50
51#define MEM2MEM_NAME "m2m-testdev"
52
53/* Per queue */
54#define MEM2MEM_DEF_NUM_BUFS VIDEO_MAX_FRAME
55/* In bytes, per queue */
56#define MEM2MEM_VID_MEM_LIMIT (16 * 1024 * 1024)
57
58/* Default transaction time in msec */
59#define MEM2MEM_DEF_TRANSTIME 1000
60/* Default number of buffers per transaction */
61#define MEM2MEM_DEF_TRANSLEN 1
62#define MEM2MEM_COLOR_STEP (0xff >> 4)
63#define MEM2MEM_NUM_TILES 8
64
65/* Flags that indicate processing mode */
66#define MEM2MEM_HFLIP (1 << 0)
67#define MEM2MEM_VFLIP (1 << 1)
68
69#define dprintk(dev, fmt, arg...) \
70 v4l2_dbg(1, 1, &dev->v4l2_dev, "%s: " fmt, __func__, ## arg)
71
72
73void m2mtest_dev_release(struct device *dev)
74{}
75
76static struct platform_device m2mtest_pdev = {
77 .name = MEM2MEM_NAME,
78 .dev.release = m2mtest_dev_release,
79};
80
81struct m2mtest_fmt {
82 char *name;
83 u32 fourcc;
84 int depth;
85 /* Types the format can be used for */
86 u32 types;
87};
88
89static struct m2mtest_fmt formats[] = {
90 {
91 .name = "RGB565 (BE)",
92 .fourcc = V4L2_PIX_FMT_RGB565X, /* rrrrrggg gggbbbbb */
93 .depth = 16,
94 /* Both capture and output format */
95 .types = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT,
96 },
97 {
98 .name = "4:2:2, packed, YUYV",
99 .fourcc = V4L2_PIX_FMT_YUYV,
100 .depth = 16,
101 /* Output-only format */
102 .types = MEM2MEM_OUTPUT,
103 },
104};
105
106#define NUM_FORMATS ARRAY_SIZE(formats)
107
108/* Per-queue, driver-specific private data */
109struct m2mtest_q_data {
110 unsigned int width;
111 unsigned int height;
112 unsigned int sizeimage;
113 struct m2mtest_fmt *fmt;
114};
115
116enum {
117 V4L2_M2M_SRC = 0,
118 V4L2_M2M_DST = 1,
119};
120
121#define V4L2_CID_TRANS_TIME_MSEC (V4L2_CID_USER_BASE + 0x1000)
122#define V4L2_CID_TRANS_NUM_BUFS (V4L2_CID_USER_BASE + 0x1001)
123
124static struct m2mtest_fmt *find_format(struct v4l2_format *f)
125{
126 struct m2mtest_fmt *fmt;
127 unsigned int k;
128
129 for (k = 0; k < NUM_FORMATS; k++) {
130 fmt = &formats[k];
131 if (fmt->fourcc == f->fmt.pix.pixelformat)
132 break;
133 }
134
135 if (k == NUM_FORMATS)
136 return NULL;
137
138 return &formats[k];
139}
140
141struct m2mtest_dev {
142 struct v4l2_device v4l2_dev;
143 struct video_device *vfd;
144
145 atomic_t num_inst;
146 struct mutex dev_mutex;
147 spinlock_t irqlock;
148
149 struct timer_list timer;
150
151 struct v4l2_m2m_dev *m2m_dev;
152};
153
154struct m2mtest_ctx {
155 struct v4l2_fh fh;
156 struct m2mtest_dev *dev;
157
158 struct v4l2_ctrl_handler hdl;
159
160 /* Processed buffers in this transaction */
161 u8 num_processed;
162
163 /* Transaction length (i.e. how many buffers per transaction) */
164 u32 translen;
165 /* Transaction time (i.e. simulated processing time) in milliseconds */
166 u32 transtime;
167
168 /* Abort requested by m2m */
169 int aborting;
170
171 /* Processing mode */
172 int mode;
173
174 enum v4l2_colorspace colorspace;
175
176 struct v4l2_m2m_ctx *m2m_ctx;
177
178 /* Source and destination queue data */
179 struct m2mtest_q_data q_data[2];
180};
181
182static inline struct m2mtest_ctx *file2ctx(struct file *file)
183{
184 return container_of(file->private_data, struct m2mtest_ctx, fh);
185}
186
187static struct m2mtest_q_data *get_q_data(struct m2mtest_ctx *ctx,
188 enum v4l2_buf_type type)
189{
190 switch (type) {
191 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
192 return &ctx->q_data[V4L2_M2M_SRC];
193 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
194 return &ctx->q_data[V4L2_M2M_DST];
195 default:
196 BUG();
197 }
198 return NULL;
199}
200
201
202static int device_process(struct m2mtest_ctx *ctx,
203 struct vb2_buffer *in_vb,
204 struct vb2_buffer *out_vb)
205{
206 struct m2mtest_dev *dev = ctx->dev;
207 struct m2mtest_q_data *q_data;
208 u8 *p_in, *p_out;
209 int x, y, t, w;
210 int tile_w, bytes_left;
211 int width, height, bytesperline;
212
213 q_data = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
214
215 width = q_data->width;
216 height = q_data->height;
217 bytesperline = (q_data->width * q_data->fmt->depth) >> 3;
218
219 p_in = vb2_plane_vaddr(in_vb, 0);
220 p_out = vb2_plane_vaddr(out_vb, 0);
221 if (!p_in || !p_out) {
222 v4l2_err(&dev->v4l2_dev,
223 "Acquiring kernel pointers to buffers failed\n");
224 return -EFAULT;
225 }
226
227 if (vb2_plane_size(in_vb, 0) > vb2_plane_size(out_vb, 0)) {
228 v4l2_err(&dev->v4l2_dev, "Output buffer is too small\n");
229 return -EINVAL;
230 }
231
232 tile_w = (width * (q_data[V4L2_M2M_DST].fmt->depth >> 3))
233 / MEM2MEM_NUM_TILES;
234 bytes_left = bytesperline - tile_w * MEM2MEM_NUM_TILES;
235 w = 0;
236
237 switch (ctx->mode) {
238 case MEM2MEM_HFLIP | MEM2MEM_VFLIP:
239 p_out += bytesperline * height - bytes_left;
240 for (y = 0; y < height; ++y) {
241 for (t = 0; t < MEM2MEM_NUM_TILES; ++t) {
242 if (w & 0x1) {
243 for (x = 0; x < tile_w; ++x)
244 *--p_out = *p_in++ +
245 MEM2MEM_COLOR_STEP;
246 } else {
247 for (x = 0; x < tile_w; ++x)
248 *--p_out = *p_in++ -
249 MEM2MEM_COLOR_STEP;
250 }
251 ++w;
252 }
253 p_in += bytes_left;
254 p_out -= bytes_left;
255 }
256 break;
257
258 case MEM2MEM_HFLIP:
259 for (y = 0; y < height; ++y) {
260 p_out += MEM2MEM_NUM_TILES * tile_w;
261 for (t = 0; t < MEM2MEM_NUM_TILES; ++t) {
262 if (w & 0x01) {
263 for (x = 0; x < tile_w; ++x)
264 *--p_out = *p_in++ +
265 MEM2MEM_COLOR_STEP;
266 } else {
267 for (x = 0; x < tile_w; ++x)
268 *--p_out = *p_in++ -
269 MEM2MEM_COLOR_STEP;
270 }
271 ++w;
272 }
273 p_in += bytes_left;
274 p_out += bytesperline;
275 }
276 break;
277
278 case MEM2MEM_VFLIP:
279 p_out += bytesperline * (height - 1);
280 for (y = 0; y < height; ++y) {
281 for (t = 0; t < MEM2MEM_NUM_TILES; ++t) {
282 if (w & 0x1) {
283 for (x = 0; x < tile_w; ++x)
284 *p_out++ = *p_in++ +
285 MEM2MEM_COLOR_STEP;
286 } else {
287 for (x = 0; x < tile_w; ++x)
288 *p_out++ = *p_in++ -
289 MEM2MEM_COLOR_STEP;
290 }
291 ++w;
292 }
293 p_in += bytes_left;
294 p_out += bytes_left - 2 * bytesperline;
295 }
296 break;
297
298 default:
299 for (y = 0; y < height; ++y) {
300 for (t = 0; t < MEM2MEM_NUM_TILES; ++t) {
301 if (w & 0x1) {
302 for (x = 0; x < tile_w; ++x)
303 *p_out++ = *p_in++ +
304 MEM2MEM_COLOR_STEP;
305 } else {
306 for (x = 0; x < tile_w; ++x)
307 *p_out++ = *p_in++ -
308 MEM2MEM_COLOR_STEP;
309 }
310 ++w;
311 }
312 p_in += bytes_left;
313 p_out += bytes_left;
314 }
315 }
316
317 return 0;
318}
319
320static void schedule_irq(struct m2mtest_dev *dev, int msec_timeout)
321{
322 dprintk(dev, "Scheduling a simulated irq\n");
323 mod_timer(&dev->timer, jiffies + msecs_to_jiffies(msec_timeout));
324}
325
326/*
327 * mem2mem callbacks
328 */
329
330/**
331 * job_ready() - check whether an instance is ready to be scheduled to run
332 */
333static int job_ready(void *priv)
334{
335 struct m2mtest_ctx *ctx = priv;
336
337 if (v4l2_m2m_num_src_bufs_ready(ctx->m2m_ctx) < ctx->translen
338 || v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx) < ctx->translen) {
339 dprintk(ctx->dev, "Not enough buffers available\n");
340 return 0;
341 }
342
343 return 1;
344}
345
346static void job_abort(void *priv)
347{
348 struct m2mtest_ctx *ctx = priv;
349
350 /* Will cancel the transaction in the next interrupt handler */
351 ctx->aborting = 1;
352}
353
354static void m2mtest_lock(void *priv)
355{
356 struct m2mtest_ctx *ctx = priv;
357 struct m2mtest_dev *dev = ctx->dev;
358 mutex_lock(&dev->dev_mutex);
359}
360
361static void m2mtest_unlock(void *priv)
362{
363 struct m2mtest_ctx *ctx = priv;
364 struct m2mtest_dev *dev = ctx->dev;
365 mutex_unlock(&dev->dev_mutex);
366}
367
368
369/* device_run() - prepares and starts the device
370 *
371 * This simulates all the immediate preparations required before starting
372 * a device. This will be called by the framework when it decides to schedule
373 * a particular instance.
374 */
375static void device_run(void *priv)
376{
377 struct m2mtest_ctx *ctx = priv;
378 struct m2mtest_dev *dev = ctx->dev;
379 struct vb2_buffer *src_buf, *dst_buf;
380
381 src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
382 dst_buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
383
384 device_process(ctx, src_buf, dst_buf);
385
386 /* Run a timer, which simulates a hardware irq */
387 schedule_irq(dev, ctx->transtime);
388}
389
390static void device_isr(unsigned long priv)
391{
392 struct m2mtest_dev *m2mtest_dev = (struct m2mtest_dev *)priv;
393 struct m2mtest_ctx *curr_ctx;
394 struct vb2_buffer *src_vb, *dst_vb;
395 unsigned long flags;
396
397 curr_ctx = v4l2_m2m_get_curr_priv(m2mtest_dev->m2m_dev);
398
399 if (NULL == curr_ctx) {
400 printk(KERN_ERR
401 "Instance released before the end of transaction\n");
402 return;
403 }
404
405 src_vb = v4l2_m2m_src_buf_remove(curr_ctx->m2m_ctx);
406 dst_vb = v4l2_m2m_dst_buf_remove(curr_ctx->m2m_ctx);
407
408 curr_ctx->num_processed++;
409
410 spin_lock_irqsave(&m2mtest_dev->irqlock, flags);
411 v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_DONE);
412 v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_DONE);
413 spin_unlock_irqrestore(&m2mtest_dev->irqlock, flags);
414
415 if (curr_ctx->num_processed == curr_ctx->translen
416 || curr_ctx->aborting) {
417 dprintk(curr_ctx->dev, "Finishing transaction\n");
418 curr_ctx->num_processed = 0;
419 v4l2_m2m_job_finish(m2mtest_dev->m2m_dev, curr_ctx->m2m_ctx);
420 } else {
421 device_run(curr_ctx);
422 }
423}
424
425/*
426 * video ioctls
427 */
428static int vidioc_querycap(struct file *file, void *priv,
429 struct v4l2_capability *cap)
430{
431 strncpy(cap->driver, MEM2MEM_NAME, sizeof(cap->driver) - 1);
432 strncpy(cap->card, MEM2MEM_NAME, sizeof(cap->card) - 1);
433 strlcpy(cap->bus_info, MEM2MEM_NAME, sizeof(cap->bus_info));
434 cap->capabilities = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING;
435 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
436 return 0;
437}
438
439static int enum_fmt(struct v4l2_fmtdesc *f, u32 type)
440{
441 int i, num;
442 struct m2mtest_fmt *fmt;
443
444 num = 0;
445
446 for (i = 0; i < NUM_FORMATS; ++i) {
447 if (formats[i].types & type) {
448 /* index-th format of type type found ? */
449 if (num == f->index)
450 break;
451 /* Correct type but haven't reached our index yet,
452 * just increment per-type index */
453 ++num;
454 }
455 }
456
457 if (i < NUM_FORMATS) {
458 /* Format found */
459 fmt = &formats[i];
460 strncpy(f->description, fmt->name, sizeof(f->description) - 1);
461 f->pixelformat = fmt->fourcc;
462 return 0;
463 }
464
465 /* Format not found */
466 return -EINVAL;
467}
468
469static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
470 struct v4l2_fmtdesc *f)
471{
472 return enum_fmt(f, MEM2MEM_CAPTURE);
473}
474
475static int vidioc_enum_fmt_vid_out(struct file *file, void *priv,
476 struct v4l2_fmtdesc *f)
477{
478 return enum_fmt(f, MEM2MEM_OUTPUT);
479}
480
481static int vidioc_g_fmt(struct m2mtest_ctx *ctx, struct v4l2_format *f)
482{
483 struct vb2_queue *vq;
484 struct m2mtest_q_data *q_data;
485
486 vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
487 if (!vq)
488 return -EINVAL;
489
490 q_data = get_q_data(ctx, f->type);
491
492 f->fmt.pix.width = q_data->width;
493 f->fmt.pix.height = q_data->height;
494 f->fmt.pix.field = V4L2_FIELD_NONE;
495 f->fmt.pix.pixelformat = q_data->fmt->fourcc;
496 f->fmt.pix.bytesperline = (q_data->width * q_data->fmt->depth) >> 3;
497 f->fmt.pix.sizeimage = q_data->sizeimage;
498 f->fmt.pix.colorspace = ctx->colorspace;
499
500 return 0;
501}
502
503static int vidioc_g_fmt_vid_out(struct file *file, void *priv,
504 struct v4l2_format *f)
505{
506 return vidioc_g_fmt(file2ctx(file), f);
507}
508
509static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
510 struct v4l2_format *f)
511{
512 return vidioc_g_fmt(file2ctx(file), f);
513}
514
515static int vidioc_try_fmt(struct v4l2_format *f, struct m2mtest_fmt *fmt)
516{
517 enum v4l2_field field;
518
519 field = f->fmt.pix.field;
520
521 if (field == V4L2_FIELD_ANY)
522 field = V4L2_FIELD_NONE;
523 else if (V4L2_FIELD_NONE != field)
524 return -EINVAL;
525
526 /* V4L2 specification suggests the driver corrects the format struct
527 * if any of the dimensions is unsupported */
528 f->fmt.pix.field = field;
529
530 if (f->fmt.pix.height < MIN_H)
531 f->fmt.pix.height = MIN_H;
532 else if (f->fmt.pix.height > MAX_H)
533 f->fmt.pix.height = MAX_H;
534
535 if (f->fmt.pix.width < MIN_W)
536 f->fmt.pix.width = MIN_W;
537 else if (f->fmt.pix.width > MAX_W)
538 f->fmt.pix.width = MAX_W;
539
540 f->fmt.pix.width &= ~DIM_ALIGN_MASK;
541 f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
542 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
543
544 return 0;
545}
546
547static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
548 struct v4l2_format *f)
549{
550 struct m2mtest_fmt *fmt;
551 struct m2mtest_ctx *ctx = file2ctx(file);
552
553 fmt = find_format(f);
554 if (!fmt || !(fmt->types & MEM2MEM_CAPTURE)) {
555 v4l2_err(&ctx->dev->v4l2_dev,
556 "Fourcc format (0x%08x) invalid.\n",
557 f->fmt.pix.pixelformat);
558 return -EINVAL;
559 }
560 f->fmt.pix.colorspace = ctx->colorspace;
561
562 return vidioc_try_fmt(f, fmt);
563}
564
565static int vidioc_try_fmt_vid_out(struct file *file, void *priv,
566 struct v4l2_format *f)
567{
568 struct m2mtest_fmt *fmt;
569 struct m2mtest_ctx *ctx = file2ctx(file);
570
571 fmt = find_format(f);
572 if (!fmt || !(fmt->types & MEM2MEM_OUTPUT)) {
573 v4l2_err(&ctx->dev->v4l2_dev,
574 "Fourcc format (0x%08x) invalid.\n",
575 f->fmt.pix.pixelformat);
576 return -EINVAL;
577 }
578 if (!f->fmt.pix.colorspace)
579 f->fmt.pix.colorspace = V4L2_COLORSPACE_REC709;
580
581 return vidioc_try_fmt(f, fmt);
582}
583
584static int vidioc_s_fmt(struct m2mtest_ctx *ctx, struct v4l2_format *f)
585{
586 struct m2mtest_q_data *q_data;
587 struct vb2_queue *vq;
588
589 vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
590 if (!vq)
591 return -EINVAL;
592
593 q_data = get_q_data(ctx, f->type);
594 if (!q_data)
595 return -EINVAL;
596
597 if (vb2_is_busy(vq)) {
598 v4l2_err(&ctx->dev->v4l2_dev, "%s queue busy\n", __func__);
599 return -EBUSY;
600 }
601
602 q_data->fmt = find_format(f);
603 q_data->width = f->fmt.pix.width;
604 q_data->height = f->fmt.pix.height;
605 q_data->sizeimage = q_data->width * q_data->height
606 * q_data->fmt->depth >> 3;
607
608 dprintk(ctx->dev,
609 "Setting format for type %d, wxh: %dx%d, fmt: %d\n",
610 f->type, q_data->width, q_data->height, q_data->fmt->fourcc);
611
612 return 0;
613}
614
615static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
616 struct v4l2_format *f)
617{
618 int ret;
619
620 ret = vidioc_try_fmt_vid_cap(file, priv, f);
621 if (ret)
622 return ret;
623
624 return vidioc_s_fmt(file2ctx(file), f);
625}
626
627static int vidioc_s_fmt_vid_out(struct file *file, void *priv,
628 struct v4l2_format *f)
629{
630 struct m2mtest_ctx *ctx = file2ctx(file);
631 int ret;
632
633 ret = vidioc_try_fmt_vid_out(file, priv, f);
634 if (ret)
635 return ret;
636
637 ret = vidioc_s_fmt(file2ctx(file), f);
638 if (!ret)
639 ctx->colorspace = f->fmt.pix.colorspace;
640 return ret;
641}
642
643static int vidioc_reqbufs(struct file *file, void *priv,
644 struct v4l2_requestbuffers *reqbufs)
645{
646 struct m2mtest_ctx *ctx = file2ctx(file);
647
648 return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs);
649}
650
651static int vidioc_querybuf(struct file *file, void *priv,
652 struct v4l2_buffer *buf)
653{
654 struct m2mtest_ctx *ctx = file2ctx(file);
655
656 return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf);
657}
658
659static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
660{
661 struct m2mtest_ctx *ctx = file2ctx(file);
662
663 return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
664}
665
666static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
667{
668 struct m2mtest_ctx *ctx = file2ctx(file);
669
670 return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
671}
672
673static int vidioc_streamon(struct file *file, void *priv,
674 enum v4l2_buf_type type)
675{
676 struct m2mtest_ctx *ctx = file2ctx(file);
677
678 return v4l2_m2m_streamon(file, ctx->m2m_ctx, type);
679}
680
681static int vidioc_streamoff(struct file *file, void *priv,
682 enum v4l2_buf_type type)
683{
684 struct m2mtest_ctx *ctx = file2ctx(file);
685
686 return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type);
687}
688
689static int m2mtest_s_ctrl(struct v4l2_ctrl *ctrl)
690{
691 struct m2mtest_ctx *ctx =
692 container_of(ctrl->handler, struct m2mtest_ctx, hdl);
693
694 switch (ctrl->id) {
695 case V4L2_CID_HFLIP:
696 if (ctrl->val)
697 ctx->mode |= MEM2MEM_HFLIP;
698 else
699 ctx->mode &= ~MEM2MEM_HFLIP;
700 break;
701
702 case V4L2_CID_VFLIP:
703 if (ctrl->val)
704 ctx->mode |= MEM2MEM_VFLIP;
705 else
706 ctx->mode &= ~MEM2MEM_VFLIP;
707 break;
708
709 case V4L2_CID_TRANS_TIME_MSEC:
710 ctx->transtime = ctrl->val;
711 break;
712
713 case V4L2_CID_TRANS_NUM_BUFS:
714 ctx->translen = ctrl->val;
715 break;
716
717 default:
718 v4l2_err(&ctx->dev->v4l2_dev, "Invalid control\n");
719 return -EINVAL;
720 }
721
722 return 0;
723}
724
725static const struct v4l2_ctrl_ops m2mtest_ctrl_ops = {
726 .s_ctrl = m2mtest_s_ctrl,
727};
728
729
730static const struct v4l2_ioctl_ops m2mtest_ioctl_ops = {
731 .vidioc_querycap = vidioc_querycap,
732
733 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
734 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
735 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
736 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
737
738 .vidioc_enum_fmt_vid_out = vidioc_enum_fmt_vid_out,
739 .vidioc_g_fmt_vid_out = vidioc_g_fmt_vid_out,
740 .vidioc_try_fmt_vid_out = vidioc_try_fmt_vid_out,
741 .vidioc_s_fmt_vid_out = vidioc_s_fmt_vid_out,
742
743 .vidioc_reqbufs = vidioc_reqbufs,
744 .vidioc_querybuf = vidioc_querybuf,
745
746 .vidioc_qbuf = vidioc_qbuf,
747 .vidioc_dqbuf = vidioc_dqbuf,
748
749 .vidioc_streamon = vidioc_streamon,
750 .vidioc_streamoff = vidioc_streamoff,
751 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
752 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
753};
754
755
756/*
757 * Queue operations
758 */
759
760static int m2mtest_queue_setup(struct vb2_queue *vq,
761 const struct v4l2_format *fmt,
762 unsigned int *nbuffers, unsigned int *nplanes,
763 unsigned int sizes[], void *alloc_ctxs[])
764{
765 struct m2mtest_ctx *ctx = vb2_get_drv_priv(vq);
766 struct m2mtest_q_data *q_data;
767 unsigned int size, count = *nbuffers;
768
769 q_data = get_q_data(ctx, vq->type);
770
771 size = q_data->width * q_data->height * q_data->fmt->depth >> 3;
772
773 while (size * count > MEM2MEM_VID_MEM_LIMIT)
774 (count)--;
775
776 *nplanes = 1;
777 *nbuffers = count;
778 sizes[0] = size;
779
780 /*
781 * videobuf2-vmalloc allocator is context-less so no need to set
782 * alloc_ctxs array.
783 */
784
785 dprintk(ctx->dev, "get %d buffer(s) of size %d each.\n", count, size);
786
787 return 0;
788}
789
790static int m2mtest_buf_prepare(struct vb2_buffer *vb)
791{
792 struct m2mtest_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
793 struct m2mtest_q_data *q_data;
794
795 dprintk(ctx->dev, "type: %d\n", vb->vb2_queue->type);
796
797 q_data = get_q_data(ctx, vb->vb2_queue->type);
798
799 if (vb2_plane_size(vb, 0) < q_data->sizeimage) {
800 dprintk(ctx->dev, "%s data will not fit into plane (%lu < %lu)\n",
801 __func__, vb2_plane_size(vb, 0), (long)q_data->sizeimage);
802 return -EINVAL;
803 }
804
805 vb2_set_plane_payload(vb, 0, q_data->sizeimage);
806
807 return 0;
808}
809
810static void m2mtest_buf_queue(struct vb2_buffer *vb)
811{
812 struct m2mtest_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
813 v4l2_m2m_buf_queue(ctx->m2m_ctx, vb);
814}
815
816static void m2mtest_wait_prepare(struct vb2_queue *q)
817{
818 struct m2mtest_ctx *ctx = vb2_get_drv_priv(q);
819 m2mtest_unlock(ctx);
820}
821
822static void m2mtest_wait_finish(struct vb2_queue *q)
823{
824 struct m2mtest_ctx *ctx = vb2_get_drv_priv(q);
825 m2mtest_lock(ctx);
826}
827
828static struct vb2_ops m2mtest_qops = {
829 .queue_setup = m2mtest_queue_setup,
830 .buf_prepare = m2mtest_buf_prepare,
831 .buf_queue = m2mtest_buf_queue,
832 .wait_prepare = m2mtest_wait_prepare,
833 .wait_finish = m2mtest_wait_finish,
834};
835
836static int queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq)
837{
838 struct m2mtest_ctx *ctx = priv;
839 int ret;
840
841 memset(src_vq, 0, sizeof(*src_vq));
842 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
843 src_vq->io_modes = VB2_MMAP;
844 src_vq->drv_priv = ctx;
845 src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
846 src_vq->ops = &m2mtest_qops;
847 src_vq->mem_ops = &vb2_vmalloc_memops;
848
849 ret = vb2_queue_init(src_vq);
850 if (ret)
851 return ret;
852
853 memset(dst_vq, 0, sizeof(*dst_vq));
854 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
855 dst_vq->io_modes = VB2_MMAP;
856 dst_vq->drv_priv = ctx;
857 dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
858 dst_vq->ops = &m2mtest_qops;
859 dst_vq->mem_ops = &vb2_vmalloc_memops;
860
861 return vb2_queue_init(dst_vq);
862}
863
864static const struct v4l2_ctrl_config m2mtest_ctrl_trans_time_msec = {
865 .ops = &m2mtest_ctrl_ops,
866 .id = V4L2_CID_TRANS_TIME_MSEC,
867 .name = "Transaction Time (msec)",
868 .type = V4L2_CTRL_TYPE_INTEGER,
869 .def = 1001,
870 .min = 1,
871 .max = 10001,
872 .step = 100,
873};
874
875static const struct v4l2_ctrl_config m2mtest_ctrl_trans_num_bufs = {
876 .ops = &m2mtest_ctrl_ops,
877 .id = V4L2_CID_TRANS_NUM_BUFS,
878 .name = "Buffers Per Transaction",
879 .type = V4L2_CTRL_TYPE_INTEGER,
880 .def = 1,
881 .min = 1,
882 .max = MEM2MEM_DEF_NUM_BUFS,
883 .step = 1,
884};
885
886/*
887 * File operations
888 */
889static int m2mtest_open(struct file *file)
890{
891 struct m2mtest_dev *dev = video_drvdata(file);
892 struct m2mtest_ctx *ctx = NULL;
893 struct v4l2_ctrl_handler *hdl;
894 int rc = 0;
895
896 if (mutex_lock_interruptible(&dev->dev_mutex))
897 return -ERESTARTSYS;
898 ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
899 if (!ctx) {
900 rc = -ENOMEM;
901 goto open_unlock;
902 }
903
904 v4l2_fh_init(&ctx->fh, video_devdata(file));
905 file->private_data = &ctx->fh;
906 ctx->dev = dev;
907 hdl = &ctx->hdl;
908 v4l2_ctrl_handler_init(hdl, 4);
909 v4l2_ctrl_new_std(hdl, &m2mtest_ctrl_ops, V4L2_CID_HFLIP, 0, 1, 1, 0);
910 v4l2_ctrl_new_std(hdl, &m2mtest_ctrl_ops, V4L2_CID_VFLIP, 0, 1, 1, 0);
911 v4l2_ctrl_new_custom(hdl, &m2mtest_ctrl_trans_time_msec, NULL);
912 v4l2_ctrl_new_custom(hdl, &m2mtest_ctrl_trans_num_bufs, NULL);
913 if (hdl->error) {
914 int err = hdl->error;
915
916 v4l2_ctrl_handler_free(hdl);
917 return err;
918 }
919 ctx->fh.ctrl_handler = hdl;
920 v4l2_ctrl_handler_setup(hdl);
921
922 ctx->q_data[V4L2_M2M_SRC].fmt = &formats[0];
923 ctx->q_data[V4L2_M2M_SRC].width = 640;
924 ctx->q_data[V4L2_M2M_SRC].height = 480;
925 ctx->q_data[V4L2_M2M_SRC].sizeimage =
926 ctx->q_data[V4L2_M2M_SRC].width *
927 ctx->q_data[V4L2_M2M_SRC].height *
928 (ctx->q_data[V4L2_M2M_SRC].fmt->depth >> 3);
929 ctx->q_data[V4L2_M2M_DST] = ctx->q_data[V4L2_M2M_SRC];
930 ctx->colorspace = V4L2_COLORSPACE_REC709;
931
932 ctx->m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx, &queue_init);
933
934 if (IS_ERR(ctx->m2m_ctx)) {
935 rc = PTR_ERR(ctx->m2m_ctx);
936
937 v4l2_ctrl_handler_free(hdl);
938 kfree(ctx);
939 goto open_unlock;
940 }
941
942 v4l2_fh_add(&ctx->fh);
943 atomic_inc(&dev->num_inst);
944
945 dprintk(dev, "Created instance %p, m2m_ctx: %p\n", ctx, ctx->m2m_ctx);
946
947open_unlock:
948 mutex_unlock(&dev->dev_mutex);
949 return 0;
950}
951
952static int m2mtest_release(struct file *file)
953{
954 struct m2mtest_dev *dev = video_drvdata(file);
955 struct m2mtest_ctx *ctx = file2ctx(file);
956
957 dprintk(dev, "Releasing instance %p\n", ctx);
958
959 v4l2_fh_del(&ctx->fh);
960 v4l2_fh_exit(&ctx->fh);
961 v4l2_ctrl_handler_free(&ctx->hdl);
962 mutex_lock(&dev->dev_mutex);
963 v4l2_m2m_ctx_release(ctx->m2m_ctx);
964 mutex_unlock(&dev->dev_mutex);
965 kfree(ctx);
966
967 atomic_dec(&dev->num_inst);
968
969 return 0;
970}
971
972static unsigned int m2mtest_poll(struct file *file,
973 struct poll_table_struct *wait)
974{
975 struct m2mtest_ctx *ctx = file2ctx(file);
976
977 return v4l2_m2m_poll(file, ctx->m2m_ctx, wait);
978}
979
980static int m2mtest_mmap(struct file *file, struct vm_area_struct *vma)
981{
982 struct m2mtest_dev *dev = video_drvdata(file);
983 struct m2mtest_ctx *ctx = file2ctx(file);
984 int res;
985
986 if (mutex_lock_interruptible(&dev->dev_mutex))
987 return -ERESTARTSYS;
988 res = v4l2_m2m_mmap(file, ctx->m2m_ctx, vma);
989 mutex_unlock(&dev->dev_mutex);
990 return res;
991}
992
993static const struct v4l2_file_operations m2mtest_fops = {
994 .owner = THIS_MODULE,
995 .open = m2mtest_open,
996 .release = m2mtest_release,
997 .poll = m2mtest_poll,
998 .unlocked_ioctl = video_ioctl2,
999 .mmap = m2mtest_mmap,
1000};
1001
1002static struct video_device m2mtest_videodev = {
1003 .name = MEM2MEM_NAME,
1004 .fops = &m2mtest_fops,
1005 .ioctl_ops = &m2mtest_ioctl_ops,
1006 .minor = -1,
1007 .release = video_device_release,
1008};
1009
1010static struct v4l2_m2m_ops m2m_ops = {
1011 .device_run = device_run,
1012 .job_ready = job_ready,
1013 .job_abort = job_abort,
1014 .lock = m2mtest_lock,
1015 .unlock = m2mtest_unlock,
1016};
1017
1018static int m2mtest_probe(struct platform_device *pdev)
1019{
1020 struct m2mtest_dev *dev;
1021 struct video_device *vfd;
1022 int ret;
1023
1024 dev = kzalloc(sizeof *dev, GFP_KERNEL);
1025 if (!dev)
1026 return -ENOMEM;
1027
1028 spin_lock_init(&dev->irqlock);
1029
1030 ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
1031 if (ret)
1032 goto free_dev;
1033
1034 atomic_set(&dev->num_inst, 0);
1035 mutex_init(&dev->dev_mutex);
1036
1037 vfd = video_device_alloc();
1038 if (!vfd) {
1039 v4l2_err(&dev->v4l2_dev, "Failed to allocate video device\n");
1040 ret = -ENOMEM;
1041 goto unreg_dev;
1042 }
1043
1044 *vfd = m2mtest_videodev;
1045 vfd->lock = &dev->dev_mutex;
1046
1047 ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
1048 if (ret) {
1049 v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");
1050 goto rel_vdev;
1051 }
1052
1053 video_set_drvdata(vfd, dev);
1054 snprintf(vfd->name, sizeof(vfd->name), "%s", m2mtest_videodev.name);
1055 dev->vfd = vfd;
1056 v4l2_info(&dev->v4l2_dev, MEM2MEM_TEST_MODULE_NAME
1057 "Device registered as /dev/video%d\n", vfd->num);
1058
1059 setup_timer(&dev->timer, device_isr, (long)dev);
1060 platform_set_drvdata(pdev, dev);
1061
1062 dev->m2m_dev = v4l2_m2m_init(&m2m_ops);
1063 if (IS_ERR(dev->m2m_dev)) {
1064 v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem device\n");
1065 ret = PTR_ERR(dev->m2m_dev);
1066 goto err_m2m;
1067 }
1068
1069 return 0;
1070
1071 v4l2_m2m_release(dev->m2m_dev);
1072err_m2m:
1073 video_unregister_device(dev->vfd);
1074rel_vdev:
1075 video_device_release(vfd);
1076unreg_dev:
1077 v4l2_device_unregister(&dev->v4l2_dev);
1078free_dev:
1079 kfree(dev);
1080
1081 return ret;
1082}
1083
1084static int m2mtest_remove(struct platform_device *pdev)
1085{
1086 struct m2mtest_dev *dev =
1087 (struct m2mtest_dev *)platform_get_drvdata(pdev);
1088
1089 v4l2_info(&dev->v4l2_dev, "Removing " MEM2MEM_TEST_MODULE_NAME);
1090 v4l2_m2m_release(dev->m2m_dev);
1091 del_timer_sync(&dev->timer);
1092 video_unregister_device(dev->vfd);
1093 v4l2_device_unregister(&dev->v4l2_dev);
1094 kfree(dev);
1095
1096 return 0;
1097}
1098
1099static struct platform_driver m2mtest_pdrv = {
1100 .probe = m2mtest_probe,
1101 .remove = m2mtest_remove,
1102 .driver = {
1103 .name = MEM2MEM_NAME,
1104 .owner = THIS_MODULE,
1105 },
1106};
1107
1108static void __exit m2mtest_exit(void)
1109{
1110 platform_driver_unregister(&m2mtest_pdrv);
1111 platform_device_unregister(&m2mtest_pdev);
1112}
1113
1114static int __init m2mtest_init(void)
1115{
1116 int ret;
1117
1118 ret = platform_device_register(&m2mtest_pdev);
1119 if (ret)
1120 return ret;
1121
1122 ret = platform_driver_register(&m2mtest_pdrv);
1123 if (ret)
1124 platform_device_unregister(&m2mtest_pdev);
1125
1126 return 0;
1127}
1128
1129module_init(m2mtest_init);
1130module_exit(m2mtest_exit);
1131
diff --git a/drivers/media/video/mx1_camera.c b/drivers/media/video/mx1_camera.c
deleted file mode 100644
index d2e6f82ecfac..000000000000
--- a/drivers/media/video/mx1_camera.c
+++ /dev/null
@@ -1,889 +0,0 @@
1/*
2 * V4L2 Driver for i.MXL/i.MXL camera (CSI) host
3 *
4 * Copyright (C) 2008, Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
5 * Copyright (C) 2009, Darius Augulis <augulis.darius@gmail.com>
6 *
7 * Based on PXA SoC camera driver
8 * Copyright (C) 2006, Sascha Hauer, Pengutronix
9 * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 */
15
16#include <linux/clk.h>
17#include <linux/delay.h>
18#include <linux/device.h>
19#include <linux/dma-mapping.h>
20#include <linux/errno.h>
21#include <linux/fs.h>
22#include <linux/init.h>
23#include <linux/interrupt.h>
24#include <linux/io.h>
25#include <linux/kernel.h>
26#include <linux/mm.h>
27#include <linux/module.h>
28#include <linux/moduleparam.h>
29#include <linux/mutex.h>
30#include <linux/platform_device.h>
31#include <linux/sched.h>
32#include <linux/slab.h>
33#include <linux/time.h>
34#include <linux/videodev2.h>
35
36#include <media/soc_camera.h>
37#include <media/v4l2-common.h>
38#include <media/v4l2-dev.h>
39#include <media/videobuf-dma-contig.h>
40#include <media/soc_mediabus.h>
41
42#include <asm/dma.h>
43#include <asm/fiq.h>
44#include <mach/dma-mx1-mx2.h>
45#include <mach/hardware.h>
46#include <mach/irqs.h>
47#include <mach/mx1_camera.h>
48
49/*
50 * CSI registers
51 */
52#define CSICR1 0x00 /* CSI Control Register 1 */
53#define CSISR 0x08 /* CSI Status Register */
54#define CSIRXR 0x10 /* CSI RxFIFO Register */
55
56#define CSICR1_RXFF_LEVEL(x) (((x) & 0x3) << 19)
57#define CSICR1_SOF_POL (1 << 17)
58#define CSICR1_SOF_INTEN (1 << 16)
59#define CSICR1_MCLKDIV(x) (((x) & 0xf) << 12)
60#define CSICR1_MCLKEN (1 << 9)
61#define CSICR1_FCC (1 << 8)
62#define CSICR1_BIG_ENDIAN (1 << 7)
63#define CSICR1_CLR_RXFIFO (1 << 5)
64#define CSICR1_GCLK_MODE (1 << 4)
65#define CSICR1_DATA_POL (1 << 2)
66#define CSICR1_REDGE (1 << 1)
67#define CSICR1_EN (1 << 0)
68
69#define CSISR_SFF_OR_INT (1 << 25)
70#define CSISR_RFF_OR_INT (1 << 24)
71#define CSISR_STATFF_INT (1 << 21)
72#define CSISR_RXFF_INT (1 << 18)
73#define CSISR_SOF_INT (1 << 16)
74#define CSISR_DRDY (1 << 0)
75
76#define DRIVER_VERSION "0.0.2"
77#define DRIVER_NAME "mx1-camera"
78
79#define CSI_IRQ_MASK (CSISR_SFF_OR_INT | CSISR_RFF_OR_INT | \
80 CSISR_STATFF_INT | CSISR_RXFF_INT | CSISR_SOF_INT)
81
82#define CSI_BUS_FLAGS (V4L2_MBUS_MASTER | V4L2_MBUS_HSYNC_ACTIVE_HIGH | \
83 V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_LOW | \
84 V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING | \
85 V4L2_MBUS_DATA_ACTIVE_HIGH | V4L2_MBUS_DATA_ACTIVE_LOW)
86
87#define MAX_VIDEO_MEM 16 /* Video memory limit in megabytes */
88
89/*
90 * Structures
91 */
92
93/* buffer for one video frame */
94struct mx1_buffer {
95 /* common v4l buffer stuff -- must be first */
96 struct videobuf_buffer vb;
97 enum v4l2_mbus_pixelcode code;
98 int inwork;
99};
100
101/*
102 * i.MX1/i.MXL is only supposed to handle one camera on its Camera Sensor
103 * Interface. If anyone ever builds hardware to enable more than
104 * one camera, they will have to modify this driver too
105 */
106struct mx1_camera_dev {
107 struct soc_camera_host soc_host;
108 struct soc_camera_device *icd;
109 struct mx1_camera_pdata *pdata;
110 struct mx1_buffer *active;
111 struct resource *res;
112 struct clk *clk;
113 struct list_head capture;
114
115 void __iomem *base;
116 int dma_chan;
117 unsigned int irq;
118 unsigned long mclk;
119
120 spinlock_t lock;
121};
122
123/*
124 * Videobuf operations
125 */
126static int mx1_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
127 unsigned int *size)
128{
129 struct soc_camera_device *icd = vq->priv_data;
130
131 *size = icd->sizeimage;
132
133 if (!*count)
134 *count = 32;
135
136 if (*size * *count > MAX_VIDEO_MEM * 1024 * 1024)
137 *count = (MAX_VIDEO_MEM * 1024 * 1024) / *size;
138
139 dev_dbg(icd->parent, "count=%d, size=%d\n", *count, *size);
140
141 return 0;
142}
143
144static void free_buffer(struct videobuf_queue *vq, struct mx1_buffer *buf)
145{
146 struct soc_camera_device *icd = vq->priv_data;
147 struct videobuf_buffer *vb = &buf->vb;
148
149 BUG_ON(in_interrupt());
150
151 dev_dbg(icd->parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
152 vb, vb->baddr, vb->bsize);
153
154 /*
155 * This waits until this buffer is out of danger, i.e., until it is no
156 * longer in STATE_QUEUED or STATE_ACTIVE
157 */
158 videobuf_waiton(vq, vb, 0, 0);
159 videobuf_dma_contig_free(vq, vb);
160
161 vb->state = VIDEOBUF_NEEDS_INIT;
162}
163
164static int mx1_videobuf_prepare(struct videobuf_queue *vq,
165 struct videobuf_buffer *vb, enum v4l2_field field)
166{
167 struct soc_camera_device *icd = vq->priv_data;
168 struct mx1_buffer *buf = container_of(vb, struct mx1_buffer, vb);
169 int ret;
170
171 dev_dbg(icd->parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
172 vb, vb->baddr, vb->bsize);
173
174 /* Added list head initialization on alloc */
175 WARN_ON(!list_empty(&vb->queue));
176
177 BUG_ON(NULL == icd->current_fmt);
178
179 /*
180 * I think, in buf_prepare you only have to protect global data,
181 * the actual buffer is yours
182 */
183 buf->inwork = 1;
184
185 if (buf->code != icd->current_fmt->code ||
186 vb->width != icd->user_width ||
187 vb->height != icd->user_height ||
188 vb->field != field) {
189 buf->code = icd->current_fmt->code;
190 vb->width = icd->user_width;
191 vb->height = icd->user_height;
192 vb->field = field;
193 vb->state = VIDEOBUF_NEEDS_INIT;
194 }
195
196 vb->size = icd->sizeimage;
197 if (0 != vb->baddr && vb->bsize < vb->size) {
198 ret = -EINVAL;
199 goto out;
200 }
201
202 if (vb->state == VIDEOBUF_NEEDS_INIT) {
203 ret = videobuf_iolock(vq, vb, NULL);
204 if (ret)
205 goto fail;
206
207 vb->state = VIDEOBUF_PREPARED;
208 }
209
210 buf->inwork = 0;
211
212 return 0;
213
214fail:
215 free_buffer(vq, buf);
216out:
217 buf->inwork = 0;
218 return ret;
219}
220
221static int mx1_camera_setup_dma(struct mx1_camera_dev *pcdev)
222{
223 struct videobuf_buffer *vbuf = &pcdev->active->vb;
224 struct device *dev = pcdev->icd->parent;
225 int ret;
226
227 if (unlikely(!pcdev->active)) {
228 dev_err(dev, "DMA End IRQ with no active buffer\n");
229 return -EFAULT;
230 }
231
232 /* setup sg list for future DMA */
233 ret = imx_dma_setup_single(pcdev->dma_chan,
234 videobuf_to_dma_contig(vbuf),
235 vbuf->size, pcdev->res->start +
236 CSIRXR, DMA_MODE_READ);
237 if (unlikely(ret))
238 dev_err(dev, "Failed to setup DMA sg list\n");
239
240 return ret;
241}
242
243/* Called under spinlock_irqsave(&pcdev->lock, ...) */
244static void mx1_videobuf_queue(struct videobuf_queue *vq,
245 struct videobuf_buffer *vb)
246{
247 struct soc_camera_device *icd = vq->priv_data;
248 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
249 struct mx1_camera_dev *pcdev = ici->priv;
250 struct mx1_buffer *buf = container_of(vb, struct mx1_buffer, vb);
251
252 dev_dbg(icd->parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
253 vb, vb->baddr, vb->bsize);
254
255 list_add_tail(&vb->queue, &pcdev->capture);
256
257 vb->state = VIDEOBUF_ACTIVE;
258
259 if (!pcdev->active) {
260 pcdev->active = buf;
261
262 /* setup sg list for future DMA */
263 if (!mx1_camera_setup_dma(pcdev)) {
264 unsigned int temp;
265 /* enable SOF irq */
266 temp = __raw_readl(pcdev->base + CSICR1) |
267 CSICR1_SOF_INTEN;
268 __raw_writel(temp, pcdev->base + CSICR1);
269 }
270 }
271}
272
273static void mx1_videobuf_release(struct videobuf_queue *vq,
274 struct videobuf_buffer *vb)
275{
276 struct mx1_buffer *buf = container_of(vb, struct mx1_buffer, vb);
277#ifdef DEBUG
278 struct soc_camera_device *icd = vq->priv_data;
279 struct device *dev = icd->parent;
280
281 dev_dbg(dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
282 vb, vb->baddr, vb->bsize);
283
284 switch (vb->state) {
285 case VIDEOBUF_ACTIVE:
286 dev_dbg(dev, "%s (active)\n", __func__);
287 break;
288 case VIDEOBUF_QUEUED:
289 dev_dbg(dev, "%s (queued)\n", __func__);
290 break;
291 case VIDEOBUF_PREPARED:
292 dev_dbg(dev, "%s (prepared)\n", __func__);
293 break;
294 default:
295 dev_dbg(dev, "%s (unknown)\n", __func__);
296 break;
297 }
298#endif
299
300 free_buffer(vq, buf);
301}
302
303static void mx1_camera_wakeup(struct mx1_camera_dev *pcdev,
304 struct videobuf_buffer *vb,
305 struct mx1_buffer *buf)
306{
307 /* _init is used to debug races, see comment in mx1_camera_reqbufs() */
308 list_del_init(&vb->queue);
309 vb->state = VIDEOBUF_DONE;
310 do_gettimeofday(&vb->ts);
311 vb->field_count++;
312 wake_up(&vb->done);
313
314 if (list_empty(&pcdev->capture)) {
315 pcdev->active = NULL;
316 return;
317 }
318
319 pcdev->active = list_entry(pcdev->capture.next,
320 struct mx1_buffer, vb.queue);
321
322 /* setup sg list for future DMA */
323 if (likely(!mx1_camera_setup_dma(pcdev))) {
324 unsigned int temp;
325
326 /* enable SOF irq */
327 temp = __raw_readl(pcdev->base + CSICR1) | CSICR1_SOF_INTEN;
328 __raw_writel(temp, pcdev->base + CSICR1);
329 }
330}
331
332static void mx1_camera_dma_irq(int channel, void *data)
333{
334 struct mx1_camera_dev *pcdev = data;
335 struct device *dev = pcdev->icd->parent;
336 struct mx1_buffer *buf;
337 struct videobuf_buffer *vb;
338 unsigned long flags;
339
340 spin_lock_irqsave(&pcdev->lock, flags);
341
342 imx_dma_disable(channel);
343
344 if (unlikely(!pcdev->active)) {
345 dev_err(dev, "DMA End IRQ with no active buffer\n");
346 goto out;
347 }
348
349 vb = &pcdev->active->vb;
350 buf = container_of(vb, struct mx1_buffer, vb);
351 WARN_ON(buf->inwork || list_empty(&vb->queue));
352 dev_dbg(dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
353 vb, vb->baddr, vb->bsize);
354
355 mx1_camera_wakeup(pcdev, vb, buf);
356out:
357 spin_unlock_irqrestore(&pcdev->lock, flags);
358}
359
360static struct videobuf_queue_ops mx1_videobuf_ops = {
361 .buf_setup = mx1_videobuf_setup,
362 .buf_prepare = mx1_videobuf_prepare,
363 .buf_queue = mx1_videobuf_queue,
364 .buf_release = mx1_videobuf_release,
365};
366
367static void mx1_camera_init_videobuf(struct videobuf_queue *q,
368 struct soc_camera_device *icd)
369{
370 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
371 struct mx1_camera_dev *pcdev = ici->priv;
372
373 videobuf_queue_dma_contig_init(q, &mx1_videobuf_ops, icd->parent,
374 &pcdev->lock, V4L2_BUF_TYPE_VIDEO_CAPTURE,
375 V4L2_FIELD_NONE,
376 sizeof(struct mx1_buffer), icd, &icd->video_lock);
377}
378
379static int mclk_get_divisor(struct mx1_camera_dev *pcdev)
380{
381 unsigned int mclk = pcdev->mclk;
382 unsigned long div;
383 unsigned long lcdclk;
384
385 lcdclk = clk_get_rate(pcdev->clk);
386
387 /*
388 * We verify platform_mclk_10khz != 0, so if anyone breaks it, here
389 * they get a nice Oops
390 */
391 div = (lcdclk + 2 * mclk - 1) / (2 * mclk) - 1;
392
393 dev_dbg(pcdev->icd->parent,
394 "System clock %lukHz, target freq %dkHz, divisor %lu\n",
395 lcdclk / 1000, mclk / 1000, div);
396
397 return div;
398}
399
400static void mx1_camera_activate(struct mx1_camera_dev *pcdev)
401{
402 unsigned int csicr1 = CSICR1_EN;
403
404 dev_dbg(pcdev->icd->parent, "Activate device\n");
405
406 clk_enable(pcdev->clk);
407
408 /* enable CSI before doing anything else */
409 __raw_writel(csicr1, pcdev->base + CSICR1);
410
411 csicr1 |= CSICR1_MCLKEN | CSICR1_FCC | CSICR1_GCLK_MODE;
412 csicr1 |= CSICR1_MCLKDIV(mclk_get_divisor(pcdev));
413 csicr1 |= CSICR1_RXFF_LEVEL(2); /* 16 words */
414
415 __raw_writel(csicr1, pcdev->base + CSICR1);
416}
417
418static void mx1_camera_deactivate(struct mx1_camera_dev *pcdev)
419{
420 dev_dbg(pcdev->icd->parent, "Deactivate device\n");
421
422 /* Disable all CSI interface */
423 __raw_writel(0x00, pcdev->base + CSICR1);
424
425 clk_disable(pcdev->clk);
426}
427
428/*
429 * The following two functions absolutely depend on the fact, that
430 * there can be only one camera on i.MX1/i.MXL camera sensor interface
431 */
432static int mx1_camera_add_device(struct soc_camera_device *icd)
433{
434 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
435 struct mx1_camera_dev *pcdev = ici->priv;
436
437 if (pcdev->icd)
438 return -EBUSY;
439
440 dev_info(icd->parent, "MX1 Camera driver attached to camera %d\n",
441 icd->devnum);
442
443 mx1_camera_activate(pcdev);
444
445 pcdev->icd = icd;
446
447 return 0;
448}
449
450static void mx1_camera_remove_device(struct soc_camera_device *icd)
451{
452 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
453 struct mx1_camera_dev *pcdev = ici->priv;
454 unsigned int csicr1;
455
456 BUG_ON(icd != pcdev->icd);
457
458 /* disable interrupts */
459 csicr1 = __raw_readl(pcdev->base + CSICR1) & ~CSI_IRQ_MASK;
460 __raw_writel(csicr1, pcdev->base + CSICR1);
461
462 /* Stop DMA engine */
463 imx_dma_disable(pcdev->dma_chan);
464
465 dev_info(icd->parent, "MX1 Camera driver detached from camera %d\n",
466 icd->devnum);
467
468 mx1_camera_deactivate(pcdev);
469
470 pcdev->icd = NULL;
471}
472
473static int mx1_camera_set_crop(struct soc_camera_device *icd,
474 struct v4l2_crop *a)
475{
476 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
477
478 return v4l2_subdev_call(sd, video, s_crop, a);
479}
480
481static int mx1_camera_set_bus_param(struct soc_camera_device *icd)
482{
483 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
484 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
485 struct mx1_camera_dev *pcdev = ici->priv;
486 struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
487 unsigned long common_flags;
488 unsigned int csicr1;
489 int ret;
490
491 /* MX1 supports only 8bit buswidth */
492 ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
493 if (!ret) {
494 common_flags = soc_mbus_config_compatible(&cfg, CSI_BUS_FLAGS);
495 if (!common_flags) {
496 dev_warn(icd->parent,
497 "Flags incompatible: camera 0x%x, host 0x%x\n",
498 cfg.flags, CSI_BUS_FLAGS);
499 return -EINVAL;
500 }
501 } else if (ret != -ENOIOCTLCMD) {
502 return ret;
503 } else {
504 common_flags = CSI_BUS_FLAGS;
505 }
506
507 /* Make choises, based on platform choice */
508 if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) &&
509 (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) {
510 if (!pcdev->pdata ||
511 pcdev->pdata->flags & MX1_CAMERA_VSYNC_HIGH)
512 common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW;
513 else
514 common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH;
515 }
516
517 if ((common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) &&
518 (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)) {
519 if (!pcdev->pdata ||
520 pcdev->pdata->flags & MX1_CAMERA_PCLK_RISING)
521 common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_FALLING;
522 else
523 common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_RISING;
524 }
525
526 if ((common_flags & V4L2_MBUS_DATA_ACTIVE_HIGH) &&
527 (common_flags & V4L2_MBUS_DATA_ACTIVE_LOW)) {
528 if (!pcdev->pdata ||
529 pcdev->pdata->flags & MX1_CAMERA_DATA_HIGH)
530 common_flags &= ~V4L2_MBUS_DATA_ACTIVE_LOW;
531 else
532 common_flags &= ~V4L2_MBUS_DATA_ACTIVE_HIGH;
533 }
534
535 cfg.flags = common_flags;
536 ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
537 if (ret < 0 && ret != -ENOIOCTLCMD) {
538 dev_dbg(icd->parent, "camera s_mbus_config(0x%lx) returned %d\n",
539 common_flags, ret);
540 return ret;
541 }
542
543 csicr1 = __raw_readl(pcdev->base + CSICR1);
544
545 if (common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING)
546 csicr1 |= CSICR1_REDGE;
547 if (common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH)
548 csicr1 |= CSICR1_SOF_POL;
549 if (common_flags & V4L2_MBUS_DATA_ACTIVE_LOW)
550 csicr1 |= CSICR1_DATA_POL;
551
552 __raw_writel(csicr1, pcdev->base + CSICR1);
553
554 return 0;
555}
556
557static int mx1_camera_set_fmt(struct soc_camera_device *icd,
558 struct v4l2_format *f)
559{
560 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
561 const struct soc_camera_format_xlate *xlate;
562 struct v4l2_pix_format *pix = &f->fmt.pix;
563 struct v4l2_mbus_framefmt mf;
564 int ret, buswidth;
565
566 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
567 if (!xlate) {
568 dev_warn(icd->parent, "Format %x not found\n",
569 pix->pixelformat);
570 return -EINVAL;
571 }
572
573 buswidth = xlate->host_fmt->bits_per_sample;
574 if (buswidth > 8) {
575 dev_warn(icd->parent,
576 "bits-per-sample %d for format %x unsupported\n",
577 buswidth, pix->pixelformat);
578 return -EINVAL;
579 }
580
581 mf.width = pix->width;
582 mf.height = pix->height;
583 mf.field = pix->field;
584 mf.colorspace = pix->colorspace;
585 mf.code = xlate->code;
586
587 ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
588 if (ret < 0)
589 return ret;
590
591 if (mf.code != xlate->code)
592 return -EINVAL;
593
594 pix->width = mf.width;
595 pix->height = mf.height;
596 pix->field = mf.field;
597 pix->colorspace = mf.colorspace;
598 icd->current_fmt = xlate;
599
600 return ret;
601}
602
603static int mx1_camera_try_fmt(struct soc_camera_device *icd,
604 struct v4l2_format *f)
605{
606 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
607 const struct soc_camera_format_xlate *xlate;
608 struct v4l2_pix_format *pix = &f->fmt.pix;
609 struct v4l2_mbus_framefmt mf;
610 int ret;
611 /* TODO: limit to mx1 hardware capabilities */
612
613 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
614 if (!xlate) {
615 dev_warn(icd->parent, "Format %x not found\n",
616 pix->pixelformat);
617 return -EINVAL;
618 }
619
620 mf.width = pix->width;
621 mf.height = pix->height;
622 mf.field = pix->field;
623 mf.colorspace = pix->colorspace;
624 mf.code = xlate->code;
625
626 /* limit to sensor capabilities */
627 ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
628 if (ret < 0)
629 return ret;
630
631 pix->width = mf.width;
632 pix->height = mf.height;
633 pix->field = mf.field;
634 pix->colorspace = mf.colorspace;
635
636 return 0;
637}
638
639static int mx1_camera_reqbufs(struct soc_camera_device *icd,
640 struct v4l2_requestbuffers *p)
641{
642 int i;
643
644 /*
645 * This is for locking debugging only. I removed spinlocks and now I
646 * check whether .prepare is ever called on a linked buffer, or whether
647 * a dma IRQ can occur for an in-work or unlinked buffer. Until now
648 * it hadn't triggered
649 */
650 for (i = 0; i < p->count; i++) {
651 struct mx1_buffer *buf = container_of(icd->vb_vidq.bufs[i],
652 struct mx1_buffer, vb);
653 buf->inwork = 0;
654 INIT_LIST_HEAD(&buf->vb.queue);
655 }
656
657 return 0;
658}
659
660static unsigned int mx1_camera_poll(struct file *file, poll_table *pt)
661{
662 struct soc_camera_device *icd = file->private_data;
663 struct mx1_buffer *buf;
664
665 buf = list_entry(icd->vb_vidq.stream.next, struct mx1_buffer,
666 vb.stream);
667
668 poll_wait(file, &buf->vb.done, pt);
669
670 if (buf->vb.state == VIDEOBUF_DONE ||
671 buf->vb.state == VIDEOBUF_ERROR)
672 return POLLIN | POLLRDNORM;
673
674 return 0;
675}
676
677static int mx1_camera_querycap(struct soc_camera_host *ici,
678 struct v4l2_capability *cap)
679{
680 /* cap->name is set by the friendly caller:-> */
681 strlcpy(cap->card, "i.MX1/i.MXL Camera", sizeof(cap->card));
682 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
683
684 return 0;
685}
686
687static struct soc_camera_host_ops mx1_soc_camera_host_ops = {
688 .owner = THIS_MODULE,
689 .add = mx1_camera_add_device,
690 .remove = mx1_camera_remove_device,
691 .set_bus_param = mx1_camera_set_bus_param,
692 .set_crop = mx1_camera_set_crop,
693 .set_fmt = mx1_camera_set_fmt,
694 .try_fmt = mx1_camera_try_fmt,
695 .init_videobuf = mx1_camera_init_videobuf,
696 .reqbufs = mx1_camera_reqbufs,
697 .poll = mx1_camera_poll,
698 .querycap = mx1_camera_querycap,
699};
700
701static struct fiq_handler fh = {
702 .name = "csi_sof"
703};
704
705static int __init mx1_camera_probe(struct platform_device *pdev)
706{
707 struct mx1_camera_dev *pcdev;
708 struct resource *res;
709 struct pt_regs regs;
710 struct clk *clk;
711 void __iomem *base;
712 unsigned int irq;
713 int err = 0;
714
715 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
716 irq = platform_get_irq(pdev, 0);
717 if (!res || (int)irq <= 0) {
718 err = -ENODEV;
719 goto exit;
720 }
721
722 clk = clk_get(&pdev->dev, "csi_clk");
723 if (IS_ERR(clk)) {
724 err = PTR_ERR(clk);
725 goto exit;
726 }
727
728 pcdev = kzalloc(sizeof(*pcdev), GFP_KERNEL);
729 if (!pcdev) {
730 dev_err(&pdev->dev, "Could not allocate pcdev\n");
731 err = -ENOMEM;
732 goto exit_put_clk;
733 }
734
735 pcdev->res = res;
736 pcdev->clk = clk;
737
738 pcdev->pdata = pdev->dev.platform_data;
739
740 if (pcdev->pdata)
741 pcdev->mclk = pcdev->pdata->mclk_10khz * 10000;
742
743 if (!pcdev->mclk) {
744 dev_warn(&pdev->dev,
745 "mclk_10khz == 0! Please, fix your platform data. "
746 "Using default 20MHz\n");
747 pcdev->mclk = 20000000;
748 }
749
750 INIT_LIST_HEAD(&pcdev->capture);
751 spin_lock_init(&pcdev->lock);
752
753 /*
754 * Request the regions.
755 */
756 if (!request_mem_region(res->start, resource_size(res), DRIVER_NAME)) {
757 err = -EBUSY;
758 goto exit_kfree;
759 }
760
761 base = ioremap(res->start, resource_size(res));
762 if (!base) {
763 err = -ENOMEM;
764 goto exit_release;
765 }
766 pcdev->irq = irq;
767 pcdev->base = base;
768
769 /* request dma */
770 pcdev->dma_chan = imx_dma_request_by_prio(DRIVER_NAME, DMA_PRIO_HIGH);
771 if (pcdev->dma_chan < 0) {
772 dev_err(&pdev->dev, "Can't request DMA for MX1 CSI\n");
773 err = -EBUSY;
774 goto exit_iounmap;
775 }
776 dev_dbg(&pdev->dev, "got DMA channel %d\n", pcdev->dma_chan);
777
778 imx_dma_setup_handlers(pcdev->dma_chan, mx1_camera_dma_irq, NULL,
779 pcdev);
780
781 imx_dma_config_channel(pcdev->dma_chan, IMX_DMA_TYPE_FIFO,
782 IMX_DMA_MEMSIZE_32, MX1_DMA_REQ_CSI_R, 0);
783 /* burst length : 16 words = 64 bytes */
784 imx_dma_config_burstlen(pcdev->dma_chan, 0);
785
786 /* request irq */
787 err = claim_fiq(&fh);
788 if (err) {
789 dev_err(&pdev->dev, "Camera interrupt register failed \n");
790 goto exit_free_dma;
791 }
792
793 set_fiq_handler(&mx1_camera_sof_fiq_start, &mx1_camera_sof_fiq_end -
794 &mx1_camera_sof_fiq_start);
795
796 regs.ARM_r8 = (long)MX1_DMA_DIMR;
797 regs.ARM_r9 = (long)MX1_DMA_CCR(pcdev->dma_chan);
798 regs.ARM_r10 = (long)pcdev->base + CSICR1;
799 regs.ARM_fp = (long)pcdev->base + CSISR;
800 regs.ARM_sp = 1 << pcdev->dma_chan;
801 set_fiq_regs(&regs);
802
803 mxc_set_irq_fiq(irq, 1);
804 enable_fiq(irq);
805
806 pcdev->soc_host.drv_name = DRIVER_NAME;
807 pcdev->soc_host.ops = &mx1_soc_camera_host_ops;
808 pcdev->soc_host.priv = pcdev;
809 pcdev->soc_host.v4l2_dev.dev = &pdev->dev;
810 pcdev->soc_host.nr = pdev->id;
811 err = soc_camera_host_register(&pcdev->soc_host);
812 if (err)
813 goto exit_free_irq;
814
815 dev_info(&pdev->dev, "MX1 Camera driver loaded\n");
816
817 return 0;
818
819exit_free_irq:
820 disable_fiq(irq);
821 mxc_set_irq_fiq(irq, 0);
822 release_fiq(&fh);
823exit_free_dma:
824 imx_dma_free(pcdev->dma_chan);
825exit_iounmap:
826 iounmap(base);
827exit_release:
828 release_mem_region(res->start, resource_size(res));
829exit_kfree:
830 kfree(pcdev);
831exit_put_clk:
832 clk_put(clk);
833exit:
834 return err;
835}
836
837static int __exit mx1_camera_remove(struct platform_device *pdev)
838{
839 struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev);
840 struct mx1_camera_dev *pcdev = container_of(soc_host,
841 struct mx1_camera_dev, soc_host);
842 struct resource *res;
843
844 imx_dma_free(pcdev->dma_chan);
845 disable_fiq(pcdev->irq);
846 mxc_set_irq_fiq(pcdev->irq, 0);
847 release_fiq(&fh);
848
849 clk_put(pcdev->clk);
850
851 soc_camera_host_unregister(soc_host);
852
853 iounmap(pcdev->base);
854
855 res = pcdev->res;
856 release_mem_region(res->start, resource_size(res));
857
858 kfree(pcdev);
859
860 dev_info(&pdev->dev, "MX1 Camera driver unloaded\n");
861
862 return 0;
863}
864
865static struct platform_driver mx1_camera_driver = {
866 .driver = {
867 .name = DRIVER_NAME,
868 },
869 .remove = __exit_p(mx1_camera_remove),
870};
871
872static int __init mx1_camera_init(void)
873{
874 return platform_driver_probe(&mx1_camera_driver, mx1_camera_probe);
875}
876
877static void __exit mx1_camera_exit(void)
878{
879 return platform_driver_unregister(&mx1_camera_driver);
880}
881
882module_init(mx1_camera_init);
883module_exit(mx1_camera_exit);
884
885MODULE_DESCRIPTION("i.MX1/i.MXL SoC Camera Host driver");
886MODULE_AUTHOR("Paulius Zaleckas <paulius.zaleckas@teltonika.lt>");
887MODULE_LICENSE("GPL v2");
888MODULE_VERSION(DRIVER_VERSION);
889MODULE_ALIAS("platform:" DRIVER_NAME);
diff --git a/drivers/media/video/mx2_camera.c b/drivers/media/video/mx2_camera.c
deleted file mode 100644
index 637bde8aca28..000000000000
--- a/drivers/media/video/mx2_camera.c
+++ /dev/null
@@ -1,1869 +0,0 @@
1/*
2 * V4L2 Driver for i.MX27/i.MX25 camera host
3 *
4 * Copyright (C) 2008, Sascha Hauer, Pengutronix
5 * Copyright (C) 2010, Baruch Siach, Orex Computed Radiography
6 * Copyright (C) 2012, Javier Martin, Vista Silicon S.L.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 */
13
14#include <linux/init.h>
15#include <linux/module.h>
16#include <linux/io.h>
17#include <linux/delay.h>
18#include <linux/slab.h>
19#include <linux/dma-mapping.h>
20#include <linux/errno.h>
21#include <linux/fs.h>
22#include <linux/gcd.h>
23#include <linux/interrupt.h>
24#include <linux/kernel.h>
25#include <linux/math64.h>
26#include <linux/mm.h>
27#include <linux/moduleparam.h>
28#include <linux/time.h>
29#include <linux/device.h>
30#include <linux/platform_device.h>
31#include <linux/mutex.h>
32#include <linux/clk.h>
33
34#include <media/v4l2-common.h>
35#include <media/v4l2-dev.h>
36#include <media/videobuf2-core.h>
37#include <media/videobuf2-dma-contig.h>
38#include <media/soc_camera.h>
39#include <media/soc_mediabus.h>
40
41#include <linux/videodev2.h>
42
43#include <mach/mx2_cam.h>
44#include <mach/hardware.h>
45
46#include <asm/dma.h>
47
48#define MX2_CAM_DRV_NAME "mx2-camera"
49#define MX2_CAM_VERSION "0.0.6"
50#define MX2_CAM_DRIVER_DESCRIPTION "i.MX2x_Camera"
51
52/* reset values */
53#define CSICR1_RESET_VAL 0x40000800
54#define CSICR2_RESET_VAL 0x0
55#define CSICR3_RESET_VAL 0x0
56
57/* csi control reg 1 */
58#define CSICR1_SWAP16_EN (1 << 31)
59#define CSICR1_EXT_VSYNC (1 << 30)
60#define CSICR1_EOF_INTEN (1 << 29)
61#define CSICR1_PRP_IF_EN (1 << 28)
62#define CSICR1_CCIR_MODE (1 << 27)
63#define CSICR1_COF_INTEN (1 << 26)
64#define CSICR1_SF_OR_INTEN (1 << 25)
65#define CSICR1_RF_OR_INTEN (1 << 24)
66#define CSICR1_STATFF_LEVEL (3 << 22)
67#define CSICR1_STATFF_INTEN (1 << 21)
68#define CSICR1_RXFF_LEVEL(l) (((l) & 3) << 19) /* MX27 */
69#define CSICR1_FB2_DMA_INTEN (1 << 20) /* MX25 */
70#define CSICR1_FB1_DMA_INTEN (1 << 19) /* MX25 */
71#define CSICR1_RXFF_INTEN (1 << 18)
72#define CSICR1_SOF_POL (1 << 17)
73#define CSICR1_SOF_INTEN (1 << 16)
74#define CSICR1_MCLKDIV(d) (((d) & 0xF) << 12)
75#define CSICR1_HSYNC_POL (1 << 11)
76#define CSICR1_CCIR_EN (1 << 10)
77#define CSICR1_MCLKEN (1 << 9)
78#define CSICR1_FCC (1 << 8)
79#define CSICR1_PACK_DIR (1 << 7)
80#define CSICR1_CLR_STATFIFO (1 << 6)
81#define CSICR1_CLR_RXFIFO (1 << 5)
82#define CSICR1_GCLK_MODE (1 << 4)
83#define CSICR1_INV_DATA (1 << 3)
84#define CSICR1_INV_PCLK (1 << 2)
85#define CSICR1_REDGE (1 << 1)
86#define CSICR1_FMT_MASK (CSICR1_PACK_DIR | CSICR1_SWAP16_EN)
87
88#define SHIFT_STATFF_LEVEL 22
89#define SHIFT_RXFF_LEVEL 19
90#define SHIFT_MCLKDIV 12
91
92/* control reg 3 */
93#define CSICR3_FRMCNT (0xFFFF << 16)
94#define CSICR3_FRMCNT_RST (1 << 15)
95#define CSICR3_DMA_REFLASH_RFF (1 << 14)
96#define CSICR3_DMA_REFLASH_SFF (1 << 13)
97#define CSICR3_DMA_REQ_EN_RFF (1 << 12)
98#define CSICR3_DMA_REQ_EN_SFF (1 << 11)
99#define CSICR3_RXFF_LEVEL(l) (((l) & 7) << 4) /* MX25 */
100#define CSICR3_CSI_SUP (1 << 3)
101#define CSICR3_ZERO_PACK_EN (1 << 2)
102#define CSICR3_ECC_INT_EN (1 << 1)
103#define CSICR3_ECC_AUTO_EN (1 << 0)
104
105#define SHIFT_FRMCNT 16
106
107/* csi status reg */
108#define CSISR_SFF_OR_INT (1 << 25)
109#define CSISR_RFF_OR_INT (1 << 24)
110#define CSISR_STATFF_INT (1 << 21)
111#define CSISR_DMA_TSF_FB2_INT (1 << 20) /* MX25 */
112#define CSISR_DMA_TSF_FB1_INT (1 << 19) /* MX25 */
113#define CSISR_RXFF_INT (1 << 18)
114#define CSISR_EOF_INT (1 << 17)
115#define CSISR_SOF_INT (1 << 16)
116#define CSISR_F2_INT (1 << 15)
117#define CSISR_F1_INT (1 << 14)
118#define CSISR_COF_INT (1 << 13)
119#define CSISR_ECC_INT (1 << 1)
120#define CSISR_DRDY (1 << 0)
121
122#define CSICR1 0x00
123#define CSICR2 0x04
124#define CSISR (cpu_is_mx27() ? 0x08 : 0x18)
125#define CSISTATFIFO 0x0c
126#define CSIRFIFO 0x10
127#define CSIRXCNT 0x14
128#define CSICR3 (cpu_is_mx27() ? 0x1C : 0x08)
129#define CSIDMASA_STATFIFO 0x20
130#define CSIDMATA_STATFIFO 0x24
131#define CSIDMASA_FB1 0x28
132#define CSIDMASA_FB2 0x2c
133#define CSIFBUF_PARA 0x30
134#define CSIIMAG_PARA 0x34
135
136/* EMMA PrP */
137#define PRP_CNTL 0x00
138#define PRP_INTR_CNTL 0x04
139#define PRP_INTRSTATUS 0x08
140#define PRP_SOURCE_Y_PTR 0x0c
141#define PRP_SOURCE_CB_PTR 0x10
142#define PRP_SOURCE_CR_PTR 0x14
143#define PRP_DEST_RGB1_PTR 0x18
144#define PRP_DEST_RGB2_PTR 0x1c
145#define PRP_DEST_Y_PTR 0x20
146#define PRP_DEST_CB_PTR 0x24
147#define PRP_DEST_CR_PTR 0x28
148#define PRP_SRC_FRAME_SIZE 0x2c
149#define PRP_DEST_CH1_LINE_STRIDE 0x30
150#define PRP_SRC_PIXEL_FORMAT_CNTL 0x34
151#define PRP_CH1_PIXEL_FORMAT_CNTL 0x38
152#define PRP_CH1_OUT_IMAGE_SIZE 0x3c
153#define PRP_CH2_OUT_IMAGE_SIZE 0x40
154#define PRP_SRC_LINE_STRIDE 0x44
155#define PRP_CSC_COEF_012 0x48
156#define PRP_CSC_COEF_345 0x4c
157#define PRP_CSC_COEF_678 0x50
158#define PRP_CH1_RZ_HORI_COEF1 0x54
159#define PRP_CH1_RZ_HORI_COEF2 0x58
160#define PRP_CH1_RZ_HORI_VALID 0x5c
161#define PRP_CH1_RZ_VERT_COEF1 0x60
162#define PRP_CH1_RZ_VERT_COEF2 0x64
163#define PRP_CH1_RZ_VERT_VALID 0x68
164#define PRP_CH2_RZ_HORI_COEF1 0x6c
165#define PRP_CH2_RZ_HORI_COEF2 0x70
166#define PRP_CH2_RZ_HORI_VALID 0x74
167#define PRP_CH2_RZ_VERT_COEF1 0x78
168#define PRP_CH2_RZ_VERT_COEF2 0x7c
169#define PRP_CH2_RZ_VERT_VALID 0x80
170
171#define PRP_CNTL_CH1EN (1 << 0)
172#define PRP_CNTL_CH2EN (1 << 1)
173#define PRP_CNTL_CSIEN (1 << 2)
174#define PRP_CNTL_DATA_IN_YUV420 (0 << 3)
175#define PRP_CNTL_DATA_IN_YUV422 (1 << 3)
176#define PRP_CNTL_DATA_IN_RGB16 (2 << 3)
177#define PRP_CNTL_DATA_IN_RGB32 (3 << 3)
178#define PRP_CNTL_CH1_OUT_RGB8 (0 << 5)
179#define PRP_CNTL_CH1_OUT_RGB16 (1 << 5)
180#define PRP_CNTL_CH1_OUT_RGB32 (2 << 5)
181#define PRP_CNTL_CH1_OUT_YUV422 (3 << 5)
182#define PRP_CNTL_CH2_OUT_YUV420 (0 << 7)
183#define PRP_CNTL_CH2_OUT_YUV422 (1 << 7)
184#define PRP_CNTL_CH2_OUT_YUV444 (2 << 7)
185#define PRP_CNTL_CH1_LEN (1 << 9)
186#define PRP_CNTL_CH2_LEN (1 << 10)
187#define PRP_CNTL_SKIP_FRAME (1 << 11)
188#define PRP_CNTL_SWRST (1 << 12)
189#define PRP_CNTL_CLKEN (1 << 13)
190#define PRP_CNTL_WEN (1 << 14)
191#define PRP_CNTL_CH1BYP (1 << 15)
192#define PRP_CNTL_IN_TSKIP(x) ((x) << 16)
193#define PRP_CNTL_CH1_TSKIP(x) ((x) << 19)
194#define PRP_CNTL_CH2_TSKIP(x) ((x) << 22)
195#define PRP_CNTL_INPUT_FIFO_LEVEL(x) ((x) << 25)
196#define PRP_CNTL_RZ_FIFO_LEVEL(x) ((x) << 27)
197#define PRP_CNTL_CH2B1EN (1 << 29)
198#define PRP_CNTL_CH2B2EN (1 << 30)
199#define PRP_CNTL_CH2FEN (1 << 31)
200
201/* IRQ Enable and status register */
202#define PRP_INTR_RDERR (1 << 0)
203#define PRP_INTR_CH1WERR (1 << 1)
204#define PRP_INTR_CH2WERR (1 << 2)
205#define PRP_INTR_CH1FC (1 << 3)
206#define PRP_INTR_CH2FC (1 << 5)
207#define PRP_INTR_LBOVF (1 << 7)
208#define PRP_INTR_CH2OVF (1 << 8)
209
210/* Resizing registers */
211#define PRP_RZ_VALID_TBL_LEN(x) ((x) << 24)
212#define PRP_RZ_VALID_BILINEAR (1 << 31)
213
214#define MAX_VIDEO_MEM 16
215
216#define RESIZE_NUM_MIN 1
217#define RESIZE_NUM_MAX 20
218#define BC_COEF 3
219#define SZ_COEF (1 << BC_COEF)
220
221#define RESIZE_DIR_H 0
222#define RESIZE_DIR_V 1
223
224#define RESIZE_ALGO_BILINEAR 0
225#define RESIZE_ALGO_AVERAGING 1
226
227struct mx2_prp_cfg {
228 int channel;
229 u32 in_fmt;
230 u32 out_fmt;
231 u32 src_pixel;
232 u32 ch1_pixel;
233 u32 irq_flags;
234 u32 csicr1;
235};
236
237/* prp resizing parameters */
238struct emma_prp_resize {
239 int algo; /* type of algorithm used */
240 int len; /* number of coefficients */
241 unsigned char s[RESIZE_NUM_MAX]; /* table of coefficients */
242};
243
244/* prp configuration for a client-host fmt pair */
245struct mx2_fmt_cfg {
246 enum v4l2_mbus_pixelcode in_fmt;
247 u32 out_fmt;
248 struct mx2_prp_cfg cfg;
249};
250
251enum mx2_buffer_state {
252 MX2_STATE_QUEUED,
253 MX2_STATE_ACTIVE,
254 MX2_STATE_DONE,
255};
256
257struct mx2_buf_internal {
258 struct list_head queue;
259 int bufnum;
260 bool discard;
261};
262
263/* buffer for one video frame */
264struct mx2_buffer {
265 /* common v4l buffer stuff -- must be first */
266 struct vb2_buffer vb;
267 enum mx2_buffer_state state;
268 struct mx2_buf_internal internal;
269};
270
271struct mx2_camera_dev {
272 struct device *dev;
273 struct soc_camera_host soc_host;
274 struct soc_camera_device *icd;
275 struct clk *clk_csi, *clk_emma;
276
277 unsigned int irq_csi, irq_emma;
278 void __iomem *base_csi, *base_emma;
279 unsigned long base_dma;
280
281 struct mx2_camera_platform_data *pdata;
282 struct resource *res_csi, *res_emma;
283 unsigned long platform_flags;
284
285 struct list_head capture;
286 struct list_head active_bufs;
287 struct list_head discard;
288
289 spinlock_t lock;
290
291 int dma;
292 struct mx2_buffer *active;
293 struct mx2_buffer *fb1_active;
294 struct mx2_buffer *fb2_active;
295
296 u32 csicr1;
297
298 struct mx2_buf_internal buf_discard[2];
299 void *discard_buffer;
300 dma_addr_t discard_buffer_dma;
301 size_t discard_size;
302 struct mx2_fmt_cfg *emma_prp;
303 struct emma_prp_resize resizing[2];
304 unsigned int s_width, s_height;
305 u32 frame_count;
306 struct vb2_alloc_ctx *alloc_ctx;
307};
308
309static struct mx2_buffer *mx2_ibuf_to_buf(struct mx2_buf_internal *int_buf)
310{
311 return container_of(int_buf, struct mx2_buffer, internal);
312}
313
314static struct mx2_fmt_cfg mx27_emma_prp_table[] = {
315 /*
316 * This is a generic configuration which is valid for most
317 * prp input-output format combinations.
318 * We set the incomming and outgoing pixelformat to a
319 * 16 Bit wide format and adjust the bytesperline
320 * accordingly. With this configuration the inputdata
321 * will not be changed by the emma and could be any type
322 * of 16 Bit Pixelformat.
323 */
324 {
325 .in_fmt = 0,
326 .out_fmt = 0,
327 .cfg = {
328 .channel = 1,
329 .in_fmt = PRP_CNTL_DATA_IN_RGB16,
330 .out_fmt = PRP_CNTL_CH1_OUT_RGB16,
331 .src_pixel = 0x2ca00565, /* RGB565 */
332 .ch1_pixel = 0x2ca00565, /* RGB565 */
333 .irq_flags = PRP_INTR_RDERR | PRP_INTR_CH1WERR |
334 PRP_INTR_CH1FC | PRP_INTR_LBOVF,
335 .csicr1 = 0,
336 }
337 },
338 {
339 .in_fmt = V4L2_MBUS_FMT_YUYV8_2X8,
340 .out_fmt = V4L2_PIX_FMT_YUV420,
341 .cfg = {
342 .channel = 2,
343 .in_fmt = PRP_CNTL_DATA_IN_YUV422,
344 .out_fmt = PRP_CNTL_CH2_OUT_YUV420,
345 .src_pixel = 0x22000888, /* YUV422 (YUYV) */
346 .irq_flags = PRP_INTR_RDERR | PRP_INTR_CH2WERR |
347 PRP_INTR_CH2FC | PRP_INTR_LBOVF |
348 PRP_INTR_CH2OVF,
349 .csicr1 = CSICR1_PACK_DIR,
350 }
351 },
352 {
353 .in_fmt = V4L2_MBUS_FMT_UYVY8_2X8,
354 .out_fmt = V4L2_PIX_FMT_YUV420,
355 .cfg = {
356 .channel = 2,
357 .in_fmt = PRP_CNTL_DATA_IN_YUV422,
358 .out_fmt = PRP_CNTL_CH2_OUT_YUV420,
359 .src_pixel = 0x22000888, /* YUV422 (YUYV) */
360 .irq_flags = PRP_INTR_RDERR | PRP_INTR_CH2WERR |
361 PRP_INTR_CH2FC | PRP_INTR_LBOVF |
362 PRP_INTR_CH2OVF,
363 .csicr1 = CSICR1_SWAP16_EN,
364 }
365 },
366};
367
368static struct mx2_fmt_cfg *mx27_emma_prp_get_format(
369 enum v4l2_mbus_pixelcode in_fmt,
370 u32 out_fmt)
371{
372 int i;
373
374 for (i = 1; i < ARRAY_SIZE(mx27_emma_prp_table); i++)
375 if ((mx27_emma_prp_table[i].in_fmt == in_fmt) &&
376 (mx27_emma_prp_table[i].out_fmt == out_fmt)) {
377 return &mx27_emma_prp_table[i];
378 }
379 /* If no match return the most generic configuration */
380 return &mx27_emma_prp_table[0];
381};
382
383static void mx27_update_emma_buf(struct mx2_camera_dev *pcdev,
384 unsigned long phys, int bufnum)
385{
386 struct mx2_fmt_cfg *prp = pcdev->emma_prp;
387
388 if (prp->cfg.channel == 1) {
389 writel(phys, pcdev->base_emma +
390 PRP_DEST_RGB1_PTR + 4 * bufnum);
391 } else {
392 writel(phys, pcdev->base_emma +
393 PRP_DEST_Y_PTR - 0x14 * bufnum);
394 if (prp->out_fmt == V4L2_PIX_FMT_YUV420) {
395 u32 imgsize = pcdev->icd->user_height *
396 pcdev->icd->user_width;
397
398 writel(phys + imgsize, pcdev->base_emma +
399 PRP_DEST_CB_PTR - 0x14 * bufnum);
400 writel(phys + ((5 * imgsize) / 4), pcdev->base_emma +
401 PRP_DEST_CR_PTR - 0x14 * bufnum);
402 }
403 }
404}
405
406static void mx2_camera_deactivate(struct mx2_camera_dev *pcdev)
407{
408 unsigned long flags;
409
410 clk_disable(pcdev->clk_csi);
411 writel(0, pcdev->base_csi + CSICR1);
412 if (cpu_is_mx27()) {
413 writel(0, pcdev->base_emma + PRP_CNTL);
414 } else if (cpu_is_mx25()) {
415 spin_lock_irqsave(&pcdev->lock, flags);
416 pcdev->fb1_active = NULL;
417 pcdev->fb2_active = NULL;
418 writel(0, pcdev->base_csi + CSIDMASA_FB1);
419 writel(0, pcdev->base_csi + CSIDMASA_FB2);
420 spin_unlock_irqrestore(&pcdev->lock, flags);
421 }
422}
423
424/*
425 * The following two functions absolutely depend on the fact, that
426 * there can be only one camera on mx2 camera sensor interface
427 */
428static int mx2_camera_add_device(struct soc_camera_device *icd)
429{
430 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
431 struct mx2_camera_dev *pcdev = ici->priv;
432 int ret;
433 u32 csicr1;
434
435 if (pcdev->icd)
436 return -EBUSY;
437
438 ret = clk_enable(pcdev->clk_csi);
439 if (ret < 0)
440 return ret;
441
442 csicr1 = CSICR1_MCLKEN;
443
444 if (cpu_is_mx27()) {
445 csicr1 |= CSICR1_PRP_IF_EN | CSICR1_FCC |
446 CSICR1_RXFF_LEVEL(0);
447 } else if (cpu_is_mx27())
448 csicr1 |= CSICR1_SOF_INTEN | CSICR1_RXFF_LEVEL(2);
449
450 pcdev->csicr1 = csicr1;
451 writel(pcdev->csicr1, pcdev->base_csi + CSICR1);
452
453 pcdev->icd = icd;
454 pcdev->frame_count = 0;
455
456 dev_info(icd->parent, "Camera driver attached to camera %d\n",
457 icd->devnum);
458
459 return 0;
460}
461
462static void mx2_camera_remove_device(struct soc_camera_device *icd)
463{
464 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
465 struct mx2_camera_dev *pcdev = ici->priv;
466
467 BUG_ON(icd != pcdev->icd);
468
469 dev_info(icd->parent, "Camera driver detached from camera %d\n",
470 icd->devnum);
471
472 mx2_camera_deactivate(pcdev);
473
474 pcdev->icd = NULL;
475}
476
477static void mx25_camera_frame_done(struct mx2_camera_dev *pcdev, int fb,
478 int state)
479{
480 struct vb2_buffer *vb;
481 struct mx2_buffer *buf;
482 struct mx2_buffer **fb_active = fb == 1 ? &pcdev->fb1_active :
483 &pcdev->fb2_active;
484 u32 fb_reg = fb == 1 ? CSIDMASA_FB1 : CSIDMASA_FB2;
485 unsigned long flags;
486
487 spin_lock_irqsave(&pcdev->lock, flags);
488
489 if (*fb_active == NULL)
490 goto out;
491
492 vb = &(*fb_active)->vb;
493 dev_dbg(pcdev->dev, "%s (vb=0x%p) 0x%p %lu\n", __func__,
494 vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0));
495
496 do_gettimeofday(&vb->v4l2_buf.timestamp);
497 vb->v4l2_buf.sequence++;
498 vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
499
500 if (list_empty(&pcdev->capture)) {
501 buf = NULL;
502 writel(0, pcdev->base_csi + fb_reg);
503 } else {
504 buf = list_first_entry(&pcdev->capture, struct mx2_buffer,
505 internal.queue);
506 vb = &buf->vb;
507 list_del(&buf->internal.queue);
508 buf->state = MX2_STATE_ACTIVE;
509 writel(vb2_dma_contig_plane_dma_addr(vb, 0),
510 pcdev->base_csi + fb_reg);
511 }
512
513 *fb_active = buf;
514
515out:
516 spin_unlock_irqrestore(&pcdev->lock, flags);
517}
518
519static irqreturn_t mx25_camera_irq(int irq_csi, void *data)
520{
521 struct mx2_camera_dev *pcdev = data;
522 u32 status = readl(pcdev->base_csi + CSISR);
523
524 if (status & CSISR_DMA_TSF_FB1_INT)
525 mx25_camera_frame_done(pcdev, 1, MX2_STATE_DONE);
526 else if (status & CSISR_DMA_TSF_FB2_INT)
527 mx25_camera_frame_done(pcdev, 2, MX2_STATE_DONE);
528
529 /* FIXME: handle CSISR_RFF_OR_INT */
530
531 writel(status, pcdev->base_csi + CSISR);
532
533 return IRQ_HANDLED;
534}
535
536/*
537 * Videobuf operations
538 */
539static int mx2_videobuf_setup(struct vb2_queue *vq,
540 const struct v4l2_format *fmt,
541 unsigned int *count, unsigned int *num_planes,
542 unsigned int sizes[], void *alloc_ctxs[])
543{
544 struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
545 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
546 struct mx2_camera_dev *pcdev = ici->priv;
547
548 dev_dbg(icd->parent, "count=%d, size=%d\n", *count, sizes[0]);
549
550 /* TODO: support for VIDIOC_CREATE_BUFS not ready */
551 if (fmt != NULL)
552 return -ENOTTY;
553
554 alloc_ctxs[0] = pcdev->alloc_ctx;
555
556 sizes[0] = icd->sizeimage;
557
558 if (0 == *count)
559 *count = 32;
560 if (!*num_planes &&
561 sizes[0] * *count > MAX_VIDEO_MEM * 1024 * 1024)
562 *count = (MAX_VIDEO_MEM * 1024 * 1024) / sizes[0];
563
564 *num_planes = 1;
565
566 return 0;
567}
568
569static int mx2_videobuf_prepare(struct vb2_buffer *vb)
570{
571 struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
572 int ret = 0;
573
574 dev_dbg(icd->parent, "%s (vb=0x%p) 0x%p %lu\n", __func__,
575 vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0));
576
577#ifdef DEBUG
578 /*
579 * This can be useful if you want to see if we actually fill
580 * the buffer with something
581 */
582 memset((void *)vb2_plane_vaddr(vb, 0),
583 0xaa, vb2_get_plane_payload(vb, 0));
584#endif
585
586 vb2_set_plane_payload(vb, 0, icd->sizeimage);
587 if (vb2_plane_vaddr(vb, 0) &&
588 vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0)) {
589 ret = -EINVAL;
590 goto out;
591 }
592
593 return 0;
594
595out:
596 return ret;
597}
598
599static void mx2_videobuf_queue(struct vb2_buffer *vb)
600{
601 struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
602 struct soc_camera_host *ici =
603 to_soc_camera_host(icd->parent);
604 struct mx2_camera_dev *pcdev = ici->priv;
605 struct mx2_buffer *buf = container_of(vb, struct mx2_buffer, vb);
606 unsigned long flags;
607
608 dev_dbg(icd->parent, "%s (vb=0x%p) 0x%p %lu\n", __func__,
609 vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0));
610
611 spin_lock_irqsave(&pcdev->lock, flags);
612
613 buf->state = MX2_STATE_QUEUED;
614 list_add_tail(&buf->internal.queue, &pcdev->capture);
615
616 if (cpu_is_mx25()) {
617 u32 csicr3, dma_inten = 0;
618
619 if (pcdev->fb1_active == NULL) {
620 writel(vb2_dma_contig_plane_dma_addr(vb, 0),
621 pcdev->base_csi + CSIDMASA_FB1);
622 pcdev->fb1_active = buf;
623 dma_inten = CSICR1_FB1_DMA_INTEN;
624 } else if (pcdev->fb2_active == NULL) {
625 writel(vb2_dma_contig_plane_dma_addr(vb, 0),
626 pcdev->base_csi + CSIDMASA_FB2);
627 pcdev->fb2_active = buf;
628 dma_inten = CSICR1_FB2_DMA_INTEN;
629 }
630
631 if (dma_inten) {
632 list_del(&buf->internal.queue);
633 buf->state = MX2_STATE_ACTIVE;
634
635 csicr3 = readl(pcdev->base_csi + CSICR3);
636
637 /* Reflash DMA */
638 writel(csicr3 | CSICR3_DMA_REFLASH_RFF,
639 pcdev->base_csi + CSICR3);
640
641 /* clear & enable interrupts */
642 writel(dma_inten, pcdev->base_csi + CSISR);
643 pcdev->csicr1 |= dma_inten;
644 writel(pcdev->csicr1, pcdev->base_csi + CSICR1);
645
646 /* enable DMA */
647 csicr3 |= CSICR3_DMA_REQ_EN_RFF | CSICR3_RXFF_LEVEL(1);
648 writel(csicr3, pcdev->base_csi + CSICR3);
649 }
650 }
651
652 spin_unlock_irqrestore(&pcdev->lock, flags);
653}
654
655static void mx2_videobuf_release(struct vb2_buffer *vb)
656{
657 struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
658 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
659 struct mx2_camera_dev *pcdev = ici->priv;
660 struct mx2_buffer *buf = container_of(vb, struct mx2_buffer, vb);
661 unsigned long flags;
662
663#ifdef DEBUG
664 dev_dbg(icd->parent, "%s (vb=0x%p) 0x%p %lu\n", __func__,
665 vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0));
666
667 switch (buf->state) {
668 case MX2_STATE_ACTIVE:
669 dev_info(icd->parent, "%s (active)\n", __func__);
670 break;
671 case MX2_STATE_QUEUED:
672 dev_info(icd->parent, "%s (queued)\n", __func__);
673 break;
674 default:
675 dev_info(icd->parent, "%s (unknown) %d\n", __func__,
676 buf->state);
677 break;
678 }
679#endif
680
681 /*
682 * Terminate only queued but inactive buffers. Active buffers are
683 * released when they become inactive after videobuf_waiton().
684 *
685 * FIXME: implement forced termination of active buffers for mx27 and
686 * mx27 eMMA, so that the user won't get stuck in an uninterruptible
687 * state. This requires a specific handling for each of the these DMA
688 * types.
689 */
690
691 spin_lock_irqsave(&pcdev->lock, flags);
692 if (cpu_is_mx25() && buf->state == MX2_STATE_ACTIVE) {
693 if (pcdev->fb1_active == buf) {
694 pcdev->csicr1 &= ~CSICR1_FB1_DMA_INTEN;
695 writel(0, pcdev->base_csi + CSIDMASA_FB1);
696 pcdev->fb1_active = NULL;
697 } else if (pcdev->fb2_active == buf) {
698 pcdev->csicr1 &= ~CSICR1_FB2_DMA_INTEN;
699 writel(0, pcdev->base_csi + CSIDMASA_FB2);
700 pcdev->fb2_active = NULL;
701 }
702 writel(pcdev->csicr1, pcdev->base_csi + CSICR1);
703 }
704 spin_unlock_irqrestore(&pcdev->lock, flags);
705}
706
707static void mx27_camera_emma_buf_init(struct soc_camera_device *icd,
708 int bytesperline)
709{
710 struct soc_camera_host *ici =
711 to_soc_camera_host(icd->parent);
712 struct mx2_camera_dev *pcdev = ici->priv;
713 struct mx2_fmt_cfg *prp = pcdev->emma_prp;
714
715 writel((pcdev->s_width << 16) | pcdev->s_height,
716 pcdev->base_emma + PRP_SRC_FRAME_SIZE);
717 writel(prp->cfg.src_pixel,
718 pcdev->base_emma + PRP_SRC_PIXEL_FORMAT_CNTL);
719 if (prp->cfg.channel == 1) {
720 writel((icd->user_width << 16) | icd->user_height,
721 pcdev->base_emma + PRP_CH1_OUT_IMAGE_SIZE);
722 writel(bytesperline,
723 pcdev->base_emma + PRP_DEST_CH1_LINE_STRIDE);
724 writel(prp->cfg.ch1_pixel,
725 pcdev->base_emma + PRP_CH1_PIXEL_FORMAT_CNTL);
726 } else { /* channel 2 */
727 writel((icd->user_width << 16) | icd->user_height,
728 pcdev->base_emma + PRP_CH2_OUT_IMAGE_SIZE);
729 }
730
731 /* Enable interrupts */
732 writel(prp->cfg.irq_flags, pcdev->base_emma + PRP_INTR_CNTL);
733}
734
735static void mx2_prp_resize_commit(struct mx2_camera_dev *pcdev)
736{
737 int dir;
738
739 for (dir = RESIZE_DIR_H; dir <= RESIZE_DIR_V; dir++) {
740 unsigned char *s = pcdev->resizing[dir].s;
741 int len = pcdev->resizing[dir].len;
742 unsigned int coeff[2] = {0, 0};
743 unsigned int valid = 0;
744 int i;
745
746 if (len == 0)
747 continue;
748
749 for (i = RESIZE_NUM_MAX - 1; i >= 0; i--) {
750 int j;
751
752 j = i > 9 ? 1 : 0;
753 coeff[j] = (coeff[j] << BC_COEF) |
754 (s[i] & (SZ_COEF - 1));
755
756 if (i == 5 || i == 15)
757 coeff[j] <<= 1;
758
759 valid = (valid << 1) | (s[i] >> BC_COEF);
760 }
761
762 valid |= PRP_RZ_VALID_TBL_LEN(len);
763
764 if (pcdev->resizing[dir].algo == RESIZE_ALGO_BILINEAR)
765 valid |= PRP_RZ_VALID_BILINEAR;
766
767 if (pcdev->emma_prp->cfg.channel == 1) {
768 if (dir == RESIZE_DIR_H) {
769 writel(coeff[0], pcdev->base_emma +
770 PRP_CH1_RZ_HORI_COEF1);
771 writel(coeff[1], pcdev->base_emma +
772 PRP_CH1_RZ_HORI_COEF2);
773 writel(valid, pcdev->base_emma +
774 PRP_CH1_RZ_HORI_VALID);
775 } else {
776 writel(coeff[0], pcdev->base_emma +
777 PRP_CH1_RZ_VERT_COEF1);
778 writel(coeff[1], pcdev->base_emma +
779 PRP_CH1_RZ_VERT_COEF2);
780 writel(valid, pcdev->base_emma +
781 PRP_CH1_RZ_VERT_VALID);
782 }
783 } else {
784 if (dir == RESIZE_DIR_H) {
785 writel(coeff[0], pcdev->base_emma +
786 PRP_CH2_RZ_HORI_COEF1);
787 writel(coeff[1], pcdev->base_emma +
788 PRP_CH2_RZ_HORI_COEF2);
789 writel(valid, pcdev->base_emma +
790 PRP_CH2_RZ_HORI_VALID);
791 } else {
792 writel(coeff[0], pcdev->base_emma +
793 PRP_CH2_RZ_VERT_COEF1);
794 writel(coeff[1], pcdev->base_emma +
795 PRP_CH2_RZ_VERT_COEF2);
796 writel(valid, pcdev->base_emma +
797 PRP_CH2_RZ_VERT_VALID);
798 }
799 }
800 }
801}
802
803static int mx2_start_streaming(struct vb2_queue *q, unsigned int count)
804{
805 struct soc_camera_device *icd = soc_camera_from_vb2q(q);
806 struct soc_camera_host *ici =
807 to_soc_camera_host(icd->parent);
808 struct mx2_camera_dev *pcdev = ici->priv;
809 struct mx2_fmt_cfg *prp = pcdev->emma_prp;
810 struct vb2_buffer *vb;
811 struct mx2_buffer *buf;
812 unsigned long phys;
813 int bytesperline;
814
815 if (cpu_is_mx27()) {
816 unsigned long flags;
817 if (count < 2)
818 return -EINVAL;
819
820 spin_lock_irqsave(&pcdev->lock, flags);
821
822 buf = list_first_entry(&pcdev->capture, struct mx2_buffer,
823 internal.queue);
824 buf->internal.bufnum = 0;
825 vb = &buf->vb;
826 buf->state = MX2_STATE_ACTIVE;
827
828 phys = vb2_dma_contig_plane_dma_addr(vb, 0);
829 mx27_update_emma_buf(pcdev, phys, buf->internal.bufnum);
830 list_move_tail(pcdev->capture.next, &pcdev->active_bufs);
831
832 buf = list_first_entry(&pcdev->capture, struct mx2_buffer,
833 internal.queue);
834 buf->internal.bufnum = 1;
835 vb = &buf->vb;
836 buf->state = MX2_STATE_ACTIVE;
837
838 phys = vb2_dma_contig_plane_dma_addr(vb, 0);
839 mx27_update_emma_buf(pcdev, phys, buf->internal.bufnum);
840 list_move_tail(pcdev->capture.next, &pcdev->active_bufs);
841
842 bytesperline = soc_mbus_bytes_per_line(icd->user_width,
843 icd->current_fmt->host_fmt);
844 if (bytesperline < 0)
845 return bytesperline;
846
847 /*
848 * I didn't manage to properly enable/disable the prp
849 * on a per frame basis during running transfers,
850 * thus we allocate a buffer here and use it to
851 * discard frames when no buffer is available.
852 * Feel free to work on this ;)
853 */
854 pcdev->discard_size = icd->user_height * bytesperline;
855 pcdev->discard_buffer = dma_alloc_coherent(ici->v4l2_dev.dev,
856 pcdev->discard_size, &pcdev->discard_buffer_dma,
857 GFP_KERNEL);
858 if (!pcdev->discard_buffer)
859 return -ENOMEM;
860
861 pcdev->buf_discard[0].discard = true;
862 list_add_tail(&pcdev->buf_discard[0].queue,
863 &pcdev->discard);
864
865 pcdev->buf_discard[1].discard = true;
866 list_add_tail(&pcdev->buf_discard[1].queue,
867 &pcdev->discard);
868
869 mx2_prp_resize_commit(pcdev);
870
871 mx27_camera_emma_buf_init(icd, bytesperline);
872
873 if (prp->cfg.channel == 1) {
874 writel(PRP_CNTL_CH1EN |
875 PRP_CNTL_CSIEN |
876 prp->cfg.in_fmt |
877 prp->cfg.out_fmt |
878 PRP_CNTL_CH1_LEN |
879 PRP_CNTL_CH1BYP |
880 PRP_CNTL_CH1_TSKIP(0) |
881 PRP_CNTL_IN_TSKIP(0),
882 pcdev->base_emma + PRP_CNTL);
883 } else {
884 writel(PRP_CNTL_CH2EN |
885 PRP_CNTL_CSIEN |
886 prp->cfg.in_fmt |
887 prp->cfg.out_fmt |
888 PRP_CNTL_CH2_LEN |
889 PRP_CNTL_CH2_TSKIP(0) |
890 PRP_CNTL_IN_TSKIP(0),
891 pcdev->base_emma + PRP_CNTL);
892 }
893 spin_unlock_irqrestore(&pcdev->lock, flags);
894 }
895
896 return 0;
897}
898
899static int mx2_stop_streaming(struct vb2_queue *q)
900{
901 struct soc_camera_device *icd = soc_camera_from_vb2q(q);
902 struct soc_camera_host *ici =
903 to_soc_camera_host(icd->parent);
904 struct mx2_camera_dev *pcdev = ici->priv;
905 struct mx2_fmt_cfg *prp = pcdev->emma_prp;
906 unsigned long flags;
907 void *b;
908 u32 cntl;
909
910 if (cpu_is_mx27()) {
911 spin_lock_irqsave(&pcdev->lock, flags);
912
913 cntl = readl(pcdev->base_emma + PRP_CNTL);
914 if (prp->cfg.channel == 1) {
915 writel(cntl & ~PRP_CNTL_CH1EN,
916 pcdev->base_emma + PRP_CNTL);
917 } else {
918 writel(cntl & ~PRP_CNTL_CH2EN,
919 pcdev->base_emma + PRP_CNTL);
920 }
921 INIT_LIST_HEAD(&pcdev->capture);
922 INIT_LIST_HEAD(&pcdev->active_bufs);
923 INIT_LIST_HEAD(&pcdev->discard);
924
925 b = pcdev->discard_buffer;
926 pcdev->discard_buffer = NULL;
927
928 spin_unlock_irqrestore(&pcdev->lock, flags);
929
930 dma_free_coherent(ici->v4l2_dev.dev,
931 pcdev->discard_size, b, pcdev->discard_buffer_dma);
932 }
933
934 return 0;
935}
936
937static struct vb2_ops mx2_videobuf_ops = {
938 .queue_setup = mx2_videobuf_setup,
939 .buf_prepare = mx2_videobuf_prepare,
940 .buf_queue = mx2_videobuf_queue,
941 .buf_cleanup = mx2_videobuf_release,
942 .start_streaming = mx2_start_streaming,
943 .stop_streaming = mx2_stop_streaming,
944};
945
946static int mx2_camera_init_videobuf(struct vb2_queue *q,
947 struct soc_camera_device *icd)
948{
949 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
950 q->io_modes = VB2_MMAP | VB2_USERPTR;
951 q->drv_priv = icd;
952 q->ops = &mx2_videobuf_ops;
953 q->mem_ops = &vb2_dma_contig_memops;
954 q->buf_struct_size = sizeof(struct mx2_buffer);
955
956 return vb2_queue_init(q);
957}
958
959#define MX2_BUS_FLAGS (V4L2_MBUS_MASTER | \
960 V4L2_MBUS_VSYNC_ACTIVE_HIGH | \
961 V4L2_MBUS_VSYNC_ACTIVE_LOW | \
962 V4L2_MBUS_HSYNC_ACTIVE_HIGH | \
963 V4L2_MBUS_HSYNC_ACTIVE_LOW | \
964 V4L2_MBUS_PCLK_SAMPLE_RISING | \
965 V4L2_MBUS_PCLK_SAMPLE_FALLING | \
966 V4L2_MBUS_DATA_ACTIVE_HIGH | \
967 V4L2_MBUS_DATA_ACTIVE_LOW)
968
969static int mx27_camera_emma_prp_reset(struct mx2_camera_dev *pcdev)
970{
971 u32 cntl;
972 int count = 0;
973
974 cntl = readl(pcdev->base_emma + PRP_CNTL);
975 writel(PRP_CNTL_SWRST, pcdev->base_emma + PRP_CNTL);
976 while (count++ < 100) {
977 if (!(readl(pcdev->base_emma + PRP_CNTL) & PRP_CNTL_SWRST))
978 return 0;
979 barrier();
980 udelay(1);
981 }
982
983 return -ETIMEDOUT;
984}
985
986static int mx2_camera_set_bus_param(struct soc_camera_device *icd)
987{
988 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
989 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
990 struct mx2_camera_dev *pcdev = ici->priv;
991 struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
992 unsigned long common_flags;
993 int ret;
994 int bytesperline;
995 u32 csicr1 = pcdev->csicr1;
996
997 ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
998 if (!ret) {
999 common_flags = soc_mbus_config_compatible(&cfg, MX2_BUS_FLAGS);
1000 if (!common_flags) {
1001 dev_warn(icd->parent,
1002 "Flags incompatible: camera 0x%x, host 0x%x\n",
1003 cfg.flags, MX2_BUS_FLAGS);
1004 return -EINVAL;
1005 }
1006 } else if (ret != -ENOIOCTLCMD) {
1007 return ret;
1008 } else {
1009 common_flags = MX2_BUS_FLAGS;
1010 }
1011
1012 if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) &&
1013 (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) {
1014 if (pcdev->platform_flags & MX2_CAMERA_HSYNC_HIGH)
1015 common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW;
1016 else
1017 common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH;
1018 }
1019
1020 if ((common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) &&
1021 (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)) {
1022 if (pcdev->platform_flags & MX2_CAMERA_PCLK_SAMPLE_RISING)
1023 common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_FALLING;
1024 else
1025 common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_RISING;
1026 }
1027
1028 cfg.flags = common_flags;
1029 ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
1030 if (ret < 0 && ret != -ENOIOCTLCMD) {
1031 dev_dbg(icd->parent, "camera s_mbus_config(0x%lx) returned %d\n",
1032 common_flags, ret);
1033 return ret;
1034 }
1035
1036 csicr1 = (csicr1 & ~CSICR1_FMT_MASK) | pcdev->emma_prp->cfg.csicr1;
1037
1038 if (common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING)
1039 csicr1 |= CSICR1_REDGE;
1040 if (common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH)
1041 csicr1 |= CSICR1_SOF_POL;
1042 if (common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH)
1043 csicr1 |= CSICR1_HSYNC_POL;
1044 if (pcdev->platform_flags & MX2_CAMERA_EXT_VSYNC)
1045 csicr1 |= CSICR1_EXT_VSYNC;
1046 if (pcdev->platform_flags & MX2_CAMERA_CCIR)
1047 csicr1 |= CSICR1_CCIR_EN;
1048 if (pcdev->platform_flags & MX2_CAMERA_CCIR_INTERLACE)
1049 csicr1 |= CSICR1_CCIR_MODE;
1050 if (pcdev->platform_flags & MX2_CAMERA_GATED_CLOCK)
1051 csicr1 |= CSICR1_GCLK_MODE;
1052 if (pcdev->platform_flags & MX2_CAMERA_INV_DATA)
1053 csicr1 |= CSICR1_INV_DATA;
1054
1055 pcdev->csicr1 = csicr1;
1056
1057 bytesperline = soc_mbus_bytes_per_line(icd->user_width,
1058 icd->current_fmt->host_fmt);
1059 if (bytesperline < 0)
1060 return bytesperline;
1061
1062 if (cpu_is_mx27()) {
1063 ret = mx27_camera_emma_prp_reset(pcdev);
1064 if (ret)
1065 return ret;
1066 } else if (cpu_is_mx25()) {
1067 writel((bytesperline * icd->user_height) >> 2,
1068 pcdev->base_csi + CSIRXCNT);
1069 writel((bytesperline << 16) | icd->user_height,
1070 pcdev->base_csi + CSIIMAG_PARA);
1071 }
1072
1073 writel(pcdev->csicr1, pcdev->base_csi + CSICR1);
1074
1075 return 0;
1076}
1077
1078static int mx2_camera_set_crop(struct soc_camera_device *icd,
1079 struct v4l2_crop *a)
1080{
1081 struct v4l2_rect *rect = &a->c;
1082 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1083 struct v4l2_mbus_framefmt mf;
1084 int ret;
1085
1086 soc_camera_limit_side(&rect->left, &rect->width, 0, 2, 4096);
1087 soc_camera_limit_side(&rect->top, &rect->height, 0, 2, 4096);
1088
1089 ret = v4l2_subdev_call(sd, video, s_crop, a);
1090 if (ret < 0)
1091 return ret;
1092
1093 /* The capture device might have changed its output */
1094 ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf);
1095 if (ret < 0)
1096 return ret;
1097
1098 dev_dbg(icd->parent, "Sensor cropped %dx%d\n",
1099 mf.width, mf.height);
1100
1101 icd->user_width = mf.width;
1102 icd->user_height = mf.height;
1103
1104 return ret;
1105}
1106
1107static int mx2_camera_get_formats(struct soc_camera_device *icd,
1108 unsigned int idx,
1109 struct soc_camera_format_xlate *xlate)
1110{
1111 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1112 const struct soc_mbus_pixelfmt *fmt;
1113 struct device *dev = icd->parent;
1114 enum v4l2_mbus_pixelcode code;
1115 int ret, formats = 0;
1116
1117 ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code);
1118 if (ret < 0)
1119 /* no more formats */
1120 return 0;
1121
1122 fmt = soc_mbus_get_fmtdesc(code);
1123 if (!fmt) {
1124 dev_err(dev, "Invalid format code #%u: %d\n", idx, code);
1125 return 0;
1126 }
1127
1128 if (code == V4L2_MBUS_FMT_YUYV8_2X8 ||
1129 code == V4L2_MBUS_FMT_UYVY8_2X8) {
1130 formats++;
1131 if (xlate) {
1132 /*
1133 * CH2 can output YUV420 which is a standard format in
1134 * soc_mediabus.c
1135 */
1136 xlate->host_fmt =
1137 soc_mbus_get_fmtdesc(V4L2_MBUS_FMT_YUYV8_1_5X8);
1138 xlate->code = code;
1139 dev_dbg(dev, "Providing host format %s for sensor code %d\n",
1140 xlate->host_fmt->name, code);
1141 xlate++;
1142 }
1143 }
1144
1145 /* Generic pass-trough */
1146 formats++;
1147 if (xlate) {
1148 xlate->host_fmt = fmt;
1149 xlate->code = code;
1150 xlate++;
1151 }
1152 return formats;
1153}
1154
1155static int mx2_emmaprp_resize(struct mx2_camera_dev *pcdev,
1156 struct v4l2_mbus_framefmt *mf_in,
1157 struct v4l2_pix_format *pix_out, bool apply)
1158{
1159 int num, den;
1160 unsigned long m;
1161 int i, dir;
1162
1163 for (dir = RESIZE_DIR_H; dir <= RESIZE_DIR_V; dir++) {
1164 struct emma_prp_resize tmprsz;
1165 unsigned char *s = tmprsz.s;
1166 int len = 0;
1167 int in, out;
1168
1169 if (dir == RESIZE_DIR_H) {
1170 in = mf_in->width;
1171 out = pix_out->width;
1172 } else {
1173 in = mf_in->height;
1174 out = pix_out->height;
1175 }
1176
1177 if (in < out)
1178 return -EINVAL;
1179 else if (in == out)
1180 continue;
1181
1182 /* Calculate ratio */
1183 m = gcd(in, out);
1184 num = in / m;
1185 den = out / m;
1186 if (num > RESIZE_NUM_MAX)
1187 return -EINVAL;
1188
1189 if ((num >= 2 * den) && (den == 1) &&
1190 (num < 9) && (!(num & 0x01))) {
1191 int sum = 0;
1192 int j;
1193
1194 /* Average scaling for >= 2:1 ratios */
1195 /* Support can be added for num >=9 and odd values */
1196
1197 tmprsz.algo = RESIZE_ALGO_AVERAGING;
1198 len = num;
1199
1200 for (i = 0; i < (len / 2); i++)
1201 s[i] = 8;
1202
1203 do {
1204 for (i = 0; i < (len / 2); i++) {
1205 s[i] = s[i] >> 1;
1206 sum = 0;
1207 for (j = 0; j < (len / 2); j++)
1208 sum += s[j];
1209 if (sum == 4)
1210 break;
1211 }
1212 } while (sum != 4);
1213
1214 for (i = (len / 2); i < len; i++)
1215 s[i] = s[len - i - 1];
1216
1217 s[len - 1] |= SZ_COEF;
1218 } else {
1219 /* bilinear scaling for < 2:1 ratios */
1220 int v; /* overflow counter */
1221 int coeff, nxt; /* table output */
1222 int in_pos_inc = 2 * den;
1223 int out_pos = num;
1224 int out_pos_inc = 2 * num;
1225 int init_carry = num - den;
1226 int carry = init_carry;
1227
1228 tmprsz.algo = RESIZE_ALGO_BILINEAR;
1229 v = den + in_pos_inc;
1230 do {
1231 coeff = v - out_pos;
1232 out_pos += out_pos_inc;
1233 carry += out_pos_inc;
1234 for (nxt = 0; v < out_pos; nxt++) {
1235 v += in_pos_inc;
1236 carry -= in_pos_inc;
1237 }
1238
1239 if (len > RESIZE_NUM_MAX)
1240 return -EINVAL;
1241
1242 coeff = ((coeff << BC_COEF) +
1243 (in_pos_inc >> 1)) / in_pos_inc;
1244
1245 if (coeff >= (SZ_COEF - 1))
1246 coeff--;
1247
1248 coeff |= SZ_COEF;
1249 s[len] = (unsigned char)coeff;
1250 len++;
1251
1252 for (i = 1; i < nxt; i++) {
1253 if (len >= RESIZE_NUM_MAX)
1254 return -EINVAL;
1255 s[len] = 0;
1256 len++;
1257 }
1258 } while (carry != init_carry);
1259 }
1260 tmprsz.len = len;
1261 if (dir == RESIZE_DIR_H)
1262 mf_in->width = pix_out->width;
1263 else
1264 mf_in->height = pix_out->height;
1265
1266 if (apply)
1267 memcpy(&pcdev->resizing[dir], &tmprsz, sizeof(tmprsz));
1268 }
1269 return 0;
1270}
1271
1272static int mx2_camera_set_fmt(struct soc_camera_device *icd,
1273 struct v4l2_format *f)
1274{
1275 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1276 struct mx2_camera_dev *pcdev = ici->priv;
1277 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1278 const struct soc_camera_format_xlate *xlate;
1279 struct v4l2_pix_format *pix = &f->fmt.pix;
1280 struct v4l2_mbus_framefmt mf;
1281 int ret;
1282
1283 dev_dbg(icd->parent, "%s: requested params: width = %d, height = %d\n",
1284 __func__, pix->width, pix->height);
1285
1286 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
1287 if (!xlate) {
1288 dev_warn(icd->parent, "Format %x not found\n",
1289 pix->pixelformat);
1290 return -EINVAL;
1291 }
1292
1293 mf.width = pix->width;
1294 mf.height = pix->height;
1295 mf.field = pix->field;
1296 mf.colorspace = pix->colorspace;
1297 mf.code = xlate->code;
1298
1299 ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
1300 if (ret < 0 && ret != -ENOIOCTLCMD)
1301 return ret;
1302
1303 /* Store width and height returned by the sensor for resizing */
1304 pcdev->s_width = mf.width;
1305 pcdev->s_height = mf.height;
1306 dev_dbg(icd->parent, "%s: sensor params: width = %d, height = %d\n",
1307 __func__, pcdev->s_width, pcdev->s_height);
1308
1309 pcdev->emma_prp = mx27_emma_prp_get_format(xlate->code,
1310 xlate->host_fmt->fourcc);
1311
1312 memset(pcdev->resizing, 0, sizeof(pcdev->resizing));
1313 if ((mf.width != pix->width || mf.height != pix->height) &&
1314 pcdev->emma_prp->cfg.in_fmt == PRP_CNTL_DATA_IN_YUV422) {
1315 if (mx2_emmaprp_resize(pcdev, &mf, pix, true) < 0)
1316 dev_dbg(icd->parent, "%s: can't resize\n", __func__);
1317 }
1318
1319 if (mf.code != xlate->code)
1320 return -EINVAL;
1321
1322 pix->width = mf.width;
1323 pix->height = mf.height;
1324 pix->field = mf.field;
1325 pix->colorspace = mf.colorspace;
1326 icd->current_fmt = xlate;
1327
1328 dev_dbg(icd->parent, "%s: returned params: width = %d, height = %d\n",
1329 __func__, pix->width, pix->height);
1330
1331 return 0;
1332}
1333
1334static int mx2_camera_try_fmt(struct soc_camera_device *icd,
1335 struct v4l2_format *f)
1336{
1337 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1338 const struct soc_camera_format_xlate *xlate;
1339 struct v4l2_pix_format *pix = &f->fmt.pix;
1340 struct v4l2_mbus_framefmt mf;
1341 __u32 pixfmt = pix->pixelformat;
1342 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1343 struct mx2_camera_dev *pcdev = ici->priv;
1344 unsigned int width_limit;
1345 int ret;
1346
1347 dev_dbg(icd->parent, "%s: requested params: width = %d, height = %d\n",
1348 __func__, pix->width, pix->height);
1349
1350 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
1351 if (pixfmt && !xlate) {
1352 dev_warn(icd->parent, "Format %x not found\n", pixfmt);
1353 return -EINVAL;
1354 }
1355
1356 /* FIXME: implement MX27 limits */
1357
1358 /* limit to MX25 hardware capabilities */
1359 if (cpu_is_mx25()) {
1360 if (xlate->host_fmt->bits_per_sample <= 8)
1361 width_limit = 0xffff * 4;
1362 else
1363 width_limit = 0xffff * 2;
1364 /* CSIIMAG_PARA limit */
1365 if (pix->width > width_limit)
1366 pix->width = width_limit;
1367 if (pix->height > 0xffff)
1368 pix->height = 0xffff;
1369
1370 pix->bytesperline = soc_mbus_bytes_per_line(pix->width,
1371 xlate->host_fmt);
1372 if (pix->bytesperline < 0)
1373 return pix->bytesperline;
1374 pix->sizeimage = soc_mbus_image_size(xlate->host_fmt,
1375 pix->bytesperline, pix->height);
1376 /* Check against the CSIRXCNT limit */
1377 if (pix->sizeimage > 4 * 0x3ffff) {
1378 /* Adjust geometry, preserve aspect ratio */
1379 unsigned int new_height = int_sqrt(div_u64(0x3ffffULL *
1380 4 * pix->height, pix->bytesperline));
1381 pix->width = new_height * pix->width / pix->height;
1382 pix->height = new_height;
1383 pix->bytesperline = soc_mbus_bytes_per_line(pix->width,
1384 xlate->host_fmt);
1385 BUG_ON(pix->bytesperline < 0);
1386 pix->sizeimage = soc_mbus_image_size(xlate->host_fmt,
1387 pix->bytesperline, pix->height);
1388 }
1389 }
1390
1391 /* limit to sensor capabilities */
1392 mf.width = pix->width;
1393 mf.height = pix->height;
1394 mf.field = pix->field;
1395 mf.colorspace = pix->colorspace;
1396 mf.code = xlate->code;
1397
1398 ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
1399 if (ret < 0)
1400 return ret;
1401
1402 dev_dbg(icd->parent, "%s: sensor params: width = %d, height = %d\n",
1403 __func__, pcdev->s_width, pcdev->s_height);
1404
1405 /* If the sensor does not support image size try PrP resizing */
1406 pcdev->emma_prp = mx27_emma_prp_get_format(xlate->code,
1407 xlate->host_fmt->fourcc);
1408
1409 memset(pcdev->resizing, 0, sizeof(pcdev->resizing));
1410 if ((mf.width != pix->width || mf.height != pix->height) &&
1411 pcdev->emma_prp->cfg.in_fmt == PRP_CNTL_DATA_IN_YUV422) {
1412 if (mx2_emmaprp_resize(pcdev, &mf, pix, false) < 0)
1413 dev_dbg(icd->parent, "%s: can't resize\n", __func__);
1414 }
1415
1416 if (mf.field == V4L2_FIELD_ANY)
1417 mf.field = V4L2_FIELD_NONE;
1418 /*
1419 * Driver supports interlaced images provided they have
1420 * both fields so that they can be processed as if they
1421 * were progressive.
1422 */
1423 if (mf.field != V4L2_FIELD_NONE && !V4L2_FIELD_HAS_BOTH(mf.field)) {
1424 dev_err(icd->parent, "Field type %d unsupported.\n",
1425 mf.field);
1426 return -EINVAL;
1427 }
1428
1429 pix->width = mf.width;
1430 pix->height = mf.height;
1431 pix->field = mf.field;
1432 pix->colorspace = mf.colorspace;
1433
1434 dev_dbg(icd->parent, "%s: returned params: width = %d, height = %d\n",
1435 __func__, pix->width, pix->height);
1436
1437 return 0;
1438}
1439
1440static int mx2_camera_querycap(struct soc_camera_host *ici,
1441 struct v4l2_capability *cap)
1442{
1443 /* cap->name is set by the friendly caller:-> */
1444 strlcpy(cap->card, MX2_CAM_DRIVER_DESCRIPTION, sizeof(cap->card));
1445 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
1446
1447 return 0;
1448}
1449
1450static unsigned int mx2_camera_poll(struct file *file, poll_table *pt)
1451{
1452 struct soc_camera_device *icd = file->private_data;
1453
1454 return vb2_poll(&icd->vb2_vidq, file, pt);
1455}
1456
1457static struct soc_camera_host_ops mx2_soc_camera_host_ops = {
1458 .owner = THIS_MODULE,
1459 .add = mx2_camera_add_device,
1460 .remove = mx2_camera_remove_device,
1461 .set_fmt = mx2_camera_set_fmt,
1462 .set_crop = mx2_camera_set_crop,
1463 .get_formats = mx2_camera_get_formats,
1464 .try_fmt = mx2_camera_try_fmt,
1465 .init_videobuf2 = mx2_camera_init_videobuf,
1466 .poll = mx2_camera_poll,
1467 .querycap = mx2_camera_querycap,
1468 .set_bus_param = mx2_camera_set_bus_param,
1469};
1470
1471static void mx27_camera_frame_done_emma(struct mx2_camera_dev *pcdev,
1472 int bufnum, bool err)
1473{
1474#ifdef DEBUG
1475 struct mx2_fmt_cfg *prp = pcdev->emma_prp;
1476#endif
1477 struct mx2_buf_internal *ibuf;
1478 struct mx2_buffer *buf;
1479 struct vb2_buffer *vb;
1480 unsigned long phys;
1481
1482 ibuf = list_first_entry(&pcdev->active_bufs, struct mx2_buf_internal,
1483 queue);
1484
1485 BUG_ON(ibuf->bufnum != bufnum);
1486
1487 if (ibuf->discard) {
1488 /*
1489 * Discard buffer must not be returned to user space.
1490 * Just return it to the discard queue.
1491 */
1492 list_move_tail(pcdev->active_bufs.next, &pcdev->discard);
1493 } else {
1494 buf = mx2_ibuf_to_buf(ibuf);
1495
1496 vb = &buf->vb;
1497#ifdef DEBUG
1498 phys = vb2_dma_contig_plane_dma_addr(vb, 0);
1499 if (prp->cfg.channel == 1) {
1500 if (readl(pcdev->base_emma + PRP_DEST_RGB1_PTR +
1501 4 * bufnum) != phys) {
1502 dev_err(pcdev->dev, "%lx != %x\n", phys,
1503 readl(pcdev->base_emma +
1504 PRP_DEST_RGB1_PTR + 4 * bufnum));
1505 }
1506 } else {
1507 if (readl(pcdev->base_emma + PRP_DEST_Y_PTR -
1508 0x14 * bufnum) != phys) {
1509 dev_err(pcdev->dev, "%lx != %x\n", phys,
1510 readl(pcdev->base_emma +
1511 PRP_DEST_Y_PTR - 0x14 * bufnum));
1512 }
1513 }
1514#endif
1515 dev_dbg(pcdev->dev, "%s (vb=0x%p) 0x%p %lu\n", __func__, vb,
1516 vb2_plane_vaddr(vb, 0),
1517 vb2_get_plane_payload(vb, 0));
1518
1519 list_del_init(&buf->internal.queue);
1520 do_gettimeofday(&vb->v4l2_buf.timestamp);
1521 vb->v4l2_buf.sequence = pcdev->frame_count;
1522 if (err)
1523 vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
1524 else
1525 vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
1526 }
1527
1528 pcdev->frame_count++;
1529
1530 if (list_empty(&pcdev->capture)) {
1531 if (list_empty(&pcdev->discard)) {
1532 dev_warn(pcdev->dev, "%s: trying to access empty discard list\n",
1533 __func__);
1534 return;
1535 }
1536
1537 ibuf = list_first_entry(&pcdev->discard,
1538 struct mx2_buf_internal, queue);
1539 ibuf->bufnum = bufnum;
1540
1541 list_move_tail(pcdev->discard.next, &pcdev->active_bufs);
1542 mx27_update_emma_buf(pcdev, pcdev->discard_buffer_dma, bufnum);
1543 return;
1544 }
1545
1546 buf = list_first_entry(&pcdev->capture, struct mx2_buffer,
1547 internal.queue);
1548
1549 buf->internal.bufnum = bufnum;
1550
1551 list_move_tail(pcdev->capture.next, &pcdev->active_bufs);
1552
1553 vb = &buf->vb;
1554 buf->state = MX2_STATE_ACTIVE;
1555
1556 phys = vb2_dma_contig_plane_dma_addr(vb, 0);
1557 mx27_update_emma_buf(pcdev, phys, bufnum);
1558}
1559
1560static irqreturn_t mx27_camera_emma_irq(int irq_emma, void *data)
1561{
1562 struct mx2_camera_dev *pcdev = data;
1563 unsigned int status = readl(pcdev->base_emma + PRP_INTRSTATUS);
1564 struct mx2_buf_internal *ibuf;
1565
1566 spin_lock(&pcdev->lock);
1567
1568 if (list_empty(&pcdev->active_bufs)) {
1569 dev_warn(pcdev->dev, "%s: called while active list is empty\n",
1570 __func__);
1571
1572 if (!status) {
1573 spin_unlock(&pcdev->lock);
1574 return IRQ_NONE;
1575 }
1576 }
1577
1578 if (status & (1 << 7)) { /* overflow */
1579 u32 cntl = readl(pcdev->base_emma + PRP_CNTL);
1580 writel(cntl & ~(PRP_CNTL_CH1EN | PRP_CNTL_CH2EN),
1581 pcdev->base_emma + PRP_CNTL);
1582 writel(cntl, pcdev->base_emma + PRP_CNTL);
1583
1584 ibuf = list_first_entry(&pcdev->active_bufs,
1585 struct mx2_buf_internal, queue);
1586 mx27_camera_frame_done_emma(pcdev,
1587 ibuf->bufnum, true);
1588
1589 status &= ~(1 << 7);
1590 } else if (((status & (3 << 5)) == (3 << 5)) ||
1591 ((status & (3 << 3)) == (3 << 3))) {
1592 /*
1593 * Both buffers have triggered, process the one we're expecting
1594 * to first
1595 */
1596 ibuf = list_first_entry(&pcdev->active_bufs,
1597 struct mx2_buf_internal, queue);
1598 mx27_camera_frame_done_emma(pcdev, ibuf->bufnum, false);
1599 status &= ~(1 << (6 - ibuf->bufnum)); /* mark processed */
1600 } else if ((status & (1 << 6)) || (status & (1 << 4))) {
1601 mx27_camera_frame_done_emma(pcdev, 0, false);
1602 } else if ((status & (1 << 5)) || (status & (1 << 3))) {
1603 mx27_camera_frame_done_emma(pcdev, 1, false);
1604 }
1605
1606 spin_unlock(&pcdev->lock);
1607 writel(status, pcdev->base_emma + PRP_INTRSTATUS);
1608
1609 return IRQ_HANDLED;
1610}
1611
1612static int __devinit mx27_camera_emma_init(struct mx2_camera_dev *pcdev)
1613{
1614 struct resource *res_emma = pcdev->res_emma;
1615 int err = 0;
1616
1617 if (!request_mem_region(res_emma->start, resource_size(res_emma),
1618 MX2_CAM_DRV_NAME)) {
1619 err = -EBUSY;
1620 goto out;
1621 }
1622
1623 pcdev->base_emma = ioremap(res_emma->start, resource_size(res_emma));
1624 if (!pcdev->base_emma) {
1625 err = -ENOMEM;
1626 goto exit_release;
1627 }
1628
1629 err = request_irq(pcdev->irq_emma, mx27_camera_emma_irq, 0,
1630 MX2_CAM_DRV_NAME, pcdev);
1631 if (err) {
1632 dev_err(pcdev->dev, "Camera EMMA interrupt register failed \n");
1633 goto exit_iounmap;
1634 }
1635
1636 pcdev->clk_emma = clk_get(NULL, "emma");
1637 if (IS_ERR(pcdev->clk_emma)) {
1638 err = PTR_ERR(pcdev->clk_emma);
1639 goto exit_free_irq;
1640 }
1641
1642 clk_enable(pcdev->clk_emma);
1643
1644 err = mx27_camera_emma_prp_reset(pcdev);
1645 if (err)
1646 goto exit_clk_emma_put;
1647
1648 return err;
1649
1650exit_clk_emma_put:
1651 clk_disable(pcdev->clk_emma);
1652 clk_put(pcdev->clk_emma);
1653exit_free_irq:
1654 free_irq(pcdev->irq_emma, pcdev);
1655exit_iounmap:
1656 iounmap(pcdev->base_emma);
1657exit_release:
1658 release_mem_region(res_emma->start, resource_size(res_emma));
1659out:
1660 return err;
1661}
1662
1663static int __devinit mx2_camera_probe(struct platform_device *pdev)
1664{
1665 struct mx2_camera_dev *pcdev;
1666 struct resource *res_csi, *res_emma;
1667 void __iomem *base_csi;
1668 int irq_csi, irq_emma;
1669 int err = 0;
1670
1671 dev_dbg(&pdev->dev, "initialising\n");
1672
1673 res_csi = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1674 irq_csi = platform_get_irq(pdev, 0);
1675 if (res_csi == NULL || irq_csi < 0) {
1676 dev_err(&pdev->dev, "Missing platform resources data\n");
1677 err = -ENODEV;
1678 goto exit;
1679 }
1680
1681 pcdev = kzalloc(sizeof(*pcdev), GFP_KERNEL);
1682 if (!pcdev) {
1683 dev_err(&pdev->dev, "Could not allocate pcdev\n");
1684 err = -ENOMEM;
1685 goto exit;
1686 }
1687
1688 pcdev->clk_csi = clk_get(&pdev->dev, NULL);
1689 if (IS_ERR(pcdev->clk_csi)) {
1690 dev_err(&pdev->dev, "Could not get csi clock\n");
1691 err = PTR_ERR(pcdev->clk_csi);
1692 goto exit_kfree;
1693 }
1694
1695 pcdev->res_csi = res_csi;
1696 pcdev->pdata = pdev->dev.platform_data;
1697 if (pcdev->pdata) {
1698 long rate;
1699
1700 pcdev->platform_flags = pcdev->pdata->flags;
1701
1702 rate = clk_round_rate(pcdev->clk_csi, pcdev->pdata->clk * 2);
1703 if (rate <= 0) {
1704 err = -ENODEV;
1705 goto exit_dma_free;
1706 }
1707 err = clk_set_rate(pcdev->clk_csi, rate);
1708 if (err < 0)
1709 goto exit_dma_free;
1710 }
1711
1712 INIT_LIST_HEAD(&pcdev->capture);
1713 INIT_LIST_HEAD(&pcdev->active_bufs);
1714 INIT_LIST_HEAD(&pcdev->discard);
1715 spin_lock_init(&pcdev->lock);
1716
1717 /*
1718 * Request the regions.
1719 */
1720 if (!request_mem_region(res_csi->start, resource_size(res_csi),
1721 MX2_CAM_DRV_NAME)) {
1722 err = -EBUSY;
1723 goto exit_dma_free;
1724 }
1725
1726 base_csi = ioremap(res_csi->start, resource_size(res_csi));
1727 if (!base_csi) {
1728 err = -ENOMEM;
1729 goto exit_release;
1730 }
1731 pcdev->irq_csi = irq_csi;
1732 pcdev->base_csi = base_csi;
1733 pcdev->base_dma = res_csi->start;
1734 pcdev->dev = &pdev->dev;
1735
1736 if (cpu_is_mx25()) {
1737 err = request_irq(pcdev->irq_csi, mx25_camera_irq, 0,
1738 MX2_CAM_DRV_NAME, pcdev);
1739 if (err) {
1740 dev_err(pcdev->dev, "Camera interrupt register failed \n");
1741 goto exit_iounmap;
1742 }
1743 }
1744
1745 if (cpu_is_mx27()) {
1746 /* EMMA support */
1747 res_emma = platform_get_resource(pdev, IORESOURCE_MEM, 1);
1748 irq_emma = platform_get_irq(pdev, 1);
1749
1750 if (!res_emma || !irq_emma) {
1751 dev_err(&pdev->dev, "no EMMA resources\n");
1752 goto exit_free_irq;
1753 }
1754
1755 pcdev->res_emma = res_emma;
1756 pcdev->irq_emma = irq_emma;
1757 if (mx27_camera_emma_init(pcdev))
1758 goto exit_free_irq;
1759 }
1760
1761 pcdev->soc_host.drv_name = MX2_CAM_DRV_NAME,
1762 pcdev->soc_host.ops = &mx2_soc_camera_host_ops,
1763 pcdev->soc_host.priv = pcdev;
1764 pcdev->soc_host.v4l2_dev.dev = &pdev->dev;
1765 pcdev->soc_host.nr = pdev->id;
1766 if (cpu_is_mx25())
1767 pcdev->soc_host.capabilities = SOCAM_HOST_CAP_STRIDE;
1768
1769 pcdev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
1770 if (IS_ERR(pcdev->alloc_ctx)) {
1771 err = PTR_ERR(pcdev->alloc_ctx);
1772 goto eallocctx;
1773 }
1774 err = soc_camera_host_register(&pcdev->soc_host);
1775 if (err)
1776 goto exit_free_emma;
1777
1778 dev_info(&pdev->dev, "MX2 Camera (CSI) driver probed, clock frequency: %ld\n",
1779 clk_get_rate(pcdev->clk_csi));
1780
1781 return 0;
1782
1783exit_free_emma:
1784 vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx);
1785eallocctx:
1786 if (cpu_is_mx27()) {
1787 free_irq(pcdev->irq_emma, pcdev);
1788 clk_disable(pcdev->clk_emma);
1789 clk_put(pcdev->clk_emma);
1790 iounmap(pcdev->base_emma);
1791 release_mem_region(pcdev->res_emma->start, resource_size(pcdev->res_emma));
1792 }
1793exit_free_irq:
1794 if (cpu_is_mx25())
1795 free_irq(pcdev->irq_csi, pcdev);
1796exit_iounmap:
1797 iounmap(base_csi);
1798exit_release:
1799 release_mem_region(res_csi->start, resource_size(res_csi));
1800exit_dma_free:
1801 clk_put(pcdev->clk_csi);
1802exit_kfree:
1803 kfree(pcdev);
1804exit:
1805 return err;
1806}
1807
1808static int __devexit mx2_camera_remove(struct platform_device *pdev)
1809{
1810 struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev);
1811 struct mx2_camera_dev *pcdev = container_of(soc_host,
1812 struct mx2_camera_dev, soc_host);
1813 struct resource *res;
1814
1815 clk_put(pcdev->clk_csi);
1816 if (cpu_is_mx25())
1817 free_irq(pcdev->irq_csi, pcdev);
1818 if (cpu_is_mx27())
1819 free_irq(pcdev->irq_emma, pcdev);
1820
1821 soc_camera_host_unregister(&pcdev->soc_host);
1822
1823 vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx);
1824
1825 iounmap(pcdev->base_csi);
1826
1827 if (cpu_is_mx27()) {
1828 clk_disable(pcdev->clk_emma);
1829 clk_put(pcdev->clk_emma);
1830 iounmap(pcdev->base_emma);
1831 res = pcdev->res_emma;
1832 release_mem_region(res->start, resource_size(res));
1833 }
1834
1835 res = pcdev->res_csi;
1836 release_mem_region(res->start, resource_size(res));
1837
1838 kfree(pcdev);
1839
1840 dev_info(&pdev->dev, "MX2 Camera driver unloaded\n");
1841
1842 return 0;
1843}
1844
1845static struct platform_driver mx2_camera_driver = {
1846 .driver = {
1847 .name = MX2_CAM_DRV_NAME,
1848 },
1849 .remove = __devexit_p(mx2_camera_remove),
1850};
1851
1852
1853static int __init mx2_camera_init(void)
1854{
1855 return platform_driver_probe(&mx2_camera_driver, &mx2_camera_probe);
1856}
1857
1858static void __exit mx2_camera_exit(void)
1859{
1860 return platform_driver_unregister(&mx2_camera_driver);
1861}
1862
1863module_init(mx2_camera_init);
1864module_exit(mx2_camera_exit);
1865
1866MODULE_DESCRIPTION("i.MX27/i.MX25 SoC Camera Host driver");
1867MODULE_AUTHOR("Sascha Hauer <sha@pengutronix.de>");
1868MODULE_LICENSE("GPL");
1869MODULE_VERSION(MX2_CAM_VERSION);
diff --git a/drivers/media/video/mx2_emmaprp.c b/drivers/media/video/mx2_emmaprp.c
deleted file mode 100644
index 2810015d78f4..000000000000
--- a/drivers/media/video/mx2_emmaprp.c
+++ /dev/null
@@ -1,1037 +0,0 @@
1/*
2 * Support eMMa-PrP through mem2mem framework.
3 *
4 * eMMa-PrP is a piece of HW that allows fetching buffers
5 * from one memory location and do several operations on
6 * them such as scaling or format conversion giving, as a result
7 * a new processed buffer in another memory location.
8 *
9 * Based on mem2mem_testdev.c by Pawel Osciak.
10 *
11 * Copyright (c) 2011 Vista Silicon S.L.
12 * Javier Martin <javier.martin@vista-silicon.com>
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by the
16 * Free Software Foundation; either version 2 of the
17 * License, or (at your option) any later version
18 */
19#include <linux/module.h>
20#include <linux/clk.h>
21#include <linux/slab.h>
22#include <linux/interrupt.h>
23#include <linux/io.h>
24
25#include <linux/platform_device.h>
26#include <media/v4l2-mem2mem.h>
27#include <media/v4l2-device.h>
28#include <media/v4l2-ioctl.h>
29#include <media/videobuf2-dma-contig.h>
30#include <asm/sizes.h>
31
32#define EMMAPRP_MODULE_NAME "mem2mem-emmaprp"
33
34MODULE_DESCRIPTION("Mem-to-mem device which supports eMMa-PrP present in mx2 SoCs");
35MODULE_AUTHOR("Javier Martin <javier.martin@vista-silicon.com");
36MODULE_LICENSE("GPL");
37MODULE_VERSION("0.0.1");
38
39static bool debug;
40module_param(debug, bool, 0644);
41
42#define MIN_W 32
43#define MIN_H 32
44#define MAX_W 2040
45#define MAX_H 2046
46
47#define S_ALIGN 1 /* multiple of 2 */
48#define W_ALIGN_YUV420 3 /* multiple of 8 */
49#define W_ALIGN_OTHERS 2 /* multiple of 4 */
50#define H_ALIGN 1 /* multiple of 2 */
51
52/* Flags that indicate a format can be used for capture/output */
53#define MEM2MEM_CAPTURE (1 << 0)
54#define MEM2MEM_OUTPUT (1 << 1)
55
56#define MEM2MEM_NAME "m2m-emmaprp"
57
58/* In bytes, per queue */
59#define MEM2MEM_VID_MEM_LIMIT SZ_16M
60
61#define dprintk(dev, fmt, arg...) \
62 v4l2_dbg(1, debug, &dev->v4l2_dev, "%s: " fmt, __func__, ## arg)
63
64/* EMMA PrP */
65#define PRP_CNTL 0x00
66#define PRP_INTR_CNTL 0x04
67#define PRP_INTRSTATUS 0x08
68#define PRP_SOURCE_Y_PTR 0x0c
69#define PRP_SOURCE_CB_PTR 0x10
70#define PRP_SOURCE_CR_PTR 0x14
71#define PRP_DEST_RGB1_PTR 0x18
72#define PRP_DEST_RGB2_PTR 0x1c
73#define PRP_DEST_Y_PTR 0x20
74#define PRP_DEST_CB_PTR 0x24
75#define PRP_DEST_CR_PTR 0x28
76#define PRP_SRC_FRAME_SIZE 0x2c
77#define PRP_DEST_CH1_LINE_STRIDE 0x30
78#define PRP_SRC_PIXEL_FORMAT_CNTL 0x34
79#define PRP_CH1_PIXEL_FORMAT_CNTL 0x38
80#define PRP_CH1_OUT_IMAGE_SIZE 0x3c
81#define PRP_CH2_OUT_IMAGE_SIZE 0x40
82#define PRP_SRC_LINE_STRIDE 0x44
83#define PRP_CSC_COEF_012 0x48
84#define PRP_CSC_COEF_345 0x4c
85#define PRP_CSC_COEF_678 0x50
86#define PRP_CH1_RZ_HORI_COEF1 0x54
87#define PRP_CH1_RZ_HORI_COEF2 0x58
88#define PRP_CH1_RZ_HORI_VALID 0x5c
89#define PRP_CH1_RZ_VERT_COEF1 0x60
90#define PRP_CH1_RZ_VERT_COEF2 0x64
91#define PRP_CH1_RZ_VERT_VALID 0x68
92#define PRP_CH2_RZ_HORI_COEF1 0x6c
93#define PRP_CH2_RZ_HORI_COEF2 0x70
94#define PRP_CH2_RZ_HORI_VALID 0x74
95#define PRP_CH2_RZ_VERT_COEF1 0x78
96#define PRP_CH2_RZ_VERT_COEF2 0x7c
97#define PRP_CH2_RZ_VERT_VALID 0x80
98
99#define PRP_CNTL_CH1EN (1 << 0)
100#define PRP_CNTL_CH2EN (1 << 1)
101#define PRP_CNTL_CSIEN (1 << 2)
102#define PRP_CNTL_DATA_IN_YUV420 (0 << 3)
103#define PRP_CNTL_DATA_IN_YUV422 (1 << 3)
104#define PRP_CNTL_DATA_IN_RGB16 (2 << 3)
105#define PRP_CNTL_DATA_IN_RGB32 (3 << 3)
106#define PRP_CNTL_CH1_OUT_RGB8 (0 << 5)
107#define PRP_CNTL_CH1_OUT_RGB16 (1 << 5)
108#define PRP_CNTL_CH1_OUT_RGB32 (2 << 5)
109#define PRP_CNTL_CH1_OUT_YUV422 (3 << 5)
110#define PRP_CNTL_CH2_OUT_YUV420 (0 << 7)
111#define PRP_CNTL_CH2_OUT_YUV422 (1 << 7)
112#define PRP_CNTL_CH2_OUT_YUV444 (2 << 7)
113#define PRP_CNTL_CH1_LEN (1 << 9)
114#define PRP_CNTL_CH2_LEN (1 << 10)
115#define PRP_CNTL_SKIP_FRAME (1 << 11)
116#define PRP_CNTL_SWRST (1 << 12)
117#define PRP_CNTL_CLKEN (1 << 13)
118#define PRP_CNTL_WEN (1 << 14)
119#define PRP_CNTL_CH1BYP (1 << 15)
120#define PRP_CNTL_IN_TSKIP(x) ((x) << 16)
121#define PRP_CNTL_CH1_TSKIP(x) ((x) << 19)
122#define PRP_CNTL_CH2_TSKIP(x) ((x) << 22)
123#define PRP_CNTL_INPUT_FIFO_LEVEL(x) ((x) << 25)
124#define PRP_CNTL_RZ_FIFO_LEVEL(x) ((x) << 27)
125#define PRP_CNTL_CH2B1EN (1 << 29)
126#define PRP_CNTL_CH2B2EN (1 << 30)
127#define PRP_CNTL_CH2FEN (1 << 31)
128
129#define PRP_SIZE_HEIGHT(x) (x)
130#define PRP_SIZE_WIDTH(x) ((x) << 16)
131
132/* IRQ Enable and status register */
133#define PRP_INTR_RDERR (1 << 0)
134#define PRP_INTR_CH1WERR (1 << 1)
135#define PRP_INTR_CH2WERR (1 << 2)
136#define PRP_INTR_CH1FC (1 << 3)
137#define PRP_INTR_CH2FC (1 << 5)
138#define PRP_INTR_LBOVF (1 << 7)
139#define PRP_INTR_CH2OVF (1 << 8)
140
141#define PRP_INTR_ST_RDERR (1 << 0)
142#define PRP_INTR_ST_CH1WERR (1 << 1)
143#define PRP_INTR_ST_CH2WERR (1 << 2)
144#define PRP_INTR_ST_CH2B2CI (1 << 3)
145#define PRP_INTR_ST_CH2B1CI (1 << 4)
146#define PRP_INTR_ST_CH1B2CI (1 << 5)
147#define PRP_INTR_ST_CH1B1CI (1 << 6)
148#define PRP_INTR_ST_LBOVF (1 << 7)
149#define PRP_INTR_ST_CH2OVF (1 << 8)
150
151struct emmaprp_fmt {
152 char *name;
153 u32 fourcc;
154 /* Types the format can be used for */
155 u32 types;
156};
157
158static struct emmaprp_fmt formats[] = {
159 {
160 .name = "YUV 4:2:0 Planar",
161 .fourcc = V4L2_PIX_FMT_YUV420,
162 .types = MEM2MEM_CAPTURE,
163 },
164 {
165 .name = "4:2:2, packed, YUYV",
166 .fourcc = V4L2_PIX_FMT_YUYV,
167 .types = MEM2MEM_OUTPUT,
168 },
169};
170
171/* Per-queue, driver-specific private data */
172struct emmaprp_q_data {
173 unsigned int width;
174 unsigned int height;
175 unsigned int sizeimage;
176 struct emmaprp_fmt *fmt;
177};
178
179enum {
180 V4L2_M2M_SRC = 0,
181 V4L2_M2M_DST = 1,
182};
183
184#define NUM_FORMATS ARRAY_SIZE(formats)
185
186static struct emmaprp_fmt *find_format(struct v4l2_format *f)
187{
188 struct emmaprp_fmt *fmt;
189 unsigned int k;
190
191 for (k = 0; k < NUM_FORMATS; k++) {
192 fmt = &formats[k];
193 if (fmt->fourcc == f->fmt.pix.pixelformat)
194 break;
195 }
196
197 if (k == NUM_FORMATS)
198 return NULL;
199
200 return &formats[k];
201}
202
203struct emmaprp_dev {
204 struct v4l2_device v4l2_dev;
205 struct video_device *vfd;
206
207 struct mutex dev_mutex;
208 spinlock_t irqlock;
209
210 int irq_emma;
211 void __iomem *base_emma;
212 struct clk *clk_emma_ahb, *clk_emma_ipg;
213 struct resource *res_emma;
214
215 struct v4l2_m2m_dev *m2m_dev;
216 struct vb2_alloc_ctx *alloc_ctx;
217};
218
219struct emmaprp_ctx {
220 struct emmaprp_dev *dev;
221 /* Abort requested by m2m */
222 int aborting;
223 struct emmaprp_q_data q_data[2];
224 struct v4l2_m2m_ctx *m2m_ctx;
225};
226
227static struct emmaprp_q_data *get_q_data(struct emmaprp_ctx *ctx,
228 enum v4l2_buf_type type)
229{
230 switch (type) {
231 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
232 return &(ctx->q_data[V4L2_M2M_SRC]);
233 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
234 return &(ctx->q_data[V4L2_M2M_DST]);
235 default:
236 BUG();
237 }
238 return NULL;
239}
240
241/*
242 * mem2mem callbacks
243 */
244static void emmaprp_job_abort(void *priv)
245{
246 struct emmaprp_ctx *ctx = priv;
247 struct emmaprp_dev *pcdev = ctx->dev;
248
249 ctx->aborting = 1;
250
251 dprintk(pcdev, "Aborting task\n");
252
253 v4l2_m2m_job_finish(pcdev->m2m_dev, ctx->m2m_ctx);
254}
255
256static void emmaprp_lock(void *priv)
257{
258 struct emmaprp_ctx *ctx = priv;
259 struct emmaprp_dev *pcdev = ctx->dev;
260 mutex_lock(&pcdev->dev_mutex);
261}
262
263static void emmaprp_unlock(void *priv)
264{
265 struct emmaprp_ctx *ctx = priv;
266 struct emmaprp_dev *pcdev = ctx->dev;
267 mutex_unlock(&pcdev->dev_mutex);
268}
269
270static inline void emmaprp_dump_regs(struct emmaprp_dev *pcdev)
271{
272 dprintk(pcdev,
273 "eMMa-PrP Registers:\n"
274 " SOURCE_Y_PTR = 0x%08X\n"
275 " SRC_FRAME_SIZE = 0x%08X\n"
276 " DEST_Y_PTR = 0x%08X\n"
277 " DEST_CR_PTR = 0x%08X\n"
278 " DEST_CB_PTR = 0x%08X\n"
279 " CH2_OUT_IMAGE_SIZE = 0x%08X\n"
280 " CNTL = 0x%08X\n",
281 readl(pcdev->base_emma + PRP_SOURCE_Y_PTR),
282 readl(pcdev->base_emma + PRP_SRC_FRAME_SIZE),
283 readl(pcdev->base_emma + PRP_DEST_Y_PTR),
284 readl(pcdev->base_emma + PRP_DEST_CR_PTR),
285 readl(pcdev->base_emma + PRP_DEST_CB_PTR),
286 readl(pcdev->base_emma + PRP_CH2_OUT_IMAGE_SIZE),
287 readl(pcdev->base_emma + PRP_CNTL));
288}
289
290static void emmaprp_device_run(void *priv)
291{
292 struct emmaprp_ctx *ctx = priv;
293 struct emmaprp_q_data *s_q_data, *d_q_data;
294 struct vb2_buffer *src_buf, *dst_buf;
295 struct emmaprp_dev *pcdev = ctx->dev;
296 unsigned int s_width, s_height;
297 unsigned int d_width, d_height;
298 unsigned int d_size;
299 dma_addr_t p_in, p_out;
300 u32 tmp;
301
302 src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
303 dst_buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
304
305 s_q_data = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
306 s_width = s_q_data->width;
307 s_height = s_q_data->height;
308
309 d_q_data = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
310 d_width = d_q_data->width;
311 d_height = d_q_data->height;
312 d_size = d_width * d_height;
313
314 p_in = vb2_dma_contig_plane_dma_addr(src_buf, 0);
315 p_out = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
316 if (!p_in || !p_out) {
317 v4l2_err(&pcdev->v4l2_dev,
318 "Acquiring kernel pointers to buffers failed\n");
319 return;
320 }
321
322 /* Input frame parameters */
323 writel(p_in, pcdev->base_emma + PRP_SOURCE_Y_PTR);
324 writel(PRP_SIZE_WIDTH(s_width) | PRP_SIZE_HEIGHT(s_height),
325 pcdev->base_emma + PRP_SRC_FRAME_SIZE);
326
327 /* Output frame parameters */
328 writel(p_out, pcdev->base_emma + PRP_DEST_Y_PTR);
329 writel(p_out + d_size, pcdev->base_emma + PRP_DEST_CB_PTR);
330 writel(p_out + d_size + (d_size >> 2),
331 pcdev->base_emma + PRP_DEST_CR_PTR);
332 writel(PRP_SIZE_WIDTH(d_width) | PRP_SIZE_HEIGHT(d_height),
333 pcdev->base_emma + PRP_CH2_OUT_IMAGE_SIZE);
334
335 /* IRQ configuration */
336 tmp = readl(pcdev->base_emma + PRP_INTR_CNTL);
337 writel(tmp | PRP_INTR_RDERR |
338 PRP_INTR_CH2WERR |
339 PRP_INTR_CH2FC,
340 pcdev->base_emma + PRP_INTR_CNTL);
341
342 emmaprp_dump_regs(pcdev);
343
344 /* Enable transfer */
345 tmp = readl(pcdev->base_emma + PRP_CNTL);
346 writel(tmp | PRP_CNTL_CH2_OUT_YUV420 |
347 PRP_CNTL_DATA_IN_YUV422 |
348 PRP_CNTL_CH2EN,
349 pcdev->base_emma + PRP_CNTL);
350}
351
352static irqreturn_t emmaprp_irq(int irq_emma, void *data)
353{
354 struct emmaprp_dev *pcdev = data;
355 struct emmaprp_ctx *curr_ctx;
356 struct vb2_buffer *src_vb, *dst_vb;
357 unsigned long flags;
358 u32 irqst;
359
360 /* Check irq flags and clear irq */
361 irqst = readl(pcdev->base_emma + PRP_INTRSTATUS);
362 writel(irqst, pcdev->base_emma + PRP_INTRSTATUS);
363 dprintk(pcdev, "irqst = 0x%08x\n", irqst);
364
365 curr_ctx = v4l2_m2m_get_curr_priv(pcdev->m2m_dev);
366 if (curr_ctx == NULL) {
367 pr_err("Instance released before the end of transaction\n");
368 return IRQ_HANDLED;
369 }
370
371 if (!curr_ctx->aborting) {
372 if ((irqst & PRP_INTR_ST_RDERR) ||
373 (irqst & PRP_INTR_ST_CH2WERR)) {
374 pr_err("PrP bus error ocurred, this transfer is probably corrupted\n");
375 writel(PRP_CNTL_SWRST, pcdev->base_emma + PRP_CNTL);
376 } else if (irqst & PRP_INTR_ST_CH2B1CI) { /* buffer ready */
377 src_vb = v4l2_m2m_src_buf_remove(curr_ctx->m2m_ctx);
378 dst_vb = v4l2_m2m_dst_buf_remove(curr_ctx->m2m_ctx);
379
380 spin_lock_irqsave(&pcdev->irqlock, flags);
381 v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_DONE);
382 v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_DONE);
383 spin_unlock_irqrestore(&pcdev->irqlock, flags);
384 }
385 }
386
387 v4l2_m2m_job_finish(pcdev->m2m_dev, curr_ctx->m2m_ctx);
388 return IRQ_HANDLED;
389}
390
391/*
392 * video ioctls
393 */
394static int vidioc_querycap(struct file *file, void *priv,
395 struct v4l2_capability *cap)
396{
397 strncpy(cap->driver, MEM2MEM_NAME, sizeof(cap->driver) - 1);
398 strncpy(cap->card, MEM2MEM_NAME, sizeof(cap->card) - 1);
399 /*
400 * This is only a mem-to-mem video device. The capture and output
401 * device capability flags are left only for backward compatibility
402 * and are scheduled for removal.
403 */
404 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT |
405 V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING;
406 return 0;
407}
408
409static int enum_fmt(struct v4l2_fmtdesc *f, u32 type)
410{
411 int i, num;
412 struct emmaprp_fmt *fmt;
413
414 num = 0;
415
416 for (i = 0; i < NUM_FORMATS; ++i) {
417 if (formats[i].types & type) {
418 /* index-th format of type type found ? */
419 if (num == f->index)
420 break;
421 /* Correct type but haven't reached our index yet,
422 * just increment per-type index */
423 ++num;
424 }
425 }
426
427 if (i < NUM_FORMATS) {
428 /* Format found */
429 fmt = &formats[i];
430 strlcpy(f->description, fmt->name, sizeof(f->description) - 1);
431 f->pixelformat = fmt->fourcc;
432 return 0;
433 }
434
435 /* Format not found */
436 return -EINVAL;
437}
438
439static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
440 struct v4l2_fmtdesc *f)
441{
442 return enum_fmt(f, MEM2MEM_CAPTURE);
443}
444
445static int vidioc_enum_fmt_vid_out(struct file *file, void *priv,
446 struct v4l2_fmtdesc *f)
447{
448 return enum_fmt(f, MEM2MEM_OUTPUT);
449}
450
451static int vidioc_g_fmt(struct emmaprp_ctx *ctx, struct v4l2_format *f)
452{
453 struct vb2_queue *vq;
454 struct emmaprp_q_data *q_data;
455
456 vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
457 if (!vq)
458 return -EINVAL;
459
460 q_data = get_q_data(ctx, f->type);
461
462 f->fmt.pix.width = q_data->width;
463 f->fmt.pix.height = q_data->height;
464 f->fmt.pix.field = V4L2_FIELD_NONE;
465 f->fmt.pix.pixelformat = q_data->fmt->fourcc;
466 if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUV420)
467 f->fmt.pix.bytesperline = q_data->width * 3 / 2;
468 else /* YUYV */
469 f->fmt.pix.bytesperline = q_data->width * 2;
470 f->fmt.pix.sizeimage = q_data->sizeimage;
471
472 return 0;
473}
474
475static int vidioc_g_fmt_vid_out(struct file *file, void *priv,
476 struct v4l2_format *f)
477{
478 return vidioc_g_fmt(priv, f);
479}
480
481static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
482 struct v4l2_format *f)
483{
484 return vidioc_g_fmt(priv, f);
485}
486
487static int vidioc_try_fmt(struct v4l2_format *f)
488{
489 enum v4l2_field field;
490
491
492 if (!find_format(f))
493 return -EINVAL;
494
495 field = f->fmt.pix.field;
496 if (field == V4L2_FIELD_ANY)
497 field = V4L2_FIELD_NONE;
498 else if (V4L2_FIELD_NONE != field)
499 return -EINVAL;
500
501 /* V4L2 specification suggests the driver corrects the format struct
502 * if any of the dimensions is unsupported */
503 f->fmt.pix.field = field;
504
505 if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUV420) {
506 v4l_bound_align_image(&f->fmt.pix.width, MIN_W, MAX_W,
507 W_ALIGN_YUV420, &f->fmt.pix.height,
508 MIN_H, MAX_H, H_ALIGN, S_ALIGN);
509 f->fmt.pix.bytesperline = f->fmt.pix.width * 3 / 2;
510 } else {
511 v4l_bound_align_image(&f->fmt.pix.width, MIN_W, MAX_W,
512 W_ALIGN_OTHERS, &f->fmt.pix.height,
513 MIN_H, MAX_H, H_ALIGN, S_ALIGN);
514 f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
515 }
516 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
517
518 return 0;
519}
520
521static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
522 struct v4l2_format *f)
523{
524 struct emmaprp_fmt *fmt;
525 struct emmaprp_ctx *ctx = priv;
526
527 fmt = find_format(f);
528 if (!fmt || !(fmt->types & MEM2MEM_CAPTURE)) {
529 v4l2_err(&ctx->dev->v4l2_dev,
530 "Fourcc format (0x%08x) invalid.\n",
531 f->fmt.pix.pixelformat);
532 return -EINVAL;
533 }
534
535 return vidioc_try_fmt(f);
536}
537
538static int vidioc_try_fmt_vid_out(struct file *file, void *priv,
539 struct v4l2_format *f)
540{
541 struct emmaprp_fmt *fmt;
542 struct emmaprp_ctx *ctx = priv;
543
544 fmt = find_format(f);
545 if (!fmt || !(fmt->types & MEM2MEM_OUTPUT)) {
546 v4l2_err(&ctx->dev->v4l2_dev,
547 "Fourcc format (0x%08x) invalid.\n",
548 f->fmt.pix.pixelformat);
549 return -EINVAL;
550 }
551
552 return vidioc_try_fmt(f);
553}
554
555static int vidioc_s_fmt(struct emmaprp_ctx *ctx, struct v4l2_format *f)
556{
557 struct emmaprp_q_data *q_data;
558 struct vb2_queue *vq;
559 int ret;
560
561 vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
562 if (!vq)
563 return -EINVAL;
564
565 q_data = get_q_data(ctx, f->type);
566 if (!q_data)
567 return -EINVAL;
568
569 if (vb2_is_busy(vq)) {
570 v4l2_err(&ctx->dev->v4l2_dev, "%s queue busy\n", __func__);
571 return -EBUSY;
572 }
573
574 ret = vidioc_try_fmt(f);
575 if (ret)
576 return ret;
577
578 q_data->fmt = find_format(f);
579 q_data->width = f->fmt.pix.width;
580 q_data->height = f->fmt.pix.height;
581 if (q_data->fmt->fourcc == V4L2_PIX_FMT_YUV420)
582 q_data->sizeimage = q_data->width * q_data->height * 3 / 2;
583 else /* YUYV */
584 q_data->sizeimage = q_data->width * q_data->height * 2;
585
586 dprintk(ctx->dev,
587 "Setting format for type %d, wxh: %dx%d, fmt: %d\n",
588 f->type, q_data->width, q_data->height, q_data->fmt->fourcc);
589
590 return 0;
591}
592
593static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
594 struct v4l2_format *f)
595{
596 int ret;
597
598 ret = vidioc_try_fmt_vid_cap(file, priv, f);
599 if (ret)
600 return ret;
601
602 return vidioc_s_fmt(priv, f);
603}
604
605static int vidioc_s_fmt_vid_out(struct file *file, void *priv,
606 struct v4l2_format *f)
607{
608 int ret;
609
610 ret = vidioc_try_fmt_vid_out(file, priv, f);
611 if (ret)
612 return ret;
613
614 return vidioc_s_fmt(priv, f);
615}
616
617static int vidioc_reqbufs(struct file *file, void *priv,
618 struct v4l2_requestbuffers *reqbufs)
619{
620 struct emmaprp_ctx *ctx = priv;
621
622 return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs);
623}
624
625static int vidioc_querybuf(struct file *file, void *priv,
626 struct v4l2_buffer *buf)
627{
628 struct emmaprp_ctx *ctx = priv;
629
630 return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf);
631}
632
633static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
634{
635 struct emmaprp_ctx *ctx = priv;
636
637 return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
638}
639
640static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
641{
642 struct emmaprp_ctx *ctx = priv;
643
644 return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
645}
646
647static int vidioc_streamon(struct file *file, void *priv,
648 enum v4l2_buf_type type)
649{
650 struct emmaprp_ctx *ctx = priv;
651
652 return v4l2_m2m_streamon(file, ctx->m2m_ctx, type);
653}
654
655static int vidioc_streamoff(struct file *file, void *priv,
656 enum v4l2_buf_type type)
657{
658 struct emmaprp_ctx *ctx = priv;
659
660 return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type);
661}
662
663static const struct v4l2_ioctl_ops emmaprp_ioctl_ops = {
664 .vidioc_querycap = vidioc_querycap,
665
666 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
667 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
668 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
669 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
670
671 .vidioc_enum_fmt_vid_out = vidioc_enum_fmt_vid_out,
672 .vidioc_g_fmt_vid_out = vidioc_g_fmt_vid_out,
673 .vidioc_try_fmt_vid_out = vidioc_try_fmt_vid_out,
674 .vidioc_s_fmt_vid_out = vidioc_s_fmt_vid_out,
675
676 .vidioc_reqbufs = vidioc_reqbufs,
677 .vidioc_querybuf = vidioc_querybuf,
678
679 .vidioc_qbuf = vidioc_qbuf,
680 .vidioc_dqbuf = vidioc_dqbuf,
681
682 .vidioc_streamon = vidioc_streamon,
683 .vidioc_streamoff = vidioc_streamoff,
684};
685
686
687/*
688 * Queue operations
689 */
690static int emmaprp_queue_setup(struct vb2_queue *vq,
691 const struct v4l2_format *fmt,
692 unsigned int *nbuffers, unsigned int *nplanes,
693 unsigned int sizes[], void *alloc_ctxs[])
694{
695 struct emmaprp_ctx *ctx = vb2_get_drv_priv(vq);
696 struct emmaprp_q_data *q_data;
697 unsigned int size, count = *nbuffers;
698
699 q_data = get_q_data(ctx, vq->type);
700
701 if (q_data->fmt->fourcc == V4L2_PIX_FMT_YUV420)
702 size = q_data->width * q_data->height * 3 / 2;
703 else
704 size = q_data->width * q_data->height * 2;
705
706 while (size * count > MEM2MEM_VID_MEM_LIMIT)
707 (count)--;
708
709 *nplanes = 1;
710 *nbuffers = count;
711 sizes[0] = size;
712
713 alloc_ctxs[0] = ctx->dev->alloc_ctx;
714
715 dprintk(ctx->dev, "get %d buffer(s) of size %d each.\n", count, size);
716
717 return 0;
718}
719
720static int emmaprp_buf_prepare(struct vb2_buffer *vb)
721{
722 struct emmaprp_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
723 struct emmaprp_q_data *q_data;
724
725 dprintk(ctx->dev, "type: %d\n", vb->vb2_queue->type);
726
727 q_data = get_q_data(ctx, vb->vb2_queue->type);
728
729 if (vb2_plane_size(vb, 0) < q_data->sizeimage) {
730 dprintk(ctx->dev, "%s data will not fit into plane"
731 "(%lu < %lu)\n", __func__,
732 vb2_plane_size(vb, 0),
733 (long)q_data->sizeimage);
734 return -EINVAL;
735 }
736
737 vb2_set_plane_payload(vb, 0, q_data->sizeimage);
738
739 return 0;
740}
741
742static void emmaprp_buf_queue(struct vb2_buffer *vb)
743{
744 struct emmaprp_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
745 v4l2_m2m_buf_queue(ctx->m2m_ctx, vb);
746}
747
748static struct vb2_ops emmaprp_qops = {
749 .queue_setup = emmaprp_queue_setup,
750 .buf_prepare = emmaprp_buf_prepare,
751 .buf_queue = emmaprp_buf_queue,
752};
753
754static int queue_init(void *priv, struct vb2_queue *src_vq,
755 struct vb2_queue *dst_vq)
756{
757 struct emmaprp_ctx *ctx = priv;
758 int ret;
759
760 memset(src_vq, 0, sizeof(*src_vq));
761 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
762 src_vq->io_modes = VB2_MMAP | VB2_USERPTR;
763 src_vq->drv_priv = ctx;
764 src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
765 src_vq->ops = &emmaprp_qops;
766 src_vq->mem_ops = &vb2_dma_contig_memops;
767
768 ret = vb2_queue_init(src_vq);
769 if (ret)
770 return ret;
771
772 memset(dst_vq, 0, sizeof(*dst_vq));
773 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
774 dst_vq->io_modes = VB2_MMAP | VB2_USERPTR;
775 dst_vq->drv_priv = ctx;
776 dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
777 dst_vq->ops = &emmaprp_qops;
778 dst_vq->mem_ops = &vb2_dma_contig_memops;
779
780 return vb2_queue_init(dst_vq);
781}
782
783/*
784 * File operations
785 */
786static int emmaprp_open(struct file *file)
787{
788 struct emmaprp_dev *pcdev = video_drvdata(file);
789 struct emmaprp_ctx *ctx;
790
791 ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
792 if (!ctx)
793 return -ENOMEM;
794
795 file->private_data = ctx;
796 ctx->dev = pcdev;
797
798 if (mutex_lock_interruptible(&pcdev->dev_mutex)) {
799 kfree(ctx);
800 return -ERESTARTSYS;
801 }
802
803 ctx->m2m_ctx = v4l2_m2m_ctx_init(pcdev->m2m_dev, ctx, &queue_init);
804
805 if (IS_ERR(ctx->m2m_ctx)) {
806 int ret = PTR_ERR(ctx->m2m_ctx);
807
808 mutex_unlock(&pcdev->dev_mutex);
809 kfree(ctx);
810 return ret;
811 }
812
813 clk_prepare_enable(pcdev->clk_emma_ipg);
814 clk_prepare_enable(pcdev->clk_emma_ahb);
815 ctx->q_data[V4L2_M2M_SRC].fmt = &formats[1];
816 ctx->q_data[V4L2_M2M_DST].fmt = &formats[0];
817 mutex_unlock(&pcdev->dev_mutex);
818
819 dprintk(pcdev, "Created instance %p, m2m_ctx: %p\n", ctx, ctx->m2m_ctx);
820
821 return 0;
822}
823
824static int emmaprp_release(struct file *file)
825{
826 struct emmaprp_dev *pcdev = video_drvdata(file);
827 struct emmaprp_ctx *ctx = file->private_data;
828
829 dprintk(pcdev, "Releasing instance %p\n", ctx);
830
831 mutex_lock(&pcdev->dev_mutex);
832 clk_disable_unprepare(pcdev->clk_emma_ahb);
833 clk_disable_unprepare(pcdev->clk_emma_ipg);
834 v4l2_m2m_ctx_release(ctx->m2m_ctx);
835 mutex_unlock(&pcdev->dev_mutex);
836 kfree(ctx);
837
838 return 0;
839}
840
841static unsigned int emmaprp_poll(struct file *file,
842 struct poll_table_struct *wait)
843{
844 struct emmaprp_dev *pcdev = video_drvdata(file);
845 struct emmaprp_ctx *ctx = file->private_data;
846 unsigned int res;
847
848 mutex_lock(&pcdev->dev_mutex);
849 res = v4l2_m2m_poll(file, ctx->m2m_ctx, wait);
850 mutex_unlock(&pcdev->dev_mutex);
851 return res;
852}
853
854static int emmaprp_mmap(struct file *file, struct vm_area_struct *vma)
855{
856 struct emmaprp_dev *pcdev = video_drvdata(file);
857 struct emmaprp_ctx *ctx = file->private_data;
858 int ret;
859
860 if (mutex_lock_interruptible(&pcdev->dev_mutex))
861 return -ERESTARTSYS;
862 ret = v4l2_m2m_mmap(file, ctx->m2m_ctx, vma);
863 mutex_unlock(&pcdev->dev_mutex);
864 return ret;
865}
866
867static const struct v4l2_file_operations emmaprp_fops = {
868 .owner = THIS_MODULE,
869 .open = emmaprp_open,
870 .release = emmaprp_release,
871 .poll = emmaprp_poll,
872 .unlocked_ioctl = video_ioctl2,
873 .mmap = emmaprp_mmap,
874};
875
876static struct video_device emmaprp_videodev = {
877 .name = MEM2MEM_NAME,
878 .fops = &emmaprp_fops,
879 .ioctl_ops = &emmaprp_ioctl_ops,
880 .minor = -1,
881 .release = video_device_release,
882};
883
884static struct v4l2_m2m_ops m2m_ops = {
885 .device_run = emmaprp_device_run,
886 .job_abort = emmaprp_job_abort,
887 .lock = emmaprp_lock,
888 .unlock = emmaprp_unlock,
889};
890
891static int emmaprp_probe(struct platform_device *pdev)
892{
893 struct emmaprp_dev *pcdev;
894 struct video_device *vfd;
895 struct resource *res_emma;
896 int irq_emma;
897 int ret;
898
899 pcdev = kzalloc(sizeof *pcdev, GFP_KERNEL);
900 if (!pcdev)
901 return -ENOMEM;
902
903 spin_lock_init(&pcdev->irqlock);
904
905 pcdev->clk_emma_ipg = devm_clk_get(&pdev->dev, "ipg");
906 if (IS_ERR(pcdev->clk_emma_ipg)) {
907 ret = PTR_ERR(pcdev->clk_emma_ipg);
908 goto free_dev;
909 }
910
911 pcdev->clk_emma_ahb = devm_clk_get(&pdev->dev, "ahb");
912 if (IS_ERR(pcdev->clk_emma_ipg)) {
913 ret = PTR_ERR(pcdev->clk_emma_ahb);
914 goto free_dev;
915 }
916
917 irq_emma = platform_get_irq(pdev, 0);
918 res_emma = platform_get_resource(pdev, IORESOURCE_MEM, 0);
919 if (irq_emma < 0 || res_emma == NULL) {
920 dev_err(&pdev->dev, "Missing platform resources data\n");
921 ret = -ENODEV;
922 goto free_dev;
923 }
924
925 ret = v4l2_device_register(&pdev->dev, &pcdev->v4l2_dev);
926 if (ret)
927 goto free_dev;
928
929 mutex_init(&pcdev->dev_mutex);
930
931 vfd = video_device_alloc();
932 if (!vfd) {
933 v4l2_err(&pcdev->v4l2_dev, "Failed to allocate video device\n");
934 ret = -ENOMEM;
935 goto unreg_dev;
936 }
937
938 *vfd = emmaprp_videodev;
939 vfd->lock = &pcdev->dev_mutex;
940
941 video_set_drvdata(vfd, pcdev);
942 snprintf(vfd->name, sizeof(vfd->name), "%s", emmaprp_videodev.name);
943 pcdev->vfd = vfd;
944 v4l2_info(&pcdev->v4l2_dev, EMMAPRP_MODULE_NAME
945 " Device registered as /dev/video%d\n", vfd->num);
946
947 platform_set_drvdata(pdev, pcdev);
948
949 if (devm_request_mem_region(&pdev->dev, res_emma->start,
950 resource_size(res_emma), MEM2MEM_NAME) == NULL)
951 goto rel_vdev;
952
953 pcdev->base_emma = devm_ioremap(&pdev->dev, res_emma->start,
954 resource_size(res_emma));
955 if (!pcdev->base_emma)
956 goto rel_vdev;
957
958 pcdev->irq_emma = irq_emma;
959 pcdev->res_emma = res_emma;
960
961 if (devm_request_irq(&pdev->dev, pcdev->irq_emma, emmaprp_irq,
962 0, MEM2MEM_NAME, pcdev) < 0)
963 goto rel_vdev;
964
965 pcdev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
966 if (IS_ERR(pcdev->alloc_ctx)) {
967 v4l2_err(&pcdev->v4l2_dev, "Failed to alloc vb2 context\n");
968 ret = PTR_ERR(pcdev->alloc_ctx);
969 goto rel_vdev;
970 }
971
972 pcdev->m2m_dev = v4l2_m2m_init(&m2m_ops);
973 if (IS_ERR(pcdev->m2m_dev)) {
974 v4l2_err(&pcdev->v4l2_dev, "Failed to init mem2mem device\n");
975 ret = PTR_ERR(pcdev->m2m_dev);
976 goto rel_ctx;
977 }
978
979 ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
980 if (ret) {
981 v4l2_err(&pcdev->v4l2_dev, "Failed to register video device\n");
982 goto rel_m2m;
983 }
984
985 return 0;
986
987
988rel_m2m:
989 v4l2_m2m_release(pcdev->m2m_dev);
990rel_ctx:
991 vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx);
992rel_vdev:
993 video_device_release(vfd);
994unreg_dev:
995 v4l2_device_unregister(&pcdev->v4l2_dev);
996free_dev:
997 kfree(pcdev);
998
999 return ret;
1000}
1001
1002static int emmaprp_remove(struct platform_device *pdev)
1003{
1004 struct emmaprp_dev *pcdev = platform_get_drvdata(pdev);
1005
1006 v4l2_info(&pcdev->v4l2_dev, "Removing " EMMAPRP_MODULE_NAME);
1007
1008 video_unregister_device(pcdev->vfd);
1009 v4l2_m2m_release(pcdev->m2m_dev);
1010 vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx);
1011 v4l2_device_unregister(&pcdev->v4l2_dev);
1012 kfree(pcdev);
1013
1014 return 0;
1015}
1016
1017static struct platform_driver emmaprp_pdrv = {
1018 .probe = emmaprp_probe,
1019 .remove = emmaprp_remove,
1020 .driver = {
1021 .name = MEM2MEM_NAME,
1022 .owner = THIS_MODULE,
1023 },
1024};
1025
1026static void __exit emmaprp_exit(void)
1027{
1028 platform_driver_unregister(&emmaprp_pdrv);
1029}
1030
1031static int __init emmaprp_init(void)
1032{
1033 return platform_driver_register(&emmaprp_pdrv);
1034}
1035
1036module_init(emmaprp_init);
1037module_exit(emmaprp_exit);
diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c
deleted file mode 100644
index f13643d31353..000000000000
--- a/drivers/media/video/mx3_camera.c
+++ /dev/null
@@ -1,1300 +0,0 @@
1/*
2 * V4L2 Driver for i.MX3x camera host
3 *
4 * Copyright (C) 2008
5 * Guennadi Liakhovetski, DENX Software Engineering, <lg@denx.de>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/init.h>
13#include <linux/module.h>
14#include <linux/videodev2.h>
15#include <linux/platform_device.h>
16#include <linux/clk.h>
17#include <linux/vmalloc.h>
18#include <linux/interrupt.h>
19#include <linux/sched.h>
20
21#include <media/v4l2-common.h>
22#include <media/v4l2-dev.h>
23#include <media/videobuf2-dma-contig.h>
24#include <media/soc_camera.h>
25#include <media/soc_mediabus.h>
26
27#include <mach/ipu.h>
28#include <mach/mx3_camera.h>
29#include <mach/dma.h>
30
31#define MX3_CAM_DRV_NAME "mx3-camera"
32
33/* CMOS Sensor Interface Registers */
34#define CSI_REG_START 0x60
35
36#define CSI_SENS_CONF (0x60 - CSI_REG_START)
37#define CSI_SENS_FRM_SIZE (0x64 - CSI_REG_START)
38#define CSI_ACT_FRM_SIZE (0x68 - CSI_REG_START)
39#define CSI_OUT_FRM_CTRL (0x6C - CSI_REG_START)
40#define CSI_TST_CTRL (0x70 - CSI_REG_START)
41#define CSI_CCIR_CODE_1 (0x74 - CSI_REG_START)
42#define CSI_CCIR_CODE_2 (0x78 - CSI_REG_START)
43#define CSI_CCIR_CODE_3 (0x7C - CSI_REG_START)
44#define CSI_FLASH_STROBE_1 (0x80 - CSI_REG_START)
45#define CSI_FLASH_STROBE_2 (0x84 - CSI_REG_START)
46
47#define CSI_SENS_CONF_VSYNC_POL_SHIFT 0
48#define CSI_SENS_CONF_HSYNC_POL_SHIFT 1
49#define CSI_SENS_CONF_DATA_POL_SHIFT 2
50#define CSI_SENS_CONF_PIX_CLK_POL_SHIFT 3
51#define CSI_SENS_CONF_SENS_PRTCL_SHIFT 4
52#define CSI_SENS_CONF_SENS_CLKSRC_SHIFT 7
53#define CSI_SENS_CONF_DATA_FMT_SHIFT 8
54#define CSI_SENS_CONF_DATA_WIDTH_SHIFT 10
55#define CSI_SENS_CONF_EXT_VSYNC_SHIFT 15
56#define CSI_SENS_CONF_DIVRATIO_SHIFT 16
57
58#define CSI_SENS_CONF_DATA_FMT_RGB_YUV444 (0UL << CSI_SENS_CONF_DATA_FMT_SHIFT)
59#define CSI_SENS_CONF_DATA_FMT_YUV422 (2UL << CSI_SENS_CONF_DATA_FMT_SHIFT)
60#define CSI_SENS_CONF_DATA_FMT_BAYER (3UL << CSI_SENS_CONF_DATA_FMT_SHIFT)
61
62#define MAX_VIDEO_MEM 16
63
64enum csi_buffer_state {
65 CSI_BUF_NEEDS_INIT,
66 CSI_BUF_PREPARED,
67};
68
69struct mx3_camera_buffer {
70 /* common v4l buffer stuff -- must be first */
71 struct vb2_buffer vb;
72 enum csi_buffer_state state;
73 struct list_head queue;
74
75 /* One descriptot per scatterlist (per frame) */
76 struct dma_async_tx_descriptor *txd;
77
78 /* We have to "build" a scatterlist ourselves - one element per frame */
79 struct scatterlist sg;
80};
81
82/**
83 * struct mx3_camera_dev - i.MX3x camera (CSI) object
84 * @dev: camera device, to which the coherent buffer is attached
85 * @icd: currently attached camera sensor
86 * @clk: pointer to clock
87 * @base: remapped register base address
88 * @pdata: platform data
89 * @platform_flags: platform flags
90 * @mclk: master clock frequency in Hz
91 * @capture: list of capture videobuffers
92 * @lock: protects video buffer lists
93 * @active: active video buffer
94 * @idmac_channel: array of pointers to IPU DMAC DMA channels
95 * @soc_host: embedded soc_host object
96 */
97struct mx3_camera_dev {
98 /*
99 * i.MX3x is only supposed to handle one camera on its Camera Sensor
100 * Interface. If anyone ever builds hardware to enable more than one
101 * camera _simultaneously_, they will have to modify this driver too
102 */
103 struct soc_camera_device *icd;
104 struct clk *clk;
105
106 void __iomem *base;
107
108 struct mx3_camera_pdata *pdata;
109
110 unsigned long platform_flags;
111 unsigned long mclk;
112 u16 width_flags; /* max 15 bits */
113
114 struct list_head capture;
115 spinlock_t lock; /* Protects video buffer lists */
116 struct mx3_camera_buffer *active;
117 size_t buf_total;
118 struct vb2_alloc_ctx *alloc_ctx;
119 enum v4l2_field field;
120 int sequence;
121
122 /* IDMAC / dmaengine interface */
123 struct idmac_channel *idmac_channel[1]; /* We need one channel */
124
125 struct soc_camera_host soc_host;
126};
127
128struct dma_chan_request {
129 struct mx3_camera_dev *mx3_cam;
130 enum ipu_channel id;
131};
132
133static u32 csi_reg_read(struct mx3_camera_dev *mx3, off_t reg)
134{
135 return __raw_readl(mx3->base + reg);
136}
137
138static void csi_reg_write(struct mx3_camera_dev *mx3, u32 value, off_t reg)
139{
140 __raw_writel(value, mx3->base + reg);
141}
142
143static struct mx3_camera_buffer *to_mx3_vb(struct vb2_buffer *vb)
144{
145 return container_of(vb, struct mx3_camera_buffer, vb);
146}
147
148/* Called from the IPU IDMAC ISR */
149static void mx3_cam_dma_done(void *arg)
150{
151 struct idmac_tx_desc *desc = to_tx_desc(arg);
152 struct dma_chan *chan = desc->txd.chan;
153 struct idmac_channel *ichannel = to_idmac_chan(chan);
154 struct mx3_camera_dev *mx3_cam = ichannel->client;
155
156 dev_dbg(chan->device->dev, "callback cookie %d, active DMA 0x%08x\n",
157 desc->txd.cookie, mx3_cam->active ? sg_dma_address(&mx3_cam->active->sg) : 0);
158
159 spin_lock(&mx3_cam->lock);
160 if (mx3_cam->active) {
161 struct vb2_buffer *vb = &mx3_cam->active->vb;
162 struct mx3_camera_buffer *buf = to_mx3_vb(vb);
163
164 list_del_init(&buf->queue);
165 do_gettimeofday(&vb->v4l2_buf.timestamp);
166 vb->v4l2_buf.field = mx3_cam->field;
167 vb->v4l2_buf.sequence = mx3_cam->sequence++;
168 vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
169 }
170
171 if (list_empty(&mx3_cam->capture)) {
172 mx3_cam->active = NULL;
173 spin_unlock(&mx3_cam->lock);
174
175 /*
176 * stop capture - without further buffers IPU_CHA_BUF0_RDY will
177 * not get updated
178 */
179 return;
180 }
181
182 mx3_cam->active = list_entry(mx3_cam->capture.next,
183 struct mx3_camera_buffer, queue);
184 spin_unlock(&mx3_cam->lock);
185}
186
187/*
188 * Videobuf operations
189 */
190
191/*
192 * Calculate the __buffer__ (not data) size and number of buffers.
193 */
194static int mx3_videobuf_setup(struct vb2_queue *vq,
195 const struct v4l2_format *fmt,
196 unsigned int *count, unsigned int *num_planes,
197 unsigned int sizes[], void *alloc_ctxs[])
198{
199 struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
200 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
201 struct mx3_camera_dev *mx3_cam = ici->priv;
202
203 if (!mx3_cam->idmac_channel[0])
204 return -EINVAL;
205
206 if (fmt) {
207 const struct soc_camera_format_xlate *xlate = soc_camera_xlate_by_fourcc(icd,
208 fmt->fmt.pix.pixelformat);
209 unsigned int bytes_per_line;
210 int ret;
211
212 if (!xlate)
213 return -EINVAL;
214
215 ret = soc_mbus_bytes_per_line(fmt->fmt.pix.width,
216 xlate->host_fmt);
217 if (ret < 0)
218 return ret;
219
220 bytes_per_line = max_t(u32, fmt->fmt.pix.bytesperline, ret);
221
222 ret = soc_mbus_image_size(xlate->host_fmt, bytes_per_line,
223 fmt->fmt.pix.height);
224 if (ret < 0)
225 return ret;
226
227 sizes[0] = max_t(u32, fmt->fmt.pix.sizeimage, ret);
228 } else {
229 /* Called from VIDIOC_REQBUFS or in compatibility mode */
230 sizes[0] = icd->sizeimage;
231 }
232
233 alloc_ctxs[0] = mx3_cam->alloc_ctx;
234
235 if (!vq->num_buffers)
236 mx3_cam->sequence = 0;
237
238 if (!*count)
239 *count = 2;
240
241 /* If *num_planes != 0, we have already verified *count. */
242 if (!*num_planes &&
243 sizes[0] * *count + mx3_cam->buf_total > MAX_VIDEO_MEM * 1024 * 1024)
244 *count = (MAX_VIDEO_MEM * 1024 * 1024 - mx3_cam->buf_total) /
245 sizes[0];
246
247 *num_planes = 1;
248
249 return 0;
250}
251
252static enum pixel_fmt fourcc_to_ipu_pix(__u32 fourcc)
253{
254 /* Add more formats as need arises and test possibilities appear... */
255 switch (fourcc) {
256 case V4L2_PIX_FMT_RGB24:
257 return IPU_PIX_FMT_RGB24;
258 case V4L2_PIX_FMT_UYVY:
259 case V4L2_PIX_FMT_RGB565:
260 default:
261 return IPU_PIX_FMT_GENERIC;
262 }
263}
264
265static void mx3_videobuf_queue(struct vb2_buffer *vb)
266{
267 struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
268 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
269 struct mx3_camera_dev *mx3_cam = ici->priv;
270 struct mx3_camera_buffer *buf = to_mx3_vb(vb);
271 struct scatterlist *sg = &buf->sg;
272 struct dma_async_tx_descriptor *txd;
273 struct idmac_channel *ichan = mx3_cam->idmac_channel[0];
274 struct idmac_video_param *video = &ichan->params.video;
275 const struct soc_mbus_pixelfmt *host_fmt = icd->current_fmt->host_fmt;
276 unsigned long flags;
277 dma_cookie_t cookie;
278 size_t new_size;
279
280 new_size = icd->sizeimage;
281
282 if (vb2_plane_size(vb, 0) < new_size) {
283 dev_err(icd->parent, "Buffer #%d too small (%lu < %zu)\n",
284 vb->v4l2_buf.index, vb2_plane_size(vb, 0), new_size);
285 goto error;
286 }
287
288 if (buf->state == CSI_BUF_NEEDS_INIT) {
289 sg_dma_address(sg) = vb2_dma_contig_plane_dma_addr(vb, 0);
290 sg_dma_len(sg) = new_size;
291
292 txd = dmaengine_prep_slave_sg(
293 &ichan->dma_chan, sg, 1, DMA_DEV_TO_MEM,
294 DMA_PREP_INTERRUPT);
295 if (!txd)
296 goto error;
297
298 txd->callback_param = txd;
299 txd->callback = mx3_cam_dma_done;
300
301 buf->state = CSI_BUF_PREPARED;
302 buf->txd = txd;
303 } else {
304 txd = buf->txd;
305 }
306
307 vb2_set_plane_payload(vb, 0, new_size);
308
309 /* This is the configuration of one sg-element */
310 video->out_pixel_fmt = fourcc_to_ipu_pix(host_fmt->fourcc);
311
312 if (video->out_pixel_fmt == IPU_PIX_FMT_GENERIC) {
313 /*
314 * If the IPU DMA channel is configured to transfer generic
315 * 8-bit data, we have to set up the geometry parameters
316 * correctly, according to the current pixel format. The DMA
317 * horizontal parameters in this case are expressed in bytes,
318 * not in pixels.
319 */
320 video->out_width = icd->bytesperline;
321 video->out_height = icd->user_height;
322 video->out_stride = icd->bytesperline;
323 } else {
324 /*
325 * For IPU known formats the pixel unit will be managed
326 * successfully by the IPU code
327 */
328 video->out_width = icd->user_width;
329 video->out_height = icd->user_height;
330 video->out_stride = icd->user_width;
331 }
332
333#ifdef DEBUG
334 /* helps to see what DMA actually has written */
335 if (vb2_plane_vaddr(vb, 0))
336 memset(vb2_plane_vaddr(vb, 0), 0xaa, vb2_get_plane_payload(vb, 0));
337#endif
338
339 spin_lock_irqsave(&mx3_cam->lock, flags);
340 list_add_tail(&buf->queue, &mx3_cam->capture);
341
342 if (!mx3_cam->active)
343 mx3_cam->active = buf;
344
345 spin_unlock_irq(&mx3_cam->lock);
346
347 cookie = txd->tx_submit(txd);
348 dev_dbg(icd->parent, "Submitted cookie %d DMA 0x%08x\n",
349 cookie, sg_dma_address(&buf->sg));
350
351 if (cookie >= 0)
352 return;
353
354 spin_lock_irq(&mx3_cam->lock);
355
356 /* Submit error */
357 list_del_init(&buf->queue);
358
359 if (mx3_cam->active == buf)
360 mx3_cam->active = NULL;
361
362 spin_unlock_irqrestore(&mx3_cam->lock, flags);
363error:
364 vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
365}
366
367static void mx3_videobuf_release(struct vb2_buffer *vb)
368{
369 struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
370 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
371 struct mx3_camera_dev *mx3_cam = ici->priv;
372 struct mx3_camera_buffer *buf = to_mx3_vb(vb);
373 struct dma_async_tx_descriptor *txd = buf->txd;
374 unsigned long flags;
375
376 dev_dbg(icd->parent,
377 "Release%s DMA 0x%08x, queue %sempty\n",
378 mx3_cam->active == buf ? " active" : "", sg_dma_address(&buf->sg),
379 list_empty(&buf->queue) ? "" : "not ");
380
381 spin_lock_irqsave(&mx3_cam->lock, flags);
382
383 if (mx3_cam->active == buf)
384 mx3_cam->active = NULL;
385
386 /* Doesn't hurt also if the list is empty */
387 list_del_init(&buf->queue);
388 buf->state = CSI_BUF_NEEDS_INIT;
389
390 if (txd) {
391 buf->txd = NULL;
392 if (mx3_cam->idmac_channel[0])
393 async_tx_ack(txd);
394 }
395
396 spin_unlock_irqrestore(&mx3_cam->lock, flags);
397
398 mx3_cam->buf_total -= vb2_plane_size(vb, 0);
399}
400
401static int mx3_videobuf_init(struct vb2_buffer *vb)
402{
403 struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
404 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
405 struct mx3_camera_dev *mx3_cam = ici->priv;
406 struct mx3_camera_buffer *buf = to_mx3_vb(vb);
407
408 /* This is for locking debugging only */
409 INIT_LIST_HEAD(&buf->queue);
410 sg_init_table(&buf->sg, 1);
411
412 buf->state = CSI_BUF_NEEDS_INIT;
413
414 mx3_cam->buf_total += vb2_plane_size(vb, 0);
415
416 return 0;
417}
418
419static int mx3_stop_streaming(struct vb2_queue *q)
420{
421 struct soc_camera_device *icd = soc_camera_from_vb2q(q);
422 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
423 struct mx3_camera_dev *mx3_cam = ici->priv;
424 struct idmac_channel *ichan = mx3_cam->idmac_channel[0];
425 struct mx3_camera_buffer *buf, *tmp;
426 unsigned long flags;
427
428 if (ichan) {
429 struct dma_chan *chan = &ichan->dma_chan;
430 chan->device->device_control(chan, DMA_PAUSE, 0);
431 }
432
433 spin_lock_irqsave(&mx3_cam->lock, flags);
434
435 mx3_cam->active = NULL;
436
437 list_for_each_entry_safe(buf, tmp, &mx3_cam->capture, queue) {
438 list_del_init(&buf->queue);
439 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
440 }
441
442 spin_unlock_irqrestore(&mx3_cam->lock, flags);
443
444 return 0;
445}
446
447static struct vb2_ops mx3_videobuf_ops = {
448 .queue_setup = mx3_videobuf_setup,
449 .buf_queue = mx3_videobuf_queue,
450 .buf_cleanup = mx3_videobuf_release,
451 .buf_init = mx3_videobuf_init,
452 .wait_prepare = soc_camera_unlock,
453 .wait_finish = soc_camera_lock,
454 .stop_streaming = mx3_stop_streaming,
455};
456
457static int mx3_camera_init_videobuf(struct vb2_queue *q,
458 struct soc_camera_device *icd)
459{
460 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
461 q->io_modes = VB2_MMAP | VB2_USERPTR;
462 q->drv_priv = icd;
463 q->ops = &mx3_videobuf_ops;
464 q->mem_ops = &vb2_dma_contig_memops;
465 q->buf_struct_size = sizeof(struct mx3_camera_buffer);
466
467 return vb2_queue_init(q);
468}
469
470/* First part of ipu_csi_init_interface() */
471static void mx3_camera_activate(struct mx3_camera_dev *mx3_cam,
472 struct soc_camera_device *icd)
473{
474 u32 conf;
475 long rate;
476
477 /* Set default size: ipu_csi_set_window_size() */
478 csi_reg_write(mx3_cam, (640 - 1) | ((480 - 1) << 16), CSI_ACT_FRM_SIZE);
479 /* ...and position to 0:0: ipu_csi_set_window_pos() */
480 conf = csi_reg_read(mx3_cam, CSI_OUT_FRM_CTRL) & 0xffff0000;
481 csi_reg_write(mx3_cam, conf, CSI_OUT_FRM_CTRL);
482
483 /* We use only gated clock synchronisation mode so far */
484 conf = 0 << CSI_SENS_CONF_SENS_PRTCL_SHIFT;
485
486 /* Set generic data, platform-biggest bus-width */
487 conf |= CSI_SENS_CONF_DATA_FMT_BAYER;
488
489 if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_15)
490 conf |= 3 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
491 else if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_10)
492 conf |= 2 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
493 else if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_8)
494 conf |= 1 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
495 else/* if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_4)*/
496 conf |= 0 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
497
498 if (mx3_cam->platform_flags & MX3_CAMERA_CLK_SRC)
499 conf |= 1 << CSI_SENS_CONF_SENS_CLKSRC_SHIFT;
500 if (mx3_cam->platform_flags & MX3_CAMERA_EXT_VSYNC)
501 conf |= 1 << CSI_SENS_CONF_EXT_VSYNC_SHIFT;
502 if (mx3_cam->platform_flags & MX3_CAMERA_DP)
503 conf |= 1 << CSI_SENS_CONF_DATA_POL_SHIFT;
504 if (mx3_cam->platform_flags & MX3_CAMERA_PCP)
505 conf |= 1 << CSI_SENS_CONF_PIX_CLK_POL_SHIFT;
506 if (mx3_cam->platform_flags & MX3_CAMERA_HSP)
507 conf |= 1 << CSI_SENS_CONF_HSYNC_POL_SHIFT;
508 if (mx3_cam->platform_flags & MX3_CAMERA_VSP)
509 conf |= 1 << CSI_SENS_CONF_VSYNC_POL_SHIFT;
510
511 /* ipu_csi_init_interface() */
512 csi_reg_write(mx3_cam, conf, CSI_SENS_CONF);
513
514 clk_prepare_enable(mx3_cam->clk);
515 rate = clk_round_rate(mx3_cam->clk, mx3_cam->mclk);
516 dev_dbg(icd->parent, "Set SENS_CONF to %x, rate %ld\n", conf, rate);
517 if (rate)
518 clk_set_rate(mx3_cam->clk, rate);
519}
520
521/* Called with .video_lock held */
522static int mx3_camera_add_device(struct soc_camera_device *icd)
523{
524 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
525 struct mx3_camera_dev *mx3_cam = ici->priv;
526
527 if (mx3_cam->icd)
528 return -EBUSY;
529
530 mx3_camera_activate(mx3_cam, icd);
531
532 mx3_cam->buf_total = 0;
533 mx3_cam->icd = icd;
534
535 dev_info(icd->parent, "MX3 Camera driver attached to camera %d\n",
536 icd->devnum);
537
538 return 0;
539}
540
541/* Called with .video_lock held */
542static void mx3_camera_remove_device(struct soc_camera_device *icd)
543{
544 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
545 struct mx3_camera_dev *mx3_cam = ici->priv;
546 struct idmac_channel **ichan = &mx3_cam->idmac_channel[0];
547
548 BUG_ON(icd != mx3_cam->icd);
549
550 if (*ichan) {
551 dma_release_channel(&(*ichan)->dma_chan);
552 *ichan = NULL;
553 }
554
555 clk_disable_unprepare(mx3_cam->clk);
556
557 mx3_cam->icd = NULL;
558
559 dev_info(icd->parent, "MX3 Camera driver detached from camera %d\n",
560 icd->devnum);
561}
562
563static int test_platform_param(struct mx3_camera_dev *mx3_cam,
564 unsigned char buswidth, unsigned long *flags)
565{
566 /*
567 * If requested data width is supported by the platform, use it or any
568 * possible lower value - i.MX31 is smart enough to shift bits
569 */
570 if (buswidth > fls(mx3_cam->width_flags))
571 return -EINVAL;
572
573 /*
574 * Platform specified synchronization and pixel clock polarities are
575 * only a recommendation and are only used during probing. MX3x
576 * camera interface only works in master mode, i.e., uses HSYNC and
577 * VSYNC signals from the sensor
578 */
579 *flags = V4L2_MBUS_MASTER |
580 V4L2_MBUS_HSYNC_ACTIVE_HIGH |
581 V4L2_MBUS_HSYNC_ACTIVE_LOW |
582 V4L2_MBUS_VSYNC_ACTIVE_HIGH |
583 V4L2_MBUS_VSYNC_ACTIVE_LOW |
584 V4L2_MBUS_PCLK_SAMPLE_RISING |
585 V4L2_MBUS_PCLK_SAMPLE_FALLING |
586 V4L2_MBUS_DATA_ACTIVE_HIGH |
587 V4L2_MBUS_DATA_ACTIVE_LOW;
588
589 return 0;
590}
591
592static int mx3_camera_try_bus_param(struct soc_camera_device *icd,
593 const unsigned int depth)
594{
595 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
596 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
597 struct mx3_camera_dev *mx3_cam = ici->priv;
598 struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
599 unsigned long bus_flags, common_flags;
600 int ret = test_platform_param(mx3_cam, depth, &bus_flags);
601
602 dev_dbg(icd->parent, "request bus width %d bit: %d\n", depth, ret);
603
604 if (ret < 0)
605 return ret;
606
607 ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
608 if (!ret) {
609 common_flags = soc_mbus_config_compatible(&cfg,
610 bus_flags);
611 if (!common_flags) {
612 dev_warn(icd->parent,
613 "Flags incompatible: camera 0x%x, host 0x%lx\n",
614 cfg.flags, bus_flags);
615 return -EINVAL;
616 }
617 } else if (ret != -ENOIOCTLCMD) {
618 return ret;
619 }
620
621 return 0;
622}
623
624static bool chan_filter(struct dma_chan *chan, void *arg)
625{
626 struct dma_chan_request *rq = arg;
627 struct mx3_camera_pdata *pdata;
628
629 if (!imx_dma_is_ipu(chan))
630 return false;
631
632 if (!rq)
633 return false;
634
635 pdata = rq->mx3_cam->soc_host.v4l2_dev.dev->platform_data;
636
637 return rq->id == chan->chan_id &&
638 pdata->dma_dev == chan->device->dev;
639}
640
641static const struct soc_mbus_pixelfmt mx3_camera_formats[] = {
642 {
643 .fourcc = V4L2_PIX_FMT_SBGGR8,
644 .name = "Bayer BGGR (sRGB) 8 bit",
645 .bits_per_sample = 8,
646 .packing = SOC_MBUS_PACKING_NONE,
647 .order = SOC_MBUS_ORDER_LE,
648 .layout = SOC_MBUS_LAYOUT_PACKED,
649 }, {
650 .fourcc = V4L2_PIX_FMT_GREY,
651 .name = "Monochrome 8 bit",
652 .bits_per_sample = 8,
653 .packing = SOC_MBUS_PACKING_NONE,
654 .order = SOC_MBUS_ORDER_LE,
655 .layout = SOC_MBUS_LAYOUT_PACKED,
656 },
657};
658
659/* This will be corrected as we get more formats */
660static bool mx3_camera_packing_supported(const struct soc_mbus_pixelfmt *fmt)
661{
662 return fmt->packing == SOC_MBUS_PACKING_NONE ||
663 (fmt->bits_per_sample == 8 &&
664 fmt->packing == SOC_MBUS_PACKING_2X8_PADHI) ||
665 (fmt->bits_per_sample > 8 &&
666 fmt->packing == SOC_MBUS_PACKING_EXTEND16);
667}
668
669static int mx3_camera_get_formats(struct soc_camera_device *icd, unsigned int idx,
670 struct soc_camera_format_xlate *xlate)
671{
672 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
673 struct device *dev = icd->parent;
674 int formats = 0, ret;
675 enum v4l2_mbus_pixelcode code;
676 const struct soc_mbus_pixelfmt *fmt;
677
678 ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code);
679 if (ret < 0)
680 /* No more formats */
681 return 0;
682
683 fmt = soc_mbus_get_fmtdesc(code);
684 if (!fmt) {
685 dev_warn(icd->parent,
686 "Unsupported format code #%u: %d\n", idx, code);
687 return 0;
688 }
689
690 /* This also checks support for the requested bits-per-sample */
691 ret = mx3_camera_try_bus_param(icd, fmt->bits_per_sample);
692 if (ret < 0)
693 return 0;
694
695 switch (code) {
696 case V4L2_MBUS_FMT_SBGGR10_1X10:
697 formats++;
698 if (xlate) {
699 xlate->host_fmt = &mx3_camera_formats[0];
700 xlate->code = code;
701 xlate++;
702 dev_dbg(dev, "Providing format %s using code %d\n",
703 mx3_camera_formats[0].name, code);
704 }
705 break;
706 case V4L2_MBUS_FMT_Y10_1X10:
707 formats++;
708 if (xlate) {
709 xlate->host_fmt = &mx3_camera_formats[1];
710 xlate->code = code;
711 xlate++;
712 dev_dbg(dev, "Providing format %s using code %d\n",
713 mx3_camera_formats[1].name, code);
714 }
715 break;
716 default:
717 if (!mx3_camera_packing_supported(fmt))
718 return 0;
719 }
720
721 /* Generic pass-through */
722 formats++;
723 if (xlate) {
724 xlate->host_fmt = fmt;
725 xlate->code = code;
726 dev_dbg(dev, "Providing format %c%c%c%c in pass-through mode\n",
727 (fmt->fourcc >> (0*8)) & 0xFF,
728 (fmt->fourcc >> (1*8)) & 0xFF,
729 (fmt->fourcc >> (2*8)) & 0xFF,
730 (fmt->fourcc >> (3*8)) & 0xFF);
731 xlate++;
732 }
733
734 return formats;
735}
736
737static void configure_geometry(struct mx3_camera_dev *mx3_cam,
738 unsigned int width, unsigned int height,
739 const struct soc_mbus_pixelfmt *fmt)
740{
741 u32 ctrl, width_field, height_field;
742
743 if (fourcc_to_ipu_pix(fmt->fourcc) == IPU_PIX_FMT_GENERIC) {
744 /*
745 * As the CSI will be configured to output BAYER, here
746 * the width parameter count the number of samples to
747 * capture to complete the whole image width.
748 */
749 unsigned int num, den;
750 int ret = soc_mbus_samples_per_pixel(fmt, &num, &den);
751 BUG_ON(ret < 0);
752 width = width * num / den;
753 }
754
755 /* Setup frame size - this cannot be changed on-the-fly... */
756 width_field = width - 1;
757 height_field = height - 1;
758 csi_reg_write(mx3_cam, width_field | (height_field << 16), CSI_SENS_FRM_SIZE);
759
760 csi_reg_write(mx3_cam, width_field << 16, CSI_FLASH_STROBE_1);
761 csi_reg_write(mx3_cam, (height_field << 16) | 0x22, CSI_FLASH_STROBE_2);
762
763 csi_reg_write(mx3_cam, width_field | (height_field << 16), CSI_ACT_FRM_SIZE);
764
765 /* ...and position */
766 ctrl = csi_reg_read(mx3_cam, CSI_OUT_FRM_CTRL) & 0xffff0000;
767 /* Sensor does the cropping */
768 csi_reg_write(mx3_cam, ctrl | 0 | (0 << 8), CSI_OUT_FRM_CTRL);
769}
770
771static int acquire_dma_channel(struct mx3_camera_dev *mx3_cam)
772{
773 dma_cap_mask_t mask;
774 struct dma_chan *chan;
775 struct idmac_channel **ichan = &mx3_cam->idmac_channel[0];
776 /* We have to use IDMAC_IC_7 for Bayer / generic data */
777 struct dma_chan_request rq = {.mx3_cam = mx3_cam,
778 .id = IDMAC_IC_7};
779
780 dma_cap_zero(mask);
781 dma_cap_set(DMA_SLAVE, mask);
782 dma_cap_set(DMA_PRIVATE, mask);
783 chan = dma_request_channel(mask, chan_filter, &rq);
784 if (!chan)
785 return -EBUSY;
786
787 *ichan = to_idmac_chan(chan);
788 (*ichan)->client = mx3_cam;
789
790 return 0;
791}
792
793/*
794 * FIXME: learn to use stride != width, then we can keep stride properly aligned
795 * and support arbitrary (even) widths.
796 */
797static inline void stride_align(__u32 *width)
798{
799 if (ALIGN(*width, 8) < 4096)
800 *width = ALIGN(*width, 8);
801 else
802 *width = *width & ~7;
803}
804
805/*
806 * As long as we don't implement host-side cropping and scaling, we can use
807 * default g_crop and cropcap from soc_camera.c
808 */
809static int mx3_camera_set_crop(struct soc_camera_device *icd,
810 struct v4l2_crop *a)
811{
812 struct v4l2_rect *rect = &a->c;
813 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
814 struct mx3_camera_dev *mx3_cam = ici->priv;
815 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
816 struct v4l2_mbus_framefmt mf;
817 int ret;
818
819 soc_camera_limit_side(&rect->left, &rect->width, 0, 2, 4096);
820 soc_camera_limit_side(&rect->top, &rect->height, 0, 2, 4096);
821
822 ret = v4l2_subdev_call(sd, video, s_crop, a);
823 if (ret < 0)
824 return ret;
825
826 /* The capture device might have changed its output sizes */
827 ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf);
828 if (ret < 0)
829 return ret;
830
831 if (mf.code != icd->current_fmt->code)
832 return -EINVAL;
833
834 if (mf.width & 7) {
835 /* Ouch! We can only handle 8-byte aligned width... */
836 stride_align(&mf.width);
837 ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
838 if (ret < 0)
839 return ret;
840 }
841
842 if (mf.width != icd->user_width || mf.height != icd->user_height)
843 configure_geometry(mx3_cam, mf.width, mf.height,
844 icd->current_fmt->host_fmt);
845
846 dev_dbg(icd->parent, "Sensor cropped %dx%d\n",
847 mf.width, mf.height);
848
849 icd->user_width = mf.width;
850 icd->user_height = mf.height;
851
852 return ret;
853}
854
855static int mx3_camera_set_fmt(struct soc_camera_device *icd,
856 struct v4l2_format *f)
857{
858 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
859 struct mx3_camera_dev *mx3_cam = ici->priv;
860 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
861 const struct soc_camera_format_xlate *xlate;
862 struct v4l2_pix_format *pix = &f->fmt.pix;
863 struct v4l2_mbus_framefmt mf;
864 int ret;
865
866 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
867 if (!xlate) {
868 dev_warn(icd->parent, "Format %x not found\n",
869 pix->pixelformat);
870 return -EINVAL;
871 }
872
873 stride_align(&pix->width);
874 dev_dbg(icd->parent, "Set format %dx%d\n", pix->width, pix->height);
875
876 /*
877 * Might have to perform a complete interface initialisation like in
878 * ipu_csi_init_interface() in mxc_v4l2_s_param(). Also consider
879 * mxc_v4l2_s_fmt()
880 */
881
882 configure_geometry(mx3_cam, pix->width, pix->height, xlate->host_fmt);
883
884 mf.width = pix->width;
885 mf.height = pix->height;
886 mf.field = pix->field;
887 mf.colorspace = pix->colorspace;
888 mf.code = xlate->code;
889
890 ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
891 if (ret < 0)
892 return ret;
893
894 if (mf.code != xlate->code)
895 return -EINVAL;
896
897 if (!mx3_cam->idmac_channel[0]) {
898 ret = acquire_dma_channel(mx3_cam);
899 if (ret < 0)
900 return ret;
901 }
902
903 pix->width = mf.width;
904 pix->height = mf.height;
905 pix->field = mf.field;
906 mx3_cam->field = mf.field;
907 pix->colorspace = mf.colorspace;
908 icd->current_fmt = xlate;
909
910 dev_dbg(icd->parent, "Sensor set %dx%d\n", pix->width, pix->height);
911
912 return ret;
913}
914
915static int mx3_camera_try_fmt(struct soc_camera_device *icd,
916 struct v4l2_format *f)
917{
918 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
919 const struct soc_camera_format_xlate *xlate;
920 struct v4l2_pix_format *pix = &f->fmt.pix;
921 struct v4l2_mbus_framefmt mf;
922 __u32 pixfmt = pix->pixelformat;
923 int ret;
924
925 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
926 if (pixfmt && !xlate) {
927 dev_warn(icd->parent, "Format %x not found\n", pixfmt);
928 return -EINVAL;
929 }
930
931 /* limit to MX3 hardware capabilities */
932 if (pix->height > 4096)
933 pix->height = 4096;
934 if (pix->width > 4096)
935 pix->width = 4096;
936
937 /* limit to sensor capabilities */
938 mf.width = pix->width;
939 mf.height = pix->height;
940 mf.field = pix->field;
941 mf.colorspace = pix->colorspace;
942 mf.code = xlate->code;
943
944 ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
945 if (ret < 0)
946 return ret;
947
948 pix->width = mf.width;
949 pix->height = mf.height;
950 pix->colorspace = mf.colorspace;
951
952 switch (mf.field) {
953 case V4L2_FIELD_ANY:
954 pix->field = V4L2_FIELD_NONE;
955 break;
956 case V4L2_FIELD_NONE:
957 break;
958 default:
959 dev_err(icd->parent, "Field type %d unsupported.\n",
960 mf.field);
961 ret = -EINVAL;
962 }
963
964 return ret;
965}
966
967static int mx3_camera_reqbufs(struct soc_camera_device *icd,
968 struct v4l2_requestbuffers *p)
969{
970 return 0;
971}
972
973static unsigned int mx3_camera_poll(struct file *file, poll_table *pt)
974{
975 struct soc_camera_device *icd = file->private_data;
976
977 return vb2_poll(&icd->vb2_vidq, file, pt);
978}
979
980static int mx3_camera_querycap(struct soc_camera_host *ici,
981 struct v4l2_capability *cap)
982{
983 /* cap->name is set by the firendly caller:-> */
984 strlcpy(cap->card, "i.MX3x Camera", sizeof(cap->card));
985 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
986
987 return 0;
988}
989
990static int mx3_camera_set_bus_param(struct soc_camera_device *icd)
991{
992 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
993 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
994 struct mx3_camera_dev *mx3_cam = ici->priv;
995 struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
996 u32 pixfmt = icd->current_fmt->host_fmt->fourcc;
997 unsigned long bus_flags, common_flags;
998 u32 dw, sens_conf;
999 const struct soc_mbus_pixelfmt *fmt;
1000 int buswidth;
1001 int ret;
1002 const struct soc_camera_format_xlate *xlate;
1003 struct device *dev = icd->parent;
1004
1005 fmt = soc_mbus_get_fmtdesc(icd->current_fmt->code);
1006 if (!fmt)
1007 return -EINVAL;
1008
1009 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
1010 if (!xlate) {
1011 dev_warn(dev, "Format %x not found\n", pixfmt);
1012 return -EINVAL;
1013 }
1014
1015 buswidth = fmt->bits_per_sample;
1016 ret = test_platform_param(mx3_cam, buswidth, &bus_flags);
1017
1018 dev_dbg(dev, "requested bus width %d bit: %d\n", buswidth, ret);
1019
1020 if (ret < 0)
1021 return ret;
1022
1023 ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
1024 if (!ret) {
1025 common_flags = soc_mbus_config_compatible(&cfg,
1026 bus_flags);
1027 if (!common_flags) {
1028 dev_warn(icd->parent,
1029 "Flags incompatible: camera 0x%x, host 0x%lx\n",
1030 cfg.flags, bus_flags);
1031 return -EINVAL;
1032 }
1033 } else if (ret != -ENOIOCTLCMD) {
1034 return ret;
1035 } else {
1036 common_flags = bus_flags;
1037 }
1038
1039 dev_dbg(dev, "Flags cam: 0x%x host: 0x%lx common: 0x%lx\n",
1040 cfg.flags, bus_flags, common_flags);
1041
1042 /* Make choices, based on platform preferences */
1043 if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) &&
1044 (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) {
1045 if (mx3_cam->platform_flags & MX3_CAMERA_HSP)
1046 common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH;
1047 else
1048 common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW;
1049 }
1050
1051 if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) &&
1052 (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) {
1053 if (mx3_cam->platform_flags & MX3_CAMERA_VSP)
1054 common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH;
1055 else
1056 common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW;
1057 }
1058
1059 if ((common_flags & V4L2_MBUS_DATA_ACTIVE_HIGH) &&
1060 (common_flags & V4L2_MBUS_DATA_ACTIVE_LOW)) {
1061 if (mx3_cam->platform_flags & MX3_CAMERA_DP)
1062 common_flags &= ~V4L2_MBUS_DATA_ACTIVE_HIGH;
1063 else
1064 common_flags &= ~V4L2_MBUS_DATA_ACTIVE_LOW;
1065 }
1066
1067 if ((common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) &&
1068 (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)) {
1069 if (mx3_cam->platform_flags & MX3_CAMERA_PCP)
1070 common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_RISING;
1071 else
1072 common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_FALLING;
1073 }
1074
1075 cfg.flags = common_flags;
1076 ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
1077 if (ret < 0 && ret != -ENOIOCTLCMD) {
1078 dev_dbg(dev, "camera s_mbus_config(0x%lx) returned %d\n",
1079 common_flags, ret);
1080 return ret;
1081 }
1082
1083 /*
1084 * So far only gated clock mode is supported. Add a line
1085 * (3 << CSI_SENS_CONF_SENS_PRTCL_SHIFT) |
1086 * below and select the required mode when supporting other
1087 * synchronisation protocols.
1088 */
1089 sens_conf = csi_reg_read(mx3_cam, CSI_SENS_CONF) &
1090 ~((1 << CSI_SENS_CONF_VSYNC_POL_SHIFT) |
1091 (1 << CSI_SENS_CONF_HSYNC_POL_SHIFT) |
1092 (1 << CSI_SENS_CONF_DATA_POL_SHIFT) |
1093 (1 << CSI_SENS_CONF_PIX_CLK_POL_SHIFT) |
1094 (3 << CSI_SENS_CONF_DATA_FMT_SHIFT) |
1095 (3 << CSI_SENS_CONF_DATA_WIDTH_SHIFT));
1096
1097 /* TODO: Support RGB and YUV formats */
1098
1099 /* This has been set in mx3_camera_activate(), but we clear it above */
1100 sens_conf |= CSI_SENS_CONF_DATA_FMT_BAYER;
1101
1102 if (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
1103 sens_conf |= 1 << CSI_SENS_CONF_PIX_CLK_POL_SHIFT;
1104 if (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
1105 sens_conf |= 1 << CSI_SENS_CONF_HSYNC_POL_SHIFT;
1106 if (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
1107 sens_conf |= 1 << CSI_SENS_CONF_VSYNC_POL_SHIFT;
1108 if (common_flags & V4L2_MBUS_DATA_ACTIVE_LOW)
1109 sens_conf |= 1 << CSI_SENS_CONF_DATA_POL_SHIFT;
1110
1111 /* Just do what we're asked to do */
1112 switch (xlate->host_fmt->bits_per_sample) {
1113 case 4:
1114 dw = 0 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
1115 break;
1116 case 8:
1117 dw = 1 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
1118 break;
1119 case 10:
1120 dw = 2 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
1121 break;
1122 default:
1123 /*
1124 * Actually it can only be 15 now, default is just to silence
1125 * compiler warnings
1126 */
1127 case 15:
1128 dw = 3 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
1129 }
1130
1131 csi_reg_write(mx3_cam, sens_conf | dw, CSI_SENS_CONF);
1132
1133 dev_dbg(dev, "Set SENS_CONF to %x\n", sens_conf | dw);
1134
1135 return 0;
1136}
1137
1138static struct soc_camera_host_ops mx3_soc_camera_host_ops = {
1139 .owner = THIS_MODULE,
1140 .add = mx3_camera_add_device,
1141 .remove = mx3_camera_remove_device,
1142 .set_crop = mx3_camera_set_crop,
1143 .set_fmt = mx3_camera_set_fmt,
1144 .try_fmt = mx3_camera_try_fmt,
1145 .get_formats = mx3_camera_get_formats,
1146 .init_videobuf2 = mx3_camera_init_videobuf,
1147 .reqbufs = mx3_camera_reqbufs,
1148 .poll = mx3_camera_poll,
1149 .querycap = mx3_camera_querycap,
1150 .set_bus_param = mx3_camera_set_bus_param,
1151};
1152
1153static int __devinit mx3_camera_probe(struct platform_device *pdev)
1154{
1155 struct mx3_camera_dev *mx3_cam;
1156 struct resource *res;
1157 void __iomem *base;
1158 int err = 0;
1159 struct soc_camera_host *soc_host;
1160
1161 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1162 if (!res) {
1163 err = -ENODEV;
1164 goto egetres;
1165 }
1166
1167 mx3_cam = vzalloc(sizeof(*mx3_cam));
1168 if (!mx3_cam) {
1169 dev_err(&pdev->dev, "Could not allocate mx3 camera object\n");
1170 err = -ENOMEM;
1171 goto ealloc;
1172 }
1173
1174 mx3_cam->clk = clk_get(&pdev->dev, NULL);
1175 if (IS_ERR(mx3_cam->clk)) {
1176 err = PTR_ERR(mx3_cam->clk);
1177 goto eclkget;
1178 }
1179
1180 mx3_cam->pdata = pdev->dev.platform_data;
1181 mx3_cam->platform_flags = mx3_cam->pdata->flags;
1182 if (!(mx3_cam->platform_flags & (MX3_CAMERA_DATAWIDTH_4 |
1183 MX3_CAMERA_DATAWIDTH_8 | MX3_CAMERA_DATAWIDTH_10 |
1184 MX3_CAMERA_DATAWIDTH_15))) {
1185 /*
1186 * Platform hasn't set available data widths. This is bad.
1187 * Warn and use a default.
1188 */
1189 dev_warn(&pdev->dev, "WARNING! Platform hasn't set available "
1190 "data widths, using default 8 bit\n");
1191 mx3_cam->platform_flags |= MX3_CAMERA_DATAWIDTH_8;
1192 }
1193 if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_4)
1194 mx3_cam->width_flags = 1 << 3;
1195 if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_8)
1196 mx3_cam->width_flags |= 1 << 7;
1197 if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_10)
1198 mx3_cam->width_flags |= 1 << 9;
1199 if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_15)
1200 mx3_cam->width_flags |= 1 << 14;
1201
1202 mx3_cam->mclk = mx3_cam->pdata->mclk_10khz * 10000;
1203 if (!mx3_cam->mclk) {
1204 dev_warn(&pdev->dev,
1205 "mclk_10khz == 0! Please, fix your platform data. "
1206 "Using default 20MHz\n");
1207 mx3_cam->mclk = 20000000;
1208 }
1209
1210 /* list of video-buffers */
1211 INIT_LIST_HEAD(&mx3_cam->capture);
1212 spin_lock_init(&mx3_cam->lock);
1213
1214 base = ioremap(res->start, resource_size(res));
1215 if (!base) {
1216 pr_err("Couldn't map %x@%x\n", resource_size(res), res->start);
1217 err = -ENOMEM;
1218 goto eioremap;
1219 }
1220
1221 mx3_cam->base = base;
1222
1223 soc_host = &mx3_cam->soc_host;
1224 soc_host->drv_name = MX3_CAM_DRV_NAME;
1225 soc_host->ops = &mx3_soc_camera_host_ops;
1226 soc_host->priv = mx3_cam;
1227 soc_host->v4l2_dev.dev = &pdev->dev;
1228 soc_host->nr = pdev->id;
1229
1230 mx3_cam->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
1231 if (IS_ERR(mx3_cam->alloc_ctx)) {
1232 err = PTR_ERR(mx3_cam->alloc_ctx);
1233 goto eallocctx;
1234 }
1235
1236 err = soc_camera_host_register(soc_host);
1237 if (err)
1238 goto ecamhostreg;
1239
1240 /* IDMAC interface */
1241 dmaengine_get();
1242
1243 return 0;
1244
1245ecamhostreg:
1246 vb2_dma_contig_cleanup_ctx(mx3_cam->alloc_ctx);
1247eallocctx:
1248 iounmap(base);
1249eioremap:
1250 clk_put(mx3_cam->clk);
1251eclkget:
1252 vfree(mx3_cam);
1253ealloc:
1254egetres:
1255 return err;
1256}
1257
1258static int __devexit mx3_camera_remove(struct platform_device *pdev)
1259{
1260 struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev);
1261 struct mx3_camera_dev *mx3_cam = container_of(soc_host,
1262 struct mx3_camera_dev, soc_host);
1263
1264 clk_put(mx3_cam->clk);
1265
1266 soc_camera_host_unregister(soc_host);
1267
1268 iounmap(mx3_cam->base);
1269
1270 /*
1271 * The channel has either not been allocated,
1272 * or should have been released
1273 */
1274 if (WARN_ON(mx3_cam->idmac_channel[0]))
1275 dma_release_channel(&mx3_cam->idmac_channel[0]->dma_chan);
1276
1277 vb2_dma_contig_cleanup_ctx(mx3_cam->alloc_ctx);
1278
1279 vfree(mx3_cam);
1280
1281 dmaengine_put();
1282
1283 return 0;
1284}
1285
1286static struct platform_driver mx3_camera_driver = {
1287 .driver = {
1288 .name = MX3_CAM_DRV_NAME,
1289 },
1290 .probe = mx3_camera_probe,
1291 .remove = __devexit_p(mx3_camera_remove),
1292};
1293
1294module_platform_driver(mx3_camera_driver);
1295
1296MODULE_DESCRIPTION("i.MX3x SoC Camera Host driver");
1297MODULE_AUTHOR("Guennadi Liakhovetski <lg@denx.de>");
1298MODULE_LICENSE("GPL v2");
1299MODULE_VERSION("0.2.3");
1300MODULE_ALIAS("platform:" MX3_CAM_DRV_NAME);
diff --git a/drivers/media/video/omap/Kconfig b/drivers/media/video/omap/Kconfig
deleted file mode 100644
index 390ab094f9f2..000000000000
--- a/drivers/media/video/omap/Kconfig
+++ /dev/null
@@ -1,14 +0,0 @@
1config VIDEO_OMAP2_VOUT_VRFB
2 bool
3
4config VIDEO_OMAP2_VOUT
5 tristate "OMAP2/OMAP3 V4L2-Display driver"
6 depends on ARCH_OMAP2 || ARCH_OMAP3
7 select VIDEOBUF_GEN
8 select VIDEOBUF_DMA_CONTIG
9 select OMAP2_DSS
10 select OMAP2_VRFB if ARCH_OMAP2 || ARCH_OMAP3
11 select VIDEO_OMAP2_VOUT_VRFB if VIDEO_OMAP2_VOUT && OMAP2_VRFB
12 default n
13 ---help---
14 V4L2 Display driver support for OMAP2/3 based boards.
diff --git a/drivers/media/video/omap/Makefile b/drivers/media/video/omap/Makefile
deleted file mode 100644
index fc410b438f7d..000000000000
--- a/drivers/media/video/omap/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
1#
2# Makefile for the omap video device drivers.
3#
4
5# OMAP2/3 Display driver
6omap-vout-y := omap_vout.o omap_voutlib.o
7omap-vout-$(CONFIG_VIDEO_OMAP2_VOUT_VRFB) += omap_vout_vrfb.o
8obj-$(CONFIG_VIDEO_OMAP2_VOUT) += omap-vout.o
diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c
deleted file mode 100644
index 88cf9d952631..000000000000
--- a/drivers/media/video/omap/omap_vout.c
+++ /dev/null
@@ -1,2289 +0,0 @@
1/*
2 * omap_vout.c
3 *
4 * Copyright (C) 2005-2010 Texas Instruments.
5 *
6 * This file is licensed under the terms of the GNU General Public License
7 * version 2. This program is licensed "as is" without any warranty of any
8 * kind, whether express or implied.
9 *
10 * Leveraged code from the OMAP2 camera driver
11 * Video-for-Linux (Version 2) camera capture driver for
12 * the OMAP24xx camera controller.
13 *
14 * Author: Andy Lowe (source@mvista.com)
15 *
16 * Copyright (C) 2004 MontaVista Software, Inc.
17 * Copyright (C) 2010 Texas Instruments.
18 *
19 * History:
20 * 20-APR-2006 Khasim Modified VRFB based Rotation,
21 * The image data is always read from 0 degree
22 * view and written
23 * to the virtual space of desired rotation angle
24 * 4-DEC-2006 Jian Changed to support better memory management
25 *
26 * 17-Nov-2008 Hardik Changed driver to use video_ioctl2
27 *
28 * 23-Feb-2010 Vaibhav H Modified to use new DSS2 interface
29 *
30 */
31
32#include <linux/init.h>
33#include <linux/module.h>
34#include <linux/vmalloc.h>
35#include <linux/sched.h>
36#include <linux/types.h>
37#include <linux/platform_device.h>
38#include <linux/irq.h>
39#include <linux/videodev2.h>
40#include <linux/dma-mapping.h>
41#include <linux/slab.h>
42
43#include <media/videobuf-dma-contig.h>
44#include <media/v4l2-device.h>
45#include <media/v4l2-ioctl.h>
46
47#include <plat/dma.h>
48#include <plat/vrfb.h>
49#include <video/omapdss.h>
50
51#include "omap_voutlib.h"
52#include "omap_voutdef.h"
53#include "omap_vout_vrfb.h"
54
55MODULE_AUTHOR("Texas Instruments");
56MODULE_DESCRIPTION("OMAP Video for Linux Video out driver");
57MODULE_LICENSE("GPL");
58
59/* Driver Configuration macros */
60#define VOUT_NAME "omap_vout"
61
62enum omap_vout_channels {
63 OMAP_VIDEO1,
64 OMAP_VIDEO2,
65};
66
67static struct videobuf_queue_ops video_vbq_ops;
68/* Variables configurable through module params*/
69static u32 video1_numbuffers = 3;
70static u32 video2_numbuffers = 3;
71static u32 video1_bufsize = OMAP_VOUT_MAX_BUF_SIZE;
72static u32 video2_bufsize = OMAP_VOUT_MAX_BUF_SIZE;
73static bool vid1_static_vrfb_alloc;
74static bool vid2_static_vrfb_alloc;
75static bool debug;
76
77/* Module parameters */
78module_param(video1_numbuffers, uint, S_IRUGO);
79MODULE_PARM_DESC(video1_numbuffers,
80 "Number of buffers to be allocated at init time for Video1 device.");
81
82module_param(video2_numbuffers, uint, S_IRUGO);
83MODULE_PARM_DESC(video2_numbuffers,
84 "Number of buffers to be allocated at init time for Video2 device.");
85
86module_param(video1_bufsize, uint, S_IRUGO);
87MODULE_PARM_DESC(video1_bufsize,
88 "Size of the buffer to be allocated for video1 device");
89
90module_param(video2_bufsize, uint, S_IRUGO);
91MODULE_PARM_DESC(video2_bufsize,
92 "Size of the buffer to be allocated for video2 device");
93
94module_param(vid1_static_vrfb_alloc, bool, S_IRUGO);
95MODULE_PARM_DESC(vid1_static_vrfb_alloc,
96 "Static allocation of the VRFB buffer for video1 device");
97
98module_param(vid2_static_vrfb_alloc, bool, S_IRUGO);
99MODULE_PARM_DESC(vid2_static_vrfb_alloc,
100 "Static allocation of the VRFB buffer for video2 device");
101
102module_param(debug, bool, S_IRUGO);
103MODULE_PARM_DESC(debug, "Debug level (0-1)");
104
105/* list of image formats supported by OMAP2 video pipelines */
106static const struct v4l2_fmtdesc omap_formats[] = {
107 {
108 /* Note: V4L2 defines RGB565 as:
109 *
110 * Byte 0 Byte 1
111 * g2 g1 g0 r4 r3 r2 r1 r0 b4 b3 b2 b1 b0 g5 g4 g3
112 *
113 * We interpret RGB565 as:
114 *
115 * Byte 0 Byte 1
116 * g2 g1 g0 b4 b3 b2 b1 b0 r4 r3 r2 r1 r0 g5 g4 g3
117 */
118 .description = "RGB565, le",
119 .pixelformat = V4L2_PIX_FMT_RGB565,
120 },
121 {
122 /* Note: V4L2 defines RGB32 as: RGB-8-8-8-8 we use
123 * this for RGB24 unpack mode, the last 8 bits are ignored
124 * */
125 .description = "RGB32, le",
126 .pixelformat = V4L2_PIX_FMT_RGB32,
127 },
128 {
129 /* Note: V4L2 defines RGB24 as: RGB-8-8-8 we use
130 * this for RGB24 packed mode
131 *
132 */
133 .description = "RGB24, le",
134 .pixelformat = V4L2_PIX_FMT_RGB24,
135 },
136 {
137 .description = "YUYV (YUV 4:2:2), packed",
138 .pixelformat = V4L2_PIX_FMT_YUYV,
139 },
140 {
141 .description = "UYVY, packed",
142 .pixelformat = V4L2_PIX_FMT_UYVY,
143 },
144};
145
146#define NUM_OUTPUT_FORMATS (ARRAY_SIZE(omap_formats))
147
148/*
149 * Try format
150 */
151static int omap_vout_try_format(struct v4l2_pix_format *pix)
152{
153 int ifmt, bpp = 0;
154
155 pix->height = clamp(pix->height, (u32)VID_MIN_HEIGHT,
156 (u32)VID_MAX_HEIGHT);
157 pix->width = clamp(pix->width, (u32)VID_MIN_WIDTH, (u32)VID_MAX_WIDTH);
158
159 for (ifmt = 0; ifmt < NUM_OUTPUT_FORMATS; ifmt++) {
160 if (pix->pixelformat == omap_formats[ifmt].pixelformat)
161 break;
162 }
163
164 if (ifmt == NUM_OUTPUT_FORMATS)
165 ifmt = 0;
166
167 pix->pixelformat = omap_formats[ifmt].pixelformat;
168 pix->field = V4L2_FIELD_ANY;
169 pix->priv = 0;
170
171 switch (pix->pixelformat) {
172 case V4L2_PIX_FMT_YUYV:
173 case V4L2_PIX_FMT_UYVY:
174 default:
175 pix->colorspace = V4L2_COLORSPACE_JPEG;
176 bpp = YUYV_BPP;
177 break;
178 case V4L2_PIX_FMT_RGB565:
179 case V4L2_PIX_FMT_RGB565X:
180 pix->colorspace = V4L2_COLORSPACE_SRGB;
181 bpp = RGB565_BPP;
182 break;
183 case V4L2_PIX_FMT_RGB24:
184 pix->colorspace = V4L2_COLORSPACE_SRGB;
185 bpp = RGB24_BPP;
186 break;
187 case V4L2_PIX_FMT_RGB32:
188 case V4L2_PIX_FMT_BGR32:
189 pix->colorspace = V4L2_COLORSPACE_SRGB;
190 bpp = RGB32_BPP;
191 break;
192 }
193 pix->bytesperline = pix->width * bpp;
194 pix->sizeimage = pix->bytesperline * pix->height;
195
196 return bpp;
197}
198
199/*
200 * omap_vout_uservirt_to_phys: This inline function is used to convert user
201 * space virtual address to physical address.
202 */
203static u32 omap_vout_uservirt_to_phys(u32 virtp)
204{
205 unsigned long physp = 0;
206 struct vm_area_struct *vma;
207 struct mm_struct *mm = current->mm;
208
209 vma = find_vma(mm, virtp);
210 /* For kernel direct-mapped memory, take the easy way */
211 if (virtp >= PAGE_OFFSET) {
212 physp = virt_to_phys((void *) virtp);
213 } else if (vma && (vma->vm_flags & VM_IO) && vma->vm_pgoff) {
214 /* this will catch, kernel-allocated, mmaped-to-usermode
215 addresses */
216 physp = (vma->vm_pgoff << PAGE_SHIFT) + (virtp - vma->vm_start);
217 } else {
218 /* otherwise, use get_user_pages() for general userland pages */
219 int res, nr_pages = 1;
220 struct page *pages;
221 down_read(&current->mm->mmap_sem);
222
223 res = get_user_pages(current, current->mm, virtp, nr_pages, 1,
224 0, &pages, NULL);
225 up_read(&current->mm->mmap_sem);
226
227 if (res == nr_pages) {
228 physp = __pa(page_address(&pages[0]) +
229 (virtp & ~PAGE_MASK));
230 } else {
231 printk(KERN_WARNING VOUT_NAME
232 "get_user_pages failed\n");
233 return 0;
234 }
235 }
236
237 return physp;
238}
239
240/*
241 * Free the V4L2 buffers
242 */
243void omap_vout_free_buffers(struct omap_vout_device *vout)
244{
245 int i, numbuffers;
246
247 /* Allocate memory for the buffers */
248 numbuffers = (vout->vid) ? video2_numbuffers : video1_numbuffers;
249 vout->buffer_size = (vout->vid) ? video2_bufsize : video1_bufsize;
250
251 for (i = 0; i < numbuffers; i++) {
252 omap_vout_free_buffer(vout->buf_virt_addr[i],
253 vout->buffer_size);
254 vout->buf_phy_addr[i] = 0;
255 vout->buf_virt_addr[i] = 0;
256 }
257}
258
259/*
260 * Convert V4L2 rotation to DSS rotation
261 * V4L2 understand 0, 90, 180, 270.
262 * Convert to 0, 1, 2 and 3 respectively for DSS
263 */
264static int v4l2_rot_to_dss_rot(int v4l2_rotation,
265 enum dss_rotation *rotation, bool mirror)
266{
267 int ret = 0;
268
269 switch (v4l2_rotation) {
270 case 90:
271 *rotation = dss_rotation_90_degree;
272 break;
273 case 180:
274 *rotation = dss_rotation_180_degree;
275 break;
276 case 270:
277 *rotation = dss_rotation_270_degree;
278 break;
279 case 0:
280 *rotation = dss_rotation_0_degree;
281 break;
282 default:
283 ret = -EINVAL;
284 }
285 return ret;
286}
287
288static int omap_vout_calculate_offset(struct omap_vout_device *vout)
289{
290 struct omapvideo_info *ovid;
291 struct v4l2_rect *crop = &vout->crop;
292 struct v4l2_pix_format *pix = &vout->pix;
293 int *cropped_offset = &vout->cropped_offset;
294 int ps = 2, line_length = 0;
295
296 ovid = &vout->vid_info;
297
298 if (ovid->rotation_type == VOUT_ROT_VRFB) {
299 omap_vout_calculate_vrfb_offset(vout);
300 } else {
301 vout->line_length = line_length = pix->width;
302
303 if (V4L2_PIX_FMT_YUYV == pix->pixelformat ||
304 V4L2_PIX_FMT_UYVY == pix->pixelformat)
305 ps = 2;
306 else if (V4L2_PIX_FMT_RGB32 == pix->pixelformat)
307 ps = 4;
308 else if (V4L2_PIX_FMT_RGB24 == pix->pixelformat)
309 ps = 3;
310
311 vout->ps = ps;
312
313 *cropped_offset = (line_length * ps) *
314 crop->top + crop->left * ps;
315 }
316
317 v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "%s Offset:%x\n",
318 __func__, vout->cropped_offset);
319
320 return 0;
321}
322
323/*
324 * Convert V4L2 pixel format to DSS pixel format
325 */
326static int video_mode_to_dss_mode(struct omap_vout_device *vout)
327{
328 struct omap_overlay *ovl;
329 struct omapvideo_info *ovid;
330 struct v4l2_pix_format *pix = &vout->pix;
331 enum omap_color_mode mode;
332
333 ovid = &vout->vid_info;
334 ovl = ovid->overlays[0];
335
336 switch (pix->pixelformat) {
337 case 0:
338 break;
339 case V4L2_PIX_FMT_YUYV:
340 mode = OMAP_DSS_COLOR_YUV2;
341 break;
342 case V4L2_PIX_FMT_UYVY:
343 mode = OMAP_DSS_COLOR_UYVY;
344 break;
345 case V4L2_PIX_FMT_RGB565:
346 mode = OMAP_DSS_COLOR_RGB16;
347 break;
348 case V4L2_PIX_FMT_RGB24:
349 mode = OMAP_DSS_COLOR_RGB24P;
350 break;
351 case V4L2_PIX_FMT_RGB32:
352 mode = (ovl->id == OMAP_DSS_VIDEO1) ?
353 OMAP_DSS_COLOR_RGB24U : OMAP_DSS_COLOR_ARGB32;
354 break;
355 case V4L2_PIX_FMT_BGR32:
356 mode = OMAP_DSS_COLOR_RGBX32;
357 break;
358 default:
359 mode = -EINVAL;
360 }
361 return mode;
362}
363
364/*
365 * Setup the overlay
366 */
367static int omapvid_setup_overlay(struct omap_vout_device *vout,
368 struct omap_overlay *ovl, int posx, int posy, int outw,
369 int outh, u32 addr)
370{
371 int ret = 0;
372 struct omap_overlay_info info;
373 int cropheight, cropwidth, pixheight, pixwidth;
374
375 if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0 &&
376 (outw != vout->pix.width || outh != vout->pix.height)) {
377 ret = -EINVAL;
378 goto setup_ovl_err;
379 }
380
381 vout->dss_mode = video_mode_to_dss_mode(vout);
382 if (vout->dss_mode == -EINVAL) {
383 ret = -EINVAL;
384 goto setup_ovl_err;
385 }
386
387 /* Setup the input plane parameters according to
388 * rotation value selected.
389 */
390 if (is_rotation_90_or_270(vout)) {
391 cropheight = vout->crop.width;
392 cropwidth = vout->crop.height;
393 pixheight = vout->pix.width;
394 pixwidth = vout->pix.height;
395 } else {
396 cropheight = vout->crop.height;
397 cropwidth = vout->crop.width;
398 pixheight = vout->pix.height;
399 pixwidth = vout->pix.width;
400 }
401
402 ovl->get_overlay_info(ovl, &info);
403 info.paddr = addr;
404 info.width = cropwidth;
405 info.height = cropheight;
406 info.color_mode = vout->dss_mode;
407 info.mirror = vout->mirror;
408 info.pos_x = posx;
409 info.pos_y = posy;
410 info.out_width = outw;
411 info.out_height = outh;
412 info.global_alpha = vout->win.global_alpha;
413 if (!is_rotation_enabled(vout)) {
414 info.rotation = 0;
415 info.rotation_type = OMAP_DSS_ROT_DMA;
416 info.screen_width = pixwidth;
417 } else {
418 info.rotation = vout->rotation;
419 info.rotation_type = OMAP_DSS_ROT_VRFB;
420 info.screen_width = 2048;
421 }
422
423 v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev,
424 "%s enable=%d addr=%x width=%d\n height=%d color_mode=%d\n"
425 "rotation=%d mirror=%d posx=%d posy=%d out_width = %d \n"
426 "out_height=%d rotation_type=%d screen_width=%d\n",
427 __func__, ovl->is_enabled(ovl), info.paddr, info.width, info.height,
428 info.color_mode, info.rotation, info.mirror, info.pos_x,
429 info.pos_y, info.out_width, info.out_height, info.rotation_type,
430 info.screen_width);
431
432 ret = ovl->set_overlay_info(ovl, &info);
433 if (ret)
434 goto setup_ovl_err;
435
436 return 0;
437
438setup_ovl_err:
439 v4l2_warn(&vout->vid_dev->v4l2_dev, "setup_overlay failed\n");
440 return ret;
441}
442
443/*
444 * Initialize the overlay structure
445 */
446static int omapvid_init(struct omap_vout_device *vout, u32 addr)
447{
448 int ret = 0, i;
449 struct v4l2_window *win;
450 struct omap_overlay *ovl;
451 int posx, posy, outw, outh, temp;
452 struct omap_video_timings *timing;
453 struct omapvideo_info *ovid = &vout->vid_info;
454
455 win = &vout->win;
456 for (i = 0; i < ovid->num_overlays; i++) {
457 ovl = ovid->overlays[i];
458 if (!ovl->manager || !ovl->manager->device)
459 return -EINVAL;
460
461 timing = &ovl->manager->device->panel.timings;
462
463 outw = win->w.width;
464 outh = win->w.height;
465 switch (vout->rotation) {
466 case dss_rotation_90_degree:
467 /* Invert the height and width for 90
468 * and 270 degree rotation
469 */
470 temp = outw;
471 outw = outh;
472 outh = temp;
473 posy = (timing->y_res - win->w.width) - win->w.left;
474 posx = win->w.top;
475 break;
476
477 case dss_rotation_180_degree:
478 posx = (timing->x_res - win->w.width) - win->w.left;
479 posy = (timing->y_res - win->w.height) - win->w.top;
480 break;
481
482 case dss_rotation_270_degree:
483 temp = outw;
484 outw = outh;
485 outh = temp;
486 posy = win->w.left;
487 posx = (timing->x_res - win->w.height) - win->w.top;
488 break;
489
490 default:
491 posx = win->w.left;
492 posy = win->w.top;
493 break;
494 }
495
496 ret = omapvid_setup_overlay(vout, ovl, posx, posy,
497 outw, outh, addr);
498 if (ret)
499 goto omapvid_init_err;
500 }
501 return 0;
502
503omapvid_init_err:
504 v4l2_warn(&vout->vid_dev->v4l2_dev, "apply_changes failed\n");
505 return ret;
506}
507
508/*
509 * Apply the changes set the go bit of DSS
510 */
511static int omapvid_apply_changes(struct omap_vout_device *vout)
512{
513 int i;
514 struct omap_overlay *ovl;
515 struct omapvideo_info *ovid = &vout->vid_info;
516
517 for (i = 0; i < ovid->num_overlays; i++) {
518 ovl = ovid->overlays[i];
519 if (!ovl->manager || !ovl->manager->device)
520 return -EINVAL;
521 ovl->manager->apply(ovl->manager);
522 }
523
524 return 0;
525}
526
527static int omapvid_handle_interlace_display(struct omap_vout_device *vout,
528 unsigned int irqstatus, struct timeval timevalue)
529{
530 u32 fid;
531
532 if (vout->first_int) {
533 vout->first_int = 0;
534 goto err;
535 }
536
537 if (irqstatus & DISPC_IRQ_EVSYNC_ODD)
538 fid = 1;
539 else if (irqstatus & DISPC_IRQ_EVSYNC_EVEN)
540 fid = 0;
541 else
542 goto err;
543
544 vout->field_id ^= 1;
545 if (fid != vout->field_id) {
546 if (fid == 0)
547 vout->field_id = fid;
548 } else if (0 == fid) {
549 if (vout->cur_frm == vout->next_frm)
550 goto err;
551
552 vout->cur_frm->ts = timevalue;
553 vout->cur_frm->state = VIDEOBUF_DONE;
554 wake_up_interruptible(&vout->cur_frm->done);
555 vout->cur_frm = vout->next_frm;
556 } else {
557 if (list_empty(&vout->dma_queue) ||
558 (vout->cur_frm != vout->next_frm))
559 goto err;
560 }
561
562 return vout->field_id;
563err:
564 return 0;
565}
566
567static void omap_vout_isr(void *arg, unsigned int irqstatus)
568{
569 int ret, fid, mgr_id;
570 u32 addr, irq;
571 struct omap_overlay *ovl;
572 struct timeval timevalue;
573 struct omapvideo_info *ovid;
574 struct omap_dss_device *cur_display;
575 struct omap_vout_device *vout = (struct omap_vout_device *)arg;
576
577 if (!vout->streaming)
578 return;
579
580 ovid = &vout->vid_info;
581 ovl = ovid->overlays[0];
582 /* get the display device attached to the overlay */
583 if (!ovl->manager || !ovl->manager->device)
584 return;
585
586 mgr_id = ovl->manager->id;
587 cur_display = ovl->manager->device;
588
589 spin_lock(&vout->vbq_lock);
590 do_gettimeofday(&timevalue);
591
592 switch (cur_display->type) {
593 case OMAP_DISPLAY_TYPE_DSI:
594 case OMAP_DISPLAY_TYPE_DPI:
595 if (mgr_id == OMAP_DSS_CHANNEL_LCD)
596 irq = DISPC_IRQ_VSYNC;
597 else if (mgr_id == OMAP_DSS_CHANNEL_LCD2)
598 irq = DISPC_IRQ_VSYNC2;
599 else
600 goto vout_isr_err;
601
602 if (!(irqstatus & irq))
603 goto vout_isr_err;
604 break;
605 case OMAP_DISPLAY_TYPE_VENC:
606 fid = omapvid_handle_interlace_display(vout, irqstatus,
607 timevalue);
608 if (!fid)
609 goto vout_isr_err;
610 break;
611 case OMAP_DISPLAY_TYPE_HDMI:
612 if (!(irqstatus & DISPC_IRQ_EVSYNC_EVEN))
613 goto vout_isr_err;
614 break;
615 default:
616 goto vout_isr_err;
617 }
618
619 if (!vout->first_int && (vout->cur_frm != vout->next_frm)) {
620 vout->cur_frm->ts = timevalue;
621 vout->cur_frm->state = VIDEOBUF_DONE;
622 wake_up_interruptible(&vout->cur_frm->done);
623 vout->cur_frm = vout->next_frm;
624 }
625
626 vout->first_int = 0;
627 if (list_empty(&vout->dma_queue))
628 goto vout_isr_err;
629
630 vout->next_frm = list_entry(vout->dma_queue.next,
631 struct videobuf_buffer, queue);
632 list_del(&vout->next_frm->queue);
633
634 vout->next_frm->state = VIDEOBUF_ACTIVE;
635
636 addr = (unsigned long) vout->queued_buf_addr[vout->next_frm->i]
637 + vout->cropped_offset;
638
639 /* First save the configuration in ovelray structure */
640 ret = omapvid_init(vout, addr);
641 if (ret)
642 printk(KERN_ERR VOUT_NAME
643 "failed to set overlay info\n");
644 /* Enable the pipeline and set the Go bit */
645 ret = omapvid_apply_changes(vout);
646 if (ret)
647 printk(KERN_ERR VOUT_NAME "failed to change mode\n");
648
649vout_isr_err:
650 spin_unlock(&vout->vbq_lock);
651}
652
653/* Video buffer call backs */
654
655/*
656 * Buffer setup function is called by videobuf layer when REQBUF ioctl is
657 * called. This is used to setup buffers and return size and count of
658 * buffers allocated. After the call to this buffer, videobuf layer will
659 * setup buffer queue depending on the size and count of buffers
660 */
661static int omap_vout_buffer_setup(struct videobuf_queue *q, unsigned int *count,
662 unsigned int *size)
663{
664 int startindex = 0, i, j;
665 u32 phy_addr = 0, virt_addr = 0;
666 struct omap_vout_device *vout = q->priv_data;
667 struct omapvideo_info *ovid = &vout->vid_info;
668 int vid_max_buf_size;
669
670 if (!vout)
671 return -EINVAL;
672
673 vid_max_buf_size = vout->vid == OMAP_VIDEO1 ? video1_bufsize :
674 video2_bufsize;
675
676 if (V4L2_BUF_TYPE_VIDEO_OUTPUT != q->type)
677 return -EINVAL;
678
679 startindex = (vout->vid == OMAP_VIDEO1) ?
680 video1_numbuffers : video2_numbuffers;
681 if (V4L2_MEMORY_MMAP == vout->memory && *count < startindex)
682 *count = startindex;
683
684 if (ovid->rotation_type == VOUT_ROT_VRFB) {
685 if (omap_vout_vrfb_buffer_setup(vout, count, startindex))
686 return -ENOMEM;
687 }
688
689 if (V4L2_MEMORY_MMAP != vout->memory)
690 return 0;
691
692 /* Now allocated the V4L2 buffers */
693 *size = PAGE_ALIGN(vout->pix.width * vout->pix.height * vout->bpp);
694 startindex = (vout->vid == OMAP_VIDEO1) ?
695 video1_numbuffers : video2_numbuffers;
696
697 /* Check the size of the buffer */
698 if (*size > vid_max_buf_size) {
699 v4l2_err(&vout->vid_dev->v4l2_dev,
700 "buffer allocation mismatch [%u] [%u]\n",
701 *size, vout->buffer_size);
702 return -ENOMEM;
703 }
704
705 for (i = startindex; i < *count; i++) {
706 vout->buffer_size = *size;
707
708 virt_addr = omap_vout_alloc_buffer(vout->buffer_size,
709 &phy_addr);
710 if (!virt_addr) {
711 if (ovid->rotation_type == VOUT_ROT_NONE) {
712 break;
713 } else {
714 if (!is_rotation_enabled(vout))
715 break;
716 /* Free the VRFB buffers if no space for V4L2 buffers */
717 for (j = i; j < *count; j++) {
718 omap_vout_free_buffer(
719 vout->smsshado_virt_addr[j],
720 vout->smsshado_size);
721 vout->smsshado_virt_addr[j] = 0;
722 vout->smsshado_phy_addr[j] = 0;
723 }
724 }
725 }
726 vout->buf_virt_addr[i] = virt_addr;
727 vout->buf_phy_addr[i] = phy_addr;
728 }
729 *count = vout->buffer_allocated = i;
730
731 return 0;
732}
733
734/*
735 * Free the V4L2 buffers additionally allocated than default
736 * number of buffers
737 */
738static void omap_vout_free_extra_buffers(struct omap_vout_device *vout)
739{
740 int num_buffers = 0, i;
741
742 num_buffers = (vout->vid == OMAP_VIDEO1) ?
743 video1_numbuffers : video2_numbuffers;
744
745 for (i = num_buffers; i < vout->buffer_allocated; i++) {
746 if (vout->buf_virt_addr[i])
747 omap_vout_free_buffer(vout->buf_virt_addr[i],
748 vout->buffer_size);
749
750 vout->buf_virt_addr[i] = 0;
751 vout->buf_phy_addr[i] = 0;
752 }
753 vout->buffer_allocated = num_buffers;
754}
755
756/*
757 * This function will be called when VIDIOC_QBUF ioctl is called.
758 * It prepare buffers before give out for the display. This function
759 * converts user space virtual address into physical address if userptr memory
760 * exchange mechanism is used. If rotation is enabled, it copies entire
761 * buffer into VRFB memory space before giving it to the DSS.
762 */
763static int omap_vout_buffer_prepare(struct videobuf_queue *q,
764 struct videobuf_buffer *vb,
765 enum v4l2_field field)
766{
767 struct omap_vout_device *vout = q->priv_data;
768 struct omapvideo_info *ovid = &vout->vid_info;
769
770 if (VIDEOBUF_NEEDS_INIT == vb->state) {
771 vb->width = vout->pix.width;
772 vb->height = vout->pix.height;
773 vb->size = vb->width * vb->height * vout->bpp;
774 vb->field = field;
775 }
776 vb->state = VIDEOBUF_PREPARED;
777 /* if user pointer memory mechanism is used, get the physical
778 * address of the buffer
779 */
780 if (V4L2_MEMORY_USERPTR == vb->memory) {
781 if (0 == vb->baddr)
782 return -EINVAL;
783 /* Physical address */
784 vout->queued_buf_addr[vb->i] = (u8 *)
785 omap_vout_uservirt_to_phys(vb->baddr);
786 } else {
787 u32 addr, dma_addr;
788 unsigned long size;
789
790 addr = (unsigned long) vout->buf_virt_addr[vb->i];
791 size = (unsigned long) vb->size;
792
793 dma_addr = dma_map_single(vout->vid_dev->v4l2_dev.dev, (void *) addr,
794 size, DMA_TO_DEVICE);
795 if (dma_mapping_error(vout->vid_dev->v4l2_dev.dev, dma_addr))
796 v4l2_err(&vout->vid_dev->v4l2_dev, "dma_map_single failed\n");
797
798 vout->queued_buf_addr[vb->i] = (u8 *)vout->buf_phy_addr[vb->i];
799 }
800
801 if (ovid->rotation_type == VOUT_ROT_VRFB)
802 return omap_vout_prepare_vrfb(vout, vb);
803 else
804 return 0;
805}
806
807/*
808 * Buffer queue function will be called from the videobuf layer when _QBUF
809 * ioctl is called. It is used to enqueue buffer, which is ready to be
810 * displayed.
811 */
812static void omap_vout_buffer_queue(struct videobuf_queue *q,
813 struct videobuf_buffer *vb)
814{
815 struct omap_vout_device *vout = q->priv_data;
816
817 /* Driver is also maintainig a queue. So enqueue buffer in the driver
818 * queue */
819 list_add_tail(&vb->queue, &vout->dma_queue);
820
821 vb->state = VIDEOBUF_QUEUED;
822}
823
824/*
825 * Buffer release function is called from videobuf layer to release buffer
826 * which are already allocated
827 */
828static void omap_vout_buffer_release(struct videobuf_queue *q,
829 struct videobuf_buffer *vb)
830{
831 struct omap_vout_device *vout = q->priv_data;
832
833 vb->state = VIDEOBUF_NEEDS_INIT;
834
835 if (V4L2_MEMORY_MMAP != vout->memory)
836 return;
837}
838
839/*
840 * File operations
841 */
842static unsigned int omap_vout_poll(struct file *file,
843 struct poll_table_struct *wait)
844{
845 struct omap_vout_device *vout = file->private_data;
846 struct videobuf_queue *q = &vout->vbq;
847
848 return videobuf_poll_stream(file, q, wait);
849}
850
851static void omap_vout_vm_open(struct vm_area_struct *vma)
852{
853 struct omap_vout_device *vout = vma->vm_private_data;
854
855 v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev,
856 "vm_open [vma=%08lx-%08lx]\n", vma->vm_start, vma->vm_end);
857 vout->mmap_count++;
858}
859
860static void omap_vout_vm_close(struct vm_area_struct *vma)
861{
862 struct omap_vout_device *vout = vma->vm_private_data;
863
864 v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev,
865 "vm_close [vma=%08lx-%08lx]\n", vma->vm_start, vma->vm_end);
866 vout->mmap_count--;
867}
868
869static struct vm_operations_struct omap_vout_vm_ops = {
870 .open = omap_vout_vm_open,
871 .close = omap_vout_vm_close,
872};
873
874static int omap_vout_mmap(struct file *file, struct vm_area_struct *vma)
875{
876 int i;
877 void *pos;
878 unsigned long start = vma->vm_start;
879 unsigned long size = (vma->vm_end - vma->vm_start);
880 struct omap_vout_device *vout = file->private_data;
881 struct videobuf_queue *q = &vout->vbq;
882
883 v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev,
884 " %s pgoff=0x%lx, start=0x%lx, end=0x%lx\n", __func__,
885 vma->vm_pgoff, vma->vm_start, vma->vm_end);
886
887 /* look for the buffer to map */
888 for (i = 0; i < VIDEO_MAX_FRAME; i++) {
889 if (NULL == q->bufs[i])
890 continue;
891 if (V4L2_MEMORY_MMAP != q->bufs[i]->memory)
892 continue;
893 if (q->bufs[i]->boff == (vma->vm_pgoff << PAGE_SHIFT))
894 break;
895 }
896
897 if (VIDEO_MAX_FRAME == i) {
898 v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev,
899 "offset invalid [offset=0x%lx]\n",
900 (vma->vm_pgoff << PAGE_SHIFT));
901 return -EINVAL;
902 }
903 /* Check the size of the buffer */
904 if (size > vout->buffer_size) {
905 v4l2_err(&vout->vid_dev->v4l2_dev,
906 "insufficient memory [%lu] [%u]\n",
907 size, vout->buffer_size);
908 return -ENOMEM;
909 }
910
911 q->bufs[i]->baddr = vma->vm_start;
912
913 vma->vm_flags |= VM_RESERVED;
914 vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
915 vma->vm_ops = &omap_vout_vm_ops;
916 vma->vm_private_data = (void *) vout;
917 pos = (void *)vout->buf_virt_addr[i];
918 vma->vm_pgoff = virt_to_phys((void *)pos) >> PAGE_SHIFT;
919 while (size > 0) {
920 unsigned long pfn;
921 pfn = virt_to_phys((void *) pos) >> PAGE_SHIFT;
922 if (remap_pfn_range(vma, start, pfn, PAGE_SIZE, PAGE_SHARED))
923 return -EAGAIN;
924 start += PAGE_SIZE;
925 pos += PAGE_SIZE;
926 size -= PAGE_SIZE;
927 }
928 vout->mmap_count++;
929 v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Exiting %s\n", __func__);
930
931 return 0;
932}
933
934static int omap_vout_release(struct file *file)
935{
936 unsigned int ret, i;
937 struct videobuf_queue *q;
938 struct omapvideo_info *ovid;
939 struct omap_vout_device *vout = file->private_data;
940
941 v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Entering %s\n", __func__);
942 ovid = &vout->vid_info;
943
944 if (!vout)
945 return 0;
946
947 q = &vout->vbq;
948 /* Disable all the overlay managers connected with this interface */
949 for (i = 0; i < ovid->num_overlays; i++) {
950 struct omap_overlay *ovl = ovid->overlays[i];
951 if (ovl->manager && ovl->manager->device)
952 ovl->disable(ovl);
953 }
954 /* Turn off the pipeline */
955 ret = omapvid_apply_changes(vout);
956 if (ret)
957 v4l2_warn(&vout->vid_dev->v4l2_dev,
958 "Unable to apply changes\n");
959
960 /* Free all buffers */
961 omap_vout_free_extra_buffers(vout);
962
963 /* Free the VRFB buffers only if they are allocated
964 * during reqbufs. Don't free if init time allocated
965 */
966 if (ovid->rotation_type == VOUT_ROT_VRFB) {
967 if (!vout->vrfb_static_allocation)
968 omap_vout_free_vrfb_buffers(vout);
969 }
970 videobuf_mmap_free(q);
971
972 /* Even if apply changes fails we should continue
973 freeing allocated memory */
974 if (vout->streaming) {
975 u32 mask = 0;
976
977 mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_EVEN |
978 DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_VSYNC2;
979 omap_dispc_unregister_isr(omap_vout_isr, vout, mask);
980 vout->streaming = 0;
981
982 videobuf_streamoff(q);
983 videobuf_queue_cancel(q);
984 }
985
986 if (vout->mmap_count != 0)
987 vout->mmap_count = 0;
988
989 vout->opened -= 1;
990 file->private_data = NULL;
991
992 if (vout->buffer_allocated)
993 videobuf_mmap_free(q);
994
995 v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Exiting %s\n", __func__);
996 return ret;
997}
998
999static int omap_vout_open(struct file *file)
1000{
1001 struct videobuf_queue *q;
1002 struct omap_vout_device *vout = NULL;
1003
1004 vout = video_drvdata(file);
1005 v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Entering %s\n", __func__);
1006
1007 if (vout == NULL)
1008 return -ENODEV;
1009
1010 /* for now, we only support single open */
1011 if (vout->opened)
1012 return -EBUSY;
1013
1014 vout->opened += 1;
1015
1016 file->private_data = vout;
1017 vout->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
1018
1019 q = &vout->vbq;
1020 video_vbq_ops.buf_setup = omap_vout_buffer_setup;
1021 video_vbq_ops.buf_prepare = omap_vout_buffer_prepare;
1022 video_vbq_ops.buf_release = omap_vout_buffer_release;
1023 video_vbq_ops.buf_queue = omap_vout_buffer_queue;
1024 spin_lock_init(&vout->vbq_lock);
1025
1026 videobuf_queue_dma_contig_init(q, &video_vbq_ops, q->dev,
1027 &vout->vbq_lock, vout->type, V4L2_FIELD_NONE,
1028 sizeof(struct videobuf_buffer), vout, NULL);
1029
1030 v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Exiting %s\n", __func__);
1031 return 0;
1032}
1033
1034/*
1035 * V4L2 ioctls
1036 */
1037static int vidioc_querycap(struct file *file, void *fh,
1038 struct v4l2_capability *cap)
1039{
1040 struct omap_vout_device *vout = fh;
1041
1042 strlcpy(cap->driver, VOUT_NAME, sizeof(cap->driver));
1043 strlcpy(cap->card, vout->vfd->name, sizeof(cap->card));
1044 cap->bus_info[0] = '\0';
1045 cap->capabilities = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_OUTPUT |
1046 V4L2_CAP_VIDEO_OUTPUT_OVERLAY;
1047
1048 return 0;
1049}
1050
1051static int vidioc_enum_fmt_vid_out(struct file *file, void *fh,
1052 struct v4l2_fmtdesc *fmt)
1053{
1054 int index = fmt->index;
1055
1056 if (index >= NUM_OUTPUT_FORMATS)
1057 return -EINVAL;
1058
1059 fmt->flags = omap_formats[index].flags;
1060 strlcpy(fmt->description, omap_formats[index].description,
1061 sizeof(fmt->description));
1062 fmt->pixelformat = omap_formats[index].pixelformat;
1063
1064 return 0;
1065}
1066
1067static int vidioc_g_fmt_vid_out(struct file *file, void *fh,
1068 struct v4l2_format *f)
1069{
1070 struct omap_vout_device *vout = fh;
1071
1072 f->fmt.pix = vout->pix;
1073 return 0;
1074
1075}
1076
1077static int vidioc_try_fmt_vid_out(struct file *file, void *fh,
1078 struct v4l2_format *f)
1079{
1080 struct omap_overlay *ovl;
1081 struct omapvideo_info *ovid;
1082 struct omap_video_timings *timing;
1083 struct omap_vout_device *vout = fh;
1084
1085 ovid = &vout->vid_info;
1086 ovl = ovid->overlays[0];
1087
1088 if (!ovl->manager || !ovl->manager->device)
1089 return -EINVAL;
1090 /* get the display device attached to the overlay */
1091 timing = &ovl->manager->device->panel.timings;
1092
1093 vout->fbuf.fmt.height = timing->y_res;
1094 vout->fbuf.fmt.width = timing->x_res;
1095
1096 omap_vout_try_format(&f->fmt.pix);
1097 return 0;
1098}
1099
1100static int vidioc_s_fmt_vid_out(struct file *file, void *fh,
1101 struct v4l2_format *f)
1102{
1103 int ret, bpp;
1104 struct omap_overlay *ovl;
1105 struct omapvideo_info *ovid;
1106 struct omap_video_timings *timing;
1107 struct omap_vout_device *vout = fh;
1108
1109 if (vout->streaming)
1110 return -EBUSY;
1111
1112 mutex_lock(&vout->lock);
1113
1114 ovid = &vout->vid_info;
1115 ovl = ovid->overlays[0];
1116
1117 /* get the display device attached to the overlay */
1118 if (!ovl->manager || !ovl->manager->device) {
1119 ret = -EINVAL;
1120 goto s_fmt_vid_out_exit;
1121 }
1122 timing = &ovl->manager->device->panel.timings;
1123
1124 /* We dont support RGB24-packed mode if vrfb rotation
1125 * is enabled*/
1126 if ((is_rotation_enabled(vout)) &&
1127 f->fmt.pix.pixelformat == V4L2_PIX_FMT_RGB24) {
1128 ret = -EINVAL;
1129 goto s_fmt_vid_out_exit;
1130 }
1131
1132 /* get the framebuffer parameters */
1133
1134 if (is_rotation_90_or_270(vout)) {
1135 vout->fbuf.fmt.height = timing->x_res;
1136 vout->fbuf.fmt.width = timing->y_res;
1137 } else {
1138 vout->fbuf.fmt.height = timing->y_res;
1139 vout->fbuf.fmt.width = timing->x_res;
1140 }
1141
1142 /* change to samller size is OK */
1143
1144 bpp = omap_vout_try_format(&f->fmt.pix);
1145 f->fmt.pix.sizeimage = f->fmt.pix.width * f->fmt.pix.height * bpp;
1146
1147 /* try & set the new output format */
1148 vout->bpp = bpp;
1149 vout->pix = f->fmt.pix;
1150 vout->vrfb_bpp = 1;
1151
1152 /* If YUYV then vrfb bpp is 2, for others its 1 */
1153 if (V4L2_PIX_FMT_YUYV == vout->pix.pixelformat ||
1154 V4L2_PIX_FMT_UYVY == vout->pix.pixelformat)
1155 vout->vrfb_bpp = 2;
1156
1157 /* set default crop and win */
1158 omap_vout_new_format(&vout->pix, &vout->fbuf, &vout->crop, &vout->win);
1159
1160 /* Save the changes in the overlay strcuture */
1161 ret = omapvid_init(vout, 0);
1162 if (ret) {
1163 v4l2_err(&vout->vid_dev->v4l2_dev, "failed to change mode\n");
1164 goto s_fmt_vid_out_exit;
1165 }
1166
1167 ret = 0;
1168
1169s_fmt_vid_out_exit:
1170 mutex_unlock(&vout->lock);
1171 return ret;
1172}
1173
1174static int vidioc_try_fmt_vid_overlay(struct file *file, void *fh,
1175 struct v4l2_format *f)
1176{
1177 int ret = 0;
1178 struct omap_vout_device *vout = fh;
1179 struct omap_overlay *ovl;
1180 struct omapvideo_info *ovid;
1181 struct v4l2_window *win = &f->fmt.win;
1182
1183 ovid = &vout->vid_info;
1184 ovl = ovid->overlays[0];
1185
1186 ret = omap_vout_try_window(&vout->fbuf, win);
1187
1188 if (!ret) {
1189 if ((ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) == 0)
1190 win->global_alpha = 255;
1191 else
1192 win->global_alpha = f->fmt.win.global_alpha;
1193 }
1194
1195 return ret;
1196}
1197
1198static int vidioc_s_fmt_vid_overlay(struct file *file, void *fh,
1199 struct v4l2_format *f)
1200{
1201 int ret = 0;
1202 struct omap_overlay *ovl;
1203 struct omapvideo_info *ovid;
1204 struct omap_vout_device *vout = fh;
1205 struct v4l2_window *win = &f->fmt.win;
1206
1207 mutex_lock(&vout->lock);
1208 ovid = &vout->vid_info;
1209 ovl = ovid->overlays[0];
1210
1211 ret = omap_vout_new_window(&vout->crop, &vout->win, &vout->fbuf, win);
1212 if (!ret) {
1213 /* Video1 plane does not support global alpha on OMAP3 */
1214 if ((ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) == 0)
1215 vout->win.global_alpha = 255;
1216 else
1217 vout->win.global_alpha = f->fmt.win.global_alpha;
1218
1219 vout->win.chromakey = f->fmt.win.chromakey;
1220 }
1221 mutex_unlock(&vout->lock);
1222 return ret;
1223}
1224
1225static int vidioc_enum_fmt_vid_overlay(struct file *file, void *fh,
1226 struct v4l2_fmtdesc *fmt)
1227{
1228 int index = fmt->index;
1229
1230 if (index >= NUM_OUTPUT_FORMATS)
1231 return -EINVAL;
1232
1233 fmt->flags = omap_formats[index].flags;
1234 strlcpy(fmt->description, omap_formats[index].description,
1235 sizeof(fmt->description));
1236 fmt->pixelformat = omap_formats[index].pixelformat;
1237 return 0;
1238}
1239
1240static int vidioc_g_fmt_vid_overlay(struct file *file, void *fh,
1241 struct v4l2_format *f)
1242{
1243 u32 key_value = 0;
1244 struct omap_overlay *ovl;
1245 struct omapvideo_info *ovid;
1246 struct omap_vout_device *vout = fh;
1247 struct omap_overlay_manager_info info;
1248 struct v4l2_window *win = &f->fmt.win;
1249
1250 ovid = &vout->vid_info;
1251 ovl = ovid->overlays[0];
1252
1253 win->w = vout->win.w;
1254 win->field = vout->win.field;
1255 win->global_alpha = vout->win.global_alpha;
1256
1257 if (ovl->manager && ovl->manager->get_manager_info) {
1258 ovl->manager->get_manager_info(ovl->manager, &info);
1259 key_value = info.trans_key;
1260 }
1261 win->chromakey = key_value;
1262 return 0;
1263}
1264
1265static int vidioc_cropcap(struct file *file, void *fh,
1266 struct v4l2_cropcap *cropcap)
1267{
1268 struct omap_vout_device *vout = fh;
1269 struct v4l2_pix_format *pix = &vout->pix;
1270
1271 if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
1272 return -EINVAL;
1273
1274 /* Width and height are always even */
1275 cropcap->bounds.width = pix->width & ~1;
1276 cropcap->bounds.height = pix->height & ~1;
1277
1278 omap_vout_default_crop(&vout->pix, &vout->fbuf, &cropcap->defrect);
1279 cropcap->pixelaspect.numerator = 1;
1280 cropcap->pixelaspect.denominator = 1;
1281 return 0;
1282}
1283
1284static int vidioc_g_crop(struct file *file, void *fh, struct v4l2_crop *crop)
1285{
1286 struct omap_vout_device *vout = fh;
1287
1288 if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
1289 return -EINVAL;
1290 crop->c = vout->crop;
1291 return 0;
1292}
1293
1294static int vidioc_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
1295{
1296 int ret = -EINVAL;
1297 struct omap_vout_device *vout = fh;
1298 struct omapvideo_info *ovid;
1299 struct omap_overlay *ovl;
1300 struct omap_video_timings *timing;
1301
1302 if (vout->streaming)
1303 return -EBUSY;
1304
1305 mutex_lock(&vout->lock);
1306 ovid = &vout->vid_info;
1307 ovl = ovid->overlays[0];
1308
1309 if (!ovl->manager || !ovl->manager->device) {
1310 ret = -EINVAL;
1311 goto s_crop_err;
1312 }
1313 /* get the display device attached to the overlay */
1314 timing = &ovl->manager->device->panel.timings;
1315
1316 if (is_rotation_90_or_270(vout)) {
1317 vout->fbuf.fmt.height = timing->x_res;
1318 vout->fbuf.fmt.width = timing->y_res;
1319 } else {
1320 vout->fbuf.fmt.height = timing->y_res;
1321 vout->fbuf.fmt.width = timing->x_res;
1322 }
1323
1324 if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
1325 ret = omap_vout_new_crop(&vout->pix, &vout->crop, &vout->win,
1326 &vout->fbuf, &crop->c);
1327
1328s_crop_err:
1329 mutex_unlock(&vout->lock);
1330 return ret;
1331}
1332
1333static int vidioc_queryctrl(struct file *file, void *fh,
1334 struct v4l2_queryctrl *ctrl)
1335{
1336 int ret = 0;
1337
1338 switch (ctrl->id) {
1339 case V4L2_CID_ROTATE:
1340 ret = v4l2_ctrl_query_fill(ctrl, 0, 270, 90, 0);
1341 break;
1342 case V4L2_CID_BG_COLOR:
1343 ret = v4l2_ctrl_query_fill(ctrl, 0, 0xFFFFFF, 1, 0);
1344 break;
1345 case V4L2_CID_VFLIP:
1346 ret = v4l2_ctrl_query_fill(ctrl, 0, 1, 1, 0);
1347 break;
1348 default:
1349 ctrl->name[0] = '\0';
1350 ret = -EINVAL;
1351 }
1352 return ret;
1353}
1354
1355static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *ctrl)
1356{
1357 int ret = 0;
1358 struct omap_vout_device *vout = fh;
1359
1360 switch (ctrl->id) {
1361 case V4L2_CID_ROTATE:
1362 ctrl->value = vout->control[0].value;
1363 break;
1364 case V4L2_CID_BG_COLOR:
1365 {
1366 struct omap_overlay_manager_info info;
1367 struct omap_overlay *ovl;
1368
1369 ovl = vout->vid_info.overlays[0];
1370 if (!ovl->manager || !ovl->manager->get_manager_info) {
1371 ret = -EINVAL;
1372 break;
1373 }
1374
1375 ovl->manager->get_manager_info(ovl->manager, &info);
1376 ctrl->value = info.default_color;
1377 break;
1378 }
1379 case V4L2_CID_VFLIP:
1380 ctrl->value = vout->control[2].value;
1381 break;
1382 default:
1383 ret = -EINVAL;
1384 }
1385 return ret;
1386}
1387
1388static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *a)
1389{
1390 int ret = 0;
1391 struct omap_vout_device *vout = fh;
1392
1393 switch (a->id) {
1394 case V4L2_CID_ROTATE:
1395 {
1396 struct omapvideo_info *ovid;
1397 int rotation = a->value;
1398
1399 ovid = &vout->vid_info;
1400
1401 mutex_lock(&vout->lock);
1402 if (rotation && ovid->rotation_type == VOUT_ROT_NONE) {
1403 mutex_unlock(&vout->lock);
1404 ret = -ERANGE;
1405 break;
1406 }
1407
1408 if (rotation && vout->pix.pixelformat == V4L2_PIX_FMT_RGB24) {
1409 mutex_unlock(&vout->lock);
1410 ret = -EINVAL;
1411 break;
1412 }
1413
1414 if (v4l2_rot_to_dss_rot(rotation, &vout->rotation,
1415 vout->mirror)) {
1416 mutex_unlock(&vout->lock);
1417 ret = -EINVAL;
1418 break;
1419 }
1420
1421 vout->control[0].value = rotation;
1422 mutex_unlock(&vout->lock);
1423 break;
1424 }
1425 case V4L2_CID_BG_COLOR:
1426 {
1427 struct omap_overlay *ovl;
1428 unsigned int color = a->value;
1429 struct omap_overlay_manager_info info;
1430
1431 ovl = vout->vid_info.overlays[0];
1432
1433 mutex_lock(&vout->lock);
1434 if (!ovl->manager || !ovl->manager->get_manager_info) {
1435 mutex_unlock(&vout->lock);
1436 ret = -EINVAL;
1437 break;
1438 }
1439
1440 ovl->manager->get_manager_info(ovl->manager, &info);
1441 info.default_color = color;
1442 if (ovl->manager->set_manager_info(ovl->manager, &info)) {
1443 mutex_unlock(&vout->lock);
1444 ret = -EINVAL;
1445 break;
1446 }
1447
1448 vout->control[1].value = color;
1449 mutex_unlock(&vout->lock);
1450 break;
1451 }
1452 case V4L2_CID_VFLIP:
1453 {
1454 struct omap_overlay *ovl;
1455 struct omapvideo_info *ovid;
1456 unsigned int mirror = a->value;
1457
1458 ovid = &vout->vid_info;
1459 ovl = ovid->overlays[0];
1460
1461 mutex_lock(&vout->lock);
1462 if (mirror && ovid->rotation_type == VOUT_ROT_NONE) {
1463 mutex_unlock(&vout->lock);
1464 ret = -ERANGE;
1465 break;
1466 }
1467
1468 if (mirror && vout->pix.pixelformat == V4L2_PIX_FMT_RGB24) {
1469 mutex_unlock(&vout->lock);
1470 ret = -EINVAL;
1471 break;
1472 }
1473 vout->mirror = mirror;
1474 vout->control[2].value = mirror;
1475 mutex_unlock(&vout->lock);
1476 break;
1477 }
1478 default:
1479 ret = -EINVAL;
1480 }
1481 return ret;
1482}
1483
1484static int vidioc_reqbufs(struct file *file, void *fh,
1485 struct v4l2_requestbuffers *req)
1486{
1487 int ret = 0;
1488 unsigned int i, num_buffers = 0;
1489 struct omap_vout_device *vout = fh;
1490 struct videobuf_queue *q = &vout->vbq;
1491
1492 if ((req->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) || (req->count < 0))
1493 return -EINVAL;
1494 /* if memory is not mmp or userptr
1495 return error */
1496 if ((V4L2_MEMORY_MMAP != req->memory) &&
1497 (V4L2_MEMORY_USERPTR != req->memory))
1498 return -EINVAL;
1499
1500 mutex_lock(&vout->lock);
1501 /* Cannot be requested when streaming is on */
1502 if (vout->streaming) {
1503 ret = -EBUSY;
1504 goto reqbuf_err;
1505 }
1506
1507 /* If buffers are already allocated free them */
1508 if (q->bufs[0] && (V4L2_MEMORY_MMAP == q->bufs[0]->memory)) {
1509 if (vout->mmap_count) {
1510 ret = -EBUSY;
1511 goto reqbuf_err;
1512 }
1513 num_buffers = (vout->vid == OMAP_VIDEO1) ?
1514 video1_numbuffers : video2_numbuffers;
1515 for (i = num_buffers; i < vout->buffer_allocated; i++) {
1516 omap_vout_free_buffer(vout->buf_virt_addr[i],
1517 vout->buffer_size);
1518 vout->buf_virt_addr[i] = 0;
1519 vout->buf_phy_addr[i] = 0;
1520 }
1521 vout->buffer_allocated = num_buffers;
1522 videobuf_mmap_free(q);
1523 } else if (q->bufs[0] && (V4L2_MEMORY_USERPTR == q->bufs[0]->memory)) {
1524 if (vout->buffer_allocated) {
1525 videobuf_mmap_free(q);
1526 for (i = 0; i < vout->buffer_allocated; i++) {
1527 kfree(q->bufs[i]);
1528 q->bufs[i] = NULL;
1529 }
1530 vout->buffer_allocated = 0;
1531 }
1532 }
1533
1534 /*store the memory type in data structure */
1535 vout->memory = req->memory;
1536
1537 INIT_LIST_HEAD(&vout->dma_queue);
1538
1539 /* call videobuf_reqbufs api */
1540 ret = videobuf_reqbufs(q, req);
1541 if (ret < 0)
1542 goto reqbuf_err;
1543
1544 vout->buffer_allocated = req->count;
1545
1546reqbuf_err:
1547 mutex_unlock(&vout->lock);
1548 return ret;
1549}
1550
1551static int vidioc_querybuf(struct file *file, void *fh,
1552 struct v4l2_buffer *b)
1553{
1554 struct omap_vout_device *vout = fh;
1555
1556 return videobuf_querybuf(&vout->vbq, b);
1557}
1558
1559static int vidioc_qbuf(struct file *file, void *fh,
1560 struct v4l2_buffer *buffer)
1561{
1562 struct omap_vout_device *vout = fh;
1563 struct videobuf_queue *q = &vout->vbq;
1564
1565 if ((V4L2_BUF_TYPE_VIDEO_OUTPUT != buffer->type) ||
1566 (buffer->index >= vout->buffer_allocated) ||
1567 (q->bufs[buffer->index]->memory != buffer->memory)) {
1568 return -EINVAL;
1569 }
1570 if (V4L2_MEMORY_USERPTR == buffer->memory) {
1571 if ((buffer->length < vout->pix.sizeimage) ||
1572 (0 == buffer->m.userptr)) {
1573 return -EINVAL;
1574 }
1575 }
1576
1577 if ((is_rotation_enabled(vout)) &&
1578 vout->vrfb_dma_tx.req_status == DMA_CHAN_NOT_ALLOTED) {
1579 v4l2_warn(&vout->vid_dev->v4l2_dev,
1580 "DMA Channel not allocated for Rotation\n");
1581 return -EINVAL;
1582 }
1583
1584 return videobuf_qbuf(q, buffer);
1585}
1586
1587static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b)
1588{
1589 struct omap_vout_device *vout = fh;
1590 struct videobuf_queue *q = &vout->vbq;
1591
1592 int ret;
1593 u32 addr;
1594 unsigned long size;
1595 struct videobuf_buffer *vb;
1596
1597 vb = q->bufs[b->index];
1598
1599 if (!vout->streaming)
1600 return -EINVAL;
1601
1602 if (file->f_flags & O_NONBLOCK)
1603 /* Call videobuf_dqbuf for non blocking mode */
1604 ret = videobuf_dqbuf(q, (struct v4l2_buffer *)b, 1);
1605 else
1606 /* Call videobuf_dqbuf for blocking mode */
1607 ret = videobuf_dqbuf(q, (struct v4l2_buffer *)b, 0);
1608
1609 addr = (unsigned long) vout->buf_phy_addr[vb->i];
1610 size = (unsigned long) vb->size;
1611 dma_unmap_single(vout->vid_dev->v4l2_dev.dev, addr,
1612 size, DMA_TO_DEVICE);
1613 return ret;
1614}
1615
1616static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
1617{
1618 int ret = 0, j;
1619 u32 addr = 0, mask = 0;
1620 struct omap_vout_device *vout = fh;
1621 struct videobuf_queue *q = &vout->vbq;
1622 struct omapvideo_info *ovid = &vout->vid_info;
1623
1624 mutex_lock(&vout->lock);
1625
1626 if (vout->streaming) {
1627 ret = -EBUSY;
1628 goto streamon_err;
1629 }
1630
1631 ret = videobuf_streamon(q);
1632 if (ret)
1633 goto streamon_err;
1634
1635 if (list_empty(&vout->dma_queue)) {
1636 ret = -EIO;
1637 goto streamon_err1;
1638 }
1639
1640 /* Get the next frame from the buffer queue */
1641 vout->next_frm = vout->cur_frm = list_entry(vout->dma_queue.next,
1642 struct videobuf_buffer, queue);
1643 /* Remove buffer from the buffer queue */
1644 list_del(&vout->cur_frm->queue);
1645 /* Mark state of the current frame to active */
1646 vout->cur_frm->state = VIDEOBUF_ACTIVE;
1647 /* Initialize field_id and started member */
1648 vout->field_id = 0;
1649
1650 /* set flag here. Next QBUF will start DMA */
1651 vout->streaming = 1;
1652
1653 vout->first_int = 1;
1654
1655 if (omap_vout_calculate_offset(vout)) {
1656 ret = -EINVAL;
1657 goto streamon_err1;
1658 }
1659 addr = (unsigned long) vout->queued_buf_addr[vout->cur_frm->i]
1660 + vout->cropped_offset;
1661
1662 mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD
1663 | DISPC_IRQ_VSYNC2;
1664
1665 omap_dispc_register_isr(omap_vout_isr, vout, mask);
1666
1667 for (j = 0; j < ovid->num_overlays; j++) {
1668 struct omap_overlay *ovl = ovid->overlays[j];
1669
1670 if (ovl->manager && ovl->manager->device) {
1671 struct omap_overlay_info info;
1672 ovl->get_overlay_info(ovl, &info);
1673 info.paddr = addr;
1674 if (ovl->set_overlay_info(ovl, &info)) {
1675 ret = -EINVAL;
1676 goto streamon_err1;
1677 }
1678 }
1679 }
1680
1681 /* First save the configuration in ovelray structure */
1682 ret = omapvid_init(vout, addr);
1683 if (ret)
1684 v4l2_err(&vout->vid_dev->v4l2_dev,
1685 "failed to set overlay info\n");
1686 /* Enable the pipeline and set the Go bit */
1687 ret = omapvid_apply_changes(vout);
1688 if (ret)
1689 v4l2_err(&vout->vid_dev->v4l2_dev, "failed to change mode\n");
1690
1691 for (j = 0; j < ovid->num_overlays; j++) {
1692 struct omap_overlay *ovl = ovid->overlays[j];
1693
1694 if (ovl->manager && ovl->manager->device) {
1695 ret = ovl->enable(ovl);
1696 if (ret)
1697 goto streamon_err1;
1698 }
1699 }
1700
1701 ret = 0;
1702
1703streamon_err1:
1704 if (ret)
1705 ret = videobuf_streamoff(q);
1706streamon_err:
1707 mutex_unlock(&vout->lock);
1708 return ret;
1709}
1710
1711static int vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i)
1712{
1713 u32 mask = 0;
1714 int ret = 0, j;
1715 struct omap_vout_device *vout = fh;
1716 struct omapvideo_info *ovid = &vout->vid_info;
1717
1718 if (!vout->streaming)
1719 return -EINVAL;
1720
1721 vout->streaming = 0;
1722 mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD
1723 | DISPC_IRQ_VSYNC2;
1724
1725 omap_dispc_unregister_isr(omap_vout_isr, vout, mask);
1726
1727 for (j = 0; j < ovid->num_overlays; j++) {
1728 struct omap_overlay *ovl = ovid->overlays[j];
1729
1730 if (ovl->manager && ovl->manager->device)
1731 ovl->disable(ovl);
1732 }
1733
1734 /* Turn of the pipeline */
1735 ret = omapvid_apply_changes(vout);
1736 if (ret)
1737 v4l2_err(&vout->vid_dev->v4l2_dev, "failed to change mode in"
1738 " streamoff\n");
1739
1740 INIT_LIST_HEAD(&vout->dma_queue);
1741 ret = videobuf_streamoff(&vout->vbq);
1742
1743 return ret;
1744}
1745
1746static int vidioc_s_fbuf(struct file *file, void *fh,
1747 struct v4l2_framebuffer *a)
1748{
1749 int enable = 0;
1750 struct omap_overlay *ovl;
1751 struct omapvideo_info *ovid;
1752 struct omap_vout_device *vout = fh;
1753 struct omap_overlay_manager_info info;
1754 enum omap_dss_trans_key_type key_type = OMAP_DSS_COLOR_KEY_GFX_DST;
1755
1756 ovid = &vout->vid_info;
1757 ovl = ovid->overlays[0];
1758
1759 /* OMAP DSS doesn't support Source and Destination color
1760 key together */
1761 if ((a->flags & V4L2_FBUF_FLAG_SRC_CHROMAKEY) &&
1762 (a->flags & V4L2_FBUF_FLAG_CHROMAKEY))
1763 return -EINVAL;
1764 /* OMAP DSS Doesn't support the Destination color key
1765 and alpha blending together */
1766 if ((a->flags & V4L2_FBUF_FLAG_CHROMAKEY) &&
1767 (a->flags & V4L2_FBUF_FLAG_LOCAL_ALPHA))
1768 return -EINVAL;
1769
1770 if ((a->flags & V4L2_FBUF_FLAG_SRC_CHROMAKEY)) {
1771 vout->fbuf.flags |= V4L2_FBUF_FLAG_SRC_CHROMAKEY;
1772 key_type = OMAP_DSS_COLOR_KEY_VID_SRC;
1773 } else
1774 vout->fbuf.flags &= ~V4L2_FBUF_FLAG_SRC_CHROMAKEY;
1775
1776 if ((a->flags & V4L2_FBUF_FLAG_CHROMAKEY)) {
1777 vout->fbuf.flags |= V4L2_FBUF_FLAG_CHROMAKEY;
1778 key_type = OMAP_DSS_COLOR_KEY_GFX_DST;
1779 } else
1780 vout->fbuf.flags &= ~V4L2_FBUF_FLAG_CHROMAKEY;
1781
1782 if (a->flags & (V4L2_FBUF_FLAG_CHROMAKEY |
1783 V4L2_FBUF_FLAG_SRC_CHROMAKEY))
1784 enable = 1;
1785 else
1786 enable = 0;
1787 if (ovl->manager && ovl->manager->get_manager_info &&
1788 ovl->manager->set_manager_info) {
1789
1790 ovl->manager->get_manager_info(ovl->manager, &info);
1791 info.trans_enabled = enable;
1792 info.trans_key_type = key_type;
1793 info.trans_key = vout->win.chromakey;
1794
1795 if (ovl->manager->set_manager_info(ovl->manager, &info))
1796 return -EINVAL;
1797 }
1798 if (a->flags & V4L2_FBUF_FLAG_LOCAL_ALPHA) {
1799 vout->fbuf.flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA;
1800 enable = 1;
1801 } else {
1802 vout->fbuf.flags &= ~V4L2_FBUF_FLAG_LOCAL_ALPHA;
1803 enable = 0;
1804 }
1805 if (ovl->manager && ovl->manager->get_manager_info &&
1806 ovl->manager->set_manager_info) {
1807 ovl->manager->get_manager_info(ovl->manager, &info);
1808 /* enable this only if there is no zorder cap */
1809 if ((ovl->caps & OMAP_DSS_OVL_CAP_ZORDER) == 0)
1810 info.partial_alpha_enabled = enable;
1811 if (ovl->manager->set_manager_info(ovl->manager, &info))
1812 return -EINVAL;
1813 }
1814
1815 return 0;
1816}
1817
1818static int vidioc_g_fbuf(struct file *file, void *fh,
1819 struct v4l2_framebuffer *a)
1820{
1821 struct omap_overlay *ovl;
1822 struct omapvideo_info *ovid;
1823 struct omap_vout_device *vout = fh;
1824 struct omap_overlay_manager_info info;
1825
1826 ovid = &vout->vid_info;
1827 ovl = ovid->overlays[0];
1828
1829 /* The video overlay must stay within the framebuffer and can't be
1830 positioned independently. */
1831 a->flags = V4L2_FBUF_FLAG_OVERLAY;
1832 a->capability = V4L2_FBUF_CAP_LOCAL_ALPHA | V4L2_FBUF_CAP_CHROMAKEY
1833 | V4L2_FBUF_CAP_SRC_CHROMAKEY;
1834
1835 if (ovl->manager && ovl->manager->get_manager_info) {
1836 ovl->manager->get_manager_info(ovl->manager, &info);
1837 if (info.trans_key_type == OMAP_DSS_COLOR_KEY_VID_SRC)
1838 a->flags |= V4L2_FBUF_FLAG_SRC_CHROMAKEY;
1839 if (info.trans_key_type == OMAP_DSS_COLOR_KEY_GFX_DST)
1840 a->flags |= V4L2_FBUF_FLAG_CHROMAKEY;
1841 }
1842 if (ovl->manager && ovl->manager->get_manager_info) {
1843 ovl->manager->get_manager_info(ovl->manager, &info);
1844 if (info.partial_alpha_enabled)
1845 a->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA;
1846 }
1847
1848 return 0;
1849}
1850
1851static const struct v4l2_ioctl_ops vout_ioctl_ops = {
1852 .vidioc_querycap = vidioc_querycap,
1853 .vidioc_enum_fmt_vid_out = vidioc_enum_fmt_vid_out,
1854 .vidioc_g_fmt_vid_out = vidioc_g_fmt_vid_out,
1855 .vidioc_try_fmt_vid_out = vidioc_try_fmt_vid_out,
1856 .vidioc_s_fmt_vid_out = vidioc_s_fmt_vid_out,
1857 .vidioc_queryctrl = vidioc_queryctrl,
1858 .vidioc_g_ctrl = vidioc_g_ctrl,
1859 .vidioc_s_fbuf = vidioc_s_fbuf,
1860 .vidioc_g_fbuf = vidioc_g_fbuf,
1861 .vidioc_s_ctrl = vidioc_s_ctrl,
1862 .vidioc_try_fmt_vid_overlay = vidioc_try_fmt_vid_overlay,
1863 .vidioc_s_fmt_vid_overlay = vidioc_s_fmt_vid_overlay,
1864 .vidioc_enum_fmt_vid_overlay = vidioc_enum_fmt_vid_overlay,
1865 .vidioc_g_fmt_vid_overlay = vidioc_g_fmt_vid_overlay,
1866 .vidioc_cropcap = vidioc_cropcap,
1867 .vidioc_g_crop = vidioc_g_crop,
1868 .vidioc_s_crop = vidioc_s_crop,
1869 .vidioc_reqbufs = vidioc_reqbufs,
1870 .vidioc_querybuf = vidioc_querybuf,
1871 .vidioc_qbuf = vidioc_qbuf,
1872 .vidioc_dqbuf = vidioc_dqbuf,
1873 .vidioc_streamon = vidioc_streamon,
1874 .vidioc_streamoff = vidioc_streamoff,
1875};
1876
1877static const struct v4l2_file_operations omap_vout_fops = {
1878 .owner = THIS_MODULE,
1879 .poll = omap_vout_poll,
1880 .unlocked_ioctl = video_ioctl2,
1881 .mmap = omap_vout_mmap,
1882 .open = omap_vout_open,
1883 .release = omap_vout_release,
1884};
1885
1886/* Init functions used during driver initialization */
1887/* Initial setup of video_data */
1888static int __init omap_vout_setup_video_data(struct omap_vout_device *vout)
1889{
1890 struct video_device *vfd;
1891 struct v4l2_pix_format *pix;
1892 struct v4l2_control *control;
1893 struct omap_dss_device *display =
1894 vout->vid_info.overlays[0]->manager->device;
1895
1896 /* set the default pix */
1897 pix = &vout->pix;
1898
1899 /* Set the default picture of QVGA */
1900 pix->width = QQVGA_WIDTH;
1901 pix->height = QQVGA_HEIGHT;
1902
1903 /* Default pixel format is RGB 5-6-5 */
1904 pix->pixelformat = V4L2_PIX_FMT_RGB565;
1905 pix->field = V4L2_FIELD_ANY;
1906 pix->bytesperline = pix->width * 2;
1907 pix->sizeimage = pix->bytesperline * pix->height;
1908 pix->priv = 0;
1909 pix->colorspace = V4L2_COLORSPACE_JPEG;
1910
1911 vout->bpp = RGB565_BPP;
1912 vout->fbuf.fmt.width = display->panel.timings.x_res;
1913 vout->fbuf.fmt.height = display->panel.timings.y_res;
1914
1915 /* Set the data structures for the overlay parameters*/
1916 vout->win.global_alpha = 255;
1917 vout->fbuf.flags = 0;
1918 vout->fbuf.capability = V4L2_FBUF_CAP_LOCAL_ALPHA |
1919 V4L2_FBUF_CAP_SRC_CHROMAKEY | V4L2_FBUF_CAP_CHROMAKEY;
1920 vout->win.chromakey = 0;
1921
1922 omap_vout_new_format(pix, &vout->fbuf, &vout->crop, &vout->win);
1923
1924 /*Initialize the control variables for
1925 rotation, flipping and background color. */
1926 control = vout->control;
1927 control[0].id = V4L2_CID_ROTATE;
1928 control[0].value = 0;
1929 vout->rotation = 0;
1930 vout->mirror = 0;
1931 vout->control[2].id = V4L2_CID_HFLIP;
1932 vout->control[2].value = 0;
1933 if (vout->vid_info.rotation_type == VOUT_ROT_VRFB)
1934 vout->vrfb_bpp = 2;
1935
1936 control[1].id = V4L2_CID_BG_COLOR;
1937 control[1].value = 0;
1938
1939 /* initialize the video_device struct */
1940 vfd = vout->vfd = video_device_alloc();
1941
1942 if (!vfd) {
1943 printk(KERN_ERR VOUT_NAME ": could not allocate"
1944 " video device struct\n");
1945 return -ENOMEM;
1946 }
1947 vfd->release = video_device_release;
1948 vfd->ioctl_ops = &vout_ioctl_ops;
1949
1950 strlcpy(vfd->name, VOUT_NAME, sizeof(vfd->name));
1951
1952 vfd->fops = &omap_vout_fops;
1953 vfd->v4l2_dev = &vout->vid_dev->v4l2_dev;
1954 mutex_init(&vout->lock);
1955
1956 vfd->minor = -1;
1957 return 0;
1958
1959}
1960
1961/* Setup video buffers */
1962static int __init omap_vout_setup_video_bufs(struct platform_device *pdev,
1963 int vid_num)
1964{
1965 u32 numbuffers;
1966 int ret = 0, i;
1967 struct omapvideo_info *ovid;
1968 struct omap_vout_device *vout;
1969 struct v4l2_device *v4l2_dev = platform_get_drvdata(pdev);
1970 struct omap2video_device *vid_dev =
1971 container_of(v4l2_dev, struct omap2video_device, v4l2_dev);
1972
1973 vout = vid_dev->vouts[vid_num];
1974 ovid = &vout->vid_info;
1975
1976 numbuffers = (vid_num == 0) ? video1_numbuffers : video2_numbuffers;
1977 vout->buffer_size = (vid_num == 0) ? video1_bufsize : video2_bufsize;
1978 dev_info(&pdev->dev, "Buffer Size = %d\n", vout->buffer_size);
1979
1980 for (i = 0; i < numbuffers; i++) {
1981 vout->buf_virt_addr[i] =
1982 omap_vout_alloc_buffer(vout->buffer_size,
1983 (u32 *) &vout->buf_phy_addr[i]);
1984 if (!vout->buf_virt_addr[i]) {
1985 numbuffers = i;
1986 ret = -ENOMEM;
1987 goto free_buffers;
1988 }
1989 }
1990
1991 vout->cropped_offset = 0;
1992
1993 if (ovid->rotation_type == VOUT_ROT_VRFB) {
1994 int static_vrfb_allocation = (vid_num == 0) ?
1995 vid1_static_vrfb_alloc : vid2_static_vrfb_alloc;
1996 ret = omap_vout_setup_vrfb_bufs(pdev, vid_num,
1997 static_vrfb_allocation);
1998 }
1999
2000 return ret;
2001
2002free_buffers:
2003 for (i = 0; i < numbuffers; i++) {
2004 omap_vout_free_buffer(vout->buf_virt_addr[i],
2005 vout->buffer_size);
2006 vout->buf_virt_addr[i] = 0;
2007 vout->buf_phy_addr[i] = 0;
2008 }
2009 return ret;
2010
2011}
2012
2013/* Create video out devices */
2014static int __init omap_vout_create_video_devices(struct platform_device *pdev)
2015{
2016 int ret = 0, k;
2017 struct omap_vout_device *vout;
2018 struct video_device *vfd = NULL;
2019 struct v4l2_device *v4l2_dev = platform_get_drvdata(pdev);
2020 struct omap2video_device *vid_dev = container_of(v4l2_dev,
2021 struct omap2video_device, v4l2_dev);
2022
2023 for (k = 0; k < pdev->num_resources; k++) {
2024
2025 vout = kzalloc(sizeof(struct omap_vout_device), GFP_KERNEL);
2026 if (!vout) {
2027 dev_err(&pdev->dev, ": could not allocate memory\n");
2028 return -ENOMEM;
2029 }
2030
2031 vout->vid = k;
2032 vid_dev->vouts[k] = vout;
2033 vout->vid_dev = vid_dev;
2034 /* Select video2 if only 1 overlay is controlled by V4L2 */
2035 if (pdev->num_resources == 1)
2036 vout->vid_info.overlays[0] = vid_dev->overlays[k + 2];
2037 else
2038 /* Else select video1 and video2 one by one. */
2039 vout->vid_info.overlays[0] = vid_dev->overlays[k + 1];
2040 vout->vid_info.num_overlays = 1;
2041 vout->vid_info.id = k + 1;
2042
2043 /* Set VRFB as rotation_type for omap2 and omap3 */
2044 if (cpu_is_omap24xx() || cpu_is_omap34xx())
2045 vout->vid_info.rotation_type = VOUT_ROT_VRFB;
2046
2047 /* Setup the default configuration for the video devices
2048 */
2049 if (omap_vout_setup_video_data(vout) != 0) {
2050 ret = -ENOMEM;
2051 goto error;
2052 }
2053
2054 /* Allocate default number of buffers for the video streaming
2055 * and reserve the VRFB space for rotation
2056 */
2057 if (omap_vout_setup_video_bufs(pdev, k) != 0) {
2058 ret = -ENOMEM;
2059 goto error1;
2060 }
2061
2062 /* Register the Video device with V4L2
2063 */
2064 vfd = vout->vfd;
2065 if (video_register_device(vfd, VFL_TYPE_GRABBER, -1) < 0) {
2066 dev_err(&pdev->dev, ": Could not register "
2067 "Video for Linux device\n");
2068 vfd->minor = -1;
2069 ret = -ENODEV;
2070 goto error2;
2071 }
2072 video_set_drvdata(vfd, vout);
2073
2074 /* Configure the overlay structure */
2075 ret = omapvid_init(vid_dev->vouts[k], 0);
2076 if (!ret)
2077 goto success;
2078
2079error2:
2080 if (vout->vid_info.rotation_type == VOUT_ROT_VRFB)
2081 omap_vout_release_vrfb(vout);
2082 omap_vout_free_buffers(vout);
2083error1:
2084 video_device_release(vfd);
2085error:
2086 kfree(vout);
2087 return ret;
2088
2089success:
2090 dev_info(&pdev->dev, ": registered and initialized"
2091 " video device %d\n", vfd->minor);
2092 if (k == (pdev->num_resources - 1))
2093 return 0;
2094 }
2095
2096 return -ENODEV;
2097}
2098/* Driver functions */
2099static void omap_vout_cleanup_device(struct omap_vout_device *vout)
2100{
2101 struct video_device *vfd;
2102 struct omapvideo_info *ovid;
2103
2104 if (!vout)
2105 return;
2106
2107 vfd = vout->vfd;
2108 ovid = &vout->vid_info;
2109 if (vfd) {
2110 if (!video_is_registered(vfd)) {
2111 /*
2112 * The device was never registered, so release the
2113 * video_device struct directly.
2114 */
2115 video_device_release(vfd);
2116 } else {
2117 /*
2118 * The unregister function will release the video_device
2119 * struct as well as unregistering it.
2120 */
2121 video_unregister_device(vfd);
2122 }
2123 }
2124 if (ovid->rotation_type == VOUT_ROT_VRFB) {
2125 omap_vout_release_vrfb(vout);
2126 /* Free the VRFB buffer if allocated
2127 * init time
2128 */
2129 if (vout->vrfb_static_allocation)
2130 omap_vout_free_vrfb_buffers(vout);
2131 }
2132 omap_vout_free_buffers(vout);
2133
2134 kfree(vout);
2135}
2136
2137static int omap_vout_remove(struct platform_device *pdev)
2138{
2139 int k;
2140 struct v4l2_device *v4l2_dev = platform_get_drvdata(pdev);
2141 struct omap2video_device *vid_dev = container_of(v4l2_dev, struct
2142 omap2video_device, v4l2_dev);
2143
2144 v4l2_device_unregister(v4l2_dev);
2145 for (k = 0; k < pdev->num_resources; k++)
2146 omap_vout_cleanup_device(vid_dev->vouts[k]);
2147
2148 for (k = 0; k < vid_dev->num_displays; k++) {
2149 if (vid_dev->displays[k]->state != OMAP_DSS_DISPLAY_DISABLED)
2150 vid_dev->displays[k]->driver->disable(vid_dev->displays[k]);
2151
2152 omap_dss_put_device(vid_dev->displays[k]);
2153 }
2154 kfree(vid_dev);
2155 return 0;
2156}
2157
2158static int __init omap_vout_probe(struct platform_device *pdev)
2159{
2160 int ret = 0, i;
2161 struct omap_overlay *ovl;
2162 struct omap_dss_device *dssdev = NULL;
2163 struct omap_dss_device *def_display;
2164 struct omap2video_device *vid_dev = NULL;
2165
2166 if (pdev->num_resources == 0) {
2167 dev_err(&pdev->dev, "probed for an unknown device\n");
2168 return -ENODEV;
2169 }
2170
2171 vid_dev = kzalloc(sizeof(struct omap2video_device), GFP_KERNEL);
2172 if (vid_dev == NULL)
2173 return -ENOMEM;
2174
2175 vid_dev->num_displays = 0;
2176 for_each_dss_dev(dssdev) {
2177 omap_dss_get_device(dssdev);
2178
2179 if (!dssdev->driver) {
2180 dev_warn(&pdev->dev, "no driver for display: %s\n",
2181 dssdev->name);
2182 omap_dss_put_device(dssdev);
2183 continue;
2184 }
2185
2186 vid_dev->displays[vid_dev->num_displays++] = dssdev;
2187 }
2188
2189 if (vid_dev->num_displays == 0) {
2190 dev_err(&pdev->dev, "no displays\n");
2191 ret = -EINVAL;
2192 goto probe_err0;
2193 }
2194
2195 vid_dev->num_overlays = omap_dss_get_num_overlays();
2196 for (i = 0; i < vid_dev->num_overlays; i++)
2197 vid_dev->overlays[i] = omap_dss_get_overlay(i);
2198
2199 vid_dev->num_managers = omap_dss_get_num_overlay_managers();
2200 for (i = 0; i < vid_dev->num_managers; i++)
2201 vid_dev->managers[i] = omap_dss_get_overlay_manager(i);
2202
2203 /* Get the Video1 overlay and video2 overlay.
2204 * Setup the Display attached to that overlays
2205 */
2206 for (i = 1; i < vid_dev->num_overlays; i++) {
2207 ovl = omap_dss_get_overlay(i);
2208 if (ovl->manager && ovl->manager->device) {
2209 def_display = ovl->manager->device;
2210 } else {
2211 dev_warn(&pdev->dev, "cannot find display\n");
2212 def_display = NULL;
2213 }
2214 if (def_display) {
2215 struct omap_dss_driver *dssdrv = def_display->driver;
2216
2217 ret = dssdrv->enable(def_display);
2218 if (ret) {
2219 /* Here we are not considering a error
2220 * as display may be enabled by frame
2221 * buffer driver
2222 */
2223 dev_warn(&pdev->dev,
2224 "'%s' Display already enabled\n",
2225 def_display->name);
2226 }
2227 }
2228 }
2229
2230 if (v4l2_device_register(&pdev->dev, &vid_dev->v4l2_dev) < 0) {
2231 dev_err(&pdev->dev, "v4l2_device_register failed\n");
2232 ret = -ENODEV;
2233 goto probe_err1;
2234 }
2235
2236 ret = omap_vout_create_video_devices(pdev);
2237 if (ret)
2238 goto probe_err2;
2239
2240 for (i = 0; i < vid_dev->num_displays; i++) {
2241 struct omap_dss_device *display = vid_dev->displays[i];
2242
2243 if (display->driver->update)
2244 display->driver->update(display, 0, 0,
2245 display->panel.timings.x_res,
2246 display->panel.timings.y_res);
2247 }
2248 return 0;
2249
2250probe_err2:
2251 v4l2_device_unregister(&vid_dev->v4l2_dev);
2252probe_err1:
2253 for (i = 1; i < vid_dev->num_overlays; i++) {
2254 def_display = NULL;
2255 ovl = omap_dss_get_overlay(i);
2256 if (ovl->manager && ovl->manager->device)
2257 def_display = ovl->manager->device;
2258
2259 if (def_display && def_display->driver)
2260 def_display->driver->disable(def_display);
2261 }
2262probe_err0:
2263 kfree(vid_dev);
2264 return ret;
2265}
2266
2267static struct platform_driver omap_vout_driver = {
2268 .driver = {
2269 .name = VOUT_NAME,
2270 },
2271 .remove = omap_vout_remove,
2272};
2273
2274static int __init omap_vout_init(void)
2275{
2276 if (platform_driver_probe(&omap_vout_driver, omap_vout_probe) != 0) {
2277 printk(KERN_ERR VOUT_NAME ":Could not register Video driver\n");
2278 return -EINVAL;
2279 }
2280 return 0;
2281}
2282
2283static void omap_vout_cleanup(void)
2284{
2285 platform_driver_unregister(&omap_vout_driver);
2286}
2287
2288late_initcall(omap_vout_init);
2289module_exit(omap_vout_cleanup);
diff --git a/drivers/media/video/omap/omap_vout_vrfb.c b/drivers/media/video/omap/omap_vout_vrfb.c
deleted file mode 100644
index 4be26abf6cea..000000000000
--- a/drivers/media/video/omap/omap_vout_vrfb.c
+++ /dev/null
@@ -1,390 +0,0 @@
1/*
2 * omap_vout_vrfb.c
3 *
4 * Copyright (C) 2010 Texas Instruments.
5 *
6 * This file is licensed under the terms of the GNU General Public License
7 * version 2. This program is licensed "as is" without any warranty of any
8 * kind, whether express or implied.
9 *
10 */
11
12#include <linux/sched.h>
13#include <linux/platform_device.h>
14#include <linux/videodev2.h>
15
16#include <media/videobuf-dma-contig.h>
17#include <media/v4l2-device.h>
18
19#include <plat/dma.h>
20#include <plat/vrfb.h>
21
22#include "omap_voutdef.h"
23#include "omap_voutlib.h"
24
25/*
26 * Function for allocating video buffers
27 */
28static int omap_vout_allocate_vrfb_buffers(struct omap_vout_device *vout,
29 unsigned int *count, int startindex)
30{
31 int i, j;
32
33 for (i = 0; i < *count; i++) {
34 if (!vout->smsshado_virt_addr[i]) {
35 vout->smsshado_virt_addr[i] =
36 omap_vout_alloc_buffer(vout->smsshado_size,
37 &vout->smsshado_phy_addr[i]);
38 }
39 if (!vout->smsshado_virt_addr[i] && startindex != -1) {
40 if (V4L2_MEMORY_MMAP == vout->memory && i >= startindex)
41 break;
42 }
43 if (!vout->smsshado_virt_addr[i]) {
44 for (j = 0; j < i; j++) {
45 omap_vout_free_buffer(
46 vout->smsshado_virt_addr[j],
47 vout->smsshado_size);
48 vout->smsshado_virt_addr[j] = 0;
49 vout->smsshado_phy_addr[j] = 0;
50 }
51 *count = 0;
52 return -ENOMEM;
53 }
54 memset((void *) vout->smsshado_virt_addr[i], 0,
55 vout->smsshado_size);
56 }
57 return 0;
58}
59
60/*
61 * Wakes up the application once the DMA transfer to VRFB space is completed.
62 */
63static void omap_vout_vrfb_dma_tx_callback(int lch, u16 ch_status, void *data)
64{
65 struct vid_vrfb_dma *t = (struct vid_vrfb_dma *) data;
66
67 t->tx_status = 1;
68 wake_up_interruptible(&t->wait);
69}
70
71/*
72 * Free VRFB buffers
73 */
74void omap_vout_free_vrfb_buffers(struct omap_vout_device *vout)
75{
76 int j;
77
78 for (j = 0; j < VRFB_NUM_BUFS; j++) {
79 omap_vout_free_buffer(vout->smsshado_virt_addr[j],
80 vout->smsshado_size);
81 vout->smsshado_virt_addr[j] = 0;
82 vout->smsshado_phy_addr[j] = 0;
83 }
84}
85
86int omap_vout_setup_vrfb_bufs(struct platform_device *pdev, int vid_num,
87 bool static_vrfb_allocation)
88{
89 int ret = 0, i, j;
90 struct omap_vout_device *vout;
91 struct video_device *vfd;
92 int image_width, image_height;
93 int vrfb_num_bufs = VRFB_NUM_BUFS;
94 struct v4l2_device *v4l2_dev = platform_get_drvdata(pdev);
95 struct omap2video_device *vid_dev =
96 container_of(v4l2_dev, struct omap2video_device, v4l2_dev);
97
98 vout = vid_dev->vouts[vid_num];
99 vfd = vout->vfd;
100
101 for (i = 0; i < VRFB_NUM_BUFS; i++) {
102 if (omap_vrfb_request_ctx(&vout->vrfb_context[i])) {
103 dev_info(&pdev->dev, ": VRFB allocation failed\n");
104 for (j = 0; j < i; j++)
105 omap_vrfb_release_ctx(&vout->vrfb_context[j]);
106 ret = -ENOMEM;
107 goto free_buffers;
108 }
109 }
110
111 /* Calculate VRFB memory size */
112 /* allocate for worst case size */
113 image_width = VID_MAX_WIDTH / TILE_SIZE;
114 if (VID_MAX_WIDTH % TILE_SIZE)
115 image_width++;
116
117 image_width = image_width * TILE_SIZE;
118 image_height = VID_MAX_HEIGHT / TILE_SIZE;
119
120 if (VID_MAX_HEIGHT % TILE_SIZE)
121 image_height++;
122
123 image_height = image_height * TILE_SIZE;
124 vout->smsshado_size = PAGE_ALIGN(image_width * image_height * 2 * 2);
125
126 /*
127 * Request and Initialize DMA, for DMA based VRFB transfer
128 */
129 vout->vrfb_dma_tx.dev_id = OMAP_DMA_NO_DEVICE;
130 vout->vrfb_dma_tx.dma_ch = -1;
131 vout->vrfb_dma_tx.req_status = DMA_CHAN_ALLOTED;
132 ret = omap_request_dma(vout->vrfb_dma_tx.dev_id, "VRFB DMA TX",
133 omap_vout_vrfb_dma_tx_callback,
134 (void *) &vout->vrfb_dma_tx, &vout->vrfb_dma_tx.dma_ch);
135 if (ret < 0) {
136 vout->vrfb_dma_tx.req_status = DMA_CHAN_NOT_ALLOTED;
137 dev_info(&pdev->dev, ": failed to allocate DMA Channel for"
138 " video%d\n", vfd->minor);
139 }
140 init_waitqueue_head(&vout->vrfb_dma_tx.wait);
141
142 /* statically allocated the VRFB buffer is done through
143 commands line aruments */
144 if (static_vrfb_allocation) {
145 if (omap_vout_allocate_vrfb_buffers(vout, &vrfb_num_bufs, -1)) {
146 ret = -ENOMEM;
147 goto release_vrfb_ctx;
148 }
149 vout->vrfb_static_allocation = 1;
150 }
151 return 0;
152
153release_vrfb_ctx:
154 for (j = 0; j < VRFB_NUM_BUFS; j++)
155 omap_vrfb_release_ctx(&vout->vrfb_context[j]);
156free_buffers:
157 omap_vout_free_buffers(vout);
158
159 return ret;
160}
161
162/*
163 * Release the VRFB context once the module exits
164 */
165void omap_vout_release_vrfb(struct omap_vout_device *vout)
166{
167 int i;
168
169 for (i = 0; i < VRFB_NUM_BUFS; i++)
170 omap_vrfb_release_ctx(&vout->vrfb_context[i]);
171
172 if (vout->vrfb_dma_tx.req_status == DMA_CHAN_ALLOTED) {
173 vout->vrfb_dma_tx.req_status = DMA_CHAN_NOT_ALLOTED;
174 omap_free_dma(vout->vrfb_dma_tx.dma_ch);
175 }
176}
177
178/*
179 * Allocate the buffers for the VRFB space. Data is copied from V4L2
180 * buffers to the VRFB buffers using the DMA engine.
181 */
182int omap_vout_vrfb_buffer_setup(struct omap_vout_device *vout,
183 unsigned int *count, unsigned int startindex)
184{
185 int i;
186 bool yuv_mode;
187
188 if (!is_rotation_enabled(vout))
189 return 0;
190
191 /* If rotation is enabled, allocate memory for VRFB space also */
192 *count = *count > VRFB_NUM_BUFS ? VRFB_NUM_BUFS : *count;
193
194 /* Allocate the VRFB buffers only if the buffers are not
195 * allocated during init time.
196 */
197 if (!vout->vrfb_static_allocation)
198 if (omap_vout_allocate_vrfb_buffers(vout, count, startindex))
199 return -ENOMEM;
200
201 if (vout->dss_mode == OMAP_DSS_COLOR_YUV2 ||
202 vout->dss_mode == OMAP_DSS_COLOR_UYVY)
203 yuv_mode = true;
204 else
205 yuv_mode = false;
206
207 for (i = 0; i < *count; i++)
208 omap_vrfb_setup(&vout->vrfb_context[i],
209 vout->smsshado_phy_addr[i], vout->pix.width,
210 vout->pix.height, vout->bpp, yuv_mode);
211
212 return 0;
213}
214
215int omap_vout_prepare_vrfb(struct omap_vout_device *vout,
216 struct videobuf_buffer *vb)
217{
218 dma_addr_t dmabuf;
219 struct vid_vrfb_dma *tx;
220 enum dss_rotation rotation;
221 u32 dest_frame_index = 0, src_element_index = 0;
222 u32 dest_element_index = 0, src_frame_index = 0;
223 u32 elem_count = 0, frame_count = 0, pixsize = 2;
224
225 if (!is_rotation_enabled(vout))
226 return 0;
227
228 dmabuf = vout->buf_phy_addr[vb->i];
229 /* If rotation is enabled, copy input buffer into VRFB
230 * memory space using DMA. We are copying input buffer
231 * into VRFB memory space of desired angle and DSS will
232 * read image VRFB memory for 0 degree angle
233 */
234 pixsize = vout->bpp * vout->vrfb_bpp;
235 /*
236 * DMA transfer in double index mode
237 */
238
239 /* Frame index */
240 dest_frame_index = ((MAX_PIXELS_PER_LINE * pixsize) -
241 (vout->pix.width * vout->bpp)) + 1;
242
243 /* Source and destination parameters */
244 src_element_index = 0;
245 src_frame_index = 0;
246 dest_element_index = 1;
247 /* Number of elements per frame */
248 elem_count = vout->pix.width * vout->bpp;
249 frame_count = vout->pix.height;
250 tx = &vout->vrfb_dma_tx;
251 tx->tx_status = 0;
252 omap_set_dma_transfer_params(tx->dma_ch, OMAP_DMA_DATA_TYPE_S32,
253 (elem_count / 4), frame_count, OMAP_DMA_SYNC_ELEMENT,
254 tx->dev_id, 0x0);
255 /* src_port required only for OMAP1 */
256 omap_set_dma_src_params(tx->dma_ch, 0, OMAP_DMA_AMODE_POST_INC,
257 dmabuf, src_element_index, src_frame_index);
258 /*set dma source burst mode for VRFB */
259 omap_set_dma_src_burst_mode(tx->dma_ch, OMAP_DMA_DATA_BURST_16);
260 rotation = calc_rotation(vout);
261
262 /* dest_port required only for OMAP1 */
263 omap_set_dma_dest_params(tx->dma_ch, 0, OMAP_DMA_AMODE_DOUBLE_IDX,
264 vout->vrfb_context[vb->i].paddr[0], dest_element_index,
265 dest_frame_index);
266 /*set dma dest burst mode for VRFB */
267 omap_set_dma_dest_burst_mode(tx->dma_ch, OMAP_DMA_DATA_BURST_16);
268 omap_dma_set_global_params(DMA_DEFAULT_ARB_RATE, 0x20, 0);
269
270 omap_start_dma(tx->dma_ch);
271 interruptible_sleep_on_timeout(&tx->wait, VRFB_TX_TIMEOUT);
272
273 if (tx->tx_status == 0) {
274 omap_stop_dma(tx->dma_ch);
275 return -EINVAL;
276 }
277 /* Store buffers physical address into an array. Addresses
278 * from this array will be used to configure DSS */
279 vout->queued_buf_addr[vb->i] = (u8 *)
280 vout->vrfb_context[vb->i].paddr[rotation];
281 return 0;
282}
283
284/*
285 * Calculate the buffer offsets from which the streaming should
286 * start. This offset calculation is mainly required because of
287 * the VRFB 32 pixels alignment with rotation.
288 */
289void omap_vout_calculate_vrfb_offset(struct omap_vout_device *vout)
290{
291 enum dss_rotation rotation;
292 bool mirroring = vout->mirror;
293 struct v4l2_rect *crop = &vout->crop;
294 struct v4l2_pix_format *pix = &vout->pix;
295 int *cropped_offset = &vout->cropped_offset;
296 int vr_ps = 1, ps = 2, temp_ps = 2;
297 int offset = 0, ctop = 0, cleft = 0, line_length = 0;
298
299 rotation = calc_rotation(vout);
300
301 if (V4L2_PIX_FMT_YUYV == pix->pixelformat ||
302 V4L2_PIX_FMT_UYVY == pix->pixelformat) {
303 if (is_rotation_enabled(vout)) {
304 /*
305 * ps - Actual pixel size for YUYV/UYVY for
306 * VRFB/Mirroring is 4 bytes
307 * vr_ps - Virtually pixel size for YUYV/UYVY is
308 * 2 bytes
309 */
310 ps = 4;
311 vr_ps = 2;
312 } else {
313 ps = 2; /* otherwise the pixel size is 2 byte */
314 }
315 } else if (V4L2_PIX_FMT_RGB32 == pix->pixelformat) {
316 ps = 4;
317 } else if (V4L2_PIX_FMT_RGB24 == pix->pixelformat) {
318 ps = 3;
319 }
320 vout->ps = ps;
321 vout->vr_ps = vr_ps;
322
323 if (is_rotation_enabled(vout)) {
324 line_length = MAX_PIXELS_PER_LINE;
325 ctop = (pix->height - crop->height) - crop->top;
326 cleft = (pix->width - crop->width) - crop->left;
327 } else {
328 line_length = pix->width;
329 }
330 vout->line_length = line_length;
331 switch (rotation) {
332 case dss_rotation_90_degree:
333 offset = vout->vrfb_context[0].yoffset *
334 vout->vrfb_context[0].bytespp;
335 temp_ps = ps / vr_ps;
336 if (mirroring == 0) {
337 *cropped_offset = offset + line_length *
338 temp_ps * cleft + crop->top * temp_ps;
339 } else {
340 *cropped_offset = offset + line_length * temp_ps *
341 cleft + crop->top * temp_ps + (line_length *
342 ((crop->width / (vr_ps)) - 1) * ps);
343 }
344 break;
345 case dss_rotation_180_degree:
346 offset = ((MAX_PIXELS_PER_LINE * vout->vrfb_context[0].yoffset *
347 vout->vrfb_context[0].bytespp) +
348 (vout->vrfb_context[0].xoffset *
349 vout->vrfb_context[0].bytespp));
350 if (mirroring == 0) {
351 *cropped_offset = offset + (line_length * ps * ctop) +
352 (cleft / vr_ps) * ps;
353
354 } else {
355 *cropped_offset = offset + (line_length * ps * ctop) +
356 (cleft / vr_ps) * ps + (line_length *
357 (crop->height - 1) * ps);
358 }
359 break;
360 case dss_rotation_270_degree:
361 offset = MAX_PIXELS_PER_LINE * vout->vrfb_context[0].xoffset *
362 vout->vrfb_context[0].bytespp;
363 temp_ps = ps / vr_ps;
364 if (mirroring == 0) {
365 *cropped_offset = offset + line_length *
366 temp_ps * crop->left + ctop * ps;
367 } else {
368 *cropped_offset = offset + line_length *
369 temp_ps * crop->left + ctop * ps +
370 (line_length * ((crop->width / vr_ps) - 1) *
371 ps);
372 }
373 break;
374 case dss_rotation_0_degree:
375 if (mirroring == 0) {
376 *cropped_offset = (line_length * ps) *
377 crop->top + (crop->left / vr_ps) * ps;
378 } else {
379 *cropped_offset = (line_length * ps) *
380 crop->top + (crop->left / vr_ps) * ps +
381 (line_length * (crop->height - 1) * ps);
382 }
383 break;
384 default:
385 *cropped_offset = (line_length * ps * crop->top) /
386 vr_ps + (crop->left * ps) / vr_ps +
387 ((crop->width / vr_ps) - 1) * ps;
388 break;
389 }
390}
diff --git a/drivers/media/video/omap/omap_vout_vrfb.h b/drivers/media/video/omap/omap_vout_vrfb.h
deleted file mode 100644
index ffde741e0590..000000000000
--- a/drivers/media/video/omap/omap_vout_vrfb.h
+++ /dev/null
@@ -1,40 +0,0 @@
1/*
2 * omap_vout_vrfb.h
3 *
4 * Copyright (C) 2010 Texas Instruments.
5 *
6 * This file is licensed under the terms of the GNU General Public License
7 * version 2. This program is licensed "as is" without any warranty of any
8 * kind, whether express or implied.
9 *
10 */
11
12#ifndef OMAP_VOUT_VRFB_H
13#define OMAP_VOUT_VRFB_H
14
15#ifdef CONFIG_VIDEO_OMAP2_VOUT_VRFB
16void omap_vout_free_vrfb_buffers(struct omap_vout_device *vout);
17int omap_vout_setup_vrfb_bufs(struct platform_device *pdev, int vid_num,
18 u32 static_vrfb_allocation);
19void omap_vout_release_vrfb(struct omap_vout_device *vout);
20int omap_vout_vrfb_buffer_setup(struct omap_vout_device *vout,
21 unsigned int *count, unsigned int startindex);
22int omap_vout_prepare_vrfb(struct omap_vout_device *vout,
23 struct videobuf_buffer *vb);
24void omap_vout_calculate_vrfb_offset(struct omap_vout_device *vout);
25#else
26void omap_vout_free_vrfb_buffers(struct omap_vout_device *vout) { }
27int omap_vout_setup_vrfb_bufs(struct platform_device *pdev, int vid_num,
28 u32 static_vrfb_allocation)
29 { return 0; }
30void omap_vout_release_vrfb(struct omap_vout_device *vout) { }
31int omap_vout_vrfb_buffer_setup(struct omap_vout_device *vout,
32 unsigned int *count, unsigned int startindex)
33 { return 0; }
34int omap_vout_prepare_vrfb(struct omap_vout_device *vout,
35 struct videobuf_buffer *vb)
36 { return 0; }
37void omap_vout_calculate_vrfb_offset(struct omap_vout_device *vout) { }
38#endif
39
40#endif
diff --git a/drivers/media/video/omap/omap_voutdef.h b/drivers/media/video/omap/omap_voutdef.h
deleted file mode 100644
index 27a95d23b913..000000000000
--- a/drivers/media/video/omap/omap_voutdef.h
+++ /dev/null
@@ -1,225 +0,0 @@
1/*
2 * omap_voutdef.h
3 *
4 * Copyright (C) 2010 Texas Instruments.
5 *
6 * This file is licensed under the terms of the GNU General Public License
7 * version 2. This program is licensed "as is" without any warranty of any
8 * kind, whether express or implied.
9 */
10
11#ifndef OMAP_VOUTDEF_H
12#define OMAP_VOUTDEF_H
13
14#include <video/omapdss.h>
15#include <plat/vrfb.h>
16
17#define YUYV_BPP 2
18#define RGB565_BPP 2
19#define RGB24_BPP 3
20#define RGB32_BPP 4
21#define TILE_SIZE 32
22#define YUYV_VRFB_BPP 2
23#define RGB_VRFB_BPP 1
24#define MAX_CID 3
25#define MAC_VRFB_CTXS 4
26#define MAX_VOUT_DEV 2
27#define MAX_OVLS 3
28#define MAX_DISPLAYS 10
29#define MAX_MANAGERS 3
30
31#define QQVGA_WIDTH 160
32#define QQVGA_HEIGHT 120
33
34/* Max Resolution supported by the driver */
35#define VID_MAX_WIDTH 1280 /* Largest width */
36#define VID_MAX_HEIGHT 720 /* Largest height */
37
38/* Mimimum requirement is 2x2 for DSS */
39#define VID_MIN_WIDTH 2
40#define VID_MIN_HEIGHT 2
41
42/* 2048 x 2048 is max res supported by OMAP display controller */
43#define MAX_PIXELS_PER_LINE 2048
44
45#define VRFB_TX_TIMEOUT 1000
46#define VRFB_NUM_BUFS 4
47
48/* Max buffer size tobe allocated during init */
49#define OMAP_VOUT_MAX_BUF_SIZE (VID_MAX_WIDTH*VID_MAX_HEIGHT*4)
50
51enum dma_channel_state {
52 DMA_CHAN_NOT_ALLOTED,
53 DMA_CHAN_ALLOTED,
54};
55
56/* Enum for Rotation
57 * DSS understands rotation in 0, 1, 2, 3 context
58 * while V4L2 driver understands it as 0, 90, 180, 270
59 */
60enum dss_rotation {
61 dss_rotation_0_degree = 0,
62 dss_rotation_90_degree = 1,
63 dss_rotation_180_degree = 2,
64 dss_rotation_270_degree = 3,
65};
66
67/* Enum for choosing rotation type for vout
68 * DSS2 doesn't understand no rotation as an
69 * option while V4L2 driver doesn't support
70 * rotation in the case where VRFB is not built in
71 * the kernel
72 */
73enum vout_rotaion_type {
74 VOUT_ROT_NONE = 0,
75 VOUT_ROT_VRFB = 1,
76};
77
78/*
79 * This structure is used to store the DMA transfer parameters
80 * for VRFB hidden buffer
81 */
82struct vid_vrfb_dma {
83 int dev_id;
84 int dma_ch;
85 int req_status;
86 int tx_status;
87 wait_queue_head_t wait;
88};
89
90struct omapvideo_info {
91 int id;
92 int num_overlays;
93 struct omap_overlay *overlays[MAX_OVLS];
94 enum vout_rotaion_type rotation_type;
95};
96
97struct omap2video_device {
98 struct mutex mtx;
99
100 int state;
101
102 struct v4l2_device v4l2_dev;
103 struct omap_vout_device *vouts[MAX_VOUT_DEV];
104
105 int num_displays;
106 struct omap_dss_device *displays[MAX_DISPLAYS];
107 int num_overlays;
108 struct omap_overlay *overlays[MAX_OVLS];
109 int num_managers;
110 struct omap_overlay_manager *managers[MAX_MANAGERS];
111};
112
113/* per-device data structure */
114struct omap_vout_device {
115
116 struct omapvideo_info vid_info;
117 struct video_device *vfd;
118 struct omap2video_device *vid_dev;
119 int vid;
120 int opened;
121
122 /* we don't allow to change image fmt/size once buffer has
123 * been allocated
124 */
125 int buffer_allocated;
126 /* allow to reuse previously allocated buffer which is big enough */
127 int buffer_size;
128 /* keep buffer info across opens */
129 unsigned long buf_virt_addr[VIDEO_MAX_FRAME];
130 unsigned long buf_phy_addr[VIDEO_MAX_FRAME];
131 enum omap_color_mode dss_mode;
132
133 /* we don't allow to request new buffer when old buffers are
134 * still mmaped
135 */
136 int mmap_count;
137
138 spinlock_t vbq_lock; /* spinlock for videobuf queues */
139 unsigned long field_count; /* field counter for videobuf_buffer */
140
141 /* non-NULL means streaming is in progress. */
142 bool streaming;
143
144 struct v4l2_pix_format pix;
145 struct v4l2_rect crop;
146 struct v4l2_window win;
147 struct v4l2_framebuffer fbuf;
148
149 /* Lock to protect the shared data structures in ioctl */
150 struct mutex lock;
151
152 /* V4L2 control structure for different control id */
153 struct v4l2_control control[MAX_CID];
154 enum dss_rotation rotation;
155 bool mirror;
156 int flicker_filter;
157 /* V4L2 control structure for different control id */
158
159 int bpp; /* bytes per pixel */
160 int vrfb_bpp; /* bytes per pixel with respect to VRFB */
161
162 struct vid_vrfb_dma vrfb_dma_tx;
163 unsigned int smsshado_phy_addr[MAC_VRFB_CTXS];
164 unsigned int smsshado_virt_addr[MAC_VRFB_CTXS];
165 struct vrfb vrfb_context[MAC_VRFB_CTXS];
166 bool vrfb_static_allocation;
167 unsigned int smsshado_size;
168 unsigned char pos;
169
170 int ps, vr_ps, line_length, first_int, field_id;
171 enum v4l2_memory memory;
172 struct videobuf_buffer *cur_frm, *next_frm;
173 struct list_head dma_queue;
174 u8 *queued_buf_addr[VIDEO_MAX_FRAME];
175 u32 cropped_offset;
176 s32 tv_field1_offset;
177 void *isr_handle;
178
179 /* Buffer queue variables */
180 struct omap_vout_device *vout;
181 enum v4l2_buf_type type;
182 struct videobuf_queue vbq;
183 int io_allowed;
184
185};
186
187/*
188 * Return true if rotation is 90 or 270
189 */
190static inline int is_rotation_90_or_270(const struct omap_vout_device *vout)
191{
192 return (vout->rotation == dss_rotation_90_degree ||
193 vout->rotation == dss_rotation_270_degree);
194}
195
196/*
197 * Return true if rotation is enabled
198 */
199static inline int is_rotation_enabled(const struct omap_vout_device *vout)
200{
201 return vout->rotation || vout->mirror;
202}
203
204/*
205 * Reverse the rotation degree if mirroring is enabled
206 */
207static inline int calc_rotation(const struct omap_vout_device *vout)
208{
209 if (!vout->mirror)
210 return vout->rotation;
211
212 switch (vout->rotation) {
213 case dss_rotation_90_degree:
214 return dss_rotation_270_degree;
215 case dss_rotation_270_degree:
216 return dss_rotation_90_degree;
217 case dss_rotation_180_degree:
218 return dss_rotation_0_degree;
219 default:
220 return dss_rotation_180_degree;
221 }
222}
223
224void omap_vout_free_buffers(struct omap_vout_device *vout);
225#endif /* ifndef OMAP_VOUTDEF_H */
diff --git a/drivers/media/video/omap/omap_voutlib.c b/drivers/media/video/omap/omap_voutlib.c
deleted file mode 100644
index 115408b9274f..000000000000
--- a/drivers/media/video/omap/omap_voutlib.c
+++ /dev/null
@@ -1,339 +0,0 @@
1/*
2 * omap_voutlib.c
3 *
4 * Copyright (C) 2005-2010 Texas Instruments.
5 *
6 * This file is licensed under the terms of the GNU General Public License
7 * version 2. This program is licensed "as is" without any warranty of any
8 * kind, whether express or implied.
9 *
10 * Based on the OMAP2 camera driver
11 * Video-for-Linux (Version 2) camera capture driver for
12 * the OMAP24xx camera controller.
13 *
14 * Author: Andy Lowe (source@mvista.com)
15 *
16 * Copyright (C) 2004 MontaVista Software, Inc.
17 * Copyright (C) 2010 Texas Instruments.
18 *
19 */
20
21#include <linux/module.h>
22#include <linux/errno.h>
23#include <linux/kernel.h>
24#include <linux/types.h>
25#include <linux/videodev2.h>
26
27#include <linux/dma-mapping.h>
28
29#include <plat/cpu.h>
30
31#include "omap_voutlib.h"
32
33MODULE_AUTHOR("Texas Instruments");
34MODULE_DESCRIPTION("OMAP Video library");
35MODULE_LICENSE("GPL");
36
37/* Return the default overlay cropping rectangle in crop given the image
38 * size in pix and the video display size in fbuf. The default
39 * cropping rectangle is the largest rectangle no larger than the capture size
40 * that will fit on the display. The default cropping rectangle is centered in
41 * the image. All dimensions and offsets are rounded down to even numbers.
42 */
43void omap_vout_default_crop(struct v4l2_pix_format *pix,
44 struct v4l2_framebuffer *fbuf, struct v4l2_rect *crop)
45{
46 crop->width = (pix->width < fbuf->fmt.width) ?
47 pix->width : fbuf->fmt.width;
48 crop->height = (pix->height < fbuf->fmt.height) ?
49 pix->height : fbuf->fmt.height;
50 crop->width &= ~1;
51 crop->height &= ~1;
52 crop->left = ((pix->width - crop->width) >> 1) & ~1;
53 crop->top = ((pix->height - crop->height) >> 1) & ~1;
54}
55EXPORT_SYMBOL_GPL(omap_vout_default_crop);
56
57/* Given a new render window in new_win, adjust the window to the
58 * nearest supported configuration. The adjusted window parameters are
59 * returned in new_win.
60 * Returns zero if successful, or -EINVAL if the requested window is
61 * impossible and cannot reasonably be adjusted.
62 */
63int omap_vout_try_window(struct v4l2_framebuffer *fbuf,
64 struct v4l2_window *new_win)
65{
66 struct v4l2_rect try_win;
67
68 /* make a working copy of the new_win rectangle */
69 try_win = new_win->w;
70
71 /* adjust the preview window so it fits on the display by clipping any
72 * offscreen areas
73 */
74 if (try_win.left < 0) {
75 try_win.width += try_win.left;
76 try_win.left = 0;
77 }
78 if (try_win.top < 0) {
79 try_win.height += try_win.top;
80 try_win.top = 0;
81 }
82 try_win.width = (try_win.width < fbuf->fmt.width) ?
83 try_win.width : fbuf->fmt.width;
84 try_win.height = (try_win.height < fbuf->fmt.height) ?
85 try_win.height : fbuf->fmt.height;
86 if (try_win.left + try_win.width > fbuf->fmt.width)
87 try_win.width = fbuf->fmt.width - try_win.left;
88 if (try_win.top + try_win.height > fbuf->fmt.height)
89 try_win.height = fbuf->fmt.height - try_win.top;
90 try_win.width &= ~1;
91 try_win.height &= ~1;
92
93 if (try_win.width <= 0 || try_win.height <= 0)
94 return -EINVAL;
95
96 /* We now have a valid preview window, so go with it */
97 new_win->w = try_win;
98 new_win->field = V4L2_FIELD_ANY;
99 return 0;
100}
101EXPORT_SYMBOL_GPL(omap_vout_try_window);
102
103/* Given a new render window in new_win, adjust the window to the
104 * nearest supported configuration. The image cropping window in crop
105 * will also be adjusted if necessary. Preference is given to keeping the
106 * the window as close to the requested configuration as possible. If
107 * successful, new_win, vout->win, and crop are updated.
108 * Returns zero if successful, or -EINVAL if the requested preview window is
109 * impossible and cannot reasonably be adjusted.
110 */
111int omap_vout_new_window(struct v4l2_rect *crop,
112 struct v4l2_window *win, struct v4l2_framebuffer *fbuf,
113 struct v4l2_window *new_win)
114{
115 int err;
116
117 err = omap_vout_try_window(fbuf, new_win);
118 if (err)
119 return err;
120
121 /* update our preview window */
122 win->w = new_win->w;
123 win->field = new_win->field;
124 win->chromakey = new_win->chromakey;
125
126 /* Adjust the cropping window to allow for resizing limitation */
127 if (cpu_is_omap24xx()) {
128 /* For 24xx limit is 8x to 1/2x scaling. */
129 if ((crop->height/win->w.height) >= 2)
130 crop->height = win->w.height * 2;
131
132 if ((crop->width/win->w.width) >= 2)
133 crop->width = win->w.width * 2;
134
135 if (crop->width > 768) {
136 /* The OMAP2420 vertical resizing line buffer is 768
137 * pixels wide. If the cropped image is wider than
138 * 768 pixels then it cannot be vertically resized.
139 */
140 if (crop->height != win->w.height)
141 crop->width = 768;
142 }
143 } else if (cpu_is_omap34xx()) {
144 /* For 34xx limit is 8x to 1/4x scaling. */
145 if ((crop->height/win->w.height) >= 4)
146 crop->height = win->w.height * 4;
147
148 if ((crop->width/win->w.width) >= 4)
149 crop->width = win->w.width * 4;
150 }
151 return 0;
152}
153EXPORT_SYMBOL_GPL(omap_vout_new_window);
154
155/* Given a new cropping rectangle in new_crop, adjust the cropping rectangle to
156 * the nearest supported configuration. The image render window in win will
157 * also be adjusted if necessary. The preview window is adjusted such that the
158 * horizontal and vertical rescaling ratios stay constant. If the render
159 * window would fall outside the display boundaries, the cropping rectangle
160 * will also be adjusted to maintain the rescaling ratios. If successful, crop
161 * and win are updated.
162 * Returns zero if successful, or -EINVAL if the requested cropping rectangle is
163 * impossible and cannot reasonably be adjusted.
164 */
165int omap_vout_new_crop(struct v4l2_pix_format *pix,
166 struct v4l2_rect *crop, struct v4l2_window *win,
167 struct v4l2_framebuffer *fbuf, const struct v4l2_rect *new_crop)
168{
169 struct v4l2_rect try_crop;
170 unsigned long vresize, hresize;
171
172 /* make a working copy of the new_crop rectangle */
173 try_crop = *new_crop;
174
175 /* adjust the cropping rectangle so it fits in the image */
176 if (try_crop.left < 0) {
177 try_crop.width += try_crop.left;
178 try_crop.left = 0;
179 }
180 if (try_crop.top < 0) {
181 try_crop.height += try_crop.top;
182 try_crop.top = 0;
183 }
184 try_crop.width = (try_crop.width < pix->width) ?
185 try_crop.width : pix->width;
186 try_crop.height = (try_crop.height < pix->height) ?
187 try_crop.height : pix->height;
188 if (try_crop.left + try_crop.width > pix->width)
189 try_crop.width = pix->width - try_crop.left;
190 if (try_crop.top + try_crop.height > pix->height)
191 try_crop.height = pix->height - try_crop.top;
192
193 try_crop.width &= ~1;
194 try_crop.height &= ~1;
195
196 if (try_crop.width <= 0 || try_crop.height <= 0)
197 return -EINVAL;
198
199 if (cpu_is_omap24xx()) {
200 if (try_crop.height != win->w.height) {
201 /* If we're resizing vertically, we can't support a
202 * crop width wider than 768 pixels.
203 */
204 if (try_crop.width > 768)
205 try_crop.width = 768;
206 }
207 }
208 /* vertical resizing */
209 vresize = (1024 * try_crop.height) / win->w.height;
210 if (cpu_is_omap24xx() && (vresize > 2048))
211 vresize = 2048;
212 else if (cpu_is_omap34xx() && (vresize > 4096))
213 vresize = 4096;
214
215 win->w.height = ((1024 * try_crop.height) / vresize) & ~1;
216 if (win->w.height == 0)
217 win->w.height = 2;
218 if (win->w.height + win->w.top > fbuf->fmt.height) {
219 /* We made the preview window extend below the bottom of the
220 * display, so clip it to the display boundary and resize the
221 * cropping height to maintain the vertical resizing ratio.
222 */
223 win->w.height = (fbuf->fmt.height - win->w.top) & ~1;
224 if (try_crop.height == 0)
225 try_crop.height = 2;
226 }
227 /* horizontal resizing */
228 hresize = (1024 * try_crop.width) / win->w.width;
229 if (cpu_is_omap24xx() && (hresize > 2048))
230 hresize = 2048;
231 else if (cpu_is_omap34xx() && (hresize > 4096))
232 hresize = 4096;
233
234 win->w.width = ((1024 * try_crop.width) / hresize) & ~1;
235 if (win->w.width == 0)
236 win->w.width = 2;
237 if (win->w.width + win->w.left > fbuf->fmt.width) {
238 /* We made the preview window extend past the right side of the
239 * display, so clip it to the display boundary and resize the
240 * cropping width to maintain the horizontal resizing ratio.
241 */
242 win->w.width = (fbuf->fmt.width - win->w.left) & ~1;
243 if (try_crop.width == 0)
244 try_crop.width = 2;
245 }
246 if (cpu_is_omap24xx()) {
247 if ((try_crop.height/win->w.height) >= 2)
248 try_crop.height = win->w.height * 2;
249
250 if ((try_crop.width/win->w.width) >= 2)
251 try_crop.width = win->w.width * 2;
252
253 if (try_crop.width > 768) {
254 /* The OMAP2420 vertical resizing line buffer is
255 * 768 pixels wide. If the cropped image is wider
256 * than 768 pixels then it cannot be vertically resized.
257 */
258 if (try_crop.height != win->w.height)
259 try_crop.width = 768;
260 }
261 } else if (cpu_is_omap34xx()) {
262 if ((try_crop.height/win->w.height) >= 4)
263 try_crop.height = win->w.height * 4;
264
265 if ((try_crop.width/win->w.width) >= 4)
266 try_crop.width = win->w.width * 4;
267 }
268 /* update our cropping rectangle and we're done */
269 *crop = try_crop;
270 return 0;
271}
272EXPORT_SYMBOL_GPL(omap_vout_new_crop);
273
274/* Given a new format in pix and fbuf, crop and win
275 * structures are initialized to default values. crop
276 * is initialized to the largest window size that will fit on the display. The
277 * crop window is centered in the image. win is initialized to
278 * the same size as crop and is centered on the display.
279 * All sizes and offsets are constrained to be even numbers.
280 */
281void omap_vout_new_format(struct v4l2_pix_format *pix,
282 struct v4l2_framebuffer *fbuf, struct v4l2_rect *crop,
283 struct v4l2_window *win)
284{
285 /* crop defines the preview source window in the image capture
286 * buffer
287 */
288 omap_vout_default_crop(pix, fbuf, crop);
289
290 /* win defines the preview target window on the display */
291 win->w.width = crop->width;
292 win->w.height = crop->height;
293 win->w.left = ((fbuf->fmt.width - win->w.width) >> 1) & ~1;
294 win->w.top = ((fbuf->fmt.height - win->w.height) >> 1) & ~1;
295}
296EXPORT_SYMBOL_GPL(omap_vout_new_format);
297
298/*
299 * Allocate buffers
300 */
301unsigned long omap_vout_alloc_buffer(u32 buf_size, u32 *phys_addr)
302{
303 u32 order, size;
304 unsigned long virt_addr, addr;
305
306 size = PAGE_ALIGN(buf_size);
307 order = get_order(size);
308 virt_addr = __get_free_pages(GFP_KERNEL, order);
309 addr = virt_addr;
310
311 if (virt_addr) {
312 while (size > 0) {
313 SetPageReserved(virt_to_page(addr));
314 addr += PAGE_SIZE;
315 size -= PAGE_SIZE;
316 }
317 }
318 *phys_addr = (u32) virt_to_phys((void *) virt_addr);
319 return virt_addr;
320}
321
322/*
323 * Free buffers
324 */
325void omap_vout_free_buffer(unsigned long virtaddr, u32 buf_size)
326{
327 u32 order, size;
328 unsigned long addr = virtaddr;
329
330 size = PAGE_ALIGN(buf_size);
331 order = get_order(size);
332
333 while (size > 0) {
334 ClearPageReserved(virt_to_page(addr));
335 addr += PAGE_SIZE;
336 size -= PAGE_SIZE;
337 }
338 free_pages((unsigned long) virtaddr, order);
339}
diff --git a/drivers/media/video/omap/omap_voutlib.h b/drivers/media/video/omap/omap_voutlib.h
deleted file mode 100644
index e51750a597e3..000000000000
--- a/drivers/media/video/omap/omap_voutlib.h
+++ /dev/null
@@ -1,36 +0,0 @@
1/*
2 * omap_voutlib.h
3 *
4 * Copyright (C) 2010 Texas Instruments.
5 *
6 * This file is licensed under the terms of the GNU General Public License
7 * version 2. This program is licensed "as is" without any warranty of any
8 * kind, whether express or implied.
9 *
10 */
11
12#ifndef OMAP_VOUTLIB_H
13#define OMAP_VOUTLIB_H
14
15void omap_vout_default_crop(struct v4l2_pix_format *pix,
16 struct v4l2_framebuffer *fbuf, struct v4l2_rect *crop);
17
18int omap_vout_new_crop(struct v4l2_pix_format *pix,
19 struct v4l2_rect *crop, struct v4l2_window *win,
20 struct v4l2_framebuffer *fbuf,
21 const struct v4l2_rect *new_crop);
22
23int omap_vout_try_window(struct v4l2_framebuffer *fbuf,
24 struct v4l2_window *new_win);
25
26int omap_vout_new_window(struct v4l2_rect *crop,
27 struct v4l2_window *win, struct v4l2_framebuffer *fbuf,
28 struct v4l2_window *new_win);
29
30void omap_vout_new_format(struct v4l2_pix_format *pix,
31 struct v4l2_framebuffer *fbuf, struct v4l2_rect *crop,
32 struct v4l2_window *win);
33unsigned long omap_vout_alloc_buffer(u32 buf_size, u32 *phys_addr);
34void omap_vout_free_buffer(unsigned long virtaddr, u32 buf_size);
35#endif /* #ifndef OMAP_VOUTLIB_H */
36
diff --git a/drivers/media/video/omap1_camera.c b/drivers/media/video/omap1_camera.c
deleted file mode 100644
index c7e41145041f..000000000000
--- a/drivers/media/video/omap1_camera.c
+++ /dev/null
@@ -1,1723 +0,0 @@
1/*
2 * V4L2 SoC Camera driver for OMAP1 Camera Interface
3 *
4 * Copyright (C) 2010, Janusz Krzysztofik <jkrzyszt@tis.icnet.pl>
5 *
6 * Based on V4L2 Driver for i.MXL/i.MXL camera (CSI) host
7 * Copyright (C) 2008, Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
8 * Copyright (C) 2009, Darius Augulis <augulis.darius@gmail.com>
9 *
10 * Based on PXA SoC camera driver
11 * Copyright (C) 2006, Sascha Hauer, Pengutronix
12 * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
13 *
14 * Hardware specific bits initialy based on former work by Matt Callow
15 * drivers/media/video/omap/omap1510cam.c
16 * Copyright (C) 2006 Matt Callow
17 *
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License version 2 as
20 * published by the Free Software Foundation.
21 */
22
23
24#include <linux/clk.h>
25#include <linux/dma-mapping.h>
26#include <linux/interrupt.h>
27#include <linux/module.h>
28#include <linux/platform_device.h>
29#include <linux/slab.h>
30
31#include <media/omap1_camera.h>
32#include <media/soc_camera.h>
33#include <media/soc_mediabus.h>
34#include <media/videobuf-dma-contig.h>
35#include <media/videobuf-dma-sg.h>
36
37#include <plat/dma.h>
38
39
40#define DRIVER_NAME "omap1-camera"
41#define DRIVER_VERSION "0.0.2"
42
43
44/*
45 * ---------------------------------------------------------------------------
46 * OMAP1 Camera Interface registers
47 * ---------------------------------------------------------------------------
48 */
49
50#define REG_CTRLCLOCK 0x00
51#define REG_IT_STATUS 0x04
52#define REG_MODE 0x08
53#define REG_STATUS 0x0C
54#define REG_CAMDATA 0x10
55#define REG_GPIO 0x14
56#define REG_PEAK_COUNTER 0x18
57
58/* CTRLCLOCK bit shifts */
59#define LCLK_EN BIT(7)
60#define DPLL_EN BIT(6)
61#define MCLK_EN BIT(5)
62#define CAMEXCLK_EN BIT(4)
63#define POLCLK BIT(3)
64#define FOSCMOD_SHIFT 0
65#define FOSCMOD_MASK (0x7 << FOSCMOD_SHIFT)
66#define FOSCMOD_12MHz 0x0
67#define FOSCMOD_6MHz 0x2
68#define FOSCMOD_9_6MHz 0x4
69#define FOSCMOD_24MHz 0x5
70#define FOSCMOD_8MHz 0x6
71
72/* IT_STATUS bit shifts */
73#define DATA_TRANSFER BIT(5)
74#define FIFO_FULL BIT(4)
75#define H_DOWN BIT(3)
76#define H_UP BIT(2)
77#define V_DOWN BIT(1)
78#define V_UP BIT(0)
79
80/* MODE bit shifts */
81#define RAZ_FIFO BIT(18)
82#define EN_FIFO_FULL BIT(17)
83#define EN_NIRQ BIT(16)
84#define THRESHOLD_SHIFT 9
85#define THRESHOLD_MASK (0x7f << THRESHOLD_SHIFT)
86#define DMA BIT(8)
87#define EN_H_DOWN BIT(7)
88#define EN_H_UP BIT(6)
89#define EN_V_DOWN BIT(5)
90#define EN_V_UP BIT(4)
91#define ORDERCAMD BIT(3)
92
93#define IRQ_MASK (EN_V_UP | EN_V_DOWN | EN_H_UP | EN_H_DOWN | \
94 EN_NIRQ | EN_FIFO_FULL)
95
96/* STATUS bit shifts */
97#define HSTATUS BIT(1)
98#define VSTATUS BIT(0)
99
100/* GPIO bit shifts */
101#define CAM_RST BIT(0)
102
103/* end of OMAP1 Camera Interface registers */
104
105
106#define SOCAM_BUS_FLAGS (V4L2_MBUS_MASTER | \
107 V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_HIGH | \
108 V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING | \
109 V4L2_MBUS_DATA_ACTIVE_HIGH)
110
111
112#define FIFO_SIZE ((THRESHOLD_MASK >> THRESHOLD_SHIFT) + 1)
113#define FIFO_SHIFT __fls(FIFO_SIZE)
114
115#define DMA_BURST_SHIFT (1 + OMAP_DMA_DATA_BURST_4)
116#define DMA_BURST_SIZE (1 << DMA_BURST_SHIFT)
117
118#define DMA_ELEMENT_SHIFT OMAP_DMA_DATA_TYPE_S32
119#define DMA_ELEMENT_SIZE (1 << DMA_ELEMENT_SHIFT)
120
121#define DMA_FRAME_SHIFT_CONTIG (FIFO_SHIFT - 1)
122#define DMA_FRAME_SHIFT_SG DMA_BURST_SHIFT
123
124#define DMA_FRAME_SHIFT(x) ((x) == OMAP1_CAM_DMA_CONTIG ? \
125 DMA_FRAME_SHIFT_CONTIG : \
126 DMA_FRAME_SHIFT_SG)
127#define DMA_FRAME_SIZE(x) (1 << DMA_FRAME_SHIFT(x))
128#define DMA_SYNC OMAP_DMA_SYNC_FRAME
129#define THRESHOLD_LEVEL DMA_FRAME_SIZE
130
131
132#define MAX_VIDEO_MEM 4 /* arbitrary video memory limit in MB */
133
134
135/*
136 * Structures
137 */
138
139/* buffer for one video frame */
140struct omap1_cam_buf {
141 struct videobuf_buffer vb;
142 enum v4l2_mbus_pixelcode code;
143 int inwork;
144 struct scatterlist *sgbuf;
145 int sgcount;
146 int bytes_left;
147 enum videobuf_state result;
148};
149
150struct omap1_cam_dev {
151 struct soc_camera_host soc_host;
152 struct soc_camera_device *icd;
153 struct clk *clk;
154
155 unsigned int irq;
156 void __iomem *base;
157
158 int dma_ch;
159
160 struct omap1_cam_platform_data *pdata;
161 struct resource *res;
162 unsigned long pflags;
163 unsigned long camexclk;
164
165 struct list_head capture;
166
167 /* lock used to protect videobuf */
168 spinlock_t lock;
169
170 /* Pointers to DMA buffers */
171 struct omap1_cam_buf *active;
172 struct omap1_cam_buf *ready;
173
174 enum omap1_cam_vb_mode vb_mode;
175 int (*mmap_mapper)(struct videobuf_queue *q,
176 struct videobuf_buffer *buf,
177 struct vm_area_struct *vma);
178
179 u32 reg_cache[0];
180};
181
182
183static void cam_write(struct omap1_cam_dev *pcdev, u16 reg, u32 val)
184{
185 pcdev->reg_cache[reg / sizeof(u32)] = val;
186 __raw_writel(val, pcdev->base + reg);
187}
188
189static u32 cam_read(struct omap1_cam_dev *pcdev, u16 reg, bool from_cache)
190{
191 return !from_cache ? __raw_readl(pcdev->base + reg) :
192 pcdev->reg_cache[reg / sizeof(u32)];
193}
194
195#define CAM_READ(pcdev, reg) \
196 cam_read(pcdev, REG_##reg, false)
197#define CAM_WRITE(pcdev, reg, val) \
198 cam_write(pcdev, REG_##reg, val)
199#define CAM_READ_CACHE(pcdev, reg) \
200 cam_read(pcdev, REG_##reg, true)
201
202/*
203 * Videobuf operations
204 */
205static int omap1_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
206 unsigned int *size)
207{
208 struct soc_camera_device *icd = vq->priv_data;
209 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
210 struct omap1_cam_dev *pcdev = ici->priv;
211
212 *size = icd->sizeimage;
213
214 if (!*count || *count < OMAP1_CAMERA_MIN_BUF_COUNT(pcdev->vb_mode))
215 *count = OMAP1_CAMERA_MIN_BUF_COUNT(pcdev->vb_mode);
216
217 if (*size * *count > MAX_VIDEO_MEM * 1024 * 1024)
218 *count = (MAX_VIDEO_MEM * 1024 * 1024) / *size;
219
220 dev_dbg(icd->parent,
221 "%s: count=%d, size=%d\n", __func__, *count, *size);
222
223 return 0;
224}
225
226static void free_buffer(struct videobuf_queue *vq, struct omap1_cam_buf *buf,
227 enum omap1_cam_vb_mode vb_mode)
228{
229 struct videobuf_buffer *vb = &buf->vb;
230
231 BUG_ON(in_interrupt());
232
233 videobuf_waiton(vq, vb, 0, 0);
234
235 if (vb_mode == OMAP1_CAM_DMA_CONTIG) {
236 videobuf_dma_contig_free(vq, vb);
237 } else {
238 struct soc_camera_device *icd = vq->priv_data;
239 struct device *dev = icd->parent;
240 struct videobuf_dmabuf *dma = videobuf_to_dma(vb);
241
242 videobuf_dma_unmap(dev, dma);
243 videobuf_dma_free(dma);
244 }
245
246 vb->state = VIDEOBUF_NEEDS_INIT;
247}
248
249static int omap1_videobuf_prepare(struct videobuf_queue *vq,
250 struct videobuf_buffer *vb, enum v4l2_field field)
251{
252 struct soc_camera_device *icd = vq->priv_data;
253 struct omap1_cam_buf *buf = container_of(vb, struct omap1_cam_buf, vb);
254 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
255 struct omap1_cam_dev *pcdev = ici->priv;
256 int ret;
257
258 WARN_ON(!list_empty(&vb->queue));
259
260 BUG_ON(NULL == icd->current_fmt);
261
262 buf->inwork = 1;
263
264 if (buf->code != icd->current_fmt->code || vb->field != field ||
265 vb->width != icd->user_width ||
266 vb->height != icd->user_height) {
267 buf->code = icd->current_fmt->code;
268 vb->width = icd->user_width;
269 vb->height = icd->user_height;
270 vb->field = field;
271 vb->state = VIDEOBUF_NEEDS_INIT;
272 }
273
274 vb->size = icd->sizeimage;
275
276 if (vb->baddr && vb->bsize < vb->size) {
277 ret = -EINVAL;
278 goto out;
279 }
280
281 if (vb->state == VIDEOBUF_NEEDS_INIT) {
282 ret = videobuf_iolock(vq, vb, NULL);
283 if (ret)
284 goto fail;
285
286 vb->state = VIDEOBUF_PREPARED;
287 }
288 buf->inwork = 0;
289
290 return 0;
291fail:
292 free_buffer(vq, buf, pcdev->vb_mode);
293out:
294 buf->inwork = 0;
295 return ret;
296}
297
298static void set_dma_dest_params(int dma_ch, struct omap1_cam_buf *buf,
299 enum omap1_cam_vb_mode vb_mode)
300{
301 dma_addr_t dma_addr;
302 unsigned int block_size;
303
304 if (vb_mode == OMAP1_CAM_DMA_CONTIG) {
305 dma_addr = videobuf_to_dma_contig(&buf->vb);
306 block_size = buf->vb.size;
307 } else {
308 if (WARN_ON(!buf->sgbuf)) {
309 buf->result = VIDEOBUF_ERROR;
310 return;
311 }
312 dma_addr = sg_dma_address(buf->sgbuf);
313 if (WARN_ON(!dma_addr)) {
314 buf->sgbuf = NULL;
315 buf->result = VIDEOBUF_ERROR;
316 return;
317 }
318 block_size = sg_dma_len(buf->sgbuf);
319 if (WARN_ON(!block_size)) {
320 buf->sgbuf = NULL;
321 buf->result = VIDEOBUF_ERROR;
322 return;
323 }
324 if (unlikely(buf->bytes_left < block_size))
325 block_size = buf->bytes_left;
326 if (WARN_ON(dma_addr & (DMA_FRAME_SIZE(vb_mode) *
327 DMA_ELEMENT_SIZE - 1))) {
328 dma_addr = ALIGN(dma_addr, DMA_FRAME_SIZE(vb_mode) *
329 DMA_ELEMENT_SIZE);
330 block_size &= ~(DMA_FRAME_SIZE(vb_mode) *
331 DMA_ELEMENT_SIZE - 1);
332 }
333 buf->bytes_left -= block_size;
334 buf->sgcount++;
335 }
336
337 omap_set_dma_dest_params(dma_ch,
338 OMAP_DMA_PORT_EMIFF, OMAP_DMA_AMODE_POST_INC, dma_addr, 0, 0);
339 omap_set_dma_transfer_params(dma_ch,
340 OMAP_DMA_DATA_TYPE_S32, DMA_FRAME_SIZE(vb_mode),
341 block_size >> (DMA_FRAME_SHIFT(vb_mode) + DMA_ELEMENT_SHIFT),
342 DMA_SYNC, 0, 0);
343}
344
345static struct omap1_cam_buf *prepare_next_vb(struct omap1_cam_dev *pcdev)
346{
347 struct omap1_cam_buf *buf;
348
349 /*
350 * If there is already a buffer pointed out by the pcdev->ready,
351 * (re)use it, otherwise try to fetch and configure a new one.
352 */
353 buf = pcdev->ready;
354 if (!buf) {
355 if (list_empty(&pcdev->capture))
356 return buf;
357 buf = list_entry(pcdev->capture.next,
358 struct omap1_cam_buf, vb.queue);
359 buf->vb.state = VIDEOBUF_ACTIVE;
360 pcdev->ready = buf;
361 list_del_init(&buf->vb.queue);
362 }
363
364 if (pcdev->vb_mode == OMAP1_CAM_DMA_CONTIG) {
365 /*
366 * In CONTIG mode, we can safely enter next buffer parameters
367 * into the DMA programming register set after the DMA
368 * has already been activated on the previous buffer
369 */
370 set_dma_dest_params(pcdev->dma_ch, buf, pcdev->vb_mode);
371 } else {
372 /*
373 * In SG mode, the above is not safe since there are probably
374 * a bunch of sgbufs from previous sglist still pending.
375 * Instead, mark the sglist fresh for the upcoming
376 * try_next_sgbuf().
377 */
378 buf->sgbuf = NULL;
379 }
380
381 return buf;
382}
383
384static struct scatterlist *try_next_sgbuf(int dma_ch, struct omap1_cam_buf *buf)
385{
386 struct scatterlist *sgbuf;
387
388 if (likely(buf->sgbuf)) {
389 /* current sglist is active */
390 if (unlikely(!buf->bytes_left)) {
391 /* indicate sglist complete */
392 sgbuf = NULL;
393 } else {
394 /* process next sgbuf */
395 sgbuf = sg_next(buf->sgbuf);
396 if (WARN_ON(!sgbuf)) {
397 buf->result = VIDEOBUF_ERROR;
398 } else if (WARN_ON(!sg_dma_len(sgbuf))) {
399 sgbuf = NULL;
400 buf->result = VIDEOBUF_ERROR;
401 }
402 }
403 buf->sgbuf = sgbuf;
404 } else {
405 /* sglist is fresh, initialize it before using */
406 struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb);
407
408 sgbuf = dma->sglist;
409 if (!(WARN_ON(!sgbuf))) {
410 buf->sgbuf = sgbuf;
411 buf->sgcount = 0;
412 buf->bytes_left = buf->vb.size;
413 buf->result = VIDEOBUF_DONE;
414 }
415 }
416 if (sgbuf)
417 /*
418 * Put our next sgbuf parameters (address, size)
419 * into the DMA programming register set.
420 */
421 set_dma_dest_params(dma_ch, buf, OMAP1_CAM_DMA_SG);
422
423 return sgbuf;
424}
425
426static void start_capture(struct omap1_cam_dev *pcdev)
427{
428 struct omap1_cam_buf *buf = pcdev->active;
429 u32 ctrlclock = CAM_READ_CACHE(pcdev, CTRLCLOCK);
430 u32 mode = CAM_READ_CACHE(pcdev, MODE) & ~EN_V_DOWN;
431
432 if (WARN_ON(!buf))
433 return;
434
435 /*
436 * Enable start of frame interrupt, which we will use for activating
437 * our end of frame watchdog when capture actually starts.
438 */
439 mode |= EN_V_UP;
440
441 if (unlikely(ctrlclock & LCLK_EN))
442 /* stop pixel clock before FIFO reset */
443 CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock & ~LCLK_EN);
444 /* reset FIFO */
445 CAM_WRITE(pcdev, MODE, mode | RAZ_FIFO);
446
447 omap_start_dma(pcdev->dma_ch);
448
449 if (pcdev->vb_mode == OMAP1_CAM_DMA_SG) {
450 /*
451 * In SG mode, it's a good moment for fetching next sgbuf
452 * from the current sglist and, if available, already putting
453 * its parameters into the DMA programming register set.
454 */
455 try_next_sgbuf(pcdev->dma_ch, buf);
456 }
457
458 /* (re)enable pixel clock */
459 CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock | LCLK_EN);
460 /* release FIFO reset */
461 CAM_WRITE(pcdev, MODE, mode);
462}
463
464static void suspend_capture(struct omap1_cam_dev *pcdev)
465{
466 u32 ctrlclock = CAM_READ_CACHE(pcdev, CTRLCLOCK);
467
468 CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock & ~LCLK_EN);
469 omap_stop_dma(pcdev->dma_ch);
470}
471
472static void disable_capture(struct omap1_cam_dev *pcdev)
473{
474 u32 mode = CAM_READ_CACHE(pcdev, MODE);
475
476 CAM_WRITE(pcdev, MODE, mode & ~(IRQ_MASK | DMA));
477}
478
479static void omap1_videobuf_queue(struct videobuf_queue *vq,
480 struct videobuf_buffer *vb)
481{
482 struct soc_camera_device *icd = vq->priv_data;
483 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
484 struct omap1_cam_dev *pcdev = ici->priv;
485 struct omap1_cam_buf *buf;
486 u32 mode;
487
488 list_add_tail(&vb->queue, &pcdev->capture);
489 vb->state = VIDEOBUF_QUEUED;
490
491 if (pcdev->active) {
492 /*
493 * Capture in progress, so don't touch pcdev->ready even if
494 * empty. Since the transfer of the DMA programming register set
495 * content to the DMA working register set is done automatically
496 * by the DMA hardware, this can pretty well happen while we
497 * are keeping the lock here. Leave fetching it from the queue
498 * to be done when a next DMA interrupt occures instead.
499 */
500 return;
501 }
502
503 WARN_ON(pcdev->ready);
504
505 buf = prepare_next_vb(pcdev);
506 if (WARN_ON(!buf))
507 return;
508
509 pcdev->active = buf;
510 pcdev->ready = NULL;
511
512 dev_dbg(icd->parent,
513 "%s: capture not active, setup FIFO, start DMA\n", __func__);
514 mode = CAM_READ_CACHE(pcdev, MODE) & ~THRESHOLD_MASK;
515 mode |= THRESHOLD_LEVEL(pcdev->vb_mode) << THRESHOLD_SHIFT;
516 CAM_WRITE(pcdev, MODE, mode | EN_FIFO_FULL | DMA);
517
518 if (pcdev->vb_mode == OMAP1_CAM_DMA_SG) {
519 /*
520 * In SG mode, the above prepare_next_vb() didn't actually
521 * put anything into the DMA programming register set,
522 * so we have to do it now, before activating DMA.
523 */
524 try_next_sgbuf(pcdev->dma_ch, buf);
525 }
526
527 start_capture(pcdev);
528}
529
530static void omap1_videobuf_release(struct videobuf_queue *vq,
531 struct videobuf_buffer *vb)
532{
533 struct omap1_cam_buf *buf =
534 container_of(vb, struct omap1_cam_buf, vb);
535 struct soc_camera_device *icd = vq->priv_data;
536 struct device *dev = icd->parent;
537 struct soc_camera_host *ici = to_soc_camera_host(dev);
538 struct omap1_cam_dev *pcdev = ici->priv;
539
540 switch (vb->state) {
541 case VIDEOBUF_DONE:
542 dev_dbg(dev, "%s (done)\n", __func__);
543 break;
544 case VIDEOBUF_ACTIVE:
545 dev_dbg(dev, "%s (active)\n", __func__);
546 break;
547 case VIDEOBUF_QUEUED:
548 dev_dbg(dev, "%s (queued)\n", __func__);
549 break;
550 case VIDEOBUF_PREPARED:
551 dev_dbg(dev, "%s (prepared)\n", __func__);
552 break;
553 default:
554 dev_dbg(dev, "%s (unknown %d)\n", __func__, vb->state);
555 break;
556 }
557
558 free_buffer(vq, buf, pcdev->vb_mode);
559}
560
561static void videobuf_done(struct omap1_cam_dev *pcdev,
562 enum videobuf_state result)
563{
564 struct omap1_cam_buf *buf = pcdev->active;
565 struct videobuf_buffer *vb;
566 struct device *dev = pcdev->icd->parent;
567
568 if (WARN_ON(!buf)) {
569 suspend_capture(pcdev);
570 disable_capture(pcdev);
571 return;
572 }
573
574 if (result == VIDEOBUF_ERROR)
575 suspend_capture(pcdev);
576
577 vb = &buf->vb;
578 if (waitqueue_active(&vb->done)) {
579 if (!pcdev->ready && result != VIDEOBUF_ERROR) {
580 /*
581 * No next buffer has been entered into the DMA
582 * programming register set on time (could be done only
583 * while the previous DMA interurpt was processed, not
584 * later), so the last DMA block, be it a whole buffer
585 * if in CONTIG or its last sgbuf if in SG mode, is
586 * about to be reused by the just autoreinitialized DMA
587 * engine, and overwritten with next frame data. Best we
588 * can do is stopping the capture as soon as possible,
589 * hopefully before the next frame start.
590 */
591 suspend_capture(pcdev);
592 }
593 vb->state = result;
594 do_gettimeofday(&vb->ts);
595 if (result != VIDEOBUF_ERROR)
596 vb->field_count++;
597 wake_up(&vb->done);
598
599 /* shift in next buffer */
600 buf = pcdev->ready;
601 pcdev->active = buf;
602 pcdev->ready = NULL;
603
604 if (!buf) {
605 /*
606 * No next buffer was ready on time (see above), so
607 * indicate error condition to force capture restart or
608 * stop, depending on next buffer already queued or not.
609 */
610 result = VIDEOBUF_ERROR;
611 prepare_next_vb(pcdev);
612
613 buf = pcdev->ready;
614 pcdev->active = buf;
615 pcdev->ready = NULL;
616 }
617 } else if (pcdev->ready) {
618 /*
619 * In both CONTIG and SG mode, the DMA engine has possibly
620 * been already autoreinitialized with the preprogrammed
621 * pcdev->ready buffer. We can either accept this fact
622 * and just swap the buffers, or provoke an error condition
623 * and restart capture. The former seems less intrusive.
624 */
625 dev_dbg(dev, "%s: nobody waiting on videobuf, swap with next\n",
626 __func__);
627 pcdev->active = pcdev->ready;
628
629 if (pcdev->vb_mode == OMAP1_CAM_DMA_SG) {
630 /*
631 * In SG mode, we have to make sure that the buffer we
632 * are putting back into the pcdev->ready is marked
633 * fresh.
634 */
635 buf->sgbuf = NULL;
636 }
637 pcdev->ready = buf;
638
639 buf = pcdev->active;
640 } else {
641 /*
642 * No next buffer has been entered into
643 * the DMA programming register set on time.
644 */
645 if (pcdev->vb_mode == OMAP1_CAM_DMA_CONTIG) {
646 /*
647 * In CONTIG mode, the DMA engine has already been
648 * reinitialized with the current buffer. Best we can do
649 * is not touching it.
650 */
651 dev_dbg(dev,
652 "%s: nobody waiting on videobuf, reuse it\n",
653 __func__);
654 } else {
655 /*
656 * In SG mode, the DMA engine has just been
657 * autoreinitialized with the last sgbuf from the
658 * current list. Restart capture in order to transfer
659 * next frame start into the first sgbuf, not the last
660 * one.
661 */
662 if (result != VIDEOBUF_ERROR) {
663 suspend_capture(pcdev);
664 result = VIDEOBUF_ERROR;
665 }
666 }
667 }
668
669 if (!buf) {
670 dev_dbg(dev, "%s: no more videobufs, stop capture\n", __func__);
671 disable_capture(pcdev);
672 return;
673 }
674
675 if (pcdev->vb_mode == OMAP1_CAM_DMA_CONTIG) {
676 /*
677 * In CONTIG mode, the current buffer parameters had already
678 * been entered into the DMA programming register set while the
679 * buffer was fetched with prepare_next_vb(), they may have also
680 * been transferred into the runtime set and already active if
681 * the DMA still running.
682 */
683 } else {
684 /* In SG mode, extra steps are required */
685 if (result == VIDEOBUF_ERROR)
686 /* make sure we (re)use sglist from start on error */
687 buf->sgbuf = NULL;
688
689 /*
690 * In any case, enter the next sgbuf parameters into the DMA
691 * programming register set. They will be used either during
692 * nearest DMA autoreinitialization or, in case of an error,
693 * on DMA startup below.
694 */
695 try_next_sgbuf(pcdev->dma_ch, buf);
696 }
697
698 if (result == VIDEOBUF_ERROR) {
699 dev_dbg(dev, "%s: videobuf error; reset FIFO, restart DMA\n",
700 __func__);
701 start_capture(pcdev);
702 /*
703 * In SG mode, the above also resulted in the next sgbuf
704 * parameters being entered into the DMA programming register
705 * set, making them ready for next DMA autoreinitialization.
706 */
707 }
708
709 /*
710 * Finally, try fetching next buffer.
711 * In CONTIG mode, it will also enter it into the DMA programming
712 * register set, making it ready for next DMA autoreinitialization.
713 */
714 prepare_next_vb(pcdev);
715}
716
717static void dma_isr(int channel, unsigned short status, void *data)
718{
719 struct omap1_cam_dev *pcdev = data;
720 struct omap1_cam_buf *buf = pcdev->active;
721 unsigned long flags;
722
723 spin_lock_irqsave(&pcdev->lock, flags);
724
725 if (WARN_ON(!buf)) {
726 suspend_capture(pcdev);
727 disable_capture(pcdev);
728 goto out;
729 }
730
731 if (pcdev->vb_mode == OMAP1_CAM_DMA_CONTIG) {
732 /*
733 * In CONTIG mode, assume we have just managed to collect the
734 * whole frame, hopefully before our end of frame watchdog is
735 * triggered. Then, all we have to do is disabling the watchdog
736 * for this frame, and calling videobuf_done() with success
737 * indicated.
738 */
739 CAM_WRITE(pcdev, MODE,
740 CAM_READ_CACHE(pcdev, MODE) & ~EN_V_DOWN);
741 videobuf_done(pcdev, VIDEOBUF_DONE);
742 } else {
743 /*
744 * In SG mode, we have to process every sgbuf from the current
745 * sglist, one after another.
746 */
747 if (buf->sgbuf) {
748 /*
749 * Current sglist not completed yet, try fetching next
750 * sgbuf, hopefully putting it into the DMA programming
751 * register set, making it ready for next DMA
752 * autoreinitialization.
753 */
754 try_next_sgbuf(pcdev->dma_ch, buf);
755 if (buf->sgbuf)
756 goto out;
757
758 /*
759 * No more sgbufs left in the current sglist. This
760 * doesn't mean that the whole videobuffer is already
761 * complete, but only that the last sgbuf from the
762 * current sglist is about to be filled. It will be
763 * ready on next DMA interrupt, signalled with the
764 * buf->sgbuf set back to NULL.
765 */
766 if (buf->result != VIDEOBUF_ERROR) {
767 /*
768 * Video frame collected without errors so far,
769 * we can prepare for collecting a next one
770 * as soon as DMA gets autoreinitialized
771 * after the current (last) sgbuf is completed.
772 */
773 buf = prepare_next_vb(pcdev);
774 if (!buf)
775 goto out;
776
777 try_next_sgbuf(pcdev->dma_ch, buf);
778 goto out;
779 }
780 }
781 /* end of videobuf */
782 videobuf_done(pcdev, buf->result);
783 }
784
785out:
786 spin_unlock_irqrestore(&pcdev->lock, flags);
787}
788
789static irqreturn_t cam_isr(int irq, void *data)
790{
791 struct omap1_cam_dev *pcdev = data;
792 struct device *dev = pcdev->icd->parent;
793 struct omap1_cam_buf *buf = pcdev->active;
794 u32 it_status;
795 unsigned long flags;
796
797 it_status = CAM_READ(pcdev, IT_STATUS);
798 if (!it_status)
799 return IRQ_NONE;
800
801 spin_lock_irqsave(&pcdev->lock, flags);
802
803 if (WARN_ON(!buf)) {
804 dev_warn(dev, "%s: unhandled camera interrupt, status == %#x\n",
805 __func__, it_status);
806 suspend_capture(pcdev);
807 disable_capture(pcdev);
808 goto out;
809 }
810
811 if (unlikely(it_status & FIFO_FULL)) {
812 dev_warn(dev, "%s: FIFO overflow\n", __func__);
813
814 } else if (it_status & V_DOWN) {
815 /* end of video frame watchdog */
816 if (pcdev->vb_mode == OMAP1_CAM_DMA_CONTIG) {
817 /*
818 * In CONTIG mode, the watchdog is disabled with
819 * successful DMA end of block interrupt, and reenabled
820 * on next frame start. If we get here, there is nothing
821 * to check, we must be out of sync.
822 */
823 } else {
824 if (buf->sgcount == 2) {
825 /*
826 * If exactly 2 sgbufs from the next sglist have
827 * been programmed into the DMA engine (the
828 * first one already transferred into the DMA
829 * runtime register set, the second one still
830 * in the programming set), then we are in sync.
831 */
832 goto out;
833 }
834 }
835 dev_notice(dev, "%s: unexpected end of video frame\n",
836 __func__);
837
838 } else if (it_status & V_UP) {
839 u32 mode;
840
841 if (pcdev->vb_mode == OMAP1_CAM_DMA_CONTIG) {
842 /*
843 * In CONTIG mode, we need this interrupt every frame
844 * in oredr to reenable our end of frame watchdog.
845 */
846 mode = CAM_READ_CACHE(pcdev, MODE);
847 } else {
848 /*
849 * In SG mode, the below enabled end of frame watchdog
850 * is kept on permanently, so we can turn this one shot
851 * setup off.
852 */
853 mode = CAM_READ_CACHE(pcdev, MODE) & ~EN_V_UP;
854 }
855
856 if (!(mode & EN_V_DOWN)) {
857 /* (re)enable end of frame watchdog interrupt */
858 mode |= EN_V_DOWN;
859 }
860 CAM_WRITE(pcdev, MODE, mode);
861 goto out;
862
863 } else {
864 dev_warn(dev, "%s: unhandled camera interrupt, status == %#x\n",
865 __func__, it_status);
866 goto out;
867 }
868
869 videobuf_done(pcdev, VIDEOBUF_ERROR);
870out:
871 spin_unlock_irqrestore(&pcdev->lock, flags);
872 return IRQ_HANDLED;
873}
874
875static struct videobuf_queue_ops omap1_videobuf_ops = {
876 .buf_setup = omap1_videobuf_setup,
877 .buf_prepare = omap1_videobuf_prepare,
878 .buf_queue = omap1_videobuf_queue,
879 .buf_release = omap1_videobuf_release,
880};
881
882
883/*
884 * SOC Camera host operations
885 */
886
887static void sensor_reset(struct omap1_cam_dev *pcdev, bool reset)
888{
889 /* apply/release camera sensor reset if requested by platform data */
890 if (pcdev->pflags & OMAP1_CAMERA_RST_HIGH)
891 CAM_WRITE(pcdev, GPIO, reset);
892 else if (pcdev->pflags & OMAP1_CAMERA_RST_LOW)
893 CAM_WRITE(pcdev, GPIO, !reset);
894}
895
896/*
897 * The following two functions absolutely depend on the fact, that
898 * there can be only one camera on OMAP1 camera sensor interface
899 */
900static int omap1_cam_add_device(struct soc_camera_device *icd)
901{
902 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
903 struct omap1_cam_dev *pcdev = ici->priv;
904 u32 ctrlclock;
905
906 if (pcdev->icd)
907 return -EBUSY;
908
909 clk_enable(pcdev->clk);
910
911 /* setup sensor clock */
912 ctrlclock = CAM_READ(pcdev, CTRLCLOCK);
913 ctrlclock &= ~(CAMEXCLK_EN | MCLK_EN | DPLL_EN);
914 CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock);
915
916 ctrlclock &= ~FOSCMOD_MASK;
917 switch (pcdev->camexclk) {
918 case 6000000:
919 ctrlclock |= CAMEXCLK_EN | FOSCMOD_6MHz;
920 break;
921 case 8000000:
922 ctrlclock |= CAMEXCLK_EN | FOSCMOD_8MHz | DPLL_EN;
923 break;
924 case 9600000:
925 ctrlclock |= CAMEXCLK_EN | FOSCMOD_9_6MHz | DPLL_EN;
926 break;
927 case 12000000:
928 ctrlclock |= CAMEXCLK_EN | FOSCMOD_12MHz;
929 break;
930 case 24000000:
931 ctrlclock |= CAMEXCLK_EN | FOSCMOD_24MHz | DPLL_EN;
932 default:
933 break;
934 }
935 CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock & ~DPLL_EN);
936
937 /* enable internal clock */
938 ctrlclock |= MCLK_EN;
939 CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock);
940
941 sensor_reset(pcdev, false);
942
943 pcdev->icd = icd;
944
945 dev_dbg(icd->parent, "OMAP1 Camera driver attached to camera %d\n",
946 icd->devnum);
947 return 0;
948}
949
950static void omap1_cam_remove_device(struct soc_camera_device *icd)
951{
952 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
953 struct omap1_cam_dev *pcdev = ici->priv;
954 u32 ctrlclock;
955
956 BUG_ON(icd != pcdev->icd);
957
958 suspend_capture(pcdev);
959 disable_capture(pcdev);
960
961 sensor_reset(pcdev, true);
962
963 /* disable and release system clocks */
964 ctrlclock = CAM_READ_CACHE(pcdev, CTRLCLOCK);
965 ctrlclock &= ~(MCLK_EN | DPLL_EN | CAMEXCLK_EN);
966 CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock);
967
968 ctrlclock = (ctrlclock & ~FOSCMOD_MASK) | FOSCMOD_12MHz;
969 CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock);
970 CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock | MCLK_EN);
971
972 CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock & ~MCLK_EN);
973
974 clk_disable(pcdev->clk);
975
976 pcdev->icd = NULL;
977
978 dev_dbg(icd->parent,
979 "OMAP1 Camera driver detached from camera %d\n", icd->devnum);
980}
981
982/* Duplicate standard formats based on host capability of byte swapping */
983static const struct soc_mbus_lookup omap1_cam_formats[] = {
984{
985 .code = V4L2_MBUS_FMT_UYVY8_2X8,
986 .fmt = {
987 .fourcc = V4L2_PIX_FMT_YUYV,
988 .name = "YUYV",
989 .bits_per_sample = 8,
990 .packing = SOC_MBUS_PACKING_2X8_PADHI,
991 .order = SOC_MBUS_ORDER_BE,
992 .layout = SOC_MBUS_LAYOUT_PACKED,
993 },
994}, {
995 .code = V4L2_MBUS_FMT_VYUY8_2X8,
996 .fmt = {
997 .fourcc = V4L2_PIX_FMT_YVYU,
998 .name = "YVYU",
999 .bits_per_sample = 8,
1000 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1001 .order = SOC_MBUS_ORDER_BE,
1002 .layout = SOC_MBUS_LAYOUT_PACKED,
1003 },
1004}, {
1005 .code = V4L2_MBUS_FMT_YUYV8_2X8,
1006 .fmt = {
1007 .fourcc = V4L2_PIX_FMT_UYVY,
1008 .name = "UYVY",
1009 .bits_per_sample = 8,
1010 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1011 .order = SOC_MBUS_ORDER_BE,
1012 .layout = SOC_MBUS_LAYOUT_PACKED,
1013 },
1014}, {
1015 .code = V4L2_MBUS_FMT_YVYU8_2X8,
1016 .fmt = {
1017 .fourcc = V4L2_PIX_FMT_VYUY,
1018 .name = "VYUY",
1019 .bits_per_sample = 8,
1020 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1021 .order = SOC_MBUS_ORDER_BE,
1022 .layout = SOC_MBUS_LAYOUT_PACKED,
1023 },
1024}, {
1025 .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE,
1026 .fmt = {
1027 .fourcc = V4L2_PIX_FMT_RGB555,
1028 .name = "RGB555",
1029 .bits_per_sample = 8,
1030 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1031 .order = SOC_MBUS_ORDER_BE,
1032 .layout = SOC_MBUS_LAYOUT_PACKED,
1033 },
1034}, {
1035 .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE,
1036 .fmt = {
1037 .fourcc = V4L2_PIX_FMT_RGB555X,
1038 .name = "RGB555X",
1039 .bits_per_sample = 8,
1040 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1041 .order = SOC_MBUS_ORDER_BE,
1042 .layout = SOC_MBUS_LAYOUT_PACKED,
1043 },
1044}, {
1045 .code = V4L2_MBUS_FMT_RGB565_2X8_BE,
1046 .fmt = {
1047 .fourcc = V4L2_PIX_FMT_RGB565,
1048 .name = "RGB565",
1049 .bits_per_sample = 8,
1050 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1051 .order = SOC_MBUS_ORDER_BE,
1052 .layout = SOC_MBUS_LAYOUT_PACKED,
1053 },
1054}, {
1055 .code = V4L2_MBUS_FMT_RGB565_2X8_LE,
1056 .fmt = {
1057 .fourcc = V4L2_PIX_FMT_RGB565X,
1058 .name = "RGB565X",
1059 .bits_per_sample = 8,
1060 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1061 .order = SOC_MBUS_ORDER_BE,
1062 .layout = SOC_MBUS_LAYOUT_PACKED,
1063 },
1064},
1065};
1066
1067static int omap1_cam_get_formats(struct soc_camera_device *icd,
1068 unsigned int idx, struct soc_camera_format_xlate *xlate)
1069{
1070 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1071 struct device *dev = icd->parent;
1072 int formats = 0, ret;
1073 enum v4l2_mbus_pixelcode code;
1074 const struct soc_mbus_pixelfmt *fmt;
1075
1076 ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code);
1077 if (ret < 0)
1078 /* No more formats */
1079 return 0;
1080
1081 fmt = soc_mbus_get_fmtdesc(code);
1082 if (!fmt) {
1083 dev_warn(dev, "%s: unsupported format code #%d: %d\n", __func__,
1084 idx, code);
1085 return 0;
1086 }
1087
1088 /* Check support for the requested bits-per-sample */
1089 if (fmt->bits_per_sample != 8)
1090 return 0;
1091
1092 switch (code) {
1093 case V4L2_MBUS_FMT_YUYV8_2X8:
1094 case V4L2_MBUS_FMT_YVYU8_2X8:
1095 case V4L2_MBUS_FMT_UYVY8_2X8:
1096 case V4L2_MBUS_FMT_VYUY8_2X8:
1097 case V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE:
1098 case V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE:
1099 case V4L2_MBUS_FMT_RGB565_2X8_BE:
1100 case V4L2_MBUS_FMT_RGB565_2X8_LE:
1101 formats++;
1102 if (xlate) {
1103 xlate->host_fmt = soc_mbus_find_fmtdesc(code,
1104 omap1_cam_formats,
1105 ARRAY_SIZE(omap1_cam_formats));
1106 xlate->code = code;
1107 xlate++;
1108 dev_dbg(dev,
1109 "%s: providing format %s as byte swapped code #%d\n",
1110 __func__, xlate->host_fmt->name, code);
1111 }
1112 default:
1113 if (xlate)
1114 dev_dbg(dev,
1115 "%s: providing format %s in pass-through mode\n",
1116 __func__, fmt->name);
1117 }
1118 formats++;
1119 if (xlate) {
1120 xlate->host_fmt = fmt;
1121 xlate->code = code;
1122 xlate++;
1123 }
1124
1125 return formats;
1126}
1127
1128static bool is_dma_aligned(s32 bytes_per_line, unsigned int height,
1129 enum omap1_cam_vb_mode vb_mode)
1130{
1131 int size = bytes_per_line * height;
1132
1133 return IS_ALIGNED(bytes_per_line, DMA_ELEMENT_SIZE) &&
1134 IS_ALIGNED(size, DMA_FRAME_SIZE(vb_mode) * DMA_ELEMENT_SIZE);
1135}
1136
1137static int dma_align(int *width, int *height,
1138 const struct soc_mbus_pixelfmt *fmt,
1139 enum omap1_cam_vb_mode vb_mode, bool enlarge)
1140{
1141 s32 bytes_per_line = soc_mbus_bytes_per_line(*width, fmt);
1142
1143 if (bytes_per_line < 0)
1144 return bytes_per_line;
1145
1146 if (!is_dma_aligned(bytes_per_line, *height, vb_mode)) {
1147 unsigned int pxalign = __fls(bytes_per_line / *width);
1148 unsigned int salign = DMA_FRAME_SHIFT(vb_mode) +
1149 DMA_ELEMENT_SHIFT - pxalign;
1150 unsigned int incr = enlarge << salign;
1151
1152 v4l_bound_align_image(width, 1, *width + incr, 0,
1153 height, 1, *height + incr, 0, salign);
1154 return 0;
1155 }
1156 return 1;
1157}
1158
1159#define subdev_call_with_sense(pcdev, dev, icd, sd, function, args...) \
1160({ \
1161 struct soc_camera_sense sense = { \
1162 .master_clock = pcdev->camexclk, \
1163 .pixel_clock_max = 0, \
1164 }; \
1165 int __ret; \
1166 \
1167 if (pcdev->pdata) \
1168 sense.pixel_clock_max = pcdev->pdata->lclk_khz_max * 1000; \
1169 icd->sense = &sense; \
1170 __ret = v4l2_subdev_call(sd, video, function, ##args); \
1171 icd->sense = NULL; \
1172 \
1173 if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) { \
1174 if (sense.pixel_clock > sense.pixel_clock_max) { \
1175 dev_err(dev, \
1176 "%s: pixel clock %lu set by the camera too high!\n", \
1177 __func__, sense.pixel_clock); \
1178 __ret = -EINVAL; \
1179 } \
1180 } \
1181 __ret; \
1182})
1183
1184static int set_mbus_format(struct omap1_cam_dev *pcdev, struct device *dev,
1185 struct soc_camera_device *icd, struct v4l2_subdev *sd,
1186 struct v4l2_mbus_framefmt *mf,
1187 const struct soc_camera_format_xlate *xlate)
1188{
1189 s32 bytes_per_line;
1190 int ret = subdev_call_with_sense(pcdev, dev, icd, sd, s_mbus_fmt, mf);
1191
1192 if (ret < 0) {
1193 dev_err(dev, "%s: s_mbus_fmt failed\n", __func__);
1194 return ret;
1195 }
1196
1197 if (mf->code != xlate->code) {
1198 dev_err(dev, "%s: unexpected pixel code change\n", __func__);
1199 return -EINVAL;
1200 }
1201
1202 bytes_per_line = soc_mbus_bytes_per_line(mf->width, xlate->host_fmt);
1203 if (bytes_per_line < 0) {
1204 dev_err(dev, "%s: soc_mbus_bytes_per_line() failed\n",
1205 __func__);
1206 return bytes_per_line;
1207 }
1208
1209 if (!is_dma_aligned(bytes_per_line, mf->height, pcdev->vb_mode)) {
1210 dev_err(dev, "%s: resulting geometry %ux%u not DMA aligned\n",
1211 __func__, mf->width, mf->height);
1212 return -EINVAL;
1213 }
1214 return 0;
1215}
1216
1217static int omap1_cam_set_crop(struct soc_camera_device *icd,
1218 struct v4l2_crop *crop)
1219{
1220 struct v4l2_rect *rect = &crop->c;
1221 const struct soc_camera_format_xlate *xlate = icd->current_fmt;
1222 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1223 struct device *dev = icd->parent;
1224 struct soc_camera_host *ici = to_soc_camera_host(dev);
1225 struct omap1_cam_dev *pcdev = ici->priv;
1226 struct v4l2_mbus_framefmt mf;
1227 int ret;
1228
1229 ret = subdev_call_with_sense(pcdev, dev, icd, sd, s_crop, crop);
1230 if (ret < 0) {
1231 dev_warn(dev, "%s: failed to crop to %ux%u@%u:%u\n", __func__,
1232 rect->width, rect->height, rect->left, rect->top);
1233 return ret;
1234 }
1235
1236 ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf);
1237 if (ret < 0) {
1238 dev_warn(dev, "%s: failed to fetch current format\n", __func__);
1239 return ret;
1240 }
1241
1242 ret = dma_align(&mf.width, &mf.height, xlate->host_fmt, pcdev->vb_mode,
1243 false);
1244 if (ret < 0) {
1245 dev_err(dev, "%s: failed to align %ux%u %s with DMA\n",
1246 __func__, mf.width, mf.height,
1247 xlate->host_fmt->name);
1248 return ret;
1249 }
1250
1251 if (!ret) {
1252 /* sensor returned geometry not DMA aligned, trying to fix */
1253 ret = set_mbus_format(pcdev, dev, icd, sd, &mf, xlate);
1254 if (ret < 0) {
1255 dev_err(dev, "%s: failed to set format\n", __func__);
1256 return ret;
1257 }
1258 }
1259
1260 icd->user_width = mf.width;
1261 icd->user_height = mf.height;
1262
1263 return 0;
1264}
1265
1266static int omap1_cam_set_fmt(struct soc_camera_device *icd,
1267 struct v4l2_format *f)
1268{
1269 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1270 const struct soc_camera_format_xlate *xlate;
1271 struct device *dev = icd->parent;
1272 struct soc_camera_host *ici = to_soc_camera_host(dev);
1273 struct omap1_cam_dev *pcdev = ici->priv;
1274 struct v4l2_pix_format *pix = &f->fmt.pix;
1275 struct v4l2_mbus_framefmt mf;
1276 int ret;
1277
1278 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
1279 if (!xlate) {
1280 dev_warn(dev, "%s: format %#x not found\n", __func__,
1281 pix->pixelformat);
1282 return -EINVAL;
1283 }
1284
1285 mf.width = pix->width;
1286 mf.height = pix->height;
1287 mf.field = pix->field;
1288 mf.colorspace = pix->colorspace;
1289 mf.code = xlate->code;
1290
1291 ret = dma_align(&mf.width, &mf.height, xlate->host_fmt, pcdev->vb_mode,
1292 true);
1293 if (ret < 0) {
1294 dev_err(dev, "%s: failed to align %ux%u %s with DMA\n",
1295 __func__, pix->width, pix->height,
1296 xlate->host_fmt->name);
1297 return ret;
1298 }
1299
1300 ret = set_mbus_format(pcdev, dev, icd, sd, &mf, xlate);
1301 if (ret < 0) {
1302 dev_err(dev, "%s: failed to set format\n", __func__);
1303 return ret;
1304 }
1305
1306 pix->width = mf.width;
1307 pix->height = mf.height;
1308 pix->field = mf.field;
1309 pix->colorspace = mf.colorspace;
1310 icd->current_fmt = xlate;
1311
1312 return 0;
1313}
1314
1315static int omap1_cam_try_fmt(struct soc_camera_device *icd,
1316 struct v4l2_format *f)
1317{
1318 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1319 const struct soc_camera_format_xlate *xlate;
1320 struct v4l2_pix_format *pix = &f->fmt.pix;
1321 struct v4l2_mbus_framefmt mf;
1322 int ret;
1323 /* TODO: limit to mx1 hardware capabilities */
1324
1325 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
1326 if (!xlate) {
1327 dev_warn(icd->parent, "Format %#x not found\n",
1328 pix->pixelformat);
1329 return -EINVAL;
1330 }
1331
1332 mf.width = pix->width;
1333 mf.height = pix->height;
1334 mf.field = pix->field;
1335 mf.colorspace = pix->colorspace;
1336 mf.code = xlate->code;
1337
1338 /* limit to sensor capabilities */
1339 ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
1340 if (ret < 0)
1341 return ret;
1342
1343 pix->width = mf.width;
1344 pix->height = mf.height;
1345 pix->field = mf.field;
1346 pix->colorspace = mf.colorspace;
1347
1348 return 0;
1349}
1350
1351static bool sg_mode;
1352
1353/*
1354 * Local mmap_mapper wrapper,
1355 * used for detecting videobuf-dma-contig buffer allocation failures
1356 * and switching to videobuf-dma-sg automatically for future attempts.
1357 */
1358static int omap1_cam_mmap_mapper(struct videobuf_queue *q,
1359 struct videobuf_buffer *buf,
1360 struct vm_area_struct *vma)
1361{
1362 struct soc_camera_device *icd = q->priv_data;
1363 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1364 struct omap1_cam_dev *pcdev = ici->priv;
1365 int ret;
1366
1367 ret = pcdev->mmap_mapper(q, buf, vma);
1368
1369 if (ret == -ENOMEM)
1370 sg_mode = true;
1371
1372 return ret;
1373}
1374
1375static void omap1_cam_init_videobuf(struct videobuf_queue *q,
1376 struct soc_camera_device *icd)
1377{
1378 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1379 struct omap1_cam_dev *pcdev = ici->priv;
1380
1381 if (!sg_mode)
1382 videobuf_queue_dma_contig_init(q, &omap1_videobuf_ops,
1383 icd->parent, &pcdev->lock,
1384 V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE,
1385 sizeof(struct omap1_cam_buf), icd, &icd->video_lock);
1386 else
1387 videobuf_queue_sg_init(q, &omap1_videobuf_ops,
1388 icd->parent, &pcdev->lock,
1389 V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE,
1390 sizeof(struct omap1_cam_buf), icd, &icd->video_lock);
1391
1392 /* use videobuf mode (auto)selected with the module parameter */
1393 pcdev->vb_mode = sg_mode ? OMAP1_CAM_DMA_SG : OMAP1_CAM_DMA_CONTIG;
1394
1395 /*
1396 * Ensure we substitute the videobuf-dma-contig version of the
1397 * mmap_mapper() callback with our own wrapper, used for switching
1398 * automatically to videobuf-dma-sg on buffer allocation failure.
1399 */
1400 if (!sg_mode && q->int_ops->mmap_mapper != omap1_cam_mmap_mapper) {
1401 pcdev->mmap_mapper = q->int_ops->mmap_mapper;
1402 q->int_ops->mmap_mapper = omap1_cam_mmap_mapper;
1403 }
1404}
1405
1406static int omap1_cam_reqbufs(struct soc_camera_device *icd,
1407 struct v4l2_requestbuffers *p)
1408{
1409 int i;
1410
1411 /*
1412 * This is for locking debugging only. I removed spinlocks and now I
1413 * check whether .prepare is ever called on a linked buffer, or whether
1414 * a dma IRQ can occur for an in-work or unlinked buffer. Until now
1415 * it hadn't triggered
1416 */
1417 for (i = 0; i < p->count; i++) {
1418 struct omap1_cam_buf *buf = container_of(icd->vb_vidq.bufs[i],
1419 struct omap1_cam_buf, vb);
1420 buf->inwork = 0;
1421 INIT_LIST_HEAD(&buf->vb.queue);
1422 }
1423
1424 return 0;
1425}
1426
1427static int omap1_cam_querycap(struct soc_camera_host *ici,
1428 struct v4l2_capability *cap)
1429{
1430 /* cap->name is set by the friendly caller:-> */
1431 strlcpy(cap->card, "OMAP1 Camera", sizeof(cap->card));
1432 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
1433
1434 return 0;
1435}
1436
1437static int omap1_cam_set_bus_param(struct soc_camera_device *icd)
1438{
1439 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1440 struct device *dev = icd->parent;
1441 struct soc_camera_host *ici = to_soc_camera_host(dev);
1442 struct omap1_cam_dev *pcdev = ici->priv;
1443 u32 pixfmt = icd->current_fmt->host_fmt->fourcc;
1444 const struct soc_camera_format_xlate *xlate;
1445 const struct soc_mbus_pixelfmt *fmt;
1446 struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
1447 unsigned long common_flags;
1448 u32 ctrlclock, mode;
1449 int ret;
1450
1451 ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
1452 if (!ret) {
1453 common_flags = soc_mbus_config_compatible(&cfg, SOCAM_BUS_FLAGS);
1454 if (!common_flags) {
1455 dev_warn(dev,
1456 "Flags incompatible: camera 0x%x, host 0x%x\n",
1457 cfg.flags, SOCAM_BUS_FLAGS);
1458 return -EINVAL;
1459 }
1460 } else if (ret != -ENOIOCTLCMD) {
1461 return ret;
1462 } else {
1463 common_flags = SOCAM_BUS_FLAGS;
1464 }
1465
1466 /* Make choices, possibly based on platform configuration */
1467 if ((common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) &&
1468 (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)) {
1469 if (!pcdev->pdata ||
1470 pcdev->pdata->flags & OMAP1_CAMERA_LCLK_RISING)
1471 common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_FALLING;
1472 else
1473 common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_RISING;
1474 }
1475
1476 cfg.flags = common_flags;
1477 ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
1478 if (ret < 0 && ret != -ENOIOCTLCMD) {
1479 dev_dbg(dev, "camera s_mbus_config(0x%lx) returned %d\n",
1480 common_flags, ret);
1481 return ret;
1482 }
1483
1484 ctrlclock = CAM_READ_CACHE(pcdev, CTRLCLOCK);
1485 if (ctrlclock & LCLK_EN)
1486 CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock & ~LCLK_EN);
1487
1488 if (common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) {
1489 dev_dbg(dev, "CTRLCLOCK_REG |= POLCLK\n");
1490 ctrlclock |= POLCLK;
1491 } else {
1492 dev_dbg(dev, "CTRLCLOCK_REG &= ~POLCLK\n");
1493 ctrlclock &= ~POLCLK;
1494 }
1495 CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock & ~LCLK_EN);
1496
1497 if (ctrlclock & LCLK_EN)
1498 CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock);
1499
1500 /* select bus endianess */
1501 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
1502 fmt = xlate->host_fmt;
1503
1504 mode = CAM_READ(pcdev, MODE) & ~(RAZ_FIFO | IRQ_MASK | DMA);
1505 if (fmt->order == SOC_MBUS_ORDER_LE) {
1506 dev_dbg(dev, "MODE_REG &= ~ORDERCAMD\n");
1507 CAM_WRITE(pcdev, MODE, mode & ~ORDERCAMD);
1508 } else {
1509 dev_dbg(dev, "MODE_REG |= ORDERCAMD\n");
1510 CAM_WRITE(pcdev, MODE, mode | ORDERCAMD);
1511 }
1512
1513 return 0;
1514}
1515
1516static unsigned int omap1_cam_poll(struct file *file, poll_table *pt)
1517{
1518 struct soc_camera_device *icd = file->private_data;
1519 struct omap1_cam_buf *buf;
1520
1521 buf = list_entry(icd->vb_vidq.stream.next, struct omap1_cam_buf,
1522 vb.stream);
1523
1524 poll_wait(file, &buf->vb.done, pt);
1525
1526 if (buf->vb.state == VIDEOBUF_DONE ||
1527 buf->vb.state == VIDEOBUF_ERROR)
1528 return POLLIN | POLLRDNORM;
1529
1530 return 0;
1531}
1532
1533static struct soc_camera_host_ops omap1_host_ops = {
1534 .owner = THIS_MODULE,
1535 .add = omap1_cam_add_device,
1536 .remove = omap1_cam_remove_device,
1537 .get_formats = omap1_cam_get_formats,
1538 .set_crop = omap1_cam_set_crop,
1539 .set_fmt = omap1_cam_set_fmt,
1540 .try_fmt = omap1_cam_try_fmt,
1541 .init_videobuf = omap1_cam_init_videobuf,
1542 .reqbufs = omap1_cam_reqbufs,
1543 .querycap = omap1_cam_querycap,
1544 .set_bus_param = omap1_cam_set_bus_param,
1545 .poll = omap1_cam_poll,
1546};
1547
1548static int __init omap1_cam_probe(struct platform_device *pdev)
1549{
1550 struct omap1_cam_dev *pcdev;
1551 struct resource *res;
1552 struct clk *clk;
1553 void __iomem *base;
1554 unsigned int irq;
1555 int err = 0;
1556
1557 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1558 irq = platform_get_irq(pdev, 0);
1559 if (!res || (int)irq <= 0) {
1560 err = -ENODEV;
1561 goto exit;
1562 }
1563
1564 clk = clk_get(&pdev->dev, "armper_ck");
1565 if (IS_ERR(clk)) {
1566 err = PTR_ERR(clk);
1567 goto exit;
1568 }
1569
1570 pcdev = kzalloc(sizeof(*pcdev) + resource_size(res), GFP_KERNEL);
1571 if (!pcdev) {
1572 dev_err(&pdev->dev, "Could not allocate pcdev\n");
1573 err = -ENOMEM;
1574 goto exit_put_clk;
1575 }
1576
1577 pcdev->res = res;
1578 pcdev->clk = clk;
1579
1580 pcdev->pdata = pdev->dev.platform_data;
1581 if (pcdev->pdata) {
1582 pcdev->pflags = pcdev->pdata->flags;
1583 pcdev->camexclk = pcdev->pdata->camexclk_khz * 1000;
1584 }
1585
1586 switch (pcdev->camexclk) {
1587 case 6000000:
1588 case 8000000:
1589 case 9600000:
1590 case 12000000:
1591 case 24000000:
1592 break;
1593 default:
1594 /* pcdev->camexclk != 0 => pcdev->pdata != NULL */
1595 dev_warn(&pdev->dev,
1596 "Incorrect sensor clock frequency %ld kHz, "
1597 "should be one of 0, 6, 8, 9.6, 12 or 24 MHz, "
1598 "please correct your platform data\n",
1599 pcdev->pdata->camexclk_khz);
1600 pcdev->camexclk = 0;
1601 case 0:
1602 dev_info(&pdev->dev, "Not providing sensor clock\n");
1603 }
1604
1605 INIT_LIST_HEAD(&pcdev->capture);
1606 spin_lock_init(&pcdev->lock);
1607
1608 /*
1609 * Request the region.
1610 */
1611 if (!request_mem_region(res->start, resource_size(res), DRIVER_NAME)) {
1612 err = -EBUSY;
1613 goto exit_kfree;
1614 }
1615
1616 base = ioremap(res->start, resource_size(res));
1617 if (!base) {
1618 err = -ENOMEM;
1619 goto exit_release;
1620 }
1621 pcdev->irq = irq;
1622 pcdev->base = base;
1623
1624 sensor_reset(pcdev, true);
1625
1626 err = omap_request_dma(OMAP_DMA_CAMERA_IF_RX, DRIVER_NAME,
1627 dma_isr, (void *)pcdev, &pcdev->dma_ch);
1628 if (err < 0) {
1629 dev_err(&pdev->dev, "Can't request DMA for OMAP1 Camera\n");
1630 err = -EBUSY;
1631 goto exit_iounmap;
1632 }
1633 dev_dbg(&pdev->dev, "got DMA channel %d\n", pcdev->dma_ch);
1634
1635 /* preconfigure DMA */
1636 omap_set_dma_src_params(pcdev->dma_ch, OMAP_DMA_PORT_TIPB,
1637 OMAP_DMA_AMODE_CONSTANT, res->start + REG_CAMDATA,
1638 0, 0);
1639 omap_set_dma_dest_burst_mode(pcdev->dma_ch, OMAP_DMA_DATA_BURST_4);
1640 /* setup DMA autoinitialization */
1641 omap_dma_link_lch(pcdev->dma_ch, pcdev->dma_ch);
1642
1643 err = request_irq(pcdev->irq, cam_isr, 0, DRIVER_NAME, pcdev);
1644 if (err) {
1645 dev_err(&pdev->dev, "Camera interrupt register failed\n");
1646 goto exit_free_dma;
1647 }
1648
1649 pcdev->soc_host.drv_name = DRIVER_NAME;
1650 pcdev->soc_host.ops = &omap1_host_ops;
1651 pcdev->soc_host.priv = pcdev;
1652 pcdev->soc_host.v4l2_dev.dev = &pdev->dev;
1653 pcdev->soc_host.nr = pdev->id;
1654
1655 err = soc_camera_host_register(&pcdev->soc_host);
1656 if (err)
1657 goto exit_free_irq;
1658
1659 dev_info(&pdev->dev, "OMAP1 Camera Interface driver loaded\n");
1660
1661 return 0;
1662
1663exit_free_irq:
1664 free_irq(pcdev->irq, pcdev);
1665exit_free_dma:
1666 omap_free_dma(pcdev->dma_ch);
1667exit_iounmap:
1668 iounmap(base);
1669exit_release:
1670 release_mem_region(res->start, resource_size(res));
1671exit_kfree:
1672 kfree(pcdev);
1673exit_put_clk:
1674 clk_put(clk);
1675exit:
1676 return err;
1677}
1678
1679static int __exit omap1_cam_remove(struct platform_device *pdev)
1680{
1681 struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev);
1682 struct omap1_cam_dev *pcdev = container_of(soc_host,
1683 struct omap1_cam_dev, soc_host);
1684 struct resource *res;
1685
1686 free_irq(pcdev->irq, pcdev);
1687
1688 omap_free_dma(pcdev->dma_ch);
1689
1690 soc_camera_host_unregister(soc_host);
1691
1692 iounmap(pcdev->base);
1693
1694 res = pcdev->res;
1695 release_mem_region(res->start, resource_size(res));
1696
1697 clk_put(pcdev->clk);
1698
1699 kfree(pcdev);
1700
1701 dev_info(&pdev->dev, "OMAP1 Camera Interface driver unloaded\n");
1702
1703 return 0;
1704}
1705
1706static struct platform_driver omap1_cam_driver = {
1707 .driver = {
1708 .name = DRIVER_NAME,
1709 },
1710 .probe = omap1_cam_probe,
1711 .remove = __exit_p(omap1_cam_remove),
1712};
1713
1714module_platform_driver(omap1_cam_driver);
1715
1716module_param(sg_mode, bool, 0644);
1717MODULE_PARM_DESC(sg_mode, "videobuf mode, 0: dma-contig (default), 1: dma-sg");
1718
1719MODULE_DESCRIPTION("OMAP1 Camera Interface driver");
1720MODULE_AUTHOR("Janusz Krzysztofik <jkrzyszt@tis.icnet.pl>");
1721MODULE_LICENSE("GPL v2");
1722MODULE_VERSION(DRIVER_VERSION);
1723MODULE_ALIAS("platform:" DRIVER_NAME);
diff --git a/drivers/media/video/omap24xxcam-dma.c b/drivers/media/video/omap24xxcam-dma.c
deleted file mode 100644
index b5ae170de4a5..000000000000
--- a/drivers/media/video/omap24xxcam-dma.c
+++ /dev/null
@@ -1,601 +0,0 @@
1/*
2 * drivers/media/video/omap24xxcam-dma.c
3 *
4 * Copyright (C) 2004 MontaVista Software, Inc.
5 * Copyright (C) 2004 Texas Instruments.
6 * Copyright (C) 2007 Nokia Corporation.
7 *
8 * Contact: Sakari Ailus <sakari.ailus@nokia.com>
9 *
10 * Based on code from Andy Lowe <source@mvista.com> and
11 * David Cohen <david.cohen@indt.org.br>.
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * version 2 as published by the Free Software Foundation.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
25 * 02110-1301 USA
26 */
27
28#include <linux/kernel.h>
29#include <linux/io.h>
30#include <linux/scatterlist.h>
31
32#include "omap24xxcam.h"
33
34/*
35 *
36 * DMA hardware.
37 *
38 */
39
40/* Ack all interrupt on CSR and IRQSTATUS_L0 */
41static void omap24xxcam_dmahw_ack_all(void __iomem *base)
42{
43 u32 csr;
44 int i;
45
46 for (i = 0; i < NUM_CAMDMA_CHANNELS; ++i) {
47 csr = omap24xxcam_reg_in(base, CAMDMA_CSR(i));
48 /* ack interrupt in CSR */
49 omap24xxcam_reg_out(base, CAMDMA_CSR(i), csr);
50 }
51 omap24xxcam_reg_out(base, CAMDMA_IRQSTATUS_L0, 0xf);
52}
53
54/* Ack dmach on CSR and IRQSTATUS_L0 */
55static u32 omap24xxcam_dmahw_ack_ch(void __iomem *base, int dmach)
56{
57 u32 csr;
58
59 csr = omap24xxcam_reg_in(base, CAMDMA_CSR(dmach));
60 /* ack interrupt in CSR */
61 omap24xxcam_reg_out(base, CAMDMA_CSR(dmach), csr);
62 /* ack interrupt in IRQSTATUS */
63 omap24xxcam_reg_out(base, CAMDMA_IRQSTATUS_L0, (1 << dmach));
64
65 return csr;
66}
67
68static int omap24xxcam_dmahw_running(void __iomem *base, int dmach)
69{
70 return omap24xxcam_reg_in(base, CAMDMA_CCR(dmach)) & CAMDMA_CCR_ENABLE;
71}
72
73static void omap24xxcam_dmahw_transfer_setup(void __iomem *base, int dmach,
74 dma_addr_t start, u32 len)
75{
76 omap24xxcam_reg_out(base, CAMDMA_CCR(dmach),
77 CAMDMA_CCR_SEL_SRC_DST_SYNC
78 | CAMDMA_CCR_BS
79 | CAMDMA_CCR_DST_AMODE_POST_INC
80 | CAMDMA_CCR_SRC_AMODE_POST_INC
81 | CAMDMA_CCR_FS
82 | CAMDMA_CCR_WR_ACTIVE
83 | CAMDMA_CCR_RD_ACTIVE
84 | CAMDMA_CCR_SYNCHRO_CAMERA);
85 omap24xxcam_reg_out(base, CAMDMA_CLNK_CTRL(dmach), 0);
86 omap24xxcam_reg_out(base, CAMDMA_CEN(dmach), len);
87 omap24xxcam_reg_out(base, CAMDMA_CFN(dmach), 1);
88 omap24xxcam_reg_out(base, CAMDMA_CSDP(dmach),
89 CAMDMA_CSDP_WRITE_MODE_POSTED
90 | CAMDMA_CSDP_DST_BURST_EN_32
91 | CAMDMA_CSDP_DST_PACKED
92 | CAMDMA_CSDP_SRC_BURST_EN_32
93 | CAMDMA_CSDP_SRC_PACKED
94 | CAMDMA_CSDP_DATA_TYPE_8BITS);
95 omap24xxcam_reg_out(base, CAMDMA_CSSA(dmach), 0);
96 omap24xxcam_reg_out(base, CAMDMA_CDSA(dmach), start);
97 omap24xxcam_reg_out(base, CAMDMA_CSEI(dmach), 0);
98 omap24xxcam_reg_out(base, CAMDMA_CSFI(dmach), DMA_THRESHOLD);
99 omap24xxcam_reg_out(base, CAMDMA_CDEI(dmach), 0);
100 omap24xxcam_reg_out(base, CAMDMA_CDFI(dmach), 0);
101 omap24xxcam_reg_out(base, CAMDMA_CSR(dmach),
102 CAMDMA_CSR_MISALIGNED_ERR
103 | CAMDMA_CSR_SECURE_ERR
104 | CAMDMA_CSR_TRANS_ERR
105 | CAMDMA_CSR_BLOCK
106 | CAMDMA_CSR_DROP);
107 omap24xxcam_reg_out(base, CAMDMA_CICR(dmach),
108 CAMDMA_CICR_MISALIGNED_ERR_IE
109 | CAMDMA_CICR_SECURE_ERR_IE
110 | CAMDMA_CICR_TRANS_ERR_IE
111 | CAMDMA_CICR_BLOCK_IE
112 | CAMDMA_CICR_DROP_IE);
113}
114
115static void omap24xxcam_dmahw_transfer_start(void __iomem *base, int dmach)
116{
117 omap24xxcam_reg_out(base, CAMDMA_CCR(dmach),
118 CAMDMA_CCR_SEL_SRC_DST_SYNC
119 | CAMDMA_CCR_BS
120 | CAMDMA_CCR_DST_AMODE_POST_INC
121 | CAMDMA_CCR_SRC_AMODE_POST_INC
122 | CAMDMA_CCR_ENABLE
123 | CAMDMA_CCR_FS
124 | CAMDMA_CCR_SYNCHRO_CAMERA);
125}
126
127static void omap24xxcam_dmahw_transfer_chain(void __iomem *base, int dmach,
128 int free_dmach)
129{
130 int prev_dmach, ch;
131
132 if (dmach == 0)
133 prev_dmach = NUM_CAMDMA_CHANNELS - 1;
134 else
135 prev_dmach = dmach - 1;
136 omap24xxcam_reg_out(base, CAMDMA_CLNK_CTRL(prev_dmach),
137 CAMDMA_CLNK_CTRL_ENABLE_LNK | dmach);
138 /* Did we chain the DMA transfer before the previous one
139 * finished?
140 */
141 ch = (dmach + free_dmach) % NUM_CAMDMA_CHANNELS;
142 while (!(omap24xxcam_reg_in(base, CAMDMA_CCR(ch))
143 & CAMDMA_CCR_ENABLE)) {
144 if (ch == dmach) {
145 /* The previous transfer has ended and this one
146 * hasn't started, so we must not have chained
147 * to the previous one in time. We'll have to
148 * start it now.
149 */
150 omap24xxcam_dmahw_transfer_start(base, dmach);
151 break;
152 } else
153 ch = (ch + 1) % NUM_CAMDMA_CHANNELS;
154 }
155}
156
157/* Abort all chained DMA transfers. After all transfers have been
158 * aborted and the DMA controller is idle, the completion routines for
159 * any aborted transfers will be called in sequence. The DMA
160 * controller may not be idle after this routine completes, because
161 * the completion routines might start new transfers.
162 */
163static void omap24xxcam_dmahw_abort_ch(void __iomem *base, int dmach)
164{
165 /* mask all interrupts from this channel */
166 omap24xxcam_reg_out(base, CAMDMA_CICR(dmach), 0);
167 /* unlink this channel */
168 omap24xxcam_reg_merge(base, CAMDMA_CLNK_CTRL(dmach), 0,
169 CAMDMA_CLNK_CTRL_ENABLE_LNK);
170 /* disable this channel */
171 omap24xxcam_reg_merge(base, CAMDMA_CCR(dmach), 0, CAMDMA_CCR_ENABLE);
172}
173
174static void omap24xxcam_dmahw_init(void __iomem *base)
175{
176 omap24xxcam_reg_out(base, CAMDMA_OCP_SYSCONFIG,
177 CAMDMA_OCP_SYSCONFIG_MIDLEMODE_FSTANDBY
178 | CAMDMA_OCP_SYSCONFIG_SIDLEMODE_FIDLE
179 | CAMDMA_OCP_SYSCONFIG_AUTOIDLE);
180
181 omap24xxcam_reg_merge(base, CAMDMA_GCR, 0x10,
182 CAMDMA_GCR_MAX_CHANNEL_FIFO_DEPTH);
183
184 omap24xxcam_reg_out(base, CAMDMA_IRQENABLE_L0, 0xf);
185}
186
187/*
188 *
189 * Individual DMA channel handling.
190 *
191 */
192
193/* Start a DMA transfer from the camera to memory.
194 * Returns zero if the transfer was successfully started, or non-zero if all
195 * DMA channels are already in use or starting is currently inhibited.
196 */
197static int omap24xxcam_dma_start(struct omap24xxcam_dma *dma, dma_addr_t start,
198 u32 len, dma_callback_t callback, void *arg)
199{
200 unsigned long flags;
201 int dmach;
202
203 spin_lock_irqsave(&dma->lock, flags);
204
205 if (!dma->free_dmach || atomic_read(&dma->dma_stop)) {
206 spin_unlock_irqrestore(&dma->lock, flags);
207 return -EBUSY;
208 }
209
210 dmach = dma->next_dmach;
211
212 dma->ch_state[dmach].callback = callback;
213 dma->ch_state[dmach].arg = arg;
214
215 omap24xxcam_dmahw_transfer_setup(dma->base, dmach, start, len);
216
217 /* We're ready to start the DMA transfer. */
218
219 if (dma->free_dmach < NUM_CAMDMA_CHANNELS) {
220 /* A transfer is already in progress, so try to chain to it. */
221 omap24xxcam_dmahw_transfer_chain(dma->base, dmach,
222 dma->free_dmach);
223 } else {
224 /* No transfer is in progress, so we'll just start this one
225 * now.
226 */
227 omap24xxcam_dmahw_transfer_start(dma->base, dmach);
228 }
229
230 dma->next_dmach = (dma->next_dmach + 1) % NUM_CAMDMA_CHANNELS;
231 dma->free_dmach--;
232
233 spin_unlock_irqrestore(&dma->lock, flags);
234
235 return 0;
236}
237
238/* Abort all chained DMA transfers. After all transfers have been
239 * aborted and the DMA controller is idle, the completion routines for
240 * any aborted transfers will be called in sequence. The DMA
241 * controller may not be idle after this routine completes, because
242 * the completion routines might start new transfers.
243 */
244static void omap24xxcam_dma_abort(struct omap24xxcam_dma *dma, u32 csr)
245{
246 unsigned long flags;
247 int dmach, i, free_dmach;
248 dma_callback_t callback;
249 void *arg;
250
251 spin_lock_irqsave(&dma->lock, flags);
252
253 /* stop any DMA transfers in progress */
254 dmach = (dma->next_dmach + dma->free_dmach) % NUM_CAMDMA_CHANNELS;
255 for (i = 0; i < NUM_CAMDMA_CHANNELS; i++) {
256 omap24xxcam_dmahw_abort_ch(dma->base, dmach);
257 dmach = (dmach + 1) % NUM_CAMDMA_CHANNELS;
258 }
259
260 /* We have to be careful here because the callback routine
261 * might start a new DMA transfer, and we only want to abort
262 * transfers that were started before this routine was called.
263 */
264 free_dmach = dma->free_dmach;
265 while ((dma->free_dmach < NUM_CAMDMA_CHANNELS) &&
266 (free_dmach < NUM_CAMDMA_CHANNELS)) {
267 dmach = (dma->next_dmach + dma->free_dmach)
268 % NUM_CAMDMA_CHANNELS;
269 callback = dma->ch_state[dmach].callback;
270 arg = dma->ch_state[dmach].arg;
271 dma->free_dmach++;
272 free_dmach++;
273 if (callback) {
274 /* leave interrupts disabled during callback */
275 spin_unlock(&dma->lock);
276 (*callback) (dma, csr, arg);
277 spin_lock(&dma->lock);
278 }
279 }
280
281 spin_unlock_irqrestore(&dma->lock, flags);
282}
283
284/* Abort all chained DMA transfers. After all transfers have been
285 * aborted and the DMA controller is idle, the completion routines for
286 * any aborted transfers will be called in sequence. If the completion
287 * routines attempt to start a new DMA transfer it will fail, so the
288 * DMA controller will be idle after this routine completes.
289 */
290static void omap24xxcam_dma_stop(struct omap24xxcam_dma *dma, u32 csr)
291{
292 atomic_inc(&dma->dma_stop);
293 omap24xxcam_dma_abort(dma, csr);
294 atomic_dec(&dma->dma_stop);
295}
296
297/* Camera DMA interrupt service routine. */
298void omap24xxcam_dma_isr(struct omap24xxcam_dma *dma)
299{
300 int dmach;
301 dma_callback_t callback;
302 void *arg;
303 u32 csr;
304 const u32 csr_error = CAMDMA_CSR_MISALIGNED_ERR
305 | CAMDMA_CSR_SUPERVISOR_ERR | CAMDMA_CSR_SECURE_ERR
306 | CAMDMA_CSR_TRANS_ERR | CAMDMA_CSR_DROP;
307
308 spin_lock(&dma->lock);
309
310 if (dma->free_dmach == NUM_CAMDMA_CHANNELS) {
311 /* A camera DMA interrupt occurred while all channels
312 * are idle, so we'll acknowledge the interrupt in the
313 * IRQSTATUS register and exit.
314 */
315 omap24xxcam_dmahw_ack_all(dma->base);
316 spin_unlock(&dma->lock);
317 return;
318 }
319
320 while (dma->free_dmach < NUM_CAMDMA_CHANNELS) {
321 dmach = (dma->next_dmach + dma->free_dmach)
322 % NUM_CAMDMA_CHANNELS;
323 if (omap24xxcam_dmahw_running(dma->base, dmach)) {
324 /* This buffer hasn't finished yet, so we're done. */
325 break;
326 }
327 csr = omap24xxcam_dmahw_ack_ch(dma->base, dmach);
328 if (csr & csr_error) {
329 /* A DMA error occurred, so stop all DMA
330 * transfers in progress.
331 */
332 spin_unlock(&dma->lock);
333 omap24xxcam_dma_stop(dma, csr);
334 return;
335 } else {
336 callback = dma->ch_state[dmach].callback;
337 arg = dma->ch_state[dmach].arg;
338 dma->free_dmach++;
339 if (callback) {
340 spin_unlock(&dma->lock);
341 (*callback) (dma, csr, arg);
342 spin_lock(&dma->lock);
343 }
344 }
345 }
346
347 spin_unlock(&dma->lock);
348
349 omap24xxcam_sgdma_process(
350 container_of(dma, struct omap24xxcam_sgdma, dma));
351}
352
353void omap24xxcam_dma_hwinit(struct omap24xxcam_dma *dma)
354{
355 unsigned long flags;
356
357 spin_lock_irqsave(&dma->lock, flags);
358
359 omap24xxcam_dmahw_init(dma->base);
360
361 spin_unlock_irqrestore(&dma->lock, flags);
362}
363
364static void omap24xxcam_dma_init(struct omap24xxcam_dma *dma,
365 void __iomem *base)
366{
367 int ch;
368
369 /* group all channels on DMA IRQ0 and unmask irq */
370 spin_lock_init(&dma->lock);
371 dma->base = base;
372 dma->free_dmach = NUM_CAMDMA_CHANNELS;
373 dma->next_dmach = 0;
374 for (ch = 0; ch < NUM_CAMDMA_CHANNELS; ch++) {
375 dma->ch_state[ch].callback = NULL;
376 dma->ch_state[ch].arg = NULL;
377 }
378}
379
380/*
381 *
382 * Scatter-gather DMA.
383 *
384 * High-level DMA construct for transferring whole picture frames to
385 * memory that is discontinuous.
386 *
387 */
388
389/* DMA completion routine for the scatter-gather DMA fragments. */
390static void omap24xxcam_sgdma_callback(struct omap24xxcam_dma *dma, u32 csr,
391 void *arg)
392{
393 struct omap24xxcam_sgdma *sgdma =
394 container_of(dma, struct omap24xxcam_sgdma, dma);
395 int sgslot = (int)arg;
396 struct sgdma_state *sg_state;
397 const u32 csr_error = CAMDMA_CSR_MISALIGNED_ERR
398 | CAMDMA_CSR_SUPERVISOR_ERR | CAMDMA_CSR_SECURE_ERR
399 | CAMDMA_CSR_TRANS_ERR | CAMDMA_CSR_DROP;
400
401 spin_lock(&sgdma->lock);
402
403 /* We got an interrupt, we can remove the timer */
404 del_timer(&sgdma->reset_timer);
405
406 sg_state = sgdma->sg_state + sgslot;
407 if (!sg_state->queued_sglist) {
408 spin_unlock(&sgdma->lock);
409 printk(KERN_ERR "%s: sgdma completed when none queued!\n",
410 __func__);
411 return;
412 }
413
414 sg_state->csr |= csr;
415 if (!--sg_state->queued_sglist) {
416 /* Queue for this sglist is empty, so check to see if we're
417 * done.
418 */
419 if ((sg_state->next_sglist == sg_state->sglen)
420 || (sg_state->csr & csr_error)) {
421 sgdma_callback_t callback = sg_state->callback;
422 void *arg = sg_state->arg;
423 u32 sg_csr = sg_state->csr;
424 /* All done with this sglist */
425 sgdma->free_sgdma++;
426 if (callback) {
427 spin_unlock(&sgdma->lock);
428 (*callback) (sgdma, sg_csr, arg);
429 return;
430 }
431 }
432 }
433
434 spin_unlock(&sgdma->lock);
435}
436
437/* Start queued scatter-gather DMA transfers. */
438void omap24xxcam_sgdma_process(struct omap24xxcam_sgdma *sgdma)
439{
440 unsigned long flags;
441 int queued_sgdma, sgslot;
442 struct sgdma_state *sg_state;
443 const u32 csr_error = CAMDMA_CSR_MISALIGNED_ERR
444 | CAMDMA_CSR_SUPERVISOR_ERR | CAMDMA_CSR_SECURE_ERR
445 | CAMDMA_CSR_TRANS_ERR | CAMDMA_CSR_DROP;
446
447 spin_lock_irqsave(&sgdma->lock, flags);
448
449 queued_sgdma = NUM_SG_DMA - sgdma->free_sgdma;
450 sgslot = (sgdma->next_sgdma + sgdma->free_sgdma) % NUM_SG_DMA;
451 while (queued_sgdma > 0) {
452 sg_state = sgdma->sg_state + sgslot;
453 while ((sg_state->next_sglist < sg_state->sglen) &&
454 !(sg_state->csr & csr_error)) {
455 const struct scatterlist *sglist;
456 unsigned int len;
457
458 sglist = sg_state->sglist + sg_state->next_sglist;
459 /* try to start the next DMA transfer */
460 if (sg_state->next_sglist + 1 == sg_state->sglen) {
461 /*
462 * On the last sg, we handle the case where
463 * cam->img.pix.sizeimage % PAGE_ALIGN != 0
464 */
465 len = sg_state->len - sg_state->bytes_read;
466 } else {
467 len = sg_dma_len(sglist);
468 }
469
470 if (omap24xxcam_dma_start(&sgdma->dma,
471 sg_dma_address(sglist),
472 len,
473 omap24xxcam_sgdma_callback,
474 (void *)sgslot)) {
475 /* DMA start failed */
476 spin_unlock_irqrestore(&sgdma->lock, flags);
477 return;
478 } else {
479 unsigned long expires;
480 /* DMA start was successful */
481 sg_state->next_sglist++;
482 sg_state->bytes_read += len;
483 sg_state->queued_sglist++;
484
485 /* We start the reset timer */
486 expires = jiffies + HZ;
487 mod_timer(&sgdma->reset_timer, expires);
488 }
489 }
490 queued_sgdma--;
491 sgslot = (sgslot + 1) % NUM_SG_DMA;
492 }
493
494 spin_unlock_irqrestore(&sgdma->lock, flags);
495}
496
497/*
498 * Queue a scatter-gather DMA transfer from the camera to memory.
499 * Returns zero if the transfer was successfully queued, or non-zero
500 * if all of the scatter-gather slots are already in use.
501 */
502int omap24xxcam_sgdma_queue(struct omap24xxcam_sgdma *sgdma,
503 const struct scatterlist *sglist, int sglen,
504 int len, sgdma_callback_t callback, void *arg)
505{
506 unsigned long flags;
507 struct sgdma_state *sg_state;
508
509 if ((sglen < 0) || ((sglen > 0) && !sglist))
510 return -EINVAL;
511
512 spin_lock_irqsave(&sgdma->lock, flags);
513
514 if (!sgdma->free_sgdma) {
515 spin_unlock_irqrestore(&sgdma->lock, flags);
516 return -EBUSY;
517 }
518
519 sg_state = sgdma->sg_state + sgdma->next_sgdma;
520
521 sg_state->sglist = sglist;
522 sg_state->sglen = sglen;
523 sg_state->next_sglist = 0;
524 sg_state->bytes_read = 0;
525 sg_state->len = len;
526 sg_state->queued_sglist = 0;
527 sg_state->csr = 0;
528 sg_state->callback = callback;
529 sg_state->arg = arg;
530
531 sgdma->next_sgdma = (sgdma->next_sgdma + 1) % NUM_SG_DMA;
532 sgdma->free_sgdma--;
533
534 spin_unlock_irqrestore(&sgdma->lock, flags);
535
536 omap24xxcam_sgdma_process(sgdma);
537
538 return 0;
539}
540
541/* Sync scatter-gather DMA by aborting any DMA transfers currently in progress.
542 * Any queued scatter-gather DMA transactions that have not yet been started
543 * will remain queued. The DMA controller will be idle after this routine
544 * completes. When the scatter-gather queue is restarted, the next
545 * scatter-gather DMA transfer will begin at the start of a new transaction.
546 */
547void omap24xxcam_sgdma_sync(struct omap24xxcam_sgdma *sgdma)
548{
549 unsigned long flags;
550 int sgslot;
551 struct sgdma_state *sg_state;
552 u32 csr = CAMDMA_CSR_TRANS_ERR;
553
554 /* stop any DMA transfers in progress */
555 omap24xxcam_dma_stop(&sgdma->dma, csr);
556
557 spin_lock_irqsave(&sgdma->lock, flags);
558
559 if (sgdma->free_sgdma < NUM_SG_DMA) {
560 sgslot = (sgdma->next_sgdma + sgdma->free_sgdma) % NUM_SG_DMA;
561 sg_state = sgdma->sg_state + sgslot;
562 if (sg_state->next_sglist != 0) {
563 /* This DMA transfer was in progress, so abort it. */
564 sgdma_callback_t callback = sg_state->callback;
565 void *arg = sg_state->arg;
566 sgdma->free_sgdma++;
567 if (callback) {
568 /* leave interrupts masked */
569 spin_unlock(&sgdma->lock);
570 (*callback) (sgdma, csr, arg);
571 spin_lock(&sgdma->lock);
572 }
573 }
574 }
575
576 spin_unlock_irqrestore(&sgdma->lock, flags);
577}
578
579void omap24xxcam_sgdma_init(struct omap24xxcam_sgdma *sgdma,
580 void __iomem *base,
581 void (*reset_callback)(unsigned long data),
582 unsigned long reset_callback_data)
583{
584 int sg;
585
586 spin_lock_init(&sgdma->lock);
587 sgdma->free_sgdma = NUM_SG_DMA;
588 sgdma->next_sgdma = 0;
589 for (sg = 0; sg < NUM_SG_DMA; sg++) {
590 sgdma->sg_state[sg].sglen = 0;
591 sgdma->sg_state[sg].next_sglist = 0;
592 sgdma->sg_state[sg].bytes_read = 0;
593 sgdma->sg_state[sg].queued_sglist = 0;
594 sgdma->sg_state[sg].csr = 0;
595 sgdma->sg_state[sg].callback = NULL;
596 sgdma->sg_state[sg].arg = NULL;
597 }
598
599 omap24xxcam_dma_init(&sgdma->dma, base);
600 setup_timer(&sgdma->reset_timer, reset_callback, reset_callback_data);
601}
diff --git a/drivers/media/video/omap24xxcam.c b/drivers/media/video/omap24xxcam.c
deleted file mode 100644
index e5015b0d5508..000000000000
--- a/drivers/media/video/omap24xxcam.c
+++ /dev/null
@@ -1,1881 +0,0 @@
1/*
2 * drivers/media/video/omap24xxcam.c
3 *
4 * OMAP 2 camera block driver.
5 *
6 * Copyright (C) 2004 MontaVista Software, Inc.
7 * Copyright (C) 2004 Texas Instruments.
8 * Copyright (C) 2007-2008 Nokia Corporation.
9 *
10 * Contact: Sakari Ailus <sakari.ailus@nokia.com>
11 *
12 * Based on code from Andy Lowe <source@mvista.com>
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * version 2 as published by the Free Software Foundation.
17 *
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 * General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
26 * 02110-1301 USA
27 */
28
29#include <linux/delay.h>
30#include <linux/kernel.h>
31#include <linux/interrupt.h>
32#include <linux/videodev2.h>
33#include <linux/pci.h> /* needed for videobufs */
34#include <linux/platform_device.h>
35#include <linux/clk.h>
36#include <linux/io.h>
37#include <linux/slab.h>
38#include <linux/sched.h>
39#include <linux/module.h>
40
41#include <media/v4l2-common.h>
42#include <media/v4l2-ioctl.h>
43
44#include "omap24xxcam.h"
45
46#define OMAP24XXCAM_VERSION "0.0.1"
47
48#define RESET_TIMEOUT_NS 10000
49
50static void omap24xxcam_reset(struct omap24xxcam_device *cam);
51static int omap24xxcam_sensor_if_enable(struct omap24xxcam_device *cam);
52static void omap24xxcam_device_unregister(struct v4l2_int_device *s);
53static int omap24xxcam_remove(struct platform_device *pdev);
54
55/* module parameters */
56static int video_nr = -1; /* video device minor (-1 ==> auto assign) */
57/*
58 * Maximum amount of memory to use for capture buffers.
59 * Default is 4800KB, enough to double-buffer SXGA.
60 */
61static int capture_mem = 1280 * 960 * 2 * 2;
62
63static struct v4l2_int_device omap24xxcam;
64
65/*
66 *
67 * Clocks.
68 *
69 */
70
71static void omap24xxcam_clock_put(struct omap24xxcam_device *cam)
72{
73 if (cam->ick != NULL && !IS_ERR(cam->ick))
74 clk_put(cam->ick);
75 if (cam->fck != NULL && !IS_ERR(cam->fck))
76 clk_put(cam->fck);
77
78 cam->ick = cam->fck = NULL;
79}
80
81static int omap24xxcam_clock_get(struct omap24xxcam_device *cam)
82{
83 int rval = 0;
84
85 cam->fck = clk_get(cam->dev, "fck");
86 if (IS_ERR(cam->fck)) {
87 dev_err(cam->dev, "can't get camera fck");
88 rval = PTR_ERR(cam->fck);
89 omap24xxcam_clock_put(cam);
90 return rval;
91 }
92
93 cam->ick = clk_get(cam->dev, "ick");
94 if (IS_ERR(cam->ick)) {
95 dev_err(cam->dev, "can't get camera ick");
96 rval = PTR_ERR(cam->ick);
97 omap24xxcam_clock_put(cam);
98 }
99
100 return rval;
101}
102
103static void omap24xxcam_clock_on(struct omap24xxcam_device *cam)
104{
105 clk_enable(cam->fck);
106 clk_enable(cam->ick);
107}
108
109static void omap24xxcam_clock_off(struct omap24xxcam_device *cam)
110{
111 clk_disable(cam->fck);
112 clk_disable(cam->ick);
113}
114
115/*
116 *
117 * Camera core
118 *
119 */
120
121/*
122 * Set xclk.
123 *
124 * To disable xclk, use value zero.
125 */
126static void omap24xxcam_core_xclk_set(const struct omap24xxcam_device *cam,
127 u32 xclk)
128{
129 if (xclk) {
130 u32 divisor = CAM_MCLK / xclk;
131
132 if (divisor == 1)
133 omap24xxcam_reg_out(cam->mmio_base + CC_REG_OFFSET,
134 CC_CTRL_XCLK,
135 CC_CTRL_XCLK_DIV_BYPASS);
136 else
137 omap24xxcam_reg_out(cam->mmio_base + CC_REG_OFFSET,
138 CC_CTRL_XCLK, divisor);
139 } else
140 omap24xxcam_reg_out(cam->mmio_base + CC_REG_OFFSET,
141 CC_CTRL_XCLK, CC_CTRL_XCLK_DIV_STABLE_LOW);
142}
143
144static void omap24xxcam_core_hwinit(const struct omap24xxcam_device *cam)
145{
146 /*
147 * Setting the camera core AUTOIDLE bit causes problems with frame
148 * synchronization, so we will clear the AUTOIDLE bit instead.
149 */
150 omap24xxcam_reg_out(cam->mmio_base + CC_REG_OFFSET, CC_SYSCONFIG,
151 CC_SYSCONFIG_AUTOIDLE);
152
153 /* program the camera interface DMA packet size */
154 omap24xxcam_reg_out(cam->mmio_base + CC_REG_OFFSET, CC_CTRL_DMA,
155 CC_CTRL_DMA_EN | (DMA_THRESHOLD / 4 - 1));
156
157 /* enable camera core error interrupts */
158 omap24xxcam_reg_out(cam->mmio_base + CC_REG_OFFSET, CC_IRQENABLE,
159 CC_IRQENABLE_FW_ERR_IRQ
160 | CC_IRQENABLE_FSC_ERR_IRQ
161 | CC_IRQENABLE_SSC_ERR_IRQ
162 | CC_IRQENABLE_FIFO_OF_IRQ);
163}
164
165/*
166 * Enable the camera core.
167 *
168 * Data transfer to the camera DMA starts from next starting frame.
169 */
170static void omap24xxcam_core_enable(const struct omap24xxcam_device *cam)
171{
172
173 omap24xxcam_reg_out(cam->mmio_base + CC_REG_OFFSET, CC_CTRL,
174 cam->cc_ctrl);
175}
176
177/*
178 * Disable camera core.
179 *
180 * The data transfer will be stopped immediately (CC_CTRL_CC_RST). The
181 * core internal state machines will be reset. Use
182 * CC_CTRL_CC_FRAME_TRIG instead if you want to transfer the current
183 * frame completely.
184 */
185static void omap24xxcam_core_disable(const struct omap24xxcam_device *cam)
186{
187 omap24xxcam_reg_out(cam->mmio_base + CC_REG_OFFSET, CC_CTRL,
188 CC_CTRL_CC_RST);
189}
190
191/* Interrupt service routine for camera core interrupts. */
192static void omap24xxcam_core_isr(struct omap24xxcam_device *cam)
193{
194 u32 cc_irqstatus;
195 const u32 cc_irqstatus_err =
196 CC_IRQSTATUS_FW_ERR_IRQ
197 | CC_IRQSTATUS_FSC_ERR_IRQ
198 | CC_IRQSTATUS_SSC_ERR_IRQ
199 | CC_IRQSTATUS_FIFO_UF_IRQ
200 | CC_IRQSTATUS_FIFO_OF_IRQ;
201
202 cc_irqstatus = omap24xxcam_reg_in(cam->mmio_base + CC_REG_OFFSET,
203 CC_IRQSTATUS);
204 omap24xxcam_reg_out(cam->mmio_base + CC_REG_OFFSET, CC_IRQSTATUS,
205 cc_irqstatus);
206
207 if (cc_irqstatus & cc_irqstatus_err
208 && !atomic_read(&cam->in_reset)) {
209 dev_dbg(cam->dev, "resetting camera, cc_irqstatus 0x%x\n",
210 cc_irqstatus);
211 omap24xxcam_reset(cam);
212 }
213}
214
215/*
216 *
217 * videobuf_buffer handling.
218 *
219 * Memory for mmapped videobuf_buffers is not allocated
220 * conventionally, but by several kmalloc allocations and then
221 * creating the scatterlist on our own. User-space buffers are handled
222 * normally.
223 *
224 */
225
226/*
227 * Free the memory-mapped buffer memory allocated for a
228 * videobuf_buffer and the associated scatterlist.
229 */
230static void omap24xxcam_vbq_free_mmap_buffer(struct videobuf_buffer *vb)
231{
232 struct videobuf_dmabuf *dma = videobuf_to_dma(vb);
233 size_t alloc_size;
234 struct page *page;
235 int i;
236
237 if (dma->sglist == NULL)
238 return;
239
240 i = dma->sglen;
241 while (i) {
242 i--;
243 alloc_size = sg_dma_len(&dma->sglist[i]);
244 page = sg_page(&dma->sglist[i]);
245 do {
246 ClearPageReserved(page++);
247 } while (alloc_size -= PAGE_SIZE);
248 __free_pages(sg_page(&dma->sglist[i]),
249 get_order(sg_dma_len(&dma->sglist[i])));
250 }
251
252 kfree(dma->sglist);
253 dma->sglist = NULL;
254}
255
256/* Release all memory related to the videobuf_queue. */
257static void omap24xxcam_vbq_free_mmap_buffers(struct videobuf_queue *vbq)
258{
259 int i;
260
261 mutex_lock(&vbq->vb_lock);
262
263 for (i = 0; i < VIDEO_MAX_FRAME; i++) {
264 if (NULL == vbq->bufs[i])
265 continue;
266 if (V4L2_MEMORY_MMAP != vbq->bufs[i]->memory)
267 continue;
268 vbq->ops->buf_release(vbq, vbq->bufs[i]);
269 omap24xxcam_vbq_free_mmap_buffer(vbq->bufs[i]);
270 kfree(vbq->bufs[i]);
271 vbq->bufs[i] = NULL;
272 }
273
274 mutex_unlock(&vbq->vb_lock);
275
276 videobuf_mmap_free(vbq);
277}
278
279/*
280 * Allocate physically as contiguous as possible buffer for video
281 * frame and allocate and build DMA scatter-gather list for it.
282 */
283static int omap24xxcam_vbq_alloc_mmap_buffer(struct videobuf_buffer *vb)
284{
285 unsigned int order;
286 size_t alloc_size, size = vb->bsize; /* vb->bsize is page aligned */
287 struct page *page;
288 int max_pages, err = 0, i = 0;
289 struct videobuf_dmabuf *dma = videobuf_to_dma(vb);
290
291 /*
292 * allocate maximum size scatter-gather list. Note this is
293 * overhead. We may not use as many entries as we allocate
294 */
295 max_pages = vb->bsize >> PAGE_SHIFT;
296 dma->sglist = kcalloc(max_pages, sizeof(*dma->sglist), GFP_KERNEL);
297 if (dma->sglist == NULL) {
298 err = -ENOMEM;
299 goto out;
300 }
301
302 while (size) {
303 order = get_order(size);
304 /*
305 * do not over-allocate even if we would get larger
306 * contiguous chunk that way
307 */
308 if ((PAGE_SIZE << order) > size)
309 order--;
310
311 /* try to allocate as many contiguous pages as possible */
312 page = alloc_pages(GFP_KERNEL, order);
313 /* if allocation fails, try to allocate smaller amount */
314 while (page == NULL) {
315 order--;
316 page = alloc_pages(GFP_KERNEL, order);
317 if (page == NULL && !order) {
318 err = -ENOMEM;
319 goto out;
320 }
321 }
322 size -= (PAGE_SIZE << order);
323
324 /* append allocated chunk of pages into scatter-gather list */
325 sg_set_page(&dma->sglist[i], page, PAGE_SIZE << order, 0);
326 dma->sglen++;
327 i++;
328
329 alloc_size = (PAGE_SIZE << order);
330
331 /* clear pages before giving them to user space */
332 memset(page_address(page), 0, alloc_size);
333
334 /* mark allocated pages reserved */
335 do {
336 SetPageReserved(page++);
337 } while (alloc_size -= PAGE_SIZE);
338 }
339 /*
340 * REVISIT: not fully correct to assign nr_pages == sglen but
341 * video-buf is passing nr_pages for e.g. unmap_sg calls
342 */
343 dma->nr_pages = dma->sglen;
344 dma->direction = PCI_DMA_FROMDEVICE;
345
346 return 0;
347
348out:
349 omap24xxcam_vbq_free_mmap_buffer(vb);
350 return err;
351}
352
353static int omap24xxcam_vbq_alloc_mmap_buffers(struct videobuf_queue *vbq,
354 unsigned int count)
355{
356 int i, err = 0;
357 struct omap24xxcam_fh *fh =
358 container_of(vbq, struct omap24xxcam_fh, vbq);
359
360 mutex_lock(&vbq->vb_lock);
361
362 for (i = 0; i < count; i++) {
363 err = omap24xxcam_vbq_alloc_mmap_buffer(vbq->bufs[i]);
364 if (err)
365 goto out;
366 dev_dbg(fh->cam->dev, "sglen is %d for buffer %d\n",
367 videobuf_to_dma(vbq->bufs[i])->sglen, i);
368 }
369
370 mutex_unlock(&vbq->vb_lock);
371
372 return 0;
373out:
374 while (i) {
375 i--;
376 omap24xxcam_vbq_free_mmap_buffer(vbq->bufs[i]);
377 }
378
379 mutex_unlock(&vbq->vb_lock);
380
381 return err;
382}
383
384/*
385 * This routine is called from interrupt context when a scatter-gather DMA
386 * transfer of a videobuf_buffer completes.
387 */
388static void omap24xxcam_vbq_complete(struct omap24xxcam_sgdma *sgdma,
389 u32 csr, void *arg)
390{
391 struct omap24xxcam_device *cam =
392 container_of(sgdma, struct omap24xxcam_device, sgdma);
393 struct omap24xxcam_fh *fh = cam->streaming->private_data;
394 struct videobuf_buffer *vb = (struct videobuf_buffer *)arg;
395 const u32 csr_error = CAMDMA_CSR_MISALIGNED_ERR
396 | CAMDMA_CSR_SUPERVISOR_ERR | CAMDMA_CSR_SECURE_ERR
397 | CAMDMA_CSR_TRANS_ERR | CAMDMA_CSR_DROP;
398 unsigned long flags;
399
400 spin_lock_irqsave(&cam->core_enable_disable_lock, flags);
401 if (--cam->sgdma_in_queue == 0)
402 omap24xxcam_core_disable(cam);
403 spin_unlock_irqrestore(&cam->core_enable_disable_lock, flags);
404
405 do_gettimeofday(&vb->ts);
406 vb->field_count = atomic_add_return(2, &fh->field_count);
407 if (csr & csr_error) {
408 vb->state = VIDEOBUF_ERROR;
409 if (!atomic_read(&fh->cam->in_reset)) {
410 dev_dbg(cam->dev, "resetting camera, csr 0x%x\n", csr);
411 omap24xxcam_reset(cam);
412 }
413 } else
414 vb->state = VIDEOBUF_DONE;
415 wake_up(&vb->done);
416}
417
418static void omap24xxcam_vbq_release(struct videobuf_queue *vbq,
419 struct videobuf_buffer *vb)
420{
421 struct videobuf_dmabuf *dma = videobuf_to_dma(vb);
422
423 /* wait for buffer, especially to get out of the sgdma queue */
424 videobuf_waiton(vbq, vb, 0, 0);
425 if (vb->memory == V4L2_MEMORY_MMAP) {
426 dma_unmap_sg(vbq->dev, dma->sglist, dma->sglen,
427 dma->direction);
428 dma->direction = DMA_NONE;
429 } else {
430 videobuf_dma_unmap(vbq->dev, videobuf_to_dma(vb));
431 videobuf_dma_free(videobuf_to_dma(vb));
432 }
433
434 vb->state = VIDEOBUF_NEEDS_INIT;
435}
436
437/*
438 * Limit the number of available kernel image capture buffers based on the
439 * number requested, the currently selected image size, and the maximum
440 * amount of memory permitted for kernel capture buffers.
441 */
442static int omap24xxcam_vbq_setup(struct videobuf_queue *vbq, unsigned int *cnt,
443 unsigned int *size)
444{
445 struct omap24xxcam_fh *fh = vbq->priv_data;
446
447 if (*cnt <= 0)
448 *cnt = VIDEO_MAX_FRAME; /* supply a default number of buffers */
449
450 if (*cnt > VIDEO_MAX_FRAME)
451 *cnt = VIDEO_MAX_FRAME;
452
453 *size = fh->pix.sizeimage;
454
455 /* accessing fh->cam->capture_mem is ok, it's constant */
456 if (*size * *cnt > fh->cam->capture_mem)
457 *cnt = fh->cam->capture_mem / *size;
458
459 return 0;
460}
461
462static int omap24xxcam_dma_iolock(struct videobuf_queue *vbq,
463 struct videobuf_dmabuf *dma)
464{
465 int err = 0;
466
467 dma->direction = PCI_DMA_FROMDEVICE;
468 if (!dma_map_sg(vbq->dev, dma->sglist, dma->sglen, dma->direction)) {
469 kfree(dma->sglist);
470 dma->sglist = NULL;
471 dma->sglen = 0;
472 err = -EIO;
473 }
474
475 return err;
476}
477
478static int omap24xxcam_vbq_prepare(struct videobuf_queue *vbq,
479 struct videobuf_buffer *vb,
480 enum v4l2_field field)
481{
482 struct omap24xxcam_fh *fh = vbq->priv_data;
483 int err = 0;
484
485 /*
486 * Accessing pix here is okay since it's constant while
487 * streaming is on (and we only get called then).
488 */
489 if (vb->baddr) {
490 /* This is a userspace buffer. */
491 if (fh->pix.sizeimage > vb->bsize) {
492 /* The buffer isn't big enough. */
493 err = -EINVAL;
494 } else
495 vb->size = fh->pix.sizeimage;
496 } else {
497 if (vb->state != VIDEOBUF_NEEDS_INIT) {
498 /*
499 * We have a kernel bounce buffer that has
500 * already been allocated.
501 */
502 if (fh->pix.sizeimage > vb->size) {
503 /*
504 * The image size has been changed to
505 * a larger size since this buffer was
506 * allocated, so we need to free and
507 * reallocate it.
508 */
509 omap24xxcam_vbq_release(vbq, vb);
510 vb->size = fh->pix.sizeimage;
511 }
512 } else {
513 /* We need to allocate a new kernel bounce buffer. */
514 vb->size = fh->pix.sizeimage;
515 }
516 }
517
518 if (err)
519 return err;
520
521 vb->width = fh->pix.width;
522 vb->height = fh->pix.height;
523 vb->field = field;
524
525 if (vb->state == VIDEOBUF_NEEDS_INIT) {
526 if (vb->memory == V4L2_MEMORY_MMAP)
527 /*
528 * we have built the scatter-gather list by ourself so
529 * do the scatter-gather mapping as well
530 */
531 err = omap24xxcam_dma_iolock(vbq, videobuf_to_dma(vb));
532 else
533 err = videobuf_iolock(vbq, vb, NULL);
534 }
535
536 if (!err)
537 vb->state = VIDEOBUF_PREPARED;
538 else
539 omap24xxcam_vbq_release(vbq, vb);
540
541 return err;
542}
543
544static void omap24xxcam_vbq_queue(struct videobuf_queue *vbq,
545 struct videobuf_buffer *vb)
546{
547 struct omap24xxcam_fh *fh = vbq->priv_data;
548 struct omap24xxcam_device *cam = fh->cam;
549 enum videobuf_state state = vb->state;
550 unsigned long flags;
551 int err;
552
553 /*
554 * FIXME: We're marking the buffer active since we have no
555 * pretty way of marking it active exactly when the
556 * scatter-gather transfer starts.
557 */
558 vb->state = VIDEOBUF_ACTIVE;
559
560 err = omap24xxcam_sgdma_queue(&fh->cam->sgdma,
561 videobuf_to_dma(vb)->sglist,
562 videobuf_to_dma(vb)->sglen, vb->size,
563 omap24xxcam_vbq_complete, vb);
564
565 if (!err) {
566 spin_lock_irqsave(&cam->core_enable_disable_lock, flags);
567 if (++cam->sgdma_in_queue == 1
568 && !atomic_read(&cam->in_reset))
569 omap24xxcam_core_enable(cam);
570 spin_unlock_irqrestore(&cam->core_enable_disable_lock, flags);
571 } else {
572 /*
573 * Oops. We're not supposed to get any errors here.
574 * The only way we could get an error is if we ran out
575 * of scatter-gather DMA slots, but we are supposed to
576 * have at least as many scatter-gather DMA slots as
577 * video buffers so that can't happen.
578 */
579 dev_err(cam->dev, "failed to queue a video buffer for dma!\n");
580 dev_err(cam->dev, "likely a bug in the driver!\n");
581 vb->state = state;
582 }
583}
584
585static struct videobuf_queue_ops omap24xxcam_vbq_ops = {
586 .buf_setup = omap24xxcam_vbq_setup,
587 .buf_prepare = omap24xxcam_vbq_prepare,
588 .buf_queue = omap24xxcam_vbq_queue,
589 .buf_release = omap24xxcam_vbq_release,
590};
591
592/*
593 *
594 * OMAP main camera system
595 *
596 */
597
598/*
599 * Reset camera block to power-on state.
600 */
601static void omap24xxcam_poweron_reset(struct omap24xxcam_device *cam)
602{
603 int max_loop = RESET_TIMEOUT_NS;
604
605 /* Reset whole camera subsystem */
606 omap24xxcam_reg_out(cam->mmio_base,
607 CAM_SYSCONFIG,
608 CAM_SYSCONFIG_SOFTRESET);
609
610 /* Wait till it's finished */
611 while (!(omap24xxcam_reg_in(cam->mmio_base, CAM_SYSSTATUS)
612 & CAM_SYSSTATUS_RESETDONE)
613 && --max_loop) {
614 ndelay(1);
615 }
616
617 if (!(omap24xxcam_reg_in(cam->mmio_base, CAM_SYSSTATUS)
618 & CAM_SYSSTATUS_RESETDONE))
619 dev_err(cam->dev, "camera soft reset timeout\n");
620}
621
622/*
623 * (Re)initialise the camera block.
624 */
625static void omap24xxcam_hwinit(struct omap24xxcam_device *cam)
626{
627 omap24xxcam_poweron_reset(cam);
628
629 /* set the camera subsystem autoidle bit */
630 omap24xxcam_reg_out(cam->mmio_base, CAM_SYSCONFIG,
631 CAM_SYSCONFIG_AUTOIDLE);
632
633 /* set the camera MMU autoidle bit */
634 omap24xxcam_reg_out(cam->mmio_base,
635 CAMMMU_REG_OFFSET + CAMMMU_SYSCONFIG,
636 CAMMMU_SYSCONFIG_AUTOIDLE);
637
638 omap24xxcam_core_hwinit(cam);
639
640 omap24xxcam_dma_hwinit(&cam->sgdma.dma);
641}
642
643/*
644 * Callback for dma transfer stalling.
645 */
646static void omap24xxcam_stalled_dma_reset(unsigned long data)
647{
648 struct omap24xxcam_device *cam = (struct omap24xxcam_device *)data;
649
650 if (!atomic_read(&cam->in_reset)) {
651 dev_dbg(cam->dev, "dma stalled, resetting camera\n");
652 omap24xxcam_reset(cam);
653 }
654}
655
656/*
657 * Stop capture. Mark we're doing a reset, stop DMA transfers and
658 * core. (No new scatter-gather transfers will be queued whilst
659 * in_reset is non-zero.)
660 *
661 * If omap24xxcam_capture_stop is called from several places at
662 * once, only the first call will have an effect. Similarly, the last
663 * call omap24xxcam_streaming_cont will have effect.
664 *
665 * Serialisation is ensured by using cam->core_enable_disable_lock.
666 */
667static void omap24xxcam_capture_stop(struct omap24xxcam_device *cam)
668{
669 unsigned long flags;
670
671 spin_lock_irqsave(&cam->core_enable_disable_lock, flags);
672
673 if (atomic_inc_return(&cam->in_reset) != 1) {
674 spin_unlock_irqrestore(&cam->core_enable_disable_lock, flags);
675 return;
676 }
677
678 omap24xxcam_core_disable(cam);
679
680 spin_unlock_irqrestore(&cam->core_enable_disable_lock, flags);
681
682 omap24xxcam_sgdma_sync(&cam->sgdma);
683}
684
685/*
686 * Reset and continue streaming.
687 *
688 * Note: Resetting the camera FIFO via the CC_RST bit in the CC_CTRL
689 * register is supposed to be sufficient to recover from a camera
690 * interface error, but it doesn't seem to be enough. If we only do
691 * that then subsequent image captures are out of sync by either one
692 * or two times DMA_THRESHOLD bytes. Resetting and re-initializing the
693 * entire camera subsystem prevents the problem with frame
694 * synchronization.
695 */
696static void omap24xxcam_capture_cont(struct omap24xxcam_device *cam)
697{
698 unsigned long flags;
699
700 spin_lock_irqsave(&cam->core_enable_disable_lock, flags);
701
702 if (atomic_read(&cam->in_reset) != 1)
703 goto out;
704
705 omap24xxcam_hwinit(cam);
706
707 omap24xxcam_sensor_if_enable(cam);
708
709 omap24xxcam_sgdma_process(&cam->sgdma);
710
711 if (cam->sgdma_in_queue)
712 omap24xxcam_core_enable(cam);
713
714out:
715 atomic_dec(&cam->in_reset);
716 spin_unlock_irqrestore(&cam->core_enable_disable_lock, flags);
717}
718
719static ssize_t
720omap24xxcam_streaming_show(struct device *dev, struct device_attribute *attr,
721 char *buf)
722{
723 struct omap24xxcam_device *cam = dev_get_drvdata(dev);
724
725 return sprintf(buf, "%s\n", cam->streaming ? "active" : "inactive");
726}
727static DEVICE_ATTR(streaming, S_IRUGO, omap24xxcam_streaming_show, NULL);
728
729/*
730 * Stop capture and restart it. I.e. reset the camera during use.
731 */
732static void omap24xxcam_reset(struct omap24xxcam_device *cam)
733{
734 omap24xxcam_capture_stop(cam);
735 omap24xxcam_capture_cont(cam);
736}
737
738/*
739 * The main interrupt handler.
740 */
741static irqreturn_t omap24xxcam_isr(int irq, void *arg)
742{
743 struct omap24xxcam_device *cam = (struct omap24xxcam_device *)arg;
744 u32 irqstatus;
745 unsigned int irqhandled = 0;
746
747 irqstatus = omap24xxcam_reg_in(cam->mmio_base, CAM_IRQSTATUS);
748
749 if (irqstatus &
750 (CAM_IRQSTATUS_DMA_IRQ2 | CAM_IRQSTATUS_DMA_IRQ1
751 | CAM_IRQSTATUS_DMA_IRQ0)) {
752 omap24xxcam_dma_isr(&cam->sgdma.dma);
753 irqhandled = 1;
754 }
755 if (irqstatus & CAM_IRQSTATUS_CC_IRQ) {
756 omap24xxcam_core_isr(cam);
757 irqhandled = 1;
758 }
759 if (irqstatus & CAM_IRQSTATUS_MMU_IRQ)
760 dev_err(cam->dev, "unhandled camera MMU interrupt!\n");
761
762 return IRQ_RETVAL(irqhandled);
763}
764
765/*
766 *
767 * Sensor handling.
768 *
769 */
770
771/*
772 * Enable the external sensor interface. Try to negotiate interface
773 * parameters with the sensor and start using the new ones. The calls
774 * to sensor_if_enable and sensor_if_disable need not to be balanced.
775 */
776static int omap24xxcam_sensor_if_enable(struct omap24xxcam_device *cam)
777{
778 int rval;
779 struct v4l2_ifparm p;
780
781 rval = vidioc_int_g_ifparm(cam->sdev, &p);
782 if (rval) {
783 dev_err(cam->dev, "vidioc_int_g_ifparm failed with %d\n", rval);
784 return rval;
785 }
786
787 cam->if_type = p.if_type;
788
789 cam->cc_ctrl = CC_CTRL_CC_EN;
790
791 switch (p.if_type) {
792 case V4L2_IF_TYPE_BT656:
793 if (p.u.bt656.frame_start_on_rising_vs)
794 cam->cc_ctrl |= CC_CTRL_NOBT_SYNCHRO;
795 if (p.u.bt656.bt_sync_correct)
796 cam->cc_ctrl |= CC_CTRL_BT_CORRECT;
797 if (p.u.bt656.swap)
798 cam->cc_ctrl |= CC_CTRL_PAR_ORDERCAM;
799 if (p.u.bt656.latch_clk_inv)
800 cam->cc_ctrl |= CC_CTRL_PAR_CLK_POL;
801 if (p.u.bt656.nobt_hs_inv)
802 cam->cc_ctrl |= CC_CTRL_NOBT_HS_POL;
803 if (p.u.bt656.nobt_vs_inv)
804 cam->cc_ctrl |= CC_CTRL_NOBT_VS_POL;
805
806 switch (p.u.bt656.mode) {
807 case V4L2_IF_TYPE_BT656_MODE_NOBT_8BIT:
808 cam->cc_ctrl |= CC_CTRL_PAR_MODE_NOBT8;
809 break;
810 case V4L2_IF_TYPE_BT656_MODE_NOBT_10BIT:
811 cam->cc_ctrl |= CC_CTRL_PAR_MODE_NOBT10;
812 break;
813 case V4L2_IF_TYPE_BT656_MODE_NOBT_12BIT:
814 cam->cc_ctrl |= CC_CTRL_PAR_MODE_NOBT12;
815 break;
816 case V4L2_IF_TYPE_BT656_MODE_BT_8BIT:
817 cam->cc_ctrl |= CC_CTRL_PAR_MODE_BT8;
818 break;
819 case V4L2_IF_TYPE_BT656_MODE_BT_10BIT:
820 cam->cc_ctrl |= CC_CTRL_PAR_MODE_BT10;
821 break;
822 default:
823 dev_err(cam->dev,
824 "bt656 interface mode %d not supported\n",
825 p.u.bt656.mode);
826 return -EINVAL;
827 }
828 /*
829 * The clock rate that the sensor wants has changed.
830 * We have to adjust the xclk from OMAP 2 side to
831 * match the sensor's wish as closely as possible.
832 */
833 if (p.u.bt656.clock_curr != cam->if_u.bt656.xclk) {
834 u32 xclk = p.u.bt656.clock_curr;
835 u32 divisor;
836
837 if (xclk == 0)
838 return -EINVAL;
839
840 if (xclk > CAM_MCLK)
841 xclk = CAM_MCLK;
842
843 divisor = CAM_MCLK / xclk;
844 if (divisor * xclk < CAM_MCLK)
845 divisor++;
846 if (CAM_MCLK / divisor < p.u.bt656.clock_min
847 && divisor > 1)
848 divisor--;
849 if (divisor > 30)
850 divisor = 30;
851
852 xclk = CAM_MCLK / divisor;
853
854 if (xclk < p.u.bt656.clock_min
855 || xclk > p.u.bt656.clock_max)
856 return -EINVAL;
857
858 cam->if_u.bt656.xclk = xclk;
859 }
860 omap24xxcam_core_xclk_set(cam, cam->if_u.bt656.xclk);
861 break;
862 default:
863 /* FIXME: how about other interfaces? */
864 dev_err(cam->dev, "interface type %d not supported\n",
865 p.if_type);
866 return -EINVAL;
867 }
868
869 return 0;
870}
871
872static void omap24xxcam_sensor_if_disable(const struct omap24xxcam_device *cam)
873{
874 switch (cam->if_type) {
875 case V4L2_IF_TYPE_BT656:
876 omap24xxcam_core_xclk_set(cam, 0);
877 break;
878 }
879}
880
881/*
882 * Initialise the sensor hardware.
883 */
884static int omap24xxcam_sensor_init(struct omap24xxcam_device *cam)
885{
886 int err = 0;
887 struct v4l2_int_device *sdev = cam->sdev;
888
889 omap24xxcam_clock_on(cam);
890 err = omap24xxcam_sensor_if_enable(cam);
891 if (err) {
892 dev_err(cam->dev, "sensor interface could not be enabled at "
893 "initialisation, %d\n", err);
894 cam->sdev = NULL;
895 goto out;
896 }
897
898 /* power up sensor during sensor initialization */
899 vidioc_int_s_power(sdev, 1);
900
901 err = vidioc_int_dev_init(sdev);
902 if (err) {
903 dev_err(cam->dev, "cannot initialize sensor, error %d\n", err);
904 /* Sensor init failed --- it's nonexistent to us! */
905 cam->sdev = NULL;
906 goto out;
907 }
908
909 dev_info(cam->dev, "sensor is %s\n", sdev->name);
910
911out:
912 omap24xxcam_sensor_if_disable(cam);
913 omap24xxcam_clock_off(cam);
914
915 vidioc_int_s_power(sdev, 0);
916
917 return err;
918}
919
920static void omap24xxcam_sensor_exit(struct omap24xxcam_device *cam)
921{
922 if (cam->sdev)
923 vidioc_int_dev_exit(cam->sdev);
924}
925
926static void omap24xxcam_sensor_disable(struct omap24xxcam_device *cam)
927{
928 omap24xxcam_sensor_if_disable(cam);
929 omap24xxcam_clock_off(cam);
930 vidioc_int_s_power(cam->sdev, 0);
931}
932
933/*
934 * Power-up and configure camera sensor. It's ready for capturing now.
935 */
936static int omap24xxcam_sensor_enable(struct omap24xxcam_device *cam)
937{
938 int rval;
939
940 omap24xxcam_clock_on(cam);
941
942 omap24xxcam_sensor_if_enable(cam);
943
944 rval = vidioc_int_s_power(cam->sdev, 1);
945 if (rval)
946 goto out;
947
948 rval = vidioc_int_init(cam->sdev);
949 if (rval)
950 goto out;
951
952 return 0;
953
954out:
955 omap24xxcam_sensor_disable(cam);
956
957 return rval;
958}
959
960static void omap24xxcam_sensor_reset_work(struct work_struct *work)
961{
962 struct omap24xxcam_device *cam =
963 container_of(work, struct omap24xxcam_device,
964 sensor_reset_work);
965
966 if (atomic_read(&cam->reset_disable))
967 return;
968
969 omap24xxcam_capture_stop(cam);
970
971 if (vidioc_int_reset(cam->sdev) == 0) {
972 vidioc_int_init(cam->sdev);
973 } else {
974 /* Can't reset it by vidioc_int_reset. */
975 omap24xxcam_sensor_disable(cam);
976 omap24xxcam_sensor_enable(cam);
977 }
978
979 omap24xxcam_capture_cont(cam);
980}
981
982/*
983 *
984 * IOCTL interface.
985 *
986 */
987
988static int vidioc_querycap(struct file *file, void *fh,
989 struct v4l2_capability *cap)
990{
991 struct omap24xxcam_fh *ofh = fh;
992 struct omap24xxcam_device *cam = ofh->cam;
993
994 strlcpy(cap->driver, CAM_NAME, sizeof(cap->driver));
995 strlcpy(cap->card, cam->vfd->name, sizeof(cap->card));
996 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
997
998 return 0;
999}
1000
1001static int vidioc_enum_fmt_vid_cap(struct file *file, void *fh,
1002 struct v4l2_fmtdesc *f)
1003{
1004 struct omap24xxcam_fh *ofh = fh;
1005 struct omap24xxcam_device *cam = ofh->cam;
1006 int rval;
1007
1008 rval = vidioc_int_enum_fmt_cap(cam->sdev, f);
1009
1010 return rval;
1011}
1012
1013static int vidioc_g_fmt_vid_cap(struct file *file, void *fh,
1014 struct v4l2_format *f)
1015{
1016 struct omap24xxcam_fh *ofh = fh;
1017 struct omap24xxcam_device *cam = ofh->cam;
1018 int rval;
1019
1020 mutex_lock(&cam->mutex);
1021 rval = vidioc_int_g_fmt_cap(cam->sdev, f);
1022 mutex_unlock(&cam->mutex);
1023
1024 return rval;
1025}
1026
1027static int vidioc_s_fmt_vid_cap(struct file *file, void *fh,
1028 struct v4l2_format *f)
1029{
1030 struct omap24xxcam_fh *ofh = fh;
1031 struct omap24xxcam_device *cam = ofh->cam;
1032 int rval;
1033
1034 mutex_lock(&cam->mutex);
1035 if (cam->streaming) {
1036 rval = -EBUSY;
1037 goto out;
1038 }
1039
1040 rval = vidioc_int_s_fmt_cap(cam->sdev, f);
1041
1042out:
1043 mutex_unlock(&cam->mutex);
1044
1045 if (!rval) {
1046 mutex_lock(&ofh->vbq.vb_lock);
1047 ofh->pix = f->fmt.pix;
1048 mutex_unlock(&ofh->vbq.vb_lock);
1049 }
1050
1051 memset(f, 0, sizeof(*f));
1052 vidioc_g_fmt_vid_cap(file, fh, f);
1053
1054 return rval;
1055}
1056
1057static int vidioc_try_fmt_vid_cap(struct file *file, void *fh,
1058 struct v4l2_format *f)
1059{
1060 struct omap24xxcam_fh *ofh = fh;
1061 struct omap24xxcam_device *cam = ofh->cam;
1062 int rval;
1063
1064 mutex_lock(&cam->mutex);
1065 rval = vidioc_int_try_fmt_cap(cam->sdev, f);
1066 mutex_unlock(&cam->mutex);
1067
1068 return rval;
1069}
1070
1071static int vidioc_reqbufs(struct file *file, void *fh,
1072 struct v4l2_requestbuffers *b)
1073{
1074 struct omap24xxcam_fh *ofh = fh;
1075 struct omap24xxcam_device *cam = ofh->cam;
1076 int rval;
1077
1078 mutex_lock(&cam->mutex);
1079 if (cam->streaming) {
1080 mutex_unlock(&cam->mutex);
1081 return -EBUSY;
1082 }
1083
1084 omap24xxcam_vbq_free_mmap_buffers(&ofh->vbq);
1085 mutex_unlock(&cam->mutex);
1086
1087 rval = videobuf_reqbufs(&ofh->vbq, b);
1088
1089 /*
1090 * Either videobuf_reqbufs failed or the buffers are not
1091 * memory-mapped (which would need special attention).
1092 */
1093 if (rval < 0 || b->memory != V4L2_MEMORY_MMAP)
1094 goto out;
1095
1096 rval = omap24xxcam_vbq_alloc_mmap_buffers(&ofh->vbq, rval);
1097 if (rval)
1098 omap24xxcam_vbq_free_mmap_buffers(&ofh->vbq);
1099
1100out:
1101 return rval;
1102}
1103
1104static int vidioc_querybuf(struct file *file, void *fh,
1105 struct v4l2_buffer *b)
1106{
1107 struct omap24xxcam_fh *ofh = fh;
1108
1109 return videobuf_querybuf(&ofh->vbq, b);
1110}
1111
1112static int vidioc_qbuf(struct file *file, void *fh, struct v4l2_buffer *b)
1113{
1114 struct omap24xxcam_fh *ofh = fh;
1115
1116 return videobuf_qbuf(&ofh->vbq, b);
1117}
1118
1119static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b)
1120{
1121 struct omap24xxcam_fh *ofh = fh;
1122 struct omap24xxcam_device *cam = ofh->cam;
1123 struct videobuf_buffer *vb;
1124 int rval;
1125
1126videobuf_dqbuf_again:
1127 rval = videobuf_dqbuf(&ofh->vbq, b, file->f_flags & O_NONBLOCK);
1128 if (rval)
1129 goto out;
1130
1131 vb = ofh->vbq.bufs[b->index];
1132
1133 mutex_lock(&cam->mutex);
1134 /* _needs_reset returns -EIO if reset is required. */
1135 rval = vidioc_int_g_needs_reset(cam->sdev, (void *)vb->baddr);
1136 mutex_unlock(&cam->mutex);
1137 if (rval == -EIO)
1138 schedule_work(&cam->sensor_reset_work);
1139 else
1140 rval = 0;
1141
1142out:
1143 /*
1144 * This is a hack. We don't want to show -EIO to the user
1145 * space. Requeue the buffer and try again if we're not doing
1146 * this in non-blocking mode.
1147 */
1148 if (rval == -EIO) {
1149 videobuf_qbuf(&ofh->vbq, b);
1150 if (!(file->f_flags & O_NONBLOCK))
1151 goto videobuf_dqbuf_again;
1152 /*
1153 * We don't have a videobuf_buffer now --- maybe next
1154 * time...
1155 */
1156 rval = -EAGAIN;
1157 }
1158
1159 return rval;
1160}
1161
1162static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
1163{
1164 struct omap24xxcam_fh *ofh = fh;
1165 struct omap24xxcam_device *cam = ofh->cam;
1166 int rval;
1167
1168 mutex_lock(&cam->mutex);
1169 if (cam->streaming) {
1170 rval = -EBUSY;
1171 goto out;
1172 }
1173
1174 rval = omap24xxcam_sensor_if_enable(cam);
1175 if (rval) {
1176 dev_dbg(cam->dev, "vidioc_int_g_ifparm failed\n");
1177 goto out;
1178 }
1179
1180 rval = videobuf_streamon(&ofh->vbq);
1181 if (!rval) {
1182 cam->streaming = file;
1183 sysfs_notify(&cam->dev->kobj, NULL, "streaming");
1184 }
1185
1186out:
1187 mutex_unlock(&cam->mutex);
1188
1189 return rval;
1190}
1191
1192static int vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i)
1193{
1194 struct omap24xxcam_fh *ofh = fh;
1195 struct omap24xxcam_device *cam = ofh->cam;
1196 struct videobuf_queue *q = &ofh->vbq;
1197 int rval;
1198
1199 atomic_inc(&cam->reset_disable);
1200
1201 flush_work_sync(&cam->sensor_reset_work);
1202
1203 rval = videobuf_streamoff(q);
1204 if (!rval) {
1205 mutex_lock(&cam->mutex);
1206 cam->streaming = NULL;
1207 mutex_unlock(&cam->mutex);
1208 sysfs_notify(&cam->dev->kobj, NULL, "streaming");
1209 }
1210
1211 atomic_dec(&cam->reset_disable);
1212
1213 return rval;
1214}
1215
1216static int vidioc_enum_input(struct file *file, void *fh,
1217 struct v4l2_input *inp)
1218{
1219 if (inp->index > 0)
1220 return -EINVAL;
1221
1222 strlcpy(inp->name, "camera", sizeof(inp->name));
1223 inp->type = V4L2_INPUT_TYPE_CAMERA;
1224
1225 return 0;
1226}
1227
1228static int vidioc_g_input(struct file *file, void *fh, unsigned int *i)
1229{
1230 *i = 0;
1231
1232 return 0;
1233}
1234
1235static int vidioc_s_input(struct file *file, void *fh, unsigned int i)
1236{
1237 if (i > 0)
1238 return -EINVAL;
1239
1240 return 0;
1241}
1242
1243static int vidioc_queryctrl(struct file *file, void *fh,
1244 struct v4l2_queryctrl *a)
1245{
1246 struct omap24xxcam_fh *ofh = fh;
1247 struct omap24xxcam_device *cam = ofh->cam;
1248 int rval;
1249
1250 rval = vidioc_int_queryctrl(cam->sdev, a);
1251
1252 return rval;
1253}
1254
1255static int vidioc_g_ctrl(struct file *file, void *fh,
1256 struct v4l2_control *a)
1257{
1258 struct omap24xxcam_fh *ofh = fh;
1259 struct omap24xxcam_device *cam = ofh->cam;
1260 int rval;
1261
1262 mutex_lock(&cam->mutex);
1263 rval = vidioc_int_g_ctrl(cam->sdev, a);
1264 mutex_unlock(&cam->mutex);
1265
1266 return rval;
1267}
1268
1269static int vidioc_s_ctrl(struct file *file, void *fh,
1270 struct v4l2_control *a)
1271{
1272 struct omap24xxcam_fh *ofh = fh;
1273 struct omap24xxcam_device *cam = ofh->cam;
1274 int rval;
1275
1276 mutex_lock(&cam->mutex);
1277 rval = vidioc_int_s_ctrl(cam->sdev, a);
1278 mutex_unlock(&cam->mutex);
1279
1280 return rval;
1281}
1282
1283static int vidioc_g_parm(struct file *file, void *fh,
1284 struct v4l2_streamparm *a) {
1285 struct omap24xxcam_fh *ofh = fh;
1286 struct omap24xxcam_device *cam = ofh->cam;
1287 int rval;
1288
1289 mutex_lock(&cam->mutex);
1290 rval = vidioc_int_g_parm(cam->sdev, a);
1291 mutex_unlock(&cam->mutex);
1292
1293 return rval;
1294}
1295
1296static int vidioc_s_parm(struct file *file, void *fh,
1297 struct v4l2_streamparm *a)
1298{
1299 struct omap24xxcam_fh *ofh = fh;
1300 struct omap24xxcam_device *cam = ofh->cam;
1301 struct v4l2_streamparm old_streamparm;
1302 int rval;
1303
1304 mutex_lock(&cam->mutex);
1305 if (cam->streaming) {
1306 rval = -EBUSY;
1307 goto out;
1308 }
1309
1310 old_streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1311 rval = vidioc_int_g_parm(cam->sdev, &old_streamparm);
1312 if (rval)
1313 goto out;
1314
1315 rval = vidioc_int_s_parm(cam->sdev, a);
1316 if (rval)
1317 goto out;
1318
1319 rval = omap24xxcam_sensor_if_enable(cam);
1320 /*
1321 * Revert to old streaming parameters if enabling sensor
1322 * interface with the new ones failed.
1323 */
1324 if (rval)
1325 vidioc_int_s_parm(cam->sdev, &old_streamparm);
1326
1327out:
1328 mutex_unlock(&cam->mutex);
1329
1330 return rval;
1331}
1332
1333/*
1334 *
1335 * File operations.
1336 *
1337 */
1338
1339static unsigned int omap24xxcam_poll(struct file *file,
1340 struct poll_table_struct *wait)
1341{
1342 struct omap24xxcam_fh *fh = file->private_data;
1343 struct omap24xxcam_device *cam = fh->cam;
1344 struct videobuf_buffer *vb;
1345
1346 mutex_lock(&cam->mutex);
1347 if (cam->streaming != file) {
1348 mutex_unlock(&cam->mutex);
1349 return POLLERR;
1350 }
1351 mutex_unlock(&cam->mutex);
1352
1353 mutex_lock(&fh->vbq.vb_lock);
1354 if (list_empty(&fh->vbq.stream)) {
1355 mutex_unlock(&fh->vbq.vb_lock);
1356 return POLLERR;
1357 }
1358 vb = list_entry(fh->vbq.stream.next, struct videobuf_buffer, stream);
1359 mutex_unlock(&fh->vbq.vb_lock);
1360
1361 poll_wait(file, &vb->done, wait);
1362
1363 if (vb->state == VIDEOBUF_DONE || vb->state == VIDEOBUF_ERROR)
1364 return POLLIN | POLLRDNORM;
1365
1366 return 0;
1367}
1368
1369static int omap24xxcam_mmap_buffers(struct file *file,
1370 struct vm_area_struct *vma)
1371{
1372 struct omap24xxcam_fh *fh = file->private_data;
1373 struct omap24xxcam_device *cam = fh->cam;
1374 struct videobuf_queue *vbq = &fh->vbq;
1375 unsigned int first, last, size, i, j;
1376 int err = 0;
1377
1378 mutex_lock(&cam->mutex);
1379 if (cam->streaming) {
1380 mutex_unlock(&cam->mutex);
1381 return -EBUSY;
1382 }
1383 mutex_unlock(&cam->mutex);
1384 mutex_lock(&vbq->vb_lock);
1385
1386 /* look for first buffer to map */
1387 for (first = 0; first < VIDEO_MAX_FRAME; first++) {
1388 if (NULL == vbq->bufs[first])
1389 continue;
1390 if (V4L2_MEMORY_MMAP != vbq->bufs[first]->memory)
1391 continue;
1392 if (vbq->bufs[first]->boff == (vma->vm_pgoff << PAGE_SHIFT))
1393 break;
1394 }
1395
1396 /* look for last buffer to map */
1397 for (size = 0, last = first; last < VIDEO_MAX_FRAME; last++) {
1398 if (NULL == vbq->bufs[last])
1399 continue;
1400 if (V4L2_MEMORY_MMAP != vbq->bufs[last]->memory)
1401 continue;
1402 size += vbq->bufs[last]->bsize;
1403 if (size == (vma->vm_end - vma->vm_start))
1404 break;
1405 }
1406
1407 size = 0;
1408 for (i = first; i <= last && i < VIDEO_MAX_FRAME; i++) {
1409 struct videobuf_dmabuf *dma = videobuf_to_dma(vbq->bufs[i]);
1410
1411 for (j = 0; j < dma->sglen; j++) {
1412 err = remap_pfn_range(
1413 vma, vma->vm_start + size,
1414 page_to_pfn(sg_page(&dma->sglist[j])),
1415 sg_dma_len(&dma->sglist[j]), vma->vm_page_prot);
1416 if (err)
1417 goto out;
1418 size += sg_dma_len(&dma->sglist[j]);
1419 }
1420 }
1421
1422out:
1423 mutex_unlock(&vbq->vb_lock);
1424
1425 return err;
1426}
1427
1428static int omap24xxcam_mmap(struct file *file, struct vm_area_struct *vma)
1429{
1430 struct omap24xxcam_fh *fh = file->private_data;
1431 int rval;
1432
1433 /* let the video-buf mapper check arguments and set-up structures */
1434 rval = videobuf_mmap_mapper(&fh->vbq, vma);
1435 if (rval)
1436 return rval;
1437
1438 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
1439
1440 /* do mapping to our allocated buffers */
1441 rval = omap24xxcam_mmap_buffers(file, vma);
1442 /*
1443 * In case of error, free vma->vm_private_data allocated by
1444 * videobuf_mmap_mapper.
1445 */
1446 if (rval)
1447 kfree(vma->vm_private_data);
1448
1449 return rval;
1450}
1451
1452static int omap24xxcam_open(struct file *file)
1453{
1454 struct omap24xxcam_device *cam = omap24xxcam.priv;
1455 struct omap24xxcam_fh *fh;
1456 struct v4l2_format format;
1457
1458 if (!cam || !cam->vfd)
1459 return -ENODEV;
1460
1461 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
1462 if (fh == NULL)
1463 return -ENOMEM;
1464
1465 mutex_lock(&cam->mutex);
1466 if (cam->sdev == NULL || !try_module_get(cam->sdev->module)) {
1467 mutex_unlock(&cam->mutex);
1468 goto out_try_module_get;
1469 }
1470
1471 if (atomic_inc_return(&cam->users) == 1) {
1472 omap24xxcam_hwinit(cam);
1473 if (omap24xxcam_sensor_enable(cam)) {
1474 mutex_unlock(&cam->mutex);
1475 goto out_omap24xxcam_sensor_enable;
1476 }
1477 }
1478 mutex_unlock(&cam->mutex);
1479
1480 fh->cam = cam;
1481 mutex_lock(&cam->mutex);
1482 vidioc_int_g_fmt_cap(cam->sdev, &format);
1483 mutex_unlock(&cam->mutex);
1484 /* FIXME: how about fh->pix when there are more users? */
1485 fh->pix = format.fmt.pix;
1486
1487 file->private_data = fh;
1488
1489 spin_lock_init(&fh->vbq_lock);
1490
1491 videobuf_queue_sg_init(&fh->vbq, &omap24xxcam_vbq_ops, NULL,
1492 &fh->vbq_lock, V4L2_BUF_TYPE_VIDEO_CAPTURE,
1493 V4L2_FIELD_NONE,
1494 sizeof(struct videobuf_buffer), fh, NULL);
1495
1496 return 0;
1497
1498out_omap24xxcam_sensor_enable:
1499 omap24xxcam_poweron_reset(cam);
1500 module_put(cam->sdev->module);
1501
1502out_try_module_get:
1503 kfree(fh);
1504
1505 return -ENODEV;
1506}
1507
1508static int omap24xxcam_release(struct file *file)
1509{
1510 struct omap24xxcam_fh *fh = file->private_data;
1511 struct omap24xxcam_device *cam = fh->cam;
1512
1513 atomic_inc(&cam->reset_disable);
1514
1515 flush_work_sync(&cam->sensor_reset_work);
1516
1517 /* stop streaming capture */
1518 videobuf_streamoff(&fh->vbq);
1519
1520 mutex_lock(&cam->mutex);
1521 if (cam->streaming == file) {
1522 cam->streaming = NULL;
1523 mutex_unlock(&cam->mutex);
1524 sysfs_notify(&cam->dev->kobj, NULL, "streaming");
1525 } else {
1526 mutex_unlock(&cam->mutex);
1527 }
1528
1529 atomic_dec(&cam->reset_disable);
1530
1531 omap24xxcam_vbq_free_mmap_buffers(&fh->vbq);
1532
1533 /*
1534 * Make sure the reset work we might have scheduled is not
1535 * pending! It may be run *only* if we have users. (And it may
1536 * not be scheduled anymore since streaming is already
1537 * disabled.)
1538 */
1539 flush_work_sync(&cam->sensor_reset_work);
1540
1541 mutex_lock(&cam->mutex);
1542 if (atomic_dec_return(&cam->users) == 0) {
1543 omap24xxcam_sensor_disable(cam);
1544 omap24xxcam_poweron_reset(cam);
1545 }
1546 mutex_unlock(&cam->mutex);
1547
1548 file->private_data = NULL;
1549
1550 module_put(cam->sdev->module);
1551 kfree(fh);
1552
1553 return 0;
1554}
1555
1556static struct v4l2_file_operations omap24xxcam_fops = {
1557 .ioctl = video_ioctl2,
1558 .poll = omap24xxcam_poll,
1559 .mmap = omap24xxcam_mmap,
1560 .open = omap24xxcam_open,
1561 .release = omap24xxcam_release,
1562};
1563
1564/*
1565 *
1566 * Power management.
1567 *
1568 */
1569
1570#ifdef CONFIG_PM
1571static int omap24xxcam_suspend(struct platform_device *pdev, pm_message_t state)
1572{
1573 struct omap24xxcam_device *cam = platform_get_drvdata(pdev);
1574
1575 if (atomic_read(&cam->users) == 0)
1576 return 0;
1577
1578 if (!atomic_read(&cam->reset_disable))
1579 omap24xxcam_capture_stop(cam);
1580
1581 omap24xxcam_sensor_disable(cam);
1582 omap24xxcam_poweron_reset(cam);
1583
1584 return 0;
1585}
1586
1587static int omap24xxcam_resume(struct platform_device *pdev)
1588{
1589 struct omap24xxcam_device *cam = platform_get_drvdata(pdev);
1590
1591 if (atomic_read(&cam->users) == 0)
1592 return 0;
1593
1594 omap24xxcam_hwinit(cam);
1595 omap24xxcam_sensor_enable(cam);
1596
1597 if (!atomic_read(&cam->reset_disable))
1598 omap24xxcam_capture_cont(cam);
1599
1600 return 0;
1601}
1602#endif /* CONFIG_PM */
1603
1604static const struct v4l2_ioctl_ops omap24xxcam_ioctl_fops = {
1605 .vidioc_querycap = vidioc_querycap,
1606 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
1607 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
1608 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
1609 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
1610 .vidioc_reqbufs = vidioc_reqbufs,
1611 .vidioc_querybuf = vidioc_querybuf,
1612 .vidioc_qbuf = vidioc_qbuf,
1613 .vidioc_dqbuf = vidioc_dqbuf,
1614 .vidioc_streamon = vidioc_streamon,
1615 .vidioc_streamoff = vidioc_streamoff,
1616 .vidioc_enum_input = vidioc_enum_input,
1617 .vidioc_g_input = vidioc_g_input,
1618 .vidioc_s_input = vidioc_s_input,
1619 .vidioc_queryctrl = vidioc_queryctrl,
1620 .vidioc_g_ctrl = vidioc_g_ctrl,
1621 .vidioc_s_ctrl = vidioc_s_ctrl,
1622 .vidioc_g_parm = vidioc_g_parm,
1623 .vidioc_s_parm = vidioc_s_parm,
1624};
1625
1626/*
1627 *
1628 * Camera device (i.e. /dev/video).
1629 *
1630 */
1631
1632static int omap24xxcam_device_register(struct v4l2_int_device *s)
1633{
1634 struct omap24xxcam_device *cam = s->u.slave->master->priv;
1635 struct video_device *vfd;
1636 int rval;
1637
1638 /* We already have a slave. */
1639 if (cam->sdev)
1640 return -EBUSY;
1641
1642 cam->sdev = s;
1643
1644 if (device_create_file(cam->dev, &dev_attr_streaming) != 0) {
1645 dev_err(cam->dev, "could not register sysfs entry\n");
1646 rval = -EBUSY;
1647 goto err;
1648 }
1649
1650 /* initialize the video_device struct */
1651 vfd = cam->vfd = video_device_alloc();
1652 if (!vfd) {
1653 dev_err(cam->dev, "could not allocate video device struct\n");
1654 rval = -ENOMEM;
1655 goto err;
1656 }
1657 vfd->release = video_device_release;
1658
1659 vfd->parent = cam->dev;
1660
1661 strlcpy(vfd->name, CAM_NAME, sizeof(vfd->name));
1662 vfd->fops = &omap24xxcam_fops;
1663 vfd->ioctl_ops = &omap24xxcam_ioctl_fops;
1664
1665 omap24xxcam_hwinit(cam);
1666
1667 rval = omap24xxcam_sensor_init(cam);
1668 if (rval)
1669 goto err;
1670
1671 if (video_register_device(vfd, VFL_TYPE_GRABBER, video_nr) < 0) {
1672 dev_err(cam->dev, "could not register V4L device\n");
1673 rval = -EBUSY;
1674 goto err;
1675 }
1676
1677 omap24xxcam_poweron_reset(cam);
1678
1679 dev_info(cam->dev, "registered device %s\n",
1680 video_device_node_name(vfd));
1681
1682 return 0;
1683
1684err:
1685 omap24xxcam_device_unregister(s);
1686
1687 return rval;
1688}
1689
1690static void omap24xxcam_device_unregister(struct v4l2_int_device *s)
1691{
1692 struct omap24xxcam_device *cam = s->u.slave->master->priv;
1693
1694 omap24xxcam_sensor_exit(cam);
1695
1696 if (cam->vfd) {
1697 if (!video_is_registered(cam->vfd)) {
1698 /*
1699 * The device was never registered, so release the
1700 * video_device struct directly.
1701 */
1702 video_device_release(cam->vfd);
1703 } else {
1704 /*
1705 * The unregister function will release the
1706 * video_device struct as well as
1707 * unregistering it.
1708 */
1709 video_unregister_device(cam->vfd);
1710 }
1711 cam->vfd = NULL;
1712 }
1713
1714 device_remove_file(cam->dev, &dev_attr_streaming);
1715
1716 cam->sdev = NULL;
1717}
1718
1719static struct v4l2_int_master omap24xxcam_master = {
1720 .attach = omap24xxcam_device_register,
1721 .detach = omap24xxcam_device_unregister,
1722};
1723
1724static struct v4l2_int_device omap24xxcam = {
1725 .module = THIS_MODULE,
1726 .name = CAM_NAME,
1727 .type = v4l2_int_type_master,
1728 .u = {
1729 .master = &omap24xxcam_master
1730 },
1731};
1732
1733/*
1734 *
1735 * Driver initialisation and deinitialisation.
1736 *
1737 */
1738
1739static int __devinit omap24xxcam_probe(struct platform_device *pdev)
1740{
1741 struct omap24xxcam_device *cam;
1742 struct resource *mem;
1743 int irq;
1744
1745 cam = kzalloc(sizeof(*cam), GFP_KERNEL);
1746 if (!cam) {
1747 dev_err(&pdev->dev, "could not allocate memory\n");
1748 goto err;
1749 }
1750
1751 platform_set_drvdata(pdev, cam);
1752
1753 cam->dev = &pdev->dev;
1754
1755 /*
1756 * Impose a lower limit on the amount of memory allocated for
1757 * capture. We require at least enough memory to double-buffer
1758 * QVGA (300KB).
1759 */
1760 if (capture_mem < 320 * 240 * 2 * 2)
1761 capture_mem = 320 * 240 * 2 * 2;
1762 cam->capture_mem = capture_mem;
1763
1764 /* request the mem region for the camera registers */
1765 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1766 if (!mem) {
1767 dev_err(cam->dev, "no mem resource?\n");
1768 goto err;
1769 }
1770 if (!request_mem_region(mem->start, resource_size(mem), pdev->name)) {
1771 dev_err(cam->dev,
1772 "cannot reserve camera register I/O region\n");
1773 goto err;
1774 }
1775 cam->mmio_base_phys = mem->start;
1776 cam->mmio_size = resource_size(mem);
1777
1778 /* map the region */
1779 cam->mmio_base = ioremap_nocache(cam->mmio_base_phys, cam->mmio_size);
1780 if (!cam->mmio_base) {
1781 dev_err(cam->dev, "cannot map camera register I/O region\n");
1782 goto err;
1783 }
1784
1785 irq = platform_get_irq(pdev, 0);
1786 if (irq <= 0) {
1787 dev_err(cam->dev, "no irq for camera?\n");
1788 goto err;
1789 }
1790
1791 /* install the interrupt service routine */
1792 if (request_irq(irq, omap24xxcam_isr, 0, CAM_NAME, cam)) {
1793 dev_err(cam->dev,
1794 "could not install interrupt service routine\n");
1795 goto err;
1796 }
1797 cam->irq = irq;
1798
1799 if (omap24xxcam_clock_get(cam))
1800 goto err;
1801
1802 INIT_WORK(&cam->sensor_reset_work, omap24xxcam_sensor_reset_work);
1803
1804 mutex_init(&cam->mutex);
1805 spin_lock_init(&cam->core_enable_disable_lock);
1806
1807 omap24xxcam_sgdma_init(&cam->sgdma,
1808 cam->mmio_base + CAMDMA_REG_OFFSET,
1809 omap24xxcam_stalled_dma_reset,
1810 (unsigned long)cam);
1811
1812 omap24xxcam.priv = cam;
1813
1814 if (v4l2_int_device_register(&omap24xxcam))
1815 goto err;
1816
1817 return 0;
1818
1819err:
1820 omap24xxcam_remove(pdev);
1821 return -ENODEV;
1822}
1823
1824static int omap24xxcam_remove(struct platform_device *pdev)
1825{
1826 struct omap24xxcam_device *cam = platform_get_drvdata(pdev);
1827
1828 if (!cam)
1829 return 0;
1830
1831 if (omap24xxcam.priv != NULL)
1832 v4l2_int_device_unregister(&omap24xxcam);
1833 omap24xxcam.priv = NULL;
1834
1835 omap24xxcam_clock_put(cam);
1836
1837 if (cam->irq) {
1838 free_irq(cam->irq, cam);
1839 cam->irq = 0;
1840 }
1841
1842 if (cam->mmio_base) {
1843 iounmap((void *)cam->mmio_base);
1844 cam->mmio_base = 0;
1845 }
1846
1847 if (cam->mmio_base_phys) {
1848 release_mem_region(cam->mmio_base_phys, cam->mmio_size);
1849 cam->mmio_base_phys = 0;
1850 }
1851
1852 kfree(cam);
1853
1854 return 0;
1855}
1856
1857static struct platform_driver omap24xxcam_driver = {
1858 .probe = omap24xxcam_probe,
1859 .remove = omap24xxcam_remove,
1860#ifdef CONFIG_PM
1861 .suspend = omap24xxcam_suspend,
1862 .resume = omap24xxcam_resume,
1863#endif
1864 .driver = {
1865 .name = CAM_NAME,
1866 .owner = THIS_MODULE,
1867 },
1868};
1869
1870module_platform_driver(omap24xxcam_driver);
1871
1872MODULE_AUTHOR("Sakari Ailus <sakari.ailus@nokia.com>");
1873MODULE_DESCRIPTION("OMAP24xx Video for Linux camera driver");
1874MODULE_LICENSE("GPL");
1875MODULE_VERSION(OMAP24XXCAM_VERSION);
1876module_param(video_nr, int, 0);
1877MODULE_PARM_DESC(video_nr,
1878 "Minor number for video device (-1 ==> auto assign)");
1879module_param(capture_mem, int, 0);
1880MODULE_PARM_DESC(capture_mem, "Maximum amount of memory for capture "
1881 "buffers (default 4800kiB)");
diff --git a/drivers/media/video/omap24xxcam.h b/drivers/media/video/omap24xxcam.h
deleted file mode 100644
index d59727afe894..000000000000
--- a/drivers/media/video/omap24xxcam.h
+++ /dev/null
@@ -1,593 +0,0 @@
1/*
2 * drivers/media/video/omap24xxcam.h
3 *
4 * Copyright (C) 2004 MontaVista Software, Inc.
5 * Copyright (C) 2004 Texas Instruments.
6 * Copyright (C) 2007 Nokia Corporation.
7 *
8 * Contact: Sakari Ailus <sakari.ailus@nokia.com>
9 *
10 * Based on code from Andy Lowe <source@mvista.com>.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * version 2 as published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 */
26
27#ifndef OMAP24XXCAM_H
28#define OMAP24XXCAM_H
29
30#include <media/videobuf-dma-sg.h>
31#include <media/v4l2-int-device.h>
32
33/*
34 *
35 * General driver related definitions.
36 *
37 */
38
39#define CAM_NAME "omap24xxcam"
40
41#define CAM_MCLK 96000000
42
43/* number of bytes transferred per DMA request */
44#define DMA_THRESHOLD 32
45
46/*
47 * NUM_CAMDMA_CHANNELS is the number of logical channels provided by
48 * the camera DMA controller.
49 */
50#define NUM_CAMDMA_CHANNELS 4
51
52/*
53 * NUM_SG_DMA is the number of scatter-gather DMA transfers that can
54 * be queued. (We don't have any overlay sglists now.)
55 */
56#define NUM_SG_DMA (VIDEO_MAX_FRAME)
57
58/*
59 *
60 * Register definitions.
61 *
62 */
63
64/* subsystem register block offsets */
65#define CC_REG_OFFSET 0x00000400
66#define CAMDMA_REG_OFFSET 0x00000800
67#define CAMMMU_REG_OFFSET 0x00000C00
68
69/* define camera subsystem register offsets */
70#define CAM_REVISION 0x000
71#define CAM_SYSCONFIG 0x010
72#define CAM_SYSSTATUS 0x014
73#define CAM_IRQSTATUS 0x018
74#define CAM_GPO 0x040
75#define CAM_GPI 0x050
76
77/* define camera core register offsets */
78#define CC_REVISION 0x000
79#define CC_SYSCONFIG 0x010
80#define CC_SYSSTATUS 0x014
81#define CC_IRQSTATUS 0x018
82#define CC_IRQENABLE 0x01C
83#define CC_CTRL 0x040
84#define CC_CTRL_DMA 0x044
85#define CC_CTRL_XCLK 0x048
86#define CC_FIFODATA 0x04C
87#define CC_TEST 0x050
88#define CC_GENPAR 0x054
89#define CC_CCPFSCR 0x058
90#define CC_CCPFECR 0x05C
91#define CC_CCPLSCR 0x060
92#define CC_CCPLECR 0x064
93#define CC_CCPDFR 0x068
94
95/* define camera dma register offsets */
96#define CAMDMA_REVISION 0x000
97#define CAMDMA_IRQSTATUS_L0 0x008
98#define CAMDMA_IRQSTATUS_L1 0x00C
99#define CAMDMA_IRQSTATUS_L2 0x010
100#define CAMDMA_IRQSTATUS_L3 0x014
101#define CAMDMA_IRQENABLE_L0 0x018
102#define CAMDMA_IRQENABLE_L1 0x01C
103#define CAMDMA_IRQENABLE_L2 0x020
104#define CAMDMA_IRQENABLE_L3 0x024
105#define CAMDMA_SYSSTATUS 0x028
106#define CAMDMA_OCP_SYSCONFIG 0x02C
107#define CAMDMA_CAPS_0 0x064
108#define CAMDMA_CAPS_2 0x06C
109#define CAMDMA_CAPS_3 0x070
110#define CAMDMA_CAPS_4 0x074
111#define CAMDMA_GCR 0x078
112#define CAMDMA_CCR(n) (0x080 + (n)*0x60)
113#define CAMDMA_CLNK_CTRL(n) (0x084 + (n)*0x60)
114#define CAMDMA_CICR(n) (0x088 + (n)*0x60)
115#define CAMDMA_CSR(n) (0x08C + (n)*0x60)
116#define CAMDMA_CSDP(n) (0x090 + (n)*0x60)
117#define CAMDMA_CEN(n) (0x094 + (n)*0x60)
118#define CAMDMA_CFN(n) (0x098 + (n)*0x60)
119#define CAMDMA_CSSA(n) (0x09C + (n)*0x60)
120#define CAMDMA_CDSA(n) (0x0A0 + (n)*0x60)
121#define CAMDMA_CSEI(n) (0x0A4 + (n)*0x60)
122#define CAMDMA_CSFI(n) (0x0A8 + (n)*0x60)
123#define CAMDMA_CDEI(n) (0x0AC + (n)*0x60)
124#define CAMDMA_CDFI(n) (0x0B0 + (n)*0x60)
125#define CAMDMA_CSAC(n) (0x0B4 + (n)*0x60)
126#define CAMDMA_CDAC(n) (0x0B8 + (n)*0x60)
127#define CAMDMA_CCEN(n) (0x0BC + (n)*0x60)
128#define CAMDMA_CCFN(n) (0x0C0 + (n)*0x60)
129#define CAMDMA_COLOR(n) (0x0C4 + (n)*0x60)
130
131/* define camera mmu register offsets */
132#define CAMMMU_REVISION 0x000
133#define CAMMMU_SYSCONFIG 0x010
134#define CAMMMU_SYSSTATUS 0x014
135#define CAMMMU_IRQSTATUS 0x018
136#define CAMMMU_IRQENABLE 0x01C
137#define CAMMMU_WALKING_ST 0x040
138#define CAMMMU_CNTL 0x044
139#define CAMMMU_FAULT_AD 0x048
140#define CAMMMU_TTB 0x04C
141#define CAMMMU_LOCK 0x050
142#define CAMMMU_LD_TLB 0x054
143#define CAMMMU_CAM 0x058
144#define CAMMMU_RAM 0x05C
145#define CAMMMU_GFLUSH 0x060
146#define CAMMMU_FLUSH_ENTRY 0x064
147#define CAMMMU_READ_CAM 0x068
148#define CAMMMU_READ_RAM 0x06C
149#define CAMMMU_EMU_FAULT_AD 0x070
150
151/* Define bit fields within selected registers */
152#define CAM_REVISION_MAJOR (15 << 4)
153#define CAM_REVISION_MAJOR_SHIFT 4
154#define CAM_REVISION_MINOR (15 << 0)
155#define CAM_REVISION_MINOR_SHIFT 0
156
157#define CAM_SYSCONFIG_SOFTRESET (1 << 1)
158#define CAM_SYSCONFIG_AUTOIDLE (1 << 0)
159
160#define CAM_SYSSTATUS_RESETDONE (1 << 0)
161
162#define CAM_IRQSTATUS_CC_IRQ (1 << 4)
163#define CAM_IRQSTATUS_MMU_IRQ (1 << 3)
164#define CAM_IRQSTATUS_DMA_IRQ2 (1 << 2)
165#define CAM_IRQSTATUS_DMA_IRQ1 (1 << 1)
166#define CAM_IRQSTATUS_DMA_IRQ0 (1 << 0)
167
168#define CAM_GPO_CAM_S_P_EN (1 << 1)
169#define CAM_GPO_CAM_CCP_MODE (1 << 0)
170
171#define CAM_GPI_CC_DMA_REQ1 (1 << 24)
172#define CAP_GPI_CC_DMA_REQ0 (1 << 23)
173#define CAP_GPI_CAM_MSTANDBY (1 << 21)
174#define CAP_GPI_CAM_WAIT (1 << 20)
175#define CAP_GPI_CAM_S_DATA (1 << 17)
176#define CAP_GPI_CAM_S_CLK (1 << 16)
177#define CAP_GPI_CAM_P_DATA (0xFFF << 3)
178#define CAP_GPI_CAM_P_DATA_SHIFT 3
179#define CAP_GPI_CAM_P_VS (1 << 2)
180#define CAP_GPI_CAM_P_HS (1 << 1)
181#define CAP_GPI_CAM_P_CLK (1 << 0)
182
183#define CC_REVISION_MAJOR (15 << 4)
184#define CC_REVISION_MAJOR_SHIFT 4
185#define CC_REVISION_MINOR (15 << 0)
186#define CC_REVISION_MINOR_SHIFT 0
187
188#define CC_SYSCONFIG_SIDLEMODE (3 << 3)
189#define CC_SYSCONFIG_SIDLEMODE_FIDLE (0 << 3)
190#define CC_SYSCONFIG_SIDLEMODE_NIDLE (1 << 3)
191#define CC_SYSCONFIG_SOFTRESET (1 << 1)
192#define CC_SYSCONFIG_AUTOIDLE (1 << 0)
193
194#define CC_SYSSTATUS_RESETDONE (1 << 0)
195
196#define CC_IRQSTATUS_FS_IRQ (1 << 19)
197#define CC_IRQSTATUS_LE_IRQ (1 << 18)
198#define CC_IRQSTATUS_LS_IRQ (1 << 17)
199#define CC_IRQSTATUS_FE_IRQ (1 << 16)
200#define CC_IRQSTATUS_FW_ERR_IRQ (1 << 10)
201#define CC_IRQSTATUS_FSC_ERR_IRQ (1 << 9)
202#define CC_IRQSTATUS_SSC_ERR_IRQ (1 << 8)
203#define CC_IRQSTATUS_FIFO_NOEMPTY_IRQ (1 << 4)
204#define CC_IRQSTATUS_FIFO_FULL_IRQ (1 << 3)
205#define CC_IRQSTATUS_FIFO_THR_IRQ (1 << 2)
206#define CC_IRQSTATUS_FIFO_OF_IRQ (1 << 1)
207#define CC_IRQSTATUS_FIFO_UF_IRQ (1 << 0)
208
209#define CC_IRQENABLE_FS_IRQ (1 << 19)
210#define CC_IRQENABLE_LE_IRQ (1 << 18)
211#define CC_IRQENABLE_LS_IRQ (1 << 17)
212#define CC_IRQENABLE_FE_IRQ (1 << 16)
213#define CC_IRQENABLE_FW_ERR_IRQ (1 << 10)
214#define CC_IRQENABLE_FSC_ERR_IRQ (1 << 9)
215#define CC_IRQENABLE_SSC_ERR_IRQ (1 << 8)
216#define CC_IRQENABLE_FIFO_NOEMPTY_IRQ (1 << 4)
217#define CC_IRQENABLE_FIFO_FULL_IRQ (1 << 3)
218#define CC_IRQENABLE_FIFO_THR_IRQ (1 << 2)
219#define CC_IRQENABLE_FIFO_OF_IRQ (1 << 1)
220#define CC_IRQENABLE_FIFO_UF_IRQ (1 << 0)
221
222#define CC_CTRL_CC_ONE_SHOT (1 << 20)
223#define CC_CTRL_CC_IF_SYNCHRO (1 << 19)
224#define CC_CTRL_CC_RST (1 << 18)
225#define CC_CTRL_CC_FRAME_TRIG (1 << 17)
226#define CC_CTRL_CC_EN (1 << 16)
227#define CC_CTRL_NOBT_SYNCHRO (1 << 13)
228#define CC_CTRL_BT_CORRECT (1 << 12)
229#define CC_CTRL_PAR_ORDERCAM (1 << 11)
230#define CC_CTRL_PAR_CLK_POL (1 << 10)
231#define CC_CTRL_NOBT_HS_POL (1 << 9)
232#define CC_CTRL_NOBT_VS_POL (1 << 8)
233#define CC_CTRL_PAR_MODE (7 << 1)
234#define CC_CTRL_PAR_MODE_SHIFT 1
235#define CC_CTRL_PAR_MODE_NOBT8 (0 << 1)
236#define CC_CTRL_PAR_MODE_NOBT10 (1 << 1)
237#define CC_CTRL_PAR_MODE_NOBT12 (2 << 1)
238#define CC_CTRL_PAR_MODE_BT8 (4 << 1)
239#define CC_CTRL_PAR_MODE_BT10 (5 << 1)
240#define CC_CTRL_PAR_MODE_FIFOTEST (7 << 1)
241#define CC_CTRL_CCP_MODE (1 << 0)
242
243#define CC_CTRL_DMA_EN (1 << 8)
244#define CC_CTRL_DMA_FIFO_THRESHOLD (0x7F << 0)
245#define CC_CTRL_DMA_FIFO_THRESHOLD_SHIFT 0
246
247#define CC_CTRL_XCLK_DIV (0x1F << 0)
248#define CC_CTRL_XCLK_DIV_SHIFT 0
249#define CC_CTRL_XCLK_DIV_STABLE_LOW (0 << 0)
250#define CC_CTRL_XCLK_DIV_STABLE_HIGH (1 << 0)
251#define CC_CTRL_XCLK_DIV_BYPASS (31 << 0)
252
253#define CC_TEST_FIFO_RD_POINTER (0xFF << 24)
254#define CC_TEST_FIFO_RD_POINTER_SHIFT 24
255#define CC_TEST_FIFO_WR_POINTER (0xFF << 16)
256#define CC_TEST_FIFO_WR_POINTER_SHIFT 16
257#define CC_TEST_FIFO_LEVEL (0xFF << 8)
258#define CC_TEST_FIFO_LEVEL_SHIFT 8
259#define CC_TEST_FIFO_LEVEL_PEAK (0xFF << 0)
260#define CC_TEST_FIFO_LEVEL_PEAK_SHIFT 0
261
262#define CC_GENPAR_FIFO_DEPTH (7 << 0)
263#define CC_GENPAR_FIFO_DEPTH_SHIFT 0
264
265#define CC_CCPDFR_ALPHA (0xFF << 8)
266#define CC_CCPDFR_ALPHA_SHIFT 8
267#define CC_CCPDFR_DATAFORMAT (15 << 0)
268#define CC_CCPDFR_DATAFORMAT_SHIFT 0
269#define CC_CCPDFR_DATAFORMAT_YUV422BE (0 << 0)
270#define CC_CCPDFR_DATAFORMAT_YUV422 (1 << 0)
271#define CC_CCPDFR_DATAFORMAT_YUV420 (2 << 0)
272#define CC_CCPDFR_DATAFORMAT_RGB444 (4 << 0)
273#define CC_CCPDFR_DATAFORMAT_RGB565 (5 << 0)
274#define CC_CCPDFR_DATAFORMAT_RGB888NDE (6 << 0)
275#define CC_CCPDFR_DATAFORMAT_RGB888 (7 << 0)
276#define CC_CCPDFR_DATAFORMAT_RAW8NDE (8 << 0)
277#define CC_CCPDFR_DATAFORMAT_RAW8 (9 << 0)
278#define CC_CCPDFR_DATAFORMAT_RAW10NDE (10 << 0)
279#define CC_CCPDFR_DATAFORMAT_RAW10 (11 << 0)
280#define CC_CCPDFR_DATAFORMAT_RAW12NDE (12 << 0)
281#define CC_CCPDFR_DATAFORMAT_RAW12 (13 << 0)
282#define CC_CCPDFR_DATAFORMAT_JPEG8 (15 << 0)
283
284#define CAMDMA_REVISION_MAJOR (15 << 4)
285#define CAMDMA_REVISION_MAJOR_SHIFT 4
286#define CAMDMA_REVISION_MINOR (15 << 0)
287#define CAMDMA_REVISION_MINOR_SHIFT 0
288
289#define CAMDMA_OCP_SYSCONFIG_MIDLEMODE (3 << 12)
290#define CAMDMA_OCP_SYSCONFIG_MIDLEMODE_FSTANDBY (0 << 12)
291#define CAMDMA_OCP_SYSCONFIG_MIDLEMODE_NSTANDBY (1 << 12)
292#define CAMDMA_OCP_SYSCONFIG_MIDLEMODE_SSTANDBY (2 << 12)
293#define CAMDMA_OCP_SYSCONFIG_FUNC_CLOCK (1 << 9)
294#define CAMDMA_OCP_SYSCONFIG_OCP_CLOCK (1 << 8)
295#define CAMDMA_OCP_SYSCONFIG_EMUFREE (1 << 5)
296#define CAMDMA_OCP_SYSCONFIG_SIDLEMODE (3 << 3)
297#define CAMDMA_OCP_SYSCONFIG_SIDLEMODE_FIDLE (0 << 3)
298#define CAMDMA_OCP_SYSCONFIG_SIDLEMODE_NIDLE (1 << 3)
299#define CAMDMA_OCP_SYSCONFIG_SIDLEMODE_SIDLE (2 << 3)
300#define CAMDMA_OCP_SYSCONFIG_SOFTRESET (1 << 1)
301#define CAMDMA_OCP_SYSCONFIG_AUTOIDLE (1 << 0)
302
303#define CAMDMA_SYSSTATUS_RESETDONE (1 << 0)
304
305#define CAMDMA_GCR_ARBITRATION_RATE (0xFF << 16)
306#define CAMDMA_GCR_ARBITRATION_RATE_SHIFT 16
307#define CAMDMA_GCR_MAX_CHANNEL_FIFO_DEPTH (0xFF << 0)
308#define CAMDMA_GCR_MAX_CHANNEL_FIFO_DEPTH_SHIFT 0
309
310#define CAMDMA_CCR_SEL_SRC_DST_SYNC (1 << 24)
311#define CAMDMA_CCR_PREFETCH (1 << 23)
312#define CAMDMA_CCR_SUPERVISOR (1 << 22)
313#define CAMDMA_CCR_SECURE (1 << 21)
314#define CAMDMA_CCR_BS (1 << 18)
315#define CAMDMA_CCR_TRANSPARENT_COPY_ENABLE (1 << 17)
316#define CAMDMA_CCR_CONSTANT_FILL_ENABLE (1 << 16)
317#define CAMDMA_CCR_DST_AMODE (3 << 14)
318#define CAMDMA_CCR_DST_AMODE_CONST_ADDR (0 << 14)
319#define CAMDMA_CCR_DST_AMODE_POST_INC (1 << 14)
320#define CAMDMA_CCR_DST_AMODE_SGL_IDX (2 << 14)
321#define CAMDMA_CCR_DST_AMODE_DBL_IDX (3 << 14)
322#define CAMDMA_CCR_SRC_AMODE (3 << 12)
323#define CAMDMA_CCR_SRC_AMODE_CONST_ADDR (0 << 12)
324#define CAMDMA_CCR_SRC_AMODE_POST_INC (1 << 12)
325#define CAMDMA_CCR_SRC_AMODE_SGL_IDX (2 << 12)
326#define CAMDMA_CCR_SRC_AMODE_DBL_IDX (3 << 12)
327#define CAMDMA_CCR_WR_ACTIVE (1 << 10)
328#define CAMDMA_CCR_RD_ACTIVE (1 << 9)
329#define CAMDMA_CCR_SUSPEND_SENSITIVE (1 << 8)
330#define CAMDMA_CCR_ENABLE (1 << 7)
331#define CAMDMA_CCR_PRIO (1 << 6)
332#define CAMDMA_CCR_FS (1 << 5)
333#define CAMDMA_CCR_SYNCHRO ((3 << 19) | (31 << 0))
334#define CAMDMA_CCR_SYNCHRO_CAMERA 0x01
335
336#define CAMDMA_CLNK_CTRL_ENABLE_LNK (1 << 15)
337#define CAMDMA_CLNK_CTRL_NEXTLCH_ID (0x1F << 0)
338#define CAMDMA_CLNK_CTRL_NEXTLCH_ID_SHIFT 0
339
340#define CAMDMA_CICR_MISALIGNED_ERR_IE (1 << 11)
341#define CAMDMA_CICR_SUPERVISOR_ERR_IE (1 << 10)
342#define CAMDMA_CICR_SECURE_ERR_IE (1 << 9)
343#define CAMDMA_CICR_TRANS_ERR_IE (1 << 8)
344#define CAMDMA_CICR_PACKET_IE (1 << 7)
345#define CAMDMA_CICR_BLOCK_IE (1 << 5)
346#define CAMDMA_CICR_LAST_IE (1 << 4)
347#define CAMDMA_CICR_FRAME_IE (1 << 3)
348#define CAMDMA_CICR_HALF_IE (1 << 2)
349#define CAMDMA_CICR_DROP_IE (1 << 1)
350
351#define CAMDMA_CSR_MISALIGNED_ERR (1 << 11)
352#define CAMDMA_CSR_SUPERVISOR_ERR (1 << 10)
353#define CAMDMA_CSR_SECURE_ERR (1 << 9)
354#define CAMDMA_CSR_TRANS_ERR (1 << 8)
355#define CAMDMA_CSR_PACKET (1 << 7)
356#define CAMDMA_CSR_SYNC (1 << 6)
357#define CAMDMA_CSR_BLOCK (1 << 5)
358#define CAMDMA_CSR_LAST (1 << 4)
359#define CAMDMA_CSR_FRAME (1 << 3)
360#define CAMDMA_CSR_HALF (1 << 2)
361#define CAMDMA_CSR_DROP (1 << 1)
362
363#define CAMDMA_CSDP_SRC_ENDIANNESS (1 << 21)
364#define CAMDMA_CSDP_SRC_ENDIANNESS_LOCK (1 << 20)
365#define CAMDMA_CSDP_DST_ENDIANNESS (1 << 19)
366#define CAMDMA_CSDP_DST_ENDIANNESS_LOCK (1 << 18)
367#define CAMDMA_CSDP_WRITE_MODE (3 << 16)
368#define CAMDMA_CSDP_WRITE_MODE_WRNP (0 << 16)
369#define CAMDMA_CSDP_WRITE_MODE_POSTED (1 << 16)
370#define CAMDMA_CSDP_WRITE_MODE_POSTED_LAST_WRNP (2 << 16)
371#define CAMDMA_CSDP_DST_BURST_EN (3 << 14)
372#define CAMDMA_CSDP_DST_BURST_EN_1 (0 << 14)
373#define CAMDMA_CSDP_DST_BURST_EN_16 (1 << 14)
374#define CAMDMA_CSDP_DST_BURST_EN_32 (2 << 14)
375#define CAMDMA_CSDP_DST_BURST_EN_64 (3 << 14)
376#define CAMDMA_CSDP_DST_PACKED (1 << 13)
377#define CAMDMA_CSDP_WR_ADD_TRSLT (15 << 9)
378#define CAMDMA_CSDP_WR_ADD_TRSLT_ENABLE_MREQADD (3 << 9)
379#define CAMDMA_CSDP_SRC_BURST_EN (3 << 7)
380#define CAMDMA_CSDP_SRC_BURST_EN_1 (0 << 7)
381#define CAMDMA_CSDP_SRC_BURST_EN_16 (1 << 7)
382#define CAMDMA_CSDP_SRC_BURST_EN_32 (2 << 7)
383#define CAMDMA_CSDP_SRC_BURST_EN_64 (3 << 7)
384#define CAMDMA_CSDP_SRC_PACKED (1 << 6)
385#define CAMDMA_CSDP_RD_ADD_TRSLT (15 << 2)
386#define CAMDMA_CSDP_RD_ADD_TRSLT_ENABLE_MREQADD (3 << 2)
387#define CAMDMA_CSDP_DATA_TYPE (3 << 0)
388#define CAMDMA_CSDP_DATA_TYPE_8BITS (0 << 0)
389#define CAMDMA_CSDP_DATA_TYPE_16BITS (1 << 0)
390#define CAMDMA_CSDP_DATA_TYPE_32BITS (2 << 0)
391
392#define CAMMMU_SYSCONFIG_AUTOIDLE (1 << 0)
393
394/*
395 *
396 * Declarations.
397 *
398 */
399
400/* forward declarations */
401struct omap24xxcam_sgdma;
402struct omap24xxcam_dma;
403
404typedef void (*sgdma_callback_t)(struct omap24xxcam_sgdma *cam,
405 u32 status, void *arg);
406typedef void (*dma_callback_t)(struct omap24xxcam_dma *cam,
407 u32 status, void *arg);
408
409struct channel_state {
410 dma_callback_t callback;
411 void *arg;
412};
413
414/* sgdma state for each of the possible videobuf_buffers + 2 overlays */
415struct sgdma_state {
416 const struct scatterlist *sglist;
417 int sglen; /* number of sglist entries */
418 int next_sglist; /* index of next sglist entry to process */
419 unsigned int bytes_read; /* number of bytes read */
420 unsigned int len; /* total length of sglist (excluding
421 * bytes due to page alignment) */
422 int queued_sglist; /* number of sglist entries queued for DMA */
423 u32 csr; /* DMA return code */
424 sgdma_callback_t callback;
425 void *arg;
426};
427
428/* physical DMA channel management */
429struct omap24xxcam_dma {
430 spinlock_t lock; /* Lock for the whole structure. */
431
432 void __iomem *base; /* base address for dma controller */
433
434 /* While dma_stop!=0, an attempt to start a new DMA transfer will
435 * fail.
436 */
437 atomic_t dma_stop;
438 int free_dmach; /* number of dma channels free */
439 int next_dmach; /* index of next dma channel to use */
440 struct channel_state ch_state[NUM_CAMDMA_CHANNELS];
441};
442
443/* scatter-gather DMA (scatterlist stuff) management */
444struct omap24xxcam_sgdma {
445 struct omap24xxcam_dma dma;
446
447 spinlock_t lock; /* Lock for the fields below. */
448 int free_sgdma; /* number of free sg dma slots */
449 int next_sgdma; /* index of next sg dma slot to use */
450 struct sgdma_state sg_state[NUM_SG_DMA];
451
452 /* Reset timer data */
453 struct timer_list reset_timer;
454};
455
456/* per-device data structure */
457struct omap24xxcam_device {
458 /*** mutex ***/
459 /*
460 * mutex serialises access to this structure. Also camera
461 * opening and releasing is synchronised by this.
462 */
463 struct mutex mutex;
464
465 /*** general driver state information ***/
466 atomic_t users;
467 /*
468 * Lock to serialise core enabling and disabling and access to
469 * sgdma_in_queue.
470 */
471 spinlock_t core_enable_disable_lock;
472 /*
473 * Number or sgdma requests in scatter-gather queue, protected
474 * by the lock above.
475 */
476 int sgdma_in_queue;
477 /*
478 * Sensor interface parameters: interface type, CC_CTRL
479 * register value and interface specific data.
480 */
481 int if_type;
482 union {
483 struct parallel {
484 u32 xclk;
485 } bt656;
486 } if_u;
487 u32 cc_ctrl;
488
489 /*** subsystem structures ***/
490 struct omap24xxcam_sgdma sgdma;
491
492 /*** hardware resources ***/
493 unsigned int irq;
494 void __iomem *mmio_base;
495 unsigned long mmio_base_phys;
496 unsigned long mmio_size;
497
498 /*** interfaces and device ***/
499 struct v4l2_int_device *sdev;
500 struct device *dev;
501 struct video_device *vfd;
502
503 /*** camera and sensor reset related stuff ***/
504 struct work_struct sensor_reset_work;
505 /*
506 * We're in the middle of a reset. Don't enable core if this
507 * is non-zero! This exists to help decisionmaking in a case
508 * where videobuf_qbuf is called while we are in the middle of
509 * a reset.
510 */
511 atomic_t in_reset;
512 /*
513 * Non-zero if we don't want any resets for now. Used to
514 * prevent reset work to run when we're about to stop
515 * streaming.
516 */
517 atomic_t reset_disable;
518
519 /*** video device parameters ***/
520 int capture_mem;
521
522 /*** camera module clocks ***/
523 struct clk *fck;
524 struct clk *ick;
525
526 /*** capture data ***/
527 /* file handle, if streaming is on */
528 struct file *streaming;
529};
530
531/* Per-file handle data. */
532struct omap24xxcam_fh {
533 spinlock_t vbq_lock; /* spinlock for the videobuf queue */
534 struct videobuf_queue vbq;
535 struct v4l2_pix_format pix; /* serialise pix by vbq->lock */
536 atomic_t field_count; /* field counter for videobuf_buffer */
537 /* accessing cam here doesn't need serialisation: it's constant */
538 struct omap24xxcam_device *cam;
539};
540
541/*
542 *
543 * Register I/O functions.
544 *
545 */
546
547static inline u32 omap24xxcam_reg_in(u32 __iomem *base, u32 offset)
548{
549 return readl(base + offset);
550}
551
552static inline u32 omap24xxcam_reg_out(u32 __iomem *base, u32 offset,
553 u32 val)
554{
555 writel(val, base + offset);
556 return val;
557}
558
559static inline u32 omap24xxcam_reg_merge(u32 __iomem *base, u32 offset,
560 u32 val, u32 mask)
561{
562 u32 __iomem *addr = base + offset;
563 u32 new_val = (readl(addr) & ~mask) | (val & mask);
564
565 writel(new_val, addr);
566 return new_val;
567}
568
569/*
570 *
571 * Function prototypes.
572 *
573 */
574
575/* dma prototypes */
576
577void omap24xxcam_dma_hwinit(struct omap24xxcam_dma *dma);
578void omap24xxcam_dma_isr(struct omap24xxcam_dma *dma);
579
580/* sgdma prototypes */
581
582void omap24xxcam_sgdma_process(struct omap24xxcam_sgdma *sgdma);
583int omap24xxcam_sgdma_queue(struct omap24xxcam_sgdma *sgdma,
584 const struct scatterlist *sglist, int sglen,
585 int len, sgdma_callback_t callback, void *arg);
586void omap24xxcam_sgdma_sync(struct omap24xxcam_sgdma *sgdma);
587void omap24xxcam_sgdma_init(struct omap24xxcam_sgdma *sgdma,
588 void __iomem *base,
589 void (*reset_callback)(unsigned long data),
590 unsigned long reset_callback_data);
591void omap24xxcam_sgdma_exit(struct omap24xxcam_sgdma *sgdma);
592
593#endif
diff --git a/drivers/media/video/omap3isp/Makefile b/drivers/media/video/omap3isp/Makefile
deleted file mode 100644
index e8847e79e31a..000000000000
--- a/drivers/media/video/omap3isp/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
1# Makefile for OMAP3 ISP driver
2
3ccflags-$(CONFIG_VIDEO_OMAP3_DEBUG) += -DDEBUG
4
5omap3-isp-objs += \
6 isp.o ispqueue.o ispvideo.o \
7 ispcsiphy.o ispccp2.o ispcsi2.o \
8 ispccdc.o isppreview.o ispresizer.o \
9 ispstat.o isph3a_aewb.o isph3a_af.o isphist.o
10
11obj-$(CONFIG_VIDEO_OMAP3) += omap3-isp.o
diff --git a/drivers/media/video/omap3isp/cfa_coef_table.h b/drivers/media/video/omap3isp/cfa_coef_table.h
deleted file mode 100644
index c84df0706f3e..000000000000
--- a/drivers/media/video/omap3isp/cfa_coef_table.h
+++ /dev/null
@@ -1,61 +0,0 @@
1/*
2 * cfa_coef_table.h
3 *
4 * TI OMAP3 ISP - CFA coefficients table
5 *
6 * Copyright (C) 2009-2010 Nokia Corporation
7 *
8 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
9 * Sakari Ailus <sakari.ailus@iki.fi>
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * version 2 as published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23 * 02110-1301 USA
24 */
25
26{ 244, 0, 247, 0, 12, 27, 36, 247, 250, 0, 27, 0, 4, 250, 12, 244,
27248, 0, 0, 0, 0, 40, 0, 0, 244, 12, 250, 4, 0, 27, 0, 250,
28247, 36, 27, 12, 0, 247, 0, 244, 0, 0, 40, 0, 0, 0, 0, 248,
29244, 0, 247, 0, 12, 27, 36, 247, 250, 0, 27, 0, 4, 250, 12, 244,
30248, 0, 0, 0, 0, 40, 0, 0, 244, 12, 250, 4, 0, 27, 0, 250,
31247, 36, 27, 12, 0, 247, 0, 244, 0, 0, 40, 0, 0, 0, 0, 248,
32244, 0, 247, 0, 12, 27, 36, 247, 250, 0, 27, 0, 4, 250, 12, 244,
33248, 0, 0, 0, 0, 40, 0, 0, 244, 12, 250, 4, 0, 27, 0, 250,
34247, 36, 27, 12, 0, 247, 0, 244, 0, 0, 40, 0, 0, 0, 0, 248 },
35{ 0, 247, 0, 244, 247, 36, 27, 12, 0, 27, 0, 250, 244, 12, 250, 4,
36 0, 0, 0, 248, 0, 0, 40, 0, 4, 250, 12, 244, 250, 0, 27, 0,
37 12, 27, 36, 247, 244, 0, 247, 0, 0, 40, 0, 0, 248, 0, 0, 0,
38 0, 247, 0, 244, 247, 36, 27, 12, 0, 27, 0, 250, 244, 12, 250, 4,
39 0, 0, 0, 248, 0, 0, 40, 0, 4, 250, 12, 244, 250, 0, 27, 0,
40 12, 27, 36, 247, 244, 0, 247, 0, 0, 40, 0, 0, 248, 0, 0, 0,
41 0, 247, 0, 244, 247, 36, 27, 12, 0, 27, 0, 250, 244, 12, 250, 4,
42 0, 0, 0, 248, 0, 0, 40, 0, 4, 250, 12, 244, 250, 0, 27, 0,
43 12, 27, 36, 247, 244, 0, 247, 0, 0, 40, 0, 0, 248, 0, 0, 0 },
44{ 4, 250, 12, 244, 250, 0, 27, 0, 12, 27, 36, 247, 244, 0, 247, 0,
45 0, 0, 0, 248, 0, 0, 40, 0, 0, 247, 0, 244, 247, 36, 27, 12,
46 0, 27, 0, 250, 244, 12, 250, 4, 0, 40, 0, 0, 248, 0, 0, 0,
47 4, 250, 12, 244, 250, 0, 27, 0, 12, 27, 36, 247, 244, 0, 247, 0,
48 0, 0, 0, 248, 0, 0, 40, 0, 0, 247, 0, 244, 247, 36, 27, 12,
49 0, 27, 0, 250, 244, 12, 250, 4, 0, 40, 0, 0, 248, 0, 0, 0,
50 4, 250, 12, 244, 250, 0, 27, 0, 12, 27, 36, 247, 244, 0, 247, 0,
51 0, 0, 0, 248, 0, 0, 40, 0, 0, 247, 0, 244, 247, 36, 27, 12,
52 0, 27, 0, 250, 244, 12, 250, 4, 0, 40, 0, 0, 248, 0, 0, 0 },
53{ 244,12, 250, 4, 0, 27, 0, 250, 247, 36, 27, 12, 0, 247, 0, 244,
54248, 0, 0, 0, 0, 40, 0, 0, 244, 0, 247, 0, 12, 27, 36, 247,
55250, 0, 27, 0, 4, 250, 12, 244, 0, 0, 40, 0, 0, 0, 0, 248,
56244, 12, 250, 4, 0, 27, 0, 250, 247, 36, 27, 12, 0, 247, 0, 244,
57248, 0, 0, 0, 0, 40, 0, 0, 244, 0, 247, 0, 12, 27, 36, 247,
58250, 0, 27, 0, 4, 250, 12, 244, 0, 0, 40, 0, 0, 0, 0, 248,
59244, 12, 250, 4, 0, 27, 0, 250, 247, 36, 27, 12, 0, 247, 0, 244,
60248, 0, 0, 0, 0, 40, 0, 0, 244, 0, 247, 0, 12, 27, 36, 247,
61250, 0, 27, 0, 4, 250, 12, 244, 0, 0, 40, 0, 0, 0, 0, 248 },
diff --git a/drivers/media/video/omap3isp/gamma_table.h b/drivers/media/video/omap3isp/gamma_table.h
deleted file mode 100644
index 78deebf7d965..000000000000
--- a/drivers/media/video/omap3isp/gamma_table.h
+++ /dev/null
@@ -1,90 +0,0 @@
1/*
2 * gamma_table.h
3 *
4 * TI OMAP3 ISP - Default gamma table for all components
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc.
8 *
9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 * Sakari Ailus <sakari.ailus@iki.fi>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 */
26
27 0, 0, 1, 2, 3, 3, 4, 5, 6, 8, 10, 12, 14, 16, 18, 20,
28 22, 23, 25, 26, 28, 29, 31, 32, 34, 35, 36, 37, 39, 40, 41, 42,
29 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 52, 53, 54, 55, 56, 57,
30 58, 59, 60, 61, 62, 63, 63, 64, 65, 66, 66, 67, 68, 69, 69, 70,
31 71, 72, 72, 73, 74, 75, 75, 76, 77, 78, 78, 79, 80, 81, 81, 82,
32 83, 84, 84, 85, 86, 87, 88, 88, 89, 90, 91, 91, 92, 93, 94, 94,
33 95, 96, 97, 97, 98, 98, 99, 99, 100, 100, 101, 101, 102, 103, 104, 104,
34105, 106, 107, 108, 108, 109, 110, 111, 111, 112, 113, 114, 114, 115, 116, 117,
35117, 118, 119, 119, 120, 120, 121, 121, 122, 122, 123, 123, 124, 124, 125, 125,
36126, 126, 127, 127, 128, 128, 129, 129, 130, 130, 131, 131, 132, 132, 133, 133,
37134, 134, 135, 135, 136, 136, 137, 137, 138, 138, 139, 139, 140, 140, 141, 141,
38142, 142, 143, 143, 144, 144, 145, 145, 146, 146, 147, 147, 148, 148, 149, 149,
39150, 150, 151, 151, 152, 152, 153, 153, 153, 153, 154, 154, 154, 154, 155, 155,
40156, 156, 157, 157, 158, 158, 158, 159, 159, 159, 160, 160, 160, 161, 161, 162,
41162, 163, 163, 164, 164, 164, 164, 165, 165, 165, 165, 166, 166, 167, 167, 168,
42168, 169, 169, 170, 170, 170, 170, 171, 171, 171, 171, 172, 172, 173, 173, 174,
43174, 175, 175, 176, 176, 176, 176, 177, 177, 177, 177, 178, 178, 178, 178, 179,
44179, 179, 179, 180, 180, 180, 180, 181, 181, 181, 181, 182, 182, 182, 182, 183,
45183, 183, 183, 184, 184, 184, 184, 185, 185, 185, 185, 186, 186, 186, 186, 187,
46187, 187, 187, 188, 188, 188, 188, 189, 189, 189, 189, 190, 190, 190, 190, 191,
47191, 191, 191, 192, 192, 192, 192, 193, 193, 193, 193, 194, 194, 194, 194, 195,
48195, 195, 195, 196, 196, 196, 196, 197, 197, 197, 197, 198, 198, 198, 198, 199,
49199, 199, 199, 200, 200, 200, 200, 201, 201, 201, 201, 202, 202, 202, 203, 203,
50203, 203, 204, 204, 204, 204, 205, 205, 205, 205, 206, 206, 206, 206, 207, 207,
51207, 207, 208, 208, 208, 208, 209, 209, 209, 209, 210, 210, 210, 210, 210, 210,
52210, 210, 210, 210, 210, 210, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211,
53211, 212, 212, 212, 212, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213,
54213, 214, 214, 214, 214, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215,
55216, 216, 216, 216, 217, 217, 217, 217, 218, 218, 218, 218, 219, 219, 219, 219,
56219, 219, 219, 219, 219, 219, 219, 219, 220, 220, 220, 220, 221, 221, 221, 221,
57221, 221, 221, 221, 221, 221, 221, 222, 222, 222, 222, 223, 223, 223, 223, 223,
58223, 223, 223, 223, 223, 223, 223, 224, 224, 224, 224, 225, 225, 225, 225, 225,
59225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 226, 226,
60226, 226, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 228, 228,
61228, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 230, 230, 230,
62230, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 232, 232, 232,
63232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232,
64233, 233, 233, 233, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 235,
65235, 235, 235, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236,
66236, 236, 236, 236, 236, 236, 237, 237, 237, 237, 238, 238, 238, 238, 238, 238,
67238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238,
68238, 238, 238, 238, 238, 239, 239, 239, 239, 240, 240, 240, 240, 240, 240, 240,
69240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240,
70240, 240, 240, 240, 241, 241, 241, 241, 242, 242, 242, 242, 242, 242, 242, 242,
71242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242,
72242, 242, 243, 243, 243, 243, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244,
73244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244,
74244, 245, 245, 245, 245, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246,
75246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246,
76246, 246, 246, 246, 246, 246, 246, 247, 247, 247, 247, 248, 248, 248, 248, 248,
77248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248,
78248, 248, 248, 248, 248, 248, 249, 249, 249, 249, 250, 250, 250, 250, 250, 250,
79250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250,
80250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250,
81250, 250, 250, 250, 251, 251, 251, 251, 252, 252, 252, 252, 252, 252, 252, 252,
82252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252,
83252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252,
84252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252,
85252, 252, 252, 252, 252, 252, 252, 252, 253, 253, 253, 253, 253, 253, 253, 253,
86253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253,
87253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253,
88253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253,
89253, 254, 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
90255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
diff --git a/drivers/media/video/omap3isp/isp.c b/drivers/media/video/omap3isp/isp.c
deleted file mode 100644
index e0096e07dbdc..000000000000
--- a/drivers/media/video/omap3isp/isp.c
+++ /dev/null
@@ -1,2241 +0,0 @@
1/*
2 * isp.c
3 *
4 * TI OMAP3 ISP - Core
5 *
6 * Copyright (C) 2006-2010 Nokia Corporation
7 * Copyright (C) 2007-2009 Texas Instruments, Inc.
8 *
9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 * Sakari Ailus <sakari.ailus@iki.fi>
11 *
12 * Contributors:
13 * Laurent Pinchart <laurent.pinchart@ideasonboard.com>
14 * Sakari Ailus <sakari.ailus@iki.fi>
15 * David Cohen <dacohen@gmail.com>
16 * Stanimir Varbanov <svarbanov@mm-sol.com>
17 * Vimarsh Zutshi <vimarsh.zutshi@gmail.com>
18 * Tuukka Toivonen <tuukkat76@gmail.com>
19 * Sergio Aguirre <saaguirre@ti.com>
20 * Antti Koskipaa <akoskipa@gmail.com>
21 * Ivan T. Ivanov <iivanov@mm-sol.com>
22 * RaniSuneela <r-m@ti.com>
23 * Atanas Filipov <afilipov@mm-sol.com>
24 * Gjorgji Rosikopulos <grosikopulos@mm-sol.com>
25 * Hiroshi DOYU <hiroshi.doyu@nokia.com>
26 * Nayden Kanchev <nkanchev@mm-sol.com>
27 * Phil Carmody <ext-phil.2.carmody@nokia.com>
28 * Artem Bityutskiy <artem.bityutskiy@nokia.com>
29 * Dominic Curran <dcurran@ti.com>
30 * Ilkka Myllyperkio <ilkka.myllyperkio@sofica.fi>
31 * Pallavi Kulkarni <p-kulkarni@ti.com>
32 * Vaibhav Hiremath <hvaibhav@ti.com>
33 * Mohit Jalori <mjalori@ti.com>
34 * Sameer Venkatraman <sameerv@ti.com>
35 * Senthilvadivu Guruswamy <svadivu@ti.com>
36 * Thara Gopinath <thara@ti.com>
37 * Toni Leinonen <toni.leinonen@nokia.com>
38 * Troy Laramy <t-laramy@ti.com>
39 *
40 * This program is free software; you can redistribute it and/or modify
41 * it under the terms of the GNU General Public License version 2 as
42 * published by the Free Software Foundation.
43 *
44 * This program is distributed in the hope that it will be useful, but
45 * WITHOUT ANY WARRANTY; without even the implied warranty of
46 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
47 * General Public License for more details.
48 *
49 * You should have received a copy of the GNU General Public License
50 * along with this program; if not, write to the Free Software
51 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
52 * 02110-1301 USA
53 */
54
55#include <asm/cacheflush.h>
56
57#include <linux/clk.h>
58#include <linux/delay.h>
59#include <linux/device.h>
60#include <linux/dma-mapping.h>
61#include <linux/i2c.h>
62#include <linux/interrupt.h>
63#include <linux/module.h>
64#include <linux/platform_device.h>
65#include <linux/regulator/consumer.h>
66#include <linux/slab.h>
67#include <linux/sched.h>
68#include <linux/vmalloc.h>
69
70#include <media/v4l2-common.h>
71#include <media/v4l2-device.h>
72
73#include "isp.h"
74#include "ispreg.h"
75#include "ispccdc.h"
76#include "isppreview.h"
77#include "ispresizer.h"
78#include "ispcsi2.h"
79#include "ispccp2.h"
80#include "isph3a.h"
81#include "isphist.h"
82
83static unsigned int autoidle;
84module_param(autoidle, int, 0444);
85MODULE_PARM_DESC(autoidle, "Enable OMAP3ISP AUTOIDLE support");
86
87static void isp_save_ctx(struct isp_device *isp);
88
89static void isp_restore_ctx(struct isp_device *isp);
90
91static const struct isp_res_mapping isp_res_maps[] = {
92 {
93 .isp_rev = ISP_REVISION_2_0,
94 .map = 1 << OMAP3_ISP_IOMEM_MAIN |
95 1 << OMAP3_ISP_IOMEM_CCP2 |
96 1 << OMAP3_ISP_IOMEM_CCDC |
97 1 << OMAP3_ISP_IOMEM_HIST |
98 1 << OMAP3_ISP_IOMEM_H3A |
99 1 << OMAP3_ISP_IOMEM_PREV |
100 1 << OMAP3_ISP_IOMEM_RESZ |
101 1 << OMAP3_ISP_IOMEM_SBL |
102 1 << OMAP3_ISP_IOMEM_CSI2A_REGS1 |
103 1 << OMAP3_ISP_IOMEM_CSIPHY2,
104 },
105 {
106 .isp_rev = ISP_REVISION_15_0,
107 .map = 1 << OMAP3_ISP_IOMEM_MAIN |
108 1 << OMAP3_ISP_IOMEM_CCP2 |
109 1 << OMAP3_ISP_IOMEM_CCDC |
110 1 << OMAP3_ISP_IOMEM_HIST |
111 1 << OMAP3_ISP_IOMEM_H3A |
112 1 << OMAP3_ISP_IOMEM_PREV |
113 1 << OMAP3_ISP_IOMEM_RESZ |
114 1 << OMAP3_ISP_IOMEM_SBL |
115 1 << OMAP3_ISP_IOMEM_CSI2A_REGS1 |
116 1 << OMAP3_ISP_IOMEM_CSIPHY2 |
117 1 << OMAP3_ISP_IOMEM_CSI2A_REGS2 |
118 1 << OMAP3_ISP_IOMEM_CSI2C_REGS1 |
119 1 << OMAP3_ISP_IOMEM_CSIPHY1 |
120 1 << OMAP3_ISP_IOMEM_CSI2C_REGS2,
121 },
122};
123
124/* Structure for saving/restoring ISP module registers */
125static struct isp_reg isp_reg_list[] = {
126 {OMAP3_ISP_IOMEM_MAIN, ISP_SYSCONFIG, 0},
127 {OMAP3_ISP_IOMEM_MAIN, ISP_CTRL, 0},
128 {OMAP3_ISP_IOMEM_MAIN, ISP_TCTRL_CTRL, 0},
129 {0, ISP_TOK_TERM, 0}
130};
131
132/*
133 * omap3isp_flush - Post pending L3 bus writes by doing a register readback
134 * @isp: OMAP3 ISP device
135 *
136 * In order to force posting of pending writes, we need to write and
137 * readback the same register, in this case the revision register.
138 *
139 * See this link for reference:
140 * http://www.mail-archive.com/linux-omap@vger.kernel.org/msg08149.html
141 */
142void omap3isp_flush(struct isp_device *isp)
143{
144 isp_reg_writel(isp, 0, OMAP3_ISP_IOMEM_MAIN, ISP_REVISION);
145 isp_reg_readl(isp, OMAP3_ISP_IOMEM_MAIN, ISP_REVISION);
146}
147
148/*
149 * isp_enable_interrupts - Enable ISP interrupts.
150 * @isp: OMAP3 ISP device
151 */
152static void isp_enable_interrupts(struct isp_device *isp)
153{
154 static const u32 irq = IRQ0ENABLE_CSIA_IRQ
155 | IRQ0ENABLE_CSIB_IRQ
156 | IRQ0ENABLE_CCDC_LSC_PREF_ERR_IRQ
157 | IRQ0ENABLE_CCDC_LSC_DONE_IRQ
158 | IRQ0ENABLE_CCDC_VD0_IRQ
159 | IRQ0ENABLE_CCDC_VD1_IRQ
160 | IRQ0ENABLE_HS_VS_IRQ
161 | IRQ0ENABLE_HIST_DONE_IRQ
162 | IRQ0ENABLE_H3A_AWB_DONE_IRQ
163 | IRQ0ENABLE_H3A_AF_DONE_IRQ
164 | IRQ0ENABLE_PRV_DONE_IRQ
165 | IRQ0ENABLE_RSZ_DONE_IRQ;
166
167 isp_reg_writel(isp, irq, OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0STATUS);
168 isp_reg_writel(isp, irq, OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0ENABLE);
169}
170
171/*
172 * isp_disable_interrupts - Disable ISP interrupts.
173 * @isp: OMAP3 ISP device
174 */
175static void isp_disable_interrupts(struct isp_device *isp)
176{
177 isp_reg_writel(isp, 0, OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0ENABLE);
178}
179
180/**
181 * isp_set_xclk - Configures the specified cam_xclk to the desired frequency.
182 * @isp: OMAP3 ISP device
183 * @xclk: Desired frequency of the clock in Hz. 0 = stable low, 1 is stable high
184 * @xclksel: XCLK to configure (0 = A, 1 = B).
185 *
186 * Configures the specified MCLK divisor in the ISP timing control register
187 * (TCTRL_CTRL) to generate the desired xclk clock value.
188 *
189 * Divisor = cam_mclk_hz / xclk
190 *
191 * Returns the final frequency that is actually being generated
192 **/
193static u32 isp_set_xclk(struct isp_device *isp, u32 xclk, u8 xclksel)
194{
195 u32 divisor;
196 u32 currentxclk;
197 unsigned long mclk_hz;
198
199 if (!omap3isp_get(isp))
200 return 0;
201
202 mclk_hz = clk_get_rate(isp->clock[ISP_CLK_CAM_MCLK]);
203
204 if (xclk >= mclk_hz) {
205 divisor = ISPTCTRL_CTRL_DIV_BYPASS;
206 currentxclk = mclk_hz;
207 } else if (xclk >= 2) {
208 divisor = mclk_hz / xclk;
209 if (divisor >= ISPTCTRL_CTRL_DIV_BYPASS)
210 divisor = ISPTCTRL_CTRL_DIV_BYPASS - 1;
211 currentxclk = mclk_hz / divisor;
212 } else {
213 divisor = xclk;
214 currentxclk = 0;
215 }
216
217 switch (xclksel) {
218 case ISP_XCLK_A:
219 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_MAIN, ISP_TCTRL_CTRL,
220 ISPTCTRL_CTRL_DIVA_MASK,
221 divisor << ISPTCTRL_CTRL_DIVA_SHIFT);
222 dev_dbg(isp->dev, "isp_set_xclk(): cam_xclka set to %d Hz\n",
223 currentxclk);
224 break;
225 case ISP_XCLK_B:
226 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_MAIN, ISP_TCTRL_CTRL,
227 ISPTCTRL_CTRL_DIVB_MASK,
228 divisor << ISPTCTRL_CTRL_DIVB_SHIFT);
229 dev_dbg(isp->dev, "isp_set_xclk(): cam_xclkb set to %d Hz\n",
230 currentxclk);
231 break;
232 case ISP_XCLK_NONE:
233 default:
234 omap3isp_put(isp);
235 dev_dbg(isp->dev, "ISP_ERR: isp_set_xclk(): Invalid requested "
236 "xclk. Must be 0 (A) or 1 (B).\n");
237 return -EINVAL;
238 }
239
240 /* Do we go from stable whatever to clock? */
241 if (divisor >= 2 && isp->xclk_divisor[xclksel - 1] < 2)
242 omap3isp_get(isp);
243 /* Stopping the clock. */
244 else if (divisor < 2 && isp->xclk_divisor[xclksel - 1] >= 2)
245 omap3isp_put(isp);
246
247 isp->xclk_divisor[xclksel - 1] = divisor;
248
249 omap3isp_put(isp);
250
251 return currentxclk;
252}
253
254/*
255 * isp_core_init - ISP core settings
256 * @isp: OMAP3 ISP device
257 * @idle: Consider idle state.
258 *
259 * Set the power settings for the ISP and SBL bus and cConfigure the HS/VS
260 * interrupt source.
261 *
262 * We need to configure the HS/VS interrupt source before interrupts get
263 * enabled, as the sensor might be free-running and the ISP default setting
264 * (HS edge) would put an unnecessary burden on the CPU.
265 */
266static void isp_core_init(struct isp_device *isp, int idle)
267{
268 isp_reg_writel(isp,
269 ((idle ? ISP_SYSCONFIG_MIDLEMODE_SMARTSTANDBY :
270 ISP_SYSCONFIG_MIDLEMODE_FORCESTANDBY) <<
271 ISP_SYSCONFIG_MIDLEMODE_SHIFT) |
272 ((isp->revision == ISP_REVISION_15_0) ?
273 ISP_SYSCONFIG_AUTOIDLE : 0),
274 OMAP3_ISP_IOMEM_MAIN, ISP_SYSCONFIG);
275
276 isp_reg_writel(isp,
277 (isp->autoidle ? ISPCTRL_SBL_AUTOIDLE : 0) |
278 ISPCTRL_SYNC_DETECT_VSRISE,
279 OMAP3_ISP_IOMEM_MAIN, ISP_CTRL);
280}
281
282/*
283 * Configure the bridge and lane shifter. Valid inputs are
284 *
285 * CCDC_INPUT_PARALLEL: Parallel interface
286 * CCDC_INPUT_CSI2A: CSI2a receiver
287 * CCDC_INPUT_CCP2B: CCP2b receiver
288 * CCDC_INPUT_CSI2C: CSI2c receiver
289 *
290 * The bridge and lane shifter are configured according to the selected input
291 * and the ISP platform data.
292 */
293void omap3isp_configure_bridge(struct isp_device *isp,
294 enum ccdc_input_entity input,
295 const struct isp_parallel_platform_data *pdata,
296 unsigned int shift, unsigned int bridge)
297{
298 u32 ispctrl_val;
299
300 ispctrl_val = isp_reg_readl(isp, OMAP3_ISP_IOMEM_MAIN, ISP_CTRL);
301 ispctrl_val &= ~ISPCTRL_SHIFT_MASK;
302 ispctrl_val &= ~ISPCTRL_PAR_CLK_POL_INV;
303 ispctrl_val &= ~ISPCTRL_PAR_SER_CLK_SEL_MASK;
304 ispctrl_val &= ~ISPCTRL_PAR_BRIDGE_MASK;
305 ispctrl_val |= bridge;
306
307 switch (input) {
308 case CCDC_INPUT_PARALLEL:
309 ispctrl_val |= ISPCTRL_PAR_SER_CLK_SEL_PARALLEL;
310 ispctrl_val |= pdata->clk_pol << ISPCTRL_PAR_CLK_POL_SHIFT;
311 shift += pdata->data_lane_shift * 2;
312 break;
313
314 case CCDC_INPUT_CSI2A:
315 ispctrl_val |= ISPCTRL_PAR_SER_CLK_SEL_CSIA;
316 break;
317
318 case CCDC_INPUT_CCP2B:
319 ispctrl_val |= ISPCTRL_PAR_SER_CLK_SEL_CSIB;
320 break;
321
322 case CCDC_INPUT_CSI2C:
323 ispctrl_val |= ISPCTRL_PAR_SER_CLK_SEL_CSIC;
324 break;
325
326 default:
327 return;
328 }
329
330 ispctrl_val |= ((shift/2) << ISPCTRL_SHIFT_SHIFT) & ISPCTRL_SHIFT_MASK;
331
332 isp_reg_writel(isp, ispctrl_val, OMAP3_ISP_IOMEM_MAIN, ISP_CTRL);
333}
334
335void omap3isp_hist_dma_done(struct isp_device *isp)
336{
337 if (omap3isp_ccdc_busy(&isp->isp_ccdc) ||
338 omap3isp_stat_pcr_busy(&isp->isp_hist)) {
339 /* Histogram cannot be enabled in this frame anymore */
340 atomic_set(&isp->isp_hist.buf_err, 1);
341 dev_dbg(isp->dev, "hist: Out of synchronization with "
342 "CCDC. Ignoring next buffer.\n");
343 }
344}
345
346static inline void isp_isr_dbg(struct isp_device *isp, u32 irqstatus)
347{
348 static const char *name[] = {
349 "CSIA_IRQ",
350 "res1",
351 "res2",
352 "CSIB_LCM_IRQ",
353 "CSIB_IRQ",
354 "res5",
355 "res6",
356 "res7",
357 "CCDC_VD0_IRQ",
358 "CCDC_VD1_IRQ",
359 "CCDC_VD2_IRQ",
360 "CCDC_ERR_IRQ",
361 "H3A_AF_DONE_IRQ",
362 "H3A_AWB_DONE_IRQ",
363 "res14",
364 "res15",
365 "HIST_DONE_IRQ",
366 "CCDC_LSC_DONE",
367 "CCDC_LSC_PREFETCH_COMPLETED",
368 "CCDC_LSC_PREFETCH_ERROR",
369 "PRV_DONE_IRQ",
370 "CBUFF_IRQ",
371 "res22",
372 "res23",
373 "RSZ_DONE_IRQ",
374 "OVF_IRQ",
375 "res26",
376 "res27",
377 "MMU_ERR_IRQ",
378 "OCP_ERR_IRQ",
379 "SEC_ERR_IRQ",
380 "HS_VS_IRQ",
381 };
382 int i;
383
384 dev_dbg(isp->dev, "ISP IRQ: ");
385
386 for (i = 0; i < ARRAY_SIZE(name); i++) {
387 if ((1 << i) & irqstatus)
388 printk(KERN_CONT "%s ", name[i]);
389 }
390 printk(KERN_CONT "\n");
391}
392
393static void isp_isr_sbl(struct isp_device *isp)
394{
395 struct device *dev = isp->dev;
396 struct isp_pipeline *pipe;
397 u32 sbl_pcr;
398
399 /*
400 * Handle shared buffer logic overflows for video buffers.
401 * ISPSBL_PCR_CCDCPRV_2_RSZ_OVF can be safely ignored.
402 */
403 sbl_pcr = isp_reg_readl(isp, OMAP3_ISP_IOMEM_SBL, ISPSBL_PCR);
404 isp_reg_writel(isp, sbl_pcr, OMAP3_ISP_IOMEM_SBL, ISPSBL_PCR);
405 sbl_pcr &= ~ISPSBL_PCR_CCDCPRV_2_RSZ_OVF;
406
407 if (sbl_pcr)
408 dev_dbg(dev, "SBL overflow (PCR = 0x%08x)\n", sbl_pcr);
409
410 if (sbl_pcr & ISPSBL_PCR_CSIB_WBL_OVF) {
411 pipe = to_isp_pipeline(&isp->isp_ccp2.subdev.entity);
412 if (pipe != NULL)
413 pipe->error = true;
414 }
415
416 if (sbl_pcr & ISPSBL_PCR_CSIA_WBL_OVF) {
417 pipe = to_isp_pipeline(&isp->isp_csi2a.subdev.entity);
418 if (pipe != NULL)
419 pipe->error = true;
420 }
421
422 if (sbl_pcr & ISPSBL_PCR_CCDC_WBL_OVF) {
423 pipe = to_isp_pipeline(&isp->isp_ccdc.subdev.entity);
424 if (pipe != NULL)
425 pipe->error = true;
426 }
427
428 if (sbl_pcr & ISPSBL_PCR_PRV_WBL_OVF) {
429 pipe = to_isp_pipeline(&isp->isp_prev.subdev.entity);
430 if (pipe != NULL)
431 pipe->error = true;
432 }
433
434 if (sbl_pcr & (ISPSBL_PCR_RSZ1_WBL_OVF
435 | ISPSBL_PCR_RSZ2_WBL_OVF
436 | ISPSBL_PCR_RSZ3_WBL_OVF
437 | ISPSBL_PCR_RSZ4_WBL_OVF)) {
438 pipe = to_isp_pipeline(&isp->isp_res.subdev.entity);
439 if (pipe != NULL)
440 pipe->error = true;
441 }
442
443 if (sbl_pcr & ISPSBL_PCR_H3A_AF_WBL_OVF)
444 omap3isp_stat_sbl_overflow(&isp->isp_af);
445
446 if (sbl_pcr & ISPSBL_PCR_H3A_AEAWB_WBL_OVF)
447 omap3isp_stat_sbl_overflow(&isp->isp_aewb);
448}
449
450/*
451 * isp_isr - Interrupt Service Routine for Camera ISP module.
452 * @irq: Not used currently.
453 * @_isp: Pointer to the OMAP3 ISP device
454 *
455 * Handles the corresponding callback if plugged in.
456 *
457 * Returns IRQ_HANDLED when IRQ was correctly handled, or IRQ_NONE when the
458 * IRQ wasn't handled.
459 */
460static irqreturn_t isp_isr(int irq, void *_isp)
461{
462 static const u32 ccdc_events = IRQ0STATUS_CCDC_LSC_PREF_ERR_IRQ |
463 IRQ0STATUS_CCDC_LSC_DONE_IRQ |
464 IRQ0STATUS_CCDC_VD0_IRQ |
465 IRQ0STATUS_CCDC_VD1_IRQ |
466 IRQ0STATUS_HS_VS_IRQ;
467 struct isp_device *isp = _isp;
468 u32 irqstatus;
469
470 irqstatus = isp_reg_readl(isp, OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0STATUS);
471 isp_reg_writel(isp, irqstatus, OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0STATUS);
472
473 isp_isr_sbl(isp);
474
475 if (irqstatus & IRQ0STATUS_CSIA_IRQ)
476 omap3isp_csi2_isr(&isp->isp_csi2a);
477
478 if (irqstatus & IRQ0STATUS_CSIB_IRQ)
479 omap3isp_ccp2_isr(&isp->isp_ccp2);
480
481 if (irqstatus & IRQ0STATUS_CCDC_VD0_IRQ) {
482 if (isp->isp_ccdc.output & CCDC_OUTPUT_PREVIEW)
483 omap3isp_preview_isr_frame_sync(&isp->isp_prev);
484 if (isp->isp_ccdc.output & CCDC_OUTPUT_RESIZER)
485 omap3isp_resizer_isr_frame_sync(&isp->isp_res);
486 omap3isp_stat_isr_frame_sync(&isp->isp_aewb);
487 omap3isp_stat_isr_frame_sync(&isp->isp_af);
488 omap3isp_stat_isr_frame_sync(&isp->isp_hist);
489 }
490
491 if (irqstatus & ccdc_events)
492 omap3isp_ccdc_isr(&isp->isp_ccdc, irqstatus & ccdc_events);
493
494 if (irqstatus & IRQ0STATUS_PRV_DONE_IRQ) {
495 if (isp->isp_prev.output & PREVIEW_OUTPUT_RESIZER)
496 omap3isp_resizer_isr_frame_sync(&isp->isp_res);
497 omap3isp_preview_isr(&isp->isp_prev);
498 }
499
500 if (irqstatus & IRQ0STATUS_RSZ_DONE_IRQ)
501 omap3isp_resizer_isr(&isp->isp_res);
502
503 if (irqstatus & IRQ0STATUS_H3A_AWB_DONE_IRQ)
504 omap3isp_stat_isr(&isp->isp_aewb);
505
506 if (irqstatus & IRQ0STATUS_H3A_AF_DONE_IRQ)
507 omap3isp_stat_isr(&isp->isp_af);
508
509 if (irqstatus & IRQ0STATUS_HIST_DONE_IRQ)
510 omap3isp_stat_isr(&isp->isp_hist);
511
512 omap3isp_flush(isp);
513
514#if defined(DEBUG) && defined(ISP_ISR_DEBUG)
515 isp_isr_dbg(isp, irqstatus);
516#endif
517
518 return IRQ_HANDLED;
519}
520
521/* -----------------------------------------------------------------------------
522 * Pipeline power management
523 *
524 * Entities must be powered up when part of a pipeline that contains at least
525 * one open video device node.
526 *
527 * To achieve this use the entity use_count field to track the number of users.
528 * For entities corresponding to video device nodes the use_count field stores
529 * the users count of the node. For entities corresponding to subdevs the
530 * use_count field stores the total number of users of all video device nodes
531 * in the pipeline.
532 *
533 * The omap3isp_pipeline_pm_use() function must be called in the open() and
534 * close() handlers of video device nodes. It increments or decrements the use
535 * count of all subdev entities in the pipeline.
536 *
537 * To react to link management on powered pipelines, the link setup notification
538 * callback updates the use count of all entities in the source and sink sides
539 * of the link.
540 */
541
542/*
543 * isp_pipeline_pm_use_count - Count the number of users of a pipeline
544 * @entity: The entity
545 *
546 * Return the total number of users of all video device nodes in the pipeline.
547 */
548static int isp_pipeline_pm_use_count(struct media_entity *entity)
549{
550 struct media_entity_graph graph;
551 int use = 0;
552
553 media_entity_graph_walk_start(&graph, entity);
554
555 while ((entity = media_entity_graph_walk_next(&graph))) {
556 if (media_entity_type(entity) == MEDIA_ENT_T_DEVNODE)
557 use += entity->use_count;
558 }
559
560 return use;
561}
562
563/*
564 * isp_pipeline_pm_power_one - Apply power change to an entity
565 * @entity: The entity
566 * @change: Use count change
567 *
568 * Change the entity use count by @change. If the entity is a subdev update its
569 * power state by calling the core::s_power operation when the use count goes
570 * from 0 to != 0 or from != 0 to 0.
571 *
572 * Return 0 on success or a negative error code on failure.
573 */
574static int isp_pipeline_pm_power_one(struct media_entity *entity, int change)
575{
576 struct v4l2_subdev *subdev;
577 int ret;
578
579 subdev = media_entity_type(entity) == MEDIA_ENT_T_V4L2_SUBDEV
580 ? media_entity_to_v4l2_subdev(entity) : NULL;
581
582 if (entity->use_count == 0 && change > 0 && subdev != NULL) {
583 ret = v4l2_subdev_call(subdev, core, s_power, 1);
584 if (ret < 0 && ret != -ENOIOCTLCMD)
585 return ret;
586 }
587
588 entity->use_count += change;
589 WARN_ON(entity->use_count < 0);
590
591 if (entity->use_count == 0 && change < 0 && subdev != NULL)
592 v4l2_subdev_call(subdev, core, s_power, 0);
593
594 return 0;
595}
596
597/*
598 * isp_pipeline_pm_power - Apply power change to all entities in a pipeline
599 * @entity: The entity
600 * @change: Use count change
601 *
602 * Walk the pipeline to update the use count and the power state of all non-node
603 * entities.
604 *
605 * Return 0 on success or a negative error code on failure.
606 */
607static int isp_pipeline_pm_power(struct media_entity *entity, int change)
608{
609 struct media_entity_graph graph;
610 struct media_entity *first = entity;
611 int ret = 0;
612
613 if (!change)
614 return 0;
615
616 media_entity_graph_walk_start(&graph, entity);
617
618 while (!ret && (entity = media_entity_graph_walk_next(&graph)))
619 if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE)
620 ret = isp_pipeline_pm_power_one(entity, change);
621
622 if (!ret)
623 return 0;
624
625 media_entity_graph_walk_start(&graph, first);
626
627 while ((first = media_entity_graph_walk_next(&graph))
628 && first != entity)
629 if (media_entity_type(first) != MEDIA_ENT_T_DEVNODE)
630 isp_pipeline_pm_power_one(first, -change);
631
632 return ret;
633}
634
635/*
636 * omap3isp_pipeline_pm_use - Update the use count of an entity
637 * @entity: The entity
638 * @use: Use (1) or stop using (0) the entity
639 *
640 * Update the use count of all entities in the pipeline and power entities on or
641 * off accordingly.
642 *
643 * Return 0 on success or a negative error code on failure. Powering entities
644 * off is assumed to never fail. No failure can occur when the use parameter is
645 * set to 0.
646 */
647int omap3isp_pipeline_pm_use(struct media_entity *entity, int use)
648{
649 int change = use ? 1 : -1;
650 int ret;
651
652 mutex_lock(&entity->parent->graph_mutex);
653
654 /* Apply use count to node. */
655 entity->use_count += change;
656 WARN_ON(entity->use_count < 0);
657
658 /* Apply power change to connected non-nodes. */
659 ret = isp_pipeline_pm_power(entity, change);
660 if (ret < 0)
661 entity->use_count -= change;
662
663 mutex_unlock(&entity->parent->graph_mutex);
664
665 return ret;
666}
667
668/*
669 * isp_pipeline_link_notify - Link management notification callback
670 * @source: Pad at the start of the link
671 * @sink: Pad at the end of the link
672 * @flags: New link flags that will be applied
673 *
674 * React to link management on powered pipelines by updating the use count of
675 * all entities in the source and sink sides of the link. Entities are powered
676 * on or off accordingly.
677 *
678 * Return 0 on success or a negative error code on failure. Powering entities
679 * off is assumed to never fail. This function will not fail for disconnection
680 * events.
681 */
682static int isp_pipeline_link_notify(struct media_pad *source,
683 struct media_pad *sink, u32 flags)
684{
685 int source_use = isp_pipeline_pm_use_count(source->entity);
686 int sink_use = isp_pipeline_pm_use_count(sink->entity);
687 int ret;
688
689 if (!(flags & MEDIA_LNK_FL_ENABLED)) {
690 /* Powering off entities is assumed to never fail. */
691 isp_pipeline_pm_power(source->entity, -sink_use);
692 isp_pipeline_pm_power(sink->entity, -source_use);
693 return 0;
694 }
695
696 ret = isp_pipeline_pm_power(source->entity, sink_use);
697 if (ret < 0)
698 return ret;
699
700 ret = isp_pipeline_pm_power(sink->entity, source_use);
701 if (ret < 0)
702 isp_pipeline_pm_power(source->entity, -sink_use);
703
704 return ret;
705}
706
707/* -----------------------------------------------------------------------------
708 * Pipeline stream management
709 */
710
711/*
712 * isp_pipeline_enable - Enable streaming on a pipeline
713 * @pipe: ISP pipeline
714 * @mode: Stream mode (single shot or continuous)
715 *
716 * Walk the entities chain starting at the pipeline output video node and start
717 * all modules in the chain in the given mode.
718 *
719 * Return 0 if successful, or the return value of the failed video::s_stream
720 * operation otherwise.
721 */
722static int isp_pipeline_enable(struct isp_pipeline *pipe,
723 enum isp_pipeline_stream_state mode)
724{
725 struct isp_device *isp = pipe->output->isp;
726 struct media_entity *entity;
727 struct media_pad *pad;
728 struct v4l2_subdev *subdev;
729 unsigned long flags;
730 int ret;
731
732 /* If the preview engine crashed it might not respond to read/write
733 * operations on the L4 bus. This would result in a bus fault and a
734 * kernel oops. Refuse to start streaming in that case. This check must
735 * be performed before the loop below to avoid starting entities if the
736 * pipeline won't start anyway (those entities would then likely fail to
737 * stop, making the problem worse).
738 */
739 if ((pipe->entities & isp->crashed) &
740 (1U << isp->isp_prev.subdev.entity.id))
741 return -EIO;
742
743 spin_lock_irqsave(&pipe->lock, flags);
744 pipe->state &= ~(ISP_PIPELINE_IDLE_INPUT | ISP_PIPELINE_IDLE_OUTPUT);
745 spin_unlock_irqrestore(&pipe->lock, flags);
746
747 pipe->do_propagation = false;
748
749 entity = &pipe->output->video.entity;
750 while (1) {
751 pad = &entity->pads[0];
752 if (!(pad->flags & MEDIA_PAD_FL_SINK))
753 break;
754
755 pad = media_entity_remote_source(pad);
756 if (pad == NULL ||
757 media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
758 break;
759
760 entity = pad->entity;
761 subdev = media_entity_to_v4l2_subdev(entity);
762
763 ret = v4l2_subdev_call(subdev, video, s_stream, mode);
764 if (ret < 0 && ret != -ENOIOCTLCMD)
765 return ret;
766
767 if (subdev == &isp->isp_ccdc.subdev) {
768 v4l2_subdev_call(&isp->isp_aewb.subdev, video,
769 s_stream, mode);
770 v4l2_subdev_call(&isp->isp_af.subdev, video,
771 s_stream, mode);
772 v4l2_subdev_call(&isp->isp_hist.subdev, video,
773 s_stream, mode);
774 pipe->do_propagation = true;
775 }
776 }
777
778 return 0;
779}
780
781static int isp_pipeline_wait_resizer(struct isp_device *isp)
782{
783 return omap3isp_resizer_busy(&isp->isp_res);
784}
785
786static int isp_pipeline_wait_preview(struct isp_device *isp)
787{
788 return omap3isp_preview_busy(&isp->isp_prev);
789}
790
791static int isp_pipeline_wait_ccdc(struct isp_device *isp)
792{
793 return omap3isp_stat_busy(&isp->isp_af)
794 || omap3isp_stat_busy(&isp->isp_aewb)
795 || omap3isp_stat_busy(&isp->isp_hist)
796 || omap3isp_ccdc_busy(&isp->isp_ccdc);
797}
798
799#define ISP_STOP_TIMEOUT msecs_to_jiffies(1000)
800
801static int isp_pipeline_wait(struct isp_device *isp,
802 int(*busy)(struct isp_device *isp))
803{
804 unsigned long timeout = jiffies + ISP_STOP_TIMEOUT;
805
806 while (!time_after(jiffies, timeout)) {
807 if (!busy(isp))
808 return 0;
809 }
810
811 return 1;
812}
813
814/*
815 * isp_pipeline_disable - Disable streaming on a pipeline
816 * @pipe: ISP pipeline
817 *
818 * Walk the entities chain starting at the pipeline output video node and stop
819 * all modules in the chain. Wait synchronously for the modules to be stopped if
820 * necessary.
821 *
822 * Return 0 if all modules have been properly stopped, or -ETIMEDOUT if a module
823 * can't be stopped (in which case a software reset of the ISP is probably
824 * necessary).
825 */
826static int isp_pipeline_disable(struct isp_pipeline *pipe)
827{
828 struct isp_device *isp = pipe->output->isp;
829 struct media_entity *entity;
830 struct media_pad *pad;
831 struct v4l2_subdev *subdev;
832 int failure = 0;
833 int ret;
834
835 /*
836 * We need to stop all the modules after CCDC first or they'll
837 * never stop since they may not get a full frame from CCDC.
838 */
839 entity = &pipe->output->video.entity;
840 while (1) {
841 pad = &entity->pads[0];
842 if (!(pad->flags & MEDIA_PAD_FL_SINK))
843 break;
844
845 pad = media_entity_remote_source(pad);
846 if (pad == NULL ||
847 media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
848 break;
849
850 entity = pad->entity;
851 subdev = media_entity_to_v4l2_subdev(entity);
852
853 if (subdev == &isp->isp_ccdc.subdev) {
854 v4l2_subdev_call(&isp->isp_aewb.subdev,
855 video, s_stream, 0);
856 v4l2_subdev_call(&isp->isp_af.subdev,
857 video, s_stream, 0);
858 v4l2_subdev_call(&isp->isp_hist.subdev,
859 video, s_stream, 0);
860 }
861
862 v4l2_subdev_call(subdev, video, s_stream, 0);
863
864 if (subdev == &isp->isp_res.subdev)
865 ret = isp_pipeline_wait(isp, isp_pipeline_wait_resizer);
866 else if (subdev == &isp->isp_prev.subdev)
867 ret = isp_pipeline_wait(isp, isp_pipeline_wait_preview);
868 else if (subdev == &isp->isp_ccdc.subdev)
869 ret = isp_pipeline_wait(isp, isp_pipeline_wait_ccdc);
870 else
871 ret = 0;
872
873 if (ret) {
874 dev_info(isp->dev, "Unable to stop %s\n", subdev->name);
875 /* If the entity failed to stopped, assume it has
876 * crashed. Mark it as such, the ISP will be reset when
877 * applications will release it.
878 */
879 isp->crashed |= 1U << subdev->entity.id;
880 failure = -ETIMEDOUT;
881 }
882 }
883
884 return failure;
885}
886
887/*
888 * omap3isp_pipeline_set_stream - Enable/disable streaming on a pipeline
889 * @pipe: ISP pipeline
890 * @state: Stream state (stopped, single shot or continuous)
891 *
892 * Set the pipeline to the given stream state. Pipelines can be started in
893 * single-shot or continuous mode.
894 *
895 * Return 0 if successful, or the return value of the failed video::s_stream
896 * operation otherwise. The pipeline state is not updated when the operation
897 * fails, except when stopping the pipeline.
898 */
899int omap3isp_pipeline_set_stream(struct isp_pipeline *pipe,
900 enum isp_pipeline_stream_state state)
901{
902 int ret;
903
904 if (state == ISP_PIPELINE_STREAM_STOPPED)
905 ret = isp_pipeline_disable(pipe);
906 else
907 ret = isp_pipeline_enable(pipe, state);
908
909 if (ret == 0 || state == ISP_PIPELINE_STREAM_STOPPED)
910 pipe->stream_state = state;
911
912 return ret;
913}
914
915/*
916 * isp_pipeline_resume - Resume streaming on a pipeline
917 * @pipe: ISP pipeline
918 *
919 * Resume video output and input and re-enable pipeline.
920 */
921static void isp_pipeline_resume(struct isp_pipeline *pipe)
922{
923 int singleshot = pipe->stream_state == ISP_PIPELINE_STREAM_SINGLESHOT;
924
925 omap3isp_video_resume(pipe->output, !singleshot);
926 if (singleshot)
927 omap3isp_video_resume(pipe->input, 0);
928 isp_pipeline_enable(pipe, pipe->stream_state);
929}
930
931/*
932 * isp_pipeline_suspend - Suspend streaming on a pipeline
933 * @pipe: ISP pipeline
934 *
935 * Suspend pipeline.
936 */
937static void isp_pipeline_suspend(struct isp_pipeline *pipe)
938{
939 isp_pipeline_disable(pipe);
940}
941
942/*
943 * isp_pipeline_is_last - Verify if entity has an enabled link to the output
944 * video node
945 * @me: ISP module's media entity
946 *
947 * Returns 1 if the entity has an enabled link to the output video node or 0
948 * otherwise. It's true only while pipeline can have no more than one output
949 * node.
950 */
951static int isp_pipeline_is_last(struct media_entity *me)
952{
953 struct isp_pipeline *pipe;
954 struct media_pad *pad;
955
956 if (!me->pipe)
957 return 0;
958 pipe = to_isp_pipeline(me);
959 if (pipe->stream_state == ISP_PIPELINE_STREAM_STOPPED)
960 return 0;
961 pad = media_entity_remote_source(&pipe->output->pad);
962 return pad->entity == me;
963}
964
965/*
966 * isp_suspend_module_pipeline - Suspend pipeline to which belongs the module
967 * @me: ISP module's media entity
968 *
969 * Suspend the whole pipeline if module's entity has an enabled link to the
970 * output video node. It works only while pipeline can have no more than one
971 * output node.
972 */
973static void isp_suspend_module_pipeline(struct media_entity *me)
974{
975 if (isp_pipeline_is_last(me))
976 isp_pipeline_suspend(to_isp_pipeline(me));
977}
978
979/*
980 * isp_resume_module_pipeline - Resume pipeline to which belongs the module
981 * @me: ISP module's media entity
982 *
983 * Resume the whole pipeline if module's entity has an enabled link to the
984 * output video node. It works only while pipeline can have no more than one
985 * output node.
986 */
987static void isp_resume_module_pipeline(struct media_entity *me)
988{
989 if (isp_pipeline_is_last(me))
990 isp_pipeline_resume(to_isp_pipeline(me));
991}
992
993/*
994 * isp_suspend_modules - Suspend ISP submodules.
995 * @isp: OMAP3 ISP device
996 *
997 * Returns 0 if suspend left in idle state all the submodules properly,
998 * or returns 1 if a general Reset is required to suspend the submodules.
999 */
1000static int isp_suspend_modules(struct isp_device *isp)
1001{
1002 unsigned long timeout;
1003
1004 omap3isp_stat_suspend(&isp->isp_aewb);
1005 omap3isp_stat_suspend(&isp->isp_af);
1006 omap3isp_stat_suspend(&isp->isp_hist);
1007 isp_suspend_module_pipeline(&isp->isp_res.subdev.entity);
1008 isp_suspend_module_pipeline(&isp->isp_prev.subdev.entity);
1009 isp_suspend_module_pipeline(&isp->isp_ccdc.subdev.entity);
1010 isp_suspend_module_pipeline(&isp->isp_csi2a.subdev.entity);
1011 isp_suspend_module_pipeline(&isp->isp_ccp2.subdev.entity);
1012
1013 timeout = jiffies + ISP_STOP_TIMEOUT;
1014 while (omap3isp_stat_busy(&isp->isp_af)
1015 || omap3isp_stat_busy(&isp->isp_aewb)
1016 || omap3isp_stat_busy(&isp->isp_hist)
1017 || omap3isp_preview_busy(&isp->isp_prev)
1018 || omap3isp_resizer_busy(&isp->isp_res)
1019 || omap3isp_ccdc_busy(&isp->isp_ccdc)) {
1020 if (time_after(jiffies, timeout)) {
1021 dev_info(isp->dev, "can't stop modules.\n");
1022 return 1;
1023 }
1024 msleep(1);
1025 }
1026
1027 return 0;
1028}
1029
1030/*
1031 * isp_resume_modules - Resume ISP submodules.
1032 * @isp: OMAP3 ISP device
1033 */
1034static void isp_resume_modules(struct isp_device *isp)
1035{
1036 omap3isp_stat_resume(&isp->isp_aewb);
1037 omap3isp_stat_resume(&isp->isp_af);
1038 omap3isp_stat_resume(&isp->isp_hist);
1039 isp_resume_module_pipeline(&isp->isp_res.subdev.entity);
1040 isp_resume_module_pipeline(&isp->isp_prev.subdev.entity);
1041 isp_resume_module_pipeline(&isp->isp_ccdc.subdev.entity);
1042 isp_resume_module_pipeline(&isp->isp_csi2a.subdev.entity);
1043 isp_resume_module_pipeline(&isp->isp_ccp2.subdev.entity);
1044}
1045
1046/*
1047 * isp_reset - Reset ISP with a timeout wait for idle.
1048 * @isp: OMAP3 ISP device
1049 */
1050static int isp_reset(struct isp_device *isp)
1051{
1052 unsigned long timeout = 0;
1053
1054 isp_reg_writel(isp,
1055 isp_reg_readl(isp, OMAP3_ISP_IOMEM_MAIN, ISP_SYSCONFIG)
1056 | ISP_SYSCONFIG_SOFTRESET,
1057 OMAP3_ISP_IOMEM_MAIN, ISP_SYSCONFIG);
1058 while (!(isp_reg_readl(isp, OMAP3_ISP_IOMEM_MAIN,
1059 ISP_SYSSTATUS) & 0x1)) {
1060 if (timeout++ > 10000) {
1061 dev_alert(isp->dev, "cannot reset ISP\n");
1062 return -ETIMEDOUT;
1063 }
1064 udelay(1);
1065 }
1066
1067 isp->crashed = 0;
1068 return 0;
1069}
1070
1071/*
1072 * isp_save_context - Saves the values of the ISP module registers.
1073 * @isp: OMAP3 ISP device
1074 * @reg_list: Structure containing pairs of register address and value to
1075 * modify on OMAP.
1076 */
1077static void
1078isp_save_context(struct isp_device *isp, struct isp_reg *reg_list)
1079{
1080 struct isp_reg *next = reg_list;
1081
1082 for (; next->reg != ISP_TOK_TERM; next++)
1083 next->val = isp_reg_readl(isp, next->mmio_range, next->reg);
1084}
1085
1086/*
1087 * isp_restore_context - Restores the values of the ISP module registers.
1088 * @isp: OMAP3 ISP device
1089 * @reg_list: Structure containing pairs of register address and value to
1090 * modify on OMAP.
1091 */
1092static void
1093isp_restore_context(struct isp_device *isp, struct isp_reg *reg_list)
1094{
1095 struct isp_reg *next = reg_list;
1096
1097 for (; next->reg != ISP_TOK_TERM; next++)
1098 isp_reg_writel(isp, next->val, next->mmio_range, next->reg);
1099}
1100
1101/*
1102 * isp_save_ctx - Saves ISP, CCDC, HIST, H3A, PREV, RESZ & MMU context.
1103 * @isp: OMAP3 ISP device
1104 *
1105 * Routine for saving the context of each module in the ISP.
1106 * CCDC, HIST, H3A, PREV, RESZ and MMU.
1107 */
1108static void isp_save_ctx(struct isp_device *isp)
1109{
1110 isp_save_context(isp, isp_reg_list);
1111 omap_iommu_save_ctx(isp->dev);
1112}
1113
1114/*
1115 * isp_restore_ctx - Restores ISP, CCDC, HIST, H3A, PREV, RESZ & MMU context.
1116 * @isp: OMAP3 ISP device
1117 *
1118 * Routine for restoring the context of each module in the ISP.
1119 * CCDC, HIST, H3A, PREV, RESZ and MMU.
1120 */
1121static void isp_restore_ctx(struct isp_device *isp)
1122{
1123 isp_restore_context(isp, isp_reg_list);
1124 omap_iommu_restore_ctx(isp->dev);
1125 omap3isp_ccdc_restore_context(isp);
1126 omap3isp_preview_restore_context(isp);
1127}
1128
1129/* -----------------------------------------------------------------------------
1130 * SBL resources management
1131 */
1132#define OMAP3_ISP_SBL_READ (OMAP3_ISP_SBL_CSI1_READ | \
1133 OMAP3_ISP_SBL_CCDC_LSC_READ | \
1134 OMAP3_ISP_SBL_PREVIEW_READ | \
1135 OMAP3_ISP_SBL_RESIZER_READ)
1136#define OMAP3_ISP_SBL_WRITE (OMAP3_ISP_SBL_CSI1_WRITE | \
1137 OMAP3_ISP_SBL_CSI2A_WRITE | \
1138 OMAP3_ISP_SBL_CSI2C_WRITE | \
1139 OMAP3_ISP_SBL_CCDC_WRITE | \
1140 OMAP3_ISP_SBL_PREVIEW_WRITE)
1141
1142void omap3isp_sbl_enable(struct isp_device *isp, enum isp_sbl_resource res)
1143{
1144 u32 sbl = 0;
1145
1146 isp->sbl_resources |= res;
1147
1148 if (isp->sbl_resources & OMAP3_ISP_SBL_CSI1_READ)
1149 sbl |= ISPCTRL_SBL_SHARED_RPORTA;
1150
1151 if (isp->sbl_resources & OMAP3_ISP_SBL_CCDC_LSC_READ)
1152 sbl |= ISPCTRL_SBL_SHARED_RPORTB;
1153
1154 if (isp->sbl_resources & OMAP3_ISP_SBL_CSI2C_WRITE)
1155 sbl |= ISPCTRL_SBL_SHARED_WPORTC;
1156
1157 if (isp->sbl_resources & OMAP3_ISP_SBL_RESIZER_WRITE)
1158 sbl |= ISPCTRL_SBL_WR0_RAM_EN;
1159
1160 if (isp->sbl_resources & OMAP3_ISP_SBL_WRITE)
1161 sbl |= ISPCTRL_SBL_WR1_RAM_EN;
1162
1163 if (isp->sbl_resources & OMAP3_ISP_SBL_READ)
1164 sbl |= ISPCTRL_SBL_RD_RAM_EN;
1165
1166 isp_reg_set(isp, OMAP3_ISP_IOMEM_MAIN, ISP_CTRL, sbl);
1167}
1168
1169void omap3isp_sbl_disable(struct isp_device *isp, enum isp_sbl_resource res)
1170{
1171 u32 sbl = 0;
1172
1173 isp->sbl_resources &= ~res;
1174
1175 if (!(isp->sbl_resources & OMAP3_ISP_SBL_CSI1_READ))
1176 sbl |= ISPCTRL_SBL_SHARED_RPORTA;
1177
1178 if (!(isp->sbl_resources & OMAP3_ISP_SBL_CCDC_LSC_READ))
1179 sbl |= ISPCTRL_SBL_SHARED_RPORTB;
1180
1181 if (!(isp->sbl_resources & OMAP3_ISP_SBL_CSI2C_WRITE))
1182 sbl |= ISPCTRL_SBL_SHARED_WPORTC;
1183
1184 if (!(isp->sbl_resources & OMAP3_ISP_SBL_RESIZER_WRITE))
1185 sbl |= ISPCTRL_SBL_WR0_RAM_EN;
1186
1187 if (!(isp->sbl_resources & OMAP3_ISP_SBL_WRITE))
1188 sbl |= ISPCTRL_SBL_WR1_RAM_EN;
1189
1190 if (!(isp->sbl_resources & OMAP3_ISP_SBL_READ))
1191 sbl |= ISPCTRL_SBL_RD_RAM_EN;
1192
1193 isp_reg_clr(isp, OMAP3_ISP_IOMEM_MAIN, ISP_CTRL, sbl);
1194}
1195
1196/*
1197 * isp_module_sync_idle - Helper to sync module with its idle state
1198 * @me: ISP submodule's media entity
1199 * @wait: ISP submodule's wait queue for streamoff/interrupt synchronization
1200 * @stopping: flag which tells module wants to stop
1201 *
1202 * This function checks if ISP submodule needs to wait for next interrupt. If
1203 * yes, makes the caller to sleep while waiting for such event.
1204 */
1205int omap3isp_module_sync_idle(struct media_entity *me, wait_queue_head_t *wait,
1206 atomic_t *stopping)
1207{
1208 struct isp_pipeline *pipe = to_isp_pipeline(me);
1209
1210 if (pipe->stream_state == ISP_PIPELINE_STREAM_STOPPED ||
1211 (pipe->stream_state == ISP_PIPELINE_STREAM_SINGLESHOT &&
1212 !isp_pipeline_ready(pipe)))
1213 return 0;
1214
1215 /*
1216 * atomic_set() doesn't include memory barrier on ARM platform for SMP
1217 * scenario. We'll call it here to avoid race conditions.
1218 */
1219 atomic_set(stopping, 1);
1220 smp_mb();
1221
1222 /*
1223 * If module is the last one, it's writing to memory. In this case,
1224 * it's necessary to check if the module is already paused due to
1225 * DMA queue underrun or if it has to wait for next interrupt to be
1226 * idle.
1227 * If it isn't the last one, the function won't sleep but *stopping
1228 * will still be set to warn next submodule caller's interrupt the
1229 * module wants to be idle.
1230 */
1231 if (isp_pipeline_is_last(me)) {
1232 struct isp_video *video = pipe->output;
1233 unsigned long flags;
1234 spin_lock_irqsave(&video->queue->irqlock, flags);
1235 if (video->dmaqueue_flags & ISP_VIDEO_DMAQUEUE_UNDERRUN) {
1236 spin_unlock_irqrestore(&video->queue->irqlock, flags);
1237 atomic_set(stopping, 0);
1238 smp_mb();
1239 return 0;
1240 }
1241 spin_unlock_irqrestore(&video->queue->irqlock, flags);
1242 if (!wait_event_timeout(*wait, !atomic_read(stopping),
1243 msecs_to_jiffies(1000))) {
1244 atomic_set(stopping, 0);
1245 smp_mb();
1246 return -ETIMEDOUT;
1247 }
1248 }
1249
1250 return 0;
1251}
1252
1253/*
1254 * omap3isp_module_sync_is_stopped - Helper to verify if module was stopping
1255 * @wait: ISP submodule's wait queue for streamoff/interrupt synchronization
1256 * @stopping: flag which tells module wants to stop
1257 *
1258 * This function checks if ISP submodule was stopping. In case of yes, it
1259 * notices the caller by setting stopping to 0 and waking up the wait queue.
1260 * Returns 1 if it was stopping or 0 otherwise.
1261 */
1262int omap3isp_module_sync_is_stopping(wait_queue_head_t *wait,
1263 atomic_t *stopping)
1264{
1265 if (atomic_cmpxchg(stopping, 1, 0)) {
1266 wake_up(wait);
1267 return 1;
1268 }
1269
1270 return 0;
1271}
1272
1273/* --------------------------------------------------------------------------
1274 * Clock management
1275 */
1276
1277#define ISPCTRL_CLKS_MASK (ISPCTRL_H3A_CLK_EN | \
1278 ISPCTRL_HIST_CLK_EN | \
1279 ISPCTRL_RSZ_CLK_EN | \
1280 (ISPCTRL_CCDC_CLK_EN | ISPCTRL_CCDC_RAM_EN) | \
1281 (ISPCTRL_PREV_CLK_EN | ISPCTRL_PREV_RAM_EN))
1282
1283static void __isp_subclk_update(struct isp_device *isp)
1284{
1285 u32 clk = 0;
1286
1287 /* AEWB and AF share the same clock. */
1288 if (isp->subclk_resources &
1289 (OMAP3_ISP_SUBCLK_AEWB | OMAP3_ISP_SUBCLK_AF))
1290 clk |= ISPCTRL_H3A_CLK_EN;
1291
1292 if (isp->subclk_resources & OMAP3_ISP_SUBCLK_HIST)
1293 clk |= ISPCTRL_HIST_CLK_EN;
1294
1295 if (isp->subclk_resources & OMAP3_ISP_SUBCLK_RESIZER)
1296 clk |= ISPCTRL_RSZ_CLK_EN;
1297
1298 /* NOTE: For CCDC & Preview submodules, we need to affect internal
1299 * RAM as well.
1300 */
1301 if (isp->subclk_resources & OMAP3_ISP_SUBCLK_CCDC)
1302 clk |= ISPCTRL_CCDC_CLK_EN | ISPCTRL_CCDC_RAM_EN;
1303
1304 if (isp->subclk_resources & OMAP3_ISP_SUBCLK_PREVIEW)
1305 clk |= ISPCTRL_PREV_CLK_EN | ISPCTRL_PREV_RAM_EN;
1306
1307 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_MAIN, ISP_CTRL,
1308 ISPCTRL_CLKS_MASK, clk);
1309}
1310
1311void omap3isp_subclk_enable(struct isp_device *isp,
1312 enum isp_subclk_resource res)
1313{
1314 isp->subclk_resources |= res;
1315
1316 __isp_subclk_update(isp);
1317}
1318
1319void omap3isp_subclk_disable(struct isp_device *isp,
1320 enum isp_subclk_resource res)
1321{
1322 isp->subclk_resources &= ~res;
1323
1324 __isp_subclk_update(isp);
1325}
1326
1327/*
1328 * isp_enable_clocks - Enable ISP clocks
1329 * @isp: OMAP3 ISP device
1330 *
1331 * Return 0 if successful, or clk_enable return value if any of tthem fails.
1332 */
1333static int isp_enable_clocks(struct isp_device *isp)
1334{
1335 int r;
1336 unsigned long rate;
1337 int divisor;
1338
1339 /*
1340 * cam_mclk clock chain:
1341 * dpll4 -> dpll4_m5 -> dpll4_m5x2 -> cam_mclk
1342 *
1343 * In OMAP3630 dpll4_m5x2 != 2 x dpll4_m5 but both are
1344 * set to the same value. Hence the rate set for dpll4_m5
1345 * has to be twice of what is set on OMAP3430 to get
1346 * the required value for cam_mclk
1347 */
1348 if (cpu_is_omap3630())
1349 divisor = 1;
1350 else
1351 divisor = 2;
1352
1353 r = clk_enable(isp->clock[ISP_CLK_CAM_ICK]);
1354 if (r) {
1355 dev_err(isp->dev, "clk_enable cam_ick failed\n");
1356 goto out_clk_enable_ick;
1357 }
1358 r = clk_set_rate(isp->clock[ISP_CLK_DPLL4_M5_CK],
1359 CM_CAM_MCLK_HZ/divisor);
1360 if (r) {
1361 dev_err(isp->dev, "clk_set_rate for dpll4_m5_ck failed\n");
1362 goto out_clk_enable_mclk;
1363 }
1364 r = clk_enable(isp->clock[ISP_CLK_CAM_MCLK]);
1365 if (r) {
1366 dev_err(isp->dev, "clk_enable cam_mclk failed\n");
1367 goto out_clk_enable_mclk;
1368 }
1369 rate = clk_get_rate(isp->clock[ISP_CLK_CAM_MCLK]);
1370 if (rate != CM_CAM_MCLK_HZ)
1371 dev_warn(isp->dev, "unexpected cam_mclk rate:\n"
1372 " expected : %d\n"
1373 " actual : %ld\n", CM_CAM_MCLK_HZ, rate);
1374 r = clk_enable(isp->clock[ISP_CLK_CSI2_FCK]);
1375 if (r) {
1376 dev_err(isp->dev, "clk_enable csi2_fck failed\n");
1377 goto out_clk_enable_csi2_fclk;
1378 }
1379 return 0;
1380
1381out_clk_enable_csi2_fclk:
1382 clk_disable(isp->clock[ISP_CLK_CAM_MCLK]);
1383out_clk_enable_mclk:
1384 clk_disable(isp->clock[ISP_CLK_CAM_ICK]);
1385out_clk_enable_ick:
1386 return r;
1387}
1388
1389/*
1390 * isp_disable_clocks - Disable ISP clocks
1391 * @isp: OMAP3 ISP device
1392 */
1393static void isp_disable_clocks(struct isp_device *isp)
1394{
1395 clk_disable(isp->clock[ISP_CLK_CAM_ICK]);
1396 clk_disable(isp->clock[ISP_CLK_CAM_MCLK]);
1397 clk_disable(isp->clock[ISP_CLK_CSI2_FCK]);
1398}
1399
1400static const char *isp_clocks[] = {
1401 "cam_ick",
1402 "cam_mclk",
1403 "dpll4_m5_ck",
1404 "csi2_96m_fck",
1405 "l3_ick",
1406};
1407
1408static void isp_put_clocks(struct isp_device *isp)
1409{
1410 unsigned int i;
1411
1412 for (i = 0; i < ARRAY_SIZE(isp_clocks); ++i) {
1413 if (isp->clock[i]) {
1414 clk_put(isp->clock[i]);
1415 isp->clock[i] = NULL;
1416 }
1417 }
1418}
1419
1420static int isp_get_clocks(struct isp_device *isp)
1421{
1422 struct clk *clk;
1423 unsigned int i;
1424
1425 for (i = 0; i < ARRAY_SIZE(isp_clocks); ++i) {
1426 clk = clk_get(isp->dev, isp_clocks[i]);
1427 if (IS_ERR(clk)) {
1428 dev_err(isp->dev, "clk_get %s failed\n", isp_clocks[i]);
1429 isp_put_clocks(isp);
1430 return PTR_ERR(clk);
1431 }
1432
1433 isp->clock[i] = clk;
1434 }
1435
1436 return 0;
1437}
1438
1439/*
1440 * omap3isp_get - Acquire the ISP resource.
1441 *
1442 * Initializes the clocks for the first acquire.
1443 *
1444 * Increment the reference count on the ISP. If the first reference is taken,
1445 * enable clocks and power-up all submodules.
1446 *
1447 * Return a pointer to the ISP device structure, or NULL if an error occurred.
1448 */
1449static struct isp_device *__omap3isp_get(struct isp_device *isp, bool irq)
1450{
1451 struct isp_device *__isp = isp;
1452
1453 if (isp == NULL)
1454 return NULL;
1455
1456 mutex_lock(&isp->isp_mutex);
1457 if (isp->ref_count > 0)
1458 goto out;
1459
1460 if (isp_enable_clocks(isp) < 0) {
1461 __isp = NULL;
1462 goto out;
1463 }
1464
1465 /* We don't want to restore context before saving it! */
1466 if (isp->has_context)
1467 isp_restore_ctx(isp);
1468
1469 if (irq)
1470 isp_enable_interrupts(isp);
1471
1472out:
1473 if (__isp != NULL)
1474 isp->ref_count++;
1475 mutex_unlock(&isp->isp_mutex);
1476
1477 return __isp;
1478}
1479
1480struct isp_device *omap3isp_get(struct isp_device *isp)
1481{
1482 return __omap3isp_get(isp, true);
1483}
1484
1485/*
1486 * omap3isp_put - Release the ISP
1487 *
1488 * Decrement the reference count on the ISP. If the last reference is released,
1489 * power-down all submodules, disable clocks and free temporary buffers.
1490 */
1491void omap3isp_put(struct isp_device *isp)
1492{
1493 if (isp == NULL)
1494 return;
1495
1496 mutex_lock(&isp->isp_mutex);
1497 BUG_ON(isp->ref_count == 0);
1498 if (--isp->ref_count == 0) {
1499 isp_disable_interrupts(isp);
1500 if (isp->domain) {
1501 isp_save_ctx(isp);
1502 isp->has_context = 1;
1503 }
1504 /* Reset the ISP if an entity has failed to stop. This is the
1505 * only way to recover from such conditions.
1506 */
1507 if (isp->crashed)
1508 isp_reset(isp);
1509 isp_disable_clocks(isp);
1510 }
1511 mutex_unlock(&isp->isp_mutex);
1512}
1513
1514/* --------------------------------------------------------------------------
1515 * Platform device driver
1516 */
1517
1518/*
1519 * omap3isp_print_status - Prints the values of the ISP Control Module registers
1520 * @isp: OMAP3 ISP device
1521 */
1522#define ISP_PRINT_REGISTER(isp, name)\
1523 dev_dbg(isp->dev, "###ISP " #name "=0x%08x\n", \
1524 isp_reg_readl(isp, OMAP3_ISP_IOMEM_MAIN, ISP_##name))
1525#define SBL_PRINT_REGISTER(isp, name)\
1526 dev_dbg(isp->dev, "###SBL " #name "=0x%08x\n", \
1527 isp_reg_readl(isp, OMAP3_ISP_IOMEM_SBL, ISPSBL_##name))
1528
1529void omap3isp_print_status(struct isp_device *isp)
1530{
1531 dev_dbg(isp->dev, "-------------ISP Register dump--------------\n");
1532
1533 ISP_PRINT_REGISTER(isp, SYSCONFIG);
1534 ISP_PRINT_REGISTER(isp, SYSSTATUS);
1535 ISP_PRINT_REGISTER(isp, IRQ0ENABLE);
1536 ISP_PRINT_REGISTER(isp, IRQ0STATUS);
1537 ISP_PRINT_REGISTER(isp, TCTRL_GRESET_LENGTH);
1538 ISP_PRINT_REGISTER(isp, TCTRL_PSTRB_REPLAY);
1539 ISP_PRINT_REGISTER(isp, CTRL);
1540 ISP_PRINT_REGISTER(isp, TCTRL_CTRL);
1541 ISP_PRINT_REGISTER(isp, TCTRL_FRAME);
1542 ISP_PRINT_REGISTER(isp, TCTRL_PSTRB_DELAY);
1543 ISP_PRINT_REGISTER(isp, TCTRL_STRB_DELAY);
1544 ISP_PRINT_REGISTER(isp, TCTRL_SHUT_DELAY);
1545 ISP_PRINT_REGISTER(isp, TCTRL_PSTRB_LENGTH);
1546 ISP_PRINT_REGISTER(isp, TCTRL_STRB_LENGTH);
1547 ISP_PRINT_REGISTER(isp, TCTRL_SHUT_LENGTH);
1548
1549 SBL_PRINT_REGISTER(isp, PCR);
1550 SBL_PRINT_REGISTER(isp, SDR_REQ_EXP);
1551
1552 dev_dbg(isp->dev, "--------------------------------------------\n");
1553}
1554
1555#ifdef CONFIG_PM
1556
1557/*
1558 * Power management support.
1559 *
1560 * As the ISP can't properly handle an input video stream interruption on a non
1561 * frame boundary, the ISP pipelines need to be stopped before sensors get
1562 * suspended. However, as suspending the sensors can require a running clock,
1563 * which can be provided by the ISP, the ISP can't be completely suspended
1564 * before the sensor.
1565 *
1566 * To solve this problem power management support is split into prepare/complete
1567 * and suspend/resume operations. The pipelines are stopped in prepare() and the
1568 * ISP clocks get disabled in suspend(). Similarly, the clocks are reenabled in
1569 * resume(), and the the pipelines are restarted in complete().
1570 *
1571 * TODO: PM dependencies between the ISP and sensors are not modeled explicitly
1572 * yet.
1573 */
1574static int isp_pm_prepare(struct device *dev)
1575{
1576 struct isp_device *isp = dev_get_drvdata(dev);
1577 int reset;
1578
1579 WARN_ON(mutex_is_locked(&isp->isp_mutex));
1580
1581 if (isp->ref_count == 0)
1582 return 0;
1583
1584 reset = isp_suspend_modules(isp);
1585 isp_disable_interrupts(isp);
1586 isp_save_ctx(isp);
1587 if (reset)
1588 isp_reset(isp);
1589
1590 return 0;
1591}
1592
1593static int isp_pm_suspend(struct device *dev)
1594{
1595 struct isp_device *isp = dev_get_drvdata(dev);
1596
1597 WARN_ON(mutex_is_locked(&isp->isp_mutex));
1598
1599 if (isp->ref_count)
1600 isp_disable_clocks(isp);
1601
1602 return 0;
1603}
1604
1605static int isp_pm_resume(struct device *dev)
1606{
1607 struct isp_device *isp = dev_get_drvdata(dev);
1608
1609 if (isp->ref_count == 0)
1610 return 0;
1611
1612 return isp_enable_clocks(isp);
1613}
1614
1615static void isp_pm_complete(struct device *dev)
1616{
1617 struct isp_device *isp = dev_get_drvdata(dev);
1618
1619 if (isp->ref_count == 0)
1620 return;
1621
1622 isp_restore_ctx(isp);
1623 isp_enable_interrupts(isp);
1624 isp_resume_modules(isp);
1625}
1626
1627#else
1628
1629#define isp_pm_prepare NULL
1630#define isp_pm_suspend NULL
1631#define isp_pm_resume NULL
1632#define isp_pm_complete NULL
1633
1634#endif /* CONFIG_PM */
1635
1636static void isp_unregister_entities(struct isp_device *isp)
1637{
1638 omap3isp_csi2_unregister_entities(&isp->isp_csi2a);
1639 omap3isp_ccp2_unregister_entities(&isp->isp_ccp2);
1640 omap3isp_ccdc_unregister_entities(&isp->isp_ccdc);
1641 omap3isp_preview_unregister_entities(&isp->isp_prev);
1642 omap3isp_resizer_unregister_entities(&isp->isp_res);
1643 omap3isp_stat_unregister_entities(&isp->isp_aewb);
1644 omap3isp_stat_unregister_entities(&isp->isp_af);
1645 omap3isp_stat_unregister_entities(&isp->isp_hist);
1646
1647 v4l2_device_unregister(&isp->v4l2_dev);
1648 media_device_unregister(&isp->media_dev);
1649}
1650
1651/*
1652 * isp_register_subdev_group - Register a group of subdevices
1653 * @isp: OMAP3 ISP device
1654 * @board_info: I2C subdevs board information array
1655 *
1656 * Register all I2C subdevices in the board_info array. The array must be
1657 * terminated by a NULL entry, and the first entry must be the sensor.
1658 *
1659 * Return a pointer to the sensor media entity if it has been successfully
1660 * registered, or NULL otherwise.
1661 */
1662static struct v4l2_subdev *
1663isp_register_subdev_group(struct isp_device *isp,
1664 struct isp_subdev_i2c_board_info *board_info)
1665{
1666 struct v4l2_subdev *sensor = NULL;
1667 unsigned int first;
1668
1669 if (board_info->board_info == NULL)
1670 return NULL;
1671
1672 for (first = 1; board_info->board_info; ++board_info, first = 0) {
1673 struct v4l2_subdev *subdev;
1674 struct i2c_adapter *adapter;
1675
1676 adapter = i2c_get_adapter(board_info->i2c_adapter_id);
1677 if (adapter == NULL) {
1678 printk(KERN_ERR "%s: Unable to get I2C adapter %d for "
1679 "device %s\n", __func__,
1680 board_info->i2c_adapter_id,
1681 board_info->board_info->type);
1682 continue;
1683 }
1684
1685 subdev = v4l2_i2c_new_subdev_board(&isp->v4l2_dev, adapter,
1686 board_info->board_info, NULL);
1687 if (subdev == NULL) {
1688 printk(KERN_ERR "%s: Unable to register subdev %s\n",
1689 __func__, board_info->board_info->type);
1690 continue;
1691 }
1692
1693 if (first)
1694 sensor = subdev;
1695 }
1696
1697 return sensor;
1698}
1699
1700static int isp_register_entities(struct isp_device *isp)
1701{
1702 struct isp_platform_data *pdata = isp->pdata;
1703 struct isp_v4l2_subdevs_group *subdevs;
1704 int ret;
1705
1706 isp->media_dev.dev = isp->dev;
1707 strlcpy(isp->media_dev.model, "TI OMAP3 ISP",
1708 sizeof(isp->media_dev.model));
1709 isp->media_dev.hw_revision = isp->revision;
1710 isp->media_dev.link_notify = isp_pipeline_link_notify;
1711 ret = media_device_register(&isp->media_dev);
1712 if (ret < 0) {
1713 printk(KERN_ERR "%s: Media device registration failed (%d)\n",
1714 __func__, ret);
1715 return ret;
1716 }
1717
1718 isp->v4l2_dev.mdev = &isp->media_dev;
1719 ret = v4l2_device_register(isp->dev, &isp->v4l2_dev);
1720 if (ret < 0) {
1721 printk(KERN_ERR "%s: V4L2 device registration failed (%d)\n",
1722 __func__, ret);
1723 goto done;
1724 }
1725
1726 /* Register internal entities */
1727 ret = omap3isp_ccp2_register_entities(&isp->isp_ccp2, &isp->v4l2_dev);
1728 if (ret < 0)
1729 goto done;
1730
1731 ret = omap3isp_csi2_register_entities(&isp->isp_csi2a, &isp->v4l2_dev);
1732 if (ret < 0)
1733 goto done;
1734
1735 ret = omap3isp_ccdc_register_entities(&isp->isp_ccdc, &isp->v4l2_dev);
1736 if (ret < 0)
1737 goto done;
1738
1739 ret = omap3isp_preview_register_entities(&isp->isp_prev,
1740 &isp->v4l2_dev);
1741 if (ret < 0)
1742 goto done;
1743
1744 ret = omap3isp_resizer_register_entities(&isp->isp_res, &isp->v4l2_dev);
1745 if (ret < 0)
1746 goto done;
1747
1748 ret = omap3isp_stat_register_entities(&isp->isp_aewb, &isp->v4l2_dev);
1749 if (ret < 0)
1750 goto done;
1751
1752 ret = omap3isp_stat_register_entities(&isp->isp_af, &isp->v4l2_dev);
1753 if (ret < 0)
1754 goto done;
1755
1756 ret = omap3isp_stat_register_entities(&isp->isp_hist, &isp->v4l2_dev);
1757 if (ret < 0)
1758 goto done;
1759
1760 /* Register external entities */
1761 for (subdevs = pdata->subdevs; subdevs && subdevs->subdevs; ++subdevs) {
1762 struct v4l2_subdev *sensor;
1763 struct media_entity *input;
1764 unsigned int flags;
1765 unsigned int pad;
1766
1767 sensor = isp_register_subdev_group(isp, subdevs->subdevs);
1768 if (sensor == NULL)
1769 continue;
1770
1771 sensor->host_priv = subdevs;
1772
1773 /* Connect the sensor to the correct interface module. Parallel
1774 * sensors are connected directly to the CCDC, while serial
1775 * sensors are connected to the CSI2a, CCP2b or CSI2c receiver
1776 * through CSIPHY1 or CSIPHY2.
1777 */
1778 switch (subdevs->interface) {
1779 case ISP_INTERFACE_PARALLEL:
1780 input = &isp->isp_ccdc.subdev.entity;
1781 pad = CCDC_PAD_SINK;
1782 flags = 0;
1783 break;
1784
1785 case ISP_INTERFACE_CSI2A_PHY2:
1786 input = &isp->isp_csi2a.subdev.entity;
1787 pad = CSI2_PAD_SINK;
1788 flags = MEDIA_LNK_FL_IMMUTABLE
1789 | MEDIA_LNK_FL_ENABLED;
1790 break;
1791
1792 case ISP_INTERFACE_CCP2B_PHY1:
1793 case ISP_INTERFACE_CCP2B_PHY2:
1794 input = &isp->isp_ccp2.subdev.entity;
1795 pad = CCP2_PAD_SINK;
1796 flags = 0;
1797 break;
1798
1799 case ISP_INTERFACE_CSI2C_PHY1:
1800 input = &isp->isp_csi2c.subdev.entity;
1801 pad = CSI2_PAD_SINK;
1802 flags = MEDIA_LNK_FL_IMMUTABLE
1803 | MEDIA_LNK_FL_ENABLED;
1804 break;
1805
1806 default:
1807 printk(KERN_ERR "%s: invalid interface type %u\n",
1808 __func__, subdevs->interface);
1809 ret = -EINVAL;
1810 goto done;
1811 }
1812
1813 ret = media_entity_create_link(&sensor->entity, 0, input, pad,
1814 flags);
1815 if (ret < 0)
1816 goto done;
1817 }
1818
1819 ret = v4l2_device_register_subdev_nodes(&isp->v4l2_dev);
1820
1821done:
1822 if (ret < 0)
1823 isp_unregister_entities(isp);
1824
1825 return ret;
1826}
1827
1828static void isp_cleanup_modules(struct isp_device *isp)
1829{
1830 omap3isp_h3a_aewb_cleanup(isp);
1831 omap3isp_h3a_af_cleanup(isp);
1832 omap3isp_hist_cleanup(isp);
1833 omap3isp_resizer_cleanup(isp);
1834 omap3isp_preview_cleanup(isp);
1835 omap3isp_ccdc_cleanup(isp);
1836 omap3isp_ccp2_cleanup(isp);
1837 omap3isp_csi2_cleanup(isp);
1838}
1839
1840static int isp_initialize_modules(struct isp_device *isp)
1841{
1842 int ret;
1843
1844 ret = omap3isp_csiphy_init(isp);
1845 if (ret < 0) {
1846 dev_err(isp->dev, "CSI PHY initialization failed\n");
1847 goto error_csiphy;
1848 }
1849
1850 ret = omap3isp_csi2_init(isp);
1851 if (ret < 0) {
1852 dev_err(isp->dev, "CSI2 initialization failed\n");
1853 goto error_csi2;
1854 }
1855
1856 ret = omap3isp_ccp2_init(isp);
1857 if (ret < 0) {
1858 dev_err(isp->dev, "CCP2 initialization failed\n");
1859 goto error_ccp2;
1860 }
1861
1862 ret = omap3isp_ccdc_init(isp);
1863 if (ret < 0) {
1864 dev_err(isp->dev, "CCDC initialization failed\n");
1865 goto error_ccdc;
1866 }
1867
1868 ret = omap3isp_preview_init(isp);
1869 if (ret < 0) {
1870 dev_err(isp->dev, "Preview initialization failed\n");
1871 goto error_preview;
1872 }
1873
1874 ret = omap3isp_resizer_init(isp);
1875 if (ret < 0) {
1876 dev_err(isp->dev, "Resizer initialization failed\n");
1877 goto error_resizer;
1878 }
1879
1880 ret = omap3isp_hist_init(isp);
1881 if (ret < 0) {
1882 dev_err(isp->dev, "Histogram initialization failed\n");
1883 goto error_hist;
1884 }
1885
1886 ret = omap3isp_h3a_aewb_init(isp);
1887 if (ret < 0) {
1888 dev_err(isp->dev, "H3A AEWB initialization failed\n");
1889 goto error_h3a_aewb;
1890 }
1891
1892 ret = omap3isp_h3a_af_init(isp);
1893 if (ret < 0) {
1894 dev_err(isp->dev, "H3A AF initialization failed\n");
1895 goto error_h3a_af;
1896 }
1897
1898 /* Connect the submodules. */
1899 ret = media_entity_create_link(
1900 &isp->isp_csi2a.subdev.entity, CSI2_PAD_SOURCE,
1901 &isp->isp_ccdc.subdev.entity, CCDC_PAD_SINK, 0);
1902 if (ret < 0)
1903 goto error_link;
1904
1905 ret = media_entity_create_link(
1906 &isp->isp_ccp2.subdev.entity, CCP2_PAD_SOURCE,
1907 &isp->isp_ccdc.subdev.entity, CCDC_PAD_SINK, 0);
1908 if (ret < 0)
1909 goto error_link;
1910
1911 ret = media_entity_create_link(
1912 &isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP,
1913 &isp->isp_prev.subdev.entity, PREV_PAD_SINK, 0);
1914 if (ret < 0)
1915 goto error_link;
1916
1917 ret = media_entity_create_link(
1918 &isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_OF,
1919 &isp->isp_res.subdev.entity, RESZ_PAD_SINK, 0);
1920 if (ret < 0)
1921 goto error_link;
1922
1923 ret = media_entity_create_link(
1924 &isp->isp_prev.subdev.entity, PREV_PAD_SOURCE,
1925 &isp->isp_res.subdev.entity, RESZ_PAD_SINK, 0);
1926 if (ret < 0)
1927 goto error_link;
1928
1929 ret = media_entity_create_link(
1930 &isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP,
1931 &isp->isp_aewb.subdev.entity, 0,
1932 MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE);
1933 if (ret < 0)
1934 goto error_link;
1935
1936 ret = media_entity_create_link(
1937 &isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP,
1938 &isp->isp_af.subdev.entity, 0,
1939 MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE);
1940 if (ret < 0)
1941 goto error_link;
1942
1943 ret = media_entity_create_link(
1944 &isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP,
1945 &isp->isp_hist.subdev.entity, 0,
1946 MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE);
1947 if (ret < 0)
1948 goto error_link;
1949
1950 return 0;
1951
1952error_link:
1953 omap3isp_h3a_af_cleanup(isp);
1954error_h3a_af:
1955 omap3isp_h3a_aewb_cleanup(isp);
1956error_h3a_aewb:
1957 omap3isp_hist_cleanup(isp);
1958error_hist:
1959 omap3isp_resizer_cleanup(isp);
1960error_resizer:
1961 omap3isp_preview_cleanup(isp);
1962error_preview:
1963 omap3isp_ccdc_cleanup(isp);
1964error_ccdc:
1965 omap3isp_ccp2_cleanup(isp);
1966error_ccp2:
1967 omap3isp_csi2_cleanup(isp);
1968error_csi2:
1969error_csiphy:
1970 return ret;
1971}
1972
1973/*
1974 * isp_remove - Remove ISP platform device
1975 * @pdev: Pointer to ISP platform device
1976 *
1977 * Always returns 0.
1978 */
1979static int __devexit isp_remove(struct platform_device *pdev)
1980{
1981 struct isp_device *isp = platform_get_drvdata(pdev);
1982 int i;
1983
1984 isp_unregister_entities(isp);
1985 isp_cleanup_modules(isp);
1986
1987 __omap3isp_get(isp, false);
1988 iommu_detach_device(isp->domain, &pdev->dev);
1989 iommu_domain_free(isp->domain);
1990 isp->domain = NULL;
1991 omap3isp_put(isp);
1992
1993 free_irq(isp->irq_num, isp);
1994 isp_put_clocks(isp);
1995
1996 for (i = 0; i < OMAP3_ISP_IOMEM_LAST; i++) {
1997 if (isp->mmio_base[i]) {
1998 iounmap(isp->mmio_base[i]);
1999 isp->mmio_base[i] = NULL;
2000 }
2001
2002 if (isp->mmio_base_phys[i]) {
2003 release_mem_region(isp->mmio_base_phys[i],
2004 isp->mmio_size[i]);
2005 isp->mmio_base_phys[i] = 0;
2006 }
2007 }
2008
2009 regulator_put(isp->isp_csiphy1.vdd);
2010 regulator_put(isp->isp_csiphy2.vdd);
2011 kfree(isp);
2012
2013 return 0;
2014}
2015
2016static int isp_map_mem_resource(struct platform_device *pdev,
2017 struct isp_device *isp,
2018 enum isp_mem_resources res)
2019{
2020 struct resource *mem;
2021
2022 /* request the mem region for the camera registers */
2023
2024 mem = platform_get_resource(pdev, IORESOURCE_MEM, res);
2025 if (!mem) {
2026 dev_err(isp->dev, "no mem resource?\n");
2027 return -ENODEV;
2028 }
2029
2030 if (!request_mem_region(mem->start, resource_size(mem), pdev->name)) {
2031 dev_err(isp->dev,
2032 "cannot reserve camera register I/O region\n");
2033 return -ENODEV;
2034 }
2035 isp->mmio_base_phys[res] = mem->start;
2036 isp->mmio_size[res] = resource_size(mem);
2037
2038 /* map the region */
2039 isp->mmio_base[res] = ioremap_nocache(isp->mmio_base_phys[res],
2040 isp->mmio_size[res]);
2041 if (!isp->mmio_base[res]) {
2042 dev_err(isp->dev, "cannot map camera register I/O region\n");
2043 return -ENODEV;
2044 }
2045
2046 return 0;
2047}
2048
2049/*
2050 * isp_probe - Probe ISP platform device
2051 * @pdev: Pointer to ISP platform device
2052 *
2053 * Returns 0 if successful,
2054 * -ENOMEM if no memory available,
2055 * -ENODEV if no platform device resources found
2056 * or no space for remapping registers,
2057 * -EINVAL if couldn't install ISR,
2058 * or clk_get return error value.
2059 */
2060static int __devinit isp_probe(struct platform_device *pdev)
2061{
2062 struct isp_platform_data *pdata = pdev->dev.platform_data;
2063 struct isp_device *isp;
2064 int ret;
2065 int i, m;
2066
2067 if (pdata == NULL)
2068 return -EINVAL;
2069
2070 isp = kzalloc(sizeof(*isp), GFP_KERNEL);
2071 if (!isp) {
2072 dev_err(&pdev->dev, "could not allocate memory\n");
2073 return -ENOMEM;
2074 }
2075
2076 isp->autoidle = autoidle;
2077 isp->platform_cb.set_xclk = isp_set_xclk;
2078
2079 mutex_init(&isp->isp_mutex);
2080 spin_lock_init(&isp->stat_lock);
2081
2082 isp->dev = &pdev->dev;
2083 isp->pdata = pdata;
2084 isp->ref_count = 0;
2085
2086 isp->raw_dmamask = DMA_BIT_MASK(32);
2087 isp->dev->dma_mask = &isp->raw_dmamask;
2088 isp->dev->coherent_dma_mask = DMA_BIT_MASK(32);
2089
2090 platform_set_drvdata(pdev, isp);
2091
2092 /* Regulators */
2093 isp->isp_csiphy1.vdd = regulator_get(&pdev->dev, "VDD_CSIPHY1");
2094 isp->isp_csiphy2.vdd = regulator_get(&pdev->dev, "VDD_CSIPHY2");
2095
2096 /* Clocks */
2097 ret = isp_map_mem_resource(pdev, isp, OMAP3_ISP_IOMEM_MAIN);
2098 if (ret < 0)
2099 goto error;
2100
2101 ret = isp_get_clocks(isp);
2102 if (ret < 0)
2103 goto error;
2104
2105 if (__omap3isp_get(isp, false) == NULL)
2106 goto error;
2107
2108 ret = isp_reset(isp);
2109 if (ret < 0)
2110 goto error_isp;
2111
2112 /* Memory resources */
2113 isp->revision = isp_reg_readl(isp, OMAP3_ISP_IOMEM_MAIN, ISP_REVISION);
2114 dev_info(isp->dev, "Revision %d.%d found\n",
2115 (isp->revision & 0xf0) >> 4, isp->revision & 0x0f);
2116
2117 for (m = 0; m < ARRAY_SIZE(isp_res_maps); m++)
2118 if (isp->revision == isp_res_maps[m].isp_rev)
2119 break;
2120
2121 if (m == ARRAY_SIZE(isp_res_maps)) {
2122 dev_err(isp->dev, "No resource map found for ISP rev %d.%d\n",
2123 (isp->revision & 0xf0) >> 4, isp->revision & 0xf);
2124 ret = -ENODEV;
2125 goto error_isp;
2126 }
2127
2128 for (i = 1; i < OMAP3_ISP_IOMEM_LAST; i++) {
2129 if (isp_res_maps[m].map & 1 << i) {
2130 ret = isp_map_mem_resource(pdev, isp, i);
2131 if (ret)
2132 goto error_isp;
2133 }
2134 }
2135
2136 isp->domain = iommu_domain_alloc(pdev->dev.bus);
2137 if (!isp->domain) {
2138 dev_err(isp->dev, "can't alloc iommu domain\n");
2139 ret = -ENOMEM;
2140 goto error_isp;
2141 }
2142
2143 ret = iommu_attach_device(isp->domain, &pdev->dev);
2144 if (ret) {
2145 dev_err(&pdev->dev, "can't attach iommu device: %d\n", ret);
2146 goto free_domain;
2147 }
2148
2149 /* Interrupt */
2150 isp->irq_num = platform_get_irq(pdev, 0);
2151 if (isp->irq_num <= 0) {
2152 dev_err(isp->dev, "No IRQ resource\n");
2153 ret = -ENODEV;
2154 goto detach_dev;
2155 }
2156
2157 if (request_irq(isp->irq_num, isp_isr, IRQF_SHARED, "OMAP3 ISP", isp)) {
2158 dev_err(isp->dev, "Unable to request IRQ\n");
2159 ret = -EINVAL;
2160 goto detach_dev;
2161 }
2162
2163 /* Entities */
2164 ret = isp_initialize_modules(isp);
2165 if (ret < 0)
2166 goto error_irq;
2167
2168 ret = isp_register_entities(isp);
2169 if (ret < 0)
2170 goto error_modules;
2171
2172 isp_core_init(isp, 1);
2173 omap3isp_put(isp);
2174
2175 return 0;
2176
2177error_modules:
2178 isp_cleanup_modules(isp);
2179error_irq:
2180 free_irq(isp->irq_num, isp);
2181detach_dev:
2182 iommu_detach_device(isp->domain, &pdev->dev);
2183free_domain:
2184 iommu_domain_free(isp->domain);
2185error_isp:
2186 omap3isp_put(isp);
2187error:
2188 isp_put_clocks(isp);
2189
2190 for (i = 0; i < OMAP3_ISP_IOMEM_LAST; i++) {
2191 if (isp->mmio_base[i]) {
2192 iounmap(isp->mmio_base[i]);
2193 isp->mmio_base[i] = NULL;
2194 }
2195
2196 if (isp->mmio_base_phys[i]) {
2197 release_mem_region(isp->mmio_base_phys[i],
2198 isp->mmio_size[i]);
2199 isp->mmio_base_phys[i] = 0;
2200 }
2201 }
2202 regulator_put(isp->isp_csiphy2.vdd);
2203 regulator_put(isp->isp_csiphy1.vdd);
2204 platform_set_drvdata(pdev, NULL);
2205
2206 mutex_destroy(&isp->isp_mutex);
2207 kfree(isp);
2208
2209 return ret;
2210}
2211
2212static const struct dev_pm_ops omap3isp_pm_ops = {
2213 .prepare = isp_pm_prepare,
2214 .suspend = isp_pm_suspend,
2215 .resume = isp_pm_resume,
2216 .complete = isp_pm_complete,
2217};
2218
2219static struct platform_device_id omap3isp_id_table[] = {
2220 { "omap3isp", 0 },
2221 { },
2222};
2223MODULE_DEVICE_TABLE(platform, omap3isp_id_table);
2224
2225static struct platform_driver omap3isp_driver = {
2226 .probe = isp_probe,
2227 .remove = __devexit_p(isp_remove),
2228 .id_table = omap3isp_id_table,
2229 .driver = {
2230 .owner = THIS_MODULE,
2231 .name = "omap3isp",
2232 .pm = &omap3isp_pm_ops,
2233 },
2234};
2235
2236module_platform_driver(omap3isp_driver);
2237
2238MODULE_AUTHOR("Nokia Corporation");
2239MODULE_DESCRIPTION("TI OMAP3 ISP driver");
2240MODULE_LICENSE("GPL");
2241MODULE_VERSION(ISP_VIDEO_DRIVER_VERSION);
diff --git a/drivers/media/video/omap3isp/isp.h b/drivers/media/video/omap3isp/isp.h
deleted file mode 100644
index 8be7487c326f..000000000000
--- a/drivers/media/video/omap3isp/isp.h
+++ /dev/null
@@ -1,352 +0,0 @@
1/*
2 * isp.h
3 *
4 * TI OMAP3 ISP - Core
5 *
6 * Copyright (C) 2009-2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc.
8 *
9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 * Sakari Ailus <sakari.ailus@iki.fi>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 */
26
27#ifndef OMAP3_ISP_CORE_H
28#define OMAP3_ISP_CORE_H
29
30#include <media/omap3isp.h>
31#include <media/v4l2-device.h>
32#include <linux/device.h>
33#include <linux/io.h>
34#include <linux/platform_device.h>
35#include <linux/wait.h>
36#include <linux/iommu.h>
37#include <plat/iommu.h>
38#include <plat/iovmm.h>
39
40#include "ispstat.h"
41#include "ispccdc.h"
42#include "ispreg.h"
43#include "ispresizer.h"
44#include "isppreview.h"
45#include "ispcsiphy.h"
46#include "ispcsi2.h"
47#include "ispccp2.h"
48
49#define IOMMU_FLAG (IOVMF_ENDIAN_LITTLE | IOVMF_ELSZ_8)
50
51#define ISP_TOK_TERM 0xFFFFFFFF /*
52 * terminating token for ISP
53 * modules reg list
54 */
55#define to_isp_device(ptr_module) \
56 container_of(ptr_module, struct isp_device, isp_##ptr_module)
57#define to_device(ptr_module) \
58 (to_isp_device(ptr_module)->dev)
59
60enum isp_mem_resources {
61 OMAP3_ISP_IOMEM_MAIN,
62 OMAP3_ISP_IOMEM_CCP2,
63 OMAP3_ISP_IOMEM_CCDC,
64 OMAP3_ISP_IOMEM_HIST,
65 OMAP3_ISP_IOMEM_H3A,
66 OMAP3_ISP_IOMEM_PREV,
67 OMAP3_ISP_IOMEM_RESZ,
68 OMAP3_ISP_IOMEM_SBL,
69 OMAP3_ISP_IOMEM_CSI2A_REGS1,
70 OMAP3_ISP_IOMEM_CSIPHY2,
71 OMAP3_ISP_IOMEM_CSI2A_REGS2,
72 OMAP3_ISP_IOMEM_CSI2C_REGS1,
73 OMAP3_ISP_IOMEM_CSIPHY1,
74 OMAP3_ISP_IOMEM_CSI2C_REGS2,
75 OMAP3_ISP_IOMEM_LAST
76};
77
78enum isp_sbl_resource {
79 OMAP3_ISP_SBL_CSI1_READ = 0x1,
80 OMAP3_ISP_SBL_CSI1_WRITE = 0x2,
81 OMAP3_ISP_SBL_CSI2A_WRITE = 0x4,
82 OMAP3_ISP_SBL_CSI2C_WRITE = 0x8,
83 OMAP3_ISP_SBL_CCDC_LSC_READ = 0x10,
84 OMAP3_ISP_SBL_CCDC_WRITE = 0x20,
85 OMAP3_ISP_SBL_PREVIEW_READ = 0x40,
86 OMAP3_ISP_SBL_PREVIEW_WRITE = 0x80,
87 OMAP3_ISP_SBL_RESIZER_READ = 0x100,
88 OMAP3_ISP_SBL_RESIZER_WRITE = 0x200,
89};
90
91enum isp_subclk_resource {
92 OMAP3_ISP_SUBCLK_CCDC = (1 << 0),
93 OMAP3_ISP_SUBCLK_AEWB = (1 << 1),
94 OMAP3_ISP_SUBCLK_AF = (1 << 2),
95 OMAP3_ISP_SUBCLK_HIST = (1 << 3),
96 OMAP3_ISP_SUBCLK_PREVIEW = (1 << 4),
97 OMAP3_ISP_SUBCLK_RESIZER = (1 << 5),
98};
99
100/* ISP: OMAP 34xx ES 1.0 */
101#define ISP_REVISION_1_0 0x10
102/* ISP2: OMAP 34xx ES 2.0, 2.1 and 3.0 */
103#define ISP_REVISION_2_0 0x20
104/* ISP2P: OMAP 36xx */
105#define ISP_REVISION_15_0 0xF0
106
107/*
108 * struct isp_res_mapping - Map ISP io resources to ISP revision.
109 * @isp_rev: ISP_REVISION_x_x
110 * @map: bitmap for enum isp_mem_resources
111 */
112struct isp_res_mapping {
113 u32 isp_rev;
114 u32 map;
115};
116
117/*
118 * struct isp_reg - Structure for ISP register values.
119 * @reg: 32-bit Register address.
120 * @val: 32-bit Register value.
121 */
122struct isp_reg {
123 enum isp_mem_resources mmio_range;
124 u32 reg;
125 u32 val;
126};
127
128struct isp_platform_callback {
129 u32 (*set_xclk)(struct isp_device *isp, u32 xclk, u8 xclksel);
130 int (*csiphy_config)(struct isp_csiphy *phy,
131 struct isp_csiphy_dphy_cfg *dphy,
132 struct isp_csiphy_lanes_cfg *lanes);
133};
134
135/*
136 * struct isp_device - ISP device structure.
137 * @dev: Device pointer specific to the OMAP3 ISP.
138 * @revision: Stores current ISP module revision.
139 * @irq_num: Currently used IRQ number.
140 * @mmio_base: Array with kernel base addresses for ioremapped ISP register
141 * regions.
142 * @mmio_base_phys: Array with physical L4 bus addresses for ISP register
143 * regions.
144 * @mmio_size: Array with ISP register regions size in bytes.
145 * @raw_dmamask: Raw DMA mask
146 * @stat_lock: Spinlock for handling statistics
147 * @isp_mutex: Mutex for serializing requests to ISP.
148 * @crashed: Bitmask of crashed entities (indexed by entity ID)
149 * @has_context: Context has been saved at least once and can be restored.
150 * @ref_count: Reference count for handling multiple ISP requests.
151 * @cam_ick: Pointer to camera interface clock structure.
152 * @cam_mclk: Pointer to camera functional clock structure.
153 * @dpll4_m5_ck: Pointer to DPLL4 M5 clock structure.
154 * @csi2_fck: Pointer to camera CSI2 complexIO clock structure.
155 * @l3_ick: Pointer to OMAP3 L3 bus interface clock.
156 * @irq: Currently attached ISP ISR callbacks information structure.
157 * @isp_af: Pointer to current settings for ISP AutoFocus SCM.
158 * @isp_hist: Pointer to current settings for ISP Histogram SCM.
159 * @isp_h3a: Pointer to current settings for ISP Auto Exposure and
160 * White Balance SCM.
161 * @isp_res: Pointer to current settings for ISP Resizer.
162 * @isp_prev: Pointer to current settings for ISP Preview.
163 * @isp_ccdc: Pointer to current settings for ISP CCDC.
164 * @iommu: Pointer to requested IOMMU instance for ISP.
165 * @platform_cb: ISP driver callback function pointers for platform code
166 *
167 * This structure is used to store the OMAP ISP Information.
168 */
169struct isp_device {
170 struct v4l2_device v4l2_dev;
171 struct media_device media_dev;
172 struct device *dev;
173 u32 revision;
174
175 /* platform HW resources */
176 struct isp_platform_data *pdata;
177 unsigned int irq_num;
178
179 void __iomem *mmio_base[OMAP3_ISP_IOMEM_LAST];
180 unsigned long mmio_base_phys[OMAP3_ISP_IOMEM_LAST];
181 resource_size_t mmio_size[OMAP3_ISP_IOMEM_LAST];
182
183 u64 raw_dmamask;
184
185 /* ISP Obj */
186 spinlock_t stat_lock; /* common lock for statistic drivers */
187 struct mutex isp_mutex; /* For handling ref_count field */
188 u32 crashed;
189 int has_context;
190 int ref_count;
191 unsigned int autoidle;
192 u32 xclk_divisor[2]; /* Two clocks, a and b. */
193#define ISP_CLK_CAM_ICK 0
194#define ISP_CLK_CAM_MCLK 1
195#define ISP_CLK_DPLL4_M5_CK 2
196#define ISP_CLK_CSI2_FCK 3
197#define ISP_CLK_L3_ICK 4
198 struct clk *clock[5];
199
200 /* ISP modules */
201 struct ispstat isp_af;
202 struct ispstat isp_aewb;
203 struct ispstat isp_hist;
204 struct isp_res_device isp_res;
205 struct isp_prev_device isp_prev;
206 struct isp_ccdc_device isp_ccdc;
207 struct isp_csi2_device isp_csi2a;
208 struct isp_csi2_device isp_csi2c;
209 struct isp_ccp2_device isp_ccp2;
210 struct isp_csiphy isp_csiphy1;
211 struct isp_csiphy isp_csiphy2;
212
213 unsigned int sbl_resources;
214 unsigned int subclk_resources;
215
216 struct iommu_domain *domain;
217
218 struct isp_platform_callback platform_cb;
219};
220
221#define v4l2_dev_to_isp_device(dev) \
222 container_of(dev, struct isp_device, v4l2_dev)
223
224void omap3isp_hist_dma_done(struct isp_device *isp);
225
226void omap3isp_flush(struct isp_device *isp);
227
228int omap3isp_module_sync_idle(struct media_entity *me, wait_queue_head_t *wait,
229 atomic_t *stopping);
230
231int omap3isp_module_sync_is_stopping(wait_queue_head_t *wait,
232 atomic_t *stopping);
233
234int omap3isp_pipeline_set_stream(struct isp_pipeline *pipe,
235 enum isp_pipeline_stream_state state);
236void omap3isp_configure_bridge(struct isp_device *isp,
237 enum ccdc_input_entity input,
238 const struct isp_parallel_platform_data *pdata,
239 unsigned int shift, unsigned int bridge);
240
241struct isp_device *omap3isp_get(struct isp_device *isp);
242void omap3isp_put(struct isp_device *isp);
243
244void omap3isp_print_status(struct isp_device *isp);
245
246void omap3isp_sbl_enable(struct isp_device *isp, enum isp_sbl_resource res);
247void omap3isp_sbl_disable(struct isp_device *isp, enum isp_sbl_resource res);
248
249void omap3isp_subclk_enable(struct isp_device *isp,
250 enum isp_subclk_resource res);
251void omap3isp_subclk_disable(struct isp_device *isp,
252 enum isp_subclk_resource res);
253
254int omap3isp_pipeline_pm_use(struct media_entity *entity, int use);
255
256int omap3isp_register_entities(struct platform_device *pdev,
257 struct v4l2_device *v4l2_dev);
258void omap3isp_unregister_entities(struct platform_device *pdev);
259
260/*
261 * isp_reg_readl - Read value of an OMAP3 ISP register
262 * @dev: Device pointer specific to the OMAP3 ISP.
263 * @isp_mmio_range: Range to which the register offset refers to.
264 * @reg_offset: Register offset to read from.
265 *
266 * Returns an unsigned 32 bit value with the required register contents.
267 */
268static inline
269u32 isp_reg_readl(struct isp_device *isp, enum isp_mem_resources isp_mmio_range,
270 u32 reg_offset)
271{
272 return __raw_readl(isp->mmio_base[isp_mmio_range] + reg_offset);
273}
274
275/*
276 * isp_reg_writel - Write value to an OMAP3 ISP register
277 * @dev: Device pointer specific to the OMAP3 ISP.
278 * @reg_value: 32 bit value to write to the register.
279 * @isp_mmio_range: Range to which the register offset refers to.
280 * @reg_offset: Register offset to write into.
281 */
282static inline
283void isp_reg_writel(struct isp_device *isp, u32 reg_value,
284 enum isp_mem_resources isp_mmio_range, u32 reg_offset)
285{
286 __raw_writel(reg_value, isp->mmio_base[isp_mmio_range] + reg_offset);
287}
288
289/*
290 * isp_reg_and - Clear individual bits in an OMAP3 ISP register
291 * @dev: Device pointer specific to the OMAP3 ISP.
292 * @mmio_range: Range to which the register offset refers to.
293 * @reg: Register offset to work on.
294 * @clr_bits: 32 bit value which would be cleared in the register.
295 */
296static inline
297void isp_reg_clr(struct isp_device *isp, enum isp_mem_resources mmio_range,
298 u32 reg, u32 clr_bits)
299{
300 u32 v = isp_reg_readl(isp, mmio_range, reg);
301
302 isp_reg_writel(isp, v & ~clr_bits, mmio_range, reg);
303}
304
305/*
306 * isp_reg_set - Set individual bits in an OMAP3 ISP register
307 * @dev: Device pointer specific to the OMAP3 ISP.
308 * @mmio_range: Range to which the register offset refers to.
309 * @reg: Register offset to work on.
310 * @set_bits: 32 bit value which would be set in the register.
311 */
312static inline
313void isp_reg_set(struct isp_device *isp, enum isp_mem_resources mmio_range,
314 u32 reg, u32 set_bits)
315{
316 u32 v = isp_reg_readl(isp, mmio_range, reg);
317
318 isp_reg_writel(isp, v | set_bits, mmio_range, reg);
319}
320
321/*
322 * isp_reg_clr_set - Clear and set invidial bits in an OMAP3 ISP register
323 * @dev: Device pointer specific to the OMAP3 ISP.
324 * @mmio_range: Range to which the register offset refers to.
325 * @reg: Register offset to work on.
326 * @clr_bits: 32 bit value which would be cleared in the register.
327 * @set_bits: 32 bit value which would be set in the register.
328 *
329 * The clear operation is done first, and then the set operation.
330 */
331static inline
332void isp_reg_clr_set(struct isp_device *isp, enum isp_mem_resources mmio_range,
333 u32 reg, u32 clr_bits, u32 set_bits)
334{
335 u32 v = isp_reg_readl(isp, mmio_range, reg);
336
337 isp_reg_writel(isp, (v & ~clr_bits) | set_bits, mmio_range, reg);
338}
339
340static inline enum v4l2_buf_type
341isp_pad_buffer_type(const struct v4l2_subdev *subdev, int pad)
342{
343 if (pad >= subdev->entity.num_pads)
344 return 0;
345
346 if (subdev->entity.pads[pad].flags & MEDIA_PAD_FL_SINK)
347 return V4L2_BUF_TYPE_VIDEO_OUTPUT;
348 else
349 return V4L2_BUF_TYPE_VIDEO_CAPTURE;
350}
351
352#endif /* OMAP3_ISP_CORE_H */
diff --git a/drivers/media/video/omap3isp/ispccdc.c b/drivers/media/video/omap3isp/ispccdc.c
deleted file mode 100644
index aa9df9d71a7b..000000000000
--- a/drivers/media/video/omap3isp/ispccdc.c
+++ /dev/null
@@ -1,2583 +0,0 @@
1/*
2 * ispccdc.c
3 *
4 * TI OMAP3 ISP - CCDC module
5 *
6 * Copyright (C) 2009-2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc.
8 *
9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 * Sakari Ailus <sakari.ailus@iki.fi>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 */
26
27#include <linux/module.h>
28#include <linux/uaccess.h>
29#include <linux/delay.h>
30#include <linux/device.h>
31#include <linux/dma-mapping.h>
32#include <linux/mm.h>
33#include <linux/sched.h>
34#include <linux/slab.h>
35#include <media/v4l2-event.h>
36
37#include "isp.h"
38#include "ispreg.h"
39#include "ispccdc.h"
40
41#define CCDC_MIN_WIDTH 32
42#define CCDC_MIN_HEIGHT 32
43
44static struct v4l2_mbus_framefmt *
45__ccdc_get_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh,
46 unsigned int pad, enum v4l2_subdev_format_whence which);
47
48static const unsigned int ccdc_fmts[] = {
49 V4L2_MBUS_FMT_Y8_1X8,
50 V4L2_MBUS_FMT_Y10_1X10,
51 V4L2_MBUS_FMT_Y12_1X12,
52 V4L2_MBUS_FMT_SGRBG8_1X8,
53 V4L2_MBUS_FMT_SRGGB8_1X8,
54 V4L2_MBUS_FMT_SBGGR8_1X8,
55 V4L2_MBUS_FMT_SGBRG8_1X8,
56 V4L2_MBUS_FMT_SGRBG10_1X10,
57 V4L2_MBUS_FMT_SRGGB10_1X10,
58 V4L2_MBUS_FMT_SBGGR10_1X10,
59 V4L2_MBUS_FMT_SGBRG10_1X10,
60 V4L2_MBUS_FMT_SGRBG12_1X12,
61 V4L2_MBUS_FMT_SRGGB12_1X12,
62 V4L2_MBUS_FMT_SBGGR12_1X12,
63 V4L2_MBUS_FMT_SGBRG12_1X12,
64 V4L2_MBUS_FMT_YUYV8_2X8,
65 V4L2_MBUS_FMT_UYVY8_2X8,
66};
67
68/*
69 * ccdc_print_status - Print current CCDC Module register values.
70 * @ccdc: Pointer to ISP CCDC device.
71 *
72 * Also prints other debug information stored in the CCDC module.
73 */
74#define CCDC_PRINT_REGISTER(isp, name)\
75 dev_dbg(isp->dev, "###CCDC " #name "=0x%08x\n", \
76 isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_##name))
77
78static void ccdc_print_status(struct isp_ccdc_device *ccdc)
79{
80 struct isp_device *isp = to_isp_device(ccdc);
81
82 dev_dbg(isp->dev, "-------------CCDC Register dump-------------\n");
83
84 CCDC_PRINT_REGISTER(isp, PCR);
85 CCDC_PRINT_REGISTER(isp, SYN_MODE);
86 CCDC_PRINT_REGISTER(isp, HD_VD_WID);
87 CCDC_PRINT_REGISTER(isp, PIX_LINES);
88 CCDC_PRINT_REGISTER(isp, HORZ_INFO);
89 CCDC_PRINT_REGISTER(isp, VERT_START);
90 CCDC_PRINT_REGISTER(isp, VERT_LINES);
91 CCDC_PRINT_REGISTER(isp, CULLING);
92 CCDC_PRINT_REGISTER(isp, HSIZE_OFF);
93 CCDC_PRINT_REGISTER(isp, SDOFST);
94 CCDC_PRINT_REGISTER(isp, SDR_ADDR);
95 CCDC_PRINT_REGISTER(isp, CLAMP);
96 CCDC_PRINT_REGISTER(isp, DCSUB);
97 CCDC_PRINT_REGISTER(isp, COLPTN);
98 CCDC_PRINT_REGISTER(isp, BLKCMP);
99 CCDC_PRINT_REGISTER(isp, FPC);
100 CCDC_PRINT_REGISTER(isp, FPC_ADDR);
101 CCDC_PRINT_REGISTER(isp, VDINT);
102 CCDC_PRINT_REGISTER(isp, ALAW);
103 CCDC_PRINT_REGISTER(isp, REC656IF);
104 CCDC_PRINT_REGISTER(isp, CFG);
105 CCDC_PRINT_REGISTER(isp, FMTCFG);
106 CCDC_PRINT_REGISTER(isp, FMT_HORZ);
107 CCDC_PRINT_REGISTER(isp, FMT_VERT);
108 CCDC_PRINT_REGISTER(isp, PRGEVEN0);
109 CCDC_PRINT_REGISTER(isp, PRGEVEN1);
110 CCDC_PRINT_REGISTER(isp, PRGODD0);
111 CCDC_PRINT_REGISTER(isp, PRGODD1);
112 CCDC_PRINT_REGISTER(isp, VP_OUT);
113 CCDC_PRINT_REGISTER(isp, LSC_CONFIG);
114 CCDC_PRINT_REGISTER(isp, LSC_INITIAL);
115 CCDC_PRINT_REGISTER(isp, LSC_TABLE_BASE);
116 CCDC_PRINT_REGISTER(isp, LSC_TABLE_OFFSET);
117
118 dev_dbg(isp->dev, "--------------------------------------------\n");
119}
120
121/*
122 * omap3isp_ccdc_busy - Get busy state of the CCDC.
123 * @ccdc: Pointer to ISP CCDC device.
124 */
125int omap3isp_ccdc_busy(struct isp_ccdc_device *ccdc)
126{
127 struct isp_device *isp = to_isp_device(ccdc);
128
129 return isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_PCR) &
130 ISPCCDC_PCR_BUSY;
131}
132
133/* -----------------------------------------------------------------------------
134 * Lens Shading Compensation
135 */
136
137/*
138 * ccdc_lsc_validate_config - Check that LSC configuration is valid.
139 * @ccdc: Pointer to ISP CCDC device.
140 * @lsc_cfg: the LSC configuration to check.
141 *
142 * Returns 0 if the LSC configuration is valid, or -EINVAL if invalid.
143 */
144static int ccdc_lsc_validate_config(struct isp_ccdc_device *ccdc,
145 struct omap3isp_ccdc_lsc_config *lsc_cfg)
146{
147 struct isp_device *isp = to_isp_device(ccdc);
148 struct v4l2_mbus_framefmt *format;
149 unsigned int paxel_width, paxel_height;
150 unsigned int paxel_shift_x, paxel_shift_y;
151 unsigned int min_width, min_height, min_size;
152 unsigned int input_width, input_height;
153
154 paxel_shift_x = lsc_cfg->gain_mode_m;
155 paxel_shift_y = lsc_cfg->gain_mode_n;
156
157 if ((paxel_shift_x < 2) || (paxel_shift_x > 6) ||
158 (paxel_shift_y < 2) || (paxel_shift_y > 6)) {
159 dev_dbg(isp->dev, "CCDC: LSC: Invalid paxel size\n");
160 return -EINVAL;
161 }
162
163 if (lsc_cfg->offset & 3) {
164 dev_dbg(isp->dev, "CCDC: LSC: Offset must be a multiple of "
165 "4\n");
166 return -EINVAL;
167 }
168
169 if ((lsc_cfg->initial_x & 1) || (lsc_cfg->initial_y & 1)) {
170 dev_dbg(isp->dev, "CCDC: LSC: initial_x and y must be even\n");
171 return -EINVAL;
172 }
173
174 format = __ccdc_get_format(ccdc, NULL, CCDC_PAD_SINK,
175 V4L2_SUBDEV_FORMAT_ACTIVE);
176 input_width = format->width;
177 input_height = format->height;
178
179 /* Calculate minimum bytesize for validation */
180 paxel_width = 1 << paxel_shift_x;
181 min_width = ((input_width + lsc_cfg->initial_x + paxel_width - 1)
182 >> paxel_shift_x) + 1;
183
184 paxel_height = 1 << paxel_shift_y;
185 min_height = ((input_height + lsc_cfg->initial_y + paxel_height - 1)
186 >> paxel_shift_y) + 1;
187
188 min_size = 4 * min_width * min_height;
189 if (min_size > lsc_cfg->size) {
190 dev_dbg(isp->dev, "CCDC: LSC: too small table\n");
191 return -EINVAL;
192 }
193 if (lsc_cfg->offset < (min_width * 4)) {
194 dev_dbg(isp->dev, "CCDC: LSC: Offset is too small\n");
195 return -EINVAL;
196 }
197 if ((lsc_cfg->size / lsc_cfg->offset) < min_height) {
198 dev_dbg(isp->dev, "CCDC: LSC: Wrong size/offset combination\n");
199 return -EINVAL;
200 }
201 return 0;
202}
203
204/*
205 * ccdc_lsc_program_table - Program Lens Shading Compensation table address.
206 * @ccdc: Pointer to ISP CCDC device.
207 */
208static void ccdc_lsc_program_table(struct isp_ccdc_device *ccdc, u32 addr)
209{
210 isp_reg_writel(to_isp_device(ccdc), addr,
211 OMAP3_ISP_IOMEM_CCDC, ISPCCDC_LSC_TABLE_BASE);
212}
213
214/*
215 * ccdc_lsc_setup_regs - Configures the lens shading compensation module
216 * @ccdc: Pointer to ISP CCDC device.
217 */
218static void ccdc_lsc_setup_regs(struct isp_ccdc_device *ccdc,
219 struct omap3isp_ccdc_lsc_config *cfg)
220{
221 struct isp_device *isp = to_isp_device(ccdc);
222 int reg;
223
224 isp_reg_writel(isp, cfg->offset, OMAP3_ISP_IOMEM_CCDC,
225 ISPCCDC_LSC_TABLE_OFFSET);
226
227 reg = 0;
228 reg |= cfg->gain_mode_n << ISPCCDC_LSC_GAIN_MODE_N_SHIFT;
229 reg |= cfg->gain_mode_m << ISPCCDC_LSC_GAIN_MODE_M_SHIFT;
230 reg |= cfg->gain_format << ISPCCDC_LSC_GAIN_FORMAT_SHIFT;
231 isp_reg_writel(isp, reg, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_LSC_CONFIG);
232
233 reg = 0;
234 reg &= ~ISPCCDC_LSC_INITIAL_X_MASK;
235 reg |= cfg->initial_x << ISPCCDC_LSC_INITIAL_X_SHIFT;
236 reg &= ~ISPCCDC_LSC_INITIAL_Y_MASK;
237 reg |= cfg->initial_y << ISPCCDC_LSC_INITIAL_Y_SHIFT;
238 isp_reg_writel(isp, reg, OMAP3_ISP_IOMEM_CCDC,
239 ISPCCDC_LSC_INITIAL);
240}
241
242static int ccdc_lsc_wait_prefetch(struct isp_ccdc_device *ccdc)
243{
244 struct isp_device *isp = to_isp_device(ccdc);
245 unsigned int wait;
246
247 isp_reg_writel(isp, IRQ0STATUS_CCDC_LSC_PREF_COMP_IRQ,
248 OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0STATUS);
249
250 /* timeout 1 ms */
251 for (wait = 0; wait < 1000; wait++) {
252 if (isp_reg_readl(isp, OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0STATUS) &
253 IRQ0STATUS_CCDC_LSC_PREF_COMP_IRQ) {
254 isp_reg_writel(isp, IRQ0STATUS_CCDC_LSC_PREF_COMP_IRQ,
255 OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0STATUS);
256 return 0;
257 }
258
259 rmb();
260 udelay(1);
261 }
262
263 return -ETIMEDOUT;
264}
265
266/*
267 * __ccdc_lsc_enable - Enables/Disables the Lens Shading Compensation module.
268 * @ccdc: Pointer to ISP CCDC device.
269 * @enable: 0 Disables LSC, 1 Enables LSC.
270 */
271static int __ccdc_lsc_enable(struct isp_ccdc_device *ccdc, int enable)
272{
273 struct isp_device *isp = to_isp_device(ccdc);
274 const struct v4l2_mbus_framefmt *format =
275 __ccdc_get_format(ccdc, NULL, CCDC_PAD_SINK,
276 V4L2_SUBDEV_FORMAT_ACTIVE);
277
278 if ((format->code != V4L2_MBUS_FMT_SGRBG10_1X10) &&
279 (format->code != V4L2_MBUS_FMT_SRGGB10_1X10) &&
280 (format->code != V4L2_MBUS_FMT_SBGGR10_1X10) &&
281 (format->code != V4L2_MBUS_FMT_SGBRG10_1X10))
282 return -EINVAL;
283
284 if (enable)
285 omap3isp_sbl_enable(isp, OMAP3_ISP_SBL_CCDC_LSC_READ);
286
287 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_LSC_CONFIG,
288 ISPCCDC_LSC_ENABLE, enable ? ISPCCDC_LSC_ENABLE : 0);
289
290 if (enable) {
291 if (ccdc_lsc_wait_prefetch(ccdc) < 0) {
292 isp_reg_clr(isp, OMAP3_ISP_IOMEM_CCDC,
293 ISPCCDC_LSC_CONFIG, ISPCCDC_LSC_ENABLE);
294 ccdc->lsc.state = LSC_STATE_STOPPED;
295 dev_warn(to_device(ccdc), "LSC prefecth timeout\n");
296 return -ETIMEDOUT;
297 }
298 ccdc->lsc.state = LSC_STATE_RUNNING;
299 } else {
300 ccdc->lsc.state = LSC_STATE_STOPPING;
301 }
302
303 return 0;
304}
305
306static int ccdc_lsc_busy(struct isp_ccdc_device *ccdc)
307{
308 struct isp_device *isp = to_isp_device(ccdc);
309
310 return isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_LSC_CONFIG) &
311 ISPCCDC_LSC_BUSY;
312}
313
314/* __ccdc_lsc_configure - Apply a new configuration to the LSC engine
315 * @ccdc: Pointer to ISP CCDC device
316 * @req: New configuration request
317 *
318 * context: in_interrupt()
319 */
320static int __ccdc_lsc_configure(struct isp_ccdc_device *ccdc,
321 struct ispccdc_lsc_config_req *req)
322{
323 if (!req->enable)
324 return -EINVAL;
325
326 if (ccdc_lsc_validate_config(ccdc, &req->config) < 0) {
327 dev_dbg(to_device(ccdc), "Discard LSC configuration\n");
328 return -EINVAL;
329 }
330
331 if (ccdc_lsc_busy(ccdc))
332 return -EBUSY;
333
334 ccdc_lsc_setup_regs(ccdc, &req->config);
335 ccdc_lsc_program_table(ccdc, req->table);
336 return 0;
337}
338
339/*
340 * ccdc_lsc_error_handler - Handle LSC prefetch error scenario.
341 * @ccdc: Pointer to ISP CCDC device.
342 *
343 * Disables LSC, and defers enablement to shadow registers update time.
344 */
345static void ccdc_lsc_error_handler(struct isp_ccdc_device *ccdc)
346{
347 struct isp_device *isp = to_isp_device(ccdc);
348 /*
349 * From OMAP3 TRM: When this event is pending, the module
350 * goes into transparent mode (output =input). Normal
351 * operation can be resumed at the start of the next frame
352 * after:
353 * 1) Clearing this event
354 * 2) Disabling the LSC module
355 * 3) Enabling it
356 */
357 isp_reg_clr(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_LSC_CONFIG,
358 ISPCCDC_LSC_ENABLE);
359 ccdc->lsc.state = LSC_STATE_STOPPED;
360}
361
362static void ccdc_lsc_free_request(struct isp_ccdc_device *ccdc,
363 struct ispccdc_lsc_config_req *req)
364{
365 struct isp_device *isp = to_isp_device(ccdc);
366
367 if (req == NULL)
368 return;
369
370 if (req->iovm)
371 dma_unmap_sg(isp->dev, req->iovm->sgt->sgl,
372 req->iovm->sgt->nents, DMA_TO_DEVICE);
373 if (req->table)
374 omap_iommu_vfree(isp->domain, isp->dev, req->table);
375 kfree(req);
376}
377
378static void ccdc_lsc_free_queue(struct isp_ccdc_device *ccdc,
379 struct list_head *queue)
380{
381 struct ispccdc_lsc_config_req *req, *n;
382 unsigned long flags;
383
384 spin_lock_irqsave(&ccdc->lsc.req_lock, flags);
385 list_for_each_entry_safe(req, n, queue, list) {
386 list_del(&req->list);
387 spin_unlock_irqrestore(&ccdc->lsc.req_lock, flags);
388 ccdc_lsc_free_request(ccdc, req);
389 spin_lock_irqsave(&ccdc->lsc.req_lock, flags);
390 }
391 spin_unlock_irqrestore(&ccdc->lsc.req_lock, flags);
392}
393
394static void ccdc_lsc_free_table_work(struct work_struct *work)
395{
396 struct isp_ccdc_device *ccdc;
397 struct ispccdc_lsc *lsc;
398
399 lsc = container_of(work, struct ispccdc_lsc, table_work);
400 ccdc = container_of(lsc, struct isp_ccdc_device, lsc);
401
402 ccdc_lsc_free_queue(ccdc, &lsc->free_queue);
403}
404
405/*
406 * ccdc_lsc_config - Configure the LSC module from a userspace request
407 *
408 * Store the request LSC configuration in the LSC engine request pointer. The
409 * configuration will be applied to the hardware when the CCDC will be enabled,
410 * or at the next LSC interrupt if the CCDC is already running.
411 */
412static int ccdc_lsc_config(struct isp_ccdc_device *ccdc,
413 struct omap3isp_ccdc_update_config *config)
414{
415 struct isp_device *isp = to_isp_device(ccdc);
416 struct ispccdc_lsc_config_req *req;
417 unsigned long flags;
418 void *table;
419 u16 update;
420 int ret;
421
422 update = config->update &
423 (OMAP3ISP_CCDC_CONFIG_LSC | OMAP3ISP_CCDC_TBL_LSC);
424 if (!update)
425 return 0;
426
427 if (update != (OMAP3ISP_CCDC_CONFIG_LSC | OMAP3ISP_CCDC_TBL_LSC)) {
428 dev_dbg(to_device(ccdc), "%s: Both LSC configuration and table "
429 "need to be supplied\n", __func__);
430 return -EINVAL;
431 }
432
433 req = kzalloc(sizeof(*req), GFP_KERNEL);
434 if (req == NULL)
435 return -ENOMEM;
436
437 if (config->flag & OMAP3ISP_CCDC_CONFIG_LSC) {
438 if (copy_from_user(&req->config, config->lsc_cfg,
439 sizeof(req->config))) {
440 ret = -EFAULT;
441 goto done;
442 }
443
444 req->enable = 1;
445
446 req->table = omap_iommu_vmalloc(isp->domain, isp->dev, 0,
447 req->config.size, IOMMU_FLAG);
448 if (IS_ERR_VALUE(req->table)) {
449 req->table = 0;
450 ret = -ENOMEM;
451 goto done;
452 }
453
454 req->iovm = omap_find_iovm_area(isp->dev, req->table);
455 if (req->iovm == NULL) {
456 ret = -ENOMEM;
457 goto done;
458 }
459
460 if (!dma_map_sg(isp->dev, req->iovm->sgt->sgl,
461 req->iovm->sgt->nents, DMA_TO_DEVICE)) {
462 ret = -ENOMEM;
463 req->iovm = NULL;
464 goto done;
465 }
466
467 dma_sync_sg_for_cpu(isp->dev, req->iovm->sgt->sgl,
468 req->iovm->sgt->nents, DMA_TO_DEVICE);
469
470 table = omap_da_to_va(isp->dev, req->table);
471 if (copy_from_user(table, config->lsc, req->config.size)) {
472 ret = -EFAULT;
473 goto done;
474 }
475
476 dma_sync_sg_for_device(isp->dev, req->iovm->sgt->sgl,
477 req->iovm->sgt->nents, DMA_TO_DEVICE);
478 }
479
480 spin_lock_irqsave(&ccdc->lsc.req_lock, flags);
481 if (ccdc->lsc.request) {
482 list_add_tail(&ccdc->lsc.request->list, &ccdc->lsc.free_queue);
483 schedule_work(&ccdc->lsc.table_work);
484 }
485 ccdc->lsc.request = req;
486 spin_unlock_irqrestore(&ccdc->lsc.req_lock, flags);
487
488 ret = 0;
489
490done:
491 if (ret < 0)
492 ccdc_lsc_free_request(ccdc, req);
493
494 return ret;
495}
496
497static inline int ccdc_lsc_is_configured(struct isp_ccdc_device *ccdc)
498{
499 unsigned long flags;
500
501 spin_lock_irqsave(&ccdc->lsc.req_lock, flags);
502 if (ccdc->lsc.active) {
503 spin_unlock_irqrestore(&ccdc->lsc.req_lock, flags);
504 return 1;
505 }
506 spin_unlock_irqrestore(&ccdc->lsc.req_lock, flags);
507 return 0;
508}
509
510static int ccdc_lsc_enable(struct isp_ccdc_device *ccdc)
511{
512 struct ispccdc_lsc *lsc = &ccdc->lsc;
513
514 if (lsc->state != LSC_STATE_STOPPED)
515 return -EINVAL;
516
517 if (lsc->active) {
518 list_add_tail(&lsc->active->list, &lsc->free_queue);
519 lsc->active = NULL;
520 }
521
522 if (__ccdc_lsc_configure(ccdc, lsc->request) < 0) {
523 omap3isp_sbl_disable(to_isp_device(ccdc),
524 OMAP3_ISP_SBL_CCDC_LSC_READ);
525 list_add_tail(&lsc->request->list, &lsc->free_queue);
526 lsc->request = NULL;
527 goto done;
528 }
529
530 lsc->active = lsc->request;
531 lsc->request = NULL;
532 __ccdc_lsc_enable(ccdc, 1);
533
534done:
535 if (!list_empty(&lsc->free_queue))
536 schedule_work(&lsc->table_work);
537
538 return 0;
539}
540
541/* -----------------------------------------------------------------------------
542 * Parameters configuration
543 */
544
545/*
546 * ccdc_configure_clamp - Configure optical-black or digital clamping
547 * @ccdc: Pointer to ISP CCDC device.
548 *
549 * The CCDC performs either optical-black or digital clamp. Configure and enable
550 * the selected clamp method.
551 */
552static void ccdc_configure_clamp(struct isp_ccdc_device *ccdc)
553{
554 struct isp_device *isp = to_isp_device(ccdc);
555 u32 clamp;
556
557 if (ccdc->obclamp) {
558 clamp = ccdc->clamp.obgain << ISPCCDC_CLAMP_OBGAIN_SHIFT;
559 clamp |= ccdc->clamp.oblen << ISPCCDC_CLAMP_OBSLEN_SHIFT;
560 clamp |= ccdc->clamp.oblines << ISPCCDC_CLAMP_OBSLN_SHIFT;
561 clamp |= ccdc->clamp.obstpixel << ISPCCDC_CLAMP_OBST_SHIFT;
562 isp_reg_writel(isp, clamp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_CLAMP);
563 } else {
564 isp_reg_writel(isp, ccdc->clamp.dcsubval,
565 OMAP3_ISP_IOMEM_CCDC, ISPCCDC_DCSUB);
566 }
567
568 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_CLAMP,
569 ISPCCDC_CLAMP_CLAMPEN,
570 ccdc->obclamp ? ISPCCDC_CLAMP_CLAMPEN : 0);
571}
572
573/*
574 * ccdc_configure_fpc - Configure Faulty Pixel Correction
575 * @ccdc: Pointer to ISP CCDC device.
576 */
577static void ccdc_configure_fpc(struct isp_ccdc_device *ccdc)
578{
579 struct isp_device *isp = to_isp_device(ccdc);
580
581 isp_reg_clr(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FPC, ISPCCDC_FPC_FPCEN);
582
583 if (!ccdc->fpc_en)
584 return;
585
586 isp_reg_writel(isp, ccdc->fpc.fpcaddr, OMAP3_ISP_IOMEM_CCDC,
587 ISPCCDC_FPC_ADDR);
588 /* The FPNUM field must be set before enabling FPC. */
589 isp_reg_writel(isp, (ccdc->fpc.fpnum << ISPCCDC_FPC_FPNUM_SHIFT),
590 OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FPC);
591 isp_reg_writel(isp, (ccdc->fpc.fpnum << ISPCCDC_FPC_FPNUM_SHIFT) |
592 ISPCCDC_FPC_FPCEN, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FPC);
593}
594
595/*
596 * ccdc_configure_black_comp - Configure Black Level Compensation.
597 * @ccdc: Pointer to ISP CCDC device.
598 */
599static void ccdc_configure_black_comp(struct isp_ccdc_device *ccdc)
600{
601 struct isp_device *isp = to_isp_device(ccdc);
602 u32 blcomp;
603
604 blcomp = ccdc->blcomp.b_mg << ISPCCDC_BLKCMP_B_MG_SHIFT;
605 blcomp |= ccdc->blcomp.gb_g << ISPCCDC_BLKCMP_GB_G_SHIFT;
606 blcomp |= ccdc->blcomp.gr_cy << ISPCCDC_BLKCMP_GR_CY_SHIFT;
607 blcomp |= ccdc->blcomp.r_ye << ISPCCDC_BLKCMP_R_YE_SHIFT;
608
609 isp_reg_writel(isp, blcomp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_BLKCMP);
610}
611
612/*
613 * ccdc_configure_lpf - Configure Low-Pass Filter (LPF).
614 * @ccdc: Pointer to ISP CCDC device.
615 */
616static void ccdc_configure_lpf(struct isp_ccdc_device *ccdc)
617{
618 struct isp_device *isp = to_isp_device(ccdc);
619
620 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SYN_MODE,
621 ISPCCDC_SYN_MODE_LPF,
622 ccdc->lpf ? ISPCCDC_SYN_MODE_LPF : 0);
623}
624
625/*
626 * ccdc_configure_alaw - Configure A-law compression.
627 * @ccdc: Pointer to ISP CCDC device.
628 */
629static void ccdc_configure_alaw(struct isp_ccdc_device *ccdc)
630{
631 struct isp_device *isp = to_isp_device(ccdc);
632 const struct isp_format_info *info;
633 u32 alaw = 0;
634
635 info = omap3isp_video_format_info(ccdc->formats[CCDC_PAD_SINK].code);
636
637 switch (info->width) {
638 case 8:
639 return;
640
641 case 10:
642 alaw = ISPCCDC_ALAW_GWDI_9_0;
643 break;
644 case 11:
645 alaw = ISPCCDC_ALAW_GWDI_10_1;
646 break;
647 case 12:
648 alaw = ISPCCDC_ALAW_GWDI_11_2;
649 break;
650 case 13:
651 alaw = ISPCCDC_ALAW_GWDI_12_3;
652 break;
653 }
654
655 if (ccdc->alaw)
656 alaw |= ISPCCDC_ALAW_CCDTBL;
657
658 isp_reg_writel(isp, alaw, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_ALAW);
659}
660
661/*
662 * ccdc_config_imgattr - Configure sensor image specific attributes.
663 * @ccdc: Pointer to ISP CCDC device.
664 * @colptn: Color pattern of the sensor.
665 */
666static void ccdc_config_imgattr(struct isp_ccdc_device *ccdc, u32 colptn)
667{
668 struct isp_device *isp = to_isp_device(ccdc);
669
670 isp_reg_writel(isp, colptn, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_COLPTN);
671}
672
673/*
674 * ccdc_config - Set CCDC configuration from userspace
675 * @ccdc: Pointer to ISP CCDC device.
676 * @userspace_add: Structure containing CCDC configuration sent from userspace.
677 *
678 * Returns 0 if successful, -EINVAL if the pointer to the configuration
679 * structure is null, or the copy_from_user function fails to copy user space
680 * memory to kernel space memory.
681 */
682static int ccdc_config(struct isp_ccdc_device *ccdc,
683 struct omap3isp_ccdc_update_config *ccdc_struct)
684{
685 struct isp_device *isp = to_isp_device(ccdc);
686 unsigned long flags;
687
688 spin_lock_irqsave(&ccdc->lock, flags);
689 ccdc->shadow_update = 1;
690 spin_unlock_irqrestore(&ccdc->lock, flags);
691
692 if (OMAP3ISP_CCDC_ALAW & ccdc_struct->update) {
693 ccdc->alaw = !!(OMAP3ISP_CCDC_ALAW & ccdc_struct->flag);
694 ccdc->update |= OMAP3ISP_CCDC_ALAW;
695 }
696
697 if (OMAP3ISP_CCDC_LPF & ccdc_struct->update) {
698 ccdc->lpf = !!(OMAP3ISP_CCDC_LPF & ccdc_struct->flag);
699 ccdc->update |= OMAP3ISP_CCDC_LPF;
700 }
701
702 if (OMAP3ISP_CCDC_BLCLAMP & ccdc_struct->update) {
703 if (copy_from_user(&ccdc->clamp, ccdc_struct->bclamp,
704 sizeof(ccdc->clamp))) {
705 ccdc->shadow_update = 0;
706 return -EFAULT;
707 }
708
709 ccdc->obclamp = !!(OMAP3ISP_CCDC_BLCLAMP & ccdc_struct->flag);
710 ccdc->update |= OMAP3ISP_CCDC_BLCLAMP;
711 }
712
713 if (OMAP3ISP_CCDC_BCOMP & ccdc_struct->update) {
714 if (copy_from_user(&ccdc->blcomp, ccdc_struct->blcomp,
715 sizeof(ccdc->blcomp))) {
716 ccdc->shadow_update = 0;
717 return -EFAULT;
718 }
719
720 ccdc->update |= OMAP3ISP_CCDC_BCOMP;
721 }
722
723 ccdc->shadow_update = 0;
724
725 if (OMAP3ISP_CCDC_FPC & ccdc_struct->update) {
726 u32 table_old = 0;
727 u32 table_new;
728 u32 size;
729
730 if (ccdc->state != ISP_PIPELINE_STREAM_STOPPED)
731 return -EBUSY;
732
733 ccdc->fpc_en = !!(OMAP3ISP_CCDC_FPC & ccdc_struct->flag);
734
735 if (ccdc->fpc_en) {
736 if (copy_from_user(&ccdc->fpc, ccdc_struct->fpc,
737 sizeof(ccdc->fpc)))
738 return -EFAULT;
739
740 /*
741 * table_new must be 64-bytes aligned, but it's
742 * already done by omap_iommu_vmalloc().
743 */
744 size = ccdc->fpc.fpnum * 4;
745 table_new = omap_iommu_vmalloc(isp->domain, isp->dev,
746 0, size, IOMMU_FLAG);
747 if (IS_ERR_VALUE(table_new))
748 return -ENOMEM;
749
750 if (copy_from_user(omap_da_to_va(isp->dev, table_new),
751 (__force void __user *)
752 ccdc->fpc.fpcaddr, size)) {
753 omap_iommu_vfree(isp->domain, isp->dev,
754 table_new);
755 return -EFAULT;
756 }
757
758 table_old = ccdc->fpc.fpcaddr;
759 ccdc->fpc.fpcaddr = table_new;
760 }
761
762 ccdc_configure_fpc(ccdc);
763 if (table_old != 0)
764 omap_iommu_vfree(isp->domain, isp->dev, table_old);
765 }
766
767 return ccdc_lsc_config(ccdc, ccdc_struct);
768}
769
770static void ccdc_apply_controls(struct isp_ccdc_device *ccdc)
771{
772 if (ccdc->update & OMAP3ISP_CCDC_ALAW) {
773 ccdc_configure_alaw(ccdc);
774 ccdc->update &= ~OMAP3ISP_CCDC_ALAW;
775 }
776
777 if (ccdc->update & OMAP3ISP_CCDC_LPF) {
778 ccdc_configure_lpf(ccdc);
779 ccdc->update &= ~OMAP3ISP_CCDC_LPF;
780 }
781
782 if (ccdc->update & OMAP3ISP_CCDC_BLCLAMP) {
783 ccdc_configure_clamp(ccdc);
784 ccdc->update &= ~OMAP3ISP_CCDC_BLCLAMP;
785 }
786
787 if (ccdc->update & OMAP3ISP_CCDC_BCOMP) {
788 ccdc_configure_black_comp(ccdc);
789 ccdc->update &= ~OMAP3ISP_CCDC_BCOMP;
790 }
791}
792
793/*
794 * omap3isp_ccdc_restore_context - Restore values of the CCDC module registers
795 * @dev: Pointer to ISP device
796 */
797void omap3isp_ccdc_restore_context(struct isp_device *isp)
798{
799 struct isp_ccdc_device *ccdc = &isp->isp_ccdc;
800
801 isp_reg_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_CFG, ISPCCDC_CFG_VDLC);
802
803 ccdc->update = OMAP3ISP_CCDC_ALAW | OMAP3ISP_CCDC_LPF
804 | OMAP3ISP_CCDC_BLCLAMP | OMAP3ISP_CCDC_BCOMP;
805 ccdc_apply_controls(ccdc);
806 ccdc_configure_fpc(ccdc);
807}
808
809/* -----------------------------------------------------------------------------
810 * Format- and pipeline-related configuration helpers
811 */
812
813/*
814 * ccdc_config_vp - Configure the Video Port.
815 * @ccdc: Pointer to ISP CCDC device.
816 */
817static void ccdc_config_vp(struct isp_ccdc_device *ccdc)
818{
819 struct isp_pipeline *pipe = to_isp_pipeline(&ccdc->subdev.entity);
820 struct isp_device *isp = to_isp_device(ccdc);
821 const struct isp_format_info *info;
822 unsigned long l3_ick = pipe->l3_ick;
823 unsigned int max_div = isp->revision == ISP_REVISION_15_0 ? 64 : 8;
824 unsigned int div = 0;
825 u32 fmtcfg_vp;
826
827 fmtcfg_vp = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FMTCFG)
828 & ~(ISPCCDC_FMTCFG_VPIN_MASK | ISPCCDC_FMTCFG_VPIF_FRQ_MASK);
829
830 info = omap3isp_video_format_info(ccdc->formats[CCDC_PAD_SINK].code);
831
832 switch (info->width) {
833 case 8:
834 case 10:
835 fmtcfg_vp |= ISPCCDC_FMTCFG_VPIN_9_0;
836 break;
837 case 11:
838 fmtcfg_vp |= ISPCCDC_FMTCFG_VPIN_10_1;
839 break;
840 case 12:
841 fmtcfg_vp |= ISPCCDC_FMTCFG_VPIN_11_2;
842 break;
843 case 13:
844 fmtcfg_vp |= ISPCCDC_FMTCFG_VPIN_12_3;
845 break;
846 }
847
848 if (pipe->input)
849 div = DIV_ROUND_UP(l3_ick, pipe->max_rate);
850 else if (pipe->external_rate)
851 div = l3_ick / pipe->external_rate;
852
853 div = clamp(div, 2U, max_div);
854 fmtcfg_vp |= (div - 2) << ISPCCDC_FMTCFG_VPIF_FRQ_SHIFT;
855
856 isp_reg_writel(isp, fmtcfg_vp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FMTCFG);
857}
858
859/*
860 * ccdc_enable_vp - Enable Video Port.
861 * @ccdc: Pointer to ISP CCDC device.
862 * @enable: 0 Disables VP, 1 Enables VP
863 *
864 * This is needed for outputting image to Preview, H3A and HIST ISP submodules.
865 */
866static void ccdc_enable_vp(struct isp_ccdc_device *ccdc, u8 enable)
867{
868 struct isp_device *isp = to_isp_device(ccdc);
869
870 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FMTCFG,
871 ISPCCDC_FMTCFG_VPEN, enable ? ISPCCDC_FMTCFG_VPEN : 0);
872}
873
874/*
875 * ccdc_config_outlineoffset - Configure memory saving output line offset
876 * @ccdc: Pointer to ISP CCDC device.
877 * @offset: Address offset to start a new line. Must be twice the
878 * Output width and aligned on 32 byte boundary
879 * @oddeven: Specifies the odd/even line pattern to be chosen to store the
880 * output.
881 * @numlines: Set the value 0-3 for +1-4lines, 4-7 for -1-4lines.
882 *
883 * - Configures the output line offset when stored in memory
884 * - Sets the odd/even line pattern to store the output
885 * (EVENEVEN (1), ODDEVEN (2), EVENODD (3), ODDODD (4))
886 * - Configures the number of even and odd line fields in case of rearranging
887 * the lines.
888 */
889static void ccdc_config_outlineoffset(struct isp_ccdc_device *ccdc,
890 u32 offset, u8 oddeven, u8 numlines)
891{
892 struct isp_device *isp = to_isp_device(ccdc);
893
894 isp_reg_writel(isp, offset & 0xffff,
895 OMAP3_ISP_IOMEM_CCDC, ISPCCDC_HSIZE_OFF);
896
897 isp_reg_clr(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDOFST,
898 ISPCCDC_SDOFST_FINV);
899
900 isp_reg_clr(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDOFST,
901 ISPCCDC_SDOFST_FOFST_4L);
902
903 switch (oddeven) {
904 case EVENEVEN:
905 isp_reg_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDOFST,
906 (numlines & 0x7) << ISPCCDC_SDOFST_LOFST0_SHIFT);
907 break;
908 case ODDEVEN:
909 isp_reg_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDOFST,
910 (numlines & 0x7) << ISPCCDC_SDOFST_LOFST1_SHIFT);
911 break;
912 case EVENODD:
913 isp_reg_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDOFST,
914 (numlines & 0x7) << ISPCCDC_SDOFST_LOFST2_SHIFT);
915 break;
916 case ODDODD:
917 isp_reg_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDOFST,
918 (numlines & 0x7) << ISPCCDC_SDOFST_LOFST3_SHIFT);
919 break;
920 default:
921 break;
922 }
923}
924
925/*
926 * ccdc_set_outaddr - Set memory address to save output image
927 * @ccdc: Pointer to ISP CCDC device.
928 * @addr: ISP MMU Mapped 32-bit memory address aligned on 32 byte boundary.
929 *
930 * Sets the memory address where the output will be saved.
931 */
932static void ccdc_set_outaddr(struct isp_ccdc_device *ccdc, u32 addr)
933{
934 struct isp_device *isp = to_isp_device(ccdc);
935
936 isp_reg_writel(isp, addr, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDR_ADDR);
937}
938
939/*
940 * omap3isp_ccdc_max_rate - Calculate maximum input data rate based on the input
941 * @ccdc: Pointer to ISP CCDC device.
942 * @max_rate: Maximum calculated data rate.
943 *
944 * Returns in *max_rate less value between calculated and passed
945 */
946void omap3isp_ccdc_max_rate(struct isp_ccdc_device *ccdc,
947 unsigned int *max_rate)
948{
949 struct isp_pipeline *pipe = to_isp_pipeline(&ccdc->subdev.entity);
950 unsigned int rate;
951
952 if (pipe == NULL)
953 return;
954
955 /*
956 * TRM says that for parallel sensors the maximum data rate
957 * should be 90% form L3/2 clock, otherwise just L3/2.
958 */
959 if (ccdc->input == CCDC_INPUT_PARALLEL)
960 rate = pipe->l3_ick / 2 * 9 / 10;
961 else
962 rate = pipe->l3_ick / 2;
963
964 *max_rate = min(*max_rate, rate);
965}
966
967/*
968 * ccdc_config_sync_if - Set CCDC sync interface configuration
969 * @ccdc: Pointer to ISP CCDC device.
970 * @pdata: Parallel interface platform data (may be NULL)
971 * @data_size: Data size
972 */
973static void ccdc_config_sync_if(struct isp_ccdc_device *ccdc,
974 struct isp_parallel_platform_data *pdata,
975 unsigned int data_size)
976{
977 struct isp_device *isp = to_isp_device(ccdc);
978 const struct v4l2_mbus_framefmt *format;
979 u32 syn_mode = ISPCCDC_SYN_MODE_VDHDEN;
980
981 format = &ccdc->formats[CCDC_PAD_SINK];
982
983 if (format->code == V4L2_MBUS_FMT_YUYV8_2X8 ||
984 format->code == V4L2_MBUS_FMT_UYVY8_2X8) {
985 /* The bridge is enabled for YUV8 formats. Configure the input
986 * mode accordingly.
987 */
988 syn_mode |= ISPCCDC_SYN_MODE_INPMOD_YCBCR16;
989 }
990
991 switch (data_size) {
992 case 8:
993 syn_mode |= ISPCCDC_SYN_MODE_DATSIZ_8;
994 break;
995 case 10:
996 syn_mode |= ISPCCDC_SYN_MODE_DATSIZ_10;
997 break;
998 case 11:
999 syn_mode |= ISPCCDC_SYN_MODE_DATSIZ_11;
1000 break;
1001 case 12:
1002 syn_mode |= ISPCCDC_SYN_MODE_DATSIZ_12;
1003 break;
1004 }
1005
1006 if (pdata && pdata->data_pol)
1007 syn_mode |= ISPCCDC_SYN_MODE_DATAPOL;
1008
1009 if (pdata && pdata->hs_pol)
1010 syn_mode |= ISPCCDC_SYN_MODE_HDPOL;
1011
1012 if (pdata && pdata->vs_pol)
1013 syn_mode |= ISPCCDC_SYN_MODE_VDPOL;
1014
1015 isp_reg_writel(isp, syn_mode, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SYN_MODE);
1016
1017 /* The CCDC_CFG.Y8POS bit is used in YCbCr8 input mode only. The
1018 * hardware seems to ignore it in all other input modes.
1019 */
1020 if (format->code == V4L2_MBUS_FMT_UYVY8_2X8)
1021 isp_reg_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_CFG,
1022 ISPCCDC_CFG_Y8POS);
1023 else
1024 isp_reg_clr(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_CFG,
1025 ISPCCDC_CFG_Y8POS);
1026
1027 isp_reg_clr(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_REC656IF,
1028 ISPCCDC_REC656IF_R656ON);
1029}
1030
1031/* CCDC formats descriptions */
1032static const u32 ccdc_sgrbg_pattern =
1033 ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP0PLC0_SHIFT |
1034 ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP0PLC1_SHIFT |
1035 ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP0PLC2_SHIFT |
1036 ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP0PLC3_SHIFT |
1037 ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP1PLC0_SHIFT |
1038 ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP1PLC1_SHIFT |
1039 ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP1PLC2_SHIFT |
1040 ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP1PLC3_SHIFT |
1041 ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP2PLC0_SHIFT |
1042 ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP2PLC1_SHIFT |
1043 ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP2PLC2_SHIFT |
1044 ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP2PLC3_SHIFT |
1045 ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP3PLC0_SHIFT |
1046 ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP3PLC1_SHIFT |
1047 ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP3PLC2_SHIFT |
1048 ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP3PLC3_SHIFT;
1049
1050static const u32 ccdc_srggb_pattern =
1051 ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP0PLC0_SHIFT |
1052 ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP0PLC1_SHIFT |
1053 ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP0PLC2_SHIFT |
1054 ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP0PLC3_SHIFT |
1055 ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP1PLC0_SHIFT |
1056 ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP1PLC1_SHIFT |
1057 ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP1PLC2_SHIFT |
1058 ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP1PLC3_SHIFT |
1059 ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP2PLC0_SHIFT |
1060 ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP2PLC1_SHIFT |
1061 ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP2PLC2_SHIFT |
1062 ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP2PLC3_SHIFT |
1063 ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP3PLC0_SHIFT |
1064 ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP3PLC1_SHIFT |
1065 ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP3PLC2_SHIFT |
1066 ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP3PLC3_SHIFT;
1067
1068static const u32 ccdc_sbggr_pattern =
1069 ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP0PLC0_SHIFT |
1070 ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP0PLC1_SHIFT |
1071 ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP0PLC2_SHIFT |
1072 ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP0PLC3_SHIFT |
1073 ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP1PLC0_SHIFT |
1074 ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP1PLC1_SHIFT |
1075 ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP1PLC2_SHIFT |
1076 ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP1PLC3_SHIFT |
1077 ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP2PLC0_SHIFT |
1078 ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP2PLC1_SHIFT |
1079 ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP2PLC2_SHIFT |
1080 ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP2PLC3_SHIFT |
1081 ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP3PLC0_SHIFT |
1082 ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP3PLC1_SHIFT |
1083 ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP3PLC2_SHIFT |
1084 ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP3PLC3_SHIFT;
1085
1086static const u32 ccdc_sgbrg_pattern =
1087 ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP0PLC0_SHIFT |
1088 ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP0PLC1_SHIFT |
1089 ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP0PLC2_SHIFT |
1090 ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP0PLC3_SHIFT |
1091 ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP1PLC0_SHIFT |
1092 ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP1PLC1_SHIFT |
1093 ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP1PLC2_SHIFT |
1094 ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP1PLC3_SHIFT |
1095 ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP2PLC0_SHIFT |
1096 ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP2PLC1_SHIFT |
1097 ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP2PLC2_SHIFT |
1098 ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP2PLC3_SHIFT |
1099 ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP3PLC0_SHIFT |
1100 ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP3PLC1_SHIFT |
1101 ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP3PLC2_SHIFT |
1102 ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP3PLC3_SHIFT;
1103
1104static void ccdc_configure(struct isp_ccdc_device *ccdc)
1105{
1106 struct isp_device *isp = to_isp_device(ccdc);
1107 struct isp_parallel_platform_data *pdata = NULL;
1108 struct v4l2_subdev *sensor;
1109 struct v4l2_mbus_framefmt *format;
1110 const struct v4l2_rect *crop;
1111 const struct isp_format_info *fmt_info;
1112 struct v4l2_subdev_format fmt_src;
1113 unsigned int depth_out;
1114 unsigned int depth_in = 0;
1115 struct media_pad *pad;
1116 unsigned long flags;
1117 unsigned int bridge;
1118 unsigned int shift;
1119 u32 syn_mode;
1120 u32 ccdc_pattern;
1121
1122 pad = media_entity_remote_source(&ccdc->pads[CCDC_PAD_SINK]);
1123 sensor = media_entity_to_v4l2_subdev(pad->entity);
1124 if (ccdc->input == CCDC_INPUT_PARALLEL)
1125 pdata = &((struct isp_v4l2_subdevs_group *)sensor->host_priv)
1126 ->bus.parallel;
1127
1128 /* Compute the lane shifter shift value and enable the bridge when the
1129 * input format is YUV.
1130 */
1131 fmt_src.pad = pad->index;
1132 fmt_src.which = V4L2_SUBDEV_FORMAT_ACTIVE;
1133 if (!v4l2_subdev_call(sensor, pad, get_fmt, NULL, &fmt_src)) {
1134 fmt_info = omap3isp_video_format_info(fmt_src.format.code);
1135 depth_in = fmt_info->width;
1136 }
1137
1138 fmt_info = omap3isp_video_format_info
1139 (isp->isp_ccdc.formats[CCDC_PAD_SINK].code);
1140 depth_out = fmt_info->width;
1141 shift = depth_in - depth_out;
1142
1143 if (fmt_info->code == V4L2_MBUS_FMT_YUYV8_2X8)
1144 bridge = ISPCTRL_PAR_BRIDGE_LENDIAN;
1145 else if (fmt_info->code == V4L2_MBUS_FMT_UYVY8_2X8)
1146 bridge = ISPCTRL_PAR_BRIDGE_BENDIAN;
1147 else
1148 bridge = ISPCTRL_PAR_BRIDGE_DISABLE;
1149
1150 omap3isp_configure_bridge(isp, ccdc->input, pdata, shift, bridge);
1151
1152 ccdc_config_sync_if(ccdc, pdata, depth_out);
1153
1154 syn_mode = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SYN_MODE);
1155
1156 /* Use the raw, unprocessed data when writing to memory. The H3A and
1157 * histogram modules are still fed with lens shading corrected data.
1158 */
1159 syn_mode &= ~ISPCCDC_SYN_MODE_VP2SDR;
1160
1161 if (ccdc->output & CCDC_OUTPUT_MEMORY)
1162 syn_mode |= ISPCCDC_SYN_MODE_WEN;
1163 else
1164 syn_mode &= ~ISPCCDC_SYN_MODE_WEN;
1165
1166 if (ccdc->output & CCDC_OUTPUT_RESIZER)
1167 syn_mode |= ISPCCDC_SYN_MODE_SDR2RSZ;
1168 else
1169 syn_mode &= ~ISPCCDC_SYN_MODE_SDR2RSZ;
1170
1171 /* CCDC_PAD_SINK */
1172 format = &ccdc->formats[CCDC_PAD_SINK];
1173
1174 /* Mosaic filter */
1175 switch (format->code) {
1176 case V4L2_MBUS_FMT_SRGGB10_1X10:
1177 case V4L2_MBUS_FMT_SRGGB12_1X12:
1178 ccdc_pattern = ccdc_srggb_pattern;
1179 break;
1180 case V4L2_MBUS_FMT_SBGGR10_1X10:
1181 case V4L2_MBUS_FMT_SBGGR12_1X12:
1182 ccdc_pattern = ccdc_sbggr_pattern;
1183 break;
1184 case V4L2_MBUS_FMT_SGBRG10_1X10:
1185 case V4L2_MBUS_FMT_SGBRG12_1X12:
1186 ccdc_pattern = ccdc_sgbrg_pattern;
1187 break;
1188 default:
1189 /* Use GRBG */
1190 ccdc_pattern = ccdc_sgrbg_pattern;
1191 break;
1192 }
1193 ccdc_config_imgattr(ccdc, ccdc_pattern);
1194
1195 /* Generate VD0 on the last line of the image and VD1 on the
1196 * 2/3 height line.
1197 */
1198 isp_reg_writel(isp, ((format->height - 2) << ISPCCDC_VDINT_0_SHIFT) |
1199 ((format->height * 2 / 3) << ISPCCDC_VDINT_1_SHIFT),
1200 OMAP3_ISP_IOMEM_CCDC, ISPCCDC_VDINT);
1201
1202 /* CCDC_PAD_SOURCE_OF */
1203 format = &ccdc->formats[CCDC_PAD_SOURCE_OF];
1204 crop = &ccdc->crop;
1205
1206 isp_reg_writel(isp, (crop->left << ISPCCDC_HORZ_INFO_SPH_SHIFT) |
1207 ((crop->width - 1) << ISPCCDC_HORZ_INFO_NPH_SHIFT),
1208 OMAP3_ISP_IOMEM_CCDC, ISPCCDC_HORZ_INFO);
1209 isp_reg_writel(isp, crop->top << ISPCCDC_VERT_START_SLV0_SHIFT,
1210 OMAP3_ISP_IOMEM_CCDC, ISPCCDC_VERT_START);
1211 isp_reg_writel(isp, (crop->height - 1)
1212 << ISPCCDC_VERT_LINES_NLV_SHIFT,
1213 OMAP3_ISP_IOMEM_CCDC, ISPCCDC_VERT_LINES);
1214
1215 ccdc_config_outlineoffset(ccdc, ccdc->video_out.bpl_value, 0, 0);
1216
1217 /* The CCDC outputs data in UYVY order by default. Swap bytes to get
1218 * YUYV.
1219 */
1220 if (format->code == V4L2_MBUS_FMT_YUYV8_1X16)
1221 isp_reg_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_CFG,
1222 ISPCCDC_CFG_BSWD);
1223 else
1224 isp_reg_clr(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_CFG,
1225 ISPCCDC_CFG_BSWD);
1226
1227 /* Use PACK8 mode for 1byte per pixel formats. */
1228 if (omap3isp_video_format_info(format->code)->width <= 8)
1229 syn_mode |= ISPCCDC_SYN_MODE_PACK8;
1230 else
1231 syn_mode &= ~ISPCCDC_SYN_MODE_PACK8;
1232
1233 isp_reg_writel(isp, syn_mode, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SYN_MODE);
1234
1235 /* CCDC_PAD_SOURCE_VP */
1236 format = &ccdc->formats[CCDC_PAD_SOURCE_VP];
1237
1238 isp_reg_writel(isp, (0 << ISPCCDC_FMT_HORZ_FMTSPH_SHIFT) |
1239 (format->width << ISPCCDC_FMT_HORZ_FMTLNH_SHIFT),
1240 OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FMT_HORZ);
1241 isp_reg_writel(isp, (0 << ISPCCDC_FMT_VERT_FMTSLV_SHIFT) |
1242 ((format->height + 1) << ISPCCDC_FMT_VERT_FMTLNV_SHIFT),
1243 OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FMT_VERT);
1244
1245 isp_reg_writel(isp, (format->width << ISPCCDC_VP_OUT_HORZ_NUM_SHIFT) |
1246 (format->height << ISPCCDC_VP_OUT_VERT_NUM_SHIFT),
1247 OMAP3_ISP_IOMEM_CCDC, ISPCCDC_VP_OUT);
1248
1249 /* Lens shading correction. */
1250 spin_lock_irqsave(&ccdc->lsc.req_lock, flags);
1251 if (ccdc->lsc.request == NULL)
1252 goto unlock;
1253
1254 WARN_ON(ccdc->lsc.active);
1255
1256 /* Get last good LSC configuration. If it is not supported for
1257 * the current active resolution discard it.
1258 */
1259 if (ccdc->lsc.active == NULL &&
1260 __ccdc_lsc_configure(ccdc, ccdc->lsc.request) == 0) {
1261 ccdc->lsc.active = ccdc->lsc.request;
1262 } else {
1263 list_add_tail(&ccdc->lsc.request->list, &ccdc->lsc.free_queue);
1264 schedule_work(&ccdc->lsc.table_work);
1265 }
1266
1267 ccdc->lsc.request = NULL;
1268
1269unlock:
1270 spin_unlock_irqrestore(&ccdc->lsc.req_lock, flags);
1271
1272 ccdc_apply_controls(ccdc);
1273}
1274
1275static void __ccdc_enable(struct isp_ccdc_device *ccdc, int enable)
1276{
1277 struct isp_device *isp = to_isp_device(ccdc);
1278
1279 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_PCR,
1280 ISPCCDC_PCR_EN, enable ? ISPCCDC_PCR_EN : 0);
1281}
1282
1283static int ccdc_disable(struct isp_ccdc_device *ccdc)
1284{
1285 unsigned long flags;
1286 int ret = 0;
1287
1288 spin_lock_irqsave(&ccdc->lock, flags);
1289 if (ccdc->state == ISP_PIPELINE_STREAM_CONTINUOUS)
1290 ccdc->stopping = CCDC_STOP_REQUEST;
1291 spin_unlock_irqrestore(&ccdc->lock, flags);
1292
1293 ret = wait_event_timeout(ccdc->wait,
1294 ccdc->stopping == CCDC_STOP_FINISHED,
1295 msecs_to_jiffies(2000));
1296 if (ret == 0) {
1297 ret = -ETIMEDOUT;
1298 dev_warn(to_device(ccdc), "CCDC stop timeout!\n");
1299 }
1300
1301 omap3isp_sbl_disable(to_isp_device(ccdc), OMAP3_ISP_SBL_CCDC_LSC_READ);
1302
1303 mutex_lock(&ccdc->ioctl_lock);
1304 ccdc_lsc_free_request(ccdc, ccdc->lsc.request);
1305 ccdc->lsc.request = ccdc->lsc.active;
1306 ccdc->lsc.active = NULL;
1307 cancel_work_sync(&ccdc->lsc.table_work);
1308 ccdc_lsc_free_queue(ccdc, &ccdc->lsc.free_queue);
1309 mutex_unlock(&ccdc->ioctl_lock);
1310
1311 ccdc->stopping = CCDC_STOP_NOT_REQUESTED;
1312
1313 return ret > 0 ? 0 : ret;
1314}
1315
1316static void ccdc_enable(struct isp_ccdc_device *ccdc)
1317{
1318 if (ccdc_lsc_is_configured(ccdc))
1319 __ccdc_lsc_enable(ccdc, 1);
1320 __ccdc_enable(ccdc, 1);
1321}
1322
1323/* -----------------------------------------------------------------------------
1324 * Interrupt handling
1325 */
1326
1327/*
1328 * ccdc_sbl_busy - Poll idle state of CCDC and related SBL memory write bits
1329 * @ccdc: Pointer to ISP CCDC device.
1330 *
1331 * Returns zero if the CCDC is idle and the image has been written to
1332 * memory, too.
1333 */
1334static int ccdc_sbl_busy(struct isp_ccdc_device *ccdc)
1335{
1336 struct isp_device *isp = to_isp_device(ccdc);
1337
1338 return omap3isp_ccdc_busy(ccdc)
1339 | (isp_reg_readl(isp, OMAP3_ISP_IOMEM_SBL, ISPSBL_CCDC_WR_0) &
1340 ISPSBL_CCDC_WR_0_DATA_READY)
1341 | (isp_reg_readl(isp, OMAP3_ISP_IOMEM_SBL, ISPSBL_CCDC_WR_1) &
1342 ISPSBL_CCDC_WR_0_DATA_READY)
1343 | (isp_reg_readl(isp, OMAP3_ISP_IOMEM_SBL, ISPSBL_CCDC_WR_2) &
1344 ISPSBL_CCDC_WR_0_DATA_READY)
1345 | (isp_reg_readl(isp, OMAP3_ISP_IOMEM_SBL, ISPSBL_CCDC_WR_3) &
1346 ISPSBL_CCDC_WR_0_DATA_READY);
1347}
1348
1349/*
1350 * ccdc_sbl_wait_idle - Wait until the CCDC and related SBL are idle
1351 * @ccdc: Pointer to ISP CCDC device.
1352 * @max_wait: Max retry count in us for wait for idle/busy transition.
1353 */
1354static int ccdc_sbl_wait_idle(struct isp_ccdc_device *ccdc,
1355 unsigned int max_wait)
1356{
1357 unsigned int wait = 0;
1358
1359 if (max_wait == 0)
1360 max_wait = 10000; /* 10 ms */
1361
1362 for (wait = 0; wait <= max_wait; wait++) {
1363 if (!ccdc_sbl_busy(ccdc))
1364 return 0;
1365
1366 rmb();
1367 udelay(1);
1368 }
1369
1370 return -EBUSY;
1371}
1372
1373/* __ccdc_handle_stopping - Handle CCDC and/or LSC stopping sequence
1374 * @ccdc: Pointer to ISP CCDC device.
1375 * @event: Pointing which event trigger handler
1376 *
1377 * Return 1 when the event and stopping request combination is satisfied,
1378 * zero otherwise.
1379 */
1380static int __ccdc_handle_stopping(struct isp_ccdc_device *ccdc, u32 event)
1381{
1382 int rval = 0;
1383
1384 switch ((ccdc->stopping & 3) | event) {
1385 case CCDC_STOP_REQUEST | CCDC_EVENT_VD1:
1386 if (ccdc->lsc.state != LSC_STATE_STOPPED)
1387 __ccdc_lsc_enable(ccdc, 0);
1388 __ccdc_enable(ccdc, 0);
1389 ccdc->stopping = CCDC_STOP_EXECUTED;
1390 return 1;
1391
1392 case CCDC_STOP_EXECUTED | CCDC_EVENT_VD0:
1393 ccdc->stopping |= CCDC_STOP_CCDC_FINISHED;
1394 if (ccdc->lsc.state == LSC_STATE_STOPPED)
1395 ccdc->stopping |= CCDC_STOP_LSC_FINISHED;
1396 rval = 1;
1397 break;
1398
1399 case CCDC_STOP_EXECUTED | CCDC_EVENT_LSC_DONE:
1400 ccdc->stopping |= CCDC_STOP_LSC_FINISHED;
1401 rval = 1;
1402 break;
1403
1404 case CCDC_STOP_EXECUTED | CCDC_EVENT_VD1:
1405 return 1;
1406 }
1407
1408 if (ccdc->stopping == CCDC_STOP_FINISHED) {
1409 wake_up(&ccdc->wait);
1410 rval = 1;
1411 }
1412
1413 return rval;
1414}
1415
1416static void ccdc_hs_vs_isr(struct isp_ccdc_device *ccdc)
1417{
1418 struct isp_pipeline *pipe = to_isp_pipeline(&ccdc->subdev.entity);
1419 struct video_device *vdev = ccdc->subdev.devnode;
1420 struct v4l2_event event;
1421
1422 /* Frame number propagation */
1423 atomic_inc(&pipe->frame_number);
1424
1425 memset(&event, 0, sizeof(event));
1426 event.type = V4L2_EVENT_FRAME_SYNC;
1427 event.u.frame_sync.frame_sequence = atomic_read(&pipe->frame_number);
1428
1429 v4l2_event_queue(vdev, &event);
1430}
1431
1432/*
1433 * ccdc_lsc_isr - Handle LSC events
1434 * @ccdc: Pointer to ISP CCDC device.
1435 * @events: LSC events
1436 */
1437static void ccdc_lsc_isr(struct isp_ccdc_device *ccdc, u32 events)
1438{
1439 unsigned long flags;
1440
1441 if (events & IRQ0STATUS_CCDC_LSC_PREF_ERR_IRQ) {
1442 struct isp_pipeline *pipe =
1443 to_isp_pipeline(&ccdc->subdev.entity);
1444
1445 ccdc_lsc_error_handler(ccdc);
1446 pipe->error = true;
1447 dev_dbg(to_device(ccdc), "lsc prefetch error\n");
1448 }
1449
1450 if (!(events & IRQ0STATUS_CCDC_LSC_DONE_IRQ))
1451 return;
1452
1453 /* LSC_DONE interrupt occur, there are two cases
1454 * 1. stopping for reconfiguration
1455 * 2. stopping because of STREAM OFF command
1456 */
1457 spin_lock_irqsave(&ccdc->lsc.req_lock, flags);
1458
1459 if (ccdc->lsc.state == LSC_STATE_STOPPING)
1460 ccdc->lsc.state = LSC_STATE_STOPPED;
1461
1462 if (__ccdc_handle_stopping(ccdc, CCDC_EVENT_LSC_DONE))
1463 goto done;
1464
1465 if (ccdc->lsc.state != LSC_STATE_RECONFIG)
1466 goto done;
1467
1468 /* LSC is in STOPPING state, change to the new state */
1469 ccdc->lsc.state = LSC_STATE_STOPPED;
1470
1471 /* This is an exception. Start of frame and LSC_DONE interrupt
1472 * have been received on the same time. Skip this event and wait
1473 * for better times.
1474 */
1475 if (events & IRQ0STATUS_HS_VS_IRQ)
1476 goto done;
1477
1478 /* The LSC engine is stopped at this point. Enable it if there's a
1479 * pending request.
1480 */
1481 if (ccdc->lsc.request == NULL)
1482 goto done;
1483
1484 ccdc_lsc_enable(ccdc);
1485
1486done:
1487 spin_unlock_irqrestore(&ccdc->lsc.req_lock, flags);
1488}
1489
1490static int ccdc_isr_buffer(struct isp_ccdc_device *ccdc)
1491{
1492 struct isp_pipeline *pipe = to_isp_pipeline(&ccdc->subdev.entity);
1493 struct isp_device *isp = to_isp_device(ccdc);
1494 struct isp_buffer *buffer;
1495 int restart = 0;
1496
1497 /* The CCDC generates VD0 interrupts even when disabled (the datasheet
1498 * doesn't explicitly state if that's supposed to happen or not, so it
1499 * can be considered as a hardware bug or as a feature, but we have to
1500 * deal with it anyway). Disabling the CCDC when no buffer is available
1501 * would thus not be enough, we need to handle the situation explicitly.
1502 */
1503 if (list_empty(&ccdc->video_out.dmaqueue))
1504 goto done;
1505
1506 /* We're in continuous mode, and memory writes were disabled due to a
1507 * buffer underrun. Reenable them now that we have a buffer. The buffer
1508 * address has been set in ccdc_video_queue.
1509 */
1510 if (ccdc->state == ISP_PIPELINE_STREAM_CONTINUOUS && ccdc->underrun) {
1511 restart = 1;
1512 ccdc->underrun = 0;
1513 goto done;
1514 }
1515
1516 if (ccdc_sbl_wait_idle(ccdc, 1000)) {
1517 dev_info(isp->dev, "CCDC won't become idle!\n");
1518 goto done;
1519 }
1520
1521 buffer = omap3isp_video_buffer_next(&ccdc->video_out);
1522 if (buffer != NULL) {
1523 ccdc_set_outaddr(ccdc, buffer->isp_addr);
1524 restart = 1;
1525 }
1526
1527 pipe->state |= ISP_PIPELINE_IDLE_OUTPUT;
1528
1529 if (ccdc->state == ISP_PIPELINE_STREAM_SINGLESHOT &&
1530 isp_pipeline_ready(pipe))
1531 omap3isp_pipeline_set_stream(pipe,
1532 ISP_PIPELINE_STREAM_SINGLESHOT);
1533
1534done:
1535 return restart;
1536}
1537
1538/*
1539 * ccdc_vd0_isr - Handle VD0 event
1540 * @ccdc: Pointer to ISP CCDC device.
1541 *
1542 * Executes LSC deferred enablement before next frame starts.
1543 */
1544static void ccdc_vd0_isr(struct isp_ccdc_device *ccdc)
1545{
1546 unsigned long flags;
1547 int restart = 0;
1548
1549 if (ccdc->output & CCDC_OUTPUT_MEMORY)
1550 restart = ccdc_isr_buffer(ccdc);
1551
1552 spin_lock_irqsave(&ccdc->lock, flags);
1553 if (__ccdc_handle_stopping(ccdc, CCDC_EVENT_VD0)) {
1554 spin_unlock_irqrestore(&ccdc->lock, flags);
1555 return;
1556 }
1557
1558 if (!ccdc->shadow_update)
1559 ccdc_apply_controls(ccdc);
1560 spin_unlock_irqrestore(&ccdc->lock, flags);
1561
1562 if (restart)
1563 ccdc_enable(ccdc);
1564}
1565
1566/*
1567 * ccdc_vd1_isr - Handle VD1 event
1568 * @ccdc: Pointer to ISP CCDC device.
1569 */
1570static void ccdc_vd1_isr(struct isp_ccdc_device *ccdc)
1571{
1572 unsigned long flags;
1573
1574 spin_lock_irqsave(&ccdc->lsc.req_lock, flags);
1575
1576 /*
1577 * Depending on the CCDC pipeline state, CCDC stopping should be
1578 * handled differently. In SINGLESHOT we emulate an internal CCDC
1579 * stopping because the CCDC hw works only in continuous mode.
1580 * When CONTINUOUS pipeline state is used and the CCDC writes it's
1581 * data to memory the CCDC and LSC are stopped immediately but
1582 * without change the CCDC stopping state machine. The CCDC
1583 * stopping state machine should be used only when user request
1584 * for stopping is received (SINGLESHOT is an exeption).
1585 */
1586 switch (ccdc->state) {
1587 case ISP_PIPELINE_STREAM_SINGLESHOT:
1588 ccdc->stopping = CCDC_STOP_REQUEST;
1589 break;
1590
1591 case ISP_PIPELINE_STREAM_CONTINUOUS:
1592 if (ccdc->output & CCDC_OUTPUT_MEMORY) {
1593 if (ccdc->lsc.state != LSC_STATE_STOPPED)
1594 __ccdc_lsc_enable(ccdc, 0);
1595 __ccdc_enable(ccdc, 0);
1596 }
1597 break;
1598
1599 case ISP_PIPELINE_STREAM_STOPPED:
1600 break;
1601 }
1602
1603 if (__ccdc_handle_stopping(ccdc, CCDC_EVENT_VD1))
1604 goto done;
1605
1606 if (ccdc->lsc.request == NULL)
1607 goto done;
1608
1609 /*
1610 * LSC need to be reconfigured. Stop it here and on next LSC_DONE IRQ
1611 * do the appropriate changes in registers
1612 */
1613 if (ccdc->lsc.state == LSC_STATE_RUNNING) {
1614 __ccdc_lsc_enable(ccdc, 0);
1615 ccdc->lsc.state = LSC_STATE_RECONFIG;
1616 goto done;
1617 }
1618
1619 /* LSC has been in STOPPED state, enable it */
1620 if (ccdc->lsc.state == LSC_STATE_STOPPED)
1621 ccdc_lsc_enable(ccdc);
1622
1623done:
1624 spin_unlock_irqrestore(&ccdc->lsc.req_lock, flags);
1625}
1626
1627/*
1628 * omap3isp_ccdc_isr - Configure CCDC during interframe time.
1629 * @ccdc: Pointer to ISP CCDC device.
1630 * @events: CCDC events
1631 */
1632int omap3isp_ccdc_isr(struct isp_ccdc_device *ccdc, u32 events)
1633{
1634 if (ccdc->state == ISP_PIPELINE_STREAM_STOPPED)
1635 return 0;
1636
1637 if (events & IRQ0STATUS_CCDC_VD1_IRQ)
1638 ccdc_vd1_isr(ccdc);
1639
1640 ccdc_lsc_isr(ccdc, events);
1641
1642 if (events & IRQ0STATUS_CCDC_VD0_IRQ)
1643 ccdc_vd0_isr(ccdc);
1644
1645 if (events & IRQ0STATUS_HS_VS_IRQ)
1646 ccdc_hs_vs_isr(ccdc);
1647
1648 return 0;
1649}
1650
1651/* -----------------------------------------------------------------------------
1652 * ISP video operations
1653 */
1654
1655static int ccdc_video_queue(struct isp_video *video, struct isp_buffer *buffer)
1656{
1657 struct isp_ccdc_device *ccdc = &video->isp->isp_ccdc;
1658
1659 if (!(ccdc->output & CCDC_OUTPUT_MEMORY))
1660 return -ENODEV;
1661
1662 ccdc_set_outaddr(ccdc, buffer->isp_addr);
1663
1664 /* We now have a buffer queued on the output, restart the pipeline
1665 * on the next CCDC interrupt if running in continuous mode (or when
1666 * starting the stream).
1667 */
1668 ccdc->underrun = 1;
1669
1670 return 0;
1671}
1672
1673static const struct isp_video_operations ccdc_video_ops = {
1674 .queue = ccdc_video_queue,
1675};
1676
1677/* -----------------------------------------------------------------------------
1678 * V4L2 subdev operations
1679 */
1680
1681/*
1682 * ccdc_ioctl - CCDC module private ioctl's
1683 * @sd: ISP CCDC V4L2 subdevice
1684 * @cmd: ioctl command
1685 * @arg: ioctl argument
1686 *
1687 * Return 0 on success or a negative error code otherwise.
1688 */
1689static long ccdc_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
1690{
1691 struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
1692 int ret;
1693
1694 switch (cmd) {
1695 case VIDIOC_OMAP3ISP_CCDC_CFG:
1696 mutex_lock(&ccdc->ioctl_lock);
1697 ret = ccdc_config(ccdc, arg);
1698 mutex_unlock(&ccdc->ioctl_lock);
1699 break;
1700
1701 default:
1702 return -ENOIOCTLCMD;
1703 }
1704
1705 return ret;
1706}
1707
1708static int ccdc_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
1709 struct v4l2_event_subscription *sub)
1710{
1711 if (sub->type != V4L2_EVENT_FRAME_SYNC)
1712 return -EINVAL;
1713
1714 /* line number is zero at frame start */
1715 if (sub->id != 0)
1716 return -EINVAL;
1717
1718 return v4l2_event_subscribe(fh, sub, OMAP3ISP_CCDC_NEVENTS, NULL);
1719}
1720
1721static int ccdc_unsubscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
1722 struct v4l2_event_subscription *sub)
1723{
1724 return v4l2_event_unsubscribe(fh, sub);
1725}
1726
1727/*
1728 * ccdc_set_stream - Enable/Disable streaming on the CCDC module
1729 * @sd: ISP CCDC V4L2 subdevice
1730 * @enable: Enable/disable stream
1731 *
1732 * When writing to memory, the CCDC hardware can't be enabled without a memory
1733 * buffer to write to. As the s_stream operation is called in response to a
1734 * STREAMON call without any buffer queued yet, just update the enabled field
1735 * and return immediately. The CCDC will be enabled in ccdc_isr_buffer().
1736 *
1737 * When not writing to memory enable the CCDC immediately.
1738 */
1739static int ccdc_set_stream(struct v4l2_subdev *sd, int enable)
1740{
1741 struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
1742 struct isp_device *isp = to_isp_device(ccdc);
1743 int ret = 0;
1744
1745 if (ccdc->state == ISP_PIPELINE_STREAM_STOPPED) {
1746 if (enable == ISP_PIPELINE_STREAM_STOPPED)
1747 return 0;
1748
1749 omap3isp_subclk_enable(isp, OMAP3_ISP_SUBCLK_CCDC);
1750 isp_reg_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_CFG,
1751 ISPCCDC_CFG_VDLC);
1752
1753 ccdc_configure(ccdc);
1754
1755 /* TODO: Don't configure the video port if all of its output
1756 * links are inactive.
1757 */
1758 ccdc_config_vp(ccdc);
1759 ccdc_enable_vp(ccdc, 1);
1760 ccdc_print_status(ccdc);
1761 }
1762
1763 switch (enable) {
1764 case ISP_PIPELINE_STREAM_CONTINUOUS:
1765 if (ccdc->output & CCDC_OUTPUT_MEMORY)
1766 omap3isp_sbl_enable(isp, OMAP3_ISP_SBL_CCDC_WRITE);
1767
1768 if (ccdc->underrun || !(ccdc->output & CCDC_OUTPUT_MEMORY))
1769 ccdc_enable(ccdc);
1770
1771 ccdc->underrun = 0;
1772 break;
1773
1774 case ISP_PIPELINE_STREAM_SINGLESHOT:
1775 if (ccdc->output & CCDC_OUTPUT_MEMORY &&
1776 ccdc->state != ISP_PIPELINE_STREAM_SINGLESHOT)
1777 omap3isp_sbl_enable(isp, OMAP3_ISP_SBL_CCDC_WRITE);
1778
1779 ccdc_enable(ccdc);
1780 break;
1781
1782 case ISP_PIPELINE_STREAM_STOPPED:
1783 ret = ccdc_disable(ccdc);
1784 if (ccdc->output & CCDC_OUTPUT_MEMORY)
1785 omap3isp_sbl_disable(isp, OMAP3_ISP_SBL_CCDC_WRITE);
1786 omap3isp_subclk_disable(isp, OMAP3_ISP_SUBCLK_CCDC);
1787 ccdc->underrun = 0;
1788 break;
1789 }
1790
1791 ccdc->state = enable;
1792 return ret;
1793}
1794
1795static struct v4l2_mbus_framefmt *
1796__ccdc_get_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh,
1797 unsigned int pad, enum v4l2_subdev_format_whence which)
1798{
1799 if (which == V4L2_SUBDEV_FORMAT_TRY)
1800 return v4l2_subdev_get_try_format(fh, pad);
1801 else
1802 return &ccdc->formats[pad];
1803}
1804
1805static struct v4l2_rect *
1806__ccdc_get_crop(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh,
1807 enum v4l2_subdev_format_whence which)
1808{
1809 if (which == V4L2_SUBDEV_FORMAT_TRY)
1810 return v4l2_subdev_get_try_crop(fh, CCDC_PAD_SOURCE_OF);
1811 else
1812 return &ccdc->crop;
1813}
1814
1815/*
1816 * ccdc_try_format - Try video format on a pad
1817 * @ccdc: ISP CCDC device
1818 * @fh : V4L2 subdev file handle
1819 * @pad: Pad number
1820 * @fmt: Format
1821 */
1822static void
1823ccdc_try_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh,
1824 unsigned int pad, struct v4l2_mbus_framefmt *fmt,
1825 enum v4l2_subdev_format_whence which)
1826{
1827 const struct isp_format_info *info;
1828 enum v4l2_mbus_pixelcode pixelcode;
1829 unsigned int width = fmt->width;
1830 unsigned int height = fmt->height;
1831 struct v4l2_rect *crop;
1832 unsigned int i;
1833
1834 switch (pad) {
1835 case CCDC_PAD_SINK:
1836 for (i = 0; i < ARRAY_SIZE(ccdc_fmts); i++) {
1837 if (fmt->code == ccdc_fmts[i])
1838 break;
1839 }
1840
1841 /* If not found, use SGRBG10 as default */
1842 if (i >= ARRAY_SIZE(ccdc_fmts))
1843 fmt->code = V4L2_MBUS_FMT_SGRBG10_1X10;
1844
1845 /* Clamp the input size. */
1846 fmt->width = clamp_t(u32, width, 32, 4096);
1847 fmt->height = clamp_t(u32, height, 32, 4096);
1848 break;
1849
1850 case CCDC_PAD_SOURCE_OF:
1851 pixelcode = fmt->code;
1852 *fmt = *__ccdc_get_format(ccdc, fh, CCDC_PAD_SINK, which);
1853
1854 /* YUV formats are converted from 2X8 to 1X16 by the bridge and
1855 * can be byte-swapped.
1856 */
1857 if (fmt->code == V4L2_MBUS_FMT_YUYV8_2X8 ||
1858 fmt->code == V4L2_MBUS_FMT_UYVY8_2X8) {
1859 /* Use the user requested format if YUV. */
1860 if (pixelcode == V4L2_MBUS_FMT_YUYV8_2X8 ||
1861 pixelcode == V4L2_MBUS_FMT_UYVY8_2X8 ||
1862 pixelcode == V4L2_MBUS_FMT_YUYV8_1X16 ||
1863 pixelcode == V4L2_MBUS_FMT_UYVY8_1X16)
1864 fmt->code = pixelcode;
1865
1866 if (fmt->code == V4L2_MBUS_FMT_YUYV8_2X8)
1867 fmt->code = V4L2_MBUS_FMT_YUYV8_1X16;
1868 else if (fmt->code == V4L2_MBUS_FMT_UYVY8_2X8)
1869 fmt->code = V4L2_MBUS_FMT_UYVY8_1X16;
1870 }
1871
1872 /* Hardcode the output size to the crop rectangle size. */
1873 crop = __ccdc_get_crop(ccdc, fh, which);
1874 fmt->width = crop->width;
1875 fmt->height = crop->height;
1876 break;
1877
1878 case CCDC_PAD_SOURCE_VP:
1879 *fmt = *__ccdc_get_format(ccdc, fh, CCDC_PAD_SINK, which);
1880
1881 /* The video port interface truncates the data to 10 bits. */
1882 info = omap3isp_video_format_info(fmt->code);
1883 fmt->code = info->truncated;
1884
1885 /* YUV formats are not supported by the video port. */
1886 if (fmt->code == V4L2_MBUS_FMT_YUYV8_2X8 ||
1887 fmt->code == V4L2_MBUS_FMT_UYVY8_2X8)
1888 fmt->code = 0;
1889
1890 /* The number of lines that can be clocked out from the video
1891 * port output must be at least one line less than the number
1892 * of input lines.
1893 */
1894 fmt->width = clamp_t(u32, width, 32, fmt->width);
1895 fmt->height = clamp_t(u32, height, 32, fmt->height - 1);
1896 break;
1897 }
1898
1899 /* Data is written to memory unpacked, each 10-bit or 12-bit pixel is
1900 * stored on 2 bytes.
1901 */
1902 fmt->colorspace = V4L2_COLORSPACE_SRGB;
1903 fmt->field = V4L2_FIELD_NONE;
1904}
1905
1906/*
1907 * ccdc_try_crop - Validate a crop rectangle
1908 * @ccdc: ISP CCDC device
1909 * @sink: format on the sink pad
1910 * @crop: crop rectangle to be validated
1911 */
1912static void ccdc_try_crop(struct isp_ccdc_device *ccdc,
1913 const struct v4l2_mbus_framefmt *sink,
1914 struct v4l2_rect *crop)
1915{
1916 const struct isp_format_info *info;
1917 unsigned int max_width;
1918
1919 /* For Bayer formats, restrict left/top and width/height to even values
1920 * to keep the Bayer pattern.
1921 */
1922 info = omap3isp_video_format_info(sink->code);
1923 if (info->flavor != V4L2_MBUS_FMT_Y8_1X8) {
1924 crop->left &= ~1;
1925 crop->top &= ~1;
1926 }
1927
1928 crop->left = clamp_t(u32, crop->left, 0, sink->width - CCDC_MIN_WIDTH);
1929 crop->top = clamp_t(u32, crop->top, 0, sink->height - CCDC_MIN_HEIGHT);
1930
1931 /* The data formatter truncates the number of horizontal output pixels
1932 * to a multiple of 16. To avoid clipping data, allow callers to request
1933 * an output size bigger than the input size up to the nearest multiple
1934 * of 16.
1935 */
1936 max_width = (sink->width - crop->left + 15) & ~15;
1937 crop->width = clamp_t(u32, crop->width, CCDC_MIN_WIDTH, max_width)
1938 & ~15;
1939 crop->height = clamp_t(u32, crop->height, CCDC_MIN_HEIGHT,
1940 sink->height - crop->top);
1941
1942 /* Odd width/height values don't make sense for Bayer formats. */
1943 if (info->flavor != V4L2_MBUS_FMT_Y8_1X8) {
1944 crop->width &= ~1;
1945 crop->height &= ~1;
1946 }
1947}
1948
1949/*
1950 * ccdc_enum_mbus_code - Handle pixel format enumeration
1951 * @sd : pointer to v4l2 subdev structure
1952 * @fh : V4L2 subdev file handle
1953 * @code : pointer to v4l2_subdev_mbus_code_enum structure
1954 * return -EINVAL or zero on success
1955 */
1956static int ccdc_enum_mbus_code(struct v4l2_subdev *sd,
1957 struct v4l2_subdev_fh *fh,
1958 struct v4l2_subdev_mbus_code_enum *code)
1959{
1960 struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
1961 struct v4l2_mbus_framefmt *format;
1962
1963 switch (code->pad) {
1964 case CCDC_PAD_SINK:
1965 if (code->index >= ARRAY_SIZE(ccdc_fmts))
1966 return -EINVAL;
1967
1968 code->code = ccdc_fmts[code->index];
1969 break;
1970
1971 case CCDC_PAD_SOURCE_OF:
1972 format = __ccdc_get_format(ccdc, fh, code->pad,
1973 V4L2_SUBDEV_FORMAT_TRY);
1974
1975 if (format->code == V4L2_MBUS_FMT_YUYV8_2X8 ||
1976 format->code == V4L2_MBUS_FMT_UYVY8_2X8) {
1977 /* In YUV mode the CCDC can swap bytes. */
1978 if (code->index == 0)
1979 code->code = V4L2_MBUS_FMT_YUYV8_1X16;
1980 else if (code->index == 1)
1981 code->code = V4L2_MBUS_FMT_UYVY8_1X16;
1982 else
1983 return -EINVAL;
1984 } else {
1985 /* In raw mode, no configurable format confversion is
1986 * available.
1987 */
1988 if (code->index == 0)
1989 code->code = format->code;
1990 else
1991 return -EINVAL;
1992 }
1993 break;
1994
1995 case CCDC_PAD_SOURCE_VP:
1996 /* The CCDC supports no configurable format conversion
1997 * compatible with the video port. Enumerate a single output
1998 * format code.
1999 */
2000 if (code->index != 0)
2001 return -EINVAL;
2002
2003 format = __ccdc_get_format(ccdc, fh, code->pad,
2004 V4L2_SUBDEV_FORMAT_TRY);
2005
2006 /* A pixel code equal to 0 means that the video port doesn't
2007 * support the input format. Don't enumerate any pixel code.
2008 */
2009 if (format->code == 0)
2010 return -EINVAL;
2011
2012 code->code = format->code;
2013 break;
2014
2015 default:
2016 return -EINVAL;
2017 }
2018
2019 return 0;
2020}
2021
2022static int ccdc_enum_frame_size(struct v4l2_subdev *sd,
2023 struct v4l2_subdev_fh *fh,
2024 struct v4l2_subdev_frame_size_enum *fse)
2025{
2026 struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
2027 struct v4l2_mbus_framefmt format;
2028
2029 if (fse->index != 0)
2030 return -EINVAL;
2031
2032 format.code = fse->code;
2033 format.width = 1;
2034 format.height = 1;
2035 ccdc_try_format(ccdc, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY);
2036 fse->min_width = format.width;
2037 fse->min_height = format.height;
2038
2039 if (format.code != fse->code)
2040 return -EINVAL;
2041
2042 format.code = fse->code;
2043 format.width = -1;
2044 format.height = -1;
2045 ccdc_try_format(ccdc, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY);
2046 fse->max_width = format.width;
2047 fse->max_height = format.height;
2048
2049 return 0;
2050}
2051
2052/*
2053 * ccdc_get_selection - Retrieve a selection rectangle on a pad
2054 * @sd: ISP CCDC V4L2 subdevice
2055 * @fh: V4L2 subdev file handle
2056 * @sel: Selection rectangle
2057 *
2058 * The only supported rectangles are the crop rectangles on the output formatter
2059 * source pad.
2060 *
2061 * Return 0 on success or a negative error code otherwise.
2062 */
2063static int ccdc_get_selection(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
2064 struct v4l2_subdev_selection *sel)
2065{
2066 struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
2067 struct v4l2_mbus_framefmt *format;
2068
2069 if (sel->pad != CCDC_PAD_SOURCE_OF)
2070 return -EINVAL;
2071
2072 switch (sel->target) {
2073 case V4L2_SEL_TGT_CROP_BOUNDS:
2074 sel->r.left = 0;
2075 sel->r.top = 0;
2076 sel->r.width = INT_MAX;
2077 sel->r.height = INT_MAX;
2078
2079 format = __ccdc_get_format(ccdc, fh, CCDC_PAD_SINK, sel->which);
2080 ccdc_try_crop(ccdc, format, &sel->r);
2081 break;
2082
2083 case V4L2_SEL_TGT_CROP:
2084 sel->r = *__ccdc_get_crop(ccdc, fh, sel->which);
2085 break;
2086
2087 default:
2088 return -EINVAL;
2089 }
2090
2091 return 0;
2092}
2093
2094/*
2095 * ccdc_set_selection - Set a selection rectangle on a pad
2096 * @sd: ISP CCDC V4L2 subdevice
2097 * @fh: V4L2 subdev file handle
2098 * @sel: Selection rectangle
2099 *
2100 * The only supported rectangle is the actual crop rectangle on the output
2101 * formatter source pad.
2102 *
2103 * Return 0 on success or a negative error code otherwise.
2104 */
2105static int ccdc_set_selection(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
2106 struct v4l2_subdev_selection *sel)
2107{
2108 struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
2109 struct v4l2_mbus_framefmt *format;
2110
2111 if (sel->target != V4L2_SEL_TGT_CROP ||
2112 sel->pad != CCDC_PAD_SOURCE_OF)
2113 return -EINVAL;
2114
2115 /* The crop rectangle can't be changed while streaming. */
2116 if (ccdc->state != ISP_PIPELINE_STREAM_STOPPED)
2117 return -EBUSY;
2118
2119 /* Modifying the crop rectangle always changes the format on the source
2120 * pad. If the KEEP_CONFIG flag is set, just return the current crop
2121 * rectangle.
2122 */
2123 if (sel->flags & V4L2_SEL_FLAG_KEEP_CONFIG) {
2124 sel->r = *__ccdc_get_crop(ccdc, fh, sel->which);
2125 return 0;
2126 }
2127
2128 format = __ccdc_get_format(ccdc, fh, CCDC_PAD_SINK, sel->which);
2129 ccdc_try_crop(ccdc, format, &sel->r);
2130 *__ccdc_get_crop(ccdc, fh, sel->which) = sel->r;
2131
2132 /* Update the source format. */
2133 format = __ccdc_get_format(ccdc, fh, CCDC_PAD_SOURCE_OF, sel->which);
2134 ccdc_try_format(ccdc, fh, CCDC_PAD_SOURCE_OF, format, sel->which);
2135
2136 return 0;
2137}
2138
2139/*
2140 * ccdc_get_format - Retrieve the video format on a pad
2141 * @sd : ISP CCDC V4L2 subdevice
2142 * @fh : V4L2 subdev file handle
2143 * @fmt: Format
2144 *
2145 * Return 0 on success or -EINVAL if the pad is invalid or doesn't correspond
2146 * to the format type.
2147 */
2148static int ccdc_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
2149 struct v4l2_subdev_format *fmt)
2150{
2151 struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
2152 struct v4l2_mbus_framefmt *format;
2153
2154 format = __ccdc_get_format(ccdc, fh, fmt->pad, fmt->which);
2155 if (format == NULL)
2156 return -EINVAL;
2157
2158 fmt->format = *format;
2159 return 0;
2160}
2161
2162/*
2163 * ccdc_set_format - Set the video format on a pad
2164 * @sd : ISP CCDC V4L2 subdevice
2165 * @fh : V4L2 subdev file handle
2166 * @fmt: Format
2167 *
2168 * Return 0 on success or -EINVAL if the pad is invalid or doesn't correspond
2169 * to the format type.
2170 */
2171static int ccdc_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
2172 struct v4l2_subdev_format *fmt)
2173{
2174 struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
2175 struct v4l2_mbus_framefmt *format;
2176 struct v4l2_rect *crop;
2177
2178 format = __ccdc_get_format(ccdc, fh, fmt->pad, fmt->which);
2179 if (format == NULL)
2180 return -EINVAL;
2181
2182 ccdc_try_format(ccdc, fh, fmt->pad, &fmt->format, fmt->which);
2183 *format = fmt->format;
2184
2185 /* Propagate the format from sink to source */
2186 if (fmt->pad == CCDC_PAD_SINK) {
2187 /* Reset the crop rectangle. */
2188 crop = __ccdc_get_crop(ccdc, fh, fmt->which);
2189 crop->left = 0;
2190 crop->top = 0;
2191 crop->width = fmt->format.width;
2192 crop->height = fmt->format.height;
2193
2194 ccdc_try_crop(ccdc, &fmt->format, crop);
2195
2196 /* Update the source formats. */
2197 format = __ccdc_get_format(ccdc, fh, CCDC_PAD_SOURCE_OF,
2198 fmt->which);
2199 *format = fmt->format;
2200 ccdc_try_format(ccdc, fh, CCDC_PAD_SOURCE_OF, format,
2201 fmt->which);
2202
2203 format = __ccdc_get_format(ccdc, fh, CCDC_PAD_SOURCE_VP,
2204 fmt->which);
2205 *format = fmt->format;
2206 ccdc_try_format(ccdc, fh, CCDC_PAD_SOURCE_VP, format,
2207 fmt->which);
2208 }
2209
2210 return 0;
2211}
2212
2213/*
2214 * Decide whether desired output pixel code can be obtained with
2215 * the lane shifter by shifting the input pixel code.
2216 * @in: input pixelcode to shifter
2217 * @out: output pixelcode from shifter
2218 * @additional_shift: # of bits the sensor's LSB is offset from CAMEXT[0]
2219 *
2220 * return true if the combination is possible
2221 * return false otherwise
2222 */
2223static bool ccdc_is_shiftable(enum v4l2_mbus_pixelcode in,
2224 enum v4l2_mbus_pixelcode out,
2225 unsigned int additional_shift)
2226{
2227 const struct isp_format_info *in_info, *out_info;
2228
2229 if (in == out)
2230 return true;
2231
2232 in_info = omap3isp_video_format_info(in);
2233 out_info = omap3isp_video_format_info(out);
2234
2235 if ((in_info->flavor == 0) || (out_info->flavor == 0))
2236 return false;
2237
2238 if (in_info->flavor != out_info->flavor)
2239 return false;
2240
2241 return in_info->width - out_info->width + additional_shift <= 6;
2242}
2243
2244static int ccdc_link_validate(struct v4l2_subdev *sd,
2245 struct media_link *link,
2246 struct v4l2_subdev_format *source_fmt,
2247 struct v4l2_subdev_format *sink_fmt)
2248{
2249 struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
2250 unsigned long parallel_shift;
2251
2252 /* Check if the two ends match */
2253 if (source_fmt->format.width != sink_fmt->format.width ||
2254 source_fmt->format.height != sink_fmt->format.height)
2255 return -EPIPE;
2256
2257 /* We've got a parallel sensor here. */
2258 if (ccdc->input == CCDC_INPUT_PARALLEL) {
2259 struct isp_parallel_platform_data *pdata =
2260 &((struct isp_v4l2_subdevs_group *)
2261 media_entity_to_v4l2_subdev(link->source->entity)
2262 ->host_priv)->bus.parallel;
2263 parallel_shift = pdata->data_lane_shift * 2;
2264 } else {
2265 parallel_shift = 0;
2266 }
2267
2268 /* Lane shifter may be used to drop bits on CCDC sink pad */
2269 if (!ccdc_is_shiftable(source_fmt->format.code,
2270 sink_fmt->format.code, parallel_shift))
2271 return -EPIPE;
2272
2273 return 0;
2274}
2275
2276/*
2277 * ccdc_init_formats - Initialize formats on all pads
2278 * @sd: ISP CCDC V4L2 subdevice
2279 * @fh: V4L2 subdev file handle
2280 *
2281 * Initialize all pad formats with default values. If fh is not NULL, try
2282 * formats are initialized on the file handle. Otherwise active formats are
2283 * initialized on the device.
2284 */
2285static int ccdc_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
2286{
2287 struct v4l2_subdev_format format;
2288
2289 memset(&format, 0, sizeof(format));
2290 format.pad = CCDC_PAD_SINK;
2291 format.which = fh ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE;
2292 format.format.code = V4L2_MBUS_FMT_SGRBG10_1X10;
2293 format.format.width = 4096;
2294 format.format.height = 4096;
2295 ccdc_set_format(sd, fh, &format);
2296
2297 return 0;
2298}
2299
2300/* V4L2 subdev core operations */
2301static const struct v4l2_subdev_core_ops ccdc_v4l2_core_ops = {
2302 .ioctl = ccdc_ioctl,
2303 .subscribe_event = ccdc_subscribe_event,
2304 .unsubscribe_event = ccdc_unsubscribe_event,
2305};
2306
2307/* V4L2 subdev video operations */
2308static const struct v4l2_subdev_video_ops ccdc_v4l2_video_ops = {
2309 .s_stream = ccdc_set_stream,
2310};
2311
2312/* V4L2 subdev pad operations */
2313static const struct v4l2_subdev_pad_ops ccdc_v4l2_pad_ops = {
2314 .enum_mbus_code = ccdc_enum_mbus_code,
2315 .enum_frame_size = ccdc_enum_frame_size,
2316 .get_fmt = ccdc_get_format,
2317 .set_fmt = ccdc_set_format,
2318 .get_selection = ccdc_get_selection,
2319 .set_selection = ccdc_set_selection,
2320 .link_validate = ccdc_link_validate,
2321};
2322
2323/* V4L2 subdev operations */
2324static const struct v4l2_subdev_ops ccdc_v4l2_ops = {
2325 .core = &ccdc_v4l2_core_ops,
2326 .video = &ccdc_v4l2_video_ops,
2327 .pad = &ccdc_v4l2_pad_ops,
2328};
2329
2330/* V4L2 subdev internal operations */
2331static const struct v4l2_subdev_internal_ops ccdc_v4l2_internal_ops = {
2332 .open = ccdc_init_formats,
2333};
2334
2335/* -----------------------------------------------------------------------------
2336 * Media entity operations
2337 */
2338
2339/*
2340 * ccdc_link_setup - Setup CCDC connections
2341 * @entity: CCDC media entity
2342 * @local: Pad at the local end of the link
2343 * @remote: Pad at the remote end of the link
2344 * @flags: Link flags
2345 *
2346 * return -EINVAL or zero on success
2347 */
2348static int ccdc_link_setup(struct media_entity *entity,
2349 const struct media_pad *local,
2350 const struct media_pad *remote, u32 flags)
2351{
2352 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
2353 struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
2354 struct isp_device *isp = to_isp_device(ccdc);
2355
2356 switch (local->index | media_entity_type(remote->entity)) {
2357 case CCDC_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV:
2358 /* Read from the sensor (parallel interface), CCP2, CSI2a or
2359 * CSI2c.
2360 */
2361 if (!(flags & MEDIA_LNK_FL_ENABLED)) {
2362 ccdc->input = CCDC_INPUT_NONE;
2363 break;
2364 }
2365
2366 if (ccdc->input != CCDC_INPUT_NONE)
2367 return -EBUSY;
2368
2369 if (remote->entity == &isp->isp_ccp2.subdev.entity)
2370 ccdc->input = CCDC_INPUT_CCP2B;
2371 else if (remote->entity == &isp->isp_csi2a.subdev.entity)
2372 ccdc->input = CCDC_INPUT_CSI2A;
2373 else if (remote->entity == &isp->isp_csi2c.subdev.entity)
2374 ccdc->input = CCDC_INPUT_CSI2C;
2375 else
2376 ccdc->input = CCDC_INPUT_PARALLEL;
2377
2378 break;
2379
2380 /*
2381 * The ISP core doesn't support pipelines with multiple video outputs.
2382 * Revisit this when it will be implemented, and return -EBUSY for now.
2383 */
2384
2385 case CCDC_PAD_SOURCE_VP | MEDIA_ENT_T_V4L2_SUBDEV:
2386 /* Write to preview engine, histogram and H3A. When none of
2387 * those links are active, the video port can be disabled.
2388 */
2389 if (flags & MEDIA_LNK_FL_ENABLED) {
2390 if (ccdc->output & ~CCDC_OUTPUT_PREVIEW)
2391 return -EBUSY;
2392 ccdc->output |= CCDC_OUTPUT_PREVIEW;
2393 } else {
2394 ccdc->output &= ~CCDC_OUTPUT_PREVIEW;
2395 }
2396 break;
2397
2398 case CCDC_PAD_SOURCE_OF | MEDIA_ENT_T_DEVNODE:
2399 /* Write to memory */
2400 if (flags & MEDIA_LNK_FL_ENABLED) {
2401 if (ccdc->output & ~CCDC_OUTPUT_MEMORY)
2402 return -EBUSY;
2403 ccdc->output |= CCDC_OUTPUT_MEMORY;
2404 } else {
2405 ccdc->output &= ~CCDC_OUTPUT_MEMORY;
2406 }
2407 break;
2408
2409 case CCDC_PAD_SOURCE_OF | MEDIA_ENT_T_V4L2_SUBDEV:
2410 /* Write to resizer */
2411 if (flags & MEDIA_LNK_FL_ENABLED) {
2412 if (ccdc->output & ~CCDC_OUTPUT_RESIZER)
2413 return -EBUSY;
2414 ccdc->output |= CCDC_OUTPUT_RESIZER;
2415 } else {
2416 ccdc->output &= ~CCDC_OUTPUT_RESIZER;
2417 }
2418 break;
2419
2420 default:
2421 return -EINVAL;
2422 }
2423
2424 return 0;
2425}
2426
2427/* media operations */
2428static const struct media_entity_operations ccdc_media_ops = {
2429 .link_setup = ccdc_link_setup,
2430 .link_validate = v4l2_subdev_link_validate,
2431};
2432
2433void omap3isp_ccdc_unregister_entities(struct isp_ccdc_device *ccdc)
2434{
2435 v4l2_device_unregister_subdev(&ccdc->subdev);
2436 omap3isp_video_unregister(&ccdc->video_out);
2437}
2438
2439int omap3isp_ccdc_register_entities(struct isp_ccdc_device *ccdc,
2440 struct v4l2_device *vdev)
2441{
2442 int ret;
2443
2444 /* Register the subdev and video node. */
2445 ret = v4l2_device_register_subdev(vdev, &ccdc->subdev);
2446 if (ret < 0)
2447 goto error;
2448
2449 ret = omap3isp_video_register(&ccdc->video_out, vdev);
2450 if (ret < 0)
2451 goto error;
2452
2453 return 0;
2454
2455error:
2456 omap3isp_ccdc_unregister_entities(ccdc);
2457 return ret;
2458}
2459
2460/* -----------------------------------------------------------------------------
2461 * ISP CCDC initialisation and cleanup
2462 */
2463
2464/*
2465 * ccdc_init_entities - Initialize V4L2 subdev and media entity
2466 * @ccdc: ISP CCDC module
2467 *
2468 * Return 0 on success and a negative error code on failure.
2469 */
2470static int ccdc_init_entities(struct isp_ccdc_device *ccdc)
2471{
2472 struct v4l2_subdev *sd = &ccdc->subdev;
2473 struct media_pad *pads = ccdc->pads;
2474 struct media_entity *me = &sd->entity;
2475 int ret;
2476
2477 ccdc->input = CCDC_INPUT_NONE;
2478
2479 v4l2_subdev_init(sd, &ccdc_v4l2_ops);
2480 sd->internal_ops = &ccdc_v4l2_internal_ops;
2481 strlcpy(sd->name, "OMAP3 ISP CCDC", sizeof(sd->name));
2482 sd->grp_id = 1 << 16; /* group ID for isp subdevs */
2483 v4l2_set_subdevdata(sd, ccdc);
2484 sd->flags |= V4L2_SUBDEV_FL_HAS_EVENTS | V4L2_SUBDEV_FL_HAS_DEVNODE;
2485
2486 pads[CCDC_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
2487 pads[CCDC_PAD_SOURCE_VP].flags = MEDIA_PAD_FL_SOURCE;
2488 pads[CCDC_PAD_SOURCE_OF].flags = MEDIA_PAD_FL_SOURCE;
2489
2490 me->ops = &ccdc_media_ops;
2491 ret = media_entity_init(me, CCDC_PADS_NUM, pads, 0);
2492 if (ret < 0)
2493 return ret;
2494
2495 ccdc_init_formats(sd, NULL);
2496
2497 ccdc->video_out.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2498 ccdc->video_out.ops = &ccdc_video_ops;
2499 ccdc->video_out.isp = to_isp_device(ccdc);
2500 ccdc->video_out.capture_mem = PAGE_ALIGN(4096 * 4096) * 3;
2501 ccdc->video_out.bpl_alignment = 32;
2502
2503 ret = omap3isp_video_init(&ccdc->video_out, "CCDC");
2504 if (ret < 0)
2505 goto error_video;
2506
2507 /* Connect the CCDC subdev to the video node. */
2508 ret = media_entity_create_link(&ccdc->subdev.entity, CCDC_PAD_SOURCE_OF,
2509 &ccdc->video_out.video.entity, 0, 0);
2510 if (ret < 0)
2511 goto error_link;
2512
2513 return 0;
2514
2515error_link:
2516 omap3isp_video_cleanup(&ccdc->video_out);
2517error_video:
2518 media_entity_cleanup(me);
2519 return ret;
2520}
2521
2522/*
2523 * omap3isp_ccdc_init - CCDC module initialization.
2524 * @dev: Device pointer specific to the OMAP3 ISP.
2525 *
2526 * TODO: Get the initialisation values from platform data.
2527 *
2528 * Return 0 on success or a negative error code otherwise.
2529 */
2530int omap3isp_ccdc_init(struct isp_device *isp)
2531{
2532 struct isp_ccdc_device *ccdc = &isp->isp_ccdc;
2533 int ret;
2534
2535 spin_lock_init(&ccdc->lock);
2536 init_waitqueue_head(&ccdc->wait);
2537 mutex_init(&ccdc->ioctl_lock);
2538
2539 ccdc->stopping = CCDC_STOP_NOT_REQUESTED;
2540
2541 INIT_WORK(&ccdc->lsc.table_work, ccdc_lsc_free_table_work);
2542 ccdc->lsc.state = LSC_STATE_STOPPED;
2543 INIT_LIST_HEAD(&ccdc->lsc.free_queue);
2544 spin_lock_init(&ccdc->lsc.req_lock);
2545
2546 ccdc->clamp.oblen = 0;
2547 ccdc->clamp.dcsubval = 0;
2548
2549 ccdc->update = OMAP3ISP_CCDC_BLCLAMP;
2550 ccdc_apply_controls(ccdc);
2551
2552 ret = ccdc_init_entities(ccdc);
2553 if (ret < 0) {
2554 mutex_destroy(&ccdc->ioctl_lock);
2555 return ret;
2556 }
2557
2558 return 0;
2559}
2560
2561/*
2562 * omap3isp_ccdc_cleanup - CCDC module cleanup.
2563 * @dev: Device pointer specific to the OMAP3 ISP.
2564 */
2565void omap3isp_ccdc_cleanup(struct isp_device *isp)
2566{
2567 struct isp_ccdc_device *ccdc = &isp->isp_ccdc;
2568
2569 omap3isp_video_cleanup(&ccdc->video_out);
2570 media_entity_cleanup(&ccdc->subdev.entity);
2571
2572 /* Free LSC requests. As the CCDC is stopped there's no active request,
2573 * so only the pending request and the free queue need to be handled.
2574 */
2575 ccdc_lsc_free_request(ccdc, ccdc->lsc.request);
2576 cancel_work_sync(&ccdc->lsc.table_work);
2577 ccdc_lsc_free_queue(ccdc, &ccdc->lsc.free_queue);
2578
2579 if (ccdc->fpc.fpcaddr != 0)
2580 omap_iommu_vfree(isp->domain, isp->dev, ccdc->fpc.fpcaddr);
2581
2582 mutex_destroy(&ccdc->ioctl_lock);
2583}
diff --git a/drivers/media/video/omap3isp/ispccdc.h b/drivers/media/video/omap3isp/ispccdc.h
deleted file mode 100644
index a5da9e19edbf..000000000000
--- a/drivers/media/video/omap3isp/ispccdc.h
+++ /dev/null
@@ -1,172 +0,0 @@
1/*
2 * ispccdc.h
3 *
4 * TI OMAP3 ISP - CCDC module
5 *
6 * Copyright (C) 2009-2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc.
8 *
9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 * Sakari Ailus <sakari.ailus@iki.fi>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 */
26
27#ifndef OMAP3_ISP_CCDC_H
28#define OMAP3_ISP_CCDC_H
29
30#include <linux/omap3isp.h>
31#include <linux/workqueue.h>
32
33#include "ispvideo.h"
34
35enum ccdc_input_entity {
36 CCDC_INPUT_NONE,
37 CCDC_INPUT_PARALLEL,
38 CCDC_INPUT_CSI2A,
39 CCDC_INPUT_CCP2B,
40 CCDC_INPUT_CSI2C
41};
42
43#define CCDC_OUTPUT_MEMORY (1 << 0)
44#define CCDC_OUTPUT_PREVIEW (1 << 1)
45#define CCDC_OUTPUT_RESIZER (1 << 2)
46
47#define OMAP3ISP_CCDC_NEVENTS 16
48
49enum ispccdc_lsc_state {
50 LSC_STATE_STOPPED = 0,
51 LSC_STATE_STOPPING = 1,
52 LSC_STATE_RUNNING = 2,
53 LSC_STATE_RECONFIG = 3,
54};
55
56struct ispccdc_lsc_config_req {
57 struct list_head list;
58 struct omap3isp_ccdc_lsc_config config;
59 unsigned char enable;
60 u32 table;
61 struct iovm_struct *iovm;
62};
63
64/*
65 * ispccdc_lsc - CCDC LSC parameters
66 * @update_config: Set when user changes config
67 * @request_enable: Whether LSC is requested to be enabled
68 * @config: LSC config set by user
69 * @update_table: Set when user provides a new LSC table to table_new
70 * @table_new: LSC table set by user, ISP address
71 * @table_inuse: LSC table currently in use, ISP address
72 */
73struct ispccdc_lsc {
74 enum ispccdc_lsc_state state;
75 struct work_struct table_work;
76
77 /* LSC queue of configurations */
78 spinlock_t req_lock;
79 struct ispccdc_lsc_config_req *request; /* requested configuration */
80 struct ispccdc_lsc_config_req *active; /* active configuration */
81 struct list_head free_queue; /* configurations for freeing */
82};
83
84#define CCDC_STOP_NOT_REQUESTED 0x00
85#define CCDC_STOP_REQUEST 0x01
86#define CCDC_STOP_EXECUTED (0x02 | CCDC_STOP_REQUEST)
87#define CCDC_STOP_CCDC_FINISHED 0x04
88#define CCDC_STOP_LSC_FINISHED 0x08
89#define CCDC_STOP_FINISHED \
90 (CCDC_STOP_EXECUTED | CCDC_STOP_CCDC_FINISHED | CCDC_STOP_LSC_FINISHED)
91
92#define CCDC_EVENT_VD1 0x10
93#define CCDC_EVENT_VD0 0x20
94#define CCDC_EVENT_LSC_DONE 0x40
95
96/* Sink and source CCDC pads */
97#define CCDC_PAD_SINK 0
98#define CCDC_PAD_SOURCE_OF 1
99#define CCDC_PAD_SOURCE_VP 2
100#define CCDC_PADS_NUM 3
101
102/*
103 * struct isp_ccdc_device - Structure for the CCDC module to store its own
104 * information
105 * @subdev: V4L2 subdevice
106 * @pads: Sink and source media entity pads
107 * @formats: Active video formats
108 * @crop: Active crop rectangle on the OF source pad
109 * @input: Active input
110 * @output: Active outputs
111 * @video_out: Output video node
112 * @alaw: A-law compression enabled (1) or disabled (0)
113 * @lpf: Low pass filter enabled (1) or disabled (0)
114 * @obclamp: Optical-black clamp enabled (1) or disabled (0)
115 * @fpc_en: Faulty pixels correction enabled (1) or disabled (0)
116 * @blcomp: Black level compensation configuration
117 * @clamp: Optical-black or digital clamp configuration
118 * @fpc: Faulty pixels correction configuration
119 * @lsc: Lens shading compensation configuration
120 * @update: Bitmask of controls to update during the next interrupt
121 * @shadow_update: Controls update in progress by userspace
122 * @underrun: A buffer underrun occurred and a new buffer has been queued
123 * @state: Streaming state
124 * @lock: Serializes shadow_update with interrupt handler
125 * @wait: Wait queue used to stop the module
126 * @stopping: Stopping state
127 * @ioctl_lock: Serializes ioctl calls and LSC requests freeing
128 */
129struct isp_ccdc_device {
130 struct v4l2_subdev subdev;
131 struct media_pad pads[CCDC_PADS_NUM];
132 struct v4l2_mbus_framefmt formats[CCDC_PADS_NUM];
133 struct v4l2_rect crop;
134
135 enum ccdc_input_entity input;
136 unsigned int output;
137 struct isp_video video_out;
138
139 unsigned int alaw:1,
140 lpf:1,
141 obclamp:1,
142 fpc_en:1;
143 struct omap3isp_ccdc_blcomp blcomp;
144 struct omap3isp_ccdc_bclamp clamp;
145 struct omap3isp_ccdc_fpc fpc;
146 struct ispccdc_lsc lsc;
147 unsigned int update;
148 unsigned int shadow_update;
149
150 unsigned int underrun:1;
151 enum isp_pipeline_stream_state state;
152 spinlock_t lock;
153 wait_queue_head_t wait;
154 unsigned int stopping;
155 struct mutex ioctl_lock;
156};
157
158struct isp_device;
159
160int omap3isp_ccdc_init(struct isp_device *isp);
161void omap3isp_ccdc_cleanup(struct isp_device *isp);
162int omap3isp_ccdc_register_entities(struct isp_ccdc_device *ccdc,
163 struct v4l2_device *vdev);
164void omap3isp_ccdc_unregister_entities(struct isp_ccdc_device *ccdc);
165
166int omap3isp_ccdc_busy(struct isp_ccdc_device *isp_ccdc);
167int omap3isp_ccdc_isr(struct isp_ccdc_device *isp_ccdc, u32 events);
168void omap3isp_ccdc_restore_context(struct isp_device *isp);
169void omap3isp_ccdc_max_rate(struct isp_ccdc_device *ccdc,
170 unsigned int *max_rate);
171
172#endif /* OMAP3_ISP_CCDC_H */
diff --git a/drivers/media/video/omap3isp/ispccp2.c b/drivers/media/video/omap3isp/ispccp2.c
deleted file mode 100644
index 85f0de85f37c..000000000000
--- a/drivers/media/video/omap3isp/ispccp2.c
+++ /dev/null
@@ -1,1171 +0,0 @@
1/*
2 * ispccp2.c
3 *
4 * TI OMAP3 ISP - CCP2 module
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2010 Texas Instruments, Inc.
8 *
9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 * Sakari Ailus <sakari.ailus@iki.fi>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 */
26
27#include <linux/delay.h>
28#include <linux/device.h>
29#include <linux/mm.h>
30#include <linux/module.h>
31#include <linux/mutex.h>
32#include <linux/uaccess.h>
33#include <linux/regulator/consumer.h>
34
35#include "isp.h"
36#include "ispreg.h"
37#include "ispccp2.h"
38
39/* Number of LCX channels */
40#define CCP2_LCx_CHANS_NUM 3
41/* Max/Min size for CCP2 video port */
42#define ISPCCP2_DAT_START_MIN 0
43#define ISPCCP2_DAT_START_MAX 4095
44#define ISPCCP2_DAT_SIZE_MIN 0
45#define ISPCCP2_DAT_SIZE_MAX 4095
46#define ISPCCP2_VPCLK_FRACDIV 65536
47#define ISPCCP2_LCx_CTRL_FORMAT_RAW8_DPCM10_VP 0x12
48#define ISPCCP2_LCx_CTRL_FORMAT_RAW10_VP 0x16
49/* Max/Min size for CCP2 memory channel */
50#define ISPCCP2_LCM_HSIZE_COUNT_MIN 16
51#define ISPCCP2_LCM_HSIZE_COUNT_MAX 8191
52#define ISPCCP2_LCM_HSIZE_SKIP_MIN 0
53#define ISPCCP2_LCM_HSIZE_SKIP_MAX 8191
54#define ISPCCP2_LCM_VSIZE_MIN 1
55#define ISPCCP2_LCM_VSIZE_MAX 8191
56#define ISPCCP2_LCM_HWORDS_MIN 1
57#define ISPCCP2_LCM_HWORDS_MAX 4095
58#define ISPCCP2_LCM_CTRL_BURST_SIZE_32X 5
59#define ISPCCP2_LCM_CTRL_READ_THROTTLE_FULL 0
60#define ISPCCP2_LCM_CTRL_SRC_DECOMPR_DPCM10 2
61#define ISPCCP2_LCM_CTRL_SRC_FORMAT_RAW8 2
62#define ISPCCP2_LCM_CTRL_SRC_FORMAT_RAW10 3
63#define ISPCCP2_LCM_CTRL_DST_FORMAT_RAW10 3
64#define ISPCCP2_LCM_CTRL_DST_PORT_VP 0
65#define ISPCCP2_LCM_CTRL_DST_PORT_MEM 1
66
67/* Set only the required bits */
68#define BIT_SET(var, shift, mask, val) \
69 do { \
70 var = ((var) & ~((mask) << (shift))) \
71 | ((val) << (shift)); \
72 } while (0)
73
74/*
75 * ccp2_print_status - Print current CCP2 module register values.
76 */
77#define CCP2_PRINT_REGISTER(isp, name)\
78 dev_dbg(isp->dev, "###CCP2 " #name "=0x%08x\n", \
79 isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_##name))
80
81static void ccp2_print_status(struct isp_ccp2_device *ccp2)
82{
83 struct isp_device *isp = to_isp_device(ccp2);
84
85 dev_dbg(isp->dev, "-------------CCP2 Register dump-------------\n");
86
87 CCP2_PRINT_REGISTER(isp, SYSCONFIG);
88 CCP2_PRINT_REGISTER(isp, SYSSTATUS);
89 CCP2_PRINT_REGISTER(isp, LC01_IRQENABLE);
90 CCP2_PRINT_REGISTER(isp, LC01_IRQSTATUS);
91 CCP2_PRINT_REGISTER(isp, LC23_IRQENABLE);
92 CCP2_PRINT_REGISTER(isp, LC23_IRQSTATUS);
93 CCP2_PRINT_REGISTER(isp, LCM_IRQENABLE);
94 CCP2_PRINT_REGISTER(isp, LCM_IRQSTATUS);
95 CCP2_PRINT_REGISTER(isp, CTRL);
96 CCP2_PRINT_REGISTER(isp, LCx_CTRL(0));
97 CCP2_PRINT_REGISTER(isp, LCx_CODE(0));
98 CCP2_PRINT_REGISTER(isp, LCx_STAT_START(0));
99 CCP2_PRINT_REGISTER(isp, LCx_STAT_SIZE(0));
100 CCP2_PRINT_REGISTER(isp, LCx_SOF_ADDR(0));
101 CCP2_PRINT_REGISTER(isp, LCx_EOF_ADDR(0));
102 CCP2_PRINT_REGISTER(isp, LCx_DAT_START(0));
103 CCP2_PRINT_REGISTER(isp, LCx_DAT_SIZE(0));
104 CCP2_PRINT_REGISTER(isp, LCx_DAT_PING_ADDR(0));
105 CCP2_PRINT_REGISTER(isp, LCx_DAT_PONG_ADDR(0));
106 CCP2_PRINT_REGISTER(isp, LCx_DAT_OFST(0));
107 CCP2_PRINT_REGISTER(isp, LCM_CTRL);
108 CCP2_PRINT_REGISTER(isp, LCM_VSIZE);
109 CCP2_PRINT_REGISTER(isp, LCM_HSIZE);
110 CCP2_PRINT_REGISTER(isp, LCM_PREFETCH);
111 CCP2_PRINT_REGISTER(isp, LCM_SRC_ADDR);
112 CCP2_PRINT_REGISTER(isp, LCM_SRC_OFST);
113 CCP2_PRINT_REGISTER(isp, LCM_DST_ADDR);
114 CCP2_PRINT_REGISTER(isp, LCM_DST_OFST);
115
116 dev_dbg(isp->dev, "--------------------------------------------\n");
117}
118
119/*
120 * ccp2_reset - Reset the CCP2
121 * @ccp2: pointer to ISP CCP2 device
122 */
123static void ccp2_reset(struct isp_ccp2_device *ccp2)
124{
125 struct isp_device *isp = to_isp_device(ccp2);
126 int i = 0;
127
128 /* Reset the CSI1/CCP2B and wait for reset to complete */
129 isp_reg_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_SYSCONFIG,
130 ISPCCP2_SYSCONFIG_SOFT_RESET);
131 while (!(isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_SYSSTATUS) &
132 ISPCCP2_SYSSTATUS_RESET_DONE)) {
133 udelay(10);
134 if (i++ > 10) { /* try read 10 times */
135 dev_warn(isp->dev,
136 "omap3_isp: timeout waiting for ccp2 reset\n");
137 break;
138 }
139 }
140}
141
142/*
143 * ccp2_pwr_cfg - Configure the power mode settings
144 * @ccp2: pointer to ISP CCP2 device
145 */
146static void ccp2_pwr_cfg(struct isp_ccp2_device *ccp2)
147{
148 struct isp_device *isp = to_isp_device(ccp2);
149
150 isp_reg_writel(isp, ISPCCP2_SYSCONFIG_MSTANDBY_MODE_SMART |
151 ((isp->revision == ISP_REVISION_15_0 && isp->autoidle) ?
152 ISPCCP2_SYSCONFIG_AUTO_IDLE : 0),
153 OMAP3_ISP_IOMEM_CCP2, ISPCCP2_SYSCONFIG);
154}
155
156/*
157 * ccp2_if_enable - Enable CCP2 interface.
158 * @ccp2: pointer to ISP CCP2 device
159 * @enable: enable/disable flag
160 */
161static void ccp2_if_enable(struct isp_ccp2_device *ccp2, u8 enable)
162{
163 struct isp_device *isp = to_isp_device(ccp2);
164 int i;
165
166 if (enable && ccp2->vdds_csib)
167 regulator_enable(ccp2->vdds_csib);
168
169 /* Enable/Disable all the LCx channels */
170 for (i = 0; i < CCP2_LCx_CHANS_NUM; i++)
171 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCx_CTRL(i),
172 ISPCCP2_LCx_CTRL_CHAN_EN,
173 enable ? ISPCCP2_LCx_CTRL_CHAN_EN : 0);
174
175 /* Enable/Disable ccp2 interface in ccp2 mode */
176 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL,
177 ISPCCP2_CTRL_MODE | ISPCCP2_CTRL_IF_EN,
178 enable ? (ISPCCP2_CTRL_MODE | ISPCCP2_CTRL_IF_EN) : 0);
179
180 if (!enable && ccp2->vdds_csib)
181 regulator_disable(ccp2->vdds_csib);
182}
183
184/*
185 * ccp2_mem_enable - Enable CCP2 memory interface.
186 * @ccp2: pointer to ISP CCP2 device
187 * @enable: enable/disable flag
188 */
189static void ccp2_mem_enable(struct isp_ccp2_device *ccp2, u8 enable)
190{
191 struct isp_device *isp = to_isp_device(ccp2);
192
193 if (enable)
194 ccp2_if_enable(ccp2, 0);
195
196 /* Enable/Disable ccp2 interface in ccp2 mode */
197 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL,
198 ISPCCP2_CTRL_MODE, enable ? ISPCCP2_CTRL_MODE : 0);
199
200 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCM_CTRL,
201 ISPCCP2_LCM_CTRL_CHAN_EN,
202 enable ? ISPCCP2_LCM_CTRL_CHAN_EN : 0);
203}
204
205/*
206 * ccp2_phyif_config - Initialize CCP2 phy interface config
207 * @ccp2: Pointer to ISP CCP2 device
208 * @config: CCP2 platform data
209 *
210 * Configure the CCP2 physical interface module from platform data.
211 *
212 * Returns -EIO if strobe is chosen in CSI1 mode, or 0 on success.
213 */
214static int ccp2_phyif_config(struct isp_ccp2_device *ccp2,
215 const struct isp_ccp2_platform_data *pdata)
216{
217 struct isp_device *isp = to_isp_device(ccp2);
218 u32 val;
219
220 /* CCP2B mode */
221 val = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL) |
222 ISPCCP2_CTRL_IO_OUT_SEL | ISPCCP2_CTRL_MODE;
223 /* Data/strobe physical layer */
224 BIT_SET(val, ISPCCP2_CTRL_PHY_SEL_SHIFT, ISPCCP2_CTRL_PHY_SEL_MASK,
225 pdata->phy_layer);
226 BIT_SET(val, ISPCCP2_CTRL_INV_SHIFT, ISPCCP2_CTRL_INV_MASK,
227 pdata->strobe_clk_pol);
228 isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL);
229
230 val = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL);
231 if (!(val & ISPCCP2_CTRL_MODE)) {
232 if (pdata->ccp2_mode == ISP_CCP2_MODE_CCP2)
233 dev_warn(isp->dev, "OMAP3 CCP2 bus not available\n");
234 if (pdata->phy_layer == ISP_CCP2_PHY_DATA_STROBE)
235 /* Strobe mode requires CCP2 */
236 return -EIO;
237 }
238
239 return 0;
240}
241
242/*
243 * ccp2_vp_config - Initialize CCP2 video port interface.
244 * @ccp2: Pointer to ISP CCP2 device
245 * @vpclk_div: Video port divisor
246 *
247 * Configure the CCP2 video port with the given clock divisor. The valid divisor
248 * values depend on the ISP revision:
249 *
250 * - revision 1.0 and 2.0 1 to 4
251 * - revision 15.0 1 to 65536
252 *
253 * The exact divisor value used might differ from the requested value, as ISP
254 * revision 15.0 represent the divisor by 65536 divided by an integer.
255 */
256static void ccp2_vp_config(struct isp_ccp2_device *ccp2,
257 unsigned int vpclk_div)
258{
259 struct isp_device *isp = to_isp_device(ccp2);
260 u32 val;
261
262 /* ISPCCP2_CTRL Video port */
263 val = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL);
264 val |= ISPCCP2_CTRL_VP_ONLY_EN; /* Disable the memory write port */
265
266 if (isp->revision == ISP_REVISION_15_0) {
267 vpclk_div = clamp_t(unsigned int, vpclk_div, 1, 65536);
268 vpclk_div = min(ISPCCP2_VPCLK_FRACDIV / vpclk_div, 65535U);
269 BIT_SET(val, ISPCCP2_CTRL_VPCLK_DIV_SHIFT,
270 ISPCCP2_CTRL_VPCLK_DIV_MASK, vpclk_div);
271 } else {
272 vpclk_div = clamp_t(unsigned int, vpclk_div, 1, 4);
273 BIT_SET(val, ISPCCP2_CTRL_VP_OUT_CTRL_SHIFT,
274 ISPCCP2_CTRL_VP_OUT_CTRL_MASK, vpclk_div - 1);
275 }
276
277 isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL);
278}
279
280/*
281 * ccp2_lcx_config - Initialize CCP2 logical channel interface.
282 * @ccp2: Pointer to ISP CCP2 device
283 * @config: Pointer to ISP LCx config structure.
284 *
285 * This will analyze the parameters passed by the interface config
286 * and configure CSI1/CCP2 logical channel
287 *
288 */
289static void ccp2_lcx_config(struct isp_ccp2_device *ccp2,
290 struct isp_interface_lcx_config *config)
291{
292 struct isp_device *isp = to_isp_device(ccp2);
293 u32 val, format;
294
295 switch (config->format) {
296 case V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8:
297 format = ISPCCP2_LCx_CTRL_FORMAT_RAW8_DPCM10_VP;
298 break;
299 case V4L2_MBUS_FMT_SGRBG10_1X10:
300 default:
301 format = ISPCCP2_LCx_CTRL_FORMAT_RAW10_VP; /* RAW10+VP */
302 break;
303 }
304 /* ISPCCP2_LCx_CTRL logical channel #0 */
305 val = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCx_CTRL(0))
306 | (ISPCCP2_LCx_CTRL_REGION_EN); /* Region */
307
308 if (isp->revision == ISP_REVISION_15_0) {
309 /* CRC */
310 BIT_SET(val, ISPCCP2_LCx_CTRL_CRC_SHIFT_15_0,
311 ISPCCP2_LCx_CTRL_CRC_MASK,
312 config->crc);
313 /* Format = RAW10+VP or RAW8+DPCM10+VP*/
314 BIT_SET(val, ISPCCP2_LCx_CTRL_FORMAT_SHIFT_15_0,
315 ISPCCP2_LCx_CTRL_FORMAT_MASK_15_0, format);
316 } else {
317 BIT_SET(val, ISPCCP2_LCx_CTRL_CRC_SHIFT,
318 ISPCCP2_LCx_CTRL_CRC_MASK,
319 config->crc);
320
321 BIT_SET(val, ISPCCP2_LCx_CTRL_FORMAT_SHIFT,
322 ISPCCP2_LCx_CTRL_FORMAT_MASK, format);
323 }
324 isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCx_CTRL(0));
325
326 /* ISPCCP2_DAT_START for logical channel #0 */
327 isp_reg_writel(isp, config->data_start << ISPCCP2_LCx_DAT_SHIFT,
328 OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCx_DAT_START(0));
329
330 /* ISPCCP2_DAT_SIZE for logical channel #0 */
331 isp_reg_writel(isp, config->data_size << ISPCCP2_LCx_DAT_SHIFT,
332 OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCx_DAT_SIZE(0));
333
334 /* Enable error IRQs for logical channel #0 */
335 val = ISPCCP2_LC01_IRQSTATUS_LC0_FIFO_OVF_IRQ |
336 ISPCCP2_LC01_IRQSTATUS_LC0_CRC_IRQ |
337 ISPCCP2_LC01_IRQSTATUS_LC0_FSP_IRQ |
338 ISPCCP2_LC01_IRQSTATUS_LC0_FW_IRQ |
339 ISPCCP2_LC01_IRQSTATUS_LC0_FSC_IRQ |
340 ISPCCP2_LC01_IRQSTATUS_LC0_SSC_IRQ;
341
342 isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LC01_IRQSTATUS);
343 isp_reg_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LC01_IRQENABLE, val);
344}
345
346/*
347 * ccp2_if_configure - Configure ccp2 with data from sensor
348 * @ccp2: Pointer to ISP CCP2 device
349 *
350 * Return 0 on success or a negative error code
351 */
352static int ccp2_if_configure(struct isp_ccp2_device *ccp2)
353{
354 const struct isp_v4l2_subdevs_group *pdata;
355 struct v4l2_mbus_framefmt *format;
356 struct media_pad *pad;
357 struct v4l2_subdev *sensor;
358 u32 lines = 0;
359 int ret;
360
361 ccp2_pwr_cfg(ccp2);
362
363 pad = media_entity_remote_source(&ccp2->pads[CCP2_PAD_SINK]);
364 sensor = media_entity_to_v4l2_subdev(pad->entity);
365 pdata = sensor->host_priv;
366
367 ret = ccp2_phyif_config(ccp2, &pdata->bus.ccp2);
368 if (ret < 0)
369 return ret;
370
371 ccp2_vp_config(ccp2, pdata->bus.ccp2.vpclk_div + 1);
372
373 v4l2_subdev_call(sensor, sensor, g_skip_top_lines, &lines);
374
375 format = &ccp2->formats[CCP2_PAD_SINK];
376
377 ccp2->if_cfg.data_start = lines;
378 ccp2->if_cfg.crc = pdata->bus.ccp2.crc;
379 ccp2->if_cfg.format = format->code;
380 ccp2->if_cfg.data_size = format->height;
381
382 ccp2_lcx_config(ccp2, &ccp2->if_cfg);
383
384 return 0;
385}
386
387static int ccp2_adjust_bandwidth(struct isp_ccp2_device *ccp2)
388{
389 struct isp_pipeline *pipe = to_isp_pipeline(&ccp2->subdev.entity);
390 struct isp_device *isp = to_isp_device(ccp2);
391 const struct v4l2_mbus_framefmt *ofmt = &ccp2->formats[CCP2_PAD_SOURCE];
392 unsigned long l3_ick = pipe->l3_ick;
393 struct v4l2_fract *timeperframe;
394 unsigned int vpclk_div = 2;
395 unsigned int value;
396 u64 bound;
397 u64 area;
398
399 /* Compute the minimum clock divisor, based on the pipeline maximum
400 * data rate. This is an absolute lower bound if we don't want SBL
401 * overflows, so round the value up.
402 */
403 vpclk_div = max_t(unsigned int, DIV_ROUND_UP(l3_ick, pipe->max_rate),
404 vpclk_div);
405
406 /* Compute the maximum clock divisor, based on the requested frame rate.
407 * This is a soft lower bound to achieve a frame rate equal or higher
408 * than the requested value, so round the value down.
409 */
410 timeperframe = &pipe->max_timeperframe;
411
412 if (timeperframe->numerator) {
413 area = ofmt->width * ofmt->height;
414 bound = div_u64(area * timeperframe->denominator,
415 timeperframe->numerator);
416 value = min_t(u64, bound, l3_ick);
417 vpclk_div = max_t(unsigned int, l3_ick / value, vpclk_div);
418 }
419
420 dev_dbg(isp->dev, "%s: minimum clock divisor = %u\n", __func__,
421 vpclk_div);
422
423 return vpclk_div;
424}
425
426/*
427 * ccp2_mem_configure - Initialize CCP2 memory input/output interface
428 * @ccp2: Pointer to ISP CCP2 device
429 * @config: Pointer to ISP mem interface config structure
430 *
431 * This will analyze the parameters passed by the interface config
432 * structure, and configure the respective registers for proper
433 * CSI1/CCP2 memory input.
434 */
435static void ccp2_mem_configure(struct isp_ccp2_device *ccp2,
436 struct isp_interface_mem_config *config)
437{
438 struct isp_device *isp = to_isp_device(ccp2);
439 u32 sink_pixcode = ccp2->formats[CCP2_PAD_SINK].code;
440 u32 source_pixcode = ccp2->formats[CCP2_PAD_SOURCE].code;
441 unsigned int dpcm_decompress = 0;
442 u32 val, hwords;
443
444 if (sink_pixcode != source_pixcode &&
445 sink_pixcode == V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8)
446 dpcm_decompress = 1;
447
448 ccp2_pwr_cfg(ccp2);
449
450 /* Hsize, Skip */
451 isp_reg_writel(isp, ISPCCP2_LCM_HSIZE_SKIP_MIN |
452 (config->hsize_count << ISPCCP2_LCM_HSIZE_SHIFT),
453 OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCM_HSIZE);
454
455 /* Vsize, no. of lines */
456 isp_reg_writel(isp, config->vsize_count << ISPCCP2_LCM_VSIZE_SHIFT,
457 OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCM_VSIZE);
458
459 if (ccp2->video_in.bpl_padding == 0)
460 config->src_ofst = 0;
461 else
462 config->src_ofst = ccp2->video_in.bpl_value;
463
464 isp_reg_writel(isp, config->src_ofst, OMAP3_ISP_IOMEM_CCP2,
465 ISPCCP2_LCM_SRC_OFST);
466
467 /* Source and Destination formats */
468 val = ISPCCP2_LCM_CTRL_DST_FORMAT_RAW10 <<
469 ISPCCP2_LCM_CTRL_DST_FORMAT_SHIFT;
470
471 if (dpcm_decompress) {
472 /* source format is RAW8 */
473 val |= ISPCCP2_LCM_CTRL_SRC_FORMAT_RAW8 <<
474 ISPCCP2_LCM_CTRL_SRC_FORMAT_SHIFT;
475
476 /* RAW8 + DPCM10 - simple predictor */
477 val |= ISPCCP2_LCM_CTRL_SRC_DPCM_PRED;
478
479 /* enable source DPCM decompression */
480 val |= ISPCCP2_LCM_CTRL_SRC_DECOMPR_DPCM10 <<
481 ISPCCP2_LCM_CTRL_SRC_DECOMPR_SHIFT;
482 } else {
483 /* source format is RAW10 */
484 val |= ISPCCP2_LCM_CTRL_SRC_FORMAT_RAW10 <<
485 ISPCCP2_LCM_CTRL_SRC_FORMAT_SHIFT;
486 }
487
488 /* Burst size to 32x64 */
489 val |= ISPCCP2_LCM_CTRL_BURST_SIZE_32X <<
490 ISPCCP2_LCM_CTRL_BURST_SIZE_SHIFT;
491
492 isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCM_CTRL);
493
494 /* Prefetch setup */
495 if (dpcm_decompress)
496 hwords = (ISPCCP2_LCM_HSIZE_SKIP_MIN +
497 config->hsize_count) >> 3;
498 else
499 hwords = (ISPCCP2_LCM_HSIZE_SKIP_MIN +
500 config->hsize_count) >> 2;
501
502 isp_reg_writel(isp, hwords << ISPCCP2_LCM_PREFETCH_SHIFT,
503 OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCM_PREFETCH);
504
505 /* Video port */
506 isp_reg_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL,
507 ISPCCP2_CTRL_IO_OUT_SEL | ISPCCP2_CTRL_MODE);
508 ccp2_vp_config(ccp2, ccp2_adjust_bandwidth(ccp2));
509
510 /* Clear LCM interrupts */
511 isp_reg_writel(isp, ISPCCP2_LCM_IRQSTATUS_OCPERROR_IRQ |
512 ISPCCP2_LCM_IRQSTATUS_EOF_IRQ,
513 OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCM_IRQSTATUS);
514
515 /* Enable LCM interupts */
516 isp_reg_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCM_IRQENABLE,
517 ISPCCP2_LCM_IRQSTATUS_EOF_IRQ |
518 ISPCCP2_LCM_IRQSTATUS_OCPERROR_IRQ);
519}
520
521/*
522 * ccp2_set_inaddr - Sets memory address of input frame.
523 * @ccp2: Pointer to ISP CCP2 device
524 * @addr: 32bit memory address aligned on 32byte boundary.
525 *
526 * Configures the memory address from which the input frame is to be read.
527 */
528static void ccp2_set_inaddr(struct isp_ccp2_device *ccp2, u32 addr)
529{
530 struct isp_device *isp = to_isp_device(ccp2);
531
532 isp_reg_writel(isp, addr, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCM_SRC_ADDR);
533}
534
535/* -----------------------------------------------------------------------------
536 * Interrupt handling
537 */
538
539static void ccp2_isr_buffer(struct isp_ccp2_device *ccp2)
540{
541 struct isp_pipeline *pipe = to_isp_pipeline(&ccp2->subdev.entity);
542 struct isp_buffer *buffer;
543
544 buffer = omap3isp_video_buffer_next(&ccp2->video_in);
545 if (buffer != NULL)
546 ccp2_set_inaddr(ccp2, buffer->isp_addr);
547
548 pipe->state |= ISP_PIPELINE_IDLE_INPUT;
549
550 if (ccp2->state == ISP_PIPELINE_STREAM_SINGLESHOT) {
551 if (isp_pipeline_ready(pipe))
552 omap3isp_pipeline_set_stream(pipe,
553 ISP_PIPELINE_STREAM_SINGLESHOT);
554 }
555}
556
557/*
558 * omap3isp_ccp2_isr - Handle ISP CCP2 interrupts
559 * @ccp2: Pointer to ISP CCP2 device
560 *
561 * This will handle the CCP2 interrupts
562 */
563void omap3isp_ccp2_isr(struct isp_ccp2_device *ccp2)
564{
565 struct isp_pipeline *pipe = to_isp_pipeline(&ccp2->subdev.entity);
566 struct isp_device *isp = to_isp_device(ccp2);
567 static const u32 ISPCCP2_LC01_ERROR =
568 ISPCCP2_LC01_IRQSTATUS_LC0_FIFO_OVF_IRQ |
569 ISPCCP2_LC01_IRQSTATUS_LC0_CRC_IRQ |
570 ISPCCP2_LC01_IRQSTATUS_LC0_FSP_IRQ |
571 ISPCCP2_LC01_IRQSTATUS_LC0_FW_IRQ |
572 ISPCCP2_LC01_IRQSTATUS_LC0_FSC_IRQ |
573 ISPCCP2_LC01_IRQSTATUS_LC0_SSC_IRQ;
574 u32 lcx_irqstatus, lcm_irqstatus;
575
576 /* First clear the interrupts */
577 lcx_irqstatus = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2,
578 ISPCCP2_LC01_IRQSTATUS);
579 isp_reg_writel(isp, lcx_irqstatus, OMAP3_ISP_IOMEM_CCP2,
580 ISPCCP2_LC01_IRQSTATUS);
581
582 lcm_irqstatus = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2,
583 ISPCCP2_LCM_IRQSTATUS);
584 isp_reg_writel(isp, lcm_irqstatus, OMAP3_ISP_IOMEM_CCP2,
585 ISPCCP2_LCM_IRQSTATUS);
586 /* Errors */
587 if (lcx_irqstatus & ISPCCP2_LC01_ERROR) {
588 pipe->error = true;
589 dev_dbg(isp->dev, "CCP2 err:%x\n", lcx_irqstatus);
590 return;
591 }
592
593 if (lcm_irqstatus & ISPCCP2_LCM_IRQSTATUS_OCPERROR_IRQ) {
594 pipe->error = true;
595 dev_dbg(isp->dev, "CCP2 OCP err:%x\n", lcm_irqstatus);
596 }
597
598 if (omap3isp_module_sync_is_stopping(&ccp2->wait, &ccp2->stopping))
599 return;
600
601 /* Handle queued buffers on frame end interrupts */
602 if (lcm_irqstatus & ISPCCP2_LCM_IRQSTATUS_EOF_IRQ)
603 ccp2_isr_buffer(ccp2);
604}
605
606/* -----------------------------------------------------------------------------
607 * V4L2 subdev operations
608 */
609
610static const unsigned int ccp2_fmts[] = {
611 V4L2_MBUS_FMT_SGRBG10_1X10,
612 V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8,
613};
614
615/*
616 * __ccp2_get_format - helper function for getting ccp2 format
617 * @ccp2 : Pointer to ISP CCP2 device
618 * @fh : V4L2 subdev file handle
619 * @pad : pad number
620 * @which : wanted subdev format
621 * return format structure or NULL on error
622 */
623static struct v4l2_mbus_framefmt *
624__ccp2_get_format(struct isp_ccp2_device *ccp2, struct v4l2_subdev_fh *fh,
625 unsigned int pad, enum v4l2_subdev_format_whence which)
626{
627 if (which == V4L2_SUBDEV_FORMAT_TRY)
628 return v4l2_subdev_get_try_format(fh, pad);
629 else
630 return &ccp2->formats[pad];
631}
632
633/*
634 * ccp2_try_format - Handle try format by pad subdev method
635 * @ccp2 : Pointer to ISP CCP2 device
636 * @fh : V4L2 subdev file handle
637 * @pad : pad num
638 * @fmt : pointer to v4l2 mbus format structure
639 * @which : wanted subdev format
640 */
641static void ccp2_try_format(struct isp_ccp2_device *ccp2,
642 struct v4l2_subdev_fh *fh, unsigned int pad,
643 struct v4l2_mbus_framefmt *fmt,
644 enum v4l2_subdev_format_whence which)
645{
646 struct v4l2_mbus_framefmt *format;
647
648 switch (pad) {
649 case CCP2_PAD_SINK:
650 if (fmt->code != V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8)
651 fmt->code = V4L2_MBUS_FMT_SGRBG10_1X10;
652
653 if (ccp2->input == CCP2_INPUT_SENSOR) {
654 fmt->width = clamp_t(u32, fmt->width,
655 ISPCCP2_DAT_START_MIN,
656 ISPCCP2_DAT_START_MAX);
657 fmt->height = clamp_t(u32, fmt->height,
658 ISPCCP2_DAT_SIZE_MIN,
659 ISPCCP2_DAT_SIZE_MAX);
660 } else if (ccp2->input == CCP2_INPUT_MEMORY) {
661 fmt->width = clamp_t(u32, fmt->width,
662 ISPCCP2_LCM_HSIZE_COUNT_MIN,
663 ISPCCP2_LCM_HSIZE_COUNT_MAX);
664 fmt->height = clamp_t(u32, fmt->height,
665 ISPCCP2_LCM_VSIZE_MIN,
666 ISPCCP2_LCM_VSIZE_MAX);
667 }
668 break;
669
670 case CCP2_PAD_SOURCE:
671 /* Source format - copy sink format and change pixel code
672 * to SGRBG10_1X10 as we don't support CCP2 write to memory.
673 * When CCP2 write to memory feature will be added this
674 * should be changed properly.
675 */
676 format = __ccp2_get_format(ccp2, fh, CCP2_PAD_SINK, which);
677 memcpy(fmt, format, sizeof(*fmt));
678 fmt->code = V4L2_MBUS_FMT_SGRBG10_1X10;
679 break;
680 }
681
682 fmt->field = V4L2_FIELD_NONE;
683 fmt->colorspace = V4L2_COLORSPACE_SRGB;
684}
685
686/*
687 * ccp2_enum_mbus_code - Handle pixel format enumeration
688 * @sd : pointer to v4l2 subdev structure
689 * @fh : V4L2 subdev file handle
690 * @code : pointer to v4l2_subdev_mbus_code_enum structure
691 * return -EINVAL or zero on success
692 */
693static int ccp2_enum_mbus_code(struct v4l2_subdev *sd,
694 struct v4l2_subdev_fh *fh,
695 struct v4l2_subdev_mbus_code_enum *code)
696{
697 struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd);
698 struct v4l2_mbus_framefmt *format;
699
700 if (code->pad == CCP2_PAD_SINK) {
701 if (code->index >= ARRAY_SIZE(ccp2_fmts))
702 return -EINVAL;
703
704 code->code = ccp2_fmts[code->index];
705 } else {
706 if (code->index != 0)
707 return -EINVAL;
708
709 format = __ccp2_get_format(ccp2, fh, CCP2_PAD_SINK,
710 V4L2_SUBDEV_FORMAT_TRY);
711 code->code = format->code;
712 }
713
714 return 0;
715}
716
717static int ccp2_enum_frame_size(struct v4l2_subdev *sd,
718 struct v4l2_subdev_fh *fh,
719 struct v4l2_subdev_frame_size_enum *fse)
720{
721 struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd);
722 struct v4l2_mbus_framefmt format;
723
724 if (fse->index != 0)
725 return -EINVAL;
726
727 format.code = fse->code;
728 format.width = 1;
729 format.height = 1;
730 ccp2_try_format(ccp2, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY);
731 fse->min_width = format.width;
732 fse->min_height = format.height;
733
734 if (format.code != fse->code)
735 return -EINVAL;
736
737 format.code = fse->code;
738 format.width = -1;
739 format.height = -1;
740 ccp2_try_format(ccp2, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY);
741 fse->max_width = format.width;
742 fse->max_height = format.height;
743
744 return 0;
745}
746
747/*
748 * ccp2_get_format - Handle get format by pads subdev method
749 * @sd : pointer to v4l2 subdev structure
750 * @fh : V4L2 subdev file handle
751 * @fmt : pointer to v4l2 subdev format structure
752 * return -EINVAL or zero on success
753 */
754static int ccp2_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
755 struct v4l2_subdev_format *fmt)
756{
757 struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd);
758 struct v4l2_mbus_framefmt *format;
759
760 format = __ccp2_get_format(ccp2, fh, fmt->pad, fmt->which);
761 if (format == NULL)
762 return -EINVAL;
763
764 fmt->format = *format;
765 return 0;
766}
767
768/*
769 * ccp2_set_format - Handle set format by pads subdev method
770 * @sd : pointer to v4l2 subdev structure
771 * @fh : V4L2 subdev file handle
772 * @fmt : pointer to v4l2 subdev format structure
773 * returns zero
774 */
775static int ccp2_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
776 struct v4l2_subdev_format *fmt)
777{
778 struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd);
779 struct v4l2_mbus_framefmt *format;
780
781 format = __ccp2_get_format(ccp2, fh, fmt->pad, fmt->which);
782 if (format == NULL)
783 return -EINVAL;
784
785 ccp2_try_format(ccp2, fh, fmt->pad, &fmt->format, fmt->which);
786 *format = fmt->format;
787
788 /* Propagate the format from sink to source */
789 if (fmt->pad == CCP2_PAD_SINK) {
790 format = __ccp2_get_format(ccp2, fh, CCP2_PAD_SOURCE,
791 fmt->which);
792 *format = fmt->format;
793 ccp2_try_format(ccp2, fh, CCP2_PAD_SOURCE, format, fmt->which);
794 }
795
796 return 0;
797}
798
799/*
800 * ccp2_init_formats - Initialize formats on all pads
801 * @sd: ISP CCP2 V4L2 subdevice
802 * @fh: V4L2 subdev file handle
803 *
804 * Initialize all pad formats with default values. If fh is not NULL, try
805 * formats are initialized on the file handle. Otherwise active formats are
806 * initialized on the device.
807 */
808static int ccp2_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
809{
810 struct v4l2_subdev_format format;
811
812 memset(&format, 0, sizeof(format));
813 format.pad = CCP2_PAD_SINK;
814 format.which = fh ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE;
815 format.format.code = V4L2_MBUS_FMT_SGRBG10_1X10;
816 format.format.width = 4096;
817 format.format.height = 4096;
818 ccp2_set_format(sd, fh, &format);
819
820 return 0;
821}
822
823/*
824 * ccp2_s_stream - Enable/Disable streaming on ccp2 subdev
825 * @sd : pointer to v4l2 subdev structure
826 * @enable: 1 == Enable, 0 == Disable
827 * return zero
828 */
829static int ccp2_s_stream(struct v4l2_subdev *sd, int enable)
830{
831 struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd);
832 struct isp_device *isp = to_isp_device(ccp2);
833 struct device *dev = to_device(ccp2);
834 int ret;
835
836 if (ccp2->state == ISP_PIPELINE_STREAM_STOPPED) {
837 if (enable == ISP_PIPELINE_STREAM_STOPPED)
838 return 0;
839 atomic_set(&ccp2->stopping, 0);
840 }
841
842 switch (enable) {
843 case ISP_PIPELINE_STREAM_CONTINUOUS:
844 if (ccp2->phy) {
845 ret = omap3isp_csiphy_acquire(ccp2->phy);
846 if (ret < 0)
847 return ret;
848 }
849
850 ccp2_if_configure(ccp2);
851 ccp2_print_status(ccp2);
852
853 /* Enable CSI1/CCP2 interface */
854 ccp2_if_enable(ccp2, 1);
855 break;
856
857 case ISP_PIPELINE_STREAM_SINGLESHOT:
858 if (ccp2->state != ISP_PIPELINE_STREAM_SINGLESHOT) {
859 struct v4l2_mbus_framefmt *format;
860
861 format = &ccp2->formats[CCP2_PAD_SINK];
862
863 ccp2->mem_cfg.hsize_count = format->width;
864 ccp2->mem_cfg.vsize_count = format->height;
865 ccp2->mem_cfg.src_ofst = 0;
866
867 ccp2_mem_configure(ccp2, &ccp2->mem_cfg);
868 omap3isp_sbl_enable(isp, OMAP3_ISP_SBL_CSI1_READ);
869 ccp2_print_status(ccp2);
870 }
871 ccp2_mem_enable(ccp2, 1);
872 break;
873
874 case ISP_PIPELINE_STREAM_STOPPED:
875 if (omap3isp_module_sync_idle(&sd->entity, &ccp2->wait,
876 &ccp2->stopping))
877 dev_dbg(dev, "%s: module stop timeout.\n", sd->name);
878 if (ccp2->input == CCP2_INPUT_MEMORY) {
879 ccp2_mem_enable(ccp2, 0);
880 omap3isp_sbl_disable(isp, OMAP3_ISP_SBL_CSI1_READ);
881 } else if (ccp2->input == CCP2_INPUT_SENSOR) {
882 /* Disable CSI1/CCP2 interface */
883 ccp2_if_enable(ccp2, 0);
884 if (ccp2->phy)
885 omap3isp_csiphy_release(ccp2->phy);
886 }
887 break;
888 }
889
890 ccp2->state = enable;
891 return 0;
892}
893
894/* subdev video operations */
895static const struct v4l2_subdev_video_ops ccp2_sd_video_ops = {
896 .s_stream = ccp2_s_stream,
897};
898
899/* subdev pad operations */
900static const struct v4l2_subdev_pad_ops ccp2_sd_pad_ops = {
901 .enum_mbus_code = ccp2_enum_mbus_code,
902 .enum_frame_size = ccp2_enum_frame_size,
903 .get_fmt = ccp2_get_format,
904 .set_fmt = ccp2_set_format,
905};
906
907/* subdev operations */
908static const struct v4l2_subdev_ops ccp2_sd_ops = {
909 .video = &ccp2_sd_video_ops,
910 .pad = &ccp2_sd_pad_ops,
911};
912
913/* subdev internal operations */
914static const struct v4l2_subdev_internal_ops ccp2_sd_internal_ops = {
915 .open = ccp2_init_formats,
916};
917
918/* --------------------------------------------------------------------------
919 * ISP ccp2 video device node
920 */
921
922/*
923 * ccp2_video_queue - Queue video buffer.
924 * @video : Pointer to isp video structure
925 * @buffer: Pointer to isp_buffer structure
926 * return -EIO or zero on success
927 */
928static int ccp2_video_queue(struct isp_video *video, struct isp_buffer *buffer)
929{
930 struct isp_ccp2_device *ccp2 = &video->isp->isp_ccp2;
931
932 ccp2_set_inaddr(ccp2, buffer->isp_addr);
933 return 0;
934}
935
936static const struct isp_video_operations ccp2_video_ops = {
937 .queue = ccp2_video_queue,
938};
939
940/* -----------------------------------------------------------------------------
941 * Media entity operations
942 */
943
944/*
945 * ccp2_link_setup - Setup ccp2 connections.
946 * @entity : Pointer to media entity structure
947 * @local : Pointer to local pad array
948 * @remote : Pointer to remote pad array
949 * @flags : Link flags
950 * return -EINVAL on error or zero on success
951 */
952static int ccp2_link_setup(struct media_entity *entity,
953 const struct media_pad *local,
954 const struct media_pad *remote, u32 flags)
955{
956 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
957 struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd);
958
959 switch (local->index | media_entity_type(remote->entity)) {
960 case CCP2_PAD_SINK | MEDIA_ENT_T_DEVNODE:
961 /* read from memory */
962 if (flags & MEDIA_LNK_FL_ENABLED) {
963 if (ccp2->input == CCP2_INPUT_SENSOR)
964 return -EBUSY;
965 ccp2->input = CCP2_INPUT_MEMORY;
966 } else {
967 if (ccp2->input == CCP2_INPUT_MEMORY)
968 ccp2->input = CCP2_INPUT_NONE;
969 }
970 break;
971
972 case CCP2_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV:
973 /* read from sensor/phy */
974 if (flags & MEDIA_LNK_FL_ENABLED) {
975 if (ccp2->input == CCP2_INPUT_MEMORY)
976 return -EBUSY;
977 ccp2->input = CCP2_INPUT_SENSOR;
978 } else {
979 if (ccp2->input == CCP2_INPUT_SENSOR)
980 ccp2->input = CCP2_INPUT_NONE;
981 } break;
982
983 case CCP2_PAD_SOURCE | MEDIA_ENT_T_V4L2_SUBDEV:
984 /* write to video port/ccdc */
985 if (flags & MEDIA_LNK_FL_ENABLED)
986 ccp2->output = CCP2_OUTPUT_CCDC;
987 else
988 ccp2->output = CCP2_OUTPUT_NONE;
989 break;
990
991 default:
992 return -EINVAL;
993 }
994
995 return 0;
996}
997
998/* media operations */
999static const struct media_entity_operations ccp2_media_ops = {
1000 .link_setup = ccp2_link_setup,
1001 .link_validate = v4l2_subdev_link_validate,
1002};
1003
1004/*
1005 * omap3isp_ccp2_unregister_entities - Unregister media entities: subdev
1006 * @ccp2: Pointer to ISP CCP2 device
1007 */
1008void omap3isp_ccp2_unregister_entities(struct isp_ccp2_device *ccp2)
1009{
1010 v4l2_device_unregister_subdev(&ccp2->subdev);
1011 omap3isp_video_unregister(&ccp2->video_in);
1012}
1013
1014/*
1015 * omap3isp_ccp2_register_entities - Register the subdev media entity
1016 * @ccp2: Pointer to ISP CCP2 device
1017 * @vdev: Pointer to v4l device
1018 * return negative error code or zero on success
1019 */
1020
1021int omap3isp_ccp2_register_entities(struct isp_ccp2_device *ccp2,
1022 struct v4l2_device *vdev)
1023{
1024 int ret;
1025
1026 /* Register the subdev and video nodes. */
1027 ret = v4l2_device_register_subdev(vdev, &ccp2->subdev);
1028 if (ret < 0)
1029 goto error;
1030
1031 ret = omap3isp_video_register(&ccp2->video_in, vdev);
1032 if (ret < 0)
1033 goto error;
1034
1035 return 0;
1036
1037error:
1038 omap3isp_ccp2_unregister_entities(ccp2);
1039 return ret;
1040}
1041
1042/* -----------------------------------------------------------------------------
1043 * ISP ccp2 initialisation and cleanup
1044 */
1045
1046/*
1047 * ccp2_init_entities - Initialize ccp2 subdev and media entity.
1048 * @ccp2: Pointer to ISP CCP2 device
1049 * return negative error code or zero on success
1050 */
1051static int ccp2_init_entities(struct isp_ccp2_device *ccp2)
1052{
1053 struct v4l2_subdev *sd = &ccp2->subdev;
1054 struct media_pad *pads = ccp2->pads;
1055 struct media_entity *me = &sd->entity;
1056 int ret;
1057
1058 ccp2->input = CCP2_INPUT_NONE;
1059 ccp2->output = CCP2_OUTPUT_NONE;
1060
1061 v4l2_subdev_init(sd, &ccp2_sd_ops);
1062 sd->internal_ops = &ccp2_sd_internal_ops;
1063 strlcpy(sd->name, "OMAP3 ISP CCP2", sizeof(sd->name));
1064 sd->grp_id = 1 << 16; /* group ID for isp subdevs */
1065 v4l2_set_subdevdata(sd, ccp2);
1066 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
1067
1068 pads[CCP2_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
1069 pads[CCP2_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
1070
1071 me->ops = &ccp2_media_ops;
1072 ret = media_entity_init(me, CCP2_PADS_NUM, pads, 0);
1073 if (ret < 0)
1074 return ret;
1075
1076 ccp2_init_formats(sd, NULL);
1077
1078 /*
1079 * The CCP2 has weird line alignment requirements, possibly caused by
1080 * DPCM8 decompression. Line length for data read from memory must be a
1081 * multiple of 128 bits (16 bytes) in continuous mode (when no padding
1082 * is present at end of lines). Additionally, if padding is used, the
1083 * padded line length must be a multiple of 32 bytes. To simplify the
1084 * implementation we use a fixed 32 bytes alignment regardless of the
1085 * input format and width. If strict 128 bits alignment support is
1086 * required ispvideo will need to be made aware of this special dual
1087 * alignement requirements.
1088 */
1089 ccp2->video_in.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
1090 ccp2->video_in.bpl_alignment = 32;
1091 ccp2->video_in.bpl_max = 0xffffffe0;
1092 ccp2->video_in.isp = to_isp_device(ccp2);
1093 ccp2->video_in.ops = &ccp2_video_ops;
1094 ccp2->video_in.capture_mem = PAGE_ALIGN(4096 * 4096) * 3;
1095
1096 ret = omap3isp_video_init(&ccp2->video_in, "CCP2");
1097 if (ret < 0)
1098 goto error_video;
1099
1100 /* Connect the video node to the ccp2 subdev. */
1101 ret = media_entity_create_link(&ccp2->video_in.video.entity, 0,
1102 &ccp2->subdev.entity, CCP2_PAD_SINK, 0);
1103 if (ret < 0)
1104 goto error_link;
1105
1106 return 0;
1107
1108error_link:
1109 omap3isp_video_cleanup(&ccp2->video_in);
1110error_video:
1111 media_entity_cleanup(&ccp2->subdev.entity);
1112 return ret;
1113}
1114
1115/*
1116 * omap3isp_ccp2_init - CCP2 initialization.
1117 * @isp : Pointer to ISP device
1118 * return negative error code or zero on success
1119 */
1120int omap3isp_ccp2_init(struct isp_device *isp)
1121{
1122 struct isp_ccp2_device *ccp2 = &isp->isp_ccp2;
1123 int ret;
1124
1125 init_waitqueue_head(&ccp2->wait);
1126
1127 /*
1128 * On the OMAP34xx the CSI1 receiver is operated in the CSIb IO
1129 * complex, which is powered by vdds_csib power rail. Hence the
1130 * request for the regulator.
1131 *
1132 * On the OMAP36xx, the CCP2 uses the CSI PHY1 or PHY2, shared with
1133 * the CSI2c or CSI2a receivers. The PHY then needs to be explicitly
1134 * configured.
1135 *
1136 * TODO: Don't hardcode the usage of PHY1 (shared with CSI2c).
1137 */
1138 if (isp->revision == ISP_REVISION_2_0) {
1139 ccp2->vdds_csib = regulator_get(isp->dev, "vdds_csib");
1140 if (IS_ERR(ccp2->vdds_csib)) {
1141 dev_dbg(isp->dev,
1142 "Could not get regulator vdds_csib\n");
1143 ccp2->vdds_csib = NULL;
1144 }
1145 } else if (isp->revision == ISP_REVISION_15_0) {
1146 ccp2->phy = &isp->isp_csiphy1;
1147 }
1148
1149 ret = ccp2_init_entities(ccp2);
1150 if (ret < 0) {
1151 regulator_put(ccp2->vdds_csib);
1152 return ret;
1153 }
1154
1155 ccp2_reset(ccp2);
1156 return 0;
1157}
1158
1159/*
1160 * omap3isp_ccp2_cleanup - CCP2 un-initialization
1161 * @isp : Pointer to ISP device
1162 */
1163void omap3isp_ccp2_cleanup(struct isp_device *isp)
1164{
1165 struct isp_ccp2_device *ccp2 = &isp->isp_ccp2;
1166
1167 omap3isp_video_cleanup(&ccp2->video_in);
1168 media_entity_cleanup(&ccp2->subdev.entity);
1169
1170 regulator_put(ccp2->vdds_csib);
1171}
diff --git a/drivers/media/video/omap3isp/ispccp2.h b/drivers/media/video/omap3isp/ispccp2.h
deleted file mode 100644
index 76d65f4576ef..000000000000
--- a/drivers/media/video/omap3isp/ispccp2.h
+++ /dev/null
@@ -1,98 +0,0 @@
1/*
2 * ispccp2.h
3 *
4 * TI OMAP3 ISP - CCP2 module
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2010 Texas Instruments, Inc.
8 *
9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 * Sakari Ailus <sakari.ailus@iki.fi>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 */
26
27#ifndef OMAP3_ISP_CCP2_H
28#define OMAP3_ISP_CCP2_H
29
30#include <linux/videodev2.h>
31
32struct isp_device;
33struct isp_csiphy;
34
35/* Sink and source ccp2 pads */
36#define CCP2_PAD_SINK 0
37#define CCP2_PAD_SOURCE 1
38#define CCP2_PADS_NUM 2
39
40/* CCP2 input media entity */
41enum ccp2_input_entity {
42 CCP2_INPUT_NONE,
43 CCP2_INPUT_SENSOR,
44 CCP2_INPUT_MEMORY,
45};
46
47/* CCP2 output media entity */
48enum ccp2_output_entity {
49 CCP2_OUTPUT_NONE,
50 CCP2_OUTPUT_CCDC,
51 CCP2_OUTPUT_MEMORY,
52};
53
54
55/* Logical channel configuration */
56struct isp_interface_lcx_config {
57 int crc;
58 u32 data_start;
59 u32 data_size;
60 u32 format;
61};
62
63/* Memory channel configuration */
64struct isp_interface_mem_config {
65 u32 dst_port;
66 u32 vsize_count;
67 u32 hsize_count;
68 u32 src_ofst;
69 u32 dst_ofst;
70};
71
72/* CCP2 device */
73struct isp_ccp2_device {
74 struct v4l2_subdev subdev;
75 struct v4l2_mbus_framefmt formats[CCP2_PADS_NUM];
76 struct media_pad pads[CCP2_PADS_NUM];
77
78 enum ccp2_input_entity input;
79 enum ccp2_output_entity output;
80 struct isp_interface_lcx_config if_cfg;
81 struct isp_interface_mem_config mem_cfg;
82 struct isp_video video_in;
83 struct isp_csiphy *phy;
84 struct regulator *vdds_csib;
85 enum isp_pipeline_stream_state state;
86 wait_queue_head_t wait;
87 atomic_t stopping;
88};
89
90/* Function declarations */
91int omap3isp_ccp2_init(struct isp_device *isp);
92void omap3isp_ccp2_cleanup(struct isp_device *isp);
93int omap3isp_ccp2_register_entities(struct isp_ccp2_device *ccp2,
94 struct v4l2_device *vdev);
95void omap3isp_ccp2_unregister_entities(struct isp_ccp2_device *ccp2);
96void omap3isp_ccp2_isr(struct isp_ccp2_device *ccp2);
97
98#endif /* OMAP3_ISP_CCP2_H */
diff --git a/drivers/media/video/omap3isp/ispcsi2.c b/drivers/media/video/omap3isp/ispcsi2.c
deleted file mode 100644
index 6a3ff792af7d..000000000000
--- a/drivers/media/video/omap3isp/ispcsi2.c
+++ /dev/null
@@ -1,1328 +0,0 @@
1/*
2 * ispcsi2.c
3 *
4 * TI OMAP3 ISP - CSI2 module
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc.
8 *
9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 * Sakari Ailus <sakari.ailus@iki.fi>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 */
26#include <linux/delay.h>
27#include <media/v4l2-common.h>
28#include <linux/v4l2-mediabus.h>
29#include <linux/mm.h>
30
31#include "isp.h"
32#include "ispreg.h"
33#include "ispcsi2.h"
34
35/*
36 * csi2_if_enable - Enable CSI2 Receiver interface.
37 * @enable: enable flag
38 *
39 */
40static void csi2_if_enable(struct isp_device *isp,
41 struct isp_csi2_device *csi2, u8 enable)
42{
43 struct isp_csi2_ctrl_cfg *currctrl = &csi2->ctrl;
44
45 isp_reg_clr_set(isp, csi2->regs1, ISPCSI2_CTRL, ISPCSI2_CTRL_IF_EN,
46 enable ? ISPCSI2_CTRL_IF_EN : 0);
47
48 currctrl->if_enable = enable;
49}
50
51/*
52 * csi2_recv_config - CSI2 receiver module configuration.
53 * @currctrl: isp_csi2_ctrl_cfg structure
54 *
55 */
56static void csi2_recv_config(struct isp_device *isp,
57 struct isp_csi2_device *csi2,
58 struct isp_csi2_ctrl_cfg *currctrl)
59{
60 u32 reg;
61
62 reg = isp_reg_readl(isp, csi2->regs1, ISPCSI2_CTRL);
63
64 if (currctrl->frame_mode)
65 reg |= ISPCSI2_CTRL_FRAME;
66 else
67 reg &= ~ISPCSI2_CTRL_FRAME;
68
69 if (currctrl->vp_clk_enable)
70 reg |= ISPCSI2_CTRL_VP_CLK_EN;
71 else
72 reg &= ~ISPCSI2_CTRL_VP_CLK_EN;
73
74 if (currctrl->vp_only_enable)
75 reg |= ISPCSI2_CTRL_VP_ONLY_EN;
76 else
77 reg &= ~ISPCSI2_CTRL_VP_ONLY_EN;
78
79 reg &= ~ISPCSI2_CTRL_VP_OUT_CTRL_MASK;
80 reg |= currctrl->vp_out_ctrl << ISPCSI2_CTRL_VP_OUT_CTRL_SHIFT;
81
82 if (currctrl->ecc_enable)
83 reg |= ISPCSI2_CTRL_ECC_EN;
84 else
85 reg &= ~ISPCSI2_CTRL_ECC_EN;
86
87 isp_reg_writel(isp, reg, csi2->regs1, ISPCSI2_CTRL);
88}
89
90static const unsigned int csi2_input_fmts[] = {
91 V4L2_MBUS_FMT_SGRBG10_1X10,
92 V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8,
93 V4L2_MBUS_FMT_SRGGB10_1X10,
94 V4L2_MBUS_FMT_SRGGB10_DPCM8_1X8,
95 V4L2_MBUS_FMT_SBGGR10_1X10,
96 V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8,
97 V4L2_MBUS_FMT_SGBRG10_1X10,
98 V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8,
99 V4L2_MBUS_FMT_YUYV8_2X8,
100};
101
102/* To set the format on the CSI2 requires a mapping function that takes
103 * the following inputs:
104 * - 3 different formats (at this time)
105 * - 2 destinations (mem, vp+mem) (vp only handled separately)
106 * - 2 decompression options (on, off)
107 * - 2 isp revisions (certain format must be handled differently on OMAP3630)
108 * Output should be CSI2 frame format code
109 * Array indices as follows: [format][dest][decompr][is_3630]
110 * Not all combinations are valid. 0 means invalid.
111 */
112static const u16 __csi2_fmt_map[3][2][2][2] = {
113 /* RAW10 formats */
114 {
115 /* Output to memory */
116 {
117 /* No DPCM decompression */
118 { CSI2_PIX_FMT_RAW10_EXP16, CSI2_PIX_FMT_RAW10_EXP16 },
119 /* DPCM decompression */
120 { 0, 0 },
121 },
122 /* Output to both */
123 {
124 /* No DPCM decompression */
125 { CSI2_PIX_FMT_RAW10_EXP16_VP,
126 CSI2_PIX_FMT_RAW10_EXP16_VP },
127 /* DPCM decompression */
128 { 0, 0 },
129 },
130 },
131 /* RAW10 DPCM8 formats */
132 {
133 /* Output to memory */
134 {
135 /* No DPCM decompression */
136 { CSI2_PIX_FMT_RAW8, CSI2_USERDEF_8BIT_DATA1 },
137 /* DPCM decompression */
138 { CSI2_PIX_FMT_RAW8_DPCM10_EXP16,
139 CSI2_USERDEF_8BIT_DATA1_DPCM10 },
140 },
141 /* Output to both */
142 {
143 /* No DPCM decompression */
144 { CSI2_PIX_FMT_RAW8_VP,
145 CSI2_PIX_FMT_RAW8_VP },
146 /* DPCM decompression */
147 { CSI2_PIX_FMT_RAW8_DPCM10_VP,
148 CSI2_USERDEF_8BIT_DATA1_DPCM10_VP },
149 },
150 },
151 /* YUYV8 2X8 formats */
152 {
153 /* Output to memory */
154 {
155 /* No DPCM decompression */
156 { CSI2_PIX_FMT_YUV422_8BIT,
157 CSI2_PIX_FMT_YUV422_8BIT },
158 /* DPCM decompression */
159 { 0, 0 },
160 },
161 /* Output to both */
162 {
163 /* No DPCM decompression */
164 { CSI2_PIX_FMT_YUV422_8BIT_VP,
165 CSI2_PIX_FMT_YUV422_8BIT_VP },
166 /* DPCM decompression */
167 { 0, 0 },
168 },
169 },
170};
171
172/*
173 * csi2_ctx_map_format - Map CSI2 sink media bus format to CSI2 format ID
174 * @csi2: ISP CSI2 device
175 *
176 * Returns CSI2 physical format id
177 */
178static u16 csi2_ctx_map_format(struct isp_csi2_device *csi2)
179{
180 const struct v4l2_mbus_framefmt *fmt = &csi2->formats[CSI2_PAD_SINK];
181 int fmtidx, destidx, is_3630;
182
183 switch (fmt->code) {
184 case V4L2_MBUS_FMT_SGRBG10_1X10:
185 case V4L2_MBUS_FMT_SRGGB10_1X10:
186 case V4L2_MBUS_FMT_SBGGR10_1X10:
187 case V4L2_MBUS_FMT_SGBRG10_1X10:
188 fmtidx = 0;
189 break;
190 case V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8:
191 case V4L2_MBUS_FMT_SRGGB10_DPCM8_1X8:
192 case V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8:
193 case V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8:
194 fmtidx = 1;
195 break;
196 case V4L2_MBUS_FMT_YUYV8_2X8:
197 fmtidx = 2;
198 break;
199 default:
200 WARN(1, KERN_ERR "CSI2: pixel format %08x unsupported!\n",
201 fmt->code);
202 return 0;
203 }
204
205 if (!(csi2->output & CSI2_OUTPUT_CCDC) &&
206 !(csi2->output & CSI2_OUTPUT_MEMORY)) {
207 /* Neither output enabled is a valid combination */
208 return CSI2_PIX_FMT_OTHERS;
209 }
210
211 /* If we need to skip frames at the beginning of the stream disable the
212 * video port to avoid sending the skipped frames to the CCDC.
213 */
214 destidx = csi2->frame_skip ? 0 : !!(csi2->output & CSI2_OUTPUT_CCDC);
215 is_3630 = csi2->isp->revision == ISP_REVISION_15_0;
216
217 return __csi2_fmt_map[fmtidx][destidx][csi2->dpcm_decompress][is_3630];
218}
219
220/*
221 * csi2_set_outaddr - Set memory address to save output image
222 * @csi2: Pointer to ISP CSI2a device.
223 * @addr: ISP MMU Mapped 32-bit memory address aligned on 32 byte boundary.
224 *
225 * Sets the memory address where the output will be saved.
226 *
227 * Returns 0 if successful, or -EINVAL if the address is not in the 32 byte
228 * boundary.
229 */
230static void csi2_set_outaddr(struct isp_csi2_device *csi2, u32 addr)
231{
232 struct isp_device *isp = csi2->isp;
233 struct isp_csi2_ctx_cfg *ctx = &csi2->contexts[0];
234
235 ctx->ping_addr = addr;
236 ctx->pong_addr = addr;
237 isp_reg_writel(isp, ctx->ping_addr,
238 csi2->regs1, ISPCSI2_CTX_DAT_PING_ADDR(ctx->ctxnum));
239 isp_reg_writel(isp, ctx->pong_addr,
240 csi2->regs1, ISPCSI2_CTX_DAT_PONG_ADDR(ctx->ctxnum));
241}
242
243/*
244 * is_usr_def_mapping - Checks whether USER_DEF_MAPPING should
245 * be enabled by CSI2.
246 * @format_id: mapped format id
247 *
248 */
249static inline int is_usr_def_mapping(u32 format_id)
250{
251 return (format_id & 0x40) ? 1 : 0;
252}
253
254/*
255 * csi2_ctx_enable - Enable specified CSI2 context
256 * @ctxnum: Context number, valid between 0 and 7 values.
257 * @enable: enable
258 *
259 */
260static void csi2_ctx_enable(struct isp_device *isp,
261 struct isp_csi2_device *csi2, u8 ctxnum, u8 enable)
262{
263 struct isp_csi2_ctx_cfg *ctx = &csi2->contexts[ctxnum];
264 unsigned int skip = 0;
265 u32 reg;
266
267 reg = isp_reg_readl(isp, csi2->regs1, ISPCSI2_CTX_CTRL1(ctxnum));
268
269 if (enable) {
270 if (csi2->frame_skip)
271 skip = csi2->frame_skip;
272 else if (csi2->output & CSI2_OUTPUT_MEMORY)
273 skip = 1;
274
275 reg &= ~ISPCSI2_CTX_CTRL1_COUNT_MASK;
276 reg |= ISPCSI2_CTX_CTRL1_COUNT_UNLOCK
277 | (skip << ISPCSI2_CTX_CTRL1_COUNT_SHIFT)
278 | ISPCSI2_CTX_CTRL1_CTX_EN;
279 } else {
280 reg &= ~ISPCSI2_CTX_CTRL1_CTX_EN;
281 }
282
283 isp_reg_writel(isp, reg, csi2->regs1, ISPCSI2_CTX_CTRL1(ctxnum));
284 ctx->enabled = enable;
285}
286
287/*
288 * csi2_ctx_config - CSI2 context configuration.
289 * @ctx: context configuration
290 *
291 */
292static void csi2_ctx_config(struct isp_device *isp,
293 struct isp_csi2_device *csi2,
294 struct isp_csi2_ctx_cfg *ctx)
295{
296 u32 reg;
297
298 /* Set up CSI2_CTx_CTRL1 */
299 reg = isp_reg_readl(isp, csi2->regs1, ISPCSI2_CTX_CTRL1(ctx->ctxnum));
300
301 if (ctx->eof_enabled)
302 reg |= ISPCSI2_CTX_CTRL1_EOF_EN;
303 else
304 reg &= ~ISPCSI2_CTX_CTRL1_EOF_EN;
305
306 if (ctx->eol_enabled)
307 reg |= ISPCSI2_CTX_CTRL1_EOL_EN;
308 else
309 reg &= ~ISPCSI2_CTX_CTRL1_EOL_EN;
310
311 if (ctx->checksum_enabled)
312 reg |= ISPCSI2_CTX_CTRL1_CS_EN;
313 else
314 reg &= ~ISPCSI2_CTX_CTRL1_CS_EN;
315
316 isp_reg_writel(isp, reg, csi2->regs1, ISPCSI2_CTX_CTRL1(ctx->ctxnum));
317
318 /* Set up CSI2_CTx_CTRL2 */
319 reg = isp_reg_readl(isp, csi2->regs1, ISPCSI2_CTX_CTRL2(ctx->ctxnum));
320
321 reg &= ~(ISPCSI2_CTX_CTRL2_VIRTUAL_ID_MASK);
322 reg |= ctx->virtual_id << ISPCSI2_CTX_CTRL2_VIRTUAL_ID_SHIFT;
323
324 reg &= ~(ISPCSI2_CTX_CTRL2_FORMAT_MASK);
325 reg |= ctx->format_id << ISPCSI2_CTX_CTRL2_FORMAT_SHIFT;
326
327 if (ctx->dpcm_decompress) {
328 if (ctx->dpcm_predictor)
329 reg |= ISPCSI2_CTX_CTRL2_DPCM_PRED;
330 else
331 reg &= ~ISPCSI2_CTX_CTRL2_DPCM_PRED;
332 }
333
334 if (is_usr_def_mapping(ctx->format_id)) {
335 reg &= ~ISPCSI2_CTX_CTRL2_USER_DEF_MAP_MASK;
336 reg |= 2 << ISPCSI2_CTX_CTRL2_USER_DEF_MAP_SHIFT;
337 }
338
339 isp_reg_writel(isp, reg, csi2->regs1, ISPCSI2_CTX_CTRL2(ctx->ctxnum));
340
341 /* Set up CSI2_CTx_CTRL3 */
342 reg = isp_reg_readl(isp, csi2->regs1, ISPCSI2_CTX_CTRL3(ctx->ctxnum));
343 reg &= ~(ISPCSI2_CTX_CTRL3_ALPHA_MASK);
344 reg |= (ctx->alpha << ISPCSI2_CTX_CTRL3_ALPHA_SHIFT);
345
346 isp_reg_writel(isp, reg, csi2->regs1, ISPCSI2_CTX_CTRL3(ctx->ctxnum));
347
348 /* Set up CSI2_CTx_DAT_OFST */
349 reg = isp_reg_readl(isp, csi2->regs1,
350 ISPCSI2_CTX_DAT_OFST(ctx->ctxnum));
351 reg &= ~ISPCSI2_CTX_DAT_OFST_OFST_MASK;
352 reg |= ctx->data_offset << ISPCSI2_CTX_DAT_OFST_OFST_SHIFT;
353 isp_reg_writel(isp, reg, csi2->regs1,
354 ISPCSI2_CTX_DAT_OFST(ctx->ctxnum));
355
356 isp_reg_writel(isp, ctx->ping_addr,
357 csi2->regs1, ISPCSI2_CTX_DAT_PING_ADDR(ctx->ctxnum));
358
359 isp_reg_writel(isp, ctx->pong_addr,
360 csi2->regs1, ISPCSI2_CTX_DAT_PONG_ADDR(ctx->ctxnum));
361}
362
363/*
364 * csi2_timing_config - CSI2 timing configuration.
365 * @timing: csi2_timing_cfg structure
366 */
367static void csi2_timing_config(struct isp_device *isp,
368 struct isp_csi2_device *csi2,
369 struct isp_csi2_timing_cfg *timing)
370{
371 u32 reg;
372
373 reg = isp_reg_readl(isp, csi2->regs1, ISPCSI2_TIMING);
374
375 if (timing->force_rx_mode)
376 reg |= ISPCSI2_TIMING_FORCE_RX_MODE_IO(timing->ionum);
377 else
378 reg &= ~ISPCSI2_TIMING_FORCE_RX_MODE_IO(timing->ionum);
379
380 if (timing->stop_state_16x)
381 reg |= ISPCSI2_TIMING_STOP_STATE_X16_IO(timing->ionum);
382 else
383 reg &= ~ISPCSI2_TIMING_STOP_STATE_X16_IO(timing->ionum);
384
385 if (timing->stop_state_4x)
386 reg |= ISPCSI2_TIMING_STOP_STATE_X4_IO(timing->ionum);
387 else
388 reg &= ~ISPCSI2_TIMING_STOP_STATE_X4_IO(timing->ionum);
389
390 reg &= ~ISPCSI2_TIMING_STOP_STATE_COUNTER_IO_MASK(timing->ionum);
391 reg |= timing->stop_state_counter <<
392 ISPCSI2_TIMING_STOP_STATE_COUNTER_IO_SHIFT(timing->ionum);
393
394 isp_reg_writel(isp, reg, csi2->regs1, ISPCSI2_TIMING);
395}
396
397/*
398 * csi2_irq_ctx_set - Enables CSI2 Context IRQs.
399 * @enable: Enable/disable CSI2 Context interrupts
400 */
401static void csi2_irq_ctx_set(struct isp_device *isp,
402 struct isp_csi2_device *csi2, int enable)
403{
404 int i;
405
406 for (i = 0; i < 8; i++) {
407 isp_reg_writel(isp, ISPCSI2_CTX_IRQSTATUS_FE_IRQ, csi2->regs1,
408 ISPCSI2_CTX_IRQSTATUS(i));
409 if (enable)
410 isp_reg_set(isp, csi2->regs1, ISPCSI2_CTX_IRQENABLE(i),
411 ISPCSI2_CTX_IRQSTATUS_FE_IRQ);
412 else
413 isp_reg_clr(isp, csi2->regs1, ISPCSI2_CTX_IRQENABLE(i),
414 ISPCSI2_CTX_IRQSTATUS_FE_IRQ);
415 }
416}
417
418/*
419 * csi2_irq_complexio1_set - Enables CSI2 ComplexIO IRQs.
420 * @enable: Enable/disable CSI2 ComplexIO #1 interrupts
421 */
422static void csi2_irq_complexio1_set(struct isp_device *isp,
423 struct isp_csi2_device *csi2, int enable)
424{
425 u32 reg;
426 reg = ISPCSI2_PHY_IRQENABLE_STATEALLULPMEXIT |
427 ISPCSI2_PHY_IRQENABLE_STATEALLULPMENTER |
428 ISPCSI2_PHY_IRQENABLE_STATEULPM5 |
429 ISPCSI2_PHY_IRQENABLE_ERRCONTROL5 |
430 ISPCSI2_PHY_IRQENABLE_ERRESC5 |
431 ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS5 |
432 ISPCSI2_PHY_IRQENABLE_ERRSOTHS5 |
433 ISPCSI2_PHY_IRQENABLE_STATEULPM4 |
434 ISPCSI2_PHY_IRQENABLE_ERRCONTROL4 |
435 ISPCSI2_PHY_IRQENABLE_ERRESC4 |
436 ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS4 |
437 ISPCSI2_PHY_IRQENABLE_ERRSOTHS4 |
438 ISPCSI2_PHY_IRQENABLE_STATEULPM3 |
439 ISPCSI2_PHY_IRQENABLE_ERRCONTROL3 |
440 ISPCSI2_PHY_IRQENABLE_ERRESC3 |
441 ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS3 |
442 ISPCSI2_PHY_IRQENABLE_ERRSOTHS3 |
443 ISPCSI2_PHY_IRQENABLE_STATEULPM2 |
444 ISPCSI2_PHY_IRQENABLE_ERRCONTROL2 |
445 ISPCSI2_PHY_IRQENABLE_ERRESC2 |
446 ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS2 |
447 ISPCSI2_PHY_IRQENABLE_ERRSOTHS2 |
448 ISPCSI2_PHY_IRQENABLE_STATEULPM1 |
449 ISPCSI2_PHY_IRQENABLE_ERRCONTROL1 |
450 ISPCSI2_PHY_IRQENABLE_ERRESC1 |
451 ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS1 |
452 ISPCSI2_PHY_IRQENABLE_ERRSOTHS1;
453 isp_reg_writel(isp, reg, csi2->regs1, ISPCSI2_PHY_IRQSTATUS);
454 if (enable)
455 reg |= isp_reg_readl(isp, csi2->regs1, ISPCSI2_PHY_IRQENABLE);
456 else
457 reg = 0;
458 isp_reg_writel(isp, reg, csi2->regs1, ISPCSI2_PHY_IRQENABLE);
459}
460
461/*
462 * csi2_irq_status_set - Enables CSI2 Status IRQs.
463 * @enable: Enable/disable CSI2 Status interrupts
464 */
465static void csi2_irq_status_set(struct isp_device *isp,
466 struct isp_csi2_device *csi2, int enable)
467{
468 u32 reg;
469 reg = ISPCSI2_IRQSTATUS_OCP_ERR_IRQ |
470 ISPCSI2_IRQSTATUS_SHORT_PACKET_IRQ |
471 ISPCSI2_IRQSTATUS_ECC_CORRECTION_IRQ |
472 ISPCSI2_IRQSTATUS_ECC_NO_CORRECTION_IRQ |
473 ISPCSI2_IRQSTATUS_COMPLEXIO2_ERR_IRQ |
474 ISPCSI2_IRQSTATUS_COMPLEXIO1_ERR_IRQ |
475 ISPCSI2_IRQSTATUS_FIFO_OVF_IRQ |
476 ISPCSI2_IRQSTATUS_CONTEXT(0);
477 isp_reg_writel(isp, reg, csi2->regs1, ISPCSI2_IRQSTATUS);
478 if (enable)
479 reg |= isp_reg_readl(isp, csi2->regs1, ISPCSI2_IRQENABLE);
480 else
481 reg = 0;
482
483 isp_reg_writel(isp, reg, csi2->regs1, ISPCSI2_IRQENABLE);
484}
485
486/*
487 * omap3isp_csi2_reset - Resets the CSI2 module.
488 *
489 * Must be called with the phy lock held.
490 *
491 * Returns 0 if successful, or -EBUSY if power command didn't respond.
492 */
493int omap3isp_csi2_reset(struct isp_csi2_device *csi2)
494{
495 struct isp_device *isp = csi2->isp;
496 u8 soft_reset_retries = 0;
497 u32 reg;
498 int i;
499
500 if (!csi2->available)
501 return -ENODEV;
502
503 if (csi2->phy->phy_in_use)
504 return -EBUSY;
505
506 isp_reg_set(isp, csi2->regs1, ISPCSI2_SYSCONFIG,
507 ISPCSI2_SYSCONFIG_SOFT_RESET);
508
509 do {
510 reg = isp_reg_readl(isp, csi2->regs1, ISPCSI2_SYSSTATUS) &
511 ISPCSI2_SYSSTATUS_RESET_DONE;
512 if (reg == ISPCSI2_SYSSTATUS_RESET_DONE)
513 break;
514 soft_reset_retries++;
515 if (soft_reset_retries < 5)
516 udelay(100);
517 } while (soft_reset_retries < 5);
518
519 if (soft_reset_retries == 5) {
520 printk(KERN_ERR "CSI2: Soft reset try count exceeded!\n");
521 return -EBUSY;
522 }
523
524 if (isp->revision == ISP_REVISION_15_0)
525 isp_reg_set(isp, csi2->regs1, ISPCSI2_PHY_CFG,
526 ISPCSI2_PHY_CFG_RESET_CTRL);
527
528 i = 100;
529 do {
530 reg = isp_reg_readl(isp, csi2->phy->phy_regs, ISPCSIPHY_REG1)
531 & ISPCSIPHY_REG1_RESET_DONE_CTRLCLK;
532 if (reg == ISPCSIPHY_REG1_RESET_DONE_CTRLCLK)
533 break;
534 udelay(100);
535 } while (--i > 0);
536
537 if (i == 0) {
538 printk(KERN_ERR
539 "CSI2: Reset for CSI2_96M_FCLK domain Failed!\n");
540 return -EBUSY;
541 }
542
543 if (isp->autoidle)
544 isp_reg_clr_set(isp, csi2->regs1, ISPCSI2_SYSCONFIG,
545 ISPCSI2_SYSCONFIG_MSTANDBY_MODE_MASK |
546 ISPCSI2_SYSCONFIG_AUTO_IDLE,
547 ISPCSI2_SYSCONFIG_MSTANDBY_MODE_SMART |
548 ((isp->revision == ISP_REVISION_15_0) ?
549 ISPCSI2_SYSCONFIG_AUTO_IDLE : 0));
550 else
551 isp_reg_clr_set(isp, csi2->regs1, ISPCSI2_SYSCONFIG,
552 ISPCSI2_SYSCONFIG_MSTANDBY_MODE_MASK |
553 ISPCSI2_SYSCONFIG_AUTO_IDLE,
554 ISPCSI2_SYSCONFIG_MSTANDBY_MODE_NO);
555
556 return 0;
557}
558
559static int csi2_configure(struct isp_csi2_device *csi2)
560{
561 const struct isp_v4l2_subdevs_group *pdata;
562 struct isp_device *isp = csi2->isp;
563 struct isp_csi2_timing_cfg *timing = &csi2->timing[0];
564 struct v4l2_subdev *sensor;
565 struct media_pad *pad;
566
567 /*
568 * CSI2 fields that can be updated while the context has
569 * been enabled or the interface has been enabled are not
570 * updated dynamically currently. So we do not allow to
571 * reconfigure if either has been enabled
572 */
573 if (csi2->contexts[0].enabled || csi2->ctrl.if_enable)
574 return -EBUSY;
575
576 pad = media_entity_remote_source(&csi2->pads[CSI2_PAD_SINK]);
577 sensor = media_entity_to_v4l2_subdev(pad->entity);
578 pdata = sensor->host_priv;
579
580 csi2->frame_skip = 0;
581 v4l2_subdev_call(sensor, sensor, g_skip_frames, &csi2->frame_skip);
582
583 csi2->ctrl.vp_out_ctrl = pdata->bus.csi2.vpclk_div;
584 csi2->ctrl.frame_mode = ISP_CSI2_FRAME_IMMEDIATE;
585 csi2->ctrl.ecc_enable = pdata->bus.csi2.crc;
586
587 timing->ionum = 1;
588 timing->force_rx_mode = 1;
589 timing->stop_state_16x = 1;
590 timing->stop_state_4x = 1;
591 timing->stop_state_counter = 0x1FF;
592
593 /*
594 * The CSI2 receiver can't do any format conversion except DPCM
595 * decompression, so every set_format call configures both pads
596 * and enables DPCM decompression as a special case:
597 */
598 if (csi2->formats[CSI2_PAD_SINK].code !=
599 csi2->formats[CSI2_PAD_SOURCE].code)
600 csi2->dpcm_decompress = true;
601 else
602 csi2->dpcm_decompress = false;
603
604 csi2->contexts[0].format_id = csi2_ctx_map_format(csi2);
605
606 if (csi2->video_out.bpl_padding == 0)
607 csi2->contexts[0].data_offset = 0;
608 else
609 csi2->contexts[0].data_offset = csi2->video_out.bpl_value;
610
611 /*
612 * Enable end of frame and end of line signals generation for
613 * context 0. These signals are generated from CSI2 receiver to
614 * qualify the last pixel of a frame and the last pixel of a line.
615 * Without enabling the signals CSI2 receiver writes data to memory
616 * beyond buffer size and/or data line offset is not handled correctly.
617 */
618 csi2->contexts[0].eof_enabled = 1;
619 csi2->contexts[0].eol_enabled = 1;
620
621 csi2_irq_complexio1_set(isp, csi2, 1);
622 csi2_irq_ctx_set(isp, csi2, 1);
623 csi2_irq_status_set(isp, csi2, 1);
624
625 /* Set configuration (timings, format and links) */
626 csi2_timing_config(isp, csi2, timing);
627 csi2_recv_config(isp, csi2, &csi2->ctrl);
628 csi2_ctx_config(isp, csi2, &csi2->contexts[0]);
629
630 return 0;
631}
632
633/*
634 * csi2_print_status - Prints CSI2 debug information.
635 */
636#define CSI2_PRINT_REGISTER(isp, regs, name)\
637 dev_dbg(isp->dev, "###CSI2 " #name "=0x%08x\n", \
638 isp_reg_readl(isp, regs, ISPCSI2_##name))
639
640static void csi2_print_status(struct isp_csi2_device *csi2)
641{
642 struct isp_device *isp = csi2->isp;
643
644 if (!csi2->available)
645 return;
646
647 dev_dbg(isp->dev, "-------------CSI2 Register dump-------------\n");
648
649 CSI2_PRINT_REGISTER(isp, csi2->regs1, SYSCONFIG);
650 CSI2_PRINT_REGISTER(isp, csi2->regs1, SYSSTATUS);
651 CSI2_PRINT_REGISTER(isp, csi2->regs1, IRQENABLE);
652 CSI2_PRINT_REGISTER(isp, csi2->regs1, IRQSTATUS);
653 CSI2_PRINT_REGISTER(isp, csi2->regs1, CTRL);
654 CSI2_PRINT_REGISTER(isp, csi2->regs1, DBG_H);
655 CSI2_PRINT_REGISTER(isp, csi2->regs1, GNQ);
656 CSI2_PRINT_REGISTER(isp, csi2->regs1, PHY_CFG);
657 CSI2_PRINT_REGISTER(isp, csi2->regs1, PHY_IRQSTATUS);
658 CSI2_PRINT_REGISTER(isp, csi2->regs1, SHORT_PACKET);
659 CSI2_PRINT_REGISTER(isp, csi2->regs1, PHY_IRQENABLE);
660 CSI2_PRINT_REGISTER(isp, csi2->regs1, DBG_P);
661 CSI2_PRINT_REGISTER(isp, csi2->regs1, TIMING);
662 CSI2_PRINT_REGISTER(isp, csi2->regs1, CTX_CTRL1(0));
663 CSI2_PRINT_REGISTER(isp, csi2->regs1, CTX_CTRL2(0));
664 CSI2_PRINT_REGISTER(isp, csi2->regs1, CTX_DAT_OFST(0));
665 CSI2_PRINT_REGISTER(isp, csi2->regs1, CTX_DAT_PING_ADDR(0));
666 CSI2_PRINT_REGISTER(isp, csi2->regs1, CTX_DAT_PONG_ADDR(0));
667 CSI2_PRINT_REGISTER(isp, csi2->regs1, CTX_IRQENABLE(0));
668 CSI2_PRINT_REGISTER(isp, csi2->regs1, CTX_IRQSTATUS(0));
669 CSI2_PRINT_REGISTER(isp, csi2->regs1, CTX_CTRL3(0));
670
671 dev_dbg(isp->dev, "--------------------------------------------\n");
672}
673
674/* -----------------------------------------------------------------------------
675 * Interrupt handling
676 */
677
678/*
679 * csi2_isr_buffer - Does buffer handling at end-of-frame
680 * when writing to memory.
681 */
682static void csi2_isr_buffer(struct isp_csi2_device *csi2)
683{
684 struct isp_device *isp = csi2->isp;
685 struct isp_buffer *buffer;
686
687 csi2_ctx_enable(isp, csi2, 0, 0);
688
689 buffer = omap3isp_video_buffer_next(&csi2->video_out);
690
691 /*
692 * Let video queue operation restart engine if there is an underrun
693 * condition.
694 */
695 if (buffer == NULL)
696 return;
697
698 csi2_set_outaddr(csi2, buffer->isp_addr);
699 csi2_ctx_enable(isp, csi2, 0, 1);
700}
701
702static void csi2_isr_ctx(struct isp_csi2_device *csi2,
703 struct isp_csi2_ctx_cfg *ctx)
704{
705 struct isp_device *isp = csi2->isp;
706 unsigned int n = ctx->ctxnum;
707 u32 status;
708
709 status = isp_reg_readl(isp, csi2->regs1, ISPCSI2_CTX_IRQSTATUS(n));
710 isp_reg_writel(isp, status, csi2->regs1, ISPCSI2_CTX_IRQSTATUS(n));
711
712 if (!(status & ISPCSI2_CTX_IRQSTATUS_FE_IRQ))
713 return;
714
715 /* Skip interrupts until we reach the frame skip count. The CSI2 will be
716 * automatically disabled, as the frame skip count has been programmed
717 * in the CSI2_CTx_CTRL1::COUNT field, so reenable it.
718 *
719 * It would have been nice to rely on the FRAME_NUMBER interrupt instead
720 * but it turned out that the interrupt is only generated when the CSI2
721 * writes to memory (the CSI2_CTx_CTRL1::COUNT field is decreased
722 * correctly and reaches 0 when data is forwarded to the video port only
723 * but no interrupt arrives). Maybe a CSI2 hardware bug.
724 */
725 if (csi2->frame_skip) {
726 csi2->frame_skip--;
727 if (csi2->frame_skip == 0) {
728 ctx->format_id = csi2_ctx_map_format(csi2);
729 csi2_ctx_config(isp, csi2, ctx);
730 csi2_ctx_enable(isp, csi2, n, 1);
731 }
732 return;
733 }
734
735 if (csi2->output & CSI2_OUTPUT_MEMORY)
736 csi2_isr_buffer(csi2);
737}
738
739/*
740 * omap3isp_csi2_isr - CSI2 interrupt handling.
741 */
742void omap3isp_csi2_isr(struct isp_csi2_device *csi2)
743{
744 struct isp_pipeline *pipe = to_isp_pipeline(&csi2->subdev.entity);
745 u32 csi2_irqstatus, cpxio1_irqstatus;
746 struct isp_device *isp = csi2->isp;
747
748 if (!csi2->available)
749 return;
750
751 csi2_irqstatus = isp_reg_readl(isp, csi2->regs1, ISPCSI2_IRQSTATUS);
752 isp_reg_writel(isp, csi2_irqstatus, csi2->regs1, ISPCSI2_IRQSTATUS);
753
754 /* Failure Cases */
755 if (csi2_irqstatus & ISPCSI2_IRQSTATUS_COMPLEXIO1_ERR_IRQ) {
756 cpxio1_irqstatus = isp_reg_readl(isp, csi2->regs1,
757 ISPCSI2_PHY_IRQSTATUS);
758 isp_reg_writel(isp, cpxio1_irqstatus,
759 csi2->regs1, ISPCSI2_PHY_IRQSTATUS);
760 dev_dbg(isp->dev, "CSI2: ComplexIO Error IRQ "
761 "%x\n", cpxio1_irqstatus);
762 pipe->error = true;
763 }
764
765 if (csi2_irqstatus & (ISPCSI2_IRQSTATUS_OCP_ERR_IRQ |
766 ISPCSI2_IRQSTATUS_SHORT_PACKET_IRQ |
767 ISPCSI2_IRQSTATUS_ECC_NO_CORRECTION_IRQ |
768 ISPCSI2_IRQSTATUS_COMPLEXIO2_ERR_IRQ |
769 ISPCSI2_IRQSTATUS_FIFO_OVF_IRQ)) {
770 dev_dbg(isp->dev, "CSI2 Err:"
771 " OCP:%d,"
772 " Short_pack:%d,"
773 " ECC:%d,"
774 " CPXIO2:%d,"
775 " FIFO_OVF:%d,"
776 "\n",
777 (csi2_irqstatus &
778 ISPCSI2_IRQSTATUS_OCP_ERR_IRQ) ? 1 : 0,
779 (csi2_irqstatus &
780 ISPCSI2_IRQSTATUS_SHORT_PACKET_IRQ) ? 1 : 0,
781 (csi2_irqstatus &
782 ISPCSI2_IRQSTATUS_ECC_NO_CORRECTION_IRQ) ? 1 : 0,
783 (csi2_irqstatus &
784 ISPCSI2_IRQSTATUS_COMPLEXIO2_ERR_IRQ) ? 1 : 0,
785 (csi2_irqstatus &
786 ISPCSI2_IRQSTATUS_FIFO_OVF_IRQ) ? 1 : 0);
787 pipe->error = true;
788 }
789
790 if (omap3isp_module_sync_is_stopping(&csi2->wait, &csi2->stopping))
791 return;
792
793 /* Successful cases */
794 if (csi2_irqstatus & ISPCSI2_IRQSTATUS_CONTEXT(0))
795 csi2_isr_ctx(csi2, &csi2->contexts[0]);
796
797 if (csi2_irqstatus & ISPCSI2_IRQSTATUS_ECC_CORRECTION_IRQ)
798 dev_dbg(isp->dev, "CSI2: ECC correction done\n");
799}
800
801/* -----------------------------------------------------------------------------
802 * ISP video operations
803 */
804
805/*
806 * csi2_queue - Queues the first buffer when using memory output
807 * @video: The video node
808 * @buffer: buffer to queue
809 */
810static int csi2_queue(struct isp_video *video, struct isp_buffer *buffer)
811{
812 struct isp_device *isp = video->isp;
813 struct isp_csi2_device *csi2 = &isp->isp_csi2a;
814
815 csi2_set_outaddr(csi2, buffer->isp_addr);
816
817 /*
818 * If streaming was enabled before there was a buffer queued
819 * or underrun happened in the ISR, the hardware was not enabled
820 * and DMA queue flag ISP_VIDEO_DMAQUEUE_UNDERRUN is still set.
821 * Enable it now.
822 */
823 if (csi2->video_out.dmaqueue_flags & ISP_VIDEO_DMAQUEUE_UNDERRUN) {
824 /* Enable / disable context 0 and IRQs */
825 csi2_if_enable(isp, csi2, 1);
826 csi2_ctx_enable(isp, csi2, 0, 1);
827 isp_video_dmaqueue_flags_clr(&csi2->video_out);
828 }
829
830 return 0;
831}
832
833static const struct isp_video_operations csi2_ispvideo_ops = {
834 .queue = csi2_queue,
835};
836
837/* -----------------------------------------------------------------------------
838 * V4L2 subdev operations
839 */
840
841static struct v4l2_mbus_framefmt *
842__csi2_get_format(struct isp_csi2_device *csi2, struct v4l2_subdev_fh *fh,
843 unsigned int pad, enum v4l2_subdev_format_whence which)
844{
845 if (which == V4L2_SUBDEV_FORMAT_TRY)
846 return v4l2_subdev_get_try_format(fh, pad);
847 else
848 return &csi2->formats[pad];
849}
850
851static void
852csi2_try_format(struct isp_csi2_device *csi2, struct v4l2_subdev_fh *fh,
853 unsigned int pad, struct v4l2_mbus_framefmt *fmt,
854 enum v4l2_subdev_format_whence which)
855{
856 enum v4l2_mbus_pixelcode pixelcode;
857 struct v4l2_mbus_framefmt *format;
858 const struct isp_format_info *info;
859 unsigned int i;
860
861 switch (pad) {
862 case CSI2_PAD_SINK:
863 /* Clamp the width and height to valid range (1-8191). */
864 for (i = 0; i < ARRAY_SIZE(csi2_input_fmts); i++) {
865 if (fmt->code == csi2_input_fmts[i])
866 break;
867 }
868
869 /* If not found, use SGRBG10 as default */
870 if (i >= ARRAY_SIZE(csi2_input_fmts))
871 fmt->code = V4L2_MBUS_FMT_SGRBG10_1X10;
872
873 fmt->width = clamp_t(u32, fmt->width, 1, 8191);
874 fmt->height = clamp_t(u32, fmt->height, 1, 8191);
875 break;
876
877 case CSI2_PAD_SOURCE:
878 /* Source format same as sink format, except for DPCM
879 * compression.
880 */
881 pixelcode = fmt->code;
882 format = __csi2_get_format(csi2, fh, CSI2_PAD_SINK, which);
883 memcpy(fmt, format, sizeof(*fmt));
884
885 /*
886 * Only Allow DPCM decompression, and check that the
887 * pattern is preserved
888 */
889 info = omap3isp_video_format_info(fmt->code);
890 if (info->uncompressed == pixelcode)
891 fmt->code = pixelcode;
892 break;
893 }
894
895 /* RGB, non-interlaced */
896 fmt->colorspace = V4L2_COLORSPACE_SRGB;
897 fmt->field = V4L2_FIELD_NONE;
898}
899
900/*
901 * csi2_enum_mbus_code - Handle pixel format enumeration
902 * @sd : pointer to v4l2 subdev structure
903 * @fh : V4L2 subdev file handle
904 * @code : pointer to v4l2_subdev_mbus_code_enum structure
905 * return -EINVAL or zero on success
906 */
907static int csi2_enum_mbus_code(struct v4l2_subdev *sd,
908 struct v4l2_subdev_fh *fh,
909 struct v4l2_subdev_mbus_code_enum *code)
910{
911 struct isp_csi2_device *csi2 = v4l2_get_subdevdata(sd);
912 struct v4l2_mbus_framefmt *format;
913 const struct isp_format_info *info;
914
915 if (code->pad == CSI2_PAD_SINK) {
916 if (code->index >= ARRAY_SIZE(csi2_input_fmts))
917 return -EINVAL;
918
919 code->code = csi2_input_fmts[code->index];
920 } else {
921 format = __csi2_get_format(csi2, fh, CSI2_PAD_SINK,
922 V4L2_SUBDEV_FORMAT_TRY);
923 switch (code->index) {
924 case 0:
925 /* Passthrough sink pad code */
926 code->code = format->code;
927 break;
928 case 1:
929 /* Uncompressed code */
930 info = omap3isp_video_format_info(format->code);
931 if (info->uncompressed == format->code)
932 return -EINVAL;
933
934 code->code = info->uncompressed;
935 break;
936 default:
937 return -EINVAL;
938 }
939 }
940
941 return 0;
942}
943
944static int csi2_enum_frame_size(struct v4l2_subdev *sd,
945 struct v4l2_subdev_fh *fh,
946 struct v4l2_subdev_frame_size_enum *fse)
947{
948 struct isp_csi2_device *csi2 = v4l2_get_subdevdata(sd);
949 struct v4l2_mbus_framefmt format;
950
951 if (fse->index != 0)
952 return -EINVAL;
953
954 format.code = fse->code;
955 format.width = 1;
956 format.height = 1;
957 csi2_try_format(csi2, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY);
958 fse->min_width = format.width;
959 fse->min_height = format.height;
960
961 if (format.code != fse->code)
962 return -EINVAL;
963
964 format.code = fse->code;
965 format.width = -1;
966 format.height = -1;
967 csi2_try_format(csi2, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY);
968 fse->max_width = format.width;
969 fse->max_height = format.height;
970
971 return 0;
972}
973
974/*
975 * csi2_get_format - Handle get format by pads subdev method
976 * @sd : pointer to v4l2 subdev structure
977 * @fh : V4L2 subdev file handle
978 * @fmt: pointer to v4l2 subdev format structure
979 * return -EINVAL or zero on success
980 */
981static int csi2_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
982 struct v4l2_subdev_format *fmt)
983{
984 struct isp_csi2_device *csi2 = v4l2_get_subdevdata(sd);
985 struct v4l2_mbus_framefmt *format;
986
987 format = __csi2_get_format(csi2, fh, fmt->pad, fmt->which);
988 if (format == NULL)
989 return -EINVAL;
990
991 fmt->format = *format;
992 return 0;
993}
994
995/*
996 * csi2_set_format - Handle set format by pads subdev method
997 * @sd : pointer to v4l2 subdev structure
998 * @fh : V4L2 subdev file handle
999 * @fmt: pointer to v4l2 subdev format structure
1000 * return -EINVAL or zero on success
1001 */
1002static int csi2_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
1003 struct v4l2_subdev_format *fmt)
1004{
1005 struct isp_csi2_device *csi2 = v4l2_get_subdevdata(sd);
1006 struct v4l2_mbus_framefmt *format;
1007
1008 format = __csi2_get_format(csi2, fh, fmt->pad, fmt->which);
1009 if (format == NULL)
1010 return -EINVAL;
1011
1012 csi2_try_format(csi2, fh, fmt->pad, &fmt->format, fmt->which);
1013 *format = fmt->format;
1014
1015 /* Propagate the format from sink to source */
1016 if (fmt->pad == CSI2_PAD_SINK) {
1017 format = __csi2_get_format(csi2, fh, CSI2_PAD_SOURCE,
1018 fmt->which);
1019 *format = fmt->format;
1020 csi2_try_format(csi2, fh, CSI2_PAD_SOURCE, format, fmt->which);
1021 }
1022
1023 return 0;
1024}
1025
1026/*
1027 * csi2_init_formats - Initialize formats on all pads
1028 * @sd: ISP CSI2 V4L2 subdevice
1029 * @fh: V4L2 subdev file handle
1030 *
1031 * Initialize all pad formats with default values. If fh is not NULL, try
1032 * formats are initialized on the file handle. Otherwise active formats are
1033 * initialized on the device.
1034 */
1035static int csi2_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
1036{
1037 struct v4l2_subdev_format format;
1038
1039 memset(&format, 0, sizeof(format));
1040 format.pad = CSI2_PAD_SINK;
1041 format.which = fh ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE;
1042 format.format.code = V4L2_MBUS_FMT_SGRBG10_1X10;
1043 format.format.width = 4096;
1044 format.format.height = 4096;
1045 csi2_set_format(sd, fh, &format);
1046
1047 return 0;
1048}
1049
1050/*
1051 * csi2_set_stream - Enable/Disable streaming on the CSI2 module
1052 * @sd: ISP CSI2 V4L2 subdevice
1053 * @enable: ISP pipeline stream state
1054 *
1055 * Return 0 on success or a negative error code otherwise.
1056 */
1057static int csi2_set_stream(struct v4l2_subdev *sd, int enable)
1058{
1059 struct isp_csi2_device *csi2 = v4l2_get_subdevdata(sd);
1060 struct isp_device *isp = csi2->isp;
1061 struct isp_video *video_out = &csi2->video_out;
1062
1063 switch (enable) {
1064 case ISP_PIPELINE_STREAM_CONTINUOUS:
1065 if (omap3isp_csiphy_acquire(csi2->phy) < 0)
1066 return -ENODEV;
1067 if (csi2->output & CSI2_OUTPUT_MEMORY)
1068 omap3isp_sbl_enable(isp, OMAP3_ISP_SBL_CSI2A_WRITE);
1069 csi2_configure(csi2);
1070 csi2_print_status(csi2);
1071
1072 /*
1073 * When outputting to memory with no buffer available, let the
1074 * buffer queue handler start the hardware. A DMA queue flag
1075 * ISP_VIDEO_DMAQUEUE_QUEUED will be set as soon as there is
1076 * a buffer available.
1077 */
1078 if (csi2->output & CSI2_OUTPUT_MEMORY &&
1079 !(video_out->dmaqueue_flags & ISP_VIDEO_DMAQUEUE_QUEUED))
1080 break;
1081 /* Enable context 0 and IRQs */
1082 atomic_set(&csi2->stopping, 0);
1083 csi2_ctx_enable(isp, csi2, 0, 1);
1084 csi2_if_enable(isp, csi2, 1);
1085 isp_video_dmaqueue_flags_clr(video_out);
1086 break;
1087
1088 case ISP_PIPELINE_STREAM_STOPPED:
1089 if (csi2->state == ISP_PIPELINE_STREAM_STOPPED)
1090 return 0;
1091 if (omap3isp_module_sync_idle(&sd->entity, &csi2->wait,
1092 &csi2->stopping))
1093 dev_dbg(isp->dev, "%s: module stop timeout.\n",
1094 sd->name);
1095 csi2_ctx_enable(isp, csi2, 0, 0);
1096 csi2_if_enable(isp, csi2, 0);
1097 csi2_irq_ctx_set(isp, csi2, 0);
1098 omap3isp_csiphy_release(csi2->phy);
1099 isp_video_dmaqueue_flags_clr(video_out);
1100 omap3isp_sbl_disable(isp, OMAP3_ISP_SBL_CSI2A_WRITE);
1101 break;
1102 }
1103
1104 csi2->state = enable;
1105 return 0;
1106}
1107
1108/* subdev video operations */
1109static const struct v4l2_subdev_video_ops csi2_video_ops = {
1110 .s_stream = csi2_set_stream,
1111};
1112
1113/* subdev pad operations */
1114static const struct v4l2_subdev_pad_ops csi2_pad_ops = {
1115 .enum_mbus_code = csi2_enum_mbus_code,
1116 .enum_frame_size = csi2_enum_frame_size,
1117 .get_fmt = csi2_get_format,
1118 .set_fmt = csi2_set_format,
1119};
1120
1121/* subdev operations */
1122static const struct v4l2_subdev_ops csi2_ops = {
1123 .video = &csi2_video_ops,
1124 .pad = &csi2_pad_ops,
1125};
1126
1127/* subdev internal operations */
1128static const struct v4l2_subdev_internal_ops csi2_internal_ops = {
1129 .open = csi2_init_formats,
1130};
1131
1132/* -----------------------------------------------------------------------------
1133 * Media entity operations
1134 */
1135
1136/*
1137 * csi2_link_setup - Setup CSI2 connections.
1138 * @entity : Pointer to media entity structure
1139 * @local : Pointer to local pad array
1140 * @remote : Pointer to remote pad array
1141 * @flags : Link flags
1142 * return -EINVAL or zero on success
1143 */
1144static int csi2_link_setup(struct media_entity *entity,
1145 const struct media_pad *local,
1146 const struct media_pad *remote, u32 flags)
1147{
1148 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
1149 struct isp_csi2_device *csi2 = v4l2_get_subdevdata(sd);
1150 struct isp_csi2_ctrl_cfg *ctrl = &csi2->ctrl;
1151
1152 /*
1153 * The ISP core doesn't support pipelines with multiple video outputs.
1154 * Revisit this when it will be implemented, and return -EBUSY for now.
1155 */
1156
1157 switch (local->index | media_entity_type(remote->entity)) {
1158 case CSI2_PAD_SOURCE | MEDIA_ENT_T_DEVNODE:
1159 if (flags & MEDIA_LNK_FL_ENABLED) {
1160 if (csi2->output & ~CSI2_OUTPUT_MEMORY)
1161 return -EBUSY;
1162 csi2->output |= CSI2_OUTPUT_MEMORY;
1163 } else {
1164 csi2->output &= ~CSI2_OUTPUT_MEMORY;
1165 }
1166 break;
1167
1168 case CSI2_PAD_SOURCE | MEDIA_ENT_T_V4L2_SUBDEV:
1169 if (flags & MEDIA_LNK_FL_ENABLED) {
1170 if (csi2->output & ~CSI2_OUTPUT_CCDC)
1171 return -EBUSY;
1172 csi2->output |= CSI2_OUTPUT_CCDC;
1173 } else {
1174 csi2->output &= ~CSI2_OUTPUT_CCDC;
1175 }
1176 break;
1177
1178 default:
1179 /* Link from camera to CSI2 is fixed... */
1180 return -EINVAL;
1181 }
1182
1183 ctrl->vp_only_enable =
1184 (csi2->output & CSI2_OUTPUT_MEMORY) ? false : true;
1185 ctrl->vp_clk_enable = !!(csi2->output & CSI2_OUTPUT_CCDC);
1186
1187 return 0;
1188}
1189
1190/* media operations */
1191static const struct media_entity_operations csi2_media_ops = {
1192 .link_setup = csi2_link_setup,
1193 .link_validate = v4l2_subdev_link_validate,
1194};
1195
1196void omap3isp_csi2_unregister_entities(struct isp_csi2_device *csi2)
1197{
1198 v4l2_device_unregister_subdev(&csi2->subdev);
1199 omap3isp_video_unregister(&csi2->video_out);
1200}
1201
1202int omap3isp_csi2_register_entities(struct isp_csi2_device *csi2,
1203 struct v4l2_device *vdev)
1204{
1205 int ret;
1206
1207 /* Register the subdev and video nodes. */
1208 ret = v4l2_device_register_subdev(vdev, &csi2->subdev);
1209 if (ret < 0)
1210 goto error;
1211
1212 ret = omap3isp_video_register(&csi2->video_out, vdev);
1213 if (ret < 0)
1214 goto error;
1215
1216 return 0;
1217
1218error:
1219 omap3isp_csi2_unregister_entities(csi2);
1220 return ret;
1221}
1222
1223/* -----------------------------------------------------------------------------
1224 * ISP CSI2 initialisation and cleanup
1225 */
1226
1227/*
1228 * csi2_init_entities - Initialize subdev and media entity.
1229 * @csi2: Pointer to csi2 structure.
1230 * return -ENOMEM or zero on success
1231 */
1232static int csi2_init_entities(struct isp_csi2_device *csi2)
1233{
1234 struct v4l2_subdev *sd = &csi2->subdev;
1235 struct media_pad *pads = csi2->pads;
1236 struct media_entity *me = &sd->entity;
1237 int ret;
1238
1239 v4l2_subdev_init(sd, &csi2_ops);
1240 sd->internal_ops = &csi2_internal_ops;
1241 strlcpy(sd->name, "OMAP3 ISP CSI2a", sizeof(sd->name));
1242
1243 sd->grp_id = 1 << 16; /* group ID for isp subdevs */
1244 v4l2_set_subdevdata(sd, csi2);
1245 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
1246
1247 pads[CSI2_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
1248 pads[CSI2_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
1249
1250 me->ops = &csi2_media_ops;
1251 ret = media_entity_init(me, CSI2_PADS_NUM, pads, 0);
1252 if (ret < 0)
1253 return ret;
1254
1255 csi2_init_formats(sd, NULL);
1256
1257 /* Video device node */
1258 csi2->video_out.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1259 csi2->video_out.ops = &csi2_ispvideo_ops;
1260 csi2->video_out.bpl_alignment = 32;
1261 csi2->video_out.bpl_zero_padding = 1;
1262 csi2->video_out.bpl_max = 0x1ffe0;
1263 csi2->video_out.isp = csi2->isp;
1264 csi2->video_out.capture_mem = PAGE_ALIGN(4096 * 4096) * 3;
1265
1266 ret = omap3isp_video_init(&csi2->video_out, "CSI2a");
1267 if (ret < 0)
1268 goto error_video;
1269
1270 /* Connect the CSI2 subdev to the video node. */
1271 ret = media_entity_create_link(&csi2->subdev.entity, CSI2_PAD_SOURCE,
1272 &csi2->video_out.video.entity, 0, 0);
1273 if (ret < 0)
1274 goto error_link;
1275
1276 return 0;
1277
1278error_link:
1279 omap3isp_video_cleanup(&csi2->video_out);
1280error_video:
1281 media_entity_cleanup(&csi2->subdev.entity);
1282 return ret;
1283}
1284
1285/*
1286 * omap3isp_csi2_init - Routine for module driver init
1287 */
1288int omap3isp_csi2_init(struct isp_device *isp)
1289{
1290 struct isp_csi2_device *csi2a = &isp->isp_csi2a;
1291 struct isp_csi2_device *csi2c = &isp->isp_csi2c;
1292 int ret;
1293
1294 csi2a->isp = isp;
1295 csi2a->available = 1;
1296 csi2a->regs1 = OMAP3_ISP_IOMEM_CSI2A_REGS1;
1297 csi2a->regs2 = OMAP3_ISP_IOMEM_CSI2A_REGS2;
1298 csi2a->phy = &isp->isp_csiphy2;
1299 csi2a->state = ISP_PIPELINE_STREAM_STOPPED;
1300 init_waitqueue_head(&csi2a->wait);
1301
1302 ret = csi2_init_entities(csi2a);
1303 if (ret < 0)
1304 return ret;
1305
1306 if (isp->revision == ISP_REVISION_15_0) {
1307 csi2c->isp = isp;
1308 csi2c->available = 1;
1309 csi2c->regs1 = OMAP3_ISP_IOMEM_CSI2C_REGS1;
1310 csi2c->regs2 = OMAP3_ISP_IOMEM_CSI2C_REGS2;
1311 csi2c->phy = &isp->isp_csiphy1;
1312 csi2c->state = ISP_PIPELINE_STREAM_STOPPED;
1313 init_waitqueue_head(&csi2c->wait);
1314 }
1315
1316 return 0;
1317}
1318
1319/*
1320 * omap3isp_csi2_cleanup - Routine for module driver cleanup
1321 */
1322void omap3isp_csi2_cleanup(struct isp_device *isp)
1323{
1324 struct isp_csi2_device *csi2a = &isp->isp_csi2a;
1325
1326 omap3isp_video_cleanup(&csi2a->video_out);
1327 media_entity_cleanup(&csi2a->subdev.entity);
1328}
diff --git a/drivers/media/video/omap3isp/ispcsi2.h b/drivers/media/video/omap3isp/ispcsi2.h
deleted file mode 100644
index c57729b7e86e..000000000000
--- a/drivers/media/video/omap3isp/ispcsi2.h
+++ /dev/null
@@ -1,165 +0,0 @@
1/*
2 * ispcsi2.h
3 *
4 * TI OMAP3 ISP - CSI2 module
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc.
8 *
9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 * Sakari Ailus <sakari.ailus@iki.fi>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 */
26
27#ifndef OMAP3_ISP_CSI2_H
28#define OMAP3_ISP_CSI2_H
29
30#include <linux/types.h>
31#include <linux/videodev2.h>
32
33struct isp_csiphy;
34
35/* This is not an exhaustive list */
36enum isp_csi2_pix_formats {
37 CSI2_PIX_FMT_OTHERS = 0,
38 CSI2_PIX_FMT_YUV422_8BIT = 0x1e,
39 CSI2_PIX_FMT_YUV422_8BIT_VP = 0x9e,
40 CSI2_PIX_FMT_RAW10_EXP16 = 0xab,
41 CSI2_PIX_FMT_RAW10_EXP16_VP = 0x12f,
42 CSI2_PIX_FMT_RAW8 = 0x2a,
43 CSI2_PIX_FMT_RAW8_DPCM10_EXP16 = 0x2aa,
44 CSI2_PIX_FMT_RAW8_DPCM10_VP = 0x32a,
45 CSI2_PIX_FMT_RAW8_VP = 0x12a,
46 CSI2_USERDEF_8BIT_DATA1_DPCM10_VP = 0x340,
47 CSI2_USERDEF_8BIT_DATA1_DPCM10 = 0x2c0,
48 CSI2_USERDEF_8BIT_DATA1 = 0x40,
49};
50
51enum isp_csi2_irqevents {
52 OCP_ERR_IRQ = 0x4000,
53 SHORT_PACKET_IRQ = 0x2000,
54 ECC_CORRECTION_IRQ = 0x1000,
55 ECC_NO_CORRECTION_IRQ = 0x800,
56 COMPLEXIO2_ERR_IRQ = 0x400,
57 COMPLEXIO1_ERR_IRQ = 0x200,
58 FIFO_OVF_IRQ = 0x100,
59 CONTEXT7 = 0x80,
60 CONTEXT6 = 0x40,
61 CONTEXT5 = 0x20,
62 CONTEXT4 = 0x10,
63 CONTEXT3 = 0x8,
64 CONTEXT2 = 0x4,
65 CONTEXT1 = 0x2,
66 CONTEXT0 = 0x1,
67};
68
69enum isp_csi2_ctx_irqevents {
70 CTX_ECC_CORRECTION = 0x100,
71 CTX_LINE_NUMBER = 0x80,
72 CTX_FRAME_NUMBER = 0x40,
73 CTX_CS = 0x20,
74 CTX_LE = 0x8,
75 CTX_LS = 0x4,
76 CTX_FE = 0x2,
77 CTX_FS = 0x1,
78};
79
80enum isp_csi2_frame_mode {
81 ISP_CSI2_FRAME_IMMEDIATE,
82 ISP_CSI2_FRAME_AFTERFEC,
83};
84
85#define ISP_CSI2_MAX_CTX_NUM 7
86
87struct isp_csi2_ctx_cfg {
88 u8 ctxnum; /* context number 0 - 7 */
89 u8 dpcm_decompress;
90
91 /* Fields in CSI2_CTx_CTRL2 - locked by CSI2_CTx_CTRL1.CTX_EN */
92 u8 virtual_id;
93 u16 format_id; /* as in CSI2_CTx_CTRL2[9:0] */
94 u8 dpcm_predictor; /* 1: simple, 0: advanced */
95
96 /* Fields in CSI2_CTx_CTRL1/3 - Shadowed */
97 u16 alpha;
98 u16 data_offset;
99 u32 ping_addr;
100 u32 pong_addr;
101 u8 eof_enabled;
102 u8 eol_enabled;
103 u8 checksum_enabled;
104 u8 enabled;
105};
106
107struct isp_csi2_timing_cfg {
108 u8 ionum; /* IO1 or IO2 as in CSI2_TIMING */
109 unsigned force_rx_mode:1;
110 unsigned stop_state_16x:1;
111 unsigned stop_state_4x:1;
112 u16 stop_state_counter;
113};
114
115struct isp_csi2_ctrl_cfg {
116 bool vp_clk_enable;
117 bool vp_only_enable;
118 u8 vp_out_ctrl;
119 enum isp_csi2_frame_mode frame_mode;
120 bool ecc_enable;
121 bool if_enable;
122};
123
124#define CSI2_PAD_SINK 0
125#define CSI2_PAD_SOURCE 1
126#define CSI2_PADS_NUM 2
127
128#define CSI2_OUTPUT_CCDC (1 << 0)
129#define CSI2_OUTPUT_MEMORY (1 << 1)
130
131struct isp_csi2_device {
132 struct v4l2_subdev subdev;
133 struct media_pad pads[CSI2_PADS_NUM];
134 struct v4l2_mbus_framefmt formats[CSI2_PADS_NUM];
135
136 struct isp_video video_out;
137 struct isp_device *isp;
138
139 u8 available; /* Is the IP present on the silicon? */
140
141 /* mem resources - enums as defined in enum isp_mem_resources */
142 u8 regs1;
143 u8 regs2;
144
145 u32 output; /* output to CCDC, memory or both? */
146 bool dpcm_decompress;
147 unsigned int frame_skip;
148
149 struct isp_csiphy *phy;
150 struct isp_csi2_ctx_cfg contexts[ISP_CSI2_MAX_CTX_NUM + 1];
151 struct isp_csi2_timing_cfg timing[2];
152 struct isp_csi2_ctrl_cfg ctrl;
153 enum isp_pipeline_stream_state state;
154 wait_queue_head_t wait;
155 atomic_t stopping;
156};
157
158void omap3isp_csi2_isr(struct isp_csi2_device *csi2);
159int omap3isp_csi2_reset(struct isp_csi2_device *csi2);
160int omap3isp_csi2_init(struct isp_device *isp);
161void omap3isp_csi2_cleanup(struct isp_device *isp);
162void omap3isp_csi2_unregister_entities(struct isp_csi2_device *csi2);
163int omap3isp_csi2_register_entities(struct isp_csi2_device *csi2,
164 struct v4l2_device *vdev);
165#endif /* OMAP3_ISP_CSI2_H */
diff --git a/drivers/media/video/omap3isp/ispcsiphy.c b/drivers/media/video/omap3isp/ispcsiphy.c
deleted file mode 100644
index 348f67ebbbc9..000000000000
--- a/drivers/media/video/omap3isp/ispcsiphy.c
+++ /dev/null
@@ -1,249 +0,0 @@
1/*
2 * ispcsiphy.c
3 *
4 * TI OMAP3 ISP - CSI PHY module
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc.
8 *
9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 * Sakari Ailus <sakari.ailus@iki.fi>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 */
26
27#include <linux/delay.h>
28#include <linux/device.h>
29#include <linux/regulator/consumer.h>
30
31#include "isp.h"
32#include "ispreg.h"
33#include "ispcsiphy.h"
34
35/*
36 * csiphy_lanes_config - Configuration of CSIPHY lanes.
37 *
38 * Updates HW configuration.
39 * Called with phy->mutex taken.
40 */
41static void csiphy_lanes_config(struct isp_csiphy *phy)
42{
43 unsigned int i;
44 u32 reg;
45
46 reg = isp_reg_readl(phy->isp, phy->cfg_regs, ISPCSI2_PHY_CFG);
47
48 for (i = 0; i < phy->num_data_lanes; i++) {
49 reg &= ~(ISPCSI2_PHY_CFG_DATA_POL_MASK(i + 1) |
50 ISPCSI2_PHY_CFG_DATA_POSITION_MASK(i + 1));
51 reg |= (phy->lanes.data[i].pol <<
52 ISPCSI2_PHY_CFG_DATA_POL_SHIFT(i + 1));
53 reg |= (phy->lanes.data[i].pos <<
54 ISPCSI2_PHY_CFG_DATA_POSITION_SHIFT(i + 1));
55 }
56
57 reg &= ~(ISPCSI2_PHY_CFG_CLOCK_POL_MASK |
58 ISPCSI2_PHY_CFG_CLOCK_POSITION_MASK);
59 reg |= phy->lanes.clk.pol << ISPCSI2_PHY_CFG_CLOCK_POL_SHIFT;
60 reg |= phy->lanes.clk.pos << ISPCSI2_PHY_CFG_CLOCK_POSITION_SHIFT;
61
62 isp_reg_writel(phy->isp, reg, phy->cfg_regs, ISPCSI2_PHY_CFG);
63}
64
65/*
66 * csiphy_power_autoswitch_enable
67 * @enable: Sets or clears the autoswitch function enable flag.
68 */
69static void csiphy_power_autoswitch_enable(struct isp_csiphy *phy, bool enable)
70{
71 isp_reg_clr_set(phy->isp, phy->cfg_regs, ISPCSI2_PHY_CFG,
72 ISPCSI2_PHY_CFG_PWR_AUTO,
73 enable ? ISPCSI2_PHY_CFG_PWR_AUTO : 0);
74}
75
76/*
77 * csiphy_set_power
78 * @power: Power state to be set.
79 *
80 * Returns 0 if successful, or -EBUSY if the retry count is exceeded.
81 */
82static int csiphy_set_power(struct isp_csiphy *phy, u32 power)
83{
84 u32 reg;
85 u8 retry_count;
86
87 isp_reg_clr_set(phy->isp, phy->cfg_regs, ISPCSI2_PHY_CFG,
88 ISPCSI2_PHY_CFG_PWR_CMD_MASK, power);
89
90 retry_count = 0;
91 do {
92 udelay(50);
93 reg = isp_reg_readl(phy->isp, phy->cfg_regs, ISPCSI2_PHY_CFG) &
94 ISPCSI2_PHY_CFG_PWR_STATUS_MASK;
95
96 if (reg != power >> 2)
97 retry_count++;
98
99 } while ((reg != power >> 2) && (retry_count < 100));
100
101 if (retry_count == 100) {
102 printk(KERN_ERR "CSI2 CIO set power failed!\n");
103 return -EBUSY;
104 }
105
106 return 0;
107}
108
109/*
110 * csiphy_dphy_config - Configure CSI2 D-PHY parameters.
111 *
112 * Called with phy->mutex taken.
113 */
114static void csiphy_dphy_config(struct isp_csiphy *phy)
115{
116 u32 reg;
117
118 /* Set up ISPCSIPHY_REG0 */
119 reg = isp_reg_readl(phy->isp, phy->phy_regs, ISPCSIPHY_REG0);
120
121 reg &= ~(ISPCSIPHY_REG0_THS_TERM_MASK |
122 ISPCSIPHY_REG0_THS_SETTLE_MASK);
123 reg |= phy->dphy.ths_term << ISPCSIPHY_REG0_THS_TERM_SHIFT;
124 reg |= phy->dphy.ths_settle << ISPCSIPHY_REG0_THS_SETTLE_SHIFT;
125
126 isp_reg_writel(phy->isp, reg, phy->phy_regs, ISPCSIPHY_REG0);
127
128 /* Set up ISPCSIPHY_REG1 */
129 reg = isp_reg_readl(phy->isp, phy->phy_regs, ISPCSIPHY_REG1);
130
131 reg &= ~(ISPCSIPHY_REG1_TCLK_TERM_MASK |
132 ISPCSIPHY_REG1_TCLK_MISS_MASK |
133 ISPCSIPHY_REG1_TCLK_SETTLE_MASK);
134 reg |= phy->dphy.tclk_term << ISPCSIPHY_REG1_TCLK_TERM_SHIFT;
135 reg |= phy->dphy.tclk_miss << ISPCSIPHY_REG1_TCLK_MISS_SHIFT;
136 reg |= phy->dphy.tclk_settle << ISPCSIPHY_REG1_TCLK_SETTLE_SHIFT;
137
138 isp_reg_writel(phy->isp, reg, phy->phy_regs, ISPCSIPHY_REG1);
139}
140
141static int csiphy_config(struct isp_csiphy *phy,
142 struct isp_csiphy_dphy_cfg *dphy,
143 struct isp_csiphy_lanes_cfg *lanes)
144{
145 unsigned int used_lanes = 0;
146 unsigned int i;
147
148 /* Clock and data lanes verification */
149 for (i = 0; i < phy->num_data_lanes; i++) {
150 if (lanes->data[i].pol > 1 || lanes->data[i].pos > 3)
151 return -EINVAL;
152
153 if (used_lanes & (1 << lanes->data[i].pos))
154 return -EINVAL;
155
156 used_lanes |= 1 << lanes->data[i].pos;
157 }
158
159 if (lanes->clk.pol > 1 || lanes->clk.pos > 3)
160 return -EINVAL;
161
162 if (lanes->clk.pos == 0 || used_lanes & (1 << lanes->clk.pos))
163 return -EINVAL;
164
165 mutex_lock(&phy->mutex);
166 phy->dphy = *dphy;
167 phy->lanes = *lanes;
168 mutex_unlock(&phy->mutex);
169
170 return 0;
171}
172
173int omap3isp_csiphy_acquire(struct isp_csiphy *phy)
174{
175 int rval;
176
177 if (phy->vdd == NULL) {
178 dev_err(phy->isp->dev, "Power regulator for CSI PHY not "
179 "available\n");
180 return -ENODEV;
181 }
182
183 mutex_lock(&phy->mutex);
184
185 rval = regulator_enable(phy->vdd);
186 if (rval < 0)
187 goto done;
188
189 rval = omap3isp_csi2_reset(phy->csi2);
190 if (rval < 0)
191 goto done;
192
193 csiphy_dphy_config(phy);
194 csiphy_lanes_config(phy);
195
196 rval = csiphy_set_power(phy, ISPCSI2_PHY_CFG_PWR_CMD_ON);
197 if (rval) {
198 regulator_disable(phy->vdd);
199 goto done;
200 }
201
202 csiphy_power_autoswitch_enable(phy, true);
203 phy->phy_in_use = 1;
204
205done:
206 mutex_unlock(&phy->mutex);
207 return rval;
208}
209
210void omap3isp_csiphy_release(struct isp_csiphy *phy)
211{
212 mutex_lock(&phy->mutex);
213 if (phy->phy_in_use) {
214 csiphy_power_autoswitch_enable(phy, false);
215 csiphy_set_power(phy, ISPCSI2_PHY_CFG_PWR_CMD_OFF);
216 regulator_disable(phy->vdd);
217 phy->phy_in_use = 0;
218 }
219 mutex_unlock(&phy->mutex);
220}
221
222/*
223 * omap3isp_csiphy_init - Initialize the CSI PHY frontends
224 */
225int omap3isp_csiphy_init(struct isp_device *isp)
226{
227 struct isp_csiphy *phy1 = &isp->isp_csiphy1;
228 struct isp_csiphy *phy2 = &isp->isp_csiphy2;
229
230 isp->platform_cb.csiphy_config = csiphy_config;
231
232 phy2->isp = isp;
233 phy2->csi2 = &isp->isp_csi2a;
234 phy2->num_data_lanes = ISP_CSIPHY2_NUM_DATA_LANES;
235 phy2->cfg_regs = OMAP3_ISP_IOMEM_CSI2A_REGS1;
236 phy2->phy_regs = OMAP3_ISP_IOMEM_CSIPHY2;
237 mutex_init(&phy2->mutex);
238
239 if (isp->revision == ISP_REVISION_15_0) {
240 phy1->isp = isp;
241 phy1->csi2 = &isp->isp_csi2c;
242 phy1->num_data_lanes = ISP_CSIPHY1_NUM_DATA_LANES;
243 phy1->cfg_regs = OMAP3_ISP_IOMEM_CSI2C_REGS1;
244 phy1->phy_regs = OMAP3_ISP_IOMEM_CSIPHY1;
245 mutex_init(&phy1->mutex);
246 }
247
248 return 0;
249}
diff --git a/drivers/media/video/omap3isp/ispcsiphy.h b/drivers/media/video/omap3isp/ispcsiphy.h
deleted file mode 100644
index e93a661e65d9..000000000000
--- a/drivers/media/video/omap3isp/ispcsiphy.h
+++ /dev/null
@@ -1,63 +0,0 @@
1/*
2 * ispcsiphy.h
3 *
4 * TI OMAP3 ISP - CSI PHY module
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc.
8 *
9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 * Sakari Ailus <sakari.ailus@iki.fi>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 */
26
27#ifndef OMAP3_ISP_CSI_PHY_H
28#define OMAP3_ISP_CSI_PHY_H
29
30#include <media/omap3isp.h>
31
32struct isp_csi2_device;
33struct regulator;
34
35struct isp_csiphy_dphy_cfg {
36 u8 ths_term;
37 u8 ths_settle;
38 u8 tclk_term;
39 unsigned tclk_miss:1;
40 u8 tclk_settle;
41};
42
43struct isp_csiphy {
44 struct isp_device *isp;
45 struct mutex mutex; /* serialize csiphy configuration */
46 u8 phy_in_use;
47 struct isp_csi2_device *csi2;
48 struct regulator *vdd;
49
50 /* mem resources - enums as defined in enum isp_mem_resources */
51 unsigned int cfg_regs;
52 unsigned int phy_regs;
53
54 u8 num_data_lanes; /* number of CSI2 Data Lanes supported */
55 struct isp_csiphy_lanes_cfg lanes;
56 struct isp_csiphy_dphy_cfg dphy;
57};
58
59int omap3isp_csiphy_acquire(struct isp_csiphy *phy);
60void omap3isp_csiphy_release(struct isp_csiphy *phy);
61int omap3isp_csiphy_init(struct isp_device *isp);
62
63#endif /* OMAP3_ISP_CSI_PHY_H */
diff --git a/drivers/media/video/omap3isp/isph3a.h b/drivers/media/video/omap3isp/isph3a.h
deleted file mode 100644
index fb09fd4ca755..000000000000
--- a/drivers/media/video/omap3isp/isph3a.h
+++ /dev/null
@@ -1,117 +0,0 @@
1/*
2 * isph3a.h
3 *
4 * TI OMAP3 ISP - H3A AF module
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc.
8 *
9 * Contacts: David Cohen <dacohen@gmail.com>
10 * Laurent Pinchart <laurent.pinchart@ideasonboard.com>
11 * Sakari Ailus <sakari.ailus@iki.fi>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
25 * 02110-1301 USA
26 */
27
28#ifndef OMAP3_ISP_H3A_H
29#define OMAP3_ISP_H3A_H
30
31#include <linux/omap3isp.h>
32
33/*
34 * ----------
35 * -H3A AEWB-
36 * ----------
37 */
38
39#define AEWB_PACKET_SIZE 16
40#define AEWB_SATURATION_LIMIT 0x3ff
41
42/* Flags for changed registers */
43#define PCR_CHNG (1 << 0)
44#define AEWWIN1_CHNG (1 << 1)
45#define AEWINSTART_CHNG (1 << 2)
46#define AEWINBLK_CHNG (1 << 3)
47#define AEWSUBWIN_CHNG (1 << 4)
48#define PRV_WBDGAIN_CHNG (1 << 5)
49#define PRV_WBGAIN_CHNG (1 << 6)
50
51/* ISPH3A REGISTERS bits */
52#define ISPH3A_PCR_AF_EN (1 << 0)
53#define ISPH3A_PCR_AF_ALAW_EN (1 << 1)
54#define ISPH3A_PCR_AF_MED_EN (1 << 2)
55#define ISPH3A_PCR_AF_BUSY (1 << 15)
56#define ISPH3A_PCR_AEW_EN (1 << 16)
57#define ISPH3A_PCR_AEW_ALAW_EN (1 << 17)
58#define ISPH3A_PCR_AEW_BUSY (1 << 18)
59#define ISPH3A_PCR_AEW_MASK (ISPH3A_PCR_AEW_ALAW_EN | \
60 ISPH3A_PCR_AEW_AVE2LMT_MASK)
61
62/*
63 * --------
64 * -H3A AF-
65 * --------
66 */
67
68/* Peripheral Revision */
69#define AFPID 0x0
70
71#define AFCOEF_OFFSET 0x00000004 /* COEF base address */
72
73/* PCR fields */
74#define AF_BUSYAF (1 << 15)
75#define AF_FVMODE (1 << 14)
76#define AF_RGBPOS (0x7 << 11)
77#define AF_MED_TH (0xFF << 3)
78#define AF_MED_EN (1 << 2)
79#define AF_ALAW_EN (1 << 1)
80#define AF_EN (1 << 0)
81#define AF_PCR_MASK (AF_FVMODE | AF_RGBPOS | AF_MED_TH | \
82 AF_MED_EN | AF_ALAW_EN)
83
84/* AFPAX1 fields */
85#define AF_PAXW (0x7F << 16)
86#define AF_PAXH 0x7F
87
88/* AFPAX2 fields */
89#define AF_AFINCV (0xF << 13)
90#define AF_PAXVC (0x7F << 6)
91#define AF_PAXHC 0x3F
92
93/* AFPAXSTART fields */
94#define AF_PAXSH (0xFFF<<16)
95#define AF_PAXSV 0xFFF
96
97/* COEFFICIENT MASK */
98#define AF_COEF_MASK0 0xFFF
99#define AF_COEF_MASK1 (0xFFF<<16)
100
101/* BIT SHIFTS */
102#define AF_RGBPOS_SHIFT 11
103#define AF_MED_TH_SHIFT 3
104#define AF_PAXW_SHIFT 16
105#define AF_LINE_INCR_SHIFT 13
106#define AF_VT_COUNT_SHIFT 6
107#define AF_HZ_START_SHIFT 16
108#define AF_COEF_SHIFT 16
109
110/* Init and cleanup functions */
111int omap3isp_h3a_aewb_init(struct isp_device *isp);
112int omap3isp_h3a_af_init(struct isp_device *isp);
113
114void omap3isp_h3a_aewb_cleanup(struct isp_device *isp);
115void omap3isp_h3a_af_cleanup(struct isp_device *isp);
116
117#endif /* OMAP3_ISP_H3A_H */
diff --git a/drivers/media/video/omap3isp/isph3a_aewb.c b/drivers/media/video/omap3isp/isph3a_aewb.c
deleted file mode 100644
index 036e9961d027..000000000000
--- a/drivers/media/video/omap3isp/isph3a_aewb.c
+++ /dev/null
@@ -1,368 +0,0 @@
1/*
2 * isph3a.c
3 *
4 * TI OMAP3 ISP - H3A module
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc.
8 *
9 * Contacts: David Cohen <dacohen@gmail.com>
10 * Laurent Pinchart <laurent.pinchart@ideasonboard.com>
11 * Sakari Ailus <sakari.ailus@iki.fi>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
25 * 02110-1301 USA
26 */
27
28#include <linux/slab.h>
29#include <linux/uaccess.h>
30
31#include "isp.h"
32#include "isph3a.h"
33#include "ispstat.h"
34
35/*
36 * h3a_aewb_update_regs - Helper function to update h3a registers.
37 */
38static void h3a_aewb_setup_regs(struct ispstat *aewb, void *priv)
39{
40 struct omap3isp_h3a_aewb_config *conf = priv;
41 u32 pcr;
42 u32 win1;
43 u32 start;
44 u32 blk;
45 u32 subwin;
46
47 if (aewb->state == ISPSTAT_DISABLED)
48 return;
49
50 isp_reg_writel(aewb->isp, aewb->active_buf->iommu_addr,
51 OMAP3_ISP_IOMEM_H3A, ISPH3A_AEWBUFST);
52
53 if (!aewb->update)
54 return;
55
56 /* Converting config metadata into reg values */
57 pcr = conf->saturation_limit << ISPH3A_PCR_AEW_AVE2LMT_SHIFT;
58 pcr |= !!conf->alaw_enable << ISPH3A_PCR_AEW_ALAW_EN_SHIFT;
59
60 win1 = ((conf->win_height >> 1) - 1) << ISPH3A_AEWWIN1_WINH_SHIFT;
61 win1 |= ((conf->win_width >> 1) - 1) << ISPH3A_AEWWIN1_WINW_SHIFT;
62 win1 |= (conf->ver_win_count - 1) << ISPH3A_AEWWIN1_WINVC_SHIFT;
63 win1 |= (conf->hor_win_count - 1) << ISPH3A_AEWWIN1_WINHC_SHIFT;
64
65 start = conf->hor_win_start << ISPH3A_AEWINSTART_WINSH_SHIFT;
66 start |= conf->ver_win_start << ISPH3A_AEWINSTART_WINSV_SHIFT;
67
68 blk = conf->blk_ver_win_start << ISPH3A_AEWINBLK_WINSV_SHIFT;
69 blk |= ((conf->blk_win_height >> 1) - 1) << ISPH3A_AEWINBLK_WINH_SHIFT;
70
71 subwin = ((conf->subsample_ver_inc >> 1) - 1) <<
72 ISPH3A_AEWSUBWIN_AEWINCV_SHIFT;
73 subwin |= ((conf->subsample_hor_inc >> 1) - 1) <<
74 ISPH3A_AEWSUBWIN_AEWINCH_SHIFT;
75
76 isp_reg_writel(aewb->isp, win1, OMAP3_ISP_IOMEM_H3A, ISPH3A_AEWWIN1);
77 isp_reg_writel(aewb->isp, start, OMAP3_ISP_IOMEM_H3A,
78 ISPH3A_AEWINSTART);
79 isp_reg_writel(aewb->isp, blk, OMAP3_ISP_IOMEM_H3A, ISPH3A_AEWINBLK);
80 isp_reg_writel(aewb->isp, subwin, OMAP3_ISP_IOMEM_H3A,
81 ISPH3A_AEWSUBWIN);
82 isp_reg_clr_set(aewb->isp, OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR,
83 ISPH3A_PCR_AEW_MASK, pcr);
84
85 aewb->update = 0;
86 aewb->config_counter += aewb->inc_config;
87 aewb->inc_config = 0;
88 aewb->buf_size = conf->buf_size;
89}
90
91static void h3a_aewb_enable(struct ispstat *aewb, int enable)
92{
93 if (enable) {
94 isp_reg_set(aewb->isp, OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR,
95 ISPH3A_PCR_AEW_EN);
96 omap3isp_subclk_enable(aewb->isp, OMAP3_ISP_SUBCLK_AEWB);
97 } else {
98 isp_reg_clr(aewb->isp, OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR,
99 ISPH3A_PCR_AEW_EN);
100 omap3isp_subclk_disable(aewb->isp, OMAP3_ISP_SUBCLK_AEWB);
101 }
102}
103
104static int h3a_aewb_busy(struct ispstat *aewb)
105{
106 return isp_reg_readl(aewb->isp, OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR)
107 & ISPH3A_PCR_BUSYAEAWB;
108}
109
110static u32 h3a_aewb_get_buf_size(struct omap3isp_h3a_aewb_config *conf)
111{
112 /* Number of configured windows + extra row for black data */
113 u32 win_count = (conf->ver_win_count + 1) * conf->hor_win_count;
114
115 /*
116 * Unsaturated block counts for each 8 windows.
117 * 1 extra for the last (win_count % 8) windows if win_count is not
118 * divisible by 8.
119 */
120 win_count += (win_count + 7) / 8;
121
122 return win_count * AEWB_PACKET_SIZE;
123}
124
125static int h3a_aewb_validate_params(struct ispstat *aewb, void *new_conf)
126{
127 struct omap3isp_h3a_aewb_config *user_cfg = new_conf;
128 u32 buf_size;
129
130 if (unlikely(user_cfg->saturation_limit >
131 OMAP3ISP_AEWB_MAX_SATURATION_LIM))
132 return -EINVAL;
133
134 if (unlikely(user_cfg->win_height < OMAP3ISP_AEWB_MIN_WIN_H ||
135 user_cfg->win_height > OMAP3ISP_AEWB_MAX_WIN_H ||
136 user_cfg->win_height & 0x01))
137 return -EINVAL;
138
139 if (unlikely(user_cfg->win_width < OMAP3ISP_AEWB_MIN_WIN_W ||
140 user_cfg->win_width > OMAP3ISP_AEWB_MAX_WIN_W ||
141 user_cfg->win_width & 0x01))
142 return -EINVAL;
143
144 if (unlikely(user_cfg->ver_win_count < OMAP3ISP_AEWB_MIN_WINVC ||
145 user_cfg->ver_win_count > OMAP3ISP_AEWB_MAX_WINVC))
146 return -EINVAL;
147
148 if (unlikely(user_cfg->hor_win_count < OMAP3ISP_AEWB_MIN_WINHC ||
149 user_cfg->hor_win_count > OMAP3ISP_AEWB_MAX_WINHC))
150 return -EINVAL;
151
152 if (unlikely(user_cfg->ver_win_start > OMAP3ISP_AEWB_MAX_WINSTART))
153 return -EINVAL;
154
155 if (unlikely(user_cfg->hor_win_start > OMAP3ISP_AEWB_MAX_WINSTART))
156 return -EINVAL;
157
158 if (unlikely(user_cfg->blk_ver_win_start > OMAP3ISP_AEWB_MAX_WINSTART))
159 return -EINVAL;
160
161 if (unlikely(user_cfg->blk_win_height < OMAP3ISP_AEWB_MIN_WIN_H ||
162 user_cfg->blk_win_height > OMAP3ISP_AEWB_MAX_WIN_H ||
163 user_cfg->blk_win_height & 0x01))
164 return -EINVAL;
165
166 if (unlikely(user_cfg->subsample_ver_inc < OMAP3ISP_AEWB_MIN_SUB_INC ||
167 user_cfg->subsample_ver_inc > OMAP3ISP_AEWB_MAX_SUB_INC ||
168 user_cfg->subsample_ver_inc & 0x01))
169 return -EINVAL;
170
171 if (unlikely(user_cfg->subsample_hor_inc < OMAP3ISP_AEWB_MIN_SUB_INC ||
172 user_cfg->subsample_hor_inc > OMAP3ISP_AEWB_MAX_SUB_INC ||
173 user_cfg->subsample_hor_inc & 0x01))
174 return -EINVAL;
175
176 buf_size = h3a_aewb_get_buf_size(user_cfg);
177 if (buf_size > user_cfg->buf_size)
178 user_cfg->buf_size = buf_size;
179 else if (user_cfg->buf_size > OMAP3ISP_AEWB_MAX_BUF_SIZE)
180 user_cfg->buf_size = OMAP3ISP_AEWB_MAX_BUF_SIZE;
181
182 return 0;
183}
184
185/*
186 * h3a_aewb_set_params - Helper function to check & store user given params.
187 * @new_conf: Pointer to AE and AWB parameters struct.
188 *
189 * As most of them are busy-lock registers, need to wait until AEW_BUSY = 0 to
190 * program them during ISR.
191 */
192static void h3a_aewb_set_params(struct ispstat *aewb, void *new_conf)
193{
194 struct omap3isp_h3a_aewb_config *user_cfg = new_conf;
195 struct omap3isp_h3a_aewb_config *cur_cfg = aewb->priv;
196 int update = 0;
197
198 if (cur_cfg->saturation_limit != user_cfg->saturation_limit) {
199 cur_cfg->saturation_limit = user_cfg->saturation_limit;
200 update = 1;
201 }
202 if (cur_cfg->alaw_enable != user_cfg->alaw_enable) {
203 cur_cfg->alaw_enable = user_cfg->alaw_enable;
204 update = 1;
205 }
206 if (cur_cfg->win_height != user_cfg->win_height) {
207 cur_cfg->win_height = user_cfg->win_height;
208 update = 1;
209 }
210 if (cur_cfg->win_width != user_cfg->win_width) {
211 cur_cfg->win_width = user_cfg->win_width;
212 update = 1;
213 }
214 if (cur_cfg->ver_win_count != user_cfg->ver_win_count) {
215 cur_cfg->ver_win_count = user_cfg->ver_win_count;
216 update = 1;
217 }
218 if (cur_cfg->hor_win_count != user_cfg->hor_win_count) {
219 cur_cfg->hor_win_count = user_cfg->hor_win_count;
220 update = 1;
221 }
222 if (cur_cfg->ver_win_start != user_cfg->ver_win_start) {
223 cur_cfg->ver_win_start = user_cfg->ver_win_start;
224 update = 1;
225 }
226 if (cur_cfg->hor_win_start != user_cfg->hor_win_start) {
227 cur_cfg->hor_win_start = user_cfg->hor_win_start;
228 update = 1;
229 }
230 if (cur_cfg->blk_ver_win_start != user_cfg->blk_ver_win_start) {
231 cur_cfg->blk_ver_win_start = user_cfg->blk_ver_win_start;
232 update = 1;
233 }
234 if (cur_cfg->blk_win_height != user_cfg->blk_win_height) {
235 cur_cfg->blk_win_height = user_cfg->blk_win_height;
236 update = 1;
237 }
238 if (cur_cfg->subsample_ver_inc != user_cfg->subsample_ver_inc) {
239 cur_cfg->subsample_ver_inc = user_cfg->subsample_ver_inc;
240 update = 1;
241 }
242 if (cur_cfg->subsample_hor_inc != user_cfg->subsample_hor_inc) {
243 cur_cfg->subsample_hor_inc = user_cfg->subsample_hor_inc;
244 update = 1;
245 }
246
247 if (update || !aewb->configured) {
248 aewb->inc_config++;
249 aewb->update = 1;
250 cur_cfg->buf_size = h3a_aewb_get_buf_size(cur_cfg);
251 }
252}
253
254static long h3a_aewb_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
255{
256 struct ispstat *stat = v4l2_get_subdevdata(sd);
257
258 switch (cmd) {
259 case VIDIOC_OMAP3ISP_AEWB_CFG:
260 return omap3isp_stat_config(stat, arg);
261 case VIDIOC_OMAP3ISP_STAT_REQ:
262 return omap3isp_stat_request_statistics(stat, arg);
263 case VIDIOC_OMAP3ISP_STAT_EN: {
264 unsigned long *en = arg;
265 return omap3isp_stat_enable(stat, !!*en);
266 }
267 }
268
269 return -ENOIOCTLCMD;
270}
271
272static const struct ispstat_ops h3a_aewb_ops = {
273 .validate_params = h3a_aewb_validate_params,
274 .set_params = h3a_aewb_set_params,
275 .setup_regs = h3a_aewb_setup_regs,
276 .enable = h3a_aewb_enable,
277 .busy = h3a_aewb_busy,
278};
279
280static const struct v4l2_subdev_core_ops h3a_aewb_subdev_core_ops = {
281 .ioctl = h3a_aewb_ioctl,
282 .subscribe_event = omap3isp_stat_subscribe_event,
283 .unsubscribe_event = omap3isp_stat_unsubscribe_event,
284};
285
286static const struct v4l2_subdev_video_ops h3a_aewb_subdev_video_ops = {
287 .s_stream = omap3isp_stat_s_stream,
288};
289
290static const struct v4l2_subdev_ops h3a_aewb_subdev_ops = {
291 .core = &h3a_aewb_subdev_core_ops,
292 .video = &h3a_aewb_subdev_video_ops,
293};
294
295/*
296 * omap3isp_h3a_aewb_init - Module Initialisation.
297 */
298int omap3isp_h3a_aewb_init(struct isp_device *isp)
299{
300 struct ispstat *aewb = &isp->isp_aewb;
301 struct omap3isp_h3a_aewb_config *aewb_cfg;
302 struct omap3isp_h3a_aewb_config *aewb_recover_cfg;
303 int ret;
304
305 aewb_cfg = kzalloc(sizeof(*aewb_cfg), GFP_KERNEL);
306 if (!aewb_cfg)
307 return -ENOMEM;
308
309 memset(aewb, 0, sizeof(*aewb));
310 aewb->ops = &h3a_aewb_ops;
311 aewb->priv = aewb_cfg;
312 aewb->dma_ch = -1;
313 aewb->event_type = V4L2_EVENT_OMAP3ISP_AEWB;
314 aewb->isp = isp;
315
316 /* Set recover state configuration */
317 aewb_recover_cfg = kzalloc(sizeof(*aewb_recover_cfg), GFP_KERNEL);
318 if (!aewb_recover_cfg) {
319 dev_err(aewb->isp->dev, "AEWB: cannot allocate memory for "
320 "recover configuration.\n");
321 ret = -ENOMEM;
322 goto err_recover_alloc;
323 }
324
325 aewb_recover_cfg->saturation_limit = OMAP3ISP_AEWB_MAX_SATURATION_LIM;
326 aewb_recover_cfg->win_height = OMAP3ISP_AEWB_MIN_WIN_H;
327 aewb_recover_cfg->win_width = OMAP3ISP_AEWB_MIN_WIN_W;
328 aewb_recover_cfg->ver_win_count = OMAP3ISP_AEWB_MIN_WINVC;
329 aewb_recover_cfg->hor_win_count = OMAP3ISP_AEWB_MIN_WINHC;
330 aewb_recover_cfg->blk_ver_win_start = aewb_recover_cfg->ver_win_start +
331 aewb_recover_cfg->win_height * aewb_recover_cfg->ver_win_count;
332 aewb_recover_cfg->blk_win_height = OMAP3ISP_AEWB_MIN_WIN_H;
333 aewb_recover_cfg->subsample_ver_inc = OMAP3ISP_AEWB_MIN_SUB_INC;
334 aewb_recover_cfg->subsample_hor_inc = OMAP3ISP_AEWB_MIN_SUB_INC;
335
336 if (h3a_aewb_validate_params(aewb, aewb_recover_cfg)) {
337 dev_err(aewb->isp->dev, "AEWB: recover configuration is "
338 "invalid.\n");
339 ret = -EINVAL;
340 goto err_conf;
341 }
342
343 aewb_recover_cfg->buf_size = h3a_aewb_get_buf_size(aewb_recover_cfg);
344 aewb->recover_priv = aewb_recover_cfg;
345
346 ret = omap3isp_stat_init(aewb, "AEWB", &h3a_aewb_subdev_ops);
347 if (ret)
348 goto err_conf;
349
350 return 0;
351
352err_conf:
353 kfree(aewb_recover_cfg);
354err_recover_alloc:
355 kfree(aewb_cfg);
356
357 return ret;
358}
359
360/*
361 * omap3isp_h3a_aewb_cleanup - Module exit.
362 */
363void omap3isp_h3a_aewb_cleanup(struct isp_device *isp)
364{
365 kfree(isp->isp_aewb.priv);
366 kfree(isp->isp_aewb.recover_priv);
367 omap3isp_stat_cleanup(&isp->isp_aewb);
368}
diff --git a/drivers/media/video/omap3isp/isph3a_af.c b/drivers/media/video/omap3isp/isph3a_af.c
deleted file mode 100644
index 42ccce318d5d..000000000000
--- a/drivers/media/video/omap3isp/isph3a_af.c
+++ /dev/null
@@ -1,423 +0,0 @@
1/*
2 * isph3a_af.c
3 *
4 * TI OMAP3 ISP - H3A AF module
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc.
8 *
9 * Contacts: David Cohen <dacohen@gmail.com>
10 * Laurent Pinchart <laurent.pinchart@ideasonboard.com>
11 * Sakari Ailus <sakari.ailus@iki.fi>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
25 * 02110-1301 USA
26 */
27
28/* Linux specific include files */
29#include <linux/device.h>
30#include <linux/slab.h>
31
32#include "isp.h"
33#include "isph3a.h"
34#include "ispstat.h"
35
36#define IS_OUT_OF_BOUNDS(value, min, max) \
37 (((value) < (min)) || ((value) > (max)))
38
39static void h3a_af_setup_regs(struct ispstat *af, void *priv)
40{
41 struct omap3isp_h3a_af_config *conf = priv;
42 u32 pcr;
43 u32 pax1;
44 u32 pax2;
45 u32 paxstart;
46 u32 coef;
47 u32 base_coef_set0;
48 u32 base_coef_set1;
49 int index;
50
51 if (af->state == ISPSTAT_DISABLED)
52 return;
53
54 isp_reg_writel(af->isp, af->active_buf->iommu_addr, OMAP3_ISP_IOMEM_H3A,
55 ISPH3A_AFBUFST);
56
57 if (!af->update)
58 return;
59
60 /* Configure Hardware Registers */
61 pax1 = ((conf->paxel.width >> 1) - 1) << AF_PAXW_SHIFT;
62 /* Set height in AFPAX1 */
63 pax1 |= (conf->paxel.height >> 1) - 1;
64 isp_reg_writel(af->isp, pax1, OMAP3_ISP_IOMEM_H3A, ISPH3A_AFPAX1);
65
66 /* Configure AFPAX2 Register */
67 /* Set Line Increment in AFPAX2 Register */
68 pax2 = ((conf->paxel.line_inc >> 1) - 1) << AF_LINE_INCR_SHIFT;
69 /* Set Vertical Count */
70 pax2 |= (conf->paxel.v_cnt - 1) << AF_VT_COUNT_SHIFT;
71 /* Set Horizontal Count */
72 pax2 |= (conf->paxel.h_cnt - 1);
73 isp_reg_writel(af->isp, pax2, OMAP3_ISP_IOMEM_H3A, ISPH3A_AFPAX2);
74
75 /* Configure PAXSTART Register */
76 /*Configure Horizontal Start */
77 paxstart = conf->paxel.h_start << AF_HZ_START_SHIFT;
78 /* Configure Vertical Start */
79 paxstart |= conf->paxel.v_start;
80 isp_reg_writel(af->isp, paxstart, OMAP3_ISP_IOMEM_H3A,
81 ISPH3A_AFPAXSTART);
82
83 /*SetIIRSH Register */
84 isp_reg_writel(af->isp, conf->iir.h_start,
85 OMAP3_ISP_IOMEM_H3A, ISPH3A_AFIIRSH);
86
87 base_coef_set0 = ISPH3A_AFCOEF010;
88 base_coef_set1 = ISPH3A_AFCOEF110;
89 for (index = 0; index <= 8; index += 2) {
90 /*Set IIR Filter0 Coefficients */
91 coef = 0;
92 coef |= conf->iir.coeff_set0[index];
93 coef |= conf->iir.coeff_set0[index + 1] <<
94 AF_COEF_SHIFT;
95 isp_reg_writel(af->isp, coef, OMAP3_ISP_IOMEM_H3A,
96 base_coef_set0);
97 base_coef_set0 += AFCOEF_OFFSET;
98
99 /*Set IIR Filter1 Coefficients */
100 coef = 0;
101 coef |= conf->iir.coeff_set1[index];
102 coef |= conf->iir.coeff_set1[index + 1] <<
103 AF_COEF_SHIFT;
104 isp_reg_writel(af->isp, coef, OMAP3_ISP_IOMEM_H3A,
105 base_coef_set1);
106 base_coef_set1 += AFCOEF_OFFSET;
107 }
108 /* set AFCOEF0010 Register */
109 isp_reg_writel(af->isp, conf->iir.coeff_set0[10],
110 OMAP3_ISP_IOMEM_H3A, ISPH3A_AFCOEF0010);
111 /* set AFCOEF1010 Register */
112 isp_reg_writel(af->isp, conf->iir.coeff_set1[10],
113 OMAP3_ISP_IOMEM_H3A, ISPH3A_AFCOEF1010);
114
115 /* PCR Register */
116 /* Set RGB Position */
117 pcr = conf->rgb_pos << AF_RGBPOS_SHIFT;
118 /* Set Accumulator Mode */
119 if (conf->fvmode == OMAP3ISP_AF_MODE_PEAK)
120 pcr |= AF_FVMODE;
121 /* Set A-law */
122 if (conf->alaw_enable)
123 pcr |= AF_ALAW_EN;
124 /* HMF Configurations */
125 if (conf->hmf.enable) {
126 /* Enable HMF */
127 pcr |= AF_MED_EN;
128 /* Set Median Threshold */
129 pcr |= conf->hmf.threshold << AF_MED_TH_SHIFT;
130 }
131 /* Set PCR Register */
132 isp_reg_clr_set(af->isp, OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR,
133 AF_PCR_MASK, pcr);
134
135 af->update = 0;
136 af->config_counter += af->inc_config;
137 af->inc_config = 0;
138 af->buf_size = conf->buf_size;
139}
140
141static void h3a_af_enable(struct ispstat *af, int enable)
142{
143 if (enable) {
144 isp_reg_set(af->isp, OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR,
145 ISPH3A_PCR_AF_EN);
146 omap3isp_subclk_enable(af->isp, OMAP3_ISP_SUBCLK_AF);
147 } else {
148 isp_reg_clr(af->isp, OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR,
149 ISPH3A_PCR_AF_EN);
150 omap3isp_subclk_disable(af->isp, OMAP3_ISP_SUBCLK_AF);
151 }
152}
153
154static int h3a_af_busy(struct ispstat *af)
155{
156 return isp_reg_readl(af->isp, OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR)
157 & ISPH3A_PCR_BUSYAF;
158}
159
160static u32 h3a_af_get_buf_size(struct omap3isp_h3a_af_config *conf)
161{
162 return conf->paxel.h_cnt * conf->paxel.v_cnt * OMAP3ISP_AF_PAXEL_SIZE;
163}
164
165/* Function to check paxel parameters */
166static int h3a_af_validate_params(struct ispstat *af, void *new_conf)
167{
168 struct omap3isp_h3a_af_config *user_cfg = new_conf;
169 struct omap3isp_h3a_af_paxel *paxel_cfg = &user_cfg->paxel;
170 struct omap3isp_h3a_af_iir *iir_cfg = &user_cfg->iir;
171 int index;
172 u32 buf_size;
173
174 /* Check horizontal Count */
175 if (IS_OUT_OF_BOUNDS(paxel_cfg->h_cnt,
176 OMAP3ISP_AF_PAXEL_HORIZONTAL_COUNT_MIN,
177 OMAP3ISP_AF_PAXEL_HORIZONTAL_COUNT_MAX))
178 return -EINVAL;
179
180 /* Check Vertical Count */
181 if (IS_OUT_OF_BOUNDS(paxel_cfg->v_cnt,
182 OMAP3ISP_AF_PAXEL_VERTICAL_COUNT_MIN,
183 OMAP3ISP_AF_PAXEL_VERTICAL_COUNT_MAX))
184 return -EINVAL;
185
186 if (IS_OUT_OF_BOUNDS(paxel_cfg->height, OMAP3ISP_AF_PAXEL_HEIGHT_MIN,
187 OMAP3ISP_AF_PAXEL_HEIGHT_MAX) ||
188 paxel_cfg->height % 2)
189 return -EINVAL;
190
191 /* Check width */
192 if (IS_OUT_OF_BOUNDS(paxel_cfg->width, OMAP3ISP_AF_PAXEL_WIDTH_MIN,
193 OMAP3ISP_AF_PAXEL_WIDTH_MAX) ||
194 paxel_cfg->width % 2)
195 return -EINVAL;
196
197 /* Check Line Increment */
198 if (IS_OUT_OF_BOUNDS(paxel_cfg->line_inc,
199 OMAP3ISP_AF_PAXEL_INCREMENT_MIN,
200 OMAP3ISP_AF_PAXEL_INCREMENT_MAX) ||
201 paxel_cfg->line_inc % 2)
202 return -EINVAL;
203
204 /* Check Horizontal Start */
205 if ((paxel_cfg->h_start < iir_cfg->h_start) ||
206 IS_OUT_OF_BOUNDS(paxel_cfg->h_start,
207 OMAP3ISP_AF_PAXEL_HZSTART_MIN,
208 OMAP3ISP_AF_PAXEL_HZSTART_MAX))
209 return -EINVAL;
210
211 /* Check IIR */
212 for (index = 0; index < OMAP3ISP_AF_NUM_COEF; index++) {
213 if ((iir_cfg->coeff_set0[index]) > OMAP3ISP_AF_COEF_MAX)
214 return -EINVAL;
215
216 if ((iir_cfg->coeff_set1[index]) > OMAP3ISP_AF_COEF_MAX)
217 return -EINVAL;
218 }
219
220 if (IS_OUT_OF_BOUNDS(iir_cfg->h_start, OMAP3ISP_AF_IIRSH_MIN,
221 OMAP3ISP_AF_IIRSH_MAX))
222 return -EINVAL;
223
224 /* Hack: If paxel size is 12, the 10th AF window may be corrupted */
225 if ((paxel_cfg->h_cnt * paxel_cfg->v_cnt > 9) &&
226 (paxel_cfg->width * paxel_cfg->height == 12))
227 return -EINVAL;
228
229 buf_size = h3a_af_get_buf_size(user_cfg);
230 if (buf_size > user_cfg->buf_size)
231 /* User buf_size request wasn't enough */
232 user_cfg->buf_size = buf_size;
233 else if (user_cfg->buf_size > OMAP3ISP_AF_MAX_BUF_SIZE)
234 user_cfg->buf_size = OMAP3ISP_AF_MAX_BUF_SIZE;
235
236 return 0;
237}
238
239/* Update local parameters */
240static void h3a_af_set_params(struct ispstat *af, void *new_conf)
241{
242 struct omap3isp_h3a_af_config *user_cfg = new_conf;
243 struct omap3isp_h3a_af_config *cur_cfg = af->priv;
244 int update = 0;
245 int index;
246
247 /* alaw */
248 if (cur_cfg->alaw_enable != user_cfg->alaw_enable) {
249 update = 1;
250 goto out;
251 }
252
253 /* hmf */
254 if (cur_cfg->hmf.enable != user_cfg->hmf.enable) {
255 update = 1;
256 goto out;
257 }
258 if (cur_cfg->hmf.threshold != user_cfg->hmf.threshold) {
259 update = 1;
260 goto out;
261 }
262
263 /* rgbpos */
264 if (cur_cfg->rgb_pos != user_cfg->rgb_pos) {
265 update = 1;
266 goto out;
267 }
268
269 /* iir */
270 if (cur_cfg->iir.h_start != user_cfg->iir.h_start) {
271 update = 1;
272 goto out;
273 }
274 for (index = 0; index < OMAP3ISP_AF_NUM_COEF; index++) {
275 if (cur_cfg->iir.coeff_set0[index] !=
276 user_cfg->iir.coeff_set0[index]) {
277 update = 1;
278 goto out;
279 }
280 if (cur_cfg->iir.coeff_set1[index] !=
281 user_cfg->iir.coeff_set1[index]) {
282 update = 1;
283 goto out;
284 }
285 }
286
287 /* paxel */
288 if ((cur_cfg->paxel.width != user_cfg->paxel.width) ||
289 (cur_cfg->paxel.height != user_cfg->paxel.height) ||
290 (cur_cfg->paxel.h_start != user_cfg->paxel.h_start) ||
291 (cur_cfg->paxel.v_start != user_cfg->paxel.v_start) ||
292 (cur_cfg->paxel.h_cnt != user_cfg->paxel.h_cnt) ||
293 (cur_cfg->paxel.v_cnt != user_cfg->paxel.v_cnt) ||
294 (cur_cfg->paxel.line_inc != user_cfg->paxel.line_inc)) {
295 update = 1;
296 goto out;
297 }
298
299 /* af_mode */
300 if (cur_cfg->fvmode != user_cfg->fvmode)
301 update = 1;
302
303out:
304 if (update || !af->configured) {
305 memcpy(cur_cfg, user_cfg, sizeof(*cur_cfg));
306 af->inc_config++;
307 af->update = 1;
308 /*
309 * User might be asked for a bigger buffer than necessary for
310 * this configuration. In order to return the right amount of
311 * data during buffer request, let's calculate the size here
312 * instead of stick with user_cfg->buf_size.
313 */
314 cur_cfg->buf_size = h3a_af_get_buf_size(cur_cfg);
315 }
316}
317
318static long h3a_af_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
319{
320 struct ispstat *stat = v4l2_get_subdevdata(sd);
321
322 switch (cmd) {
323 case VIDIOC_OMAP3ISP_AF_CFG:
324 return omap3isp_stat_config(stat, arg);
325 case VIDIOC_OMAP3ISP_STAT_REQ:
326 return omap3isp_stat_request_statistics(stat, arg);
327 case VIDIOC_OMAP3ISP_STAT_EN: {
328 int *en = arg;
329 return omap3isp_stat_enable(stat, !!*en);
330 }
331 }
332
333 return -ENOIOCTLCMD;
334
335}
336
337static const struct ispstat_ops h3a_af_ops = {
338 .validate_params = h3a_af_validate_params,
339 .set_params = h3a_af_set_params,
340 .setup_regs = h3a_af_setup_regs,
341 .enable = h3a_af_enable,
342 .busy = h3a_af_busy,
343};
344
345static const struct v4l2_subdev_core_ops h3a_af_subdev_core_ops = {
346 .ioctl = h3a_af_ioctl,
347 .subscribe_event = omap3isp_stat_subscribe_event,
348 .unsubscribe_event = omap3isp_stat_unsubscribe_event,
349};
350
351static const struct v4l2_subdev_video_ops h3a_af_subdev_video_ops = {
352 .s_stream = omap3isp_stat_s_stream,
353};
354
355static const struct v4l2_subdev_ops h3a_af_subdev_ops = {
356 .core = &h3a_af_subdev_core_ops,
357 .video = &h3a_af_subdev_video_ops,
358};
359
360/* Function to register the AF character device driver. */
361int omap3isp_h3a_af_init(struct isp_device *isp)
362{
363 struct ispstat *af = &isp->isp_af;
364 struct omap3isp_h3a_af_config *af_cfg;
365 struct omap3isp_h3a_af_config *af_recover_cfg;
366 int ret;
367
368 af_cfg = kzalloc(sizeof(*af_cfg), GFP_KERNEL);
369 if (af_cfg == NULL)
370 return -ENOMEM;
371
372 memset(af, 0, sizeof(*af));
373 af->ops = &h3a_af_ops;
374 af->priv = af_cfg;
375 af->dma_ch = -1;
376 af->event_type = V4L2_EVENT_OMAP3ISP_AF;
377 af->isp = isp;
378
379 /* Set recover state configuration */
380 af_recover_cfg = kzalloc(sizeof(*af_recover_cfg), GFP_KERNEL);
381 if (!af_recover_cfg) {
382 dev_err(af->isp->dev, "AF: cannot allocate memory for recover "
383 "configuration.\n");
384 ret = -ENOMEM;
385 goto err_recover_alloc;
386 }
387
388 af_recover_cfg->paxel.h_start = OMAP3ISP_AF_PAXEL_HZSTART_MIN;
389 af_recover_cfg->paxel.width = OMAP3ISP_AF_PAXEL_WIDTH_MIN;
390 af_recover_cfg->paxel.height = OMAP3ISP_AF_PAXEL_HEIGHT_MIN;
391 af_recover_cfg->paxel.h_cnt = OMAP3ISP_AF_PAXEL_HORIZONTAL_COUNT_MIN;
392 af_recover_cfg->paxel.v_cnt = OMAP3ISP_AF_PAXEL_VERTICAL_COUNT_MIN;
393 af_recover_cfg->paxel.line_inc = OMAP3ISP_AF_PAXEL_INCREMENT_MIN;
394 if (h3a_af_validate_params(af, af_recover_cfg)) {
395 dev_err(af->isp->dev, "AF: recover configuration is "
396 "invalid.\n");
397 ret = -EINVAL;
398 goto err_conf;
399 }
400
401 af_recover_cfg->buf_size = h3a_af_get_buf_size(af_recover_cfg);
402 af->recover_priv = af_recover_cfg;
403
404 ret = omap3isp_stat_init(af, "AF", &h3a_af_subdev_ops);
405 if (ret)
406 goto err_conf;
407
408 return 0;
409
410err_conf:
411 kfree(af_recover_cfg);
412err_recover_alloc:
413 kfree(af_cfg);
414
415 return ret;
416}
417
418void omap3isp_h3a_af_cleanup(struct isp_device *isp)
419{
420 kfree(isp->isp_af.priv);
421 kfree(isp->isp_af.recover_priv);
422 omap3isp_stat_cleanup(&isp->isp_af);
423}
diff --git a/drivers/media/video/omap3isp/isphist.c b/drivers/media/video/omap3isp/isphist.c
deleted file mode 100644
index d1a8dee5e1ca..000000000000
--- a/drivers/media/video/omap3isp/isphist.c
+++ /dev/null
@@ -1,518 +0,0 @@
1/*
2 * isphist.c
3 *
4 * TI OMAP3 ISP - Histogram module
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc.
8 *
9 * Contacts: David Cohen <dacohen@gmail.com>
10 * Laurent Pinchart <laurent.pinchart@ideasonboard.com>
11 * Sakari Ailus <sakari.ailus@iki.fi>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
25 * 02110-1301 USA
26 */
27
28#include <linux/delay.h>
29#include <linux/slab.h>
30#include <linux/uaccess.h>
31#include <linux/device.h>
32
33#include "isp.h"
34#include "ispreg.h"
35#include "isphist.h"
36
37#define HIST_CONFIG_DMA 1
38
39#define HIST_USING_DMA(hist) ((hist)->dma_ch >= 0)
40
41/*
42 * hist_reset_mem - clear Histogram memory before start stats engine.
43 */
44static void hist_reset_mem(struct ispstat *hist)
45{
46 struct isp_device *isp = hist->isp;
47 struct omap3isp_hist_config *conf = hist->priv;
48 unsigned int i;
49
50 isp_reg_writel(isp, 0, OMAP3_ISP_IOMEM_HIST, ISPHIST_ADDR);
51
52 /*
53 * By setting it, the histogram internal buffer is being cleared at the
54 * same time it's being read. This bit must be cleared afterwards.
55 */
56 isp_reg_set(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT, ISPHIST_CNT_CLEAR);
57
58 /*
59 * We'll clear 4 words at each iteration for optimization. It avoids
60 * 3/4 of the jumps. We also know HIST_MEM_SIZE is divisible by 4.
61 */
62 for (i = OMAP3ISP_HIST_MEM_SIZE / 4; i > 0; i--) {
63 isp_reg_readl(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_DATA);
64 isp_reg_readl(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_DATA);
65 isp_reg_readl(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_DATA);
66 isp_reg_readl(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_DATA);
67 }
68 isp_reg_clr(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT, ISPHIST_CNT_CLEAR);
69
70 hist->wait_acc_frames = conf->num_acc_frames;
71}
72
73static void hist_dma_config(struct ispstat *hist)
74{
75 hist->dma_config.data_type = OMAP_DMA_DATA_TYPE_S32;
76 hist->dma_config.sync_mode = OMAP_DMA_SYNC_ELEMENT;
77 hist->dma_config.frame_count = 1;
78 hist->dma_config.src_amode = OMAP_DMA_AMODE_CONSTANT;
79 hist->dma_config.src_start = OMAP3ISP_HIST_REG_BASE + ISPHIST_DATA;
80 hist->dma_config.dst_amode = OMAP_DMA_AMODE_POST_INC;
81 hist->dma_config.src_or_dst_synch = OMAP_DMA_SRC_SYNC;
82}
83
84/*
85 * hist_setup_regs - Helper function to update Histogram registers.
86 */
87static void hist_setup_regs(struct ispstat *hist, void *priv)
88{
89 struct isp_device *isp = hist->isp;
90 struct omap3isp_hist_config *conf = priv;
91 int c;
92 u32 cnt;
93 u32 wb_gain;
94 u32 reg_hor[OMAP3ISP_HIST_MAX_REGIONS];
95 u32 reg_ver[OMAP3ISP_HIST_MAX_REGIONS];
96
97 if (!hist->update || hist->state == ISPSTAT_DISABLED ||
98 hist->state == ISPSTAT_DISABLING)
99 return;
100
101 cnt = conf->cfa << ISPHIST_CNT_CFA_SHIFT;
102
103 wb_gain = conf->wg[0] << ISPHIST_WB_GAIN_WG00_SHIFT;
104 wb_gain |= conf->wg[1] << ISPHIST_WB_GAIN_WG01_SHIFT;
105 wb_gain |= conf->wg[2] << ISPHIST_WB_GAIN_WG02_SHIFT;
106 if (conf->cfa == OMAP3ISP_HIST_CFA_BAYER)
107 wb_gain |= conf->wg[3] << ISPHIST_WB_GAIN_WG03_SHIFT;
108
109 /* Regions size and position */
110 for (c = 0; c < OMAP3ISP_HIST_MAX_REGIONS; c++) {
111 if (c < conf->num_regions) {
112 reg_hor[c] = conf->region[c].h_start <<
113 ISPHIST_REG_START_SHIFT;
114 reg_hor[c] = conf->region[c].h_end <<
115 ISPHIST_REG_END_SHIFT;
116 reg_ver[c] = conf->region[c].v_start <<
117 ISPHIST_REG_START_SHIFT;
118 reg_ver[c] = conf->region[c].v_end <<
119 ISPHIST_REG_END_SHIFT;
120 } else {
121 reg_hor[c] = 0;
122 reg_ver[c] = 0;
123 }
124 }
125
126 cnt |= conf->hist_bins << ISPHIST_CNT_BINS_SHIFT;
127 switch (conf->hist_bins) {
128 case OMAP3ISP_HIST_BINS_256:
129 cnt |= (ISPHIST_IN_BIT_WIDTH_CCDC - 8) <<
130 ISPHIST_CNT_SHIFT_SHIFT;
131 break;
132 case OMAP3ISP_HIST_BINS_128:
133 cnt |= (ISPHIST_IN_BIT_WIDTH_CCDC - 7) <<
134 ISPHIST_CNT_SHIFT_SHIFT;
135 break;
136 case OMAP3ISP_HIST_BINS_64:
137 cnt |= (ISPHIST_IN_BIT_WIDTH_CCDC - 6) <<
138 ISPHIST_CNT_SHIFT_SHIFT;
139 break;
140 default: /* OMAP3ISP_HIST_BINS_32 */
141 cnt |= (ISPHIST_IN_BIT_WIDTH_CCDC - 5) <<
142 ISPHIST_CNT_SHIFT_SHIFT;
143 break;
144 }
145
146 hist_reset_mem(hist);
147
148 isp_reg_writel(isp, cnt, OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT);
149 isp_reg_writel(isp, wb_gain, OMAP3_ISP_IOMEM_HIST, ISPHIST_WB_GAIN);
150 isp_reg_writel(isp, reg_hor[0], OMAP3_ISP_IOMEM_HIST, ISPHIST_R0_HORZ);
151 isp_reg_writel(isp, reg_ver[0], OMAP3_ISP_IOMEM_HIST, ISPHIST_R0_VERT);
152 isp_reg_writel(isp, reg_hor[1], OMAP3_ISP_IOMEM_HIST, ISPHIST_R1_HORZ);
153 isp_reg_writel(isp, reg_ver[1], OMAP3_ISP_IOMEM_HIST, ISPHIST_R1_VERT);
154 isp_reg_writel(isp, reg_hor[2], OMAP3_ISP_IOMEM_HIST, ISPHIST_R2_HORZ);
155 isp_reg_writel(isp, reg_ver[2], OMAP3_ISP_IOMEM_HIST, ISPHIST_R2_VERT);
156 isp_reg_writel(isp, reg_hor[3], OMAP3_ISP_IOMEM_HIST, ISPHIST_R3_HORZ);
157 isp_reg_writel(isp, reg_ver[3], OMAP3_ISP_IOMEM_HIST, ISPHIST_R3_VERT);
158
159 hist->update = 0;
160 hist->config_counter += hist->inc_config;
161 hist->inc_config = 0;
162 hist->buf_size = conf->buf_size;
163}
164
165static void hist_enable(struct ispstat *hist, int enable)
166{
167 if (enable) {
168 isp_reg_set(hist->isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_PCR,
169 ISPHIST_PCR_ENABLE);
170 omap3isp_subclk_enable(hist->isp, OMAP3_ISP_SUBCLK_HIST);
171 } else {
172 isp_reg_clr(hist->isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_PCR,
173 ISPHIST_PCR_ENABLE);
174 omap3isp_subclk_disable(hist->isp, OMAP3_ISP_SUBCLK_HIST);
175 }
176}
177
178static int hist_busy(struct ispstat *hist)
179{
180 return isp_reg_readl(hist->isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_PCR)
181 & ISPHIST_PCR_BUSY;
182}
183
184static void hist_dma_cb(int lch, u16 ch_status, void *data)
185{
186 struct ispstat *hist = data;
187
188 if (ch_status & ~OMAP_DMA_BLOCK_IRQ) {
189 dev_dbg(hist->isp->dev, "hist: DMA error. status = 0x%04x\n",
190 ch_status);
191 omap_stop_dma(lch);
192 hist_reset_mem(hist);
193 atomic_set(&hist->buf_err, 1);
194 }
195 isp_reg_clr(hist->isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT,
196 ISPHIST_CNT_CLEAR);
197
198 omap3isp_stat_dma_isr(hist);
199 if (hist->state != ISPSTAT_DISABLED)
200 omap3isp_hist_dma_done(hist->isp);
201}
202
203static int hist_buf_dma(struct ispstat *hist)
204{
205 dma_addr_t dma_addr = hist->active_buf->dma_addr;
206
207 if (unlikely(!dma_addr)) {
208 dev_dbg(hist->isp->dev, "hist: invalid DMA buffer address\n");
209 hist_reset_mem(hist);
210 return STAT_NO_BUF;
211 }
212
213 isp_reg_writel(hist->isp, 0, OMAP3_ISP_IOMEM_HIST, ISPHIST_ADDR);
214 isp_reg_set(hist->isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT,
215 ISPHIST_CNT_CLEAR);
216 omap3isp_flush(hist->isp);
217 hist->dma_config.dst_start = dma_addr;
218 hist->dma_config.elem_count = hist->buf_size / sizeof(u32);
219 omap_set_dma_params(hist->dma_ch, &hist->dma_config);
220
221 omap_start_dma(hist->dma_ch);
222
223 return STAT_BUF_WAITING_DMA;
224}
225
226static int hist_buf_pio(struct ispstat *hist)
227{
228 struct isp_device *isp = hist->isp;
229 u32 *buf = hist->active_buf->virt_addr;
230 unsigned int i;
231
232 if (!buf) {
233 dev_dbg(isp->dev, "hist: invalid PIO buffer address\n");
234 hist_reset_mem(hist);
235 return STAT_NO_BUF;
236 }
237
238 isp_reg_writel(isp, 0, OMAP3_ISP_IOMEM_HIST, ISPHIST_ADDR);
239
240 /*
241 * By setting it, the histogram internal buffer is being cleared at the
242 * same time it's being read. This bit must be cleared just after all
243 * data is acquired.
244 */
245 isp_reg_set(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT, ISPHIST_CNT_CLEAR);
246
247 /*
248 * We'll read 4 times a 4-bytes-word at each iteration for
249 * optimization. It avoids 3/4 of the jumps. We also know buf_size is
250 * divisible by 16.
251 */
252 for (i = hist->buf_size / 16; i > 0; i--) {
253 *buf++ = isp_reg_readl(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_DATA);
254 *buf++ = isp_reg_readl(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_DATA);
255 *buf++ = isp_reg_readl(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_DATA);
256 *buf++ = isp_reg_readl(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_DATA);
257 }
258 isp_reg_clr(hist->isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT,
259 ISPHIST_CNT_CLEAR);
260
261 return STAT_BUF_DONE;
262}
263
264/*
265 * hist_buf_process - Callback from ISP driver for HIST interrupt.
266 */
267static int hist_buf_process(struct ispstat *hist)
268{
269 struct omap3isp_hist_config *user_cfg = hist->priv;
270 int ret;
271
272 if (atomic_read(&hist->buf_err) || hist->state != ISPSTAT_ENABLED) {
273 hist_reset_mem(hist);
274 return STAT_NO_BUF;
275 }
276
277 if (--(hist->wait_acc_frames))
278 return STAT_NO_BUF;
279
280 if (HIST_USING_DMA(hist))
281 ret = hist_buf_dma(hist);
282 else
283 ret = hist_buf_pio(hist);
284
285 hist->wait_acc_frames = user_cfg->num_acc_frames;
286
287 return ret;
288}
289
290static u32 hist_get_buf_size(struct omap3isp_hist_config *conf)
291{
292 return OMAP3ISP_HIST_MEM_SIZE_BINS(conf->hist_bins) * conf->num_regions;
293}
294
295/*
296 * hist_validate_params - Helper function to check user given params.
297 * @user_cfg: Pointer to user configuration structure.
298 *
299 * Returns 0 on success configuration.
300 */
301static int hist_validate_params(struct ispstat *hist, void *new_conf)
302{
303 struct omap3isp_hist_config *user_cfg = new_conf;
304 int c;
305 u32 buf_size;
306
307 if (user_cfg->cfa > OMAP3ISP_HIST_CFA_FOVEONX3)
308 return -EINVAL;
309
310 /* Regions size and position */
311
312 if ((user_cfg->num_regions < OMAP3ISP_HIST_MIN_REGIONS) ||
313 (user_cfg->num_regions > OMAP3ISP_HIST_MAX_REGIONS))
314 return -EINVAL;
315
316 /* Regions */
317 for (c = 0; c < user_cfg->num_regions; c++) {
318 if (user_cfg->region[c].h_start & ~ISPHIST_REG_START_END_MASK)
319 return -EINVAL;
320 if (user_cfg->region[c].h_end & ~ISPHIST_REG_START_END_MASK)
321 return -EINVAL;
322 if (user_cfg->region[c].v_start & ~ISPHIST_REG_START_END_MASK)
323 return -EINVAL;
324 if (user_cfg->region[c].v_end & ~ISPHIST_REG_START_END_MASK)
325 return -EINVAL;
326 if (user_cfg->region[c].h_start > user_cfg->region[c].h_end)
327 return -EINVAL;
328 if (user_cfg->region[c].v_start > user_cfg->region[c].v_end)
329 return -EINVAL;
330 }
331
332 switch (user_cfg->num_regions) {
333 case 1:
334 if (user_cfg->hist_bins > OMAP3ISP_HIST_BINS_256)
335 return -EINVAL;
336 break;
337 case 2:
338 if (user_cfg->hist_bins > OMAP3ISP_HIST_BINS_128)
339 return -EINVAL;
340 break;
341 default: /* 3 or 4 */
342 if (user_cfg->hist_bins > OMAP3ISP_HIST_BINS_64)
343 return -EINVAL;
344 break;
345 }
346
347 buf_size = hist_get_buf_size(user_cfg);
348 if (buf_size > user_cfg->buf_size)
349 /* User's buf_size request wasn't enoght */
350 user_cfg->buf_size = buf_size;
351 else if (user_cfg->buf_size > OMAP3ISP_HIST_MAX_BUF_SIZE)
352 user_cfg->buf_size = OMAP3ISP_HIST_MAX_BUF_SIZE;
353
354 return 0;
355}
356
357static int hist_comp_params(struct ispstat *hist,
358 struct omap3isp_hist_config *user_cfg)
359{
360 struct omap3isp_hist_config *cur_cfg = hist->priv;
361 int c;
362
363 if (cur_cfg->cfa != user_cfg->cfa)
364 return 1;
365
366 if (cur_cfg->num_acc_frames != user_cfg->num_acc_frames)
367 return 1;
368
369 if (cur_cfg->hist_bins != user_cfg->hist_bins)
370 return 1;
371
372 for (c = 0; c < OMAP3ISP_HIST_MAX_WG; c++) {
373 if (c == 3 && user_cfg->cfa == OMAP3ISP_HIST_CFA_FOVEONX3)
374 break;
375 else if (cur_cfg->wg[c] != user_cfg->wg[c])
376 return 1;
377 }
378
379 if (cur_cfg->num_regions != user_cfg->num_regions)
380 return 1;
381
382 /* Regions */
383 for (c = 0; c < user_cfg->num_regions; c++) {
384 if (cur_cfg->region[c].h_start != user_cfg->region[c].h_start)
385 return 1;
386 if (cur_cfg->region[c].h_end != user_cfg->region[c].h_end)
387 return 1;
388 if (cur_cfg->region[c].v_start != user_cfg->region[c].v_start)
389 return 1;
390 if (cur_cfg->region[c].v_end != user_cfg->region[c].v_end)
391 return 1;
392 }
393
394 return 0;
395}
396
397/*
398 * hist_update_params - Helper function to check and store user given params.
399 * @new_conf: Pointer to user configuration structure.
400 */
401static void hist_set_params(struct ispstat *hist, void *new_conf)
402{
403 struct omap3isp_hist_config *user_cfg = new_conf;
404 struct omap3isp_hist_config *cur_cfg = hist->priv;
405
406 if (!hist->configured || hist_comp_params(hist, user_cfg)) {
407 memcpy(cur_cfg, user_cfg, sizeof(*user_cfg));
408 if (user_cfg->num_acc_frames == 0)
409 user_cfg->num_acc_frames = 1;
410 hist->inc_config++;
411 hist->update = 1;
412 /*
413 * User might be asked for a bigger buffer than necessary for
414 * this configuration. In order to return the right amount of
415 * data during buffer request, let's calculate the size here
416 * instead of stick with user_cfg->buf_size.
417 */
418 cur_cfg->buf_size = hist_get_buf_size(cur_cfg);
419
420 }
421}
422
423static long hist_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
424{
425 struct ispstat *stat = v4l2_get_subdevdata(sd);
426
427 switch (cmd) {
428 case VIDIOC_OMAP3ISP_HIST_CFG:
429 return omap3isp_stat_config(stat, arg);
430 case VIDIOC_OMAP3ISP_STAT_REQ:
431 return omap3isp_stat_request_statistics(stat, arg);
432 case VIDIOC_OMAP3ISP_STAT_EN: {
433 int *en = arg;
434 return omap3isp_stat_enable(stat, !!*en);
435 }
436 }
437
438 return -ENOIOCTLCMD;
439
440}
441
442static const struct ispstat_ops hist_ops = {
443 .validate_params = hist_validate_params,
444 .set_params = hist_set_params,
445 .setup_regs = hist_setup_regs,
446 .enable = hist_enable,
447 .busy = hist_busy,
448 .buf_process = hist_buf_process,
449};
450
451static const struct v4l2_subdev_core_ops hist_subdev_core_ops = {
452 .ioctl = hist_ioctl,
453 .subscribe_event = omap3isp_stat_subscribe_event,
454 .unsubscribe_event = omap3isp_stat_unsubscribe_event,
455};
456
457static const struct v4l2_subdev_video_ops hist_subdev_video_ops = {
458 .s_stream = omap3isp_stat_s_stream,
459};
460
461static const struct v4l2_subdev_ops hist_subdev_ops = {
462 .core = &hist_subdev_core_ops,
463 .video = &hist_subdev_video_ops,
464};
465
466/*
467 * omap3isp_hist_init - Module Initialization.
468 */
469int omap3isp_hist_init(struct isp_device *isp)
470{
471 struct ispstat *hist = &isp->isp_hist;
472 struct omap3isp_hist_config *hist_cfg;
473 int ret = -1;
474
475 hist_cfg = kzalloc(sizeof(*hist_cfg), GFP_KERNEL);
476 if (hist_cfg == NULL)
477 return -ENOMEM;
478
479 memset(hist, 0, sizeof(*hist));
480 if (HIST_CONFIG_DMA)
481 ret = omap_request_dma(OMAP24XX_DMA_NO_DEVICE, "DMA_ISP_HIST",
482 hist_dma_cb, hist, &hist->dma_ch);
483 if (ret) {
484 if (HIST_CONFIG_DMA)
485 dev_warn(isp->dev, "hist: DMA request channel failed. "
486 "Using PIO only.\n");
487 hist->dma_ch = -1;
488 } else {
489 dev_dbg(isp->dev, "hist: DMA channel = %d\n", hist->dma_ch);
490 hist_dma_config(hist);
491 omap_enable_dma_irq(hist->dma_ch, OMAP_DMA_BLOCK_IRQ);
492 }
493
494 hist->ops = &hist_ops;
495 hist->priv = hist_cfg;
496 hist->event_type = V4L2_EVENT_OMAP3ISP_HIST;
497 hist->isp = isp;
498
499 ret = omap3isp_stat_init(hist, "histogram", &hist_subdev_ops);
500 if (ret) {
501 kfree(hist_cfg);
502 if (HIST_USING_DMA(hist))
503 omap_free_dma(hist->dma_ch);
504 }
505
506 return ret;
507}
508
509/*
510 * omap3isp_hist_cleanup - Module cleanup.
511 */
512void omap3isp_hist_cleanup(struct isp_device *isp)
513{
514 if (HIST_USING_DMA(&isp->isp_hist))
515 omap_free_dma(isp->isp_hist.dma_ch);
516 kfree(isp->isp_hist.priv);
517 omap3isp_stat_cleanup(&isp->isp_hist);
518}
diff --git a/drivers/media/video/omap3isp/isphist.h b/drivers/media/video/omap3isp/isphist.h
deleted file mode 100644
index 0b2a38ec94c4..000000000000
--- a/drivers/media/video/omap3isp/isphist.h
+++ /dev/null
@@ -1,40 +0,0 @@
1/*
2 * isphist.h
3 *
4 * TI OMAP3 ISP - Histogram module
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc.
8 *
9 * Contacts: David Cohen <dacohen@gmail.com>
10 * Laurent Pinchart <laurent.pinchart@ideasonboard.com>
11 * Sakari Ailus <sakari.ailus@iki.fi>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
25 * 02110-1301 USA
26 */
27
28#ifndef OMAP3_ISP_HIST_H
29#define OMAP3_ISP_HIST_H
30
31#include <linux/omap3isp.h>
32
33#define ISPHIST_IN_BIT_WIDTH_CCDC 10
34
35struct isp_device;
36
37int omap3isp_hist_init(struct isp_device *isp);
38void omap3isp_hist_cleanup(struct isp_device *isp);
39
40#endif /* OMAP3_ISP_HIST */
diff --git a/drivers/media/video/omap3isp/isppreview.c b/drivers/media/video/omap3isp/isppreview.c
deleted file mode 100644
index 1ae1c0909ed1..000000000000
--- a/drivers/media/video/omap3isp/isppreview.c
+++ /dev/null
@@ -1,2348 +0,0 @@
1/*
2 * isppreview.c
3 *
4 * TI OMAP3 ISP driver - Preview module
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc.
8 *
9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 * Sakari Ailus <sakari.ailus@iki.fi>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 */
26
27#include <linux/device.h>
28#include <linux/mm.h>
29#include <linux/module.h>
30#include <linux/mutex.h>
31#include <linux/uaccess.h>
32
33#include "isp.h"
34#include "ispreg.h"
35#include "isppreview.h"
36
37/* Default values in Office Fluorescent Light for RGBtoRGB Blending */
38static struct omap3isp_prev_rgbtorgb flr_rgb2rgb = {
39 { /* RGB-RGB Matrix */
40 {0x01E2, 0x0F30, 0x0FEE},
41 {0x0F9B, 0x01AC, 0x0FB9},
42 {0x0FE0, 0x0EC0, 0x0260}
43 }, /* RGB Offset */
44 {0x0000, 0x0000, 0x0000}
45};
46
47/* Default values in Office Fluorescent Light for RGB to YUV Conversion*/
48static struct omap3isp_prev_csc flr_prev_csc = {
49 { /* CSC Coef Matrix */
50 {66, 129, 25},
51 {-38, -75, 112},
52 {112, -94 , -18}
53 }, /* CSC Offset */
54 {0x0, 0x0, 0x0}
55};
56
57/* Default values in Office Fluorescent Light for CFA Gradient*/
58#define FLR_CFA_GRADTHRS_HORZ 0x28
59#define FLR_CFA_GRADTHRS_VERT 0x28
60
61/* Default values in Office Fluorescent Light for Chroma Suppression*/
62#define FLR_CSUP_GAIN 0x0D
63#define FLR_CSUP_THRES 0xEB
64
65/* Default values in Office Fluorescent Light for Noise Filter*/
66#define FLR_NF_STRGTH 0x03
67
68/* Default values for White Balance */
69#define FLR_WBAL_DGAIN 0x100
70#define FLR_WBAL_COEF 0x20
71
72/* Default values in Office Fluorescent Light for Black Adjustment*/
73#define FLR_BLKADJ_BLUE 0x0
74#define FLR_BLKADJ_GREEN 0x0
75#define FLR_BLKADJ_RED 0x0
76
77#define DEF_DETECT_CORRECT_VAL 0xe
78
79/*
80 * Margins and image size limits.
81 *
82 * The preview engine crops several rows and columns internally depending on
83 * which filters are enabled. To avoid format changes when the filters are
84 * enabled or disabled (which would prevent them from being turned on or off
85 * during streaming), the driver assumes all the filters are enabled when
86 * computing sink crop and source format limits.
87 *
88 * If a filter is disabled, additional cropping is automatically added at the
89 * preview engine input by the driver to avoid overflow at line and frame end.
90 * This is completely transparent for applications.
91 *
92 * Median filter 4 pixels
93 * Noise filter,
94 * Faulty pixels correction 4 pixels, 4 lines
95 * CFA filter 4 pixels, 4 lines in Bayer mode
96 * 2 lines in other modes
97 * Color suppression 2 pixels
98 * or luma enhancement
99 * -------------------------------------------------------------
100 * Maximum total 14 pixels, 8 lines
101 *
102 * The color suppression and luma enhancement filters are applied after bayer to
103 * YUV conversion. They thus can crop one pixel on the left and one pixel on the
104 * right side of the image without changing the color pattern. When both those
105 * filters are disabled, the driver must crop the two pixels on the same side of
106 * the image to avoid changing the bayer pattern. The left margin is thus set to
107 * 8 pixels and the right margin to 6 pixels.
108 */
109
110#define PREV_MARGIN_LEFT 8
111#define PREV_MARGIN_RIGHT 6
112#define PREV_MARGIN_TOP 4
113#define PREV_MARGIN_BOTTOM 4
114
115#define PREV_MIN_IN_WIDTH 64
116#define PREV_MIN_IN_HEIGHT 8
117#define PREV_MAX_IN_HEIGHT 16384
118
119#define PREV_MIN_OUT_WIDTH 0
120#define PREV_MIN_OUT_HEIGHT 0
121#define PREV_MAX_OUT_WIDTH_REV_1 1280
122#define PREV_MAX_OUT_WIDTH_REV_2 3300
123#define PREV_MAX_OUT_WIDTH_REV_15 4096
124
125/*
126 * Coeficient Tables for the submodules in Preview.
127 * Array is initialised with the values from.the tables text file.
128 */
129
130/*
131 * CFA Filter Coefficient Table
132 *
133 */
134static u32 cfa_coef_table[4][OMAP3ISP_PREV_CFA_BLK_SIZE] = {
135#include "cfa_coef_table.h"
136};
137
138/*
139 * Default Gamma Correction Table - All components
140 */
141static u32 gamma_table[] = {
142#include "gamma_table.h"
143};
144
145/*
146 * Noise Filter Threshold table
147 */
148static u32 noise_filter_table[] = {
149#include "noise_filter_table.h"
150};
151
152/*
153 * Luminance Enhancement Table
154 */
155static u32 luma_enhance_table[] = {
156#include "luma_enhance_table.h"
157};
158
159/*
160 * preview_config_luma_enhancement - Configure the Luminance Enhancement table
161 */
162static void
163preview_config_luma_enhancement(struct isp_prev_device *prev,
164 const struct prev_params *params)
165{
166 struct isp_device *isp = to_isp_device(prev);
167 const struct omap3isp_prev_luma *yt = &params->luma;
168 unsigned int i;
169
170 isp_reg_writel(isp, ISPPRV_YENH_TABLE_ADDR,
171 OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_ADDR);
172 for (i = 0; i < OMAP3ISP_PREV_YENH_TBL_SIZE; i++) {
173 isp_reg_writel(isp, yt->table[i],
174 OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_DATA);
175 }
176}
177
178/*
179 * preview_enable_luma_enhancement - Enable/disable Luminance Enhancement
180 */
181static void
182preview_enable_luma_enhancement(struct isp_prev_device *prev, bool enable)
183{
184 struct isp_device *isp = to_isp_device(prev);
185
186 if (enable)
187 isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
188 ISPPRV_PCR_YNENHEN);
189 else
190 isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
191 ISPPRV_PCR_YNENHEN);
192}
193
194/*
195 * preview_enable_invalaw - Enable/disable Inverse A-Law decompression
196 */
197static void preview_enable_invalaw(struct isp_prev_device *prev, bool enable)
198{
199 struct isp_device *isp = to_isp_device(prev);
200
201 if (enable)
202 isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
203 ISPPRV_PCR_WIDTH | ISPPRV_PCR_INVALAW);
204 else
205 isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
206 ISPPRV_PCR_WIDTH | ISPPRV_PCR_INVALAW);
207}
208
209/*
210 * preview_config_hmed - Configure the Horizontal Median Filter
211 */
212static void preview_config_hmed(struct isp_prev_device *prev,
213 const struct prev_params *params)
214{
215 struct isp_device *isp = to_isp_device(prev);
216 const struct omap3isp_prev_hmed *hmed = &params->hmed;
217
218 isp_reg_writel(isp, (hmed->odddist == 1 ? 0 : ISPPRV_HMED_ODDDIST) |
219 (hmed->evendist == 1 ? 0 : ISPPRV_HMED_EVENDIST) |
220 (hmed->thres << ISPPRV_HMED_THRESHOLD_SHIFT),
221 OMAP3_ISP_IOMEM_PREV, ISPPRV_HMED);
222}
223
224/*
225 * preview_enable_hmed - Enable/disable the Horizontal Median Filter
226 */
227static void preview_enable_hmed(struct isp_prev_device *prev, bool enable)
228{
229 struct isp_device *isp = to_isp_device(prev);
230
231 if (enable)
232 isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
233 ISPPRV_PCR_HMEDEN);
234 else
235 isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
236 ISPPRV_PCR_HMEDEN);
237}
238
239/*
240 * preview_config_cfa - Configure CFA Interpolation for Bayer formats
241 *
242 * The CFA table is organised in four blocks, one per Bayer component. The
243 * hardware expects blocks to follow the Bayer order of the input data, while
244 * the driver stores the table in GRBG order in memory. The blocks need to be
245 * reordered to support non-GRBG Bayer patterns.
246 */
247static void preview_config_cfa(struct isp_prev_device *prev,
248 const struct prev_params *params)
249{
250 static const unsigned int cfa_coef_order[4][4] = {
251 { 0, 1, 2, 3 }, /* GRBG */
252 { 1, 0, 3, 2 }, /* RGGB */
253 { 2, 3, 0, 1 }, /* BGGR */
254 { 3, 2, 1, 0 }, /* GBRG */
255 };
256 const unsigned int *order = cfa_coef_order[prev->params.cfa_order];
257 const struct omap3isp_prev_cfa *cfa = &params->cfa;
258 struct isp_device *isp = to_isp_device(prev);
259 unsigned int i;
260 unsigned int j;
261
262 isp_reg_writel(isp,
263 (cfa->gradthrs_vert << ISPPRV_CFA_GRADTH_VER_SHIFT) |
264 (cfa->gradthrs_horz << ISPPRV_CFA_GRADTH_HOR_SHIFT),
265 OMAP3_ISP_IOMEM_PREV, ISPPRV_CFA);
266
267 isp_reg_writel(isp, ISPPRV_CFA_TABLE_ADDR,
268 OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_ADDR);
269
270 for (i = 0; i < 4; ++i) {
271 const __u32 *block = cfa->table[order[i]];
272
273 for (j = 0; j < OMAP3ISP_PREV_CFA_BLK_SIZE; ++j)
274 isp_reg_writel(isp, block[j], OMAP3_ISP_IOMEM_PREV,
275 ISPPRV_SET_TBL_DATA);
276 }
277}
278
279/*
280 * preview_config_chroma_suppression - Configure Chroma Suppression
281 */
282static void
283preview_config_chroma_suppression(struct isp_prev_device *prev,
284 const struct prev_params *params)
285{
286 struct isp_device *isp = to_isp_device(prev);
287 const struct omap3isp_prev_csup *cs = &params->csup;
288
289 isp_reg_writel(isp,
290 cs->gain | (cs->thres << ISPPRV_CSUP_THRES_SHIFT) |
291 (cs->hypf_en << ISPPRV_CSUP_HPYF_SHIFT),
292 OMAP3_ISP_IOMEM_PREV, ISPPRV_CSUP);
293}
294
295/*
296 * preview_enable_chroma_suppression - Enable/disable Chrominance Suppression
297 */
298static void
299preview_enable_chroma_suppression(struct isp_prev_device *prev, bool enable)
300{
301 struct isp_device *isp = to_isp_device(prev);
302
303 if (enable)
304 isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
305 ISPPRV_PCR_SUPEN);
306 else
307 isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
308 ISPPRV_PCR_SUPEN);
309}
310
311/*
312 * preview_config_whitebalance - Configure White Balance parameters
313 *
314 * Coefficient matrix always with default values.
315 */
316static void
317preview_config_whitebalance(struct isp_prev_device *prev,
318 const struct prev_params *params)
319{
320 struct isp_device *isp = to_isp_device(prev);
321 const struct omap3isp_prev_wbal *wbal = &params->wbal;
322 u32 val;
323
324 isp_reg_writel(isp, wbal->dgain, OMAP3_ISP_IOMEM_PREV, ISPPRV_WB_DGAIN);
325
326 val = wbal->coef0 << ISPPRV_WBGAIN_COEF0_SHIFT;
327 val |= wbal->coef1 << ISPPRV_WBGAIN_COEF1_SHIFT;
328 val |= wbal->coef2 << ISPPRV_WBGAIN_COEF2_SHIFT;
329 val |= wbal->coef3 << ISPPRV_WBGAIN_COEF3_SHIFT;
330 isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_PREV, ISPPRV_WBGAIN);
331
332 isp_reg_writel(isp,
333 ISPPRV_WBSEL_COEF0 << ISPPRV_WBSEL_N0_0_SHIFT |
334 ISPPRV_WBSEL_COEF1 << ISPPRV_WBSEL_N0_1_SHIFT |
335 ISPPRV_WBSEL_COEF0 << ISPPRV_WBSEL_N0_2_SHIFT |
336 ISPPRV_WBSEL_COEF1 << ISPPRV_WBSEL_N0_3_SHIFT |
337 ISPPRV_WBSEL_COEF2 << ISPPRV_WBSEL_N1_0_SHIFT |
338 ISPPRV_WBSEL_COEF3 << ISPPRV_WBSEL_N1_1_SHIFT |
339 ISPPRV_WBSEL_COEF2 << ISPPRV_WBSEL_N1_2_SHIFT |
340 ISPPRV_WBSEL_COEF3 << ISPPRV_WBSEL_N1_3_SHIFT |
341 ISPPRV_WBSEL_COEF0 << ISPPRV_WBSEL_N2_0_SHIFT |
342 ISPPRV_WBSEL_COEF1 << ISPPRV_WBSEL_N2_1_SHIFT |
343 ISPPRV_WBSEL_COEF0 << ISPPRV_WBSEL_N2_2_SHIFT |
344 ISPPRV_WBSEL_COEF1 << ISPPRV_WBSEL_N2_3_SHIFT |
345 ISPPRV_WBSEL_COEF2 << ISPPRV_WBSEL_N3_0_SHIFT |
346 ISPPRV_WBSEL_COEF3 << ISPPRV_WBSEL_N3_1_SHIFT |
347 ISPPRV_WBSEL_COEF2 << ISPPRV_WBSEL_N3_2_SHIFT |
348 ISPPRV_WBSEL_COEF3 << ISPPRV_WBSEL_N3_3_SHIFT,
349 OMAP3_ISP_IOMEM_PREV, ISPPRV_WBSEL);
350}
351
352/*
353 * preview_config_blkadj - Configure Black Adjustment
354 */
355static void
356preview_config_blkadj(struct isp_prev_device *prev,
357 const struct prev_params *params)
358{
359 struct isp_device *isp = to_isp_device(prev);
360 const struct omap3isp_prev_blkadj *blkadj = &params->blkadj;
361
362 isp_reg_writel(isp, (blkadj->blue << ISPPRV_BLKADJOFF_B_SHIFT) |
363 (blkadj->green << ISPPRV_BLKADJOFF_G_SHIFT) |
364 (blkadj->red << ISPPRV_BLKADJOFF_R_SHIFT),
365 OMAP3_ISP_IOMEM_PREV, ISPPRV_BLKADJOFF);
366}
367
368/*
369 * preview_config_rgb_blending - Configure RGB-RGB Blending
370 */
371static void
372preview_config_rgb_blending(struct isp_prev_device *prev,
373 const struct prev_params *params)
374{
375 struct isp_device *isp = to_isp_device(prev);
376 const struct omap3isp_prev_rgbtorgb *rgbrgb = &params->rgb2rgb;
377 u32 val;
378
379 val = (rgbrgb->matrix[0][0] & 0xfff) << ISPPRV_RGB_MAT1_MTX_RR_SHIFT;
380 val |= (rgbrgb->matrix[0][1] & 0xfff) << ISPPRV_RGB_MAT1_MTX_GR_SHIFT;
381 isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_PREV, ISPPRV_RGB_MAT1);
382
383 val = (rgbrgb->matrix[0][2] & 0xfff) << ISPPRV_RGB_MAT2_MTX_BR_SHIFT;
384 val |= (rgbrgb->matrix[1][0] & 0xfff) << ISPPRV_RGB_MAT2_MTX_RG_SHIFT;
385 isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_PREV, ISPPRV_RGB_MAT2);
386
387 val = (rgbrgb->matrix[1][1] & 0xfff) << ISPPRV_RGB_MAT3_MTX_GG_SHIFT;
388 val |= (rgbrgb->matrix[1][2] & 0xfff) << ISPPRV_RGB_MAT3_MTX_BG_SHIFT;
389 isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_PREV, ISPPRV_RGB_MAT3);
390
391 val = (rgbrgb->matrix[2][0] & 0xfff) << ISPPRV_RGB_MAT4_MTX_RB_SHIFT;
392 val |= (rgbrgb->matrix[2][1] & 0xfff) << ISPPRV_RGB_MAT4_MTX_GB_SHIFT;
393 isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_PREV, ISPPRV_RGB_MAT4);
394
395 val = (rgbrgb->matrix[2][2] & 0xfff) << ISPPRV_RGB_MAT5_MTX_BB_SHIFT;
396 isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_PREV, ISPPRV_RGB_MAT5);
397
398 val = (rgbrgb->offset[0] & 0x3ff) << ISPPRV_RGB_OFF1_MTX_OFFR_SHIFT;
399 val |= (rgbrgb->offset[1] & 0x3ff) << ISPPRV_RGB_OFF1_MTX_OFFG_SHIFT;
400 isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_PREV, ISPPRV_RGB_OFF1);
401
402 val = (rgbrgb->offset[2] & 0x3ff) << ISPPRV_RGB_OFF2_MTX_OFFB_SHIFT;
403 isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_PREV, ISPPRV_RGB_OFF2);
404}
405
406/*
407 * preview_config_csc - Configure Color Space Conversion (RGB to YCbYCr)
408 */
409static void
410preview_config_csc(struct isp_prev_device *prev,
411 const struct prev_params *params)
412{
413 struct isp_device *isp = to_isp_device(prev);
414 const struct omap3isp_prev_csc *csc = &params->csc;
415 u32 val;
416
417 val = (csc->matrix[0][0] & 0x3ff) << ISPPRV_CSC0_RY_SHIFT;
418 val |= (csc->matrix[0][1] & 0x3ff) << ISPPRV_CSC0_GY_SHIFT;
419 val |= (csc->matrix[0][2] & 0x3ff) << ISPPRV_CSC0_BY_SHIFT;
420 isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_PREV, ISPPRV_CSC0);
421
422 val = (csc->matrix[1][0] & 0x3ff) << ISPPRV_CSC1_RCB_SHIFT;
423 val |= (csc->matrix[1][1] & 0x3ff) << ISPPRV_CSC1_GCB_SHIFT;
424 val |= (csc->matrix[1][2] & 0x3ff) << ISPPRV_CSC1_BCB_SHIFT;
425 isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_PREV, ISPPRV_CSC1);
426
427 val = (csc->matrix[2][0] & 0x3ff) << ISPPRV_CSC2_RCR_SHIFT;
428 val |= (csc->matrix[2][1] & 0x3ff) << ISPPRV_CSC2_GCR_SHIFT;
429 val |= (csc->matrix[2][2] & 0x3ff) << ISPPRV_CSC2_BCR_SHIFT;
430 isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_PREV, ISPPRV_CSC2);
431
432 val = (csc->offset[0] & 0xff) << ISPPRV_CSC_OFFSET_Y_SHIFT;
433 val |= (csc->offset[1] & 0xff) << ISPPRV_CSC_OFFSET_CB_SHIFT;
434 val |= (csc->offset[2] & 0xff) << ISPPRV_CSC_OFFSET_CR_SHIFT;
435 isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_PREV, ISPPRV_CSC_OFFSET);
436}
437
438/*
439 * preview_config_yc_range - Configure the max and min Y and C values
440 */
441static void
442preview_config_yc_range(struct isp_prev_device *prev,
443 const struct prev_params *params)
444{
445 struct isp_device *isp = to_isp_device(prev);
446 const struct omap3isp_prev_yclimit *yc = &params->yclimit;
447
448 isp_reg_writel(isp,
449 yc->maxC << ISPPRV_SETUP_YC_MAXC_SHIFT |
450 yc->maxY << ISPPRV_SETUP_YC_MAXY_SHIFT |
451 yc->minC << ISPPRV_SETUP_YC_MINC_SHIFT |
452 yc->minY << ISPPRV_SETUP_YC_MINY_SHIFT,
453 OMAP3_ISP_IOMEM_PREV, ISPPRV_SETUP_YC);
454}
455
456/*
457 * preview_config_dcor - Configure Couplet Defect Correction
458 */
459static void
460preview_config_dcor(struct isp_prev_device *prev,
461 const struct prev_params *params)
462{
463 struct isp_device *isp = to_isp_device(prev);
464 const struct omap3isp_prev_dcor *dcor = &params->dcor;
465
466 isp_reg_writel(isp, dcor->detect_correct[0],
467 OMAP3_ISP_IOMEM_PREV, ISPPRV_CDC_THR0);
468 isp_reg_writel(isp, dcor->detect_correct[1],
469 OMAP3_ISP_IOMEM_PREV, ISPPRV_CDC_THR1);
470 isp_reg_writel(isp, dcor->detect_correct[2],
471 OMAP3_ISP_IOMEM_PREV, ISPPRV_CDC_THR2);
472 isp_reg_writel(isp, dcor->detect_correct[3],
473 OMAP3_ISP_IOMEM_PREV, ISPPRV_CDC_THR3);
474 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
475 ISPPRV_PCR_DCCOUP,
476 dcor->couplet_mode_en ? ISPPRV_PCR_DCCOUP : 0);
477}
478
479/*
480 * preview_enable_dcor - Enable/disable Couplet Defect Correction
481 */
482static void preview_enable_dcor(struct isp_prev_device *prev, bool enable)
483{
484 struct isp_device *isp = to_isp_device(prev);
485
486 if (enable)
487 isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
488 ISPPRV_PCR_DCOREN);
489 else
490 isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
491 ISPPRV_PCR_DCOREN);
492}
493
494/*
495 * preview_enable_drkframe_capture - Enable/disable Dark Frame Capture
496 */
497static void
498preview_enable_drkframe_capture(struct isp_prev_device *prev, bool enable)
499{
500 struct isp_device *isp = to_isp_device(prev);
501
502 if (enable)
503 isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
504 ISPPRV_PCR_DRKFCAP);
505 else
506 isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
507 ISPPRV_PCR_DRKFCAP);
508}
509
510/*
511 * preview_enable_drkframe - Enable/disable Dark Frame Subtraction
512 */
513static void preview_enable_drkframe(struct isp_prev_device *prev, bool enable)
514{
515 struct isp_device *isp = to_isp_device(prev);
516
517 if (enable)
518 isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
519 ISPPRV_PCR_DRKFEN);
520 else
521 isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
522 ISPPRV_PCR_DRKFEN);
523}
524
525/*
526 * preview_config_noisefilter - Configure the Noise Filter
527 */
528static void
529preview_config_noisefilter(struct isp_prev_device *prev,
530 const struct prev_params *params)
531{
532 struct isp_device *isp = to_isp_device(prev);
533 const struct omap3isp_prev_nf *nf = &params->nf;
534 unsigned int i;
535
536 isp_reg_writel(isp, nf->spread, OMAP3_ISP_IOMEM_PREV, ISPPRV_NF);
537 isp_reg_writel(isp, ISPPRV_NF_TABLE_ADDR,
538 OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_ADDR);
539 for (i = 0; i < OMAP3ISP_PREV_NF_TBL_SIZE; i++) {
540 isp_reg_writel(isp, nf->table[i],
541 OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_DATA);
542 }
543}
544
545/*
546 * preview_enable_noisefilter - Enable/disable the Noise Filter
547 */
548static void
549preview_enable_noisefilter(struct isp_prev_device *prev, bool enable)
550{
551 struct isp_device *isp = to_isp_device(prev);
552
553 if (enable)
554 isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
555 ISPPRV_PCR_NFEN);
556 else
557 isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
558 ISPPRV_PCR_NFEN);
559}
560
561/*
562 * preview_config_gammacorrn - Configure the Gamma Correction tables
563 */
564static void
565preview_config_gammacorrn(struct isp_prev_device *prev,
566 const struct prev_params *params)
567{
568 struct isp_device *isp = to_isp_device(prev);
569 const struct omap3isp_prev_gtables *gt = &params->gamma;
570 unsigned int i;
571
572 isp_reg_writel(isp, ISPPRV_REDGAMMA_TABLE_ADDR,
573 OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_ADDR);
574 for (i = 0; i < OMAP3ISP_PREV_GAMMA_TBL_SIZE; i++)
575 isp_reg_writel(isp, gt->red[i], OMAP3_ISP_IOMEM_PREV,
576 ISPPRV_SET_TBL_DATA);
577
578 isp_reg_writel(isp, ISPPRV_GREENGAMMA_TABLE_ADDR,
579 OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_ADDR);
580 for (i = 0; i < OMAP3ISP_PREV_GAMMA_TBL_SIZE; i++)
581 isp_reg_writel(isp, gt->green[i], OMAP3_ISP_IOMEM_PREV,
582 ISPPRV_SET_TBL_DATA);
583
584 isp_reg_writel(isp, ISPPRV_BLUEGAMMA_TABLE_ADDR,
585 OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_ADDR);
586 for (i = 0; i < OMAP3ISP_PREV_GAMMA_TBL_SIZE; i++)
587 isp_reg_writel(isp, gt->blue[i], OMAP3_ISP_IOMEM_PREV,
588 ISPPRV_SET_TBL_DATA);
589}
590
591/*
592 * preview_enable_gammacorrn - Enable/disable Gamma Correction
593 *
594 * When gamma correction is disabled, the module is bypassed and its output is
595 * the 8 MSB of the 10-bit input .
596 */
597static void
598preview_enable_gammacorrn(struct isp_prev_device *prev, bool enable)
599{
600 struct isp_device *isp = to_isp_device(prev);
601
602 if (enable)
603 isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
604 ISPPRV_PCR_GAMMA_BYPASS);
605 else
606 isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
607 ISPPRV_PCR_GAMMA_BYPASS);
608}
609
610/*
611 * preview_config_contrast - Configure the Contrast
612 *
613 * Value should be programmed before enabling the module.
614 */
615static void
616preview_config_contrast(struct isp_prev_device *prev,
617 const struct prev_params *params)
618{
619 struct isp_device *isp = to_isp_device(prev);
620
621 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_CNT_BRT,
622 0xff << ISPPRV_CNT_BRT_CNT_SHIFT,
623 params->contrast << ISPPRV_CNT_BRT_CNT_SHIFT);
624}
625
626/*
627 * preview_config_brightness - Configure the Brightness
628 */
629static void
630preview_config_brightness(struct isp_prev_device *prev,
631 const struct prev_params *params)
632{
633 struct isp_device *isp = to_isp_device(prev);
634
635 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_CNT_BRT,
636 0xff << ISPPRV_CNT_BRT_BRT_SHIFT,
637 params->brightness << ISPPRV_CNT_BRT_BRT_SHIFT);
638}
639
640/*
641 * preview_update_contrast - Updates the contrast.
642 * @contrast: Pointer to hold the current programmed contrast value.
643 *
644 * Value should be programmed before enabling the module.
645 */
646static void
647preview_update_contrast(struct isp_prev_device *prev, u8 contrast)
648{
649 struct prev_params *params;
650 unsigned long flags;
651
652 spin_lock_irqsave(&prev->params.lock, flags);
653 params = (prev->params.active & OMAP3ISP_PREV_CONTRAST)
654 ? &prev->params.params[0] : &prev->params.params[1];
655
656 if (params->contrast != (contrast * ISPPRV_CONTRAST_UNITS)) {
657 params->contrast = contrast * ISPPRV_CONTRAST_UNITS;
658 params->update |= OMAP3ISP_PREV_CONTRAST;
659 }
660 spin_unlock_irqrestore(&prev->params.lock, flags);
661}
662
663/*
664 * preview_update_brightness - Updates the brightness in preview module.
665 * @brightness: Pointer to hold the current programmed brightness value.
666 *
667 */
668static void
669preview_update_brightness(struct isp_prev_device *prev, u8 brightness)
670{
671 struct prev_params *params;
672 unsigned long flags;
673
674 spin_lock_irqsave(&prev->params.lock, flags);
675 params = (prev->params.active & OMAP3ISP_PREV_BRIGHTNESS)
676 ? &prev->params.params[0] : &prev->params.params[1];
677
678 if (params->brightness != (brightness * ISPPRV_BRIGHT_UNITS)) {
679 params->brightness = brightness * ISPPRV_BRIGHT_UNITS;
680 params->update |= OMAP3ISP_PREV_BRIGHTNESS;
681 }
682 spin_unlock_irqrestore(&prev->params.lock, flags);
683}
684
685static u32
686preview_params_lock(struct isp_prev_device *prev, u32 update, bool shadow)
687{
688 u32 active = prev->params.active;
689
690 if (shadow) {
691 /* Mark all shadow parameters we are going to touch as busy. */
692 prev->params.params[0].busy |= ~active & update;
693 prev->params.params[1].busy |= active & update;
694 } else {
695 /* Mark all active parameters we are going to touch as busy. */
696 update = (prev->params.params[0].update & active)
697 | (prev->params.params[1].update & ~active);
698
699 prev->params.params[0].busy |= active & update;
700 prev->params.params[1].busy |= ~active & update;
701 }
702
703 return update;
704}
705
706static void
707preview_params_unlock(struct isp_prev_device *prev, u32 update, bool shadow)
708{
709 u32 active = prev->params.active;
710
711 if (shadow) {
712 /* Set the update flag for shadow parameters that have been
713 * updated and clear the busy flag for all shadow parameters.
714 */
715 prev->params.params[0].update |= (~active & update);
716 prev->params.params[1].update |= (active & update);
717 prev->params.params[0].busy &= active;
718 prev->params.params[1].busy &= ~active;
719 } else {
720 /* Clear the update flag for active parameters that have been
721 * applied and the busy flag for all active parameters.
722 */
723 prev->params.params[0].update &= ~(active & update);
724 prev->params.params[1].update &= ~(~active & update);
725 prev->params.params[0].busy &= ~active;
726 prev->params.params[1].busy &= active;
727 }
728}
729
730static void preview_params_switch(struct isp_prev_device *prev)
731{
732 u32 to_switch;
733
734 /* Switch active parameters with updated shadow parameters when the
735 * shadow parameter has been updated and neither the active not the
736 * shadow parameter is busy.
737 */
738 to_switch = (prev->params.params[0].update & ~prev->params.active)
739 | (prev->params.params[1].update & prev->params.active);
740 to_switch &= ~(prev->params.params[0].busy |
741 prev->params.params[1].busy);
742 if (to_switch == 0)
743 return;
744
745 prev->params.active ^= to_switch;
746
747 /* Remove the update flag for the shadow copy of parameters we have
748 * switched.
749 */
750 prev->params.params[0].update &= ~(~prev->params.active & to_switch);
751 prev->params.params[1].update &= ~(prev->params.active & to_switch);
752}
753
754/* preview parameters update structure */
755struct preview_update {
756 void (*config)(struct isp_prev_device *, const struct prev_params *);
757 void (*enable)(struct isp_prev_device *, bool);
758 unsigned int param_offset;
759 unsigned int param_size;
760 unsigned int config_offset;
761 bool skip;
762};
763
764/* Keep the array indexed by the OMAP3ISP_PREV_* bit number. */
765static const struct preview_update update_attrs[] = {
766 /* OMAP3ISP_PREV_LUMAENH */ {
767 preview_config_luma_enhancement,
768 preview_enable_luma_enhancement,
769 offsetof(struct prev_params, luma),
770 FIELD_SIZEOF(struct prev_params, luma),
771 offsetof(struct omap3isp_prev_update_config, luma),
772 }, /* OMAP3ISP_PREV_INVALAW */ {
773 NULL,
774 preview_enable_invalaw,
775 }, /* OMAP3ISP_PREV_HRZ_MED */ {
776 preview_config_hmed,
777 preview_enable_hmed,
778 offsetof(struct prev_params, hmed),
779 FIELD_SIZEOF(struct prev_params, hmed),
780 offsetof(struct omap3isp_prev_update_config, hmed),
781 }, /* OMAP3ISP_PREV_CFA */ {
782 preview_config_cfa,
783 NULL,
784 offsetof(struct prev_params, cfa),
785 FIELD_SIZEOF(struct prev_params, cfa),
786 offsetof(struct omap3isp_prev_update_config, cfa),
787 }, /* OMAP3ISP_PREV_CHROMA_SUPP */ {
788 preview_config_chroma_suppression,
789 preview_enable_chroma_suppression,
790 offsetof(struct prev_params, csup),
791 FIELD_SIZEOF(struct prev_params, csup),
792 offsetof(struct omap3isp_prev_update_config, csup),
793 }, /* OMAP3ISP_PREV_WB */ {
794 preview_config_whitebalance,
795 NULL,
796 offsetof(struct prev_params, wbal),
797 FIELD_SIZEOF(struct prev_params, wbal),
798 offsetof(struct omap3isp_prev_update_config, wbal),
799 }, /* OMAP3ISP_PREV_BLKADJ */ {
800 preview_config_blkadj,
801 NULL,
802 offsetof(struct prev_params, blkadj),
803 FIELD_SIZEOF(struct prev_params, blkadj),
804 offsetof(struct omap3isp_prev_update_config, blkadj),
805 }, /* OMAP3ISP_PREV_RGB2RGB */ {
806 preview_config_rgb_blending,
807 NULL,
808 offsetof(struct prev_params, rgb2rgb),
809 FIELD_SIZEOF(struct prev_params, rgb2rgb),
810 offsetof(struct omap3isp_prev_update_config, rgb2rgb),
811 }, /* OMAP3ISP_PREV_COLOR_CONV */ {
812 preview_config_csc,
813 NULL,
814 offsetof(struct prev_params, csc),
815 FIELD_SIZEOF(struct prev_params, csc),
816 offsetof(struct omap3isp_prev_update_config, csc),
817 }, /* OMAP3ISP_PREV_YC_LIMIT */ {
818 preview_config_yc_range,
819 NULL,
820 offsetof(struct prev_params, yclimit),
821 FIELD_SIZEOF(struct prev_params, yclimit),
822 offsetof(struct omap3isp_prev_update_config, yclimit),
823 }, /* OMAP3ISP_PREV_DEFECT_COR */ {
824 preview_config_dcor,
825 preview_enable_dcor,
826 offsetof(struct prev_params, dcor),
827 FIELD_SIZEOF(struct prev_params, dcor),
828 offsetof(struct omap3isp_prev_update_config, dcor),
829 }, /* Previously OMAP3ISP_PREV_GAMMABYPASS, not used anymore */ {
830 NULL,
831 NULL,
832 }, /* OMAP3ISP_PREV_DRK_FRM_CAPTURE */ {
833 NULL,
834 preview_enable_drkframe_capture,
835 }, /* OMAP3ISP_PREV_DRK_FRM_SUBTRACT */ {
836 NULL,
837 preview_enable_drkframe,
838 }, /* OMAP3ISP_PREV_LENS_SHADING */ {
839 NULL,
840 preview_enable_drkframe,
841 }, /* OMAP3ISP_PREV_NF */ {
842 preview_config_noisefilter,
843 preview_enable_noisefilter,
844 offsetof(struct prev_params, nf),
845 FIELD_SIZEOF(struct prev_params, nf),
846 offsetof(struct omap3isp_prev_update_config, nf),
847 }, /* OMAP3ISP_PREV_GAMMA */ {
848 preview_config_gammacorrn,
849 preview_enable_gammacorrn,
850 offsetof(struct prev_params, gamma),
851 FIELD_SIZEOF(struct prev_params, gamma),
852 offsetof(struct omap3isp_prev_update_config, gamma),
853 }, /* OMAP3ISP_PREV_CONTRAST */ {
854 preview_config_contrast,
855 NULL,
856 0, 0, 0, true,
857 }, /* OMAP3ISP_PREV_BRIGHTNESS */ {
858 preview_config_brightness,
859 NULL,
860 0, 0, 0, true,
861 },
862};
863
864/*
865 * preview_config - Copy and update local structure with userspace preview
866 * configuration.
867 * @prev: ISP preview engine
868 * @cfg: Configuration
869 *
870 * Return zero if success or -EFAULT if the configuration can't be copied from
871 * userspace.
872 */
873static int preview_config(struct isp_prev_device *prev,
874 struct omap3isp_prev_update_config *cfg)
875{
876 unsigned long flags;
877 unsigned int i;
878 int rval = 0;
879 u32 update;
880 u32 active;
881
882 if (cfg->update == 0)
883 return 0;
884
885 /* Mark the shadow parameters we're going to update as busy. */
886 spin_lock_irqsave(&prev->params.lock, flags);
887 preview_params_lock(prev, cfg->update, true);
888 active = prev->params.active;
889 spin_unlock_irqrestore(&prev->params.lock, flags);
890
891 update = 0;
892
893 for (i = 0; i < ARRAY_SIZE(update_attrs); i++) {
894 const struct preview_update *attr = &update_attrs[i];
895 struct prev_params *params;
896 unsigned int bit = 1 << i;
897
898 if (attr->skip || !(cfg->update & bit))
899 continue;
900
901 params = &prev->params.params[!!(active & bit)];
902
903 if (cfg->flag & bit) {
904 void __user *from = *(void * __user *)
905 ((void *)cfg + attr->config_offset);
906 void *to = (void *)params + attr->param_offset;
907 size_t size = attr->param_size;
908
909 if (to && from && size) {
910 if (copy_from_user(to, from, size)) {
911 rval = -EFAULT;
912 break;
913 }
914 }
915 params->features |= bit;
916 } else {
917 params->features &= ~bit;
918 }
919
920 update |= bit;
921 }
922
923 spin_lock_irqsave(&prev->params.lock, flags);
924 preview_params_unlock(prev, update, true);
925 preview_params_switch(prev);
926 spin_unlock_irqrestore(&prev->params.lock, flags);
927
928 return rval;
929}
930
931/*
932 * preview_setup_hw - Setup preview registers and/or internal memory
933 * @prev: pointer to preview private structure
934 * @update: Bitmask of parameters to setup
935 * @active: Bitmask of parameters active in set 0
936 * Note: can be called from interrupt context
937 * Return none
938 */
939static void preview_setup_hw(struct isp_prev_device *prev, u32 update,
940 u32 active)
941{
942 unsigned int i;
943 u32 features;
944
945 if (update == 0)
946 return;
947
948 features = (prev->params.params[0].features & active)
949 | (prev->params.params[1].features & ~active);
950
951 for (i = 0; i < ARRAY_SIZE(update_attrs); i++) {
952 const struct preview_update *attr = &update_attrs[i];
953 struct prev_params *params;
954 unsigned int bit = 1 << i;
955
956 if (!(update & bit))
957 continue;
958
959 params = &prev->params.params[!(active & bit)];
960
961 if (params->features & bit) {
962 if (attr->config)
963 attr->config(prev, params);
964 if (attr->enable)
965 attr->enable(prev, true);
966 } else {
967 if (attr->enable)
968 attr->enable(prev, false);
969 }
970 }
971}
972
973/*
974 * preview_config_ycpos - Configure byte layout of YUV image.
975 * @mode: Indicates the required byte layout.
976 */
977static void
978preview_config_ycpos(struct isp_prev_device *prev,
979 enum v4l2_mbus_pixelcode pixelcode)
980{
981 struct isp_device *isp = to_isp_device(prev);
982 enum preview_ycpos_mode mode;
983
984 switch (pixelcode) {
985 case V4L2_MBUS_FMT_YUYV8_1X16:
986 mode = YCPOS_CrYCbY;
987 break;
988 case V4L2_MBUS_FMT_UYVY8_1X16:
989 mode = YCPOS_YCrYCb;
990 break;
991 default:
992 return;
993 }
994
995 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
996 ISPPRV_PCR_YCPOS_CrYCbY,
997 mode << ISPPRV_PCR_YCPOS_SHIFT);
998}
999
1000/*
1001 * preview_config_averager - Enable / disable / configure averager
1002 * @average: Average value to be configured.
1003 */
1004static void preview_config_averager(struct isp_prev_device *prev, u8 average)
1005{
1006 struct isp_device *isp = to_isp_device(prev);
1007
1008 isp_reg_writel(isp, ISPPRV_AVE_EVENDIST_2 << ISPPRV_AVE_EVENDIST_SHIFT |
1009 ISPPRV_AVE_ODDDIST_2 << ISPPRV_AVE_ODDDIST_SHIFT |
1010 average, OMAP3_ISP_IOMEM_PREV, ISPPRV_AVE);
1011}
1012
1013
1014/*
1015 * preview_config_input_format - Configure the input format
1016 * @prev: The preview engine
1017 * @format: Format on the preview engine sink pad
1018 *
1019 * Enable and configure CFA interpolation for Bayer formats and disable it for
1020 * greyscale formats.
1021 *
1022 * The CFA table is organised in four blocks, one per Bayer component. The
1023 * hardware expects blocks to follow the Bayer order of the input data, while
1024 * the driver stores the table in GRBG order in memory. The blocks need to be
1025 * reordered to support non-GRBG Bayer patterns.
1026 */
1027static void preview_config_input_format(struct isp_prev_device *prev,
1028 const struct v4l2_mbus_framefmt *format)
1029{
1030 struct isp_device *isp = to_isp_device(prev);
1031 struct prev_params *params;
1032
1033 switch (format->code) {
1034 case V4L2_MBUS_FMT_SGRBG10_1X10:
1035 prev->params.cfa_order = 0;
1036 break;
1037 case V4L2_MBUS_FMT_SRGGB10_1X10:
1038 prev->params.cfa_order = 1;
1039 break;
1040 case V4L2_MBUS_FMT_SBGGR10_1X10:
1041 prev->params.cfa_order = 2;
1042 break;
1043 case V4L2_MBUS_FMT_SGBRG10_1X10:
1044 prev->params.cfa_order = 3;
1045 break;
1046 default:
1047 /* Disable CFA for non-Bayer formats. */
1048 isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
1049 ISPPRV_PCR_CFAEN);
1050 return;
1051 }
1052
1053 isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR, ISPPRV_PCR_CFAEN);
1054 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
1055 ISPPRV_PCR_CFAFMT_MASK, ISPPRV_PCR_CFAFMT_BAYER);
1056
1057 params = (prev->params.active & OMAP3ISP_PREV_CFA)
1058 ? &prev->params.params[0] : &prev->params.params[1];
1059
1060 preview_config_cfa(prev, params);
1061}
1062
1063/*
1064 * preview_config_input_size - Configure the input frame size
1065 *
1066 * The preview engine crops several rows and columns internally depending on
1067 * which processing blocks are enabled. The driver assumes all those blocks are
1068 * enabled when reporting source pad formats to userspace. If this assumption is
1069 * not true, rows and columns must be manually cropped at the preview engine
1070 * input to avoid overflows at the end of lines and frames.
1071 *
1072 * See the explanation at the PREV_MARGIN_* definitions for more details.
1073 */
1074static void preview_config_input_size(struct isp_prev_device *prev, u32 active)
1075{
1076 const struct v4l2_mbus_framefmt *format = &prev->formats[PREV_PAD_SINK];
1077 struct isp_device *isp = to_isp_device(prev);
1078 unsigned int sph = prev->crop.left;
1079 unsigned int eph = prev->crop.left + prev->crop.width - 1;
1080 unsigned int slv = prev->crop.top;
1081 unsigned int elv = prev->crop.top + prev->crop.height - 1;
1082 u32 features;
1083
1084 if (format->code != V4L2_MBUS_FMT_Y10_1X10) {
1085 sph -= 2;
1086 eph += 2;
1087 slv -= 2;
1088 elv += 2;
1089 }
1090
1091 features = (prev->params.params[0].features & active)
1092 | (prev->params.params[1].features & ~active);
1093
1094 if (features & (OMAP3ISP_PREV_DEFECT_COR | OMAP3ISP_PREV_NF)) {
1095 sph -= 2;
1096 eph += 2;
1097 slv -= 2;
1098 elv += 2;
1099 }
1100 if (features & OMAP3ISP_PREV_HRZ_MED) {
1101 sph -= 2;
1102 eph += 2;
1103 }
1104 if (features & (OMAP3ISP_PREV_CHROMA_SUPP | OMAP3ISP_PREV_LUMAENH))
1105 sph -= 2;
1106
1107 isp_reg_writel(isp, (sph << ISPPRV_HORZ_INFO_SPH_SHIFT) | eph,
1108 OMAP3_ISP_IOMEM_PREV, ISPPRV_HORZ_INFO);
1109 isp_reg_writel(isp, (slv << ISPPRV_VERT_INFO_SLV_SHIFT) | elv,
1110 OMAP3_ISP_IOMEM_PREV, ISPPRV_VERT_INFO);
1111}
1112
1113/*
1114 * preview_config_inlineoffset - Configures the Read address line offset.
1115 * @prev: Preview module
1116 * @offset: Line offset
1117 *
1118 * According to the TRM, the line offset must be aligned on a 32 bytes boundary.
1119 * However, a hardware bug requires the memory start address to be aligned on a
1120 * 64 bytes boundary, so the offset probably should be aligned on 64 bytes as
1121 * well.
1122 */
1123static void
1124preview_config_inlineoffset(struct isp_prev_device *prev, u32 offset)
1125{
1126 struct isp_device *isp = to_isp_device(prev);
1127
1128 isp_reg_writel(isp, offset & 0xffff, OMAP3_ISP_IOMEM_PREV,
1129 ISPPRV_RADR_OFFSET);
1130}
1131
1132/*
1133 * preview_set_inaddr - Sets memory address of input frame.
1134 * @addr: 32bit memory address aligned on 32byte boundary.
1135 *
1136 * Configures the memory address from which the input frame is to be read.
1137 */
1138static void preview_set_inaddr(struct isp_prev_device *prev, u32 addr)
1139{
1140 struct isp_device *isp = to_isp_device(prev);
1141
1142 isp_reg_writel(isp, addr, OMAP3_ISP_IOMEM_PREV, ISPPRV_RSDR_ADDR);
1143}
1144
1145/*
1146 * preview_config_outlineoffset - Configures the Write address line offset.
1147 * @offset: Line Offset for the preview output.
1148 *
1149 * The offset must be a multiple of 32 bytes.
1150 */
1151static void preview_config_outlineoffset(struct isp_prev_device *prev,
1152 u32 offset)
1153{
1154 struct isp_device *isp = to_isp_device(prev);
1155
1156 isp_reg_writel(isp, offset & 0xffff, OMAP3_ISP_IOMEM_PREV,
1157 ISPPRV_WADD_OFFSET);
1158}
1159
1160/*
1161 * preview_set_outaddr - Sets the memory address to store output frame
1162 * @addr: 32bit memory address aligned on 32byte boundary.
1163 *
1164 * Configures the memory address to which the output frame is written.
1165 */
1166static void preview_set_outaddr(struct isp_prev_device *prev, u32 addr)
1167{
1168 struct isp_device *isp = to_isp_device(prev);
1169
1170 isp_reg_writel(isp, addr, OMAP3_ISP_IOMEM_PREV, ISPPRV_WSDR_ADDR);
1171}
1172
1173static void preview_adjust_bandwidth(struct isp_prev_device *prev)
1174{
1175 struct isp_pipeline *pipe = to_isp_pipeline(&prev->subdev.entity);
1176 struct isp_device *isp = to_isp_device(prev);
1177 const struct v4l2_mbus_framefmt *ifmt = &prev->formats[PREV_PAD_SINK];
1178 unsigned long l3_ick = pipe->l3_ick;
1179 struct v4l2_fract *timeperframe;
1180 unsigned int cycles_per_frame;
1181 unsigned int requests_per_frame;
1182 unsigned int cycles_per_request;
1183 unsigned int minimum;
1184 unsigned int maximum;
1185 unsigned int value;
1186
1187 if (prev->input != PREVIEW_INPUT_MEMORY) {
1188 isp_reg_clr(isp, OMAP3_ISP_IOMEM_SBL, ISPSBL_SDR_REQ_EXP,
1189 ISPSBL_SDR_REQ_PRV_EXP_MASK);
1190 return;
1191 }
1192
1193 /* Compute the minimum number of cycles per request, based on the
1194 * pipeline maximum data rate. This is an absolute lower bound if we
1195 * don't want SBL overflows, so round the value up.
1196 */
1197 cycles_per_request = div_u64((u64)l3_ick / 2 * 256 + pipe->max_rate - 1,
1198 pipe->max_rate);
1199 minimum = DIV_ROUND_UP(cycles_per_request, 32);
1200
1201 /* Compute the maximum number of cycles per request, based on the
1202 * requested frame rate. This is a soft upper bound to achieve a frame
1203 * rate equal or higher than the requested value, so round the value
1204 * down.
1205 */
1206 timeperframe = &pipe->max_timeperframe;
1207
1208 requests_per_frame = DIV_ROUND_UP(ifmt->width * 2, 256) * ifmt->height;
1209 cycles_per_frame = div_u64((u64)l3_ick * timeperframe->numerator,
1210 timeperframe->denominator);
1211 cycles_per_request = cycles_per_frame / requests_per_frame;
1212
1213 maximum = cycles_per_request / 32;
1214
1215 value = max(minimum, maximum);
1216
1217 dev_dbg(isp->dev, "%s: cycles per request = %u\n", __func__, value);
1218 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_SBL, ISPSBL_SDR_REQ_EXP,
1219 ISPSBL_SDR_REQ_PRV_EXP_MASK,
1220 value << ISPSBL_SDR_REQ_PRV_EXP_SHIFT);
1221}
1222
1223/*
1224 * omap3isp_preview_busy - Gets busy state of preview module.
1225 */
1226int omap3isp_preview_busy(struct isp_prev_device *prev)
1227{
1228 struct isp_device *isp = to_isp_device(prev);
1229
1230 return isp_reg_readl(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR)
1231 & ISPPRV_PCR_BUSY;
1232}
1233
1234/*
1235 * omap3isp_preview_restore_context - Restores the values of preview registers
1236 */
1237void omap3isp_preview_restore_context(struct isp_device *isp)
1238{
1239 struct isp_prev_device *prev = &isp->isp_prev;
1240 const u32 update = OMAP3ISP_PREV_FEATURES_END - 1;
1241
1242 prev->params.params[0].update = prev->params.active & update;
1243 prev->params.params[1].update = ~prev->params.active & update;
1244
1245 preview_setup_hw(prev, update, prev->params.active);
1246
1247 prev->params.params[0].update = 0;
1248 prev->params.params[1].update = 0;
1249}
1250
1251/*
1252 * preview_print_status - Dump preview module registers to the kernel log
1253 */
1254#define PREV_PRINT_REGISTER(isp, name)\
1255 dev_dbg(isp->dev, "###PRV " #name "=0x%08x\n", \
1256 isp_reg_readl(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_##name))
1257
1258static void preview_print_status(struct isp_prev_device *prev)
1259{
1260 struct isp_device *isp = to_isp_device(prev);
1261
1262 dev_dbg(isp->dev, "-------------Preview Register dump----------\n");
1263
1264 PREV_PRINT_REGISTER(isp, PCR);
1265 PREV_PRINT_REGISTER(isp, HORZ_INFO);
1266 PREV_PRINT_REGISTER(isp, VERT_INFO);
1267 PREV_PRINT_REGISTER(isp, RSDR_ADDR);
1268 PREV_PRINT_REGISTER(isp, RADR_OFFSET);
1269 PREV_PRINT_REGISTER(isp, DSDR_ADDR);
1270 PREV_PRINT_REGISTER(isp, DRKF_OFFSET);
1271 PREV_PRINT_REGISTER(isp, WSDR_ADDR);
1272 PREV_PRINT_REGISTER(isp, WADD_OFFSET);
1273 PREV_PRINT_REGISTER(isp, AVE);
1274 PREV_PRINT_REGISTER(isp, HMED);
1275 PREV_PRINT_REGISTER(isp, NF);
1276 PREV_PRINT_REGISTER(isp, WB_DGAIN);
1277 PREV_PRINT_REGISTER(isp, WBGAIN);
1278 PREV_PRINT_REGISTER(isp, WBSEL);
1279 PREV_PRINT_REGISTER(isp, CFA);
1280 PREV_PRINT_REGISTER(isp, BLKADJOFF);
1281 PREV_PRINT_REGISTER(isp, RGB_MAT1);
1282 PREV_PRINT_REGISTER(isp, RGB_MAT2);
1283 PREV_PRINT_REGISTER(isp, RGB_MAT3);
1284 PREV_PRINT_REGISTER(isp, RGB_MAT4);
1285 PREV_PRINT_REGISTER(isp, RGB_MAT5);
1286 PREV_PRINT_REGISTER(isp, RGB_OFF1);
1287 PREV_PRINT_REGISTER(isp, RGB_OFF2);
1288 PREV_PRINT_REGISTER(isp, CSC0);
1289 PREV_PRINT_REGISTER(isp, CSC1);
1290 PREV_PRINT_REGISTER(isp, CSC2);
1291 PREV_PRINT_REGISTER(isp, CSC_OFFSET);
1292 PREV_PRINT_REGISTER(isp, CNT_BRT);
1293 PREV_PRINT_REGISTER(isp, CSUP);
1294 PREV_PRINT_REGISTER(isp, SETUP_YC);
1295 PREV_PRINT_REGISTER(isp, SET_TBL_ADDR);
1296 PREV_PRINT_REGISTER(isp, CDC_THR0);
1297 PREV_PRINT_REGISTER(isp, CDC_THR1);
1298 PREV_PRINT_REGISTER(isp, CDC_THR2);
1299 PREV_PRINT_REGISTER(isp, CDC_THR3);
1300
1301 dev_dbg(isp->dev, "--------------------------------------------\n");
1302}
1303
1304/*
1305 * preview_init_params - init image processing parameters.
1306 * @prev: pointer to previewer private structure
1307 */
1308static void preview_init_params(struct isp_prev_device *prev)
1309{
1310 struct prev_params *params;
1311 unsigned int i;
1312
1313 spin_lock_init(&prev->params.lock);
1314
1315 prev->params.active = ~0;
1316 prev->params.params[0].busy = 0;
1317 prev->params.params[0].update = OMAP3ISP_PREV_FEATURES_END - 1;
1318 prev->params.params[1].busy = 0;
1319 prev->params.params[1].update = 0;
1320
1321 params = &prev->params.params[0];
1322
1323 /* Init values */
1324 params->contrast = ISPPRV_CONTRAST_DEF * ISPPRV_CONTRAST_UNITS;
1325 params->brightness = ISPPRV_BRIGHT_DEF * ISPPRV_BRIGHT_UNITS;
1326 params->cfa.format = OMAP3ISP_CFAFMT_BAYER;
1327 memcpy(params->cfa.table, cfa_coef_table,
1328 sizeof(params->cfa.table));
1329 params->cfa.gradthrs_horz = FLR_CFA_GRADTHRS_HORZ;
1330 params->cfa.gradthrs_vert = FLR_CFA_GRADTHRS_VERT;
1331 params->csup.gain = FLR_CSUP_GAIN;
1332 params->csup.thres = FLR_CSUP_THRES;
1333 params->csup.hypf_en = 0;
1334 memcpy(params->luma.table, luma_enhance_table,
1335 sizeof(params->luma.table));
1336 params->nf.spread = FLR_NF_STRGTH;
1337 memcpy(params->nf.table, noise_filter_table, sizeof(params->nf.table));
1338 params->dcor.couplet_mode_en = 1;
1339 for (i = 0; i < OMAP3ISP_PREV_DETECT_CORRECT_CHANNELS; i++)
1340 params->dcor.detect_correct[i] = DEF_DETECT_CORRECT_VAL;
1341 memcpy(params->gamma.blue, gamma_table, sizeof(params->gamma.blue));
1342 memcpy(params->gamma.green, gamma_table, sizeof(params->gamma.green));
1343 memcpy(params->gamma.red, gamma_table, sizeof(params->gamma.red));
1344 params->wbal.dgain = FLR_WBAL_DGAIN;
1345 params->wbal.coef0 = FLR_WBAL_COEF;
1346 params->wbal.coef1 = FLR_WBAL_COEF;
1347 params->wbal.coef2 = FLR_WBAL_COEF;
1348 params->wbal.coef3 = FLR_WBAL_COEF;
1349 params->blkadj.red = FLR_BLKADJ_RED;
1350 params->blkadj.green = FLR_BLKADJ_GREEN;
1351 params->blkadj.blue = FLR_BLKADJ_BLUE;
1352 params->rgb2rgb = flr_rgb2rgb;
1353 params->csc = flr_prev_csc;
1354 params->yclimit.minC = ISPPRV_YC_MIN;
1355 params->yclimit.maxC = ISPPRV_YC_MAX;
1356 params->yclimit.minY = ISPPRV_YC_MIN;
1357 params->yclimit.maxY = ISPPRV_YC_MAX;
1358
1359 params->features = OMAP3ISP_PREV_CFA | OMAP3ISP_PREV_DEFECT_COR
1360 | OMAP3ISP_PREV_NF | OMAP3ISP_PREV_GAMMA
1361 | OMAP3ISP_PREV_BLKADJ | OMAP3ISP_PREV_YC_LIMIT
1362 | OMAP3ISP_PREV_RGB2RGB | OMAP3ISP_PREV_COLOR_CONV
1363 | OMAP3ISP_PREV_WB | OMAP3ISP_PREV_BRIGHTNESS
1364 | OMAP3ISP_PREV_CONTRAST;
1365}
1366
1367/*
1368 * preview_max_out_width - Handle previewer hardware ouput limitations
1369 * @isp_revision : ISP revision
1370 * returns maximum width output for current isp revision
1371 */
1372static unsigned int preview_max_out_width(struct isp_prev_device *prev)
1373{
1374 struct isp_device *isp = to_isp_device(prev);
1375
1376 switch (isp->revision) {
1377 case ISP_REVISION_1_0:
1378 return PREV_MAX_OUT_WIDTH_REV_1;
1379
1380 case ISP_REVISION_2_0:
1381 default:
1382 return PREV_MAX_OUT_WIDTH_REV_2;
1383
1384 case ISP_REVISION_15_0:
1385 return PREV_MAX_OUT_WIDTH_REV_15;
1386 }
1387}
1388
1389static void preview_configure(struct isp_prev_device *prev)
1390{
1391 struct isp_device *isp = to_isp_device(prev);
1392 struct v4l2_mbus_framefmt *format;
1393 unsigned long flags;
1394 u32 update;
1395 u32 active;
1396
1397 spin_lock_irqsave(&prev->params.lock, flags);
1398 /* Mark all active parameters we are going to touch as busy. */
1399 update = preview_params_lock(prev, 0, false);
1400 active = prev->params.active;
1401 spin_unlock_irqrestore(&prev->params.lock, flags);
1402
1403 /* PREV_PAD_SINK */
1404 format = &prev->formats[PREV_PAD_SINK];
1405
1406 preview_adjust_bandwidth(prev);
1407
1408 preview_config_input_format(prev, format);
1409 preview_config_input_size(prev, active);
1410
1411 if (prev->input == PREVIEW_INPUT_CCDC)
1412 preview_config_inlineoffset(prev, 0);
1413 else
1414 preview_config_inlineoffset(prev,
1415 ALIGN(format->width, 0x20) * 2);
1416
1417 preview_setup_hw(prev, update, active);
1418
1419 /* PREV_PAD_SOURCE */
1420 format = &prev->formats[PREV_PAD_SOURCE];
1421
1422 if (prev->output & PREVIEW_OUTPUT_MEMORY)
1423 isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
1424 ISPPRV_PCR_SDRPORT);
1425 else
1426 isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
1427 ISPPRV_PCR_SDRPORT);
1428
1429 if (prev->output & PREVIEW_OUTPUT_RESIZER)
1430 isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
1431 ISPPRV_PCR_RSZPORT);
1432 else
1433 isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
1434 ISPPRV_PCR_RSZPORT);
1435
1436 if (prev->output & PREVIEW_OUTPUT_MEMORY)
1437 preview_config_outlineoffset(prev,
1438 ALIGN(format->width, 0x10) * 2);
1439
1440 preview_config_averager(prev, 0);
1441 preview_config_ycpos(prev, format->code);
1442
1443 spin_lock_irqsave(&prev->params.lock, flags);
1444 preview_params_unlock(prev, update, false);
1445 spin_unlock_irqrestore(&prev->params.lock, flags);
1446}
1447
1448/* -----------------------------------------------------------------------------
1449 * Interrupt handling
1450 */
1451
1452static void preview_enable_oneshot(struct isp_prev_device *prev)
1453{
1454 struct isp_device *isp = to_isp_device(prev);
1455
1456 /* The PCR.SOURCE bit is automatically reset to 0 when the PCR.ENABLE
1457 * bit is set. As the preview engine is used in single-shot mode, we
1458 * need to set PCR.SOURCE before enabling the preview engine.
1459 */
1460 if (prev->input == PREVIEW_INPUT_MEMORY)
1461 isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
1462 ISPPRV_PCR_SOURCE);
1463
1464 isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
1465 ISPPRV_PCR_EN | ISPPRV_PCR_ONESHOT);
1466}
1467
1468void omap3isp_preview_isr_frame_sync(struct isp_prev_device *prev)
1469{
1470 /*
1471 * If ISP_VIDEO_DMAQUEUE_QUEUED is set, DMA queue had an underrun
1472 * condition, the module was paused and now we have a buffer queued
1473 * on the output again. Restart the pipeline if running in continuous
1474 * mode.
1475 */
1476 if (prev->state == ISP_PIPELINE_STREAM_CONTINUOUS &&
1477 prev->video_out.dmaqueue_flags & ISP_VIDEO_DMAQUEUE_QUEUED) {
1478 preview_enable_oneshot(prev);
1479 isp_video_dmaqueue_flags_clr(&prev->video_out);
1480 }
1481}
1482
1483static void preview_isr_buffer(struct isp_prev_device *prev)
1484{
1485 struct isp_pipeline *pipe = to_isp_pipeline(&prev->subdev.entity);
1486 struct isp_buffer *buffer;
1487 int restart = 0;
1488
1489 if (prev->input == PREVIEW_INPUT_MEMORY) {
1490 buffer = omap3isp_video_buffer_next(&prev->video_in);
1491 if (buffer != NULL)
1492 preview_set_inaddr(prev, buffer->isp_addr);
1493 pipe->state |= ISP_PIPELINE_IDLE_INPUT;
1494 }
1495
1496 if (prev->output & PREVIEW_OUTPUT_MEMORY) {
1497 buffer = omap3isp_video_buffer_next(&prev->video_out);
1498 if (buffer != NULL) {
1499 preview_set_outaddr(prev, buffer->isp_addr);
1500 restart = 1;
1501 }
1502 pipe->state |= ISP_PIPELINE_IDLE_OUTPUT;
1503 }
1504
1505 switch (prev->state) {
1506 case ISP_PIPELINE_STREAM_SINGLESHOT:
1507 if (isp_pipeline_ready(pipe))
1508 omap3isp_pipeline_set_stream(pipe,
1509 ISP_PIPELINE_STREAM_SINGLESHOT);
1510 break;
1511
1512 case ISP_PIPELINE_STREAM_CONTINUOUS:
1513 /* If an underrun occurs, the video queue operation handler will
1514 * restart the preview engine. Otherwise restart it immediately.
1515 */
1516 if (restart)
1517 preview_enable_oneshot(prev);
1518 break;
1519
1520 case ISP_PIPELINE_STREAM_STOPPED:
1521 default:
1522 return;
1523 }
1524}
1525
1526/*
1527 * omap3isp_preview_isr - ISP preview engine interrupt handler
1528 *
1529 * Manage the preview engine video buffers and configure shadowed registers.
1530 */
1531void omap3isp_preview_isr(struct isp_prev_device *prev)
1532{
1533 unsigned long flags;
1534 u32 update;
1535 u32 active;
1536
1537 if (omap3isp_module_sync_is_stopping(&prev->wait, &prev->stopping))
1538 return;
1539
1540 spin_lock_irqsave(&prev->params.lock, flags);
1541 preview_params_switch(prev);
1542 update = preview_params_lock(prev, 0, false);
1543 active = prev->params.active;
1544 spin_unlock_irqrestore(&prev->params.lock, flags);
1545
1546 preview_setup_hw(prev, update, active);
1547 preview_config_input_size(prev, active);
1548
1549 if (prev->input == PREVIEW_INPUT_MEMORY ||
1550 prev->output & PREVIEW_OUTPUT_MEMORY)
1551 preview_isr_buffer(prev);
1552 else if (prev->state == ISP_PIPELINE_STREAM_CONTINUOUS)
1553 preview_enable_oneshot(prev);
1554
1555 spin_lock_irqsave(&prev->params.lock, flags);
1556 preview_params_unlock(prev, update, false);
1557 spin_unlock_irqrestore(&prev->params.lock, flags);
1558}
1559
1560/* -----------------------------------------------------------------------------
1561 * ISP video operations
1562 */
1563
1564static int preview_video_queue(struct isp_video *video,
1565 struct isp_buffer *buffer)
1566{
1567 struct isp_prev_device *prev = &video->isp->isp_prev;
1568
1569 if (video->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
1570 preview_set_inaddr(prev, buffer->isp_addr);
1571
1572 if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1573 preview_set_outaddr(prev, buffer->isp_addr);
1574
1575 return 0;
1576}
1577
1578static const struct isp_video_operations preview_video_ops = {
1579 .queue = preview_video_queue,
1580};
1581
1582/* -----------------------------------------------------------------------------
1583 * V4L2 subdev operations
1584 */
1585
1586/*
1587 * preview_s_ctrl - Handle set control subdev method
1588 * @ctrl: pointer to v4l2 control structure
1589 */
1590static int preview_s_ctrl(struct v4l2_ctrl *ctrl)
1591{
1592 struct isp_prev_device *prev =
1593 container_of(ctrl->handler, struct isp_prev_device, ctrls);
1594
1595 switch (ctrl->id) {
1596 case V4L2_CID_BRIGHTNESS:
1597 preview_update_brightness(prev, ctrl->val);
1598 break;
1599 case V4L2_CID_CONTRAST:
1600 preview_update_contrast(prev, ctrl->val);
1601 break;
1602 }
1603
1604 return 0;
1605}
1606
1607static const struct v4l2_ctrl_ops preview_ctrl_ops = {
1608 .s_ctrl = preview_s_ctrl,
1609};
1610
1611/*
1612 * preview_ioctl - Handle preview module private ioctl's
1613 * @prev: pointer to preview context structure
1614 * @cmd: configuration command
1615 * @arg: configuration argument
1616 * return -EINVAL or zero on success
1617 */
1618static long preview_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
1619{
1620 struct isp_prev_device *prev = v4l2_get_subdevdata(sd);
1621
1622 switch (cmd) {
1623 case VIDIOC_OMAP3ISP_PRV_CFG:
1624 return preview_config(prev, arg);
1625
1626 default:
1627 return -ENOIOCTLCMD;
1628 }
1629}
1630
1631/*
1632 * preview_set_stream - Enable/Disable streaming on preview subdev
1633 * @sd : pointer to v4l2 subdev structure
1634 * @enable: 1 == Enable, 0 == Disable
1635 * return -EINVAL or zero on success
1636 */
1637static int preview_set_stream(struct v4l2_subdev *sd, int enable)
1638{
1639 struct isp_prev_device *prev = v4l2_get_subdevdata(sd);
1640 struct isp_video *video_out = &prev->video_out;
1641 struct isp_device *isp = to_isp_device(prev);
1642 struct device *dev = to_device(prev);
1643
1644 if (prev->state == ISP_PIPELINE_STREAM_STOPPED) {
1645 if (enable == ISP_PIPELINE_STREAM_STOPPED)
1646 return 0;
1647
1648 omap3isp_subclk_enable(isp, OMAP3_ISP_SUBCLK_PREVIEW);
1649 preview_configure(prev);
1650 atomic_set(&prev->stopping, 0);
1651 preview_print_status(prev);
1652 }
1653
1654 switch (enable) {
1655 case ISP_PIPELINE_STREAM_CONTINUOUS:
1656 if (prev->output & PREVIEW_OUTPUT_MEMORY)
1657 omap3isp_sbl_enable(isp, OMAP3_ISP_SBL_PREVIEW_WRITE);
1658
1659 if (video_out->dmaqueue_flags & ISP_VIDEO_DMAQUEUE_QUEUED ||
1660 !(prev->output & PREVIEW_OUTPUT_MEMORY))
1661 preview_enable_oneshot(prev);
1662
1663 isp_video_dmaqueue_flags_clr(video_out);
1664 break;
1665
1666 case ISP_PIPELINE_STREAM_SINGLESHOT:
1667 if (prev->input == PREVIEW_INPUT_MEMORY)
1668 omap3isp_sbl_enable(isp, OMAP3_ISP_SBL_PREVIEW_READ);
1669 if (prev->output & PREVIEW_OUTPUT_MEMORY)
1670 omap3isp_sbl_enable(isp, OMAP3_ISP_SBL_PREVIEW_WRITE);
1671
1672 preview_enable_oneshot(prev);
1673 break;
1674
1675 case ISP_PIPELINE_STREAM_STOPPED:
1676 if (omap3isp_module_sync_idle(&sd->entity, &prev->wait,
1677 &prev->stopping))
1678 dev_dbg(dev, "%s: stop timeout.\n", sd->name);
1679 omap3isp_sbl_disable(isp, OMAP3_ISP_SBL_PREVIEW_READ);
1680 omap3isp_sbl_disable(isp, OMAP3_ISP_SBL_PREVIEW_WRITE);
1681 omap3isp_subclk_disable(isp, OMAP3_ISP_SUBCLK_PREVIEW);
1682 isp_video_dmaqueue_flags_clr(video_out);
1683 break;
1684 }
1685
1686 prev->state = enable;
1687 return 0;
1688}
1689
1690static struct v4l2_mbus_framefmt *
1691__preview_get_format(struct isp_prev_device *prev, struct v4l2_subdev_fh *fh,
1692 unsigned int pad, enum v4l2_subdev_format_whence which)
1693{
1694 if (which == V4L2_SUBDEV_FORMAT_TRY)
1695 return v4l2_subdev_get_try_format(fh, pad);
1696 else
1697 return &prev->formats[pad];
1698}
1699
1700static struct v4l2_rect *
1701__preview_get_crop(struct isp_prev_device *prev, struct v4l2_subdev_fh *fh,
1702 enum v4l2_subdev_format_whence which)
1703{
1704 if (which == V4L2_SUBDEV_FORMAT_TRY)
1705 return v4l2_subdev_get_try_crop(fh, PREV_PAD_SINK);
1706 else
1707 return &prev->crop;
1708}
1709
1710/* previewer format descriptions */
1711static const unsigned int preview_input_fmts[] = {
1712 V4L2_MBUS_FMT_Y10_1X10,
1713 V4L2_MBUS_FMT_SGRBG10_1X10,
1714 V4L2_MBUS_FMT_SRGGB10_1X10,
1715 V4L2_MBUS_FMT_SBGGR10_1X10,
1716 V4L2_MBUS_FMT_SGBRG10_1X10,
1717};
1718
1719static const unsigned int preview_output_fmts[] = {
1720 V4L2_MBUS_FMT_UYVY8_1X16,
1721 V4L2_MBUS_FMT_YUYV8_1X16,
1722};
1723
1724/*
1725 * preview_try_format - Validate a format
1726 * @prev: ISP preview engine
1727 * @fh: V4L2 subdev file handle
1728 * @pad: pad number
1729 * @fmt: format to be validated
1730 * @which: try/active format selector
1731 *
1732 * Validate and adjust the given format for the given pad based on the preview
1733 * engine limits and the format and crop rectangles on other pads.
1734 */
1735static void preview_try_format(struct isp_prev_device *prev,
1736 struct v4l2_subdev_fh *fh, unsigned int pad,
1737 struct v4l2_mbus_framefmt *fmt,
1738 enum v4l2_subdev_format_whence which)
1739{
1740 enum v4l2_mbus_pixelcode pixelcode;
1741 struct v4l2_rect *crop;
1742 unsigned int i;
1743
1744 switch (pad) {
1745 case PREV_PAD_SINK:
1746 /* When reading data from the CCDC, the input size has already
1747 * been mangled by the CCDC output pad so it can be accepted
1748 * as-is.
1749 *
1750 * When reading data from memory, clamp the requested width and
1751 * height. The TRM doesn't specify a minimum input height, make
1752 * sure we got enough lines to enable the noise filter and color
1753 * filter array interpolation.
1754 */
1755 if (prev->input == PREVIEW_INPUT_MEMORY) {
1756 fmt->width = clamp_t(u32, fmt->width, PREV_MIN_IN_WIDTH,
1757 preview_max_out_width(prev));
1758 fmt->height = clamp_t(u32, fmt->height,
1759 PREV_MIN_IN_HEIGHT,
1760 PREV_MAX_IN_HEIGHT);
1761 }
1762
1763 fmt->colorspace = V4L2_COLORSPACE_SRGB;
1764
1765 for (i = 0; i < ARRAY_SIZE(preview_input_fmts); i++) {
1766 if (fmt->code == preview_input_fmts[i])
1767 break;
1768 }
1769
1770 /* If not found, use SGRBG10 as default */
1771 if (i >= ARRAY_SIZE(preview_input_fmts))
1772 fmt->code = V4L2_MBUS_FMT_SGRBG10_1X10;
1773 break;
1774
1775 case PREV_PAD_SOURCE:
1776 pixelcode = fmt->code;
1777 *fmt = *__preview_get_format(prev, fh, PREV_PAD_SINK, which);
1778
1779 switch (pixelcode) {
1780 case V4L2_MBUS_FMT_YUYV8_1X16:
1781 case V4L2_MBUS_FMT_UYVY8_1X16:
1782 fmt->code = pixelcode;
1783 break;
1784
1785 default:
1786 fmt->code = V4L2_MBUS_FMT_YUYV8_1X16;
1787 break;
1788 }
1789
1790 /* The preview module output size is configurable through the
1791 * averager (horizontal scaling by 1/1, 1/2, 1/4 or 1/8). This
1792 * is not supported yet, hardcode the output size to the crop
1793 * rectangle size.
1794 */
1795 crop = __preview_get_crop(prev, fh, which);
1796 fmt->width = crop->width;
1797 fmt->height = crop->height;
1798
1799 fmt->colorspace = V4L2_COLORSPACE_JPEG;
1800 break;
1801 }
1802
1803 fmt->field = V4L2_FIELD_NONE;
1804}
1805
1806/*
1807 * preview_try_crop - Validate a crop rectangle
1808 * @prev: ISP preview engine
1809 * @sink: format on the sink pad
1810 * @crop: crop rectangle to be validated
1811 *
1812 * The preview engine crops lines and columns for its internal operation,
1813 * depending on which filters are enabled. Enforce minimum crop margins to
1814 * handle that transparently for userspace.
1815 *
1816 * See the explanation at the PREV_MARGIN_* definitions for more details.
1817 */
1818static void preview_try_crop(struct isp_prev_device *prev,
1819 const struct v4l2_mbus_framefmt *sink,
1820 struct v4l2_rect *crop)
1821{
1822 unsigned int left = PREV_MARGIN_LEFT;
1823 unsigned int right = sink->width - PREV_MARGIN_RIGHT;
1824 unsigned int top = PREV_MARGIN_TOP;
1825 unsigned int bottom = sink->height - PREV_MARGIN_BOTTOM;
1826
1827 /* When processing data on-the-fly from the CCDC, at least 2 pixels must
1828 * be cropped from the left and right sides of the image. As we don't
1829 * know which filters will be enabled, increase the left and right
1830 * margins by two.
1831 */
1832 if (prev->input == PREVIEW_INPUT_CCDC) {
1833 left += 2;
1834 right -= 2;
1835 }
1836
1837 /* Restrict left/top to even values to keep the Bayer pattern. */
1838 crop->left &= ~1;
1839 crop->top &= ~1;
1840
1841 crop->left = clamp_t(u32, crop->left, left, right - PREV_MIN_OUT_WIDTH);
1842 crop->top = clamp_t(u32, crop->top, top, bottom - PREV_MIN_OUT_HEIGHT);
1843 crop->width = clamp_t(u32, crop->width, PREV_MIN_OUT_WIDTH,
1844 right - crop->left);
1845 crop->height = clamp_t(u32, crop->height, PREV_MIN_OUT_HEIGHT,
1846 bottom - crop->top);
1847}
1848
1849/*
1850 * preview_enum_mbus_code - Handle pixel format enumeration
1851 * @sd : pointer to v4l2 subdev structure
1852 * @fh : V4L2 subdev file handle
1853 * @code : pointer to v4l2_subdev_mbus_code_enum structure
1854 * return -EINVAL or zero on success
1855 */
1856static int preview_enum_mbus_code(struct v4l2_subdev *sd,
1857 struct v4l2_subdev_fh *fh,
1858 struct v4l2_subdev_mbus_code_enum *code)
1859{
1860 switch (code->pad) {
1861 case PREV_PAD_SINK:
1862 if (code->index >= ARRAY_SIZE(preview_input_fmts))
1863 return -EINVAL;
1864
1865 code->code = preview_input_fmts[code->index];
1866 break;
1867 case PREV_PAD_SOURCE:
1868 if (code->index >= ARRAY_SIZE(preview_output_fmts))
1869 return -EINVAL;
1870
1871 code->code = preview_output_fmts[code->index];
1872 break;
1873 default:
1874 return -EINVAL;
1875 }
1876
1877 return 0;
1878}
1879
1880static int preview_enum_frame_size(struct v4l2_subdev *sd,
1881 struct v4l2_subdev_fh *fh,
1882 struct v4l2_subdev_frame_size_enum *fse)
1883{
1884 struct isp_prev_device *prev = v4l2_get_subdevdata(sd);
1885 struct v4l2_mbus_framefmt format;
1886
1887 if (fse->index != 0)
1888 return -EINVAL;
1889
1890 format.code = fse->code;
1891 format.width = 1;
1892 format.height = 1;
1893 preview_try_format(prev, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY);
1894 fse->min_width = format.width;
1895 fse->min_height = format.height;
1896
1897 if (format.code != fse->code)
1898 return -EINVAL;
1899
1900 format.code = fse->code;
1901 format.width = -1;
1902 format.height = -1;
1903 preview_try_format(prev, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY);
1904 fse->max_width = format.width;
1905 fse->max_height = format.height;
1906
1907 return 0;
1908}
1909
1910/*
1911 * preview_get_selection - Retrieve a selection rectangle on a pad
1912 * @sd: ISP preview V4L2 subdevice
1913 * @fh: V4L2 subdev file handle
1914 * @sel: Selection rectangle
1915 *
1916 * The only supported rectangles are the crop rectangles on the sink pad.
1917 *
1918 * Return 0 on success or a negative error code otherwise.
1919 */
1920static int preview_get_selection(struct v4l2_subdev *sd,
1921 struct v4l2_subdev_fh *fh,
1922 struct v4l2_subdev_selection *sel)
1923{
1924 struct isp_prev_device *prev = v4l2_get_subdevdata(sd);
1925 struct v4l2_mbus_framefmt *format;
1926
1927 if (sel->pad != PREV_PAD_SINK)
1928 return -EINVAL;
1929
1930 switch (sel->target) {
1931 case V4L2_SEL_TGT_CROP_BOUNDS:
1932 sel->r.left = 0;
1933 sel->r.top = 0;
1934 sel->r.width = INT_MAX;
1935 sel->r.height = INT_MAX;
1936
1937 format = __preview_get_format(prev, fh, PREV_PAD_SINK,
1938 sel->which);
1939 preview_try_crop(prev, format, &sel->r);
1940 break;
1941
1942 case V4L2_SEL_TGT_CROP:
1943 sel->r = *__preview_get_crop(prev, fh, sel->which);
1944 break;
1945
1946 default:
1947 return -EINVAL;
1948 }
1949
1950 return 0;
1951}
1952
1953/*
1954 * preview_set_selection - Set a selection rectangle on a pad
1955 * @sd: ISP preview V4L2 subdevice
1956 * @fh: V4L2 subdev file handle
1957 * @sel: Selection rectangle
1958 *
1959 * The only supported rectangle is the actual crop rectangle on the sink pad.
1960 *
1961 * Return 0 on success or a negative error code otherwise.
1962 */
1963static int preview_set_selection(struct v4l2_subdev *sd,
1964 struct v4l2_subdev_fh *fh,
1965 struct v4l2_subdev_selection *sel)
1966{
1967 struct isp_prev_device *prev = v4l2_get_subdevdata(sd);
1968 struct v4l2_mbus_framefmt *format;
1969
1970 if (sel->target != V4L2_SEL_TGT_CROP ||
1971 sel->pad != PREV_PAD_SINK)
1972 return -EINVAL;
1973
1974 /* The crop rectangle can't be changed while streaming. */
1975 if (prev->state != ISP_PIPELINE_STREAM_STOPPED)
1976 return -EBUSY;
1977
1978 /* Modifying the crop rectangle always changes the format on the source
1979 * pad. If the KEEP_CONFIG flag is set, just return the current crop
1980 * rectangle.
1981 */
1982 if (sel->flags & V4L2_SEL_FLAG_KEEP_CONFIG) {
1983 sel->r = *__preview_get_crop(prev, fh, sel->which);
1984 return 0;
1985 }
1986
1987 format = __preview_get_format(prev, fh, PREV_PAD_SINK, sel->which);
1988 preview_try_crop(prev, format, &sel->r);
1989 *__preview_get_crop(prev, fh, sel->which) = sel->r;
1990
1991 /* Update the source format. */
1992 format = __preview_get_format(prev, fh, PREV_PAD_SOURCE, sel->which);
1993 preview_try_format(prev, fh, PREV_PAD_SOURCE, format, sel->which);
1994
1995 return 0;
1996}
1997
1998/*
1999 * preview_get_format - Handle get format by pads subdev method
2000 * @sd : pointer to v4l2 subdev structure
2001 * @fh : V4L2 subdev file handle
2002 * @fmt: pointer to v4l2 subdev format structure
2003 * return -EINVAL or zero on success
2004 */
2005static int preview_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
2006 struct v4l2_subdev_format *fmt)
2007{
2008 struct isp_prev_device *prev = v4l2_get_subdevdata(sd);
2009 struct v4l2_mbus_framefmt *format;
2010
2011 format = __preview_get_format(prev, fh, fmt->pad, fmt->which);
2012 if (format == NULL)
2013 return -EINVAL;
2014
2015 fmt->format = *format;
2016 return 0;
2017}
2018
2019/*
2020 * preview_set_format - Handle set format by pads subdev method
2021 * @sd : pointer to v4l2 subdev structure
2022 * @fh : V4L2 subdev file handle
2023 * @fmt: pointer to v4l2 subdev format structure
2024 * return -EINVAL or zero on success
2025 */
2026static int preview_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
2027 struct v4l2_subdev_format *fmt)
2028{
2029 struct isp_prev_device *prev = v4l2_get_subdevdata(sd);
2030 struct v4l2_mbus_framefmt *format;
2031 struct v4l2_rect *crop;
2032
2033 format = __preview_get_format(prev, fh, fmt->pad, fmt->which);
2034 if (format == NULL)
2035 return -EINVAL;
2036
2037 preview_try_format(prev, fh, fmt->pad, &fmt->format, fmt->which);
2038 *format = fmt->format;
2039
2040 /* Propagate the format from sink to source */
2041 if (fmt->pad == PREV_PAD_SINK) {
2042 /* Reset the crop rectangle. */
2043 crop = __preview_get_crop(prev, fh, fmt->which);
2044 crop->left = 0;
2045 crop->top = 0;
2046 crop->width = fmt->format.width;
2047 crop->height = fmt->format.height;
2048
2049 preview_try_crop(prev, &fmt->format, crop);
2050
2051 /* Update the source format. */
2052 format = __preview_get_format(prev, fh, PREV_PAD_SOURCE,
2053 fmt->which);
2054 preview_try_format(prev, fh, PREV_PAD_SOURCE, format,
2055 fmt->which);
2056 }
2057
2058 return 0;
2059}
2060
2061/*
2062 * preview_init_formats - Initialize formats on all pads
2063 * @sd: ISP preview V4L2 subdevice
2064 * @fh: V4L2 subdev file handle
2065 *
2066 * Initialize all pad formats with default values. If fh is not NULL, try
2067 * formats are initialized on the file handle. Otherwise active formats are
2068 * initialized on the device.
2069 */
2070static int preview_init_formats(struct v4l2_subdev *sd,
2071 struct v4l2_subdev_fh *fh)
2072{
2073 struct v4l2_subdev_format format;
2074
2075 memset(&format, 0, sizeof(format));
2076 format.pad = PREV_PAD_SINK;
2077 format.which = fh ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE;
2078 format.format.code = V4L2_MBUS_FMT_SGRBG10_1X10;
2079 format.format.width = 4096;
2080 format.format.height = 4096;
2081 preview_set_format(sd, fh, &format);
2082
2083 return 0;
2084}
2085
2086/* subdev core operations */
2087static const struct v4l2_subdev_core_ops preview_v4l2_core_ops = {
2088 .ioctl = preview_ioctl,
2089};
2090
2091/* subdev video operations */
2092static const struct v4l2_subdev_video_ops preview_v4l2_video_ops = {
2093 .s_stream = preview_set_stream,
2094};
2095
2096/* subdev pad operations */
2097static const struct v4l2_subdev_pad_ops preview_v4l2_pad_ops = {
2098 .enum_mbus_code = preview_enum_mbus_code,
2099 .enum_frame_size = preview_enum_frame_size,
2100 .get_fmt = preview_get_format,
2101 .set_fmt = preview_set_format,
2102 .get_selection = preview_get_selection,
2103 .set_selection = preview_set_selection,
2104};
2105
2106/* subdev operations */
2107static const struct v4l2_subdev_ops preview_v4l2_ops = {
2108 .core = &preview_v4l2_core_ops,
2109 .video = &preview_v4l2_video_ops,
2110 .pad = &preview_v4l2_pad_ops,
2111};
2112
2113/* subdev internal operations */
2114static const struct v4l2_subdev_internal_ops preview_v4l2_internal_ops = {
2115 .open = preview_init_formats,
2116};
2117
2118/* -----------------------------------------------------------------------------
2119 * Media entity operations
2120 */
2121
2122/*
2123 * preview_link_setup - Setup previewer connections.
2124 * @entity : Pointer to media entity structure
2125 * @local : Pointer to local pad array
2126 * @remote : Pointer to remote pad array
2127 * @flags : Link flags
2128 * return -EINVAL or zero on success
2129 */
2130static int preview_link_setup(struct media_entity *entity,
2131 const struct media_pad *local,
2132 const struct media_pad *remote, u32 flags)
2133{
2134 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
2135 struct isp_prev_device *prev = v4l2_get_subdevdata(sd);
2136
2137 switch (local->index | media_entity_type(remote->entity)) {
2138 case PREV_PAD_SINK | MEDIA_ENT_T_DEVNODE:
2139 /* read from memory */
2140 if (flags & MEDIA_LNK_FL_ENABLED) {
2141 if (prev->input == PREVIEW_INPUT_CCDC)
2142 return -EBUSY;
2143 prev->input = PREVIEW_INPUT_MEMORY;
2144 } else {
2145 if (prev->input == PREVIEW_INPUT_MEMORY)
2146 prev->input = PREVIEW_INPUT_NONE;
2147 }
2148 break;
2149
2150 case PREV_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV:
2151 /* read from ccdc */
2152 if (flags & MEDIA_LNK_FL_ENABLED) {
2153 if (prev->input == PREVIEW_INPUT_MEMORY)
2154 return -EBUSY;
2155 prev->input = PREVIEW_INPUT_CCDC;
2156 } else {
2157 if (prev->input == PREVIEW_INPUT_CCDC)
2158 prev->input = PREVIEW_INPUT_NONE;
2159 }
2160 break;
2161
2162 /*
2163 * The ISP core doesn't support pipelines with multiple video outputs.
2164 * Revisit this when it will be implemented, and return -EBUSY for now.
2165 */
2166
2167 case PREV_PAD_SOURCE | MEDIA_ENT_T_DEVNODE:
2168 /* write to memory */
2169 if (flags & MEDIA_LNK_FL_ENABLED) {
2170 if (prev->output & ~PREVIEW_OUTPUT_MEMORY)
2171 return -EBUSY;
2172 prev->output |= PREVIEW_OUTPUT_MEMORY;
2173 } else {
2174 prev->output &= ~PREVIEW_OUTPUT_MEMORY;
2175 }
2176 break;
2177
2178 case PREV_PAD_SOURCE | MEDIA_ENT_T_V4L2_SUBDEV:
2179 /* write to resizer */
2180 if (flags & MEDIA_LNK_FL_ENABLED) {
2181 if (prev->output & ~PREVIEW_OUTPUT_RESIZER)
2182 return -EBUSY;
2183 prev->output |= PREVIEW_OUTPUT_RESIZER;
2184 } else {
2185 prev->output &= ~PREVIEW_OUTPUT_RESIZER;
2186 }
2187 break;
2188
2189 default:
2190 return -EINVAL;
2191 }
2192
2193 return 0;
2194}
2195
2196/* media operations */
2197static const struct media_entity_operations preview_media_ops = {
2198 .link_setup = preview_link_setup,
2199 .link_validate = v4l2_subdev_link_validate,
2200};
2201
2202void omap3isp_preview_unregister_entities(struct isp_prev_device *prev)
2203{
2204 v4l2_device_unregister_subdev(&prev->subdev);
2205 omap3isp_video_unregister(&prev->video_in);
2206 omap3isp_video_unregister(&prev->video_out);
2207}
2208
2209int omap3isp_preview_register_entities(struct isp_prev_device *prev,
2210 struct v4l2_device *vdev)
2211{
2212 int ret;
2213
2214 /* Register the subdev and video nodes. */
2215 ret = v4l2_device_register_subdev(vdev, &prev->subdev);
2216 if (ret < 0)
2217 goto error;
2218
2219 ret = omap3isp_video_register(&prev->video_in, vdev);
2220 if (ret < 0)
2221 goto error;
2222
2223 ret = omap3isp_video_register(&prev->video_out, vdev);
2224 if (ret < 0)
2225 goto error;
2226
2227 return 0;
2228
2229error:
2230 omap3isp_preview_unregister_entities(prev);
2231 return ret;
2232}
2233
2234/* -----------------------------------------------------------------------------
2235 * ISP previewer initialisation and cleanup
2236 */
2237
2238/*
2239 * preview_init_entities - Initialize subdev and media entity.
2240 * @prev : Pointer to preview structure
2241 * return -ENOMEM or zero on success
2242 */
2243static int preview_init_entities(struct isp_prev_device *prev)
2244{
2245 struct v4l2_subdev *sd = &prev->subdev;
2246 struct media_pad *pads = prev->pads;
2247 struct media_entity *me = &sd->entity;
2248 int ret;
2249
2250 prev->input = PREVIEW_INPUT_NONE;
2251
2252 v4l2_subdev_init(sd, &preview_v4l2_ops);
2253 sd->internal_ops = &preview_v4l2_internal_ops;
2254 strlcpy(sd->name, "OMAP3 ISP preview", sizeof(sd->name));
2255 sd->grp_id = 1 << 16; /* group ID for isp subdevs */
2256 v4l2_set_subdevdata(sd, prev);
2257 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
2258
2259 v4l2_ctrl_handler_init(&prev->ctrls, 2);
2260 v4l2_ctrl_new_std(&prev->ctrls, &preview_ctrl_ops, V4L2_CID_BRIGHTNESS,
2261 ISPPRV_BRIGHT_LOW, ISPPRV_BRIGHT_HIGH,
2262 ISPPRV_BRIGHT_STEP, ISPPRV_BRIGHT_DEF);
2263 v4l2_ctrl_new_std(&prev->ctrls, &preview_ctrl_ops, V4L2_CID_CONTRAST,
2264 ISPPRV_CONTRAST_LOW, ISPPRV_CONTRAST_HIGH,
2265 ISPPRV_CONTRAST_STEP, ISPPRV_CONTRAST_DEF);
2266 v4l2_ctrl_handler_setup(&prev->ctrls);
2267 sd->ctrl_handler = &prev->ctrls;
2268
2269 pads[PREV_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
2270 pads[PREV_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
2271
2272 me->ops = &preview_media_ops;
2273 ret = media_entity_init(me, PREV_PADS_NUM, pads, 0);
2274 if (ret < 0)
2275 return ret;
2276
2277 preview_init_formats(sd, NULL);
2278
2279 /* According to the OMAP34xx TRM, video buffers need to be aligned on a
2280 * 32 bytes boundary. However, an undocumented hardware bug requires a
2281 * 64 bytes boundary at the preview engine input.
2282 */
2283 prev->video_in.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
2284 prev->video_in.ops = &preview_video_ops;
2285 prev->video_in.isp = to_isp_device(prev);
2286 prev->video_in.capture_mem = PAGE_ALIGN(4096 * 4096) * 2 * 3;
2287 prev->video_in.bpl_alignment = 64;
2288 prev->video_out.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2289 prev->video_out.ops = &preview_video_ops;
2290 prev->video_out.isp = to_isp_device(prev);
2291 prev->video_out.capture_mem = PAGE_ALIGN(4096 * 4096) * 2 * 3;
2292 prev->video_out.bpl_alignment = 32;
2293
2294 ret = omap3isp_video_init(&prev->video_in, "preview");
2295 if (ret < 0)
2296 goto error_video_in;
2297
2298 ret = omap3isp_video_init(&prev->video_out, "preview");
2299 if (ret < 0)
2300 goto error_video_out;
2301
2302 /* Connect the video nodes to the previewer subdev. */
2303 ret = media_entity_create_link(&prev->video_in.video.entity, 0,
2304 &prev->subdev.entity, PREV_PAD_SINK, 0);
2305 if (ret < 0)
2306 goto error_link;
2307
2308 ret = media_entity_create_link(&prev->subdev.entity, PREV_PAD_SOURCE,
2309 &prev->video_out.video.entity, 0, 0);
2310 if (ret < 0)
2311 goto error_link;
2312
2313 return 0;
2314
2315error_link:
2316 omap3isp_video_cleanup(&prev->video_out);
2317error_video_out:
2318 omap3isp_video_cleanup(&prev->video_in);
2319error_video_in:
2320 media_entity_cleanup(&prev->subdev.entity);
2321 return ret;
2322}
2323
2324/*
2325 * omap3isp_preview_init - Previewer initialization.
2326 * @dev : Pointer to ISP device
2327 * return -ENOMEM or zero on success
2328 */
2329int omap3isp_preview_init(struct isp_device *isp)
2330{
2331 struct isp_prev_device *prev = &isp->isp_prev;
2332
2333 init_waitqueue_head(&prev->wait);
2334
2335 preview_init_params(prev);
2336
2337 return preview_init_entities(prev);
2338}
2339
2340void omap3isp_preview_cleanup(struct isp_device *isp)
2341{
2342 struct isp_prev_device *prev = &isp->isp_prev;
2343
2344 v4l2_ctrl_handler_free(&prev->ctrls);
2345 omap3isp_video_cleanup(&prev->video_in);
2346 omap3isp_video_cleanup(&prev->video_out);
2347 media_entity_cleanup(&prev->subdev.entity);
2348}
diff --git a/drivers/media/video/omap3isp/isppreview.h b/drivers/media/video/omap3isp/isppreview.h
deleted file mode 100644
index f66923407f8c..000000000000
--- a/drivers/media/video/omap3isp/isppreview.h
+++ /dev/null
@@ -1,174 +0,0 @@
1/*
2 * isppreview.h
3 *
4 * TI OMAP3 ISP - Preview module
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc.
8 *
9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 * Sakari Ailus <sakari.ailus@iki.fi>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 */
26
27#ifndef OMAP3_ISP_PREVIEW_H
28#define OMAP3_ISP_PREVIEW_H
29
30#include <linux/omap3isp.h>
31#include <linux/types.h>
32#include <media/v4l2-ctrls.h>
33
34#include "ispvideo.h"
35
36#define ISPPRV_BRIGHT_STEP 0x1
37#define ISPPRV_BRIGHT_DEF 0x0
38#define ISPPRV_BRIGHT_LOW 0x0
39#define ISPPRV_BRIGHT_HIGH 0xFF
40#define ISPPRV_BRIGHT_UNITS 0x1
41
42#define ISPPRV_CONTRAST_STEP 0x1
43#define ISPPRV_CONTRAST_DEF 0x10
44#define ISPPRV_CONTRAST_LOW 0x0
45#define ISPPRV_CONTRAST_HIGH 0xFF
46#define ISPPRV_CONTRAST_UNITS 0x1
47
48/* Additional features not listed in linux/omap3isp.h */
49#define OMAP3ISP_PREV_CONTRAST (1 << 17)
50#define OMAP3ISP_PREV_BRIGHTNESS (1 << 18)
51#define OMAP3ISP_PREV_FEATURES_END (1 << 19)
52
53enum preview_input_entity {
54 PREVIEW_INPUT_NONE,
55 PREVIEW_INPUT_CCDC,
56 PREVIEW_INPUT_MEMORY,
57};
58
59#define PREVIEW_OUTPUT_RESIZER (1 << 1)
60#define PREVIEW_OUTPUT_MEMORY (1 << 2)
61
62/* Configure byte layout of YUV image */
63enum preview_ycpos_mode {
64 YCPOS_YCrYCb = 0,
65 YCPOS_YCbYCr = 1,
66 YCPOS_CbYCrY = 2,
67 YCPOS_CrYCbY = 3
68};
69
70/*
71 * struct prev_params - Structure for all configuration
72 * @busy: Bitmask of busy parameters (being updated or used)
73 * @update: Bitmask of the parameters to be updated
74 * @features: Set of features enabled.
75 * @cfa: CFA coefficients.
76 * @csup: Chroma suppression coefficients.
77 * @luma: Luma enhancement coefficients.
78 * @nf: Noise filter coefficients.
79 * @dcor: Noise filter coefficients.
80 * @gamma: Gamma coefficients.
81 * @wbal: White Balance parameters.
82 * @blkadj: Black adjustment parameters.
83 * @rgb2rgb: RGB blending parameters.
84 * @csc: Color space conversion (RGB to YCbCr) parameters.
85 * @hmed: Horizontal median filter.
86 * @yclimit: YC limits parameters.
87 * @contrast: Contrast.
88 * @brightness: Brightness.
89 */
90struct prev_params {
91 u32 busy;
92 u32 update;
93 u32 features;
94 struct omap3isp_prev_cfa cfa;
95 struct omap3isp_prev_csup csup;
96 struct omap3isp_prev_luma luma;
97 struct omap3isp_prev_nf nf;
98 struct omap3isp_prev_dcor dcor;
99 struct omap3isp_prev_gtables gamma;
100 struct omap3isp_prev_wbal wbal;
101 struct omap3isp_prev_blkadj blkadj;
102 struct omap3isp_prev_rgbtorgb rgb2rgb;
103 struct omap3isp_prev_csc csc;
104 struct omap3isp_prev_hmed hmed;
105 struct omap3isp_prev_yclimit yclimit;
106 u8 contrast;
107 u8 brightness;
108};
109
110/* Sink and source previewer pads */
111#define PREV_PAD_SINK 0
112#define PREV_PAD_SOURCE 1
113#define PREV_PADS_NUM 2
114
115/*
116 * struct isp_prev_device - Structure for storing ISP Preview module information
117 * @subdev: V4L2 subdevice
118 * @pads: Media entity pads
119 * @formats: Active formats at the subdev pad
120 * @crop: Active crop rectangle
121 * @input: Module currently connected to the input pad
122 * @output: Bitmask of the active output
123 * @video_in: Input video entity
124 * @video_out: Output video entity
125 * @params.params : Active and shadow parameters sets
126 * @params.active: Bitmask of parameters active in set 0
127 * @params.lock: Parameters lock, protects params.active and params.shadow
128 * @underrun: Whether the preview entity has queued buffers on the output
129 * @state: Current preview pipeline state
130 *
131 * This structure is used to store the OMAP ISP Preview module Information.
132 */
133struct isp_prev_device {
134 struct v4l2_subdev subdev;
135 struct media_pad pads[PREV_PADS_NUM];
136 struct v4l2_mbus_framefmt formats[PREV_PADS_NUM];
137 struct v4l2_rect crop;
138
139 struct v4l2_ctrl_handler ctrls;
140
141 enum preview_input_entity input;
142 unsigned int output;
143 struct isp_video video_in;
144 struct isp_video video_out;
145
146 struct {
147 unsigned int cfa_order;
148 struct prev_params params[2];
149 u32 active;
150 spinlock_t lock;
151 } params;
152
153 enum isp_pipeline_stream_state state;
154 wait_queue_head_t wait;
155 atomic_t stopping;
156};
157
158struct isp_device;
159
160int omap3isp_preview_init(struct isp_device *isp);
161void omap3isp_preview_cleanup(struct isp_device *isp);
162
163int omap3isp_preview_register_entities(struct isp_prev_device *prv,
164 struct v4l2_device *vdev);
165void omap3isp_preview_unregister_entities(struct isp_prev_device *prv);
166
167void omap3isp_preview_isr_frame_sync(struct isp_prev_device *prev);
168void omap3isp_preview_isr(struct isp_prev_device *prev);
169
170int omap3isp_preview_busy(struct isp_prev_device *isp_prev);
171
172void omap3isp_preview_restore_context(struct isp_device *isp);
173
174#endif /* OMAP3_ISP_PREVIEW_H */
diff --git a/drivers/media/video/omap3isp/ispqueue.c b/drivers/media/video/omap3isp/ispqueue.c
deleted file mode 100644
index 15bf3eab2224..000000000000
--- a/drivers/media/video/omap3isp/ispqueue.c
+++ /dev/null
@@ -1,1158 +0,0 @@
1/*
2 * ispqueue.c
3 *
4 * TI OMAP3 ISP - Video buffers queue handling
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 *
8 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
9 * Sakari Ailus <sakari.ailus@iki.fi>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23 * 02110-1301 USA
24 */
25
26#include <asm/cacheflush.h>
27#include <linux/dma-mapping.h>
28#include <linux/mm.h>
29#include <linux/pagemap.h>
30#include <linux/poll.h>
31#include <linux/scatterlist.h>
32#include <linux/sched.h>
33#include <linux/slab.h>
34#include <linux/vmalloc.h>
35
36#include "ispqueue.h"
37
38/* -----------------------------------------------------------------------------
39 * Video buffers management
40 */
41
42/*
43 * isp_video_buffer_cache_sync - Keep the buffers coherent between CPU and ISP
44 *
45 * The typical operation required here is Cache Invalidation across
46 * the (user space) buffer address range. And this _must_ be done
47 * at QBUF stage (and *only* at QBUF).
48 *
49 * We try to use optimal cache invalidation function:
50 * - dmac_map_area:
51 * - used when the number of pages are _low_.
52 * - it becomes quite slow as the number of pages increase.
53 * - for 648x492 viewfinder (150 pages) it takes 1.3 ms.
54 * - for 5 Mpix buffer (2491 pages) it takes between 25-50 ms.
55 *
56 * - flush_cache_all:
57 * - used when the number of pages are _high_.
58 * - time taken in the range of 500-900 us.
59 * - has a higher penalty but, as whole dcache + icache is invalidated
60 */
61/*
62 * FIXME: dmac_inv_range crashes randomly on the user space buffer
63 * address. Fall back to flush_cache_all for now.
64 */
65#define ISP_CACHE_FLUSH_PAGES_MAX 0
66
67static void isp_video_buffer_cache_sync(struct isp_video_buffer *buf)
68{
69 if (buf->skip_cache)
70 return;
71
72 if (buf->vbuf.m.userptr == 0 || buf->npages == 0 ||
73 buf->npages > ISP_CACHE_FLUSH_PAGES_MAX)
74 flush_cache_all();
75 else {
76 dmac_map_area((void *)buf->vbuf.m.userptr, buf->vbuf.length,
77 DMA_FROM_DEVICE);
78 outer_inv_range(buf->vbuf.m.userptr,
79 buf->vbuf.m.userptr + buf->vbuf.length);
80 }
81}
82
83/*
84 * isp_video_buffer_lock_vma - Prevent VMAs from being unmapped
85 *
86 * Lock the VMAs underlying the given buffer into memory. This avoids the
87 * userspace buffer mapping from being swapped out, making VIPT cache handling
88 * easier.
89 *
90 * Note that the pages will not be freed as the buffers have been locked to
91 * memory using by a call to get_user_pages(), but the userspace mapping could
92 * still disappear if the VMAs are not locked. This is caused by the memory
93 * management code trying to be as lock-less as possible, which results in the
94 * userspace mapping manager not finding out that the pages are locked under
95 * some conditions.
96 */
97static int isp_video_buffer_lock_vma(struct isp_video_buffer *buf, int lock)
98{
99 struct vm_area_struct *vma;
100 unsigned long start;
101 unsigned long end;
102 int ret = 0;
103
104 if (buf->vbuf.memory == V4L2_MEMORY_MMAP)
105 return 0;
106
107 /* We can be called from workqueue context if the current task dies to
108 * unlock the VMAs. In that case there's no current memory management
109 * context so unlocking can't be performed, but the VMAs have been or
110 * are getting destroyed anyway so it doesn't really matter.
111 */
112 if (!current || !current->mm)
113 return lock ? -EINVAL : 0;
114
115 start = buf->vbuf.m.userptr;
116 end = buf->vbuf.m.userptr + buf->vbuf.length - 1;
117
118 down_write(&current->mm->mmap_sem);
119 spin_lock(&current->mm->page_table_lock);
120
121 do {
122 vma = find_vma(current->mm, start);
123 if (vma == NULL) {
124 ret = -EFAULT;
125 goto out;
126 }
127
128 if (lock)
129 vma->vm_flags |= VM_LOCKED;
130 else
131 vma->vm_flags &= ~VM_LOCKED;
132
133 start = vma->vm_end + 1;
134 } while (vma->vm_end < end);
135
136 if (lock)
137 buf->vm_flags |= VM_LOCKED;
138 else
139 buf->vm_flags &= ~VM_LOCKED;
140
141out:
142 spin_unlock(&current->mm->page_table_lock);
143 up_write(&current->mm->mmap_sem);
144 return ret;
145}
146
147/*
148 * isp_video_buffer_sglist_kernel - Build a scatter list for a vmalloc'ed buffer
149 *
150 * Iterate over the vmalloc'ed area and create a scatter list entry for every
151 * page.
152 */
153static int isp_video_buffer_sglist_kernel(struct isp_video_buffer *buf)
154{
155 struct scatterlist *sglist;
156 unsigned int npages;
157 unsigned int i;
158 void *addr;
159
160 addr = buf->vaddr;
161 npages = PAGE_ALIGN(buf->vbuf.length) >> PAGE_SHIFT;
162
163 sglist = vmalloc(npages * sizeof(*sglist));
164 if (sglist == NULL)
165 return -ENOMEM;
166
167 sg_init_table(sglist, npages);
168
169 for (i = 0; i < npages; ++i, addr += PAGE_SIZE) {
170 struct page *page = vmalloc_to_page(addr);
171
172 if (page == NULL || PageHighMem(page)) {
173 vfree(sglist);
174 return -EINVAL;
175 }
176
177 sg_set_page(&sglist[i], page, PAGE_SIZE, 0);
178 }
179
180 buf->sglen = npages;
181 buf->sglist = sglist;
182
183 return 0;
184}
185
186/*
187 * isp_video_buffer_sglist_user - Build a scatter list for a userspace buffer
188 *
189 * Walk the buffer pages list and create a 1:1 mapping to a scatter list.
190 */
191static int isp_video_buffer_sglist_user(struct isp_video_buffer *buf)
192{
193 struct scatterlist *sglist;
194 unsigned int offset = buf->offset;
195 unsigned int i;
196
197 sglist = vmalloc(buf->npages * sizeof(*sglist));
198 if (sglist == NULL)
199 return -ENOMEM;
200
201 sg_init_table(sglist, buf->npages);
202
203 for (i = 0; i < buf->npages; ++i) {
204 if (PageHighMem(buf->pages[i])) {
205 vfree(sglist);
206 return -EINVAL;
207 }
208
209 sg_set_page(&sglist[i], buf->pages[i], PAGE_SIZE - offset,
210 offset);
211 offset = 0;
212 }
213
214 buf->sglen = buf->npages;
215 buf->sglist = sglist;
216
217 return 0;
218}
219
220/*
221 * isp_video_buffer_sglist_pfnmap - Build a scatter list for a VM_PFNMAP buffer
222 *
223 * Create a scatter list of physically contiguous pages starting at the buffer
224 * memory physical address.
225 */
226static int isp_video_buffer_sglist_pfnmap(struct isp_video_buffer *buf)
227{
228 struct scatterlist *sglist;
229 unsigned int offset = buf->offset;
230 unsigned long pfn = buf->paddr >> PAGE_SHIFT;
231 unsigned int i;
232
233 sglist = vmalloc(buf->npages * sizeof(*sglist));
234 if (sglist == NULL)
235 return -ENOMEM;
236
237 sg_init_table(sglist, buf->npages);
238
239 for (i = 0; i < buf->npages; ++i, ++pfn) {
240 sg_set_page(&sglist[i], pfn_to_page(pfn), PAGE_SIZE - offset,
241 offset);
242 /* PFNMAP buffers will not get DMA-mapped, set the DMA address
243 * manually.
244 */
245 sg_dma_address(&sglist[i]) = (pfn << PAGE_SHIFT) + offset;
246 offset = 0;
247 }
248
249 buf->sglen = buf->npages;
250 buf->sglist = sglist;
251
252 return 0;
253}
254
255/*
256 * isp_video_buffer_cleanup - Release pages for a userspace VMA.
257 *
258 * Release pages locked by a call isp_video_buffer_prepare_user and free the
259 * pages table.
260 */
261static void isp_video_buffer_cleanup(struct isp_video_buffer *buf)
262{
263 enum dma_data_direction direction;
264 unsigned int i;
265
266 if (buf->queue->ops->buffer_cleanup)
267 buf->queue->ops->buffer_cleanup(buf);
268
269 if (!(buf->vm_flags & VM_PFNMAP)) {
270 direction = buf->vbuf.type == V4L2_BUF_TYPE_VIDEO_CAPTURE
271 ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
272 dma_unmap_sg(buf->queue->dev, buf->sglist, buf->sglen,
273 direction);
274 }
275
276 vfree(buf->sglist);
277 buf->sglist = NULL;
278 buf->sglen = 0;
279
280 if (buf->pages != NULL) {
281 isp_video_buffer_lock_vma(buf, 0);
282
283 for (i = 0; i < buf->npages; ++i)
284 page_cache_release(buf->pages[i]);
285
286 vfree(buf->pages);
287 buf->pages = NULL;
288 }
289
290 buf->npages = 0;
291 buf->skip_cache = false;
292}
293
294/*
295 * isp_video_buffer_prepare_user - Pin userspace VMA pages to memory.
296 *
297 * This function creates a list of pages for a userspace VMA. The number of
298 * pages is first computed based on the buffer size, and pages are then
299 * retrieved by a call to get_user_pages.
300 *
301 * Pages are pinned to memory by get_user_pages, making them available for DMA
302 * transfers. However, due to memory management optimization, it seems the
303 * get_user_pages doesn't guarantee that the pinned pages will not be written
304 * to swap and removed from the userspace mapping(s). When this happens, a page
305 * fault can be generated when accessing those unmapped pages.
306 *
307 * If the fault is triggered by a page table walk caused by VIPT cache
308 * management operations, the page fault handler might oops if the MM semaphore
309 * is held, as it can't handle kernel page faults in that case. To fix that, a
310 * fixup entry needs to be added to the cache management code, or the userspace
311 * VMA must be locked to avoid removing pages from the userspace mapping in the
312 * first place.
313 *
314 * If the number of pages retrieved is smaller than the number required by the
315 * buffer size, the function returns -EFAULT.
316 */
317static int isp_video_buffer_prepare_user(struct isp_video_buffer *buf)
318{
319 unsigned long data;
320 unsigned int first;
321 unsigned int last;
322 int ret;
323
324 data = buf->vbuf.m.userptr;
325 first = (data & PAGE_MASK) >> PAGE_SHIFT;
326 last = ((data + buf->vbuf.length - 1) & PAGE_MASK) >> PAGE_SHIFT;
327
328 buf->offset = data & ~PAGE_MASK;
329 buf->npages = last - first + 1;
330 buf->pages = vmalloc(buf->npages * sizeof(buf->pages[0]));
331 if (buf->pages == NULL)
332 return -ENOMEM;
333
334 down_read(&current->mm->mmap_sem);
335 ret = get_user_pages(current, current->mm, data & PAGE_MASK,
336 buf->npages,
337 buf->vbuf.type == V4L2_BUF_TYPE_VIDEO_CAPTURE, 0,
338 buf->pages, NULL);
339 up_read(&current->mm->mmap_sem);
340
341 if (ret != buf->npages) {
342 buf->npages = ret < 0 ? 0 : ret;
343 isp_video_buffer_cleanup(buf);
344 return -EFAULT;
345 }
346
347 ret = isp_video_buffer_lock_vma(buf, 1);
348 if (ret < 0)
349 isp_video_buffer_cleanup(buf);
350
351 return ret;
352}
353
354/*
355 * isp_video_buffer_prepare_pfnmap - Validate a VM_PFNMAP userspace buffer
356 *
357 * Userspace VM_PFNMAP buffers are supported only if they are contiguous in
358 * memory and if they span a single VMA.
359 *
360 * Return 0 if the buffer is valid, or -EFAULT otherwise.
361 */
362static int isp_video_buffer_prepare_pfnmap(struct isp_video_buffer *buf)
363{
364 struct vm_area_struct *vma;
365 unsigned long prev_pfn;
366 unsigned long this_pfn;
367 unsigned long start;
368 unsigned long end;
369 dma_addr_t pa;
370 int ret = -EFAULT;
371
372 start = buf->vbuf.m.userptr;
373 end = buf->vbuf.m.userptr + buf->vbuf.length - 1;
374
375 buf->offset = start & ~PAGE_MASK;
376 buf->npages = (end >> PAGE_SHIFT) - (start >> PAGE_SHIFT) + 1;
377 buf->pages = NULL;
378
379 down_read(&current->mm->mmap_sem);
380 vma = find_vma(current->mm, start);
381 if (vma == NULL || vma->vm_end < end)
382 goto done;
383
384 for (prev_pfn = 0; start <= end; start += PAGE_SIZE) {
385 ret = follow_pfn(vma, start, &this_pfn);
386 if (ret)
387 goto done;
388
389 if (prev_pfn == 0)
390 pa = this_pfn << PAGE_SHIFT;
391 else if (this_pfn != prev_pfn + 1) {
392 ret = -EFAULT;
393 goto done;
394 }
395
396 prev_pfn = this_pfn;
397 }
398
399 buf->paddr = pa + buf->offset;
400 ret = 0;
401
402done:
403 up_read(&current->mm->mmap_sem);
404 return ret;
405}
406
407/*
408 * isp_video_buffer_prepare_vm_flags - Get VMA flags for a userspace address
409 *
410 * This function locates the VMAs for the buffer's userspace address and checks
411 * that their flags match. The only flag that we need to care for at the moment
412 * is VM_PFNMAP.
413 *
414 * The buffer vm_flags field is set to the first VMA flags.
415 *
416 * Return -EFAULT if no VMA can be found for part of the buffer, or if the VMAs
417 * have incompatible flags.
418 */
419static int isp_video_buffer_prepare_vm_flags(struct isp_video_buffer *buf)
420{
421 struct vm_area_struct *vma;
422 pgprot_t vm_page_prot;
423 unsigned long start;
424 unsigned long end;
425 int ret = -EFAULT;
426
427 start = buf->vbuf.m.userptr;
428 end = buf->vbuf.m.userptr + buf->vbuf.length - 1;
429
430 down_read(&current->mm->mmap_sem);
431
432 do {
433 vma = find_vma(current->mm, start);
434 if (vma == NULL)
435 goto done;
436
437 if (start == buf->vbuf.m.userptr) {
438 buf->vm_flags = vma->vm_flags;
439 vm_page_prot = vma->vm_page_prot;
440 }
441
442 if ((buf->vm_flags ^ vma->vm_flags) & VM_PFNMAP)
443 goto done;
444
445 if (vm_page_prot != vma->vm_page_prot)
446 goto done;
447
448 start = vma->vm_end + 1;
449 } while (vma->vm_end < end);
450
451 /* Skip cache management to enhance performances for non-cached or
452 * write-combining buffers.
453 */
454 if (vm_page_prot == pgprot_noncached(vm_page_prot) ||
455 vm_page_prot == pgprot_writecombine(vm_page_prot))
456 buf->skip_cache = true;
457
458 ret = 0;
459
460done:
461 up_read(&current->mm->mmap_sem);
462 return ret;
463}
464
465/*
466 * isp_video_buffer_prepare - Make a buffer ready for operation
467 *
468 * Preparing a buffer involves:
469 *
470 * - validating VMAs (userspace buffers only)
471 * - locking pages and VMAs into memory (userspace buffers only)
472 * - building page and scatter-gather lists
473 * - mapping buffers for DMA operation
474 * - performing driver-specific preparation
475 *
476 * The function must be called in userspace context with a valid mm context
477 * (this excludes cleanup paths such as sys_close when the userspace process
478 * segfaults).
479 */
480static int isp_video_buffer_prepare(struct isp_video_buffer *buf)
481{
482 enum dma_data_direction direction;
483 int ret;
484
485 switch (buf->vbuf.memory) {
486 case V4L2_MEMORY_MMAP:
487 ret = isp_video_buffer_sglist_kernel(buf);
488 break;
489
490 case V4L2_MEMORY_USERPTR:
491 ret = isp_video_buffer_prepare_vm_flags(buf);
492 if (ret < 0)
493 return ret;
494
495 if (buf->vm_flags & VM_PFNMAP) {
496 ret = isp_video_buffer_prepare_pfnmap(buf);
497 if (ret < 0)
498 return ret;
499
500 ret = isp_video_buffer_sglist_pfnmap(buf);
501 } else {
502 ret = isp_video_buffer_prepare_user(buf);
503 if (ret < 0)
504 return ret;
505
506 ret = isp_video_buffer_sglist_user(buf);
507 }
508 break;
509
510 default:
511 return -EINVAL;
512 }
513
514 if (ret < 0)
515 goto done;
516
517 if (!(buf->vm_flags & VM_PFNMAP)) {
518 direction = buf->vbuf.type == V4L2_BUF_TYPE_VIDEO_CAPTURE
519 ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
520 ret = dma_map_sg(buf->queue->dev, buf->sglist, buf->sglen,
521 direction);
522 if (ret != buf->sglen) {
523 ret = -EFAULT;
524 goto done;
525 }
526 }
527
528 if (buf->queue->ops->buffer_prepare)
529 ret = buf->queue->ops->buffer_prepare(buf);
530
531done:
532 if (ret < 0) {
533 isp_video_buffer_cleanup(buf);
534 return ret;
535 }
536
537 return ret;
538}
539
540/*
541 * isp_video_queue_query - Query the status of a given buffer
542 *
543 * Locking: must be called with the queue lock held.
544 */
545static void isp_video_buffer_query(struct isp_video_buffer *buf,
546 struct v4l2_buffer *vbuf)
547{
548 memcpy(vbuf, &buf->vbuf, sizeof(*vbuf));
549
550 if (buf->vma_use_count)
551 vbuf->flags |= V4L2_BUF_FLAG_MAPPED;
552
553 switch (buf->state) {
554 case ISP_BUF_STATE_ERROR:
555 vbuf->flags |= V4L2_BUF_FLAG_ERROR;
556 case ISP_BUF_STATE_DONE:
557 vbuf->flags |= V4L2_BUF_FLAG_DONE;
558 case ISP_BUF_STATE_QUEUED:
559 case ISP_BUF_STATE_ACTIVE:
560 vbuf->flags |= V4L2_BUF_FLAG_QUEUED;
561 break;
562 case ISP_BUF_STATE_IDLE:
563 default:
564 break;
565 }
566}
567
568/*
569 * isp_video_buffer_wait - Wait for a buffer to be ready
570 *
571 * In non-blocking mode, return immediately with 0 if the buffer is ready or
572 * -EAGAIN if the buffer is in the QUEUED or ACTIVE state.
573 *
574 * In blocking mode, wait (interruptibly but with no timeout) on the buffer wait
575 * queue using the same condition.
576 */
577static int isp_video_buffer_wait(struct isp_video_buffer *buf, int nonblocking)
578{
579 if (nonblocking) {
580 return (buf->state != ISP_BUF_STATE_QUEUED &&
581 buf->state != ISP_BUF_STATE_ACTIVE)
582 ? 0 : -EAGAIN;
583 }
584
585 return wait_event_interruptible(buf->wait,
586 buf->state != ISP_BUF_STATE_QUEUED &&
587 buf->state != ISP_BUF_STATE_ACTIVE);
588}
589
590/* -----------------------------------------------------------------------------
591 * Queue management
592 */
593
594/*
595 * isp_video_queue_free - Free video buffers memory
596 *
597 * Buffers can only be freed if the queue isn't streaming and if no buffer is
598 * mapped to userspace. Return -EBUSY if those conditions aren't statisfied.
599 *
600 * This function must be called with the queue lock held.
601 */
602static int isp_video_queue_free(struct isp_video_queue *queue)
603{
604 unsigned int i;
605
606 if (queue->streaming)
607 return -EBUSY;
608
609 for (i = 0; i < queue->count; ++i) {
610 if (queue->buffers[i]->vma_use_count != 0)
611 return -EBUSY;
612 }
613
614 for (i = 0; i < queue->count; ++i) {
615 struct isp_video_buffer *buf = queue->buffers[i];
616
617 isp_video_buffer_cleanup(buf);
618
619 vfree(buf->vaddr);
620 buf->vaddr = NULL;
621
622 kfree(buf);
623 queue->buffers[i] = NULL;
624 }
625
626 INIT_LIST_HEAD(&queue->queue);
627 queue->count = 0;
628 return 0;
629}
630
631/*
632 * isp_video_queue_alloc - Allocate video buffers memory
633 *
634 * This function must be called with the queue lock held.
635 */
636static int isp_video_queue_alloc(struct isp_video_queue *queue,
637 unsigned int nbuffers,
638 unsigned int size, enum v4l2_memory memory)
639{
640 struct isp_video_buffer *buf;
641 unsigned int i;
642 void *mem;
643 int ret;
644
645 /* Start by freeing the buffers. */
646 ret = isp_video_queue_free(queue);
647 if (ret < 0)
648 return ret;
649
650 /* Bail out if no buffers should be allocated. */
651 if (nbuffers == 0)
652 return 0;
653
654 /* Initialize the allocated buffers. */
655 for (i = 0; i < nbuffers; ++i) {
656 buf = kzalloc(queue->bufsize, GFP_KERNEL);
657 if (buf == NULL)
658 break;
659
660 if (memory == V4L2_MEMORY_MMAP) {
661 /* Allocate video buffers memory for mmap mode. Align
662 * the size to the page size.
663 */
664 mem = vmalloc_32_user(PAGE_ALIGN(size));
665 if (mem == NULL) {
666 kfree(buf);
667 break;
668 }
669
670 buf->vbuf.m.offset = i * PAGE_ALIGN(size);
671 buf->vaddr = mem;
672 }
673
674 buf->vbuf.index = i;
675 buf->vbuf.length = size;
676 buf->vbuf.type = queue->type;
677 buf->vbuf.field = V4L2_FIELD_NONE;
678 buf->vbuf.memory = memory;
679
680 buf->queue = queue;
681 init_waitqueue_head(&buf->wait);
682
683 queue->buffers[i] = buf;
684 }
685
686 if (i == 0)
687 return -ENOMEM;
688
689 queue->count = i;
690 return nbuffers;
691}
692
693/**
694 * omap3isp_video_queue_cleanup - Clean up the video buffers queue
695 * @queue: Video buffers queue
696 *
697 * Free all allocated resources and clean up the video buffers queue. The queue
698 * must not be busy (no ongoing video stream) and buffers must have been
699 * unmapped.
700 *
701 * Return 0 on success or -EBUSY if the queue is busy or buffers haven't been
702 * unmapped.
703 */
704int omap3isp_video_queue_cleanup(struct isp_video_queue *queue)
705{
706 return isp_video_queue_free(queue);
707}
708
709/**
710 * omap3isp_video_queue_init - Initialize the video buffers queue
711 * @queue: Video buffers queue
712 * @type: V4L2 buffer type (capture or output)
713 * @ops: Driver-specific queue operations
714 * @dev: Device used for DMA operations
715 * @bufsize: Size of the driver-specific buffer structure
716 *
717 * Initialize the video buffers queue with the supplied parameters.
718 *
719 * The queue type must be one of V4L2_BUF_TYPE_VIDEO_CAPTURE or
720 * V4L2_BUF_TYPE_VIDEO_OUTPUT. Other buffer types are not supported yet.
721 *
722 * Buffer objects will be allocated using the given buffer size to allow room
723 * for driver-specific fields. Driver-specific buffer structures must start
724 * with a struct isp_video_buffer field. Drivers with no driver-specific buffer
725 * structure must pass the size of the isp_video_buffer structure in the bufsize
726 * parameter.
727 *
728 * Return 0 on success.
729 */
730int omap3isp_video_queue_init(struct isp_video_queue *queue,
731 enum v4l2_buf_type type,
732 const struct isp_video_queue_operations *ops,
733 struct device *dev, unsigned int bufsize)
734{
735 INIT_LIST_HEAD(&queue->queue);
736 mutex_init(&queue->lock);
737 spin_lock_init(&queue->irqlock);
738
739 queue->type = type;
740 queue->ops = ops;
741 queue->dev = dev;
742 queue->bufsize = bufsize;
743
744 return 0;
745}
746
747/* -----------------------------------------------------------------------------
748 * V4L2 operations
749 */
750
751/**
752 * omap3isp_video_queue_reqbufs - Allocate video buffers memory
753 *
754 * This function is intended to be used as a VIDIOC_REQBUFS ioctl handler. It
755 * allocated video buffer objects and, for MMAP buffers, buffer memory.
756 *
757 * If the number of buffers is 0, all buffers are freed and the function returns
758 * without performing any allocation.
759 *
760 * If the number of buffers is not 0, currently allocated buffers (if any) are
761 * freed and the requested number of buffers are allocated. Depending on
762 * driver-specific requirements and on memory availability, a number of buffer
763 * smaller or bigger than requested can be allocated. This isn't considered as
764 * an error.
765 *
766 * Return 0 on success or one of the following error codes:
767 *
768 * -EINVAL if the buffer type or index are invalid
769 * -EBUSY if the queue is busy (streaming or buffers mapped)
770 * -ENOMEM if the buffers can't be allocated due to an out-of-memory condition
771 */
772int omap3isp_video_queue_reqbufs(struct isp_video_queue *queue,
773 struct v4l2_requestbuffers *rb)
774{
775 unsigned int nbuffers = rb->count;
776 unsigned int size;
777 int ret;
778
779 if (rb->type != queue->type)
780 return -EINVAL;
781
782 queue->ops->queue_prepare(queue, &nbuffers, &size);
783 if (size == 0)
784 return -EINVAL;
785
786 nbuffers = min_t(unsigned int, nbuffers, ISP_VIDEO_MAX_BUFFERS);
787
788 mutex_lock(&queue->lock);
789
790 ret = isp_video_queue_alloc(queue, nbuffers, size, rb->memory);
791 if (ret < 0)
792 goto done;
793
794 rb->count = ret;
795 ret = 0;
796
797done:
798 mutex_unlock(&queue->lock);
799 return ret;
800}
801
802/**
803 * omap3isp_video_queue_querybuf - Query the status of a buffer in a queue
804 *
805 * This function is intended to be used as a VIDIOC_QUERYBUF ioctl handler. It
806 * returns the status of a given video buffer.
807 *
808 * Return 0 on success or -EINVAL if the buffer type or index are invalid.
809 */
810int omap3isp_video_queue_querybuf(struct isp_video_queue *queue,
811 struct v4l2_buffer *vbuf)
812{
813 struct isp_video_buffer *buf;
814 int ret = 0;
815
816 if (vbuf->type != queue->type)
817 return -EINVAL;
818
819 mutex_lock(&queue->lock);
820
821 if (vbuf->index >= queue->count) {
822 ret = -EINVAL;
823 goto done;
824 }
825
826 buf = queue->buffers[vbuf->index];
827 isp_video_buffer_query(buf, vbuf);
828
829done:
830 mutex_unlock(&queue->lock);
831 return ret;
832}
833
834/**
835 * omap3isp_video_queue_qbuf - Queue a buffer
836 *
837 * This function is intended to be used as a VIDIOC_QBUF ioctl handler.
838 *
839 * The v4l2_buffer structure passed from userspace is first sanity tested. If
840 * sane, the buffer is then processed and added to the main queue and, if the
841 * queue is streaming, to the IRQ queue.
842 *
843 * Before being enqueued, USERPTR buffers are checked for address changes. If
844 * the buffer has a different userspace address, the old memory area is unlocked
845 * and the new memory area is locked.
846 */
847int omap3isp_video_queue_qbuf(struct isp_video_queue *queue,
848 struct v4l2_buffer *vbuf)
849{
850 struct isp_video_buffer *buf;
851 unsigned long flags;
852 int ret = -EINVAL;
853
854 if (vbuf->type != queue->type)
855 goto done;
856
857 mutex_lock(&queue->lock);
858
859 if (vbuf->index >= queue->count)
860 goto done;
861
862 buf = queue->buffers[vbuf->index];
863
864 if (vbuf->memory != buf->vbuf.memory)
865 goto done;
866
867 if (buf->state != ISP_BUF_STATE_IDLE)
868 goto done;
869
870 if (vbuf->memory == V4L2_MEMORY_USERPTR &&
871 vbuf->length < buf->vbuf.length)
872 goto done;
873
874 if (vbuf->memory == V4L2_MEMORY_USERPTR &&
875 vbuf->m.userptr != buf->vbuf.m.userptr) {
876 isp_video_buffer_cleanup(buf);
877 buf->vbuf.m.userptr = vbuf->m.userptr;
878 buf->prepared = 0;
879 }
880
881 if (!buf->prepared) {
882 ret = isp_video_buffer_prepare(buf);
883 if (ret < 0)
884 goto done;
885 buf->prepared = 1;
886 }
887
888 isp_video_buffer_cache_sync(buf);
889
890 buf->state = ISP_BUF_STATE_QUEUED;
891 list_add_tail(&buf->stream, &queue->queue);
892
893 if (queue->streaming) {
894 spin_lock_irqsave(&queue->irqlock, flags);
895 queue->ops->buffer_queue(buf);
896 spin_unlock_irqrestore(&queue->irqlock, flags);
897 }
898
899 ret = 0;
900
901done:
902 mutex_unlock(&queue->lock);
903 return ret;
904}
905
906/**
907 * omap3isp_video_queue_dqbuf - Dequeue a buffer
908 *
909 * This function is intended to be used as a VIDIOC_DQBUF ioctl handler.
910 *
911 * Wait until a buffer is ready to be dequeued, remove it from the queue and
912 * copy its information to the v4l2_buffer structure.
913 *
914 * If the nonblocking argument is not zero and no buffer is ready, return
915 * -EAGAIN immediately instead of waiting.
916 *
917 * If no buffer has been enqueued, or if the requested buffer type doesn't match
918 * the queue type, return -EINVAL.
919 */
920int omap3isp_video_queue_dqbuf(struct isp_video_queue *queue,
921 struct v4l2_buffer *vbuf, int nonblocking)
922{
923 struct isp_video_buffer *buf;
924 int ret;
925
926 if (vbuf->type != queue->type)
927 return -EINVAL;
928
929 mutex_lock(&queue->lock);
930
931 if (list_empty(&queue->queue)) {
932 ret = -EINVAL;
933 goto done;
934 }
935
936 buf = list_first_entry(&queue->queue, struct isp_video_buffer, stream);
937 ret = isp_video_buffer_wait(buf, nonblocking);
938 if (ret < 0)
939 goto done;
940
941 list_del(&buf->stream);
942
943 isp_video_buffer_query(buf, vbuf);
944 buf->state = ISP_BUF_STATE_IDLE;
945 vbuf->flags &= ~V4L2_BUF_FLAG_QUEUED;
946
947done:
948 mutex_unlock(&queue->lock);
949 return ret;
950}
951
952/**
953 * omap3isp_video_queue_streamon - Start streaming
954 *
955 * This function is intended to be used as a VIDIOC_STREAMON ioctl handler. It
956 * starts streaming on the queue and calls the buffer_queue operation for all
957 * queued buffers.
958 *
959 * Return 0 on success.
960 */
961int omap3isp_video_queue_streamon(struct isp_video_queue *queue)
962{
963 struct isp_video_buffer *buf;
964 unsigned long flags;
965
966 mutex_lock(&queue->lock);
967
968 if (queue->streaming)
969 goto done;
970
971 queue->streaming = 1;
972
973 spin_lock_irqsave(&queue->irqlock, flags);
974 list_for_each_entry(buf, &queue->queue, stream)
975 queue->ops->buffer_queue(buf);
976 spin_unlock_irqrestore(&queue->irqlock, flags);
977
978done:
979 mutex_unlock(&queue->lock);
980 return 0;
981}
982
983/**
984 * omap3isp_video_queue_streamoff - Stop streaming
985 *
986 * This function is intended to be used as a VIDIOC_STREAMOFF ioctl handler. It
987 * stops streaming on the queue and wakes up all the buffers.
988 *
989 * Drivers must stop the hardware and synchronize with interrupt handlers and/or
990 * delayed works before calling this function to make sure no buffer will be
991 * touched by the driver and/or hardware.
992 */
993void omap3isp_video_queue_streamoff(struct isp_video_queue *queue)
994{
995 struct isp_video_buffer *buf;
996 unsigned long flags;
997 unsigned int i;
998
999 mutex_lock(&queue->lock);
1000
1001 if (!queue->streaming)
1002 goto done;
1003
1004 queue->streaming = 0;
1005
1006 spin_lock_irqsave(&queue->irqlock, flags);
1007 for (i = 0; i < queue->count; ++i) {
1008 buf = queue->buffers[i];
1009
1010 if (buf->state == ISP_BUF_STATE_ACTIVE)
1011 wake_up(&buf->wait);
1012
1013 buf->state = ISP_BUF_STATE_IDLE;
1014 }
1015 spin_unlock_irqrestore(&queue->irqlock, flags);
1016
1017 INIT_LIST_HEAD(&queue->queue);
1018
1019done:
1020 mutex_unlock(&queue->lock);
1021}
1022
1023/**
1024 * omap3isp_video_queue_discard_done - Discard all buffers marked as DONE
1025 *
1026 * This function is intended to be used with suspend/resume operations. It
1027 * discards all 'done' buffers as they would be too old to be requested after
1028 * resume.
1029 *
1030 * Drivers must stop the hardware and synchronize with interrupt handlers and/or
1031 * delayed works before calling this function to make sure no buffer will be
1032 * touched by the driver and/or hardware.
1033 */
1034void omap3isp_video_queue_discard_done(struct isp_video_queue *queue)
1035{
1036 struct isp_video_buffer *buf;
1037 unsigned int i;
1038
1039 mutex_lock(&queue->lock);
1040
1041 if (!queue->streaming)
1042 goto done;
1043
1044 for (i = 0; i < queue->count; ++i) {
1045 buf = queue->buffers[i];
1046
1047 if (buf->state == ISP_BUF_STATE_DONE)
1048 buf->state = ISP_BUF_STATE_ERROR;
1049 }
1050
1051done:
1052 mutex_unlock(&queue->lock);
1053}
1054
1055static void isp_video_queue_vm_open(struct vm_area_struct *vma)
1056{
1057 struct isp_video_buffer *buf = vma->vm_private_data;
1058
1059 buf->vma_use_count++;
1060}
1061
1062static void isp_video_queue_vm_close(struct vm_area_struct *vma)
1063{
1064 struct isp_video_buffer *buf = vma->vm_private_data;
1065
1066 buf->vma_use_count--;
1067}
1068
1069static const struct vm_operations_struct isp_video_queue_vm_ops = {
1070 .open = isp_video_queue_vm_open,
1071 .close = isp_video_queue_vm_close,
1072};
1073
1074/**
1075 * omap3isp_video_queue_mmap - Map buffers to userspace
1076 *
1077 * This function is intended to be used as an mmap() file operation handler. It
1078 * maps a buffer to userspace based on the VMA offset.
1079 *
1080 * Only buffers of memory type MMAP are supported.
1081 */
1082int omap3isp_video_queue_mmap(struct isp_video_queue *queue,
1083 struct vm_area_struct *vma)
1084{
1085 struct isp_video_buffer *uninitialized_var(buf);
1086 unsigned long size;
1087 unsigned int i;
1088 int ret = 0;
1089
1090 mutex_lock(&queue->lock);
1091
1092 for (i = 0; i < queue->count; ++i) {
1093 buf = queue->buffers[i];
1094 if ((buf->vbuf.m.offset >> PAGE_SHIFT) == vma->vm_pgoff)
1095 break;
1096 }
1097
1098 if (i == queue->count) {
1099 ret = -EINVAL;
1100 goto done;
1101 }
1102
1103 size = vma->vm_end - vma->vm_start;
1104
1105 if (buf->vbuf.memory != V4L2_MEMORY_MMAP ||
1106 size != PAGE_ALIGN(buf->vbuf.length)) {
1107 ret = -EINVAL;
1108 goto done;
1109 }
1110
1111 ret = remap_vmalloc_range(vma, buf->vaddr, 0);
1112 if (ret < 0)
1113 goto done;
1114
1115 vma->vm_ops = &isp_video_queue_vm_ops;
1116 vma->vm_private_data = buf;
1117 isp_video_queue_vm_open(vma);
1118
1119done:
1120 mutex_unlock(&queue->lock);
1121 return ret;
1122}
1123
1124/**
1125 * omap3isp_video_queue_poll - Poll video queue state
1126 *
1127 * This function is intended to be used as a poll() file operation handler. It
1128 * polls the state of the video buffer at the front of the queue and returns an
1129 * events mask.
1130 *
1131 * If no buffer is present at the front of the queue, POLLERR is returned.
1132 */
1133unsigned int omap3isp_video_queue_poll(struct isp_video_queue *queue,
1134 struct file *file, poll_table *wait)
1135{
1136 struct isp_video_buffer *buf;
1137 unsigned int mask = 0;
1138
1139 mutex_lock(&queue->lock);
1140 if (list_empty(&queue->queue)) {
1141 mask |= POLLERR;
1142 goto done;
1143 }
1144 buf = list_first_entry(&queue->queue, struct isp_video_buffer, stream);
1145
1146 poll_wait(file, &buf->wait, wait);
1147 if (buf->state == ISP_BUF_STATE_DONE ||
1148 buf->state == ISP_BUF_STATE_ERROR) {
1149 if (queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1150 mask |= POLLIN | POLLRDNORM;
1151 else
1152 mask |= POLLOUT | POLLWRNORM;
1153 }
1154
1155done:
1156 mutex_unlock(&queue->lock);
1157 return mask;
1158}
diff --git a/drivers/media/video/omap3isp/ispqueue.h b/drivers/media/video/omap3isp/ispqueue.h
deleted file mode 100644
index 908dfd712e8e..000000000000
--- a/drivers/media/video/omap3isp/ispqueue.h
+++ /dev/null
@@ -1,187 +0,0 @@
1/*
2 * ispqueue.h
3 *
4 * TI OMAP3 ISP - Video buffers queue handling
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 *
8 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
9 * Sakari Ailus <sakari.ailus@iki.fi>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23 * 02110-1301 USA
24 */
25
26#ifndef OMAP3_ISP_QUEUE_H
27#define OMAP3_ISP_QUEUE_H
28
29#include <linux/kernel.h>
30#include <linux/list.h>
31#include <linux/mutex.h>
32#include <linux/videodev2.h>
33#include <linux/wait.h>
34
35struct isp_video_queue;
36struct page;
37struct scatterlist;
38
39#define ISP_VIDEO_MAX_BUFFERS 16
40
41/**
42 * enum isp_video_buffer_state - ISP video buffer state
43 * @ISP_BUF_STATE_IDLE: The buffer is under userspace control (dequeued
44 * or not queued yet).
45 * @ISP_BUF_STATE_QUEUED: The buffer has been queued but isn't used by the
46 * device yet.
47 * @ISP_BUF_STATE_ACTIVE: The buffer is in use for an active video transfer.
48 * @ISP_BUF_STATE_ERROR: The device is done with the buffer and an error
49 * occurred. For capture device the buffer likely contains corrupted data or
50 * no data at all.
51 * @ISP_BUF_STATE_DONE: The device is done with the buffer and no error occurred.
52 * For capture devices the buffer contains valid data.
53 */
54enum isp_video_buffer_state {
55 ISP_BUF_STATE_IDLE,
56 ISP_BUF_STATE_QUEUED,
57 ISP_BUF_STATE_ACTIVE,
58 ISP_BUF_STATE_ERROR,
59 ISP_BUF_STATE_DONE,
60};
61
62/**
63 * struct isp_video_buffer - ISP video buffer
64 * @vma_use_count: Number of times the buffer is mmap'ed to userspace
65 * @stream: List head for insertion into main queue
66 * @queue: ISP buffers queue this buffer belongs to
67 * @prepared: Whether the buffer has been prepared
68 * @skip_cache: Whether to skip cache management operations for this buffer
69 * @vaddr: Memory virtual address (for kernel buffers)
70 * @vm_flags: Buffer VMA flags (for userspace buffers)
71 * @offset: Offset inside the first page (for userspace buffers)
72 * @npages: Number of pages (for userspace buffers)
73 * @pages: Pages table (for userspace non-VM_PFNMAP buffers)
74 * @paddr: Memory physical address (for userspace VM_PFNMAP buffers)
75 * @sglen: Number of elements in the scatter list (for non-VM_PFNMAP buffers)
76 * @sglist: Scatter list (for non-VM_PFNMAP buffers)
77 * @vbuf: V4L2 buffer
78 * @irqlist: List head for insertion into IRQ queue
79 * @state: Current buffer state
80 * @wait: Wait queue to signal buffer completion
81 */
82struct isp_video_buffer {
83 unsigned long vma_use_count;
84 struct list_head stream;
85 struct isp_video_queue *queue;
86 unsigned int prepared:1;
87 bool skip_cache;
88
89 /* For kernel buffers. */
90 void *vaddr;
91
92 /* For userspace buffers. */
93 vm_flags_t vm_flags;
94 unsigned long offset;
95 unsigned int npages;
96 struct page **pages;
97 dma_addr_t paddr;
98
99 /* For all buffers except VM_PFNMAP. */
100 unsigned int sglen;
101 struct scatterlist *sglist;
102
103 /* Touched by the interrupt handler. */
104 struct v4l2_buffer vbuf;
105 struct list_head irqlist;
106 enum isp_video_buffer_state state;
107 wait_queue_head_t wait;
108};
109
110#define to_isp_video_buffer(vb) container_of(vb, struct isp_video_buffer, vb)
111
112/**
113 * struct isp_video_queue_operations - Driver-specific operations
114 * @queue_prepare: Called before allocating buffers. Drivers should clamp the
115 * number of buffers according to their requirements, and must return the
116 * buffer size in bytes.
117 * @buffer_prepare: Called the first time a buffer is queued, or after changing
118 * the userspace memory address for a USERPTR buffer, with the queue lock
119 * held. Drivers should perform device-specific buffer preparation (such as
120 * mapping the buffer memory in an IOMMU). This operation is optional.
121 * @buffer_queue: Called when a buffer is being added to the queue with the
122 * queue irqlock spinlock held.
123 * @buffer_cleanup: Called before freeing buffers, or before changing the
124 * userspace memory address for a USERPTR buffer, with the queue lock held.
125 * Drivers must perform cleanup operations required to undo the
126 * buffer_prepare call. This operation is optional.
127 */
128struct isp_video_queue_operations {
129 void (*queue_prepare)(struct isp_video_queue *queue,
130 unsigned int *nbuffers, unsigned int *size);
131 int (*buffer_prepare)(struct isp_video_buffer *buf);
132 void (*buffer_queue)(struct isp_video_buffer *buf);
133 void (*buffer_cleanup)(struct isp_video_buffer *buf);
134};
135
136/**
137 * struct isp_video_queue - ISP video buffers queue
138 * @type: Type of video buffers handled by this queue
139 * @ops: Queue operations
140 * @dev: Device used for DMA operations
141 * @bufsize: Size of a driver-specific buffer object
142 * @count: Number of currently allocated buffers
143 * @buffers: ISP video buffers
144 * @lock: Mutex to protect access to the buffers, main queue and state
145 * @irqlock: Spinlock to protect access to the IRQ queue
146 * @streaming: Queue state, indicates whether the queue is streaming
147 * @queue: List of all queued buffers
148 */
149struct isp_video_queue {
150 enum v4l2_buf_type type;
151 const struct isp_video_queue_operations *ops;
152 struct device *dev;
153 unsigned int bufsize;
154
155 unsigned int count;
156 struct isp_video_buffer *buffers[ISP_VIDEO_MAX_BUFFERS];
157 struct mutex lock;
158 spinlock_t irqlock;
159
160 unsigned int streaming:1;
161
162 struct list_head queue;
163};
164
165int omap3isp_video_queue_cleanup(struct isp_video_queue *queue);
166int omap3isp_video_queue_init(struct isp_video_queue *queue,
167 enum v4l2_buf_type type,
168 const struct isp_video_queue_operations *ops,
169 struct device *dev, unsigned int bufsize);
170
171int omap3isp_video_queue_reqbufs(struct isp_video_queue *queue,
172 struct v4l2_requestbuffers *rb);
173int omap3isp_video_queue_querybuf(struct isp_video_queue *queue,
174 struct v4l2_buffer *vbuf);
175int omap3isp_video_queue_qbuf(struct isp_video_queue *queue,
176 struct v4l2_buffer *vbuf);
177int omap3isp_video_queue_dqbuf(struct isp_video_queue *queue,
178 struct v4l2_buffer *vbuf, int nonblocking);
179int omap3isp_video_queue_streamon(struct isp_video_queue *queue);
180void omap3isp_video_queue_streamoff(struct isp_video_queue *queue);
181void omap3isp_video_queue_discard_done(struct isp_video_queue *queue);
182int omap3isp_video_queue_mmap(struct isp_video_queue *queue,
183 struct vm_area_struct *vma);
184unsigned int omap3isp_video_queue_poll(struct isp_video_queue *queue,
185 struct file *file, poll_table *wait);
186
187#endif /* OMAP3_ISP_QUEUE_H */
diff --git a/drivers/media/video/omap3isp/ispreg.h b/drivers/media/video/omap3isp/ispreg.h
deleted file mode 100644
index 084ea77d65a7..000000000000
--- a/drivers/media/video/omap3isp/ispreg.h
+++ /dev/null
@@ -1,1586 +0,0 @@
1/*
2 * ispreg.h
3 *
4 * TI OMAP3 ISP - Registers definitions
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc
8 *
9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 * Sakari Ailus <sakari.ailus@iki.fi>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 */
26
27#ifndef OMAP3_ISP_REG_H
28#define OMAP3_ISP_REG_H
29
30#include <plat/omap34xx.h>
31
32
33#define CM_CAM_MCLK_HZ 172800000 /* Hz */
34
35/* ISP Submodules offset */
36
37#define OMAP3ISP_REG_BASE OMAP3430_ISP_BASE
38#define OMAP3ISP_REG(offset) (OMAP3ISP_REG_BASE + (offset))
39
40#define OMAP3ISP_CCP2_REG_OFFSET 0x0400
41#define OMAP3ISP_CCP2_REG_BASE (OMAP3ISP_REG_BASE + \
42 OMAP3ISP_CCP2_REG_OFFSET)
43#define OMAP3ISP_CCP2_REG(offset) (OMAP3ISP_CCP2_REG_BASE + (offset))
44
45#define OMAP3ISP_CCDC_REG_OFFSET 0x0600
46#define OMAP3ISP_CCDC_REG_BASE (OMAP3ISP_REG_BASE + \
47 OMAP3ISP_CCDC_REG_OFFSET)
48#define OMAP3ISP_CCDC_REG(offset) (OMAP3ISP_CCDC_REG_BASE + (offset))
49
50#define OMAP3ISP_HIST_REG_OFFSET 0x0A00
51#define OMAP3ISP_HIST_REG_BASE (OMAP3ISP_REG_BASE + \
52 OMAP3ISP_HIST_REG_OFFSET)
53#define OMAP3ISP_HIST_REG(offset) (OMAP3ISP_HIST_REG_BASE + (offset))
54
55#define OMAP3ISP_H3A_REG_OFFSET 0x0C00
56#define OMAP3ISP_H3A_REG_BASE (OMAP3ISP_REG_BASE + \
57 OMAP3ISP_H3A_REG_OFFSET)
58#define OMAP3ISP_H3A_REG(offset) (OMAP3ISP_H3A_REG_BASE + (offset))
59
60#define OMAP3ISP_PREV_REG_OFFSET 0x0E00
61#define OMAP3ISP_PREV_REG_BASE (OMAP3ISP_REG_BASE + \
62 OMAP3ISP_PREV_REG_OFFSET)
63#define OMAP3ISP_PREV_REG(offset) (OMAP3ISP_PREV_REG_BASE + (offset))
64
65#define OMAP3ISP_RESZ_REG_OFFSET 0x1000
66#define OMAP3ISP_RESZ_REG_BASE (OMAP3ISP_REG_BASE + \
67 OMAP3ISP_RESZ_REG_OFFSET)
68#define OMAP3ISP_RESZ_REG(offset) (OMAP3ISP_RESZ_REG_BASE + (offset))
69
70#define OMAP3ISP_SBL_REG_OFFSET 0x1200
71#define OMAP3ISP_SBL_REG_BASE (OMAP3ISP_REG_BASE + \
72 OMAP3ISP_SBL_REG_OFFSET)
73#define OMAP3ISP_SBL_REG(offset) (OMAP3ISP_SBL_REG_BASE + (offset))
74
75#define OMAP3ISP_CSI2A_REGS1_REG_OFFSET 0x1800
76#define OMAP3ISP_CSI2A_REGS1_REG_BASE (OMAP3ISP_REG_BASE + \
77 OMAP3ISP_CSI2A_REGS1_REG_OFFSET)
78#define OMAP3ISP_CSI2A_REGS1_REG(offset) \
79 (OMAP3ISP_CSI2A_REGS1_REG_BASE + (offset))
80
81#define OMAP3ISP_CSIPHY2_REG_OFFSET 0x1970
82#define OMAP3ISP_CSIPHY2_REG_BASE (OMAP3ISP_REG_BASE + \
83 OMAP3ISP_CSIPHY2_REG_OFFSET)
84#define OMAP3ISP_CSIPHY2_REG(offset) (OMAP3ISP_CSIPHY2_REG_BASE + (offset))
85
86#define OMAP3ISP_CSI2A_REGS2_REG_OFFSET 0x19C0
87#define OMAP3ISP_CSI2A_REGS2_REG_BASE (OMAP3ISP_REG_BASE + \
88 OMAP3ISP_CSI2A_REGS2_REG_OFFSET)
89#define OMAP3ISP_CSI2A_REGS2_REG(offset) \
90 (OMAP3ISP_CSI2A_REGS2_REG_BASE + (offset))
91
92#define OMAP3ISP_CSI2C_REGS1_REG_OFFSET 0x1C00
93#define OMAP3ISP_CSI2C_REGS1_REG_BASE (OMAP3ISP_REG_BASE + \
94 OMAP3ISP_CSI2C_REGS1_REG_OFFSET)
95#define OMAP3ISP_CSI2C_REGS1_REG(offset) \
96 (OMAP3ISP_CSI2C_REGS1_REG_BASE + (offset))
97
98#define OMAP3ISP_CSIPHY1_REG_OFFSET 0x1D70
99#define OMAP3ISP_CSIPHY1_REG_BASE (OMAP3ISP_REG_BASE + \
100 OMAP3ISP_CSIPHY1_REG_OFFSET)
101#define OMAP3ISP_CSIPHY1_REG(offset) (OMAP3ISP_CSIPHY1_REG_BASE + (offset))
102
103#define OMAP3ISP_CSI2C_REGS2_REG_OFFSET 0x1DC0
104#define OMAP3ISP_CSI2C_REGS2_REG_BASE (OMAP3ISP_REG_BASE + \
105 OMAP3ISP_CSI2C_REGS2_REG_OFFSET)
106#define OMAP3ISP_CSI2C_REGS2_REG(offset) \
107 (OMAP3ISP_CSI2C_REGS2_REG_BASE + (offset))
108
109/* ISP module register offset */
110
111#define ISP_REVISION (0x000)
112#define ISP_SYSCONFIG (0x004)
113#define ISP_SYSSTATUS (0x008)
114#define ISP_IRQ0ENABLE (0x00C)
115#define ISP_IRQ0STATUS (0x010)
116#define ISP_IRQ1ENABLE (0x014)
117#define ISP_IRQ1STATUS (0x018)
118#define ISP_TCTRL_GRESET_LENGTH (0x030)
119#define ISP_TCTRL_PSTRB_REPLAY (0x034)
120#define ISP_CTRL (0x040)
121#define ISP_SECURE (0x044)
122#define ISP_TCTRL_CTRL (0x050)
123#define ISP_TCTRL_FRAME (0x054)
124#define ISP_TCTRL_PSTRB_DELAY (0x058)
125#define ISP_TCTRL_STRB_DELAY (0x05C)
126#define ISP_TCTRL_SHUT_DELAY (0x060)
127#define ISP_TCTRL_PSTRB_LENGTH (0x064)
128#define ISP_TCTRL_STRB_LENGTH (0x068)
129#define ISP_TCTRL_SHUT_LENGTH (0x06C)
130#define ISP_PING_PONG_ADDR (0x070)
131#define ISP_PING_PONG_MEM_RANGE (0x074)
132#define ISP_PING_PONG_BUF_SIZE (0x078)
133
134/* CCP2 receiver registers */
135
136#define ISPCCP2_REVISION (0x000)
137#define ISPCCP2_SYSCONFIG (0x004)
138#define ISPCCP2_SYSCONFIG_SOFT_RESET (1 << 1)
139#define ISPCCP2_SYSCONFIG_AUTO_IDLE 0x1
140#define ISPCCP2_SYSCONFIG_MSTANDBY_MODE_SHIFT 12
141#define ISPCCP2_SYSCONFIG_MSTANDBY_MODE_FORCE \
142 (0x0 << ISPCCP2_SYSCONFIG_MSTANDBY_MODE_SHIFT)
143#define ISPCCP2_SYSCONFIG_MSTANDBY_MODE_NO \
144 (0x1 << ISPCCP2_SYSCONFIG_MSTANDBY_MODE_SHIFT)
145#define ISPCCP2_SYSCONFIG_MSTANDBY_MODE_SMART \
146 (0x2 << ISPCCP2_SYSCONFIG_MSTANDBY_MODE_SHIFT)
147#define ISPCCP2_SYSSTATUS (0x008)
148#define ISPCCP2_SYSSTATUS_RESET_DONE (1 << 0)
149#define ISPCCP2_LC01_IRQENABLE (0x00C)
150#define ISPCCP2_LC01_IRQSTATUS (0x010)
151#define ISPCCP2_LC01_IRQSTATUS_LC0_FS_IRQ (1 << 11)
152#define ISPCCP2_LC01_IRQSTATUS_LC0_LE_IRQ (1 << 10)
153#define ISPCCP2_LC01_IRQSTATUS_LC0_LS_IRQ (1 << 9)
154#define ISPCCP2_LC01_IRQSTATUS_LC0_FE_IRQ (1 << 8)
155#define ISPCCP2_LC01_IRQSTATUS_LC0_COUNT_IRQ (1 << 7)
156#define ISPCCP2_LC01_IRQSTATUS_LC0_FIFO_OVF_IRQ (1 << 5)
157#define ISPCCP2_LC01_IRQSTATUS_LC0_CRC_IRQ (1 << 4)
158#define ISPCCP2_LC01_IRQSTATUS_LC0_FSP_IRQ (1 << 3)
159#define ISPCCP2_LC01_IRQSTATUS_LC0_FW_IRQ (1 << 2)
160#define ISPCCP2_LC01_IRQSTATUS_LC0_FSC_IRQ (1 << 1)
161#define ISPCCP2_LC01_IRQSTATUS_LC0_SSC_IRQ (1 << 0)
162
163#define ISPCCP2_LC23_IRQENABLE (0x014)
164#define ISPCCP2_LC23_IRQSTATUS (0x018)
165#define ISPCCP2_LCM_IRQENABLE (0x02C)
166#define ISPCCP2_LCM_IRQSTATUS_EOF_IRQ (1 << 0)
167#define ISPCCP2_LCM_IRQSTATUS_OCPERROR_IRQ (1 << 1)
168#define ISPCCP2_LCM_IRQSTATUS (0x030)
169#define ISPCCP2_CTRL (0x040)
170#define ISPCCP2_CTRL_IF_EN (1 << 0)
171#define ISPCCP2_CTRL_PHY_SEL (1 << 1)
172#define ISPCCP2_CTRL_PHY_SEL_CLOCK (0 << 1)
173#define ISPCCP2_CTRL_PHY_SEL_STROBE (1 << 1)
174#define ISPCCP2_CTRL_PHY_SEL_MASK 0x1
175#define ISPCCP2_CTRL_PHY_SEL_SHIFT 1
176#define ISPCCP2_CTRL_IO_OUT_SEL (1 << 2)
177#define ISPCCP2_CTRL_MODE (1 << 4)
178#define ISPCCP2_CTRL_VP_CLK_FORCE_ON (1 << 9)
179#define ISPCCP2_CTRL_INV (1 << 10)
180#define ISPCCP2_CTRL_INV_MASK 0x1
181#define ISPCCP2_CTRL_INV_SHIFT 10
182#define ISPCCP2_CTRL_VP_ONLY_EN (1 << 11)
183#define ISPCCP2_CTRL_VP_CLK_POL (1 << 12)
184#define ISPCCP2_CTRL_VPCLK_DIV_SHIFT 15
185#define ISPCCP2_CTRL_VPCLK_DIV_MASK 0x1ffff /* [31:15] */
186#define ISPCCP2_CTRL_VP_OUT_CTRL_SHIFT 8 /* 3430 bits */
187#define ISPCCP2_CTRL_VP_OUT_CTRL_MASK 0x3 /* 3430 bits */
188#define ISPCCP2_DBG (0x044)
189#define ISPCCP2_GNQ (0x048)
190#define ISPCCP2_LCx_CTRL(x) ((0x050)+0x30*(x))
191#define ISPCCP2_LCx_CTRL_CHAN_EN (1 << 0)
192#define ISPCCP2_LCx_CTRL_CRC_EN (1 << 19)
193#define ISPCCP2_LCx_CTRL_CRC_MASK 0x1
194#define ISPCCP2_LCx_CTRL_CRC_SHIFT 2
195#define ISPCCP2_LCx_CTRL_CRC_SHIFT_15_0 19
196#define ISPCCP2_LCx_CTRL_REGION_EN (1 << 1)
197#define ISPCCP2_LCx_CTRL_REGION_MASK 0x1
198#define ISPCCP2_LCx_CTRL_REGION_SHIFT 1
199#define ISPCCP2_LCx_CTRL_FORMAT_MASK_15_0 0x3f
200#define ISPCCP2_LCx_CTRL_FORMAT_SHIFT_15_0 0x2
201#define ISPCCP2_LCx_CTRL_FORMAT_MASK 0x1f
202#define ISPCCP2_LCx_CTRL_FORMAT_SHIFT 0x3
203#define ISPCCP2_LCx_CODE(x) ((0x054)+0x30*(x))
204#define ISPCCP2_LCx_STAT_START(x) ((0x058)+0x30*(x))
205#define ISPCCP2_LCx_STAT_SIZE(x) ((0x05C)+0x30*(x))
206#define ISPCCP2_LCx_SOF_ADDR(x) ((0x060)+0x30*(x))
207#define ISPCCP2_LCx_EOF_ADDR(x) ((0x064)+0x30*(x))
208#define ISPCCP2_LCx_DAT_START(x) ((0x068)+0x30*(x))
209#define ISPCCP2_LCx_DAT_SIZE(x) ((0x06C)+0x30*(x))
210#define ISPCCP2_LCx_DAT_MASK 0xFFF
211#define ISPCCP2_LCx_DAT_SHIFT 16
212#define ISPCCP2_LCx_DAT_PING_ADDR(x) ((0x070)+0x30*(x))
213#define ISPCCP2_LCx_DAT_PONG_ADDR(x) ((0x074)+0x30*(x))
214#define ISPCCP2_LCx_DAT_OFST(x) ((0x078)+0x30*(x))
215#define ISPCCP2_LCM_CTRL (0x1D0)
216#define ISPCCP2_LCM_CTRL_CHAN_EN (1 << 0)
217#define ISPCCP2_LCM_CTRL_DST_PORT (1 << 2)
218#define ISPCCP2_LCM_CTRL_DST_PORT_SHIFT 2
219#define ISPCCP2_LCM_CTRL_READ_THROTTLE_SHIFT 3
220#define ISPCCP2_LCM_CTRL_READ_THROTTLE_MASK 0x11
221#define ISPCCP2_LCM_CTRL_BURST_SIZE_SHIFT 5
222#define ISPCCP2_LCM_CTRL_BURST_SIZE_MASK 0x7
223#define ISPCCP2_LCM_CTRL_SRC_FORMAT_SHIFT 16
224#define ISPCCP2_LCM_CTRL_SRC_FORMAT_MASK 0x7
225#define ISPCCP2_LCM_CTRL_SRC_DECOMPR_SHIFT 20
226#define ISPCCP2_LCM_CTRL_SRC_DECOMPR_MASK 0x3
227#define ISPCCP2_LCM_CTRL_SRC_DPCM_PRED (1 << 22)
228#define ISPCCP2_LCM_CTRL_SRC_PACK (1 << 23)
229#define ISPCCP2_LCM_CTRL_DST_FORMAT_SHIFT 24
230#define ISPCCP2_LCM_CTRL_DST_FORMAT_MASK 0x7
231#define ISPCCP2_LCM_VSIZE (0x1D4)
232#define ISPCCP2_LCM_VSIZE_SHIFT 16
233#define ISPCCP2_LCM_HSIZE (0x1D8)
234#define ISPCCP2_LCM_HSIZE_SHIFT 16
235#define ISPCCP2_LCM_PREFETCH (0x1DC)
236#define ISPCCP2_LCM_PREFETCH_SHIFT 3
237#define ISPCCP2_LCM_SRC_ADDR (0x1E0)
238#define ISPCCP2_LCM_SRC_OFST (0x1E4)
239#define ISPCCP2_LCM_DST_ADDR (0x1E8)
240#define ISPCCP2_LCM_DST_OFST (0x1EC)
241
242/* CCDC module register offset */
243
244#define ISPCCDC_PID (0x000)
245#define ISPCCDC_PCR (0x004)
246#define ISPCCDC_SYN_MODE (0x008)
247#define ISPCCDC_HD_VD_WID (0x00C)
248#define ISPCCDC_PIX_LINES (0x010)
249#define ISPCCDC_HORZ_INFO (0x014)
250#define ISPCCDC_VERT_START (0x018)
251#define ISPCCDC_VERT_LINES (0x01C)
252#define ISPCCDC_CULLING (0x020)
253#define ISPCCDC_HSIZE_OFF (0x024)
254#define ISPCCDC_SDOFST (0x028)
255#define ISPCCDC_SDR_ADDR (0x02C)
256#define ISPCCDC_CLAMP (0x030)
257#define ISPCCDC_DCSUB (0x034)
258#define ISPCCDC_COLPTN (0x038)
259#define ISPCCDC_BLKCMP (0x03C)
260#define ISPCCDC_FPC (0x040)
261#define ISPCCDC_FPC_ADDR (0x044)
262#define ISPCCDC_VDINT (0x048)
263#define ISPCCDC_ALAW (0x04C)
264#define ISPCCDC_REC656IF (0x050)
265#define ISPCCDC_CFG (0x054)
266#define ISPCCDC_FMTCFG (0x058)
267#define ISPCCDC_FMT_HORZ (0x05C)
268#define ISPCCDC_FMT_VERT (0x060)
269#define ISPCCDC_FMT_ADDR0 (0x064)
270#define ISPCCDC_FMT_ADDR1 (0x068)
271#define ISPCCDC_FMT_ADDR2 (0x06C)
272#define ISPCCDC_FMT_ADDR3 (0x070)
273#define ISPCCDC_FMT_ADDR4 (0x074)
274#define ISPCCDC_FMT_ADDR5 (0x078)
275#define ISPCCDC_FMT_ADDR6 (0x07C)
276#define ISPCCDC_FMT_ADDR7 (0x080)
277#define ISPCCDC_PRGEVEN0 (0x084)
278#define ISPCCDC_PRGEVEN1 (0x088)
279#define ISPCCDC_PRGODD0 (0x08C)
280#define ISPCCDC_PRGODD1 (0x090)
281#define ISPCCDC_VP_OUT (0x094)
282
283#define ISPCCDC_LSC_CONFIG (0x098)
284#define ISPCCDC_LSC_INITIAL (0x09C)
285#define ISPCCDC_LSC_TABLE_BASE (0x0A0)
286#define ISPCCDC_LSC_TABLE_OFFSET (0x0A4)
287
288/* SBL */
289#define ISPSBL_PCR 0x4
290#define ISPSBL_PCR_H3A_AEAWB_WBL_OVF (1 << 16)
291#define ISPSBL_PCR_H3A_AF_WBL_OVF (1 << 17)
292#define ISPSBL_PCR_RSZ4_WBL_OVF (1 << 18)
293#define ISPSBL_PCR_RSZ3_WBL_OVF (1 << 19)
294#define ISPSBL_PCR_RSZ2_WBL_OVF (1 << 20)
295#define ISPSBL_PCR_RSZ1_WBL_OVF (1 << 21)
296#define ISPSBL_PCR_PRV_WBL_OVF (1 << 22)
297#define ISPSBL_PCR_CCDC_WBL_OVF (1 << 23)
298#define ISPSBL_PCR_CCDCPRV_2_RSZ_OVF (1 << 24)
299#define ISPSBL_PCR_CSIA_WBL_OVF (1 << 25)
300#define ISPSBL_PCR_CSIB_WBL_OVF (1 << 26)
301#define ISPSBL_CCDC_WR_0 (0x028)
302#define ISPSBL_CCDC_WR_0_DATA_READY (1 << 21)
303#define ISPSBL_CCDC_WR_1 (0x02C)
304#define ISPSBL_CCDC_WR_2 (0x030)
305#define ISPSBL_CCDC_WR_3 (0x034)
306
307#define ISPSBL_SDR_REQ_EXP 0xF8
308#define ISPSBL_SDR_REQ_HIST_EXP_SHIFT 0
309#define ISPSBL_SDR_REQ_HIST_EXP_MASK (0x3FF)
310#define ISPSBL_SDR_REQ_RSZ_EXP_SHIFT 10
311#define ISPSBL_SDR_REQ_RSZ_EXP_MASK (0x3FF << ISPSBL_SDR_REQ_RSZ_EXP_SHIFT)
312#define ISPSBL_SDR_REQ_PRV_EXP_SHIFT 20
313#define ISPSBL_SDR_REQ_PRV_EXP_MASK (0x3FF << ISPSBL_SDR_REQ_PRV_EXP_SHIFT)
314
315/* Histogram registers */
316#define ISPHIST_PID (0x000)
317#define ISPHIST_PCR (0x004)
318#define ISPHIST_CNT (0x008)
319#define ISPHIST_WB_GAIN (0x00C)
320#define ISPHIST_R0_HORZ (0x010)
321#define ISPHIST_R0_VERT (0x014)
322#define ISPHIST_R1_HORZ (0x018)
323#define ISPHIST_R1_VERT (0x01C)
324#define ISPHIST_R2_HORZ (0x020)
325#define ISPHIST_R2_VERT (0x024)
326#define ISPHIST_R3_HORZ (0x028)
327#define ISPHIST_R3_VERT (0x02C)
328#define ISPHIST_ADDR (0x030)
329#define ISPHIST_DATA (0x034)
330#define ISPHIST_RADD (0x038)
331#define ISPHIST_RADD_OFF (0x03C)
332#define ISPHIST_H_V_INFO (0x040)
333
334/* H3A module registers */
335#define ISPH3A_PID (0x000)
336#define ISPH3A_PCR (0x004)
337#define ISPH3A_AEWWIN1 (0x04C)
338#define ISPH3A_AEWINSTART (0x050)
339#define ISPH3A_AEWINBLK (0x054)
340#define ISPH3A_AEWSUBWIN (0x058)
341#define ISPH3A_AEWBUFST (0x05C)
342#define ISPH3A_AFPAX1 (0x008)
343#define ISPH3A_AFPAX2 (0x00C)
344#define ISPH3A_AFPAXSTART (0x010)
345#define ISPH3A_AFIIRSH (0x014)
346#define ISPH3A_AFBUFST (0x018)
347#define ISPH3A_AFCOEF010 (0x01C)
348#define ISPH3A_AFCOEF032 (0x020)
349#define ISPH3A_AFCOEF054 (0x024)
350#define ISPH3A_AFCOEF076 (0x028)
351#define ISPH3A_AFCOEF098 (0x02C)
352#define ISPH3A_AFCOEF0010 (0x030)
353#define ISPH3A_AFCOEF110 (0x034)
354#define ISPH3A_AFCOEF132 (0x038)
355#define ISPH3A_AFCOEF154 (0x03C)
356#define ISPH3A_AFCOEF176 (0x040)
357#define ISPH3A_AFCOEF198 (0x044)
358#define ISPH3A_AFCOEF1010 (0x048)
359
360#define ISPPRV_PCR (0x004)
361#define ISPPRV_HORZ_INFO (0x008)
362#define ISPPRV_VERT_INFO (0x00C)
363#define ISPPRV_RSDR_ADDR (0x010)
364#define ISPPRV_RADR_OFFSET (0x014)
365#define ISPPRV_DSDR_ADDR (0x018)
366#define ISPPRV_DRKF_OFFSET (0x01C)
367#define ISPPRV_WSDR_ADDR (0x020)
368#define ISPPRV_WADD_OFFSET (0x024)
369#define ISPPRV_AVE (0x028)
370#define ISPPRV_HMED (0x02C)
371#define ISPPRV_NF (0x030)
372#define ISPPRV_WB_DGAIN (0x034)
373#define ISPPRV_WBGAIN (0x038)
374#define ISPPRV_WBSEL (0x03C)
375#define ISPPRV_CFA (0x040)
376#define ISPPRV_BLKADJOFF (0x044)
377#define ISPPRV_RGB_MAT1 (0x048)
378#define ISPPRV_RGB_MAT2 (0x04C)
379#define ISPPRV_RGB_MAT3 (0x050)
380#define ISPPRV_RGB_MAT4 (0x054)
381#define ISPPRV_RGB_MAT5 (0x058)
382#define ISPPRV_RGB_OFF1 (0x05C)
383#define ISPPRV_RGB_OFF2 (0x060)
384#define ISPPRV_CSC0 (0x064)
385#define ISPPRV_CSC1 (0x068)
386#define ISPPRV_CSC2 (0x06C)
387#define ISPPRV_CSC_OFFSET (0x070)
388#define ISPPRV_CNT_BRT (0x074)
389#define ISPPRV_CSUP (0x078)
390#define ISPPRV_SETUP_YC (0x07C)
391#define ISPPRV_SET_TBL_ADDR (0x080)
392#define ISPPRV_SET_TBL_DATA (0x084)
393#define ISPPRV_CDC_THR0 (0x090)
394#define ISPPRV_CDC_THR1 (ISPPRV_CDC_THR0 + (0x4))
395#define ISPPRV_CDC_THR2 (ISPPRV_CDC_THR0 + (0x4) * 2)
396#define ISPPRV_CDC_THR3 (ISPPRV_CDC_THR0 + (0x4) * 3)
397
398#define ISPPRV_REDGAMMA_TABLE_ADDR 0x0000
399#define ISPPRV_GREENGAMMA_TABLE_ADDR 0x0400
400#define ISPPRV_BLUEGAMMA_TABLE_ADDR 0x0800
401#define ISPPRV_NF_TABLE_ADDR 0x0C00
402#define ISPPRV_YENH_TABLE_ADDR 0x1000
403#define ISPPRV_CFA_TABLE_ADDR 0x1400
404
405#define ISPRSZ_MIN_OUTPUT 64
406#define ISPRSZ_MAX_OUTPUT 3312
407
408/* Resizer module register offset */
409#define ISPRSZ_PID (0x000)
410#define ISPRSZ_PCR (0x004)
411#define ISPRSZ_CNT (0x008)
412#define ISPRSZ_OUT_SIZE (0x00C)
413#define ISPRSZ_IN_START (0x010)
414#define ISPRSZ_IN_SIZE (0x014)
415#define ISPRSZ_SDR_INADD (0x018)
416#define ISPRSZ_SDR_INOFF (0x01C)
417#define ISPRSZ_SDR_OUTADD (0x020)
418#define ISPRSZ_SDR_OUTOFF (0x024)
419#define ISPRSZ_HFILT10 (0x028)
420#define ISPRSZ_HFILT32 (0x02C)
421#define ISPRSZ_HFILT54 (0x030)
422#define ISPRSZ_HFILT76 (0x034)
423#define ISPRSZ_HFILT98 (0x038)
424#define ISPRSZ_HFILT1110 (0x03C)
425#define ISPRSZ_HFILT1312 (0x040)
426#define ISPRSZ_HFILT1514 (0x044)
427#define ISPRSZ_HFILT1716 (0x048)
428#define ISPRSZ_HFILT1918 (0x04C)
429#define ISPRSZ_HFILT2120 (0x050)
430#define ISPRSZ_HFILT2322 (0x054)
431#define ISPRSZ_HFILT2524 (0x058)
432#define ISPRSZ_HFILT2726 (0x05C)
433#define ISPRSZ_HFILT2928 (0x060)
434#define ISPRSZ_HFILT3130 (0x064)
435#define ISPRSZ_VFILT10 (0x068)
436#define ISPRSZ_VFILT32 (0x06C)
437#define ISPRSZ_VFILT54 (0x070)
438#define ISPRSZ_VFILT76 (0x074)
439#define ISPRSZ_VFILT98 (0x078)
440#define ISPRSZ_VFILT1110 (0x07C)
441#define ISPRSZ_VFILT1312 (0x080)
442#define ISPRSZ_VFILT1514 (0x084)
443#define ISPRSZ_VFILT1716 (0x088)
444#define ISPRSZ_VFILT1918 (0x08C)
445#define ISPRSZ_VFILT2120 (0x090)
446#define ISPRSZ_VFILT2322 (0x094)
447#define ISPRSZ_VFILT2524 (0x098)
448#define ISPRSZ_VFILT2726 (0x09C)
449#define ISPRSZ_VFILT2928 (0x0A0)
450#define ISPRSZ_VFILT3130 (0x0A4)
451#define ISPRSZ_YENH (0x0A8)
452
453#define ISP_INT_CLR 0xFF113F11
454#define ISPPRV_PCR_EN 1
455#define ISPPRV_PCR_BUSY (1 << 1)
456#define ISPPRV_PCR_SOURCE (1 << 2)
457#define ISPPRV_PCR_ONESHOT (1 << 3)
458#define ISPPRV_PCR_WIDTH (1 << 4)
459#define ISPPRV_PCR_INVALAW (1 << 5)
460#define ISPPRV_PCR_DRKFEN (1 << 6)
461#define ISPPRV_PCR_DRKFCAP (1 << 7)
462#define ISPPRV_PCR_HMEDEN (1 << 8)
463#define ISPPRV_PCR_NFEN (1 << 9)
464#define ISPPRV_PCR_CFAEN (1 << 10)
465#define ISPPRV_PCR_CFAFMT_SHIFT 11
466#define ISPPRV_PCR_CFAFMT_MASK 0x7800
467#define ISPPRV_PCR_CFAFMT_BAYER (0 << 11)
468#define ISPPRV_PCR_CFAFMT_SONYVGA (1 << 11)
469#define ISPPRV_PCR_CFAFMT_RGBFOVEON (2 << 11)
470#define ISPPRV_PCR_CFAFMT_DNSPL (3 << 11)
471#define ISPPRV_PCR_CFAFMT_HONEYCOMB (4 << 11)
472#define ISPPRV_PCR_CFAFMT_RRGGBBFOVEON (5 << 11)
473#define ISPPRV_PCR_YNENHEN (1 << 15)
474#define ISPPRV_PCR_SUPEN (1 << 16)
475#define ISPPRV_PCR_YCPOS_SHIFT 17
476#define ISPPRV_PCR_YCPOS_YCrYCb (0 << 17)
477#define ISPPRV_PCR_YCPOS_YCbYCr (1 << 17)
478#define ISPPRV_PCR_YCPOS_CbYCrY (2 << 17)
479#define ISPPRV_PCR_YCPOS_CrYCbY (3 << 17)
480#define ISPPRV_PCR_RSZPORT (1 << 19)
481#define ISPPRV_PCR_SDRPORT (1 << 20)
482#define ISPPRV_PCR_SCOMP_EN (1 << 21)
483#define ISPPRV_PCR_SCOMP_SFT_SHIFT (22)
484#define ISPPRV_PCR_SCOMP_SFT_MASK (7 << 22)
485#define ISPPRV_PCR_GAMMA_BYPASS (1 << 26)
486#define ISPPRV_PCR_DCOREN (1 << 27)
487#define ISPPRV_PCR_DCCOUP (1 << 28)
488#define ISPPRV_PCR_DRK_FAIL (1 << 31)
489
490#define ISPPRV_HORZ_INFO_EPH_SHIFT 0
491#define ISPPRV_HORZ_INFO_EPH_MASK 0x3fff
492#define ISPPRV_HORZ_INFO_SPH_SHIFT 16
493#define ISPPRV_HORZ_INFO_SPH_MASK 0x3fff0
494
495#define ISPPRV_VERT_INFO_ELV_SHIFT 0
496#define ISPPRV_VERT_INFO_ELV_MASK 0x3fff
497#define ISPPRV_VERT_INFO_SLV_SHIFT 16
498#define ISPPRV_VERT_INFO_SLV_MASK 0x3fff0
499
500#define ISPPRV_AVE_EVENDIST_SHIFT 2
501#define ISPPRV_AVE_EVENDIST_1 0x0
502#define ISPPRV_AVE_EVENDIST_2 0x1
503#define ISPPRV_AVE_EVENDIST_3 0x2
504#define ISPPRV_AVE_EVENDIST_4 0x3
505#define ISPPRV_AVE_ODDDIST_SHIFT 4
506#define ISPPRV_AVE_ODDDIST_1 0x0
507#define ISPPRV_AVE_ODDDIST_2 0x1
508#define ISPPRV_AVE_ODDDIST_3 0x2
509#define ISPPRV_AVE_ODDDIST_4 0x3
510
511#define ISPPRV_HMED_THRESHOLD_SHIFT 0
512#define ISPPRV_HMED_EVENDIST (1 << 8)
513#define ISPPRV_HMED_ODDDIST (1 << 9)
514
515#define ISPPRV_WBGAIN_COEF0_SHIFT 0
516#define ISPPRV_WBGAIN_COEF1_SHIFT 8
517#define ISPPRV_WBGAIN_COEF2_SHIFT 16
518#define ISPPRV_WBGAIN_COEF3_SHIFT 24
519
520#define ISPPRV_WBSEL_COEF0 0x0
521#define ISPPRV_WBSEL_COEF1 0x1
522#define ISPPRV_WBSEL_COEF2 0x2
523#define ISPPRV_WBSEL_COEF3 0x3
524
525#define ISPPRV_WBSEL_N0_0_SHIFT 0
526#define ISPPRV_WBSEL_N0_1_SHIFT 2
527#define ISPPRV_WBSEL_N0_2_SHIFT 4
528#define ISPPRV_WBSEL_N0_3_SHIFT 6
529#define ISPPRV_WBSEL_N1_0_SHIFT 8
530#define ISPPRV_WBSEL_N1_1_SHIFT 10
531#define ISPPRV_WBSEL_N1_2_SHIFT 12
532#define ISPPRV_WBSEL_N1_3_SHIFT 14
533#define ISPPRV_WBSEL_N2_0_SHIFT 16
534#define ISPPRV_WBSEL_N2_1_SHIFT 18
535#define ISPPRV_WBSEL_N2_2_SHIFT 20
536#define ISPPRV_WBSEL_N2_3_SHIFT 22
537#define ISPPRV_WBSEL_N3_0_SHIFT 24
538#define ISPPRV_WBSEL_N3_1_SHIFT 26
539#define ISPPRV_WBSEL_N3_2_SHIFT 28
540#define ISPPRV_WBSEL_N3_3_SHIFT 30
541
542#define ISPPRV_CFA_GRADTH_HOR_SHIFT 0
543#define ISPPRV_CFA_GRADTH_VER_SHIFT 8
544
545#define ISPPRV_BLKADJOFF_B_SHIFT 0
546#define ISPPRV_BLKADJOFF_G_SHIFT 8
547#define ISPPRV_BLKADJOFF_R_SHIFT 16
548
549#define ISPPRV_RGB_MAT1_MTX_RR_SHIFT 0
550#define ISPPRV_RGB_MAT1_MTX_GR_SHIFT 16
551
552#define ISPPRV_RGB_MAT2_MTX_BR_SHIFT 0
553#define ISPPRV_RGB_MAT2_MTX_RG_SHIFT 16
554
555#define ISPPRV_RGB_MAT3_MTX_GG_SHIFT 0
556#define ISPPRV_RGB_MAT3_MTX_BG_SHIFT 16
557
558#define ISPPRV_RGB_MAT4_MTX_RB_SHIFT 0
559#define ISPPRV_RGB_MAT4_MTX_GB_SHIFT 16
560
561#define ISPPRV_RGB_MAT5_MTX_BB_SHIFT 0
562
563#define ISPPRV_RGB_OFF1_MTX_OFFG_SHIFT 0
564#define ISPPRV_RGB_OFF1_MTX_OFFR_SHIFT 16
565
566#define ISPPRV_RGB_OFF2_MTX_OFFB_SHIFT 0
567
568#define ISPPRV_CSC0_RY_SHIFT 0
569#define ISPPRV_CSC0_GY_SHIFT 10
570#define ISPPRV_CSC0_BY_SHIFT 20
571
572#define ISPPRV_CSC1_RCB_SHIFT 0
573#define ISPPRV_CSC1_GCB_SHIFT 10
574#define ISPPRV_CSC1_BCB_SHIFT 20
575
576#define ISPPRV_CSC2_RCR_SHIFT 0
577#define ISPPRV_CSC2_GCR_SHIFT 10
578#define ISPPRV_CSC2_BCR_SHIFT 20
579
580#define ISPPRV_CSC_OFFSET_CR_SHIFT 0
581#define ISPPRV_CSC_OFFSET_CB_SHIFT 8
582#define ISPPRV_CSC_OFFSET_Y_SHIFT 16
583
584#define ISPPRV_CNT_BRT_BRT_SHIFT 0
585#define ISPPRV_CNT_BRT_CNT_SHIFT 8
586
587#define ISPPRV_CONTRAST_MAX 0x10
588#define ISPPRV_CONTRAST_MIN 0xFF
589#define ISPPRV_BRIGHT_MIN 0x00
590#define ISPPRV_BRIGHT_MAX 0xFF
591
592#define ISPPRV_CSUP_CSUPG_SHIFT 0
593#define ISPPRV_CSUP_THRES_SHIFT 8
594#define ISPPRV_CSUP_HPYF_SHIFT 16
595
596#define ISPPRV_SETUP_YC_MINC_SHIFT 0
597#define ISPPRV_SETUP_YC_MAXC_SHIFT 8
598#define ISPPRV_SETUP_YC_MINY_SHIFT 16
599#define ISPPRV_SETUP_YC_MAXY_SHIFT 24
600#define ISPPRV_YC_MAX 0xFF
601#define ISPPRV_YC_MIN 0x0
602
603/* Define bit fields within selected registers */
604#define ISP_REVISION_SHIFT 0
605
606#define ISP_SYSCONFIG_AUTOIDLE (1 << 0)
607#define ISP_SYSCONFIG_SOFTRESET (1 << 1)
608#define ISP_SYSCONFIG_MIDLEMODE_SHIFT 12
609#define ISP_SYSCONFIG_MIDLEMODE_FORCESTANDBY 0x0
610#define ISP_SYSCONFIG_MIDLEMODE_NOSTANBY 0x1
611#define ISP_SYSCONFIG_MIDLEMODE_SMARTSTANDBY 0x2
612
613#define ISP_SYSSTATUS_RESETDONE 0
614
615#define IRQ0ENABLE_CSIA_IRQ (1 << 0)
616#define IRQ0ENABLE_CSIC_IRQ (1 << 1)
617#define IRQ0ENABLE_CCP2_LCM_IRQ (1 << 3)
618#define IRQ0ENABLE_CCP2_LC0_IRQ (1 << 4)
619#define IRQ0ENABLE_CCP2_LC1_IRQ (1 << 5)
620#define IRQ0ENABLE_CCP2_LC2_IRQ (1 << 6)
621#define IRQ0ENABLE_CCP2_LC3_IRQ (1 << 7)
622#define IRQ0ENABLE_CSIB_IRQ (IRQ0ENABLE_CCP2_LCM_IRQ | \
623 IRQ0ENABLE_CCP2_LC0_IRQ | \
624 IRQ0ENABLE_CCP2_LC1_IRQ | \
625 IRQ0ENABLE_CCP2_LC2_IRQ | \
626 IRQ0ENABLE_CCP2_LC3_IRQ)
627
628#define IRQ0ENABLE_CCDC_VD0_IRQ (1 << 8)
629#define IRQ0ENABLE_CCDC_VD1_IRQ (1 << 9)
630#define IRQ0ENABLE_CCDC_VD2_IRQ (1 << 10)
631#define IRQ0ENABLE_CCDC_ERR_IRQ (1 << 11)
632#define IRQ0ENABLE_H3A_AF_DONE_IRQ (1 << 12)
633#define IRQ0ENABLE_H3A_AWB_DONE_IRQ (1 << 13)
634#define IRQ0ENABLE_HIST_DONE_IRQ (1 << 16)
635#define IRQ0ENABLE_CCDC_LSC_DONE_IRQ (1 << 17)
636#define IRQ0ENABLE_CCDC_LSC_PREF_COMP_IRQ (1 << 18)
637#define IRQ0ENABLE_CCDC_LSC_PREF_ERR_IRQ (1 << 19)
638#define IRQ0ENABLE_PRV_DONE_IRQ (1 << 20)
639#define IRQ0ENABLE_RSZ_DONE_IRQ (1 << 24)
640#define IRQ0ENABLE_OVF_IRQ (1 << 25)
641#define IRQ0ENABLE_PING_IRQ (1 << 26)
642#define IRQ0ENABLE_PONG_IRQ (1 << 27)
643#define IRQ0ENABLE_MMU_ERR_IRQ (1 << 28)
644#define IRQ0ENABLE_OCP_ERR_IRQ (1 << 29)
645#define IRQ0ENABLE_SEC_ERR_IRQ (1 << 30)
646#define IRQ0ENABLE_HS_VS_IRQ (1 << 31)
647
648#define IRQ0STATUS_CSIA_IRQ (1 << 0)
649#define IRQ0STATUS_CSI2C_IRQ (1 << 1)
650#define IRQ0STATUS_CCP2_LCM_IRQ (1 << 3)
651#define IRQ0STATUS_CCP2_LC0_IRQ (1 << 4)
652#define IRQ0STATUS_CSIB_IRQ (IRQ0STATUS_CCP2_LCM_IRQ | \
653 IRQ0STATUS_CCP2_LC0_IRQ)
654
655#define IRQ0STATUS_CSIB_LC1_IRQ (1 << 5)
656#define IRQ0STATUS_CSIB_LC2_IRQ (1 << 6)
657#define IRQ0STATUS_CSIB_LC3_IRQ (1 << 7)
658#define IRQ0STATUS_CCDC_VD0_IRQ (1 << 8)
659#define IRQ0STATUS_CCDC_VD1_IRQ (1 << 9)
660#define IRQ0STATUS_CCDC_VD2_IRQ (1 << 10)
661#define IRQ0STATUS_CCDC_ERR_IRQ (1 << 11)
662#define IRQ0STATUS_H3A_AF_DONE_IRQ (1 << 12)
663#define IRQ0STATUS_H3A_AWB_DONE_IRQ (1 << 13)
664#define IRQ0STATUS_HIST_DONE_IRQ (1 << 16)
665#define IRQ0STATUS_CCDC_LSC_DONE_IRQ (1 << 17)
666#define IRQ0STATUS_CCDC_LSC_PREF_COMP_IRQ (1 << 18)
667#define IRQ0STATUS_CCDC_LSC_PREF_ERR_IRQ (1 << 19)
668#define IRQ0STATUS_PRV_DONE_IRQ (1 << 20)
669#define IRQ0STATUS_RSZ_DONE_IRQ (1 << 24)
670#define IRQ0STATUS_OVF_IRQ (1 << 25)
671#define IRQ0STATUS_PING_IRQ (1 << 26)
672#define IRQ0STATUS_PONG_IRQ (1 << 27)
673#define IRQ0STATUS_MMU_ERR_IRQ (1 << 28)
674#define IRQ0STATUS_OCP_ERR_IRQ (1 << 29)
675#define IRQ0STATUS_SEC_ERR_IRQ (1 << 30)
676#define IRQ0STATUS_HS_VS_IRQ (1 << 31)
677
678#define TCTRL_GRESET_LEN 0
679
680#define TCTRL_PSTRB_REPLAY_DELAY 0
681#define TCTRL_PSTRB_REPLAY_COUNTER_SHIFT 25
682
683#define ISPCTRL_PAR_SER_CLK_SEL_PARALLEL 0x0
684#define ISPCTRL_PAR_SER_CLK_SEL_CSIA 0x1
685#define ISPCTRL_PAR_SER_CLK_SEL_CSIB 0x2
686#define ISPCTRL_PAR_SER_CLK_SEL_CSIC 0x3
687#define ISPCTRL_PAR_SER_CLK_SEL_MASK 0x3
688
689#define ISPCTRL_PAR_BRIDGE_SHIFT 2
690#define ISPCTRL_PAR_BRIDGE_DISABLE (0x0 << 2)
691#define ISPCTRL_PAR_BRIDGE_LENDIAN (0x2 << 2)
692#define ISPCTRL_PAR_BRIDGE_BENDIAN (0x3 << 2)
693#define ISPCTRL_PAR_BRIDGE_MASK (0x3 << 2)
694
695#define ISPCTRL_PAR_CLK_POL_SHIFT 4
696#define ISPCTRL_PAR_CLK_POL_INV (1 << 4)
697#define ISPCTRL_PING_PONG_EN (1 << 5)
698#define ISPCTRL_SHIFT_SHIFT 6
699#define ISPCTRL_SHIFT_0 (0x0 << 6)
700#define ISPCTRL_SHIFT_2 (0x1 << 6)
701#define ISPCTRL_SHIFT_4 (0x2 << 6)
702#define ISPCTRL_SHIFT_MASK (0x3 << 6)
703
704#define ISPCTRL_CCDC_CLK_EN (1 << 8)
705#define ISPCTRL_SCMP_CLK_EN (1 << 9)
706#define ISPCTRL_H3A_CLK_EN (1 << 10)
707#define ISPCTRL_HIST_CLK_EN (1 << 11)
708#define ISPCTRL_PREV_CLK_EN (1 << 12)
709#define ISPCTRL_RSZ_CLK_EN (1 << 13)
710#define ISPCTRL_SYNC_DETECT_SHIFT 14
711#define ISPCTRL_SYNC_DETECT_HSFALL (0x0 << ISPCTRL_SYNC_DETECT_SHIFT)
712#define ISPCTRL_SYNC_DETECT_HSRISE (0x1 << ISPCTRL_SYNC_DETECT_SHIFT)
713#define ISPCTRL_SYNC_DETECT_VSFALL (0x2 << ISPCTRL_SYNC_DETECT_SHIFT)
714#define ISPCTRL_SYNC_DETECT_VSRISE (0x3 << ISPCTRL_SYNC_DETECT_SHIFT)
715#define ISPCTRL_SYNC_DETECT_MASK (0x3 << ISPCTRL_SYNC_DETECT_SHIFT)
716
717#define ISPCTRL_CCDC_RAM_EN (1 << 16)
718#define ISPCTRL_PREV_RAM_EN (1 << 17)
719#define ISPCTRL_SBL_RD_RAM_EN (1 << 18)
720#define ISPCTRL_SBL_WR1_RAM_EN (1 << 19)
721#define ISPCTRL_SBL_WR0_RAM_EN (1 << 20)
722#define ISPCTRL_SBL_AUTOIDLE (1 << 21)
723#define ISPCTRL_SBL_SHARED_WPORTC (1 << 26)
724#define ISPCTRL_SBL_SHARED_RPORTA (1 << 27)
725#define ISPCTRL_SBL_SHARED_RPORTB (1 << 28)
726#define ISPCTRL_JPEG_FLUSH (1 << 30)
727#define ISPCTRL_CCDC_FLUSH (1 << 31)
728
729#define ISPSECURE_SECUREMODE 0
730
731#define ISPTCTRL_CTRL_DIV_LOW 0x0
732#define ISPTCTRL_CTRL_DIV_HIGH 0x1
733#define ISPTCTRL_CTRL_DIV_BYPASS 0x1F
734
735#define ISPTCTRL_CTRL_DIVA_SHIFT 0
736#define ISPTCTRL_CTRL_DIVA_MASK (0x1F << ISPTCTRL_CTRL_DIVA_SHIFT)
737
738#define ISPTCTRL_CTRL_DIVB_SHIFT 5
739#define ISPTCTRL_CTRL_DIVB_MASK (0x1F << ISPTCTRL_CTRL_DIVB_SHIFT)
740
741#define ISPTCTRL_CTRL_DIVC_SHIFT 10
742#define ISPTCTRL_CTRL_DIVC_NOCLOCK (0x0 << 10)
743
744#define ISPTCTRL_CTRL_SHUTEN (1 << 21)
745#define ISPTCTRL_CTRL_PSTRBEN (1 << 22)
746#define ISPTCTRL_CTRL_STRBEN (1 << 23)
747#define ISPTCTRL_CTRL_SHUTPOL (1 << 24)
748#define ISPTCTRL_CTRL_STRBPSTRBPOL (1 << 26)
749
750#define ISPTCTRL_CTRL_INSEL_SHIFT 27
751#define ISPTCTRL_CTRL_INSEL_PARALLEL (0x0 << 27)
752#define ISPTCTRL_CTRL_INSEL_CSIA (0x1 << 27)
753#define ISPTCTRL_CTRL_INSEL_CSIB (0x2 << 27)
754
755#define ISPTCTRL_CTRL_GRESETEn (1 << 29)
756#define ISPTCTRL_CTRL_GRESETPOL (1 << 30)
757#define ISPTCTRL_CTRL_GRESETDIR (1 << 31)
758
759#define ISPTCTRL_FRAME_SHUT_SHIFT 0
760#define ISPTCTRL_FRAME_PSTRB_SHIFT 6
761#define ISPTCTRL_FRAME_STRB_SHIFT 12
762
763#define ISPCCDC_PID_PREV_SHIFT 0
764#define ISPCCDC_PID_CID_SHIFT 8
765#define ISPCCDC_PID_TID_SHIFT 16
766
767#define ISPCCDC_PCR_EN 1
768#define ISPCCDC_PCR_BUSY (1 << 1)
769
770#define ISPCCDC_SYN_MODE_VDHDOUT 0x1
771#define ISPCCDC_SYN_MODE_FLDOUT (1 << 1)
772#define ISPCCDC_SYN_MODE_VDPOL (1 << 2)
773#define ISPCCDC_SYN_MODE_HDPOL (1 << 3)
774#define ISPCCDC_SYN_MODE_FLDPOL (1 << 4)
775#define ISPCCDC_SYN_MODE_EXWEN (1 << 5)
776#define ISPCCDC_SYN_MODE_DATAPOL (1 << 6)
777#define ISPCCDC_SYN_MODE_FLDMODE (1 << 7)
778#define ISPCCDC_SYN_MODE_DATSIZ_MASK (0x7 << 8)
779#define ISPCCDC_SYN_MODE_DATSIZ_8_16 (0x0 << 8)
780#define ISPCCDC_SYN_MODE_DATSIZ_12 (0x4 << 8)
781#define ISPCCDC_SYN_MODE_DATSIZ_11 (0x5 << 8)
782#define ISPCCDC_SYN_MODE_DATSIZ_10 (0x6 << 8)
783#define ISPCCDC_SYN_MODE_DATSIZ_8 (0x7 << 8)
784#define ISPCCDC_SYN_MODE_PACK8 (1 << 11)
785#define ISPCCDC_SYN_MODE_INPMOD_MASK (3 << 12)
786#define ISPCCDC_SYN_MODE_INPMOD_RAW (0 << 12)
787#define ISPCCDC_SYN_MODE_INPMOD_YCBCR16 (1 << 12)
788#define ISPCCDC_SYN_MODE_INPMOD_YCBCR8 (2 << 12)
789#define ISPCCDC_SYN_MODE_LPF (1 << 14)
790#define ISPCCDC_SYN_MODE_FLDSTAT (1 << 15)
791#define ISPCCDC_SYN_MODE_VDHDEN (1 << 16)
792#define ISPCCDC_SYN_MODE_WEN (1 << 17)
793#define ISPCCDC_SYN_MODE_VP2SDR (1 << 18)
794#define ISPCCDC_SYN_MODE_SDR2RSZ (1 << 19)
795
796#define ISPCCDC_HD_VD_WID_VDW_SHIFT 0
797#define ISPCCDC_HD_VD_WID_HDW_SHIFT 16
798
799#define ISPCCDC_PIX_LINES_HLPRF_SHIFT 0
800#define ISPCCDC_PIX_LINES_PPLN_SHIFT 16
801
802#define ISPCCDC_HORZ_INFO_NPH_SHIFT 0
803#define ISPCCDC_HORZ_INFO_NPH_MASK 0x00007fff
804#define ISPCCDC_HORZ_INFO_SPH_SHIFT 16
805#define ISPCCDC_HORZ_INFO_SPH_MASK 0x7fff0000
806
807#define ISPCCDC_VERT_START_SLV1_SHIFT 0
808#define ISPCCDC_VERT_START_SLV0_SHIFT 16
809#define ISPCCDC_VERT_START_SLV0_MASK 0x7fff0000
810
811#define ISPCCDC_VERT_LINES_NLV_SHIFT 0
812#define ISPCCDC_VERT_LINES_NLV_MASK 0x00007fff
813
814#define ISPCCDC_CULLING_CULV_SHIFT 0
815#define ISPCCDC_CULLING_CULHODD_SHIFT 16
816#define ISPCCDC_CULLING_CULHEVN_SHIFT 24
817
818#define ISPCCDC_HSIZE_OFF_SHIFT 0
819
820#define ISPCCDC_SDOFST_FINV (1 << 14)
821#define ISPCCDC_SDOFST_FOFST_1L 0
822#define ISPCCDC_SDOFST_FOFST_4L (3 << 12)
823#define ISPCCDC_SDOFST_LOFST3_SHIFT 0
824#define ISPCCDC_SDOFST_LOFST2_SHIFT 3
825#define ISPCCDC_SDOFST_LOFST1_SHIFT 6
826#define ISPCCDC_SDOFST_LOFST0_SHIFT 9
827#define EVENEVEN 1
828#define ODDEVEN 2
829#define EVENODD 3
830#define ODDODD 4
831
832#define ISPCCDC_CLAMP_OBGAIN_SHIFT 0
833#define ISPCCDC_CLAMP_OBST_SHIFT 10
834#define ISPCCDC_CLAMP_OBSLN_SHIFT 25
835#define ISPCCDC_CLAMP_OBSLEN_SHIFT 28
836#define ISPCCDC_CLAMP_CLAMPEN (1 << 31)
837
838#define ISPCCDC_COLPTN_R_Ye 0x0
839#define ISPCCDC_COLPTN_Gr_Cy 0x1
840#define ISPCCDC_COLPTN_Gb_G 0x2
841#define ISPCCDC_COLPTN_B_Mg 0x3
842#define ISPCCDC_COLPTN_CP0PLC0_SHIFT 0
843#define ISPCCDC_COLPTN_CP0PLC1_SHIFT 2
844#define ISPCCDC_COLPTN_CP0PLC2_SHIFT 4
845#define ISPCCDC_COLPTN_CP0PLC3_SHIFT 6
846#define ISPCCDC_COLPTN_CP1PLC0_SHIFT 8
847#define ISPCCDC_COLPTN_CP1PLC1_SHIFT 10
848#define ISPCCDC_COLPTN_CP1PLC2_SHIFT 12
849#define ISPCCDC_COLPTN_CP1PLC3_SHIFT 14
850#define ISPCCDC_COLPTN_CP2PLC0_SHIFT 16
851#define ISPCCDC_COLPTN_CP2PLC1_SHIFT 18
852#define ISPCCDC_COLPTN_CP2PLC2_SHIFT 20
853#define ISPCCDC_COLPTN_CP2PLC3_SHIFT 22
854#define ISPCCDC_COLPTN_CP3PLC0_SHIFT 24
855#define ISPCCDC_COLPTN_CP3PLC1_SHIFT 26
856#define ISPCCDC_COLPTN_CP3PLC2_SHIFT 28
857#define ISPCCDC_COLPTN_CP3PLC3_SHIFT 30
858
859#define ISPCCDC_BLKCMP_B_MG_SHIFT 0
860#define ISPCCDC_BLKCMP_GB_G_SHIFT 8
861#define ISPCCDC_BLKCMP_GR_CY_SHIFT 16
862#define ISPCCDC_BLKCMP_R_YE_SHIFT 24
863
864#define ISPCCDC_FPC_FPNUM_SHIFT 0
865#define ISPCCDC_FPC_FPCEN (1 << 15)
866#define ISPCCDC_FPC_FPERR (1 << 16)
867
868#define ISPCCDC_VDINT_1_SHIFT 0
869#define ISPCCDC_VDINT_1_MASK 0x00007fff
870#define ISPCCDC_VDINT_0_SHIFT 16
871#define ISPCCDC_VDINT_0_MASK 0x7fff0000
872
873#define ISPCCDC_ALAW_GWDI_12_3 (0x3 << 0)
874#define ISPCCDC_ALAW_GWDI_11_2 (0x4 << 0)
875#define ISPCCDC_ALAW_GWDI_10_1 (0x5 << 0)
876#define ISPCCDC_ALAW_GWDI_9_0 (0x6 << 0)
877#define ISPCCDC_ALAW_CCDTBL (1 << 3)
878
879#define ISPCCDC_REC656IF_R656ON 1
880#define ISPCCDC_REC656IF_ECCFVH (1 << 1)
881
882#define ISPCCDC_CFG_BW656 (1 << 5)
883#define ISPCCDC_CFG_FIDMD_SHIFT 6
884#define ISPCCDC_CFG_WENLOG (1 << 8)
885#define ISPCCDC_CFG_WENLOG_AND (0 << 8)
886#define ISPCCDC_CFG_WENLOG_OR (1 << 8)
887#define ISPCCDC_CFG_Y8POS (1 << 11)
888#define ISPCCDC_CFG_BSWD (1 << 12)
889#define ISPCCDC_CFG_MSBINVI (1 << 13)
890#define ISPCCDC_CFG_VDLC (1 << 15)
891
892#define ISPCCDC_FMTCFG_FMTEN 0x1
893#define ISPCCDC_FMTCFG_LNALT (1 << 1)
894#define ISPCCDC_FMTCFG_LNUM_SHIFT 2
895#define ISPCCDC_FMTCFG_PLEN_ODD_SHIFT 4
896#define ISPCCDC_FMTCFG_PLEN_EVEN_SHIFT 8
897#define ISPCCDC_FMTCFG_VPIN_MASK 0x00007000
898#define ISPCCDC_FMTCFG_VPIN_12_3 (0x3 << 12)
899#define ISPCCDC_FMTCFG_VPIN_11_2 (0x4 << 12)
900#define ISPCCDC_FMTCFG_VPIN_10_1 (0x5 << 12)
901#define ISPCCDC_FMTCFG_VPIN_9_0 (0x6 << 12)
902#define ISPCCDC_FMTCFG_VPEN (1 << 15)
903
904#define ISPCCDC_FMTCFG_VPIF_FRQ_MASK 0x003f0000
905#define ISPCCDC_FMTCFG_VPIF_FRQ_SHIFT 16
906#define ISPCCDC_FMTCFG_VPIF_FRQ_BY2 (0x0 << 16)
907#define ISPCCDC_FMTCFG_VPIF_FRQ_BY3 (0x1 << 16)
908#define ISPCCDC_FMTCFG_VPIF_FRQ_BY4 (0x2 << 16)
909#define ISPCCDC_FMTCFG_VPIF_FRQ_BY5 (0x3 << 16)
910#define ISPCCDC_FMTCFG_VPIF_FRQ_BY6 (0x4 << 16)
911
912#define ISPCCDC_FMT_HORZ_FMTLNH_SHIFT 0
913#define ISPCCDC_FMT_HORZ_FMTSPH_SHIFT 16
914
915#define ISPCCDC_FMT_VERT_FMTLNV_SHIFT 0
916#define ISPCCDC_FMT_VERT_FMTSLV_SHIFT 16
917
918#define ISPCCDC_FMT_HORZ_FMTSPH_MASK 0x1fff0000
919#define ISPCCDC_FMT_HORZ_FMTLNH_MASK 0x00001fff
920
921#define ISPCCDC_FMT_VERT_FMTSLV_MASK 0x1fff0000
922#define ISPCCDC_FMT_VERT_FMTLNV_MASK 0x00001fff
923
924#define ISPCCDC_VP_OUT_HORZ_ST_SHIFT 0
925#define ISPCCDC_VP_OUT_HORZ_NUM_SHIFT 4
926#define ISPCCDC_VP_OUT_VERT_NUM_SHIFT 17
927
928#define ISPRSZ_PID_PREV_SHIFT 0
929#define ISPRSZ_PID_CID_SHIFT 8
930#define ISPRSZ_PID_TID_SHIFT 16
931
932#define ISPRSZ_PCR_ENABLE (1 << 0)
933#define ISPRSZ_PCR_BUSY (1 << 1)
934#define ISPRSZ_PCR_ONESHOT (1 << 2)
935
936#define ISPRSZ_CNT_HRSZ_SHIFT 0
937#define ISPRSZ_CNT_HRSZ_MASK \
938 (0x3FF << ISPRSZ_CNT_HRSZ_SHIFT)
939#define ISPRSZ_CNT_VRSZ_SHIFT 10
940#define ISPRSZ_CNT_VRSZ_MASK \
941 (0x3FF << ISPRSZ_CNT_VRSZ_SHIFT)
942#define ISPRSZ_CNT_HSTPH_SHIFT 20
943#define ISPRSZ_CNT_HSTPH_MASK (0x7 << ISPRSZ_CNT_HSTPH_SHIFT)
944#define ISPRSZ_CNT_VSTPH_SHIFT 23
945#define ISPRSZ_CNT_VSTPH_MASK (0x7 << ISPRSZ_CNT_VSTPH_SHIFT)
946#define ISPRSZ_CNT_YCPOS (1 << 26)
947#define ISPRSZ_CNT_INPTYP (1 << 27)
948#define ISPRSZ_CNT_INPSRC (1 << 28)
949#define ISPRSZ_CNT_CBILIN (1 << 29)
950
951#define ISPRSZ_OUT_SIZE_HORZ_SHIFT 0
952#define ISPRSZ_OUT_SIZE_HORZ_MASK \
953 (0xFFF << ISPRSZ_OUT_SIZE_HORZ_SHIFT)
954#define ISPRSZ_OUT_SIZE_VERT_SHIFT 16
955#define ISPRSZ_OUT_SIZE_VERT_MASK \
956 (0xFFF << ISPRSZ_OUT_SIZE_VERT_SHIFT)
957
958#define ISPRSZ_IN_START_HORZ_ST_SHIFT 0
959#define ISPRSZ_IN_START_HORZ_ST_MASK \
960 (0x1FFF << ISPRSZ_IN_START_HORZ_ST_SHIFT)
961#define ISPRSZ_IN_START_VERT_ST_SHIFT 16
962#define ISPRSZ_IN_START_VERT_ST_MASK \
963 (0x1FFF << ISPRSZ_IN_START_VERT_ST_SHIFT)
964
965#define ISPRSZ_IN_SIZE_HORZ_SHIFT 0
966#define ISPRSZ_IN_SIZE_HORZ_MASK \
967 (0x1FFF << ISPRSZ_IN_SIZE_HORZ_SHIFT)
968#define ISPRSZ_IN_SIZE_VERT_SHIFT 16
969#define ISPRSZ_IN_SIZE_VERT_MASK \
970 (0x1FFF << ISPRSZ_IN_SIZE_VERT_SHIFT)
971
972#define ISPRSZ_SDR_INADD_ADDR_SHIFT 0
973#define ISPRSZ_SDR_INADD_ADDR_MASK 0xFFFFFFFF
974
975#define ISPRSZ_SDR_INOFF_OFFSET_SHIFT 0
976#define ISPRSZ_SDR_INOFF_OFFSET_MASK \
977 (0xFFFF << ISPRSZ_SDR_INOFF_OFFSET_SHIFT)
978
979#define ISPRSZ_SDR_OUTADD_ADDR_SHIFT 0
980#define ISPRSZ_SDR_OUTADD_ADDR_MASK 0xFFFFFFFF
981
982
983#define ISPRSZ_SDR_OUTOFF_OFFSET_SHIFT 0
984#define ISPRSZ_SDR_OUTOFF_OFFSET_MASK \
985 (0xFFFF << ISPRSZ_SDR_OUTOFF_OFFSET_SHIFT)
986
987#define ISPRSZ_HFILT_COEF0_SHIFT 0
988#define ISPRSZ_HFILT_COEF0_MASK \
989 (0x3FF << ISPRSZ_HFILT_COEF0_SHIFT)
990#define ISPRSZ_HFILT_COEF1_SHIFT 16
991#define ISPRSZ_HFILT_COEF1_MASK \
992 (0x3FF << ISPRSZ_HFILT_COEF1_SHIFT)
993
994#define ISPRSZ_HFILT32_COEF2_SHIFT 0
995#define ISPRSZ_HFILT32_COEF2_MASK 0x3FF
996#define ISPRSZ_HFILT32_COEF3_SHIFT 16
997#define ISPRSZ_HFILT32_COEF3_MASK 0x3FF0000
998
999#define ISPRSZ_HFILT54_COEF4_SHIFT 0
1000#define ISPRSZ_HFILT54_COEF4_MASK 0x3FF
1001#define ISPRSZ_HFILT54_COEF5_SHIFT 16
1002#define ISPRSZ_HFILT54_COEF5_MASK 0x3FF0000
1003
1004#define ISPRSZ_HFILT76_COEFF6_SHIFT 0
1005#define ISPRSZ_HFILT76_COEFF6_MASK 0x3FF
1006#define ISPRSZ_HFILT76_COEFF7_SHIFT 16
1007#define ISPRSZ_HFILT76_COEFF7_MASK 0x3FF0000
1008
1009#define ISPRSZ_HFILT98_COEFF8_SHIFT 0
1010#define ISPRSZ_HFILT98_COEFF8_MASK 0x3FF
1011#define ISPRSZ_HFILT98_COEFF9_SHIFT 16
1012#define ISPRSZ_HFILT98_COEFF9_MASK 0x3FF0000
1013
1014#define ISPRSZ_HFILT1110_COEF10_SHIFT 0
1015#define ISPRSZ_HFILT1110_COEF10_MASK 0x3FF
1016#define ISPRSZ_HFILT1110_COEF11_SHIFT 16
1017#define ISPRSZ_HFILT1110_COEF11_MASK 0x3FF0000
1018
1019#define ISPRSZ_HFILT1312_COEFF12_SHIFT 0
1020#define ISPRSZ_HFILT1312_COEFF12_MASK 0x3FF
1021#define ISPRSZ_HFILT1312_COEFF13_SHIFT 16
1022#define ISPRSZ_HFILT1312_COEFF13_MASK 0x3FF0000
1023
1024#define ISPRSZ_HFILT1514_COEFF14_SHIFT 0
1025#define ISPRSZ_HFILT1514_COEFF14_MASK 0x3FF
1026#define ISPRSZ_HFILT1514_COEFF15_SHIFT 16
1027#define ISPRSZ_HFILT1514_COEFF15_MASK 0x3FF0000
1028
1029#define ISPRSZ_HFILT1716_COEF16_SHIFT 0
1030#define ISPRSZ_HFILT1716_COEF16_MASK 0x3FF
1031#define ISPRSZ_HFILT1716_COEF17_SHIFT 16
1032#define ISPRSZ_HFILT1716_COEF17_MASK 0x3FF0000
1033
1034#define ISPRSZ_HFILT1918_COEF18_SHIFT 0
1035#define ISPRSZ_HFILT1918_COEF18_MASK 0x3FF
1036#define ISPRSZ_HFILT1918_COEF19_SHIFT 16
1037#define ISPRSZ_HFILT1918_COEF19_MASK 0x3FF0000
1038
1039#define ISPRSZ_HFILT2120_COEF20_SHIFT 0
1040#define ISPRSZ_HFILT2120_COEF20_MASK 0x3FF
1041#define ISPRSZ_HFILT2120_COEF21_SHIFT 16
1042#define ISPRSZ_HFILT2120_COEF21_MASK 0x3FF0000
1043
1044#define ISPRSZ_HFILT2322_COEF22_SHIFT 0
1045#define ISPRSZ_HFILT2322_COEF22_MASK 0x3FF
1046#define ISPRSZ_HFILT2322_COEF23_SHIFT 16
1047#define ISPRSZ_HFILT2322_COEF23_MASK 0x3FF0000
1048
1049#define ISPRSZ_HFILT2524_COEF24_SHIFT 0
1050#define ISPRSZ_HFILT2524_COEF24_MASK 0x3FF
1051#define ISPRSZ_HFILT2524_COEF25_SHIFT 16
1052#define ISPRSZ_HFILT2524_COEF25_MASK 0x3FF0000
1053
1054#define ISPRSZ_HFILT2726_COEF26_SHIFT 0
1055#define ISPRSZ_HFILT2726_COEF26_MASK 0x3FF
1056#define ISPRSZ_HFILT2726_COEF27_SHIFT 16
1057#define ISPRSZ_HFILT2726_COEF27_MASK 0x3FF0000
1058
1059#define ISPRSZ_HFILT2928_COEF28_SHIFT 0
1060#define ISPRSZ_HFILT2928_COEF28_MASK 0x3FF
1061#define ISPRSZ_HFILT2928_COEF29_SHIFT 16
1062#define ISPRSZ_HFILT2928_COEF29_MASK 0x3FF0000
1063
1064#define ISPRSZ_HFILT3130_COEF30_SHIFT 0
1065#define ISPRSZ_HFILT3130_COEF30_MASK 0x3FF
1066#define ISPRSZ_HFILT3130_COEF31_SHIFT 16
1067#define ISPRSZ_HFILT3130_COEF31_MASK 0x3FF0000
1068
1069#define ISPRSZ_VFILT_COEF0_SHIFT 0
1070#define ISPRSZ_VFILT_COEF0_MASK \
1071 (0x3FF << ISPRSZ_VFILT_COEF0_SHIFT)
1072#define ISPRSZ_VFILT_COEF1_SHIFT 16
1073#define ISPRSZ_VFILT_COEF1_MASK \
1074 (0x3FF << ISPRSZ_VFILT_COEF1_SHIFT)
1075
1076#define ISPRSZ_VFILT10_COEF0_SHIFT 0
1077#define ISPRSZ_VFILT10_COEF0_MASK 0x3FF
1078#define ISPRSZ_VFILT10_COEF1_SHIFT 16
1079#define ISPRSZ_VFILT10_COEF1_MASK 0x3FF0000
1080
1081#define ISPRSZ_VFILT32_COEF2_SHIFT 0
1082#define ISPRSZ_VFILT32_COEF2_MASK 0x3FF
1083#define ISPRSZ_VFILT32_COEF3_SHIFT 16
1084#define ISPRSZ_VFILT32_COEF3_MASK 0x3FF0000
1085
1086#define ISPRSZ_VFILT54_COEF4_SHIFT 0
1087#define ISPRSZ_VFILT54_COEF4_MASK 0x3FF
1088#define ISPRSZ_VFILT54_COEF5_SHIFT 16
1089#define ISPRSZ_VFILT54_COEF5_MASK 0x3FF0000
1090
1091#define ISPRSZ_VFILT76_COEFF6_SHIFT 0
1092#define ISPRSZ_VFILT76_COEFF6_MASK 0x3FF
1093#define ISPRSZ_VFILT76_COEFF7_SHIFT 16
1094#define ISPRSZ_VFILT76_COEFF7_MASK 0x3FF0000
1095
1096#define ISPRSZ_VFILT98_COEFF8_SHIFT 0
1097#define ISPRSZ_VFILT98_COEFF8_MASK 0x3FF
1098#define ISPRSZ_VFILT98_COEFF9_SHIFT 16
1099#define ISPRSZ_VFILT98_COEFF9_MASK 0x3FF0000
1100
1101#define ISPRSZ_VFILT1110_COEF10_SHIFT 0
1102#define ISPRSZ_VFILT1110_COEF10_MASK 0x3FF
1103#define ISPRSZ_VFILT1110_COEF11_SHIFT 16
1104#define ISPRSZ_VFILT1110_COEF11_MASK 0x3FF0000
1105
1106#define ISPRSZ_VFILT1312_COEFF12_SHIFT 0
1107#define ISPRSZ_VFILT1312_COEFF12_MASK 0x3FF
1108#define ISPRSZ_VFILT1312_COEFF13_SHIFT 16
1109#define ISPRSZ_VFILT1312_COEFF13_MASK 0x3FF0000
1110
1111#define ISPRSZ_VFILT1514_COEFF14_SHIFT 0
1112#define ISPRSZ_VFILT1514_COEFF14_MASK 0x3FF
1113#define ISPRSZ_VFILT1514_COEFF15_SHIFT 16
1114#define ISPRSZ_VFILT1514_COEFF15_MASK 0x3FF0000
1115
1116#define ISPRSZ_VFILT1716_COEF16_SHIFT 0
1117#define ISPRSZ_VFILT1716_COEF16_MASK 0x3FF
1118#define ISPRSZ_VFILT1716_COEF17_SHIFT 16
1119#define ISPRSZ_VFILT1716_COEF17_MASK 0x3FF0000
1120
1121#define ISPRSZ_VFILT1918_COEF18_SHIFT 0
1122#define ISPRSZ_VFILT1918_COEF18_MASK 0x3FF
1123#define ISPRSZ_VFILT1918_COEF19_SHIFT 16
1124#define ISPRSZ_VFILT1918_COEF19_MASK 0x3FF0000
1125
1126#define ISPRSZ_VFILT2120_COEF20_SHIFT 0
1127#define ISPRSZ_VFILT2120_COEF20_MASK 0x3FF
1128#define ISPRSZ_VFILT2120_COEF21_SHIFT 16
1129#define ISPRSZ_VFILT2120_COEF21_MASK 0x3FF0000
1130
1131#define ISPRSZ_VFILT2322_COEF22_SHIFT 0
1132#define ISPRSZ_VFILT2322_COEF22_MASK 0x3FF
1133#define ISPRSZ_VFILT2322_COEF23_SHIFT 16
1134#define ISPRSZ_VFILT2322_COEF23_MASK 0x3FF0000
1135
1136#define ISPRSZ_VFILT2524_COEF24_SHIFT 0
1137#define ISPRSZ_VFILT2524_COEF24_MASK 0x3FF
1138#define ISPRSZ_VFILT2524_COEF25_SHIFT 16
1139#define ISPRSZ_VFILT2524_COEF25_MASK 0x3FF0000
1140
1141#define ISPRSZ_VFILT2726_COEF26_SHIFT 0
1142#define ISPRSZ_VFILT2726_COEF26_MASK 0x3FF
1143#define ISPRSZ_VFILT2726_COEF27_SHIFT 16
1144#define ISPRSZ_VFILT2726_COEF27_MASK 0x3FF0000
1145
1146#define ISPRSZ_VFILT2928_COEF28_SHIFT 0
1147#define ISPRSZ_VFILT2928_COEF28_MASK 0x3FF
1148#define ISPRSZ_VFILT2928_COEF29_SHIFT 16
1149#define ISPRSZ_VFILT2928_COEF29_MASK 0x3FF0000
1150
1151#define ISPRSZ_VFILT3130_COEF30_SHIFT 0
1152#define ISPRSZ_VFILT3130_COEF30_MASK 0x3FF
1153#define ISPRSZ_VFILT3130_COEF31_SHIFT 16
1154#define ISPRSZ_VFILT3130_COEF31_MASK 0x3FF0000
1155
1156#define ISPRSZ_YENH_CORE_SHIFT 0
1157#define ISPRSZ_YENH_CORE_MASK \
1158 (0xFF << ISPRSZ_YENH_CORE_SHIFT)
1159#define ISPRSZ_YENH_SLOP_SHIFT 8
1160#define ISPRSZ_YENH_SLOP_MASK \
1161 (0xF << ISPRSZ_YENH_SLOP_SHIFT)
1162#define ISPRSZ_YENH_GAIN_SHIFT 12
1163#define ISPRSZ_YENH_GAIN_MASK \
1164 (0xF << ISPRSZ_YENH_GAIN_SHIFT)
1165#define ISPRSZ_YENH_ALGO_SHIFT 16
1166#define ISPRSZ_YENH_ALGO_MASK \
1167 (0x3 << ISPRSZ_YENH_ALGO_SHIFT)
1168
1169#define ISPH3A_PCR_AEW_ALAW_EN_SHIFT 1
1170#define ISPH3A_PCR_AF_MED_TH_SHIFT 3
1171#define ISPH3A_PCR_AF_RGBPOS_SHIFT 11
1172#define ISPH3A_PCR_AEW_AVE2LMT_SHIFT 22
1173#define ISPH3A_PCR_AEW_AVE2LMT_MASK 0xFFC00000
1174#define ISPH3A_PCR_BUSYAF (1 << 15)
1175#define ISPH3A_PCR_BUSYAEAWB (1 << 18)
1176
1177#define ISPH3A_AEWWIN1_WINHC_SHIFT 0
1178#define ISPH3A_AEWWIN1_WINHC_MASK 0x3F
1179#define ISPH3A_AEWWIN1_WINVC_SHIFT 6
1180#define ISPH3A_AEWWIN1_WINVC_MASK 0x1FC0
1181#define ISPH3A_AEWWIN1_WINW_SHIFT 13
1182#define ISPH3A_AEWWIN1_WINW_MASK 0xFE000
1183#define ISPH3A_AEWWIN1_WINH_SHIFT 24
1184#define ISPH3A_AEWWIN1_WINH_MASK 0x7F000000
1185
1186#define ISPH3A_AEWINSTART_WINSH_SHIFT 0
1187#define ISPH3A_AEWINSTART_WINSH_MASK 0x0FFF
1188#define ISPH3A_AEWINSTART_WINSV_SHIFT 16
1189#define ISPH3A_AEWINSTART_WINSV_MASK 0x0FFF0000
1190
1191#define ISPH3A_AEWINBLK_WINH_SHIFT 0
1192#define ISPH3A_AEWINBLK_WINH_MASK 0x7F
1193#define ISPH3A_AEWINBLK_WINSV_SHIFT 16
1194#define ISPH3A_AEWINBLK_WINSV_MASK 0x0FFF0000
1195
1196#define ISPH3A_AEWSUBWIN_AEWINCH_SHIFT 0
1197#define ISPH3A_AEWSUBWIN_AEWINCH_MASK 0x0F
1198#define ISPH3A_AEWSUBWIN_AEWINCV_SHIFT 8
1199#define ISPH3A_AEWSUBWIN_AEWINCV_MASK 0x0F00
1200
1201#define ISPHIST_PCR_ENABLE_SHIFT 0
1202#define ISPHIST_PCR_ENABLE_MASK 0x01
1203#define ISPHIST_PCR_ENABLE (1 << ISPHIST_PCR_ENABLE_SHIFT)
1204#define ISPHIST_PCR_BUSY 0x02
1205
1206#define ISPHIST_CNT_DATASIZE_SHIFT 8
1207#define ISPHIST_CNT_DATASIZE_MASK 0x0100
1208#define ISPHIST_CNT_CLEAR_SHIFT 7
1209#define ISPHIST_CNT_CLEAR_MASK 0x080
1210#define ISPHIST_CNT_CLEAR (1 << ISPHIST_CNT_CLEAR_SHIFT)
1211#define ISPHIST_CNT_CFA_SHIFT 6
1212#define ISPHIST_CNT_CFA_MASK 0x040
1213#define ISPHIST_CNT_BINS_SHIFT 4
1214#define ISPHIST_CNT_BINS_MASK 0x030
1215#define ISPHIST_CNT_SOURCE_SHIFT 3
1216#define ISPHIST_CNT_SOURCE_MASK 0x08
1217#define ISPHIST_CNT_SHIFT_SHIFT 0
1218#define ISPHIST_CNT_SHIFT_MASK 0x07
1219
1220#define ISPHIST_WB_GAIN_WG00_SHIFT 24
1221#define ISPHIST_WB_GAIN_WG00_MASK 0xFF000000
1222#define ISPHIST_WB_GAIN_WG01_SHIFT 16
1223#define ISPHIST_WB_GAIN_WG01_MASK 0xFF0000
1224#define ISPHIST_WB_GAIN_WG02_SHIFT 8
1225#define ISPHIST_WB_GAIN_WG02_MASK 0xFF00
1226#define ISPHIST_WB_GAIN_WG03_SHIFT 0
1227#define ISPHIST_WB_GAIN_WG03_MASK 0xFF
1228
1229#define ISPHIST_REG_START_END_MASK 0x3FFF
1230#define ISPHIST_REG_START_SHIFT 16
1231#define ISPHIST_REG_END_SHIFT 0
1232#define ISPHIST_REG_START_MASK (ISPHIST_REG_START_END_MASK << \
1233 ISPHIST_REG_START_SHIFT)
1234#define ISPHIST_REG_END_MASK (ISPHIST_REG_START_END_MASK << \
1235 ISPHIST_REG_END_SHIFT)
1236
1237#define ISPHIST_REG_MASK (ISPHIST_REG_START_MASK | \
1238 ISPHIST_REG_END_MASK)
1239
1240#define ISPHIST_ADDR_SHIFT 0
1241#define ISPHIST_ADDR_MASK 0x3FF
1242
1243#define ISPHIST_DATA_SHIFT 0
1244#define ISPHIST_DATA_MASK 0xFFFFF
1245
1246#define ISPHIST_RADD_SHIFT 0
1247#define ISPHIST_RADD_MASK 0xFFFFFFFF
1248
1249#define ISPHIST_RADD_OFF_SHIFT 0
1250#define ISPHIST_RADD_OFF_MASK 0xFFFF
1251
1252#define ISPHIST_HV_INFO_HSIZE_SHIFT 16
1253#define ISPHIST_HV_INFO_HSIZE_MASK 0x3FFF0000
1254#define ISPHIST_HV_INFO_VSIZE_SHIFT 0
1255#define ISPHIST_HV_INFO_VSIZE_MASK 0x3FFF
1256
1257#define ISPHIST_HV_INFO_MASK 0x3FFF3FFF
1258
1259#define ISPCCDC_LSC_ENABLE 1
1260#define ISPCCDC_LSC_BUSY (1 << 7)
1261#define ISPCCDC_LSC_GAIN_MODE_N_MASK 0x700
1262#define ISPCCDC_LSC_GAIN_MODE_N_SHIFT 8
1263#define ISPCCDC_LSC_GAIN_MODE_M_MASK 0x3800
1264#define ISPCCDC_LSC_GAIN_MODE_M_SHIFT 12
1265#define ISPCCDC_LSC_GAIN_FORMAT_MASK 0xE
1266#define ISPCCDC_LSC_GAIN_FORMAT_SHIFT 1
1267#define ISPCCDC_LSC_AFTER_REFORMATTER_MASK (1<<6)
1268
1269#define ISPCCDC_LSC_INITIAL_X_MASK 0x3F
1270#define ISPCCDC_LSC_INITIAL_X_SHIFT 0
1271#define ISPCCDC_LSC_INITIAL_Y_MASK 0x3F0000
1272#define ISPCCDC_LSC_INITIAL_Y_SHIFT 16
1273
1274/* -----------------------------------------------------------------------------
1275 * CSI2 receiver registers (ES2.0)
1276 */
1277
1278#define ISPCSI2_REVISION (0x000)
1279#define ISPCSI2_SYSCONFIG (0x010)
1280#define ISPCSI2_SYSCONFIG_MSTANDBY_MODE_SHIFT 12
1281#define ISPCSI2_SYSCONFIG_MSTANDBY_MODE_MASK \
1282 (0x3 << ISPCSI2_SYSCONFIG_MSTANDBY_MODE_SHIFT)
1283#define ISPCSI2_SYSCONFIG_MSTANDBY_MODE_FORCE \
1284 (0x0 << ISPCSI2_SYSCONFIG_MSTANDBY_MODE_SHIFT)
1285#define ISPCSI2_SYSCONFIG_MSTANDBY_MODE_NO \
1286 (0x1 << ISPCSI2_SYSCONFIG_MSTANDBY_MODE_SHIFT)
1287#define ISPCSI2_SYSCONFIG_MSTANDBY_MODE_SMART \
1288 (0x2 << ISPCSI2_SYSCONFIG_MSTANDBY_MODE_SHIFT)
1289#define ISPCSI2_SYSCONFIG_SOFT_RESET (1 << 1)
1290#define ISPCSI2_SYSCONFIG_AUTO_IDLE (1 << 0)
1291
1292#define ISPCSI2_SYSSTATUS (0x014)
1293#define ISPCSI2_SYSSTATUS_RESET_DONE (1 << 0)
1294
1295#define ISPCSI2_IRQSTATUS (0x018)
1296#define ISPCSI2_IRQSTATUS_OCP_ERR_IRQ (1 << 14)
1297#define ISPCSI2_IRQSTATUS_SHORT_PACKET_IRQ (1 << 13)
1298#define ISPCSI2_IRQSTATUS_ECC_CORRECTION_IRQ (1 << 12)
1299#define ISPCSI2_IRQSTATUS_ECC_NO_CORRECTION_IRQ (1 << 11)
1300#define ISPCSI2_IRQSTATUS_COMPLEXIO2_ERR_IRQ (1 << 10)
1301#define ISPCSI2_IRQSTATUS_COMPLEXIO1_ERR_IRQ (1 << 9)
1302#define ISPCSI2_IRQSTATUS_FIFO_OVF_IRQ (1 << 8)
1303#define ISPCSI2_IRQSTATUS_CONTEXT(n) (1 << (n))
1304
1305#define ISPCSI2_IRQENABLE (0x01c)
1306#define ISPCSI2_CTRL (0x040)
1307#define ISPCSI2_CTRL_VP_CLK_EN (1 << 15)
1308#define ISPCSI2_CTRL_VP_ONLY_EN (1 << 11)
1309#define ISPCSI2_CTRL_VP_OUT_CTRL_SHIFT 8
1310#define ISPCSI2_CTRL_VP_OUT_CTRL_MASK \
1311 (3 << ISPCSI2_CTRL_VP_OUT_CTRL_SHIFT)
1312#define ISPCSI2_CTRL_DBG_EN (1 << 7)
1313#define ISPCSI2_CTRL_BURST_SIZE_SHIFT 5
1314#define ISPCSI2_CTRL_BURST_SIZE_MASK \
1315 (3 << ISPCSI2_CTRL_BURST_SIZE_SHIFT)
1316#define ISPCSI2_CTRL_FRAME (1 << 3)
1317#define ISPCSI2_CTRL_ECC_EN (1 << 2)
1318#define ISPCSI2_CTRL_SECURE (1 << 1)
1319#define ISPCSI2_CTRL_IF_EN (1 << 0)
1320
1321#define ISPCSI2_DBG_H (0x044)
1322#define ISPCSI2_GNQ (0x048)
1323#define ISPCSI2_PHY_CFG (0x050)
1324#define ISPCSI2_PHY_CFG_RESET_CTRL (1 << 30)
1325#define ISPCSI2_PHY_CFG_RESET_DONE (1 << 29)
1326#define ISPCSI2_PHY_CFG_PWR_CMD_SHIFT 27
1327#define ISPCSI2_PHY_CFG_PWR_CMD_MASK \
1328 (0x3 << ISPCSI2_PHY_CFG_PWR_CMD_SHIFT)
1329#define ISPCSI2_PHY_CFG_PWR_CMD_OFF \
1330 (0x0 << ISPCSI2_PHY_CFG_PWR_CMD_SHIFT)
1331#define ISPCSI2_PHY_CFG_PWR_CMD_ON \
1332 (0x1 << ISPCSI2_PHY_CFG_PWR_CMD_SHIFT)
1333#define ISPCSI2_PHY_CFG_PWR_CMD_ULPW \
1334 (0x2 << ISPCSI2_PHY_CFG_PWR_CMD_SHIFT)
1335#define ISPCSI2_PHY_CFG_PWR_STATUS_SHIFT 25
1336#define ISPCSI2_PHY_CFG_PWR_STATUS_MASK \
1337 (0x3 << ISPCSI2_PHY_CFG_PWR_STATUS_SHIFT)
1338#define ISPCSI2_PHY_CFG_PWR_STATUS_OFF \
1339 (0x0 << ISPCSI2_PHY_CFG_PWR_STATUS_SHIFT)
1340#define ISPCSI2_PHY_CFG_PWR_STATUS_ON \
1341 (0x1 << ISPCSI2_PHY_CFG_PWR_STATUS_SHIFT)
1342#define ISPCSI2_PHY_CFG_PWR_STATUS_ULPW \
1343 (0x2 << ISPCSI2_PHY_CFG_PWR_STATUS_SHIFT)
1344#define ISPCSI2_PHY_CFG_PWR_AUTO (1 << 24)
1345
1346#define ISPCSI2_PHY_CFG_DATA_POL_SHIFT(n) (3 + ((n) * 4))
1347#define ISPCSI2_PHY_CFG_DATA_POL_MASK(n) \
1348 (0x1 << ISPCSI2_PHY_CFG_DATA_POL_SHIFT(n))
1349#define ISPCSI2_PHY_CFG_DATA_POL_PN(n) \
1350 (0x0 << ISPCSI2_PHY_CFG_DATA_POL_SHIFT(n))
1351#define ISPCSI2_PHY_CFG_DATA_POL_NP(n) \
1352 (0x1 << ISPCSI2_PHY_CFG_DATA_POL_SHIFT(n))
1353
1354#define ISPCSI2_PHY_CFG_DATA_POSITION_SHIFT(n) ((n) * 4)
1355#define ISPCSI2_PHY_CFG_DATA_POSITION_MASK(n) \
1356 (0x7 << ISPCSI2_PHY_CFG_DATA_POSITION_SHIFT(n))
1357#define ISPCSI2_PHY_CFG_DATA_POSITION_NC(n) \
1358 (0x0 << ISPCSI2_PHY_CFG_DATA_POSITION_SHIFT(n))
1359#define ISPCSI2_PHY_CFG_DATA_POSITION_1(n) \
1360 (0x1 << ISPCSI2_PHY_CFG_DATA_POSITION_SHIFT(n))
1361#define ISPCSI2_PHY_CFG_DATA_POSITION_2(n) \
1362 (0x2 << ISPCSI2_PHY_CFG_DATA_POSITION_SHIFT(n))
1363#define ISPCSI2_PHY_CFG_DATA_POSITION_3(n) \
1364 (0x3 << ISPCSI2_PHY_CFG_DATA_POSITION_SHIFT(n))
1365#define ISPCSI2_PHY_CFG_DATA_POSITION_4(n) \
1366 (0x4 << ISPCSI2_PHY_CFG_DATA_POSITION_SHIFT(n))
1367#define ISPCSI2_PHY_CFG_DATA_POSITION_5(n) \
1368 (0x5 << ISPCSI2_PHY_CFG_DATA_POSITION_SHIFT(n))
1369
1370#define ISPCSI2_PHY_CFG_CLOCK_POL_SHIFT 3
1371#define ISPCSI2_PHY_CFG_CLOCK_POL_MASK \
1372 (0x1 << ISPCSI2_PHY_CFG_CLOCK_POL_SHIFT)
1373#define ISPCSI2_PHY_CFG_CLOCK_POL_PN \
1374 (0x0 << ISPCSI2_PHY_CFG_CLOCK_POL_SHIFT)
1375#define ISPCSI2_PHY_CFG_CLOCK_POL_NP \
1376 (0x1 << ISPCSI2_PHY_CFG_CLOCK_POL_SHIFT)
1377
1378#define ISPCSI2_PHY_CFG_CLOCK_POSITION_SHIFT 0
1379#define ISPCSI2_PHY_CFG_CLOCK_POSITION_MASK \
1380 (0x7 << ISPCSI2_PHY_CFG_CLOCK_POSITION_SHIFT)
1381#define ISPCSI2_PHY_CFG_CLOCK_POSITION_1 \
1382 (0x1 << ISPCSI2_PHY_CFG_CLOCK_POSITION_SHIFT)
1383#define ISPCSI2_PHY_CFG_CLOCK_POSITION_2 \
1384 (0x2 << ISPCSI2_PHY_CFG_CLOCK_POSITION_SHIFT)
1385#define ISPCSI2_PHY_CFG_CLOCK_POSITION_3 \
1386 (0x3 << ISPCSI2_PHY_CFG_CLOCK_POSITION_SHIFT)
1387#define ISPCSI2_PHY_CFG_CLOCK_POSITION_4 \
1388 (0x4 << ISPCSI2_PHY_CFG_CLOCK_POSITION_SHIFT)
1389#define ISPCSI2_PHY_CFG_CLOCK_POSITION_5 \
1390 (0x5 << ISPCSI2_PHY_CFG_CLOCK_POSITION_SHIFT)
1391
1392#define ISPCSI2_PHY_IRQSTATUS (0x054)
1393#define ISPCSI2_PHY_IRQSTATUS_STATEALLULPMEXIT (1 << 26)
1394#define ISPCSI2_PHY_IRQSTATUS_STATEALLULPMENTER (1 << 25)
1395#define ISPCSI2_PHY_IRQSTATUS_STATEULPM5 (1 << 24)
1396#define ISPCSI2_PHY_IRQSTATUS_STATEULPM4 (1 << 23)
1397#define ISPCSI2_PHY_IRQSTATUS_STATEULPM3 (1 << 22)
1398#define ISPCSI2_PHY_IRQSTATUS_STATEULPM2 (1 << 21)
1399#define ISPCSI2_PHY_IRQSTATUS_STATEULPM1 (1 << 20)
1400#define ISPCSI2_PHY_IRQSTATUS_ERRCONTROL5 (1 << 19)
1401#define ISPCSI2_PHY_IRQSTATUS_ERRCONTROL4 (1 << 18)
1402#define ISPCSI2_PHY_IRQSTATUS_ERRCONTROL3 (1 << 17)
1403#define ISPCSI2_PHY_IRQSTATUS_ERRCONTROL2 (1 << 16)
1404#define ISPCSI2_PHY_IRQSTATUS_ERRCONTROL1 (1 << 15)
1405#define ISPCSI2_PHY_IRQSTATUS_ERRESC5 (1 << 14)
1406#define ISPCSI2_PHY_IRQSTATUS_ERRESC4 (1 << 13)
1407#define ISPCSI2_PHY_IRQSTATUS_ERRESC3 (1 << 12)
1408#define ISPCSI2_PHY_IRQSTATUS_ERRESC2 (1 << 11)
1409#define ISPCSI2_PHY_IRQSTATUS_ERRESC1 (1 << 10)
1410#define ISPCSI2_PHY_IRQSTATUS_ERRSOTSYNCHS5 (1 << 9)
1411#define ISPCSI2_PHY_IRQSTATUS_ERRSOTSYNCHS4 (1 << 8)
1412#define ISPCSI2_PHY_IRQSTATUS_ERRSOTSYNCHS3 (1 << 7)
1413#define ISPCSI2_PHY_IRQSTATUS_ERRSOTSYNCHS2 (1 << 6)
1414#define ISPCSI2_PHY_IRQSTATUS_ERRSOTSYNCHS1 (1 << 5)
1415#define ISPCSI2_PHY_IRQSTATUS_ERRSOTHS5 (1 << 4)
1416#define ISPCSI2_PHY_IRQSTATUS_ERRSOTHS4 (1 << 3)
1417#define ISPCSI2_PHY_IRQSTATUS_ERRSOTHS3 (1 << 2)
1418#define ISPCSI2_PHY_IRQSTATUS_ERRSOTHS2 (1 << 1)
1419#define ISPCSI2_PHY_IRQSTATUS_ERRSOTHS1 1
1420
1421#define ISPCSI2_SHORT_PACKET (0x05c)
1422#define ISPCSI2_PHY_IRQENABLE (0x060)
1423#define ISPCSI2_PHY_IRQENABLE_STATEALLULPMEXIT (1 << 26)
1424#define ISPCSI2_PHY_IRQENABLE_STATEALLULPMENTER (1 << 25)
1425#define ISPCSI2_PHY_IRQENABLE_STATEULPM5 (1 << 24)
1426#define ISPCSI2_PHY_IRQENABLE_STATEULPM4 (1 << 23)
1427#define ISPCSI2_PHY_IRQENABLE_STATEULPM3 (1 << 22)
1428#define ISPCSI2_PHY_IRQENABLE_STATEULPM2 (1 << 21)
1429#define ISPCSI2_PHY_IRQENABLE_STATEULPM1 (1 << 20)
1430#define ISPCSI2_PHY_IRQENABLE_ERRCONTROL5 (1 << 19)
1431#define ISPCSI2_PHY_IRQENABLE_ERRCONTROL4 (1 << 18)
1432#define ISPCSI2_PHY_IRQENABLE_ERRCONTROL3 (1 << 17)
1433#define ISPCSI2_PHY_IRQENABLE_ERRCONTROL2 (1 << 16)
1434#define ISPCSI2_PHY_IRQENABLE_ERRCONTROL1 (1 << 15)
1435#define ISPCSI2_PHY_IRQENABLE_ERRESC5 (1 << 14)
1436#define ISPCSI2_PHY_IRQENABLE_ERRESC4 (1 << 13)
1437#define ISPCSI2_PHY_IRQENABLE_ERRESC3 (1 << 12)
1438#define ISPCSI2_PHY_IRQENABLE_ERRESC2 (1 << 11)
1439#define ISPCSI2_PHY_IRQENABLE_ERRESC1 (1 << 10)
1440#define ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS5 (1 << 9)
1441#define ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS4 (1 << 8)
1442#define ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS3 (1 << 7)
1443#define ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS2 (1 << 6)
1444#define ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS1 (1 << 5)
1445#define ISPCSI2_PHY_IRQENABLE_ERRSOTHS5 (1 << 4)
1446#define ISPCSI2_PHY_IRQENABLE_ERRSOTHS4 (1 << 3)
1447#define ISPCSI2_PHY_IRQENABLE_ERRSOTHS3 (1 << 2)
1448#define ISPCSI2_PHY_IRQENABLE_ERRSOTHS2 (1 << 1)
1449#define ISPCSI2_PHY_IRQENABLE_ERRSOTHS1 (1 << 0)
1450
1451#define ISPCSI2_DBG_P (0x068)
1452#define ISPCSI2_TIMING (0x06c)
1453#define ISPCSI2_TIMING_FORCE_RX_MODE_IO(n) (1 << ((16 * ((n) - 1)) + 15))
1454#define ISPCSI2_TIMING_STOP_STATE_X16_IO(n) (1 << ((16 * ((n) - 1)) + 14))
1455#define ISPCSI2_TIMING_STOP_STATE_X4_IO(n) (1 << ((16 * ((n) - 1)) + 13))
1456#define ISPCSI2_TIMING_STOP_STATE_COUNTER_IO_SHIFT(n) (16 * ((n) - 1))
1457#define ISPCSI2_TIMING_STOP_STATE_COUNTER_IO_MASK(n) \
1458 (0x1fff << ISPCSI2_TIMING_STOP_STATE_COUNTER_IO_SHIFT(n))
1459
1460#define ISPCSI2_CTX_CTRL1(n) ((0x070) + 0x20 * (n))
1461#define ISPCSI2_CTX_CTRL1_COUNT_SHIFT 8
1462#define ISPCSI2_CTX_CTRL1_COUNT_MASK \
1463 (0xff << ISPCSI2_CTX_CTRL1_COUNT_SHIFT)
1464#define ISPCSI2_CTX_CTRL1_EOF_EN (1 << 7)
1465#define ISPCSI2_CTX_CTRL1_EOL_EN (1 << 6)
1466#define ISPCSI2_CTX_CTRL1_CS_EN (1 << 5)
1467#define ISPCSI2_CTX_CTRL1_COUNT_UNLOCK (1 << 4)
1468#define ISPCSI2_CTX_CTRL1_PING_PONG (1 << 3)
1469#define ISPCSI2_CTX_CTRL1_CTX_EN (1 << 0)
1470
1471#define ISPCSI2_CTX_CTRL2(n) ((0x074) + 0x20 * (n))
1472#define ISPCSI2_CTX_CTRL2_USER_DEF_MAP_SHIFT 13
1473#define ISPCSI2_CTX_CTRL2_USER_DEF_MAP_MASK \
1474 (0x3 << ISPCSI2_CTX_CTRL2_USER_DEF_MAP_SHIFT)
1475#define ISPCSI2_CTX_CTRL2_VIRTUAL_ID_SHIFT 11
1476#define ISPCSI2_CTX_CTRL2_VIRTUAL_ID_MASK \
1477 (0x3 << ISPCSI2_CTX_CTRL2_VIRTUAL_ID_SHIFT)
1478#define ISPCSI2_CTX_CTRL2_DPCM_PRED (1 << 10)
1479#define ISPCSI2_CTX_CTRL2_FORMAT_SHIFT 0
1480#define ISPCSI2_CTX_CTRL2_FORMAT_MASK \
1481 (0x3ff << ISPCSI2_CTX_CTRL2_FORMAT_SHIFT)
1482#define ISPCSI2_CTX_CTRL2_FRAME_SHIFT 16
1483#define ISPCSI2_CTX_CTRL2_FRAME_MASK \
1484 (0xffff << ISPCSI2_CTX_CTRL2_FRAME_SHIFT)
1485
1486#define ISPCSI2_CTX_DAT_OFST(n) ((0x078) + 0x20 * (n))
1487#define ISPCSI2_CTX_DAT_OFST_OFST_SHIFT 0
1488#define ISPCSI2_CTX_DAT_OFST_OFST_MASK \
1489 (0x1ffe0 << ISPCSI2_CTX_DAT_OFST_OFST_SHIFT)
1490
1491#define ISPCSI2_CTX_DAT_PING_ADDR(n) ((0x07c) + 0x20 * (n))
1492#define ISPCSI2_CTX_DAT_PONG_ADDR(n) ((0x080) + 0x20 * (n))
1493#define ISPCSI2_CTX_IRQENABLE(n) ((0x084) + 0x20 * (n))
1494#define ISPCSI2_CTX_IRQENABLE_ECC_CORRECTION_IRQ (1 << 8)
1495#define ISPCSI2_CTX_IRQENABLE_LINE_NUMBER_IRQ (1 << 7)
1496#define ISPCSI2_CTX_IRQENABLE_FRAME_NUMBER_IRQ (1 << 6)
1497#define ISPCSI2_CTX_IRQENABLE_CS_IRQ (1 << 5)
1498#define ISPCSI2_CTX_IRQENABLE_LE_IRQ (1 << 3)
1499#define ISPCSI2_CTX_IRQENABLE_LS_IRQ (1 << 2)
1500#define ISPCSI2_CTX_IRQENABLE_FE_IRQ (1 << 1)
1501#define ISPCSI2_CTX_IRQENABLE_FS_IRQ (1 << 0)
1502
1503#define ISPCSI2_CTX_IRQSTATUS(n) ((0x088) + 0x20 * (n))
1504#define ISPCSI2_CTX_IRQSTATUS_ECC_CORRECTION_IRQ (1 << 8)
1505#define ISPCSI2_CTX_IRQSTATUS_LINE_NUMBER_IRQ (1 << 7)
1506#define ISPCSI2_CTX_IRQSTATUS_FRAME_NUMBER_IRQ (1 << 6)
1507#define ISPCSI2_CTX_IRQSTATUS_CS_IRQ (1 << 5)
1508#define ISPCSI2_CTX_IRQSTATUS_LE_IRQ (1 << 3)
1509#define ISPCSI2_CTX_IRQSTATUS_LS_IRQ (1 << 2)
1510#define ISPCSI2_CTX_IRQSTATUS_FE_IRQ (1 << 1)
1511#define ISPCSI2_CTX_IRQSTATUS_FS_IRQ (1 << 0)
1512
1513#define ISPCSI2_CTX_CTRL3(n) ((0x08c) + 0x20 * (n))
1514#define ISPCSI2_CTX_CTRL3_ALPHA_SHIFT 5
1515#define ISPCSI2_CTX_CTRL3_ALPHA_MASK \
1516 (0x3fff << ISPCSI2_CTX_CTRL3_ALPHA_SHIFT)
1517
1518/* This instance is for OMAP3630 only */
1519#define ISPCSI2_CTX_TRANSCODEH(n) (0x000 + 0x8 * (n))
1520#define ISPCSI2_CTX_TRANSCODEH_HCOUNT_SHIFT 16
1521#define ISPCSI2_CTX_TRANSCODEH_HCOUNT_MASK \
1522 (0x1fff << ISPCSI2_CTX_TRANSCODEH_HCOUNT_SHIFT)
1523#define ISPCSI2_CTX_TRANSCODEH_HSKIP_SHIFT 0
1524#define ISPCSI2_CTX_TRANSCODEH_HSKIP_MASK \
1525 (0x1fff << ISPCSI2_CTX_TRANSCODEH_HCOUNT_SHIFT)
1526#define ISPCSI2_CTX_TRANSCODEV(n) (0x004 + 0x8 * (n))
1527#define ISPCSI2_CTX_TRANSCODEV_VCOUNT_SHIFT 16
1528#define ISPCSI2_CTX_TRANSCODEV_VCOUNT_MASK \
1529 (0x1fff << ISPCSI2_CTX_TRANSCODEV_VCOUNT_SHIFT)
1530#define ISPCSI2_CTX_TRANSCODEV_VSKIP_SHIFT 0
1531#define ISPCSI2_CTX_TRANSCODEV_VSKIP_MASK \
1532 (0x1fff << ISPCSI2_CTX_TRANSCODEV_VCOUNT_SHIFT)
1533
1534/* -----------------------------------------------------------------------------
1535 * CSI PHY registers
1536 */
1537
1538#define ISPCSIPHY_REG0 (0x000)
1539#define ISPCSIPHY_REG0_THS_TERM_SHIFT 8
1540#define ISPCSIPHY_REG0_THS_TERM_MASK \
1541 (0xff << ISPCSIPHY_REG0_THS_TERM_SHIFT)
1542#define ISPCSIPHY_REG0_THS_SETTLE_SHIFT 0
1543#define ISPCSIPHY_REG0_THS_SETTLE_MASK \
1544 (0xff << ISPCSIPHY_REG0_THS_SETTLE_SHIFT)
1545
1546#define ISPCSIPHY_REG1 (0x004)
1547#define ISPCSIPHY_REG1_RESET_DONE_CTRLCLK (1 << 29)
1548/* This field is for OMAP3630 only */
1549#define ISPCSIPHY_REG1_CLOCK_MISS_DETECTOR_STATUS (1 << 25)
1550#define ISPCSIPHY_REG1_TCLK_TERM_SHIFT 18
1551#define ISPCSIPHY_REG1_TCLK_TERM_MASK \
1552 (0x7f << ISPCSIPHY_REG1_TCLK_TERM_SHIFT)
1553#define ISPCSIPHY_REG1_DPHY_HS_SYNC_PATTERN_SHIFT 10
1554#define ISPCSIPHY_REG1_DPHY_HS_SYNC_PATTERN_MASK \
1555 (0xff << ISPCSIPHY_REG1_DPHY_HS_SYNC_PATTERN)
1556/* This field is for OMAP3430 only */
1557#define ISPCSIPHY_REG1_TCLK_MISS_SHIFT 8
1558#define ISPCSIPHY_REG1_TCLK_MISS_MASK \
1559 (0x3 << ISPCSIPHY_REG1_TCLK_MISS_SHIFT)
1560/* This field is for OMAP3630 only */
1561#define ISPCSIPHY_REG1_CTRLCLK_DIV_FACTOR_SHIFT 8
1562#define ISPCSIPHY_REG1_CTRLCLK_DIV_FACTOR_MASK \
1563 (0x3 << ISPCSIPHY_REG1_CTRLCLK_DIV_FACTOR_SHIFT)
1564#define ISPCSIPHY_REG1_TCLK_SETTLE_SHIFT 0
1565#define ISPCSIPHY_REG1_TCLK_SETTLE_MASK \
1566 (0xff << ISPCSIPHY_REG1_TCLK_SETTLE_SHIFT)
1567
1568/* This register is for OMAP3630 only */
1569#define ISPCSIPHY_REG2 (0x008)
1570#define ISPCSIPHY_REG2_TRIGGER_CMD_RXTRIGESC0_SHIFT 30
1571#define ISPCSIPHY_REG2_TRIGGER_CMD_RXTRIGESC0_MASK \
1572 (0x3 << ISPCSIPHY_REG2_TRIGGER_CMD_RXTRIGESC0_SHIFT)
1573#define ISPCSIPHY_REG2_TRIGGER_CMD_RXTRIGESC1_SHIFT 28
1574#define ISPCSIPHY_REG2_TRIGGER_CMD_RXTRIGESC1_MASK \
1575 (0x3 << ISPCSIPHY_REG2_TRIGGER_CMD_RXTRIGESC1_SHIFT)
1576#define ISPCSIPHY_REG2_TRIGGER_CMD_RXTRIGESC2_SHIFT 26
1577#define ISPCSIPHY_REG2_TRIGGER_CMD_RXTRIGESC2_MASK \
1578 (0x3 << ISPCSIPHY_REG2_TRIGGER_CMD_RXTRIGESC2_SHIFT)
1579#define ISPCSIPHY_REG2_TRIGGER_CMD_RXTRIGESC3_SHIFT 24
1580#define ISPCSIPHY_REG2_TRIGGER_CMD_RXTRIGESC3_MASK \
1581 (0x3 << ISPCSIPHY_REG2_TRIGGER_CMD_RXTRIGESC3_SHIFT)
1582#define ISPCSIPHY_REG2_CCP2_SYNC_PATTERN_SHIFT 0
1583#define ISPCSIPHY_REG2_CCP2_SYNC_PATTERN_MASK \
1584 (0x7fffff << ISPCSIPHY_REG2_CCP2_SYNC_PATTERN_SHIFT)
1585
1586#endif /* OMAP3_ISP_REG_H */
diff --git a/drivers/media/video/omap3isp/ispresizer.c b/drivers/media/video/omap3isp/ispresizer.c
deleted file mode 100644
index d11fb261d530..000000000000
--- a/drivers/media/video/omap3isp/ispresizer.c
+++ /dev/null
@@ -1,1778 +0,0 @@
1/*
2 * ispresizer.c
3 *
4 * TI OMAP3 ISP - Resizer module
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc
8 *
9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 * Sakari Ailus <sakari.ailus@iki.fi>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 */
26
27#include <linux/device.h>
28#include <linux/mm.h>
29#include <linux/module.h>
30
31#include "isp.h"
32#include "ispreg.h"
33#include "ispresizer.h"
34
35/*
36 * Resizer Constants
37 */
38#define MIN_RESIZE_VALUE 64
39#define MID_RESIZE_VALUE 512
40#define MAX_RESIZE_VALUE 1024
41
42#define MIN_IN_WIDTH 32
43#define MIN_IN_HEIGHT 32
44#define MAX_IN_WIDTH_MEMORY_MODE 4095
45#define MAX_IN_WIDTH_ONTHEFLY_MODE_ES1 1280
46#define MAX_IN_WIDTH_ONTHEFLY_MODE_ES2 4095
47#define MAX_IN_HEIGHT 4095
48
49#define MIN_OUT_WIDTH 16
50#define MIN_OUT_HEIGHT 2
51#define MAX_OUT_HEIGHT 4095
52
53/*
54 * Resizer Use Constraints
55 * "TRM ES3.1, table 12-46"
56 */
57#define MAX_4TAP_OUT_WIDTH_ES1 1280
58#define MAX_7TAP_OUT_WIDTH_ES1 640
59#define MAX_4TAP_OUT_WIDTH_ES2 3312
60#define MAX_7TAP_OUT_WIDTH_ES2 1650
61#define MAX_4TAP_OUT_WIDTH_3630 4096
62#define MAX_7TAP_OUT_WIDTH_3630 2048
63
64/*
65 * Constants for ratio calculation
66 */
67#define RESIZE_DIVISOR 256
68#define DEFAULT_PHASE 1
69
70/*
71 * Default (and only) configuration of filter coefficients.
72 * 7-tap mode is for scale factors 0.25x to 0.5x.
73 * 4-tap mode is for scale factors 0.5x to 4.0x.
74 * There shouldn't be any reason to recalculate these, EVER.
75 */
76static const struct isprsz_coef filter_coefs = {
77 /* For 8-phase 4-tap horizontal filter: */
78 {
79 0x0000, 0x0100, 0x0000, 0x0000,
80 0x03FA, 0x00F6, 0x0010, 0x0000,
81 0x03F9, 0x00DB, 0x002C, 0x0000,
82 0x03FB, 0x00B3, 0x0053, 0x03FF,
83 0x03FD, 0x0082, 0x0084, 0x03FD,
84 0x03FF, 0x0053, 0x00B3, 0x03FB,
85 0x0000, 0x002C, 0x00DB, 0x03F9,
86 0x0000, 0x0010, 0x00F6, 0x03FA
87 },
88 /* For 8-phase 4-tap vertical filter: */
89 {
90 0x0000, 0x0100, 0x0000, 0x0000,
91 0x03FA, 0x00F6, 0x0010, 0x0000,
92 0x03F9, 0x00DB, 0x002C, 0x0000,
93 0x03FB, 0x00B3, 0x0053, 0x03FF,
94 0x03FD, 0x0082, 0x0084, 0x03FD,
95 0x03FF, 0x0053, 0x00B3, 0x03FB,
96 0x0000, 0x002C, 0x00DB, 0x03F9,
97 0x0000, 0x0010, 0x00F6, 0x03FA
98 },
99 /* For 4-phase 7-tap horizontal filter: */
100 #define DUMMY 0
101 {
102 0x0004, 0x0023, 0x005A, 0x0058, 0x0023, 0x0004, 0x0000, DUMMY,
103 0x0002, 0x0018, 0x004d, 0x0060, 0x0031, 0x0008, 0x0000, DUMMY,
104 0x0001, 0x000f, 0x003f, 0x0062, 0x003f, 0x000f, 0x0001, DUMMY,
105 0x0000, 0x0008, 0x0031, 0x0060, 0x004d, 0x0018, 0x0002, DUMMY
106 },
107 /* For 4-phase 7-tap vertical filter: */
108 {
109 0x0004, 0x0023, 0x005A, 0x0058, 0x0023, 0x0004, 0x0000, DUMMY,
110 0x0002, 0x0018, 0x004d, 0x0060, 0x0031, 0x0008, 0x0000, DUMMY,
111 0x0001, 0x000f, 0x003f, 0x0062, 0x003f, 0x000f, 0x0001, DUMMY,
112 0x0000, 0x0008, 0x0031, 0x0060, 0x004d, 0x0018, 0x0002, DUMMY
113 }
114 /*
115 * The dummy padding is required in 7-tap mode because of how the
116 * registers are arranged physically.
117 */
118 #undef DUMMY
119};
120
121/*
122 * __resizer_get_format - helper function for getting resizer format
123 * @res : pointer to resizer private structure
124 * @pad : pad number
125 * @fh : V4L2 subdev file handle
126 * @which : wanted subdev format
127 * return zero
128 */
129static struct v4l2_mbus_framefmt *
130__resizer_get_format(struct isp_res_device *res, struct v4l2_subdev_fh *fh,
131 unsigned int pad, enum v4l2_subdev_format_whence which)
132{
133 if (which == V4L2_SUBDEV_FORMAT_TRY)
134 return v4l2_subdev_get_try_format(fh, pad);
135 else
136 return &res->formats[pad];
137}
138
139/*
140 * __resizer_get_crop - helper function for getting resizer crop rectangle
141 * @res : pointer to resizer private structure
142 * @fh : V4L2 subdev file handle
143 * @which : wanted subdev crop rectangle
144 */
145static struct v4l2_rect *
146__resizer_get_crop(struct isp_res_device *res, struct v4l2_subdev_fh *fh,
147 enum v4l2_subdev_format_whence which)
148{
149 if (which == V4L2_SUBDEV_FORMAT_TRY)
150 return v4l2_subdev_get_try_crop(fh, RESZ_PAD_SINK);
151 else
152 return &res->crop.request;
153}
154
155/*
156 * resizer_set_filters - Set resizer filters
157 * @res: Device context.
158 * @h_coeff: horizontal coefficient
159 * @v_coeff: vertical coefficient
160 * Return none
161 */
162static void resizer_set_filters(struct isp_res_device *res, const u16 *h_coeff,
163 const u16 *v_coeff)
164{
165 struct isp_device *isp = to_isp_device(res);
166 u32 startaddr_h, startaddr_v, tmp_h, tmp_v;
167 int i;
168
169 startaddr_h = ISPRSZ_HFILT10;
170 startaddr_v = ISPRSZ_VFILT10;
171
172 for (i = 0; i < COEFF_CNT; i += 2) {
173 tmp_h = h_coeff[i] |
174 (h_coeff[i + 1] << ISPRSZ_HFILT_COEF1_SHIFT);
175 tmp_v = v_coeff[i] |
176 (v_coeff[i + 1] << ISPRSZ_VFILT_COEF1_SHIFT);
177 isp_reg_writel(isp, tmp_h, OMAP3_ISP_IOMEM_RESZ, startaddr_h);
178 isp_reg_writel(isp, tmp_v, OMAP3_ISP_IOMEM_RESZ, startaddr_v);
179 startaddr_h += 4;
180 startaddr_v += 4;
181 }
182}
183
184/*
185 * resizer_set_bilinear - Chrominance horizontal algorithm select
186 * @res: Device context.
187 * @type: Filtering interpolation type.
188 *
189 * Filtering that is same as luminance processing is
190 * intended only for downsampling, and bilinear interpolation
191 * is intended only for upsampling.
192 */
193static void resizer_set_bilinear(struct isp_res_device *res,
194 enum resizer_chroma_algo type)
195{
196 struct isp_device *isp = to_isp_device(res);
197
198 if (type == RSZ_BILINEAR)
199 isp_reg_set(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT,
200 ISPRSZ_CNT_CBILIN);
201 else
202 isp_reg_clr(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT,
203 ISPRSZ_CNT_CBILIN);
204}
205
206/*
207 * resizer_set_ycpos - Luminance and chrominance order
208 * @res: Device context.
209 * @order: order type.
210 */
211static void resizer_set_ycpos(struct isp_res_device *res,
212 enum v4l2_mbus_pixelcode pixelcode)
213{
214 struct isp_device *isp = to_isp_device(res);
215
216 switch (pixelcode) {
217 case V4L2_MBUS_FMT_YUYV8_1X16:
218 isp_reg_set(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT,
219 ISPRSZ_CNT_YCPOS);
220 break;
221 case V4L2_MBUS_FMT_UYVY8_1X16:
222 isp_reg_clr(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT,
223 ISPRSZ_CNT_YCPOS);
224 break;
225 default:
226 return;
227 }
228}
229
230/*
231 * resizer_set_phase - Setup horizontal and vertical starting phase
232 * @res: Device context.
233 * @h_phase: horizontal phase parameters.
234 * @v_phase: vertical phase parameters.
235 *
236 * Horizontal and vertical phase range is 0 to 7
237 */
238static void resizer_set_phase(struct isp_res_device *res, u32 h_phase,
239 u32 v_phase)
240{
241 struct isp_device *isp = to_isp_device(res);
242 u32 rgval = 0;
243
244 rgval = isp_reg_readl(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT) &
245 ~(ISPRSZ_CNT_HSTPH_MASK | ISPRSZ_CNT_VSTPH_MASK);
246 rgval |= (h_phase << ISPRSZ_CNT_HSTPH_SHIFT) & ISPRSZ_CNT_HSTPH_MASK;
247 rgval |= (v_phase << ISPRSZ_CNT_VSTPH_SHIFT) & ISPRSZ_CNT_VSTPH_MASK;
248
249 isp_reg_writel(isp, rgval, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT);
250}
251
252/*
253 * resizer_set_luma - Setup luminance enhancer parameters
254 * @res: Device context.
255 * @luma: Structure for luminance enhancer parameters.
256 *
257 * Algorithm select:
258 * 0x0: Disable
259 * 0x1: [-1 2 -1]/2 high-pass filter
260 * 0x2: [-1 -2 6 -2 -1]/4 high-pass filter
261 *
262 * Maximum gain:
263 * The data is coded in U4Q4 representation.
264 *
265 * Slope:
266 * The data is coded in U4Q4 representation.
267 *
268 * Coring offset:
269 * The data is coded in U8Q0 representation.
270 *
271 * The new luminance value is computed as:
272 * Y += HPF(Y) x max(GAIN, (HPF(Y) - CORE) x SLOP + 8) >> 4.
273 */
274static void resizer_set_luma(struct isp_res_device *res,
275 struct resizer_luma_yenh *luma)
276{
277 struct isp_device *isp = to_isp_device(res);
278 u32 rgval = 0;
279
280 rgval = (luma->algo << ISPRSZ_YENH_ALGO_SHIFT)
281 & ISPRSZ_YENH_ALGO_MASK;
282 rgval |= (luma->gain << ISPRSZ_YENH_GAIN_SHIFT)
283 & ISPRSZ_YENH_GAIN_MASK;
284 rgval |= (luma->slope << ISPRSZ_YENH_SLOP_SHIFT)
285 & ISPRSZ_YENH_SLOP_MASK;
286 rgval |= (luma->core << ISPRSZ_YENH_CORE_SHIFT)
287 & ISPRSZ_YENH_CORE_MASK;
288
289 isp_reg_writel(isp, rgval, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_YENH);
290}
291
292/*
293 * resizer_set_source - Input source select
294 * @res: Device context.
295 * @source: Input source type
296 *
297 * If this field is set to RESIZER_INPUT_VP, the resizer input is fed from
298 * Preview/CCDC engine, otherwise from memory.
299 */
300static void resizer_set_source(struct isp_res_device *res,
301 enum resizer_input_entity source)
302{
303 struct isp_device *isp = to_isp_device(res);
304
305 if (source == RESIZER_INPUT_MEMORY)
306 isp_reg_set(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT,
307 ISPRSZ_CNT_INPSRC);
308 else
309 isp_reg_clr(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT,
310 ISPRSZ_CNT_INPSRC);
311}
312
313/*
314 * resizer_set_ratio - Setup horizontal and vertical resizing value
315 * @res: Device context.
316 * @ratio: Structure for ratio parameters.
317 *
318 * Resizing range from 64 to 1024
319 */
320static void resizer_set_ratio(struct isp_res_device *res,
321 const struct resizer_ratio *ratio)
322{
323 struct isp_device *isp = to_isp_device(res);
324 const u16 *h_filter, *v_filter;
325 u32 rgval = 0;
326
327 rgval = isp_reg_readl(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT) &
328 ~(ISPRSZ_CNT_HRSZ_MASK | ISPRSZ_CNT_VRSZ_MASK);
329 rgval |= ((ratio->horz - 1) << ISPRSZ_CNT_HRSZ_SHIFT)
330 & ISPRSZ_CNT_HRSZ_MASK;
331 rgval |= ((ratio->vert - 1) << ISPRSZ_CNT_VRSZ_SHIFT)
332 & ISPRSZ_CNT_VRSZ_MASK;
333 isp_reg_writel(isp, rgval, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT);
334
335 /* prepare horizontal filter coefficients */
336 if (ratio->horz > MID_RESIZE_VALUE)
337 h_filter = &filter_coefs.h_filter_coef_7tap[0];
338 else
339 h_filter = &filter_coefs.h_filter_coef_4tap[0];
340
341 /* prepare vertical filter coefficients */
342 if (ratio->vert > MID_RESIZE_VALUE)
343 v_filter = &filter_coefs.v_filter_coef_7tap[0];
344 else
345 v_filter = &filter_coefs.v_filter_coef_4tap[0];
346
347 resizer_set_filters(res, h_filter, v_filter);
348}
349
350/*
351 * resizer_set_dst_size - Setup the output height and width
352 * @res: Device context.
353 * @width: Output width.
354 * @height: Output height.
355 *
356 * Width :
357 * The value must be EVEN.
358 *
359 * Height:
360 * The number of bytes written to SDRAM must be
361 * a multiple of 16-bytes if the vertical resizing factor
362 * is greater than 1x (upsizing)
363 */
364static void resizer_set_output_size(struct isp_res_device *res,
365 u32 width, u32 height)
366{
367 struct isp_device *isp = to_isp_device(res);
368 u32 rgval = 0;
369
370 dev_dbg(isp->dev, "Output size[w/h]: %dx%d\n", width, height);
371 rgval = (width << ISPRSZ_OUT_SIZE_HORZ_SHIFT)
372 & ISPRSZ_OUT_SIZE_HORZ_MASK;
373 rgval |= (height << ISPRSZ_OUT_SIZE_VERT_SHIFT)
374 & ISPRSZ_OUT_SIZE_VERT_MASK;
375 isp_reg_writel(isp, rgval, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_OUT_SIZE);
376}
377
378/*
379 * resizer_set_output_offset - Setup memory offset for the output lines.
380 * @res: Device context.
381 * @offset: Memory offset.
382 *
383 * The 5 LSBs are forced to be zeros by the hardware to align on a 32-byte
384 * boundary; the 5 LSBs are read-only. For optimal use of SDRAM bandwidth,
385 * the SDRAM line offset must be set on a 256-byte boundary
386 */
387static void resizer_set_output_offset(struct isp_res_device *res, u32 offset)
388{
389 struct isp_device *isp = to_isp_device(res);
390
391 isp_reg_writel(isp, offset, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_SDR_OUTOFF);
392}
393
394/*
395 * resizer_set_start - Setup vertical and horizontal start position
396 * @res: Device context.
397 * @left: Horizontal start position.
398 * @top: Vertical start position.
399 *
400 * Vertical start line:
401 * This field makes sense only when the resizer obtains its input
402 * from the preview engine/CCDC
403 *
404 * Horizontal start pixel:
405 * Pixels are coded on 16 bits for YUV and 8 bits for color separate data.
406 * When the resizer gets its input from SDRAM, this field must be set
407 * to <= 15 for YUV 16-bit data and <= 31 for 8-bit color separate data
408 */
409static void resizer_set_start(struct isp_res_device *res, u32 left, u32 top)
410{
411 struct isp_device *isp = to_isp_device(res);
412 u32 rgval = 0;
413
414 rgval = (left << ISPRSZ_IN_START_HORZ_ST_SHIFT)
415 & ISPRSZ_IN_START_HORZ_ST_MASK;
416 rgval |= (top << ISPRSZ_IN_START_VERT_ST_SHIFT)
417 & ISPRSZ_IN_START_VERT_ST_MASK;
418
419 isp_reg_writel(isp, rgval, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_IN_START);
420}
421
422/*
423 * resizer_set_input_size - Setup the input size
424 * @res: Device context.
425 * @width: The range is 0 to 4095 pixels
426 * @height: The range is 0 to 4095 lines
427 */
428static void resizer_set_input_size(struct isp_res_device *res,
429 u32 width, u32 height)
430{
431 struct isp_device *isp = to_isp_device(res);
432 u32 rgval = 0;
433
434 dev_dbg(isp->dev, "Input size[w/h]: %dx%d\n", width, height);
435
436 rgval = (width << ISPRSZ_IN_SIZE_HORZ_SHIFT)
437 & ISPRSZ_IN_SIZE_HORZ_MASK;
438 rgval |= (height << ISPRSZ_IN_SIZE_VERT_SHIFT)
439 & ISPRSZ_IN_SIZE_VERT_MASK;
440
441 isp_reg_writel(isp, rgval, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_IN_SIZE);
442}
443
444/*
445 * resizer_set_src_offs - Setup the memory offset for the input lines
446 * @res: Device context.
447 * @offset: Memory offset.
448 *
449 * The 5 LSBs are forced to be zeros by the hardware to align on a 32-byte
450 * boundary; the 5 LSBs are read-only. This field must be programmed to be
451 * 0x0 if the resizer input is from preview engine/CCDC.
452 */
453static void resizer_set_input_offset(struct isp_res_device *res, u32 offset)
454{
455 struct isp_device *isp = to_isp_device(res);
456
457 isp_reg_writel(isp, offset, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_SDR_INOFF);
458}
459
460/*
461 * resizer_set_intype - Input type select
462 * @res: Device context.
463 * @type: Pixel format type.
464 */
465static void resizer_set_intype(struct isp_res_device *res,
466 enum resizer_colors_type type)
467{
468 struct isp_device *isp = to_isp_device(res);
469
470 if (type == RSZ_COLOR8)
471 isp_reg_set(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT,
472 ISPRSZ_CNT_INPTYP);
473 else
474 isp_reg_clr(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT,
475 ISPRSZ_CNT_INPTYP);
476}
477
478/*
479 * __resizer_set_inaddr - Helper function for set input address
480 * @res : pointer to resizer private data structure
481 * @addr: input address
482 * return none
483 */
484static void __resizer_set_inaddr(struct isp_res_device *res, u32 addr)
485{
486 struct isp_device *isp = to_isp_device(res);
487
488 isp_reg_writel(isp, addr, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_SDR_INADD);
489}
490
491/*
492 * The data rate at the horizontal resizer output must not exceed half the
493 * functional clock or 100 MP/s, whichever is lower. According to the TRM
494 * there's no similar requirement for the vertical resizer output. However
495 * experience showed that vertical upscaling by 4 leads to SBL overflows (with
496 * data rates at the resizer output exceeding 300 MP/s). Limiting the resizer
497 * output data rate to the functional clock or 200 MP/s, whichever is lower,
498 * seems to get rid of SBL overflows.
499 *
500 * The maximum data rate at the output of the horizontal resizer can thus be
501 * computed with
502 *
503 * max intermediate rate <= L3 clock * input height / output height
504 * max intermediate rate <= L3 clock / 2
505 *
506 * The maximum data rate at the resizer input is then
507 *
508 * max input rate <= max intermediate rate * input width / output width
509 *
510 * where the input width and height are the resizer input crop rectangle size.
511 * The TRM doesn't clearly explain if that's a maximum instant data rate or a
512 * maximum average data rate.
513 */
514void omap3isp_resizer_max_rate(struct isp_res_device *res,
515 unsigned int *max_rate)
516{
517 struct isp_pipeline *pipe = to_isp_pipeline(&res->subdev.entity);
518 const struct v4l2_mbus_framefmt *ofmt = &res->formats[RESZ_PAD_SOURCE];
519 unsigned long limit = min(pipe->l3_ick, 200000000UL);
520 unsigned long clock;
521
522 clock = div_u64((u64)limit * res->crop.active.height, ofmt->height);
523 clock = min(clock, limit / 2);
524 *max_rate = div_u64((u64)clock * res->crop.active.width, ofmt->width);
525}
526
527/*
528 * When the resizer processes images from memory, the driver must slow down read
529 * requests on the input to at least comply with the internal data rate
530 * requirements. If the application real-time requirements can cope with slower
531 * processing, the resizer can be slowed down even more to put less pressure on
532 * the overall system.
533 *
534 * When the resizer processes images on the fly (either from the CCDC or the
535 * preview module), the same data rate requirements apply but they can't be
536 * enforced at the resizer level. The image input module (sensor, CCP2 or
537 * preview module) must not provide image data faster than the resizer can
538 * process.
539 *
540 * For live image pipelines, the data rate is set by the frame format, size and
541 * rate. The sensor output frame rate must not exceed the maximum resizer data
542 * rate.
543 *
544 * The resizer slows down read requests by inserting wait cycles in the SBL
545 * requests. The maximum number of 256-byte requests per second can be computed
546 * as (the data rate is multiplied by 2 to convert from pixels per second to
547 * bytes per second)
548 *
549 * request per second = data rate * 2 / 256
550 * cycles per request = cycles per second / requests per second
551 *
552 * The number of cycles per second is controlled by the L3 clock, leading to
553 *
554 * cycles per request = L3 frequency / 2 * 256 / data rate
555 */
556static void resizer_adjust_bandwidth(struct isp_res_device *res)
557{
558 struct isp_pipeline *pipe = to_isp_pipeline(&res->subdev.entity);
559 struct isp_device *isp = to_isp_device(res);
560 unsigned long l3_ick = pipe->l3_ick;
561 struct v4l2_fract *timeperframe;
562 unsigned int cycles_per_frame;
563 unsigned int requests_per_frame;
564 unsigned int cycles_per_request;
565 unsigned int granularity;
566 unsigned int minimum;
567 unsigned int maximum;
568 unsigned int value;
569
570 if (res->input != RESIZER_INPUT_MEMORY) {
571 isp_reg_clr(isp, OMAP3_ISP_IOMEM_SBL, ISPSBL_SDR_REQ_EXP,
572 ISPSBL_SDR_REQ_RSZ_EXP_MASK);
573 return;
574 }
575
576 switch (isp->revision) {
577 case ISP_REVISION_1_0:
578 case ISP_REVISION_2_0:
579 default:
580 granularity = 1024;
581 break;
582
583 case ISP_REVISION_15_0:
584 granularity = 32;
585 break;
586 }
587
588 /* Compute the minimum number of cycles per request, based on the
589 * pipeline maximum data rate. This is an absolute lower bound if we
590 * don't want SBL overflows, so round the value up.
591 */
592 cycles_per_request = div_u64((u64)l3_ick / 2 * 256 + pipe->max_rate - 1,
593 pipe->max_rate);
594 minimum = DIV_ROUND_UP(cycles_per_request, granularity);
595
596 /* Compute the maximum number of cycles per request, based on the
597 * requested frame rate. This is a soft upper bound to achieve a frame
598 * rate equal or higher than the requested value, so round the value
599 * down.
600 */
601 timeperframe = &pipe->max_timeperframe;
602
603 requests_per_frame = DIV_ROUND_UP(res->crop.active.width * 2, 256)
604 * res->crop.active.height;
605 cycles_per_frame = div_u64((u64)l3_ick * timeperframe->numerator,
606 timeperframe->denominator);
607 cycles_per_request = cycles_per_frame / requests_per_frame;
608
609 maximum = cycles_per_request / granularity;
610
611 value = max(minimum, maximum);
612
613 dev_dbg(isp->dev, "%s: cycles per request = %u\n", __func__, value);
614 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_SBL, ISPSBL_SDR_REQ_EXP,
615 ISPSBL_SDR_REQ_RSZ_EXP_MASK,
616 value << ISPSBL_SDR_REQ_RSZ_EXP_SHIFT);
617}
618
619/*
620 * omap3isp_resizer_busy - Checks if ISP resizer is busy.
621 *
622 * Returns busy field from ISPRSZ_PCR register.
623 */
624int omap3isp_resizer_busy(struct isp_res_device *res)
625{
626 struct isp_device *isp = to_isp_device(res);
627
628 return isp_reg_readl(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_PCR) &
629 ISPRSZ_PCR_BUSY;
630}
631
632/*
633 * resizer_set_inaddr - Sets the memory address of the input frame.
634 * @addr: 32bit memory address aligned on 32byte boundary.
635 */
636static void resizer_set_inaddr(struct isp_res_device *res, u32 addr)
637{
638 res->addr_base = addr;
639
640 /* This will handle crop settings in stream off state */
641 if (res->crop_offset)
642 addr += res->crop_offset & ~0x1f;
643
644 __resizer_set_inaddr(res, addr);
645}
646
647/*
648 * Configures the memory address to which the output frame is written.
649 * @addr: 32bit memory address aligned on 32byte boundary.
650 * Note: For SBL efficiency reasons the address should be on a 256-byte
651 * boundary.
652 */
653static void resizer_set_outaddr(struct isp_res_device *res, u32 addr)
654{
655 struct isp_device *isp = to_isp_device(res);
656
657 /*
658 * Set output address. This needs to be in its own function
659 * because it changes often.
660 */
661 isp_reg_writel(isp, addr << ISPRSZ_SDR_OUTADD_ADDR_SHIFT,
662 OMAP3_ISP_IOMEM_RESZ, ISPRSZ_SDR_OUTADD);
663}
664
665/*
666 * resizer_print_status - Prints the values of the resizer module registers.
667 */
668#define RSZ_PRINT_REGISTER(isp, name)\
669 dev_dbg(isp->dev, "###RSZ " #name "=0x%08x\n", \
670 isp_reg_readl(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_##name))
671
672static void resizer_print_status(struct isp_res_device *res)
673{
674 struct isp_device *isp = to_isp_device(res);
675
676 dev_dbg(isp->dev, "-------------Resizer Register dump----------\n");
677
678 RSZ_PRINT_REGISTER(isp, PCR);
679 RSZ_PRINT_REGISTER(isp, CNT);
680 RSZ_PRINT_REGISTER(isp, OUT_SIZE);
681 RSZ_PRINT_REGISTER(isp, IN_START);
682 RSZ_PRINT_REGISTER(isp, IN_SIZE);
683 RSZ_PRINT_REGISTER(isp, SDR_INADD);
684 RSZ_PRINT_REGISTER(isp, SDR_INOFF);
685 RSZ_PRINT_REGISTER(isp, SDR_OUTADD);
686 RSZ_PRINT_REGISTER(isp, SDR_OUTOFF);
687 RSZ_PRINT_REGISTER(isp, YENH);
688
689 dev_dbg(isp->dev, "--------------------------------------------\n");
690}
691
692/*
693 * resizer_calc_ratios - Helper function for calculating resizer ratios
694 * @res: pointer to resizer private data structure
695 * @input: input frame size
696 * @output: output frame size
697 * @ratio : return calculated ratios
698 * return none
699 *
700 * The resizer uses a polyphase sample rate converter. The upsampling filter
701 * has a fixed number of phases that depend on the resizing ratio. As the ratio
702 * computation depends on the number of phases, we need to compute a first
703 * approximation and then refine it.
704 *
705 * The input/output/ratio relationship is given by the OMAP34xx TRM:
706 *
707 * - 8-phase, 4-tap mode (RSZ = 64 ~ 512)
708 * iw = (32 * sph + (ow - 1) * hrsz + 16) >> 8 + 7
709 * ih = (32 * spv + (oh - 1) * vrsz + 16) >> 8 + 4
710 * - 4-phase, 7-tap mode (RSZ = 513 ~ 1024)
711 * iw = (64 * sph + (ow - 1) * hrsz + 32) >> 8 + 7
712 * ih = (64 * spv + (oh - 1) * vrsz + 32) >> 8 + 7
713 *
714 * iw and ih are the input width and height after cropping. Those equations need
715 * to be satisfied exactly for the resizer to work correctly.
716 *
717 * The equations can't be easily reverted, as the >> 8 operation is not linear.
718 * In addition, not all input sizes can be achieved for a given output size. To
719 * get the highest input size lower than or equal to the requested input size,
720 * we need to compute the highest resizing ratio that satisfies the following
721 * inequality (taking the 4-tap mode width equation as an example)
722 *
723 * iw >= (32 * sph + (ow - 1) * hrsz + 16) >> 8 - 7
724 *
725 * (where iw is the requested input width) which can be rewritten as
726 *
727 * iw - 7 >= (32 * sph + (ow - 1) * hrsz + 16) >> 8
728 * (iw - 7) << 8 >= 32 * sph + (ow - 1) * hrsz + 16 - b
729 * ((iw - 7) << 8) + b >= 32 * sph + (ow - 1) * hrsz + 16
730 *
731 * where b is the value of the 8 least significant bits of the right hand side
732 * expression of the last inequality. The highest resizing ratio value will be
733 * achieved when b is equal to its maximum value of 255. That resizing ratio
734 * value will still satisfy the original inequality, as b will disappear when
735 * the expression will be shifted right by 8.
736 *
737 * The reverted equations thus become
738 *
739 * - 8-phase, 4-tap mode
740 * hrsz = ((iw - 7) * 256 + 255 - 16 - 32 * sph) / (ow - 1)
741 * vrsz = ((ih - 4) * 256 + 255 - 16 - 32 * spv) / (oh - 1)
742 * - 4-phase, 7-tap mode
743 * hrsz = ((iw - 7) * 256 + 255 - 32 - 64 * sph) / (ow - 1)
744 * vrsz = ((ih - 7) * 256 + 255 - 32 - 64 * spv) / (oh - 1)
745 *
746 * The ratios are integer values, and are rounded down to ensure that the
747 * cropped input size is not bigger than the uncropped input size.
748 *
749 * As the number of phases/taps, used to select the correct equations to compute
750 * the ratio, depends on the ratio, we start with the 4-tap mode equations to
751 * compute an approximation of the ratio, and switch to the 7-tap mode equations
752 * if the approximation is higher than the ratio threshold.
753 *
754 * As the 7-tap mode equations will return a ratio smaller than or equal to the
755 * 4-tap mode equations, the resulting ratio could become lower than or equal to
756 * the ratio threshold. This 'equations loop' isn't an issue as long as the
757 * correct equations are used to compute the final input size. Starting with the
758 * 4-tap mode equations ensure that, in case of values resulting in a 'ratio
759 * loop', the smallest of the ratio values will be used, never exceeding the
760 * requested input size.
761 *
762 * We first clamp the output size according to the hardware capability to avoid
763 * auto-cropping the input more than required to satisfy the TRM equations. The
764 * minimum output size is achieved with a scaling factor of 1024. It is thus
765 * computed using the 7-tap equations.
766 *
767 * min ow = ((iw - 7) * 256 - 32 - 64 * sph) / 1024 + 1
768 * min oh = ((ih - 7) * 256 - 32 - 64 * spv) / 1024 + 1
769 *
770 * Similarly, the maximum output size is achieved with a scaling factor of 64
771 * and computed using the 4-tap equations.
772 *
773 * max ow = ((iw - 7) * 256 + 255 - 16 - 32 * sph) / 64 + 1
774 * max oh = ((ih - 4) * 256 + 255 - 16 - 32 * spv) / 64 + 1
775 *
776 * The additional +255 term compensates for the round down operation performed
777 * by the TRM equations when shifting the value right by 8 bits.
778 *
779 * We then compute and clamp the ratios (x1/4 ~ x4). Clamping the output size to
780 * the maximum value guarantees that the ratio value will never be smaller than
781 * the minimum, but it could still slightly exceed the maximum. Clamping the
782 * ratio will thus result in a resizing factor slightly larger than the
783 * requested value.
784 *
785 * To accommodate that, and make sure the TRM equations are satisfied exactly, we
786 * compute the input crop rectangle as the last step.
787 *
788 * As if the situation wasn't complex enough, the maximum output width depends
789 * on the vertical resizing ratio. Fortunately, the output height doesn't
790 * depend on the horizontal resizing ratio. We can then start by computing the
791 * output height and the vertical ratio, and then move to computing the output
792 * width and the horizontal ratio.
793 */
794static void resizer_calc_ratios(struct isp_res_device *res,
795 struct v4l2_rect *input,
796 struct v4l2_mbus_framefmt *output,
797 struct resizer_ratio *ratio)
798{
799 struct isp_device *isp = to_isp_device(res);
800 const unsigned int spv = DEFAULT_PHASE;
801 const unsigned int sph = DEFAULT_PHASE;
802 unsigned int upscaled_width;
803 unsigned int upscaled_height;
804 unsigned int min_width;
805 unsigned int min_height;
806 unsigned int max_width;
807 unsigned int max_height;
808 unsigned int width_alignment;
809 unsigned int width;
810 unsigned int height;
811
812 /*
813 * Clamp the output height based on the hardware capabilities and
814 * compute the vertical resizing ratio.
815 */
816 min_height = ((input->height - 7) * 256 - 32 - 64 * spv) / 1024 + 1;
817 min_height = max_t(unsigned int, min_height, MIN_OUT_HEIGHT);
818 max_height = ((input->height - 4) * 256 + 255 - 16 - 32 * spv) / 64 + 1;
819 max_height = min_t(unsigned int, max_height, MAX_OUT_HEIGHT);
820 output->height = clamp(output->height, min_height, max_height);
821
822 ratio->vert = ((input->height - 4) * 256 + 255 - 16 - 32 * spv)
823 / (output->height - 1);
824 if (ratio->vert > MID_RESIZE_VALUE)
825 ratio->vert = ((input->height - 7) * 256 + 255 - 32 - 64 * spv)
826 / (output->height - 1);
827 ratio->vert = clamp_t(unsigned int, ratio->vert,
828 MIN_RESIZE_VALUE, MAX_RESIZE_VALUE);
829
830 if (ratio->vert <= MID_RESIZE_VALUE) {
831 upscaled_height = (output->height - 1) * ratio->vert
832 + 32 * spv + 16;
833 height = (upscaled_height >> 8) + 4;
834 } else {
835 upscaled_height = (output->height - 1) * ratio->vert
836 + 64 * spv + 32;
837 height = (upscaled_height >> 8) + 7;
838 }
839
840 /*
841 * Compute the minimum and maximum output widths based on the hardware
842 * capabilities. The maximum depends on the vertical resizing ratio.
843 */
844 min_width = ((input->width - 7) * 256 - 32 - 64 * sph) / 1024 + 1;
845 min_width = max_t(unsigned int, min_width, MIN_OUT_WIDTH);
846
847 if (ratio->vert <= MID_RESIZE_VALUE) {
848 switch (isp->revision) {
849 case ISP_REVISION_1_0:
850 max_width = MAX_4TAP_OUT_WIDTH_ES1;
851 break;
852
853 case ISP_REVISION_2_0:
854 default:
855 max_width = MAX_4TAP_OUT_WIDTH_ES2;
856 break;
857
858 case ISP_REVISION_15_0:
859 max_width = MAX_4TAP_OUT_WIDTH_3630;
860 break;
861 }
862 } else {
863 switch (isp->revision) {
864 case ISP_REVISION_1_0:
865 max_width = MAX_7TAP_OUT_WIDTH_ES1;
866 break;
867
868 case ISP_REVISION_2_0:
869 default:
870 max_width = MAX_7TAP_OUT_WIDTH_ES2;
871 break;
872
873 case ISP_REVISION_15_0:
874 max_width = MAX_7TAP_OUT_WIDTH_3630;
875 break;
876 }
877 }
878 max_width = min(((input->width - 7) * 256 + 255 - 16 - 32 * sph) / 64
879 + 1, max_width);
880
881 /*
882 * The output width must be even, and must be a multiple of 16 bytes
883 * when upscaling vertically. Clamp the output width to the valid range.
884 * Take the alignment into account (the maximum width in 7-tap mode on
885 * ES2 isn't a multiple of 8) and align the result up to make sure it
886 * won't be smaller than the minimum.
887 */
888 width_alignment = ratio->vert < 256 ? 8 : 2;
889 output->width = clamp(output->width, min_width,
890 max_width & ~(width_alignment - 1));
891 output->width = ALIGN(output->width, width_alignment);
892
893 ratio->horz = ((input->width - 7) * 256 + 255 - 16 - 32 * sph)
894 / (output->width - 1);
895 if (ratio->horz > MID_RESIZE_VALUE)
896 ratio->horz = ((input->width - 7) * 256 + 255 - 32 - 64 * sph)
897 / (output->width - 1);
898 ratio->horz = clamp_t(unsigned int, ratio->horz,
899 MIN_RESIZE_VALUE, MAX_RESIZE_VALUE);
900
901 if (ratio->horz <= MID_RESIZE_VALUE) {
902 upscaled_width = (output->width - 1) * ratio->horz
903 + 32 * sph + 16;
904 width = (upscaled_width >> 8) + 7;
905 } else {
906 upscaled_width = (output->width - 1) * ratio->horz
907 + 64 * sph + 32;
908 width = (upscaled_width >> 8) + 7;
909 }
910
911 /* Center the new crop rectangle. */
912 input->left += (input->width - width) / 2;
913 input->top += (input->height - height) / 2;
914 input->width = width;
915 input->height = height;
916}
917
918/*
919 * resizer_set_crop_params - Setup hardware with cropping parameters
920 * @res : resizer private structure
921 * @crop_rect : current crop rectangle
922 * @ratio : resizer ratios
923 * return none
924 */
925static void resizer_set_crop_params(struct isp_res_device *res,
926 const struct v4l2_mbus_framefmt *input,
927 const struct v4l2_mbus_framefmt *output)
928{
929 resizer_set_ratio(res, &res->ratio);
930
931 /* Set chrominance horizontal algorithm */
932 if (res->ratio.horz >= RESIZE_DIVISOR)
933 resizer_set_bilinear(res, RSZ_THE_SAME);
934 else
935 resizer_set_bilinear(res, RSZ_BILINEAR);
936
937 resizer_adjust_bandwidth(res);
938
939 if (res->input == RESIZER_INPUT_MEMORY) {
940 /* Calculate additional offset for crop */
941 res->crop_offset = (res->crop.active.top * input->width +
942 res->crop.active.left) * 2;
943 /*
944 * Write lowest 4 bits of horizontal pixel offset (in pixels),
945 * vertical start must be 0.
946 */
947 resizer_set_start(res, (res->crop_offset / 2) & 0xf, 0);
948
949 /*
950 * Set start (read) address for cropping, in bytes.
951 * Lowest 5 bits must be zero.
952 */
953 __resizer_set_inaddr(res,
954 res->addr_base + (res->crop_offset & ~0x1f));
955 } else {
956 /*
957 * Set vertical start line and horizontal starting pixel.
958 * If the input is from CCDC/PREV, horizontal start field is
959 * in bytes (twice number of pixels).
960 */
961 resizer_set_start(res, res->crop.active.left * 2,
962 res->crop.active.top);
963 /* Input address and offset must be 0 for preview/ccdc input */
964 __resizer_set_inaddr(res, 0);
965 resizer_set_input_offset(res, 0);
966 }
967
968 /* Set the input size */
969 resizer_set_input_size(res, res->crop.active.width,
970 res->crop.active.height);
971}
972
973static void resizer_configure(struct isp_res_device *res)
974{
975 struct v4l2_mbus_framefmt *informat, *outformat;
976 struct resizer_luma_yenh luma = {0, 0, 0, 0};
977
978 resizer_set_source(res, res->input);
979
980 informat = &res->formats[RESZ_PAD_SINK];
981 outformat = &res->formats[RESZ_PAD_SOURCE];
982
983 /* RESZ_PAD_SINK */
984 if (res->input == RESIZER_INPUT_VP)
985 resizer_set_input_offset(res, 0);
986 else
987 resizer_set_input_offset(res, ALIGN(informat->width, 0x10) * 2);
988
989 /* YUV422 interleaved, default phase, no luma enhancement */
990 resizer_set_intype(res, RSZ_YUV422);
991 resizer_set_ycpos(res, informat->code);
992 resizer_set_phase(res, DEFAULT_PHASE, DEFAULT_PHASE);
993 resizer_set_luma(res, &luma);
994
995 /* RESZ_PAD_SOURCE */
996 resizer_set_output_offset(res, ALIGN(outformat->width * 2, 32));
997 resizer_set_output_size(res, outformat->width, outformat->height);
998
999 resizer_set_crop_params(res, informat, outformat);
1000}
1001
1002/* -----------------------------------------------------------------------------
1003 * Interrupt handling
1004 */
1005
1006static void resizer_enable_oneshot(struct isp_res_device *res)
1007{
1008 struct isp_device *isp = to_isp_device(res);
1009
1010 isp_reg_set(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_PCR,
1011 ISPRSZ_PCR_ENABLE | ISPRSZ_PCR_ONESHOT);
1012}
1013
1014void omap3isp_resizer_isr_frame_sync(struct isp_res_device *res)
1015{
1016 /*
1017 * If ISP_VIDEO_DMAQUEUE_QUEUED is set, DMA queue had an underrun
1018 * condition, the module was paused and now we have a buffer queued
1019 * on the output again. Restart the pipeline if running in continuous
1020 * mode.
1021 */
1022 if (res->state == ISP_PIPELINE_STREAM_CONTINUOUS &&
1023 res->video_out.dmaqueue_flags & ISP_VIDEO_DMAQUEUE_QUEUED) {
1024 resizer_enable_oneshot(res);
1025 isp_video_dmaqueue_flags_clr(&res->video_out);
1026 }
1027}
1028
1029static void resizer_isr_buffer(struct isp_res_device *res)
1030{
1031 struct isp_pipeline *pipe = to_isp_pipeline(&res->subdev.entity);
1032 struct isp_buffer *buffer;
1033 int restart = 0;
1034
1035 if (res->state == ISP_PIPELINE_STREAM_STOPPED)
1036 return;
1037
1038 /* Complete the output buffer and, if reading from memory, the input
1039 * buffer.
1040 */
1041 buffer = omap3isp_video_buffer_next(&res->video_out);
1042 if (buffer != NULL) {
1043 resizer_set_outaddr(res, buffer->isp_addr);
1044 restart = 1;
1045 }
1046
1047 pipe->state |= ISP_PIPELINE_IDLE_OUTPUT;
1048
1049 if (res->input == RESIZER_INPUT_MEMORY) {
1050 buffer = omap3isp_video_buffer_next(&res->video_in);
1051 if (buffer != NULL)
1052 resizer_set_inaddr(res, buffer->isp_addr);
1053 pipe->state |= ISP_PIPELINE_IDLE_INPUT;
1054 }
1055
1056 if (res->state == ISP_PIPELINE_STREAM_SINGLESHOT) {
1057 if (isp_pipeline_ready(pipe))
1058 omap3isp_pipeline_set_stream(pipe,
1059 ISP_PIPELINE_STREAM_SINGLESHOT);
1060 } else {
1061 /* If an underrun occurs, the video queue operation handler will
1062 * restart the resizer. Otherwise restart it immediately.
1063 */
1064 if (restart)
1065 resizer_enable_oneshot(res);
1066 }
1067}
1068
1069/*
1070 * omap3isp_resizer_isr - ISP resizer interrupt handler
1071 *
1072 * Manage the resizer video buffers and configure shadowed and busy-locked
1073 * registers.
1074 */
1075void omap3isp_resizer_isr(struct isp_res_device *res)
1076{
1077 struct v4l2_mbus_framefmt *informat, *outformat;
1078
1079 if (omap3isp_module_sync_is_stopping(&res->wait, &res->stopping))
1080 return;
1081
1082 if (res->applycrop) {
1083 outformat = __resizer_get_format(res, NULL, RESZ_PAD_SOURCE,
1084 V4L2_SUBDEV_FORMAT_ACTIVE);
1085 informat = __resizer_get_format(res, NULL, RESZ_PAD_SINK,
1086 V4L2_SUBDEV_FORMAT_ACTIVE);
1087 resizer_set_crop_params(res, informat, outformat);
1088 res->applycrop = 0;
1089 }
1090
1091 resizer_isr_buffer(res);
1092}
1093
1094/* -----------------------------------------------------------------------------
1095 * ISP video operations
1096 */
1097
1098static int resizer_video_queue(struct isp_video *video,
1099 struct isp_buffer *buffer)
1100{
1101 struct isp_res_device *res = &video->isp->isp_res;
1102
1103 if (video->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
1104 resizer_set_inaddr(res, buffer->isp_addr);
1105
1106 /*
1107 * We now have a buffer queued on the output. Despite what the
1108 * TRM says, the resizer can't be restarted immediately.
1109 * Enabling it in one shot mode in the middle of a frame (or at
1110 * least asynchronously to the frame) results in the output
1111 * being shifted randomly left/right and up/down, as if the
1112 * hardware didn't synchronize itself to the beginning of the
1113 * frame correctly.
1114 *
1115 * Restart the resizer on the next sync interrupt if running in
1116 * continuous mode or when starting the stream.
1117 */
1118 if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1119 resizer_set_outaddr(res, buffer->isp_addr);
1120
1121 return 0;
1122}
1123
1124static const struct isp_video_operations resizer_video_ops = {
1125 .queue = resizer_video_queue,
1126};
1127
1128/* -----------------------------------------------------------------------------
1129 * V4L2 subdev operations
1130 */
1131
1132/*
1133 * resizer_set_stream - Enable/Disable streaming on resizer subdev
1134 * @sd: ISP resizer V4L2 subdev
1135 * @enable: 1 == Enable, 0 == Disable
1136 *
1137 * The resizer hardware can't be enabled without a memory buffer to write to.
1138 * As the s_stream operation is called in response to a STREAMON call without
1139 * any buffer queued yet, just update the state field and return immediately.
1140 * The resizer will be enabled in resizer_video_queue().
1141 */
1142static int resizer_set_stream(struct v4l2_subdev *sd, int enable)
1143{
1144 struct isp_res_device *res = v4l2_get_subdevdata(sd);
1145 struct isp_video *video_out = &res->video_out;
1146 struct isp_device *isp = to_isp_device(res);
1147 struct device *dev = to_device(res);
1148
1149 if (res->state == ISP_PIPELINE_STREAM_STOPPED) {
1150 if (enable == ISP_PIPELINE_STREAM_STOPPED)
1151 return 0;
1152
1153 omap3isp_subclk_enable(isp, OMAP3_ISP_SUBCLK_RESIZER);
1154 resizer_configure(res);
1155 resizer_print_status(res);
1156 }
1157
1158 switch (enable) {
1159 case ISP_PIPELINE_STREAM_CONTINUOUS:
1160 omap3isp_sbl_enable(isp, OMAP3_ISP_SBL_RESIZER_WRITE);
1161 if (video_out->dmaqueue_flags & ISP_VIDEO_DMAQUEUE_QUEUED) {
1162 resizer_enable_oneshot(res);
1163 isp_video_dmaqueue_flags_clr(video_out);
1164 }
1165 break;
1166
1167 case ISP_PIPELINE_STREAM_SINGLESHOT:
1168 if (res->input == RESIZER_INPUT_MEMORY)
1169 omap3isp_sbl_enable(isp, OMAP3_ISP_SBL_RESIZER_READ);
1170 omap3isp_sbl_enable(isp, OMAP3_ISP_SBL_RESIZER_WRITE);
1171
1172 resizer_enable_oneshot(res);
1173 break;
1174
1175 case ISP_PIPELINE_STREAM_STOPPED:
1176 if (omap3isp_module_sync_idle(&sd->entity, &res->wait,
1177 &res->stopping))
1178 dev_dbg(dev, "%s: module stop timeout.\n", sd->name);
1179 omap3isp_sbl_disable(isp, OMAP3_ISP_SBL_RESIZER_READ |
1180 OMAP3_ISP_SBL_RESIZER_WRITE);
1181 omap3isp_subclk_disable(isp, OMAP3_ISP_SUBCLK_RESIZER);
1182 isp_video_dmaqueue_flags_clr(video_out);
1183 break;
1184 }
1185
1186 res->state = enable;
1187 return 0;
1188}
1189
1190/*
1191 * resizer_try_crop - mangles crop parameters.
1192 */
1193static void resizer_try_crop(const struct v4l2_mbus_framefmt *sink,
1194 const struct v4l2_mbus_framefmt *source,
1195 struct v4l2_rect *crop)
1196{
1197 const unsigned int spv = DEFAULT_PHASE;
1198 const unsigned int sph = DEFAULT_PHASE;
1199
1200 /* Crop rectangle is constrained by the output size so that zoom ratio
1201 * cannot exceed +/-4.0.
1202 */
1203 unsigned int min_width =
1204 ((32 * sph + (source->width - 1) * 64 + 16) >> 8) + 7;
1205 unsigned int min_height =
1206 ((32 * spv + (source->height - 1) * 64 + 16) >> 8) + 4;
1207 unsigned int max_width =
1208 ((64 * sph + (source->width - 1) * 1024 + 32) >> 8) + 7;
1209 unsigned int max_height =
1210 ((64 * spv + (source->height - 1) * 1024 + 32) >> 8) + 7;
1211
1212 crop->width = clamp_t(u32, crop->width, min_width, max_width);
1213 crop->height = clamp_t(u32, crop->height, min_height, max_height);
1214
1215 /* Crop can not go beyond of the input rectangle */
1216 crop->left = clamp_t(u32, crop->left, 0, sink->width - MIN_IN_WIDTH);
1217 crop->width = clamp_t(u32, crop->width, MIN_IN_WIDTH,
1218 sink->width - crop->left);
1219 crop->top = clamp_t(u32, crop->top, 0, sink->height - MIN_IN_HEIGHT);
1220 crop->height = clamp_t(u32, crop->height, MIN_IN_HEIGHT,
1221 sink->height - crop->top);
1222}
1223
1224/*
1225 * resizer_get_selection - Retrieve a selection rectangle on a pad
1226 * @sd: ISP resizer V4L2 subdevice
1227 * @fh: V4L2 subdev file handle
1228 * @sel: Selection rectangle
1229 *
1230 * The only supported rectangles are the crop rectangles on the sink pad.
1231 *
1232 * Return 0 on success or a negative error code otherwise.
1233 */
1234static int resizer_get_selection(struct v4l2_subdev *sd,
1235 struct v4l2_subdev_fh *fh,
1236 struct v4l2_subdev_selection *sel)
1237{
1238 struct isp_res_device *res = v4l2_get_subdevdata(sd);
1239 struct v4l2_mbus_framefmt *format_source;
1240 struct v4l2_mbus_framefmt *format_sink;
1241 struct resizer_ratio ratio;
1242
1243 if (sel->pad != RESZ_PAD_SINK)
1244 return -EINVAL;
1245
1246 format_sink = __resizer_get_format(res, fh, RESZ_PAD_SINK,
1247 sel->which);
1248 format_source = __resizer_get_format(res, fh, RESZ_PAD_SOURCE,
1249 sel->which);
1250
1251 switch (sel->target) {
1252 case V4L2_SEL_TGT_CROP_BOUNDS:
1253 sel->r.left = 0;
1254 sel->r.top = 0;
1255 sel->r.width = INT_MAX;
1256 sel->r.height = INT_MAX;
1257
1258 resizer_try_crop(format_sink, format_source, &sel->r);
1259 resizer_calc_ratios(res, &sel->r, format_source, &ratio);
1260 break;
1261
1262 case V4L2_SEL_TGT_CROP:
1263 sel->r = *__resizer_get_crop(res, fh, sel->which);
1264 resizer_calc_ratios(res, &sel->r, format_source, &ratio);
1265 break;
1266
1267 default:
1268 return -EINVAL;
1269 }
1270
1271 return 0;
1272}
1273
1274/*
1275 * resizer_set_selection - Set a selection rectangle on a pad
1276 * @sd: ISP resizer V4L2 subdevice
1277 * @fh: V4L2 subdev file handle
1278 * @sel: Selection rectangle
1279 *
1280 * The only supported rectangle is the actual crop rectangle on the sink pad.
1281 *
1282 * FIXME: This function currently behaves as if the KEEP_CONFIG selection flag
1283 * was always set.
1284 *
1285 * Return 0 on success or a negative error code otherwise.
1286 */
1287static int resizer_set_selection(struct v4l2_subdev *sd,
1288 struct v4l2_subdev_fh *fh,
1289 struct v4l2_subdev_selection *sel)
1290{
1291 struct isp_res_device *res = v4l2_get_subdevdata(sd);
1292 struct isp_device *isp = to_isp_device(res);
1293 struct v4l2_mbus_framefmt *format_sink, *format_source;
1294 struct resizer_ratio ratio;
1295
1296 if (sel->target != V4L2_SEL_TGT_CROP ||
1297 sel->pad != RESZ_PAD_SINK)
1298 return -EINVAL;
1299
1300 format_sink = __resizer_get_format(res, fh, RESZ_PAD_SINK,
1301 sel->which);
1302 format_source = __resizer_get_format(res, fh, RESZ_PAD_SOURCE,
1303 sel->which);
1304
1305 dev_dbg(isp->dev, "%s: L=%d,T=%d,W=%d,H=%d,which=%d\n", __func__,
1306 sel->r.left, sel->r.top, sel->r.width, sel->r.height,
1307 sel->which);
1308
1309 dev_dbg(isp->dev, "%s: input=%dx%d, output=%dx%d\n", __func__,
1310 format_sink->width, format_sink->height,
1311 format_source->width, format_source->height);
1312
1313 /* Clamp the crop rectangle to the bounds, and then mangle it further to
1314 * fulfill the TRM equations. Store the clamped but otherwise unmangled
1315 * rectangle to avoid cropping the input multiple times: when an
1316 * application sets the output format, the current crop rectangle is
1317 * mangled during crop rectangle computation, which would lead to a new,
1318 * smaller input crop rectangle every time the output size is set if we
1319 * stored the mangled rectangle.
1320 */
1321 resizer_try_crop(format_sink, format_source, &sel->r);
1322 *__resizer_get_crop(res, fh, sel->which) = sel->r;
1323 resizer_calc_ratios(res, &sel->r, format_source, &ratio);
1324
1325 if (sel->which == V4L2_SUBDEV_FORMAT_TRY)
1326 return 0;
1327
1328 res->ratio = ratio;
1329 res->crop.active = sel->r;
1330
1331 /*
1332 * set_selection can be called while streaming is on. In this case the
1333 * crop values will be set in the next IRQ.
1334 */
1335 if (res->state != ISP_PIPELINE_STREAM_STOPPED)
1336 res->applycrop = 1;
1337
1338 return 0;
1339}
1340
1341/* resizer pixel formats */
1342static const unsigned int resizer_formats[] = {
1343 V4L2_MBUS_FMT_UYVY8_1X16,
1344 V4L2_MBUS_FMT_YUYV8_1X16,
1345};
1346
1347static unsigned int resizer_max_in_width(struct isp_res_device *res)
1348{
1349 struct isp_device *isp = to_isp_device(res);
1350
1351 if (res->input == RESIZER_INPUT_MEMORY) {
1352 return MAX_IN_WIDTH_MEMORY_MODE;
1353 } else {
1354 if (isp->revision == ISP_REVISION_1_0)
1355 return MAX_IN_WIDTH_ONTHEFLY_MODE_ES1;
1356 else
1357 return MAX_IN_WIDTH_ONTHEFLY_MODE_ES2;
1358 }
1359}
1360
1361/*
1362 * resizer_try_format - Handle try format by pad subdev method
1363 * @res : ISP resizer device
1364 * @fh : V4L2 subdev file handle
1365 * @pad : pad num
1366 * @fmt : pointer to v4l2 format structure
1367 * @which : wanted subdev format
1368 */
1369static void resizer_try_format(struct isp_res_device *res,
1370 struct v4l2_subdev_fh *fh, unsigned int pad,
1371 struct v4l2_mbus_framefmt *fmt,
1372 enum v4l2_subdev_format_whence which)
1373{
1374 struct v4l2_mbus_framefmt *format;
1375 struct resizer_ratio ratio;
1376 struct v4l2_rect crop;
1377
1378 switch (pad) {
1379 case RESZ_PAD_SINK:
1380 if (fmt->code != V4L2_MBUS_FMT_YUYV8_1X16 &&
1381 fmt->code != V4L2_MBUS_FMT_UYVY8_1X16)
1382 fmt->code = V4L2_MBUS_FMT_YUYV8_1X16;
1383
1384 fmt->width = clamp_t(u32, fmt->width, MIN_IN_WIDTH,
1385 resizer_max_in_width(res));
1386 fmt->height = clamp_t(u32, fmt->height, MIN_IN_HEIGHT,
1387 MAX_IN_HEIGHT);
1388 break;
1389
1390 case RESZ_PAD_SOURCE:
1391 format = __resizer_get_format(res, fh, RESZ_PAD_SINK, which);
1392 fmt->code = format->code;
1393
1394 crop = *__resizer_get_crop(res, fh, which);
1395 resizer_calc_ratios(res, &crop, fmt, &ratio);
1396 break;
1397 }
1398
1399 fmt->colorspace = V4L2_COLORSPACE_JPEG;
1400 fmt->field = V4L2_FIELD_NONE;
1401}
1402
1403/*
1404 * resizer_enum_mbus_code - Handle pixel format enumeration
1405 * @sd : pointer to v4l2 subdev structure
1406 * @fh : V4L2 subdev file handle
1407 * @code : pointer to v4l2_subdev_mbus_code_enum structure
1408 * return -EINVAL or zero on success
1409 */
1410static int resizer_enum_mbus_code(struct v4l2_subdev *sd,
1411 struct v4l2_subdev_fh *fh,
1412 struct v4l2_subdev_mbus_code_enum *code)
1413{
1414 struct isp_res_device *res = v4l2_get_subdevdata(sd);
1415 struct v4l2_mbus_framefmt *format;
1416
1417 if (code->pad == RESZ_PAD_SINK) {
1418 if (code->index >= ARRAY_SIZE(resizer_formats))
1419 return -EINVAL;
1420
1421 code->code = resizer_formats[code->index];
1422 } else {
1423 if (code->index != 0)
1424 return -EINVAL;
1425
1426 format = __resizer_get_format(res, fh, RESZ_PAD_SINK,
1427 V4L2_SUBDEV_FORMAT_TRY);
1428 code->code = format->code;
1429 }
1430
1431 return 0;
1432}
1433
1434static int resizer_enum_frame_size(struct v4l2_subdev *sd,
1435 struct v4l2_subdev_fh *fh,
1436 struct v4l2_subdev_frame_size_enum *fse)
1437{
1438 struct isp_res_device *res = v4l2_get_subdevdata(sd);
1439 struct v4l2_mbus_framefmt format;
1440
1441 if (fse->index != 0)
1442 return -EINVAL;
1443
1444 format.code = fse->code;
1445 format.width = 1;
1446 format.height = 1;
1447 resizer_try_format(res, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY);
1448 fse->min_width = format.width;
1449 fse->min_height = format.height;
1450
1451 if (format.code != fse->code)
1452 return -EINVAL;
1453
1454 format.code = fse->code;
1455 format.width = -1;
1456 format.height = -1;
1457 resizer_try_format(res, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY);
1458 fse->max_width = format.width;
1459 fse->max_height = format.height;
1460
1461 return 0;
1462}
1463
1464/*
1465 * resizer_get_format - Handle get format by pads subdev method
1466 * @sd : pointer to v4l2 subdev structure
1467 * @fh : V4L2 subdev file handle
1468 * @fmt : pointer to v4l2 subdev format structure
1469 * return -EINVAL or zero on success
1470 */
1471static int resizer_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
1472 struct v4l2_subdev_format *fmt)
1473{
1474 struct isp_res_device *res = v4l2_get_subdevdata(sd);
1475 struct v4l2_mbus_framefmt *format;
1476
1477 format = __resizer_get_format(res, fh, fmt->pad, fmt->which);
1478 if (format == NULL)
1479 return -EINVAL;
1480
1481 fmt->format = *format;
1482 return 0;
1483}
1484
1485/*
1486 * resizer_set_format - Handle set format by pads subdev method
1487 * @sd : pointer to v4l2 subdev structure
1488 * @fh : V4L2 subdev file handle
1489 * @fmt : pointer to v4l2 subdev format structure
1490 * return -EINVAL or zero on success
1491 */
1492static int resizer_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
1493 struct v4l2_subdev_format *fmt)
1494{
1495 struct isp_res_device *res = v4l2_get_subdevdata(sd);
1496 struct v4l2_mbus_framefmt *format;
1497 struct v4l2_rect *crop;
1498
1499 format = __resizer_get_format(res, fh, fmt->pad, fmt->which);
1500 if (format == NULL)
1501 return -EINVAL;
1502
1503 resizer_try_format(res, fh, fmt->pad, &fmt->format, fmt->which);
1504 *format = fmt->format;
1505
1506 if (fmt->pad == RESZ_PAD_SINK) {
1507 /* reset crop rectangle */
1508 crop = __resizer_get_crop(res, fh, fmt->which);
1509 crop->left = 0;
1510 crop->top = 0;
1511 crop->width = fmt->format.width;
1512 crop->height = fmt->format.height;
1513
1514 /* Propagate the format from sink to source */
1515 format = __resizer_get_format(res, fh, RESZ_PAD_SOURCE,
1516 fmt->which);
1517 *format = fmt->format;
1518 resizer_try_format(res, fh, RESZ_PAD_SOURCE, format,
1519 fmt->which);
1520 }
1521
1522 if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
1523 /* Compute and store the active crop rectangle and resizer
1524 * ratios. format already points to the source pad active
1525 * format.
1526 */
1527 res->crop.active = res->crop.request;
1528 resizer_calc_ratios(res, &res->crop.active, format,
1529 &res->ratio);
1530 }
1531
1532 return 0;
1533}
1534
1535/*
1536 * resizer_init_formats - Initialize formats on all pads
1537 * @sd: ISP resizer V4L2 subdevice
1538 * @fh: V4L2 subdev file handle
1539 *
1540 * Initialize all pad formats with default values. If fh is not NULL, try
1541 * formats are initialized on the file handle. Otherwise active formats are
1542 * initialized on the device.
1543 */
1544static int resizer_init_formats(struct v4l2_subdev *sd,
1545 struct v4l2_subdev_fh *fh)
1546{
1547 struct v4l2_subdev_format format;
1548
1549 memset(&format, 0, sizeof(format));
1550 format.pad = RESZ_PAD_SINK;
1551 format.which = fh ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE;
1552 format.format.code = V4L2_MBUS_FMT_YUYV8_1X16;
1553 format.format.width = 4096;
1554 format.format.height = 4096;
1555 resizer_set_format(sd, fh, &format);
1556
1557 return 0;
1558}
1559
1560/* subdev video operations */
1561static const struct v4l2_subdev_video_ops resizer_v4l2_video_ops = {
1562 .s_stream = resizer_set_stream,
1563};
1564
1565/* subdev pad operations */
1566static const struct v4l2_subdev_pad_ops resizer_v4l2_pad_ops = {
1567 .enum_mbus_code = resizer_enum_mbus_code,
1568 .enum_frame_size = resizer_enum_frame_size,
1569 .get_fmt = resizer_get_format,
1570 .set_fmt = resizer_set_format,
1571 .get_selection = resizer_get_selection,
1572 .set_selection = resizer_set_selection,
1573};
1574
1575/* subdev operations */
1576static const struct v4l2_subdev_ops resizer_v4l2_ops = {
1577 .video = &resizer_v4l2_video_ops,
1578 .pad = &resizer_v4l2_pad_ops,
1579};
1580
1581/* subdev internal operations */
1582static const struct v4l2_subdev_internal_ops resizer_v4l2_internal_ops = {
1583 .open = resizer_init_formats,
1584};
1585
1586/* -----------------------------------------------------------------------------
1587 * Media entity operations
1588 */
1589
1590/*
1591 * resizer_link_setup - Setup resizer connections.
1592 * @entity : Pointer to media entity structure
1593 * @local : Pointer to local pad array
1594 * @remote : Pointer to remote pad array
1595 * @flags : Link flags
1596 * return -EINVAL or zero on success
1597 */
1598static int resizer_link_setup(struct media_entity *entity,
1599 const struct media_pad *local,
1600 const struct media_pad *remote, u32 flags)
1601{
1602 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
1603 struct isp_res_device *res = v4l2_get_subdevdata(sd);
1604
1605 switch (local->index | media_entity_type(remote->entity)) {
1606 case RESZ_PAD_SINK | MEDIA_ENT_T_DEVNODE:
1607 /* read from memory */
1608 if (flags & MEDIA_LNK_FL_ENABLED) {
1609 if (res->input == RESIZER_INPUT_VP)
1610 return -EBUSY;
1611 res->input = RESIZER_INPUT_MEMORY;
1612 } else {
1613 if (res->input == RESIZER_INPUT_MEMORY)
1614 res->input = RESIZER_INPUT_NONE;
1615 }
1616 break;
1617
1618 case RESZ_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV:
1619 /* read from ccdc or previewer */
1620 if (flags & MEDIA_LNK_FL_ENABLED) {
1621 if (res->input == RESIZER_INPUT_MEMORY)
1622 return -EBUSY;
1623 res->input = RESIZER_INPUT_VP;
1624 } else {
1625 if (res->input == RESIZER_INPUT_VP)
1626 res->input = RESIZER_INPUT_NONE;
1627 }
1628 break;
1629
1630 case RESZ_PAD_SOURCE | MEDIA_ENT_T_DEVNODE:
1631 /* resizer always write to memory */
1632 break;
1633
1634 default:
1635 return -EINVAL;
1636 }
1637
1638 return 0;
1639}
1640
1641/* media operations */
1642static const struct media_entity_operations resizer_media_ops = {
1643 .link_setup = resizer_link_setup,
1644 .link_validate = v4l2_subdev_link_validate,
1645};
1646
1647void omap3isp_resizer_unregister_entities(struct isp_res_device *res)
1648{
1649 v4l2_device_unregister_subdev(&res->subdev);
1650 omap3isp_video_unregister(&res->video_in);
1651 omap3isp_video_unregister(&res->video_out);
1652}
1653
1654int omap3isp_resizer_register_entities(struct isp_res_device *res,
1655 struct v4l2_device *vdev)
1656{
1657 int ret;
1658
1659 /* Register the subdev and video nodes. */
1660 ret = v4l2_device_register_subdev(vdev, &res->subdev);
1661 if (ret < 0)
1662 goto error;
1663
1664 ret = omap3isp_video_register(&res->video_in, vdev);
1665 if (ret < 0)
1666 goto error;
1667
1668 ret = omap3isp_video_register(&res->video_out, vdev);
1669 if (ret < 0)
1670 goto error;
1671
1672 return 0;
1673
1674error:
1675 omap3isp_resizer_unregister_entities(res);
1676 return ret;
1677}
1678
1679/* -----------------------------------------------------------------------------
1680 * ISP resizer initialization and cleanup
1681 */
1682
1683/*
1684 * resizer_init_entities - Initialize resizer subdev and media entity.
1685 * @res : Pointer to resizer device structure
1686 * return -ENOMEM or zero on success
1687 */
1688static int resizer_init_entities(struct isp_res_device *res)
1689{
1690 struct v4l2_subdev *sd = &res->subdev;
1691 struct media_pad *pads = res->pads;
1692 struct media_entity *me = &sd->entity;
1693 int ret;
1694
1695 res->input = RESIZER_INPUT_NONE;
1696
1697 v4l2_subdev_init(sd, &resizer_v4l2_ops);
1698 sd->internal_ops = &resizer_v4l2_internal_ops;
1699 strlcpy(sd->name, "OMAP3 ISP resizer", sizeof(sd->name));
1700 sd->grp_id = 1 << 16; /* group ID for isp subdevs */
1701 v4l2_set_subdevdata(sd, res);
1702 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
1703
1704 pads[RESZ_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
1705 pads[RESZ_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
1706
1707 me->ops = &resizer_media_ops;
1708 ret = media_entity_init(me, RESZ_PADS_NUM, pads, 0);
1709 if (ret < 0)
1710 return ret;
1711
1712 resizer_init_formats(sd, NULL);
1713
1714 res->video_in.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
1715 res->video_in.ops = &resizer_video_ops;
1716 res->video_in.isp = to_isp_device(res);
1717 res->video_in.capture_mem = PAGE_ALIGN(4096 * 4096) * 2 * 3;
1718 res->video_in.bpl_alignment = 32;
1719 res->video_out.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1720 res->video_out.ops = &resizer_video_ops;
1721 res->video_out.isp = to_isp_device(res);
1722 res->video_out.capture_mem = PAGE_ALIGN(4096 * 4096) * 2 * 3;
1723 res->video_out.bpl_alignment = 32;
1724
1725 ret = omap3isp_video_init(&res->video_in, "resizer");
1726 if (ret < 0)
1727 goto error_video_in;
1728
1729 ret = omap3isp_video_init(&res->video_out, "resizer");
1730 if (ret < 0)
1731 goto error_video_out;
1732
1733 res->video_out.video.entity.flags |= MEDIA_ENT_FL_DEFAULT;
1734
1735 /* Connect the video nodes to the resizer subdev. */
1736 ret = media_entity_create_link(&res->video_in.video.entity, 0,
1737 &res->subdev.entity, RESZ_PAD_SINK, 0);
1738 if (ret < 0)
1739 goto error_link;
1740
1741 ret = media_entity_create_link(&res->subdev.entity, RESZ_PAD_SOURCE,
1742 &res->video_out.video.entity, 0, 0);
1743 if (ret < 0)
1744 goto error_link;
1745
1746 return 0;
1747
1748error_link:
1749 omap3isp_video_cleanup(&res->video_out);
1750error_video_out:
1751 omap3isp_video_cleanup(&res->video_in);
1752error_video_in:
1753 media_entity_cleanup(&res->subdev.entity);
1754 return ret;
1755}
1756
1757/*
1758 * isp_resizer_init - Resizer initialization.
1759 * @isp : Pointer to ISP device
1760 * return -ENOMEM or zero on success
1761 */
1762int omap3isp_resizer_init(struct isp_device *isp)
1763{
1764 struct isp_res_device *res = &isp->isp_res;
1765
1766 init_waitqueue_head(&res->wait);
1767 atomic_set(&res->stopping, 0);
1768 return resizer_init_entities(res);
1769}
1770
1771void omap3isp_resizer_cleanup(struct isp_device *isp)
1772{
1773 struct isp_res_device *res = &isp->isp_res;
1774
1775 omap3isp_video_cleanup(&res->video_in);
1776 omap3isp_video_cleanup(&res->video_out);
1777 media_entity_cleanup(&res->subdev.entity);
1778}
diff --git a/drivers/media/video/omap3isp/ispresizer.h b/drivers/media/video/omap3isp/ispresizer.h
deleted file mode 100644
index 70c1c0e1bbdf..000000000000
--- a/drivers/media/video/omap3isp/ispresizer.h
+++ /dev/null
@@ -1,146 +0,0 @@
1/*
2 * ispresizer.h
3 *
4 * TI OMAP3 ISP - Resizer module
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc
8 *
9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 * Sakari Ailus <sakari.ailus@iki.fi>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 */
26
27#ifndef OMAP3_ISP_RESIZER_H
28#define OMAP3_ISP_RESIZER_H
29
30#include <linux/types.h>
31
32/*
33 * Constants for filter coefficents count
34 */
35#define COEFF_CNT 32
36
37/*
38 * struct isprsz_coef - Structure for resizer filter coeffcients.
39 * @h_filter_coef_4tap: Horizontal filter coefficients for 8-phase/4-tap
40 * mode (.5x-4x)
41 * @v_filter_coef_4tap: Vertical filter coefficients for 8-phase/4-tap
42 * mode (.5x-4x)
43 * @h_filter_coef_7tap: Horizontal filter coefficients for 4-phase/7-tap
44 * mode (.25x-.5x)
45 * @v_filter_coef_7tap: Vertical filter coefficients for 4-phase/7-tap
46 * mode (.25x-.5x)
47 */
48struct isprsz_coef {
49 u16 h_filter_coef_4tap[32];
50 u16 v_filter_coef_4tap[32];
51 /* Every 8th value is a dummy value in the following arrays: */
52 u16 h_filter_coef_7tap[32];
53 u16 v_filter_coef_7tap[32];
54};
55
56/* Chrominance horizontal algorithm */
57enum resizer_chroma_algo {
58 RSZ_THE_SAME = 0, /* Chrominance the same as Luminance */
59 RSZ_BILINEAR = 1, /* Chrominance uses bilinear interpolation */
60};
61
62/* Resizer input type select */
63enum resizer_colors_type {
64 RSZ_YUV422 = 0, /* YUV422 color is interleaved */
65 RSZ_COLOR8 = 1, /* Color separate data on 8 bits */
66};
67
68/*
69 * Structure for horizontal and vertical resizing value
70 */
71struct resizer_ratio {
72 u32 horz;
73 u32 vert;
74};
75
76/*
77 * Structure for luminance enhancer parameters.
78 */
79struct resizer_luma_yenh {
80 u8 algo; /* algorithm select. */
81 u8 gain; /* maximum gain. */
82 u8 slope; /* slope. */
83 u8 core; /* core offset. */
84};
85
86enum resizer_input_entity {
87 RESIZER_INPUT_NONE,
88 RESIZER_INPUT_VP, /* input video port - prev or ccdc */
89 RESIZER_INPUT_MEMORY,
90};
91
92/* Sink and source resizer pads */
93#define RESZ_PAD_SINK 0
94#define RESZ_PAD_SOURCE 1
95#define RESZ_PADS_NUM 2
96
97/*
98 * struct isp_res_device - OMAP3 ISP resizer module
99 * @crop.request: Crop rectangle requested by the user
100 * @crop.active: Active crop rectangle (based on hardware requirements)
101 */
102struct isp_res_device {
103 struct v4l2_subdev subdev;
104 struct media_pad pads[RESZ_PADS_NUM];
105 struct v4l2_mbus_framefmt formats[RESZ_PADS_NUM];
106
107 enum resizer_input_entity input;
108 struct isp_video video_in;
109 struct isp_video video_out;
110
111 u32 addr_base; /* stored source buffer address in memory mode */
112 u32 crop_offset; /* additional offset for crop in memory mode */
113 struct resizer_ratio ratio;
114 int pm_state;
115 unsigned int applycrop:1;
116 enum isp_pipeline_stream_state state;
117 wait_queue_head_t wait;
118 atomic_t stopping;
119
120 struct {
121 struct v4l2_rect request;
122 struct v4l2_rect active;
123 } crop;
124};
125
126struct isp_device;
127
128int omap3isp_resizer_init(struct isp_device *isp);
129void omap3isp_resizer_cleanup(struct isp_device *isp);
130
131int omap3isp_resizer_register_entities(struct isp_res_device *res,
132 struct v4l2_device *vdev);
133void omap3isp_resizer_unregister_entities(struct isp_res_device *res);
134void omap3isp_resizer_isr_frame_sync(struct isp_res_device *res);
135void omap3isp_resizer_isr(struct isp_res_device *isp_res);
136
137void omap3isp_resizer_max_rate(struct isp_res_device *res,
138 unsigned int *max_rate);
139
140void omap3isp_resizer_suspend(struct isp_res_device *isp_res);
141
142void omap3isp_resizer_resume(struct isp_res_device *isp_res);
143
144int omap3isp_resizer_busy(struct isp_res_device *isp_res);
145
146#endif /* OMAP3_ISP_RESIZER_H */
diff --git a/drivers/media/video/omap3isp/ispstat.c b/drivers/media/video/omap3isp/ispstat.c
deleted file mode 100644
index b8640be692f1..000000000000
--- a/drivers/media/video/omap3isp/ispstat.c
+++ /dev/null
@@ -1,1102 +0,0 @@
1/*
2 * ispstat.c
3 *
4 * TI OMAP3 ISP - Statistics core
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc
8 *
9 * Contacts: David Cohen <dacohen@gmail.com>
10 * Laurent Pinchart <laurent.pinchart@ideasonboard.com>
11 * Sakari Ailus <sakari.ailus@iki.fi>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
25 * 02110-1301 USA
26 */
27
28#include <linux/dma-mapping.h>
29#include <linux/slab.h>
30#include <linux/uaccess.h>
31
32#include "isp.h"
33
34#define IS_COHERENT_BUF(stat) ((stat)->dma_ch >= 0)
35
36/*
37 * MAGIC_SIZE must always be the greatest common divisor of
38 * AEWB_PACKET_SIZE and AF_PAXEL_SIZE.
39 */
40#define MAGIC_SIZE 16
41#define MAGIC_NUM 0x55
42
43/* HACK: AF module seems to be writing one more paxel data than it should. */
44#define AF_EXTRA_DATA OMAP3ISP_AF_PAXEL_SIZE
45
46/*
47 * HACK: H3A modules go to an invalid state after have a SBL overflow. It makes
48 * the next buffer to start to be written in the same point where the overflow
49 * occurred instead of the configured address. The only known way to make it to
50 * go back to a valid state is having a valid buffer processing. Of course it
51 * requires at least a doubled buffer size to avoid an access to invalid memory
52 * region. But it does not fix everything. It may happen more than one
53 * consecutive SBL overflows. In that case, it might be unpredictable how many
54 * buffers the allocated memory should fit. For that case, a recover
55 * configuration was created. It produces the minimum buffer size for each H3A
56 * module and decrease the change for more SBL overflows. This recover state
57 * will be enabled every time a SBL overflow occur. As the output buffer size
58 * isn't big, it's possible to have an extra size able to fit many recover
59 * buffers making it extreamily unlikely to have an access to invalid memory
60 * region.
61 */
62#define NUM_H3A_RECOVER_BUFS 10
63
64/*
65 * HACK: Because of HW issues the generic layer sometimes need to have
66 * different behaviour for different statistic modules.
67 */
68#define IS_H3A_AF(stat) ((stat) == &(stat)->isp->isp_af)
69#define IS_H3A_AEWB(stat) ((stat) == &(stat)->isp->isp_aewb)
70#define IS_H3A(stat) (IS_H3A_AF(stat) || IS_H3A_AEWB(stat))
71
72static void __isp_stat_buf_sync_magic(struct ispstat *stat,
73 struct ispstat_buffer *buf,
74 u32 buf_size, enum dma_data_direction dir,
75 void (*dma_sync)(struct device *,
76 dma_addr_t, unsigned long, size_t,
77 enum dma_data_direction))
78{
79 struct device *dev = stat->isp->dev;
80 struct page *pg;
81 dma_addr_t dma_addr;
82 u32 offset;
83
84 /* Initial magic words */
85 pg = vmalloc_to_page(buf->virt_addr);
86 dma_addr = pfn_to_dma(dev, page_to_pfn(pg));
87 dma_sync(dev, dma_addr, 0, MAGIC_SIZE, dir);
88
89 /* Final magic words */
90 pg = vmalloc_to_page(buf->virt_addr + buf_size);
91 dma_addr = pfn_to_dma(dev, page_to_pfn(pg));
92 offset = ((u32)buf->virt_addr + buf_size) & ~PAGE_MASK;
93 dma_sync(dev, dma_addr, offset, MAGIC_SIZE, dir);
94}
95
96static void isp_stat_buf_sync_magic_for_device(struct ispstat *stat,
97 struct ispstat_buffer *buf,
98 u32 buf_size,
99 enum dma_data_direction dir)
100{
101 if (IS_COHERENT_BUF(stat))
102 return;
103
104 __isp_stat_buf_sync_magic(stat, buf, buf_size, dir,
105 dma_sync_single_range_for_device);
106}
107
108static void isp_stat_buf_sync_magic_for_cpu(struct ispstat *stat,
109 struct ispstat_buffer *buf,
110 u32 buf_size,
111 enum dma_data_direction dir)
112{
113 if (IS_COHERENT_BUF(stat))
114 return;
115
116 __isp_stat_buf_sync_magic(stat, buf, buf_size, dir,
117 dma_sync_single_range_for_cpu);
118}
119
120static int isp_stat_buf_check_magic(struct ispstat *stat,
121 struct ispstat_buffer *buf)
122{
123 const u32 buf_size = IS_H3A_AF(stat) ?
124 buf->buf_size + AF_EXTRA_DATA : buf->buf_size;
125 u8 *w;
126 u8 *end;
127 int ret = -EINVAL;
128
129 isp_stat_buf_sync_magic_for_cpu(stat, buf, buf_size, DMA_FROM_DEVICE);
130
131 /* Checking initial magic numbers. They shouldn't be here anymore. */
132 for (w = buf->virt_addr, end = w + MAGIC_SIZE; w < end; w++)
133 if (likely(*w != MAGIC_NUM))
134 ret = 0;
135
136 if (ret) {
137 dev_dbg(stat->isp->dev, "%s: beginning magic check does not "
138 "match.\n", stat->subdev.name);
139 return ret;
140 }
141
142 /* Checking magic numbers at the end. They must be still here. */
143 for (w = buf->virt_addr + buf_size, end = w + MAGIC_SIZE;
144 w < end; w++) {
145 if (unlikely(*w != MAGIC_NUM)) {
146 dev_dbg(stat->isp->dev, "%s: endding magic check does "
147 "not match.\n", stat->subdev.name);
148 return -EINVAL;
149 }
150 }
151
152 isp_stat_buf_sync_magic_for_device(stat, buf, buf_size,
153 DMA_FROM_DEVICE);
154
155 return 0;
156}
157
158static void isp_stat_buf_insert_magic(struct ispstat *stat,
159 struct ispstat_buffer *buf)
160{
161 const u32 buf_size = IS_H3A_AF(stat) ?
162 stat->buf_size + AF_EXTRA_DATA : stat->buf_size;
163
164 isp_stat_buf_sync_magic_for_cpu(stat, buf, buf_size, DMA_FROM_DEVICE);
165
166 /*
167 * Inserting MAGIC_NUM at the beginning and end of the buffer.
168 * buf->buf_size is set only after the buffer is queued. For now the
169 * right buf_size for the current configuration is pointed by
170 * stat->buf_size.
171 */
172 memset(buf->virt_addr, MAGIC_NUM, MAGIC_SIZE);
173 memset(buf->virt_addr + buf_size, MAGIC_NUM, MAGIC_SIZE);
174
175 isp_stat_buf_sync_magic_for_device(stat, buf, buf_size,
176 DMA_BIDIRECTIONAL);
177}
178
179static void isp_stat_buf_sync_for_device(struct ispstat *stat,
180 struct ispstat_buffer *buf)
181{
182 if (IS_COHERENT_BUF(stat))
183 return;
184
185 dma_sync_sg_for_device(stat->isp->dev, buf->iovm->sgt->sgl,
186 buf->iovm->sgt->nents, DMA_FROM_DEVICE);
187}
188
189static void isp_stat_buf_sync_for_cpu(struct ispstat *stat,
190 struct ispstat_buffer *buf)
191{
192 if (IS_COHERENT_BUF(stat))
193 return;
194
195 dma_sync_sg_for_cpu(stat->isp->dev, buf->iovm->sgt->sgl,
196 buf->iovm->sgt->nents, DMA_FROM_DEVICE);
197}
198
199static void isp_stat_buf_clear(struct ispstat *stat)
200{
201 int i;
202
203 for (i = 0; i < STAT_MAX_BUFS; i++)
204 stat->buf[i].empty = 1;
205}
206
207static struct ispstat_buffer *
208__isp_stat_buf_find(struct ispstat *stat, int look_empty)
209{
210 struct ispstat_buffer *found = NULL;
211 int i;
212
213 for (i = 0; i < STAT_MAX_BUFS; i++) {
214 struct ispstat_buffer *curr = &stat->buf[i];
215
216 /*
217 * Don't select the buffer which is being copied to
218 * userspace or used by the module.
219 */
220 if (curr == stat->locked_buf || curr == stat->active_buf)
221 continue;
222
223 /* Don't select uninitialised buffers if it's not required */
224 if (!look_empty && curr->empty)
225 continue;
226
227 /* Pick uninitialised buffer over anything else if look_empty */
228 if (curr->empty) {
229 found = curr;
230 break;
231 }
232
233 /* Choose the oldest buffer */
234 if (!found ||
235 (s32)curr->frame_number - (s32)found->frame_number < 0)
236 found = curr;
237 }
238
239 return found;
240}
241
242static inline struct ispstat_buffer *
243isp_stat_buf_find_oldest(struct ispstat *stat)
244{
245 return __isp_stat_buf_find(stat, 0);
246}
247
248static inline struct ispstat_buffer *
249isp_stat_buf_find_oldest_or_empty(struct ispstat *stat)
250{
251 return __isp_stat_buf_find(stat, 1);
252}
253
254static int isp_stat_buf_queue(struct ispstat *stat)
255{
256 if (!stat->active_buf)
257 return STAT_NO_BUF;
258
259 do_gettimeofday(&stat->active_buf->ts);
260
261 stat->active_buf->buf_size = stat->buf_size;
262 if (isp_stat_buf_check_magic(stat, stat->active_buf)) {
263 dev_dbg(stat->isp->dev, "%s: data wasn't properly written.\n",
264 stat->subdev.name);
265 return STAT_NO_BUF;
266 }
267 stat->active_buf->config_counter = stat->config_counter;
268 stat->active_buf->frame_number = stat->frame_number;
269 stat->active_buf->empty = 0;
270 stat->active_buf = NULL;
271
272 return STAT_BUF_DONE;
273}
274
275/* Get next free buffer to write the statistics to and mark it active. */
276static void isp_stat_buf_next(struct ispstat *stat)
277{
278 if (unlikely(stat->active_buf))
279 /* Overwriting unused active buffer */
280 dev_dbg(stat->isp->dev, "%s: new buffer requested without "
281 "queuing active one.\n",
282 stat->subdev.name);
283 else
284 stat->active_buf = isp_stat_buf_find_oldest_or_empty(stat);
285}
286
287static void isp_stat_buf_release(struct ispstat *stat)
288{
289 unsigned long flags;
290
291 isp_stat_buf_sync_for_device(stat, stat->locked_buf);
292 spin_lock_irqsave(&stat->isp->stat_lock, flags);
293 stat->locked_buf = NULL;
294 spin_unlock_irqrestore(&stat->isp->stat_lock, flags);
295}
296
297/* Get buffer to userspace. */
298static struct ispstat_buffer *isp_stat_buf_get(struct ispstat *stat,
299 struct omap3isp_stat_data *data)
300{
301 int rval = 0;
302 unsigned long flags;
303 struct ispstat_buffer *buf;
304
305 spin_lock_irqsave(&stat->isp->stat_lock, flags);
306
307 while (1) {
308 buf = isp_stat_buf_find_oldest(stat);
309 if (!buf) {
310 spin_unlock_irqrestore(&stat->isp->stat_lock, flags);
311 dev_dbg(stat->isp->dev, "%s: cannot find a buffer.\n",
312 stat->subdev.name);
313 return ERR_PTR(-EBUSY);
314 }
315 if (isp_stat_buf_check_magic(stat, buf)) {
316 dev_dbg(stat->isp->dev, "%s: current buffer has "
317 "corrupted data\n.", stat->subdev.name);
318 /* Mark empty because it doesn't have valid data. */
319 buf->empty = 1;
320 } else {
321 /* Buffer isn't corrupted. */
322 break;
323 }
324 }
325
326 stat->locked_buf = buf;
327
328 spin_unlock_irqrestore(&stat->isp->stat_lock, flags);
329
330 if (buf->buf_size > data->buf_size) {
331 dev_warn(stat->isp->dev, "%s: userspace's buffer size is "
332 "not enough.\n", stat->subdev.name);
333 isp_stat_buf_release(stat);
334 return ERR_PTR(-EINVAL);
335 }
336
337 isp_stat_buf_sync_for_cpu(stat, buf);
338
339 rval = copy_to_user(data->buf,
340 buf->virt_addr,
341 buf->buf_size);
342
343 if (rval) {
344 dev_info(stat->isp->dev,
345 "%s: failed copying %d bytes of stat data\n",
346 stat->subdev.name, rval);
347 buf = ERR_PTR(-EFAULT);
348 isp_stat_buf_release(stat);
349 }
350
351 return buf;
352}
353
354static void isp_stat_bufs_free(struct ispstat *stat)
355{
356 struct isp_device *isp = stat->isp;
357 int i;
358
359 for (i = 0; i < STAT_MAX_BUFS; i++) {
360 struct ispstat_buffer *buf = &stat->buf[i];
361
362 if (!IS_COHERENT_BUF(stat)) {
363 if (IS_ERR_OR_NULL((void *)buf->iommu_addr))
364 continue;
365 if (buf->iovm)
366 dma_unmap_sg(isp->dev, buf->iovm->sgt->sgl,
367 buf->iovm->sgt->nents,
368 DMA_FROM_DEVICE);
369 omap_iommu_vfree(isp->domain, isp->dev,
370 buf->iommu_addr);
371 } else {
372 if (!buf->virt_addr)
373 continue;
374 dma_free_coherent(stat->isp->dev, stat->buf_alloc_size,
375 buf->virt_addr, buf->dma_addr);
376 }
377 buf->iommu_addr = 0;
378 buf->iovm = NULL;
379 buf->dma_addr = 0;
380 buf->virt_addr = NULL;
381 buf->empty = 1;
382 }
383
384 dev_dbg(stat->isp->dev, "%s: all buffers were freed.\n",
385 stat->subdev.name);
386
387 stat->buf_alloc_size = 0;
388 stat->active_buf = NULL;
389}
390
391static int isp_stat_bufs_alloc_iommu(struct ispstat *stat, unsigned int size)
392{
393 struct isp_device *isp = stat->isp;
394 int i;
395
396 stat->buf_alloc_size = size;
397
398 for (i = 0; i < STAT_MAX_BUFS; i++) {
399 struct ispstat_buffer *buf = &stat->buf[i];
400 struct iovm_struct *iovm;
401
402 WARN_ON(buf->dma_addr);
403 buf->iommu_addr = omap_iommu_vmalloc(isp->domain, isp->dev, 0,
404 size, IOMMU_FLAG);
405 if (IS_ERR((void *)buf->iommu_addr)) {
406 dev_err(stat->isp->dev,
407 "%s: Can't acquire memory for "
408 "buffer %d\n", stat->subdev.name, i);
409 isp_stat_bufs_free(stat);
410 return -ENOMEM;
411 }
412
413 iovm = omap_find_iovm_area(isp->dev, buf->iommu_addr);
414 if (!iovm ||
415 !dma_map_sg(isp->dev, iovm->sgt->sgl, iovm->sgt->nents,
416 DMA_FROM_DEVICE)) {
417 isp_stat_bufs_free(stat);
418 return -ENOMEM;
419 }
420 buf->iovm = iovm;
421
422 buf->virt_addr = omap_da_to_va(stat->isp->dev,
423 (u32)buf->iommu_addr);
424 buf->empty = 1;
425 dev_dbg(stat->isp->dev, "%s: buffer[%d] allocated."
426 "iommu_addr=0x%08lx virt_addr=0x%08lx",
427 stat->subdev.name, i, buf->iommu_addr,
428 (unsigned long)buf->virt_addr);
429 }
430
431 return 0;
432}
433
434static int isp_stat_bufs_alloc_dma(struct ispstat *stat, unsigned int size)
435{
436 int i;
437
438 stat->buf_alloc_size = size;
439
440 for (i = 0; i < STAT_MAX_BUFS; i++) {
441 struct ispstat_buffer *buf = &stat->buf[i];
442
443 WARN_ON(buf->iommu_addr);
444 buf->virt_addr = dma_alloc_coherent(stat->isp->dev, size,
445 &buf->dma_addr, GFP_KERNEL | GFP_DMA);
446
447 if (!buf->virt_addr || !buf->dma_addr) {
448 dev_info(stat->isp->dev,
449 "%s: Can't acquire memory for "
450 "DMA buffer %d\n", stat->subdev.name, i);
451 isp_stat_bufs_free(stat);
452 return -ENOMEM;
453 }
454 buf->empty = 1;
455
456 dev_dbg(stat->isp->dev, "%s: buffer[%d] allocated."
457 "dma_addr=0x%08lx virt_addr=0x%08lx\n",
458 stat->subdev.name, i, (unsigned long)buf->dma_addr,
459 (unsigned long)buf->virt_addr);
460 }
461
462 return 0;
463}
464
465static int isp_stat_bufs_alloc(struct ispstat *stat, u32 size)
466{
467 unsigned long flags;
468
469 spin_lock_irqsave(&stat->isp->stat_lock, flags);
470
471 BUG_ON(stat->locked_buf != NULL);
472
473 /* Are the old buffers big enough? */
474 if (stat->buf_alloc_size >= size) {
475 spin_unlock_irqrestore(&stat->isp->stat_lock, flags);
476 return 0;
477 }
478
479 if (stat->state != ISPSTAT_DISABLED || stat->buf_processing) {
480 dev_info(stat->isp->dev,
481 "%s: trying to allocate memory when busy\n",
482 stat->subdev.name);
483 spin_unlock_irqrestore(&stat->isp->stat_lock, flags);
484 return -EBUSY;
485 }
486
487 spin_unlock_irqrestore(&stat->isp->stat_lock, flags);
488
489 isp_stat_bufs_free(stat);
490
491 if (IS_COHERENT_BUF(stat))
492 return isp_stat_bufs_alloc_dma(stat, size);
493 else
494 return isp_stat_bufs_alloc_iommu(stat, size);
495}
496
497static void isp_stat_queue_event(struct ispstat *stat, int err)
498{
499 struct video_device *vdev = stat->subdev.devnode;
500 struct v4l2_event event;
501 struct omap3isp_stat_event_status *status = (void *)event.u.data;
502
503 memset(&event, 0, sizeof(event));
504 if (!err) {
505 status->frame_number = stat->frame_number;
506 status->config_counter = stat->config_counter;
507 } else {
508 status->buf_err = 1;
509 }
510 event.type = stat->event_type;
511 v4l2_event_queue(vdev, &event);
512}
513
514
515/*
516 * omap3isp_stat_request_statistics - Request statistics.
517 * @data: Pointer to return statistics data.
518 *
519 * Returns 0 if successful.
520 */
521int omap3isp_stat_request_statistics(struct ispstat *stat,
522 struct omap3isp_stat_data *data)
523{
524 struct ispstat_buffer *buf;
525
526 if (stat->state != ISPSTAT_ENABLED) {
527 dev_dbg(stat->isp->dev, "%s: engine not enabled.\n",
528 stat->subdev.name);
529 return -EINVAL;
530 }
531
532 mutex_lock(&stat->ioctl_lock);
533 buf = isp_stat_buf_get(stat, data);
534 if (IS_ERR(buf)) {
535 mutex_unlock(&stat->ioctl_lock);
536 return PTR_ERR(buf);
537 }
538
539 data->ts = buf->ts;
540 data->config_counter = buf->config_counter;
541 data->frame_number = buf->frame_number;
542 data->buf_size = buf->buf_size;
543
544 buf->empty = 1;
545 isp_stat_buf_release(stat);
546 mutex_unlock(&stat->ioctl_lock);
547
548 return 0;
549}
550
551/*
552 * omap3isp_stat_config - Receives new statistic engine configuration.
553 * @new_conf: Pointer to config structure.
554 *
555 * Returns 0 if successful, -EINVAL if new_conf pointer is NULL, -ENOMEM if
556 * was unable to allocate memory for the buffer, or other errors if parameters
557 * are invalid.
558 */
559int omap3isp_stat_config(struct ispstat *stat, void *new_conf)
560{
561 int ret;
562 unsigned long irqflags;
563 struct ispstat_generic_config *user_cfg = new_conf;
564 u32 buf_size = user_cfg->buf_size;
565
566 if (!new_conf) {
567 dev_dbg(stat->isp->dev, "%s: configuration is NULL\n",
568 stat->subdev.name);
569 return -EINVAL;
570 }
571
572 mutex_lock(&stat->ioctl_lock);
573
574 dev_dbg(stat->isp->dev, "%s: configuring module with buffer "
575 "size=0x%08lx\n", stat->subdev.name, (unsigned long)buf_size);
576
577 ret = stat->ops->validate_params(stat, new_conf);
578 if (ret) {
579 mutex_unlock(&stat->ioctl_lock);
580 dev_dbg(stat->isp->dev, "%s: configuration values are "
581 "invalid.\n", stat->subdev.name);
582 return ret;
583 }
584
585 if (buf_size != user_cfg->buf_size)
586 dev_dbg(stat->isp->dev, "%s: driver has corrected buffer size "
587 "request to 0x%08lx\n", stat->subdev.name,
588 (unsigned long)user_cfg->buf_size);
589
590 /*
591 * Hack: H3A modules may need a doubled buffer size to avoid access
592 * to a invalid memory address after a SBL overflow.
593 * The buffer size is always PAGE_ALIGNED.
594 * Hack 2: MAGIC_SIZE is added to buf_size so a magic word can be
595 * inserted at the end to data integrity check purpose.
596 * Hack 3: AF module writes one paxel data more than it should, so
597 * the buffer allocation must consider it to avoid invalid memory
598 * access.
599 * Hack 4: H3A need to allocate extra space for the recover state.
600 */
601 if (IS_H3A(stat)) {
602 buf_size = user_cfg->buf_size * 2 + MAGIC_SIZE;
603 if (IS_H3A_AF(stat))
604 /*
605 * Adding one extra paxel data size for each recover
606 * buffer + 2 regular ones.
607 */
608 buf_size += AF_EXTRA_DATA * (NUM_H3A_RECOVER_BUFS + 2);
609 if (stat->recover_priv) {
610 struct ispstat_generic_config *recover_cfg =
611 stat->recover_priv;
612 buf_size += recover_cfg->buf_size *
613 NUM_H3A_RECOVER_BUFS;
614 }
615 buf_size = PAGE_ALIGN(buf_size);
616 } else { /* Histogram */
617 buf_size = PAGE_ALIGN(user_cfg->buf_size + MAGIC_SIZE);
618 }
619
620 ret = isp_stat_bufs_alloc(stat, buf_size);
621 if (ret) {
622 mutex_unlock(&stat->ioctl_lock);
623 return ret;
624 }
625
626 spin_lock_irqsave(&stat->isp->stat_lock, irqflags);
627 stat->ops->set_params(stat, new_conf);
628 spin_unlock_irqrestore(&stat->isp->stat_lock, irqflags);
629
630 /*
631 * Returning the right future config_counter for this setup, so
632 * userspace can *know* when it has been applied.
633 */
634 user_cfg->config_counter = stat->config_counter + stat->inc_config;
635
636 /* Module has a valid configuration. */
637 stat->configured = 1;
638 dev_dbg(stat->isp->dev, "%s: module has been successfully "
639 "configured.\n", stat->subdev.name);
640
641 mutex_unlock(&stat->ioctl_lock);
642
643 return 0;
644}
645
646/*
647 * isp_stat_buf_process - Process statistic buffers.
648 * @buf_state: points out if buffer is ready to be processed. It's necessary
649 * because histogram needs to copy the data from internal memory
650 * before be able to process the buffer.
651 */
652static int isp_stat_buf_process(struct ispstat *stat, int buf_state)
653{
654 int ret = STAT_NO_BUF;
655
656 if (!atomic_add_unless(&stat->buf_err, -1, 0) &&
657 buf_state == STAT_BUF_DONE && stat->state == ISPSTAT_ENABLED) {
658 ret = isp_stat_buf_queue(stat);
659 isp_stat_buf_next(stat);
660 }
661
662 return ret;
663}
664
665int omap3isp_stat_pcr_busy(struct ispstat *stat)
666{
667 return stat->ops->busy(stat);
668}
669
670int omap3isp_stat_busy(struct ispstat *stat)
671{
672 return omap3isp_stat_pcr_busy(stat) | stat->buf_processing |
673 (stat->state != ISPSTAT_DISABLED);
674}
675
676/*
677 * isp_stat_pcr_enable - Disables/Enables statistic engines.
678 * @pcr_enable: 0/1 - Disables/Enables the engine.
679 *
680 * Must be called from ISP driver when the module is idle and synchronized
681 * with CCDC.
682 */
683static void isp_stat_pcr_enable(struct ispstat *stat, u8 pcr_enable)
684{
685 if ((stat->state != ISPSTAT_ENABLING &&
686 stat->state != ISPSTAT_ENABLED) && pcr_enable)
687 /* Userspace has disabled the module. Aborting. */
688 return;
689
690 stat->ops->enable(stat, pcr_enable);
691 if (stat->state == ISPSTAT_DISABLING && !pcr_enable)
692 stat->state = ISPSTAT_DISABLED;
693 else if (stat->state == ISPSTAT_ENABLING && pcr_enable)
694 stat->state = ISPSTAT_ENABLED;
695}
696
697void omap3isp_stat_suspend(struct ispstat *stat)
698{
699 unsigned long flags;
700
701 spin_lock_irqsave(&stat->isp->stat_lock, flags);
702
703 if (stat->state != ISPSTAT_DISABLED)
704 stat->ops->enable(stat, 0);
705 if (stat->state == ISPSTAT_ENABLED)
706 stat->state = ISPSTAT_SUSPENDED;
707
708 spin_unlock_irqrestore(&stat->isp->stat_lock, flags);
709}
710
711void omap3isp_stat_resume(struct ispstat *stat)
712{
713 /* Module will be re-enabled with its pipeline */
714 if (stat->state == ISPSTAT_SUSPENDED)
715 stat->state = ISPSTAT_ENABLING;
716}
717
718static void isp_stat_try_enable(struct ispstat *stat)
719{
720 unsigned long irqflags;
721
722 if (stat->priv == NULL)
723 /* driver wasn't initialised */
724 return;
725
726 spin_lock_irqsave(&stat->isp->stat_lock, irqflags);
727 if (stat->state == ISPSTAT_ENABLING && !stat->buf_processing &&
728 stat->buf_alloc_size) {
729 /*
730 * Userspace's requested to enable the engine but it wasn't yet.
731 * Let's do that now.
732 */
733 stat->update = 1;
734 isp_stat_buf_next(stat);
735 stat->ops->setup_regs(stat, stat->priv);
736 isp_stat_buf_insert_magic(stat, stat->active_buf);
737
738 /*
739 * H3A module has some hw issues which forces the driver to
740 * ignore next buffers even if it was disabled in the meantime.
741 * On the other hand, Histogram shouldn't ignore buffers anymore
742 * if it's being enabled.
743 */
744 if (!IS_H3A(stat))
745 atomic_set(&stat->buf_err, 0);
746
747 isp_stat_pcr_enable(stat, 1);
748 spin_unlock_irqrestore(&stat->isp->stat_lock, irqflags);
749 dev_dbg(stat->isp->dev, "%s: module is enabled.\n",
750 stat->subdev.name);
751 } else {
752 spin_unlock_irqrestore(&stat->isp->stat_lock, irqflags);
753 }
754}
755
756void omap3isp_stat_isr_frame_sync(struct ispstat *stat)
757{
758 isp_stat_try_enable(stat);
759}
760
761void omap3isp_stat_sbl_overflow(struct ispstat *stat)
762{
763 unsigned long irqflags;
764
765 spin_lock_irqsave(&stat->isp->stat_lock, irqflags);
766 /*
767 * Due to a H3A hw issue which prevents the next buffer to start from
768 * the correct memory address, 2 buffers must be ignored.
769 */
770 atomic_set(&stat->buf_err, 2);
771
772 /*
773 * If more than one SBL overflow happen in a row, H3A module may access
774 * invalid memory region.
775 * stat->sbl_ovl_recover is set to tell to the driver to temporarily use
776 * a soft configuration which helps to avoid consecutive overflows.
777 */
778 if (stat->recover_priv)
779 stat->sbl_ovl_recover = 1;
780 spin_unlock_irqrestore(&stat->isp->stat_lock, irqflags);
781}
782
783/*
784 * omap3isp_stat_enable - Disable/Enable statistic engine as soon as possible
785 * @enable: 0/1 - Disables/Enables the engine.
786 *
787 * Client should configure all the module registers before this.
788 * This function can be called from a userspace request.
789 */
790int omap3isp_stat_enable(struct ispstat *stat, u8 enable)
791{
792 unsigned long irqflags;
793
794 dev_dbg(stat->isp->dev, "%s: user wants to %s module.\n",
795 stat->subdev.name, enable ? "enable" : "disable");
796
797 /* Prevent enabling while configuring */
798 mutex_lock(&stat->ioctl_lock);
799
800 spin_lock_irqsave(&stat->isp->stat_lock, irqflags);
801
802 if (!stat->configured && enable) {
803 spin_unlock_irqrestore(&stat->isp->stat_lock, irqflags);
804 mutex_unlock(&stat->ioctl_lock);
805 dev_dbg(stat->isp->dev, "%s: cannot enable module as it's "
806 "never been successfully configured so far.\n",
807 stat->subdev.name);
808 return -EINVAL;
809 }
810
811 if (enable) {
812 if (stat->state == ISPSTAT_DISABLING)
813 /* Previous disabling request wasn't done yet */
814 stat->state = ISPSTAT_ENABLED;
815 else if (stat->state == ISPSTAT_DISABLED)
816 /* Module is now being enabled */
817 stat->state = ISPSTAT_ENABLING;
818 } else {
819 if (stat->state == ISPSTAT_ENABLING) {
820 /* Previous enabling request wasn't done yet */
821 stat->state = ISPSTAT_DISABLED;
822 } else if (stat->state == ISPSTAT_ENABLED) {
823 /* Module is now being disabled */
824 stat->state = ISPSTAT_DISABLING;
825 isp_stat_buf_clear(stat);
826 }
827 }
828
829 spin_unlock_irqrestore(&stat->isp->stat_lock, irqflags);
830 mutex_unlock(&stat->ioctl_lock);
831
832 return 0;
833}
834
835int omap3isp_stat_s_stream(struct v4l2_subdev *subdev, int enable)
836{
837 struct ispstat *stat = v4l2_get_subdevdata(subdev);
838
839 if (enable) {
840 /*
841 * Only set enable PCR bit if the module was previously
842 * enabled through ioct.
843 */
844 isp_stat_try_enable(stat);
845 } else {
846 unsigned long flags;
847 /* Disable PCR bit and config enable field */
848 omap3isp_stat_enable(stat, 0);
849 spin_lock_irqsave(&stat->isp->stat_lock, flags);
850 stat->ops->enable(stat, 0);
851 spin_unlock_irqrestore(&stat->isp->stat_lock, flags);
852
853 /*
854 * If module isn't busy, a new interrupt may come or not to
855 * set the state to DISABLED. As Histogram needs to read its
856 * internal memory to clear it, let interrupt handler
857 * responsible of changing state to DISABLED. If the last
858 * interrupt is coming, it's still safe as the handler will
859 * ignore the second time when state is already set to DISABLED.
860 * It's necessary to synchronize Histogram with streamoff, once
861 * the module may be considered idle before last SDMA transfer
862 * starts if we return here.
863 */
864 if (!omap3isp_stat_pcr_busy(stat))
865 omap3isp_stat_isr(stat);
866
867 dev_dbg(stat->isp->dev, "%s: module is being disabled\n",
868 stat->subdev.name);
869 }
870
871 return 0;
872}
873
874/*
875 * __stat_isr - Interrupt handler for statistic drivers
876 */
877static void __stat_isr(struct ispstat *stat, int from_dma)
878{
879 int ret = STAT_BUF_DONE;
880 int buf_processing;
881 unsigned long irqflags;
882 struct isp_pipeline *pipe;
883
884 /*
885 * stat->buf_processing must be set before disable module. It's
886 * necessary to not inform too early the buffers aren't busy in case
887 * of SDMA is going to be used.
888 */
889 spin_lock_irqsave(&stat->isp->stat_lock, irqflags);
890 if (stat->state == ISPSTAT_DISABLED) {
891 spin_unlock_irqrestore(&stat->isp->stat_lock, irqflags);
892 return;
893 }
894 buf_processing = stat->buf_processing;
895 stat->buf_processing = 1;
896 stat->ops->enable(stat, 0);
897
898 if (buf_processing && !from_dma) {
899 if (stat->state == ISPSTAT_ENABLED) {
900 spin_unlock_irqrestore(&stat->isp->stat_lock, irqflags);
901 dev_err(stat->isp->dev,
902 "%s: interrupt occurred when module was still "
903 "processing a buffer.\n", stat->subdev.name);
904 ret = STAT_NO_BUF;
905 goto out;
906 } else {
907 /*
908 * Interrupt handler was called from streamoff when
909 * the module wasn't busy anymore to ensure it is being
910 * disabled after process last buffer. If such buffer
911 * processing has already started, no need to do
912 * anything else.
913 */
914 spin_unlock_irqrestore(&stat->isp->stat_lock, irqflags);
915 return;
916 }
917 }
918 spin_unlock_irqrestore(&stat->isp->stat_lock, irqflags);
919
920 /* If it's busy we can't process this buffer anymore */
921 if (!omap3isp_stat_pcr_busy(stat)) {
922 if (!from_dma && stat->ops->buf_process)
923 /* Module still need to copy data to buffer. */
924 ret = stat->ops->buf_process(stat);
925 if (ret == STAT_BUF_WAITING_DMA)
926 /* Buffer is not ready yet */
927 return;
928
929 spin_lock_irqsave(&stat->isp->stat_lock, irqflags);
930
931 /*
932 * Histogram needs to read its internal memory to clear it
933 * before be disabled. For that reason, common statistic layer
934 * can return only after call stat's buf_process() operator.
935 */
936 if (stat->state == ISPSTAT_DISABLING) {
937 stat->state = ISPSTAT_DISABLED;
938 spin_unlock_irqrestore(&stat->isp->stat_lock, irqflags);
939 stat->buf_processing = 0;
940 return;
941 }
942 pipe = to_isp_pipeline(&stat->subdev.entity);
943 stat->frame_number = atomic_read(&pipe->frame_number);
944
945 /*
946 * Before this point, 'ret' stores the buffer's status if it's
947 * ready to be processed. Afterwards, it holds the status if
948 * it was processed successfully.
949 */
950 ret = isp_stat_buf_process(stat, ret);
951
952 if (likely(!stat->sbl_ovl_recover)) {
953 stat->ops->setup_regs(stat, stat->priv);
954 } else {
955 /*
956 * Using recover config to increase the chance to have
957 * a good buffer processing and make the H3A module to
958 * go back to a valid state.
959 */
960 stat->update = 1;
961 stat->ops->setup_regs(stat, stat->recover_priv);
962 stat->sbl_ovl_recover = 0;
963
964 /*
965 * Set 'update' in case of the module needs to use
966 * regular configuration after next buffer.
967 */
968 stat->update = 1;
969 }
970
971 isp_stat_buf_insert_magic(stat, stat->active_buf);
972
973 /*
974 * Hack: H3A modules may access invalid memory address or send
975 * corrupted data to userspace if more than 1 SBL overflow
976 * happens in a row without re-writing its buffer's start memory
977 * address in the meantime. Such situation is avoided if the
978 * module is not immediately re-enabled when the ISR misses the
979 * timing to process the buffer and to setup the registers.
980 * Because of that, pcr_enable(1) was moved to inside this 'if'
981 * block. But the next interruption will still happen as during
982 * pcr_enable(0) the module was busy.
983 */
984 isp_stat_pcr_enable(stat, 1);
985 spin_unlock_irqrestore(&stat->isp->stat_lock, irqflags);
986 } else {
987 /*
988 * If a SBL overflow occurs and the H3A driver misses the timing
989 * to process the buffer, stat->buf_err is set and won't be
990 * cleared now. So the next buffer will be correctly ignored.
991 * It's necessary due to a hw issue which makes the next H3A
992 * buffer to start from the memory address where the previous
993 * one stopped, instead of start where it was configured to.
994 * Do not "stat->buf_err = 0" here.
995 */
996
997 if (stat->ops->buf_process)
998 /*
999 * Driver may need to erase current data prior to
1000 * process a new buffer. If it misses the timing, the
1001 * next buffer might be wrong. So should be ignored.
1002 * It happens only for Histogram.
1003 */
1004 atomic_set(&stat->buf_err, 1);
1005
1006 ret = STAT_NO_BUF;
1007 dev_dbg(stat->isp->dev, "%s: cannot process buffer, "
1008 "device is busy.\n", stat->subdev.name);
1009 }
1010
1011out:
1012 stat->buf_processing = 0;
1013 isp_stat_queue_event(stat, ret != STAT_BUF_DONE);
1014}
1015
1016void omap3isp_stat_isr(struct ispstat *stat)
1017{
1018 __stat_isr(stat, 0);
1019}
1020
1021void omap3isp_stat_dma_isr(struct ispstat *stat)
1022{
1023 __stat_isr(stat, 1);
1024}
1025
1026int omap3isp_stat_subscribe_event(struct v4l2_subdev *subdev,
1027 struct v4l2_fh *fh,
1028 struct v4l2_event_subscription *sub)
1029{
1030 struct ispstat *stat = v4l2_get_subdevdata(subdev);
1031
1032 if (sub->type != stat->event_type)
1033 return -EINVAL;
1034
1035 return v4l2_event_subscribe(fh, sub, STAT_NEVENTS, NULL);
1036}
1037
1038int omap3isp_stat_unsubscribe_event(struct v4l2_subdev *subdev,
1039 struct v4l2_fh *fh,
1040 struct v4l2_event_subscription *sub)
1041{
1042 return v4l2_event_unsubscribe(fh, sub);
1043}
1044
1045void omap3isp_stat_unregister_entities(struct ispstat *stat)
1046{
1047 v4l2_device_unregister_subdev(&stat->subdev);
1048}
1049
1050int omap3isp_stat_register_entities(struct ispstat *stat,
1051 struct v4l2_device *vdev)
1052{
1053 return v4l2_device_register_subdev(vdev, &stat->subdev);
1054}
1055
1056static int isp_stat_init_entities(struct ispstat *stat, const char *name,
1057 const struct v4l2_subdev_ops *sd_ops)
1058{
1059 struct v4l2_subdev *subdev = &stat->subdev;
1060 struct media_entity *me = &subdev->entity;
1061
1062 v4l2_subdev_init(subdev, sd_ops);
1063 snprintf(subdev->name, V4L2_SUBDEV_NAME_SIZE, "OMAP3 ISP %s", name);
1064 subdev->grp_id = 1 << 16; /* group ID for isp subdevs */
1065 subdev->flags |= V4L2_SUBDEV_FL_HAS_EVENTS | V4L2_SUBDEV_FL_HAS_DEVNODE;
1066 v4l2_set_subdevdata(subdev, stat);
1067
1068 stat->pad.flags = MEDIA_PAD_FL_SINK;
1069 me->ops = NULL;
1070
1071 return media_entity_init(me, 1, &stat->pad, 0);
1072}
1073
1074int omap3isp_stat_init(struct ispstat *stat, const char *name,
1075 const struct v4l2_subdev_ops *sd_ops)
1076{
1077 int ret;
1078
1079 stat->buf = kcalloc(STAT_MAX_BUFS, sizeof(*stat->buf), GFP_KERNEL);
1080 if (!stat->buf)
1081 return -ENOMEM;
1082
1083 isp_stat_buf_clear(stat);
1084 mutex_init(&stat->ioctl_lock);
1085 atomic_set(&stat->buf_err, 0);
1086
1087 ret = isp_stat_init_entities(stat, name, sd_ops);
1088 if (ret < 0) {
1089 mutex_destroy(&stat->ioctl_lock);
1090 kfree(stat->buf);
1091 }
1092
1093 return ret;
1094}
1095
1096void omap3isp_stat_cleanup(struct ispstat *stat)
1097{
1098 media_entity_cleanup(&stat->subdev.entity);
1099 mutex_destroy(&stat->ioctl_lock);
1100 isp_stat_bufs_free(stat);
1101 kfree(stat->buf);
1102}
diff --git a/drivers/media/video/omap3isp/ispstat.h b/drivers/media/video/omap3isp/ispstat.h
deleted file mode 100644
index 9b7c8654dc8a..000000000000
--- a/drivers/media/video/omap3isp/ispstat.h
+++ /dev/null
@@ -1,169 +0,0 @@
1/*
2 * ispstat.h
3 *
4 * TI OMAP3 ISP - Statistics core
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc
8 *
9 * Contacts: David Cohen <dacohen@gmail.com>
10 * Laurent Pinchart <laurent.pinchart@ideasonboard.com>
11 * Sakari Ailus <sakari.ailus@iki.fi>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
25 * 02110-1301 USA
26 */
27
28#ifndef OMAP3_ISP_STAT_H
29#define OMAP3_ISP_STAT_H
30
31#include <linux/types.h>
32#include <linux/omap3isp.h>
33#include <plat/dma.h>
34#include <media/v4l2-event.h>
35
36#include "isp.h"
37#include "ispvideo.h"
38
39#define STAT_MAX_BUFS 5
40#define STAT_NEVENTS 8
41
42#define STAT_BUF_DONE 0 /* Buffer is ready */
43#define STAT_NO_BUF 1 /* An error has occurred */
44#define STAT_BUF_WAITING_DMA 2 /* Histogram only: DMA is running */
45
46struct ispstat;
47
48struct ispstat_buffer {
49 unsigned long iommu_addr;
50 struct iovm_struct *iovm;
51 void *virt_addr;
52 dma_addr_t dma_addr;
53 struct timeval ts;
54 u32 buf_size;
55 u32 frame_number;
56 u16 config_counter;
57 u8 empty;
58};
59
60struct ispstat_ops {
61 /*
62 * Validate new params configuration.
63 * new_conf->buf_size value must be changed to the exact buffer size
64 * necessary for the new configuration if it's smaller.
65 */
66 int (*validate_params)(struct ispstat *stat, void *new_conf);
67
68 /*
69 * Save new params configuration.
70 * stat->priv->buf_size value must be set to the exact buffer size for
71 * the new configuration.
72 * stat->update is set to 1 if new configuration is different than
73 * current one.
74 */
75 void (*set_params)(struct ispstat *stat, void *new_conf);
76
77 /* Apply stored configuration. */
78 void (*setup_regs)(struct ispstat *stat, void *priv);
79
80 /* Enable/Disable module. */
81 void (*enable)(struct ispstat *stat, int enable);
82
83 /* Verify is module is busy. */
84 int (*busy)(struct ispstat *stat);
85
86 /* Used for specific operations during generic buf process task. */
87 int (*buf_process)(struct ispstat *stat);
88};
89
90enum ispstat_state_t {
91 ISPSTAT_DISABLED = 0,
92 ISPSTAT_DISABLING,
93 ISPSTAT_ENABLED,
94 ISPSTAT_ENABLING,
95 ISPSTAT_SUSPENDED,
96};
97
98struct ispstat {
99 struct v4l2_subdev subdev;
100 struct media_pad pad; /* sink pad */
101
102 /* Control */
103 unsigned configured:1;
104 unsigned update:1;
105 unsigned buf_processing:1;
106 unsigned sbl_ovl_recover:1;
107 u8 inc_config;
108 atomic_t buf_err;
109 enum ispstat_state_t state; /* enabling/disabling state */
110 struct omap_dma_channel_params dma_config;
111 struct isp_device *isp;
112 void *priv; /* pointer to priv config struct */
113 void *recover_priv; /* pointer to recover priv configuration */
114 struct mutex ioctl_lock; /* serialize private ioctl */
115
116 const struct ispstat_ops *ops;
117
118 /* Buffer */
119 u8 wait_acc_frames;
120 u16 config_counter;
121 u32 frame_number;
122 u32 buf_size;
123 u32 buf_alloc_size;
124 int dma_ch;
125 unsigned long event_type;
126 struct ispstat_buffer *buf;
127 struct ispstat_buffer *active_buf;
128 struct ispstat_buffer *locked_buf;
129};
130
131struct ispstat_generic_config {
132 /*
133 * Fields must be in the same order as in:
134 * - omap3isp_h3a_aewb_config
135 * - omap3isp_h3a_af_config
136 * - omap3isp_hist_config
137 */
138 u32 buf_size;
139 u16 config_counter;
140};
141
142int omap3isp_stat_config(struct ispstat *stat, void *new_conf);
143int omap3isp_stat_request_statistics(struct ispstat *stat,
144 struct omap3isp_stat_data *data);
145int omap3isp_stat_init(struct ispstat *stat, const char *name,
146 const struct v4l2_subdev_ops *sd_ops);
147void omap3isp_stat_cleanup(struct ispstat *stat);
148int omap3isp_stat_subscribe_event(struct v4l2_subdev *subdev,
149 struct v4l2_fh *fh,
150 struct v4l2_event_subscription *sub);
151int omap3isp_stat_unsubscribe_event(struct v4l2_subdev *subdev,
152 struct v4l2_fh *fh,
153 struct v4l2_event_subscription *sub);
154int omap3isp_stat_s_stream(struct v4l2_subdev *subdev, int enable);
155
156int omap3isp_stat_busy(struct ispstat *stat);
157int omap3isp_stat_pcr_busy(struct ispstat *stat);
158void omap3isp_stat_suspend(struct ispstat *stat);
159void omap3isp_stat_resume(struct ispstat *stat);
160int omap3isp_stat_enable(struct ispstat *stat, u8 enable);
161void omap3isp_stat_sbl_overflow(struct ispstat *stat);
162void omap3isp_stat_isr(struct ispstat *stat);
163void omap3isp_stat_isr_frame_sync(struct ispstat *stat);
164void omap3isp_stat_dma_isr(struct ispstat *stat);
165int omap3isp_stat_register_entities(struct ispstat *stat,
166 struct v4l2_device *vdev);
167void omap3isp_stat_unregister_entities(struct ispstat *stat);
168
169#endif /* OMAP3_ISP_STAT_H */
diff --git a/drivers/media/video/omap3isp/ispvideo.c b/drivers/media/video/omap3isp/ispvideo.c
deleted file mode 100644
index 3a5085e90024..000000000000
--- a/drivers/media/video/omap3isp/ispvideo.c
+++ /dev/null
@@ -1,1403 +0,0 @@
1/*
2 * ispvideo.c
3 *
4 * TI OMAP3 ISP - Generic video node
5 *
6 * Copyright (C) 2009-2010 Nokia Corporation
7 *
8 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
9 * Sakari Ailus <sakari.ailus@iki.fi>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23 * 02110-1301 USA
24 */
25
26#include <asm/cacheflush.h>
27#include <linux/clk.h>
28#include <linux/mm.h>
29#include <linux/module.h>
30#include <linux/pagemap.h>
31#include <linux/scatterlist.h>
32#include <linux/sched.h>
33#include <linux/slab.h>
34#include <linux/vmalloc.h>
35#include <media/v4l2-dev.h>
36#include <media/v4l2-ioctl.h>
37#include <plat/iommu.h>
38#include <plat/iovmm.h>
39#include <plat/omap-pm.h>
40
41#include "ispvideo.h"
42#include "isp.h"
43
44
45/* -----------------------------------------------------------------------------
46 * Helper functions
47 */
48
49/*
50 * NOTE: When adding new media bus codes, always remember to add
51 * corresponding in-memory formats to the table below!!!
52 */
53static struct isp_format_info formats[] = {
54 { V4L2_MBUS_FMT_Y8_1X8, V4L2_MBUS_FMT_Y8_1X8,
55 V4L2_MBUS_FMT_Y8_1X8, V4L2_MBUS_FMT_Y8_1X8,
56 V4L2_PIX_FMT_GREY, 8, 1, },
57 { V4L2_MBUS_FMT_Y10_1X10, V4L2_MBUS_FMT_Y10_1X10,
58 V4L2_MBUS_FMT_Y10_1X10, V4L2_MBUS_FMT_Y8_1X8,
59 V4L2_PIX_FMT_Y10, 10, 2, },
60 { V4L2_MBUS_FMT_Y12_1X12, V4L2_MBUS_FMT_Y10_1X10,
61 V4L2_MBUS_FMT_Y12_1X12, V4L2_MBUS_FMT_Y8_1X8,
62 V4L2_PIX_FMT_Y12, 12, 2, },
63 { V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_MBUS_FMT_SBGGR8_1X8,
64 V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_MBUS_FMT_SBGGR8_1X8,
65 V4L2_PIX_FMT_SBGGR8, 8, 1, },
66 { V4L2_MBUS_FMT_SGBRG8_1X8, V4L2_MBUS_FMT_SGBRG8_1X8,
67 V4L2_MBUS_FMT_SGBRG8_1X8, V4L2_MBUS_FMT_SGBRG8_1X8,
68 V4L2_PIX_FMT_SGBRG8, 8, 1, },
69 { V4L2_MBUS_FMT_SGRBG8_1X8, V4L2_MBUS_FMT_SGRBG8_1X8,
70 V4L2_MBUS_FMT_SGRBG8_1X8, V4L2_MBUS_FMT_SGRBG8_1X8,
71 V4L2_PIX_FMT_SGRBG8, 8, 1, },
72 { V4L2_MBUS_FMT_SRGGB8_1X8, V4L2_MBUS_FMT_SRGGB8_1X8,
73 V4L2_MBUS_FMT_SRGGB8_1X8, V4L2_MBUS_FMT_SRGGB8_1X8,
74 V4L2_PIX_FMT_SRGGB8, 8, 1, },
75 { V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8, V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8,
76 V4L2_MBUS_FMT_SBGGR10_1X10, 0,
77 V4L2_PIX_FMT_SBGGR10DPCM8, 8, 1, },
78 { V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8, V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8,
79 V4L2_MBUS_FMT_SGBRG10_1X10, 0,
80 V4L2_PIX_FMT_SGBRG10DPCM8, 8, 1, },
81 { V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8, V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8,
82 V4L2_MBUS_FMT_SGRBG10_1X10, 0,
83 V4L2_PIX_FMT_SGRBG10DPCM8, 8, 1, },
84 { V4L2_MBUS_FMT_SRGGB10_DPCM8_1X8, V4L2_MBUS_FMT_SRGGB10_DPCM8_1X8,
85 V4L2_MBUS_FMT_SRGGB10_1X10, 0,
86 V4L2_PIX_FMT_SRGGB10DPCM8, 8, 1, },
87 { V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_MBUS_FMT_SBGGR10_1X10,
88 V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_MBUS_FMT_SBGGR8_1X8,
89 V4L2_PIX_FMT_SBGGR10, 10, 2, },
90 { V4L2_MBUS_FMT_SGBRG10_1X10, V4L2_MBUS_FMT_SGBRG10_1X10,
91 V4L2_MBUS_FMT_SGBRG10_1X10, V4L2_MBUS_FMT_SGBRG8_1X8,
92 V4L2_PIX_FMT_SGBRG10, 10, 2, },
93 { V4L2_MBUS_FMT_SGRBG10_1X10, V4L2_MBUS_FMT_SGRBG10_1X10,
94 V4L2_MBUS_FMT_SGRBG10_1X10, V4L2_MBUS_FMT_SGRBG8_1X8,
95 V4L2_PIX_FMT_SGRBG10, 10, 2, },
96 { V4L2_MBUS_FMT_SRGGB10_1X10, V4L2_MBUS_FMT_SRGGB10_1X10,
97 V4L2_MBUS_FMT_SRGGB10_1X10, V4L2_MBUS_FMT_SRGGB8_1X8,
98 V4L2_PIX_FMT_SRGGB10, 10, 2, },
99 { V4L2_MBUS_FMT_SBGGR12_1X12, V4L2_MBUS_FMT_SBGGR10_1X10,
100 V4L2_MBUS_FMT_SBGGR12_1X12, V4L2_MBUS_FMT_SBGGR8_1X8,
101 V4L2_PIX_FMT_SBGGR12, 12, 2, },
102 { V4L2_MBUS_FMT_SGBRG12_1X12, V4L2_MBUS_FMT_SGBRG10_1X10,
103 V4L2_MBUS_FMT_SGBRG12_1X12, V4L2_MBUS_FMT_SGBRG8_1X8,
104 V4L2_PIX_FMT_SGBRG12, 12, 2, },
105 { V4L2_MBUS_FMT_SGRBG12_1X12, V4L2_MBUS_FMT_SGRBG10_1X10,
106 V4L2_MBUS_FMT_SGRBG12_1X12, V4L2_MBUS_FMT_SGRBG8_1X8,
107 V4L2_PIX_FMT_SGRBG12, 12, 2, },
108 { V4L2_MBUS_FMT_SRGGB12_1X12, V4L2_MBUS_FMT_SRGGB10_1X10,
109 V4L2_MBUS_FMT_SRGGB12_1X12, V4L2_MBUS_FMT_SRGGB8_1X8,
110 V4L2_PIX_FMT_SRGGB12, 12, 2, },
111 { V4L2_MBUS_FMT_UYVY8_1X16, V4L2_MBUS_FMT_UYVY8_1X16,
112 V4L2_MBUS_FMT_UYVY8_1X16, 0,
113 V4L2_PIX_FMT_UYVY, 16, 2, },
114 { V4L2_MBUS_FMT_YUYV8_1X16, V4L2_MBUS_FMT_YUYV8_1X16,
115 V4L2_MBUS_FMT_YUYV8_1X16, 0,
116 V4L2_PIX_FMT_YUYV, 16, 2, },
117 { V4L2_MBUS_FMT_UYVY8_2X8, V4L2_MBUS_FMT_UYVY8_2X8,
118 V4L2_MBUS_FMT_UYVY8_2X8, 0,
119 V4L2_PIX_FMT_UYVY, 8, 2, },
120 { V4L2_MBUS_FMT_YUYV8_2X8, V4L2_MBUS_FMT_YUYV8_2X8,
121 V4L2_MBUS_FMT_YUYV8_2X8, 0,
122 V4L2_PIX_FMT_YUYV, 8, 2, },
123 /* Empty entry to catch the unsupported pixel code (0) used by the CCDC
124 * module and avoid NULL pointer dereferences.
125 */
126 { 0, }
127};
128
129const struct isp_format_info *
130omap3isp_video_format_info(enum v4l2_mbus_pixelcode code)
131{
132 unsigned int i;
133
134 for (i = 0; i < ARRAY_SIZE(formats); ++i) {
135 if (formats[i].code == code)
136 return &formats[i];
137 }
138
139 return NULL;
140}
141
142/*
143 * isp_video_mbus_to_pix - Convert v4l2_mbus_framefmt to v4l2_pix_format
144 * @video: ISP video instance
145 * @mbus: v4l2_mbus_framefmt format (input)
146 * @pix: v4l2_pix_format format (output)
147 *
148 * Fill the output pix structure with information from the input mbus format.
149 * The bytesperline and sizeimage fields are computed from the requested bytes
150 * per line value in the pix format and information from the video instance.
151 *
152 * Return the number of padding bytes at end of line.
153 */
154static unsigned int isp_video_mbus_to_pix(const struct isp_video *video,
155 const struct v4l2_mbus_framefmt *mbus,
156 struct v4l2_pix_format *pix)
157{
158 unsigned int bpl = pix->bytesperline;
159 unsigned int min_bpl;
160 unsigned int i;
161
162 memset(pix, 0, sizeof(*pix));
163 pix->width = mbus->width;
164 pix->height = mbus->height;
165
166 for (i = 0; i < ARRAY_SIZE(formats); ++i) {
167 if (formats[i].code == mbus->code)
168 break;
169 }
170
171 if (WARN_ON(i == ARRAY_SIZE(formats)))
172 return 0;
173
174 min_bpl = pix->width * formats[i].bpp;
175
176 /* Clamp the requested bytes per line value. If the maximum bytes per
177 * line value is zero, the module doesn't support user configurable line
178 * sizes. Override the requested value with the minimum in that case.
179 */
180 if (video->bpl_max)
181 bpl = clamp(bpl, min_bpl, video->bpl_max);
182 else
183 bpl = min_bpl;
184
185 if (!video->bpl_zero_padding || bpl != min_bpl)
186 bpl = ALIGN(bpl, video->bpl_alignment);
187
188 pix->pixelformat = formats[i].pixelformat;
189 pix->bytesperline = bpl;
190 pix->sizeimage = pix->bytesperline * pix->height;
191 pix->colorspace = mbus->colorspace;
192 pix->field = mbus->field;
193
194 return bpl - min_bpl;
195}
196
197static void isp_video_pix_to_mbus(const struct v4l2_pix_format *pix,
198 struct v4l2_mbus_framefmt *mbus)
199{
200 unsigned int i;
201
202 memset(mbus, 0, sizeof(*mbus));
203 mbus->width = pix->width;
204 mbus->height = pix->height;
205
206 /* Skip the last format in the loop so that it will be selected if no
207 * match is found.
208 */
209 for (i = 0; i < ARRAY_SIZE(formats) - 1; ++i) {
210 if (formats[i].pixelformat == pix->pixelformat)
211 break;
212 }
213
214 mbus->code = formats[i].code;
215 mbus->colorspace = pix->colorspace;
216 mbus->field = pix->field;
217}
218
219static struct v4l2_subdev *
220isp_video_remote_subdev(struct isp_video *video, u32 *pad)
221{
222 struct media_pad *remote;
223
224 remote = media_entity_remote_source(&video->pad);
225
226 if (remote == NULL ||
227 media_entity_type(remote->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
228 return NULL;
229
230 if (pad)
231 *pad = remote->index;
232
233 return media_entity_to_v4l2_subdev(remote->entity);
234}
235
236/* Return a pointer to the ISP video instance at the far end of the pipeline. */
237static int isp_video_get_graph_data(struct isp_video *video,
238 struct isp_pipeline *pipe)
239{
240 struct media_entity_graph graph;
241 struct media_entity *entity = &video->video.entity;
242 struct media_device *mdev = entity->parent;
243 struct isp_video *far_end = NULL;
244
245 mutex_lock(&mdev->graph_mutex);
246 media_entity_graph_walk_start(&graph, entity);
247
248 while ((entity = media_entity_graph_walk_next(&graph))) {
249 struct isp_video *__video;
250
251 pipe->entities |= 1 << entity->id;
252
253 if (far_end != NULL)
254 continue;
255
256 if (entity == &video->video.entity)
257 continue;
258
259 if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE)
260 continue;
261
262 __video = to_isp_video(media_entity_to_video_device(entity));
263 if (__video->type != video->type)
264 far_end = __video;
265 }
266
267 mutex_unlock(&mdev->graph_mutex);
268
269 if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
270 pipe->input = far_end;
271 pipe->output = video;
272 } else {
273 if (far_end == NULL)
274 return -EPIPE;
275
276 pipe->input = video;
277 pipe->output = far_end;
278 }
279
280 return 0;
281}
282
283/*
284 * Validate a pipeline by checking both ends of all links for format
285 * discrepancies.
286 *
287 * Compute the minimum time per frame value as the maximum of time per frame
288 * limits reported by every block in the pipeline.
289 *
290 * Return 0 if all formats match, or -EPIPE if at least one link is found with
291 * different formats on its two ends or if the pipeline doesn't start with a
292 * video source (either a subdev with no input pad, or a non-subdev entity).
293 */
294static int isp_video_validate_pipeline(struct isp_pipeline *pipe)
295{
296 struct isp_device *isp = pipe->output->isp;
297 struct media_pad *pad;
298 struct v4l2_subdev *subdev;
299
300 subdev = isp_video_remote_subdev(pipe->output, NULL);
301 if (subdev == NULL)
302 return -EPIPE;
303
304 while (1) {
305 /* Retrieve the sink format */
306 pad = &subdev->entity.pads[0];
307 if (!(pad->flags & MEDIA_PAD_FL_SINK))
308 break;
309
310 /* Update the maximum frame rate */
311 if (subdev == &isp->isp_res.subdev)
312 omap3isp_resizer_max_rate(&isp->isp_res,
313 &pipe->max_rate);
314
315 /* Retrieve the source format. Return an error if no source
316 * entity can be found, and stop checking the pipeline if the
317 * source entity isn't a subdev.
318 */
319 pad = media_entity_remote_source(pad);
320 if (pad == NULL)
321 return -EPIPE;
322
323 if (media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
324 break;
325
326 subdev = media_entity_to_v4l2_subdev(pad->entity);
327 }
328
329 return 0;
330}
331
332static int
333__isp_video_get_format(struct isp_video *video, struct v4l2_format *format)
334{
335 struct v4l2_subdev_format fmt;
336 struct v4l2_subdev *subdev;
337 u32 pad;
338 int ret;
339
340 subdev = isp_video_remote_subdev(video, &pad);
341 if (subdev == NULL)
342 return -EINVAL;
343
344 mutex_lock(&video->mutex);
345
346 fmt.pad = pad;
347 fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
348 ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &fmt);
349 if (ret == -ENOIOCTLCMD)
350 ret = -EINVAL;
351
352 mutex_unlock(&video->mutex);
353
354 if (ret)
355 return ret;
356
357 format->type = video->type;
358 return isp_video_mbus_to_pix(video, &fmt.format, &format->fmt.pix);
359}
360
361static int
362isp_video_check_format(struct isp_video *video, struct isp_video_fh *vfh)
363{
364 struct v4l2_format format;
365 int ret;
366
367 memcpy(&format, &vfh->format, sizeof(format));
368 ret = __isp_video_get_format(video, &format);
369 if (ret < 0)
370 return ret;
371
372 if (vfh->format.fmt.pix.pixelformat != format.fmt.pix.pixelformat ||
373 vfh->format.fmt.pix.height != format.fmt.pix.height ||
374 vfh->format.fmt.pix.width != format.fmt.pix.width ||
375 vfh->format.fmt.pix.bytesperline != format.fmt.pix.bytesperline ||
376 vfh->format.fmt.pix.sizeimage != format.fmt.pix.sizeimage)
377 return -EINVAL;
378
379 return ret;
380}
381
382/* -----------------------------------------------------------------------------
383 * IOMMU management
384 */
385
386#define IOMMU_FLAG (IOVMF_ENDIAN_LITTLE | IOVMF_ELSZ_8)
387
388/*
389 * ispmmu_vmap - Wrapper for Virtual memory mapping of a scatter gather list
390 * @dev: Device pointer specific to the OMAP3 ISP.
391 * @sglist: Pointer to source Scatter gather list to allocate.
392 * @sglen: Number of elements of the scatter-gatter list.
393 *
394 * Returns a resulting mapped device address by the ISP MMU, or -ENOMEM if
395 * we ran out of memory.
396 */
397static dma_addr_t
398ispmmu_vmap(struct isp_device *isp, const struct scatterlist *sglist, int sglen)
399{
400 struct sg_table *sgt;
401 u32 da;
402
403 sgt = kmalloc(sizeof(*sgt), GFP_KERNEL);
404 if (sgt == NULL)
405 return -ENOMEM;
406
407 sgt->sgl = (struct scatterlist *)sglist;
408 sgt->nents = sglen;
409 sgt->orig_nents = sglen;
410
411 da = omap_iommu_vmap(isp->domain, isp->dev, 0, sgt, IOMMU_FLAG);
412 if (IS_ERR_VALUE(da))
413 kfree(sgt);
414
415 return da;
416}
417
418/*
419 * ispmmu_vunmap - Unmap a device address from the ISP MMU
420 * @dev: Device pointer specific to the OMAP3 ISP.
421 * @da: Device address generated from a ispmmu_vmap call.
422 */
423static void ispmmu_vunmap(struct isp_device *isp, dma_addr_t da)
424{
425 struct sg_table *sgt;
426
427 sgt = omap_iommu_vunmap(isp->domain, isp->dev, (u32)da);
428 kfree(sgt);
429}
430
431/* -----------------------------------------------------------------------------
432 * Video queue operations
433 */
434
435static void isp_video_queue_prepare(struct isp_video_queue *queue,
436 unsigned int *nbuffers, unsigned int *size)
437{
438 struct isp_video_fh *vfh =
439 container_of(queue, struct isp_video_fh, queue);
440 struct isp_video *video = vfh->video;
441
442 *size = vfh->format.fmt.pix.sizeimage;
443 if (*size == 0)
444 return;
445
446 *nbuffers = min(*nbuffers, video->capture_mem / PAGE_ALIGN(*size));
447}
448
449static void isp_video_buffer_cleanup(struct isp_video_buffer *buf)
450{
451 struct isp_video_fh *vfh = isp_video_queue_to_isp_video_fh(buf->queue);
452 struct isp_buffer *buffer = to_isp_buffer(buf);
453 struct isp_video *video = vfh->video;
454
455 if (buffer->isp_addr) {
456 ispmmu_vunmap(video->isp, buffer->isp_addr);
457 buffer->isp_addr = 0;
458 }
459}
460
461static int isp_video_buffer_prepare(struct isp_video_buffer *buf)
462{
463 struct isp_video_fh *vfh = isp_video_queue_to_isp_video_fh(buf->queue);
464 struct isp_buffer *buffer = to_isp_buffer(buf);
465 struct isp_video *video = vfh->video;
466 unsigned long addr;
467
468 addr = ispmmu_vmap(video->isp, buf->sglist, buf->sglen);
469 if (IS_ERR_VALUE(addr))
470 return -EIO;
471
472 if (!IS_ALIGNED(addr, 32)) {
473 dev_dbg(video->isp->dev, "Buffer address must be "
474 "aligned to 32 bytes boundary.\n");
475 ispmmu_vunmap(video->isp, buffer->isp_addr);
476 return -EINVAL;
477 }
478
479 buf->vbuf.bytesused = vfh->format.fmt.pix.sizeimage;
480 buffer->isp_addr = addr;
481 return 0;
482}
483
484/*
485 * isp_video_buffer_queue - Add buffer to streaming queue
486 * @buf: Video buffer
487 *
488 * In memory-to-memory mode, start streaming on the pipeline if buffers are
489 * queued on both the input and the output, if the pipeline isn't already busy.
490 * If the pipeline is busy, it will be restarted in the output module interrupt
491 * handler.
492 */
493static void isp_video_buffer_queue(struct isp_video_buffer *buf)
494{
495 struct isp_video_fh *vfh = isp_video_queue_to_isp_video_fh(buf->queue);
496 struct isp_buffer *buffer = to_isp_buffer(buf);
497 struct isp_video *video = vfh->video;
498 struct isp_pipeline *pipe = to_isp_pipeline(&video->video.entity);
499 enum isp_pipeline_state state;
500 unsigned long flags;
501 unsigned int empty;
502 unsigned int start;
503
504 empty = list_empty(&video->dmaqueue);
505 list_add_tail(&buffer->buffer.irqlist, &video->dmaqueue);
506
507 if (empty) {
508 if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
509 state = ISP_PIPELINE_QUEUE_OUTPUT;
510 else
511 state = ISP_PIPELINE_QUEUE_INPUT;
512
513 spin_lock_irqsave(&pipe->lock, flags);
514 pipe->state |= state;
515 video->ops->queue(video, buffer);
516 video->dmaqueue_flags |= ISP_VIDEO_DMAQUEUE_QUEUED;
517
518 start = isp_pipeline_ready(pipe);
519 if (start)
520 pipe->state |= ISP_PIPELINE_STREAM;
521 spin_unlock_irqrestore(&pipe->lock, flags);
522
523 if (start)
524 omap3isp_pipeline_set_stream(pipe,
525 ISP_PIPELINE_STREAM_SINGLESHOT);
526 }
527}
528
529static const struct isp_video_queue_operations isp_video_queue_ops = {
530 .queue_prepare = &isp_video_queue_prepare,
531 .buffer_prepare = &isp_video_buffer_prepare,
532 .buffer_queue = &isp_video_buffer_queue,
533 .buffer_cleanup = &isp_video_buffer_cleanup,
534};
535
536/*
537 * omap3isp_video_buffer_next - Complete the current buffer and return the next
538 * @video: ISP video object
539 *
540 * Remove the current video buffer from the DMA queue and fill its timestamp,
541 * field count and state fields before waking up its completion handler.
542 *
543 * For capture video nodes the buffer state is set to ISP_BUF_STATE_DONE if no
544 * error has been flagged in the pipeline, or to ISP_BUF_STATE_ERROR otherwise.
545 * For video output nodes the buffer state is always set to ISP_BUF_STATE_DONE.
546 *
547 * The DMA queue is expected to contain at least one buffer.
548 *
549 * Return a pointer to the next buffer in the DMA queue, or NULL if the queue is
550 * empty.
551 */
552struct isp_buffer *omap3isp_video_buffer_next(struct isp_video *video)
553{
554 struct isp_pipeline *pipe = to_isp_pipeline(&video->video.entity);
555 struct isp_video_queue *queue = video->queue;
556 enum isp_pipeline_state state;
557 struct isp_video_buffer *buf;
558 unsigned long flags;
559 struct timespec ts;
560
561 spin_lock_irqsave(&queue->irqlock, flags);
562 if (WARN_ON(list_empty(&video->dmaqueue))) {
563 spin_unlock_irqrestore(&queue->irqlock, flags);
564 return NULL;
565 }
566
567 buf = list_first_entry(&video->dmaqueue, struct isp_video_buffer,
568 irqlist);
569 list_del(&buf->irqlist);
570 spin_unlock_irqrestore(&queue->irqlock, flags);
571
572 ktime_get_ts(&ts);
573 buf->vbuf.timestamp.tv_sec = ts.tv_sec;
574 buf->vbuf.timestamp.tv_usec = ts.tv_nsec / NSEC_PER_USEC;
575
576 /* Do frame number propagation only if this is the output video node.
577 * Frame number either comes from the CSI receivers or it gets
578 * incremented here if H3A is not active.
579 * Note: There is no guarantee that the output buffer will finish
580 * first, so the input number might lag behind by 1 in some cases.
581 */
582 if (video == pipe->output && !pipe->do_propagation)
583 buf->vbuf.sequence = atomic_inc_return(&pipe->frame_number);
584 else
585 buf->vbuf.sequence = atomic_read(&pipe->frame_number);
586
587 /* Report pipeline errors to userspace on the capture device side. */
588 if (queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && pipe->error) {
589 buf->state = ISP_BUF_STATE_ERROR;
590 pipe->error = false;
591 } else {
592 buf->state = ISP_BUF_STATE_DONE;
593 }
594
595 wake_up(&buf->wait);
596
597 if (list_empty(&video->dmaqueue)) {
598 if (queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
599 state = ISP_PIPELINE_QUEUE_OUTPUT
600 | ISP_PIPELINE_STREAM;
601 else
602 state = ISP_PIPELINE_QUEUE_INPUT
603 | ISP_PIPELINE_STREAM;
604
605 spin_lock_irqsave(&pipe->lock, flags);
606 pipe->state &= ~state;
607 if (video->pipe.stream_state == ISP_PIPELINE_STREAM_CONTINUOUS)
608 video->dmaqueue_flags |= ISP_VIDEO_DMAQUEUE_UNDERRUN;
609 spin_unlock_irqrestore(&pipe->lock, flags);
610 return NULL;
611 }
612
613 if (queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && pipe->input != NULL) {
614 spin_lock_irqsave(&pipe->lock, flags);
615 pipe->state &= ~ISP_PIPELINE_STREAM;
616 spin_unlock_irqrestore(&pipe->lock, flags);
617 }
618
619 buf = list_first_entry(&video->dmaqueue, struct isp_video_buffer,
620 irqlist);
621 buf->state = ISP_BUF_STATE_ACTIVE;
622 return to_isp_buffer(buf);
623}
624
625/*
626 * omap3isp_video_resume - Perform resume operation on the buffers
627 * @video: ISP video object
628 * @continuous: Pipeline is in single shot mode if 0 or continuous mode otherwise
629 *
630 * This function is intended to be used on suspend/resume scenario. It
631 * requests video queue layer to discard buffers marked as DONE if it's in
632 * continuous mode and requests ISP modules to queue again the ACTIVE buffer
633 * if there's any.
634 */
635void omap3isp_video_resume(struct isp_video *video, int continuous)
636{
637 struct isp_buffer *buf = NULL;
638
639 if (continuous && video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
640 omap3isp_video_queue_discard_done(video->queue);
641
642 if (!list_empty(&video->dmaqueue)) {
643 buf = list_first_entry(&video->dmaqueue,
644 struct isp_buffer, buffer.irqlist);
645 video->ops->queue(video, buf);
646 video->dmaqueue_flags |= ISP_VIDEO_DMAQUEUE_QUEUED;
647 } else {
648 if (continuous)
649 video->dmaqueue_flags |= ISP_VIDEO_DMAQUEUE_UNDERRUN;
650 }
651}
652
653/* -----------------------------------------------------------------------------
654 * V4L2 ioctls
655 */
656
657static int
658isp_video_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
659{
660 struct isp_video *video = video_drvdata(file);
661
662 strlcpy(cap->driver, ISP_VIDEO_DRIVER_NAME, sizeof(cap->driver));
663 strlcpy(cap->card, video->video.name, sizeof(cap->card));
664 strlcpy(cap->bus_info, "media", sizeof(cap->bus_info));
665
666 if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
667 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
668 else
669 cap->capabilities = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
670
671 return 0;
672}
673
674static int
675isp_video_get_format(struct file *file, void *fh, struct v4l2_format *format)
676{
677 struct isp_video_fh *vfh = to_isp_video_fh(fh);
678 struct isp_video *video = video_drvdata(file);
679
680 if (format->type != video->type)
681 return -EINVAL;
682
683 mutex_lock(&video->mutex);
684 *format = vfh->format;
685 mutex_unlock(&video->mutex);
686
687 return 0;
688}
689
690static int
691isp_video_set_format(struct file *file, void *fh, struct v4l2_format *format)
692{
693 struct isp_video_fh *vfh = to_isp_video_fh(fh);
694 struct isp_video *video = video_drvdata(file);
695 struct v4l2_mbus_framefmt fmt;
696
697 if (format->type != video->type)
698 return -EINVAL;
699
700 mutex_lock(&video->mutex);
701
702 /* Fill the bytesperline and sizeimage fields by converting to media bus
703 * format and back to pixel format.
704 */
705 isp_video_pix_to_mbus(&format->fmt.pix, &fmt);
706 isp_video_mbus_to_pix(video, &fmt, &format->fmt.pix);
707
708 vfh->format = *format;
709
710 mutex_unlock(&video->mutex);
711 return 0;
712}
713
714static int
715isp_video_try_format(struct file *file, void *fh, struct v4l2_format *format)
716{
717 struct isp_video *video = video_drvdata(file);
718 struct v4l2_subdev_format fmt;
719 struct v4l2_subdev *subdev;
720 u32 pad;
721 int ret;
722
723 if (format->type != video->type)
724 return -EINVAL;
725
726 subdev = isp_video_remote_subdev(video, &pad);
727 if (subdev == NULL)
728 return -EINVAL;
729
730 isp_video_pix_to_mbus(&format->fmt.pix, &fmt.format);
731
732 fmt.pad = pad;
733 fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
734 ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &fmt);
735 if (ret)
736 return ret == -ENOIOCTLCMD ? -EINVAL : ret;
737
738 isp_video_mbus_to_pix(video, &fmt.format, &format->fmt.pix);
739 return 0;
740}
741
742static int
743isp_video_cropcap(struct file *file, void *fh, struct v4l2_cropcap *cropcap)
744{
745 struct isp_video *video = video_drvdata(file);
746 struct v4l2_subdev *subdev;
747 int ret;
748
749 subdev = isp_video_remote_subdev(video, NULL);
750 if (subdev == NULL)
751 return -EINVAL;
752
753 mutex_lock(&video->mutex);
754 ret = v4l2_subdev_call(subdev, video, cropcap, cropcap);
755 mutex_unlock(&video->mutex);
756
757 return ret == -ENOIOCTLCMD ? -EINVAL : ret;
758}
759
760static int
761isp_video_get_crop(struct file *file, void *fh, struct v4l2_crop *crop)
762{
763 struct isp_video *video = video_drvdata(file);
764 struct v4l2_subdev_format format;
765 struct v4l2_subdev *subdev;
766 u32 pad;
767 int ret;
768
769 subdev = isp_video_remote_subdev(video, &pad);
770 if (subdev == NULL)
771 return -EINVAL;
772
773 /* Try the get crop operation first and fallback to get format if not
774 * implemented.
775 */
776 ret = v4l2_subdev_call(subdev, video, g_crop, crop);
777 if (ret != -ENOIOCTLCMD)
778 return ret;
779
780 format.pad = pad;
781 format.which = V4L2_SUBDEV_FORMAT_ACTIVE;
782 ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &format);
783 if (ret < 0)
784 return ret == -ENOIOCTLCMD ? -EINVAL : ret;
785
786 crop->c.left = 0;
787 crop->c.top = 0;
788 crop->c.width = format.format.width;
789 crop->c.height = format.format.height;
790
791 return 0;
792}
793
794static int
795isp_video_set_crop(struct file *file, void *fh, struct v4l2_crop *crop)
796{
797 struct isp_video *video = video_drvdata(file);
798 struct v4l2_subdev *subdev;
799 int ret;
800
801 subdev = isp_video_remote_subdev(video, NULL);
802 if (subdev == NULL)
803 return -EINVAL;
804
805 mutex_lock(&video->mutex);
806 ret = v4l2_subdev_call(subdev, video, s_crop, crop);
807 mutex_unlock(&video->mutex);
808
809 return ret == -ENOIOCTLCMD ? -EINVAL : ret;
810}
811
812static int
813isp_video_get_param(struct file *file, void *fh, struct v4l2_streamparm *a)
814{
815 struct isp_video_fh *vfh = to_isp_video_fh(fh);
816 struct isp_video *video = video_drvdata(file);
817
818 if (video->type != V4L2_BUF_TYPE_VIDEO_OUTPUT ||
819 video->type != a->type)
820 return -EINVAL;
821
822 memset(a, 0, sizeof(*a));
823 a->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
824 a->parm.output.capability = V4L2_CAP_TIMEPERFRAME;
825 a->parm.output.timeperframe = vfh->timeperframe;
826
827 return 0;
828}
829
830static int
831isp_video_set_param(struct file *file, void *fh, struct v4l2_streamparm *a)
832{
833 struct isp_video_fh *vfh = to_isp_video_fh(fh);
834 struct isp_video *video = video_drvdata(file);
835
836 if (video->type != V4L2_BUF_TYPE_VIDEO_OUTPUT ||
837 video->type != a->type)
838 return -EINVAL;
839
840 if (a->parm.output.timeperframe.denominator == 0)
841 a->parm.output.timeperframe.denominator = 1;
842
843 vfh->timeperframe = a->parm.output.timeperframe;
844
845 return 0;
846}
847
848static int
849isp_video_reqbufs(struct file *file, void *fh, struct v4l2_requestbuffers *rb)
850{
851 struct isp_video_fh *vfh = to_isp_video_fh(fh);
852
853 return omap3isp_video_queue_reqbufs(&vfh->queue, rb);
854}
855
856static int
857isp_video_querybuf(struct file *file, void *fh, struct v4l2_buffer *b)
858{
859 struct isp_video_fh *vfh = to_isp_video_fh(fh);
860
861 return omap3isp_video_queue_querybuf(&vfh->queue, b);
862}
863
864static int
865isp_video_qbuf(struct file *file, void *fh, struct v4l2_buffer *b)
866{
867 struct isp_video_fh *vfh = to_isp_video_fh(fh);
868
869 return omap3isp_video_queue_qbuf(&vfh->queue, b);
870}
871
872static int
873isp_video_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b)
874{
875 struct isp_video_fh *vfh = to_isp_video_fh(fh);
876
877 return omap3isp_video_queue_dqbuf(&vfh->queue, b,
878 file->f_flags & O_NONBLOCK);
879}
880
881static int isp_video_check_external_subdevs(struct isp_video *video,
882 struct isp_pipeline *pipe)
883{
884 struct isp_device *isp = video->isp;
885 struct media_entity *ents[] = {
886 &isp->isp_csi2a.subdev.entity,
887 &isp->isp_csi2c.subdev.entity,
888 &isp->isp_ccp2.subdev.entity,
889 &isp->isp_ccdc.subdev.entity
890 };
891 struct media_pad *source_pad;
892 struct media_entity *source = NULL;
893 struct media_entity *sink;
894 struct v4l2_subdev_format fmt;
895 struct v4l2_ext_controls ctrls;
896 struct v4l2_ext_control ctrl;
897 unsigned int i;
898 int ret = 0;
899
900 for (i = 0; i < ARRAY_SIZE(ents); i++) {
901 /* Is the entity part of the pipeline? */
902 if (!(pipe->entities & (1 << ents[i]->id)))
903 continue;
904
905 /* ISP entities have always sink pad == 0. Find source. */
906 source_pad = media_entity_remote_source(&ents[i]->pads[0]);
907 if (source_pad == NULL)
908 continue;
909
910 source = source_pad->entity;
911 sink = ents[i];
912 break;
913 }
914
915 if (!source) {
916 dev_warn(isp->dev, "can't find source, failing now\n");
917 return ret;
918 }
919
920 if (media_entity_type(source) != MEDIA_ENT_T_V4L2_SUBDEV)
921 return 0;
922
923 pipe->external = media_entity_to_v4l2_subdev(source);
924
925 fmt.pad = source_pad->index;
926 fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
927 ret = v4l2_subdev_call(media_entity_to_v4l2_subdev(sink),
928 pad, get_fmt, NULL, &fmt);
929 if (unlikely(ret < 0)) {
930 dev_warn(isp->dev, "get_fmt returned null!\n");
931 return ret;
932 }
933
934 pipe->external_width =
935 omap3isp_video_format_info(fmt.format.code)->width;
936
937 memset(&ctrls, 0, sizeof(ctrls));
938 memset(&ctrl, 0, sizeof(ctrl));
939
940 ctrl.id = V4L2_CID_PIXEL_RATE;
941
942 ctrls.count = 1;
943 ctrls.controls = &ctrl;
944
945 ret = v4l2_g_ext_ctrls(pipe->external->ctrl_handler, &ctrls);
946 if (ret < 0) {
947 dev_warn(isp->dev, "no pixel rate control in subdev %s\n",
948 pipe->external->name);
949 return ret;
950 }
951
952 pipe->external_rate = ctrl.value64;
953
954 if (pipe->entities & (1 << isp->isp_ccdc.subdev.entity.id)) {
955 unsigned int rate = UINT_MAX;
956 /*
957 * Check that maximum allowed CCDC pixel rate isn't
958 * exceeded by the pixel rate.
959 */
960 omap3isp_ccdc_max_rate(&isp->isp_ccdc, &rate);
961 if (pipe->external_rate > rate)
962 return -ENOSPC;
963 }
964
965 return 0;
966}
967
968/*
969 * Stream management
970 *
971 * Every ISP pipeline has a single input and a single output. The input can be
972 * either a sensor or a video node. The output is always a video node.
973 *
974 * As every pipeline has an output video node, the ISP video objects at the
975 * pipeline output stores the pipeline state. It tracks the streaming state of
976 * both the input and output, as well as the availability of buffers.
977 *
978 * In sensor-to-memory mode, frames are always available at the pipeline input.
979 * Starting the sensor usually requires I2C transfers and must be done in
980 * interruptible context. The pipeline is started and stopped synchronously
981 * to the stream on/off commands. All modules in the pipeline will get their
982 * subdev set stream handler called. The module at the end of the pipeline must
983 * delay starting the hardware until buffers are available at its output.
984 *
985 * In memory-to-memory mode, starting/stopping the stream requires
986 * synchronization between the input and output. ISP modules can't be stopped
987 * in the middle of a frame, and at least some of the modules seem to become
988 * busy as soon as they're started, even if they don't receive a frame start
989 * event. For that reason frames need to be processed in single-shot mode. The
990 * driver needs to wait until a frame is completely processed and written to
991 * memory before restarting the pipeline for the next frame. Pipelined
992 * processing might be possible but requires more testing.
993 *
994 * Stream start must be delayed until buffers are available at both the input
995 * and output. The pipeline must be started in the videobuf queue callback with
996 * the buffers queue spinlock held. The modules subdev set stream operation must
997 * not sleep.
998 */
999static int
1000isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
1001{
1002 struct isp_video_fh *vfh = to_isp_video_fh(fh);
1003 struct isp_video *video = video_drvdata(file);
1004 enum isp_pipeline_state state;
1005 struct isp_pipeline *pipe;
1006 unsigned long flags;
1007 int ret;
1008
1009 if (type != video->type)
1010 return -EINVAL;
1011
1012 mutex_lock(&video->stream_lock);
1013
1014 if (video->streaming) {
1015 mutex_unlock(&video->stream_lock);
1016 return -EBUSY;
1017 }
1018
1019 /* Start streaming on the pipeline. No link touching an entity in the
1020 * pipeline can be activated or deactivated once streaming is started.
1021 */
1022 pipe = video->video.entity.pipe
1023 ? to_isp_pipeline(&video->video.entity) : &video->pipe;
1024
1025 pipe->entities = 0;
1026
1027 if (video->isp->pdata->set_constraints)
1028 video->isp->pdata->set_constraints(video->isp, true);
1029 pipe->l3_ick = clk_get_rate(video->isp->clock[ISP_CLK_L3_ICK]);
1030 pipe->max_rate = pipe->l3_ick;
1031
1032 ret = media_entity_pipeline_start(&video->video.entity, &pipe->pipe);
1033 if (ret < 0)
1034 goto err_pipeline_start;
1035
1036 /* Verify that the currently configured format matches the output of
1037 * the connected subdev.
1038 */
1039 ret = isp_video_check_format(video, vfh);
1040 if (ret < 0)
1041 goto err_check_format;
1042
1043 video->bpl_padding = ret;
1044 video->bpl_value = vfh->format.fmt.pix.bytesperline;
1045
1046 ret = isp_video_get_graph_data(video, pipe);
1047 if (ret < 0)
1048 goto err_check_format;
1049
1050 if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1051 state = ISP_PIPELINE_STREAM_OUTPUT | ISP_PIPELINE_IDLE_OUTPUT;
1052 else
1053 state = ISP_PIPELINE_STREAM_INPUT | ISP_PIPELINE_IDLE_INPUT;
1054
1055 ret = isp_video_check_external_subdevs(video, pipe);
1056 if (ret < 0)
1057 goto err_check_format;
1058
1059 /* Validate the pipeline and update its state. */
1060 ret = isp_video_validate_pipeline(pipe);
1061 if (ret < 0)
1062 goto err_check_format;
1063
1064 pipe->error = false;
1065
1066 spin_lock_irqsave(&pipe->lock, flags);
1067 pipe->state &= ~ISP_PIPELINE_STREAM;
1068 pipe->state |= state;
1069 spin_unlock_irqrestore(&pipe->lock, flags);
1070
1071 /* Set the maximum time per frame as the value requested by userspace.
1072 * This is a soft limit that can be overridden if the hardware doesn't
1073 * support the request limit.
1074 */
1075 if (video->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
1076 pipe->max_timeperframe = vfh->timeperframe;
1077
1078 video->queue = &vfh->queue;
1079 INIT_LIST_HEAD(&video->dmaqueue);
1080 atomic_set(&pipe->frame_number, -1);
1081
1082 ret = omap3isp_video_queue_streamon(&vfh->queue);
1083 if (ret < 0)
1084 goto err_check_format;
1085
1086 /* In sensor-to-memory mode, the stream can be started synchronously
1087 * to the stream on command. In memory-to-memory mode, it will be
1088 * started when buffers are queued on both the input and output.
1089 */
1090 if (pipe->input == NULL) {
1091 ret = omap3isp_pipeline_set_stream(pipe,
1092 ISP_PIPELINE_STREAM_CONTINUOUS);
1093 if (ret < 0)
1094 goto err_set_stream;
1095 spin_lock_irqsave(&video->queue->irqlock, flags);
1096 if (list_empty(&video->dmaqueue))
1097 video->dmaqueue_flags |= ISP_VIDEO_DMAQUEUE_UNDERRUN;
1098 spin_unlock_irqrestore(&video->queue->irqlock, flags);
1099 }
1100
1101 video->streaming = 1;
1102
1103 mutex_unlock(&video->stream_lock);
1104 return 0;
1105
1106err_set_stream:
1107 omap3isp_video_queue_streamoff(&vfh->queue);
1108err_check_format:
1109 media_entity_pipeline_stop(&video->video.entity);
1110err_pipeline_start:
1111 if (video->isp->pdata->set_constraints)
1112 video->isp->pdata->set_constraints(video->isp, false);
1113 /* The DMA queue must be emptied here, otherwise CCDC interrupts that
1114 * will get triggered the next time the CCDC is powered up will try to
1115 * access buffers that might have been freed but still present in the
1116 * DMA queue. This can easily get triggered if the above
1117 * omap3isp_pipeline_set_stream() call fails on a system with a
1118 * free-running sensor.
1119 */
1120 INIT_LIST_HEAD(&video->dmaqueue);
1121 video->queue = NULL;
1122
1123 mutex_unlock(&video->stream_lock);
1124 return ret;
1125}
1126
1127static int
1128isp_video_streamoff(struct file *file, void *fh, enum v4l2_buf_type type)
1129{
1130 struct isp_video_fh *vfh = to_isp_video_fh(fh);
1131 struct isp_video *video = video_drvdata(file);
1132 struct isp_pipeline *pipe = to_isp_pipeline(&video->video.entity);
1133 enum isp_pipeline_state state;
1134 unsigned int streaming;
1135 unsigned long flags;
1136
1137 if (type != video->type)
1138 return -EINVAL;
1139
1140 mutex_lock(&video->stream_lock);
1141
1142 /* Make sure we're not streaming yet. */
1143 mutex_lock(&vfh->queue.lock);
1144 streaming = vfh->queue.streaming;
1145 mutex_unlock(&vfh->queue.lock);
1146
1147 if (!streaming)
1148 goto done;
1149
1150 /* Update the pipeline state. */
1151 if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1152 state = ISP_PIPELINE_STREAM_OUTPUT
1153 | ISP_PIPELINE_QUEUE_OUTPUT;
1154 else
1155 state = ISP_PIPELINE_STREAM_INPUT
1156 | ISP_PIPELINE_QUEUE_INPUT;
1157
1158 spin_lock_irqsave(&pipe->lock, flags);
1159 pipe->state &= ~state;
1160 spin_unlock_irqrestore(&pipe->lock, flags);
1161
1162 /* Stop the stream. */
1163 omap3isp_pipeline_set_stream(pipe, ISP_PIPELINE_STREAM_STOPPED);
1164 omap3isp_video_queue_streamoff(&vfh->queue);
1165 video->queue = NULL;
1166 video->streaming = 0;
1167
1168 if (video->isp->pdata->set_constraints)
1169 video->isp->pdata->set_constraints(video->isp, false);
1170 media_entity_pipeline_stop(&video->video.entity);
1171
1172done:
1173 mutex_unlock(&video->stream_lock);
1174 return 0;
1175}
1176
1177static int
1178isp_video_enum_input(struct file *file, void *fh, struct v4l2_input *input)
1179{
1180 if (input->index > 0)
1181 return -EINVAL;
1182
1183 strlcpy(input->name, "camera", sizeof(input->name));
1184 input->type = V4L2_INPUT_TYPE_CAMERA;
1185
1186 return 0;
1187}
1188
1189static int
1190isp_video_g_input(struct file *file, void *fh, unsigned int *input)
1191{
1192 *input = 0;
1193
1194 return 0;
1195}
1196
1197static int
1198isp_video_s_input(struct file *file, void *fh, unsigned int input)
1199{
1200 return input == 0 ? 0 : -EINVAL;
1201}
1202
1203static const struct v4l2_ioctl_ops isp_video_ioctl_ops = {
1204 .vidioc_querycap = isp_video_querycap,
1205 .vidioc_g_fmt_vid_cap = isp_video_get_format,
1206 .vidioc_s_fmt_vid_cap = isp_video_set_format,
1207 .vidioc_try_fmt_vid_cap = isp_video_try_format,
1208 .vidioc_g_fmt_vid_out = isp_video_get_format,
1209 .vidioc_s_fmt_vid_out = isp_video_set_format,
1210 .vidioc_try_fmt_vid_out = isp_video_try_format,
1211 .vidioc_cropcap = isp_video_cropcap,
1212 .vidioc_g_crop = isp_video_get_crop,
1213 .vidioc_s_crop = isp_video_set_crop,
1214 .vidioc_g_parm = isp_video_get_param,
1215 .vidioc_s_parm = isp_video_set_param,
1216 .vidioc_reqbufs = isp_video_reqbufs,
1217 .vidioc_querybuf = isp_video_querybuf,
1218 .vidioc_qbuf = isp_video_qbuf,
1219 .vidioc_dqbuf = isp_video_dqbuf,
1220 .vidioc_streamon = isp_video_streamon,
1221 .vidioc_streamoff = isp_video_streamoff,
1222 .vidioc_enum_input = isp_video_enum_input,
1223 .vidioc_g_input = isp_video_g_input,
1224 .vidioc_s_input = isp_video_s_input,
1225};
1226
1227/* -----------------------------------------------------------------------------
1228 * V4L2 file operations
1229 */
1230
1231static int isp_video_open(struct file *file)
1232{
1233 struct isp_video *video = video_drvdata(file);
1234 struct isp_video_fh *handle;
1235 int ret = 0;
1236
1237 handle = kzalloc(sizeof(*handle), GFP_KERNEL);
1238 if (handle == NULL)
1239 return -ENOMEM;
1240
1241 v4l2_fh_init(&handle->vfh, &video->video);
1242 v4l2_fh_add(&handle->vfh);
1243
1244 /* If this is the first user, initialise the pipeline. */
1245 if (omap3isp_get(video->isp) == NULL) {
1246 ret = -EBUSY;
1247 goto done;
1248 }
1249
1250 ret = omap3isp_pipeline_pm_use(&video->video.entity, 1);
1251 if (ret < 0) {
1252 omap3isp_put(video->isp);
1253 goto done;
1254 }
1255
1256 omap3isp_video_queue_init(&handle->queue, video->type,
1257 &isp_video_queue_ops, video->isp->dev,
1258 sizeof(struct isp_buffer));
1259
1260 memset(&handle->format, 0, sizeof(handle->format));
1261 handle->format.type = video->type;
1262 handle->timeperframe.denominator = 1;
1263
1264 handle->video = video;
1265 file->private_data = &handle->vfh;
1266
1267done:
1268 if (ret < 0) {
1269 v4l2_fh_del(&handle->vfh);
1270 kfree(handle);
1271 }
1272
1273 return ret;
1274}
1275
1276static int isp_video_release(struct file *file)
1277{
1278 struct isp_video *video = video_drvdata(file);
1279 struct v4l2_fh *vfh = file->private_data;
1280 struct isp_video_fh *handle = to_isp_video_fh(vfh);
1281
1282 /* Disable streaming and free the buffers queue resources. */
1283 isp_video_streamoff(file, vfh, video->type);
1284
1285 mutex_lock(&handle->queue.lock);
1286 omap3isp_video_queue_cleanup(&handle->queue);
1287 mutex_unlock(&handle->queue.lock);
1288
1289 omap3isp_pipeline_pm_use(&video->video.entity, 0);
1290
1291 /* Release the file handle. */
1292 v4l2_fh_del(vfh);
1293 kfree(handle);
1294 file->private_data = NULL;
1295
1296 omap3isp_put(video->isp);
1297
1298 return 0;
1299}
1300
1301static unsigned int isp_video_poll(struct file *file, poll_table *wait)
1302{
1303 struct isp_video_fh *vfh = to_isp_video_fh(file->private_data);
1304 struct isp_video_queue *queue = &vfh->queue;
1305
1306 return omap3isp_video_queue_poll(queue, file, wait);
1307}
1308
1309static int isp_video_mmap(struct file *file, struct vm_area_struct *vma)
1310{
1311 struct isp_video_fh *vfh = to_isp_video_fh(file->private_data);
1312
1313 return omap3isp_video_queue_mmap(&vfh->queue, vma);
1314}
1315
1316static struct v4l2_file_operations isp_video_fops = {
1317 .owner = THIS_MODULE,
1318 .unlocked_ioctl = video_ioctl2,
1319 .open = isp_video_open,
1320 .release = isp_video_release,
1321 .poll = isp_video_poll,
1322 .mmap = isp_video_mmap,
1323};
1324
1325/* -----------------------------------------------------------------------------
1326 * ISP video core
1327 */
1328
1329static const struct isp_video_operations isp_video_dummy_ops = {
1330};
1331
1332int omap3isp_video_init(struct isp_video *video, const char *name)
1333{
1334 const char *direction;
1335 int ret;
1336
1337 switch (video->type) {
1338 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1339 direction = "output";
1340 video->pad.flags = MEDIA_PAD_FL_SINK;
1341 break;
1342 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1343 direction = "input";
1344 video->pad.flags = MEDIA_PAD_FL_SOURCE;
1345 break;
1346
1347 default:
1348 return -EINVAL;
1349 }
1350
1351 ret = media_entity_init(&video->video.entity, 1, &video->pad, 0);
1352 if (ret < 0)
1353 return ret;
1354
1355 mutex_init(&video->mutex);
1356 atomic_set(&video->active, 0);
1357
1358 spin_lock_init(&video->pipe.lock);
1359 mutex_init(&video->stream_lock);
1360
1361 /* Initialize the video device. */
1362 if (video->ops == NULL)
1363 video->ops = &isp_video_dummy_ops;
1364
1365 video->video.fops = &isp_video_fops;
1366 snprintf(video->video.name, sizeof(video->video.name),
1367 "OMAP3 ISP %s %s", name, direction);
1368 video->video.vfl_type = VFL_TYPE_GRABBER;
1369 video->video.release = video_device_release_empty;
1370 video->video.ioctl_ops = &isp_video_ioctl_ops;
1371 video->pipe.stream_state = ISP_PIPELINE_STREAM_STOPPED;
1372
1373 video_set_drvdata(&video->video, video);
1374
1375 return 0;
1376}
1377
1378void omap3isp_video_cleanup(struct isp_video *video)
1379{
1380 media_entity_cleanup(&video->video.entity);
1381 mutex_destroy(&video->stream_lock);
1382 mutex_destroy(&video->mutex);
1383}
1384
1385int omap3isp_video_register(struct isp_video *video, struct v4l2_device *vdev)
1386{
1387 int ret;
1388
1389 video->video.v4l2_dev = vdev;
1390
1391 ret = video_register_device(&video->video, VFL_TYPE_GRABBER, -1);
1392 if (ret < 0)
1393 printk(KERN_ERR "%s: could not register video device (%d)\n",
1394 __func__, ret);
1395
1396 return ret;
1397}
1398
1399void omap3isp_video_unregister(struct isp_video *video)
1400{
1401 if (video_is_registered(&video->video))
1402 video_unregister_device(&video->video);
1403}
diff --git a/drivers/media/video/omap3isp/ispvideo.h b/drivers/media/video/omap3isp/ispvideo.h
deleted file mode 100644
index 1ad470ec2b9d..000000000000
--- a/drivers/media/video/omap3isp/ispvideo.h
+++ /dev/null
@@ -1,216 +0,0 @@
1/*
2 * ispvideo.h
3 *
4 * TI OMAP3 ISP - Generic video node
5 *
6 * Copyright (C) 2009-2010 Nokia Corporation
7 *
8 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
9 * Sakari Ailus <sakari.ailus@iki.fi>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23 * 02110-1301 USA
24 */
25
26#ifndef OMAP3_ISP_VIDEO_H
27#define OMAP3_ISP_VIDEO_H
28
29#include <linux/v4l2-mediabus.h>
30#include <media/media-entity.h>
31#include <media/v4l2-dev.h>
32#include <media/v4l2-fh.h>
33
34#include "ispqueue.h"
35
36#define ISP_VIDEO_DRIVER_NAME "ispvideo"
37#define ISP_VIDEO_DRIVER_VERSION "0.0.2"
38
39struct isp_device;
40struct isp_video;
41struct v4l2_mbus_framefmt;
42struct v4l2_pix_format;
43
44/*
45 * struct isp_format_info - ISP media bus format information
46 * @code: V4L2 media bus format code
47 * @truncated: V4L2 media bus format code for the same format truncated to 10
48 * bits. Identical to @code if the format is 10 bits wide or less.
49 * @uncompressed: V4L2 media bus format code for the corresponding uncompressed
50 * format. Identical to @code if the format is not DPCM compressed.
51 * @flavor: V4L2 media bus format code for the same pixel layout but
52 * shifted to be 8 bits per pixel. =0 if format is not shiftable.
53 * @pixelformat: V4L2 pixel format FCC identifier
54 * @width: Bits per pixel (when transferred over a bus)
55 * @bpp: Bytes per pixel (when stored in memory)
56 */
57struct isp_format_info {
58 enum v4l2_mbus_pixelcode code;
59 enum v4l2_mbus_pixelcode truncated;
60 enum v4l2_mbus_pixelcode uncompressed;
61 enum v4l2_mbus_pixelcode flavor;
62 u32 pixelformat;
63 unsigned int width;
64 unsigned int bpp;
65};
66
67enum isp_pipeline_stream_state {
68 ISP_PIPELINE_STREAM_STOPPED = 0,
69 ISP_PIPELINE_STREAM_CONTINUOUS = 1,
70 ISP_PIPELINE_STREAM_SINGLESHOT = 2,
71};
72
73enum isp_pipeline_state {
74 /* The stream has been started on the input video node. */
75 ISP_PIPELINE_STREAM_INPUT = 1,
76 /* The stream has been started on the output video node. */
77 ISP_PIPELINE_STREAM_OUTPUT = 2,
78 /* At least one buffer is queued on the input video node. */
79 ISP_PIPELINE_QUEUE_INPUT = 4,
80 /* At least one buffer is queued on the output video node. */
81 ISP_PIPELINE_QUEUE_OUTPUT = 8,
82 /* The input entity is idle, ready to be started. */
83 ISP_PIPELINE_IDLE_INPUT = 16,
84 /* The output entity is idle, ready to be started. */
85 ISP_PIPELINE_IDLE_OUTPUT = 32,
86 /* The pipeline is currently streaming. */
87 ISP_PIPELINE_STREAM = 64,
88};
89
90/*
91 * struct isp_pipeline - An ISP hardware pipeline
92 * @error: A hardware error occurred during capture
93 * @entities: Bitmask of entities in the pipeline (indexed by entity ID)
94 */
95struct isp_pipeline {
96 struct media_pipeline pipe;
97 spinlock_t lock; /* Pipeline state and queue flags */
98 unsigned int state;
99 enum isp_pipeline_stream_state stream_state;
100 struct isp_video *input;
101 struct isp_video *output;
102 u32 entities;
103 unsigned long l3_ick;
104 unsigned int max_rate;
105 atomic_t frame_number;
106 bool do_propagation; /* of frame number */
107 bool error;
108 struct v4l2_fract max_timeperframe;
109 struct v4l2_subdev *external;
110 unsigned int external_rate;
111 unsigned int external_width;
112};
113
114#define to_isp_pipeline(__e) \
115 container_of((__e)->pipe, struct isp_pipeline, pipe)
116
117static inline int isp_pipeline_ready(struct isp_pipeline *pipe)
118{
119 return pipe->state == (ISP_PIPELINE_STREAM_INPUT |
120 ISP_PIPELINE_STREAM_OUTPUT |
121 ISP_PIPELINE_QUEUE_INPUT |
122 ISP_PIPELINE_QUEUE_OUTPUT |
123 ISP_PIPELINE_IDLE_INPUT |
124 ISP_PIPELINE_IDLE_OUTPUT);
125}
126
127/*
128 * struct isp_buffer - ISP buffer
129 * @buffer: ISP video buffer
130 * @isp_addr: MMU mapped address (a.k.a. device address) of the buffer.
131 */
132struct isp_buffer {
133 struct isp_video_buffer buffer;
134 dma_addr_t isp_addr;
135};
136
137#define to_isp_buffer(buf) container_of(buf, struct isp_buffer, buffer)
138
139enum isp_video_dmaqueue_flags {
140 /* Set if DMA queue becomes empty when ISP_PIPELINE_STREAM_CONTINUOUS */
141 ISP_VIDEO_DMAQUEUE_UNDERRUN = (1 << 0),
142 /* Set when queuing buffer to an empty DMA queue */
143 ISP_VIDEO_DMAQUEUE_QUEUED = (1 << 1),
144};
145
146#define isp_video_dmaqueue_flags_clr(video) \
147 ({ (video)->dmaqueue_flags = 0; })
148
149/*
150 * struct isp_video_operations - ISP video operations
151 * @queue: Resume streaming when a buffer is queued. Called on VIDIOC_QBUF
152 * if there was no buffer previously queued.
153 */
154struct isp_video_operations {
155 int(*queue)(struct isp_video *video, struct isp_buffer *buffer);
156};
157
158struct isp_video {
159 struct video_device video;
160 enum v4l2_buf_type type;
161 struct media_pad pad;
162
163 struct mutex mutex; /* format and crop settings */
164 atomic_t active;
165
166 struct isp_device *isp;
167
168 unsigned int capture_mem;
169 unsigned int bpl_alignment; /* alignment value */
170 unsigned int bpl_zero_padding; /* whether the alignment is optional */
171 unsigned int bpl_max; /* maximum bytes per line value */
172 unsigned int bpl_value; /* bytes per line value */
173 unsigned int bpl_padding; /* padding at end of line */
174
175 /* Entity video node streaming */
176 unsigned int streaming:1;
177
178 /* Pipeline state */
179 struct isp_pipeline pipe;
180 struct mutex stream_lock; /* pipeline and stream states */
181
182 /* Video buffers queue */
183 struct isp_video_queue *queue;
184 struct list_head dmaqueue;
185 enum isp_video_dmaqueue_flags dmaqueue_flags;
186
187 const struct isp_video_operations *ops;
188};
189
190#define to_isp_video(vdev) container_of(vdev, struct isp_video, video)
191
192struct isp_video_fh {
193 struct v4l2_fh vfh;
194 struct isp_video *video;
195 struct isp_video_queue queue;
196 struct v4l2_format format;
197 struct v4l2_fract timeperframe;
198};
199
200#define to_isp_video_fh(fh) container_of(fh, struct isp_video_fh, vfh)
201#define isp_video_queue_to_isp_video_fh(q) \
202 container_of(q, struct isp_video_fh, queue)
203
204int omap3isp_video_init(struct isp_video *video, const char *name);
205void omap3isp_video_cleanup(struct isp_video *video);
206int omap3isp_video_register(struct isp_video *video,
207 struct v4l2_device *vdev);
208void omap3isp_video_unregister(struct isp_video *video);
209struct isp_buffer *omap3isp_video_buffer_next(struct isp_video *video);
210void omap3isp_video_resume(struct isp_video *video, int continuous);
211struct media_pad *omap3isp_video_remote_pad(struct isp_video *video);
212
213const struct isp_format_info *
214omap3isp_video_format_info(enum v4l2_mbus_pixelcode code);
215
216#endif /* OMAP3_ISP_VIDEO_H */
diff --git a/drivers/media/video/omap3isp/luma_enhance_table.h b/drivers/media/video/omap3isp/luma_enhance_table.h
deleted file mode 100644
index 098b45e2280f..000000000000
--- a/drivers/media/video/omap3isp/luma_enhance_table.h
+++ /dev/null
@@ -1,42 +0,0 @@
1/*
2 * luma_enhance_table.h
3 *
4 * TI OMAP3 ISP - Luminance enhancement table
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc.
8 *
9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 * Sakari Ailus <sakari.ailus@iki.fi>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 */
26
271047552, 1047552, 1047552, 1047552, 1047552, 1047552, 1047552, 1047552,
281047552, 1047552, 1047552, 1047552, 1047552, 1047552, 1047552, 1047552,
291047552, 1047552, 1047552, 1047552, 1047552, 1047552, 1047552, 1047552,
301047552, 1047552, 1047552, 1047552, 1048575, 1047551, 1046527, 1045503,
311044479, 1043455, 1042431, 1041407, 1040383, 1039359, 1038335, 1037311,
321036287, 1035263, 1034239, 1033215, 1032191, 1031167, 1030143, 1028096,
331028096, 1028096, 1028096, 1028096, 1028096, 1028096, 1028096, 1028096,
341028096, 1028100, 1032196, 1036292, 1040388, 1044484, 0, 0,
35 0, 5, 5125, 10245, 15365, 20485, 25605, 30720,
36 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720,
37 30720, 30720, 31743, 30719, 29695, 28671, 27647, 26623,
38 25599, 24575, 23551, 22527, 21503, 20479, 19455, 18431,
39 17407, 16383, 15359, 14335, 13311, 12287, 11263, 10239,
40 9215, 8191, 7167, 6143, 5119, 4095, 3071, 1024,
41 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024,
42 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024
diff --git a/drivers/media/video/omap3isp/noise_filter_table.h b/drivers/media/video/omap3isp/noise_filter_table.h
deleted file mode 100644
index d50451a4a242..000000000000
--- a/drivers/media/video/omap3isp/noise_filter_table.h
+++ /dev/null
@@ -1,30 +0,0 @@
1/*
2 * noise_filter_table.h
3 *
4 * TI OMAP3 ISP - Noise filter table
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc.
8 *
9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 * Sakari Ailus <sakari.ailus@iki.fi>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 */
26
2716, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
2816, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
2931, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
3031, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31
diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c
deleted file mode 100644
index 9c21e01f2c24..000000000000
--- a/drivers/media/video/pxa_camera.c
+++ /dev/null
@@ -1,1852 +0,0 @@
1/*
2 * V4L2 Driver for PXA camera host
3 *
4 * Copyright (C) 2006, Sascha Hauer, Pengutronix
5 * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <linux/init.h>
14#include <linux/module.h>
15#include <linux/io.h>
16#include <linux/delay.h>
17#include <linux/dma-mapping.h>
18#include <linux/errno.h>
19#include <linux/fs.h>
20#include <linux/interrupt.h>
21#include <linux/kernel.h>
22#include <linux/mm.h>
23#include <linux/moduleparam.h>
24#include <linux/time.h>
25#include <linux/device.h>
26#include <linux/platform_device.h>
27#include <linux/clk.h>
28#include <linux/sched.h>
29#include <linux/slab.h>
30
31#include <media/v4l2-common.h>
32#include <media/v4l2-dev.h>
33#include <media/videobuf-dma-sg.h>
34#include <media/soc_camera.h>
35#include <media/soc_mediabus.h>
36
37#include <linux/videodev2.h>
38
39#include <mach/dma.h>
40#include <mach/camera.h>
41
42#define PXA_CAM_VERSION "0.0.6"
43#define PXA_CAM_DRV_NAME "pxa27x-camera"
44
45/* Camera Interface */
46#define CICR0 0x0000
47#define CICR1 0x0004
48#define CICR2 0x0008
49#define CICR3 0x000C
50#define CICR4 0x0010
51#define CISR 0x0014
52#define CIFR 0x0018
53#define CITOR 0x001C
54#define CIBR0 0x0028
55#define CIBR1 0x0030
56#define CIBR2 0x0038
57
58#define CICR0_DMAEN (1 << 31) /* DMA request enable */
59#define CICR0_PAR_EN (1 << 30) /* Parity enable */
60#define CICR0_SL_CAP_EN (1 << 29) /* Capture enable for slave mode */
61#define CICR0_ENB (1 << 28) /* Camera interface enable */
62#define CICR0_DIS (1 << 27) /* Camera interface disable */
63#define CICR0_SIM (0x7 << 24) /* Sensor interface mode mask */
64#define CICR0_TOM (1 << 9) /* Time-out mask */
65#define CICR0_RDAVM (1 << 8) /* Receive-data-available mask */
66#define CICR0_FEM (1 << 7) /* FIFO-empty mask */
67#define CICR0_EOLM (1 << 6) /* End-of-line mask */
68#define CICR0_PERRM (1 << 5) /* Parity-error mask */
69#define CICR0_QDM (1 << 4) /* Quick-disable mask */
70#define CICR0_CDM (1 << 3) /* Disable-done mask */
71#define CICR0_SOFM (1 << 2) /* Start-of-frame mask */
72#define CICR0_EOFM (1 << 1) /* End-of-frame mask */
73#define CICR0_FOM (1 << 0) /* FIFO-overrun mask */
74
75#define CICR1_TBIT (1 << 31) /* Transparency bit */
76#define CICR1_RGBT_CONV (0x3 << 29) /* RGBT conversion mask */
77#define CICR1_PPL (0x7ff << 15) /* Pixels per line mask */
78#define CICR1_RGB_CONV (0x7 << 12) /* RGB conversion mask */
79#define CICR1_RGB_F (1 << 11) /* RGB format */
80#define CICR1_YCBCR_F (1 << 10) /* YCbCr format */
81#define CICR1_RGB_BPP (0x7 << 7) /* RGB bis per pixel mask */
82#define CICR1_RAW_BPP (0x3 << 5) /* Raw bis per pixel mask */
83#define CICR1_COLOR_SP (0x3 << 3) /* Color space mask */
84#define CICR1_DW (0x7 << 0) /* Data width mask */
85
86#define CICR2_BLW (0xff << 24) /* Beginning-of-line pixel clock
87 wait count mask */
88#define CICR2_ELW (0xff << 16) /* End-of-line pixel clock
89 wait count mask */
90#define CICR2_HSW (0x3f << 10) /* Horizontal sync pulse width mask */
91#define CICR2_BFPW (0x3f << 3) /* Beginning-of-frame pixel clock
92 wait count mask */
93#define CICR2_FSW (0x7 << 0) /* Frame stabilization
94 wait count mask */
95
96#define CICR3_BFW (0xff << 24) /* Beginning-of-frame line clock
97 wait count mask */
98#define CICR3_EFW (0xff << 16) /* End-of-frame line clock
99 wait count mask */
100#define CICR3_VSW (0x3f << 10) /* Vertical sync pulse width mask */
101#define CICR3_BFPW (0x3f << 3) /* Beginning-of-frame pixel clock
102 wait count mask */
103#define CICR3_LPF (0x7ff << 0) /* Lines per frame mask */
104
105#define CICR4_MCLK_DLY (0x3 << 24) /* MCLK Data Capture Delay mask */
106#define CICR4_PCLK_EN (1 << 23) /* Pixel clock enable */
107#define CICR4_PCP (1 << 22) /* Pixel clock polarity */
108#define CICR4_HSP (1 << 21) /* Horizontal sync polarity */
109#define CICR4_VSP (1 << 20) /* Vertical sync polarity */
110#define CICR4_MCLK_EN (1 << 19) /* MCLK enable */
111#define CICR4_FR_RATE (0x7 << 8) /* Frame rate mask */
112#define CICR4_DIV (0xff << 0) /* Clock divisor mask */
113
114#define CISR_FTO (1 << 15) /* FIFO time-out */
115#define CISR_RDAV_2 (1 << 14) /* Channel 2 receive data available */
116#define CISR_RDAV_1 (1 << 13) /* Channel 1 receive data available */
117#define CISR_RDAV_0 (1 << 12) /* Channel 0 receive data available */
118#define CISR_FEMPTY_2 (1 << 11) /* Channel 2 FIFO empty */
119#define CISR_FEMPTY_1 (1 << 10) /* Channel 1 FIFO empty */
120#define CISR_FEMPTY_0 (1 << 9) /* Channel 0 FIFO empty */
121#define CISR_EOL (1 << 8) /* End of line */
122#define CISR_PAR_ERR (1 << 7) /* Parity error */
123#define CISR_CQD (1 << 6) /* Camera interface quick disable */
124#define CISR_CDD (1 << 5) /* Camera interface disable done */
125#define CISR_SOF (1 << 4) /* Start of frame */
126#define CISR_EOF (1 << 3) /* End of frame */
127#define CISR_IFO_2 (1 << 2) /* FIFO overrun for Channel 2 */
128#define CISR_IFO_1 (1 << 1) /* FIFO overrun for Channel 1 */
129#define CISR_IFO_0 (1 << 0) /* FIFO overrun for Channel 0 */
130
131#define CIFR_FLVL2 (0x7f << 23) /* FIFO 2 level mask */
132#define CIFR_FLVL1 (0x7f << 16) /* FIFO 1 level mask */
133#define CIFR_FLVL0 (0xff << 8) /* FIFO 0 level mask */
134#define CIFR_THL_0 (0x3 << 4) /* Threshold Level for Channel 0 FIFO */
135#define CIFR_RESET_F (1 << 3) /* Reset input FIFOs */
136#define CIFR_FEN2 (1 << 2) /* FIFO enable for channel 2 */
137#define CIFR_FEN1 (1 << 1) /* FIFO enable for channel 1 */
138#define CIFR_FEN0 (1 << 0) /* FIFO enable for channel 0 */
139
140#define CICR0_SIM_MP (0 << 24)
141#define CICR0_SIM_SP (1 << 24)
142#define CICR0_SIM_MS (2 << 24)
143#define CICR0_SIM_EP (3 << 24)
144#define CICR0_SIM_ES (4 << 24)
145
146#define CICR1_DW_VAL(x) ((x) & CICR1_DW) /* Data bus width */
147#define CICR1_PPL_VAL(x) (((x) << 15) & CICR1_PPL) /* Pixels per line */
148#define CICR1_COLOR_SP_VAL(x) (((x) << 3) & CICR1_COLOR_SP) /* color space */
149#define CICR1_RGB_BPP_VAL(x) (((x) << 7) & CICR1_RGB_BPP) /* bpp for rgb */
150#define CICR1_RGBT_CONV_VAL(x) (((x) << 29) & CICR1_RGBT_CONV) /* rgbt conv */
151
152#define CICR2_BLW_VAL(x) (((x) << 24) & CICR2_BLW) /* Beginning-of-line pixel clock wait count */
153#define CICR2_ELW_VAL(x) (((x) << 16) & CICR2_ELW) /* End-of-line pixel clock wait count */
154#define CICR2_HSW_VAL(x) (((x) << 10) & CICR2_HSW) /* Horizontal sync pulse width */
155#define CICR2_BFPW_VAL(x) (((x) << 3) & CICR2_BFPW) /* Beginning-of-frame pixel clock wait count */
156#define CICR2_FSW_VAL(x) (((x) << 0) & CICR2_FSW) /* Frame stabilization wait count */
157
158#define CICR3_BFW_VAL(x) (((x) << 24) & CICR3_BFW) /* Beginning-of-frame line clock wait count */
159#define CICR3_EFW_VAL(x) (((x) << 16) & CICR3_EFW) /* End-of-frame line clock wait count */
160#define CICR3_VSW_VAL(x) (((x) << 11) & CICR3_VSW) /* Vertical sync pulse width */
161#define CICR3_LPF_VAL(x) (((x) << 0) & CICR3_LPF) /* Lines per frame */
162
163#define CICR0_IRQ_MASK (CICR0_TOM | CICR0_RDAVM | CICR0_FEM | CICR0_EOLM | \
164 CICR0_PERRM | CICR0_QDM | CICR0_CDM | CICR0_SOFM | \
165 CICR0_EOFM | CICR0_FOM)
166
167/*
168 * Structures
169 */
170enum pxa_camera_active_dma {
171 DMA_Y = 0x1,
172 DMA_U = 0x2,
173 DMA_V = 0x4,
174};
175
176/* descriptor needed for the PXA DMA engine */
177struct pxa_cam_dma {
178 dma_addr_t sg_dma;
179 struct pxa_dma_desc *sg_cpu;
180 size_t sg_size;
181 int sglen;
182};
183
184/* buffer for one video frame */
185struct pxa_buffer {
186 /* common v4l buffer stuff -- must be first */
187 struct videobuf_buffer vb;
188 enum v4l2_mbus_pixelcode code;
189 /* our descriptor lists for Y, U and V channels */
190 struct pxa_cam_dma dmas[3];
191 int inwork;
192 enum pxa_camera_active_dma active_dma;
193};
194
195struct pxa_camera_dev {
196 struct soc_camera_host soc_host;
197 /*
198 * PXA27x is only supposed to handle one camera on its Quick Capture
199 * interface. If anyone ever builds hardware to enable more than
200 * one camera, they will have to modify this driver too
201 */
202 struct soc_camera_device *icd;
203 struct clk *clk;
204
205 unsigned int irq;
206 void __iomem *base;
207
208 int channels;
209 unsigned int dma_chans[3];
210
211 struct pxacamera_platform_data *pdata;
212 struct resource *res;
213 unsigned long platform_flags;
214 unsigned long ciclk;
215 unsigned long mclk;
216 u32 mclk_divisor;
217 u16 width_flags; /* max 10 bits */
218
219 struct list_head capture;
220
221 spinlock_t lock;
222
223 struct pxa_buffer *active;
224 struct pxa_dma_desc *sg_tail[3];
225
226 u32 save_cicr[5];
227};
228
229struct pxa_cam {
230 unsigned long flags;
231};
232
233static const char *pxa_cam_driver_description = "PXA_Camera";
234
235static unsigned int vid_limit = 16; /* Video memory limit, in Mb */
236
237/*
238 * Videobuf operations
239 */
240static int pxa_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
241 unsigned int *size)
242{
243 struct soc_camera_device *icd = vq->priv_data;
244
245 dev_dbg(icd->parent, "count=%d, size=%d\n", *count, *size);
246
247 *size = icd->sizeimage;
248
249 if (0 == *count)
250 *count = 32;
251 if (*size * *count > vid_limit * 1024 * 1024)
252 *count = (vid_limit * 1024 * 1024) / *size;
253
254 return 0;
255}
256
257static void free_buffer(struct videobuf_queue *vq, struct pxa_buffer *buf)
258{
259 struct soc_camera_device *icd = vq->priv_data;
260 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
261 struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb);
262 int i;
263
264 BUG_ON(in_interrupt());
265
266 dev_dbg(icd->parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
267 &buf->vb, buf->vb.baddr, buf->vb.bsize);
268
269 /*
270 * This waits until this buffer is out of danger, i.e., until it is no
271 * longer in STATE_QUEUED or STATE_ACTIVE
272 */
273 videobuf_waiton(vq, &buf->vb, 0, 0);
274 videobuf_dma_unmap(vq->dev, dma);
275 videobuf_dma_free(dma);
276
277 for (i = 0; i < ARRAY_SIZE(buf->dmas); i++) {
278 if (buf->dmas[i].sg_cpu)
279 dma_free_coherent(ici->v4l2_dev.dev,
280 buf->dmas[i].sg_size,
281 buf->dmas[i].sg_cpu,
282 buf->dmas[i].sg_dma);
283 buf->dmas[i].sg_cpu = NULL;
284 }
285
286 buf->vb.state = VIDEOBUF_NEEDS_INIT;
287}
288
289static int calculate_dma_sglen(struct scatterlist *sglist, int sglen,
290 int sg_first_ofs, int size)
291{
292 int i, offset, dma_len, xfer_len;
293 struct scatterlist *sg;
294
295 offset = sg_first_ofs;
296 for_each_sg(sglist, sg, sglen, i) {
297 dma_len = sg_dma_len(sg);
298
299 /* PXA27x Developer's Manual 27.4.4.1: round up to 8 bytes */
300 xfer_len = roundup(min(dma_len - offset, size), 8);
301
302 size = max(0, size - xfer_len);
303 offset = 0;
304 if (size == 0)
305 break;
306 }
307
308 BUG_ON(size != 0);
309 return i + 1;
310}
311
312/**
313 * pxa_init_dma_channel - init dma descriptors
314 * @pcdev: pxa camera device
315 * @buf: pxa buffer to find pxa dma channel
316 * @dma: dma video buffer
317 * @channel: dma channel (0 => 'Y', 1 => 'U', 2 => 'V')
318 * @cibr: camera Receive Buffer Register
319 * @size: bytes to transfer
320 * @sg_first: first element of sg_list
321 * @sg_first_ofs: offset in first element of sg_list
322 *
323 * Prepares the pxa dma descriptors to transfer one camera channel.
324 * Beware sg_first and sg_first_ofs are both input and output parameters.
325 *
326 * Returns 0 or -ENOMEM if no coherent memory is available
327 */
328static int pxa_init_dma_channel(struct pxa_camera_dev *pcdev,
329 struct pxa_buffer *buf,
330 struct videobuf_dmabuf *dma, int channel,
331 int cibr, int size,
332 struct scatterlist **sg_first, int *sg_first_ofs)
333{
334 struct pxa_cam_dma *pxa_dma = &buf->dmas[channel];
335 struct device *dev = pcdev->soc_host.v4l2_dev.dev;
336 struct scatterlist *sg;
337 int i, offset, sglen;
338 int dma_len = 0, xfer_len = 0;
339
340 if (pxa_dma->sg_cpu)
341 dma_free_coherent(dev, pxa_dma->sg_size,
342 pxa_dma->sg_cpu, pxa_dma->sg_dma);
343
344 sglen = calculate_dma_sglen(*sg_first, dma->sglen,
345 *sg_first_ofs, size);
346
347 pxa_dma->sg_size = (sglen + 1) * sizeof(struct pxa_dma_desc);
348 pxa_dma->sg_cpu = dma_alloc_coherent(dev, pxa_dma->sg_size,
349 &pxa_dma->sg_dma, GFP_KERNEL);
350 if (!pxa_dma->sg_cpu)
351 return -ENOMEM;
352
353 pxa_dma->sglen = sglen;
354 offset = *sg_first_ofs;
355
356 dev_dbg(dev, "DMA: sg_first=%p, sglen=%d, ofs=%d, dma.desc=%x\n",
357 *sg_first, sglen, *sg_first_ofs, pxa_dma->sg_dma);
358
359
360 for_each_sg(*sg_first, sg, sglen, i) {
361 dma_len = sg_dma_len(sg);
362
363 /* PXA27x Developer's Manual 27.4.4.1: round up to 8 bytes */
364 xfer_len = roundup(min(dma_len - offset, size), 8);
365
366 size = max(0, size - xfer_len);
367
368 pxa_dma->sg_cpu[i].dsadr = pcdev->res->start + cibr;
369 pxa_dma->sg_cpu[i].dtadr = sg_dma_address(sg) + offset;
370 pxa_dma->sg_cpu[i].dcmd =
371 DCMD_FLOWSRC | DCMD_BURST8 | DCMD_INCTRGADDR | xfer_len;
372#ifdef DEBUG
373 if (!i)
374 pxa_dma->sg_cpu[i].dcmd |= DCMD_STARTIRQEN;
375#endif
376 pxa_dma->sg_cpu[i].ddadr =
377 pxa_dma->sg_dma + (i + 1) * sizeof(struct pxa_dma_desc);
378
379 dev_vdbg(dev, "DMA: desc.%08x->@phys=0x%08x, len=%d\n",
380 pxa_dma->sg_dma + i * sizeof(struct pxa_dma_desc),
381 sg_dma_address(sg) + offset, xfer_len);
382 offset = 0;
383
384 if (size == 0)
385 break;
386 }
387
388 pxa_dma->sg_cpu[sglen].ddadr = DDADR_STOP;
389 pxa_dma->sg_cpu[sglen].dcmd = DCMD_FLOWSRC | DCMD_BURST8 | DCMD_ENDIRQEN;
390
391 /*
392 * Handle 1 special case :
393 * - in 3 planes (YUV422P format), we might finish with xfer_len equal
394 * to dma_len (end on PAGE boundary). In this case, the sg element
395 * for next plane should be the next after the last used to store the
396 * last scatter gather RAM page
397 */
398 if (xfer_len >= dma_len) {
399 *sg_first_ofs = xfer_len - dma_len;
400 *sg_first = sg_next(sg);
401 } else {
402 *sg_first_ofs = xfer_len;
403 *sg_first = sg;
404 }
405
406 return 0;
407}
408
409static void pxa_videobuf_set_actdma(struct pxa_camera_dev *pcdev,
410 struct pxa_buffer *buf)
411{
412 buf->active_dma = DMA_Y;
413 if (pcdev->channels == 3)
414 buf->active_dma |= DMA_U | DMA_V;
415}
416
417/*
418 * Please check the DMA prepared buffer structure in :
419 * Documentation/video4linux/pxa_camera.txt
420 * Please check also in pxa_camera_check_link_miss() to understand why DMA chain
421 * modification while DMA chain is running will work anyway.
422 */
423static int pxa_videobuf_prepare(struct videobuf_queue *vq,
424 struct videobuf_buffer *vb, enum v4l2_field field)
425{
426 struct soc_camera_device *icd = vq->priv_data;
427 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
428 struct pxa_camera_dev *pcdev = ici->priv;
429 struct device *dev = pcdev->soc_host.v4l2_dev.dev;
430 struct pxa_buffer *buf = container_of(vb, struct pxa_buffer, vb);
431 int ret;
432 int size_y, size_u = 0, size_v = 0;
433
434 dev_dbg(dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
435 vb, vb->baddr, vb->bsize);
436
437 /* Added list head initialization on alloc */
438 WARN_ON(!list_empty(&vb->queue));
439
440#ifdef DEBUG
441 /*
442 * This can be useful if you want to see if we actually fill
443 * the buffer with something
444 */
445 memset((void *)vb->baddr, 0xaa, vb->bsize);
446#endif
447
448 BUG_ON(NULL == icd->current_fmt);
449
450 /*
451 * I think, in buf_prepare you only have to protect global data,
452 * the actual buffer is yours
453 */
454 buf->inwork = 1;
455
456 if (buf->code != icd->current_fmt->code ||
457 vb->width != icd->user_width ||
458 vb->height != icd->user_height ||
459 vb->field != field) {
460 buf->code = icd->current_fmt->code;
461 vb->width = icd->user_width;
462 vb->height = icd->user_height;
463 vb->field = field;
464 vb->state = VIDEOBUF_NEEDS_INIT;
465 }
466
467 vb->size = icd->sizeimage;
468 if (0 != vb->baddr && vb->bsize < vb->size) {
469 ret = -EINVAL;
470 goto out;
471 }
472
473 if (vb->state == VIDEOBUF_NEEDS_INIT) {
474 int size = vb->size;
475 int next_ofs = 0;
476 struct videobuf_dmabuf *dma = videobuf_to_dma(vb);
477 struct scatterlist *sg;
478
479 ret = videobuf_iolock(vq, vb, NULL);
480 if (ret)
481 goto fail;
482
483 if (pcdev->channels == 3) {
484 size_y = size / 2;
485 size_u = size_v = size / 4;
486 } else {
487 size_y = size;
488 }
489
490 sg = dma->sglist;
491
492 /* init DMA for Y channel */
493 ret = pxa_init_dma_channel(pcdev, buf, dma, 0, CIBR0, size_y,
494 &sg, &next_ofs);
495 if (ret) {
496 dev_err(dev, "DMA initialization for Y/RGB failed\n");
497 goto fail;
498 }
499
500 /* init DMA for U channel */
501 if (size_u)
502 ret = pxa_init_dma_channel(pcdev, buf, dma, 1, CIBR1,
503 size_u, &sg, &next_ofs);
504 if (ret) {
505 dev_err(dev, "DMA initialization for U failed\n");
506 goto fail_u;
507 }
508
509 /* init DMA for V channel */
510 if (size_v)
511 ret = pxa_init_dma_channel(pcdev, buf, dma, 2, CIBR2,
512 size_v, &sg, &next_ofs);
513 if (ret) {
514 dev_err(dev, "DMA initialization for V failed\n");
515 goto fail_v;
516 }
517
518 vb->state = VIDEOBUF_PREPARED;
519 }
520
521 buf->inwork = 0;
522 pxa_videobuf_set_actdma(pcdev, buf);
523
524 return 0;
525
526fail_v:
527 dma_free_coherent(dev, buf->dmas[1].sg_size,
528 buf->dmas[1].sg_cpu, buf->dmas[1].sg_dma);
529fail_u:
530 dma_free_coherent(dev, buf->dmas[0].sg_size,
531 buf->dmas[0].sg_cpu, buf->dmas[0].sg_dma);
532fail:
533 free_buffer(vq, buf);
534out:
535 buf->inwork = 0;
536 return ret;
537}
538
539/**
540 * pxa_dma_start_channels - start DMA channel for active buffer
541 * @pcdev: pxa camera device
542 *
543 * Initialize DMA channels to the beginning of the active video buffer, and
544 * start these channels.
545 */
546static void pxa_dma_start_channels(struct pxa_camera_dev *pcdev)
547{
548 int i;
549 struct pxa_buffer *active;
550
551 active = pcdev->active;
552
553 for (i = 0; i < pcdev->channels; i++) {
554 dev_dbg(pcdev->soc_host.v4l2_dev.dev,
555 "%s (channel=%d) ddadr=%08x\n", __func__,
556 i, active->dmas[i].sg_dma);
557 DDADR(pcdev->dma_chans[i]) = active->dmas[i].sg_dma;
558 DCSR(pcdev->dma_chans[i]) = DCSR_RUN;
559 }
560}
561
562static void pxa_dma_stop_channels(struct pxa_camera_dev *pcdev)
563{
564 int i;
565
566 for (i = 0; i < pcdev->channels; i++) {
567 dev_dbg(pcdev->soc_host.v4l2_dev.dev,
568 "%s (channel=%d)\n", __func__, i);
569 DCSR(pcdev->dma_chans[i]) = 0;
570 }
571}
572
573static void pxa_dma_add_tail_buf(struct pxa_camera_dev *pcdev,
574 struct pxa_buffer *buf)
575{
576 int i;
577 struct pxa_dma_desc *buf_last_desc;
578
579 for (i = 0; i < pcdev->channels; i++) {
580 buf_last_desc = buf->dmas[i].sg_cpu + buf->dmas[i].sglen;
581 buf_last_desc->ddadr = DDADR_STOP;
582
583 if (pcdev->sg_tail[i])
584 /* Link the new buffer to the old tail */
585 pcdev->sg_tail[i]->ddadr = buf->dmas[i].sg_dma;
586
587 /* Update the channel tail */
588 pcdev->sg_tail[i] = buf_last_desc;
589 }
590}
591
592/**
593 * pxa_camera_start_capture - start video capturing
594 * @pcdev: camera device
595 *
596 * Launch capturing. DMA channels should not be active yet. They should get
597 * activated at the end of frame interrupt, to capture only whole frames, and
598 * never begin the capture of a partial frame.
599 */
600static void pxa_camera_start_capture(struct pxa_camera_dev *pcdev)
601{
602 unsigned long cicr0;
603
604 dev_dbg(pcdev->soc_host.v4l2_dev.dev, "%s\n", __func__);
605 /* Enable End-Of-Frame Interrupt */
606 cicr0 = __raw_readl(pcdev->base + CICR0) | CICR0_ENB;
607 cicr0 &= ~CICR0_EOFM;
608 __raw_writel(cicr0, pcdev->base + CICR0);
609}
610
611static void pxa_camera_stop_capture(struct pxa_camera_dev *pcdev)
612{
613 unsigned long cicr0;
614
615 pxa_dma_stop_channels(pcdev);
616
617 cicr0 = __raw_readl(pcdev->base + CICR0) & ~CICR0_ENB;
618 __raw_writel(cicr0, pcdev->base + CICR0);
619
620 pcdev->active = NULL;
621 dev_dbg(pcdev->soc_host.v4l2_dev.dev, "%s\n", __func__);
622}
623
624/* Called under spinlock_irqsave(&pcdev->lock, ...) */
625static void pxa_videobuf_queue(struct videobuf_queue *vq,
626 struct videobuf_buffer *vb)
627{
628 struct soc_camera_device *icd = vq->priv_data;
629 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
630 struct pxa_camera_dev *pcdev = ici->priv;
631 struct pxa_buffer *buf = container_of(vb, struct pxa_buffer, vb);
632
633 dev_dbg(icd->parent, "%s (vb=0x%p) 0x%08lx %d active=%p\n",
634 __func__, vb, vb->baddr, vb->bsize, pcdev->active);
635
636 list_add_tail(&vb->queue, &pcdev->capture);
637
638 vb->state = VIDEOBUF_ACTIVE;
639 pxa_dma_add_tail_buf(pcdev, buf);
640
641 if (!pcdev->active)
642 pxa_camera_start_capture(pcdev);
643}
644
645static void pxa_videobuf_release(struct videobuf_queue *vq,
646 struct videobuf_buffer *vb)
647{
648 struct pxa_buffer *buf = container_of(vb, struct pxa_buffer, vb);
649#ifdef DEBUG
650 struct soc_camera_device *icd = vq->priv_data;
651 struct device *dev = icd->parent;
652
653 dev_dbg(dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
654 vb, vb->baddr, vb->bsize);
655
656 switch (vb->state) {
657 case VIDEOBUF_ACTIVE:
658 dev_dbg(dev, "%s (active)\n", __func__);
659 break;
660 case VIDEOBUF_QUEUED:
661 dev_dbg(dev, "%s (queued)\n", __func__);
662 break;
663 case VIDEOBUF_PREPARED:
664 dev_dbg(dev, "%s (prepared)\n", __func__);
665 break;
666 default:
667 dev_dbg(dev, "%s (unknown)\n", __func__);
668 break;
669 }
670#endif
671
672 free_buffer(vq, buf);
673}
674
675static void pxa_camera_wakeup(struct pxa_camera_dev *pcdev,
676 struct videobuf_buffer *vb,
677 struct pxa_buffer *buf)
678{
679 int i;
680
681 /* _init is used to debug races, see comment in pxa_camera_reqbufs() */
682 list_del_init(&vb->queue);
683 vb->state = VIDEOBUF_DONE;
684 do_gettimeofday(&vb->ts);
685 vb->field_count++;
686 wake_up(&vb->done);
687 dev_dbg(pcdev->soc_host.v4l2_dev.dev, "%s dequeud buffer (vb=0x%p)\n",
688 __func__, vb);
689
690 if (list_empty(&pcdev->capture)) {
691 pxa_camera_stop_capture(pcdev);
692 for (i = 0; i < pcdev->channels; i++)
693 pcdev->sg_tail[i] = NULL;
694 return;
695 }
696
697 pcdev->active = list_entry(pcdev->capture.next,
698 struct pxa_buffer, vb.queue);
699}
700
701/**
702 * pxa_camera_check_link_miss - check missed DMA linking
703 * @pcdev: camera device
704 *
705 * The DMA chaining is done with DMA running. This means a tiny temporal window
706 * remains, where a buffer is queued on the chain, while the chain is already
707 * stopped. This means the tailed buffer would never be transferred by DMA.
708 * This function restarts the capture for this corner case, where :
709 * - DADR() == DADDR_STOP
710 * - a videobuffer is queued on the pcdev->capture list
711 *
712 * Please check the "DMA hot chaining timeslice issue" in
713 * Documentation/video4linux/pxa_camera.txt
714 *
715 * Context: should only be called within the dma irq handler
716 */
717static void pxa_camera_check_link_miss(struct pxa_camera_dev *pcdev)
718{
719 int i, is_dma_stopped = 1;
720
721 for (i = 0; i < pcdev->channels; i++)
722 if (DDADR(pcdev->dma_chans[i]) != DDADR_STOP)
723 is_dma_stopped = 0;
724 dev_dbg(pcdev->soc_host.v4l2_dev.dev,
725 "%s : top queued buffer=%p, dma_stopped=%d\n",
726 __func__, pcdev->active, is_dma_stopped);
727 if (pcdev->active && is_dma_stopped)
728 pxa_camera_start_capture(pcdev);
729}
730
731static void pxa_camera_dma_irq(int channel, struct pxa_camera_dev *pcdev,
732 enum pxa_camera_active_dma act_dma)
733{
734 struct device *dev = pcdev->soc_host.v4l2_dev.dev;
735 struct pxa_buffer *buf;
736 unsigned long flags;
737 u32 status, camera_status, overrun;
738 struct videobuf_buffer *vb;
739
740 spin_lock_irqsave(&pcdev->lock, flags);
741
742 status = DCSR(channel);
743 DCSR(channel) = status;
744
745 camera_status = __raw_readl(pcdev->base + CISR);
746 overrun = CISR_IFO_0;
747 if (pcdev->channels == 3)
748 overrun |= CISR_IFO_1 | CISR_IFO_2;
749
750 if (status & DCSR_BUSERR) {
751 dev_err(dev, "DMA Bus Error IRQ!\n");
752 goto out;
753 }
754
755 if (!(status & (DCSR_ENDINTR | DCSR_STARTINTR))) {
756 dev_err(dev, "Unknown DMA IRQ source, status: 0x%08x\n",
757 status);
758 goto out;
759 }
760
761 /*
762 * pcdev->active should not be NULL in DMA irq handler.
763 *
764 * But there is one corner case : if capture was stopped due to an
765 * overrun of channel 1, and at that same channel 2 was completed.
766 *
767 * When handling the overrun in DMA irq for channel 1, we'll stop the
768 * capture and restart it (and thus set pcdev->active to NULL). But the
769 * DMA irq handler will already be pending for channel 2. So on entering
770 * the DMA irq handler for channel 2 there will be no active buffer, yet
771 * that is normal.
772 */
773 if (!pcdev->active)
774 goto out;
775
776 vb = &pcdev->active->vb;
777 buf = container_of(vb, struct pxa_buffer, vb);
778 WARN_ON(buf->inwork || list_empty(&vb->queue));
779
780 dev_dbg(dev, "%s channel=%d %s%s(vb=0x%p) dma.desc=%x\n",
781 __func__, channel, status & DCSR_STARTINTR ? "SOF " : "",
782 status & DCSR_ENDINTR ? "EOF " : "", vb, DDADR(channel));
783
784 if (status & DCSR_ENDINTR) {
785 /*
786 * It's normal if the last frame creates an overrun, as there
787 * are no more DMA descriptors to fetch from QCI fifos
788 */
789 if (camera_status & overrun &&
790 !list_is_last(pcdev->capture.next, &pcdev->capture)) {
791 dev_dbg(dev, "FIFO overrun! CISR: %x\n",
792 camera_status);
793 pxa_camera_stop_capture(pcdev);
794 pxa_camera_start_capture(pcdev);
795 goto out;
796 }
797 buf->active_dma &= ~act_dma;
798 if (!buf->active_dma) {
799 pxa_camera_wakeup(pcdev, vb, buf);
800 pxa_camera_check_link_miss(pcdev);
801 }
802 }
803
804out:
805 spin_unlock_irqrestore(&pcdev->lock, flags);
806}
807
808static void pxa_camera_dma_irq_y(int channel, void *data)
809{
810 struct pxa_camera_dev *pcdev = data;
811 pxa_camera_dma_irq(channel, pcdev, DMA_Y);
812}
813
814static void pxa_camera_dma_irq_u(int channel, void *data)
815{
816 struct pxa_camera_dev *pcdev = data;
817 pxa_camera_dma_irq(channel, pcdev, DMA_U);
818}
819
820static void pxa_camera_dma_irq_v(int channel, void *data)
821{
822 struct pxa_camera_dev *pcdev = data;
823 pxa_camera_dma_irq(channel, pcdev, DMA_V);
824}
825
826static struct videobuf_queue_ops pxa_videobuf_ops = {
827 .buf_setup = pxa_videobuf_setup,
828 .buf_prepare = pxa_videobuf_prepare,
829 .buf_queue = pxa_videobuf_queue,
830 .buf_release = pxa_videobuf_release,
831};
832
833static void pxa_camera_init_videobuf(struct videobuf_queue *q,
834 struct soc_camera_device *icd)
835{
836 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
837 struct pxa_camera_dev *pcdev = ici->priv;
838
839 /*
840 * We must pass NULL as dev pointer, then all pci_* dma operations
841 * transform to normal dma_* ones.
842 */
843 videobuf_queue_sg_init(q, &pxa_videobuf_ops, NULL, &pcdev->lock,
844 V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE,
845 sizeof(struct pxa_buffer), icd, &icd->video_lock);
846}
847
848static u32 mclk_get_divisor(struct platform_device *pdev,
849 struct pxa_camera_dev *pcdev)
850{
851 unsigned long mclk = pcdev->mclk;
852 struct device *dev = &pdev->dev;
853 u32 div;
854 unsigned long lcdclk;
855
856 lcdclk = clk_get_rate(pcdev->clk);
857 pcdev->ciclk = lcdclk;
858
859 /* mclk <= ciclk / 4 (27.4.2) */
860 if (mclk > lcdclk / 4) {
861 mclk = lcdclk / 4;
862 dev_warn(dev, "Limiting master clock to %lu\n", mclk);
863 }
864
865 /* We verify mclk != 0, so if anyone breaks it, here comes their Oops */
866 div = (lcdclk + 2 * mclk - 1) / (2 * mclk) - 1;
867
868 /* If we're not supplying MCLK, leave it at 0 */
869 if (pcdev->platform_flags & PXA_CAMERA_MCLK_EN)
870 pcdev->mclk = lcdclk / (2 * (div + 1));
871
872 dev_dbg(dev, "LCD clock %luHz, target freq %luHz, divisor %u\n",
873 lcdclk, mclk, div);
874
875 return div;
876}
877
878static void recalculate_fifo_timeout(struct pxa_camera_dev *pcdev,
879 unsigned long pclk)
880{
881 /* We want a timeout > 1 pixel time, not ">=" */
882 u32 ciclk_per_pixel = pcdev->ciclk / pclk + 1;
883
884 __raw_writel(ciclk_per_pixel, pcdev->base + CITOR);
885}
886
887static void pxa_camera_activate(struct pxa_camera_dev *pcdev)
888{
889 u32 cicr4 = 0;
890
891 /* disable all interrupts */
892 __raw_writel(0x3ff, pcdev->base + CICR0);
893
894 if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN)
895 cicr4 |= CICR4_PCLK_EN;
896 if (pcdev->platform_flags & PXA_CAMERA_MCLK_EN)
897 cicr4 |= CICR4_MCLK_EN;
898 if (pcdev->platform_flags & PXA_CAMERA_PCP)
899 cicr4 |= CICR4_PCP;
900 if (pcdev->platform_flags & PXA_CAMERA_HSP)
901 cicr4 |= CICR4_HSP;
902 if (pcdev->platform_flags & PXA_CAMERA_VSP)
903 cicr4 |= CICR4_VSP;
904
905 __raw_writel(pcdev->mclk_divisor | cicr4, pcdev->base + CICR4);
906
907 if (pcdev->platform_flags & PXA_CAMERA_MCLK_EN)
908 /* Initialise the timeout under the assumption pclk = mclk */
909 recalculate_fifo_timeout(pcdev, pcdev->mclk);
910 else
911 /* "Safe default" - 13MHz */
912 recalculate_fifo_timeout(pcdev, 13000000);
913
914 clk_prepare_enable(pcdev->clk);
915}
916
917static void pxa_camera_deactivate(struct pxa_camera_dev *pcdev)
918{
919 clk_disable_unprepare(pcdev->clk);
920}
921
922static irqreturn_t pxa_camera_irq(int irq, void *data)
923{
924 struct pxa_camera_dev *pcdev = data;
925 unsigned long status, cifr, cicr0;
926 struct pxa_buffer *buf;
927 struct videobuf_buffer *vb;
928
929 status = __raw_readl(pcdev->base + CISR);
930 dev_dbg(pcdev->soc_host.v4l2_dev.dev,
931 "Camera interrupt status 0x%lx\n", status);
932
933 if (!status)
934 return IRQ_NONE;
935
936 __raw_writel(status, pcdev->base + CISR);
937
938 if (status & CISR_EOF) {
939 /* Reset the FIFOs */
940 cifr = __raw_readl(pcdev->base + CIFR) | CIFR_RESET_F;
941 __raw_writel(cifr, pcdev->base + CIFR);
942
943 pcdev->active = list_first_entry(&pcdev->capture,
944 struct pxa_buffer, vb.queue);
945 vb = &pcdev->active->vb;
946 buf = container_of(vb, struct pxa_buffer, vb);
947 pxa_videobuf_set_actdma(pcdev, buf);
948
949 pxa_dma_start_channels(pcdev);
950
951 cicr0 = __raw_readl(pcdev->base + CICR0) | CICR0_EOFM;
952 __raw_writel(cicr0, pcdev->base + CICR0);
953 }
954
955 return IRQ_HANDLED;
956}
957
958/*
959 * The following two functions absolutely depend on the fact, that
960 * there can be only one camera on PXA quick capture interface
961 * Called with .video_lock held
962 */
963static int pxa_camera_add_device(struct soc_camera_device *icd)
964{
965 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
966 struct pxa_camera_dev *pcdev = ici->priv;
967
968 if (pcdev->icd)
969 return -EBUSY;
970
971 pxa_camera_activate(pcdev);
972
973 pcdev->icd = icd;
974
975 dev_info(icd->parent, "PXA Camera driver attached to camera %d\n",
976 icd->devnum);
977
978 return 0;
979}
980
981/* Called with .video_lock held */
982static void pxa_camera_remove_device(struct soc_camera_device *icd)
983{
984 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
985 struct pxa_camera_dev *pcdev = ici->priv;
986
987 BUG_ON(icd != pcdev->icd);
988
989 dev_info(icd->parent, "PXA Camera driver detached from camera %d\n",
990 icd->devnum);
991
992 /* disable capture, disable interrupts */
993 __raw_writel(0x3ff, pcdev->base + CICR0);
994
995 /* Stop DMA engine */
996 DCSR(pcdev->dma_chans[0]) = 0;
997 DCSR(pcdev->dma_chans[1]) = 0;
998 DCSR(pcdev->dma_chans[2]) = 0;
999
1000 pxa_camera_deactivate(pcdev);
1001
1002 pcdev->icd = NULL;
1003}
1004
1005static int test_platform_param(struct pxa_camera_dev *pcdev,
1006 unsigned char buswidth, unsigned long *flags)
1007{
1008 /*
1009 * Platform specified synchronization and pixel clock polarities are
1010 * only a recommendation and are only used during probing. The PXA270
1011 * quick capture interface supports both.
1012 */
1013 *flags = (pcdev->platform_flags & PXA_CAMERA_MASTER ?
1014 V4L2_MBUS_MASTER : V4L2_MBUS_SLAVE) |
1015 V4L2_MBUS_HSYNC_ACTIVE_HIGH |
1016 V4L2_MBUS_HSYNC_ACTIVE_LOW |
1017 V4L2_MBUS_VSYNC_ACTIVE_HIGH |
1018 V4L2_MBUS_VSYNC_ACTIVE_LOW |
1019 V4L2_MBUS_DATA_ACTIVE_HIGH |
1020 V4L2_MBUS_PCLK_SAMPLE_RISING |
1021 V4L2_MBUS_PCLK_SAMPLE_FALLING;
1022
1023 /* If requested data width is supported by the platform, use it */
1024 if ((1 << (buswidth - 1)) & pcdev->width_flags)
1025 return 0;
1026
1027 return -EINVAL;
1028}
1029
1030static void pxa_camera_setup_cicr(struct soc_camera_device *icd,
1031 unsigned long flags, __u32 pixfmt)
1032{
1033 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1034 struct pxa_camera_dev *pcdev = ici->priv;
1035 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1036 unsigned long dw, bpp;
1037 u32 cicr0, cicr1, cicr2, cicr3, cicr4 = 0, y_skip_top;
1038 int ret = v4l2_subdev_call(sd, sensor, g_skip_top_lines, &y_skip_top);
1039
1040 if (ret < 0)
1041 y_skip_top = 0;
1042
1043 /*
1044 * Datawidth is now guaranteed to be equal to one of the three values.
1045 * We fix bit-per-pixel equal to data-width...
1046 */
1047 switch (icd->current_fmt->host_fmt->bits_per_sample) {
1048 case 10:
1049 dw = 4;
1050 bpp = 0x40;
1051 break;
1052 case 9:
1053 dw = 3;
1054 bpp = 0x20;
1055 break;
1056 default:
1057 /*
1058 * Actually it can only be 8 now,
1059 * default is just to silence compiler warnings
1060 */
1061 case 8:
1062 dw = 2;
1063 bpp = 0;
1064 }
1065
1066 if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN)
1067 cicr4 |= CICR4_PCLK_EN;
1068 if (pcdev->platform_flags & PXA_CAMERA_MCLK_EN)
1069 cicr4 |= CICR4_MCLK_EN;
1070 if (flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
1071 cicr4 |= CICR4_PCP;
1072 if (flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
1073 cicr4 |= CICR4_HSP;
1074 if (flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
1075 cicr4 |= CICR4_VSP;
1076
1077 cicr0 = __raw_readl(pcdev->base + CICR0);
1078 if (cicr0 & CICR0_ENB)
1079 __raw_writel(cicr0 & ~CICR0_ENB, pcdev->base + CICR0);
1080
1081 cicr1 = CICR1_PPL_VAL(icd->user_width - 1) | bpp | dw;
1082
1083 switch (pixfmt) {
1084 case V4L2_PIX_FMT_YUV422P:
1085 pcdev->channels = 3;
1086 cicr1 |= CICR1_YCBCR_F;
1087 /*
1088 * Normally, pxa bus wants as input UYVY format. We allow all
1089 * reorderings of the YUV422 format, as no processing is done,
1090 * and the YUV stream is just passed through without any
1091 * transformation. Note that UYVY is the only format that
1092 * should be used if pxa framebuffer Overlay2 is used.
1093 */
1094 case V4L2_PIX_FMT_UYVY:
1095 case V4L2_PIX_FMT_VYUY:
1096 case V4L2_PIX_FMT_YUYV:
1097 case V4L2_PIX_FMT_YVYU:
1098 cicr1 |= CICR1_COLOR_SP_VAL(2);
1099 break;
1100 case V4L2_PIX_FMT_RGB555:
1101 cicr1 |= CICR1_RGB_BPP_VAL(1) | CICR1_RGBT_CONV_VAL(2) |
1102 CICR1_TBIT | CICR1_COLOR_SP_VAL(1);
1103 break;
1104 case V4L2_PIX_FMT_RGB565:
1105 cicr1 |= CICR1_COLOR_SP_VAL(1) | CICR1_RGB_BPP_VAL(2);
1106 break;
1107 }
1108
1109 cicr2 = 0;
1110 cicr3 = CICR3_LPF_VAL(icd->user_height - 1) |
1111 CICR3_BFW_VAL(min((u32)255, y_skip_top));
1112 cicr4 |= pcdev->mclk_divisor;
1113
1114 __raw_writel(cicr1, pcdev->base + CICR1);
1115 __raw_writel(cicr2, pcdev->base + CICR2);
1116 __raw_writel(cicr3, pcdev->base + CICR3);
1117 __raw_writel(cicr4, pcdev->base + CICR4);
1118
1119 /* CIF interrupts are not used, only DMA */
1120 cicr0 = (cicr0 & CICR0_ENB) | (pcdev->platform_flags & PXA_CAMERA_MASTER ?
1121 CICR0_SIM_MP : (CICR0_SL_CAP_EN | CICR0_SIM_SP));
1122 cicr0 |= CICR0_DMAEN | CICR0_IRQ_MASK;
1123 __raw_writel(cicr0, pcdev->base + CICR0);
1124}
1125
1126static int pxa_camera_set_bus_param(struct soc_camera_device *icd)
1127{
1128 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1129 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1130 struct pxa_camera_dev *pcdev = ici->priv;
1131 struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
1132 u32 pixfmt = icd->current_fmt->host_fmt->fourcc;
1133 unsigned long bus_flags, common_flags;
1134 int ret;
1135 struct pxa_cam *cam = icd->host_priv;
1136
1137 ret = test_platform_param(pcdev, icd->current_fmt->host_fmt->bits_per_sample,
1138 &bus_flags);
1139 if (ret < 0)
1140 return ret;
1141
1142 ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
1143 if (!ret) {
1144 common_flags = soc_mbus_config_compatible(&cfg,
1145 bus_flags);
1146 if (!common_flags) {
1147 dev_warn(icd->parent,
1148 "Flags incompatible: camera 0x%x, host 0x%lx\n",
1149 cfg.flags, bus_flags);
1150 return -EINVAL;
1151 }
1152 } else if (ret != -ENOIOCTLCMD) {
1153 return ret;
1154 } else {
1155 common_flags = bus_flags;
1156 }
1157
1158 pcdev->channels = 1;
1159
1160 /* Make choises, based on platform preferences */
1161 if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) &&
1162 (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) {
1163 if (pcdev->platform_flags & PXA_CAMERA_HSP)
1164 common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH;
1165 else
1166 common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW;
1167 }
1168
1169 if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) &&
1170 (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) {
1171 if (pcdev->platform_flags & PXA_CAMERA_VSP)
1172 common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH;
1173 else
1174 common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW;
1175 }
1176
1177 if ((common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) &&
1178 (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)) {
1179 if (pcdev->platform_flags & PXA_CAMERA_PCP)
1180 common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_RISING;
1181 else
1182 common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_FALLING;
1183 }
1184
1185 cfg.flags = common_flags;
1186 ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
1187 if (ret < 0 && ret != -ENOIOCTLCMD) {
1188 dev_dbg(icd->parent, "camera s_mbus_config(0x%lx) returned %d\n",
1189 common_flags, ret);
1190 return ret;
1191 }
1192
1193 cam->flags = common_flags;
1194
1195 pxa_camera_setup_cicr(icd, common_flags, pixfmt);
1196
1197 return 0;
1198}
1199
1200static int pxa_camera_try_bus_param(struct soc_camera_device *icd,
1201 unsigned char buswidth)
1202{
1203 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1204 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1205 struct pxa_camera_dev *pcdev = ici->priv;
1206 struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
1207 unsigned long bus_flags, common_flags;
1208 int ret = test_platform_param(pcdev, buswidth, &bus_flags);
1209
1210 if (ret < 0)
1211 return ret;
1212
1213 ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
1214 if (!ret) {
1215 common_flags = soc_mbus_config_compatible(&cfg,
1216 bus_flags);
1217 if (!common_flags) {
1218 dev_warn(icd->parent,
1219 "Flags incompatible: camera 0x%x, host 0x%lx\n",
1220 cfg.flags, bus_flags);
1221 return -EINVAL;
1222 }
1223 } else if (ret == -ENOIOCTLCMD) {
1224 ret = 0;
1225 }
1226
1227 return ret;
1228}
1229
1230static const struct soc_mbus_pixelfmt pxa_camera_formats[] = {
1231 {
1232 .fourcc = V4L2_PIX_FMT_YUV422P,
1233 .name = "Planar YUV422 16 bit",
1234 .bits_per_sample = 8,
1235 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1236 .order = SOC_MBUS_ORDER_LE,
1237 .layout = SOC_MBUS_LAYOUT_PLANAR_2Y_U_V,
1238 },
1239};
1240
1241/* This will be corrected as we get more formats */
1242static bool pxa_camera_packing_supported(const struct soc_mbus_pixelfmt *fmt)
1243{
1244 return fmt->packing == SOC_MBUS_PACKING_NONE ||
1245 (fmt->bits_per_sample == 8 &&
1246 fmt->packing == SOC_MBUS_PACKING_2X8_PADHI) ||
1247 (fmt->bits_per_sample > 8 &&
1248 fmt->packing == SOC_MBUS_PACKING_EXTEND16);
1249}
1250
1251static int pxa_camera_get_formats(struct soc_camera_device *icd, unsigned int idx,
1252 struct soc_camera_format_xlate *xlate)
1253{
1254 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1255 struct device *dev = icd->parent;
1256 int formats = 0, ret;
1257 struct pxa_cam *cam;
1258 enum v4l2_mbus_pixelcode code;
1259 const struct soc_mbus_pixelfmt *fmt;
1260
1261 ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code);
1262 if (ret < 0)
1263 /* No more formats */
1264 return 0;
1265
1266 fmt = soc_mbus_get_fmtdesc(code);
1267 if (!fmt) {
1268 dev_err(dev, "Invalid format code #%u: %d\n", idx, code);
1269 return 0;
1270 }
1271
1272 /* This also checks support for the requested bits-per-sample */
1273 ret = pxa_camera_try_bus_param(icd, fmt->bits_per_sample);
1274 if (ret < 0)
1275 return 0;
1276
1277 if (!icd->host_priv) {
1278 cam = kzalloc(sizeof(*cam), GFP_KERNEL);
1279 if (!cam)
1280 return -ENOMEM;
1281
1282 icd->host_priv = cam;
1283 } else {
1284 cam = icd->host_priv;
1285 }
1286
1287 switch (code) {
1288 case V4L2_MBUS_FMT_UYVY8_2X8:
1289 formats++;
1290 if (xlate) {
1291 xlate->host_fmt = &pxa_camera_formats[0];
1292 xlate->code = code;
1293 xlate++;
1294 dev_dbg(dev, "Providing format %s using code %d\n",
1295 pxa_camera_formats[0].name, code);
1296 }
1297 case V4L2_MBUS_FMT_VYUY8_2X8:
1298 case V4L2_MBUS_FMT_YUYV8_2X8:
1299 case V4L2_MBUS_FMT_YVYU8_2X8:
1300 case V4L2_MBUS_FMT_RGB565_2X8_LE:
1301 case V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE:
1302 if (xlate)
1303 dev_dbg(dev, "Providing format %s packed\n",
1304 fmt->name);
1305 break;
1306 default:
1307 if (!pxa_camera_packing_supported(fmt))
1308 return 0;
1309 if (xlate)
1310 dev_dbg(dev,
1311 "Providing format %s in pass-through mode\n",
1312 fmt->name);
1313 }
1314
1315 /* Generic pass-through */
1316 formats++;
1317 if (xlate) {
1318 xlate->host_fmt = fmt;
1319 xlate->code = code;
1320 xlate++;
1321 }
1322
1323 return formats;
1324}
1325
1326static void pxa_camera_put_formats(struct soc_camera_device *icd)
1327{
1328 kfree(icd->host_priv);
1329 icd->host_priv = NULL;
1330}
1331
1332static int pxa_camera_check_frame(u32 width, u32 height)
1333{
1334 /* limit to pxa hardware capabilities */
1335 return height < 32 || height > 2048 || width < 48 || width > 2048 ||
1336 (width & 0x01);
1337}
1338
1339static int pxa_camera_set_crop(struct soc_camera_device *icd,
1340 struct v4l2_crop *a)
1341{
1342 struct v4l2_rect *rect = &a->c;
1343 struct device *dev = icd->parent;
1344 struct soc_camera_host *ici = to_soc_camera_host(dev);
1345 struct pxa_camera_dev *pcdev = ici->priv;
1346 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1347 struct soc_camera_sense sense = {
1348 .master_clock = pcdev->mclk,
1349 .pixel_clock_max = pcdev->ciclk / 4,
1350 };
1351 struct v4l2_mbus_framefmt mf;
1352 struct pxa_cam *cam = icd->host_priv;
1353 u32 fourcc = icd->current_fmt->host_fmt->fourcc;
1354 int ret;
1355
1356 /* If PCLK is used to latch data from the sensor, check sense */
1357 if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN)
1358 icd->sense = &sense;
1359
1360 ret = v4l2_subdev_call(sd, video, s_crop, a);
1361
1362 icd->sense = NULL;
1363
1364 if (ret < 0) {
1365 dev_warn(dev, "Failed to crop to %ux%u@%u:%u\n",
1366 rect->width, rect->height, rect->left, rect->top);
1367 return ret;
1368 }
1369
1370 ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf);
1371 if (ret < 0)
1372 return ret;
1373
1374 if (pxa_camera_check_frame(mf.width, mf.height)) {
1375 /*
1376 * Camera cropping produced a frame beyond our capabilities.
1377 * FIXME: just extract a subframe, that we can process.
1378 */
1379 v4l_bound_align_image(&mf.width, 48, 2048, 1,
1380 &mf.height, 32, 2048, 0,
1381 fourcc == V4L2_PIX_FMT_YUV422P ? 4 : 0);
1382 ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
1383 if (ret < 0)
1384 return ret;
1385
1386 if (pxa_camera_check_frame(mf.width, mf.height)) {
1387 dev_warn(icd->parent,
1388 "Inconsistent state. Use S_FMT to repair\n");
1389 return -EINVAL;
1390 }
1391 }
1392
1393 if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) {
1394 if (sense.pixel_clock > sense.pixel_clock_max) {
1395 dev_err(dev,
1396 "pixel clock %lu set by the camera too high!",
1397 sense.pixel_clock);
1398 return -EIO;
1399 }
1400 recalculate_fifo_timeout(pcdev, sense.pixel_clock);
1401 }
1402
1403 icd->user_width = mf.width;
1404 icd->user_height = mf.height;
1405
1406 pxa_camera_setup_cicr(icd, cam->flags, fourcc);
1407
1408 return ret;
1409}
1410
1411static int pxa_camera_set_fmt(struct soc_camera_device *icd,
1412 struct v4l2_format *f)
1413{
1414 struct device *dev = icd->parent;
1415 struct soc_camera_host *ici = to_soc_camera_host(dev);
1416 struct pxa_camera_dev *pcdev = ici->priv;
1417 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1418 const struct soc_camera_format_xlate *xlate = NULL;
1419 struct soc_camera_sense sense = {
1420 .master_clock = pcdev->mclk,
1421 .pixel_clock_max = pcdev->ciclk / 4,
1422 };
1423 struct v4l2_pix_format *pix = &f->fmt.pix;
1424 struct v4l2_mbus_framefmt mf;
1425 int ret;
1426
1427 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
1428 if (!xlate) {
1429 dev_warn(dev, "Format %x not found\n", pix->pixelformat);
1430 return -EINVAL;
1431 }
1432
1433 /* If PCLK is used to latch data from the sensor, check sense */
1434 if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN)
1435 /* The caller holds a mutex. */
1436 icd->sense = &sense;
1437
1438 mf.width = pix->width;
1439 mf.height = pix->height;
1440 mf.field = pix->field;
1441 mf.colorspace = pix->colorspace;
1442 mf.code = xlate->code;
1443
1444 ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
1445
1446 if (mf.code != xlate->code)
1447 return -EINVAL;
1448
1449 icd->sense = NULL;
1450
1451 if (ret < 0) {
1452 dev_warn(dev, "Failed to configure for format %x\n",
1453 pix->pixelformat);
1454 } else if (pxa_camera_check_frame(mf.width, mf.height)) {
1455 dev_warn(dev,
1456 "Camera driver produced an unsupported frame %dx%d\n",
1457 mf.width, mf.height);
1458 ret = -EINVAL;
1459 } else if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) {
1460 if (sense.pixel_clock > sense.pixel_clock_max) {
1461 dev_err(dev,
1462 "pixel clock %lu set by the camera too high!",
1463 sense.pixel_clock);
1464 return -EIO;
1465 }
1466 recalculate_fifo_timeout(pcdev, sense.pixel_clock);
1467 }
1468
1469 if (ret < 0)
1470 return ret;
1471
1472 pix->width = mf.width;
1473 pix->height = mf.height;
1474 pix->field = mf.field;
1475 pix->colorspace = mf.colorspace;
1476 icd->current_fmt = xlate;
1477
1478 return ret;
1479}
1480
1481static int pxa_camera_try_fmt(struct soc_camera_device *icd,
1482 struct v4l2_format *f)
1483{
1484 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1485 const struct soc_camera_format_xlate *xlate;
1486 struct v4l2_pix_format *pix = &f->fmt.pix;
1487 struct v4l2_mbus_framefmt mf;
1488 __u32 pixfmt = pix->pixelformat;
1489 int ret;
1490
1491 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
1492 if (!xlate) {
1493 dev_warn(icd->parent, "Format %x not found\n", pixfmt);
1494 return -EINVAL;
1495 }
1496
1497 /*
1498 * Limit to pxa hardware capabilities. YUV422P planar format requires
1499 * images size to be a multiple of 16 bytes. If not, zeros will be
1500 * inserted between Y and U planes, and U and V planes, which violates
1501 * the YUV422P standard.
1502 */
1503 v4l_bound_align_image(&pix->width, 48, 2048, 1,
1504 &pix->height, 32, 2048, 0,
1505 pixfmt == V4L2_PIX_FMT_YUV422P ? 4 : 0);
1506
1507 /* limit to sensor capabilities */
1508 mf.width = pix->width;
1509 mf.height = pix->height;
1510 /* Only progressive video supported so far */
1511 mf.field = V4L2_FIELD_NONE;
1512 mf.colorspace = pix->colorspace;
1513 mf.code = xlate->code;
1514
1515 ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
1516 if (ret < 0)
1517 return ret;
1518
1519 pix->width = mf.width;
1520 pix->height = mf.height;
1521 pix->colorspace = mf.colorspace;
1522
1523 switch (mf.field) {
1524 case V4L2_FIELD_ANY:
1525 case V4L2_FIELD_NONE:
1526 pix->field = V4L2_FIELD_NONE;
1527 break;
1528 default:
1529 /* TODO: support interlaced at least in pass-through mode */
1530 dev_err(icd->parent, "Field type %d unsupported.\n",
1531 mf.field);
1532 return -EINVAL;
1533 }
1534
1535 return ret;
1536}
1537
1538static int pxa_camera_reqbufs(struct soc_camera_device *icd,
1539 struct v4l2_requestbuffers *p)
1540{
1541 int i;
1542
1543 /*
1544 * This is for locking debugging only. I removed spinlocks and now I
1545 * check whether .prepare is ever called on a linked buffer, or whether
1546 * a dma IRQ can occur for an in-work or unlinked buffer. Until now
1547 * it hadn't triggered
1548 */
1549 for (i = 0; i < p->count; i++) {
1550 struct pxa_buffer *buf = container_of(icd->vb_vidq.bufs[i],
1551 struct pxa_buffer, vb);
1552 buf->inwork = 0;
1553 INIT_LIST_HEAD(&buf->vb.queue);
1554 }
1555
1556 return 0;
1557}
1558
1559static unsigned int pxa_camera_poll(struct file *file, poll_table *pt)
1560{
1561 struct soc_camera_device *icd = file->private_data;
1562 struct pxa_buffer *buf;
1563
1564 buf = list_entry(icd->vb_vidq.stream.next, struct pxa_buffer,
1565 vb.stream);
1566
1567 poll_wait(file, &buf->vb.done, pt);
1568
1569 if (buf->vb.state == VIDEOBUF_DONE ||
1570 buf->vb.state == VIDEOBUF_ERROR)
1571 return POLLIN|POLLRDNORM;
1572
1573 return 0;
1574}
1575
1576static int pxa_camera_querycap(struct soc_camera_host *ici,
1577 struct v4l2_capability *cap)
1578{
1579 /* cap->name is set by the firendly caller:-> */
1580 strlcpy(cap->card, pxa_cam_driver_description, sizeof(cap->card));
1581 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
1582
1583 return 0;
1584}
1585
1586static int pxa_camera_suspend(struct device *dev)
1587{
1588 struct soc_camera_host *ici = to_soc_camera_host(dev);
1589 struct pxa_camera_dev *pcdev = ici->priv;
1590 int i = 0, ret = 0;
1591
1592 pcdev->save_cicr[i++] = __raw_readl(pcdev->base + CICR0);
1593 pcdev->save_cicr[i++] = __raw_readl(pcdev->base + CICR1);
1594 pcdev->save_cicr[i++] = __raw_readl(pcdev->base + CICR2);
1595 pcdev->save_cicr[i++] = __raw_readl(pcdev->base + CICR3);
1596 pcdev->save_cicr[i++] = __raw_readl(pcdev->base + CICR4);
1597
1598 if (pcdev->icd) {
1599 struct v4l2_subdev *sd = soc_camera_to_subdev(pcdev->icd);
1600 ret = v4l2_subdev_call(sd, core, s_power, 0);
1601 if (ret == -ENOIOCTLCMD)
1602 ret = 0;
1603 }
1604
1605 return ret;
1606}
1607
1608static int pxa_camera_resume(struct device *dev)
1609{
1610 struct soc_camera_host *ici = to_soc_camera_host(dev);
1611 struct pxa_camera_dev *pcdev = ici->priv;
1612 int i = 0, ret = 0;
1613
1614 DRCMR(68) = pcdev->dma_chans[0] | DRCMR_MAPVLD;
1615 DRCMR(69) = pcdev->dma_chans[1] | DRCMR_MAPVLD;
1616 DRCMR(70) = pcdev->dma_chans[2] | DRCMR_MAPVLD;
1617
1618 __raw_writel(pcdev->save_cicr[i++] & ~CICR0_ENB, pcdev->base + CICR0);
1619 __raw_writel(pcdev->save_cicr[i++], pcdev->base + CICR1);
1620 __raw_writel(pcdev->save_cicr[i++], pcdev->base + CICR2);
1621 __raw_writel(pcdev->save_cicr[i++], pcdev->base + CICR3);
1622 __raw_writel(pcdev->save_cicr[i++], pcdev->base + CICR4);
1623
1624 if (pcdev->icd) {
1625 struct v4l2_subdev *sd = soc_camera_to_subdev(pcdev->icd);
1626 ret = v4l2_subdev_call(sd, core, s_power, 1);
1627 if (ret == -ENOIOCTLCMD)
1628 ret = 0;
1629 }
1630
1631 /* Restart frame capture if active buffer exists */
1632 if (!ret && pcdev->active)
1633 pxa_camera_start_capture(pcdev);
1634
1635 return ret;
1636}
1637
1638static struct soc_camera_host_ops pxa_soc_camera_host_ops = {
1639 .owner = THIS_MODULE,
1640 .add = pxa_camera_add_device,
1641 .remove = pxa_camera_remove_device,
1642 .set_crop = pxa_camera_set_crop,
1643 .get_formats = pxa_camera_get_formats,
1644 .put_formats = pxa_camera_put_formats,
1645 .set_fmt = pxa_camera_set_fmt,
1646 .try_fmt = pxa_camera_try_fmt,
1647 .init_videobuf = pxa_camera_init_videobuf,
1648 .reqbufs = pxa_camera_reqbufs,
1649 .poll = pxa_camera_poll,
1650 .querycap = pxa_camera_querycap,
1651 .set_bus_param = pxa_camera_set_bus_param,
1652};
1653
1654static int __devinit pxa_camera_probe(struct platform_device *pdev)
1655{
1656 struct pxa_camera_dev *pcdev;
1657 struct resource *res;
1658 void __iomem *base;
1659 int irq;
1660 int err = 0;
1661
1662 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1663 irq = platform_get_irq(pdev, 0);
1664 if (!res || irq < 0) {
1665 err = -ENODEV;
1666 goto exit;
1667 }
1668
1669 pcdev = kzalloc(sizeof(*pcdev), GFP_KERNEL);
1670 if (!pcdev) {
1671 dev_err(&pdev->dev, "Could not allocate pcdev\n");
1672 err = -ENOMEM;
1673 goto exit;
1674 }
1675
1676 pcdev->clk = clk_get(&pdev->dev, NULL);
1677 if (IS_ERR(pcdev->clk)) {
1678 err = PTR_ERR(pcdev->clk);
1679 goto exit_kfree;
1680 }
1681
1682 pcdev->res = res;
1683
1684 pcdev->pdata = pdev->dev.platform_data;
1685 pcdev->platform_flags = pcdev->pdata->flags;
1686 if (!(pcdev->platform_flags & (PXA_CAMERA_DATAWIDTH_8 |
1687 PXA_CAMERA_DATAWIDTH_9 | PXA_CAMERA_DATAWIDTH_10))) {
1688 /*
1689 * Platform hasn't set available data widths. This is bad.
1690 * Warn and use a default.
1691 */
1692 dev_warn(&pdev->dev, "WARNING! Platform hasn't set available "
1693 "data widths, using default 10 bit\n");
1694 pcdev->platform_flags |= PXA_CAMERA_DATAWIDTH_10;
1695 }
1696 if (pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_8)
1697 pcdev->width_flags = 1 << 7;
1698 if (pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_9)
1699 pcdev->width_flags |= 1 << 8;
1700 if (pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_10)
1701 pcdev->width_flags |= 1 << 9;
1702 pcdev->mclk = pcdev->pdata->mclk_10khz * 10000;
1703 if (!pcdev->mclk) {
1704 dev_warn(&pdev->dev,
1705 "mclk == 0! Please, fix your platform data. "
1706 "Using default 20MHz\n");
1707 pcdev->mclk = 20000000;
1708 }
1709
1710 pcdev->mclk_divisor = mclk_get_divisor(pdev, pcdev);
1711
1712 INIT_LIST_HEAD(&pcdev->capture);
1713 spin_lock_init(&pcdev->lock);
1714
1715 /*
1716 * Request the regions.
1717 */
1718 if (!request_mem_region(res->start, resource_size(res),
1719 PXA_CAM_DRV_NAME)) {
1720 err = -EBUSY;
1721 goto exit_clk;
1722 }
1723
1724 base = ioremap(res->start, resource_size(res));
1725 if (!base) {
1726 err = -ENOMEM;
1727 goto exit_release;
1728 }
1729 pcdev->irq = irq;
1730 pcdev->base = base;
1731
1732 /* request dma */
1733 err = pxa_request_dma("CI_Y", DMA_PRIO_HIGH,
1734 pxa_camera_dma_irq_y, pcdev);
1735 if (err < 0) {
1736 dev_err(&pdev->dev, "Can't request DMA for Y\n");
1737 goto exit_iounmap;
1738 }
1739 pcdev->dma_chans[0] = err;
1740 dev_dbg(&pdev->dev, "got DMA channel %d\n", pcdev->dma_chans[0]);
1741
1742 err = pxa_request_dma("CI_U", DMA_PRIO_HIGH,
1743 pxa_camera_dma_irq_u, pcdev);
1744 if (err < 0) {
1745 dev_err(&pdev->dev, "Can't request DMA for U\n");
1746 goto exit_free_dma_y;
1747 }
1748 pcdev->dma_chans[1] = err;
1749 dev_dbg(&pdev->dev, "got DMA channel (U) %d\n", pcdev->dma_chans[1]);
1750
1751 err = pxa_request_dma("CI_V", DMA_PRIO_HIGH,
1752 pxa_camera_dma_irq_v, pcdev);
1753 if (err < 0) {
1754 dev_err(&pdev->dev, "Can't request DMA for V\n");
1755 goto exit_free_dma_u;
1756 }
1757 pcdev->dma_chans[2] = err;
1758 dev_dbg(&pdev->dev, "got DMA channel (V) %d\n", pcdev->dma_chans[2]);
1759
1760 DRCMR(68) = pcdev->dma_chans[0] | DRCMR_MAPVLD;
1761 DRCMR(69) = pcdev->dma_chans[1] | DRCMR_MAPVLD;
1762 DRCMR(70) = pcdev->dma_chans[2] | DRCMR_MAPVLD;
1763
1764 /* request irq */
1765 err = request_irq(pcdev->irq, pxa_camera_irq, 0, PXA_CAM_DRV_NAME,
1766 pcdev);
1767 if (err) {
1768 dev_err(&pdev->dev, "Camera interrupt register failed \n");
1769 goto exit_free_dma;
1770 }
1771
1772 pcdev->soc_host.drv_name = PXA_CAM_DRV_NAME;
1773 pcdev->soc_host.ops = &pxa_soc_camera_host_ops;
1774 pcdev->soc_host.priv = pcdev;
1775 pcdev->soc_host.v4l2_dev.dev = &pdev->dev;
1776 pcdev->soc_host.nr = pdev->id;
1777
1778 err = soc_camera_host_register(&pcdev->soc_host);
1779 if (err)
1780 goto exit_free_irq;
1781
1782 return 0;
1783
1784exit_free_irq:
1785 free_irq(pcdev->irq, pcdev);
1786exit_free_dma:
1787 pxa_free_dma(pcdev->dma_chans[2]);
1788exit_free_dma_u:
1789 pxa_free_dma(pcdev->dma_chans[1]);
1790exit_free_dma_y:
1791 pxa_free_dma(pcdev->dma_chans[0]);
1792exit_iounmap:
1793 iounmap(base);
1794exit_release:
1795 release_mem_region(res->start, resource_size(res));
1796exit_clk:
1797 clk_put(pcdev->clk);
1798exit_kfree:
1799 kfree(pcdev);
1800exit:
1801 return err;
1802}
1803
1804static int __devexit pxa_camera_remove(struct platform_device *pdev)
1805{
1806 struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev);
1807 struct pxa_camera_dev *pcdev = container_of(soc_host,
1808 struct pxa_camera_dev, soc_host);
1809 struct resource *res;
1810
1811 clk_put(pcdev->clk);
1812
1813 pxa_free_dma(pcdev->dma_chans[0]);
1814 pxa_free_dma(pcdev->dma_chans[1]);
1815 pxa_free_dma(pcdev->dma_chans[2]);
1816 free_irq(pcdev->irq, pcdev);
1817
1818 soc_camera_host_unregister(soc_host);
1819
1820 iounmap(pcdev->base);
1821
1822 res = pcdev->res;
1823 release_mem_region(res->start, resource_size(res));
1824
1825 kfree(pcdev);
1826
1827 dev_info(&pdev->dev, "PXA Camera driver unloaded\n");
1828
1829 return 0;
1830}
1831
1832static struct dev_pm_ops pxa_camera_pm = {
1833 .suspend = pxa_camera_suspend,
1834 .resume = pxa_camera_resume,
1835};
1836
1837static struct platform_driver pxa_camera_driver = {
1838 .driver = {
1839 .name = PXA_CAM_DRV_NAME,
1840 .pm = &pxa_camera_pm,
1841 },
1842 .probe = pxa_camera_probe,
1843 .remove = __devexit_p(pxa_camera_remove),
1844};
1845
1846module_platform_driver(pxa_camera_driver);
1847
1848MODULE_DESCRIPTION("PXA27x SoC Camera Host driver");
1849MODULE_AUTHOR("Guennadi Liakhovetski <kernel@pengutronix.de>");
1850MODULE_LICENSE("GPL");
1851MODULE_VERSION(PXA_CAM_VERSION);
1852MODULE_ALIAS("platform:" PXA_CAM_DRV_NAME);
diff --git a/drivers/media/video/s5p-fimc/Kconfig b/drivers/media/video/s5p-fimc/Kconfig
deleted file mode 100644
index a564f7eeb064..000000000000
--- a/drivers/media/video/s5p-fimc/Kconfig
+++ /dev/null
@@ -1,48 +0,0 @@
1
2config VIDEO_SAMSUNG_S5P_FIMC
3 bool "Samsung S5P/EXYNOS SoC camera interface driver (experimental)"
4 depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && PLAT_S5P && PM_RUNTIME
5 depends on EXPERIMENTAL
6 help
7 Say Y here to enable camera host interface devices for
8 Samsung S5P and EXYNOS SoC series.
9
10if VIDEO_SAMSUNG_S5P_FIMC
11
12config VIDEO_S5P_FIMC
13 tristate "S5P/EXYNOS4 FIMC/CAMIF camera interface driver"
14 depends on I2C
15 select VIDEOBUF2_DMA_CONTIG
16 select V4L2_MEM2MEM_DEV
17 help
18 This is a V4L2 driver for Samsung S5P and EXYNOS4 SoC camera host
19 interface and video postprocessor (FIMC and FIMC-LITE) devices.
20
21 To compile this driver as a module, choose M here: the
22 module will be called s5p-fimc.
23
24config VIDEO_S5P_MIPI_CSIS
25 tristate "S5P/EXYNOS MIPI-CSI2 receiver (MIPI-CSIS) driver"
26 depends on REGULATOR
27 help
28 This is a V4L2 driver for Samsung S5P and EXYNOS4 SoC MIPI-CSI2
29 receiver (MIPI-CSIS) devices.
30
31 To compile this driver as a module, choose M here: the
32 module will be called s5p-csis.
33
34if ARCH_EXYNOS
35
36config VIDEO_EXYNOS_FIMC_LITE
37 tristate "EXYNOS FIMC-LITE camera interface driver"
38 depends on I2C
39 select VIDEOBUF2_DMA_CONTIG
40 help
41 This is a V4L2 driver for Samsung EXYNOS4/5 SoC FIMC-LITE camera
42 host interface.
43
44 To compile this driver as a module, choose M here: the
45 module will be called exynos-fimc-lite.
46endif
47
48endif # VIDEO_SAMSUNG_S5P_FIMC
diff --git a/drivers/media/video/s5p-fimc/Makefile b/drivers/media/video/s5p-fimc/Makefile
deleted file mode 100644
index 46485143e1ca..000000000000
--- a/drivers/media/video/s5p-fimc/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
1s5p-fimc-objs := fimc-core.o fimc-reg.o fimc-m2m.o fimc-capture.o fimc-mdevice.o
2exynos-fimc-lite-objs += fimc-lite-reg.o fimc-lite.o
3s5p-csis-objs := mipi-csis.o
4
5obj-$(CONFIG_VIDEO_S5P_MIPI_CSIS) += s5p-csis.o
6obj-$(CONFIG_VIDEO_EXYNOS_FIMC_LITE) += exynos-fimc-lite.o
7obj-$(CONFIG_VIDEO_S5P_FIMC) += s5p-fimc.o
diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c
deleted file mode 100644
index 8e413dd3c0b0..000000000000
--- a/drivers/media/video/s5p-fimc/fimc-capture.c
+++ /dev/null
@@ -1,1738 +0,0 @@
1/*
2 * Samsung S5P/EXYNOS4 SoC series camera interface (camera capture) driver
3 *
4 * Copyright (C) 2010 - 2012 Samsung Electronics Co., Ltd.
5 * Sylwester Nawrocki <s.nawrocki@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/module.h>
13#include <linux/kernel.h>
14#include <linux/types.h>
15#include <linux/errno.h>
16#include <linux/bug.h>
17#include <linux/interrupt.h>
18#include <linux/device.h>
19#include <linux/pm_runtime.h>
20#include <linux/list.h>
21#include <linux/slab.h>
22
23#include <linux/videodev2.h>
24#include <media/v4l2-device.h>
25#include <media/v4l2-ioctl.h>
26#include <media/v4l2-mem2mem.h>
27#include <media/videobuf2-core.h>
28#include <media/videobuf2-dma-contig.h>
29
30#include "fimc-mdevice.h"
31#include "fimc-core.h"
32#include "fimc-reg.h"
33
34static int fimc_capture_hw_init(struct fimc_dev *fimc)
35{
36 struct fimc_ctx *ctx = fimc->vid_cap.ctx;
37 struct fimc_pipeline *p = &fimc->pipeline;
38 struct fimc_sensor_info *sensor;
39 unsigned long flags;
40 int ret = 0;
41
42 if (p->subdevs[IDX_SENSOR] == NULL || ctx == NULL)
43 return -ENXIO;
44 if (ctx->s_frame.fmt == NULL)
45 return -EINVAL;
46
47 sensor = v4l2_get_subdev_hostdata(p->subdevs[IDX_SENSOR]);
48
49 spin_lock_irqsave(&fimc->slock, flags);
50 fimc_prepare_dma_offset(ctx, &ctx->d_frame);
51 fimc_set_yuv_order(ctx);
52
53 fimc_hw_set_camera_polarity(fimc, sensor->pdata);
54 fimc_hw_set_camera_type(fimc, sensor->pdata);
55 fimc_hw_set_camera_source(fimc, sensor->pdata);
56 fimc_hw_set_camera_offset(fimc, &ctx->s_frame);
57
58 ret = fimc_set_scaler_info(ctx);
59 if (!ret) {
60 fimc_hw_set_input_path(ctx);
61 fimc_hw_set_prescaler(ctx);
62 fimc_hw_set_mainscaler(ctx);
63 fimc_hw_set_target_format(ctx);
64 fimc_hw_set_rotation(ctx);
65 fimc_hw_set_effect(ctx);
66 fimc_hw_set_output_path(ctx);
67 fimc_hw_set_out_dma(ctx);
68 if (fimc->variant->has_alpha)
69 fimc_hw_set_rgb_alpha(ctx);
70 clear_bit(ST_CAPT_APPLY_CFG, &fimc->state);
71 }
72 spin_unlock_irqrestore(&fimc->slock, flags);
73 return ret;
74}
75
76/*
77 * Reinitialize the driver so it is ready to start the streaming again.
78 * Set fimc->state to indicate stream off and the hardware shut down state.
79 * If not suspending (@suspend is false), return any buffers to videobuf2.
80 * Otherwise put any owned buffers onto the pending buffers queue, so they
81 * can be re-spun when the device is being resumed. Also perform FIMC
82 * software reset and disable streaming on the whole pipeline if required.
83 */
84static int fimc_capture_state_cleanup(struct fimc_dev *fimc, bool suspend)
85{
86 struct fimc_vid_cap *cap = &fimc->vid_cap;
87 struct fimc_vid_buffer *buf;
88 unsigned long flags;
89 bool streaming;
90
91 spin_lock_irqsave(&fimc->slock, flags);
92 streaming = fimc->state & (1 << ST_CAPT_ISP_STREAM);
93
94 fimc->state &= ~(1 << ST_CAPT_RUN | 1 << ST_CAPT_SHUT |
95 1 << ST_CAPT_STREAM | 1 << ST_CAPT_ISP_STREAM);
96 if (suspend)
97 fimc->state |= (1 << ST_CAPT_SUSPENDED);
98 else
99 fimc->state &= ~(1 << ST_CAPT_PEND | 1 << ST_CAPT_SUSPENDED);
100
101 /* Release unused buffers */
102 while (!suspend && !list_empty(&cap->pending_buf_q)) {
103 buf = fimc_pending_queue_pop(cap);
104 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
105 }
106 /* If suspending put unused buffers onto pending queue */
107 while (!list_empty(&cap->active_buf_q)) {
108 buf = fimc_active_queue_pop(cap);
109 if (suspend)
110 fimc_pending_queue_add(cap, buf);
111 else
112 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
113 }
114
115 fimc_hw_reset(fimc);
116 cap->buf_index = 0;
117
118 spin_unlock_irqrestore(&fimc->slock, flags);
119
120 if (streaming)
121 return fimc_pipeline_s_stream(&fimc->pipeline, 0);
122 else
123 return 0;
124}
125
126static int fimc_stop_capture(struct fimc_dev *fimc, bool suspend)
127{
128 unsigned long flags;
129
130 if (!fimc_capture_active(fimc))
131 return 0;
132
133 spin_lock_irqsave(&fimc->slock, flags);
134 set_bit(ST_CAPT_SHUT, &fimc->state);
135 fimc_deactivate_capture(fimc);
136 spin_unlock_irqrestore(&fimc->slock, flags);
137
138 wait_event_timeout(fimc->irq_queue,
139 !test_bit(ST_CAPT_SHUT, &fimc->state),
140 (2*HZ/10)); /* 200 ms */
141
142 return fimc_capture_state_cleanup(fimc, suspend);
143}
144
145/**
146 * fimc_capture_config_update - apply the camera interface configuration
147 *
148 * To be called from within the interrupt handler with fimc.slock
149 * spinlock held. It updates the camera pixel crop, rotation and
150 * image flip in H/W.
151 */
152static int fimc_capture_config_update(struct fimc_ctx *ctx)
153{
154 struct fimc_dev *fimc = ctx->fimc_dev;
155 int ret;
156
157 fimc_hw_set_camera_offset(fimc, &ctx->s_frame);
158
159 ret = fimc_set_scaler_info(ctx);
160 if (ret)
161 return ret;
162
163 fimc_hw_set_prescaler(ctx);
164 fimc_hw_set_mainscaler(ctx);
165 fimc_hw_set_target_format(ctx);
166 fimc_hw_set_rotation(ctx);
167 fimc_hw_set_effect(ctx);
168 fimc_prepare_dma_offset(ctx, &ctx->d_frame);
169 fimc_hw_set_out_dma(ctx);
170 if (fimc->variant->has_alpha)
171 fimc_hw_set_rgb_alpha(ctx);
172
173 clear_bit(ST_CAPT_APPLY_CFG, &fimc->state);
174 return ret;
175}
176
177void fimc_capture_irq_handler(struct fimc_dev *fimc, int deq_buf)
178{
179 struct fimc_vid_cap *cap = &fimc->vid_cap;
180 struct fimc_vid_buffer *v_buf;
181 struct timeval *tv;
182 struct timespec ts;
183
184 if (test_and_clear_bit(ST_CAPT_SHUT, &fimc->state)) {
185 wake_up(&fimc->irq_queue);
186 goto done;
187 }
188
189 if (!list_empty(&cap->active_buf_q) &&
190 test_bit(ST_CAPT_RUN, &fimc->state) && deq_buf) {
191 ktime_get_real_ts(&ts);
192
193 v_buf = fimc_active_queue_pop(cap);
194
195 tv = &v_buf->vb.v4l2_buf.timestamp;
196 tv->tv_sec = ts.tv_sec;
197 tv->tv_usec = ts.tv_nsec / NSEC_PER_USEC;
198 v_buf->vb.v4l2_buf.sequence = cap->frame_count++;
199
200 vb2_buffer_done(&v_buf->vb, VB2_BUF_STATE_DONE);
201 }
202
203 if (!list_empty(&cap->pending_buf_q)) {
204
205 v_buf = fimc_pending_queue_pop(cap);
206 fimc_hw_set_output_addr(fimc, &v_buf->paddr, cap->buf_index);
207 v_buf->index = cap->buf_index;
208
209 /* Move the buffer to the capture active queue */
210 fimc_active_queue_add(cap, v_buf);
211
212 dbg("next frame: %d, done frame: %d",
213 fimc_hw_get_frame_index(fimc), v_buf->index);
214
215 if (++cap->buf_index >= FIMC_MAX_OUT_BUFS)
216 cap->buf_index = 0;
217 }
218
219 if (cap->active_buf_cnt == 0) {
220 if (deq_buf)
221 clear_bit(ST_CAPT_RUN, &fimc->state);
222
223 if (++cap->buf_index >= FIMC_MAX_OUT_BUFS)
224 cap->buf_index = 0;
225 } else {
226 set_bit(ST_CAPT_RUN, &fimc->state);
227 }
228
229 if (test_bit(ST_CAPT_APPLY_CFG, &fimc->state))
230 fimc_capture_config_update(cap->ctx);
231done:
232 if (cap->active_buf_cnt == 1) {
233 fimc_deactivate_capture(fimc);
234 clear_bit(ST_CAPT_STREAM, &fimc->state);
235 }
236
237 dbg("frame: %d, active_buf_cnt: %d",
238 fimc_hw_get_frame_index(fimc), cap->active_buf_cnt);
239}
240
241
242static int start_streaming(struct vb2_queue *q, unsigned int count)
243{
244 struct fimc_ctx *ctx = q->drv_priv;
245 struct fimc_dev *fimc = ctx->fimc_dev;
246 struct fimc_vid_cap *vid_cap = &fimc->vid_cap;
247 int min_bufs;
248 int ret;
249
250 vid_cap->frame_count = 0;
251
252 ret = fimc_capture_hw_init(fimc);
253 if (ret) {
254 fimc_capture_state_cleanup(fimc, false);
255 return ret;
256 }
257
258 set_bit(ST_CAPT_PEND, &fimc->state);
259
260 min_bufs = fimc->vid_cap.reqbufs_count > 1 ? 2 : 1;
261
262 if (vid_cap->active_buf_cnt >= min_bufs &&
263 !test_and_set_bit(ST_CAPT_STREAM, &fimc->state)) {
264 fimc_activate_capture(ctx);
265
266 if (!test_and_set_bit(ST_CAPT_ISP_STREAM, &fimc->state))
267 fimc_pipeline_s_stream(&fimc->pipeline, 1);
268 }
269
270 return 0;
271}
272
273static int stop_streaming(struct vb2_queue *q)
274{
275 struct fimc_ctx *ctx = q->drv_priv;
276 struct fimc_dev *fimc = ctx->fimc_dev;
277
278 if (!fimc_capture_active(fimc))
279 return -EINVAL;
280
281 return fimc_stop_capture(fimc, false);
282}
283
284int fimc_capture_suspend(struct fimc_dev *fimc)
285{
286 bool suspend = fimc_capture_busy(fimc);
287
288 int ret = fimc_stop_capture(fimc, suspend);
289 if (ret)
290 return ret;
291 return fimc_pipeline_shutdown(&fimc->pipeline);
292}
293
294static void buffer_queue(struct vb2_buffer *vb);
295
296int fimc_capture_resume(struct fimc_dev *fimc)
297{
298 struct fimc_vid_cap *vid_cap = &fimc->vid_cap;
299 struct fimc_vid_buffer *buf;
300 int i;
301
302 if (!test_and_clear_bit(ST_CAPT_SUSPENDED, &fimc->state))
303 return 0;
304
305 INIT_LIST_HEAD(&fimc->vid_cap.active_buf_q);
306 vid_cap->buf_index = 0;
307 fimc_pipeline_initialize(&fimc->pipeline, &vid_cap->vfd->entity,
308 false);
309 fimc_capture_hw_init(fimc);
310
311 clear_bit(ST_CAPT_SUSPENDED, &fimc->state);
312
313 for (i = 0; i < vid_cap->reqbufs_count; i++) {
314 if (list_empty(&vid_cap->pending_buf_q))
315 break;
316 buf = fimc_pending_queue_pop(vid_cap);
317 buffer_queue(&buf->vb);
318 }
319 return 0;
320
321}
322
323static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *pfmt,
324 unsigned int *num_buffers, unsigned int *num_planes,
325 unsigned int sizes[], void *allocators[])
326{
327 const struct v4l2_pix_format_mplane *pixm = NULL;
328 struct fimc_ctx *ctx = vq->drv_priv;
329 struct fimc_frame *frame = &ctx->d_frame;
330 struct fimc_fmt *fmt = frame->fmt;
331 unsigned long wh;
332 int i;
333
334 if (pfmt) {
335 pixm = &pfmt->fmt.pix_mp;
336 fmt = fimc_find_format(&pixm->pixelformat, NULL,
337 FMT_FLAGS_CAM | FMT_FLAGS_M2M, -1);
338 wh = pixm->width * pixm->height;
339 } else {
340 wh = frame->f_width * frame->f_height;
341 }
342
343 if (fmt == NULL)
344 return -EINVAL;
345
346 *num_planes = fmt->memplanes;
347
348 for (i = 0; i < fmt->memplanes; i++) {
349 unsigned int size = (wh * fmt->depth[i]) / 8;
350 if (pixm)
351 sizes[i] = max(size, pixm->plane_fmt[i].sizeimage);
352 else
353 sizes[i] = max_t(u32, size, frame->payload[i]);
354
355 allocators[i] = ctx->fimc_dev->alloc_ctx;
356 }
357
358 return 0;
359}
360
361static int buffer_prepare(struct vb2_buffer *vb)
362{
363 struct vb2_queue *vq = vb->vb2_queue;
364 struct fimc_ctx *ctx = vq->drv_priv;
365 int i;
366
367 if (ctx->d_frame.fmt == NULL)
368 return -EINVAL;
369
370 for (i = 0; i < ctx->d_frame.fmt->memplanes; i++) {
371 unsigned long size = ctx->d_frame.payload[i];
372
373 if (vb2_plane_size(vb, i) < size) {
374 v4l2_err(ctx->fimc_dev->vid_cap.vfd,
375 "User buffer too small (%ld < %ld)\n",
376 vb2_plane_size(vb, i), size);
377 return -EINVAL;
378 }
379 vb2_set_plane_payload(vb, i, size);
380 }
381
382 return 0;
383}
384
385static void buffer_queue(struct vb2_buffer *vb)
386{
387 struct fimc_vid_buffer *buf
388 = container_of(vb, struct fimc_vid_buffer, vb);
389 struct fimc_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
390 struct fimc_dev *fimc = ctx->fimc_dev;
391 struct fimc_vid_cap *vid_cap = &fimc->vid_cap;
392 unsigned long flags;
393 int min_bufs;
394
395 spin_lock_irqsave(&fimc->slock, flags);
396 fimc_prepare_addr(ctx, &buf->vb, &ctx->d_frame, &buf->paddr);
397
398 if (!test_bit(ST_CAPT_SUSPENDED, &fimc->state) &&
399 !test_bit(ST_CAPT_STREAM, &fimc->state) &&
400 vid_cap->active_buf_cnt < FIMC_MAX_OUT_BUFS) {
401 /* Setup the buffer directly for processing. */
402 int buf_id = (vid_cap->reqbufs_count == 1) ? -1 :
403 vid_cap->buf_index;
404
405 fimc_hw_set_output_addr(fimc, &buf->paddr, buf_id);
406 buf->index = vid_cap->buf_index;
407 fimc_active_queue_add(vid_cap, buf);
408
409 if (++vid_cap->buf_index >= FIMC_MAX_OUT_BUFS)
410 vid_cap->buf_index = 0;
411 } else {
412 fimc_pending_queue_add(vid_cap, buf);
413 }
414
415 min_bufs = vid_cap->reqbufs_count > 1 ? 2 : 1;
416
417
418 if (vb2_is_streaming(&vid_cap->vbq) &&
419 vid_cap->active_buf_cnt >= min_bufs &&
420 !test_and_set_bit(ST_CAPT_STREAM, &fimc->state)) {
421 fimc_activate_capture(ctx);
422 spin_unlock_irqrestore(&fimc->slock, flags);
423
424 if (!test_and_set_bit(ST_CAPT_ISP_STREAM, &fimc->state))
425 fimc_pipeline_s_stream(&fimc->pipeline, 1);
426 return;
427 }
428 spin_unlock_irqrestore(&fimc->slock, flags);
429}
430
431static void fimc_lock(struct vb2_queue *vq)
432{
433 struct fimc_ctx *ctx = vb2_get_drv_priv(vq);
434 mutex_lock(&ctx->fimc_dev->lock);
435}
436
437static void fimc_unlock(struct vb2_queue *vq)
438{
439 struct fimc_ctx *ctx = vb2_get_drv_priv(vq);
440 mutex_unlock(&ctx->fimc_dev->lock);
441}
442
443static struct vb2_ops fimc_capture_qops = {
444 .queue_setup = queue_setup,
445 .buf_prepare = buffer_prepare,
446 .buf_queue = buffer_queue,
447 .wait_prepare = fimc_unlock,
448 .wait_finish = fimc_lock,
449 .start_streaming = start_streaming,
450 .stop_streaming = stop_streaming,
451};
452
453/**
454 * fimc_capture_ctrls_create - initialize the control handler
455 * Initialize the capture video node control handler and fill it
456 * with the FIMC controls. Inherit any sensor's controls if the
457 * 'user_subdev_api' flag is false (default behaviour).
458 * This function need to be called with the graph mutex held.
459 */
460int fimc_capture_ctrls_create(struct fimc_dev *fimc)
461{
462 struct fimc_vid_cap *vid_cap = &fimc->vid_cap;
463 int ret;
464
465 if (WARN_ON(vid_cap->ctx == NULL))
466 return -ENXIO;
467 if (vid_cap->ctx->ctrls.ready)
468 return 0;
469
470 ret = fimc_ctrls_create(vid_cap->ctx);
471 if (ret || vid_cap->user_subdev_api || !vid_cap->ctx->ctrls.ready)
472 return ret;
473
474 return v4l2_ctrl_add_handler(&vid_cap->ctx->ctrls.handler,
475 fimc->pipeline.subdevs[IDX_SENSOR]->ctrl_handler);
476}
477
478static int fimc_capture_set_default_format(struct fimc_dev *fimc);
479
480static int fimc_capture_open(struct file *file)
481{
482 struct fimc_dev *fimc = video_drvdata(file);
483 int ret = -EBUSY;
484
485 dbg("pid: %d, state: 0x%lx", task_pid_nr(current), fimc->state);
486
487 if (mutex_lock_interruptible(&fimc->lock))
488 return -ERESTARTSYS;
489
490 if (fimc_m2m_active(fimc))
491 goto unlock;
492
493 set_bit(ST_CAPT_BUSY, &fimc->state);
494 ret = pm_runtime_get_sync(&fimc->pdev->dev);
495 if (ret < 0)
496 goto unlock;
497
498 ret = v4l2_fh_open(file);
499 if (ret) {
500 pm_runtime_put(&fimc->pdev->dev);
501 goto unlock;
502 }
503
504 if (++fimc->vid_cap.refcnt == 1) {
505 ret = fimc_pipeline_initialize(&fimc->pipeline,
506 &fimc->vid_cap.vfd->entity, true);
507
508 if (!ret && !fimc->vid_cap.user_subdev_api)
509 ret = fimc_capture_set_default_format(fimc);
510
511 if (!ret)
512 ret = fimc_capture_ctrls_create(fimc);
513
514 if (ret < 0) {
515 clear_bit(ST_CAPT_BUSY, &fimc->state);
516 pm_runtime_put_sync(&fimc->pdev->dev);
517 fimc->vid_cap.refcnt--;
518 v4l2_fh_release(file);
519 }
520 }
521unlock:
522 mutex_unlock(&fimc->lock);
523 return ret;
524}
525
526static int fimc_capture_close(struct file *file)
527{
528 struct fimc_dev *fimc = video_drvdata(file);
529 int ret;
530
531 dbg("pid: %d, state: 0x%lx", task_pid_nr(current), fimc->state);
532
533 if (mutex_lock_interruptible(&fimc->lock))
534 return -ERESTARTSYS;
535
536 if (--fimc->vid_cap.refcnt == 0) {
537 clear_bit(ST_CAPT_BUSY, &fimc->state);
538 fimc_stop_capture(fimc, false);
539 fimc_pipeline_shutdown(&fimc->pipeline);
540 clear_bit(ST_CAPT_SUSPENDED, &fimc->state);
541 }
542
543 pm_runtime_put(&fimc->pdev->dev);
544
545 if (fimc->vid_cap.refcnt == 0) {
546 vb2_queue_release(&fimc->vid_cap.vbq);
547 fimc_ctrls_delete(fimc->vid_cap.ctx);
548 }
549
550 ret = v4l2_fh_release(file);
551
552 mutex_unlock(&fimc->lock);
553 return ret;
554}
555
556static unsigned int fimc_capture_poll(struct file *file,
557 struct poll_table_struct *wait)
558{
559 struct fimc_dev *fimc = video_drvdata(file);
560 int ret;
561
562 if (mutex_lock_interruptible(&fimc->lock))
563 return POLL_ERR;
564
565 ret = vb2_poll(&fimc->vid_cap.vbq, file, wait);
566 mutex_unlock(&fimc->lock);
567
568 return ret;
569}
570
571static int fimc_capture_mmap(struct file *file, struct vm_area_struct *vma)
572{
573 struct fimc_dev *fimc = video_drvdata(file);
574 int ret;
575
576 if (mutex_lock_interruptible(&fimc->lock))
577 return -ERESTARTSYS;
578
579 ret = vb2_mmap(&fimc->vid_cap.vbq, vma);
580 mutex_unlock(&fimc->lock);
581
582 return ret;
583}
584
585static const struct v4l2_file_operations fimc_capture_fops = {
586 .owner = THIS_MODULE,
587 .open = fimc_capture_open,
588 .release = fimc_capture_close,
589 .poll = fimc_capture_poll,
590 .unlocked_ioctl = video_ioctl2,
591 .mmap = fimc_capture_mmap,
592};
593
594/*
595 * Format and crop negotiation helpers
596 */
597
598static struct fimc_fmt *fimc_capture_try_format(struct fimc_ctx *ctx,
599 u32 *width, u32 *height,
600 u32 *code, u32 *fourcc, int pad)
601{
602 bool rotation = ctx->rotation == 90 || ctx->rotation == 270;
603 struct fimc_dev *fimc = ctx->fimc_dev;
604 struct fimc_variant *var = fimc->variant;
605 struct fimc_pix_limit *pl = var->pix_limit;
606 struct fimc_frame *dst = &ctx->d_frame;
607 u32 depth, min_w, max_w, min_h, align_h = 3;
608 u32 mask = FMT_FLAGS_CAM;
609 struct fimc_fmt *ffmt;
610
611 /* Color conversion from/to JPEG is not supported */
612 if (code && ctx->s_frame.fmt && pad == FIMC_SD_PAD_SOURCE &&
613 fimc_fmt_is_jpeg(ctx->s_frame.fmt->color))
614 *code = V4L2_MBUS_FMT_JPEG_1X8;
615
616 if (fourcc && *fourcc != V4L2_PIX_FMT_JPEG && pad != FIMC_SD_PAD_SINK)
617 mask |= FMT_FLAGS_M2M;
618
619 ffmt = fimc_find_format(fourcc, code, mask, 0);
620 if (WARN_ON(!ffmt))
621 return NULL;
622 if (code)
623 *code = ffmt->mbus_code;
624 if (fourcc)
625 *fourcc = ffmt->fourcc;
626
627 if (pad == FIMC_SD_PAD_SINK) {
628 max_w = fimc_fmt_is_jpeg(ffmt->color) ?
629 pl->scaler_dis_w : pl->scaler_en_w;
630 /* Apply the camera input interface pixel constraints */
631 v4l_bound_align_image(width, max_t(u32, *width, 32), max_w, 4,
632 height, max_t(u32, *height, 32),
633 FIMC_CAMIF_MAX_HEIGHT,
634 fimc_fmt_is_jpeg(ffmt->color) ? 3 : 1,
635 0);
636 return ffmt;
637 }
638 /* Can't scale or crop in transparent (JPEG) transfer mode */
639 if (fimc_fmt_is_jpeg(ffmt->color)) {
640 *width = ctx->s_frame.f_width;
641 *height = ctx->s_frame.f_height;
642 return ffmt;
643 }
644 /* Apply the scaler and the output DMA constraints */
645 max_w = rotation ? pl->out_rot_en_w : pl->out_rot_dis_w;
646 if (ctx->state & FIMC_COMPOSE) {
647 min_w = dst->offs_h + dst->width;
648 min_h = dst->offs_v + dst->height;
649 } else {
650 min_w = var->min_out_pixsize;
651 min_h = var->min_out_pixsize;
652 }
653 if (var->min_vsize_align == 1 && !rotation)
654 align_h = fimc_fmt_is_rgb(ffmt->color) ? 0 : 1;
655
656 depth = fimc_get_format_depth(ffmt);
657 v4l_bound_align_image(width, min_w, max_w,
658 ffs(var->min_out_pixsize) - 1,
659 height, min_h, FIMC_CAMIF_MAX_HEIGHT,
660 align_h,
661 64/(ALIGN(depth, 8)));
662
663 dbg("pad%d: code: 0x%x, %dx%d. dst fmt: %dx%d",
664 pad, code ? *code : 0, *width, *height,
665 dst->f_width, dst->f_height);
666
667 return ffmt;
668}
669
670static void fimc_capture_try_selection(struct fimc_ctx *ctx,
671 struct v4l2_rect *r,
672 int target)
673{
674 bool rotate = ctx->rotation == 90 || ctx->rotation == 270;
675 struct fimc_dev *fimc = ctx->fimc_dev;
676 struct fimc_variant *var = fimc->variant;
677 struct fimc_pix_limit *pl = var->pix_limit;
678 struct fimc_frame *sink = &ctx->s_frame;
679 u32 max_w, max_h, min_w = 0, min_h = 0, min_sz;
680 u32 align_sz = 0, align_h = 4;
681 u32 max_sc_h, max_sc_v;
682
683 /* In JPEG transparent transfer mode cropping is not supported */
684 if (fimc_fmt_is_jpeg(ctx->d_frame.fmt->color)) {
685 r->width = sink->f_width;
686 r->height = sink->f_height;
687 r->left = r->top = 0;
688 return;
689 }
690 if (target == V4L2_SEL_TGT_COMPOSE) {
691 if (ctx->rotation != 90 && ctx->rotation != 270)
692 align_h = 1;
693 max_sc_h = min(SCALER_MAX_HRATIO, 1 << (ffs(sink->width) - 3));
694 max_sc_v = min(SCALER_MAX_VRATIO, 1 << (ffs(sink->height) - 1));
695 min_sz = var->min_out_pixsize;
696 } else {
697 u32 depth = fimc_get_format_depth(sink->fmt);
698 align_sz = 64/ALIGN(depth, 8);
699 min_sz = var->min_inp_pixsize;
700 min_w = min_h = min_sz;
701 max_sc_h = max_sc_v = 1;
702 }
703 /*
704 * For the compose rectangle the following constraints must be met:
705 * - it must fit in the sink pad format rectangle (f_width/f_height);
706 * - maximum downscaling ratio is 64;
707 * - maximum crop size depends if the rotator is used or not;
708 * - the sink pad format width/height must be 4 multiple of the
709 * prescaler ratios determined by sink pad size and source pad crop,
710 * the prescaler ratio is returned by fimc_get_scaler_factor().
711 */
712 max_w = min_t(u32,
713 rotate ? pl->out_rot_en_w : pl->out_rot_dis_w,
714 rotate ? sink->f_height : sink->f_width);
715 max_h = min_t(u32, FIMC_CAMIF_MAX_HEIGHT, sink->f_height);
716
717 if (target == V4L2_SEL_TGT_COMPOSE) {
718 min_w = min_t(u32, max_w, sink->f_width / max_sc_h);
719 min_h = min_t(u32, max_h, sink->f_height / max_sc_v);
720 if (rotate) {
721 swap(max_sc_h, max_sc_v);
722 swap(min_w, min_h);
723 }
724 }
725 v4l_bound_align_image(&r->width, min_w, max_w, ffs(min_sz) - 1,
726 &r->height, min_h, max_h, align_h,
727 align_sz);
728 /* Adjust left/top if crop/compose rectangle is out of bounds */
729 r->left = clamp_t(u32, r->left, 0, sink->f_width - r->width);
730 r->top = clamp_t(u32, r->top, 0, sink->f_height - r->height);
731 r->left = round_down(r->left, var->hor_offs_align);
732
733 dbg("target %#x: (%d,%d)/%dx%d, sink fmt: %dx%d",
734 target, r->left, r->top, r->width, r->height,
735 sink->f_width, sink->f_height);
736}
737
738/*
739 * The video node ioctl operations
740 */
741static int fimc_vidioc_querycap_capture(struct file *file, void *priv,
742 struct v4l2_capability *cap)
743{
744 struct fimc_dev *fimc = video_drvdata(file);
745
746 strncpy(cap->driver, fimc->pdev->name, sizeof(cap->driver) - 1);
747 strncpy(cap->card, fimc->pdev->name, sizeof(cap->card) - 1);
748 cap->bus_info[0] = 0;
749 cap->capabilities = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE_MPLANE;
750
751 return 0;
752}
753
754static int fimc_cap_enum_fmt_mplane(struct file *file, void *priv,
755 struct v4l2_fmtdesc *f)
756{
757 struct fimc_fmt *fmt;
758
759 fmt = fimc_find_format(NULL, NULL, FMT_FLAGS_CAM | FMT_FLAGS_M2M,
760 f->index);
761 if (!fmt)
762 return -EINVAL;
763 strncpy(f->description, fmt->name, sizeof(f->description) - 1);
764 f->pixelformat = fmt->fourcc;
765 if (fmt->fourcc == V4L2_MBUS_FMT_JPEG_1X8)
766 f->flags |= V4L2_FMT_FLAG_COMPRESSED;
767 return 0;
768}
769
770/**
771 * fimc_pipeline_try_format - negotiate and/or set formats at pipeline
772 * elements
773 * @ctx: FIMC capture context
774 * @tfmt: media bus format to try/set on subdevs
775 * @fmt_id: fimc pixel format id corresponding to returned @tfmt (output)
776 * @set: true to set format on subdevs, false to try only
777 */
778static int fimc_pipeline_try_format(struct fimc_ctx *ctx,
779 struct v4l2_mbus_framefmt *tfmt,
780 struct fimc_fmt **fmt_id,
781 bool set)
782{
783 struct fimc_dev *fimc = ctx->fimc_dev;
784 struct v4l2_subdev *sd = fimc->pipeline.subdevs[IDX_SENSOR];
785 struct v4l2_subdev *csis = fimc->pipeline.subdevs[IDX_CSIS];
786 struct v4l2_subdev_format sfmt;
787 struct v4l2_mbus_framefmt *mf = &sfmt.format;
788 struct fimc_fmt *ffmt = NULL;
789 int ret, i = 0;
790
791 if (WARN_ON(!sd || !tfmt))
792 return -EINVAL;
793
794 memset(&sfmt, 0, sizeof(sfmt));
795 sfmt.format = *tfmt;
796
797 sfmt.which = set ? V4L2_SUBDEV_FORMAT_ACTIVE : V4L2_SUBDEV_FORMAT_TRY;
798 while (1) {
799 ffmt = fimc_find_format(NULL, mf->code != 0 ? &mf->code : NULL,
800 FMT_FLAGS_CAM, i++);
801 if (ffmt == NULL) {
802 /*
803 * Notify user-space if common pixel code for
804 * host and sensor does not exist.
805 */
806 return -EINVAL;
807 }
808 mf->code = tfmt->code = ffmt->mbus_code;
809
810 ret = v4l2_subdev_call(sd, pad, set_fmt, NULL, &sfmt);
811 if (ret)
812 return ret;
813 if (mf->code != tfmt->code) {
814 mf->code = 0;
815 continue;
816 }
817 if (mf->width != tfmt->width || mf->height != tfmt->height) {
818 u32 fcc = ffmt->fourcc;
819 tfmt->width = mf->width;
820 tfmt->height = mf->height;
821 ffmt = fimc_capture_try_format(ctx,
822 &tfmt->width, &tfmt->height,
823 NULL, &fcc, FIMC_SD_PAD_SOURCE);
824 if (ffmt && ffmt->mbus_code)
825 mf->code = ffmt->mbus_code;
826 if (mf->width != tfmt->width ||
827 mf->height != tfmt->height)
828 continue;
829 tfmt->code = mf->code;
830 }
831 if (csis)
832 ret = v4l2_subdev_call(csis, pad, set_fmt, NULL, &sfmt);
833
834 if (mf->code == tfmt->code &&
835 mf->width == tfmt->width && mf->height == tfmt->height)
836 break;
837 }
838
839 if (fmt_id && ffmt)
840 *fmt_id = ffmt;
841 *tfmt = *mf;
842
843 dbg("code: 0x%x, %dx%d, %p", mf->code, mf->width, mf->height, ffmt);
844 return 0;
845}
846
847static int fimc_cap_g_fmt_mplane(struct file *file, void *fh,
848 struct v4l2_format *f)
849{
850 struct fimc_dev *fimc = video_drvdata(file);
851 struct fimc_ctx *ctx = fimc->vid_cap.ctx;
852
853 return fimc_fill_format(&ctx->d_frame, f);
854}
855
856static int fimc_cap_try_fmt_mplane(struct file *file, void *fh,
857 struct v4l2_format *f)
858{
859 struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
860 struct fimc_dev *fimc = video_drvdata(file);
861 struct fimc_ctx *ctx = fimc->vid_cap.ctx;
862 struct v4l2_mbus_framefmt mf;
863 struct fimc_fmt *ffmt = NULL;
864
865 if (pix->pixelformat == V4L2_PIX_FMT_JPEG) {
866 fimc_capture_try_format(ctx, &pix->width, &pix->height,
867 NULL, &pix->pixelformat,
868 FIMC_SD_PAD_SINK);
869 ctx->s_frame.f_width = pix->width;
870 ctx->s_frame.f_height = pix->height;
871 }
872 ffmt = fimc_capture_try_format(ctx, &pix->width, &pix->height,
873 NULL, &pix->pixelformat,
874 FIMC_SD_PAD_SOURCE);
875 if (!ffmt)
876 return -EINVAL;
877
878 if (!fimc->vid_cap.user_subdev_api) {
879 mf.width = pix->width;
880 mf.height = pix->height;
881 mf.code = ffmt->mbus_code;
882 fimc_md_graph_lock(fimc);
883 fimc_pipeline_try_format(ctx, &mf, &ffmt, false);
884 fimc_md_graph_unlock(fimc);
885
886 pix->width = mf.width;
887 pix->height = mf.height;
888 if (ffmt)
889 pix->pixelformat = ffmt->fourcc;
890 }
891
892 fimc_adjust_mplane_format(ffmt, pix->width, pix->height, pix);
893 return 0;
894}
895
896static void fimc_capture_mark_jpeg_xfer(struct fimc_ctx *ctx, bool jpeg)
897{
898 ctx->scaler.enabled = !jpeg;
899 fimc_ctrls_activate(ctx, !jpeg);
900
901 if (jpeg)
902 set_bit(ST_CAPT_JPEG, &ctx->fimc_dev->state);
903 else
904 clear_bit(ST_CAPT_JPEG, &ctx->fimc_dev->state);
905}
906
907static int fimc_capture_set_format(struct fimc_dev *fimc, struct v4l2_format *f)
908{
909 struct fimc_ctx *ctx = fimc->vid_cap.ctx;
910 struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
911 struct v4l2_mbus_framefmt *mf = &fimc->vid_cap.mf;
912 struct fimc_frame *ff = &ctx->d_frame;
913 struct fimc_fmt *s_fmt = NULL;
914 int ret, i;
915
916 if (vb2_is_busy(&fimc->vid_cap.vbq))
917 return -EBUSY;
918
919 /* Pre-configure format at camera interface input, for JPEG only */
920 if (pix->pixelformat == V4L2_PIX_FMT_JPEG) {
921 fimc_capture_try_format(ctx, &pix->width, &pix->height,
922 NULL, &pix->pixelformat,
923 FIMC_SD_PAD_SINK);
924 ctx->s_frame.f_width = pix->width;
925 ctx->s_frame.f_height = pix->height;
926 }
927 /* Try the format at the scaler and the DMA output */
928 ff->fmt = fimc_capture_try_format(ctx, &pix->width, &pix->height,
929 NULL, &pix->pixelformat,
930 FIMC_SD_PAD_SOURCE);
931 if (!ff->fmt)
932 return -EINVAL;
933
934 /* Update RGB Alpha control state and value range */
935 fimc_alpha_ctrl_update(ctx);
936
937 /* Try to match format at the host and the sensor */
938 if (!fimc->vid_cap.user_subdev_api) {
939 mf->code = ff->fmt->mbus_code;
940 mf->width = pix->width;
941 mf->height = pix->height;
942
943 fimc_md_graph_lock(fimc);
944 ret = fimc_pipeline_try_format(ctx, mf, &s_fmt, true);
945 fimc_md_graph_unlock(fimc);
946 if (ret)
947 return ret;
948 pix->width = mf->width;
949 pix->height = mf->height;
950 }
951
952 fimc_adjust_mplane_format(ff->fmt, pix->width, pix->height, pix);
953 for (i = 0; i < ff->fmt->colplanes; i++)
954 ff->payload[i] = pix->plane_fmt[i].sizeimage;
955
956 set_frame_bounds(ff, pix->width, pix->height);
957 /* Reset the composition rectangle if not yet configured */
958 if (!(ctx->state & FIMC_COMPOSE))
959 set_frame_crop(ff, 0, 0, pix->width, pix->height);
960
961 fimc_capture_mark_jpeg_xfer(ctx, fimc_fmt_is_jpeg(ff->fmt->color));
962
963 /* Reset cropping and set format at the camera interface input */
964 if (!fimc->vid_cap.user_subdev_api) {
965 ctx->s_frame.fmt = s_fmt;
966 set_frame_bounds(&ctx->s_frame, pix->width, pix->height);
967 set_frame_crop(&ctx->s_frame, 0, 0, pix->width, pix->height);
968 }
969
970 return ret;
971}
972
973static int fimc_cap_s_fmt_mplane(struct file *file, void *priv,
974 struct v4l2_format *f)
975{
976 struct fimc_dev *fimc = video_drvdata(file);
977
978 return fimc_capture_set_format(fimc, f);
979}
980
981static int fimc_cap_enum_input(struct file *file, void *priv,
982 struct v4l2_input *i)
983{
984 struct fimc_dev *fimc = video_drvdata(file);
985 struct v4l2_subdev *sd = fimc->pipeline.subdevs[IDX_SENSOR];
986
987 if (i->index != 0)
988 return -EINVAL;
989
990 i->type = V4L2_INPUT_TYPE_CAMERA;
991 if (sd)
992 strlcpy(i->name, sd->name, sizeof(i->name));
993 return 0;
994}
995
996static int fimc_cap_s_input(struct file *file, void *priv, unsigned int i)
997{
998 return i == 0 ? i : -EINVAL;
999}
1000
1001static int fimc_cap_g_input(struct file *file, void *priv, unsigned int *i)
1002{
1003 *i = 0;
1004 return 0;
1005}
1006
1007/**
1008 * fimc_pipeline_validate - check for formats inconsistencies
1009 * between source and sink pad of each link
1010 *
1011 * Return 0 if all formats match or -EPIPE otherwise.
1012 */
1013static int fimc_pipeline_validate(struct fimc_dev *fimc)
1014{
1015 struct v4l2_subdev_format sink_fmt, src_fmt;
1016 struct fimc_vid_cap *vid_cap = &fimc->vid_cap;
1017 struct v4l2_subdev *sd;
1018 struct media_pad *pad;
1019 int ret;
1020
1021 /* Start with the video capture node pad */
1022 pad = media_entity_remote_source(&vid_cap->vd_pad);
1023 if (pad == NULL)
1024 return -EPIPE;
1025 /* FIMC.{N} subdevice */
1026 sd = media_entity_to_v4l2_subdev(pad->entity);
1027
1028 while (1) {
1029 /* Retrieve format at the sink pad */
1030 pad = &sd->entity.pads[0];
1031 if (!(pad->flags & MEDIA_PAD_FL_SINK))
1032 break;
1033 /* Don't call FIMC subdev operation to avoid nested locking */
1034 if (sd == &fimc->vid_cap.subdev) {
1035 struct fimc_frame *ff = &vid_cap->ctx->s_frame;
1036 sink_fmt.format.width = ff->f_width;
1037 sink_fmt.format.height = ff->f_height;
1038 sink_fmt.format.code = ff->fmt ? ff->fmt->mbus_code : 0;
1039 } else {
1040 sink_fmt.pad = pad->index;
1041 sink_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
1042 ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &sink_fmt);
1043 if (ret < 0 && ret != -ENOIOCTLCMD)
1044 return -EPIPE;
1045 }
1046 /* Retrieve format at the source pad */
1047 pad = media_entity_remote_source(pad);
1048 if (pad == NULL ||
1049 media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
1050 break;
1051
1052 sd = media_entity_to_v4l2_subdev(pad->entity);
1053 src_fmt.pad = pad->index;
1054 src_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
1055 ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &src_fmt);
1056 if (ret < 0 && ret != -ENOIOCTLCMD)
1057 return -EPIPE;
1058
1059 if (src_fmt.format.width != sink_fmt.format.width ||
1060 src_fmt.format.height != sink_fmt.format.height ||
1061 src_fmt.format.code != sink_fmt.format.code)
1062 return -EPIPE;
1063 }
1064 return 0;
1065}
1066
1067static int fimc_cap_streamon(struct file *file, void *priv,
1068 enum v4l2_buf_type type)
1069{
1070 struct fimc_dev *fimc = video_drvdata(file);
1071 struct fimc_pipeline *p = &fimc->pipeline;
1072 struct v4l2_subdev *sd = p->subdevs[IDX_SENSOR];
1073 int ret;
1074
1075 if (fimc_capture_active(fimc))
1076 return -EBUSY;
1077
1078 ret = media_entity_pipeline_start(&sd->entity, p->m_pipeline);
1079 if (ret < 0)
1080 return ret;
1081
1082 if (fimc->vid_cap.user_subdev_api) {
1083 ret = fimc_pipeline_validate(fimc);
1084 if (ret < 0) {
1085 media_entity_pipeline_stop(&sd->entity);
1086 return ret;
1087 }
1088 }
1089 return vb2_streamon(&fimc->vid_cap.vbq, type);
1090}
1091
1092static int fimc_cap_streamoff(struct file *file, void *priv,
1093 enum v4l2_buf_type type)
1094{
1095 struct fimc_dev *fimc = video_drvdata(file);
1096 struct v4l2_subdev *sd = fimc->pipeline.subdevs[IDX_SENSOR];
1097 int ret;
1098
1099 ret = vb2_streamoff(&fimc->vid_cap.vbq, type);
1100 if (ret == 0)
1101 media_entity_pipeline_stop(&sd->entity);
1102 return ret;
1103}
1104
1105static int fimc_cap_reqbufs(struct file *file, void *priv,
1106 struct v4l2_requestbuffers *reqbufs)
1107{
1108 struct fimc_dev *fimc = video_drvdata(file);
1109 int ret = vb2_reqbufs(&fimc->vid_cap.vbq, reqbufs);
1110
1111 if (!ret)
1112 fimc->vid_cap.reqbufs_count = reqbufs->count;
1113 return ret;
1114}
1115
1116static int fimc_cap_querybuf(struct file *file, void *priv,
1117 struct v4l2_buffer *buf)
1118{
1119 struct fimc_dev *fimc = video_drvdata(file);
1120
1121 return vb2_querybuf(&fimc->vid_cap.vbq, buf);
1122}
1123
1124static int fimc_cap_qbuf(struct file *file, void *priv,
1125 struct v4l2_buffer *buf)
1126{
1127 struct fimc_dev *fimc = video_drvdata(file);
1128
1129 return vb2_qbuf(&fimc->vid_cap.vbq, buf);
1130}
1131
1132static int fimc_cap_dqbuf(struct file *file, void *priv,
1133 struct v4l2_buffer *buf)
1134{
1135 struct fimc_dev *fimc = video_drvdata(file);
1136
1137 return vb2_dqbuf(&fimc->vid_cap.vbq, buf, file->f_flags & O_NONBLOCK);
1138}
1139
1140static int fimc_cap_create_bufs(struct file *file, void *priv,
1141 struct v4l2_create_buffers *create)
1142{
1143 struct fimc_dev *fimc = video_drvdata(file);
1144
1145 return vb2_create_bufs(&fimc->vid_cap.vbq, create);
1146}
1147
1148static int fimc_cap_prepare_buf(struct file *file, void *priv,
1149 struct v4l2_buffer *b)
1150{
1151 struct fimc_dev *fimc = video_drvdata(file);
1152
1153 return vb2_prepare_buf(&fimc->vid_cap.vbq, b);
1154}
1155
1156static int fimc_cap_g_selection(struct file *file, void *fh,
1157 struct v4l2_selection *s)
1158{
1159 struct fimc_dev *fimc = video_drvdata(file);
1160 struct fimc_ctx *ctx = fimc->vid_cap.ctx;
1161 struct fimc_frame *f = &ctx->s_frame;
1162
1163 if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
1164 return -EINVAL;
1165
1166 switch (s->target) {
1167 case V4L2_SEL_TGT_COMPOSE_DEFAULT:
1168 case V4L2_SEL_TGT_COMPOSE_BOUNDS:
1169 f = &ctx->d_frame;
1170 case V4L2_SEL_TGT_CROP_BOUNDS:
1171 case V4L2_SEL_TGT_CROP_DEFAULT:
1172 s->r.left = 0;
1173 s->r.top = 0;
1174 s->r.width = f->o_width;
1175 s->r.height = f->o_height;
1176 return 0;
1177
1178 case V4L2_SEL_TGT_COMPOSE:
1179 f = &ctx->d_frame;
1180 case V4L2_SEL_TGT_CROP:
1181 s->r.left = f->offs_h;
1182 s->r.top = f->offs_v;
1183 s->r.width = f->width;
1184 s->r.height = f->height;
1185 return 0;
1186 }
1187
1188 return -EINVAL;
1189}
1190
1191/* Return 1 if rectangle a is enclosed in rectangle b, or 0 otherwise. */
1192static int enclosed_rectangle(struct v4l2_rect *a, struct v4l2_rect *b)
1193{
1194 if (a->left < b->left || a->top < b->top)
1195 return 0;
1196 if (a->left + a->width > b->left + b->width)
1197 return 0;
1198 if (a->top + a->height > b->top + b->height)
1199 return 0;
1200
1201 return 1;
1202}
1203
1204static int fimc_cap_s_selection(struct file *file, void *fh,
1205 struct v4l2_selection *s)
1206{
1207 struct fimc_dev *fimc = video_drvdata(file);
1208 struct fimc_ctx *ctx = fimc->vid_cap.ctx;
1209 struct v4l2_rect rect = s->r;
1210 struct fimc_frame *f;
1211 unsigned long flags;
1212
1213 if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
1214 return -EINVAL;
1215
1216 if (s->target == V4L2_SEL_TGT_COMPOSE)
1217 f = &ctx->d_frame;
1218 else if (s->target == V4L2_SEL_TGT_CROP)
1219 f = &ctx->s_frame;
1220 else
1221 return -EINVAL;
1222
1223 fimc_capture_try_selection(ctx, &rect, s->target);
1224
1225 if (s->flags & V4L2_SEL_FLAG_LE &&
1226 !enclosed_rectangle(&rect, &s->r))
1227 return -ERANGE;
1228
1229 if (s->flags & V4L2_SEL_FLAG_GE &&
1230 !enclosed_rectangle(&s->r, &rect))
1231 return -ERANGE;
1232
1233 s->r = rect;
1234 spin_lock_irqsave(&fimc->slock, flags);
1235 set_frame_crop(f, s->r.left, s->r.top, s->r.width,
1236 s->r.height);
1237 spin_unlock_irqrestore(&fimc->slock, flags);
1238
1239 set_bit(ST_CAPT_APPLY_CFG, &fimc->state);
1240 return 0;
1241}
1242
1243static const struct v4l2_ioctl_ops fimc_capture_ioctl_ops = {
1244 .vidioc_querycap = fimc_vidioc_querycap_capture,
1245
1246 .vidioc_enum_fmt_vid_cap_mplane = fimc_cap_enum_fmt_mplane,
1247 .vidioc_try_fmt_vid_cap_mplane = fimc_cap_try_fmt_mplane,
1248 .vidioc_s_fmt_vid_cap_mplane = fimc_cap_s_fmt_mplane,
1249 .vidioc_g_fmt_vid_cap_mplane = fimc_cap_g_fmt_mplane,
1250
1251 .vidioc_reqbufs = fimc_cap_reqbufs,
1252 .vidioc_querybuf = fimc_cap_querybuf,
1253
1254 .vidioc_qbuf = fimc_cap_qbuf,
1255 .vidioc_dqbuf = fimc_cap_dqbuf,
1256
1257 .vidioc_prepare_buf = fimc_cap_prepare_buf,
1258 .vidioc_create_bufs = fimc_cap_create_bufs,
1259
1260 .vidioc_streamon = fimc_cap_streamon,
1261 .vidioc_streamoff = fimc_cap_streamoff,
1262
1263 .vidioc_g_selection = fimc_cap_g_selection,
1264 .vidioc_s_selection = fimc_cap_s_selection,
1265
1266 .vidioc_enum_input = fimc_cap_enum_input,
1267 .vidioc_s_input = fimc_cap_s_input,
1268 .vidioc_g_input = fimc_cap_g_input,
1269};
1270
1271/* Capture subdev media entity operations */
1272static int fimc_link_setup(struct media_entity *entity,
1273 const struct media_pad *local,
1274 const struct media_pad *remote, u32 flags)
1275{
1276 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
1277 struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
1278
1279 if (media_entity_type(remote->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
1280 return -EINVAL;
1281
1282 if (WARN_ON(fimc == NULL))
1283 return 0;
1284
1285 dbg("%s --> %s, flags: 0x%x. input: 0x%x",
1286 local->entity->name, remote->entity->name, flags,
1287 fimc->vid_cap.input);
1288
1289 if (flags & MEDIA_LNK_FL_ENABLED) {
1290 if (fimc->vid_cap.input != 0)
1291 return -EBUSY;
1292 fimc->vid_cap.input = sd->grp_id;
1293 return 0;
1294 }
1295
1296 fimc->vid_cap.input = 0;
1297 return 0;
1298}
1299
1300static const struct media_entity_operations fimc_sd_media_ops = {
1301 .link_setup = fimc_link_setup,
1302};
1303
1304/**
1305 * fimc_sensor_notify - v4l2_device notification from a sensor subdev
1306 * @sd: pointer to a subdev generating the notification
1307 * @notification: the notification type, must be S5P_FIMC_TX_END_NOTIFY
1308 * @arg: pointer to an u32 type integer that stores the frame payload value
1309 *
1310 * The End Of Frame notification sent by sensor subdev in its still capture
1311 * mode. If there is only a single VSYNC generated by the sensor at the
1312 * beginning of a frame transmission, FIMC does not issue the LastIrq
1313 * (end of frame) interrupt. And this notification is used to complete the
1314 * frame capture and returning a buffer to user-space. Subdev drivers should
1315 * call this notification from their last 'End of frame capture' interrupt.
1316 */
1317void fimc_sensor_notify(struct v4l2_subdev *sd, unsigned int notification,
1318 void *arg)
1319{
1320 struct fimc_sensor_info *sensor;
1321 struct fimc_vid_buffer *buf;
1322 struct fimc_md *fmd;
1323 struct fimc_dev *fimc;
1324 unsigned long flags;
1325
1326 if (sd == NULL)
1327 return;
1328
1329 sensor = v4l2_get_subdev_hostdata(sd);
1330 fmd = entity_to_fimc_mdev(&sd->entity);
1331
1332 spin_lock_irqsave(&fmd->slock, flags);
1333 fimc = sensor ? sensor->host : NULL;
1334
1335 if (fimc && arg && notification == S5P_FIMC_TX_END_NOTIFY &&
1336 test_bit(ST_CAPT_PEND, &fimc->state)) {
1337 unsigned long irq_flags;
1338 spin_lock_irqsave(&fimc->slock, irq_flags);
1339 if (!list_empty(&fimc->vid_cap.active_buf_q)) {
1340 buf = list_entry(fimc->vid_cap.active_buf_q.next,
1341 struct fimc_vid_buffer, list);
1342 vb2_set_plane_payload(&buf->vb, 0, *((u32 *)arg));
1343 }
1344 fimc_capture_irq_handler(fimc, 1);
1345 fimc_deactivate_capture(fimc);
1346 spin_unlock_irqrestore(&fimc->slock, irq_flags);
1347 }
1348 spin_unlock_irqrestore(&fmd->slock, flags);
1349}
1350
1351static int fimc_subdev_enum_mbus_code(struct v4l2_subdev *sd,
1352 struct v4l2_subdev_fh *fh,
1353 struct v4l2_subdev_mbus_code_enum *code)
1354{
1355 struct fimc_fmt *fmt;
1356
1357 fmt = fimc_find_format(NULL, NULL, FMT_FLAGS_CAM, code->index);
1358 if (!fmt)
1359 return -EINVAL;
1360 code->code = fmt->mbus_code;
1361 return 0;
1362}
1363
1364static int fimc_subdev_get_fmt(struct v4l2_subdev *sd,
1365 struct v4l2_subdev_fh *fh,
1366 struct v4l2_subdev_format *fmt)
1367{
1368 struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
1369 struct fimc_ctx *ctx = fimc->vid_cap.ctx;
1370 struct v4l2_mbus_framefmt *mf;
1371 struct fimc_frame *ff;
1372
1373 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
1374 mf = v4l2_subdev_get_try_format(fh, fmt->pad);
1375 fmt->format = *mf;
1376 return 0;
1377 }
1378 mf = &fmt->format;
1379 mf->colorspace = V4L2_COLORSPACE_JPEG;
1380 ff = fmt->pad == FIMC_SD_PAD_SINK ? &ctx->s_frame : &ctx->d_frame;
1381
1382 mutex_lock(&fimc->lock);
1383 /* The pixel code is same on both input and output pad */
1384 if (!WARN_ON(ctx->s_frame.fmt == NULL))
1385 mf->code = ctx->s_frame.fmt->mbus_code;
1386 mf->width = ff->f_width;
1387 mf->height = ff->f_height;
1388 mutex_unlock(&fimc->lock);
1389
1390 return 0;
1391}
1392
1393static int fimc_subdev_set_fmt(struct v4l2_subdev *sd,
1394 struct v4l2_subdev_fh *fh,
1395 struct v4l2_subdev_format *fmt)
1396{
1397 struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
1398 struct v4l2_mbus_framefmt *mf = &fmt->format;
1399 struct fimc_ctx *ctx = fimc->vid_cap.ctx;
1400 struct fimc_frame *ff;
1401 struct fimc_fmt *ffmt;
1402
1403 dbg("pad%d: code: 0x%x, %dx%d",
1404 fmt->pad, mf->code, mf->width, mf->height);
1405
1406 if (fmt->pad == FIMC_SD_PAD_SOURCE &&
1407 vb2_is_busy(&fimc->vid_cap.vbq))
1408 return -EBUSY;
1409
1410 mutex_lock(&fimc->lock);
1411 ffmt = fimc_capture_try_format(ctx, &mf->width, &mf->height,
1412 &mf->code, NULL, fmt->pad);
1413 mutex_unlock(&fimc->lock);
1414 mf->colorspace = V4L2_COLORSPACE_JPEG;
1415
1416 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
1417 mf = v4l2_subdev_get_try_format(fh, fmt->pad);
1418 *mf = fmt->format;
1419 return 0;
1420 }
1421 /* Update RGB Alpha control state and value range */
1422 fimc_alpha_ctrl_update(ctx);
1423
1424 fimc_capture_mark_jpeg_xfer(ctx, fimc_fmt_is_jpeg(ffmt->color));
1425
1426 ff = fmt->pad == FIMC_SD_PAD_SINK ?
1427 &ctx->s_frame : &ctx->d_frame;
1428
1429 mutex_lock(&fimc->lock);
1430 set_frame_bounds(ff, mf->width, mf->height);
1431 fimc->vid_cap.mf = *mf;
1432 ff->fmt = ffmt;
1433
1434 /* Reset the crop rectangle if required. */
1435 if (!(fmt->pad == FIMC_SD_PAD_SOURCE && (ctx->state & FIMC_COMPOSE)))
1436 set_frame_crop(ff, 0, 0, mf->width, mf->height);
1437
1438 if (fmt->pad == FIMC_SD_PAD_SINK)
1439 ctx->state &= ~FIMC_COMPOSE;
1440 mutex_unlock(&fimc->lock);
1441 return 0;
1442}
1443
1444static int fimc_subdev_get_selection(struct v4l2_subdev *sd,
1445 struct v4l2_subdev_fh *fh,
1446 struct v4l2_subdev_selection *sel)
1447{
1448 struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
1449 struct fimc_ctx *ctx = fimc->vid_cap.ctx;
1450 struct fimc_frame *f = &ctx->s_frame;
1451 struct v4l2_rect *r = &sel->r;
1452 struct v4l2_rect *try_sel;
1453
1454 if (sel->pad != FIMC_SD_PAD_SINK)
1455 return -EINVAL;
1456
1457 mutex_lock(&fimc->lock);
1458
1459 switch (sel->target) {
1460 case V4L2_SEL_TGT_COMPOSE_BOUNDS:
1461 f = &ctx->d_frame;
1462 case V4L2_SEL_TGT_CROP_BOUNDS:
1463 r->width = f->o_width;
1464 r->height = f->o_height;
1465 r->left = 0;
1466 r->top = 0;
1467 mutex_unlock(&fimc->lock);
1468 return 0;
1469
1470 case V4L2_SEL_TGT_CROP:
1471 try_sel = v4l2_subdev_get_try_crop(fh, sel->pad);
1472 break;
1473 case V4L2_SEL_TGT_COMPOSE:
1474 try_sel = v4l2_subdev_get_try_compose(fh, sel->pad);
1475 f = &ctx->d_frame;
1476 break;
1477 default:
1478 mutex_unlock(&fimc->lock);
1479 return -EINVAL;
1480 }
1481
1482 if (sel->which == V4L2_SUBDEV_FORMAT_TRY) {
1483 sel->r = *try_sel;
1484 } else {
1485 r->left = f->offs_h;
1486 r->top = f->offs_v;
1487 r->width = f->width;
1488 r->height = f->height;
1489 }
1490
1491 dbg("target %#x: l:%d, t:%d, %dx%d, f_w: %d, f_h: %d",
1492 sel->pad, r->left, r->top, r->width, r->height,
1493 f->f_width, f->f_height);
1494
1495 mutex_unlock(&fimc->lock);
1496 return 0;
1497}
1498
1499static int fimc_subdev_set_selection(struct v4l2_subdev *sd,
1500 struct v4l2_subdev_fh *fh,
1501 struct v4l2_subdev_selection *sel)
1502{
1503 struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
1504 struct fimc_ctx *ctx = fimc->vid_cap.ctx;
1505 struct fimc_frame *f = &ctx->s_frame;
1506 struct v4l2_rect *r = &sel->r;
1507 struct v4l2_rect *try_sel;
1508 unsigned long flags;
1509
1510 if (sel->pad != FIMC_SD_PAD_SINK)
1511 return -EINVAL;
1512
1513 mutex_lock(&fimc->lock);
1514 fimc_capture_try_selection(ctx, r, V4L2_SEL_TGT_CROP);
1515
1516 switch (sel->target) {
1517 case V4L2_SEL_TGT_COMPOSE_BOUNDS:
1518 f = &ctx->d_frame;
1519 case V4L2_SEL_TGT_CROP_BOUNDS:
1520 r->width = f->o_width;
1521 r->height = f->o_height;
1522 r->left = 0;
1523 r->top = 0;
1524 mutex_unlock(&fimc->lock);
1525 return 0;
1526
1527 case V4L2_SEL_TGT_CROP:
1528 try_sel = v4l2_subdev_get_try_crop(fh, sel->pad);
1529 break;
1530 case V4L2_SEL_TGT_COMPOSE:
1531 try_sel = v4l2_subdev_get_try_compose(fh, sel->pad);
1532 f = &ctx->d_frame;
1533 break;
1534 default:
1535 mutex_unlock(&fimc->lock);
1536 return -EINVAL;
1537 }
1538
1539 if (sel->which == V4L2_SUBDEV_FORMAT_TRY) {
1540 *try_sel = sel->r;
1541 } else {
1542 spin_lock_irqsave(&fimc->slock, flags);
1543 set_frame_crop(f, r->left, r->top, r->width, r->height);
1544 set_bit(ST_CAPT_APPLY_CFG, &fimc->state);
1545 spin_unlock_irqrestore(&fimc->slock, flags);
1546 if (sel->target == V4L2_SEL_TGT_COMPOSE)
1547 ctx->state |= FIMC_COMPOSE;
1548 }
1549
1550 dbg("target %#x: (%d,%d)/%dx%d", sel->target, r->left, r->top,
1551 r->width, r->height);
1552
1553 mutex_unlock(&fimc->lock);
1554 return 0;
1555}
1556
1557static struct v4l2_subdev_pad_ops fimc_subdev_pad_ops = {
1558 .enum_mbus_code = fimc_subdev_enum_mbus_code,
1559 .get_selection = fimc_subdev_get_selection,
1560 .set_selection = fimc_subdev_set_selection,
1561 .get_fmt = fimc_subdev_get_fmt,
1562 .set_fmt = fimc_subdev_set_fmt,
1563};
1564
1565static struct v4l2_subdev_ops fimc_subdev_ops = {
1566 .pad = &fimc_subdev_pad_ops,
1567};
1568
1569/* Set default format at the sensor and host interface */
1570static int fimc_capture_set_default_format(struct fimc_dev *fimc)
1571{
1572 struct v4l2_format fmt = {
1573 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
1574 .fmt.pix_mp = {
1575 .width = 640,
1576 .height = 480,
1577 .pixelformat = V4L2_PIX_FMT_YUYV,
1578 .field = V4L2_FIELD_NONE,
1579 .colorspace = V4L2_COLORSPACE_JPEG,
1580 },
1581 };
1582
1583 return fimc_capture_set_format(fimc, &fmt);
1584}
1585
1586/* fimc->lock must be already initialized */
1587static int fimc_register_capture_device(struct fimc_dev *fimc,
1588 struct v4l2_device *v4l2_dev)
1589{
1590 struct video_device *vfd;
1591 struct fimc_vid_cap *vid_cap;
1592 struct fimc_ctx *ctx;
1593 struct vb2_queue *q;
1594 int ret = -ENOMEM;
1595
1596 ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
1597 if (!ctx)
1598 return -ENOMEM;
1599
1600 ctx->fimc_dev = fimc;
1601 ctx->in_path = FIMC_IO_CAMERA;
1602 ctx->out_path = FIMC_IO_DMA;
1603 ctx->state = FIMC_CTX_CAP;
1604 ctx->s_frame.fmt = fimc_find_format(NULL, NULL, FMT_FLAGS_CAM, 0);
1605 ctx->d_frame.fmt = ctx->s_frame.fmt;
1606
1607 vfd = video_device_alloc();
1608 if (!vfd) {
1609 v4l2_err(v4l2_dev, "Failed to allocate video device\n");
1610 goto err_vd_alloc;
1611 }
1612
1613 snprintf(vfd->name, sizeof(vfd->name), "fimc.%d.capture", fimc->id);
1614
1615 vfd->fops = &fimc_capture_fops;
1616 vfd->ioctl_ops = &fimc_capture_ioctl_ops;
1617 vfd->v4l2_dev = v4l2_dev;
1618 vfd->minor = -1;
1619 vfd->release = video_device_release;
1620 vfd->lock = &fimc->lock;
1621
1622 video_set_drvdata(vfd, fimc);
1623
1624 vid_cap = &fimc->vid_cap;
1625 vid_cap->vfd = vfd;
1626 vid_cap->active_buf_cnt = 0;
1627 vid_cap->reqbufs_count = 0;
1628 vid_cap->refcnt = 0;
1629
1630 INIT_LIST_HEAD(&vid_cap->pending_buf_q);
1631 INIT_LIST_HEAD(&vid_cap->active_buf_q);
1632 vid_cap->ctx = ctx;
1633
1634 q = &fimc->vid_cap.vbq;
1635 memset(q, 0, sizeof(*q));
1636 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1637 q->io_modes = VB2_MMAP | VB2_USERPTR;
1638 q->drv_priv = fimc->vid_cap.ctx;
1639 q->ops = &fimc_capture_qops;
1640 q->mem_ops = &vb2_dma_contig_memops;
1641 q->buf_struct_size = sizeof(struct fimc_vid_buffer);
1642
1643 vb2_queue_init(q);
1644
1645 vid_cap->vd_pad.flags = MEDIA_PAD_FL_SINK;
1646 ret = media_entity_init(&vfd->entity, 1, &vid_cap->vd_pad, 0);
1647 if (ret)
1648 goto err_ent;
1649
1650 ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1);
1651 if (ret)
1652 goto err_vd;
1653
1654 v4l2_info(v4l2_dev, "Registered %s as /dev/%s\n",
1655 vfd->name, video_device_node_name(vfd));
1656
1657 vfd->ctrl_handler = &ctx->ctrls.handler;
1658 return 0;
1659
1660err_vd:
1661 media_entity_cleanup(&vfd->entity);
1662err_ent:
1663 video_device_release(vfd);
1664err_vd_alloc:
1665 kfree(ctx);
1666 return ret;
1667}
1668
1669static int fimc_capture_subdev_registered(struct v4l2_subdev *sd)
1670{
1671 struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
1672 int ret;
1673
1674 ret = fimc_register_m2m_device(fimc, sd->v4l2_dev);
1675 if (ret)
1676 return ret;
1677
1678 ret = fimc_register_capture_device(fimc, sd->v4l2_dev);
1679 if (ret)
1680 fimc_unregister_m2m_device(fimc);
1681
1682 return ret;
1683}
1684
1685static void fimc_capture_subdev_unregistered(struct v4l2_subdev *sd)
1686{
1687 struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
1688
1689 if (fimc == NULL)
1690 return;
1691
1692 fimc_unregister_m2m_device(fimc);
1693
1694 if (fimc->vid_cap.vfd) {
1695 media_entity_cleanup(&fimc->vid_cap.vfd->entity);
1696 video_unregister_device(fimc->vid_cap.vfd);
1697 fimc->vid_cap.vfd = NULL;
1698 }
1699
1700 kfree(fimc->vid_cap.ctx);
1701 fimc->vid_cap.ctx = NULL;
1702}
1703
1704static const struct v4l2_subdev_internal_ops fimc_capture_sd_internal_ops = {
1705 .registered = fimc_capture_subdev_registered,
1706 .unregistered = fimc_capture_subdev_unregistered,
1707};
1708
1709int fimc_initialize_capture_subdev(struct fimc_dev *fimc)
1710{
1711 struct v4l2_subdev *sd = &fimc->vid_cap.subdev;
1712 int ret;
1713
1714 v4l2_subdev_init(sd, &fimc_subdev_ops);
1715 sd->flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
1716 snprintf(sd->name, sizeof(sd->name), "FIMC.%d", fimc->pdev->id);
1717
1718 fimc->vid_cap.sd_pads[FIMC_SD_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
1719 fimc->vid_cap.sd_pads[FIMC_SD_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
1720 ret = media_entity_init(&sd->entity, FIMC_SD_PADS_NUM,
1721 fimc->vid_cap.sd_pads, 0);
1722 if (ret)
1723 return ret;
1724
1725 sd->entity.ops = &fimc_sd_media_ops;
1726 sd->internal_ops = &fimc_capture_sd_internal_ops;
1727 v4l2_set_subdevdata(sd, fimc);
1728 return 0;
1729}
1730
1731void fimc_unregister_capture_subdev(struct fimc_dev *fimc)
1732{
1733 struct v4l2_subdev *sd = &fimc->vid_cap.subdev;
1734
1735 v4l2_device_unregister_subdev(sd);
1736 media_entity_cleanup(&sd->entity);
1737 v4l2_set_subdevdata(sd, NULL);
1738}
diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c
deleted file mode 100644
index 1a445404e73d..000000000000
--- a/drivers/media/video/s5p-fimc/fimc-core.c
+++ /dev/null
@@ -1,1239 +0,0 @@
1/*
2 * Samsung S5P/EXYNOS4 SoC series FIMC (CAMIF) driver
3 *
4 * Copyright (C) 2010-2012 Samsung Electronics Co., Ltd.
5 * Sylwester Nawrocki <s.nawrocki@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published
9 * by the Free Software Foundation, either version 2 of the License,
10 * or (at your option) any later version.
11 */
12
13#include <linux/module.h>
14#include <linux/kernel.h>
15#include <linux/types.h>
16#include <linux/errno.h>
17#include <linux/bug.h>
18#include <linux/interrupt.h>
19#include <linux/device.h>
20#include <linux/platform_device.h>
21#include <linux/pm_runtime.h>
22#include <linux/list.h>
23#include <linux/io.h>
24#include <linux/slab.h>
25#include <linux/clk.h>
26#include <media/v4l2-ioctl.h>
27#include <media/videobuf2-core.h>
28#include <media/videobuf2-dma-contig.h>
29
30#include "fimc-core.h"
31#include "fimc-reg.h"
32#include "fimc-mdevice.h"
33
34static char *fimc_clocks[MAX_FIMC_CLOCKS] = {
35 "sclk_fimc", "fimc"
36};
37
38static struct fimc_fmt fimc_formats[] = {
39 {
40 .name = "RGB565",
41 .fourcc = V4L2_PIX_FMT_RGB565,
42 .depth = { 16 },
43 .color = FIMC_FMT_RGB565,
44 .memplanes = 1,
45 .colplanes = 1,
46 .flags = FMT_FLAGS_M2M,
47 }, {
48 .name = "BGR666",
49 .fourcc = V4L2_PIX_FMT_BGR666,
50 .depth = { 32 },
51 .color = FIMC_FMT_RGB666,
52 .memplanes = 1,
53 .colplanes = 1,
54 .flags = FMT_FLAGS_M2M,
55 }, {
56 .name = "ARGB8888, 32 bpp",
57 .fourcc = V4L2_PIX_FMT_RGB32,
58 .depth = { 32 },
59 .color = FIMC_FMT_RGB888,
60 .memplanes = 1,
61 .colplanes = 1,
62 .flags = FMT_FLAGS_M2M | FMT_HAS_ALPHA,
63 }, {
64 .name = "ARGB1555",
65 .fourcc = V4L2_PIX_FMT_RGB555,
66 .depth = { 16 },
67 .color = FIMC_FMT_RGB555,
68 .memplanes = 1,
69 .colplanes = 1,
70 .flags = FMT_FLAGS_M2M_OUT | FMT_HAS_ALPHA,
71 }, {
72 .name = "ARGB4444",
73 .fourcc = V4L2_PIX_FMT_RGB444,
74 .depth = { 16 },
75 .color = FIMC_FMT_RGB444,
76 .memplanes = 1,
77 .colplanes = 1,
78 .flags = FMT_FLAGS_M2M_OUT | FMT_HAS_ALPHA,
79 }, {
80 .name = "YUV 4:2:2 packed, YCbYCr",
81 .fourcc = V4L2_PIX_FMT_YUYV,
82 .depth = { 16 },
83 .color = FIMC_FMT_YCBYCR422,
84 .memplanes = 1,
85 .colplanes = 1,
86 .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8,
87 .flags = FMT_FLAGS_M2M | FMT_FLAGS_CAM,
88 }, {
89 .name = "YUV 4:2:2 packed, CbYCrY",
90 .fourcc = V4L2_PIX_FMT_UYVY,
91 .depth = { 16 },
92 .color = FIMC_FMT_CBYCRY422,
93 .memplanes = 1,
94 .colplanes = 1,
95 .mbus_code = V4L2_MBUS_FMT_UYVY8_2X8,
96 .flags = FMT_FLAGS_M2M | FMT_FLAGS_CAM,
97 }, {
98 .name = "YUV 4:2:2 packed, CrYCbY",
99 .fourcc = V4L2_PIX_FMT_VYUY,
100 .depth = { 16 },
101 .color = FIMC_FMT_CRYCBY422,
102 .memplanes = 1,
103 .colplanes = 1,
104 .mbus_code = V4L2_MBUS_FMT_VYUY8_2X8,
105 .flags = FMT_FLAGS_M2M | FMT_FLAGS_CAM,
106 }, {
107 .name = "YUV 4:2:2 packed, YCrYCb",
108 .fourcc = V4L2_PIX_FMT_YVYU,
109 .depth = { 16 },
110 .color = FIMC_FMT_YCRYCB422,
111 .memplanes = 1,
112 .colplanes = 1,
113 .mbus_code = V4L2_MBUS_FMT_YVYU8_2X8,
114 .flags = FMT_FLAGS_M2M | FMT_FLAGS_CAM,
115 }, {
116 .name = "YUV 4:2:2 planar, Y/Cb/Cr",
117 .fourcc = V4L2_PIX_FMT_YUV422P,
118 .depth = { 12 },
119 .color = FIMC_FMT_YCBYCR422,
120 .memplanes = 1,
121 .colplanes = 3,
122 .flags = FMT_FLAGS_M2M,
123 }, {
124 .name = "YUV 4:2:2 planar, Y/CbCr",
125 .fourcc = V4L2_PIX_FMT_NV16,
126 .depth = { 16 },
127 .color = FIMC_FMT_YCBYCR422,
128 .memplanes = 1,
129 .colplanes = 2,
130 .flags = FMT_FLAGS_M2M,
131 }, {
132 .name = "YUV 4:2:2 planar, Y/CrCb",
133 .fourcc = V4L2_PIX_FMT_NV61,
134 .depth = { 16 },
135 .color = FIMC_FMT_YCRYCB422,
136 .memplanes = 1,
137 .colplanes = 2,
138 .flags = FMT_FLAGS_M2M,
139 }, {
140 .name = "YUV 4:2:0 planar, YCbCr",
141 .fourcc = V4L2_PIX_FMT_YUV420,
142 .depth = { 12 },
143 .color = FIMC_FMT_YCBCR420,
144 .memplanes = 1,
145 .colplanes = 3,
146 .flags = FMT_FLAGS_M2M,
147 }, {
148 .name = "YUV 4:2:0 planar, Y/CbCr",
149 .fourcc = V4L2_PIX_FMT_NV12,
150 .depth = { 12 },
151 .color = FIMC_FMT_YCBCR420,
152 .memplanes = 1,
153 .colplanes = 2,
154 .flags = FMT_FLAGS_M2M,
155 }, {
156 .name = "YUV 4:2:0 non-contig. 2p, Y/CbCr",
157 .fourcc = V4L2_PIX_FMT_NV12M,
158 .color = FIMC_FMT_YCBCR420,
159 .depth = { 8, 4 },
160 .memplanes = 2,
161 .colplanes = 2,
162 .flags = FMT_FLAGS_M2M,
163 }, {
164 .name = "YUV 4:2:0 non-contig. 3p, Y/Cb/Cr",
165 .fourcc = V4L2_PIX_FMT_YUV420M,
166 .color = FIMC_FMT_YCBCR420,
167 .depth = { 8, 2, 2 },
168 .memplanes = 3,
169 .colplanes = 3,
170 .flags = FMT_FLAGS_M2M,
171 }, {
172 .name = "YUV 4:2:0 non-contig. 2p, tiled",
173 .fourcc = V4L2_PIX_FMT_NV12MT,
174 .color = FIMC_FMT_YCBCR420,
175 .depth = { 8, 4 },
176 .memplanes = 2,
177 .colplanes = 2,
178 .flags = FMT_FLAGS_M2M,
179 }, {
180 .name = "JPEG encoded data",
181 .fourcc = V4L2_PIX_FMT_JPEG,
182 .color = FIMC_FMT_JPEG,
183 .depth = { 8 },
184 .memplanes = 1,
185 .colplanes = 1,
186 .mbus_code = V4L2_MBUS_FMT_JPEG_1X8,
187 .flags = FMT_FLAGS_CAM,
188 },
189};
190
191struct fimc_fmt *fimc_get_format(unsigned int index)
192{
193 if (index >= ARRAY_SIZE(fimc_formats))
194 return NULL;
195
196 return &fimc_formats[index];
197}
198
199int fimc_check_scaler_ratio(struct fimc_ctx *ctx, int sw, int sh,
200 int dw, int dh, int rotation)
201{
202 if (rotation == 90 || rotation == 270)
203 swap(dw, dh);
204
205 if (!ctx->scaler.enabled)
206 return (sw == dw && sh == dh) ? 0 : -EINVAL;
207
208 if ((sw >= SCALER_MAX_HRATIO * dw) || (sh >= SCALER_MAX_VRATIO * dh))
209 return -EINVAL;
210
211 return 0;
212}
213
214static int fimc_get_scaler_factor(u32 src, u32 tar, u32 *ratio, u32 *shift)
215{
216 u32 sh = 6;
217
218 if (src >= 64 * tar)
219 return -EINVAL;
220
221 while (sh--) {
222 u32 tmp = 1 << sh;
223 if (src >= tar * tmp) {
224 *shift = sh, *ratio = tmp;
225 return 0;
226 }
227 }
228 *shift = 0, *ratio = 1;
229 return 0;
230}
231
232int fimc_set_scaler_info(struct fimc_ctx *ctx)
233{
234 struct fimc_variant *variant = ctx->fimc_dev->variant;
235 struct device *dev = &ctx->fimc_dev->pdev->dev;
236 struct fimc_scaler *sc = &ctx->scaler;
237 struct fimc_frame *s_frame = &ctx->s_frame;
238 struct fimc_frame *d_frame = &ctx->d_frame;
239 int tx, ty, sx, sy;
240 int ret;
241
242 if (ctx->rotation == 90 || ctx->rotation == 270) {
243 ty = d_frame->width;
244 tx = d_frame->height;
245 } else {
246 tx = d_frame->width;
247 ty = d_frame->height;
248 }
249 if (tx <= 0 || ty <= 0) {
250 dev_err(dev, "Invalid target size: %dx%d", tx, ty);
251 return -EINVAL;
252 }
253
254 sx = s_frame->width;
255 sy = s_frame->height;
256 if (sx <= 0 || sy <= 0) {
257 dev_err(dev, "Invalid source size: %dx%d", sx, sy);
258 return -EINVAL;
259 }
260 sc->real_width = sx;
261 sc->real_height = sy;
262
263 ret = fimc_get_scaler_factor(sx, tx, &sc->pre_hratio, &sc->hfactor);
264 if (ret)
265 return ret;
266
267 ret = fimc_get_scaler_factor(sy, ty, &sc->pre_vratio, &sc->vfactor);
268 if (ret)
269 return ret;
270
271 sc->pre_dst_width = sx / sc->pre_hratio;
272 sc->pre_dst_height = sy / sc->pre_vratio;
273
274 if (variant->has_mainscaler_ext) {
275 sc->main_hratio = (sx << 14) / (tx << sc->hfactor);
276 sc->main_vratio = (sy << 14) / (ty << sc->vfactor);
277 } else {
278 sc->main_hratio = (sx << 8) / (tx << sc->hfactor);
279 sc->main_vratio = (sy << 8) / (ty << sc->vfactor);
280
281 }
282
283 sc->scaleup_h = (tx >= sx) ? 1 : 0;
284 sc->scaleup_v = (ty >= sy) ? 1 : 0;
285
286 /* check to see if input and output size/format differ */
287 if (s_frame->fmt->color == d_frame->fmt->color
288 && s_frame->width == d_frame->width
289 && s_frame->height == d_frame->height)
290 sc->copy_mode = 1;
291 else
292 sc->copy_mode = 0;
293
294 return 0;
295}
296
297static irqreturn_t fimc_irq_handler(int irq, void *priv)
298{
299 struct fimc_dev *fimc = priv;
300 struct fimc_ctx *ctx;
301
302 fimc_hw_clear_irq(fimc);
303
304 spin_lock(&fimc->slock);
305
306 if (test_and_clear_bit(ST_M2M_PEND, &fimc->state)) {
307 if (test_and_clear_bit(ST_M2M_SUSPENDING, &fimc->state)) {
308 set_bit(ST_M2M_SUSPENDED, &fimc->state);
309 wake_up(&fimc->irq_queue);
310 goto out;
311 }
312 ctx = v4l2_m2m_get_curr_priv(fimc->m2m.m2m_dev);
313 if (ctx != NULL) {
314 spin_unlock(&fimc->slock);
315 fimc_m2m_job_finish(ctx, VB2_BUF_STATE_DONE);
316
317 if (ctx->state & FIMC_CTX_SHUT) {
318 ctx->state &= ~FIMC_CTX_SHUT;
319 wake_up(&fimc->irq_queue);
320 }
321 return IRQ_HANDLED;
322 }
323 } else if (test_bit(ST_CAPT_PEND, &fimc->state)) {
324 int last_buf = test_bit(ST_CAPT_JPEG, &fimc->state) &&
325 fimc->vid_cap.reqbufs_count == 1;
326 fimc_capture_irq_handler(fimc, !last_buf);
327 }
328out:
329 spin_unlock(&fimc->slock);
330 return IRQ_HANDLED;
331}
332
333/* The color format (colplanes, memplanes) must be already configured. */
334int fimc_prepare_addr(struct fimc_ctx *ctx, struct vb2_buffer *vb,
335 struct fimc_frame *frame, struct fimc_addr *paddr)
336{
337 int ret = 0;
338 u32 pix_size;
339
340 if (vb == NULL || frame == NULL)
341 return -EINVAL;
342
343 pix_size = frame->width * frame->height;
344
345 dbg("memplanes= %d, colplanes= %d, pix_size= %d",
346 frame->fmt->memplanes, frame->fmt->colplanes, pix_size);
347
348 paddr->y = vb2_dma_contig_plane_dma_addr(vb, 0);
349
350 if (frame->fmt->memplanes == 1) {
351 switch (frame->fmt->colplanes) {
352 case 1:
353 paddr->cb = 0;
354 paddr->cr = 0;
355 break;
356 case 2:
357 /* decompose Y into Y/Cb */
358 paddr->cb = (u32)(paddr->y + pix_size);
359 paddr->cr = 0;
360 break;
361 case 3:
362 paddr->cb = (u32)(paddr->y + pix_size);
363 /* decompose Y into Y/Cb/Cr */
364 if (FIMC_FMT_YCBCR420 == frame->fmt->color)
365 paddr->cr = (u32)(paddr->cb
366 + (pix_size >> 2));
367 else /* 422 */
368 paddr->cr = (u32)(paddr->cb
369 + (pix_size >> 1));
370 break;
371 default:
372 return -EINVAL;
373 }
374 } else {
375 if (frame->fmt->memplanes >= 2)
376 paddr->cb = vb2_dma_contig_plane_dma_addr(vb, 1);
377
378 if (frame->fmt->memplanes == 3)
379 paddr->cr = vb2_dma_contig_plane_dma_addr(vb, 2);
380 }
381
382 dbg("PHYS_ADDR: y= 0x%X cb= 0x%X cr= 0x%X ret= %d",
383 paddr->y, paddr->cb, paddr->cr, ret);
384
385 return ret;
386}
387
388/* Set order for 1 and 2 plane YCBCR 4:2:2 formats. */
389void fimc_set_yuv_order(struct fimc_ctx *ctx)
390{
391 /* The one only mode supported in SoC. */
392 ctx->in_order_2p = FIMC_REG_CIOCTRL_ORDER422_2P_LSB_CRCB;
393 ctx->out_order_2p = FIMC_REG_CIOCTRL_ORDER422_2P_LSB_CRCB;
394
395 /* Set order for 1 plane input formats. */
396 switch (ctx->s_frame.fmt->color) {
397 case FIMC_FMT_YCRYCB422:
398 ctx->in_order_1p = FIMC_REG_MSCTRL_ORDER422_CBYCRY;
399 break;
400 case FIMC_FMT_CBYCRY422:
401 ctx->in_order_1p = FIMC_REG_MSCTRL_ORDER422_YCRYCB;
402 break;
403 case FIMC_FMT_CRYCBY422:
404 ctx->in_order_1p = FIMC_REG_MSCTRL_ORDER422_YCBYCR;
405 break;
406 case FIMC_FMT_YCBYCR422:
407 default:
408 ctx->in_order_1p = FIMC_REG_MSCTRL_ORDER422_CRYCBY;
409 break;
410 }
411 dbg("ctx->in_order_1p= %d", ctx->in_order_1p);
412
413 switch (ctx->d_frame.fmt->color) {
414 case FIMC_FMT_YCRYCB422:
415 ctx->out_order_1p = FIMC_REG_CIOCTRL_ORDER422_CBYCRY;
416 break;
417 case FIMC_FMT_CBYCRY422:
418 ctx->out_order_1p = FIMC_REG_CIOCTRL_ORDER422_YCRYCB;
419 break;
420 case FIMC_FMT_CRYCBY422:
421 ctx->out_order_1p = FIMC_REG_CIOCTRL_ORDER422_YCBYCR;
422 break;
423 case FIMC_FMT_YCBYCR422:
424 default:
425 ctx->out_order_1p = FIMC_REG_CIOCTRL_ORDER422_CRYCBY;
426 break;
427 }
428 dbg("ctx->out_order_1p= %d", ctx->out_order_1p);
429}
430
431void fimc_prepare_dma_offset(struct fimc_ctx *ctx, struct fimc_frame *f)
432{
433 struct fimc_variant *variant = ctx->fimc_dev->variant;
434 u32 i, depth = 0;
435
436 for (i = 0; i < f->fmt->colplanes; i++)
437 depth += f->fmt->depth[i];
438
439 f->dma_offset.y_h = f->offs_h;
440 if (!variant->pix_hoff)
441 f->dma_offset.y_h *= (depth >> 3);
442
443 f->dma_offset.y_v = f->offs_v;
444
445 f->dma_offset.cb_h = f->offs_h;
446 f->dma_offset.cb_v = f->offs_v;
447
448 f->dma_offset.cr_h = f->offs_h;
449 f->dma_offset.cr_v = f->offs_v;
450
451 if (!variant->pix_hoff) {
452 if (f->fmt->colplanes == 3) {
453 f->dma_offset.cb_h >>= 1;
454 f->dma_offset.cr_h >>= 1;
455 }
456 if (f->fmt->color == FIMC_FMT_YCBCR420) {
457 f->dma_offset.cb_v >>= 1;
458 f->dma_offset.cr_v >>= 1;
459 }
460 }
461
462 dbg("in_offset: color= %d, y_h= %d, y_v= %d",
463 f->fmt->color, f->dma_offset.y_h, f->dma_offset.y_v);
464}
465
466static int fimc_set_color_effect(struct fimc_ctx *ctx, enum v4l2_colorfx colorfx)
467{
468 struct fimc_effect *effect = &ctx->effect;
469
470 switch (colorfx) {
471 case V4L2_COLORFX_NONE:
472 effect->type = FIMC_REG_CIIMGEFF_FIN_BYPASS;
473 break;
474 case V4L2_COLORFX_BW:
475 effect->type = FIMC_REG_CIIMGEFF_FIN_ARBITRARY;
476 effect->pat_cb = 128;
477 effect->pat_cr = 128;
478 break;
479 case V4L2_COLORFX_SEPIA:
480 effect->type = FIMC_REG_CIIMGEFF_FIN_ARBITRARY;
481 effect->pat_cb = 115;
482 effect->pat_cr = 145;
483 break;
484 case V4L2_COLORFX_NEGATIVE:
485 effect->type = FIMC_REG_CIIMGEFF_FIN_NEGATIVE;
486 break;
487 case V4L2_COLORFX_EMBOSS:
488 effect->type = FIMC_REG_CIIMGEFF_FIN_EMBOSSING;
489 break;
490 case V4L2_COLORFX_ART_FREEZE:
491 effect->type = FIMC_REG_CIIMGEFF_FIN_ARTFREEZE;
492 break;
493 case V4L2_COLORFX_SILHOUETTE:
494 effect->type = FIMC_REG_CIIMGEFF_FIN_SILHOUETTE;
495 break;
496 case V4L2_COLORFX_SET_CBCR:
497 effect->type = FIMC_REG_CIIMGEFF_FIN_ARBITRARY;
498 effect->pat_cb = ctx->ctrls.colorfx_cbcr->val >> 8;
499 effect->pat_cr = ctx->ctrls.colorfx_cbcr->val & 0xff;
500 break;
501 default:
502 return -EINVAL;
503 }
504
505 return 0;
506}
507
508/*
509 * V4L2 controls handling
510 */
511#define ctrl_to_ctx(__ctrl) \
512 container_of((__ctrl)->handler, struct fimc_ctx, ctrls.handler)
513
514static int __fimc_s_ctrl(struct fimc_ctx *ctx, struct v4l2_ctrl *ctrl)
515{
516 struct fimc_dev *fimc = ctx->fimc_dev;
517 struct fimc_variant *variant = fimc->variant;
518 unsigned int flags = FIMC_DST_FMT | FIMC_SRC_FMT;
519 int ret = 0;
520
521 if (ctrl->flags & V4L2_CTRL_FLAG_INACTIVE)
522 return 0;
523
524 switch (ctrl->id) {
525 case V4L2_CID_HFLIP:
526 ctx->hflip = ctrl->val;
527 break;
528
529 case V4L2_CID_VFLIP:
530 ctx->vflip = ctrl->val;
531 break;
532
533 case V4L2_CID_ROTATE:
534 if (fimc_capture_pending(fimc) ||
535 (ctx->state & flags) == flags) {
536 ret = fimc_check_scaler_ratio(ctx, ctx->s_frame.width,
537 ctx->s_frame.height, ctx->d_frame.width,
538 ctx->d_frame.height, ctrl->val);
539 if (ret)
540 return -EINVAL;
541 }
542 if ((ctrl->val == 90 || ctrl->val == 270) &&
543 !variant->has_out_rot)
544 return -EINVAL;
545
546 ctx->rotation = ctrl->val;
547 break;
548
549 case V4L2_CID_ALPHA_COMPONENT:
550 ctx->d_frame.alpha = ctrl->val;
551 break;
552
553 case V4L2_CID_COLORFX:
554 ret = fimc_set_color_effect(ctx, ctrl->val);
555 if (ret)
556 return ret;
557 break;
558 }
559
560 ctx->state |= FIMC_PARAMS;
561 set_bit(ST_CAPT_APPLY_CFG, &fimc->state);
562 return 0;
563}
564
565static int fimc_s_ctrl(struct v4l2_ctrl *ctrl)
566{
567 struct fimc_ctx *ctx = ctrl_to_ctx(ctrl);
568 unsigned long flags;
569 int ret;
570
571 spin_lock_irqsave(&ctx->fimc_dev->slock, flags);
572 ret = __fimc_s_ctrl(ctx, ctrl);
573 spin_unlock_irqrestore(&ctx->fimc_dev->slock, flags);
574
575 return ret;
576}
577
578static const struct v4l2_ctrl_ops fimc_ctrl_ops = {
579 .s_ctrl = fimc_s_ctrl,
580};
581
582int fimc_ctrls_create(struct fimc_ctx *ctx)
583{
584 struct fimc_variant *variant = ctx->fimc_dev->variant;
585 unsigned int max_alpha = fimc_get_alpha_mask(ctx->d_frame.fmt);
586 struct fimc_ctrls *ctrls = &ctx->ctrls;
587 struct v4l2_ctrl_handler *handler = &ctrls->handler;
588
589 if (ctx->ctrls.ready)
590 return 0;
591
592 v4l2_ctrl_handler_init(handler, 6);
593
594 ctrls->rotate = v4l2_ctrl_new_std(handler, &fimc_ctrl_ops,
595 V4L2_CID_ROTATE, 0, 270, 90, 0);
596 ctrls->hflip = v4l2_ctrl_new_std(handler, &fimc_ctrl_ops,
597 V4L2_CID_HFLIP, 0, 1, 1, 0);
598 ctrls->vflip = v4l2_ctrl_new_std(handler, &fimc_ctrl_ops,
599 V4L2_CID_VFLIP, 0, 1, 1, 0);
600
601 if (variant->has_alpha)
602 ctrls->alpha = v4l2_ctrl_new_std(handler, &fimc_ctrl_ops,
603 V4L2_CID_ALPHA_COMPONENT,
604 0, max_alpha, 1, 0);
605 else
606 ctrls->alpha = NULL;
607
608 ctrls->colorfx = v4l2_ctrl_new_std_menu(handler, &fimc_ctrl_ops,
609 V4L2_CID_COLORFX, V4L2_COLORFX_SET_CBCR,
610 ~0x983f, V4L2_COLORFX_NONE);
611
612 ctrls->colorfx_cbcr = v4l2_ctrl_new_std(handler, &fimc_ctrl_ops,
613 V4L2_CID_COLORFX_CBCR, 0, 0xffff, 1, 0);
614
615 ctx->effect.type = FIMC_REG_CIIMGEFF_FIN_BYPASS;
616
617 if (!handler->error) {
618 v4l2_ctrl_cluster(2, &ctrls->colorfx);
619 ctrls->ready = true;
620 }
621
622 return handler->error;
623}
624
625void fimc_ctrls_delete(struct fimc_ctx *ctx)
626{
627 struct fimc_ctrls *ctrls = &ctx->ctrls;
628
629 if (ctrls->ready) {
630 v4l2_ctrl_handler_free(&ctrls->handler);
631 ctrls->ready = false;
632 ctrls->alpha = NULL;
633 }
634}
635
636void fimc_ctrls_activate(struct fimc_ctx *ctx, bool active)
637{
638 unsigned int has_alpha = ctx->d_frame.fmt->flags & FMT_HAS_ALPHA;
639 struct fimc_ctrls *ctrls = &ctx->ctrls;
640
641 if (!ctrls->ready)
642 return;
643
644 mutex_lock(ctrls->handler.lock);
645 v4l2_ctrl_activate(ctrls->rotate, active);
646 v4l2_ctrl_activate(ctrls->hflip, active);
647 v4l2_ctrl_activate(ctrls->vflip, active);
648 v4l2_ctrl_activate(ctrls->colorfx, active);
649 if (ctrls->alpha)
650 v4l2_ctrl_activate(ctrls->alpha, active && has_alpha);
651
652 if (active) {
653 fimc_set_color_effect(ctx, ctrls->colorfx->cur.val);
654 ctx->rotation = ctrls->rotate->val;
655 ctx->hflip = ctrls->hflip->val;
656 ctx->vflip = ctrls->vflip->val;
657 } else {
658 ctx->effect.type = FIMC_REG_CIIMGEFF_FIN_BYPASS;
659 ctx->rotation = 0;
660 ctx->hflip = 0;
661 ctx->vflip = 0;
662 }
663 mutex_unlock(ctrls->handler.lock);
664}
665
666/* Update maximum value of the alpha color control */
667void fimc_alpha_ctrl_update(struct fimc_ctx *ctx)
668{
669 struct fimc_dev *fimc = ctx->fimc_dev;
670 struct v4l2_ctrl *ctrl = ctx->ctrls.alpha;
671
672 if (ctrl == NULL || !fimc->variant->has_alpha)
673 return;
674
675 v4l2_ctrl_lock(ctrl);
676 ctrl->maximum = fimc_get_alpha_mask(ctx->d_frame.fmt);
677
678 if (ctrl->cur.val > ctrl->maximum)
679 ctrl->cur.val = ctrl->maximum;
680
681 v4l2_ctrl_unlock(ctrl);
682}
683
684int fimc_fill_format(struct fimc_frame *frame, struct v4l2_format *f)
685{
686 struct v4l2_pix_format_mplane *pixm = &f->fmt.pix_mp;
687 int i;
688
689 pixm->width = frame->o_width;
690 pixm->height = frame->o_height;
691 pixm->field = V4L2_FIELD_NONE;
692 pixm->pixelformat = frame->fmt->fourcc;
693 pixm->colorspace = V4L2_COLORSPACE_JPEG;
694 pixm->num_planes = frame->fmt->memplanes;
695
696 for (i = 0; i < pixm->num_planes; ++i) {
697 int bpl = frame->f_width;
698 if (frame->fmt->colplanes == 1) /* packed formats */
699 bpl = (bpl * frame->fmt->depth[0]) / 8;
700 pixm->plane_fmt[i].bytesperline = bpl;
701 pixm->plane_fmt[i].sizeimage = (frame->o_width *
702 frame->o_height * frame->fmt->depth[i]) / 8;
703 }
704 return 0;
705}
706
707void fimc_fill_frame(struct fimc_frame *frame, struct v4l2_format *f)
708{
709 struct v4l2_pix_format_mplane *pixm = &f->fmt.pix_mp;
710
711 frame->f_width = pixm->plane_fmt[0].bytesperline;
712 if (frame->fmt->colplanes == 1)
713 frame->f_width = (frame->f_width * 8) / frame->fmt->depth[0];
714 frame->f_height = pixm->height;
715 frame->width = pixm->width;
716 frame->height = pixm->height;
717 frame->o_width = pixm->width;
718 frame->o_height = pixm->height;
719 frame->offs_h = 0;
720 frame->offs_v = 0;
721}
722
723/**
724 * fimc_adjust_mplane_format - adjust bytesperline/sizeimage for each plane
725 * @fmt: fimc pixel format description (input)
726 * @width: requested pixel width
727 * @height: requested pixel height
728 * @pix: multi-plane format to adjust
729 */
730void fimc_adjust_mplane_format(struct fimc_fmt *fmt, u32 width, u32 height,
731 struct v4l2_pix_format_mplane *pix)
732{
733 u32 bytesperline = 0;
734 int i;
735
736 pix->colorspace = V4L2_COLORSPACE_JPEG;
737 pix->field = V4L2_FIELD_NONE;
738 pix->num_planes = fmt->memplanes;
739 pix->pixelformat = fmt->fourcc;
740 pix->height = height;
741 pix->width = width;
742
743 for (i = 0; i < pix->num_planes; ++i) {
744 struct v4l2_plane_pix_format *plane_fmt = &pix->plane_fmt[i];
745 u32 bpl = plane_fmt->bytesperline;
746
747 if (fmt->colplanes > 1 && (bpl == 0 || bpl < pix->width))
748 bpl = pix->width; /* Planar */
749
750 if (fmt->colplanes == 1 && /* Packed */
751 (bpl == 0 || ((bpl * 8) / fmt->depth[i]) < pix->width))
752 bpl = (pix->width * fmt->depth[0]) / 8;
753
754 if (i == 0) /* Same bytesperline for each plane. */
755 bytesperline = bpl;
756
757 plane_fmt->bytesperline = bytesperline;
758 plane_fmt->sizeimage = max((pix->width * pix->height *
759 fmt->depth[i]) / 8, plane_fmt->sizeimage);
760 }
761}
762
763/**
764 * fimc_find_format - lookup fimc color format by fourcc or media bus format
765 * @pixelformat: fourcc to match, ignored if null
766 * @mbus_code: media bus code to match, ignored if null
767 * @mask: the color flags to match
768 * @index: offset in the fimc_formats array, ignored if negative
769 */
770struct fimc_fmt *fimc_find_format(const u32 *pixelformat, const u32 *mbus_code,
771 unsigned int mask, int index)
772{
773 struct fimc_fmt *fmt, *def_fmt = NULL;
774 unsigned int i;
775 int id = 0;
776
777 if (index >= (int)ARRAY_SIZE(fimc_formats))
778 return NULL;
779
780 for (i = 0; i < ARRAY_SIZE(fimc_formats); ++i) {
781 fmt = &fimc_formats[i];
782 if (!(fmt->flags & mask))
783 continue;
784 if (pixelformat && fmt->fourcc == *pixelformat)
785 return fmt;
786 if (mbus_code && fmt->mbus_code == *mbus_code)
787 return fmt;
788 if (index == id)
789 def_fmt = fmt;
790 id++;
791 }
792 return def_fmt;
793}
794
795static void fimc_clk_put(struct fimc_dev *fimc)
796{
797 int i;
798 for (i = 0; i < MAX_FIMC_CLOCKS; i++) {
799 if (IS_ERR_OR_NULL(fimc->clock[i]))
800 continue;
801 clk_unprepare(fimc->clock[i]);
802 clk_put(fimc->clock[i]);
803 fimc->clock[i] = NULL;
804 }
805}
806
807static int fimc_clk_get(struct fimc_dev *fimc)
808{
809 int i, ret;
810
811 for (i = 0; i < MAX_FIMC_CLOCKS; i++) {
812 fimc->clock[i] = clk_get(&fimc->pdev->dev, fimc_clocks[i]);
813 if (IS_ERR(fimc->clock[i]))
814 goto err;
815 ret = clk_prepare(fimc->clock[i]);
816 if (ret < 0) {
817 clk_put(fimc->clock[i]);
818 fimc->clock[i] = NULL;
819 goto err;
820 }
821 }
822 return 0;
823err:
824 fimc_clk_put(fimc);
825 dev_err(&fimc->pdev->dev, "failed to get clock: %s\n",
826 fimc_clocks[i]);
827 return -ENXIO;
828}
829
830static int fimc_m2m_suspend(struct fimc_dev *fimc)
831{
832 unsigned long flags;
833 int timeout;
834
835 spin_lock_irqsave(&fimc->slock, flags);
836 if (!fimc_m2m_pending(fimc)) {
837 spin_unlock_irqrestore(&fimc->slock, flags);
838 return 0;
839 }
840 clear_bit(ST_M2M_SUSPENDED, &fimc->state);
841 set_bit(ST_M2M_SUSPENDING, &fimc->state);
842 spin_unlock_irqrestore(&fimc->slock, flags);
843
844 timeout = wait_event_timeout(fimc->irq_queue,
845 test_bit(ST_M2M_SUSPENDED, &fimc->state),
846 FIMC_SHUTDOWN_TIMEOUT);
847
848 clear_bit(ST_M2M_SUSPENDING, &fimc->state);
849 return timeout == 0 ? -EAGAIN : 0;
850}
851
852static int fimc_m2m_resume(struct fimc_dev *fimc)
853{
854 unsigned long flags;
855
856 spin_lock_irqsave(&fimc->slock, flags);
857 /* Clear for full H/W setup in first run after resume */
858 fimc->m2m.ctx = NULL;
859 spin_unlock_irqrestore(&fimc->slock, flags);
860
861 if (test_and_clear_bit(ST_M2M_SUSPENDED, &fimc->state))
862 fimc_m2m_job_finish(fimc->m2m.ctx,
863 VB2_BUF_STATE_ERROR);
864 return 0;
865}
866
867static int fimc_probe(struct platform_device *pdev)
868{
869 struct fimc_drvdata *drv_data = fimc_get_drvdata(pdev);
870 struct s5p_platform_fimc *pdata;
871 struct fimc_dev *fimc;
872 struct resource *res;
873 int ret = 0;
874
875 if (pdev->id >= drv_data->num_entities) {
876 dev_err(&pdev->dev, "Invalid platform device id: %d\n",
877 pdev->id);
878 return -EINVAL;
879 }
880
881 fimc = devm_kzalloc(&pdev->dev, sizeof(*fimc), GFP_KERNEL);
882 if (!fimc)
883 return -ENOMEM;
884
885 fimc->id = pdev->id;
886
887 fimc->variant = drv_data->variant[fimc->id];
888 fimc->pdev = pdev;
889 pdata = pdev->dev.platform_data;
890 fimc->pdata = pdata;
891
892 init_waitqueue_head(&fimc->irq_queue);
893 spin_lock_init(&fimc->slock);
894 mutex_init(&fimc->lock);
895
896 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
897 fimc->regs = devm_request_and_ioremap(&pdev->dev, res);
898 if (fimc->regs == NULL) {
899 dev_err(&pdev->dev, "Failed to obtain io memory\n");
900 return -ENOENT;
901 }
902
903 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
904 if (res == NULL) {
905 dev_err(&pdev->dev, "Failed to get IRQ resource\n");
906 return -ENXIO;
907 }
908
909 ret = fimc_clk_get(fimc);
910 if (ret)
911 return ret;
912 clk_set_rate(fimc->clock[CLK_BUS], drv_data->lclk_frequency);
913 clk_enable(fimc->clock[CLK_BUS]);
914
915 ret = devm_request_irq(&pdev->dev, res->start, fimc_irq_handler,
916 0, dev_name(&pdev->dev), fimc);
917 if (ret) {
918 dev_err(&pdev->dev, "failed to install irq (%d)\n", ret);
919 goto err_clk;
920 }
921
922 ret = fimc_initialize_capture_subdev(fimc);
923 if (ret)
924 goto err_clk;
925
926 platform_set_drvdata(pdev, fimc);
927 pm_runtime_enable(&pdev->dev);
928 ret = pm_runtime_get_sync(&pdev->dev);
929 if (ret < 0)
930 goto err_sd;
931 /* Initialize contiguous memory allocator */
932 fimc->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
933 if (IS_ERR(fimc->alloc_ctx)) {
934 ret = PTR_ERR(fimc->alloc_ctx);
935 goto err_pm;
936 }
937
938 dev_dbg(&pdev->dev, "FIMC.%d registered successfully\n", fimc->id);
939
940 pm_runtime_put(&pdev->dev);
941 return 0;
942err_pm:
943 pm_runtime_put(&pdev->dev);
944err_sd:
945 fimc_unregister_capture_subdev(fimc);
946err_clk:
947 fimc_clk_put(fimc);
948 return ret;
949}
950
951static int fimc_runtime_resume(struct device *dev)
952{
953 struct fimc_dev *fimc = dev_get_drvdata(dev);
954
955 dbg("fimc%d: state: 0x%lx", fimc->id, fimc->state);
956
957 /* Enable clocks and perform basic initalization */
958 clk_enable(fimc->clock[CLK_GATE]);
959 fimc_hw_reset(fimc);
960
961 /* Resume the capture or mem-to-mem device */
962 if (fimc_capture_busy(fimc))
963 return fimc_capture_resume(fimc);
964
965 return fimc_m2m_resume(fimc);
966}
967
968static int fimc_runtime_suspend(struct device *dev)
969{
970 struct fimc_dev *fimc = dev_get_drvdata(dev);
971 int ret = 0;
972
973 if (fimc_capture_busy(fimc))
974 ret = fimc_capture_suspend(fimc);
975 else
976 ret = fimc_m2m_suspend(fimc);
977 if (!ret)
978 clk_disable(fimc->clock[CLK_GATE]);
979
980 dbg("fimc%d: state: 0x%lx", fimc->id, fimc->state);
981 return ret;
982}
983
984#ifdef CONFIG_PM_SLEEP
985static int fimc_resume(struct device *dev)
986{
987 struct fimc_dev *fimc = dev_get_drvdata(dev);
988 unsigned long flags;
989
990 dbg("fimc%d: state: 0x%lx", fimc->id, fimc->state);
991
992 /* Do not resume if the device was idle before system suspend */
993 spin_lock_irqsave(&fimc->slock, flags);
994 if (!test_and_clear_bit(ST_LPM, &fimc->state) ||
995 (!fimc_m2m_active(fimc) && !fimc_capture_busy(fimc))) {
996 spin_unlock_irqrestore(&fimc->slock, flags);
997 return 0;
998 }
999 fimc_hw_reset(fimc);
1000 spin_unlock_irqrestore(&fimc->slock, flags);
1001
1002 if (fimc_capture_busy(fimc))
1003 return fimc_capture_resume(fimc);
1004
1005 return fimc_m2m_resume(fimc);
1006}
1007
1008static int fimc_suspend(struct device *dev)
1009{
1010 struct fimc_dev *fimc = dev_get_drvdata(dev);
1011
1012 dbg("fimc%d: state: 0x%lx", fimc->id, fimc->state);
1013
1014 if (test_and_set_bit(ST_LPM, &fimc->state))
1015 return 0;
1016 if (fimc_capture_busy(fimc))
1017 return fimc_capture_suspend(fimc);
1018
1019 return fimc_m2m_suspend(fimc);
1020}
1021#endif /* CONFIG_PM_SLEEP */
1022
1023static int __devexit fimc_remove(struct platform_device *pdev)
1024{
1025 struct fimc_dev *fimc = platform_get_drvdata(pdev);
1026
1027 pm_runtime_disable(&pdev->dev);
1028 pm_runtime_set_suspended(&pdev->dev);
1029
1030 fimc_unregister_capture_subdev(fimc);
1031 vb2_dma_contig_cleanup_ctx(fimc->alloc_ctx);
1032
1033 clk_disable(fimc->clock[CLK_BUS]);
1034 fimc_clk_put(fimc);
1035
1036 dev_info(&pdev->dev, "driver unloaded\n");
1037 return 0;
1038}
1039
1040/* Image pixel limits, similar across several FIMC HW revisions. */
1041static struct fimc_pix_limit s5p_pix_limit[4] = {
1042 [0] = {
1043 .scaler_en_w = 3264,
1044 .scaler_dis_w = 8192,
1045 .in_rot_en_h = 1920,
1046 .in_rot_dis_w = 8192,
1047 .out_rot_en_w = 1920,
1048 .out_rot_dis_w = 4224,
1049 },
1050 [1] = {
1051 .scaler_en_w = 4224,
1052 .scaler_dis_w = 8192,
1053 .in_rot_en_h = 1920,
1054 .in_rot_dis_w = 8192,
1055 .out_rot_en_w = 1920,
1056 .out_rot_dis_w = 4224,
1057 },
1058 [2] = {
1059 .scaler_en_w = 1920,
1060 .scaler_dis_w = 8192,
1061 .in_rot_en_h = 1280,
1062 .in_rot_dis_w = 8192,
1063 .out_rot_en_w = 1280,
1064 .out_rot_dis_w = 1920,
1065 },
1066 [3] = {
1067 .scaler_en_w = 1920,
1068 .scaler_dis_w = 8192,
1069 .in_rot_en_h = 1366,
1070 .in_rot_dis_w = 8192,
1071 .out_rot_en_w = 1366,
1072 .out_rot_dis_w = 1920,
1073 },
1074};
1075
1076static struct fimc_variant fimc0_variant_s5p = {
1077 .has_inp_rot = 1,
1078 .has_out_rot = 1,
1079 .has_cam_if = 1,
1080 .min_inp_pixsize = 16,
1081 .min_out_pixsize = 16,
1082 .hor_offs_align = 8,
1083 .min_vsize_align = 16,
1084 .out_buf_count = 4,
1085 .pix_limit = &s5p_pix_limit[0],
1086};
1087
1088static struct fimc_variant fimc2_variant_s5p = {
1089 .has_cam_if = 1,
1090 .min_inp_pixsize = 16,
1091 .min_out_pixsize = 16,
1092 .hor_offs_align = 8,
1093 .min_vsize_align = 16,
1094 .out_buf_count = 4,
1095 .pix_limit = &s5p_pix_limit[1],
1096};
1097
1098static struct fimc_variant fimc0_variant_s5pv210 = {
1099 .pix_hoff = 1,
1100 .has_inp_rot = 1,
1101 .has_out_rot = 1,
1102 .has_cam_if = 1,
1103 .min_inp_pixsize = 16,
1104 .min_out_pixsize = 16,
1105 .hor_offs_align = 8,
1106 .min_vsize_align = 16,
1107 .out_buf_count = 4,
1108 .pix_limit = &s5p_pix_limit[1],
1109};
1110
1111static struct fimc_variant fimc1_variant_s5pv210 = {
1112 .pix_hoff = 1,
1113 .has_inp_rot = 1,
1114 .has_out_rot = 1,
1115 .has_cam_if = 1,
1116 .has_mainscaler_ext = 1,
1117 .min_inp_pixsize = 16,
1118 .min_out_pixsize = 16,
1119 .hor_offs_align = 1,
1120 .min_vsize_align = 1,
1121 .out_buf_count = 4,
1122 .pix_limit = &s5p_pix_limit[2],
1123};
1124
1125static struct fimc_variant fimc2_variant_s5pv210 = {
1126 .has_cam_if = 1,
1127 .pix_hoff = 1,
1128 .min_inp_pixsize = 16,
1129 .min_out_pixsize = 16,
1130 .hor_offs_align = 8,
1131 .min_vsize_align = 16,
1132 .out_buf_count = 4,
1133 .pix_limit = &s5p_pix_limit[2],
1134};
1135
1136static struct fimc_variant fimc0_variant_exynos4 = {
1137 .pix_hoff = 1,
1138 .has_inp_rot = 1,
1139 .has_out_rot = 1,
1140 .has_cam_if = 1,
1141 .has_cistatus2 = 1,
1142 .has_mainscaler_ext = 1,
1143 .has_alpha = 1,
1144 .min_inp_pixsize = 16,
1145 .min_out_pixsize = 16,
1146 .hor_offs_align = 2,
1147 .min_vsize_align = 1,
1148 .out_buf_count = 32,
1149 .pix_limit = &s5p_pix_limit[1],
1150};
1151
1152static struct fimc_variant fimc3_variant_exynos4 = {
1153 .pix_hoff = 1,
1154 .has_cam_if = 1,
1155 .has_cistatus2 = 1,
1156 .has_mainscaler_ext = 1,
1157 .has_alpha = 1,
1158 .min_inp_pixsize = 16,
1159 .min_out_pixsize = 16,
1160 .hor_offs_align = 2,
1161 .min_vsize_align = 1,
1162 .out_buf_count = 32,
1163 .pix_limit = &s5p_pix_limit[3],
1164};
1165
1166/* S5PC100 */
1167static struct fimc_drvdata fimc_drvdata_s5p = {
1168 .variant = {
1169 [0] = &fimc0_variant_s5p,
1170 [1] = &fimc0_variant_s5p,
1171 [2] = &fimc2_variant_s5p,
1172 },
1173 .num_entities = 3,
1174 .lclk_frequency = 133000000UL,
1175};
1176
1177/* S5PV210, S5PC110 */
1178static struct fimc_drvdata fimc_drvdata_s5pv210 = {
1179 .variant = {
1180 [0] = &fimc0_variant_s5pv210,
1181 [1] = &fimc1_variant_s5pv210,
1182 [2] = &fimc2_variant_s5pv210,
1183 },
1184 .num_entities = 3,
1185 .lclk_frequency = 166000000UL,
1186};
1187
1188/* EXYNOS4210, S5PV310, S5PC210 */
1189static struct fimc_drvdata fimc_drvdata_exynos4 = {
1190 .variant = {
1191 [0] = &fimc0_variant_exynos4,
1192 [1] = &fimc0_variant_exynos4,
1193 [2] = &fimc0_variant_exynos4,
1194 [3] = &fimc3_variant_exynos4,
1195 },
1196 .num_entities = 4,
1197 .lclk_frequency = 166000000UL,
1198};
1199
1200static struct platform_device_id fimc_driver_ids[] = {
1201 {
1202 .name = "s5p-fimc",
1203 .driver_data = (unsigned long)&fimc_drvdata_s5p,
1204 }, {
1205 .name = "s5pv210-fimc",
1206 .driver_data = (unsigned long)&fimc_drvdata_s5pv210,
1207 }, {
1208 .name = "exynos4-fimc",
1209 .driver_data = (unsigned long)&fimc_drvdata_exynos4,
1210 },
1211 {},
1212};
1213MODULE_DEVICE_TABLE(platform, fimc_driver_ids);
1214
1215static const struct dev_pm_ops fimc_pm_ops = {
1216 SET_SYSTEM_SLEEP_PM_OPS(fimc_suspend, fimc_resume)
1217 SET_RUNTIME_PM_OPS(fimc_runtime_suspend, fimc_runtime_resume, NULL)
1218};
1219
1220static struct platform_driver fimc_driver = {
1221 .probe = fimc_probe,
1222 .remove = __devexit_p(fimc_remove),
1223 .id_table = fimc_driver_ids,
1224 .driver = {
1225 .name = FIMC_MODULE_NAME,
1226 .owner = THIS_MODULE,
1227 .pm = &fimc_pm_ops,
1228 }
1229};
1230
1231int __init fimc_register_driver(void)
1232{
1233 return platform_driver_register(&fimc_driver);
1234}
1235
1236void __exit fimc_unregister_driver(void)
1237{
1238 platform_driver_unregister(&fimc_driver);
1239}
diff --git a/drivers/media/video/s5p-fimc/fimc-core.h b/drivers/media/video/s5p-fimc/fimc-core.h
deleted file mode 100644
index 808ccc621846..000000000000
--- a/drivers/media/video/s5p-fimc/fimc-core.h
+++ /dev/null
@@ -1,713 +0,0 @@
1/*
2 * Copyright (C) 2010 - 2012 Samsung Electronics Co., Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#ifndef FIMC_CORE_H_
10#define FIMC_CORE_H_
11
12/*#define DEBUG*/
13
14#include <linux/platform_device.h>
15#include <linux/sched.h>
16#include <linux/spinlock.h>
17#include <linux/types.h>
18#include <linux/videodev2.h>
19#include <linux/io.h>
20#include <asm/sizes.h>
21
22#include <media/media-entity.h>
23#include <media/videobuf2-core.h>
24#include <media/v4l2-ctrls.h>
25#include <media/v4l2-device.h>
26#include <media/v4l2-mem2mem.h>
27#include <media/v4l2-mediabus.h>
28#include <media/s5p_fimc.h>
29
30#define dbg(fmt, args...) \
31 pr_debug("%s:%d: " fmt "\n", __func__, __LINE__, ##args)
32
33/* Time to wait for next frame VSYNC interrupt while stopping operation. */
34#define FIMC_SHUTDOWN_TIMEOUT ((100*HZ)/1000)
35#define MAX_FIMC_CLOCKS 2
36#define FIMC_MODULE_NAME "s5p-fimc"
37#define FIMC_MAX_DEVS 4
38#define FIMC_MAX_OUT_BUFS 4
39#define SCALER_MAX_HRATIO 64
40#define SCALER_MAX_VRATIO 64
41#define DMA_MIN_SIZE 8
42#define FIMC_CAMIF_MAX_HEIGHT 0x2000
43
44/* indices to the clocks array */
45enum {
46 CLK_BUS,
47 CLK_GATE,
48};
49
50enum fimc_dev_flags {
51 ST_LPM,
52 /* m2m node */
53 ST_M2M_RUN,
54 ST_M2M_PEND,
55 ST_M2M_SUSPENDING,
56 ST_M2M_SUSPENDED,
57 /* capture node */
58 ST_CAPT_PEND,
59 ST_CAPT_RUN,
60 ST_CAPT_STREAM,
61 ST_CAPT_ISP_STREAM,
62 ST_CAPT_SUSPENDED,
63 ST_CAPT_SHUT,
64 ST_CAPT_BUSY,
65 ST_CAPT_APPLY_CFG,
66 ST_CAPT_JPEG,
67};
68
69#define fimc_m2m_active(dev) test_bit(ST_M2M_RUN, &(dev)->state)
70#define fimc_m2m_pending(dev) test_bit(ST_M2M_PEND, &(dev)->state)
71
72#define fimc_capture_running(dev) test_bit(ST_CAPT_RUN, &(dev)->state)
73#define fimc_capture_pending(dev) test_bit(ST_CAPT_PEND, &(dev)->state)
74#define fimc_capture_busy(dev) test_bit(ST_CAPT_BUSY, &(dev)->state)
75
76enum fimc_datapath {
77 FIMC_IO_NONE,
78 FIMC_IO_CAMERA,
79 FIMC_IO_DMA,
80 FIMC_IO_LCDFIFO,
81 FIMC_IO_WRITEBACK,
82 FIMC_IO_ISP,
83};
84
85enum fimc_color_fmt {
86 FIMC_FMT_RGB444 = 0x10,
87 FIMC_FMT_RGB555,
88 FIMC_FMT_RGB565,
89 FIMC_FMT_RGB666,
90 FIMC_FMT_RGB888,
91 FIMC_FMT_RGB30_LOCAL,
92 FIMC_FMT_YCBCR420 = 0x20,
93 FIMC_FMT_YCBYCR422,
94 FIMC_FMT_YCRYCB422,
95 FIMC_FMT_CBYCRY422,
96 FIMC_FMT_CRYCBY422,
97 FIMC_FMT_YCBCR444_LOCAL,
98 FIMC_FMT_JPEG = 0x40,
99 FIMC_FMT_RAW8 = 0x80,
100 FIMC_FMT_RAW10,
101 FIMC_FMT_RAW12,
102};
103
104#define fimc_fmt_is_rgb(x) (!!((x) & 0x10))
105#define fimc_fmt_is_jpeg(x) (!!((x) & 0x40))
106
107#define IS_M2M(__strt) ((__strt) == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE || \
108 __strt == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
109
110/* The hardware context state. */
111#define FIMC_PARAMS (1 << 0)
112#define FIMC_SRC_FMT (1 << 3)
113#define FIMC_DST_FMT (1 << 4)
114#define FIMC_COMPOSE (1 << 5)
115#define FIMC_CTX_M2M (1 << 16)
116#define FIMC_CTX_CAP (1 << 17)
117#define FIMC_CTX_SHUT (1 << 18)
118
119/* Image conversion flags */
120#define FIMC_IN_DMA_ACCESS_TILED (1 << 0)
121#define FIMC_IN_DMA_ACCESS_LINEAR (0 << 0)
122#define FIMC_OUT_DMA_ACCESS_TILED (1 << 1)
123#define FIMC_OUT_DMA_ACCESS_LINEAR (0 << 1)
124#define FIMC_SCAN_MODE_PROGRESSIVE (0 << 2)
125#define FIMC_SCAN_MODE_INTERLACED (1 << 2)
126/*
127 * YCbCr data dynamic range for RGB-YUV color conversion.
128 * Y/Cb/Cr: (0 ~ 255) */
129#define FIMC_COLOR_RANGE_WIDE (0 << 3)
130/* Y (16 ~ 235), Cb/Cr (16 ~ 240) */
131#define FIMC_COLOR_RANGE_NARROW (1 << 3)
132
133/**
134 * struct fimc_fmt - the driver's internal color format data
135 * @mbus_code: Media Bus pixel code, -1 if not applicable
136 * @name: format description
137 * @fourcc: the fourcc code for this format, 0 if not applicable
138 * @color: the corresponding fimc_color_fmt
139 * @memplanes: number of physically non-contiguous data planes
140 * @colplanes: number of physically contiguous data planes
141 * @depth: per plane driver's private 'number of bits per pixel'
142 * @flags: flags indicating which operation mode format applies to
143 */
144struct fimc_fmt {
145 enum v4l2_mbus_pixelcode mbus_code;
146 char *name;
147 u32 fourcc;
148 u32 color;
149 u16 memplanes;
150 u16 colplanes;
151 u8 depth[VIDEO_MAX_PLANES];
152 u16 flags;
153#define FMT_FLAGS_CAM (1 << 0)
154#define FMT_FLAGS_M2M_IN (1 << 1)
155#define FMT_FLAGS_M2M_OUT (1 << 2)
156#define FMT_FLAGS_M2M (1 << 1 | 1 << 2)
157#define FMT_HAS_ALPHA (1 << 3)
158};
159
160/**
161 * struct fimc_dma_offset - pixel offset information for DMA
162 * @y_h: y value horizontal offset
163 * @y_v: y value vertical offset
164 * @cb_h: cb value horizontal offset
165 * @cb_v: cb value vertical offset
166 * @cr_h: cr value horizontal offset
167 * @cr_v: cr value vertical offset
168 */
169struct fimc_dma_offset {
170 int y_h;
171 int y_v;
172 int cb_h;
173 int cb_v;
174 int cr_h;
175 int cr_v;
176};
177
178/**
179 * struct fimc_effect - color effect information
180 * @type: effect type
181 * @pat_cb: cr value when type is "arbitrary"
182 * @pat_cr: cr value when type is "arbitrary"
183 */
184struct fimc_effect {
185 u32 type;
186 u8 pat_cb;
187 u8 pat_cr;
188};
189
190/**
191 * struct fimc_scaler - the configuration data for FIMC inetrnal scaler
192 * @scaleup_h: flag indicating scaling up horizontally
193 * @scaleup_v: flag indicating scaling up vertically
194 * @copy_mode: flag indicating transparent DMA transfer (no scaling
195 * and color format conversion)
196 * @enabled: flag indicating if the scaler is used
197 * @hfactor: horizontal shift factor
198 * @vfactor: vertical shift factor
199 * @pre_hratio: horizontal ratio of the prescaler
200 * @pre_vratio: vertical ratio of the prescaler
201 * @pre_dst_width: the prescaler's destination width
202 * @pre_dst_height: the prescaler's destination height
203 * @main_hratio: the main scaler's horizontal ratio
204 * @main_vratio: the main scaler's vertical ratio
205 * @real_width: source pixel (width - offset)
206 * @real_height: source pixel (height - offset)
207 */
208struct fimc_scaler {
209 unsigned int scaleup_h:1;
210 unsigned int scaleup_v:1;
211 unsigned int copy_mode:1;
212 unsigned int enabled:1;
213 u32 hfactor;
214 u32 vfactor;
215 u32 pre_hratio;
216 u32 pre_vratio;
217 u32 pre_dst_width;
218 u32 pre_dst_height;
219 u32 main_hratio;
220 u32 main_vratio;
221 u32 real_width;
222 u32 real_height;
223};
224
225/**
226 * struct fimc_addr - the FIMC physical address set for DMA
227 * @y: luminance plane physical address
228 * @cb: Cb plane physical address
229 * @cr: Cr plane physical address
230 */
231struct fimc_addr {
232 u32 y;
233 u32 cb;
234 u32 cr;
235};
236
237/**
238 * struct fimc_vid_buffer - the driver's video buffer
239 * @vb: v4l videobuf buffer
240 * @list: linked list structure for buffer queue
241 * @paddr: precalculated physical address set
242 * @index: buffer index for the output DMA engine
243 */
244struct fimc_vid_buffer {
245 struct vb2_buffer vb;
246 struct list_head list;
247 struct fimc_addr paddr;
248 int index;
249};
250
251/**
252 * struct fimc_frame - source/target frame properties
253 * @f_width: image full width (virtual screen size)
254 * @f_height: image full height (virtual screen size)
255 * @o_width: original image width as set by S_FMT
256 * @o_height: original image height as set by S_FMT
257 * @offs_h: image horizontal pixel offset
258 * @offs_v: image vertical pixel offset
259 * @width: image pixel width
260 * @height: image pixel weight
261 * @payload: image size in bytes (w x h x bpp)
262 * @paddr: image frame buffer physical addresses
263 * @dma_offset: DMA offset in bytes
264 * @fmt: fimc color format pointer
265 */
266struct fimc_frame {
267 u32 f_width;
268 u32 f_height;
269 u32 o_width;
270 u32 o_height;
271 u32 offs_h;
272 u32 offs_v;
273 u32 width;
274 u32 height;
275 unsigned long payload[VIDEO_MAX_PLANES];
276 struct fimc_addr paddr;
277 struct fimc_dma_offset dma_offset;
278 struct fimc_fmt *fmt;
279 u8 alpha;
280};
281
282/**
283 * struct fimc_m2m_device - v4l2 memory-to-memory device data
284 * @vfd: the video device node for v4l2 m2m mode
285 * @m2m_dev: v4l2 memory-to-memory device data
286 * @ctx: hardware context data
287 * @refcnt: the reference counter
288 */
289struct fimc_m2m_device {
290 struct video_device *vfd;
291 struct v4l2_m2m_dev *m2m_dev;
292 struct fimc_ctx *ctx;
293 int refcnt;
294};
295
296#define FIMC_SD_PAD_SINK 0
297#define FIMC_SD_PAD_SOURCE 1
298#define FIMC_SD_PADS_NUM 2
299
300/**
301 * struct fimc_vid_cap - camera capture device information
302 * @ctx: hardware context data
303 * @vfd: video device node for camera capture mode
304 * @subdev: subdev exposing the FIMC processing block
305 * @vd_pad: fimc video capture node pad
306 * @sd_pads: fimc video processing block pads
307 * @mf: media bus format at the FIMC camera input (and the scaler output) pad
308 * @pending_buf_q: the pending buffer queue head
309 * @active_buf_q: the queue head of buffers scheduled in hardware
310 * @vbq: the capture am video buffer queue
311 * @active_buf_cnt: number of video buffers scheduled in hardware
312 * @buf_index: index for managing the output DMA buffers
313 * @frame_count: the frame counter for statistics
314 * @reqbufs_count: the number of buffers requested in REQBUFS ioctl
315 * @input_index: input (camera sensor) index
316 * @refcnt: driver's private reference counter
317 * @input: capture input type, grp_id of the attached subdev
318 * @user_subdev_api: true if subdevs are not configured by the host driver
319 */
320struct fimc_vid_cap {
321 struct fimc_ctx *ctx;
322 struct vb2_alloc_ctx *alloc_ctx;
323 struct video_device *vfd;
324 struct v4l2_subdev subdev;
325 struct media_pad vd_pad;
326 struct v4l2_mbus_framefmt mf;
327 struct media_pad sd_pads[FIMC_SD_PADS_NUM];
328 struct list_head pending_buf_q;
329 struct list_head active_buf_q;
330 struct vb2_queue vbq;
331 int active_buf_cnt;
332 int buf_index;
333 unsigned int frame_count;
334 unsigned int reqbufs_count;
335 int input_index;
336 int refcnt;
337 u32 input;
338 bool user_subdev_api;
339};
340
341/**
342 * struct fimc_pix_limit - image pixel size limits in various IP configurations
343 *
344 * @scaler_en_w: max input pixel width when the scaler is enabled
345 * @scaler_dis_w: max input pixel width when the scaler is disabled
346 * @in_rot_en_h: max input width with the input rotator is on
347 * @in_rot_dis_w: max input width with the input rotator is off
348 * @out_rot_en_w: max output width with the output rotator on
349 * @out_rot_dis_w: max output width with the output rotator off
350 */
351struct fimc_pix_limit {
352 u16 scaler_en_w;
353 u16 scaler_dis_w;
354 u16 in_rot_en_h;
355 u16 in_rot_dis_w;
356 u16 out_rot_en_w;
357 u16 out_rot_dis_w;
358};
359
360/**
361 * struct fimc_variant - FIMC device variant information
362 * @pix_hoff: indicate whether horizontal offset is in pixels or in bytes
363 * @has_inp_rot: set if has input rotator
364 * @has_out_rot: set if has output rotator
365 * @has_cistatus2: 1 if CISTATUS2 register is present in this IP revision
366 * @has_mainscaler_ext: 1 if extended mainscaler ratios in CIEXTEN register
367 * are present in this IP revision
368 * @has_cam_if: set if this instance has a camera input interface
369 * @pix_limit: pixel size constraints for the scaler
370 * @min_inp_pixsize: minimum input pixel size
371 * @min_out_pixsize: minimum output pixel size
372 * @hor_offs_align: horizontal pixel offset aligment
373 * @min_vsize_align: minimum vertical pixel size alignment
374 * @out_buf_count: the number of buffers in output DMA sequence
375 */
376struct fimc_variant {
377 unsigned int pix_hoff:1;
378 unsigned int has_inp_rot:1;
379 unsigned int has_out_rot:1;
380 unsigned int has_cistatus2:1;
381 unsigned int has_mainscaler_ext:1;
382 unsigned int has_cam_if:1;
383 unsigned int has_alpha:1;
384 struct fimc_pix_limit *pix_limit;
385 u16 min_inp_pixsize;
386 u16 min_out_pixsize;
387 u16 hor_offs_align;
388 u16 min_vsize_align;
389 u16 out_buf_count;
390};
391
392/**
393 * struct fimc_drvdata - per device type driver data
394 * @variant: variant information for this device
395 * @num_entities: number of fimc instances available in a SoC
396 * @lclk_frequency: local bus clock frequency
397 */
398struct fimc_drvdata {
399 struct fimc_variant *variant[FIMC_MAX_DEVS];
400 int num_entities;
401 unsigned long lclk_frequency;
402};
403
404#define fimc_get_drvdata(_pdev) \
405 ((struct fimc_drvdata *) platform_get_device_id(_pdev)->driver_data)
406
407struct fimc_ctx;
408
409/**
410 * struct fimc_dev - abstraction for FIMC entity
411 * @slock: the spinlock protecting this data structure
412 * @lock: the mutex protecting this data structure
413 * @pdev: pointer to the FIMC platform device
414 * @pdata: pointer to the device platform data
415 * @variant: the IP variant information
416 * @id: FIMC device index (0..FIMC_MAX_DEVS)
417 * @clock: clocks required for FIMC operation
418 * @regs: the mapped hardware registers
419 * @irq_queue: interrupt handler waitqueue
420 * @v4l2_dev: root v4l2_device
421 * @m2m: memory-to-memory V4L2 device information
422 * @vid_cap: camera capture device information
423 * @state: flags used to synchronize m2m and capture mode operation
424 * @alloc_ctx: videobuf2 memory allocator context
425 * @pipeline: fimc video capture pipeline data structure
426 */
427struct fimc_dev {
428 spinlock_t slock;
429 struct mutex lock;
430 struct platform_device *pdev;
431 struct s5p_platform_fimc *pdata;
432 struct fimc_variant *variant;
433 u16 id;
434 struct clk *clock[MAX_FIMC_CLOCKS];
435 void __iomem *regs;
436 wait_queue_head_t irq_queue;
437 struct v4l2_device *v4l2_dev;
438 struct fimc_m2m_device m2m;
439 struct fimc_vid_cap vid_cap;
440 unsigned long state;
441 struct vb2_alloc_ctx *alloc_ctx;
442 struct fimc_pipeline pipeline;
443};
444
445/**
446 * struct fimc_ctrls - v4l2 controls structure
447 * @handler: the control handler
448 * @colorfx: image effect control
449 * @colorfx_cbcr: Cb/Cr coefficients control
450 * @rotate: image rotation control
451 * @hflip: horizontal flip control
452 * @vflip: vertical flip control
453 * @alpha: RGB alpha control
454 * @ready: true if @handler is initialized
455 */
456struct fimc_ctrls {
457 struct v4l2_ctrl_handler handler;
458 struct {
459 struct v4l2_ctrl *colorfx;
460 struct v4l2_ctrl *colorfx_cbcr;
461 };
462 struct v4l2_ctrl *rotate;
463 struct v4l2_ctrl *hflip;
464 struct v4l2_ctrl *vflip;
465 struct v4l2_ctrl *alpha;
466 bool ready;
467};
468
469/**
470 * fimc_ctx - the device context data
471 * @s_frame: source frame properties
472 * @d_frame: destination frame properties
473 * @out_order_1p: output 1-plane YCBCR order
474 * @out_order_2p: output 2-plane YCBCR order
475 * @in_order_1p input 1-plane YCBCR order
476 * @in_order_2p: input 2-plane YCBCR order
477 * @in_path: input mode (DMA or camera)
478 * @out_path: output mode (DMA or FIFO)
479 * @scaler: image scaler properties
480 * @effect: image effect
481 * @rotation: image clockwise rotation in degrees
482 * @hflip: indicates image horizontal flip if set
483 * @vflip: indicates image vertical flip if set
484 * @flags: additional flags for image conversion
485 * @state: flags to keep track of user configuration
486 * @fimc_dev: the FIMC device this context applies to
487 * @m2m_ctx: memory-to-memory device context
488 * @fh: v4l2 file handle
489 * @ctrls: v4l2 controls structure
490 */
491struct fimc_ctx {
492 struct fimc_frame s_frame;
493 struct fimc_frame d_frame;
494 u32 out_order_1p;
495 u32 out_order_2p;
496 u32 in_order_1p;
497 u32 in_order_2p;
498 enum fimc_datapath in_path;
499 enum fimc_datapath out_path;
500 struct fimc_scaler scaler;
501 struct fimc_effect effect;
502 int rotation;
503 unsigned int hflip:1;
504 unsigned int vflip:1;
505 u32 flags;
506 u32 state;
507 struct fimc_dev *fimc_dev;
508 struct v4l2_m2m_ctx *m2m_ctx;
509 struct v4l2_fh fh;
510 struct fimc_ctrls ctrls;
511};
512
513#define fh_to_ctx(__fh) container_of(__fh, struct fimc_ctx, fh)
514
515static inline void set_frame_bounds(struct fimc_frame *f, u32 width, u32 height)
516{
517 f->o_width = width;
518 f->o_height = height;
519 f->f_width = width;
520 f->f_height = height;
521}
522
523static inline void set_frame_crop(struct fimc_frame *f,
524 u32 left, u32 top, u32 width, u32 height)
525{
526 f->offs_h = left;
527 f->offs_v = top;
528 f->width = width;
529 f->height = height;
530}
531
532static inline u32 fimc_get_format_depth(struct fimc_fmt *ff)
533{
534 u32 i, depth = 0;
535
536 if (ff != NULL)
537 for (i = 0; i < ff->colplanes; i++)
538 depth += ff->depth[i];
539 return depth;
540}
541
542static inline bool fimc_capture_active(struct fimc_dev *fimc)
543{
544 unsigned long flags;
545 bool ret;
546
547 spin_lock_irqsave(&fimc->slock, flags);
548 ret = !!(fimc->state & (1 << ST_CAPT_RUN) ||
549 fimc->state & (1 << ST_CAPT_PEND));
550 spin_unlock_irqrestore(&fimc->slock, flags);
551 return ret;
552}
553
554static inline void fimc_ctx_state_set(u32 state, struct fimc_ctx *ctx)
555{
556 unsigned long flags;
557
558 spin_lock_irqsave(&ctx->fimc_dev->slock, flags);
559 ctx->state |= state;
560 spin_unlock_irqrestore(&ctx->fimc_dev->slock, flags);
561}
562
563static inline bool fimc_ctx_state_is_set(u32 mask, struct fimc_ctx *ctx)
564{
565 unsigned long flags;
566 bool ret;
567
568 spin_lock_irqsave(&ctx->fimc_dev->slock, flags);
569 ret = (ctx->state & mask) == mask;
570 spin_unlock_irqrestore(&ctx->fimc_dev->slock, flags);
571 return ret;
572}
573
574static inline int tiled_fmt(struct fimc_fmt *fmt)
575{
576 return fmt->fourcc == V4L2_PIX_FMT_NV12MT;
577}
578
579/* Return the alpha component bit mask */
580static inline int fimc_get_alpha_mask(struct fimc_fmt *fmt)
581{
582 switch (fmt->color) {
583 case FIMC_FMT_RGB444: return 0x0f;
584 case FIMC_FMT_RGB555: return 0x01;
585 case FIMC_FMT_RGB888: return 0xff;
586 default: return 0;
587 };
588}
589
590static inline struct fimc_frame *ctx_get_frame(struct fimc_ctx *ctx,
591 enum v4l2_buf_type type)
592{
593 struct fimc_frame *frame;
594
595 if (V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE == type) {
596 if (fimc_ctx_state_is_set(FIMC_CTX_M2M, ctx))
597 frame = &ctx->s_frame;
598 else
599 return ERR_PTR(-EINVAL);
600 } else if (V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE == type) {
601 frame = &ctx->d_frame;
602 } else {
603 v4l2_err(ctx->fimc_dev->v4l2_dev,
604 "Wrong buffer/video queue type (%d)\n", type);
605 return ERR_PTR(-EINVAL);
606 }
607
608 return frame;
609}
610
611/* -----------------------------------------------------*/
612/* fimc-core.c */
613int fimc_vidioc_enum_fmt_mplane(struct file *file, void *priv,
614 struct v4l2_fmtdesc *f);
615int fimc_ctrls_create(struct fimc_ctx *ctx);
616void fimc_ctrls_delete(struct fimc_ctx *ctx);
617void fimc_ctrls_activate(struct fimc_ctx *ctx, bool active);
618void fimc_alpha_ctrl_update(struct fimc_ctx *ctx);
619int fimc_fill_format(struct fimc_frame *frame, struct v4l2_format *f);
620void fimc_adjust_mplane_format(struct fimc_fmt *fmt, u32 width, u32 height,
621 struct v4l2_pix_format_mplane *pix);
622struct fimc_fmt *fimc_find_format(const u32 *pixelformat, const u32 *mbus_code,
623 unsigned int mask, int index);
624struct fimc_fmt *fimc_get_format(unsigned int index);
625
626int fimc_check_scaler_ratio(struct fimc_ctx *ctx, int sw, int sh,
627 int dw, int dh, int rotation);
628int fimc_set_scaler_info(struct fimc_ctx *ctx);
629int fimc_prepare_config(struct fimc_ctx *ctx, u32 flags);
630int fimc_prepare_addr(struct fimc_ctx *ctx, struct vb2_buffer *vb,
631 struct fimc_frame *frame, struct fimc_addr *paddr);
632void fimc_prepare_dma_offset(struct fimc_ctx *ctx, struct fimc_frame *f);
633void fimc_set_yuv_order(struct fimc_ctx *ctx);
634void fimc_fill_frame(struct fimc_frame *frame, struct v4l2_format *f);
635void fimc_capture_irq_handler(struct fimc_dev *fimc, int deq_buf);
636
637int fimc_register_m2m_device(struct fimc_dev *fimc,
638 struct v4l2_device *v4l2_dev);
639void fimc_unregister_m2m_device(struct fimc_dev *fimc);
640int fimc_register_driver(void);
641void fimc_unregister_driver(void);
642
643/* -----------------------------------------------------*/
644/* fimc-m2m.c */
645void fimc_m2m_job_finish(struct fimc_ctx *ctx, int vb_state);
646
647/* -----------------------------------------------------*/
648/* fimc-capture.c */
649int fimc_initialize_capture_subdev(struct fimc_dev *fimc);
650void fimc_unregister_capture_subdev(struct fimc_dev *fimc);
651int fimc_capture_ctrls_create(struct fimc_dev *fimc);
652void fimc_sensor_notify(struct v4l2_subdev *sd, unsigned int notification,
653 void *arg);
654int fimc_capture_suspend(struct fimc_dev *fimc);
655int fimc_capture_resume(struct fimc_dev *fimc);
656
657/*
658 * Buffer list manipulation functions. Must be called with fimc.slock held.
659 */
660
661/**
662 * fimc_active_queue_add - add buffer to the capture active buffers queue
663 * @buf: buffer to add to the active buffers list
664 */
665static inline void fimc_active_queue_add(struct fimc_vid_cap *vid_cap,
666 struct fimc_vid_buffer *buf)
667{
668 list_add_tail(&buf->list, &vid_cap->active_buf_q);
669 vid_cap->active_buf_cnt++;
670}
671
672/**
673 * fimc_active_queue_pop - pop buffer from the capture active buffers queue
674 *
675 * The caller must assure the active_buf_q list is not empty.
676 */
677static inline struct fimc_vid_buffer *fimc_active_queue_pop(
678 struct fimc_vid_cap *vid_cap)
679{
680 struct fimc_vid_buffer *buf;
681 buf = list_entry(vid_cap->active_buf_q.next,
682 struct fimc_vid_buffer, list);
683 list_del(&buf->list);
684 vid_cap->active_buf_cnt--;
685 return buf;
686}
687
688/**
689 * fimc_pending_queue_add - add buffer to the capture pending buffers queue
690 * @buf: buffer to add to the pending buffers list
691 */
692static inline void fimc_pending_queue_add(struct fimc_vid_cap *vid_cap,
693 struct fimc_vid_buffer *buf)
694{
695 list_add_tail(&buf->list, &vid_cap->pending_buf_q);
696}
697
698/**
699 * fimc_pending_queue_pop - pop buffer from the capture pending buffers queue
700 *
701 * The caller must assure the pending_buf_q list is not empty.
702 */
703static inline struct fimc_vid_buffer *fimc_pending_queue_pop(
704 struct fimc_vid_cap *vid_cap)
705{
706 struct fimc_vid_buffer *buf;
707 buf = list_entry(vid_cap->pending_buf_q.next,
708 struct fimc_vid_buffer, list);
709 list_del(&buf->list);
710 return buf;
711}
712
713#endif /* FIMC_CORE_H_ */
diff --git a/drivers/media/video/s5p-fimc/fimc-lite-reg.c b/drivers/media/video/s5p-fimc/fimc-lite-reg.c
deleted file mode 100644
index f996e94873f6..000000000000
--- a/drivers/media/video/s5p-fimc/fimc-lite-reg.c
+++ /dev/null
@@ -1,300 +0,0 @@
1/*
2 * Register interface file for EXYNOS FIMC-LITE (camera interface) driver
3 *
4 * Copyright (C) 2012 Samsung Electronics Co., Ltd.
5 * Sylwester Nawrocki <s.nawrocki@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10*/
11
12#include <linux/io.h>
13#include <linux/delay.h>
14#include <media/s5p_fimc.h>
15
16#include "fimc-lite-reg.h"
17#include "fimc-lite.h"
18#include "fimc-core.h"
19
20#define FLITE_RESET_TIMEOUT 50 /* in ms */
21
22void flite_hw_reset(struct fimc_lite *dev)
23{
24 unsigned long end = jiffies + msecs_to_jiffies(FLITE_RESET_TIMEOUT);
25 u32 cfg;
26
27 cfg = readl(dev->regs + FLITE_REG_CIGCTRL);
28 cfg |= FLITE_REG_CIGCTRL_SWRST_REQ;
29 writel(cfg, dev->regs + FLITE_REG_CIGCTRL);
30
31 while (time_is_after_jiffies(end)) {
32 cfg = readl(dev->regs + FLITE_REG_CIGCTRL);
33 if (cfg & FLITE_REG_CIGCTRL_SWRST_RDY)
34 break;
35 usleep_range(1000, 5000);
36 }
37
38 cfg |= FLITE_REG_CIGCTRL_SWRST;
39 writel(cfg, dev->regs + FLITE_REG_CIGCTRL);
40}
41
42void flite_hw_clear_pending_irq(struct fimc_lite *dev)
43{
44 u32 cfg = readl(dev->regs + FLITE_REG_CISTATUS);
45 cfg &= ~FLITE_REG_CISTATUS_IRQ_CAM;
46 writel(cfg, dev->regs + FLITE_REG_CISTATUS);
47}
48
49u32 flite_hw_get_interrupt_source(struct fimc_lite *dev)
50{
51 u32 intsrc = readl(dev->regs + FLITE_REG_CISTATUS);
52 return intsrc & FLITE_REG_CISTATUS_IRQ_MASK;
53}
54
55void flite_hw_clear_last_capture_end(struct fimc_lite *dev)
56{
57
58 u32 cfg = readl(dev->regs + FLITE_REG_CISTATUS2);
59 cfg &= ~FLITE_REG_CISTATUS2_LASTCAPEND;
60 writel(cfg, dev->regs + FLITE_REG_CISTATUS2);
61}
62
63void flite_hw_set_interrupt_mask(struct fimc_lite *dev)
64{
65 u32 cfg, intsrc;
66
67 /* Select interrupts to be enabled for each output mode */
68 if (dev->out_path == FIMC_IO_DMA) {
69 intsrc = FLITE_REG_CIGCTRL_IRQ_OVFEN |
70 FLITE_REG_CIGCTRL_IRQ_LASTEN |
71 FLITE_REG_CIGCTRL_IRQ_STARTEN;
72 } else {
73 /* An output to the FIMC-IS */
74 intsrc = FLITE_REG_CIGCTRL_IRQ_OVFEN |
75 FLITE_REG_CIGCTRL_IRQ_LASTEN;
76 }
77
78 cfg = readl(dev->regs + FLITE_REG_CIGCTRL);
79 cfg |= FLITE_REG_CIGCTRL_IRQ_DISABLE_MASK;
80 cfg &= ~intsrc;
81 writel(cfg, dev->regs + FLITE_REG_CIGCTRL);
82}
83
84void flite_hw_capture_start(struct fimc_lite *dev)
85{
86 u32 cfg = readl(dev->regs + FLITE_REG_CIIMGCPT);
87 cfg |= FLITE_REG_CIIMGCPT_IMGCPTEN;
88 writel(cfg, dev->regs + FLITE_REG_CIIMGCPT);
89}
90
91void flite_hw_capture_stop(struct fimc_lite *dev)
92{
93 u32 cfg = readl(dev->regs + FLITE_REG_CIIMGCPT);
94 cfg &= ~FLITE_REG_CIIMGCPT_IMGCPTEN;
95 writel(cfg, dev->regs + FLITE_REG_CIIMGCPT);
96}
97
98/*
99 * Test pattern (color bars) enable/disable. External sensor
100 * pixel clock must be active for the test pattern to work.
101 */
102void flite_hw_set_test_pattern(struct fimc_lite *dev, bool on)
103{
104 u32 cfg = readl(dev->regs + FLITE_REG_CIGCTRL);
105 if (on)
106 cfg |= FLITE_REG_CIGCTRL_TEST_PATTERN_COLORBAR;
107 else
108 cfg &= ~FLITE_REG_CIGCTRL_TEST_PATTERN_COLORBAR;
109 writel(cfg, dev->regs + FLITE_REG_CIGCTRL);
110}
111
112static const u32 src_pixfmt_map[8][3] = {
113 { V4L2_MBUS_FMT_YUYV8_2X8, FLITE_REG_CISRCSIZE_ORDER422_IN_YCBYCR,
114 FLITE_REG_CIGCTRL_YUV422_1P },
115 { V4L2_MBUS_FMT_YVYU8_2X8, FLITE_REG_CISRCSIZE_ORDER422_IN_YCRYCB,
116 FLITE_REG_CIGCTRL_YUV422_1P },
117 { V4L2_MBUS_FMT_UYVY8_2X8, FLITE_REG_CISRCSIZE_ORDER422_IN_CBYCRY,
118 FLITE_REG_CIGCTRL_YUV422_1P },
119 { V4L2_MBUS_FMT_VYUY8_2X8, FLITE_REG_CISRCSIZE_ORDER422_IN_CRYCBY,
120 FLITE_REG_CIGCTRL_YUV422_1P },
121 { V4L2_PIX_FMT_SGRBG8, 0, FLITE_REG_CIGCTRL_RAW8 },
122 { V4L2_PIX_FMT_SGRBG10, 0, FLITE_REG_CIGCTRL_RAW10 },
123 { V4L2_PIX_FMT_SGRBG12, 0, FLITE_REG_CIGCTRL_RAW12 },
124 { V4L2_MBUS_FMT_JPEG_1X8, 0, FLITE_REG_CIGCTRL_USER(1) },
125};
126
127/* Set camera input pixel format and resolution */
128void flite_hw_set_source_format(struct fimc_lite *dev, struct flite_frame *f)
129{
130 enum v4l2_mbus_pixelcode pixelcode = dev->fmt->mbus_code;
131 unsigned int i = ARRAY_SIZE(src_pixfmt_map);
132 u32 cfg;
133
134 while (i-- >= 0) {
135 if (src_pixfmt_map[i][0] == pixelcode)
136 break;
137 }
138
139 if (i == 0 && src_pixfmt_map[i][0] != pixelcode) {
140 v4l2_err(dev->vfd,
141 "Unsupported pixel code, falling back to %#08x\n",
142 src_pixfmt_map[i][0]);
143 }
144
145 cfg = readl(dev->regs + FLITE_REG_CIGCTRL);
146 cfg &= ~FLITE_REG_CIGCTRL_FMT_MASK;
147 cfg |= src_pixfmt_map[i][2];
148 writel(cfg, dev->regs + FLITE_REG_CIGCTRL);
149
150 cfg = readl(dev->regs + FLITE_REG_CISRCSIZE);
151 cfg &= ~(FLITE_REG_CISRCSIZE_ORDER422_MASK |
152 FLITE_REG_CISRCSIZE_SIZE_CAM_MASK);
153 cfg |= (f->f_width << 16) | f->f_height;
154 cfg |= src_pixfmt_map[i][1];
155 writel(cfg, dev->regs + FLITE_REG_CISRCSIZE);
156}
157
158/* Set the camera host input window offsets (cropping) */
159void flite_hw_set_window_offset(struct fimc_lite *dev, struct flite_frame *f)
160{
161 u32 hoff2, voff2;
162 u32 cfg;
163
164 cfg = readl(dev->regs + FLITE_REG_CIWDOFST);
165 cfg &= ~FLITE_REG_CIWDOFST_OFST_MASK;
166 cfg |= (f->rect.left << 16) | f->rect.top;
167 cfg |= FLITE_REG_CIWDOFST_WINOFSEN;
168 writel(cfg, dev->regs + FLITE_REG_CIWDOFST);
169
170 hoff2 = f->f_width - f->rect.width - f->rect.left;
171 voff2 = f->f_height - f->rect.height - f->rect.top;
172
173 cfg = (hoff2 << 16) | voff2;
174 writel(cfg, dev->regs + FLITE_REG_CIWDOFST2);
175}
176
177/* Select camera port (A, B) */
178static void flite_hw_set_camera_port(struct fimc_lite *dev, int id)
179{
180 u32 cfg = readl(dev->regs + FLITE_REG_CIGENERAL);
181 if (id == 0)
182 cfg &= ~FLITE_REG_CIGENERAL_CAM_B;
183 else
184 cfg |= FLITE_REG_CIGENERAL_CAM_B;
185 writel(cfg, dev->regs + FLITE_REG_CIGENERAL);
186}
187
188/* Select serial or parallel bus, camera port (A,B) and set signals polarity */
189void flite_hw_set_camera_bus(struct fimc_lite *dev,
190 struct s5p_fimc_isp_info *s_info)
191{
192 u32 cfg = readl(dev->regs + FLITE_REG_CIGCTRL);
193 unsigned int flags = s_info->flags;
194
195 if (s_info->bus_type != FIMC_MIPI_CSI2) {
196 cfg &= ~(FLITE_REG_CIGCTRL_SELCAM_MIPI |
197 FLITE_REG_CIGCTRL_INVPOLPCLK |
198 FLITE_REG_CIGCTRL_INVPOLVSYNC |
199 FLITE_REG_CIGCTRL_INVPOLHREF);
200
201 if (flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
202 cfg |= FLITE_REG_CIGCTRL_INVPOLPCLK;
203
204 if (flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
205 cfg |= FLITE_REG_CIGCTRL_INVPOLVSYNC;
206
207 if (flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
208 cfg |= FLITE_REG_CIGCTRL_INVPOLHREF;
209 } else {
210 cfg |= FLITE_REG_CIGCTRL_SELCAM_MIPI;
211 }
212
213 writel(cfg, dev->regs + FLITE_REG_CIGCTRL);
214
215 flite_hw_set_camera_port(dev, s_info->mux_id);
216}
217
218static void flite_hw_set_out_order(struct fimc_lite *dev, struct flite_frame *f)
219{
220 static const u32 pixcode[4][2] = {
221 { V4L2_MBUS_FMT_YUYV8_2X8, FLITE_REG_CIODMAFMT_YCBYCR },
222 { V4L2_MBUS_FMT_YVYU8_2X8, FLITE_REG_CIODMAFMT_YCRYCB },
223 { V4L2_MBUS_FMT_UYVY8_2X8, FLITE_REG_CIODMAFMT_CBYCRY },
224 { V4L2_MBUS_FMT_VYUY8_2X8, FLITE_REG_CIODMAFMT_CRYCBY },
225 };
226 u32 cfg = readl(dev->regs + FLITE_REG_CIODMAFMT);
227 unsigned int i = ARRAY_SIZE(pixcode);
228
229 while (i-- >= 0)
230 if (pixcode[i][0] == dev->fmt->mbus_code)
231 break;
232 cfg &= ~FLITE_REG_CIODMAFMT_YCBCR_ORDER_MASK;
233 writel(cfg | pixcode[i][1], dev->regs + FLITE_REG_CIODMAFMT);
234}
235
236void flite_hw_set_dma_window(struct fimc_lite *dev, struct flite_frame *f)
237{
238 u32 cfg;
239
240 /* Maximum output pixel size */
241 cfg = readl(dev->regs + FLITE_REG_CIOCAN);
242 cfg &= ~FLITE_REG_CIOCAN_MASK;
243 cfg = (f->f_height << 16) | f->f_width;
244 writel(cfg, dev->regs + FLITE_REG_CIOCAN);
245
246 /* DMA offsets */
247 cfg = readl(dev->regs + FLITE_REG_CIOOFF);
248 cfg &= ~FLITE_REG_CIOOFF_MASK;
249 cfg |= (f->rect.top << 16) | f->rect.left;
250 writel(cfg, dev->regs + FLITE_REG_CIOOFF);
251}
252
253/* Enable/disable output DMA, set output pixel size and offsets (composition) */
254void flite_hw_set_output_dma(struct fimc_lite *dev, struct flite_frame *f,
255 bool enable)
256{
257 u32 cfg = readl(dev->regs + FLITE_REG_CIGCTRL);
258
259 if (!enable) {
260 cfg |= FLITE_REG_CIGCTRL_ODMA_DISABLE;
261 writel(cfg, dev->regs + FLITE_REG_CIGCTRL);
262 return;
263 }
264
265 cfg &= ~FLITE_REG_CIGCTRL_ODMA_DISABLE;
266 writel(cfg, dev->regs + FLITE_REG_CIGCTRL);
267
268 flite_hw_set_out_order(dev, f);
269 flite_hw_set_dma_window(dev, f);
270}
271
272void flite_hw_dump_regs(struct fimc_lite *dev, const char *label)
273{
274 struct {
275 u32 offset;
276 const char * const name;
277 } registers[] = {
278 { 0x00, "CISRCSIZE" },
279 { 0x04, "CIGCTRL" },
280 { 0x08, "CIIMGCPT" },
281 { 0x0c, "CICPTSEQ" },
282 { 0x10, "CIWDOFST" },
283 { 0x14, "CIWDOFST2" },
284 { 0x18, "CIODMAFMT" },
285 { 0x20, "CIOCAN" },
286 { 0x24, "CIOOFF" },
287 { 0x30, "CIOSA" },
288 { 0x40, "CISTATUS" },
289 { 0x44, "CISTATUS2" },
290 { 0xf0, "CITHOLD" },
291 { 0xfc, "CIGENERAL" },
292 };
293 u32 i;
294
295 pr_info("--- %s ---\n", label);
296 for (i = 0; i < ARRAY_SIZE(registers); i++) {
297 u32 cfg = readl(dev->regs + registers[i].offset);
298 pr_info("%s: %s:\t0x%08x\n", __func__, registers[i].name, cfg);
299 }
300}
diff --git a/drivers/media/video/s5p-fimc/fimc-lite-reg.h b/drivers/media/video/s5p-fimc/fimc-lite-reg.h
deleted file mode 100644
index adb9e9e6f3c2..000000000000
--- a/drivers/media/video/s5p-fimc/fimc-lite-reg.h
+++ /dev/null
@@ -1,150 +0,0 @@
1/*
2 * Copyright (C) 2012 Samsung Electronics Co., Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#ifndef FIMC_LITE_REG_H_
10#define FIMC_LITE_REG_H_
11
12#include "fimc-lite.h"
13
14/* Camera Source size */
15#define FLITE_REG_CISRCSIZE 0x00
16#define FLITE_REG_CISRCSIZE_ORDER422_IN_YCBYCR (0 << 14)
17#define FLITE_REG_CISRCSIZE_ORDER422_IN_YCRYCB (1 << 14)
18#define FLITE_REG_CISRCSIZE_ORDER422_IN_CBYCRY (2 << 14)
19#define FLITE_REG_CISRCSIZE_ORDER422_IN_CRYCBY (3 << 14)
20#define FLITE_REG_CISRCSIZE_ORDER422_MASK (0x3 << 14)
21#define FLITE_REG_CISRCSIZE_SIZE_CAM_MASK (0x3fff << 16 | 0x3fff)
22
23/* Global control */
24#define FLITE_REG_CIGCTRL 0x04
25#define FLITE_REG_CIGCTRL_YUV422_1P (0x1e << 24)
26#define FLITE_REG_CIGCTRL_RAW8 (0x2a << 24)
27#define FLITE_REG_CIGCTRL_RAW10 (0x2b << 24)
28#define FLITE_REG_CIGCTRL_RAW12 (0x2c << 24)
29#define FLITE_REG_CIGCTRL_RAW14 (0x2d << 24)
30/* User defined formats. x = 0...15 */
31#define FLITE_REG_CIGCTRL_USER(x) ((0x30 + x - 1) << 24)
32#define FLITE_REG_CIGCTRL_FMT_MASK (0x3f << 24)
33#define FLITE_REG_CIGCTRL_SHADOWMASK_DISABLE (1 << 21)
34#define FLITE_REG_CIGCTRL_ODMA_DISABLE (1 << 20)
35#define FLITE_REG_CIGCTRL_SWRST_REQ (1 << 19)
36#define FLITE_REG_CIGCTRL_SWRST_RDY (1 << 18)
37#define FLITE_REG_CIGCTRL_SWRST (1 << 17)
38#define FLITE_REG_CIGCTRL_TEST_PATTERN_COLORBAR (1 << 15)
39#define FLITE_REG_CIGCTRL_INVPOLPCLK (1 << 14)
40#define FLITE_REG_CIGCTRL_INVPOLVSYNC (1 << 13)
41#define FLITE_REG_CIGCTRL_INVPOLHREF (1 << 12)
42/* Interrupts mask bits (1 disables an interrupt) */
43#define FLITE_REG_CIGCTRL_IRQ_LASTEN (1 << 8)
44#define FLITE_REG_CIGCTRL_IRQ_ENDEN (1 << 7)
45#define FLITE_REG_CIGCTRL_IRQ_STARTEN (1 << 6)
46#define FLITE_REG_CIGCTRL_IRQ_OVFEN (1 << 5)
47#define FLITE_REG_CIGCTRL_IRQ_DISABLE_MASK (0xf << 5)
48#define FLITE_REG_CIGCTRL_SELCAM_MIPI (1 << 3)
49
50/* Image Capture Enable */
51#define FLITE_REG_CIIMGCPT 0x08
52#define FLITE_REG_CIIMGCPT_IMGCPTEN (1 << 31)
53#define FLITE_REG_CIIMGCPT_CPT_FREN (1 << 25)
54#define FLITE_REG_CIIMGCPT_CPT_MOD_FRCNT (1 << 18)
55#define FLITE_REG_CIIMGCPT_CPT_MOD_FREN (0 << 18)
56
57/* Capture Sequence */
58#define FLITE_REG_CICPTSEQ 0x0c
59
60/* Camera Window Offset */
61#define FLITE_REG_CIWDOFST 0x10
62#define FLITE_REG_CIWDOFST_WINOFSEN (1 << 31)
63#define FLITE_REG_CIWDOFST_CLROVIY (1 << 31)
64#define FLITE_REG_CIWDOFST_CLROVFICB (1 << 15)
65#define FLITE_REG_CIWDOFST_CLROVFICR (1 << 14)
66#define FLITE_REG_CIWDOFST_OFST_MASK ((0x1fff << 16) | 0x1fff)
67
68/* Camera Window Offset2 */
69#define FLITE_REG_CIWDOFST2 0x14
70
71/* Camera Output DMA Format */
72#define FLITE_REG_CIODMAFMT 0x18
73#define FLITE_REG_CIODMAFMT_RAW_CON (1 << 15)
74#define FLITE_REG_CIODMAFMT_PACK12 (1 << 14)
75#define FLITE_REG_CIODMAFMT_CRYCBY (0 << 4)
76#define FLITE_REG_CIODMAFMT_CBYCRY (1 << 4)
77#define FLITE_REG_CIODMAFMT_YCRYCB (2 << 4)
78#define FLITE_REG_CIODMAFMT_YCBYCR (3 << 4)
79#define FLITE_REG_CIODMAFMT_YCBCR_ORDER_MASK (0x3 << 4)
80
81/* Camera Output Canvas */
82#define FLITE_REG_CIOCAN 0x20
83#define FLITE_REG_CIOCAN_MASK ((0x3fff << 16) | 0x3fff)
84
85/* Camera Output DMA Offset */
86#define FLITE_REG_CIOOFF 0x24
87#define FLITE_REG_CIOOFF_MASK ((0x3fff << 16) | 0x3fff)
88
89/* Camera Output DMA Start Address */
90#define FLITE_REG_CIOSA 0x30
91
92/* Camera Status */
93#define FLITE_REG_CISTATUS 0x40
94#define FLITE_REG_CISTATUS_MIPI_VVALID (1 << 22)
95#define FLITE_REG_CISTATUS_MIPI_HVALID (1 << 21)
96#define FLITE_REG_CISTATUS_MIPI_DVALID (1 << 20)
97#define FLITE_REG_CISTATUS_ITU_VSYNC (1 << 14)
98#define FLITE_REG_CISTATUS_ITU_HREFF (1 << 13)
99#define FLITE_REG_CISTATUS_OVFIY (1 << 10)
100#define FLITE_REG_CISTATUS_OVFICB (1 << 9)
101#define FLITE_REG_CISTATUS_OVFICR (1 << 8)
102#define FLITE_REG_CISTATUS_IRQ_SRC_OVERFLOW (1 << 7)
103#define FLITE_REG_CISTATUS_IRQ_SRC_LASTCAPEND (1 << 6)
104#define FLITE_REG_CISTATUS_IRQ_SRC_FRMSTART (1 << 5)
105#define FLITE_REG_CISTATUS_IRQ_SRC_FRMEND (1 << 4)
106#define FLITE_REG_CISTATUS_IRQ_CAM (1 << 0)
107#define FLITE_REG_CISTATUS_IRQ_MASK (0xf << 4)
108
109/* Camera Status2 */
110#define FLITE_REG_CISTATUS2 0x44
111#define FLITE_REG_CISTATUS2_LASTCAPEND (1 << 1)
112#define FLITE_REG_CISTATUS2_FRMEND (1 << 0)
113
114/* Qos Threshold */
115#define FLITE_REG_CITHOLD 0xf0
116#define FLITE_REG_CITHOLD_W_QOS_EN (1 << 30)
117
118/* Camera General Purpose */
119#define FLITE_REG_CIGENERAL 0xfc
120/* b0: 1 - camera B, 0 - camera A */
121#define FLITE_REG_CIGENERAL_CAM_B (1 << 0)
122
123/* ----------------------------------------------------------------------------
124 * Function declarations
125 */
126void flite_hw_reset(struct fimc_lite *dev);
127void flite_hw_clear_pending_irq(struct fimc_lite *dev);
128u32 flite_hw_get_interrupt_source(struct fimc_lite *dev);
129void flite_hw_clear_last_capture_end(struct fimc_lite *dev);
130void flite_hw_set_interrupt_mask(struct fimc_lite *dev);
131void flite_hw_capture_start(struct fimc_lite *dev);
132void flite_hw_capture_stop(struct fimc_lite *dev);
133void flite_hw_set_camera_bus(struct fimc_lite *dev,
134 struct s5p_fimc_isp_info *s_info);
135void flite_hw_set_camera_polarity(struct fimc_lite *dev,
136 struct s5p_fimc_isp_info *cam);
137void flite_hw_set_window_offset(struct fimc_lite *dev, struct flite_frame *f);
138void flite_hw_set_source_format(struct fimc_lite *dev, struct flite_frame *f);
139
140void flite_hw_set_output_dma(struct fimc_lite *dev, struct flite_frame *f,
141 bool enable);
142void flite_hw_set_dma_window(struct fimc_lite *dev, struct flite_frame *f);
143void flite_hw_set_test_pattern(struct fimc_lite *dev, bool on);
144void flite_hw_dump_regs(struct fimc_lite *dev, const char *label);
145
146static inline void flite_hw_set_output_addr(struct fimc_lite *dev, u32 paddr)
147{
148 writel(paddr, dev->regs + FLITE_REG_CIOSA);
149}
150#endif /* FIMC_LITE_REG_H */
diff --git a/drivers/media/video/s5p-fimc/fimc-lite.c b/drivers/media/video/s5p-fimc/fimc-lite.c
deleted file mode 100644
index c5b57e805b68..000000000000
--- a/drivers/media/video/s5p-fimc/fimc-lite.c
+++ /dev/null
@@ -1,1606 +0,0 @@
1/*
2 * Samsung EXYNOS FIMC-LITE (camera host interface) driver
3*
4 * Copyright (C) 2012 Samsung Electronics Co., Ltd.
5 * Sylwester Nawrocki <s.nawrocki@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#define pr_fmt(fmt) "%s:%d " fmt, __func__, __LINE__
12
13#include <linux/bug.h>
14#include <linux/device.h>
15#include <linux/errno.h>
16#include <linux/interrupt.h>
17#include <linux/kernel.h>
18#include <linux/list.h>
19#include <linux/module.h>
20#include <linux/types.h>
21#include <linux/platform_device.h>
22#include <linux/pm_runtime.h>
23#include <linux/slab.h>
24#include <linux/videodev2.h>
25
26#include <media/v4l2-device.h>
27#include <media/v4l2-ioctl.h>
28#include <media/v4l2-mem2mem.h>
29#include <media/videobuf2-core.h>
30#include <media/videobuf2-dma-contig.h>
31
32#include "fimc-mdevice.h"
33#include "fimc-core.h"
34#include "fimc-lite-reg.h"
35
36static int debug;
37module_param(debug, int, 0644);
38
39static const struct fimc_fmt fimc_lite_formats[] = {
40 {
41 .name = "YUV 4:2:2 packed, YCbYCr",
42 .fourcc = V4L2_PIX_FMT_YUYV,
43 .depth = { 16 },
44 .color = FIMC_FMT_YCBYCR422,
45 .memplanes = 1,
46 .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8,
47 }, {
48 .name = "YUV 4:2:2 packed, CbYCrY",
49 .fourcc = V4L2_PIX_FMT_UYVY,
50 .depth = { 16 },
51 .color = FIMC_FMT_CBYCRY422,
52 .memplanes = 1,
53 .mbus_code = V4L2_MBUS_FMT_UYVY8_2X8,
54 }, {
55 .name = "YUV 4:2:2 packed, CrYCbY",
56 .fourcc = V4L2_PIX_FMT_VYUY,
57 .depth = { 16 },
58 .color = FIMC_FMT_CRYCBY422,
59 .memplanes = 1,
60 .mbus_code = V4L2_MBUS_FMT_VYUY8_2X8,
61 }, {
62 .name = "YUV 4:2:2 packed, YCrYCb",
63 .fourcc = V4L2_PIX_FMT_YVYU,
64 .depth = { 16 },
65 .color = FIMC_FMT_YCRYCB422,
66 .memplanes = 1,
67 .mbus_code = V4L2_MBUS_FMT_YVYU8_2X8,
68 }, {
69 .name = "RAW8 (GRBG)",
70 .fourcc = V4L2_PIX_FMT_SGRBG8,
71 .depth = { 8 },
72 .color = FIMC_FMT_RAW8,
73 .memplanes = 1,
74 .mbus_code = V4L2_MBUS_FMT_SGRBG8_1X8,
75 }, {
76 .name = "RAW10 (GRBG)",
77 .fourcc = V4L2_PIX_FMT_SGRBG10,
78 .depth = { 10 },
79 .color = FIMC_FMT_RAW10,
80 .memplanes = 1,
81 .mbus_code = V4L2_MBUS_FMT_SGRBG10_1X10,
82 }, {
83 .name = "RAW12 (GRBG)",
84 .fourcc = V4L2_PIX_FMT_SGRBG12,
85 .depth = { 12 },
86 .color = FIMC_FMT_RAW12,
87 .memplanes = 1,
88 .mbus_code = V4L2_MBUS_FMT_SGRBG12_1X12,
89 },
90};
91
92/**
93 * fimc_lite_find_format - lookup fimc color format by fourcc or media bus code
94 * @pixelformat: fourcc to match, ignored if null
95 * @mbus_code: media bus code to match, ignored if null
96 * @index: index to the fimc_lite_formats array, ignored if negative
97 */
98static const struct fimc_fmt *fimc_lite_find_format(const u32 *pixelformat,
99 const u32 *mbus_code, int index)
100{
101 const struct fimc_fmt *fmt, *def_fmt = NULL;
102 unsigned int i;
103 int id = 0;
104
105 if (index >= (int)ARRAY_SIZE(fimc_lite_formats))
106 return NULL;
107
108 for (i = 0; i < ARRAY_SIZE(fimc_lite_formats); ++i) {
109 fmt = &fimc_lite_formats[i];
110 if (pixelformat && fmt->fourcc == *pixelformat)
111 return fmt;
112 if (mbus_code && fmt->mbus_code == *mbus_code)
113 return fmt;
114 if (index == id)
115 def_fmt = fmt;
116 id++;
117 }
118 return def_fmt;
119}
120
121static int fimc_lite_hw_init(struct fimc_lite *fimc)
122{
123 struct fimc_pipeline *pipeline = &fimc->pipeline;
124 struct fimc_sensor_info *sensor;
125 unsigned long flags;
126
127 if (pipeline->subdevs[IDX_SENSOR] == NULL)
128 return -ENXIO;
129
130 if (fimc->fmt == NULL)
131 return -EINVAL;
132
133 sensor = v4l2_get_subdev_hostdata(pipeline->subdevs[IDX_SENSOR]);
134 spin_lock_irqsave(&fimc->slock, flags);
135
136 flite_hw_set_camera_bus(fimc, sensor->pdata);
137 flite_hw_set_source_format(fimc, &fimc->inp_frame);
138 flite_hw_set_window_offset(fimc, &fimc->inp_frame);
139 flite_hw_set_output_dma(fimc, &fimc->out_frame, true);
140 flite_hw_set_interrupt_mask(fimc);
141 flite_hw_set_test_pattern(fimc, fimc->test_pattern->val);
142
143 if (debug > 0)
144 flite_hw_dump_regs(fimc, __func__);
145
146 spin_unlock_irqrestore(&fimc->slock, flags);
147 return 0;
148}
149
150/*
151 * Reinitialize the driver so it is ready to start the streaming again.
152 * Set fimc->state to indicate stream off and the hardware shut down state.
153 * If not suspending (@suspend is false), return any buffers to videobuf2.
154 * Otherwise put any owned buffers onto the pending buffers queue, so they
155 * can be re-spun when the device is being resumed. Also perform FIMC
156 * software reset and disable streaming on the whole pipeline if required.
157 */
158static int fimc_lite_reinit(struct fimc_lite *fimc, bool suspend)
159{
160 struct flite_buffer *buf;
161 unsigned long flags;
162 bool streaming;
163
164 spin_lock_irqsave(&fimc->slock, flags);
165 streaming = fimc->state & (1 << ST_SENSOR_STREAM);
166
167 fimc->state &= ~(1 << ST_FLITE_RUN | 1 << ST_FLITE_OFF |
168 1 << ST_FLITE_STREAM | 1 << ST_SENSOR_STREAM);
169 if (suspend)
170 fimc->state |= (1 << ST_FLITE_SUSPENDED);
171 else
172 fimc->state &= ~(1 << ST_FLITE_PENDING |
173 1 << ST_FLITE_SUSPENDED);
174
175 /* Release unused buffers */
176 while (!suspend && !list_empty(&fimc->pending_buf_q)) {
177 buf = fimc_lite_pending_queue_pop(fimc);
178 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
179 }
180 /* If suspending put unused buffers onto pending queue */
181 while (!list_empty(&fimc->active_buf_q)) {
182 buf = fimc_lite_active_queue_pop(fimc);
183 if (suspend)
184 fimc_lite_pending_queue_add(fimc, buf);
185 else
186 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
187 }
188
189 spin_unlock_irqrestore(&fimc->slock, flags);
190
191 flite_hw_reset(fimc);
192
193 if (!streaming)
194 return 0;
195
196 return fimc_pipeline_s_stream(&fimc->pipeline, 0);
197}
198
199static int fimc_lite_stop_capture(struct fimc_lite *fimc, bool suspend)
200{
201 unsigned long flags;
202
203 if (!fimc_lite_active(fimc))
204 return 0;
205
206 spin_lock_irqsave(&fimc->slock, flags);
207 set_bit(ST_FLITE_OFF, &fimc->state);
208 flite_hw_capture_stop(fimc);
209 spin_unlock_irqrestore(&fimc->slock, flags);
210
211 wait_event_timeout(fimc->irq_queue,
212 !test_bit(ST_FLITE_OFF, &fimc->state),
213 (2*HZ/10)); /* 200 ms */
214
215 return fimc_lite_reinit(fimc, suspend);
216}
217
218/* Must be called with fimc.slock spinlock held. */
219static void fimc_lite_config_update(struct fimc_lite *fimc)
220{
221 flite_hw_set_window_offset(fimc, &fimc->inp_frame);
222 flite_hw_set_dma_window(fimc, &fimc->out_frame);
223 flite_hw_set_test_pattern(fimc, fimc->test_pattern->val);
224 clear_bit(ST_FLITE_CONFIG, &fimc->state);
225}
226
227static irqreturn_t flite_irq_handler(int irq, void *priv)
228{
229 struct fimc_lite *fimc = priv;
230 struct flite_buffer *vbuf;
231 unsigned long flags;
232 struct timeval *tv;
233 struct timespec ts;
234 u32 intsrc;
235
236 spin_lock_irqsave(&fimc->slock, flags);
237
238 intsrc = flite_hw_get_interrupt_source(fimc);
239 flite_hw_clear_pending_irq(fimc);
240
241 if (test_and_clear_bit(ST_FLITE_OFF, &fimc->state)) {
242 wake_up(&fimc->irq_queue);
243 goto done;
244 }
245
246 if (intsrc & FLITE_REG_CISTATUS_IRQ_SRC_OVERFLOW) {
247 clear_bit(ST_FLITE_RUN, &fimc->state);
248 fimc->events.data_overflow++;
249 }
250
251 if (intsrc & FLITE_REG_CISTATUS_IRQ_SRC_LASTCAPEND) {
252 flite_hw_clear_last_capture_end(fimc);
253 clear_bit(ST_FLITE_STREAM, &fimc->state);
254 wake_up(&fimc->irq_queue);
255 }
256
257 if (fimc->out_path != FIMC_IO_DMA)
258 goto done;
259
260 if ((intsrc & FLITE_REG_CISTATUS_IRQ_SRC_FRMSTART) &&
261 test_bit(ST_FLITE_RUN, &fimc->state) &&
262 !list_empty(&fimc->active_buf_q) &&
263 !list_empty(&fimc->pending_buf_q)) {
264 vbuf = fimc_lite_active_queue_pop(fimc);
265 ktime_get_ts(&ts);
266 tv = &vbuf->vb.v4l2_buf.timestamp;
267 tv->tv_sec = ts.tv_sec;
268 tv->tv_usec = ts.tv_nsec / NSEC_PER_USEC;
269 vbuf->vb.v4l2_buf.sequence = fimc->frame_count++;
270 vb2_buffer_done(&vbuf->vb, VB2_BUF_STATE_DONE);
271
272 vbuf = fimc_lite_pending_queue_pop(fimc);
273 flite_hw_set_output_addr(fimc, vbuf->paddr);
274 fimc_lite_active_queue_add(fimc, vbuf);
275 }
276
277 if (test_bit(ST_FLITE_CONFIG, &fimc->state))
278 fimc_lite_config_update(fimc);
279
280 if (list_empty(&fimc->pending_buf_q)) {
281 flite_hw_capture_stop(fimc);
282 clear_bit(ST_FLITE_STREAM, &fimc->state);
283 }
284done:
285 set_bit(ST_FLITE_RUN, &fimc->state);
286 spin_unlock_irqrestore(&fimc->slock, flags);
287 return IRQ_HANDLED;
288}
289
290static int start_streaming(struct vb2_queue *q, unsigned int count)
291{
292 struct fimc_lite *fimc = q->drv_priv;
293 int ret;
294
295 fimc->frame_count = 0;
296
297 ret = fimc_lite_hw_init(fimc);
298 if (ret) {
299 fimc_lite_reinit(fimc, false);
300 return ret;
301 }
302
303 set_bit(ST_FLITE_PENDING, &fimc->state);
304
305 if (!list_empty(&fimc->active_buf_q) &&
306 !test_and_set_bit(ST_FLITE_STREAM, &fimc->state)) {
307 flite_hw_capture_start(fimc);
308
309 if (!test_and_set_bit(ST_SENSOR_STREAM, &fimc->state))
310 fimc_pipeline_s_stream(&fimc->pipeline, 1);
311 }
312 if (debug > 0)
313 flite_hw_dump_regs(fimc, __func__);
314
315 return 0;
316}
317
318static int stop_streaming(struct vb2_queue *q)
319{
320 struct fimc_lite *fimc = q->drv_priv;
321
322 if (!fimc_lite_active(fimc))
323 return -EINVAL;
324
325 return fimc_lite_stop_capture(fimc, false);
326}
327
328static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *pfmt,
329 unsigned int *num_buffers, unsigned int *num_planes,
330 unsigned int sizes[], void *allocators[])
331{
332 const struct v4l2_pix_format_mplane *pixm = NULL;
333 struct fimc_lite *fimc = vq->drv_priv;
334 struct flite_frame *frame = &fimc->out_frame;
335 const struct fimc_fmt *fmt = fimc->fmt;
336 unsigned long wh;
337 int i;
338
339 if (pfmt) {
340 pixm = &pfmt->fmt.pix_mp;
341 fmt = fimc_lite_find_format(&pixm->pixelformat, NULL, -1);
342 wh = pixm->width * pixm->height;
343 } else {
344 wh = frame->f_width * frame->f_height;
345 }
346
347 if (fmt == NULL)
348 return -EINVAL;
349
350 *num_planes = fmt->memplanes;
351
352 for (i = 0; i < fmt->memplanes; i++) {
353 unsigned int size = (wh * fmt->depth[i]) / 8;
354 if (pixm)
355 sizes[i] = max(size, pixm->plane_fmt[i].sizeimage);
356 else
357 sizes[i] = size;
358 allocators[i] = fimc->alloc_ctx;
359 }
360
361 return 0;
362}
363
364static int buffer_prepare(struct vb2_buffer *vb)
365{
366 struct vb2_queue *vq = vb->vb2_queue;
367 struct fimc_lite *fimc = vq->drv_priv;
368 int i;
369
370 if (fimc->fmt == NULL)
371 return -EINVAL;
372
373 for (i = 0; i < fimc->fmt->memplanes; i++) {
374 unsigned long size = fimc->payload[i];
375
376 if (vb2_plane_size(vb, i) < size) {
377 v4l2_err(fimc->vfd,
378 "User buffer too small (%ld < %ld)\n",
379 vb2_plane_size(vb, i), size);
380 return -EINVAL;
381 }
382 vb2_set_plane_payload(vb, i, size);
383 }
384
385 return 0;
386}
387
388static void buffer_queue(struct vb2_buffer *vb)
389{
390 struct flite_buffer *buf
391 = container_of(vb, struct flite_buffer, vb);
392 struct fimc_lite *fimc = vb2_get_drv_priv(vb->vb2_queue);
393 unsigned long flags;
394
395 spin_lock_irqsave(&fimc->slock, flags);
396 buf->paddr = vb2_dma_contig_plane_dma_addr(vb, 0);
397
398 if (!test_bit(ST_FLITE_SUSPENDED, &fimc->state) &&
399 !test_bit(ST_FLITE_STREAM, &fimc->state) &&
400 list_empty(&fimc->active_buf_q)) {
401 flite_hw_set_output_addr(fimc, buf->paddr);
402 fimc_lite_active_queue_add(fimc, buf);
403 } else {
404 fimc_lite_pending_queue_add(fimc, buf);
405 }
406
407 if (vb2_is_streaming(&fimc->vb_queue) &&
408 !list_empty(&fimc->pending_buf_q) &&
409 !test_and_set_bit(ST_FLITE_STREAM, &fimc->state)) {
410 flite_hw_capture_start(fimc);
411 spin_unlock_irqrestore(&fimc->slock, flags);
412
413 if (!test_and_set_bit(ST_SENSOR_STREAM, &fimc->state))
414 fimc_pipeline_s_stream(&fimc->pipeline, 1);
415 return;
416 }
417 spin_unlock_irqrestore(&fimc->slock, flags);
418}
419
420static void fimc_lock(struct vb2_queue *vq)
421{
422 struct fimc_lite *fimc = vb2_get_drv_priv(vq);
423 mutex_lock(&fimc->lock);
424}
425
426static void fimc_unlock(struct vb2_queue *vq)
427{
428 struct fimc_lite *fimc = vb2_get_drv_priv(vq);
429 mutex_unlock(&fimc->lock);
430}
431
432static const struct vb2_ops fimc_lite_qops = {
433 .queue_setup = queue_setup,
434 .buf_prepare = buffer_prepare,
435 .buf_queue = buffer_queue,
436 .wait_prepare = fimc_unlock,
437 .wait_finish = fimc_lock,
438 .start_streaming = start_streaming,
439 .stop_streaming = stop_streaming,
440};
441
442static void fimc_lite_clear_event_counters(struct fimc_lite *fimc)
443{
444 unsigned long flags;
445
446 spin_lock_irqsave(&fimc->slock, flags);
447 memset(&fimc->events, 0, sizeof(fimc->events));
448 spin_unlock_irqrestore(&fimc->slock, flags);
449}
450
451static int fimc_lite_open(struct file *file)
452{
453 struct fimc_lite *fimc = video_drvdata(file);
454 int ret;
455
456 if (mutex_lock_interruptible(&fimc->lock))
457 return -ERESTARTSYS;
458
459 set_bit(ST_FLITE_IN_USE, &fimc->state);
460 ret = pm_runtime_get_sync(&fimc->pdev->dev);
461 if (ret < 0)
462 goto done;
463
464 ret = v4l2_fh_open(file);
465 if (ret < 0)
466 goto done;
467
468 if (++fimc->ref_count == 1 && fimc->out_path == FIMC_IO_DMA) {
469 ret = fimc_pipeline_initialize(&fimc->pipeline,
470 &fimc->vfd->entity, true);
471 if (ret < 0) {
472 pm_runtime_put_sync(&fimc->pdev->dev);
473 fimc->ref_count--;
474 v4l2_fh_release(file);
475 clear_bit(ST_FLITE_IN_USE, &fimc->state);
476 }
477
478 fimc_lite_clear_event_counters(fimc);
479 }
480done:
481 mutex_unlock(&fimc->lock);
482 return ret;
483}
484
485static int fimc_lite_close(struct file *file)
486{
487 struct fimc_lite *fimc = video_drvdata(file);
488 int ret;
489
490 if (mutex_lock_interruptible(&fimc->lock))
491 return -ERESTARTSYS;
492
493 if (--fimc->ref_count == 0 && fimc->out_path == FIMC_IO_DMA) {
494 clear_bit(ST_FLITE_IN_USE, &fimc->state);
495 fimc_lite_stop_capture(fimc, false);
496 fimc_pipeline_shutdown(&fimc->pipeline);
497 clear_bit(ST_FLITE_SUSPENDED, &fimc->state);
498 }
499
500 pm_runtime_put(&fimc->pdev->dev);
501
502 if (fimc->ref_count == 0)
503 vb2_queue_release(&fimc->vb_queue);
504
505 ret = v4l2_fh_release(file);
506
507 mutex_unlock(&fimc->lock);
508 return ret;
509}
510
511static unsigned int fimc_lite_poll(struct file *file,
512 struct poll_table_struct *wait)
513{
514 struct fimc_lite *fimc = video_drvdata(file);
515 int ret;
516
517 if (mutex_lock_interruptible(&fimc->lock))
518 return POLL_ERR;
519
520 ret = vb2_poll(&fimc->vb_queue, file, wait);
521 mutex_unlock(&fimc->lock);
522
523 return ret;
524}
525
526static int fimc_lite_mmap(struct file *file, struct vm_area_struct *vma)
527{
528 struct fimc_lite *fimc = video_drvdata(file);
529 int ret;
530
531 if (mutex_lock_interruptible(&fimc->lock))
532 return -ERESTARTSYS;
533
534 ret = vb2_mmap(&fimc->vb_queue, vma);
535 mutex_unlock(&fimc->lock);
536
537 return ret;
538}
539
540static const struct v4l2_file_operations fimc_lite_fops = {
541 .owner = THIS_MODULE,
542 .open = fimc_lite_open,
543 .release = fimc_lite_close,
544 .poll = fimc_lite_poll,
545 .unlocked_ioctl = video_ioctl2,
546 .mmap = fimc_lite_mmap,
547};
548
549/*
550 * Format and crop negotiation helpers
551 */
552
553static const struct fimc_fmt *fimc_lite_try_format(struct fimc_lite *fimc,
554 u32 *width, u32 *height,
555 u32 *code, u32 *fourcc, int pad)
556{
557 struct flite_variant *variant = fimc->variant;
558 const struct fimc_fmt *fmt;
559
560 fmt = fimc_lite_find_format(fourcc, code, 0);
561 if (WARN_ON(!fmt))
562 return NULL;
563
564 if (code)
565 *code = fmt->mbus_code;
566 if (fourcc)
567 *fourcc = fmt->fourcc;
568
569 if (pad == FLITE_SD_PAD_SINK) {
570 v4l_bound_align_image(width, 8, variant->max_width,
571 ffs(variant->out_width_align) - 1,
572 height, 0, variant->max_height, 0, 0);
573 } else {
574 v4l_bound_align_image(width, 8, fimc->inp_frame.rect.width,
575 ffs(variant->out_width_align) - 1,
576 height, 0, fimc->inp_frame.rect.height,
577 0, 0);
578 }
579
580 v4l2_dbg(1, debug, &fimc->subdev, "code: 0x%x, %dx%d\n",
581 code ? *code : 0, *width, *height);
582
583 return fmt;
584}
585
586static void fimc_lite_try_crop(struct fimc_lite *fimc, struct v4l2_rect *r)
587{
588 struct flite_frame *frame = &fimc->inp_frame;
589
590 v4l_bound_align_image(&r->width, 0, frame->f_width, 0,
591 &r->height, 0, frame->f_height, 0, 0);
592
593 /* Adjust left/top if cropping rectangle got out of bounds */
594 r->left = clamp_t(u32, r->left, 0, frame->f_width - r->width);
595 r->left = round_down(r->left, fimc->variant->win_hor_offs_align);
596 r->top = clamp_t(u32, r->top, 0, frame->f_height - r->height);
597
598 v4l2_dbg(1, debug, &fimc->subdev, "(%d,%d)/%dx%d, sink fmt: %dx%d",
599 r->left, r->top, r->width, r->height,
600 frame->f_width, frame->f_height);
601}
602
603static void fimc_lite_try_compose(struct fimc_lite *fimc, struct v4l2_rect *r)
604{
605 struct flite_frame *frame = &fimc->out_frame;
606 struct v4l2_rect *crop_rect = &fimc->inp_frame.rect;
607
608 /* Scaling is not supported so we enforce compose rectangle size
609 same as size of the sink crop rectangle. */
610 r->width = crop_rect->width;
611 r->height = crop_rect->height;
612
613 /* Adjust left/top if the composing rectangle got out of bounds */
614 r->left = clamp_t(u32, r->left, 0, frame->f_width - r->width);
615 r->left = round_down(r->left, fimc->variant->out_hor_offs_align);
616 r->top = clamp_t(u32, r->top, 0, fimc->out_frame.f_height - r->height);
617
618 v4l2_dbg(1, debug, &fimc->subdev, "(%d,%d)/%dx%d, source fmt: %dx%d",
619 r->left, r->top, r->width, r->height,
620 frame->f_width, frame->f_height);
621}
622
623/*
624 * Video node ioctl operations
625 */
626static int fimc_vidioc_querycap_capture(struct file *file, void *priv,
627 struct v4l2_capability *cap)
628{
629 strlcpy(cap->driver, FIMC_LITE_DRV_NAME, sizeof(cap->driver));
630 cap->bus_info[0] = 0;
631 cap->card[0] = 0;
632 cap->capabilities = V4L2_CAP_STREAMING;
633 return 0;
634}
635
636static int fimc_lite_enum_fmt_mplane(struct file *file, void *priv,
637 struct v4l2_fmtdesc *f)
638{
639 const struct fimc_fmt *fmt;
640
641 if (f->index >= ARRAY_SIZE(fimc_lite_formats))
642 return -EINVAL;
643
644 fmt = &fimc_lite_formats[f->index];
645 strlcpy(f->description, fmt->name, sizeof(f->description));
646 f->pixelformat = fmt->fourcc;
647
648 return 0;
649}
650
651static int fimc_lite_g_fmt_mplane(struct file *file, void *fh,
652 struct v4l2_format *f)
653{
654 struct fimc_lite *fimc = video_drvdata(file);
655 struct v4l2_pix_format_mplane *pixm = &f->fmt.pix_mp;
656 struct v4l2_plane_pix_format *plane_fmt = &pixm->plane_fmt[0];
657 struct flite_frame *frame = &fimc->out_frame;
658 const struct fimc_fmt *fmt = fimc->fmt;
659
660 plane_fmt->bytesperline = (frame->f_width * fmt->depth[0]) / 8;
661 plane_fmt->sizeimage = plane_fmt->bytesperline * frame->f_height;
662
663 pixm->num_planes = fmt->memplanes;
664 pixm->pixelformat = fmt->fourcc;
665 pixm->width = frame->f_width;
666 pixm->height = frame->f_height;
667 pixm->field = V4L2_FIELD_NONE;
668 pixm->colorspace = V4L2_COLORSPACE_JPEG;
669 return 0;
670}
671
672static int fimc_lite_try_fmt(struct fimc_lite *fimc,
673 struct v4l2_pix_format_mplane *pixm,
674 const struct fimc_fmt **ffmt)
675{
676 struct flite_variant *variant = fimc->variant;
677 u32 bpl = pixm->plane_fmt[0].bytesperline;
678 const struct fimc_fmt *fmt;
679
680 fmt = fimc_lite_find_format(&pixm->pixelformat, NULL, 0);
681 if (WARN_ON(fmt == NULL))
682 return -EINVAL;
683 if (ffmt)
684 *ffmt = fmt;
685 v4l_bound_align_image(&pixm->width, 8, variant->max_width,
686 ffs(variant->out_width_align) - 1,
687 &pixm->height, 0, variant->max_height, 0, 0);
688
689 if ((bpl == 0 || ((bpl * 8) / fmt->depth[0]) < pixm->width))
690 pixm->plane_fmt[0].bytesperline = (pixm->width *
691 fmt->depth[0]) / 8;
692
693 if (pixm->plane_fmt[0].sizeimage == 0)
694 pixm->plane_fmt[0].sizeimage = (pixm->width * pixm->height *
695 fmt->depth[0]) / 8;
696 pixm->num_planes = fmt->memplanes;
697 pixm->pixelformat = fmt->fourcc;
698 pixm->colorspace = V4L2_COLORSPACE_JPEG;
699 pixm->field = V4L2_FIELD_NONE;
700 return 0;
701}
702
703static int fimc_lite_try_fmt_mplane(struct file *file, void *fh,
704 struct v4l2_format *f)
705{
706 struct fimc_lite *fimc = video_drvdata(file);
707
708 return fimc_lite_try_fmt(fimc, &f->fmt.pix_mp, NULL);
709}
710
711static int fimc_lite_s_fmt_mplane(struct file *file, void *priv,
712 struct v4l2_format *f)
713{
714 struct v4l2_pix_format_mplane *pixm = &f->fmt.pix_mp;
715 struct fimc_lite *fimc = video_drvdata(file);
716 struct flite_frame *frame = &fimc->out_frame;
717 const struct fimc_fmt *fmt = NULL;
718 int ret;
719
720 if (vb2_is_busy(&fimc->vb_queue))
721 return -EBUSY;
722
723 ret = fimc_lite_try_fmt(fimc, &f->fmt.pix_mp, &fmt);
724 if (ret < 0)
725 return ret;
726
727 fimc->fmt = fmt;
728 fimc->payload[0] = max((pixm->width * pixm->height * fmt->depth[0]) / 8,
729 pixm->plane_fmt[0].sizeimage);
730 frame->f_width = pixm->width;
731 frame->f_height = pixm->height;
732
733 return 0;
734}
735
736static int fimc_pipeline_validate(struct fimc_lite *fimc)
737{
738 struct v4l2_subdev *sd = &fimc->subdev;
739 struct v4l2_subdev_format sink_fmt, src_fmt;
740 struct media_pad *pad;
741 int ret;
742
743 while (1) {
744 /* Retrieve format at the sink pad */
745 pad = &sd->entity.pads[0];
746 if (!(pad->flags & MEDIA_PAD_FL_SINK))
747 break;
748 /* Don't call FIMC subdev operation to avoid nested locking */
749 if (sd == &fimc->subdev) {
750 struct flite_frame *ff = &fimc->out_frame;
751 sink_fmt.format.width = ff->f_width;
752 sink_fmt.format.height = ff->f_height;
753 sink_fmt.format.code = fimc->fmt->mbus_code;
754 } else {
755 sink_fmt.pad = pad->index;
756 sink_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
757 ret = v4l2_subdev_call(sd, pad, get_fmt, NULL,
758 &sink_fmt);
759 if (ret < 0 && ret != -ENOIOCTLCMD)
760 return -EPIPE;
761 }
762 /* Retrieve format at the source pad */
763 pad = media_entity_remote_source(pad);
764 if (pad == NULL ||
765 media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
766 break;
767
768 sd = media_entity_to_v4l2_subdev(pad->entity);
769 src_fmt.pad = pad->index;
770 src_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
771 ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &src_fmt);
772 if (ret < 0 && ret != -ENOIOCTLCMD)
773 return -EPIPE;
774
775 if (src_fmt.format.width != sink_fmt.format.width ||
776 src_fmt.format.height != sink_fmt.format.height ||
777 src_fmt.format.code != sink_fmt.format.code)
778 return -EPIPE;
779 }
780 return 0;
781}
782
783static int fimc_lite_streamon(struct file *file, void *priv,
784 enum v4l2_buf_type type)
785{
786 struct fimc_lite *fimc = video_drvdata(file);
787 struct v4l2_subdev *sensor = fimc->pipeline.subdevs[IDX_SENSOR];
788 struct fimc_pipeline *p = &fimc->pipeline;
789 int ret;
790
791 if (fimc_lite_active(fimc))
792 return -EBUSY;
793
794 ret = media_entity_pipeline_start(&sensor->entity, p->m_pipeline);
795 if (ret < 0)
796 return ret;
797
798 ret = fimc_pipeline_validate(fimc);
799 if (ret) {
800 media_entity_pipeline_stop(&sensor->entity);
801 return ret;
802 }
803
804 return vb2_streamon(&fimc->vb_queue, type);
805}
806
807static int fimc_lite_streamoff(struct file *file, void *priv,
808 enum v4l2_buf_type type)
809{
810 struct fimc_lite *fimc = video_drvdata(file);
811 struct v4l2_subdev *sd = fimc->pipeline.subdevs[IDX_SENSOR];
812 int ret;
813
814 ret = vb2_streamoff(&fimc->vb_queue, type);
815 if (ret == 0)
816 media_entity_pipeline_stop(&sd->entity);
817 return ret;
818}
819
820static int fimc_lite_reqbufs(struct file *file, void *priv,
821 struct v4l2_requestbuffers *reqbufs)
822{
823 struct fimc_lite *fimc = video_drvdata(file);
824 int ret;
825
826 reqbufs->count = max_t(u32, FLITE_REQ_BUFS_MIN, reqbufs->count);
827 ret = vb2_reqbufs(&fimc->vb_queue, reqbufs);
828 if (!ret < 0)
829 fimc->reqbufs_count = reqbufs->count;
830
831 return ret;
832}
833
834static int fimc_lite_querybuf(struct file *file, void *priv,
835 struct v4l2_buffer *buf)
836{
837 struct fimc_lite *fimc = video_drvdata(file);
838
839 return vb2_querybuf(&fimc->vb_queue, buf);
840}
841
842static int fimc_lite_qbuf(struct file *file, void *priv,
843 struct v4l2_buffer *buf)
844{
845 struct fimc_lite *fimc = video_drvdata(file);
846
847 return vb2_qbuf(&fimc->vb_queue, buf);
848}
849
850static int fimc_lite_dqbuf(struct file *file, void *priv,
851 struct v4l2_buffer *buf)
852{
853 struct fimc_lite *fimc = video_drvdata(file);
854
855 return vb2_dqbuf(&fimc->vb_queue, buf, file->f_flags & O_NONBLOCK);
856}
857
858static int fimc_lite_create_bufs(struct file *file, void *priv,
859 struct v4l2_create_buffers *create)
860{
861 struct fimc_lite *fimc = video_drvdata(file);
862
863 return vb2_create_bufs(&fimc->vb_queue, create);
864}
865
866static int fimc_lite_prepare_buf(struct file *file, void *priv,
867 struct v4l2_buffer *b)
868{
869 struct fimc_lite *fimc = video_drvdata(file);
870
871 return vb2_prepare_buf(&fimc->vb_queue, b);
872}
873
874/* Return 1 if rectangle a is enclosed in rectangle b, or 0 otherwise. */
875static int enclosed_rectangle(struct v4l2_rect *a, struct v4l2_rect *b)
876{
877 if (a->left < b->left || a->top < b->top)
878 return 0;
879 if (a->left + a->width > b->left + b->width)
880 return 0;
881 if (a->top + a->height > b->top + b->height)
882 return 0;
883
884 return 1;
885}
886
887static int fimc_lite_g_selection(struct file *file, void *fh,
888 struct v4l2_selection *sel)
889{
890 struct fimc_lite *fimc = video_drvdata(file);
891 struct flite_frame *f = &fimc->out_frame;
892
893 if (sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
894 return -EINVAL;
895
896 switch (sel->target) {
897 case V4L2_SEL_TGT_COMPOSE_BOUNDS:
898 case V4L2_SEL_TGT_COMPOSE_DEFAULT:
899 sel->r.left = 0;
900 sel->r.top = 0;
901 sel->r.width = f->f_width;
902 sel->r.height = f->f_height;
903 return 0;
904
905 case V4L2_SEL_TGT_COMPOSE:
906 sel->r = f->rect;
907 return 0;
908 }
909
910 return -EINVAL;
911}
912
913static int fimc_lite_s_selection(struct file *file, void *fh,
914 struct v4l2_selection *sel)
915{
916 struct fimc_lite *fimc = video_drvdata(file);
917 struct flite_frame *f = &fimc->out_frame;
918 struct v4l2_rect rect = sel->r;
919 unsigned long flags;
920
921 if (sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
922 sel->target != V4L2_SEL_TGT_COMPOSE)
923 return -EINVAL;
924
925 fimc_lite_try_compose(fimc, &rect);
926
927 if ((sel->flags & V4L2_SEL_FLAG_LE) &&
928 !enclosed_rectangle(&rect, &sel->r))
929 return -ERANGE;
930
931 if ((sel->flags & V4L2_SEL_FLAG_GE) &&
932 !enclosed_rectangle(&sel->r, &rect))
933 return -ERANGE;
934
935 sel->r = rect;
936 spin_lock_irqsave(&fimc->slock, flags);
937 f->rect = rect;
938 set_bit(ST_FLITE_CONFIG, &fimc->state);
939 spin_unlock_irqrestore(&fimc->slock, flags);
940
941 return 0;
942}
943
944static const struct v4l2_ioctl_ops fimc_lite_ioctl_ops = {
945 .vidioc_querycap = fimc_vidioc_querycap_capture,
946 .vidioc_enum_fmt_vid_cap_mplane = fimc_lite_enum_fmt_mplane,
947 .vidioc_try_fmt_vid_cap_mplane = fimc_lite_try_fmt_mplane,
948 .vidioc_s_fmt_vid_cap_mplane = fimc_lite_s_fmt_mplane,
949 .vidioc_g_fmt_vid_cap_mplane = fimc_lite_g_fmt_mplane,
950 .vidioc_g_selection = fimc_lite_g_selection,
951 .vidioc_s_selection = fimc_lite_s_selection,
952 .vidioc_reqbufs = fimc_lite_reqbufs,
953 .vidioc_querybuf = fimc_lite_querybuf,
954 .vidioc_prepare_buf = fimc_lite_prepare_buf,
955 .vidioc_create_bufs = fimc_lite_create_bufs,
956 .vidioc_qbuf = fimc_lite_qbuf,
957 .vidioc_dqbuf = fimc_lite_dqbuf,
958 .vidioc_streamon = fimc_lite_streamon,
959 .vidioc_streamoff = fimc_lite_streamoff,
960};
961
962/* Capture subdev media entity operations */
963static int fimc_lite_link_setup(struct media_entity *entity,
964 const struct media_pad *local,
965 const struct media_pad *remote, u32 flags)
966{
967 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
968 struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
969 unsigned int remote_ent_type = media_entity_type(remote->entity);
970
971 if (WARN_ON(fimc == NULL))
972 return 0;
973
974 v4l2_dbg(1, debug, sd, "%s: %s --> %s, flags: 0x%x. source_id: 0x%x",
975 __func__, local->entity->name, remote->entity->name,
976 flags, fimc->source_subdev_grp_id);
977
978 switch (local->index) {
979 case FIMC_SD_PAD_SINK:
980 if (remote_ent_type != MEDIA_ENT_T_V4L2_SUBDEV)
981 return -EINVAL;
982
983 if (flags & MEDIA_LNK_FL_ENABLED) {
984 if (fimc->source_subdev_grp_id != 0)
985 return -EBUSY;
986 fimc->source_subdev_grp_id = sd->grp_id;
987 return 0;
988 }
989
990 fimc->source_subdev_grp_id = 0;
991 break;
992
993 case FIMC_SD_PAD_SOURCE:
994 if (!(flags & MEDIA_LNK_FL_ENABLED)) {
995 fimc->out_path = FIMC_IO_NONE;
996 return 0;
997 }
998 if (remote_ent_type == MEDIA_ENT_T_V4L2_SUBDEV)
999 fimc->out_path = FIMC_IO_ISP;
1000 else
1001 fimc->out_path = FIMC_IO_DMA;
1002 break;
1003
1004 default:
1005 v4l2_err(sd, "Invalid pad index\n");
1006 return -EINVAL;
1007 }
1008
1009 return 0;
1010}
1011
1012static const struct media_entity_operations fimc_lite_subdev_media_ops = {
1013 .link_setup = fimc_lite_link_setup,
1014};
1015
1016static int fimc_lite_subdev_enum_mbus_code(struct v4l2_subdev *sd,
1017 struct v4l2_subdev_fh *fh,
1018 struct v4l2_subdev_mbus_code_enum *code)
1019{
1020 const struct fimc_fmt *fmt;
1021
1022 fmt = fimc_lite_find_format(NULL, NULL, code->index);
1023 if (!fmt)
1024 return -EINVAL;
1025 code->code = fmt->mbus_code;
1026 return 0;
1027}
1028
1029static int fimc_lite_subdev_get_fmt(struct v4l2_subdev *sd,
1030 struct v4l2_subdev_fh *fh,
1031 struct v4l2_subdev_format *fmt)
1032{
1033 struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
1034 struct v4l2_mbus_framefmt *mf = &fmt->format;
1035 struct flite_frame *f = &fimc->out_frame;
1036
1037 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
1038 mf = v4l2_subdev_get_try_format(fh, fmt->pad);
1039 fmt->format = *mf;
1040 return 0;
1041 }
1042 mf->colorspace = V4L2_COLORSPACE_JPEG;
1043
1044 mutex_lock(&fimc->lock);
1045 mf->code = fimc->fmt->mbus_code;
1046
1047 if (fmt->pad == FLITE_SD_PAD_SINK) {
1048 /* full camera input frame size */
1049 mf->width = f->f_width;
1050 mf->height = f->f_height;
1051 } else {
1052 /* crop size */
1053 mf->width = f->rect.width;
1054 mf->height = f->rect.height;
1055 }
1056 mutex_unlock(&fimc->lock);
1057 return 0;
1058}
1059
1060static int fimc_lite_subdev_set_fmt(struct v4l2_subdev *sd,
1061 struct v4l2_subdev_fh *fh,
1062 struct v4l2_subdev_format *fmt)
1063{
1064 struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
1065 struct v4l2_mbus_framefmt *mf = &fmt->format;
1066 struct flite_frame *sink = &fimc->inp_frame;
1067 const struct fimc_fmt *ffmt;
1068
1069 v4l2_dbg(1, debug, sd, "pad%d: code: 0x%x, %dx%d",
1070 fmt->pad, mf->code, mf->width, mf->height);
1071
1072 mf->colorspace = V4L2_COLORSPACE_JPEG;
1073 mutex_lock(&fimc->lock);
1074
1075 if ((fimc->out_path == FIMC_IO_ISP && sd->entity.stream_count > 0) ||
1076 (fimc->out_path == FIMC_IO_DMA && vb2_is_busy(&fimc->vb_queue))) {
1077 mutex_unlock(&fimc->lock);
1078 return -EBUSY;
1079 }
1080
1081 ffmt = fimc_lite_try_format(fimc, &mf->width, &mf->height,
1082 &mf->code, NULL, fmt->pad);
1083
1084 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
1085 mf = v4l2_subdev_get_try_format(fh, fmt->pad);
1086 *mf = fmt->format;
1087 mutex_unlock(&fimc->lock);
1088 return 0;
1089 }
1090
1091 if (fmt->pad == FLITE_SD_PAD_SINK) {
1092 sink->f_width = mf->width;
1093 sink->f_height = mf->height;
1094 fimc->fmt = ffmt;
1095 /* Set sink crop rectangle */
1096 sink->rect.width = mf->width;
1097 sink->rect.height = mf->height;
1098 sink->rect.left = 0;
1099 sink->rect.top = 0;
1100 /* Reset source crop rectangle */
1101 fimc->out_frame.rect = sink->rect;
1102 } else {
1103 /* Allow changing format only on sink pad */
1104 mf->code = fimc->fmt->mbus_code;
1105 mf->width = sink->rect.width;
1106 mf->height = sink->rect.height;
1107 }
1108
1109 mutex_unlock(&fimc->lock);
1110 return 0;
1111}
1112
1113static int fimc_lite_subdev_get_selection(struct v4l2_subdev *sd,
1114 struct v4l2_subdev_fh *fh,
1115 struct v4l2_subdev_selection *sel)
1116{
1117 struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
1118 struct flite_frame *f = &fimc->inp_frame;
1119
1120 if ((sel->target != V4L2_SEL_TGT_CROP &&
1121 sel->target != V4L2_SEL_TGT_CROP_BOUNDS) ||
1122 sel->pad != FLITE_SD_PAD_SINK)
1123 return -EINVAL;
1124
1125 if (sel->which == V4L2_SUBDEV_FORMAT_TRY) {
1126 sel->r = *v4l2_subdev_get_try_crop(fh, sel->pad);
1127 return 0;
1128 }
1129
1130 mutex_lock(&fimc->lock);
1131 if (sel->target == V4L2_SEL_TGT_CROP) {
1132 sel->r = f->rect;
1133 } else {
1134 sel->r.left = 0;
1135 sel->r.top = 0;
1136 sel->r.width = f->f_width;
1137 sel->r.height = f->f_height;
1138 }
1139 mutex_unlock(&fimc->lock);
1140
1141 v4l2_dbg(1, debug, sd, "%s: (%d,%d) %dx%d, f_w: %d, f_h: %d",
1142 __func__, f->rect.left, f->rect.top, f->rect.width,
1143 f->rect.height, f->f_width, f->f_height);
1144
1145 return 0;
1146}
1147
1148static int fimc_lite_subdev_set_selection(struct v4l2_subdev *sd,
1149 struct v4l2_subdev_fh *fh,
1150 struct v4l2_subdev_selection *sel)
1151{
1152 struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
1153 struct flite_frame *f = &fimc->inp_frame;
1154 int ret = 0;
1155
1156 if (sel->target != V4L2_SEL_TGT_CROP || sel->pad != FLITE_SD_PAD_SINK)
1157 return -EINVAL;
1158
1159 mutex_lock(&fimc->lock);
1160 fimc_lite_try_crop(fimc, &sel->r);
1161
1162 if (sel->which == V4L2_SUBDEV_FORMAT_TRY) {
1163 *v4l2_subdev_get_try_crop(fh, sel->pad) = sel->r;
1164 } else {
1165 unsigned long flags;
1166 spin_lock_irqsave(&fimc->slock, flags);
1167 f->rect = sel->r;
1168 /* Same crop rectangle on the source pad */
1169 fimc->out_frame.rect = sel->r;
1170 set_bit(ST_FLITE_CONFIG, &fimc->state);
1171 spin_unlock_irqrestore(&fimc->slock, flags);
1172 }
1173 mutex_unlock(&fimc->lock);
1174
1175 v4l2_dbg(1, debug, sd, "%s: (%d,%d) %dx%d, f_w: %d, f_h: %d",
1176 __func__, f->rect.left, f->rect.top, f->rect.width,
1177 f->rect.height, f->f_width, f->f_height);
1178
1179 return ret;
1180}
1181
1182static int fimc_lite_subdev_s_stream(struct v4l2_subdev *sd, int on)
1183{
1184 struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
1185
1186 if (fimc->out_path == FIMC_IO_DMA)
1187 return -ENOIOCTLCMD;
1188
1189 /* TODO: */
1190
1191 return 0;
1192}
1193
1194static int fimc_lite_subdev_s_power(struct v4l2_subdev *sd, int on)
1195{
1196 struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
1197
1198 if (fimc->out_path == FIMC_IO_DMA)
1199 return -ENOIOCTLCMD;
1200
1201 /* TODO: */
1202
1203 return 0;
1204}
1205
1206static int fimc_lite_log_status(struct v4l2_subdev *sd)
1207{
1208 struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
1209
1210 flite_hw_dump_regs(fimc, __func__);
1211 return 0;
1212}
1213
1214static int fimc_lite_subdev_registered(struct v4l2_subdev *sd)
1215{
1216 struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
1217 struct vb2_queue *q = &fimc->vb_queue;
1218 struct video_device *vfd;
1219 int ret;
1220
1221 fimc->fmt = &fimc_lite_formats[0];
1222 fimc->out_path = FIMC_IO_DMA;
1223
1224 vfd = video_device_alloc();
1225 if (!vfd) {
1226 v4l2_err(sd->v4l2_dev, "Failed to allocate video device\n");
1227 return -ENOMEM;
1228 }
1229
1230 snprintf(vfd->name, sizeof(vfd->name), "fimc-lite.%d.capture",
1231 fimc->index);
1232
1233 vfd->fops = &fimc_lite_fops;
1234 vfd->ioctl_ops = &fimc_lite_ioctl_ops;
1235 vfd->v4l2_dev = sd->v4l2_dev;
1236 vfd->minor = -1;
1237 vfd->release = video_device_release;
1238 vfd->lock = &fimc->lock;
1239 fimc->vfd = vfd;
1240 fimc->ref_count = 0;
1241 fimc->reqbufs_count = 0;
1242
1243 INIT_LIST_HEAD(&fimc->pending_buf_q);
1244 INIT_LIST_HEAD(&fimc->active_buf_q);
1245
1246 memset(q, 0, sizeof(*q));
1247 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1248 q->io_modes = VB2_MMAP | VB2_USERPTR;
1249 q->ops = &fimc_lite_qops;
1250 q->mem_ops = &vb2_dma_contig_memops;
1251 q->buf_struct_size = sizeof(struct flite_buffer);
1252 q->drv_priv = fimc;
1253
1254 vb2_queue_init(q);
1255
1256 fimc->vd_pad.flags = MEDIA_PAD_FL_SINK;
1257 ret = media_entity_init(&vfd->entity, 1, &fimc->vd_pad, 0);
1258 if (ret)
1259 goto err;
1260
1261 video_set_drvdata(vfd, fimc);
1262
1263 ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1);
1264 if (ret)
1265 goto err_vd;
1266
1267 v4l2_info(sd->v4l2_dev, "Registered %s as /dev/%s\n",
1268 vfd->name, video_device_node_name(vfd));
1269 return 0;
1270
1271 err_vd:
1272 media_entity_cleanup(&vfd->entity);
1273 err:
1274 video_device_release(vfd);
1275 return ret;
1276}
1277
1278static void fimc_lite_subdev_unregistered(struct v4l2_subdev *sd)
1279{
1280 struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
1281
1282 if (fimc == NULL)
1283 return;
1284
1285 if (fimc->vfd) {
1286 video_unregister_device(fimc->vfd);
1287 media_entity_cleanup(&fimc->vfd->entity);
1288 fimc->vfd = NULL;
1289 }
1290}
1291
1292static const struct v4l2_subdev_internal_ops fimc_lite_subdev_internal_ops = {
1293 .registered = fimc_lite_subdev_registered,
1294 .unregistered = fimc_lite_subdev_unregistered,
1295};
1296
1297static const struct v4l2_subdev_pad_ops fimc_lite_subdev_pad_ops = {
1298 .enum_mbus_code = fimc_lite_subdev_enum_mbus_code,
1299 .get_selection = fimc_lite_subdev_get_selection,
1300 .set_selection = fimc_lite_subdev_set_selection,
1301 .get_fmt = fimc_lite_subdev_get_fmt,
1302 .set_fmt = fimc_lite_subdev_set_fmt,
1303};
1304
1305static const struct v4l2_subdev_video_ops fimc_lite_subdev_video_ops = {
1306 .s_stream = fimc_lite_subdev_s_stream,
1307};
1308
1309static const struct v4l2_subdev_core_ops fimc_lite_core_ops = {
1310 .s_power = fimc_lite_subdev_s_power,
1311 .log_status = fimc_lite_log_status,
1312};
1313
1314static struct v4l2_subdev_ops fimc_lite_subdev_ops = {
1315 .core = &fimc_lite_core_ops,
1316 .video = &fimc_lite_subdev_video_ops,
1317 .pad = &fimc_lite_subdev_pad_ops,
1318};
1319
1320static int fimc_lite_s_ctrl(struct v4l2_ctrl *ctrl)
1321{
1322 struct fimc_lite *fimc = container_of(ctrl->handler, struct fimc_lite,
1323 ctrl_handler);
1324 set_bit(ST_FLITE_CONFIG, &fimc->state);
1325 return 0;
1326}
1327
1328static const struct v4l2_ctrl_ops fimc_lite_ctrl_ops = {
1329 .s_ctrl = fimc_lite_s_ctrl,
1330};
1331
1332static const struct v4l2_ctrl_config fimc_lite_ctrl = {
1333 .ops = &fimc_lite_ctrl_ops,
1334 .id = V4L2_CTRL_CLASS_USER | 0x1001,
1335 .type = V4L2_CTRL_TYPE_BOOLEAN,
1336 .name = "Test Pattern 640x480",
1337};
1338
1339static int fimc_lite_create_capture_subdev(struct fimc_lite *fimc)
1340{
1341 struct v4l2_ctrl_handler *handler = &fimc->ctrl_handler;
1342 struct v4l2_subdev *sd = &fimc->subdev;
1343 int ret;
1344
1345 v4l2_subdev_init(sd, &fimc_lite_subdev_ops);
1346 sd->flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
1347 snprintf(sd->name, sizeof(sd->name), "FIMC-LITE.%d", fimc->index);
1348
1349 fimc->subdev_pads[FIMC_SD_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
1350 fimc->subdev_pads[FIMC_SD_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
1351 ret = media_entity_init(&sd->entity, FIMC_SD_PADS_NUM,
1352 fimc->subdev_pads, 0);
1353 if (ret)
1354 return ret;
1355
1356 v4l2_ctrl_handler_init(handler, 1);
1357 fimc->test_pattern = v4l2_ctrl_new_custom(handler, &fimc_lite_ctrl,
1358 NULL);
1359 if (handler->error) {
1360 media_entity_cleanup(&sd->entity);
1361 return handler->error;
1362 }
1363
1364 sd->ctrl_handler = handler;
1365 sd->internal_ops = &fimc_lite_subdev_internal_ops;
1366 sd->entity.ops = &fimc_lite_subdev_media_ops;
1367 v4l2_set_subdevdata(sd, fimc);
1368
1369 return 0;
1370}
1371
1372static void fimc_lite_unregister_capture_subdev(struct fimc_lite *fimc)
1373{
1374 struct v4l2_subdev *sd = &fimc->subdev;
1375
1376 v4l2_device_unregister_subdev(sd);
1377 media_entity_cleanup(&sd->entity);
1378 v4l2_ctrl_handler_free(&fimc->ctrl_handler);
1379 v4l2_set_subdevdata(sd, NULL);
1380}
1381
1382static void fimc_lite_clk_put(struct fimc_lite *fimc)
1383{
1384 if (IS_ERR_OR_NULL(fimc->clock))
1385 return;
1386
1387 clk_unprepare(fimc->clock);
1388 clk_put(fimc->clock);
1389 fimc->clock = NULL;
1390}
1391
1392static int fimc_lite_clk_get(struct fimc_lite *fimc)
1393{
1394 int ret;
1395
1396 fimc->clock = clk_get(&fimc->pdev->dev, FLITE_CLK_NAME);
1397 if (IS_ERR(fimc->clock))
1398 return PTR_ERR(fimc->clock);
1399
1400 ret = clk_prepare(fimc->clock);
1401 if (ret < 0) {
1402 clk_put(fimc->clock);
1403 fimc->clock = NULL;
1404 }
1405 return ret;
1406}
1407
1408static int __devinit fimc_lite_probe(struct platform_device *pdev)
1409{
1410 struct flite_drvdata *drv_data = fimc_lite_get_drvdata(pdev);
1411 struct fimc_lite *fimc;
1412 struct resource *res;
1413 int ret;
1414
1415 fimc = devm_kzalloc(&pdev->dev, sizeof(*fimc), GFP_KERNEL);
1416 if (!fimc)
1417 return -ENOMEM;
1418
1419 fimc->index = pdev->id;
1420 fimc->variant = drv_data->variant[fimc->index];
1421 fimc->pdev = pdev;
1422
1423 init_waitqueue_head(&fimc->irq_queue);
1424 spin_lock_init(&fimc->slock);
1425 mutex_init(&fimc->lock);
1426
1427 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1428 fimc->regs = devm_request_and_ioremap(&pdev->dev, res);
1429 if (fimc->regs == NULL) {
1430 dev_err(&pdev->dev, "Failed to obtain io memory\n");
1431 return -ENOENT;
1432 }
1433
1434 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
1435 if (res == NULL) {
1436 dev_err(&pdev->dev, "Failed to get IRQ resource\n");
1437 return -ENXIO;
1438 }
1439
1440 ret = fimc_lite_clk_get(fimc);
1441 if (ret)
1442 return ret;
1443
1444 ret = devm_request_irq(&pdev->dev, res->start, flite_irq_handler,
1445 0, dev_name(&pdev->dev), fimc);
1446 if (ret) {
1447 dev_err(&pdev->dev, "Failed to install irq (%d)\n", ret);
1448 goto err_clk;
1449 }
1450
1451 /* The video node will be created within the subdev's registered() op */
1452 ret = fimc_lite_create_capture_subdev(fimc);
1453 if (ret)
1454 goto err_clk;
1455
1456 platform_set_drvdata(pdev, fimc);
1457 pm_runtime_enable(&pdev->dev);
1458 ret = pm_runtime_get_sync(&pdev->dev);
1459 if (ret < 0)
1460 goto err_sd;
1461
1462 fimc->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
1463 if (IS_ERR(fimc->alloc_ctx)) {
1464 ret = PTR_ERR(fimc->alloc_ctx);
1465 goto err_pm;
1466 }
1467 pm_runtime_put(&pdev->dev);
1468
1469 dev_dbg(&pdev->dev, "FIMC-LITE.%d registered successfully\n",
1470 fimc->index);
1471 return 0;
1472err_pm:
1473 pm_runtime_put(&pdev->dev);
1474err_sd:
1475 fimc_lite_unregister_capture_subdev(fimc);
1476err_clk:
1477 fimc_lite_clk_put(fimc);
1478 return ret;
1479}
1480
1481static int fimc_lite_runtime_resume(struct device *dev)
1482{
1483 struct fimc_lite *fimc = dev_get_drvdata(dev);
1484
1485 clk_enable(fimc->clock);
1486 return 0;
1487}
1488
1489static int fimc_lite_runtime_suspend(struct device *dev)
1490{
1491 struct fimc_lite *fimc = dev_get_drvdata(dev);
1492
1493 clk_disable(fimc->clock);
1494 return 0;
1495}
1496
1497#ifdef CONFIG_PM_SLEEP
1498static int fimc_lite_resume(struct device *dev)
1499{
1500 struct fimc_lite *fimc = dev_get_drvdata(dev);
1501 struct flite_buffer *buf;
1502 unsigned long flags;
1503 int i;
1504
1505 spin_lock_irqsave(&fimc->slock, flags);
1506 if (!test_and_clear_bit(ST_LPM, &fimc->state) ||
1507 !test_bit(ST_FLITE_IN_USE, &fimc->state)) {
1508 spin_unlock_irqrestore(&fimc->slock, flags);
1509 return 0;
1510 }
1511 flite_hw_reset(fimc);
1512 spin_unlock_irqrestore(&fimc->slock, flags);
1513
1514 if (!test_and_clear_bit(ST_FLITE_SUSPENDED, &fimc->state))
1515 return 0;
1516
1517 INIT_LIST_HEAD(&fimc->active_buf_q);
1518 fimc_pipeline_initialize(&fimc->pipeline, &fimc->vfd->entity, false);
1519 fimc_lite_hw_init(fimc);
1520 clear_bit(ST_FLITE_SUSPENDED, &fimc->state);
1521
1522 for (i = 0; i < fimc->reqbufs_count; i++) {
1523 if (list_empty(&fimc->pending_buf_q))
1524 break;
1525 buf = fimc_lite_pending_queue_pop(fimc);
1526 buffer_queue(&buf->vb);
1527 }
1528 return 0;
1529}
1530
1531static int fimc_lite_suspend(struct device *dev)
1532{
1533 struct fimc_lite *fimc = dev_get_drvdata(dev);
1534 bool suspend = test_bit(ST_FLITE_IN_USE, &fimc->state);
1535 int ret;
1536
1537 if (test_and_set_bit(ST_LPM, &fimc->state))
1538 return 0;
1539
1540 ret = fimc_lite_stop_capture(fimc, suspend);
1541 if (ret < 0 || !fimc_lite_active(fimc))
1542 return ret;
1543
1544 return fimc_pipeline_shutdown(&fimc->pipeline);
1545}
1546#endif /* CONFIG_PM_SLEEP */
1547
1548static int __devexit fimc_lite_remove(struct platform_device *pdev)
1549{
1550 struct fimc_lite *fimc = platform_get_drvdata(pdev);
1551 struct device *dev = &pdev->dev;
1552
1553 pm_runtime_disable(dev);
1554 pm_runtime_set_suspended(dev);
1555 fimc_lite_unregister_capture_subdev(fimc);
1556 vb2_dma_contig_cleanup_ctx(fimc->alloc_ctx);
1557 fimc_lite_clk_put(fimc);
1558
1559 dev_info(dev, "Driver unloaded\n");
1560 return 0;
1561}
1562
1563static struct flite_variant fimc_lite0_variant_exynos4 = {
1564 .max_width = 8192,
1565 .max_height = 8192,
1566 .out_width_align = 8,
1567 .win_hor_offs_align = 2,
1568 .out_hor_offs_align = 8,
1569};
1570
1571/* EXYNOS4212, EXYNOS4412 */
1572static struct flite_drvdata fimc_lite_drvdata_exynos4 = {
1573 .variant = {
1574 [0] = &fimc_lite0_variant_exynos4,
1575 [1] = &fimc_lite0_variant_exynos4,
1576 },
1577};
1578
1579static struct platform_device_id fimc_lite_driver_ids[] = {
1580 {
1581 .name = "exynos-fimc-lite",
1582 .driver_data = (unsigned long)&fimc_lite_drvdata_exynos4,
1583 },
1584 { /* sentinel */ },
1585};
1586MODULE_DEVICE_TABLE(platform, fimc_lite_driver_ids);
1587
1588static const struct dev_pm_ops fimc_lite_pm_ops = {
1589 SET_SYSTEM_SLEEP_PM_OPS(fimc_lite_suspend, fimc_lite_resume)
1590 SET_RUNTIME_PM_OPS(fimc_lite_runtime_suspend, fimc_lite_runtime_resume,
1591 NULL)
1592};
1593
1594static struct platform_driver fimc_lite_driver = {
1595 .probe = fimc_lite_probe,
1596 .remove = __devexit_p(fimc_lite_remove),
1597 .id_table = fimc_lite_driver_ids,
1598 .driver = {
1599 .name = FIMC_LITE_DRV_NAME,
1600 .owner = THIS_MODULE,
1601 .pm = &fimc_lite_pm_ops,
1602 }
1603};
1604module_platform_driver(fimc_lite_driver);
1605MODULE_LICENSE("GPL");
1606MODULE_ALIAS("platform:" FIMC_LITE_DRV_NAME);
diff --git a/drivers/media/video/s5p-fimc/fimc-lite.h b/drivers/media/video/s5p-fimc/fimc-lite.h
deleted file mode 100644
index 44424eee81d8..000000000000
--- a/drivers/media/video/s5p-fimc/fimc-lite.h
+++ /dev/null
@@ -1,213 +0,0 @@
1/*
2 * Copyright (C) 2012 Samsung Electronics Co., Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#ifndef FIMC_LITE_H_
10#define FIMC_LITE_H_
11
12#include <asm/sizes.h>
13#include <linux/io.h>
14#include <linux/irqreturn.h>
15#include <linux/platform_device.h>
16#include <linux/sched.h>
17#include <linux/spinlock.h>
18#include <linux/types.h>
19#include <linux/videodev2.h>
20
21#include <media/media-entity.h>
22#include <media/videobuf2-core.h>
23#include <media/v4l2-device.h>
24#include <media/v4l2-mediabus.h>
25#include <media/s5p_fimc.h>
26
27#include "fimc-core.h"
28
29#define FIMC_LITE_DRV_NAME "exynos-fimc-lite"
30#define FLITE_CLK_NAME "flite"
31#define FIMC_LITE_MAX_DEVS 2
32#define FLITE_REQ_BUFS_MIN 2
33
34/* Bit index definitions for struct fimc_lite::state */
35enum {
36 ST_FLITE_LPM,
37 ST_FLITE_PENDING,
38 ST_FLITE_RUN,
39 ST_FLITE_STREAM,
40 ST_FLITE_SUSPENDED,
41 ST_FLITE_OFF,
42 ST_FLITE_IN_USE,
43 ST_FLITE_CONFIG,
44 ST_SENSOR_STREAM,
45};
46
47#define FLITE_SD_PAD_SINK 0
48#define FLITE_SD_PAD_SOURCE 1
49#define FLITE_SD_PADS_NUM 2
50
51struct flite_variant {
52 unsigned short max_width;
53 unsigned short max_height;
54 unsigned short out_width_align;
55 unsigned short win_hor_offs_align;
56 unsigned short out_hor_offs_align;
57};
58
59struct flite_drvdata {
60 struct flite_variant *variant[FIMC_LITE_MAX_DEVS];
61};
62
63#define fimc_lite_get_drvdata(_pdev) \
64 ((struct flite_drvdata *) platform_get_device_id(_pdev)->driver_data)
65
66struct fimc_lite_events {
67 unsigned int data_overflow;
68};
69
70#define FLITE_MAX_PLANES 1
71
72/**
73 * struct flite_frame - source/target frame properties
74 * @f_width: full pixel width
75 * @f_height: full pixel height
76 * @rect: crop/composition rectangle
77 */
78struct flite_frame {
79 u16 f_width;
80 u16 f_height;
81 struct v4l2_rect rect;
82};
83
84/**
85 * struct flite_buffer - video buffer structure
86 * @vb: vb2 buffer
87 * @list: list head for the buffers queue
88 * @paddr: precalculated physical address
89 */
90struct flite_buffer {
91 struct vb2_buffer vb;
92 struct list_head list;
93 dma_addr_t paddr;
94};
95
96/**
97 * struct fimc_lite - fimc lite structure
98 * @pdev: pointer to FIMC-LITE platform device
99 * @variant: variant information for this IP
100 * @v4l2_dev: pointer to top the level v4l2_device
101 * @vfd: video device node
102 * @fh: v4l2 file handle
103 * @alloc_ctx: videobuf2 memory allocator context
104 * @subdev: FIMC-LITE subdev
105 * @vd_pad: media (sink) pad for the capture video node
106 * @subdev_pads: the subdev media pads
107 * @ctrl_handler: v4l2 control handler
108 * @test_pattern: test pattern controls
109 * @index: FIMC-LITE platform device index
110 * @pipeline: video capture pipeline data structure
111 * @slock: spinlock protecting this data structure and the hw registers
112 * @lock: mutex serializing video device and the subdev operations
113 * @clock: FIMC-LITE gate clock
114 * @regs: memory mapped io registers
115 * @irq_queue: interrupt handler waitqueue
116 * @fmt: pointer to color format description structure
117 * @payload: image size in bytes (w x h x bpp)
118 * @inp_frame: camera input frame structure
119 * @out_frame: DMA output frame structure
120 * @out_path: output data path (DMA or FIFO)
121 * @source_subdev_grp_id: source subdev group id
122 * @state: driver state flags
123 * @pending_buf_q: pending buffers queue head
124 * @active_buf_q: the queue head of buffers scheduled in hardware
125 * @vb_queue: vb2 buffers queue
126 * @active_buf_count: number of video buffers scheduled in hardware
127 * @frame_count: the captured frames counter
128 * @reqbufs_count: the number of buffers requested with REQBUFS ioctl
129 * @ref_count: driver's private reference counter
130 */
131struct fimc_lite {
132 struct platform_device *pdev;
133 struct flite_variant *variant;
134 struct v4l2_device *v4l2_dev;
135 struct video_device *vfd;
136 struct v4l2_fh fh;
137 struct vb2_alloc_ctx *alloc_ctx;
138 struct v4l2_subdev subdev;
139 struct media_pad vd_pad;
140 struct media_pad subdev_pads[FLITE_SD_PADS_NUM];
141 struct v4l2_ctrl_handler ctrl_handler;
142 struct v4l2_ctrl *test_pattern;
143 u32 index;
144 struct fimc_pipeline pipeline;
145
146 struct mutex lock;
147 spinlock_t slock;
148
149 struct clk *clock;
150 void __iomem *regs;
151 wait_queue_head_t irq_queue;
152
153 const struct fimc_fmt *fmt;
154 unsigned long payload[FLITE_MAX_PLANES];
155 struct flite_frame inp_frame;
156 struct flite_frame out_frame;
157 enum fimc_datapath out_path;
158 unsigned int source_subdev_grp_id;
159
160 unsigned long state;
161 struct list_head pending_buf_q;
162 struct list_head active_buf_q;
163 struct vb2_queue vb_queue;
164 unsigned int frame_count;
165 unsigned int reqbufs_count;
166 int ref_count;
167
168 struct fimc_lite_events events;
169};
170
171static inline bool fimc_lite_active(struct fimc_lite *fimc)
172{
173 unsigned long flags;
174 bool ret;
175
176 spin_lock_irqsave(&fimc->slock, flags);
177 ret = fimc->state & (1 << ST_FLITE_RUN) ||
178 fimc->state & (1 << ST_FLITE_PENDING);
179 spin_unlock_irqrestore(&fimc->slock, flags);
180 return ret;
181}
182
183static inline void fimc_lite_active_queue_add(struct fimc_lite *dev,
184 struct flite_buffer *buf)
185{
186 list_add_tail(&buf->list, &dev->active_buf_q);
187}
188
189static inline struct flite_buffer *fimc_lite_active_queue_pop(
190 struct fimc_lite *dev)
191{
192 struct flite_buffer *buf = list_entry(dev->active_buf_q.next,
193 struct flite_buffer, list);
194 list_del(&buf->list);
195 return buf;
196}
197
198static inline void fimc_lite_pending_queue_add(struct fimc_lite *dev,
199 struct flite_buffer *buf)
200{
201 list_add_tail(&buf->list, &dev->pending_buf_q);
202}
203
204static inline struct flite_buffer *fimc_lite_pending_queue_pop(
205 struct fimc_lite *dev)
206{
207 struct flite_buffer *buf = list_entry(dev->pending_buf_q.next,
208 struct flite_buffer, list);
209 list_del(&buf->list);
210 return buf;
211}
212
213#endif /* FIMC_LITE_H_ */
diff --git a/drivers/media/video/s5p-fimc/fimc-m2m.c b/drivers/media/video/s5p-fimc/fimc-m2m.c
deleted file mode 100644
index c587011d80ef..000000000000
--- a/drivers/media/video/s5p-fimc/fimc-m2m.c
+++ /dev/null
@@ -1,854 +0,0 @@
1/*
2 * Samsung S5P/EXYNOS4 SoC series FIMC (video postprocessor) driver
3 *
4 * Copyright (C) 2012 Samsung Electronics Co., Ltd.
5 * Sylwester Nawrocki, <s.nawrocki@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published
9 * by the Free Software Foundation, either version 2 of the License,
10 * or (at your option) any later version.
11 */
12
13#include <linux/module.h>
14#include <linux/kernel.h>
15#include <linux/types.h>
16#include <linux/errno.h>
17#include <linux/bug.h>
18#include <linux/interrupt.h>
19#include <linux/device.h>
20#include <linux/platform_device.h>
21#include <linux/pm_runtime.h>
22#include <linux/list.h>
23#include <linux/io.h>
24#include <linux/slab.h>
25#include <linux/clk.h>
26#include <media/v4l2-ioctl.h>
27#include <media/videobuf2-core.h>
28#include <media/videobuf2-dma-contig.h>
29
30#include "fimc-core.h"
31#include "fimc-reg.h"
32#include "fimc-mdevice.h"
33
34
35static unsigned int get_m2m_fmt_flags(unsigned int stream_type)
36{
37 if (stream_type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
38 return FMT_FLAGS_M2M_IN;
39 else
40 return FMT_FLAGS_M2M_OUT;
41}
42
43void fimc_m2m_job_finish(struct fimc_ctx *ctx, int vb_state)
44{
45 struct vb2_buffer *src_vb, *dst_vb;
46
47 if (!ctx || !ctx->m2m_ctx)
48 return;
49
50 src_vb = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
51 dst_vb = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
52
53 if (src_vb && dst_vb) {
54 v4l2_m2m_buf_done(src_vb, vb_state);
55 v4l2_m2m_buf_done(dst_vb, vb_state);
56 v4l2_m2m_job_finish(ctx->fimc_dev->m2m.m2m_dev,
57 ctx->m2m_ctx);
58 }
59}
60
61/* Complete the transaction which has been scheduled for execution. */
62static int fimc_m2m_shutdown(struct fimc_ctx *ctx)
63{
64 struct fimc_dev *fimc = ctx->fimc_dev;
65 int ret;
66
67 if (!fimc_m2m_pending(fimc))
68 return 0;
69
70 fimc_ctx_state_set(FIMC_CTX_SHUT, ctx);
71
72 ret = wait_event_timeout(fimc->irq_queue,
73 !fimc_ctx_state_is_set(FIMC_CTX_SHUT, ctx),
74 FIMC_SHUTDOWN_TIMEOUT);
75
76 return ret == 0 ? -ETIMEDOUT : ret;
77}
78
79static int start_streaming(struct vb2_queue *q, unsigned int count)
80{
81 struct fimc_ctx *ctx = q->drv_priv;
82 int ret;
83
84 ret = pm_runtime_get_sync(&ctx->fimc_dev->pdev->dev);
85 return ret > 0 ? 0 : ret;
86}
87
88static int stop_streaming(struct vb2_queue *q)
89{
90 struct fimc_ctx *ctx = q->drv_priv;
91 int ret;
92
93 ret = fimc_m2m_shutdown(ctx);
94 if (ret == -ETIMEDOUT)
95 fimc_m2m_job_finish(ctx, VB2_BUF_STATE_ERROR);
96
97 pm_runtime_put(&ctx->fimc_dev->pdev->dev);
98 return 0;
99}
100
101static void fimc_device_run(void *priv)
102{
103 struct vb2_buffer *vb = NULL;
104 struct fimc_ctx *ctx = priv;
105 struct fimc_frame *sf, *df;
106 struct fimc_dev *fimc;
107 unsigned long flags;
108 u32 ret;
109
110 if (WARN(!ctx, "Null context\n"))
111 return;
112
113 fimc = ctx->fimc_dev;
114 spin_lock_irqsave(&fimc->slock, flags);
115
116 set_bit(ST_M2M_PEND, &fimc->state);
117 sf = &ctx->s_frame;
118 df = &ctx->d_frame;
119
120 if (ctx->state & FIMC_PARAMS) {
121 /* Prepare the DMA offsets for scaler */
122 fimc_prepare_dma_offset(ctx, sf);
123 fimc_prepare_dma_offset(ctx, df);
124 }
125
126 vb = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
127 ret = fimc_prepare_addr(ctx, vb, sf, &sf->paddr);
128 if (ret)
129 goto dma_unlock;
130
131 vb = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
132 ret = fimc_prepare_addr(ctx, vb, df, &df->paddr);
133 if (ret)
134 goto dma_unlock;
135
136 /* Reconfigure hardware if the context has changed. */
137 if (fimc->m2m.ctx != ctx) {
138 ctx->state |= FIMC_PARAMS;
139 fimc->m2m.ctx = ctx;
140 }
141
142 if (ctx->state & FIMC_PARAMS) {
143 fimc_set_yuv_order(ctx);
144 fimc_hw_set_input_path(ctx);
145 fimc_hw_set_in_dma(ctx);
146 ret = fimc_set_scaler_info(ctx);
147 if (ret)
148 goto dma_unlock;
149 fimc_hw_set_prescaler(ctx);
150 fimc_hw_set_mainscaler(ctx);
151 fimc_hw_set_target_format(ctx);
152 fimc_hw_set_rotation(ctx);
153 fimc_hw_set_effect(ctx);
154 fimc_hw_set_out_dma(ctx);
155 if (fimc->variant->has_alpha)
156 fimc_hw_set_rgb_alpha(ctx);
157 fimc_hw_set_output_path(ctx);
158 }
159 fimc_hw_set_input_addr(fimc, &sf->paddr);
160 fimc_hw_set_output_addr(fimc, &df->paddr, -1);
161
162 fimc_activate_capture(ctx);
163 ctx->state &= (FIMC_CTX_M2M | FIMC_CTX_CAP |
164 FIMC_SRC_FMT | FIMC_DST_FMT);
165 fimc_hw_activate_input_dma(fimc, true);
166
167dma_unlock:
168 spin_unlock_irqrestore(&fimc->slock, flags);
169}
170
171static void fimc_job_abort(void *priv)
172{
173 fimc_m2m_shutdown(priv);
174}
175
176static int fimc_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
177 unsigned int *num_buffers, unsigned int *num_planes,
178 unsigned int sizes[], void *allocators[])
179{
180 struct fimc_ctx *ctx = vb2_get_drv_priv(vq);
181 struct fimc_frame *f;
182 int i;
183
184 f = ctx_get_frame(ctx, vq->type);
185 if (IS_ERR(f))
186 return PTR_ERR(f);
187 /*
188 * Return number of non-contigous planes (plane buffers)
189 * depending on the configured color format.
190 */
191 if (!f->fmt)
192 return -EINVAL;
193
194 *num_planes = f->fmt->memplanes;
195 for (i = 0; i < f->fmt->memplanes; i++) {
196 sizes[i] = (f->f_width * f->f_height * f->fmt->depth[i]) / 8;
197 allocators[i] = ctx->fimc_dev->alloc_ctx;
198 }
199 return 0;
200}
201
202static int fimc_buf_prepare(struct vb2_buffer *vb)
203{
204 struct fimc_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
205 struct fimc_frame *frame;
206 int i;
207
208 frame = ctx_get_frame(ctx, vb->vb2_queue->type);
209 if (IS_ERR(frame))
210 return PTR_ERR(frame);
211
212 for (i = 0; i < frame->fmt->memplanes; i++)
213 vb2_set_plane_payload(vb, i, frame->payload[i]);
214
215 return 0;
216}
217
218static void fimc_buf_queue(struct vb2_buffer *vb)
219{
220 struct fimc_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
221
222 dbg("ctx: %p, ctx->state: 0x%x", ctx, ctx->state);
223
224 if (ctx->m2m_ctx)
225 v4l2_m2m_buf_queue(ctx->m2m_ctx, vb);
226}
227
228static void fimc_lock(struct vb2_queue *vq)
229{
230 struct fimc_ctx *ctx = vb2_get_drv_priv(vq);
231 mutex_lock(&ctx->fimc_dev->lock);
232}
233
234static void fimc_unlock(struct vb2_queue *vq)
235{
236 struct fimc_ctx *ctx = vb2_get_drv_priv(vq);
237 mutex_unlock(&ctx->fimc_dev->lock);
238}
239
240static struct vb2_ops fimc_qops = {
241 .queue_setup = fimc_queue_setup,
242 .buf_prepare = fimc_buf_prepare,
243 .buf_queue = fimc_buf_queue,
244 .wait_prepare = fimc_unlock,
245 .wait_finish = fimc_lock,
246 .stop_streaming = stop_streaming,
247 .start_streaming = start_streaming,
248};
249
250/*
251 * V4L2 ioctl handlers
252 */
253static int fimc_m2m_querycap(struct file *file, void *fh,
254 struct v4l2_capability *cap)
255{
256 struct fimc_ctx *ctx = fh_to_ctx(fh);
257 struct fimc_dev *fimc = ctx->fimc_dev;
258
259 strncpy(cap->driver, fimc->pdev->name, sizeof(cap->driver) - 1);
260 strncpy(cap->card, fimc->pdev->name, sizeof(cap->card) - 1);
261 cap->bus_info[0] = 0;
262 /*
263 * This is only a mem-to-mem video device. The capture and output
264 * device capability flags are left only for backward compatibility
265 * and are scheduled for removal.
266 */
267 cap->capabilities = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M_MPLANE |
268 V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_VIDEO_OUTPUT_MPLANE;
269
270 return 0;
271}
272
273static int fimc_m2m_enum_fmt_mplane(struct file *file, void *priv,
274 struct v4l2_fmtdesc *f)
275{
276 struct fimc_fmt *fmt;
277
278 fmt = fimc_find_format(NULL, NULL, get_m2m_fmt_flags(f->type),
279 f->index);
280 if (!fmt)
281 return -EINVAL;
282
283 strncpy(f->description, fmt->name, sizeof(f->description) - 1);
284 f->pixelformat = fmt->fourcc;
285 return 0;
286}
287
288static int fimc_m2m_g_fmt_mplane(struct file *file, void *fh,
289 struct v4l2_format *f)
290{
291 struct fimc_ctx *ctx = fh_to_ctx(fh);
292 struct fimc_frame *frame = ctx_get_frame(ctx, f->type);
293
294 if (IS_ERR(frame))
295 return PTR_ERR(frame);
296
297 return fimc_fill_format(frame, f);
298}
299
300static int fimc_try_fmt_mplane(struct fimc_ctx *ctx, struct v4l2_format *f)
301{
302 struct fimc_dev *fimc = ctx->fimc_dev;
303 struct fimc_variant *variant = fimc->variant;
304 struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
305 struct fimc_fmt *fmt;
306 u32 max_w, mod_x, mod_y;
307
308 if (!IS_M2M(f->type))
309 return -EINVAL;
310
311 dbg("w: %d, h: %d", pix->width, pix->height);
312
313 fmt = fimc_find_format(&pix->pixelformat, NULL,
314 get_m2m_fmt_flags(f->type), 0);
315 if (WARN(fmt == NULL, "Pixel format lookup failed"))
316 return -EINVAL;
317
318 if (pix->field == V4L2_FIELD_ANY)
319 pix->field = V4L2_FIELD_NONE;
320 else if (pix->field != V4L2_FIELD_NONE)
321 return -EINVAL;
322
323 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
324 max_w = variant->pix_limit->scaler_dis_w;
325 mod_x = ffs(variant->min_inp_pixsize) - 1;
326 } else {
327 max_w = variant->pix_limit->out_rot_dis_w;
328 mod_x = ffs(variant->min_out_pixsize) - 1;
329 }
330
331 if (tiled_fmt(fmt)) {
332 mod_x = 6; /* 64 x 32 pixels tile */
333 mod_y = 5;
334 } else {
335 if (variant->min_vsize_align == 1)
336 mod_y = fimc_fmt_is_rgb(fmt->color) ? 0 : 1;
337 else
338 mod_y = ffs(variant->min_vsize_align) - 1;
339 }
340
341 v4l_bound_align_image(&pix->width, 16, max_w, mod_x,
342 &pix->height, 8, variant->pix_limit->scaler_dis_w, mod_y, 0);
343
344 fimc_adjust_mplane_format(fmt, pix->width, pix->height, &f->fmt.pix_mp);
345 return 0;
346}
347
348static int fimc_m2m_try_fmt_mplane(struct file *file, void *fh,
349 struct v4l2_format *f)
350{
351 struct fimc_ctx *ctx = fh_to_ctx(fh);
352
353 return fimc_try_fmt_mplane(ctx, f);
354}
355
356static int fimc_m2m_s_fmt_mplane(struct file *file, void *fh,
357 struct v4l2_format *f)
358{
359 struct fimc_ctx *ctx = fh_to_ctx(fh);
360 struct fimc_dev *fimc = ctx->fimc_dev;
361 struct vb2_queue *vq;
362 struct fimc_frame *frame;
363 struct v4l2_pix_format_mplane *pix;
364 int i, ret = 0;
365
366 ret = fimc_try_fmt_mplane(ctx, f);
367 if (ret)
368 return ret;
369
370 vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
371
372 if (vb2_is_busy(vq)) {
373 v4l2_err(fimc->m2m.vfd, "queue (%d) busy\n", f->type);
374 return -EBUSY;
375 }
376
377 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
378 frame = &ctx->s_frame;
379 else
380 frame = &ctx->d_frame;
381
382 pix = &f->fmt.pix_mp;
383 frame->fmt = fimc_find_format(&pix->pixelformat, NULL,
384 get_m2m_fmt_flags(f->type), 0);
385 if (!frame->fmt)
386 return -EINVAL;
387
388 /* Update RGB Alpha control state and value range */
389 fimc_alpha_ctrl_update(ctx);
390
391 for (i = 0; i < frame->fmt->colplanes; i++) {
392 frame->payload[i] =
393 (pix->width * pix->height * frame->fmt->depth[i]) / 8;
394 }
395
396 fimc_fill_frame(frame, f);
397
398 ctx->scaler.enabled = 1;
399
400 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
401 fimc_ctx_state_set(FIMC_PARAMS | FIMC_DST_FMT, ctx);
402 else
403 fimc_ctx_state_set(FIMC_PARAMS | FIMC_SRC_FMT, ctx);
404
405 dbg("f_w: %d, f_h: %d", frame->f_width, frame->f_height);
406
407 return 0;
408}
409
410static int fimc_m2m_reqbufs(struct file *file, void *fh,
411 struct v4l2_requestbuffers *reqbufs)
412{
413 struct fimc_ctx *ctx = fh_to_ctx(fh);
414
415 return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs);
416}
417
418static int fimc_m2m_querybuf(struct file *file, void *fh,
419 struct v4l2_buffer *buf)
420{
421 struct fimc_ctx *ctx = fh_to_ctx(fh);
422
423 return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf);
424}
425
426static int fimc_m2m_qbuf(struct file *file, void *fh,
427 struct v4l2_buffer *buf)
428{
429 struct fimc_ctx *ctx = fh_to_ctx(fh);
430
431 return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
432}
433
434static int fimc_m2m_dqbuf(struct file *file, void *fh,
435 struct v4l2_buffer *buf)
436{
437 struct fimc_ctx *ctx = fh_to_ctx(fh);
438
439 return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
440}
441
442static int fimc_m2m_streamon(struct file *file, void *fh,
443 enum v4l2_buf_type type)
444{
445 struct fimc_ctx *ctx = fh_to_ctx(fh);
446
447 /* The source and target color format need to be set */
448 if (V4L2_TYPE_IS_OUTPUT(type)) {
449 if (!fimc_ctx_state_is_set(FIMC_SRC_FMT, ctx))
450 return -EINVAL;
451 } else if (!fimc_ctx_state_is_set(FIMC_DST_FMT, ctx)) {
452 return -EINVAL;
453 }
454
455 return v4l2_m2m_streamon(file, ctx->m2m_ctx, type);
456}
457
458static int fimc_m2m_streamoff(struct file *file, void *fh,
459 enum v4l2_buf_type type)
460{
461 struct fimc_ctx *ctx = fh_to_ctx(fh);
462
463 return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type);
464}
465
466static int fimc_m2m_cropcap(struct file *file, void *fh,
467 struct v4l2_cropcap *cr)
468{
469 struct fimc_ctx *ctx = fh_to_ctx(fh);
470 struct fimc_frame *frame;
471
472 frame = ctx_get_frame(ctx, cr->type);
473 if (IS_ERR(frame))
474 return PTR_ERR(frame);
475
476 cr->bounds.left = 0;
477 cr->bounds.top = 0;
478 cr->bounds.width = frame->o_width;
479 cr->bounds.height = frame->o_height;
480 cr->defrect = cr->bounds;
481
482 return 0;
483}
484
485static int fimc_m2m_g_crop(struct file *file, void *fh, struct v4l2_crop *cr)
486{
487 struct fimc_ctx *ctx = fh_to_ctx(fh);
488 struct fimc_frame *frame;
489
490 frame = ctx_get_frame(ctx, cr->type);
491 if (IS_ERR(frame))
492 return PTR_ERR(frame);
493
494 cr->c.left = frame->offs_h;
495 cr->c.top = frame->offs_v;
496 cr->c.width = frame->width;
497 cr->c.height = frame->height;
498
499 return 0;
500}
501
502static int fimc_m2m_try_crop(struct fimc_ctx *ctx, struct v4l2_crop *cr)
503{
504 struct fimc_dev *fimc = ctx->fimc_dev;
505 struct fimc_frame *f;
506 u32 min_size, halign, depth = 0;
507 int i;
508
509 if (cr->c.top < 0 || cr->c.left < 0) {
510 v4l2_err(fimc->m2m.vfd,
511 "doesn't support negative values for top & left\n");
512 return -EINVAL;
513 }
514 if (cr->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
515 f = &ctx->d_frame;
516 else if (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
517 f = &ctx->s_frame;
518 else
519 return -EINVAL;
520
521 min_size = (f == &ctx->s_frame) ?
522 fimc->variant->min_inp_pixsize : fimc->variant->min_out_pixsize;
523
524 /* Get pixel alignment constraints. */
525 if (fimc->variant->min_vsize_align == 1)
526 halign = fimc_fmt_is_rgb(f->fmt->color) ? 0 : 1;
527 else
528 halign = ffs(fimc->variant->min_vsize_align) - 1;
529
530 for (i = 0; i < f->fmt->colplanes; i++)
531 depth += f->fmt->depth[i];
532
533 v4l_bound_align_image(&cr->c.width, min_size, f->o_width,
534 ffs(min_size) - 1,
535 &cr->c.height, min_size, f->o_height,
536 halign, 64/(ALIGN(depth, 8)));
537
538 /* adjust left/top if cropping rectangle is out of bounds */
539 if (cr->c.left + cr->c.width > f->o_width)
540 cr->c.left = f->o_width - cr->c.width;
541 if (cr->c.top + cr->c.height > f->o_height)
542 cr->c.top = f->o_height - cr->c.height;
543
544 cr->c.left = round_down(cr->c.left, min_size);
545 cr->c.top = round_down(cr->c.top, fimc->variant->hor_offs_align);
546
547 dbg("l:%d, t:%d, w:%d, h:%d, f_w: %d, f_h: %d",
548 cr->c.left, cr->c.top, cr->c.width, cr->c.height,
549 f->f_width, f->f_height);
550
551 return 0;
552}
553
554static int fimc_m2m_s_crop(struct file *file, void *fh, struct v4l2_crop *cr)
555{
556 struct fimc_ctx *ctx = fh_to_ctx(fh);
557 struct fimc_dev *fimc = ctx->fimc_dev;
558 struct fimc_frame *f;
559 int ret;
560
561 ret = fimc_m2m_try_crop(ctx, cr);
562 if (ret)
563 return ret;
564
565 f = (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) ?
566 &ctx->s_frame : &ctx->d_frame;
567
568 /* Check to see if scaling ratio is within supported range */
569 if (fimc_ctx_state_is_set(FIMC_DST_FMT | FIMC_SRC_FMT, ctx)) {
570 if (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
571 ret = fimc_check_scaler_ratio(ctx, cr->c.width,
572 cr->c.height, ctx->d_frame.width,
573 ctx->d_frame.height, ctx->rotation);
574 } else {
575 ret = fimc_check_scaler_ratio(ctx, ctx->s_frame.width,
576 ctx->s_frame.height, cr->c.width,
577 cr->c.height, ctx->rotation);
578 }
579 if (ret) {
580 v4l2_err(fimc->m2m.vfd, "Out of scaler range\n");
581 return -EINVAL;
582 }
583 }
584
585 f->offs_h = cr->c.left;
586 f->offs_v = cr->c.top;
587 f->width = cr->c.width;
588 f->height = cr->c.height;
589
590 fimc_ctx_state_set(FIMC_PARAMS, ctx);
591
592 return 0;
593}
594
595static const struct v4l2_ioctl_ops fimc_m2m_ioctl_ops = {
596 .vidioc_querycap = fimc_m2m_querycap,
597 .vidioc_enum_fmt_vid_cap_mplane = fimc_m2m_enum_fmt_mplane,
598 .vidioc_enum_fmt_vid_out_mplane = fimc_m2m_enum_fmt_mplane,
599 .vidioc_g_fmt_vid_cap_mplane = fimc_m2m_g_fmt_mplane,
600 .vidioc_g_fmt_vid_out_mplane = fimc_m2m_g_fmt_mplane,
601 .vidioc_try_fmt_vid_cap_mplane = fimc_m2m_try_fmt_mplane,
602 .vidioc_try_fmt_vid_out_mplane = fimc_m2m_try_fmt_mplane,
603 .vidioc_s_fmt_vid_cap_mplane = fimc_m2m_s_fmt_mplane,
604 .vidioc_s_fmt_vid_out_mplane = fimc_m2m_s_fmt_mplane,
605 .vidioc_reqbufs = fimc_m2m_reqbufs,
606 .vidioc_querybuf = fimc_m2m_querybuf,
607 .vidioc_qbuf = fimc_m2m_qbuf,
608 .vidioc_dqbuf = fimc_m2m_dqbuf,
609 .vidioc_streamon = fimc_m2m_streamon,
610 .vidioc_streamoff = fimc_m2m_streamoff,
611 .vidioc_g_crop = fimc_m2m_g_crop,
612 .vidioc_s_crop = fimc_m2m_s_crop,
613 .vidioc_cropcap = fimc_m2m_cropcap
614
615};
616
617static int queue_init(void *priv, struct vb2_queue *src_vq,
618 struct vb2_queue *dst_vq)
619{
620 struct fimc_ctx *ctx = priv;
621 int ret;
622
623 memset(src_vq, 0, sizeof(*src_vq));
624 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
625 src_vq->io_modes = VB2_MMAP | VB2_USERPTR;
626 src_vq->drv_priv = ctx;
627 src_vq->ops = &fimc_qops;
628 src_vq->mem_ops = &vb2_dma_contig_memops;
629 src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
630
631 ret = vb2_queue_init(src_vq);
632 if (ret)
633 return ret;
634
635 memset(dst_vq, 0, sizeof(*dst_vq));
636 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
637 dst_vq->io_modes = VB2_MMAP | VB2_USERPTR;
638 dst_vq->drv_priv = ctx;
639 dst_vq->ops = &fimc_qops;
640 dst_vq->mem_ops = &vb2_dma_contig_memops;
641 dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
642
643 return vb2_queue_init(dst_vq);
644}
645
646static int fimc_m2m_open(struct file *file)
647{
648 struct fimc_dev *fimc = video_drvdata(file);
649 struct fimc_ctx *ctx;
650 int ret = -EBUSY;
651
652 dbg("pid: %d, state: 0x%lx, refcnt: %d",
653 task_pid_nr(current), fimc->state, fimc->vid_cap.refcnt);
654
655 if (mutex_lock_interruptible(&fimc->lock))
656 return -ERESTARTSYS;
657 /*
658 * Return if the corresponding video capture node
659 * is already opened.
660 */
661 if (fimc->vid_cap.refcnt > 0)
662 goto unlock;
663
664 ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
665 if (!ctx) {
666 ret = -ENOMEM;
667 goto unlock;
668 }
669 v4l2_fh_init(&ctx->fh, fimc->m2m.vfd);
670 ctx->fimc_dev = fimc;
671
672 /* Default color format */
673 ctx->s_frame.fmt = fimc_get_format(0);
674 ctx->d_frame.fmt = fimc_get_format(0);
675
676 ret = fimc_ctrls_create(ctx);
677 if (ret)
678 goto error_fh;
679
680 /* Use separate control handler per file handle */
681 ctx->fh.ctrl_handler = &ctx->ctrls.handler;
682 file->private_data = &ctx->fh;
683 v4l2_fh_add(&ctx->fh);
684
685 /* Setup the device context for memory-to-memory mode */
686 ctx->state = FIMC_CTX_M2M;
687 ctx->flags = 0;
688 ctx->in_path = FIMC_IO_DMA;
689 ctx->out_path = FIMC_IO_DMA;
690
691 ctx->m2m_ctx = v4l2_m2m_ctx_init(fimc->m2m.m2m_dev, ctx, queue_init);
692 if (IS_ERR(ctx->m2m_ctx)) {
693 ret = PTR_ERR(ctx->m2m_ctx);
694 goto error_c;
695 }
696
697 if (fimc->m2m.refcnt++ == 0)
698 set_bit(ST_M2M_RUN, &fimc->state);
699
700 mutex_unlock(&fimc->lock);
701 return 0;
702
703error_c:
704 fimc_ctrls_delete(ctx);
705error_fh:
706 v4l2_fh_del(&ctx->fh);
707 v4l2_fh_exit(&ctx->fh);
708 kfree(ctx);
709unlock:
710 mutex_unlock(&fimc->lock);
711 return ret;
712}
713
714static int fimc_m2m_release(struct file *file)
715{
716 struct fimc_ctx *ctx = fh_to_ctx(file->private_data);
717 struct fimc_dev *fimc = ctx->fimc_dev;
718
719 dbg("pid: %d, state: 0x%lx, refcnt= %d",
720 task_pid_nr(current), fimc->state, fimc->m2m.refcnt);
721
722 if (mutex_lock_interruptible(&fimc->lock))
723 return -ERESTARTSYS;
724
725 v4l2_m2m_ctx_release(ctx->m2m_ctx);
726 fimc_ctrls_delete(ctx);
727 v4l2_fh_del(&ctx->fh);
728 v4l2_fh_exit(&ctx->fh);
729
730 if (--fimc->m2m.refcnt <= 0)
731 clear_bit(ST_M2M_RUN, &fimc->state);
732 kfree(ctx);
733
734 mutex_unlock(&fimc->lock);
735 return 0;
736}
737
738static unsigned int fimc_m2m_poll(struct file *file,
739 struct poll_table_struct *wait)
740{
741 struct fimc_ctx *ctx = fh_to_ctx(file->private_data);
742 struct fimc_dev *fimc = ctx->fimc_dev;
743 int ret;
744
745 if (mutex_lock_interruptible(&fimc->lock))
746 return -ERESTARTSYS;
747
748 ret = v4l2_m2m_poll(file, ctx->m2m_ctx, wait);
749 mutex_unlock(&fimc->lock);
750
751 return ret;
752}
753
754
755static int fimc_m2m_mmap(struct file *file, struct vm_area_struct *vma)
756{
757 struct fimc_ctx *ctx = fh_to_ctx(file->private_data);
758 struct fimc_dev *fimc = ctx->fimc_dev;
759 int ret;
760
761 if (mutex_lock_interruptible(&fimc->lock))
762 return -ERESTARTSYS;
763
764 ret = v4l2_m2m_mmap(file, ctx->m2m_ctx, vma);
765 mutex_unlock(&fimc->lock);
766
767 return ret;
768}
769
770static const struct v4l2_file_operations fimc_m2m_fops = {
771 .owner = THIS_MODULE,
772 .open = fimc_m2m_open,
773 .release = fimc_m2m_release,
774 .poll = fimc_m2m_poll,
775 .unlocked_ioctl = video_ioctl2,
776 .mmap = fimc_m2m_mmap,
777};
778
779static struct v4l2_m2m_ops m2m_ops = {
780 .device_run = fimc_device_run,
781 .job_abort = fimc_job_abort,
782};
783
784int fimc_register_m2m_device(struct fimc_dev *fimc,
785 struct v4l2_device *v4l2_dev)
786{
787 struct video_device *vfd;
788 struct platform_device *pdev;
789 int ret = 0;
790
791 if (!fimc)
792 return -ENODEV;
793
794 pdev = fimc->pdev;
795 fimc->v4l2_dev = v4l2_dev;
796
797 vfd = video_device_alloc();
798 if (!vfd) {
799 v4l2_err(v4l2_dev, "Failed to allocate video device\n");
800 return -ENOMEM;
801 }
802
803 vfd->fops = &fimc_m2m_fops;
804 vfd->ioctl_ops = &fimc_m2m_ioctl_ops;
805 vfd->v4l2_dev = v4l2_dev;
806 vfd->minor = -1;
807 vfd->release = video_device_release;
808 vfd->lock = &fimc->lock;
809
810 snprintf(vfd->name, sizeof(vfd->name), "fimc.%d.m2m", fimc->id);
811 video_set_drvdata(vfd, fimc);
812
813 fimc->m2m.vfd = vfd;
814 fimc->m2m.m2m_dev = v4l2_m2m_init(&m2m_ops);
815 if (IS_ERR(fimc->m2m.m2m_dev)) {
816 v4l2_err(v4l2_dev, "failed to initialize v4l2-m2m device\n");
817 ret = PTR_ERR(fimc->m2m.m2m_dev);
818 goto err_init;
819 }
820
821 ret = media_entity_init(&vfd->entity, 0, NULL, 0);
822 if (ret)
823 goto err_me;
824
825 ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1);
826 if (ret)
827 goto err_vd;
828
829 v4l2_info(v4l2_dev, "Registered %s as /dev/%s\n",
830 vfd->name, video_device_node_name(vfd));
831 return 0;
832
833err_vd:
834 media_entity_cleanup(&vfd->entity);
835err_me:
836 v4l2_m2m_release(fimc->m2m.m2m_dev);
837err_init:
838 video_device_release(fimc->m2m.vfd);
839 return ret;
840}
841
842void fimc_unregister_m2m_device(struct fimc_dev *fimc)
843{
844 if (!fimc)
845 return;
846
847 if (fimc->m2m.m2m_dev)
848 v4l2_m2m_release(fimc->m2m.m2m_dev);
849 if (fimc->m2m.vfd) {
850 media_entity_cleanup(&fimc->m2m.vfd->entity);
851 /* Can also be called if video device wasn't registered */
852 video_unregister_device(fimc->m2m.vfd);
853 }
854}
diff --git a/drivers/media/video/s5p-fimc/fimc-mdevice.c b/drivers/media/video/s5p-fimc/fimc-mdevice.c
deleted file mode 100644
index e65bb283fd8a..000000000000
--- a/drivers/media/video/s5p-fimc/fimc-mdevice.c
+++ /dev/null
@@ -1,1037 +0,0 @@
1/*
2 * S5P/EXYNOS4 SoC series camera host interface media device driver
3 *
4 * Copyright (C) 2011 Samsung Electronics Co., Ltd.
5 * Contact: Sylwester Nawrocki, <s.nawrocki@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published
9 * by the Free Software Foundation, either version 2 of the License,
10 * or (at your option) any later version.
11 */
12
13#include <linux/bug.h>
14#include <linux/device.h>
15#include <linux/errno.h>
16#include <linux/i2c.h>
17#include <linux/kernel.h>
18#include <linux/list.h>
19#include <linux/module.h>
20#include <linux/platform_device.h>
21#include <linux/pm_runtime.h>
22#include <linux/types.h>
23#include <linux/slab.h>
24#include <media/v4l2-ctrls.h>
25#include <media/media-device.h>
26
27#include "fimc-core.h"
28#include "fimc-lite.h"
29#include "fimc-mdevice.h"
30#include "mipi-csis.h"
31
32static int __fimc_md_set_camclk(struct fimc_md *fmd,
33 struct fimc_sensor_info *s_info,
34 bool on);
35/**
36 * fimc_pipeline_prepare - update pipeline information with subdevice pointers
37 * @fimc: fimc device terminating the pipeline
38 *
39 * Caller holds the graph mutex.
40 */
41void fimc_pipeline_prepare(struct fimc_pipeline *p, struct media_entity *me)
42{
43 struct media_pad *pad = &me->pads[0];
44 struct v4l2_subdev *sd;
45 int i;
46
47 for (i = 0; i < IDX_MAX; i++)
48 p->subdevs[i] = NULL;
49
50 while (1) {
51 if (!(pad->flags & MEDIA_PAD_FL_SINK))
52 break;
53
54 /* source pad */
55 pad = media_entity_remote_source(pad);
56 if (pad == NULL ||
57 media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
58 break;
59
60 sd = media_entity_to_v4l2_subdev(pad->entity);
61
62 switch (sd->grp_id) {
63 case SENSOR_GROUP_ID:
64 p->subdevs[IDX_SENSOR] = sd;
65 break;
66 case CSIS_GROUP_ID:
67 p->subdevs[IDX_CSIS] = sd;
68 break;
69 case FLITE_GROUP_ID:
70 p->subdevs[IDX_FLITE] = sd;
71 break;
72 case FIMC_GROUP_ID:
73 /* No need to control FIMC subdev through subdev ops */
74 break;
75 default:
76 pr_warn("%s: Unknown subdev grp_id: %#x\n",
77 __func__, sd->grp_id);
78 }
79 /* sink pad */
80 pad = &sd->entity.pads[0];
81 }
82}
83
84/**
85 * __subdev_set_power - change power state of a single subdev
86 * @sd: subdevice to change power state for
87 * @on: 1 to enable power or 0 to disable
88 *
89 * Return result of s_power subdev operation or -ENXIO if sd argument
90 * is NULL. Return 0 if the subdevice does not implement s_power.
91 */
92static int __subdev_set_power(struct v4l2_subdev *sd, int on)
93{
94 int *use_count;
95 int ret;
96
97 if (sd == NULL)
98 return -ENXIO;
99
100 use_count = &sd->entity.use_count;
101 if (on && (*use_count)++ > 0)
102 return 0;
103 else if (!on && (*use_count == 0 || --(*use_count) > 0))
104 return 0;
105 ret = v4l2_subdev_call(sd, core, s_power, on);
106
107 return ret != -ENOIOCTLCMD ? ret : 0;
108}
109
110/**
111 * fimc_pipeline_s_power - change power state of all pipeline subdevs
112 * @fimc: fimc device terminating the pipeline
113 * @state: true to power on, false to power off
114 *
115 * Needs to be called with the graph mutex held.
116 */
117int fimc_pipeline_s_power(struct fimc_pipeline *p, bool state)
118{
119 unsigned int i;
120 int ret;
121
122 if (p->subdevs[IDX_SENSOR] == NULL)
123 return -ENXIO;
124
125 for (i = 0; i < IDX_MAX; i++) {
126 unsigned int idx = state ? (IDX_MAX - 1) - i : i;
127
128 ret = __subdev_set_power(p->subdevs[idx], state);
129 if (ret < 0 && ret != -ENXIO)
130 return ret;
131 }
132
133 return 0;
134}
135
136/**
137 * __fimc_pipeline_initialize - update the pipeline information, enable power
138 * of all pipeline subdevs and the sensor clock
139 * @me: media entity to start graph walk with
140 * @prep: true to acquire sensor (and csis) subdevs
141 *
142 * This function must be called with the graph mutex held.
143 */
144static int __fimc_pipeline_initialize(struct fimc_pipeline *p,
145 struct media_entity *me, bool prep)
146{
147 int ret;
148
149 if (prep)
150 fimc_pipeline_prepare(p, me);
151
152 if (p->subdevs[IDX_SENSOR] == NULL)
153 return -EINVAL;
154
155 ret = fimc_md_set_camclk(p->subdevs[IDX_SENSOR], true);
156 if (ret)
157 return ret;
158
159 return fimc_pipeline_s_power(p, 1);
160}
161
162int fimc_pipeline_initialize(struct fimc_pipeline *p, struct media_entity *me,
163 bool prep)
164{
165 int ret;
166
167 mutex_lock(&me->parent->graph_mutex);
168 ret = __fimc_pipeline_initialize(p, me, prep);
169 mutex_unlock(&me->parent->graph_mutex);
170
171 return ret;
172}
173EXPORT_SYMBOL_GPL(fimc_pipeline_initialize);
174
175/**
176 * __fimc_pipeline_shutdown - disable the sensor clock and pipeline power
177 * @fimc: fimc device terminating the pipeline
178 *
179 * Disable power of all subdevs in the pipeline and turn off the external
180 * sensor clock.
181 * Called with the graph mutex held.
182 */
183static int __fimc_pipeline_shutdown(struct fimc_pipeline *p)
184{
185 int ret = 0;
186
187 if (p->subdevs[IDX_SENSOR]) {
188 ret = fimc_pipeline_s_power(p, 0);
189 fimc_md_set_camclk(p->subdevs[IDX_SENSOR], false);
190 }
191 return ret == -ENXIO ? 0 : ret;
192}
193
194int fimc_pipeline_shutdown(struct fimc_pipeline *p)
195{
196 struct media_entity *me;
197 int ret;
198
199 if (!p || !p->subdevs[IDX_SENSOR])
200 return -EINVAL;
201
202 me = &p->subdevs[IDX_SENSOR]->entity;
203 mutex_lock(&me->parent->graph_mutex);
204 ret = __fimc_pipeline_shutdown(p);
205 mutex_unlock(&me->parent->graph_mutex);
206
207 return ret;
208}
209EXPORT_SYMBOL_GPL(fimc_pipeline_shutdown);
210
211/**
212 * fimc_pipeline_s_stream - invoke s_stream on pipeline subdevs
213 * @pipeline: video pipeline structure
214 * @on: passed as the s_stream call argument
215 */
216int fimc_pipeline_s_stream(struct fimc_pipeline *p, bool on)
217{
218 int i, ret;
219
220 if (p->subdevs[IDX_SENSOR] == NULL)
221 return -ENODEV;
222
223 for (i = 0; i < IDX_MAX; i++) {
224 unsigned int idx = on ? (IDX_MAX - 1) - i : i;
225
226 ret = v4l2_subdev_call(p->subdevs[idx], video, s_stream, on);
227
228 if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
229 return ret;
230 }
231
232 return 0;
233
234}
235EXPORT_SYMBOL_GPL(fimc_pipeline_s_stream);
236
237/*
238 * Sensor subdevice helper functions
239 */
240static struct v4l2_subdev *fimc_md_register_sensor(struct fimc_md *fmd,
241 struct fimc_sensor_info *s_info)
242{
243 struct i2c_adapter *adapter;
244 struct v4l2_subdev *sd = NULL;
245
246 if (!s_info || !fmd)
247 return NULL;
248
249 adapter = i2c_get_adapter(s_info->pdata->i2c_bus_num);
250 if (!adapter) {
251 v4l2_warn(&fmd->v4l2_dev,
252 "Failed to get I2C adapter %d, deferring probe\n",
253 s_info->pdata->i2c_bus_num);
254 return ERR_PTR(-EPROBE_DEFER);
255 }
256 sd = v4l2_i2c_new_subdev_board(&fmd->v4l2_dev, adapter,
257 s_info->pdata->board_info, NULL);
258 if (IS_ERR_OR_NULL(sd)) {
259 i2c_put_adapter(adapter);
260 v4l2_warn(&fmd->v4l2_dev,
261 "Failed to acquire subdev %s, deferring probe\n",
262 s_info->pdata->board_info->type);
263 return ERR_PTR(-EPROBE_DEFER);
264 }
265 v4l2_set_subdev_hostdata(sd, s_info);
266 sd->grp_id = SENSOR_GROUP_ID;
267
268 v4l2_info(&fmd->v4l2_dev, "Registered sensor subdevice %s\n",
269 s_info->pdata->board_info->type);
270 return sd;
271}
272
273static void fimc_md_unregister_sensor(struct v4l2_subdev *sd)
274{
275 struct i2c_client *client = v4l2_get_subdevdata(sd);
276 struct i2c_adapter *adapter;
277
278 if (!client)
279 return;
280 v4l2_device_unregister_subdev(sd);
281 adapter = client->adapter;
282 i2c_unregister_device(client);
283 if (adapter)
284 i2c_put_adapter(adapter);
285}
286
287static int fimc_md_register_sensor_entities(struct fimc_md *fmd)
288{
289 struct s5p_platform_fimc *pdata = fmd->pdev->dev.platform_data;
290 struct fimc_dev *fd = NULL;
291 int num_clients, ret, i;
292
293 /*
294 * Runtime resume one of the FIMC entities to make sure
295 * the sclk_cam clocks are not globally disabled.
296 */
297 for (i = 0; !fd && i < ARRAY_SIZE(fmd->fimc); i++)
298 if (fmd->fimc[i])
299 fd = fmd->fimc[i];
300 if (!fd)
301 return -ENXIO;
302 ret = pm_runtime_get_sync(&fd->pdev->dev);
303 if (ret < 0)
304 return ret;
305
306 WARN_ON(pdata->num_clients > ARRAY_SIZE(fmd->sensor));
307 num_clients = min_t(u32, pdata->num_clients, ARRAY_SIZE(fmd->sensor));
308
309 fmd->num_sensors = num_clients;
310 for (i = 0; i < num_clients; i++) {
311 struct v4l2_subdev *sd;
312
313 fmd->sensor[i].pdata = &pdata->isp_info[i];
314 ret = __fimc_md_set_camclk(fmd, &fmd->sensor[i], true);
315 if (ret)
316 break;
317 sd = fimc_md_register_sensor(fmd, &fmd->sensor[i]);
318 ret = __fimc_md_set_camclk(fmd, &fmd->sensor[i], false);
319
320 if (!IS_ERR(sd)) {
321 fmd->sensor[i].subdev = sd;
322 } else {
323 fmd->sensor[i].subdev = NULL;
324 ret = PTR_ERR(sd);
325 break;
326 }
327 if (ret)
328 break;
329 }
330 pm_runtime_put(&fd->pdev->dev);
331 return ret;
332}
333
334/*
335 * MIPI CSIS and FIMC platform devices registration.
336 */
337static int fimc_register_callback(struct device *dev, void *p)
338{
339 struct fimc_dev *fimc = dev_get_drvdata(dev);
340 struct v4l2_subdev *sd = &fimc->vid_cap.subdev;
341 struct fimc_md *fmd = p;
342 int ret = 0;
343
344 if (!fimc || !fimc->pdev)
345 return 0;
346
347 if (fimc->pdev->id < 0 || fimc->pdev->id >= FIMC_MAX_DEVS)
348 return 0;
349
350 fmd->fimc[fimc->pdev->id] = fimc;
351 sd->grp_id = FIMC_GROUP_ID;
352
353 ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd);
354 if (ret) {
355 v4l2_err(&fmd->v4l2_dev, "Failed to register FIMC.%d (%d)\n",
356 fimc->id, ret);
357 }
358
359 return ret;
360}
361
362static int fimc_lite_register_callback(struct device *dev, void *p)
363{
364 struct fimc_lite *fimc = dev_get_drvdata(dev);
365 struct v4l2_subdev *sd = &fimc->subdev;
366 struct fimc_md *fmd = p;
367 int ret;
368
369 if (fimc == NULL)
370 return 0;
371
372 if (fimc->index >= FIMC_LITE_MAX_DEVS)
373 return 0;
374
375 fmd->fimc_lite[fimc->index] = fimc;
376 sd->grp_id = FLITE_GROUP_ID;
377
378 ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd);
379 if (ret) {
380 v4l2_err(&fmd->v4l2_dev,
381 "Failed to register FIMC-LITE.%d (%d)\n",
382 fimc->index, ret);
383 }
384 return ret;
385}
386
387static int csis_register_callback(struct device *dev, void *p)
388{
389 struct v4l2_subdev *sd = dev_get_drvdata(dev);
390 struct platform_device *pdev;
391 struct fimc_md *fmd = p;
392 int id, ret;
393
394 if (!sd)
395 return 0;
396 pdev = v4l2_get_subdevdata(sd);
397 if (!pdev || pdev->id < 0 || pdev->id >= CSIS_MAX_ENTITIES)
398 return 0;
399 v4l2_info(sd, "csis%d sd: %s\n", pdev->id, sd->name);
400
401 id = pdev->id < 0 ? 0 : pdev->id;
402 fmd->csis[id].sd = sd;
403 sd->grp_id = CSIS_GROUP_ID;
404 ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd);
405 if (ret)
406 v4l2_err(&fmd->v4l2_dev,
407 "Failed to register CSIS subdevice: %d\n", ret);
408 return ret;
409}
410
411/**
412 * fimc_md_register_platform_entities - register FIMC and CSIS media entities
413 */
414static int fimc_md_register_platform_entities(struct fimc_md *fmd)
415{
416 struct s5p_platform_fimc *pdata = fmd->pdev->dev.platform_data;
417 struct device_driver *driver;
418 int ret, i;
419
420 driver = driver_find(FIMC_MODULE_NAME, &platform_bus_type);
421 if (!driver) {
422 v4l2_warn(&fmd->v4l2_dev,
423 "%s driver not found, deffering probe\n",
424 FIMC_MODULE_NAME);
425 return -EPROBE_DEFER;
426 }
427
428 ret = driver_for_each_device(driver, NULL, fmd,
429 fimc_register_callback);
430 if (ret)
431 return ret;
432
433 driver = driver_find(FIMC_LITE_DRV_NAME, &platform_bus_type);
434 if (driver && try_module_get(driver->owner)) {
435 ret = driver_for_each_device(driver, NULL, fmd,
436 fimc_lite_register_callback);
437 if (ret)
438 return ret;
439 module_put(driver->owner);
440 }
441 /*
442 * Check if there is any sensor on the MIPI-CSI2 bus and
443 * if not skip the s5p-csis module loading.
444 */
445 if (pdata == NULL)
446 return 0;
447 for (i = 0; i < pdata->num_clients; i++) {
448 if (pdata->isp_info[i].bus_type == FIMC_MIPI_CSI2) {
449 ret = 1;
450 break;
451 }
452 }
453 if (!ret)
454 return 0;
455
456 driver = driver_find(CSIS_DRIVER_NAME, &platform_bus_type);
457 if (!driver || !try_module_get(driver->owner)) {
458 v4l2_warn(&fmd->v4l2_dev,
459 "%s driver not found, deffering probe\n",
460 CSIS_DRIVER_NAME);
461 return -EPROBE_DEFER;
462 }
463
464 return driver_for_each_device(driver, NULL, fmd,
465 csis_register_callback);
466}
467
468static void fimc_md_unregister_entities(struct fimc_md *fmd)
469{
470 int i;
471
472 for (i = 0; i < FIMC_MAX_DEVS; i++) {
473 if (fmd->fimc[i] == NULL)
474 continue;
475 v4l2_device_unregister_subdev(&fmd->fimc[i]->vid_cap.subdev);
476 fmd->fimc[i] = NULL;
477 }
478 for (i = 0; i < FIMC_LITE_MAX_DEVS; i++) {
479 if (fmd->fimc_lite[i] == NULL)
480 continue;
481 v4l2_device_unregister_subdev(&fmd->fimc_lite[i]->subdev);
482 fmd->fimc_lite[i] = NULL;
483 }
484 for (i = 0; i < CSIS_MAX_ENTITIES; i++) {
485 if (fmd->csis[i].sd == NULL)
486 continue;
487 v4l2_device_unregister_subdev(fmd->csis[i].sd);
488 module_put(fmd->csis[i].sd->owner);
489 fmd->csis[i].sd = NULL;
490 }
491 for (i = 0; i < fmd->num_sensors; i++) {
492 if (fmd->sensor[i].subdev == NULL)
493 continue;
494 fimc_md_unregister_sensor(fmd->sensor[i].subdev);
495 fmd->sensor[i].subdev = NULL;
496 }
497}
498
499/**
500 * __fimc_md_create_fimc_links - create links to all FIMC entities
501 * @fmd: fimc media device
502 * @source: the source entity to create links to all fimc entities from
503 * @sensor: sensor subdev linked to FIMC[fimc_id] entity, may be null
504 * @pad: the source entity pad index
505 * @link_mask: bitmask of the fimc devices for which link should be enabled
506 */
507static int __fimc_md_create_fimc_sink_links(struct fimc_md *fmd,
508 struct media_entity *source,
509 struct v4l2_subdev *sensor,
510 int pad, int link_mask)
511{
512 struct fimc_sensor_info *s_info;
513 struct media_entity *sink;
514 unsigned int flags = 0;
515 int ret, i;
516
517 for (i = 0; i < FIMC_MAX_DEVS; i++) {
518 if (!fmd->fimc[i])
519 continue;
520 /*
521 * Some FIMC variants are not fitted with camera capture
522 * interface. Skip creating a link from sensor for those.
523 */
524 if (!fmd->fimc[i]->variant->has_cam_if)
525 continue;
526
527 flags = ((1 << i) & link_mask) ? MEDIA_LNK_FL_ENABLED : 0;
528
529 sink = &fmd->fimc[i]->vid_cap.subdev.entity;
530 ret = media_entity_create_link(source, pad, sink,
531 FIMC_SD_PAD_SINK, flags);
532 if (ret)
533 return ret;
534
535 /* Notify FIMC capture subdev entity */
536 ret = media_entity_call(sink, link_setup, &sink->pads[0],
537 &source->pads[pad], flags);
538 if (ret)
539 break;
540
541 v4l2_info(&fmd->v4l2_dev, "created link [%s] %c> [%s]",
542 source->name, flags ? '=' : '-', sink->name);
543
544 if (flags == 0 || sensor == NULL)
545 continue;
546 s_info = v4l2_get_subdev_hostdata(sensor);
547 if (!WARN_ON(s_info == NULL)) {
548 unsigned long irq_flags;
549 spin_lock_irqsave(&fmd->slock, irq_flags);
550 s_info->host = fmd->fimc[i];
551 spin_unlock_irqrestore(&fmd->slock, irq_flags);
552 }
553 }
554
555 for (i = 0; i < FIMC_LITE_MAX_DEVS; i++) {
556 if (!fmd->fimc_lite[i])
557 continue;
558
559 if (link_mask & (1 << (i + FIMC_MAX_DEVS)))
560 flags = MEDIA_LNK_FL_ENABLED;
561 else
562 flags = 0;
563
564 sink = &fmd->fimc_lite[i]->subdev.entity;
565 ret = media_entity_create_link(source, pad, sink,
566 FLITE_SD_PAD_SINK, flags);
567 if (ret)
568 return ret;
569
570 /* Notify FIMC-LITE subdev entity */
571 ret = media_entity_call(sink, link_setup, &sink->pads[0],
572 &source->pads[pad], flags);
573 if (ret)
574 break;
575
576 v4l2_info(&fmd->v4l2_dev, "created link [%s] %c> [%s]",
577 source->name, flags ? '=' : '-', sink->name);
578 }
579 return 0;
580}
581
582/* Create links from FIMC-LITE source pads to other entities */
583static int __fimc_md_create_flite_source_links(struct fimc_md *fmd)
584{
585 struct media_entity *source, *sink;
586 unsigned int flags = MEDIA_LNK_FL_ENABLED;
587 int i, ret;
588
589 for (i = 0; i < FIMC_LITE_MAX_DEVS; i++) {
590 struct fimc_lite *fimc = fmd->fimc_lite[i];
591 if (fimc == NULL)
592 continue;
593 source = &fimc->subdev.entity;
594 sink = &fimc->vfd->entity;
595 /* FIMC-LITE's subdev and video node */
596 ret = media_entity_create_link(source, FIMC_SD_PAD_SOURCE,
597 sink, 0, flags);
598 if (ret)
599 break;
600 /* TODO: create links to other entities */
601 }
602
603 return ret;
604}
605
606/**
607 * fimc_md_create_links - create default links between registered entities
608 *
609 * Parallel interface sensor entities are connected directly to FIMC capture
610 * entities. The sensors using MIPI CSIS bus are connected through immutable
611 * link with CSI receiver entity specified by mux_id. Any registered CSIS
612 * entity has a link to each registered FIMC capture entity. Enabled links
613 * are created by default between each subsequent registered sensor and
614 * subsequent FIMC capture entity. The number of default active links is
615 * determined by the number of available sensors or FIMC entities,
616 * whichever is less.
617 */
618static int fimc_md_create_links(struct fimc_md *fmd)
619{
620 struct v4l2_subdev *sensor, *csis;
621 struct s5p_fimc_isp_info *pdata;
622 struct fimc_sensor_info *s_info;
623 struct media_entity *source, *sink;
624 int i, pad, fimc_id = 0, ret = 0;
625 u32 flags, link_mask = 0;
626
627 for (i = 0; i < fmd->num_sensors; i++) {
628 if (fmd->sensor[i].subdev == NULL)
629 continue;
630
631 sensor = fmd->sensor[i].subdev;
632 s_info = v4l2_get_subdev_hostdata(sensor);
633 if (!s_info || !s_info->pdata)
634 continue;
635
636 source = NULL;
637 pdata = s_info->pdata;
638
639 switch (pdata->bus_type) {
640 case FIMC_MIPI_CSI2:
641 if (WARN(pdata->mux_id >= CSIS_MAX_ENTITIES,
642 "Wrong CSI channel id: %d\n", pdata->mux_id))
643 return -EINVAL;
644
645 csis = fmd->csis[pdata->mux_id].sd;
646 if (WARN(csis == NULL,
647 "MIPI-CSI interface specified "
648 "but s5p-csis module is not loaded!\n"))
649 return -EINVAL;
650
651 ret = media_entity_create_link(&sensor->entity, 0,
652 &csis->entity, CSIS_PAD_SINK,
653 MEDIA_LNK_FL_IMMUTABLE |
654 MEDIA_LNK_FL_ENABLED);
655 if (ret)
656 return ret;
657
658 v4l2_info(&fmd->v4l2_dev, "created link [%s] => [%s]",
659 sensor->entity.name, csis->entity.name);
660
661 source = NULL;
662 break;
663
664 case FIMC_ITU_601...FIMC_ITU_656:
665 source = &sensor->entity;
666 pad = 0;
667 break;
668
669 default:
670 v4l2_err(&fmd->v4l2_dev, "Wrong bus_type: %x\n",
671 pdata->bus_type);
672 return -EINVAL;
673 }
674 if (source == NULL)
675 continue;
676
677 link_mask = 1 << fimc_id++;
678 ret = __fimc_md_create_fimc_sink_links(fmd, source, sensor,
679 pad, link_mask);
680 }
681
682 for (i = 0; i < ARRAY_SIZE(fmd->csis); i++) {
683 if (fmd->csis[i].sd == NULL)
684 continue;
685 source = &fmd->csis[i].sd->entity;
686 pad = CSIS_PAD_SOURCE;
687
688 link_mask = 1 << fimc_id++;
689 ret = __fimc_md_create_fimc_sink_links(fmd, source, NULL,
690 pad, link_mask);
691 }
692
693 /* Create immutable links between each FIMC's subdev and video node */
694 flags = MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED;
695 for (i = 0; i < FIMC_MAX_DEVS; i++) {
696 if (!fmd->fimc[i])
697 continue;
698 source = &fmd->fimc[i]->vid_cap.subdev.entity;
699 sink = &fmd->fimc[i]->vid_cap.vfd->entity;
700 ret = media_entity_create_link(source, FIMC_SD_PAD_SOURCE,
701 sink, 0, flags);
702 if (ret)
703 break;
704 }
705
706 return __fimc_md_create_flite_source_links(fmd);
707}
708
709/*
710 * The peripheral sensor clock management.
711 */
712static int fimc_md_get_clocks(struct fimc_md *fmd)
713{
714 char clk_name[32];
715 struct clk *clock;
716 int i;
717
718 for (i = 0; i < FIMC_MAX_CAMCLKS; i++) {
719 snprintf(clk_name, sizeof(clk_name), "sclk_cam%u", i);
720 clock = clk_get(NULL, clk_name);
721 if (IS_ERR_OR_NULL(clock)) {
722 v4l2_err(&fmd->v4l2_dev, "Failed to get clock: %s",
723 clk_name);
724 return -ENXIO;
725 }
726 fmd->camclk[i].clock = clock;
727 }
728 return 0;
729}
730
731static void fimc_md_put_clocks(struct fimc_md *fmd)
732{
733 int i = FIMC_MAX_CAMCLKS;
734
735 while (--i >= 0) {
736 if (IS_ERR_OR_NULL(fmd->camclk[i].clock))
737 continue;
738 clk_put(fmd->camclk[i].clock);
739 fmd->camclk[i].clock = NULL;
740 }
741}
742
743static int __fimc_md_set_camclk(struct fimc_md *fmd,
744 struct fimc_sensor_info *s_info,
745 bool on)
746{
747 struct s5p_fimc_isp_info *pdata = s_info->pdata;
748 struct fimc_camclk_info *camclk;
749 int ret = 0;
750
751 if (WARN_ON(pdata->clk_id >= FIMC_MAX_CAMCLKS) || fmd == NULL)
752 return -EINVAL;
753
754 camclk = &fmd->camclk[pdata->clk_id];
755
756 dbg("camclk %d, f: %lu, use_count: %d, on: %d",
757 pdata->clk_id, pdata->clk_frequency, camclk->use_count, on);
758
759 if (on) {
760 if (camclk->use_count > 0 &&
761 camclk->frequency != pdata->clk_frequency)
762 return -EINVAL;
763
764 if (camclk->use_count++ == 0) {
765 clk_set_rate(camclk->clock, pdata->clk_frequency);
766 camclk->frequency = pdata->clk_frequency;
767 ret = clk_enable(camclk->clock);
768 dbg("Enabled camclk %d: f: %lu", pdata->clk_id,
769 clk_get_rate(camclk->clock));
770 }
771 return ret;
772 }
773
774 if (WARN_ON(camclk->use_count == 0))
775 return 0;
776
777 if (--camclk->use_count == 0) {
778 clk_disable(camclk->clock);
779 dbg("Disabled camclk %d", pdata->clk_id);
780 }
781 return ret;
782}
783
784/**
785 * fimc_md_set_camclk - peripheral sensor clock setup
786 * @sd: sensor subdev to configure sclk_cam clock for
787 * @on: 1 to enable or 0 to disable the clock
788 *
789 * There are 2 separate clock outputs available in the SoC for external
790 * image processors. These clocks are shared between all registered FIMC
791 * devices to which sensors can be attached, either directly or through
792 * the MIPI CSI receiver. The clock is allowed here to be used by
793 * multiple sensors concurrently if they use same frequency.
794 * This function should only be called when the graph mutex is held.
795 */
796int fimc_md_set_camclk(struct v4l2_subdev *sd, bool on)
797{
798 struct fimc_sensor_info *s_info = v4l2_get_subdev_hostdata(sd);
799 struct fimc_md *fmd = entity_to_fimc_mdev(&sd->entity);
800
801 return __fimc_md_set_camclk(fmd, s_info, on);
802}
803
804static int fimc_md_link_notify(struct media_pad *source,
805 struct media_pad *sink, u32 flags)
806{
807 struct fimc_lite *fimc_lite = NULL;
808 struct fimc_dev *fimc = NULL;
809 struct fimc_pipeline *pipeline;
810 struct v4l2_subdev *sd;
811 int ret = 0;
812
813 if (media_entity_type(sink->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
814 return 0;
815
816 sd = media_entity_to_v4l2_subdev(sink->entity);
817
818 switch (sd->grp_id) {
819 case FLITE_GROUP_ID:
820 fimc_lite = v4l2_get_subdevdata(sd);
821 pipeline = &fimc_lite->pipeline;
822 break;
823 case FIMC_GROUP_ID:
824 fimc = v4l2_get_subdevdata(sd);
825 pipeline = &fimc->pipeline;
826 break;
827 default:
828 return 0;
829 }
830
831 if (!(flags & MEDIA_LNK_FL_ENABLED)) {
832 ret = __fimc_pipeline_shutdown(pipeline);
833 pipeline->subdevs[IDX_SENSOR] = NULL;
834 pipeline->subdevs[IDX_CSIS] = NULL;
835
836 if (fimc) {
837 mutex_lock(&fimc->lock);
838 fimc_ctrls_delete(fimc->vid_cap.ctx);
839 mutex_unlock(&fimc->lock);
840 }
841 return ret;
842 }
843 /*
844 * Link activation. Enable power of pipeline elements only if the
845 * pipeline is already in use, i.e. its video node is opened.
846 * Recreate the controls destroyed during the link deactivation.
847 */
848 if (fimc) {
849 mutex_lock(&fimc->lock);
850 if (fimc->vid_cap.refcnt > 0) {
851 ret = __fimc_pipeline_initialize(pipeline,
852 source->entity, true);
853 if (!ret)
854 ret = fimc_capture_ctrls_create(fimc);
855 }
856 mutex_unlock(&fimc->lock);
857 } else {
858 mutex_lock(&fimc_lite->lock);
859 if (fimc_lite->ref_count > 0) {
860 ret = __fimc_pipeline_initialize(pipeline,
861 source->entity, true);
862 }
863 mutex_unlock(&fimc_lite->lock);
864 }
865 return ret ? -EPIPE : ret;
866}
867
868static ssize_t fimc_md_sysfs_show(struct device *dev,
869 struct device_attribute *attr, char *buf)
870{
871 struct platform_device *pdev = to_platform_device(dev);
872 struct fimc_md *fmd = platform_get_drvdata(pdev);
873
874 if (fmd->user_subdev_api)
875 return strlcpy(buf, "Sub-device API (sub-dev)\n", PAGE_SIZE);
876
877 return strlcpy(buf, "V4L2 video node only API (vid-dev)\n", PAGE_SIZE);
878}
879
880static ssize_t fimc_md_sysfs_store(struct device *dev,
881 struct device_attribute *attr,
882 const char *buf, size_t count)
883{
884 struct platform_device *pdev = to_platform_device(dev);
885 struct fimc_md *fmd = platform_get_drvdata(pdev);
886 bool subdev_api;
887 int i;
888
889 if (!strcmp(buf, "vid-dev\n"))
890 subdev_api = false;
891 else if (!strcmp(buf, "sub-dev\n"))
892 subdev_api = true;
893 else
894 return count;
895
896 fmd->user_subdev_api = subdev_api;
897 for (i = 0; i < FIMC_MAX_DEVS; i++)
898 if (fmd->fimc[i])
899 fmd->fimc[i]->vid_cap.user_subdev_api = subdev_api;
900 return count;
901}
902/*
903 * This device attribute is to select video pipeline configuration method.
904 * There are following valid values:
905 * vid-dev - for V4L2 video node API only, subdevice will be configured
906 * by the host driver.
907 * sub-dev - for media controller API, subdevs must be configured in user
908 * space before starting streaming.
909 */
910static DEVICE_ATTR(subdev_conf_mode, S_IWUSR | S_IRUGO,
911 fimc_md_sysfs_show, fimc_md_sysfs_store);
912
913static int fimc_md_probe(struct platform_device *pdev)
914{
915 struct v4l2_device *v4l2_dev;
916 struct fimc_md *fmd;
917 int ret;
918
919 fmd = devm_kzalloc(&pdev->dev, sizeof(*fmd), GFP_KERNEL);
920 if (!fmd)
921 return -ENOMEM;
922
923 spin_lock_init(&fmd->slock);
924 fmd->pdev = pdev;
925
926 strlcpy(fmd->media_dev.model, "SAMSUNG S5P FIMC",
927 sizeof(fmd->media_dev.model));
928 fmd->media_dev.link_notify = fimc_md_link_notify;
929 fmd->media_dev.dev = &pdev->dev;
930
931 v4l2_dev = &fmd->v4l2_dev;
932 v4l2_dev->mdev = &fmd->media_dev;
933 v4l2_dev->notify = fimc_sensor_notify;
934 snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "%s",
935 dev_name(&pdev->dev));
936
937 ret = v4l2_device_register(&pdev->dev, &fmd->v4l2_dev);
938 if (ret < 0) {
939 v4l2_err(v4l2_dev, "Failed to register v4l2_device: %d\n", ret);
940 return ret;
941 }
942 ret = media_device_register(&fmd->media_dev);
943 if (ret < 0) {
944 v4l2_err(v4l2_dev, "Failed to register media device: %d\n", ret);
945 goto err_md;
946 }
947 ret = fimc_md_get_clocks(fmd);
948 if (ret)
949 goto err_clk;
950
951 fmd->user_subdev_api = false;
952
953 /* Protect the media graph while we're registering entities */
954 mutex_lock(&fmd->media_dev.graph_mutex);
955
956 ret = fimc_md_register_platform_entities(fmd);
957 if (ret)
958 goto err_unlock;
959
960 if (pdev->dev.platform_data) {
961 ret = fimc_md_register_sensor_entities(fmd);
962 if (ret)
963 goto err_unlock;
964 }
965 ret = fimc_md_create_links(fmd);
966 if (ret)
967 goto err_unlock;
968 ret = v4l2_device_register_subdev_nodes(&fmd->v4l2_dev);
969 if (ret)
970 goto err_unlock;
971
972 ret = device_create_file(&pdev->dev, &dev_attr_subdev_conf_mode);
973 if (ret)
974 goto err_unlock;
975
976 platform_set_drvdata(pdev, fmd);
977 mutex_unlock(&fmd->media_dev.graph_mutex);
978 return 0;
979
980err_unlock:
981 mutex_unlock(&fmd->media_dev.graph_mutex);
982err_clk:
983 media_device_unregister(&fmd->media_dev);
984 fimc_md_put_clocks(fmd);
985 fimc_md_unregister_entities(fmd);
986err_md:
987 v4l2_device_unregister(&fmd->v4l2_dev);
988 return ret;
989}
990
991static int __devexit fimc_md_remove(struct platform_device *pdev)
992{
993 struct fimc_md *fmd = platform_get_drvdata(pdev);
994
995 if (!fmd)
996 return 0;
997 device_remove_file(&pdev->dev, &dev_attr_subdev_conf_mode);
998 fimc_md_unregister_entities(fmd);
999 media_device_unregister(&fmd->media_dev);
1000 fimc_md_put_clocks(fmd);
1001 return 0;
1002}
1003
1004static struct platform_driver fimc_md_driver = {
1005 .probe = fimc_md_probe,
1006 .remove = __devexit_p(fimc_md_remove),
1007 .driver = {
1008 .name = "s5p-fimc-md",
1009 .owner = THIS_MODULE,
1010 }
1011};
1012
1013static int __init fimc_md_init(void)
1014{
1015 int ret;
1016
1017 request_module("s5p-csis");
1018 ret = fimc_register_driver();
1019 if (ret)
1020 return ret;
1021
1022 return platform_driver_register(&fimc_md_driver);
1023}
1024
1025static void __exit fimc_md_exit(void)
1026{
1027 platform_driver_unregister(&fimc_md_driver);
1028 fimc_unregister_driver();
1029}
1030
1031module_init(fimc_md_init);
1032module_exit(fimc_md_exit);
1033
1034MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
1035MODULE_DESCRIPTION("S5P FIMC camera host interface/video postprocessor driver");
1036MODULE_LICENSE("GPL");
1037MODULE_VERSION("2.0.1");
diff --git a/drivers/media/video/s5p-fimc/fimc-mdevice.h b/drivers/media/video/s5p-fimc/fimc-mdevice.h
deleted file mode 100644
index 1f5dbaff5442..000000000000
--- a/drivers/media/video/s5p-fimc/fimc-mdevice.h
+++ /dev/null
@@ -1,120 +0,0 @@
1/*
2 * Copyright (C) 2011 - 2012 Samsung Electronics Co., Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#ifndef FIMC_MDEVICE_H_
10#define FIMC_MDEVICE_H_
11
12#include <linux/clk.h>
13#include <linux/platform_device.h>
14#include <linux/mutex.h>
15#include <media/media-device.h>
16#include <media/media-entity.h>
17#include <media/v4l2-device.h>
18#include <media/v4l2-subdev.h>
19
20#include "fimc-core.h"
21#include "fimc-lite.h"
22#include "mipi-csis.h"
23
24/* Group IDs of sensor, MIPI-CSIS, FIMC-LITE and the writeback subdevs. */
25#define SENSOR_GROUP_ID (1 << 8)
26#define CSIS_GROUP_ID (1 << 9)
27#define WRITEBACK_GROUP_ID (1 << 10)
28#define FIMC_GROUP_ID (1 << 11)
29#define FLITE_GROUP_ID (1 << 12)
30
31#define FIMC_MAX_SENSORS 8
32#define FIMC_MAX_CAMCLKS 2
33
34struct fimc_csis_info {
35 struct v4l2_subdev *sd;
36 int id;
37};
38
39struct fimc_camclk_info {
40 struct clk *clock;
41 int use_count;
42 unsigned long frequency;
43};
44
45/**
46 * struct fimc_sensor_info - image data source subdev information
47 * @pdata: sensor's atrributes passed as media device's platform data
48 * @subdev: image sensor v4l2 subdev
49 * @host: fimc device the sensor is currently linked to
50 *
51 * This data structure applies to image sensor and the writeback subdevs.
52 */
53struct fimc_sensor_info {
54 struct s5p_fimc_isp_info *pdata;
55 struct v4l2_subdev *subdev;
56 struct fimc_dev *host;
57};
58
59/**
60 * struct fimc_md - fimc media device information
61 * @csis: MIPI CSIS subdevs data
62 * @sensor: array of registered sensor subdevs
63 * @num_sensors: actual number of registered sensors
64 * @camclk: external sensor clock information
65 * @fimc: array of registered fimc devices
66 * @media_dev: top level media device
67 * @v4l2_dev: top level v4l2_device holding up the subdevs
68 * @pdev: platform device this media device is hooked up into
69 * @user_subdev_api: true if subdevs are not configured by the host driver
70 * @slock: spinlock protecting @sensor array
71 */
72struct fimc_md {
73 struct fimc_csis_info csis[CSIS_MAX_ENTITIES];
74 struct fimc_sensor_info sensor[FIMC_MAX_SENSORS];
75 int num_sensors;
76 struct fimc_camclk_info camclk[FIMC_MAX_CAMCLKS];
77 struct fimc_lite *fimc_lite[FIMC_LITE_MAX_DEVS];
78 struct fimc_dev *fimc[FIMC_MAX_DEVS];
79 struct media_device media_dev;
80 struct v4l2_device v4l2_dev;
81 struct platform_device *pdev;
82 bool user_subdev_api;
83 spinlock_t slock;
84};
85
86#define is_subdev_pad(pad) (pad == NULL || \
87 media_entity_type(pad->entity) == MEDIA_ENT_T_V4L2_SUBDEV)
88
89#define me_subtype(me) \
90 ((me->type) & (MEDIA_ENT_TYPE_MASK | MEDIA_ENT_SUBTYPE_MASK))
91
92#define subdev_has_devnode(__sd) (__sd->flags & V4L2_SUBDEV_FL_HAS_DEVNODE)
93
94static inline struct fimc_md *entity_to_fimc_mdev(struct media_entity *me)
95{
96 return me->parent == NULL ? NULL :
97 container_of(me->parent, struct fimc_md, media_dev);
98}
99
100static inline void fimc_md_graph_lock(struct fimc_dev *fimc)
101{
102 BUG_ON(fimc->vid_cap.vfd == NULL);
103 mutex_lock(&fimc->vid_cap.vfd->entity.parent->graph_mutex);
104}
105
106static inline void fimc_md_graph_unlock(struct fimc_dev *fimc)
107{
108 BUG_ON(fimc->vid_cap.vfd == NULL);
109 mutex_unlock(&fimc->vid_cap.vfd->entity.parent->graph_mutex);
110}
111
112int fimc_md_set_camclk(struct v4l2_subdev *sd, bool on);
113void fimc_pipeline_prepare(struct fimc_pipeline *p, struct media_entity *me);
114int fimc_pipeline_initialize(struct fimc_pipeline *p, struct media_entity *me,
115 bool resume);
116int fimc_pipeline_shutdown(struct fimc_pipeline *p);
117int fimc_pipeline_s_power(struct fimc_pipeline *p, bool state);
118int fimc_pipeline_s_stream(struct fimc_pipeline *p, bool state);
119
120#endif
diff --git a/drivers/media/video/s5p-fimc/fimc-reg.c b/drivers/media/video/s5p-fimc/fimc-reg.c
deleted file mode 100644
index 0e3eb9ce4f98..000000000000
--- a/drivers/media/video/s5p-fimc/fimc-reg.c
+++ /dev/null
@@ -1,775 +0,0 @@
1/*
2 * Register interface file for Samsung Camera Interface (FIMC) driver
3 *
4 * Copyright (C) 2010 - 2012 Samsung Electronics Co., Ltd.
5 * Sylwester Nawrocki, <s.nawrocki@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10*/
11
12#include <linux/io.h>
13#include <linux/delay.h>
14#include <media/s5p_fimc.h>
15
16#include "fimc-reg.h"
17#include "fimc-core.h"
18
19
20void fimc_hw_reset(struct fimc_dev *dev)
21{
22 u32 cfg;
23
24 cfg = readl(dev->regs + FIMC_REG_CISRCFMT);
25 cfg |= FIMC_REG_CISRCFMT_ITU601_8BIT;
26 writel(cfg, dev->regs + FIMC_REG_CISRCFMT);
27
28 /* Software reset. */
29 cfg = readl(dev->regs + FIMC_REG_CIGCTRL);
30 cfg |= (FIMC_REG_CIGCTRL_SWRST | FIMC_REG_CIGCTRL_IRQ_LEVEL);
31 writel(cfg, dev->regs + FIMC_REG_CIGCTRL);
32 udelay(10);
33
34 cfg = readl(dev->regs + FIMC_REG_CIGCTRL);
35 cfg &= ~FIMC_REG_CIGCTRL_SWRST;
36 writel(cfg, dev->regs + FIMC_REG_CIGCTRL);
37
38 if (dev->variant->out_buf_count > 4)
39 fimc_hw_set_dma_seq(dev, 0xF);
40}
41
42static u32 fimc_hw_get_in_flip(struct fimc_ctx *ctx)
43{
44 u32 flip = FIMC_REG_MSCTRL_FLIP_NORMAL;
45
46 if (ctx->hflip)
47 flip = FIMC_REG_MSCTRL_FLIP_X_MIRROR;
48 if (ctx->vflip)
49 flip = FIMC_REG_MSCTRL_FLIP_Y_MIRROR;
50
51 if (ctx->rotation <= 90)
52 return flip;
53
54 return (flip ^ FIMC_REG_MSCTRL_FLIP_180) & FIMC_REG_MSCTRL_FLIP_180;
55}
56
57static u32 fimc_hw_get_target_flip(struct fimc_ctx *ctx)
58{
59 u32 flip = FIMC_REG_CITRGFMT_FLIP_NORMAL;
60
61 if (ctx->hflip)
62 flip |= FIMC_REG_CITRGFMT_FLIP_X_MIRROR;
63 if (ctx->vflip)
64 flip |= FIMC_REG_CITRGFMT_FLIP_Y_MIRROR;
65
66 if (ctx->rotation <= 90)
67 return flip;
68
69 return (flip ^ FIMC_REG_CITRGFMT_FLIP_180) & FIMC_REG_CITRGFMT_FLIP_180;
70}
71
72void fimc_hw_set_rotation(struct fimc_ctx *ctx)
73{
74 u32 cfg, flip;
75 struct fimc_dev *dev = ctx->fimc_dev;
76
77 cfg = readl(dev->regs + FIMC_REG_CITRGFMT);
78 cfg &= ~(FIMC_REG_CITRGFMT_INROT90 | FIMC_REG_CITRGFMT_OUTROT90 |
79 FIMC_REG_CITRGFMT_FLIP_180);
80
81 /*
82 * The input and output rotator cannot work simultaneously.
83 * Use the output rotator in output DMA mode or the input rotator
84 * in direct fifo output mode.
85 */
86 if (ctx->rotation == 90 || ctx->rotation == 270) {
87 if (ctx->out_path == FIMC_IO_LCDFIFO)
88 cfg |= FIMC_REG_CITRGFMT_INROT90;
89 else
90 cfg |= FIMC_REG_CITRGFMT_OUTROT90;
91 }
92
93 if (ctx->out_path == FIMC_IO_DMA) {
94 cfg |= fimc_hw_get_target_flip(ctx);
95 writel(cfg, dev->regs + FIMC_REG_CITRGFMT);
96 } else {
97 /* LCD FIFO path */
98 flip = readl(dev->regs + FIMC_REG_MSCTRL);
99 flip &= ~FIMC_REG_MSCTRL_FLIP_MASK;
100 flip |= fimc_hw_get_in_flip(ctx);
101 writel(flip, dev->regs + FIMC_REG_MSCTRL);
102 }
103}
104
105void fimc_hw_set_target_format(struct fimc_ctx *ctx)
106{
107 u32 cfg;
108 struct fimc_dev *dev = ctx->fimc_dev;
109 struct fimc_frame *frame = &ctx->d_frame;
110
111 dbg("w= %d, h= %d color: %d", frame->width,
112 frame->height, frame->fmt->color);
113
114 cfg = readl(dev->regs + FIMC_REG_CITRGFMT);
115 cfg &= ~(FIMC_REG_CITRGFMT_FMT_MASK | FIMC_REG_CITRGFMT_HSIZE_MASK |
116 FIMC_REG_CITRGFMT_VSIZE_MASK);
117
118 switch (frame->fmt->color) {
119 case FIMC_FMT_RGB444...FIMC_FMT_RGB888:
120 cfg |= FIMC_REG_CITRGFMT_RGB;
121 break;
122 case FIMC_FMT_YCBCR420:
123 cfg |= FIMC_REG_CITRGFMT_YCBCR420;
124 break;
125 case FIMC_FMT_YCBYCR422...FIMC_FMT_CRYCBY422:
126 if (frame->fmt->colplanes == 1)
127 cfg |= FIMC_REG_CITRGFMT_YCBCR422_1P;
128 else
129 cfg |= FIMC_REG_CITRGFMT_YCBCR422;
130 break;
131 default:
132 break;
133 }
134
135 if (ctx->rotation == 90 || ctx->rotation == 270)
136 cfg |= (frame->height << 16) | frame->width;
137 else
138 cfg |= (frame->width << 16) | frame->height;
139
140 writel(cfg, dev->regs + FIMC_REG_CITRGFMT);
141
142 cfg = readl(dev->regs + FIMC_REG_CITAREA);
143 cfg &= ~FIMC_REG_CITAREA_MASK;
144 cfg |= (frame->width * frame->height);
145 writel(cfg, dev->regs + FIMC_REG_CITAREA);
146}
147
148static void fimc_hw_set_out_dma_size(struct fimc_ctx *ctx)
149{
150 struct fimc_dev *dev = ctx->fimc_dev;
151 struct fimc_frame *frame = &ctx->d_frame;
152 u32 cfg;
153
154 cfg = (frame->f_height << 16) | frame->f_width;
155 writel(cfg, dev->regs + FIMC_REG_ORGOSIZE);
156
157 /* Select color space conversion equation (HD/SD size).*/
158 cfg = readl(dev->regs + FIMC_REG_CIGCTRL);
159 if (frame->f_width >= 1280) /* HD */
160 cfg |= FIMC_REG_CIGCTRL_CSC_ITU601_709;
161 else /* SD */
162 cfg &= ~FIMC_REG_CIGCTRL_CSC_ITU601_709;
163 writel(cfg, dev->regs + FIMC_REG_CIGCTRL);
164
165}
166
167void fimc_hw_set_out_dma(struct fimc_ctx *ctx)
168{
169 struct fimc_dev *dev = ctx->fimc_dev;
170 struct fimc_frame *frame = &ctx->d_frame;
171 struct fimc_dma_offset *offset = &frame->dma_offset;
172 struct fimc_fmt *fmt = frame->fmt;
173 u32 cfg;
174
175 /* Set the input dma offsets. */
176 cfg = (offset->y_v << 16) | offset->y_h;
177 writel(cfg, dev->regs + FIMC_REG_CIOYOFF);
178
179 cfg = (offset->cb_v << 16) | offset->cb_h;
180 writel(cfg, dev->regs + FIMC_REG_CIOCBOFF);
181
182 cfg = (offset->cr_v << 16) | offset->cr_h;
183 writel(cfg, dev->regs + FIMC_REG_CIOCROFF);
184
185 fimc_hw_set_out_dma_size(ctx);
186
187 /* Configure chroma components order. */
188 cfg = readl(dev->regs + FIMC_REG_CIOCTRL);
189
190 cfg &= ~(FIMC_REG_CIOCTRL_ORDER2P_MASK |
191 FIMC_REG_CIOCTRL_ORDER422_MASK |
192 FIMC_REG_CIOCTRL_YCBCR_PLANE_MASK |
193 FIMC_REG_CIOCTRL_RGB16FMT_MASK);
194
195 if (fmt->colplanes == 1)
196 cfg |= ctx->out_order_1p;
197 else if (fmt->colplanes == 2)
198 cfg |= ctx->out_order_2p | FIMC_REG_CIOCTRL_YCBCR_2PLANE;
199 else if (fmt->colplanes == 3)
200 cfg |= FIMC_REG_CIOCTRL_YCBCR_3PLANE;
201
202 if (fmt->color == FIMC_FMT_RGB565)
203 cfg |= FIMC_REG_CIOCTRL_RGB565;
204 else if (fmt->color == FIMC_FMT_RGB555)
205 cfg |= FIMC_REG_CIOCTRL_ARGB1555;
206 else if (fmt->color == FIMC_FMT_RGB444)
207 cfg |= FIMC_REG_CIOCTRL_ARGB4444;
208
209 writel(cfg, dev->regs + FIMC_REG_CIOCTRL);
210}
211
212static void fimc_hw_en_autoload(struct fimc_dev *dev, int enable)
213{
214 u32 cfg = readl(dev->regs + FIMC_REG_ORGISIZE);
215 if (enable)
216 cfg |= FIMC_REG_CIREAL_ISIZE_AUTOLOAD_EN;
217 else
218 cfg &= ~FIMC_REG_CIREAL_ISIZE_AUTOLOAD_EN;
219 writel(cfg, dev->regs + FIMC_REG_ORGISIZE);
220}
221
222void fimc_hw_en_lastirq(struct fimc_dev *dev, int enable)
223{
224 u32 cfg = readl(dev->regs + FIMC_REG_CIOCTRL);
225 if (enable)
226 cfg |= FIMC_REG_CIOCTRL_LASTIRQ_ENABLE;
227 else
228 cfg &= ~FIMC_REG_CIOCTRL_LASTIRQ_ENABLE;
229 writel(cfg, dev->regs + FIMC_REG_CIOCTRL);
230}
231
232void fimc_hw_set_prescaler(struct fimc_ctx *ctx)
233{
234 struct fimc_dev *dev = ctx->fimc_dev;
235 struct fimc_scaler *sc = &ctx->scaler;
236 u32 cfg, shfactor;
237
238 shfactor = 10 - (sc->hfactor + sc->vfactor);
239 cfg = shfactor << 28;
240
241 cfg |= (sc->pre_hratio << 16) | sc->pre_vratio;
242 writel(cfg, dev->regs + FIMC_REG_CISCPRERATIO);
243
244 cfg = (sc->pre_dst_width << 16) | sc->pre_dst_height;
245 writel(cfg, dev->regs + FIMC_REG_CISCPREDST);
246}
247
248static void fimc_hw_set_scaler(struct fimc_ctx *ctx)
249{
250 struct fimc_dev *dev = ctx->fimc_dev;
251 struct fimc_scaler *sc = &ctx->scaler;
252 struct fimc_frame *src_frame = &ctx->s_frame;
253 struct fimc_frame *dst_frame = &ctx->d_frame;
254
255 u32 cfg = readl(dev->regs + FIMC_REG_CISCCTRL);
256
257 cfg &= ~(FIMC_REG_CISCCTRL_CSCR2Y_WIDE | FIMC_REG_CISCCTRL_CSCY2R_WIDE |
258 FIMC_REG_CISCCTRL_SCALEUP_H | FIMC_REG_CISCCTRL_SCALEUP_V |
259 FIMC_REG_CISCCTRL_SCALERBYPASS | FIMC_REG_CISCCTRL_ONE2ONE |
260 FIMC_REG_CISCCTRL_INRGB_FMT_MASK | FIMC_REG_CISCCTRL_OUTRGB_FMT_MASK |
261 FIMC_REG_CISCCTRL_INTERLACE | FIMC_REG_CISCCTRL_RGB_EXT);
262
263 if (!(ctx->flags & FIMC_COLOR_RANGE_NARROW))
264 cfg |= (FIMC_REG_CISCCTRL_CSCR2Y_WIDE |
265 FIMC_REG_CISCCTRL_CSCY2R_WIDE);
266
267 if (!sc->enabled)
268 cfg |= FIMC_REG_CISCCTRL_SCALERBYPASS;
269
270 if (sc->scaleup_h)
271 cfg |= FIMC_REG_CISCCTRL_SCALEUP_H;
272
273 if (sc->scaleup_v)
274 cfg |= FIMC_REG_CISCCTRL_SCALEUP_V;
275
276 if (sc->copy_mode)
277 cfg |= FIMC_REG_CISCCTRL_ONE2ONE;
278
279 if (ctx->in_path == FIMC_IO_DMA) {
280 switch (src_frame->fmt->color) {
281 case FIMC_FMT_RGB565:
282 cfg |= FIMC_REG_CISCCTRL_INRGB_FMT_RGB565;
283 break;
284 case FIMC_FMT_RGB666:
285 cfg |= FIMC_REG_CISCCTRL_INRGB_FMT_RGB666;
286 break;
287 case FIMC_FMT_RGB888:
288 cfg |= FIMC_REG_CISCCTRL_INRGB_FMT_RGB888;
289 break;
290 }
291 }
292
293 if (ctx->out_path == FIMC_IO_DMA) {
294 u32 color = dst_frame->fmt->color;
295
296 if (color >= FIMC_FMT_RGB444 && color <= FIMC_FMT_RGB565)
297 cfg |= FIMC_REG_CISCCTRL_OUTRGB_FMT_RGB565;
298 else if (color == FIMC_FMT_RGB666)
299 cfg |= FIMC_REG_CISCCTRL_OUTRGB_FMT_RGB666;
300 else if (color == FIMC_FMT_RGB888)
301 cfg |= FIMC_REG_CISCCTRL_OUTRGB_FMT_RGB888;
302 } else {
303 cfg |= FIMC_REG_CISCCTRL_OUTRGB_FMT_RGB888;
304
305 if (ctx->flags & FIMC_SCAN_MODE_INTERLACED)
306 cfg |= FIMC_REG_CISCCTRL_INTERLACE;
307 }
308
309 writel(cfg, dev->regs + FIMC_REG_CISCCTRL);
310}
311
312void fimc_hw_set_mainscaler(struct fimc_ctx *ctx)
313{
314 struct fimc_dev *dev = ctx->fimc_dev;
315 struct fimc_variant *variant = dev->variant;
316 struct fimc_scaler *sc = &ctx->scaler;
317 u32 cfg;
318
319 dbg("main_hratio= 0x%X main_vratio= 0x%X",
320 sc->main_hratio, sc->main_vratio);
321
322 fimc_hw_set_scaler(ctx);
323
324 cfg = readl(dev->regs + FIMC_REG_CISCCTRL);
325 cfg &= ~(FIMC_REG_CISCCTRL_MHRATIO_MASK |
326 FIMC_REG_CISCCTRL_MVRATIO_MASK);
327
328 if (variant->has_mainscaler_ext) {
329 cfg |= FIMC_REG_CISCCTRL_MHRATIO_EXT(sc->main_hratio);
330 cfg |= FIMC_REG_CISCCTRL_MVRATIO_EXT(sc->main_vratio);
331 writel(cfg, dev->regs + FIMC_REG_CISCCTRL);
332
333 cfg = readl(dev->regs + FIMC_REG_CIEXTEN);
334
335 cfg &= ~(FIMC_REG_CIEXTEN_MVRATIO_EXT_MASK |
336 FIMC_REG_CIEXTEN_MHRATIO_EXT_MASK);
337 cfg |= FIMC_REG_CIEXTEN_MHRATIO_EXT(sc->main_hratio);
338 cfg |= FIMC_REG_CIEXTEN_MVRATIO_EXT(sc->main_vratio);
339 writel(cfg, dev->regs + FIMC_REG_CIEXTEN);
340 } else {
341 cfg |= FIMC_REG_CISCCTRL_MHRATIO(sc->main_hratio);
342 cfg |= FIMC_REG_CISCCTRL_MVRATIO(sc->main_vratio);
343 writel(cfg, dev->regs + FIMC_REG_CISCCTRL);
344 }
345}
346
347void fimc_hw_en_capture(struct fimc_ctx *ctx)
348{
349 struct fimc_dev *dev = ctx->fimc_dev;
350
351 u32 cfg = readl(dev->regs + FIMC_REG_CIIMGCPT);
352
353 if (ctx->out_path == FIMC_IO_DMA) {
354 /* one shot mode */
355 cfg |= FIMC_REG_CIIMGCPT_CPT_FREN_ENABLE |
356 FIMC_REG_CIIMGCPT_IMGCPTEN;
357 } else {
358 /* Continuous frame capture mode (freerun). */
359 cfg &= ~(FIMC_REG_CIIMGCPT_CPT_FREN_ENABLE |
360 FIMC_REG_CIIMGCPT_CPT_FRMOD_CNT);
361 cfg |= FIMC_REG_CIIMGCPT_IMGCPTEN;
362 }
363
364 if (ctx->scaler.enabled)
365 cfg |= FIMC_REG_CIIMGCPT_IMGCPTEN_SC;
366
367 cfg |= FIMC_REG_CIIMGCPT_IMGCPTEN;
368 writel(cfg, dev->regs + FIMC_REG_CIIMGCPT);
369}
370
371void fimc_hw_set_effect(struct fimc_ctx *ctx)
372{
373 struct fimc_dev *dev = ctx->fimc_dev;
374 struct fimc_effect *effect = &ctx->effect;
375 u32 cfg = 0;
376
377 if (effect->type != FIMC_REG_CIIMGEFF_FIN_BYPASS) {
378 cfg |= FIMC_REG_CIIMGEFF_IE_SC_AFTER |
379 FIMC_REG_CIIMGEFF_IE_ENABLE;
380 cfg |= effect->type;
381 if (effect->type == FIMC_REG_CIIMGEFF_FIN_ARBITRARY)
382 cfg |= (effect->pat_cb << 13) | effect->pat_cr;
383 }
384
385 writel(cfg, dev->regs + FIMC_REG_CIIMGEFF);
386}
387
388void fimc_hw_set_rgb_alpha(struct fimc_ctx *ctx)
389{
390 struct fimc_dev *dev = ctx->fimc_dev;
391 struct fimc_frame *frame = &ctx->d_frame;
392 u32 cfg;
393
394 if (!(frame->fmt->flags & FMT_HAS_ALPHA))
395 return;
396
397 cfg = readl(dev->regs + FIMC_REG_CIOCTRL);
398 cfg &= ~FIMC_REG_CIOCTRL_ALPHA_OUT_MASK;
399 cfg |= (frame->alpha << 4);
400 writel(cfg, dev->regs + FIMC_REG_CIOCTRL);
401}
402
403static void fimc_hw_set_in_dma_size(struct fimc_ctx *ctx)
404{
405 struct fimc_dev *dev = ctx->fimc_dev;
406 struct fimc_frame *frame = &ctx->s_frame;
407 u32 cfg_o = 0;
408 u32 cfg_r = 0;
409
410 if (FIMC_IO_LCDFIFO == ctx->out_path)
411 cfg_r |= FIMC_REG_CIREAL_ISIZE_AUTOLOAD_EN;
412
413 cfg_o |= (frame->f_height << 16) | frame->f_width;
414 cfg_r |= (frame->height << 16) | frame->width;
415
416 writel(cfg_o, dev->regs + FIMC_REG_ORGISIZE);
417 writel(cfg_r, dev->regs + FIMC_REG_CIREAL_ISIZE);
418}
419
420void fimc_hw_set_in_dma(struct fimc_ctx *ctx)
421{
422 struct fimc_dev *dev = ctx->fimc_dev;
423 struct fimc_frame *frame = &ctx->s_frame;
424 struct fimc_dma_offset *offset = &frame->dma_offset;
425 u32 cfg;
426
427 /* Set the pixel offsets. */
428 cfg = (offset->y_v << 16) | offset->y_h;
429 writel(cfg, dev->regs + FIMC_REG_CIIYOFF);
430
431 cfg = (offset->cb_v << 16) | offset->cb_h;
432 writel(cfg, dev->regs + FIMC_REG_CIICBOFF);
433
434 cfg = (offset->cr_v << 16) | offset->cr_h;
435 writel(cfg, dev->regs + FIMC_REG_CIICROFF);
436
437 /* Input original and real size. */
438 fimc_hw_set_in_dma_size(ctx);
439
440 /* Use DMA autoload only in FIFO mode. */
441 fimc_hw_en_autoload(dev, ctx->out_path == FIMC_IO_LCDFIFO);
442
443 /* Set the input DMA to process single frame only. */
444 cfg = readl(dev->regs + FIMC_REG_MSCTRL);
445 cfg &= ~(FIMC_REG_MSCTRL_INFORMAT_MASK
446 | FIMC_REG_MSCTRL_IN_BURST_COUNT_MASK
447 | FIMC_REG_MSCTRL_INPUT_MASK
448 | FIMC_REG_MSCTRL_C_INT_IN_MASK
449 | FIMC_REG_MSCTRL_2P_IN_ORDER_MASK);
450
451 cfg |= (FIMC_REG_MSCTRL_IN_BURST_COUNT(4)
452 | FIMC_REG_MSCTRL_INPUT_MEMORY
453 | FIMC_REG_MSCTRL_FIFO_CTRL_FULL);
454
455 switch (frame->fmt->color) {
456 case FIMC_FMT_RGB565...FIMC_FMT_RGB888:
457 cfg |= FIMC_REG_MSCTRL_INFORMAT_RGB;
458 break;
459 case FIMC_FMT_YCBCR420:
460 cfg |= FIMC_REG_MSCTRL_INFORMAT_YCBCR420;
461
462 if (frame->fmt->colplanes == 2)
463 cfg |= ctx->in_order_2p | FIMC_REG_MSCTRL_C_INT_IN_2PLANE;
464 else
465 cfg |= FIMC_REG_MSCTRL_C_INT_IN_3PLANE;
466
467 break;
468 case FIMC_FMT_YCBYCR422...FIMC_FMT_CRYCBY422:
469 if (frame->fmt->colplanes == 1) {
470 cfg |= ctx->in_order_1p
471 | FIMC_REG_MSCTRL_INFORMAT_YCBCR422_1P;
472 } else {
473 cfg |= FIMC_REG_MSCTRL_INFORMAT_YCBCR422;
474
475 if (frame->fmt->colplanes == 2)
476 cfg |= ctx->in_order_2p
477 | FIMC_REG_MSCTRL_C_INT_IN_2PLANE;
478 else
479 cfg |= FIMC_REG_MSCTRL_C_INT_IN_3PLANE;
480 }
481 break;
482 default:
483 break;
484 }
485
486 writel(cfg, dev->regs + FIMC_REG_MSCTRL);
487
488 /* Input/output DMA linear/tiled mode. */
489 cfg = readl(dev->regs + FIMC_REG_CIDMAPARAM);
490 cfg &= ~FIMC_REG_CIDMAPARAM_TILE_MASK;
491
492 if (tiled_fmt(ctx->s_frame.fmt))
493 cfg |= FIMC_REG_CIDMAPARAM_R_64X32;
494
495 if (tiled_fmt(ctx->d_frame.fmt))
496 cfg |= FIMC_REG_CIDMAPARAM_W_64X32;
497
498 writel(cfg, dev->regs + FIMC_REG_CIDMAPARAM);
499}
500
501
502void fimc_hw_set_input_path(struct fimc_ctx *ctx)
503{
504 struct fimc_dev *dev = ctx->fimc_dev;
505
506 u32 cfg = readl(dev->regs + FIMC_REG_MSCTRL);
507 cfg &= ~FIMC_REG_MSCTRL_INPUT_MASK;
508
509 if (ctx->in_path == FIMC_IO_DMA)
510 cfg |= FIMC_REG_MSCTRL_INPUT_MEMORY;
511 else
512 cfg |= FIMC_REG_MSCTRL_INPUT_EXTCAM;
513
514 writel(cfg, dev->regs + FIMC_REG_MSCTRL);
515}
516
517void fimc_hw_set_output_path(struct fimc_ctx *ctx)
518{
519 struct fimc_dev *dev = ctx->fimc_dev;
520
521 u32 cfg = readl(dev->regs + FIMC_REG_CISCCTRL);
522 cfg &= ~FIMC_REG_CISCCTRL_LCDPATHEN_FIFO;
523 if (ctx->out_path == FIMC_IO_LCDFIFO)
524 cfg |= FIMC_REG_CISCCTRL_LCDPATHEN_FIFO;
525 writel(cfg, dev->regs + FIMC_REG_CISCCTRL);
526}
527
528void fimc_hw_set_input_addr(struct fimc_dev *dev, struct fimc_addr *paddr)
529{
530 u32 cfg = readl(dev->regs + FIMC_REG_CIREAL_ISIZE);
531 cfg |= FIMC_REG_CIREAL_ISIZE_ADDR_CH_DIS;
532 writel(cfg, dev->regs + FIMC_REG_CIREAL_ISIZE);
533
534 writel(paddr->y, dev->regs + FIMC_REG_CIIYSA(0));
535 writel(paddr->cb, dev->regs + FIMC_REG_CIICBSA(0));
536 writel(paddr->cr, dev->regs + FIMC_REG_CIICRSA(0));
537
538 cfg &= ~FIMC_REG_CIREAL_ISIZE_ADDR_CH_DIS;
539 writel(cfg, dev->regs + FIMC_REG_CIREAL_ISIZE);
540}
541
542void fimc_hw_set_output_addr(struct fimc_dev *dev,
543 struct fimc_addr *paddr, int index)
544{
545 int i = (index == -1) ? 0 : index;
546 do {
547 writel(paddr->y, dev->regs + FIMC_REG_CIOYSA(i));
548 writel(paddr->cb, dev->regs + FIMC_REG_CIOCBSA(i));
549 writel(paddr->cr, dev->regs + FIMC_REG_CIOCRSA(i));
550 dbg("dst_buf[%d]: 0x%X, cb: 0x%X, cr: 0x%X",
551 i, paddr->y, paddr->cb, paddr->cr);
552 } while (index == -1 && ++i < FIMC_MAX_OUT_BUFS);
553}
554
555int fimc_hw_set_camera_polarity(struct fimc_dev *fimc,
556 struct s5p_fimc_isp_info *cam)
557{
558 u32 cfg = readl(fimc->regs + FIMC_REG_CIGCTRL);
559
560 cfg &= ~(FIMC_REG_CIGCTRL_INVPOLPCLK | FIMC_REG_CIGCTRL_INVPOLVSYNC |
561 FIMC_REG_CIGCTRL_INVPOLHREF | FIMC_REG_CIGCTRL_INVPOLHSYNC |
562 FIMC_REG_CIGCTRL_INVPOLFIELD);
563
564 if (cam->flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
565 cfg |= FIMC_REG_CIGCTRL_INVPOLPCLK;
566
567 if (cam->flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
568 cfg |= FIMC_REG_CIGCTRL_INVPOLVSYNC;
569
570 if (cam->flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
571 cfg |= FIMC_REG_CIGCTRL_INVPOLHREF;
572
573 if (cam->flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
574 cfg |= FIMC_REG_CIGCTRL_INVPOLHSYNC;
575
576 if (cam->flags & V4L2_MBUS_FIELD_EVEN_LOW)
577 cfg |= FIMC_REG_CIGCTRL_INVPOLFIELD;
578
579 writel(cfg, fimc->regs + FIMC_REG_CIGCTRL);
580
581 return 0;
582}
583
584struct mbus_pixfmt_desc {
585 u32 pixelcode;
586 u32 cisrcfmt;
587 u16 bus_width;
588};
589
590static const struct mbus_pixfmt_desc pix_desc[] = {
591 { V4L2_MBUS_FMT_YUYV8_2X8, FIMC_REG_CISRCFMT_ORDER422_YCBYCR, 8 },
592 { V4L2_MBUS_FMT_YVYU8_2X8, FIMC_REG_CISRCFMT_ORDER422_YCRYCB, 8 },
593 { V4L2_MBUS_FMT_VYUY8_2X8, FIMC_REG_CISRCFMT_ORDER422_CRYCBY, 8 },
594 { V4L2_MBUS_FMT_UYVY8_2X8, FIMC_REG_CISRCFMT_ORDER422_CBYCRY, 8 },
595};
596
597int fimc_hw_set_camera_source(struct fimc_dev *fimc,
598 struct s5p_fimc_isp_info *cam)
599{
600 struct fimc_frame *f = &fimc->vid_cap.ctx->s_frame;
601 u32 cfg = 0;
602 u32 bus_width;
603 int i;
604
605 if (cam->bus_type == FIMC_ITU_601 || cam->bus_type == FIMC_ITU_656) {
606 for (i = 0; i < ARRAY_SIZE(pix_desc); i++) {
607 if (fimc->vid_cap.mf.code == pix_desc[i].pixelcode) {
608 cfg = pix_desc[i].cisrcfmt;
609 bus_width = pix_desc[i].bus_width;
610 break;
611 }
612 }
613
614 if (i == ARRAY_SIZE(pix_desc)) {
615 v4l2_err(fimc->vid_cap.vfd,
616 "Camera color format not supported: %d\n",
617 fimc->vid_cap.mf.code);
618 return -EINVAL;
619 }
620
621 if (cam->bus_type == FIMC_ITU_601) {
622 if (bus_width == 8)
623 cfg |= FIMC_REG_CISRCFMT_ITU601_8BIT;
624 else if (bus_width == 16)
625 cfg |= FIMC_REG_CISRCFMT_ITU601_16BIT;
626 } /* else defaults to ITU-R BT.656 8-bit */
627 } else if (cam->bus_type == FIMC_MIPI_CSI2) {
628 if (fimc_fmt_is_jpeg(f->fmt->color))
629 cfg |= FIMC_REG_CISRCFMT_ITU601_8BIT;
630 }
631
632 cfg |= (f->o_width << 16) | f->o_height;
633 writel(cfg, fimc->regs + FIMC_REG_CISRCFMT);
634 return 0;
635}
636
637void fimc_hw_set_camera_offset(struct fimc_dev *fimc, struct fimc_frame *f)
638{
639 u32 hoff2, voff2;
640
641 u32 cfg = readl(fimc->regs + FIMC_REG_CIWDOFST);
642
643 cfg &= ~(FIMC_REG_CIWDOFST_HOROFF_MASK | FIMC_REG_CIWDOFST_VEROFF_MASK);
644 cfg |= FIMC_REG_CIWDOFST_OFF_EN |
645 (f->offs_h << 16) | f->offs_v;
646
647 writel(cfg, fimc->regs + FIMC_REG_CIWDOFST);
648
649 /* See CIWDOFSTn register description in the datasheet for details. */
650 hoff2 = f->o_width - f->width - f->offs_h;
651 voff2 = f->o_height - f->height - f->offs_v;
652 cfg = (hoff2 << 16) | voff2;
653 writel(cfg, fimc->regs + FIMC_REG_CIWDOFST2);
654}
655
656int fimc_hw_set_camera_type(struct fimc_dev *fimc,
657 struct s5p_fimc_isp_info *cam)
658{
659 u32 cfg, tmp;
660 struct fimc_vid_cap *vid_cap = &fimc->vid_cap;
661 u32 csis_data_alignment = 32;
662
663 cfg = readl(fimc->regs + FIMC_REG_CIGCTRL);
664
665 /* Select ITU B interface, disable Writeback path and test pattern. */
666 cfg &= ~(FIMC_REG_CIGCTRL_TESTPAT_MASK | FIMC_REG_CIGCTRL_SELCAM_ITU_A |
667 FIMC_REG_CIGCTRL_SELCAM_MIPI | FIMC_REG_CIGCTRL_CAMIF_SELWB |
668 FIMC_REG_CIGCTRL_SELCAM_MIPI_A | FIMC_REG_CIGCTRL_CAM_JPEG);
669
670 switch (cam->bus_type) {
671 case FIMC_MIPI_CSI2:
672 cfg |= FIMC_REG_CIGCTRL_SELCAM_MIPI;
673
674 if (cam->mux_id == 0)
675 cfg |= FIMC_REG_CIGCTRL_SELCAM_MIPI_A;
676
677 /* TODO: add remaining supported formats. */
678 switch (vid_cap->mf.code) {
679 case V4L2_MBUS_FMT_VYUY8_2X8:
680 tmp = FIMC_REG_CSIIMGFMT_YCBCR422_8BIT;
681 break;
682 case V4L2_MBUS_FMT_JPEG_1X8:
683 tmp = FIMC_REG_CSIIMGFMT_USER(1);
684 cfg |= FIMC_REG_CIGCTRL_CAM_JPEG;
685 break;
686 default:
687 v4l2_err(vid_cap->vfd,
688 "Not supported camera pixel format: %#x\n",
689 vid_cap->mf.code);
690 return -EINVAL;
691 }
692 tmp |= (csis_data_alignment == 32) << 8;
693
694 writel(tmp, fimc->regs + FIMC_REG_CSIIMGFMT);
695 break;
696 case FIMC_ITU_601...FIMC_ITU_656:
697 if (cam->mux_id == 0) /* ITU-A, ITU-B: 0, 1 */
698 cfg |= FIMC_REG_CIGCTRL_SELCAM_ITU_A;
699 break;
700 case FIMC_LCD_WB:
701 cfg |= FIMC_REG_CIGCTRL_CAMIF_SELWB;
702 break;
703 default:
704 v4l2_err(vid_cap->vfd, "Invalid camera bus type selected\n");
705 return -EINVAL;
706 }
707 writel(cfg, fimc->regs + FIMC_REG_CIGCTRL);
708
709 return 0;
710}
711
712void fimc_hw_clear_irq(struct fimc_dev *dev)
713{
714 u32 cfg = readl(dev->regs + FIMC_REG_CIGCTRL);
715 cfg |= FIMC_REG_CIGCTRL_IRQ_CLR;
716 writel(cfg, dev->regs + FIMC_REG_CIGCTRL);
717}
718
719void fimc_hw_enable_scaler(struct fimc_dev *dev, bool on)
720{
721 u32 cfg = readl(dev->regs + FIMC_REG_CISCCTRL);
722 if (on)
723 cfg |= FIMC_REG_CISCCTRL_SCALERSTART;
724 else
725 cfg &= ~FIMC_REG_CISCCTRL_SCALERSTART;
726 writel(cfg, dev->regs + FIMC_REG_CISCCTRL);
727}
728
729void fimc_hw_activate_input_dma(struct fimc_dev *dev, bool on)
730{
731 u32 cfg = readl(dev->regs + FIMC_REG_MSCTRL);
732 if (on)
733 cfg |= FIMC_REG_MSCTRL_ENVID;
734 else
735 cfg &= ~FIMC_REG_MSCTRL_ENVID;
736 writel(cfg, dev->regs + FIMC_REG_MSCTRL);
737}
738
739void fimc_hw_dis_capture(struct fimc_dev *dev)
740{
741 u32 cfg = readl(dev->regs + FIMC_REG_CIIMGCPT);
742 cfg &= ~(FIMC_REG_CIIMGCPT_IMGCPTEN | FIMC_REG_CIIMGCPT_IMGCPTEN_SC);
743 writel(cfg, dev->regs + FIMC_REG_CIIMGCPT);
744}
745
746/* Return an index to the buffer actually being written. */
747u32 fimc_hw_get_frame_index(struct fimc_dev *dev)
748{
749 u32 reg;
750
751 if (dev->variant->has_cistatus2) {
752 reg = readl(dev->regs + FIMC_REG_CISTATUS2) & 0x3F;
753 return reg > 0 ? --reg : reg;
754 }
755
756 reg = readl(dev->regs + FIMC_REG_CISTATUS);
757
758 return (reg & FIMC_REG_CISTATUS_FRAMECNT_MASK) >>
759 FIMC_REG_CISTATUS_FRAMECNT_SHIFT;
760}
761
762/* Locking: the caller holds fimc->slock */
763void fimc_activate_capture(struct fimc_ctx *ctx)
764{
765 fimc_hw_enable_scaler(ctx->fimc_dev, ctx->scaler.enabled);
766 fimc_hw_en_capture(ctx);
767}
768
769void fimc_deactivate_capture(struct fimc_dev *fimc)
770{
771 fimc_hw_en_lastirq(fimc, true);
772 fimc_hw_dis_capture(fimc);
773 fimc_hw_enable_scaler(fimc, false);
774 fimc_hw_en_lastirq(fimc, false);
775}
diff --git a/drivers/media/video/s5p-fimc/fimc-reg.h b/drivers/media/video/s5p-fimc/fimc-reg.h
deleted file mode 100644
index 579ac8ac03de..000000000000
--- a/drivers/media/video/s5p-fimc/fimc-reg.h
+++ /dev/null
@@ -1,326 +0,0 @@
1/*
2 * Samsung camera host interface (FIMC) registers definition
3 *
4 * Copyright (C) 2010 - 2012 Samsung Electronics Co., Ltd.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef FIMC_REG_H_
12#define FIMC_REG_H_
13
14#include "fimc-core.h"
15
16/* Input source format */
17#define FIMC_REG_CISRCFMT 0x00
18#define FIMC_REG_CISRCFMT_ITU601_8BIT (1 << 31)
19#define FIMC_REG_CISRCFMT_ITU601_16BIT (1 << 29)
20#define FIMC_REG_CISRCFMT_ORDER422_YCBYCR (0 << 14)
21#define FIMC_REG_CISRCFMT_ORDER422_YCRYCB (1 << 14)
22#define FIMC_REG_CISRCFMT_ORDER422_CBYCRY (2 << 14)
23#define FIMC_REG_CISRCFMT_ORDER422_CRYCBY (3 << 14)
24
25/* Window offset */
26#define FIMC_REG_CIWDOFST 0x04
27#define FIMC_REG_CIWDOFST_OFF_EN (1 << 31)
28#define FIMC_REG_CIWDOFST_CLROVFIY (1 << 30)
29#define FIMC_REG_CIWDOFST_CLROVRLB (1 << 29)
30#define FIMC_REG_CIWDOFST_HOROFF_MASK (0x7ff << 16)
31#define FIMC_REG_CIWDOFST_CLROVFICB (1 << 15)
32#define FIMC_REG_CIWDOFST_CLROVFICR (1 << 14)
33#define FIMC_REG_CIWDOFST_VEROFF_MASK (0xfff << 0)
34
35/* Global control */
36#define FIMC_REG_CIGCTRL 0x08
37#define FIMC_REG_CIGCTRL_SWRST (1 << 31)
38#define FIMC_REG_CIGCTRL_CAMRST_A (1 << 30)
39#define FIMC_REG_CIGCTRL_SELCAM_ITU_A (1 << 29)
40#define FIMC_REG_CIGCTRL_TESTPAT_NORMAL (0 << 27)
41#define FIMC_REG_CIGCTRL_TESTPAT_COLOR_BAR (1 << 27)
42#define FIMC_REG_CIGCTRL_TESTPAT_HOR_INC (2 << 27)
43#define FIMC_REG_CIGCTRL_TESTPAT_VER_INC (3 << 27)
44#define FIMC_REG_CIGCTRL_TESTPAT_MASK (3 << 27)
45#define FIMC_REG_CIGCTRL_TESTPAT_SHIFT 27
46#define FIMC_REG_CIGCTRL_INVPOLPCLK (1 << 26)
47#define FIMC_REG_CIGCTRL_INVPOLVSYNC (1 << 25)
48#define FIMC_REG_CIGCTRL_INVPOLHREF (1 << 24)
49#define FIMC_REG_CIGCTRL_IRQ_OVFEN (1 << 22)
50#define FIMC_REG_CIGCTRL_HREF_MASK (1 << 21)
51#define FIMC_REG_CIGCTRL_IRQ_LEVEL (1 << 20)
52#define FIMC_REG_CIGCTRL_IRQ_CLR (1 << 19)
53#define FIMC_REG_CIGCTRL_IRQ_ENABLE (1 << 16)
54#define FIMC_REG_CIGCTRL_SHDW_DISABLE (1 << 12)
55#define FIMC_REG_CIGCTRL_CAM_JPEG (1 << 8)
56#define FIMC_REG_CIGCTRL_SELCAM_MIPI_A (1 << 7)
57#define FIMC_REG_CIGCTRL_CAMIF_SELWB (1 << 6)
58/* 0 - ITU601; 1 - ITU709 */
59#define FIMC_REG_CIGCTRL_CSC_ITU601_709 (1 << 5)
60#define FIMC_REG_CIGCTRL_INVPOLHSYNC (1 << 4)
61#define FIMC_REG_CIGCTRL_SELCAM_MIPI (1 << 3)
62#define FIMC_REG_CIGCTRL_INVPOLFIELD (1 << 1)
63#define FIMC_REG_CIGCTRL_INTERLACE (1 << 0)
64
65/* Window offset 2 */
66#define FIMC_REG_CIWDOFST2 0x14
67#define FIMC_REG_CIWDOFST2_HOROFF_MASK (0xfff << 16)
68#define FIMC_REG_CIWDOFST2_VEROFF_MASK (0xfff << 0)
69
70/* Output DMA Y/Cb/Cr plane start addresses */
71#define FIMC_REG_CIOYSA(n) (0x18 + (n) * 4)
72#define FIMC_REG_CIOCBSA(n) (0x28 + (n) * 4)
73#define FIMC_REG_CIOCRSA(n) (0x38 + (n) * 4)
74
75/* Target image format */
76#define FIMC_REG_CITRGFMT 0x48
77#define FIMC_REG_CITRGFMT_INROT90 (1 << 31)
78#define FIMC_REG_CITRGFMT_YCBCR420 (0 << 29)
79#define FIMC_REG_CITRGFMT_YCBCR422 (1 << 29)
80#define FIMC_REG_CITRGFMT_YCBCR422_1P (2 << 29)
81#define FIMC_REG_CITRGFMT_RGB (3 << 29)
82#define FIMC_REG_CITRGFMT_FMT_MASK (3 << 29)
83#define FIMC_REG_CITRGFMT_HSIZE_MASK (0xfff << 16)
84#define FIMC_REG_CITRGFMT_FLIP_SHIFT 14
85#define FIMC_REG_CITRGFMT_FLIP_NORMAL (0 << 14)
86#define FIMC_REG_CITRGFMT_FLIP_X_MIRROR (1 << 14)
87#define FIMC_REG_CITRGFMT_FLIP_Y_MIRROR (2 << 14)
88#define FIMC_REG_CITRGFMT_FLIP_180 (3 << 14)
89#define FIMC_REG_CITRGFMT_FLIP_MASK (3 << 14)
90#define FIMC_REG_CITRGFMT_OUTROT90 (1 << 13)
91#define FIMC_REG_CITRGFMT_VSIZE_MASK (0xfff << 0)
92
93/* Output DMA control */
94#define FIMC_REG_CIOCTRL 0x4c
95#define FIMC_REG_CIOCTRL_ORDER422_MASK (3 << 0)
96#define FIMC_REG_CIOCTRL_ORDER422_CRYCBY (0 << 0)
97#define FIMC_REG_CIOCTRL_ORDER422_CBYCRY (1 << 0)
98#define FIMC_REG_CIOCTRL_ORDER422_YCRYCB (2 << 0)
99#define FIMC_REG_CIOCTRL_ORDER422_YCBYCR (3 << 0)
100#define FIMC_REG_CIOCTRL_LASTIRQ_ENABLE (1 << 2)
101#define FIMC_REG_CIOCTRL_YCBCR_3PLANE (0 << 3)
102#define FIMC_REG_CIOCTRL_YCBCR_2PLANE (1 << 3)
103#define FIMC_REG_CIOCTRL_YCBCR_PLANE_MASK (1 << 3)
104#define FIMC_REG_CIOCTRL_ALPHA_OUT_MASK (0xff << 4)
105#define FIMC_REG_CIOCTRL_RGB16FMT_MASK (3 << 16)
106#define FIMC_REG_CIOCTRL_RGB565 (0 << 16)
107#define FIMC_REG_CIOCTRL_ARGB1555 (1 << 16)
108#define FIMC_REG_CIOCTRL_ARGB4444 (2 << 16)
109#define FIMC_REG_CIOCTRL_ORDER2P_SHIFT 24
110#define FIMC_REG_CIOCTRL_ORDER2P_MASK (3 << 24)
111#define FIMC_REG_CIOCTRL_ORDER422_2P_LSB_CRCB (0 << 24)
112
113/* Pre-scaler control 1 */
114#define FIMC_REG_CISCPRERATIO 0x50
115
116#define FIMC_REG_CISCPREDST 0x54
117
118/* Main scaler control */
119#define FIMC_REG_CISCCTRL 0x58
120#define FIMC_REG_CISCCTRL_SCALERBYPASS (1 << 31)
121#define FIMC_REG_CISCCTRL_SCALEUP_H (1 << 30)
122#define FIMC_REG_CISCCTRL_SCALEUP_V (1 << 29)
123#define FIMC_REG_CISCCTRL_CSCR2Y_WIDE (1 << 28)
124#define FIMC_REG_CISCCTRL_CSCY2R_WIDE (1 << 27)
125#define FIMC_REG_CISCCTRL_LCDPATHEN_FIFO (1 << 26)
126#define FIMC_REG_CISCCTRL_INTERLACE (1 << 25)
127#define FIMC_REG_CISCCTRL_SCALERSTART (1 << 15)
128#define FIMC_REG_CISCCTRL_INRGB_FMT_RGB565 (0 << 13)
129#define FIMC_REG_CISCCTRL_INRGB_FMT_RGB666 (1 << 13)
130#define FIMC_REG_CISCCTRL_INRGB_FMT_RGB888 (2 << 13)
131#define FIMC_REG_CISCCTRL_INRGB_FMT_MASK (3 << 13)
132#define FIMC_REG_CISCCTRL_OUTRGB_FMT_RGB565 (0 << 11)
133#define FIMC_REG_CISCCTRL_OUTRGB_FMT_RGB666 (1 << 11)
134#define FIMC_REG_CISCCTRL_OUTRGB_FMT_RGB888 (2 << 11)
135#define FIMC_REG_CISCCTRL_OUTRGB_FMT_MASK (3 << 11)
136#define FIMC_REG_CISCCTRL_RGB_EXT (1 << 10)
137#define FIMC_REG_CISCCTRL_ONE2ONE (1 << 9)
138#define FIMC_REG_CISCCTRL_MHRATIO(x) ((x) << 16)
139#define FIMC_REG_CISCCTRL_MVRATIO(x) ((x) << 0)
140#define FIMC_REG_CISCCTRL_MHRATIO_MASK (0x1ff << 16)
141#define FIMC_REG_CISCCTRL_MVRATIO_MASK (0x1ff << 0)
142#define FIMC_REG_CISCCTRL_MHRATIO_EXT(x) (((x) >> 6) << 16)
143#define FIMC_REG_CISCCTRL_MVRATIO_EXT(x) (((x) >> 6) << 0)
144
145/* Target area */
146#define FIMC_REG_CITAREA 0x5c
147#define FIMC_REG_CITAREA_MASK 0x0fffffff
148
149/* General status */
150#define FIMC_REG_CISTATUS 0x64
151#define FIMC_REG_CISTATUS_OVFIY (1 << 31)
152#define FIMC_REG_CISTATUS_OVFICB (1 << 30)
153#define FIMC_REG_CISTATUS_OVFICR (1 << 29)
154#define FIMC_REG_CISTATUS_VSYNC (1 << 28)
155#define FIMC_REG_CISTATUS_FRAMECNT_MASK (3 << 26)
156#define FIMC_REG_CISTATUS_FRAMECNT_SHIFT 26
157#define FIMC_REG_CISTATUS_WINOFF_EN (1 << 25)
158#define FIMC_REG_CISTATUS_IMGCPT_EN (1 << 22)
159#define FIMC_REG_CISTATUS_IMGCPT_SCEN (1 << 21)
160#define FIMC_REG_CISTATUS_VSYNC_A (1 << 20)
161#define FIMC_REG_CISTATUS_VSYNC_B (1 << 19)
162#define FIMC_REG_CISTATUS_OVRLB (1 << 18)
163#define FIMC_REG_CISTATUS_FRAME_END (1 << 17)
164#define FIMC_REG_CISTATUS_LASTCAPT_END (1 << 16)
165#define FIMC_REG_CISTATUS_VVALID_A (1 << 15)
166#define FIMC_REG_CISTATUS_VVALID_B (1 << 14)
167
168/* Indexes to the last and the currently processed buffer. */
169#define FIMC_REG_CISTATUS2 0x68
170
171/* Image capture control */
172#define FIMC_REG_CIIMGCPT 0xc0
173#define FIMC_REG_CIIMGCPT_IMGCPTEN (1 << 31)
174#define FIMC_REG_CIIMGCPT_IMGCPTEN_SC (1 << 30)
175#define FIMC_REG_CIIMGCPT_CPT_FREN_ENABLE (1 << 25)
176#define FIMC_REG_CIIMGCPT_CPT_FRMOD_CNT (1 << 18)
177
178/* Frame capture sequence */
179#define FIMC_REG_CICPTSEQ 0xc4
180
181/* Image effect */
182#define FIMC_REG_CIIMGEFF 0xd0
183#define FIMC_REG_CIIMGEFF_IE_ENABLE (1 << 30)
184#define FIMC_REG_CIIMGEFF_IE_SC_BEFORE (0 << 29)
185#define FIMC_REG_CIIMGEFF_IE_SC_AFTER (1 << 29)
186#define FIMC_REG_CIIMGEFF_FIN_BYPASS (0 << 26)
187#define FIMC_REG_CIIMGEFF_FIN_ARBITRARY (1 << 26)
188#define FIMC_REG_CIIMGEFF_FIN_NEGATIVE (2 << 26)
189#define FIMC_REG_CIIMGEFF_FIN_ARTFREEZE (3 << 26)
190#define FIMC_REG_CIIMGEFF_FIN_EMBOSSING (4 << 26)
191#define FIMC_REG_CIIMGEFF_FIN_SILHOUETTE (5 << 26)
192#define FIMC_REG_CIIMGEFF_FIN_MASK (7 << 26)
193#define FIMC_REG_CIIMGEFF_PAT_CBCR_MASK ((0xff << 13) | 0xff)
194
195/* Input DMA Y/Cb/Cr plane start address 0/1 */
196#define FIMC_REG_CIIYSA(n) (0xd4 + (n) * 0x70)
197#define FIMC_REG_CIICBSA(n) (0xd8 + (n) * 0x70)
198#define FIMC_REG_CIICRSA(n) (0xdc + (n) * 0x70)
199
200/* Real input DMA image size */
201#define FIMC_REG_CIREAL_ISIZE 0xf8
202#define FIMC_REG_CIREAL_ISIZE_AUTOLOAD_EN (1 << 31)
203#define FIMC_REG_CIREAL_ISIZE_ADDR_CH_DIS (1 << 30)
204
205/* Input DMA control */
206#define FIMC_REG_MSCTRL 0xfc
207#define FIMC_REG_MSCTRL_IN_BURST_COUNT_MASK (0xf << 24)
208#define FIMC_REG_MSCTRL_2P_IN_ORDER_MASK (3 << 16)
209#define FIMC_REG_MSCTRL_2P_IN_ORDER_SHIFT 16
210#define FIMC_REG_MSCTRL_C_INT_IN_3PLANE (0 << 15)
211#define FIMC_REG_MSCTRL_C_INT_IN_2PLANE (1 << 15)
212#define FIMC_REG_MSCTRL_C_INT_IN_MASK (1 << 15)
213#define FIMC_REG_MSCTRL_FLIP_SHIFT 13
214#define FIMC_REG_MSCTRL_FLIP_MASK (3 << 13)
215#define FIMC_REG_MSCTRL_FLIP_NORMAL (0 << 13)
216#define FIMC_REG_MSCTRL_FLIP_X_MIRROR (1 << 13)
217#define FIMC_REG_MSCTRL_FLIP_Y_MIRROR (2 << 13)
218#define FIMC_REG_MSCTRL_FLIP_180 (3 << 13)
219#define FIMC_REG_MSCTRL_FIFO_CTRL_FULL (1 << 12)
220#define FIMC_REG_MSCTRL_ORDER422_SHIFT 4
221#define FIMC_REG_MSCTRL_ORDER422_YCBYCR (0 << 4)
222#define FIMC_REG_MSCTRL_ORDER422_CBYCRY (1 << 4)
223#define FIMC_REG_MSCTRL_ORDER422_YCRYCB (2 << 4)
224#define FIMC_REG_MSCTRL_ORDER422_CRYCBY (3 << 4)
225#define FIMC_REG_MSCTRL_ORDER422_MASK (3 << 4)
226#define FIMC_REG_MSCTRL_INPUT_EXTCAM (0 << 3)
227#define FIMC_REG_MSCTRL_INPUT_MEMORY (1 << 3)
228#define FIMC_REG_MSCTRL_INPUT_MASK (1 << 3)
229#define FIMC_REG_MSCTRL_INFORMAT_YCBCR420 (0 << 1)
230#define FIMC_REG_MSCTRL_INFORMAT_YCBCR422 (1 << 1)
231#define FIMC_REG_MSCTRL_INFORMAT_YCBCR422_1P (2 << 1)
232#define FIMC_REG_MSCTRL_INFORMAT_RGB (3 << 1)
233#define FIMC_REG_MSCTRL_INFORMAT_MASK (3 << 1)
234#define FIMC_REG_MSCTRL_ENVID (1 << 0)
235#define FIMC_REG_MSCTRL_IN_BURST_COUNT(x) ((x) << 24)
236
237/* Output DMA Y/Cb/Cr offset */
238#define FIMC_REG_CIOYOFF 0x168
239#define FIMC_REG_CIOCBOFF 0x16c
240#define FIMC_REG_CIOCROFF 0x170
241
242/* Input DMA Y/Cb/Cr offset */
243#define FIMC_REG_CIIYOFF 0x174
244#define FIMC_REG_CIICBOFF 0x178
245#define FIMC_REG_CIICROFF 0x17c
246
247/* Input DMA original image size */
248#define FIMC_REG_ORGISIZE 0x180
249
250/* Output DMA original image size */
251#define FIMC_REG_ORGOSIZE 0x184
252
253/* Real output DMA image size (extension register) */
254#define FIMC_REG_CIEXTEN 0x188
255#define FIMC_REG_CIEXTEN_MHRATIO_EXT(x) (((x) & 0x3f) << 10)
256#define FIMC_REG_CIEXTEN_MVRATIO_EXT(x) ((x) & 0x3f)
257#define FIMC_REG_CIEXTEN_MHRATIO_EXT_MASK (0x3f << 10)
258#define FIMC_REG_CIEXTEN_MVRATIO_EXT_MASK 0x3f
259
260#define FIMC_REG_CIDMAPARAM 0x18c
261#define FIMC_REG_CIDMAPARAM_R_LINEAR (0 << 29)
262#define FIMC_REG_CIDMAPARAM_R_64X32 (3 << 29)
263#define FIMC_REG_CIDMAPARAM_W_LINEAR (0 << 13)
264#define FIMC_REG_CIDMAPARAM_W_64X32 (3 << 13)
265#define FIMC_REG_CIDMAPARAM_TILE_MASK ((3 << 29) | (3 << 13))
266
267/* MIPI CSI image format */
268#define FIMC_REG_CSIIMGFMT 0x194
269#define FIMC_REG_CSIIMGFMT_YCBCR422_8BIT 0x1e
270#define FIMC_REG_CSIIMGFMT_RAW8 0x2a
271#define FIMC_REG_CSIIMGFMT_RAW10 0x2b
272#define FIMC_REG_CSIIMGFMT_RAW12 0x2c
273/* User defined formats. x = 0...16. */
274#define FIMC_REG_CSIIMGFMT_USER(x) (0x30 + x - 1)
275
276/* Output frame buffer sequence mask */
277#define FIMC_REG_CIFCNTSEQ 0x1fc
278
279/*
280 * Function declarations
281 */
282void fimc_hw_reset(struct fimc_dev *fimc);
283void fimc_hw_set_rotation(struct fimc_ctx *ctx);
284void fimc_hw_set_target_format(struct fimc_ctx *ctx);
285void fimc_hw_set_out_dma(struct fimc_ctx *ctx);
286void fimc_hw_en_lastirq(struct fimc_dev *fimc, int enable);
287void fimc_hw_en_irq(struct fimc_dev *fimc, int enable);
288void fimc_hw_set_prescaler(struct fimc_ctx *ctx);
289void fimc_hw_set_mainscaler(struct fimc_ctx *ctx);
290void fimc_hw_en_capture(struct fimc_ctx *ctx);
291void fimc_hw_set_effect(struct fimc_ctx *ctx);
292void fimc_hw_set_rgb_alpha(struct fimc_ctx *ctx);
293void fimc_hw_set_in_dma(struct fimc_ctx *ctx);
294void fimc_hw_set_input_path(struct fimc_ctx *ctx);
295void fimc_hw_set_output_path(struct fimc_ctx *ctx);
296void fimc_hw_set_input_addr(struct fimc_dev *fimc, struct fimc_addr *paddr);
297void fimc_hw_set_output_addr(struct fimc_dev *fimc, struct fimc_addr *paddr,
298 int index);
299int fimc_hw_set_camera_source(struct fimc_dev *fimc,
300 struct s5p_fimc_isp_info *cam);
301void fimc_hw_set_camera_offset(struct fimc_dev *fimc, struct fimc_frame *f);
302int fimc_hw_set_camera_polarity(struct fimc_dev *fimc,
303 struct s5p_fimc_isp_info *cam);
304int fimc_hw_set_camera_type(struct fimc_dev *fimc,
305 struct s5p_fimc_isp_info *cam);
306void fimc_hw_clear_irq(struct fimc_dev *dev);
307void fimc_hw_enable_scaler(struct fimc_dev *dev, bool on);
308void fimc_hw_activate_input_dma(struct fimc_dev *dev, bool on);
309void fimc_hw_dis_capture(struct fimc_dev *dev);
310u32 fimc_hw_get_frame_index(struct fimc_dev *dev);
311void fimc_activate_capture(struct fimc_ctx *ctx);
312void fimc_deactivate_capture(struct fimc_dev *fimc);
313
314/**
315 * fimc_hw_set_dma_seq - configure output DMA buffer sequence
316 * @mask: bitmask for the DMA output buffer registers, set to 0 to skip buffer
317 * This function masks output DMA ring buffers, it allows to select which of
318 * the 32 available output buffer address registers will be used by the DMA
319 * engine.
320 */
321static inline void fimc_hw_set_dma_seq(struct fimc_dev *dev, u32 mask)
322{
323 writel(mask, dev->regs + FIMC_REG_CIFCNTSEQ);
324}
325
326#endif /* FIMC_REG_H_ */
diff --git a/drivers/media/video/s5p-fimc/mipi-csis.c b/drivers/media/video/s5p-fimc/mipi-csis.c
deleted file mode 100644
index 2f73d9e3d0b7..000000000000
--- a/drivers/media/video/s5p-fimc/mipi-csis.c
+++ /dev/null
@@ -1,722 +0,0 @@
1/*
2 * Samsung S5P/EXYNOS4 SoC series MIPI-CSI receiver driver
3 *
4 * Copyright (C) 2011 - 2012 Samsung Electronics Co., Ltd.
5 * Sylwester Nawrocki, <s.nawrocki@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/clk.h>
13#include <linux/delay.h>
14#include <linux/device.h>
15#include <linux/errno.h>
16#include <linux/interrupt.h>
17#include <linux/io.h>
18#include <linux/irq.h>
19#include <linux/kernel.h>
20#include <linux/memory.h>
21#include <linux/module.h>
22#include <linux/platform_device.h>
23#include <linux/pm_runtime.h>
24#include <linux/regulator/consumer.h>
25#include <linux/slab.h>
26#include <linux/spinlock.h>
27#include <linux/videodev2.h>
28#include <media/v4l2-subdev.h>
29#include <plat/mipi_csis.h>
30#include "mipi-csis.h"
31
32static int debug;
33module_param(debug, int, 0644);
34MODULE_PARM_DESC(debug, "Debug level (0-1)");
35
36/* Register map definition */
37
38/* CSIS global control */
39#define S5PCSIS_CTRL 0x00
40#define S5PCSIS_CTRL_DPDN_DEFAULT (0 << 31)
41#define S5PCSIS_CTRL_DPDN_SWAP (1 << 31)
42#define S5PCSIS_CTRL_ALIGN_32BIT (1 << 20)
43#define S5PCSIS_CTRL_UPDATE_SHADOW (1 << 16)
44#define S5PCSIS_CTRL_WCLK_EXTCLK (1 << 8)
45#define S5PCSIS_CTRL_RESET (1 << 4)
46#define S5PCSIS_CTRL_ENABLE (1 << 0)
47
48/* D-PHY control */
49#define S5PCSIS_DPHYCTRL 0x04
50#define S5PCSIS_DPHYCTRL_HSS_MASK (0x1f << 27)
51#define S5PCSIS_DPHYCTRL_ENABLE (0x1f << 0)
52
53#define S5PCSIS_CONFIG 0x08
54#define S5PCSIS_CFG_FMT_YCBCR422_8BIT (0x1e << 2)
55#define S5PCSIS_CFG_FMT_RAW8 (0x2a << 2)
56#define S5PCSIS_CFG_FMT_RAW10 (0x2b << 2)
57#define S5PCSIS_CFG_FMT_RAW12 (0x2c << 2)
58/* User defined formats, x = 1...4 */
59#define S5PCSIS_CFG_FMT_USER(x) ((0x30 + x - 1) << 2)
60#define S5PCSIS_CFG_FMT_MASK (0x3f << 2)
61#define S5PCSIS_CFG_NR_LANE_MASK 3
62
63/* Interrupt mask. */
64#define S5PCSIS_INTMSK 0x10
65#define S5PCSIS_INTMSK_EN_ALL 0xf000003f
66#define S5PCSIS_INTSRC 0x14
67
68/* Pixel resolution */
69#define S5PCSIS_RESOL 0x2c
70#define CSIS_MAX_PIX_WIDTH 0xffff
71#define CSIS_MAX_PIX_HEIGHT 0xffff
72
73enum {
74 CSIS_CLK_MUX,
75 CSIS_CLK_GATE,
76};
77
78static char *csi_clock_name[] = {
79 [CSIS_CLK_MUX] = "sclk_csis",
80 [CSIS_CLK_GATE] = "csis",
81};
82#define NUM_CSIS_CLOCKS ARRAY_SIZE(csi_clock_name)
83
84static const char * const csis_supply_name[] = {
85 "vdd11", /* 1.1V or 1.2V (s5pc100) MIPI CSI suppply */
86 "vdd18", /* VDD 1.8V and MIPI CSI PLL supply */
87};
88#define CSIS_NUM_SUPPLIES ARRAY_SIZE(csis_supply_name)
89
90enum {
91 ST_POWERED = 1,
92 ST_STREAMING = 2,
93 ST_SUSPENDED = 4,
94};
95
96/**
97 * struct csis_state - the driver's internal state data structure
98 * @lock: mutex serializing the subdev and power management operations,
99 * protecting @format and @flags members
100 * @pads: CSIS pads array
101 * @sd: v4l2_subdev associated with CSIS device instance
102 * @pdev: CSIS platform device
103 * @regs: mmaped I/O registers memory
104 * @clock: CSIS clocks
105 * @irq: requested s5p-mipi-csis irq number
106 * @flags: the state variable for power and streaming control
107 * @csis_fmt: current CSIS pixel format
108 * @format: common media bus format for the source and sink pad
109 */
110struct csis_state {
111 struct mutex lock;
112 struct media_pad pads[CSIS_PADS_NUM];
113 struct v4l2_subdev sd;
114 struct platform_device *pdev;
115 void __iomem *regs;
116 struct regulator_bulk_data supplies[CSIS_NUM_SUPPLIES];
117 struct clk *clock[NUM_CSIS_CLOCKS];
118 int irq;
119 u32 flags;
120 const struct csis_pix_format *csis_fmt;
121 struct v4l2_mbus_framefmt format;
122};
123
124/**
125 * struct csis_pix_format - CSIS pixel format description
126 * @pix_width_alignment: horizontal pixel alignment, width will be
127 * multiple of 2^pix_width_alignment
128 * @code: corresponding media bus code
129 * @fmt_reg: S5PCSIS_CONFIG register value
130 * @data_alignment: MIPI-CSI data alignment in bits
131 */
132struct csis_pix_format {
133 unsigned int pix_width_alignment;
134 enum v4l2_mbus_pixelcode code;
135 u32 fmt_reg;
136 u8 data_alignment;
137};
138
139static const struct csis_pix_format s5pcsis_formats[] = {
140 {
141 .code = V4L2_MBUS_FMT_VYUY8_2X8,
142 .fmt_reg = S5PCSIS_CFG_FMT_YCBCR422_8BIT,
143 .data_alignment = 32,
144 }, {
145 .code = V4L2_MBUS_FMT_JPEG_1X8,
146 .fmt_reg = S5PCSIS_CFG_FMT_USER(1),
147 .data_alignment = 32,
148 },
149};
150
151#define s5pcsis_write(__csis, __r, __v) writel(__v, __csis->regs + __r)
152#define s5pcsis_read(__csis, __r) readl(__csis->regs + __r)
153
154static struct csis_state *sd_to_csis_state(struct v4l2_subdev *sdev)
155{
156 return container_of(sdev, struct csis_state, sd);
157}
158
159static const struct csis_pix_format *find_csis_format(
160 struct v4l2_mbus_framefmt *mf)
161{
162 int i;
163
164 for (i = 0; i < ARRAY_SIZE(s5pcsis_formats); i++)
165 if (mf->code == s5pcsis_formats[i].code)
166 return &s5pcsis_formats[i];
167 return NULL;
168}
169
170static void s5pcsis_enable_interrupts(struct csis_state *state, bool on)
171{
172 u32 val = s5pcsis_read(state, S5PCSIS_INTMSK);
173
174 val = on ? val | S5PCSIS_INTMSK_EN_ALL :
175 val & ~S5PCSIS_INTMSK_EN_ALL;
176 s5pcsis_write(state, S5PCSIS_INTMSK, val);
177}
178
179static void s5pcsis_reset(struct csis_state *state)
180{
181 u32 val = s5pcsis_read(state, S5PCSIS_CTRL);
182
183 s5pcsis_write(state, S5PCSIS_CTRL, val | S5PCSIS_CTRL_RESET);
184 udelay(10);
185}
186
187static void s5pcsis_system_enable(struct csis_state *state, int on)
188{
189 u32 val;
190
191 val = s5pcsis_read(state, S5PCSIS_CTRL);
192 if (on)
193 val |= S5PCSIS_CTRL_ENABLE;
194 else
195 val &= ~S5PCSIS_CTRL_ENABLE;
196 s5pcsis_write(state, S5PCSIS_CTRL, val);
197
198 val = s5pcsis_read(state, S5PCSIS_DPHYCTRL);
199 if (on)
200 val |= S5PCSIS_DPHYCTRL_ENABLE;
201 else
202 val &= ~S5PCSIS_DPHYCTRL_ENABLE;
203 s5pcsis_write(state, S5PCSIS_DPHYCTRL, val);
204}
205
206/* Called with the state.lock mutex held */
207static void __s5pcsis_set_format(struct csis_state *state)
208{
209 struct v4l2_mbus_framefmt *mf = &state->format;
210 u32 val;
211
212 v4l2_dbg(1, debug, &state->sd, "fmt: %d, %d x %d\n",
213 mf->code, mf->width, mf->height);
214
215 /* Color format */
216 val = s5pcsis_read(state, S5PCSIS_CONFIG);
217 val = (val & ~S5PCSIS_CFG_FMT_MASK) | state->csis_fmt->fmt_reg;
218 s5pcsis_write(state, S5PCSIS_CONFIG, val);
219
220 /* Pixel resolution */
221 val = (mf->width << 16) | mf->height;
222 s5pcsis_write(state, S5PCSIS_RESOL, val);
223}
224
225static void s5pcsis_set_hsync_settle(struct csis_state *state, int settle)
226{
227 u32 val = s5pcsis_read(state, S5PCSIS_DPHYCTRL);
228
229 val = (val & ~S5PCSIS_DPHYCTRL_HSS_MASK) | (settle << 27);
230 s5pcsis_write(state, S5PCSIS_DPHYCTRL, val);
231}
232
233static void s5pcsis_set_params(struct csis_state *state)
234{
235 struct s5p_platform_mipi_csis *pdata = state->pdev->dev.platform_data;
236 u32 val;
237
238 val = s5pcsis_read(state, S5PCSIS_CONFIG);
239 val = (val & ~S5PCSIS_CFG_NR_LANE_MASK) | (pdata->lanes - 1);
240 s5pcsis_write(state, S5PCSIS_CONFIG, val);
241
242 __s5pcsis_set_format(state);
243 s5pcsis_set_hsync_settle(state, pdata->hs_settle);
244
245 val = s5pcsis_read(state, S5PCSIS_CTRL);
246 if (state->csis_fmt->data_alignment == 32)
247 val |= S5PCSIS_CTRL_ALIGN_32BIT;
248 else /* 24-bits */
249 val &= ~S5PCSIS_CTRL_ALIGN_32BIT;
250 /* Not using external clock. */
251 val &= ~S5PCSIS_CTRL_WCLK_EXTCLK;
252 s5pcsis_write(state, S5PCSIS_CTRL, val);
253
254 /* Update the shadow register. */
255 val = s5pcsis_read(state, S5PCSIS_CTRL);
256 s5pcsis_write(state, S5PCSIS_CTRL, val | S5PCSIS_CTRL_UPDATE_SHADOW);
257}
258
259static void s5pcsis_clk_put(struct csis_state *state)
260{
261 int i;
262
263 for (i = 0; i < NUM_CSIS_CLOCKS; i++) {
264 if (IS_ERR_OR_NULL(state->clock[i]))
265 continue;
266 clk_unprepare(state->clock[i]);
267 clk_put(state->clock[i]);
268 state->clock[i] = NULL;
269 }
270}
271
272static int s5pcsis_clk_get(struct csis_state *state)
273{
274 struct device *dev = &state->pdev->dev;
275 int i, ret;
276
277 for (i = 0; i < NUM_CSIS_CLOCKS; i++) {
278 state->clock[i] = clk_get(dev, csi_clock_name[i]);
279 if (IS_ERR(state->clock[i]))
280 goto err;
281 ret = clk_prepare(state->clock[i]);
282 if (ret < 0) {
283 clk_put(state->clock[i]);
284 state->clock[i] = NULL;
285 goto err;
286 }
287 }
288 return 0;
289err:
290 s5pcsis_clk_put(state);
291 dev_err(dev, "failed to get clock: %s\n", csi_clock_name[i]);
292 return -ENXIO;
293}
294
295static int s5pcsis_s_power(struct v4l2_subdev *sd, int on)
296{
297 struct csis_state *state = sd_to_csis_state(sd);
298 struct device *dev = &state->pdev->dev;
299
300 if (on)
301 return pm_runtime_get_sync(dev);
302
303 return pm_runtime_put_sync(dev);
304}
305
306static void s5pcsis_start_stream(struct csis_state *state)
307{
308 s5pcsis_reset(state);
309 s5pcsis_set_params(state);
310 s5pcsis_system_enable(state, true);
311 s5pcsis_enable_interrupts(state, true);
312}
313
314static void s5pcsis_stop_stream(struct csis_state *state)
315{
316 s5pcsis_enable_interrupts(state, false);
317 s5pcsis_system_enable(state, false);
318}
319
320/* v4l2_subdev operations */
321static int s5pcsis_s_stream(struct v4l2_subdev *sd, int enable)
322{
323 struct csis_state *state = sd_to_csis_state(sd);
324 int ret = 0;
325
326 v4l2_dbg(1, debug, sd, "%s: %d, state: 0x%x\n",
327 __func__, enable, state->flags);
328
329 if (enable) {
330 ret = pm_runtime_get_sync(&state->pdev->dev);
331 if (ret && ret != 1)
332 return ret;
333 }
334 mutex_lock(&state->lock);
335 if (enable) {
336 if (state->flags & ST_SUSPENDED) {
337 ret = -EBUSY;
338 goto unlock;
339 }
340 s5pcsis_start_stream(state);
341 state->flags |= ST_STREAMING;
342 } else {
343 s5pcsis_stop_stream(state);
344 state->flags &= ~ST_STREAMING;
345 }
346unlock:
347 mutex_unlock(&state->lock);
348 if (!enable)
349 pm_runtime_put(&state->pdev->dev);
350
351 return ret == 1 ? 0 : ret;
352}
353
354static int s5pcsis_enum_mbus_code(struct v4l2_subdev *sd,
355 struct v4l2_subdev_fh *fh,
356 struct v4l2_subdev_mbus_code_enum *code)
357{
358 if (code->index >= ARRAY_SIZE(s5pcsis_formats))
359 return -EINVAL;
360
361 code->code = s5pcsis_formats[code->index].code;
362 return 0;
363}
364
365static struct csis_pix_format const *s5pcsis_try_format(
366 struct v4l2_mbus_framefmt *mf)
367{
368 struct csis_pix_format const *csis_fmt;
369
370 csis_fmt = find_csis_format(mf);
371 if (csis_fmt == NULL)
372 csis_fmt = &s5pcsis_formats[0];
373
374 mf->code = csis_fmt->code;
375 v4l_bound_align_image(&mf->width, 1, CSIS_MAX_PIX_WIDTH,
376 csis_fmt->pix_width_alignment,
377 &mf->height, 1, CSIS_MAX_PIX_HEIGHT, 1,
378 0);
379 return csis_fmt;
380}
381
382static struct v4l2_mbus_framefmt *__s5pcsis_get_format(
383 struct csis_state *state, struct v4l2_subdev_fh *fh,
384 u32 pad, enum v4l2_subdev_format_whence which)
385{
386 if (which == V4L2_SUBDEV_FORMAT_TRY)
387 return fh ? v4l2_subdev_get_try_format(fh, pad) : NULL;
388
389 return &state->format;
390}
391
392static int s5pcsis_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
393 struct v4l2_subdev_format *fmt)
394{
395 struct csis_state *state = sd_to_csis_state(sd);
396 struct csis_pix_format const *csis_fmt;
397 struct v4l2_mbus_framefmt *mf;
398
399 if (fmt->pad != CSIS_PAD_SOURCE && fmt->pad != CSIS_PAD_SINK)
400 return -EINVAL;
401
402 mf = __s5pcsis_get_format(state, fh, fmt->pad, fmt->which);
403
404 if (fmt->pad == CSIS_PAD_SOURCE) {
405 if (mf) {
406 mutex_lock(&state->lock);
407 fmt->format = *mf;
408 mutex_unlock(&state->lock);
409 }
410 return 0;
411 }
412 csis_fmt = s5pcsis_try_format(&fmt->format);
413 if (mf) {
414 mutex_lock(&state->lock);
415 *mf = fmt->format;
416 if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE)
417 state->csis_fmt = csis_fmt;
418 mutex_unlock(&state->lock);
419 }
420 return 0;
421}
422
423static int s5pcsis_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
424 struct v4l2_subdev_format *fmt)
425{
426 struct csis_state *state = sd_to_csis_state(sd);
427 struct v4l2_mbus_framefmt *mf;
428
429 if (fmt->pad != CSIS_PAD_SOURCE && fmt->pad != CSIS_PAD_SINK)
430 return -EINVAL;
431
432 mf = __s5pcsis_get_format(state, fh, fmt->pad, fmt->which);
433 if (!mf)
434 return -EINVAL;
435
436 mutex_lock(&state->lock);
437 fmt->format = *mf;
438 mutex_unlock(&state->lock);
439 return 0;
440}
441
442static int s5pcsis_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
443{
444 struct v4l2_mbus_framefmt *format = v4l2_subdev_get_try_format(fh, 0);
445
446 format->colorspace = V4L2_COLORSPACE_JPEG;
447 format->code = s5pcsis_formats[0].code;
448 format->width = S5PCSIS_DEF_PIX_WIDTH;
449 format->height = S5PCSIS_DEF_PIX_HEIGHT;
450 format->field = V4L2_FIELD_NONE;
451
452 return 0;
453}
454
455static const struct v4l2_subdev_internal_ops s5pcsis_sd_internal_ops = {
456 .open = s5pcsis_open,
457};
458
459static struct v4l2_subdev_core_ops s5pcsis_core_ops = {
460 .s_power = s5pcsis_s_power,
461};
462
463static struct v4l2_subdev_pad_ops s5pcsis_pad_ops = {
464 .enum_mbus_code = s5pcsis_enum_mbus_code,
465 .get_fmt = s5pcsis_get_fmt,
466 .set_fmt = s5pcsis_set_fmt,
467};
468
469static struct v4l2_subdev_video_ops s5pcsis_video_ops = {
470 .s_stream = s5pcsis_s_stream,
471};
472
473static struct v4l2_subdev_ops s5pcsis_subdev_ops = {
474 .core = &s5pcsis_core_ops,
475 .pad = &s5pcsis_pad_ops,
476 .video = &s5pcsis_video_ops,
477};
478
479static irqreturn_t s5pcsis_irq_handler(int irq, void *dev_id)
480{
481 struct csis_state *state = dev_id;
482 u32 val;
483
484 /* Just clear the interrupt pending bits. */
485 val = s5pcsis_read(state, S5PCSIS_INTSRC);
486 s5pcsis_write(state, S5PCSIS_INTSRC, val);
487
488 return IRQ_HANDLED;
489}
490
491static int __devinit s5pcsis_probe(struct platform_device *pdev)
492{
493 struct s5p_platform_mipi_csis *pdata;
494 struct resource *mem_res;
495 struct csis_state *state;
496 int ret = -ENOMEM;
497 int i;
498
499 state = devm_kzalloc(&pdev->dev, sizeof(*state), GFP_KERNEL);
500 if (!state)
501 return -ENOMEM;
502
503 mutex_init(&state->lock);
504 state->pdev = pdev;
505
506 pdata = pdev->dev.platform_data;
507 if (pdata == NULL || pdata->phy_enable == NULL) {
508 dev_err(&pdev->dev, "Platform data not fully specified\n");
509 return -EINVAL;
510 }
511
512 if ((pdev->id == 1 && pdata->lanes > CSIS1_MAX_LANES) ||
513 pdata->lanes > CSIS0_MAX_LANES) {
514 dev_err(&pdev->dev, "Unsupported number of data lanes: %d\n",
515 pdata->lanes);
516 return -EINVAL;
517 }
518
519 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
520 state->regs = devm_request_and_ioremap(&pdev->dev, mem_res);
521 if (state->regs == NULL) {
522 dev_err(&pdev->dev, "Failed to request and remap io memory\n");
523 return -ENXIO;
524 }
525
526 state->irq = platform_get_irq(pdev, 0);
527 if (state->irq < 0) {
528 dev_err(&pdev->dev, "Failed to get irq\n");
529 return state->irq;
530 }
531
532 for (i = 0; i < CSIS_NUM_SUPPLIES; i++)
533 state->supplies[i].supply = csis_supply_name[i];
534
535 ret = regulator_bulk_get(&pdev->dev, CSIS_NUM_SUPPLIES,
536 state->supplies);
537 if (ret)
538 return ret;
539
540 ret = s5pcsis_clk_get(state);
541 if (ret)
542 goto e_clkput;
543
544 clk_enable(state->clock[CSIS_CLK_MUX]);
545 if (pdata->clk_rate)
546 clk_set_rate(state->clock[CSIS_CLK_MUX], pdata->clk_rate);
547 else
548 dev_WARN(&pdev->dev, "No clock frequency specified!\n");
549
550 ret = devm_request_irq(&pdev->dev, state->irq, s5pcsis_irq_handler,
551 0, dev_name(&pdev->dev), state);
552 if (ret) {
553 dev_err(&pdev->dev, "Interrupt request failed\n");
554 goto e_regput;
555 }
556
557 v4l2_subdev_init(&state->sd, &s5pcsis_subdev_ops);
558 state->sd.owner = THIS_MODULE;
559 strlcpy(state->sd.name, dev_name(&pdev->dev), sizeof(state->sd.name));
560 state->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
561 state->csis_fmt = &s5pcsis_formats[0];
562
563 state->format.code = s5pcsis_formats[0].code;
564 state->format.width = S5PCSIS_DEF_PIX_WIDTH;
565 state->format.height = S5PCSIS_DEF_PIX_HEIGHT;
566
567 state->pads[CSIS_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
568 state->pads[CSIS_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
569 ret = media_entity_init(&state->sd.entity,
570 CSIS_PADS_NUM, state->pads, 0);
571 if (ret < 0)
572 goto e_clkput;
573
574 /* This allows to retrieve the platform device id by the host driver */
575 v4l2_set_subdevdata(&state->sd, pdev);
576
577 /* .. and a pointer to the subdev. */
578 platform_set_drvdata(pdev, &state->sd);
579
580 pm_runtime_enable(&pdev->dev);
581 return 0;
582
583e_regput:
584 regulator_bulk_free(CSIS_NUM_SUPPLIES, state->supplies);
585e_clkput:
586 clk_disable(state->clock[CSIS_CLK_MUX]);
587 s5pcsis_clk_put(state);
588 return ret;
589}
590
591static int s5pcsis_pm_suspend(struct device *dev, bool runtime)
592{
593 struct s5p_platform_mipi_csis *pdata = dev->platform_data;
594 struct platform_device *pdev = to_platform_device(dev);
595 struct v4l2_subdev *sd = platform_get_drvdata(pdev);
596 struct csis_state *state = sd_to_csis_state(sd);
597 int ret = 0;
598
599 v4l2_dbg(1, debug, sd, "%s: flags: 0x%x\n",
600 __func__, state->flags);
601
602 mutex_lock(&state->lock);
603 if (state->flags & ST_POWERED) {
604 s5pcsis_stop_stream(state);
605 ret = pdata->phy_enable(state->pdev, false);
606 if (ret)
607 goto unlock;
608 ret = regulator_bulk_disable(CSIS_NUM_SUPPLIES,
609 state->supplies);
610 if (ret)
611 goto unlock;
612 clk_disable(state->clock[CSIS_CLK_GATE]);
613 state->flags &= ~ST_POWERED;
614 if (!runtime)
615 state->flags |= ST_SUSPENDED;
616 }
617 unlock:
618 mutex_unlock(&state->lock);
619 return ret ? -EAGAIN : 0;
620}
621
622static int s5pcsis_pm_resume(struct device *dev, bool runtime)
623{
624 struct s5p_platform_mipi_csis *pdata = dev->platform_data;
625 struct platform_device *pdev = to_platform_device(dev);
626 struct v4l2_subdev *sd = platform_get_drvdata(pdev);
627 struct csis_state *state = sd_to_csis_state(sd);
628 int ret = 0;
629
630 v4l2_dbg(1, debug, sd, "%s: flags: 0x%x\n",
631 __func__, state->flags);
632
633 mutex_lock(&state->lock);
634 if (!runtime && !(state->flags & ST_SUSPENDED))
635 goto unlock;
636
637 if (!(state->flags & ST_POWERED)) {
638 ret = regulator_bulk_enable(CSIS_NUM_SUPPLIES,
639 state->supplies);
640 if (ret)
641 goto unlock;
642 ret = pdata->phy_enable(state->pdev, true);
643 if (!ret) {
644 state->flags |= ST_POWERED;
645 } else {
646 regulator_bulk_disable(CSIS_NUM_SUPPLIES,
647 state->supplies);
648 goto unlock;
649 }
650 clk_enable(state->clock[CSIS_CLK_GATE]);
651 }
652 if (state->flags & ST_STREAMING)
653 s5pcsis_start_stream(state);
654
655 state->flags &= ~ST_SUSPENDED;
656 unlock:
657 mutex_unlock(&state->lock);
658 return ret ? -EAGAIN : 0;
659}
660
661#ifdef CONFIG_PM_SLEEP
662static int s5pcsis_suspend(struct device *dev)
663{
664 return s5pcsis_pm_suspend(dev, false);
665}
666
667static int s5pcsis_resume(struct device *dev)
668{
669 return s5pcsis_pm_resume(dev, false);
670}
671#endif
672
673#ifdef CONFIG_PM_RUNTIME
674static int s5pcsis_runtime_suspend(struct device *dev)
675{
676 return s5pcsis_pm_suspend(dev, true);
677}
678
679static int s5pcsis_runtime_resume(struct device *dev)
680{
681 return s5pcsis_pm_resume(dev, true);
682}
683#endif
684
685static int __devexit s5pcsis_remove(struct platform_device *pdev)
686{
687 struct v4l2_subdev *sd = platform_get_drvdata(pdev);
688 struct csis_state *state = sd_to_csis_state(sd);
689
690 pm_runtime_disable(&pdev->dev);
691 s5pcsis_pm_suspend(&pdev->dev, false);
692 clk_disable(state->clock[CSIS_CLK_MUX]);
693 pm_runtime_set_suspended(&pdev->dev);
694 s5pcsis_clk_put(state);
695 regulator_bulk_free(CSIS_NUM_SUPPLIES, state->supplies);
696
697 media_entity_cleanup(&state->sd.entity);
698
699 return 0;
700}
701
702static const struct dev_pm_ops s5pcsis_pm_ops = {
703 SET_RUNTIME_PM_OPS(s5pcsis_runtime_suspend, s5pcsis_runtime_resume,
704 NULL)
705 SET_SYSTEM_SLEEP_PM_OPS(s5pcsis_suspend, s5pcsis_resume)
706};
707
708static struct platform_driver s5pcsis_driver = {
709 .probe = s5pcsis_probe,
710 .remove = __devexit_p(s5pcsis_remove),
711 .driver = {
712 .name = CSIS_DRIVER_NAME,
713 .owner = THIS_MODULE,
714 .pm = &s5pcsis_pm_ops,
715 },
716};
717
718module_platform_driver(s5pcsis_driver);
719
720MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
721MODULE_DESCRIPTION("Samsung S5P/EXYNOS SoC MIPI-CSI2 receiver driver");
722MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/s5p-fimc/mipi-csis.h b/drivers/media/video/s5p-fimc/mipi-csis.h
deleted file mode 100644
index 2709286396e1..000000000000
--- a/drivers/media/video/s5p-fimc/mipi-csis.h
+++ /dev/null
@@ -1,25 +0,0 @@
1/*
2 * Samsung S5P/EXYNOS4 SoC series MIPI-CSI receiver driver
3 *
4 * Copyright (C) 2011 Samsung Electronics Co., Ltd.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#ifndef S5P_MIPI_CSIS_H_
11#define S5P_MIPI_CSIS_H_
12
13#define CSIS_DRIVER_NAME "s5p-mipi-csis"
14#define CSIS_MAX_ENTITIES 2
15#define CSIS0_MAX_LANES 4
16#define CSIS1_MAX_LANES 2
17
18#define CSIS_PAD_SINK 0
19#define CSIS_PAD_SOURCE 1
20#define CSIS_PADS_NUM 2
21
22#define S5PCSIS_DEF_PIX_WIDTH 640
23#define S5PCSIS_DEF_PIX_HEIGHT 480
24
25#endif
diff --git a/drivers/media/video/s5p-g2d/Makefile b/drivers/media/video/s5p-g2d/Makefile
deleted file mode 100644
index 2c48c416a804..000000000000
--- a/drivers/media/video/s5p-g2d/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
1s5p-g2d-objs := g2d.o g2d-hw.o
2
3obj-$(CONFIG_VIDEO_SAMSUNG_S5P_G2D) += s5p-g2d.o
diff --git a/drivers/media/video/s5p-g2d/g2d-hw.c b/drivers/media/video/s5p-g2d/g2d-hw.c
deleted file mode 100644
index 5b86cbe408e2..000000000000
--- a/drivers/media/video/s5p-g2d/g2d-hw.c
+++ /dev/null
@@ -1,109 +0,0 @@
1/*
2 * Samsung S5P G2D - 2D Graphics Accelerator Driver
3 *
4 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
5 * Kamil Debski, <k.debski@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the
10 * License, or (at your option) any later version
11 */
12
13#include <linux/io.h>
14
15#include "g2d.h"
16#include "g2d-regs.h"
17
18#define w(x, a) writel((x), d->regs + (a))
19#define r(a) readl(d->regs + (a))
20
21/* g2d_reset clears all g2d registers */
22void g2d_reset(struct g2d_dev *d)
23{
24 w(1, SOFT_RESET_REG);
25}
26
27void g2d_set_src_size(struct g2d_dev *d, struct g2d_frame *f)
28{
29 u32 n;
30
31 w(f->stride & 0xFFFF, SRC_STRIDE_REG);
32
33 n = f->o_height & 0xFFF;
34 n <<= 16;
35 n |= f->o_width & 0xFFF;
36 w(n, SRC_LEFT_TOP_REG);
37
38 n = f->bottom & 0xFFF;
39 n <<= 16;
40 n |= f->right & 0xFFF;
41 w(n, SRC_RIGHT_BOTTOM_REG);
42
43 w(f->fmt->hw, SRC_COLOR_MODE_REG);
44}
45
46void g2d_set_src_addr(struct g2d_dev *d, dma_addr_t a)
47{
48 w(a, SRC_BASE_ADDR_REG);
49}
50
51void g2d_set_dst_size(struct g2d_dev *d, struct g2d_frame *f)
52{
53 u32 n;
54
55 w(f->stride & 0xFFFF, DST_STRIDE_REG);
56
57 n = f->o_height & 0xFFF;
58 n <<= 16;
59 n |= f->o_width & 0xFFF;
60 w(n, DST_LEFT_TOP_REG);
61
62 n = f->bottom & 0xFFF;
63 n <<= 16;
64 n |= f->right & 0xFFF;
65 w(n, DST_RIGHT_BOTTOM_REG);
66
67 w(f->fmt->hw, DST_COLOR_MODE_REG);
68}
69
70void g2d_set_dst_addr(struct g2d_dev *d, dma_addr_t a)
71{
72 w(a, DST_BASE_ADDR_REG);
73}
74
75void g2d_set_rop4(struct g2d_dev *d, u32 r)
76{
77 w(r, ROP4_REG);
78}
79
80void g2d_set_flip(struct g2d_dev *d, u32 r)
81{
82 w(r, SRC_MSK_DIRECT_REG);
83}
84
85u32 g2d_cmd_stretch(u32 e)
86{
87 e &= 1;
88 return e << 4;
89}
90
91void g2d_set_cmd(struct g2d_dev *d, u32 c)
92{
93 w(c, BITBLT_COMMAND_REG);
94}
95
96void g2d_start(struct g2d_dev *d)
97{
98 /* Clear cache */
99 w(0x7, CACHECTL_REG);
100 /* Enable interrupt */
101 w(1, INTEN_REG);
102 /* Start G2D engine */
103 w(1, BITBLT_START_REG);
104}
105
106void g2d_clear_int(struct g2d_dev *d)
107{
108 w(1, INTC_PEND_REG);
109}
diff --git a/drivers/media/video/s5p-g2d/g2d-regs.h b/drivers/media/video/s5p-g2d/g2d-regs.h
deleted file mode 100644
index 02e1cf50da4e..000000000000
--- a/drivers/media/video/s5p-g2d/g2d-regs.h
+++ /dev/null
@@ -1,115 +0,0 @@
1/*
2 * Samsung S5P G2D - 2D Graphics Accelerator Driver
3 *
4 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
5 * Kamil Debski, <k.debski@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the
10 * License, or (at your option) any later version
11 */
12
13/* General Registers */
14#define SOFT_RESET_REG 0x0000 /* Software reset reg */
15#define INTEN_REG 0x0004 /* Interrupt Enable reg */
16#define INTC_PEND_REG 0x000C /* Interrupt Control Pending reg */
17#define FIFO_STAT_REG 0x0010 /* Command FIFO Status reg */
18#define AXI_ID_MODE_REG 0x0014 /* AXI Read ID Mode reg */
19#define CACHECTL_REG 0x0018 /* Cache & Buffer clear reg */
20#define AXI_MODE_REG 0x001C /* AXI Mode reg */
21
22/* Command Registers */
23#define BITBLT_START_REG 0x0100 /* BitBLT Start reg */
24#define BITBLT_COMMAND_REG 0x0104 /* Command reg for BitBLT */
25
26/* Parameter Setting Registers (Rotate & Direction) */
27#define ROTATE_REG 0x0200 /* Rotation reg */
28#define SRC_MSK_DIRECT_REG 0x0204 /* Src and Mask Direction reg */
29#define DST_PAT_DIRECT_REG 0x0208 /* Dest and Pattern Direction reg */
30
31/* Parameter Setting Registers (Src) */
32#define SRC_SELECT_REG 0x0300 /* Src Image Selection reg */
33#define SRC_BASE_ADDR_REG 0x0304 /* Src Image Base Address reg */
34#define SRC_STRIDE_REG 0x0308 /* Src Stride reg */
35#define SRC_COLOR_MODE_REG 0x030C /* Src Image Color Mode reg */
36#define SRC_LEFT_TOP_REG 0x0310 /* Src Left Top Coordinate reg */
37#define SRC_RIGHT_BOTTOM_REG 0x0314 /* Src Right Bottom Coordinate reg */
38
39/* Parameter Setting Registers (Dest) */
40#define DST_SELECT_REG 0x0400 /* Dest Image Selection reg */
41#define DST_BASE_ADDR_REG 0x0404 /* Dest Image Base Address reg */
42#define DST_STRIDE_REG 0x0408 /* Dest Stride reg */
43#define DST_COLOR_MODE_REG 0x040C /* Dest Image Color Mode reg */
44#define DST_LEFT_TOP_REG 0x0410 /* Dest Left Top Coordinate reg */
45#define DST_RIGHT_BOTTOM_REG 0x0414 /* Dest Right Bottom Coordinate reg */
46
47/* Parameter Setting Registers (Pattern) */
48#define PAT_BASE_ADDR_REG 0x0500 /* Pattern Image Base Address reg */
49#define PAT_SIZE_REG 0x0504 /* Pattern Image Size reg */
50#define PAT_COLOR_MODE_REG 0x0508 /* Pattern Image Color Mode reg */
51#define PAT_OFFSET_REG 0x050C /* Pattern Left Top Coordinate reg */
52#define PAT_STRIDE_REG 0x0510 /* Pattern Stride reg */
53
54/* Parameter Setting Registers (Mask) */
55#define MASK_BASE_ADDR_REG 0x0520 /* Mask Base Address reg */
56#define MASK_STRIDE_REG 0x0524 /* Mask Stride reg */
57
58/* Parameter Setting Registers (Clipping Window) */
59#define CW_LT_REG 0x0600 /* LeftTop coordinates of Clip Window */
60#define CW_RB_REG 0x0604 /* RightBottom coordinates of Clip
61 Window */
62
63/* Parameter Setting Registers (ROP & Alpha Setting) */
64#define THIRD_OPERAND_REG 0x0610 /* Third Operand Selection reg */
65#define ROP4_REG 0x0614 /* Raster Operation reg */
66#define ALPHA_REG 0x0618 /* Alpha value, Fading offset value */
67
68/* Parameter Setting Registers (Color) */
69#define FG_COLOR_REG 0x0700 /* Foreground Color reg */
70#define BG_COLOR_REG 0x0704 /* Background Color reg */
71#define BS_COLOR_REG 0x0708 /* Blue Screen Color reg */
72
73/* Parameter Setting Registers (Color Key) */
74#define SRC_COLORKEY_CTRL_REG 0x0710 /* Src Colorkey control reg */
75#define SRC_COLORKEY_DR_MIN_REG 0x0714 /* Src Colorkey Decision Reference
76 Min reg */
77#define SRC_COLORKEY_DR_MAX_REG 0x0718 /* Src Colorkey Decision Reference
78 Max reg */
79#define DST_COLORKEY_CTRL_REG 0x071C /* Dest Colorkey control reg */
80#define DST_COLORKEY_DR_MIN_REG 0x0720 /* Dest Colorkey Decision Reference
81 Min reg */
82#define DST_COLORKEY_DR_MAX_REG 0x0724 /* Dest Colorkey Decision Reference
83 Max reg */
84
85/* Color mode values */
86
87#define ORDER_XRGB 0
88#define ORDER_RGBX 1
89#define ORDER_XBGR 2
90#define ORDER_BGRX 3
91
92#define MODE_XRGB_8888 0
93#define MODE_ARGB_8888 1
94#define MODE_RGB_565 2
95#define MODE_XRGB_1555 3
96#define MODE_ARGB_1555 4
97#define MODE_XRGB_4444 5
98#define MODE_ARGB_4444 6
99#define MODE_PACKED_RGB_888 7
100
101#define COLOR_MODE(o, m) (((o) << 4) | (m))
102
103/* ROP4 operation values */
104#define ROP4_COPY 0xCCCC
105#define ROP4_INVERT 0x3333
106
107/* Hardware limits */
108#define MAX_WIDTH 8000
109#define MAX_HEIGHT 8000
110
111#define G2D_TIMEOUT 500
112
113#define DEFAULT_WIDTH 100
114#define DEFAULT_HEIGHT 100
115
diff --git a/drivers/media/video/s5p-g2d/g2d.c b/drivers/media/video/s5p-g2d/g2d.c
deleted file mode 100644
index 0edc2df98732..000000000000
--- a/drivers/media/video/s5p-g2d/g2d.c
+++ /dev/null
@@ -1,847 +0,0 @@
1/*
2 * Samsung S5P G2D - 2D Graphics Accelerator Driver
3 *
4 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
5 * Kamil Debski, <k.debski@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the
10 * License, or (at your option) any later version
11 */
12
13#include <linux/module.h>
14#include <linux/fs.h>
15#include <linux/version.h>
16#include <linux/timer.h>
17#include <linux/sched.h>
18#include <linux/slab.h>
19#include <linux/clk.h>
20#include <linux/interrupt.h>
21
22#include <linux/platform_device.h>
23#include <media/v4l2-mem2mem.h>
24#include <media/v4l2-device.h>
25#include <media/v4l2-ioctl.h>
26#include <media/videobuf2-core.h>
27#include <media/videobuf2-dma-contig.h>
28
29#include "g2d.h"
30#include "g2d-regs.h"
31
32#define fh2ctx(__fh) container_of(__fh, struct g2d_ctx, fh)
33
34static struct g2d_fmt formats[] = {
35 {
36 .name = "XRGB_8888",
37 .fourcc = V4L2_PIX_FMT_RGB32,
38 .depth = 32,
39 .hw = COLOR_MODE(ORDER_XRGB, MODE_XRGB_8888),
40 },
41 {
42 .name = "RGB_565",
43 .fourcc = V4L2_PIX_FMT_RGB565X,
44 .depth = 16,
45 .hw = COLOR_MODE(ORDER_XRGB, MODE_RGB_565),
46 },
47 {
48 .name = "XRGB_1555",
49 .fourcc = V4L2_PIX_FMT_RGB555X,
50 .depth = 16,
51 .hw = COLOR_MODE(ORDER_XRGB, MODE_XRGB_1555),
52 },
53 {
54 .name = "XRGB_4444",
55 .fourcc = V4L2_PIX_FMT_RGB444,
56 .depth = 16,
57 .hw = COLOR_MODE(ORDER_XRGB, MODE_XRGB_4444),
58 },
59 {
60 .name = "PACKED_RGB_888",
61 .fourcc = V4L2_PIX_FMT_RGB24,
62 .depth = 24,
63 .hw = COLOR_MODE(ORDER_XRGB, MODE_PACKED_RGB_888),
64 },
65};
66#define NUM_FORMATS ARRAY_SIZE(formats)
67
68static struct g2d_frame def_frame = {
69 .width = DEFAULT_WIDTH,
70 .height = DEFAULT_HEIGHT,
71 .c_width = DEFAULT_WIDTH,
72 .c_height = DEFAULT_HEIGHT,
73 .o_width = 0,
74 .o_height = 0,
75 .fmt = &formats[0],
76 .right = DEFAULT_WIDTH,
77 .bottom = DEFAULT_HEIGHT,
78};
79
80static struct g2d_fmt *find_fmt(struct v4l2_format *f)
81{
82 unsigned int i;
83 for (i = 0; i < NUM_FORMATS; i++) {
84 if (formats[i].fourcc == f->fmt.pix.pixelformat)
85 return &formats[i];
86 }
87 return NULL;
88}
89
90
91static struct g2d_frame *get_frame(struct g2d_ctx *ctx,
92 enum v4l2_buf_type type)
93{
94 switch (type) {
95 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
96 return &ctx->in;
97 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
98 return &ctx->out;
99 default:
100 return ERR_PTR(-EINVAL);
101 }
102}
103
104static int g2d_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
105 unsigned int *nbuffers, unsigned int *nplanes,
106 unsigned int sizes[], void *alloc_ctxs[])
107{
108 struct g2d_ctx *ctx = vb2_get_drv_priv(vq);
109 struct g2d_frame *f = get_frame(ctx, vq->type);
110
111 if (IS_ERR(f))
112 return PTR_ERR(f);
113
114 sizes[0] = f->size;
115 *nplanes = 1;
116 alloc_ctxs[0] = ctx->dev->alloc_ctx;
117
118 if (*nbuffers == 0)
119 *nbuffers = 1;
120
121 return 0;
122}
123
124static int g2d_buf_prepare(struct vb2_buffer *vb)
125{
126 struct g2d_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
127 struct g2d_frame *f = get_frame(ctx, vb->vb2_queue->type);
128
129 if (IS_ERR(f))
130 return PTR_ERR(f);
131 vb2_set_plane_payload(vb, 0, f->size);
132 return 0;
133}
134
135static void g2d_buf_queue(struct vb2_buffer *vb)
136{
137 struct g2d_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
138 v4l2_m2m_buf_queue(ctx->m2m_ctx, vb);
139}
140
141
142static struct vb2_ops g2d_qops = {
143 .queue_setup = g2d_queue_setup,
144 .buf_prepare = g2d_buf_prepare,
145 .buf_queue = g2d_buf_queue,
146};
147
148static int queue_init(void *priv, struct vb2_queue *src_vq,
149 struct vb2_queue *dst_vq)
150{
151 struct g2d_ctx *ctx = priv;
152 int ret;
153
154 memset(src_vq, 0, sizeof(*src_vq));
155 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
156 src_vq->io_modes = VB2_MMAP | VB2_USERPTR;
157 src_vq->drv_priv = ctx;
158 src_vq->ops = &g2d_qops;
159 src_vq->mem_ops = &vb2_dma_contig_memops;
160 src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
161
162 ret = vb2_queue_init(src_vq);
163 if (ret)
164 return ret;
165
166 memset(dst_vq, 0, sizeof(*dst_vq));
167 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
168 dst_vq->io_modes = VB2_MMAP | VB2_USERPTR;
169 dst_vq->drv_priv = ctx;
170 dst_vq->ops = &g2d_qops;
171 dst_vq->mem_ops = &vb2_dma_contig_memops;
172 dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
173
174 return vb2_queue_init(dst_vq);
175}
176
177static int g2d_s_ctrl(struct v4l2_ctrl *ctrl)
178{
179 struct g2d_ctx *ctx = container_of(ctrl->handler, struct g2d_ctx,
180 ctrl_handler);
181 unsigned long flags;
182
183 spin_lock_irqsave(&ctx->dev->ctrl_lock, flags);
184 switch (ctrl->id) {
185 case V4L2_CID_COLORFX:
186 if (ctrl->val == V4L2_COLORFX_NEGATIVE)
187 ctx->rop = ROP4_INVERT;
188 else
189 ctx->rop = ROP4_COPY;
190 break;
191
192 case V4L2_CID_HFLIP:
193 ctx->flip = ctx->ctrl_hflip->val | (ctx->ctrl_vflip->val << 1);
194 break;
195
196 }
197 spin_unlock_irqrestore(&ctx->dev->ctrl_lock, flags);
198 return 0;
199}
200
201static const struct v4l2_ctrl_ops g2d_ctrl_ops = {
202 .s_ctrl = g2d_s_ctrl,
203};
204
205static int g2d_setup_ctrls(struct g2d_ctx *ctx)
206{
207 struct g2d_dev *dev = ctx->dev;
208
209 v4l2_ctrl_handler_init(&ctx->ctrl_handler, 3);
210
211 ctx->ctrl_hflip = v4l2_ctrl_new_std(&ctx->ctrl_handler, &g2d_ctrl_ops,
212 V4L2_CID_HFLIP, 0, 1, 1, 0);
213
214 ctx->ctrl_vflip = v4l2_ctrl_new_std(&ctx->ctrl_handler, &g2d_ctrl_ops,
215 V4L2_CID_VFLIP, 0, 1, 1, 0);
216
217 v4l2_ctrl_new_std_menu(
218 &ctx->ctrl_handler,
219 &g2d_ctrl_ops,
220 V4L2_CID_COLORFX,
221 V4L2_COLORFX_NEGATIVE,
222 ~((1 << V4L2_COLORFX_NONE) | (1 << V4L2_COLORFX_NEGATIVE)),
223 V4L2_COLORFX_NONE);
224
225 if (ctx->ctrl_handler.error) {
226 int err = ctx->ctrl_handler.error;
227 v4l2_err(&dev->v4l2_dev, "g2d_setup_ctrls failed\n");
228 v4l2_ctrl_handler_free(&ctx->ctrl_handler);
229 return err;
230 }
231
232 v4l2_ctrl_cluster(2, &ctx->ctrl_hflip);
233
234 return 0;
235}
236
237static int g2d_open(struct file *file)
238{
239 struct g2d_dev *dev = video_drvdata(file);
240 struct g2d_ctx *ctx = NULL;
241 int ret = 0;
242
243 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
244 if (!ctx)
245 return -ENOMEM;
246 ctx->dev = dev;
247 /* Set default formats */
248 ctx->in = def_frame;
249 ctx->out = def_frame;
250
251 if (mutex_lock_interruptible(&dev->mutex)) {
252 kfree(ctx);
253 return -ERESTARTSYS;
254 }
255 ctx->m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx, &queue_init);
256 if (IS_ERR(ctx->m2m_ctx)) {
257 ret = PTR_ERR(ctx->m2m_ctx);
258 mutex_unlock(&dev->mutex);
259 kfree(ctx);
260 return ret;
261 }
262 v4l2_fh_init(&ctx->fh, video_devdata(file));
263 file->private_data = &ctx->fh;
264 v4l2_fh_add(&ctx->fh);
265
266 g2d_setup_ctrls(ctx);
267
268 /* Write the default values to the ctx struct */
269 v4l2_ctrl_handler_setup(&ctx->ctrl_handler);
270
271 ctx->fh.ctrl_handler = &ctx->ctrl_handler;
272 mutex_unlock(&dev->mutex);
273
274 v4l2_info(&dev->v4l2_dev, "instance opened\n");
275 return 0;
276}
277
278static int g2d_release(struct file *file)
279{
280 struct g2d_dev *dev = video_drvdata(file);
281 struct g2d_ctx *ctx = fh2ctx(file->private_data);
282
283 v4l2_ctrl_handler_free(&ctx->ctrl_handler);
284 v4l2_fh_del(&ctx->fh);
285 v4l2_fh_exit(&ctx->fh);
286 kfree(ctx);
287 v4l2_info(&dev->v4l2_dev, "instance closed\n");
288 return 0;
289}
290
291
292static int vidioc_querycap(struct file *file, void *priv,
293 struct v4l2_capability *cap)
294{
295 strncpy(cap->driver, G2D_NAME, sizeof(cap->driver) - 1);
296 strncpy(cap->card, G2D_NAME, sizeof(cap->card) - 1);
297 cap->bus_info[0] = 0;
298 cap->version = KERNEL_VERSION(1, 0, 0);
299 /*
300 * This is only a mem-to-mem video device. The capture and output
301 * device capability flags are left only for backward compatibility
302 * and are scheduled for removal.
303 */
304 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT |
305 V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING;
306 return 0;
307}
308
309static int vidioc_enum_fmt(struct file *file, void *prv, struct v4l2_fmtdesc *f)
310{
311 struct g2d_fmt *fmt;
312 if (f->index >= NUM_FORMATS)
313 return -EINVAL;
314 fmt = &formats[f->index];
315 f->pixelformat = fmt->fourcc;
316 strncpy(f->description, fmt->name, sizeof(f->description) - 1);
317 return 0;
318}
319
320static int vidioc_g_fmt(struct file *file, void *prv, struct v4l2_format *f)
321{
322 struct g2d_ctx *ctx = prv;
323 struct vb2_queue *vq;
324 struct g2d_frame *frm;
325
326 vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
327 if (!vq)
328 return -EINVAL;
329 frm = get_frame(ctx, f->type);
330 if (IS_ERR(frm))
331 return PTR_ERR(frm);
332
333 f->fmt.pix.width = frm->width;
334 f->fmt.pix.height = frm->height;
335 f->fmt.pix.field = V4L2_FIELD_NONE;
336 f->fmt.pix.pixelformat = frm->fmt->fourcc;
337 f->fmt.pix.bytesperline = (frm->width * frm->fmt->depth) >> 3;
338 f->fmt.pix.sizeimage = frm->size;
339 return 0;
340}
341
342static int vidioc_try_fmt(struct file *file, void *prv, struct v4l2_format *f)
343{
344 struct g2d_fmt *fmt;
345 enum v4l2_field *field;
346
347 fmt = find_fmt(f);
348 if (!fmt)
349 return -EINVAL;
350
351 field = &f->fmt.pix.field;
352 if (*field == V4L2_FIELD_ANY)
353 *field = V4L2_FIELD_NONE;
354 else if (*field != V4L2_FIELD_NONE)
355 return -EINVAL;
356
357 if (f->fmt.pix.width > MAX_WIDTH)
358 f->fmt.pix.width = MAX_WIDTH;
359 if (f->fmt.pix.height > MAX_HEIGHT)
360 f->fmt.pix.height = MAX_HEIGHT;
361
362 if (f->fmt.pix.width < 1)
363 f->fmt.pix.width = 1;
364 if (f->fmt.pix.height < 1)
365 f->fmt.pix.height = 1;
366
367 f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
368 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
369 return 0;
370}
371
372static int vidioc_s_fmt(struct file *file, void *prv, struct v4l2_format *f)
373{
374 struct g2d_ctx *ctx = prv;
375 struct g2d_dev *dev = ctx->dev;
376 struct vb2_queue *vq;
377 struct g2d_frame *frm;
378 struct g2d_fmt *fmt;
379 int ret = 0;
380
381 /* Adjust all values accordingly to the hardware capabilities
382 * and chosen format. */
383 ret = vidioc_try_fmt(file, prv, f);
384 if (ret)
385 return ret;
386 vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
387 if (vb2_is_busy(vq)) {
388 v4l2_err(&dev->v4l2_dev, "queue (%d) bust\n", f->type);
389 return -EBUSY;
390 }
391 frm = get_frame(ctx, f->type);
392 if (IS_ERR(frm))
393 return PTR_ERR(frm);
394 fmt = find_fmt(f);
395 if (!fmt)
396 return -EINVAL;
397 frm->width = f->fmt.pix.width;
398 frm->height = f->fmt.pix.height;
399 frm->size = f->fmt.pix.sizeimage;
400 /* Reset crop settings */
401 frm->o_width = 0;
402 frm->o_height = 0;
403 frm->c_width = frm->width;
404 frm->c_height = frm->height;
405 frm->right = frm->width;
406 frm->bottom = frm->height;
407 frm->fmt = fmt;
408 frm->stride = f->fmt.pix.bytesperline;
409 return 0;
410}
411
412static unsigned int g2d_poll(struct file *file, struct poll_table_struct *wait)
413{
414 struct g2d_ctx *ctx = fh2ctx(file->private_data);
415 struct g2d_dev *dev = ctx->dev;
416 unsigned int res;
417
418 mutex_lock(&dev->mutex);
419 res = v4l2_m2m_poll(file, ctx->m2m_ctx, wait);
420 mutex_unlock(&dev->mutex);
421 return res;
422}
423
424static int g2d_mmap(struct file *file, struct vm_area_struct *vma)
425{
426 struct g2d_ctx *ctx = fh2ctx(file->private_data);
427 struct g2d_dev *dev = ctx->dev;
428 int ret;
429
430 if (mutex_lock_interruptible(&dev->mutex))
431 return -ERESTARTSYS;
432 ret = v4l2_m2m_mmap(file, ctx->m2m_ctx, vma);
433 mutex_unlock(&dev->mutex);
434 return ret;
435}
436
437static int vidioc_reqbufs(struct file *file, void *priv,
438 struct v4l2_requestbuffers *reqbufs)
439{
440 struct g2d_ctx *ctx = priv;
441 return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs);
442}
443
444static int vidioc_querybuf(struct file *file, void *priv,
445 struct v4l2_buffer *buf)
446{
447 struct g2d_ctx *ctx = priv;
448 return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf);
449}
450
451static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
452{
453 struct g2d_ctx *ctx = priv;
454 return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
455}
456
457static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
458{
459 struct g2d_ctx *ctx = priv;
460 return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
461}
462
463
464static int vidioc_streamon(struct file *file, void *priv,
465 enum v4l2_buf_type type)
466{
467 struct g2d_ctx *ctx = priv;
468 return v4l2_m2m_streamon(file, ctx->m2m_ctx, type);
469}
470
471static int vidioc_streamoff(struct file *file, void *priv,
472 enum v4l2_buf_type type)
473{
474 struct g2d_ctx *ctx = priv;
475 return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type);
476}
477
478static int vidioc_cropcap(struct file *file, void *priv,
479 struct v4l2_cropcap *cr)
480{
481 struct g2d_ctx *ctx = priv;
482 struct g2d_frame *f;
483
484 f = get_frame(ctx, cr->type);
485 if (IS_ERR(f))
486 return PTR_ERR(f);
487
488 cr->bounds.left = 0;
489 cr->bounds.top = 0;
490 cr->bounds.width = f->width;
491 cr->bounds.height = f->height;
492 cr->defrect = cr->bounds;
493 return 0;
494}
495
496static int vidioc_g_crop(struct file *file, void *prv, struct v4l2_crop *cr)
497{
498 struct g2d_ctx *ctx = prv;
499 struct g2d_frame *f;
500
501 f = get_frame(ctx, cr->type);
502 if (IS_ERR(f))
503 return PTR_ERR(f);
504
505 cr->c.left = f->o_height;
506 cr->c.top = f->o_width;
507 cr->c.width = f->c_width;
508 cr->c.height = f->c_height;
509 return 0;
510}
511
512static int vidioc_try_crop(struct file *file, void *prv, struct v4l2_crop *cr)
513{
514 struct g2d_ctx *ctx = prv;
515 struct g2d_dev *dev = ctx->dev;
516 struct g2d_frame *f;
517
518 f = get_frame(ctx, cr->type);
519 if (IS_ERR(f))
520 return PTR_ERR(f);
521
522 if (cr->c.top < 0 || cr->c.left < 0) {
523 v4l2_err(&dev->v4l2_dev,
524 "doesn't support negative values for top & left\n");
525 return -EINVAL;
526 }
527
528 return 0;
529}
530
531static int vidioc_s_crop(struct file *file, void *prv, struct v4l2_crop *cr)
532{
533 struct g2d_ctx *ctx = prv;
534 struct g2d_frame *f;
535 int ret;
536
537 ret = vidioc_try_crop(file, prv, cr);
538 if (ret)
539 return ret;
540 f = get_frame(ctx, cr->type);
541 if (IS_ERR(f))
542 return PTR_ERR(f);
543
544 f->c_width = cr->c.width;
545 f->c_height = cr->c.height;
546 f->o_width = cr->c.left;
547 f->o_height = cr->c.top;
548 f->bottom = f->o_height + f->c_height;
549 f->right = f->o_width + f->c_width;
550 return 0;
551}
552
553static void g2d_lock(void *prv)
554{
555 struct g2d_ctx *ctx = prv;
556 struct g2d_dev *dev = ctx->dev;
557 mutex_lock(&dev->mutex);
558}
559
560static void g2d_unlock(void *prv)
561{
562 struct g2d_ctx *ctx = prv;
563 struct g2d_dev *dev = ctx->dev;
564 mutex_unlock(&dev->mutex);
565}
566
567static void job_abort(void *prv)
568{
569 struct g2d_ctx *ctx = prv;
570 struct g2d_dev *dev = ctx->dev;
571 int ret;
572
573 if (dev->curr == NULL) /* No job currently running */
574 return;
575
576 ret = wait_event_timeout(dev->irq_queue,
577 dev->curr == NULL,
578 msecs_to_jiffies(G2D_TIMEOUT));
579}
580
581static void device_run(void *prv)
582{
583 struct g2d_ctx *ctx = prv;
584 struct g2d_dev *dev = ctx->dev;
585 struct vb2_buffer *src, *dst;
586 unsigned long flags;
587 u32 cmd = 0;
588
589 dev->curr = ctx;
590
591 src = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
592 dst = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
593
594 clk_enable(dev->gate);
595 g2d_reset(dev);
596
597 spin_lock_irqsave(&dev->ctrl_lock, flags);
598
599 g2d_set_src_size(dev, &ctx->in);
600 g2d_set_src_addr(dev, vb2_dma_contig_plane_dma_addr(src, 0));
601
602 g2d_set_dst_size(dev, &ctx->out);
603 g2d_set_dst_addr(dev, vb2_dma_contig_plane_dma_addr(dst, 0));
604
605 g2d_set_rop4(dev, ctx->rop);
606 g2d_set_flip(dev, ctx->flip);
607
608 if (ctx->in.c_width != ctx->out.c_width ||
609 ctx->in.c_height != ctx->out.c_height)
610 cmd |= g2d_cmd_stretch(1);
611 g2d_set_cmd(dev, cmd);
612 g2d_start(dev);
613
614 spin_unlock_irqrestore(&dev->ctrl_lock, flags);
615}
616
617static irqreturn_t g2d_isr(int irq, void *prv)
618{
619 struct g2d_dev *dev = prv;
620 struct g2d_ctx *ctx = dev->curr;
621 struct vb2_buffer *src, *dst;
622
623 g2d_clear_int(dev);
624 clk_disable(dev->gate);
625
626 BUG_ON(ctx == NULL);
627
628 src = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
629 dst = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
630
631 BUG_ON(src == NULL);
632 BUG_ON(dst == NULL);
633
634 v4l2_m2m_buf_done(src, VB2_BUF_STATE_DONE);
635 v4l2_m2m_buf_done(dst, VB2_BUF_STATE_DONE);
636 v4l2_m2m_job_finish(dev->m2m_dev, ctx->m2m_ctx);
637
638 dev->curr = NULL;
639 wake_up(&dev->irq_queue);
640 return IRQ_HANDLED;
641}
642
643static const struct v4l2_file_operations g2d_fops = {
644 .owner = THIS_MODULE,
645 .open = g2d_open,
646 .release = g2d_release,
647 .poll = g2d_poll,
648 .unlocked_ioctl = video_ioctl2,
649 .mmap = g2d_mmap,
650};
651
652static const struct v4l2_ioctl_ops g2d_ioctl_ops = {
653 .vidioc_querycap = vidioc_querycap,
654
655 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt,
656 .vidioc_g_fmt_vid_cap = vidioc_g_fmt,
657 .vidioc_try_fmt_vid_cap = vidioc_try_fmt,
658 .vidioc_s_fmt_vid_cap = vidioc_s_fmt,
659
660 .vidioc_enum_fmt_vid_out = vidioc_enum_fmt,
661 .vidioc_g_fmt_vid_out = vidioc_g_fmt,
662 .vidioc_try_fmt_vid_out = vidioc_try_fmt,
663 .vidioc_s_fmt_vid_out = vidioc_s_fmt,
664
665 .vidioc_reqbufs = vidioc_reqbufs,
666 .vidioc_querybuf = vidioc_querybuf,
667
668 .vidioc_qbuf = vidioc_qbuf,
669 .vidioc_dqbuf = vidioc_dqbuf,
670
671 .vidioc_streamon = vidioc_streamon,
672 .vidioc_streamoff = vidioc_streamoff,
673
674 .vidioc_g_crop = vidioc_g_crop,
675 .vidioc_s_crop = vidioc_s_crop,
676 .vidioc_cropcap = vidioc_cropcap,
677};
678
679static struct video_device g2d_videodev = {
680 .name = G2D_NAME,
681 .fops = &g2d_fops,
682 .ioctl_ops = &g2d_ioctl_ops,
683 .minor = -1,
684 .release = video_device_release,
685};
686
687static struct v4l2_m2m_ops g2d_m2m_ops = {
688 .device_run = device_run,
689 .job_abort = job_abort,
690 .lock = g2d_lock,
691 .unlock = g2d_unlock,
692};
693
694static int g2d_probe(struct platform_device *pdev)
695{
696 struct g2d_dev *dev;
697 struct video_device *vfd;
698 struct resource *res;
699 int ret = 0;
700
701 dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
702 if (!dev)
703 return -ENOMEM;
704
705 spin_lock_init(&dev->ctrl_lock);
706 mutex_init(&dev->mutex);
707 atomic_set(&dev->num_inst, 0);
708 init_waitqueue_head(&dev->irq_queue);
709
710 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
711
712 dev->regs = devm_request_and_ioremap(&pdev->dev, res);
713 if (dev->regs == NULL) {
714 dev_err(&pdev->dev, "Failed to obtain io memory\n");
715 return -ENOENT;
716 }
717
718 dev->clk = clk_get(&pdev->dev, "sclk_fimg2d");
719 if (IS_ERR_OR_NULL(dev->clk)) {
720 dev_err(&pdev->dev, "failed to get g2d clock\n");
721 return -ENXIO;
722 }
723
724 ret = clk_prepare(dev->clk);
725 if (ret) {
726 dev_err(&pdev->dev, "failed to prepare g2d clock\n");
727 goto put_clk;
728 }
729
730 dev->gate = clk_get(&pdev->dev, "fimg2d");
731 if (IS_ERR_OR_NULL(dev->gate)) {
732 dev_err(&pdev->dev, "failed to get g2d clock gate\n");
733 ret = -ENXIO;
734 goto unprep_clk;
735 }
736
737 ret = clk_prepare(dev->gate);
738 if (ret) {
739 dev_err(&pdev->dev, "failed to prepare g2d clock gate\n");
740 goto put_clk_gate;
741 }
742
743 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
744 if (!res) {
745 dev_err(&pdev->dev, "failed to find IRQ\n");
746 ret = -ENXIO;
747 goto unprep_clk_gate;
748 }
749
750 dev->irq = res->start;
751
752 ret = devm_request_irq(&pdev->dev, dev->irq, g2d_isr,
753 0, pdev->name, dev);
754 if (ret) {
755 dev_err(&pdev->dev, "failed to install IRQ\n");
756 goto put_clk_gate;
757 }
758
759 dev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
760 if (IS_ERR(dev->alloc_ctx)) {
761 ret = PTR_ERR(dev->alloc_ctx);
762 goto unprep_clk_gate;
763 }
764
765 ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
766 if (ret)
767 goto alloc_ctx_cleanup;
768 vfd = video_device_alloc();
769 if (!vfd) {
770 v4l2_err(&dev->v4l2_dev, "Failed to allocate video device\n");
771 ret = -ENOMEM;
772 goto unreg_v4l2_dev;
773 }
774 *vfd = g2d_videodev;
775 vfd->lock = &dev->mutex;
776 ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
777 if (ret) {
778 v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");
779 goto rel_vdev;
780 }
781 video_set_drvdata(vfd, dev);
782 snprintf(vfd->name, sizeof(vfd->name), "%s", g2d_videodev.name);
783 dev->vfd = vfd;
784 v4l2_info(&dev->v4l2_dev, "device registered as /dev/video%d\n",
785 vfd->num);
786 platform_set_drvdata(pdev, dev);
787 dev->m2m_dev = v4l2_m2m_init(&g2d_m2m_ops);
788 if (IS_ERR(dev->m2m_dev)) {
789 v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem device\n");
790 ret = PTR_ERR(dev->m2m_dev);
791 goto unreg_video_dev;
792 }
793
794 def_frame.stride = (def_frame.width * def_frame.fmt->depth) >> 3;
795
796 return 0;
797
798unreg_video_dev:
799 video_unregister_device(dev->vfd);
800rel_vdev:
801 video_device_release(vfd);
802unreg_v4l2_dev:
803 v4l2_device_unregister(&dev->v4l2_dev);
804alloc_ctx_cleanup:
805 vb2_dma_contig_cleanup_ctx(dev->alloc_ctx);
806unprep_clk_gate:
807 clk_unprepare(dev->gate);
808put_clk_gate:
809 clk_put(dev->gate);
810unprep_clk:
811 clk_unprepare(dev->clk);
812put_clk:
813 clk_put(dev->clk);
814
815 return ret;
816}
817
818static int g2d_remove(struct platform_device *pdev)
819{
820 struct g2d_dev *dev = (struct g2d_dev *)platform_get_drvdata(pdev);
821
822 v4l2_info(&dev->v4l2_dev, "Removing " G2D_NAME);
823 v4l2_m2m_release(dev->m2m_dev);
824 video_unregister_device(dev->vfd);
825 v4l2_device_unregister(&dev->v4l2_dev);
826 vb2_dma_contig_cleanup_ctx(dev->alloc_ctx);
827 clk_unprepare(dev->gate);
828 clk_put(dev->gate);
829 clk_unprepare(dev->clk);
830 clk_put(dev->clk);
831 return 0;
832}
833
834static struct platform_driver g2d_pdrv = {
835 .probe = g2d_probe,
836 .remove = g2d_remove,
837 .driver = {
838 .name = G2D_NAME,
839 .owner = THIS_MODULE,
840 },
841};
842
843module_platform_driver(g2d_pdrv);
844
845MODULE_AUTHOR("Kamil Debski <k.debski@samsung.com>");
846MODULE_DESCRIPTION("S5P G2D 2d graphics accelerator driver");
847MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/s5p-g2d/g2d.h b/drivers/media/video/s5p-g2d/g2d.h
deleted file mode 100644
index 6b765b0216c5..000000000000
--- a/drivers/media/video/s5p-g2d/g2d.h
+++ /dev/null
@@ -1,86 +0,0 @@
1/*
2 * Samsung S5P G2D - 2D Graphics Accelerator Driver
3 *
4 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
5 * Kamil Debski, <k.debski@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the
10 * License, or (at your option) any later version
11 */
12
13#include <media/v4l2-device.h>
14#include <media/v4l2-ctrls.h>
15
16#define G2D_NAME "s5p-g2d"
17
18struct g2d_dev {
19 struct v4l2_device v4l2_dev;
20 struct v4l2_m2m_dev *m2m_dev;
21 struct video_device *vfd;
22 struct mutex mutex;
23 spinlock_t ctrl_lock;
24 atomic_t num_inst;
25 struct vb2_alloc_ctx *alloc_ctx;
26 void __iomem *regs;
27 struct clk *clk;
28 struct clk *gate;
29 struct g2d_ctx *curr;
30 int irq;
31 wait_queue_head_t irq_queue;
32};
33
34struct g2d_frame {
35 /* Original dimensions */
36 u32 width;
37 u32 height;
38 /* Crop size */
39 u32 c_width;
40 u32 c_height;
41 /* Offset */
42 u32 o_width;
43 u32 o_height;
44 /* Image format */
45 struct g2d_fmt *fmt;
46 /* Variables that can calculated once and reused */
47 u32 stride;
48 u32 bottom;
49 u32 right;
50 u32 size;
51};
52
53struct g2d_ctx {
54 struct v4l2_fh fh;
55 struct g2d_dev *dev;
56 struct v4l2_m2m_ctx *m2m_ctx;
57 struct g2d_frame in;
58 struct g2d_frame out;
59 struct v4l2_ctrl *ctrl_hflip;
60 struct v4l2_ctrl *ctrl_vflip;
61 struct v4l2_ctrl_handler ctrl_handler;
62 u32 rop;
63 u32 flip;
64};
65
66struct g2d_fmt {
67 char *name;
68 u32 fourcc;
69 int depth;
70 u32 hw;
71};
72
73
74void g2d_reset(struct g2d_dev *d);
75void g2d_set_src_size(struct g2d_dev *d, struct g2d_frame *f);
76void g2d_set_src_addr(struct g2d_dev *d, dma_addr_t a);
77void g2d_set_dst_size(struct g2d_dev *d, struct g2d_frame *f);
78void g2d_set_dst_addr(struct g2d_dev *d, dma_addr_t a);
79void g2d_start(struct g2d_dev *d);
80void g2d_clear_int(struct g2d_dev *d);
81void g2d_set_rop4(struct g2d_dev *d, u32 r);
82void g2d_set_flip(struct g2d_dev *d, u32 r);
83u32 g2d_cmd_stretch(u32 e);
84void g2d_set_cmd(struct g2d_dev *d, u32 c);
85
86
diff --git a/drivers/media/video/s5p-jpeg/Makefile b/drivers/media/video/s5p-jpeg/Makefile
deleted file mode 100644
index ddc2900d88a2..000000000000
--- a/drivers/media/video/s5p-jpeg/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
1s5p-jpeg-objs := jpeg-core.o
2obj-$(CONFIG_VIDEO_SAMSUNG_S5P_JPEG) := s5p-jpeg.o
diff --git a/drivers/media/video/s5p-jpeg/jpeg-core.c b/drivers/media/video/s5p-jpeg/jpeg-core.c
deleted file mode 100644
index be04d584e36a..000000000000
--- a/drivers/media/video/s5p-jpeg/jpeg-core.c
+++ /dev/null
@@ -1,1529 +0,0 @@
1/* linux/drivers/media/video/s5p-jpeg/jpeg-core.c
2 *
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/clk.h>
14#include <linux/err.h>
15#include <linux/gfp.h>
16#include <linux/interrupt.h>
17#include <linux/io.h>
18#include <linux/kernel.h>
19#include <linux/module.h>
20#include <linux/platform_device.h>
21#include <linux/pm_runtime.h>
22#include <linux/slab.h>
23#include <linux/spinlock.h>
24#include <linux/string.h>
25#include <media/v4l2-mem2mem.h>
26#include <media/v4l2-ioctl.h>
27#include <media/videobuf2-core.h>
28#include <media/videobuf2-dma-contig.h>
29
30#include "jpeg-core.h"
31#include "jpeg-hw.h"
32
33static struct s5p_jpeg_fmt formats_enc[] = {
34 {
35 .name = "JPEG JFIF",
36 .fourcc = V4L2_PIX_FMT_JPEG,
37 .colplanes = 1,
38 .types = MEM2MEM_CAPTURE,
39 },
40 {
41 .name = "YUV 4:2:2 packed, YCbYCr",
42 .fourcc = V4L2_PIX_FMT_YUYV,
43 .depth = 16,
44 .colplanes = 1,
45 .types = MEM2MEM_OUTPUT,
46 },
47 {
48 .name = "RGB565",
49 .fourcc = V4L2_PIX_FMT_RGB565,
50 .depth = 16,
51 .colplanes = 1,
52 .types = MEM2MEM_OUTPUT,
53 },
54};
55#define NUM_FORMATS_ENC ARRAY_SIZE(formats_enc)
56
57static struct s5p_jpeg_fmt formats_dec[] = {
58 {
59 .name = "YUV 4:2:0 planar, YCbCr",
60 .fourcc = V4L2_PIX_FMT_YUV420,
61 .depth = 12,
62 .colplanes = 3,
63 .h_align = 4,
64 .v_align = 4,
65 .types = MEM2MEM_CAPTURE,
66 },
67 {
68 .name = "YUV 4:2:2 packed, YCbYCr",
69 .fourcc = V4L2_PIX_FMT_YUYV,
70 .depth = 16,
71 .colplanes = 1,
72 .h_align = 4,
73 .v_align = 3,
74 .types = MEM2MEM_CAPTURE,
75 },
76 {
77 .name = "JPEG JFIF",
78 .fourcc = V4L2_PIX_FMT_JPEG,
79 .colplanes = 1,
80 .types = MEM2MEM_OUTPUT,
81 },
82};
83#define NUM_FORMATS_DEC ARRAY_SIZE(formats_dec)
84
85static const unsigned char qtbl_luminance[4][64] = {
86 {/* level 1 - high quality */
87 8, 6, 6, 8, 12, 14, 16, 17,
88 6, 6, 6, 8, 10, 13, 12, 15,
89 6, 6, 7, 8, 13, 14, 18, 24,
90 8, 8, 8, 14, 13, 19, 24, 35,
91 12, 10, 13, 13, 20, 26, 34, 39,
92 14, 13, 14, 19, 26, 34, 39, 39,
93 16, 12, 18, 24, 34, 39, 39, 39,
94 17, 15, 24, 35, 39, 39, 39, 39
95 },
96 {/* level 2 */
97 12, 8, 8, 12, 17, 21, 24, 23,
98 8, 9, 9, 11, 15, 19, 18, 23,
99 8, 9, 10, 12, 19, 20, 27, 36,
100 12, 11, 12, 21, 20, 28, 36, 53,
101 17, 15, 19, 20, 30, 39, 51, 59,
102 21, 19, 20, 28, 39, 51, 59, 59,
103 24, 18, 27, 36, 51, 59, 59, 59,
104 23, 23, 36, 53, 59, 59, 59, 59
105 },
106 {/* level 3 */
107 16, 11, 11, 16, 23, 27, 31, 30,
108 11, 12, 12, 15, 20, 23, 23, 30,
109 11, 12, 13, 16, 23, 26, 35, 47,
110 16, 15, 16, 23, 26, 37, 47, 64,
111 23, 20, 23, 26, 39, 51, 64, 64,
112 27, 23, 26, 37, 51, 64, 64, 64,
113 31, 23, 35, 47, 64, 64, 64, 64,
114 30, 30, 47, 64, 64, 64, 64, 64
115 },
116 {/*level 4 - low quality */
117 20, 16, 25, 39, 50, 46, 62, 68,
118 16, 18, 23, 38, 38, 53, 65, 68,
119 25, 23, 31, 38, 53, 65, 68, 68,
120 39, 38, 38, 53, 65, 68, 68, 68,
121 50, 38, 53, 65, 68, 68, 68, 68,
122 46, 53, 65, 68, 68, 68, 68, 68,
123 62, 65, 68, 68, 68, 68, 68, 68,
124 68, 68, 68, 68, 68, 68, 68, 68
125 }
126};
127
128static const unsigned char qtbl_chrominance[4][64] = {
129 {/* level 1 - high quality */
130 9, 8, 9, 11, 14, 17, 19, 24,
131 8, 10, 9, 11, 14, 13, 17, 22,
132 9, 9, 13, 14, 13, 15, 23, 26,
133 11, 11, 14, 14, 15, 20, 26, 33,
134 14, 14, 13, 15, 20, 24, 33, 39,
135 17, 13, 15, 20, 24, 32, 39, 39,
136 19, 17, 23, 26, 33, 39, 39, 39,
137 24, 22, 26, 33, 39, 39, 39, 39
138 },
139 {/* level 2 */
140 13, 11, 13, 16, 20, 20, 29, 37,
141 11, 14, 14, 14, 16, 20, 26, 32,
142 13, 14, 15, 17, 20, 23, 35, 40,
143 16, 14, 17, 21, 23, 30, 40, 50,
144 20, 16, 20, 23, 30, 37, 50, 59,
145 20, 20, 23, 30, 37, 48, 59, 59,
146 29, 26, 35, 40, 50, 59, 59, 59,
147 37, 32, 40, 50, 59, 59, 59, 59
148 },
149 {/* level 3 */
150 17, 15, 17, 21, 20, 26, 38, 48,
151 15, 19, 18, 17, 20, 26, 35, 43,
152 17, 18, 20, 22, 26, 30, 46, 53,
153 21, 17, 22, 28, 30, 39, 53, 64,
154 20, 20, 26, 30, 39, 48, 64, 64,
155 26, 26, 30, 39, 48, 63, 64, 64,
156 38, 35, 46, 53, 64, 64, 64, 64,
157 48, 43, 53, 64, 64, 64, 64, 64
158 },
159 {/*level 4 - low quality */
160 21, 25, 32, 38, 54, 68, 68, 68,
161 25, 28, 24, 38, 54, 68, 68, 68,
162 32, 24, 32, 43, 66, 68, 68, 68,
163 38, 38, 43, 53, 68, 68, 68, 68,
164 54, 54, 66, 68, 68, 68, 68, 68,
165 68, 68, 68, 68, 68, 68, 68, 68,
166 68, 68, 68, 68, 68, 68, 68, 68,
167 68, 68, 68, 68, 68, 68, 68, 68
168 }
169};
170
171static const unsigned char hdctbl0[16] = {
172 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0
173};
174
175static const unsigned char hdctblg0[12] = {
176 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb
177};
178static const unsigned char hactbl0[16] = {
179 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d
180};
181static const unsigned char hactblg0[162] = {
182 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
183 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
184 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
185 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
186 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
187 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
188 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
189 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
190 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
191 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
192 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
193 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
194 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
195 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
196 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
197 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
198 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
199 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
200 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
201 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
202 0xf9, 0xfa
203};
204
205static inline struct s5p_jpeg_ctx *ctrl_to_ctx(struct v4l2_ctrl *c)
206{
207 return container_of(c->handler, struct s5p_jpeg_ctx, ctrl_handler);
208}
209
210static inline struct s5p_jpeg_ctx *fh_to_ctx(struct v4l2_fh *fh)
211{
212 return container_of(fh, struct s5p_jpeg_ctx, fh);
213}
214
215static inline void jpeg_set_qtbl(void __iomem *regs, const unsigned char *qtbl,
216 unsigned long tab, int len)
217{
218 int i;
219
220 for (i = 0; i < len; i++)
221 writel((unsigned int)qtbl[i], regs + tab + (i * 0x04));
222}
223
224static inline void jpeg_set_qtbl_lum(void __iomem *regs, int quality)
225{
226 /* this driver fills quantisation table 0 with data for luma */
227 jpeg_set_qtbl(regs, qtbl_luminance[quality], S5P_JPG_QTBL_CONTENT(0),
228 ARRAY_SIZE(qtbl_luminance[quality]));
229}
230
231static inline void jpeg_set_qtbl_chr(void __iomem *regs, int quality)
232{
233 /* this driver fills quantisation table 1 with data for chroma */
234 jpeg_set_qtbl(regs, qtbl_chrominance[quality], S5P_JPG_QTBL_CONTENT(1),
235 ARRAY_SIZE(qtbl_chrominance[quality]));
236}
237
238static inline void jpeg_set_htbl(void __iomem *regs, const unsigned char *htbl,
239 unsigned long tab, int len)
240{
241 int i;
242
243 for (i = 0; i < len; i++)
244 writel((unsigned int)htbl[i], regs + tab + (i * 0x04));
245}
246
247static inline void jpeg_set_hdctbl(void __iomem *regs)
248{
249 /* this driver fills table 0 for this component */
250 jpeg_set_htbl(regs, hdctbl0, S5P_JPG_HDCTBL(0), ARRAY_SIZE(hdctbl0));
251}
252
253static inline void jpeg_set_hdctblg(void __iomem *regs)
254{
255 /* this driver fills table 0 for this component */
256 jpeg_set_htbl(regs, hdctblg0, S5P_JPG_HDCTBLG(0), ARRAY_SIZE(hdctblg0));
257}
258
259static inline void jpeg_set_hactbl(void __iomem *regs)
260{
261 /* this driver fills table 0 for this component */
262 jpeg_set_htbl(regs, hactbl0, S5P_JPG_HACTBL(0), ARRAY_SIZE(hactbl0));
263}
264
265static inline void jpeg_set_hactblg(void __iomem *regs)
266{
267 /* this driver fills table 0 for this component */
268 jpeg_set_htbl(regs, hactblg0, S5P_JPG_HACTBLG(0), ARRAY_SIZE(hactblg0));
269}
270
271/*
272 * ============================================================================
273 * Device file operations
274 * ============================================================================
275 */
276
277static int queue_init(void *priv, struct vb2_queue *src_vq,
278 struct vb2_queue *dst_vq);
279static struct s5p_jpeg_fmt *s5p_jpeg_find_format(unsigned int mode,
280 __u32 pixelformat);
281static int s5p_jpeg_controls_create(struct s5p_jpeg_ctx *ctx);
282
283static int s5p_jpeg_open(struct file *file)
284{
285 struct s5p_jpeg *jpeg = video_drvdata(file);
286 struct video_device *vfd = video_devdata(file);
287 struct s5p_jpeg_ctx *ctx;
288 struct s5p_jpeg_fmt *out_fmt;
289 int ret = 0;
290
291 ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
292 if (!ctx)
293 return -ENOMEM;
294
295 if (mutex_lock_interruptible(&jpeg->lock)) {
296 ret = -ERESTARTSYS;
297 goto free;
298 }
299
300 v4l2_fh_init(&ctx->fh, vfd);
301 /* Use separate control handler per file handle */
302 ctx->fh.ctrl_handler = &ctx->ctrl_handler;
303 file->private_data = &ctx->fh;
304 v4l2_fh_add(&ctx->fh);
305
306 ctx->jpeg = jpeg;
307 if (vfd == jpeg->vfd_encoder) {
308 ctx->mode = S5P_JPEG_ENCODE;
309 out_fmt = s5p_jpeg_find_format(ctx->mode, V4L2_PIX_FMT_RGB565);
310 } else {
311 ctx->mode = S5P_JPEG_DECODE;
312 out_fmt = s5p_jpeg_find_format(ctx->mode, V4L2_PIX_FMT_JPEG);
313 }
314
315 ret = s5p_jpeg_controls_create(ctx);
316 if (ret < 0)
317 goto error;
318
319 ctx->m2m_ctx = v4l2_m2m_ctx_init(jpeg->m2m_dev, ctx, queue_init);
320 if (IS_ERR(ctx->m2m_ctx)) {
321 ret = PTR_ERR(ctx->m2m_ctx);
322 goto error;
323 }
324
325 ctx->out_q.fmt = out_fmt;
326 ctx->cap_q.fmt = s5p_jpeg_find_format(ctx->mode, V4L2_PIX_FMT_YUYV);
327 mutex_unlock(&jpeg->lock);
328 return 0;
329
330error:
331 v4l2_fh_del(&ctx->fh);
332 v4l2_fh_exit(&ctx->fh);
333 mutex_unlock(&jpeg->lock);
334free:
335 kfree(ctx);
336 return ret;
337}
338
339static int s5p_jpeg_release(struct file *file)
340{
341 struct s5p_jpeg *jpeg = video_drvdata(file);
342 struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data);
343
344 mutex_lock(&jpeg->lock);
345 v4l2_m2m_ctx_release(ctx->m2m_ctx);
346 mutex_unlock(&jpeg->lock);
347 v4l2_ctrl_handler_free(&ctx->ctrl_handler);
348 v4l2_fh_del(&ctx->fh);
349 v4l2_fh_exit(&ctx->fh);
350 kfree(ctx);
351
352 return 0;
353}
354
355static unsigned int s5p_jpeg_poll(struct file *file,
356 struct poll_table_struct *wait)
357{
358 struct s5p_jpeg *jpeg = video_drvdata(file);
359 struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data);
360 unsigned int res;
361
362 mutex_lock(&jpeg->lock);
363 res = v4l2_m2m_poll(file, ctx->m2m_ctx, wait);
364 mutex_unlock(&jpeg->lock);
365 return res;
366}
367
368static int s5p_jpeg_mmap(struct file *file, struct vm_area_struct *vma)
369{
370 struct s5p_jpeg *jpeg = video_drvdata(file);
371 struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data);
372 int ret;
373
374 if (mutex_lock_interruptible(&jpeg->lock))
375 return -ERESTARTSYS;
376 ret = v4l2_m2m_mmap(file, ctx->m2m_ctx, vma);
377 mutex_unlock(&jpeg->lock);
378 return ret;
379}
380
381static const struct v4l2_file_operations s5p_jpeg_fops = {
382 .owner = THIS_MODULE,
383 .open = s5p_jpeg_open,
384 .release = s5p_jpeg_release,
385 .poll = s5p_jpeg_poll,
386 .unlocked_ioctl = video_ioctl2,
387 .mmap = s5p_jpeg_mmap,
388};
389
390/*
391 * ============================================================================
392 * video ioctl operations
393 * ============================================================================
394 */
395
396static int get_byte(struct s5p_jpeg_buffer *buf)
397{
398 if (buf->curr >= buf->size)
399 return -1;
400
401 return ((unsigned char *)buf->data)[buf->curr++];
402}
403
404static int get_word_be(struct s5p_jpeg_buffer *buf, unsigned int *word)
405{
406 unsigned int temp;
407 int byte;
408
409 byte = get_byte(buf);
410 if (byte == -1)
411 return -1;
412 temp = byte << 8;
413 byte = get_byte(buf);
414 if (byte == -1)
415 return -1;
416 *word = (unsigned int)byte | temp;
417 return 0;
418}
419
420static void skip(struct s5p_jpeg_buffer *buf, long len)
421{
422 if (len <= 0)
423 return;
424
425 while (len--)
426 get_byte(buf);
427}
428
429static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data *result,
430 unsigned long buffer, unsigned long size)
431{
432 int c, components, notfound;
433 unsigned int height, width, word;
434 long length;
435 struct s5p_jpeg_buffer jpeg_buffer;
436
437 jpeg_buffer.size = size;
438 jpeg_buffer.data = buffer;
439 jpeg_buffer.curr = 0;
440
441 notfound = 1;
442 while (notfound) {
443 c = get_byte(&jpeg_buffer);
444 if (c == -1)
445 break;
446 if (c != 0xff)
447 continue;
448 do
449 c = get_byte(&jpeg_buffer);
450 while (c == 0xff);
451 if (c == -1)
452 break;
453 if (c == 0)
454 continue;
455 length = 0;
456 switch (c) {
457 /* SOF0: baseline JPEG */
458 case SOF0:
459 if (get_word_be(&jpeg_buffer, &word))
460 break;
461 if (get_byte(&jpeg_buffer) == -1)
462 break;
463 if (get_word_be(&jpeg_buffer, &height))
464 break;
465 if (get_word_be(&jpeg_buffer, &width))
466 break;
467 components = get_byte(&jpeg_buffer);
468 if (components == -1)
469 break;
470 notfound = 0;
471
472 skip(&jpeg_buffer, components * 3);
473 break;
474
475 /* skip payload-less markers */
476 case RST ... RST + 7:
477 case SOI:
478 case EOI:
479 case TEM:
480 break;
481
482 /* skip uninteresting payload markers */
483 default:
484 if (get_word_be(&jpeg_buffer, &word))
485 break;
486 length = (long)word - 2;
487 skip(&jpeg_buffer, length);
488 break;
489 }
490 }
491 result->w = width;
492 result->h = height;
493 result->size = components;
494 return !notfound;
495}
496
497static int s5p_jpeg_querycap(struct file *file, void *priv,
498 struct v4l2_capability *cap)
499{
500 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
501
502 if (ctx->mode == S5P_JPEG_ENCODE) {
503 strlcpy(cap->driver, S5P_JPEG_M2M_NAME " encoder",
504 sizeof(cap->driver));
505 strlcpy(cap->card, S5P_JPEG_M2M_NAME " encoder",
506 sizeof(cap->card));
507 } else {
508 strlcpy(cap->driver, S5P_JPEG_M2M_NAME " decoder",
509 sizeof(cap->driver));
510 strlcpy(cap->card, S5P_JPEG_M2M_NAME " decoder",
511 sizeof(cap->card));
512 }
513 cap->bus_info[0] = 0;
514 /*
515 * This is only a mem-to-mem video device. The capture and output
516 * device capability flags are left only for backward compatibility
517 * and are scheduled for removal.
518 */
519 cap->capabilities = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M |
520 V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT;
521 return 0;
522}
523
524static int enum_fmt(struct s5p_jpeg_fmt *formats, int n,
525 struct v4l2_fmtdesc *f, u32 type)
526{
527 int i, num = 0;
528
529 for (i = 0; i < n; ++i) {
530 if (formats[i].types & type) {
531 /* index-th format of type type found ? */
532 if (num == f->index)
533 break;
534 /* Correct type but haven't reached our index yet,
535 * just increment per-type index */
536 ++num;
537 }
538 }
539
540 /* Format not found */
541 if (i >= n)
542 return -EINVAL;
543
544 strlcpy(f->description, formats[i].name, sizeof(f->description));
545 f->pixelformat = formats[i].fourcc;
546
547 return 0;
548}
549
550static int s5p_jpeg_enum_fmt_vid_cap(struct file *file, void *priv,
551 struct v4l2_fmtdesc *f)
552{
553 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
554
555 if (ctx->mode == S5P_JPEG_ENCODE)
556 return enum_fmt(formats_enc, NUM_FORMATS_ENC, f,
557 MEM2MEM_CAPTURE);
558
559 return enum_fmt(formats_dec, NUM_FORMATS_DEC, f, MEM2MEM_CAPTURE);
560}
561
562static int s5p_jpeg_enum_fmt_vid_out(struct file *file, void *priv,
563 struct v4l2_fmtdesc *f)
564{
565 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
566
567 if (ctx->mode == S5P_JPEG_ENCODE)
568 return enum_fmt(formats_enc, NUM_FORMATS_ENC, f,
569 MEM2MEM_OUTPUT);
570
571 return enum_fmt(formats_dec, NUM_FORMATS_DEC, f, MEM2MEM_OUTPUT);
572}
573
574static struct s5p_jpeg_q_data *get_q_data(struct s5p_jpeg_ctx *ctx,
575 enum v4l2_buf_type type)
576{
577 if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
578 return &ctx->out_q;
579 if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
580 return &ctx->cap_q;
581
582 return NULL;
583}
584
585static int s5p_jpeg_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
586{
587 struct vb2_queue *vq;
588 struct s5p_jpeg_q_data *q_data = NULL;
589 struct v4l2_pix_format *pix = &f->fmt.pix;
590 struct s5p_jpeg_ctx *ct = fh_to_ctx(priv);
591
592 vq = v4l2_m2m_get_vq(ct->m2m_ctx, f->type);
593 if (!vq)
594 return -EINVAL;
595
596 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE &&
597 ct->mode == S5P_JPEG_DECODE && !ct->hdr_parsed)
598 return -EINVAL;
599 q_data = get_q_data(ct, f->type);
600 BUG_ON(q_data == NULL);
601
602 pix->width = q_data->w;
603 pix->height = q_data->h;
604 pix->field = V4L2_FIELD_NONE;
605 pix->pixelformat = q_data->fmt->fourcc;
606 pix->bytesperline = 0;
607 if (q_data->fmt->fourcc != V4L2_PIX_FMT_JPEG) {
608 u32 bpl = q_data->w;
609 if (q_data->fmt->colplanes == 1)
610 bpl = (bpl * q_data->fmt->depth) >> 3;
611 pix->bytesperline = bpl;
612 }
613 pix->sizeimage = q_data->size;
614
615 return 0;
616}
617
618static struct s5p_jpeg_fmt *s5p_jpeg_find_format(unsigned int mode,
619 u32 pixelformat)
620{
621 unsigned int k;
622 struct s5p_jpeg_fmt *formats;
623 int n;
624
625 if (mode == S5P_JPEG_ENCODE) {
626 formats = formats_enc;
627 n = NUM_FORMATS_ENC;
628 } else {
629 formats = formats_dec;
630 n = NUM_FORMATS_DEC;
631 }
632
633 for (k = 0; k < n; k++) {
634 struct s5p_jpeg_fmt *fmt = &formats[k];
635 if (fmt->fourcc == pixelformat)
636 return fmt;
637 }
638
639 return NULL;
640
641}
642
643static void jpeg_bound_align_image(u32 *w, unsigned int wmin, unsigned int wmax,
644 unsigned int walign,
645 u32 *h, unsigned int hmin, unsigned int hmax,
646 unsigned int halign)
647{
648 int width, height, w_step, h_step;
649
650 width = *w;
651 height = *h;
652
653 w_step = 1 << walign;
654 h_step = 1 << halign;
655 v4l_bound_align_image(w, wmin, wmax, walign, h, hmin, hmax, halign, 0);
656
657 if (*w < width && (*w + w_step) < wmax)
658 *w += w_step;
659 if (*h < height && (*h + h_step) < hmax)
660 *h += h_step;
661
662}
663
664static int vidioc_try_fmt(struct v4l2_format *f, struct s5p_jpeg_fmt *fmt,
665 struct s5p_jpeg_ctx *ctx, int q_type)
666{
667 struct v4l2_pix_format *pix = &f->fmt.pix;
668
669 if (pix->field == V4L2_FIELD_ANY)
670 pix->field = V4L2_FIELD_NONE;
671 else if (pix->field != V4L2_FIELD_NONE)
672 return -EINVAL;
673
674 /* V4L2 specification suggests the driver corrects the format struct
675 * if any of the dimensions is unsupported */
676 if (q_type == MEM2MEM_OUTPUT)
677 jpeg_bound_align_image(&pix->width, S5P_JPEG_MIN_WIDTH,
678 S5P_JPEG_MAX_WIDTH, 0,
679 &pix->height, S5P_JPEG_MIN_HEIGHT,
680 S5P_JPEG_MAX_HEIGHT, 0);
681 else
682 jpeg_bound_align_image(&pix->width, S5P_JPEG_MIN_WIDTH,
683 S5P_JPEG_MAX_WIDTH, fmt->h_align,
684 &pix->height, S5P_JPEG_MIN_HEIGHT,
685 S5P_JPEG_MAX_HEIGHT, fmt->v_align);
686
687 if (fmt->fourcc == V4L2_PIX_FMT_JPEG) {
688 if (pix->sizeimage <= 0)
689 pix->sizeimage = PAGE_SIZE;
690 pix->bytesperline = 0;
691 } else {
692 u32 bpl = pix->bytesperline;
693
694 if (fmt->colplanes > 1 && bpl < pix->width)
695 bpl = pix->width; /* planar */
696
697 if (fmt->colplanes == 1 && /* packed */
698 (bpl << 3) * fmt->depth < pix->width)
699 bpl = (pix->width * fmt->depth) >> 3;
700
701 pix->bytesperline = bpl;
702 pix->sizeimage = (pix->width * pix->height * fmt->depth) >> 3;
703 }
704
705 return 0;
706}
707
708static int s5p_jpeg_try_fmt_vid_cap(struct file *file, void *priv,
709 struct v4l2_format *f)
710{
711 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
712 struct s5p_jpeg_fmt *fmt;
713
714 fmt = s5p_jpeg_find_format(ctx->mode, f->fmt.pix.pixelformat);
715 if (!fmt || !(fmt->types & MEM2MEM_CAPTURE)) {
716 v4l2_err(&ctx->jpeg->v4l2_dev,
717 "Fourcc format (0x%08x) invalid.\n",
718 f->fmt.pix.pixelformat);
719 return -EINVAL;
720 }
721
722 return vidioc_try_fmt(f, fmt, ctx, MEM2MEM_CAPTURE);
723}
724
725static int s5p_jpeg_try_fmt_vid_out(struct file *file, void *priv,
726 struct v4l2_format *f)
727{
728 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
729 struct s5p_jpeg_fmt *fmt;
730
731 fmt = s5p_jpeg_find_format(ctx->mode, f->fmt.pix.pixelformat);
732 if (!fmt || !(fmt->types & MEM2MEM_OUTPUT)) {
733 v4l2_err(&ctx->jpeg->v4l2_dev,
734 "Fourcc format (0x%08x) invalid.\n",
735 f->fmt.pix.pixelformat);
736 return -EINVAL;
737 }
738
739 return vidioc_try_fmt(f, fmt, ctx, MEM2MEM_OUTPUT);
740}
741
742static int s5p_jpeg_s_fmt(struct s5p_jpeg_ctx *ct, struct v4l2_format *f)
743{
744 struct vb2_queue *vq;
745 struct s5p_jpeg_q_data *q_data = NULL;
746 struct v4l2_pix_format *pix = &f->fmt.pix;
747
748 vq = v4l2_m2m_get_vq(ct->m2m_ctx, f->type);
749 if (!vq)
750 return -EINVAL;
751
752 q_data = get_q_data(ct, f->type);
753 BUG_ON(q_data == NULL);
754
755 if (vb2_is_busy(vq)) {
756 v4l2_err(&ct->jpeg->v4l2_dev, "%s queue busy\n", __func__);
757 return -EBUSY;
758 }
759
760 q_data->fmt = s5p_jpeg_find_format(ct->mode, pix->pixelformat);
761 q_data->w = pix->width;
762 q_data->h = pix->height;
763 if (q_data->fmt->fourcc != V4L2_PIX_FMT_JPEG)
764 q_data->size = q_data->w * q_data->h * q_data->fmt->depth >> 3;
765 else
766 q_data->size = pix->sizeimage;
767
768 return 0;
769}
770
771static int s5p_jpeg_s_fmt_vid_cap(struct file *file, void *priv,
772 struct v4l2_format *f)
773{
774 int ret;
775
776 ret = s5p_jpeg_try_fmt_vid_cap(file, priv, f);
777 if (ret)
778 return ret;
779
780 return s5p_jpeg_s_fmt(fh_to_ctx(priv), f);
781}
782
783static int s5p_jpeg_s_fmt_vid_out(struct file *file, void *priv,
784 struct v4l2_format *f)
785{
786 int ret;
787
788 ret = s5p_jpeg_try_fmt_vid_out(file, priv, f);
789 if (ret)
790 return ret;
791
792 return s5p_jpeg_s_fmt(fh_to_ctx(priv), f);
793}
794
795static int s5p_jpeg_reqbufs(struct file *file, void *priv,
796 struct v4l2_requestbuffers *reqbufs)
797{
798 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
799
800 return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs);
801}
802
803static int s5p_jpeg_querybuf(struct file *file, void *priv,
804 struct v4l2_buffer *buf)
805{
806 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
807
808 return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf);
809}
810
811static int s5p_jpeg_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
812{
813 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
814
815 return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
816}
817
818static int s5p_jpeg_dqbuf(struct file *file, void *priv,
819 struct v4l2_buffer *buf)
820{
821 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
822
823 return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
824}
825
826static int s5p_jpeg_streamon(struct file *file, void *priv,
827 enum v4l2_buf_type type)
828{
829 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
830
831 return v4l2_m2m_streamon(file, ctx->m2m_ctx, type);
832}
833
834static int s5p_jpeg_streamoff(struct file *file, void *priv,
835 enum v4l2_buf_type type)
836{
837 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
838
839 return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type);
840}
841
842static int s5p_jpeg_g_selection(struct file *file, void *priv,
843 struct v4l2_selection *s)
844{
845 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
846
847 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
848 s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
849 return -EINVAL;
850
851 /* For JPEG blob active == default == bounds */
852 switch (s->target) {
853 case V4L2_SEL_TGT_CROP:
854 case V4L2_SEL_TGT_CROP_BOUNDS:
855 case V4L2_SEL_TGT_CROP_DEFAULT:
856 case V4L2_SEL_TGT_COMPOSE:
857 case V4L2_SEL_TGT_COMPOSE_DEFAULT:
858 s->r.width = ctx->out_q.w;
859 s->r.height = ctx->out_q.h;
860 break;
861 case V4L2_SEL_TGT_COMPOSE_BOUNDS:
862 case V4L2_SEL_TGT_COMPOSE_PADDED:
863 s->r.width = ctx->cap_q.w;
864 s->r.height = ctx->cap_q.h;
865 break;
866 default:
867 return -EINVAL;
868 }
869 s->r.left = 0;
870 s->r.top = 0;
871 return 0;
872}
873
874/*
875 * V4L2 controls
876 */
877
878static int s5p_jpeg_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
879{
880 struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
881 struct s5p_jpeg *jpeg = ctx->jpeg;
882 unsigned long flags;
883
884 switch (ctrl->id) {
885 case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
886 spin_lock_irqsave(&jpeg->slock, flags);
887
888 WARN_ON(ctx->subsampling > S5P_SUBSAMPLING_MODE_GRAY);
889 if (ctx->subsampling > 2)
890 ctrl->val = V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
891 else
892 ctrl->val = ctx->subsampling;
893 spin_unlock_irqrestore(&jpeg->slock, flags);
894 break;
895 }
896
897 return 0;
898}
899
900static int s5p_jpeg_s_ctrl(struct v4l2_ctrl *ctrl)
901{
902 struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
903 unsigned long flags;
904
905 spin_lock_irqsave(&ctx->jpeg->slock, flags);
906
907 switch (ctrl->id) {
908 case V4L2_CID_JPEG_COMPRESSION_QUALITY:
909 ctx->compr_quality = S5P_JPEG_COMPR_QUAL_WORST - ctrl->val;
910 break;
911 case V4L2_CID_JPEG_RESTART_INTERVAL:
912 ctx->restart_interval = ctrl->val;
913 break;
914 case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
915 ctx->subsampling = ctrl->val;
916 break;
917 }
918
919 spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
920 return 0;
921}
922
923static const struct v4l2_ctrl_ops s5p_jpeg_ctrl_ops = {
924 .g_volatile_ctrl = s5p_jpeg_g_volatile_ctrl,
925 .s_ctrl = s5p_jpeg_s_ctrl,
926};
927
928static int s5p_jpeg_controls_create(struct s5p_jpeg_ctx *ctx)
929{
930 unsigned int mask = ~0x27; /* 444, 422, 420, GRAY */
931 struct v4l2_ctrl *ctrl;
932
933 v4l2_ctrl_handler_init(&ctx->ctrl_handler, 3);
934
935 if (ctx->mode == S5P_JPEG_ENCODE) {
936 v4l2_ctrl_new_std(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
937 V4L2_CID_JPEG_COMPRESSION_QUALITY,
938 0, 3, 1, 3);
939
940 v4l2_ctrl_new_std(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
941 V4L2_CID_JPEG_RESTART_INTERVAL,
942 0, 3, 0xffff, 0);
943 mask = ~0x06; /* 422, 420 */
944 }
945
946 ctrl = v4l2_ctrl_new_std_menu(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
947 V4L2_CID_JPEG_CHROMA_SUBSAMPLING,
948 V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY, mask,
949 V4L2_JPEG_CHROMA_SUBSAMPLING_422);
950
951 if (ctx->ctrl_handler.error)
952 return ctx->ctrl_handler.error;
953
954 if (ctx->mode == S5P_JPEG_DECODE)
955 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE |
956 V4L2_CTRL_FLAG_READ_ONLY;
957 return 0;
958}
959
960static const struct v4l2_ioctl_ops s5p_jpeg_ioctl_ops = {
961 .vidioc_querycap = s5p_jpeg_querycap,
962
963 .vidioc_enum_fmt_vid_cap = s5p_jpeg_enum_fmt_vid_cap,
964 .vidioc_enum_fmt_vid_out = s5p_jpeg_enum_fmt_vid_out,
965
966 .vidioc_g_fmt_vid_cap = s5p_jpeg_g_fmt,
967 .vidioc_g_fmt_vid_out = s5p_jpeg_g_fmt,
968
969 .vidioc_try_fmt_vid_cap = s5p_jpeg_try_fmt_vid_cap,
970 .vidioc_try_fmt_vid_out = s5p_jpeg_try_fmt_vid_out,
971
972 .vidioc_s_fmt_vid_cap = s5p_jpeg_s_fmt_vid_cap,
973 .vidioc_s_fmt_vid_out = s5p_jpeg_s_fmt_vid_out,
974
975 .vidioc_reqbufs = s5p_jpeg_reqbufs,
976 .vidioc_querybuf = s5p_jpeg_querybuf,
977
978 .vidioc_qbuf = s5p_jpeg_qbuf,
979 .vidioc_dqbuf = s5p_jpeg_dqbuf,
980
981 .vidioc_streamon = s5p_jpeg_streamon,
982 .vidioc_streamoff = s5p_jpeg_streamoff,
983
984 .vidioc_g_selection = s5p_jpeg_g_selection,
985};
986
987/*
988 * ============================================================================
989 * mem2mem callbacks
990 * ============================================================================
991 */
992
993static void s5p_jpeg_device_run(void *priv)
994{
995 struct s5p_jpeg_ctx *ctx = priv;
996 struct s5p_jpeg *jpeg = ctx->jpeg;
997 struct vb2_buffer *src_buf, *dst_buf;
998 unsigned long src_addr, dst_addr;
999
1000 src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
1001 dst_buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
1002 src_addr = vb2_dma_contig_plane_dma_addr(src_buf, 0);
1003 dst_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
1004
1005 jpeg_reset(jpeg->regs);
1006 jpeg_poweron(jpeg->regs);
1007 jpeg_proc_mode(jpeg->regs, ctx->mode);
1008 if (ctx->mode == S5P_JPEG_ENCODE) {
1009 if (ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB565)
1010 jpeg_input_raw_mode(jpeg->regs, S5P_JPEG_RAW_IN_565);
1011 else
1012 jpeg_input_raw_mode(jpeg->regs, S5P_JPEG_RAW_IN_422);
1013 jpeg_subsampling_mode(jpeg->regs, ctx->subsampling);
1014 jpeg_dri(jpeg->regs, ctx->restart_interval);
1015 jpeg_x(jpeg->regs, ctx->out_q.w);
1016 jpeg_y(jpeg->regs, ctx->out_q.h);
1017 jpeg_imgadr(jpeg->regs, src_addr);
1018 jpeg_jpgadr(jpeg->regs, dst_addr);
1019
1020 /* ultimately comes from sizeimage from userspace */
1021 jpeg_enc_stream_int(jpeg->regs, ctx->cap_q.size);
1022
1023 /* JPEG RGB to YCbCr conversion matrix */
1024 jpeg_coef(jpeg->regs, 1, 1, S5P_JPEG_COEF11);
1025 jpeg_coef(jpeg->regs, 1, 2, S5P_JPEG_COEF12);
1026 jpeg_coef(jpeg->regs, 1, 3, S5P_JPEG_COEF13);
1027 jpeg_coef(jpeg->regs, 2, 1, S5P_JPEG_COEF21);
1028 jpeg_coef(jpeg->regs, 2, 2, S5P_JPEG_COEF22);
1029 jpeg_coef(jpeg->regs, 2, 3, S5P_JPEG_COEF23);
1030 jpeg_coef(jpeg->regs, 3, 1, S5P_JPEG_COEF31);
1031 jpeg_coef(jpeg->regs, 3, 2, S5P_JPEG_COEF32);
1032 jpeg_coef(jpeg->regs, 3, 3, S5P_JPEG_COEF33);
1033
1034 /*
1035 * JPEG IP allows storing 4 quantization tables
1036 * We fill table 0 for luma and table 1 for chroma
1037 */
1038 jpeg_set_qtbl_lum(jpeg->regs, ctx->compr_quality);
1039 jpeg_set_qtbl_chr(jpeg->regs, ctx->compr_quality);
1040 /* use table 0 for Y */
1041 jpeg_qtbl(jpeg->regs, 1, 0);
1042 /* use table 1 for Cb and Cr*/
1043 jpeg_qtbl(jpeg->regs, 2, 1);
1044 jpeg_qtbl(jpeg->regs, 3, 1);
1045
1046 /* Y, Cb, Cr use Huffman table 0 */
1047 jpeg_htbl_ac(jpeg->regs, 1);
1048 jpeg_htbl_dc(jpeg->regs, 1);
1049 jpeg_htbl_ac(jpeg->regs, 2);
1050 jpeg_htbl_dc(jpeg->regs, 2);
1051 jpeg_htbl_ac(jpeg->regs, 3);
1052 jpeg_htbl_dc(jpeg->regs, 3);
1053 } else { /* S5P_JPEG_DECODE */
1054 jpeg_rst_int_enable(jpeg->regs, true);
1055 jpeg_data_num_int_enable(jpeg->regs, true);
1056 jpeg_final_mcu_num_int_enable(jpeg->regs, true);
1057 if (ctx->cap_q.fmt->fourcc == V4L2_PIX_FMT_YUYV)
1058 jpeg_outform_raw(jpeg->regs, S5P_JPEG_RAW_OUT_422);
1059 else
1060 jpeg_outform_raw(jpeg->regs, S5P_JPEG_RAW_OUT_420);
1061 jpeg_jpgadr(jpeg->regs, src_addr);
1062 jpeg_imgadr(jpeg->regs, dst_addr);
1063 }
1064
1065 jpeg_start(jpeg->regs);
1066}
1067
1068static int s5p_jpeg_job_ready(void *priv)
1069{
1070 struct s5p_jpeg_ctx *ctx = priv;
1071
1072 if (ctx->mode == S5P_JPEG_DECODE)
1073 return ctx->hdr_parsed;
1074 return 1;
1075}
1076
1077static void s5p_jpeg_job_abort(void *priv)
1078{
1079}
1080
1081static struct v4l2_m2m_ops s5p_jpeg_m2m_ops = {
1082 .device_run = s5p_jpeg_device_run,
1083 .job_ready = s5p_jpeg_job_ready,
1084 .job_abort = s5p_jpeg_job_abort,
1085};
1086
1087/*
1088 * ============================================================================
1089 * Queue operations
1090 * ============================================================================
1091 */
1092
1093static int s5p_jpeg_queue_setup(struct vb2_queue *vq,
1094 const struct v4l2_format *fmt,
1095 unsigned int *nbuffers, unsigned int *nplanes,
1096 unsigned int sizes[], void *alloc_ctxs[])
1097{
1098 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vq);
1099 struct s5p_jpeg_q_data *q_data = NULL;
1100 unsigned int size, count = *nbuffers;
1101
1102 q_data = get_q_data(ctx, vq->type);
1103 BUG_ON(q_data == NULL);
1104
1105 size = q_data->size;
1106
1107 /*
1108 * header is parsed during decoding and parsed information stored
1109 * in the context so we do not allow another buffer to overwrite it
1110 */
1111 if (ctx->mode == S5P_JPEG_DECODE)
1112 count = 1;
1113
1114 *nbuffers = count;
1115 *nplanes = 1;
1116 sizes[0] = size;
1117 alloc_ctxs[0] = ctx->jpeg->alloc_ctx;
1118
1119 return 0;
1120}
1121
1122static int s5p_jpeg_buf_prepare(struct vb2_buffer *vb)
1123{
1124 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
1125 struct s5p_jpeg_q_data *q_data = NULL;
1126
1127 q_data = get_q_data(ctx, vb->vb2_queue->type);
1128 BUG_ON(q_data == NULL);
1129
1130 if (vb2_plane_size(vb, 0) < q_data->size) {
1131 pr_err("%s data will not fit into plane (%lu < %lu)\n",
1132 __func__, vb2_plane_size(vb, 0),
1133 (long)q_data->size);
1134 return -EINVAL;
1135 }
1136
1137 vb2_set_plane_payload(vb, 0, q_data->size);
1138
1139 return 0;
1140}
1141
1142static void s5p_jpeg_buf_queue(struct vb2_buffer *vb)
1143{
1144 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
1145
1146 if (ctx->mode == S5P_JPEG_DECODE &&
1147 vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
1148 struct s5p_jpeg_q_data tmp, *q_data;
1149 ctx->hdr_parsed = s5p_jpeg_parse_hdr(&tmp,
1150 (unsigned long)vb2_plane_vaddr(vb, 0),
1151 min((unsigned long)ctx->out_q.size,
1152 vb2_get_plane_payload(vb, 0)));
1153 if (!ctx->hdr_parsed) {
1154 vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
1155 return;
1156 }
1157
1158 q_data = &ctx->out_q;
1159 q_data->w = tmp.w;
1160 q_data->h = tmp.h;
1161
1162 q_data = &ctx->cap_q;
1163 q_data->w = tmp.w;
1164 q_data->h = tmp.h;
1165
1166 jpeg_bound_align_image(&q_data->w, S5P_JPEG_MIN_WIDTH,
1167 S5P_JPEG_MAX_WIDTH, q_data->fmt->h_align,
1168 &q_data->h, S5P_JPEG_MIN_HEIGHT,
1169 S5P_JPEG_MAX_HEIGHT, q_data->fmt->v_align
1170 );
1171 q_data->size = q_data->w * q_data->h * q_data->fmt->depth >> 3;
1172 }
1173 if (ctx->m2m_ctx)
1174 v4l2_m2m_buf_queue(ctx->m2m_ctx, vb);
1175}
1176
1177static void s5p_jpeg_wait_prepare(struct vb2_queue *vq)
1178{
1179 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vq);
1180
1181 mutex_unlock(&ctx->jpeg->lock);
1182}
1183
1184static void s5p_jpeg_wait_finish(struct vb2_queue *vq)
1185{
1186 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vq);
1187
1188 mutex_lock(&ctx->jpeg->lock);
1189}
1190
1191static int s5p_jpeg_start_streaming(struct vb2_queue *q, unsigned int count)
1192{
1193 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(q);
1194 int ret;
1195
1196 ret = pm_runtime_get_sync(ctx->jpeg->dev);
1197
1198 return ret > 0 ? 0 : ret;
1199}
1200
1201static int s5p_jpeg_stop_streaming(struct vb2_queue *q)
1202{
1203 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(q);
1204
1205 pm_runtime_put(ctx->jpeg->dev);
1206
1207 return 0;
1208}
1209
1210static struct vb2_ops s5p_jpeg_qops = {
1211 .queue_setup = s5p_jpeg_queue_setup,
1212 .buf_prepare = s5p_jpeg_buf_prepare,
1213 .buf_queue = s5p_jpeg_buf_queue,
1214 .wait_prepare = s5p_jpeg_wait_prepare,
1215 .wait_finish = s5p_jpeg_wait_finish,
1216 .start_streaming = s5p_jpeg_start_streaming,
1217 .stop_streaming = s5p_jpeg_stop_streaming,
1218};
1219
1220static int queue_init(void *priv, struct vb2_queue *src_vq,
1221 struct vb2_queue *dst_vq)
1222{
1223 struct s5p_jpeg_ctx *ctx = priv;
1224 int ret;
1225
1226 memset(src_vq, 0, sizeof(*src_vq));
1227 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
1228 src_vq->io_modes = VB2_MMAP | VB2_USERPTR;
1229 src_vq->drv_priv = ctx;
1230 src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
1231 src_vq->ops = &s5p_jpeg_qops;
1232 src_vq->mem_ops = &vb2_dma_contig_memops;
1233
1234 ret = vb2_queue_init(src_vq);
1235 if (ret)
1236 return ret;
1237
1238 memset(dst_vq, 0, sizeof(*dst_vq));
1239 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1240 dst_vq->io_modes = VB2_MMAP | VB2_USERPTR;
1241 dst_vq->drv_priv = ctx;
1242 dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
1243 dst_vq->ops = &s5p_jpeg_qops;
1244 dst_vq->mem_ops = &vb2_dma_contig_memops;
1245
1246 return vb2_queue_init(dst_vq);
1247}
1248
1249/*
1250 * ============================================================================
1251 * ISR
1252 * ============================================================================
1253 */
1254
1255static irqreturn_t s5p_jpeg_irq(int irq, void *dev_id)
1256{
1257 struct s5p_jpeg *jpeg = dev_id;
1258 struct s5p_jpeg_ctx *curr_ctx;
1259 struct vb2_buffer *src_buf, *dst_buf;
1260 unsigned long payload_size = 0;
1261 enum vb2_buffer_state state = VB2_BUF_STATE_DONE;
1262 bool enc_jpeg_too_large = false;
1263 bool timer_elapsed = false;
1264 bool op_completed = false;
1265
1266 spin_lock(&jpeg->slock);
1267
1268 curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
1269
1270 src_buf = v4l2_m2m_src_buf_remove(curr_ctx->m2m_ctx);
1271 dst_buf = v4l2_m2m_dst_buf_remove(curr_ctx->m2m_ctx);
1272
1273 if (curr_ctx->mode == S5P_JPEG_ENCODE)
1274 enc_jpeg_too_large = jpeg_enc_stream_stat(jpeg->regs);
1275 timer_elapsed = jpeg_timer_stat(jpeg->regs);
1276 op_completed = jpeg_result_stat_ok(jpeg->regs);
1277 if (curr_ctx->mode == S5P_JPEG_DECODE)
1278 op_completed = op_completed && jpeg_stream_stat_ok(jpeg->regs);
1279
1280 if (enc_jpeg_too_large) {
1281 state = VB2_BUF_STATE_ERROR;
1282 jpeg_clear_enc_stream_stat(jpeg->regs);
1283 } else if (timer_elapsed) {
1284 state = VB2_BUF_STATE_ERROR;
1285 jpeg_clear_timer_stat(jpeg->regs);
1286 } else if (!op_completed) {
1287 state = VB2_BUF_STATE_ERROR;
1288 } else {
1289 payload_size = jpeg_compressed_size(jpeg->regs);
1290 }
1291
1292 v4l2_m2m_buf_done(src_buf, state);
1293 if (curr_ctx->mode == S5P_JPEG_ENCODE)
1294 vb2_set_plane_payload(dst_buf, 0, payload_size);
1295 v4l2_m2m_buf_done(dst_buf, state);
1296 v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->m2m_ctx);
1297
1298 curr_ctx->subsampling = jpeg_get_subsampling_mode(jpeg->regs);
1299 spin_unlock(&jpeg->slock);
1300
1301 jpeg_clear_int(jpeg->regs);
1302
1303 return IRQ_HANDLED;
1304}
1305
1306/*
1307 * ============================================================================
1308 * Driver basic infrastructure
1309 * ============================================================================
1310 */
1311
1312static int s5p_jpeg_probe(struct platform_device *pdev)
1313{
1314 struct s5p_jpeg *jpeg;
1315 struct resource *res;
1316 int ret;
1317
1318 /* JPEG IP abstraction struct */
1319 jpeg = devm_kzalloc(&pdev->dev, sizeof(struct s5p_jpeg), GFP_KERNEL);
1320 if (!jpeg)
1321 return -ENOMEM;
1322
1323 mutex_init(&jpeg->lock);
1324 spin_lock_init(&jpeg->slock);
1325 jpeg->dev = &pdev->dev;
1326
1327 /* memory-mapped registers */
1328 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1329
1330 jpeg->regs = devm_request_and_ioremap(&pdev->dev, res);
1331 if (jpeg->regs == NULL) {
1332 dev_err(&pdev->dev, "Failed to obtain io memory\n");
1333 return -ENOENT;
1334 }
1335
1336 /* interrupt service routine registration */
1337 jpeg->irq = ret = platform_get_irq(pdev, 0);
1338 if (ret < 0) {
1339 dev_err(&pdev->dev, "cannot find IRQ\n");
1340 return ret;
1341 }
1342
1343 ret = devm_request_irq(&pdev->dev, jpeg->irq, s5p_jpeg_irq, 0,
1344 dev_name(&pdev->dev), jpeg);
1345 if (ret) {
1346 dev_err(&pdev->dev, "cannot claim IRQ %d\n", jpeg->irq);
1347 return ret;
1348 }
1349
1350 /* clocks */
1351 jpeg->clk = clk_get(&pdev->dev, "jpeg");
1352 if (IS_ERR(jpeg->clk)) {
1353 dev_err(&pdev->dev, "cannot get clock\n");
1354 ret = PTR_ERR(jpeg->clk);
1355 return ret;
1356 }
1357 dev_dbg(&pdev->dev, "clock source %p\n", jpeg->clk);
1358 clk_enable(jpeg->clk);
1359
1360 /* v4l2 device */
1361 ret = v4l2_device_register(&pdev->dev, &jpeg->v4l2_dev);
1362 if (ret) {
1363 dev_err(&pdev->dev, "Failed to register v4l2 device\n");
1364 goto clk_get_rollback;
1365 }
1366
1367 /* mem2mem device */
1368 jpeg->m2m_dev = v4l2_m2m_init(&s5p_jpeg_m2m_ops);
1369 if (IS_ERR(jpeg->m2m_dev)) {
1370 v4l2_err(&jpeg->v4l2_dev, "Failed to init mem2mem device\n");
1371 ret = PTR_ERR(jpeg->m2m_dev);
1372 goto device_register_rollback;
1373 }
1374
1375 jpeg->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
1376 if (IS_ERR(jpeg->alloc_ctx)) {
1377 v4l2_err(&jpeg->v4l2_dev, "Failed to init memory allocator\n");
1378 ret = PTR_ERR(jpeg->alloc_ctx);
1379 goto m2m_init_rollback;
1380 }
1381
1382 /* JPEG encoder /dev/videoX node */
1383 jpeg->vfd_encoder = video_device_alloc();
1384 if (!jpeg->vfd_encoder) {
1385 v4l2_err(&jpeg->v4l2_dev, "Failed to allocate video device\n");
1386 ret = -ENOMEM;
1387 goto vb2_allocator_rollback;
1388 }
1389 strlcpy(jpeg->vfd_encoder->name, S5P_JPEG_M2M_NAME,
1390 sizeof(jpeg->vfd_encoder->name));
1391 jpeg->vfd_encoder->fops = &s5p_jpeg_fops;
1392 jpeg->vfd_encoder->ioctl_ops = &s5p_jpeg_ioctl_ops;
1393 jpeg->vfd_encoder->minor = -1;
1394 jpeg->vfd_encoder->release = video_device_release;
1395 jpeg->vfd_encoder->lock = &jpeg->lock;
1396 jpeg->vfd_encoder->v4l2_dev = &jpeg->v4l2_dev;
1397
1398 ret = video_register_device(jpeg->vfd_encoder, VFL_TYPE_GRABBER, -1);
1399 if (ret) {
1400 v4l2_err(&jpeg->v4l2_dev, "Failed to register video device\n");
1401 goto enc_vdev_alloc_rollback;
1402 }
1403
1404 video_set_drvdata(jpeg->vfd_encoder, jpeg);
1405 v4l2_info(&jpeg->v4l2_dev,
1406 "encoder device registered as /dev/video%d\n",
1407 jpeg->vfd_encoder->num);
1408
1409 /* JPEG decoder /dev/videoX node */
1410 jpeg->vfd_decoder = video_device_alloc();
1411 if (!jpeg->vfd_decoder) {
1412 v4l2_err(&jpeg->v4l2_dev, "Failed to allocate video device\n");
1413 ret = -ENOMEM;
1414 goto enc_vdev_register_rollback;
1415 }
1416 strlcpy(jpeg->vfd_decoder->name, S5P_JPEG_M2M_NAME,
1417 sizeof(jpeg->vfd_decoder->name));
1418 jpeg->vfd_decoder->fops = &s5p_jpeg_fops;
1419 jpeg->vfd_decoder->ioctl_ops = &s5p_jpeg_ioctl_ops;
1420 jpeg->vfd_decoder->minor = -1;
1421 jpeg->vfd_decoder->release = video_device_release;
1422 jpeg->vfd_decoder->lock = &jpeg->lock;
1423 jpeg->vfd_decoder->v4l2_dev = &jpeg->v4l2_dev;
1424
1425 ret = video_register_device(jpeg->vfd_decoder, VFL_TYPE_GRABBER, -1);
1426 if (ret) {
1427 v4l2_err(&jpeg->v4l2_dev, "Failed to register video device\n");
1428 goto dec_vdev_alloc_rollback;
1429 }
1430
1431 video_set_drvdata(jpeg->vfd_decoder, jpeg);
1432 v4l2_info(&jpeg->v4l2_dev,
1433 "decoder device registered as /dev/video%d\n",
1434 jpeg->vfd_decoder->num);
1435
1436 /* final statements & power management */
1437 platform_set_drvdata(pdev, jpeg);
1438
1439 pm_runtime_enable(&pdev->dev);
1440
1441 v4l2_info(&jpeg->v4l2_dev, "Samsung S5P JPEG codec\n");
1442
1443 return 0;
1444
1445dec_vdev_alloc_rollback:
1446 video_device_release(jpeg->vfd_decoder);
1447
1448enc_vdev_register_rollback:
1449 video_unregister_device(jpeg->vfd_encoder);
1450
1451enc_vdev_alloc_rollback:
1452 video_device_release(jpeg->vfd_encoder);
1453
1454vb2_allocator_rollback:
1455 vb2_dma_contig_cleanup_ctx(jpeg->alloc_ctx);
1456
1457m2m_init_rollback:
1458 v4l2_m2m_release(jpeg->m2m_dev);
1459
1460device_register_rollback:
1461 v4l2_device_unregister(&jpeg->v4l2_dev);
1462
1463clk_get_rollback:
1464 clk_disable(jpeg->clk);
1465 clk_put(jpeg->clk);
1466
1467 return ret;
1468}
1469
1470static int s5p_jpeg_remove(struct platform_device *pdev)
1471{
1472 struct s5p_jpeg *jpeg = platform_get_drvdata(pdev);
1473
1474 pm_runtime_disable(jpeg->dev);
1475
1476 video_unregister_device(jpeg->vfd_decoder);
1477 video_device_release(jpeg->vfd_decoder);
1478 video_unregister_device(jpeg->vfd_encoder);
1479 video_device_release(jpeg->vfd_encoder);
1480 vb2_dma_contig_cleanup_ctx(jpeg->alloc_ctx);
1481 v4l2_m2m_release(jpeg->m2m_dev);
1482 v4l2_device_unregister(&jpeg->v4l2_dev);
1483
1484 clk_disable(jpeg->clk);
1485 clk_put(jpeg->clk);
1486
1487 return 0;
1488}
1489
1490static int s5p_jpeg_runtime_suspend(struct device *dev)
1491{
1492 return 0;
1493}
1494
1495static int s5p_jpeg_runtime_resume(struct device *dev)
1496{
1497 struct s5p_jpeg *jpeg = dev_get_drvdata(dev);
1498 /*
1499 * JPEG IP allows storing two Huffman tables for each component
1500 * We fill table 0 for each component
1501 */
1502 jpeg_set_hdctbl(jpeg->regs);
1503 jpeg_set_hdctblg(jpeg->regs);
1504 jpeg_set_hactbl(jpeg->regs);
1505 jpeg_set_hactblg(jpeg->regs);
1506 return 0;
1507}
1508
1509static const struct dev_pm_ops s5p_jpeg_pm_ops = {
1510 .runtime_suspend = s5p_jpeg_runtime_suspend,
1511 .runtime_resume = s5p_jpeg_runtime_resume,
1512};
1513
1514static struct platform_driver s5p_jpeg_driver = {
1515 .probe = s5p_jpeg_probe,
1516 .remove = s5p_jpeg_remove,
1517 .driver = {
1518 .owner = THIS_MODULE,
1519 .name = S5P_JPEG_M2M_NAME,
1520 .pm = &s5p_jpeg_pm_ops,
1521 },
1522};
1523
1524module_platform_driver(s5p_jpeg_driver);
1525
1526MODULE_AUTHOR("Andrzej Pietrasiewicz <andrzej.p@samsung.com>");
1527MODULE_DESCRIPTION("Samsung JPEG codec driver");
1528MODULE_LICENSE("GPL");
1529
diff --git a/drivers/media/video/s5p-jpeg/jpeg-core.h b/drivers/media/video/s5p-jpeg/jpeg-core.h
deleted file mode 100644
index 9d0cd2b76f61..000000000000
--- a/drivers/media/video/s5p-jpeg/jpeg-core.h
+++ /dev/null
@@ -1,150 +0,0 @@
1/* linux/drivers/media/video/s5p-jpeg/jpeg-core.h
2 *
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef JPEG_CORE_H_
14#define JPEG_CORE_H_
15
16#include <media/v4l2-device.h>
17#include <media/v4l2-fh.h>
18#include <media/v4l2-ctrls.h>
19
20#define S5P_JPEG_M2M_NAME "s5p-jpeg"
21
22/* JPEG compression quality setting */
23#define S5P_JPEG_COMPR_QUAL_BEST 0
24#define S5P_JPEG_COMPR_QUAL_WORST 3
25
26/* JPEG RGB to YCbCr conversion matrix coefficients */
27#define S5P_JPEG_COEF11 0x4d
28#define S5P_JPEG_COEF12 0x97
29#define S5P_JPEG_COEF13 0x1e
30#define S5P_JPEG_COEF21 0x2c
31#define S5P_JPEG_COEF22 0x57
32#define S5P_JPEG_COEF23 0x83
33#define S5P_JPEG_COEF31 0x83
34#define S5P_JPEG_COEF32 0x6e
35#define S5P_JPEG_COEF33 0x13
36
37/* a selection of JPEG markers */
38#define TEM 0x01
39#define SOF0 0xc0
40#define RST 0xd0
41#define SOI 0xd8
42#define EOI 0xd9
43#define DHP 0xde
44
45/* Flags that indicate a format can be used for capture/output */
46#define MEM2MEM_CAPTURE (1 << 0)
47#define MEM2MEM_OUTPUT (1 << 1)
48
49/**
50 * struct s5p_jpeg - JPEG IP abstraction
51 * @lock: the mutex protecting this structure
52 * @slock: spinlock protecting the device contexts
53 * @v4l2_dev: v4l2 device for mem2mem mode
54 * @vfd_encoder: video device node for encoder mem2mem mode
55 * @vfd_decoder: video device node for decoder mem2mem mode
56 * @m2m_dev: v4l2 mem2mem device data
57 * @regs: JPEG IP registers mapping
58 * @irq: JPEG IP irq
59 * @clk: JPEG IP clock
60 * @dev: JPEG IP struct device
61 * @alloc_ctx: videobuf2 memory allocator's context
62 */
63struct s5p_jpeg {
64 struct mutex lock;
65 struct spinlock slock;
66
67 struct v4l2_device v4l2_dev;
68 struct video_device *vfd_encoder;
69 struct video_device *vfd_decoder;
70 struct v4l2_m2m_dev *m2m_dev;
71
72 void __iomem *regs;
73 unsigned int irq;
74 struct clk *clk;
75 struct device *dev;
76 void *alloc_ctx;
77};
78
79/**
80 * struct jpeg_fmt - driver's internal color format data
81 * @name: format descritpion
82 * @fourcc: the fourcc code, 0 if not applicable
83 * @depth: number of bits per pixel
84 * @colplanes: number of color planes (1 for packed formats)
85 * @h_align: horizontal alignment order (align to 2^h_align)
86 * @v_align: vertical alignment order (align to 2^v_align)
87 * @types: types of queue this format is applicable to
88 */
89struct s5p_jpeg_fmt {
90 char *name;
91 u32 fourcc;
92 int depth;
93 int colplanes;
94 int h_align;
95 int v_align;
96 u32 types;
97};
98
99/**
100 * s5p_jpeg_q_data - parameters of one queue
101 * @fmt: driver-specific format of this queue
102 * @w: image width
103 * @h: image height
104 * @size: image buffer size in bytes
105 */
106struct s5p_jpeg_q_data {
107 struct s5p_jpeg_fmt *fmt;
108 u32 w;
109 u32 h;
110 u32 size;
111};
112
113/**
114 * s5p_jpeg_ctx - the device context data
115 * @jpeg: JPEG IP device for this context
116 * @mode: compression (encode) operation or decompression (decode)
117 * @compr_quality: destination image quality in compression (encode) mode
118 * @m2m_ctx: mem2mem device context
119 * @out_q: source (output) queue information
120 * @cap_fmt: destination (capture) queue queue information
121 * @hdr_parsed: set if header has been parsed during decompression
122 * @ctrl_handler: controls handler
123 */
124struct s5p_jpeg_ctx {
125 struct s5p_jpeg *jpeg;
126 unsigned int mode;
127 unsigned short compr_quality;
128 unsigned short restart_interval;
129 unsigned short subsampling;
130 struct v4l2_m2m_ctx *m2m_ctx;
131 struct s5p_jpeg_q_data out_q;
132 struct s5p_jpeg_q_data cap_q;
133 struct v4l2_fh fh;
134 bool hdr_parsed;
135 struct v4l2_ctrl_handler ctrl_handler;
136};
137
138/**
139 * s5p_jpeg_buffer - description of memory containing input JPEG data
140 * @size: buffer size
141 * @curr: current position in the buffer
142 * @data: pointer to the data
143 */
144struct s5p_jpeg_buffer {
145 unsigned long size;
146 unsigned long curr;
147 unsigned long data;
148};
149
150#endif /* JPEG_CORE_H */
diff --git a/drivers/media/video/s5p-jpeg/jpeg-hw.h b/drivers/media/video/s5p-jpeg/jpeg-hw.h
deleted file mode 100644
index f12f0fdbde7c..000000000000
--- a/drivers/media/video/s5p-jpeg/jpeg-hw.h
+++ /dev/null
@@ -1,357 +0,0 @@
1/* linux/drivers/media/video/s5p-jpeg/jpeg-hw.h
2 *
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12#ifndef JPEG_HW_H_
13#define JPEG_HW_H_
14
15#include <linux/io.h>
16#include <linux/videodev2.h>
17
18#include "jpeg-hw.h"
19#include "jpeg-regs.h"
20
21#define S5P_JPEG_MIN_WIDTH 32
22#define S5P_JPEG_MIN_HEIGHT 32
23#define S5P_JPEG_MAX_WIDTH 8192
24#define S5P_JPEG_MAX_HEIGHT 8192
25#define S5P_JPEG_ENCODE 0
26#define S5P_JPEG_DECODE 1
27#define S5P_JPEG_RAW_IN_565 0
28#define S5P_JPEG_RAW_IN_422 1
29#define S5P_JPEG_RAW_OUT_422 0
30#define S5P_JPEG_RAW_OUT_420 1
31
32static inline void jpeg_reset(void __iomem *regs)
33{
34 unsigned long reg;
35
36 writel(1, regs + S5P_JPG_SW_RESET);
37 reg = readl(regs + S5P_JPG_SW_RESET);
38 /* no other way but polling for when JPEG IP becomes operational */
39 while (reg != 0) {
40 cpu_relax();
41 reg = readl(regs + S5P_JPG_SW_RESET);
42 }
43}
44
45static inline void jpeg_poweron(void __iomem *regs)
46{
47 writel(S5P_POWER_ON, regs + S5P_JPGCLKCON);
48}
49
50static inline void jpeg_input_raw_mode(void __iomem *regs, unsigned long mode)
51{
52 unsigned long reg, m;
53
54 m = S5P_MOD_SEL_565;
55 if (mode == S5P_JPEG_RAW_IN_565)
56 m = S5P_MOD_SEL_565;
57 else if (mode == S5P_JPEG_RAW_IN_422)
58 m = S5P_MOD_SEL_422;
59
60 reg = readl(regs + S5P_JPGCMOD);
61 reg &= ~S5P_MOD_SEL_MASK;
62 reg |= m;
63 writel(reg, regs + S5P_JPGCMOD);
64}
65
66static inline void jpeg_input_raw_y16(void __iomem *regs, bool y16)
67{
68 unsigned long reg;
69
70 reg = readl(regs + S5P_JPGCMOD);
71 if (y16)
72 reg |= S5P_MODE_Y16;
73 else
74 reg &= ~S5P_MODE_Y16_MASK;
75 writel(reg, regs + S5P_JPGCMOD);
76}
77
78static inline void jpeg_proc_mode(void __iomem *regs, unsigned long mode)
79{
80 unsigned long reg, m;
81
82 m = S5P_PROC_MODE_DECOMPR;
83 if (mode == S5P_JPEG_ENCODE)
84 m = S5P_PROC_MODE_COMPR;
85 else
86 m = S5P_PROC_MODE_DECOMPR;
87 reg = readl(regs + S5P_JPGMOD);
88 reg &= ~S5P_PROC_MODE_MASK;
89 reg |= m;
90 writel(reg, regs + S5P_JPGMOD);
91}
92
93static inline void jpeg_subsampling_mode(void __iomem *regs, unsigned int mode)
94{
95 unsigned long reg, m;
96
97 if (mode == V4L2_JPEG_CHROMA_SUBSAMPLING_420)
98 m = S5P_SUBSAMPLING_MODE_420;
99 else
100 m = S5P_SUBSAMPLING_MODE_422;
101
102 reg = readl(regs + S5P_JPGMOD);
103 reg &= ~S5P_SUBSAMPLING_MODE_MASK;
104 reg |= m;
105 writel(reg, regs + S5P_JPGMOD);
106}
107
108static inline unsigned int jpeg_get_subsampling_mode(void __iomem *regs)
109{
110 return readl(regs + S5P_JPGMOD) & S5P_SUBSAMPLING_MODE_MASK;
111}
112
113static inline void jpeg_dri(void __iomem *regs, unsigned int dri)
114{
115 unsigned long reg;
116
117 reg = readl(regs + S5P_JPGDRI_U);
118 reg &= ~0xff;
119 reg |= (dri >> 8) & 0xff;
120 writel(reg, regs + S5P_JPGDRI_U);
121
122 reg = readl(regs + S5P_JPGDRI_L);
123 reg &= ~0xff;
124 reg |= dri & 0xff;
125 writel(reg, regs + S5P_JPGDRI_L);
126}
127
128static inline void jpeg_qtbl(void __iomem *regs, unsigned int t, unsigned int n)
129{
130 unsigned long reg;
131
132 reg = readl(regs + S5P_JPG_QTBL);
133 reg &= ~S5P_QT_NUMt_MASK(t);
134 reg |= (n << S5P_QT_NUMt_SHIFT(t)) & S5P_QT_NUMt_MASK(t);
135 writel(reg, regs + S5P_JPG_QTBL);
136}
137
138static inline void jpeg_htbl_ac(void __iomem *regs, unsigned int t)
139{
140 unsigned long reg;
141
142 reg = readl(regs + S5P_JPG_HTBL);
143 reg &= ~S5P_HT_NUMt_AC_MASK(t);
144 /* this driver uses table 0 for all color components */
145 reg |= (0 << S5P_HT_NUMt_AC_SHIFT(t)) & S5P_HT_NUMt_AC_MASK(t);
146 writel(reg, regs + S5P_JPG_HTBL);
147}
148
149static inline void jpeg_htbl_dc(void __iomem *regs, unsigned int t)
150{
151 unsigned long reg;
152
153 reg = readl(regs + S5P_JPG_HTBL);
154 reg &= ~S5P_HT_NUMt_DC_MASK(t);
155 /* this driver uses table 0 for all color components */
156 reg |= (0 << S5P_HT_NUMt_DC_SHIFT(t)) & S5P_HT_NUMt_DC_MASK(t);
157 writel(reg, regs + S5P_JPG_HTBL);
158}
159
160static inline void jpeg_y(void __iomem *regs, unsigned int y)
161{
162 unsigned long reg;
163
164 reg = readl(regs + S5P_JPGY_U);
165 reg &= ~0xff;
166 reg |= (y >> 8) & 0xff;
167 writel(reg, regs + S5P_JPGY_U);
168
169 reg = readl(regs + S5P_JPGY_L);
170 reg &= ~0xff;
171 reg |= y & 0xff;
172 writel(reg, regs + S5P_JPGY_L);
173}
174
175static inline void jpeg_x(void __iomem *regs, unsigned int x)
176{
177 unsigned long reg;
178
179 reg = readl(regs + S5P_JPGX_U);
180 reg &= ~0xff;
181 reg |= (x >> 8) & 0xff;
182 writel(reg, regs + S5P_JPGX_U);
183
184 reg = readl(regs + S5P_JPGX_L);
185 reg &= ~0xff;
186 reg |= x & 0xff;
187 writel(reg, regs + S5P_JPGX_L);
188}
189
190static inline void jpeg_rst_int_enable(void __iomem *regs, bool enable)
191{
192 unsigned long reg;
193
194 reg = readl(regs + S5P_JPGINTSE);
195 reg &= ~S5P_RSTm_INT_EN_MASK;
196 if (enable)
197 reg |= S5P_RSTm_INT_EN;
198 writel(reg, regs + S5P_JPGINTSE);
199}
200
201static inline void jpeg_data_num_int_enable(void __iomem *regs, bool enable)
202{
203 unsigned long reg;
204
205 reg = readl(regs + S5P_JPGINTSE);
206 reg &= ~S5P_DATA_NUM_INT_EN_MASK;
207 if (enable)
208 reg |= S5P_DATA_NUM_INT_EN;
209 writel(reg, regs + S5P_JPGINTSE);
210}
211
212static inline void jpeg_final_mcu_num_int_enable(void __iomem *regs, bool enbl)
213{
214 unsigned long reg;
215
216 reg = readl(regs + S5P_JPGINTSE);
217 reg &= ~S5P_FINAL_MCU_NUM_INT_EN_MASK;
218 if (enbl)
219 reg |= S5P_FINAL_MCU_NUM_INT_EN;
220 writel(reg, regs + S5P_JPGINTSE);
221}
222
223static inline void jpeg_timer_enable(void __iomem *regs, unsigned long val)
224{
225 unsigned long reg;
226
227 reg = readl(regs + S5P_JPG_TIMER_SE);
228 reg |= S5P_TIMER_INT_EN;
229 reg &= ~S5P_TIMER_INIT_MASK;
230 reg |= val & S5P_TIMER_INIT_MASK;
231 writel(reg, regs + S5P_JPG_TIMER_SE);
232}
233
234static inline void jpeg_timer_disable(void __iomem *regs)
235{
236 unsigned long reg;
237
238 reg = readl(regs + S5P_JPG_TIMER_SE);
239 reg &= ~S5P_TIMER_INT_EN_MASK;
240 writel(reg, regs + S5P_JPG_TIMER_SE);
241}
242
243static inline int jpeg_timer_stat(void __iomem *regs)
244{
245 return (int)((readl(regs + S5P_JPG_TIMER_ST) & S5P_TIMER_INT_STAT_MASK)
246 >> S5P_TIMER_INT_STAT_SHIFT);
247}
248
249static inline void jpeg_clear_timer_stat(void __iomem *regs)
250{
251 unsigned long reg;
252
253 reg = readl(regs + S5P_JPG_TIMER_SE);
254 reg &= ~S5P_TIMER_INT_STAT_MASK;
255 writel(reg, regs + S5P_JPG_TIMER_SE);
256}
257
258static inline void jpeg_enc_stream_int(void __iomem *regs, unsigned long size)
259{
260 unsigned long reg;
261
262 reg = readl(regs + S5P_JPG_ENC_STREAM_INTSE);
263 reg &= ~S5P_ENC_STREAM_BOUND_MASK;
264 reg |= S5P_ENC_STREAM_INT_EN;
265 reg |= size & S5P_ENC_STREAM_BOUND_MASK;
266 writel(reg, regs + S5P_JPG_ENC_STREAM_INTSE);
267}
268
269static inline int jpeg_enc_stream_stat(void __iomem *regs)
270{
271 return (int)(readl(regs + S5P_JPG_ENC_STREAM_INTST) &
272 S5P_ENC_STREAM_INT_STAT_MASK);
273}
274
275static inline void jpeg_clear_enc_stream_stat(void __iomem *regs)
276{
277 unsigned long reg;
278
279 reg = readl(regs + S5P_JPG_ENC_STREAM_INTSE);
280 reg &= ~S5P_ENC_STREAM_INT_MASK;
281 writel(reg, regs + S5P_JPG_ENC_STREAM_INTSE);
282}
283
284static inline void jpeg_outform_raw(void __iomem *regs, unsigned long format)
285{
286 unsigned long reg, f;
287
288 f = S5P_DEC_OUT_FORMAT_422;
289 if (format == S5P_JPEG_RAW_OUT_422)
290 f = S5P_DEC_OUT_FORMAT_422;
291 else if (format == S5P_JPEG_RAW_OUT_420)
292 f = S5P_DEC_OUT_FORMAT_420;
293 reg = readl(regs + S5P_JPG_OUTFORM);
294 reg &= ~S5P_DEC_OUT_FORMAT_MASK;
295 reg |= f;
296 writel(reg, regs + S5P_JPG_OUTFORM);
297}
298
299static inline void jpeg_jpgadr(void __iomem *regs, unsigned long addr)
300{
301 writel(addr, regs + S5P_JPG_JPGADR);
302}
303
304static inline void jpeg_imgadr(void __iomem *regs, unsigned long addr)
305{
306 writel(addr, regs + S5P_JPG_IMGADR);
307}
308
309static inline void jpeg_coef(void __iomem *regs, unsigned int i,
310 unsigned int j, unsigned int coef)
311{
312 unsigned long reg;
313
314 reg = readl(regs + S5P_JPG_COEF(i));
315 reg &= ~S5P_COEFn_MASK(j);
316 reg |= (coef << S5P_COEFn_SHIFT(j)) & S5P_COEFn_MASK(j);
317 writel(reg, regs + S5P_JPG_COEF(i));
318}
319
320static inline void jpeg_start(void __iomem *regs)
321{
322 writel(1, regs + S5P_JSTART);
323}
324
325static inline int jpeg_result_stat_ok(void __iomem *regs)
326{
327 return (int)((readl(regs + S5P_JPGINTST) & S5P_RESULT_STAT_MASK)
328 >> S5P_RESULT_STAT_SHIFT);
329}
330
331static inline int jpeg_stream_stat_ok(void __iomem *regs)
332{
333 return !(int)((readl(regs + S5P_JPGINTST) & S5P_STREAM_STAT_MASK)
334 >> S5P_STREAM_STAT_SHIFT);
335}
336
337static inline void jpeg_clear_int(void __iomem *regs)
338{
339 unsigned long reg;
340
341 reg = readl(regs + S5P_JPGINTST);
342 writel(S5P_INT_RELEASE, regs + S5P_JPGCOM);
343 reg = readl(regs + S5P_JPGOPR);
344}
345
346static inline unsigned int jpeg_compressed_size(void __iomem *regs)
347{
348 unsigned long jpeg_size = 0;
349
350 jpeg_size |= (readl(regs + S5P_JPGCNT_U) & 0xff) << 16;
351 jpeg_size |= (readl(regs + S5P_JPGCNT_M) & 0xff) << 8;
352 jpeg_size |= (readl(regs + S5P_JPGCNT_L) & 0xff);
353
354 return (unsigned int)jpeg_size;
355}
356
357#endif /* JPEG_HW_H_ */
diff --git a/drivers/media/video/s5p-jpeg/jpeg-regs.h b/drivers/media/video/s5p-jpeg/jpeg-regs.h
deleted file mode 100644
index 91f4dd5f86dd..000000000000
--- a/drivers/media/video/s5p-jpeg/jpeg-regs.h
+++ /dev/null
@@ -1,170 +0,0 @@
1/* linux/drivers/media/video/s5p-jpeg/jpeg-regs.h
2 *
3 * Register definition file for Samsung JPEG codec driver
4 *
5 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
6 * http://www.samsung.com
7 *
8 * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#ifndef JPEG_REGS_H_
16#define JPEG_REGS_H_
17
18/* JPEG mode register */
19#define S5P_JPGMOD 0x00
20#define S5P_PROC_MODE_MASK (0x1 << 3)
21#define S5P_PROC_MODE_DECOMPR (0x1 << 3)
22#define S5P_PROC_MODE_COMPR (0x0 << 3)
23#define S5P_SUBSAMPLING_MODE_MASK 0x7
24#define S5P_SUBSAMPLING_MODE_444 (0x0 << 0)
25#define S5P_SUBSAMPLING_MODE_422 (0x1 << 0)
26#define S5P_SUBSAMPLING_MODE_420 (0x2 << 0)
27#define S5P_SUBSAMPLING_MODE_GRAY (0x3 << 0)
28
29/* JPEG operation status register */
30#define S5P_JPGOPR 0x04
31
32/* Quantization tables*/
33#define S5P_JPG_QTBL 0x08
34#define S5P_QT_NUMt_SHIFT(t) (((t) - 1) << 1)
35#define S5P_QT_NUMt_MASK(t) (0x3 << S5P_QT_NUMt_SHIFT(t))
36
37/* Huffman tables */
38#define S5P_JPG_HTBL 0x0c
39#define S5P_HT_NUMt_AC_SHIFT(t) (((t) << 1) - 1)
40#define S5P_HT_NUMt_AC_MASK(t) (0x1 << S5P_HT_NUMt_AC_SHIFT(t))
41
42#define S5P_HT_NUMt_DC_SHIFT(t) (((t) - 1) << 1)
43#define S5P_HT_NUMt_DC_MASK(t) (0x1 << S5P_HT_NUMt_DC_SHIFT(t))
44
45/* JPEG restart interval register upper byte */
46#define S5P_JPGDRI_U 0x10
47
48/* JPEG restart interval register lower byte */
49#define S5P_JPGDRI_L 0x14
50
51/* JPEG vertical resolution register upper byte */
52#define S5P_JPGY_U 0x18
53
54/* JPEG vertical resolution register lower byte */
55#define S5P_JPGY_L 0x1c
56
57/* JPEG horizontal resolution register upper byte */
58#define S5P_JPGX_U 0x20
59
60/* JPEG horizontal resolution register lower byte */
61#define S5P_JPGX_L 0x24
62
63/* JPEG byte count register upper byte */
64#define S5P_JPGCNT_U 0x28
65
66/* JPEG byte count register middle byte */
67#define S5P_JPGCNT_M 0x2c
68
69/* JPEG byte count register lower byte */
70#define S5P_JPGCNT_L 0x30
71
72/* JPEG interrupt setting register */
73#define S5P_JPGINTSE 0x34
74#define S5P_RSTm_INT_EN_MASK (0x1 << 7)
75#define S5P_RSTm_INT_EN (0x1 << 7)
76#define S5P_DATA_NUM_INT_EN_MASK (0x1 << 6)
77#define S5P_DATA_NUM_INT_EN (0x1 << 6)
78#define S5P_FINAL_MCU_NUM_INT_EN_MASK (0x1 << 5)
79#define S5P_FINAL_MCU_NUM_INT_EN (0x1 << 5)
80
81/* JPEG interrupt status register */
82#define S5P_JPGINTST 0x38
83#define S5P_RESULT_STAT_SHIFT 6
84#define S5P_RESULT_STAT_MASK (0x1 << S5P_RESULT_STAT_SHIFT)
85#define S5P_STREAM_STAT_SHIFT 5
86#define S5P_STREAM_STAT_MASK (0x1 << S5P_STREAM_STAT_SHIFT)
87
88/* JPEG command register */
89#define S5P_JPGCOM 0x4c
90#define S5P_INT_RELEASE (0x1 << 2)
91
92/* Raw image data r/w address register */
93#define S5P_JPG_IMGADR 0x50
94
95/* JPEG file r/w address register */
96#define S5P_JPG_JPGADR 0x58
97
98/* Coefficient for RGB-to-YCbCr converter register */
99#define S5P_JPG_COEF(n) (0x5c + (((n) - 1) << 2))
100#define S5P_COEFn_SHIFT(j) ((3 - (j)) << 3)
101#define S5P_COEFn_MASK(j) (0xff << S5P_COEFn_SHIFT(j))
102
103/* JPEG color mode register */
104#define S5P_JPGCMOD 0x68
105#define S5P_MOD_SEL_MASK (0x7 << 5)
106#define S5P_MOD_SEL_422 (0x1 << 5)
107#define S5P_MOD_SEL_565 (0x2 << 5)
108#define S5P_MODE_Y16_MASK (0x1 << 1)
109#define S5P_MODE_Y16 (0x1 << 1)
110
111/* JPEG clock control register */
112#define S5P_JPGCLKCON 0x6c
113#define S5P_CLK_DOWN_READY (0x1 << 1)
114#define S5P_POWER_ON (0x1 << 0)
115
116/* JPEG start register */
117#define S5P_JSTART 0x70
118
119/* JPEG SW reset register */
120#define S5P_JPG_SW_RESET 0x78
121
122/* JPEG timer setting register */
123#define S5P_JPG_TIMER_SE 0x7c
124#define S5P_TIMER_INT_EN_MASK (0x1 << 31)
125#define S5P_TIMER_INT_EN (0x1 << 31)
126#define S5P_TIMER_INIT_MASK 0x7fffffff
127
128/* JPEG timer status register */
129#define S5P_JPG_TIMER_ST 0x80
130#define S5P_TIMER_INT_STAT_SHIFT 31
131#define S5P_TIMER_INT_STAT_MASK (0x1 << S5P_TIMER_INT_STAT_SHIFT)
132#define S5P_TIMER_CNT_SHIFT 0
133#define S5P_TIMER_CNT_MASK 0x7fffffff
134
135/* JPEG decompression output format register */
136#define S5P_JPG_OUTFORM 0x88
137#define S5P_DEC_OUT_FORMAT_MASK (0x1 << 0)
138#define S5P_DEC_OUT_FORMAT_422 (0x0 << 0)
139#define S5P_DEC_OUT_FORMAT_420 (0x1 << 0)
140
141/* JPEG version register */
142#define S5P_JPG_VERSION 0x8c
143
144/* JPEG compressed stream size interrupt setting register */
145#define S5P_JPG_ENC_STREAM_INTSE 0x98
146#define S5P_ENC_STREAM_INT_MASK (0x1 << 24)
147#define S5P_ENC_STREAM_INT_EN (0x1 << 24)
148#define S5P_ENC_STREAM_BOUND_MASK 0xffffff
149
150/* JPEG compressed stream size interrupt status register */
151#define S5P_JPG_ENC_STREAM_INTST 0x9c
152#define S5P_ENC_STREAM_INT_STAT_MASK 0x1
153
154/* JPEG quantizer table register */
155#define S5P_JPG_QTBL_CONTENT(n) (0x400 + (n) * 0x100)
156
157/* JPEG DC Huffman table register */
158#define S5P_JPG_HDCTBL(n) (0x800 + (n) * 0x400)
159
160/* JPEG DC Huffman table register */
161#define S5P_JPG_HDCTBLG(n) (0x840 + (n) * 0x400)
162
163/* JPEG AC Huffman table register */
164#define S5P_JPG_HACTBL(n) (0x880 + (n) * 0x400)
165
166/* JPEG AC Huffman table register */
167#define S5P_JPG_HACTBLG(n) (0x8c0 + (n) * 0x400)
168
169#endif /* JPEG_REGS_H_ */
170
diff --git a/drivers/media/video/s5p-mfc/Makefile b/drivers/media/video/s5p-mfc/Makefile
deleted file mode 100644
index d0663409af00..000000000000
--- a/drivers/media/video/s5p-mfc/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
1obj-$(CONFIG_VIDEO_SAMSUNG_S5P_MFC) := s5p-mfc.o
2s5p-mfc-y += s5p_mfc.o s5p_mfc_intr.o s5p_mfc_opr.o
3s5p-mfc-y += s5p_mfc_dec.o s5p_mfc_enc.o
4s5p-mfc-y += s5p_mfc_ctrl.o s5p_mfc_cmd.o
5s5p-mfc-y += s5p_mfc_pm.o s5p_mfc_shm.o
diff --git a/drivers/media/video/s5p-mfc/regs-mfc.h b/drivers/media/video/s5p-mfc/regs-mfc.h
deleted file mode 100644
index a19bece41ba9..000000000000
--- a/drivers/media/video/s5p-mfc/regs-mfc.h
+++ /dev/null
@@ -1,418 +0,0 @@
1/*
2 * Register definition file for Samsung MFC V5.1 Interface (FIMV) driver
3 *
4 * Kamil Debski, Copyright (c) 2010 Samsung Electronics
5 * http://www.samsung.com/
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10*/
11
12#ifndef _REGS_FIMV_H
13#define _REGS_FIMV_H
14
15#define S5P_FIMV_REG_SIZE (S5P_FIMV_END_ADDR - S5P_FIMV_START_ADDR)
16#define S5P_FIMV_REG_COUNT ((S5P_FIMV_END_ADDR - S5P_FIMV_START_ADDR) / 4)
17
18/* Number of bits that the buffer address should be shifted for particular
19 * MFC buffers. */
20#define S5P_FIMV_START_ADDR 0x0000
21#define S5P_FIMV_END_ADDR 0xe008
22
23#define S5P_FIMV_SW_RESET 0x0000
24#define S5P_FIMV_RISC_HOST_INT 0x0008
25
26/* Command from HOST to RISC */
27#define S5P_FIMV_HOST2RISC_CMD 0x0030
28#define S5P_FIMV_HOST2RISC_ARG1 0x0034
29#define S5P_FIMV_HOST2RISC_ARG2 0x0038
30#define S5P_FIMV_HOST2RISC_ARG3 0x003c
31#define S5P_FIMV_HOST2RISC_ARG4 0x0040
32
33/* Command from RISC to HOST */
34#define S5P_FIMV_RISC2HOST_CMD 0x0044
35#define S5P_FIMV_RISC2HOST_CMD_MASK 0x1FFFF
36#define S5P_FIMV_RISC2HOST_ARG1 0x0048
37#define S5P_FIMV_RISC2HOST_ARG2 0x004c
38#define S5P_FIMV_RISC2HOST_ARG3 0x0050
39#define S5P_FIMV_RISC2HOST_ARG4 0x0054
40
41#define S5P_FIMV_FW_VERSION 0x0058
42#define S5P_FIMV_SYS_MEM_SZ 0x005c
43#define S5P_FIMV_FW_STATUS 0x0080
44
45/* Memory controller register */
46#define S5P_FIMV_MC_DRAMBASE_ADR_A 0x0508
47#define S5P_FIMV_MC_DRAMBASE_ADR_B 0x050c
48#define S5P_FIMV_MC_STATUS 0x0510
49
50/* Common register */
51#define S5P_FIMV_COMMON_BASE_A 0x0600
52#define S5P_FIMV_COMMON_BASE_B 0x0700
53
54/* Decoder */
55#define S5P_FIMV_DEC_CHROMA_ADR (S5P_FIMV_COMMON_BASE_A)
56#define S5P_FIMV_DEC_LUMA_ADR (S5P_FIMV_COMMON_BASE_B)
57
58/* H.264 decoding */
59#define S5P_FIMV_H264_VERT_NB_MV_ADR (S5P_FIMV_COMMON_BASE_A + 0x8c)
60 /* vertical neighbor motion vector */
61#define S5P_FIMV_H264_NB_IP_ADR (S5P_FIMV_COMMON_BASE_A + 0x90)
62 /* neighbor pixels for intra pred */
63#define S5P_FIMV_H264_MV_ADR (S5P_FIMV_COMMON_BASE_B + 0x80)
64 /* H264 motion vector */
65
66/* MPEG4 decoding */
67#define S5P_FIMV_MPEG4_NB_DCAC_ADR (S5P_FIMV_COMMON_BASE_A + 0x8c)
68 /* neighbor AC/DC coeff. */
69#define S5P_FIMV_MPEG4_UP_NB_MV_ADR (S5P_FIMV_COMMON_BASE_A + 0x90)
70 /* upper neighbor motion vector */
71#define S5P_FIMV_MPEG4_SA_MV_ADR (S5P_FIMV_COMMON_BASE_A + 0x94)
72 /* subseq. anchor motion vector */
73#define S5P_FIMV_MPEG4_OT_LINE_ADR (S5P_FIMV_COMMON_BASE_A + 0x98)
74 /* overlap transform line */
75#define S5P_FIMV_MPEG4_SP_ADR (S5P_FIMV_COMMON_BASE_A + 0xa8)
76 /* syntax parser */
77
78/* H.263 decoding */
79#define S5P_FIMV_H263_NB_DCAC_ADR (S5P_FIMV_COMMON_BASE_A + 0x8c)
80#define S5P_FIMV_H263_UP_NB_MV_ADR (S5P_FIMV_COMMON_BASE_A + 0x90)
81#define S5P_FIMV_H263_SA_MV_ADR (S5P_FIMV_COMMON_BASE_A + 0x94)
82#define S5P_FIMV_H263_OT_LINE_ADR (S5P_FIMV_COMMON_BASE_A + 0x98)
83
84/* VC-1 decoding */
85#define S5P_FIMV_VC1_NB_DCAC_ADR (S5P_FIMV_COMMON_BASE_A + 0x8c)
86#define S5P_FIMV_VC1_UP_NB_MV_ADR (S5P_FIMV_COMMON_BASE_A + 0x90)
87#define S5P_FIMV_VC1_SA_MV_ADR (S5P_FIMV_COMMON_BASE_A + 0x94)
88#define S5P_FIMV_VC1_OT_LINE_ADR (S5P_FIMV_COMMON_BASE_A + 0x98)
89#define S5P_FIMV_VC1_BITPLANE3_ADR (S5P_FIMV_COMMON_BASE_A + 0x9c)
90 /* bitplane3 */
91#define S5P_FIMV_VC1_BITPLANE2_ADR (S5P_FIMV_COMMON_BASE_A + 0xa0)
92 /* bitplane2 */
93#define S5P_FIMV_VC1_BITPLANE1_ADR (S5P_FIMV_COMMON_BASE_A + 0xa4)
94 /* bitplane1 */
95
96/* Encoder */
97#define S5P_FIMV_ENC_REF0_LUMA_ADR (S5P_FIMV_COMMON_BASE_A + 0x1c)
98#define S5P_FIMV_ENC_REF1_LUMA_ADR (S5P_FIMV_COMMON_BASE_A + 0x20)
99 /* reconstructed luma */
100#define S5P_FIMV_ENC_REF0_CHROMA_ADR (S5P_FIMV_COMMON_BASE_B)
101#define S5P_FIMV_ENC_REF1_CHROMA_ADR (S5P_FIMV_COMMON_BASE_B + 0x04)
102 /* reconstructed chroma */
103#define S5P_FIMV_ENC_REF2_LUMA_ADR (S5P_FIMV_COMMON_BASE_B + 0x10)
104#define S5P_FIMV_ENC_REF2_CHROMA_ADR (S5P_FIMV_COMMON_BASE_B + 0x08)
105#define S5P_FIMV_ENC_REF3_LUMA_ADR (S5P_FIMV_COMMON_BASE_B + 0x14)
106#define S5P_FIMV_ENC_REF3_CHROMA_ADR (S5P_FIMV_COMMON_BASE_B + 0x0c)
107
108/* H.264 encoding */
109#define S5P_FIMV_H264_UP_MV_ADR (S5P_FIMV_COMMON_BASE_A)
110 /* upper motion vector */
111#define S5P_FIMV_H264_NBOR_INFO_ADR (S5P_FIMV_COMMON_BASE_A + 0x04)
112 /* entropy engine's neighbor info. */
113#define S5P_FIMV_H264_UP_INTRA_MD_ADR (S5P_FIMV_COMMON_BASE_A + 0x08)
114 /* upper intra MD */
115#define S5P_FIMV_H264_COZERO_FLAG_ADR (S5P_FIMV_COMMON_BASE_A + 0x10)
116 /* direct cozero flag */
117#define S5P_FIMV_H264_UP_INTRA_PRED_ADR (S5P_FIMV_COMMON_BASE_B + 0x40)
118 /* upper intra PRED */
119
120/* H.263 encoding */
121#define S5P_FIMV_H263_UP_MV_ADR (S5P_FIMV_COMMON_BASE_A)
122 /* upper motion vector */
123#define S5P_FIMV_H263_ACDC_COEF_ADR (S5P_FIMV_COMMON_BASE_A + 0x04)
124 /* upper Q coeff. */
125
126/* MPEG4 encoding */
127#define S5P_FIMV_MPEG4_UP_MV_ADR (S5P_FIMV_COMMON_BASE_A)
128 /* upper motion vector */
129#define S5P_FIMV_MPEG4_ACDC_COEF_ADR (S5P_FIMV_COMMON_BASE_A + 0x04)
130 /* upper Q coeff. */
131#define S5P_FIMV_MPEG4_COZERO_FLAG_ADR (S5P_FIMV_COMMON_BASE_A + 0x10)
132 /* direct cozero flag */
133
134#define S5P_FIMV_ENC_REF_B_LUMA_ADR 0x062c /* ref B Luma addr */
135#define S5P_FIMV_ENC_REF_B_CHROMA_ADR 0x0630 /* ref B Chroma addr */
136
137#define S5P_FIMV_ENC_CUR_LUMA_ADR 0x0718 /* current Luma addr */
138#define S5P_FIMV_ENC_CUR_CHROMA_ADR 0x071C /* current Chroma addr */
139
140/* Codec common register */
141#define S5P_FIMV_ENC_HSIZE_PX 0x0818 /* frame width at encoder */
142#define S5P_FIMV_ENC_VSIZE_PX 0x081c /* frame height at encoder */
143#define S5P_FIMV_ENC_PROFILE 0x0830 /* profile register */
144#define S5P_FIMV_ENC_PROFILE_H264_MAIN 0
145#define S5P_FIMV_ENC_PROFILE_H264_HIGH 1
146#define S5P_FIMV_ENC_PROFILE_H264_BASELINE 2
147#define S5P_FIMV_ENC_PROFILE_MPEG4_SIMPLE 0
148#define S5P_FIMV_ENC_PROFILE_MPEG4_ADVANCED_SIMPLE 1
149#define S5P_FIMV_ENC_PIC_STRUCT 0x083c /* picture field/frame flag */
150#define S5P_FIMV_ENC_LF_CTRL 0x0848 /* loop filter control */
151#define S5P_FIMV_ENC_ALPHA_OFF 0x084c /* loop filter alpha offset */
152#define S5P_FIMV_ENC_BETA_OFF 0x0850 /* loop filter beta offset */
153#define S5P_FIMV_MR_BUSIF_CTRL 0x0854 /* hidden, bus interface ctrl */
154#define S5P_FIMV_ENC_PXL_CACHE_CTRL 0x0a00 /* pixel cache control */
155
156/* Channel & stream interface register */
157#define S5P_FIMV_SI_RTN_CHID 0x2000 /* Return CH inst ID register */
158#define S5P_FIMV_SI_CH0_INST_ID 0x2040 /* codec instance ID */
159#define S5P_FIMV_SI_CH1_INST_ID 0x2080 /* codec instance ID */
160/* Decoder */
161#define S5P_FIMV_SI_VRESOL 0x2004 /* vertical res of decoder */
162#define S5P_FIMV_SI_HRESOL 0x2008 /* horizontal res of decoder */
163#define S5P_FIMV_SI_BUF_NUMBER 0x200c /* number of frames in the
164 decoded pic */
165#define S5P_FIMV_SI_DISPLAY_Y_ADR 0x2010 /* luma addr of displayed pic */
166#define S5P_FIMV_SI_DISPLAY_C_ADR 0x2014 /* chroma addrof displayed pic */
167
168#define S5P_FIMV_SI_CONSUMED_BYTES 0x2018 /* Consumed number of bytes to
169 decode a frame */
170#define S5P_FIMV_SI_DISPLAY_STATUS 0x201c /* status of decoded picture */
171
172#define S5P_FIMV_SI_DECODE_Y_ADR 0x2024 /* luma addr of decoded pic */
173#define S5P_FIMV_SI_DECODE_C_ADR 0x2028 /* chroma addrof decoded pic */
174#define S5P_FIMV_SI_DECODE_STATUS 0x202c /* status of decoded picture */
175
176#define S5P_FIMV_SI_CH0_SB_ST_ADR 0x2044 /* start addr of stream buf */
177#define S5P_FIMV_SI_CH0_SB_FRM_SIZE 0x2048 /* size of stream buf */
178#define S5P_FIMV_SI_CH0_DESC_ADR 0x204c /* addr of descriptor buf */
179#define S5P_FIMV_SI_CH0_CPB_SIZE 0x2058 /* max size of coded pic. buf */
180#define S5P_FIMV_SI_CH0_DESC_SIZE 0x205c /* max size of descriptor buf */
181
182#define S5P_FIMV_SI_CH1_SB_ST_ADR 0x2084 /* start addr of stream buf */
183#define S5P_FIMV_SI_CH1_SB_FRM_SIZE 0x2088 /* size of stream buf */
184#define S5P_FIMV_SI_CH1_DESC_ADR 0x208c /* addr of descriptor buf */
185#define S5P_FIMV_SI_CH1_CPB_SIZE 0x2098 /* max size of coded pic. buf */
186#define S5P_FIMV_SI_CH1_DESC_SIZE 0x209c /* max size of descriptor buf */
187
188#define S5P_FIMV_CRC_LUMA0 0x2030 /* luma crc data per frame
189 (top field) */
190#define S5P_FIMV_CRC_CHROMA0 0x2034 /* chroma crc data per frame
191 (top field) */
192#define S5P_FIMV_CRC_LUMA1 0x2038 /* luma crc data per bottom
193 field */
194#define S5P_FIMV_CRC_CHROMA1 0x203c /* chroma crc data per bottom
195 field */
196
197/* Display status */
198#define S5P_FIMV_DEC_STATUS_DECODING_ONLY 0
199#define S5P_FIMV_DEC_STATUS_DECODING_DISPLAY 1
200#define S5P_FIMV_DEC_STATUS_DISPLAY_ONLY 2
201#define S5P_FIMV_DEC_STATUS_DECODING_EMPTY 3
202#define S5P_FIMV_DEC_STATUS_DECODING_STATUS_MASK 7
203#define S5P_FIMV_DEC_STATUS_PROGRESSIVE (0<<3)
204#define S5P_FIMV_DEC_STATUS_INTERLACE (1<<3)
205#define S5P_FIMV_DEC_STATUS_INTERLACE_MASK (1<<3)
206#define S5P_FIMV_DEC_STATUS_CRC_NUMBER_TWO (0<<4)
207#define S5P_FIMV_DEC_STATUS_CRC_NUMBER_FOUR (1<<4)
208#define S5P_FIMV_DEC_STATUS_CRC_NUMBER_MASK (1<<4)
209#define S5P_FIMV_DEC_STATUS_CRC_GENERATED (1<<5)
210#define S5P_FIMV_DEC_STATUS_CRC_NOT_GENERATED (0<<5)
211#define S5P_FIMV_DEC_STATUS_CRC_MASK (1<<5)
212
213#define S5P_FIMV_DEC_STATUS_RESOLUTION_MASK (3<<4)
214#define S5P_FIMV_DEC_STATUS_RESOLUTION_INC (1<<4)
215#define S5P_FIMV_DEC_STATUS_RESOLUTION_DEC (2<<4)
216
217/* Decode frame address */
218#define S5P_FIMV_DECODE_Y_ADR 0x2024
219#define S5P_FIMV_DECODE_C_ADR 0x2028
220
221/* Decoded frame tpe */
222#define S5P_FIMV_DECODE_FRAME_TYPE 0x2020
223#define S5P_FIMV_DECODE_FRAME_MASK 7
224
225#define S5P_FIMV_DECODE_FRAME_SKIPPED 0
226#define S5P_FIMV_DECODE_FRAME_I_FRAME 1
227#define S5P_FIMV_DECODE_FRAME_P_FRAME 2
228#define S5P_FIMV_DECODE_FRAME_B_FRAME 3
229#define S5P_FIMV_DECODE_FRAME_OTHER_FRAME 4
230
231/* Sizes of buffers required for decoding */
232#define S5P_FIMV_DEC_NB_IP_SIZE (32 * 1024)
233#define S5P_FIMV_DEC_VERT_NB_MV_SIZE (16 * 1024)
234#define S5P_FIMV_DEC_NB_DCAC_SIZE (16 * 1024)
235#define S5P_FIMV_DEC_UPNB_MV_SIZE (68 * 1024)
236#define S5P_FIMV_DEC_SUB_ANCHOR_MV_SIZE (136 * 1024)
237#define S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE (32 * 1024)
238#define S5P_FIMV_DEC_VC1_BITPLANE_SIZE (2 * 1024)
239#define S5P_FIMV_DEC_STX_PARSER_SIZE (68 * 1024)
240
241#define S5P_FIMV_DEC_BUF_ALIGN (8 * 1024)
242#define S5P_FIMV_ENC_BUF_ALIGN (8 * 1024)
243#define S5P_FIMV_NV12M_HALIGN 16
244#define S5P_FIMV_NV12M_LVALIGN 16
245#define S5P_FIMV_NV12M_CVALIGN 8
246#define S5P_FIMV_NV12MT_HALIGN 128
247#define S5P_FIMV_NV12MT_VALIGN 32
248#define S5P_FIMV_NV12M_SALIGN 2048
249#define S5P_FIMV_NV12MT_SALIGN 8192
250
251/* Sizes of buffers required for encoding */
252#define S5P_FIMV_ENC_UPMV_SIZE 0x10000
253#define S5P_FIMV_ENC_COLFLG_SIZE 0x10000
254#define S5P_FIMV_ENC_INTRAMD_SIZE 0x10000
255#define S5P_FIMV_ENC_INTRAPRED_SIZE 0x4000
256#define S5P_FIMV_ENC_NBORINFO_SIZE 0x10000
257#define S5P_FIMV_ENC_ACDCCOEF_SIZE 0x10000
258
259/* Encoder */
260#define S5P_FIMV_ENC_SI_STRM_SIZE 0x2004 /* stream size */
261#define S5P_FIMV_ENC_SI_PIC_CNT 0x2008 /* picture count */
262#define S5P_FIMV_ENC_SI_WRITE_PTR 0x200c /* write pointer */
263#define S5P_FIMV_ENC_SI_SLICE_TYPE 0x2010 /* slice type(I/P/B/IDR) */
264#define S5P_FIMV_ENC_SI_SLICE_TYPE_NON_CODED 0
265#define S5P_FIMV_ENC_SI_SLICE_TYPE_I 1
266#define S5P_FIMV_ENC_SI_SLICE_TYPE_P 2
267#define S5P_FIMV_ENC_SI_SLICE_TYPE_B 3
268#define S5P_FIMV_ENC_SI_SLICE_TYPE_SKIPPED 4
269#define S5P_FIMV_ENC_SI_SLICE_TYPE_OTHERS 5
270#define S5P_FIMV_ENCODED_Y_ADDR 0x2014 /* the addr of the encoded
271 luma pic */
272#define S5P_FIMV_ENCODED_C_ADDR 0x2018 /* the addr of the encoded
273 chroma pic */
274
275#define S5P_FIMV_ENC_SI_CH0_SB_ADR 0x2044 /* addr of stream buf */
276#define S5P_FIMV_ENC_SI_CH0_SB_SIZE 0x204c /* size of stream buf */
277#define S5P_FIMV_ENC_SI_CH0_CUR_Y_ADR 0x2050 /* current Luma addr */
278#define S5P_FIMV_ENC_SI_CH0_CUR_C_ADR 0x2054 /* current Chroma addr */
279#define S5P_FIMV_ENC_SI_CH0_FRAME_INS 0x2058 /* frame insertion */
280
281#define S5P_FIMV_ENC_SI_CH1_SB_ADR 0x2084 /* addr of stream buf */
282#define S5P_FIMV_ENC_SI_CH1_SB_SIZE 0x208c /* size of stream buf */
283#define S5P_FIMV_ENC_SI_CH1_CUR_Y_ADR 0x2090 /* current Luma addr */
284#define S5P_FIMV_ENC_SI_CH1_CUR_C_ADR 0x2094 /* current Chroma addr */
285#define S5P_FIMV_ENC_SI_CH1_FRAME_INS 0x2098 /* frame insertion */
286
287#define S5P_FIMV_ENC_PIC_TYPE_CTRL 0xc504 /* pic type level control */
288#define S5P_FIMV_ENC_B_RECON_WRITE_ON 0xc508 /* B frame recon write ctrl */
289#define S5P_FIMV_ENC_MSLICE_CTRL 0xc50c /* multi slice control */
290#define S5P_FIMV_ENC_MSLICE_MB 0xc510 /* MB number in the one slice */
291#define S5P_FIMV_ENC_MSLICE_BIT 0xc514 /* bit count for one slice */
292#define S5P_FIMV_ENC_CIR_CTRL 0xc518 /* number of intra refresh MB */
293#define S5P_FIMV_ENC_MAP_FOR_CUR 0xc51c /* linear or tiled mode */
294#define S5P_FIMV_ENC_PADDING_CTRL 0xc520 /* padding control */
295
296#define S5P_FIMV_ENC_RC_CONFIG 0xc5a0 /* RC config */
297#define S5P_FIMV_ENC_RC_BIT_RATE 0xc5a8 /* bit rate */
298#define S5P_FIMV_ENC_RC_QBOUND 0xc5ac /* max/min QP */
299#define S5P_FIMV_ENC_RC_RPARA 0xc5b0 /* rate control reaction coeff */
300#define S5P_FIMV_ENC_RC_MB_CTRL 0xc5b4 /* MB adaptive scaling */
301
302/* Encoder for H264 only */
303#define S5P_FIMV_ENC_H264_ENTROPY_MODE 0xd004 /* CAVLC or CABAC */
304#define S5P_FIMV_ENC_H264_ALPHA_OFF 0xd008 /* loop filter alpha offset */
305#define S5P_FIMV_ENC_H264_BETA_OFF 0xd00c /* loop filter beta offset */
306#define S5P_FIMV_ENC_H264_NUM_OF_REF 0xd010 /* number of reference for P/B */
307#define S5P_FIMV_ENC_H264_TRANS_FLAG 0xd034 /* 8x8 transform flag in PPS &
308 high profile */
309
310#define S5P_FIMV_ENC_RC_FRAME_RATE 0xd0d0 /* frame rate */
311
312/* Encoder for MPEG4 only */
313#define S5P_FIMV_ENC_MPEG4_QUART_PXL 0xe008 /* qpel interpolation ctrl */
314
315/* Additional */
316#define S5P_FIMV_SI_CH0_DPB_CONF_CTRL 0x2068 /* DPB Config Control Register */
317#define S5P_FIMV_SLICE_INT_MASK 1
318#define S5P_FIMV_SLICE_INT_SHIFT 31
319#define S5P_FIMV_DDELAY_ENA_SHIFT 30
320#define S5P_FIMV_DDELAY_VAL_MASK 0xff
321#define S5P_FIMV_DDELAY_VAL_SHIFT 16
322#define S5P_FIMV_DPB_COUNT_MASK 0xffff
323#define S5P_FIMV_DPB_FLUSH_MASK 1
324#define S5P_FIMV_DPB_FLUSH_SHIFT 14
325
326
327#define S5P_FIMV_SI_CH0_RELEASE_BUF 0x2060 /* DPB release buffer register */
328#define S5P_FIMV_SI_CH0_HOST_WR_ADR 0x2064 /* address of shared memory */
329
330/* Codec numbers */
331#define S5P_FIMV_CODEC_NONE -1
332
333#define S5P_FIMV_CODEC_H264_DEC 0
334#define S5P_FIMV_CODEC_VC1_DEC 1
335#define S5P_FIMV_CODEC_MPEG4_DEC 2
336#define S5P_FIMV_CODEC_MPEG2_DEC 3
337#define S5P_FIMV_CODEC_H263_DEC 4
338#define S5P_FIMV_CODEC_VC1RCV_DEC 5
339
340#define S5P_FIMV_CODEC_H264_ENC 16
341#define S5P_FIMV_CODEC_MPEG4_ENC 17
342#define S5P_FIMV_CODEC_H263_ENC 18
343
344/* Channel Control Register */
345#define S5P_FIMV_CH_SEQ_HEADER 1
346#define S5P_FIMV_CH_FRAME_START 2
347#define S5P_FIMV_CH_LAST_FRAME 3
348#define S5P_FIMV_CH_INIT_BUFS 4
349#define S5P_FIMV_CH_FRAME_START_REALLOC 5
350#define S5P_FIMV_CH_MASK 7
351#define S5P_FIMV_CH_SHIFT 16
352
353
354/* Host to RISC command */
355#define S5P_FIMV_H2R_CMD_EMPTY 0
356#define S5P_FIMV_H2R_CMD_OPEN_INSTANCE 1
357#define S5P_FIMV_H2R_CMD_CLOSE_INSTANCE 2
358#define S5P_FIMV_H2R_CMD_SYS_INIT 3
359#define S5P_FIMV_H2R_CMD_FLUSH 4
360#define S5P_FIMV_H2R_CMD_SLEEP 5
361#define S5P_FIMV_H2R_CMD_WAKEUP 6
362
363#define S5P_FIMV_R2H_CMD_EMPTY 0
364#define S5P_FIMV_R2H_CMD_OPEN_INSTANCE_RET 1
365#define S5P_FIMV_R2H_CMD_CLOSE_INSTANCE_RET 2
366#define S5P_FIMV_R2H_CMD_RSV_RET 3
367#define S5P_FIMV_R2H_CMD_SEQ_DONE_RET 4
368#define S5P_FIMV_R2H_CMD_FRAME_DONE_RET 5
369#define S5P_FIMV_R2H_CMD_SLICE_DONE_RET 6
370#define S5P_FIMV_R2H_CMD_ENC_COMPLETE_RET 7
371#define S5P_FIMV_R2H_CMD_SYS_INIT_RET 8
372#define S5P_FIMV_R2H_CMD_FW_STATUS_RET 9
373#define S5P_FIMV_R2H_CMD_SLEEP_RET 10
374#define S5P_FIMV_R2H_CMD_WAKEUP_RET 11
375#define S5P_FIMV_R2H_CMD_FLUSH_RET 12
376#define S5P_FIMV_R2H_CMD_INIT_BUFFERS_RET 15
377#define S5P_FIMV_R2H_CMD_EDFU_INIT_RET 16
378#define S5P_FIMV_R2H_CMD_ERR_RET 32
379
380/* Error handling defines */
381#define S5P_FIMV_ERR_WARNINGS_START 145
382#define S5P_FIMV_ERR_DEC_MASK 0xFFFF
383#define S5P_FIMV_ERR_DEC_SHIFT 0
384#define S5P_FIMV_ERR_DSPL_MASK 0xFFFF0000
385#define S5P_FIMV_ERR_DSPL_SHIFT 16
386
387/* Shared memory registers' offsets */
388
389/* An offset of the start position in the stream when
390 * the start position is not aligned */
391#define S5P_FIMV_SHARED_CROP_INFO_H 0x0020
392#define S5P_FIMV_SHARED_CROP_LEFT_MASK 0xFFFF
393#define S5P_FIMV_SHARED_CROP_LEFT_SHIFT 0
394#define S5P_FIMV_SHARED_CROP_RIGHT_MASK 0xFFFF0000
395#define S5P_FIMV_SHARED_CROP_RIGHT_SHIFT 16
396#define S5P_FIMV_SHARED_CROP_INFO_V 0x0024
397#define S5P_FIMV_SHARED_CROP_TOP_MASK 0xFFFF
398#define S5P_FIMV_SHARED_CROP_TOP_SHIFT 0
399#define S5P_FIMV_SHARED_CROP_BOTTOM_MASK 0xFFFF0000
400#define S5P_FIMV_SHARED_CROP_BOTTOM_SHIFT 16
401#define S5P_FIMV_SHARED_SET_FRAME_TAG 0x0004
402#define S5P_FIMV_SHARED_GET_FRAME_TAG_TOP 0x0008
403#define S5P_FIMV_SHARED_GET_FRAME_TAG_BOT 0x000C
404#define S5P_FIMV_SHARED_START_BYTE_NUM 0x0018
405#define S5P_FIMV_SHARED_RC_VOP_TIMING 0x0030
406#define S5P_FIMV_SHARED_LUMA_DPB_SIZE 0x0064
407#define S5P_FIMV_SHARED_CHROMA_DPB_SIZE 0x0068
408#define S5P_FIMV_SHARED_MV_SIZE 0x006C
409#define S5P_FIMV_SHARED_PIC_TIME_TOP 0x0010
410#define S5P_FIMV_SHARED_PIC_TIME_BOTTOM 0x0014
411#define S5P_FIMV_SHARED_EXT_ENC_CONTROL 0x0028
412#define S5P_FIMV_SHARED_P_B_FRAME_QP 0x0070
413#define S5P_FIMV_SHARED_ASPECT_RATIO_IDC 0x0074
414#define S5P_FIMV_SHARED_EXTENDED_SAR 0x0078
415#define S5P_FIMV_SHARED_H264_I_PERIOD 0x009C
416#define S5P_FIMV_SHARED_RC_CONTROL_CONFIG 0x00A0
417
418#endif /* _REGS_FIMV_H */
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc.c b/drivers/media/video/s5p-mfc/s5p_mfc.c
deleted file mode 100644
index e3e616d8a09d..000000000000
--- a/drivers/media/video/s5p-mfc/s5p_mfc.c
+++ /dev/null
@@ -1,1230 +0,0 @@
1/*
2 * Samsung S5P Multi Format Codec v 5.1
3 *
4 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
5 * Kamil Debski, <k.debski@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <linux/clk.h>
14#include <linux/delay.h>
15#include <linux/interrupt.h>
16#include <linux/io.h>
17#include <linux/module.h>
18#include <linux/platform_device.h>
19#include <linux/sched.h>
20#include <linux/slab.h>
21#include <linux/videodev2.h>
22#include <linux/workqueue.h>
23#include <media/videobuf2-core.h>
24#include "regs-mfc.h"
25#include "s5p_mfc_ctrl.h"
26#include "s5p_mfc_debug.h"
27#include "s5p_mfc_dec.h"
28#include "s5p_mfc_enc.h"
29#include "s5p_mfc_intr.h"
30#include "s5p_mfc_opr.h"
31#include "s5p_mfc_pm.h"
32#include "s5p_mfc_shm.h"
33
34#define S5P_MFC_NAME "s5p-mfc"
35#define S5P_MFC_DEC_NAME "s5p-mfc-dec"
36#define S5P_MFC_ENC_NAME "s5p-mfc-enc"
37
38int debug;
39module_param(debug, int, S_IRUGO | S_IWUSR);
40MODULE_PARM_DESC(debug, "Debug level - higher value produces more verbose messages");
41
42/* Helper functions for interrupt processing */
43/* Remove from hw execution round robin */
44static void clear_work_bit(struct s5p_mfc_ctx *ctx)
45{
46 struct s5p_mfc_dev *dev = ctx->dev;
47
48 spin_lock(&dev->condlock);
49 clear_bit(ctx->num, &dev->ctx_work_bits);
50 spin_unlock(&dev->condlock);
51}
52
53/* Wake up context wait_queue */
54static void wake_up_ctx(struct s5p_mfc_ctx *ctx, unsigned int reason,
55 unsigned int err)
56{
57 ctx->int_cond = 1;
58 ctx->int_type = reason;
59 ctx->int_err = err;
60 wake_up(&ctx->queue);
61}
62
63/* Wake up device wait_queue */
64static void wake_up_dev(struct s5p_mfc_dev *dev, unsigned int reason,
65 unsigned int err)
66{
67 dev->int_cond = 1;
68 dev->int_type = reason;
69 dev->int_err = err;
70 wake_up(&dev->queue);
71}
72
73static void s5p_mfc_watchdog(unsigned long arg)
74{
75 struct s5p_mfc_dev *dev = (struct s5p_mfc_dev *)arg;
76
77 if (test_bit(0, &dev->hw_lock))
78 atomic_inc(&dev->watchdog_cnt);
79 if (atomic_read(&dev->watchdog_cnt) >= MFC_WATCHDOG_CNT) {
80 /* This means that hw is busy and no interrupts were
81 * generated by hw for the Nth time of running this
82 * watchdog timer. This usually means a serious hw
83 * error. Now it is time to kill all instances and
84 * reset the MFC. */
85 mfc_err("Time out during waiting for HW\n");
86 queue_work(dev->watchdog_workqueue, &dev->watchdog_work);
87 }
88 dev->watchdog_timer.expires = jiffies +
89 msecs_to_jiffies(MFC_WATCHDOG_INTERVAL);
90 add_timer(&dev->watchdog_timer);
91}
92
93static void s5p_mfc_watchdog_worker(struct work_struct *work)
94{
95 struct s5p_mfc_dev *dev;
96 struct s5p_mfc_ctx *ctx;
97 unsigned long flags;
98 int mutex_locked;
99 int i, ret;
100
101 dev = container_of(work, struct s5p_mfc_dev, watchdog_work);
102
103 mfc_err("Driver timeout error handling\n");
104 /* Lock the mutex that protects open and release.
105 * This is necessary as they may load and unload firmware. */
106 mutex_locked = mutex_trylock(&dev->mfc_mutex);
107 if (!mutex_locked)
108 mfc_err("Error: some instance may be closing/opening\n");
109 spin_lock_irqsave(&dev->irqlock, flags);
110
111 s5p_mfc_clock_off();
112
113 for (i = 0; i < MFC_NUM_CONTEXTS; i++) {
114 ctx = dev->ctx[i];
115 if (!ctx)
116 continue;
117 ctx->state = MFCINST_ERROR;
118 s5p_mfc_cleanup_queue(&ctx->dst_queue, &ctx->vq_dst);
119 s5p_mfc_cleanup_queue(&ctx->src_queue, &ctx->vq_src);
120 clear_work_bit(ctx);
121 wake_up_ctx(ctx, S5P_FIMV_R2H_CMD_ERR_RET, 0);
122 }
123 clear_bit(0, &dev->hw_lock);
124 spin_unlock_irqrestore(&dev->irqlock, flags);
125 /* Double check if there is at least one instance running.
126 * If no instance is in memory than no firmware should be present */
127 if (dev->num_inst > 0) {
128 ret = s5p_mfc_reload_firmware(dev);
129 if (ret) {
130 mfc_err("Failed to reload FW\n");
131 goto unlock;
132 }
133 s5p_mfc_clock_on();
134 ret = s5p_mfc_init_hw(dev);
135 if (ret)
136 mfc_err("Failed to reinit FW\n");
137 }
138unlock:
139 if (mutex_locked)
140 mutex_unlock(&dev->mfc_mutex);
141}
142
143static enum s5p_mfc_node_type s5p_mfc_get_node_type(struct file *file)
144{
145 struct video_device *vdev = video_devdata(file);
146
147 if (!vdev) {
148 mfc_err("failed to get video_device");
149 return MFCNODE_INVALID;
150 }
151 if (vdev->index == 0)
152 return MFCNODE_DECODER;
153 else if (vdev->index == 1)
154 return MFCNODE_ENCODER;
155 return MFCNODE_INVALID;
156}
157
158static void s5p_mfc_clear_int_flags(struct s5p_mfc_dev *dev)
159{
160 mfc_write(dev, 0, S5P_FIMV_RISC_HOST_INT);
161 mfc_write(dev, 0, S5P_FIMV_RISC2HOST_CMD);
162 mfc_write(dev, 0xffff, S5P_FIMV_SI_RTN_CHID);
163}
164
165static void s5p_mfc_handle_frame_all_extracted(struct s5p_mfc_ctx *ctx)
166{
167 struct s5p_mfc_buf *dst_buf;
168
169 ctx->state = MFCINST_FINISHED;
170 ctx->sequence++;
171 while (!list_empty(&ctx->dst_queue)) {
172 dst_buf = list_entry(ctx->dst_queue.next,
173 struct s5p_mfc_buf, list);
174 mfc_debug(2, "Cleaning up buffer: %d\n",
175 dst_buf->b->v4l2_buf.index);
176 vb2_set_plane_payload(dst_buf->b, 0, 0);
177 vb2_set_plane_payload(dst_buf->b, 1, 0);
178 list_del(&dst_buf->list);
179 ctx->dst_queue_cnt--;
180 dst_buf->b->v4l2_buf.sequence = (ctx->sequence++);
181
182 if (s5p_mfc_read_shm(ctx, PIC_TIME_TOP) ==
183 s5p_mfc_read_shm(ctx, PIC_TIME_BOT))
184 dst_buf->b->v4l2_buf.field = V4L2_FIELD_NONE;
185 else
186 dst_buf->b->v4l2_buf.field = V4L2_FIELD_INTERLACED;
187
188 ctx->dec_dst_flag &= ~(1 << dst_buf->b->v4l2_buf.index);
189 vb2_buffer_done(dst_buf->b, VB2_BUF_STATE_DONE);
190 }
191}
192
193static void s5p_mfc_handle_frame_copy_time(struct s5p_mfc_ctx *ctx)
194{
195 struct s5p_mfc_dev *dev = ctx->dev;
196 struct s5p_mfc_buf *dst_buf, *src_buf;
197 size_t dec_y_addr = s5p_mfc_get_dec_y_adr();
198 unsigned int frame_type = s5p_mfc_get_frame_type();
199
200 /* Copy timestamp / timecode from decoded src to dst and set
201 appropraite flags */
202 src_buf = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
203 list_for_each_entry(dst_buf, &ctx->dst_queue, list) {
204 if (vb2_dma_contig_plane_dma_addr(dst_buf->b, 0) == dec_y_addr) {
205 memcpy(&dst_buf->b->v4l2_buf.timecode,
206 &src_buf->b->v4l2_buf.timecode,
207 sizeof(struct v4l2_timecode));
208 memcpy(&dst_buf->b->v4l2_buf.timestamp,
209 &src_buf->b->v4l2_buf.timestamp,
210 sizeof(struct timeval));
211 switch (frame_type) {
212 case S5P_FIMV_DECODE_FRAME_I_FRAME:
213 dst_buf->b->v4l2_buf.flags |=
214 V4L2_BUF_FLAG_KEYFRAME;
215 break;
216 case S5P_FIMV_DECODE_FRAME_P_FRAME:
217 dst_buf->b->v4l2_buf.flags |=
218 V4L2_BUF_FLAG_PFRAME;
219 break;
220 case S5P_FIMV_DECODE_FRAME_B_FRAME:
221 dst_buf->b->v4l2_buf.flags |=
222 V4L2_BUF_FLAG_BFRAME;
223 break;
224 }
225 break;
226 }
227 }
228}
229
230static void s5p_mfc_handle_frame_new(struct s5p_mfc_ctx *ctx, unsigned int err)
231{
232 struct s5p_mfc_dev *dev = ctx->dev;
233 struct s5p_mfc_buf *dst_buf;
234 size_t dspl_y_addr = s5p_mfc_get_dspl_y_adr();
235 unsigned int frame_type = s5p_mfc_get_frame_type();
236 unsigned int index;
237
238 /* If frame is same as previous then skip and do not dequeue */
239 if (frame_type == S5P_FIMV_DECODE_FRAME_SKIPPED) {
240 if (!ctx->after_packed_pb)
241 ctx->sequence++;
242 ctx->after_packed_pb = 0;
243 return;
244 }
245 ctx->sequence++;
246 /* The MFC returns address of the buffer, now we have to
247 * check which videobuf does it correspond to */
248 list_for_each_entry(dst_buf, &ctx->dst_queue, list) {
249 /* Check if this is the buffer we're looking for */
250 if (vb2_dma_contig_plane_dma_addr(dst_buf->b, 0) == dspl_y_addr) {
251 list_del(&dst_buf->list);
252 ctx->dst_queue_cnt--;
253 dst_buf->b->v4l2_buf.sequence = ctx->sequence;
254 if (s5p_mfc_read_shm(ctx, PIC_TIME_TOP) ==
255 s5p_mfc_read_shm(ctx, PIC_TIME_BOT))
256 dst_buf->b->v4l2_buf.field = V4L2_FIELD_NONE;
257 else
258 dst_buf->b->v4l2_buf.field =
259 V4L2_FIELD_INTERLACED;
260 vb2_set_plane_payload(dst_buf->b, 0, ctx->luma_size);
261 vb2_set_plane_payload(dst_buf->b, 1, ctx->chroma_size);
262 clear_bit(dst_buf->b->v4l2_buf.index,
263 &ctx->dec_dst_flag);
264
265 vb2_buffer_done(dst_buf->b,
266 err ? VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
267
268 index = dst_buf->b->v4l2_buf.index;
269 break;
270 }
271 }
272}
273
274/* Handle frame decoding interrupt */
275static void s5p_mfc_handle_frame(struct s5p_mfc_ctx *ctx,
276 unsigned int reason, unsigned int err)
277{
278 struct s5p_mfc_dev *dev = ctx->dev;
279 unsigned int dst_frame_status;
280 struct s5p_mfc_buf *src_buf;
281 unsigned long flags;
282 unsigned int res_change;
283
284 unsigned int index;
285
286 dst_frame_status = s5p_mfc_get_dspl_status()
287 & S5P_FIMV_DEC_STATUS_DECODING_STATUS_MASK;
288 res_change = s5p_mfc_get_dspl_status()
289 & S5P_FIMV_DEC_STATUS_RESOLUTION_MASK;
290 mfc_debug(2, "Frame Status: %x\n", dst_frame_status);
291 if (ctx->state == MFCINST_RES_CHANGE_INIT)
292 ctx->state = MFCINST_RES_CHANGE_FLUSH;
293 if (res_change) {
294 ctx->state = MFCINST_RES_CHANGE_INIT;
295 s5p_mfc_clear_int_flags(dev);
296 wake_up_ctx(ctx, reason, err);
297 if (test_and_clear_bit(0, &dev->hw_lock) == 0)
298 BUG();
299 s5p_mfc_clock_off();
300 s5p_mfc_try_run(dev);
301 return;
302 }
303 if (ctx->dpb_flush_flag)
304 ctx->dpb_flush_flag = 0;
305
306 spin_lock_irqsave(&dev->irqlock, flags);
307 /* All frames remaining in the buffer have been extracted */
308 if (dst_frame_status == S5P_FIMV_DEC_STATUS_DECODING_EMPTY) {
309 if (ctx->state == MFCINST_RES_CHANGE_FLUSH) {
310 s5p_mfc_handle_frame_all_extracted(ctx);
311 ctx->state = MFCINST_RES_CHANGE_END;
312 goto leave_handle_frame;
313 } else {
314 s5p_mfc_handle_frame_all_extracted(ctx);
315 }
316 }
317
318 if (dst_frame_status == S5P_FIMV_DEC_STATUS_DECODING_DISPLAY ||
319 dst_frame_status == S5P_FIMV_DEC_STATUS_DECODING_ONLY)
320 s5p_mfc_handle_frame_copy_time(ctx);
321
322 /* A frame has been decoded and is in the buffer */
323 if (dst_frame_status == S5P_FIMV_DEC_STATUS_DISPLAY_ONLY ||
324 dst_frame_status == S5P_FIMV_DEC_STATUS_DECODING_DISPLAY) {
325 s5p_mfc_handle_frame_new(ctx, err);
326 } else {
327 mfc_debug(2, "No frame decode\n");
328 }
329 /* Mark source buffer as complete */
330 if (dst_frame_status != S5P_FIMV_DEC_STATUS_DISPLAY_ONLY
331 && !list_empty(&ctx->src_queue)) {
332 src_buf = list_entry(ctx->src_queue.next, struct s5p_mfc_buf,
333 list);
334 ctx->consumed_stream += s5p_mfc_get_consumed_stream();
335 if (ctx->codec_mode != S5P_FIMV_CODEC_H264_DEC &&
336 s5p_mfc_get_frame_type() == S5P_FIMV_DECODE_FRAME_P_FRAME
337 && ctx->consumed_stream + STUFF_BYTE <
338 src_buf->b->v4l2_planes[0].bytesused) {
339 /* Run MFC again on the same buffer */
340 mfc_debug(2, "Running again the same buffer\n");
341 ctx->after_packed_pb = 1;
342 } else {
343 index = src_buf->b->v4l2_buf.index;
344 mfc_debug(2, "MFC needs next buffer\n");
345 ctx->consumed_stream = 0;
346 list_del(&src_buf->list);
347 ctx->src_queue_cnt--;
348 if (s5p_mfc_err_dec(err) > 0)
349 vb2_buffer_done(src_buf->b, VB2_BUF_STATE_ERROR);
350 else
351 vb2_buffer_done(src_buf->b, VB2_BUF_STATE_DONE);
352 }
353 }
354leave_handle_frame:
355 spin_unlock_irqrestore(&dev->irqlock, flags);
356 if ((ctx->src_queue_cnt == 0 && ctx->state != MFCINST_FINISHING)
357 || ctx->dst_queue_cnt < ctx->dpb_count)
358 clear_work_bit(ctx);
359 s5p_mfc_clear_int_flags(dev);
360 wake_up_ctx(ctx, reason, err);
361 if (test_and_clear_bit(0, &dev->hw_lock) == 0)
362 BUG();
363 s5p_mfc_clock_off();
364 s5p_mfc_try_run(dev);
365}
366
367/* Error handling for interrupt */
368static void s5p_mfc_handle_error(struct s5p_mfc_ctx *ctx,
369 unsigned int reason, unsigned int err)
370{
371 struct s5p_mfc_dev *dev;
372 unsigned long flags;
373
374 /* If no context is available then all necessary
375 * processing has been done. */
376 if (ctx == NULL)
377 return;
378
379 dev = ctx->dev;
380 mfc_err("Interrupt Error: %08x\n", err);
381 s5p_mfc_clear_int_flags(dev);
382 wake_up_dev(dev, reason, err);
383
384 /* Error recovery is dependent on the state of context */
385 switch (ctx->state) {
386 case MFCINST_INIT:
387 /* This error had to happen while acquireing instance */
388 case MFCINST_GOT_INST:
389 /* This error had to happen while parsing the header */
390 case MFCINST_HEAD_PARSED:
391 /* This error had to happen while setting dst buffers */
392 case MFCINST_RETURN_INST:
393 /* This error had to happen while releasing instance */
394 clear_work_bit(ctx);
395 wake_up_ctx(ctx, reason, err);
396 if (test_and_clear_bit(0, &dev->hw_lock) == 0)
397 BUG();
398 s5p_mfc_clock_off();
399 ctx->state = MFCINST_ERROR;
400 break;
401 case MFCINST_FINISHING:
402 case MFCINST_FINISHED:
403 case MFCINST_RUNNING:
404 /* It is higly probable that an error occured
405 * while decoding a frame */
406 clear_work_bit(ctx);
407 ctx->state = MFCINST_ERROR;
408 /* Mark all dst buffers as having an error */
409 spin_lock_irqsave(&dev->irqlock, flags);
410 s5p_mfc_cleanup_queue(&ctx->dst_queue, &ctx->vq_dst);
411 /* Mark all src buffers as having an error */
412 s5p_mfc_cleanup_queue(&ctx->src_queue, &ctx->vq_src);
413 spin_unlock_irqrestore(&dev->irqlock, flags);
414 if (test_and_clear_bit(0, &dev->hw_lock) == 0)
415 BUG();
416 s5p_mfc_clock_off();
417 break;
418 default:
419 mfc_err("Encountered an error interrupt which had not been handled\n");
420 break;
421 }
422 return;
423}
424
425/* Header parsing interrupt handling */
426static void s5p_mfc_handle_seq_done(struct s5p_mfc_ctx *ctx,
427 unsigned int reason, unsigned int err)
428{
429 struct s5p_mfc_dev *dev;
430 unsigned int guard_width, guard_height;
431
432 if (ctx == NULL)
433 return;
434 dev = ctx->dev;
435 if (ctx->c_ops->post_seq_start) {
436 if (ctx->c_ops->post_seq_start(ctx))
437 mfc_err("post_seq_start() failed\n");
438 } else {
439 ctx->img_width = s5p_mfc_get_img_width();
440 ctx->img_height = s5p_mfc_get_img_height();
441
442 ctx->buf_width = ALIGN(ctx->img_width,
443 S5P_FIMV_NV12MT_HALIGN);
444 ctx->buf_height = ALIGN(ctx->img_height,
445 S5P_FIMV_NV12MT_VALIGN);
446 mfc_debug(2, "SEQ Done: Movie dimensions %dx%d, "
447 "buffer dimensions: %dx%d\n", ctx->img_width,
448 ctx->img_height, ctx->buf_width,
449 ctx->buf_height);
450 if (ctx->codec_mode == S5P_FIMV_CODEC_H264_DEC) {
451 ctx->luma_size = ALIGN(ctx->buf_width *
452 ctx->buf_height, S5P_FIMV_DEC_BUF_ALIGN);
453 ctx->chroma_size = ALIGN(ctx->buf_width *
454 ALIGN((ctx->img_height >> 1),
455 S5P_FIMV_NV12MT_VALIGN),
456 S5P_FIMV_DEC_BUF_ALIGN);
457 ctx->mv_size = ALIGN(ctx->buf_width *
458 ALIGN((ctx->buf_height >> 2),
459 S5P_FIMV_NV12MT_VALIGN),
460 S5P_FIMV_DEC_BUF_ALIGN);
461 } else {
462 guard_width = ALIGN(ctx->img_width + 24,
463 S5P_FIMV_NV12MT_HALIGN);
464 guard_height = ALIGN(ctx->img_height + 16,
465 S5P_FIMV_NV12MT_VALIGN);
466 ctx->luma_size = ALIGN(guard_width *
467 guard_height, S5P_FIMV_DEC_BUF_ALIGN);
468 guard_width = ALIGN(ctx->img_width + 16,
469 S5P_FIMV_NV12MT_HALIGN);
470 guard_height = ALIGN((ctx->img_height >> 1) + 4,
471 S5P_FIMV_NV12MT_VALIGN);
472 ctx->chroma_size = ALIGN(guard_width *
473 guard_height, S5P_FIMV_DEC_BUF_ALIGN);
474 ctx->mv_size = 0;
475 }
476 ctx->dpb_count = s5p_mfc_get_dpb_count();
477 if (ctx->img_width == 0 || ctx->img_height == 0)
478 ctx->state = MFCINST_ERROR;
479 else
480 ctx->state = MFCINST_HEAD_PARSED;
481 }
482 s5p_mfc_clear_int_flags(dev);
483 clear_work_bit(ctx);
484 if (test_and_clear_bit(0, &dev->hw_lock) == 0)
485 BUG();
486 s5p_mfc_clock_off();
487 s5p_mfc_try_run(dev);
488 wake_up_ctx(ctx, reason, err);
489}
490
491/* Header parsing interrupt handling */
492static void s5p_mfc_handle_init_buffers(struct s5p_mfc_ctx *ctx,
493 unsigned int reason, unsigned int err)
494{
495 struct s5p_mfc_buf *src_buf;
496 struct s5p_mfc_dev *dev;
497 unsigned long flags;
498
499 if (ctx == NULL)
500 return;
501 dev = ctx->dev;
502 s5p_mfc_clear_int_flags(dev);
503 ctx->int_type = reason;
504 ctx->int_err = err;
505 ctx->int_cond = 1;
506 spin_lock(&dev->condlock);
507 clear_bit(ctx->num, &dev->ctx_work_bits);
508 spin_unlock(&dev->condlock);
509 if (err == 0) {
510 ctx->state = MFCINST_RUNNING;
511 if (!ctx->dpb_flush_flag) {
512 spin_lock_irqsave(&dev->irqlock, flags);
513 if (!list_empty(&ctx->src_queue)) {
514 src_buf = list_entry(ctx->src_queue.next,
515 struct s5p_mfc_buf, list);
516 list_del(&src_buf->list);
517 ctx->src_queue_cnt--;
518 vb2_buffer_done(src_buf->b,
519 VB2_BUF_STATE_DONE);
520 }
521 spin_unlock_irqrestore(&dev->irqlock, flags);
522 } else {
523 ctx->dpb_flush_flag = 0;
524 }
525 if (test_and_clear_bit(0, &dev->hw_lock) == 0)
526 BUG();
527
528 s5p_mfc_clock_off();
529
530 wake_up(&ctx->queue);
531 s5p_mfc_try_run(dev);
532 } else {
533 if (test_and_clear_bit(0, &dev->hw_lock) == 0)
534 BUG();
535
536 s5p_mfc_clock_off();
537
538 wake_up(&ctx->queue);
539 }
540}
541
542/* Interrupt processing */
543static irqreturn_t s5p_mfc_irq(int irq, void *priv)
544{
545 struct s5p_mfc_dev *dev = priv;
546 struct s5p_mfc_ctx *ctx;
547 unsigned int reason;
548 unsigned int err;
549
550 mfc_debug_enter();
551 /* Reset the timeout watchdog */
552 atomic_set(&dev->watchdog_cnt, 0);
553 ctx = dev->ctx[dev->curr_ctx];
554 /* Get the reason of interrupt and the error code */
555 reason = s5p_mfc_get_int_reason();
556 err = s5p_mfc_get_int_err();
557 mfc_debug(1, "Int reason: %d (err: %08x)\n", reason, err);
558 switch (reason) {
559 case S5P_FIMV_R2H_CMD_ERR_RET:
560 /* An error has occured */
561 if (ctx->state == MFCINST_RUNNING &&
562 s5p_mfc_err_dec(err) >= S5P_FIMV_ERR_WARNINGS_START)
563 s5p_mfc_handle_frame(ctx, reason, err);
564 else
565 s5p_mfc_handle_error(ctx, reason, err);
566 clear_bit(0, &dev->enter_suspend);
567 break;
568
569 case S5P_FIMV_R2H_CMD_SLICE_DONE_RET:
570 case S5P_FIMV_R2H_CMD_FRAME_DONE_RET:
571 if (ctx->c_ops->post_frame_start) {
572 if (ctx->c_ops->post_frame_start(ctx))
573 mfc_err("post_frame_start() failed\n");
574 s5p_mfc_clear_int_flags(dev);
575 wake_up_ctx(ctx, reason, err);
576 if (test_and_clear_bit(0, &dev->hw_lock) == 0)
577 BUG();
578 s5p_mfc_clock_off();
579 s5p_mfc_try_run(dev);
580 } else {
581 s5p_mfc_handle_frame(ctx, reason, err);
582 }
583 break;
584
585 case S5P_FIMV_R2H_CMD_SEQ_DONE_RET:
586 s5p_mfc_handle_seq_done(ctx, reason, err);
587 break;
588
589 case S5P_FIMV_R2H_CMD_OPEN_INSTANCE_RET:
590 ctx->inst_no = s5p_mfc_get_inst_no();
591 ctx->state = MFCINST_GOT_INST;
592 clear_work_bit(ctx);
593 wake_up(&ctx->queue);
594 goto irq_cleanup_hw;
595
596 case S5P_FIMV_R2H_CMD_CLOSE_INSTANCE_RET:
597 clear_work_bit(ctx);
598 ctx->state = MFCINST_FREE;
599 wake_up(&ctx->queue);
600 goto irq_cleanup_hw;
601
602 case S5P_FIMV_R2H_CMD_SYS_INIT_RET:
603 case S5P_FIMV_R2H_CMD_FW_STATUS_RET:
604 case S5P_FIMV_R2H_CMD_SLEEP_RET:
605 case S5P_FIMV_R2H_CMD_WAKEUP_RET:
606 if (ctx)
607 clear_work_bit(ctx);
608 s5p_mfc_clear_int_flags(dev);
609 wake_up_dev(dev, reason, err);
610 clear_bit(0, &dev->hw_lock);
611 clear_bit(0, &dev->enter_suspend);
612 break;
613
614 case S5P_FIMV_R2H_CMD_INIT_BUFFERS_RET:
615 s5p_mfc_handle_init_buffers(ctx, reason, err);
616 break;
617 default:
618 mfc_debug(2, "Unknown int reason\n");
619 s5p_mfc_clear_int_flags(dev);
620 }
621 mfc_debug_leave();
622 return IRQ_HANDLED;
623irq_cleanup_hw:
624 s5p_mfc_clear_int_flags(dev);
625 ctx->int_type = reason;
626 ctx->int_err = err;
627 ctx->int_cond = 1;
628 if (test_and_clear_bit(0, &dev->hw_lock) == 0)
629 mfc_err("Failed to unlock hw\n");
630
631 s5p_mfc_clock_off();
632
633 s5p_mfc_try_run(dev);
634 mfc_debug(2, "Exit via irq_cleanup_hw\n");
635 return IRQ_HANDLED;
636}
637
638/* Open an MFC node */
639static int s5p_mfc_open(struct file *file)
640{
641 struct s5p_mfc_dev *dev = video_drvdata(file);
642 struct s5p_mfc_ctx *ctx = NULL;
643 struct vb2_queue *q;
644 unsigned long flags;
645 int ret = 0;
646
647 mfc_debug_enter();
648 if (mutex_lock_interruptible(&dev->mfc_mutex))
649 return -ERESTARTSYS;
650 dev->num_inst++; /* It is guarded by mfc_mutex in vfd */
651 /* Allocate memory for context */
652 ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
653 if (!ctx) {
654 mfc_err("Not enough memory\n");
655 ret = -ENOMEM;
656 goto err_alloc;
657 }
658 v4l2_fh_init(&ctx->fh, video_devdata(file));
659 file->private_data = &ctx->fh;
660 v4l2_fh_add(&ctx->fh);
661 ctx->dev = dev;
662 INIT_LIST_HEAD(&ctx->src_queue);
663 INIT_LIST_HEAD(&ctx->dst_queue);
664 ctx->src_queue_cnt = 0;
665 ctx->dst_queue_cnt = 0;
666 /* Get context number */
667 ctx->num = 0;
668 while (dev->ctx[ctx->num]) {
669 ctx->num++;
670 if (ctx->num >= MFC_NUM_CONTEXTS) {
671 mfc_err("Too many open contexts\n");
672 ret = -EBUSY;
673 goto err_no_ctx;
674 }
675 }
676 /* Mark context as idle */
677 spin_lock_irqsave(&dev->condlock, flags);
678 clear_bit(ctx->num, &dev->ctx_work_bits);
679 spin_unlock_irqrestore(&dev->condlock, flags);
680 dev->ctx[ctx->num] = ctx;
681 if (s5p_mfc_get_node_type(file) == MFCNODE_DECODER) {
682 ctx->type = MFCINST_DECODER;
683 ctx->c_ops = get_dec_codec_ops();
684 /* Setup ctrl handler */
685 ret = s5p_mfc_dec_ctrls_setup(ctx);
686 if (ret) {
687 mfc_err("Failed to setup mfc controls\n");
688 goto err_ctrls_setup;
689 }
690 } else if (s5p_mfc_get_node_type(file) == MFCNODE_ENCODER) {
691 ctx->type = MFCINST_ENCODER;
692 ctx->c_ops = get_enc_codec_ops();
693 /* only for encoder */
694 INIT_LIST_HEAD(&ctx->ref_queue);
695 ctx->ref_queue_cnt = 0;
696 /* Setup ctrl handler */
697 ret = s5p_mfc_enc_ctrls_setup(ctx);
698 if (ret) {
699 mfc_err("Failed to setup mfc controls\n");
700 goto err_ctrls_setup;
701 }
702 } else {
703 ret = -ENOENT;
704 goto err_bad_node;
705 }
706 ctx->fh.ctrl_handler = &ctx->ctrl_handler;
707 ctx->inst_no = -1;
708 /* Load firmware if this is the first instance */
709 if (dev->num_inst == 1) {
710 dev->watchdog_timer.expires = jiffies +
711 msecs_to_jiffies(MFC_WATCHDOG_INTERVAL);
712 add_timer(&dev->watchdog_timer);
713 ret = s5p_mfc_power_on();
714 if (ret < 0) {
715 mfc_err("power on failed\n");
716 goto err_pwr_enable;
717 }
718 s5p_mfc_clock_on();
719 ret = s5p_mfc_alloc_and_load_firmware(dev);
720 if (ret)
721 goto err_alloc_fw;
722 /* Init the FW */
723 ret = s5p_mfc_init_hw(dev);
724 if (ret)
725 goto err_init_hw;
726 s5p_mfc_clock_off();
727 }
728 /* Init videobuf2 queue for CAPTURE */
729 q = &ctx->vq_dst;
730 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
731 q->drv_priv = &ctx->fh;
732 if (s5p_mfc_get_node_type(file) == MFCNODE_DECODER) {
733 q->io_modes = VB2_MMAP;
734 q->ops = get_dec_queue_ops();
735 } else if (s5p_mfc_get_node_type(file) == MFCNODE_ENCODER) {
736 q->io_modes = VB2_MMAP | VB2_USERPTR;
737 q->ops = get_enc_queue_ops();
738 } else {
739 ret = -ENOENT;
740 goto err_queue_init;
741 }
742 q->mem_ops = (struct vb2_mem_ops *)&vb2_dma_contig_memops;
743 ret = vb2_queue_init(q);
744 if (ret) {
745 mfc_err("Failed to initialize videobuf2 queue(capture)\n");
746 goto err_queue_init;
747 }
748 /* Init videobuf2 queue for OUTPUT */
749 q = &ctx->vq_src;
750 q->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
751 q->io_modes = VB2_MMAP;
752 q->drv_priv = &ctx->fh;
753 if (s5p_mfc_get_node_type(file) == MFCNODE_DECODER) {
754 q->io_modes = VB2_MMAP;
755 q->ops = get_dec_queue_ops();
756 } else if (s5p_mfc_get_node_type(file) == MFCNODE_ENCODER) {
757 q->io_modes = VB2_MMAP | VB2_USERPTR;
758 q->ops = get_enc_queue_ops();
759 } else {
760 ret = -ENOENT;
761 goto err_queue_init;
762 }
763 q->mem_ops = (struct vb2_mem_ops *)&vb2_dma_contig_memops;
764 ret = vb2_queue_init(q);
765 if (ret) {
766 mfc_err("Failed to initialize videobuf2 queue(output)\n");
767 goto err_queue_init;
768 }
769 init_waitqueue_head(&ctx->queue);
770 mutex_unlock(&dev->mfc_mutex);
771 mfc_debug_leave();
772 return ret;
773 /* Deinit when failure occured */
774err_queue_init:
775err_init_hw:
776 s5p_mfc_release_firmware(dev);
777err_alloc_fw:
778 dev->ctx[ctx->num] = NULL;
779 del_timer_sync(&dev->watchdog_timer);
780 s5p_mfc_clock_off();
781err_pwr_enable:
782 if (dev->num_inst == 1) {
783 if (s5p_mfc_power_off() < 0)
784 mfc_err("power off failed\n");
785 s5p_mfc_release_firmware(dev);
786 }
787err_ctrls_setup:
788 s5p_mfc_dec_ctrls_delete(ctx);
789err_bad_node:
790err_no_ctx:
791 v4l2_fh_del(&ctx->fh);
792 v4l2_fh_exit(&ctx->fh);
793 kfree(ctx);
794err_alloc:
795 dev->num_inst--;
796 mutex_unlock(&dev->mfc_mutex);
797 mfc_debug_leave();
798 return ret;
799}
800
801/* Release MFC context */
802static int s5p_mfc_release(struct file *file)
803{
804 struct s5p_mfc_ctx *ctx = fh_to_ctx(file->private_data);
805 struct s5p_mfc_dev *dev = ctx->dev;
806 unsigned long flags;
807
808 mfc_debug_enter();
809 mutex_lock(&dev->mfc_mutex);
810 s5p_mfc_clock_on();
811 vb2_queue_release(&ctx->vq_src);
812 vb2_queue_release(&ctx->vq_dst);
813 /* Mark context as idle */
814 spin_lock_irqsave(&dev->condlock, flags);
815 clear_bit(ctx->num, &dev->ctx_work_bits);
816 spin_unlock_irqrestore(&dev->condlock, flags);
817 /* If instance was initialised then
818 * return instance and free reosurces */
819 if (ctx->inst_no != MFC_NO_INSTANCE_SET) {
820 mfc_debug(2, "Has to free instance\n");
821 ctx->state = MFCINST_RETURN_INST;
822 spin_lock_irqsave(&dev->condlock, flags);
823 set_bit(ctx->num, &dev->ctx_work_bits);
824 spin_unlock_irqrestore(&dev->condlock, flags);
825 s5p_mfc_clean_ctx_int_flags(ctx);
826 s5p_mfc_try_run(dev);
827 /* Wait until instance is returned or timeout occured */
828 if (s5p_mfc_wait_for_done_ctx
829 (ctx, S5P_FIMV_R2H_CMD_CLOSE_INSTANCE_RET, 0)) {
830 s5p_mfc_clock_off();
831 mfc_err("Err returning instance\n");
832 }
833 mfc_debug(2, "After free instance\n");
834 /* Free resources */
835 s5p_mfc_release_codec_buffers(ctx);
836 s5p_mfc_release_instance_buffer(ctx);
837 if (ctx->type == MFCINST_DECODER)
838 s5p_mfc_release_dec_desc_buffer(ctx);
839
840 ctx->inst_no = MFC_NO_INSTANCE_SET;
841 }
842 /* hardware locking scheme */
843 if (dev->curr_ctx == ctx->num)
844 clear_bit(0, &dev->hw_lock);
845 dev->num_inst--;
846 if (dev->num_inst == 0) {
847 mfc_debug(2, "Last instance - release firmware\n");
848 /* reset <-> F/W release */
849 s5p_mfc_reset(dev);
850 s5p_mfc_release_firmware(dev);
851 del_timer_sync(&dev->watchdog_timer);
852 if (s5p_mfc_power_off() < 0)
853 mfc_err("Power off failed\n");
854 }
855 mfc_debug(2, "Shutting down clock\n");
856 s5p_mfc_clock_off();
857 dev->ctx[ctx->num] = NULL;
858 s5p_mfc_dec_ctrls_delete(ctx);
859 v4l2_fh_del(&ctx->fh);
860 v4l2_fh_exit(&ctx->fh);
861 kfree(ctx);
862 mfc_debug_leave();
863 mutex_unlock(&dev->mfc_mutex);
864 return 0;
865}
866
867/* Poll */
868static unsigned int s5p_mfc_poll(struct file *file,
869 struct poll_table_struct *wait)
870{
871 struct s5p_mfc_ctx *ctx = fh_to_ctx(file->private_data);
872 struct s5p_mfc_dev *dev = ctx->dev;
873 struct vb2_queue *src_q, *dst_q;
874 struct vb2_buffer *src_vb = NULL, *dst_vb = NULL;
875 unsigned int rc = 0;
876 unsigned long flags;
877
878 mutex_lock(&dev->mfc_mutex);
879 src_q = &ctx->vq_src;
880 dst_q = &ctx->vq_dst;
881 /*
882 * There has to be at least one buffer queued on each queued_list, which
883 * means either in driver already or waiting for driver to claim it
884 * and start processing.
885 */
886 if ((!src_q->streaming || list_empty(&src_q->queued_list))
887 && (!dst_q->streaming || list_empty(&dst_q->queued_list))) {
888 rc = POLLERR;
889 goto end;
890 }
891 mutex_unlock(&dev->mfc_mutex);
892 poll_wait(file, &src_q->done_wq, wait);
893 poll_wait(file, &dst_q->done_wq, wait);
894 mutex_lock(&dev->mfc_mutex);
895 spin_lock_irqsave(&src_q->done_lock, flags);
896 if (!list_empty(&src_q->done_list))
897 src_vb = list_first_entry(&src_q->done_list, struct vb2_buffer,
898 done_entry);
899 if (src_vb && (src_vb->state == VB2_BUF_STATE_DONE
900 || src_vb->state == VB2_BUF_STATE_ERROR))
901 rc |= POLLOUT | POLLWRNORM;
902 spin_unlock_irqrestore(&src_q->done_lock, flags);
903 spin_lock_irqsave(&dst_q->done_lock, flags);
904 if (!list_empty(&dst_q->done_list))
905 dst_vb = list_first_entry(&dst_q->done_list, struct vb2_buffer,
906 done_entry);
907 if (dst_vb && (dst_vb->state == VB2_BUF_STATE_DONE
908 || dst_vb->state == VB2_BUF_STATE_ERROR))
909 rc |= POLLIN | POLLRDNORM;
910 spin_unlock_irqrestore(&dst_q->done_lock, flags);
911end:
912 mutex_unlock(&dev->mfc_mutex);
913 return rc;
914}
915
916/* Mmap */
917static int s5p_mfc_mmap(struct file *file, struct vm_area_struct *vma)
918{
919 struct s5p_mfc_ctx *ctx = fh_to_ctx(file->private_data);
920 struct s5p_mfc_dev *dev = ctx->dev;
921 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
922 int ret;
923
924 if (mutex_lock_interruptible(&dev->mfc_mutex))
925 return -ERESTARTSYS;
926 if (offset < DST_QUEUE_OFF_BASE) {
927 mfc_debug(2, "mmaping source\n");
928 ret = vb2_mmap(&ctx->vq_src, vma);
929 } else { /* capture */
930 mfc_debug(2, "mmaping destination\n");
931 vma->vm_pgoff -= (DST_QUEUE_OFF_BASE >> PAGE_SHIFT);
932 ret = vb2_mmap(&ctx->vq_dst, vma);
933 }
934 mutex_unlock(&dev->mfc_mutex);
935 return ret;
936}
937
938/* v4l2 ops */
939static const struct v4l2_file_operations s5p_mfc_fops = {
940 .owner = THIS_MODULE,
941 .open = s5p_mfc_open,
942 .release = s5p_mfc_release,
943 .poll = s5p_mfc_poll,
944 .unlocked_ioctl = video_ioctl2,
945 .mmap = s5p_mfc_mmap,
946};
947
948static int match_child(struct device *dev, void *data)
949{
950 if (!dev_name(dev))
951 return 0;
952 return !strcmp(dev_name(dev), (char *)data);
953}
954
955/* MFC probe function */
956static int s5p_mfc_probe(struct platform_device *pdev)
957{
958 struct s5p_mfc_dev *dev;
959 struct video_device *vfd;
960 struct resource *res;
961 int ret;
962
963 pr_debug("%s++\n", __func__);
964 dev = devm_kzalloc(&pdev->dev, sizeof *dev, GFP_KERNEL);
965 if (!dev) {
966 dev_err(&pdev->dev, "Not enough memory for MFC device\n");
967 return -ENOMEM;
968 }
969
970 spin_lock_init(&dev->irqlock);
971 spin_lock_init(&dev->condlock);
972 dev->plat_dev = pdev;
973 if (!dev->plat_dev) {
974 dev_err(&pdev->dev, "No platform data specified\n");
975 return -ENODEV;
976 }
977
978 ret = s5p_mfc_init_pm(dev);
979 if (ret < 0) {
980 dev_err(&pdev->dev, "failed to get mfc clock source\n");
981 return ret;
982 }
983
984 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
985
986 dev->regs_base = devm_request_and_ioremap(&pdev->dev, res);
987 if (dev->regs_base == NULL) {
988 dev_err(&pdev->dev, "Failed to obtain io memory\n");
989 return -ENOENT;
990 }
991
992 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
993 if (res == NULL) {
994 dev_err(&pdev->dev, "failed to get irq resource\n");
995 ret = -ENOENT;
996 goto err_res;
997 }
998 dev->irq = res->start;
999 ret = devm_request_irq(&pdev->dev, dev->irq, s5p_mfc_irq,
1000 IRQF_DISABLED, pdev->name, dev);
1001 if (ret) {
1002 dev_err(&pdev->dev, "Failed to install irq (%d)\n", ret);
1003 goto err_res;
1004 }
1005
1006 dev->mem_dev_l = device_find_child(&dev->plat_dev->dev, "s5p-mfc-l",
1007 match_child);
1008 if (!dev->mem_dev_l) {
1009 mfc_err("Mem child (L) device get failed\n");
1010 ret = -ENODEV;
1011 goto err_res;
1012 }
1013 dev->mem_dev_r = device_find_child(&dev->plat_dev->dev, "s5p-mfc-r",
1014 match_child);
1015 if (!dev->mem_dev_r) {
1016 mfc_err("Mem child (R) device get failed\n");
1017 ret = -ENODEV;
1018 goto err_res;
1019 }
1020
1021 dev->alloc_ctx[0] = vb2_dma_contig_init_ctx(dev->mem_dev_l);
1022 if (IS_ERR_OR_NULL(dev->alloc_ctx[0])) {
1023 ret = PTR_ERR(dev->alloc_ctx[0]);
1024 goto err_res;
1025 }
1026 dev->alloc_ctx[1] = vb2_dma_contig_init_ctx(dev->mem_dev_r);
1027 if (IS_ERR_OR_NULL(dev->alloc_ctx[1])) {
1028 ret = PTR_ERR(dev->alloc_ctx[1]);
1029 goto err_mem_init_ctx_1;
1030 }
1031
1032 mutex_init(&dev->mfc_mutex);
1033
1034 ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
1035 if (ret)
1036 goto err_v4l2_dev_reg;
1037 init_waitqueue_head(&dev->queue);
1038
1039 /* decoder */
1040 vfd = video_device_alloc();
1041 if (!vfd) {
1042 v4l2_err(&dev->v4l2_dev, "Failed to allocate video device\n");
1043 ret = -ENOMEM;
1044 goto err_dec_alloc;
1045 }
1046 vfd->fops = &s5p_mfc_fops,
1047 vfd->ioctl_ops = get_dec_v4l2_ioctl_ops();
1048 vfd->release = video_device_release,
1049 vfd->lock = &dev->mfc_mutex;
1050 vfd->v4l2_dev = &dev->v4l2_dev;
1051 snprintf(vfd->name, sizeof(vfd->name), "%s", S5P_MFC_DEC_NAME);
1052 dev->vfd_dec = vfd;
1053 ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
1054 if (ret) {
1055 v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");
1056 video_device_release(vfd);
1057 goto err_dec_reg;
1058 }
1059 v4l2_info(&dev->v4l2_dev,
1060 "decoder registered as /dev/video%d\n", vfd->num);
1061 video_set_drvdata(vfd, dev);
1062
1063 /* encoder */
1064 vfd = video_device_alloc();
1065 if (!vfd) {
1066 v4l2_err(&dev->v4l2_dev, "Failed to allocate video device\n");
1067 ret = -ENOMEM;
1068 goto err_enc_alloc;
1069 }
1070 vfd->fops = &s5p_mfc_fops,
1071 vfd->ioctl_ops = get_enc_v4l2_ioctl_ops();
1072 vfd->release = video_device_release,
1073 vfd->lock = &dev->mfc_mutex;
1074 vfd->v4l2_dev = &dev->v4l2_dev;
1075 snprintf(vfd->name, sizeof(vfd->name), "%s", S5P_MFC_ENC_NAME);
1076 dev->vfd_enc = vfd;
1077 ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
1078 if (ret) {
1079 v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");
1080 video_device_release(vfd);
1081 goto err_enc_reg;
1082 }
1083 v4l2_info(&dev->v4l2_dev,
1084 "encoder registered as /dev/video%d\n", vfd->num);
1085 video_set_drvdata(vfd, dev);
1086 platform_set_drvdata(pdev, dev);
1087
1088 dev->hw_lock = 0;
1089 dev->watchdog_workqueue = create_singlethread_workqueue(S5P_MFC_NAME);
1090 INIT_WORK(&dev->watchdog_work, s5p_mfc_watchdog_worker);
1091 atomic_set(&dev->watchdog_cnt, 0);
1092 init_timer(&dev->watchdog_timer);
1093 dev->watchdog_timer.data = (unsigned long)dev;
1094 dev->watchdog_timer.function = s5p_mfc_watchdog;
1095
1096 pr_debug("%s--\n", __func__);
1097 return 0;
1098
1099/* Deinit MFC if probe had failed */
1100err_enc_reg:
1101 video_device_release(dev->vfd_enc);
1102err_enc_alloc:
1103 video_unregister_device(dev->vfd_dec);
1104err_dec_reg:
1105 video_device_release(dev->vfd_dec);
1106err_dec_alloc:
1107 v4l2_device_unregister(&dev->v4l2_dev);
1108err_v4l2_dev_reg:
1109 vb2_dma_contig_cleanup_ctx(dev->alloc_ctx[1]);
1110err_mem_init_ctx_1:
1111 vb2_dma_contig_cleanup_ctx(dev->alloc_ctx[0]);
1112err_res:
1113 s5p_mfc_final_pm(dev);
1114
1115 pr_debug("%s-- with error\n", __func__);
1116 return ret;
1117
1118}
1119
1120/* Remove the driver */
1121static int __devexit s5p_mfc_remove(struct platform_device *pdev)
1122{
1123 struct s5p_mfc_dev *dev = platform_get_drvdata(pdev);
1124
1125 v4l2_info(&dev->v4l2_dev, "Removing %s\n", pdev->name);
1126
1127 del_timer_sync(&dev->watchdog_timer);
1128 flush_workqueue(dev->watchdog_workqueue);
1129 destroy_workqueue(dev->watchdog_workqueue);
1130
1131 video_unregister_device(dev->vfd_enc);
1132 video_unregister_device(dev->vfd_dec);
1133 v4l2_device_unregister(&dev->v4l2_dev);
1134 vb2_dma_contig_cleanup_ctx(dev->alloc_ctx[0]);
1135 vb2_dma_contig_cleanup_ctx(dev->alloc_ctx[1]);
1136
1137 s5p_mfc_final_pm(dev);
1138 return 0;
1139}
1140
1141#ifdef CONFIG_PM_SLEEP
1142
1143static int s5p_mfc_suspend(struct device *dev)
1144{
1145 struct platform_device *pdev = to_platform_device(dev);
1146 struct s5p_mfc_dev *m_dev = platform_get_drvdata(pdev);
1147 int ret;
1148
1149 if (m_dev->num_inst == 0)
1150 return 0;
1151 return s5p_mfc_sleep(m_dev);
1152 if (test_and_set_bit(0, &m_dev->enter_suspend) != 0) {
1153 mfc_err("Error: going to suspend for a second time\n");
1154 return -EIO;
1155 }
1156
1157 /* Check if we're processing then wait if it necessary. */
1158 while (test_and_set_bit(0, &m_dev->hw_lock) != 0) {
1159 /* Try and lock the HW */
1160 /* Wait on the interrupt waitqueue */
1161 ret = wait_event_interruptible_timeout(m_dev->queue,
1162 m_dev->int_cond || m_dev->ctx[m_dev->curr_ctx]->int_cond,
1163 msecs_to_jiffies(MFC_INT_TIMEOUT));
1164
1165 if (ret == 0) {
1166 mfc_err("Waiting for hardware to finish timed out\n");
1167 return -EIO;
1168 }
1169 }
1170 return 0;
1171}
1172
1173static int s5p_mfc_resume(struct device *dev)
1174{
1175 struct platform_device *pdev = to_platform_device(dev);
1176 struct s5p_mfc_dev *m_dev = platform_get_drvdata(pdev);
1177
1178 if (m_dev->num_inst == 0)
1179 return 0;
1180 return s5p_mfc_wakeup(m_dev);
1181}
1182#endif
1183
1184#ifdef CONFIG_PM_RUNTIME
1185static int s5p_mfc_runtime_suspend(struct device *dev)
1186{
1187 struct platform_device *pdev = to_platform_device(dev);
1188 struct s5p_mfc_dev *m_dev = platform_get_drvdata(pdev);
1189
1190 atomic_set(&m_dev->pm.power, 0);
1191 return 0;
1192}
1193
1194static int s5p_mfc_runtime_resume(struct device *dev)
1195{
1196 struct platform_device *pdev = to_platform_device(dev);
1197 struct s5p_mfc_dev *m_dev = platform_get_drvdata(pdev);
1198 int pre_power;
1199
1200 if (!m_dev->alloc_ctx)
1201 return 0;
1202 pre_power = atomic_read(&m_dev->pm.power);
1203 atomic_set(&m_dev->pm.power, 1);
1204 return 0;
1205}
1206#endif
1207
1208/* Power management */
1209static const struct dev_pm_ops s5p_mfc_pm_ops = {
1210 SET_SYSTEM_SLEEP_PM_OPS(s5p_mfc_suspend, s5p_mfc_resume)
1211 SET_RUNTIME_PM_OPS(s5p_mfc_runtime_suspend, s5p_mfc_runtime_resume,
1212 NULL)
1213};
1214
1215static struct platform_driver s5p_mfc_driver = {
1216 .probe = s5p_mfc_probe,
1217 .remove = __devexit_p(s5p_mfc_remove),
1218 .driver = {
1219 .name = S5P_MFC_NAME,
1220 .owner = THIS_MODULE,
1221 .pm = &s5p_mfc_pm_ops
1222 },
1223};
1224
1225module_platform_driver(s5p_mfc_driver);
1226
1227MODULE_LICENSE("GPL");
1228MODULE_AUTHOR("Kamil Debski <k.debski@samsung.com>");
1229MODULE_DESCRIPTION("Samsung S5P Multi Format Codec V4L2 driver");
1230
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_cmd.c b/drivers/media/video/s5p-mfc/s5p_mfc_cmd.c
deleted file mode 100644
index f0665ed1a529..000000000000
--- a/drivers/media/video/s5p-mfc/s5p_mfc_cmd.c
+++ /dev/null
@@ -1,120 +0,0 @@
1/*
2 * linux/drivers/media/video/s5p-mfc/s5p_mfc_cmd.c
3 *
4 * Copyright (C) 2011 Samsung Electronics Co., Ltd.
5 * http://www.samsung.com/
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include "regs-mfc.h"
14#include "s5p_mfc_cmd.h"
15#include "s5p_mfc_common.h"
16#include "s5p_mfc_debug.h"
17
18/* This function is used to send a command to the MFC */
19static int s5p_mfc_cmd_host2risc(struct s5p_mfc_dev *dev, int cmd,
20 struct s5p_mfc_cmd_args *args)
21{
22 int cur_cmd;
23 unsigned long timeout;
24
25 timeout = jiffies + msecs_to_jiffies(MFC_BW_TIMEOUT);
26 /* wait until host to risc command register becomes 'H2R_CMD_EMPTY' */
27 do {
28 if (time_after(jiffies, timeout)) {
29 mfc_err("Timeout while waiting for hardware\n");
30 return -EIO;
31 }
32 cur_cmd = mfc_read(dev, S5P_FIMV_HOST2RISC_CMD);
33 } while (cur_cmd != S5P_FIMV_H2R_CMD_EMPTY);
34 mfc_write(dev, args->arg[0], S5P_FIMV_HOST2RISC_ARG1);
35 mfc_write(dev, args->arg[1], S5P_FIMV_HOST2RISC_ARG2);
36 mfc_write(dev, args->arg[2], S5P_FIMV_HOST2RISC_ARG3);
37 mfc_write(dev, args->arg[3], S5P_FIMV_HOST2RISC_ARG4);
38 /* Issue the command */
39 mfc_write(dev, cmd, S5P_FIMV_HOST2RISC_CMD);
40 return 0;
41}
42
43/* Initialize the MFC */
44int s5p_mfc_sys_init_cmd(struct s5p_mfc_dev *dev)
45{
46 struct s5p_mfc_cmd_args h2r_args;
47
48 memset(&h2r_args, 0, sizeof(struct s5p_mfc_cmd_args));
49 h2r_args.arg[0] = dev->fw_size;
50 return s5p_mfc_cmd_host2risc(dev, S5P_FIMV_H2R_CMD_SYS_INIT, &h2r_args);
51}
52
53/* Suspend the MFC hardware */
54int s5p_mfc_sleep_cmd(struct s5p_mfc_dev *dev)
55{
56 struct s5p_mfc_cmd_args h2r_args;
57
58 memset(&h2r_args, 0, sizeof(struct s5p_mfc_cmd_args));
59 return s5p_mfc_cmd_host2risc(dev, S5P_FIMV_H2R_CMD_SLEEP, &h2r_args);
60}
61
62/* Wake up the MFC hardware */
63int s5p_mfc_wakeup_cmd(struct s5p_mfc_dev *dev)
64{
65 struct s5p_mfc_cmd_args h2r_args;
66
67 memset(&h2r_args, 0, sizeof(struct s5p_mfc_cmd_args));
68 return s5p_mfc_cmd_host2risc(dev, S5P_FIMV_H2R_CMD_WAKEUP, &h2r_args);
69}
70
71
72int s5p_mfc_open_inst_cmd(struct s5p_mfc_ctx *ctx)
73{
74 struct s5p_mfc_dev *dev = ctx->dev;
75 struct s5p_mfc_cmd_args h2r_args;
76 int ret;
77
78 /* Preparing decoding - getting instance number */
79 mfc_debug(2, "Getting instance number (codec: %d)\n", ctx->codec_mode);
80 dev->curr_ctx = ctx->num;
81 memset(&h2r_args, 0, sizeof(struct s5p_mfc_cmd_args));
82 h2r_args.arg[0] = ctx->codec_mode;
83 h2r_args.arg[1] = 0; /* no crc & no pixelcache */
84 h2r_args.arg[2] = ctx->ctx_ofs;
85 h2r_args.arg[3] = ctx->ctx_size;
86 ret = s5p_mfc_cmd_host2risc(dev, S5P_FIMV_H2R_CMD_OPEN_INSTANCE,
87 &h2r_args);
88 if (ret) {
89 mfc_err("Failed to create a new instance\n");
90 ctx->state = MFCINST_ERROR;
91 }
92 return ret;
93}
94
95int s5p_mfc_close_inst_cmd(struct s5p_mfc_ctx *ctx)
96{
97 struct s5p_mfc_dev *dev = ctx->dev;
98 struct s5p_mfc_cmd_args h2r_args;
99 int ret;
100
101 if (ctx->state == MFCINST_FREE) {
102 mfc_err("Instance already returned\n");
103 ctx->state = MFCINST_ERROR;
104 return -EINVAL;
105 }
106 /* Closing decoding instance */
107 mfc_debug(2, "Returning instance number %d\n", ctx->inst_no);
108 dev->curr_ctx = ctx->num;
109 memset(&h2r_args, 0, sizeof(struct s5p_mfc_cmd_args));
110 h2r_args.arg[0] = ctx->inst_no;
111 ret = s5p_mfc_cmd_host2risc(dev, S5P_FIMV_H2R_CMD_CLOSE_INSTANCE,
112 &h2r_args);
113 if (ret) {
114 mfc_err("Failed to return an instance\n");
115 ctx->state = MFCINST_ERROR;
116 return -EINVAL;
117 }
118 return 0;
119}
120
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_cmd.h b/drivers/media/video/s5p-mfc/s5p_mfc_cmd.h
deleted file mode 100644
index 5ceebfe6131a..000000000000
--- a/drivers/media/video/s5p-mfc/s5p_mfc_cmd.h
+++ /dev/null
@@ -1,30 +0,0 @@
1/*
2 * linux/drivers/media/video/s5p-mfc/s5p_mfc_cmd.h
3 *
4 * Copyright (C) 2011 Samsung Electronics Co., Ltd.
5 * http://www.samsung.com/
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#ifndef S5P_MFC_CMD_H_
14#define S5P_MFC_CMD_H_
15
16#include "s5p_mfc_common.h"
17
18#define MAX_H2R_ARG 4
19
20struct s5p_mfc_cmd_args {
21 unsigned int arg[MAX_H2R_ARG];
22};
23
24int s5p_mfc_sys_init_cmd(struct s5p_mfc_dev *dev);
25int s5p_mfc_sleep_cmd(struct s5p_mfc_dev *dev);
26int s5p_mfc_wakeup_cmd(struct s5p_mfc_dev *dev);
27int s5p_mfc_open_inst_cmd(struct s5p_mfc_ctx *ctx);
28int s5p_mfc_close_inst_cmd(struct s5p_mfc_ctx *ctx);
29
30#endif /* S5P_MFC_CMD_H_ */
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_common.h b/drivers/media/video/s5p-mfc/s5p_mfc_common.h
deleted file mode 100644
index bd5706a6bad1..000000000000
--- a/drivers/media/video/s5p-mfc/s5p_mfc_common.h
+++ /dev/null
@@ -1,570 +0,0 @@
1/*
2 * Samsung S5P Multi Format Codec v 5.0
3 *
4 * This file contains definitions of enums and structs used by the codec
5 * driver.
6 *
7 * Copyright (C) 2011 Samsung Electronics Co., Ltd.
8 * Kamil Debski, <k.debski@samsung.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the
13 * License, or (at your option) any later version
14 */
15
16#ifndef S5P_MFC_COMMON_H_
17#define S5P_MFC_COMMON_H_
18
19#include "regs-mfc.h"
20#include <linux/platform_device.h>
21#include <linux/videodev2.h>
22#include <media/v4l2-ctrls.h>
23#include <media/v4l2-device.h>
24#include <media/v4l2-ioctl.h>
25#include <media/videobuf2-core.h>
26
27/* Definitions related to MFC memory */
28
29/* Offset base used to differentiate between CAPTURE and OUTPUT
30* while mmaping */
31#define DST_QUEUE_OFF_BASE (TASK_SIZE / 2)
32
33/* Offset used by the hardware to store addresses */
34#define MFC_OFFSET_SHIFT 11
35
36#define FIRMWARE_ALIGN 0x20000 /* 128KB */
37#define MFC_H264_CTX_BUF_SIZE 0x96000 /* 600KB per H264 instance */
38#define MFC_CTX_BUF_SIZE 0x2800 /* 10KB per instance */
39#define DESC_BUF_SIZE 0x20000 /* 128KB for DESC buffer */
40#define SHARED_BUF_SIZE 0x2000 /* 8KB for shared buffer */
41
42#define DEF_CPB_SIZE 0x40000 /* 512KB */
43
44#define MFC_BANK1_ALLOC_CTX 0
45#define MFC_BANK2_ALLOC_CTX 1
46
47#define MFC_BANK1_ALIGN_ORDER 13
48#define MFC_BANK2_ALIGN_ORDER 13
49#define MFC_BASE_ALIGN_ORDER 17
50
51#include <media/videobuf2-dma-contig.h>
52
53static inline dma_addr_t s5p_mfc_mem_cookie(void *a, void *b)
54{
55 /* Same functionality as the vb2_dma_contig_plane_paddr */
56 dma_addr_t *paddr = vb2_dma_contig_memops.cookie(b);
57
58 return *paddr;
59}
60
61/* MFC definitions */
62#define MFC_MAX_EXTRA_DPB 5
63#define MFC_MAX_BUFFERS 32
64#define MFC_NUM_CONTEXTS 4
65/* Interrupt timeout */
66#define MFC_INT_TIMEOUT 2000
67/* Busy wait timeout */
68#define MFC_BW_TIMEOUT 500
69/* Watchdog interval */
70#define MFC_WATCHDOG_INTERVAL 1000
71/* After how many executions watchdog should assume lock up */
72#define MFC_WATCHDOG_CNT 10
73#define MFC_NO_INSTANCE_SET -1
74#define MFC_ENC_CAP_PLANE_COUNT 1
75#define MFC_ENC_OUT_PLANE_COUNT 2
76#define STUFF_BYTE 4
77#define MFC_MAX_CTRLS 64
78
79#define mfc_read(dev, offset) readl(dev->regs_base + (offset))
80#define mfc_write(dev, data, offset) writel((data), dev->regs_base + \
81 (offset))
82
83/**
84 * enum s5p_mfc_fmt_type - type of the pixelformat
85 */
86enum s5p_mfc_fmt_type {
87 MFC_FMT_DEC,
88 MFC_FMT_ENC,
89 MFC_FMT_RAW,
90};
91
92/**
93 * enum s5p_mfc_node_type - The type of an MFC device node.
94 */
95enum s5p_mfc_node_type {
96 MFCNODE_INVALID = -1,
97 MFCNODE_DECODER = 0,
98 MFCNODE_ENCODER = 1,
99};
100
101/**
102 * enum s5p_mfc_inst_type - The type of an MFC instance.
103 */
104enum s5p_mfc_inst_type {
105 MFCINST_INVALID,
106 MFCINST_DECODER,
107 MFCINST_ENCODER,
108};
109
110/**
111 * enum s5p_mfc_inst_state - The state of an MFC instance.
112 */
113enum s5p_mfc_inst_state {
114 MFCINST_FREE = 0,
115 MFCINST_INIT = 100,
116 MFCINST_GOT_INST,
117 MFCINST_HEAD_PARSED,
118 MFCINST_BUFS_SET,
119 MFCINST_RUNNING,
120 MFCINST_FINISHING,
121 MFCINST_FINISHED,
122 MFCINST_RETURN_INST,
123 MFCINST_ERROR,
124 MFCINST_ABORT,
125 MFCINST_RES_CHANGE_INIT,
126 MFCINST_RES_CHANGE_FLUSH,
127 MFCINST_RES_CHANGE_END,
128};
129
130/**
131 * enum s5p_mfc_queue_state - The state of buffer queue.
132 */
133enum s5p_mfc_queue_state {
134 QUEUE_FREE,
135 QUEUE_BUFS_REQUESTED,
136 QUEUE_BUFS_QUERIED,
137 QUEUE_BUFS_MMAPED,
138};
139
140/**
141 * enum s5p_mfc_decode_arg - type of frame decoding
142 */
143enum s5p_mfc_decode_arg {
144 MFC_DEC_FRAME,
145 MFC_DEC_LAST_FRAME,
146 MFC_DEC_RES_CHANGE,
147};
148
149struct s5p_mfc_ctx;
150
151/**
152 * struct s5p_mfc_buf - MFC buffer
153 */
154struct s5p_mfc_buf {
155 struct list_head list;
156 struct vb2_buffer *b;
157 union {
158 struct {
159 size_t luma;
160 size_t chroma;
161 } raw;
162 size_t stream;
163 } cookie;
164 int used;
165};
166
167/**
168 * struct s5p_mfc_pm - power management data structure
169 */
170struct s5p_mfc_pm {
171 struct clk *clock;
172 struct clk *clock_gate;
173 atomic_t power;
174 struct device *device;
175};
176
177/**
178 * struct s5p_mfc_dev - The struct containing driver internal parameters.
179 *
180 * @v4l2_dev: v4l2_device
181 * @vfd_dec: video device for decoding
182 * @vfd_enc: video device for encoding
183 * @plat_dev: platform device
184 * @mem_dev_l: child device of the left memory bank (0)
185 * @mem_dev_r: child device of the right memory bank (1)
186 * @regs_base: base address of the MFC hw registers
187 * @irq: irq resource
188 * @dec_ctrl_handler: control framework handler for decoding
189 * @enc_ctrl_handler: control framework handler for encoding
190 * @pm: power management control
191 * @num_inst: couter of active MFC instances
192 * @irqlock: lock for operations on videobuf2 queues
193 * @condlock: lock for changing/checking if a context is ready to be
194 * processed
195 * @mfc_mutex: lock for video_device
196 * @int_cond: variable used by the waitqueue
197 * @int_type: type of last interrupt
198 * @int_err: error number for last interrupt
199 * @queue: waitqueue for waiting for completion of device commands
200 * @fw_size: size of firmware
201 * @bank1: address of the beggining of bank 1 memory
202 * @bank2: address of the beggining of bank 2 memory
203 * @hw_lock: used for hardware locking
204 * @ctx: array of driver contexts
205 * @curr_ctx: number of the currently running context
206 * @ctx_work_bits: used to mark which contexts are waiting for hardware
207 * @watchdog_cnt: counter for the watchdog
208 * @watchdog_workqueue: workqueue for the watchdog
209 * @watchdog_work: worker for the watchdog
210 * @alloc_ctx: videobuf2 allocator contexts for two memory banks
211 * @enter_suspend: flag set when entering suspend
212 *
213 */
214struct s5p_mfc_dev {
215 struct v4l2_device v4l2_dev;
216 struct video_device *vfd_dec;
217 struct video_device *vfd_enc;
218 struct platform_device *plat_dev;
219 struct device *mem_dev_l;
220 struct device *mem_dev_r;
221 void __iomem *regs_base;
222 int irq;
223 struct v4l2_ctrl_handler dec_ctrl_handler;
224 struct v4l2_ctrl_handler enc_ctrl_handler;
225 struct s5p_mfc_pm pm;
226 int num_inst;
227 spinlock_t irqlock; /* lock when operating on videobuf2 queues */
228 spinlock_t condlock; /* lock when changing/checking if a context is
229 ready to be processed */
230 struct mutex mfc_mutex; /* video_device lock */
231 int int_cond;
232 int int_type;
233 unsigned int int_err;
234 wait_queue_head_t queue;
235 size_t fw_size;
236 size_t bank1;
237 size_t bank2;
238 unsigned long hw_lock;
239 struct s5p_mfc_ctx *ctx[MFC_NUM_CONTEXTS];
240 int curr_ctx;
241 unsigned long ctx_work_bits;
242 atomic_t watchdog_cnt;
243 struct timer_list watchdog_timer;
244 struct workqueue_struct *watchdog_workqueue;
245 struct work_struct watchdog_work;
246 void *alloc_ctx[2];
247 unsigned long enter_suspend;
248};
249
250/**
251 * struct s5p_mfc_h264_enc_params - encoding parameters for h264
252 */
253struct s5p_mfc_h264_enc_params {
254 enum v4l2_mpeg_video_h264_profile profile;
255 enum v4l2_mpeg_video_h264_loop_filter_mode loop_filter_mode;
256 s8 loop_filter_alpha;
257 s8 loop_filter_beta;
258 enum v4l2_mpeg_video_h264_entropy_mode entropy_mode;
259 u8 max_ref_pic;
260 u8 num_ref_pic_4p;
261 int _8x8_transform;
262 int rc_mb;
263 int rc_mb_dark;
264 int rc_mb_smooth;
265 int rc_mb_static;
266 int rc_mb_activity;
267 int vui_sar;
268 u8 vui_sar_idc;
269 u16 vui_ext_sar_width;
270 u16 vui_ext_sar_height;
271 int open_gop;
272 u16 open_gop_size;
273 u8 rc_frame_qp;
274 u8 rc_min_qp;
275 u8 rc_max_qp;
276 u8 rc_p_frame_qp;
277 u8 rc_b_frame_qp;
278 enum v4l2_mpeg_video_h264_level level_v4l2;
279 int level;
280 u16 cpb_size;
281};
282
283/**
284 * struct s5p_mfc_mpeg4_enc_params - encoding parameters for h263 and mpeg4
285 */
286struct s5p_mfc_mpeg4_enc_params {
287 /* MPEG4 Only */
288 enum v4l2_mpeg_video_mpeg4_profile profile;
289 int quarter_pixel;
290 /* Common for MPEG4, H263 */
291 u16 vop_time_res;
292 u16 vop_frm_delta;
293 u8 rc_frame_qp;
294 u8 rc_min_qp;
295 u8 rc_max_qp;
296 u8 rc_p_frame_qp;
297 u8 rc_b_frame_qp;
298 enum v4l2_mpeg_video_mpeg4_level level_v4l2;
299 int level;
300};
301
302/**
303 * struct s5p_mfc_enc_params - general encoding parameters
304 */
305struct s5p_mfc_enc_params {
306 u16 width;
307 u16 height;
308
309 u16 gop_size;
310 enum v4l2_mpeg_video_multi_slice_mode slice_mode;
311 u16 slice_mb;
312 u32 slice_bit;
313 u16 intra_refresh_mb;
314 int pad;
315 u8 pad_luma;
316 u8 pad_cb;
317 u8 pad_cr;
318 int rc_frame;
319 u32 rc_bitrate;
320 u16 rc_reaction_coeff;
321 u16 vbv_size;
322
323 enum v4l2_mpeg_video_header_mode seq_hdr_mode;
324 enum v4l2_mpeg_mfc51_video_frame_skip_mode frame_skip_mode;
325 int fixed_target_bit;
326
327 u8 num_b_frame;
328 u32 rc_framerate_num;
329 u32 rc_framerate_denom;
330 int interlace;
331
332 union {
333 struct s5p_mfc_h264_enc_params h264;
334 struct s5p_mfc_mpeg4_enc_params mpeg4;
335 } codec;
336
337};
338
339/**
340 * struct s5p_mfc_codec_ops - codec ops, used by encoding
341 */
342struct s5p_mfc_codec_ops {
343 /* initialization routines */
344 int (*pre_seq_start) (struct s5p_mfc_ctx *ctx);
345 int (*post_seq_start) (struct s5p_mfc_ctx *ctx);
346 /* execution routines */
347 int (*pre_frame_start) (struct s5p_mfc_ctx *ctx);
348 int (*post_frame_start) (struct s5p_mfc_ctx *ctx);
349};
350
351#define call_cop(c, op, args...) \
352 (((c)->c_ops->op) ? \
353 ((c)->c_ops->op(args)) : 0)
354
355/**
356 * struct s5p_mfc_ctx - This struct contains the instance context
357 *
358 * @dev: pointer to the s5p_mfc_dev of the device
359 * @fh: struct v4l2_fh
360 * @num: number of the context that this structure describes
361 * @int_cond: variable used by the waitqueue
362 * @int_type: type of the last interrupt
363 * @int_err: error number received from MFC hw in the interrupt
364 * @queue: waitqueue that can be used to wait for this context to
365 * finish
366 * @src_fmt: source pixelformat information
367 * @dst_fmt: destination pixelformat information
368 * @vq_src: vb2 queue for source buffers
369 * @vq_dst: vb2 queue for destination buffers
370 * @src_queue: driver internal queue for source buffers
371 * @dst_queue: driver internal queue for destination buffers
372 * @src_queue_cnt: number of buffers queued on the source internal queue
373 * @dst_queue_cnt: number of buffers queued on the dest internal queue
374 * @type: type of the instance - decoder or encoder
375 * @state: state of the context
376 * @inst_no: number of hw instance associated with the context
377 * @img_width: width of the image that is decoded or encoded
378 * @img_height: height of the image that is decoded or encoded
379 * @buf_width: width of the buffer for processed image
380 * @buf_height: height of the buffer for processed image
381 * @luma_size: size of a luma plane
382 * @chroma_size: size of a chroma plane
383 * @mv_size: size of a motion vectors buffer
384 * @consumed_stream: number of bytes that have been used so far from the
385 * decoding buffer
386 * @dpb_flush_flag: flag used to indicate that a DPB buffers are being
387 * flushed
388 * @bank1_buf: handle to memory allocated for temporary buffers from
389 * memory bank 1
390 * @bank1_phys: address of the temporary buffers from memory bank 1
391 * @bank1_size: size of the memory allocated for temporary buffers from
392 * memory bank 1
393 * @bank2_buf: handle to memory allocated for temporary buffers from
394 * memory bank 2
395 * @bank2_phys: address of the temporary buffers from memory bank 2
396 * @bank2_size: size of the memory allocated for temporary buffers from
397 * memory bank 2
398 * @capture_state: state of the capture buffers queue
399 * @output_state: state of the output buffers queue
400 * @src_bufs: information on allocated source buffers
401 * @dst_bufs: information on allocated destination buffers
402 * @sequence: counter for the sequence number for v4l2
403 * @dec_dst_flag: flags for buffers queued in the hardware
404 * @dec_src_buf_size: size of the buffer for source buffers in decoding
405 * @codec_mode: number of codec mode used by MFC hw
406 * @slice_interface: slice interface flag
407 * @loop_filter_mpeg4: loop filter for MPEG4 flag
408 * @display_delay: value of the display delay for H264
409 * @display_delay_enable: display delay for H264 enable flag
410 * @after_packed_pb: flag used to track buffer when stream is in
411 * Packed PB format
412 * @dpb_count: count of the DPB buffers required by MFC hw
413 * @total_dpb_count: count of DPB buffers with additional buffers
414 * requested by the application
415 * @ctx_buf: handle to the memory associated with this context
416 * @ctx_phys: address of the memory associated with this context
417 * @ctx_size: size of the memory associated with this context
418 * @desc_buf: description buffer for decoding handle
419 * @desc_phys: description buffer for decoding address
420 * @shm_alloc: handle for the shared memory buffer
421 * @shm: virtual address for the shared memory buffer
422 * @shm_ofs: address offset for shared memory
423 * @enc_params: encoding parameters for MFC
424 * @enc_dst_buf_size: size of the buffers for encoder output
425 * @frame_type: used to force the type of the next encoded frame
426 * @ref_queue: list of the reference buffers for encoding
427 * @ref_queue_cnt: number of the buffers in the reference list
428 * @c_ops: ops for encoding
429 * @ctrls: array of controls, used when adding controls to the
430 * v4l2 control framework
431 * @ctrl_handler: handler for v4l2 framework
432 */
433struct s5p_mfc_ctx {
434 struct s5p_mfc_dev *dev;
435 struct v4l2_fh fh;
436
437 int num;
438
439 int int_cond;
440 int int_type;
441 unsigned int int_err;
442 wait_queue_head_t queue;
443
444 struct s5p_mfc_fmt *src_fmt;
445 struct s5p_mfc_fmt *dst_fmt;
446
447 struct vb2_queue vq_src;
448 struct vb2_queue vq_dst;
449
450 struct list_head src_queue;
451 struct list_head dst_queue;
452
453 unsigned int src_queue_cnt;
454 unsigned int dst_queue_cnt;
455
456 enum s5p_mfc_inst_type type;
457 enum s5p_mfc_inst_state state;
458 int inst_no;
459
460 /* Image parameters */
461 int img_width;
462 int img_height;
463 int buf_width;
464 int buf_height;
465
466 int luma_size;
467 int chroma_size;
468 int mv_size;
469
470 unsigned long consumed_stream;
471
472 unsigned int dpb_flush_flag;
473
474 /* Buffers */
475 void *bank1_buf;
476 size_t bank1_phys;
477 size_t bank1_size;
478
479 void *bank2_buf;
480 size_t bank2_phys;
481 size_t bank2_size;
482
483 enum s5p_mfc_queue_state capture_state;
484 enum s5p_mfc_queue_state output_state;
485
486 struct s5p_mfc_buf src_bufs[MFC_MAX_BUFFERS];
487 int src_bufs_cnt;
488 struct s5p_mfc_buf dst_bufs[MFC_MAX_BUFFERS];
489 int dst_bufs_cnt;
490
491 unsigned int sequence;
492 unsigned long dec_dst_flag;
493 size_t dec_src_buf_size;
494
495 /* Control values */
496 int codec_mode;
497 int slice_interface;
498 int loop_filter_mpeg4;
499 int display_delay;
500 int display_delay_enable;
501 int after_packed_pb;
502
503 int dpb_count;
504 int total_dpb_count;
505
506 /* Buffers */
507 void *ctx_buf;
508 size_t ctx_phys;
509 size_t ctx_ofs;
510 size_t ctx_size;
511
512 void *desc_buf;
513 size_t desc_phys;
514
515
516 void *shm_alloc;
517 void *shm;
518 size_t shm_ofs;
519
520 struct s5p_mfc_enc_params enc_params;
521
522 size_t enc_dst_buf_size;
523
524 enum v4l2_mpeg_mfc51_video_force_frame_type force_frame_type;
525
526 struct list_head ref_queue;
527 unsigned int ref_queue_cnt;
528
529 struct s5p_mfc_codec_ops *c_ops;
530
531 struct v4l2_ctrl *ctrls[MFC_MAX_CTRLS];
532 struct v4l2_ctrl_handler ctrl_handler;
533};
534
535/*
536 * struct s5p_mfc_fmt - structure used to store information about pixelformats
537 * used by the MFC
538 */
539struct s5p_mfc_fmt {
540 char *name;
541 u32 fourcc;
542 u32 codec_mode;
543 enum s5p_mfc_fmt_type type;
544 u32 num_planes;
545};
546
547/**
548 * struct mfc_control - structure used to store information about MFC controls
549 * it is used to initialize the control framework.
550 */
551struct mfc_control {
552 __u32 id;
553 enum v4l2_ctrl_type type;
554 __u8 name[32]; /* Whatever */
555 __s32 minimum; /* Note signedness */
556 __s32 maximum;
557 __s32 step;
558 __u32 menu_skip_mask;
559 __s32 default_value;
560 __u32 flags;
561 __u32 reserved[2];
562 __u8 is_volatile;
563};
564
565
566#define fh_to_ctx(__fh) container_of(__fh, struct s5p_mfc_ctx, fh)
567#define ctrl_to_ctx(__ctrl) \
568 container_of((__ctrl)->handler, struct s5p_mfc_ctx, ctrl_handler)
569
570#endif /* S5P_MFC_COMMON_H_ */
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_ctrl.c b/drivers/media/video/s5p-mfc/s5p_mfc_ctrl.c
deleted file mode 100644
index 08a5cfeaa59e..000000000000
--- a/drivers/media/video/s5p-mfc/s5p_mfc_ctrl.c
+++ /dev/null
@@ -1,343 +0,0 @@
1/*
2 * linux/drivers/media/video/s5p-mfc/s5p_mfc_ctrl.c
3 *
4 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
5 * http://www.samsung.com/
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <linux/delay.h>
14#include <linux/err.h>
15#include <linux/firmware.h>
16#include <linux/jiffies.h>
17#include <linux/sched.h>
18#include "regs-mfc.h"
19#include "s5p_mfc_cmd.h"
20#include "s5p_mfc_common.h"
21#include "s5p_mfc_debug.h"
22#include "s5p_mfc_intr.h"
23#include "s5p_mfc_pm.h"
24
25static void *s5p_mfc_bitproc_buf;
26static size_t s5p_mfc_bitproc_phys;
27static unsigned char *s5p_mfc_bitproc_virt;
28
29/* Allocate and load firmware */
30int s5p_mfc_alloc_and_load_firmware(struct s5p_mfc_dev *dev)
31{
32 struct firmware *fw_blob;
33 size_t bank2_base_phys;
34 void *b_base;
35 int err;
36
37 /* Firmare has to be present as a separate file or compiled
38 * into kernel. */
39 mfc_debug_enter();
40 err = request_firmware((const struct firmware **)&fw_blob,
41 "s5p-mfc.fw", dev->v4l2_dev.dev);
42 if (err != 0) {
43 mfc_err("Firmware is not present in the /lib/firmware directory nor compiled in kernel\n");
44 return -EINVAL;
45 }
46 dev->fw_size = ALIGN(fw_blob->size, FIRMWARE_ALIGN);
47 if (s5p_mfc_bitproc_buf) {
48 mfc_err("Attempting to allocate firmware when it seems that it is already loaded\n");
49 release_firmware(fw_blob);
50 return -ENOMEM;
51 }
52 s5p_mfc_bitproc_buf = vb2_dma_contig_memops.alloc(
53 dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], dev->fw_size);
54 if (IS_ERR(s5p_mfc_bitproc_buf)) {
55 s5p_mfc_bitproc_buf = NULL;
56 mfc_err("Allocating bitprocessor buffer failed\n");
57 release_firmware(fw_blob);
58 return -ENOMEM;
59 }
60 s5p_mfc_bitproc_phys = s5p_mfc_mem_cookie(
61 dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], s5p_mfc_bitproc_buf);
62 if (s5p_mfc_bitproc_phys & ((1 << MFC_BASE_ALIGN_ORDER) - 1)) {
63 mfc_err("The base memory for bank 1 is not aligned to 128KB\n");
64 vb2_dma_contig_memops.put(s5p_mfc_bitproc_buf);
65 s5p_mfc_bitproc_phys = 0;
66 s5p_mfc_bitproc_buf = NULL;
67 release_firmware(fw_blob);
68 return -EIO;
69 }
70 s5p_mfc_bitproc_virt = vb2_dma_contig_memops.vaddr(s5p_mfc_bitproc_buf);
71 if (!s5p_mfc_bitproc_virt) {
72 mfc_err("Bitprocessor memory remap failed\n");
73 vb2_dma_contig_memops.put(s5p_mfc_bitproc_buf);
74 s5p_mfc_bitproc_phys = 0;
75 s5p_mfc_bitproc_buf = NULL;
76 release_firmware(fw_blob);
77 return -EIO;
78 }
79 dev->bank1 = s5p_mfc_bitproc_phys;
80 b_base = vb2_dma_contig_memops.alloc(
81 dev->alloc_ctx[MFC_BANK2_ALLOC_CTX], 1 << MFC_BANK2_ALIGN_ORDER);
82 if (IS_ERR(b_base)) {
83 vb2_dma_contig_memops.put(s5p_mfc_bitproc_buf);
84 s5p_mfc_bitproc_phys = 0;
85 s5p_mfc_bitproc_buf = NULL;
86 mfc_err("Allocating bank2 base failed\n");
87 release_firmware(fw_blob);
88 return -ENOMEM;
89 }
90 bank2_base_phys = s5p_mfc_mem_cookie(
91 dev->alloc_ctx[MFC_BANK2_ALLOC_CTX], b_base);
92 vb2_dma_contig_memops.put(b_base);
93 if (bank2_base_phys & ((1 << MFC_BASE_ALIGN_ORDER) - 1)) {
94 mfc_err("The base memory for bank 2 is not aligned to 128KB\n");
95 vb2_dma_contig_memops.put(s5p_mfc_bitproc_buf);
96 s5p_mfc_bitproc_phys = 0;
97 s5p_mfc_bitproc_buf = NULL;
98 release_firmware(fw_blob);
99 return -EIO;
100 }
101 dev->bank2 = bank2_base_phys;
102 memcpy(s5p_mfc_bitproc_virt, fw_blob->data, fw_blob->size);
103 wmb();
104 release_firmware(fw_blob);
105 mfc_debug_leave();
106 return 0;
107}
108
109/* Reload firmware to MFC */
110int s5p_mfc_reload_firmware(struct s5p_mfc_dev *dev)
111{
112 struct firmware *fw_blob;
113 int err;
114
115 /* Firmare has to be present as a separate file or compiled
116 * into kernel. */
117 mfc_debug_enter();
118 err = request_firmware((const struct firmware **)&fw_blob,
119 "s5p-mfc.fw", dev->v4l2_dev.dev);
120 if (err != 0) {
121 mfc_err("Firmware is not present in the /lib/firmware directory nor compiled in kernel\n");
122 return -EINVAL;
123 }
124 if (fw_blob->size > dev->fw_size) {
125 mfc_err("MFC firmware is too big to be loaded\n");
126 release_firmware(fw_blob);
127 return -ENOMEM;
128 }
129 if (s5p_mfc_bitproc_buf == NULL || s5p_mfc_bitproc_phys == 0) {
130 mfc_err("MFC firmware is not allocated or was not mapped correctly\n");
131 release_firmware(fw_blob);
132 return -EINVAL;
133 }
134 memcpy(s5p_mfc_bitproc_virt, fw_blob->data, fw_blob->size);
135 wmb();
136 release_firmware(fw_blob);
137 mfc_debug_leave();
138 return 0;
139}
140
141/* Release firmware memory */
142int s5p_mfc_release_firmware(struct s5p_mfc_dev *dev)
143{
144 /* Before calling this function one has to make sure
145 * that MFC is no longer processing */
146 if (!s5p_mfc_bitproc_buf)
147 return -EINVAL;
148 vb2_dma_contig_memops.put(s5p_mfc_bitproc_buf);
149 s5p_mfc_bitproc_virt = NULL;
150 s5p_mfc_bitproc_phys = 0;
151 s5p_mfc_bitproc_buf = NULL;
152 return 0;
153}
154
155/* Reset the device */
156int s5p_mfc_reset(struct s5p_mfc_dev *dev)
157{
158 unsigned int mc_status;
159 unsigned long timeout;
160
161 mfc_debug_enter();
162 /* Stop procedure */
163 /* reset RISC */
164 mfc_write(dev, 0x3f6, S5P_FIMV_SW_RESET);
165 /* All reset except for MC */
166 mfc_write(dev, 0x3e2, S5P_FIMV_SW_RESET);
167 mdelay(10);
168
169 timeout = jiffies + msecs_to_jiffies(MFC_BW_TIMEOUT);
170 /* Check MC status */
171 do {
172 if (time_after(jiffies, timeout)) {
173 mfc_err("Timeout while resetting MFC\n");
174 return -EIO;
175 }
176
177 mc_status = mfc_read(dev, S5P_FIMV_MC_STATUS);
178
179 } while (mc_status & 0x3);
180
181 mfc_write(dev, 0x0, S5P_FIMV_SW_RESET);
182 mfc_write(dev, 0x3fe, S5P_FIMV_SW_RESET);
183 mfc_debug_leave();
184 return 0;
185}
186
187static inline void s5p_mfc_init_memctrl(struct s5p_mfc_dev *dev)
188{
189 mfc_write(dev, dev->bank1, S5P_FIMV_MC_DRAMBASE_ADR_A);
190 mfc_write(dev, dev->bank2, S5P_FIMV_MC_DRAMBASE_ADR_B);
191 mfc_debug(2, "Bank1: %08x, Bank2: %08x\n", dev->bank1, dev->bank2);
192}
193
194static inline void s5p_mfc_clear_cmds(struct s5p_mfc_dev *dev)
195{
196 mfc_write(dev, 0xffffffff, S5P_FIMV_SI_CH0_INST_ID);
197 mfc_write(dev, 0xffffffff, S5P_FIMV_SI_CH1_INST_ID);
198 mfc_write(dev, 0, S5P_FIMV_RISC2HOST_CMD);
199 mfc_write(dev, 0, S5P_FIMV_HOST2RISC_CMD);
200}
201
202/* Initialize hardware */
203int s5p_mfc_init_hw(struct s5p_mfc_dev *dev)
204{
205 unsigned int ver;
206 int ret;
207
208 mfc_debug_enter();
209 if (!s5p_mfc_bitproc_buf)
210 return -EINVAL;
211
212 /* 0. MFC reset */
213 mfc_debug(2, "MFC reset..\n");
214 s5p_mfc_clock_on();
215 ret = s5p_mfc_reset(dev);
216 if (ret) {
217 mfc_err("Failed to reset MFC - timeout\n");
218 return ret;
219 }
220 mfc_debug(2, "Done MFC reset..\n");
221 /* 1. Set DRAM base Addr */
222 s5p_mfc_init_memctrl(dev);
223 /* 2. Initialize registers of channel I/F */
224 s5p_mfc_clear_cmds(dev);
225 /* 3. Release reset signal to the RISC */
226 s5p_mfc_clean_dev_int_flags(dev);
227 mfc_write(dev, 0x3ff, S5P_FIMV_SW_RESET);
228 mfc_debug(2, "Will now wait for completion of firmware transfer\n");
229 if (s5p_mfc_wait_for_done_dev(dev, S5P_FIMV_R2H_CMD_FW_STATUS_RET)) {
230 mfc_err("Failed to load firmware\n");
231 s5p_mfc_reset(dev);
232 s5p_mfc_clock_off();
233 return -EIO;
234 }
235 s5p_mfc_clean_dev_int_flags(dev);
236 /* 4. Initialize firmware */
237 ret = s5p_mfc_sys_init_cmd(dev);
238 if (ret) {
239 mfc_err("Failed to send command to MFC - timeout\n");
240 s5p_mfc_reset(dev);
241 s5p_mfc_clock_off();
242 return ret;
243 }
244 mfc_debug(2, "Ok, now will write a command to init the system\n");
245 if (s5p_mfc_wait_for_done_dev(dev, S5P_FIMV_R2H_CMD_SYS_INIT_RET)) {
246 mfc_err("Failed to load firmware\n");
247 s5p_mfc_reset(dev);
248 s5p_mfc_clock_off();
249 return -EIO;
250 }
251 dev->int_cond = 0;
252 if (dev->int_err != 0 || dev->int_type !=
253 S5P_FIMV_R2H_CMD_SYS_INIT_RET) {
254 /* Failure. */
255 mfc_err("Failed to init firmware - error: %d int: %d\n",
256 dev->int_err, dev->int_type);
257 s5p_mfc_reset(dev);
258 s5p_mfc_clock_off();
259 return -EIO;
260 }
261 ver = mfc_read(dev, S5P_FIMV_FW_VERSION);
262 mfc_debug(2, "MFC F/W version : %02xyy, %02xmm, %02xdd\n",
263 (ver >> 16) & 0xFF, (ver >> 8) & 0xFF, ver & 0xFF);
264 s5p_mfc_clock_off();
265 mfc_debug_leave();
266 return 0;
267}
268
269
270int s5p_mfc_sleep(struct s5p_mfc_dev *dev)
271{
272 int ret;
273
274 mfc_debug_enter();
275 s5p_mfc_clock_on();
276 s5p_mfc_clean_dev_int_flags(dev);
277 ret = s5p_mfc_sleep_cmd(dev);
278 if (ret) {
279 mfc_err("Failed to send command to MFC - timeout\n");
280 return ret;
281 }
282 if (s5p_mfc_wait_for_done_dev(dev, S5P_FIMV_R2H_CMD_SLEEP_RET)) {
283 mfc_err("Failed to sleep\n");
284 return -EIO;
285 }
286 s5p_mfc_clock_off();
287 dev->int_cond = 0;
288 if (dev->int_err != 0 || dev->int_type !=
289 S5P_FIMV_R2H_CMD_SLEEP_RET) {
290 /* Failure. */
291 mfc_err("Failed to sleep - error: %d int: %d\n", dev->int_err,
292 dev->int_type);
293 return -EIO;
294 }
295 mfc_debug_leave();
296 return ret;
297}
298
299int s5p_mfc_wakeup(struct s5p_mfc_dev *dev)
300{
301 int ret;
302
303 mfc_debug_enter();
304 /* 0. MFC reset */
305 mfc_debug(2, "MFC reset..\n");
306 s5p_mfc_clock_on();
307 ret = s5p_mfc_reset(dev);
308 if (ret) {
309 mfc_err("Failed to reset MFC - timeout\n");
310 return ret;
311 }
312 mfc_debug(2, "Done MFC reset..\n");
313 /* 1. Set DRAM base Addr */
314 s5p_mfc_init_memctrl(dev);
315 /* 2. Initialize registers of channel I/F */
316 s5p_mfc_clear_cmds(dev);
317 s5p_mfc_clean_dev_int_flags(dev);
318 /* 3. Initialize firmware */
319 ret = s5p_mfc_wakeup_cmd(dev);
320 if (ret) {
321 mfc_err("Failed to send command to MFC - timeout\n");
322 return ret;
323 }
324 /* 4. Release reset signal to the RISC */
325 mfc_write(dev, 0x3ff, S5P_FIMV_SW_RESET);
326 mfc_debug(2, "Ok, now will write a command to wakeup the system\n");
327 if (s5p_mfc_wait_for_done_dev(dev, S5P_FIMV_R2H_CMD_WAKEUP_RET)) {
328 mfc_err("Failed to load firmware\n");
329 return -EIO;
330 }
331 s5p_mfc_clock_off();
332 dev->int_cond = 0;
333 if (dev->int_err != 0 || dev->int_type !=
334 S5P_FIMV_R2H_CMD_WAKEUP_RET) {
335 /* Failure. */
336 mfc_err("Failed to wakeup - error: %d int: %d\n", dev->int_err,
337 dev->int_type);
338 return -EIO;
339 }
340 mfc_debug_leave();
341 return 0;
342}
343
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_ctrl.h b/drivers/media/video/s5p-mfc/s5p_mfc_ctrl.h
deleted file mode 100644
index 61dc23b7ee5a..000000000000
--- a/drivers/media/video/s5p-mfc/s5p_mfc_ctrl.h
+++ /dev/null
@@ -1,29 +0,0 @@
1/*
2 * linux/drivers/media/video/s5p-mfc/s5p_mfc_ctrl.h
3 *
4 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
5 * http://www.samsung.com/
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#ifndef S5P_MFC_CTRL_H
14#define S5P_MFC_CTRL_H
15
16#include "s5p_mfc_common.h"
17
18int s5p_mfc_release_firmware(struct s5p_mfc_dev *dev);
19int s5p_mfc_alloc_and_load_firmware(struct s5p_mfc_dev *dev);
20int s5p_mfc_reload_firmware(struct s5p_mfc_dev *dev);
21
22int s5p_mfc_init_hw(struct s5p_mfc_dev *dev);
23
24int s5p_mfc_sleep(struct s5p_mfc_dev *dev);
25int s5p_mfc_wakeup(struct s5p_mfc_dev *dev);
26
27int s5p_mfc_reset(struct s5p_mfc_dev *dev);
28
29#endif /* S5P_MFC_CTRL_H */
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_debug.h b/drivers/media/video/s5p-mfc/s5p_mfc_debug.h
deleted file mode 100644
index ecb8616a492a..000000000000
--- a/drivers/media/video/s5p-mfc/s5p_mfc_debug.h
+++ /dev/null
@@ -1,48 +0,0 @@
1/*
2 * drivers/media/video/samsung/mfc5/s5p_mfc_debug.h
3 *
4 * Header file for Samsung MFC (Multi Function Codec - FIMV) driver
5 * This file contains debug macros
6 *
7 * Kamil Debski, Copyright (c) 2011 Samsung Electronics
8 * http://www.samsung.com/
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#ifndef S5P_MFC_DEBUG_H_
16#define S5P_MFC_DEBUG_H_
17
18#define DEBUG
19
20#ifdef DEBUG
21extern int debug;
22
23#define mfc_debug(level, fmt, args...) \
24 do { \
25 if (debug >= level) \
26 printk(KERN_DEBUG "%s:%d: " fmt, \
27 __func__, __LINE__, ##args); \
28 } while (0)
29#else
30#define mfc_debug(level, fmt, args...)
31#endif
32
33#define mfc_debug_enter() mfc_debug(5, "enter")
34#define mfc_debug_leave() mfc_debug(5, "leave")
35
36#define mfc_err(fmt, args...) \
37 do { \
38 printk(KERN_ERR "%s:%d: " fmt, \
39 __func__, __LINE__, ##args); \
40 } while (0)
41
42#define mfc_info(fmt, args...) \
43 do { \
44 printk(KERN_INFO "%s:%d: " fmt, \
45 __func__, __LINE__, ##args); \
46 } while (0)
47
48#endif /* S5P_MFC_DEBUG_H_ */
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_dec.c b/drivers/media/video/s5p-mfc/s5p_mfc_dec.c
deleted file mode 100644
index c5d567f87d77..000000000000
--- a/drivers/media/video/s5p-mfc/s5p_mfc_dec.c
+++ /dev/null
@@ -1,1044 +0,0 @@
1/*
2 * linux/drivers/media/video/s5p-mfc/s5p_mfc_dec.c
3 *
4 * Copyright (C) 2011 Samsung Electronics Co., Ltd.
5 * http://www.samsung.com/
6 * Kamil Debski, <k.debski@samsung.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 */
13
14#include <linux/clk.h>
15#include <linux/interrupt.h>
16#include <linux/io.h>
17#include <linux/module.h>
18#include <linux/platform_device.h>
19#include <linux/sched.h>
20#include <linux/slab.h>
21#include <linux/version.h>
22#include <linux/videodev2.h>
23#include <linux/workqueue.h>
24#include <media/v4l2-ctrls.h>
25#include <media/videobuf2-core.h>
26#include "regs-mfc.h"
27#include "s5p_mfc_common.h"
28#include "s5p_mfc_debug.h"
29#include "s5p_mfc_dec.h"
30#include "s5p_mfc_intr.h"
31#include "s5p_mfc_opr.h"
32#include "s5p_mfc_pm.h"
33#include "s5p_mfc_shm.h"
34
35static struct s5p_mfc_fmt formats[] = {
36 {
37 .name = "4:2:0 2 Planes 64x32 Tiles",
38 .fourcc = V4L2_PIX_FMT_NV12MT,
39 .codec_mode = S5P_FIMV_CODEC_NONE,
40 .type = MFC_FMT_RAW,
41 .num_planes = 2,
42 },
43 {
44 .name = "4:2:0 2 Planes",
45 .fourcc = V4L2_PIX_FMT_NV12M,
46 .codec_mode = S5P_FIMV_CODEC_NONE,
47 .type = MFC_FMT_RAW,
48 .num_planes = 2,
49 },
50 {
51 .name = "H264 Encoded Stream",
52 .fourcc = V4L2_PIX_FMT_H264,
53 .codec_mode = S5P_FIMV_CODEC_H264_DEC,
54 .type = MFC_FMT_DEC,
55 .num_planes = 1,
56 },
57 {
58 .name = "H263 Encoded Stream",
59 .fourcc = V4L2_PIX_FMT_H263,
60 .codec_mode = S5P_FIMV_CODEC_H263_DEC,
61 .type = MFC_FMT_DEC,
62 .num_planes = 1,
63 },
64 {
65 .name = "MPEG1 Encoded Stream",
66 .fourcc = V4L2_PIX_FMT_MPEG1,
67 .codec_mode = S5P_FIMV_CODEC_MPEG2_DEC,
68 .type = MFC_FMT_DEC,
69 .num_planes = 1,
70 },
71 {
72 .name = "MPEG2 Encoded Stream",
73 .fourcc = V4L2_PIX_FMT_MPEG2,
74 .codec_mode = S5P_FIMV_CODEC_MPEG2_DEC,
75 .type = MFC_FMT_DEC,
76 .num_planes = 1,
77 },
78 {
79 .name = "MPEG4 Encoded Stream",
80 .fourcc = V4L2_PIX_FMT_MPEG4,
81 .codec_mode = S5P_FIMV_CODEC_MPEG4_DEC,
82 .type = MFC_FMT_DEC,
83 .num_planes = 1,
84 },
85 {
86 .name = "XviD Encoded Stream",
87 .fourcc = V4L2_PIX_FMT_XVID,
88 .codec_mode = S5P_FIMV_CODEC_MPEG4_DEC,
89 .type = MFC_FMT_DEC,
90 .num_planes = 1,
91 },
92 {
93 .name = "VC1 Encoded Stream",
94 .fourcc = V4L2_PIX_FMT_VC1_ANNEX_G,
95 .codec_mode = S5P_FIMV_CODEC_VC1_DEC,
96 .type = MFC_FMT_DEC,
97 .num_planes = 1,
98 },
99 {
100 .name = "VC1 RCV Encoded Stream",
101 .fourcc = V4L2_PIX_FMT_VC1_ANNEX_L,
102 .codec_mode = S5P_FIMV_CODEC_VC1RCV_DEC,
103 .type = MFC_FMT_DEC,
104 .num_planes = 1,
105 },
106};
107
108#define NUM_FORMATS ARRAY_SIZE(formats)
109
110/* Find selected format description */
111static struct s5p_mfc_fmt *find_format(struct v4l2_format *f, unsigned int t)
112{
113 unsigned int i;
114
115 for (i = 0; i < NUM_FORMATS; i++) {
116 if (formats[i].fourcc == f->fmt.pix_mp.pixelformat &&
117 formats[i].type == t)
118 return &formats[i];
119 }
120 return NULL;
121}
122
123static struct mfc_control controls[] = {
124 {
125 .id = V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY,
126 .type = V4L2_CTRL_TYPE_INTEGER,
127 .name = "H264 Display Delay",
128 .minimum = 0,
129 .maximum = 16383,
130 .step = 1,
131 .default_value = 0,
132 },
133 {
134 .id = V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY_ENABLE,
135 .type = V4L2_CTRL_TYPE_BOOLEAN,
136 .name = "H264 Display Delay Enable",
137 .minimum = 0,
138 .maximum = 1,
139 .step = 1,
140 .default_value = 0,
141 },
142 {
143 .id = V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER,
144 .type = V4L2_CTRL_TYPE_BOOLEAN,
145 .name = "Mpeg4 Loop Filter Enable",
146 .minimum = 0,
147 .maximum = 1,
148 .step = 1,
149 .default_value = 0,
150 },
151 {
152 .id = V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE,
153 .type = V4L2_CTRL_TYPE_BOOLEAN,
154 .name = "Slice Interface Enable",
155 .minimum = 0,
156 .maximum = 1,
157 .step = 1,
158 .default_value = 0,
159 },
160 {
161 .id = V4L2_CID_MIN_BUFFERS_FOR_CAPTURE,
162 .type = V4L2_CTRL_TYPE_INTEGER,
163 .name = "Minimum number of cap bufs",
164 .minimum = 1,
165 .maximum = 32,
166 .step = 1,
167 .default_value = 1,
168 .is_volatile = 1,
169 },
170};
171
172#define NUM_CTRLS ARRAY_SIZE(controls)
173
174/* Check whether a context should be run on hardware */
175static int s5p_mfc_ctx_ready(struct s5p_mfc_ctx *ctx)
176{
177 /* Context is to parse header */
178 if (ctx->src_queue_cnt >= 1 && ctx->state == MFCINST_GOT_INST)
179 return 1;
180 /* Context is to decode a frame */
181 if (ctx->src_queue_cnt >= 1 &&
182 ctx->state == MFCINST_RUNNING &&
183 ctx->dst_queue_cnt >= ctx->dpb_count)
184 return 1;
185 /* Context is to return last frame */
186 if (ctx->state == MFCINST_FINISHING &&
187 ctx->dst_queue_cnt >= ctx->dpb_count)
188 return 1;
189 /* Context is to set buffers */
190 if (ctx->src_queue_cnt >= 1 &&
191 ctx->state == MFCINST_HEAD_PARSED &&
192 ctx->capture_state == QUEUE_BUFS_MMAPED)
193 return 1;
194 /* Resolution change */
195 if ((ctx->state == MFCINST_RES_CHANGE_INIT ||
196 ctx->state == MFCINST_RES_CHANGE_FLUSH) &&
197 ctx->dst_queue_cnt >= ctx->dpb_count)
198 return 1;
199 if (ctx->state == MFCINST_RES_CHANGE_END &&
200 ctx->src_queue_cnt >= 1)
201 return 1;
202 mfc_debug(2, "ctx is not ready\n");
203 return 0;
204}
205
206static struct s5p_mfc_codec_ops decoder_codec_ops = {
207 .pre_seq_start = NULL,
208 .post_seq_start = NULL,
209 .pre_frame_start = NULL,
210 .post_frame_start = NULL,
211};
212
213/* Query capabilities of the device */
214static int vidioc_querycap(struct file *file, void *priv,
215 struct v4l2_capability *cap)
216{
217 struct s5p_mfc_dev *dev = video_drvdata(file);
218
219 strncpy(cap->driver, dev->plat_dev->name, sizeof(cap->driver) - 1);
220 strncpy(cap->card, dev->plat_dev->name, sizeof(cap->card) - 1);
221 cap->bus_info[0] = 0;
222 cap->version = KERNEL_VERSION(1, 0, 0);
223 /*
224 * This is only a mem-to-mem video device. The capture and output
225 * device capability flags are left only for backward compatibility
226 * and are scheduled for removal.
227 */
228 cap->capabilities = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING |
229 V4L2_CAP_VIDEO_CAPTURE_MPLANE |
230 V4L2_CAP_VIDEO_OUTPUT_MPLANE;
231 return 0;
232}
233
234/* Enumerate format */
235static int vidioc_enum_fmt(struct v4l2_fmtdesc *f, bool mplane, bool out)
236{
237 struct s5p_mfc_fmt *fmt;
238 int i, j = 0;
239
240 for (i = 0; i < ARRAY_SIZE(formats); ++i) {
241 if (mplane && formats[i].num_planes == 1)
242 continue;
243 else if (!mplane && formats[i].num_planes > 1)
244 continue;
245 if (out && formats[i].type != MFC_FMT_DEC)
246 continue;
247 else if (!out && formats[i].type != MFC_FMT_RAW)
248 continue;
249
250 if (j == f->index)
251 break;
252 ++j;
253 }
254 if (i == ARRAY_SIZE(formats))
255 return -EINVAL;
256 fmt = &formats[i];
257 strlcpy(f->description, fmt->name, sizeof(f->description));
258 f->pixelformat = fmt->fourcc;
259 return 0;
260}
261
262static int vidioc_enum_fmt_vid_cap(struct file *file, void *pirv,
263 struct v4l2_fmtdesc *f)
264{
265 return vidioc_enum_fmt(f, false, false);
266}
267
268static int vidioc_enum_fmt_vid_cap_mplane(struct file *file, void *pirv,
269 struct v4l2_fmtdesc *f)
270{
271 return vidioc_enum_fmt(f, true, false);
272}
273
274static int vidioc_enum_fmt_vid_out(struct file *file, void *prov,
275 struct v4l2_fmtdesc *f)
276{
277 return vidioc_enum_fmt(f, false, true);
278}
279
280static int vidioc_enum_fmt_vid_out_mplane(struct file *file, void *prov,
281 struct v4l2_fmtdesc *f)
282{
283 return vidioc_enum_fmt(f, true, true);
284}
285
286/* Get format */
287static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
288{
289 struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
290 struct v4l2_pix_format_mplane *pix_mp;
291
292 mfc_debug_enter();
293 pix_mp = &f->fmt.pix_mp;
294 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE &&
295 (ctx->state == MFCINST_GOT_INST || ctx->state ==
296 MFCINST_RES_CHANGE_END)) {
297 /* If the MFC is parsing the header,
298 * so wait until it is finished */
299 s5p_mfc_clean_ctx_int_flags(ctx);
300 s5p_mfc_wait_for_done_ctx(ctx, S5P_FIMV_R2H_CMD_SEQ_DONE_RET,
301 0);
302 }
303 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE &&
304 ctx->state >= MFCINST_HEAD_PARSED &&
305 ctx->state < MFCINST_ABORT) {
306 /* This is run on CAPTURE (decode output) */
307 /* Width and height are set to the dimensions
308 of the movie, the buffer is bigger and
309 further processing stages should crop to this
310 rectangle. */
311 pix_mp->width = ctx->buf_width;
312 pix_mp->height = ctx->buf_height;
313 pix_mp->field = V4L2_FIELD_NONE;
314 pix_mp->num_planes = 2;
315 /* Set pixelformat to the format in which MFC
316 outputs the decoded frame */
317 pix_mp->pixelformat = V4L2_PIX_FMT_NV12MT;
318 pix_mp->plane_fmt[0].bytesperline = ctx->buf_width;
319 pix_mp->plane_fmt[0].sizeimage = ctx->luma_size;
320 pix_mp->plane_fmt[1].bytesperline = ctx->buf_width;
321 pix_mp->plane_fmt[1].sizeimage = ctx->chroma_size;
322 } else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
323 /* This is run on OUTPUT
324 The buffer contains compressed image
325 so width and height have no meaning */
326 pix_mp->width = 0;
327 pix_mp->height = 0;
328 pix_mp->field = V4L2_FIELD_NONE;
329 pix_mp->plane_fmt[0].bytesperline = ctx->dec_src_buf_size;
330 pix_mp->plane_fmt[0].sizeimage = ctx->dec_src_buf_size;
331 pix_mp->pixelformat = ctx->src_fmt->fourcc;
332 pix_mp->num_planes = ctx->src_fmt->num_planes;
333 } else {
334 mfc_err("Format could not be read\n");
335 mfc_debug(2, "%s-- with error\n", __func__);
336 return -EINVAL;
337 }
338 mfc_debug_leave();
339 return 0;
340}
341
342/* Try format */
343static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
344{
345 struct s5p_mfc_fmt *fmt;
346
347 if (f->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
348 mfc_err("This node supports decoding only\n");
349 return -EINVAL;
350 }
351 fmt = find_format(f, MFC_FMT_DEC);
352 if (!fmt) {
353 mfc_err("Unsupported format\n");
354 return -EINVAL;
355 }
356 if (fmt->type != MFC_FMT_DEC) {
357 mfc_err("\n");
358 return -EINVAL;
359 }
360 return 0;
361}
362
363/* Set format */
364static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
365{
366 struct s5p_mfc_dev *dev = video_drvdata(file);
367 struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
368 int ret = 0;
369 struct s5p_mfc_fmt *fmt;
370 struct v4l2_pix_format_mplane *pix_mp;
371
372 mfc_debug_enter();
373 ret = vidioc_try_fmt(file, priv, f);
374 pix_mp = &f->fmt.pix_mp;
375 if (ret)
376 return ret;
377 if (ctx->vq_src.streaming || ctx->vq_dst.streaming) {
378 v4l2_err(&dev->v4l2_dev, "%s queue busy\n", __func__);
379 ret = -EBUSY;
380 goto out;
381 }
382 fmt = find_format(f, MFC_FMT_DEC);
383 if (!fmt || fmt->codec_mode == S5P_FIMV_CODEC_NONE) {
384 mfc_err("Unknown codec\n");
385 ret = -EINVAL;
386 goto out;
387 }
388 if (fmt->type != MFC_FMT_DEC) {
389 mfc_err("Wrong format selected, you should choose "
390 "format for decoding\n");
391 ret = -EINVAL;
392 goto out;
393 }
394 ctx->src_fmt = fmt;
395 ctx->codec_mode = fmt->codec_mode;
396 mfc_debug(2, "The codec number is: %d\n", ctx->codec_mode);
397 pix_mp->height = 0;
398 pix_mp->width = 0;
399 if (pix_mp->plane_fmt[0].sizeimage)
400 ctx->dec_src_buf_size = pix_mp->plane_fmt[0].sizeimage;
401 else
402 pix_mp->plane_fmt[0].sizeimage = ctx->dec_src_buf_size =
403 DEF_CPB_SIZE;
404 pix_mp->plane_fmt[0].bytesperline = 0;
405 ctx->state = MFCINST_INIT;
406out:
407 mfc_debug_leave();
408 return ret;
409}
410
411/* Reqeust buffers */
412static int vidioc_reqbufs(struct file *file, void *priv,
413 struct v4l2_requestbuffers *reqbufs)
414{
415 struct s5p_mfc_dev *dev = video_drvdata(file);
416 struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
417 int ret = 0;
418 unsigned long flags;
419
420 if (reqbufs->memory != V4L2_MEMORY_MMAP) {
421 mfc_err("Only V4L2_MEMORY_MAP is supported\n");
422 return -EINVAL;
423 }
424 if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
425 /* Can only request buffers after an instance has been opened.*/
426 if (ctx->state == MFCINST_INIT) {
427 ctx->src_bufs_cnt = 0;
428 if (reqbufs->count == 0) {
429 mfc_debug(2, "Freeing buffers\n");
430 s5p_mfc_clock_on();
431 ret = vb2_reqbufs(&ctx->vq_src, reqbufs);
432 s5p_mfc_clock_off();
433 return ret;
434 }
435 /* Decoding */
436 if (ctx->output_state != QUEUE_FREE) {
437 mfc_err("Bufs have already been requested\n");
438 return -EINVAL;
439 }
440 s5p_mfc_clock_on();
441 ret = vb2_reqbufs(&ctx->vq_src, reqbufs);
442 s5p_mfc_clock_off();
443 if (ret) {
444 mfc_err("vb2_reqbufs on output failed\n");
445 return ret;
446 }
447 mfc_debug(2, "vb2_reqbufs: %d\n", ret);
448 ctx->output_state = QUEUE_BUFS_REQUESTED;
449 }
450 } else if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
451 ctx->dst_bufs_cnt = 0;
452 if (reqbufs->count == 0) {
453 mfc_debug(2, "Freeing buffers\n");
454 s5p_mfc_clock_on();
455 ret = vb2_reqbufs(&ctx->vq_dst, reqbufs);
456 s5p_mfc_clock_off();
457 return ret;
458 }
459 if (ctx->capture_state != QUEUE_FREE) {
460 mfc_err("Bufs have already been requested\n");
461 return -EINVAL;
462 }
463 ctx->capture_state = QUEUE_BUFS_REQUESTED;
464 s5p_mfc_clock_on();
465 ret = vb2_reqbufs(&ctx->vq_dst, reqbufs);
466 s5p_mfc_clock_off();
467 if (ret) {
468 mfc_err("vb2_reqbufs on capture failed\n");
469 return ret;
470 }
471 if (reqbufs->count < ctx->dpb_count) {
472 mfc_err("Not enough buffers allocated\n");
473 reqbufs->count = 0;
474 s5p_mfc_clock_on();
475 ret = vb2_reqbufs(&ctx->vq_dst, reqbufs);
476 s5p_mfc_clock_off();
477 return -ENOMEM;
478 }
479 ctx->total_dpb_count = reqbufs->count;
480 ret = s5p_mfc_alloc_codec_buffers(ctx);
481 if (ret) {
482 mfc_err("Failed to allocate decoding buffers\n");
483 reqbufs->count = 0;
484 s5p_mfc_clock_on();
485 ret = vb2_reqbufs(&ctx->vq_dst, reqbufs);
486 s5p_mfc_clock_off();
487 return -ENOMEM;
488 }
489 if (ctx->dst_bufs_cnt == ctx->total_dpb_count) {
490 ctx->capture_state = QUEUE_BUFS_MMAPED;
491 } else {
492 mfc_err("Not all buffers passed to buf_init\n");
493 reqbufs->count = 0;
494 s5p_mfc_clock_on();
495 ret = vb2_reqbufs(&ctx->vq_dst, reqbufs);
496 s5p_mfc_release_codec_buffers(ctx);
497 s5p_mfc_clock_off();
498 return -ENOMEM;
499 }
500 if (s5p_mfc_ctx_ready(ctx)) {
501 spin_lock_irqsave(&dev->condlock, flags);
502 set_bit(ctx->num, &dev->ctx_work_bits);
503 spin_unlock_irqrestore(&dev->condlock, flags);
504 }
505 s5p_mfc_try_run(dev);
506 s5p_mfc_wait_for_done_ctx(ctx,
507 S5P_FIMV_R2H_CMD_INIT_BUFFERS_RET, 0);
508 }
509 return ret;
510}
511
512/* Query buffer */
513static int vidioc_querybuf(struct file *file, void *priv,
514 struct v4l2_buffer *buf)
515{
516 struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
517 int ret;
518 int i;
519
520 if (buf->memory != V4L2_MEMORY_MMAP) {
521 mfc_err("Only mmaped buffers can be used\n");
522 return -EINVAL;
523 }
524 mfc_debug(2, "State: %d, buf->type: %d\n", ctx->state, buf->type);
525 if (ctx->state == MFCINST_INIT &&
526 buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
527 ret = vb2_querybuf(&ctx->vq_src, buf);
528 } else if (ctx->state == MFCINST_RUNNING &&
529 buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
530 ret = vb2_querybuf(&ctx->vq_dst, buf);
531 for (i = 0; i < buf->length; i++)
532 buf->m.planes[i].m.mem_offset += DST_QUEUE_OFF_BASE;
533 } else {
534 mfc_err("vidioc_querybuf called in an inappropriate state\n");
535 ret = -EINVAL;
536 }
537 mfc_debug_leave();
538 return ret;
539}
540
541/* Queue a buffer */
542static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
543{
544 struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
545
546 if (ctx->state == MFCINST_ERROR) {
547 mfc_err("Call on QBUF after unrecoverable error\n");
548 return -EIO;
549 }
550 if (buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
551 return vb2_qbuf(&ctx->vq_src, buf);
552 else if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
553 return vb2_qbuf(&ctx->vq_dst, buf);
554 return -EINVAL;
555}
556
557/* Dequeue a buffer */
558static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
559{
560 struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
561
562 if (ctx->state == MFCINST_ERROR) {
563 mfc_err("Call on DQBUF after unrecoverable error\n");
564 return -EIO;
565 }
566 if (buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
567 return vb2_dqbuf(&ctx->vq_src, buf, file->f_flags & O_NONBLOCK);
568 else if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
569 return vb2_dqbuf(&ctx->vq_dst, buf, file->f_flags & O_NONBLOCK);
570 return -EINVAL;
571}
572
573/* Stream on */
574static int vidioc_streamon(struct file *file, void *priv,
575 enum v4l2_buf_type type)
576{
577 struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
578 struct s5p_mfc_dev *dev = ctx->dev;
579 unsigned long flags;
580 int ret = -EINVAL;
581
582 mfc_debug_enter();
583 if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
584
585 if (ctx->state == MFCINST_INIT) {
586 ctx->dst_bufs_cnt = 0;
587 ctx->src_bufs_cnt = 0;
588 ctx->capture_state = QUEUE_FREE;
589 ctx->output_state = QUEUE_FREE;
590 s5p_mfc_alloc_instance_buffer(ctx);
591 s5p_mfc_alloc_dec_temp_buffers(ctx);
592 spin_lock_irqsave(&dev->condlock, flags);
593 set_bit(ctx->num, &dev->ctx_work_bits);
594 spin_unlock_irqrestore(&dev->condlock, flags);
595 s5p_mfc_clean_ctx_int_flags(ctx);
596 s5p_mfc_try_run(dev);
597
598 if (s5p_mfc_wait_for_done_ctx(ctx,
599 S5P_FIMV_R2H_CMD_OPEN_INSTANCE_RET, 0)) {
600 /* Error or timeout */
601 mfc_err("Error getting instance from hardware\n");
602 s5p_mfc_release_instance_buffer(ctx);
603 s5p_mfc_release_dec_desc_buffer(ctx);
604 return -EIO;
605 }
606 mfc_debug(2, "Got instance number: %d\n", ctx->inst_no);
607 }
608 ret = vb2_streamon(&ctx->vq_src, type);
609 }
610 else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
611 ret = vb2_streamon(&ctx->vq_dst, type);
612 mfc_debug_leave();
613 return ret;
614}
615
616/* Stream off, which equals to a pause */
617static int vidioc_streamoff(struct file *file, void *priv,
618 enum v4l2_buf_type type)
619{
620 struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
621
622 if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
623 return vb2_streamoff(&ctx->vq_src, type);
624 else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
625 return vb2_streamoff(&ctx->vq_dst, type);
626 return -EINVAL;
627}
628
629/* Set controls - v4l2 control framework */
630static int s5p_mfc_dec_s_ctrl(struct v4l2_ctrl *ctrl)
631{
632 struct s5p_mfc_ctx *ctx = ctrl_to_ctx(ctrl);
633
634 switch (ctrl->id) {
635 case V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY:
636 ctx->display_delay = ctrl->val;
637 break;
638 case V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY_ENABLE:
639 ctx->display_delay_enable = ctrl->val;
640 break;
641 case V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER:
642 ctx->loop_filter_mpeg4 = ctrl->val;
643 break;
644 case V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE:
645 ctx->slice_interface = ctrl->val;
646 break;
647 default:
648 mfc_err("Invalid control 0x%08x\n", ctrl->id);
649 return -EINVAL;
650 }
651 return 0;
652}
653
654static int s5p_mfc_dec_g_v_ctrl(struct v4l2_ctrl *ctrl)
655{
656 struct s5p_mfc_ctx *ctx = ctrl_to_ctx(ctrl);
657 struct s5p_mfc_dev *dev = ctx->dev;
658
659 switch (ctrl->id) {
660 case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
661 if (ctx->state >= MFCINST_HEAD_PARSED &&
662 ctx->state < MFCINST_ABORT) {
663 ctrl->val = ctx->dpb_count;
664 break;
665 } else if (ctx->state != MFCINST_INIT) {
666 v4l2_err(&dev->v4l2_dev, "Decoding not initialised\n");
667 return -EINVAL;
668 }
669 /* Should wait for the header to be parsed */
670 s5p_mfc_clean_ctx_int_flags(ctx);
671 s5p_mfc_wait_for_done_ctx(ctx,
672 S5P_FIMV_R2H_CMD_SEQ_DONE_RET, 0);
673 if (ctx->state >= MFCINST_HEAD_PARSED &&
674 ctx->state < MFCINST_ABORT) {
675 ctrl->val = ctx->dpb_count;
676 } else {
677 v4l2_err(&dev->v4l2_dev, "Decoding not initialised\n");
678 return -EINVAL;
679 }
680 break;
681 }
682 return 0;
683}
684
685
686static const struct v4l2_ctrl_ops s5p_mfc_dec_ctrl_ops = {
687 .s_ctrl = s5p_mfc_dec_s_ctrl,
688 .g_volatile_ctrl = s5p_mfc_dec_g_v_ctrl,
689};
690
691/* Get cropping information */
692static int vidioc_g_crop(struct file *file, void *priv,
693 struct v4l2_crop *cr)
694{
695 struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
696 u32 left, right, top, bottom;
697
698 if (ctx->state != MFCINST_HEAD_PARSED &&
699 ctx->state != MFCINST_RUNNING && ctx->state != MFCINST_FINISHING
700 && ctx->state != MFCINST_FINISHED) {
701 mfc_err("Cannont set crop\n");
702 return -EINVAL;
703 }
704 if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_H264) {
705 left = s5p_mfc_read_shm(ctx, CROP_INFO_H);
706 right = left >> S5P_FIMV_SHARED_CROP_RIGHT_SHIFT;
707 left = left & S5P_FIMV_SHARED_CROP_LEFT_MASK;
708 top = s5p_mfc_read_shm(ctx, CROP_INFO_V);
709 bottom = top >> S5P_FIMV_SHARED_CROP_BOTTOM_SHIFT;
710 top = top & S5P_FIMV_SHARED_CROP_TOP_MASK;
711 cr->c.left = left;
712 cr->c.top = top;
713 cr->c.width = ctx->img_width - left - right;
714 cr->c.height = ctx->img_height - top - bottom;
715 mfc_debug(2, "Cropping info [h264]: l=%d t=%d "
716 "w=%d h=%d (r=%d b=%d fw=%d fh=%d\n", left, top,
717 cr->c.width, cr->c.height, right, bottom,
718 ctx->buf_width, ctx->buf_height);
719 } else {
720 cr->c.left = 0;
721 cr->c.top = 0;
722 cr->c.width = ctx->img_width;
723 cr->c.height = ctx->img_height;
724 mfc_debug(2, "Cropping info: w=%d h=%d fw=%d "
725 "fh=%d\n", cr->c.width, cr->c.height, ctx->buf_width,
726 ctx->buf_height);
727 }
728 return 0;
729}
730
731/* v4l2_ioctl_ops */
732static const struct v4l2_ioctl_ops s5p_mfc_dec_ioctl_ops = {
733 .vidioc_querycap = vidioc_querycap,
734 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
735 .vidioc_enum_fmt_vid_cap_mplane = vidioc_enum_fmt_vid_cap_mplane,
736 .vidioc_enum_fmt_vid_out = vidioc_enum_fmt_vid_out,
737 .vidioc_enum_fmt_vid_out_mplane = vidioc_enum_fmt_vid_out_mplane,
738 .vidioc_g_fmt_vid_cap_mplane = vidioc_g_fmt,
739 .vidioc_g_fmt_vid_out_mplane = vidioc_g_fmt,
740 .vidioc_try_fmt_vid_cap_mplane = vidioc_try_fmt,
741 .vidioc_try_fmt_vid_out_mplane = vidioc_try_fmt,
742 .vidioc_s_fmt_vid_cap_mplane = vidioc_s_fmt,
743 .vidioc_s_fmt_vid_out_mplane = vidioc_s_fmt,
744 .vidioc_reqbufs = vidioc_reqbufs,
745 .vidioc_querybuf = vidioc_querybuf,
746 .vidioc_qbuf = vidioc_qbuf,
747 .vidioc_dqbuf = vidioc_dqbuf,
748 .vidioc_streamon = vidioc_streamon,
749 .vidioc_streamoff = vidioc_streamoff,
750 .vidioc_g_crop = vidioc_g_crop,
751};
752
753static int s5p_mfc_queue_setup(struct vb2_queue *vq,
754 const struct v4l2_format *fmt, unsigned int *buf_count,
755 unsigned int *plane_count, unsigned int psize[],
756 void *allocators[])
757{
758 struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv);
759
760 /* Video output for decoding (source)
761 * this can be set after getting an instance */
762 if (ctx->state == MFCINST_INIT &&
763 vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
764 /* A single plane is required for input */
765 *plane_count = 1;
766 if (*buf_count < 1)
767 *buf_count = 1;
768 if (*buf_count > MFC_MAX_BUFFERS)
769 *buf_count = MFC_MAX_BUFFERS;
770 /* Video capture for decoding (destination)
771 * this can be set after the header was parsed */
772 } else if (ctx->state == MFCINST_HEAD_PARSED &&
773 vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
774 /* Output plane count is 2 - one for Y and one for CbCr */
775 *plane_count = 2;
776 /* Setup buffer count */
777 if (*buf_count < ctx->dpb_count)
778 *buf_count = ctx->dpb_count;
779 if (*buf_count > ctx->dpb_count + MFC_MAX_EXTRA_DPB)
780 *buf_count = ctx->dpb_count + MFC_MAX_EXTRA_DPB;
781 if (*buf_count > MFC_MAX_BUFFERS)
782 *buf_count = MFC_MAX_BUFFERS;
783 } else {
784 mfc_err("State seems invalid. State = %d, vq->type = %d\n",
785 ctx->state, vq->type);
786 return -EINVAL;
787 }
788 mfc_debug(2, "Buffer count=%d, plane count=%d\n",
789 *buf_count, *plane_count);
790 if (ctx->state == MFCINST_HEAD_PARSED &&
791 vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
792 psize[0] = ctx->luma_size;
793 psize[1] = ctx->chroma_size;
794 allocators[0] = ctx->dev->alloc_ctx[MFC_BANK2_ALLOC_CTX];
795 allocators[1] = ctx->dev->alloc_ctx[MFC_BANK1_ALLOC_CTX];
796 } else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE &&
797 ctx->state == MFCINST_INIT) {
798 psize[0] = ctx->dec_src_buf_size;
799 allocators[0] = ctx->dev->alloc_ctx[MFC_BANK1_ALLOC_CTX];
800 } else {
801 mfc_err("This video node is dedicated to decoding. Decoding not initalised\n");
802 return -EINVAL;
803 }
804 return 0;
805}
806
807static void s5p_mfc_unlock(struct vb2_queue *q)
808{
809 struct s5p_mfc_ctx *ctx = fh_to_ctx(q->drv_priv);
810 struct s5p_mfc_dev *dev = ctx->dev;
811
812 mutex_unlock(&dev->mfc_mutex);
813}
814
815static void s5p_mfc_lock(struct vb2_queue *q)
816{
817 struct s5p_mfc_ctx *ctx = fh_to_ctx(q->drv_priv);
818 struct s5p_mfc_dev *dev = ctx->dev;
819
820 mutex_lock(&dev->mfc_mutex);
821}
822
823static int s5p_mfc_buf_init(struct vb2_buffer *vb)
824{
825 struct vb2_queue *vq = vb->vb2_queue;
826 struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv);
827 unsigned int i;
828
829 if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
830 if (ctx->capture_state == QUEUE_BUFS_MMAPED)
831 return 0;
832 for (i = 0; i <= ctx->src_fmt->num_planes ; i++) {
833 if (IS_ERR_OR_NULL(ERR_PTR(
834 vb2_dma_contig_plane_dma_addr(vb, i)))) {
835 mfc_err("Plane mem not allocated\n");
836 return -EINVAL;
837 }
838 }
839 if (vb2_plane_size(vb, 0) < ctx->luma_size ||
840 vb2_plane_size(vb, 1) < ctx->chroma_size) {
841 mfc_err("Plane buffer (CAPTURE) is too small\n");
842 return -EINVAL;
843 }
844 i = vb->v4l2_buf.index;
845 ctx->dst_bufs[i].b = vb;
846 ctx->dst_bufs[i].cookie.raw.luma =
847 vb2_dma_contig_plane_dma_addr(vb, 0);
848 ctx->dst_bufs[i].cookie.raw.chroma =
849 vb2_dma_contig_plane_dma_addr(vb, 1);
850 ctx->dst_bufs_cnt++;
851 } else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
852 if (IS_ERR_OR_NULL(ERR_PTR(
853 vb2_dma_contig_plane_dma_addr(vb, 0)))) {
854 mfc_err("Plane memory not allocated\n");
855 return -EINVAL;
856 }
857 if (vb2_plane_size(vb, 0) < ctx->dec_src_buf_size) {
858 mfc_err("Plane buffer (OUTPUT) is too small\n");
859 return -EINVAL;
860 }
861
862 i = vb->v4l2_buf.index;
863 ctx->src_bufs[i].b = vb;
864 ctx->src_bufs[i].cookie.stream =
865 vb2_dma_contig_plane_dma_addr(vb, 0);
866 ctx->src_bufs_cnt++;
867 } else {
868 mfc_err("s5p_mfc_buf_init: unknown queue type\n");
869 return -EINVAL;
870 }
871 return 0;
872}
873
874static int s5p_mfc_start_streaming(struct vb2_queue *q, unsigned int count)
875{
876 struct s5p_mfc_ctx *ctx = fh_to_ctx(q->drv_priv);
877 struct s5p_mfc_dev *dev = ctx->dev;
878 unsigned long flags;
879
880 v4l2_ctrl_handler_setup(&ctx->ctrl_handler);
881 if (ctx->state == MFCINST_FINISHING ||
882 ctx->state == MFCINST_FINISHED)
883 ctx->state = MFCINST_RUNNING;
884 /* If context is ready then dev = work->data;schedule it to run */
885 if (s5p_mfc_ctx_ready(ctx)) {
886 spin_lock_irqsave(&dev->condlock, flags);
887 set_bit(ctx->num, &dev->ctx_work_bits);
888 spin_unlock_irqrestore(&dev->condlock, flags);
889 }
890 s5p_mfc_try_run(dev);
891 return 0;
892}
893
894static int s5p_mfc_stop_streaming(struct vb2_queue *q)
895{
896 unsigned long flags;
897 struct s5p_mfc_ctx *ctx = fh_to_ctx(q->drv_priv);
898 struct s5p_mfc_dev *dev = ctx->dev;
899 int aborted = 0;
900
901 if ((ctx->state == MFCINST_FINISHING ||
902 ctx->state == MFCINST_RUNNING) &&
903 dev->curr_ctx == ctx->num && dev->hw_lock) {
904 ctx->state = MFCINST_ABORT;
905 s5p_mfc_wait_for_done_ctx(ctx,
906 S5P_FIMV_R2H_CMD_FRAME_DONE_RET, 0);
907 aborted = 1;
908 }
909 spin_lock_irqsave(&dev->irqlock, flags);
910 if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
911 s5p_mfc_cleanup_queue(&ctx->dst_queue, &ctx->vq_dst);
912 INIT_LIST_HEAD(&ctx->dst_queue);
913 ctx->dst_queue_cnt = 0;
914 ctx->dpb_flush_flag = 1;
915 ctx->dec_dst_flag = 0;
916 }
917 if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
918 s5p_mfc_cleanup_queue(&ctx->src_queue, &ctx->vq_src);
919 INIT_LIST_HEAD(&ctx->src_queue);
920 ctx->src_queue_cnt = 0;
921 }
922 if (aborted)
923 ctx->state = MFCINST_RUNNING;
924 spin_unlock_irqrestore(&dev->irqlock, flags);
925 return 0;
926}
927
928
929static void s5p_mfc_buf_queue(struct vb2_buffer *vb)
930{
931 struct vb2_queue *vq = vb->vb2_queue;
932 struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv);
933 struct s5p_mfc_dev *dev = ctx->dev;
934 unsigned long flags;
935 struct s5p_mfc_buf *mfc_buf;
936
937 if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
938 mfc_buf = &ctx->src_bufs[vb->v4l2_buf.index];
939 mfc_buf->used = 0;
940 spin_lock_irqsave(&dev->irqlock, flags);
941 list_add_tail(&mfc_buf->list, &ctx->src_queue);
942 ctx->src_queue_cnt++;
943 spin_unlock_irqrestore(&dev->irqlock, flags);
944 } else if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
945 mfc_buf = &ctx->dst_bufs[vb->v4l2_buf.index];
946 mfc_buf->used = 0;
947 /* Mark destination as available for use by MFC */
948 spin_lock_irqsave(&dev->irqlock, flags);
949 set_bit(vb->v4l2_buf.index, &ctx->dec_dst_flag);
950 list_add_tail(&mfc_buf->list, &ctx->dst_queue);
951 ctx->dst_queue_cnt++;
952 spin_unlock_irqrestore(&dev->irqlock, flags);
953 } else {
954 mfc_err("Unsupported buffer type (%d)\n", vq->type);
955 }
956 if (s5p_mfc_ctx_ready(ctx)) {
957 spin_lock_irqsave(&dev->condlock, flags);
958 set_bit(ctx->num, &dev->ctx_work_bits);
959 spin_unlock_irqrestore(&dev->condlock, flags);
960 }
961 s5p_mfc_try_run(dev);
962}
963
964static struct vb2_ops s5p_mfc_dec_qops = {
965 .queue_setup = s5p_mfc_queue_setup,
966 .wait_prepare = s5p_mfc_unlock,
967 .wait_finish = s5p_mfc_lock,
968 .buf_init = s5p_mfc_buf_init,
969 .start_streaming = s5p_mfc_start_streaming,
970 .stop_streaming = s5p_mfc_stop_streaming,
971 .buf_queue = s5p_mfc_buf_queue,
972};
973
974struct s5p_mfc_codec_ops *get_dec_codec_ops(void)
975{
976 return &decoder_codec_ops;
977}
978
979struct vb2_ops *get_dec_queue_ops(void)
980{
981 return &s5p_mfc_dec_qops;
982}
983
984const struct v4l2_ioctl_ops *get_dec_v4l2_ioctl_ops(void)
985{
986 return &s5p_mfc_dec_ioctl_ops;
987}
988
989#define IS_MFC51_PRIV(x) ((V4L2_CTRL_ID2CLASS(x) == V4L2_CTRL_CLASS_MPEG) \
990 && V4L2_CTRL_DRIVER_PRIV(x))
991
992int s5p_mfc_dec_ctrls_setup(struct s5p_mfc_ctx *ctx)
993{
994 struct v4l2_ctrl_config cfg;
995 int i;
996
997 v4l2_ctrl_handler_init(&ctx->ctrl_handler, NUM_CTRLS);
998 if (ctx->ctrl_handler.error) {
999 mfc_err("v4l2_ctrl_handler_init failed\n");
1000 return ctx->ctrl_handler.error;
1001 }
1002
1003 for (i = 0; i < NUM_CTRLS; i++) {
1004 if (IS_MFC51_PRIV(controls[i].id)) {
1005 memset(&cfg, 0, sizeof(struct v4l2_ctrl_config));
1006 cfg.ops = &s5p_mfc_dec_ctrl_ops;
1007 cfg.id = controls[i].id;
1008 cfg.min = controls[i].minimum;
1009 cfg.max = controls[i].maximum;
1010 cfg.def = controls[i].default_value;
1011 cfg.name = controls[i].name;
1012 cfg.type = controls[i].type;
1013
1014 cfg.step = controls[i].step;
1015 cfg.menu_skip_mask = 0;
1016
1017 ctx->ctrls[i] = v4l2_ctrl_new_custom(&ctx->ctrl_handler,
1018 &cfg, NULL);
1019 } else {
1020 ctx->ctrls[i] = v4l2_ctrl_new_std(&ctx->ctrl_handler,
1021 &s5p_mfc_dec_ctrl_ops,
1022 controls[i].id, controls[i].minimum,
1023 controls[i].maximum, controls[i].step,
1024 controls[i].default_value);
1025 }
1026 if (ctx->ctrl_handler.error) {
1027 mfc_err("Adding control (%d) failed\n", i);
1028 return ctx->ctrl_handler.error;
1029 }
1030 if (controls[i].is_volatile && ctx->ctrls[i])
1031 ctx->ctrls[i]->flags |= V4L2_CTRL_FLAG_VOLATILE;
1032 }
1033 return 0;
1034}
1035
1036void s5p_mfc_dec_ctrls_delete(struct s5p_mfc_ctx *ctx)
1037{
1038 int i;
1039
1040 v4l2_ctrl_handler_free(&ctx->ctrl_handler);
1041 for (i = 0; i < NUM_CTRLS; i++)
1042 ctx->ctrls[i] = NULL;
1043}
1044
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_dec.h b/drivers/media/video/s5p-mfc/s5p_mfc_dec.h
deleted file mode 100644
index fb8b215db0e7..000000000000
--- a/drivers/media/video/s5p-mfc/s5p_mfc_dec.h
+++ /dev/null
@@ -1,23 +0,0 @@
1/*
2 * linux/drivers/media/video/s5p-mfc/s5p_mfc_dec.h
3 *
4 * Copyright (C) 2011 Samsung Electronics Co., Ltd.
5 * http://www.samsung.com/
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#ifndef S5P_MFC_DEC_H_
14#define S5P_MFC_DEC_H_
15
16struct s5p_mfc_codec_ops *get_dec_codec_ops(void);
17struct vb2_ops *get_dec_queue_ops(void);
18const struct v4l2_ioctl_ops *get_dec_v4l2_ioctl_ops(void);
19struct s5p_mfc_fmt *get_dec_def_fmt(bool src);
20int s5p_mfc_dec_ctrls_setup(struct s5p_mfc_ctx *ctx);
21void s5p_mfc_dec_ctrls_delete(struct s5p_mfc_ctx *ctx);
22
23#endif /* S5P_MFC_DEC_H_ */
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_enc.c b/drivers/media/video/s5p-mfc/s5p_mfc_enc.c
deleted file mode 100644
index aa1c244cf66e..000000000000
--- a/drivers/media/video/s5p-mfc/s5p_mfc_enc.c
+++ /dev/null
@@ -1,1834 +0,0 @@
1/*
2 * linux/drivers/media/video/s5p-mfc/s5p_mfc_enc.c
3 *
4 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
5 * http://www.samsung.com/
6 *
7 * Jeongtae Park <jtp.park@samsung.com>
8 * Kamil Debski <k.debski@samsung.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 */
15
16#include <linux/clk.h>
17#include <linux/interrupt.h>
18#include <linux/io.h>
19#include <linux/module.h>
20#include <linux/platform_device.h>
21#include <linux/sched.h>
22#include <linux/version.h>
23#include <linux/videodev2.h>
24#include <linux/workqueue.h>
25#include <media/v4l2-ctrls.h>
26#include <media/videobuf2-core.h>
27#include "regs-mfc.h"
28#include "s5p_mfc_common.h"
29#include "s5p_mfc_debug.h"
30#include "s5p_mfc_enc.h"
31#include "s5p_mfc_intr.h"
32#include "s5p_mfc_opr.h"
33
34static struct s5p_mfc_fmt formats[] = {
35 {
36 .name = "4:2:0 2 Planes 64x32 Tiles",
37 .fourcc = V4L2_PIX_FMT_NV12MT,
38 .codec_mode = S5P_FIMV_CODEC_NONE,
39 .type = MFC_FMT_RAW,
40 .num_planes = 2,
41 },
42 {
43 .name = "4:2:0 2 Planes",
44 .fourcc = V4L2_PIX_FMT_NV12M,
45 .codec_mode = S5P_FIMV_CODEC_NONE,
46 .type = MFC_FMT_RAW,
47 .num_planes = 2,
48 },
49 {
50 .name = "H264 Encoded Stream",
51 .fourcc = V4L2_PIX_FMT_H264,
52 .codec_mode = S5P_FIMV_CODEC_H264_ENC,
53 .type = MFC_FMT_ENC,
54 .num_planes = 1,
55 },
56 {
57 .name = "MPEG4 Encoded Stream",
58 .fourcc = V4L2_PIX_FMT_MPEG4,
59 .codec_mode = S5P_FIMV_CODEC_MPEG4_ENC,
60 .type = MFC_FMT_ENC,
61 .num_planes = 1,
62 },
63 {
64 .name = "H263 Encoded Stream",
65 .fourcc = V4L2_PIX_FMT_H263,
66 .codec_mode = S5P_FIMV_CODEC_H263_ENC,
67 .type = MFC_FMT_ENC,
68 .num_planes = 1,
69 },
70};
71
72#define NUM_FORMATS ARRAY_SIZE(formats)
73static struct s5p_mfc_fmt *find_format(struct v4l2_format *f, unsigned int t)
74{
75 unsigned int i;
76
77 for (i = 0; i < NUM_FORMATS; i++) {
78 if (formats[i].fourcc == f->fmt.pix_mp.pixelformat &&
79 formats[i].type == t)
80 return &formats[i];
81 }
82 return NULL;
83}
84
85static struct mfc_control controls[] = {
86 {
87 .id = V4L2_CID_MPEG_VIDEO_GOP_SIZE,
88 .type = V4L2_CTRL_TYPE_INTEGER,
89 .minimum = 0,
90 .maximum = (1 << 16) - 1,
91 .step = 1,
92 .default_value = 0,
93 },
94 {
95 .id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE,
96 .type = V4L2_CTRL_TYPE_MENU,
97 .minimum = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE,
98 .maximum = V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES,
99 .default_value = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE,
100 .menu_skip_mask = 0,
101 },
102 {
103 .id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB,
104 .type = V4L2_CTRL_TYPE_INTEGER,
105 .minimum = 1,
106 .maximum = (1 << 16) - 1,
107 .step = 1,
108 .default_value = 1,
109 },
110 {
111 .id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES,
112 .type = V4L2_CTRL_TYPE_INTEGER,
113 .minimum = 1900,
114 .maximum = (1 << 30) - 1,
115 .step = 1,
116 .default_value = 1900,
117 },
118 {
119 .id = V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB,
120 .type = V4L2_CTRL_TYPE_INTEGER,
121 .minimum = 0,
122 .maximum = (1 << 16) - 1,
123 .step = 1,
124 .default_value = 0,
125 },
126 {
127 .id = V4L2_CID_MPEG_MFC51_VIDEO_PADDING,
128 .type = V4L2_CTRL_TYPE_BOOLEAN,
129 .name = "Padding Control Enable",
130 .minimum = 0,
131 .maximum = 1,
132 .step = 1,
133 .default_value = 0,
134 },
135 {
136 .id = V4L2_CID_MPEG_MFC51_VIDEO_PADDING_YUV,
137 .type = V4L2_CTRL_TYPE_INTEGER,
138 .name = "Padding Color YUV Value",
139 .minimum = 0,
140 .maximum = (1 << 25) - 1,
141 .step = 1,
142 .default_value = 0,
143 },
144 {
145 .id = V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE,
146 .type = V4L2_CTRL_TYPE_BOOLEAN,
147 .minimum = 0,
148 .maximum = 1,
149 .step = 1,
150 .default_value = 0,
151 },
152 {
153 .id = V4L2_CID_MPEG_VIDEO_BITRATE,
154 .type = V4L2_CTRL_TYPE_INTEGER,
155 .minimum = 1,
156 .maximum = (1 << 30) - 1,
157 .step = 1,
158 .default_value = 1,
159 },
160 {
161 .id = V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF,
162 .type = V4L2_CTRL_TYPE_INTEGER,
163 .name = "Rate Control Reaction Coeff.",
164 .minimum = 1,
165 .maximum = (1 << 16) - 1,
166 .step = 1,
167 .default_value = 1,
168 },
169 {
170 .id = V4L2_CID_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE,
171 .type = V4L2_CTRL_TYPE_MENU,
172 .name = "Force frame type",
173 .minimum = V4L2_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE_DISABLED,
174 .maximum = V4L2_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE_NOT_CODED,
175 .default_value = V4L2_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE_DISABLED,
176 .menu_skip_mask = 0,
177 },
178 {
179 .id = V4L2_CID_MPEG_VIDEO_VBV_SIZE,
180 .type = V4L2_CTRL_TYPE_INTEGER,
181 .minimum = 0,
182 .maximum = (1 << 16) - 1,
183 .step = 1,
184 .default_value = 0,
185 },
186 {
187 .id = V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE,
188 .type = V4L2_CTRL_TYPE_INTEGER,
189 .minimum = 0,
190 .maximum = (1 << 16) - 1,
191 .step = 1,
192 .default_value = 0,
193 },
194 {
195 .id = V4L2_CID_MPEG_VIDEO_HEADER_MODE,
196 .type = V4L2_CTRL_TYPE_MENU,
197 .minimum = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE,
198 .maximum = V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME,
199 .default_value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE,
200 .menu_skip_mask = 0,
201 },
202 {
203 .id = V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE,
204 .type = V4L2_CTRL_TYPE_MENU,
205 .name = "Frame Skip Enable",
206 .minimum = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_DISABLED,
207 .maximum = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT,
208 .menu_skip_mask = 0,
209 .default_value = V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_DISABLED,
210 },
211 {
212 .id = V4L2_CID_MPEG_MFC51_VIDEO_RC_FIXED_TARGET_BIT,
213 .type = V4L2_CTRL_TYPE_BOOLEAN,
214 .name = "Fixed Target Bit Enable",
215 .minimum = 0,
216 .maximum = 1,
217 .default_value = 0,
218 .menu_skip_mask = 0,
219 },
220 {
221 .id = V4L2_CID_MPEG_VIDEO_B_FRAMES,
222 .type = V4L2_CTRL_TYPE_INTEGER,
223 .minimum = 0,
224 .maximum = 2,
225 .step = 1,
226 .default_value = 0,
227 },
228 {
229 .id = V4L2_CID_MPEG_VIDEO_H264_PROFILE,
230 .type = V4L2_CTRL_TYPE_MENU,
231 .minimum = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE,
232 .maximum = V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH,
233 .default_value = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE,
234 .menu_skip_mask = ~(
235 (1 << V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) |
236 (1 << V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) |
237 (1 << V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)
238 ),
239 },
240 {
241 .id = V4L2_CID_MPEG_VIDEO_H264_LEVEL,
242 .type = V4L2_CTRL_TYPE_MENU,
243 .minimum = V4L2_MPEG_VIDEO_H264_LEVEL_1_0,
244 .maximum = V4L2_MPEG_VIDEO_H264_LEVEL_4_0,
245 .default_value = V4L2_MPEG_VIDEO_H264_LEVEL_1_0,
246 },
247 {
248 .id = V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL,
249 .type = V4L2_CTRL_TYPE_MENU,
250 .minimum = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0,
251 .maximum = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5,
252 .default_value = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0,
253 .menu_skip_mask = 0,
254 },
255 {
256 .id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE,
257 .type = V4L2_CTRL_TYPE_MENU,
258 .minimum = V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED,
259 .maximum = V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY,
260 .default_value = V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED,
261 .menu_skip_mask = 0,
262 },
263 {
264 .id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA,
265 .type = V4L2_CTRL_TYPE_INTEGER,
266 .minimum = -6,
267 .maximum = 6,
268 .step = 1,
269 .default_value = 0,
270 },
271 {
272 .id = V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA,
273 .type = V4L2_CTRL_TYPE_INTEGER,
274 .minimum = -6,
275 .maximum = 6,
276 .step = 1,
277 .default_value = 0,
278 },
279 {
280 .id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE,
281 .type = V4L2_CTRL_TYPE_MENU,
282 .minimum = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC,
283 .maximum = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC,
284 .default_value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC,
285 .menu_skip_mask = 0,
286 },
287 {
288 .id = V4L2_CID_MPEG_MFC51_VIDEO_H264_NUM_REF_PIC_FOR_P,
289 .type = V4L2_CTRL_TYPE_INTEGER,
290 .name = "The Number of Ref. Pic for P",
291 .minimum = 1,
292 .maximum = 2,
293 .step = 1,
294 .default_value = 1,
295 },
296 {
297 .id = V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM,
298 .type = V4L2_CTRL_TYPE_BOOLEAN,
299 .minimum = 0,
300 .maximum = 1,
301 .step = 1,
302 .default_value = 0,
303 },
304 {
305 .id = V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE,
306 .type = V4L2_CTRL_TYPE_BOOLEAN,
307 .minimum = 0,
308 .maximum = 1,
309 .step = 1,
310 .default_value = 0,
311 },
312 {
313 .id = V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP,
314 .type = V4L2_CTRL_TYPE_INTEGER,
315 .minimum = 0,
316 .maximum = 51,
317 .step = 1,
318 .default_value = 1,
319 },
320 {
321 .id = V4L2_CID_MPEG_VIDEO_H264_MIN_QP,
322 .type = V4L2_CTRL_TYPE_INTEGER,
323 .minimum = 0,
324 .maximum = 51,
325 .step = 1,
326 .default_value = 1,
327 },
328 {
329 .id = V4L2_CID_MPEG_VIDEO_H264_MAX_QP,
330 .type = V4L2_CTRL_TYPE_INTEGER,
331 .minimum = 0,
332 .maximum = 51,
333 .step = 1,
334 .default_value = 1,
335 },
336 {
337 .id = V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP,
338 .type = V4L2_CTRL_TYPE_INTEGER,
339 .minimum = 0,
340 .maximum = 51,
341 .step = 1,
342 .default_value = 1,
343 },
344 {
345 .id = V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP,
346 .type = V4L2_CTRL_TYPE_INTEGER,
347 .minimum = 0,
348 .maximum = 51,
349 .step = 1,
350 .default_value = 1,
351 },
352 {
353 .id = V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP,
354 .type = V4L2_CTRL_TYPE_INTEGER,
355 .name = "H263 I-Frame QP value",
356 .minimum = 1,
357 .maximum = 31,
358 .step = 1,
359 .default_value = 1,
360 },
361 {
362 .id = V4L2_CID_MPEG_VIDEO_H263_MIN_QP,
363 .type = V4L2_CTRL_TYPE_INTEGER,
364 .name = "H263 Minimum QP value",
365 .minimum = 1,
366 .maximum = 31,
367 .step = 1,
368 .default_value = 1,
369 },
370 {
371 .id = V4L2_CID_MPEG_VIDEO_H263_MAX_QP,
372 .type = V4L2_CTRL_TYPE_INTEGER,
373 .name = "H263 Maximum QP value",
374 .minimum = 1,
375 .maximum = 31,
376 .step = 1,
377 .default_value = 1,
378 },
379 {
380 .id = V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP,
381 .type = V4L2_CTRL_TYPE_INTEGER,
382 .name = "H263 P frame QP value",
383 .minimum = 1,
384 .maximum = 31,
385 .step = 1,
386 .default_value = 1,
387 },
388 {
389 .id = V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP,
390 .type = V4L2_CTRL_TYPE_INTEGER,
391 .name = "H263 B frame QP value",
392 .minimum = 1,
393 .maximum = 31,
394 .step = 1,
395 .default_value = 1,
396 },
397 {
398 .id = V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP,
399 .type = V4L2_CTRL_TYPE_INTEGER,
400 .name = "MPEG4 I-Frame QP value",
401 .minimum = 1,
402 .maximum = 31,
403 .step = 1,
404 .default_value = 1,
405 },
406 {
407 .id = V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP,
408 .type = V4L2_CTRL_TYPE_INTEGER,
409 .name = "MPEG4 Minimum QP value",
410 .minimum = 1,
411 .maximum = 31,
412 .step = 1,
413 .default_value = 1,
414 },
415 {
416 .id = V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP,
417 .type = V4L2_CTRL_TYPE_INTEGER,
418 .name = "MPEG4 Maximum QP value",
419 .minimum = 0,
420 .maximum = 51,
421 .step = 1,
422 .default_value = 1,
423 },
424 {
425 .id = V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP,
426 .type = V4L2_CTRL_TYPE_INTEGER,
427 .name = "MPEG4 P frame QP value",
428 .minimum = 1,
429 .maximum = 31,
430 .step = 1,
431 .default_value = 1,
432 },
433 {
434 .id = V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP,
435 .type = V4L2_CTRL_TYPE_INTEGER,
436 .name = "MPEG4 B frame QP value",
437 .minimum = 1,
438 .maximum = 31,
439 .step = 1,
440 .default_value = 1,
441 },
442 {
443 .id = V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_DARK,
444 .type = V4L2_CTRL_TYPE_BOOLEAN,
445 .name = "H264 Dark Reg Adaptive RC",
446 .minimum = 0,
447 .maximum = 1,
448 .step = 1,
449 .default_value = 0,
450 },
451 {
452 .id = V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_SMOOTH,
453 .type = V4L2_CTRL_TYPE_BOOLEAN,
454 .name = "H264 Smooth Reg Adaptive RC",
455 .minimum = 0,
456 .maximum = 1,
457 .step = 1,
458 .default_value = 0,
459 },
460 {
461 .id = V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_STATIC,
462 .type = V4L2_CTRL_TYPE_BOOLEAN,
463 .name = "H264 Static Reg Adaptive RC",
464 .minimum = 0,
465 .maximum = 1,
466 .step = 1,
467 .default_value = 0,
468 },
469 {
470 .id = V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_ACTIVITY,
471 .type = V4L2_CTRL_TYPE_BOOLEAN,
472 .name = "H264 Activity Reg Adaptive RC",
473 .minimum = 0,
474 .maximum = 1,
475 .step = 1,
476 .default_value = 0,
477 },
478 {
479 .id = V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE,
480 .type = V4L2_CTRL_TYPE_BOOLEAN,
481 .minimum = 0,
482 .maximum = 1,
483 .step = 1,
484 .default_value = 0,
485 },
486 {
487 .id = V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC,
488 .type = V4L2_CTRL_TYPE_MENU,
489 .minimum = V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_UNSPECIFIED,
490 .maximum = V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_EXTENDED,
491 .default_value = V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_UNSPECIFIED,
492 .menu_skip_mask = 0,
493 },
494 {
495 .id = V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH,
496 .type = V4L2_CTRL_TYPE_INTEGER,
497 .minimum = 0,
498 .maximum = (1 << 16) - 1,
499 .step = 1,
500 .default_value = 0,
501 },
502 {
503 .id = V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT,
504 .type = V4L2_CTRL_TYPE_INTEGER,
505 .minimum = 0,
506 .maximum = (1 << 16) - 1,
507 .step = 1,
508 .default_value = 0,
509 },
510 {
511 .id = V4L2_CID_MPEG_VIDEO_GOP_CLOSURE,
512 .type = V4L2_CTRL_TYPE_BOOLEAN,
513 .minimum = 0,
514 .maximum = 1,
515 .step = 1,
516 .default_value = 1,
517 },
518 {
519 .id = V4L2_CID_MPEG_VIDEO_H264_I_PERIOD,
520 .type = V4L2_CTRL_TYPE_INTEGER,
521 .minimum = 0,
522 .maximum = (1 << 16) - 1,
523 .step = 1,
524 .default_value = 0,
525 },
526 {
527 .id = V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE,
528 .type = V4L2_CTRL_TYPE_MENU,
529 .minimum = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE,
530 .maximum = V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE,
531 .default_value = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE,
532 .menu_skip_mask = 0,
533 },
534 {
535 .id = V4L2_CID_MPEG_VIDEO_MPEG4_QPEL,
536 .type = V4L2_CTRL_TYPE_BOOLEAN,
537 .minimum = 0,
538 .maximum = 1,
539 .step = 1,
540 .default_value = 0,
541 },
542};
543
544#define NUM_CTRLS ARRAY_SIZE(controls)
545static const char * const *mfc51_get_menu(u32 id)
546{
547 static const char * const mfc51_video_frame_skip[] = {
548 "Disabled",
549 "Level Limit",
550 "VBV/CPB Limit",
551 NULL,
552 };
553 static const char * const mfc51_video_force_frame[] = {
554 "Disabled",
555 "I Frame",
556 "Not Coded",
557 NULL,
558 };
559 switch (id) {
560 case V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE:
561 return mfc51_video_frame_skip;
562 case V4L2_CID_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE:
563 return mfc51_video_force_frame;
564 }
565 return NULL;
566}
567
568static int s5p_mfc_ctx_ready(struct s5p_mfc_ctx *ctx)
569{
570 mfc_debug(2, "src=%d, dst=%d, state=%d\n",
571 ctx->src_queue_cnt, ctx->dst_queue_cnt, ctx->state);
572 /* context is ready to make header */
573 if (ctx->state == MFCINST_GOT_INST && ctx->dst_queue_cnt >= 1)
574 return 1;
575 /* context is ready to encode a frame */
576 if (ctx->state == MFCINST_RUNNING &&
577 ctx->src_queue_cnt >= 1 && ctx->dst_queue_cnt >= 1)
578 return 1;
579 /* context is ready to encode remain frames */
580 if (ctx->state == MFCINST_FINISHING &&
581 ctx->src_queue_cnt >= 1 && ctx->dst_queue_cnt >= 1)
582 return 1;
583 mfc_debug(2, "ctx is not ready\n");
584 return 0;
585}
586
587static void cleanup_ref_queue(struct s5p_mfc_ctx *ctx)
588{
589 struct s5p_mfc_buf *mb_entry;
590 unsigned long mb_y_addr, mb_c_addr;
591
592 /* move buffers in ref queue to src queue */
593 while (!list_empty(&ctx->ref_queue)) {
594 mb_entry = list_entry((&ctx->ref_queue)->next,
595 struct s5p_mfc_buf, list);
596 mb_y_addr = vb2_dma_contig_plane_dma_addr(mb_entry->b, 0);
597 mb_c_addr = vb2_dma_contig_plane_dma_addr(mb_entry->b, 1);
598 list_del(&mb_entry->list);
599 ctx->ref_queue_cnt--;
600 list_add_tail(&mb_entry->list, &ctx->src_queue);
601 ctx->src_queue_cnt++;
602 }
603 mfc_debug(2, "enc src count: %d, enc ref count: %d\n",
604 ctx->src_queue_cnt, ctx->ref_queue_cnt);
605 INIT_LIST_HEAD(&ctx->ref_queue);
606 ctx->ref_queue_cnt = 0;
607}
608
609static int enc_pre_seq_start(struct s5p_mfc_ctx *ctx)
610{
611 struct s5p_mfc_dev *dev = ctx->dev;
612 struct s5p_mfc_buf *dst_mb;
613 unsigned long dst_addr;
614 unsigned int dst_size;
615 unsigned long flags;
616
617 spin_lock_irqsave(&dev->irqlock, flags);
618 dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list);
619 dst_addr = vb2_dma_contig_plane_dma_addr(dst_mb->b, 0);
620 dst_size = vb2_plane_size(dst_mb->b, 0);
621 s5p_mfc_set_enc_stream_buffer(ctx, dst_addr, dst_size);
622 spin_unlock_irqrestore(&dev->irqlock, flags);
623 return 0;
624}
625
626static int enc_post_seq_start(struct s5p_mfc_ctx *ctx)
627{
628 struct s5p_mfc_dev *dev = ctx->dev;
629 struct s5p_mfc_enc_params *p = &ctx->enc_params;
630 struct s5p_mfc_buf *dst_mb;
631 unsigned long flags;
632
633 if (p->seq_hdr_mode == V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE) {
634 spin_lock_irqsave(&dev->irqlock, flags);
635 dst_mb = list_entry(ctx->dst_queue.next,
636 struct s5p_mfc_buf, list);
637 list_del(&dst_mb->list);
638 ctx->dst_queue_cnt--;
639 vb2_set_plane_payload(dst_mb->b, 0,
640 s5p_mfc_get_enc_strm_size());
641 vb2_buffer_done(dst_mb->b, VB2_BUF_STATE_DONE);
642 spin_unlock_irqrestore(&dev->irqlock, flags);
643 }
644 ctx->state = MFCINST_RUNNING;
645 if (s5p_mfc_ctx_ready(ctx)) {
646 spin_lock_irqsave(&dev->condlock, flags);
647 set_bit(ctx->num, &dev->ctx_work_bits);
648 spin_unlock_irqrestore(&dev->condlock, flags);
649 }
650 s5p_mfc_try_run(dev);
651 return 0;
652}
653
654static int enc_pre_frame_start(struct s5p_mfc_ctx *ctx)
655{
656 struct s5p_mfc_dev *dev = ctx->dev;
657 struct s5p_mfc_buf *dst_mb;
658 struct s5p_mfc_buf *src_mb;
659 unsigned long flags;
660 unsigned long src_y_addr, src_c_addr, dst_addr;
661 unsigned int dst_size;
662
663 spin_lock_irqsave(&dev->irqlock, flags);
664 src_mb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
665 src_y_addr = vb2_dma_contig_plane_dma_addr(src_mb->b, 0);
666 src_c_addr = vb2_dma_contig_plane_dma_addr(src_mb->b, 1);
667 s5p_mfc_set_enc_frame_buffer(ctx, src_y_addr, src_c_addr);
668 spin_unlock_irqrestore(&dev->irqlock, flags);
669
670 spin_lock_irqsave(&dev->irqlock, flags);
671 dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list);
672 dst_addr = vb2_dma_contig_plane_dma_addr(dst_mb->b, 0);
673 dst_size = vb2_plane_size(dst_mb->b, 0);
674 s5p_mfc_set_enc_stream_buffer(ctx, dst_addr, dst_size);
675 spin_unlock_irqrestore(&dev->irqlock, flags);
676
677 return 0;
678}
679
680static int enc_post_frame_start(struct s5p_mfc_ctx *ctx)
681{
682 struct s5p_mfc_dev *dev = ctx->dev;
683 struct s5p_mfc_buf *mb_entry;
684 unsigned long enc_y_addr, enc_c_addr;
685 unsigned long mb_y_addr, mb_c_addr;
686 int slice_type;
687 unsigned int strm_size;
688 unsigned long flags;
689
690 slice_type = s5p_mfc_get_enc_slice_type();
691 strm_size = s5p_mfc_get_enc_strm_size();
692 mfc_debug(2, "Encoded slice type: %d", slice_type);
693 mfc_debug(2, "Encoded stream size: %d", strm_size);
694 mfc_debug(2, "Display order: %d",
695 mfc_read(dev, S5P_FIMV_ENC_SI_PIC_CNT));
696 spin_lock_irqsave(&dev->irqlock, flags);
697 if (slice_type >= 0) {
698 s5p_mfc_get_enc_frame_buffer(ctx, &enc_y_addr, &enc_c_addr);
699 list_for_each_entry(mb_entry, &ctx->src_queue, list) {
700 mb_y_addr = vb2_dma_contig_plane_dma_addr(mb_entry->b, 0);
701 mb_c_addr = vb2_dma_contig_plane_dma_addr(mb_entry->b, 1);
702 if ((enc_y_addr == mb_y_addr) &&
703 (enc_c_addr == mb_c_addr)) {
704 list_del(&mb_entry->list);
705 ctx->src_queue_cnt--;
706 vb2_buffer_done(mb_entry->b,
707 VB2_BUF_STATE_DONE);
708 break;
709 }
710 }
711 list_for_each_entry(mb_entry, &ctx->ref_queue, list) {
712 mb_y_addr = vb2_dma_contig_plane_dma_addr(mb_entry->b, 0);
713 mb_c_addr = vb2_dma_contig_plane_dma_addr(mb_entry->b, 1);
714 if ((enc_y_addr == mb_y_addr) &&
715 (enc_c_addr == mb_c_addr)) {
716 list_del(&mb_entry->list);
717 ctx->ref_queue_cnt--;
718 vb2_buffer_done(mb_entry->b,
719 VB2_BUF_STATE_DONE);
720 break;
721 }
722 }
723 }
724 if ((ctx->src_queue_cnt > 0) && (ctx->state == MFCINST_RUNNING)) {
725 mb_entry = list_entry(ctx->src_queue.next, struct s5p_mfc_buf,
726 list);
727 if (mb_entry->used) {
728 list_del(&mb_entry->list);
729 ctx->src_queue_cnt--;
730 list_add_tail(&mb_entry->list, &ctx->ref_queue);
731 ctx->ref_queue_cnt++;
732 }
733 mfc_debug(2, "enc src count: %d, enc ref count: %d\n",
734 ctx->src_queue_cnt, ctx->ref_queue_cnt);
735 }
736 if (strm_size > 0) {
737 /* at least one more dest. buffers exist always */
738 mb_entry = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf,
739 list);
740 list_del(&mb_entry->list);
741 ctx->dst_queue_cnt--;
742 switch (slice_type) {
743 case S5P_FIMV_ENC_SI_SLICE_TYPE_I:
744 mb_entry->b->v4l2_buf.flags |= V4L2_BUF_FLAG_KEYFRAME;
745 break;
746 case S5P_FIMV_ENC_SI_SLICE_TYPE_P:
747 mb_entry->b->v4l2_buf.flags |= V4L2_BUF_FLAG_PFRAME;
748 break;
749 case S5P_FIMV_ENC_SI_SLICE_TYPE_B:
750 mb_entry->b->v4l2_buf.flags |= V4L2_BUF_FLAG_BFRAME;
751 break;
752 }
753 vb2_set_plane_payload(mb_entry->b, 0, strm_size);
754 vb2_buffer_done(mb_entry->b, VB2_BUF_STATE_DONE);
755 }
756 spin_unlock_irqrestore(&dev->irqlock, flags);
757 if ((ctx->src_queue_cnt == 0) || (ctx->dst_queue_cnt == 0)) {
758 spin_lock(&dev->condlock);
759 clear_bit(ctx->num, &dev->ctx_work_bits);
760 spin_unlock(&dev->condlock);
761 }
762 return 0;
763}
764
765static struct s5p_mfc_codec_ops encoder_codec_ops = {
766 .pre_seq_start = enc_pre_seq_start,
767 .post_seq_start = enc_post_seq_start,
768 .pre_frame_start = enc_pre_frame_start,
769 .post_frame_start = enc_post_frame_start,
770};
771
772/* Query capabilities of the device */
773static int vidioc_querycap(struct file *file, void *priv,
774 struct v4l2_capability *cap)
775{
776 struct s5p_mfc_dev *dev = video_drvdata(file);
777
778 strncpy(cap->driver, dev->plat_dev->name, sizeof(cap->driver) - 1);
779 strncpy(cap->card, dev->plat_dev->name, sizeof(cap->card) - 1);
780 cap->bus_info[0] = 0;
781 cap->version = KERNEL_VERSION(1, 0, 0);
782 /*
783 * This is only a mem-to-mem video device. The capture and output
784 * device capability flags are left only for backward compatibility
785 * and are scheduled for removal.
786 */
787 cap->capabilities = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING |
788 V4L2_CAP_VIDEO_CAPTURE_MPLANE |
789 V4L2_CAP_VIDEO_OUTPUT_MPLANE;
790 return 0;
791}
792
793static int vidioc_enum_fmt(struct v4l2_fmtdesc *f, bool mplane, bool out)
794{
795 struct s5p_mfc_fmt *fmt;
796 int i, j = 0;
797
798 for (i = 0; i < ARRAY_SIZE(formats); ++i) {
799 if (mplane && formats[i].num_planes == 1)
800 continue;
801 else if (!mplane && formats[i].num_planes > 1)
802 continue;
803 if (out && formats[i].type != MFC_FMT_RAW)
804 continue;
805 else if (!out && formats[i].type != MFC_FMT_ENC)
806 continue;
807 if (j == f->index) {
808 fmt = &formats[i];
809 strlcpy(f->description, fmt->name,
810 sizeof(f->description));
811 f->pixelformat = fmt->fourcc;
812 return 0;
813 }
814 ++j;
815 }
816 return -EINVAL;
817}
818
819static int vidioc_enum_fmt_vid_cap(struct file *file, void *pirv,
820 struct v4l2_fmtdesc *f)
821{
822 return vidioc_enum_fmt(f, false, false);
823}
824
825static int vidioc_enum_fmt_vid_cap_mplane(struct file *file, void *pirv,
826 struct v4l2_fmtdesc *f)
827{
828 return vidioc_enum_fmt(f, true, false);
829}
830
831static int vidioc_enum_fmt_vid_out(struct file *file, void *prov,
832 struct v4l2_fmtdesc *f)
833{
834 return vidioc_enum_fmt(f, false, true);
835}
836
837static int vidioc_enum_fmt_vid_out_mplane(struct file *file, void *prov,
838 struct v4l2_fmtdesc *f)
839{
840 return vidioc_enum_fmt(f, true, true);
841}
842
843static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
844{
845 struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
846 struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
847
848 mfc_debug(2, "f->type = %d ctx->state = %d\n", f->type, ctx->state);
849 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
850 /* This is run on output (encoder dest) */
851 pix_fmt_mp->width = 0;
852 pix_fmt_mp->height = 0;
853 pix_fmt_mp->field = V4L2_FIELD_NONE;
854 pix_fmt_mp->pixelformat = ctx->dst_fmt->fourcc;
855 pix_fmt_mp->num_planes = ctx->dst_fmt->num_planes;
856
857 pix_fmt_mp->plane_fmt[0].bytesperline = ctx->enc_dst_buf_size;
858 pix_fmt_mp->plane_fmt[0].sizeimage = ctx->enc_dst_buf_size;
859 } else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
860 /* This is run on capture (encoder src) */
861 pix_fmt_mp->width = ctx->img_width;
862 pix_fmt_mp->height = ctx->img_height;
863
864 pix_fmt_mp->field = V4L2_FIELD_NONE;
865 pix_fmt_mp->pixelformat = ctx->src_fmt->fourcc;
866 pix_fmt_mp->num_planes = ctx->src_fmt->num_planes;
867
868 pix_fmt_mp->plane_fmt[0].bytesperline = ctx->buf_width;
869 pix_fmt_mp->plane_fmt[0].sizeimage = ctx->luma_size;
870 pix_fmt_mp->plane_fmt[1].bytesperline = ctx->buf_width;
871 pix_fmt_mp->plane_fmt[1].sizeimage = ctx->chroma_size;
872 } else {
873 mfc_err("invalid buf type\n");
874 return -EINVAL;
875 }
876 return 0;
877}
878
879static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
880{
881 struct s5p_mfc_fmt *fmt;
882 struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
883
884 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
885 fmt = find_format(f, MFC_FMT_ENC);
886 if (!fmt) {
887 mfc_err("failed to try output format\n");
888 return -EINVAL;
889 }
890
891 if (pix_fmt_mp->plane_fmt[0].sizeimage == 0) {
892 mfc_err("must be set encoding output size\n");
893 return -EINVAL;
894 }
895
896 pix_fmt_mp->plane_fmt[0].bytesperline =
897 pix_fmt_mp->plane_fmt[0].sizeimage;
898 } else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
899 fmt = find_format(f, MFC_FMT_RAW);
900 if (!fmt) {
901 mfc_err("failed to try output format\n");
902 return -EINVAL;
903 }
904
905 if (fmt->num_planes != pix_fmt_mp->num_planes) {
906 mfc_err("failed to try output format\n");
907 return -EINVAL;
908 }
909 v4l_bound_align_image(&pix_fmt_mp->width, 8, 1920, 1,
910 &pix_fmt_mp->height, 4, 1080, 1, 0);
911 } else {
912 mfc_err("invalid buf type\n");
913 return -EINVAL;
914 }
915 return 0;
916}
917
918static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
919{
920 struct s5p_mfc_dev *dev = video_drvdata(file);
921 struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
922 struct s5p_mfc_fmt *fmt;
923 struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
924 unsigned long flags;
925 int ret = 0;
926
927 ret = vidioc_try_fmt(file, priv, f);
928 if (ret)
929 return ret;
930 if (ctx->vq_src.streaming || ctx->vq_dst.streaming) {
931 v4l2_err(&dev->v4l2_dev, "%s queue busy\n", __func__);
932 ret = -EBUSY;
933 goto out;
934 }
935 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
936 fmt = find_format(f, MFC_FMT_ENC);
937 if (!fmt) {
938 mfc_err("failed to set capture format\n");
939 return -EINVAL;
940 }
941 ctx->state = MFCINST_INIT;
942 ctx->dst_fmt = fmt;
943 ctx->codec_mode = ctx->dst_fmt->codec_mode;
944 ctx->enc_dst_buf_size = pix_fmt_mp->plane_fmt[0].sizeimage;
945 pix_fmt_mp->plane_fmt[0].bytesperline = 0;
946 ctx->dst_bufs_cnt = 0;
947 ctx->capture_state = QUEUE_FREE;
948 s5p_mfc_alloc_instance_buffer(ctx);
949 spin_lock_irqsave(&dev->condlock, flags);
950 set_bit(ctx->num, &dev->ctx_work_bits);
951 spin_unlock_irqrestore(&dev->condlock, flags);
952 s5p_mfc_clean_ctx_int_flags(ctx);
953 s5p_mfc_try_run(dev);
954 if (s5p_mfc_wait_for_done_ctx(ctx, \
955 S5P_FIMV_R2H_CMD_OPEN_INSTANCE_RET, 1)) {
956 /* Error or timeout */
957 mfc_err("Error getting instance from hardware\n");
958 s5p_mfc_release_instance_buffer(ctx);
959 ret = -EIO;
960 goto out;
961 }
962 mfc_debug(2, "Got instance number: %d\n", ctx->inst_no);
963 } else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
964 fmt = find_format(f, MFC_FMT_RAW);
965 if (!fmt) {
966 mfc_err("failed to set output format\n");
967 return -EINVAL;
968 }
969 if (fmt->num_planes != pix_fmt_mp->num_planes) {
970 mfc_err("failed to set output format\n");
971 ret = -EINVAL;
972 goto out;
973 }
974 ctx->src_fmt = fmt;
975 ctx->img_width = pix_fmt_mp->width;
976 ctx->img_height = pix_fmt_mp->height;
977 mfc_debug(2, "codec number: %d\n", ctx->src_fmt->codec_mode);
978 mfc_debug(2, "fmt - w: %d, h: %d, ctx - w: %d, h: %d\n",
979 pix_fmt_mp->width, pix_fmt_mp->height,
980 ctx->img_width, ctx->img_height);
981 if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12M) {
982 ctx->buf_width = ALIGN(ctx->img_width,
983 S5P_FIMV_NV12M_HALIGN);
984 ctx->luma_size = ALIGN(ctx->img_width,
985 S5P_FIMV_NV12M_HALIGN) * ALIGN(ctx->img_height,
986 S5P_FIMV_NV12M_LVALIGN);
987 ctx->chroma_size = ALIGN(ctx->img_width,
988 S5P_FIMV_NV12M_HALIGN) * ALIGN((ctx->img_height
989 >> 1), S5P_FIMV_NV12M_CVALIGN);
990
991 ctx->luma_size = ALIGN(ctx->luma_size,
992 S5P_FIMV_NV12M_SALIGN);
993 ctx->chroma_size = ALIGN(ctx->chroma_size,
994 S5P_FIMV_NV12M_SALIGN);
995
996 pix_fmt_mp->plane_fmt[0].sizeimage = ctx->luma_size;
997 pix_fmt_mp->plane_fmt[0].bytesperline = ctx->buf_width;
998 pix_fmt_mp->plane_fmt[1].sizeimage = ctx->chroma_size;
999 pix_fmt_mp->plane_fmt[1].bytesperline = ctx->buf_width;
1000
1001 } else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12MT) {
1002 ctx->buf_width = ALIGN(ctx->img_width,
1003 S5P_FIMV_NV12MT_HALIGN);
1004 ctx->luma_size = ALIGN(ctx->img_width,
1005 S5P_FIMV_NV12MT_HALIGN) * ALIGN(ctx->img_height,
1006 S5P_FIMV_NV12MT_VALIGN);
1007 ctx->chroma_size = ALIGN(ctx->img_width,
1008 S5P_FIMV_NV12MT_HALIGN) * ALIGN((ctx->img_height
1009 >> 1), S5P_FIMV_NV12MT_VALIGN);
1010 ctx->luma_size = ALIGN(ctx->luma_size,
1011 S5P_FIMV_NV12MT_SALIGN);
1012 ctx->chroma_size = ALIGN(ctx->chroma_size,
1013 S5P_FIMV_NV12MT_SALIGN);
1014
1015 pix_fmt_mp->plane_fmt[0].sizeimage = ctx->luma_size;
1016 pix_fmt_mp->plane_fmt[0].bytesperline = ctx->buf_width;
1017 pix_fmt_mp->plane_fmt[1].sizeimage = ctx->chroma_size;
1018 pix_fmt_mp->plane_fmt[1].bytesperline = ctx->buf_width;
1019 }
1020 ctx->src_bufs_cnt = 0;
1021 ctx->output_state = QUEUE_FREE;
1022 } else {
1023 mfc_err("invalid buf type\n");
1024 return -EINVAL;
1025 }
1026out:
1027 mfc_debug_leave();
1028 return ret;
1029}
1030
1031static int vidioc_reqbufs(struct file *file, void *priv,
1032 struct v4l2_requestbuffers *reqbufs)
1033{
1034 struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
1035 int ret = 0;
1036
1037 /* if memory is not mmp or userptr return error */
1038 if ((reqbufs->memory != V4L2_MEMORY_MMAP) &&
1039 (reqbufs->memory != V4L2_MEMORY_USERPTR))
1040 return -EINVAL;
1041 if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
1042 if (ctx->capture_state != QUEUE_FREE) {
1043 mfc_err("invalid capture state: %d\n",
1044 ctx->capture_state);
1045 return -EINVAL;
1046 }
1047 ret = vb2_reqbufs(&ctx->vq_dst, reqbufs);
1048 if (ret != 0) {
1049 mfc_err("error in vb2_reqbufs() for E(D)\n");
1050 return ret;
1051 }
1052 ctx->capture_state = QUEUE_BUFS_REQUESTED;
1053 ret = s5p_mfc_alloc_codec_buffers(ctx);
1054 if (ret) {
1055 mfc_err("Failed to allocate encoding buffers\n");
1056 reqbufs->count = 0;
1057 ret = vb2_reqbufs(&ctx->vq_dst, reqbufs);
1058 return -ENOMEM;
1059 }
1060 } else if (reqbufs->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
1061 if (ctx->output_state != QUEUE_FREE) {
1062 mfc_err("invalid output state: %d\n",
1063 ctx->output_state);
1064 return -EINVAL;
1065 }
1066 ret = vb2_reqbufs(&ctx->vq_src, reqbufs);
1067 if (ret != 0) {
1068 mfc_err("error in vb2_reqbufs() for E(S)\n");
1069 return ret;
1070 }
1071 ctx->output_state = QUEUE_BUFS_REQUESTED;
1072 } else {
1073 mfc_err("invalid buf type\n");
1074 return -EINVAL;
1075 }
1076 return ret;
1077}
1078
1079static int vidioc_querybuf(struct file *file, void *priv,
1080 struct v4l2_buffer *buf)
1081{
1082 struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
1083 int ret = 0;
1084
1085 /* if memory is not mmp or userptr return error */
1086 if ((buf->memory != V4L2_MEMORY_MMAP) &&
1087 (buf->memory != V4L2_MEMORY_USERPTR))
1088 return -EINVAL;
1089 if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
1090 if (ctx->state != MFCINST_GOT_INST) {
1091 mfc_err("invalid context state: %d\n", ctx->state);
1092 return -EINVAL;
1093 }
1094 ret = vb2_querybuf(&ctx->vq_dst, buf);
1095 if (ret != 0) {
1096 mfc_err("error in vb2_querybuf() for E(D)\n");
1097 return ret;
1098 }
1099 buf->m.planes[0].m.mem_offset += DST_QUEUE_OFF_BASE;
1100 } else if (buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
1101 ret = vb2_querybuf(&ctx->vq_src, buf);
1102 if (ret != 0) {
1103 mfc_err("error in vb2_querybuf() for E(S)\n");
1104 return ret;
1105 }
1106 } else {
1107 mfc_err("invalid buf type\n");
1108 return -EINVAL;
1109 }
1110 return ret;
1111}
1112
1113/* Queue a buffer */
1114static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
1115{
1116 struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
1117
1118 if (ctx->state == MFCINST_ERROR) {
1119 mfc_err("Call on QBUF after unrecoverable error\n");
1120 return -EIO;
1121 }
1122 if (buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
1123 return vb2_qbuf(&ctx->vq_src, buf);
1124 else if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
1125 return vb2_qbuf(&ctx->vq_dst, buf);
1126 return -EINVAL;
1127}
1128
1129/* Dequeue a buffer */
1130static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
1131{
1132 struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
1133
1134 if (ctx->state == MFCINST_ERROR) {
1135 mfc_err("Call on DQBUF after unrecoverable error\n");
1136 return -EIO;
1137 }
1138 if (buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
1139 return vb2_dqbuf(&ctx->vq_src, buf, file->f_flags & O_NONBLOCK);
1140 else if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
1141 return vb2_dqbuf(&ctx->vq_dst, buf, file->f_flags & O_NONBLOCK);
1142 return -EINVAL;
1143}
1144
1145/* Stream on */
1146static int vidioc_streamon(struct file *file, void *priv,
1147 enum v4l2_buf_type type)
1148{
1149 struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
1150
1151 if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
1152 return vb2_streamon(&ctx->vq_src, type);
1153 else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
1154 return vb2_streamon(&ctx->vq_dst, type);
1155 return -EINVAL;
1156}
1157
1158/* Stream off, which equals to a pause */
1159static int vidioc_streamoff(struct file *file, void *priv,
1160 enum v4l2_buf_type type)
1161{
1162 struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
1163
1164 if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
1165 return vb2_streamoff(&ctx->vq_src, type);
1166 else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
1167 return vb2_streamoff(&ctx->vq_dst, type);
1168 return -EINVAL;
1169}
1170
1171static inline int h264_level(enum v4l2_mpeg_video_h264_level lvl)
1172{
1173 static unsigned int t[V4L2_MPEG_VIDEO_H264_LEVEL_4_0 + 1] = {
1174 /* V4L2_MPEG_VIDEO_H264_LEVEL_1_0 */ 10,
1175 /* V4L2_MPEG_VIDEO_H264_LEVEL_1B */ 9,
1176 /* V4L2_MPEG_VIDEO_H264_LEVEL_1_1 */ 11,
1177 /* V4L2_MPEG_VIDEO_H264_LEVEL_1_2 */ 12,
1178 /* V4L2_MPEG_VIDEO_H264_LEVEL_1_3 */ 13,
1179 /* V4L2_MPEG_VIDEO_H264_LEVEL_2_0 */ 20,
1180 /* V4L2_MPEG_VIDEO_H264_LEVEL_2_1 */ 21,
1181 /* V4L2_MPEG_VIDEO_H264_LEVEL_2_2 */ 22,
1182 /* V4L2_MPEG_VIDEO_H264_LEVEL_3_0 */ 30,
1183 /* V4L2_MPEG_VIDEO_H264_LEVEL_3_1 */ 31,
1184 /* V4L2_MPEG_VIDEO_H264_LEVEL_3_2 */ 32,
1185 /* V4L2_MPEG_VIDEO_H264_LEVEL_4_0 */ 40,
1186 };
1187 return t[lvl];
1188}
1189
1190static inline int mpeg4_level(enum v4l2_mpeg_video_mpeg4_level lvl)
1191{
1192 static unsigned int t[V4L2_MPEG_VIDEO_MPEG4_LEVEL_5 + 1] = {
1193 /* V4L2_MPEG_VIDEO_MPEG4_LEVEL_0 */ 0,
1194 /* V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B */ 9,
1195 /* V4L2_MPEG_VIDEO_MPEG4_LEVEL_1 */ 1,
1196 /* V4L2_MPEG_VIDEO_MPEG4_LEVEL_2 */ 2,
1197 /* V4L2_MPEG_VIDEO_MPEG4_LEVEL_3 */ 3,
1198 /* V4L2_MPEG_VIDEO_MPEG4_LEVEL_3B */ 7,
1199 /* V4L2_MPEG_VIDEO_MPEG4_LEVEL_4 */ 4,
1200 /* V4L2_MPEG_VIDEO_MPEG4_LEVEL_5 */ 5,
1201 };
1202 return t[lvl];
1203}
1204
1205static inline int vui_sar_idc(enum v4l2_mpeg_video_h264_vui_sar_idc sar)
1206{
1207 static unsigned int t[V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_EXTENDED + 1] = {
1208 /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_UNSPECIFIED */ 0,
1209 /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_1x1 */ 1,
1210 /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_12x11 */ 2,
1211 /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_10x11 */ 3,
1212 /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_16x11 */ 4,
1213 /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_40x33 */ 5,
1214 /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_24x11 */ 6,
1215 /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_20x11 */ 7,
1216 /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_32x11 */ 8,
1217 /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_80x33 */ 9,
1218 /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_18x11 */ 10,
1219 /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_15x11 */ 11,
1220 /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_64x33 */ 12,
1221 /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_160x99 */ 13,
1222 /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_4x3 */ 14,
1223 /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_3x2 */ 15,
1224 /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_2x1 */ 16,
1225 /* V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_EXTENDED */ 255,
1226 };
1227 return t[sar];
1228}
1229
1230static int s5p_mfc_enc_s_ctrl(struct v4l2_ctrl *ctrl)
1231{
1232 struct s5p_mfc_ctx *ctx = ctrl_to_ctx(ctrl);
1233 struct s5p_mfc_dev *dev = ctx->dev;
1234 struct s5p_mfc_enc_params *p = &ctx->enc_params;
1235 int ret = 0;
1236
1237 switch (ctrl->id) {
1238 case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
1239 p->gop_size = ctrl->val;
1240 break;
1241 case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE:
1242 p->slice_mode = ctrl->val;
1243 break;
1244 case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB:
1245 p->slice_mb = ctrl->val;
1246 break;
1247 case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES:
1248 p->slice_bit = ctrl->val * 8;
1249 break;
1250 case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB:
1251 p->intra_refresh_mb = ctrl->val;
1252 break;
1253 case V4L2_CID_MPEG_MFC51_VIDEO_PADDING:
1254 p->pad = ctrl->val;
1255 break;
1256 case V4L2_CID_MPEG_MFC51_VIDEO_PADDING_YUV:
1257 p->pad_luma = (ctrl->val >> 16) & 0xff;
1258 p->pad_cb = (ctrl->val >> 8) & 0xff;
1259 p->pad_cr = (ctrl->val >> 0) & 0xff;
1260 break;
1261 case V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE:
1262 p->rc_frame = ctrl->val;
1263 break;
1264 case V4L2_CID_MPEG_VIDEO_BITRATE:
1265 p->rc_bitrate = ctrl->val;
1266 break;
1267 case V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF:
1268 p->rc_reaction_coeff = ctrl->val;
1269 break;
1270 case V4L2_CID_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE:
1271 ctx->force_frame_type = ctrl->val;
1272 break;
1273 case V4L2_CID_MPEG_VIDEO_VBV_SIZE:
1274 p->vbv_size = ctrl->val;
1275 break;
1276 case V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE:
1277 p->codec.h264.cpb_size = ctrl->val;
1278 break;
1279 case V4L2_CID_MPEG_VIDEO_HEADER_MODE:
1280 p->seq_hdr_mode = ctrl->val;
1281 break;
1282 case V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE:
1283 p->frame_skip_mode = ctrl->val;
1284 break;
1285 case V4L2_CID_MPEG_MFC51_VIDEO_RC_FIXED_TARGET_BIT:
1286 p->fixed_target_bit = ctrl->val;
1287 break;
1288 case V4L2_CID_MPEG_VIDEO_B_FRAMES:
1289 p->num_b_frame = ctrl->val;
1290 break;
1291 case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
1292 switch (ctrl->val) {
1293 case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
1294 p->codec.h264.profile =
1295 S5P_FIMV_ENC_PROFILE_H264_MAIN;
1296 break;
1297 case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
1298 p->codec.h264.profile =
1299 S5P_FIMV_ENC_PROFILE_H264_HIGH;
1300 break;
1301 case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
1302 p->codec.h264.profile =
1303 S5P_FIMV_ENC_PROFILE_H264_BASELINE;
1304 break;
1305 default:
1306 ret = -EINVAL;
1307 }
1308 break;
1309 case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
1310 p->codec.h264.level_v4l2 = ctrl->val;
1311 p->codec.h264.level = h264_level(ctrl->val);
1312 if (p->codec.h264.level < 0) {
1313 mfc_err("Level number is wrong\n");
1314 ret = p->codec.h264.level;
1315 }
1316 break;
1317 case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL:
1318 p->codec.mpeg4.level_v4l2 = ctrl->val;
1319 p->codec.mpeg4.level = mpeg4_level(ctrl->val);
1320 if (p->codec.mpeg4.level < 0) {
1321 mfc_err("Level number is wrong\n");
1322 ret = p->codec.mpeg4.level;
1323 }
1324 break;
1325 case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE:
1326 p->codec.h264.loop_filter_mode = ctrl->val;
1327 break;
1328 case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA:
1329 p->codec.h264.loop_filter_alpha = ctrl->val;
1330 break;
1331 case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA:
1332 p->codec.h264.loop_filter_beta = ctrl->val;
1333 break;
1334 case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE:
1335 p->codec.h264.entropy_mode = ctrl->val;
1336 break;
1337 case V4L2_CID_MPEG_MFC51_VIDEO_H264_NUM_REF_PIC_FOR_P:
1338 p->codec.h264.num_ref_pic_4p = ctrl->val;
1339 break;
1340 case V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM:
1341 p->codec.h264._8x8_transform = ctrl->val;
1342 break;
1343 case V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE:
1344 p->codec.h264.rc_mb = ctrl->val;
1345 break;
1346 case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP:
1347 p->codec.h264.rc_frame_qp = ctrl->val;
1348 break;
1349 case V4L2_CID_MPEG_VIDEO_H264_MIN_QP:
1350 p->codec.h264.rc_min_qp = ctrl->val;
1351 break;
1352 case V4L2_CID_MPEG_VIDEO_H264_MAX_QP:
1353 p->codec.h264.rc_max_qp = ctrl->val;
1354 break;
1355 case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP:
1356 p->codec.h264.rc_p_frame_qp = ctrl->val;
1357 break;
1358 case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP:
1359 p->codec.h264.rc_b_frame_qp = ctrl->val;
1360 break;
1361 case V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP:
1362 case V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP:
1363 p->codec.mpeg4.rc_frame_qp = ctrl->val;
1364 break;
1365 case V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP:
1366 case V4L2_CID_MPEG_VIDEO_H263_MIN_QP:
1367 p->codec.mpeg4.rc_min_qp = ctrl->val;
1368 break;
1369 case V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP:
1370 case V4L2_CID_MPEG_VIDEO_H263_MAX_QP:
1371 p->codec.mpeg4.rc_max_qp = ctrl->val;
1372 break;
1373 case V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP:
1374 case V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP:
1375 p->codec.mpeg4.rc_p_frame_qp = ctrl->val;
1376 break;
1377 case V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP:
1378 case V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP:
1379 p->codec.mpeg4.rc_b_frame_qp = ctrl->val;
1380 break;
1381 case V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_DARK:
1382 p->codec.h264.rc_mb_dark = ctrl->val;
1383 break;
1384 case V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_SMOOTH:
1385 p->codec.h264.rc_mb_smooth = ctrl->val;
1386 break;
1387 case V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_STATIC:
1388 p->codec.h264.rc_mb_static = ctrl->val;
1389 break;
1390 case V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_ACTIVITY:
1391 p->codec.h264.rc_mb_activity = ctrl->val;
1392 break;
1393 case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE:
1394 p->codec.h264.vui_sar = ctrl->val;
1395 break;
1396 case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC:
1397 p->codec.h264.vui_sar_idc = vui_sar_idc(ctrl->val);
1398 break;
1399 case V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH:
1400 p->codec.h264.vui_ext_sar_width = ctrl->val;
1401 break;
1402 case V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT:
1403 p->codec.h264.vui_ext_sar_height = ctrl->val;
1404 break;
1405 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
1406 p->codec.h264.open_gop = !ctrl->val;
1407 break;
1408 case V4L2_CID_MPEG_VIDEO_H264_I_PERIOD:
1409 p->codec.h264.open_gop_size = ctrl->val;
1410 break;
1411 case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE:
1412 switch (ctrl->val) {
1413 case V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE:
1414 p->codec.mpeg4.profile =
1415 S5P_FIMV_ENC_PROFILE_MPEG4_SIMPLE;
1416 break;
1417 case V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE:
1418 p->codec.mpeg4.profile =
1419 S5P_FIMV_ENC_PROFILE_MPEG4_ADVANCED_SIMPLE;
1420 break;
1421 default:
1422 ret = -EINVAL;
1423 }
1424 break;
1425 case V4L2_CID_MPEG_VIDEO_MPEG4_QPEL:
1426 p->codec.mpeg4.quarter_pixel = ctrl->val;
1427 break;
1428 default:
1429 v4l2_err(&dev->v4l2_dev, "Invalid control, id=%d, val=%d\n",
1430 ctrl->id, ctrl->val);
1431 ret = -EINVAL;
1432 }
1433 return ret;
1434}
1435
1436static const struct v4l2_ctrl_ops s5p_mfc_enc_ctrl_ops = {
1437 .s_ctrl = s5p_mfc_enc_s_ctrl,
1438};
1439
1440static int vidioc_s_parm(struct file *file, void *priv,
1441 struct v4l2_streamparm *a)
1442{
1443 struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
1444
1445 if (a->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
1446 ctx->enc_params.rc_framerate_num =
1447 a->parm.output.timeperframe.denominator;
1448 ctx->enc_params.rc_framerate_denom =
1449 a->parm.output.timeperframe.numerator;
1450 } else {
1451 mfc_err("Setting FPS is only possible for the output queue\n");
1452 return -EINVAL;
1453 }
1454 return 0;
1455}
1456
1457static int vidioc_g_parm(struct file *file, void *priv,
1458 struct v4l2_streamparm *a)
1459{
1460 struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
1461
1462 if (a->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
1463 a->parm.output.timeperframe.denominator =
1464 ctx->enc_params.rc_framerate_num;
1465 a->parm.output.timeperframe.numerator =
1466 ctx->enc_params.rc_framerate_denom;
1467 } else {
1468 mfc_err("Setting FPS is only possible for the output queue\n");
1469 return -EINVAL;
1470 }
1471 return 0;
1472}
1473
1474static const struct v4l2_ioctl_ops s5p_mfc_enc_ioctl_ops = {
1475 .vidioc_querycap = vidioc_querycap,
1476 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
1477 .vidioc_enum_fmt_vid_cap_mplane = vidioc_enum_fmt_vid_cap_mplane,
1478 .vidioc_enum_fmt_vid_out = vidioc_enum_fmt_vid_out,
1479 .vidioc_enum_fmt_vid_out_mplane = vidioc_enum_fmt_vid_out_mplane,
1480 .vidioc_g_fmt_vid_cap_mplane = vidioc_g_fmt,
1481 .vidioc_g_fmt_vid_out_mplane = vidioc_g_fmt,
1482 .vidioc_try_fmt_vid_cap_mplane = vidioc_try_fmt,
1483 .vidioc_try_fmt_vid_out_mplane = vidioc_try_fmt,
1484 .vidioc_s_fmt_vid_cap_mplane = vidioc_s_fmt,
1485 .vidioc_s_fmt_vid_out_mplane = vidioc_s_fmt,
1486 .vidioc_reqbufs = vidioc_reqbufs,
1487 .vidioc_querybuf = vidioc_querybuf,
1488 .vidioc_qbuf = vidioc_qbuf,
1489 .vidioc_dqbuf = vidioc_dqbuf,
1490 .vidioc_streamon = vidioc_streamon,
1491 .vidioc_streamoff = vidioc_streamoff,
1492 .vidioc_s_parm = vidioc_s_parm,
1493 .vidioc_g_parm = vidioc_g_parm,
1494};
1495
1496static int check_vb_with_fmt(struct s5p_mfc_fmt *fmt, struct vb2_buffer *vb)
1497{
1498 int i;
1499
1500 if (!fmt)
1501 return -EINVAL;
1502 if (fmt->num_planes != vb->num_planes) {
1503 mfc_err("invalid plane number for the format\n");
1504 return -EINVAL;
1505 }
1506 for (i = 0; i < fmt->num_planes; i++) {
1507 if (!vb2_dma_contig_plane_dma_addr(vb, i)) {
1508 mfc_err("failed to get plane cookie\n");
1509 return -EINVAL;
1510 }
1511 mfc_debug(2, "index: %d, plane[%d] cookie: 0x%08zx",
1512 vb->v4l2_buf.index, i,
1513 vb2_dma_contig_plane_dma_addr(vb, i));
1514 }
1515 return 0;
1516}
1517
1518static int s5p_mfc_queue_setup(struct vb2_queue *vq,
1519 const struct v4l2_format *fmt,
1520 unsigned int *buf_count, unsigned int *plane_count,
1521 unsigned int psize[], void *allocators[])
1522{
1523 struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv);
1524
1525 if (ctx->state != MFCINST_GOT_INST) {
1526 mfc_err("inavlid state: %d\n", ctx->state);
1527 return -EINVAL;
1528 }
1529 if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
1530 if (ctx->dst_fmt)
1531 *plane_count = ctx->dst_fmt->num_planes;
1532 else
1533 *plane_count = MFC_ENC_CAP_PLANE_COUNT;
1534 if (*buf_count < 1)
1535 *buf_count = 1;
1536 if (*buf_count > MFC_MAX_BUFFERS)
1537 *buf_count = MFC_MAX_BUFFERS;
1538 psize[0] = ctx->enc_dst_buf_size;
1539 allocators[0] = ctx->dev->alloc_ctx[MFC_BANK1_ALLOC_CTX];
1540 } else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
1541 if (ctx->src_fmt)
1542 *plane_count = ctx->src_fmt->num_planes;
1543 else
1544 *plane_count = MFC_ENC_OUT_PLANE_COUNT;
1545
1546 if (*buf_count < 1)
1547 *buf_count = 1;
1548 if (*buf_count > MFC_MAX_BUFFERS)
1549 *buf_count = MFC_MAX_BUFFERS;
1550 psize[0] = ctx->luma_size;
1551 psize[1] = ctx->chroma_size;
1552 allocators[0] = ctx->dev->alloc_ctx[MFC_BANK2_ALLOC_CTX];
1553 allocators[1] = ctx->dev->alloc_ctx[MFC_BANK2_ALLOC_CTX];
1554 } else {
1555 mfc_err("inavlid queue type: %d\n", vq->type);
1556 return -EINVAL;
1557 }
1558 return 0;
1559}
1560
1561static void s5p_mfc_unlock(struct vb2_queue *q)
1562{
1563 struct s5p_mfc_ctx *ctx = fh_to_ctx(q->drv_priv);
1564 struct s5p_mfc_dev *dev = ctx->dev;
1565
1566 mutex_unlock(&dev->mfc_mutex);
1567}
1568
1569static void s5p_mfc_lock(struct vb2_queue *q)
1570{
1571 struct s5p_mfc_ctx *ctx = fh_to_ctx(q->drv_priv);
1572 struct s5p_mfc_dev *dev = ctx->dev;
1573
1574 mutex_lock(&dev->mfc_mutex);
1575}
1576
1577static int s5p_mfc_buf_init(struct vb2_buffer *vb)
1578{
1579 struct vb2_queue *vq = vb->vb2_queue;
1580 struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv);
1581 unsigned int i;
1582 int ret;
1583
1584 if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
1585 ret = check_vb_with_fmt(ctx->dst_fmt, vb);
1586 if (ret < 0)
1587 return ret;
1588 i = vb->v4l2_buf.index;
1589 ctx->dst_bufs[i].b = vb;
1590 ctx->dst_bufs[i].cookie.stream =
1591 vb2_dma_contig_plane_dma_addr(vb, 0);
1592 ctx->dst_bufs_cnt++;
1593 } else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
1594 ret = check_vb_with_fmt(ctx->src_fmt, vb);
1595 if (ret < 0)
1596 return ret;
1597 i = vb->v4l2_buf.index;
1598 ctx->src_bufs[i].b = vb;
1599 ctx->src_bufs[i].cookie.raw.luma =
1600 vb2_dma_contig_plane_dma_addr(vb, 0);
1601 ctx->src_bufs[i].cookie.raw.chroma =
1602 vb2_dma_contig_plane_dma_addr(vb, 1);
1603 ctx->src_bufs_cnt++;
1604 } else {
1605 mfc_err("inavlid queue type: %d\n", vq->type);
1606 return -EINVAL;
1607 }
1608 return 0;
1609}
1610
1611static int s5p_mfc_buf_prepare(struct vb2_buffer *vb)
1612{
1613 struct vb2_queue *vq = vb->vb2_queue;
1614 struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv);
1615 int ret;
1616
1617 if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
1618 ret = check_vb_with_fmt(ctx->dst_fmt, vb);
1619 if (ret < 0)
1620 return ret;
1621 mfc_debug(2, "plane size: %ld, dst size: %d\n",
1622 vb2_plane_size(vb, 0), ctx->enc_dst_buf_size);
1623 if (vb2_plane_size(vb, 0) < ctx->enc_dst_buf_size) {
1624 mfc_err("plane size is too small for capture\n");
1625 return -EINVAL;
1626 }
1627 } else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
1628 ret = check_vb_with_fmt(ctx->src_fmt, vb);
1629 if (ret < 0)
1630 return ret;
1631 mfc_debug(2, "plane size: %ld, luma size: %d\n",
1632 vb2_plane_size(vb, 0), ctx->luma_size);
1633 mfc_debug(2, "plane size: %ld, chroma size: %d\n",
1634 vb2_plane_size(vb, 1), ctx->chroma_size);
1635 if (vb2_plane_size(vb, 0) < ctx->luma_size ||
1636 vb2_plane_size(vb, 1) < ctx->chroma_size) {
1637 mfc_err("plane size is too small for output\n");
1638 return -EINVAL;
1639 }
1640 } else {
1641 mfc_err("inavlid queue type: %d\n", vq->type);
1642 return -EINVAL;
1643 }
1644 return 0;
1645}
1646
1647static int s5p_mfc_start_streaming(struct vb2_queue *q, unsigned int count)
1648{
1649 struct s5p_mfc_ctx *ctx = fh_to_ctx(q->drv_priv);
1650 struct s5p_mfc_dev *dev = ctx->dev;
1651 unsigned long flags;
1652
1653 v4l2_ctrl_handler_setup(&ctx->ctrl_handler);
1654 /* If context is ready then dev = work->data;schedule it to run */
1655 if (s5p_mfc_ctx_ready(ctx)) {
1656 spin_lock_irqsave(&dev->condlock, flags);
1657 set_bit(ctx->num, &dev->ctx_work_bits);
1658 spin_unlock_irqrestore(&dev->condlock, flags);
1659 }
1660 s5p_mfc_try_run(dev);
1661 return 0;
1662}
1663
1664static int s5p_mfc_stop_streaming(struct vb2_queue *q)
1665{
1666 unsigned long flags;
1667 struct s5p_mfc_ctx *ctx = fh_to_ctx(q->drv_priv);
1668 struct s5p_mfc_dev *dev = ctx->dev;
1669
1670 if ((ctx->state == MFCINST_FINISHING ||
1671 ctx->state == MFCINST_RUNNING) &&
1672 dev->curr_ctx == ctx->num && dev->hw_lock) {
1673 ctx->state = MFCINST_ABORT;
1674 s5p_mfc_wait_for_done_ctx(ctx, S5P_FIMV_R2H_CMD_FRAME_DONE_RET,
1675 0);
1676 }
1677 ctx->state = MFCINST_FINISHED;
1678 spin_lock_irqsave(&dev->irqlock, flags);
1679 if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
1680 s5p_mfc_cleanup_queue(&ctx->dst_queue, &ctx->vq_dst);
1681 INIT_LIST_HEAD(&ctx->dst_queue);
1682 ctx->dst_queue_cnt = 0;
1683 }
1684 if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
1685 cleanup_ref_queue(ctx);
1686 s5p_mfc_cleanup_queue(&ctx->src_queue, &ctx->vq_src);
1687 INIT_LIST_HEAD(&ctx->src_queue);
1688 ctx->src_queue_cnt = 0;
1689 }
1690 spin_unlock_irqrestore(&dev->irqlock, flags);
1691 return 0;
1692}
1693
1694static void s5p_mfc_buf_queue(struct vb2_buffer *vb)
1695{
1696 struct vb2_queue *vq = vb->vb2_queue;
1697 struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv);
1698 struct s5p_mfc_dev *dev = ctx->dev;
1699 unsigned long flags;
1700 struct s5p_mfc_buf *mfc_buf;
1701
1702 if (ctx->state == MFCINST_ERROR) {
1703 vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
1704 cleanup_ref_queue(ctx);
1705 return;
1706 }
1707 if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
1708 mfc_buf = &ctx->dst_bufs[vb->v4l2_buf.index];
1709 mfc_buf->used = 0;
1710 /* Mark destination as available for use by MFC */
1711 spin_lock_irqsave(&dev->irqlock, flags);
1712 list_add_tail(&mfc_buf->list, &ctx->dst_queue);
1713 ctx->dst_queue_cnt++;
1714 spin_unlock_irqrestore(&dev->irqlock, flags);
1715 } else if (vq->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
1716 mfc_buf = &ctx->src_bufs[vb->v4l2_buf.index];
1717 mfc_buf->used = 0;
1718 spin_lock_irqsave(&dev->irqlock, flags);
1719 if (vb->v4l2_planes[0].bytesused == 0) {
1720 mfc_debug(1, "change state to FINISHING\n");
1721 ctx->state = MFCINST_FINISHING;
1722 vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
1723 cleanup_ref_queue(ctx);
1724 } else {
1725 list_add_tail(&mfc_buf->list, &ctx->src_queue);
1726 ctx->src_queue_cnt++;
1727 }
1728 spin_unlock_irqrestore(&dev->irqlock, flags);
1729 } else {
1730 mfc_err("unsupported buffer type (%d)\n", vq->type);
1731 }
1732 if (s5p_mfc_ctx_ready(ctx)) {
1733 spin_lock_irqsave(&dev->condlock, flags);
1734 set_bit(ctx->num, &dev->ctx_work_bits);
1735 spin_unlock_irqrestore(&dev->condlock, flags);
1736 }
1737 s5p_mfc_try_run(dev);
1738}
1739
1740static struct vb2_ops s5p_mfc_enc_qops = {
1741 .queue_setup = s5p_mfc_queue_setup,
1742 .wait_prepare = s5p_mfc_unlock,
1743 .wait_finish = s5p_mfc_lock,
1744 .buf_init = s5p_mfc_buf_init,
1745 .buf_prepare = s5p_mfc_buf_prepare,
1746 .start_streaming = s5p_mfc_start_streaming,
1747 .stop_streaming = s5p_mfc_stop_streaming,
1748 .buf_queue = s5p_mfc_buf_queue,
1749};
1750
1751struct s5p_mfc_codec_ops *get_enc_codec_ops(void)
1752{
1753 return &encoder_codec_ops;
1754}
1755
1756struct vb2_ops *get_enc_queue_ops(void)
1757{
1758 return &s5p_mfc_enc_qops;
1759}
1760
1761const struct v4l2_ioctl_ops *get_enc_v4l2_ioctl_ops(void)
1762{
1763 return &s5p_mfc_enc_ioctl_ops;
1764}
1765
1766#define IS_MFC51_PRIV(x) ((V4L2_CTRL_ID2CLASS(x) == V4L2_CTRL_CLASS_MPEG) \
1767 && V4L2_CTRL_DRIVER_PRIV(x))
1768
1769int s5p_mfc_enc_ctrls_setup(struct s5p_mfc_ctx *ctx)
1770{
1771 struct v4l2_ctrl_config cfg;
1772 int i;
1773
1774 v4l2_ctrl_handler_init(&ctx->ctrl_handler, NUM_CTRLS);
1775 if (ctx->ctrl_handler.error) {
1776 mfc_err("v4l2_ctrl_handler_init failed\n");
1777 return ctx->ctrl_handler.error;
1778 }
1779 for (i = 0; i < NUM_CTRLS; i++) {
1780 if (IS_MFC51_PRIV(controls[i].id)) {
1781 memset(&cfg, 0, sizeof(struct v4l2_ctrl_config));
1782 cfg.ops = &s5p_mfc_enc_ctrl_ops;
1783 cfg.id = controls[i].id;
1784 cfg.min = controls[i].minimum;
1785 cfg.max = controls[i].maximum;
1786 cfg.def = controls[i].default_value;
1787 cfg.name = controls[i].name;
1788 cfg.type = controls[i].type;
1789 cfg.flags = 0;
1790
1791 if (cfg.type == V4L2_CTRL_TYPE_MENU) {
1792 cfg.step = 0;
1793 cfg.menu_skip_mask = cfg.menu_skip_mask;
1794 cfg.qmenu = mfc51_get_menu(cfg.id);
1795 } else {
1796 cfg.step = controls[i].step;
1797 cfg.menu_skip_mask = 0;
1798 }
1799 ctx->ctrls[i] = v4l2_ctrl_new_custom(&ctx->ctrl_handler,
1800 &cfg, NULL);
1801 } else {
1802 if (controls[i].type == V4L2_CTRL_TYPE_MENU) {
1803 ctx->ctrls[i] = v4l2_ctrl_new_std_menu(
1804 &ctx->ctrl_handler,
1805 &s5p_mfc_enc_ctrl_ops, controls[i].id,
1806 controls[i].maximum, 0,
1807 controls[i].default_value);
1808 } else {
1809 ctx->ctrls[i] = v4l2_ctrl_new_std(
1810 &ctx->ctrl_handler,
1811 &s5p_mfc_enc_ctrl_ops, controls[i].id,
1812 controls[i].minimum,
1813 controls[i].maximum, controls[i].step,
1814 controls[i].default_value);
1815 }
1816 }
1817 if (ctx->ctrl_handler.error) {
1818 mfc_err("Adding control (%d) failed\n", i);
1819 return ctx->ctrl_handler.error;
1820 }
1821 if (controls[i].is_volatile && ctx->ctrls[i])
1822 ctx->ctrls[i]->flags |= V4L2_CTRL_FLAG_VOLATILE;
1823 }
1824 return 0;
1825}
1826
1827void s5p_mfc_enc_ctrls_delete(struct s5p_mfc_ctx *ctx)
1828{
1829 int i;
1830
1831 v4l2_ctrl_handler_free(&ctx->ctrl_handler);
1832 for (i = 0; i < NUM_CTRLS; i++)
1833 ctx->ctrls[i] = NULL;
1834}
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_enc.h b/drivers/media/video/s5p-mfc/s5p_mfc_enc.h
deleted file mode 100644
index 405bdd3ee083..000000000000
--- a/drivers/media/video/s5p-mfc/s5p_mfc_enc.h
+++ /dev/null
@@ -1,23 +0,0 @@
1/*
2 * linux/drivers/media/video/s5p-mfc/s5p_mfc_enc.h
3 *
4 * Copyright (C) 2011 Samsung Electronics Co., Ltd.
5 * http://www.samsung.com/
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#ifndef S5P_MFC_ENC_H_
14#define S5P_MFC_ENC_H_
15
16struct s5p_mfc_codec_ops *get_enc_codec_ops(void);
17struct vb2_ops *get_enc_queue_ops(void);
18const struct v4l2_ioctl_ops *get_enc_v4l2_ioctl_ops(void);
19struct s5p_mfc_fmt *get_enc_def_fmt(bool src);
20int s5p_mfc_enc_ctrls_setup(struct s5p_mfc_ctx *ctx);
21void s5p_mfc_enc_ctrls_delete(struct s5p_mfc_ctx *ctx);
22
23#endif /* S5P_MFC_ENC_H_ */
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_intr.c b/drivers/media/video/s5p-mfc/s5p_mfc_intr.c
deleted file mode 100644
index 8f2f8bf4da7f..000000000000
--- a/drivers/media/video/s5p-mfc/s5p_mfc_intr.c
+++ /dev/null
@@ -1,92 +0,0 @@
1/*
2 * drivers/media/video/samsung/mfc5/s5p_mfc_intr.c
3 *
4 * C file for Samsung MFC (Multi Function Codec - FIMV) driver
5 * This file contains functions used to wait for command completion.
6 *
7 * Kamil Debski, Copyright (C) 2011 Samsung Electronics Co., Ltd.
8 * http://www.samsung.com/
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#include <linux/delay.h>
16#include <linux/errno.h>
17#include <linux/io.h>
18#include <linux/sched.h>
19#include <linux/wait.h>
20#include "regs-mfc.h"
21#include "s5p_mfc_common.h"
22#include "s5p_mfc_debug.h"
23#include "s5p_mfc_intr.h"
24
25int s5p_mfc_wait_for_done_dev(struct s5p_mfc_dev *dev, int command)
26{
27 int ret;
28
29 ret = wait_event_interruptible_timeout(dev->queue,
30 (dev->int_cond && (dev->int_type == command
31 || dev->int_type == S5P_FIMV_R2H_CMD_ERR_RET)),
32 msecs_to_jiffies(MFC_INT_TIMEOUT));
33 if (ret == 0) {
34 mfc_err("Interrupt (dev->int_type:%d, command:%d) timed out\n",
35 dev->int_type, command);
36 return 1;
37 } else if (ret == -ERESTARTSYS) {
38 mfc_err("Interrupted by a signal\n");
39 return 1;
40 }
41 mfc_debug(1, "Finished waiting (dev->int_type:%d, command: %d)\n",
42 dev->int_type, command);
43 if (dev->int_type == S5P_FIMV_R2H_CMD_ERR_RET)
44 return 1;
45 return 0;
46}
47
48void s5p_mfc_clean_dev_int_flags(struct s5p_mfc_dev *dev)
49{
50 dev->int_cond = 0;
51 dev->int_type = 0;
52 dev->int_err = 0;
53}
54
55int s5p_mfc_wait_for_done_ctx(struct s5p_mfc_ctx *ctx,
56 int command, int interrupt)
57{
58 int ret;
59
60 if (interrupt) {
61 ret = wait_event_interruptible_timeout(ctx->queue,
62 (ctx->int_cond && (ctx->int_type == command
63 || ctx->int_type == S5P_FIMV_R2H_CMD_ERR_RET)),
64 msecs_to_jiffies(MFC_INT_TIMEOUT));
65 } else {
66 ret = wait_event_timeout(ctx->queue,
67 (ctx->int_cond && (ctx->int_type == command
68 || ctx->int_type == S5P_FIMV_R2H_CMD_ERR_RET)),
69 msecs_to_jiffies(MFC_INT_TIMEOUT));
70 }
71 if (ret == 0) {
72 mfc_err("Interrupt (ctx->int_type:%d, command:%d) timed out\n",
73 ctx->int_type, command);
74 return 1;
75 } else if (ret == -ERESTARTSYS) {
76 mfc_err("Interrupted by a signal\n");
77 return 1;
78 }
79 mfc_debug(1, "Finished waiting (ctx->int_type:%d, command: %d)\n",
80 ctx->int_type, command);
81 if (ctx->int_type == S5P_FIMV_R2H_CMD_ERR_RET)
82 return 1;
83 return 0;
84}
85
86void s5p_mfc_clean_ctx_int_flags(struct s5p_mfc_ctx *ctx)
87{
88 ctx->int_cond = 0;
89 ctx->int_type = 0;
90 ctx->int_err = 0;
91}
92
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_intr.h b/drivers/media/video/s5p-mfc/s5p_mfc_intr.h
deleted file mode 100644
index 122d7732f745..000000000000
--- a/drivers/media/video/s5p-mfc/s5p_mfc_intr.h
+++ /dev/null
@@ -1,26 +0,0 @@
1/*
2 * drivers/media/video/samsung/mfc5/s5p_mfc_intr.h
3 *
4 * Header file for Samsung MFC (Multi Function Codec - FIMV) driver
5 * It contains waiting functions declarations.
6 *
7 * Kamil Debski, Copyright (C) 2011 Samsung Electronics
8 * http://www.samsung.com/
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#ifndef S5P_MFC_INTR_H_
16#define S5P_MFC_INTR_H_
17
18#include "s5p_mfc_common.h"
19
20int s5p_mfc_wait_for_done_ctx(struct s5p_mfc_ctx *ctx,
21 int command, int interrupt);
22int s5p_mfc_wait_for_done_dev(struct s5p_mfc_dev *dev, int command);
23void s5p_mfc_clean_ctx_int_flags(struct s5p_mfc_ctx *ctx);
24void s5p_mfc_clean_dev_int_flags(struct s5p_mfc_dev *dev);
25
26#endif /* S5P_MFC_INTR_H_ */
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_opr.c b/drivers/media/video/s5p-mfc/s5p_mfc_opr.c
deleted file mode 100644
index e6217cbfa4a3..000000000000
--- a/drivers/media/video/s5p-mfc/s5p_mfc_opr.c
+++ /dev/null
@@ -1,1397 +0,0 @@
1/*
2 * drivers/media/video/samsung/mfc5/s5p_mfc_opr.c
3 *
4 * Samsung MFC (Multi Function Codec - FIMV) driver
5 * This file contains hw related functions.
6 *
7 * Kamil Debski, Copyright (c) 2011 Samsung Electronics
8 * http://www.samsung.com/
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#include "regs-mfc.h"
16#include "s5p_mfc_cmd.h"
17#include "s5p_mfc_common.h"
18#include "s5p_mfc_ctrl.h"
19#include "s5p_mfc_debug.h"
20#include "s5p_mfc_intr.h"
21#include "s5p_mfc_opr.h"
22#include "s5p_mfc_pm.h"
23#include "s5p_mfc_shm.h"
24#include <asm/cacheflush.h>
25#include <linux/delay.h>
26#include <linux/dma-mapping.h>
27#include <linux/err.h>
28#include <linux/firmware.h>
29#include <linux/io.h>
30#include <linux/jiffies.h>
31#include <linux/mm.h>
32#include <linux/sched.h>
33
34#define OFFSETA(x) (((x) - dev->bank1) >> MFC_OFFSET_SHIFT)
35#define OFFSETB(x) (((x) - dev->bank2) >> MFC_OFFSET_SHIFT)
36
37/* Allocate temporary buffers for decoding */
38int s5p_mfc_alloc_dec_temp_buffers(struct s5p_mfc_ctx *ctx)
39{
40 void *desc_virt;
41 struct s5p_mfc_dev *dev = ctx->dev;
42
43 ctx->desc_buf = vb2_dma_contig_memops.alloc(
44 dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], DESC_BUF_SIZE);
45 if (IS_ERR_VALUE((int)ctx->desc_buf)) {
46 ctx->desc_buf = NULL;
47 mfc_err("Allocating DESC buffer failed\n");
48 return -ENOMEM;
49 }
50 ctx->desc_phys = s5p_mfc_mem_cookie(
51 dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->desc_buf);
52 BUG_ON(ctx->desc_phys & ((1 << MFC_BANK1_ALIGN_ORDER) - 1));
53 desc_virt = vb2_dma_contig_memops.vaddr(ctx->desc_buf);
54 if (desc_virt == NULL) {
55 vb2_dma_contig_memops.put(ctx->desc_buf);
56 ctx->desc_phys = 0;
57 ctx->desc_buf = NULL;
58 mfc_err("Remapping DESC buffer failed\n");
59 return -ENOMEM;
60 }
61 memset(desc_virt, 0, DESC_BUF_SIZE);
62 wmb();
63 return 0;
64}
65
66/* Release temporary buffers for decoding */
67void s5p_mfc_release_dec_desc_buffer(struct s5p_mfc_ctx *ctx)
68{
69 if (ctx->desc_phys) {
70 vb2_dma_contig_memops.put(ctx->desc_buf);
71 ctx->desc_phys = 0;
72 ctx->desc_buf = NULL;
73 }
74}
75
76/* Allocate codec buffers */
77int s5p_mfc_alloc_codec_buffers(struct s5p_mfc_ctx *ctx)
78{
79 struct s5p_mfc_dev *dev = ctx->dev;
80 unsigned int enc_ref_y_size = 0;
81 unsigned int enc_ref_c_size = 0;
82 unsigned int guard_width, guard_height;
83
84 if (ctx->type == MFCINST_DECODER) {
85 mfc_debug(2, "Luma size:%d Chroma size:%d MV size:%d\n",
86 ctx->luma_size, ctx->chroma_size, ctx->mv_size);
87 mfc_debug(2, "Totals bufs: %d\n", ctx->total_dpb_count);
88 } else if (ctx->type == MFCINST_ENCODER) {
89 enc_ref_y_size = ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN)
90 * ALIGN(ctx->img_height, S5P_FIMV_NV12MT_VALIGN);
91 enc_ref_y_size = ALIGN(enc_ref_y_size, S5P_FIMV_NV12MT_SALIGN);
92
93 if (ctx->codec_mode == S5P_FIMV_CODEC_H264_ENC) {
94 enc_ref_c_size = ALIGN(ctx->img_width,
95 S5P_FIMV_NV12MT_HALIGN)
96 * ALIGN(ctx->img_height >> 1,
97 S5P_FIMV_NV12MT_VALIGN);
98 enc_ref_c_size = ALIGN(enc_ref_c_size,
99 S5P_FIMV_NV12MT_SALIGN);
100 } else {
101 guard_width = ALIGN(ctx->img_width + 16,
102 S5P_FIMV_NV12MT_HALIGN);
103 guard_height = ALIGN((ctx->img_height >> 1) + 4,
104 S5P_FIMV_NV12MT_VALIGN);
105 enc_ref_c_size = ALIGN(guard_width * guard_height,
106 S5P_FIMV_NV12MT_SALIGN);
107 }
108 mfc_debug(2, "recon luma size: %d chroma size: %d\n",
109 enc_ref_y_size, enc_ref_c_size);
110 } else {
111 return -EINVAL;
112 }
113 /* Codecs have different memory requirements */
114 switch (ctx->codec_mode) {
115 case S5P_FIMV_CODEC_H264_DEC:
116 ctx->bank1_size =
117 ALIGN(S5P_FIMV_DEC_NB_IP_SIZE +
118 S5P_FIMV_DEC_VERT_NB_MV_SIZE,
119 S5P_FIMV_DEC_BUF_ALIGN);
120 ctx->bank2_size = ctx->total_dpb_count * ctx->mv_size;
121 break;
122 case S5P_FIMV_CODEC_MPEG4_DEC:
123 ctx->bank1_size =
124 ALIGN(S5P_FIMV_DEC_NB_DCAC_SIZE +
125 S5P_FIMV_DEC_UPNB_MV_SIZE +
126 S5P_FIMV_DEC_SUB_ANCHOR_MV_SIZE +
127 S5P_FIMV_DEC_STX_PARSER_SIZE +
128 S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE,
129 S5P_FIMV_DEC_BUF_ALIGN);
130 ctx->bank2_size = 0;
131 break;
132 case S5P_FIMV_CODEC_VC1RCV_DEC:
133 case S5P_FIMV_CODEC_VC1_DEC:
134 ctx->bank1_size =
135 ALIGN(S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE +
136 S5P_FIMV_DEC_UPNB_MV_SIZE +
137 S5P_FIMV_DEC_SUB_ANCHOR_MV_SIZE +
138 S5P_FIMV_DEC_NB_DCAC_SIZE +
139 3 * S5P_FIMV_DEC_VC1_BITPLANE_SIZE,
140 S5P_FIMV_DEC_BUF_ALIGN);
141 ctx->bank2_size = 0;
142 break;
143 case S5P_FIMV_CODEC_MPEG2_DEC:
144 ctx->bank1_size = 0;
145 ctx->bank2_size = 0;
146 break;
147 case S5P_FIMV_CODEC_H263_DEC:
148 ctx->bank1_size =
149 ALIGN(S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE +
150 S5P_FIMV_DEC_UPNB_MV_SIZE +
151 S5P_FIMV_DEC_SUB_ANCHOR_MV_SIZE +
152 S5P_FIMV_DEC_NB_DCAC_SIZE,
153 S5P_FIMV_DEC_BUF_ALIGN);
154 ctx->bank2_size = 0;
155 break;
156 case S5P_FIMV_CODEC_H264_ENC:
157 ctx->bank1_size = (enc_ref_y_size * 2) +
158 S5P_FIMV_ENC_UPMV_SIZE +
159 S5P_FIMV_ENC_COLFLG_SIZE +
160 S5P_FIMV_ENC_INTRAMD_SIZE +
161 S5P_FIMV_ENC_NBORINFO_SIZE;
162 ctx->bank2_size = (enc_ref_y_size * 2) +
163 (enc_ref_c_size * 4) +
164 S5P_FIMV_ENC_INTRAPRED_SIZE;
165 break;
166 case S5P_FIMV_CODEC_MPEG4_ENC:
167 ctx->bank1_size = (enc_ref_y_size * 2) +
168 S5P_FIMV_ENC_UPMV_SIZE +
169 S5P_FIMV_ENC_COLFLG_SIZE +
170 S5P_FIMV_ENC_ACDCCOEF_SIZE;
171 ctx->bank2_size = (enc_ref_y_size * 2) +
172 (enc_ref_c_size * 4);
173 break;
174 case S5P_FIMV_CODEC_H263_ENC:
175 ctx->bank1_size = (enc_ref_y_size * 2) +
176 S5P_FIMV_ENC_UPMV_SIZE +
177 S5P_FIMV_ENC_ACDCCOEF_SIZE;
178 ctx->bank2_size = (enc_ref_y_size * 2) +
179 (enc_ref_c_size * 4);
180 break;
181 default:
182 break;
183 }
184 /* Allocate only if memory from bank 1 is necessary */
185 if (ctx->bank1_size > 0) {
186 ctx->bank1_buf = vb2_dma_contig_memops.alloc(
187 dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->bank1_size);
188 if (IS_ERR(ctx->bank1_buf)) {
189 ctx->bank1_buf = NULL;
190 printk(KERN_ERR
191 "Buf alloc for decoding failed (port A)\n");
192 return -ENOMEM;
193 }
194 ctx->bank1_phys = s5p_mfc_mem_cookie(
195 dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->bank1_buf);
196 BUG_ON(ctx->bank1_phys & ((1 << MFC_BANK1_ALIGN_ORDER) - 1));
197 }
198 /* Allocate only if memory from bank 2 is necessary */
199 if (ctx->bank2_size > 0) {
200 ctx->bank2_buf = vb2_dma_contig_memops.alloc(
201 dev->alloc_ctx[MFC_BANK2_ALLOC_CTX], ctx->bank2_size);
202 if (IS_ERR(ctx->bank2_buf)) {
203 ctx->bank2_buf = NULL;
204 mfc_err("Buf alloc for decoding failed (port B)\n");
205 return -ENOMEM;
206 }
207 ctx->bank2_phys = s5p_mfc_mem_cookie(
208 dev->alloc_ctx[MFC_BANK2_ALLOC_CTX], ctx->bank2_buf);
209 BUG_ON(ctx->bank2_phys & ((1 << MFC_BANK2_ALIGN_ORDER) - 1));
210 }
211 return 0;
212}
213
214/* Release buffers allocated for codec */
215void s5p_mfc_release_codec_buffers(struct s5p_mfc_ctx *ctx)
216{
217 if (ctx->bank1_buf) {
218 vb2_dma_contig_memops.put(ctx->bank1_buf);
219 ctx->bank1_buf = NULL;
220 ctx->bank1_phys = 0;
221 ctx->bank1_size = 0;
222 }
223 if (ctx->bank2_buf) {
224 vb2_dma_contig_memops.put(ctx->bank2_buf);
225 ctx->bank2_buf = NULL;
226 ctx->bank2_phys = 0;
227 ctx->bank2_size = 0;
228 }
229}
230
231/* Allocate memory for instance data buffer */
232int s5p_mfc_alloc_instance_buffer(struct s5p_mfc_ctx *ctx)
233{
234 void *context_virt;
235 struct s5p_mfc_dev *dev = ctx->dev;
236
237 if (ctx->codec_mode == S5P_FIMV_CODEC_H264_DEC ||
238 ctx->codec_mode == S5P_FIMV_CODEC_H264_ENC)
239 ctx->ctx_size = MFC_H264_CTX_BUF_SIZE;
240 else
241 ctx->ctx_size = MFC_CTX_BUF_SIZE;
242 ctx->ctx_buf = vb2_dma_contig_memops.alloc(
243 dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->ctx_size);
244 if (IS_ERR(ctx->ctx_buf)) {
245 mfc_err("Allocating context buffer failed\n");
246 ctx->ctx_phys = 0;
247 ctx->ctx_buf = NULL;
248 return -ENOMEM;
249 }
250 ctx->ctx_phys = s5p_mfc_mem_cookie(
251 dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->ctx_buf);
252 BUG_ON(ctx->ctx_phys & ((1 << MFC_BANK1_ALIGN_ORDER) - 1));
253 ctx->ctx_ofs = OFFSETA(ctx->ctx_phys);
254 context_virt = vb2_dma_contig_memops.vaddr(ctx->ctx_buf);
255 if (context_virt == NULL) {
256 mfc_err("Remapping instance buffer failed\n");
257 vb2_dma_contig_memops.put(ctx->ctx_buf);
258 ctx->ctx_phys = 0;
259 ctx->ctx_buf = NULL;
260 return -ENOMEM;
261 }
262 /* Zero content of the allocated memory */
263 memset(context_virt, 0, ctx->ctx_size);
264 wmb();
265 if (s5p_mfc_init_shm(ctx) < 0) {
266 vb2_dma_contig_memops.put(ctx->ctx_buf);
267 ctx->ctx_phys = 0;
268 ctx->ctx_buf = NULL;
269 return -ENOMEM;
270 }
271 return 0;
272}
273
274/* Release instance buffer */
275void s5p_mfc_release_instance_buffer(struct s5p_mfc_ctx *ctx)
276{
277 if (ctx->ctx_buf) {
278 vb2_dma_contig_memops.put(ctx->ctx_buf);
279 ctx->ctx_phys = 0;
280 ctx->ctx_buf = NULL;
281 }
282 if (ctx->shm_alloc) {
283 vb2_dma_contig_memops.put(ctx->shm_alloc);
284 ctx->shm_alloc = NULL;
285 ctx->shm = NULL;
286 }
287}
288
289/* Set registers for decoding temporary buffers */
290void s5p_mfc_set_dec_desc_buffer(struct s5p_mfc_ctx *ctx)
291{
292 struct s5p_mfc_dev *dev = ctx->dev;
293
294 mfc_write(dev, OFFSETA(ctx->desc_phys), S5P_FIMV_SI_CH0_DESC_ADR);
295 mfc_write(dev, DESC_BUF_SIZE, S5P_FIMV_SI_CH0_DESC_SIZE);
296}
297
298/* Set registers for shared buffer */
299static void s5p_mfc_set_shared_buffer(struct s5p_mfc_ctx *ctx)
300{
301 struct s5p_mfc_dev *dev = ctx->dev;
302 mfc_write(dev, ctx->shm_ofs, S5P_FIMV_SI_CH0_HOST_WR_ADR);
303}
304
305/* Set registers for decoding stream buffer */
306int s5p_mfc_set_dec_stream_buffer(struct s5p_mfc_ctx *ctx, int buf_addr,
307 unsigned int start_num_byte, unsigned int buf_size)
308{
309 struct s5p_mfc_dev *dev = ctx->dev;
310
311 mfc_write(dev, OFFSETA(buf_addr), S5P_FIMV_SI_CH0_SB_ST_ADR);
312 mfc_write(dev, ctx->dec_src_buf_size, S5P_FIMV_SI_CH0_CPB_SIZE);
313 mfc_write(dev, buf_size, S5P_FIMV_SI_CH0_SB_FRM_SIZE);
314 s5p_mfc_write_shm(ctx, start_num_byte, START_BYTE_NUM);
315 return 0;
316}
317
318/* Set decoding frame buffer */
319int s5p_mfc_set_dec_frame_buffer(struct s5p_mfc_ctx *ctx)
320{
321 unsigned int frame_size, i;
322 unsigned int frame_size_ch, frame_size_mv;
323 struct s5p_mfc_dev *dev = ctx->dev;
324 unsigned int dpb;
325 size_t buf_addr1, buf_addr2;
326 int buf_size1, buf_size2;
327
328 buf_addr1 = ctx->bank1_phys;
329 buf_size1 = ctx->bank1_size;
330 buf_addr2 = ctx->bank2_phys;
331 buf_size2 = ctx->bank2_size;
332 dpb = mfc_read(dev, S5P_FIMV_SI_CH0_DPB_CONF_CTRL) &
333 ~S5P_FIMV_DPB_COUNT_MASK;
334 mfc_write(dev, ctx->total_dpb_count | dpb,
335 S5P_FIMV_SI_CH0_DPB_CONF_CTRL);
336 s5p_mfc_set_shared_buffer(ctx);
337 switch (ctx->codec_mode) {
338 case S5P_FIMV_CODEC_H264_DEC:
339 mfc_write(dev, OFFSETA(buf_addr1),
340 S5P_FIMV_H264_VERT_NB_MV_ADR);
341 buf_addr1 += S5P_FIMV_DEC_VERT_NB_MV_SIZE;
342 buf_size1 -= S5P_FIMV_DEC_VERT_NB_MV_SIZE;
343 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_H264_NB_IP_ADR);
344 buf_addr1 += S5P_FIMV_DEC_NB_IP_SIZE;
345 buf_size1 -= S5P_FIMV_DEC_NB_IP_SIZE;
346 break;
347 case S5P_FIMV_CODEC_MPEG4_DEC:
348 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_MPEG4_NB_DCAC_ADR);
349 buf_addr1 += S5P_FIMV_DEC_NB_DCAC_SIZE;
350 buf_size1 -= S5P_FIMV_DEC_NB_DCAC_SIZE;
351 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_MPEG4_UP_NB_MV_ADR);
352 buf_addr1 += S5P_FIMV_DEC_UPNB_MV_SIZE;
353 buf_size1 -= S5P_FIMV_DEC_UPNB_MV_SIZE;
354 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_MPEG4_SA_MV_ADR);
355 buf_addr1 += S5P_FIMV_DEC_SUB_ANCHOR_MV_SIZE;
356 buf_size1 -= S5P_FIMV_DEC_SUB_ANCHOR_MV_SIZE;
357 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_MPEG4_SP_ADR);
358 buf_addr1 += S5P_FIMV_DEC_STX_PARSER_SIZE;
359 buf_size1 -= S5P_FIMV_DEC_STX_PARSER_SIZE;
360 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_MPEG4_OT_LINE_ADR);
361 buf_addr1 += S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE;
362 buf_size1 -= S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE;
363 break;
364 case S5P_FIMV_CODEC_H263_DEC:
365 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_H263_OT_LINE_ADR);
366 buf_addr1 += S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE;
367 buf_size1 -= S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE;
368 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_H263_UP_NB_MV_ADR);
369 buf_addr1 += S5P_FIMV_DEC_UPNB_MV_SIZE;
370 buf_size1 -= S5P_FIMV_DEC_UPNB_MV_SIZE;
371 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_H263_SA_MV_ADR);
372 buf_addr1 += S5P_FIMV_DEC_SUB_ANCHOR_MV_SIZE;
373 buf_size1 -= S5P_FIMV_DEC_SUB_ANCHOR_MV_SIZE;
374 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_H263_NB_DCAC_ADR);
375 buf_addr1 += S5P_FIMV_DEC_NB_DCAC_SIZE;
376 buf_size1 -= S5P_FIMV_DEC_NB_DCAC_SIZE;
377 break;
378 case S5P_FIMV_CODEC_VC1_DEC:
379 case S5P_FIMV_CODEC_VC1RCV_DEC:
380 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_VC1_NB_DCAC_ADR);
381 buf_addr1 += S5P_FIMV_DEC_NB_DCAC_SIZE;
382 buf_size1 -= S5P_FIMV_DEC_NB_DCAC_SIZE;
383 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_VC1_OT_LINE_ADR);
384 buf_addr1 += S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE;
385 buf_size1 -= S5P_FIMV_DEC_OVERLAP_TRANSFORM_SIZE;
386 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_VC1_UP_NB_MV_ADR);
387 buf_addr1 += S5P_FIMV_DEC_UPNB_MV_SIZE;
388 buf_size1 -= S5P_FIMV_DEC_UPNB_MV_SIZE;
389 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_VC1_SA_MV_ADR);
390 buf_addr1 += S5P_FIMV_DEC_SUB_ANCHOR_MV_SIZE;
391 buf_size1 -= S5P_FIMV_DEC_SUB_ANCHOR_MV_SIZE;
392 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_VC1_BITPLANE3_ADR);
393 buf_addr1 += S5P_FIMV_DEC_VC1_BITPLANE_SIZE;
394 buf_size1 -= S5P_FIMV_DEC_VC1_BITPLANE_SIZE;
395 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_VC1_BITPLANE2_ADR);
396 buf_addr1 += S5P_FIMV_DEC_VC1_BITPLANE_SIZE;
397 buf_size1 -= S5P_FIMV_DEC_VC1_BITPLANE_SIZE;
398 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_VC1_BITPLANE1_ADR);
399 buf_addr1 += S5P_FIMV_DEC_VC1_BITPLANE_SIZE;
400 buf_size1 -= S5P_FIMV_DEC_VC1_BITPLANE_SIZE;
401 break;
402 case S5P_FIMV_CODEC_MPEG2_DEC:
403 break;
404 default:
405 mfc_err("Unknown codec for decoding (%x)\n",
406 ctx->codec_mode);
407 return -EINVAL;
408 break;
409 }
410 frame_size = ctx->luma_size;
411 frame_size_ch = ctx->chroma_size;
412 frame_size_mv = ctx->mv_size;
413 mfc_debug(2, "Frm size: %d ch: %d mv: %d\n", frame_size, frame_size_ch,
414 frame_size_mv);
415 for (i = 0; i < ctx->total_dpb_count; i++) {
416 /* Bank2 */
417 mfc_debug(2, "Luma %d: %x\n", i,
418 ctx->dst_bufs[i].cookie.raw.luma);
419 mfc_write(dev, OFFSETB(ctx->dst_bufs[i].cookie.raw.luma),
420 S5P_FIMV_DEC_LUMA_ADR + i * 4);
421 mfc_debug(2, "\tChroma %d: %x\n", i,
422 ctx->dst_bufs[i].cookie.raw.chroma);
423 mfc_write(dev, OFFSETA(ctx->dst_bufs[i].cookie.raw.chroma),
424 S5P_FIMV_DEC_CHROMA_ADR + i * 4);
425 if (ctx->codec_mode == S5P_FIMV_CODEC_H264_DEC) {
426 mfc_debug(2, "\tBuf2: %x, size: %d\n",
427 buf_addr2, buf_size2);
428 mfc_write(dev, OFFSETB(buf_addr2),
429 S5P_FIMV_H264_MV_ADR + i * 4);
430 buf_addr2 += frame_size_mv;
431 buf_size2 -= frame_size_mv;
432 }
433 }
434 mfc_debug(2, "Buf1: %u, buf_size1: %d\n", buf_addr1, buf_size1);
435 mfc_debug(2, "Buf 1/2 size after: %d/%d (frames %d)\n",
436 buf_size1, buf_size2, ctx->total_dpb_count);
437 if (buf_size1 < 0 || buf_size2 < 0) {
438 mfc_debug(2, "Not enough memory has been allocated\n");
439 return -ENOMEM;
440 }
441 s5p_mfc_write_shm(ctx, frame_size, ALLOC_LUMA_DPB_SIZE);
442 s5p_mfc_write_shm(ctx, frame_size_ch, ALLOC_CHROMA_DPB_SIZE);
443 if (ctx->codec_mode == S5P_FIMV_CODEC_H264_DEC)
444 s5p_mfc_write_shm(ctx, frame_size_mv, ALLOC_MV_SIZE);
445 mfc_write(dev, ((S5P_FIMV_CH_INIT_BUFS & S5P_FIMV_CH_MASK)
446 << S5P_FIMV_CH_SHIFT) | (ctx->inst_no),
447 S5P_FIMV_SI_CH0_INST_ID);
448 return 0;
449}
450
451/* Set registers for encoding stream buffer */
452int s5p_mfc_set_enc_stream_buffer(struct s5p_mfc_ctx *ctx,
453 unsigned long addr, unsigned int size)
454{
455 struct s5p_mfc_dev *dev = ctx->dev;
456
457 mfc_write(dev, OFFSETA(addr), S5P_FIMV_ENC_SI_CH0_SB_ADR);
458 mfc_write(dev, size, S5P_FIMV_ENC_SI_CH0_SB_SIZE);
459 return 0;
460}
461
462void s5p_mfc_set_enc_frame_buffer(struct s5p_mfc_ctx *ctx,
463 unsigned long y_addr, unsigned long c_addr)
464{
465 struct s5p_mfc_dev *dev = ctx->dev;
466
467 mfc_write(dev, OFFSETB(y_addr), S5P_FIMV_ENC_SI_CH0_CUR_Y_ADR);
468 mfc_write(dev, OFFSETB(c_addr), S5P_FIMV_ENC_SI_CH0_CUR_C_ADR);
469}
470
471void s5p_mfc_get_enc_frame_buffer(struct s5p_mfc_ctx *ctx,
472 unsigned long *y_addr, unsigned long *c_addr)
473{
474 struct s5p_mfc_dev *dev = ctx->dev;
475
476 *y_addr = dev->bank2 + (mfc_read(dev, S5P_FIMV_ENCODED_Y_ADDR)
477 << MFC_OFFSET_SHIFT);
478 *c_addr = dev->bank2 + (mfc_read(dev, S5P_FIMV_ENCODED_C_ADDR)
479 << MFC_OFFSET_SHIFT);
480}
481
482/* Set encoding ref & codec buffer */
483int s5p_mfc_set_enc_ref_buffer(struct s5p_mfc_ctx *ctx)
484{
485 struct s5p_mfc_dev *dev = ctx->dev;
486 size_t buf_addr1, buf_addr2;
487 size_t buf_size1, buf_size2;
488 unsigned int enc_ref_y_size, enc_ref_c_size;
489 unsigned int guard_width, guard_height;
490 int i;
491
492 buf_addr1 = ctx->bank1_phys;
493 buf_size1 = ctx->bank1_size;
494 buf_addr2 = ctx->bank2_phys;
495 buf_size2 = ctx->bank2_size;
496 enc_ref_y_size = ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN)
497 * ALIGN(ctx->img_height, S5P_FIMV_NV12MT_VALIGN);
498 enc_ref_y_size = ALIGN(enc_ref_y_size, S5P_FIMV_NV12MT_SALIGN);
499 if (ctx->codec_mode == S5P_FIMV_CODEC_H264_ENC) {
500 enc_ref_c_size = ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN)
501 * ALIGN((ctx->img_height >> 1), S5P_FIMV_NV12MT_VALIGN);
502 enc_ref_c_size = ALIGN(enc_ref_c_size, S5P_FIMV_NV12MT_SALIGN);
503 } else {
504 guard_width = ALIGN(ctx->img_width + 16,
505 S5P_FIMV_NV12MT_HALIGN);
506 guard_height = ALIGN((ctx->img_height >> 1) + 4,
507 S5P_FIMV_NV12MT_VALIGN);
508 enc_ref_c_size = ALIGN(guard_width * guard_height,
509 S5P_FIMV_NV12MT_SALIGN);
510 }
511 mfc_debug(2, "buf_size1: %d, buf_size2: %d\n", buf_size1, buf_size2);
512 switch (ctx->codec_mode) {
513 case S5P_FIMV_CODEC_H264_ENC:
514 for (i = 0; i < 2; i++) {
515 mfc_write(dev, OFFSETA(buf_addr1),
516 S5P_FIMV_ENC_REF0_LUMA_ADR + (4 * i));
517 buf_addr1 += enc_ref_y_size;
518 buf_size1 -= enc_ref_y_size;
519
520 mfc_write(dev, OFFSETB(buf_addr2),
521 S5P_FIMV_ENC_REF2_LUMA_ADR + (4 * i));
522 buf_addr2 += enc_ref_y_size;
523 buf_size2 -= enc_ref_y_size;
524 }
525 for (i = 0; i < 4; i++) {
526 mfc_write(dev, OFFSETB(buf_addr2),
527 S5P_FIMV_ENC_REF0_CHROMA_ADR + (4 * i));
528 buf_addr2 += enc_ref_c_size;
529 buf_size2 -= enc_ref_c_size;
530 }
531 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_H264_UP_MV_ADR);
532 buf_addr1 += S5P_FIMV_ENC_UPMV_SIZE;
533 buf_size1 -= S5P_FIMV_ENC_UPMV_SIZE;
534 mfc_write(dev, OFFSETA(buf_addr1),
535 S5P_FIMV_H264_COZERO_FLAG_ADR);
536 buf_addr1 += S5P_FIMV_ENC_COLFLG_SIZE;
537 buf_size1 -= S5P_FIMV_ENC_COLFLG_SIZE;
538 mfc_write(dev, OFFSETA(buf_addr1),
539 S5P_FIMV_H264_UP_INTRA_MD_ADR);
540 buf_addr1 += S5P_FIMV_ENC_INTRAMD_SIZE;
541 buf_size1 -= S5P_FIMV_ENC_INTRAMD_SIZE;
542 mfc_write(dev, OFFSETB(buf_addr2),
543 S5P_FIMV_H264_UP_INTRA_PRED_ADR);
544 buf_addr2 += S5P_FIMV_ENC_INTRAPRED_SIZE;
545 buf_size2 -= S5P_FIMV_ENC_INTRAPRED_SIZE;
546 mfc_write(dev, OFFSETA(buf_addr1),
547 S5P_FIMV_H264_NBOR_INFO_ADR);
548 buf_addr1 += S5P_FIMV_ENC_NBORINFO_SIZE;
549 buf_size1 -= S5P_FIMV_ENC_NBORINFO_SIZE;
550 mfc_debug(2, "buf_size1: %d, buf_size2: %d\n",
551 buf_size1, buf_size2);
552 break;
553 case S5P_FIMV_CODEC_MPEG4_ENC:
554 for (i = 0; i < 2; i++) {
555 mfc_write(dev, OFFSETA(buf_addr1),
556 S5P_FIMV_ENC_REF0_LUMA_ADR + (4 * i));
557 buf_addr1 += enc_ref_y_size;
558 buf_size1 -= enc_ref_y_size;
559 mfc_write(dev, OFFSETB(buf_addr2),
560 S5P_FIMV_ENC_REF2_LUMA_ADR + (4 * i));
561 buf_addr2 += enc_ref_y_size;
562 buf_size2 -= enc_ref_y_size;
563 }
564 for (i = 0; i < 4; i++) {
565 mfc_write(dev, OFFSETB(buf_addr2),
566 S5P_FIMV_ENC_REF0_CHROMA_ADR + (4 * i));
567 buf_addr2 += enc_ref_c_size;
568 buf_size2 -= enc_ref_c_size;
569 }
570 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_MPEG4_UP_MV_ADR);
571 buf_addr1 += S5P_FIMV_ENC_UPMV_SIZE;
572 buf_size1 -= S5P_FIMV_ENC_UPMV_SIZE;
573 mfc_write(dev, OFFSETA(buf_addr1),
574 S5P_FIMV_MPEG4_COZERO_FLAG_ADR);
575 buf_addr1 += S5P_FIMV_ENC_COLFLG_SIZE;
576 buf_size1 -= S5P_FIMV_ENC_COLFLG_SIZE;
577 mfc_write(dev, OFFSETA(buf_addr1),
578 S5P_FIMV_MPEG4_ACDC_COEF_ADR);
579 buf_addr1 += S5P_FIMV_ENC_ACDCCOEF_SIZE;
580 buf_size1 -= S5P_FIMV_ENC_ACDCCOEF_SIZE;
581 mfc_debug(2, "buf_size1: %d, buf_size2: %d\n",
582 buf_size1, buf_size2);
583 break;
584 case S5P_FIMV_CODEC_H263_ENC:
585 for (i = 0; i < 2; i++) {
586 mfc_write(dev, OFFSETA(buf_addr1),
587 S5P_FIMV_ENC_REF0_LUMA_ADR + (4 * i));
588 buf_addr1 += enc_ref_y_size;
589 buf_size1 -= enc_ref_y_size;
590 mfc_write(dev, OFFSETB(buf_addr2),
591 S5P_FIMV_ENC_REF2_LUMA_ADR + (4 * i));
592 buf_addr2 += enc_ref_y_size;
593 buf_size2 -= enc_ref_y_size;
594 }
595 for (i = 0; i < 4; i++) {
596 mfc_write(dev, OFFSETB(buf_addr2),
597 S5P_FIMV_ENC_REF0_CHROMA_ADR + (4 * i));
598 buf_addr2 += enc_ref_c_size;
599 buf_size2 -= enc_ref_c_size;
600 }
601 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_H263_UP_MV_ADR);
602 buf_addr1 += S5P_FIMV_ENC_UPMV_SIZE;
603 buf_size1 -= S5P_FIMV_ENC_UPMV_SIZE;
604 mfc_write(dev, OFFSETA(buf_addr1), S5P_FIMV_H263_ACDC_COEF_ADR);
605 buf_addr1 += S5P_FIMV_ENC_ACDCCOEF_SIZE;
606 buf_size1 -= S5P_FIMV_ENC_ACDCCOEF_SIZE;
607 mfc_debug(2, "buf_size1: %d, buf_size2: %d\n",
608 buf_size1, buf_size2);
609 break;
610 default:
611 mfc_err("Unknown codec set for encoding: %d\n",
612 ctx->codec_mode);
613 return -EINVAL;
614 }
615 return 0;
616}
617
618static int s5p_mfc_set_enc_params(struct s5p_mfc_ctx *ctx)
619{
620 struct s5p_mfc_dev *dev = ctx->dev;
621 struct s5p_mfc_enc_params *p = &ctx->enc_params;
622 unsigned int reg;
623 unsigned int shm;
624
625 /* width */
626 mfc_write(dev, ctx->img_width, S5P_FIMV_ENC_HSIZE_PX);
627 /* height */
628 mfc_write(dev, ctx->img_height, S5P_FIMV_ENC_VSIZE_PX);
629 /* pictype : enable, IDR period */
630 reg = mfc_read(dev, S5P_FIMV_ENC_PIC_TYPE_CTRL);
631 reg |= (1 << 18);
632 reg &= ~(0xFFFF);
633 reg |= p->gop_size;
634 mfc_write(dev, reg, S5P_FIMV_ENC_PIC_TYPE_CTRL);
635 mfc_write(dev, 0, S5P_FIMV_ENC_B_RECON_WRITE_ON);
636 /* multi-slice control */
637 /* multi-slice MB number or bit size */
638 mfc_write(dev, p->slice_mode, S5P_FIMV_ENC_MSLICE_CTRL);
639 if (p->slice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB) {
640 mfc_write(dev, p->slice_mb, S5P_FIMV_ENC_MSLICE_MB);
641 } else if (p->slice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES) {
642 mfc_write(dev, p->slice_bit, S5P_FIMV_ENC_MSLICE_BIT);
643 } else {
644 mfc_write(dev, 0, S5P_FIMV_ENC_MSLICE_MB);
645 mfc_write(dev, 0, S5P_FIMV_ENC_MSLICE_BIT);
646 }
647 /* cyclic intra refresh */
648 mfc_write(dev, p->intra_refresh_mb, S5P_FIMV_ENC_CIR_CTRL);
649 /* memory structure cur. frame */
650 if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12M)
651 mfc_write(dev, 0, S5P_FIMV_ENC_MAP_FOR_CUR);
652 else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12MT)
653 mfc_write(dev, 3, S5P_FIMV_ENC_MAP_FOR_CUR);
654 /* padding control & value */
655 reg = mfc_read(dev, S5P_FIMV_ENC_PADDING_CTRL);
656 if (p->pad) {
657 /** enable */
658 reg |= (1 << 31);
659 /** cr value */
660 reg &= ~(0xFF << 16);
661 reg |= (p->pad_cr << 16);
662 /** cb value */
663 reg &= ~(0xFF << 8);
664 reg |= (p->pad_cb << 8);
665 /** y value */
666 reg &= ~(0xFF);
667 reg |= (p->pad_luma);
668 } else {
669 /** disable & all value clear */
670 reg = 0;
671 }
672 mfc_write(dev, reg, S5P_FIMV_ENC_PADDING_CTRL);
673 /* rate control config. */
674 reg = mfc_read(dev, S5P_FIMV_ENC_RC_CONFIG);
675 /** frame-level rate control */
676 reg &= ~(0x1 << 9);
677 reg |= (p->rc_frame << 9);
678 mfc_write(dev, reg, S5P_FIMV_ENC_RC_CONFIG);
679 /* bit rate */
680 if (p->rc_frame)
681 mfc_write(dev, p->rc_bitrate,
682 S5P_FIMV_ENC_RC_BIT_RATE);
683 else
684 mfc_write(dev, 0, S5P_FIMV_ENC_RC_BIT_RATE);
685 /* reaction coefficient */
686 if (p->rc_frame)
687 mfc_write(dev, p->rc_reaction_coeff, S5P_FIMV_ENC_RC_RPARA);
688 shm = s5p_mfc_read_shm(ctx, EXT_ENC_CONTROL);
689 /* seq header ctrl */
690 shm &= ~(0x1 << 3);
691 shm |= (p->seq_hdr_mode << 3);
692 /* frame skip mode */
693 shm &= ~(0x3 << 1);
694 shm |= (p->frame_skip_mode << 1);
695 s5p_mfc_write_shm(ctx, shm, EXT_ENC_CONTROL);
696 /* fixed target bit */
697 s5p_mfc_write_shm(ctx, p->fixed_target_bit, RC_CONTROL_CONFIG);
698 return 0;
699}
700
701static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx)
702{
703 struct s5p_mfc_dev *dev = ctx->dev;
704 struct s5p_mfc_enc_params *p = &ctx->enc_params;
705 struct s5p_mfc_h264_enc_params *p_264 = &p->codec.h264;
706 unsigned int reg;
707 unsigned int shm;
708
709 s5p_mfc_set_enc_params(ctx);
710 /* pictype : number of B */
711 reg = mfc_read(dev, S5P_FIMV_ENC_PIC_TYPE_CTRL);
712 /* num_b_frame - 0 ~ 2 */
713 reg &= ~(0x3 << 16);
714 reg |= (p->num_b_frame << 16);
715 mfc_write(dev, reg, S5P_FIMV_ENC_PIC_TYPE_CTRL);
716 /* profile & level */
717 reg = mfc_read(dev, S5P_FIMV_ENC_PROFILE);
718 /* level */
719 reg &= ~(0xFF << 8);
720 reg |= (p_264->level << 8);
721 /* profile - 0 ~ 2 */
722 reg &= ~(0x3F);
723 reg |= p_264->profile;
724 mfc_write(dev, reg, S5P_FIMV_ENC_PROFILE);
725 /* interlace */
726 mfc_write(dev, p->interlace, S5P_FIMV_ENC_PIC_STRUCT);
727 /* height */
728 if (p->interlace)
729 mfc_write(dev, ctx->img_height >> 1, S5P_FIMV_ENC_VSIZE_PX);
730 /* loopfilter ctrl */
731 mfc_write(dev, p_264->loop_filter_mode, S5P_FIMV_ENC_LF_CTRL);
732 /* loopfilter alpha offset */
733 if (p_264->loop_filter_alpha < 0) {
734 reg = 0x10;
735 reg |= (0xFF - p_264->loop_filter_alpha) + 1;
736 } else {
737 reg = 0x00;
738 reg |= (p_264->loop_filter_alpha & 0xF);
739 }
740 mfc_write(dev, reg, S5P_FIMV_ENC_ALPHA_OFF);
741 /* loopfilter beta offset */
742 if (p_264->loop_filter_beta < 0) {
743 reg = 0x10;
744 reg |= (0xFF - p_264->loop_filter_beta) + 1;
745 } else {
746 reg = 0x00;
747 reg |= (p_264->loop_filter_beta & 0xF);
748 }
749 mfc_write(dev, reg, S5P_FIMV_ENC_BETA_OFF);
750 /* entropy coding mode */
751 if (p_264->entropy_mode == V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC)
752 mfc_write(dev, 1, S5P_FIMV_ENC_H264_ENTROPY_MODE);
753 else
754 mfc_write(dev, 0, S5P_FIMV_ENC_H264_ENTROPY_MODE);
755 /* number of ref. picture */
756 reg = mfc_read(dev, S5P_FIMV_ENC_H264_NUM_OF_REF);
757 /* num of ref. pictures of P */
758 reg &= ~(0x3 << 5);
759 reg |= (p_264->num_ref_pic_4p << 5);
760 /* max number of ref. pictures */
761 reg &= ~(0x1F);
762 reg |= p_264->max_ref_pic;
763 mfc_write(dev, reg, S5P_FIMV_ENC_H264_NUM_OF_REF);
764 /* 8x8 transform enable */
765 mfc_write(dev, p_264->_8x8_transform, S5P_FIMV_ENC_H264_TRANS_FLAG);
766 /* rate control config. */
767 reg = mfc_read(dev, S5P_FIMV_ENC_RC_CONFIG);
768 /* macroblock level rate control */
769 reg &= ~(0x1 << 8);
770 reg |= (p_264->rc_mb << 8);
771 /* frame QP */
772 reg &= ~(0x3F);
773 reg |= p_264->rc_frame_qp;
774 mfc_write(dev, reg, S5P_FIMV_ENC_RC_CONFIG);
775 /* frame rate */
776 if (p->rc_frame && p->rc_framerate_denom)
777 mfc_write(dev, p->rc_framerate_num * 1000
778 / p->rc_framerate_denom, S5P_FIMV_ENC_RC_FRAME_RATE);
779 else
780 mfc_write(dev, 0, S5P_FIMV_ENC_RC_FRAME_RATE);
781 /* max & min value of QP */
782 reg = mfc_read(dev, S5P_FIMV_ENC_RC_QBOUND);
783 /* max QP */
784 reg &= ~(0x3F << 8);
785 reg |= (p_264->rc_max_qp << 8);
786 /* min QP */
787 reg &= ~(0x3F);
788 reg |= p_264->rc_min_qp;
789 mfc_write(dev, reg, S5P_FIMV_ENC_RC_QBOUND);
790 /* macroblock adaptive scaling features */
791 if (p_264->rc_mb) {
792 reg = mfc_read(dev, S5P_FIMV_ENC_RC_MB_CTRL);
793 /* dark region */
794 reg &= ~(0x1 << 3);
795 reg |= (p_264->rc_mb_dark << 3);
796 /* smooth region */
797 reg &= ~(0x1 << 2);
798 reg |= (p_264->rc_mb_smooth << 2);
799 /* static region */
800 reg &= ~(0x1 << 1);
801 reg |= (p_264->rc_mb_static << 1);
802 /* high activity region */
803 reg &= ~(0x1);
804 reg |= p_264->rc_mb_activity;
805 mfc_write(dev, reg, S5P_FIMV_ENC_RC_MB_CTRL);
806 }
807 if (!p->rc_frame &&
808 !p_264->rc_mb) {
809 shm = s5p_mfc_read_shm(ctx, P_B_FRAME_QP);
810 shm &= ~(0xFFF);
811 shm |= ((p_264->rc_b_frame_qp & 0x3F) << 6);
812 shm |= (p_264->rc_p_frame_qp & 0x3F);
813 s5p_mfc_write_shm(ctx, shm, P_B_FRAME_QP);
814 }
815 /* extended encoder ctrl */
816 shm = s5p_mfc_read_shm(ctx, EXT_ENC_CONTROL);
817 /* AR VUI control */
818 shm &= ~(0x1 << 15);
819 shm |= (p_264->vui_sar << 1);
820 s5p_mfc_write_shm(ctx, shm, EXT_ENC_CONTROL);
821 if (p_264->vui_sar) {
822 /* aspect ration IDC */
823 shm = s5p_mfc_read_shm(ctx, SAMPLE_ASPECT_RATIO_IDC);
824 shm &= ~(0xFF);
825 shm |= p_264->vui_sar_idc;
826 s5p_mfc_write_shm(ctx, shm, SAMPLE_ASPECT_RATIO_IDC);
827 if (p_264->vui_sar_idc == 0xFF) {
828 /* sample AR info */
829 shm = s5p_mfc_read_shm(ctx, EXTENDED_SAR);
830 shm &= ~(0xFFFFFFFF);
831 shm |= p_264->vui_ext_sar_width << 16;
832 shm |= p_264->vui_ext_sar_height;
833 s5p_mfc_write_shm(ctx, shm, EXTENDED_SAR);
834 }
835 }
836 /* intra picture period for H.264 */
837 shm = s5p_mfc_read_shm(ctx, H264_I_PERIOD);
838 /* control */
839 shm &= ~(0x1 << 16);
840 shm |= (p_264->open_gop << 16);
841 /* value */
842 if (p_264->open_gop) {
843 shm &= ~(0xFFFF);
844 shm |= p_264->open_gop_size;
845 }
846 s5p_mfc_write_shm(ctx, shm, H264_I_PERIOD);
847 /* extended encoder ctrl */
848 shm = s5p_mfc_read_shm(ctx, EXT_ENC_CONTROL);
849 /* vbv buffer size */
850 if (p->frame_skip_mode ==
851 V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT) {
852 shm &= ~(0xFFFF << 16);
853 shm |= (p_264->cpb_size << 16);
854 }
855 s5p_mfc_write_shm(ctx, shm, EXT_ENC_CONTROL);
856 return 0;
857}
858
859static int s5p_mfc_set_enc_params_mpeg4(struct s5p_mfc_ctx *ctx)
860{
861 struct s5p_mfc_dev *dev = ctx->dev;
862 struct s5p_mfc_enc_params *p = &ctx->enc_params;
863 struct s5p_mfc_mpeg4_enc_params *p_mpeg4 = &p->codec.mpeg4;
864 unsigned int reg;
865 unsigned int shm;
866 unsigned int framerate;
867
868 s5p_mfc_set_enc_params(ctx);
869 /* pictype : number of B */
870 reg = mfc_read(dev, S5P_FIMV_ENC_PIC_TYPE_CTRL);
871 /* num_b_frame - 0 ~ 2 */
872 reg &= ~(0x3 << 16);
873 reg |= (p->num_b_frame << 16);
874 mfc_write(dev, reg, S5P_FIMV_ENC_PIC_TYPE_CTRL);
875 /* profile & level */
876 reg = mfc_read(dev, S5P_FIMV_ENC_PROFILE);
877 /* level */
878 reg &= ~(0xFF << 8);
879 reg |= (p_mpeg4->level << 8);
880 /* profile - 0 ~ 2 */
881 reg &= ~(0x3F);
882 reg |= p_mpeg4->profile;
883 mfc_write(dev, reg, S5P_FIMV_ENC_PROFILE);
884 /* quarter_pixel */
885 mfc_write(dev, p_mpeg4->quarter_pixel, S5P_FIMV_ENC_MPEG4_QUART_PXL);
886 /* qp */
887 if (!p->rc_frame) {
888 shm = s5p_mfc_read_shm(ctx, P_B_FRAME_QP);
889 shm &= ~(0xFFF);
890 shm |= ((p_mpeg4->rc_b_frame_qp & 0x3F) << 6);
891 shm |= (p_mpeg4->rc_p_frame_qp & 0x3F);
892 s5p_mfc_write_shm(ctx, shm, P_B_FRAME_QP);
893 }
894 /* frame rate */
895 if (p->rc_frame) {
896 if (p->rc_framerate_denom > 0) {
897 framerate = p->rc_framerate_num * 1000 /
898 p->rc_framerate_denom;
899 mfc_write(dev, framerate,
900 S5P_FIMV_ENC_RC_FRAME_RATE);
901 shm = s5p_mfc_read_shm(ctx, RC_VOP_TIMING);
902 shm &= ~(0xFFFFFFFF);
903 shm |= (1 << 31);
904 shm |= ((p->rc_framerate_num & 0x7FFF) << 16);
905 shm |= (p->rc_framerate_denom & 0xFFFF);
906 s5p_mfc_write_shm(ctx, shm, RC_VOP_TIMING);
907 }
908 } else {
909 mfc_write(dev, 0, S5P_FIMV_ENC_RC_FRAME_RATE);
910 }
911 /* rate control config. */
912 reg = mfc_read(dev, S5P_FIMV_ENC_RC_CONFIG);
913 /* frame QP */
914 reg &= ~(0x3F);
915 reg |= p_mpeg4->rc_frame_qp;
916 mfc_write(dev, reg, S5P_FIMV_ENC_RC_CONFIG);
917 /* max & min value of QP */
918 reg = mfc_read(dev, S5P_FIMV_ENC_RC_QBOUND);
919 /* max QP */
920 reg &= ~(0x3F << 8);
921 reg |= (p_mpeg4->rc_max_qp << 8);
922 /* min QP */
923 reg &= ~(0x3F);
924 reg |= p_mpeg4->rc_min_qp;
925 mfc_write(dev, reg, S5P_FIMV_ENC_RC_QBOUND);
926 /* extended encoder ctrl */
927 shm = s5p_mfc_read_shm(ctx, EXT_ENC_CONTROL);
928 /* vbv buffer size */
929 if (p->frame_skip_mode ==
930 V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT) {
931 shm &= ~(0xFFFF << 16);
932 shm |= (p->vbv_size << 16);
933 }
934 s5p_mfc_write_shm(ctx, shm, EXT_ENC_CONTROL);
935 return 0;
936}
937
938static int s5p_mfc_set_enc_params_h263(struct s5p_mfc_ctx *ctx)
939{
940 struct s5p_mfc_dev *dev = ctx->dev;
941 struct s5p_mfc_enc_params *p = &ctx->enc_params;
942 struct s5p_mfc_mpeg4_enc_params *p_h263 = &p->codec.mpeg4;
943 unsigned int reg;
944 unsigned int shm;
945
946 s5p_mfc_set_enc_params(ctx);
947 /* qp */
948 if (!p->rc_frame) {
949 shm = s5p_mfc_read_shm(ctx, P_B_FRAME_QP);
950 shm &= ~(0xFFF);
951 shm |= (p_h263->rc_p_frame_qp & 0x3F);
952 s5p_mfc_write_shm(ctx, shm, P_B_FRAME_QP);
953 }
954 /* frame rate */
955 if (p->rc_frame && p->rc_framerate_denom)
956 mfc_write(dev, p->rc_framerate_num * 1000
957 / p->rc_framerate_denom, S5P_FIMV_ENC_RC_FRAME_RATE);
958 else
959 mfc_write(dev, 0, S5P_FIMV_ENC_RC_FRAME_RATE);
960 /* rate control config. */
961 reg = mfc_read(dev, S5P_FIMV_ENC_RC_CONFIG);
962 /* frame QP */
963 reg &= ~(0x3F);
964 reg |= p_h263->rc_frame_qp;
965 mfc_write(dev, reg, S5P_FIMV_ENC_RC_CONFIG);
966 /* max & min value of QP */
967 reg = mfc_read(dev, S5P_FIMV_ENC_RC_QBOUND);
968 /* max QP */
969 reg &= ~(0x3F << 8);
970 reg |= (p_h263->rc_max_qp << 8);
971 /* min QP */
972 reg &= ~(0x3F);
973 reg |= p_h263->rc_min_qp;
974 mfc_write(dev, reg, S5P_FIMV_ENC_RC_QBOUND);
975 /* extended encoder ctrl */
976 shm = s5p_mfc_read_shm(ctx, EXT_ENC_CONTROL);
977 /* vbv buffer size */
978 if (p->frame_skip_mode ==
979 V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT) {
980 shm &= ~(0xFFFF << 16);
981 shm |= (p->vbv_size << 16);
982 }
983 s5p_mfc_write_shm(ctx, shm, EXT_ENC_CONTROL);
984 return 0;
985}
986
987/* Initialize decoding */
988int s5p_mfc_init_decode(struct s5p_mfc_ctx *ctx)
989{
990 struct s5p_mfc_dev *dev = ctx->dev;
991
992 s5p_mfc_set_shared_buffer(ctx);
993 /* Setup loop filter, for decoding this is only valid for MPEG4 */
994 if (ctx->codec_mode == S5P_FIMV_CODEC_MPEG4_DEC)
995 mfc_write(dev, ctx->loop_filter_mpeg4, S5P_FIMV_ENC_LF_CTRL);
996 else
997 mfc_write(dev, 0, S5P_FIMV_ENC_LF_CTRL);
998 mfc_write(dev, ((ctx->slice_interface & S5P_FIMV_SLICE_INT_MASK) <<
999 S5P_FIMV_SLICE_INT_SHIFT) | (ctx->display_delay_enable <<
1000 S5P_FIMV_DDELAY_ENA_SHIFT) | ((ctx->display_delay &
1001 S5P_FIMV_DDELAY_VAL_MASK) << S5P_FIMV_DDELAY_VAL_SHIFT),
1002 S5P_FIMV_SI_CH0_DPB_CONF_CTRL);
1003 mfc_write(dev,
1004 ((S5P_FIMV_CH_SEQ_HEADER & S5P_FIMV_CH_MASK) << S5P_FIMV_CH_SHIFT)
1005 | (ctx->inst_no), S5P_FIMV_SI_CH0_INST_ID);
1006 return 0;
1007}
1008
1009static void s5p_mfc_set_flush(struct s5p_mfc_ctx *ctx, int flush)
1010{
1011 struct s5p_mfc_dev *dev = ctx->dev;
1012 unsigned int dpb;
1013
1014 if (flush)
1015 dpb = mfc_read(dev, S5P_FIMV_SI_CH0_DPB_CONF_CTRL) | (
1016 S5P_FIMV_DPB_FLUSH_MASK << S5P_FIMV_DPB_FLUSH_SHIFT);
1017 else
1018 dpb = mfc_read(dev, S5P_FIMV_SI_CH0_DPB_CONF_CTRL) &
1019 ~(S5P_FIMV_DPB_FLUSH_MASK << S5P_FIMV_DPB_FLUSH_SHIFT);
1020 mfc_write(dev, dpb, S5P_FIMV_SI_CH0_DPB_CONF_CTRL);
1021}
1022
1023/* Decode a single frame */
1024int s5p_mfc_decode_one_frame(struct s5p_mfc_ctx *ctx,
1025 enum s5p_mfc_decode_arg last_frame)
1026{
1027 struct s5p_mfc_dev *dev = ctx->dev;
1028
1029 mfc_write(dev, ctx->dec_dst_flag, S5P_FIMV_SI_CH0_RELEASE_BUF);
1030 s5p_mfc_set_shared_buffer(ctx);
1031 s5p_mfc_set_flush(ctx, ctx->dpb_flush_flag);
1032 /* Issue different commands to instance basing on whether it
1033 * is the last frame or not. */
1034 switch (last_frame) {
1035 case MFC_DEC_FRAME:
1036 mfc_write(dev, ((S5P_FIMV_CH_FRAME_START & S5P_FIMV_CH_MASK) <<
1037 S5P_FIMV_CH_SHIFT) | (ctx->inst_no), S5P_FIMV_SI_CH0_INST_ID);
1038 break;
1039 case MFC_DEC_LAST_FRAME:
1040 mfc_write(dev, ((S5P_FIMV_CH_LAST_FRAME & S5P_FIMV_CH_MASK) <<
1041 S5P_FIMV_CH_SHIFT) | (ctx->inst_no), S5P_FIMV_SI_CH0_INST_ID);
1042 break;
1043 case MFC_DEC_RES_CHANGE:
1044 mfc_write(dev, ((S5P_FIMV_CH_FRAME_START_REALLOC &
1045 S5P_FIMV_CH_MASK) << S5P_FIMV_CH_SHIFT) | (ctx->inst_no),
1046 S5P_FIMV_SI_CH0_INST_ID);
1047 break;
1048 }
1049 mfc_debug(2, "Decoding a usual frame\n");
1050 return 0;
1051}
1052
1053int s5p_mfc_init_encode(struct s5p_mfc_ctx *ctx)
1054{
1055 struct s5p_mfc_dev *dev = ctx->dev;
1056
1057 if (ctx->codec_mode == S5P_FIMV_CODEC_H264_ENC)
1058 s5p_mfc_set_enc_params_h264(ctx);
1059 else if (ctx->codec_mode == S5P_FIMV_CODEC_MPEG4_ENC)
1060 s5p_mfc_set_enc_params_mpeg4(ctx);
1061 else if (ctx->codec_mode == S5P_FIMV_CODEC_H263_ENC)
1062 s5p_mfc_set_enc_params_h263(ctx);
1063 else {
1064 mfc_err("Unknown codec for encoding (%x)\n",
1065 ctx->codec_mode);
1066 return -EINVAL;
1067 }
1068 s5p_mfc_set_shared_buffer(ctx);
1069 mfc_write(dev, ((S5P_FIMV_CH_SEQ_HEADER << 16) & 0x70000) |
1070 (ctx->inst_no), S5P_FIMV_SI_CH0_INST_ID);
1071 return 0;
1072}
1073
1074/* Encode a single frame */
1075int s5p_mfc_encode_one_frame(struct s5p_mfc_ctx *ctx)
1076{
1077 struct s5p_mfc_dev *dev = ctx->dev;
1078 /* memory structure cur. frame */
1079 if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12M)
1080 mfc_write(dev, 0, S5P_FIMV_ENC_MAP_FOR_CUR);
1081 else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12MT)
1082 mfc_write(dev, 3, S5P_FIMV_ENC_MAP_FOR_CUR);
1083 s5p_mfc_set_shared_buffer(ctx);
1084 mfc_write(dev, (S5P_FIMV_CH_FRAME_START << 16 & 0x70000) |
1085 (ctx->inst_no), S5P_FIMV_SI_CH0_INST_ID);
1086 return 0;
1087}
1088
1089static int s5p_mfc_get_new_ctx(struct s5p_mfc_dev *dev)
1090{
1091 unsigned long flags;
1092 int new_ctx;
1093 int cnt;
1094
1095 spin_lock_irqsave(&dev->condlock, flags);
1096 new_ctx = (dev->curr_ctx + 1) % MFC_NUM_CONTEXTS;
1097 cnt = 0;
1098 while (!test_bit(new_ctx, &dev->ctx_work_bits)) {
1099 new_ctx = (new_ctx + 1) % MFC_NUM_CONTEXTS;
1100 if (++cnt > MFC_NUM_CONTEXTS) {
1101 /* No contexts to run */
1102 spin_unlock_irqrestore(&dev->condlock, flags);
1103 return -EAGAIN;
1104 }
1105 }
1106 spin_unlock_irqrestore(&dev->condlock, flags);
1107 return new_ctx;
1108}
1109
1110static void s5p_mfc_run_res_change(struct s5p_mfc_ctx *ctx)
1111{
1112 struct s5p_mfc_dev *dev = ctx->dev;
1113
1114 s5p_mfc_set_dec_stream_buffer(ctx, 0, 0, 0);
1115 dev->curr_ctx = ctx->num;
1116 s5p_mfc_clean_ctx_int_flags(ctx);
1117 s5p_mfc_decode_one_frame(ctx, MFC_DEC_RES_CHANGE);
1118}
1119
1120static int s5p_mfc_run_dec_frame(struct s5p_mfc_ctx *ctx, int last_frame)
1121{
1122 struct s5p_mfc_dev *dev = ctx->dev;
1123 struct s5p_mfc_buf *temp_vb;
1124 unsigned long flags;
1125 unsigned int index;
1126
1127 spin_lock_irqsave(&dev->irqlock, flags);
1128 /* Frames are being decoded */
1129 if (list_empty(&ctx->src_queue)) {
1130 mfc_debug(2, "No src buffers\n");
1131 spin_unlock_irqrestore(&dev->irqlock, flags);
1132 return -EAGAIN;
1133 }
1134 /* Get the next source buffer */
1135 temp_vb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
1136 temp_vb->used = 1;
1137 s5p_mfc_set_dec_stream_buffer(ctx,
1138 vb2_dma_contig_plane_dma_addr(temp_vb->b, 0), ctx->consumed_stream,
1139 temp_vb->b->v4l2_planes[0].bytesused);
1140 spin_unlock_irqrestore(&dev->irqlock, flags);
1141 index = temp_vb->b->v4l2_buf.index;
1142 dev->curr_ctx = ctx->num;
1143 s5p_mfc_clean_ctx_int_flags(ctx);
1144 if (temp_vb->b->v4l2_planes[0].bytesused == 0) {
1145 last_frame = MFC_DEC_LAST_FRAME;
1146 mfc_debug(2, "Setting ctx->state to FINISHING\n");
1147 ctx->state = MFCINST_FINISHING;
1148 }
1149 s5p_mfc_decode_one_frame(ctx, last_frame);
1150 return 0;
1151}
1152
1153static int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx)
1154{
1155 struct s5p_mfc_dev *dev = ctx->dev;
1156 unsigned long flags;
1157 struct s5p_mfc_buf *dst_mb;
1158 struct s5p_mfc_buf *src_mb;
1159 unsigned long src_y_addr, src_c_addr, dst_addr;
1160 unsigned int dst_size;
1161
1162 spin_lock_irqsave(&dev->irqlock, flags);
1163 if (list_empty(&ctx->src_queue)) {
1164 mfc_debug(2, "no src buffers\n");
1165 spin_unlock_irqrestore(&dev->irqlock, flags);
1166 return -EAGAIN;
1167 }
1168 if (list_empty(&ctx->dst_queue)) {
1169 mfc_debug(2, "no dst buffers\n");
1170 spin_unlock_irqrestore(&dev->irqlock, flags);
1171 return -EAGAIN;
1172 }
1173 src_mb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
1174 src_mb->used = 1;
1175 src_y_addr = vb2_dma_contig_plane_dma_addr(src_mb->b, 0);
1176 src_c_addr = vb2_dma_contig_plane_dma_addr(src_mb->b, 1);
1177 s5p_mfc_set_enc_frame_buffer(ctx, src_y_addr, src_c_addr);
1178 dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list);
1179 dst_mb->used = 1;
1180 dst_addr = vb2_dma_contig_plane_dma_addr(dst_mb->b, 0);
1181 dst_size = vb2_plane_size(dst_mb->b, 0);
1182 s5p_mfc_set_enc_stream_buffer(ctx, dst_addr, dst_size);
1183 spin_unlock_irqrestore(&dev->irqlock, flags);
1184 dev->curr_ctx = ctx->num;
1185 s5p_mfc_clean_ctx_int_flags(ctx);
1186 s5p_mfc_encode_one_frame(ctx);
1187 return 0;
1188}
1189
1190static void s5p_mfc_run_init_dec(struct s5p_mfc_ctx *ctx)
1191{
1192 struct s5p_mfc_dev *dev = ctx->dev;
1193 unsigned long flags;
1194 struct s5p_mfc_buf *temp_vb;
1195
1196 /* Initializing decoding - parsing header */
1197 spin_lock_irqsave(&dev->irqlock, flags);
1198 mfc_debug(2, "Preparing to init decoding\n");
1199 temp_vb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
1200 s5p_mfc_set_dec_desc_buffer(ctx);
1201 mfc_debug(2, "Header size: %d\n", temp_vb->b->v4l2_planes[0].bytesused);
1202 s5p_mfc_set_dec_stream_buffer(ctx,
1203 vb2_dma_contig_plane_dma_addr(temp_vb->b, 0),
1204 0, temp_vb->b->v4l2_planes[0].bytesused);
1205 spin_unlock_irqrestore(&dev->irqlock, flags);
1206 dev->curr_ctx = ctx->num;
1207 s5p_mfc_clean_ctx_int_flags(ctx);
1208 s5p_mfc_init_decode(ctx);
1209}
1210
1211static void s5p_mfc_run_init_enc(struct s5p_mfc_ctx *ctx)
1212{
1213 struct s5p_mfc_dev *dev = ctx->dev;
1214 unsigned long flags;
1215 struct s5p_mfc_buf *dst_mb;
1216 unsigned long dst_addr;
1217 unsigned int dst_size;
1218
1219 s5p_mfc_set_enc_ref_buffer(ctx);
1220 spin_lock_irqsave(&dev->irqlock, flags);
1221 dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list);
1222 dst_addr = vb2_dma_contig_plane_dma_addr(dst_mb->b, 0);
1223 dst_size = vb2_plane_size(dst_mb->b, 0);
1224 s5p_mfc_set_enc_stream_buffer(ctx, dst_addr, dst_size);
1225 spin_unlock_irqrestore(&dev->irqlock, flags);
1226 dev->curr_ctx = ctx->num;
1227 s5p_mfc_clean_ctx_int_flags(ctx);
1228 s5p_mfc_init_encode(ctx);
1229}
1230
1231static int s5p_mfc_run_init_dec_buffers(struct s5p_mfc_ctx *ctx)
1232{
1233 struct s5p_mfc_dev *dev = ctx->dev;
1234 unsigned long flags;
1235 struct s5p_mfc_buf *temp_vb;
1236 int ret;
1237
1238 /*
1239 * Header was parsed now starting processing
1240 * First set the output frame buffers
1241 */
1242 if (ctx->capture_state != QUEUE_BUFS_MMAPED) {
1243 mfc_err("It seems that not all destionation buffers were "
1244 "mmaped\nMFC requires that all destination are mmaped "
1245 "before starting processing\n");
1246 return -EAGAIN;
1247 }
1248 spin_lock_irqsave(&dev->irqlock, flags);
1249 if (list_empty(&ctx->src_queue)) {
1250 mfc_err("Header has been deallocated in the middle of"
1251 " initialization\n");
1252 spin_unlock_irqrestore(&dev->irqlock, flags);
1253 return -EIO;
1254 }
1255 temp_vb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
1256 mfc_debug(2, "Header size: %d\n", temp_vb->b->v4l2_planes[0].bytesused);
1257 s5p_mfc_set_dec_stream_buffer(ctx,
1258 vb2_dma_contig_plane_dma_addr(temp_vb->b, 0),
1259 0, temp_vb->b->v4l2_planes[0].bytesused);
1260 spin_unlock_irqrestore(&dev->irqlock, flags);
1261 dev->curr_ctx = ctx->num;
1262 s5p_mfc_clean_ctx_int_flags(ctx);
1263 ret = s5p_mfc_set_dec_frame_buffer(ctx);
1264 if (ret) {
1265 mfc_err("Failed to alloc frame mem\n");
1266 ctx->state = MFCINST_ERROR;
1267 }
1268 return ret;
1269}
1270
1271/* Try running an operation on hardware */
1272void s5p_mfc_try_run(struct s5p_mfc_dev *dev)
1273{
1274 struct s5p_mfc_ctx *ctx;
1275 int new_ctx;
1276 unsigned int ret = 0;
1277
1278 if (test_bit(0, &dev->enter_suspend)) {
1279 mfc_debug(1, "Entering suspend so do not schedule any jobs\n");
1280 return;
1281 }
1282 /* Check whether hardware is not running */
1283 if (test_and_set_bit(0, &dev->hw_lock) != 0) {
1284 /* This is perfectly ok, the scheduled ctx should wait */
1285 mfc_debug(1, "Couldn't lock HW\n");
1286 return;
1287 }
1288 /* Choose the context to run */
1289 new_ctx = s5p_mfc_get_new_ctx(dev);
1290 if (new_ctx < 0) {
1291 /* No contexts to run */
1292 if (test_and_clear_bit(0, &dev->hw_lock) == 0) {
1293 mfc_err("Failed to unlock hardware\n");
1294 return;
1295 }
1296 mfc_debug(1, "No ctx is scheduled to be run\n");
1297 return;
1298 }
1299 ctx = dev->ctx[new_ctx];
1300 /* Got context to run in ctx */
1301 /*
1302 * Last frame has already been sent to MFC.
1303 * Now obtaining frames from MFC buffer
1304 */
1305 s5p_mfc_clock_on();
1306 if (ctx->type == MFCINST_DECODER) {
1307 s5p_mfc_set_dec_desc_buffer(ctx);
1308 switch (ctx->state) {
1309 case MFCINST_FINISHING:
1310 s5p_mfc_run_dec_frame(ctx, MFC_DEC_LAST_FRAME);
1311 break;
1312 case MFCINST_RUNNING:
1313 ret = s5p_mfc_run_dec_frame(ctx, MFC_DEC_FRAME);
1314 break;
1315 case MFCINST_INIT:
1316 s5p_mfc_clean_ctx_int_flags(ctx);
1317 ret = s5p_mfc_open_inst_cmd(ctx);
1318 break;
1319 case MFCINST_RETURN_INST:
1320 s5p_mfc_clean_ctx_int_flags(ctx);
1321 ret = s5p_mfc_close_inst_cmd(ctx);
1322 break;
1323 case MFCINST_GOT_INST:
1324 s5p_mfc_run_init_dec(ctx);
1325 break;
1326 case MFCINST_HEAD_PARSED:
1327 ret = s5p_mfc_run_init_dec_buffers(ctx);
1328 mfc_debug(1, "head parsed\n");
1329 break;
1330 case MFCINST_RES_CHANGE_INIT:
1331 s5p_mfc_run_res_change(ctx);
1332 break;
1333 case MFCINST_RES_CHANGE_FLUSH:
1334 s5p_mfc_run_dec_frame(ctx, MFC_DEC_FRAME);
1335 break;
1336 case MFCINST_RES_CHANGE_END:
1337 mfc_debug(2, "Finished remaining frames after resolution change\n");
1338 ctx->capture_state = QUEUE_FREE;
1339 mfc_debug(2, "Will re-init the codec\n");
1340 s5p_mfc_run_init_dec(ctx);
1341 break;
1342 default:
1343 ret = -EAGAIN;
1344 }
1345 } else if (ctx->type == MFCINST_ENCODER) {
1346 switch (ctx->state) {
1347 case MFCINST_FINISHING:
1348 case MFCINST_RUNNING:
1349 ret = s5p_mfc_run_enc_frame(ctx);
1350 break;
1351 case MFCINST_INIT:
1352 s5p_mfc_clean_ctx_int_flags(ctx);
1353 ret = s5p_mfc_open_inst_cmd(ctx);
1354 break;
1355 case MFCINST_RETURN_INST:
1356 s5p_mfc_clean_ctx_int_flags(ctx);
1357 ret = s5p_mfc_close_inst_cmd(ctx);
1358 break;
1359 case MFCINST_GOT_INST:
1360 s5p_mfc_run_init_enc(ctx);
1361 break;
1362 default:
1363 ret = -EAGAIN;
1364 }
1365 } else {
1366 mfc_err("Invalid context type: %d\n", ctx->type);
1367 ret = -EAGAIN;
1368 }
1369
1370 if (ret) {
1371 /* Free hardware lock */
1372 if (test_and_clear_bit(0, &dev->hw_lock) == 0)
1373 mfc_err("Failed to unlock hardware\n");
1374
1375 /* This is in deed imporant, as no operation has been
1376 * scheduled, reduce the clock count as no one will
1377 * ever do this, because no interrupt related to this try_run
1378 * will ever come from hardware. */
1379 s5p_mfc_clock_off();
1380 }
1381}
1382
1383
1384void s5p_mfc_cleanup_queue(struct list_head *lh, struct vb2_queue *vq)
1385{
1386 struct s5p_mfc_buf *b;
1387 int i;
1388
1389 while (!list_empty(lh)) {
1390 b = list_entry(lh->next, struct s5p_mfc_buf, list);
1391 for (i = 0; i < b->b->num_planes; i++)
1392 vb2_set_plane_payload(b->b, i, 0);
1393 vb2_buffer_done(b->b, VB2_BUF_STATE_ERROR);
1394 list_del(&b->list);
1395 }
1396}
1397
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_opr.h b/drivers/media/video/s5p-mfc/s5p_mfc_opr.h
deleted file mode 100644
index 5932d1c782c5..000000000000
--- a/drivers/media/video/s5p-mfc/s5p_mfc_opr.h
+++ /dev/null
@@ -1,93 +0,0 @@
1/*
2 * drivers/media/video/samsung/mfc5/s5p_mfc_opr.h
3 *
4 * Header file for Samsung MFC (Multi Function Codec - FIMV) driver
5 * Contains declarations of hw related functions.
6 *
7 * Kamil Debski, Copyright (C) 2011 Samsung Electronics
8 * http://www.samsung.com/
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#ifndef S5P_MFC_OPR_H_
16#define S5P_MFC_OPR_H_
17
18#include "s5p_mfc_common.h"
19
20int s5p_mfc_init_decode(struct s5p_mfc_ctx *ctx);
21int s5p_mfc_init_encode(struct s5p_mfc_ctx *mfc_ctx);
22
23/* Decoding functions */
24int s5p_mfc_set_dec_frame_buffer(struct s5p_mfc_ctx *ctx);
25int s5p_mfc_set_dec_stream_buffer(struct s5p_mfc_ctx *ctx, int buf_addr,
26 unsigned int start_num_byte,
27 unsigned int buf_size);
28
29/* Encoding functions */
30void s5p_mfc_set_enc_frame_buffer(struct s5p_mfc_ctx *ctx,
31 unsigned long y_addr, unsigned long c_addr);
32int s5p_mfc_set_enc_stream_buffer(struct s5p_mfc_ctx *ctx,
33 unsigned long addr, unsigned int size);
34void s5p_mfc_get_enc_frame_buffer(struct s5p_mfc_ctx *ctx,
35 unsigned long *y_addr, unsigned long *c_addr);
36int s5p_mfc_set_enc_ref_buffer(struct s5p_mfc_ctx *mfc_ctx);
37
38int s5p_mfc_decode_one_frame(struct s5p_mfc_ctx *ctx,
39 enum s5p_mfc_decode_arg last_frame);
40int s5p_mfc_encode_one_frame(struct s5p_mfc_ctx *mfc_ctx);
41
42/* Memory allocation */
43int s5p_mfc_alloc_dec_temp_buffers(struct s5p_mfc_ctx *ctx);
44void s5p_mfc_set_dec_desc_buffer(struct s5p_mfc_ctx *ctx);
45void s5p_mfc_release_dec_desc_buffer(struct s5p_mfc_ctx *ctx);
46
47int s5p_mfc_alloc_codec_buffers(struct s5p_mfc_ctx *ctx);
48void s5p_mfc_release_codec_buffers(struct s5p_mfc_ctx *ctx);
49
50int s5p_mfc_alloc_instance_buffer(struct s5p_mfc_ctx *ctx);
51void s5p_mfc_release_instance_buffer(struct s5p_mfc_ctx *ctx);
52
53void s5p_mfc_try_run(struct s5p_mfc_dev *dev);
54void s5p_mfc_cleanup_queue(struct list_head *lh, struct vb2_queue *vq);
55
56#define s5p_mfc_get_dspl_y_adr() (readl(dev->regs_base + \
57 S5P_FIMV_SI_DISPLAY_Y_ADR) << \
58 MFC_OFFSET_SHIFT)
59#define s5p_mfc_get_dec_y_adr() (readl(dev->regs_base + \
60 S5P_FIMV_SI_DECODE_Y_ADR) << \
61 MFC_OFFSET_SHIFT)
62#define s5p_mfc_get_dspl_status() readl(dev->regs_base + \
63 S5P_FIMV_SI_DISPLAY_STATUS)
64#define s5p_mfc_get_dec_status() readl(dev->regs_base + \
65 S5P_FIMV_SI_DECODE_STATUS)
66#define s5p_mfc_get_frame_type() (readl(dev->regs_base + \
67 S5P_FIMV_DECODE_FRAME_TYPE) \
68 & S5P_FIMV_DECODE_FRAME_MASK)
69#define s5p_mfc_get_consumed_stream() readl(dev->regs_base + \
70 S5P_FIMV_SI_CONSUMED_BYTES)
71#define s5p_mfc_get_int_reason() (readl(dev->regs_base + \
72 S5P_FIMV_RISC2HOST_CMD) & \
73 S5P_FIMV_RISC2HOST_CMD_MASK)
74#define s5p_mfc_get_int_err() readl(dev->regs_base + \
75 S5P_FIMV_RISC2HOST_ARG2)
76#define s5p_mfc_err_dec(x) (((x) & S5P_FIMV_ERR_DEC_MASK) >> \
77 S5P_FIMV_ERR_DEC_SHIFT)
78#define s5p_mfc_err_dspl(x) (((x) & S5P_FIMV_ERR_DSPL_MASK) >> \
79 S5P_FIMV_ERR_DSPL_SHIFT)
80#define s5p_mfc_get_img_width() readl(dev->regs_base + \
81 S5P_FIMV_SI_HRESOL)
82#define s5p_mfc_get_img_height() readl(dev->regs_base + \
83 S5P_FIMV_SI_VRESOL)
84#define s5p_mfc_get_dpb_count() readl(dev->regs_base + \
85 S5P_FIMV_SI_BUF_NUMBER)
86#define s5p_mfc_get_inst_no() readl(dev->regs_base + \
87 S5P_FIMV_RISC2HOST_ARG1)
88#define s5p_mfc_get_enc_strm_size() readl(dev->regs_base + \
89 S5P_FIMV_ENC_SI_STRM_SIZE)
90#define s5p_mfc_get_enc_slice_type() readl(dev->regs_base + \
91 S5P_FIMV_ENC_SI_SLICE_TYPE)
92
93#endif /* S5P_MFC_OPR_H_ */
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_pm.c b/drivers/media/video/s5p-mfc/s5p_mfc_pm.c
deleted file mode 100644
index 738a607be43c..000000000000
--- a/drivers/media/video/s5p-mfc/s5p_mfc_pm.c
+++ /dev/null
@@ -1,137 +0,0 @@
1/*
2 * linux/drivers/media/video/s5p-mfc/s5p_mfc_pm.c
3 *
4 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
5 * http://www.samsung.com/
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <linux/clk.h>
14#include <linux/err.h>
15#include <linux/platform_device.h>
16#ifdef CONFIG_PM_RUNTIME
17#include <linux/pm_runtime.h>
18#endif
19#include "s5p_mfc_common.h"
20#include "s5p_mfc_debug.h"
21#include "s5p_mfc_pm.h"
22
23#define MFC_CLKNAME "sclk_mfc"
24#define MFC_GATE_CLK_NAME "mfc"
25
26#define CLK_DEBUG
27
28static struct s5p_mfc_pm *pm;
29static struct s5p_mfc_dev *p_dev;
30
31#ifdef CLK_DEBUG
32atomic_t clk_ref;
33#endif
34
35int s5p_mfc_init_pm(struct s5p_mfc_dev *dev)
36{
37 int ret = 0;
38
39 pm = &dev->pm;
40 p_dev = dev;
41 pm->clock_gate = clk_get(&dev->plat_dev->dev, MFC_GATE_CLK_NAME);
42 if (IS_ERR(pm->clock_gate)) {
43 mfc_err("Failed to get clock-gating control\n");
44 ret = PTR_ERR(pm->clock_gate);
45 goto err_g_ip_clk;
46 }
47
48 ret = clk_prepare(pm->clock_gate);
49 if (ret) {
50 mfc_err("Failed to preapre clock-gating control\n");
51 goto err_p_ip_clk;
52 }
53
54 pm->clock = clk_get(&dev->plat_dev->dev, MFC_CLKNAME);
55 if (IS_ERR(pm->clock)) {
56 mfc_err("Failed to get MFC clock\n");
57 ret = PTR_ERR(pm->clock);
58 goto err_g_ip_clk_2;
59 }
60
61 ret = clk_prepare(pm->clock);
62 if (ret) {
63 mfc_err("Failed to prepare MFC clock\n");
64 goto err_p_ip_clk_2;
65 }
66
67 atomic_set(&pm->power, 0);
68#ifdef CONFIG_PM_RUNTIME
69 pm->device = &dev->plat_dev->dev;
70 pm_runtime_enable(pm->device);
71#endif
72#ifdef CLK_DEBUG
73 atomic_set(&clk_ref, 0);
74#endif
75 return 0;
76err_p_ip_clk_2:
77 clk_put(pm->clock);
78err_g_ip_clk_2:
79 clk_unprepare(pm->clock_gate);
80err_p_ip_clk:
81 clk_put(pm->clock_gate);
82err_g_ip_clk:
83 return ret;
84}
85
86void s5p_mfc_final_pm(struct s5p_mfc_dev *dev)
87{
88 clk_unprepare(pm->clock_gate);
89 clk_put(pm->clock_gate);
90 clk_unprepare(pm->clock);
91 clk_put(pm->clock);
92#ifdef CONFIG_PM_RUNTIME
93 pm_runtime_disable(pm->device);
94#endif
95}
96
97int s5p_mfc_clock_on(void)
98{
99 int ret;
100#ifdef CLK_DEBUG
101 atomic_inc(&clk_ref);
102 mfc_debug(3, "+ %d", atomic_read(&clk_ref));
103#endif
104 ret = clk_enable(pm->clock_gate);
105 return ret;
106}
107
108void s5p_mfc_clock_off(void)
109{
110#ifdef CLK_DEBUG
111 atomic_dec(&clk_ref);
112 mfc_debug(3, "- %d", atomic_read(&clk_ref));
113#endif
114 clk_disable(pm->clock_gate);
115}
116
117int s5p_mfc_power_on(void)
118{
119#ifdef CONFIG_PM_RUNTIME
120 return pm_runtime_get_sync(pm->device);
121#else
122 atomic_set(&pm->power, 1);
123 return 0;
124#endif
125}
126
127int s5p_mfc_power_off(void)
128{
129#ifdef CONFIG_PM_RUNTIME
130 return pm_runtime_put_sync(pm->device);
131#else
132 atomic_set(&pm->power, 0);
133 return 0;
134#endif
135}
136
137
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_pm.h b/drivers/media/video/s5p-mfc/s5p_mfc_pm.h
deleted file mode 100644
index 5107914f27e4..000000000000
--- a/drivers/media/video/s5p-mfc/s5p_mfc_pm.h
+++ /dev/null
@@ -1,24 +0,0 @@
1/*
2 * linux/drivers/media/video/s5p-mfc/s5p_mfc_pm.h
3 *
4 * Copyright (C) 2011 Samsung Electronics Co., Ltd.
5 * http://www.samsung.com/
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#ifndef S5P_MFC_PM_H_
14#define S5P_MFC_PM_H_
15
16int s5p_mfc_init_pm(struct s5p_mfc_dev *dev);
17void s5p_mfc_final_pm(struct s5p_mfc_dev *dev);
18
19int s5p_mfc_clock_on(void);
20void s5p_mfc_clock_off(void);
21int s5p_mfc_power_on(void);
22int s5p_mfc_power_off(void);
23
24#endif /* S5P_MFC_PM_H_ */
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_shm.c b/drivers/media/video/s5p-mfc/s5p_mfc_shm.c
deleted file mode 100644
index 91fdbac8c37a..000000000000
--- a/drivers/media/video/s5p-mfc/s5p_mfc_shm.c
+++ /dev/null
@@ -1,47 +0,0 @@
1/*
2 * linux/drivers/media/video/s5p-mfc/s5p_mfc_shm.c
3 *
4 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
5 * http://www.samsung.com/
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#ifdef CONFIG_ARCH_EXYNOS4
14#include <linux/dma-mapping.h>
15#endif
16#include <linux/io.h>
17#include "s5p_mfc_common.h"
18#include "s5p_mfc_debug.h"
19
20int s5p_mfc_init_shm(struct s5p_mfc_ctx *ctx)
21{
22 struct s5p_mfc_dev *dev = ctx->dev;
23 void *shm_alloc_ctx = dev->alloc_ctx[MFC_BANK1_ALLOC_CTX];
24
25 ctx->shm_alloc = vb2_dma_contig_memops.alloc(shm_alloc_ctx,
26 SHARED_BUF_SIZE);
27 if (IS_ERR(ctx->shm_alloc)) {
28 mfc_err("failed to allocate shared memory\n");
29 return PTR_ERR(ctx->shm_alloc);
30 }
31 /* shm_ofs only keeps the offset from base (port a) */
32 ctx->shm_ofs = s5p_mfc_mem_cookie(shm_alloc_ctx, ctx->shm_alloc)
33 - dev->bank1;
34 BUG_ON(ctx->shm_ofs & ((1 << MFC_BANK1_ALIGN_ORDER) - 1));
35 ctx->shm = vb2_dma_contig_memops.vaddr(ctx->shm_alloc);
36 if (!ctx->shm) {
37 vb2_dma_contig_memops.put(ctx->shm_alloc);
38 ctx->shm_ofs = 0;
39 ctx->shm_alloc = NULL;
40 mfc_err("failed to virt addr of shared memory\n");
41 return -ENOMEM;
42 }
43 memset((void *)ctx->shm, 0, SHARED_BUF_SIZE);
44 wmb();
45 return 0;
46}
47
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_shm.h b/drivers/media/video/s5p-mfc/s5p_mfc_shm.h
deleted file mode 100644
index cf962a466276..000000000000
--- a/drivers/media/video/s5p-mfc/s5p_mfc_shm.h
+++ /dev/null
@@ -1,90 +0,0 @@
1/*
2 * linux/drivers/media/video/s5p-mfc/s5p_mfc_shm.h
3 *
4 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
5 * http://www.samsung.com/
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#ifndef S5P_MFC_SHM_H_
14#define S5P_MFC_SHM_H_
15
16enum MFC_SHM_OFS {
17 EXTENEDED_DECODE_STATUS = 0x00, /* D */
18 SET_FRAME_TAG = 0x04, /* D */
19 GET_FRAME_TAG_TOP = 0x08, /* D */
20 GET_FRAME_TAG_BOT = 0x0C, /* D */
21 PIC_TIME_TOP = 0x10, /* D */
22 PIC_TIME_BOT = 0x14, /* D */
23 START_BYTE_NUM = 0x18, /* D */
24
25 CROP_INFO_H = 0x20, /* D */
26 CROP_INFO_V = 0x24, /* D */
27 EXT_ENC_CONTROL = 0x28, /* E */
28 ENC_PARAM_CHANGE = 0x2C, /* E */
29 RC_VOP_TIMING = 0x30, /* E, MPEG4 */
30 HEC_PERIOD = 0x34, /* E, MPEG4 */
31 METADATA_ENABLE = 0x38, /* C */
32 METADATA_STATUS = 0x3C, /* C */
33 METADATA_DISPLAY_INDEX = 0x40, /* C */
34 EXT_METADATA_START_ADDR = 0x44, /* C */
35 PUT_EXTRADATA = 0x48, /* C */
36 EXTRADATA_ADDR = 0x4C, /* C */
37
38 ALLOC_LUMA_DPB_SIZE = 0x64, /* D */
39 ALLOC_CHROMA_DPB_SIZE = 0x68, /* D */
40 ALLOC_MV_SIZE = 0x6C, /* D */
41 P_B_FRAME_QP = 0x70, /* E */
42 SAMPLE_ASPECT_RATIO_IDC = 0x74, /* E, H.264, depend on
43 ASPECT_RATIO_VUI_ENABLE in EXT_ENC_CONTROL */
44 EXTENDED_SAR = 0x78, /* E, H.264, depned on
45 ASPECT_RATIO_VUI_ENABLE in EXT_ENC_CONTROL */
46 DISP_PIC_PROFILE = 0x7C, /* D */
47 FLUSH_CMD_TYPE = 0x80, /* C */
48 FLUSH_CMD_INBUF1 = 0x84, /* C */
49 FLUSH_CMD_INBUF2 = 0x88, /* C */
50 FLUSH_CMD_OUTBUF = 0x8C, /* E */
51 NEW_RC_BIT_RATE = 0x90, /* E, format as RC_BIT_RATE(0xC5A8)
52 depend on RC_BIT_RATE_CHANGE in ENC_PARAM_CHANGE */
53 NEW_RC_FRAME_RATE = 0x94, /* E, format as RC_FRAME_RATE(0xD0D0)
54 depend on RC_FRAME_RATE_CHANGE in ENC_PARAM_CHANGE */
55 NEW_I_PERIOD = 0x98, /* E, format as I_FRM_CTRL(0xC504)
56 depend on I_PERIOD_CHANGE in ENC_PARAM_CHANGE */
57 H264_I_PERIOD = 0x9C, /* E, H.264, open GOP */
58 RC_CONTROL_CONFIG = 0xA0, /* E */
59 BATCH_INPUT_ADDR = 0xA4, /* E */
60 BATCH_OUTPUT_ADDR = 0xA8, /* E */
61 BATCH_OUTPUT_SIZE = 0xAC, /* E */
62 MIN_LUMA_DPB_SIZE = 0xB0, /* D */
63 DEVICE_FORMAT_ID = 0xB4, /* C */
64 H264_POC_TYPE = 0xB8, /* D */
65 MIN_CHROMA_DPB_SIZE = 0xBC, /* D */
66 DISP_PIC_FRAME_TYPE = 0xC0, /* D */
67 FREE_LUMA_DPB = 0xC4, /* D, VC1 MPEG4 */
68 ASPECT_RATIO_INFO = 0xC8, /* D, MPEG4 */
69 EXTENDED_PAR = 0xCC, /* D, MPEG4 */
70 DBG_HISTORY_INPUT0 = 0xD0, /* C */
71 DBG_HISTORY_INPUT1 = 0xD4, /* C */
72 DBG_HISTORY_OUTPUT = 0xD8, /* C */
73 HIERARCHICAL_P_QP = 0xE0, /* E, H.264 */
74};
75
76int s5p_mfc_init_shm(struct s5p_mfc_ctx *ctx);
77
78#define s5p_mfc_write_shm(ctx, x, ofs) \
79 do { \
80 writel(x, (ctx->shm + ofs)); \
81 wmb(); \
82 } while (0)
83
84static inline u32 s5p_mfc_read_shm(struct s5p_mfc_ctx *ctx, unsigned int ofs)
85{
86 rmb();
87 return readl(ctx->shm + ofs);
88}
89
90#endif /* S5P_MFC_SHM_H_ */
diff --git a/drivers/media/video/s5p-tv/Kconfig b/drivers/media/video/s5p-tv/Kconfig
deleted file mode 100644
index f248b2856720..000000000000
--- a/drivers/media/video/s5p-tv/Kconfig
+++ /dev/null
@@ -1,86 +0,0 @@
1# drivers/media/video/s5p-tv/Kconfig
2#
3# Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
4# http://www.samsung.com/
5# Tomasz Stanislawski <t.stanislaws@samsung.com>
6#
7# Licensed under GPL
8
9config VIDEO_SAMSUNG_S5P_TV
10 bool "Samsung TV driver for S5P platform (experimental)"
11 depends on PLAT_S5P && PM_RUNTIME
12 depends on EXPERIMENTAL
13 default n
14 ---help---
15 Say Y here to enable selecting the TV output devices for
16 Samsung S5P platform.
17
18if VIDEO_SAMSUNG_S5P_TV
19
20config VIDEO_SAMSUNG_S5P_HDMI
21 tristate "Samsung HDMI Driver"
22 depends on VIDEO_V4L2
23 depends on VIDEO_SAMSUNG_S5P_TV
24 select VIDEO_SAMSUNG_S5P_HDMIPHY
25 help
26 Say Y here if you want support for the HDMI output
27 interface in S5P Samsung SoC. The driver can be compiled
28 as module. It is an auxiliary driver, that exposes a V4L2
29 subdev for use by other drivers. This driver requires
30 hdmiphy driver to work correctly.
31
32config VIDEO_SAMSUNG_S5P_HDMI_DEBUG
33 bool "Enable debug for HDMI Driver"
34 depends on VIDEO_SAMSUNG_S5P_HDMI
35 default n
36 help
37 Enables debugging for HDMI driver.
38
39config VIDEO_SAMSUNG_S5P_HDMIPHY
40 tristate "Samsung HDMIPHY Driver"
41 depends on VIDEO_DEV && VIDEO_V4L2 && I2C
42 depends on VIDEO_SAMSUNG_S5P_TV
43 help
44 Say Y here if you want support for the physical HDMI
45 interface in S5P Samsung SoC. The driver can be compiled
46 as module. It is an I2C driver, that exposes a V4L2
47 subdev for use by other drivers.
48
49config VIDEO_SAMSUNG_S5P_SII9234
50 tristate "Samsung SII9234 Driver"
51 depends on VIDEO_DEV && VIDEO_V4L2 && I2C
52 depends on VIDEO_SAMSUNG_S5P_TV
53 help
54 Say Y here if you want support for the MHL interface
55 in S5P Samsung SoC. The driver can be compiled
56 as module. It is an I2C driver, that exposes a V4L2
57 subdev for use by other drivers.
58
59config VIDEO_SAMSUNG_S5P_SDO
60 tristate "Samsung Analog TV Driver"
61 depends on VIDEO_DEV && VIDEO_V4L2
62 depends on VIDEO_SAMSUNG_S5P_TV
63 help
64 Say Y here if you want support for the analog TV output
65 interface in S5P Samsung SoC. The driver can be compiled
66 as module. It is an auxiliary driver, that exposes a V4L2
67 subdev for use by other drivers. This driver requires
68 hdmiphy driver to work correctly.
69
70config VIDEO_SAMSUNG_S5P_MIXER
71 tristate "Samsung Mixer and Video Processor Driver"
72 depends on VIDEO_DEV && VIDEO_V4L2
73 depends on VIDEO_SAMSUNG_S5P_TV
74 select VIDEOBUF2_DMA_CONTIG
75 help
76 Say Y here if you want support for the Mixer in Samsung S5P SoCs.
77 This device produce image data to one of output interfaces.
78
79config VIDEO_SAMSUNG_S5P_MIXER_DEBUG
80 bool "Enable debug for Mixer Driver"
81 depends on VIDEO_SAMSUNG_S5P_MIXER
82 default n
83 help
84 Enables debugging for Mixer driver.
85
86endif # VIDEO_SAMSUNG_S5P_TV
diff --git a/drivers/media/video/s5p-tv/Makefile b/drivers/media/video/s5p-tv/Makefile
deleted file mode 100644
index f49e756a2fde..000000000000
--- a/drivers/media/video/s5p-tv/Makefile
+++ /dev/null
@@ -1,19 +0,0 @@
1# drivers/media/video/samsung/tvout/Makefile
2#
3# Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
4# http://www.samsung.com/
5# Tomasz Stanislawski <t.stanislaws@samsung.com>
6#
7# Licensed under GPL
8
9obj-$(CONFIG_VIDEO_SAMSUNG_S5P_HDMIPHY) += s5p-hdmiphy.o
10s5p-hdmiphy-y += hdmiphy_drv.o
11obj-$(CONFIG_VIDEO_SAMSUNG_S5P_SII9234) += s5p-sii9234.o
12s5p-sii9234-y += sii9234_drv.o
13obj-$(CONFIG_VIDEO_SAMSUNG_S5P_HDMI) += s5p-hdmi.o
14s5p-hdmi-y += hdmi_drv.o
15obj-$(CONFIG_VIDEO_SAMSUNG_S5P_SDO) += s5p-sdo.o
16s5p-sdo-y += sdo_drv.o
17obj-$(CONFIG_VIDEO_SAMSUNG_S5P_MIXER) += s5p-mixer.o
18s5p-mixer-y += mixer_drv.o mixer_video.o mixer_reg.o mixer_grp_layer.o mixer_vp_layer.o
19
diff --git a/drivers/media/video/s5p-tv/hdmi_drv.c b/drivers/media/video/s5p-tv/hdmi_drv.c
deleted file mode 100644
index 20cb6eef2979..000000000000
--- a/drivers/media/video/s5p-tv/hdmi_drv.c
+++ /dev/null
@@ -1,1007 +0,0 @@
1/*
2 * Samsung HDMI interface driver
3 *
4 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
5 *
6 * Tomasz Stanislawski, <t.stanislaws@samsung.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published
10 * by the Free Software Foundiation. either version 2 of the License,
11 * or (at your option) any later version
12 */
13
14#ifdef CONFIG_VIDEO_SAMSUNG_S5P_HDMI_DEBUG
15#define DEBUG
16#endif
17
18#include <linux/kernel.h>
19#include <linux/slab.h>
20#include <linux/io.h>
21#include <linux/i2c.h>
22#include <linux/platform_device.h>
23#include <media/v4l2-subdev.h>
24#include <linux/module.h>
25#include <linux/interrupt.h>
26#include <linux/irq.h>
27#include <linux/delay.h>
28#include <linux/bug.h>
29#include <linux/pm_runtime.h>
30#include <linux/clk.h>
31#include <linux/regulator/consumer.h>
32
33#include <media/s5p_hdmi.h>
34#include <media/v4l2-common.h>
35#include <media/v4l2-dev.h>
36#include <media/v4l2-device.h>
37
38#include "regs-hdmi.h"
39
40MODULE_AUTHOR("Tomasz Stanislawski, <t.stanislaws@samsung.com>");
41MODULE_DESCRIPTION("Samsung HDMI");
42MODULE_LICENSE("GPL");
43
44/* default preset configured on probe */
45#define HDMI_DEFAULT_PRESET V4L2_DV_480P59_94
46
47struct hdmi_pulse {
48 u32 beg;
49 u32 end;
50};
51
52struct hdmi_timings {
53 struct hdmi_pulse hact;
54 u32 hsyn_pol; /* 0 - high, 1 - low */
55 struct hdmi_pulse hsyn;
56 u32 interlaced;
57 struct hdmi_pulse vact[2];
58 u32 vsyn_pol; /* 0 - high, 1 - low */
59 u32 vsyn_off;
60 struct hdmi_pulse vsyn[2];
61};
62
63struct hdmi_resources {
64 struct clk *hdmi;
65 struct clk *sclk_hdmi;
66 struct clk *sclk_pixel;
67 struct clk *sclk_hdmiphy;
68 struct clk *hdmiphy;
69 struct regulator_bulk_data *regul_bulk;
70 int regul_count;
71};
72
73struct hdmi_device {
74 /** base address of HDMI registers */
75 void __iomem *regs;
76 /** HDMI interrupt */
77 unsigned int irq;
78 /** pointer to device parent */
79 struct device *dev;
80 /** subdev generated by HDMI device */
81 struct v4l2_subdev sd;
82 /** V4L2 device structure */
83 struct v4l2_device v4l2_dev;
84 /** subdev of HDMIPHY interface */
85 struct v4l2_subdev *phy_sd;
86 /** subdev of MHL interface */
87 struct v4l2_subdev *mhl_sd;
88 /** configuration of current graphic mode */
89 const struct hdmi_timings *cur_conf;
90 /** flag indicating that timings are dirty */
91 int cur_conf_dirty;
92 /** current preset */
93 u32 cur_preset;
94 /** other resources */
95 struct hdmi_resources res;
96};
97
98static struct platform_device_id hdmi_driver_types[] = {
99 {
100 .name = "s5pv210-hdmi",
101 }, {
102 .name = "exynos4-hdmi",
103 }, {
104 /* end node */
105 }
106};
107
108static const struct v4l2_subdev_ops hdmi_sd_ops;
109
110static struct hdmi_device *sd_to_hdmi_dev(struct v4l2_subdev *sd)
111{
112 return container_of(sd, struct hdmi_device, sd);
113}
114
115static inline
116void hdmi_write(struct hdmi_device *hdev, u32 reg_id, u32 value)
117{
118 writel(value, hdev->regs + reg_id);
119}
120
121static inline
122void hdmi_write_mask(struct hdmi_device *hdev, u32 reg_id, u32 value, u32 mask)
123{
124 u32 old = readl(hdev->regs + reg_id);
125 value = (value & mask) | (old & ~mask);
126 writel(value, hdev->regs + reg_id);
127}
128
129static inline
130void hdmi_writeb(struct hdmi_device *hdev, u32 reg_id, u8 value)
131{
132 writeb(value, hdev->regs + reg_id);
133}
134
135static inline
136void hdmi_writebn(struct hdmi_device *hdev, u32 reg_id, int n, u32 value)
137{
138 switch (n) {
139 default:
140 writeb(value >> 24, hdev->regs + reg_id + 12);
141 case 3:
142 writeb(value >> 16, hdev->regs + reg_id + 8);
143 case 2:
144 writeb(value >> 8, hdev->regs + reg_id + 4);
145 case 1:
146 writeb(value >> 0, hdev->regs + reg_id + 0);
147 }
148}
149
150static inline u32 hdmi_read(struct hdmi_device *hdev, u32 reg_id)
151{
152 return readl(hdev->regs + reg_id);
153}
154
155static irqreturn_t hdmi_irq_handler(int irq, void *dev_data)
156{
157 struct hdmi_device *hdev = dev_data;
158 u32 intc_flag;
159
160 (void)irq;
161 intc_flag = hdmi_read(hdev, HDMI_INTC_FLAG);
162 /* clearing flags for HPD plug/unplug */
163 if (intc_flag & HDMI_INTC_FLAG_HPD_UNPLUG) {
164 printk(KERN_INFO "unplugged\n");
165 hdmi_write_mask(hdev, HDMI_INTC_FLAG, ~0,
166 HDMI_INTC_FLAG_HPD_UNPLUG);
167 }
168 if (intc_flag & HDMI_INTC_FLAG_HPD_PLUG) {
169 printk(KERN_INFO "plugged\n");
170 hdmi_write_mask(hdev, HDMI_INTC_FLAG, ~0,
171 HDMI_INTC_FLAG_HPD_PLUG);
172 }
173
174 return IRQ_HANDLED;
175}
176
177static void hdmi_reg_init(struct hdmi_device *hdev)
178{
179 /* enable HPD interrupts */
180 hdmi_write_mask(hdev, HDMI_INTC_CON, ~0, HDMI_INTC_EN_GLOBAL |
181 HDMI_INTC_EN_HPD_PLUG | HDMI_INTC_EN_HPD_UNPLUG);
182 /* choose DVI mode */
183 hdmi_write_mask(hdev, HDMI_MODE_SEL,
184 HDMI_MODE_DVI_EN, HDMI_MODE_MASK);
185 hdmi_write_mask(hdev, HDMI_CON_2, ~0,
186 HDMI_DVI_PERAMBLE_EN | HDMI_DVI_BAND_EN);
187 /* disable bluescreen */
188 hdmi_write_mask(hdev, HDMI_CON_0, 0, HDMI_BLUE_SCR_EN);
189 /* choose bluescreen (fecal) color */
190 hdmi_writeb(hdev, HDMI_BLUE_SCREEN_0, 0x12);
191 hdmi_writeb(hdev, HDMI_BLUE_SCREEN_1, 0x34);
192 hdmi_writeb(hdev, HDMI_BLUE_SCREEN_2, 0x56);
193}
194
195static void hdmi_timing_apply(struct hdmi_device *hdev,
196 const struct hdmi_timings *t)
197{
198 /* setting core registers */
199 hdmi_writebn(hdev, HDMI_H_BLANK_0, 2, t->hact.beg);
200 hdmi_writebn(hdev, HDMI_H_SYNC_GEN_0, 3,
201 (t->hsyn_pol << 20) | (t->hsyn.end << 10) | t->hsyn.beg);
202 hdmi_writeb(hdev, HDMI_VSYNC_POL, t->vsyn_pol);
203 hdmi_writebn(hdev, HDMI_V_BLANK_0, 3,
204 (t->vact[0].beg << 11) | t->vact[0].end);
205 hdmi_writebn(hdev, HDMI_V_SYNC_GEN_1_0, 3,
206 (t->vsyn[0].beg << 12) | t->vsyn[0].end);
207 if (t->interlaced) {
208 u32 vsyn_trans = t->hsyn.beg + t->vsyn_off;
209
210 hdmi_writeb(hdev, HDMI_INT_PRO_MODE, 1);
211 hdmi_writebn(hdev, HDMI_H_V_LINE_0, 3,
212 (t->hact.end << 12) | t->vact[1].end);
213 hdmi_writebn(hdev, HDMI_V_BLANK_F_0, 3,
214 (t->vact[1].end << 11) | t->vact[1].beg);
215 hdmi_writebn(hdev, HDMI_V_SYNC_GEN_2_0, 3,
216 (t->vsyn[1].beg << 12) | t->vsyn[1].end);
217 hdmi_writebn(hdev, HDMI_V_SYNC_GEN_3_0, 3,
218 (vsyn_trans << 12) | vsyn_trans);
219 } else {
220 hdmi_writeb(hdev, HDMI_INT_PRO_MODE, 0);
221 hdmi_writebn(hdev, HDMI_H_V_LINE_0, 3,
222 (t->hact.end << 12) | t->vact[0].end);
223 }
224
225 /* Timing generator registers */
226 hdmi_writebn(hdev, HDMI_TG_H_FSZ_L, 2, t->hact.end);
227 hdmi_writebn(hdev, HDMI_TG_HACT_ST_L, 2, t->hact.beg);
228 hdmi_writebn(hdev, HDMI_TG_HACT_SZ_L, 2, t->hact.end - t->hact.beg);
229 hdmi_writebn(hdev, HDMI_TG_VSYNC_L, 2, t->vsyn[0].beg);
230 hdmi_writebn(hdev, HDMI_TG_VACT_ST_L, 2, t->vact[0].beg);
231 hdmi_writebn(hdev, HDMI_TG_VACT_SZ_L, 2,
232 t->vact[0].end - t->vact[0].beg);
233 hdmi_writebn(hdev, HDMI_TG_VSYNC_TOP_HDMI_L, 2, t->vsyn[0].beg);
234 hdmi_writebn(hdev, HDMI_TG_FIELD_TOP_HDMI_L, 2, t->vsyn[0].beg);
235 if (t->interlaced) {
236 hdmi_write_mask(hdev, HDMI_TG_CMD, ~0, HDMI_TG_FIELD_EN);
237 hdmi_writebn(hdev, HDMI_TG_V_FSZ_L, 2, t->vact[1].end);
238 hdmi_writebn(hdev, HDMI_TG_VSYNC2_L, 2, t->vsyn[1].beg);
239 hdmi_writebn(hdev, HDMI_TG_FIELD_CHG_L, 2, t->vact[0].end);
240 hdmi_writebn(hdev, HDMI_TG_VACT_ST2_L, 2, t->vact[1].beg);
241 hdmi_writebn(hdev, HDMI_TG_VSYNC_BOT_HDMI_L, 2, t->vsyn[1].beg);
242 hdmi_writebn(hdev, HDMI_TG_FIELD_BOT_HDMI_L, 2, t->vsyn[1].beg);
243 } else {
244 hdmi_write_mask(hdev, HDMI_TG_CMD, 0, HDMI_TG_FIELD_EN);
245 hdmi_writebn(hdev, HDMI_TG_V_FSZ_L, 2, t->vact[0].end);
246 }
247}
248
249static int hdmi_conf_apply(struct hdmi_device *hdmi_dev)
250{
251 struct device *dev = hdmi_dev->dev;
252 const struct hdmi_timings *conf = hdmi_dev->cur_conf;
253 struct v4l2_dv_preset preset;
254 int ret;
255
256 dev_dbg(dev, "%s\n", __func__);
257
258 /* skip if conf is already synchronized with HW */
259 if (!hdmi_dev->cur_conf_dirty)
260 return 0;
261
262 /* reset hdmiphy */
263 hdmi_write_mask(hdmi_dev, HDMI_PHY_RSTOUT, ~0, HDMI_PHY_SW_RSTOUT);
264 mdelay(10);
265 hdmi_write_mask(hdmi_dev, HDMI_PHY_RSTOUT, 0, HDMI_PHY_SW_RSTOUT);
266 mdelay(10);
267
268 /* configure presets */
269 preset.preset = hdmi_dev->cur_preset;
270 ret = v4l2_subdev_call(hdmi_dev->phy_sd, video, s_dv_preset, &preset);
271 if (ret) {
272 dev_err(dev, "failed to set preset (%u)\n", preset.preset);
273 return ret;
274 }
275
276 /* resetting HDMI core */
277 hdmi_write_mask(hdmi_dev, HDMI_CORE_RSTOUT, 0, HDMI_CORE_SW_RSTOUT);
278 mdelay(10);
279 hdmi_write_mask(hdmi_dev, HDMI_CORE_RSTOUT, ~0, HDMI_CORE_SW_RSTOUT);
280 mdelay(10);
281
282 hdmi_reg_init(hdmi_dev);
283
284 /* setting core registers */
285 hdmi_timing_apply(hdmi_dev, conf);
286
287 hdmi_dev->cur_conf_dirty = 0;
288
289 return 0;
290}
291
292static void hdmi_dumpregs(struct hdmi_device *hdev, char *prefix)
293{
294#define DUMPREG(reg_id) \
295 dev_dbg(hdev->dev, "%s:" #reg_id " = %08x\n", prefix, \
296 readl(hdev->regs + reg_id))
297
298 dev_dbg(hdev->dev, "%s: ---- CONTROL REGISTERS ----\n", prefix);
299 DUMPREG(HDMI_INTC_FLAG);
300 DUMPREG(HDMI_INTC_CON);
301 DUMPREG(HDMI_HPD_STATUS);
302 DUMPREG(HDMI_PHY_RSTOUT);
303 DUMPREG(HDMI_PHY_VPLL);
304 DUMPREG(HDMI_PHY_CMU);
305 DUMPREG(HDMI_CORE_RSTOUT);
306
307 dev_dbg(hdev->dev, "%s: ---- CORE REGISTERS ----\n", prefix);
308 DUMPREG(HDMI_CON_0);
309 DUMPREG(HDMI_CON_1);
310 DUMPREG(HDMI_CON_2);
311 DUMPREG(HDMI_SYS_STATUS);
312 DUMPREG(HDMI_PHY_STATUS);
313 DUMPREG(HDMI_STATUS_EN);
314 DUMPREG(HDMI_HPD);
315 DUMPREG(HDMI_MODE_SEL);
316 DUMPREG(HDMI_HPD_GEN);
317 DUMPREG(HDMI_DC_CONTROL);
318 DUMPREG(HDMI_VIDEO_PATTERN_GEN);
319
320 dev_dbg(hdev->dev, "%s: ---- CORE SYNC REGISTERS ----\n", prefix);
321 DUMPREG(HDMI_H_BLANK_0);
322 DUMPREG(HDMI_H_BLANK_1);
323 DUMPREG(HDMI_V_BLANK_0);
324 DUMPREG(HDMI_V_BLANK_1);
325 DUMPREG(HDMI_V_BLANK_2);
326 DUMPREG(HDMI_H_V_LINE_0);
327 DUMPREG(HDMI_H_V_LINE_1);
328 DUMPREG(HDMI_H_V_LINE_2);
329 DUMPREG(HDMI_VSYNC_POL);
330 DUMPREG(HDMI_INT_PRO_MODE);
331 DUMPREG(HDMI_V_BLANK_F_0);
332 DUMPREG(HDMI_V_BLANK_F_1);
333 DUMPREG(HDMI_V_BLANK_F_2);
334 DUMPREG(HDMI_H_SYNC_GEN_0);
335 DUMPREG(HDMI_H_SYNC_GEN_1);
336 DUMPREG(HDMI_H_SYNC_GEN_2);
337 DUMPREG(HDMI_V_SYNC_GEN_1_0);
338 DUMPREG(HDMI_V_SYNC_GEN_1_1);
339 DUMPREG(HDMI_V_SYNC_GEN_1_2);
340 DUMPREG(HDMI_V_SYNC_GEN_2_0);
341 DUMPREG(HDMI_V_SYNC_GEN_2_1);
342 DUMPREG(HDMI_V_SYNC_GEN_2_2);
343 DUMPREG(HDMI_V_SYNC_GEN_3_0);
344 DUMPREG(HDMI_V_SYNC_GEN_3_1);
345 DUMPREG(HDMI_V_SYNC_GEN_3_2);
346
347 dev_dbg(hdev->dev, "%s: ---- TG REGISTERS ----\n", prefix);
348 DUMPREG(HDMI_TG_CMD);
349 DUMPREG(HDMI_TG_H_FSZ_L);
350 DUMPREG(HDMI_TG_H_FSZ_H);
351 DUMPREG(HDMI_TG_HACT_ST_L);
352 DUMPREG(HDMI_TG_HACT_ST_H);
353 DUMPREG(HDMI_TG_HACT_SZ_L);
354 DUMPREG(HDMI_TG_HACT_SZ_H);
355 DUMPREG(HDMI_TG_V_FSZ_L);
356 DUMPREG(HDMI_TG_V_FSZ_H);
357 DUMPREG(HDMI_TG_VSYNC_L);
358 DUMPREG(HDMI_TG_VSYNC_H);
359 DUMPREG(HDMI_TG_VSYNC2_L);
360 DUMPREG(HDMI_TG_VSYNC2_H);
361 DUMPREG(HDMI_TG_VACT_ST_L);
362 DUMPREG(HDMI_TG_VACT_ST_H);
363 DUMPREG(HDMI_TG_VACT_SZ_L);
364 DUMPREG(HDMI_TG_VACT_SZ_H);
365 DUMPREG(HDMI_TG_FIELD_CHG_L);
366 DUMPREG(HDMI_TG_FIELD_CHG_H);
367 DUMPREG(HDMI_TG_VACT_ST2_L);
368 DUMPREG(HDMI_TG_VACT_ST2_H);
369 DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_L);
370 DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_H);
371 DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_L);
372 DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_H);
373 DUMPREG(HDMI_TG_FIELD_TOP_HDMI_L);
374 DUMPREG(HDMI_TG_FIELD_TOP_HDMI_H);
375 DUMPREG(HDMI_TG_FIELD_BOT_HDMI_L);
376 DUMPREG(HDMI_TG_FIELD_BOT_HDMI_H);
377#undef DUMPREG
378}
379
380static const struct hdmi_timings hdmi_timings_480p = {
381 .hact = { .beg = 138, .end = 858 },
382 .hsyn_pol = 1,
383 .hsyn = { .beg = 16, .end = 16 + 62 },
384 .interlaced = 0,
385 .vact[0] = { .beg = 42 + 3, .end = 522 + 3 },
386 .vsyn_pol = 1,
387 .vsyn[0] = { .beg = 6 + 3, .end = 12 + 3},
388};
389
390static const struct hdmi_timings hdmi_timings_576p50 = {
391 .hact = { .beg = 144, .end = 864 },
392 .hsyn_pol = 1,
393 .hsyn = { .beg = 12, .end = 12 + 64 },
394 .interlaced = 0,
395 .vact[0] = { .beg = 44 + 5, .end = 620 + 5 },
396 .vsyn_pol = 1,
397 .vsyn[0] = { .beg = 0 + 5, .end = 5 + 5},
398};
399
400static const struct hdmi_timings hdmi_timings_720p60 = {
401 .hact = { .beg = 370, .end = 1650 },
402 .hsyn_pol = 0,
403 .hsyn = { .beg = 110, .end = 110 + 40 },
404 .interlaced = 0,
405 .vact[0] = { .beg = 25 + 5, .end = 745 + 5 },
406 .vsyn_pol = 0,
407 .vsyn[0] = { .beg = 0 + 5, .end = 5 + 5},
408};
409
410static const struct hdmi_timings hdmi_timings_720p50 = {
411 .hact = { .beg = 700, .end = 1980 },
412 .hsyn_pol = 0,
413 .hsyn = { .beg = 440, .end = 440 + 40 },
414 .interlaced = 0,
415 .vact[0] = { .beg = 25 + 5, .end = 745 + 5 },
416 .vsyn_pol = 0,
417 .vsyn[0] = { .beg = 0 + 5, .end = 5 + 5},
418};
419
420static const struct hdmi_timings hdmi_timings_1080p24 = {
421 .hact = { .beg = 830, .end = 2750 },
422 .hsyn_pol = 0,
423 .hsyn = { .beg = 638, .end = 638 + 44 },
424 .interlaced = 0,
425 .vact[0] = { .beg = 41 + 4, .end = 1121 + 4 },
426 .vsyn_pol = 0,
427 .vsyn[0] = { .beg = 0 + 4, .end = 5 + 4},
428};
429
430static const struct hdmi_timings hdmi_timings_1080p60 = {
431 .hact = { .beg = 280, .end = 2200 },
432 .hsyn_pol = 0,
433 .hsyn = { .beg = 88, .end = 88 + 44 },
434 .interlaced = 0,
435 .vact[0] = { .beg = 41 + 4, .end = 1121 + 4 },
436 .vsyn_pol = 0,
437 .vsyn[0] = { .beg = 0 + 4, .end = 5 + 4},
438};
439
440static const struct hdmi_timings hdmi_timings_1080i60 = {
441 .hact = { .beg = 280, .end = 2200 },
442 .hsyn_pol = 0,
443 .hsyn = { .beg = 88, .end = 88 + 44 },
444 .interlaced = 1,
445 .vact[0] = { .beg = 20 + 2, .end = 560 + 2 },
446 .vact[1] = { .beg = 583 + 2, .end = 1123 + 2 },
447 .vsyn_pol = 0,
448 .vsyn_off = 1100,
449 .vsyn[0] = { .beg = 0 + 2, .end = 5 + 2},
450 .vsyn[1] = { .beg = 562 + 2, .end = 567 + 2},
451};
452
453static const struct hdmi_timings hdmi_timings_1080i50 = {
454 .hact = { .beg = 720, .end = 2640 },
455 .hsyn_pol = 0,
456 .hsyn = { .beg = 528, .end = 528 + 44 },
457 .interlaced = 1,
458 .vact[0] = { .beg = 20 + 2, .end = 560 + 2 },
459 .vact[1] = { .beg = 583 + 2, .end = 1123 + 2 },
460 .vsyn_pol = 0,
461 .vsyn_off = 1320,
462 .vsyn[0] = { .beg = 0 + 2, .end = 5 + 2},
463 .vsyn[1] = { .beg = 562 + 2, .end = 567 + 2},
464};
465
466static const struct hdmi_timings hdmi_timings_1080p50 = {
467 .hact = { .beg = 720, .end = 2640 },
468 .hsyn_pol = 0,
469 .hsyn = { .beg = 528, .end = 528 + 44 },
470 .interlaced = 0,
471 .vact[0] = { .beg = 41 + 4, .end = 1121 + 4 },
472 .vsyn_pol = 0,
473 .vsyn[0] = { .beg = 0 + 4, .end = 5 + 4},
474};
475
476static const struct {
477 u32 preset;
478 const struct hdmi_timings *timings;
479} hdmi_timings[] = {
480 { V4L2_DV_480P59_94, &hdmi_timings_480p },
481 { V4L2_DV_576P50, &hdmi_timings_576p50 },
482 { V4L2_DV_720P50, &hdmi_timings_720p50 },
483 { V4L2_DV_720P59_94, &hdmi_timings_720p60 },
484 { V4L2_DV_720P60, &hdmi_timings_720p60 },
485 { V4L2_DV_1080P24, &hdmi_timings_1080p24 },
486 { V4L2_DV_1080P30, &hdmi_timings_1080p60 },
487 { V4L2_DV_1080P50, &hdmi_timings_1080p50 },
488 { V4L2_DV_1080I50, &hdmi_timings_1080i50 },
489 { V4L2_DV_1080I60, &hdmi_timings_1080i60 },
490 { V4L2_DV_1080P60, &hdmi_timings_1080p60 },
491};
492
493static const struct hdmi_timings *hdmi_preset2timings(u32 preset)
494{
495 int i;
496
497 for (i = 0; i < ARRAY_SIZE(hdmi_timings); ++i)
498 if (hdmi_timings[i].preset == preset)
499 return hdmi_timings[i].timings;
500 return NULL;
501}
502
503static int hdmi_streamon(struct hdmi_device *hdev)
504{
505 struct device *dev = hdev->dev;
506 struct hdmi_resources *res = &hdev->res;
507 int ret, tries;
508
509 dev_dbg(dev, "%s\n", __func__);
510
511 ret = hdmi_conf_apply(hdev);
512 if (ret)
513 return ret;
514
515 ret = v4l2_subdev_call(hdev->phy_sd, video, s_stream, 1);
516 if (ret)
517 return ret;
518
519 /* waiting for HDMIPHY's PLL to get to steady state */
520 for (tries = 100; tries; --tries) {
521 u32 val = hdmi_read(hdev, HDMI_PHY_STATUS);
522 if (val & HDMI_PHY_STATUS_READY)
523 break;
524 mdelay(1);
525 }
526 /* steady state not achieved */
527 if (tries == 0) {
528 dev_err(dev, "hdmiphy's pll could not reach steady state.\n");
529 v4l2_subdev_call(hdev->phy_sd, video, s_stream, 0);
530 hdmi_dumpregs(hdev, "hdmiphy - s_stream");
531 return -EIO;
532 }
533
534 /* starting MHL */
535 ret = v4l2_subdev_call(hdev->mhl_sd, video, s_stream, 1);
536 if (hdev->mhl_sd && ret) {
537 v4l2_subdev_call(hdev->phy_sd, video, s_stream, 0);
538 hdmi_dumpregs(hdev, "mhl - s_stream");
539 return -EIO;
540 }
541
542 /* hdmiphy clock is used for HDMI in streaming mode */
543 clk_disable(res->sclk_hdmi);
544 clk_set_parent(res->sclk_hdmi, res->sclk_hdmiphy);
545 clk_enable(res->sclk_hdmi);
546
547 /* enable HDMI and timing generator */
548 hdmi_write_mask(hdev, HDMI_CON_0, ~0, HDMI_EN);
549 hdmi_write_mask(hdev, HDMI_TG_CMD, ~0, HDMI_TG_EN);
550 hdmi_dumpregs(hdev, "streamon");
551 return 0;
552}
553
554static int hdmi_streamoff(struct hdmi_device *hdev)
555{
556 struct device *dev = hdev->dev;
557 struct hdmi_resources *res = &hdev->res;
558
559 dev_dbg(dev, "%s\n", __func__);
560
561 hdmi_write_mask(hdev, HDMI_CON_0, 0, HDMI_EN);
562 hdmi_write_mask(hdev, HDMI_TG_CMD, 0, HDMI_TG_EN);
563
564 /* pixel(vpll) clock is used for HDMI in config mode */
565 clk_disable(res->sclk_hdmi);
566 clk_set_parent(res->sclk_hdmi, res->sclk_pixel);
567 clk_enable(res->sclk_hdmi);
568
569 v4l2_subdev_call(hdev->mhl_sd, video, s_stream, 0);
570 v4l2_subdev_call(hdev->phy_sd, video, s_stream, 0);
571
572 hdmi_dumpregs(hdev, "streamoff");
573 return 0;
574}
575
576static int hdmi_s_stream(struct v4l2_subdev *sd, int enable)
577{
578 struct hdmi_device *hdev = sd_to_hdmi_dev(sd);
579 struct device *dev = hdev->dev;
580
581 dev_dbg(dev, "%s(%d)\n", __func__, enable);
582 if (enable)
583 return hdmi_streamon(hdev);
584 return hdmi_streamoff(hdev);
585}
586
587static void hdmi_resource_poweron(struct hdmi_resources *res)
588{
589 /* turn HDMI power on */
590 regulator_bulk_enable(res->regul_count, res->regul_bulk);
591 /* power-on hdmi physical interface */
592 clk_enable(res->hdmiphy);
593 /* use VPP as parent clock; HDMIPHY is not working yet */
594 clk_set_parent(res->sclk_hdmi, res->sclk_pixel);
595 /* turn clocks on */
596 clk_enable(res->sclk_hdmi);
597}
598
599static void hdmi_resource_poweroff(struct hdmi_resources *res)
600{
601 /* turn clocks off */
602 clk_disable(res->sclk_hdmi);
603 /* power-off hdmiphy */
604 clk_disable(res->hdmiphy);
605 /* turn HDMI power off */
606 regulator_bulk_disable(res->regul_count, res->regul_bulk);
607}
608
609static int hdmi_s_power(struct v4l2_subdev *sd, int on)
610{
611 struct hdmi_device *hdev = sd_to_hdmi_dev(sd);
612 int ret;
613
614 if (on)
615 ret = pm_runtime_get_sync(hdev->dev);
616 else
617 ret = pm_runtime_put_sync(hdev->dev);
618 /* only values < 0 indicate errors */
619 return IS_ERR_VALUE(ret) ? ret : 0;
620}
621
622static int hdmi_s_dv_preset(struct v4l2_subdev *sd,
623 struct v4l2_dv_preset *preset)
624{
625 struct hdmi_device *hdev = sd_to_hdmi_dev(sd);
626 struct device *dev = hdev->dev;
627 const struct hdmi_timings *conf;
628
629 conf = hdmi_preset2timings(preset->preset);
630 if (conf == NULL) {
631 dev_err(dev, "preset (%u) not supported\n", preset->preset);
632 return -EINVAL;
633 }
634 hdev->cur_conf = conf;
635 hdev->cur_conf_dirty = 1;
636 hdev->cur_preset = preset->preset;
637 return 0;
638}
639
640static int hdmi_g_dv_preset(struct v4l2_subdev *sd,
641 struct v4l2_dv_preset *preset)
642{
643 memset(preset, 0, sizeof(*preset));
644 preset->preset = sd_to_hdmi_dev(sd)->cur_preset;
645 return 0;
646}
647
648static int hdmi_g_mbus_fmt(struct v4l2_subdev *sd,
649 struct v4l2_mbus_framefmt *fmt)
650{
651 struct hdmi_device *hdev = sd_to_hdmi_dev(sd);
652 const struct hdmi_timings *t = hdev->cur_conf;
653
654 dev_dbg(hdev->dev, "%s\n", __func__);
655 if (!hdev->cur_conf)
656 return -EINVAL;
657 memset(fmt, 0, sizeof *fmt);
658 fmt->width = t->hact.end - t->hact.beg;
659 fmt->height = t->vact[0].end - t->vact[0].beg;
660 fmt->code = V4L2_MBUS_FMT_FIXED; /* means RGB888 */
661 fmt->colorspace = V4L2_COLORSPACE_SRGB;
662 if (t->interlaced) {
663 fmt->field = V4L2_FIELD_INTERLACED;
664 fmt->height *= 2;
665 } else {
666 fmt->field = V4L2_FIELD_NONE;
667 }
668 return 0;
669}
670
671static int hdmi_enum_dv_presets(struct v4l2_subdev *sd,
672 struct v4l2_dv_enum_preset *preset)
673{
674 if (preset->index >= ARRAY_SIZE(hdmi_timings))
675 return -EINVAL;
676 return v4l_fill_dv_preset_info(hdmi_timings[preset->index].preset,
677 preset);
678}
679
680static const struct v4l2_subdev_core_ops hdmi_sd_core_ops = {
681 .s_power = hdmi_s_power,
682};
683
684static const struct v4l2_subdev_video_ops hdmi_sd_video_ops = {
685 .s_dv_preset = hdmi_s_dv_preset,
686 .g_dv_preset = hdmi_g_dv_preset,
687 .enum_dv_presets = hdmi_enum_dv_presets,
688 .g_mbus_fmt = hdmi_g_mbus_fmt,
689 .s_stream = hdmi_s_stream,
690};
691
692static const struct v4l2_subdev_ops hdmi_sd_ops = {
693 .core = &hdmi_sd_core_ops,
694 .video = &hdmi_sd_video_ops,
695};
696
697static int hdmi_runtime_suspend(struct device *dev)
698{
699 struct v4l2_subdev *sd = dev_get_drvdata(dev);
700 struct hdmi_device *hdev = sd_to_hdmi_dev(sd);
701
702 dev_dbg(dev, "%s\n", __func__);
703 v4l2_subdev_call(hdev->mhl_sd, core, s_power, 0);
704 hdmi_resource_poweroff(&hdev->res);
705 /* flag that device context is lost */
706 hdev->cur_conf_dirty = 1;
707 return 0;
708}
709
710static int hdmi_runtime_resume(struct device *dev)
711{
712 struct v4l2_subdev *sd = dev_get_drvdata(dev);
713 struct hdmi_device *hdev = sd_to_hdmi_dev(sd);
714 int ret = 0;
715
716 dev_dbg(dev, "%s\n", __func__);
717
718 hdmi_resource_poweron(&hdev->res);
719
720 /* starting MHL */
721 ret = v4l2_subdev_call(hdev->mhl_sd, core, s_power, 1);
722 if (hdev->mhl_sd && ret)
723 goto fail;
724
725 dev_dbg(dev, "poweron succeed\n");
726
727 return 0;
728
729fail:
730 hdmi_resource_poweroff(&hdev->res);
731 dev_err(dev, "poweron failed\n");
732
733 return ret;
734}
735
736static const struct dev_pm_ops hdmi_pm_ops = {
737 .runtime_suspend = hdmi_runtime_suspend,
738 .runtime_resume = hdmi_runtime_resume,
739};
740
741static void hdmi_resources_cleanup(struct hdmi_device *hdev)
742{
743 struct hdmi_resources *res = &hdev->res;
744
745 dev_dbg(hdev->dev, "HDMI resource cleanup\n");
746 /* put clocks, power */
747 if (res->regul_count)
748 regulator_bulk_free(res->regul_count, res->regul_bulk);
749 /* kfree is NULL-safe */
750 kfree(res->regul_bulk);
751 if (!IS_ERR_OR_NULL(res->hdmiphy))
752 clk_put(res->hdmiphy);
753 if (!IS_ERR_OR_NULL(res->sclk_hdmiphy))
754 clk_put(res->sclk_hdmiphy);
755 if (!IS_ERR_OR_NULL(res->sclk_pixel))
756 clk_put(res->sclk_pixel);
757 if (!IS_ERR_OR_NULL(res->sclk_hdmi))
758 clk_put(res->sclk_hdmi);
759 if (!IS_ERR_OR_NULL(res->hdmi))
760 clk_put(res->hdmi);
761 memset(res, 0, sizeof *res);
762}
763
764static int hdmi_resources_init(struct hdmi_device *hdev)
765{
766 struct device *dev = hdev->dev;
767 struct hdmi_resources *res = &hdev->res;
768 static char *supply[] = {
769 "hdmi-en",
770 "vdd",
771 "vdd_osc",
772 "vdd_pll",
773 };
774 int i, ret;
775
776 dev_dbg(dev, "HDMI resource init\n");
777
778 memset(res, 0, sizeof *res);
779 /* get clocks, power */
780
781 res->hdmi = clk_get(dev, "hdmi");
782 if (IS_ERR_OR_NULL(res->hdmi)) {
783 dev_err(dev, "failed to get clock 'hdmi'\n");
784 goto fail;
785 }
786 res->sclk_hdmi = clk_get(dev, "sclk_hdmi");
787 if (IS_ERR_OR_NULL(res->sclk_hdmi)) {
788 dev_err(dev, "failed to get clock 'sclk_hdmi'\n");
789 goto fail;
790 }
791 res->sclk_pixel = clk_get(dev, "sclk_pixel");
792 if (IS_ERR_OR_NULL(res->sclk_pixel)) {
793 dev_err(dev, "failed to get clock 'sclk_pixel'\n");
794 goto fail;
795 }
796 res->sclk_hdmiphy = clk_get(dev, "sclk_hdmiphy");
797 if (IS_ERR_OR_NULL(res->sclk_hdmiphy)) {
798 dev_err(dev, "failed to get clock 'sclk_hdmiphy'\n");
799 goto fail;
800 }
801 res->hdmiphy = clk_get(dev, "hdmiphy");
802 if (IS_ERR_OR_NULL(res->hdmiphy)) {
803 dev_err(dev, "failed to get clock 'hdmiphy'\n");
804 goto fail;
805 }
806 res->regul_bulk = kcalloc(ARRAY_SIZE(supply),
807 sizeof(res->regul_bulk[0]), GFP_KERNEL);
808 if (!res->regul_bulk) {
809 dev_err(dev, "failed to get memory for regulators\n");
810 goto fail;
811 }
812 for (i = 0; i < ARRAY_SIZE(supply); ++i) {
813 res->regul_bulk[i].supply = supply[i];
814 res->regul_bulk[i].consumer = NULL;
815 }
816
817 ret = regulator_bulk_get(dev, ARRAY_SIZE(supply), res->regul_bulk);
818 if (ret) {
819 dev_err(dev, "failed to get regulators\n");
820 goto fail;
821 }
822 res->regul_count = ARRAY_SIZE(supply);
823
824 return 0;
825fail:
826 dev_err(dev, "HDMI resource init - failed\n");
827 hdmi_resources_cleanup(hdev);
828 return -ENODEV;
829}
830
831static int __devinit hdmi_probe(struct platform_device *pdev)
832{
833 struct device *dev = &pdev->dev;
834 struct resource *res;
835 struct i2c_adapter *adapter;
836 struct v4l2_subdev *sd;
837 struct hdmi_device *hdmi_dev = NULL;
838 struct s5p_hdmi_platform_data *pdata = dev->platform_data;
839 int ret;
840
841 dev_dbg(dev, "probe start\n");
842
843 if (!pdata) {
844 dev_err(dev, "platform data is missing\n");
845 ret = -ENODEV;
846 goto fail;
847 }
848
849 hdmi_dev = devm_kzalloc(&pdev->dev, sizeof(*hdmi_dev), GFP_KERNEL);
850 if (!hdmi_dev) {
851 dev_err(dev, "out of memory\n");
852 ret = -ENOMEM;
853 goto fail;
854 }
855
856 hdmi_dev->dev = dev;
857
858 ret = hdmi_resources_init(hdmi_dev);
859 if (ret)
860 goto fail;
861
862 /* mapping HDMI registers */
863 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
864 if (res == NULL) {
865 dev_err(dev, "get memory resource failed.\n");
866 ret = -ENXIO;
867 goto fail_init;
868 }
869
870 hdmi_dev->regs = devm_ioremap(&pdev->dev, res->start,
871 resource_size(res));
872 if (hdmi_dev->regs == NULL) {
873 dev_err(dev, "register mapping failed.\n");
874 ret = -ENXIO;
875 goto fail_init;
876 }
877
878 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
879 if (res == NULL) {
880 dev_err(dev, "get interrupt resource failed.\n");
881 ret = -ENXIO;
882 goto fail_init;
883 }
884
885 ret = devm_request_irq(&pdev->dev, res->start, hdmi_irq_handler, 0,
886 "hdmi", hdmi_dev);
887 if (ret) {
888 dev_err(dev, "request interrupt failed.\n");
889 goto fail_init;
890 }
891 hdmi_dev->irq = res->start;
892
893 /* setting v4l2 name to prevent WARN_ON in v4l2_device_register */
894 strlcpy(hdmi_dev->v4l2_dev.name, dev_name(dev),
895 sizeof(hdmi_dev->v4l2_dev.name));
896 /* passing NULL owner prevents driver from erasing drvdata */
897 ret = v4l2_device_register(NULL, &hdmi_dev->v4l2_dev);
898 if (ret) {
899 dev_err(dev, "could not register v4l2 device.\n");
900 goto fail_init;
901 }
902
903 /* testing if hdmiphy info is present */
904 if (!pdata->hdmiphy_info) {
905 dev_err(dev, "hdmiphy info is missing in platform data\n");
906 ret = -ENXIO;
907 goto fail_vdev;
908 }
909
910 adapter = i2c_get_adapter(pdata->hdmiphy_bus);
911 if (adapter == NULL) {
912 dev_err(dev, "hdmiphy adapter request failed\n");
913 ret = -ENXIO;
914 goto fail_vdev;
915 }
916
917 hdmi_dev->phy_sd = v4l2_i2c_new_subdev_board(&hdmi_dev->v4l2_dev,
918 adapter, pdata->hdmiphy_info, NULL);
919 /* on failure or not adapter is no longer useful */
920 i2c_put_adapter(adapter);
921 if (hdmi_dev->phy_sd == NULL) {
922 dev_err(dev, "missing subdev for hdmiphy\n");
923 ret = -ENODEV;
924 goto fail_vdev;
925 }
926
927 /* initialization of MHL interface if present */
928 if (pdata->mhl_info) {
929 adapter = i2c_get_adapter(pdata->mhl_bus);
930 if (adapter == NULL) {
931 dev_err(dev, "MHL adapter request failed\n");
932 ret = -ENXIO;
933 goto fail_vdev;
934 }
935
936 hdmi_dev->mhl_sd = v4l2_i2c_new_subdev_board(
937 &hdmi_dev->v4l2_dev, adapter,
938 pdata->mhl_info, NULL);
939 /* on failure or not adapter is no longer useful */
940 i2c_put_adapter(adapter);
941 if (hdmi_dev->mhl_sd == NULL) {
942 dev_err(dev, "missing subdev for MHL\n");
943 ret = -ENODEV;
944 goto fail_vdev;
945 }
946 }
947
948 clk_enable(hdmi_dev->res.hdmi);
949
950 pm_runtime_enable(dev);
951
952 sd = &hdmi_dev->sd;
953 v4l2_subdev_init(sd, &hdmi_sd_ops);
954 sd->owner = THIS_MODULE;
955
956 strlcpy(sd->name, "s5p-hdmi", sizeof sd->name);
957 hdmi_dev->cur_preset = HDMI_DEFAULT_PRESET;
958 /* FIXME: missing fail preset is not supported */
959 hdmi_dev->cur_conf = hdmi_preset2timings(hdmi_dev->cur_preset);
960 hdmi_dev->cur_conf_dirty = 1;
961
962 /* storing subdev for call that have only access to struct device */
963 dev_set_drvdata(dev, sd);
964
965 dev_info(dev, "probe successful\n");
966
967 return 0;
968
969fail_vdev:
970 v4l2_device_unregister(&hdmi_dev->v4l2_dev);
971
972fail_init:
973 hdmi_resources_cleanup(hdmi_dev);
974
975fail:
976 dev_err(dev, "probe failed\n");
977 return ret;
978}
979
980static int __devexit hdmi_remove(struct platform_device *pdev)
981{
982 struct device *dev = &pdev->dev;
983 struct v4l2_subdev *sd = dev_get_drvdata(dev);
984 struct hdmi_device *hdmi_dev = sd_to_hdmi_dev(sd);
985
986 pm_runtime_disable(dev);
987 clk_disable(hdmi_dev->res.hdmi);
988 v4l2_device_unregister(&hdmi_dev->v4l2_dev);
989 disable_irq(hdmi_dev->irq);
990 hdmi_resources_cleanup(hdmi_dev);
991 dev_info(dev, "remove successful\n");
992
993 return 0;
994}
995
996static struct platform_driver hdmi_driver __refdata = {
997 .probe = hdmi_probe,
998 .remove = __devexit_p(hdmi_remove),
999 .id_table = hdmi_driver_types,
1000 .driver = {
1001 .name = "s5p-hdmi",
1002 .owner = THIS_MODULE,
1003 .pm = &hdmi_pm_ops,
1004 }
1005};
1006
1007module_platform_driver(hdmi_driver);
diff --git a/drivers/media/video/s5p-tv/hdmiphy_drv.c b/drivers/media/video/s5p-tv/hdmiphy_drv.c
deleted file mode 100644
index f67b38631801..000000000000
--- a/drivers/media/video/s5p-tv/hdmiphy_drv.c
+++ /dev/null
@@ -1,329 +0,0 @@
1/*
2 * Samsung HDMI Physical interface driver
3 *
4 * Copyright (C) 2010-2011 Samsung Electronics Co.Ltd
5 * Author: Tomasz Stanislawski <t.stanislaws@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#include <linux/module.h>
14#include <linux/i2c.h>
15#include <linux/slab.h>
16#include <linux/clk.h>
17#include <linux/io.h>
18#include <linux/interrupt.h>
19#include <linux/irq.h>
20#include <linux/err.h>
21
22#include <media/v4l2-subdev.h>
23
24MODULE_AUTHOR("Tomasz Stanislawski <t.stanislaws@samsung.com>");
25MODULE_DESCRIPTION("Samsung HDMI Physical interface driver");
26MODULE_LICENSE("GPL");
27
28struct hdmiphy_conf {
29 unsigned long pixclk;
30 const u8 *data;
31};
32
33struct hdmiphy_ctx {
34 struct v4l2_subdev sd;
35 const struct hdmiphy_conf *conf_tab;
36};
37
38static const struct hdmiphy_conf hdmiphy_conf_s5pv210[] = {
39 { .pixclk = 27000000, .data = (u8 [32]) {
40 0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40,
41 0x6B, 0x10, 0x02, 0x52, 0xDF, 0xF2, 0x54, 0x87,
42 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
43 0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00, }
44 },
45 { .pixclk = 27027000, .data = (u8 [32]) {
46 0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x09, 0x64,
47 0x6B, 0x10, 0x02, 0x52, 0xDF, 0xF2, 0x54, 0x87,
48 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
49 0x22, 0x40, 0xE2, 0x26, 0x00, 0x00, 0x00, 0x00, }
50 },
51 { .pixclk = 74176000, .data = (u8 [32]) {
52 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xEF, 0x5B,
53 0x6D, 0x10, 0x01, 0x52, 0xEF, 0xF3, 0x54, 0xB9,
54 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
55 0x22, 0x40, 0xA5, 0x26, 0x01, 0x00, 0x00, 0x00, }
56 },
57 { .pixclk = 74250000, .data = (u8 [32]) {
58 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xF8, 0x40,
59 0x6A, 0x10, 0x01, 0x52, 0xFF, 0xF1, 0x54, 0xBA,
60 0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xE0,
61 0x22, 0x40, 0xA4, 0x26, 0x01, 0x00, 0x00, 0x00, }
62 },
63 { /* end marker */ }
64};
65
66static const struct hdmiphy_conf hdmiphy_conf_exynos4210[] = {
67 { .pixclk = 27000000, .data = (u8 [32]) {
68 0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40,
69 0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
70 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
71 0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00, }
72 },
73 { .pixclk = 27027000, .data = (u8 [32]) {
74 0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x09, 0x64,
75 0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
76 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
77 0x22, 0x40, 0xE2, 0x26, 0x00, 0x00, 0x00, 0x00, }
78 },
79 { .pixclk = 74176000, .data = (u8 [32]) {
80 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xEF, 0x5B,
81 0x6D, 0x10, 0x01, 0x51, 0xEF, 0xF3, 0x54, 0xB9,
82 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
83 0x22, 0x40, 0xA5, 0x26, 0x01, 0x00, 0x00, 0x00, }
84 },
85 { .pixclk = 74250000, .data = (u8 [32]) {
86 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xF8, 0x40,
87 0x6A, 0x10, 0x01, 0x51, 0xFF, 0xF1, 0x54, 0xBA,
88 0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xE0,
89 0x22, 0x40, 0xA4, 0x26, 0x01, 0x00, 0x00, 0x00, }
90 },
91 { .pixclk = 148352000, .data = (u8 [32]) {
92 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xEF, 0x5B,
93 0x6D, 0x18, 0x00, 0x51, 0xEF, 0xF3, 0x54, 0xB9,
94 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
95 0x11, 0x40, 0xA5, 0x26, 0x02, 0x00, 0x00, 0x00, }
96 },
97 { .pixclk = 148500000, .data = (u8 [32]) {
98 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xF8, 0x40,
99 0x6A, 0x18, 0x00, 0x51, 0xFF, 0xF1, 0x54, 0xBA,
100 0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xE0,
101 0x11, 0x40, 0xA4, 0x26, 0x02, 0x00, 0x00, 0x00, }
102 },
103 { /* end marker */ }
104};
105
106static const struct hdmiphy_conf hdmiphy_conf_exynos4212[] = {
107 { .pixclk = 27000000, .data = (u8 [32]) {
108 0x01, 0x11, 0x2D, 0x75, 0x00, 0x01, 0x00, 0x08,
109 0x82, 0x00, 0x0E, 0xD9, 0x45, 0xA0, 0x34, 0xC0,
110 0x0B, 0x80, 0x12, 0x87, 0x08, 0x24, 0x24, 0x71,
111 0x54, 0xE3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, }
112 },
113 { .pixclk = 27027000, .data = (u8 [32]) {
114 0x01, 0x91, 0x2D, 0x72, 0x00, 0x64, 0x12, 0x08,
115 0x43, 0x20, 0x0E, 0xD9, 0x45, 0xA0, 0x34, 0xC0,
116 0x0B, 0x80, 0x12, 0x87, 0x08, 0x24, 0x24, 0x71,
117 0x54, 0xE2, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, }
118 },
119 { .pixclk = 74176000, .data = (u8 [32]) {
120 0x01, 0x91, 0x3E, 0x35, 0x00, 0x5B, 0xDE, 0x08,
121 0x82, 0x20, 0x73, 0xD9, 0x45, 0xA0, 0x34, 0xC0,
122 0x0B, 0x80, 0x12, 0x87, 0x08, 0x24, 0x24, 0x52,
123 0x54, 0xA5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x00, }
124 },
125 { .pixclk = 74250000, .data = (u8 [32]) {
126 0x01, 0x91, 0x3E, 0x35, 0x00, 0x40, 0xF0, 0x08,
127 0x82, 0x20, 0x73, 0xD9, 0x45, 0xA0, 0x34, 0xC0,
128 0x0B, 0x80, 0x12, 0x87, 0x08, 0x24, 0x24, 0x52,
129 0x54, 0xA4, 0x24, 0x01, 0x00, 0x00, 0x01, 0x00, }
130 },
131 { .pixclk = 148500000, .data = (u8 [32]) {
132 0x01, 0x91, 0x3E, 0x15, 0x00, 0x40, 0xF0, 0x08,
133 0x82, 0x20, 0x73, 0xD9, 0x45, 0xA0, 0x34, 0xC0,
134 0x0B, 0x80, 0x12, 0x87, 0x08, 0x24, 0x24, 0xA4,
135 0x54, 0x4A, 0x25, 0x03, 0x00, 0x00, 0x01, 0x00, }
136 },
137 { /* end marker */ }
138};
139
140static const struct hdmiphy_conf hdmiphy_conf_exynos4412[] = {
141 { .pixclk = 27000000, .data = (u8 [32]) {
142 0x01, 0x11, 0x2D, 0x75, 0x40, 0x01, 0x00, 0x08,
143 0x82, 0x00, 0x0E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
144 0x08, 0x80, 0x11, 0x84, 0x02, 0x22, 0x44, 0x86,
145 0x54, 0xE4, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, }
146 },
147 { .pixclk = 27027000, .data = (u8 [32]) {
148 0x01, 0x91, 0x2D, 0x72, 0x40, 0x64, 0x12, 0x08,
149 0x43, 0x20, 0x0E, 0xD9, 0x45, 0xA0, 0xAC, 0x80,
150 0x08, 0x80, 0x11, 0x84, 0x02, 0x22, 0x44, 0x86,
151 0x54, 0xE3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, }
152 },
153 { .pixclk = 74176000, .data = (u8 [32]) {
154 0x01, 0x91, 0x1F, 0x10, 0x40, 0x5B, 0xEF, 0x08,
155 0x81, 0x20, 0xB9, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
156 0x08, 0x80, 0x11, 0x84, 0x02, 0x22, 0x44, 0x86,
157 0x54, 0xA6, 0x24, 0x01, 0x00, 0x00, 0x01, 0x00, }
158 },
159 { .pixclk = 74250000, .data = (u8 [32]) {
160 0x01, 0x91, 0x1F, 0x10, 0x40, 0x40, 0xF8, 0x08,
161 0x81, 0x20, 0xBA, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
162 0x08, 0x80, 0x11, 0x84, 0x02, 0x22, 0x44, 0x86,
163 0x54, 0xA5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x00, }
164 },
165 { .pixclk = 148500000, .data = (u8 [32]) {
166 0x01, 0x91, 0x1F, 0x00, 0x40, 0x40, 0xF8, 0x08,
167 0x81, 0x20, 0xBA, 0xD8, 0x45, 0xA0, 0xAC, 0x80,
168 0x08, 0x80, 0x11, 0x84, 0x02, 0x22, 0x44, 0x86,
169 0x54, 0x4B, 0x25, 0x03, 0x00, 0x00, 0x01, 0x00, }
170 },
171 { /* end marker */ }
172};
173
174static inline struct hdmiphy_ctx *sd_to_ctx(struct v4l2_subdev *sd)
175{
176 return container_of(sd, struct hdmiphy_ctx, sd);
177}
178
179static unsigned long hdmiphy_preset_to_pixclk(u32 preset)
180{
181 static const unsigned long pixclk[] = {
182 [V4L2_DV_480P59_94] = 27000000,
183 [V4L2_DV_576P50] = 27000000,
184 [V4L2_DV_720P59_94] = 74176000,
185 [V4L2_DV_720P50] = 74250000,
186 [V4L2_DV_720P60] = 74250000,
187 [V4L2_DV_1080P24] = 74250000,
188 [V4L2_DV_1080P30] = 74250000,
189 [V4L2_DV_1080I50] = 74250000,
190 [V4L2_DV_1080I60] = 74250000,
191 [V4L2_DV_1080P50] = 148500000,
192 [V4L2_DV_1080P60] = 148500000,
193 };
194 if (preset < ARRAY_SIZE(pixclk))
195 return pixclk[preset];
196 else
197 return 0;
198}
199
200static const u8 *hdmiphy_find_conf(u32 preset, const struct hdmiphy_conf *conf)
201{
202 unsigned long pixclk;
203
204 pixclk = hdmiphy_preset_to_pixclk(preset);
205 if (!pixclk)
206 return NULL;
207
208 for (; conf->pixclk; ++conf)
209 if (conf->pixclk == pixclk)
210 return conf->data;
211 return NULL;
212}
213
214static int hdmiphy_s_power(struct v4l2_subdev *sd, int on)
215{
216 /* to be implemented */
217 return 0;
218}
219
220static int hdmiphy_s_dv_preset(struct v4l2_subdev *sd,
221 struct v4l2_dv_preset *preset)
222{
223 const u8 *data;
224 u8 buffer[32];
225 int ret;
226 struct hdmiphy_ctx *ctx = sd_to_ctx(sd);
227 struct i2c_client *client = v4l2_get_subdevdata(sd);
228 struct device *dev = &client->dev;
229
230 dev_info(dev, "s_dv_preset(preset = %d)\n", preset->preset);
231 data = hdmiphy_find_conf(preset->preset, ctx->conf_tab);
232 if (!data) {
233 dev_err(dev, "format not supported\n");
234 return -EINVAL;
235 }
236
237 /* storing configuration to the device */
238 memcpy(buffer, data, 32);
239 ret = i2c_master_send(client, buffer, 32);
240 if (ret != 32) {
241 dev_err(dev, "failed to configure HDMIPHY via I2C\n");
242 return -EIO;
243 }
244
245 return 0;
246}
247
248static int hdmiphy_s_stream(struct v4l2_subdev *sd, int enable)
249{
250 struct i2c_client *client = v4l2_get_subdevdata(sd);
251 struct device *dev = &client->dev;
252 u8 buffer[2];
253 int ret;
254
255 dev_info(dev, "s_stream(%d)\n", enable);
256 /* going to/from configuration from/to operation mode */
257 buffer[0] = 0x1f;
258 buffer[1] = enable ? 0x80 : 0x00;
259
260 ret = i2c_master_send(client, buffer, 2);
261 if (ret != 2) {
262 dev_err(dev, "stream (%d) failed\n", enable);
263 return -EIO;
264 }
265 return 0;
266}
267
268static const struct v4l2_subdev_core_ops hdmiphy_core_ops = {
269 .s_power = hdmiphy_s_power,
270};
271
272static const struct v4l2_subdev_video_ops hdmiphy_video_ops = {
273 .s_dv_preset = hdmiphy_s_dv_preset,
274 .s_stream = hdmiphy_s_stream,
275};
276
277static const struct v4l2_subdev_ops hdmiphy_ops = {
278 .core = &hdmiphy_core_ops,
279 .video = &hdmiphy_video_ops,
280};
281
282static int __devinit hdmiphy_probe(struct i2c_client *client,
283 const struct i2c_device_id *id)
284{
285 struct hdmiphy_ctx *ctx;
286
287 ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
288 if (!ctx)
289 return -ENOMEM;
290
291 ctx->conf_tab = (struct hdmiphy_conf *)id->driver_data;
292 v4l2_i2c_subdev_init(&ctx->sd, client, &hdmiphy_ops);
293
294 dev_info(&client->dev, "probe successful\n");
295 return 0;
296}
297
298static int __devexit hdmiphy_remove(struct i2c_client *client)
299{
300 struct v4l2_subdev *sd = i2c_get_clientdata(client);
301 struct hdmiphy_ctx *ctx = sd_to_ctx(sd);
302
303 kfree(ctx);
304 dev_info(&client->dev, "remove successful\n");
305
306 return 0;
307}
308
309static const struct i2c_device_id hdmiphy_id[] = {
310 { "hdmiphy", (unsigned long)hdmiphy_conf_exynos4210 },
311 { "hdmiphy-s5pv210", (unsigned long)hdmiphy_conf_s5pv210 },
312 { "hdmiphy-exynos4210", (unsigned long)hdmiphy_conf_exynos4210 },
313 { "hdmiphy-exynos4212", (unsigned long)hdmiphy_conf_exynos4212 },
314 { "hdmiphy-exynos4412", (unsigned long)hdmiphy_conf_exynos4412 },
315 { },
316};
317MODULE_DEVICE_TABLE(i2c, hdmiphy_id);
318
319static struct i2c_driver hdmiphy_driver = {
320 .driver = {
321 .name = "s5p-hdmiphy",
322 .owner = THIS_MODULE,
323 },
324 .probe = hdmiphy_probe,
325 .remove = __devexit_p(hdmiphy_remove),
326 .id_table = hdmiphy_id,
327};
328
329module_i2c_driver(hdmiphy_driver);
diff --git a/drivers/media/video/s5p-tv/mixer.h b/drivers/media/video/s5p-tv/mixer.h
deleted file mode 100644
index ddb422e23550..000000000000
--- a/drivers/media/video/s5p-tv/mixer.h
+++ /dev/null
@@ -1,365 +0,0 @@
1/*
2 * Samsung TV Mixer driver
3 *
4 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
5 *
6 * Tomasz Stanislawski, <t.stanislaws@samsung.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published
10 * by the Free Software Foundiation. either version 2 of the License,
11 * or (at your option) any later version
12 */
13
14#ifndef SAMSUNG_MIXER_H
15#define SAMSUNG_MIXER_H
16
17#ifdef CONFIG_VIDEO_SAMSUNG_S5P_MIXER_DEBUG
18 #define DEBUG
19#endif
20
21#include <linux/fb.h>
22#include <linux/kernel.h>
23#include <linux/spinlock.h>
24#include <linux/wait.h>
25#include <media/v4l2-device.h>
26#include <media/videobuf2-core.h>
27
28#include "regs-mixer.h"
29
30/** maximum number of output interfaces */
31#define MXR_MAX_OUTPUTS 2
32/** maximum number of input interfaces (layers) */
33#define MXR_MAX_LAYERS 3
34#define MXR_DRIVER_NAME "s5p-mixer"
35/** maximal number of planes for every layer */
36#define MXR_MAX_PLANES 2
37
38#define MXR_ENABLE 1
39#define MXR_DISABLE 0
40
41/** description of a macroblock for packed formats */
42struct mxr_block {
43 /** vertical number of pixels in macroblock */
44 unsigned int width;
45 /** horizontal number of pixels in macroblock */
46 unsigned int height;
47 /** size of block in bytes */
48 unsigned int size;
49};
50
51/** description of supported format */
52struct mxr_format {
53 /** format name/mnemonic */
54 const char *name;
55 /** fourcc identifier */
56 u32 fourcc;
57 /** colorspace identifier */
58 enum v4l2_colorspace colorspace;
59 /** number of planes in image data */
60 int num_planes;
61 /** description of block for each plane */
62 struct mxr_block plane[MXR_MAX_PLANES];
63 /** number of subframes in image data */
64 int num_subframes;
65 /** specifies to which subframe belong given plane */
66 int plane2subframe[MXR_MAX_PLANES];
67 /** internal code, driver dependant */
68 unsigned long cookie;
69};
70
71/** description of crop configuration for image */
72struct mxr_crop {
73 /** width of layer in pixels */
74 unsigned int full_width;
75 /** height of layer in pixels */
76 unsigned int full_height;
77 /** horizontal offset of first pixel to be displayed */
78 unsigned int x_offset;
79 /** vertical offset of first pixel to be displayed */
80 unsigned int y_offset;
81 /** width of displayed data in pixels */
82 unsigned int width;
83 /** height of displayed data in pixels */
84 unsigned int height;
85 /** indicate which fields are present in buffer */
86 unsigned int field;
87};
88
89/** stages of geometry operations */
90enum mxr_geometry_stage {
91 MXR_GEOMETRY_SINK,
92 MXR_GEOMETRY_COMPOSE,
93 MXR_GEOMETRY_CROP,
94 MXR_GEOMETRY_SOURCE,
95};
96
97/* flag indicating that offset should be 0 */
98#define MXR_NO_OFFSET 0x80000000
99
100/** description of transformation from source to destination image */
101struct mxr_geometry {
102 /** cropping for source image */
103 struct mxr_crop src;
104 /** cropping for destination image */
105 struct mxr_crop dst;
106 /** layer-dependant description of horizontal scaling */
107 unsigned int x_ratio;
108 /** layer-dependant description of vertical scaling */
109 unsigned int y_ratio;
110};
111
112/** instance of a buffer */
113struct mxr_buffer {
114 /** common v4l buffer stuff -- must be first */
115 struct vb2_buffer vb;
116 /** node for layer's lists */
117 struct list_head list;
118};
119
120
121/** internal states of layer */
122enum mxr_layer_state {
123 /** layers is not shown */
124 MXR_LAYER_IDLE = 0,
125 /** layer is shown */
126 MXR_LAYER_STREAMING,
127 /** state before STREAMOFF is finished */
128 MXR_LAYER_STREAMING_FINISH,
129};
130
131/** forward declarations */
132struct mxr_device;
133struct mxr_layer;
134
135/** callback for layers operation */
136struct mxr_layer_ops {
137 /* TODO: try to port it to subdev API */
138 /** handler for resource release function */
139 void (*release)(struct mxr_layer *);
140 /** setting buffer to HW */
141 void (*buffer_set)(struct mxr_layer *, struct mxr_buffer *);
142 /** setting format and geometry in HW */
143 void (*format_set)(struct mxr_layer *);
144 /** streaming stop/start */
145 void (*stream_set)(struct mxr_layer *, int);
146 /** adjusting geometry */
147 void (*fix_geometry)(struct mxr_layer *,
148 enum mxr_geometry_stage, unsigned long);
149};
150
151/** layer instance, a single window and content displayed on output */
152struct mxr_layer {
153 /** parent mixer device */
154 struct mxr_device *mdev;
155 /** layer index (unique identifier) */
156 int idx;
157 /** callbacks for layer methods */
158 struct mxr_layer_ops ops;
159 /** format array */
160 const struct mxr_format **fmt_array;
161 /** size of format array */
162 unsigned long fmt_array_size;
163
164 /** lock for protection of list and state fields */
165 spinlock_t enq_slock;
166 /** list for enqueued buffers */
167 struct list_head enq_list;
168 /** buffer currently owned by hardware in temporary registers */
169 struct mxr_buffer *update_buf;
170 /** buffer currently owned by hardware in shadow registers */
171 struct mxr_buffer *shadow_buf;
172 /** state of layer IDLE/STREAMING */
173 enum mxr_layer_state state;
174
175 /** mutex for protection of fields below */
176 struct mutex mutex;
177 /** handler for video node */
178 struct video_device vfd;
179 /** queue for output buffers */
180 struct vb2_queue vb_queue;
181 /** current image format */
182 const struct mxr_format *fmt;
183 /** current geometry of image */
184 struct mxr_geometry geo;
185};
186
187/** description of mixers output interface */
188struct mxr_output {
189 /** name of output */
190 char name[32];
191 /** output subdev */
192 struct v4l2_subdev *sd;
193 /** cookie used for configuration of registers */
194 int cookie;
195};
196
197/** specify source of output subdevs */
198struct mxr_output_conf {
199 /** name of output (connector) */
200 char *output_name;
201 /** name of module that generates output subdev */
202 char *module_name;
203 /** cookie need for mixer HW */
204 int cookie;
205};
206
207struct clk;
208struct regulator;
209
210/** auxiliary resources used my mixer */
211struct mxr_resources {
212 /** interrupt index */
213 int irq;
214 /** pointer to Mixer registers */
215 void __iomem *mxr_regs;
216 /** pointer to Video Processor registers */
217 void __iomem *vp_regs;
218 /** other resources, should used under mxr_device.mutex */
219 struct clk *mixer;
220 struct clk *vp;
221 struct clk *sclk_mixer;
222 struct clk *sclk_hdmi;
223 struct clk *sclk_dac;
224};
225
226/* event flags used */
227enum mxr_devide_flags {
228 MXR_EVENT_VSYNC = 0,
229 MXR_EVENT_TOP = 1,
230};
231
232/** drivers instance */
233struct mxr_device {
234 /** master device */
235 struct device *dev;
236 /** state of each layer */
237 struct mxr_layer *layer[MXR_MAX_LAYERS];
238 /** state of each output */
239 struct mxr_output *output[MXR_MAX_OUTPUTS];
240 /** number of registered outputs */
241 int output_cnt;
242
243 /* video resources */
244
245 /** V4L2 device */
246 struct v4l2_device v4l2_dev;
247 /** context of allocator */
248 void *alloc_ctx;
249 /** event wait queue */
250 wait_queue_head_t event_queue;
251 /** state flags */
252 unsigned long event_flags;
253
254 /** spinlock for protection of registers */
255 spinlock_t reg_slock;
256
257 /** mutex for protection of fields below */
258 struct mutex mutex;
259 /** number of entities depndant on output configuration */
260 int n_output;
261 /** number of users that do streaming */
262 int n_streamer;
263 /** index of current output */
264 int current_output;
265 /** auxiliary resources used my mixer */
266 struct mxr_resources res;
267};
268
269/** transform device structure into mixer device */
270static inline struct mxr_device *to_mdev(struct device *dev)
271{
272 struct v4l2_device *vdev = dev_get_drvdata(dev);
273 return container_of(vdev, struct mxr_device, v4l2_dev);
274}
275
276/** get current output data, should be called under mdev's mutex */
277static inline struct mxr_output *to_output(struct mxr_device *mdev)
278{
279 return mdev->output[mdev->current_output];
280}
281
282/** get current output subdev, should be called under mdev's mutex */
283static inline struct v4l2_subdev *to_outsd(struct mxr_device *mdev)
284{
285 struct mxr_output *out = to_output(mdev);
286 return out ? out->sd : NULL;
287}
288
289/** forward declaration for mixer platform data */
290struct mxr_platform_data;
291
292/** acquiring common video resources */
293int __devinit mxr_acquire_video(struct mxr_device *mdev,
294 struct mxr_output_conf *output_cont, int output_count);
295
296/** releasing common video resources */
297void mxr_release_video(struct mxr_device *mdev);
298
299struct mxr_layer *mxr_graph_layer_create(struct mxr_device *mdev, int idx);
300struct mxr_layer *mxr_vp_layer_create(struct mxr_device *mdev, int idx);
301struct mxr_layer *mxr_base_layer_create(struct mxr_device *mdev,
302 int idx, char *name, struct mxr_layer_ops *ops);
303
304void mxr_base_layer_release(struct mxr_layer *layer);
305void mxr_layer_release(struct mxr_layer *layer);
306
307int mxr_base_layer_register(struct mxr_layer *layer);
308void mxr_base_layer_unregister(struct mxr_layer *layer);
309
310unsigned long mxr_get_plane_size(const struct mxr_block *blk,
311 unsigned int width, unsigned int height);
312
313/** adds new consumer for mixer's power */
314int __must_check mxr_power_get(struct mxr_device *mdev);
315/** removes consumer for mixer's power */
316void mxr_power_put(struct mxr_device *mdev);
317/** add new client for output configuration */
318void mxr_output_get(struct mxr_device *mdev);
319/** removes new client for output configuration */
320void mxr_output_put(struct mxr_device *mdev);
321/** add new client for streaming */
322void mxr_streamer_get(struct mxr_device *mdev);
323/** removes new client for streaming */
324void mxr_streamer_put(struct mxr_device *mdev);
325/** returns format of data delivared to current output */
326void mxr_get_mbus_fmt(struct mxr_device *mdev,
327 struct v4l2_mbus_framefmt *mbus_fmt);
328
329/* Debug */
330
331#define mxr_err(mdev, fmt, ...) dev_err(mdev->dev, fmt, ##__VA_ARGS__)
332#define mxr_warn(mdev, fmt, ...) dev_warn(mdev->dev, fmt, ##__VA_ARGS__)
333#define mxr_info(mdev, fmt, ...) dev_info(mdev->dev, fmt, ##__VA_ARGS__)
334
335#ifdef CONFIG_VIDEO_SAMSUNG_S5P_MIXER_DEBUG
336 #define mxr_dbg(mdev, fmt, ...) dev_dbg(mdev->dev, fmt, ##__VA_ARGS__)
337#else
338 #define mxr_dbg(mdev, fmt, ...) do { (void) mdev; } while (0)
339#endif
340
341/* accessing Mixer's and Video Processor's registers */
342
343void mxr_vsync_set_update(struct mxr_device *mdev, int en);
344void mxr_reg_reset(struct mxr_device *mdev);
345irqreturn_t mxr_irq_handler(int irq, void *dev_data);
346void mxr_reg_s_output(struct mxr_device *mdev, int cookie);
347void mxr_reg_streamon(struct mxr_device *mdev);
348void mxr_reg_streamoff(struct mxr_device *mdev);
349int mxr_reg_wait4vsync(struct mxr_device *mdev);
350void mxr_reg_set_mbus_fmt(struct mxr_device *mdev,
351 struct v4l2_mbus_framefmt *fmt);
352void mxr_reg_graph_layer_stream(struct mxr_device *mdev, int idx, int en);
353void mxr_reg_graph_buffer(struct mxr_device *mdev, int idx, dma_addr_t addr);
354void mxr_reg_graph_format(struct mxr_device *mdev, int idx,
355 const struct mxr_format *fmt, const struct mxr_geometry *geo);
356
357void mxr_reg_vp_layer_stream(struct mxr_device *mdev, int en);
358void mxr_reg_vp_buffer(struct mxr_device *mdev,
359 dma_addr_t luma_addr[2], dma_addr_t chroma_addr[2]);
360void mxr_reg_vp_format(struct mxr_device *mdev,
361 const struct mxr_format *fmt, const struct mxr_geometry *geo);
362void mxr_reg_dump(struct mxr_device *mdev);
363
364#endif /* SAMSUNG_MIXER_H */
365
diff --git a/drivers/media/video/s5p-tv/mixer_drv.c b/drivers/media/video/s5p-tv/mixer_drv.c
deleted file mode 100644
index edca06592883..000000000000
--- a/drivers/media/video/s5p-tv/mixer_drv.c
+++ /dev/null
@@ -1,487 +0,0 @@
1/*
2 * Samsung TV Mixer driver
3 *
4 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
5 *
6 * Tomasz Stanislawski, <t.stanislaws@samsung.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published
10 * by the Free Software Foundiation. either version 2 of the License,
11 * or (at your option) any later version
12 */
13
14#include "mixer.h"
15
16#include <linux/module.h>
17#include <linux/platform_device.h>
18#include <linux/io.h>
19#include <linux/interrupt.h>
20#include <linux/irq.h>
21#include <linux/fb.h>
22#include <linux/delay.h>
23#include <linux/pm_runtime.h>
24#include <linux/clk.h>
25
26MODULE_AUTHOR("Tomasz Stanislawski, <t.stanislaws@samsung.com>");
27MODULE_DESCRIPTION("Samsung MIXER");
28MODULE_LICENSE("GPL");
29
30/* --------- DRIVER PARAMETERS ---------- */
31
32static struct mxr_output_conf mxr_output_conf[] = {
33 {
34 .output_name = "S5P HDMI connector",
35 .module_name = "s5p-hdmi",
36 .cookie = 1,
37 },
38 {
39 .output_name = "S5P SDO connector",
40 .module_name = "s5p-sdo",
41 .cookie = 0,
42 },
43};
44
45void mxr_get_mbus_fmt(struct mxr_device *mdev,
46 struct v4l2_mbus_framefmt *mbus_fmt)
47{
48 struct v4l2_subdev *sd;
49 int ret;
50
51 mutex_lock(&mdev->mutex);
52 sd = to_outsd(mdev);
53 ret = v4l2_subdev_call(sd, video, g_mbus_fmt, mbus_fmt);
54 WARN(ret, "failed to get mbus_fmt for output %s\n", sd->name);
55 mutex_unlock(&mdev->mutex);
56}
57
58void mxr_streamer_get(struct mxr_device *mdev)
59{
60 mutex_lock(&mdev->mutex);
61 ++mdev->n_streamer;
62 mxr_dbg(mdev, "%s(%d)\n", __func__, mdev->n_streamer);
63 if (mdev->n_streamer == 1) {
64 struct v4l2_subdev *sd = to_outsd(mdev);
65 struct v4l2_mbus_framefmt mbus_fmt;
66 struct mxr_resources *res = &mdev->res;
67 int ret;
68
69 if (to_output(mdev)->cookie == 0)
70 clk_set_parent(res->sclk_mixer, res->sclk_dac);
71 else
72 clk_set_parent(res->sclk_mixer, res->sclk_hdmi);
73 mxr_reg_s_output(mdev, to_output(mdev)->cookie);
74
75 ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mbus_fmt);
76 WARN(ret, "failed to get mbus_fmt for output %s\n", sd->name);
77 ret = v4l2_subdev_call(sd, video, s_stream, 1);
78 WARN(ret, "starting stream failed for output %s\n", sd->name);
79
80 mxr_reg_set_mbus_fmt(mdev, &mbus_fmt);
81 mxr_reg_streamon(mdev);
82 ret = mxr_reg_wait4vsync(mdev);
83 WARN(ret, "failed to get vsync (%d) from output\n", ret);
84 }
85 mutex_unlock(&mdev->mutex);
86 mxr_reg_dump(mdev);
87 /* FIXME: what to do when streaming fails? */
88}
89
90void mxr_streamer_put(struct mxr_device *mdev)
91{
92 mutex_lock(&mdev->mutex);
93 --mdev->n_streamer;
94 mxr_dbg(mdev, "%s(%d)\n", __func__, mdev->n_streamer);
95 if (mdev->n_streamer == 0) {
96 int ret;
97 struct v4l2_subdev *sd = to_outsd(mdev);
98
99 mxr_reg_streamoff(mdev);
100 /* vsync applies Mixer setup */
101 ret = mxr_reg_wait4vsync(mdev);
102 WARN(ret, "failed to get vsync (%d) from output\n", ret);
103 ret = v4l2_subdev_call(sd, video, s_stream, 0);
104 WARN(ret, "stopping stream failed for output %s\n", sd->name);
105 }
106 WARN(mdev->n_streamer < 0, "negative number of streamers (%d)\n",
107 mdev->n_streamer);
108 mutex_unlock(&mdev->mutex);
109 mxr_reg_dump(mdev);
110}
111
112void mxr_output_get(struct mxr_device *mdev)
113{
114 mutex_lock(&mdev->mutex);
115 ++mdev->n_output;
116 mxr_dbg(mdev, "%s(%d)\n", __func__, mdev->n_output);
117 /* turn on auxiliary driver */
118 if (mdev->n_output == 1)
119 v4l2_subdev_call(to_outsd(mdev), core, s_power, 1);
120 mutex_unlock(&mdev->mutex);
121}
122
123void mxr_output_put(struct mxr_device *mdev)
124{
125 mutex_lock(&mdev->mutex);
126 --mdev->n_output;
127 mxr_dbg(mdev, "%s(%d)\n", __func__, mdev->n_output);
128 /* turn on auxiliary driver */
129 if (mdev->n_output == 0)
130 v4l2_subdev_call(to_outsd(mdev), core, s_power, 0);
131 WARN(mdev->n_output < 0, "negative number of output users (%d)\n",
132 mdev->n_output);
133 mutex_unlock(&mdev->mutex);
134}
135
136int mxr_power_get(struct mxr_device *mdev)
137{
138 int ret = pm_runtime_get_sync(mdev->dev);
139
140 /* returning 1 means that power is already enabled,
141 * so zero success be returned */
142 if (IS_ERR_VALUE(ret))
143 return ret;
144 return 0;
145}
146
147void mxr_power_put(struct mxr_device *mdev)
148{
149 pm_runtime_put_sync(mdev->dev);
150}
151
152/* --------- RESOURCE MANAGEMENT -------------*/
153
154static int __devinit mxr_acquire_plat_resources(struct mxr_device *mdev,
155 struct platform_device *pdev)
156{
157 struct resource *res;
158 int ret;
159
160 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mxr");
161 if (res == NULL) {
162 mxr_err(mdev, "get memory resource failed.\n");
163 ret = -ENXIO;
164 goto fail;
165 }
166
167 mdev->res.mxr_regs = ioremap(res->start, resource_size(res));
168 if (mdev->res.mxr_regs == NULL) {
169 mxr_err(mdev, "register mapping failed.\n");
170 ret = -ENXIO;
171 goto fail;
172 }
173
174 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vp");
175 if (res == NULL) {
176 mxr_err(mdev, "get memory resource failed.\n");
177 ret = -ENXIO;
178 goto fail_mxr_regs;
179 }
180
181 mdev->res.vp_regs = ioremap(res->start, resource_size(res));
182 if (mdev->res.vp_regs == NULL) {
183 mxr_err(mdev, "register mapping failed.\n");
184 ret = -ENXIO;
185 goto fail_mxr_regs;
186 }
187
188 res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "irq");
189 if (res == NULL) {
190 mxr_err(mdev, "get interrupt resource failed.\n");
191 ret = -ENXIO;
192 goto fail_vp_regs;
193 }
194
195 ret = request_irq(res->start, mxr_irq_handler, 0, "s5p-mixer", mdev);
196 if (ret) {
197 mxr_err(mdev, "request interrupt failed.\n");
198 goto fail_vp_regs;
199 }
200 mdev->res.irq = res->start;
201
202 return 0;
203
204fail_vp_regs:
205 iounmap(mdev->res.vp_regs);
206
207fail_mxr_regs:
208 iounmap(mdev->res.mxr_regs);
209
210fail:
211 return ret;
212}
213
214static void mxr_release_plat_resources(struct mxr_device *mdev)
215{
216 free_irq(mdev->res.irq, mdev);
217 iounmap(mdev->res.vp_regs);
218 iounmap(mdev->res.mxr_regs);
219}
220
221static void mxr_release_clocks(struct mxr_device *mdev)
222{
223 struct mxr_resources *res = &mdev->res;
224
225 if (!IS_ERR_OR_NULL(res->sclk_dac))
226 clk_put(res->sclk_dac);
227 if (!IS_ERR_OR_NULL(res->sclk_hdmi))
228 clk_put(res->sclk_hdmi);
229 if (!IS_ERR_OR_NULL(res->sclk_mixer))
230 clk_put(res->sclk_mixer);
231 if (!IS_ERR_OR_NULL(res->vp))
232 clk_put(res->vp);
233 if (!IS_ERR_OR_NULL(res->mixer))
234 clk_put(res->mixer);
235}
236
237static int mxr_acquire_clocks(struct mxr_device *mdev)
238{
239 struct mxr_resources *res = &mdev->res;
240 struct device *dev = mdev->dev;
241
242 res->mixer = clk_get(dev, "mixer");
243 if (IS_ERR_OR_NULL(res->mixer)) {
244 mxr_err(mdev, "failed to get clock 'mixer'\n");
245 goto fail;
246 }
247 res->vp = clk_get(dev, "vp");
248 if (IS_ERR_OR_NULL(res->vp)) {
249 mxr_err(mdev, "failed to get clock 'vp'\n");
250 goto fail;
251 }
252 res->sclk_mixer = clk_get(dev, "sclk_mixer");
253 if (IS_ERR_OR_NULL(res->sclk_mixer)) {
254 mxr_err(mdev, "failed to get clock 'sclk_mixer'\n");
255 goto fail;
256 }
257 res->sclk_hdmi = clk_get(dev, "sclk_hdmi");
258 if (IS_ERR_OR_NULL(res->sclk_hdmi)) {
259 mxr_err(mdev, "failed to get clock 'sclk_hdmi'\n");
260 goto fail;
261 }
262 res->sclk_dac = clk_get(dev, "sclk_dac");
263 if (IS_ERR_OR_NULL(res->sclk_dac)) {
264 mxr_err(mdev, "failed to get clock 'sclk_dac'\n");
265 goto fail;
266 }
267
268 return 0;
269fail:
270 mxr_release_clocks(mdev);
271 return -ENODEV;
272}
273
274static int __devinit mxr_acquire_resources(struct mxr_device *mdev,
275 struct platform_device *pdev)
276{
277 int ret;
278 ret = mxr_acquire_plat_resources(mdev, pdev);
279
280 if (ret)
281 goto fail;
282
283 ret = mxr_acquire_clocks(mdev);
284 if (ret)
285 goto fail_plat;
286
287 mxr_info(mdev, "resources acquired\n");
288 return 0;
289
290fail_plat:
291 mxr_release_plat_resources(mdev);
292fail:
293 mxr_err(mdev, "resources acquire failed\n");
294 return ret;
295}
296
297static void mxr_release_resources(struct mxr_device *mdev)
298{
299 mxr_release_clocks(mdev);
300 mxr_release_plat_resources(mdev);
301 memset(&mdev->res, 0, sizeof mdev->res);
302}
303
304static void mxr_release_layers(struct mxr_device *mdev)
305{
306 int i;
307
308 for (i = 0; i < ARRAY_SIZE(mdev->layer); ++i)
309 if (mdev->layer[i])
310 mxr_layer_release(mdev->layer[i]);
311}
312
313static int __devinit mxr_acquire_layers(struct mxr_device *mdev,
314 struct mxr_platform_data *pdata)
315{
316 mdev->layer[0] = mxr_graph_layer_create(mdev, 0);
317 mdev->layer[1] = mxr_graph_layer_create(mdev, 1);
318 mdev->layer[2] = mxr_vp_layer_create(mdev, 0);
319
320 if (!mdev->layer[0] || !mdev->layer[1] || !mdev->layer[2]) {
321 mxr_err(mdev, "failed to acquire layers\n");
322 goto fail;
323 }
324
325 return 0;
326
327fail:
328 mxr_release_layers(mdev);
329 return -ENODEV;
330}
331
332/* ---------- POWER MANAGEMENT ----------- */
333
334static int mxr_runtime_resume(struct device *dev)
335{
336 struct mxr_device *mdev = to_mdev(dev);
337 struct mxr_resources *res = &mdev->res;
338
339 mxr_dbg(mdev, "resume - start\n");
340 mutex_lock(&mdev->mutex);
341 /* turn clocks on */
342 clk_enable(res->mixer);
343 clk_enable(res->vp);
344 clk_enable(res->sclk_mixer);
345 /* apply default configuration */
346 mxr_reg_reset(mdev);
347 mxr_dbg(mdev, "resume - finished\n");
348
349 mutex_unlock(&mdev->mutex);
350 return 0;
351}
352
353static int mxr_runtime_suspend(struct device *dev)
354{
355 struct mxr_device *mdev = to_mdev(dev);
356 struct mxr_resources *res = &mdev->res;
357 mxr_dbg(mdev, "suspend - start\n");
358 mutex_lock(&mdev->mutex);
359 /* turn clocks off */
360 clk_disable(res->sclk_mixer);
361 clk_disable(res->vp);
362 clk_disable(res->mixer);
363 mutex_unlock(&mdev->mutex);
364 mxr_dbg(mdev, "suspend - finished\n");
365 return 0;
366}
367
368static const struct dev_pm_ops mxr_pm_ops = {
369 .runtime_suspend = mxr_runtime_suspend,
370 .runtime_resume = mxr_runtime_resume,
371};
372
373/* --------- DRIVER INITIALIZATION ---------- */
374
375static int __devinit mxr_probe(struct platform_device *pdev)
376{
377 struct device *dev = &pdev->dev;
378 struct mxr_platform_data *pdata = dev->platform_data;
379 struct mxr_device *mdev;
380 int ret;
381
382 /* mdev does not exist yet so no mxr_dbg is used */
383 dev_info(dev, "probe start\n");
384
385 mdev = kzalloc(sizeof *mdev, GFP_KERNEL);
386 if (!mdev) {
387 mxr_err(mdev, "not enough memory.\n");
388 ret = -ENOMEM;
389 goto fail;
390 }
391
392 /* setup pointer to master device */
393 mdev->dev = dev;
394
395 mutex_init(&mdev->mutex);
396 spin_lock_init(&mdev->reg_slock);
397 init_waitqueue_head(&mdev->event_queue);
398
399 /* acquire resources: regs, irqs, clocks, regulators */
400 ret = mxr_acquire_resources(mdev, pdev);
401 if (ret)
402 goto fail_mem;
403
404 /* configure resources for video output */
405 ret = mxr_acquire_video(mdev, mxr_output_conf,
406 ARRAY_SIZE(mxr_output_conf));
407 if (ret)
408 goto fail_resources;
409
410 /* configure layers */
411 ret = mxr_acquire_layers(mdev, pdata);
412 if (ret)
413 goto fail_video;
414
415 pm_runtime_enable(dev);
416
417 mxr_info(mdev, "probe successful\n");
418 return 0;
419
420fail_video:
421 mxr_release_video(mdev);
422
423fail_resources:
424 mxr_release_resources(mdev);
425
426fail_mem:
427 kfree(mdev);
428
429fail:
430 dev_info(dev, "probe failed\n");
431 return ret;
432}
433
434static int __devexit mxr_remove(struct platform_device *pdev)
435{
436 struct device *dev = &pdev->dev;
437 struct mxr_device *mdev = to_mdev(dev);
438
439 pm_runtime_disable(dev);
440
441 mxr_release_layers(mdev);
442 mxr_release_video(mdev);
443 mxr_release_resources(mdev);
444
445 kfree(mdev);
446
447 dev_info(dev, "remove successful\n");
448 return 0;
449}
450
451static struct platform_driver mxr_driver __refdata = {
452 .probe = mxr_probe,
453 .remove = __devexit_p(mxr_remove),
454 .driver = {
455 .name = MXR_DRIVER_NAME,
456 .owner = THIS_MODULE,
457 .pm = &mxr_pm_ops,
458 }
459};
460
461static int __init mxr_init(void)
462{
463 int i, ret;
464 static const char banner[] __initconst = KERN_INFO
465 "Samsung TV Mixer driver, "
466 "(c) 2010-2011 Samsung Electronics Co., Ltd.\n";
467 printk(banner);
468
469 /* Loading auxiliary modules */
470 for (i = 0; i < ARRAY_SIZE(mxr_output_conf); ++i)
471 request_module(mxr_output_conf[i].module_name);
472
473 ret = platform_driver_register(&mxr_driver);
474 if (ret != 0) {
475 printk(KERN_ERR "registration of MIXER driver failed\n");
476 return -ENXIO;
477 }
478
479 return 0;
480}
481module_init(mxr_init);
482
483static void __exit mxr_exit(void)
484{
485 platform_driver_unregister(&mxr_driver);
486}
487module_exit(mxr_exit);
diff --git a/drivers/media/video/s5p-tv/mixer_grp_layer.c b/drivers/media/video/s5p-tv/mixer_grp_layer.c
deleted file mode 100644
index b93a21f5aa13..000000000000
--- a/drivers/media/video/s5p-tv/mixer_grp_layer.c
+++ /dev/null
@@ -1,270 +0,0 @@
1/*
2 * Samsung TV Mixer driver
3 *
4 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
5 *
6 * Tomasz Stanislawski, <t.stanislaws@samsung.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published
10 * by the Free Software Foundiation. either version 2 of the License,
11 * or (at your option) any later version
12 */
13
14#include "mixer.h"
15
16#include <media/videobuf2-dma-contig.h>
17
18/* FORMAT DEFINITIONS */
19
20static const struct mxr_format mxr_fb_fmt_rgb565 = {
21 .name = "RGB565",
22 .fourcc = V4L2_PIX_FMT_RGB565,
23 .colorspace = V4L2_COLORSPACE_SRGB,
24 .num_planes = 1,
25 .plane = {
26 { .width = 1, .height = 1, .size = 2 },
27 },
28 .num_subframes = 1,
29 .cookie = 4,
30};
31
32static const struct mxr_format mxr_fb_fmt_argb1555 = {
33 .name = "ARGB1555",
34 .num_planes = 1,
35 .fourcc = V4L2_PIX_FMT_RGB555,
36 .colorspace = V4L2_COLORSPACE_SRGB,
37 .plane = {
38 { .width = 1, .height = 1, .size = 2 },
39 },
40 .num_subframes = 1,
41 .cookie = 5,
42};
43
44static const struct mxr_format mxr_fb_fmt_argb4444 = {
45 .name = "ARGB4444",
46 .num_planes = 1,
47 .fourcc = V4L2_PIX_FMT_RGB444,
48 .colorspace = V4L2_COLORSPACE_SRGB,
49 .plane = {
50 { .width = 1, .height = 1, .size = 2 },
51 },
52 .num_subframes = 1,
53 .cookie = 6,
54};
55
56static const struct mxr_format mxr_fb_fmt_argb8888 = {
57 .name = "ARGB8888",
58 .fourcc = V4L2_PIX_FMT_BGR32,
59 .colorspace = V4L2_COLORSPACE_SRGB,
60 .num_planes = 1,
61 .plane = {
62 { .width = 1, .height = 1, .size = 4 },
63 },
64 .num_subframes = 1,
65 .cookie = 7,
66};
67
68static const struct mxr_format *mxr_graph_format[] = {
69 &mxr_fb_fmt_rgb565,
70 &mxr_fb_fmt_argb1555,
71 &mxr_fb_fmt_argb4444,
72 &mxr_fb_fmt_argb8888,
73};
74
75/* AUXILIARY CALLBACKS */
76
77static void mxr_graph_layer_release(struct mxr_layer *layer)
78{
79 mxr_base_layer_unregister(layer);
80 mxr_base_layer_release(layer);
81}
82
83static void mxr_graph_buffer_set(struct mxr_layer *layer,
84 struct mxr_buffer *buf)
85{
86 dma_addr_t addr = 0;
87
88 if (buf)
89 addr = vb2_dma_contig_plane_dma_addr(&buf->vb, 0);
90 mxr_reg_graph_buffer(layer->mdev, layer->idx, addr);
91}
92
93static void mxr_graph_stream_set(struct mxr_layer *layer, int en)
94{
95 mxr_reg_graph_layer_stream(layer->mdev, layer->idx, en);
96}
97
98static void mxr_graph_format_set(struct mxr_layer *layer)
99{
100 mxr_reg_graph_format(layer->mdev, layer->idx,
101 layer->fmt, &layer->geo);
102}
103
104static inline unsigned int closest(unsigned int x, unsigned int a,
105 unsigned int b, unsigned long flags)
106{
107 unsigned int mid = (a + b) / 2;
108
109 /* choosing closest value with constraints according to table:
110 * -------------+-----+-----+-----+-------+
111 * flags | 0 | LE | GE | LE|GE |
112 * -------------+-----+-----+-----+-------+
113 * x <= a | a | a | a | a |
114 * a < x <= mid | a | a | b | a |
115 * mid < x < b | b | a | b | b |
116 * b <= x | b | b | b | b |
117 * -------------+-----+-----+-----+-------+
118 */
119
120 /* remove all non-constraint flags */
121 flags &= V4L2_SEL_FLAG_LE | V4L2_SEL_FLAG_GE;
122
123 if (x <= a)
124 return a;
125 if (x >= b)
126 return b;
127 if (flags == V4L2_SEL_FLAG_LE)
128 return a;
129 if (flags == V4L2_SEL_FLAG_GE)
130 return b;
131 if (x <= mid)
132 return a;
133 return b;
134}
135
136static inline unsigned int do_center(unsigned int center,
137 unsigned int size, unsigned int upper, unsigned int flags)
138{
139 unsigned int lower;
140
141 if (flags & MXR_NO_OFFSET)
142 return 0;
143
144 lower = center - min(center, size / 2);
145 return min(lower, upper - size);
146}
147
148static void mxr_graph_fix_geometry(struct mxr_layer *layer,
149 enum mxr_geometry_stage stage, unsigned long flags)
150{
151 struct mxr_geometry *geo = &layer->geo;
152 struct mxr_crop *src = &geo->src;
153 struct mxr_crop *dst = &geo->dst;
154 unsigned int x_center, y_center;
155
156 switch (stage) {
157
158 case MXR_GEOMETRY_SINK: /* nothing to be fixed here */
159 flags = 0;
160 /* fall through */
161
162 case MXR_GEOMETRY_COMPOSE:
163 /* remember center of the area */
164 x_center = dst->x_offset + dst->width / 2;
165 y_center = dst->y_offset + dst->height / 2;
166 /* round up/down to 2 multiple depending on flags */
167 if (flags & V4L2_SEL_FLAG_LE) {
168 dst->width = round_down(dst->width, 2);
169 dst->height = round_down(dst->height, 2);
170 } else {
171 dst->width = round_up(dst->width, 2);
172 dst->height = round_up(dst->height, 2);
173 }
174 /* assure that compose rect is inside display area */
175 dst->width = min(dst->width, dst->full_width);
176 dst->height = min(dst->height, dst->full_height);
177
178 /* ensure that compose is reachable using 2x scaling */
179 dst->width = min(dst->width, 2 * src->full_width);
180 dst->height = min(dst->height, 2 * src->full_height);
181
182 /* setup offsets */
183 dst->x_offset = do_center(x_center, dst->width,
184 dst->full_width, flags);
185 dst->y_offset = do_center(y_center, dst->height,
186 dst->full_height, flags);
187 flags = 0;
188 /* fall through */
189
190 case MXR_GEOMETRY_CROP:
191 /* remember center of the area */
192 x_center = src->x_offset + src->width / 2;
193 y_center = src->y_offset + src->height / 2;
194 /* ensure that cropping area lies inside the buffer */
195 if (src->full_width < dst->width)
196 src->width = dst->width / 2;
197 else
198 src->width = closest(src->width, dst->width / 2,
199 dst->width, flags);
200
201 if (src->width == dst->width)
202 geo->x_ratio = 0;
203 else
204 geo->x_ratio = 1;
205
206 if (src->full_height < dst->height)
207 src->height = dst->height / 2;
208 else
209 src->height = closest(src->height, dst->height / 2,
210 dst->height, flags);
211
212 if (src->height == dst->height)
213 geo->y_ratio = 0;
214 else
215 geo->y_ratio = 1;
216
217 /* setup offsets */
218 src->x_offset = do_center(x_center, src->width,
219 src->full_width, flags);
220 src->y_offset = do_center(y_center, src->height,
221 src->full_height, flags);
222 flags = 0;
223 /* fall through */
224 case MXR_GEOMETRY_SOURCE:
225 src->full_width = clamp_val(src->full_width,
226 src->width + src->x_offset, 32767);
227 src->full_height = clamp_val(src->full_height,
228 src->height + src->y_offset, 2047);
229 };
230}
231
232/* PUBLIC API */
233
234struct mxr_layer *mxr_graph_layer_create(struct mxr_device *mdev, int idx)
235{
236 struct mxr_layer *layer;
237 int ret;
238 struct mxr_layer_ops ops = {
239 .release = mxr_graph_layer_release,
240 .buffer_set = mxr_graph_buffer_set,
241 .stream_set = mxr_graph_stream_set,
242 .format_set = mxr_graph_format_set,
243 .fix_geometry = mxr_graph_fix_geometry,
244 };
245 char name[32];
246
247 sprintf(name, "graph%d", idx);
248
249 layer = mxr_base_layer_create(mdev, idx, name, &ops);
250 if (layer == NULL) {
251 mxr_err(mdev, "failed to initialize layer(%d) base\n", idx);
252 goto fail;
253 }
254
255 layer->fmt_array = mxr_graph_format;
256 layer->fmt_array_size = ARRAY_SIZE(mxr_graph_format);
257
258 ret = mxr_base_layer_register(layer);
259 if (ret)
260 goto fail_layer;
261
262 return layer;
263
264fail_layer:
265 mxr_base_layer_release(layer);
266
267fail:
268 return NULL;
269}
270
diff --git a/drivers/media/video/s5p-tv/mixer_reg.c b/drivers/media/video/s5p-tv/mixer_reg.c
deleted file mode 100644
index 3b1670a045f4..000000000000
--- a/drivers/media/video/s5p-tv/mixer_reg.c
+++ /dev/null
@@ -1,553 +0,0 @@
1/*
2 * Samsung TV Mixer driver
3 *
4 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
5 *
6 * Tomasz Stanislawski, <t.stanislaws@samsung.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published
10 * by the Free Software Foundiation. either version 2 of the License,
11 * or (at your option) any later version
12 */
13
14#include "mixer.h"
15#include "regs-mixer.h"
16#include "regs-vp.h"
17
18#include <linux/delay.h>
19
20/* Register access subroutines */
21
22static inline u32 vp_read(struct mxr_device *mdev, u32 reg_id)
23{
24 return readl(mdev->res.vp_regs + reg_id);
25}
26
27static inline void vp_write(struct mxr_device *mdev, u32 reg_id, u32 val)
28{
29 writel(val, mdev->res.vp_regs + reg_id);
30}
31
32static inline void vp_write_mask(struct mxr_device *mdev, u32 reg_id,
33 u32 val, u32 mask)
34{
35 u32 old = vp_read(mdev, reg_id);
36
37 val = (val & mask) | (old & ~mask);
38 writel(val, mdev->res.vp_regs + reg_id);
39}
40
41static inline u32 mxr_read(struct mxr_device *mdev, u32 reg_id)
42{
43 return readl(mdev->res.mxr_regs + reg_id);
44}
45
46static inline void mxr_write(struct mxr_device *mdev, u32 reg_id, u32 val)
47{
48 writel(val, mdev->res.mxr_regs + reg_id);
49}
50
51static inline void mxr_write_mask(struct mxr_device *mdev, u32 reg_id,
52 u32 val, u32 mask)
53{
54 u32 old = mxr_read(mdev, reg_id);
55
56 val = (val & mask) | (old & ~mask);
57 writel(val, mdev->res.mxr_regs + reg_id);
58}
59
60void mxr_vsync_set_update(struct mxr_device *mdev, int en)
61{
62 /* block update on vsync */
63 mxr_write_mask(mdev, MXR_STATUS, en ? MXR_STATUS_SYNC_ENABLE : 0,
64 MXR_STATUS_SYNC_ENABLE);
65 vp_write(mdev, VP_SHADOW_UPDATE, en ? VP_SHADOW_UPDATE_ENABLE : 0);
66}
67
68static void __mxr_reg_vp_reset(struct mxr_device *mdev)
69{
70 int tries = 100;
71
72 vp_write(mdev, VP_SRESET, VP_SRESET_PROCESSING);
73 for (tries = 100; tries; --tries) {
74 /* waiting until VP_SRESET_PROCESSING is 0 */
75 if (~vp_read(mdev, VP_SRESET) & VP_SRESET_PROCESSING)
76 break;
77 mdelay(10);
78 }
79 WARN(tries == 0, "failed to reset Video Processor\n");
80}
81
82static void mxr_reg_vp_default_filter(struct mxr_device *mdev);
83
84void mxr_reg_reset(struct mxr_device *mdev)
85{
86 unsigned long flags;
87 u32 val; /* value stored to register */
88
89 spin_lock_irqsave(&mdev->reg_slock, flags);
90 mxr_vsync_set_update(mdev, MXR_DISABLE);
91
92 /* set output in RGB888 mode */
93 mxr_write(mdev, MXR_CFG, MXR_CFG_OUT_RGB888);
94
95 /* 16 beat burst in DMA */
96 mxr_write_mask(mdev, MXR_STATUS, MXR_STATUS_16_BURST,
97 MXR_STATUS_BURST_MASK);
98
99 /* setting default layer priority: layer1 > video > layer0
100 * because typical usage scenario would be
101 * layer0 - framebuffer
102 * video - video overlay
103 * layer1 - OSD
104 */
105 val = MXR_LAYER_CFG_GRP0_VAL(1);
106 val |= MXR_LAYER_CFG_VP_VAL(2);
107 val |= MXR_LAYER_CFG_GRP1_VAL(3);
108 mxr_write(mdev, MXR_LAYER_CFG, val);
109
110 /* use dark gray background color */
111 mxr_write(mdev, MXR_BG_COLOR0, 0x808080);
112 mxr_write(mdev, MXR_BG_COLOR1, 0x808080);
113 mxr_write(mdev, MXR_BG_COLOR2, 0x808080);
114
115 /* setting graphical layers */
116
117 val = MXR_GRP_CFG_COLOR_KEY_DISABLE; /* no blank key */
118 val |= MXR_GRP_CFG_BLEND_PRE_MUL; /* premul mode */
119 val |= MXR_GRP_CFG_ALPHA_VAL(0xff); /* non-transparent alpha */
120
121 /* the same configuration for both layers */
122 mxr_write(mdev, MXR_GRAPHIC_CFG(0), val);
123 mxr_write(mdev, MXR_GRAPHIC_CFG(1), val);
124
125 /* configuration of Video Processor Registers */
126 __mxr_reg_vp_reset(mdev);
127 mxr_reg_vp_default_filter(mdev);
128
129 /* enable all interrupts */
130 mxr_write_mask(mdev, MXR_INT_EN, ~0, MXR_INT_EN_ALL);
131
132 mxr_vsync_set_update(mdev, MXR_ENABLE);
133 spin_unlock_irqrestore(&mdev->reg_slock, flags);
134}
135
136void mxr_reg_graph_format(struct mxr_device *mdev, int idx,
137 const struct mxr_format *fmt, const struct mxr_geometry *geo)
138{
139 u32 val;
140 unsigned long flags;
141
142 spin_lock_irqsave(&mdev->reg_slock, flags);
143 mxr_vsync_set_update(mdev, MXR_DISABLE);
144
145 /* setup format */
146 mxr_write_mask(mdev, MXR_GRAPHIC_CFG(idx),
147 MXR_GRP_CFG_FORMAT_VAL(fmt->cookie), MXR_GRP_CFG_FORMAT_MASK);
148
149 /* setup geometry */
150 mxr_write(mdev, MXR_GRAPHIC_SPAN(idx), geo->src.full_width);
151 val = MXR_GRP_WH_WIDTH(geo->src.width);
152 val |= MXR_GRP_WH_HEIGHT(geo->src.height);
153 val |= MXR_GRP_WH_H_SCALE(geo->x_ratio);
154 val |= MXR_GRP_WH_V_SCALE(geo->y_ratio);
155 mxr_write(mdev, MXR_GRAPHIC_WH(idx), val);
156
157 /* setup offsets in source image */
158 val = MXR_GRP_SXY_SX(geo->src.x_offset);
159 val |= MXR_GRP_SXY_SY(geo->src.y_offset);
160 mxr_write(mdev, MXR_GRAPHIC_SXY(idx), val);
161
162 /* setup offsets in display image */
163 val = MXR_GRP_DXY_DX(geo->dst.x_offset);
164 val |= MXR_GRP_DXY_DY(geo->dst.y_offset);
165 mxr_write(mdev, MXR_GRAPHIC_DXY(idx), val);
166
167 mxr_vsync_set_update(mdev, MXR_ENABLE);
168 spin_unlock_irqrestore(&mdev->reg_slock, flags);
169}
170
171void mxr_reg_vp_format(struct mxr_device *mdev,
172 const struct mxr_format *fmt, const struct mxr_geometry *geo)
173{
174 unsigned long flags;
175
176 spin_lock_irqsave(&mdev->reg_slock, flags);
177 mxr_vsync_set_update(mdev, MXR_DISABLE);
178
179 vp_write_mask(mdev, VP_MODE, fmt->cookie, VP_MODE_FMT_MASK);
180
181 /* setting size of input image */
182 vp_write(mdev, VP_IMG_SIZE_Y, VP_IMG_HSIZE(geo->src.full_width) |
183 VP_IMG_VSIZE(geo->src.full_height));
184 /* chroma height has to reduced by 2 to avoid chroma distorions */
185 vp_write(mdev, VP_IMG_SIZE_C, VP_IMG_HSIZE(geo->src.full_width) |
186 VP_IMG_VSIZE(geo->src.full_height / 2));
187
188 vp_write(mdev, VP_SRC_WIDTH, geo->src.width);
189 vp_write(mdev, VP_SRC_HEIGHT, geo->src.height);
190 vp_write(mdev, VP_SRC_H_POSITION,
191 VP_SRC_H_POSITION_VAL(geo->src.x_offset));
192 vp_write(mdev, VP_SRC_V_POSITION, geo->src.y_offset);
193
194 vp_write(mdev, VP_DST_WIDTH, geo->dst.width);
195 vp_write(mdev, VP_DST_H_POSITION, geo->dst.x_offset);
196 if (geo->dst.field == V4L2_FIELD_INTERLACED) {
197 vp_write(mdev, VP_DST_HEIGHT, geo->dst.height / 2);
198 vp_write(mdev, VP_DST_V_POSITION, geo->dst.y_offset / 2);
199 } else {
200 vp_write(mdev, VP_DST_HEIGHT, geo->dst.height);
201 vp_write(mdev, VP_DST_V_POSITION, geo->dst.y_offset);
202 }
203
204 vp_write(mdev, VP_H_RATIO, geo->x_ratio);
205 vp_write(mdev, VP_V_RATIO, geo->y_ratio);
206
207 vp_write(mdev, VP_ENDIAN_MODE, VP_ENDIAN_MODE_LITTLE);
208
209 mxr_vsync_set_update(mdev, MXR_ENABLE);
210 spin_unlock_irqrestore(&mdev->reg_slock, flags);
211
212}
213
214void mxr_reg_graph_buffer(struct mxr_device *mdev, int idx, dma_addr_t addr)
215{
216 u32 val = addr ? ~0 : 0;
217 unsigned long flags;
218
219 spin_lock_irqsave(&mdev->reg_slock, flags);
220 mxr_vsync_set_update(mdev, MXR_DISABLE);
221
222 if (idx == 0)
223 mxr_write_mask(mdev, MXR_CFG, val, MXR_CFG_GRP0_ENABLE);
224 else
225 mxr_write_mask(mdev, MXR_CFG, val, MXR_CFG_GRP1_ENABLE);
226 mxr_write(mdev, MXR_GRAPHIC_BASE(idx), addr);
227
228 mxr_vsync_set_update(mdev, MXR_ENABLE);
229 spin_unlock_irqrestore(&mdev->reg_slock, flags);
230}
231
232void mxr_reg_vp_buffer(struct mxr_device *mdev,
233 dma_addr_t luma_addr[2], dma_addr_t chroma_addr[2])
234{
235 u32 val = luma_addr[0] ? ~0 : 0;
236 unsigned long flags;
237
238 spin_lock_irqsave(&mdev->reg_slock, flags);
239 mxr_vsync_set_update(mdev, MXR_DISABLE);
240
241 mxr_write_mask(mdev, MXR_CFG, val, MXR_CFG_VP_ENABLE);
242 vp_write_mask(mdev, VP_ENABLE, val, VP_ENABLE_ON);
243 /* TODO: fix tiled mode */
244 vp_write(mdev, VP_TOP_Y_PTR, luma_addr[0]);
245 vp_write(mdev, VP_TOP_C_PTR, chroma_addr[0]);
246 vp_write(mdev, VP_BOT_Y_PTR, luma_addr[1]);
247 vp_write(mdev, VP_BOT_C_PTR, chroma_addr[1]);
248
249 mxr_vsync_set_update(mdev, MXR_ENABLE);
250 spin_unlock_irqrestore(&mdev->reg_slock, flags);
251}
252
253static void mxr_irq_layer_handle(struct mxr_layer *layer)
254{
255 struct list_head *head = &layer->enq_list;
256 struct mxr_buffer *done;
257
258 /* skip non-existing layer */
259 if (layer == NULL)
260 return;
261
262 spin_lock(&layer->enq_slock);
263 if (layer->state == MXR_LAYER_IDLE)
264 goto done;
265
266 done = layer->shadow_buf;
267 layer->shadow_buf = layer->update_buf;
268
269 if (list_empty(head)) {
270 if (layer->state != MXR_LAYER_STREAMING)
271 layer->update_buf = NULL;
272 } else {
273 struct mxr_buffer *next;
274 next = list_first_entry(head, struct mxr_buffer, list);
275 list_del(&next->list);
276 layer->update_buf = next;
277 }
278
279 layer->ops.buffer_set(layer, layer->update_buf);
280
281 if (done && done != layer->shadow_buf)
282 vb2_buffer_done(&done->vb, VB2_BUF_STATE_DONE);
283
284done:
285 spin_unlock(&layer->enq_slock);
286}
287
288irqreturn_t mxr_irq_handler(int irq, void *dev_data)
289{
290 struct mxr_device *mdev = dev_data;
291 u32 i, val;
292
293 spin_lock(&mdev->reg_slock);
294 val = mxr_read(mdev, MXR_INT_STATUS);
295
296 /* wake up process waiting for VSYNC */
297 if (val & MXR_INT_STATUS_VSYNC) {
298 set_bit(MXR_EVENT_VSYNC, &mdev->event_flags);
299 /* toggle TOP field event if working in interlaced mode */
300 if (~mxr_read(mdev, MXR_CFG) & MXR_CFG_SCAN_PROGRASSIVE)
301 change_bit(MXR_EVENT_TOP, &mdev->event_flags);
302 wake_up(&mdev->event_queue);
303 /* vsync interrupt use different bit for read and clear */
304 val &= ~MXR_INT_STATUS_VSYNC;
305 val |= MXR_INT_CLEAR_VSYNC;
306 }
307
308 /* clear interrupts */
309 mxr_write(mdev, MXR_INT_STATUS, val);
310
311 spin_unlock(&mdev->reg_slock);
312 /* leave on non-vsync event */
313 if (~val & MXR_INT_CLEAR_VSYNC)
314 return IRQ_HANDLED;
315 /* skip layer update on bottom field */
316 if (!test_bit(MXR_EVENT_TOP, &mdev->event_flags))
317 return IRQ_HANDLED;
318 for (i = 0; i < MXR_MAX_LAYERS; ++i)
319 mxr_irq_layer_handle(mdev->layer[i]);
320 return IRQ_HANDLED;
321}
322
323void mxr_reg_s_output(struct mxr_device *mdev, int cookie)
324{
325 u32 val;
326
327 val = cookie == 0 ? MXR_CFG_DST_SDO : MXR_CFG_DST_HDMI;
328 mxr_write_mask(mdev, MXR_CFG, val, MXR_CFG_DST_MASK);
329}
330
331void mxr_reg_streamon(struct mxr_device *mdev)
332{
333 unsigned long flags;
334
335 spin_lock_irqsave(&mdev->reg_slock, flags);
336 /* single write -> no need to block vsync update */
337
338 /* start MIXER */
339 mxr_write_mask(mdev, MXR_STATUS, ~0, MXR_STATUS_REG_RUN);
340 set_bit(MXR_EVENT_TOP, &mdev->event_flags);
341
342 spin_unlock_irqrestore(&mdev->reg_slock, flags);
343}
344
345void mxr_reg_streamoff(struct mxr_device *mdev)
346{
347 unsigned long flags;
348
349 spin_lock_irqsave(&mdev->reg_slock, flags);
350 /* single write -> no need to block vsync update */
351
352 /* stop MIXER */
353 mxr_write_mask(mdev, MXR_STATUS, 0, MXR_STATUS_REG_RUN);
354
355 spin_unlock_irqrestore(&mdev->reg_slock, flags);
356}
357
358int mxr_reg_wait4vsync(struct mxr_device *mdev)
359{
360 int ret;
361
362 clear_bit(MXR_EVENT_VSYNC, &mdev->event_flags);
363 /* TODO: consider adding interruptible */
364 ret = wait_event_timeout(mdev->event_queue,
365 test_bit(MXR_EVENT_VSYNC, &mdev->event_flags),
366 msecs_to_jiffies(1000));
367 if (ret > 0)
368 return 0;
369 if (ret < 0)
370 return ret;
371 mxr_warn(mdev, "no vsync detected - timeout\n");
372 return -ETIME;
373}
374
375void mxr_reg_set_mbus_fmt(struct mxr_device *mdev,
376 struct v4l2_mbus_framefmt *fmt)
377{
378 u32 val = 0;
379 unsigned long flags;
380
381 spin_lock_irqsave(&mdev->reg_slock, flags);
382 mxr_vsync_set_update(mdev, MXR_DISABLE);
383
384 /* selecting colorspace accepted by output */
385 if (fmt->colorspace == V4L2_COLORSPACE_JPEG)
386 val |= MXR_CFG_OUT_YUV444;
387 else
388 val |= MXR_CFG_OUT_RGB888;
389
390 /* choosing between interlace and progressive mode */
391 if (fmt->field == V4L2_FIELD_INTERLACED)
392 val |= MXR_CFG_SCAN_INTERLACE;
393 else
394 val |= MXR_CFG_SCAN_PROGRASSIVE;
395
396 /* choosing between porper HD and SD mode */
397 if (fmt->height == 480)
398 val |= MXR_CFG_SCAN_NTSC | MXR_CFG_SCAN_SD;
399 else if (fmt->height == 576)
400 val |= MXR_CFG_SCAN_PAL | MXR_CFG_SCAN_SD;
401 else if (fmt->height == 720)
402 val |= MXR_CFG_SCAN_HD_720 | MXR_CFG_SCAN_HD;
403 else if (fmt->height == 1080)
404 val |= MXR_CFG_SCAN_HD_1080 | MXR_CFG_SCAN_HD;
405 else
406 WARN(1, "unrecognized mbus height %u!\n", fmt->height);
407
408 mxr_write_mask(mdev, MXR_CFG, val, MXR_CFG_SCAN_MASK |
409 MXR_CFG_OUT_MASK);
410
411 val = (fmt->field == V4L2_FIELD_INTERLACED) ? ~0 : 0;
412 vp_write_mask(mdev, VP_MODE, val,
413 VP_MODE_LINE_SKIP | VP_MODE_FIELD_ID_AUTO_TOGGLING);
414
415 mxr_vsync_set_update(mdev, MXR_ENABLE);
416 spin_unlock_irqrestore(&mdev->reg_slock, flags);
417}
418
419void mxr_reg_graph_layer_stream(struct mxr_device *mdev, int idx, int en)
420{
421 /* no extra actions need to be done */
422}
423
424void mxr_reg_vp_layer_stream(struct mxr_device *mdev, int en)
425{
426 /* no extra actions need to be done */
427}
428
429static const u8 filter_y_horiz_tap8[] = {
430 0, -1, -1, -1, -1, -1, -1, -1,
431 -1, -1, -1, -1, -1, 0, 0, 0,
432 0, 2, 4, 5, 6, 6, 6, 6,
433 6, 5, 5, 4, 3, 2, 1, 1,
434 0, -6, -12, -16, -18, -20, -21, -20,
435 -20, -18, -16, -13, -10, -8, -5, -2,
436 127, 126, 125, 121, 114, 107, 99, 89,
437 79, 68, 57, 46, 35, 25, 16, 8,
438};
439
440static const u8 filter_y_vert_tap4[] = {
441 0, -3, -6, -8, -8, -8, -8, -7,
442 -6, -5, -4, -3, -2, -1, -1, 0,
443 127, 126, 124, 118, 111, 102, 92, 81,
444 70, 59, 48, 37, 27, 19, 11, 5,
445 0, 5, 11, 19, 27, 37, 48, 59,
446 70, 81, 92, 102, 111, 118, 124, 126,
447 0, 0, -1, -1, -2, -3, -4, -5,
448 -6, -7, -8, -8, -8, -8, -6, -3,
449};
450
451static const u8 filter_cr_horiz_tap4[] = {
452 0, -3, -6, -8, -8, -8, -8, -7,
453 -6, -5, -4, -3, -2, -1, -1, 0,
454 127, 126, 124, 118, 111, 102, 92, 81,
455 70, 59, 48, 37, 27, 19, 11, 5,
456};
457
458static inline void mxr_reg_vp_filter_set(struct mxr_device *mdev,
459 int reg_id, const u8 *data, unsigned int size)
460{
461 /* assure 4-byte align */
462 BUG_ON(size & 3);
463 for (; size; size -= 4, reg_id += 4, data += 4) {
464 u32 val = (data[0] << 24) | (data[1] << 16) |
465 (data[2] << 8) | data[3];
466 vp_write(mdev, reg_id, val);
467 }
468}
469
470static void mxr_reg_vp_default_filter(struct mxr_device *mdev)
471{
472 mxr_reg_vp_filter_set(mdev, VP_POLY8_Y0_LL,
473 filter_y_horiz_tap8, sizeof filter_y_horiz_tap8);
474 mxr_reg_vp_filter_set(mdev, VP_POLY4_Y0_LL,
475 filter_y_vert_tap4, sizeof filter_y_vert_tap4);
476 mxr_reg_vp_filter_set(mdev, VP_POLY4_C0_LL,
477 filter_cr_horiz_tap4, sizeof filter_cr_horiz_tap4);
478}
479
480static void mxr_reg_mxr_dump(struct mxr_device *mdev)
481{
482#define DUMPREG(reg_id) \
483do { \
484 mxr_dbg(mdev, #reg_id " = %08x\n", \
485 (u32)readl(mdev->res.mxr_regs + reg_id)); \
486} while (0)
487
488 DUMPREG(MXR_STATUS);
489 DUMPREG(MXR_CFG);
490 DUMPREG(MXR_INT_EN);
491 DUMPREG(MXR_INT_STATUS);
492
493 DUMPREG(MXR_LAYER_CFG);
494 DUMPREG(MXR_VIDEO_CFG);
495
496 DUMPREG(MXR_GRAPHIC0_CFG);
497 DUMPREG(MXR_GRAPHIC0_BASE);
498 DUMPREG(MXR_GRAPHIC0_SPAN);
499 DUMPREG(MXR_GRAPHIC0_WH);
500 DUMPREG(MXR_GRAPHIC0_SXY);
501 DUMPREG(MXR_GRAPHIC0_DXY);
502
503 DUMPREG(MXR_GRAPHIC1_CFG);
504 DUMPREG(MXR_GRAPHIC1_BASE);
505 DUMPREG(MXR_GRAPHIC1_SPAN);
506 DUMPREG(MXR_GRAPHIC1_WH);
507 DUMPREG(MXR_GRAPHIC1_SXY);
508 DUMPREG(MXR_GRAPHIC1_DXY);
509#undef DUMPREG
510}
511
512static void mxr_reg_vp_dump(struct mxr_device *mdev)
513{
514#define DUMPREG(reg_id) \
515do { \
516 mxr_dbg(mdev, #reg_id " = %08x\n", \
517 (u32) readl(mdev->res.vp_regs + reg_id)); \
518} while (0)
519
520
521 DUMPREG(VP_ENABLE);
522 DUMPREG(VP_SRESET);
523 DUMPREG(VP_SHADOW_UPDATE);
524 DUMPREG(VP_FIELD_ID);
525 DUMPREG(VP_MODE);
526 DUMPREG(VP_IMG_SIZE_Y);
527 DUMPREG(VP_IMG_SIZE_C);
528 DUMPREG(VP_PER_RATE_CTRL);
529 DUMPREG(VP_TOP_Y_PTR);
530 DUMPREG(VP_BOT_Y_PTR);
531 DUMPREG(VP_TOP_C_PTR);
532 DUMPREG(VP_BOT_C_PTR);
533 DUMPREG(VP_ENDIAN_MODE);
534 DUMPREG(VP_SRC_H_POSITION);
535 DUMPREG(VP_SRC_V_POSITION);
536 DUMPREG(VP_SRC_WIDTH);
537 DUMPREG(VP_SRC_HEIGHT);
538 DUMPREG(VP_DST_H_POSITION);
539 DUMPREG(VP_DST_V_POSITION);
540 DUMPREG(VP_DST_WIDTH);
541 DUMPREG(VP_DST_HEIGHT);
542 DUMPREG(VP_H_RATIO);
543 DUMPREG(VP_V_RATIO);
544
545#undef DUMPREG
546}
547
548void mxr_reg_dump(struct mxr_device *mdev)
549{
550 mxr_reg_mxr_dump(mdev);
551 mxr_reg_vp_dump(mdev);
552}
553
diff --git a/drivers/media/video/s5p-tv/mixer_video.c b/drivers/media/video/s5p-tv/mixer_video.c
deleted file mode 100644
index e0e02cce1bcb..000000000000
--- a/drivers/media/video/s5p-tv/mixer_video.c
+++ /dev/null
@@ -1,1125 +0,0 @@
1/*
2 * Samsung TV Mixer driver
3 *
4 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
5 *
6 * Tomasz Stanislawski, <t.stanislaws@samsung.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published
10 * by the Free Software Foundation. either version 2 of the License,
11 * or (at your option) any later version
12 */
13
14#include "mixer.h"
15
16#include <media/v4l2-ioctl.h>
17#include <linux/videodev2.h>
18#include <linux/mm.h>
19#include <linux/module.h>
20#include <linux/version.h>
21#include <linux/timer.h>
22#include <media/videobuf2-dma-contig.h>
23
24static int find_reg_callback(struct device *dev, void *p)
25{
26 struct v4l2_subdev **sd = p;
27
28 *sd = dev_get_drvdata(dev);
29 /* non-zero value stops iteration */
30 return 1;
31}
32
33static struct v4l2_subdev *find_and_register_subdev(
34 struct mxr_device *mdev, char *module_name)
35{
36 struct device_driver *drv;
37 struct v4l2_subdev *sd = NULL;
38 int ret;
39
40 /* TODO: add waiting until probe is finished */
41 drv = driver_find(module_name, &platform_bus_type);
42 if (!drv) {
43 mxr_warn(mdev, "module %s is missing\n", module_name);
44 return NULL;
45 }
46 /* driver refcnt is increased, it is safe to iterate over devices */
47 ret = driver_for_each_device(drv, NULL, &sd, find_reg_callback);
48 /* ret == 0 means that find_reg_callback was never executed */
49 if (sd == NULL) {
50 mxr_warn(mdev, "module %s provides no subdev!\n", module_name);
51 goto done;
52 }
53 /* v4l2_device_register_subdev detects if sd is NULL */
54 ret = v4l2_device_register_subdev(&mdev->v4l2_dev, sd);
55 if (ret) {
56 mxr_warn(mdev, "failed to register subdev %s\n", sd->name);
57 sd = NULL;
58 }
59
60done:
61 return sd;
62}
63
64int __devinit mxr_acquire_video(struct mxr_device *mdev,
65 struct mxr_output_conf *output_conf, int output_count)
66{
67 struct device *dev = mdev->dev;
68 struct v4l2_device *v4l2_dev = &mdev->v4l2_dev;
69 int i;
70 int ret = 0;
71 struct v4l2_subdev *sd;
72
73 strlcpy(v4l2_dev->name, dev_name(mdev->dev), sizeof(v4l2_dev->name));
74 /* prepare context for V4L2 device */
75 ret = v4l2_device_register(dev, v4l2_dev);
76 if (ret) {
77 mxr_err(mdev, "could not register v4l2 device.\n");
78 goto fail;
79 }
80
81 mdev->alloc_ctx = vb2_dma_contig_init_ctx(mdev->dev);
82 if (IS_ERR_OR_NULL(mdev->alloc_ctx)) {
83 mxr_err(mdev, "could not acquire vb2 allocator\n");
84 goto fail_v4l2_dev;
85 }
86
87 /* registering outputs */
88 mdev->output_cnt = 0;
89 for (i = 0; i < output_count; ++i) {
90 struct mxr_output_conf *conf = &output_conf[i];
91 struct mxr_output *out;
92
93 sd = find_and_register_subdev(mdev, conf->module_name);
94 /* trying to register next output */
95 if (sd == NULL)
96 continue;
97 out = kzalloc(sizeof *out, GFP_KERNEL);
98 if (out == NULL) {
99 mxr_err(mdev, "no memory for '%s'\n",
100 conf->output_name);
101 ret = -ENOMEM;
102 /* registered subdevs are removed in fail_v4l2_dev */
103 goto fail_output;
104 }
105 strlcpy(out->name, conf->output_name, sizeof(out->name));
106 out->sd = sd;
107 out->cookie = conf->cookie;
108 mdev->output[mdev->output_cnt++] = out;
109 mxr_info(mdev, "added output '%s' from module '%s'\n",
110 conf->output_name, conf->module_name);
111 /* checking if maximal number of outputs is reached */
112 if (mdev->output_cnt >= MXR_MAX_OUTPUTS)
113 break;
114 }
115
116 if (mdev->output_cnt == 0) {
117 mxr_err(mdev, "failed to register any output\n");
118 ret = -ENODEV;
119 /* skipping fail_output because there is nothing to free */
120 goto fail_vb2_allocator;
121 }
122
123 return 0;
124
125fail_output:
126 /* kfree is NULL-safe */
127 for (i = 0; i < mdev->output_cnt; ++i)
128 kfree(mdev->output[i]);
129 memset(mdev->output, 0, sizeof mdev->output);
130
131fail_vb2_allocator:
132 /* freeing allocator context */
133 vb2_dma_contig_cleanup_ctx(mdev->alloc_ctx);
134
135fail_v4l2_dev:
136 /* NOTE: automatically unregister all subdevs */
137 v4l2_device_unregister(v4l2_dev);
138
139fail:
140 return ret;
141}
142
143void mxr_release_video(struct mxr_device *mdev)
144{
145 int i;
146
147 /* kfree is NULL-safe */
148 for (i = 0; i < mdev->output_cnt; ++i)
149 kfree(mdev->output[i]);
150
151 vb2_dma_contig_cleanup_ctx(mdev->alloc_ctx);
152 v4l2_device_unregister(&mdev->v4l2_dev);
153}
154
155static int mxr_querycap(struct file *file, void *priv,
156 struct v4l2_capability *cap)
157{
158 struct mxr_layer *layer = video_drvdata(file);
159
160 mxr_dbg(layer->mdev, "%s:%d\n", __func__, __LINE__);
161
162 strlcpy(cap->driver, MXR_DRIVER_NAME, sizeof cap->driver);
163 strlcpy(cap->card, layer->vfd.name, sizeof cap->card);
164 sprintf(cap->bus_info, "%d", layer->idx);
165 cap->version = KERNEL_VERSION(0, 1, 0);
166 cap->capabilities = V4L2_CAP_STREAMING |
167 V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_MPLANE;
168
169 return 0;
170}
171
172static void mxr_geometry_dump(struct mxr_device *mdev, struct mxr_geometry *geo)
173{
174 mxr_dbg(mdev, "src.full_size = (%u, %u)\n",
175 geo->src.full_width, geo->src.full_height);
176 mxr_dbg(mdev, "src.size = (%u, %u)\n",
177 geo->src.width, geo->src.height);
178 mxr_dbg(mdev, "src.offset = (%u, %u)\n",
179 geo->src.x_offset, geo->src.y_offset);
180 mxr_dbg(mdev, "dst.full_size = (%u, %u)\n",
181 geo->dst.full_width, geo->dst.full_height);
182 mxr_dbg(mdev, "dst.size = (%u, %u)\n",
183 geo->dst.width, geo->dst.height);
184 mxr_dbg(mdev, "dst.offset = (%u, %u)\n",
185 geo->dst.x_offset, geo->dst.y_offset);
186 mxr_dbg(mdev, "ratio = (%u, %u)\n",
187 geo->x_ratio, geo->y_ratio);
188}
189
190static void mxr_layer_default_geo(struct mxr_layer *layer)
191{
192 struct mxr_device *mdev = layer->mdev;
193 struct v4l2_mbus_framefmt mbus_fmt;
194
195 memset(&layer->geo, 0, sizeof layer->geo);
196
197 mxr_get_mbus_fmt(mdev, &mbus_fmt);
198
199 layer->geo.dst.full_width = mbus_fmt.width;
200 layer->geo.dst.full_height = mbus_fmt.height;
201 layer->geo.dst.width = layer->geo.dst.full_width;
202 layer->geo.dst.height = layer->geo.dst.full_height;
203 layer->geo.dst.field = mbus_fmt.field;
204
205 layer->geo.src.full_width = mbus_fmt.width;
206 layer->geo.src.full_height = mbus_fmt.height;
207 layer->geo.src.width = layer->geo.src.full_width;
208 layer->geo.src.height = layer->geo.src.full_height;
209
210 mxr_geometry_dump(mdev, &layer->geo);
211 layer->ops.fix_geometry(layer, MXR_GEOMETRY_SINK, 0);
212 mxr_geometry_dump(mdev, &layer->geo);
213}
214
215static void mxr_layer_update_output(struct mxr_layer *layer)
216{
217 struct mxr_device *mdev = layer->mdev;
218 struct v4l2_mbus_framefmt mbus_fmt;
219
220 mxr_get_mbus_fmt(mdev, &mbus_fmt);
221 /* checking if update is needed */
222 if (layer->geo.dst.full_width == mbus_fmt.width &&
223 layer->geo.dst.full_height == mbus_fmt.width)
224 return;
225
226 layer->geo.dst.full_width = mbus_fmt.width;
227 layer->geo.dst.full_height = mbus_fmt.height;
228 layer->geo.dst.field = mbus_fmt.field;
229 layer->ops.fix_geometry(layer, MXR_GEOMETRY_SINK, 0);
230
231 mxr_geometry_dump(mdev, &layer->geo);
232}
233
234static const struct mxr_format *find_format_by_fourcc(
235 struct mxr_layer *layer, unsigned long fourcc);
236static const struct mxr_format *find_format_by_index(
237 struct mxr_layer *layer, unsigned long index);
238
239static int mxr_enum_fmt(struct file *file, void *priv,
240 struct v4l2_fmtdesc *f)
241{
242 struct mxr_layer *layer = video_drvdata(file);
243 struct mxr_device *mdev = layer->mdev;
244 const struct mxr_format *fmt;
245
246 mxr_dbg(mdev, "%s\n", __func__);
247 fmt = find_format_by_index(layer, f->index);
248 if (fmt == NULL)
249 return -EINVAL;
250
251 strlcpy(f->description, fmt->name, sizeof(f->description));
252 f->pixelformat = fmt->fourcc;
253
254 return 0;
255}
256
257static unsigned int divup(unsigned int divident, unsigned int divisor)
258{
259 return (divident + divisor - 1) / divisor;
260}
261
262unsigned long mxr_get_plane_size(const struct mxr_block *blk,
263 unsigned int width, unsigned int height)
264{
265 unsigned int bl_width = divup(width, blk->width);
266 unsigned int bl_height = divup(height, blk->height);
267
268 return bl_width * bl_height * blk->size;
269}
270
271static void mxr_mplane_fill(struct v4l2_plane_pix_format *planes,
272 const struct mxr_format *fmt, u32 width, u32 height)
273{
274 int i;
275
276 /* checking if nothing to fill */
277 if (!planes)
278 return;
279
280 memset(planes, 0, sizeof(*planes) * fmt->num_subframes);
281 for (i = 0; i < fmt->num_planes; ++i) {
282 struct v4l2_plane_pix_format *plane = planes
283 + fmt->plane2subframe[i];
284 const struct mxr_block *blk = &fmt->plane[i];
285 u32 bl_width = divup(width, blk->width);
286 u32 bl_height = divup(height, blk->height);
287 u32 sizeimage = bl_width * bl_height * blk->size;
288 u16 bytesperline = bl_width * blk->size / blk->height;
289
290 plane->sizeimage += sizeimage;
291 plane->bytesperline = max(plane->bytesperline, bytesperline);
292 }
293}
294
295static int mxr_g_fmt(struct file *file, void *priv,
296 struct v4l2_format *f)
297{
298 struct mxr_layer *layer = video_drvdata(file);
299 struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
300
301 mxr_dbg(layer->mdev, "%s:%d\n", __func__, __LINE__);
302
303 pix->width = layer->geo.src.full_width;
304 pix->height = layer->geo.src.full_height;
305 pix->field = V4L2_FIELD_NONE;
306 pix->pixelformat = layer->fmt->fourcc;
307 pix->colorspace = layer->fmt->colorspace;
308 mxr_mplane_fill(pix->plane_fmt, layer->fmt, pix->width, pix->height);
309
310 return 0;
311}
312
313static int mxr_s_fmt(struct file *file, void *priv,
314 struct v4l2_format *f)
315{
316 struct mxr_layer *layer = video_drvdata(file);
317 const struct mxr_format *fmt;
318 struct v4l2_pix_format_mplane *pix;
319 struct mxr_device *mdev = layer->mdev;
320 struct mxr_geometry *geo = &layer->geo;
321
322 mxr_dbg(mdev, "%s:%d\n", __func__, __LINE__);
323
324 pix = &f->fmt.pix_mp;
325 fmt = find_format_by_fourcc(layer, pix->pixelformat);
326 if (fmt == NULL) {
327 mxr_warn(mdev, "not recognized fourcc: %08x\n",
328 pix->pixelformat);
329 return -EINVAL;
330 }
331 layer->fmt = fmt;
332 /* set source size to highest accepted value */
333 geo->src.full_width = max(geo->dst.full_width, pix->width);
334 geo->src.full_height = max(geo->dst.full_height, pix->height);
335 layer->ops.fix_geometry(layer, MXR_GEOMETRY_SOURCE, 0);
336 mxr_geometry_dump(mdev, &layer->geo);
337 /* set cropping to total visible screen */
338 geo->src.width = pix->width;
339 geo->src.height = pix->height;
340 geo->src.x_offset = 0;
341 geo->src.y_offset = 0;
342 /* assure consistency of geometry */
343 layer->ops.fix_geometry(layer, MXR_GEOMETRY_CROP, MXR_NO_OFFSET);
344 mxr_geometry_dump(mdev, &layer->geo);
345 /* set full size to lowest possible value */
346 geo->src.full_width = 0;
347 geo->src.full_height = 0;
348 layer->ops.fix_geometry(layer, MXR_GEOMETRY_SOURCE, 0);
349 mxr_geometry_dump(mdev, &layer->geo);
350
351 /* returning results */
352 mxr_g_fmt(file, priv, f);
353
354 return 0;
355}
356
357static int mxr_g_selection(struct file *file, void *fh,
358 struct v4l2_selection *s)
359{
360 struct mxr_layer *layer = video_drvdata(file);
361 struct mxr_geometry *geo = &layer->geo;
362
363 mxr_dbg(layer->mdev, "%s:%d\n", __func__, __LINE__);
364
365 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
366 s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
367 return -EINVAL;
368
369 switch (s->target) {
370 case V4L2_SEL_TGT_CROP:
371 s->r.left = geo->src.x_offset;
372 s->r.top = geo->src.y_offset;
373 s->r.width = geo->src.width;
374 s->r.height = geo->src.height;
375 break;
376 case V4L2_SEL_TGT_CROP_DEFAULT:
377 case V4L2_SEL_TGT_CROP_BOUNDS:
378 s->r.left = 0;
379 s->r.top = 0;
380 s->r.width = geo->src.full_width;
381 s->r.height = geo->src.full_height;
382 break;
383 case V4L2_SEL_TGT_COMPOSE:
384 case V4L2_SEL_TGT_COMPOSE_PADDED:
385 s->r.left = geo->dst.x_offset;
386 s->r.top = geo->dst.y_offset;
387 s->r.width = geo->dst.width;
388 s->r.height = geo->dst.height;
389 break;
390 case V4L2_SEL_TGT_COMPOSE_DEFAULT:
391 case V4L2_SEL_TGT_COMPOSE_BOUNDS:
392 s->r.left = 0;
393 s->r.top = 0;
394 s->r.width = geo->dst.full_width;
395 s->r.height = geo->dst.full_height;
396 break;
397 default:
398 return -EINVAL;
399 }
400
401 return 0;
402}
403
404/* returns 1 if rectangle 'a' is inside 'b' */
405static int mxr_is_rect_inside(struct v4l2_rect *a, struct v4l2_rect *b)
406{
407 if (a->left < b->left)
408 return 0;
409 if (a->top < b->top)
410 return 0;
411 if (a->left + a->width > b->left + b->width)
412 return 0;
413 if (a->top + a->height > b->top + b->height)
414 return 0;
415 return 1;
416}
417
418static int mxr_s_selection(struct file *file, void *fh,
419 struct v4l2_selection *s)
420{
421 struct mxr_layer *layer = video_drvdata(file);
422 struct mxr_geometry *geo = &layer->geo;
423 struct mxr_crop *target = NULL;
424 enum mxr_geometry_stage stage;
425 struct mxr_geometry tmp;
426 struct v4l2_rect res;
427
428 memset(&res, 0, sizeof res);
429
430 mxr_dbg(layer->mdev, "%s: rect: %dx%d@%d,%d\n", __func__,
431 s->r.width, s->r.height, s->r.left, s->r.top);
432
433 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
434 s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
435 return -EINVAL;
436
437 switch (s->target) {
438 /* ignore read-only targets */
439 case V4L2_SEL_TGT_CROP_DEFAULT:
440 case V4L2_SEL_TGT_CROP_BOUNDS:
441 res.width = geo->src.full_width;
442 res.height = geo->src.full_height;
443 break;
444
445 /* ignore read-only targets */
446 case V4L2_SEL_TGT_COMPOSE_DEFAULT:
447 case V4L2_SEL_TGT_COMPOSE_BOUNDS:
448 res.width = geo->dst.full_width;
449 res.height = geo->dst.full_height;
450 break;
451
452 case V4L2_SEL_TGT_CROP:
453 target = &geo->src;
454 stage = MXR_GEOMETRY_CROP;
455 break;
456 case V4L2_SEL_TGT_COMPOSE:
457 case V4L2_SEL_TGT_COMPOSE_PADDED:
458 target = &geo->dst;
459 stage = MXR_GEOMETRY_COMPOSE;
460 break;
461 default:
462 return -EINVAL;
463 }
464 /* apply change and update geometry if needed */
465 if (target) {
466 /* backup current geometry if setup fails */
467 memcpy(&tmp, geo, sizeof tmp);
468
469 /* apply requested selection */
470 target->x_offset = s->r.left;
471 target->y_offset = s->r.top;
472 target->width = s->r.width;
473 target->height = s->r.height;
474
475 layer->ops.fix_geometry(layer, stage, s->flags);
476
477 /* retrieve update selection rectangle */
478 res.left = target->x_offset;
479 res.top = target->y_offset;
480 res.width = target->width;
481 res.height = target->height;
482
483 mxr_geometry_dump(layer->mdev, &layer->geo);
484 }
485
486 /* checking if the rectangle satisfies constraints */
487 if ((s->flags & V4L2_SEL_FLAG_LE) && !mxr_is_rect_inside(&res, &s->r))
488 goto fail;
489 if ((s->flags & V4L2_SEL_FLAG_GE) && !mxr_is_rect_inside(&s->r, &res))
490 goto fail;
491
492 /* return result rectangle */
493 s->r = res;
494
495 return 0;
496fail:
497 /* restore old geometry, which is not touched if target is NULL */
498 if (target)
499 memcpy(geo, &tmp, sizeof tmp);
500 return -ERANGE;
501}
502
503static int mxr_enum_dv_presets(struct file *file, void *fh,
504 struct v4l2_dv_enum_preset *preset)
505{
506 struct mxr_layer *layer = video_drvdata(file);
507 struct mxr_device *mdev = layer->mdev;
508 int ret;
509
510 /* lock protects from changing sd_out */
511 mutex_lock(&mdev->mutex);
512 ret = v4l2_subdev_call(to_outsd(mdev), video, enum_dv_presets, preset);
513 mutex_unlock(&mdev->mutex);
514
515 return ret ? -EINVAL : 0;
516}
517
518static int mxr_s_dv_preset(struct file *file, void *fh,
519 struct v4l2_dv_preset *preset)
520{
521 struct mxr_layer *layer = video_drvdata(file);
522 struct mxr_device *mdev = layer->mdev;
523 int ret;
524
525 /* lock protects from changing sd_out */
526 mutex_lock(&mdev->mutex);
527
528 /* preset change cannot be done while there is an entity
529 * dependant on output configuration
530 */
531 if (mdev->n_output > 0) {
532 mutex_unlock(&mdev->mutex);
533 return -EBUSY;
534 }
535
536 ret = v4l2_subdev_call(to_outsd(mdev), video, s_dv_preset, preset);
537
538 mutex_unlock(&mdev->mutex);
539
540 mxr_layer_update_output(layer);
541
542 /* any failure should return EINVAL according to V4L2 doc */
543 return ret ? -EINVAL : 0;
544}
545
546static int mxr_g_dv_preset(struct file *file, void *fh,
547 struct v4l2_dv_preset *preset)
548{
549 struct mxr_layer *layer = video_drvdata(file);
550 struct mxr_device *mdev = layer->mdev;
551 int ret;
552
553 /* lock protects from changing sd_out */
554 mutex_lock(&mdev->mutex);
555 ret = v4l2_subdev_call(to_outsd(mdev), video, g_dv_preset, preset);
556 mutex_unlock(&mdev->mutex);
557
558 return ret ? -EINVAL : 0;
559}
560
561static int mxr_s_std(struct file *file, void *fh, v4l2_std_id *norm)
562{
563 struct mxr_layer *layer = video_drvdata(file);
564 struct mxr_device *mdev = layer->mdev;
565 int ret;
566
567 /* lock protects from changing sd_out */
568 mutex_lock(&mdev->mutex);
569
570 /* standard change cannot be done while there is an entity
571 * dependant on output configuration
572 */
573 if (mdev->n_output > 0) {
574 mutex_unlock(&mdev->mutex);
575 return -EBUSY;
576 }
577
578 ret = v4l2_subdev_call(to_outsd(mdev), video, s_std_output, *norm);
579
580 mutex_unlock(&mdev->mutex);
581
582 mxr_layer_update_output(layer);
583
584 return ret ? -EINVAL : 0;
585}
586
587static int mxr_g_std(struct file *file, void *fh, v4l2_std_id *norm)
588{
589 struct mxr_layer *layer = video_drvdata(file);
590 struct mxr_device *mdev = layer->mdev;
591 int ret;
592
593 /* lock protects from changing sd_out */
594 mutex_lock(&mdev->mutex);
595 ret = v4l2_subdev_call(to_outsd(mdev), video, g_std_output, norm);
596 mutex_unlock(&mdev->mutex);
597
598 return ret ? -EINVAL : 0;
599}
600
601static int mxr_enum_output(struct file *file, void *fh, struct v4l2_output *a)
602{
603 struct mxr_layer *layer = video_drvdata(file);
604 struct mxr_device *mdev = layer->mdev;
605 struct mxr_output *out;
606 struct v4l2_subdev *sd;
607
608 if (a->index >= mdev->output_cnt)
609 return -EINVAL;
610 out = mdev->output[a->index];
611 BUG_ON(out == NULL);
612 sd = out->sd;
613 strlcpy(a->name, out->name, sizeof(a->name));
614
615 /* try to obtain supported tv norms */
616 v4l2_subdev_call(sd, video, g_tvnorms_output, &a->std);
617 a->capabilities = 0;
618 if (sd->ops->video && sd->ops->video->s_dv_preset)
619 a->capabilities |= V4L2_OUT_CAP_PRESETS;
620 if (sd->ops->video && sd->ops->video->s_std_output)
621 a->capabilities |= V4L2_OUT_CAP_STD;
622 a->type = V4L2_OUTPUT_TYPE_ANALOG;
623
624 return 0;
625}
626
627static int mxr_s_output(struct file *file, void *fh, unsigned int i)
628{
629 struct video_device *vfd = video_devdata(file);
630 struct mxr_layer *layer = video_drvdata(file);
631 struct mxr_device *mdev = layer->mdev;
632
633 if (i >= mdev->output_cnt || mdev->output[i] == NULL)
634 return -EINVAL;
635
636 mutex_lock(&mdev->mutex);
637 if (mdev->n_output > 0) {
638 mutex_unlock(&mdev->mutex);
639 return -EBUSY;
640 }
641 mdev->current_output = i;
642 vfd->tvnorms = 0;
643 v4l2_subdev_call(to_outsd(mdev), video, g_tvnorms_output,
644 &vfd->tvnorms);
645 mutex_unlock(&mdev->mutex);
646
647 /* update layers geometry */
648 mxr_layer_update_output(layer);
649
650 mxr_dbg(mdev, "tvnorms = %08llx\n", vfd->tvnorms);
651
652 return 0;
653}
654
655static int mxr_g_output(struct file *file, void *fh, unsigned int *p)
656{
657 struct mxr_layer *layer = video_drvdata(file);
658 struct mxr_device *mdev = layer->mdev;
659
660 mutex_lock(&mdev->mutex);
661 *p = mdev->current_output;
662 mutex_unlock(&mdev->mutex);
663
664 return 0;
665}
666
667static int mxr_reqbufs(struct file *file, void *priv,
668 struct v4l2_requestbuffers *p)
669{
670 struct mxr_layer *layer = video_drvdata(file);
671
672 mxr_dbg(layer->mdev, "%s:%d\n", __func__, __LINE__);
673 return vb2_reqbufs(&layer->vb_queue, p);
674}
675
676static int mxr_querybuf(struct file *file, void *priv, struct v4l2_buffer *p)
677{
678 struct mxr_layer *layer = video_drvdata(file);
679
680 mxr_dbg(layer->mdev, "%s:%d\n", __func__, __LINE__);
681 return vb2_querybuf(&layer->vb_queue, p);
682}
683
684static int mxr_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
685{
686 struct mxr_layer *layer = video_drvdata(file);
687
688 mxr_dbg(layer->mdev, "%s:%d(%d)\n", __func__, __LINE__, p->index);
689 return vb2_qbuf(&layer->vb_queue, p);
690}
691
692static int mxr_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
693{
694 struct mxr_layer *layer = video_drvdata(file);
695
696 mxr_dbg(layer->mdev, "%s:%d\n", __func__, __LINE__);
697 return vb2_dqbuf(&layer->vb_queue, p, file->f_flags & O_NONBLOCK);
698}
699
700static int mxr_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
701{
702 struct mxr_layer *layer = video_drvdata(file);
703
704 mxr_dbg(layer->mdev, "%s:%d\n", __func__, __LINE__);
705 return vb2_streamon(&layer->vb_queue, i);
706}
707
708static int mxr_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
709{
710 struct mxr_layer *layer = video_drvdata(file);
711
712 mxr_dbg(layer->mdev, "%s:%d\n", __func__, __LINE__);
713 return vb2_streamoff(&layer->vb_queue, i);
714}
715
716static const struct v4l2_ioctl_ops mxr_ioctl_ops = {
717 .vidioc_querycap = mxr_querycap,
718 /* format handling */
719 .vidioc_enum_fmt_vid_out = mxr_enum_fmt,
720 .vidioc_s_fmt_vid_out_mplane = mxr_s_fmt,
721 .vidioc_g_fmt_vid_out_mplane = mxr_g_fmt,
722 /* buffer control */
723 .vidioc_reqbufs = mxr_reqbufs,
724 .vidioc_querybuf = mxr_querybuf,
725 .vidioc_qbuf = mxr_qbuf,
726 .vidioc_dqbuf = mxr_dqbuf,
727 /* Streaming control */
728 .vidioc_streamon = mxr_streamon,
729 .vidioc_streamoff = mxr_streamoff,
730 /* Preset functions */
731 .vidioc_enum_dv_presets = mxr_enum_dv_presets,
732 .vidioc_s_dv_preset = mxr_s_dv_preset,
733 .vidioc_g_dv_preset = mxr_g_dv_preset,
734 /* analog TV standard functions */
735 .vidioc_s_std = mxr_s_std,
736 .vidioc_g_std = mxr_g_std,
737 /* Output handling */
738 .vidioc_enum_output = mxr_enum_output,
739 .vidioc_s_output = mxr_s_output,
740 .vidioc_g_output = mxr_g_output,
741 /* selection ioctls */
742 .vidioc_g_selection = mxr_g_selection,
743 .vidioc_s_selection = mxr_s_selection,
744};
745
746static int mxr_video_open(struct file *file)
747{
748 struct mxr_layer *layer = video_drvdata(file);
749 struct mxr_device *mdev = layer->mdev;
750 int ret = 0;
751
752 mxr_dbg(mdev, "%s:%d\n", __func__, __LINE__);
753 if (mutex_lock_interruptible(&layer->mutex))
754 return -ERESTARTSYS;
755 /* assure device probe is finished */
756 wait_for_device_probe();
757 /* creating context for file descriptor */
758 ret = v4l2_fh_open(file);
759 if (ret) {
760 mxr_err(mdev, "v4l2_fh_open failed\n");
761 goto unlock;
762 }
763
764 /* leaving if layer is already initialized */
765 if (!v4l2_fh_is_singular_file(file))
766 goto unlock;
767
768 /* FIXME: should power be enabled on open? */
769 ret = mxr_power_get(mdev);
770 if (ret) {
771 mxr_err(mdev, "power on failed\n");
772 goto fail_fh_open;
773 }
774
775 ret = vb2_queue_init(&layer->vb_queue);
776 if (ret != 0) {
777 mxr_err(mdev, "failed to initialize vb2 queue\n");
778 goto fail_power;
779 }
780 /* set default format, first on the list */
781 layer->fmt = layer->fmt_array[0];
782 /* setup default geometry */
783 mxr_layer_default_geo(layer);
784 mutex_unlock(&layer->mutex);
785
786 return 0;
787
788fail_power:
789 mxr_power_put(mdev);
790
791fail_fh_open:
792 v4l2_fh_release(file);
793
794unlock:
795 mutex_unlock(&layer->mutex);
796
797 return ret;
798}
799
800static unsigned int
801mxr_video_poll(struct file *file, struct poll_table_struct *wait)
802{
803 struct mxr_layer *layer = video_drvdata(file);
804 unsigned int res;
805
806 mxr_dbg(layer->mdev, "%s:%d\n", __func__, __LINE__);
807
808 mutex_lock(&layer->mutex);
809 res = vb2_poll(&layer->vb_queue, file, wait);
810 mutex_unlock(&layer->mutex);
811 return res;
812}
813
814static int mxr_video_mmap(struct file *file, struct vm_area_struct *vma)
815{
816 struct mxr_layer *layer = video_drvdata(file);
817 int ret;
818
819 mxr_dbg(layer->mdev, "%s:%d\n", __func__, __LINE__);
820
821 if (mutex_lock_interruptible(&layer->mutex))
822 return -ERESTARTSYS;
823 ret = vb2_mmap(&layer->vb_queue, vma);
824 mutex_unlock(&layer->mutex);
825 return ret;
826}
827
828static int mxr_video_release(struct file *file)
829{
830 struct mxr_layer *layer = video_drvdata(file);
831
832 mxr_dbg(layer->mdev, "%s:%d\n", __func__, __LINE__);
833 mutex_lock(&layer->mutex);
834 if (v4l2_fh_is_singular_file(file)) {
835 vb2_queue_release(&layer->vb_queue);
836 mxr_power_put(layer->mdev);
837 }
838 v4l2_fh_release(file);
839 mutex_unlock(&layer->mutex);
840 return 0;
841}
842
843static const struct v4l2_file_operations mxr_fops = {
844 .owner = THIS_MODULE,
845 .open = mxr_video_open,
846 .poll = mxr_video_poll,
847 .mmap = mxr_video_mmap,
848 .release = mxr_video_release,
849 .unlocked_ioctl = video_ioctl2,
850};
851
852static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *pfmt,
853 unsigned int *nbuffers, unsigned int *nplanes, unsigned int sizes[],
854 void *alloc_ctxs[])
855{
856 struct mxr_layer *layer = vb2_get_drv_priv(vq);
857 const struct mxr_format *fmt = layer->fmt;
858 int i;
859 struct mxr_device *mdev = layer->mdev;
860 struct v4l2_plane_pix_format planes[3];
861
862 mxr_dbg(mdev, "%s\n", __func__);
863 /* checking if format was configured */
864 if (fmt == NULL)
865 return -EINVAL;
866 mxr_dbg(mdev, "fmt = %s\n", fmt->name);
867 mxr_mplane_fill(planes, fmt, layer->geo.src.full_width,
868 layer->geo.src.full_height);
869
870 *nplanes = fmt->num_subframes;
871 for (i = 0; i < fmt->num_subframes; ++i) {
872 alloc_ctxs[i] = layer->mdev->alloc_ctx;
873 sizes[i] = planes[i].sizeimage;
874 mxr_dbg(mdev, "size[%d] = %08x\n", i, sizes[i]);
875 }
876
877 if (*nbuffers == 0)
878 *nbuffers = 1;
879
880 return 0;
881}
882
883static void buf_queue(struct vb2_buffer *vb)
884{
885 struct mxr_buffer *buffer = container_of(vb, struct mxr_buffer, vb);
886 struct mxr_layer *layer = vb2_get_drv_priv(vb->vb2_queue);
887 struct mxr_device *mdev = layer->mdev;
888 unsigned long flags;
889
890 spin_lock_irqsave(&layer->enq_slock, flags);
891 list_add_tail(&buffer->list, &layer->enq_list);
892 spin_unlock_irqrestore(&layer->enq_slock, flags);
893
894 mxr_dbg(mdev, "queuing buffer\n");
895}
896
897static void wait_lock(struct vb2_queue *vq)
898{
899 struct mxr_layer *layer = vb2_get_drv_priv(vq);
900
901 mxr_dbg(layer->mdev, "%s\n", __func__);
902 mutex_lock(&layer->mutex);
903}
904
905static void wait_unlock(struct vb2_queue *vq)
906{
907 struct mxr_layer *layer = vb2_get_drv_priv(vq);
908
909 mxr_dbg(layer->mdev, "%s\n", __func__);
910 mutex_unlock(&layer->mutex);
911}
912
913static int start_streaming(struct vb2_queue *vq, unsigned int count)
914{
915 struct mxr_layer *layer = vb2_get_drv_priv(vq);
916 struct mxr_device *mdev = layer->mdev;
917 unsigned long flags;
918
919 mxr_dbg(mdev, "%s\n", __func__);
920
921 if (count == 0) {
922 mxr_dbg(mdev, "no output buffers queued\n");
923 return -EINVAL;
924 }
925
926 /* block any changes in output configuration */
927 mxr_output_get(mdev);
928
929 mxr_layer_update_output(layer);
930 layer->ops.format_set(layer);
931 /* enabling layer in hardware */
932 spin_lock_irqsave(&layer->enq_slock, flags);
933 layer->state = MXR_LAYER_STREAMING;
934 spin_unlock_irqrestore(&layer->enq_slock, flags);
935
936 layer->ops.stream_set(layer, MXR_ENABLE);
937 mxr_streamer_get(mdev);
938
939 return 0;
940}
941
942static void mxr_watchdog(unsigned long arg)
943{
944 struct mxr_layer *layer = (struct mxr_layer *) arg;
945 struct mxr_device *mdev = layer->mdev;
946 unsigned long flags;
947
948 mxr_err(mdev, "watchdog fired for layer %s\n", layer->vfd.name);
949
950 spin_lock_irqsave(&layer->enq_slock, flags);
951
952 if (layer->update_buf == layer->shadow_buf)
953 layer->update_buf = NULL;
954 if (layer->update_buf) {
955 vb2_buffer_done(&layer->update_buf->vb, VB2_BUF_STATE_ERROR);
956 layer->update_buf = NULL;
957 }
958 if (layer->shadow_buf) {
959 vb2_buffer_done(&layer->shadow_buf->vb, VB2_BUF_STATE_ERROR);
960 layer->shadow_buf = NULL;
961 }
962 spin_unlock_irqrestore(&layer->enq_slock, flags);
963}
964
965static int stop_streaming(struct vb2_queue *vq)
966{
967 struct mxr_layer *layer = vb2_get_drv_priv(vq);
968 struct mxr_device *mdev = layer->mdev;
969 unsigned long flags;
970 struct timer_list watchdog;
971 struct mxr_buffer *buf, *buf_tmp;
972
973 mxr_dbg(mdev, "%s\n", __func__);
974
975 spin_lock_irqsave(&layer->enq_slock, flags);
976
977 /* reset list */
978 layer->state = MXR_LAYER_STREAMING_FINISH;
979
980 /* set all buffer to be done */
981 list_for_each_entry_safe(buf, buf_tmp, &layer->enq_list, list) {
982 list_del(&buf->list);
983 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
984 }
985
986 spin_unlock_irqrestore(&layer->enq_slock, flags);
987
988 /* give 1 seconds to complete to complete last buffers */
989 setup_timer_on_stack(&watchdog, mxr_watchdog,
990 (unsigned long)layer);
991 mod_timer(&watchdog, jiffies + msecs_to_jiffies(1000));
992
993 /* wait until all buffers are goes to done state */
994 vb2_wait_for_all_buffers(vq);
995
996 /* stop timer if all synchronization is done */
997 del_timer_sync(&watchdog);
998 destroy_timer_on_stack(&watchdog);
999
1000 /* stopping hardware */
1001 spin_lock_irqsave(&layer->enq_slock, flags);
1002 layer->state = MXR_LAYER_IDLE;
1003 spin_unlock_irqrestore(&layer->enq_slock, flags);
1004
1005 /* disabling layer in hardware */
1006 layer->ops.stream_set(layer, MXR_DISABLE);
1007 /* remove one streamer */
1008 mxr_streamer_put(mdev);
1009 /* allow changes in output configuration */
1010 mxr_output_put(mdev);
1011 return 0;
1012}
1013
1014static struct vb2_ops mxr_video_qops = {
1015 .queue_setup = queue_setup,
1016 .buf_queue = buf_queue,
1017 .wait_prepare = wait_unlock,
1018 .wait_finish = wait_lock,
1019 .start_streaming = start_streaming,
1020 .stop_streaming = stop_streaming,
1021};
1022
1023/* FIXME: try to put this functions to mxr_base_layer_create */
1024int mxr_base_layer_register(struct mxr_layer *layer)
1025{
1026 struct mxr_device *mdev = layer->mdev;
1027 int ret;
1028
1029 ret = video_register_device(&layer->vfd, VFL_TYPE_GRABBER, -1);
1030 if (ret)
1031 mxr_err(mdev, "failed to register video device\n");
1032 else
1033 mxr_info(mdev, "registered layer %s as /dev/video%d\n",
1034 layer->vfd.name, layer->vfd.num);
1035 return ret;
1036}
1037
1038void mxr_base_layer_unregister(struct mxr_layer *layer)
1039{
1040 video_unregister_device(&layer->vfd);
1041}
1042
1043void mxr_layer_release(struct mxr_layer *layer)
1044{
1045 if (layer->ops.release)
1046 layer->ops.release(layer);
1047}
1048
1049void mxr_base_layer_release(struct mxr_layer *layer)
1050{
1051 kfree(layer);
1052}
1053
1054static void mxr_vfd_release(struct video_device *vdev)
1055{
1056 printk(KERN_INFO "video device release\n");
1057}
1058
1059struct mxr_layer *mxr_base_layer_create(struct mxr_device *mdev,
1060 int idx, char *name, struct mxr_layer_ops *ops)
1061{
1062 struct mxr_layer *layer;
1063
1064 layer = kzalloc(sizeof *layer, GFP_KERNEL);
1065 if (layer == NULL) {
1066 mxr_err(mdev, "not enough memory for layer.\n");
1067 goto fail;
1068 }
1069
1070 layer->mdev = mdev;
1071 layer->idx = idx;
1072 layer->ops = *ops;
1073
1074 spin_lock_init(&layer->enq_slock);
1075 INIT_LIST_HEAD(&layer->enq_list);
1076 mutex_init(&layer->mutex);
1077
1078 layer->vfd = (struct video_device) {
1079 .minor = -1,
1080 .release = mxr_vfd_release,
1081 .fops = &mxr_fops,
1082 .ioctl_ops = &mxr_ioctl_ops,
1083 };
1084 strlcpy(layer->vfd.name, name, sizeof(layer->vfd.name));
1085 /* let framework control PRIORITY */
1086 set_bit(V4L2_FL_USE_FH_PRIO, &layer->vfd.flags);
1087
1088 video_set_drvdata(&layer->vfd, layer);
1089 layer->vfd.lock = &layer->mutex;
1090 layer->vfd.v4l2_dev = &mdev->v4l2_dev;
1091
1092 layer->vb_queue = (struct vb2_queue) {
1093 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
1094 .io_modes = VB2_MMAP | VB2_USERPTR,
1095 .drv_priv = layer,
1096 .buf_struct_size = sizeof(struct mxr_buffer),
1097 .ops = &mxr_video_qops,
1098 .mem_ops = &vb2_dma_contig_memops,
1099 };
1100
1101 return layer;
1102
1103fail:
1104 return NULL;
1105}
1106
1107static const struct mxr_format *find_format_by_fourcc(
1108 struct mxr_layer *layer, unsigned long fourcc)
1109{
1110 int i;
1111
1112 for (i = 0; i < layer->fmt_array_size; ++i)
1113 if (layer->fmt_array[i]->fourcc == fourcc)
1114 return layer->fmt_array[i];
1115 return NULL;
1116}
1117
1118static const struct mxr_format *find_format_by_index(
1119 struct mxr_layer *layer, unsigned long index)
1120{
1121 if (index >= layer->fmt_array_size)
1122 return NULL;
1123 return layer->fmt_array[index];
1124}
1125
diff --git a/drivers/media/video/s5p-tv/mixer_vp_layer.c b/drivers/media/video/s5p-tv/mixer_vp_layer.c
deleted file mode 100644
index 3d13a636877b..000000000000
--- a/drivers/media/video/s5p-tv/mixer_vp_layer.c
+++ /dev/null
@@ -1,241 +0,0 @@
1/*
2 * Samsung TV Mixer driver
3 *
4 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
5 *
6 * Tomasz Stanislawski, <t.stanislaws@samsung.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published
10 * by the Free Software Foundiation. either version 2 of the License,
11 * or (at your option) any later version
12 */
13
14#include "mixer.h"
15
16#include "regs-vp.h"
17
18#include <media/videobuf2-dma-contig.h>
19
20/* FORMAT DEFINITIONS */
21static const struct mxr_format mxr_fmt_nv12 = {
22 .name = "NV12",
23 .fourcc = V4L2_PIX_FMT_NV12,
24 .colorspace = V4L2_COLORSPACE_JPEG,
25 .num_planes = 2,
26 .plane = {
27 { .width = 1, .height = 1, .size = 1 },
28 { .width = 2, .height = 2, .size = 2 },
29 },
30 .num_subframes = 1,
31 .cookie = VP_MODE_NV12 | VP_MODE_MEM_LINEAR,
32};
33
34static const struct mxr_format mxr_fmt_nv21 = {
35 .name = "NV21",
36 .fourcc = V4L2_PIX_FMT_NV21,
37 .colorspace = V4L2_COLORSPACE_JPEG,
38 .num_planes = 2,
39 .plane = {
40 { .width = 1, .height = 1, .size = 1 },
41 { .width = 2, .height = 2, .size = 2 },
42 },
43 .num_subframes = 1,
44 .cookie = VP_MODE_NV21 | VP_MODE_MEM_LINEAR,
45};
46
47static const struct mxr_format mxr_fmt_nv12m = {
48 .name = "NV12 (mplane)",
49 .fourcc = V4L2_PIX_FMT_NV12M,
50 .colorspace = V4L2_COLORSPACE_JPEG,
51 .num_planes = 2,
52 .plane = {
53 { .width = 1, .height = 1, .size = 1 },
54 { .width = 2, .height = 2, .size = 2 },
55 },
56 .num_subframes = 2,
57 .plane2subframe = {0, 1},
58 .cookie = VP_MODE_NV12 | VP_MODE_MEM_LINEAR,
59};
60
61static const struct mxr_format mxr_fmt_nv12mt = {
62 .name = "NV12 tiled (mplane)",
63 .fourcc = V4L2_PIX_FMT_NV12MT,
64 .colorspace = V4L2_COLORSPACE_JPEG,
65 .num_planes = 2,
66 .plane = {
67 { .width = 128, .height = 32, .size = 4096 },
68 { .width = 128, .height = 32, .size = 2048 },
69 },
70 .num_subframes = 2,
71 .plane2subframe = {0, 1},
72 .cookie = VP_MODE_NV12 | VP_MODE_MEM_TILED,
73};
74
75static const struct mxr_format *mxr_video_format[] = {
76 &mxr_fmt_nv12,
77 &mxr_fmt_nv21,
78 &mxr_fmt_nv12m,
79 &mxr_fmt_nv12mt,
80};
81
82/* AUXILIARY CALLBACKS */
83
84static void mxr_vp_layer_release(struct mxr_layer *layer)
85{
86 mxr_base_layer_unregister(layer);
87 mxr_base_layer_release(layer);
88}
89
90static void mxr_vp_buffer_set(struct mxr_layer *layer,
91 struct mxr_buffer *buf)
92{
93 dma_addr_t luma_addr[2] = {0, 0};
94 dma_addr_t chroma_addr[2] = {0, 0};
95
96 if (buf == NULL) {
97 mxr_reg_vp_buffer(layer->mdev, luma_addr, chroma_addr);
98 return;
99 }
100 luma_addr[0] = vb2_dma_contig_plane_dma_addr(&buf->vb, 0);
101 if (layer->fmt->num_subframes == 2) {
102 chroma_addr[0] = vb2_dma_contig_plane_dma_addr(&buf->vb, 1);
103 } else {
104 /* FIXME: mxr_get_plane_size compute integer division,
105 * which is slow and should not be performed in interrupt */
106 chroma_addr[0] = luma_addr[0] + mxr_get_plane_size(
107 &layer->fmt->plane[0], layer->geo.src.full_width,
108 layer->geo.src.full_height);
109 }
110 if (layer->fmt->cookie & VP_MODE_MEM_TILED) {
111 luma_addr[1] = luma_addr[0] + 0x40;
112 chroma_addr[1] = chroma_addr[0] + 0x40;
113 } else {
114 luma_addr[1] = luma_addr[0] + layer->geo.src.full_width;
115 chroma_addr[1] = chroma_addr[0];
116 }
117 mxr_reg_vp_buffer(layer->mdev, luma_addr, chroma_addr);
118}
119
120static void mxr_vp_stream_set(struct mxr_layer *layer, int en)
121{
122 mxr_reg_vp_layer_stream(layer->mdev, en);
123}
124
125static void mxr_vp_format_set(struct mxr_layer *layer)
126{
127 mxr_reg_vp_format(layer->mdev, layer->fmt, &layer->geo);
128}
129
130static inline unsigned int do_center(unsigned int center,
131 unsigned int size, unsigned int upper, unsigned int flags)
132{
133 unsigned int lower;
134
135 if (flags & MXR_NO_OFFSET)
136 return 0;
137
138 lower = center - min(center, size / 2);
139 return min(lower, upper - size);
140}
141
142static void mxr_vp_fix_geometry(struct mxr_layer *layer,
143 enum mxr_geometry_stage stage, unsigned long flags)
144{
145 struct mxr_geometry *geo = &layer->geo;
146 struct mxr_crop *src = &geo->src;
147 struct mxr_crop *dst = &geo->dst;
148 unsigned long x_center, y_center;
149
150 switch (stage) {
151
152 case MXR_GEOMETRY_SINK: /* nothing to be fixed here */
153 case MXR_GEOMETRY_COMPOSE:
154 /* remember center of the area */
155 x_center = dst->x_offset + dst->width / 2;
156 y_center = dst->y_offset + dst->height / 2;
157
158 /* ensure that compose is reachable using 16x scaling */
159 dst->width = clamp(dst->width, 8U, 16 * src->full_width);
160 dst->height = clamp(dst->height, 1U, 16 * src->full_height);
161
162 /* setup offsets */
163 dst->x_offset = do_center(x_center, dst->width,
164 dst->full_width, flags);
165 dst->y_offset = do_center(y_center, dst->height,
166 dst->full_height, flags);
167 flags = 0; /* remove possible MXR_NO_OFFSET flag */
168 /* fall through */
169 case MXR_GEOMETRY_CROP:
170 /* remember center of the area */
171 x_center = src->x_offset + src->width / 2;
172 y_center = src->y_offset + src->height / 2;
173
174 /* ensure scaling is between 0.25x .. 16x */
175 src->width = clamp(src->width, round_up(dst->width / 16, 4),
176 dst->width * 4);
177 src->height = clamp(src->height, round_up(dst->height / 16, 4),
178 dst->height * 4);
179
180 /* hardware limits */
181 src->width = clamp(src->width, 32U, 2047U);
182 src->height = clamp(src->height, 4U, 2047U);
183
184 /* setup offsets */
185 src->x_offset = do_center(x_center, src->width,
186 src->full_width, flags);
187 src->y_offset = do_center(y_center, src->height,
188 src->full_height, flags);
189
190 /* setting scaling ratio */
191 geo->x_ratio = (src->width << 16) / dst->width;
192 geo->y_ratio = (src->height << 16) / dst->height;
193 /* fall through */
194
195 case MXR_GEOMETRY_SOURCE:
196 src->full_width = clamp(src->full_width,
197 ALIGN(src->width + src->x_offset, 8), 8192U);
198 src->full_height = clamp(src->full_height,
199 src->height + src->y_offset, 8192U);
200 };
201}
202
203/* PUBLIC API */
204
205struct mxr_layer *mxr_vp_layer_create(struct mxr_device *mdev, int idx)
206{
207 struct mxr_layer *layer;
208 int ret;
209 struct mxr_layer_ops ops = {
210 .release = mxr_vp_layer_release,
211 .buffer_set = mxr_vp_buffer_set,
212 .stream_set = mxr_vp_stream_set,
213 .format_set = mxr_vp_format_set,
214 .fix_geometry = mxr_vp_fix_geometry,
215 };
216 char name[32];
217
218 sprintf(name, "video%d", idx);
219
220 layer = mxr_base_layer_create(mdev, idx, name, &ops);
221 if (layer == NULL) {
222 mxr_err(mdev, "failed to initialize layer(%d) base\n", idx);
223 goto fail;
224 }
225
226 layer->fmt_array = mxr_video_format;
227 layer->fmt_array_size = ARRAY_SIZE(mxr_video_format);
228
229 ret = mxr_base_layer_register(layer);
230 if (ret)
231 goto fail_layer;
232
233 return layer;
234
235fail_layer:
236 mxr_base_layer_release(layer);
237
238fail:
239 return NULL;
240}
241
diff --git a/drivers/media/video/s5p-tv/regs-hdmi.h b/drivers/media/video/s5p-tv/regs-hdmi.h
deleted file mode 100644
index a889d1f57f28..000000000000
--- a/drivers/media/video/s5p-tv/regs-hdmi.h
+++ /dev/null
@@ -1,146 +0,0 @@
1/* linux/arch/arm/mach-exynos4/include/mach/regs-hdmi.h
2 *
3 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * HDMI register header file for Samsung TVOUT driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#ifndef SAMSUNG_REGS_HDMI_H
14#define SAMSUNG_REGS_HDMI_H
15
16/*
17 * Register part
18*/
19
20#define HDMI_CTRL_BASE(x) ((x) + 0x00000000)
21#define HDMI_CORE_BASE(x) ((x) + 0x00010000)
22#define HDMI_TG_BASE(x) ((x) + 0x00050000)
23
24/* Control registers */
25#define HDMI_INTC_CON HDMI_CTRL_BASE(0x0000)
26#define HDMI_INTC_FLAG HDMI_CTRL_BASE(0x0004)
27#define HDMI_HPD_STATUS HDMI_CTRL_BASE(0x000C)
28#define HDMI_PHY_RSTOUT HDMI_CTRL_BASE(0x0014)
29#define HDMI_PHY_VPLL HDMI_CTRL_BASE(0x0018)
30#define HDMI_PHY_CMU HDMI_CTRL_BASE(0x001C)
31#define HDMI_CORE_RSTOUT HDMI_CTRL_BASE(0x0020)
32
33/* Core registers */
34#define HDMI_CON_0 HDMI_CORE_BASE(0x0000)
35#define HDMI_CON_1 HDMI_CORE_BASE(0x0004)
36#define HDMI_CON_2 HDMI_CORE_BASE(0x0008)
37#define HDMI_SYS_STATUS HDMI_CORE_BASE(0x0010)
38#define HDMI_PHY_STATUS HDMI_CORE_BASE(0x0014)
39#define HDMI_STATUS_EN HDMI_CORE_BASE(0x0020)
40#define HDMI_HPD HDMI_CORE_BASE(0x0030)
41#define HDMI_MODE_SEL HDMI_CORE_BASE(0x0040)
42#define HDMI_BLUE_SCREEN_0 HDMI_CORE_BASE(0x0050)
43#define HDMI_BLUE_SCREEN_1 HDMI_CORE_BASE(0x0054)
44#define HDMI_BLUE_SCREEN_2 HDMI_CORE_BASE(0x0058)
45#define HDMI_H_BLANK_0 HDMI_CORE_BASE(0x00A0)
46#define HDMI_H_BLANK_1 HDMI_CORE_BASE(0x00A4)
47#define HDMI_V_BLANK_0 HDMI_CORE_BASE(0x00B0)
48#define HDMI_V_BLANK_1 HDMI_CORE_BASE(0x00B4)
49#define HDMI_V_BLANK_2 HDMI_CORE_BASE(0x00B8)
50#define HDMI_H_V_LINE_0 HDMI_CORE_BASE(0x00C0)
51#define HDMI_H_V_LINE_1 HDMI_CORE_BASE(0x00C4)
52#define HDMI_H_V_LINE_2 HDMI_CORE_BASE(0x00C8)
53#define HDMI_VSYNC_POL HDMI_CORE_BASE(0x00E4)
54#define HDMI_INT_PRO_MODE HDMI_CORE_BASE(0x00E8)
55#define HDMI_V_BLANK_F_0 HDMI_CORE_BASE(0x0110)
56#define HDMI_V_BLANK_F_1 HDMI_CORE_BASE(0x0114)
57#define HDMI_V_BLANK_F_2 HDMI_CORE_BASE(0x0118)
58#define HDMI_H_SYNC_GEN_0 HDMI_CORE_BASE(0x0120)
59#define HDMI_H_SYNC_GEN_1 HDMI_CORE_BASE(0x0124)
60#define HDMI_H_SYNC_GEN_2 HDMI_CORE_BASE(0x0128)
61#define HDMI_V_SYNC_GEN_1_0 HDMI_CORE_BASE(0x0130)
62#define HDMI_V_SYNC_GEN_1_1 HDMI_CORE_BASE(0x0134)
63#define HDMI_V_SYNC_GEN_1_2 HDMI_CORE_BASE(0x0138)
64#define HDMI_V_SYNC_GEN_2_0 HDMI_CORE_BASE(0x0140)
65#define HDMI_V_SYNC_GEN_2_1 HDMI_CORE_BASE(0x0144)
66#define HDMI_V_SYNC_GEN_2_2 HDMI_CORE_BASE(0x0148)
67#define HDMI_V_SYNC_GEN_3_0 HDMI_CORE_BASE(0x0150)
68#define HDMI_V_SYNC_GEN_3_1 HDMI_CORE_BASE(0x0154)
69#define HDMI_V_SYNC_GEN_3_2 HDMI_CORE_BASE(0x0158)
70#define HDMI_AVI_CON HDMI_CORE_BASE(0x0300)
71#define HDMI_AVI_BYTE(n) HDMI_CORE_BASE(0x0320 + 4 * (n))
72#define HDMI_DC_CONTROL HDMI_CORE_BASE(0x05C0)
73#define HDMI_VIDEO_PATTERN_GEN HDMI_CORE_BASE(0x05C4)
74#define HDMI_HPD_GEN HDMI_CORE_BASE(0x05C8)
75
76/* Timing generator registers */
77#define HDMI_TG_CMD HDMI_TG_BASE(0x0000)
78#define HDMI_TG_H_FSZ_L HDMI_TG_BASE(0x0018)
79#define HDMI_TG_H_FSZ_H HDMI_TG_BASE(0x001C)
80#define HDMI_TG_HACT_ST_L HDMI_TG_BASE(0x0020)
81#define HDMI_TG_HACT_ST_H HDMI_TG_BASE(0x0024)
82#define HDMI_TG_HACT_SZ_L HDMI_TG_BASE(0x0028)
83#define HDMI_TG_HACT_SZ_H HDMI_TG_BASE(0x002C)
84#define HDMI_TG_V_FSZ_L HDMI_TG_BASE(0x0030)
85#define HDMI_TG_V_FSZ_H HDMI_TG_BASE(0x0034)
86#define HDMI_TG_VSYNC_L HDMI_TG_BASE(0x0038)
87#define HDMI_TG_VSYNC_H HDMI_TG_BASE(0x003C)
88#define HDMI_TG_VSYNC2_L HDMI_TG_BASE(0x0040)
89#define HDMI_TG_VSYNC2_H HDMI_TG_BASE(0x0044)
90#define HDMI_TG_VACT_ST_L HDMI_TG_BASE(0x0048)
91#define HDMI_TG_VACT_ST_H HDMI_TG_BASE(0x004C)
92#define HDMI_TG_VACT_SZ_L HDMI_TG_BASE(0x0050)
93#define HDMI_TG_VACT_SZ_H HDMI_TG_BASE(0x0054)
94#define HDMI_TG_FIELD_CHG_L HDMI_TG_BASE(0x0058)
95#define HDMI_TG_FIELD_CHG_H HDMI_TG_BASE(0x005C)
96#define HDMI_TG_VACT_ST2_L HDMI_TG_BASE(0x0060)
97#define HDMI_TG_VACT_ST2_H HDMI_TG_BASE(0x0064)
98#define HDMI_TG_VSYNC_TOP_HDMI_L HDMI_TG_BASE(0x0078)
99#define HDMI_TG_VSYNC_TOP_HDMI_H HDMI_TG_BASE(0x007C)
100#define HDMI_TG_VSYNC_BOT_HDMI_L HDMI_TG_BASE(0x0080)
101#define HDMI_TG_VSYNC_BOT_HDMI_H HDMI_TG_BASE(0x0084)
102#define HDMI_TG_FIELD_TOP_HDMI_L HDMI_TG_BASE(0x0088)
103#define HDMI_TG_FIELD_TOP_HDMI_H HDMI_TG_BASE(0x008C)
104#define HDMI_TG_FIELD_BOT_HDMI_L HDMI_TG_BASE(0x0090)
105#define HDMI_TG_FIELD_BOT_HDMI_H HDMI_TG_BASE(0x0094)
106
107/*
108 * Bit definition part
109 */
110
111/* HDMI_INTC_CON */
112#define HDMI_INTC_EN_GLOBAL (1 << 6)
113#define HDMI_INTC_EN_HPD_PLUG (1 << 3)
114#define HDMI_INTC_EN_HPD_UNPLUG (1 << 2)
115
116/* HDMI_INTC_FLAG */
117#define HDMI_INTC_FLAG_HPD_PLUG (1 << 3)
118#define HDMI_INTC_FLAG_HPD_UNPLUG (1 << 2)
119
120/* HDMI_PHY_RSTOUT */
121#define HDMI_PHY_SW_RSTOUT (1 << 0)
122
123/* HDMI_CORE_RSTOUT */
124#define HDMI_CORE_SW_RSTOUT (1 << 0)
125
126/* HDMI_CON_0 */
127#define HDMI_BLUE_SCR_EN (1 << 5)
128#define HDMI_EN (1 << 0)
129
130/* HDMI_CON_2 */
131#define HDMI_DVI_PERAMBLE_EN (1 << 5)
132#define HDMI_DVI_BAND_EN (1 << 1)
133
134/* HDMI_PHY_STATUS */
135#define HDMI_PHY_STATUS_READY (1 << 0)
136
137/* HDMI_MODE_SEL */
138#define HDMI_MODE_HDMI_EN (1 << 1)
139#define HDMI_MODE_DVI_EN (1 << 0)
140#define HDMI_MODE_MASK (3 << 0)
141
142/* HDMI_TG_CMD */
143#define HDMI_TG_FIELD_EN (1 << 1)
144#define HDMI_TG_EN (1 << 0)
145
146#endif /* SAMSUNG_REGS_HDMI_H */
diff --git a/drivers/media/video/s5p-tv/regs-mixer.h b/drivers/media/video/s5p-tv/regs-mixer.h
deleted file mode 100644
index 158abb43d0a4..000000000000
--- a/drivers/media/video/s5p-tv/regs-mixer.h
+++ /dev/null
@@ -1,122 +0,0 @@
1/*
2 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
3 * http://www.samsung.com/
4 *
5 * Mixer register header file for Samsung Mixer driver
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10*/
11#ifndef SAMSUNG_REGS_MIXER_H
12#define SAMSUNG_REGS_MIXER_H
13
14/*
15 * Register part
16 */
17#define MXR_STATUS 0x0000
18#define MXR_CFG 0x0004
19#define MXR_INT_EN 0x0008
20#define MXR_INT_STATUS 0x000C
21#define MXR_LAYER_CFG 0x0010
22#define MXR_VIDEO_CFG 0x0014
23#define MXR_GRAPHIC0_CFG 0x0020
24#define MXR_GRAPHIC0_BASE 0x0024
25#define MXR_GRAPHIC0_SPAN 0x0028
26#define MXR_GRAPHIC0_SXY 0x002C
27#define MXR_GRAPHIC0_WH 0x0030
28#define MXR_GRAPHIC0_DXY 0x0034
29#define MXR_GRAPHIC0_BLANK 0x0038
30#define MXR_GRAPHIC1_CFG 0x0040
31#define MXR_GRAPHIC1_BASE 0x0044
32#define MXR_GRAPHIC1_SPAN 0x0048
33#define MXR_GRAPHIC1_SXY 0x004C
34#define MXR_GRAPHIC1_WH 0x0050
35#define MXR_GRAPHIC1_DXY 0x0054
36#define MXR_GRAPHIC1_BLANK 0x0058
37#define MXR_BG_CFG 0x0060
38#define MXR_BG_COLOR0 0x0064
39#define MXR_BG_COLOR1 0x0068
40#define MXR_BG_COLOR2 0x006C
41
42/* for parametrized access to layer registers */
43#define MXR_GRAPHIC_CFG(i) (0x0020 + (i) * 0x20)
44#define MXR_GRAPHIC_BASE(i) (0x0024 + (i) * 0x20)
45#define MXR_GRAPHIC_SPAN(i) (0x0028 + (i) * 0x20)
46#define MXR_GRAPHIC_SXY(i) (0x002C + (i) * 0x20)
47#define MXR_GRAPHIC_WH(i) (0x0030 + (i) * 0x20)
48#define MXR_GRAPHIC_DXY(i) (0x0034 + (i) * 0x20)
49
50/*
51 * Bit definition part
52 */
53
54/* generates mask for range of bits */
55#define MXR_MASK(high_bit, low_bit) \
56 (((2 << ((high_bit) - (low_bit))) - 1) << (low_bit))
57
58#define MXR_MASK_VAL(val, high_bit, low_bit) \
59 (((val) << (low_bit)) & MXR_MASK(high_bit, low_bit))
60
61/* bits for MXR_STATUS */
62#define MXR_STATUS_16_BURST (1 << 7)
63#define MXR_STATUS_BURST_MASK (1 << 7)
64#define MXR_STATUS_SYNC_ENABLE (1 << 2)
65#define MXR_STATUS_REG_RUN (1 << 0)
66
67/* bits for MXR_CFG */
68#define MXR_CFG_OUT_YUV444 (0 << 8)
69#define MXR_CFG_OUT_RGB888 (1 << 8)
70#define MXR_CFG_OUT_MASK (1 << 8)
71#define MXR_CFG_DST_SDO (0 << 7)
72#define MXR_CFG_DST_HDMI (1 << 7)
73#define MXR_CFG_DST_MASK (1 << 7)
74#define MXR_CFG_SCAN_HD_720 (0 << 6)
75#define MXR_CFG_SCAN_HD_1080 (1 << 6)
76#define MXR_CFG_GRP1_ENABLE (1 << 5)
77#define MXR_CFG_GRP0_ENABLE (1 << 4)
78#define MXR_CFG_VP_ENABLE (1 << 3)
79#define MXR_CFG_SCAN_INTERLACE (0 << 2)
80#define MXR_CFG_SCAN_PROGRASSIVE (1 << 2)
81#define MXR_CFG_SCAN_NTSC (0 << 1)
82#define MXR_CFG_SCAN_PAL (1 << 1)
83#define MXR_CFG_SCAN_SD (0 << 0)
84#define MXR_CFG_SCAN_HD (1 << 0)
85#define MXR_CFG_SCAN_MASK 0x47
86
87/* bits for MXR_GRAPHICn_CFG */
88#define MXR_GRP_CFG_COLOR_KEY_DISABLE (1 << 21)
89#define MXR_GRP_CFG_BLEND_PRE_MUL (1 << 20)
90#define MXR_GRP_CFG_FORMAT_VAL(x) MXR_MASK_VAL(x, 11, 8)
91#define MXR_GRP_CFG_FORMAT_MASK MXR_GRP_CFG_FORMAT_VAL(~0)
92#define MXR_GRP_CFG_ALPHA_VAL(x) MXR_MASK_VAL(x, 7, 0)
93
94/* bits for MXR_GRAPHICn_WH */
95#define MXR_GRP_WH_H_SCALE(x) MXR_MASK_VAL(x, 28, 28)
96#define MXR_GRP_WH_V_SCALE(x) MXR_MASK_VAL(x, 12, 12)
97#define MXR_GRP_WH_WIDTH(x) MXR_MASK_VAL(x, 26, 16)
98#define MXR_GRP_WH_HEIGHT(x) MXR_MASK_VAL(x, 10, 0)
99
100/* bits for MXR_GRAPHICn_SXY */
101#define MXR_GRP_SXY_SX(x) MXR_MASK_VAL(x, 26, 16)
102#define MXR_GRP_SXY_SY(x) MXR_MASK_VAL(x, 10, 0)
103
104/* bits for MXR_GRAPHICn_DXY */
105#define MXR_GRP_DXY_DX(x) MXR_MASK_VAL(x, 26, 16)
106#define MXR_GRP_DXY_DY(x) MXR_MASK_VAL(x, 10, 0)
107
108/* bits for MXR_INT_EN */
109#define MXR_INT_EN_VSYNC (1 << 11)
110#define MXR_INT_EN_ALL (0x0f << 8)
111
112/* bit for MXR_INT_STATUS */
113#define MXR_INT_CLEAR_VSYNC (1 << 11)
114#define MXR_INT_STATUS_VSYNC (1 << 0)
115
116/* bit for MXR_LAYER_CFG */
117#define MXR_LAYER_CFG_GRP1_VAL(x) MXR_MASK_VAL(x, 11, 8)
118#define MXR_LAYER_CFG_GRP0_VAL(x) MXR_MASK_VAL(x, 7, 4)
119#define MXR_LAYER_CFG_VP_VAL(x) MXR_MASK_VAL(x, 3, 0)
120
121#endif /* SAMSUNG_REGS_MIXER_H */
122
diff --git a/drivers/media/video/s5p-tv/regs-sdo.h b/drivers/media/video/s5p-tv/regs-sdo.h
deleted file mode 100644
index 7f7c2b8ac140..000000000000
--- a/drivers/media/video/s5p-tv/regs-sdo.h
+++ /dev/null
@@ -1,63 +0,0 @@
1/* drivers/media/video/s5p-tv/regs-sdo.h
2 *
3 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * SDO register description file
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef SAMSUNG_REGS_SDO_H
14#define SAMSUNG_REGS_SDO_H
15
16/*
17 * Register part
18 */
19
20#define SDO_CLKCON 0x0000
21#define SDO_CONFIG 0x0008
22#define SDO_VBI 0x0014
23#define SDO_DAC 0x003C
24#define SDO_CCCON 0x0180
25#define SDO_IRQ 0x0280
26#define SDO_IRQMASK 0x0284
27#define SDO_VERSION 0x03D8
28
29/*
30 * Bit definition part
31 */
32
33/* SDO Clock Control Register (SDO_CLKCON) */
34#define SDO_TVOUT_SW_RESET (1 << 4)
35#define SDO_TVOUT_CLOCK_READY (1 << 1)
36#define SDO_TVOUT_CLOCK_ON (1 << 0)
37
38/* SDO Video Standard Configuration Register (SDO_CONFIG) */
39#define SDO_PROGRESSIVE (1 << 4)
40#define SDO_NTSC_M 0
41#define SDO_PAL_M 1
42#define SDO_PAL_BGHID 2
43#define SDO_PAL_N 3
44#define SDO_PAL_NC 4
45#define SDO_NTSC_443 8
46#define SDO_PAL_60 9
47#define SDO_STANDARD_MASK 0xf
48
49/* SDO VBI Configuration Register (SDO_VBI) */
50#define SDO_CVBS_WSS_INS (1 << 14)
51#define SDO_CVBS_CLOSED_CAPTION_MASK (3 << 12)
52
53/* SDO DAC Configuration Register (SDO_DAC) */
54#define SDO_POWER_ON_DAC (1 << 0)
55
56/* SDO Color Compensation On/Off Control (SDO_CCCON) */
57#define SDO_COMPENSATION_BHS_ADJ_OFF (1 << 4)
58#define SDO_COMPENSATION_CVBS_COMP_OFF (1 << 0)
59
60/* SDO Interrupt Request Register (SDO_IRQ) */
61#define SDO_VSYNC_IRQ_PEND (1 << 0)
62
63#endif /* SAMSUNG_REGS_SDO_H */
diff --git a/drivers/media/video/s5p-tv/regs-vp.h b/drivers/media/video/s5p-tv/regs-vp.h
deleted file mode 100644
index 6c63984e11e8..000000000000
--- a/drivers/media/video/s5p-tv/regs-vp.h
+++ /dev/null
@@ -1,88 +0,0 @@
1/*
2 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
3 * http://www.samsung.com/
4 *
5 * Video processor register header file for Samsung Mixer driver
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef SAMSUNG_REGS_VP_H
13#define SAMSUNG_REGS_VP_H
14
15/*
16 * Register part
17 */
18
19#define VP_ENABLE 0x0000
20#define VP_SRESET 0x0004
21#define VP_SHADOW_UPDATE 0x0008
22#define VP_FIELD_ID 0x000C
23#define VP_MODE 0x0010
24#define VP_IMG_SIZE_Y 0x0014
25#define VP_IMG_SIZE_C 0x0018
26#define VP_PER_RATE_CTRL 0x001C
27#define VP_TOP_Y_PTR 0x0028
28#define VP_BOT_Y_PTR 0x002C
29#define VP_TOP_C_PTR 0x0030
30#define VP_BOT_C_PTR 0x0034
31#define VP_ENDIAN_MODE 0x03CC
32#define VP_SRC_H_POSITION 0x0044
33#define VP_SRC_V_POSITION 0x0048
34#define VP_SRC_WIDTH 0x004C
35#define VP_SRC_HEIGHT 0x0050
36#define VP_DST_H_POSITION 0x0054
37#define VP_DST_V_POSITION 0x0058
38#define VP_DST_WIDTH 0x005C
39#define VP_DST_HEIGHT 0x0060
40#define VP_H_RATIO 0x0064
41#define VP_V_RATIO 0x0068
42#define VP_POLY8_Y0_LL 0x006C
43#define VP_POLY4_Y0_LL 0x00EC
44#define VP_POLY4_C0_LL 0x012C
45
46/*
47 * Bit definition part
48 */
49
50/* generates mask for range of bits */
51
52#define VP_MASK(high_bit, low_bit) \
53 (((2 << ((high_bit) - (low_bit))) - 1) << (low_bit))
54
55#define VP_MASK_VAL(val, high_bit, low_bit) \
56 (((val) << (low_bit)) & VP_MASK(high_bit, low_bit))
57
58 /* VP_ENABLE */
59#define VP_ENABLE_ON (1 << 0)
60
61/* VP_SRESET */
62#define VP_SRESET_PROCESSING (1 << 0)
63
64/* VP_SHADOW_UPDATE */
65#define VP_SHADOW_UPDATE_ENABLE (1 << 0)
66
67/* VP_MODE */
68#define VP_MODE_NV12 (0 << 6)
69#define VP_MODE_NV21 (1 << 6)
70#define VP_MODE_LINE_SKIP (1 << 5)
71#define VP_MODE_MEM_LINEAR (0 << 4)
72#define VP_MODE_MEM_TILED (1 << 4)
73#define VP_MODE_FMT_MASK (5 << 4)
74#define VP_MODE_FIELD_ID_AUTO_TOGGLING (1 << 2)
75#define VP_MODE_2D_IPC (1 << 1)
76
77/* VP_IMG_SIZE_Y */
78/* VP_IMG_SIZE_C */
79#define VP_IMG_HSIZE(x) VP_MASK_VAL(x, 29, 16)
80#define VP_IMG_VSIZE(x) VP_MASK_VAL(x, 13, 0)
81
82/* VP_SRC_H_POSITION */
83#define VP_SRC_H_POSITION_VAL(x) VP_MASK_VAL(x, 14, 4)
84
85/* VP_ENDIAN_MODE */
86#define VP_ENDIAN_MODE_LITTLE (1 << 0)
87
88#endif /* SAMSUNG_REGS_VP_H */
diff --git a/drivers/media/video/s5p-tv/sdo_drv.c b/drivers/media/video/s5p-tv/sdo_drv.c
deleted file mode 100644
index f6bca2c20e89..000000000000
--- a/drivers/media/video/s5p-tv/sdo_drv.c
+++ /dev/null
@@ -1,452 +0,0 @@
1/*
2 * Samsung Standard Definition Output (SDO) driver
3 *
4 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
5 *
6 * Tomasz Stanislawski, <t.stanislaws@samsung.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published
10 * by the Free Software Foundiation. either version 2 of the License,
11 * or (at your option) any later version
12 */
13
14#include <linux/clk.h>
15#include <linux/delay.h>
16#include <linux/kernel.h>
17#include <linux/module.h>
18#include <linux/interrupt.h>
19#include <linux/io.h>
20#include <linux/irq.h>
21#include <linux/platform_device.h>
22#include <linux/pm_runtime.h>
23#include <linux/regulator/consumer.h>
24#include <linux/slab.h>
25
26#include <media/v4l2-subdev.h>
27
28#include "regs-sdo.h"
29
30MODULE_AUTHOR("Tomasz Stanislawski, <t.stanislaws@samsung.com>");
31MODULE_DESCRIPTION("Samsung Standard Definition Output (SDO)");
32MODULE_LICENSE("GPL");
33
34#define SDO_DEFAULT_STD V4L2_STD_PAL
35
36struct sdo_format {
37 v4l2_std_id id;
38 /* all modes are 720 pixels wide */
39 unsigned int height;
40 unsigned int cookie;
41};
42
43struct sdo_device {
44 /** pointer to device parent */
45 struct device *dev;
46 /** base address of SDO registers */
47 void __iomem *regs;
48 /** SDO interrupt */
49 unsigned int irq;
50 /** DAC source clock */
51 struct clk *sclk_dac;
52 /** DAC clock */
53 struct clk *dac;
54 /** DAC physical interface */
55 struct clk *dacphy;
56 /** clock for control of VPLL */
57 struct clk *fout_vpll;
58 /** regulator for SDO IP power */
59 struct regulator *vdac;
60 /** regulator for SDO plug detection */
61 struct regulator *vdet;
62 /** subdev used as device interface */
63 struct v4l2_subdev sd;
64 /** current format */
65 const struct sdo_format *fmt;
66};
67
68static inline struct sdo_device *sd_to_sdev(struct v4l2_subdev *sd)
69{
70 return container_of(sd, struct sdo_device, sd);
71}
72
73static inline
74void sdo_write_mask(struct sdo_device *sdev, u32 reg_id, u32 value, u32 mask)
75{
76 u32 old = readl(sdev->regs + reg_id);
77 value = (value & mask) | (old & ~mask);
78 writel(value, sdev->regs + reg_id);
79}
80
81static inline
82void sdo_write(struct sdo_device *sdev, u32 reg_id, u32 value)
83{
84 writel(value, sdev->regs + reg_id);
85}
86
87static inline
88u32 sdo_read(struct sdo_device *sdev, u32 reg_id)
89{
90 return readl(sdev->regs + reg_id);
91}
92
93static irqreturn_t sdo_irq_handler(int irq, void *dev_data)
94{
95 struct sdo_device *sdev = dev_data;
96
97 /* clear interrupt */
98 sdo_write_mask(sdev, SDO_IRQ, ~0, SDO_VSYNC_IRQ_PEND);
99 return IRQ_HANDLED;
100}
101
102static void sdo_reg_debug(struct sdo_device *sdev)
103{
104#define DBGREG(reg_id) \
105 dev_info(sdev->dev, #reg_id " = %08x\n", \
106 sdo_read(sdev, reg_id))
107
108 DBGREG(SDO_CLKCON);
109 DBGREG(SDO_CONFIG);
110 DBGREG(SDO_VBI);
111 DBGREG(SDO_DAC);
112 DBGREG(SDO_IRQ);
113 DBGREG(SDO_IRQMASK);
114 DBGREG(SDO_VERSION);
115}
116
117static const struct sdo_format sdo_format[] = {
118 { V4L2_STD_PAL_N, .height = 576, .cookie = SDO_PAL_N },
119 { V4L2_STD_PAL_Nc, .height = 576, .cookie = SDO_PAL_NC },
120 { V4L2_STD_PAL_M, .height = 480, .cookie = SDO_PAL_M },
121 { V4L2_STD_PAL_60, .height = 480, .cookie = SDO_PAL_60 },
122 { V4L2_STD_NTSC_443, .height = 480, .cookie = SDO_NTSC_443 },
123 { V4L2_STD_PAL, .height = 576, .cookie = SDO_PAL_BGHID },
124 { V4L2_STD_NTSC_M, .height = 480, .cookie = SDO_NTSC_M },
125};
126
127static const struct sdo_format *sdo_find_format(v4l2_std_id id)
128{
129 int i;
130 for (i = 0; i < ARRAY_SIZE(sdo_format); ++i)
131 if (sdo_format[i].id & id)
132 return &sdo_format[i];
133 return NULL;
134}
135
136static int sdo_g_tvnorms_output(struct v4l2_subdev *sd, v4l2_std_id *std)
137{
138 *std = V4L2_STD_NTSC_M | V4L2_STD_PAL_M | V4L2_STD_PAL |
139 V4L2_STD_PAL_N | V4L2_STD_PAL_Nc |
140 V4L2_STD_NTSC_443 | V4L2_STD_PAL_60;
141 return 0;
142}
143
144static int sdo_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std)
145{
146 struct sdo_device *sdev = sd_to_sdev(sd);
147 const struct sdo_format *fmt;
148 fmt = sdo_find_format(std);
149 if (fmt == NULL)
150 return -EINVAL;
151 sdev->fmt = fmt;
152 return 0;
153}
154
155static int sdo_g_std_output(struct v4l2_subdev *sd, v4l2_std_id *std)
156{
157 *std = sd_to_sdev(sd)->fmt->id;
158 return 0;
159}
160
161static int sdo_g_mbus_fmt(struct v4l2_subdev *sd,
162 struct v4l2_mbus_framefmt *fmt)
163{
164 struct sdo_device *sdev = sd_to_sdev(sd);
165
166 if (!sdev->fmt)
167 return -ENXIO;
168 /* all modes are 720 pixels wide */
169 fmt->width = 720;
170 fmt->height = sdev->fmt->height;
171 fmt->code = V4L2_MBUS_FMT_FIXED;
172 fmt->field = V4L2_FIELD_INTERLACED;
173 fmt->colorspace = V4L2_COLORSPACE_JPEG;
174 return 0;
175}
176
177static int sdo_s_power(struct v4l2_subdev *sd, int on)
178{
179 struct sdo_device *sdev = sd_to_sdev(sd);
180 struct device *dev = sdev->dev;
181 int ret;
182
183 dev_info(dev, "sdo_s_power(%d)\n", on);
184
185 if (on)
186 ret = pm_runtime_get_sync(dev);
187 else
188 ret = pm_runtime_put_sync(dev);
189
190 /* only values < 0 indicate errors */
191 return IS_ERR_VALUE(ret) ? ret : 0;
192}
193
194static int sdo_streamon(struct sdo_device *sdev)
195{
196 /* set proper clock for Timing Generator */
197 clk_set_rate(sdev->fout_vpll, 54000000);
198 dev_info(sdev->dev, "fout_vpll.rate = %lu\n",
199 clk_get_rate(sdev->fout_vpll));
200 /* enable clock in SDO */
201 sdo_write_mask(sdev, SDO_CLKCON, ~0, SDO_TVOUT_CLOCK_ON);
202 clk_enable(sdev->dacphy);
203 /* enable DAC */
204 sdo_write_mask(sdev, SDO_DAC, ~0, SDO_POWER_ON_DAC);
205 sdo_reg_debug(sdev);
206 return 0;
207}
208
209static int sdo_streamoff(struct sdo_device *sdev)
210{
211 int tries;
212
213 sdo_write_mask(sdev, SDO_DAC, 0, SDO_POWER_ON_DAC);
214 clk_disable(sdev->dacphy);
215 sdo_write_mask(sdev, SDO_CLKCON, 0, SDO_TVOUT_CLOCK_ON);
216 for (tries = 100; tries; --tries) {
217 if (sdo_read(sdev, SDO_CLKCON) & SDO_TVOUT_CLOCK_READY)
218 break;
219 mdelay(1);
220 }
221 if (tries == 0)
222 dev_err(sdev->dev, "failed to stop streaming\n");
223 return tries ? 0 : -EIO;
224}
225
226static int sdo_s_stream(struct v4l2_subdev *sd, int on)
227{
228 struct sdo_device *sdev = sd_to_sdev(sd);
229 return on ? sdo_streamon(sdev) : sdo_streamoff(sdev);
230}
231
232static const struct v4l2_subdev_core_ops sdo_sd_core_ops = {
233 .s_power = sdo_s_power,
234};
235
236static const struct v4l2_subdev_video_ops sdo_sd_video_ops = {
237 .s_std_output = sdo_s_std_output,
238 .g_std_output = sdo_g_std_output,
239 .g_tvnorms_output = sdo_g_tvnorms_output,
240 .g_mbus_fmt = sdo_g_mbus_fmt,
241 .s_stream = sdo_s_stream,
242};
243
244static const struct v4l2_subdev_ops sdo_sd_ops = {
245 .core = &sdo_sd_core_ops,
246 .video = &sdo_sd_video_ops,
247};
248
249static int sdo_runtime_suspend(struct device *dev)
250{
251 struct v4l2_subdev *sd = dev_get_drvdata(dev);
252 struct sdo_device *sdev = sd_to_sdev(sd);
253
254 dev_info(dev, "suspend\n");
255 regulator_disable(sdev->vdet);
256 regulator_disable(sdev->vdac);
257 clk_disable(sdev->sclk_dac);
258 return 0;
259}
260
261static int sdo_runtime_resume(struct device *dev)
262{
263 struct v4l2_subdev *sd = dev_get_drvdata(dev);
264 struct sdo_device *sdev = sd_to_sdev(sd);
265
266 dev_info(dev, "resume\n");
267 clk_enable(sdev->sclk_dac);
268 regulator_enable(sdev->vdac);
269 regulator_enable(sdev->vdet);
270
271 /* software reset */
272 sdo_write_mask(sdev, SDO_CLKCON, ~0, SDO_TVOUT_SW_RESET);
273 mdelay(10);
274 sdo_write_mask(sdev, SDO_CLKCON, 0, SDO_TVOUT_SW_RESET);
275
276 /* setting TV mode */
277 sdo_write_mask(sdev, SDO_CONFIG, sdev->fmt->cookie, SDO_STANDARD_MASK);
278 /* XXX: forcing interlaced mode using undocumented bit */
279 sdo_write_mask(sdev, SDO_CONFIG, 0, SDO_PROGRESSIVE);
280 /* turn all VBI off */
281 sdo_write_mask(sdev, SDO_VBI, 0, SDO_CVBS_WSS_INS |
282 SDO_CVBS_CLOSED_CAPTION_MASK);
283 /* turn all post processing off */
284 sdo_write_mask(sdev, SDO_CCCON, ~0, SDO_COMPENSATION_BHS_ADJ_OFF |
285 SDO_COMPENSATION_CVBS_COMP_OFF);
286 sdo_reg_debug(sdev);
287 return 0;
288}
289
290static const struct dev_pm_ops sdo_pm_ops = {
291 .runtime_suspend = sdo_runtime_suspend,
292 .runtime_resume = sdo_runtime_resume,
293};
294
295static int __devinit sdo_probe(struct platform_device *pdev)
296{
297 struct device *dev = &pdev->dev;
298 struct sdo_device *sdev;
299 struct resource *res;
300 int ret = 0;
301 struct clk *sclk_vpll;
302
303 dev_info(dev, "probe start\n");
304 sdev = devm_kzalloc(&pdev->dev, sizeof *sdev, GFP_KERNEL);
305 if (!sdev) {
306 dev_err(dev, "not enough memory.\n");
307 ret = -ENOMEM;
308 goto fail;
309 }
310 sdev->dev = dev;
311
312 /* mapping registers */
313 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
314 if (res == NULL) {
315 dev_err(dev, "get memory resource failed.\n");
316 ret = -ENXIO;
317 goto fail;
318 }
319
320 sdev->regs = devm_ioremap(&pdev->dev, res->start, resource_size(res));
321 if (sdev->regs == NULL) {
322 dev_err(dev, "register mapping failed.\n");
323 ret = -ENXIO;
324 goto fail;
325 }
326
327 /* acquiring interrupt */
328 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
329 if (res == NULL) {
330 dev_err(dev, "get interrupt resource failed.\n");
331 ret = -ENXIO;
332 goto fail;
333 }
334 ret = devm_request_irq(&pdev->dev, res->start, sdo_irq_handler, 0,
335 "s5p-sdo", sdev);
336 if (ret) {
337 dev_err(dev, "request interrupt failed.\n");
338 goto fail;
339 }
340 sdev->irq = res->start;
341
342 /* acquire clocks */
343 sdev->sclk_dac = clk_get(dev, "sclk_dac");
344 if (IS_ERR_OR_NULL(sdev->sclk_dac)) {
345 dev_err(dev, "failed to get clock 'sclk_dac'\n");
346 ret = -ENXIO;
347 goto fail;
348 }
349 sdev->dac = clk_get(dev, "dac");
350 if (IS_ERR_OR_NULL(sdev->dac)) {
351 dev_err(dev, "failed to get clock 'dac'\n");
352 ret = -ENXIO;
353 goto fail_sclk_dac;
354 }
355 sdev->dacphy = clk_get(dev, "dacphy");
356 if (IS_ERR_OR_NULL(sdev->dacphy)) {
357 dev_err(dev, "failed to get clock 'dacphy'\n");
358 ret = -ENXIO;
359 goto fail_dac;
360 }
361 sclk_vpll = clk_get(dev, "sclk_vpll");
362 if (IS_ERR_OR_NULL(sclk_vpll)) {
363 dev_err(dev, "failed to get clock 'sclk_vpll'\n");
364 ret = -ENXIO;
365 goto fail_dacphy;
366 }
367 clk_set_parent(sdev->sclk_dac, sclk_vpll);
368 clk_put(sclk_vpll);
369 sdev->fout_vpll = clk_get(dev, "fout_vpll");
370 if (IS_ERR_OR_NULL(sdev->fout_vpll)) {
371 dev_err(dev, "failed to get clock 'fout_vpll'\n");
372 goto fail_dacphy;
373 }
374 dev_info(dev, "fout_vpll.rate = %lu\n", clk_get_rate(sclk_vpll));
375
376 /* acquire regulator */
377 sdev->vdac = regulator_get(dev, "vdd33a_dac");
378 if (IS_ERR_OR_NULL(sdev->vdac)) {
379 dev_err(dev, "failed to get regulator 'vdac'\n");
380 goto fail_fout_vpll;
381 }
382 sdev->vdet = regulator_get(dev, "vdet");
383 if (IS_ERR_OR_NULL(sdev->vdet)) {
384 dev_err(dev, "failed to get regulator 'vdet'\n");
385 goto fail_vdac;
386 }
387
388 /* enable gate for dac clock, because mixer uses it */
389 clk_enable(sdev->dac);
390
391 /* configure power management */
392 pm_runtime_enable(dev);
393
394 /* configuration of interface subdevice */
395 v4l2_subdev_init(&sdev->sd, &sdo_sd_ops);
396 sdev->sd.owner = THIS_MODULE;
397 strlcpy(sdev->sd.name, "s5p-sdo", sizeof sdev->sd.name);
398
399 /* set default format */
400 sdev->fmt = sdo_find_format(SDO_DEFAULT_STD);
401 BUG_ON(sdev->fmt == NULL);
402
403 /* keeping subdev in device's private for use by other drivers */
404 dev_set_drvdata(dev, &sdev->sd);
405
406 dev_info(dev, "probe succeeded\n");
407 return 0;
408
409fail_vdac:
410 regulator_put(sdev->vdac);
411fail_fout_vpll:
412 clk_put(sdev->fout_vpll);
413fail_dacphy:
414 clk_put(sdev->dacphy);
415fail_dac:
416 clk_put(sdev->dac);
417fail_sclk_dac:
418 clk_put(sdev->sclk_dac);
419fail:
420 dev_info(dev, "probe failed\n");
421 return ret;
422}
423
424static int __devexit sdo_remove(struct platform_device *pdev)
425{
426 struct v4l2_subdev *sd = dev_get_drvdata(&pdev->dev);
427 struct sdo_device *sdev = sd_to_sdev(sd);
428
429 pm_runtime_disable(&pdev->dev);
430 clk_disable(sdev->dac);
431 regulator_put(sdev->vdet);
432 regulator_put(sdev->vdac);
433 clk_put(sdev->fout_vpll);
434 clk_put(sdev->dacphy);
435 clk_put(sdev->dac);
436 clk_put(sdev->sclk_dac);
437
438 dev_info(&pdev->dev, "remove successful\n");
439 return 0;
440}
441
442static struct platform_driver sdo_driver __refdata = {
443 .probe = sdo_probe,
444 .remove = __devexit_p(sdo_remove),
445 .driver = {
446 .name = "s5p-sdo",
447 .owner = THIS_MODULE,
448 .pm = &sdo_pm_ops,
449 }
450};
451
452module_platform_driver(sdo_driver);
diff --git a/drivers/media/video/s5p-tv/sii9234_drv.c b/drivers/media/video/s5p-tv/sii9234_drv.c
deleted file mode 100644
index 6d348f90237a..000000000000
--- a/drivers/media/video/s5p-tv/sii9234_drv.c
+++ /dev/null
@@ -1,422 +0,0 @@
1/*
2 * Samsung MHL interface driver
3 *
4 * Copyright (C) 2011 Samsung Electronics Co.Ltd
5 * Author: Tomasz Stanislawski <t.stanislaws@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#include <linux/delay.h>
14#include <linux/err.h>
15#include <linux/freezer.h>
16#include <linux/gpio.h>
17#include <linux/i2c.h>
18#include <linux/interrupt.h>
19#include <linux/irq.h>
20#include <linux/kthread.h>
21#include <linux/module.h>
22#include <linux/pm_runtime.h>
23#include <linux/regulator/machine.h>
24#include <linux/slab.h>
25
26#include <mach/gpio.h>
27#include <plat/gpio-cfg.h>
28
29#include <media/sii9234.h>
30#include <media/v4l2-subdev.h>
31
32MODULE_AUTHOR("Tomasz Stanislawski <t.stanislaws@samsung.com>");
33MODULE_DESCRIPTION("Samsung MHL interface driver");
34MODULE_LICENSE("GPL");
35
36struct sii9234_context {
37 struct i2c_client *client;
38 struct regulator *power;
39 int gpio_n_reset;
40 struct v4l2_subdev sd;
41};
42
43static inline struct sii9234_context *sd_to_context(struct v4l2_subdev *sd)
44{
45 return container_of(sd, struct sii9234_context, sd);
46}
47
48static inline int sii9234_readb(struct i2c_client *client, int addr)
49{
50 return i2c_smbus_read_byte_data(client, addr);
51}
52
53static inline int sii9234_writeb(struct i2c_client *client, int addr, int value)
54{
55 return i2c_smbus_write_byte_data(client, addr, value);
56}
57
58static inline int sii9234_writeb_mask(struct i2c_client *client, int addr,
59 int value, int mask)
60{
61 int ret;
62
63 ret = i2c_smbus_read_byte_data(client, addr);
64 if (ret < 0)
65 return ret;
66 ret = (ret & ~mask) | (value & mask);
67 return i2c_smbus_write_byte_data(client, addr, ret);
68}
69
70static inline int sii9234_readb_idx(struct i2c_client *client, int addr)
71{
72 int ret;
73 ret = i2c_smbus_write_byte_data(client, 0xbc, addr >> 8);
74 if (ret < 0)
75 return ret;
76 ret = i2c_smbus_write_byte_data(client, 0xbd, addr & 0xff);
77 if (ret < 0)
78 return ret;
79 return i2c_smbus_read_byte_data(client, 0xbe);
80}
81
82static inline int sii9234_writeb_idx(struct i2c_client *client, int addr,
83 int value)
84{
85 int ret;
86 ret = i2c_smbus_write_byte_data(client, 0xbc, addr >> 8);
87 if (ret < 0)
88 return ret;
89 ret = i2c_smbus_write_byte_data(client, 0xbd, addr & 0xff);
90 if (ret < 0)
91 return ret;
92 ret = i2c_smbus_write_byte_data(client, 0xbe, value);
93 return ret;
94}
95
96static inline int sii9234_writeb_idx_mask(struct i2c_client *client, int addr,
97 int value, int mask)
98{
99 int ret;
100
101 ret = sii9234_readb_idx(client, addr);
102 if (ret < 0)
103 return ret;
104 ret = (ret & ~mask) | (value & mask);
105 return sii9234_writeb_idx(client, addr, ret);
106}
107
108static int sii9234_reset(struct sii9234_context *ctx)
109{
110 struct i2c_client *client = ctx->client;
111 struct device *dev = &client->dev;
112 int ret, tries;
113
114 gpio_direction_output(ctx->gpio_n_reset, 1);
115 mdelay(1);
116 gpio_direction_output(ctx->gpio_n_reset, 0);
117 mdelay(1);
118 gpio_direction_output(ctx->gpio_n_reset, 1);
119 mdelay(1);
120
121 /* going to TTPI mode */
122 ret = sii9234_writeb(client, 0xc7, 0);
123 if (ret < 0) {
124 dev_err(dev, "failed to set TTPI mode\n");
125 return ret;
126 }
127 for (tries = 0; tries < 100 ; ++tries) {
128 ret = sii9234_readb(client, 0x1b);
129 if (ret > 0)
130 break;
131 if (ret < 0) {
132 dev_err(dev, "failed to reset device\n");
133 return -EIO;
134 }
135 mdelay(1);
136 }
137 if (tries == 100) {
138 dev_err(dev, "maximal number of tries reached\n");
139 return -EIO;
140 }
141
142 return 0;
143}
144
145static int sii9234_verify_version(struct i2c_client *client)
146{
147 struct device *dev = &client->dev;
148 int family, rev, tpi_rev, dev_id, sub_id, hdcp, id;
149
150 family = sii9234_readb(client, 0x1b);
151 rev = sii9234_readb(client, 0x1c) & 0x0f;
152 tpi_rev = sii9234_readb(client, 0x1d) & 0x7f;
153 dev_id = sii9234_readb_idx(client, 0x0103);
154 sub_id = sii9234_readb_idx(client, 0x0102);
155 hdcp = sii9234_readb(client, 0x30);
156
157 if (family < 0 || rev < 0 || tpi_rev < 0 || dev_id < 0 ||
158 sub_id < 0 || hdcp < 0) {
159 dev_err(dev, "failed to read chip's version\n");
160 return -EIO;
161 }
162
163 id = (dev_id << 8) | sub_id;
164
165 dev_info(dev, "chip: SiL%02x family: %02x, rev: %02x\n",
166 id, family, rev);
167 dev_info(dev, "tpi_rev:%02x, hdcp: %02x\n", tpi_rev, hdcp);
168 if (id != 0x9234) {
169 dev_err(dev, "not supported chip\n");
170 return -ENODEV;
171 }
172
173 return 0;
174}
175
176static u8 data[][3] = {
177/* setup from driver created by doonsoo45.kim */
178 { 0x01, 0x05, 0x04 }, /* Enable Auto soft reset on SCDT = 0 */
179 { 0x01, 0x08, 0x35 }, /* Power Up TMDS Tx Core */
180 { 0x01, 0x0d, 0x1c }, /* HDMI Transcode mode enable */
181 { 0x01, 0x2b, 0x01 }, /* Enable HDCP Compliance workaround */
182 { 0x01, 0x79, 0x40 }, /* daniel test...MHL_INT */
183 { 0x01, 0x80, 0x34 }, /* Enable Rx PLL Clock Value */
184 { 0x01, 0x90, 0x27 }, /* Enable CBUS discovery */
185 { 0x01, 0x91, 0xe5 }, /* Skip RGND detection */
186 { 0x01, 0x92, 0x46 }, /* Force MHD mode */
187 { 0x01, 0x93, 0xdc }, /* Disable CBUS pull-up during RGND measurement */
188 { 0x01, 0x94, 0x66 }, /* 1.8V CBUS VTH & GND threshold */
189 { 0x01, 0x95, 0x31 }, /* RGND block & single discovery attempt */
190 { 0x01, 0x96, 0x22 }, /* use 1K and 2K setting */
191 { 0x01, 0xa0, 0x10 }, /* SIMG: Term mode */
192 { 0x01, 0xa1, 0xfc }, /* Disable internal Mobile HD driver */
193 { 0x01, 0xa3, 0xfa }, /* SIMG: Output Swing default EB, 3x Clk Mult */
194 { 0x01, 0xa5, 0x80 }, /* SIMG: RGND Hysterisis, 3x mode for Beast */
195 { 0x01, 0xa6, 0x0c }, /* SIMG: Swing Offset */
196 { 0x02, 0x3d, 0x3f }, /* Power up CVCC 1.2V core */
197 { 0x03, 0x00, 0x00 }, /* SIMG: correcting HW default */
198 { 0x03, 0x11, 0x01 }, /* Enable TxPLL Clock */
199 { 0x03, 0x12, 0x15 }, /* Enable Tx Clock Path & Equalizer */
200 { 0x03, 0x13, 0x60 }, /* SIMG: Set termination value */
201 { 0x03, 0x14, 0xf0 }, /* SIMG: Change CKDT level */
202 { 0x03, 0x17, 0x07 }, /* SIMG: PLL Calrefsel */
203 { 0x03, 0x1a, 0x20 }, /* VCO Cal */
204 { 0x03, 0x22, 0xe0 }, /* SIMG: Auto EQ */
205 { 0x03, 0x23, 0xc0 }, /* SIMG: Auto EQ */
206 { 0x03, 0x24, 0xa0 }, /* SIMG: Auto EQ */
207 { 0x03, 0x25, 0x80 }, /* SIMG: Auto EQ */
208 { 0x03, 0x26, 0x60 }, /* SIMG: Auto EQ */
209 { 0x03, 0x27, 0x40 }, /* SIMG: Auto EQ */
210 { 0x03, 0x28, 0x20 }, /* SIMG: Auto EQ */
211 { 0x03, 0x29, 0x00 }, /* SIMG: Auto EQ */
212 { 0x03, 0x31, 0x0b }, /* SIMG: Rx PLL BW value from I2C BW ~ 4MHz */
213 { 0x03, 0x45, 0x06 }, /* SIMG: DPLL Mode */
214 { 0x03, 0x4b, 0x06 }, /* SIMG: Correcting HW default */
215 { 0x03, 0x4c, 0xa0 }, /* Manual zone control */
216 { 0x03, 0x4d, 0x02 }, /* SIMG: PLL Mode Value (order is important) */
217};
218
219static int sii9234_set_internal(struct sii9234_context *ctx)
220{
221 struct i2c_client *client = ctx->client;
222 int i, ret;
223
224 for (i = 0; i < ARRAY_SIZE(data); ++i) {
225 int addr = (data[i][0] << 8) | data[i][1];
226 ret = sii9234_writeb_idx(client, addr, data[i][2]);
227 if (ret < 0)
228 return ret;
229 }
230 return 0;
231}
232
233static int sii9234_runtime_suspend(struct device *dev)
234{
235 struct v4l2_subdev *sd = dev_get_drvdata(dev);
236 struct sii9234_context *ctx = sd_to_context(sd);
237 struct i2c_client *client = ctx->client;
238
239 dev_info(dev, "suspend start\n");
240
241 sii9234_writeb_mask(client, 0x1e, 3, 3);
242 regulator_disable(ctx->power);
243
244 return 0;
245}
246
247static int sii9234_runtime_resume(struct device *dev)
248{
249 struct v4l2_subdev *sd = dev_get_drvdata(dev);
250 struct sii9234_context *ctx = sd_to_context(sd);
251 struct i2c_client *client = ctx->client;
252 int ret;
253
254 dev_info(dev, "resume start\n");
255 regulator_enable(ctx->power);
256
257 ret = sii9234_reset(ctx);
258 if (ret)
259 goto fail;
260
261 /* enable tpi */
262 ret = sii9234_writeb_mask(client, 0x1e, 1, 0);
263 if (ret < 0)
264 goto fail;
265 ret = sii9234_set_internal(ctx);
266 if (ret < 0)
267 goto fail;
268
269 return 0;
270
271fail:
272 dev_err(dev, "failed to resume\n");
273 regulator_disable(ctx->power);
274
275 return ret;
276}
277
278static const struct dev_pm_ops sii9234_pm_ops = {
279 .runtime_suspend = sii9234_runtime_suspend,
280 .runtime_resume = sii9234_runtime_resume,
281};
282
283static int sii9234_s_power(struct v4l2_subdev *sd, int on)
284{
285 struct sii9234_context *ctx = sd_to_context(sd);
286 int ret;
287
288 if (on)
289 ret = pm_runtime_get_sync(&ctx->client->dev);
290 else
291 ret = pm_runtime_put(&ctx->client->dev);
292 /* only values < 0 indicate errors */
293 return IS_ERR_VALUE(ret) ? ret : 0;
294}
295
296static int sii9234_s_stream(struct v4l2_subdev *sd, int enable)
297{
298 struct sii9234_context *ctx = sd_to_context(sd);
299
300 /* (dis/en)able TDMS output */
301 sii9234_writeb_mask(ctx->client, 0x1a, enable ? 0 : ~0 , 1 << 4);
302 return 0;
303}
304
305static const struct v4l2_subdev_core_ops sii9234_core_ops = {
306 .s_power = sii9234_s_power,
307};
308
309static const struct v4l2_subdev_video_ops sii9234_video_ops = {
310 .s_stream = sii9234_s_stream,
311};
312
313static const struct v4l2_subdev_ops sii9234_ops = {
314 .core = &sii9234_core_ops,
315 .video = &sii9234_video_ops,
316};
317
318static int __devinit sii9234_probe(struct i2c_client *client,
319 const struct i2c_device_id *id)
320{
321 struct device *dev = &client->dev;
322 struct sii9234_platform_data *pdata = dev->platform_data;
323 struct sii9234_context *ctx;
324 int ret;
325
326 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
327 if (!ctx) {
328 dev_err(dev, "out of memory\n");
329 ret = -ENOMEM;
330 goto fail;
331 }
332 ctx->client = client;
333
334 ctx->power = regulator_get(dev, "hdmi-en");
335 if (IS_ERR(ctx->power)) {
336 dev_err(dev, "failed to acquire regulator hdmi-en\n");
337 ret = PTR_ERR(ctx->power);
338 goto fail_ctx;
339 }
340
341 ctx->gpio_n_reset = pdata->gpio_n_reset;
342 ret = gpio_request(ctx->gpio_n_reset, "MHL_RST");
343 if (ret) {
344 dev_err(dev, "failed to acquire MHL_RST gpio\n");
345 goto fail_power;
346 }
347
348 v4l2_i2c_subdev_init(&ctx->sd, client, &sii9234_ops);
349
350 pm_runtime_enable(dev);
351
352 /* enable device */
353 ret = pm_runtime_get_sync(dev);
354 if (ret)
355 goto fail_pm;
356
357 /* verify chip version */
358 ret = sii9234_verify_version(client);
359 if (ret)
360 goto fail_pm_get;
361
362 /* stop processing */
363 pm_runtime_put(dev);
364
365 dev_info(dev, "probe successful\n");
366
367 return 0;
368
369fail_pm_get:
370 pm_runtime_put_sync(dev);
371
372fail_pm:
373 pm_runtime_disable(dev);
374 gpio_free(ctx->gpio_n_reset);
375
376fail_power:
377 regulator_put(ctx->power);
378
379fail_ctx:
380 kfree(ctx);
381
382fail:
383 dev_err(dev, "probe failed\n");
384
385 return ret;
386}
387
388static int __devexit sii9234_remove(struct i2c_client *client)
389{
390 struct device *dev = &client->dev;
391 struct v4l2_subdev *sd = i2c_get_clientdata(client);
392 struct sii9234_context *ctx = sd_to_context(sd);
393
394 pm_runtime_disable(dev);
395 gpio_free(ctx->gpio_n_reset);
396 regulator_put(ctx->power);
397 kfree(ctx);
398
399 dev_info(dev, "remove successful\n");
400
401 return 0;
402}
403
404
405static const struct i2c_device_id sii9234_id[] = {
406 { "SII9234", 0 },
407 { },
408};
409
410MODULE_DEVICE_TABLE(i2c, sii9234_id);
411static struct i2c_driver sii9234_driver = {
412 .driver = {
413 .name = "sii9234",
414 .owner = THIS_MODULE,
415 .pm = &sii9234_pm_ops,
416 },
417 .probe = sii9234_probe,
418 .remove = __devexit_p(sii9234_remove),
419 .id_table = sii9234_id,
420};
421
422module_i2c_driver(sii9234_driver);
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c
deleted file mode 100644
index 0baaf94db7e0..000000000000
--- a/drivers/media/video/sh_mobile_ceu_camera.c
+++ /dev/null
@@ -1,2331 +0,0 @@
1/*
2 * V4L2 Driver for SuperH Mobile CEU interface
3 *
4 * Copyright (C) 2008 Magnus Damm
5 *
6 * Based on V4L2 Driver for PXA camera host - "pxa_camera.c",
7 *
8 * Copyright (C) 2006, Sascha Hauer, Pengutronix
9 * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 */
16
17#include <linux/init.h>
18#include <linux/module.h>
19#include <linux/io.h>
20#include <linux/completion.h>
21#include <linux/delay.h>
22#include <linux/dma-mapping.h>
23#include <linux/errno.h>
24#include <linux/fs.h>
25#include <linux/interrupt.h>
26#include <linux/kernel.h>
27#include <linux/mm.h>
28#include <linux/moduleparam.h>
29#include <linux/time.h>
30#include <linux/slab.h>
31#include <linux/device.h>
32#include <linux/platform_device.h>
33#include <linux/videodev2.h>
34#include <linux/pm_runtime.h>
35#include <linux/sched.h>
36
37#include <media/v4l2-common.h>
38#include <media/v4l2-dev.h>
39#include <media/soc_camera.h>
40#include <media/sh_mobile_ceu.h>
41#include <media/sh_mobile_csi2.h>
42#include <media/videobuf2-dma-contig.h>
43#include <media/v4l2-mediabus.h>
44#include <media/soc_mediabus.h>
45
46/* register offsets for sh7722 / sh7723 */
47
48#define CAPSR 0x00 /* Capture start register */
49#define CAPCR 0x04 /* Capture control register */
50#define CAMCR 0x08 /* Capture interface control register */
51#define CMCYR 0x0c /* Capture interface cycle register */
52#define CAMOR 0x10 /* Capture interface offset register */
53#define CAPWR 0x14 /* Capture interface width register */
54#define CAIFR 0x18 /* Capture interface input format register */
55#define CSTCR 0x20 /* Camera strobe control register (<= sh7722) */
56#define CSECR 0x24 /* Camera strobe emission count register (<= sh7722) */
57#define CRCNTR 0x28 /* CEU register control register */
58#define CRCMPR 0x2c /* CEU register forcible control register */
59#define CFLCR 0x30 /* Capture filter control register */
60#define CFSZR 0x34 /* Capture filter size clip register */
61#define CDWDR 0x38 /* Capture destination width register */
62#define CDAYR 0x3c /* Capture data address Y register */
63#define CDACR 0x40 /* Capture data address C register */
64#define CDBYR 0x44 /* Capture data bottom-field address Y register */
65#define CDBCR 0x48 /* Capture data bottom-field address C register */
66#define CBDSR 0x4c /* Capture bundle destination size register */
67#define CFWCR 0x5c /* Firewall operation control register */
68#define CLFCR 0x60 /* Capture low-pass filter control register */
69#define CDOCR 0x64 /* Capture data output control register */
70#define CDDCR 0x68 /* Capture data complexity level register */
71#define CDDAR 0x6c /* Capture data complexity level address register */
72#define CEIER 0x70 /* Capture event interrupt enable register */
73#define CETCR 0x74 /* Capture event flag clear register */
74#define CSTSR 0x7c /* Capture status register */
75#define CSRTR 0x80 /* Capture software reset register */
76#define CDSSR 0x84 /* Capture data size register */
77#define CDAYR2 0x90 /* Capture data address Y register 2 */
78#define CDACR2 0x94 /* Capture data address C register 2 */
79#define CDBYR2 0x98 /* Capture data bottom-field address Y register 2 */
80#define CDBCR2 0x9c /* Capture data bottom-field address C register 2 */
81
82#undef DEBUG_GEOMETRY
83#ifdef DEBUG_GEOMETRY
84#define dev_geo dev_info
85#else
86#define dev_geo dev_dbg
87#endif
88
89/* per video frame buffer */
90struct sh_mobile_ceu_buffer {
91 struct vb2_buffer vb; /* v4l buffer must be first */
92 struct list_head queue;
93};
94
95struct sh_mobile_ceu_dev {
96 struct soc_camera_host ici;
97 struct soc_camera_device *icd;
98 struct platform_device *csi2_pdev;
99
100 unsigned int irq;
101 void __iomem *base;
102 size_t video_limit;
103 size_t buf_total;
104
105 spinlock_t lock; /* Protects video buffer lists */
106 struct list_head capture;
107 struct vb2_buffer *active;
108 struct vb2_alloc_ctx *alloc_ctx;
109
110 struct sh_mobile_ceu_info *pdata;
111 struct completion complete;
112
113 u32 cflcr;
114
115 /* static max sizes either from platform data or default */
116 int max_width;
117 int max_height;
118
119 enum v4l2_field field;
120 int sequence;
121
122 unsigned int image_mode:1;
123 unsigned int is_16bit:1;
124 unsigned int frozen:1;
125};
126
127struct sh_mobile_ceu_cam {
128 /* CEU offsets within the camera output, before the CEU scaler */
129 unsigned int ceu_left;
130 unsigned int ceu_top;
131 /* Client output, as seen by the CEU */
132 unsigned int width;
133 unsigned int height;
134 /*
135 * User window from S_CROP / G_CROP, produced by client cropping and
136 * scaling, CEU scaling and CEU cropping, mapped back onto the client
137 * input window
138 */
139 struct v4l2_rect subrect;
140 /* Camera cropping rectangle */
141 struct v4l2_rect rect;
142 const struct soc_mbus_pixelfmt *extra_fmt;
143 enum v4l2_mbus_pixelcode code;
144};
145
146static struct sh_mobile_ceu_buffer *to_ceu_vb(struct vb2_buffer *vb)
147{
148 return container_of(vb, struct sh_mobile_ceu_buffer, vb);
149}
150
151static void ceu_write(struct sh_mobile_ceu_dev *priv,
152 unsigned long reg_offs, u32 data)
153{
154 iowrite32(data, priv->base + reg_offs);
155}
156
157static u32 ceu_read(struct sh_mobile_ceu_dev *priv, unsigned long reg_offs)
158{
159 return ioread32(priv->base + reg_offs);
160}
161
162static int sh_mobile_ceu_soft_reset(struct sh_mobile_ceu_dev *pcdev)
163{
164 int i, success = 0;
165 struct soc_camera_device *icd = pcdev->icd;
166
167 ceu_write(pcdev, CAPSR, 1 << 16); /* reset */
168
169 /* wait CSTSR.CPTON bit */
170 for (i = 0; i < 1000; i++) {
171 if (!(ceu_read(pcdev, CSTSR) & 1)) {
172 success++;
173 break;
174 }
175 udelay(1);
176 }
177
178 /* wait CAPSR.CPKIL bit */
179 for (i = 0; i < 1000; i++) {
180 if (!(ceu_read(pcdev, CAPSR) & (1 << 16))) {
181 success++;
182 break;
183 }
184 udelay(1);
185 }
186
187
188 if (2 != success) {
189 dev_warn(icd->pdev, "soft reset time out\n");
190 return -EIO;
191 }
192
193 return 0;
194}
195
196/*
197 * Videobuf operations
198 */
199
200/*
201 * .queue_setup() is called to check, whether the driver can accept the
202 * requested number of buffers and to fill in plane sizes
203 * for the current frame format if required
204 */
205static int sh_mobile_ceu_videobuf_setup(struct vb2_queue *vq,
206 const struct v4l2_format *fmt,
207 unsigned int *count, unsigned int *num_planes,
208 unsigned int sizes[], void *alloc_ctxs[])
209{
210 struct soc_camera_device *icd = container_of(vq, struct soc_camera_device, vb2_vidq);
211 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
212 struct sh_mobile_ceu_dev *pcdev = ici->priv;
213
214 if (fmt) {
215 const struct soc_camera_format_xlate *xlate = soc_camera_xlate_by_fourcc(icd,
216 fmt->fmt.pix.pixelformat);
217 unsigned int bytes_per_line;
218 int ret;
219
220 if (!xlate)
221 return -EINVAL;
222
223 ret = soc_mbus_bytes_per_line(fmt->fmt.pix.width,
224 xlate->host_fmt);
225 if (ret < 0)
226 return ret;
227
228 bytes_per_line = max_t(u32, fmt->fmt.pix.bytesperline, ret);
229
230 ret = soc_mbus_image_size(xlate->host_fmt, bytes_per_line,
231 fmt->fmt.pix.height);
232 if (ret < 0)
233 return ret;
234
235 sizes[0] = max_t(u32, fmt->fmt.pix.sizeimage, ret);
236 } else {
237 /* Called from VIDIOC_REQBUFS or in compatibility mode */
238 sizes[0] = icd->sizeimage;
239 }
240
241 alloc_ctxs[0] = pcdev->alloc_ctx;
242
243 if (!vq->num_buffers)
244 pcdev->sequence = 0;
245
246 if (!*count)
247 *count = 2;
248
249 /* If *num_planes != 0, we have already verified *count. */
250 if (pcdev->video_limit && !*num_planes) {
251 size_t size = PAGE_ALIGN(sizes[0]) * *count;
252
253 if (size + pcdev->buf_total > pcdev->video_limit)
254 *count = (pcdev->video_limit - pcdev->buf_total) /
255 PAGE_ALIGN(sizes[0]);
256 }
257
258 *num_planes = 1;
259
260 dev_dbg(icd->parent, "count=%d, size=%u\n", *count, sizes[0]);
261
262 return 0;
263}
264
265#define CEU_CETCR_MAGIC 0x0317f313 /* acknowledge magical interrupt sources */
266#define CEU_CETCR_IGRW (1 << 4) /* prohibited register access interrupt bit */
267#define CEU_CEIER_CPEIE (1 << 0) /* one-frame capture end interrupt */
268#define CEU_CEIER_VBP (1 << 20) /* vbp error */
269#define CEU_CAPCR_CTNCP (1 << 16) /* continuous capture mode (if set) */
270#define CEU_CEIER_MASK (CEU_CEIER_CPEIE | CEU_CEIER_VBP)
271
272
273/*
274 * return value doesn't reflex the success/failure to queue the new buffer,
275 * but rather the status of the previous buffer.
276 */
277static int sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
278{
279 struct soc_camera_device *icd = pcdev->icd;
280 dma_addr_t phys_addr_top, phys_addr_bottom;
281 unsigned long top1, top2;
282 unsigned long bottom1, bottom2;
283 u32 status;
284 bool planar;
285 int ret = 0;
286
287 /*
288 * The hardware is _very_ picky about this sequence. Especially
289 * the CEU_CETCR_MAGIC value. It seems like we need to acknowledge
290 * several not-so-well documented interrupt sources in CETCR.
291 */
292 ceu_write(pcdev, CEIER, ceu_read(pcdev, CEIER) & ~CEU_CEIER_MASK);
293 status = ceu_read(pcdev, CETCR);
294 ceu_write(pcdev, CETCR, ~status & CEU_CETCR_MAGIC);
295 if (!pcdev->frozen)
296 ceu_write(pcdev, CEIER, ceu_read(pcdev, CEIER) | CEU_CEIER_MASK);
297 ceu_write(pcdev, CAPCR, ceu_read(pcdev, CAPCR) & ~CEU_CAPCR_CTNCP);
298 ceu_write(pcdev, CETCR, CEU_CETCR_MAGIC ^ CEU_CETCR_IGRW);
299
300 /*
301 * When a VBP interrupt occurs, a capture end interrupt does not occur
302 * and the image of that frame is not captured correctly. So, soft reset
303 * is needed here.
304 */
305 if (status & CEU_CEIER_VBP) {
306 sh_mobile_ceu_soft_reset(pcdev);
307 ret = -EIO;
308 }
309
310 if (pcdev->frozen) {
311 complete(&pcdev->complete);
312 return ret;
313 }
314
315 if (!pcdev->active)
316 return ret;
317
318 if (V4L2_FIELD_INTERLACED_BT == pcdev->field) {
319 top1 = CDBYR;
320 top2 = CDBCR;
321 bottom1 = CDAYR;
322 bottom2 = CDACR;
323 } else {
324 top1 = CDAYR;
325 top2 = CDACR;
326 bottom1 = CDBYR;
327 bottom2 = CDBCR;
328 }
329
330 phys_addr_top = vb2_dma_contig_plane_dma_addr(pcdev->active, 0);
331
332 switch (icd->current_fmt->host_fmt->fourcc) {
333 case V4L2_PIX_FMT_NV12:
334 case V4L2_PIX_FMT_NV21:
335 case V4L2_PIX_FMT_NV16:
336 case V4L2_PIX_FMT_NV61:
337 planar = true;
338 break;
339 default:
340 planar = false;
341 }
342
343 ceu_write(pcdev, top1, phys_addr_top);
344 if (V4L2_FIELD_NONE != pcdev->field) {
345 phys_addr_bottom = phys_addr_top + icd->bytesperline;
346 ceu_write(pcdev, bottom1, phys_addr_bottom);
347 }
348
349 if (planar) {
350 phys_addr_top += icd->bytesperline * icd->user_height;
351 ceu_write(pcdev, top2, phys_addr_top);
352 if (V4L2_FIELD_NONE != pcdev->field) {
353 phys_addr_bottom = phys_addr_top + icd->bytesperline;
354 ceu_write(pcdev, bottom2, phys_addr_bottom);
355 }
356 }
357
358 ceu_write(pcdev, CAPSR, 0x1); /* start capture */
359
360 return ret;
361}
362
363static int sh_mobile_ceu_videobuf_prepare(struct vb2_buffer *vb)
364{
365 struct sh_mobile_ceu_buffer *buf = to_ceu_vb(vb);
366
367 /* Added list head initialization on alloc */
368 WARN(!list_empty(&buf->queue), "Buffer %p on queue!\n", vb);
369
370 return 0;
371}
372
373static void sh_mobile_ceu_videobuf_queue(struct vb2_buffer *vb)
374{
375 struct soc_camera_device *icd = container_of(vb->vb2_queue, struct soc_camera_device, vb2_vidq);
376 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
377 struct sh_mobile_ceu_dev *pcdev = ici->priv;
378 struct sh_mobile_ceu_buffer *buf = to_ceu_vb(vb);
379 unsigned long size;
380
381 size = icd->sizeimage;
382
383 if (vb2_plane_size(vb, 0) < size) {
384 dev_err(icd->parent, "Buffer #%d too small (%lu < %lu)\n",
385 vb->v4l2_buf.index, vb2_plane_size(vb, 0), size);
386 goto error;
387 }
388
389 vb2_set_plane_payload(vb, 0, size);
390
391 dev_dbg(icd->parent, "%s (vb=0x%p) 0x%p %lu\n", __func__,
392 vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0));
393
394#ifdef DEBUG
395 /*
396 * This can be useful if you want to see if we actually fill
397 * the buffer with something
398 */
399 if (vb2_plane_vaddr(vb, 0))
400 memset(vb2_plane_vaddr(vb, 0), 0xaa, vb2_get_plane_payload(vb, 0));
401#endif
402
403 spin_lock_irq(&pcdev->lock);
404 list_add_tail(&buf->queue, &pcdev->capture);
405
406 if (!pcdev->active) {
407 /*
408 * Because there were no active buffer at this moment,
409 * we are not interested in the return value of
410 * sh_mobile_ceu_capture here.
411 */
412 pcdev->active = vb;
413 sh_mobile_ceu_capture(pcdev);
414 }
415 spin_unlock_irq(&pcdev->lock);
416
417 return;
418
419error:
420 vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
421}
422
423static void sh_mobile_ceu_videobuf_release(struct vb2_buffer *vb)
424{
425 struct soc_camera_device *icd = container_of(vb->vb2_queue, struct soc_camera_device, vb2_vidq);
426 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
427 struct sh_mobile_ceu_buffer *buf = to_ceu_vb(vb);
428 struct sh_mobile_ceu_dev *pcdev = ici->priv;
429
430 spin_lock_irq(&pcdev->lock);
431
432 if (pcdev->active == vb) {
433 /* disable capture (release DMA buffer), reset */
434 ceu_write(pcdev, CAPSR, 1 << 16);
435 pcdev->active = NULL;
436 }
437
438 /*
439 * Doesn't hurt also if the list is empty, but it hurts, if queuing the
440 * buffer failed, and .buf_init() hasn't been called
441 */
442 if (buf->queue.next)
443 list_del_init(&buf->queue);
444
445 pcdev->buf_total -= PAGE_ALIGN(vb2_plane_size(vb, 0));
446 dev_dbg(icd->parent, "%s() %zu bytes buffers\n", __func__,
447 pcdev->buf_total);
448
449 spin_unlock_irq(&pcdev->lock);
450}
451
452static int sh_mobile_ceu_videobuf_init(struct vb2_buffer *vb)
453{
454 struct soc_camera_device *icd = container_of(vb->vb2_queue, struct soc_camera_device, vb2_vidq);
455 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
456 struct sh_mobile_ceu_dev *pcdev = ici->priv;
457
458 pcdev->buf_total += PAGE_ALIGN(vb2_plane_size(vb, 0));
459 dev_dbg(icd->parent, "%s() %zu bytes buffers\n", __func__,
460 pcdev->buf_total);
461
462 /* This is for locking debugging only */
463 INIT_LIST_HEAD(&to_ceu_vb(vb)->queue);
464 return 0;
465}
466
467static int sh_mobile_ceu_stop_streaming(struct vb2_queue *q)
468{
469 struct soc_camera_device *icd = container_of(q, struct soc_camera_device, vb2_vidq);
470 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
471 struct sh_mobile_ceu_dev *pcdev = ici->priv;
472 struct list_head *buf_head, *tmp;
473
474 spin_lock_irq(&pcdev->lock);
475
476 pcdev->active = NULL;
477
478 list_for_each_safe(buf_head, tmp, &pcdev->capture)
479 list_del_init(buf_head);
480
481 spin_unlock_irq(&pcdev->lock);
482
483 return sh_mobile_ceu_soft_reset(pcdev);
484}
485
486static struct vb2_ops sh_mobile_ceu_videobuf_ops = {
487 .queue_setup = sh_mobile_ceu_videobuf_setup,
488 .buf_prepare = sh_mobile_ceu_videobuf_prepare,
489 .buf_queue = sh_mobile_ceu_videobuf_queue,
490 .buf_cleanup = sh_mobile_ceu_videobuf_release,
491 .buf_init = sh_mobile_ceu_videobuf_init,
492 .wait_prepare = soc_camera_unlock,
493 .wait_finish = soc_camera_lock,
494 .stop_streaming = sh_mobile_ceu_stop_streaming,
495};
496
497static irqreturn_t sh_mobile_ceu_irq(int irq, void *data)
498{
499 struct sh_mobile_ceu_dev *pcdev = data;
500 struct vb2_buffer *vb;
501 int ret;
502
503 spin_lock(&pcdev->lock);
504
505 vb = pcdev->active;
506 if (!vb)
507 /* Stale interrupt from a released buffer */
508 goto out;
509
510 list_del_init(&to_ceu_vb(vb)->queue);
511
512 if (!list_empty(&pcdev->capture))
513 pcdev->active = &list_entry(pcdev->capture.next,
514 struct sh_mobile_ceu_buffer, queue)->vb;
515 else
516 pcdev->active = NULL;
517
518 ret = sh_mobile_ceu_capture(pcdev);
519 do_gettimeofday(&vb->v4l2_buf.timestamp);
520 if (!ret) {
521 vb->v4l2_buf.field = pcdev->field;
522 vb->v4l2_buf.sequence = pcdev->sequence++;
523 }
524 vb2_buffer_done(vb, ret < 0 ? VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
525
526out:
527 spin_unlock(&pcdev->lock);
528
529 return IRQ_HANDLED;
530}
531
532static struct v4l2_subdev *find_csi2(struct sh_mobile_ceu_dev *pcdev)
533{
534 struct v4l2_subdev *sd;
535
536 if (!pcdev->csi2_pdev)
537 return NULL;
538
539 v4l2_device_for_each_subdev(sd, &pcdev->ici.v4l2_dev)
540 if (&pcdev->csi2_pdev->dev == v4l2_get_subdevdata(sd))
541 return sd;
542
543 return NULL;
544}
545
546/* Called with .video_lock held */
547static int sh_mobile_ceu_add_device(struct soc_camera_device *icd)
548{
549 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
550 struct sh_mobile_ceu_dev *pcdev = ici->priv;
551 struct v4l2_subdev *csi2_sd;
552 int ret;
553
554 if (pcdev->icd)
555 return -EBUSY;
556
557 dev_info(icd->parent,
558 "SuperH Mobile CEU driver attached to camera %d\n",
559 icd->devnum);
560
561 pm_runtime_get_sync(ici->v4l2_dev.dev);
562
563 pcdev->buf_total = 0;
564
565 ret = sh_mobile_ceu_soft_reset(pcdev);
566
567 csi2_sd = find_csi2(pcdev);
568 if (csi2_sd) {
569 csi2_sd->grp_id = soc_camera_grp_id(icd);
570 v4l2_set_subdev_hostdata(csi2_sd, icd);
571 }
572
573 ret = v4l2_subdev_call(csi2_sd, core, s_power, 1);
574 if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV) {
575 pm_runtime_put_sync(ici->v4l2_dev.dev);
576 return ret;
577 }
578
579 /*
580 * -ENODEV is special: either csi2_sd == NULL or the CSI-2 driver
581 * has not found this soc-camera device among its clients
582 */
583 if (ret == -ENODEV && csi2_sd)
584 csi2_sd->grp_id = 0;
585 pcdev->icd = icd;
586
587 return 0;
588}
589
590/* Called with .video_lock held */
591static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd)
592{
593 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
594 struct sh_mobile_ceu_dev *pcdev = ici->priv;
595 struct v4l2_subdev *csi2_sd = find_csi2(pcdev);
596
597 BUG_ON(icd != pcdev->icd);
598
599 v4l2_subdev_call(csi2_sd, core, s_power, 0);
600 if (csi2_sd)
601 csi2_sd->grp_id = 0;
602 /* disable capture, disable interrupts */
603 ceu_write(pcdev, CEIER, 0);
604 sh_mobile_ceu_soft_reset(pcdev);
605
606 /* make sure active buffer is canceled */
607 spin_lock_irq(&pcdev->lock);
608 if (pcdev->active) {
609 list_del_init(&to_ceu_vb(pcdev->active)->queue);
610 vb2_buffer_done(pcdev->active, VB2_BUF_STATE_ERROR);
611 pcdev->active = NULL;
612 }
613 spin_unlock_irq(&pcdev->lock);
614
615 pm_runtime_put_sync(ici->v4l2_dev.dev);
616
617 dev_info(icd->parent,
618 "SuperH Mobile CEU driver detached from camera %d\n",
619 icd->devnum);
620
621 pcdev->icd = NULL;
622}
623
624/*
625 * See chapter 29.4.12 "Capture Filter Control Register (CFLCR)"
626 * in SH7722 Hardware Manual
627 */
628static unsigned int size_dst(unsigned int src, unsigned int scale)
629{
630 unsigned int mant_pre = scale >> 12;
631 if (!src || !scale)
632 return src;
633 return ((mant_pre + 2 * (src - 1)) / (2 * mant_pre) - 1) *
634 mant_pre * 4096 / scale + 1;
635}
636
637static u16 calc_scale(unsigned int src, unsigned int *dst)
638{
639 u16 scale;
640
641 if (src == *dst)
642 return 0;
643
644 scale = (src * 4096 / *dst) & ~7;
645
646 while (scale > 4096 && size_dst(src, scale) < *dst)
647 scale -= 8;
648
649 *dst = size_dst(src, scale);
650
651 return scale;
652}
653
654/* rect is guaranteed to not exceed the scaled camera rectangle */
655static void sh_mobile_ceu_set_rect(struct soc_camera_device *icd)
656{
657 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
658 struct sh_mobile_ceu_cam *cam = icd->host_priv;
659 struct sh_mobile_ceu_dev *pcdev = ici->priv;
660 unsigned int height, width, cdwdr_width, in_width, in_height;
661 unsigned int left_offset, top_offset;
662 u32 camor;
663
664 dev_geo(icd->parent, "Crop %ux%u@%u:%u\n",
665 icd->user_width, icd->user_height, cam->ceu_left, cam->ceu_top);
666
667 left_offset = cam->ceu_left;
668 top_offset = cam->ceu_top;
669
670 WARN_ON(icd->user_width & 3 || icd->user_height & 3);
671
672 width = icd->user_width;
673
674 if (pcdev->image_mode) {
675 in_width = cam->width;
676 if (!pcdev->is_16bit) {
677 in_width *= 2;
678 left_offset *= 2;
679 }
680 } else {
681 unsigned int w_factor;
682
683 switch (icd->current_fmt->host_fmt->packing) {
684 case SOC_MBUS_PACKING_2X8_PADHI:
685 w_factor = 2;
686 break;
687 default:
688 w_factor = 1;
689 }
690
691 in_width = cam->width * w_factor;
692 left_offset *= w_factor;
693 }
694
695 cdwdr_width = icd->bytesperline;
696
697 height = icd->user_height;
698 in_height = cam->height;
699 if (V4L2_FIELD_NONE != pcdev->field) {
700 height = (height / 2) & ~3;
701 in_height /= 2;
702 top_offset /= 2;
703 cdwdr_width *= 2;
704 }
705
706 /* CSI2 special configuration */
707 if (pcdev->pdata->csi2) {
708 in_width = ((in_width - 2) * 2);
709 left_offset *= 2;
710 }
711
712 /* Set CAMOR, CAPWR, CFSZR, take care of CDWDR */
713 camor = left_offset | (top_offset << 16);
714
715 dev_geo(icd->parent,
716 "CAMOR 0x%x, CAPWR 0x%x, CFSZR 0x%x, CDWDR 0x%x\n", camor,
717 (in_height << 16) | in_width, (height << 16) | width,
718 cdwdr_width);
719
720 ceu_write(pcdev, CAMOR, camor);
721 ceu_write(pcdev, CAPWR, (in_height << 16) | in_width);
722 /* CFSZR clipping is applied _after_ the scaling filter (CFLCR) */
723 ceu_write(pcdev, CFSZR, (height << 16) | width);
724 ceu_write(pcdev, CDWDR, cdwdr_width);
725}
726
727static u32 capture_save_reset(struct sh_mobile_ceu_dev *pcdev)
728{
729 u32 capsr = ceu_read(pcdev, CAPSR);
730 ceu_write(pcdev, CAPSR, 1 << 16); /* reset, stop capture */
731 return capsr;
732}
733
734static void capture_restore(struct sh_mobile_ceu_dev *pcdev, u32 capsr)
735{
736 unsigned long timeout = jiffies + 10 * HZ;
737
738 /*
739 * Wait until the end of the current frame. It can take a long time,
740 * but if it has been aborted by a CAPSR reset, it shoule exit sooner.
741 */
742 while ((ceu_read(pcdev, CSTSR) & 1) && time_before(jiffies, timeout))
743 msleep(1);
744
745 if (time_after(jiffies, timeout)) {
746 dev_err(pcdev->ici.v4l2_dev.dev,
747 "Timeout waiting for frame end! Interface problem?\n");
748 return;
749 }
750
751 /* Wait until reset clears, this shall not hang... */
752 while (ceu_read(pcdev, CAPSR) & (1 << 16))
753 udelay(10);
754
755 /* Anything to restore? */
756 if (capsr & ~(1 << 16))
757 ceu_write(pcdev, CAPSR, capsr);
758}
759
760/* Find the bus subdevice driver, e.g., CSI2 */
761static struct v4l2_subdev *find_bus_subdev(struct sh_mobile_ceu_dev *pcdev,
762 struct soc_camera_device *icd)
763{
764 if (pcdev->csi2_pdev) {
765 struct v4l2_subdev *csi2_sd = find_csi2(pcdev);
766 if (csi2_sd && csi2_sd->grp_id == soc_camera_grp_id(icd))
767 return csi2_sd;
768 }
769
770 return soc_camera_to_subdev(icd);
771}
772
773#define CEU_BUS_FLAGS (V4L2_MBUS_MASTER | \
774 V4L2_MBUS_PCLK_SAMPLE_RISING | \
775 V4L2_MBUS_HSYNC_ACTIVE_HIGH | \
776 V4L2_MBUS_HSYNC_ACTIVE_LOW | \
777 V4L2_MBUS_VSYNC_ACTIVE_HIGH | \
778 V4L2_MBUS_VSYNC_ACTIVE_LOW | \
779 V4L2_MBUS_DATA_ACTIVE_HIGH)
780
781/* Capture is not running, no interrupts, no locking needed */
782static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd)
783{
784 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
785 struct sh_mobile_ceu_dev *pcdev = ici->priv;
786 struct v4l2_subdev *sd = find_bus_subdev(pcdev, icd);
787 struct sh_mobile_ceu_cam *cam = icd->host_priv;
788 struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
789 unsigned long value, common_flags = CEU_BUS_FLAGS;
790 u32 capsr = capture_save_reset(pcdev);
791 unsigned int yuv_lineskip;
792 int ret;
793
794 /*
795 * If the client doesn't implement g_mbus_config, we just use our
796 * platform data
797 */
798 ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
799 if (!ret) {
800 common_flags = soc_mbus_config_compatible(&cfg,
801 common_flags);
802 if (!common_flags)
803 return -EINVAL;
804 } else if (ret != -ENOIOCTLCMD) {
805 return ret;
806 }
807
808 /* Make choises, based on platform preferences */
809 if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) &&
810 (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) {
811 if (pcdev->pdata->flags & SH_CEU_FLAG_HSYNC_LOW)
812 common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH;
813 else
814 common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW;
815 }
816
817 if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) &&
818 (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) {
819 if (pcdev->pdata->flags & SH_CEU_FLAG_VSYNC_LOW)
820 common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH;
821 else
822 common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW;
823 }
824
825 cfg.flags = common_flags;
826 ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
827 if (ret < 0 && ret != -ENOIOCTLCMD)
828 return ret;
829
830 if (icd->current_fmt->host_fmt->bits_per_sample > 8)
831 pcdev->is_16bit = 1;
832 else
833 pcdev->is_16bit = 0;
834
835 ceu_write(pcdev, CRCNTR, 0);
836 ceu_write(pcdev, CRCMPR, 0);
837
838 value = 0x00000010; /* data fetch by default */
839 yuv_lineskip = 0x10;
840
841 switch (icd->current_fmt->host_fmt->fourcc) {
842 case V4L2_PIX_FMT_NV12:
843 case V4L2_PIX_FMT_NV21:
844 /* convert 4:2:2 -> 4:2:0 */
845 yuv_lineskip = 0; /* skip for NV12/21, no skip for NV16/61 */
846 /* fall-through */
847 case V4L2_PIX_FMT_NV16:
848 case V4L2_PIX_FMT_NV61:
849 switch (cam->code) {
850 case V4L2_MBUS_FMT_UYVY8_2X8:
851 value = 0x00000000; /* Cb0, Y0, Cr0, Y1 */
852 break;
853 case V4L2_MBUS_FMT_VYUY8_2X8:
854 value = 0x00000100; /* Cr0, Y0, Cb0, Y1 */
855 break;
856 case V4L2_MBUS_FMT_YUYV8_2X8:
857 value = 0x00000200; /* Y0, Cb0, Y1, Cr0 */
858 break;
859 case V4L2_MBUS_FMT_YVYU8_2X8:
860 value = 0x00000300; /* Y0, Cr0, Y1, Cb0 */
861 break;
862 default:
863 BUG();
864 }
865 }
866
867 if (icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_NV21 ||
868 icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_NV61)
869 value ^= 0x00000100; /* swap U, V to change from NV1x->NVx1 */
870
871 value |= common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW ? 1 << 1 : 0;
872 value |= common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW ? 1 << 0 : 0;
873
874 if (pcdev->pdata->csi2) /* CSI2 mode */
875 value |= 3 << 12;
876 else if (pcdev->is_16bit)
877 value |= 1 << 12;
878 else if (pcdev->pdata->flags & SH_CEU_FLAG_LOWER_8BIT)
879 value |= 2 << 12;
880
881 ceu_write(pcdev, CAMCR, value);
882
883 ceu_write(pcdev, CAPCR, 0x00300000);
884
885 switch (pcdev->field) {
886 case V4L2_FIELD_INTERLACED_TB:
887 value = 0x101;
888 break;
889 case V4L2_FIELD_INTERLACED_BT:
890 value = 0x102;
891 break;
892 default:
893 value = 0;
894 break;
895 }
896 ceu_write(pcdev, CAIFR, value);
897
898 sh_mobile_ceu_set_rect(icd);
899 mdelay(1);
900
901 dev_geo(icd->parent, "CFLCR 0x%x\n", pcdev->cflcr);
902 ceu_write(pcdev, CFLCR, pcdev->cflcr);
903
904 /*
905 * A few words about byte order (observed in Big Endian mode)
906 *
907 * In data fetch mode bytes are received in chunks of 8 bytes.
908 * D0, D1, D2, D3, D4, D5, D6, D7 (D0 received first)
909 *
910 * The data is however by default written to memory in reverse order:
911 * D7, D6, D5, D4, D3, D2, D1, D0 (D7 written to lowest byte)
912 *
913 * The lowest three bits of CDOCR allows us to do swapping,
914 * using 7 we swap the data bytes to match the incoming order:
915 * D0, D1, D2, D3, D4, D5, D6, D7
916 */
917 value = 0x00000007 | yuv_lineskip;
918
919 ceu_write(pcdev, CDOCR, value);
920 ceu_write(pcdev, CFWCR, 0); /* keep "datafetch firewall" disabled */
921
922 capture_restore(pcdev, capsr);
923
924 /* not in bundle mode: skip CBDSR, CDAYR2, CDACR2, CDBYR2, CDBCR2 */
925 return 0;
926}
927
928static int sh_mobile_ceu_try_bus_param(struct soc_camera_device *icd,
929 unsigned char buswidth)
930{
931 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
932 struct sh_mobile_ceu_dev *pcdev = ici->priv;
933 struct v4l2_subdev *sd = find_bus_subdev(pcdev, icd);
934 unsigned long common_flags = CEU_BUS_FLAGS;
935 struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
936 int ret;
937
938 ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
939 if (!ret)
940 common_flags = soc_mbus_config_compatible(&cfg,
941 common_flags);
942 else if (ret != -ENOIOCTLCMD)
943 return ret;
944
945 if (!common_flags || buswidth > 16)
946 return -EINVAL;
947
948 return 0;
949}
950
951static const struct soc_mbus_pixelfmt sh_mobile_ceu_formats[] = {
952 {
953 .fourcc = V4L2_PIX_FMT_NV12,
954 .name = "NV12",
955 .bits_per_sample = 8,
956 .packing = SOC_MBUS_PACKING_1_5X8,
957 .order = SOC_MBUS_ORDER_LE,
958 .layout = SOC_MBUS_LAYOUT_PLANAR_2Y_C,
959 }, {
960 .fourcc = V4L2_PIX_FMT_NV21,
961 .name = "NV21",
962 .bits_per_sample = 8,
963 .packing = SOC_MBUS_PACKING_1_5X8,
964 .order = SOC_MBUS_ORDER_LE,
965 .layout = SOC_MBUS_LAYOUT_PLANAR_2Y_C,
966 }, {
967 .fourcc = V4L2_PIX_FMT_NV16,
968 .name = "NV16",
969 .bits_per_sample = 8,
970 .packing = SOC_MBUS_PACKING_2X8_PADHI,
971 .order = SOC_MBUS_ORDER_LE,
972 .layout = SOC_MBUS_LAYOUT_PLANAR_Y_C,
973 }, {
974 .fourcc = V4L2_PIX_FMT_NV61,
975 .name = "NV61",
976 .bits_per_sample = 8,
977 .packing = SOC_MBUS_PACKING_2X8_PADHI,
978 .order = SOC_MBUS_ORDER_LE,
979 .layout = SOC_MBUS_LAYOUT_PLANAR_Y_C,
980 },
981};
982
983/* This will be corrected as we get more formats */
984static bool sh_mobile_ceu_packing_supported(const struct soc_mbus_pixelfmt *fmt)
985{
986 return fmt->packing == SOC_MBUS_PACKING_NONE ||
987 (fmt->bits_per_sample == 8 &&
988 fmt->packing == SOC_MBUS_PACKING_1_5X8) ||
989 (fmt->bits_per_sample == 8 &&
990 fmt->packing == SOC_MBUS_PACKING_2X8_PADHI) ||
991 (fmt->bits_per_sample > 8 &&
992 fmt->packing == SOC_MBUS_PACKING_EXTEND16);
993}
994
995static int client_g_rect(struct v4l2_subdev *sd, struct v4l2_rect *rect);
996
997static struct soc_camera_device *ctrl_to_icd(struct v4l2_ctrl *ctrl)
998{
999 return container_of(ctrl->handler, struct soc_camera_device,
1000 ctrl_handler);
1001}
1002
1003static int sh_mobile_ceu_s_ctrl(struct v4l2_ctrl *ctrl)
1004{
1005 struct soc_camera_device *icd = ctrl_to_icd(ctrl);
1006 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1007 struct sh_mobile_ceu_dev *pcdev = ici->priv;
1008
1009 switch (ctrl->id) {
1010 case V4L2_CID_SHARPNESS:
1011 switch (icd->current_fmt->host_fmt->fourcc) {
1012 case V4L2_PIX_FMT_NV12:
1013 case V4L2_PIX_FMT_NV21:
1014 case V4L2_PIX_FMT_NV16:
1015 case V4L2_PIX_FMT_NV61:
1016 ceu_write(pcdev, CLFCR, !ctrl->val);
1017 return 0;
1018 }
1019 break;
1020 }
1021
1022 return -EINVAL;
1023}
1024
1025static const struct v4l2_ctrl_ops sh_mobile_ceu_ctrl_ops = {
1026 .s_ctrl = sh_mobile_ceu_s_ctrl,
1027};
1028
1029static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, unsigned int idx,
1030 struct soc_camera_format_xlate *xlate)
1031{
1032 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1033 struct device *dev = icd->parent;
1034 struct soc_camera_host *ici = to_soc_camera_host(dev);
1035 struct sh_mobile_ceu_dev *pcdev = ici->priv;
1036 int ret, k, n;
1037 int formats = 0;
1038 struct sh_mobile_ceu_cam *cam;
1039 enum v4l2_mbus_pixelcode code;
1040 const struct soc_mbus_pixelfmt *fmt;
1041
1042 ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code);
1043 if (ret < 0)
1044 /* No more formats */
1045 return 0;
1046
1047 fmt = soc_mbus_get_fmtdesc(code);
1048 if (!fmt) {
1049 dev_warn(dev, "unsupported format code #%u: %d\n", idx, code);
1050 return 0;
1051 }
1052
1053 if (!pcdev->pdata->csi2) {
1054 /* Are there any restrictions in the CSI-2 case? */
1055 ret = sh_mobile_ceu_try_bus_param(icd, fmt->bits_per_sample);
1056 if (ret < 0)
1057 return 0;
1058 }
1059
1060 if (!icd->host_priv) {
1061 struct v4l2_mbus_framefmt mf;
1062 struct v4l2_rect rect;
1063 int shift = 0;
1064
1065 /* Add our control */
1066 v4l2_ctrl_new_std(&icd->ctrl_handler, &sh_mobile_ceu_ctrl_ops,
1067 V4L2_CID_SHARPNESS, 0, 1, 1, 0);
1068 if (icd->ctrl_handler.error)
1069 return icd->ctrl_handler.error;
1070
1071 /* FIXME: subwindow is lost between close / open */
1072
1073 /* Cache current client geometry */
1074 ret = client_g_rect(sd, &rect);
1075 if (ret < 0)
1076 return ret;
1077
1078 /* First time */
1079 ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf);
1080 if (ret < 0)
1081 return ret;
1082
1083 /*
1084 * All currently existing CEU implementations support 2560x1920
1085 * or larger frames. If the sensor is proposing too big a frame,
1086 * don't bother with possibly supportred by the CEU larger
1087 * sizes, just try VGA multiples. If needed, this can be
1088 * adjusted in the future.
1089 */
1090 while ((mf.width > pcdev->max_width ||
1091 mf.height > pcdev->max_height) && shift < 4) {
1092 /* Try 2560x1920, 1280x960, 640x480, 320x240 */
1093 mf.width = 2560 >> shift;
1094 mf.height = 1920 >> shift;
1095 ret = v4l2_device_call_until_err(sd->v4l2_dev,
1096 soc_camera_grp_id(icd), video,
1097 s_mbus_fmt, &mf);
1098 if (ret < 0)
1099 return ret;
1100 shift++;
1101 }
1102
1103 if (shift == 4) {
1104 dev_err(dev, "Failed to configure the client below %ux%x\n",
1105 mf.width, mf.height);
1106 return -EIO;
1107 }
1108
1109 dev_geo(dev, "camera fmt %ux%u\n", mf.width, mf.height);
1110
1111 cam = kzalloc(sizeof(*cam), GFP_KERNEL);
1112 if (!cam)
1113 return -ENOMEM;
1114
1115 /* We are called with current camera crop, initialise subrect with it */
1116 cam->rect = rect;
1117 cam->subrect = rect;
1118
1119 cam->width = mf.width;
1120 cam->height = mf.height;
1121
1122 icd->host_priv = cam;
1123 } else {
1124 cam = icd->host_priv;
1125 }
1126
1127 /* Beginning of a pass */
1128 if (!idx)
1129 cam->extra_fmt = NULL;
1130
1131 switch (code) {
1132 case V4L2_MBUS_FMT_UYVY8_2X8:
1133 case V4L2_MBUS_FMT_VYUY8_2X8:
1134 case V4L2_MBUS_FMT_YUYV8_2X8:
1135 case V4L2_MBUS_FMT_YVYU8_2X8:
1136 if (cam->extra_fmt)
1137 break;
1138
1139 /*
1140 * Our case is simple so far: for any of the above four camera
1141 * formats we add all our four synthesized NV* formats, so,
1142 * just marking the device with a single flag suffices. If
1143 * the format generation rules are more complex, you would have
1144 * to actually hang your already added / counted formats onto
1145 * the host_priv pointer and check whether the format you're
1146 * going to add now is already there.
1147 */
1148 cam->extra_fmt = sh_mobile_ceu_formats;
1149
1150 n = ARRAY_SIZE(sh_mobile_ceu_formats);
1151 formats += n;
1152 for (k = 0; xlate && k < n; k++) {
1153 xlate->host_fmt = &sh_mobile_ceu_formats[k];
1154 xlate->code = code;
1155 xlate++;
1156 dev_dbg(dev, "Providing format %s using code %d\n",
1157 sh_mobile_ceu_formats[k].name, code);
1158 }
1159 break;
1160 default:
1161 if (!sh_mobile_ceu_packing_supported(fmt))
1162 return 0;
1163 }
1164
1165 /* Generic pass-through */
1166 formats++;
1167 if (xlate) {
1168 xlate->host_fmt = fmt;
1169 xlate->code = code;
1170 xlate++;
1171 dev_dbg(dev, "Providing format %s in pass-through mode\n",
1172 fmt->name);
1173 }
1174
1175 return formats;
1176}
1177
1178static void sh_mobile_ceu_put_formats(struct soc_camera_device *icd)
1179{
1180 kfree(icd->host_priv);
1181 icd->host_priv = NULL;
1182}
1183
1184/* Check if any dimension of r1 is smaller than respective one of r2 */
1185static bool is_smaller(struct v4l2_rect *r1, struct v4l2_rect *r2)
1186{
1187 return r1->width < r2->width || r1->height < r2->height;
1188}
1189
1190/* Check if r1 fails to cover r2 */
1191static bool is_inside(struct v4l2_rect *r1, struct v4l2_rect *r2)
1192{
1193 return r1->left > r2->left || r1->top > r2->top ||
1194 r1->left + r1->width < r2->left + r2->width ||
1195 r1->top + r1->height < r2->top + r2->height;
1196}
1197
1198static unsigned int scale_down(unsigned int size, unsigned int scale)
1199{
1200 return (size * 4096 + scale / 2) / scale;
1201}
1202
1203static unsigned int calc_generic_scale(unsigned int input, unsigned int output)
1204{
1205 return (input * 4096 + output / 2) / output;
1206}
1207
1208/* Get and store current client crop */
1209static int client_g_rect(struct v4l2_subdev *sd, struct v4l2_rect *rect)
1210{
1211 struct v4l2_crop crop;
1212 struct v4l2_cropcap cap;
1213 int ret;
1214
1215 crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1216
1217 ret = v4l2_subdev_call(sd, video, g_crop, &crop);
1218 if (!ret) {
1219 *rect = crop.c;
1220 return ret;
1221 }
1222
1223 /* Camera driver doesn't support .g_crop(), assume default rectangle */
1224 cap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1225
1226 ret = v4l2_subdev_call(sd, video, cropcap, &cap);
1227 if (!ret)
1228 *rect = cap.defrect;
1229
1230 return ret;
1231}
1232
1233/* Client crop has changed, update our sub-rectangle to remain within the area */
1234static void update_subrect(struct sh_mobile_ceu_cam *cam)
1235{
1236 struct v4l2_rect *rect = &cam->rect, *subrect = &cam->subrect;
1237
1238 if (rect->width < subrect->width)
1239 subrect->width = rect->width;
1240
1241 if (rect->height < subrect->height)
1242 subrect->height = rect->height;
1243
1244 if (rect->left > subrect->left)
1245 subrect->left = rect->left;
1246 else if (rect->left + rect->width >
1247 subrect->left + subrect->width)
1248 subrect->left = rect->left + rect->width -
1249 subrect->width;
1250
1251 if (rect->top > subrect->top)
1252 subrect->top = rect->top;
1253 else if (rect->top + rect->height >
1254 subrect->top + subrect->height)
1255 subrect->top = rect->top + rect->height -
1256 subrect->height;
1257}
1258
1259/*
1260 * The common for both scaling and cropping iterative approach is:
1261 * 1. try if the client can produce exactly what requested by the user
1262 * 2. if (1) failed, try to double the client image until we get one big enough
1263 * 3. if (2) failed, try to request the maximum image
1264 */
1265static int client_s_crop(struct soc_camera_device *icd, struct v4l2_crop *crop,
1266 struct v4l2_crop *cam_crop)
1267{
1268 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1269 struct v4l2_rect *rect = &crop->c, *cam_rect = &cam_crop->c;
1270 struct device *dev = sd->v4l2_dev->dev;
1271 struct sh_mobile_ceu_cam *cam = icd->host_priv;
1272 struct v4l2_cropcap cap;
1273 int ret;
1274 unsigned int width, height;
1275
1276 v4l2_subdev_call(sd, video, s_crop, crop);
1277 ret = client_g_rect(sd, cam_rect);
1278 if (ret < 0)
1279 return ret;
1280
1281 /*
1282 * Now cam_crop contains the current camera input rectangle, and it must
1283 * be within camera cropcap bounds
1284 */
1285 if (!memcmp(rect, cam_rect, sizeof(*rect))) {
1286 /* Even if camera S_CROP failed, but camera rectangle matches */
1287 dev_dbg(dev, "Camera S_CROP successful for %dx%d@%d:%d\n",
1288 rect->width, rect->height, rect->left, rect->top);
1289 cam->rect = *cam_rect;
1290 return 0;
1291 }
1292
1293 /* Try to fix cropping, that camera hasn't managed to set */
1294 dev_geo(dev, "Fix camera S_CROP for %dx%d@%d:%d to %dx%d@%d:%d\n",
1295 cam_rect->width, cam_rect->height,
1296 cam_rect->left, cam_rect->top,
1297 rect->width, rect->height, rect->left, rect->top);
1298
1299 /* We need sensor maximum rectangle */
1300 ret = v4l2_subdev_call(sd, video, cropcap, &cap);
1301 if (ret < 0)
1302 return ret;
1303
1304 /* Put user requested rectangle within sensor bounds */
1305 soc_camera_limit_side(&rect->left, &rect->width, cap.bounds.left, 2,
1306 cap.bounds.width);
1307 soc_camera_limit_side(&rect->top, &rect->height, cap.bounds.top, 4,
1308 cap.bounds.height);
1309
1310 /*
1311 * Popular special case - some cameras can only handle fixed sizes like
1312 * QVGA, VGA,... Take care to avoid infinite loop.
1313 */
1314 width = max(cam_rect->width, 2);
1315 height = max(cam_rect->height, 2);
1316
1317 /*
1318 * Loop as long as sensor is not covering the requested rectangle and
1319 * is still within its bounds
1320 */
1321 while (!ret && (is_smaller(cam_rect, rect) ||
1322 is_inside(cam_rect, rect)) &&
1323 (cap.bounds.width > width || cap.bounds.height > height)) {
1324
1325 width *= 2;
1326 height *= 2;
1327
1328 cam_rect->width = width;
1329 cam_rect->height = height;
1330
1331 /*
1332 * We do not know what capabilities the camera has to set up
1333 * left and top borders. We could try to be smarter in iterating
1334 * them, e.g., if camera current left is to the right of the
1335 * target left, set it to the middle point between the current
1336 * left and minimum left. But that would add too much
1337 * complexity: we would have to iterate each border separately.
1338 * Instead we just drop to the left and top bounds.
1339 */
1340 if (cam_rect->left > rect->left)
1341 cam_rect->left = cap.bounds.left;
1342
1343 if (cam_rect->left + cam_rect->width < rect->left + rect->width)
1344 cam_rect->width = rect->left + rect->width -
1345 cam_rect->left;
1346
1347 if (cam_rect->top > rect->top)
1348 cam_rect->top = cap.bounds.top;
1349
1350 if (cam_rect->top + cam_rect->height < rect->top + rect->height)
1351 cam_rect->height = rect->top + rect->height -
1352 cam_rect->top;
1353
1354 v4l2_subdev_call(sd, video, s_crop, cam_crop);
1355 ret = client_g_rect(sd, cam_rect);
1356 dev_geo(dev, "Camera S_CROP %d for %dx%d@%d:%d\n", ret,
1357 cam_rect->width, cam_rect->height,
1358 cam_rect->left, cam_rect->top);
1359 }
1360
1361 /* S_CROP must not modify the rectangle */
1362 if (is_smaller(cam_rect, rect) || is_inside(cam_rect, rect)) {
1363 /*
1364 * The camera failed to configure a suitable cropping,
1365 * we cannot use the current rectangle, set to max
1366 */
1367 *cam_rect = cap.bounds;
1368 v4l2_subdev_call(sd, video, s_crop, cam_crop);
1369 ret = client_g_rect(sd, cam_rect);
1370 dev_geo(dev, "Camera S_CROP %d for max %dx%d@%d:%d\n", ret,
1371 cam_rect->width, cam_rect->height,
1372 cam_rect->left, cam_rect->top);
1373 }
1374
1375 if (!ret) {
1376 cam->rect = *cam_rect;
1377 update_subrect(cam);
1378 }
1379
1380 return ret;
1381}
1382
1383/* Iterative s_mbus_fmt, also updates cached client crop on success */
1384static int client_s_fmt(struct soc_camera_device *icd,
1385 struct v4l2_mbus_framefmt *mf, bool ceu_can_scale)
1386{
1387 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1388 struct sh_mobile_ceu_dev *pcdev = ici->priv;
1389 struct sh_mobile_ceu_cam *cam = icd->host_priv;
1390 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1391 struct device *dev = icd->parent;
1392 unsigned int width = mf->width, height = mf->height, tmp_w, tmp_h;
1393 unsigned int max_width, max_height;
1394 struct v4l2_cropcap cap;
1395 bool ceu_1to1;
1396 int ret;
1397
1398 ret = v4l2_device_call_until_err(sd->v4l2_dev,
1399 soc_camera_grp_id(icd), video,
1400 s_mbus_fmt, mf);
1401 if (ret < 0)
1402 return ret;
1403
1404 dev_geo(dev, "camera scaled to %ux%u\n", mf->width, mf->height);
1405
1406 if (width == mf->width && height == mf->height) {
1407 /* Perfect! The client has done it all. */
1408 ceu_1to1 = true;
1409 goto update_cache;
1410 }
1411
1412 ceu_1to1 = false;
1413 if (!ceu_can_scale)
1414 goto update_cache;
1415
1416 cap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1417
1418 ret = v4l2_subdev_call(sd, video, cropcap, &cap);
1419 if (ret < 0)
1420 return ret;
1421
1422 max_width = min(cap.bounds.width, pcdev->max_width);
1423 max_height = min(cap.bounds.height, pcdev->max_height);
1424
1425 /* Camera set a format, but geometry is not precise, try to improve */
1426 tmp_w = mf->width;
1427 tmp_h = mf->height;
1428
1429 /* width <= max_width && height <= max_height - guaranteed by try_fmt */
1430 while ((width > tmp_w || height > tmp_h) &&
1431 tmp_w < max_width && tmp_h < max_height) {
1432 tmp_w = min(2 * tmp_w, max_width);
1433 tmp_h = min(2 * tmp_h, max_height);
1434 mf->width = tmp_w;
1435 mf->height = tmp_h;
1436 ret = v4l2_device_call_until_err(sd->v4l2_dev,
1437 soc_camera_grp_id(icd), video,
1438 s_mbus_fmt, mf);
1439 dev_geo(dev, "Camera scaled to %ux%u\n",
1440 mf->width, mf->height);
1441 if (ret < 0) {
1442 /* This shouldn't happen */
1443 dev_err(dev, "Client failed to set format: %d\n", ret);
1444 return ret;
1445 }
1446 }
1447
1448update_cache:
1449 /* Update cache */
1450 ret = client_g_rect(sd, &cam->rect);
1451 if (ret < 0)
1452 return ret;
1453
1454 if (ceu_1to1)
1455 cam->subrect = cam->rect;
1456 else
1457 update_subrect(cam);
1458
1459 return 0;
1460}
1461
1462/**
1463 * @width - on output: user width, mapped back to input
1464 * @height - on output: user height, mapped back to input
1465 * @mf - in- / output camera output window
1466 */
1467static int client_scale(struct soc_camera_device *icd,
1468 struct v4l2_mbus_framefmt *mf,
1469 unsigned int *width, unsigned int *height,
1470 bool ceu_can_scale)
1471{
1472 struct sh_mobile_ceu_cam *cam = icd->host_priv;
1473 struct device *dev = icd->parent;
1474 struct v4l2_mbus_framefmt mf_tmp = *mf;
1475 unsigned int scale_h, scale_v;
1476 int ret;
1477
1478 /*
1479 * 5. Apply iterative camera S_FMT for camera user window (also updates
1480 * client crop cache and the imaginary sub-rectangle).
1481 */
1482 ret = client_s_fmt(icd, &mf_tmp, ceu_can_scale);
1483 if (ret < 0)
1484 return ret;
1485
1486 dev_geo(dev, "5: camera scaled to %ux%u\n",
1487 mf_tmp.width, mf_tmp.height);
1488
1489 /* 6. Retrieve camera output window (g_fmt) */
1490
1491 /* unneeded - it is already in "mf_tmp" */
1492
1493 /* 7. Calculate new client scales. */
1494 scale_h = calc_generic_scale(cam->rect.width, mf_tmp.width);
1495 scale_v = calc_generic_scale(cam->rect.height, mf_tmp.height);
1496
1497 mf->width = mf_tmp.width;
1498 mf->height = mf_tmp.height;
1499 mf->colorspace = mf_tmp.colorspace;
1500
1501 /*
1502 * 8. Calculate new CEU crop - apply camera scales to previously
1503 * updated "effective" crop.
1504 */
1505 *width = scale_down(cam->subrect.width, scale_h);
1506 *height = scale_down(cam->subrect.height, scale_v);
1507
1508 dev_geo(dev, "8: new client sub-window %ux%u\n", *width, *height);
1509
1510 return 0;
1511}
1512
1513/*
1514 * CEU can scale and crop, but we don't want to waste bandwidth and kill the
1515 * framerate by always requesting the maximum image from the client. See
1516 * Documentation/video4linux/sh_mobile_ceu_camera.txt for a description of
1517 * scaling and cropping algorithms and for the meaning of referenced here steps.
1518 */
1519static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd,
1520 struct v4l2_crop *a)
1521{
1522 struct v4l2_rect *rect = &a->c;
1523 struct device *dev = icd->parent;
1524 struct soc_camera_host *ici = to_soc_camera_host(dev);
1525 struct sh_mobile_ceu_dev *pcdev = ici->priv;
1526 struct v4l2_crop cam_crop;
1527 struct sh_mobile_ceu_cam *cam = icd->host_priv;
1528 struct v4l2_rect *cam_rect = &cam_crop.c;
1529 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1530 struct v4l2_mbus_framefmt mf;
1531 unsigned int scale_cam_h, scale_cam_v, scale_ceu_h, scale_ceu_v,
1532 out_width, out_height;
1533 int interm_width, interm_height;
1534 u32 capsr, cflcr;
1535 int ret;
1536
1537 dev_geo(dev, "S_CROP(%ux%u@%u:%u)\n", rect->width, rect->height,
1538 rect->left, rect->top);
1539
1540 /* During camera cropping its output window can change too, stop CEU */
1541 capsr = capture_save_reset(pcdev);
1542 dev_dbg(dev, "CAPSR 0x%x, CFLCR 0x%x\n", capsr, pcdev->cflcr);
1543
1544 /*
1545 * 1. - 2. Apply iterative camera S_CROP for new input window, read back
1546 * actual camera rectangle.
1547 */
1548 ret = client_s_crop(icd, a, &cam_crop);
1549 if (ret < 0)
1550 return ret;
1551
1552 dev_geo(dev, "1-2: camera cropped to %ux%u@%u:%u\n",
1553 cam_rect->width, cam_rect->height,
1554 cam_rect->left, cam_rect->top);
1555
1556 /* On success cam_crop contains current camera crop */
1557
1558 /* 3. Retrieve camera output window */
1559 ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf);
1560 if (ret < 0)
1561 return ret;
1562
1563 if (mf.width > pcdev->max_width || mf.height > pcdev->max_height)
1564 return -EINVAL;
1565
1566 /* 4. Calculate camera scales */
1567 scale_cam_h = calc_generic_scale(cam_rect->width, mf.width);
1568 scale_cam_v = calc_generic_scale(cam_rect->height, mf.height);
1569
1570 /* Calculate intermediate window */
1571 interm_width = scale_down(rect->width, scale_cam_h);
1572 interm_height = scale_down(rect->height, scale_cam_v);
1573
1574 if (interm_width < icd->user_width) {
1575 u32 new_scale_h;
1576
1577 new_scale_h = calc_generic_scale(rect->width, icd->user_width);
1578
1579 mf.width = scale_down(cam_rect->width, new_scale_h);
1580 }
1581
1582 if (interm_height < icd->user_height) {
1583 u32 new_scale_v;
1584
1585 new_scale_v = calc_generic_scale(rect->height, icd->user_height);
1586
1587 mf.height = scale_down(cam_rect->height, new_scale_v);
1588 }
1589
1590 if (interm_width < icd->user_width || interm_height < icd->user_height) {
1591 ret = v4l2_device_call_until_err(sd->v4l2_dev,
1592 soc_camera_grp_id(icd), video,
1593 s_mbus_fmt, &mf);
1594 if (ret < 0)
1595 return ret;
1596
1597 dev_geo(dev, "New camera output %ux%u\n", mf.width, mf.height);
1598 scale_cam_h = calc_generic_scale(cam_rect->width, mf.width);
1599 scale_cam_v = calc_generic_scale(cam_rect->height, mf.height);
1600 interm_width = scale_down(rect->width, scale_cam_h);
1601 interm_height = scale_down(rect->height, scale_cam_v);
1602 }
1603
1604 /* Cache camera output window */
1605 cam->width = mf.width;
1606 cam->height = mf.height;
1607
1608 if (pcdev->image_mode) {
1609 out_width = min(interm_width, icd->user_width);
1610 out_height = min(interm_height, icd->user_height);
1611 } else {
1612 out_width = interm_width;
1613 out_height = interm_height;
1614 }
1615
1616 /*
1617 * 5. Calculate CEU scales from camera scales from results of (5) and
1618 * the user window
1619 */
1620 scale_ceu_h = calc_scale(interm_width, &out_width);
1621 scale_ceu_v = calc_scale(interm_height, &out_height);
1622
1623 dev_geo(dev, "5: CEU scales %u:%u\n", scale_ceu_h, scale_ceu_v);
1624
1625 /* Apply CEU scales. */
1626 cflcr = scale_ceu_h | (scale_ceu_v << 16);
1627 if (cflcr != pcdev->cflcr) {
1628 pcdev->cflcr = cflcr;
1629 ceu_write(pcdev, CFLCR, cflcr);
1630 }
1631
1632 icd->user_width = out_width & ~3;
1633 icd->user_height = out_height & ~3;
1634 /* Offsets are applied at the CEU scaling filter input */
1635 cam->ceu_left = scale_down(rect->left - cam_rect->left, scale_cam_h) & ~1;
1636 cam->ceu_top = scale_down(rect->top - cam_rect->top, scale_cam_v) & ~1;
1637
1638 /* 6. Use CEU cropping to crop to the new window. */
1639 sh_mobile_ceu_set_rect(icd);
1640
1641 cam->subrect = *rect;
1642
1643 dev_geo(dev, "6: CEU cropped to %ux%u@%u:%u\n",
1644 icd->user_width, icd->user_height,
1645 cam->ceu_left, cam->ceu_top);
1646
1647 /* Restore capture. The CE bit can be cleared by the hardware */
1648 if (pcdev->active)
1649 capsr |= 1;
1650 capture_restore(pcdev, capsr);
1651
1652 /* Even if only camera cropping succeeded */
1653 return ret;
1654}
1655
1656static int sh_mobile_ceu_get_crop(struct soc_camera_device *icd,
1657 struct v4l2_crop *a)
1658{
1659 struct sh_mobile_ceu_cam *cam = icd->host_priv;
1660
1661 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1662 a->c = cam->subrect;
1663
1664 return 0;
1665}
1666
1667/*
1668 * Calculate real client output window by applying new scales to the current
1669 * client crop. New scales are calculated from the requested output format and
1670 * CEU crop, mapped backed onto the client input (subrect).
1671 */
1672static void calculate_client_output(struct soc_camera_device *icd,
1673 const struct v4l2_pix_format *pix, struct v4l2_mbus_framefmt *mf)
1674{
1675 struct sh_mobile_ceu_cam *cam = icd->host_priv;
1676 struct device *dev = icd->parent;
1677 struct v4l2_rect *cam_subrect = &cam->subrect;
1678 unsigned int scale_v, scale_h;
1679
1680 if (cam_subrect->width == cam->rect.width &&
1681 cam_subrect->height == cam->rect.height) {
1682 /* No sub-cropping */
1683 mf->width = pix->width;
1684 mf->height = pix->height;
1685 return;
1686 }
1687
1688 /* 1.-2. Current camera scales and subwin - cached. */
1689
1690 dev_geo(dev, "2: subwin %ux%u@%u:%u\n",
1691 cam_subrect->width, cam_subrect->height,
1692 cam_subrect->left, cam_subrect->top);
1693
1694 /*
1695 * 3. Calculate new combined scales from input sub-window to requested
1696 * user window.
1697 */
1698
1699 /*
1700 * TODO: CEU cannot scale images larger than VGA to smaller than SubQCIF
1701 * (128x96) or larger than VGA
1702 */
1703 scale_h = calc_generic_scale(cam_subrect->width, pix->width);
1704 scale_v = calc_generic_scale(cam_subrect->height, pix->height);
1705
1706 dev_geo(dev, "3: scales %u:%u\n", scale_h, scale_v);
1707
1708 /*
1709 * 4. Calculate desired client output window by applying combined scales
1710 * to client (real) input window.
1711 */
1712 mf->width = scale_down(cam->rect.width, scale_h);
1713 mf->height = scale_down(cam->rect.height, scale_v);
1714}
1715
1716/* Similar to set_crop multistage iterative algorithm */
1717static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd,
1718 struct v4l2_format *f)
1719{
1720 struct device *dev = icd->parent;
1721 struct soc_camera_host *ici = to_soc_camera_host(dev);
1722 struct sh_mobile_ceu_dev *pcdev = ici->priv;
1723 struct sh_mobile_ceu_cam *cam = icd->host_priv;
1724 struct v4l2_pix_format *pix = &f->fmt.pix;
1725 struct v4l2_mbus_framefmt mf;
1726 __u32 pixfmt = pix->pixelformat;
1727 const struct soc_camera_format_xlate *xlate;
1728 /* Keep Compiler Happy */
1729 unsigned int ceu_sub_width = 0, ceu_sub_height = 0;
1730 u16 scale_v, scale_h;
1731 int ret;
1732 bool image_mode;
1733 enum v4l2_field field;
1734
1735 switch (pix->field) {
1736 default:
1737 pix->field = V4L2_FIELD_NONE;
1738 /* fall-through */
1739 case V4L2_FIELD_INTERLACED_TB:
1740 case V4L2_FIELD_INTERLACED_BT:
1741 case V4L2_FIELD_NONE:
1742 field = pix->field;
1743 break;
1744 case V4L2_FIELD_INTERLACED:
1745 field = V4L2_FIELD_INTERLACED_TB;
1746 break;
1747 }
1748
1749 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
1750 if (!xlate) {
1751 dev_warn(dev, "Format %x not found\n", pixfmt);
1752 return -EINVAL;
1753 }
1754
1755 /* 1.-4. Calculate desired client output geometry */
1756 calculate_client_output(icd, pix, &mf);
1757 mf.field = pix->field;
1758 mf.colorspace = pix->colorspace;
1759 mf.code = xlate->code;
1760
1761 switch (pixfmt) {
1762 case V4L2_PIX_FMT_NV12:
1763 case V4L2_PIX_FMT_NV21:
1764 case V4L2_PIX_FMT_NV16:
1765 case V4L2_PIX_FMT_NV61:
1766 image_mode = true;
1767 break;
1768 default:
1769 image_mode = false;
1770 }
1771
1772 dev_geo(dev, "S_FMT(pix=0x%x, fld 0x%x, code 0x%x, %ux%u)\n", pixfmt, mf.field, mf.code,
1773 pix->width, pix->height);
1774
1775 dev_geo(dev, "4: request camera output %ux%u\n", mf.width, mf.height);
1776
1777 /* 5. - 9. */
1778 ret = client_scale(icd, &mf, &ceu_sub_width, &ceu_sub_height,
1779 image_mode && V4L2_FIELD_NONE == field);
1780
1781 dev_geo(dev, "5-9: client scale return %d\n", ret);
1782
1783 /* Done with the camera. Now see if we can improve the result */
1784
1785 dev_geo(dev, "fmt %ux%u, requested %ux%u\n",
1786 mf.width, mf.height, pix->width, pix->height);
1787 if (ret < 0)
1788 return ret;
1789
1790 if (mf.code != xlate->code)
1791 return -EINVAL;
1792
1793 /* 9. Prepare CEU crop */
1794 cam->width = mf.width;
1795 cam->height = mf.height;
1796
1797 /* 10. Use CEU scaling to scale to the requested user window. */
1798
1799 /* We cannot scale up */
1800 if (pix->width > ceu_sub_width)
1801 ceu_sub_width = pix->width;
1802
1803 if (pix->height > ceu_sub_height)
1804 ceu_sub_height = pix->height;
1805
1806 pix->colorspace = mf.colorspace;
1807
1808 if (image_mode) {
1809 /* Scale pix->{width x height} down to width x height */
1810 scale_h = calc_scale(ceu_sub_width, &pix->width);
1811 scale_v = calc_scale(ceu_sub_height, &pix->height);
1812 } else {
1813 pix->width = ceu_sub_width;
1814 pix->height = ceu_sub_height;
1815 scale_h = 0;
1816 scale_v = 0;
1817 }
1818
1819 pcdev->cflcr = scale_h | (scale_v << 16);
1820
1821 /*
1822 * We have calculated CFLCR, the actual configuration will be performed
1823 * in sh_mobile_ceu_set_bus_param()
1824 */
1825
1826 dev_geo(dev, "10: W: %u : 0x%x = %u, H: %u : 0x%x = %u\n",
1827 ceu_sub_width, scale_h, pix->width,
1828 ceu_sub_height, scale_v, pix->height);
1829
1830 cam->code = xlate->code;
1831 icd->current_fmt = xlate;
1832
1833 pcdev->field = field;
1834 pcdev->image_mode = image_mode;
1835
1836 /* CFSZR requirement */
1837 pix->width &= ~3;
1838 pix->height &= ~3;
1839
1840 return 0;
1841}
1842
1843#define CEU_CHDW_MAX 8188U /* Maximum line stride */
1844
1845static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd,
1846 struct v4l2_format *f)
1847{
1848 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1849 struct sh_mobile_ceu_dev *pcdev = ici->priv;
1850 const struct soc_camera_format_xlate *xlate;
1851 struct v4l2_pix_format *pix = &f->fmt.pix;
1852 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1853 struct v4l2_mbus_framefmt mf;
1854 __u32 pixfmt = pix->pixelformat;
1855 int width, height;
1856 int ret;
1857
1858 dev_geo(icd->parent, "TRY_FMT(pix=0x%x, %ux%u)\n",
1859 pixfmt, pix->width, pix->height);
1860
1861 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
1862 if (!xlate) {
1863 xlate = icd->current_fmt;
1864 dev_dbg(icd->parent, "Format %x not found, keeping %x\n",
1865 pixfmt, xlate->host_fmt->fourcc);
1866 pixfmt = xlate->host_fmt->fourcc;
1867 pix->pixelformat = pixfmt;
1868 pix->colorspace = icd->colorspace;
1869 }
1870
1871 /* FIXME: calculate using depth and bus width */
1872
1873 /* CFSZR requires height and width to be 4-pixel aligned */
1874 v4l_bound_align_image(&pix->width, 2, pcdev->max_width, 2,
1875 &pix->height, 4, pcdev->max_height, 2, 0);
1876
1877 width = pix->width;
1878 height = pix->height;
1879
1880 /* limit to sensor capabilities */
1881 mf.width = pix->width;
1882 mf.height = pix->height;
1883 mf.field = pix->field;
1884 mf.code = xlate->code;
1885 mf.colorspace = pix->colorspace;
1886
1887 ret = v4l2_device_call_until_err(sd->v4l2_dev, soc_camera_grp_id(icd),
1888 video, try_mbus_fmt, &mf);
1889 if (ret < 0)
1890 return ret;
1891
1892 pix->width = mf.width;
1893 pix->height = mf.height;
1894 pix->field = mf.field;
1895 pix->colorspace = mf.colorspace;
1896
1897 switch (pixfmt) {
1898 case V4L2_PIX_FMT_NV12:
1899 case V4L2_PIX_FMT_NV21:
1900 case V4L2_PIX_FMT_NV16:
1901 case V4L2_PIX_FMT_NV61:
1902 /* FIXME: check against rect_max after converting soc-camera */
1903 /* We can scale precisely, need a bigger image from camera */
1904 if (pix->width < width || pix->height < height) {
1905 /*
1906 * We presume, the sensor behaves sanely, i.e., if
1907 * requested a bigger rectangle, it will not return a
1908 * smaller one.
1909 */
1910 mf.width = pcdev->max_width;
1911 mf.height = pcdev->max_height;
1912 ret = v4l2_device_call_until_err(sd->v4l2_dev,
1913 soc_camera_grp_id(icd), video,
1914 try_mbus_fmt, &mf);
1915 if (ret < 0) {
1916 /* Shouldn't actually happen... */
1917 dev_err(icd->parent,
1918 "FIXME: client try_fmt() = %d\n", ret);
1919 return ret;
1920 }
1921 }
1922 /* We will scale exactly */
1923 if (mf.width > width)
1924 pix->width = width;
1925 if (mf.height > height)
1926 pix->height = height;
1927
1928 pix->bytesperline = max(pix->bytesperline, pix->width);
1929 pix->bytesperline = min(pix->bytesperline, CEU_CHDW_MAX);
1930 pix->bytesperline &= ~3;
1931 break;
1932
1933 default:
1934 /* Configurable stride isn't supported in pass-through mode. */
1935 pix->bytesperline = 0;
1936 }
1937
1938 pix->width &= ~3;
1939 pix->height &= ~3;
1940 pix->sizeimage = 0;
1941
1942 dev_geo(icd->parent, "%s(): return %d, fmt 0x%x, %ux%u\n",
1943 __func__, ret, pix->pixelformat, pix->width, pix->height);
1944
1945 return ret;
1946}
1947
1948static int sh_mobile_ceu_set_livecrop(struct soc_camera_device *icd,
1949 struct v4l2_crop *a)
1950{
1951 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1952 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1953 struct sh_mobile_ceu_dev *pcdev = ici->priv;
1954 u32 out_width = icd->user_width, out_height = icd->user_height;
1955 int ret;
1956
1957 /* Freeze queue */
1958 pcdev->frozen = 1;
1959 /* Wait for frame */
1960 ret = wait_for_completion_interruptible(&pcdev->complete);
1961 /* Stop the client */
1962 ret = v4l2_subdev_call(sd, video, s_stream, 0);
1963 if (ret < 0)
1964 dev_warn(icd->parent,
1965 "Client failed to stop the stream: %d\n", ret);
1966 else
1967 /* Do the crop, if it fails, there's nothing more we can do */
1968 sh_mobile_ceu_set_crop(icd, a);
1969
1970 dev_geo(icd->parent, "Output after crop: %ux%u\n", icd->user_width, icd->user_height);
1971
1972 if (icd->user_width != out_width || icd->user_height != out_height) {
1973 struct v4l2_format f = {
1974 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
1975 .fmt.pix = {
1976 .width = out_width,
1977 .height = out_height,
1978 .pixelformat = icd->current_fmt->host_fmt->fourcc,
1979 .field = pcdev->field,
1980 .colorspace = icd->colorspace,
1981 },
1982 };
1983 ret = sh_mobile_ceu_set_fmt(icd, &f);
1984 if (!ret && (out_width != f.fmt.pix.width ||
1985 out_height != f.fmt.pix.height))
1986 ret = -EINVAL;
1987 if (!ret) {
1988 icd->user_width = out_width & ~3;
1989 icd->user_height = out_height & ~3;
1990 ret = sh_mobile_ceu_set_bus_param(icd);
1991 }
1992 }
1993
1994 /* Thaw the queue */
1995 pcdev->frozen = 0;
1996 spin_lock_irq(&pcdev->lock);
1997 sh_mobile_ceu_capture(pcdev);
1998 spin_unlock_irq(&pcdev->lock);
1999 /* Start the client */
2000 ret = v4l2_subdev_call(sd, video, s_stream, 1);
2001 return ret;
2002}
2003
2004static unsigned int sh_mobile_ceu_poll(struct file *file, poll_table *pt)
2005{
2006 struct soc_camera_device *icd = file->private_data;
2007
2008 return vb2_poll(&icd->vb2_vidq, file, pt);
2009}
2010
2011static int sh_mobile_ceu_querycap(struct soc_camera_host *ici,
2012 struct v4l2_capability *cap)
2013{
2014 strlcpy(cap->card, "SuperH_Mobile_CEU", sizeof(cap->card));
2015 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
2016 return 0;
2017}
2018
2019static int sh_mobile_ceu_init_videobuf(struct vb2_queue *q,
2020 struct soc_camera_device *icd)
2021{
2022 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2023 q->io_modes = VB2_MMAP | VB2_USERPTR;
2024 q->drv_priv = icd;
2025 q->ops = &sh_mobile_ceu_videobuf_ops;
2026 q->mem_ops = &vb2_dma_contig_memops;
2027 q->buf_struct_size = sizeof(struct sh_mobile_ceu_buffer);
2028
2029 return vb2_queue_init(q);
2030}
2031
2032static struct soc_camera_host_ops sh_mobile_ceu_host_ops = {
2033 .owner = THIS_MODULE,
2034 .add = sh_mobile_ceu_add_device,
2035 .remove = sh_mobile_ceu_remove_device,
2036 .get_formats = sh_mobile_ceu_get_formats,
2037 .put_formats = sh_mobile_ceu_put_formats,
2038 .get_crop = sh_mobile_ceu_get_crop,
2039 .set_crop = sh_mobile_ceu_set_crop,
2040 .set_livecrop = sh_mobile_ceu_set_livecrop,
2041 .set_fmt = sh_mobile_ceu_set_fmt,
2042 .try_fmt = sh_mobile_ceu_try_fmt,
2043 .poll = sh_mobile_ceu_poll,
2044 .querycap = sh_mobile_ceu_querycap,
2045 .set_bus_param = sh_mobile_ceu_set_bus_param,
2046 .init_videobuf2 = sh_mobile_ceu_init_videobuf,
2047};
2048
2049struct bus_wait {
2050 struct notifier_block notifier;
2051 struct completion completion;
2052 struct device *dev;
2053};
2054
2055static int bus_notify(struct notifier_block *nb,
2056 unsigned long action, void *data)
2057{
2058 struct device *dev = data;
2059 struct bus_wait *wait = container_of(nb, struct bus_wait, notifier);
2060
2061 if (wait->dev != dev)
2062 return NOTIFY_DONE;
2063
2064 switch (action) {
2065 case BUS_NOTIFY_UNBOUND_DRIVER:
2066 /* Protect from module unloading */
2067 wait_for_completion(&wait->completion);
2068 return NOTIFY_OK;
2069 }
2070 return NOTIFY_DONE;
2071}
2072
2073static int __devinit sh_mobile_ceu_probe(struct platform_device *pdev)
2074{
2075 struct sh_mobile_ceu_dev *pcdev;
2076 struct resource *res;
2077 void __iomem *base;
2078 unsigned int irq;
2079 int err = 0;
2080 struct bus_wait wait = {
2081 .completion = COMPLETION_INITIALIZER_ONSTACK(wait.completion),
2082 .notifier.notifier_call = bus_notify,
2083 };
2084 struct sh_mobile_ceu_companion *csi2;
2085
2086 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2087 irq = platform_get_irq(pdev, 0);
2088 if (!res || (int)irq <= 0) {
2089 dev_err(&pdev->dev, "Not enough CEU platform resources.\n");
2090 err = -ENODEV;
2091 goto exit;
2092 }
2093
2094 pcdev = kzalloc(sizeof(*pcdev), GFP_KERNEL);
2095 if (!pcdev) {
2096 dev_err(&pdev->dev, "Could not allocate pcdev\n");
2097 err = -ENOMEM;
2098 goto exit;
2099 }
2100
2101 INIT_LIST_HEAD(&pcdev->capture);
2102 spin_lock_init(&pcdev->lock);
2103 init_completion(&pcdev->complete);
2104
2105 pcdev->pdata = pdev->dev.platform_data;
2106 if (!pcdev->pdata) {
2107 err = -EINVAL;
2108 dev_err(&pdev->dev, "CEU platform data not set.\n");
2109 goto exit_kfree;
2110 }
2111
2112 pcdev->max_width = pcdev->pdata->max_width ? : 2560;
2113 pcdev->max_height = pcdev->pdata->max_height ? : 1920;
2114
2115 base = ioremap_nocache(res->start, resource_size(res));
2116 if (!base) {
2117 err = -ENXIO;
2118 dev_err(&pdev->dev, "Unable to ioremap CEU registers.\n");
2119 goto exit_kfree;
2120 }
2121
2122 pcdev->irq = irq;
2123 pcdev->base = base;
2124 pcdev->video_limit = 0; /* only enabled if second resource exists */
2125
2126 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
2127 if (res) {
2128 err = dma_declare_coherent_memory(&pdev->dev, res->start,
2129 res->start,
2130 resource_size(res),
2131 DMA_MEMORY_MAP |
2132 DMA_MEMORY_EXCLUSIVE);
2133 if (!err) {
2134 dev_err(&pdev->dev, "Unable to declare CEU memory.\n");
2135 err = -ENXIO;
2136 goto exit_iounmap;
2137 }
2138
2139 pcdev->video_limit = resource_size(res);
2140 }
2141
2142 /* request irq */
2143 err = request_irq(pcdev->irq, sh_mobile_ceu_irq, IRQF_DISABLED,
2144 dev_name(&pdev->dev), pcdev);
2145 if (err) {
2146 dev_err(&pdev->dev, "Unable to register CEU interrupt.\n");
2147 goto exit_release_mem;
2148 }
2149
2150 pm_suspend_ignore_children(&pdev->dev, true);
2151 pm_runtime_enable(&pdev->dev);
2152 pm_runtime_resume(&pdev->dev);
2153
2154 pcdev->ici.priv = pcdev;
2155 pcdev->ici.v4l2_dev.dev = &pdev->dev;
2156 pcdev->ici.nr = pdev->id;
2157 pcdev->ici.drv_name = dev_name(&pdev->dev);
2158 pcdev->ici.ops = &sh_mobile_ceu_host_ops;
2159 pcdev->ici.capabilities = SOCAM_HOST_CAP_STRIDE;
2160
2161 pcdev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
2162 if (IS_ERR(pcdev->alloc_ctx)) {
2163 err = PTR_ERR(pcdev->alloc_ctx);
2164 goto exit_free_clk;
2165 }
2166
2167 err = soc_camera_host_register(&pcdev->ici);
2168 if (err)
2169 goto exit_free_ctx;
2170
2171 /* CSI2 interfacing */
2172 csi2 = pcdev->pdata->csi2;
2173 if (csi2) {
2174 struct platform_device *csi2_pdev =
2175 platform_device_alloc("sh-mobile-csi2", csi2->id);
2176 struct sh_csi2_pdata *csi2_pdata = csi2->platform_data;
2177
2178 if (!csi2_pdev) {
2179 err = -ENOMEM;
2180 goto exit_host_unregister;
2181 }
2182
2183 pcdev->csi2_pdev = csi2_pdev;
2184
2185 err = platform_device_add_data(csi2_pdev, csi2_pdata, sizeof(*csi2_pdata));
2186 if (err < 0)
2187 goto exit_pdev_put;
2188
2189 csi2_pdata = csi2_pdev->dev.platform_data;
2190 csi2_pdata->v4l2_dev = &pcdev->ici.v4l2_dev;
2191
2192 csi2_pdev->resource = csi2->resource;
2193 csi2_pdev->num_resources = csi2->num_resources;
2194
2195 err = platform_device_add(csi2_pdev);
2196 if (err < 0)
2197 goto exit_pdev_put;
2198
2199 wait.dev = &csi2_pdev->dev;
2200
2201 err = bus_register_notifier(&platform_bus_type, &wait.notifier);
2202 if (err < 0)
2203 goto exit_pdev_unregister;
2204
2205 /*
2206 * From this point the driver module will not unload, until
2207 * we complete the completion.
2208 */
2209
2210 if (!csi2_pdev->dev.driver) {
2211 complete(&wait.completion);
2212 /* Either too late, or probing failed */
2213 bus_unregister_notifier(&platform_bus_type, &wait.notifier);
2214 err = -ENXIO;
2215 goto exit_pdev_unregister;
2216 }
2217
2218 /*
2219 * The module is still loaded, in the worst case it is hanging
2220 * in device release on our completion. So, _now_ dereferencing
2221 * the "owner" is safe!
2222 */
2223
2224 err = try_module_get(csi2_pdev->dev.driver->owner);
2225
2226 /* Let notifier complete, if it has been locked */
2227 complete(&wait.completion);
2228 bus_unregister_notifier(&platform_bus_type, &wait.notifier);
2229 if (!err) {
2230 err = -ENODEV;
2231 goto exit_pdev_unregister;
2232 }
2233 }
2234
2235 return 0;
2236
2237exit_pdev_unregister:
2238 platform_device_del(pcdev->csi2_pdev);
2239exit_pdev_put:
2240 pcdev->csi2_pdev->resource = NULL;
2241 platform_device_put(pcdev->csi2_pdev);
2242exit_host_unregister:
2243 soc_camera_host_unregister(&pcdev->ici);
2244exit_free_ctx:
2245 vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx);
2246exit_free_clk:
2247 pm_runtime_disable(&pdev->dev);
2248 free_irq(pcdev->irq, pcdev);
2249exit_release_mem:
2250 if (platform_get_resource(pdev, IORESOURCE_MEM, 1))
2251 dma_release_declared_memory(&pdev->dev);
2252exit_iounmap:
2253 iounmap(base);
2254exit_kfree:
2255 kfree(pcdev);
2256exit:
2257 return err;
2258}
2259
2260static int __devexit sh_mobile_ceu_remove(struct platform_device *pdev)
2261{
2262 struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev);
2263 struct sh_mobile_ceu_dev *pcdev = container_of(soc_host,
2264 struct sh_mobile_ceu_dev, ici);
2265 struct platform_device *csi2_pdev = pcdev->csi2_pdev;
2266
2267 soc_camera_host_unregister(soc_host);
2268 pm_runtime_disable(&pdev->dev);
2269 free_irq(pcdev->irq, pcdev);
2270 if (platform_get_resource(pdev, IORESOURCE_MEM, 1))
2271 dma_release_declared_memory(&pdev->dev);
2272 iounmap(pcdev->base);
2273 vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx);
2274 if (csi2_pdev && csi2_pdev->dev.driver) {
2275 struct module *csi2_drv = csi2_pdev->dev.driver->owner;
2276 platform_device_del(csi2_pdev);
2277 csi2_pdev->resource = NULL;
2278 platform_device_put(csi2_pdev);
2279 module_put(csi2_drv);
2280 }
2281 kfree(pcdev);
2282
2283 return 0;
2284}
2285
2286static int sh_mobile_ceu_runtime_nop(struct device *dev)
2287{
2288 /* Runtime PM callback shared between ->runtime_suspend()
2289 * and ->runtime_resume(). Simply returns success.
2290 *
2291 * This driver re-initializes all registers after
2292 * pm_runtime_get_sync() anyway so there is no need
2293 * to save and restore registers here.
2294 */
2295 return 0;
2296}
2297
2298static const struct dev_pm_ops sh_mobile_ceu_dev_pm_ops = {
2299 .runtime_suspend = sh_mobile_ceu_runtime_nop,
2300 .runtime_resume = sh_mobile_ceu_runtime_nop,
2301};
2302
2303static struct platform_driver sh_mobile_ceu_driver = {
2304 .driver = {
2305 .name = "sh_mobile_ceu",
2306 .pm = &sh_mobile_ceu_dev_pm_ops,
2307 },
2308 .probe = sh_mobile_ceu_probe,
2309 .remove = __devexit_p(sh_mobile_ceu_remove),
2310};
2311
2312static int __init sh_mobile_ceu_init(void)
2313{
2314 /* Whatever return code */
2315 request_module("sh_mobile_csi2");
2316 return platform_driver_register(&sh_mobile_ceu_driver);
2317}
2318
2319static void __exit sh_mobile_ceu_exit(void)
2320{
2321 platform_driver_unregister(&sh_mobile_ceu_driver);
2322}
2323
2324module_init(sh_mobile_ceu_init);
2325module_exit(sh_mobile_ceu_exit);
2326
2327MODULE_DESCRIPTION("SuperH Mobile CEU driver");
2328MODULE_AUTHOR("Magnus Damm");
2329MODULE_LICENSE("GPL");
2330MODULE_VERSION("0.0.6");
2331MODULE_ALIAS("platform:sh_mobile_ceu");
diff --git a/drivers/media/video/sh_vou.c b/drivers/media/video/sh_vou.c
deleted file mode 100644
index 9f62fd89ab57..000000000000
--- a/drivers/media/video/sh_vou.c
+++ /dev/null
@@ -1,1510 +0,0 @@
1/*
2 * SuperH Video Output Unit (VOU) driver
3 *
4 * Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/dma-mapping.h>
12#include <linux/delay.h>
13#include <linux/errno.h>
14#include <linux/fs.h>
15#include <linux/i2c.h>
16#include <linux/init.h>
17#include <linux/interrupt.h>
18#include <linux/kernel.h>
19#include <linux/platform_device.h>
20#include <linux/pm_runtime.h>
21#include <linux/slab.h>
22#include <linux/videodev2.h>
23#include <linux/module.h>
24
25#include <media/sh_vou.h>
26#include <media/v4l2-common.h>
27#include <media/v4l2-device.h>
28#include <media/v4l2-ioctl.h>
29#include <media/v4l2-mediabus.h>
30#include <media/videobuf-dma-contig.h>
31
32/* Mirror addresses are not available for all registers */
33#define VOUER 0
34#define VOUCR 4
35#define VOUSTR 8
36#define VOUVCR 0xc
37#define VOUISR 0x10
38#define VOUBCR 0x14
39#define VOUDPR 0x18
40#define VOUDSR 0x1c
41#define VOUVPR 0x20
42#define VOUIR 0x24
43#define VOUSRR 0x28
44#define VOUMSR 0x2c
45#define VOUHIR 0x30
46#define VOUDFR 0x34
47#define VOUAD1R 0x38
48#define VOUAD2R 0x3c
49#define VOUAIR 0x40
50#define VOUSWR 0x44
51#define VOURCR 0x48
52#define VOURPR 0x50
53
54enum sh_vou_status {
55 SH_VOU_IDLE,
56 SH_VOU_INITIALISING,
57 SH_VOU_RUNNING,
58};
59
60#define VOU_MAX_IMAGE_WIDTH 720
61#define VOU_MAX_IMAGE_HEIGHT 576
62
63struct sh_vou_device {
64 struct v4l2_device v4l2_dev;
65 struct video_device *vdev;
66 atomic_t use_count;
67 struct sh_vou_pdata *pdata;
68 spinlock_t lock;
69 void __iomem *base;
70 /* State information */
71 struct v4l2_pix_format pix;
72 struct v4l2_rect rect;
73 struct list_head queue;
74 v4l2_std_id std;
75 int pix_idx;
76 struct videobuf_buffer *active;
77 enum sh_vou_status status;
78 struct mutex fop_lock;
79};
80
81struct sh_vou_file {
82 struct videobuf_queue vbq;
83};
84
85/* Register access routines for sides A, B and mirror addresses */
86static void sh_vou_reg_a_write(struct sh_vou_device *vou_dev, unsigned int reg,
87 u32 value)
88{
89 __raw_writel(value, vou_dev->base + reg);
90}
91
92static void sh_vou_reg_ab_write(struct sh_vou_device *vou_dev, unsigned int reg,
93 u32 value)
94{
95 __raw_writel(value, vou_dev->base + reg);
96 __raw_writel(value, vou_dev->base + reg + 0x1000);
97}
98
99static void sh_vou_reg_m_write(struct sh_vou_device *vou_dev, unsigned int reg,
100 u32 value)
101{
102 __raw_writel(value, vou_dev->base + reg + 0x2000);
103}
104
105static u32 sh_vou_reg_a_read(struct sh_vou_device *vou_dev, unsigned int reg)
106{
107 return __raw_readl(vou_dev->base + reg);
108}
109
110static void sh_vou_reg_a_set(struct sh_vou_device *vou_dev, unsigned int reg,
111 u32 value, u32 mask)
112{
113 u32 old = __raw_readl(vou_dev->base + reg);
114
115 value = (value & mask) | (old & ~mask);
116 __raw_writel(value, vou_dev->base + reg);
117}
118
119static void sh_vou_reg_b_set(struct sh_vou_device *vou_dev, unsigned int reg,
120 u32 value, u32 mask)
121{
122 sh_vou_reg_a_set(vou_dev, reg + 0x1000, value, mask);
123}
124
125static void sh_vou_reg_ab_set(struct sh_vou_device *vou_dev, unsigned int reg,
126 u32 value, u32 mask)
127{
128 sh_vou_reg_a_set(vou_dev, reg, value, mask);
129 sh_vou_reg_b_set(vou_dev, reg, value, mask);
130}
131
132struct sh_vou_fmt {
133 u32 pfmt;
134 char *desc;
135 unsigned char bpp;
136 unsigned char rgb;
137 unsigned char yf;
138 unsigned char pkf;
139};
140
141/* Further pixel formats can be added */
142static struct sh_vou_fmt vou_fmt[] = {
143 {
144 .pfmt = V4L2_PIX_FMT_NV12,
145 .bpp = 12,
146 .desc = "YVU420 planar",
147 .yf = 0,
148 .rgb = 0,
149 },
150 {
151 .pfmt = V4L2_PIX_FMT_NV16,
152 .bpp = 16,
153 .desc = "YVYU planar",
154 .yf = 1,
155 .rgb = 0,
156 },
157 {
158 .pfmt = V4L2_PIX_FMT_RGB24,
159 .bpp = 24,
160 .desc = "RGB24",
161 .pkf = 2,
162 .rgb = 1,
163 },
164 {
165 .pfmt = V4L2_PIX_FMT_RGB565,
166 .bpp = 16,
167 .desc = "RGB565",
168 .pkf = 3,
169 .rgb = 1,
170 },
171 {
172 .pfmt = V4L2_PIX_FMT_RGB565X,
173 .bpp = 16,
174 .desc = "RGB565 byteswapped",
175 .pkf = 3,
176 .rgb = 1,
177 },
178};
179
180static void sh_vou_schedule_next(struct sh_vou_device *vou_dev,
181 struct videobuf_buffer *vb)
182{
183 dma_addr_t addr1, addr2;
184
185 addr1 = videobuf_to_dma_contig(vb);
186 switch (vou_dev->pix.pixelformat) {
187 case V4L2_PIX_FMT_NV12:
188 case V4L2_PIX_FMT_NV16:
189 addr2 = addr1 + vou_dev->pix.width * vou_dev->pix.height;
190 break;
191 default:
192 addr2 = 0;
193 }
194
195 sh_vou_reg_m_write(vou_dev, VOUAD1R, addr1);
196 sh_vou_reg_m_write(vou_dev, VOUAD2R, addr2);
197}
198
199static void sh_vou_stream_start(struct sh_vou_device *vou_dev,
200 struct videobuf_buffer *vb)
201{
202 unsigned int row_coeff;
203#ifdef __LITTLE_ENDIAN
204 u32 dataswap = 7;
205#else
206 u32 dataswap = 0;
207#endif
208
209 switch (vou_dev->pix.pixelformat) {
210 case V4L2_PIX_FMT_NV12:
211 case V4L2_PIX_FMT_NV16:
212 row_coeff = 1;
213 break;
214 case V4L2_PIX_FMT_RGB565:
215 dataswap ^= 1;
216 case V4L2_PIX_FMT_RGB565X:
217 row_coeff = 2;
218 break;
219 case V4L2_PIX_FMT_RGB24:
220 row_coeff = 3;
221 break;
222 }
223
224 sh_vou_reg_a_write(vou_dev, VOUSWR, dataswap);
225 sh_vou_reg_ab_write(vou_dev, VOUAIR, vou_dev->pix.width * row_coeff);
226 sh_vou_schedule_next(vou_dev, vb);
227}
228
229static void free_buffer(struct videobuf_queue *vq, struct videobuf_buffer *vb)
230{
231 BUG_ON(in_interrupt());
232
233 /* Wait until this buffer is no longer in STATE_QUEUED or STATE_ACTIVE */
234 videobuf_waiton(vq, vb, 0, 0);
235 videobuf_dma_contig_free(vq, vb);
236 vb->state = VIDEOBUF_NEEDS_INIT;
237}
238
239/* Locking: caller holds fop_lock mutex */
240static int sh_vou_buf_setup(struct videobuf_queue *vq, unsigned int *count,
241 unsigned int *size)
242{
243 struct video_device *vdev = vq->priv_data;
244 struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
245
246 *size = vou_fmt[vou_dev->pix_idx].bpp * vou_dev->pix.width *
247 vou_dev->pix.height / 8;
248
249 if (*count < 2)
250 *count = 2;
251
252 /* Taking into account maximum frame size, *count will stay >= 2 */
253 if (PAGE_ALIGN(*size) * *count > 4 * 1024 * 1024)
254 *count = 4 * 1024 * 1024 / PAGE_ALIGN(*size);
255
256 dev_dbg(vq->dev, "%s(): count=%d, size=%d\n", __func__, *count, *size);
257
258 return 0;
259}
260
261/* Locking: caller holds fop_lock mutex */
262static int sh_vou_buf_prepare(struct videobuf_queue *vq,
263 struct videobuf_buffer *vb,
264 enum v4l2_field field)
265{
266 struct video_device *vdev = vq->priv_data;
267 struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
268 struct v4l2_pix_format *pix = &vou_dev->pix;
269 int bytes_per_line = vou_fmt[vou_dev->pix_idx].bpp * pix->width / 8;
270 int ret;
271
272 dev_dbg(vq->dev, "%s()\n", __func__);
273
274 if (vb->width != pix->width ||
275 vb->height != pix->height ||
276 vb->field != pix->field) {
277 vb->width = pix->width;
278 vb->height = pix->height;
279 vb->field = field;
280 if (vb->state != VIDEOBUF_NEEDS_INIT)
281 free_buffer(vq, vb);
282 }
283
284 vb->size = vb->height * bytes_per_line;
285 if (vb->baddr && vb->bsize < vb->size) {
286 /* User buffer too small */
287 dev_warn(vq->dev, "User buffer too small: [%u] @ %lx\n",
288 vb->bsize, vb->baddr);
289 return -EINVAL;
290 }
291
292 if (vb->state == VIDEOBUF_NEEDS_INIT) {
293 ret = videobuf_iolock(vq, vb, NULL);
294 if (ret < 0) {
295 dev_warn(vq->dev, "IOLOCK buf-type %d: %d\n",
296 vb->memory, ret);
297 return ret;
298 }
299 vb->state = VIDEOBUF_PREPARED;
300 }
301
302 dev_dbg(vq->dev,
303 "%s(): fmt #%d, %u bytes per line, phys 0x%x, type %d, state %d\n",
304 __func__, vou_dev->pix_idx, bytes_per_line,
305 videobuf_to_dma_contig(vb), vb->memory, vb->state);
306
307 return 0;
308}
309
310/* Locking: caller holds fop_lock mutex and vq->irqlock spinlock */
311static void sh_vou_buf_queue(struct videobuf_queue *vq,
312 struct videobuf_buffer *vb)
313{
314 struct video_device *vdev = vq->priv_data;
315 struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
316
317 dev_dbg(vq->dev, "%s()\n", __func__);
318
319 vb->state = VIDEOBUF_QUEUED;
320 list_add_tail(&vb->queue, &vou_dev->queue);
321
322 if (vou_dev->status == SH_VOU_RUNNING) {
323 return;
324 } else if (!vou_dev->active) {
325 vou_dev->active = vb;
326 /* Start from side A: we use mirror addresses, so, set B */
327 sh_vou_reg_a_write(vou_dev, VOURPR, 1);
328 dev_dbg(vq->dev, "%s: first buffer status 0x%x\n", __func__,
329 sh_vou_reg_a_read(vou_dev, VOUSTR));
330 sh_vou_schedule_next(vou_dev, vb);
331 /* Only activate VOU after the second buffer */
332 } else if (vou_dev->active->queue.next == &vb->queue) {
333 /* Second buffer - initialise register side B */
334 sh_vou_reg_a_write(vou_dev, VOURPR, 0);
335 sh_vou_stream_start(vou_dev, vb);
336
337 /* Register side switching with frame VSYNC */
338 sh_vou_reg_a_write(vou_dev, VOURCR, 5);
339 dev_dbg(vq->dev, "%s: second buffer status 0x%x\n", __func__,
340 sh_vou_reg_a_read(vou_dev, VOUSTR));
341
342 /* Enable End-of-Frame (VSYNC) interrupts */
343 sh_vou_reg_a_write(vou_dev, VOUIR, 0x10004);
344 /* Two buffers on the queue - activate the hardware */
345
346 vou_dev->status = SH_VOU_RUNNING;
347 sh_vou_reg_a_write(vou_dev, VOUER, 0x107);
348 }
349}
350
351static void sh_vou_buf_release(struct videobuf_queue *vq,
352 struct videobuf_buffer *vb)
353{
354 struct video_device *vdev = vq->priv_data;
355 struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
356 unsigned long flags;
357
358 dev_dbg(vq->dev, "%s()\n", __func__);
359
360 spin_lock_irqsave(&vou_dev->lock, flags);
361
362 if (vou_dev->active == vb) {
363 /* disable output */
364 sh_vou_reg_a_set(vou_dev, VOUER, 0, 1);
365 /* ...but the current frame will complete */
366 sh_vou_reg_a_set(vou_dev, VOUIR, 0, 0x30000);
367 vou_dev->active = NULL;
368 }
369
370 if ((vb->state == VIDEOBUF_ACTIVE || vb->state == VIDEOBUF_QUEUED)) {
371 vb->state = VIDEOBUF_ERROR;
372 list_del(&vb->queue);
373 }
374
375 spin_unlock_irqrestore(&vou_dev->lock, flags);
376
377 free_buffer(vq, vb);
378}
379
380static struct videobuf_queue_ops sh_vou_video_qops = {
381 .buf_setup = sh_vou_buf_setup,
382 .buf_prepare = sh_vou_buf_prepare,
383 .buf_queue = sh_vou_buf_queue,
384 .buf_release = sh_vou_buf_release,
385};
386
387/* Video IOCTLs */
388static int sh_vou_querycap(struct file *file, void *priv,
389 struct v4l2_capability *cap)
390{
391 struct sh_vou_file *vou_file = priv;
392
393 dev_dbg(vou_file->vbq.dev, "%s()\n", __func__);
394
395 strlcpy(cap->card, "SuperH VOU", sizeof(cap->card));
396 cap->capabilities = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
397 return 0;
398}
399
400/* Enumerate formats, that the device can accept from the user */
401static int sh_vou_enum_fmt_vid_out(struct file *file, void *priv,
402 struct v4l2_fmtdesc *fmt)
403{
404 struct sh_vou_file *vou_file = priv;
405
406 if (fmt->index >= ARRAY_SIZE(vou_fmt))
407 return -EINVAL;
408
409 dev_dbg(vou_file->vbq.dev, "%s()\n", __func__);
410
411 fmt->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
412 strlcpy(fmt->description, vou_fmt[fmt->index].desc,
413 sizeof(fmt->description));
414 fmt->pixelformat = vou_fmt[fmt->index].pfmt;
415
416 return 0;
417}
418
419static int sh_vou_g_fmt_vid_out(struct file *file, void *priv,
420 struct v4l2_format *fmt)
421{
422 struct video_device *vdev = video_devdata(file);
423 struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
424
425 dev_dbg(vou_dev->v4l2_dev.dev, "%s()\n", __func__);
426
427 fmt->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
428 fmt->fmt.pix = vou_dev->pix;
429
430 return 0;
431}
432
433static const unsigned char vou_scale_h_num[] = {1, 9, 2, 9, 4};
434static const unsigned char vou_scale_h_den[] = {1, 8, 1, 4, 1};
435static const unsigned char vou_scale_h_fld[] = {0, 2, 1, 3};
436static const unsigned char vou_scale_v_num[] = {1, 2, 4};
437static const unsigned char vou_scale_v_den[] = {1, 1, 1};
438static const unsigned char vou_scale_v_fld[] = {0, 1};
439
440static void sh_vou_configure_geometry(struct sh_vou_device *vou_dev,
441 int pix_idx, int w_idx, int h_idx)
442{
443 struct sh_vou_fmt *fmt = vou_fmt + pix_idx;
444 unsigned int black_left, black_top, width_max, height_max,
445 frame_in_height, frame_out_height, frame_out_top;
446 struct v4l2_rect *rect = &vou_dev->rect;
447 struct v4l2_pix_format *pix = &vou_dev->pix;
448 u32 vouvcr = 0, dsr_h, dsr_v;
449
450 if (vou_dev->std & V4L2_STD_525_60) {
451 width_max = 858;
452 height_max = 262;
453 } else {
454 width_max = 864;
455 height_max = 312;
456 }
457
458 frame_in_height = pix->height / 2;
459 frame_out_height = rect->height / 2;
460 frame_out_top = rect->top / 2;
461
462 /*
463 * Cropping scheme: max useful image is 720x480, and the total video
464 * area is 858x525 (NTSC) or 864x625 (PAL). AK8813 / 8814 starts
465 * sampling data beginning with fixed 276th (NTSC) / 288th (PAL) clock,
466 * of which the first 33 / 25 clocks HSYNC must be held active. This
467 * has to be configured in CR[HW]. 1 pixel equals 2 clock periods.
468 * This gives CR[HW] = 16 / 12, VPR[HVP] = 138 / 144, which gives
469 * exactly 858 - 138 = 864 - 144 = 720! We call the out-of-display area,
470 * beyond DSR, specified on the left and top by the VPR register "black
471 * pixels" and out-of-image area (DPR) "background pixels." We fix VPR
472 * at 138 / 144 : 20, because that's the HSYNC timing, that our first
473 * client requires, and that's exactly what leaves us 720 pixels for the
474 * image; we leave VPR[VVP] at default 20 for now, because the client
475 * doesn't seem to have any special requirements for it. Otherwise we
476 * could also set it to max - 240 = 22 / 72. Thus VPR depends only on
477 * the selected standard, and DPR and DSR are selected according to
478 * cropping. Q: how does the client detect the first valid line? Does
479 * HSYNC stay inactive during invalid (black) lines?
480 */
481 black_left = width_max - VOU_MAX_IMAGE_WIDTH;
482 black_top = 20;
483
484 dsr_h = rect->width + rect->left;
485 dsr_v = frame_out_height + frame_out_top;
486
487 dev_dbg(vou_dev->v4l2_dev.dev,
488 "image %ux%u, black %u:%u, offset %u:%u, display %ux%u\n",
489 pix->width, frame_in_height, black_left, black_top,
490 rect->left, frame_out_top, dsr_h, dsr_v);
491
492 /* VOUISR height - half of a frame height in frame mode */
493 sh_vou_reg_ab_write(vou_dev, VOUISR, (pix->width << 16) | frame_in_height);
494 sh_vou_reg_ab_write(vou_dev, VOUVPR, (black_left << 16) | black_top);
495 sh_vou_reg_ab_write(vou_dev, VOUDPR, (rect->left << 16) | frame_out_top);
496 sh_vou_reg_ab_write(vou_dev, VOUDSR, (dsr_h << 16) | dsr_v);
497
498 /*
499 * if necessary, we could set VOUHIR to
500 * max(black_left + dsr_h, width_max) here
501 */
502
503 if (w_idx)
504 vouvcr |= (1 << 15) | (vou_scale_h_fld[w_idx - 1] << 4);
505 if (h_idx)
506 vouvcr |= (1 << 14) | vou_scale_v_fld[h_idx - 1];
507
508 dev_dbg(vou_dev->v4l2_dev.dev, "%s: scaling 0x%x\n", fmt->desc, vouvcr);
509
510 /* To produce a colour bar for testing set bit 23 of VOUVCR */
511 sh_vou_reg_ab_write(vou_dev, VOUVCR, vouvcr);
512 sh_vou_reg_ab_write(vou_dev, VOUDFR,
513 fmt->pkf | (fmt->yf << 8) | (fmt->rgb << 16));
514}
515
516struct sh_vou_geometry {
517 struct v4l2_rect output;
518 unsigned int in_width;
519 unsigned int in_height;
520 int scale_idx_h;
521 int scale_idx_v;
522};
523
524/*
525 * Find input geometry, that we can use to produce output, closest to the
526 * requested rectangle, using VOU scaling
527 */
528static void vou_adjust_input(struct sh_vou_geometry *geo, v4l2_std_id std)
529{
530 /* The compiler cannot know, that best and idx will indeed be set */
531 unsigned int best_err = UINT_MAX, best = 0, img_height_max;
532 int i, idx = 0;
533
534 if (std & V4L2_STD_525_60)
535 img_height_max = 480;
536 else
537 img_height_max = 576;
538
539 /* Image width must be a multiple of 4 */
540 v4l_bound_align_image(&geo->in_width, 0, VOU_MAX_IMAGE_WIDTH, 2,
541 &geo->in_height, 0, img_height_max, 1, 0);
542
543 /* Select scales to come as close as possible to the output image */
544 for (i = ARRAY_SIZE(vou_scale_h_num) - 1; i >= 0; i--) {
545 unsigned int err;
546 unsigned int found = geo->output.width * vou_scale_h_den[i] /
547 vou_scale_h_num[i];
548
549 if (found > VOU_MAX_IMAGE_WIDTH)
550 /* scales increase */
551 break;
552
553 err = abs(found - geo->in_width);
554 if (err < best_err) {
555 best_err = err;
556 idx = i;
557 best = found;
558 }
559 if (!err)
560 break;
561 }
562
563 geo->in_width = best;
564 geo->scale_idx_h = idx;
565
566 best_err = UINT_MAX;
567
568 /* This loop can be replaced with one division */
569 for (i = ARRAY_SIZE(vou_scale_v_num) - 1; i >= 0; i--) {
570 unsigned int err;
571 unsigned int found = geo->output.height * vou_scale_v_den[i] /
572 vou_scale_v_num[i];
573
574 if (found > img_height_max)
575 /* scales increase */
576 break;
577
578 err = abs(found - geo->in_height);
579 if (err < best_err) {
580 best_err = err;
581 idx = i;
582 best = found;
583 }
584 if (!err)
585 break;
586 }
587
588 geo->in_height = best;
589 geo->scale_idx_v = idx;
590}
591
592/*
593 * Find output geometry, that we can produce, using VOU scaling, closest to
594 * the requested rectangle
595 */
596static void vou_adjust_output(struct sh_vou_geometry *geo, v4l2_std_id std)
597{
598 unsigned int best_err = UINT_MAX, best, width_max, height_max,
599 img_height_max;
600 int i, idx;
601
602 if (std & V4L2_STD_525_60) {
603 width_max = 858;
604 height_max = 262 * 2;
605 img_height_max = 480;
606 } else {
607 width_max = 864;
608 height_max = 312 * 2;
609 img_height_max = 576;
610 }
611
612 /* Select scales to come as close as possible to the output image */
613 for (i = 0; i < ARRAY_SIZE(vou_scale_h_num); i++) {
614 unsigned int err;
615 unsigned int found = geo->in_width * vou_scale_h_num[i] /
616 vou_scale_h_den[i];
617
618 if (found > VOU_MAX_IMAGE_WIDTH)
619 /* scales increase */
620 break;
621
622 err = abs(found - geo->output.width);
623 if (err < best_err) {
624 best_err = err;
625 idx = i;
626 best = found;
627 }
628 if (!err)
629 break;
630 }
631
632 geo->output.width = best;
633 geo->scale_idx_h = idx;
634 if (geo->output.left + best > width_max)
635 geo->output.left = width_max - best;
636
637 pr_debug("%s(): W %u * %u/%u = %u\n", __func__, geo->in_width,
638 vou_scale_h_num[idx], vou_scale_h_den[idx], best);
639
640 best_err = UINT_MAX;
641
642 /* This loop can be replaced with one division */
643 for (i = 0; i < ARRAY_SIZE(vou_scale_v_num); i++) {
644 unsigned int err;
645 unsigned int found = geo->in_height * vou_scale_v_num[i] /
646 vou_scale_v_den[i];
647
648 if (found > img_height_max)
649 /* scales increase */
650 break;
651
652 err = abs(found - geo->output.height);
653 if (err < best_err) {
654 best_err = err;
655 idx = i;
656 best = found;
657 }
658 if (!err)
659 break;
660 }
661
662 geo->output.height = best;
663 geo->scale_idx_v = idx;
664 if (geo->output.top + best > height_max)
665 geo->output.top = height_max - best;
666
667 pr_debug("%s(): H %u * %u/%u = %u\n", __func__, geo->in_height,
668 vou_scale_v_num[idx], vou_scale_v_den[idx], best);
669}
670
671static int sh_vou_s_fmt_vid_out(struct file *file, void *priv,
672 struct v4l2_format *fmt)
673{
674 struct video_device *vdev = video_devdata(file);
675 struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
676 struct v4l2_pix_format *pix = &fmt->fmt.pix;
677 unsigned int img_height_max;
678 int pix_idx;
679 struct sh_vou_geometry geo;
680 struct v4l2_mbus_framefmt mbfmt = {
681 /* Revisit: is this the correct code? */
682 .code = V4L2_MBUS_FMT_YUYV8_2X8,
683 .field = V4L2_FIELD_INTERLACED,
684 .colorspace = V4L2_COLORSPACE_SMPTE170M,
685 };
686 int ret;
687
688 dev_dbg(vou_dev->v4l2_dev.dev, "%s(): %ux%u -> %ux%u\n", __func__,
689 vou_dev->rect.width, vou_dev->rect.height,
690 pix->width, pix->height);
691
692 if (pix->field == V4L2_FIELD_ANY)
693 pix->field = V4L2_FIELD_NONE;
694
695 if (fmt->type != V4L2_BUF_TYPE_VIDEO_OUTPUT ||
696 pix->field != V4L2_FIELD_NONE)
697 return -EINVAL;
698
699 for (pix_idx = 0; pix_idx < ARRAY_SIZE(vou_fmt); pix_idx++)
700 if (vou_fmt[pix_idx].pfmt == pix->pixelformat)
701 break;
702
703 if (pix_idx == ARRAY_SIZE(vou_fmt))
704 return -EINVAL;
705
706 if (vou_dev->std & V4L2_STD_525_60)
707 img_height_max = 480;
708 else
709 img_height_max = 576;
710
711 /* Image width must be a multiple of 4 */
712 v4l_bound_align_image(&pix->width, 0, VOU_MAX_IMAGE_WIDTH, 2,
713 &pix->height, 0, img_height_max, 1, 0);
714
715 geo.in_width = pix->width;
716 geo.in_height = pix->height;
717 geo.output = vou_dev->rect;
718
719 vou_adjust_output(&geo, vou_dev->std);
720
721 mbfmt.width = geo.output.width;
722 mbfmt.height = geo.output.height;
723 ret = v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0, video,
724 s_mbus_fmt, &mbfmt);
725 /* Must be implemented, so, don't check for -ENOIOCTLCMD */
726 if (ret < 0)
727 return ret;
728
729 dev_dbg(vou_dev->v4l2_dev.dev, "%s(): %ux%u -> %ux%u\n", __func__,
730 geo.output.width, geo.output.height, mbfmt.width, mbfmt.height);
731
732 /* Sanity checks */
733 if ((unsigned)mbfmt.width > VOU_MAX_IMAGE_WIDTH ||
734 (unsigned)mbfmt.height > img_height_max ||
735 mbfmt.code != V4L2_MBUS_FMT_YUYV8_2X8)
736 return -EIO;
737
738 if (mbfmt.width != geo.output.width ||
739 mbfmt.height != geo.output.height) {
740 geo.output.width = mbfmt.width;
741 geo.output.height = mbfmt.height;
742
743 vou_adjust_input(&geo, vou_dev->std);
744 }
745
746 /* We tried to preserve output rectangle, but it could have changed */
747 vou_dev->rect = geo.output;
748 pix->width = geo.in_width;
749 pix->height = geo.in_height;
750
751 dev_dbg(vou_dev->v4l2_dev.dev, "%s(): %ux%u\n", __func__,
752 pix->width, pix->height);
753
754 vou_dev->pix_idx = pix_idx;
755
756 vou_dev->pix = *pix;
757
758 sh_vou_configure_geometry(vou_dev, pix_idx,
759 geo.scale_idx_h, geo.scale_idx_v);
760
761 return 0;
762}
763
764static int sh_vou_try_fmt_vid_out(struct file *file, void *priv,
765 struct v4l2_format *fmt)
766{
767 struct sh_vou_file *vou_file = priv;
768 struct v4l2_pix_format *pix = &fmt->fmt.pix;
769 int i;
770
771 dev_dbg(vou_file->vbq.dev, "%s()\n", __func__);
772
773 fmt->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
774 pix->field = V4L2_FIELD_NONE;
775
776 v4l_bound_align_image(&pix->width, 0, VOU_MAX_IMAGE_WIDTH, 1,
777 &pix->height, 0, VOU_MAX_IMAGE_HEIGHT, 1, 0);
778
779 for (i = 0; ARRAY_SIZE(vou_fmt); i++)
780 if (vou_fmt[i].pfmt == pix->pixelformat)
781 return 0;
782
783 pix->pixelformat = vou_fmt[0].pfmt;
784
785 return 0;
786}
787
788static int sh_vou_reqbufs(struct file *file, void *priv,
789 struct v4l2_requestbuffers *req)
790{
791 struct sh_vou_file *vou_file = priv;
792
793 dev_dbg(vou_file->vbq.dev, "%s()\n", __func__);
794
795 if (req->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
796 return -EINVAL;
797
798 return videobuf_reqbufs(&vou_file->vbq, req);
799}
800
801static int sh_vou_querybuf(struct file *file, void *priv,
802 struct v4l2_buffer *b)
803{
804 struct sh_vou_file *vou_file = priv;
805
806 dev_dbg(vou_file->vbq.dev, "%s()\n", __func__);
807
808 return videobuf_querybuf(&vou_file->vbq, b);
809}
810
811static int sh_vou_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
812{
813 struct sh_vou_file *vou_file = priv;
814
815 dev_dbg(vou_file->vbq.dev, "%s()\n", __func__);
816
817 return videobuf_qbuf(&vou_file->vbq, b);
818}
819
820static int sh_vou_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
821{
822 struct sh_vou_file *vou_file = priv;
823
824 dev_dbg(vou_file->vbq.dev, "%s()\n", __func__);
825
826 return videobuf_dqbuf(&vou_file->vbq, b, file->f_flags & O_NONBLOCK);
827}
828
829static int sh_vou_streamon(struct file *file, void *priv,
830 enum v4l2_buf_type buftype)
831{
832 struct video_device *vdev = video_devdata(file);
833 struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
834 struct sh_vou_file *vou_file = priv;
835 int ret;
836
837 dev_dbg(vou_file->vbq.dev, "%s()\n", __func__);
838
839 ret = v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0,
840 video, s_stream, 1);
841 if (ret < 0 && ret != -ENOIOCTLCMD)
842 return ret;
843
844 /* This calls our .buf_queue() (== sh_vou_buf_queue) */
845 return videobuf_streamon(&vou_file->vbq);
846}
847
848static int sh_vou_streamoff(struct file *file, void *priv,
849 enum v4l2_buf_type buftype)
850{
851 struct video_device *vdev = video_devdata(file);
852 struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
853 struct sh_vou_file *vou_file = priv;
854
855 dev_dbg(vou_file->vbq.dev, "%s()\n", __func__);
856
857 /*
858 * This calls buf_release from host driver's videobuf_queue_ops for all
859 * remaining buffers. When the last buffer is freed, stop streaming
860 */
861 videobuf_streamoff(&vou_file->vbq);
862 v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0, video, s_stream, 0);
863
864 return 0;
865}
866
867static u32 sh_vou_ntsc_mode(enum sh_vou_bus_fmt bus_fmt)
868{
869 switch (bus_fmt) {
870 default:
871 pr_warning("%s(): Invalid bus-format code %d, using default 8-bit\n",
872 __func__, bus_fmt);
873 case SH_VOU_BUS_8BIT:
874 return 1;
875 case SH_VOU_BUS_16BIT:
876 return 0;
877 case SH_VOU_BUS_BT656:
878 return 3;
879 }
880}
881
882static int sh_vou_s_std(struct file *file, void *priv, v4l2_std_id *std_id)
883{
884 struct video_device *vdev = video_devdata(file);
885 struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
886 int ret;
887
888 dev_dbg(vou_dev->v4l2_dev.dev, "%s(): 0x%llx\n", __func__, *std_id);
889
890 if (*std_id & ~vdev->tvnorms)
891 return -EINVAL;
892
893 ret = v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0, video,
894 s_std_output, *std_id);
895 /* Shall we continue, if the subdev doesn't support .s_std_output()? */
896 if (ret < 0 && ret != -ENOIOCTLCMD)
897 return ret;
898
899 if (*std_id & V4L2_STD_525_60)
900 sh_vou_reg_ab_set(vou_dev, VOUCR,
901 sh_vou_ntsc_mode(vou_dev->pdata->bus_fmt) << 29, 7 << 29);
902 else
903 sh_vou_reg_ab_set(vou_dev, VOUCR, 5 << 29, 7 << 29);
904
905 vou_dev->std = *std_id;
906
907 return 0;
908}
909
910static int sh_vou_g_std(struct file *file, void *priv, v4l2_std_id *std)
911{
912 struct video_device *vdev = video_devdata(file);
913 struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
914
915 dev_dbg(vou_dev->v4l2_dev.dev, "%s()\n", __func__);
916
917 *std = vou_dev->std;
918
919 return 0;
920}
921
922static int sh_vou_g_crop(struct file *file, void *fh, struct v4l2_crop *a)
923{
924 struct video_device *vdev = video_devdata(file);
925 struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
926
927 dev_dbg(vou_dev->v4l2_dev.dev, "%s()\n", __func__);
928
929 a->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
930 a->c = vou_dev->rect;
931
932 return 0;
933}
934
935/* Assume a dull encoder, do all the work ourselves. */
936static int sh_vou_s_crop(struct file *file, void *fh, struct v4l2_crop *a)
937{
938 struct video_device *vdev = video_devdata(file);
939 struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
940 struct v4l2_rect *rect = &a->c;
941 struct v4l2_crop sd_crop = {.type = V4L2_BUF_TYPE_VIDEO_OUTPUT};
942 struct v4l2_pix_format *pix = &vou_dev->pix;
943 struct sh_vou_geometry geo;
944 struct v4l2_mbus_framefmt mbfmt = {
945 /* Revisit: is this the correct code? */
946 .code = V4L2_MBUS_FMT_YUYV8_2X8,
947 .field = V4L2_FIELD_INTERLACED,
948 .colorspace = V4L2_COLORSPACE_SMPTE170M,
949 };
950 unsigned int img_height_max;
951 int ret;
952
953 dev_dbg(vou_dev->v4l2_dev.dev, "%s(): %ux%u@%u:%u\n", __func__,
954 rect->width, rect->height, rect->left, rect->top);
955
956 if (a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
957 return -EINVAL;
958
959 if (vou_dev->std & V4L2_STD_525_60)
960 img_height_max = 480;
961 else
962 img_height_max = 576;
963
964 v4l_bound_align_image(&rect->width, 0, VOU_MAX_IMAGE_WIDTH, 1,
965 &rect->height, 0, img_height_max, 1, 0);
966
967 if (rect->width + rect->left > VOU_MAX_IMAGE_WIDTH)
968 rect->left = VOU_MAX_IMAGE_WIDTH - rect->width;
969
970 if (rect->height + rect->top > img_height_max)
971 rect->top = img_height_max - rect->height;
972
973 geo.output = *rect;
974 geo.in_width = pix->width;
975 geo.in_height = pix->height;
976
977 /* Configure the encoder one-to-one, position at 0, ignore errors */
978 sd_crop.c.width = geo.output.width;
979 sd_crop.c.height = geo.output.height;
980 /*
981 * We first issue a S_CROP, so that the subsequent S_FMT delivers the
982 * final encoder configuration.
983 */
984 v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0, video,
985 s_crop, &sd_crop);
986 mbfmt.width = geo.output.width;
987 mbfmt.height = geo.output.height;
988 ret = v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0, video,
989 s_mbus_fmt, &mbfmt);
990 /* Must be implemented, so, don't check for -ENOIOCTLCMD */
991 if (ret < 0)
992 return ret;
993
994 /* Sanity checks */
995 if ((unsigned)mbfmt.width > VOU_MAX_IMAGE_WIDTH ||
996 (unsigned)mbfmt.height > img_height_max ||
997 mbfmt.code != V4L2_MBUS_FMT_YUYV8_2X8)
998 return -EIO;
999
1000 geo.output.width = mbfmt.width;
1001 geo.output.height = mbfmt.height;
1002
1003 /*
1004 * No down-scaling. According to the API, current call has precedence:
1005 * http://v4l2spec.bytesex.org/spec/x1904.htm#AEN1954 paragraph two.
1006 */
1007 vou_adjust_input(&geo, vou_dev->std);
1008
1009 /* We tried to preserve output rectangle, but it could have changed */
1010 vou_dev->rect = geo.output;
1011 pix->width = geo.in_width;
1012 pix->height = geo.in_height;
1013
1014 sh_vou_configure_geometry(vou_dev, vou_dev->pix_idx,
1015 geo.scale_idx_h, geo.scale_idx_v);
1016
1017 return 0;
1018}
1019
1020/*
1021 * Total field: NTSC 858 x 2 * 262/263, PAL 864 x 2 * 312/313, default rectangle
1022 * is the initial register values, height takes the interlaced format into
1023 * account. The actual image can only go up to 720 x 2 * 240, So, VOUVPR can
1024 * actually only meaningfully contain values <= 720 and <= 240 respectively, and
1025 * not <= 864 and <= 312.
1026 */
1027static int sh_vou_cropcap(struct file *file, void *priv,
1028 struct v4l2_cropcap *a)
1029{
1030 struct sh_vou_file *vou_file = priv;
1031
1032 dev_dbg(vou_file->vbq.dev, "%s()\n", __func__);
1033
1034 a->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
1035 a->bounds.left = 0;
1036 a->bounds.top = 0;
1037 a->bounds.width = VOU_MAX_IMAGE_WIDTH;
1038 a->bounds.height = VOU_MAX_IMAGE_HEIGHT;
1039 /* Default = max, set VOUDPR = 0, which is not hardware default */
1040 a->defrect.left = 0;
1041 a->defrect.top = 0;
1042 a->defrect.width = VOU_MAX_IMAGE_WIDTH;
1043 a->defrect.height = VOU_MAX_IMAGE_HEIGHT;
1044 a->pixelaspect.numerator = 1;
1045 a->pixelaspect.denominator = 1;
1046
1047 return 0;
1048}
1049
1050static irqreturn_t sh_vou_isr(int irq, void *dev_id)
1051{
1052 struct sh_vou_device *vou_dev = dev_id;
1053 static unsigned long j;
1054 struct videobuf_buffer *vb;
1055 static int cnt;
1056 static int side;
1057 u32 irq_status = sh_vou_reg_a_read(vou_dev, VOUIR), masked;
1058 u32 vou_status = sh_vou_reg_a_read(vou_dev, VOUSTR);
1059
1060 if (!(irq_status & 0x300)) {
1061 if (printk_timed_ratelimit(&j, 500))
1062 dev_warn(vou_dev->v4l2_dev.dev, "IRQ status 0x%x!\n",
1063 irq_status);
1064 return IRQ_NONE;
1065 }
1066
1067 spin_lock(&vou_dev->lock);
1068 if (!vou_dev->active || list_empty(&vou_dev->queue)) {
1069 if (printk_timed_ratelimit(&j, 500))
1070 dev_warn(vou_dev->v4l2_dev.dev,
1071 "IRQ without active buffer: %x!\n", irq_status);
1072 /* Just ack: buf_release will disable further interrupts */
1073 sh_vou_reg_a_set(vou_dev, VOUIR, 0, 0x300);
1074 spin_unlock(&vou_dev->lock);
1075 return IRQ_HANDLED;
1076 }
1077
1078 masked = ~(0x300 & irq_status) & irq_status & 0x30304;
1079 dev_dbg(vou_dev->v4l2_dev.dev,
1080 "IRQ status 0x%x -> 0x%x, VOU status 0x%x, cnt %d\n",
1081 irq_status, masked, vou_status, cnt);
1082
1083 cnt++;
1084 side = vou_status & 0x10000;
1085
1086 /* Clear only set interrupts */
1087 sh_vou_reg_a_write(vou_dev, VOUIR, masked);
1088
1089 vb = vou_dev->active;
1090 list_del(&vb->queue);
1091
1092 vb->state = VIDEOBUF_DONE;
1093 do_gettimeofday(&vb->ts);
1094 vb->field_count++;
1095 wake_up(&vb->done);
1096
1097 if (list_empty(&vou_dev->queue)) {
1098 /* Stop VOU */
1099 dev_dbg(vou_dev->v4l2_dev.dev, "%s: queue empty after %d\n",
1100 __func__, cnt);
1101 sh_vou_reg_a_set(vou_dev, VOUER, 0, 1);
1102 vou_dev->active = NULL;
1103 vou_dev->status = SH_VOU_INITIALISING;
1104 /* Disable End-of-Frame (VSYNC) interrupts */
1105 sh_vou_reg_a_set(vou_dev, VOUIR, 0, 0x30000);
1106 spin_unlock(&vou_dev->lock);
1107 return IRQ_HANDLED;
1108 }
1109
1110 vou_dev->active = list_entry(vou_dev->queue.next,
1111 struct videobuf_buffer, queue);
1112
1113 if (vou_dev->active->queue.next != &vou_dev->queue) {
1114 struct videobuf_buffer *new = list_entry(vou_dev->active->queue.next,
1115 struct videobuf_buffer, queue);
1116 sh_vou_schedule_next(vou_dev, new);
1117 }
1118
1119 spin_unlock(&vou_dev->lock);
1120
1121 return IRQ_HANDLED;
1122}
1123
1124static int sh_vou_hw_init(struct sh_vou_device *vou_dev)
1125{
1126 struct sh_vou_pdata *pdata = vou_dev->pdata;
1127 u32 voucr = sh_vou_ntsc_mode(pdata->bus_fmt) << 29;
1128 int i = 100;
1129
1130 /* Disable all IRQs */
1131 sh_vou_reg_a_write(vou_dev, VOUIR, 0);
1132
1133 /* Reset VOU interfaces - registers unaffected */
1134 sh_vou_reg_a_write(vou_dev, VOUSRR, 0x101);
1135 while (--i && (sh_vou_reg_a_read(vou_dev, VOUSRR) & 0x101))
1136 udelay(1);
1137
1138 if (!i)
1139 return -ETIMEDOUT;
1140
1141 dev_dbg(vou_dev->v4l2_dev.dev, "Reset took %dus\n", 100 - i);
1142
1143 if (pdata->flags & SH_VOU_PCLK_FALLING)
1144 voucr |= 1 << 28;
1145 if (pdata->flags & SH_VOU_HSYNC_LOW)
1146 voucr |= 1 << 27;
1147 if (pdata->flags & SH_VOU_VSYNC_LOW)
1148 voucr |= 1 << 26;
1149 sh_vou_reg_ab_set(vou_dev, VOUCR, voucr, 0xfc000000);
1150
1151 /* Manual register side switching at first */
1152 sh_vou_reg_a_write(vou_dev, VOURCR, 4);
1153 /* Default - fixed HSYNC length, can be made configurable is required */
1154 sh_vou_reg_ab_write(vou_dev, VOUMSR, 0x800000);
1155
1156 return 0;
1157}
1158
1159/* File operations */
1160static int sh_vou_open(struct file *file)
1161{
1162 struct video_device *vdev = video_devdata(file);
1163 struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
1164 struct sh_vou_file *vou_file = kzalloc(sizeof(struct sh_vou_file),
1165 GFP_KERNEL);
1166
1167 if (!vou_file)
1168 return -ENOMEM;
1169
1170 dev_dbg(vou_dev->v4l2_dev.dev, "%s()\n", __func__);
1171
1172 file->private_data = vou_file;
1173
1174 if (mutex_lock_interruptible(&vou_dev->fop_lock))
1175 return -ERESTARTSYS;
1176 if (atomic_inc_return(&vou_dev->use_count) == 1) {
1177 int ret;
1178 /* First open */
1179 vou_dev->status = SH_VOU_INITIALISING;
1180 pm_runtime_get_sync(vdev->v4l2_dev->dev);
1181 ret = sh_vou_hw_init(vou_dev);
1182 if (ret < 0) {
1183 atomic_dec(&vou_dev->use_count);
1184 pm_runtime_put(vdev->v4l2_dev->dev);
1185 vou_dev->status = SH_VOU_IDLE;
1186 mutex_unlock(&vou_dev->fop_lock);
1187 return ret;
1188 }
1189 }
1190
1191 videobuf_queue_dma_contig_init(&vou_file->vbq, &sh_vou_video_qops,
1192 vou_dev->v4l2_dev.dev, &vou_dev->lock,
1193 V4L2_BUF_TYPE_VIDEO_OUTPUT,
1194 V4L2_FIELD_NONE,
1195 sizeof(struct videobuf_buffer), vdev,
1196 &vou_dev->fop_lock);
1197 mutex_unlock(&vou_dev->fop_lock);
1198
1199 return 0;
1200}
1201
1202static int sh_vou_release(struct file *file)
1203{
1204 struct video_device *vdev = video_devdata(file);
1205 struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
1206 struct sh_vou_file *vou_file = file->private_data;
1207
1208 dev_dbg(vou_file->vbq.dev, "%s()\n", __func__);
1209
1210 if (!atomic_dec_return(&vou_dev->use_count)) {
1211 mutex_lock(&vou_dev->fop_lock);
1212 /* Last close */
1213 vou_dev->status = SH_VOU_IDLE;
1214 sh_vou_reg_a_set(vou_dev, VOUER, 0, 0x101);
1215 pm_runtime_put(vdev->v4l2_dev->dev);
1216 mutex_unlock(&vou_dev->fop_lock);
1217 }
1218
1219 file->private_data = NULL;
1220 kfree(vou_file);
1221
1222 return 0;
1223}
1224
1225static int sh_vou_mmap(struct file *file, struct vm_area_struct *vma)
1226{
1227 struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
1228 struct sh_vou_file *vou_file = file->private_data;
1229 int ret;
1230
1231 dev_dbg(vou_file->vbq.dev, "%s()\n", __func__);
1232
1233 if (mutex_lock_interruptible(&vou_dev->fop_lock))
1234 return -ERESTARTSYS;
1235 ret = videobuf_mmap_mapper(&vou_file->vbq, vma);
1236 mutex_unlock(&vou_dev->fop_lock);
1237 return ret;
1238}
1239
1240static unsigned int sh_vou_poll(struct file *file, poll_table *wait)
1241{
1242 struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
1243 struct sh_vou_file *vou_file = file->private_data;
1244 unsigned int res;
1245
1246 dev_dbg(vou_file->vbq.dev, "%s()\n", __func__);
1247
1248 mutex_lock(&vou_dev->fop_lock);
1249 res = videobuf_poll_stream(file, &vou_file->vbq, wait);
1250 mutex_unlock(&vou_dev->fop_lock);
1251 return res;
1252}
1253
1254static int sh_vou_g_chip_ident(struct file *file, void *fh,
1255 struct v4l2_dbg_chip_ident *id)
1256{
1257 struct video_device *vdev = video_devdata(file);
1258 struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
1259
1260 return v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0, core, g_chip_ident, id);
1261}
1262
1263#ifdef CONFIG_VIDEO_ADV_DEBUG
1264static int sh_vou_g_register(struct file *file, void *fh,
1265 struct v4l2_dbg_register *reg)
1266{
1267 struct video_device *vdev = video_devdata(file);
1268 struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
1269
1270 return v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0, core, g_register, reg);
1271}
1272
1273static int sh_vou_s_register(struct file *file, void *fh,
1274 struct v4l2_dbg_register *reg)
1275{
1276 struct video_device *vdev = video_devdata(file);
1277 struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
1278
1279 return v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0, core, s_register, reg);
1280}
1281#endif
1282
1283/* sh_vou display ioctl operations */
1284static const struct v4l2_ioctl_ops sh_vou_ioctl_ops = {
1285 .vidioc_querycap = sh_vou_querycap,
1286 .vidioc_enum_fmt_vid_out = sh_vou_enum_fmt_vid_out,
1287 .vidioc_g_fmt_vid_out = sh_vou_g_fmt_vid_out,
1288 .vidioc_s_fmt_vid_out = sh_vou_s_fmt_vid_out,
1289 .vidioc_try_fmt_vid_out = sh_vou_try_fmt_vid_out,
1290 .vidioc_reqbufs = sh_vou_reqbufs,
1291 .vidioc_querybuf = sh_vou_querybuf,
1292 .vidioc_qbuf = sh_vou_qbuf,
1293 .vidioc_dqbuf = sh_vou_dqbuf,
1294 .vidioc_streamon = sh_vou_streamon,
1295 .vidioc_streamoff = sh_vou_streamoff,
1296 .vidioc_s_std = sh_vou_s_std,
1297 .vidioc_g_std = sh_vou_g_std,
1298 .vidioc_cropcap = sh_vou_cropcap,
1299 .vidioc_g_crop = sh_vou_g_crop,
1300 .vidioc_s_crop = sh_vou_s_crop,
1301 .vidioc_g_chip_ident = sh_vou_g_chip_ident,
1302#ifdef CONFIG_VIDEO_ADV_DEBUG
1303 .vidioc_g_register = sh_vou_g_register,
1304 .vidioc_s_register = sh_vou_s_register,
1305#endif
1306};
1307
1308static const struct v4l2_file_operations sh_vou_fops = {
1309 .owner = THIS_MODULE,
1310 .open = sh_vou_open,
1311 .release = sh_vou_release,
1312 .unlocked_ioctl = video_ioctl2,
1313 .mmap = sh_vou_mmap,
1314 .poll = sh_vou_poll,
1315};
1316
1317static const struct video_device sh_vou_video_template = {
1318 .name = "sh_vou",
1319 .fops = &sh_vou_fops,
1320 .ioctl_ops = &sh_vou_ioctl_ops,
1321 .tvnorms = V4L2_STD_525_60, /* PAL only supported in 8-bit non-bt656 mode */
1322 .current_norm = V4L2_STD_NTSC_M,
1323};
1324
1325static int __devinit sh_vou_probe(struct platform_device *pdev)
1326{
1327 struct sh_vou_pdata *vou_pdata = pdev->dev.platform_data;
1328 struct v4l2_rect *rect;
1329 struct v4l2_pix_format *pix;
1330 struct i2c_adapter *i2c_adap;
1331 struct video_device *vdev;
1332 struct sh_vou_device *vou_dev;
1333 struct resource *reg_res, *region;
1334 struct v4l2_subdev *subdev;
1335 int irq, ret;
1336
1337 reg_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1338 irq = platform_get_irq(pdev, 0);
1339
1340 if (!vou_pdata || !reg_res || irq <= 0) {
1341 dev_err(&pdev->dev, "Insufficient VOU platform information.\n");
1342 return -ENODEV;
1343 }
1344
1345 vou_dev = kzalloc(sizeof(*vou_dev), GFP_KERNEL);
1346 if (!vou_dev)
1347 return -ENOMEM;
1348
1349 INIT_LIST_HEAD(&vou_dev->queue);
1350 spin_lock_init(&vou_dev->lock);
1351 mutex_init(&vou_dev->fop_lock);
1352 atomic_set(&vou_dev->use_count, 0);
1353 vou_dev->pdata = vou_pdata;
1354 vou_dev->status = SH_VOU_IDLE;
1355
1356 rect = &vou_dev->rect;
1357 pix = &vou_dev->pix;
1358
1359 /* Fill in defaults */
1360 vou_dev->std = sh_vou_video_template.current_norm;
1361 rect->left = 0;
1362 rect->top = 0;
1363 rect->width = VOU_MAX_IMAGE_WIDTH;
1364 rect->height = 480;
1365 pix->width = VOU_MAX_IMAGE_WIDTH;
1366 pix->height = 480;
1367 pix->pixelformat = V4L2_PIX_FMT_YVYU;
1368 pix->field = V4L2_FIELD_NONE;
1369 pix->bytesperline = VOU_MAX_IMAGE_WIDTH * 2;
1370 pix->sizeimage = VOU_MAX_IMAGE_WIDTH * 2 * 480;
1371 pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
1372
1373 region = request_mem_region(reg_res->start, resource_size(reg_res),
1374 pdev->name);
1375 if (!region) {
1376 dev_err(&pdev->dev, "VOU region already claimed\n");
1377 ret = -EBUSY;
1378 goto ereqmemreg;
1379 }
1380
1381 vou_dev->base = ioremap(reg_res->start, resource_size(reg_res));
1382 if (!vou_dev->base) {
1383 ret = -ENOMEM;
1384 goto emap;
1385 }
1386
1387 ret = request_irq(irq, sh_vou_isr, 0, "vou", vou_dev);
1388 if (ret < 0)
1389 goto ereqirq;
1390
1391 ret = v4l2_device_register(&pdev->dev, &vou_dev->v4l2_dev);
1392 if (ret < 0) {
1393 dev_err(&pdev->dev, "Error registering v4l2 device\n");
1394 goto ev4l2devreg;
1395 }
1396
1397 /* Allocate memory for video device */
1398 vdev = video_device_alloc();
1399 if (vdev == NULL) {
1400 ret = -ENOMEM;
1401 goto evdevalloc;
1402 }
1403
1404 *vdev = sh_vou_video_template;
1405 if (vou_pdata->bus_fmt == SH_VOU_BUS_8BIT)
1406 vdev->tvnorms |= V4L2_STD_PAL;
1407 vdev->v4l2_dev = &vou_dev->v4l2_dev;
1408 vdev->release = video_device_release;
1409 vdev->lock = &vou_dev->fop_lock;
1410
1411 vou_dev->vdev = vdev;
1412 video_set_drvdata(vdev, vou_dev);
1413
1414 pm_runtime_enable(&pdev->dev);
1415 pm_runtime_resume(&pdev->dev);
1416
1417 i2c_adap = i2c_get_adapter(vou_pdata->i2c_adap);
1418 if (!i2c_adap) {
1419 ret = -ENODEV;
1420 goto ei2cgadap;
1421 }
1422
1423 ret = sh_vou_hw_init(vou_dev);
1424 if (ret < 0)
1425 goto ereset;
1426
1427 subdev = v4l2_i2c_new_subdev_board(&vou_dev->v4l2_dev, i2c_adap,
1428 vou_pdata->board_info, NULL);
1429 if (!subdev) {
1430 ret = -ENOMEM;
1431 goto ei2cnd;
1432 }
1433
1434 ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
1435 if (ret < 0)
1436 goto evregdev;
1437
1438 return 0;
1439
1440evregdev:
1441ei2cnd:
1442ereset:
1443 i2c_put_adapter(i2c_adap);
1444ei2cgadap:
1445 video_device_release(vdev);
1446 pm_runtime_disable(&pdev->dev);
1447evdevalloc:
1448 v4l2_device_unregister(&vou_dev->v4l2_dev);
1449ev4l2devreg:
1450 free_irq(irq, vou_dev);
1451ereqirq:
1452 iounmap(vou_dev->base);
1453emap:
1454 release_mem_region(reg_res->start, resource_size(reg_res));
1455ereqmemreg:
1456 kfree(vou_dev);
1457 return ret;
1458}
1459
1460static int __devexit sh_vou_remove(struct platform_device *pdev)
1461{
1462 int irq = platform_get_irq(pdev, 0);
1463 struct v4l2_device *v4l2_dev = platform_get_drvdata(pdev);
1464 struct sh_vou_device *vou_dev = container_of(v4l2_dev,
1465 struct sh_vou_device, v4l2_dev);
1466 struct v4l2_subdev *sd = list_entry(v4l2_dev->subdevs.next,
1467 struct v4l2_subdev, list);
1468 struct i2c_client *client = v4l2_get_subdevdata(sd);
1469 struct resource *reg_res;
1470
1471 if (irq > 0)
1472 free_irq(irq, vou_dev);
1473 pm_runtime_disable(&pdev->dev);
1474 video_unregister_device(vou_dev->vdev);
1475 i2c_put_adapter(client->adapter);
1476 v4l2_device_unregister(&vou_dev->v4l2_dev);
1477 iounmap(vou_dev->base);
1478 reg_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1479 if (reg_res)
1480 release_mem_region(reg_res->start, resource_size(reg_res));
1481 kfree(vou_dev);
1482 return 0;
1483}
1484
1485static struct platform_driver __refdata sh_vou = {
1486 .remove = __devexit_p(sh_vou_remove),
1487 .driver = {
1488 .name = "sh-vou",
1489 .owner = THIS_MODULE,
1490 },
1491};
1492
1493static int __init sh_vou_init(void)
1494{
1495 return platform_driver_probe(&sh_vou, sh_vou_probe);
1496}
1497
1498static void __exit sh_vou_exit(void)
1499{
1500 platform_driver_unregister(&sh_vou);
1501}
1502
1503module_init(sh_vou_init);
1504module_exit(sh_vou_exit);
1505
1506MODULE_DESCRIPTION("SuperH VOU driver");
1507MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
1508MODULE_LICENSE("GPL v2");
1509MODULE_VERSION("0.1.0");
1510MODULE_ALIAS("platform:sh-vou");
diff --git a/drivers/media/video/soc_camera_platform.c b/drivers/media/video/soc_camera_platform.c
deleted file mode 100644
index f59ccade07c8..000000000000
--- a/drivers/media/video/soc_camera_platform.c
+++ /dev/null
@@ -1,197 +0,0 @@
1/*
2 * Generic Platform Camera Driver
3 *
4 * Copyright (C) 2008 Magnus Damm
5 * Based on mt9m001 driver,
6 * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/init.h>
14#include <linux/module.h>
15#include <linux/slab.h>
16#include <linux/delay.h>
17#include <linux/platform_device.h>
18#include <linux/videodev2.h>
19#include <media/v4l2-subdev.h>
20#include <media/soc_camera.h>
21#include <media/soc_camera_platform.h>
22
23struct soc_camera_platform_priv {
24 struct v4l2_subdev subdev;
25};
26
27static struct soc_camera_platform_priv *get_priv(struct platform_device *pdev)
28{
29 struct v4l2_subdev *subdev = platform_get_drvdata(pdev);
30 return container_of(subdev, struct soc_camera_platform_priv, subdev);
31}
32
33static int soc_camera_platform_s_stream(struct v4l2_subdev *sd, int enable)
34{
35 struct soc_camera_platform_info *p = v4l2_get_subdevdata(sd);
36 return p->set_capture(p, enable);
37}
38
39static int soc_camera_platform_fill_fmt(struct v4l2_subdev *sd,
40 struct v4l2_mbus_framefmt *mf)
41{
42 struct soc_camera_platform_info *p = v4l2_get_subdevdata(sd);
43
44 mf->width = p->format.width;
45 mf->height = p->format.height;
46 mf->code = p->format.code;
47 mf->colorspace = p->format.colorspace;
48 mf->field = p->format.field;
49
50 return 0;
51}
52
53static struct v4l2_subdev_core_ops platform_subdev_core_ops;
54
55static int soc_camera_platform_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
56 enum v4l2_mbus_pixelcode *code)
57{
58 struct soc_camera_platform_info *p = v4l2_get_subdevdata(sd);
59
60 if (index)
61 return -EINVAL;
62
63 *code = p->format.code;
64 return 0;
65}
66
67static int soc_camera_platform_g_crop(struct v4l2_subdev *sd,
68 struct v4l2_crop *a)
69{
70 struct soc_camera_platform_info *p = v4l2_get_subdevdata(sd);
71
72 a->c.left = 0;
73 a->c.top = 0;
74 a->c.width = p->format.width;
75 a->c.height = p->format.height;
76 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
77
78 return 0;
79}
80
81static int soc_camera_platform_cropcap(struct v4l2_subdev *sd,
82 struct v4l2_cropcap *a)
83{
84 struct soc_camera_platform_info *p = v4l2_get_subdevdata(sd);
85
86 a->bounds.left = 0;
87 a->bounds.top = 0;
88 a->bounds.width = p->format.width;
89 a->bounds.height = p->format.height;
90 a->defrect = a->bounds;
91 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
92 a->pixelaspect.numerator = 1;
93 a->pixelaspect.denominator = 1;
94
95 return 0;
96}
97
98static int soc_camera_platform_g_mbus_config(struct v4l2_subdev *sd,
99 struct v4l2_mbus_config *cfg)
100{
101 struct soc_camera_platform_info *p = v4l2_get_subdevdata(sd);
102
103 cfg->flags = p->mbus_param;
104 cfg->type = p->mbus_type;
105
106 return 0;
107}
108
109static struct v4l2_subdev_video_ops platform_subdev_video_ops = {
110 .s_stream = soc_camera_platform_s_stream,
111 .enum_mbus_fmt = soc_camera_platform_enum_fmt,
112 .cropcap = soc_camera_platform_cropcap,
113 .g_crop = soc_camera_platform_g_crop,
114 .try_mbus_fmt = soc_camera_platform_fill_fmt,
115 .g_mbus_fmt = soc_camera_platform_fill_fmt,
116 .s_mbus_fmt = soc_camera_platform_fill_fmt,
117 .g_mbus_config = soc_camera_platform_g_mbus_config,
118};
119
120static struct v4l2_subdev_ops platform_subdev_ops = {
121 .core = &platform_subdev_core_ops,
122 .video = &platform_subdev_video_ops,
123};
124
125static int soc_camera_platform_probe(struct platform_device *pdev)
126{
127 struct soc_camera_host *ici;
128 struct soc_camera_platform_priv *priv;
129 struct soc_camera_platform_info *p = pdev->dev.platform_data;
130 struct soc_camera_device *icd;
131 int ret;
132
133 if (!p)
134 return -EINVAL;
135
136 if (!p->icd) {
137 dev_err(&pdev->dev,
138 "Platform has not set soc_camera_device pointer!\n");
139 return -EINVAL;
140 }
141
142 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
143 if (!priv)
144 return -ENOMEM;
145
146 icd = p->icd;
147
148 /* soc-camera convention: control's drvdata points to the subdev */
149 platform_set_drvdata(pdev, &priv->subdev);
150 /* Set the control device reference */
151 icd->control = &pdev->dev;
152
153 ici = to_soc_camera_host(icd->parent);
154
155 v4l2_subdev_init(&priv->subdev, &platform_subdev_ops);
156 v4l2_set_subdevdata(&priv->subdev, p);
157 strncpy(priv->subdev.name, dev_name(&pdev->dev), V4L2_SUBDEV_NAME_SIZE);
158
159 ret = v4l2_device_register_subdev(&ici->v4l2_dev, &priv->subdev);
160 if (ret)
161 goto evdrs;
162
163 return ret;
164
165evdrs:
166 platform_set_drvdata(pdev, NULL);
167 kfree(priv);
168 return ret;
169}
170
171static int soc_camera_platform_remove(struct platform_device *pdev)
172{
173 struct soc_camera_platform_priv *priv = get_priv(pdev);
174 struct soc_camera_platform_info *p = v4l2_get_subdevdata(&priv->subdev);
175
176 p->icd->control = NULL;
177 v4l2_device_unregister_subdev(&priv->subdev);
178 platform_set_drvdata(pdev, NULL);
179 kfree(priv);
180 return 0;
181}
182
183static struct platform_driver soc_camera_platform_driver = {
184 .driver = {
185 .name = "soc_camera_platform",
186 .owner = THIS_MODULE,
187 },
188 .probe = soc_camera_platform_probe,
189 .remove = soc_camera_platform_remove,
190};
191
192module_platform_driver(soc_camera_platform_driver);
193
194MODULE_DESCRIPTION("SoC Camera Platform driver");
195MODULE_AUTHOR("Magnus Damm");
196MODULE_LICENSE("GPL v2");
197MODULE_ALIAS("platform:soc_camera_platform");
diff --git a/drivers/media/video/soc_mediabus.c b/drivers/media/video/soc_mediabus.c
deleted file mode 100644
index 89dce097a827..000000000000
--- a/drivers/media/video/soc_mediabus.c
+++ /dev/null
@@ -1,487 +0,0 @@
1/*
2 * soc-camera media bus helper routines
3 *
4 * Copyright (C) 2009, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/kernel.h>
12#include <linux/module.h>
13
14#include <media/v4l2-device.h>
15#include <media/v4l2-mediabus.h>
16#include <media/soc_mediabus.h>
17
18static const struct soc_mbus_lookup mbus_fmt[] = {
19{
20 .code = V4L2_MBUS_FMT_YUYV8_2X8,
21 .fmt = {
22 .fourcc = V4L2_PIX_FMT_YUYV,
23 .name = "YUYV",
24 .bits_per_sample = 8,
25 .packing = SOC_MBUS_PACKING_2X8_PADHI,
26 .order = SOC_MBUS_ORDER_LE,
27 .layout = SOC_MBUS_LAYOUT_PACKED,
28 },
29}, {
30 .code = V4L2_MBUS_FMT_YVYU8_2X8,
31 .fmt = {
32 .fourcc = V4L2_PIX_FMT_YVYU,
33 .name = "YVYU",
34 .bits_per_sample = 8,
35 .packing = SOC_MBUS_PACKING_2X8_PADHI,
36 .order = SOC_MBUS_ORDER_LE,
37 .layout = SOC_MBUS_LAYOUT_PACKED,
38 },
39}, {
40 .code = V4L2_MBUS_FMT_UYVY8_2X8,
41 .fmt = {
42 .fourcc = V4L2_PIX_FMT_UYVY,
43 .name = "UYVY",
44 .bits_per_sample = 8,
45 .packing = SOC_MBUS_PACKING_2X8_PADHI,
46 .order = SOC_MBUS_ORDER_LE,
47 .layout = SOC_MBUS_LAYOUT_PACKED,
48 },
49}, {
50 .code = V4L2_MBUS_FMT_VYUY8_2X8,
51 .fmt = {
52 .fourcc = V4L2_PIX_FMT_VYUY,
53 .name = "VYUY",
54 .bits_per_sample = 8,
55 .packing = SOC_MBUS_PACKING_2X8_PADHI,
56 .order = SOC_MBUS_ORDER_LE,
57 .layout = SOC_MBUS_LAYOUT_PACKED,
58 },
59}, {
60 .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE,
61 .fmt = {
62 .fourcc = V4L2_PIX_FMT_RGB555,
63 .name = "RGB555",
64 .bits_per_sample = 8,
65 .packing = SOC_MBUS_PACKING_2X8_PADHI,
66 .order = SOC_MBUS_ORDER_LE,
67 .layout = SOC_MBUS_LAYOUT_PACKED,
68 },
69}, {
70 .code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE,
71 .fmt = {
72 .fourcc = V4L2_PIX_FMT_RGB555X,
73 .name = "RGB555X",
74 .bits_per_sample = 8,
75 .packing = SOC_MBUS_PACKING_2X8_PADHI,
76 .order = SOC_MBUS_ORDER_LE,
77 .layout = SOC_MBUS_LAYOUT_PACKED,
78 },
79}, {
80 .code = V4L2_MBUS_FMT_RGB565_2X8_LE,
81 .fmt = {
82 .fourcc = V4L2_PIX_FMT_RGB565,
83 .name = "RGB565",
84 .bits_per_sample = 8,
85 .packing = SOC_MBUS_PACKING_2X8_PADHI,
86 .order = SOC_MBUS_ORDER_LE,
87 .layout = SOC_MBUS_LAYOUT_PACKED,
88 },
89}, {
90 .code = V4L2_MBUS_FMT_RGB565_2X8_BE,
91 .fmt = {
92 .fourcc = V4L2_PIX_FMT_RGB565X,
93 .name = "RGB565X",
94 .bits_per_sample = 8,
95 .packing = SOC_MBUS_PACKING_2X8_PADHI,
96 .order = SOC_MBUS_ORDER_LE,
97 .layout = SOC_MBUS_LAYOUT_PACKED,
98 },
99}, {
100 .code = V4L2_MBUS_FMT_SBGGR8_1X8,
101 .fmt = {
102 .fourcc = V4L2_PIX_FMT_SBGGR8,
103 .name = "Bayer 8 BGGR",
104 .bits_per_sample = 8,
105 .packing = SOC_MBUS_PACKING_NONE,
106 .order = SOC_MBUS_ORDER_LE,
107 .layout = SOC_MBUS_LAYOUT_PACKED,
108 },
109}, {
110 .code = V4L2_MBUS_FMT_SBGGR10_1X10,
111 .fmt = {
112 .fourcc = V4L2_PIX_FMT_SBGGR10,
113 .name = "Bayer 10 BGGR",
114 .bits_per_sample = 10,
115 .packing = SOC_MBUS_PACKING_EXTEND16,
116 .order = SOC_MBUS_ORDER_LE,
117 .layout = SOC_MBUS_LAYOUT_PACKED,
118 },
119}, {
120 .code = V4L2_MBUS_FMT_Y8_1X8,
121 .fmt = {
122 .fourcc = V4L2_PIX_FMT_GREY,
123 .name = "Grey",
124 .bits_per_sample = 8,
125 .packing = SOC_MBUS_PACKING_NONE,
126 .order = SOC_MBUS_ORDER_LE,
127 .layout = SOC_MBUS_LAYOUT_PACKED,
128 },
129}, {
130 .code = V4L2_MBUS_FMT_Y10_1X10,
131 .fmt = {
132 .fourcc = V4L2_PIX_FMT_Y10,
133 .name = "Grey 10bit",
134 .bits_per_sample = 10,
135 .packing = SOC_MBUS_PACKING_EXTEND16,
136 .order = SOC_MBUS_ORDER_LE,
137 .layout = SOC_MBUS_LAYOUT_PACKED,
138 },
139}, {
140 .code = V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE,
141 .fmt = {
142 .fourcc = V4L2_PIX_FMT_SBGGR10,
143 .name = "Bayer 10 BGGR",
144 .bits_per_sample = 8,
145 .packing = SOC_MBUS_PACKING_2X8_PADHI,
146 .order = SOC_MBUS_ORDER_LE,
147 .layout = SOC_MBUS_LAYOUT_PACKED,
148 },
149}, {
150 .code = V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE,
151 .fmt = {
152 .fourcc = V4L2_PIX_FMT_SBGGR10,
153 .name = "Bayer 10 BGGR",
154 .bits_per_sample = 8,
155 .packing = SOC_MBUS_PACKING_2X8_PADLO,
156 .order = SOC_MBUS_ORDER_LE,
157 .layout = SOC_MBUS_LAYOUT_PACKED,
158 },
159}, {
160 .code = V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE,
161 .fmt = {
162 .fourcc = V4L2_PIX_FMT_SBGGR10,
163 .name = "Bayer 10 BGGR",
164 .bits_per_sample = 8,
165 .packing = SOC_MBUS_PACKING_2X8_PADHI,
166 .order = SOC_MBUS_ORDER_BE,
167 .layout = SOC_MBUS_LAYOUT_PACKED,
168 },
169}, {
170 .code = V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE,
171 .fmt = {
172 .fourcc = V4L2_PIX_FMT_SBGGR10,
173 .name = "Bayer 10 BGGR",
174 .bits_per_sample = 8,
175 .packing = SOC_MBUS_PACKING_2X8_PADLO,
176 .order = SOC_MBUS_ORDER_BE,
177 .layout = SOC_MBUS_LAYOUT_PACKED,
178 },
179}, {
180 .code = V4L2_MBUS_FMT_JPEG_1X8,
181 .fmt = {
182 .fourcc = V4L2_PIX_FMT_JPEG,
183 .name = "JPEG",
184 .bits_per_sample = 8,
185 .packing = SOC_MBUS_PACKING_VARIABLE,
186 .order = SOC_MBUS_ORDER_LE,
187 .layout = SOC_MBUS_LAYOUT_PACKED,
188 },
189}, {
190 .code = V4L2_MBUS_FMT_RGB444_2X8_PADHI_BE,
191 .fmt = {
192 .fourcc = V4L2_PIX_FMT_RGB444,
193 .name = "RGB444",
194 .bits_per_sample = 8,
195 .packing = SOC_MBUS_PACKING_2X8_PADHI,
196 .order = SOC_MBUS_ORDER_BE,
197 .layout = SOC_MBUS_LAYOUT_PACKED,
198 },
199}, {
200 .code = V4L2_MBUS_FMT_YUYV8_1_5X8,
201 .fmt = {
202 .fourcc = V4L2_PIX_FMT_YUV420,
203 .name = "YUYV 4:2:0",
204 .bits_per_sample = 8,
205 .packing = SOC_MBUS_PACKING_1_5X8,
206 .order = SOC_MBUS_ORDER_LE,
207 .layout = SOC_MBUS_LAYOUT_PACKED,
208 },
209}, {
210 .code = V4L2_MBUS_FMT_YVYU8_1_5X8,
211 .fmt = {
212 .fourcc = V4L2_PIX_FMT_YVU420,
213 .name = "YVYU 4:2:0",
214 .bits_per_sample = 8,
215 .packing = SOC_MBUS_PACKING_1_5X8,
216 .order = SOC_MBUS_ORDER_LE,
217 .layout = SOC_MBUS_LAYOUT_PACKED,
218 },
219}, {
220 .code = V4L2_MBUS_FMT_UYVY8_1X16,
221 .fmt = {
222 .fourcc = V4L2_PIX_FMT_UYVY,
223 .name = "UYVY 16bit",
224 .bits_per_sample = 16,
225 .packing = SOC_MBUS_PACKING_EXTEND16,
226 .order = SOC_MBUS_ORDER_LE,
227 .layout = SOC_MBUS_LAYOUT_PACKED,
228 },
229}, {
230 .code = V4L2_MBUS_FMT_VYUY8_1X16,
231 .fmt = {
232 .fourcc = V4L2_PIX_FMT_VYUY,
233 .name = "VYUY 16bit",
234 .bits_per_sample = 16,
235 .packing = SOC_MBUS_PACKING_EXTEND16,
236 .order = SOC_MBUS_ORDER_LE,
237 .layout = SOC_MBUS_LAYOUT_PACKED,
238 },
239}, {
240 .code = V4L2_MBUS_FMT_YUYV8_1X16,
241 .fmt = {
242 .fourcc = V4L2_PIX_FMT_YUYV,
243 .name = "YUYV 16bit",
244 .bits_per_sample = 16,
245 .packing = SOC_MBUS_PACKING_EXTEND16,
246 .order = SOC_MBUS_ORDER_LE,
247 .layout = SOC_MBUS_LAYOUT_PACKED,
248 },
249}, {
250 .code = V4L2_MBUS_FMT_YVYU8_1X16,
251 .fmt = {
252 .fourcc = V4L2_PIX_FMT_YVYU,
253 .name = "YVYU 16bit",
254 .bits_per_sample = 16,
255 .packing = SOC_MBUS_PACKING_EXTEND16,
256 .order = SOC_MBUS_ORDER_LE,
257 .layout = SOC_MBUS_LAYOUT_PACKED,
258 },
259}, {
260 .code = V4L2_MBUS_FMT_SGRBG8_1X8,
261 .fmt = {
262 .fourcc = V4L2_PIX_FMT_SGRBG8,
263 .name = "Bayer 8 GRBG",
264 .bits_per_sample = 8,
265 .packing = SOC_MBUS_PACKING_NONE,
266 .order = SOC_MBUS_ORDER_LE,
267 .layout = SOC_MBUS_LAYOUT_PACKED,
268 },
269}, {
270 .code = V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8,
271 .fmt = {
272 .fourcc = V4L2_PIX_FMT_SGRBG10DPCM8,
273 .name = "Bayer 10 BGGR DPCM 8",
274 .bits_per_sample = 8,
275 .packing = SOC_MBUS_PACKING_NONE,
276 .order = SOC_MBUS_ORDER_LE,
277 .layout = SOC_MBUS_LAYOUT_PACKED,
278 },
279}, {
280 .code = V4L2_MBUS_FMT_SGBRG10_1X10,
281 .fmt = {
282 .fourcc = V4L2_PIX_FMT_SGBRG10,
283 .name = "Bayer 10 GBRG",
284 .bits_per_sample = 10,
285 .packing = SOC_MBUS_PACKING_EXTEND16,
286 .order = SOC_MBUS_ORDER_LE,
287 .layout = SOC_MBUS_LAYOUT_PACKED,
288 },
289}, {
290 .code = V4L2_MBUS_FMT_SGRBG10_1X10,
291 .fmt = {
292 .fourcc = V4L2_PIX_FMT_SGRBG10,
293 .name = "Bayer 10 GRBG",
294 .bits_per_sample = 10,
295 .packing = SOC_MBUS_PACKING_EXTEND16,
296 .order = SOC_MBUS_ORDER_LE,
297 .layout = SOC_MBUS_LAYOUT_PACKED,
298 },
299}, {
300 .code = V4L2_MBUS_FMT_SRGGB10_1X10,
301 .fmt = {
302 .fourcc = V4L2_PIX_FMT_SRGGB10,
303 .name = "Bayer 10 RGGB",
304 .bits_per_sample = 10,
305 .packing = SOC_MBUS_PACKING_EXTEND16,
306 .order = SOC_MBUS_ORDER_LE,
307 .layout = SOC_MBUS_LAYOUT_PACKED,
308 },
309}, {
310 .code = V4L2_MBUS_FMT_SBGGR12_1X12,
311 .fmt = {
312 .fourcc = V4L2_PIX_FMT_SBGGR12,
313 .name = "Bayer 12 BGGR",
314 .bits_per_sample = 12,
315 .packing = SOC_MBUS_PACKING_EXTEND16,
316 .order = SOC_MBUS_ORDER_LE,
317 .layout = SOC_MBUS_LAYOUT_PACKED,
318 },
319}, {
320 .code = V4L2_MBUS_FMT_SGBRG12_1X12,
321 .fmt = {
322 .fourcc = V4L2_PIX_FMT_SGBRG12,
323 .name = "Bayer 12 GBRG",
324 .bits_per_sample = 12,
325 .packing = SOC_MBUS_PACKING_EXTEND16,
326 .order = SOC_MBUS_ORDER_LE,
327 .layout = SOC_MBUS_LAYOUT_PACKED,
328 },
329}, {
330 .code = V4L2_MBUS_FMT_SGRBG12_1X12,
331 .fmt = {
332 .fourcc = V4L2_PIX_FMT_SGRBG12,
333 .name = "Bayer 12 GRBG",
334 .bits_per_sample = 12,
335 .packing = SOC_MBUS_PACKING_EXTEND16,
336 .order = SOC_MBUS_ORDER_LE,
337 .layout = SOC_MBUS_LAYOUT_PACKED,
338 },
339}, {
340 .code = V4L2_MBUS_FMT_SRGGB12_1X12,
341 .fmt = {
342 .fourcc = V4L2_PIX_FMT_SRGGB12,
343 .name = "Bayer 12 RGGB",
344 .bits_per_sample = 12,
345 .packing = SOC_MBUS_PACKING_EXTEND16,
346 .order = SOC_MBUS_ORDER_LE,
347 .layout = SOC_MBUS_LAYOUT_PACKED,
348 },
349},
350};
351
352int soc_mbus_samples_per_pixel(const struct soc_mbus_pixelfmt *mf,
353 unsigned int *numerator, unsigned int *denominator)
354{
355 switch (mf->packing) {
356 case SOC_MBUS_PACKING_NONE:
357 case SOC_MBUS_PACKING_EXTEND16:
358 *numerator = 1;
359 *denominator = 1;
360 return 0;
361 case SOC_MBUS_PACKING_2X8_PADHI:
362 case SOC_MBUS_PACKING_2X8_PADLO:
363 *numerator = 2;
364 *denominator = 1;
365 return 0;
366 case SOC_MBUS_PACKING_1_5X8:
367 *numerator = 3;
368 *denominator = 2;
369 return 0;
370 case SOC_MBUS_PACKING_VARIABLE:
371 *numerator = 0;
372 *denominator = 1;
373 return 0;
374 }
375 return -EINVAL;
376}
377EXPORT_SYMBOL(soc_mbus_samples_per_pixel);
378
379s32 soc_mbus_bytes_per_line(u32 width, const struct soc_mbus_pixelfmt *mf)
380{
381 if (mf->layout != SOC_MBUS_LAYOUT_PACKED)
382 return width * mf->bits_per_sample / 8;
383
384 switch (mf->packing) {
385 case SOC_MBUS_PACKING_NONE:
386 return width * mf->bits_per_sample / 8;
387 case SOC_MBUS_PACKING_2X8_PADHI:
388 case SOC_MBUS_PACKING_2X8_PADLO:
389 case SOC_MBUS_PACKING_EXTEND16:
390 return width * 2;
391 case SOC_MBUS_PACKING_1_5X8:
392 return width * 3 / 2;
393 case SOC_MBUS_PACKING_VARIABLE:
394 return 0;
395 }
396 return -EINVAL;
397}
398EXPORT_SYMBOL(soc_mbus_bytes_per_line);
399
400s32 soc_mbus_image_size(const struct soc_mbus_pixelfmt *mf,
401 u32 bytes_per_line, u32 height)
402{
403 if (mf->layout == SOC_MBUS_LAYOUT_PACKED)
404 return bytes_per_line * height;
405
406 switch (mf->packing) {
407 case SOC_MBUS_PACKING_2X8_PADHI:
408 case SOC_MBUS_PACKING_2X8_PADLO:
409 return bytes_per_line * height * 2;
410 case SOC_MBUS_PACKING_1_5X8:
411 return bytes_per_line * height * 3 / 2;
412 default:
413 return -EINVAL;
414 }
415}
416EXPORT_SYMBOL(soc_mbus_image_size);
417
418const struct soc_mbus_pixelfmt *soc_mbus_find_fmtdesc(
419 enum v4l2_mbus_pixelcode code,
420 const struct soc_mbus_lookup *lookup,
421 int n)
422{
423 int i;
424
425 for (i = 0; i < n; i++)
426 if (lookup[i].code == code)
427 return &lookup[i].fmt;
428
429 return NULL;
430}
431EXPORT_SYMBOL(soc_mbus_find_fmtdesc);
432
433const struct soc_mbus_pixelfmt *soc_mbus_get_fmtdesc(
434 enum v4l2_mbus_pixelcode code)
435{
436 return soc_mbus_find_fmtdesc(code, mbus_fmt, ARRAY_SIZE(mbus_fmt));
437}
438EXPORT_SYMBOL(soc_mbus_get_fmtdesc);
439
440unsigned int soc_mbus_config_compatible(const struct v4l2_mbus_config *cfg,
441 unsigned int flags)
442{
443 unsigned long common_flags;
444 bool hsync = true, vsync = true, pclk, data, mode;
445 bool mipi_lanes, mipi_clock;
446
447 common_flags = cfg->flags & flags;
448
449 switch (cfg->type) {
450 case V4L2_MBUS_PARALLEL:
451 hsync = common_flags & (V4L2_MBUS_HSYNC_ACTIVE_HIGH |
452 V4L2_MBUS_HSYNC_ACTIVE_LOW);
453 vsync = common_flags & (V4L2_MBUS_VSYNC_ACTIVE_HIGH |
454 V4L2_MBUS_VSYNC_ACTIVE_LOW);
455 case V4L2_MBUS_BT656:
456 pclk = common_flags & (V4L2_MBUS_PCLK_SAMPLE_RISING |
457 V4L2_MBUS_PCLK_SAMPLE_FALLING);
458 data = common_flags & (V4L2_MBUS_DATA_ACTIVE_HIGH |
459 V4L2_MBUS_DATA_ACTIVE_LOW);
460 mode = common_flags & (V4L2_MBUS_MASTER | V4L2_MBUS_SLAVE);
461 return (!hsync || !vsync || !pclk || !data || !mode) ?
462 0 : common_flags;
463 case V4L2_MBUS_CSI2:
464 mipi_lanes = common_flags & V4L2_MBUS_CSI2_LANES;
465 mipi_clock = common_flags & (V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK |
466 V4L2_MBUS_CSI2_CONTINUOUS_CLOCK);
467 return (!mipi_lanes || !mipi_clock) ? 0 : common_flags;
468 }
469 return 0;
470}
471EXPORT_SYMBOL(soc_mbus_config_compatible);
472
473static int __init soc_mbus_init(void)
474{
475 return 0;
476}
477
478static void __exit soc_mbus_exit(void)
479{
480}
481
482module_init(soc_mbus_init);
483module_exit(soc_mbus_exit);
484
485MODULE_DESCRIPTION("soc-camera media bus interface");
486MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
487MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/timblogiw.c b/drivers/media/video/timblogiw.c
deleted file mode 100644
index 02194c056b00..000000000000
--- a/drivers/media/video/timblogiw.c
+++ /dev/null
@@ -1,880 +0,0 @@
1/*
2 * timblogiw.c timberdale FPGA LogiWin Video In driver
3 * Copyright (c) 2009-2010 Intel Corporation
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18
19/* Supports:
20 * Timberdale FPGA LogiWin Video In
21 */
22
23#include <linux/platform_device.h>
24#include <linux/slab.h>
25#include <linux/dmaengine.h>
26#include <linux/scatterlist.h>
27#include <linux/interrupt.h>
28#include <linux/list.h>
29#include <linux/i2c.h>
30#include <linux/module.h>
31#include <media/v4l2-ioctl.h>
32#include <media/v4l2-device.h>
33#include <media/videobuf-dma-contig.h>
34#include <media/timb_video.h>
35
36#define DRIVER_NAME "timb-video"
37
38#define TIMBLOGIWIN_NAME "Timberdale Video-In"
39#define TIMBLOGIW_VERSION_CODE 0x04
40
41#define TIMBLOGIW_LINES_PER_DESC 44
42#define TIMBLOGIW_MAX_VIDEO_MEM 16
43
44#define TIMBLOGIW_HAS_DECODER(lw) (lw->pdata.encoder.module_name)
45
46
47struct timblogiw {
48 struct video_device video_dev;
49 struct v4l2_device v4l2_dev; /* mutual exclusion */
50 struct mutex lock;
51 struct device *dev;
52 struct timb_video_platform_data pdata;
53 struct v4l2_subdev *sd_enc; /* encoder */
54 bool opened;
55};
56
57struct timblogiw_tvnorm {
58 v4l2_std_id std;
59 u16 width;
60 u16 height;
61 u8 fps;
62};
63
64struct timblogiw_fh {
65 struct videobuf_queue vb_vidq;
66 struct timblogiw_tvnorm const *cur_norm;
67 struct list_head capture;
68 struct dma_chan *chan;
69 spinlock_t queue_lock; /* mutual exclusion */
70 unsigned int frame_count;
71};
72
73struct timblogiw_buffer {
74 /* common v4l buffer stuff -- must be first */
75 struct videobuf_buffer vb;
76 struct scatterlist sg[16];
77 dma_cookie_t cookie;
78 struct timblogiw_fh *fh;
79};
80
81const struct timblogiw_tvnorm timblogiw_tvnorms[] = {
82 {
83 .std = V4L2_STD_PAL,
84 .width = 720,
85 .height = 576,
86 .fps = 25
87 },
88 {
89 .std = V4L2_STD_NTSC,
90 .width = 720,
91 .height = 480,
92 .fps = 30
93 }
94};
95
96static int timblogiw_bytes_per_line(const struct timblogiw_tvnorm *norm)
97{
98 return norm->width * 2;
99}
100
101
102static int timblogiw_frame_size(const struct timblogiw_tvnorm *norm)
103{
104 return norm->height * timblogiw_bytes_per_line(norm);
105}
106
107static const struct timblogiw_tvnorm *timblogiw_get_norm(const v4l2_std_id std)
108{
109 int i;
110 for (i = 0; i < ARRAY_SIZE(timblogiw_tvnorms); i++)
111 if (timblogiw_tvnorms[i].std & std)
112 return timblogiw_tvnorms + i;
113
114 /* default to first element */
115 return timblogiw_tvnorms;
116}
117
118static void timblogiw_dma_cb(void *data)
119{
120 struct timblogiw_buffer *buf = data;
121 struct timblogiw_fh *fh = buf->fh;
122 struct videobuf_buffer *vb = &buf->vb;
123
124 spin_lock(&fh->queue_lock);
125
126 /* mark the transfer done */
127 buf->cookie = -1;
128
129 fh->frame_count++;
130
131 if (vb->state != VIDEOBUF_ERROR) {
132 list_del(&vb->queue);
133 do_gettimeofday(&vb->ts);
134 vb->field_count = fh->frame_count * 2;
135 vb->state = VIDEOBUF_DONE;
136
137 wake_up(&vb->done);
138 }
139
140 if (!list_empty(&fh->capture)) {
141 vb = list_entry(fh->capture.next, struct videobuf_buffer,
142 queue);
143 vb->state = VIDEOBUF_ACTIVE;
144 }
145
146 spin_unlock(&fh->queue_lock);
147}
148
149static bool timblogiw_dma_filter_fn(struct dma_chan *chan, void *filter_param)
150{
151 return chan->chan_id == (uintptr_t)filter_param;
152}
153
154/* IOCTL functions */
155
156static int timblogiw_g_fmt(struct file *file, void *priv,
157 struct v4l2_format *format)
158{
159 struct video_device *vdev = video_devdata(file);
160 struct timblogiw *lw = video_get_drvdata(vdev);
161 struct timblogiw_fh *fh = priv;
162
163 dev_dbg(&vdev->dev, "%s entry\n", __func__);
164
165 if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
166 return -EINVAL;
167
168 mutex_lock(&lw->lock);
169
170 format->fmt.pix.width = fh->cur_norm->width;
171 format->fmt.pix.height = fh->cur_norm->height;
172 format->fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
173 format->fmt.pix.bytesperline = timblogiw_bytes_per_line(fh->cur_norm);
174 format->fmt.pix.sizeimage = timblogiw_frame_size(fh->cur_norm);
175 format->fmt.pix.field = V4L2_FIELD_NONE;
176
177 mutex_unlock(&lw->lock);
178
179 return 0;
180}
181
182static int timblogiw_try_fmt(struct file *file, void *priv,
183 struct v4l2_format *format)
184{
185 struct video_device *vdev = video_devdata(file);
186 struct v4l2_pix_format *pix = &format->fmt.pix;
187
188 dev_dbg(&vdev->dev,
189 "%s - width=%d, height=%d, pixelformat=%d, field=%d\n"
190 "bytes per line %d, size image: %d, colorspace: %d\n",
191 __func__,
192 pix->width, pix->height, pix->pixelformat, pix->field,
193 pix->bytesperline, pix->sizeimage, pix->colorspace);
194
195 if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
196 return -EINVAL;
197
198 if (pix->field != V4L2_FIELD_NONE)
199 return -EINVAL;
200
201 if (pix->pixelformat != V4L2_PIX_FMT_UYVY)
202 return -EINVAL;
203
204 return 0;
205}
206
207static int timblogiw_s_fmt(struct file *file, void *priv,
208 struct v4l2_format *format)
209{
210 struct video_device *vdev = video_devdata(file);
211 struct timblogiw *lw = video_get_drvdata(vdev);
212 struct timblogiw_fh *fh = priv;
213 struct v4l2_pix_format *pix = &format->fmt.pix;
214 int err;
215
216 mutex_lock(&lw->lock);
217
218 err = timblogiw_try_fmt(file, priv, format);
219 if (err)
220 goto out;
221
222 if (videobuf_queue_is_busy(&fh->vb_vidq)) {
223 dev_err(&vdev->dev, "%s queue busy\n", __func__);
224 err = -EBUSY;
225 goto out;
226 }
227
228 pix->width = fh->cur_norm->width;
229 pix->height = fh->cur_norm->height;
230
231out:
232 mutex_unlock(&lw->lock);
233 return err;
234}
235
236static int timblogiw_querycap(struct file *file, void *priv,
237 struct v4l2_capability *cap)
238{
239 struct video_device *vdev = video_devdata(file);
240
241 dev_dbg(&vdev->dev, "%s: Entry\n", __func__);
242 memset(cap, 0, sizeof(*cap));
243 strncpy(cap->card, TIMBLOGIWIN_NAME, sizeof(cap->card)-1);
244 strncpy(cap->driver, DRIVER_NAME, sizeof(cap->driver) - 1);
245 strlcpy(cap->bus_info, vdev->name, sizeof(cap->bus_info));
246 cap->version = TIMBLOGIW_VERSION_CODE;
247 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
248 V4L2_CAP_READWRITE;
249
250 return 0;
251}
252
253static int timblogiw_enum_fmt(struct file *file, void *priv,
254 struct v4l2_fmtdesc *fmt)
255{
256 struct video_device *vdev = video_devdata(file);
257
258 dev_dbg(&vdev->dev, "%s, index: %d\n", __func__, fmt->index);
259
260 if (fmt->index != 0)
261 return -EINVAL;
262 memset(fmt, 0, sizeof(*fmt));
263 fmt->index = 0;
264 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
265 strncpy(fmt->description, "4:2:2, packed, YUYV",
266 sizeof(fmt->description)-1);
267 fmt->pixelformat = V4L2_PIX_FMT_UYVY;
268
269 return 0;
270}
271
272static int timblogiw_g_parm(struct file *file, void *priv,
273 struct v4l2_streamparm *sp)
274{
275 struct timblogiw_fh *fh = priv;
276 struct v4l2_captureparm *cp = &sp->parm.capture;
277
278 cp->capability = V4L2_CAP_TIMEPERFRAME;
279 cp->timeperframe.numerator = 1;
280 cp->timeperframe.denominator = fh->cur_norm->fps;
281
282 return 0;
283}
284
285static int timblogiw_reqbufs(struct file *file, void *priv,
286 struct v4l2_requestbuffers *rb)
287{
288 struct video_device *vdev = video_devdata(file);
289 struct timblogiw_fh *fh = priv;
290
291 dev_dbg(&vdev->dev, "%s: entry\n", __func__);
292
293 return videobuf_reqbufs(&fh->vb_vidq, rb);
294}
295
296static int timblogiw_querybuf(struct file *file, void *priv,
297 struct v4l2_buffer *b)
298{
299 struct video_device *vdev = video_devdata(file);
300 struct timblogiw_fh *fh = priv;
301
302 dev_dbg(&vdev->dev, "%s: entry\n", __func__);
303
304 return videobuf_querybuf(&fh->vb_vidq, b);
305}
306
307static int timblogiw_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
308{
309 struct video_device *vdev = video_devdata(file);
310 struct timblogiw_fh *fh = priv;
311
312 dev_dbg(&vdev->dev, "%s: entry\n", __func__);
313
314 return videobuf_qbuf(&fh->vb_vidq, b);
315}
316
317static int timblogiw_dqbuf(struct file *file, void *priv,
318 struct v4l2_buffer *b)
319{
320 struct video_device *vdev = video_devdata(file);
321 struct timblogiw_fh *fh = priv;
322
323 dev_dbg(&vdev->dev, "%s: entry\n", __func__);
324
325 return videobuf_dqbuf(&fh->vb_vidq, b, file->f_flags & O_NONBLOCK);
326}
327
328static int timblogiw_g_std(struct file *file, void *priv, v4l2_std_id *std)
329{
330 struct video_device *vdev = video_devdata(file);
331 struct timblogiw_fh *fh = priv;
332
333 dev_dbg(&vdev->dev, "%s: entry\n", __func__);
334
335 *std = fh->cur_norm->std;
336 return 0;
337}
338
339static int timblogiw_s_std(struct file *file, void *priv, v4l2_std_id *std)
340{
341 struct video_device *vdev = video_devdata(file);
342 struct timblogiw *lw = video_get_drvdata(vdev);
343 struct timblogiw_fh *fh = priv;
344 int err = 0;
345
346 dev_dbg(&vdev->dev, "%s: entry\n", __func__);
347
348 mutex_lock(&lw->lock);
349
350 if (TIMBLOGIW_HAS_DECODER(lw))
351 err = v4l2_subdev_call(lw->sd_enc, core, s_std, *std);
352
353 if (!err)
354 fh->cur_norm = timblogiw_get_norm(*std);
355
356 mutex_unlock(&lw->lock);
357
358 return err;
359}
360
361static int timblogiw_enuminput(struct file *file, void *priv,
362 struct v4l2_input *inp)
363{
364 struct video_device *vdev = video_devdata(file);
365 int i;
366
367 dev_dbg(&vdev->dev, "%s: Entry\n", __func__);
368
369 if (inp->index != 0)
370 return -EINVAL;
371
372 inp->index = 0;
373
374 strncpy(inp->name, "Timb input 1", sizeof(inp->name) - 1);
375 inp->type = V4L2_INPUT_TYPE_CAMERA;
376
377 inp->std = 0;
378 for (i = 0; i < ARRAY_SIZE(timblogiw_tvnorms); i++)
379 inp->std |= timblogiw_tvnorms[i].std;
380
381 return 0;
382}
383
384static int timblogiw_g_input(struct file *file, void *priv,
385 unsigned int *input)
386{
387 struct video_device *vdev = video_devdata(file);
388
389 dev_dbg(&vdev->dev, "%s: Entry\n", __func__);
390
391 *input = 0;
392
393 return 0;
394}
395
396static int timblogiw_s_input(struct file *file, void *priv, unsigned int input)
397{
398 struct video_device *vdev = video_devdata(file);
399
400 dev_dbg(&vdev->dev, "%s: Entry\n", __func__);
401
402 if (input != 0)
403 return -EINVAL;
404 return 0;
405}
406
407static int timblogiw_streamon(struct file *file, void *priv, unsigned int type)
408{
409 struct video_device *vdev = video_devdata(file);
410 struct timblogiw_fh *fh = priv;
411
412 dev_dbg(&vdev->dev, "%s: entry\n", __func__);
413
414 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
415 dev_dbg(&vdev->dev, "%s - No capture device\n", __func__);
416 return -EINVAL;
417 }
418
419 fh->frame_count = 0;
420 return videobuf_streamon(&fh->vb_vidq);
421}
422
423static int timblogiw_streamoff(struct file *file, void *priv,
424 unsigned int type)
425{
426 struct video_device *vdev = video_devdata(file);
427 struct timblogiw_fh *fh = priv;
428
429 dev_dbg(&vdev->dev, "%s entry\n", __func__);
430
431 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
432 return -EINVAL;
433
434 return videobuf_streamoff(&fh->vb_vidq);
435}
436
437static int timblogiw_querystd(struct file *file, void *priv, v4l2_std_id *std)
438{
439 struct video_device *vdev = video_devdata(file);
440 struct timblogiw *lw = video_get_drvdata(vdev);
441 struct timblogiw_fh *fh = priv;
442
443 dev_dbg(&vdev->dev, "%s entry\n", __func__);
444
445 if (TIMBLOGIW_HAS_DECODER(lw))
446 return v4l2_subdev_call(lw->sd_enc, video, querystd, std);
447 else {
448 *std = fh->cur_norm->std;
449 return 0;
450 }
451}
452
453static int timblogiw_enum_framesizes(struct file *file, void *priv,
454 struct v4l2_frmsizeenum *fsize)
455{
456 struct video_device *vdev = video_devdata(file);
457 struct timblogiw_fh *fh = priv;
458
459 dev_dbg(&vdev->dev, "%s - index: %d, format: %d\n", __func__,
460 fsize->index, fsize->pixel_format);
461
462 if ((fsize->index != 0) ||
463 (fsize->pixel_format != V4L2_PIX_FMT_UYVY))
464 return -EINVAL;
465
466 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
467 fsize->discrete.width = fh->cur_norm->width;
468 fsize->discrete.height = fh->cur_norm->height;
469
470 return 0;
471}
472
473/* Video buffer functions */
474
475static int buffer_setup(struct videobuf_queue *vq, unsigned int *count,
476 unsigned int *size)
477{
478 struct timblogiw_fh *fh = vq->priv_data;
479
480 *size = timblogiw_frame_size(fh->cur_norm);
481
482 if (!*count)
483 *count = 32;
484
485 while (*size * *count > TIMBLOGIW_MAX_VIDEO_MEM * 1024 * 1024)
486 (*count)--;
487
488 return 0;
489}
490
491static int buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
492 enum v4l2_field field)
493{
494 struct timblogiw_fh *fh = vq->priv_data;
495 struct timblogiw_buffer *buf = container_of(vb, struct timblogiw_buffer,
496 vb);
497 unsigned int data_size = timblogiw_frame_size(fh->cur_norm);
498 int err = 0;
499
500 if (vb->baddr && vb->bsize < data_size)
501 /* User provided buffer, but it is too small */
502 return -ENOMEM;
503
504 vb->size = data_size;
505 vb->width = fh->cur_norm->width;
506 vb->height = fh->cur_norm->height;
507 vb->field = field;
508
509 if (vb->state == VIDEOBUF_NEEDS_INIT) {
510 int i;
511 unsigned int size;
512 unsigned int bytes_per_desc = TIMBLOGIW_LINES_PER_DESC *
513 timblogiw_bytes_per_line(fh->cur_norm);
514 dma_addr_t addr;
515
516 sg_init_table(buf->sg, ARRAY_SIZE(buf->sg));
517
518 err = videobuf_iolock(vq, vb, NULL);
519 if (err)
520 goto err;
521
522 addr = videobuf_to_dma_contig(vb);
523 for (i = 0, size = 0; size < data_size; i++) {
524 sg_dma_address(buf->sg + i) = addr + size;
525 size += bytes_per_desc;
526 sg_dma_len(buf->sg + i) = (size > data_size) ?
527 (bytes_per_desc - (size - data_size)) :
528 bytes_per_desc;
529 }
530
531 vb->state = VIDEOBUF_PREPARED;
532 buf->cookie = -1;
533 buf->fh = fh;
534 }
535
536 return 0;
537
538err:
539 videobuf_dma_contig_free(vq, vb);
540 vb->state = VIDEOBUF_NEEDS_INIT;
541 return err;
542}
543
544static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
545{
546 struct timblogiw_fh *fh = vq->priv_data;
547 struct timblogiw_buffer *buf = container_of(vb, struct timblogiw_buffer,
548 vb);
549 struct dma_async_tx_descriptor *desc;
550 int sg_elems;
551 int bytes_per_desc = TIMBLOGIW_LINES_PER_DESC *
552 timblogiw_bytes_per_line(fh->cur_norm);
553
554 sg_elems = timblogiw_frame_size(fh->cur_norm) / bytes_per_desc;
555 sg_elems +=
556 (timblogiw_frame_size(fh->cur_norm) % bytes_per_desc) ? 1 : 0;
557
558 if (list_empty(&fh->capture))
559 vb->state = VIDEOBUF_ACTIVE;
560 else
561 vb->state = VIDEOBUF_QUEUED;
562
563 list_add_tail(&vb->queue, &fh->capture);
564
565 spin_unlock_irq(&fh->queue_lock);
566
567 desc = dmaengine_prep_slave_sg(fh->chan,
568 buf->sg, sg_elems, DMA_DEV_TO_MEM,
569 DMA_PREP_INTERRUPT | DMA_COMPL_SKIP_SRC_UNMAP);
570 if (!desc) {
571 spin_lock_irq(&fh->queue_lock);
572 list_del_init(&vb->queue);
573 vb->state = VIDEOBUF_PREPARED;
574 return;
575 }
576
577 desc->callback_param = buf;
578 desc->callback = timblogiw_dma_cb;
579
580 buf->cookie = desc->tx_submit(desc);
581
582 spin_lock_irq(&fh->queue_lock);
583}
584
585static void buffer_release(struct videobuf_queue *vq,
586 struct videobuf_buffer *vb)
587{
588 struct timblogiw_fh *fh = vq->priv_data;
589 struct timblogiw_buffer *buf = container_of(vb, struct timblogiw_buffer,
590 vb);
591
592 videobuf_waiton(vq, vb, 0, 0);
593 if (buf->cookie >= 0)
594 dma_sync_wait(fh->chan, buf->cookie);
595
596 videobuf_dma_contig_free(vq, vb);
597 vb->state = VIDEOBUF_NEEDS_INIT;
598}
599
600static struct videobuf_queue_ops timblogiw_video_qops = {
601 .buf_setup = buffer_setup,
602 .buf_prepare = buffer_prepare,
603 .buf_queue = buffer_queue,
604 .buf_release = buffer_release,
605};
606
607/* Device Operations functions */
608
609static int timblogiw_open(struct file *file)
610{
611 struct video_device *vdev = video_devdata(file);
612 struct timblogiw *lw = video_get_drvdata(vdev);
613 struct timblogiw_fh *fh;
614 v4l2_std_id std;
615 dma_cap_mask_t mask;
616 int err = 0;
617
618 dev_dbg(&vdev->dev, "%s: entry\n", __func__);
619
620 mutex_lock(&lw->lock);
621 if (lw->opened) {
622 err = -EBUSY;
623 goto out;
624 }
625
626 if (TIMBLOGIW_HAS_DECODER(lw) && !lw->sd_enc) {
627 struct i2c_adapter *adapt;
628
629 /* find the video decoder */
630 adapt = i2c_get_adapter(lw->pdata.i2c_adapter);
631 if (!adapt) {
632 dev_err(&vdev->dev, "No I2C bus #%d\n",
633 lw->pdata.i2c_adapter);
634 err = -ENODEV;
635 goto out;
636 }
637
638 /* now find the encoder */
639 lw->sd_enc = v4l2_i2c_new_subdev_board(&lw->v4l2_dev, adapt,
640 lw->pdata.encoder.info, NULL);
641
642 i2c_put_adapter(adapt);
643
644 if (!lw->sd_enc) {
645 dev_err(&vdev->dev, "Failed to get encoder: %s\n",
646 lw->pdata.encoder.module_name);
647 err = -ENODEV;
648 goto out;
649 }
650 }
651
652 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
653 if (!fh) {
654 err = -ENOMEM;
655 goto out;
656 }
657
658 fh->cur_norm = timblogiw_tvnorms;
659 timblogiw_querystd(file, fh, &std);
660 fh->cur_norm = timblogiw_get_norm(std);
661
662 INIT_LIST_HEAD(&fh->capture);
663 spin_lock_init(&fh->queue_lock);
664
665 dma_cap_zero(mask);
666 dma_cap_set(DMA_SLAVE, mask);
667 dma_cap_set(DMA_PRIVATE, mask);
668
669 /* find the DMA channel */
670 fh->chan = dma_request_channel(mask, timblogiw_dma_filter_fn,
671 (void *)(uintptr_t)lw->pdata.dma_channel);
672 if (!fh->chan) {
673 dev_err(&vdev->dev, "Failed to get DMA channel\n");
674 kfree(fh);
675 err = -ENODEV;
676 goto out;
677 }
678
679 file->private_data = fh;
680 videobuf_queue_dma_contig_init(&fh->vb_vidq,
681 &timblogiw_video_qops, lw->dev, &fh->queue_lock,
682 V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE,
683 sizeof(struct timblogiw_buffer), fh, NULL);
684
685 lw->opened = true;
686out:
687 mutex_unlock(&lw->lock);
688
689 return err;
690}
691
692static int timblogiw_close(struct file *file)
693{
694 struct video_device *vdev = video_devdata(file);
695 struct timblogiw *lw = video_get_drvdata(vdev);
696 struct timblogiw_fh *fh = file->private_data;
697
698 dev_dbg(&vdev->dev, "%s: Entry\n", __func__);
699
700 videobuf_stop(&fh->vb_vidq);
701 videobuf_mmap_free(&fh->vb_vidq);
702
703 dma_release_channel(fh->chan);
704
705 kfree(fh);
706
707 mutex_lock(&lw->lock);
708 lw->opened = false;
709 mutex_unlock(&lw->lock);
710 return 0;
711}
712
713static ssize_t timblogiw_read(struct file *file, char __user *data,
714 size_t count, loff_t *ppos)
715{
716 struct video_device *vdev = video_devdata(file);
717 struct timblogiw_fh *fh = file->private_data;
718
719 dev_dbg(&vdev->dev, "%s: entry\n", __func__);
720
721 return videobuf_read_stream(&fh->vb_vidq, data, count, ppos, 0,
722 file->f_flags & O_NONBLOCK);
723}
724
725static unsigned int timblogiw_poll(struct file *file,
726 struct poll_table_struct *wait)
727{
728 struct video_device *vdev = video_devdata(file);
729 struct timblogiw_fh *fh = file->private_data;
730
731 dev_dbg(&vdev->dev, "%s: entry\n", __func__);
732
733 return videobuf_poll_stream(file, &fh->vb_vidq, wait);
734}
735
736static int timblogiw_mmap(struct file *file, struct vm_area_struct *vma)
737{
738 struct video_device *vdev = video_devdata(file);
739 struct timblogiw_fh *fh = file->private_data;
740
741 dev_dbg(&vdev->dev, "%s: entry\n", __func__);
742
743 return videobuf_mmap_mapper(&fh->vb_vidq, vma);
744}
745
746/* Platform device functions */
747
748static __devinitconst struct v4l2_ioctl_ops timblogiw_ioctl_ops = {
749 .vidioc_querycap = timblogiw_querycap,
750 .vidioc_enum_fmt_vid_cap = timblogiw_enum_fmt,
751 .vidioc_g_fmt_vid_cap = timblogiw_g_fmt,
752 .vidioc_try_fmt_vid_cap = timblogiw_try_fmt,
753 .vidioc_s_fmt_vid_cap = timblogiw_s_fmt,
754 .vidioc_g_parm = timblogiw_g_parm,
755 .vidioc_reqbufs = timblogiw_reqbufs,
756 .vidioc_querybuf = timblogiw_querybuf,
757 .vidioc_qbuf = timblogiw_qbuf,
758 .vidioc_dqbuf = timblogiw_dqbuf,
759 .vidioc_g_std = timblogiw_g_std,
760 .vidioc_s_std = timblogiw_s_std,
761 .vidioc_enum_input = timblogiw_enuminput,
762 .vidioc_g_input = timblogiw_g_input,
763 .vidioc_s_input = timblogiw_s_input,
764 .vidioc_streamon = timblogiw_streamon,
765 .vidioc_streamoff = timblogiw_streamoff,
766 .vidioc_querystd = timblogiw_querystd,
767 .vidioc_enum_framesizes = timblogiw_enum_framesizes,
768};
769
770static __devinitconst struct v4l2_file_operations timblogiw_fops = {
771 .owner = THIS_MODULE,
772 .open = timblogiw_open,
773 .release = timblogiw_close,
774 .unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */
775 .mmap = timblogiw_mmap,
776 .read = timblogiw_read,
777 .poll = timblogiw_poll,
778};
779
780static __devinitconst struct video_device timblogiw_template = {
781 .name = TIMBLOGIWIN_NAME,
782 .fops = &timblogiw_fops,
783 .ioctl_ops = &timblogiw_ioctl_ops,
784 .release = video_device_release_empty,
785 .minor = -1,
786 .tvnorms = V4L2_STD_PAL | V4L2_STD_NTSC
787};
788
789static int __devinit timblogiw_probe(struct platform_device *pdev)
790{
791 int err;
792 struct timblogiw *lw = NULL;
793 struct timb_video_platform_data *pdata = pdev->dev.platform_data;
794
795 if (!pdata) {
796 dev_err(&pdev->dev, "No platform data\n");
797 err = -EINVAL;
798 goto err;
799 }
800
801 if (!pdata->encoder.module_name)
802 dev_info(&pdev->dev, "Running without decoder\n");
803
804 lw = kzalloc(sizeof(*lw), GFP_KERNEL);
805 if (!lw) {
806 err = -ENOMEM;
807 goto err;
808 }
809
810 if (pdev->dev.parent)
811 lw->dev = pdev->dev.parent;
812 else
813 lw->dev = &pdev->dev;
814
815 memcpy(&lw->pdata, pdata, sizeof(lw->pdata));
816
817 mutex_init(&lw->lock);
818
819 lw->video_dev = timblogiw_template;
820
821 strlcpy(lw->v4l2_dev.name, DRIVER_NAME, sizeof(lw->v4l2_dev.name));
822 err = v4l2_device_register(NULL, &lw->v4l2_dev);
823 if (err)
824 goto err_register;
825
826 lw->video_dev.v4l2_dev = &lw->v4l2_dev;
827
828 platform_set_drvdata(pdev, lw);
829 video_set_drvdata(&lw->video_dev, lw);
830
831 err = video_register_device(&lw->video_dev, VFL_TYPE_GRABBER, 0);
832 if (err) {
833 dev_err(&pdev->dev, "Error reg video: %d\n", err);
834 goto err_request;
835 }
836
837
838 return 0;
839
840err_request:
841 platform_set_drvdata(pdev, NULL);
842 v4l2_device_unregister(&lw->v4l2_dev);
843err_register:
844 kfree(lw);
845err:
846 dev_err(&pdev->dev, "Failed to register: %d\n", err);
847
848 return err;
849}
850
851static int __devexit timblogiw_remove(struct platform_device *pdev)
852{
853 struct timblogiw *lw = platform_get_drvdata(pdev);
854
855 video_unregister_device(&lw->video_dev);
856
857 v4l2_device_unregister(&lw->v4l2_dev);
858
859 kfree(lw);
860
861 platform_set_drvdata(pdev, NULL);
862
863 return 0;
864}
865
866static struct platform_driver timblogiw_platform_driver = {
867 .driver = {
868 .name = DRIVER_NAME,
869 .owner = THIS_MODULE,
870 },
871 .probe = timblogiw_probe,
872 .remove = __devexit_p(timblogiw_remove),
873};
874
875module_platform_driver(timblogiw_platform_driver);
876
877MODULE_DESCRIPTION(TIMBLOGIWIN_NAME);
878MODULE_AUTHOR("Pelagicore AB <info@pelagicore.com>");
879MODULE_LICENSE("GPL v2");
880MODULE_ALIAS("platform:"DRIVER_NAME);
diff --git a/drivers/media/video/via-camera.c b/drivers/media/video/via-camera.c
deleted file mode 100644
index eb404c2ce270..000000000000
--- a/drivers/media/video/via-camera.c
+++ /dev/null
@@ -1,1514 +0,0 @@
1/*
2 * Driver for the VIA Chrome integrated camera controller.
3 *
4 * Copyright 2009,2010 Jonathan Corbet <corbet@lwn.net>
5 * Distributable under the terms of the GNU General Public License, version 2
6 *
7 * This work was supported by the One Laptop Per Child project
8 */
9#include <linux/kernel.h>
10#include <linux/module.h>
11#include <linux/device.h>
12#include <linux/list.h>
13#include <linux/pci.h>
14#include <linux/gpio.h>
15#include <linux/interrupt.h>
16#include <linux/platform_device.h>
17#include <linux/videodev2.h>
18#include <media/v4l2-device.h>
19#include <media/v4l2-ioctl.h>
20#include <media/v4l2-chip-ident.h>
21#include <media/ov7670.h>
22#include <media/videobuf-dma-sg.h>
23#include <linux/delay.h>
24#include <linux/dma-mapping.h>
25#include <linux/pm_qos.h>
26#include <linux/via-core.h>
27#include <linux/via-gpio.h>
28#include <linux/via_i2c.h>
29#include <asm/olpc.h>
30
31#include "via-camera.h"
32
33MODULE_ALIAS("platform:viafb-camera");
34MODULE_AUTHOR("Jonathan Corbet <corbet@lwn.net>");
35MODULE_DESCRIPTION("VIA framebuffer-based camera controller driver");
36MODULE_LICENSE("GPL");
37
38static bool flip_image;
39module_param(flip_image, bool, 0444);
40MODULE_PARM_DESC(flip_image,
41 "If set, the sensor will be instructed to flip the image "
42 "vertically.");
43
44static bool override_serial;
45module_param(override_serial, bool, 0444);
46MODULE_PARM_DESC(override_serial,
47 "The camera driver will normally refuse to load if "
48 "the XO 1.5 serial port is enabled. Set this option "
49 "to force-enable the camera.");
50
51/*
52 * Basic window sizes.
53 */
54#define VGA_WIDTH 640
55#define VGA_HEIGHT 480
56#define QCIF_WIDTH 176
57#define QCIF_HEIGHT 144
58
59/*
60 * The structure describing our camera.
61 */
62enum viacam_opstate { S_IDLE = 0, S_RUNNING = 1 };
63
64struct via_camera {
65 struct v4l2_device v4l2_dev;
66 struct video_device vdev;
67 struct v4l2_subdev *sensor;
68 struct platform_device *platdev;
69 struct viafb_dev *viadev;
70 struct mutex lock;
71 enum viacam_opstate opstate;
72 unsigned long flags;
73 struct pm_qos_request qos_request;
74 /*
75 * GPIO info for power/reset management
76 */
77 int power_gpio;
78 int reset_gpio;
79 /*
80 * I/O memory stuff.
81 */
82 void __iomem *mmio; /* Where the registers live */
83 void __iomem *fbmem; /* Frame buffer memory */
84 u32 fb_offset; /* Reserved memory offset (FB) */
85 /*
86 * Capture buffers and related. The controller supports
87 * up to three, so that's what we have here. These buffers
88 * live in frame buffer memory, so we don't call them "DMA".
89 */
90 unsigned int cb_offsets[3]; /* offsets into fb mem */
91 u8 *cb_addrs[3]; /* Kernel-space addresses */
92 int n_cap_bufs; /* How many are we using? */
93 int next_buf;
94 struct videobuf_queue vb_queue;
95 struct list_head buffer_queue; /* prot. by reg_lock */
96 /*
97 * User tracking.
98 */
99 int users;
100 struct file *owner;
101 /*
102 * Video format information. sensor_format is kept in a form
103 * that we can use to pass to the sensor. We always run the
104 * sensor in VGA resolution, though, and let the controller
105 * downscale things if need be. So we keep the "real*
106 * dimensions separately.
107 */
108 struct v4l2_pix_format sensor_format;
109 struct v4l2_pix_format user_format;
110 enum v4l2_mbus_pixelcode mbus_code;
111};
112
113/*
114 * Yes, this is a hack, but there's only going to be one of these
115 * on any system we know of.
116 */
117static struct via_camera *via_cam_info;
118
119/*
120 * Flag values, manipulated with bitops
121 */
122#define CF_DMA_ACTIVE 0 /* A frame is incoming */
123#define CF_CONFIG_NEEDED 1 /* Must configure hardware */
124
125
126/*
127 * Nasty ugly v4l2 boilerplate.
128 */
129#define sensor_call(cam, optype, func, args...) \
130 v4l2_subdev_call(cam->sensor, optype, func, ##args)
131
132/*
133 * Debugging and related.
134 */
135#define cam_err(cam, fmt, arg...) \
136 dev_err(&(cam)->platdev->dev, fmt, ##arg);
137#define cam_warn(cam, fmt, arg...) \
138 dev_warn(&(cam)->platdev->dev, fmt, ##arg);
139#define cam_dbg(cam, fmt, arg...) \
140 dev_dbg(&(cam)->platdev->dev, fmt, ##arg);
141
142/*
143 * Format handling. This is ripped almost directly from Hans's changes
144 * to cafe_ccic.c. It's a little unfortunate; until this change, we
145 * didn't need to know anything about the format except its byte depth;
146 * now this information must be managed at this level too.
147 */
148static struct via_format {
149 __u8 *desc;
150 __u32 pixelformat;
151 int bpp; /* Bytes per pixel */
152 enum v4l2_mbus_pixelcode mbus_code;
153} via_formats[] = {
154 {
155 .desc = "YUYV 4:2:2",
156 .pixelformat = V4L2_PIX_FMT_YUYV,
157 .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8,
158 .bpp = 2,
159 },
160 /* RGB444 and Bayer should be doable, but have never been
161 tested with this driver. RGB565 seems to work at the default
162 resolution, but results in color corruption when being scaled by
163 viacam_set_scaled(), and is disabled as a result. */
164};
165#define N_VIA_FMTS ARRAY_SIZE(via_formats)
166
167static struct via_format *via_find_format(u32 pixelformat)
168{
169 unsigned i;
170
171 for (i = 0; i < N_VIA_FMTS; i++)
172 if (via_formats[i].pixelformat == pixelformat)
173 return via_formats + i;
174 /* Not found? Then return the first format. */
175 return via_formats;
176}
177
178
179/*--------------------------------------------------------------------------*/
180/*
181 * Sensor power/reset management. This piece is OLPC-specific for
182 * sure; other configurations will have things connected differently.
183 */
184static int via_sensor_power_setup(struct via_camera *cam)
185{
186 int ret;
187
188 cam->power_gpio = viafb_gpio_lookup("VGPIO3");
189 cam->reset_gpio = viafb_gpio_lookup("VGPIO2");
190 if (cam->power_gpio < 0 || cam->reset_gpio < 0) {
191 dev_err(&cam->platdev->dev, "Unable to find GPIO lines\n");
192 return -EINVAL;
193 }
194 ret = gpio_request(cam->power_gpio, "viafb-camera");
195 if (ret) {
196 dev_err(&cam->platdev->dev, "Unable to request power GPIO\n");
197 return ret;
198 }
199 ret = gpio_request(cam->reset_gpio, "viafb-camera");
200 if (ret) {
201 dev_err(&cam->platdev->dev, "Unable to request reset GPIO\n");
202 gpio_free(cam->power_gpio);
203 return ret;
204 }
205 gpio_direction_output(cam->power_gpio, 0);
206 gpio_direction_output(cam->reset_gpio, 0);
207 return 0;
208}
209
210/*
211 * Power up the sensor and perform the reset dance.
212 */
213static void via_sensor_power_up(struct via_camera *cam)
214{
215 gpio_set_value(cam->power_gpio, 1);
216 gpio_set_value(cam->reset_gpio, 0);
217 msleep(20); /* Probably excessive */
218 gpio_set_value(cam->reset_gpio, 1);
219 msleep(20);
220}
221
222static void via_sensor_power_down(struct via_camera *cam)
223{
224 gpio_set_value(cam->power_gpio, 0);
225 gpio_set_value(cam->reset_gpio, 0);
226}
227
228
229static void via_sensor_power_release(struct via_camera *cam)
230{
231 via_sensor_power_down(cam);
232 gpio_free(cam->power_gpio);
233 gpio_free(cam->reset_gpio);
234}
235
236/* --------------------------------------------------------------------------*/
237/* Sensor ops */
238
239/*
240 * Manage the ov7670 "flip" bit, which needs special help.
241 */
242static int viacam_set_flip(struct via_camera *cam)
243{
244 struct v4l2_control ctrl;
245
246 memset(&ctrl, 0, sizeof(ctrl));
247 ctrl.id = V4L2_CID_VFLIP;
248 ctrl.value = flip_image;
249 return sensor_call(cam, core, s_ctrl, &ctrl);
250}
251
252/*
253 * Configure the sensor. It's up to the caller to ensure
254 * that the camera is in the correct operating state.
255 */
256static int viacam_configure_sensor(struct via_camera *cam)
257{
258 struct v4l2_mbus_framefmt mbus_fmt;
259 int ret;
260
261 v4l2_fill_mbus_format(&mbus_fmt, &cam->sensor_format, cam->mbus_code);
262 ret = sensor_call(cam, core, init, 0);
263 if (ret == 0)
264 ret = sensor_call(cam, video, s_mbus_fmt, &mbus_fmt);
265 /*
266 * OV7670 does weird things if flip is set *before* format...
267 */
268 if (ret == 0)
269 ret = viacam_set_flip(cam);
270 return ret;
271}
272
273
274
275/* --------------------------------------------------------------------------*/
276/*
277 * Some simple register accessors; they assume that the lock is held.
278 *
279 * Should we want to support the second capture engine, we could
280 * hide the register difference by adding 0x1000 to registers in the
281 * 0x300-350 range.
282 */
283static inline void viacam_write_reg(struct via_camera *cam,
284 int reg, int value)
285{
286 iowrite32(value, cam->mmio + reg);
287}
288
289static inline int viacam_read_reg(struct via_camera *cam, int reg)
290{
291 return ioread32(cam->mmio + reg);
292}
293
294static inline void viacam_write_reg_mask(struct via_camera *cam,
295 int reg, int value, int mask)
296{
297 int tmp = viacam_read_reg(cam, reg);
298
299 tmp = (tmp & ~mask) | (value & mask);
300 viacam_write_reg(cam, reg, tmp);
301}
302
303
304/* --------------------------------------------------------------------------*/
305/* Interrupt management and handling */
306
307static irqreturn_t viacam_quick_irq(int irq, void *data)
308{
309 struct via_camera *cam = data;
310 irqreturn_t ret = IRQ_NONE;
311 int icv;
312
313 /*
314 * All we do here is to clear the interrupts and tell
315 * the handler thread to wake up.
316 */
317 spin_lock(&cam->viadev->reg_lock);
318 icv = viacam_read_reg(cam, VCR_INTCTRL);
319 if (icv & VCR_IC_EAV) {
320 icv |= VCR_IC_EAV|VCR_IC_EVBI|VCR_IC_FFULL;
321 viacam_write_reg(cam, VCR_INTCTRL, icv);
322 ret = IRQ_WAKE_THREAD;
323 }
324 spin_unlock(&cam->viadev->reg_lock);
325 return ret;
326}
327
328/*
329 * Find the next videobuf buffer which has somebody waiting on it.
330 */
331static struct videobuf_buffer *viacam_next_buffer(struct via_camera *cam)
332{
333 unsigned long flags;
334 struct videobuf_buffer *buf = NULL;
335
336 spin_lock_irqsave(&cam->viadev->reg_lock, flags);
337 if (cam->opstate != S_RUNNING)
338 goto out;
339 if (list_empty(&cam->buffer_queue))
340 goto out;
341 buf = list_entry(cam->buffer_queue.next, struct videobuf_buffer, queue);
342 if (!waitqueue_active(&buf->done)) {/* Nobody waiting */
343 buf = NULL;
344 goto out;
345 }
346 list_del(&buf->queue);
347 buf->state = VIDEOBUF_ACTIVE;
348out:
349 spin_unlock_irqrestore(&cam->viadev->reg_lock, flags);
350 return buf;
351}
352
353/*
354 * The threaded IRQ handler.
355 */
356static irqreturn_t viacam_irq(int irq, void *data)
357{
358 int bufn;
359 struct videobuf_buffer *vb;
360 struct via_camera *cam = data;
361 struct videobuf_dmabuf *vdma;
362
363 /*
364 * If there is no place to put the data frame, don't bother
365 * with anything else.
366 */
367 vb = viacam_next_buffer(cam);
368 if (vb == NULL)
369 goto done;
370 /*
371 * Figure out which buffer we just completed.
372 */
373 bufn = (viacam_read_reg(cam, VCR_INTCTRL) & VCR_IC_ACTBUF) >> 3;
374 bufn -= 1;
375 if (bufn < 0)
376 bufn = cam->n_cap_bufs - 1;
377 /*
378 * Copy over the data and let any waiters know.
379 */
380 vdma = videobuf_to_dma(vb);
381 viafb_dma_copy_out_sg(cam->cb_offsets[bufn], vdma->sglist, vdma->sglen);
382 vb->state = VIDEOBUF_DONE;
383 vb->size = cam->user_format.sizeimage;
384 wake_up(&vb->done);
385done:
386 return IRQ_HANDLED;
387}
388
389
390/*
391 * These functions must mess around with the general interrupt
392 * control register, which is relevant to much more than just the
393 * camera. Nothing else uses interrupts, though, as of this writing.
394 * Should that situation change, we'll have to improve support at
395 * the via-core level.
396 */
397static void viacam_int_enable(struct via_camera *cam)
398{
399 viacam_write_reg(cam, VCR_INTCTRL,
400 VCR_IC_INTEN|VCR_IC_EAV|VCR_IC_EVBI|VCR_IC_FFULL);
401 viafb_irq_enable(VDE_I_C0AVEN);
402}
403
404static void viacam_int_disable(struct via_camera *cam)
405{
406 viafb_irq_disable(VDE_I_C0AVEN);
407 viacam_write_reg(cam, VCR_INTCTRL, 0);
408}
409
410
411
412/* --------------------------------------------------------------------------*/
413/* Controller operations */
414
415/*
416 * Set up our capture buffers in framebuffer memory.
417 */
418static int viacam_ctlr_cbufs(struct via_camera *cam)
419{
420 int nbuf = cam->viadev->camera_fbmem_size/cam->sensor_format.sizeimage;
421 int i;
422 unsigned int offset;
423
424 /*
425 * See how many buffers we can work with.
426 */
427 if (nbuf >= 3) {
428 cam->n_cap_bufs = 3;
429 viacam_write_reg_mask(cam, VCR_CAPINTC, VCR_CI_3BUFS,
430 VCR_CI_3BUFS);
431 } else if (nbuf == 2) {
432 cam->n_cap_bufs = 2;
433 viacam_write_reg_mask(cam, VCR_CAPINTC, 0, VCR_CI_3BUFS);
434 } else {
435 cam_warn(cam, "Insufficient frame buffer memory\n");
436 return -ENOMEM;
437 }
438 /*
439 * Set them up.
440 */
441 offset = cam->fb_offset;
442 for (i = 0; i < cam->n_cap_bufs; i++) {
443 cam->cb_offsets[i] = offset;
444 cam->cb_addrs[i] = cam->fbmem + offset;
445 viacam_write_reg(cam, VCR_VBUF1 + i*4, offset & VCR_VBUF_MASK);
446 offset += cam->sensor_format.sizeimage;
447 }
448 return 0;
449}
450
451/*
452 * Set the scaling register for downscaling the image.
453 *
454 * This register works like this... Vertical scaling is enabled
455 * by bit 26; if that bit is set, downscaling is controlled by the
456 * value in bits 16:25. Those bits are divided by 1024 to get
457 * the scaling factor; setting just bit 25 thus cuts the height
458 * in half.
459 *
460 * Horizontal scaling works about the same, but it's enabled by
461 * bit 11, with bits 0:10 giving the numerator of a fraction
462 * (over 2048) for the scaling value.
463 *
464 * This function is naive in that, if the user departs from
465 * the 3x4 VGA scaling factor, the image will distort. We
466 * could work around that if it really seemed important.
467 */
468static void viacam_set_scale(struct via_camera *cam)
469{
470 unsigned int avscale;
471 int sf;
472
473 if (cam->user_format.width == VGA_WIDTH)
474 avscale = 0;
475 else {
476 sf = (cam->user_format.width*2048)/VGA_WIDTH;
477 avscale = VCR_AVS_HEN | sf;
478 }
479 if (cam->user_format.height < VGA_HEIGHT) {
480 sf = (1024*cam->user_format.height)/VGA_HEIGHT;
481 avscale |= VCR_AVS_VEN | (sf << 16);
482 }
483 viacam_write_reg(cam, VCR_AVSCALE, avscale);
484}
485
486
487/*
488 * Configure image-related information into the capture engine.
489 */
490static void viacam_ctlr_image(struct via_camera *cam)
491{
492 int cicreg;
493
494 /*
495 * Disable clock before messing with stuff - from the via
496 * sample driver.
497 */
498 viacam_write_reg(cam, VCR_CAPINTC, ~(VCR_CI_ENABLE|VCR_CI_CLKEN));
499 /*
500 * Set up the controller for VGA resolution, modulo magic
501 * offsets from the via sample driver.
502 */
503 viacam_write_reg(cam, VCR_HORRANGE, 0x06200120);
504 viacam_write_reg(cam, VCR_VERTRANGE, 0x01de0000);
505 viacam_set_scale(cam);
506 /*
507 * Image size info.
508 */
509 viacam_write_reg(cam, VCR_MAXDATA,
510 (cam->sensor_format.height << 16) |
511 (cam->sensor_format.bytesperline >> 3));
512 viacam_write_reg(cam, VCR_MAXVBI, 0);
513 viacam_write_reg(cam, VCR_VSTRIDE,
514 cam->user_format.bytesperline & VCR_VS_STRIDE);
515 /*
516 * Set up the capture interface control register,
517 * everything but the "go" bit.
518 *
519 * The FIFO threshold is a bit of a magic number; 8 is what
520 * VIA's sample code uses.
521 */
522 cicreg = VCR_CI_CLKEN |
523 0x08000000 | /* FIFO threshold */
524 VCR_CI_FLDINV | /* OLPC-specific? */
525 VCR_CI_VREFINV | /* OLPC-specific? */
526 VCR_CI_DIBOTH | /* Capture both fields */
527 VCR_CI_CCIR601_8;
528 if (cam->n_cap_bufs == 3)
529 cicreg |= VCR_CI_3BUFS;
530 /*
531 * YUV formats need different byte swapping than RGB.
532 */
533 if (cam->user_format.pixelformat == V4L2_PIX_FMT_YUYV)
534 cicreg |= VCR_CI_YUYV;
535 else
536 cicreg |= VCR_CI_UYVY;
537 viacam_write_reg(cam, VCR_CAPINTC, cicreg);
538}
539
540
541static int viacam_config_controller(struct via_camera *cam)
542{
543 int ret;
544 unsigned long flags;
545
546 spin_lock_irqsave(&cam->viadev->reg_lock, flags);
547 ret = viacam_ctlr_cbufs(cam);
548 if (!ret)
549 viacam_ctlr_image(cam);
550 spin_unlock_irqrestore(&cam->viadev->reg_lock, flags);
551 clear_bit(CF_CONFIG_NEEDED, &cam->flags);
552 return ret;
553}
554
555/*
556 * Make it start grabbing data.
557 */
558static void viacam_start_engine(struct via_camera *cam)
559{
560 spin_lock_irq(&cam->viadev->reg_lock);
561 cam->next_buf = 0;
562 viacam_write_reg_mask(cam, VCR_CAPINTC, VCR_CI_ENABLE, VCR_CI_ENABLE);
563 viacam_int_enable(cam);
564 (void) viacam_read_reg(cam, VCR_CAPINTC); /* Force post */
565 cam->opstate = S_RUNNING;
566 spin_unlock_irq(&cam->viadev->reg_lock);
567}
568
569
570static void viacam_stop_engine(struct via_camera *cam)
571{
572 spin_lock_irq(&cam->viadev->reg_lock);
573 viacam_int_disable(cam);
574 viacam_write_reg_mask(cam, VCR_CAPINTC, 0, VCR_CI_ENABLE);
575 (void) viacam_read_reg(cam, VCR_CAPINTC); /* Force post */
576 cam->opstate = S_IDLE;
577 spin_unlock_irq(&cam->viadev->reg_lock);
578}
579
580
581/* --------------------------------------------------------------------------*/
582/* Videobuf callback ops */
583
584/*
585 * buffer_setup. The purpose of this one would appear to be to tell
586 * videobuf how big a single image is. It's also evidently up to us
587 * to put some sort of limit on the maximum number of buffers allowed.
588 */
589static int viacam_vb_buf_setup(struct videobuf_queue *q,
590 unsigned int *count, unsigned int *size)
591{
592 struct via_camera *cam = q->priv_data;
593
594 *size = cam->user_format.sizeimage;
595 if (*count == 0 || *count > 6) /* Arbitrary number */
596 *count = 6;
597 return 0;
598}
599
600/*
601 * Prepare a buffer.
602 */
603static int viacam_vb_buf_prepare(struct videobuf_queue *q,
604 struct videobuf_buffer *vb, enum v4l2_field field)
605{
606 struct via_camera *cam = q->priv_data;
607
608 vb->size = cam->user_format.sizeimage;
609 vb->width = cam->user_format.width; /* bytesperline???? */
610 vb->height = cam->user_format.height;
611 vb->field = field;
612 if (vb->state == VIDEOBUF_NEEDS_INIT) {
613 int ret = videobuf_iolock(q, vb, NULL);
614 if (ret)
615 return ret;
616 }
617 vb->state = VIDEOBUF_PREPARED;
618 return 0;
619}
620
621/*
622 * We've got a buffer to put data into.
623 *
624 * FIXME: check for a running engine and valid buffers?
625 */
626static void viacam_vb_buf_queue(struct videobuf_queue *q,
627 struct videobuf_buffer *vb)
628{
629 struct via_camera *cam = q->priv_data;
630
631 /*
632 * Note that videobuf holds the lock when it calls
633 * us, so we need not (indeed, cannot) take it here.
634 */
635 vb->state = VIDEOBUF_QUEUED;
636 list_add_tail(&vb->queue, &cam->buffer_queue);
637}
638
639/*
640 * Free a buffer.
641 */
642static void viacam_vb_buf_release(struct videobuf_queue *q,
643 struct videobuf_buffer *vb)
644{
645 struct via_camera *cam = q->priv_data;
646
647 videobuf_dma_unmap(&cam->platdev->dev, videobuf_to_dma(vb));
648 videobuf_dma_free(videobuf_to_dma(vb));
649 vb->state = VIDEOBUF_NEEDS_INIT;
650}
651
652static const struct videobuf_queue_ops viacam_vb_ops = {
653 .buf_setup = viacam_vb_buf_setup,
654 .buf_prepare = viacam_vb_buf_prepare,
655 .buf_queue = viacam_vb_buf_queue,
656 .buf_release = viacam_vb_buf_release,
657};
658
659/* --------------------------------------------------------------------------*/
660/* File operations */
661
662static int viacam_open(struct file *filp)
663{
664 struct via_camera *cam = video_drvdata(filp);
665
666 filp->private_data = cam;
667 /*
668 * Note the new user. If this is the first one, we'll also
669 * need to power up the sensor.
670 */
671 mutex_lock(&cam->lock);
672 if (cam->users == 0) {
673 int ret = viafb_request_dma();
674
675 if (ret) {
676 mutex_unlock(&cam->lock);
677 return ret;
678 }
679 via_sensor_power_up(cam);
680 set_bit(CF_CONFIG_NEEDED, &cam->flags);
681 /*
682 * Hook into videobuf. Evidently this cannot fail.
683 */
684 videobuf_queue_sg_init(&cam->vb_queue, &viacam_vb_ops,
685 &cam->platdev->dev, &cam->viadev->reg_lock,
686 V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE,
687 sizeof(struct videobuf_buffer), cam, NULL);
688 }
689 (cam->users)++;
690 mutex_unlock(&cam->lock);
691 return 0;
692}
693
694static int viacam_release(struct file *filp)
695{
696 struct via_camera *cam = video_drvdata(filp);
697
698 mutex_lock(&cam->lock);
699 (cam->users)--;
700 /*
701 * If the "owner" is closing, shut down any ongoing
702 * operations.
703 */
704 if (filp == cam->owner) {
705 videobuf_stop(&cam->vb_queue);
706 /*
707 * We don't hold the spinlock here, but, if release()
708 * is being called by the owner, nobody else will
709 * be changing the state. And an extra stop would
710 * not hurt anyway.
711 */
712 if (cam->opstate != S_IDLE)
713 viacam_stop_engine(cam);
714 cam->owner = NULL;
715 }
716 /*
717 * Last one out needs to turn out the lights.
718 */
719 if (cam->users == 0) {
720 videobuf_mmap_free(&cam->vb_queue);
721 via_sensor_power_down(cam);
722 viafb_release_dma();
723 }
724 mutex_unlock(&cam->lock);
725 return 0;
726}
727
728/*
729 * Read a frame from the device.
730 */
731static ssize_t viacam_read(struct file *filp, char __user *buffer,
732 size_t len, loff_t *pos)
733{
734 struct via_camera *cam = video_drvdata(filp);
735 int ret;
736
737 mutex_lock(&cam->lock);
738 /*
739 * Enforce the V4l2 "only one owner gets to read data" rule.
740 */
741 if (cam->owner && cam->owner != filp) {
742 ret = -EBUSY;
743 goto out_unlock;
744 }
745 cam->owner = filp;
746 /*
747 * Do we need to configure the hardware?
748 */
749 if (test_bit(CF_CONFIG_NEEDED, &cam->flags)) {
750 ret = viacam_configure_sensor(cam);
751 if (!ret)
752 ret = viacam_config_controller(cam);
753 if (ret)
754 goto out_unlock;
755 }
756 /*
757 * Fire up the capture engine, then have videobuf do
758 * the heavy lifting. Someday it would be good to avoid
759 * stopping and restarting the engine each time.
760 */
761 INIT_LIST_HEAD(&cam->buffer_queue);
762 viacam_start_engine(cam);
763 ret = videobuf_read_stream(&cam->vb_queue, buffer, len, pos, 0,
764 filp->f_flags & O_NONBLOCK);
765 viacam_stop_engine(cam);
766 /* videobuf_stop() ?? */
767
768out_unlock:
769 mutex_unlock(&cam->lock);
770 return ret;
771}
772
773
774static unsigned int viacam_poll(struct file *filp, struct poll_table_struct *pt)
775{
776 struct via_camera *cam = video_drvdata(filp);
777
778 return videobuf_poll_stream(filp, &cam->vb_queue, pt);
779}
780
781
782static int viacam_mmap(struct file *filp, struct vm_area_struct *vma)
783{
784 struct via_camera *cam = video_drvdata(filp);
785
786 return videobuf_mmap_mapper(&cam->vb_queue, vma);
787}
788
789
790
791static const struct v4l2_file_operations viacam_fops = {
792 .owner = THIS_MODULE,
793 .open = viacam_open,
794 .release = viacam_release,
795 .read = viacam_read,
796 .poll = viacam_poll,
797 .mmap = viacam_mmap,
798 .unlocked_ioctl = video_ioctl2,
799};
800
801/*----------------------------------------------------------------------------*/
802/*
803 * The long list of v4l2 ioctl ops
804 */
805
806static int viacam_g_chip_ident(struct file *file, void *priv,
807 struct v4l2_dbg_chip_ident *ident)
808{
809 struct via_camera *cam = priv;
810
811 ident->ident = V4L2_IDENT_NONE;
812 ident->revision = 0;
813 if (v4l2_chip_match_host(&ident->match)) {
814 ident->ident = V4L2_IDENT_VIA_VX855;
815 return 0;
816 }
817 return sensor_call(cam, core, g_chip_ident, ident);
818}
819
820/*
821 * Control ops are passed through to the sensor.
822 */
823static int viacam_queryctrl(struct file *filp, void *priv,
824 struct v4l2_queryctrl *qc)
825{
826 struct via_camera *cam = priv;
827 int ret;
828
829 mutex_lock(&cam->lock);
830 ret = sensor_call(cam, core, queryctrl, qc);
831 mutex_unlock(&cam->lock);
832 return ret;
833}
834
835
836static int viacam_g_ctrl(struct file *filp, void *priv,
837 struct v4l2_control *ctrl)
838{
839 struct via_camera *cam = priv;
840 int ret;
841
842 mutex_lock(&cam->lock);
843 ret = sensor_call(cam, core, g_ctrl, ctrl);
844 mutex_unlock(&cam->lock);
845 return ret;
846}
847
848
849static int viacam_s_ctrl(struct file *filp, void *priv,
850 struct v4l2_control *ctrl)
851{
852 struct via_camera *cam = priv;
853 int ret;
854
855 mutex_lock(&cam->lock);
856 ret = sensor_call(cam, core, s_ctrl, ctrl);
857 mutex_unlock(&cam->lock);
858 return ret;
859}
860
861/*
862 * Only one input.
863 */
864static int viacam_enum_input(struct file *filp, void *priv,
865 struct v4l2_input *input)
866{
867 if (input->index != 0)
868 return -EINVAL;
869
870 input->type = V4L2_INPUT_TYPE_CAMERA;
871 input->std = V4L2_STD_ALL; /* Not sure what should go here */
872 strcpy(input->name, "Camera");
873 return 0;
874}
875
876static int viacam_g_input(struct file *filp, void *priv, unsigned int *i)
877{
878 *i = 0;
879 return 0;
880}
881
882static int viacam_s_input(struct file *filp, void *priv, unsigned int i)
883{
884 if (i != 0)
885 return -EINVAL;
886 return 0;
887}
888
889static int viacam_s_std(struct file *filp, void *priv, v4l2_std_id *std)
890{
891 return 0;
892}
893
894/*
895 * Video format stuff. Here is our default format until
896 * user space messes with things.
897 */
898static const struct v4l2_pix_format viacam_def_pix_format = {
899 .width = VGA_WIDTH,
900 .height = VGA_HEIGHT,
901 .pixelformat = V4L2_PIX_FMT_YUYV,
902 .field = V4L2_FIELD_NONE,
903 .bytesperline = VGA_WIDTH * 2,
904 .sizeimage = VGA_WIDTH * VGA_HEIGHT * 2,
905};
906
907static const enum v4l2_mbus_pixelcode via_def_mbus_code = V4L2_MBUS_FMT_YUYV8_2X8;
908
909static int viacam_enum_fmt_vid_cap(struct file *filp, void *priv,
910 struct v4l2_fmtdesc *fmt)
911{
912 if (fmt->index >= N_VIA_FMTS)
913 return -EINVAL;
914 strlcpy(fmt->description, via_formats[fmt->index].desc,
915 sizeof(fmt->description));
916 fmt->pixelformat = via_formats[fmt->index].pixelformat;
917 return 0;
918}
919
920/*
921 * Figure out proper image dimensions, but always force the
922 * sensor to VGA.
923 */
924static void viacam_fmt_pre(struct v4l2_pix_format *userfmt,
925 struct v4l2_pix_format *sensorfmt)
926{
927 *sensorfmt = *userfmt;
928 if (userfmt->width < QCIF_WIDTH || userfmt->height < QCIF_HEIGHT) {
929 userfmt->width = QCIF_WIDTH;
930 userfmt->height = QCIF_HEIGHT;
931 }
932 if (userfmt->width > VGA_WIDTH || userfmt->height > VGA_HEIGHT) {
933 userfmt->width = VGA_WIDTH;
934 userfmt->height = VGA_HEIGHT;
935 }
936 sensorfmt->width = VGA_WIDTH;
937 sensorfmt->height = VGA_HEIGHT;
938}
939
940static void viacam_fmt_post(struct v4l2_pix_format *userfmt,
941 struct v4l2_pix_format *sensorfmt)
942{
943 struct via_format *f = via_find_format(userfmt->pixelformat);
944
945 sensorfmt->bytesperline = sensorfmt->width * f->bpp;
946 sensorfmt->sizeimage = sensorfmt->height * sensorfmt->bytesperline;
947 userfmt->pixelformat = sensorfmt->pixelformat;
948 userfmt->field = sensorfmt->field;
949 userfmt->bytesperline = 2 * userfmt->width;
950 userfmt->sizeimage = userfmt->bytesperline * userfmt->height;
951}
952
953
954/*
955 * The real work of figuring out a workable format.
956 */
957static int viacam_do_try_fmt(struct via_camera *cam,
958 struct v4l2_pix_format *upix, struct v4l2_pix_format *spix)
959{
960 int ret;
961 struct v4l2_mbus_framefmt mbus_fmt;
962 struct via_format *f = via_find_format(upix->pixelformat);
963
964 upix->pixelformat = f->pixelformat;
965 viacam_fmt_pre(upix, spix);
966 v4l2_fill_mbus_format(&mbus_fmt, spix, f->mbus_code);
967 ret = sensor_call(cam, video, try_mbus_fmt, &mbus_fmt);
968 v4l2_fill_pix_format(spix, &mbus_fmt);
969 viacam_fmt_post(upix, spix);
970 return ret;
971}
972
973
974
975static int viacam_try_fmt_vid_cap(struct file *filp, void *priv,
976 struct v4l2_format *fmt)
977{
978 struct via_camera *cam = priv;
979 struct v4l2_format sfmt;
980 int ret;
981
982 mutex_lock(&cam->lock);
983 ret = viacam_do_try_fmt(cam, &fmt->fmt.pix, &sfmt.fmt.pix);
984 mutex_unlock(&cam->lock);
985 return ret;
986}
987
988
989static int viacam_g_fmt_vid_cap(struct file *filp, void *priv,
990 struct v4l2_format *fmt)
991{
992 struct via_camera *cam = priv;
993
994 mutex_lock(&cam->lock);
995 fmt->fmt.pix = cam->user_format;
996 mutex_unlock(&cam->lock);
997 return 0;
998}
999
1000static int viacam_s_fmt_vid_cap(struct file *filp, void *priv,
1001 struct v4l2_format *fmt)
1002{
1003 struct via_camera *cam = priv;
1004 int ret;
1005 struct v4l2_format sfmt;
1006 struct via_format *f = via_find_format(fmt->fmt.pix.pixelformat);
1007
1008 /*
1009 * Camera must be idle or we can't mess with the
1010 * video setup.
1011 */
1012 mutex_lock(&cam->lock);
1013 if (cam->opstate != S_IDLE) {
1014 ret = -EBUSY;
1015 goto out;
1016 }
1017 /*
1018 * Let the sensor code look over and tweak the
1019 * requested formatting.
1020 */
1021 ret = viacam_do_try_fmt(cam, &fmt->fmt.pix, &sfmt.fmt.pix);
1022 if (ret)
1023 goto out;
1024 /*
1025 * OK, let's commit to the new format.
1026 */
1027 cam->user_format = fmt->fmt.pix;
1028 cam->sensor_format = sfmt.fmt.pix;
1029 cam->mbus_code = f->mbus_code;
1030 ret = viacam_configure_sensor(cam);
1031 if (!ret)
1032 ret = viacam_config_controller(cam);
1033out:
1034 mutex_unlock(&cam->lock);
1035 return ret;
1036}
1037
1038static int viacam_querycap(struct file *filp, void *priv,
1039 struct v4l2_capability *cap)
1040{
1041 strcpy(cap->driver, "via-camera");
1042 strcpy(cap->card, "via-camera");
1043 cap->version = 1;
1044 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
1045 V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
1046 return 0;
1047}
1048
1049/*
1050 * Streaming operations - pure videobuf stuff.
1051 */
1052static int viacam_reqbufs(struct file *filp, void *priv,
1053 struct v4l2_requestbuffers *rb)
1054{
1055 struct via_camera *cam = priv;
1056
1057 return videobuf_reqbufs(&cam->vb_queue, rb);
1058}
1059
1060static int viacam_querybuf(struct file *filp, void *priv,
1061 struct v4l2_buffer *buf)
1062{
1063 struct via_camera *cam = priv;
1064
1065 return videobuf_querybuf(&cam->vb_queue, buf);
1066}
1067
1068static int viacam_qbuf(struct file *filp, void *priv, struct v4l2_buffer *buf)
1069{
1070 struct via_camera *cam = priv;
1071
1072 return videobuf_qbuf(&cam->vb_queue, buf);
1073}
1074
1075static int viacam_dqbuf(struct file *filp, void *priv, struct v4l2_buffer *buf)
1076{
1077 struct via_camera *cam = priv;
1078
1079 return videobuf_dqbuf(&cam->vb_queue, buf, filp->f_flags & O_NONBLOCK);
1080}
1081
1082static int viacam_streamon(struct file *filp, void *priv, enum v4l2_buf_type t)
1083{
1084 struct via_camera *cam = priv;
1085 int ret = 0;
1086
1087 if (t != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1088 return -EINVAL;
1089
1090 mutex_lock(&cam->lock);
1091 if (cam->opstate != S_IDLE) {
1092 ret = -EBUSY;
1093 goto out;
1094 }
1095 /*
1096 * Enforce the V4l2 "only one owner gets to read data" rule.
1097 */
1098 if (cam->owner && cam->owner != filp) {
1099 ret = -EBUSY;
1100 goto out;
1101 }
1102 cam->owner = filp;
1103 /*
1104 * Configure things if need be.
1105 */
1106 if (test_bit(CF_CONFIG_NEEDED, &cam->flags)) {
1107 ret = viacam_configure_sensor(cam);
1108 if (ret)
1109 goto out;
1110 ret = viacam_config_controller(cam);
1111 if (ret)
1112 goto out;
1113 }
1114 /*
1115 * If the CPU goes into C3, the DMA transfer gets corrupted and
1116 * users start filing unsightly bug reports. Put in a "latency"
1117 * requirement which will keep the CPU out of the deeper sleep
1118 * states.
1119 */
1120 pm_qos_add_request(&cam->qos_request, PM_QOS_CPU_DMA_LATENCY, 50);
1121 /*
1122 * Fire things up.
1123 */
1124 INIT_LIST_HEAD(&cam->buffer_queue);
1125 ret = videobuf_streamon(&cam->vb_queue);
1126 if (!ret)
1127 viacam_start_engine(cam);
1128out:
1129 mutex_unlock(&cam->lock);
1130 return ret;
1131}
1132
1133static int viacam_streamoff(struct file *filp, void *priv, enum v4l2_buf_type t)
1134{
1135 struct via_camera *cam = priv;
1136 int ret;
1137
1138 if (t != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1139 return -EINVAL;
1140 mutex_lock(&cam->lock);
1141 if (cam->opstate != S_RUNNING) {
1142 ret = -EINVAL;
1143 goto out;
1144 }
1145 pm_qos_remove_request(&cam->qos_request);
1146 viacam_stop_engine(cam);
1147 /*
1148 * Videobuf will recycle all of the outstanding buffers, but
1149 * we should be sure we don't retain any references to
1150 * any of them.
1151 */
1152 ret = videobuf_streamoff(&cam->vb_queue);
1153 INIT_LIST_HEAD(&cam->buffer_queue);
1154out:
1155 mutex_unlock(&cam->lock);
1156 return ret;
1157}
1158
1159/* G/S_PARM */
1160
1161static int viacam_g_parm(struct file *filp, void *priv,
1162 struct v4l2_streamparm *parm)
1163{
1164 struct via_camera *cam = priv;
1165 int ret;
1166
1167 mutex_lock(&cam->lock);
1168 ret = sensor_call(cam, video, g_parm, parm);
1169 mutex_unlock(&cam->lock);
1170 parm->parm.capture.readbuffers = cam->n_cap_bufs;
1171 return ret;
1172}
1173
1174static int viacam_s_parm(struct file *filp, void *priv,
1175 struct v4l2_streamparm *parm)
1176{
1177 struct via_camera *cam = priv;
1178 int ret;
1179
1180 mutex_lock(&cam->lock);
1181 ret = sensor_call(cam, video, s_parm, parm);
1182 mutex_unlock(&cam->lock);
1183 parm->parm.capture.readbuffers = cam->n_cap_bufs;
1184 return ret;
1185}
1186
1187static int viacam_enum_framesizes(struct file *filp, void *priv,
1188 struct v4l2_frmsizeenum *sizes)
1189{
1190 if (sizes->index != 0)
1191 return -EINVAL;
1192 sizes->type = V4L2_FRMSIZE_TYPE_CONTINUOUS;
1193 sizes->stepwise.min_width = QCIF_WIDTH;
1194 sizes->stepwise.min_height = QCIF_HEIGHT;
1195 sizes->stepwise.max_width = VGA_WIDTH;
1196 sizes->stepwise.max_height = VGA_HEIGHT;
1197 sizes->stepwise.step_width = sizes->stepwise.step_height = 1;
1198 return 0;
1199}
1200
1201static int viacam_enum_frameintervals(struct file *filp, void *priv,
1202 struct v4l2_frmivalenum *interval)
1203{
1204 struct via_camera *cam = priv;
1205 int ret;
1206
1207 mutex_lock(&cam->lock);
1208 ret = sensor_call(cam, video, enum_frameintervals, interval);
1209 mutex_unlock(&cam->lock);
1210 return ret;
1211}
1212
1213
1214
1215static const struct v4l2_ioctl_ops viacam_ioctl_ops = {
1216 .vidioc_g_chip_ident = viacam_g_chip_ident,
1217 .vidioc_queryctrl = viacam_queryctrl,
1218 .vidioc_g_ctrl = viacam_g_ctrl,
1219 .vidioc_s_ctrl = viacam_s_ctrl,
1220 .vidioc_enum_input = viacam_enum_input,
1221 .vidioc_g_input = viacam_g_input,
1222 .vidioc_s_input = viacam_s_input,
1223 .vidioc_s_std = viacam_s_std,
1224 .vidioc_enum_fmt_vid_cap = viacam_enum_fmt_vid_cap,
1225 .vidioc_try_fmt_vid_cap = viacam_try_fmt_vid_cap,
1226 .vidioc_g_fmt_vid_cap = viacam_g_fmt_vid_cap,
1227 .vidioc_s_fmt_vid_cap = viacam_s_fmt_vid_cap,
1228 .vidioc_querycap = viacam_querycap,
1229 .vidioc_reqbufs = viacam_reqbufs,
1230 .vidioc_querybuf = viacam_querybuf,
1231 .vidioc_qbuf = viacam_qbuf,
1232 .vidioc_dqbuf = viacam_dqbuf,
1233 .vidioc_streamon = viacam_streamon,
1234 .vidioc_streamoff = viacam_streamoff,
1235 .vidioc_g_parm = viacam_g_parm,
1236 .vidioc_s_parm = viacam_s_parm,
1237 .vidioc_enum_framesizes = viacam_enum_framesizes,
1238 .vidioc_enum_frameintervals = viacam_enum_frameintervals,
1239};
1240
1241/*----------------------------------------------------------------------------*/
1242
1243/*
1244 * Power management.
1245 */
1246#ifdef CONFIG_PM
1247
1248static int viacam_suspend(void *priv)
1249{
1250 struct via_camera *cam = priv;
1251 enum viacam_opstate state = cam->opstate;
1252
1253 if (cam->opstate != S_IDLE) {
1254 viacam_stop_engine(cam);
1255 cam->opstate = state; /* So resume restarts */
1256 }
1257
1258 return 0;
1259}
1260
1261static int viacam_resume(void *priv)
1262{
1263 struct via_camera *cam = priv;
1264 int ret = 0;
1265
1266 /*
1267 * Get back to a reasonable operating state.
1268 */
1269 via_write_reg_mask(VIASR, 0x78, 0, 0x80);
1270 via_write_reg_mask(VIASR, 0x1e, 0xc0, 0xc0);
1271 viacam_int_disable(cam);
1272 set_bit(CF_CONFIG_NEEDED, &cam->flags);
1273 /*
1274 * Make sure the sensor's power state is correct
1275 */
1276 if (cam->users > 0)
1277 via_sensor_power_up(cam);
1278 else
1279 via_sensor_power_down(cam);
1280 /*
1281 * If it was operating, try to restart it.
1282 */
1283 if (cam->opstate != S_IDLE) {
1284 mutex_lock(&cam->lock);
1285 ret = viacam_configure_sensor(cam);
1286 if (!ret)
1287 ret = viacam_config_controller(cam);
1288 mutex_unlock(&cam->lock);
1289 if (!ret)
1290 viacam_start_engine(cam);
1291 }
1292
1293 return ret;
1294}
1295
1296static struct viafb_pm_hooks viacam_pm_hooks = {
1297 .suspend = viacam_suspend,
1298 .resume = viacam_resume
1299};
1300
1301#endif /* CONFIG_PM */
1302
1303/*
1304 * Setup stuff.
1305 */
1306
1307static struct video_device viacam_v4l_template = {
1308 .name = "via-camera",
1309 .minor = -1,
1310 .tvnorms = V4L2_STD_NTSC_M,
1311 .current_norm = V4L2_STD_NTSC_M,
1312 .fops = &viacam_fops,
1313 .ioctl_ops = &viacam_ioctl_ops,
1314 .release = video_device_release_empty, /* Check this */
1315};
1316
1317/*
1318 * The OLPC folks put the serial port on the same pin as
1319 * the camera. They also get grumpy if we break the
1320 * serial port and keep them from using it. So we have
1321 * to check the serial enable bit and not step on it.
1322 */
1323#define VIACAM_SERIAL_DEVFN 0x88
1324#define VIACAM_SERIAL_CREG 0x46
1325#define VIACAM_SERIAL_BIT 0x40
1326
1327static __devinit bool viacam_serial_is_enabled(void)
1328{
1329 struct pci_bus *pbus = pci_find_bus(0, 0);
1330 u8 cbyte;
1331
1332 if (!pbus)
1333 return false;
1334 pci_bus_read_config_byte(pbus, VIACAM_SERIAL_DEVFN,
1335 VIACAM_SERIAL_CREG, &cbyte);
1336 if ((cbyte & VIACAM_SERIAL_BIT) == 0)
1337 return false; /* Not enabled */
1338 if (override_serial == 0) {
1339 printk(KERN_NOTICE "Via camera: serial port is enabled, " \
1340 "refusing to load.\n");
1341 printk(KERN_NOTICE "Specify override_serial=1 to force " \
1342 "module loading.\n");
1343 return true;
1344 }
1345 printk(KERN_NOTICE "Via camera: overriding serial port\n");
1346 pci_bus_write_config_byte(pbus, VIACAM_SERIAL_DEVFN,
1347 VIACAM_SERIAL_CREG, cbyte & ~VIACAM_SERIAL_BIT);
1348 return false;
1349}
1350
1351static struct ov7670_config sensor_cfg = {
1352 /* The XO-1.5 (only known user) clocks the camera at 90MHz. */
1353 .clock_speed = 90,
1354};
1355
1356static __devinit int viacam_probe(struct platform_device *pdev)
1357{
1358 int ret;
1359 struct i2c_adapter *sensor_adapter;
1360 struct viafb_dev *viadev = pdev->dev.platform_data;
1361 struct i2c_board_info ov7670_info = {
1362 .type = "ov7670",
1363 .addr = 0x42 >> 1,
1364 .platform_data = &sensor_cfg,
1365 };
1366
1367 /*
1368 * Note that there are actually two capture channels on
1369 * the device. We only deal with one for now. That
1370 * is encoded here; nothing else assumes it's dealing with
1371 * a unique capture device.
1372 */
1373 struct via_camera *cam;
1374
1375 /*
1376 * Ensure that frame buffer memory has been set aside for
1377 * this purpose. As an arbitrary limit, refuse to work
1378 * with less than two frames of VGA 16-bit data.
1379 *
1380 * If we ever support the second port, we'll need to set
1381 * aside more memory.
1382 */
1383 if (viadev->camera_fbmem_size < (VGA_HEIGHT*VGA_WIDTH*4)) {
1384 printk(KERN_ERR "viacam: insufficient FB memory reserved\n");
1385 return -ENOMEM;
1386 }
1387 if (viadev->engine_mmio == NULL) {
1388 printk(KERN_ERR "viacam: No I/O memory, so no pictures\n");
1389 return -ENOMEM;
1390 }
1391
1392 if (machine_is_olpc() && viacam_serial_is_enabled())
1393 return -EBUSY;
1394
1395 /*
1396 * Basic structure initialization.
1397 */
1398 cam = kzalloc (sizeof(struct via_camera), GFP_KERNEL);
1399 if (cam == NULL)
1400 return -ENOMEM;
1401 via_cam_info = cam;
1402 cam->platdev = pdev;
1403 cam->viadev = viadev;
1404 cam->users = 0;
1405 cam->owner = NULL;
1406 cam->opstate = S_IDLE;
1407 cam->user_format = cam->sensor_format = viacam_def_pix_format;
1408 mutex_init(&cam->lock);
1409 INIT_LIST_HEAD(&cam->buffer_queue);
1410 cam->mmio = viadev->engine_mmio;
1411 cam->fbmem = viadev->fbmem;
1412 cam->fb_offset = viadev->camera_fbmem_offset;
1413 cam->flags = 1 << CF_CONFIG_NEEDED;
1414 cam->mbus_code = via_def_mbus_code;
1415 /*
1416 * Tell V4L that we exist.
1417 */
1418 ret = v4l2_device_register(&pdev->dev, &cam->v4l2_dev);
1419 if (ret) {
1420 dev_err(&pdev->dev, "Unable to register v4l2 device\n");
1421 return ret;
1422 }
1423 /*
1424 * Convince the system that we can do DMA.
1425 */
1426 pdev->dev.dma_mask = &viadev->pdev->dma_mask;
1427 dma_set_mask(&pdev->dev, 0xffffffff);
1428 /*
1429 * Fire up the capture port. The write to 0x78 looks purely
1430 * OLPCish; any system will need to tweak 0x1e.
1431 */
1432 via_write_reg_mask(VIASR, 0x78, 0, 0x80);
1433 via_write_reg_mask(VIASR, 0x1e, 0xc0, 0xc0);
1434 /*
1435 * Get the sensor powered up.
1436 */
1437 ret = via_sensor_power_setup(cam);
1438 if (ret)
1439 goto out_unregister;
1440 via_sensor_power_up(cam);
1441
1442 /*
1443 * See if we can't find it on the bus. The VIA_PORT_31 assumption
1444 * is OLPC-specific. 0x42 assumption is ov7670-specific.
1445 */
1446 sensor_adapter = viafb_find_i2c_adapter(VIA_PORT_31);
1447 cam->sensor = v4l2_i2c_new_subdev_board(&cam->v4l2_dev, sensor_adapter,
1448 &ov7670_info, NULL);
1449 if (cam->sensor == NULL) {
1450 dev_err(&pdev->dev, "Unable to find the sensor!\n");
1451 ret = -ENODEV;
1452 goto out_power_down;
1453 }
1454 /*
1455 * Get the IRQ.
1456 */
1457 viacam_int_disable(cam);
1458 ret = request_threaded_irq(viadev->pdev->irq, viacam_quick_irq,
1459 viacam_irq, IRQF_SHARED, "via-camera", cam);
1460 if (ret)
1461 goto out_power_down;
1462 /*
1463 * Tell V4l2 that we exist.
1464 */
1465 cam->vdev = viacam_v4l_template;
1466 cam->vdev.v4l2_dev = &cam->v4l2_dev;
1467 ret = video_register_device(&cam->vdev, VFL_TYPE_GRABBER, -1);
1468 if (ret)
1469 goto out_irq;
1470 video_set_drvdata(&cam->vdev, cam);
1471
1472#ifdef CONFIG_PM
1473 /*
1474 * Hook into PM events
1475 */
1476 viacam_pm_hooks.private = cam;
1477 viafb_pm_register(&viacam_pm_hooks);
1478#endif
1479
1480 /* Power the sensor down until somebody opens the device */
1481 via_sensor_power_down(cam);
1482 return 0;
1483
1484out_irq:
1485 free_irq(viadev->pdev->irq, cam);
1486out_power_down:
1487 via_sensor_power_release(cam);
1488out_unregister:
1489 v4l2_device_unregister(&cam->v4l2_dev);
1490 return ret;
1491}
1492
1493static __devexit int viacam_remove(struct platform_device *pdev)
1494{
1495 struct via_camera *cam = via_cam_info;
1496 struct viafb_dev *viadev = pdev->dev.platform_data;
1497
1498 video_unregister_device(&cam->vdev);
1499 v4l2_device_unregister(&cam->v4l2_dev);
1500 free_irq(viadev->pdev->irq, cam);
1501 via_sensor_power_release(cam);
1502 via_cam_info = NULL;
1503 return 0;
1504}
1505
1506static struct platform_driver viacam_driver = {
1507 .driver = {
1508 .name = "viafb-camera",
1509 },
1510 .probe = viacam_probe,
1511 .remove = viacam_remove,
1512};
1513
1514module_platform_driver(viacam_driver);
diff --git a/drivers/media/video/via-camera.h b/drivers/media/video/via-camera.h
deleted file mode 100644
index b12a4b3d616f..000000000000
--- a/drivers/media/video/via-camera.h
+++ /dev/null
@@ -1,93 +0,0 @@
1/*
2 * VIA Camera register definitions.
3 */
4#define VCR_INTCTRL 0x300 /* Capture interrupt control */
5#define VCR_IC_EAV 0x0001 /* End of active video status */
6#define VCR_IC_EVBI 0x0002 /* End of VBI status */
7#define VCR_IC_FBOTFLD 0x0004 /* "flipping" Bottom field is active */
8#define VCR_IC_ACTBUF 0x0018 /* Active video buffer */
9#define VCR_IC_VSYNC 0x0020 /* 0 = VB, 1 = active video */
10#define VCR_IC_BOTFLD 0x0040 /* Bottom field is active */
11#define VCR_IC_FFULL 0x0080 /* FIFO full */
12#define VCR_IC_INTEN 0x0100 /* End of active video int. enable */
13#define VCR_IC_VBIINT 0x0200 /* End of VBI int enable */
14#define VCR_IC_VBIBUF 0x0400 /* Current VBI buffer */
15
16#define VCR_TSC 0x308 /* Transport stream control */
17#define VCR_TSC_ENABLE 0x000001 /* Transport stream input enable */
18#define VCR_TSC_DROPERR 0x000002 /* Drop error packets */
19#define VCR_TSC_METHOD 0x00000c /* DMA method (non-functional) */
20#define VCR_TSC_COUNT 0x07fff0 /* KByte or packet count */
21#define VCR_TSC_CBMODE 0x080000 /* Change buffer by byte count */
22#define VCR_TSC_PSSIG 0x100000 /* Packet starting signal disable */
23#define VCR_TSC_BE 0x200000 /* MSB first (serial mode) */
24#define VCR_TSC_SERIAL 0x400000 /* Serial input (0 = parallel) */
25
26#define VCR_CAPINTC 0x310 /* Capture interface control */
27#define VCR_CI_ENABLE 0x00000001 /* Capture enable */
28#define VCR_CI_BSS 0x00000002 /* WTF "bit stream selection" */
29#define VCR_CI_3BUFS 0x00000004 /* 1 = 3 buffers, 0 = 2 buffers */
30#define VCR_CI_VIPEN 0x00000008 /* VIP enable */
31#define VCR_CI_CCIR601_8 0 /* CCIR601 input stream, 8 bit */
32#define VCR_CI_CCIR656_8 0x00000010 /* ... CCIR656, 8 bit */
33#define VCR_CI_CCIR601_16 0x00000020 /* ... CCIR601, 16 bit */
34#define VCR_CI_CCIR656_16 0x00000030 /* ... CCIR656, 16 bit */
35#define VCR_CI_HDMODE 0x00000040 /* CCIR656-16 hdr decode mode; 1=16b */
36#define VCR_CI_BSWAP 0x00000080 /* Swap bytes (16-bit) */
37#define VCR_CI_YUYV 0 /* Byte order 0123 */
38#define VCR_CI_UYVY 0x00000100 /* Byte order 1032 */
39#define VCR_CI_YVYU 0x00000200 /* Byte order 0321 */
40#define VCR_CI_VYUY 0x00000300 /* Byte order 3012 */
41#define VCR_CI_VIPTYPE 0x00000400 /* VIP type */
42#define VCR_CI_IFSEN 0x00000800 /* Input field signal enable */
43#define VCR_CI_DIODD 0 /* De-interlace odd, 30fps */
44#define VCR_CI_DIEVEN 0x00001000 /* ...even field, 30fps */
45#define VCR_CI_DIBOTH 0x00002000 /* ...both fields, 60fps */
46#define VCR_CI_DIBOTH30 0x00003000 /* ...both fields, 30fps interlace */
47#define VCR_CI_CONVTYPE 0x00004000 /* 4:2:2 to 4:4:4; 1 = interpolate */
48#define VCR_CI_CFC 0x00008000 /* Capture flipping control */
49#define VCR_CI_FILTER 0x00070000 /* Horiz filter mode select
50 000 = none
51 001 = 2 tap
52 010 = 3 tap
53 011 = 4 tap
54 100 = 5 tap */
55#define VCR_CI_CLKINV 0x00080000 /* Input CLK inverted */
56#define VCR_CI_VREFINV 0x00100000 /* VREF inverted */
57#define VCR_CI_HREFINV 0x00200000 /* HREF inverted */
58#define VCR_CI_FLDINV 0x00400000 /* Field inverted */
59#define VCR_CI_CLKPIN 0x00800000 /* Capture clock pin */
60#define VCR_CI_THRESH 0x0f000000 /* Capture fifo threshold */
61#define VCR_CI_HRLE 0x10000000 /* Positive edge of HREF */
62#define VCR_CI_VRLE 0x20000000 /* Positive edge of VREF */
63#define VCR_CI_OFLDINV 0x40000000 /* Field output inverted */
64#define VCR_CI_CLKEN 0x80000000 /* Capture clock enable */
65
66#define VCR_HORRANGE 0x314 /* Active video horizontal range */
67#define VCR_VERTRANGE 0x318 /* Active video vertical range */
68#define VCR_AVSCALE 0x31c /* Active video scaling control */
69#define VCR_AVS_HEN 0x00000800 /* Horizontal scale enable */
70#define VCR_AVS_VEN 0x04000000 /* Vertical enable */
71#define VCR_VBIHOR 0x320 /* VBI Data horizontal range */
72#define VCR_VBIVERT 0x324 /* VBI data vertical range */
73#define VCR_VBIBUF1 0x328 /* First VBI buffer */
74#define VCR_VBISTRIDE 0x32c /* VBI stride */
75#define VCR_ANCDATACNT 0x330 /* Ancillary data count setting */
76#define VCR_MAXDATA 0x334 /* Active data count of active video */
77#define VCR_MAXVBI 0x338 /* Maximum data count of VBI */
78#define VCR_CAPDATA 0x33c /* Capture data count */
79#define VCR_VBUF1 0x340 /* First video buffer */
80#define VCR_VBUF2 0x344 /* Second video buffer */
81#define VCR_VBUF3 0x348 /* Third video buffer */
82#define VCR_VBUF_MASK 0x1ffffff0 /* Bits 28:4 */
83#define VCR_VBIBUF2 0x34c /* Second VBI buffer */
84#define VCR_VSTRIDE 0x350 /* Stride of video + coring control */
85#define VCR_VS_STRIDE_SHIFT 4
86#define VCR_VS_STRIDE 0x00001ff0 /* Stride (8-byte units) */
87#define VCR_VS_CCD 0x007f0000 /* Coring compare data */
88#define VCR_VS_COREEN 0x00800000 /* Coring enable */
89#define VCR_TS0ERR 0x354 /* TS buffer 0 error indicator */
90#define VCR_TS1ERR 0x358 /* TS buffer 0 error indicator */
91#define VCR_TS2ERR 0x35c /* TS buffer 0 error indicator */
92
93/* Add 0x1000 for the second capture engine registers */
diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c
deleted file mode 100644
index aae1720b2f2d..000000000000
--- a/drivers/media/video/vino.c
+++ /dev/null
@@ -1,4349 +0,0 @@
1/*
2 * Driver for the VINO (Video In No Out) system found in SGI Indys.
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License version 2 as published by the Free Software Foundation.
6 *
7 * Copyright (C) 2004,2005 Mikael Nousiainen <tmnousia@cc.hut.fi>
8 *
9 * Based on the previous version of the driver for 2.4 kernels by:
10 * Copyright (C) 2003 Ladislav Michl <ladis@linux-mips.org>
11 *
12 * v4l2_device/v4l2_subdev conversion by:
13 * Copyright (C) 2009 Hans Verkuil <hverkuil@xs4all.nl>
14 *
15 * Note: this conversion is untested! Please contact the linux-media
16 * mailinglist if you can test this, together with the test results.
17 */
18
19/*
20 * TODO:
21 * - remove "mark pages reserved-hacks" from memory allocation code
22 * and implement fault()
23 * - check decimation, calculating and reporting image size when
24 * using decimation
25 * - implement read(), user mode buffers and overlay (?)
26 */
27
28#include <linux/init.h>
29#include <linux/module.h>
30#include <linux/delay.h>
31#include <linux/dma-mapping.h>
32#include <linux/errno.h>
33#include <linux/fs.h>
34#include <linux/interrupt.h>
35#include <linux/kernel.h>
36#include <linux/slab.h>
37#include <linux/mm.h>
38#include <linux/time.h>
39#include <linux/kmod.h>
40
41#include <linux/i2c.h>
42
43#include <linux/videodev2.h>
44#include <media/v4l2-device.h>
45#include <media/v4l2-ioctl.h>
46#include <linux/mutex.h>
47
48#include <asm/paccess.h>
49#include <asm/io.h>
50#include <asm/sgi/ip22.h>
51#include <asm/sgi/mc.h>
52
53#include "vino.h"
54#include "saa7191.h"
55#include "indycam.h"
56
57/* Uncomment the following line to get lots and lots of (mostly useless)
58 * debug info.
59 * Note that the debug output also slows down the driver significantly */
60// #define VINO_DEBUG
61// #define VINO_DEBUG_INT
62
63#define VINO_MODULE_VERSION "0.0.7"
64
65MODULE_DESCRIPTION("SGI VINO Video4Linux2 driver");
66MODULE_VERSION(VINO_MODULE_VERSION);
67MODULE_AUTHOR("Mikael Nousiainen <tmnousia@cc.hut.fi>");
68MODULE_LICENSE("GPL");
69
70#ifdef VINO_DEBUG
71#define dprintk(x...) printk("VINO: " x);
72#else
73#define dprintk(x...)
74#endif
75
76#define VINO_NO_CHANNEL 0
77#define VINO_CHANNEL_A 1
78#define VINO_CHANNEL_B 2
79
80#define VINO_PAL_WIDTH 768
81#define VINO_PAL_HEIGHT 576
82#define VINO_NTSC_WIDTH 640
83#define VINO_NTSC_HEIGHT 480
84
85#define VINO_MIN_WIDTH 32
86#define VINO_MIN_HEIGHT 32
87
88#define VINO_CLIPPING_START_ODD_D1 1
89#define VINO_CLIPPING_START_ODD_PAL 15
90#define VINO_CLIPPING_START_ODD_NTSC 12
91
92#define VINO_CLIPPING_START_EVEN_D1 2
93#define VINO_CLIPPING_START_EVEN_PAL 15
94#define VINO_CLIPPING_START_EVEN_NTSC 12
95
96#define VINO_INPUT_CHANNEL_COUNT 3
97
98/* the number is the index for vino_inputs */
99#define VINO_INPUT_NONE -1
100#define VINO_INPUT_COMPOSITE 0
101#define VINO_INPUT_SVIDEO 1
102#define VINO_INPUT_D1 2
103
104#define VINO_PAGE_RATIO (PAGE_SIZE / VINO_PAGE_SIZE)
105
106#define VINO_FIFO_THRESHOLD_DEFAULT 16
107
108#define VINO_FRAMEBUFFER_SIZE ((VINO_PAL_WIDTH \
109 * VINO_PAL_HEIGHT * 4 \
110 + 3 * PAGE_SIZE) & ~(PAGE_SIZE - 1))
111
112#define VINO_FRAMEBUFFER_COUNT_MAX 8
113
114#define VINO_FRAMEBUFFER_UNUSED 0
115#define VINO_FRAMEBUFFER_IN_USE 1
116#define VINO_FRAMEBUFFER_READY 2
117
118#define VINO_QUEUE_ERROR -1
119#define VINO_QUEUE_MAGIC 0x20050125
120
121#define VINO_MEMORY_NONE 0
122#define VINO_MEMORY_MMAP 1
123#define VINO_MEMORY_USERPTR 2
124
125#define VINO_DUMMY_DESC_COUNT 4
126#define VINO_DESC_FETCH_DELAY 5 /* microseconds */
127
128#define VINO_MAX_FRAME_SKIP_COUNT 128
129
130/* the number is the index for vino_data_formats */
131#define VINO_DATA_FMT_NONE -1
132#define VINO_DATA_FMT_GREY 0
133#define VINO_DATA_FMT_RGB332 1
134#define VINO_DATA_FMT_RGB32 2
135#define VINO_DATA_FMT_YUV 3
136
137#define VINO_DATA_FMT_COUNT 4
138
139/* the number is the index for vino_data_norms */
140#define VINO_DATA_NORM_NONE -1
141#define VINO_DATA_NORM_NTSC 0
142#define VINO_DATA_NORM_PAL 1
143#define VINO_DATA_NORM_SECAM 2
144#define VINO_DATA_NORM_D1 3
145
146#define VINO_DATA_NORM_COUNT 4
147
148/* I2C controller flags */
149#define SGI_I2C_FORCE_IDLE (0 << 0)
150#define SGI_I2C_NOT_IDLE (1 << 0)
151#define SGI_I2C_WRITE (0 << 1)
152#define SGI_I2C_READ (1 << 1)
153#define SGI_I2C_RELEASE_BUS (0 << 2)
154#define SGI_I2C_HOLD_BUS (1 << 2)
155#define SGI_I2C_XFER_DONE (0 << 4)
156#define SGI_I2C_XFER_BUSY (1 << 4)
157#define SGI_I2C_ACK (0 << 5)
158#define SGI_I2C_NACK (1 << 5)
159#define SGI_I2C_BUS_OK (0 << 7)
160#define SGI_I2C_BUS_ERR (1 << 7)
161
162/* Internal data structure definitions */
163
164struct vino_input {
165 char *name;
166 v4l2_std_id std;
167};
168
169struct vino_clipping {
170 unsigned int left, right, top, bottom;
171};
172
173struct vino_data_format {
174 /* the description */
175 char *description;
176 /* bytes per pixel */
177 unsigned int bpp;
178 /* V4L2 fourcc code */
179 __u32 pixelformat;
180 /* V4L2 colorspace (duh!) */
181 enum v4l2_colorspace colorspace;
182};
183
184struct vino_data_norm {
185 char *description;
186 unsigned int width, height;
187 struct vino_clipping odd;
188 struct vino_clipping even;
189
190 v4l2_std_id std;
191 unsigned int fps_min, fps_max;
192 __u32 framelines;
193};
194
195struct vino_descriptor_table {
196 /* the number of PAGE_SIZE sized pages in the buffer */
197 unsigned int page_count;
198 /* virtual (kmalloc'd) pointers to the actual data
199 * (in PAGE_SIZE chunks, used with mmap streaming) */
200 unsigned long *virtual;
201
202 /* cpu address for the VINO descriptor table
203 * (contains DMA addresses, VINO_PAGE_SIZE chunks) */
204 unsigned long *dma_cpu;
205 /* dma address for the VINO descriptor table
206 * (contains DMA addresses, VINO_PAGE_SIZE chunks) */
207 dma_addr_t dma;
208};
209
210struct vino_framebuffer {
211 /* identifier nubmer */
212 unsigned int id;
213 /* the length of the whole buffer */
214 unsigned int size;
215 /* the length of actual data in buffer */
216 unsigned int data_size;
217 /* the data format */
218 unsigned int data_format;
219 /* the state of buffer data */
220 unsigned int state;
221 /* is the buffer mapped in user space? */
222 unsigned int map_count;
223 /* memory offset for mmap() */
224 unsigned int offset;
225 /* frame counter */
226 unsigned int frame_counter;
227 /* timestamp (written when image capture finishes) */
228 struct timeval timestamp;
229
230 struct vino_descriptor_table desc_table;
231
232 spinlock_t state_lock;
233};
234
235struct vino_framebuffer_fifo {
236 unsigned int length;
237
238 unsigned int used;
239 unsigned int head;
240 unsigned int tail;
241
242 unsigned int data[VINO_FRAMEBUFFER_COUNT_MAX];
243};
244
245struct vino_framebuffer_queue {
246 unsigned int magic;
247
248 /* VINO_MEMORY_NONE, VINO_MEMORY_MMAP or VINO_MEMORY_USERPTR */
249 unsigned int type;
250 unsigned int length;
251
252 /* data field of in and out contain index numbers for buffer */
253 struct vino_framebuffer_fifo in;
254 struct vino_framebuffer_fifo out;
255
256 struct vino_framebuffer *buffer[VINO_FRAMEBUFFER_COUNT_MAX];
257
258 spinlock_t queue_lock;
259 struct mutex queue_mutex;
260 wait_queue_head_t frame_wait_queue;
261};
262
263struct vino_interrupt_data {
264 struct timeval timestamp;
265 unsigned int frame_counter;
266 unsigned int skip_count;
267 unsigned int skip;
268};
269
270struct vino_channel_settings {
271 unsigned int channel;
272
273 int input;
274 unsigned int data_format;
275 unsigned int data_norm;
276 struct vino_clipping clipping;
277 unsigned int decimation;
278 unsigned int line_size;
279 unsigned int alpha;
280 unsigned int fps;
281 unsigned int framert_reg;
282
283 unsigned int fifo_threshold;
284
285 struct vino_framebuffer_queue fb_queue;
286
287 /* number of the current field */
288 unsigned int field;
289
290 /* read in progress */
291 int reading;
292 /* streaming is active */
293 int streaming;
294 /* the driver is currently processing the queue */
295 int capturing;
296
297 struct mutex mutex;
298 spinlock_t capture_lock;
299
300 unsigned int users;
301
302 struct vino_interrupt_data int_data;
303
304 /* V4L support */
305 struct video_device *vdev;
306};
307
308struct vino_settings {
309 struct v4l2_device v4l2_dev;
310 struct vino_channel_settings a;
311 struct vino_channel_settings b;
312
313 /* the channel which owns this client:
314 * VINO_NO_CHANNEL, VINO_CHANNEL_A or VINO_CHANNEL_B */
315 unsigned int decoder_owner;
316 struct v4l2_subdev *decoder;
317 unsigned int camera_owner;
318 struct v4l2_subdev *camera;
319
320 /* a lock for vino register access */
321 spinlock_t vino_lock;
322 /* a lock for channel input changes */
323 spinlock_t input_lock;
324
325 unsigned long dummy_page;
326 struct vino_descriptor_table dummy_desc_table;
327};
328
329/* Module parameters */
330
331/*
332 * Using vino_pixel_conversion the ABGR32-format pixels supplied
333 * by the VINO chip can be converted to more common formats
334 * like RGBA32 (or probably RGB24 in the future). This way we
335 * can give out data that can be specified correctly with
336 * the V4L2-definitions.
337 *
338 * The pixel format is specified as RGBA32 when no conversion
339 * is used.
340 *
341 * Note that this only affects the 32-bit bit depth.
342 *
343 * Use non-zero value to enable conversion.
344 */
345static int vino_pixel_conversion;
346
347module_param_named(pixelconv, vino_pixel_conversion, int, 0);
348
349MODULE_PARM_DESC(pixelconv,
350 "enable pixel conversion (non-zero value enables)");
351
352/* Internal data structures */
353
354static struct sgi_vino *vino;
355
356static struct vino_settings *vino_drvdata;
357
358#define camera_call(o, f, args...) \
359 v4l2_subdev_call(vino_drvdata->camera, o, f, ##args)
360#define decoder_call(o, f, args...) \
361 v4l2_subdev_call(vino_drvdata->decoder, o, f, ##args)
362
363static const char *vino_driver_name = "vino";
364static const char *vino_driver_description = "SGI VINO";
365static const char *vino_bus_name = "GIO64 bus";
366static const char *vino_vdev_name_a = "SGI VINO Channel A";
367static const char *vino_vdev_name_b = "SGI VINO Channel B";
368
369static void vino_capture_tasklet(unsigned long channel);
370
371DECLARE_TASKLET(vino_tasklet_a, vino_capture_tasklet, VINO_CHANNEL_A);
372DECLARE_TASKLET(vino_tasklet_b, vino_capture_tasklet, VINO_CHANNEL_B);
373
374static const struct vino_input vino_inputs[] = {
375 {
376 .name = "Composite",
377 .std = V4L2_STD_NTSC | V4L2_STD_PAL
378 | V4L2_STD_SECAM,
379 }, {
380 .name = "S-Video",
381 .std = V4L2_STD_NTSC | V4L2_STD_PAL
382 | V4L2_STD_SECAM,
383 }, {
384 .name = "D1/IndyCam",
385 .std = V4L2_STD_NTSC,
386 }
387};
388
389static const struct vino_data_format vino_data_formats[] = {
390 {
391 .description = "8-bit greyscale",
392 .bpp = 1,
393 .pixelformat = V4L2_PIX_FMT_GREY,
394 .colorspace = V4L2_COLORSPACE_SMPTE170M,
395 }, {
396 .description = "8-bit dithered RGB 3-3-2",
397 .bpp = 1,
398 .pixelformat = V4L2_PIX_FMT_RGB332,
399 .colorspace = V4L2_COLORSPACE_SRGB,
400 }, {
401 .description = "32-bit RGB",
402 .bpp = 4,
403 .pixelformat = V4L2_PIX_FMT_RGB32,
404 .colorspace = V4L2_COLORSPACE_SRGB,
405 }, {
406 .description = "YUV 4:2:2",
407 .bpp = 2,
408 .pixelformat = V4L2_PIX_FMT_YUYV, // XXX: swapped?
409 .colorspace = V4L2_COLORSPACE_SMPTE170M,
410 }
411};
412
413static const struct vino_data_norm vino_data_norms[] = {
414 {
415 .description = "NTSC",
416 .std = V4L2_STD_NTSC,
417 .fps_min = 6,
418 .fps_max = 30,
419 .framelines = 525,
420 .width = VINO_NTSC_WIDTH,
421 .height = VINO_NTSC_HEIGHT,
422 .odd = {
423 .top = VINO_CLIPPING_START_ODD_NTSC,
424 .left = 0,
425 .bottom = VINO_CLIPPING_START_ODD_NTSC
426 + VINO_NTSC_HEIGHT / 2 - 1,
427 .right = VINO_NTSC_WIDTH,
428 },
429 .even = {
430 .top = VINO_CLIPPING_START_EVEN_NTSC,
431 .left = 0,
432 .bottom = VINO_CLIPPING_START_EVEN_NTSC
433 + VINO_NTSC_HEIGHT / 2 - 1,
434 .right = VINO_NTSC_WIDTH,
435 },
436 }, {
437 .description = "PAL",
438 .std = V4L2_STD_PAL,
439 .fps_min = 5,
440 .fps_max = 25,
441 .framelines = 625,
442 .width = VINO_PAL_WIDTH,
443 .height = VINO_PAL_HEIGHT,
444 .odd = {
445 .top = VINO_CLIPPING_START_ODD_PAL,
446 .left = 0,
447 .bottom = VINO_CLIPPING_START_ODD_PAL
448 + VINO_PAL_HEIGHT / 2 - 1,
449 .right = VINO_PAL_WIDTH,
450 },
451 .even = {
452 .top = VINO_CLIPPING_START_EVEN_PAL,
453 .left = 0,
454 .bottom = VINO_CLIPPING_START_EVEN_PAL
455 + VINO_PAL_HEIGHT / 2 - 1,
456 .right = VINO_PAL_WIDTH,
457 },
458 }, {
459 .description = "SECAM",
460 .std = V4L2_STD_SECAM,
461 .fps_min = 5,
462 .fps_max = 25,
463 .framelines = 625,
464 .width = VINO_PAL_WIDTH,
465 .height = VINO_PAL_HEIGHT,
466 .odd = {
467 .top = VINO_CLIPPING_START_ODD_PAL,
468 .left = 0,
469 .bottom = VINO_CLIPPING_START_ODD_PAL
470 + VINO_PAL_HEIGHT / 2 - 1,
471 .right = VINO_PAL_WIDTH,
472 },
473 .even = {
474 .top = VINO_CLIPPING_START_EVEN_PAL,
475 .left = 0,
476 .bottom = VINO_CLIPPING_START_EVEN_PAL
477 + VINO_PAL_HEIGHT / 2 - 1,
478 .right = VINO_PAL_WIDTH,
479 },
480 }, {
481 .description = "NTSC/D1",
482 .std = V4L2_STD_NTSC,
483 .fps_min = 6,
484 .fps_max = 30,
485 .framelines = 525,
486 .width = VINO_NTSC_WIDTH,
487 .height = VINO_NTSC_HEIGHT,
488 .odd = {
489 .top = VINO_CLIPPING_START_ODD_D1,
490 .left = 0,
491 .bottom = VINO_CLIPPING_START_ODD_D1
492 + VINO_NTSC_HEIGHT / 2 - 1,
493 .right = VINO_NTSC_WIDTH,
494 },
495 .even = {
496 .top = VINO_CLIPPING_START_EVEN_D1,
497 .left = 0,
498 .bottom = VINO_CLIPPING_START_EVEN_D1
499 + VINO_NTSC_HEIGHT / 2 - 1,
500 .right = VINO_NTSC_WIDTH,
501 },
502 }
503};
504
505#define VINO_INDYCAM_V4L2_CONTROL_COUNT 9
506
507struct v4l2_queryctrl vino_indycam_v4l2_controls[] = {
508 {
509 .id = V4L2_CID_AUTOGAIN,
510 .type = V4L2_CTRL_TYPE_BOOLEAN,
511 .name = "Automatic Gain Control",
512 .minimum = 0,
513 .maximum = 1,
514 .step = 1,
515 .default_value = INDYCAM_AGC_DEFAULT,
516 }, {
517 .id = V4L2_CID_AUTO_WHITE_BALANCE,
518 .type = V4L2_CTRL_TYPE_BOOLEAN,
519 .name = "Automatic White Balance",
520 .minimum = 0,
521 .maximum = 1,
522 .step = 1,
523 .default_value = INDYCAM_AWB_DEFAULT,
524 }, {
525 .id = V4L2_CID_GAIN,
526 .type = V4L2_CTRL_TYPE_INTEGER,
527 .name = "Gain",
528 .minimum = INDYCAM_GAIN_MIN,
529 .maximum = INDYCAM_GAIN_MAX,
530 .step = 1,
531 .default_value = INDYCAM_GAIN_DEFAULT,
532 }, {
533 .id = INDYCAM_CONTROL_RED_SATURATION,
534 .type = V4L2_CTRL_TYPE_INTEGER,
535 .name = "Red Saturation",
536 .minimum = INDYCAM_RED_SATURATION_MIN,
537 .maximum = INDYCAM_RED_SATURATION_MAX,
538 .step = 1,
539 .default_value = INDYCAM_RED_SATURATION_DEFAULT,
540 }, {
541 .id = INDYCAM_CONTROL_BLUE_SATURATION,
542 .type = V4L2_CTRL_TYPE_INTEGER,
543 .name = "Blue Saturation",
544 .minimum = INDYCAM_BLUE_SATURATION_MIN,
545 .maximum = INDYCAM_BLUE_SATURATION_MAX,
546 .step = 1,
547 .default_value = INDYCAM_BLUE_SATURATION_DEFAULT,
548 }, {
549 .id = V4L2_CID_RED_BALANCE,
550 .type = V4L2_CTRL_TYPE_INTEGER,
551 .name = "Red Balance",
552 .minimum = INDYCAM_RED_BALANCE_MIN,
553 .maximum = INDYCAM_RED_BALANCE_MAX,
554 .step = 1,
555 .default_value = INDYCAM_RED_BALANCE_DEFAULT,
556 }, {
557 .id = V4L2_CID_BLUE_BALANCE,
558 .type = V4L2_CTRL_TYPE_INTEGER,
559 .name = "Blue Balance",
560 .minimum = INDYCAM_BLUE_BALANCE_MIN,
561 .maximum = INDYCAM_BLUE_BALANCE_MAX,
562 .step = 1,
563 .default_value = INDYCAM_BLUE_BALANCE_DEFAULT,
564 }, {
565 .id = V4L2_CID_EXPOSURE,
566 .type = V4L2_CTRL_TYPE_INTEGER,
567 .name = "Shutter Control",
568 .minimum = INDYCAM_SHUTTER_MIN,
569 .maximum = INDYCAM_SHUTTER_MAX,
570 .step = 1,
571 .default_value = INDYCAM_SHUTTER_DEFAULT,
572 }, {
573 .id = V4L2_CID_GAMMA,
574 .type = V4L2_CTRL_TYPE_INTEGER,
575 .name = "Gamma",
576 .minimum = INDYCAM_GAMMA_MIN,
577 .maximum = INDYCAM_GAMMA_MAX,
578 .step = 1,
579 .default_value = INDYCAM_GAMMA_DEFAULT,
580 }
581};
582
583#define VINO_SAA7191_V4L2_CONTROL_COUNT 9
584
585struct v4l2_queryctrl vino_saa7191_v4l2_controls[] = {
586 {
587 .id = V4L2_CID_HUE,
588 .type = V4L2_CTRL_TYPE_INTEGER,
589 .name = "Hue",
590 .minimum = SAA7191_HUE_MIN,
591 .maximum = SAA7191_HUE_MAX,
592 .step = 1,
593 .default_value = SAA7191_HUE_DEFAULT,
594 }, {
595 .id = SAA7191_CONTROL_BANDPASS,
596 .type = V4L2_CTRL_TYPE_INTEGER,
597 .name = "Luminance Bandpass",
598 .minimum = SAA7191_BANDPASS_MIN,
599 .maximum = SAA7191_BANDPASS_MAX,
600 .step = 1,
601 .default_value = SAA7191_BANDPASS_DEFAULT,
602 }, {
603 .id = SAA7191_CONTROL_BANDPASS_WEIGHT,
604 .type = V4L2_CTRL_TYPE_INTEGER,
605 .name = "Luminance Bandpass Weight",
606 .minimum = SAA7191_BANDPASS_WEIGHT_MIN,
607 .maximum = SAA7191_BANDPASS_WEIGHT_MAX,
608 .step = 1,
609 .default_value = SAA7191_BANDPASS_WEIGHT_DEFAULT,
610 }, {
611 .id = SAA7191_CONTROL_CORING,
612 .type = V4L2_CTRL_TYPE_INTEGER,
613 .name = "HF Luminance Coring",
614 .minimum = SAA7191_CORING_MIN,
615 .maximum = SAA7191_CORING_MAX,
616 .step = 1,
617 .default_value = SAA7191_CORING_DEFAULT,
618 }, {
619 .id = SAA7191_CONTROL_FORCE_COLOUR,
620 .type = V4L2_CTRL_TYPE_BOOLEAN,
621 .name = "Force Colour",
622 .minimum = SAA7191_FORCE_COLOUR_MIN,
623 .maximum = SAA7191_FORCE_COLOUR_MAX,
624 .step = 1,
625 .default_value = SAA7191_FORCE_COLOUR_DEFAULT,
626 }, {
627 .id = SAA7191_CONTROL_CHROMA_GAIN,
628 .type = V4L2_CTRL_TYPE_INTEGER,
629 .name = "Chrominance Gain Control",
630 .minimum = SAA7191_CHROMA_GAIN_MIN,
631 .maximum = SAA7191_CHROMA_GAIN_MAX,
632 .step = 1,
633 .default_value = SAA7191_CHROMA_GAIN_DEFAULT,
634 }, {
635 .id = SAA7191_CONTROL_VTRC,
636 .type = V4L2_CTRL_TYPE_BOOLEAN,
637 .name = "VTR Time Constant",
638 .minimum = SAA7191_VTRC_MIN,
639 .maximum = SAA7191_VTRC_MAX,
640 .step = 1,
641 .default_value = SAA7191_VTRC_DEFAULT,
642 }, {
643 .id = SAA7191_CONTROL_LUMA_DELAY,
644 .type = V4L2_CTRL_TYPE_INTEGER,
645 .name = "Luminance Delay Compensation",
646 .minimum = SAA7191_LUMA_DELAY_MIN,
647 .maximum = SAA7191_LUMA_DELAY_MAX,
648 .step = 1,
649 .default_value = SAA7191_LUMA_DELAY_DEFAULT,
650 }, {
651 .id = SAA7191_CONTROL_VNR,
652 .type = V4L2_CTRL_TYPE_INTEGER,
653 .name = "Vertical Noise Reduction",
654 .minimum = SAA7191_VNR_MIN,
655 .maximum = SAA7191_VNR_MAX,
656 .step = 1,
657 .default_value = SAA7191_VNR_DEFAULT,
658 }
659};
660
661/* VINO framebuffer/DMA descriptor management */
662
663static void vino_free_buffer_with_count(struct vino_framebuffer *fb,
664 unsigned int count)
665{
666 unsigned int i;
667
668 dprintk("vino_free_buffer_with_count(): count = %d\n", count);
669
670 for (i = 0; i < count; i++) {
671 ClearPageReserved(virt_to_page((void *)fb->desc_table.virtual[i]));
672 dma_unmap_single(NULL,
673 fb->desc_table.dma_cpu[VINO_PAGE_RATIO * i],
674 PAGE_SIZE, DMA_FROM_DEVICE);
675 free_page(fb->desc_table.virtual[i]);
676 }
677
678 dma_free_coherent(NULL,
679 VINO_PAGE_RATIO * (fb->desc_table.page_count + 4) *
680 sizeof(dma_addr_t), (void *)fb->desc_table.dma_cpu,
681 fb->desc_table.dma);
682 kfree(fb->desc_table.virtual);
683
684 memset(fb, 0, sizeof(struct vino_framebuffer));
685}
686
687static void vino_free_buffer(struct vino_framebuffer *fb)
688{
689 vino_free_buffer_with_count(fb, fb->desc_table.page_count);
690}
691
692static int vino_allocate_buffer(struct vino_framebuffer *fb,
693 unsigned int size)
694{
695 unsigned int count, i, j;
696 int ret = 0;
697
698 dprintk("vino_allocate_buffer():\n");
699
700 if (size < 1)
701 return -EINVAL;
702
703 memset(fb, 0, sizeof(struct vino_framebuffer));
704
705 count = ((size / PAGE_SIZE) + 4) & ~3;
706
707 dprintk("vino_allocate_buffer(): size = %d, count = %d\n",
708 size, count);
709
710 /* allocate memory for table with virtual (page) addresses */
711 fb->desc_table.virtual =
712 kmalloc(count * sizeof(unsigned long), GFP_KERNEL);
713 if (!fb->desc_table.virtual)
714 return -ENOMEM;
715
716 /* allocate memory for table with dma addresses
717 * (has space for four extra descriptors) */
718 fb->desc_table.dma_cpu =
719 dma_alloc_coherent(NULL, VINO_PAGE_RATIO * (count + 4) *
720 sizeof(dma_addr_t), &fb->desc_table.dma,
721 GFP_KERNEL | GFP_DMA);
722 if (!fb->desc_table.dma_cpu) {
723 ret = -ENOMEM;
724 goto out_free_virtual;
725 }
726
727 /* allocate pages for the buffer and acquire the according
728 * dma addresses */
729 for (i = 0; i < count; i++) {
730 dma_addr_t dma_data_addr;
731
732 fb->desc_table.virtual[i] =
733 get_zeroed_page(GFP_KERNEL | GFP_DMA);
734 if (!fb->desc_table.virtual[i]) {
735 ret = -ENOBUFS;
736 break;
737 }
738
739 dma_data_addr =
740 dma_map_single(NULL,
741 (void *)fb->desc_table.virtual[i],
742 PAGE_SIZE, DMA_FROM_DEVICE);
743
744 for (j = 0; j < VINO_PAGE_RATIO; j++) {
745 fb->desc_table.dma_cpu[VINO_PAGE_RATIO * i + j] =
746 dma_data_addr + VINO_PAGE_SIZE * j;
747 }
748
749 SetPageReserved(virt_to_page((void *)fb->desc_table.virtual[i]));
750 }
751
752 /* page_count needs to be set anyway, because the descriptor table has
753 * been allocated according to this number */
754 fb->desc_table.page_count = count;
755
756 if (ret) {
757 /* the descriptor with index i doesn't contain
758 * a valid address yet */
759 vino_free_buffer_with_count(fb, i);
760 return ret;
761 }
762
763 //fb->size = size;
764 fb->size = count * PAGE_SIZE;
765 fb->data_format = VINO_DATA_FMT_NONE;
766
767 /* set the dma stop-bit for the last (count+1)th descriptor */
768 fb->desc_table.dma_cpu[VINO_PAGE_RATIO * count] = VINO_DESC_STOP;
769 return 0;
770
771 out_free_virtual:
772 kfree(fb->desc_table.virtual);
773 return ret;
774}
775
776#if 0
777/* user buffers not fully implemented yet */
778static int vino_prepare_user_buffer(struct vino_framebuffer *fb,
779 void *user,
780 unsigned int size)
781{
782 unsigned int count, i, j;
783 int ret = 0;
784
785 dprintk("vino_prepare_user_buffer():\n");
786
787 if (size < 1)
788 return -EINVAL;
789
790 memset(fb, 0, sizeof(struct vino_framebuffer));
791
792 count = ((size / PAGE_SIZE)) & ~3;
793
794 dprintk("vino_prepare_user_buffer(): size = %d, count = %d\n",
795 size, count);
796
797 /* allocate memory for table with virtual (page) addresses */
798 fb->desc_table.virtual = (unsigned long *)
799 kmalloc(count * sizeof(unsigned long), GFP_KERNEL);
800 if (!fb->desc_table.virtual)
801 return -ENOMEM;
802
803 /* allocate memory for table with dma addresses
804 * (has space for four extra descriptors) */
805 fb->desc_table.dma_cpu =
806 dma_alloc_coherent(NULL, VINO_PAGE_RATIO * (count + 4) *
807 sizeof(dma_addr_t), &fb->desc_table.dma,
808 GFP_KERNEL | GFP_DMA);
809 if (!fb->desc_table.dma_cpu) {
810 ret = -ENOMEM;
811 goto out_free_virtual;
812 }
813
814 /* allocate pages for the buffer and acquire the according
815 * dma addresses */
816 for (i = 0; i < count; i++) {
817 dma_addr_t dma_data_addr;
818
819 fb->desc_table.virtual[i] =
820 get_zeroed_page(GFP_KERNEL | GFP_DMA);
821 if (!fb->desc_table.virtual[i]) {
822 ret = -ENOBUFS;
823 break;
824 }
825
826 dma_data_addr =
827 dma_map_single(NULL,
828 (void *)fb->desc_table.virtual[i],
829 PAGE_SIZE, DMA_FROM_DEVICE);
830
831 for (j = 0; j < VINO_PAGE_RATIO; j++) {
832 fb->desc_table.dma_cpu[VINO_PAGE_RATIO * i + j] =
833 dma_data_addr + VINO_PAGE_SIZE * j;
834 }
835
836 SetPageReserved(virt_to_page((void *)fb->desc_table.virtual[i]));
837 }
838
839 /* page_count needs to be set anyway, because the descriptor table has
840 * been allocated according to this number */
841 fb->desc_table.page_count = count;
842
843 if (ret) {
844 /* the descriptor with index i doesn't contain
845 * a valid address yet */
846 vino_free_buffer_with_count(fb, i);
847 return ret;
848 }
849
850 //fb->size = size;
851 fb->size = count * PAGE_SIZE;
852
853 /* set the dma stop-bit for the last (count+1)th descriptor */
854 fb->desc_table.dma_cpu[VINO_PAGE_RATIO * count] = VINO_DESC_STOP;
855 return 0;
856
857 out_free_virtual:
858 kfree(fb->desc_table.virtual);
859 return ret;
860}
861#endif
862
863static void vino_sync_buffer(struct vino_framebuffer *fb)
864{
865 int i;
866
867 dprintk("vino_sync_buffer():\n");
868
869 for (i = 0; i < fb->desc_table.page_count; i++)
870 dma_sync_single_for_cpu(NULL,
871 fb->desc_table.dma_cpu[VINO_PAGE_RATIO * i],
872 PAGE_SIZE, DMA_FROM_DEVICE);
873}
874
875/* Framebuffer fifo functions (need to be locked externally) */
876
877static inline void vino_fifo_init(struct vino_framebuffer_fifo *f,
878 unsigned int length)
879{
880 f->length = 0;
881 f->used = 0;
882 f->head = 0;
883 f->tail = 0;
884
885 if (length > VINO_FRAMEBUFFER_COUNT_MAX)
886 length = VINO_FRAMEBUFFER_COUNT_MAX;
887
888 f->length = length;
889}
890
891/* returns true/false */
892static inline int vino_fifo_has_id(struct vino_framebuffer_fifo *f,
893 unsigned int id)
894{
895 unsigned int i;
896
897 for (i = f->head; i == (f->tail - 1); i = (i + 1) % f->length) {
898 if (f->data[i] == id)
899 return 1;
900 }
901
902 return 0;
903}
904
905#if 0
906/* returns true/false */
907static inline int vino_fifo_full(struct vino_framebuffer_fifo *f)
908{
909 return (f->used == f->length);
910}
911#endif
912
913static inline unsigned int vino_fifo_get_used(struct vino_framebuffer_fifo *f)
914{
915 return f->used;
916}
917
918static int vino_fifo_enqueue(struct vino_framebuffer_fifo *f, unsigned int id)
919{
920 if (id >= f->length) {
921 return VINO_QUEUE_ERROR;
922 }
923
924 if (vino_fifo_has_id(f, id)) {
925 return VINO_QUEUE_ERROR;
926 }
927
928 if (f->used < f->length) {
929 f->data[f->tail] = id;
930 f->tail = (f->tail + 1) % f->length;
931 f->used++;
932 } else {
933 return VINO_QUEUE_ERROR;
934 }
935
936 return 0;
937}
938
939static int vino_fifo_peek(struct vino_framebuffer_fifo *f, unsigned int *id)
940{
941 if (f->used > 0) {
942 *id = f->data[f->head];
943 } else {
944 return VINO_QUEUE_ERROR;
945 }
946
947 return 0;
948}
949
950static int vino_fifo_dequeue(struct vino_framebuffer_fifo *f, unsigned int *id)
951{
952 if (f->used > 0) {
953 *id = f->data[f->head];
954 f->head = (f->head + 1) % f->length;
955 f->used--;
956 } else {
957 return VINO_QUEUE_ERROR;
958 }
959
960 return 0;
961}
962
963/* Framebuffer queue functions */
964
965/* execute with queue_lock locked */
966static void vino_queue_free_with_count(struct vino_framebuffer_queue *q,
967 unsigned int length)
968{
969 unsigned int i;
970
971 q->length = 0;
972 memset(&q->in, 0, sizeof(struct vino_framebuffer_fifo));
973 memset(&q->out, 0, sizeof(struct vino_framebuffer_fifo));
974 for (i = 0; i < length; i++) {
975 dprintk("vino_queue_free_with_count(): freeing buffer %d\n",
976 i);
977 vino_free_buffer(q->buffer[i]);
978 kfree(q->buffer[i]);
979 }
980
981 q->type = VINO_MEMORY_NONE;
982 q->magic = 0;
983}
984
985static void vino_queue_free(struct vino_framebuffer_queue *q)
986{
987 dprintk("vino_queue_free():\n");
988
989 if (q->magic != VINO_QUEUE_MAGIC)
990 return;
991 if (q->type != VINO_MEMORY_MMAP)
992 return;
993
994 mutex_lock(&q->queue_mutex);
995
996 vino_queue_free_with_count(q, q->length);
997
998 mutex_unlock(&q->queue_mutex);
999}
1000
1001static int vino_queue_init(struct vino_framebuffer_queue *q,
1002 unsigned int *length)
1003{
1004 unsigned int i;
1005 int ret = 0;
1006
1007 dprintk("vino_queue_init(): length = %d\n", *length);
1008
1009 if (q->magic == VINO_QUEUE_MAGIC) {
1010 dprintk("vino_queue_init(): queue already initialized!\n");
1011 return -EINVAL;
1012 }
1013
1014 if (q->type != VINO_MEMORY_NONE) {
1015 dprintk("vino_queue_init(): queue already initialized!\n");
1016 return -EINVAL;
1017 }
1018
1019 if (*length < 1)
1020 return -EINVAL;
1021
1022 mutex_lock(&q->queue_mutex);
1023
1024 if (*length > VINO_FRAMEBUFFER_COUNT_MAX)
1025 *length = VINO_FRAMEBUFFER_COUNT_MAX;
1026
1027 q->length = 0;
1028
1029 for (i = 0; i < *length; i++) {
1030 dprintk("vino_queue_init(): allocating buffer %d\n", i);
1031 q->buffer[i] = kmalloc(sizeof(struct vino_framebuffer),
1032 GFP_KERNEL);
1033 if (!q->buffer[i]) {
1034 dprintk("vino_queue_init(): kmalloc() failed\n");
1035 ret = -ENOMEM;
1036 break;
1037 }
1038
1039 ret = vino_allocate_buffer(q->buffer[i],
1040 VINO_FRAMEBUFFER_SIZE);
1041 if (ret) {
1042 kfree(q->buffer[i]);
1043 dprintk("vino_queue_init(): "
1044 "vino_allocate_buffer() failed\n");
1045 break;
1046 }
1047
1048 q->buffer[i]->id = i;
1049 if (i > 0) {
1050 q->buffer[i]->offset = q->buffer[i - 1]->offset +
1051 q->buffer[i - 1]->size;
1052 } else {
1053 q->buffer[i]->offset = 0;
1054 }
1055
1056 spin_lock_init(&q->buffer[i]->state_lock);
1057
1058 dprintk("vino_queue_init(): buffer = %d, offset = %d, "
1059 "size = %d\n", i, q->buffer[i]->offset,
1060 q->buffer[i]->size);
1061 }
1062
1063 if (ret) {
1064 vino_queue_free_with_count(q, i);
1065 *length = 0;
1066 } else {
1067 q->length = *length;
1068 vino_fifo_init(&q->in, q->length);
1069 vino_fifo_init(&q->out, q->length);
1070 q->type = VINO_MEMORY_MMAP;
1071 q->magic = VINO_QUEUE_MAGIC;
1072 }
1073
1074 mutex_unlock(&q->queue_mutex);
1075
1076 return ret;
1077}
1078
1079static struct vino_framebuffer *vino_queue_add(struct
1080 vino_framebuffer_queue *q,
1081 unsigned int id)
1082{
1083 struct vino_framebuffer *ret = NULL;
1084 unsigned int total;
1085 unsigned long flags;
1086
1087 dprintk("vino_queue_add(): id = %d\n", id);
1088
1089 if (q->magic != VINO_QUEUE_MAGIC) {
1090 return ret;
1091 }
1092
1093 spin_lock_irqsave(&q->queue_lock, flags);
1094
1095 if (q->length == 0)
1096 goto out;
1097
1098 if (id >= q->length)
1099 goto out;
1100
1101 /* not needed?: if (vino_fifo_full(&q->out)) {
1102 goto out;
1103 }*/
1104 /* check that outgoing queue isn't already full
1105 * (or that it won't become full) */
1106 total = vino_fifo_get_used(&q->in) +
1107 vino_fifo_get_used(&q->out);
1108 if (total >= q->length)
1109 goto out;
1110
1111 if (vino_fifo_enqueue(&q->in, id))
1112 goto out;
1113
1114 ret = q->buffer[id];
1115
1116out:
1117 spin_unlock_irqrestore(&q->queue_lock, flags);
1118
1119 return ret;
1120}
1121
1122static struct vino_framebuffer *vino_queue_transfer(struct
1123 vino_framebuffer_queue *q)
1124{
1125 struct vino_framebuffer *ret = NULL;
1126 struct vino_framebuffer *fb;
1127 int id;
1128 unsigned long flags;
1129
1130 dprintk("vino_queue_transfer():\n");
1131
1132 if (q->magic != VINO_QUEUE_MAGIC) {
1133 return ret;
1134 }
1135
1136 spin_lock_irqsave(&q->queue_lock, flags);
1137
1138 if (q->length == 0)
1139 goto out;
1140
1141 // now this actually removes an entry from the incoming queue
1142 if (vino_fifo_dequeue(&q->in, &id)) {
1143 goto out;
1144 }
1145
1146 dprintk("vino_queue_transfer(): id = %d\n", id);
1147 fb = q->buffer[id];
1148
1149 // we have already checked that the outgoing queue is not full, but...
1150 if (vino_fifo_enqueue(&q->out, id)) {
1151 printk(KERN_ERR "vino_queue_transfer(): "
1152 "outgoing queue is full, this shouldn't happen!\n");
1153 goto out;
1154 }
1155
1156 ret = fb;
1157out:
1158 spin_unlock_irqrestore(&q->queue_lock, flags);
1159
1160 return ret;
1161}
1162
1163/* returns true/false */
1164static int vino_queue_incoming_contains(struct vino_framebuffer_queue *q,
1165 unsigned int id)
1166{
1167 int ret = 0;
1168 unsigned long flags;
1169
1170 if (q->magic != VINO_QUEUE_MAGIC) {
1171 return ret;
1172 }
1173
1174 spin_lock_irqsave(&q->queue_lock, flags);
1175
1176 if (q->length == 0)
1177 goto out;
1178
1179 ret = vino_fifo_has_id(&q->in, id);
1180
1181out:
1182 spin_unlock_irqrestore(&q->queue_lock, flags);
1183
1184 return ret;
1185}
1186
1187/* returns true/false */
1188static int vino_queue_outgoing_contains(struct vino_framebuffer_queue *q,
1189 unsigned int id)
1190{
1191 int ret = 0;
1192 unsigned long flags;
1193
1194 if (q->magic != VINO_QUEUE_MAGIC) {
1195 return ret;
1196 }
1197
1198 spin_lock_irqsave(&q->queue_lock, flags);
1199
1200 if (q->length == 0)
1201 goto out;
1202
1203 ret = vino_fifo_has_id(&q->out, id);
1204
1205out:
1206 spin_unlock_irqrestore(&q->queue_lock, flags);
1207
1208 return ret;
1209}
1210
1211static int vino_queue_get_incoming(struct vino_framebuffer_queue *q,
1212 unsigned int *used)
1213{
1214 int ret = 0;
1215 unsigned long flags;
1216
1217 if (q->magic != VINO_QUEUE_MAGIC) {
1218 return VINO_QUEUE_ERROR;
1219 }
1220
1221 spin_lock_irqsave(&q->queue_lock, flags);
1222
1223 if (q->length == 0) {
1224 ret = VINO_QUEUE_ERROR;
1225 goto out;
1226 }
1227
1228 *used = vino_fifo_get_used(&q->in);
1229
1230out:
1231 spin_unlock_irqrestore(&q->queue_lock, flags);
1232
1233 return ret;
1234}
1235
1236static int vino_queue_get_outgoing(struct vino_framebuffer_queue *q,
1237 unsigned int *used)
1238{
1239 int ret = 0;
1240 unsigned long flags;
1241
1242 if (q->magic != VINO_QUEUE_MAGIC) {
1243 return VINO_QUEUE_ERROR;
1244 }
1245
1246 spin_lock_irqsave(&q->queue_lock, flags);
1247
1248 if (q->length == 0) {
1249 ret = VINO_QUEUE_ERROR;
1250 goto out;
1251 }
1252
1253 *used = vino_fifo_get_used(&q->out);
1254
1255out:
1256 spin_unlock_irqrestore(&q->queue_lock, flags);
1257
1258 return ret;
1259}
1260
1261#if 0
1262static int vino_queue_get_total(struct vino_framebuffer_queue *q,
1263 unsigned int *total)
1264{
1265 int ret = 0;
1266 unsigned long flags;
1267
1268 if (q->magic != VINO_QUEUE_MAGIC) {
1269 return VINO_QUEUE_ERROR;
1270 }
1271
1272 spin_lock_irqsave(&q->queue_lock, flags);
1273
1274 if (q->length == 0) {
1275 ret = VINO_QUEUE_ERROR;
1276 goto out;
1277 }
1278
1279 *total = vino_fifo_get_used(&q->in) +
1280 vino_fifo_get_used(&q->out);
1281
1282out:
1283 spin_unlock_irqrestore(&q->queue_lock, flags);
1284
1285 return ret;
1286}
1287#endif
1288
1289static struct vino_framebuffer *vino_queue_peek(struct
1290 vino_framebuffer_queue *q,
1291 unsigned int *id)
1292{
1293 struct vino_framebuffer *ret = NULL;
1294 unsigned long flags;
1295
1296 if (q->magic != VINO_QUEUE_MAGIC) {
1297 return ret;
1298 }
1299
1300 spin_lock_irqsave(&q->queue_lock, flags);
1301
1302 if (q->length == 0)
1303 goto out;
1304
1305 if (vino_fifo_peek(&q->in, id)) {
1306 goto out;
1307 }
1308
1309 ret = q->buffer[*id];
1310out:
1311 spin_unlock_irqrestore(&q->queue_lock, flags);
1312
1313 return ret;
1314}
1315
1316static struct vino_framebuffer *vino_queue_remove(struct
1317 vino_framebuffer_queue *q,
1318 unsigned int *id)
1319{
1320 struct vino_framebuffer *ret = NULL;
1321 unsigned long flags;
1322 dprintk("vino_queue_remove():\n");
1323
1324 if (q->magic != VINO_QUEUE_MAGIC) {
1325 return ret;
1326 }
1327
1328 spin_lock_irqsave(&q->queue_lock, flags);
1329
1330 if (q->length == 0)
1331 goto out;
1332
1333 if (vino_fifo_dequeue(&q->out, id)) {
1334 goto out;
1335 }
1336
1337 dprintk("vino_queue_remove(): id = %d\n", *id);
1338 ret = q->buffer[*id];
1339out:
1340 spin_unlock_irqrestore(&q->queue_lock, flags);
1341
1342 return ret;
1343}
1344
1345static struct
1346vino_framebuffer *vino_queue_get_buffer(struct vino_framebuffer_queue *q,
1347 unsigned int id)
1348{
1349 struct vino_framebuffer *ret = NULL;
1350 unsigned long flags;
1351
1352 if (q->magic != VINO_QUEUE_MAGIC) {
1353 return ret;
1354 }
1355
1356 spin_lock_irqsave(&q->queue_lock, flags);
1357
1358 if (q->length == 0)
1359 goto out;
1360
1361 if (id >= q->length)
1362 goto out;
1363
1364 ret = q->buffer[id];
1365 out:
1366 spin_unlock_irqrestore(&q->queue_lock, flags);
1367
1368 return ret;
1369}
1370
1371static unsigned int vino_queue_get_length(struct vino_framebuffer_queue *q)
1372{
1373 unsigned int length = 0;
1374 unsigned long flags;
1375
1376 if (q->magic != VINO_QUEUE_MAGIC) {
1377 return length;
1378 }
1379
1380 spin_lock_irqsave(&q->queue_lock, flags);
1381 length = q->length;
1382 spin_unlock_irqrestore(&q->queue_lock, flags);
1383
1384 return length;
1385}
1386
1387static int vino_queue_has_mapped_buffers(struct vino_framebuffer_queue *q)
1388{
1389 unsigned int i;
1390 int ret = 0;
1391 unsigned long flags;
1392
1393 if (q->magic != VINO_QUEUE_MAGIC) {
1394 return ret;
1395 }
1396
1397 spin_lock_irqsave(&q->queue_lock, flags);
1398 for (i = 0; i < q->length; i++) {
1399 if (q->buffer[i]->map_count > 0) {
1400 ret = 1;
1401 break;
1402 }
1403 }
1404 spin_unlock_irqrestore(&q->queue_lock, flags);
1405
1406 return ret;
1407}
1408
1409/* VINO functions */
1410
1411/* execute with input_lock locked */
1412static void vino_update_line_size(struct vino_channel_settings *vcs)
1413{
1414 unsigned int w = vcs->clipping.right - vcs->clipping.left;
1415 unsigned int d = vcs->decimation;
1416 unsigned int bpp = vino_data_formats[vcs->data_format].bpp;
1417 unsigned int lsize;
1418
1419 dprintk("update_line_size(): before: w = %d, d = %d, "
1420 "line_size = %d\n", w, d, vcs->line_size);
1421
1422 /* line size must be multiple of 8 bytes */
1423 lsize = (bpp * (w / d)) & ~7;
1424 w = (lsize / bpp) * d;
1425
1426 vcs->clipping.right = vcs->clipping.left + w;
1427 vcs->line_size = lsize;
1428
1429 dprintk("update_line_size(): after: w = %d, d = %d, "
1430 "line_size = %d\n", w, d, vcs->line_size);
1431}
1432
1433/* execute with input_lock locked */
1434static void vino_set_clipping(struct vino_channel_settings *vcs,
1435 unsigned int x, unsigned int y,
1436 unsigned int w, unsigned int h)
1437{
1438 unsigned int maxwidth, maxheight;
1439 unsigned int d;
1440
1441 maxwidth = vino_data_norms[vcs->data_norm].width;
1442 maxheight = vino_data_norms[vcs->data_norm].height;
1443 d = vcs->decimation;
1444
1445 y &= ~1; /* odd/even fields */
1446
1447 if (x > maxwidth) {
1448 x = 0;
1449 }
1450 if (y > maxheight) {
1451 y = 0;
1452 }
1453
1454 if (((w / d) < VINO_MIN_WIDTH)
1455 || ((h / d) < VINO_MIN_HEIGHT)) {
1456 w = VINO_MIN_WIDTH * d;
1457 h = VINO_MIN_HEIGHT * d;
1458 }
1459
1460 if ((x + w) > maxwidth) {
1461 w = maxwidth - x;
1462 if ((w / d) < VINO_MIN_WIDTH)
1463 x = maxwidth - VINO_MIN_WIDTH * d;
1464 }
1465 if ((y + h) > maxheight) {
1466 h = maxheight - y;
1467 if ((h / d) < VINO_MIN_HEIGHT)
1468 y = maxheight - VINO_MIN_HEIGHT * d;
1469 }
1470
1471 vcs->clipping.left = x;
1472 vcs->clipping.top = y;
1473 vcs->clipping.right = x + w;
1474 vcs->clipping.bottom = y + h;
1475
1476 vino_update_line_size(vcs);
1477
1478 dprintk("clipping %d, %d, %d, %d / %d - %d\n",
1479 vcs->clipping.left, vcs->clipping.top, vcs->clipping.right,
1480 vcs->clipping.bottom, vcs->decimation, vcs->line_size);
1481}
1482
1483/* execute with input_lock locked */
1484static inline void vino_set_default_clipping(struct vino_channel_settings *vcs)
1485{
1486 vino_set_clipping(vcs, 0, 0, vino_data_norms[vcs->data_norm].width,
1487 vino_data_norms[vcs->data_norm].height);
1488}
1489
1490/* execute with input_lock locked */
1491static void vino_set_scaling(struct vino_channel_settings *vcs,
1492 unsigned int w, unsigned int h)
1493{
1494 unsigned int x, y, curw, curh, d;
1495
1496 x = vcs->clipping.left;
1497 y = vcs->clipping.top;
1498 curw = vcs->clipping.right - vcs->clipping.left;
1499 curh = vcs->clipping.bottom - vcs->clipping.top;
1500
1501 d = max(curw / w, curh / h);
1502
1503 dprintk("scaling w: %d, h: %d, curw: %d, curh: %d, d: %d\n",
1504 w, h, curw, curh, d);
1505
1506 if (d < 1) {
1507 d = 1;
1508 } else if (d > 8) {
1509 d = 8;
1510 }
1511
1512 vcs->decimation = d;
1513 vino_set_clipping(vcs, x, y, w * d, h * d);
1514
1515 dprintk("scaling %d, %d, %d, %d / %d - %d\n", vcs->clipping.left,
1516 vcs->clipping.top, vcs->clipping.right, vcs->clipping.bottom,
1517 vcs->decimation, vcs->line_size);
1518}
1519
1520/* execute with input_lock locked */
1521static inline void vino_set_default_scaling(struct vino_channel_settings *vcs)
1522{
1523 vino_set_scaling(vcs, vcs->clipping.right - vcs->clipping.left,
1524 vcs->clipping.bottom - vcs->clipping.top);
1525}
1526
1527/* execute with input_lock locked */
1528static void vino_set_framerate(struct vino_channel_settings *vcs,
1529 unsigned int fps)
1530{
1531 unsigned int mask;
1532
1533 switch (vcs->data_norm) {
1534 case VINO_DATA_NORM_NTSC:
1535 case VINO_DATA_NORM_D1:
1536 fps = (unsigned int)(fps / 6) * 6; // FIXME: round!
1537
1538 if (fps < vino_data_norms[vcs->data_norm].fps_min)
1539 fps = vino_data_norms[vcs->data_norm].fps_min;
1540 if (fps > vino_data_norms[vcs->data_norm].fps_max)
1541 fps = vino_data_norms[vcs->data_norm].fps_max;
1542
1543 switch (fps) {
1544 case 6:
1545 mask = 0x003;
1546 break;
1547 case 12:
1548 mask = 0x0c3;
1549 break;
1550 case 18:
1551 mask = 0x333;
1552 break;
1553 case 24:
1554 mask = 0x3ff;
1555 break;
1556 case 30:
1557 mask = 0xfff;
1558 break;
1559 default:
1560 mask = VINO_FRAMERT_FULL;
1561 }
1562 vcs->framert_reg = VINO_FRAMERT_RT(mask);
1563 break;
1564 case VINO_DATA_NORM_PAL:
1565 case VINO_DATA_NORM_SECAM:
1566 fps = (unsigned int)(fps / 5) * 5; // FIXME: round!
1567
1568 if (fps < vino_data_norms[vcs->data_norm].fps_min)
1569 fps = vino_data_norms[vcs->data_norm].fps_min;
1570 if (fps > vino_data_norms[vcs->data_norm].fps_max)
1571 fps = vino_data_norms[vcs->data_norm].fps_max;
1572
1573 switch (fps) {
1574 case 5:
1575 mask = 0x003;
1576 break;
1577 case 10:
1578 mask = 0x0c3;
1579 break;
1580 case 15:
1581 mask = 0x333;
1582 break;
1583 case 20:
1584 mask = 0x0ff;
1585 break;
1586 case 25:
1587 mask = 0x3ff;
1588 break;
1589 default:
1590 mask = VINO_FRAMERT_FULL;
1591 }
1592 vcs->framert_reg = VINO_FRAMERT_RT(mask) | VINO_FRAMERT_PAL;
1593 break;
1594 }
1595
1596 vcs->fps = fps;
1597}
1598
1599/* execute with input_lock locked */
1600static inline void vino_set_default_framerate(struct
1601 vino_channel_settings *vcs)
1602{
1603 vino_set_framerate(vcs, vino_data_norms[vcs->data_norm].fps_max);
1604}
1605
1606/* VINO I2C bus functions */
1607
1608struct i2c_algo_sgi_data {
1609 void *data; /* private data for lowlevel routines */
1610 unsigned (*getctrl)(void *data);
1611 void (*setctrl)(void *data, unsigned val);
1612 unsigned (*rdata)(void *data);
1613 void (*wdata)(void *data, unsigned val);
1614
1615 int xfer_timeout;
1616 int ack_timeout;
1617};
1618
1619static int wait_xfer_done(struct i2c_algo_sgi_data *adap)
1620{
1621 int i;
1622
1623 for (i = 0; i < adap->xfer_timeout; i++) {
1624 if ((adap->getctrl(adap->data) & SGI_I2C_XFER_BUSY) == 0)
1625 return 0;
1626 udelay(1);
1627 }
1628
1629 return -ETIMEDOUT;
1630}
1631
1632static int wait_ack(struct i2c_algo_sgi_data *adap)
1633{
1634 int i;
1635
1636 if (wait_xfer_done(adap))
1637 return -ETIMEDOUT;
1638 for (i = 0; i < adap->ack_timeout; i++) {
1639 if ((adap->getctrl(adap->data) & SGI_I2C_NACK) == 0)
1640 return 0;
1641 udelay(1);
1642 }
1643
1644 return -ETIMEDOUT;
1645}
1646
1647static int force_idle(struct i2c_algo_sgi_data *adap)
1648{
1649 int i;
1650
1651 adap->setctrl(adap->data, SGI_I2C_FORCE_IDLE);
1652 for (i = 0; i < adap->xfer_timeout; i++) {
1653 if ((adap->getctrl(adap->data) & SGI_I2C_NOT_IDLE) == 0)
1654 goto out;
1655 udelay(1);
1656 }
1657 return -ETIMEDOUT;
1658out:
1659 if (adap->getctrl(adap->data) & SGI_I2C_BUS_ERR)
1660 return -EIO;
1661 return 0;
1662}
1663
1664static int do_address(struct i2c_algo_sgi_data *adap, unsigned int addr,
1665 int rd)
1666{
1667 if (rd)
1668 adap->setctrl(adap->data, SGI_I2C_NOT_IDLE);
1669 /* Check if bus is idle, eventually force it to do so */
1670 if (adap->getctrl(adap->data) & SGI_I2C_NOT_IDLE)
1671 if (force_idle(adap))
1672 return -EIO;
1673 /* Write out the i2c chip address and specify operation */
1674 adap->setctrl(adap->data,
1675 SGI_I2C_HOLD_BUS | SGI_I2C_WRITE | SGI_I2C_NOT_IDLE);
1676 if (rd)
1677 addr |= 1;
1678 adap->wdata(adap->data, addr);
1679 if (wait_ack(adap))
1680 return -EIO;
1681 return 0;
1682}
1683
1684static int i2c_read(struct i2c_algo_sgi_data *adap, unsigned char *buf,
1685 unsigned int len)
1686{
1687 int i;
1688
1689 adap->setctrl(adap->data,
1690 SGI_I2C_HOLD_BUS | SGI_I2C_READ | SGI_I2C_NOT_IDLE);
1691 for (i = 0; i < len; i++) {
1692 if (wait_xfer_done(adap))
1693 return -EIO;
1694 buf[i] = adap->rdata(adap->data);
1695 }
1696 adap->setctrl(adap->data, SGI_I2C_RELEASE_BUS | SGI_I2C_FORCE_IDLE);
1697
1698 return 0;
1699
1700}
1701
1702static int i2c_write(struct i2c_algo_sgi_data *adap, unsigned char *buf,
1703 unsigned int len)
1704{
1705 int i;
1706
1707 /* We are already in write state */
1708 for (i = 0; i < len; i++) {
1709 adap->wdata(adap->data, buf[i]);
1710 if (wait_ack(adap))
1711 return -EIO;
1712 }
1713 return 0;
1714}
1715
1716static int sgi_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs,
1717 int num)
1718{
1719 struct i2c_algo_sgi_data *adap = i2c_adap->algo_data;
1720 struct i2c_msg *p;
1721 int i, err = 0;
1722
1723 for (i = 0; !err && i < num; i++) {
1724 p = &msgs[i];
1725 err = do_address(adap, p->addr, p->flags & I2C_M_RD);
1726 if (err || !p->len)
1727 continue;
1728 if (p->flags & I2C_M_RD)
1729 err = i2c_read(adap, p->buf, p->len);
1730 else
1731 err = i2c_write(adap, p->buf, p->len);
1732 }
1733
1734 return (err < 0) ? err : i;
1735}
1736
1737static u32 sgi_func(struct i2c_adapter *adap)
1738{
1739 return I2C_FUNC_SMBUS_EMUL;
1740}
1741
1742static const struct i2c_algorithm sgi_algo = {
1743 .master_xfer = sgi_xfer,
1744 .functionality = sgi_func,
1745};
1746
1747static unsigned i2c_vino_getctrl(void *data)
1748{
1749 return vino->i2c_control;
1750}
1751
1752static void i2c_vino_setctrl(void *data, unsigned val)
1753{
1754 vino->i2c_control = val;
1755}
1756
1757static unsigned i2c_vino_rdata(void *data)
1758{
1759 return vino->i2c_data;
1760}
1761
1762static void i2c_vino_wdata(void *data, unsigned val)
1763{
1764 vino->i2c_data = val;
1765}
1766
1767static struct i2c_algo_sgi_data i2c_sgi_vino_data = {
1768 .getctrl = &i2c_vino_getctrl,
1769 .setctrl = &i2c_vino_setctrl,
1770 .rdata = &i2c_vino_rdata,
1771 .wdata = &i2c_vino_wdata,
1772 .xfer_timeout = 200,
1773 .ack_timeout = 1000,
1774};
1775
1776static struct i2c_adapter vino_i2c_adapter = {
1777 .name = "VINO I2C bus",
1778 .algo = &sgi_algo,
1779 .algo_data = &i2c_sgi_vino_data,
1780 .owner = THIS_MODULE,
1781};
1782
1783/*
1784 * Prepare VINO for DMA transfer...
1785 * (execute only with vino_lock and input_lock locked)
1786 */
1787static int vino_dma_setup(struct vino_channel_settings *vcs,
1788 struct vino_framebuffer *fb)
1789{
1790 u32 ctrl, intr;
1791 struct sgi_vino_channel *ch;
1792 const struct vino_data_norm *norm;
1793
1794 dprintk("vino_dma_setup():\n");
1795
1796 vcs->field = 0;
1797 fb->frame_counter = 0;
1798
1799 ch = (vcs->channel == VINO_CHANNEL_A) ? &vino->a : &vino->b;
1800 norm = &vino_data_norms[vcs->data_norm];
1801
1802 ch->page_index = 0;
1803 ch->line_count = 0;
1804
1805 /* VINO line size register is set 8 bytes less than actual */
1806 ch->line_size = vcs->line_size - 8;
1807
1808 /* let VINO know where to transfer data */
1809 ch->start_desc_tbl = fb->desc_table.dma;
1810 ch->next_4_desc = fb->desc_table.dma;
1811
1812 /* give vino time to fetch the first four descriptors, 5 usec
1813 * should be more than enough time */
1814 udelay(VINO_DESC_FETCH_DELAY);
1815
1816 dprintk("vino_dma_setup(): start desc = %08x, next 4 desc = %08x\n",
1817 ch->start_desc_tbl, ch->next_4_desc);
1818
1819 /* set the alpha register */
1820 ch->alpha = vcs->alpha;
1821
1822 /* set clipping registers */
1823 ch->clip_start = VINO_CLIP_ODD(norm->odd.top + vcs->clipping.top / 2) |
1824 VINO_CLIP_EVEN(norm->even.top +
1825 vcs->clipping.top / 2) |
1826 VINO_CLIP_X(vcs->clipping.left);
1827 ch->clip_end = VINO_CLIP_ODD(norm->odd.top +
1828 vcs->clipping.bottom / 2 - 1) |
1829 VINO_CLIP_EVEN(norm->even.top +
1830 vcs->clipping.bottom / 2 - 1) |
1831 VINO_CLIP_X(vcs->clipping.right);
1832
1833 /* set the size of actual content in the buffer (DECIMATION !) */
1834 fb->data_size = ((vcs->clipping.right - vcs->clipping.left) /
1835 vcs->decimation) *
1836 ((vcs->clipping.bottom - vcs->clipping.top) /
1837 vcs->decimation) *
1838 vino_data_formats[vcs->data_format].bpp;
1839
1840 ch->frame_rate = vcs->framert_reg;
1841
1842 ctrl = vino->control;
1843 intr = vino->intr_status;
1844
1845 if (vcs->channel == VINO_CHANNEL_A) {
1846 /* All interrupt conditions for this channel was cleared
1847 * so clear the interrupt status register and enable
1848 * interrupts */
1849 intr &= ~VINO_INTSTAT_A;
1850 ctrl |= VINO_CTRL_A_INT;
1851
1852 /* enable synchronization */
1853 ctrl |= VINO_CTRL_A_SYNC_ENBL;
1854
1855 /* enable frame assembly */
1856 ctrl |= VINO_CTRL_A_INTERLEAVE_ENBL;
1857
1858 /* set decimation used */
1859 if (vcs->decimation < 2)
1860 ctrl &= ~VINO_CTRL_A_DEC_ENBL;
1861 else {
1862 ctrl |= VINO_CTRL_A_DEC_ENBL;
1863 ctrl &= ~VINO_CTRL_A_DEC_SCALE_MASK;
1864 ctrl |= (vcs->decimation - 1) <<
1865 VINO_CTRL_A_DEC_SCALE_SHIFT;
1866 }
1867
1868 /* select input interface */
1869 if (vcs->input == VINO_INPUT_D1)
1870 ctrl |= VINO_CTRL_A_SELECT;
1871 else
1872 ctrl &= ~VINO_CTRL_A_SELECT;
1873
1874 /* palette */
1875 ctrl &= ~(VINO_CTRL_A_LUMA_ONLY | VINO_CTRL_A_RGB |
1876 VINO_CTRL_A_DITHER);
1877 } else {
1878 intr &= ~VINO_INTSTAT_B;
1879 ctrl |= VINO_CTRL_B_INT;
1880
1881 ctrl |= VINO_CTRL_B_SYNC_ENBL;
1882 ctrl |= VINO_CTRL_B_INTERLEAVE_ENBL;
1883
1884 if (vcs->decimation < 2)
1885 ctrl &= ~VINO_CTRL_B_DEC_ENBL;
1886 else {
1887 ctrl |= VINO_CTRL_B_DEC_ENBL;
1888 ctrl &= ~VINO_CTRL_B_DEC_SCALE_MASK;
1889 ctrl |= (vcs->decimation - 1) <<
1890 VINO_CTRL_B_DEC_SCALE_SHIFT;
1891
1892 }
1893 if (vcs->input == VINO_INPUT_D1)
1894 ctrl |= VINO_CTRL_B_SELECT;
1895 else
1896 ctrl &= ~VINO_CTRL_B_SELECT;
1897
1898 ctrl &= ~(VINO_CTRL_B_LUMA_ONLY | VINO_CTRL_B_RGB |
1899 VINO_CTRL_B_DITHER);
1900 }
1901
1902 /* set palette */
1903 fb->data_format = vcs->data_format;
1904
1905 switch (vcs->data_format) {
1906 case VINO_DATA_FMT_GREY:
1907 ctrl |= (vcs->channel == VINO_CHANNEL_A) ?
1908 VINO_CTRL_A_LUMA_ONLY : VINO_CTRL_B_LUMA_ONLY;
1909 break;
1910 case VINO_DATA_FMT_RGB32:
1911 ctrl |= (vcs->channel == VINO_CHANNEL_A) ?
1912 VINO_CTRL_A_RGB : VINO_CTRL_B_RGB;
1913 break;
1914 case VINO_DATA_FMT_YUV:
1915 /* nothing needs to be done */
1916 break;
1917 case VINO_DATA_FMT_RGB332:
1918 ctrl |= (vcs->channel == VINO_CHANNEL_A) ?
1919 VINO_CTRL_A_RGB | VINO_CTRL_A_DITHER :
1920 VINO_CTRL_B_RGB | VINO_CTRL_B_DITHER;
1921 break;
1922 }
1923
1924 vino->intr_status = intr;
1925 vino->control = ctrl;
1926
1927 return 0;
1928}
1929
1930/* (execute only with vino_lock locked) */
1931static inline void vino_dma_start(struct vino_channel_settings *vcs)
1932{
1933 u32 ctrl = vino->control;
1934
1935 dprintk("vino_dma_start():\n");
1936 ctrl |= (vcs->channel == VINO_CHANNEL_A) ?
1937 VINO_CTRL_A_DMA_ENBL : VINO_CTRL_B_DMA_ENBL;
1938 vino->control = ctrl;
1939}
1940
1941/* (execute only with vino_lock locked) */
1942static inline void vino_dma_stop(struct vino_channel_settings *vcs)
1943{
1944 u32 ctrl = vino->control;
1945
1946 ctrl &= (vcs->channel == VINO_CHANNEL_A) ?
1947 ~VINO_CTRL_A_DMA_ENBL : ~VINO_CTRL_B_DMA_ENBL;
1948 ctrl &= (vcs->channel == VINO_CHANNEL_A) ?
1949 ~VINO_CTRL_A_INT : ~VINO_CTRL_B_INT;
1950 vino->control = ctrl;
1951 dprintk("vino_dma_stop():\n");
1952}
1953
1954/*
1955 * Load dummy page to descriptor registers. This prevents generating of
1956 * spurious interrupts. (execute only with vino_lock locked)
1957 */
1958static void vino_clear_interrupt(struct vino_channel_settings *vcs)
1959{
1960 struct sgi_vino_channel *ch;
1961
1962 ch = (vcs->channel == VINO_CHANNEL_A) ? &vino->a : &vino->b;
1963
1964 ch->page_index = 0;
1965 ch->line_count = 0;
1966
1967 ch->start_desc_tbl = vino_drvdata->dummy_desc_table.dma;
1968 ch->next_4_desc = vino_drvdata->dummy_desc_table.dma;
1969
1970 udelay(VINO_DESC_FETCH_DELAY);
1971 dprintk("channel %c clear interrupt condition\n",
1972 (vcs->channel == VINO_CHANNEL_A) ? 'A':'B');
1973}
1974
1975static int vino_capture(struct vino_channel_settings *vcs,
1976 struct vino_framebuffer *fb)
1977{
1978 int err = 0;
1979 unsigned long flags, flags2;
1980
1981 spin_lock_irqsave(&fb->state_lock, flags);
1982
1983 if (fb->state == VINO_FRAMEBUFFER_IN_USE)
1984 err = -EBUSY;
1985 fb->state = VINO_FRAMEBUFFER_IN_USE;
1986
1987 spin_unlock_irqrestore(&fb->state_lock, flags);
1988
1989 if (err)
1990 return err;
1991
1992 spin_lock_irqsave(&vino_drvdata->vino_lock, flags);
1993 spin_lock_irqsave(&vino_drvdata->input_lock, flags2);
1994
1995 vino_dma_setup(vcs, fb);
1996 vino_dma_start(vcs);
1997
1998 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags2);
1999 spin_unlock_irqrestore(&vino_drvdata->vino_lock, flags);
2000
2001 return err;
2002}
2003
2004static
2005struct vino_framebuffer *vino_capture_enqueue(struct
2006 vino_channel_settings *vcs,
2007 unsigned int index)
2008{
2009 struct vino_framebuffer *fb;
2010 unsigned long flags;
2011
2012 dprintk("vino_capture_enqueue():\n");
2013
2014 spin_lock_irqsave(&vcs->capture_lock, flags);
2015
2016 fb = vino_queue_add(&vcs->fb_queue, index);
2017 if (fb == NULL) {
2018 dprintk("vino_capture_enqueue(): vino_queue_add() failed, "
2019 "queue full?\n");
2020 goto out;
2021 }
2022out:
2023 spin_unlock_irqrestore(&vcs->capture_lock, flags);
2024
2025 return fb;
2026}
2027
2028static int vino_capture_next(struct vino_channel_settings *vcs, int start)
2029{
2030 struct vino_framebuffer *fb;
2031 unsigned int incoming, id;
2032 int err = 0;
2033 unsigned long flags;
2034
2035 dprintk("vino_capture_next():\n");
2036
2037 spin_lock_irqsave(&vcs->capture_lock, flags);
2038
2039 if (start) {
2040 /* start capture only if capture isn't in progress already */
2041 if (vcs->capturing) {
2042 spin_unlock_irqrestore(&vcs->capture_lock, flags);
2043 return 0;
2044 }
2045
2046 } else {
2047 /* capture next frame:
2048 * stop capture if capturing is not set */
2049 if (!vcs->capturing) {
2050 spin_unlock_irqrestore(&vcs->capture_lock, flags);
2051 return 0;
2052 }
2053 }
2054
2055 err = vino_queue_get_incoming(&vcs->fb_queue, &incoming);
2056 if (err) {
2057 dprintk("vino_capture_next(): vino_queue_get_incoming() "
2058 "failed\n");
2059 err = -EINVAL;
2060 goto out;
2061 }
2062 if (incoming == 0) {
2063 dprintk("vino_capture_next(): no buffers available\n");
2064 goto out;
2065 }
2066
2067 fb = vino_queue_peek(&vcs->fb_queue, &id);
2068 if (fb == NULL) {
2069 dprintk("vino_capture_next(): vino_queue_peek() failed\n");
2070 err = -EINVAL;
2071 goto out;
2072 }
2073
2074 if (start) {
2075 vcs->capturing = 1;
2076 }
2077
2078 spin_unlock_irqrestore(&vcs->capture_lock, flags);
2079
2080 err = vino_capture(vcs, fb);
2081
2082 return err;
2083
2084out:
2085 vcs->capturing = 0;
2086 spin_unlock_irqrestore(&vcs->capture_lock, flags);
2087
2088 return err;
2089}
2090
2091static inline int vino_is_capturing(struct vino_channel_settings *vcs)
2092{
2093 int ret;
2094 unsigned long flags;
2095
2096 spin_lock_irqsave(&vcs->capture_lock, flags);
2097
2098 ret = vcs->capturing;
2099
2100 spin_unlock_irqrestore(&vcs->capture_lock, flags);
2101
2102 return ret;
2103}
2104
2105/* waits until a frame is captured */
2106static int vino_wait_for_frame(struct vino_channel_settings *vcs)
2107{
2108 wait_queue_t wait;
2109 int err = 0;
2110
2111 dprintk("vino_wait_for_frame():\n");
2112
2113 init_waitqueue_entry(&wait, current);
2114 /* add ourselves into wait queue */
2115 add_wait_queue(&vcs->fb_queue.frame_wait_queue, &wait);
2116
2117 /* to ensure that schedule_timeout will return immediately
2118 * if VINO interrupt was triggered meanwhile */
2119 schedule_timeout_interruptible(msecs_to_jiffies(100));
2120
2121 if (signal_pending(current))
2122 err = -EINTR;
2123
2124 remove_wait_queue(&vcs->fb_queue.frame_wait_queue, &wait);
2125
2126 dprintk("vino_wait_for_frame(): waiting for frame %s\n",
2127 err ? "failed" : "ok");
2128
2129 return err;
2130}
2131
2132/* the function assumes that PAGE_SIZE % 4 == 0 */
2133static void vino_convert_to_rgba(struct vino_framebuffer *fb) {
2134 unsigned char *pageptr;
2135 unsigned int page, i;
2136 unsigned char a;
2137
2138 for (page = 0; page < fb->desc_table.page_count; page++) {
2139 pageptr = (unsigned char *)fb->desc_table.virtual[page];
2140
2141 for (i = 0; i < PAGE_SIZE; i += 4) {
2142 a = pageptr[0];
2143 pageptr[0] = pageptr[3];
2144 pageptr[1] = pageptr[2];
2145 pageptr[2] = pageptr[1];
2146 pageptr[3] = a;
2147 pageptr += 4;
2148 }
2149 }
2150}
2151
2152/* checks if the buffer is in correct state and syncs data */
2153static int vino_check_buffer(struct vino_channel_settings *vcs,
2154 struct vino_framebuffer *fb)
2155{
2156 int err = 0;
2157 unsigned long flags;
2158
2159 dprintk("vino_check_buffer():\n");
2160
2161 spin_lock_irqsave(&fb->state_lock, flags);
2162 switch (fb->state) {
2163 case VINO_FRAMEBUFFER_IN_USE:
2164 err = -EIO;
2165 break;
2166 case VINO_FRAMEBUFFER_READY:
2167 vino_sync_buffer(fb);
2168 fb->state = VINO_FRAMEBUFFER_UNUSED;
2169 break;
2170 default:
2171 err = -EINVAL;
2172 }
2173 spin_unlock_irqrestore(&fb->state_lock, flags);
2174
2175 if (!err) {
2176 if (vino_pixel_conversion
2177 && (fb->data_format == VINO_DATA_FMT_RGB32)) {
2178 vino_convert_to_rgba(fb);
2179 }
2180 } else if (err && (err != -EINVAL)) {
2181 dprintk("vino_check_buffer(): buffer not ready\n");
2182
2183 spin_lock_irqsave(&vino_drvdata->vino_lock, flags);
2184 vino_dma_stop(vcs);
2185 vino_clear_interrupt(vcs);
2186 spin_unlock_irqrestore(&vino_drvdata->vino_lock, flags);
2187 }
2188
2189 return err;
2190}
2191
2192/* forcefully terminates capture */
2193static void vino_capture_stop(struct vino_channel_settings *vcs)
2194{
2195 unsigned int incoming = 0, outgoing = 0, id;
2196 unsigned long flags, flags2;
2197
2198 dprintk("vino_capture_stop():\n");
2199
2200 spin_lock_irqsave(&vcs->capture_lock, flags);
2201
2202 /* unset capturing to stop queue processing */
2203 vcs->capturing = 0;
2204
2205 spin_lock_irqsave(&vino_drvdata->vino_lock, flags2);
2206
2207 vino_dma_stop(vcs);
2208 vino_clear_interrupt(vcs);
2209
2210 spin_unlock_irqrestore(&vino_drvdata->vino_lock, flags2);
2211
2212 /* remove all items from the queue */
2213 if (vino_queue_get_incoming(&vcs->fb_queue, &incoming)) {
2214 dprintk("vino_capture_stop(): "
2215 "vino_queue_get_incoming() failed\n");
2216 goto out;
2217 }
2218 while (incoming > 0) {
2219 vino_queue_transfer(&vcs->fb_queue);
2220
2221 if (vino_queue_get_incoming(&vcs->fb_queue, &incoming)) {
2222 dprintk("vino_capture_stop(): "
2223 "vino_queue_get_incoming() failed\n");
2224 goto out;
2225 }
2226 }
2227
2228 if (vino_queue_get_outgoing(&vcs->fb_queue, &outgoing)) {
2229 dprintk("vino_capture_stop(): "
2230 "vino_queue_get_outgoing() failed\n");
2231 goto out;
2232 }
2233 while (outgoing > 0) {
2234 vino_queue_remove(&vcs->fb_queue, &id);
2235
2236 if (vino_queue_get_outgoing(&vcs->fb_queue, &outgoing)) {
2237 dprintk("vino_capture_stop(): "
2238 "vino_queue_get_outgoing() failed\n");
2239 goto out;
2240 }
2241 }
2242
2243out:
2244 spin_unlock_irqrestore(&vcs->capture_lock, flags);
2245}
2246
2247#if 0
2248static int vino_capture_failed(struct vino_channel_settings *vcs)
2249{
2250 struct vino_framebuffer *fb;
2251 unsigned long flags;
2252 unsigned int i;
2253 int ret;
2254
2255 dprintk("vino_capture_failed():\n");
2256
2257 spin_lock_irqsave(&vino_drvdata->vino_lock, flags);
2258
2259 vino_dma_stop(vcs);
2260 vino_clear_interrupt(vcs);
2261
2262 spin_unlock_irqrestore(&vino_drvdata->vino_lock, flags);
2263
2264 ret = vino_queue_get_incoming(&vcs->fb_queue, &i);
2265 if (ret == VINO_QUEUE_ERROR) {
2266 dprintk("vino_queue_get_incoming() failed\n");
2267 return -EINVAL;
2268 }
2269 if (i == 0) {
2270 /* no buffers to process */
2271 return 0;
2272 }
2273
2274 fb = vino_queue_peek(&vcs->fb_queue, &i);
2275 if (fb == NULL) {
2276 dprintk("vino_queue_peek() failed\n");
2277 return -EINVAL;
2278 }
2279
2280 spin_lock_irqsave(&fb->state_lock, flags);
2281 if (fb->state == VINO_FRAMEBUFFER_IN_USE) {
2282 fb->state = VINO_FRAMEBUFFER_UNUSED;
2283 vino_queue_transfer(&vcs->fb_queue);
2284 vino_queue_remove(&vcs->fb_queue, &i);
2285 /* we should actually discard the newest frame,
2286 * but who cares ... */
2287 }
2288 spin_unlock_irqrestore(&fb->state_lock, flags);
2289
2290 return 0;
2291}
2292#endif
2293
2294static void vino_skip_frame(struct vino_channel_settings *vcs)
2295{
2296 struct vino_framebuffer *fb;
2297 unsigned long flags;
2298 unsigned int id;
2299
2300 spin_lock_irqsave(&vcs->capture_lock, flags);
2301 fb = vino_queue_peek(&vcs->fb_queue, &id);
2302 if (!fb) {
2303 spin_unlock_irqrestore(&vcs->capture_lock, flags);
2304 dprintk("vino_skip_frame(): vino_queue_peek() failed!\n");
2305 return;
2306 }
2307 spin_unlock_irqrestore(&vcs->capture_lock, flags);
2308
2309 spin_lock_irqsave(&fb->state_lock, flags);
2310 fb->state = VINO_FRAMEBUFFER_UNUSED;
2311 spin_unlock_irqrestore(&fb->state_lock, flags);
2312
2313 vino_capture_next(vcs, 0);
2314}
2315
2316static void vino_frame_done(struct vino_channel_settings *vcs)
2317{
2318 struct vino_framebuffer *fb;
2319 unsigned long flags;
2320
2321 spin_lock_irqsave(&vcs->capture_lock, flags);
2322 fb = vino_queue_transfer(&vcs->fb_queue);
2323 if (!fb) {
2324 spin_unlock_irqrestore(&vcs->capture_lock, flags);
2325 dprintk("vino_frame_done(): vino_queue_transfer() failed!\n");
2326 return;
2327 }
2328 spin_unlock_irqrestore(&vcs->capture_lock, flags);
2329
2330 fb->frame_counter = vcs->int_data.frame_counter;
2331 memcpy(&fb->timestamp, &vcs->int_data.timestamp,
2332 sizeof(struct timeval));
2333
2334 spin_lock_irqsave(&fb->state_lock, flags);
2335 if (fb->state == VINO_FRAMEBUFFER_IN_USE)
2336 fb->state = VINO_FRAMEBUFFER_READY;
2337 spin_unlock_irqrestore(&fb->state_lock, flags);
2338
2339 wake_up(&vcs->fb_queue.frame_wait_queue);
2340
2341 vino_capture_next(vcs, 0);
2342}
2343
2344static void vino_capture_tasklet(unsigned long channel) {
2345 struct vino_channel_settings *vcs;
2346
2347 vcs = (channel == VINO_CHANNEL_A)
2348 ? &vino_drvdata->a : &vino_drvdata->b;
2349
2350 if (vcs->int_data.skip)
2351 vcs->int_data.skip_count++;
2352
2353 if (vcs->int_data.skip && (vcs->int_data.skip_count
2354 <= VINO_MAX_FRAME_SKIP_COUNT)) {
2355 vino_skip_frame(vcs);
2356 } else {
2357 vcs->int_data.skip_count = 0;
2358 vino_frame_done(vcs);
2359 }
2360}
2361
2362static irqreturn_t vino_interrupt(int irq, void *dev_id)
2363{
2364 u32 ctrl, intr;
2365 unsigned int fc_a, fc_b;
2366 int handled_a = 0, skip_a = 0, done_a = 0;
2367 int handled_b = 0, skip_b = 0, done_b = 0;
2368
2369#ifdef VINO_DEBUG_INT
2370 int loop = 0;
2371 unsigned int line_count = vino->a.line_count,
2372 page_index = vino->a.page_index,
2373 field_counter = vino->a.field_counter,
2374 start_desc_tbl = vino->a.start_desc_tbl,
2375 next_4_desc = vino->a.next_4_desc;
2376 unsigned int line_count_2,
2377 page_index_2,
2378 field_counter_2,
2379 start_desc_tbl_2,
2380 next_4_desc_2;
2381#endif
2382
2383 spin_lock(&vino_drvdata->vino_lock);
2384
2385 while ((intr = vino->intr_status)) {
2386 fc_a = vino->a.field_counter >> 1;
2387 fc_b = vino->b.field_counter >> 1;
2388
2389 /* handle error-interrupts in some special way ?
2390 * --> skips frames */
2391 if (intr & VINO_INTSTAT_A) {
2392 if (intr & VINO_INTSTAT_A_EOF) {
2393 vino_drvdata->a.field++;
2394 if (vino_drvdata->a.field > 1) {
2395 vino_dma_stop(&vino_drvdata->a);
2396 vino_clear_interrupt(&vino_drvdata->a);
2397 vino_drvdata->a.field = 0;
2398 done_a = 1;
2399 } else {
2400 if (vino->a.page_index
2401 != vino_drvdata->a.line_size) {
2402 vino->a.line_count = 0;
2403 vino->a.page_index =
2404 vino_drvdata->
2405 a.line_size;
2406 vino->a.next_4_desc =
2407 vino->a.start_desc_tbl;
2408 }
2409 }
2410 dprintk("channel A end-of-field "
2411 "interrupt: %04x\n", intr);
2412 } else {
2413 vino_dma_stop(&vino_drvdata->a);
2414 vino_clear_interrupt(&vino_drvdata->a);
2415 vino_drvdata->a.field = 0;
2416 skip_a = 1;
2417 dprintk("channel A error interrupt: %04x\n",
2418 intr);
2419 }
2420
2421#ifdef VINO_DEBUG_INT
2422 line_count_2 = vino->a.line_count;
2423 page_index_2 = vino->a.page_index;
2424 field_counter_2 = vino->a.field_counter;
2425 start_desc_tbl_2 = vino->a.start_desc_tbl;
2426 next_4_desc_2 = vino->a.next_4_desc;
2427
2428 printk("intr = %04x, loop = %d, field = %d\n",
2429 intr, loop, vino_drvdata->a.field);
2430 printk("1- line count = %04d, page index = %04d, "
2431 "start = %08x, next = %08x\n"
2432 " fieldc = %d, framec = %d\n",
2433 line_count, page_index, start_desc_tbl,
2434 next_4_desc, field_counter, fc_a);
2435 printk("12-line count = %04d, page index = %04d, "
2436 " start = %08x, next = %08x\n",
2437 line_count_2, page_index_2, start_desc_tbl_2,
2438 next_4_desc_2);
2439
2440 if (done_a)
2441 printk("\n");
2442#endif
2443 }
2444
2445 if (intr & VINO_INTSTAT_B) {
2446 if (intr & VINO_INTSTAT_B_EOF) {
2447 vino_drvdata->b.field++;
2448 if (vino_drvdata->b.field > 1) {
2449 vino_dma_stop(&vino_drvdata->b);
2450 vino_clear_interrupt(&vino_drvdata->b);
2451 vino_drvdata->b.field = 0;
2452 done_b = 1;
2453 }
2454 dprintk("channel B end-of-field "
2455 "interrupt: %04x\n", intr);
2456 } else {
2457 vino_dma_stop(&vino_drvdata->b);
2458 vino_clear_interrupt(&vino_drvdata->b);
2459 vino_drvdata->b.field = 0;
2460 skip_b = 1;
2461 dprintk("channel B error interrupt: %04x\n",
2462 intr);
2463 }
2464 }
2465
2466 /* Always remember to clear interrupt status.
2467 * Disable VINO interrupts while we do this. */
2468 ctrl = vino->control;
2469 vino->control = ctrl & ~(VINO_CTRL_A_INT | VINO_CTRL_B_INT);
2470 vino->intr_status = ~intr;
2471 vino->control = ctrl;
2472
2473 spin_unlock(&vino_drvdata->vino_lock);
2474
2475 if ((!handled_a) && (done_a || skip_a)) {
2476 if (!skip_a) {
2477 do_gettimeofday(&vino_drvdata->
2478 a.int_data.timestamp);
2479 vino_drvdata->a.int_data.frame_counter = fc_a;
2480 }
2481 vino_drvdata->a.int_data.skip = skip_a;
2482
2483 dprintk("channel A %s, interrupt: %d\n",
2484 skip_a ? "skipping frame" : "frame done",
2485 intr);
2486 tasklet_hi_schedule(&vino_tasklet_a);
2487 handled_a = 1;
2488 }
2489
2490 if ((!handled_b) && (done_b || skip_b)) {
2491 if (!skip_b) {
2492 do_gettimeofday(&vino_drvdata->
2493 b.int_data.timestamp);
2494 vino_drvdata->b.int_data.frame_counter = fc_b;
2495 }
2496 vino_drvdata->b.int_data.skip = skip_b;
2497
2498 dprintk("channel B %s, interrupt: %d\n",
2499 skip_b ? "skipping frame" : "frame done",
2500 intr);
2501 tasklet_hi_schedule(&vino_tasklet_b);
2502 handled_b = 1;
2503 }
2504
2505#ifdef VINO_DEBUG_INT
2506 loop++;
2507#endif
2508 spin_lock(&vino_drvdata->vino_lock);
2509 }
2510
2511 spin_unlock(&vino_drvdata->vino_lock);
2512
2513 return IRQ_HANDLED;
2514}
2515
2516/* VINO video input management */
2517
2518static int vino_get_saa7191_input(int input)
2519{
2520 switch (input) {
2521 case VINO_INPUT_COMPOSITE:
2522 return SAA7191_INPUT_COMPOSITE;
2523 case VINO_INPUT_SVIDEO:
2524 return SAA7191_INPUT_SVIDEO;
2525 default:
2526 printk(KERN_ERR "VINO: vino_get_saa7191_input(): "
2527 "invalid input!\n");
2528 return -1;
2529 }
2530}
2531
2532/* execute with input_lock locked */
2533static int vino_is_input_owner(struct vino_channel_settings *vcs)
2534{
2535 switch(vcs->input) {
2536 case VINO_INPUT_COMPOSITE:
2537 case VINO_INPUT_SVIDEO:
2538 return vino_drvdata->decoder_owner == vcs->channel;
2539 case VINO_INPUT_D1:
2540 return vino_drvdata->camera_owner == vcs->channel;
2541 default:
2542 return 0;
2543 }
2544}
2545
2546static int vino_acquire_input(struct vino_channel_settings *vcs)
2547{
2548 unsigned long flags;
2549 int ret = 0;
2550
2551 dprintk("vino_acquire_input():\n");
2552
2553 spin_lock_irqsave(&vino_drvdata->input_lock, flags);
2554
2555 /* First try D1 and then SAA7191 */
2556 if (vino_drvdata->camera
2557 && (vino_drvdata->camera_owner == VINO_NO_CHANNEL)) {
2558 vino_drvdata->camera_owner = vcs->channel;
2559 vcs->input = VINO_INPUT_D1;
2560 vcs->data_norm = VINO_DATA_NORM_D1;
2561 } else if (vino_drvdata->decoder
2562 && (vino_drvdata->decoder_owner == VINO_NO_CHANNEL)) {
2563 int input;
2564 int data_norm = 0;
2565 v4l2_std_id norm;
2566
2567 input = VINO_INPUT_COMPOSITE;
2568
2569 ret = decoder_call(video, s_routing,
2570 vino_get_saa7191_input(input), 0, 0);
2571 if (ret) {
2572 ret = -EINVAL;
2573 goto out;
2574 }
2575
2576 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
2577
2578 /* Don't hold spinlocks while auto-detecting norm
2579 * as it may take a while... */
2580
2581 ret = decoder_call(video, querystd, &norm);
2582 if (!ret) {
2583 for (data_norm = 0; data_norm < 3; data_norm++) {
2584 if (vino_data_norms[data_norm].std & norm)
2585 break;
2586 }
2587 if (data_norm == 3)
2588 data_norm = VINO_DATA_NORM_PAL;
2589 ret = decoder_call(core, s_std, norm);
2590 }
2591
2592 spin_lock_irqsave(&vino_drvdata->input_lock, flags);
2593
2594 if (ret) {
2595 ret = -EINVAL;
2596 goto out;
2597 }
2598
2599 vino_drvdata->decoder_owner = vcs->channel;
2600
2601 vcs->input = input;
2602 vcs->data_norm = data_norm;
2603 } else {
2604 vcs->input = (vcs->channel == VINO_CHANNEL_A) ?
2605 vino_drvdata->b.input : vino_drvdata->a.input;
2606 vcs->data_norm = (vcs->channel == VINO_CHANNEL_A) ?
2607 vino_drvdata->b.data_norm : vino_drvdata->a.data_norm;
2608 }
2609
2610 if (vcs->input == VINO_INPUT_NONE) {
2611 ret = -ENODEV;
2612 goto out;
2613 }
2614
2615 vino_set_default_clipping(vcs);
2616 vino_set_default_scaling(vcs);
2617 vino_set_default_framerate(vcs);
2618
2619 dprintk("vino_acquire_input(): %s\n", vino_inputs[vcs->input].name);
2620
2621out:
2622 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
2623
2624 return ret;
2625}
2626
2627static int vino_set_input(struct vino_channel_settings *vcs, int input)
2628{
2629 struct vino_channel_settings *vcs2 = (vcs->channel == VINO_CHANNEL_A) ?
2630 &vino_drvdata->b : &vino_drvdata->a;
2631 unsigned long flags;
2632 int ret = 0;
2633
2634 dprintk("vino_set_input():\n");
2635
2636 spin_lock_irqsave(&vino_drvdata->input_lock, flags);
2637
2638 if (vcs->input == input)
2639 goto out;
2640
2641 switch (input) {
2642 case VINO_INPUT_COMPOSITE:
2643 case VINO_INPUT_SVIDEO:
2644 if (!vino_drvdata->decoder) {
2645 ret = -EINVAL;
2646 goto out;
2647 }
2648
2649 if (vino_drvdata->decoder_owner == VINO_NO_CHANNEL) {
2650 vino_drvdata->decoder_owner = vcs->channel;
2651 }
2652
2653 if (vino_drvdata->decoder_owner == vcs->channel) {
2654 int data_norm = 0;
2655 v4l2_std_id norm;
2656
2657 ret = decoder_call(video, s_routing,
2658 vino_get_saa7191_input(input), 0, 0);
2659 if (ret) {
2660 vino_drvdata->decoder_owner = VINO_NO_CHANNEL;
2661 ret = -EINVAL;
2662 goto out;
2663 }
2664
2665 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
2666
2667 /* Don't hold spinlocks while auto-detecting norm
2668 * as it may take a while... */
2669
2670 ret = decoder_call(video, querystd, &norm);
2671 if (!ret) {
2672 for (data_norm = 0; data_norm < 3; data_norm++) {
2673 if (vino_data_norms[data_norm].std & norm)
2674 break;
2675 }
2676 if (data_norm == 3)
2677 data_norm = VINO_DATA_NORM_PAL;
2678 ret = decoder_call(core, s_std, norm);
2679 }
2680
2681 spin_lock_irqsave(&vino_drvdata->input_lock, flags);
2682
2683 if (ret) {
2684 vino_drvdata->decoder_owner = VINO_NO_CHANNEL;
2685 ret = -EINVAL;
2686 goto out;
2687 }
2688
2689 vcs->input = input;
2690 vcs->data_norm = data_norm;
2691 } else {
2692 if (input != vcs2->input) {
2693 ret = -EBUSY;
2694 goto out;
2695 }
2696
2697 vcs->input = input;
2698 vcs->data_norm = vcs2->data_norm;
2699 }
2700
2701 if (vino_drvdata->camera_owner == vcs->channel) {
2702 /* Transfer the ownership or release the input */
2703 if (vcs2->input == VINO_INPUT_D1) {
2704 vino_drvdata->camera_owner = vcs2->channel;
2705 } else {
2706 vino_drvdata->camera_owner = VINO_NO_CHANNEL;
2707 }
2708 }
2709 break;
2710 case VINO_INPUT_D1:
2711 if (!vino_drvdata->camera) {
2712 ret = -EINVAL;
2713 goto out;
2714 }
2715
2716 if (vino_drvdata->camera_owner == VINO_NO_CHANNEL)
2717 vino_drvdata->camera_owner = vcs->channel;
2718
2719 if (vino_drvdata->decoder_owner == vcs->channel) {
2720 /* Transfer the ownership or release the input */
2721 if ((vcs2->input == VINO_INPUT_COMPOSITE) ||
2722 (vcs2->input == VINO_INPUT_SVIDEO)) {
2723 vino_drvdata->decoder_owner = vcs2->channel;
2724 } else {
2725 vino_drvdata->decoder_owner = VINO_NO_CHANNEL;
2726 }
2727 }
2728
2729 vcs->input = input;
2730 vcs->data_norm = VINO_DATA_NORM_D1;
2731 break;
2732 default:
2733 ret = -EINVAL;
2734 goto out;
2735 }
2736
2737 vino_set_default_clipping(vcs);
2738 vino_set_default_scaling(vcs);
2739 vino_set_default_framerate(vcs);
2740
2741 dprintk("vino_set_input(): %s\n", vino_inputs[vcs->input].name);
2742
2743out:
2744 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
2745
2746 return ret;
2747}
2748
2749static void vino_release_input(struct vino_channel_settings *vcs)
2750{
2751 struct vino_channel_settings *vcs2 = (vcs->channel == VINO_CHANNEL_A) ?
2752 &vino_drvdata->b : &vino_drvdata->a;
2753 unsigned long flags;
2754
2755 dprintk("vino_release_input():\n");
2756
2757 spin_lock_irqsave(&vino_drvdata->input_lock, flags);
2758
2759 /* Release ownership of the channel
2760 * and if the other channel takes input from
2761 * the same source, transfer the ownership */
2762 if (vino_drvdata->camera_owner == vcs->channel) {
2763 if (vcs2->input == VINO_INPUT_D1) {
2764 vino_drvdata->camera_owner = vcs2->channel;
2765 } else {
2766 vino_drvdata->camera_owner = VINO_NO_CHANNEL;
2767 }
2768 } else if (vino_drvdata->decoder_owner == vcs->channel) {
2769 if ((vcs2->input == VINO_INPUT_COMPOSITE) ||
2770 (vcs2->input == VINO_INPUT_SVIDEO)) {
2771 vino_drvdata->decoder_owner = vcs2->channel;
2772 } else {
2773 vino_drvdata->decoder_owner = VINO_NO_CHANNEL;
2774 }
2775 }
2776 vcs->input = VINO_INPUT_NONE;
2777
2778 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
2779}
2780
2781/* execute with input_lock locked */
2782static int vino_set_data_norm(struct vino_channel_settings *vcs,
2783 unsigned int data_norm,
2784 unsigned long *flags)
2785{
2786 int err = 0;
2787
2788 if (data_norm == vcs->data_norm)
2789 return 0;
2790
2791 switch (vcs->input) {
2792 case VINO_INPUT_D1:
2793 /* only one "norm" supported */
2794 if (data_norm != VINO_DATA_NORM_D1)
2795 return -EINVAL;
2796 break;
2797 case VINO_INPUT_COMPOSITE:
2798 case VINO_INPUT_SVIDEO: {
2799 v4l2_std_id norm;
2800
2801 if ((data_norm != VINO_DATA_NORM_PAL)
2802 && (data_norm != VINO_DATA_NORM_NTSC)
2803 && (data_norm != VINO_DATA_NORM_SECAM))
2804 return -EINVAL;
2805
2806 spin_unlock_irqrestore(&vino_drvdata->input_lock, *flags);
2807
2808 /* Don't hold spinlocks while setting norm
2809 * as it may take a while... */
2810
2811 norm = vino_data_norms[data_norm].std;
2812 err = decoder_call(core, s_std, norm);
2813
2814 spin_lock_irqsave(&vino_drvdata->input_lock, *flags);
2815
2816 if (err)
2817 goto out;
2818
2819 vcs->data_norm = data_norm;
2820
2821 vino_set_default_clipping(vcs);
2822 vino_set_default_scaling(vcs);
2823 vino_set_default_framerate(vcs);
2824 break;
2825 }
2826 default:
2827 return -EINVAL;
2828 }
2829
2830out:
2831 return err;
2832}
2833
2834/* V4L2 helper functions */
2835
2836static int vino_find_data_format(__u32 pixelformat)
2837{
2838 int i;
2839
2840 for (i = 0; i < VINO_DATA_FMT_COUNT; i++) {
2841 if (vino_data_formats[i].pixelformat == pixelformat)
2842 return i;
2843 }
2844
2845 return VINO_DATA_FMT_NONE;
2846}
2847
2848static int vino_int_enum_input(struct vino_channel_settings *vcs, __u32 index)
2849{
2850 int input = VINO_INPUT_NONE;
2851 unsigned long flags;
2852
2853 spin_lock_irqsave(&vino_drvdata->input_lock, flags);
2854 if (vino_drvdata->decoder && vino_drvdata->camera) {
2855 switch (index) {
2856 case 0:
2857 input = VINO_INPUT_COMPOSITE;
2858 break;
2859 case 1:
2860 input = VINO_INPUT_SVIDEO;
2861 break;
2862 case 2:
2863 input = VINO_INPUT_D1;
2864 break;
2865 }
2866 } else if (vino_drvdata->decoder) {
2867 switch (index) {
2868 case 0:
2869 input = VINO_INPUT_COMPOSITE;
2870 break;
2871 case 1:
2872 input = VINO_INPUT_SVIDEO;
2873 break;
2874 }
2875 } else if (vino_drvdata->camera) {
2876 switch (index) {
2877 case 0:
2878 input = VINO_INPUT_D1;
2879 break;
2880 }
2881 }
2882 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
2883
2884 return input;
2885}
2886
2887/* execute with input_lock locked */
2888static __u32 vino_find_input_index(struct vino_channel_settings *vcs)
2889{
2890 __u32 index = 0;
2891 // FIXME: detect when no inputs available
2892
2893 if (vino_drvdata->decoder && vino_drvdata->camera) {
2894 switch (vcs->input) {
2895 case VINO_INPUT_COMPOSITE:
2896 index = 0;
2897 break;
2898 case VINO_INPUT_SVIDEO:
2899 index = 1;
2900 break;
2901 case VINO_INPUT_D1:
2902 index = 2;
2903 break;
2904 }
2905 } else if (vino_drvdata->decoder) {
2906 switch (vcs->input) {
2907 case VINO_INPUT_COMPOSITE:
2908 index = 0;
2909 break;
2910 case VINO_INPUT_SVIDEO:
2911 index = 1;
2912 break;
2913 }
2914 } else if (vino_drvdata->camera) {
2915 switch (vcs->input) {
2916 case VINO_INPUT_D1:
2917 index = 0;
2918 break;
2919 }
2920 }
2921
2922 return index;
2923}
2924
2925/* V4L2 ioctls */
2926
2927static int vino_querycap(struct file *file, void *__fh,
2928 struct v4l2_capability *cap)
2929{
2930 memset(cap, 0, sizeof(struct v4l2_capability));
2931
2932 strcpy(cap->driver, vino_driver_name);
2933 strcpy(cap->card, vino_driver_description);
2934 strcpy(cap->bus_info, vino_bus_name);
2935 cap->capabilities =
2936 V4L2_CAP_VIDEO_CAPTURE |
2937 V4L2_CAP_STREAMING;
2938 // V4L2_CAP_OVERLAY, V4L2_CAP_READWRITE
2939 return 0;
2940}
2941
2942static int vino_enum_input(struct file *file, void *__fh,
2943 struct v4l2_input *i)
2944{
2945 struct vino_channel_settings *vcs = video_drvdata(file);
2946 __u32 index = i->index;
2947 int input;
2948 dprintk("requested index = %d\n", index);
2949
2950 input = vino_int_enum_input(vcs, index);
2951 if (input == VINO_INPUT_NONE)
2952 return -EINVAL;
2953
2954 i->type = V4L2_INPUT_TYPE_CAMERA;
2955 i->std = vino_inputs[input].std;
2956 strcpy(i->name, vino_inputs[input].name);
2957
2958 if (input == VINO_INPUT_COMPOSITE || input == VINO_INPUT_SVIDEO)
2959 decoder_call(video, g_input_status, &i->status);
2960 return 0;
2961}
2962
2963static int vino_g_input(struct file *file, void *__fh,
2964 unsigned int *i)
2965{
2966 struct vino_channel_settings *vcs = video_drvdata(file);
2967 __u32 index;
2968 int input;
2969 unsigned long flags;
2970
2971 spin_lock_irqsave(&vino_drvdata->input_lock, flags);
2972 input = vcs->input;
2973 index = vino_find_input_index(vcs);
2974 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
2975
2976 dprintk("input = %d\n", input);
2977
2978 if (input == VINO_INPUT_NONE) {
2979 return -EINVAL;
2980 }
2981
2982 *i = index;
2983
2984 return 0;
2985}
2986
2987static int vino_s_input(struct file *file, void *__fh,
2988 unsigned int i)
2989{
2990 struct vino_channel_settings *vcs = video_drvdata(file);
2991 int input;
2992 dprintk("requested input = %d\n", i);
2993
2994 input = vino_int_enum_input(vcs, i);
2995 if (input == VINO_INPUT_NONE)
2996 return -EINVAL;
2997
2998 return vino_set_input(vcs, input);
2999}
3000
3001static int vino_querystd(struct file *file, void *__fh,
3002 v4l2_std_id *std)
3003{
3004 struct vino_channel_settings *vcs = video_drvdata(file);
3005 unsigned long flags;
3006 int err = 0;
3007
3008 spin_lock_irqsave(&vino_drvdata->input_lock, flags);
3009
3010 switch (vcs->input) {
3011 case VINO_INPUT_D1:
3012 *std = vino_inputs[vcs->input].std;
3013 break;
3014 case VINO_INPUT_COMPOSITE:
3015 case VINO_INPUT_SVIDEO: {
3016 decoder_call(video, querystd, std);
3017 break;
3018 }
3019 default:
3020 err = -EINVAL;
3021 }
3022
3023 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
3024
3025 return err;
3026}
3027
3028static int vino_g_std(struct file *file, void *__fh,
3029 v4l2_std_id *std)
3030{
3031 struct vino_channel_settings *vcs = video_drvdata(file);
3032 unsigned long flags;
3033
3034 spin_lock_irqsave(&vino_drvdata->input_lock, flags);
3035
3036 *std = vino_data_norms[vcs->data_norm].std;
3037 dprintk("current standard = %d\n", vcs->data_norm);
3038
3039 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
3040
3041 return 0;
3042}
3043
3044static int vino_s_std(struct file *file, void *__fh,
3045 v4l2_std_id *std)
3046{
3047 struct vino_channel_settings *vcs = video_drvdata(file);
3048 unsigned long flags;
3049 int ret = 0;
3050
3051 spin_lock_irqsave(&vino_drvdata->input_lock, flags);
3052
3053 if (!vino_is_input_owner(vcs)) {
3054 ret = -EBUSY;
3055 goto out;
3056 }
3057
3058 /* check if the standard is valid for the current input */
3059 if ((*std) & vino_inputs[vcs->input].std) {
3060 dprintk("standard accepted\n");
3061
3062 /* change the video norm for SAA7191
3063 * and accept NTSC for D1 (do nothing) */
3064
3065 if (vcs->input == VINO_INPUT_D1)
3066 goto out;
3067
3068 if ((*std) & V4L2_STD_PAL) {
3069 ret = vino_set_data_norm(vcs, VINO_DATA_NORM_PAL,
3070 &flags);
3071 } else if ((*std) & V4L2_STD_NTSC) {
3072 ret = vino_set_data_norm(vcs, VINO_DATA_NORM_NTSC,
3073 &flags);
3074 } else if ((*std) & V4L2_STD_SECAM) {
3075 ret = vino_set_data_norm(vcs, VINO_DATA_NORM_SECAM,
3076 &flags);
3077 } else {
3078 ret = -EINVAL;
3079 }
3080
3081 if (ret) {
3082 ret = -EINVAL;
3083 }
3084 } else {
3085 ret = -EINVAL;
3086 }
3087
3088out:
3089 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
3090
3091 return ret;
3092}
3093
3094static int vino_enum_fmt_vid_cap(struct file *file, void *__fh,
3095 struct v4l2_fmtdesc *fd)
3096{
3097 dprintk("format index = %d\n", fd->index);
3098
3099 if (fd->index >= VINO_DATA_FMT_COUNT)
3100 return -EINVAL;
3101 dprintk("format name = %s\n", vino_data_formats[fd->index].description);
3102
3103 fd->pixelformat = vino_data_formats[fd->index].pixelformat;
3104 strcpy(fd->description, vino_data_formats[fd->index].description);
3105 return 0;
3106}
3107
3108static int vino_try_fmt_vid_cap(struct file *file, void *__fh,
3109 struct v4l2_format *f)
3110{
3111 struct vino_channel_settings *vcs = video_drvdata(file);
3112 struct vino_channel_settings tempvcs;
3113 unsigned long flags;
3114 struct v4l2_pix_format *pf = &f->fmt.pix;
3115
3116 dprintk("requested: w = %d, h = %d\n",
3117 pf->width, pf->height);
3118
3119 spin_lock_irqsave(&vino_drvdata->input_lock, flags);
3120 memcpy(&tempvcs, vcs, sizeof(struct vino_channel_settings));
3121 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
3122
3123 tempvcs.data_format = vino_find_data_format(pf->pixelformat);
3124 if (tempvcs.data_format == VINO_DATA_FMT_NONE) {
3125 tempvcs.data_format = VINO_DATA_FMT_GREY;
3126 pf->pixelformat =
3127 vino_data_formats[tempvcs.data_format].
3128 pixelformat;
3129 }
3130
3131 /* data format must be set before clipping/scaling */
3132 vino_set_scaling(&tempvcs, pf->width, pf->height);
3133
3134 dprintk("data format = %s\n",
3135 vino_data_formats[tempvcs.data_format].description);
3136
3137 pf->width = (tempvcs.clipping.right - tempvcs.clipping.left) /
3138 tempvcs.decimation;
3139 pf->height = (tempvcs.clipping.bottom - tempvcs.clipping.top) /
3140 tempvcs.decimation;
3141
3142 pf->field = V4L2_FIELD_INTERLACED;
3143 pf->bytesperline = tempvcs.line_size;
3144 pf->sizeimage = tempvcs.line_size *
3145 (tempvcs.clipping.bottom - tempvcs.clipping.top) /
3146 tempvcs.decimation;
3147 pf->colorspace =
3148 vino_data_formats[tempvcs.data_format].colorspace;
3149
3150 pf->priv = 0;
3151 return 0;
3152}
3153
3154static int vino_g_fmt_vid_cap(struct file *file, void *__fh,
3155 struct v4l2_format *f)
3156{
3157 struct vino_channel_settings *vcs = video_drvdata(file);
3158 unsigned long flags;
3159 struct v4l2_pix_format *pf = &f->fmt.pix;
3160
3161 spin_lock_irqsave(&vino_drvdata->input_lock, flags);
3162
3163 pf->width = (vcs->clipping.right - vcs->clipping.left) /
3164 vcs->decimation;
3165 pf->height = (vcs->clipping.bottom - vcs->clipping.top) /
3166 vcs->decimation;
3167 pf->pixelformat =
3168 vino_data_formats[vcs->data_format].pixelformat;
3169
3170 pf->field = V4L2_FIELD_INTERLACED;
3171 pf->bytesperline = vcs->line_size;
3172 pf->sizeimage = vcs->line_size *
3173 (vcs->clipping.bottom - vcs->clipping.top) /
3174 vcs->decimation;
3175 pf->colorspace =
3176 vino_data_formats[vcs->data_format].colorspace;
3177
3178 pf->priv = 0;
3179
3180 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
3181 return 0;
3182}
3183
3184static int vino_s_fmt_vid_cap(struct file *file, void *__fh,
3185 struct v4l2_format *f)
3186{
3187 struct vino_channel_settings *vcs = video_drvdata(file);
3188 int data_format;
3189 unsigned long flags;
3190 struct v4l2_pix_format *pf = &f->fmt.pix;
3191
3192 spin_lock_irqsave(&vino_drvdata->input_lock, flags);
3193
3194 data_format = vino_find_data_format(pf->pixelformat);
3195
3196 if (data_format == VINO_DATA_FMT_NONE) {
3197 vcs->data_format = VINO_DATA_FMT_GREY;
3198 pf->pixelformat =
3199 vino_data_formats[vcs->data_format].
3200 pixelformat;
3201 } else {
3202 vcs->data_format = data_format;
3203 }
3204
3205 /* data format must be set before clipping/scaling */
3206 vino_set_scaling(vcs, pf->width, pf->height);
3207
3208 dprintk("data format = %s\n",
3209 vino_data_formats[vcs->data_format].description);
3210
3211 pf->width = vcs->clipping.right - vcs->clipping.left;
3212 pf->height = vcs->clipping.bottom - vcs->clipping.top;
3213
3214 pf->field = V4L2_FIELD_INTERLACED;
3215 pf->bytesperline = vcs->line_size;
3216 pf->sizeimage = vcs->line_size *
3217 (vcs->clipping.bottom - vcs->clipping.top) /
3218 vcs->decimation;
3219 pf->colorspace =
3220 vino_data_formats[vcs->data_format].colorspace;
3221
3222 pf->priv = 0;
3223
3224 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
3225 return 0;
3226}
3227
3228static int vino_cropcap(struct file *file, void *__fh,
3229 struct v4l2_cropcap *ccap)
3230{
3231 struct vino_channel_settings *vcs = video_drvdata(file);
3232 const struct vino_data_norm *norm;
3233 unsigned long flags;
3234
3235 switch (ccap->type) {
3236 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
3237 spin_lock_irqsave(&vino_drvdata->input_lock, flags);
3238
3239 norm = &vino_data_norms[vcs->data_norm];
3240
3241 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
3242
3243 ccap->bounds.left = 0;
3244 ccap->bounds.top = 0;
3245 ccap->bounds.width = norm->width;
3246 ccap->bounds.height = norm->height;
3247 memcpy(&ccap->defrect, &ccap->bounds,
3248 sizeof(struct v4l2_rect));
3249
3250 ccap->pixelaspect.numerator = 1;
3251 ccap->pixelaspect.denominator = 1;
3252 break;
3253 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3254 default:
3255 return -EINVAL;
3256 }
3257
3258 return 0;
3259}
3260
3261static int vino_g_crop(struct file *file, void *__fh,
3262 struct v4l2_crop *c)
3263{
3264 struct vino_channel_settings *vcs = video_drvdata(file);
3265 unsigned long flags;
3266
3267 switch (c->type) {
3268 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
3269 spin_lock_irqsave(&vino_drvdata->input_lock, flags);
3270
3271 c->c.left = vcs->clipping.left;
3272 c->c.top = vcs->clipping.top;
3273 c->c.width = vcs->clipping.right - vcs->clipping.left;
3274 c->c.height = vcs->clipping.bottom - vcs->clipping.top;
3275
3276 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
3277 break;
3278 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3279 default:
3280 return -EINVAL;
3281 }
3282
3283 return 0;
3284}
3285
3286static int vino_s_crop(struct file *file, void *__fh,
3287 struct v4l2_crop *c)
3288{
3289 struct vino_channel_settings *vcs = video_drvdata(file);
3290 unsigned long flags;
3291
3292 switch (c->type) {
3293 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
3294 spin_lock_irqsave(&vino_drvdata->input_lock, flags);
3295
3296 vino_set_clipping(vcs, c->c.left, c->c.top,
3297 c->c.width, c->c.height);
3298
3299 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
3300 break;
3301 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3302 default:
3303 return -EINVAL;
3304 }
3305
3306 return 0;
3307}
3308
3309static int vino_g_parm(struct file *file, void *__fh,
3310 struct v4l2_streamparm *sp)
3311{
3312 struct vino_channel_settings *vcs = video_drvdata(file);
3313 unsigned long flags;
3314 struct v4l2_captureparm *cp = &sp->parm.capture;
3315
3316 cp->capability = V4L2_CAP_TIMEPERFRAME;
3317 cp->timeperframe.numerator = 1;
3318
3319 spin_lock_irqsave(&vino_drvdata->input_lock, flags);
3320
3321 cp->timeperframe.denominator = vcs->fps;
3322
3323 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
3324
3325 /* TODO: cp->readbuffers = xxx; */
3326
3327 return 0;
3328}
3329
3330static int vino_s_parm(struct file *file, void *__fh,
3331 struct v4l2_streamparm *sp)
3332{
3333 struct vino_channel_settings *vcs = video_drvdata(file);
3334 unsigned long flags;
3335 struct v4l2_captureparm *cp = &sp->parm.capture;
3336
3337 spin_lock_irqsave(&vino_drvdata->input_lock, flags);
3338
3339 if ((cp->timeperframe.numerator == 0) ||
3340 (cp->timeperframe.denominator == 0)) {
3341 /* reset framerate */
3342 vino_set_default_framerate(vcs);
3343 } else {
3344 vino_set_framerate(vcs, cp->timeperframe.denominator /
3345 cp->timeperframe.numerator);
3346 }
3347
3348 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
3349
3350 return 0;
3351}
3352
3353static int vino_reqbufs(struct file *file, void *__fh,
3354 struct v4l2_requestbuffers *rb)
3355{
3356 struct vino_channel_settings *vcs = video_drvdata(file);
3357
3358 if (vcs->reading)
3359 return -EBUSY;
3360
3361 /* TODO: check queue type */
3362 if (rb->memory != V4L2_MEMORY_MMAP) {
3363 dprintk("type not mmap\n");
3364 return -EINVAL;
3365 }
3366
3367 dprintk("count = %d\n", rb->count);
3368 if (rb->count > 0) {
3369 if (vino_is_capturing(vcs)) {
3370 dprintk("busy, capturing\n");
3371 return -EBUSY;
3372 }
3373
3374 if (vino_queue_has_mapped_buffers(&vcs->fb_queue)) {
3375 dprintk("busy, buffers still mapped\n");
3376 return -EBUSY;
3377 } else {
3378 vcs->streaming = 0;
3379 vino_queue_free(&vcs->fb_queue);
3380 vino_queue_init(&vcs->fb_queue, &rb->count);
3381 }
3382 } else {
3383 vcs->streaming = 0;
3384 vino_capture_stop(vcs);
3385 vino_queue_free(&vcs->fb_queue);
3386 }
3387
3388 return 0;
3389}
3390
3391static void vino_v4l2_get_buffer_status(struct vino_channel_settings *vcs,
3392 struct vino_framebuffer *fb,
3393 struct v4l2_buffer *b)
3394{
3395 if (vino_queue_outgoing_contains(&vcs->fb_queue,
3396 fb->id)) {
3397 b->flags &= ~V4L2_BUF_FLAG_QUEUED;
3398 b->flags |= V4L2_BUF_FLAG_DONE;
3399 } else if (vino_queue_incoming_contains(&vcs->fb_queue,
3400 fb->id)) {
3401 b->flags &= ~V4L2_BUF_FLAG_DONE;
3402 b->flags |= V4L2_BUF_FLAG_QUEUED;
3403 } else {
3404 b->flags &= ~(V4L2_BUF_FLAG_DONE |
3405 V4L2_BUF_FLAG_QUEUED);
3406 }
3407
3408 b->flags &= ~(V4L2_BUF_FLAG_TIMECODE);
3409
3410 if (fb->map_count > 0)
3411 b->flags |= V4L2_BUF_FLAG_MAPPED;
3412
3413 b->index = fb->id;
3414 b->memory = (vcs->fb_queue.type == VINO_MEMORY_MMAP) ?
3415 V4L2_MEMORY_MMAP : V4L2_MEMORY_USERPTR;
3416 b->m.offset = fb->offset;
3417 b->bytesused = fb->data_size;
3418 b->length = fb->size;
3419 b->field = V4L2_FIELD_INTERLACED;
3420 b->sequence = fb->frame_counter;
3421 memcpy(&b->timestamp, &fb->timestamp,
3422 sizeof(struct timeval));
3423 // b->input ?
3424
3425 dprintk("buffer %d: length = %d, bytesused = %d, offset = %d\n",
3426 fb->id, fb->size, fb->data_size, fb->offset);
3427}
3428
3429static int vino_querybuf(struct file *file, void *__fh,
3430 struct v4l2_buffer *b)
3431{
3432 struct vino_channel_settings *vcs = video_drvdata(file);
3433 struct vino_framebuffer *fb;
3434
3435 if (vcs->reading)
3436 return -EBUSY;
3437
3438 /* TODO: check queue type */
3439 if (b->index >= vino_queue_get_length(&vcs->fb_queue)) {
3440 dprintk("invalid index = %d\n",
3441 b->index);
3442 return -EINVAL;
3443 }
3444
3445 fb = vino_queue_get_buffer(&vcs->fb_queue,
3446 b->index);
3447 if (fb == NULL) {
3448 dprintk("vino_queue_get_buffer() failed");
3449 return -EINVAL;
3450 }
3451
3452 vino_v4l2_get_buffer_status(vcs, fb, b);
3453
3454 return 0;
3455}
3456
3457static int vino_qbuf(struct file *file, void *__fh,
3458 struct v4l2_buffer *b)
3459{
3460 struct vino_channel_settings *vcs = video_drvdata(file);
3461 struct vino_framebuffer *fb;
3462 int ret;
3463
3464 if (vcs->reading)
3465 return -EBUSY;
3466
3467 /* TODO: check queue type */
3468 if (b->memory != V4L2_MEMORY_MMAP) {
3469 dprintk("type not mmap\n");
3470 return -EINVAL;
3471 }
3472
3473 fb = vino_capture_enqueue(vcs, b->index);
3474 if (fb == NULL)
3475 return -EINVAL;
3476
3477 vino_v4l2_get_buffer_status(vcs, fb, b);
3478
3479 if (vcs->streaming) {
3480 ret = vino_capture_next(vcs, 1);
3481 if (ret)
3482 return ret;
3483 }
3484
3485 return 0;
3486}
3487
3488static int vino_dqbuf(struct file *file, void *__fh,
3489 struct v4l2_buffer *b)
3490{
3491 struct vino_channel_settings *vcs = video_drvdata(file);
3492 unsigned int nonblocking = file->f_flags & O_NONBLOCK;
3493 struct vino_framebuffer *fb;
3494 unsigned int incoming, outgoing;
3495 int err;
3496
3497 if (vcs->reading)
3498 return -EBUSY;
3499
3500 /* TODO: check queue type */
3501
3502 err = vino_queue_get_incoming(&vcs->fb_queue, &incoming);
3503 if (err) {
3504 dprintk("vino_queue_get_incoming() failed\n");
3505 return -EINVAL;
3506 }
3507 err = vino_queue_get_outgoing(&vcs->fb_queue, &outgoing);
3508 if (err) {
3509 dprintk("vino_queue_get_outgoing() failed\n");
3510 return -EINVAL;
3511 }
3512
3513 dprintk("incoming = %d, outgoing = %d\n", incoming, outgoing);
3514
3515 if (outgoing == 0) {
3516 if (incoming == 0) {
3517 dprintk("no incoming or outgoing buffers\n");
3518 return -EINVAL;
3519 }
3520 if (nonblocking) {
3521 dprintk("non-blocking I/O was selected and "
3522 "there are no buffers to dequeue\n");
3523 return -EAGAIN;
3524 }
3525
3526 err = vino_wait_for_frame(vcs);
3527 if (err) {
3528 err = vino_wait_for_frame(vcs);
3529 if (err) {
3530 /* interrupted or no frames captured because of
3531 * frame skipping */
3532 /* vino_capture_failed(vcs); */
3533 return -EIO;
3534 }
3535 }
3536 }
3537
3538 fb = vino_queue_remove(&vcs->fb_queue, &b->index);
3539 if (fb == NULL) {
3540 dprintk("vino_queue_remove() failed\n");
3541 return -EINVAL;
3542 }
3543
3544 err = vino_check_buffer(vcs, fb);
3545
3546 vino_v4l2_get_buffer_status(vcs, fb, b);
3547
3548 if (err)
3549 return -EIO;
3550
3551 return 0;
3552}
3553
3554static int vino_streamon(struct file *file, void *__fh,
3555 enum v4l2_buf_type i)
3556{
3557 struct vino_channel_settings *vcs = video_drvdata(file);
3558 unsigned int incoming;
3559 int ret;
3560 if (vcs->reading)
3561 return -EBUSY;
3562
3563 if (vcs->streaming)
3564 return 0;
3565
3566 // TODO: check queue type
3567
3568 if (vino_queue_get_length(&vcs->fb_queue) < 1) {
3569 dprintk("no buffers allocated\n");
3570 return -EINVAL;
3571 }
3572
3573 ret = vino_queue_get_incoming(&vcs->fb_queue, &incoming);
3574 if (ret) {
3575 dprintk("vino_queue_get_incoming() failed\n");
3576 return -EINVAL;
3577 }
3578
3579 vcs->streaming = 1;
3580
3581 if (incoming > 0) {
3582 ret = vino_capture_next(vcs, 1);
3583 if (ret) {
3584 vcs->streaming = 0;
3585
3586 dprintk("couldn't start capture\n");
3587 return -EINVAL;
3588 }
3589 }
3590
3591 return 0;
3592}
3593
3594static int vino_streamoff(struct file *file, void *__fh,
3595 enum v4l2_buf_type i)
3596{
3597 struct vino_channel_settings *vcs = video_drvdata(file);
3598 if (vcs->reading)
3599 return -EBUSY;
3600
3601 if (!vcs->streaming)
3602 return 0;
3603
3604 vcs->streaming = 0;
3605 vino_capture_stop(vcs);
3606
3607 return 0;
3608}
3609
3610static int vino_queryctrl(struct file *file, void *__fh,
3611 struct v4l2_queryctrl *queryctrl)
3612{
3613 struct vino_channel_settings *vcs = video_drvdata(file);
3614 unsigned long flags;
3615 int i;
3616 int err = 0;
3617
3618 spin_lock_irqsave(&vino_drvdata->input_lock, flags);
3619
3620 switch (vcs->input) {
3621 case VINO_INPUT_D1:
3622 for (i = 0; i < VINO_INDYCAM_V4L2_CONTROL_COUNT; i++) {
3623 if (vino_indycam_v4l2_controls[i].id ==
3624 queryctrl->id) {
3625 memcpy(queryctrl,
3626 &vino_indycam_v4l2_controls[i],
3627 sizeof(struct v4l2_queryctrl));
3628 queryctrl->reserved[0] = 0;
3629 goto found;
3630 }
3631 }
3632
3633 err = -EINVAL;
3634 break;
3635 case VINO_INPUT_COMPOSITE:
3636 case VINO_INPUT_SVIDEO:
3637 for (i = 0; i < VINO_SAA7191_V4L2_CONTROL_COUNT; i++) {
3638 if (vino_saa7191_v4l2_controls[i].id ==
3639 queryctrl->id) {
3640 memcpy(queryctrl,
3641 &vino_saa7191_v4l2_controls[i],
3642 sizeof(struct v4l2_queryctrl));
3643 queryctrl->reserved[0] = 0;
3644 goto found;
3645 }
3646 }
3647
3648 err = -EINVAL;
3649 break;
3650 default:
3651 err = -EINVAL;
3652 }
3653
3654 found:
3655 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
3656
3657 return err;
3658}
3659
3660static int vino_g_ctrl(struct file *file, void *__fh,
3661 struct v4l2_control *control)
3662{
3663 struct vino_channel_settings *vcs = video_drvdata(file);
3664 unsigned long flags;
3665 int i;
3666 int err = 0;
3667
3668 spin_lock_irqsave(&vino_drvdata->input_lock, flags);
3669
3670 switch (vcs->input) {
3671 case VINO_INPUT_D1: {
3672 err = -EINVAL;
3673 for (i = 0; i < VINO_INDYCAM_V4L2_CONTROL_COUNT; i++) {
3674 if (vino_indycam_v4l2_controls[i].id == control->id) {
3675 err = 0;
3676 break;
3677 }
3678 }
3679
3680 if (err)
3681 goto out;
3682
3683 err = camera_call(core, g_ctrl, control);
3684 if (err)
3685 err = -EINVAL;
3686 break;
3687 }
3688 case VINO_INPUT_COMPOSITE:
3689 case VINO_INPUT_SVIDEO: {
3690 err = -EINVAL;
3691 for (i = 0; i < VINO_SAA7191_V4L2_CONTROL_COUNT; i++) {
3692 if (vino_saa7191_v4l2_controls[i].id == control->id) {
3693 err = 0;
3694 break;
3695 }
3696 }
3697
3698 if (err)
3699 goto out;
3700
3701 err = decoder_call(core, g_ctrl, control);
3702 if (err)
3703 err = -EINVAL;
3704 break;
3705 }
3706 default:
3707 err = -EINVAL;
3708 }
3709
3710out:
3711 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
3712
3713 return err;
3714}
3715
3716static int vino_s_ctrl(struct file *file, void *__fh,
3717 struct v4l2_control *control)
3718{
3719 struct vino_channel_settings *vcs = video_drvdata(file);
3720 unsigned long flags;
3721 int i;
3722 int err = 0;
3723
3724 spin_lock_irqsave(&vino_drvdata->input_lock, flags);
3725
3726 if (!vino_is_input_owner(vcs)) {
3727 err = -EBUSY;
3728 goto out;
3729 }
3730
3731 switch (vcs->input) {
3732 case VINO_INPUT_D1: {
3733 err = -EINVAL;
3734 for (i = 0; i < VINO_INDYCAM_V4L2_CONTROL_COUNT; i++) {
3735 if (vino_indycam_v4l2_controls[i].id == control->id) {
3736 err = 0;
3737 break;
3738 }
3739 }
3740 if (err)
3741 goto out;
3742 if (control->value < vino_indycam_v4l2_controls[i].minimum ||
3743 control->value > vino_indycam_v4l2_controls[i].maximum) {
3744 err = -ERANGE;
3745 goto out;
3746 }
3747 err = camera_call(core, s_ctrl, control);
3748 if (err)
3749 err = -EINVAL;
3750 break;
3751 }
3752 case VINO_INPUT_COMPOSITE:
3753 case VINO_INPUT_SVIDEO: {
3754 err = -EINVAL;
3755 for (i = 0; i < VINO_SAA7191_V4L2_CONTROL_COUNT; i++) {
3756 if (vino_saa7191_v4l2_controls[i].id == control->id) {
3757 err = 0;
3758 break;
3759 }
3760 }
3761 if (err)
3762 goto out;
3763 if (control->value < vino_saa7191_v4l2_controls[i].minimum ||
3764 control->value > vino_saa7191_v4l2_controls[i].maximum) {
3765 err = -ERANGE;
3766 goto out;
3767 }
3768
3769 err = decoder_call(core, s_ctrl, control);
3770 if (err)
3771 err = -EINVAL;
3772 break;
3773 }
3774 default:
3775 err = -EINVAL;
3776 }
3777
3778out:
3779 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
3780
3781 return err;
3782}
3783
3784/* File operations */
3785
3786static int vino_open(struct file *file)
3787{
3788 struct vino_channel_settings *vcs = video_drvdata(file);
3789 int ret = 0;
3790 dprintk("open(): channel = %c\n",
3791 (vcs->channel == VINO_CHANNEL_A) ? 'A' : 'B');
3792
3793 mutex_lock(&vcs->mutex);
3794
3795 if (vcs->users) {
3796 dprintk("open(): driver busy\n");
3797 ret = -EBUSY;
3798 goto out;
3799 }
3800
3801 ret = vino_acquire_input(vcs);
3802 if (ret) {
3803 dprintk("open(): vino_acquire_input() failed\n");
3804 goto out;
3805 }
3806
3807 vcs->users++;
3808
3809 out:
3810 mutex_unlock(&vcs->mutex);
3811
3812 dprintk("open(): %s!\n", ret ? "failed" : "complete");
3813
3814 return ret;
3815}
3816
3817static int vino_close(struct file *file)
3818{
3819 struct vino_channel_settings *vcs = video_drvdata(file);
3820 dprintk("close():\n");
3821
3822 mutex_lock(&vcs->mutex);
3823
3824 vcs->users--;
3825
3826 if (!vcs->users) {
3827 vino_release_input(vcs);
3828
3829 /* stop DMA and free buffers */
3830 vino_capture_stop(vcs);
3831 vino_queue_free(&vcs->fb_queue);
3832 }
3833
3834 mutex_unlock(&vcs->mutex);
3835
3836 return 0;
3837}
3838
3839static void vino_vm_open(struct vm_area_struct *vma)
3840{
3841 struct vino_framebuffer *fb = vma->vm_private_data;
3842
3843 fb->map_count++;
3844 dprintk("vino_vm_open(): count = %d\n", fb->map_count);
3845}
3846
3847static void vino_vm_close(struct vm_area_struct *vma)
3848{
3849 struct vino_framebuffer *fb = vma->vm_private_data;
3850
3851 fb->map_count--;
3852 dprintk("vino_vm_close(): count = %d\n", fb->map_count);
3853}
3854
3855static const struct vm_operations_struct vino_vm_ops = {
3856 .open = vino_vm_open,
3857 .close = vino_vm_close,
3858};
3859
3860static int vino_mmap(struct file *file, struct vm_area_struct *vma)
3861{
3862 struct vino_channel_settings *vcs = video_drvdata(file);
3863
3864 unsigned long start = vma->vm_start;
3865 unsigned long size = vma->vm_end - vma->vm_start;
3866 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
3867
3868 struct vino_framebuffer *fb = NULL;
3869 unsigned int i, length;
3870 int ret = 0;
3871
3872 dprintk("mmap():\n");
3873
3874 // TODO: reject mmap if already mapped
3875
3876 if (mutex_lock_interruptible(&vcs->mutex))
3877 return -EINTR;
3878
3879 if (vcs->reading) {
3880 ret = -EBUSY;
3881 goto out;
3882 }
3883
3884 // TODO: check queue type
3885
3886 if (!(vma->vm_flags & VM_WRITE)) {
3887 dprintk("mmap(): app bug: PROT_WRITE please\n");
3888 ret = -EINVAL;
3889 goto out;
3890 }
3891 if (!(vma->vm_flags & VM_SHARED)) {
3892 dprintk("mmap(): app bug: MAP_SHARED please\n");
3893 ret = -EINVAL;
3894 goto out;
3895 }
3896
3897 /* find the correct buffer using offset */
3898 length = vino_queue_get_length(&vcs->fb_queue);
3899 if (length == 0) {
3900 dprintk("mmap(): queue not initialized\n");
3901 ret = -EINVAL;
3902 goto out;
3903 }
3904
3905 for (i = 0; i < length; i++) {
3906 fb = vino_queue_get_buffer(&vcs->fb_queue, i);
3907 if (fb == NULL) {
3908 dprintk("mmap(): vino_queue_get_buffer() failed\n");
3909 ret = -EINVAL;
3910 goto out;
3911 }
3912
3913 if (fb->offset == offset)
3914 goto found;
3915 }
3916
3917 dprintk("mmap(): invalid offset = %lu\n", offset);
3918 ret = -EINVAL;
3919 goto out;
3920
3921found:
3922 dprintk("mmap(): buffer = %d\n", i);
3923
3924 if (size > (fb->desc_table.page_count * PAGE_SIZE)) {
3925 dprintk("mmap(): failed: size = %lu > %lu\n",
3926 size, fb->desc_table.page_count * PAGE_SIZE);
3927 ret = -EINVAL;
3928 goto out;
3929 }
3930
3931 for (i = 0; i < fb->desc_table.page_count; i++) {
3932 unsigned long pfn =
3933 virt_to_phys((void *)fb->desc_table.virtual[i]) >>
3934 PAGE_SHIFT;
3935
3936 if (size < PAGE_SIZE)
3937 break;
3938
3939 // protection was: PAGE_READONLY
3940 if (remap_pfn_range(vma, start, pfn, PAGE_SIZE,
3941 vma->vm_page_prot)) {
3942 dprintk("mmap(): remap_pfn_range() failed\n");
3943 ret = -EAGAIN;
3944 goto out;
3945 }
3946
3947 start += PAGE_SIZE;
3948 size -= PAGE_SIZE;
3949 }
3950
3951 fb->map_count = 1;
3952
3953 vma->vm_flags |= VM_DONTEXPAND | VM_RESERVED;
3954 vma->vm_flags &= ~VM_IO;
3955 vma->vm_private_data = fb;
3956 vma->vm_file = file;
3957 vma->vm_ops = &vino_vm_ops;
3958
3959out:
3960 mutex_unlock(&vcs->mutex);
3961
3962 return ret;
3963}
3964
3965static unsigned int vino_poll(struct file *file, poll_table *pt)
3966{
3967 struct vino_channel_settings *vcs = video_drvdata(file);
3968 unsigned int outgoing;
3969 unsigned int ret = 0;
3970
3971 // lock mutex (?)
3972 // TODO: this has to be corrected for different read modes
3973
3974 dprintk("poll():\n");
3975
3976 if (vino_queue_get_outgoing(&vcs->fb_queue, &outgoing)) {
3977 dprintk("poll(): vino_queue_get_outgoing() failed\n");
3978 ret = POLLERR;
3979 goto error;
3980 }
3981 if (outgoing > 0)
3982 goto over;
3983
3984 poll_wait(file, &vcs->fb_queue.frame_wait_queue, pt);
3985
3986 if (vino_queue_get_outgoing(&vcs->fb_queue, &outgoing)) {
3987 dprintk("poll(): vino_queue_get_outgoing() failed\n");
3988 ret = POLLERR;
3989 goto error;
3990 }
3991
3992over:
3993 dprintk("poll(): data %savailable\n",
3994 (outgoing > 0) ? "" : "not ");
3995
3996 if (outgoing > 0)
3997 ret = POLLIN | POLLRDNORM;
3998
3999error:
4000 return ret;
4001}
4002
4003static long vino_ioctl(struct file *file,
4004 unsigned int cmd, unsigned long arg)
4005{
4006 struct vino_channel_settings *vcs = video_drvdata(file);
4007 long ret;
4008
4009 if (mutex_lock_interruptible(&vcs->mutex))
4010 return -EINTR;
4011
4012 ret = video_ioctl2(file, cmd, arg);
4013
4014 mutex_unlock(&vcs->mutex);
4015
4016 return ret;
4017}
4018
4019/* Initialization and cleanup */
4020
4021/* __initdata */
4022static int vino_init_stage;
4023
4024const struct v4l2_ioctl_ops vino_ioctl_ops = {
4025 .vidioc_enum_fmt_vid_cap = vino_enum_fmt_vid_cap,
4026 .vidioc_g_fmt_vid_cap = vino_g_fmt_vid_cap,
4027 .vidioc_s_fmt_vid_cap = vino_s_fmt_vid_cap,
4028 .vidioc_try_fmt_vid_cap = vino_try_fmt_vid_cap,
4029 .vidioc_querycap = vino_querycap,
4030 .vidioc_enum_input = vino_enum_input,
4031 .vidioc_g_input = vino_g_input,
4032 .vidioc_s_input = vino_s_input,
4033 .vidioc_g_std = vino_g_std,
4034 .vidioc_s_std = vino_s_std,
4035 .vidioc_querystd = vino_querystd,
4036 .vidioc_cropcap = vino_cropcap,
4037 .vidioc_s_crop = vino_s_crop,
4038 .vidioc_g_crop = vino_g_crop,
4039 .vidioc_s_parm = vino_s_parm,
4040 .vidioc_g_parm = vino_g_parm,
4041 .vidioc_reqbufs = vino_reqbufs,
4042 .vidioc_querybuf = vino_querybuf,
4043 .vidioc_qbuf = vino_qbuf,
4044 .vidioc_dqbuf = vino_dqbuf,
4045 .vidioc_streamon = vino_streamon,
4046 .vidioc_streamoff = vino_streamoff,
4047 .vidioc_queryctrl = vino_queryctrl,
4048 .vidioc_g_ctrl = vino_g_ctrl,
4049 .vidioc_s_ctrl = vino_s_ctrl,
4050};
4051
4052static const struct v4l2_file_operations vino_fops = {
4053 .owner = THIS_MODULE,
4054 .open = vino_open,
4055 .release = vino_close,
4056 .unlocked_ioctl = vino_ioctl,
4057 .mmap = vino_mmap,
4058 .poll = vino_poll,
4059};
4060
4061static struct video_device vdev_template = {
4062 .name = "NOT SET",
4063 .fops = &vino_fops,
4064 .ioctl_ops = &vino_ioctl_ops,
4065 .tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM,
4066};
4067
4068static void vino_module_cleanup(int stage)
4069{
4070 switch(stage) {
4071 case 11:
4072 video_unregister_device(vino_drvdata->b.vdev);
4073 vino_drvdata->b.vdev = NULL;
4074 case 10:
4075 video_unregister_device(vino_drvdata->a.vdev);
4076 vino_drvdata->a.vdev = NULL;
4077 case 9:
4078 i2c_del_adapter(&vino_i2c_adapter);
4079 case 8:
4080 free_irq(SGI_VINO_IRQ, NULL);
4081 case 7:
4082 if (vino_drvdata->b.vdev) {
4083 video_device_release(vino_drvdata->b.vdev);
4084 vino_drvdata->b.vdev = NULL;
4085 }
4086 case 6:
4087 if (vino_drvdata->a.vdev) {
4088 video_device_release(vino_drvdata->a.vdev);
4089 vino_drvdata->a.vdev = NULL;
4090 }
4091 case 5:
4092 /* all entries in dma_cpu dummy table have the same address */
4093 dma_unmap_single(NULL,
4094 vino_drvdata->dummy_desc_table.dma_cpu[0],
4095 PAGE_SIZE, DMA_FROM_DEVICE);
4096 dma_free_coherent(NULL, VINO_DUMMY_DESC_COUNT
4097 * sizeof(dma_addr_t),
4098 (void *)vino_drvdata->
4099 dummy_desc_table.dma_cpu,
4100 vino_drvdata->dummy_desc_table.dma);
4101 case 4:
4102 free_page(vino_drvdata->dummy_page);
4103 case 3:
4104 v4l2_device_unregister(&vino_drvdata->v4l2_dev);
4105 case 2:
4106 kfree(vino_drvdata);
4107 case 1:
4108 iounmap(vino);
4109 case 0:
4110 break;
4111 default:
4112 dprintk("vino_module_cleanup(): invalid cleanup stage = %d\n",
4113 stage);
4114 }
4115}
4116
4117static int vino_probe(void)
4118{
4119 unsigned long rev_id;
4120
4121 if (ip22_is_fullhouse()) {
4122 printk(KERN_ERR "VINO doesn't exist in IP22 Fullhouse\n");
4123 return -ENODEV;
4124 }
4125
4126 if (!(sgimc->systemid & SGIMC_SYSID_EPRESENT)) {
4127 printk(KERN_ERR "VINO is not found (EISA BUS not present)\n");
4128 return -ENODEV;
4129 }
4130
4131 vino = (struct sgi_vino *)ioremap(VINO_BASE, sizeof(struct sgi_vino));
4132 if (!vino) {
4133 printk(KERN_ERR "VINO: ioremap() failed\n");
4134 return -EIO;
4135 }
4136 vino_init_stage++;
4137
4138 if (get_dbe(rev_id, &(vino->rev_id))) {
4139 printk(KERN_ERR "Failed to read VINO revision register\n");
4140 vino_module_cleanup(vino_init_stage);
4141 return -ENODEV;
4142 }
4143
4144 if (VINO_ID_VALUE(rev_id) != VINO_CHIP_ID) {
4145 printk(KERN_ERR "Unknown VINO chip ID (Rev/ID: 0x%02lx)\n",
4146 rev_id);
4147 vino_module_cleanup(vino_init_stage);
4148 return -ENODEV;
4149 }
4150
4151 printk(KERN_INFO "VINO revision %ld found\n", VINO_REV_NUM(rev_id));
4152
4153 return 0;
4154}
4155
4156static int vino_init(void)
4157{
4158 dma_addr_t dma_dummy_address;
4159 int err;
4160 int i;
4161
4162 vino_drvdata = kzalloc(sizeof(struct vino_settings), GFP_KERNEL);
4163 if (!vino_drvdata) {
4164 vino_module_cleanup(vino_init_stage);
4165 return -ENOMEM;
4166 }
4167 vino_init_stage++;
4168 strlcpy(vino_drvdata->v4l2_dev.name, "vino",
4169 sizeof(vino_drvdata->v4l2_dev.name));
4170 err = v4l2_device_register(NULL, &vino_drvdata->v4l2_dev);
4171 if (err)
4172 return err;
4173 vino_init_stage++;
4174
4175 /* create a dummy dma descriptor */
4176 vino_drvdata->dummy_page = get_zeroed_page(GFP_KERNEL | GFP_DMA);
4177 if (!vino_drvdata->dummy_page) {
4178 vino_module_cleanup(vino_init_stage);
4179 return -ENOMEM;
4180 }
4181 vino_init_stage++;
4182
4183 // TODO: use page_count in dummy_desc_table
4184
4185 vino_drvdata->dummy_desc_table.dma_cpu =
4186 dma_alloc_coherent(NULL,
4187 VINO_DUMMY_DESC_COUNT * sizeof(dma_addr_t),
4188 &vino_drvdata->dummy_desc_table.dma,
4189 GFP_KERNEL | GFP_DMA);
4190 if (!vino_drvdata->dummy_desc_table.dma_cpu) {
4191 vino_module_cleanup(vino_init_stage);
4192 return -ENOMEM;
4193 }
4194 vino_init_stage++;
4195
4196 dma_dummy_address = dma_map_single(NULL,
4197 (void *)vino_drvdata->dummy_page,
4198 PAGE_SIZE, DMA_FROM_DEVICE);
4199 for (i = 0; i < VINO_DUMMY_DESC_COUNT; i++) {
4200 vino_drvdata->dummy_desc_table.dma_cpu[i] = dma_dummy_address;
4201 }
4202
4203 /* initialize VINO */
4204
4205 vino->control = 0;
4206 vino->a.next_4_desc = vino_drvdata->dummy_desc_table.dma;
4207 vino->b.next_4_desc = vino_drvdata->dummy_desc_table.dma;
4208 udelay(VINO_DESC_FETCH_DELAY);
4209
4210 vino->intr_status = 0;
4211
4212 vino->a.fifo_thres = VINO_FIFO_THRESHOLD_DEFAULT;
4213 vino->b.fifo_thres = VINO_FIFO_THRESHOLD_DEFAULT;
4214
4215 return 0;
4216}
4217
4218static int vino_init_channel_settings(struct vino_channel_settings *vcs,
4219 unsigned int channel, const char *name)
4220{
4221 vcs->channel = channel;
4222 vcs->input = VINO_INPUT_NONE;
4223 vcs->alpha = 0;
4224 vcs->users = 0;
4225 vcs->data_format = VINO_DATA_FMT_GREY;
4226 vcs->data_norm = VINO_DATA_NORM_NTSC;
4227 vcs->decimation = 1;
4228 vino_set_default_clipping(vcs);
4229 vino_set_default_framerate(vcs);
4230
4231 vcs->capturing = 0;
4232
4233 mutex_init(&vcs->mutex);
4234 spin_lock_init(&vcs->capture_lock);
4235
4236 mutex_init(&vcs->fb_queue.queue_mutex);
4237 spin_lock_init(&vcs->fb_queue.queue_lock);
4238 init_waitqueue_head(&vcs->fb_queue.frame_wait_queue);
4239
4240 vcs->vdev = video_device_alloc();
4241 if (!vcs->vdev) {
4242 vino_module_cleanup(vino_init_stage);
4243 return -ENOMEM;
4244 }
4245 vino_init_stage++;
4246
4247 memcpy(vcs->vdev, &vdev_template,
4248 sizeof(struct video_device));
4249 strcpy(vcs->vdev->name, name);
4250 vcs->vdev->release = video_device_release;
4251 vcs->vdev->v4l2_dev = &vino_drvdata->v4l2_dev;
4252
4253 video_set_drvdata(vcs->vdev, vcs);
4254
4255 return 0;
4256}
4257
4258static int __init vino_module_init(void)
4259{
4260 int ret;
4261
4262 printk(KERN_INFO "SGI VINO driver version %s\n",
4263 VINO_MODULE_VERSION);
4264
4265 ret = vino_probe();
4266 if (ret)
4267 return ret;
4268
4269 ret = vino_init();
4270 if (ret)
4271 return ret;
4272
4273 /* initialize data structures */
4274
4275 spin_lock_init(&vino_drvdata->vino_lock);
4276 spin_lock_init(&vino_drvdata->input_lock);
4277
4278 ret = vino_init_channel_settings(&vino_drvdata->a, VINO_CHANNEL_A,
4279 vino_vdev_name_a);
4280 if (ret)
4281 return ret;
4282
4283 ret = vino_init_channel_settings(&vino_drvdata->b, VINO_CHANNEL_B,
4284 vino_vdev_name_b);
4285 if (ret)
4286 return ret;
4287
4288 /* initialize hardware and register V4L devices */
4289
4290 ret = request_irq(SGI_VINO_IRQ, vino_interrupt, 0,
4291 vino_driver_description, NULL);
4292 if (ret) {
4293 printk(KERN_ERR "VINO: requesting IRQ %02d failed\n",
4294 SGI_VINO_IRQ);
4295 vino_module_cleanup(vino_init_stage);
4296 return -EAGAIN;
4297 }
4298 vino_init_stage++;
4299
4300 ret = i2c_add_adapter(&vino_i2c_adapter);
4301 if (ret) {
4302 printk(KERN_ERR "VINO I2C bus registration failed\n");
4303 vino_module_cleanup(vino_init_stage);
4304 return ret;
4305 }
4306 i2c_set_adapdata(&vino_i2c_adapter, &vino_drvdata->v4l2_dev);
4307 vino_init_stage++;
4308
4309 ret = video_register_device(vino_drvdata->a.vdev,
4310 VFL_TYPE_GRABBER, -1);
4311 if (ret < 0) {
4312 printk(KERN_ERR "VINO channel A Video4Linux-device "
4313 "registration failed\n");
4314 vino_module_cleanup(vino_init_stage);
4315 return -EINVAL;
4316 }
4317 vino_init_stage++;
4318
4319 ret = video_register_device(vino_drvdata->b.vdev,
4320 VFL_TYPE_GRABBER, -1);
4321 if (ret < 0) {
4322 printk(KERN_ERR "VINO channel B Video4Linux-device "
4323 "registration failed\n");
4324 vino_module_cleanup(vino_init_stage);
4325 return -EINVAL;
4326 }
4327 vino_init_stage++;
4328
4329 vino_drvdata->decoder =
4330 v4l2_i2c_new_subdev(&vino_drvdata->v4l2_dev, &vino_i2c_adapter,
4331 "saa7191", 0, I2C_ADDRS(0x45));
4332 vino_drvdata->camera =
4333 v4l2_i2c_new_subdev(&vino_drvdata->v4l2_dev, &vino_i2c_adapter,
4334 "indycam", 0, I2C_ADDRS(0x2b));
4335
4336 dprintk("init complete!\n");
4337
4338 return 0;
4339}
4340
4341static void __exit vino_module_exit(void)
4342{
4343 dprintk("exiting, stage = %d ...\n", vino_init_stage);
4344 vino_module_cleanup(vino_init_stage);
4345 dprintk("cleanup complete, exit!\n");
4346}
4347
4348module_init(vino_module_init);
4349module_exit(vino_module_exit);
diff --git a/drivers/media/video/vino.h b/drivers/media/video/vino.h
deleted file mode 100644
index de2d615ae7c9..000000000000
--- a/drivers/media/video/vino.h
+++ /dev/null
@@ -1,138 +0,0 @@
1/*
2 * Driver for the VINO (Video In No Out) system found in SGI Indys.
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License version 2 as published by the Free Software Foundation.
6 *
7 * Copyright (C) 1999 Ulf Karlsson <ulfc@bun.falkenberg.se>
8 * Copyright (C) 2003 Ladislav Michl <ladis@linux-mips.org>
9 */
10
11#ifndef _VINO_H_
12#define _VINO_H_
13
14#define VINO_BASE 0x00080000 /* Vino is in the EISA address space,
15 * but it is not an EISA bus card */
16#define VINO_PAGE_SIZE 4096
17
18struct sgi_vino_channel {
19 u32 _pad_alpha;
20 volatile u32 alpha;
21
22#define VINO_CLIP_X(x) ((x) & 0x3ff) /* bits 0:9 */
23#define VINO_CLIP_ODD(x) (((x) & 0x1ff) << 10) /* bits 10:18 */
24#define VINO_CLIP_EVEN(x) (((x) & 0x1ff) << 19) /* bits 19:27 */
25 u32 _pad_clip_start;
26 volatile u32 clip_start;
27 u32 _pad_clip_end;
28 volatile u32 clip_end;
29
30#define VINO_FRAMERT_FULL 0xfff
31#define VINO_FRAMERT_PAL (1<<0) /* 0=NTSC 1=PAL */
32#define VINO_FRAMERT_RT(x) (((x) & 0xfff) << 1) /* bits 1:12 */
33 u32 _pad_frame_rate;
34 volatile u32 frame_rate;
35
36 u32 _pad_field_counter;
37 volatile u32 field_counter;
38 u32 _pad_line_size;
39 volatile u32 line_size;
40 u32 _pad_line_count;
41 volatile u32 line_count;
42 u32 _pad_page_index;
43 volatile u32 page_index;
44 u32 _pad_next_4_desc;
45 volatile u32 next_4_desc;
46 u32 _pad_start_desc_tbl;
47 volatile u32 start_desc_tbl;
48
49#define VINO_DESC_JUMP (1<<30)
50#define VINO_DESC_STOP (1<<31)
51#define VINO_DESC_VALID (1<<32)
52 u32 _pad_desc_0;
53 volatile u32 desc_0;
54 u32 _pad_desc_1;
55 volatile u32 desc_1;
56 u32 _pad_desc_2;
57 volatile u32 desc_2;
58 u32 _pad_Bdesc_3;
59 volatile u32 desc_3;
60
61 u32 _pad_fifo_thres;
62 volatile u32 fifo_thres;
63 u32 _pad_fifo_read;
64 volatile u32 fifo_read;
65 u32 _pad_fifo_write;
66 volatile u32 fifo_write;
67};
68
69struct sgi_vino {
70#define VINO_CHIP_ID 0xb
71#define VINO_REV_NUM(x) ((x) & 0x0f)
72#define VINO_ID_VALUE(x) (((x) & 0xf0) >> 4)
73 u32 _pad_rev_id;
74 volatile u32 rev_id;
75
76#define VINO_CTRL_LITTLE_ENDIAN (1<<0)
77#define VINO_CTRL_A_EOF_INT (1<<1) /* Field transferred int */
78#define VINO_CTRL_A_FIFO_INT (1<<2) /* FIFO overflow int */
79#define VINO_CTRL_A_EOD_INT (1<<3) /* End of desc table int */
80#define VINO_CTRL_A_INT (VINO_CTRL_A_EOF_INT | \
81 VINO_CTRL_A_FIFO_INT | \
82 VINO_CTRL_A_EOD_INT)
83#define VINO_CTRL_B_EOF_INT (1<<4) /* Field transferred int */
84#define VINO_CTRL_B_FIFO_INT (1<<5) /* FIFO overflow int */
85#define VINO_CTRL_B_EOD_INT (1<<6) /* End of desc table int */
86#define VINO_CTRL_B_INT (VINO_CTRL_B_EOF_INT | \
87 VINO_CTRL_B_FIFO_INT | \
88 VINO_CTRL_B_EOD_INT)
89#define VINO_CTRL_A_DMA_ENBL (1<<7)
90#define VINO_CTRL_A_INTERLEAVE_ENBL (1<<8)
91#define VINO_CTRL_A_SYNC_ENBL (1<<9)
92#define VINO_CTRL_A_SELECT (1<<10) /* 1=D1 0=Philips */
93#define VINO_CTRL_A_RGB (1<<11) /* 1=RGB 0=YUV */
94#define VINO_CTRL_A_LUMA_ONLY (1<<12)
95#define VINO_CTRL_A_DEC_ENBL (1<<13) /* Decimation */
96#define VINO_CTRL_A_DEC_SCALE_MASK 0x1c000 /* bits 14:17 */
97#define VINO_CTRL_A_DEC_SCALE_SHIFT (14)
98#define VINO_CTRL_A_DEC_HOR_ONLY (1<<17) /* Horizontal only */
99#define VINO_CTRL_A_DITHER (1<<18) /* 24 -> 8 bit dither */
100#define VINO_CTRL_B_DMA_ENBL (1<<19)
101#define VINO_CTRL_B_INTERLEAVE_ENBL (1<<20)
102#define VINO_CTRL_B_SYNC_ENBL (1<<21)
103#define VINO_CTRL_B_SELECT (1<<22) /* 1=D1 0=Philips */
104#define VINO_CTRL_B_RGB (1<<23) /* 1=RGB 0=YUV */
105#define VINO_CTRL_B_LUMA_ONLY (1<<24)
106#define VINO_CTRL_B_DEC_ENBL (1<<25) /* Decimation */
107#define VINO_CTRL_B_DEC_SCALE_MASK 0x1c000000 /* bits 26:28 */
108#define VINO_CTRL_B_DEC_SCALE_SHIFT (26)
109#define VINO_CTRL_B_DEC_HOR_ONLY (1<<29) /* Decimation horizontal only */
110#define VINO_CTRL_B_DITHER (1<<30) /* ChanB 24 -> 8 bit dither */
111 u32 _pad_control;
112 volatile u32 control;
113
114#define VINO_INTSTAT_A_EOF (1<<0) /* Field transferred int */
115#define VINO_INTSTAT_A_FIFO (1<<1) /* FIFO overflow int */
116#define VINO_INTSTAT_A_EOD (1<<2) /* End of desc table int */
117#define VINO_INTSTAT_A (VINO_INTSTAT_A_EOF | \
118 VINO_INTSTAT_A_FIFO | \
119 VINO_INTSTAT_A_EOD)
120#define VINO_INTSTAT_B_EOF (1<<3) /* Field transferred int */
121#define VINO_INTSTAT_B_FIFO (1<<4) /* FIFO overflow int */
122#define VINO_INTSTAT_B_EOD (1<<5) /* End of desc table int */
123#define VINO_INTSTAT_B (VINO_INTSTAT_B_EOF | \
124 VINO_INTSTAT_B_FIFO | \
125 VINO_INTSTAT_B_EOD)
126 u32 _pad_intr_status;
127 volatile u32 intr_status;
128
129 u32 _pad_i2c_control;
130 volatile u32 i2c_control;
131 u32 _pad_i2c_data;
132 volatile u32 i2c_data;
133
134 struct sgi_vino_channel a;
135 struct sgi_vino_channel b;
136};
137
138#endif
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c
deleted file mode 100644
index a6351c49bfd3..000000000000
--- a/drivers/media/video/vivi.c
+++ /dev/null
@@ -1,1409 +0,0 @@
1/*
2 * Virtual Video driver - This code emulates a real video device with v4l2 api
3 *
4 * Copyright (c) 2006 by:
5 * Mauro Carvalho Chehab <mchehab--a.t--infradead.org>
6 * Ted Walther <ted--a.t--enumera.com>
7 * John Sokol <sokol--a.t--videotechnology.com>
8 * http://v4l.videotechnology.com/
9 *
10 * Conversion to videobuf2 by Pawel Osciak & Marek Szyprowski
11 * Copyright (c) 2010 Samsung Electronics
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the BSD Licence, GNU General Public License
15 * as published by the Free Software Foundation; either version 2 of the
16 * License, or (at your option) any later version
17 */
18#include <linux/module.h>
19#include <linux/errno.h>
20#include <linux/kernel.h>
21#include <linux/init.h>
22#include <linux/sched.h>
23#include <linux/slab.h>
24#include <linux/font.h>
25#include <linux/mutex.h>
26#include <linux/videodev2.h>
27#include <linux/kthread.h>
28#include <linux/freezer.h>
29#include <media/videobuf2-vmalloc.h>
30#include <media/v4l2-device.h>
31#include <media/v4l2-ioctl.h>
32#include <media/v4l2-ctrls.h>
33#include <media/v4l2-fh.h>
34#include <media/v4l2-event.h>
35#include <media/v4l2-common.h>
36
37#define VIVI_MODULE_NAME "vivi"
38
39/* Wake up at about 30 fps */
40#define WAKE_NUMERATOR 30
41#define WAKE_DENOMINATOR 1001
42#define BUFFER_TIMEOUT msecs_to_jiffies(500) /* 0.5 seconds */
43
44#define MAX_WIDTH 1920
45#define MAX_HEIGHT 1200
46
47#define VIVI_VERSION "0.8.1"
48
49MODULE_DESCRIPTION("Video Technology Magazine Virtual Video Capture Board");
50MODULE_AUTHOR("Mauro Carvalho Chehab, Ted Walther and John Sokol");
51MODULE_LICENSE("Dual BSD/GPL");
52MODULE_VERSION(VIVI_VERSION);
53
54static unsigned video_nr = -1;
55module_param(video_nr, uint, 0644);
56MODULE_PARM_DESC(video_nr, "videoX start number, -1 is autodetect");
57
58static unsigned n_devs = 1;
59module_param(n_devs, uint, 0644);
60MODULE_PARM_DESC(n_devs, "number of video devices to create");
61
62static unsigned debug;
63module_param(debug, uint, 0644);
64MODULE_PARM_DESC(debug, "activates debug info");
65
66static unsigned int vid_limit = 16;
67module_param(vid_limit, uint, 0644);
68MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes");
69
70/* Global font descriptor */
71static const u8 *font8x16;
72
73#define dprintk(dev, level, fmt, arg...) \
74 v4l2_dbg(level, debug, &dev->v4l2_dev, fmt, ## arg)
75
76/* ------------------------------------------------------------------
77 Basic structures
78 ------------------------------------------------------------------*/
79
80struct vivi_fmt {
81 char *name;
82 u32 fourcc; /* v4l2 format id */
83 u8 depth;
84 bool is_yuv;
85};
86
87static struct vivi_fmt formats[] = {
88 {
89 .name = "4:2:2, packed, YUYV",
90 .fourcc = V4L2_PIX_FMT_YUYV,
91 .depth = 16,
92 .is_yuv = true,
93 },
94 {
95 .name = "4:2:2, packed, UYVY",
96 .fourcc = V4L2_PIX_FMT_UYVY,
97 .depth = 16,
98 .is_yuv = true,
99 },
100 {
101 .name = "4:2:2, packed, YVYU",
102 .fourcc = V4L2_PIX_FMT_YVYU,
103 .depth = 16,
104 .is_yuv = true,
105 },
106 {
107 .name = "4:2:2, packed, VYUY",
108 .fourcc = V4L2_PIX_FMT_VYUY,
109 .depth = 16,
110 .is_yuv = true,
111 },
112 {
113 .name = "RGB565 (LE)",
114 .fourcc = V4L2_PIX_FMT_RGB565, /* gggbbbbb rrrrrggg */
115 .depth = 16,
116 },
117 {
118 .name = "RGB565 (BE)",
119 .fourcc = V4L2_PIX_FMT_RGB565X, /* rrrrrggg gggbbbbb */
120 .depth = 16,
121 },
122 {
123 .name = "RGB555 (LE)",
124 .fourcc = V4L2_PIX_FMT_RGB555, /* gggbbbbb arrrrrgg */
125 .depth = 16,
126 },
127 {
128 .name = "RGB555 (BE)",
129 .fourcc = V4L2_PIX_FMT_RGB555X, /* arrrrrgg gggbbbbb */
130 .depth = 16,
131 },
132 {
133 .name = "RGB24 (LE)",
134 .fourcc = V4L2_PIX_FMT_RGB24, /* rgb */
135 .depth = 24,
136 },
137 {
138 .name = "RGB24 (BE)",
139 .fourcc = V4L2_PIX_FMT_BGR24, /* bgr */
140 .depth = 24,
141 },
142 {
143 .name = "RGB32 (LE)",
144 .fourcc = V4L2_PIX_FMT_RGB32, /* argb */
145 .depth = 32,
146 },
147 {
148 .name = "RGB32 (BE)",
149 .fourcc = V4L2_PIX_FMT_BGR32, /* bgra */
150 .depth = 32,
151 },
152};
153
154static struct vivi_fmt *get_format(struct v4l2_format *f)
155{
156 struct vivi_fmt *fmt;
157 unsigned int k;
158
159 for (k = 0; k < ARRAY_SIZE(formats); k++) {
160 fmt = &formats[k];
161 if (fmt->fourcc == f->fmt.pix.pixelformat)
162 break;
163 }
164
165 if (k == ARRAY_SIZE(formats))
166 return NULL;
167
168 return &formats[k];
169}
170
171/* buffer for one video frame */
172struct vivi_buffer {
173 /* common v4l buffer stuff -- must be first */
174 struct vb2_buffer vb;
175 struct list_head list;
176 struct vivi_fmt *fmt;
177};
178
179struct vivi_dmaqueue {
180 struct list_head active;
181
182 /* thread for generating video stream*/
183 struct task_struct *kthread;
184 wait_queue_head_t wq;
185 /* Counters to control fps rate */
186 int frame;
187 int ini_jiffies;
188};
189
190static LIST_HEAD(vivi_devlist);
191
192struct vivi_dev {
193 struct list_head vivi_devlist;
194 struct v4l2_device v4l2_dev;
195 struct v4l2_ctrl_handler ctrl_handler;
196 struct video_device vdev;
197
198 /* controls */
199 struct v4l2_ctrl *brightness;
200 struct v4l2_ctrl *contrast;
201 struct v4l2_ctrl *saturation;
202 struct v4l2_ctrl *hue;
203 struct {
204 /* autogain/gain cluster */
205 struct v4l2_ctrl *autogain;
206 struct v4l2_ctrl *gain;
207 };
208 struct v4l2_ctrl *volume;
209 struct v4l2_ctrl *alpha;
210 struct v4l2_ctrl *button;
211 struct v4l2_ctrl *boolean;
212 struct v4l2_ctrl *int32;
213 struct v4l2_ctrl *int64;
214 struct v4l2_ctrl *menu;
215 struct v4l2_ctrl *string;
216 struct v4l2_ctrl *bitmask;
217 struct v4l2_ctrl *int_menu;
218
219 spinlock_t slock;
220 struct mutex mutex;
221
222 struct vivi_dmaqueue vidq;
223
224 /* Several counters */
225 unsigned ms;
226 unsigned long jiffies;
227 unsigned button_pressed;
228
229 int mv_count; /* Controls bars movement */
230
231 /* Input Number */
232 int input;
233
234 /* video capture */
235 struct vivi_fmt *fmt;
236 unsigned int width, height;
237 struct vb2_queue vb_vidq;
238 unsigned int field_count;
239
240 u8 bars[9][3];
241 u8 line[MAX_WIDTH * 8];
242 unsigned int pixelsize;
243 u8 alpha_component;
244};
245
246/* ------------------------------------------------------------------
247 DMA and thread functions
248 ------------------------------------------------------------------*/
249
250/* Bars and Colors should match positions */
251
252enum colors {
253 WHITE,
254 AMBER,
255 CYAN,
256 GREEN,
257 MAGENTA,
258 RED,
259 BLUE,
260 BLACK,
261 TEXT_BLACK,
262};
263
264/* R G B */
265#define COLOR_WHITE {204, 204, 204}
266#define COLOR_AMBER {208, 208, 0}
267#define COLOR_CYAN { 0, 206, 206}
268#define COLOR_GREEN { 0, 239, 0}
269#define COLOR_MAGENTA {239, 0, 239}
270#define COLOR_RED {205, 0, 0}
271#define COLOR_BLUE { 0, 0, 255}
272#define COLOR_BLACK { 0, 0, 0}
273
274struct bar_std {
275 u8 bar[9][3];
276};
277
278/* Maximum number of bars are 10 - otherwise, the input print code
279 should be modified */
280static struct bar_std bars[] = {
281 { /* Standard ITU-R color bar sequence */
282 { COLOR_WHITE, COLOR_AMBER, COLOR_CYAN, COLOR_GREEN,
283 COLOR_MAGENTA, COLOR_RED, COLOR_BLUE, COLOR_BLACK, COLOR_BLACK }
284 }, {
285 { COLOR_WHITE, COLOR_AMBER, COLOR_BLACK, COLOR_WHITE,
286 COLOR_AMBER, COLOR_BLACK, COLOR_WHITE, COLOR_AMBER, COLOR_BLACK }
287 }, {
288 { COLOR_WHITE, COLOR_CYAN, COLOR_BLACK, COLOR_WHITE,
289 COLOR_CYAN, COLOR_BLACK, COLOR_WHITE, COLOR_CYAN, COLOR_BLACK }
290 }, {
291 { COLOR_WHITE, COLOR_GREEN, COLOR_BLACK, COLOR_WHITE,
292 COLOR_GREEN, COLOR_BLACK, COLOR_WHITE, COLOR_GREEN, COLOR_BLACK }
293 },
294};
295
296#define NUM_INPUTS ARRAY_SIZE(bars)
297
298#define TO_Y(r, g, b) \
299 (((16829 * r + 33039 * g + 6416 * b + 32768) >> 16) + 16)
300/* RGB to V(Cr) Color transform */
301#define TO_V(r, g, b) \
302 (((28784 * r - 24103 * g - 4681 * b + 32768) >> 16) + 128)
303/* RGB to U(Cb) Color transform */
304#define TO_U(r, g, b) \
305 (((-9714 * r - 19070 * g + 28784 * b + 32768) >> 16) + 128)
306
307/* precalculate color bar values to speed up rendering */
308static void precalculate_bars(struct vivi_dev *dev)
309{
310 u8 r, g, b;
311 int k, is_yuv;
312
313 for (k = 0; k < 9; k++) {
314 r = bars[dev->input].bar[k][0];
315 g = bars[dev->input].bar[k][1];
316 b = bars[dev->input].bar[k][2];
317 is_yuv = dev->fmt->is_yuv;
318
319 switch (dev->fmt->fourcc) {
320 case V4L2_PIX_FMT_RGB565:
321 case V4L2_PIX_FMT_RGB565X:
322 r >>= 3;
323 g >>= 2;
324 b >>= 3;
325 break;
326 case V4L2_PIX_FMT_RGB555:
327 case V4L2_PIX_FMT_RGB555X:
328 r >>= 3;
329 g >>= 3;
330 b >>= 3;
331 break;
332 case V4L2_PIX_FMT_YUYV:
333 case V4L2_PIX_FMT_UYVY:
334 case V4L2_PIX_FMT_YVYU:
335 case V4L2_PIX_FMT_VYUY:
336 case V4L2_PIX_FMT_RGB24:
337 case V4L2_PIX_FMT_BGR24:
338 case V4L2_PIX_FMT_RGB32:
339 case V4L2_PIX_FMT_BGR32:
340 break;
341 }
342
343 if (is_yuv) {
344 dev->bars[k][0] = TO_Y(r, g, b); /* Luma */
345 dev->bars[k][1] = TO_U(r, g, b); /* Cb */
346 dev->bars[k][2] = TO_V(r, g, b); /* Cr */
347 } else {
348 dev->bars[k][0] = r;
349 dev->bars[k][1] = g;
350 dev->bars[k][2] = b;
351 }
352 }
353}
354
355#define TSTAMP_MIN_Y 24
356#define TSTAMP_MAX_Y (TSTAMP_MIN_Y + 15)
357#define TSTAMP_INPUT_X 10
358#define TSTAMP_MIN_X (54 + TSTAMP_INPUT_X)
359
360/* 'odd' is true for pixels 1, 3, 5, etc. and false for pixels 0, 2, 4, etc. */
361static void gen_twopix(struct vivi_dev *dev, u8 *buf, int colorpos, bool odd)
362{
363 u8 r_y, g_u, b_v;
364 u8 alpha = dev->alpha_component;
365 int color;
366 u8 *p;
367
368 r_y = dev->bars[colorpos][0]; /* R or precalculated Y */
369 g_u = dev->bars[colorpos][1]; /* G or precalculated U */
370 b_v = dev->bars[colorpos][2]; /* B or precalculated V */
371
372 for (color = 0; color < dev->pixelsize; color++) {
373 p = buf + color;
374
375 switch (dev->fmt->fourcc) {
376 case V4L2_PIX_FMT_YUYV:
377 switch (color) {
378 case 0:
379 *p = r_y;
380 break;
381 case 1:
382 *p = odd ? b_v : g_u;
383 break;
384 }
385 break;
386 case V4L2_PIX_FMT_UYVY:
387 switch (color) {
388 case 0:
389 *p = odd ? b_v : g_u;
390 break;
391 case 1:
392 *p = r_y;
393 break;
394 }
395 break;
396 case V4L2_PIX_FMT_YVYU:
397 switch (color) {
398 case 0:
399 *p = r_y;
400 break;
401 case 1:
402 *p = odd ? g_u : b_v;
403 break;
404 }
405 break;
406 case V4L2_PIX_FMT_VYUY:
407 switch (color) {
408 case 0:
409 *p = odd ? g_u : b_v;
410 break;
411 case 1:
412 *p = r_y;
413 break;
414 }
415 break;
416 case V4L2_PIX_FMT_RGB565:
417 switch (color) {
418 case 0:
419 *p = (g_u << 5) | b_v;
420 break;
421 case 1:
422 *p = (r_y << 3) | (g_u >> 3);
423 break;
424 }
425 break;
426 case V4L2_PIX_FMT_RGB565X:
427 switch (color) {
428 case 0:
429 *p = (r_y << 3) | (g_u >> 3);
430 break;
431 case 1:
432 *p = (g_u << 5) | b_v;
433 break;
434 }
435 break;
436 case V4L2_PIX_FMT_RGB555:
437 switch (color) {
438 case 0:
439 *p = (g_u << 5) | b_v;
440 break;
441 case 1:
442 *p = (alpha & 0x80) | (r_y << 2) | (g_u >> 3);
443 break;
444 }
445 break;
446 case V4L2_PIX_FMT_RGB555X:
447 switch (color) {
448 case 0:
449 *p = (alpha & 0x80) | (r_y << 2) | (g_u >> 3);
450 break;
451 case 1:
452 *p = (g_u << 5) | b_v;
453 break;
454 }
455 break;
456 case V4L2_PIX_FMT_RGB24:
457 switch (color) {
458 case 0:
459 *p = r_y;
460 break;
461 case 1:
462 *p = g_u;
463 break;
464 case 2:
465 *p = b_v;
466 break;
467 }
468 break;
469 case V4L2_PIX_FMT_BGR24:
470 switch (color) {
471 case 0:
472 *p = b_v;
473 break;
474 case 1:
475 *p = g_u;
476 break;
477 case 2:
478 *p = r_y;
479 break;
480 }
481 break;
482 case V4L2_PIX_FMT_RGB32:
483 switch (color) {
484 case 0:
485 *p = alpha;
486 break;
487 case 1:
488 *p = r_y;
489 break;
490 case 2:
491 *p = g_u;
492 break;
493 case 3:
494 *p = b_v;
495 break;
496 }
497 break;
498 case V4L2_PIX_FMT_BGR32:
499 switch (color) {
500 case 0:
501 *p = b_v;
502 break;
503 case 1:
504 *p = g_u;
505 break;
506 case 2:
507 *p = r_y;
508 break;
509 case 3:
510 *p = alpha;
511 break;
512 }
513 break;
514 }
515 }
516}
517
518static void precalculate_line(struct vivi_dev *dev)
519{
520 int w;
521
522 for (w = 0; w < dev->width * 2; w++) {
523 int colorpos = w / (dev->width / 8) % 8;
524
525 gen_twopix(dev, dev->line + w * dev->pixelsize, colorpos, w & 1);
526 }
527}
528
529static void gen_text(struct vivi_dev *dev, char *basep,
530 int y, int x, char *text)
531{
532 int line;
533
534 /* Checks if it is possible to show string */
535 if (y + 16 >= dev->height || x + strlen(text) * 8 >= dev->width)
536 return;
537
538 /* Print stream time */
539 for (line = y; line < y + 16; line++) {
540 int j = 0;
541 char *pos = basep + line * dev->width * dev->pixelsize + x * dev->pixelsize;
542 char *s;
543
544 for (s = text; *s; s++) {
545 u8 chr = font8x16[*s * 16 + line - y];
546 int i;
547
548 for (i = 0; i < 7; i++, j++) {
549 /* Draw white font on black background */
550 if (chr & (1 << (7 - i)))
551 gen_twopix(dev, pos + j * dev->pixelsize, WHITE, (x+y) & 1);
552 else
553 gen_twopix(dev, pos + j * dev->pixelsize, TEXT_BLACK, (x+y) & 1);
554 }
555 }
556 }
557}
558
559static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf)
560{
561 int wmax = dev->width;
562 int hmax = dev->height;
563 struct timeval ts;
564 void *vbuf = vb2_plane_vaddr(&buf->vb, 0);
565 unsigned ms;
566 char str[100];
567 int h, line = 1;
568 s32 gain;
569
570 if (!vbuf)
571 return;
572
573 for (h = 0; h < hmax; h++)
574 memcpy(vbuf + h * wmax * dev->pixelsize,
575 dev->line + (dev->mv_count % wmax) * dev->pixelsize,
576 wmax * dev->pixelsize);
577
578 /* Updates stream time */
579
580 dev->ms += jiffies_to_msecs(jiffies - dev->jiffies);
581 dev->jiffies = jiffies;
582 ms = dev->ms;
583 snprintf(str, sizeof(str), " %02d:%02d:%02d:%03d ",
584 (ms / (60 * 60 * 1000)) % 24,
585 (ms / (60 * 1000)) % 60,
586 (ms / 1000) % 60,
587 ms % 1000);
588 gen_text(dev, vbuf, line++ * 16, 16, str);
589 snprintf(str, sizeof(str), " %dx%d, input %d ",
590 dev->width, dev->height, dev->input);
591 gen_text(dev, vbuf, line++ * 16, 16, str);
592
593 gain = v4l2_ctrl_g_ctrl(dev->gain);
594 mutex_lock(dev->ctrl_handler.lock);
595 snprintf(str, sizeof(str), " brightness %3d, contrast %3d, saturation %3d, hue %d ",
596 dev->brightness->cur.val,
597 dev->contrast->cur.val,
598 dev->saturation->cur.val,
599 dev->hue->cur.val);
600 gen_text(dev, vbuf, line++ * 16, 16, str);
601 snprintf(str, sizeof(str), " autogain %d, gain %3d, volume %3d, alpha 0x%02x ",
602 dev->autogain->cur.val, gain, dev->volume->cur.val,
603 dev->alpha->cur.val);
604 gen_text(dev, vbuf, line++ * 16, 16, str);
605 snprintf(str, sizeof(str), " int32 %d, int64 %lld, bitmask %08x ",
606 dev->int32->cur.val,
607 dev->int64->cur.val64,
608 dev->bitmask->cur.val);
609 gen_text(dev, vbuf, line++ * 16, 16, str);
610 snprintf(str, sizeof(str), " boolean %d, menu %s, string \"%s\" ",
611 dev->boolean->cur.val,
612 dev->menu->qmenu[dev->menu->cur.val],
613 dev->string->cur.string);
614 gen_text(dev, vbuf, line++ * 16, 16, str);
615 snprintf(str, sizeof(str), " integer_menu %lld, value %d ",
616 dev->int_menu->qmenu_int[dev->int_menu->cur.val],
617 dev->int_menu->cur.val);
618 gen_text(dev, vbuf, line++ * 16, 16, str);
619 mutex_unlock(dev->ctrl_handler.lock);
620 if (dev->button_pressed) {
621 dev->button_pressed--;
622 snprintf(str, sizeof(str), " button pressed!");
623 gen_text(dev, vbuf, line++ * 16, 16, str);
624 }
625
626 dev->mv_count += 2;
627
628 buf->vb.v4l2_buf.field = V4L2_FIELD_INTERLACED;
629 dev->field_count++;
630 buf->vb.v4l2_buf.sequence = dev->field_count >> 1;
631 do_gettimeofday(&ts);
632 buf->vb.v4l2_buf.timestamp = ts;
633}
634
635static void vivi_thread_tick(struct vivi_dev *dev)
636{
637 struct vivi_dmaqueue *dma_q = &dev->vidq;
638 struct vivi_buffer *buf;
639 unsigned long flags = 0;
640
641 dprintk(dev, 1, "Thread tick\n");
642
643 spin_lock_irqsave(&dev->slock, flags);
644 if (list_empty(&dma_q->active)) {
645 dprintk(dev, 1, "No active queue to serve\n");
646 spin_unlock_irqrestore(&dev->slock, flags);
647 return;
648 }
649
650 buf = list_entry(dma_q->active.next, struct vivi_buffer, list);
651 list_del(&buf->list);
652 spin_unlock_irqrestore(&dev->slock, flags);
653
654 do_gettimeofday(&buf->vb.v4l2_buf.timestamp);
655
656 /* Fill buffer */
657 vivi_fillbuff(dev, buf);
658 dprintk(dev, 1, "filled buffer %p\n", buf);
659
660 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_DONE);
661 dprintk(dev, 2, "[%p/%d] done\n", buf, buf->vb.v4l2_buf.index);
662}
663
664#define frames_to_ms(frames) \
665 ((frames * WAKE_NUMERATOR * 1000) / WAKE_DENOMINATOR)
666
667static void vivi_sleep(struct vivi_dev *dev)
668{
669 struct vivi_dmaqueue *dma_q = &dev->vidq;
670 int timeout;
671 DECLARE_WAITQUEUE(wait, current);
672
673 dprintk(dev, 1, "%s dma_q=0x%08lx\n", __func__,
674 (unsigned long)dma_q);
675
676 add_wait_queue(&dma_q->wq, &wait);
677 if (kthread_should_stop())
678 goto stop_task;
679
680 /* Calculate time to wake up */
681 timeout = msecs_to_jiffies(frames_to_ms(1));
682
683 vivi_thread_tick(dev);
684
685 schedule_timeout_interruptible(timeout);
686
687stop_task:
688 remove_wait_queue(&dma_q->wq, &wait);
689 try_to_freeze();
690}
691
692static int vivi_thread(void *data)
693{
694 struct vivi_dev *dev = data;
695
696 dprintk(dev, 1, "thread started\n");
697
698 set_freezable();
699
700 for (;;) {
701 vivi_sleep(dev);
702
703 if (kthread_should_stop())
704 break;
705 }
706 dprintk(dev, 1, "thread: exit\n");
707 return 0;
708}
709
710static int vivi_start_generating(struct vivi_dev *dev)
711{
712 struct vivi_dmaqueue *dma_q = &dev->vidq;
713
714 dprintk(dev, 1, "%s\n", __func__);
715
716 /* Resets frame counters */
717 dev->ms = 0;
718 dev->mv_count = 0;
719 dev->jiffies = jiffies;
720
721 dma_q->frame = 0;
722 dma_q->ini_jiffies = jiffies;
723 dma_q->kthread = kthread_run(vivi_thread, dev, dev->v4l2_dev.name);
724
725 if (IS_ERR(dma_q->kthread)) {
726 v4l2_err(&dev->v4l2_dev, "kernel_thread() failed\n");
727 return PTR_ERR(dma_q->kthread);
728 }
729 /* Wakes thread */
730 wake_up_interruptible(&dma_q->wq);
731
732 dprintk(dev, 1, "returning from %s\n", __func__);
733 return 0;
734}
735
736static void vivi_stop_generating(struct vivi_dev *dev)
737{
738 struct vivi_dmaqueue *dma_q = &dev->vidq;
739
740 dprintk(dev, 1, "%s\n", __func__);
741
742 /* shutdown control thread */
743 if (dma_q->kthread) {
744 kthread_stop(dma_q->kthread);
745 dma_q->kthread = NULL;
746 }
747
748 /*
749 * Typical driver might need to wait here until dma engine stops.
750 * In this case we can abort imiedetly, so it's just a noop.
751 */
752
753 /* Release all active buffers */
754 while (!list_empty(&dma_q->active)) {
755 struct vivi_buffer *buf;
756 buf = list_entry(dma_q->active.next, struct vivi_buffer, list);
757 list_del(&buf->list);
758 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
759 dprintk(dev, 2, "[%p/%d] done\n", buf, buf->vb.v4l2_buf.index);
760 }
761}
762/* ------------------------------------------------------------------
763 Videobuf operations
764 ------------------------------------------------------------------*/
765static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
766 unsigned int *nbuffers, unsigned int *nplanes,
767 unsigned int sizes[], void *alloc_ctxs[])
768{
769 struct vivi_dev *dev = vb2_get_drv_priv(vq);
770 unsigned long size;
771
772 if (fmt)
773 size = fmt->fmt.pix.sizeimage;
774 else
775 size = dev->width * dev->height * dev->pixelsize;
776
777 if (size == 0)
778 return -EINVAL;
779
780 if (0 == *nbuffers)
781 *nbuffers = 32;
782
783 while (size * *nbuffers > vid_limit * 1024 * 1024)
784 (*nbuffers)--;
785
786 *nplanes = 1;
787
788 sizes[0] = size;
789
790 /*
791 * videobuf2-vmalloc allocator is context-less so no need to set
792 * alloc_ctxs array.
793 */
794
795 dprintk(dev, 1, "%s, count=%d, size=%ld\n", __func__,
796 *nbuffers, size);
797
798 return 0;
799}
800
801static int buffer_prepare(struct vb2_buffer *vb)
802{
803 struct vivi_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
804 struct vivi_buffer *buf = container_of(vb, struct vivi_buffer, vb);
805 unsigned long size;
806
807 dprintk(dev, 1, "%s, field=%d\n", __func__, vb->v4l2_buf.field);
808
809 BUG_ON(NULL == dev->fmt);
810
811 /*
812 * Theses properties only change when queue is idle, see s_fmt.
813 * The below checks should not be performed here, on each
814 * buffer_prepare (i.e. on each qbuf). Most of the code in this function
815 * should thus be moved to buffer_init and s_fmt.
816 */
817 if (dev->width < 48 || dev->width > MAX_WIDTH ||
818 dev->height < 32 || dev->height > MAX_HEIGHT)
819 return -EINVAL;
820
821 size = dev->width * dev->height * dev->pixelsize;
822 if (vb2_plane_size(vb, 0) < size) {
823 dprintk(dev, 1, "%s data will not fit into plane (%lu < %lu)\n",
824 __func__, vb2_plane_size(vb, 0), size);
825 return -EINVAL;
826 }
827
828 vb2_set_plane_payload(&buf->vb, 0, size);
829
830 buf->fmt = dev->fmt;
831
832 precalculate_bars(dev);
833 precalculate_line(dev);
834
835 return 0;
836}
837
838static void buffer_queue(struct vb2_buffer *vb)
839{
840 struct vivi_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
841 struct vivi_buffer *buf = container_of(vb, struct vivi_buffer, vb);
842 struct vivi_dmaqueue *vidq = &dev->vidq;
843 unsigned long flags = 0;
844
845 dprintk(dev, 1, "%s\n", __func__);
846
847 spin_lock_irqsave(&dev->slock, flags);
848 list_add_tail(&buf->list, &vidq->active);
849 spin_unlock_irqrestore(&dev->slock, flags);
850}
851
852static int start_streaming(struct vb2_queue *vq, unsigned int count)
853{
854 struct vivi_dev *dev = vb2_get_drv_priv(vq);
855 dprintk(dev, 1, "%s\n", __func__);
856 return vivi_start_generating(dev);
857}
858
859/* abort streaming and wait for last buffer */
860static int stop_streaming(struct vb2_queue *vq)
861{
862 struct vivi_dev *dev = vb2_get_drv_priv(vq);
863 dprintk(dev, 1, "%s\n", __func__);
864 vivi_stop_generating(dev);
865 return 0;
866}
867
868static void vivi_lock(struct vb2_queue *vq)
869{
870 struct vivi_dev *dev = vb2_get_drv_priv(vq);
871 mutex_lock(&dev->mutex);
872}
873
874static void vivi_unlock(struct vb2_queue *vq)
875{
876 struct vivi_dev *dev = vb2_get_drv_priv(vq);
877 mutex_unlock(&dev->mutex);
878}
879
880
881static struct vb2_ops vivi_video_qops = {
882 .queue_setup = queue_setup,
883 .buf_prepare = buffer_prepare,
884 .buf_queue = buffer_queue,
885 .start_streaming = start_streaming,
886 .stop_streaming = stop_streaming,
887 .wait_prepare = vivi_unlock,
888 .wait_finish = vivi_lock,
889};
890
891/* ------------------------------------------------------------------
892 IOCTL vidioc handling
893 ------------------------------------------------------------------*/
894static int vidioc_querycap(struct file *file, void *priv,
895 struct v4l2_capability *cap)
896{
897 struct vivi_dev *dev = video_drvdata(file);
898
899 strcpy(cap->driver, "vivi");
900 strcpy(cap->card, "vivi");
901 strlcpy(cap->bus_info, dev->v4l2_dev.name, sizeof(cap->bus_info));
902 cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
903 V4L2_CAP_READWRITE;
904 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
905 return 0;
906}
907
908static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
909 struct v4l2_fmtdesc *f)
910{
911 struct vivi_fmt *fmt;
912
913 if (f->index >= ARRAY_SIZE(formats))
914 return -EINVAL;
915
916 fmt = &formats[f->index];
917
918 strlcpy(f->description, fmt->name, sizeof(f->description));
919 f->pixelformat = fmt->fourcc;
920 return 0;
921}
922
923static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
924 struct v4l2_format *f)
925{
926 struct vivi_dev *dev = video_drvdata(file);
927
928 f->fmt.pix.width = dev->width;
929 f->fmt.pix.height = dev->height;
930 f->fmt.pix.field = V4L2_FIELD_INTERLACED;
931 f->fmt.pix.pixelformat = dev->fmt->fourcc;
932 f->fmt.pix.bytesperline =
933 (f->fmt.pix.width * dev->fmt->depth) >> 3;
934 f->fmt.pix.sizeimage =
935 f->fmt.pix.height * f->fmt.pix.bytesperline;
936 if (dev->fmt->is_yuv)
937 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
938 else
939 f->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB;
940 return 0;
941}
942
943static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
944 struct v4l2_format *f)
945{
946 struct vivi_dev *dev = video_drvdata(file);
947 struct vivi_fmt *fmt;
948
949 fmt = get_format(f);
950 if (!fmt) {
951 dprintk(dev, 1, "Fourcc format (0x%08x) unknown.\n",
952 f->fmt.pix.pixelformat);
953 f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
954 fmt = get_format(f);
955 }
956
957 f->fmt.pix.field = V4L2_FIELD_INTERLACED;
958 v4l_bound_align_image(&f->fmt.pix.width, 48, MAX_WIDTH, 2,
959 &f->fmt.pix.height, 32, MAX_HEIGHT, 0, 0);
960 f->fmt.pix.bytesperline =
961 (f->fmt.pix.width * fmt->depth) >> 3;
962 f->fmt.pix.sizeimage =
963 f->fmt.pix.height * f->fmt.pix.bytesperline;
964 if (fmt->is_yuv)
965 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
966 else
967 f->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB;
968 f->fmt.pix.priv = 0;
969 return 0;
970}
971
972static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
973 struct v4l2_format *f)
974{
975 struct vivi_dev *dev = video_drvdata(file);
976 struct vb2_queue *q = &dev->vb_vidq;
977
978 int ret = vidioc_try_fmt_vid_cap(file, priv, f);
979 if (ret < 0)
980 return ret;
981
982 if (vb2_is_busy(q)) {
983 dprintk(dev, 1, "%s device busy\n", __func__);
984 return -EBUSY;
985 }
986
987 dev->fmt = get_format(f);
988 dev->pixelsize = dev->fmt->depth / 8;
989 dev->width = f->fmt.pix.width;
990 dev->height = f->fmt.pix.height;
991
992 return 0;
993}
994
995static int vidioc_enum_framesizes(struct file *file, void *fh,
996 struct v4l2_frmsizeenum *fsize)
997{
998 static const struct v4l2_frmsize_stepwise sizes = {
999 48, MAX_WIDTH, 4,
1000 32, MAX_HEIGHT, 1
1001 };
1002 int i;
1003
1004 if (fsize->index)
1005 return -EINVAL;
1006 for (i = 0; i < ARRAY_SIZE(formats); i++)
1007 if (formats[i].fourcc == fsize->pixel_format)
1008 break;
1009 if (i == ARRAY_SIZE(formats))
1010 return -EINVAL;
1011 fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
1012 fsize->stepwise = sizes;
1013 return 0;
1014}
1015
1016/* only one input in this sample driver */
1017static int vidioc_enum_input(struct file *file, void *priv,
1018 struct v4l2_input *inp)
1019{
1020 if (inp->index >= NUM_INPUTS)
1021 return -EINVAL;
1022
1023 inp->type = V4L2_INPUT_TYPE_CAMERA;
1024 sprintf(inp->name, "Camera %u", inp->index);
1025 return 0;
1026}
1027
1028static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
1029{
1030 struct vivi_dev *dev = video_drvdata(file);
1031
1032 *i = dev->input;
1033 return 0;
1034}
1035
1036static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
1037{
1038 struct vivi_dev *dev = video_drvdata(file);
1039
1040 if (i >= NUM_INPUTS)
1041 return -EINVAL;
1042
1043 if (i == dev->input)
1044 return 0;
1045
1046 dev->input = i;
1047 precalculate_bars(dev);
1048 precalculate_line(dev);
1049 return 0;
1050}
1051
1052/* --- controls ---------------------------------------------- */
1053
1054static int vivi_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
1055{
1056 struct vivi_dev *dev = container_of(ctrl->handler, struct vivi_dev, ctrl_handler);
1057
1058 if (ctrl == dev->autogain)
1059 dev->gain->val = jiffies & 0xff;
1060 return 0;
1061}
1062
1063static int vivi_s_ctrl(struct v4l2_ctrl *ctrl)
1064{
1065 struct vivi_dev *dev = container_of(ctrl->handler, struct vivi_dev, ctrl_handler);
1066
1067 switch (ctrl->id) {
1068 case V4L2_CID_ALPHA_COMPONENT:
1069 dev->alpha_component = ctrl->val;
1070 break;
1071 default:
1072 if (ctrl == dev->button)
1073 dev->button_pressed = 30;
1074 break;
1075 }
1076 return 0;
1077}
1078
1079/* ------------------------------------------------------------------
1080 File operations for the device
1081 ------------------------------------------------------------------*/
1082
1083static const struct v4l2_ctrl_ops vivi_ctrl_ops = {
1084 .g_volatile_ctrl = vivi_g_volatile_ctrl,
1085 .s_ctrl = vivi_s_ctrl,
1086};
1087
1088#define VIVI_CID_CUSTOM_BASE (V4L2_CID_USER_BASE | 0xf000)
1089
1090static const struct v4l2_ctrl_config vivi_ctrl_button = {
1091 .ops = &vivi_ctrl_ops,
1092 .id = VIVI_CID_CUSTOM_BASE + 0,
1093 .name = "Button",
1094 .type = V4L2_CTRL_TYPE_BUTTON,
1095};
1096
1097static const struct v4l2_ctrl_config vivi_ctrl_boolean = {
1098 .ops = &vivi_ctrl_ops,
1099 .id = VIVI_CID_CUSTOM_BASE + 1,
1100 .name = "Boolean",
1101 .type = V4L2_CTRL_TYPE_BOOLEAN,
1102 .min = 0,
1103 .max = 1,
1104 .step = 1,
1105 .def = 1,
1106};
1107
1108static const struct v4l2_ctrl_config vivi_ctrl_int32 = {
1109 .ops = &vivi_ctrl_ops,
1110 .id = VIVI_CID_CUSTOM_BASE + 2,
1111 .name = "Integer 32 Bits",
1112 .type = V4L2_CTRL_TYPE_INTEGER,
1113 .min = 0x80000000,
1114 .max = 0x7fffffff,
1115 .step = 1,
1116};
1117
1118static const struct v4l2_ctrl_config vivi_ctrl_int64 = {
1119 .ops = &vivi_ctrl_ops,
1120 .id = VIVI_CID_CUSTOM_BASE + 3,
1121 .name = "Integer 64 Bits",
1122 .type = V4L2_CTRL_TYPE_INTEGER64,
1123};
1124
1125static const char * const vivi_ctrl_menu_strings[] = {
1126 "Menu Item 0 (Skipped)",
1127 "Menu Item 1",
1128 "Menu Item 2 (Skipped)",
1129 "Menu Item 3",
1130 "Menu Item 4",
1131 "Menu Item 5 (Skipped)",
1132 NULL,
1133};
1134
1135static const struct v4l2_ctrl_config vivi_ctrl_menu = {
1136 .ops = &vivi_ctrl_ops,
1137 .id = VIVI_CID_CUSTOM_BASE + 4,
1138 .name = "Menu",
1139 .type = V4L2_CTRL_TYPE_MENU,
1140 .min = 1,
1141 .max = 4,
1142 .def = 3,
1143 .menu_skip_mask = 0x04,
1144 .qmenu = vivi_ctrl_menu_strings,
1145};
1146
1147static const struct v4l2_ctrl_config vivi_ctrl_string = {
1148 .ops = &vivi_ctrl_ops,
1149 .id = VIVI_CID_CUSTOM_BASE + 5,
1150 .name = "String",
1151 .type = V4L2_CTRL_TYPE_STRING,
1152 .min = 2,
1153 .max = 4,
1154 .step = 1,
1155};
1156
1157static const struct v4l2_ctrl_config vivi_ctrl_bitmask = {
1158 .ops = &vivi_ctrl_ops,
1159 .id = VIVI_CID_CUSTOM_BASE + 6,
1160 .name = "Bitmask",
1161 .type = V4L2_CTRL_TYPE_BITMASK,
1162 .def = 0x80002000,
1163 .min = 0,
1164 .max = 0x80402010,
1165 .step = 0,
1166};
1167
1168static const s64 vivi_ctrl_int_menu_values[] = {
1169 1, 1, 2, 3, 5, 8, 13, 21, 42,
1170};
1171
1172static const struct v4l2_ctrl_config vivi_ctrl_int_menu = {
1173 .ops = &vivi_ctrl_ops,
1174 .id = VIVI_CID_CUSTOM_BASE + 7,
1175 .name = "Integer menu",
1176 .type = V4L2_CTRL_TYPE_INTEGER_MENU,
1177 .min = 1,
1178 .max = 8,
1179 .def = 4,
1180 .menu_skip_mask = 0x02,
1181 .qmenu_int = vivi_ctrl_int_menu_values,
1182};
1183
1184static const struct v4l2_file_operations vivi_fops = {
1185 .owner = THIS_MODULE,
1186 .open = v4l2_fh_open,
1187 .release = vb2_fop_release,
1188 .read = vb2_fop_read,
1189 .poll = vb2_fop_poll,
1190 .unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */
1191 .mmap = vb2_fop_mmap,
1192};
1193
1194static const struct v4l2_ioctl_ops vivi_ioctl_ops = {
1195 .vidioc_querycap = vidioc_querycap,
1196 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
1197 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
1198 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
1199 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
1200 .vidioc_enum_framesizes = vidioc_enum_framesizes,
1201 .vidioc_reqbufs = vb2_ioctl_reqbufs,
1202 .vidioc_create_bufs = vb2_ioctl_create_bufs,
1203 .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
1204 .vidioc_querybuf = vb2_ioctl_querybuf,
1205 .vidioc_qbuf = vb2_ioctl_qbuf,
1206 .vidioc_dqbuf = vb2_ioctl_dqbuf,
1207 .vidioc_enum_input = vidioc_enum_input,
1208 .vidioc_g_input = vidioc_g_input,
1209 .vidioc_s_input = vidioc_s_input,
1210 .vidioc_streamon = vb2_ioctl_streamon,
1211 .vidioc_streamoff = vb2_ioctl_streamoff,
1212 .vidioc_log_status = v4l2_ctrl_log_status,
1213 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
1214 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
1215};
1216
1217static struct video_device vivi_template = {
1218 .name = "vivi",
1219 .fops = &vivi_fops,
1220 .ioctl_ops = &vivi_ioctl_ops,
1221 .release = video_device_release_empty,
1222};
1223
1224/* -----------------------------------------------------------------
1225 Initialization and module stuff
1226 ------------------------------------------------------------------*/
1227
1228static int vivi_release(void)
1229{
1230 struct vivi_dev *dev;
1231 struct list_head *list;
1232
1233 while (!list_empty(&vivi_devlist)) {
1234 list = vivi_devlist.next;
1235 list_del(list);
1236 dev = list_entry(list, struct vivi_dev, vivi_devlist);
1237
1238 v4l2_info(&dev->v4l2_dev, "unregistering %s\n",
1239 video_device_node_name(&dev->vdev));
1240 video_unregister_device(&dev->vdev);
1241 v4l2_device_unregister(&dev->v4l2_dev);
1242 v4l2_ctrl_handler_free(&dev->ctrl_handler);
1243 kfree(dev);
1244 }
1245
1246 return 0;
1247}
1248
1249static int __init vivi_create_instance(int inst)
1250{
1251 struct vivi_dev *dev;
1252 struct video_device *vfd;
1253 struct v4l2_ctrl_handler *hdl;
1254 struct vb2_queue *q;
1255 int ret;
1256
1257 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
1258 if (!dev)
1259 return -ENOMEM;
1260
1261 snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name),
1262 "%s-%03d", VIVI_MODULE_NAME, inst);
1263 ret = v4l2_device_register(NULL, &dev->v4l2_dev);
1264 if (ret)
1265 goto free_dev;
1266
1267 dev->fmt = &formats[0];
1268 dev->width = 640;
1269 dev->height = 480;
1270 dev->pixelsize = dev->fmt->depth / 8;
1271 hdl = &dev->ctrl_handler;
1272 v4l2_ctrl_handler_init(hdl, 11);
1273 dev->volume = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
1274 V4L2_CID_AUDIO_VOLUME, 0, 255, 1, 200);
1275 dev->brightness = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
1276 V4L2_CID_BRIGHTNESS, 0, 255, 1, 127);
1277 dev->contrast = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
1278 V4L2_CID_CONTRAST, 0, 255, 1, 16);
1279 dev->saturation = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
1280 V4L2_CID_SATURATION, 0, 255, 1, 127);
1281 dev->hue = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
1282 V4L2_CID_HUE, -128, 127, 1, 0);
1283 dev->autogain = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
1284 V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
1285 dev->gain = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
1286 V4L2_CID_GAIN, 0, 255, 1, 100);
1287 dev->alpha = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
1288 V4L2_CID_ALPHA_COMPONENT, 0, 255, 1, 0);
1289 dev->button = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_button, NULL);
1290 dev->int32 = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_int32, NULL);
1291 dev->int64 = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_int64, NULL);
1292 dev->boolean = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_boolean, NULL);
1293 dev->menu = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_menu, NULL);
1294 dev->string = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_string, NULL);
1295 dev->bitmask = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_bitmask, NULL);
1296 dev->int_menu = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_int_menu, NULL);
1297 if (hdl->error) {
1298 ret = hdl->error;
1299 goto unreg_dev;
1300 }
1301 v4l2_ctrl_auto_cluster(2, &dev->autogain, 0, true);
1302 dev->v4l2_dev.ctrl_handler = hdl;
1303
1304 /* initialize locks */
1305 spin_lock_init(&dev->slock);
1306
1307 /* initialize queue */
1308 q = &dev->vb_vidq;
1309 memset(q, 0, sizeof(dev->vb_vidq));
1310 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1311 q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
1312 q->drv_priv = dev;
1313 q->buf_struct_size = sizeof(struct vivi_buffer);
1314 q->ops = &vivi_video_qops;
1315 q->mem_ops = &vb2_vmalloc_memops;
1316
1317 vb2_queue_init(q);
1318
1319 mutex_init(&dev->mutex);
1320
1321 /* init video dma queues */
1322 INIT_LIST_HEAD(&dev->vidq.active);
1323 init_waitqueue_head(&dev->vidq.wq);
1324
1325 vfd = &dev->vdev;
1326 *vfd = vivi_template;
1327 vfd->debug = debug;
1328 vfd->v4l2_dev = &dev->v4l2_dev;
1329 vfd->queue = q;
1330 set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags);
1331
1332 /*
1333 * Provide a mutex to v4l2 core. It will be used to protect
1334 * all fops and v4l2 ioctls.
1335 */
1336 vfd->lock = &dev->mutex;
1337 video_set_drvdata(vfd, dev);
1338
1339 ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr);
1340 if (ret < 0)
1341 goto unreg_dev;
1342
1343 /* Now that everything is fine, let's add it to device list */
1344 list_add_tail(&dev->vivi_devlist, &vivi_devlist);
1345
1346 v4l2_info(&dev->v4l2_dev, "V4L2 device registered as %s\n",
1347 video_device_node_name(vfd));
1348 return 0;
1349
1350unreg_dev:
1351 v4l2_ctrl_handler_free(hdl);
1352 v4l2_device_unregister(&dev->v4l2_dev);
1353free_dev:
1354 kfree(dev);
1355 return ret;
1356}
1357
1358/* This routine allocates from 1 to n_devs virtual drivers.
1359
1360 The real maximum number of virtual drivers will depend on how many drivers
1361 will succeed. This is limited to the maximum number of devices that
1362 videodev supports, which is equal to VIDEO_NUM_DEVICES.
1363 */
1364static int __init vivi_init(void)
1365{
1366 const struct font_desc *font = find_font("VGA8x16");
1367 int ret = 0, i;
1368
1369 if (font == NULL) {
1370 printk(KERN_ERR "vivi: could not find font\n");
1371 return -ENODEV;
1372 }
1373 font8x16 = font->data;
1374
1375 if (n_devs <= 0)
1376 n_devs = 1;
1377
1378 for (i = 0; i < n_devs; i++) {
1379 ret = vivi_create_instance(i);
1380 if (ret) {
1381 /* If some instantiations succeeded, keep driver */
1382 if (i)
1383 ret = 0;
1384 break;
1385 }
1386 }
1387
1388 if (ret < 0) {
1389 printk(KERN_ERR "vivi: error %d while loading driver\n", ret);
1390 return ret;
1391 }
1392
1393 printk(KERN_INFO "Video Technology Magazine Virtual Video "
1394 "Capture Board ver %s successfully loaded.\n",
1395 VIVI_VERSION);
1396
1397 /* n_devs will reflect the actual number of allocated devices */
1398 n_devs = i;
1399
1400 return ret;
1401}
1402
1403static void __exit vivi_exit(void)
1404{
1405 vivi_release();
1406}
1407
1408module_init(vivi_init);
1409module_exit(vivi_exit);