// SPDX-License-Identifier: GPL-2.0
/*
* SuperH Video Output Unit (VOU) driver
*
* Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
*/
#include <linux/dma-mapping.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/slab.h>
#include <linux/videodev2.h>
#include <linux/module.h>
#include <media/drv-intf/sh_vou.h>
#include <media/v4l2-common.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-mediabus.h>
#include <media/videobuf2-v4l2.h>
#include <media/videobuf2-dma-contig.h>
/* Mirror addresses are not available for all registers */
#define VOUER 0
#define VOUCR 4
#define VOUSTR 8
#define VOUVCR 0xc
#define VOUISR 0x10
#define VOUBCR 0x14
#define VOUDPR 0x18
#define VOUDSR 0x1c
#define VOUVPR 0x20
#define VOUIR 0x24
#define VOUSRR 0x28
#define VOUMSR 0x2c
#define VOUHIR 0x30
#define VOUDFR 0x34
#define VOUAD1R 0x38
#define VOUAD2R 0x3c
#define VOUAIR 0x40
#define VOUSWR 0x44
#define VOURCR 0x48
#define VOURPR 0x50
enum sh_vou_status {
SH_VOU_IDLE,
SH_VOU_INITIALISING,
SH_VOU_RUNNING,
};
#define VOU_MIN_IMAGE_WIDTH 16
#define VOU_MAX_IMAGE_WIDTH 720
#define VOU_MIN_IMAGE_HEIGHT 16
struct sh_vou_buffer {
struct vb2_v4l2_buffer vb;
struct list_head list;
};
static inline struct
sh_vou_buffer *to_sh_vou_buffer(struct vb2_v4l2_buffer *vb2)
{
return container_of(vb2, struct sh_vou_buffer, vb);
}
struct sh_vou_device {
struct v4l2_device v4l2_dev;
struct video_device vdev;
struct sh_vou_pdata *pdata;
spinlock_t lock;
void __iomem *base;
/* State information */
struct v4l2_pix_format pix;
struct v4l2_rect rect;
struct list_head buf_list;
v4l2_std_id std;
int pix_idx;
struct vb2_queue queue;
struct sh_vou_buffer *active;
enum sh_vou_status status;
unsigned sequence;
struct mutex fop_lock;
};
/* Register access routines for sides A, B and mirror addresses */
static void sh_vou_reg_a_write(struct sh_vou_device *vou_dev, unsigned int reg,
u32 value)
{
__raw_writel(value, vou_dev->base + reg);
}
static void sh_vou_reg_ab_write(struct sh_vou_device *vou_dev, unsigned int reg,
u32 value)
{
__raw_writel(value, vou_dev-