History

media: rppx1: exm: Add support for exposure measurement

Extend the RPPX1 driver to allow setting the exposure measurement configuration and consuming the resulting statistics. It uses the RPPX1 framework for parameters and its writer abstraction to allow the user to control how, and when, configuration is applied to the RPPX1.

Niklas Söderlund committed 3 months ago

Commit b020bec1 parent 9ebf5005 files · +216 −2Browse files

Unified · Split

5 files
  1. drivers/media/platform/dreamchip/rppx1/rpp_module.h +2 −0
  2. drivers/media/platform/dreamchip/rppx1/rpp_params.c +5 −0
  3. drivers/media/platform/dreamchip/rppx1/rpp_stats.c +10 −0
  4. drivers/media/platform/dreamchip/rppx1/rppx1_exm.c +76 −0
  5. include/uapi/linux/media/dreamchip/rppx1-config.h +123 −2
drivers/media/platform/dreamchip/rppx1/rpp_module.h+2−0
@@ -48,11 +48,13 @@ void rpp_module_clrset(struct rpp_module *mod, u32 offset, u32 mask, u32 value); · 47 unmodified lines
48union rppx1_params_block {48union rppx1_params_block {
49 struct v4l2_isp_block_header header;49 struct v4l2_isp_block_header header;
50 struct rppx1_awbg_params awbg;50 struct rppx1_awbg_params awbg;
51 struct rppx1_exm_params exm;
51 struct rppx1_wbmeas_params wbmeas;52 struct rppx1_wbmeas_params wbmeas;
52};53};
53 54
54union rppx1_stats_block {55union rppx1_stats_block {
55 struct v4l2_isp_block_header header;56 struct v4l2_isp_block_header header;
57 struct rppx1_exm_stats exm;
56 struct rppx1_wbmeas_stats wbmeas;58 struct rppx1_wbmeas_stats wbmeas;
57};59};
58 60
drivers/media/platform/dreamchip/rppx1/rpp_params.c+5−0
@@ -19,6 +19,8 @@ static const struct v4l2_isp_params_block_type_info · 18 unmodified lines
19rppx1_ext_params_blocks_info[] = {19rppx1_ext_params_blocks_info[] = {
20 RPPX1_PARAMS_BLOCK_INFO(AWBG_PRE1, awbg),20 RPPX1_PARAMS_BLOCK_INFO(AWBG_PRE1, awbg),
21 RPPX1_PARAMS_BLOCK_INFO(AWBG_PRE2, awbg),21 RPPX1_PARAMS_BLOCK_INFO(AWBG_PRE2, awbg),
22 RPPX1_PARAMS_BLOCK_INFO(EXM_PRE1, exm),
23 RPPX1_PARAMS_BLOCK_INFO(EXM_PRE2, exm),
22 RPPX1_PARAMS_BLOCK_INFO(WBMEAS_POST, wbmeas),24 RPPX1_PARAMS_BLOCK_INFO(WBMEAS_POST, wbmeas),
23};25};
24 26
@@ -56,6 +58,9 @@ int rppx1_params(struct rppx1 *rpp, struct vb2_buffer *vb, size_t max_size, · 31 unmodified lines
56 case RPPX1_PARAMS_BLOCK_TYPE_AWBG_PRE1:58 case RPPX1_PARAMS_BLOCK_TYPE_AWBG_PRE1:
57 module = &rpp->pre1.awbg;59 module = &rpp->pre1.awbg;
58 break;60 break;
61 case RPPX1_PARAMS_BLOCK_TYPE_EXM_PRE1:
62 module = &rpp->pre1.exm;
63 break;
59 case RPPX1_PARAMS_BLOCK_TYPE_WBMEAS_POST:64 case RPPX1_PARAMS_BLOCK_TYPE_WBMEAS_POST:
60 module = &rpp->post.wbmeas;65 module = &rpp->post.wbmeas;
61 break;66 break;
drivers/media/platform/dreamchip/rppx1/rpp_stats.c+10−0
@@ -17,6 +17,7 @@ · 16 unmodified lines
17 17
18static const struct v4l2_isp_stats_block_type_info18static const struct v4l2_isp_stats_block_type_info
19rppx1_stats_blocks_info[] = {19rppx1_stats_blocks_info[] = {
20 RPPX1_STATS_BLOCK_INFO(EXM_PRE1, exm),
20 RPPX1_STATS_BLOCK_INFO(WBMEAS_POST, wbmeas),21 RPPX1_STATS_BLOCK_INFO(WBMEAS_POST, wbmeas),
21};22};
22 23
@@ -34,6 +35,15 @@ void rppx1_stats_fill_isr(struct rppx1 *rpp, u32 isc, void *buf) · 11 unmodified lines
34 35
35 v4l2_isp_stats_init_buffer(stats, V4L2_ISP_VERSION_V1);36 v4l2_isp_stats_init_buffer(stats, V4L2_ISP_VERSION_V1);
36 37
38 if (isc & RPPX1_IRQ_ID_PRE1_EXM) {
39 block = rppx1_init_stats_block(rpp, stats,
40 RPPX1_STATS_BLOCK_TYPE_EXM_PRE1);
41 if (IS_ERR(block))
42 return;
43
44 rpp_module_call(&rpp->pre1.exm, fill_stats, block);
45 }
46
37 if (isc & RPPX1_IRQ_ID_POST_AWB_MEAS) {47 if (isc & RPPX1_IRQ_ID_POST_AWB_MEAS) {
38 block = rppx1_init_stats_block(rpp, stats,48 block = rppx1_init_stats_block(rpp, stats,
39 RPPX1_STATS_BLOCK_TYPE_WBMEAS_POST);49 RPPX1_STATS_BLOCK_TYPE_WBMEAS_POST);
drivers/media/platform/dreamchip/rppx1/rppx1_exm.c+76−0
@@ -11,10 +11,14 @@ · 10 unmodified lines
11#define EXM_START_REG 0x000411#define EXM_START_REG 0x0004
12 12
13#define EXM_CTRL_REG 0x000813#define EXM_CTRL_REG 0x0008
14#define EXM_CTRL_EXM_AUTOSTOP BIT(1) /* HW doc says not supported. */
14#define EXM_CTRL_EXM_UPDATE_ENABLE BIT(0)15#define EXM_CTRL_EXM_UPDATE_ENABLE BIT(0)
15 16
16#define EXM_MODE_REG 0x000c17#define EXM_MODE_REG 0x000c
18
17#define EXM_CHANNEL_SEL_REG 0x001019#define EXM_CHANNEL_SEL_REG 0x0010
20#define EXM_CHANNEL_SEL_CHANNEL_SELECT_MASK GENMASK(2, 0)
21
18#define EXM_LAST_MEAS_LINE_REG 0x001422#define EXM_LAST_MEAS_LINE_REG 0x0014
19#define EXM_COEFF_R_REG 0x001823#define EXM_COEFF_R_REG 0x0018
20#define EXM_COEFF_G_GR_REG 0x001c24#define EXM_COEFF_G_GR_REG 0x001c
@@ -46,6 +50,78 @@ static int rppx1_exm_probe(struct rpp_module *mod) · 25 unmodified lines
46 return 0;50 return 0;
47}51}
48 52
53static int
54rppx1_exm_fill_params(struct rpp_module *mod,
55 const union rppx1_params_block *block,
56 rppx1_reg_write write, void *priv)
57{
58 const struct rppx1_exm_params *cfg = &block->exm;
59 u32 h_offs, v_offs, h_size, v_size;
60
61 /* If the modules is disabled, simply bypass it. */
62 if (cfg->header.flags & V4L2_ISP_PARAMS_FL_BLOCK_DISABLE) {
63 write(priv, mod->base + EXM_MODE_REG, 0);
64 return 0;
65 }
66
67 switch (cfg->mode) {
68 case RPPX1_EXP_MEASURING_MODE_RGB:
69 case RPPX1_EXP_MEASURING_MODE_BAYER:
70 write(priv, mod->base + EXM_MODE_REG, cfg->mode);
71 break;
72 default:
73 write(priv, mod->base + EXM_MODE_REG, 0);
74 return 0;
75 }
76
77 write(priv, mod->base + EXM_COEFF_R_REG, cfg->coeff_r);
78 write(priv, mod->base + EXM_COEFF_G_GR_REG, cfg->coeff_g_gr);
79 write(priv, mod->base + EXM_COEFF_GB_REG, cfg->coeff_gb);
80 write(priv, mod->base + EXM_COEFF_B_REG, cfg->coeff_b);
81
82 /* Select sample point */
83 write(priv, mod->base + EXM_CHANNEL_SEL_REG,
84 cfg->channel_sel & EXM_CHANNEL_SEL_CHANNEL_SELECT_MASK);
85
86 /*
87 * Adjust and set measurement window,
88 * - Offsets must be even.
89 * - Width and height must be even and divisible in 5 windows.
90 */
91 h_offs = cfg->wnd.h_offs & 0x1ffe;
92 v_offs = cfg->wnd.v_offs & 0x1ffe;
93 h_size = (cfg->wnd.h_size - 1) - ((cfg->wnd.h_size - 1) % 10);
94 v_size = (cfg->wnd.v_size - 1) - ((cfg->wnd.v_size - 1) % 10);
95
96 write(priv, mod->base + EXM_H_OFFS_REG, h_offs);
97 write(priv, mod->base + EXM_V_OFFS_REG, v_offs);
98 write(priv, mod->base + EXM_H_SIZE_REG, h_size / 5);
99 write(priv, mod->base + EXM_V_SIZE_REG, v_size / 5);
100
101 /*
102 * Set last measurement line for ready interrupt. Ignore the value
103 * from the parameters as it is only useful for fast-channel switching.
104 */
105 write(priv, mod->base + EXM_LAST_MEAS_LINE_REG, v_offs + v_size + 1);
106
107 write(priv, mod->base + EXM_START_REG, 1);
108
109 return 0;
110}
111
112static int rppx1_exm_fill_stats(struct rpp_module *mod,
113 union rppx1_stats_block *block)
114{
115 struct rppx1_exm_stats *stats = &block->exm;
116
117 for (unsigned int i = 0; i < RPPX1_EXM_NUM_WIN; i++)
118 stats->exp_mean[i] = rpp_module_read(mod, EXM_MEAN_REG(i));
119
120 return 0;
121}
122
49const struct rpp_module_ops rppx1_exm_ops = {123const struct rpp_module_ops rppx1_exm_ops = {
50 .probe = rppx1_exm_probe,124 .probe = rppx1_exm_probe,
125 .fill_params = rppx1_exm_fill_params,
126 .fill_stats = rppx1_exm_fill_stats,
51};127};
include/uapi/linux/media/dreamchip/rppx1-config.h+123−2
@@ -32,6 +32,36 @@ struct rppx1_window { · 31 unmodified lines
32 __u16 v_size;32 __u16 v_size;
33};33};
34 34
35/**
36 * enum rppx1_meas_chan - Measurement point for the Histogram and EXM Modules
37 *
38 * Measurement points for the RPP-X1 Histogram measurement module and Exposure
39 * measurement module.
40 *
41 * All tap points are available for the PRE1/PRE2 pipes. Only
42 * RPPX1_MEAS_CHAN_SEL4 and RPPX1_MEAS_CHAN_SEL7 are available for the
43 * MAIN_POST pipe.
44 *
45 * @RPPX1_MEAS_CHAN_SEL0: after input acquisition
46 * @RPPX1_MEAS_CHAN_SEL1: after black level subtraction
47 * @RPPX1_MEAS_CHAN_SEL2: after sensor gamma linearization
48 * @RPPX1_MEAS_CHAN_SEL3: after lens shading correction
49 * @RPPX1_MEAS_CHAN_SEL4: after auto white balance gains
50 * @RPPX1_MEAS_CHAN_SEL5: after defect pixel correction
51 * @RPPX1_MEAS_CHAN_SEL6: after denoise pre-filter
52 * @RPPX1_MEAS_CHAN_SEL7: after demosaicing
53 */
54enum rppx1_meas_chan {
55 RPPX1_MEAS_CHAN_SEL0,
56 RPPX1_MEAS_CHAN_SEL1,
57 RPPX1_MEAS_CHAN_SEL2,
58 RPPX1_MEAS_CHAN_SEL3,
59 RPPX1_MEAS_CHAN_SEL4,
60 RPPX1_MEAS_CHAN_SEL5,
61 RPPX1_MEAS_CHAN_SEL6,
62 RPPX1_MEAS_CHAN_SEL7,
63};
64
35/* ---------------------------------------------------------------------------65/* ---------------------------------------------------------------------------
36 * Parameter Structures66 * Parameter Structures
37 *67 *
@@ -50,12 +80,16 @@ struct rppx1_window { · 12 unmodified lines
50 * @RPPX1_PARAMS_BLOCK_TYPE_AWBG_PRE1: PRE1 pipe White Balance Gains80 * @RPPX1_PARAMS_BLOCK_TYPE_AWBG_PRE1: PRE1 pipe White Balance Gains
51 * @RPPX1_PARAMS_BLOCK_TYPE_AWBG_PRE2: PRE2 White Balance Gains81 * @RPPX1_PARAMS_BLOCK_TYPE_AWBG_PRE2: PRE2 White Balance Gains
52 * @RPPX1_PARAMS_BLOCK_TYPE_AWBG_POST: MAIN_POST White Balance Gains82 * @RPPX1_PARAMS_BLOCK_TYPE_AWBG_POST: MAIN_POST White Balance Gains
83 * @RPPX1_PARAMS_BLOCK_TYPE_EXM_PRE1: PRE1 pipe Exposure Measurement
84 * @RPPX1_PARAMS_BLOCK_TYPE_EXM_PRE2: PRE2 pipe Exposure Measurement
53 */85 */
54enum rppx1_params_block_type {86enum rppx1_params_block_type {
55 RPPX1_PARAMS_BLOCK_TYPE_WBMEAS_POST,87 RPPX1_PARAMS_BLOCK_TYPE_WBMEAS_POST,
56 RPPX1_PARAMS_BLOCK_TYPE_AWBG_PRE1,88 RPPX1_PARAMS_BLOCK_TYPE_AWBG_PRE1,
57 RPPX1_PARAMS_BLOCK_TYPE_AWBG_PRE2,89 RPPX1_PARAMS_BLOCK_TYPE_AWBG_PRE2,
58 RPPX1_PARAMS_BLOCK_TYPE_AWBG_POST,90 RPPX1_PARAMS_BLOCK_TYPE_AWBG_POST,
91 RPPX1_PARAMS_BLOCK_TYPE_EXM_PRE1,
92 RPPX1_PARAMS_BLOCK_TYPE_EXM_PRE2,
59};93};
60 94
61/**95/**
@@ -149,6 +183,66 @@ struct rppx1_awbg_params { · 87 unmodified lines
149 __u32 gain_green_b;183 __u32 gain_green_b;
150};184};
151 185
186/**
187 * enum rppx1_exm_mode - Exposure measurement mode
188 *
189 * Exaposure measurement mode selection (RGB/Bayer).
190 *
191 * @RPPX1_EXP_MEASURING_MODE_DISABLED: no measurement
192 * @RPPX1_EXP_MEASURING_MODE_RGB: Y/R/G/B measurement
193 * @RPPX1_EXP_MEASURING_MODE_BAYER: Bayer RGB measurement
194 */
195enum rppx1_exm_mode {
196 RPPX1_EXP_MEASURING_MODE_DISABLED,
197 RPPX1_EXP_MEASURING_MODE_RGB,
198 RPPX1_EXP_MEASURING_MODE_BAYER,
199};
200
201/**
202 * struct rppx1_exm_params - Exposure measurement configuration
203 *
204 * The RPP-X1 Exposure measurement unit is available on the PRE1 and PRE2
205 * pre-fusion pipes. Userspace selects which pipe to operate by setting
206 * the @header.type field to RPPX1_PARAMS_BLOCK_TYPE_EXM_PRE1 or
207 * RPPX1_PARAMS_BLOCK_TYPE_EXM_PRE2.
208 *
209 * Exposure measurement is performed in the RGB or Bayer domain, according to
210 * the setting of the @mode field. The exposure measurement tap point is
211 * selected according to the value of @channel_sel.
212 *
213 * The exposure measurement is performed on an input window specified in @wnd.
214 * To each color component a programmable weight coefficient is associated.
215 * Coefficients are represented as unsigned 8 bits integer values in Q1.7 format
216 * ranging from 0 to 1.992.
217 *
218 * The @last_line fields controls when the exposure measurement completes. It
219 * is usually programmed to the value of (@wnd.v_offs + @wnd.v_size + 1).
220 *
221 * @header: block header (type = RPPX1_PARAMS_BLOCK_TYPE_EXM_PRE1 or
222 * type = RPPX1_PARAMS_BLOCK_TYPE_EXM_PRE2)
223 * @wnd: measurement window coordinates
224 * @mode: exposure measure mode (from enum rppx1_exm_mode)
225 * @last_line: line number for which the exposure measurement completes
226 * @channel_sel: exposure measurement point (see enum rppx1_meas_chan)
227 * @coeff_r: coefficient for the red Bayer sample or red color channel, Q1.7
228 * @coeff_g_gr: coefficient for the green/red Bayer sample or green color channel, Q1.7
229 * @coeff_b: coefficient for the blue Bayer sample or blue color channel, Q1.7
230 * @coeff_gb: coefficient for the green/blue Bayer sample, unused in RGB mode, Q1.7
231 * @reserved: padding
232 */
233struct rppx1_exm_params {
234 struct v4l2_isp_params_block_header header;
235 struct rppx1_window wnd;
236 __u32 mode;
237 __u32 last_line;
238 __u8 channel_sel;
239 __u8 coeff_r;
240 __u8 coeff_g_gr;
241 __u8 coeff_b;
242 __u8 coeff_gb;
243 __u8 reserved[3];
244};
245
152/**246/**
153 * RPPX1_PARAMS_MAX_SIZE - Maximum size of all RPP-X1 parameter blocks247 * RPPX1_PARAMS_MAX_SIZE - Maximum size of all RPP-X1 parameter blocks
154 *248 *
@@ -159,7 +253,9 @@ struct rppx1_awbg_params { · 4 unmodified lines
159 (sizeof(struct rppx1_wbmeas_params) + \253 (sizeof(struct rppx1_wbmeas_params) + \
160 sizeof(struct rppx1_awbg_params) + \254 sizeof(struct rppx1_awbg_params) + \
161 sizeof(struct rppx1_awbg_params) + \255 sizeof(struct rppx1_awbg_params) + \
162 sizeof(struct rppx1_awbg_params))256 sizeof(struct rppx1_awbg_params) + \
257 sizeof(struct rppx1_exm_params) + \
258 sizeof(struct rppx1_exm_params))
163 259
164/* ---------------------------------------------------------------------------260/* ---------------------------------------------------------------------------
165 * Statistics Structures261 * Statistics Structures
@@ -176,9 +272,13 @@ struct rppx1_awbg_params { · 10 unmodified lines
176 * NOTE: Only append to the enumeration as the numbers are uAPI.272 * NOTE: Only append to the enumeration as the numbers are uAPI.
177 *273 *
178 * @RPPX1_STATS_BLOCK_TYPE_WBMEAS_POST: post-fusion white-balance measurement274 * @RPPX1_STATS_BLOCK_TYPE_WBMEAS_POST: post-fusion white-balance measurement
275 * @RPPX1_STATS_BLOCK_TYPE_EXM_PRE1: pre-fusion pipe1 exposure measurement
276 * @RPPX1_STATS_BLOCK_TYPE_EXM_PRE2: pre-fusion pipe2 exposure measurement
179 */277 */
180enum rppx1_stats_block_type {278enum rppx1_stats_block_type {
181 RPPX1_STATS_BLOCK_TYPE_WBMEAS_POST,279 RPPX1_STATS_BLOCK_TYPE_WBMEAS_POST,
280 RPPX1_STATS_BLOCK_TYPE_EXM_PRE1,
281 RPPX1_STATS_BLOCK_TYPE_EXM_PRE2,
182};282};
183 283
184/**284/**
@@ -198,6 +298,25 @@ struct rppx1_wbmeas_stats { · 13 unmodified lines
198 __u32 mean_cr_or_r;298 __u32 mean_cr_or_r;
199};299};
200 300
301/* Exposure Measurement */
302#define RPPX1_EXM_NUM_WIN 25
303
304/**
305 * struct rppx1_exm_stats - Exposure measurement
306 *
307 * RPP-X1 exposure measurement calculates the mean value on 25 programmable
308 * windows on the input picture.
309 *
310 * @header: block header (type = RPPX1_STATS_BLOCK_TYPE_EXM_PRE1)
311 * @exp_mean: mean luminance values per block, up to 20-bit
312 * @reserved: padding
313 */
314struct rppx1_exm_stats {
315 struct v4l2_isp_block_header header;
316 __u32 exp_mean[RPPX1_EXM_NUM_WIN];
317 __u32 reserved;
318};
319
201/**320/**
202 * RPPX1_STATS_MAX_SIZE - Maximum size of all RPP-X1 statistics321 * RPPX1_STATS_MAX_SIZE - Maximum size of all RPP-X1 statistics
203 *322 *
@@ -205,6 +324,8 @@ struct rppx1_wbmeas_stats { · 1 unmodified line
205 * multiple pipes.324 * multiple pipes.
206 */325 */
207#define RPPX1_STATS_MAX_SIZE \326#define RPPX1_STATS_MAX_SIZE \
208 (sizeof(struct rppx1_wbmeas_stats))327 (sizeof(struct rppx1_wbmeas_stats) + \
328 sizeof(struct rppx1_exm_stats) + \
329 sizeof(struct rppx1_exm_stats))
209 330
210#endif /* __UAPI_RPP_X1_CONFIG_H */331#endif /* __UAPI_RPP_X1_CONFIG_H */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t