xref: /linux/drivers/media/platform/dreamchip/rppx1/rppx1.c (revision f4cdf7ca9a1fdcca413157df19753f388a5a224e)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2026 Renesas Electronics Corp.
4  * Copyright (C) 2026 Ideas on Board Oy
5  * Copyright (C) 2026 Ragnatech AB
6  *
7  * Support library for Dreamchip HDR RPPX1 High Dynamic Range Real-time Pixel
8  * Processor.
9  */
10 
11 #include <linux/io.h>
12 #include <linux/module.h>
13 #include <linux/slab.h>
14 
15 #include "rppx1.h"
16 
17 /* RPP_HDR Base Addresses */
18 #define RPPX1_HDRREGS_BASE			0x0000
19 #define RPPX1_HDR_IRQ_BASE			0x0200
20 #define RPPX1_RPP_OUT_BASE			0x0800
21 #define RPPX1_RPP_RMAP_BASE			0x0c00
22 #define RPPX1_RPP_RMAP_MEAS_BASE		0x1000
23 #define RPPX1_RPP_MAIN_PRE1_BASE		0x2000
24 #define RPPX1_RPP_MAIN_PRE2_BASE		0x4000
25 #define RPPX1_RPP_MAIN_POST_BASE		0xa000
26 #define RPPX1_RPP_MVOUT_BASE			0xc000
27 #define RPPX1_RPP_FUSA_BASE			0xf000
28 
29 #define RPPX1_RPP_HDRREGS_VERSION_REG		(RPPX1_HDRREGS_BASE + 0x0000)
30 
31 #define RPPX1_RPP_HDR_UPD_REG			(RPPX1_HDRREGS_BASE + 0x0004)
32 #define RPPX1_RPP_HDR_UPD_REGS_GEN_CFG_UPD	BIT(1)
33 #define RPPX1_RPP_HDR_UPD_REGS_CFG_UPD		BIT(0)
34 
35 #define RPPX1_RESERVED_3_REG			(RPPX1_HDRREGS_BASE + 0x0008)
36 
37 #define RPPX1_RPP_HDR_INFORM_ENABLE_REG		(RPPX1_HDRREGS_BASE + 0x000c)
38 #define RPPX1_RPP_HDR_INFORM_ENABLE_ENABLE	1
39 #define RPPX1_RPP_HDR_INFORM_ENABLE_DISABLE	0
40 
41 #define RPPX1_RPP_HDR_OUT_IF_ON_REG		(RPPX1_HDRREGS_BASE + 0x0010)
42 #define RPPX1_RPP_HDR_OUT_IF_OFF_REG		(RPPX1_HDRREGS_BASE + 0x0014)
43 
44 #define RPPX1_RPP_HDR_SAFETY_ACCESS_PROTECTION_REG	(RPPX1_HDRREGS_BASE + 0x0018)
45 #define RPPX1_RPP_HDR_SAFETY_ACCESS_PROTECTION_ENABLE	1
46 #define RPPX1_RPP_HDR_SAFETY_ACCESS_PROTECTION_DISABLE	0
47 
48 #define RPPX1_RPP_ISM				(RPPX1_HDR_IRQ_BASE + 0x00)
49 #define RPPX1_RPP_RIS				(RPPX1_HDR_IRQ_BASE + 0x04)
50 #define RPPX1_RPP_MIS				(RPPX1_HDR_IRQ_BASE + 0x08)
51 #define RPPX1_RPP_ISC				(RPPX1_HDR_IRQ_BASE + 0x0c)
52 
53 /* RPP_OUT/MV_OUT Pipelines - Base Addresses */
54 #define RPPX1_GAMMA_OUT_BASE			0x0000 /* HV, MV */
55 #define RPPX1_IS_BASE				0x00c0 /* HV, MV */
56 #define RPPX1_CSM_BASE				0x0100 /* HV, MV */
57 #define RPPX1_OUT_IF_BASE			0x0200 /* HV, MV */
58 #define RPPX1_RPP_OUTREGS_BASE			0x02c0 /* HV, MV */
59 #define RPPX1_LUV_BASE				0x0300 /* MV */
60 
61 /* PRE1/PRE2/POST Pipelines - Base Addresses */
62 #define RPPX1_ACQ_BASE				0x0080 /* PRE1, PRE2 */
63 #define RPPX1_BLS_BASE				0x0100 /* PRE1, PRE2 */
64 #define RPPX1_GAMMA_IN_BASE			0x0200 /* PRE1, PRE2 */
65 #define RPPX1_LSC_BASE				0x0400 /* PRE1, PRE2 */
66 #define RPPX1_AWB_GAIN_BASE			0x0500 /* PRE1, PRE2, POST */
67 #define RPPX1_DPCC_BASE				0x0600 /* PRE1, PRE2 */
68 #define RPPX1_DPF_BASE				0x0700 /* PRE1, PRE2 */
69 #define RPPX1_FILT_BASE				0x0800 /* POST */
70 #define RPPX1_CAC_BASE				0x0880 /* POST */
71 #define RPPX1_CCOR_BASE				0x0900 /* POST */
72 #define RPPX1_HIST_BASE				0x0a00 /* PRE1, PRE2, POST */
73 #define RPPX1_HIST256_BASE			0x0b00 /* PRE1 */
74 #define RPPX1_EXM_BASE				0x0c00 /* PRE1, PRE2 */
75 #define RPPX1_LTM_BASE				0x1000 /* POST */
76 #define RPPX1_LTM_MEAS_BASE			0x1200 /* POST */
77 #define RPPX1_WBMEAS_BASE			0x1700 /* POST */
78 #define RPPX1_BDRGB_BASE			0x1800 /* POST */
79 #define RPPX1_SHRP_BASE				0x1a00 /* POST */
80 
81 /* Functional Safety Module Base Addresses */
82 #define RPPX1_FMU_BASE				0x0100
83 
84 #define RPPX1_RPP_HDR_FMU_FSM_REG		(RPPX1_RPP_FUSA_BASE + RPPX1_FMU_BASE + 0x00)
85 #define RPPX1_RPP_HDR_FMU_FSM_FSM_IRQM_FAULT	BIT(23)
86 #define RPPX1_RPP_HDR_FMU_FSM_PRE2_SIZE_FAULT	BIT(20)
87 #define RPPX1_RPP_HDR_FMU_FSM_PRE2_TIME_FAULT	BIT(19)
88 #define RPPX1_RPP_HDR_FMU_FSM_PRE1_SIZE_FAULT	BIT(18)
89 #define RPPX1_RPP_HDR_FMU_FSM_PRE1_TIME_FAULT	BIT(17)
90 #define RPPX1_RPP_HDR_FMU_FSM_SIZE_FAULT	BIT(16)
91 #define RPPX1_RPP_HDR_FMU_FSM_TIME_FAULT	BIT(15)
92 #define RPPX1_RPP_HDR_FMU_FSM_MV_OUT_SIZE_FAULT	BIT(14)
93 #define RPPX1_RPP_HDR_FMU_FSM_MV_OUT_TIME_FAULT	BIT(13)
94 #define RPPX1_RPP_HDR_FMU_FSM_HV_OUT_SIZE_FAULT	BIT(12)
95 #define RPPX1_RPP_HDR_FMU_FSM_HV_OUT_TIME_FAULT	BIT(11)
96 #define RPPX1_RPP_HDR_FMU_FSM_MV_OUT_SIZE_ERR	BIT(10)
97 #define RPPX1_RPP_HDR_FMU_FSM_IS_OUT_SIZE_ERR	BIT(9)
98 #define RPPX1_RPP_HDR_FMU_FSM_PRE2_FIFO_OVFLW	BIT(7)
99 #define RPPX1_RPP_HDR_FMU_FSM_PRE1_FIFO_OVFLW	BIT(6)
100 #define RPPX1_RPP_HDR_FMU_FSM_PRE1_INFORM_SIZE	BIT(5)
101 #define RPPX1_RPP_HDR_FMU_FSM_PRE1_OUTFORM_SIZE	BIT(4)
102 #define RPPX1_RPP_HDR_FMU_FSM_PRE2_INFORM_SIZE	BIT(3)
103 #define RPPX1_RPP_HDR_FMU_FSM_PRE2_OUTFORM_SIZE	BIT(2)
104 
105 #define RPPX1_RPP_HDR_FMU_RFS_REG		(RPPX1_RPP_FUSA_BASE + RPPX1_FMU_BASE + 0x04)
106 #define RPPX1_RPP_HDR_FMU_MFS_REG		(RPPX1_RPP_FUSA_BASE + RPPX1_FMU_BASE + 0x08)
107 #define RPPX1_RPP_HDR_FMU_FSC_REG		(RPPX1_RPP_FUSA_BASE + RPPX1_FMU_BASE + 0x0c)
108 
109 void rppx1_write(struct rppx1 *rpp, u32 offset, u32 value)
110 {
111 	iowrite32(value, rpp->base + offset);
112 }
113 
114 u32 rppx1_read(struct rppx1 *rpp, u32 offset)
115 {
116 	return ioread32(rpp->base + offset);
117 }
118 
119 bool rppx1_interrupt(struct rppx1 *rpp, u32 *isc)
120 {
121 	u32 status, raw, fault;
122 
123 	fault = rppx1_read(rpp, RPPX1_RPP_HDR_FMU_MFS_REG);
124 	if (fault) {
125 		dev_err(rpp->dev, "%s: fault 0x%08x\n", __func__, fault);
126 		rppx1_write(rpp, RPPX1_RPP_HDR_FMU_FSC_REG, fault);
127 	}
128 
129 	/* Read raw interrupt status. */
130 	raw = rppx1_read(rpp, RPPX1_RPP_RIS);
131 	status = rppx1_read(rpp, RPPX1_RPP_MIS);
132 
133 	/* Propagate the isc status. */
134 	if (isc)
135 		*isc = status | raw;
136 
137 	/* Clear enabled interrupts */
138 	rppx1_write(rpp, RPPX1_RPP_ISC, status);
139 
140 	return !!(status & RPPX1_IRQ_ID_OUT_FRAME);
141 }
142 EXPORT_SYMBOL_GPL(rppx1_interrupt);
143 
144 void rppx1_destroy(struct rppx1 *rpp)
145 {
146 	kfree(rpp);
147 }
148 EXPORT_SYMBOL_GPL(rppx1_destroy);
149 
150 /*
151  * Allocate the private data structure and verify the hardware is present.
152  */
153 struct rppx1 *rppx1_create(void __iomem *base, struct device *dev)
154 {
155 	struct rppx1 *rpp;
156 	u32 reg;
157 
158 	/* Allocate library structure */
159 	rpp = kzalloc_obj(*rpp);
160 	if (!rpp)
161 		return NULL;
162 
163 	rpp->base = base;
164 	rpp->dev = dev;
165 
166 	/* Check communication with RPP and verify it truly is a X1. */
167 	reg = rppx1_read(rpp, RPPX1_RPP_HDRREGS_VERSION_REG);
168 	if (reg != 3) {
169 		dev_err(rpp->dev, "Unsupported HDR version (%u)\n", reg);
170 		rppx1_destroy(rpp);
171 		return NULL;
172 	}
173 
174 	/* Probe the PRE1 pipeline. */
175 	if (rpp_module_probe(&rpp->pre1.acq, rpp, &rppx1_acq_ops,
176 			     RPPX1_RPP_MAIN_PRE1_BASE + RPPX1_ACQ_BASE) ||
177 	    rpp_module_probe(&rpp->pre1.bls, rpp, &rppx1_bls_ops,
178 			     RPPX1_RPP_MAIN_PRE1_BASE + RPPX1_BLS_BASE) ||
179 	    rpp_module_probe(&rpp->pre1.lin, rpp, &rppx1_lin_ops,
180 			     RPPX1_RPP_MAIN_PRE1_BASE + RPPX1_GAMMA_IN_BASE) ||
181 	    rpp_module_probe(&rpp->pre1.lsc, rpp, &rppx1_lsc_ops,
182 			     RPPX1_RPP_MAIN_PRE1_BASE + RPPX1_LSC_BASE) ||
183 	    rpp_module_probe(&rpp->pre1.awbg, rpp, &rppx1_awbg_ops,
184 			     RPPX1_RPP_MAIN_PRE1_BASE + RPPX1_AWB_GAIN_BASE) ||
185 	    rpp_module_probe(&rpp->pre1.dpcc, rpp, &rppx1_dpcc_ops,
186 			     RPPX1_RPP_MAIN_PRE1_BASE + RPPX1_DPCC_BASE) ||
187 	    rpp_module_probe(&rpp->pre1.bd, rpp, &rppx1_bd_ops,
188 			     RPPX1_RPP_MAIN_PRE1_BASE + RPPX1_DPF_BASE) ||
189 	    rpp_module_probe(&rpp->pre1.hist, rpp, &rppx1_hist_ops,
190 			     RPPX1_RPP_MAIN_PRE1_BASE + RPPX1_HIST_BASE) ||
191 	    rpp_module_probe(&rpp->pre1.hist256, rpp, &rppx1_hist256_ops,
192 			     RPPX1_RPP_MAIN_PRE1_BASE + RPPX1_HIST256_BASE) ||
193 	    rpp_module_probe(&rpp->pre1.exm, rpp, &rppx1_exm_ops,
194 			     RPPX1_RPP_MAIN_PRE1_BASE + RPPX1_EXM_BASE))
195 		goto err;
196 
197 	/* Probe the PRE2 pipeline. */
198 	if (rpp_module_probe(&rpp->pre2.acq, rpp, &rppx1_acq_ops,
199 			     RPPX1_RPP_MAIN_PRE2_BASE + RPPX1_ACQ_BASE) ||
200 	    rpp_module_probe(&rpp->pre2.bls, rpp, &rppx1_bls_ops,
201 			     RPPX1_RPP_MAIN_PRE2_BASE + RPPX1_BLS_BASE) ||
202 	    rpp_module_probe(&rpp->pre2.lin, rpp, &rppx1_lin_ops,
203 			     RPPX1_RPP_MAIN_PRE2_BASE + RPPX1_GAMMA_IN_BASE) ||
204 	    rpp_module_probe(&rpp->pre2.lsc, rpp, &rppx1_lsc_ops,
205 			     RPPX1_RPP_MAIN_PRE2_BASE + RPPX1_LSC_BASE) ||
206 	    rpp_module_probe(&rpp->pre2.awbg, rpp, &rppx1_awbg_ops,
207 			     RPPX1_RPP_MAIN_PRE2_BASE + RPPX1_AWB_GAIN_BASE) ||
208 	    rpp_module_probe(&rpp->pre2.dpcc, rpp, &rppx1_dpcc_ops,
209 			     RPPX1_RPP_MAIN_PRE2_BASE + RPPX1_DPCC_BASE) ||
210 	    rpp_module_probe(&rpp->pre2.bd, rpp, &rppx1_bd_ops,
211 			     RPPX1_RPP_MAIN_PRE2_BASE + RPPX1_DPF_BASE) ||
212 	    rpp_module_probe(&rpp->pre2.hist, rpp, &rppx1_hist_ops,
213 			     RPPX1_RPP_MAIN_PRE2_BASE + RPPX1_HIST_BASE) ||
214 	    rpp_module_probe(&rpp->pre2.exm, rpp, &rppx1_exm_ops,
215 			     RPPX1_RPP_MAIN_PRE2_BASE + RPPX1_EXM_BASE))
216 		goto err;
217 
218 	/* Probe the POST pipeline. */
219 	if (rpp_module_probe(&rpp->post.awbg, rpp, &rppx1_awbg_ops,
220 			     RPPX1_RPP_MAIN_POST_BASE + RPPX1_AWB_GAIN_BASE) ||
221 	    rpp_module_probe(&rpp->post.ccor, rpp, &rppx1_ccor_ops,
222 			     RPPX1_RPP_MAIN_POST_BASE + RPPX1_CCOR_BASE) ||
223 	    rpp_module_probe(&rpp->post.hist, rpp, &rppx1_hist_ops,
224 			     RPPX1_RPP_MAIN_POST_BASE + RPPX1_HIST_BASE) ||
225 	    rpp_module_probe(&rpp->post.db, rpp, &rppx1_db_ops,
226 			     RPPX1_RPP_MAIN_POST_BASE + RPPX1_FILT_BASE) ||
227 	    rpp_module_probe(&rpp->post.cac, rpp, &rppx1_cac_ops,
228 			     RPPX1_RPP_MAIN_POST_BASE + RPPX1_CAC_BASE) ||
229 	    rpp_module_probe(&rpp->post.ltm, rpp, &rppx1_ltm_ops,
230 			     RPPX1_RPP_MAIN_POST_BASE + RPPX1_LTM_BASE) ||
231 	    rpp_module_probe(&rpp->post.ltmmeas, rpp, &rppx1_ltmmeas_ops,
232 			     RPPX1_RPP_MAIN_POST_BASE + RPPX1_LTM_MEAS_BASE) ||
233 	    rpp_module_probe(&rpp->post.wbmeas, rpp, &rppx1_wbmeas_ops,
234 			     RPPX1_RPP_MAIN_POST_BASE + RPPX1_WBMEAS_BASE) ||
235 	    rpp_module_probe(&rpp->post.bdrgb, rpp, &rppx1_bdrgb_ops,
236 			     RPPX1_RPP_MAIN_POST_BASE + RPPX1_BDRGB_BASE) ||
237 	    rpp_module_probe(&rpp->post.shrp, rpp, &rppx1_shrp_ops,
238 			     RPPX1_RPP_MAIN_POST_BASE + RPPX1_SHRP_BASE))
239 		goto err;
240 
241 	/* Probe the Human Vision pipeline. */
242 	if (rpp_module_probe(&rpp->hv.ga, rpp, &rppx1_ga_ops,
243 			     RPPX1_RPP_OUT_BASE + RPPX1_GAMMA_OUT_BASE) ||
244 	    rpp_module_probe(&rpp->hv.is, rpp, &rppx1_is_ops,
245 			     RPPX1_RPP_OUT_BASE + RPPX1_IS_BASE) ||
246 	    rpp_module_probe(&rpp->hv.ccor, rpp, &rppx1_ccor_csm_ops,
247 			     RPPX1_RPP_OUT_BASE + RPPX1_CSM_BASE) ||
248 	    rpp_module_probe(&rpp->hv.outif, rpp, &rppx1_outif_ops,
249 			     RPPX1_RPP_OUT_BASE + RPPX1_OUT_IF_BASE) ||
250 	    rpp_module_probe(&rpp->hv.outregs, rpp, &rppx1_outregs_ops,
251 			     RPPX1_RPP_OUT_BASE + RPPX1_RPP_OUTREGS_BASE))
252 		goto err;
253 
254 	/* Probe the Machine Vision pipeline. */
255 	if (rpp_module_probe(&rpp->mv.ga, rpp, &rppx1_ga_ops,
256 			     RPPX1_RPP_MVOUT_BASE + RPPX1_GAMMA_OUT_BASE) ||
257 	    rpp_module_probe(&rpp->mv.is, rpp, &rppx1_is_ops,
258 			     RPPX1_RPP_MVOUT_BASE + RPPX1_IS_BASE) ||
259 	    rpp_module_probe(&rpp->mv.ccor, rpp, &rppx1_ccor_csm_ops,
260 			     RPPX1_RPP_MVOUT_BASE + RPPX1_CSM_BASE) ||
261 	    rpp_module_probe(&rpp->mv.outif, rpp, &rppx1_outif_ops,
262 			     RPPX1_RPP_MVOUT_BASE + RPPX1_OUT_IF_BASE) ||
263 	    rpp_module_probe(&rpp->mv.outregs, rpp, &rppx1_outregs_ops,
264 			     RPPX1_RPP_MVOUT_BASE + RPPX1_RPP_OUTREGS_BASE) ||
265 	    rpp_module_probe(&rpp->mv.xyz2luv, rpp, &rppx1_xyz2luv_ops,
266 			     RPPX1_RPP_MVOUT_BASE + RPPX1_LUV_BASE))
267 		goto err;
268 
269 	/* Probe the standalone Radiance Mapping modules. */
270 	if (rpp_module_probe(&rpp->rmap, rpp, &rppx1_rmap_ops,
271 			     RPPX1_RPP_RMAP_BASE) ||
272 	    rpp_module_probe(&rpp->rmapmeas, rpp, &rppx1_rmapmeas_ops,
273 			     RPPX1_RPP_RMAP_MEAS_BASE))
274 		goto err;
275 
276 	return rpp;
277 err:
278 	rppx1_destroy(rpp);
279 
280 	return NULL;
281 }
282 EXPORT_SYMBOL_GPL(rppx1_create);
283 
284 int rppx1_start(struct rppx1 *rpp,
285 		const struct v4l2_mbus_framefmt *input,
286 		const struct v4l2_mbus_framefmt *hv,
287 		const struct v4l2_mbus_framefmt *mv)
288 {
289 	if (rpp_module_call(&rpp->pre1.acq, start, input) ||
290 	    rpp_module_call(&rpp->pre1.bls, start, input) ||
291 	    rpp_module_call(&rpp->pre1.lin, start, input) ||
292 	    rpp_module_call(&rpp->pre1.lsc, start, input) ||
293 	    rpp_module_call(&rpp->pre1.awbg, start, input) ||
294 	    rpp_module_call(&rpp->pre1.dpcc, start, input) ||
295 	    rpp_module_call(&rpp->pre1.bd, start, input) ||
296 	    rpp_module_call(&rpp->pre1.hist, start, input) ||
297 	    rpp_module_call(&rpp->pre1.exm, start, input) ||
298 	    rpp_module_call(&rpp->pre1.hist256, start, input))
299 		return -EINVAL;
300 
301 	if (rpp_module_call(&rpp->rmap, start, NULL) ||
302 	    rpp_module_call(&rpp->rmapmeas, start, NULL))
303 		return -EINVAL;
304 
305 	if (rpp_module_call(&rpp->post.awbg, start, input) ||
306 	    rpp_module_call(&rpp->post.db, start, input) ||
307 	    rpp_module_call(&rpp->post.cac, start, input) ||
308 	    rpp_module_call(&rpp->post.ccor, start, input) ||
309 	    rpp_module_call(&rpp->post.ltm, start, input) ||
310 	    rpp_module_call(&rpp->post.bdrgb, start, input) ||
311 	    rpp_module_call(&rpp->post.shrp, start, input) ||
312 	    rpp_module_call(&rpp->post.ltmmeas, start, input) ||
313 	    rpp_module_call(&rpp->post.wbmeas, start, input) ||
314 	    rpp_module_call(&rpp->post.hist, start, input))
315 		return -EINVAL;
316 
317 	if (hv && (rpp_module_call(&rpp->hv.ga, start, hv) ||
318 		   rpp_module_call(&rpp->hv.ccor, start, hv) ||
319 		   rpp_module_call(&rpp->hv.outregs, start, hv) ||
320 		   rpp_module_call(&rpp->hv.is, start, hv) ||
321 		   rpp_module_call(&rpp->hv.outif, start, hv)))
322 		return -EINVAL;
323 
324 	if (mv && (rpp_module_call(&rpp->mv.ga, start, mv) ||
325 		   rpp_module_call(&rpp->mv.ccor, start, mv) ||
326 		   rpp_module_call(&rpp->mv.xyz2luv, start, mv) ||
327 		   rpp_module_call(&rpp->mv.outregs, start, mv) ||
328 		   rpp_module_call(&rpp->mv.is, start, mv) ||
329 		   rpp_module_call(&rpp->mv.outif, start, mv)))
330 		return -EINVAL;
331 
332 	/* Immediate update for shadows. */
333 	rppx1_write(rpp, RPPX1_RPP_HDR_UPD_REG, RPPX1_RPP_HDR_UPD_REGS_CFG_UPD);
334 
335 	/* Clear fault interrupts. */
336 	rppx1_write(rpp, RPPX1_RPP_HDR_SAFETY_ACCESS_PROTECTION_REG,
337 		    RPPX1_RPP_HDR_SAFETY_ACCESS_PROTECTION_ENABLE);
338 	rppx1_write(rpp, RPPX1_RPP_HDR_FMU_FSM_REG,
339 		    RPPX1_RPP_HDR_FMU_FSM_PRE2_FIFO_OVFLW |
340 		    RPPX1_RPP_HDR_FMU_FSM_PRE1_FIFO_OVFLW);
341 	rppx1_write(rpp, RPPX1_RPP_HDR_FMU_FSC_REG,
342 		    rppx1_read(rpp, RPPX1_RPP_HDR_FMU_MFS_REG));
343 	rppx1_write(rpp, RPPX1_RPP_HDR_SAFETY_ACCESS_PROTECTION_REG,
344 		    RPPX1_RPP_HDR_SAFETY_ACCESS_PROTECTION_DISABLE);
345 
346 	/* Set interrupt mask. */
347 	rppx1_write(rpp, RPPX1_RPP_ISM, RPPX1_IRQ_ID_OUT_FRAME);
348 
349 	/* Immediate commit update for shadows. */
350 	rppx1_write(rpp, RPPX1_RPP_HDR_UPD_REG, RPPX1_RPP_HDR_UPD_REGS_CFG_UPD);
351 
352 	/* Then for operation update shadows with picture synchronization. */
353 	rppx1_write(rpp, RPPX1_RPP_HDR_UPD_REG, RPPX1_RPP_HDR_UPD_REGS_GEN_CFG_UPD);
354 
355 	/* Clear any pending interrupts. */
356 	rppx1_interrupt(rpp, NULL);
357 
358 	/* Enable input formatters. */
359 	rppx1_write(rpp, RPPX1_RPP_HDR_INFORM_ENABLE_REG,
360 		    RPPX1_RPP_HDR_INFORM_ENABLE_ENABLE);
361 
362 	return 0;
363 }
364 EXPORT_SYMBOL_GPL(rppx1_start);
365 
366 int rppx1_stop(struct rppx1 *rpp)
367 {
368 	/* Disable input formatters. */
369 	rppx1_write(rpp, RPPX1_RPP_HDR_INFORM_ENABLE_REG,
370 		    RPPX1_RPP_HDR_INFORM_ENABLE_DISABLE);
371 
372 	/* Clear any pending interrupts. */
373 	rppx1_interrupt(rpp, NULL);
374 
375 	return 0;
376 }
377 EXPORT_SYMBOL_GPL(rppx1_stop);
378 
379 MODULE_AUTHOR("Niklas Söderlund <niklas.soderlund@ragnatech.se>");
380 MODULE_DESCRIPTION("Dreamchip HDR RPPX1 support library");
381 MODULE_LICENSE("GPL");
382