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