1 // SPDX-License-Identifier: GPL-2.0
5 * Qualcomm MSM Camera Subsystem - CSID (CSI Decoder) Module
7 * Copyright (C) 2020 Linaro Ltd.
10 #include <linux/completion.h>
11 #include <linux/interrupt.h>
13 #include <linux/kernel.h>
16 #include "camss-csid.h"
17 #include "camss-csid-gen1.h"
20 #define CAMSS_CSID_HW_VERSION 0x0
21 #define CAMSS_CSID_CORE_CTRL_0 0x004
22 #define CAMSS_CSID_CORE_CTRL_1 0x008
23 #define CAMSS_CSID_RST_CMD 0x00c
24 #define CAMSS_CSID_CID_LUT_VC_n(n) (0x010 + 0x4 * (n))
25 #define CAMSS_CSID_CID_n_CFG(n) (0x020 + 0x4 * (n))
26 #define CAMSS_CSID_CID_n_CFG_ISPIF_EN BIT(0)
27 #define CAMSS_CSID_CID_n_CFG_RDI_EN BIT(1)
28 #define CAMSS_CSID_CID_n_CFG_DECODE_FORMAT_SHIFT 4
29 #define CAMSS_CSID_CID_n_CFG_PLAIN_FORMAT_8 (PLAIN_FORMAT_PLAIN8 << 8)
30 #define CAMSS_CSID_CID_n_CFG_PLAIN_FORMAT_16 (PLAIN_FORMAT_PLAIN16 << 8)
31 #define CAMSS_CSID_CID_n_CFG_PLAIN_ALIGNMENT_LSB (0 << 9)
32 #define CAMSS_CSID_CID_n_CFG_PLAIN_ALIGNMENT_MSB (1 << 9)
33 #define CAMSS_CSID_CID_n_CFG_RDI_MODE_RAW_DUMP (0 << 10)
34 #define CAMSS_CSID_CID_n_CFG_RDI_MODE_PLAIN_PACKING (1 << 10)
35 #define CAMSS_CSID_IRQ_CLEAR_CMD 0x060
36 #define CAMSS_CSID_IRQ_MASK 0x064
37 #define CAMSS_CSID_IRQ_STATUS 0x068
38 #define CAMSS_CSID_TG_CTRL 0x0a0
39 #define CAMSS_CSID_TG_CTRL_DISABLE 0xa06436
40 #define CAMSS_CSID_TG_CTRL_ENABLE 0xa06437
41 #define CAMSS_CSID_TG_VC_CFG 0x0a4
42 #define CAMSS_CSID_TG_VC_CFG_H_BLANKING 0x3ff
43 #define CAMSS_CSID_TG_VC_CFG_V_BLANKING 0x7f
44 #define CAMSS_CSID_TG_DT_n_CGG_0(n) (0x0ac + 0xc * (n))
45 #define CAMSS_CSID_TG_DT_n_CGG_1(n) (0x0b0 + 0xc * (n))
46 #define CAMSS_CSID_TG_DT_n_CGG_2(n) (0x0b4 + 0xc * (n))
48 static void csid_configure_stream(struct csid_device
*csid
, u8 enable
)
50 struct csid_testgen_config
*tg
= &csid
->testgen
;
54 struct v4l2_mbus_framefmt
*input_format
;
55 const struct csid_format_info
*format
;
56 u8 vc
= 0; /* Virtual Channel 0 */
57 u8 cid
= vc
* 4; /* id of Virtual Channel and Data Type set */
61 /* Config Test Generator */
62 u32 num_lines
, num_bytes_per_line
;
64 input_format
= &csid
->fmt
[MSM_CSID_PAD_SRC
];
65 format
= csid_get_fmt_entry(csid
->res
->formats
->formats
,
66 csid
->res
->formats
->nformats
,
68 num_bytes_per_line
= input_format
->width
* format
->bpp
* format
->spp
/ 8;
69 num_lines
= input_format
->height
;
71 /* 31:24 V blank, 23:13 H blank, 3:2 num of active DT */
73 val
= ((CAMSS_CSID_TG_VC_CFG_V_BLANKING
& 0xff) << 24) |
74 ((CAMSS_CSID_TG_VC_CFG_H_BLANKING
& 0x7ff) << 13);
75 writel_relaxed(val
, csid
->base
+ CAMSS_CSID_TG_VC_CFG
);
77 /* 28:16 bytes per lines, 12:0 num of lines */
78 val
= ((num_bytes_per_line
& 0x1fff) << 16) |
80 writel_relaxed(val
, csid
->base
+ CAMSS_CSID_TG_DT_n_CGG_0(0));
83 val
= format
->data_type
;
84 writel_relaxed(val
, csid
->base
+ CAMSS_CSID_TG_DT_n_CGG_1(0));
86 /* 2:0 output test pattern */
88 writel_relaxed(val
, csid
->base
+ CAMSS_CSID_TG_DT_n_CGG_2(0));
90 struct csid_phy_config
*phy
= &csid
->phy
;
92 input_format
= &csid
->fmt
[MSM_CSID_PAD_SINK
];
93 format
= csid_get_fmt_entry(csid
->res
->formats
->formats
,
94 csid
->res
->formats
->nformats
,
97 val
= phy
->lane_cnt
- 1;
98 val
|= phy
->lane_assign
<< 4;
100 writel_relaxed(val
, csid
->base
+ CAMSS_CSID_CORE_CTRL_0
);
102 val
= phy
->csiphy_id
<< 17;
105 writel_relaxed(val
, csid
->base
+ CAMSS_CSID_CORE_CTRL_1
);
110 dt_shift
= (cid
% 4) * 8;
111 val
= readl_relaxed(csid
->base
+ CAMSS_CSID_CID_LUT_VC_n(vc
));
112 val
&= ~(0xff << dt_shift
);
113 val
|= format
->data_type
<< dt_shift
;
114 writel_relaxed(val
, csid
->base
+ CAMSS_CSID_CID_LUT_VC_n(vc
));
116 val
= CAMSS_CSID_CID_n_CFG_ISPIF_EN
;
117 val
|= CAMSS_CSID_CID_n_CFG_RDI_EN
;
118 val
|= format
->decode_format
<< CAMSS_CSID_CID_n_CFG_DECODE_FORMAT_SHIFT
;
119 val
|= CAMSS_CSID_CID_n_CFG_RDI_MODE_RAW_DUMP
;
120 writel_relaxed(val
, csid
->base
+ CAMSS_CSID_CID_n_CFG(cid
));
123 val
= CAMSS_CSID_TG_CTRL_ENABLE
;
124 writel_relaxed(val
, csid
->base
+ CAMSS_CSID_TG_CTRL
);
128 val
= CAMSS_CSID_TG_CTRL_DISABLE
;
129 writel_relaxed(val
, csid
->base
+ CAMSS_CSID_TG_CTRL
);
134 static int csid_configure_testgen_pattern(struct csid_device
*csid
, s32 val
)
136 if (val
> 0 && val
<= csid
->testgen
.nmodes
)
137 csid
->testgen
.mode
= val
;
142 static u32
csid_hw_version(struct csid_device
*csid
)
144 u32 hw_version
= readl_relaxed(csid
->base
+ CAMSS_CSID_HW_VERSION
);
146 dev_dbg(csid
->camss
->dev
, "CSID HW Version = 0x%08x\n", hw_version
);
151 static irqreturn_t
csid_isr(int irq
, void *dev
)
153 struct csid_device
*csid
= dev
;
156 value
= readl_relaxed(csid
->base
+ CAMSS_CSID_IRQ_STATUS
);
157 writel_relaxed(value
, csid
->base
+ CAMSS_CSID_IRQ_CLEAR_CMD
);
159 if ((value
>> 11) & 0x1)
160 complete(&csid
->reset_complete
);
165 static int csid_reset(struct csid_device
*csid
)
169 reinit_completion(&csid
->reset_complete
);
171 writel_relaxed(0x7fff, csid
->base
+ CAMSS_CSID_RST_CMD
);
173 time
= wait_for_completion_timeout(&csid
->reset_complete
,
174 msecs_to_jiffies(CSID_RESET_TIMEOUT_MS
));
176 dev_err(csid
->camss
->dev
, "CSID reset timeout\n");
183 static u32
csid_src_pad_code(struct csid_device
*csid
, u32 sink_code
,
184 unsigned int match_format_idx
, u32 match_code
)
186 if (match_format_idx
> 0)
192 static void csid_subdev_init(struct csid_device
*csid
)
194 csid
->testgen
.modes
= csid_testgen_modes
;
195 csid
->testgen
.nmodes
= CSID_PAYLOAD_MODE_NUM_SUPPORTED_GEN1
;
198 const struct csid_hw_ops csid_ops_4_1
= {
199 .configure_stream
= csid_configure_stream
,
200 .configure_testgen_pattern
= csid_configure_testgen_pattern
,
201 .hw_version
= csid_hw_version
,
204 .src_pad_code
= csid_src_pad_code
,
205 .subdev_init
= csid_subdev_init
,