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/irqreturn.h> 23#include <linux/kernel.h> 24#include <linux/spinlock.h> 25#include <linux/wait.h> 26#include <media/v4l2-device.h> 27#include <media/videobuf2-v4l2.h> 28 29#include "regs-mixer.h" 30 31/** maximum number of output interfaces */ 32#define MXR_MAX_OUTPUTS 2 33/** maximum number of input interfaces (layers) */ 34#define MXR_MAX_LAYERS 3 35#define MXR_DRIVER_NAME "s5p-mixer" 36/** maximal number of planes for every layer */ 37#define MXR_MAX_PLANES 2 38 39#define MXR_ENABLE 1 40#define MXR_DISABLE 0 41 42/** description of a macroblock for packed formats */ 43struct mxr_block { 44 /** vertical number of pixels in macroblock */ 45 unsigned int width; 46 /** horizontal number of pixels in macroblock */ 47 unsigned int height; 48 /** size of block in bytes */ 49 unsigned int size; 50}; 51 52/** description of supported format */ 53struct mxr_format { 54 /** format name/mnemonic */ 55 const char *name; 56 /** fourcc identifier */ 57 u32 fourcc; 58 /** colorspace identifier */ 59 enum v4l2_colorspace colorspace; 60 /** number of planes in image data */ 61 int num_planes; 62 /** description of block for each plane */ 63 struct mxr_block plane[MXR_MAX_PLANES]; 64 /** number of subframes in image data */ 65 int num_subframes; 66 /** specifies to which subframe belong given plane */ 67 int plane2subframe[MXR_MAX_PLANES]; 68 /** internal code, driver dependent */ 69 unsigned long cookie; 70}; 71 72/** description of crop configuration for image */ 73struct mxr_crop { 74 /** width of layer in pixels */ 75 unsigned int full_width; 76 /** height of layer in pixels */ 77 unsigned int full_height; 78 /** horizontal offset of first pixel to be displayed */ 79 unsigned int x_offset; 80 /** vertical offset of first pixel to be displayed */ 81 unsigned int y_offset; 82 /** width of displayed data in pixels */ 83 unsigned int width; 84 /** height of displayed data in pixels */ 85 unsigned int height; 86 /** indicate which fields are present in buffer */ 87 unsigned int field; 88}; 89 90/** stages of geometry operations */ 91enum mxr_geometry_stage { 92 MXR_GEOMETRY_SINK, 93 MXR_GEOMETRY_COMPOSE, 94 MXR_GEOMETRY_CROP, 95 MXR_GEOMETRY_SOURCE, 96}; 97 98/* flag indicating that offset should be 0 */ 99#define MXR_NO_OFFSET 0x80000000 100 101/** description of transformation from source to destination image */ 102struct mxr_geometry { 103 /** cropping for source image */ 104 struct mxr_crop src; 105 /** cropping for destination image */ 106 struct mxr_crop dst; 107 /** layer-dependant description of horizontal scaling */ 108 unsigned int x_ratio; 109 /** layer-dependant description of vertical scaling */ 110 unsigned int y_ratio; 111}; 112 113/** instance of a buffer */ 114struct mxr_buffer { 115 /** common v4l buffer stuff -- must be first */ 116 struct vb2_v4l2_buffer vb; 117 /** node for layer's lists */ 118 struct list_head list; 119}; 120 121 122/** internal states of layer */ 123enum mxr_layer_state { 124 /** layers is not shown */ 125 MXR_LAYER_IDLE = 0, 126 /** layer is shown */ 127 MXR_LAYER_STREAMING, 128 /** state before STREAMOFF is finished */ 129 MXR_LAYER_STREAMING_FINISH, 130}; 131 132/** forward declarations */ 133struct mxr_device; 134struct mxr_layer; 135 136/** callback for layers operation */ 137struct mxr_layer_ops { 138 /* TODO: try to port it to subdev API */ 139 /** handler for resource release function */ 140 void (*release)(struct mxr_layer *); 141 /** setting buffer to HW */ 142 void (*buffer_set)(struct mxr_layer *, struct mxr_buffer *); 143 /** setting format and geometry in HW */ 144 void (*format_set)(struct mxr_layer *); 145 /** streaming stop/start */ 146 void (*stream_set)(struct mxr_layer *, int); 147 /** adjusting geometry */ 148 void (*fix_geometry)(struct mxr_layer *, 149 enum mxr_geometry_stage, unsigned long); 150}; 151 152/** layer instance, a single window and content displayed on output */ 153struct mxr_layer { 154 /** parent mixer device */ 155 struct mxr_device *mdev; 156 /** layer index (unique identifier) */ 157 int idx; 158 /** callbacks for layer methods */ 159 struct mxr_layer_ops ops; 160 /** format array */ 161 const struct mxr_format **fmt_array; 162 /** size of format array */ 163 unsigned long fmt_array_size; 164 165 /** lock for protection of list and state fields */ 166 spinlock_t enq_slock; 167 /** list for enqueued buffers */ 168 struct list_head enq_list; 169 /** buffer currently owned by hardware in temporary registers */ 170 struct mxr_buffer *update_buf; 171 /** buffer currently owned by hardware in shadow registers */ 172 struct mxr_buffer *shadow_buf; 173 /** state of layer IDLE/STREAMING */ 174 enum mxr_layer_state state; 175 176 /** mutex for protection of fields below */ 177 struct mutex mutex; 178 /** handler for video node */ 179 struct video_device vfd; 180 /** queue for output buffers */ 181 struct vb2_queue vb_queue; 182 /** current image format */ 183 const struct mxr_format *fmt; 184 /** current geometry of image */ 185 struct mxr_geometry geo; 186}; 187 188/** description of mixers output interface */ 189struct mxr_output { 190 /** name of output */ 191 char name[32]; 192 /** output subdev */ 193 struct v4l2_subdev *sd; 194 /** cookie used for configuration of registers */ 195 int cookie; 196}; 197 198/** specify source of output subdevs */ 199struct mxr_output_conf { 200 /** name of output (connector) */ 201 char *output_name; 202 /** name of module that generates output subdev */ 203 char *module_name; 204 /** cookie need for mixer HW */ 205 int cookie; 206}; 207 208struct clk; 209struct regulator; 210 211/** auxiliary resources used my mixer */ 212struct mxr_resources { 213 /** interrupt index */ 214 int irq; 215 /** pointer to Mixer registers */ 216 void __iomem *mxr_regs; 217 /** pointer to Video Processor registers */ 218 void __iomem *vp_regs; 219 /** other resources, should used under mxr_device.mutex */ 220 struct clk *mixer; 221 struct clk *vp; 222 struct clk *sclk_mixer; 223 struct clk *sclk_hdmi; 224 struct clk *sclk_dac; 225}; 226 227/* event flags used */ 228enum mxr_devide_flags { 229 MXR_EVENT_VSYNC = 0, 230 MXR_EVENT_TOP = 1, 231}; 232 233/** drivers instance */ 234struct mxr_device { 235 /** master device */ 236 struct device *dev; 237 /** state of each layer */ 238 struct mxr_layer *layer[MXR_MAX_LAYERS]; 239 /** state of each output */ 240 struct mxr_output *output[MXR_MAX_OUTPUTS]; 241 /** number of registered outputs */ 242 int output_cnt; 243 244 /* video resources */ 245 246 /** V4L2 device */ 247 struct v4l2_device v4l2_dev; 248 /** context of allocator */ 249 void *alloc_ctx; 250 /** event wait queue */ 251 wait_queue_head_t event_queue; 252 /** state flags */ 253 unsigned long event_flags; 254 255 /** spinlock for protection of registers */ 256 spinlock_t reg_slock; 257 258 /** mutex for protection of fields below */ 259 struct mutex mutex; 260 /** number of entities depndant on output configuration */ 261 int n_output; 262 /** number of users that do streaming */ 263 int n_streamer; 264 /** index of current output */ 265 int current_output; 266 /** auxiliary resources used my mixer */ 267 struct mxr_resources res; 268}; 269 270/** transform device structure into mixer device */ 271static inline struct mxr_device *to_mdev(struct device *dev) 272{ 273 struct v4l2_device *vdev = dev_get_drvdata(dev); 274 return container_of(vdev, struct mxr_device, v4l2_dev); 275} 276 277/** get current output data, should be called under mdev's mutex */ 278static inline struct mxr_output *to_output(struct mxr_device *mdev) 279{ 280 return mdev->output[mdev->current_output]; 281} 282 283/** get current output subdev, should be called under mdev's mutex */ 284static inline struct v4l2_subdev *to_outsd(struct mxr_device *mdev) 285{ 286 struct mxr_output *out = to_output(mdev); 287 return out ? out->sd : NULL; 288} 289 290/** forward declaration for mixer platform data */ 291struct mxr_platform_data; 292 293/** acquiring common video resources */ 294int mxr_acquire_video(struct mxr_device *mdev, 295 struct mxr_output_conf *output_cont, int output_count); 296 297/** releasing common video resources */ 298void mxr_release_video(struct mxr_device *mdev); 299 300struct mxr_layer *mxr_graph_layer_create(struct mxr_device *mdev, int idx); 301struct mxr_layer *mxr_vp_layer_create(struct mxr_device *mdev, int idx); 302struct mxr_layer *mxr_base_layer_create(struct mxr_device *mdev, 303 int idx, char *name, struct mxr_layer_ops *ops); 304 305void mxr_base_layer_release(struct mxr_layer *layer); 306void mxr_layer_release(struct mxr_layer *layer); 307 308int mxr_base_layer_register(struct mxr_layer *layer); 309void mxr_base_layer_unregister(struct mxr_layer *layer); 310 311unsigned long mxr_get_plane_size(const struct mxr_block *blk, 312 unsigned int width, unsigned int height); 313 314/** adds new consumer for mixer's power */ 315int __must_check mxr_power_get(struct mxr_device *mdev); 316/** removes consumer for mixer's power */ 317void mxr_power_put(struct mxr_device *mdev); 318/** add new client for output configuration */ 319void mxr_output_get(struct mxr_device *mdev); 320/** removes new client for output configuration */ 321void mxr_output_put(struct mxr_device *mdev); 322/** add new client for streaming */ 323void mxr_streamer_get(struct mxr_device *mdev); 324/** removes new client for streaming */ 325void mxr_streamer_put(struct mxr_device *mdev); 326/** returns format of data delivared to current output */ 327void mxr_get_mbus_fmt(struct mxr_device *mdev, 328 struct v4l2_mbus_framefmt *mbus_fmt); 329 330/* Debug */ 331 332#define mxr_err(mdev, fmt, ...) dev_err(mdev->dev, fmt, ##__VA_ARGS__) 333#define mxr_warn(mdev, fmt, ...) dev_warn(mdev->dev, fmt, ##__VA_ARGS__) 334#define mxr_info(mdev, fmt, ...) dev_info(mdev->dev, fmt, ##__VA_ARGS__) 335 336#ifdef CONFIG_VIDEO_SAMSUNG_S5P_MIXER_DEBUG 337 #define mxr_dbg(mdev, fmt, ...) dev_dbg(mdev->dev, fmt, ##__VA_ARGS__) 338#else 339 #define mxr_dbg(mdev, fmt, ...) do { (void) mdev; } while (0) 340#endif 341 342/* accessing Mixer's and Video Processor's registers */ 343 344void mxr_vsync_set_update(struct mxr_device *mdev, int en); 345void mxr_reg_reset(struct mxr_device *mdev); 346irqreturn_t mxr_irq_handler(int irq, void *dev_data); 347void mxr_reg_s_output(struct mxr_device *mdev, int cookie); 348void mxr_reg_streamon(struct mxr_device *mdev); 349void mxr_reg_streamoff(struct mxr_device *mdev); 350int mxr_reg_wait4vsync(struct mxr_device *mdev); 351void mxr_reg_set_mbus_fmt(struct mxr_device *mdev, 352 struct v4l2_mbus_framefmt *fmt); 353void mxr_reg_graph_layer_stream(struct mxr_device *mdev, int idx, int en); 354void mxr_reg_graph_buffer(struct mxr_device *mdev, int idx, dma_addr_t addr); 355void mxr_reg_graph_format(struct mxr_device *mdev, int idx, 356 const struct mxr_format *fmt, const struct mxr_geometry *geo); 357 358void mxr_reg_vp_layer_stream(struct mxr_device *mdev, int en); 359void mxr_reg_vp_buffer(struct mxr_device *mdev, 360 dma_addr_t luma_addr[2], dma_addr_t chroma_addr[2]); 361void mxr_reg_vp_format(struct mxr_device *mdev, 362 const struct mxr_format *fmt, const struct mxr_geometry *geo); 363void mxr_reg_dump(struct mxr_device *mdev); 364 365#endif /* SAMSUNG_MIXER_H */ 366 367