10d6d5f49SVikram Sharma // SPDX-License-Identifier: GPL-2.0 20d6d5f49SVikram Sharma /* 30d6d5f49SVikram Sharma * Qualcomm MSM Camera Subsystem - CSID (CSI Decoder) Module 40d6d5f49SVikram Sharma * 50d6d5f49SVikram Sharma * Copyright (c) 2024 Qualcomm Technologies, Inc. 60d6d5f49SVikram Sharma */ 70d6d5f49SVikram Sharma #include <linux/completion.h> 80d6d5f49SVikram Sharma #include <linux/delay.h> 90d6d5f49SVikram Sharma #include <linux/interrupt.h> 100d6d5f49SVikram Sharma #include <linux/io.h> 110d6d5f49SVikram Sharma #include <linux/kernel.h> 120d6d5f49SVikram Sharma #include <linux/of.h> 130d6d5f49SVikram Sharma 140d6d5f49SVikram Sharma #include "camss.h" 150d6d5f49SVikram Sharma #include "camss-csid.h" 160d6d5f49SVikram Sharma #include "camss-csid-gen3.h" 170d6d5f49SVikram Sharma 180d6d5f49SVikram Sharma #define CSID_IO_PATH_CFG0(csid) (0x4 * (csid)) 190d6d5f49SVikram Sharma #define OUTPUT_IFE_EN 0x100 200d6d5f49SVikram Sharma #define INTERNAL_CSID 1 210d6d5f49SVikram Sharma 220d6d5f49SVikram Sharma #define CSID_RST_CFG 0xC 230d6d5f49SVikram Sharma #define RST_MODE BIT(0) 240d6d5f49SVikram Sharma #define RST_LOCATION BIT(4) 250d6d5f49SVikram Sharma 260d6d5f49SVikram Sharma #define CSID_RST_CMD 0x10 270d6d5f49SVikram Sharma #define SELECT_HW_RST BIT(0) 280d6d5f49SVikram Sharma #define SELECT_IRQ_RST BIT(2) 290d6d5f49SVikram Sharma 300d6d5f49SVikram Sharma #define CSID_IRQ_CMD 0x14 310d6d5f49SVikram Sharma #define IRQ_CMD_CLEAR BIT(0) 320d6d5f49SVikram Sharma 330d6d5f49SVikram Sharma #define CSID_RUP_AUP_CMD 0x18 340d6d5f49SVikram Sharma #define CSID_RUP_AUP_RDI(rdi) ((BIT(4) | BIT(20)) << (rdi)) 350d6d5f49SVikram Sharma 360d6d5f49SVikram Sharma #define CSID_TOP_IRQ_STATUS 0x7C 370d6d5f49SVikram Sharma #define TOP_IRQ_STATUS_RESET_DONE BIT(0) 380d6d5f49SVikram Sharma 390d6d5f49SVikram Sharma #define CSID_TOP_IRQ_MASK 0x80 400d6d5f49SVikram Sharma #define CSID_TOP_IRQ_CLEAR 0x84 410d6d5f49SVikram Sharma #define CSID_TOP_IRQ_SET 0x88 420d6d5f49SVikram Sharma 430d6d5f49SVikram Sharma #define CSID_CSI2_RX_IRQ_STATUS 0x9C 440d6d5f49SVikram Sharma #define CSID_CSI2_RX_IRQ_MASK 0xA0 450d6d5f49SVikram Sharma #define CSID_CSI2_RX_IRQ_CLEAR 0xA4 460d6d5f49SVikram Sharma #define CSID_CSI2_RX_IRQ_SET 0xA8 470d6d5f49SVikram Sharma 48*950f3d30SVikram Sharma #define IS_CSID_690(csid) ((csid->camss->res->version == CAMSS_8775P) \ 49*950f3d30SVikram Sharma || (csid->camss->res->version == CAMSS_8300)) 500d6d5f49SVikram Sharma #define CSID_BUF_DONE_IRQ_STATUS 0x8C 51ed03e99dSVikram Sharma #define BUF_DONE_IRQ_STATUS_RDI_OFFSET (csid_is_lite(csid) ?\ 52ed03e99dSVikram Sharma 1 : (IS_CSID_690(csid) ?\ 53ed03e99dSVikram Sharma 13 : 14)) 540d6d5f49SVikram Sharma #define CSID_BUF_DONE_IRQ_MASK 0x90 550d6d5f49SVikram Sharma #define CSID_BUF_DONE_IRQ_CLEAR 0x94 560d6d5f49SVikram Sharma #define CSID_BUF_DONE_IRQ_SET 0x98 570d6d5f49SVikram Sharma 580d6d5f49SVikram Sharma #define CSID_CSI2_RDIN_IRQ_STATUS(rdi) (0xEC + 0x10 * (rdi)) 590d6d5f49SVikram Sharma #define RUP_DONE_IRQ_STATUS BIT(23) 600d6d5f49SVikram Sharma 610d6d5f49SVikram Sharma #define CSID_CSI2_RDIN_IRQ_CLEAR(rdi) (0xF4 + 0x10 * (rdi)) 620d6d5f49SVikram Sharma #define CSID_CSI2_RDIN_IRQ_SET(rdi) (0xF8 + 0x10 * (rdi)) 630d6d5f49SVikram Sharma 640d6d5f49SVikram Sharma #define CSID_CSI2_RX_CFG0 0x200 650d6d5f49SVikram Sharma #define CSI2_RX_CFG0_NUM_ACTIVE_LANES 0 66ed03e99dSVikram Sharma #define CSI2_RX_CFG0_VC_MODE 3 670d6d5f49SVikram Sharma #define CSI2_RX_CFG0_DL0_INPUT_SEL 4 680d6d5f49SVikram Sharma #define CSI2_RX_CFG0_PHY_NUM_SEL 20 690d6d5f49SVikram Sharma 700d6d5f49SVikram Sharma #define CSID_CSI2_RX_CFG1 0x204 710d6d5f49SVikram Sharma #define CSI2_RX_CFG1_ECC_CORRECTION_EN BIT(0) 720d6d5f49SVikram Sharma #define CSI2_RX_CFG1_VC_MODE BIT(2) 730d6d5f49SVikram Sharma 74ed03e99dSVikram Sharma #define CSID_RDI_CFG0(rdi) (csid_is_lite(csid) && IS_CSID_690(csid) ?\ 75ed03e99dSVikram Sharma (0x300 + 0x100 * (rdi)) :\ 76ed03e99dSVikram Sharma (0x500 + 0x100 * (rdi))) 770d6d5f49SVikram Sharma #define RDI_CFG0_TIMESTAMP_EN BIT(6) 780d6d5f49SVikram Sharma #define RDI_CFG0_TIMESTAMP_STB_SEL BIT(8) 790d6d5f49SVikram Sharma #define RDI_CFG0_DECODE_FORMAT 12 800d6d5f49SVikram Sharma #define RDI_CFG0_DT 16 810d6d5f49SVikram Sharma #define RDI_CFG0_VC 22 820d6d5f49SVikram Sharma #define RDI_CFG0_DT_ID 27 830d6d5f49SVikram Sharma #define RDI_CFG0_EN BIT(31) 840d6d5f49SVikram Sharma 85ed03e99dSVikram Sharma #define CSID_RDI_CTRL(rdi) (csid_is_lite(csid) && IS_CSID_690(csid) ?\ 86ed03e99dSVikram Sharma (0x304 + 0x100 * (rdi)) :\ 87ed03e99dSVikram Sharma (0x504 + 0x100 * (rdi))) 880d6d5f49SVikram Sharma #define RDI_CTRL_START_CMD BIT(0) 890d6d5f49SVikram Sharma 90ed03e99dSVikram Sharma #define CSID_RDI_CFG1(rdi) (csid_is_lite(csid) && IS_CSID_690(csid) ?\ 91ed03e99dSVikram Sharma (0x310 + 0x100 * (rdi)) :\ 92ed03e99dSVikram Sharma (0x510 + 0x100 * (rdi))) 930d6d5f49SVikram Sharma #define RDI_CFG1_DROP_H_EN BIT(5) 940d6d5f49SVikram Sharma #define RDI_CFG1_DROP_V_EN BIT(6) 950d6d5f49SVikram Sharma #define RDI_CFG1_CROP_H_EN BIT(7) 960d6d5f49SVikram Sharma #define RDI_CFG1_CROP_V_EN BIT(8) 970d6d5f49SVikram Sharma #define RDI_CFG1_PIX_STORE BIT(10) 980d6d5f49SVikram Sharma #define RDI_CFG1_PACKING_FORMAT_MIPI BIT(15) 990d6d5f49SVikram Sharma 100ed03e99dSVikram Sharma #define CSID_RDI_IRQ_SUBSAMPLE_PATTERN(rdi) (csid_is_lite(csid) && IS_CSID_690(csid) ?\ 101ed03e99dSVikram Sharma (0x348 + 0x100 * (rdi)) :\ 102ed03e99dSVikram Sharma (0x548 + 0x100 * (rdi))) 103ed03e99dSVikram Sharma #define CSID_RDI_IRQ_SUBSAMPLE_PERIOD(rdi) (csid_is_lite(csid) && IS_CSID_690(csid) ?\ 104ed03e99dSVikram Sharma (0x34C + 0x100 * (rdi)) :\ 105ed03e99dSVikram Sharma (0x54C + 0x100 * (rdi))) 1060d6d5f49SVikram Sharma #define CSI2_RX_CFG0_PHY_SEL_BASE_IDX 1 1070d6d5f49SVikram Sharma 1080d6d5f49SVikram Sharma static void __csid_configure_rx(struct csid_device *csid, 1090d6d5f49SVikram Sharma struct csid_phy_config *phy, int vc) 1100d6d5f49SVikram Sharma { 1110d6d5f49SVikram Sharma int val; 1120d6d5f49SVikram Sharma 1130d6d5f49SVikram Sharma val = (phy->lane_cnt - 1) << CSI2_RX_CFG0_NUM_ACTIVE_LANES; 1140d6d5f49SVikram Sharma val |= phy->lane_assign << CSI2_RX_CFG0_DL0_INPUT_SEL; 1150d6d5f49SVikram Sharma val |= (phy->csiphy_id + CSI2_RX_CFG0_PHY_SEL_BASE_IDX) << CSI2_RX_CFG0_PHY_NUM_SEL; 1160d6d5f49SVikram Sharma 1170d6d5f49SVikram Sharma writel(val, csid->base + CSID_CSI2_RX_CFG0); 1180d6d5f49SVikram Sharma 1190d6d5f49SVikram Sharma val = CSI2_RX_CFG1_ECC_CORRECTION_EN; 1200d6d5f49SVikram Sharma if (vc > 3) 1210d6d5f49SVikram Sharma val |= CSI2_RX_CFG1_VC_MODE; 1220d6d5f49SVikram Sharma 1230d6d5f49SVikram Sharma writel(val, csid->base + CSID_CSI2_RX_CFG1); 1240d6d5f49SVikram Sharma } 1250d6d5f49SVikram Sharma 1260d6d5f49SVikram Sharma static void __csid_ctrl_rdi(struct csid_device *csid, int enable, u8 rdi) 1270d6d5f49SVikram Sharma { 1280d6d5f49SVikram Sharma int val = 0; 1290d6d5f49SVikram Sharma 1300d6d5f49SVikram Sharma if (enable) 1310d6d5f49SVikram Sharma val = RDI_CTRL_START_CMD; 1320d6d5f49SVikram Sharma 1330d6d5f49SVikram Sharma writel(val, csid->base + CSID_RDI_CTRL(rdi)); 1340d6d5f49SVikram Sharma } 1350d6d5f49SVikram Sharma 1360d6d5f49SVikram Sharma static void __csid_configure_wrapper(struct csid_device *csid) 1370d6d5f49SVikram Sharma { 1380d6d5f49SVikram Sharma u32 val; 1390d6d5f49SVikram Sharma 1400d6d5f49SVikram Sharma /* csid lite doesn't need to configure top register */ 1410d6d5f49SVikram Sharma if (csid->res->is_lite) 1420d6d5f49SVikram Sharma return; 1430d6d5f49SVikram Sharma 1440d6d5f49SVikram Sharma val = OUTPUT_IFE_EN | INTERNAL_CSID; 1450d6d5f49SVikram Sharma writel(val, csid->camss->csid_wrapper_base + CSID_IO_PATH_CFG0(csid->id)); 1460d6d5f49SVikram Sharma } 1470d6d5f49SVikram Sharma 1480d6d5f49SVikram Sharma static void __csid_configure_rdi_stream(struct csid_device *csid, u8 enable, u8 vc) 1490d6d5f49SVikram Sharma { 1500d6d5f49SVikram Sharma u32 val; 1510d6d5f49SVikram Sharma u8 lane_cnt = csid->phy.lane_cnt; 1520d6d5f49SVikram Sharma /* Source pads matching RDI channels on hardware. Pad 1 -> RDI0, Pad 2 -> RDI1, etc. */ 1530d6d5f49SVikram Sharma struct v4l2_mbus_framefmt *input_format = &csid->fmt[MSM_CSID_PAD_FIRST_SRC + vc]; 1540d6d5f49SVikram Sharma const struct csid_format_info *format = csid_get_fmt_entry(csid->res->formats->formats, 1550d6d5f49SVikram Sharma csid->res->formats->nformats, 1560d6d5f49SVikram Sharma input_format->code); 1570d6d5f49SVikram Sharma 1580d6d5f49SVikram Sharma if (!lane_cnt) 1590d6d5f49SVikram Sharma lane_cnt = 4; 1600d6d5f49SVikram Sharma 1610d6d5f49SVikram Sharma /* 1620d6d5f49SVikram Sharma * DT_ID is a two bit bitfield that is concatenated with 1630d6d5f49SVikram Sharma * the four least significant bits of the five bit VC 1640d6d5f49SVikram Sharma * bitfield to generate an internal CID value. 1650d6d5f49SVikram Sharma * 1660d6d5f49SVikram Sharma * CSID_RDI_CFG0(vc) 1670d6d5f49SVikram Sharma * DT_ID : 28:27 1680d6d5f49SVikram Sharma * VC : 26:22 1690d6d5f49SVikram Sharma * DT : 21:16 1700d6d5f49SVikram Sharma * 1710d6d5f49SVikram Sharma * CID : VC 3:0 << 2 | DT_ID 1:0 1720d6d5f49SVikram Sharma */ 1730d6d5f49SVikram Sharma u8 dt_id = vc & 0x03; 1740d6d5f49SVikram Sharma 1750d6d5f49SVikram Sharma val = RDI_CFG0_TIMESTAMP_EN; 1760d6d5f49SVikram Sharma val |= RDI_CFG0_TIMESTAMP_STB_SEL; 1770d6d5f49SVikram Sharma /* note: for non-RDI path, this should be format->decode_format */ 1780d6d5f49SVikram Sharma val |= DECODE_FORMAT_PAYLOAD_ONLY << RDI_CFG0_DECODE_FORMAT; 1790d6d5f49SVikram Sharma val |= vc << RDI_CFG0_VC; 1800d6d5f49SVikram Sharma val |= format->data_type << RDI_CFG0_DT; 1810d6d5f49SVikram Sharma val |= dt_id << RDI_CFG0_DT_ID; 1820d6d5f49SVikram Sharma 1830d6d5f49SVikram Sharma writel(val, csid->base + CSID_RDI_CFG0(vc)); 1840d6d5f49SVikram Sharma 1850d6d5f49SVikram Sharma val = RDI_CFG1_PACKING_FORMAT_MIPI; 1860d6d5f49SVikram Sharma val |= RDI_CFG1_PIX_STORE; 1870d6d5f49SVikram Sharma val |= RDI_CFG1_DROP_H_EN; 1880d6d5f49SVikram Sharma val |= RDI_CFG1_DROP_V_EN; 1890d6d5f49SVikram Sharma val |= RDI_CFG1_CROP_H_EN; 1900d6d5f49SVikram Sharma val |= RDI_CFG1_CROP_V_EN; 1910d6d5f49SVikram Sharma 1920d6d5f49SVikram Sharma writel(val, csid->base + CSID_RDI_CFG1(vc)); 1930d6d5f49SVikram Sharma 1940d6d5f49SVikram Sharma val = 0; 1950d6d5f49SVikram Sharma writel(val, csid->base + CSID_RDI_IRQ_SUBSAMPLE_PERIOD(vc)); 1960d6d5f49SVikram Sharma 1970d6d5f49SVikram Sharma val = 1; 1980d6d5f49SVikram Sharma writel(val, csid->base + CSID_RDI_IRQ_SUBSAMPLE_PATTERN(vc)); 1990d6d5f49SVikram Sharma 2000d6d5f49SVikram Sharma val = 0; 2010d6d5f49SVikram Sharma writel(val, csid->base + CSID_RDI_CTRL(vc)); 2020d6d5f49SVikram Sharma 2030d6d5f49SVikram Sharma val = readl(csid->base + CSID_RDI_CFG0(vc)); 2040d6d5f49SVikram Sharma 2050d6d5f49SVikram Sharma if (enable) 2060d6d5f49SVikram Sharma val |= RDI_CFG0_EN; 2070d6d5f49SVikram Sharma writel(val, csid->base + CSID_RDI_CFG0(vc)); 2080d6d5f49SVikram Sharma } 2090d6d5f49SVikram Sharma 2100d6d5f49SVikram Sharma static void csid_configure_stream(struct csid_device *csid, u8 enable) 2110d6d5f49SVikram Sharma { 2120d6d5f49SVikram Sharma u8 i; 2130d6d5f49SVikram Sharma 2140d6d5f49SVikram Sharma __csid_configure_wrapper(csid); 2150d6d5f49SVikram Sharma 2160d6d5f49SVikram Sharma /* Loop through all enabled VCs and configure stream for each */ 2170d6d5f49SVikram Sharma for (i = 0; i < MSM_CSID_MAX_SRC_STREAMS; i++) 2180d6d5f49SVikram Sharma if (csid->phy.en_vc & BIT(i)) { 2190d6d5f49SVikram Sharma __csid_configure_rdi_stream(csid, enable, i); 2200d6d5f49SVikram Sharma __csid_configure_rx(csid, &csid->phy, i); 2210d6d5f49SVikram Sharma __csid_ctrl_rdi(csid, enable, i); 2220d6d5f49SVikram Sharma } 2230d6d5f49SVikram Sharma } 2240d6d5f49SVikram Sharma 2250d6d5f49SVikram Sharma static int csid_configure_testgen_pattern(struct csid_device *csid, s32 val) 2260d6d5f49SVikram Sharma { 2270d6d5f49SVikram Sharma return 0; 2280d6d5f49SVikram Sharma } 2290d6d5f49SVikram Sharma 2300d6d5f49SVikram Sharma static void csid_subdev_reg_update(struct csid_device *csid, int port_id, bool clear) 2310d6d5f49SVikram Sharma { 2320d6d5f49SVikram Sharma if (clear) { 2330d6d5f49SVikram Sharma csid->reg_update &= ~CSID_RUP_AUP_RDI(port_id); 2340d6d5f49SVikram Sharma } else { 2350d6d5f49SVikram Sharma csid->reg_update |= CSID_RUP_AUP_RDI(port_id); 2360d6d5f49SVikram Sharma writel(csid->reg_update, csid->base + CSID_RUP_AUP_CMD); 2370d6d5f49SVikram Sharma } 2380d6d5f49SVikram Sharma } 2390d6d5f49SVikram Sharma 2400d6d5f49SVikram Sharma /* 2410d6d5f49SVikram Sharma * csid_isr - CSID module interrupt service routine 2420d6d5f49SVikram Sharma * @irq: Interrupt line 2430d6d5f49SVikram Sharma * @dev: CSID device 2440d6d5f49SVikram Sharma * 2450d6d5f49SVikram Sharma * Return IRQ_HANDLED on success 2460d6d5f49SVikram Sharma */ 2470d6d5f49SVikram Sharma static irqreturn_t csid_isr(int irq, void *dev) 2480d6d5f49SVikram Sharma { 2490d6d5f49SVikram Sharma struct csid_device *csid = dev; 2500d6d5f49SVikram Sharma u32 val, buf_done_val; 2510d6d5f49SVikram Sharma u8 reset_done; 2520d6d5f49SVikram Sharma int i; 2530d6d5f49SVikram Sharma 2540d6d5f49SVikram Sharma val = readl(csid->base + CSID_TOP_IRQ_STATUS); 2550d6d5f49SVikram Sharma writel(val, csid->base + CSID_TOP_IRQ_CLEAR); 2560d6d5f49SVikram Sharma reset_done = val & TOP_IRQ_STATUS_RESET_DONE; 2570d6d5f49SVikram Sharma 2580d6d5f49SVikram Sharma val = readl(csid->base + CSID_CSI2_RX_IRQ_STATUS); 2590d6d5f49SVikram Sharma writel(val, csid->base + CSID_CSI2_RX_IRQ_CLEAR); 2600d6d5f49SVikram Sharma 2610d6d5f49SVikram Sharma buf_done_val = readl(csid->base + CSID_BUF_DONE_IRQ_STATUS); 2620d6d5f49SVikram Sharma writel(buf_done_val, csid->base + CSID_BUF_DONE_IRQ_CLEAR); 2630d6d5f49SVikram Sharma 2640d6d5f49SVikram Sharma /* Read and clear IRQ status for each enabled RDI channel */ 2650d6d5f49SVikram Sharma for (i = 0; i < MSM_CSID_MAX_SRC_STREAMS; i++) 2660d6d5f49SVikram Sharma if (csid->phy.en_vc & BIT(i)) { 2670d6d5f49SVikram Sharma val = readl(csid->base + CSID_CSI2_RDIN_IRQ_STATUS(i)); 2680d6d5f49SVikram Sharma writel(val, csid->base + CSID_CSI2_RDIN_IRQ_CLEAR(i)); 2690d6d5f49SVikram Sharma 2700d6d5f49SVikram Sharma if (val & RUP_DONE_IRQ_STATUS) 2710d6d5f49SVikram Sharma /* clear the reg update bit */ 2720d6d5f49SVikram Sharma csid_subdev_reg_update(csid, i, true); 2730d6d5f49SVikram Sharma 2740d6d5f49SVikram Sharma if (buf_done_val & BIT(BUF_DONE_IRQ_STATUS_RDI_OFFSET + i)) { 2750d6d5f49SVikram Sharma /* 2760d6d5f49SVikram Sharma * For Titan Gen3, bus done and RUP IRQ have been moved to 2770d6d5f49SVikram Sharma * CSID from VFE. Once CSID received bus done, need notify 2780d6d5f49SVikram Sharma * VFE of this event. Trigger VFE to handle bus done process. 2790d6d5f49SVikram Sharma */ 2800d6d5f49SVikram Sharma camss_buf_done(csid->camss, csid->id, i); 2810d6d5f49SVikram Sharma } 2820d6d5f49SVikram Sharma } 2830d6d5f49SVikram Sharma 2840d6d5f49SVikram Sharma val = IRQ_CMD_CLEAR; 2850d6d5f49SVikram Sharma writel(val, csid->base + CSID_IRQ_CMD); 2860d6d5f49SVikram Sharma 2870d6d5f49SVikram Sharma if (reset_done) 2880d6d5f49SVikram Sharma complete(&csid->reset_complete); 2890d6d5f49SVikram Sharma 2900d6d5f49SVikram Sharma return IRQ_HANDLED; 2910d6d5f49SVikram Sharma } 2920d6d5f49SVikram Sharma 2930d6d5f49SVikram Sharma /* 2940d6d5f49SVikram Sharma * csid_reset - Trigger reset on CSID module and wait to complete 2950d6d5f49SVikram Sharma * @csid: CSID device 2960d6d5f49SVikram Sharma * 2970d6d5f49SVikram Sharma * Return 0 on success or a negative error code otherwise 2980d6d5f49SVikram Sharma */ 2990d6d5f49SVikram Sharma static int csid_reset(struct csid_device *csid) 3000d6d5f49SVikram Sharma { 3010d6d5f49SVikram Sharma unsigned long time; 3020d6d5f49SVikram Sharma u32 val; 3030d6d5f49SVikram Sharma int i; 3040d6d5f49SVikram Sharma 3050d6d5f49SVikram Sharma reinit_completion(&csid->reset_complete); 3060d6d5f49SVikram Sharma 3070d6d5f49SVikram Sharma writel(1, csid->base + CSID_TOP_IRQ_CLEAR); 3080d6d5f49SVikram Sharma writel(1, csid->base + CSID_IRQ_CMD); 3090d6d5f49SVikram Sharma writel(1, csid->base + CSID_TOP_IRQ_MASK); 3100d6d5f49SVikram Sharma 3110d6d5f49SVikram Sharma for (i = 0; i < MSM_CSID_MAX_SRC_STREAMS; i++) 3120d6d5f49SVikram Sharma if (csid->phy.en_vc & BIT(i)) { 3130d6d5f49SVikram Sharma writel(BIT(BUF_DONE_IRQ_STATUS_RDI_OFFSET + i), 3140d6d5f49SVikram Sharma csid->base + CSID_BUF_DONE_IRQ_CLEAR); 3150d6d5f49SVikram Sharma writel(IRQ_CMD_CLEAR, csid->base + CSID_IRQ_CMD); 3160d6d5f49SVikram Sharma writel(BIT(BUF_DONE_IRQ_STATUS_RDI_OFFSET + i), 3170d6d5f49SVikram Sharma csid->base + CSID_BUF_DONE_IRQ_MASK); 3180d6d5f49SVikram Sharma } 3190d6d5f49SVikram Sharma 3200d6d5f49SVikram Sharma /* preserve registers */ 3210d6d5f49SVikram Sharma val = RST_LOCATION | RST_MODE; 3220d6d5f49SVikram Sharma writel(val, csid->base + CSID_RST_CFG); 3230d6d5f49SVikram Sharma 3240d6d5f49SVikram Sharma val = SELECT_HW_RST | SELECT_IRQ_RST; 3250d6d5f49SVikram Sharma writel(val, csid->base + CSID_RST_CMD); 3260d6d5f49SVikram Sharma 3270d6d5f49SVikram Sharma time = wait_for_completion_timeout(&csid->reset_complete, 3280d6d5f49SVikram Sharma msecs_to_jiffies(CSID_RESET_TIMEOUT_MS)); 3290d6d5f49SVikram Sharma if (!time) { 3300d6d5f49SVikram Sharma dev_err(csid->camss->dev, "CSID reset timeout\n"); 3310d6d5f49SVikram Sharma return -EIO; 3320d6d5f49SVikram Sharma } 3330d6d5f49SVikram Sharma 3340d6d5f49SVikram Sharma return 0; 3350d6d5f49SVikram Sharma } 3360d6d5f49SVikram Sharma 3370d6d5f49SVikram Sharma static void csid_subdev_init(struct csid_device *csid) 3380d6d5f49SVikram Sharma { 3390d6d5f49SVikram Sharma csid->testgen.nmodes = CSID_PAYLOAD_MODE_DISABLED; 3400d6d5f49SVikram Sharma } 3410d6d5f49SVikram Sharma 3420d6d5f49SVikram Sharma const struct csid_hw_ops csid_ops_gen3 = { 3430d6d5f49SVikram Sharma .configure_stream = csid_configure_stream, 3440d6d5f49SVikram Sharma .configure_testgen_pattern = csid_configure_testgen_pattern, 3450d6d5f49SVikram Sharma .hw_version = csid_hw_version, 3460d6d5f49SVikram Sharma .isr = csid_isr, 3470d6d5f49SVikram Sharma .reset = csid_reset, 3480d6d5f49SVikram Sharma .src_pad_code = csid_src_pad_code, 3490d6d5f49SVikram Sharma .subdev_init = csid_subdev_init, 3500d6d5f49SVikram Sharma .reg_update = csid_subdev_reg_update, 3510d6d5f49SVikram Sharma }; 352