13 #include <linux/errno.h>
15 #include <linux/i2c.h>
18 #include <linux/kernel.h>
21 #include <linux/slab.h>
22 #include <linux/videodev2.h>
23 #include <linux/module.h>
60 #define VOU_MAX_IMAGE_WIDTH 720
61 #define VOU_MAX_IMAGE_HEIGHT 576
86 static void sh_vou_reg_a_write(
struct sh_vou_device *vou_dev,
unsigned int reg,
92 static void sh_vou_reg_ab_write(
struct sh_vou_device *vou_dev,
unsigned int reg,
99 static void sh_vou_reg_m_write(
struct sh_vou_device *vou_dev,
unsigned int reg,
110 static void sh_vou_reg_a_set(
struct sh_vou_device *vou_dev,
unsigned int reg,
115 value = (value &
mask) | (old & ~mask);
119 static void sh_vou_reg_b_set(
struct sh_vou_device *vou_dev,
unsigned int reg,
122 sh_vou_reg_a_set(vou_dev, reg + 0x1000, value, mask);
125 static void sh_vou_reg_ab_set(
struct sh_vou_device *vou_dev,
unsigned int reg,
128 sh_vou_reg_a_set(vou_dev, reg, value, mask);
129 sh_vou_reg_b_set(vou_dev, reg, value, mask);
146 .desc =
"YVU420 planar",
153 .desc =
"YVYU planar",
174 .desc =
"RGB565 byteswapped",
180 static void sh_vou_schedule_next(
struct sh_vou_device *vou_dev,
186 switch (vou_dev->
pix.pixelformat) {
189 addr2 = addr1 + vou_dev->
pix.width * vou_dev->
pix.height;
195 sh_vou_reg_m_write(vou_dev,
VOUAD1R, addr1);
196 sh_vou_reg_m_write(vou_dev,
VOUAD2R, addr2);
199 static void sh_vou_stream_start(
struct sh_vou_device *vou_dev,
202 unsigned int row_coeff;
203 #ifdef __LITTLE_ENDIAN
209 switch (vou_dev->
pix.pixelformat) {
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);
247 vou_dev->
pix.height / 8;
253 if (
PAGE_ALIGN(*size) * *count > 4 * 1024 * 1024)
256 dev_dbg(vq->
dev,
"%s(): count=%d, size=%d\n", __func__, *count, *size);
287 dev_warn(vq->
dev,
"User buffer too small: [%u] @ %lx\n",
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,
324 }
else if (!vou_dev->
active) {
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);
332 }
else if (vou_dev->
active->queue.next == &vb->
queue) {
334 sh_vou_reg_a_write(vou_dev,
VOURPR, 0);
335 sh_vou_stream_start(vou_dev, vb);
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));
343 sh_vou_reg_a_write(vou_dev,
VOUIR, 0x10004);
347 sh_vou_reg_a_write(vou_dev,
VOUER, 0x107);
362 if (vou_dev->
active == vb) {
364 sh_vou_reg_a_set(vou_dev,
VOUER, 0, 1);
366 sh_vou_reg_a_set(vou_dev,
VOUIR, 0, 0x30000);
375 spin_unlock_irqrestore(&vou_dev->
lock, flags);
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,
388 static int sh_vou_querycap(
struct file *
file,
void *
priv,
393 dev_dbg(vou_file->
vbq.dev,
"%s()\n", __func__);
401 static int sh_vou_enum_fmt_vid_out(
struct file *
file,
void *
priv,
409 dev_dbg(vou_file->
vbq.dev,
"%s()\n", __func__);
419 static int sh_vou_g_fmt_vid_out(
struct file *file,
void *priv,
433 static const unsigned char vou_scale_h_num[] = {1, 9, 2, 9, 4};
434 static const unsigned char vou_scale_h_den[] = {1, 8, 1, 4, 1};
435 static const unsigned char vou_scale_h_fld[] = {0, 2, 1, 3};
436 static const unsigned char vou_scale_v_num[] = {1, 2, 4};
437 static const unsigned char vou_scale_v_den[] = {1, 1, 1};
438 static const unsigned char vou_scale_v_fld[] = {0, 1};
440 static void sh_vou_configure_geometry(
struct sh_vou_device *vou_dev,
441 int pix_idx,
int w_idx,
int h_idx)
444 unsigned int black_left, black_top, width_max, height_max,
445 frame_in_height, frame_out_height, frame_out_top;
448 u32 vouvcr = 0, dsr_h, dsr_v;
458 frame_in_height = pix->
height / 2;
459 frame_out_height = rect->
height / 2;
460 frame_out_top = rect->
top / 2;
485 dsr_v = frame_out_height + frame_out_top;
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);
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);
504 vouvcr |= (1 << 15) | (vou_scale_h_fld[w_idx - 1] << 4);
506 vouvcr |= (1 << 14) | vou_scale_v_fld[h_idx - 1];
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));
531 unsigned int best_err =
UINT_MAX, best = 0, img_height_max;
535 img_height_max = 480;
537 img_height_max = 576;
541 &geo->
in_height, 0, img_height_max, 1, 0);
544 for (i =
ARRAY_SIZE(vou_scale_h_num) - 1; i >= 0; i--) {
546 unsigned int found = geo->
output.width * vou_scale_h_den[
i] /
549 if (found > VOU_MAX_IMAGE_WIDTH)
554 if (err < best_err) {
569 for (i =
ARRAY_SIZE(vou_scale_v_num) - 1; i >= 0; i--) {
571 unsigned int found = geo->
output.height * vou_scale_v_den[
i] /
574 if (found > img_height_max)
579 if (err < best_err) {
598 unsigned int best_err =
UINT_MAX, best, width_max, height_max,
602 if (std & V4L2_STD_525_60) {
604 height_max = 262 * 2;
605 img_height_max = 480;
608 height_max = 312 * 2;
609 img_height_max = 576;
613 for (i = 0; i <
ARRAY_SIZE(vou_scale_h_num); i++) {
615 unsigned int found = geo->
in_width * vou_scale_h_num[
i] /
618 if (found > VOU_MAX_IMAGE_WIDTH)
623 if (err < best_err) {
634 if (geo->
output.left + best > width_max)
635 geo->
output.left = width_max - best;
638 vou_scale_h_num[idx], vou_scale_h_den[idx], best);
643 for (i = 0; i <
ARRAY_SIZE(vou_scale_v_num); i++) {
645 unsigned int found = geo->
in_height * vou_scale_v_num[
i] /
648 if (found > img_height_max)
653 if (err < best_err) {
662 geo->
output.height = best;
664 if (geo->
output.top + best > height_max)
665 geo->
output.top = height_max - best;
668 vou_scale_v_num[idx], vou_scale_v_den[idx], best);
671 static int sh_vou_s_fmt_vid_out(
struct file *file,
void *priv,
677 unsigned int img_height_max;
680 struct v4l2_mbus_framefmt mbfmt = {
689 vou_dev->
rect.width, vou_dev->
rect.height,
699 for (pix_idx = 0; pix_idx <
ARRAY_SIZE(vou_fmt); pix_idx++)
706 if (vou_dev->
std & V4L2_STD_525_60)
707 img_height_max = 480;
709 img_height_max = 576;
713 &pix->
height, 0, img_height_max, 1, 0);
719 vou_adjust_output(&geo, vou_dev->
std);
721 mbfmt.width = geo.
output.width;
722 mbfmt.height = geo.
output.height;
730 geo.
output.width, geo.
output.height, mbfmt.width, mbfmt.height);
733 if ((
unsigned)mbfmt.width > VOU_MAX_IMAGE_WIDTH ||
734 (
unsigned)mbfmt.height > img_height_max ||
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;
743 vou_adjust_input(&geo, vou_dev->
std);
758 sh_vou_configure_geometry(vou_dev, pix_idx,
764 static int sh_vou_try_fmt_vid_out(
struct file *file,
void *priv,
771 dev_dbg(vou_file->
vbq.dev,
"%s()\n", __func__);
788 static int sh_vou_reqbufs(
struct file *file,
void *priv,
793 dev_dbg(vou_file->
vbq.dev,
"%s()\n", __func__);
801 static int sh_vou_querybuf(
struct file *file,
void *priv,
806 dev_dbg(vou_file->
vbq.dev,
"%s()\n", __func__);
811 static int sh_vou_qbuf(
struct file *file,
void *priv,
struct v4l2_buffer *
b)
815 dev_dbg(vou_file->
vbq.dev,
"%s()\n", __func__);
820 static int sh_vou_dqbuf(
struct file *file,
void *priv,
struct v4l2_buffer *
b)
824 dev_dbg(vou_file->
vbq.dev,
"%s()\n", __func__);
829 static int sh_vou_streamon(
struct file *file,
void *priv,
837 dev_dbg(vou_file->
vbq.dev,
"%s()\n", __func__);
848 static int sh_vou_streamoff(
struct file *file,
void *priv,
855 dev_dbg(vou_file->
vbq.dev,
"%s()\n", __func__);
871 pr_warning(
"%s(): Invalid bus-format code %d, using default 8-bit\n",
882 static int sh_vou_s_std(
struct file *file,
void *priv,
v4l2_std_id *std_id)
894 s_std_output, *std_id);
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);
903 sh_vou_reg_ab_set(vou_dev,
VOUCR, 5 << 29, 7 << 29);
905 vou_dev->
std = *std_id;
910 static int sh_vou_g_std(
struct file *file,
void *priv,
v4l2_std_id *std)
922 static int sh_vou_g_crop(
struct file *file,
void *fh,
struct v4l2_crop *
a)
930 a->
c = vou_dev->
rect;
936 static int sh_vou_s_crop(
struct file *file,
void *fh,
const struct v4l2_crop *
a)
945 struct v4l2_mbus_framefmt mbfmt = {
951 unsigned int img_height_max;
960 if (vou_dev->
std & V4L2_STD_525_60)
961 img_height_max = 480;
963 img_height_max = 576;
966 &rect->
height, 0, img_height_max, 1, 0);
968 if (rect->
width + rect->
left > VOU_MAX_IMAGE_WIDTH)
969 rect->
left = VOU_MAX_IMAGE_WIDTH - rect->
width;
971 if (rect->
height + rect->
top > img_height_max)
972 rect->
top = img_height_max - rect->
height;
979 sd_crop.
c.width = geo.
output.width;
980 sd_crop.
c.height = geo.
output.height;
987 mbfmt.width = geo.
output.width;
988 mbfmt.height = geo.
output.height;
996 if ((
unsigned)mbfmt.width > VOU_MAX_IMAGE_WIDTH ||
997 (
unsigned)mbfmt.height > img_height_max ||
1001 geo.
output.width = mbfmt.width;
1002 geo.
output.height = mbfmt.height;
1008 vou_adjust_input(&geo, vou_dev->
std);
1015 sh_vou_configure_geometry(vou_dev, vou_dev->
pix_idx,
1028 static int sh_vou_cropcap(
struct file *file,
void *priv,
1033 dev_dbg(vou_file->
vbq.dev,
"%s()\n", __func__);
1054 static unsigned long j;
1058 u32 irq_status = sh_vou_reg_a_read(vou_dev,
VOUIR), masked;
1059 u32 vou_status = sh_vou_reg_a_read(vou_dev,
VOUSTR);
1061 if (!(irq_status & 0x300)) {
1062 if (printk_timed_ratelimit(&j, 500))
1068 spin_lock(&vou_dev->
lock);
1069 if (!vou_dev->
active || list_empty(&vou_dev->
queue)) {
1070 if (printk_timed_ratelimit(&j, 500))
1072 "IRQ without active buffer: %x!\n", irq_status);
1074 sh_vou_reg_a_set(vou_dev,
VOUIR, 0, 0x300);
1075 spin_unlock(&vou_dev->
lock);
1079 masked = ~(0x300 & irq_status) & irq_status & 0x30304;
1081 "IRQ status 0x%x -> 0x%x, VOU status 0x%x, cnt %d\n",
1082 irq_status, masked, vou_status, cnt);
1085 side = vou_status & 0x10000;
1088 sh_vou_reg_a_write(vou_dev,
VOUIR, masked);
1098 if (list_empty(&vou_dev->
queue)) {
1102 sh_vou_reg_a_set(vou_dev,
VOUER, 0, 1);
1106 sh_vou_reg_a_set(vou_dev,
VOUIR, 0, 0x30000);
1107 spin_unlock(&vou_dev->
lock);
1114 if (vou_dev->
active->queue.next != &vou_dev->
queue) {
1117 sh_vou_schedule_next(vou_dev,
new);
1120 spin_unlock(&vou_dev->
lock);
1128 u32 voucr = sh_vou_ntsc_mode(pdata->
bus_fmt) << 29;
1132 sh_vou_reg_a_write(vou_dev,
VOUIR, 0);
1135 sh_vou_reg_a_write(vou_dev,
VOUSRR, 0x101);
1136 while (--i && (sh_vou_reg_a_read(vou_dev,
VOUSRR) & 0x101))
1150 sh_vou_reg_ab_set(vou_dev,
VOUCR, voucr, 0xfc000000);
1153 sh_vou_reg_a_write(vou_dev,
VOURCR, 4);
1155 sh_vou_reg_ab_write(vou_dev,
VOUMSR, 0x800000);
1161 static int sh_vou_open(
struct file *file)
1181 pm_runtime_get_sync(vdev->
v4l2_dev->dev);
1182 ret = sh_vou_hw_init(vou_dev);
1185 pm_runtime_put(vdev->
v4l2_dev->dev);
1203 static int sh_vou_release(
struct file *file)
1209 dev_dbg(vou_file->
vbq.dev,
"%s()\n", __func__);
1215 sh_vou_reg_a_set(vou_dev,
VOUER, 0, 0x101);
1216 pm_runtime_put(vdev->
v4l2_dev->dev);
1226 static int sh_vou_mmap(
struct file *file,
struct vm_area_struct *vma)
1233 dev_dbg(vou_file->
vbq.dev,
"%s()\n", __func__);
1242 static unsigned int sh_vou_poll(
struct file *file,
poll_table *
wait)
1249 dev_dbg(vou_file->
vbq.dev,
"%s()\n", __func__);
1257 static int sh_vou_g_chip_ident(
struct file *file,
void *fh,
1266 #ifdef CONFIG_VIDEO_ADV_DEBUG
1267 static int sh_vou_g_register(
struct file *file,
void *fh,
1276 static int sh_vou_s_register(
struct file *file,
void *fh,
1288 .vidioc_querycap = sh_vou_querycap,
1289 .vidioc_enum_fmt_vid_out = sh_vou_enum_fmt_vid_out,
1290 .vidioc_g_fmt_vid_out = sh_vou_g_fmt_vid_out,
1291 .vidioc_s_fmt_vid_out = sh_vou_s_fmt_vid_out,
1292 .vidioc_try_fmt_vid_out = sh_vou_try_fmt_vid_out,
1293 .vidioc_reqbufs = sh_vou_reqbufs,
1294 .vidioc_querybuf = sh_vou_querybuf,
1295 .vidioc_qbuf = sh_vou_qbuf,
1296 .vidioc_dqbuf = sh_vou_dqbuf,
1297 .vidioc_streamon = sh_vou_streamon,
1298 .vidioc_streamoff = sh_vou_streamoff,
1299 .vidioc_s_std = sh_vou_s_std,
1300 .vidioc_g_std = sh_vou_g_std,
1301 .vidioc_cropcap = sh_vou_cropcap,
1302 .vidioc_g_crop = sh_vou_g_crop,
1303 .vidioc_s_crop = sh_vou_s_crop,
1304 .vidioc_g_chip_ident = sh_vou_g_chip_ident,
1305 #ifdef CONFIG_VIDEO_ADV_DEBUG
1306 .vidioc_g_register = sh_vou_g_register,
1307 .vidioc_s_register = sh_vou_s_register,
1313 .open = sh_vou_open,
1314 .release = sh_vou_release,
1316 .mmap = sh_vou_mmap,
1317 .poll = sh_vou_poll,
1320 static const struct video_device sh_vou_video_template = {
1322 .fops = &sh_vou_fops,
1323 .ioctl_ops = &sh_vou_ioctl_ops,
1344 if (!vou_pdata || !reg_res || irq <= 0) {
1345 dev_err(&pdev->
dev,
"Insufficient VOU platform information.\n");
1349 vou_dev = kzalloc(
sizeof(*vou_dev),
GFP_KERNEL);
1353 INIT_LIST_HEAD(&vou_dev->
queue);
1357 vou_dev->
pdata = vou_pdata;
1360 rect = &vou_dev->
rect;
1361 pix = &vou_dev->
pix;
1374 pix->
sizeimage = VOU_MAX_IMAGE_WIDTH * 2 * 480;
1380 dev_err(&pdev->
dev,
"VOU region already claimed\n");
1386 if (!vou_dev->
base) {
1391 ret =
request_irq(irq, sh_vou_isr, 0,
"vou", vou_dev);
1397 dev_err(&pdev->
dev,
"Error registering v4l2 device\n");
1408 *vdev = sh_vou_video_template;
1415 vou_dev->
vdev = vdev;
1416 video_set_drvdata(vdev, vou_dev);
1419 pm_runtime_resume(&pdev->
dev);
1427 ret = sh_vou_hw_init(vou_dev);
1450 pm_runtime_disable(&pdev->
dev);
1467 struct v4l2_device *v4l2_dev = platform_get_drvdata(pdev);
1477 pm_runtime_disable(&pdev->
dev);
1497 static int __init sh_vou_init(
void)
1502 static void __exit sh_vou_exit(
void)