1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | /* |
3 | * Copyright 2019 NXP. |
4 | */ |
5 | |
6 | #ifndef __DCSS_PRV_H__ |
7 | #define __DCSS_PRV_H__ |
8 | |
9 | #include <drm/drm_fourcc.h> |
10 | #include <drm/drm_plane.h> |
11 | #include <linux/io.h> |
12 | #include <linux/pm.h> |
13 | #include <video/videomode.h> |
14 | |
15 | #define SET 0x04 |
16 | #define CLR 0x08 |
17 | #define TGL 0x0C |
18 | |
19 | #define dcss_writel(v, c) writel((v), (c)) |
20 | #define dcss_readl(c) readl(c) |
21 | #define dcss_set(v, c) writel((v), (c) + SET) |
22 | #define dcss_clr(v, c) writel((v), (c) + CLR) |
23 | #define dcss_toggle(v, c) writel((v), (c) + TGL) |
24 | |
25 | static inline void dcss_update(u32 v, u32 m, void __iomem *c) |
26 | { |
27 | writel(val: (readl(addr: c) & ~(m)) | (v), addr: (c)); |
28 | } |
29 | |
30 | #define DCSS_DBG_REG(reg) {.name = #reg, .ofs = reg} |
31 | |
32 | enum { |
33 | DCSS_IMX8MQ = 0, |
34 | }; |
35 | |
36 | struct dcss_type_data { |
37 | const char *name; |
38 | u32 blkctl_ofs; |
39 | u32 ctxld_ofs; |
40 | u32 rdsrc_ofs; |
41 | u32 wrscl_ofs; |
42 | u32 dtg_ofs; |
43 | u32 scaler_ofs; |
44 | u32 ss_ofs; |
45 | u32 dpr_ofs; |
46 | u32 dtrc_ofs; |
47 | u32 dec400d_ofs; |
48 | u32 hdr10_ofs; |
49 | }; |
50 | |
51 | struct dcss_debug_reg { |
52 | char *name; |
53 | u32 ofs; |
54 | }; |
55 | |
56 | enum dcss_ctxld_ctx_type { |
57 | CTX_DB, |
58 | CTX_SB_HP, /* high-priority */ |
59 | CTX_SB_LP, /* low-priority */ |
60 | }; |
61 | |
62 | struct dcss_dev { |
63 | struct device *dev; |
64 | const struct dcss_type_data *devtype; |
65 | struct device_node *of_port; |
66 | |
67 | u32 start_addr; |
68 | |
69 | struct dcss_blkctl *blkctl; |
70 | struct dcss_ctxld *ctxld; |
71 | struct dcss_dpr *dpr; |
72 | struct dcss_dtg *dtg; |
73 | struct dcss_ss *ss; |
74 | struct dcss_hdr10 *hdr10; |
75 | struct dcss_scaler *scaler; |
76 | struct dcss_dtrc *dtrc; |
77 | struct dcss_dec400d *dec400d; |
78 | struct dcss_wrscl *wrscl; |
79 | struct dcss_rdsrc *rdsrc; |
80 | |
81 | struct clk *apb_clk; |
82 | struct clk *axi_clk; |
83 | struct clk *pix_clk; |
84 | struct clk *rtrm_clk; |
85 | struct clk *dtrc_clk; |
86 | struct clk *pll_src_clk; |
87 | struct clk *pll_phy_ref_clk; |
88 | |
89 | bool hdmi_output; |
90 | |
91 | void (*disable_callback)(void *data); |
92 | struct completion disable_completion; |
93 | }; |
94 | |
95 | struct dcss_dev *dcss_drv_dev_to_dcss(struct device *dev); |
96 | struct drm_device *dcss_drv_dev_to_drm(struct device *dev); |
97 | struct dcss_dev *dcss_dev_create(struct device *dev, bool hdmi_output); |
98 | void dcss_dev_destroy(struct dcss_dev *dcss); |
99 | void dcss_enable_dtg_and_ss(struct dcss_dev *dcss); |
100 | void dcss_disable_dtg_and_ss(struct dcss_dev *dcss); |
101 | |
102 | extern const struct dev_pm_ops dcss_dev_pm_ops; |
103 | |
104 | /* BLKCTL */ |
105 | int dcss_blkctl_init(struct dcss_dev *dcss, unsigned long blkctl_base); |
106 | void dcss_blkctl_cfg(struct dcss_blkctl *blkctl); |
107 | |
108 | /* CTXLD */ |
109 | int dcss_ctxld_init(struct dcss_dev *dcss, unsigned long ctxld_base); |
110 | void dcss_ctxld_exit(struct dcss_ctxld *ctxld); |
111 | void dcss_ctxld_write(struct dcss_ctxld *ctxld, u32 ctx_id, |
112 | u32 val, u32 reg_idx); |
113 | int dcss_ctxld_resume(struct dcss_ctxld *dcss_ctxld); |
114 | int dcss_ctxld_suspend(struct dcss_ctxld *dcss_ctxld); |
115 | void dcss_ctxld_write_irqsafe(struct dcss_ctxld *ctlxd, u32 ctx_id, u32 val, |
116 | u32 reg_ofs); |
117 | void dcss_ctxld_kick(struct dcss_ctxld *ctxld); |
118 | bool dcss_ctxld_is_flushed(struct dcss_ctxld *ctxld); |
119 | int dcss_ctxld_enable(struct dcss_ctxld *ctxld); |
120 | void dcss_ctxld_register_completion(struct dcss_ctxld *ctxld, |
121 | struct completion *dis_completion); |
122 | void dcss_ctxld_assert_locked(struct dcss_ctxld *ctxld); |
123 | |
124 | /* DPR */ |
125 | int dcss_dpr_init(struct dcss_dev *dcss, unsigned long dpr_base); |
126 | void dcss_dpr_exit(struct dcss_dpr *dpr); |
127 | void dcss_dpr_write_sysctrl(struct dcss_dpr *dpr); |
128 | void dcss_dpr_set_res(struct dcss_dpr *dpr, int ch_num, u32 xres, u32 yres); |
129 | void dcss_dpr_addr_set(struct dcss_dpr *dpr, int ch_num, u32 luma_base_addr, |
130 | u32 chroma_base_addr, u16 pitch); |
131 | void dcss_dpr_enable(struct dcss_dpr *dpr, int ch_num, bool en); |
132 | void dcss_dpr_format_set(struct dcss_dpr *dpr, int ch_num, |
133 | const struct drm_format_info *format, u64 modifier); |
134 | void dcss_dpr_set_rotation(struct dcss_dpr *dpr, int ch_num, u32 rotation); |
135 | |
136 | /* DTG */ |
137 | int dcss_dtg_init(struct dcss_dev *dcss, unsigned long dtg_base); |
138 | void dcss_dtg_exit(struct dcss_dtg *dtg); |
139 | bool dcss_dtg_vblank_irq_valid(struct dcss_dtg *dtg); |
140 | void dcss_dtg_vblank_irq_enable(struct dcss_dtg *dtg, bool en); |
141 | void dcss_dtg_vblank_irq_clear(struct dcss_dtg *dtg); |
142 | void dcss_dtg_sync_set(struct dcss_dtg *dtg, struct videomode *vm); |
143 | void dcss_dtg_css_set(struct dcss_dtg *dtg); |
144 | void dcss_dtg_enable(struct dcss_dtg *dtg); |
145 | void dcss_dtg_shutoff(struct dcss_dtg *dtg); |
146 | bool dcss_dtg_is_enabled(struct dcss_dtg *dtg); |
147 | void dcss_dtg_ctxld_kick_irq_enable(struct dcss_dtg *dtg, bool en); |
148 | bool dcss_dtg_global_alpha_changed(struct dcss_dtg *dtg, int ch_num, int alpha); |
149 | void dcss_dtg_plane_alpha_set(struct dcss_dtg *dtg, int ch_num, |
150 | const struct drm_format_info *format, int alpha); |
151 | void dcss_dtg_plane_pos_set(struct dcss_dtg *dtg, int ch_num, |
152 | int px, int py, int pw, int ph); |
153 | void dcss_dtg_ch_enable(struct dcss_dtg *dtg, int ch_num, bool en); |
154 | |
155 | /* SUBSAM */ |
156 | int dcss_ss_init(struct dcss_dev *dcss, unsigned long subsam_base); |
157 | void dcss_ss_exit(struct dcss_ss *ss); |
158 | void dcss_ss_enable(struct dcss_ss *ss); |
159 | void dcss_ss_shutoff(struct dcss_ss *ss); |
160 | void dcss_ss_subsam_set(struct dcss_ss *ss); |
161 | void dcss_ss_sync_set(struct dcss_ss *ss, struct videomode *vm, |
162 | bool phsync, bool pvsync); |
163 | |
164 | /* SCALER */ |
165 | int dcss_scaler_init(struct dcss_dev *dcss, unsigned long scaler_base); |
166 | void dcss_scaler_exit(struct dcss_scaler *scl); |
167 | void dcss_scaler_set_filter(struct dcss_scaler *scl, int ch_num, |
168 | enum drm_scaling_filter scaling_filter); |
169 | void dcss_scaler_setup(struct dcss_scaler *scl, int ch_num, |
170 | const struct drm_format_info *format, |
171 | int src_xres, int src_yres, int dst_xres, int dst_yres, |
172 | u32 vrefresh_hz); |
173 | void dcss_scaler_ch_enable(struct dcss_scaler *scl, int ch_num, bool en); |
174 | int dcss_scaler_get_min_max_ratios(struct dcss_scaler *scl, int ch_num, |
175 | int *min, int *max); |
176 | void dcss_scaler_write_sclctrl(struct dcss_scaler *scl); |
177 | |
178 | #endif /* __DCSS_PRV_H__ */ |
179 | |