1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
3  */
4 
5 #ifndef _DPU_HW_PINGPONG_H
6 #define _DPU_HW_PINGPONG_H
7 
8 #include "dpu_hw_catalog.h"
9 #include "dpu_hw_mdss.h"
10 #include "dpu_hw_util.h"
11 
12 #define DITHER_MATRIX_SZ 16
13 
14 struct dpu_hw_pingpong;
15 
16 struct dpu_hw_tear_check {
17 	/*
18 	 * This is ratio of MDP VSYNC clk freq(Hz) to
19 	 * refresh rate divided by no of lines
20 	 */
21 	u32 vsync_count;
22 	u32 sync_cfg_height;
23 	u32 vsync_init_val;
24 	u32 sync_threshold_start;
25 	u32 sync_threshold_continue;
26 	u32 start_pos;
27 	u32 rd_ptr_irq;
28 	u8 hw_vsync_mode;
29 };
30 
31 struct dpu_hw_pp_vsync_info {
32 	u32 rd_ptr_init_val;	/* value of rd pointer at vsync edge */
33 	u32 rd_ptr_frame_count;	/* num frames sent since enabling interface */
34 	u32 rd_ptr_line_count;	/* current line on panel (rd ptr) */
35 	u32 wr_ptr_line_count;	/* current line within pp fifo (wr ptr) */
36 };
37 
38 /**
39  * struct dpu_hw_dither_cfg - dither feature structure
40  * @flags: for customizing operations
41  * @temporal_en: temperal dither enable
42  * @c0_bitdepth: c0 component bit depth
43  * @c1_bitdepth: c1 component bit depth
44  * @c2_bitdepth: c2 component bit depth
45  * @c3_bitdepth: c2 component bit depth
46  * @matrix: dither strength matrix
47  */
48 struct dpu_hw_dither_cfg {
49 	u64 flags;
50 	u32 temporal_en;
51 	u32 c0_bitdepth;
52 	u32 c1_bitdepth;
53 	u32 c2_bitdepth;
54 	u32 c3_bitdepth;
55 	u32 matrix[DITHER_MATRIX_SZ];
56 };
57 
58 /**
59  *
60  * struct dpu_hw_pingpong_ops : Interface to the pingpong Hw driver functions
61  *  Assumption is these functions will be called after clocks are enabled
62  *  @setup_tearcheck : program tear check values
63  *  @enable_tearcheck : enables tear check
64  *  @get_vsync_info : retries timing info of the panel
65  *  @setup_autorefresh : configure and enable the autorefresh config
66  *  @get_autorefresh : retrieve autorefresh config from hardware
67  *  @setup_dither : function to program the dither hw block
68  *  @get_line_count: obtain current vertical line counter
69  */
70 struct dpu_hw_pingpong_ops {
71 	/**
72 	 * enables vysnc generation and sets up init value of
73 	 * read pointer and programs the tear check cofiguration
74 	 */
75 	int (*setup_tearcheck)(struct dpu_hw_pingpong *pp,
76 			struct dpu_hw_tear_check *cfg);
77 
78 	/**
79 	 * enables tear check block
80 	 */
81 	int (*enable_tearcheck)(struct dpu_hw_pingpong *pp,
82 			bool enable);
83 
84 	/**
85 	 * read, modify, write to either set or clear listening to external TE
86 	 * @Return: 1 if TE was originally connected, 0 if not, or -ERROR
87 	 */
88 	int (*connect_external_te)(struct dpu_hw_pingpong *pp,
89 			bool enable_external_te);
90 
91 	/**
92 	 * provides the programmed and current
93 	 * line_count
94 	 */
95 	int (*get_vsync_info)(struct dpu_hw_pingpong *pp,
96 			struct dpu_hw_pp_vsync_info  *info);
97 
98 	/**
99 	 * configure and enable the autorefresh config
100 	 */
101 	void (*setup_autorefresh)(struct dpu_hw_pingpong *pp,
102 				  u32 frame_count, bool enable);
103 
104 	/**
105 	 * retrieve autorefresh config from hardware
106 	 */
107 	bool (*get_autorefresh)(struct dpu_hw_pingpong *pp,
108 				u32 *frame_count);
109 
110 	/**
111 	 * poll until write pointer transmission starts
112 	 * @Return: 0 on success, -ETIMEDOUT on timeout
113 	 */
114 	int (*poll_timeout_wr_ptr)(struct dpu_hw_pingpong *pp, u32 timeout_us);
115 
116 	/**
117 	 * Obtain current vertical line counter
118 	 */
119 	u32 (*get_line_count)(struct dpu_hw_pingpong *pp);
120 
121 	/**
122 	 * Setup dither matix for pingpong block
123 	 */
124 	void (*setup_dither)(struct dpu_hw_pingpong *pp,
125 			struct dpu_hw_dither_cfg *cfg);
126 	/**
127 	 * Enable DSC
128 	 */
129 	int (*enable_dsc)(struct dpu_hw_pingpong *pp);
130 
131 	/**
132 	 * Disable DSC
133 	 */
134 	void (*disable_dsc)(struct dpu_hw_pingpong *pp);
135 
136 	/**
137 	 * Setup DSC
138 	 */
139 	int (*setup_dsc)(struct dpu_hw_pingpong *pp);
140 };
141 
142 struct dpu_hw_merge_3d;
143 
144 struct dpu_hw_pingpong {
145 	struct dpu_hw_blk base;
146 	struct dpu_hw_blk_reg_map hw;
147 
148 	/* pingpong */
149 	enum dpu_pingpong idx;
150 	const struct dpu_pingpong_cfg *caps;
151 	struct dpu_hw_merge_3d *merge_3d;
152 
153 	/* ops */
154 	struct dpu_hw_pingpong_ops ops;
155 };
156 
157 /**
158  * to_dpu_hw_pingpong - convert base object dpu_hw_base to container
159  * @hw: Pointer to base hardware block
160  * return: Pointer to hardware block container
161  */
162 static inline struct dpu_hw_pingpong *to_dpu_hw_pingpong(struct dpu_hw_blk *hw)
163 {
164 	return container_of(hw, struct dpu_hw_pingpong, base);
165 }
166 
167 /**
168  * dpu_hw_pingpong_init - initializes the pingpong driver for the passed
169  *	pingpong idx.
170  * @idx:  Pingpong index for which driver object is required
171  * @addr: Mapped register io address of MDP
172  * @m:    Pointer to mdss catalog data
173  * Returns: Error code or allocated dpu_hw_pingpong context
174  */
175 struct dpu_hw_pingpong *dpu_hw_pingpong_init(enum dpu_pingpong idx,
176 		void __iomem *addr,
177 		const struct dpu_mdss_cfg *m);
178 
179 /**
180  * dpu_hw_pingpong_destroy - destroys pingpong driver context
181  *	should be called to free the context
182  * @pp:   Pointer to PP driver context returned by dpu_hw_pingpong_init
183  */
184 void dpu_hw_pingpong_destroy(struct dpu_hw_pingpong *pp);
185 
186 #endif /*_DPU_HW_PINGPONG_H */
187