1/* SPDX-License-Identifier: GPL-2.0-only */
2/*
3 * Copyright (c) 2023, The Linux Foundation. All rights reserved.
4 */
5
6#ifndef _DPU_HW_CDM_H
7#define _DPU_HW_CDM_H
8
9#include "dpu_hw_mdss.h"
10#include "dpu_hw_top.h"
11
12struct dpu_hw_cdm;
13
14/**
15 * struct dpu_hw_cdm_cfg : current configuration of CDM block
16 *
17 *  @output_width:         output ROI width of CDM block
18 *  @output_height:        output ROI height of CDM block
19 *  @output_bit_depth:     output bit-depth of CDM block
20 *  @h_cdwn_type:          downsample type used for horizontal pixels
21 *  @v_cdwn_type:          downsample type used for vertical pixels
22 *  @output_fmt:           handle to dpu_format of CDM block
23 *  @csc_cfg:              handle to CSC matrix programmed for CDM block
24 *  @output_type:          interface to which CDM is paired (HDMI/WB)
25 *  @pp_id:                ping-pong block to which CDM is bound to
26 */
27struct dpu_hw_cdm_cfg {
28	u32 output_width;
29	u32 output_height;
30	u32 output_bit_depth;
31	u32 h_cdwn_type;
32	u32 v_cdwn_type;
33	const struct dpu_format *output_fmt;
34	const struct dpu_csc_cfg *csc_cfg;
35	u32 output_type;
36	int pp_id;
37};
38
39/*
40 * These values are used indicate which type of downsample is used
41 * in the horizontal/vertical direction for the CDM block.
42 */
43enum dpu_hw_cdwn_type {
44	CDM_CDWN_DISABLE,
45	CDM_CDWN_PIXEL_DROP,
46	CDM_CDWN_AVG,
47	CDM_CDWN_COSITE,
48	CDM_CDWN_OFFSITE,
49};
50
51/*
52 * CDM block can be paired with WB or HDMI block. These values match
53 * the input with which the CDM block is paired.
54 */
55enum dpu_hw_cdwn_output_type {
56	CDM_CDWN_OUTPUT_HDMI,
57	CDM_CDWN_OUTPUT_WB,
58};
59
60/*
61 * CDM block can give an 8-bit or 10-bit output. These values
62 * are used to indicate the output bit depth of CDM block
63 */
64enum dpu_hw_cdwn_output_bit_depth {
65	CDM_CDWN_OUTPUT_8BIT,
66	CDM_CDWN_OUTPUT_10BIT,
67};
68
69/*
70 * CDM block can downsample using different methods. These values
71 * are used to indicate the downsample method which can be used
72 * either in the horizontal or vertical direction.
73 */
74enum dpu_hw_cdwn_op_mode_method_h_v {
75	CDM_CDWN2_METHOD_PIXEL_DROP,
76	CDM_CDWN2_METHOD_AVG,
77	CDM_CDWN2_METHOD_COSITE,
78	CDM_CDWN2_METHOD_OFFSITE
79};
80
81/**
82 * struct dpu_hw_cdm_ops : Interface to the chroma down Hw driver functions
83 *                         Assumption is these functions will be called after
84 *                         clocks are enabled
85 *  @enable:               Enables the output to interface and programs the
86 *                         output packer
87 *  @bind_pingpong_blk:    enable/disable the connection with pingpong which
88 *                         will feed pixels to this cdm
89 */
90struct dpu_hw_cdm_ops {
91	/**
92	 * Enable the CDM module
93	 * @cdm         Pointer to chroma down context
94	 */
95	int (*enable)(struct dpu_hw_cdm *cdm, struct dpu_hw_cdm_cfg *cfg);
96
97	/**
98	 * Enable/disable the connection with pingpong
99	 * @cdm         Pointer to chroma down context
100	 * @pp          pingpong block id.
101	 */
102	void (*bind_pingpong_blk)(struct dpu_hw_cdm *cdm, const enum dpu_pingpong pp);
103};
104
105/**
106 * struct dpu_hw_cdm - cdm description
107 * @base: Hardware block base structure
108 * @hw: Block hardware details
109 * @idx: CDM index
110 * @caps: Pointer to cdm_cfg
111 * @ops: handle to operations possible for this CDM
112 */
113struct dpu_hw_cdm {
114	struct dpu_hw_blk base;
115	struct dpu_hw_blk_reg_map hw;
116
117	/* chroma down */
118	const struct dpu_cdm_cfg *caps;
119	enum  dpu_cdm  idx;
120
121	/* ops */
122	struct dpu_hw_cdm_ops ops;
123};
124
125/**
126 * dpu_hw_cdm_init - initializes the cdm hw driver object.
127 * should be called once before accessing every cdm.
128 * @dev: DRM device handle
129 * @cdm: CDM catalog entry for which driver object is required
130 * @addr :   mapped register io address of MDSS
131 * @mdss_rev: mdss hw core revision
132 */
133struct dpu_hw_cdm *dpu_hw_cdm_init(struct drm_device *dev,
134				   const struct dpu_cdm_cfg *cdm, void __iomem *addr,
135				   const struct dpu_mdss_version *mdss_rev);
136
137static inline struct dpu_hw_cdm *to_dpu_hw_cdm(struct dpu_hw_blk *hw)
138{
139	return container_of(hw, struct dpu_hw_cdm, base);
140}
141
142#endif /*_DPU_HW_CDM_H */
143