1730b0ac3SDaniel Graefe /* SPDX-License-Identifier: GPL-2.0+ */
259f0ad80SSergio Aguirre /*
359f0ad80SSergio Aguirre  * TI OMAP4 ISS V4L2 Driver
459f0ad80SSergio Aguirre  *
559f0ad80SSergio Aguirre  * Copyright (C) 2012 Texas Instruments.
659f0ad80SSergio Aguirre  *
759f0ad80SSergio Aguirre  * Author: Sergio Aguirre <sergio.a.aguirre@gmail.com>
859f0ad80SSergio Aguirre  */
959f0ad80SSergio Aguirre 
1059f0ad80SSergio Aguirre #ifndef _OMAP4_ISS_H_
1159f0ad80SSergio Aguirre #define _OMAP4_ISS_H_
1259f0ad80SSergio Aguirre 
1359f0ad80SSergio Aguirre #include <media/v4l2-device.h>
14a288b78bSSakari Ailus #include <media/v4l2-mc.h>
15a288b78bSSakari Ailus 
1659f0ad80SSergio Aguirre #include <linux/device.h>
1759f0ad80SSergio Aguirre #include <linux/io.h>
1859f0ad80SSergio Aguirre #include <linux/platform_device.h>
1959f0ad80SSergio Aguirre #include <linux/wait.h>
2059f0ad80SSergio Aguirre 
21eb4b0ec7SMauro Carvalho Chehab #include <linux/platform_data/media/omap4iss.h>
2259f0ad80SSergio Aguirre 
2359f0ad80SSergio Aguirre #include "iss_regs.h"
2459f0ad80SSergio Aguirre #include "iss_csiphy.h"
2559f0ad80SSergio Aguirre #include "iss_csi2.h"
2659f0ad80SSergio Aguirre #include "iss_ipipeif.h"
2759f0ad80SSergio Aguirre #include "iss_ipipe.h"
2859f0ad80SSergio Aguirre #include "iss_resizer.h"
2959f0ad80SSergio Aguirre 
30fefad2d5SLaurent Pinchart struct regmap;
31fefad2d5SLaurent Pinchart 
3259f0ad80SSergio Aguirre #define to_iss_device(ptr_module)				\
3359f0ad80SSergio Aguirre 	container_of(ptr_module, struct iss_device, ptr_module)
3459f0ad80SSergio Aguirre #define to_device(ptr_module)						\
3559f0ad80SSergio Aguirre 	(to_iss_device(ptr_module)->dev)
3659f0ad80SSergio Aguirre 
3759f0ad80SSergio Aguirre enum iss_mem_resources {
3859f0ad80SSergio Aguirre 	OMAP4_ISS_MEM_TOP,
3959f0ad80SSergio Aguirre 	OMAP4_ISS_MEM_CSI2_A_REGS1,
4059f0ad80SSergio Aguirre 	OMAP4_ISS_MEM_CAMERARX_CORE1,
4159f0ad80SSergio Aguirre 	OMAP4_ISS_MEM_CSI2_B_REGS1,
4259f0ad80SSergio Aguirre 	OMAP4_ISS_MEM_CAMERARX_CORE2,
4359f0ad80SSergio Aguirre 	OMAP4_ISS_MEM_BTE,
4459f0ad80SSergio Aguirre 	OMAP4_ISS_MEM_ISP_SYS1,
4559f0ad80SSergio Aguirre 	OMAP4_ISS_MEM_ISP_RESIZER,
4659f0ad80SSergio Aguirre 	OMAP4_ISS_MEM_ISP_IPIPE,
4759f0ad80SSergio Aguirre 	OMAP4_ISS_MEM_ISP_ISIF,
4859f0ad80SSergio Aguirre 	OMAP4_ISS_MEM_ISP_IPIPEIF,
4959f0ad80SSergio Aguirre 	OMAP4_ISS_MEM_LAST,
5059f0ad80SSergio Aguirre };
5159f0ad80SSergio Aguirre 
5259f0ad80SSergio Aguirre enum iss_subclk_resource {
5359f0ad80SSergio Aguirre 	OMAP4_ISS_SUBCLK_SIMCOP		= (1 << 0),
5459f0ad80SSergio Aguirre 	OMAP4_ISS_SUBCLK_ISP		= (1 << 1),
5559f0ad80SSergio Aguirre 	OMAP4_ISS_SUBCLK_CSI2_A		= (1 << 2),
5659f0ad80SSergio Aguirre 	OMAP4_ISS_SUBCLK_CSI2_B		= (1 << 3),
5759f0ad80SSergio Aguirre 	OMAP4_ISS_SUBCLK_CCP2		= (1 << 4),
5859f0ad80SSergio Aguirre };
5959f0ad80SSergio Aguirre 
6059f0ad80SSergio Aguirre enum iss_isp_subclk_resource {
6159f0ad80SSergio Aguirre 	OMAP4_ISS_ISP_SUBCLK_BL		= (1 << 0),
6259f0ad80SSergio Aguirre 	OMAP4_ISS_ISP_SUBCLK_ISIF	= (1 << 1),
6359f0ad80SSergio Aguirre 	OMAP4_ISS_ISP_SUBCLK_H3A	= (1 << 2),
6459f0ad80SSergio Aguirre 	OMAP4_ISS_ISP_SUBCLK_RSZ	= (1 << 3),
6559f0ad80SSergio Aguirre 	OMAP4_ISS_ISP_SUBCLK_IPIPE	= (1 << 4),
6659f0ad80SSergio Aguirre 	OMAP4_ISS_ISP_SUBCLK_IPIPEIF	= (1 << 5),
6759f0ad80SSergio Aguirre };
6859f0ad80SSergio Aguirre 
6959f0ad80SSergio Aguirre /*
7059f0ad80SSergio Aguirre  * struct iss_reg - Structure for ISS register values.
7159f0ad80SSergio Aguirre  * @reg: 32-bit Register address.
7259f0ad80SSergio Aguirre  * @val: 32-bit Register value.
7359f0ad80SSergio Aguirre  */
7459f0ad80SSergio Aguirre struct iss_reg {
7559f0ad80SSergio Aguirre 	enum iss_mem_resources mmio_range;
7659f0ad80SSergio Aguirre 	u32 reg;
7759f0ad80SSergio Aguirre 	u32 val;
7859f0ad80SSergio Aguirre };
7959f0ad80SSergio Aguirre 
80f3632ba8SLaurent Pinchart /*
81f3632ba8SLaurent Pinchart  * struct iss_device - ISS device structure.
82fefad2d5SLaurent Pinchart  * @syscon: Regmap for the syscon register space
836246b2a7SSakari Ailus  * @crashed: Crashed entities
84f3632ba8SLaurent Pinchart  */
8559f0ad80SSergio Aguirre struct iss_device {
8659f0ad80SSergio Aguirre 	struct v4l2_device v4l2_dev;
8759f0ad80SSergio Aguirre 	struct media_device media_dev;
8859f0ad80SSergio Aguirre 	struct device *dev;
8959f0ad80SSergio Aguirre 	u32 revision;
9059f0ad80SSergio Aguirre 
9159f0ad80SSergio Aguirre 	/* platform HW resources */
9259f0ad80SSergio Aguirre 	struct iss_platform_data *pdata;
9359f0ad80SSergio Aguirre 	unsigned int irq_num;
9459f0ad80SSergio Aguirre 
9559f0ad80SSergio Aguirre 	struct resource *res[OMAP4_ISS_MEM_LAST];
9659f0ad80SSergio Aguirre 	void __iomem *regs[OMAP4_ISS_MEM_LAST];
97fefad2d5SLaurent Pinchart 	struct regmap *syscon;
9859f0ad80SSergio Aguirre 
9959f0ad80SSergio Aguirre 	u64 raw_dmamask;
10059f0ad80SSergio Aguirre 
10159f0ad80SSergio Aguirre 	struct mutex iss_mutex;	/* For handling ref_count field */
1026246b2a7SSakari Ailus 	struct media_entity_enum crashed;
10359f0ad80SSergio Aguirre 	int has_context;
10459f0ad80SSergio Aguirre 	int ref_count;
10559f0ad80SSergio Aguirre 
10659f0ad80SSergio Aguirre 	struct clk *iss_fck;
10759f0ad80SSergio Aguirre 	struct clk *iss_ctrlclk;
10859f0ad80SSergio Aguirre 
10959f0ad80SSergio Aguirre 	/* ISS modules */
11059f0ad80SSergio Aguirre 	struct iss_csi2_device csi2a;
11159f0ad80SSergio Aguirre 	struct iss_csi2_device csi2b;
11259f0ad80SSergio Aguirre 	struct iss_csiphy csiphy1;
11359f0ad80SSergio Aguirre 	struct iss_csiphy csiphy2;
11459f0ad80SSergio Aguirre 	struct iss_ipipeif_device ipipeif;
11559f0ad80SSergio Aguirre 	struct iss_ipipe_device ipipe;
11659f0ad80SSergio Aguirre 	struct iss_resizer_device resizer;
11759f0ad80SSergio Aguirre 
11859f0ad80SSergio Aguirre 	unsigned int subclk_resources;
11959f0ad80SSergio Aguirre 	unsigned int isp_subclk_resources;
12059f0ad80SSergio Aguirre };
12159f0ad80SSergio Aguirre 
12259f0ad80SSergio Aguirre int omap4iss_get_external_info(struct iss_pipeline *pipe,
12359f0ad80SSergio Aguirre 			       struct media_link *link);
12459f0ad80SSergio Aguirre 
12559f0ad80SSergio Aguirre int omap4iss_module_sync_idle(struct media_entity *me, wait_queue_head_t *wait,
12659f0ad80SSergio Aguirre 			      atomic_t *stopping);
12759f0ad80SSergio Aguirre 
12859f0ad80SSergio Aguirre int omap4iss_module_sync_is_stopping(wait_queue_head_t *wait,
12959f0ad80SSergio Aguirre 				     atomic_t *stopping);
13059f0ad80SSergio Aguirre 
13159f0ad80SSergio Aguirre int omap4iss_pipeline_set_stream(struct iss_pipeline *pipe,
13259f0ad80SSergio Aguirre 				 enum iss_pipeline_stream_state state);
133112da085SLaurent Pinchart void omap4iss_pipeline_cancel_stream(struct iss_pipeline *pipe);
13459f0ad80SSergio Aguirre 
13559f0ad80SSergio Aguirre void omap4iss_configure_bridge(struct iss_device *iss,
13659f0ad80SSergio Aguirre 			       enum ipipeif_input_entity input);
13759f0ad80SSergio Aguirre 
13859f0ad80SSergio Aguirre struct iss_device *omap4iss_get(struct iss_device *iss);
13959f0ad80SSergio Aguirre void omap4iss_put(struct iss_device *iss);
14059f0ad80SSergio Aguirre int omap4iss_subclk_enable(struct iss_device *iss,
14159f0ad80SSergio Aguirre 			   enum iss_subclk_resource res);
14259f0ad80SSergio Aguirre int omap4iss_subclk_disable(struct iss_device *iss,
14359f0ad80SSergio Aguirre 			    enum iss_subclk_resource res);
14468c03a66SLaurent Pinchart void omap4iss_isp_subclk_enable(struct iss_device *iss,
14559f0ad80SSergio Aguirre 				enum iss_isp_subclk_resource res);
14668c03a66SLaurent Pinchart void omap4iss_isp_subclk_disable(struct iss_device *iss,
14759f0ad80SSergio Aguirre 				 enum iss_isp_subclk_resource res);
14859f0ad80SSergio Aguirre 
14959f0ad80SSergio Aguirre int omap4iss_register_entities(struct platform_device *pdev,
15059f0ad80SSergio Aguirre 			       struct v4l2_device *v4l2_dev);
15159f0ad80SSergio Aguirre void omap4iss_unregister_entities(struct platform_device *pdev);
15259f0ad80SSergio Aguirre 
15311abbfd3SLaurent Pinchart /*
15411abbfd3SLaurent Pinchart  * iss_reg_read - Read the value of an OMAP4 ISS register
15511abbfd3SLaurent Pinchart  * @iss: the ISS device
15611abbfd3SLaurent Pinchart  * @res: memory resource in which the register is located
15711abbfd3SLaurent Pinchart  * @offset: register offset in the memory resource
15811abbfd3SLaurent Pinchart  *
15911abbfd3SLaurent Pinchart  * Return the register value.
16011abbfd3SLaurent Pinchart  */
16111abbfd3SLaurent Pinchart static inline
iss_reg_read(struct iss_device * iss,enum iss_mem_resources res,u32 offset)16211abbfd3SLaurent Pinchart u32 iss_reg_read(struct iss_device *iss, enum iss_mem_resources res,
16311abbfd3SLaurent Pinchart 		 u32 offset)
16411abbfd3SLaurent Pinchart {
16511abbfd3SLaurent Pinchart 	return readl(iss->regs[res] + offset);
16611abbfd3SLaurent Pinchart }
16711abbfd3SLaurent Pinchart 
16811abbfd3SLaurent Pinchart /*
16911abbfd3SLaurent Pinchart  * iss_reg_write - Write a value to an OMAP4 ISS register
17011abbfd3SLaurent Pinchart  * @iss: the ISS device
17111abbfd3SLaurent Pinchart  * @res: memory resource in which the register is located
17211abbfd3SLaurent Pinchart  * @offset: register offset in the memory resource
17311abbfd3SLaurent Pinchart  * @value: value to be written
17411abbfd3SLaurent Pinchart  */
17511abbfd3SLaurent Pinchart static inline
iss_reg_write(struct iss_device * iss,enum iss_mem_resources res,u32 offset,u32 value)17611abbfd3SLaurent Pinchart void iss_reg_write(struct iss_device *iss, enum iss_mem_resources res,
17711abbfd3SLaurent Pinchart 		   u32 offset, u32 value)
17811abbfd3SLaurent Pinchart {
17911abbfd3SLaurent Pinchart 	writel(value, iss->regs[res] + offset);
18011abbfd3SLaurent Pinchart }
18111abbfd3SLaurent Pinchart 
18211abbfd3SLaurent Pinchart /*
18311abbfd3SLaurent Pinchart  * iss_reg_clr - Clear bits in an OMAP4 ISS register
18411abbfd3SLaurent Pinchart  * @iss: the ISS device
18511abbfd3SLaurent Pinchart  * @res: memory resource in which the register is located
18611abbfd3SLaurent Pinchart  * @offset: register offset in the memory resource
18711abbfd3SLaurent Pinchart  * @clr: bit mask to be cleared
18811abbfd3SLaurent Pinchart  */
18911abbfd3SLaurent Pinchart static inline
iss_reg_clr(struct iss_device * iss,enum iss_mem_resources res,u32 offset,u32 clr)19011abbfd3SLaurent Pinchart void iss_reg_clr(struct iss_device *iss, enum iss_mem_resources res,
19111abbfd3SLaurent Pinchart 		 u32 offset, u32 clr)
19211abbfd3SLaurent Pinchart {
19311abbfd3SLaurent Pinchart 	u32 v = iss_reg_read(iss, res, offset);
19411abbfd3SLaurent Pinchart 
19511abbfd3SLaurent Pinchart 	iss_reg_write(iss, res, offset, v & ~clr);
19611abbfd3SLaurent Pinchart }
19711abbfd3SLaurent Pinchart 
19811abbfd3SLaurent Pinchart /*
19911abbfd3SLaurent Pinchart  * iss_reg_set - Set bits in an OMAP4 ISS register
20011abbfd3SLaurent Pinchart  * @iss: the ISS device
20111abbfd3SLaurent Pinchart  * @res: memory resource in which the register is located
20211abbfd3SLaurent Pinchart  * @offset: register offset in the memory resource
20311abbfd3SLaurent Pinchart  * @set: bit mask to be set
20411abbfd3SLaurent Pinchart  */
20511abbfd3SLaurent Pinchart static inline
iss_reg_set(struct iss_device * iss,enum iss_mem_resources res,u32 offset,u32 set)20611abbfd3SLaurent Pinchart void iss_reg_set(struct iss_device *iss, enum iss_mem_resources res,
20711abbfd3SLaurent Pinchart 		 u32 offset, u32 set)
20811abbfd3SLaurent Pinchart {
20911abbfd3SLaurent Pinchart 	u32 v = iss_reg_read(iss, res, offset);
21011abbfd3SLaurent Pinchart 
21111abbfd3SLaurent Pinchart 	iss_reg_write(iss, res, offset, v | set);
21211abbfd3SLaurent Pinchart }
21311abbfd3SLaurent Pinchart 
21411abbfd3SLaurent Pinchart /*
21511abbfd3SLaurent Pinchart  * iss_reg_update - Clear and set bits in an OMAP4 ISS register
21611abbfd3SLaurent Pinchart  * @iss: the ISS device
21711abbfd3SLaurent Pinchart  * @res: memory resource in which the register is located
21811abbfd3SLaurent Pinchart  * @offset: register offset in the memory resource
21911abbfd3SLaurent Pinchart  * @clr: bit mask to be cleared
22011abbfd3SLaurent Pinchart  * @set: bit mask to be set
22111abbfd3SLaurent Pinchart  *
22211abbfd3SLaurent Pinchart  * Clear the clr mask first and then set the set mask.
22311abbfd3SLaurent Pinchart  */
22411abbfd3SLaurent Pinchart static inline
iss_reg_update(struct iss_device * iss,enum iss_mem_resources res,u32 offset,u32 clr,u32 set)22511abbfd3SLaurent Pinchart void iss_reg_update(struct iss_device *iss, enum iss_mem_resources res,
22611abbfd3SLaurent Pinchart 		    u32 offset, u32 clr, u32 set)
22711abbfd3SLaurent Pinchart {
22811abbfd3SLaurent Pinchart 	u32 v = iss_reg_read(iss, res, offset);
22911abbfd3SLaurent Pinchart 
23011abbfd3SLaurent Pinchart 	iss_reg_write(iss, res, offset, (v & ~clr) | set);
23111abbfd3SLaurent Pinchart }
23211abbfd3SLaurent Pinchart 
23305b1b986SLaurent Pinchart #define iss_poll_condition_timeout(cond, timeout, min_ival, max_ival)	\
23405b1b986SLaurent Pinchart ({									\
23505b1b986SLaurent Pinchart 	unsigned long __timeout = jiffies + usecs_to_jiffies(timeout);	\
23605b1b986SLaurent Pinchart 	unsigned int __min_ival = (min_ival);				\
23705b1b986SLaurent Pinchart 	unsigned int __max_ival = (max_ival);				\
23805b1b986SLaurent Pinchart 	bool __cond;							\
23905b1b986SLaurent Pinchart 	while (!(__cond = (cond))) {					\
24005b1b986SLaurent Pinchart 		if (time_after(jiffies, __timeout))			\
24105b1b986SLaurent Pinchart 			break;						\
24205b1b986SLaurent Pinchart 		usleep_range(__min_ival, __max_ival);			\
24305b1b986SLaurent Pinchart 	}								\
24405b1b986SLaurent Pinchart 	!__cond;							\
24505b1b986SLaurent Pinchart })
24605b1b986SLaurent Pinchart 
24759f0ad80SSergio Aguirre #endif /* _OMAP4_ISS_H_ */
248