201 lines · c
1/* SPDX-License-Identifier: GPL-2.0-only */2/*3 * Copyright (C) 2011 - 2012 Samsung Electronics Co., Ltd.4 */5 6#ifndef FIMC_MDEVICE_H_7#define FIMC_MDEVICE_H_8 9#include <linux/clk.h>10#include <linux/clk-provider.h>11#include <linux/platform_device.h>12#include <linux/mutex.h>13#include <linux/of.h>14#include <media/media-device.h>15#include <media/media-entity.h>16#include <media/v4l2-device.h>17#include <media/v4l2-subdev.h>18#include <media/drv-intf/exynos-fimc.h>19 20#include "fimc-core.h"21#include "fimc-lite.h"22#include "mipi-csis.h"23 24#define FIMC_OF_NODE_NAME "fimc"25#define FIMC_LITE_OF_NODE_NAME "fimc-lite"26#define FIMC_IS_OF_NODE_NAME "fimc-is"27#define CSIS_OF_NODE_NAME "csis"28 29#define FIMC_MAX_SENSORS 430#define FIMC_MAX_CAMCLKS 231#define DEFAULT_SENSOR_CLK_FREQ 24000000U32 33/* LCD/ISP Writeback clocks (PIXELASYNCMx) */34enum {35 CLK_IDX_WB_A,36 CLK_IDX_WB_B,37 FIMC_MAX_WBCLKS38};39 40enum fimc_subdev_index {41 IDX_SENSOR,42 IDX_CSIS,43 IDX_FLITE,44 IDX_IS_ISP,45 IDX_FIMC,46 IDX_MAX,47};48 49/*50 * This structure represents a chain of media entities, including a data51 * source entity (e.g. an image sensor subdevice), a data capture entity52 * - a video capture device node and any remaining entities.53 */54struct fimc_pipeline {55 struct exynos_media_pipeline ep;56 struct list_head list;57 struct media_entity *vdev_entity;58 struct v4l2_subdev *subdevs[IDX_MAX];59};60 61#define to_fimc_pipeline(_ep) container_of(_ep, struct fimc_pipeline, ep)62 63struct fimc_csis_info {64 struct v4l2_subdev *sd;65 int id;66};67 68struct fimc_camclk_info {69 struct clk *clock;70 int use_count;71 unsigned long frequency;72};73 74/**75 * struct fimc_sensor_info - image data source subdev information76 * @pdata: sensor's attributes passed as media device's platform data77 * @asd: asynchronous subdev registration data structure78 * @subdev: image sensor v4l2 subdev79 * @host: fimc device the sensor is currently linked to80 *81 * This data structure applies to image sensor and the writeback subdevs.82 */83struct fimc_sensor_info {84 struct fimc_source_info pdata;85 struct v4l2_async_connection *asd;86 struct v4l2_subdev *subdev;87 struct fimc_dev *host;88};89 90struct cam_clk {91 struct clk_hw hw;92 struct fimc_md *fmd;93};94#define to_cam_clk(_hw) container_of(_hw, struct cam_clk, hw)95 96/**97 * struct fimc_md - fimc media device information98 * @csis: MIPI CSIS subdevs data99 * @sensor: array of registered sensor subdevs100 * @num_sensors: actual number of registered sensors101 * @camclk: external sensor clock information102 * @wbclk: external writeback clock information103 * @fimc_lite: array of registered fimc-lite devices104 * @fimc: array of registered fimc devices105 * @fimc_is: fimc-is data structure106 * @use_isp: set to true when FIMC-IS subsystem is used107 * @pmf: handle to the CAMCLK clock control FIMC helper device108 * @media_dev: top level media device109 * @v4l2_dev: top level v4l2_device holding up the subdevs110 * @pdev: platform device this media device is hooked up into111 * @clk_provider: CAMCLK clock provider structure112 * @subdev_notifier: notifier for the subdevs113 * @user_subdev_api: true if subdevs are not configured by the host driver114 * @slock: spinlock protecting @sensor array115 * @pipelines: list of pipelines116 * @link_setup_graph: graph iterator117 */118struct fimc_md {119 struct fimc_csis_info csis[CSIS_MAX_ENTITIES];120 struct fimc_sensor_info sensor[FIMC_MAX_SENSORS];121 int num_sensors;122 struct fimc_camclk_info camclk[FIMC_MAX_CAMCLKS];123 struct clk *wbclk[FIMC_MAX_WBCLKS];124 struct fimc_lite *fimc_lite[FIMC_LITE_MAX_DEVS];125 struct fimc_dev *fimc[FIMC_MAX_DEVS];126 struct fimc_is *fimc_is;127 bool use_isp;128 struct device *pmf;129 struct media_device media_dev;130 struct v4l2_device v4l2_dev;131 struct platform_device *pdev;132 133 struct cam_clk_provider {134 struct clk *clks[FIMC_MAX_CAMCLKS];135 struct clk_onecell_data clk_data;136 struct device_node *of_node;137 struct cam_clk camclk[FIMC_MAX_CAMCLKS];138 int num_clocks;139 } clk_provider;140 141 struct v4l2_async_notifier subdev_notifier;142 143 bool user_subdev_api;144 spinlock_t slock;145 struct list_head pipelines;146 struct media_graph link_setup_graph;147};148 149static inline150struct fimc_sensor_info *source_to_sensor_info(struct fimc_source_info *si)151{152 return container_of(si, struct fimc_sensor_info, pdata);153}154 155static inline struct fimc_md *entity_to_fimc_mdev(struct media_entity *me)156{157 return me->graph_obj.mdev == NULL ? NULL :158 container_of(me->graph_obj.mdev, struct fimc_md, media_dev);159}160 161static inline struct fimc_md *notifier_to_fimc_md(struct v4l2_async_notifier *n)162{163 return container_of(n, struct fimc_md, subdev_notifier);164}165 166static inline void fimc_md_graph_lock(struct exynos_video_entity *ve)167{168 mutex_lock(&ve->vdev.entity.graph_obj.mdev->graph_mutex);169}170 171static inline void fimc_md_graph_unlock(struct exynos_video_entity *ve)172{173 mutex_unlock(&ve->vdev.entity.graph_obj.mdev->graph_mutex);174}175 176int fimc_md_set_camclk(struct v4l2_subdev *sd, bool on);177 178#ifdef CONFIG_OF179static inline bool fimc_md_is_isp_available(struct device_node *node)180{181 node = of_get_child_by_name(node, FIMC_IS_OF_NODE_NAME);182 return node ? of_device_is_available(node) : false;183}184#else185#define fimc_md_is_isp_available(node) (false)186#endif /* CONFIG_OF */187 188static inline struct v4l2_subdev *__fimc_md_get_subdev(189 struct exynos_media_pipeline *ep,190 unsigned int index)191{192 struct fimc_pipeline *p = to_fimc_pipeline(ep);193 194 if (!p || index >= IDX_MAX)195 return NULL;196 else197 return p->subdevs[index];198}199 200#endif201