197fb5e8dSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */
225fdd593SJeykumar Sankaran /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
325fdd593SJeykumar Sankaran  */
425fdd593SJeykumar Sankaran 
525fdd593SJeykumar Sankaran #ifndef _DPU_HW_PINGPONG_H
625fdd593SJeykumar Sankaran #define _DPU_HW_PINGPONG_H
725fdd593SJeykumar Sankaran 
825fdd593SJeykumar Sankaran #include "dpu_hw_catalog.h"
925fdd593SJeykumar Sankaran #include "dpu_hw_mdss.h"
1025fdd593SJeykumar Sankaran #include "dpu_hw_util.h"
1125fdd593SJeykumar Sankaran 
123c128638SKalyan Thota #define DITHER_MATRIX_SZ 16
133c128638SKalyan Thota 
1425fdd593SJeykumar Sankaran struct dpu_hw_pingpong;
1525fdd593SJeykumar Sankaran 
1625fdd593SJeykumar Sankaran struct dpu_hw_tear_check {
1725fdd593SJeykumar Sankaran 	/*
1825fdd593SJeykumar Sankaran 	 * This is ratio of MDP VSYNC clk freq(Hz) to
1925fdd593SJeykumar Sankaran 	 * refresh rate divided by no of lines
2025fdd593SJeykumar Sankaran 	 */
2125fdd593SJeykumar Sankaran 	u32 vsync_count;
2225fdd593SJeykumar Sankaran 	u32 sync_cfg_height;
2325fdd593SJeykumar Sankaran 	u32 vsync_init_val;
2425fdd593SJeykumar Sankaran 	u32 sync_threshold_start;
2525fdd593SJeykumar Sankaran 	u32 sync_threshold_continue;
2625fdd593SJeykumar Sankaran 	u32 start_pos;
2725fdd593SJeykumar Sankaran 	u32 rd_ptr_irq;
2825fdd593SJeykumar Sankaran 	u8 hw_vsync_mode;
2925fdd593SJeykumar Sankaran };
3025fdd593SJeykumar Sankaran 
3125fdd593SJeykumar Sankaran struct dpu_hw_pp_vsync_info {
3225fdd593SJeykumar Sankaran 	u32 rd_ptr_init_val;	/* value of rd pointer at vsync edge */
3325fdd593SJeykumar Sankaran 	u32 rd_ptr_frame_count;	/* num frames sent since enabling interface */
3425fdd593SJeykumar Sankaran 	u32 rd_ptr_line_count;	/* current line on panel (rd ptr) */
3525fdd593SJeykumar Sankaran 	u32 wr_ptr_line_count;	/* current line within pp fifo (wr ptr) */
3625fdd593SJeykumar Sankaran };
3725fdd593SJeykumar Sankaran 
3825fdd593SJeykumar Sankaran /**
393c128638SKalyan Thota  * struct dpu_hw_dither_cfg - dither feature structure
403c128638SKalyan Thota  * @flags: for customizing operations
413c128638SKalyan Thota  * @temporal_en: temperal dither enable
423c128638SKalyan Thota  * @c0_bitdepth: c0 component bit depth
433c128638SKalyan Thota  * @c1_bitdepth: c1 component bit depth
443c128638SKalyan Thota  * @c2_bitdepth: c2 component bit depth
453c128638SKalyan Thota  * @c3_bitdepth: c2 component bit depth
463c128638SKalyan Thota  * @matrix: dither strength matrix
473c128638SKalyan Thota  */
483c128638SKalyan Thota struct dpu_hw_dither_cfg {
493c128638SKalyan Thota 	u64 flags;
503c128638SKalyan Thota 	u32 temporal_en;
513c128638SKalyan Thota 	u32 c0_bitdepth;
523c128638SKalyan Thota 	u32 c1_bitdepth;
533c128638SKalyan Thota 	u32 c2_bitdepth;
543c128638SKalyan Thota 	u32 c3_bitdepth;
553c128638SKalyan Thota 	u32 matrix[DITHER_MATRIX_SZ];
563c128638SKalyan Thota };
573c128638SKalyan Thota 
583c128638SKalyan Thota /**
5925fdd593SJeykumar Sankaran  *
6025fdd593SJeykumar Sankaran  * struct dpu_hw_pingpong_ops : Interface to the pingpong Hw driver functions
6125fdd593SJeykumar Sankaran  *  Assumption is these functions will be called after clocks are enabled
6225fdd593SJeykumar Sankaran  *  @setup_tearcheck : program tear check values
6325fdd593SJeykumar Sankaran  *  @enable_tearcheck : enables tear check
6425fdd593SJeykumar Sankaran  *  @get_vsync_info : retries timing info of the panel
65aa9223a6SAngeloGioacchino Del Regno  *  @setup_autorefresh : configure and enable the autorefresh config
66aa9223a6SAngeloGioacchino Del Regno  *  @get_autorefresh : retrieve autorefresh config from hardware
6725fdd593SJeykumar Sankaran  *  @setup_dither : function to program the dither hw block
6825fdd593SJeykumar Sankaran  *  @get_line_count: obtain current vertical line counter
6925fdd593SJeykumar Sankaran  */
7025fdd593SJeykumar Sankaran struct dpu_hw_pingpong_ops {
7125fdd593SJeykumar Sankaran 	/**
7225fdd593SJeykumar Sankaran 	 * enables vysnc generation and sets up init value of
7325fdd593SJeykumar Sankaran 	 * read pointer and programs the tear check cofiguration
7425fdd593SJeykumar Sankaran 	 */
7525fdd593SJeykumar Sankaran 	int (*setup_tearcheck)(struct dpu_hw_pingpong *pp,
7625fdd593SJeykumar Sankaran 			struct dpu_hw_tear_check *cfg);
7725fdd593SJeykumar Sankaran 
7825fdd593SJeykumar Sankaran 	/**
7925fdd593SJeykumar Sankaran 	 * enables tear check block
8025fdd593SJeykumar Sankaran 	 */
8125fdd593SJeykumar Sankaran 	int (*enable_tearcheck)(struct dpu_hw_pingpong *pp,
8225fdd593SJeykumar Sankaran 			bool enable);
8325fdd593SJeykumar Sankaran 
8425fdd593SJeykumar Sankaran 	/**
8525fdd593SJeykumar Sankaran 	 * read, modify, write to either set or clear listening to external TE
8625fdd593SJeykumar Sankaran 	 * @Return: 1 if TE was originally connected, 0 if not, or -ERROR
8725fdd593SJeykumar Sankaran 	 */
8825fdd593SJeykumar Sankaran 	int (*connect_external_te)(struct dpu_hw_pingpong *pp,
8925fdd593SJeykumar Sankaran 			bool enable_external_te);
9025fdd593SJeykumar Sankaran 
9125fdd593SJeykumar Sankaran 	/**
9225fdd593SJeykumar Sankaran 	 * provides the programmed and current
9325fdd593SJeykumar Sankaran 	 * line_count
9425fdd593SJeykumar Sankaran 	 */
9525fdd593SJeykumar Sankaran 	int (*get_vsync_info)(struct dpu_hw_pingpong *pp,
9625fdd593SJeykumar Sankaran 			struct dpu_hw_pp_vsync_info  *info);
9725fdd593SJeykumar Sankaran 
9825fdd593SJeykumar Sankaran 	/**
99aa9223a6SAngeloGioacchino Del Regno 	 * configure and enable the autorefresh config
100aa9223a6SAngeloGioacchino Del Regno 	 */
101aa9223a6SAngeloGioacchino Del Regno 	void (*setup_autorefresh)(struct dpu_hw_pingpong *pp,
102aa9223a6SAngeloGioacchino Del Regno 				  u32 frame_count, bool enable);
103aa9223a6SAngeloGioacchino Del Regno 
104aa9223a6SAngeloGioacchino Del Regno 	/**
105aa9223a6SAngeloGioacchino Del Regno 	 * retrieve autorefresh config from hardware
106aa9223a6SAngeloGioacchino Del Regno 	 */
107aa9223a6SAngeloGioacchino Del Regno 	bool (*get_autorefresh)(struct dpu_hw_pingpong *pp,
108aa9223a6SAngeloGioacchino Del Regno 				u32 *frame_count);
109aa9223a6SAngeloGioacchino Del Regno 
110aa9223a6SAngeloGioacchino Del Regno 	/**
11125fdd593SJeykumar Sankaran 	 * poll until write pointer transmission starts
11225fdd593SJeykumar Sankaran 	 * @Return: 0 on success, -ETIMEDOUT on timeout
11325fdd593SJeykumar Sankaran 	 */
11425fdd593SJeykumar Sankaran 	int (*poll_timeout_wr_ptr)(struct dpu_hw_pingpong *pp, u32 timeout_us);
11525fdd593SJeykumar Sankaran 
11625fdd593SJeykumar Sankaran 	/**
11725fdd593SJeykumar Sankaran 	 * Obtain current vertical line counter
11825fdd593SJeykumar Sankaran 	 */
11925fdd593SJeykumar Sankaran 	u32 (*get_line_count)(struct dpu_hw_pingpong *pp);
1203c128638SKalyan Thota 
1213c128638SKalyan Thota 	/**
1223c128638SKalyan Thota 	 * Setup dither matix for pingpong block
1233c128638SKalyan Thota 	 */
1243c128638SKalyan Thota 	void (*setup_dither)(struct dpu_hw_pingpong *pp,
1253c128638SKalyan Thota 			struct dpu_hw_dither_cfg *cfg);
126893d6982SVinod Koul 	/**
127893d6982SVinod Koul 	 * Enable DSC
128893d6982SVinod Koul 	 */
129893d6982SVinod Koul 	int (*enable_dsc)(struct dpu_hw_pingpong *pp);
130893d6982SVinod Koul 
131893d6982SVinod Koul 	/**
132893d6982SVinod Koul 	 * Disable DSC
133893d6982SVinod Koul 	 */
134893d6982SVinod Koul 	void (*disable_dsc)(struct dpu_hw_pingpong *pp);
135893d6982SVinod Koul 
136893d6982SVinod Koul 	/**
137893d6982SVinod Koul 	 * Setup DSC
138893d6982SVinod Koul 	 */
139893d6982SVinod Koul 	int (*setup_dsc)(struct dpu_hw_pingpong *pp);
14025fdd593SJeykumar Sankaran };
14125fdd593SJeykumar Sankaran 
142dfa35bacSDmitry Baryshkov struct dpu_hw_merge_3d;
143dfa35bacSDmitry Baryshkov 
14425fdd593SJeykumar Sankaran struct dpu_hw_pingpong {
14525fdd593SJeykumar Sankaran 	struct dpu_hw_blk base;
14625fdd593SJeykumar Sankaran 	struct dpu_hw_blk_reg_map hw;
14725fdd593SJeykumar Sankaran 
14825fdd593SJeykumar Sankaran 	/* pingpong */
14925fdd593SJeykumar Sankaran 	enum dpu_pingpong idx;
15025fdd593SJeykumar Sankaran 	const struct dpu_pingpong_cfg *caps;
151dfa35bacSDmitry Baryshkov 	struct dpu_hw_merge_3d *merge_3d;
15225fdd593SJeykumar Sankaran 
15325fdd593SJeykumar Sankaran 	/* ops */
15425fdd593SJeykumar Sankaran 	struct dpu_hw_pingpong_ops ops;
15525fdd593SJeykumar Sankaran };
15625fdd593SJeykumar Sankaran 
15725fdd593SJeykumar Sankaran /**
158b954fa6bSDrew Davenport  * to_dpu_hw_pingpong - convert base object dpu_hw_base to container
159b954fa6bSDrew Davenport  * @hw: Pointer to base hardware block
160b954fa6bSDrew Davenport  * return: Pointer to hardware block container
161b954fa6bSDrew Davenport  */
162b954fa6bSDrew Davenport static inline struct dpu_hw_pingpong *to_dpu_hw_pingpong(struct dpu_hw_blk *hw)
163b954fa6bSDrew Davenport {
164b954fa6bSDrew Davenport 	return container_of(hw, struct dpu_hw_pingpong, base);
165b954fa6bSDrew Davenport }
166b954fa6bSDrew Davenport 
167b954fa6bSDrew Davenport /**
168*babdb815SMarijn Suijten  * dpu_hw_pingpong_init() - initializes the pingpong driver for the passed
169*babdb815SMarijn Suijten  * pingpong catalog entry.
170*babdb815SMarijn Suijten  * @cfg:  Pingpong catalog entry for which driver object is required
17125fdd593SJeykumar Sankaran  * @addr: Mapped register io address of MDP
172*babdb815SMarijn Suijten  * Return: Error code or allocated dpu_hw_pingpong context
17325fdd593SJeykumar Sankaran  */
174*babdb815SMarijn Suijten struct dpu_hw_pingpong *dpu_hw_pingpong_init(const struct dpu_pingpong_cfg *cfg,
175*babdb815SMarijn Suijten 		void __iomem *addr);
17625fdd593SJeykumar Sankaran 
17725fdd593SJeykumar Sankaran /**
17825fdd593SJeykumar Sankaran  * dpu_hw_pingpong_destroy - destroys pingpong driver context
17925fdd593SJeykumar Sankaran  *	should be called to free the context
18025fdd593SJeykumar Sankaran  * @pp:   Pointer to PP driver context returned by dpu_hw_pingpong_init
18125fdd593SJeykumar Sankaran  */
18225fdd593SJeykumar Sankaran void dpu_hw_pingpong_destroy(struct dpu_hw_pingpong *pp);
18325fdd593SJeykumar Sankaran 
18425fdd593SJeykumar Sankaran #endif /*_DPU_HW_PINGPONG_H */
185