1/* 2 * Xilinx Video IP Core 3 * 4 * Copyright (C) 2013-2015 Ideas on Board 5 * Copyright (C) 2013-2015 Xilinx, Inc. 6 * 7 * Contacts: Hyun Kwon <hyun.kwon@xilinx.com> 8 * Laurent Pinchart <laurent.pinchart@ideasonboard.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 __XILINX_VIP_H__ 16#define __XILINX_VIP_H__ 17 18#include <linux/io.h> 19#include <media/v4l2-subdev.h> 20 21struct clk; 22 23/* 24 * Minimum and maximum width and height common to most video IP cores. IP 25 * cores with different requirements must define their own values. 26 */ 27#define XVIP_MIN_WIDTH 32 28#define XVIP_MAX_WIDTH 7680 29#define XVIP_MIN_HEIGHT 32 30#define XVIP_MAX_HEIGHT 7680 31 32/* 33 * Pad IDs. IP cores with with multiple inputs or outputs should define 34 * their own values. 35 */ 36#define XVIP_PAD_SINK 0 37#define XVIP_PAD_SOURCE 1 38 39/* Xilinx Video IP Control Registers */ 40#define XVIP_CTRL_CONTROL 0x0000 41#define XVIP_CTRL_CONTROL_SW_ENABLE (1 << 0) 42#define XVIP_CTRL_CONTROL_REG_UPDATE (1 << 1) 43#define XVIP_CTRL_CONTROL_BYPASS (1 << 4) 44#define XVIP_CTRL_CONTROL_TEST_PATTERN (1 << 5) 45#define XVIP_CTRL_CONTROL_FRAME_SYNC_RESET (1 << 30) 46#define XVIP_CTRL_CONTROL_SW_RESET (1 << 31) 47#define XVIP_CTRL_STATUS 0x0004 48#define XVIP_CTRL_STATUS_PROC_STARTED (1 << 0) 49#define XVIP_CTRL_STATUS_EOF (1 << 1) 50#define XVIP_CTRL_ERROR 0x0008 51#define XVIP_CTRL_ERROR_SLAVE_EOL_EARLY (1 << 0) 52#define XVIP_CTRL_ERROR_SLAVE_EOL_LATE (1 << 1) 53#define XVIP_CTRL_ERROR_SLAVE_SOF_EARLY (1 << 2) 54#define XVIP_CTRL_ERROR_SLAVE_SOF_LATE (1 << 3) 55#define XVIP_CTRL_IRQ_ENABLE 0x000c 56#define XVIP_CTRL_IRQ_ENABLE_PROC_STARTED (1 << 0) 57#define XVIP_CTRL_IRQ_EOF (1 << 1) 58#define XVIP_CTRL_VERSION 0x0010 59#define XVIP_CTRL_VERSION_MAJOR_MASK (0xff << 24) 60#define XVIP_CTRL_VERSION_MAJOR_SHIFT 24 61#define XVIP_CTRL_VERSION_MINOR_MASK (0xff << 16) 62#define XVIP_CTRL_VERSION_MINOR_SHIFT 16 63#define XVIP_CTRL_VERSION_REVISION_MASK (0xf << 12) 64#define XVIP_CTRL_VERSION_REVISION_SHIFT 12 65#define XVIP_CTRL_VERSION_PATCH_MASK (0xf << 8) 66#define XVIP_CTRL_VERSION_PATCH_SHIFT 8 67#define XVIP_CTRL_VERSION_INTERNAL_MASK (0xff << 0) 68#define XVIP_CTRL_VERSION_INTERNAL_SHIFT 0 69 70/* Xilinx Video IP Timing Registers */ 71#define XVIP_ACTIVE_SIZE 0x0020 72#define XVIP_ACTIVE_VSIZE_MASK (0x7ff << 16) 73#define XVIP_ACTIVE_VSIZE_SHIFT 16 74#define XVIP_ACTIVE_HSIZE_MASK (0x7ff << 0) 75#define XVIP_ACTIVE_HSIZE_SHIFT 0 76#define XVIP_ENCODING 0x0028 77#define XVIP_ENCODING_NBITS_8 (0 << 4) 78#define XVIP_ENCODING_NBITS_10 (1 << 4) 79#define XVIP_ENCODING_NBITS_12 (2 << 4) 80#define XVIP_ENCODING_NBITS_16 (3 << 4) 81#define XVIP_ENCODING_NBITS_MASK (3 << 4) 82#define XVIP_ENCODING_NBITS_SHIFT 4 83#define XVIP_ENCODING_VIDEO_FORMAT_YUV422 (0 << 0) 84#define XVIP_ENCODING_VIDEO_FORMAT_YUV444 (1 << 0) 85#define XVIP_ENCODING_VIDEO_FORMAT_RGB (2 << 0) 86#define XVIP_ENCODING_VIDEO_FORMAT_YUV420 (3 << 0) 87#define XVIP_ENCODING_VIDEO_FORMAT_MASK (3 << 0) 88#define XVIP_ENCODING_VIDEO_FORMAT_SHIFT 0 89 90/** 91 * struct xvip_device - Xilinx Video IP device structure 92 * @subdev: V4L2 subdevice 93 * @dev: (OF) device 94 * @iomem: device I/O register space remapped to kernel virtual memory 95 * @clk: video core clock 96 * @saved_ctrl: saved control register for resume / suspend 97 */ 98struct xvip_device { 99 struct v4l2_subdev subdev; 100 struct device *dev; 101 void __iomem *iomem; 102 struct clk *clk; 103 u32 saved_ctrl; 104}; 105 106/** 107 * struct xvip_video_format - Xilinx Video IP video format description 108 * @vf_code: AXI4 video format code 109 * @width: AXI4 format width in bits per component 110 * @pattern: CFA pattern for Mono/Sensor formats 111 * @code: media bus format code 112 * @bpp: bytes per pixel (when stored in memory) 113 * @fourcc: V4L2 pixel format FCC identifier 114 * @description: format description, suitable for userspace 115 */ 116struct xvip_video_format { 117 unsigned int vf_code; 118 unsigned int width; 119 const char *pattern; 120 unsigned int code; 121 unsigned int bpp; 122 u32 fourcc; 123 const char *description; 124}; 125 126const struct xvip_video_format *xvip_get_format_by_code(unsigned int code); 127const struct xvip_video_format *xvip_get_format_by_fourcc(u32 fourcc); 128const struct xvip_video_format *xvip_of_get_format(struct device_node *node); 129void xvip_set_format_size(struct v4l2_mbus_framefmt *format, 130 const struct v4l2_subdev_format *fmt); 131int xvip_enum_mbus_code(struct v4l2_subdev *subdev, 132 struct v4l2_subdev_pad_config *cfg, 133 struct v4l2_subdev_mbus_code_enum *code); 134int xvip_enum_frame_size(struct v4l2_subdev *subdev, 135 struct v4l2_subdev_pad_config *cfg, 136 struct v4l2_subdev_frame_size_enum *fse); 137 138static inline u32 xvip_read(struct xvip_device *xvip, u32 addr) 139{ 140 return ioread32(xvip->iomem + addr); 141} 142 143static inline void xvip_write(struct xvip_device *xvip, u32 addr, u32 value) 144{ 145 iowrite32(value, xvip->iomem + addr); 146} 147 148static inline void xvip_clr(struct xvip_device *xvip, u32 addr, u32 clr) 149{ 150 xvip_write(xvip, addr, xvip_read(xvip, addr) & ~clr); 151} 152 153static inline void xvip_set(struct xvip_device *xvip, u32 addr, u32 set) 154{ 155 xvip_write(xvip, addr, xvip_read(xvip, addr) | set); 156} 157 158void xvip_clr_or_set(struct xvip_device *xvip, u32 addr, u32 mask, bool set); 159void xvip_clr_and_set(struct xvip_device *xvip, u32 addr, u32 clr, u32 set); 160 161int xvip_init_resources(struct xvip_device *xvip); 162void xvip_cleanup_resources(struct xvip_device *xvip); 163 164static inline void xvip_reset(struct xvip_device *xvip) 165{ 166 xvip_write(xvip, XVIP_CTRL_CONTROL, XVIP_CTRL_CONTROL_SW_RESET); 167} 168 169static inline void xvip_start(struct xvip_device *xvip) 170{ 171 xvip_set(xvip, XVIP_CTRL_CONTROL, 172 XVIP_CTRL_CONTROL_SW_ENABLE | XVIP_CTRL_CONTROL_REG_UPDATE); 173} 174 175static inline void xvip_stop(struct xvip_device *xvip) 176{ 177 xvip_clr(xvip, XVIP_CTRL_CONTROL, XVIP_CTRL_CONTROL_SW_ENABLE); 178} 179 180static inline void xvip_resume(struct xvip_device *xvip) 181{ 182 xvip_write(xvip, XVIP_CTRL_CONTROL, 183 xvip->saved_ctrl | XVIP_CTRL_CONTROL_SW_ENABLE); 184} 185 186static inline void xvip_suspend(struct xvip_device *xvip) 187{ 188 xvip->saved_ctrl = xvip_read(xvip, XVIP_CTRL_CONTROL); 189 xvip_write(xvip, XVIP_CTRL_CONTROL, 190 xvip->saved_ctrl & ~XVIP_CTRL_CONTROL_SW_ENABLE); 191} 192 193static inline void xvip_set_frame_size(struct xvip_device *xvip, 194 const struct v4l2_mbus_framefmt *format) 195{ 196 xvip_write(xvip, XVIP_ACTIVE_SIZE, 197 (format->height << XVIP_ACTIVE_VSIZE_SHIFT) | 198 (format->width << XVIP_ACTIVE_HSIZE_SHIFT)); 199} 200 201static inline void xvip_get_frame_size(struct xvip_device *xvip, 202 struct v4l2_mbus_framefmt *format) 203{ 204 u32 reg; 205 206 reg = xvip_read(xvip, XVIP_ACTIVE_SIZE); 207 format->width = (reg & XVIP_ACTIVE_HSIZE_MASK) >> 208 XVIP_ACTIVE_HSIZE_SHIFT; 209 format->height = (reg & XVIP_ACTIVE_VSIZE_MASK) >> 210 XVIP_ACTIVE_VSIZE_SHIFT; 211} 212 213static inline void xvip_enable_reg_update(struct xvip_device *xvip) 214{ 215 xvip_set(xvip, XVIP_CTRL_CONTROL, XVIP_CTRL_CONTROL_REG_UPDATE); 216} 217 218static inline void xvip_disable_reg_update(struct xvip_device *xvip) 219{ 220 xvip_clr(xvip, XVIP_CTRL_CONTROL, XVIP_CTRL_CONTROL_REG_UPDATE); 221} 222 223static inline void xvip_print_version(struct xvip_device *xvip) 224{ 225 u32 version; 226 227 version = xvip_read(xvip, XVIP_CTRL_VERSION); 228 229 dev_info(xvip->dev, "device found, version %u.%02x%x\n", 230 ((version & XVIP_CTRL_VERSION_MAJOR_MASK) >> 231 XVIP_CTRL_VERSION_MAJOR_SHIFT), 232 ((version & XVIP_CTRL_VERSION_MINOR_MASK) >> 233 XVIP_CTRL_VERSION_MINOR_SHIFT), 234 ((version & XVIP_CTRL_VERSION_REVISION_MASK) >> 235 XVIP_CTRL_VERSION_REVISION_SHIFT)); 236} 237 238#endif /* __XILINX_VIP_H__ */ 239