]> rtime.felk.cvut.cz Git - hercules2020/nv-tegra/linux-4.4.git/blob - drivers/media/platform/tegra/camera/csi/csi2_fops.c
361b879729fcc4388b58ae02b0c4ecf5503bc344
[hercules2020/nv-tegra/linux-4.4.git] / drivers / media / platform / tegra / camera / csi / csi2_fops.c
1 /*
2  * Tegra CSI2 device common APIs
3  *
4  * Copyright (c) 2016-2017, NVIDIA CORPORATION.  All rights reserved.
5  *
6  * Author: Bryan Wu <pengw@nvidia.com>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 as
10  * published by the Free Software Foundation.
11  */
12
13 #include <linux/device.h>
14 #include <linux/clk/tegra.h>
15 #include "camera/csi/csi.h"
16 #include "camera/vi/mc_common.h"
17 #include "mipical/mipi_cal.h"
18 #include "nvhost_acm.h"
19 #include <linux/clk/tegra.h>
20
21 static void csi_write(struct tegra_csi_channel *chan, unsigned int addr,
22                         u32 val, u8 port)
23 {
24         struct tegra_csi_device *csi = chan->csi;
25
26         writel(val, (csi->iomem[port] + addr));
27 }
28
29 static u32 csi_read(struct tegra_csi_channel *chan, unsigned int addr,
30                         u8 port)
31 {
32         struct tegra_csi_device *csi = chan->csi;
33
34         return readl((csi->iomem[port] + addr));
35 }
36
37 /* Pixel parser registers accessors */
38 static void pp_write(struct tegra_csi_port *port, u32 addr, u32 val)
39 {
40         writel(val, port->pixel_parser + addr);
41 }
42
43 static u32 pp_read(struct tegra_csi_port *port, u32 addr)
44 {
45         return readl(port->pixel_parser + addr);
46 }
47
48 /* CSI CIL registers accessors */
49 static void cil_write(struct tegra_csi_port *port, u32 addr, u32 val)
50 {
51         writel(val, port->cil + addr);
52 }
53
54 static u32 cil_read(struct tegra_csi_port *port, u32 addr)
55 {
56         return readl(port->cil + addr);
57 }
58
59 /* Test pattern generator registers accessor */
60 static void tpg_write(struct tegra_csi_port *port,
61                         unsigned int addr, u32 val)
62 {
63         writel(val, port->tpg + addr);
64 }
65
66 int tegra_csi_error(struct tegra_csi_channel *chan,
67                         enum tegra_csi_port_num port_num)
68 {
69         struct tegra_csi_port *port;
70         u32 val;
71         int err = 0;
72
73         port = &chan->ports[port_num];
74         /*
75          * only uncorrectable header error and multi-bit
76          * transmission errors are checked as they cannot be
77          * corrected automatically
78          */
79         val = pp_read(port, TEGRA_CSI_PIXEL_PARSER_STATUS);
80         err |= val & 0x4000;
81         pp_write(port, TEGRA_CSI_PIXEL_PARSER_STATUS, val);
82
83         val = cil_read(port, TEGRA_CSI_CIL_STATUS);
84         err |= val & 0x02;
85         cil_write(port, TEGRA_CSI_CIL_STATUS, val);
86
87         val = cil_read(port, TEGRA_CSI_CILX_STATUS);
88         err |= val & 0x00020020;
89         cil_write(port, TEGRA_CSI_CILX_STATUS, val);
90
91         return err;
92 }
93
94 void tegra_csi_status(struct tegra_csi_channel *chan,
95                         enum tegra_csi_port_num port_num)
96 {
97         int i;
98         u32 val;
99         struct tegra_csi_port *port;
100
101         for (i = 0; i < chan->numports; i++) {
102                 port = &chan->ports[i];
103                 val = pp_read(port, TEGRA_CSI_PIXEL_PARSER_STATUS);
104
105                 dev_dbg(chan->csi->dev,
106                         "TEGRA_CSI_PIXEL_PARSER_STATUS 0x%08x\n",
107                         val);
108
109                 val = cil_read(port, TEGRA_CSI_CIL_STATUS);
110                 dev_dbg(chan->csi->dev,
111                         "TEGRA_CSI_CIL_STATUS 0x%08x\n", val);
112
113                 val = cil_read(port, TEGRA_CSI_CILX_STATUS);
114                 dev_dbg(chan->csi->dev,
115                         "TEGRA_CSI_CILX_STATUS 0x%08x\n", val);
116         }
117 }
118 EXPORT_SYMBOL(tegra_csi_status);
119
120 void tegra_csi_error_recover(struct tegra_csi_channel *chan,
121                                 enum tegra_csi_port_num port_num)
122 {
123         struct tegra_csi_port *port;
124         struct tegra_csi_device *csi;
125         int i;
126
127         csi = chan->csi;
128
129         for (i = 0; i < chan->numports; i++) {
130                 port = &chan->ports[i];
131
132                 if (port->lanes == 4) {
133                         int port_val = ((port_num >> 1) << 1);
134                         struct tegra_csi_port *port_a =
135                                 &chan->ports[port_val];
136                         struct tegra_csi_port *port_b =
137                                 &chan->ports[port_val+1];
138
139                         tpg_write(port_a,
140                                 TEGRA_CSI_PATTERN_GENERATOR_CTRL, PG_ENABLE);
141                         tpg_write(port_b,
142                                 TEGRA_CSI_PATTERN_GENERATOR_CTRL, PG_ENABLE);
143                         cil_write(port_a,
144                                 TEGRA_CSI_CIL_SW_SENSOR_RESET, 0x1);
145                         cil_write(port_b,
146                                 TEGRA_CSI_CIL_SW_SENSOR_RESET, 0x1);
147                         csi_write(chan, TEGRA_CSI_CSI_SW_STATUS_RESET, 0x1,
148                                         port_num >> 1);
149                         /* sleep for clock cycles to drain the Rx FIFO */
150                         usleep_range(10, 20);
151                         cil_write(port_a,
152                                 TEGRA_CSI_CIL_SW_SENSOR_RESET, 0x0);
153                         cil_write(port_b,
154                                 TEGRA_CSI_CIL_SW_SENSOR_RESET, 0x0);
155                         csi_write(chan,
156                                 TEGRA_CSI_CSI_SW_STATUS_RESET,
157                                 0x0, port_num >> 1);
158                         tpg_write(port_a,
159                                 TEGRA_CSI_PATTERN_GENERATOR_CTRL, PG_DISABLE);
160                         tpg_write(port_b,
161                                 TEGRA_CSI_PATTERN_GENERATOR_CTRL, PG_DISABLE);
162                 } else {
163                         tpg_write(port,
164                                 TEGRA_CSI_PATTERN_GENERATOR_CTRL, PG_ENABLE);
165                         cil_write(port,
166                                 TEGRA_CSI_CIL_SW_SENSOR_RESET, 0x1);
167                         csi_write(chan,
168                                 TEGRA_CSI_CSI_SW_STATUS_RESET,
169                                 0x1, port_num >> 1);
170                         /* sleep for clock cycles to drain the Rx FIFO */
171                         usleep_range(10, 20);
172                         cil_write(port,
173                                 TEGRA_CSI_CIL_SW_SENSOR_RESET, 0x0);
174                         csi_write(chan,
175                                 TEGRA_CSI_CSI_SW_STATUS_RESET,
176                                 0x0, port_num >> 1);
177                         tpg_write(port,
178                                 TEGRA_CSI_PATTERN_GENERATOR_CTRL, PG_DISABLE);
179                 }
180         }
181 }
182
183
184 static int tpg_clk_enable(struct tegra_csi_device *csi)
185 {
186         int err = 0;
187
188         mutex_lock(&csi->source_update);
189         if (csi->tpg_active != 1) {
190                 mutex_unlock(&csi->source_update);
191                 return 0;
192         }
193         mutex_unlock(&csi->source_update);
194
195         clk_set_rate(csi->plld, TEGRA_CLOCK_TPG);
196         err = clk_prepare_enable(csi->plld);
197         if (err) {
198                 dev_err(csi->dev, "pll_d enable failed");
199                 return err;
200         }
201
202         err = clk_prepare_enable(csi->plld_dsi);
203         if (err) {
204                 dev_err(csi->dev, "pll_d enable failed");
205                 goto plld_dsi_err;
206         }
207         tegra210_csi_source_from_plld();
208         return err;
209 plld_dsi_err:
210         clk_disable_unprepare(csi->plld);
211         return err;
212 }
213
214 static int tpg_clk_disable(struct tegra_csi_device *csi)
215 {
216         int err = 0;
217
218         mutex_lock(&csi->source_update);
219         if (csi->tpg_active != 0) {
220                 mutex_unlock(&csi->source_update);
221                 return 0;
222         }
223         mutex_unlock(&csi->source_update);
224         tegra210_csi_source_from_brick();
225         clk_disable_unprepare(csi->plld_dsi);
226         clk_disable_unprepare(csi->plld);
227
228         return err;
229 }
230
231 static int csi2_tpg_start_streaming(struct tegra_csi_channel *chan,
232                               enum tegra_csi_port_num port_num)
233 {
234         struct tegra_csi_port *port = &chan->ports[port_num];
235
236         tpg_write(port, TEGRA_CSI_PATTERN_GENERATOR_CTRL,
237                        ((chan->pg_mode - 1) << PG_MODE_OFFSET) |
238                        PG_ENABLE);
239         tpg_write(port, TEGRA_CSI_PG_BLANK,
240                         port->v_blank << PG_VBLANK_OFFSET |
241                         port->h_blank);
242         tpg_write(port, TEGRA_CSI_PG_PHASE, 0x0);
243         tpg_write(port, TEGRA_CSI_PG_RED_FREQ,
244                        (0x10 << PG_RED_VERT_INIT_FREQ_OFFSET) |
245                        (0x10 << PG_RED_HOR_INIT_FREQ_OFFSET));
246         tpg_write(port, TEGRA_CSI_PG_RED_FREQ_RATE, 0x0);
247         tpg_write(port, TEGRA_CSI_PG_GREEN_FREQ,
248                        (0x10 << PG_GREEN_VERT_INIT_FREQ_OFFSET) |
249                        (0x10 << PG_GREEN_HOR_INIT_FREQ_OFFSET));
250         tpg_write(port, TEGRA_CSI_PG_GREEN_FREQ_RATE, 0x0);
251         tpg_write(port, TEGRA_CSI_PG_BLUE_FREQ,
252                        (0x10 << PG_BLUE_VERT_INIT_FREQ_OFFSET) |
253                        (0x10 << PG_BLUE_HOR_INIT_FREQ_OFFSET));
254         tpg_write(port, TEGRA_CSI_PG_BLUE_FREQ_RATE, 0x0);
255         return 0;
256 }
257
258 int csi2_start_streaming(struct tegra_csi_channel *chan,
259                                 enum tegra_csi_port_num port_num)
260 {
261         struct tegra_csi_port *port = &chan->ports[port_num];
262         int csi_port, csi_lanes;
263
264         csi_port = chan->ports[port_num].num;
265         csi_lanes = chan->ports[port_num].lanes;
266
267         csi_write(chan, TEGRA_CSI_CLKEN_OVERRIDE, 0, csi_port >> 1);
268
269         /* Clean up status */
270         pp_write(port, TEGRA_CSI_PIXEL_PARSER_STATUS, 0xFFFFFFFF);
271         cil_write(port, TEGRA_CSI_CIL_STATUS, 0xFFFFFFFF);
272         cil_write(port, TEGRA_CSI_CILX_STATUS, 0xFFFFFFFF);
273
274         cil_write(port, TEGRA_CSI_CIL_INTERRUPT_MASK, 0x0);
275
276         /* CIL PHY registers setup */
277         cil_write(port, TEGRA_CSI_CIL_PAD_CONFIG0, 0x0);
278         cil_write(port, TEGRA_CSI_CIL_PHY_CONTROL,
279                         BYPASS_LP_SEQ | 0xA);
280
281         /*
282          * The CSI unit provides for connection of up to six cameras in
283          * the system and is organized as three identical instances of
284          * two MIPI support blocks, each with a separate 4-lane
285          * interface that can be configured as a single camera with 4
286          * lanes or as a dual camera with 2 lanes available for each
287          * camera.
288          */
289         if (csi_lanes == 4) {
290                 unsigned int cilb_offset;
291
292                 cilb_offset = TEGRA_CSI_CIL_OFFSET + TEGRA_CSI_PORT_OFFSET;
293
294                 cil_write(port, TEGRA_CSI_CIL_PAD_CONFIG0,
295                                 BRICK_CLOCK_A_4X);
296                 csi_write(chan, cilb_offset + TEGRA_CSI_CIL_PAD_CONFIG0, 0x0,
297                                 csi_port >> 1);
298                 csi_write(chan, cilb_offset + TEGRA_CSI_CIL_INTERRUPT_MASK, 0x0,
299                                 csi_port >> 1);
300                 cil_write(port, TEGRA_CSI_CIL_PHY_CONTROL,
301                                 BYPASS_LP_SEQ | 0xA);
302                 csi_write(chan, cilb_offset + TEGRA_CSI_CIL_PHY_CONTROL,
303                                 BYPASS_LP_SEQ | 0xA, csi_port >> 1);
304                 csi_write(chan, TEGRA_CSI_PHY_CIL_COMMAND,
305                                 CSI_A_PHY_CIL_ENABLE | CSI_B_PHY_CIL_ENABLE,
306                                 csi_port >> 1);
307         } else {
308                 u32 val = csi_read(chan, TEGRA_CSI_PHY_CIL_COMMAND,
309                                         csi_port >> 1);
310
311                 csi_write(chan,
312                         TEGRA_CSI_CIL_OFFSET + TEGRA_CSI_CIL_PAD_CONFIG0, 0x0,
313                         csi_port >> 1);
314                 val |= ((csi_port & 0x1) == PORT_A) ? CSI_A_PHY_CIL_ENABLE :
315                         CSI_B_PHY_CIL_ENABLE;
316                 csi_write(chan, TEGRA_CSI_PHY_CIL_COMMAND, val,
317                                 csi_port >> 1);
318         }
319         /* CSI pixel parser registers setup */
320         pp_write(port, TEGRA_CSI_PIXEL_STREAM_PP_COMMAND,
321                         (0xF << CSI_PP_START_MARKER_FRAME_MAX_OFFSET) |
322                         CSI_PP_SINGLE_SHOT_ENABLE | CSI_PP_RST);
323         pp_write(port, TEGRA_CSI_PIXEL_PARSER_INTERRUPT_MASK, 0x0);
324         pp_write(port, TEGRA_CSI_PIXEL_STREAM_CONTROL0,
325                         CSI_PP_PACKET_HEADER_SENT |
326                         CSI_PP_DATA_IDENTIFIER_ENABLE |
327                         CSI_PP_WORD_COUNT_SELECT_HEADER |
328                         CSI_PP_CRC_CHECK_ENABLE |  CSI_PP_WC_CHECK |
329                         CSI_PP_OUTPUT_FORMAT_STORE | CSI_PPA_PAD_LINE_NOPAD |
330                         CSI_PP_HEADER_EC_DISABLE | CSI_PPA_PAD_FRAME_NOPAD |
331                         (csi_port & 1));
332         pp_write(port, TEGRA_CSI_PIXEL_STREAM_CONTROL1,
333                         (0x1 << CSI_PP_TOP_FIELD_FRAME_OFFSET) |
334                         (0x1 << CSI_PP_TOP_FIELD_FRAME_MASK_OFFSET));
335         pp_write(port, TEGRA_CSI_PIXEL_STREAM_GAP,
336                         0x14 << PP_FRAME_MIN_GAP_OFFSET);
337         pp_write(port, TEGRA_CSI_PIXEL_STREAM_EXPECTED_FRAME, 0x0);
338         pp_write(port, TEGRA_CSI_INPUT_STREAM_CONTROL,
339                         (0x3f << CSI_SKIP_PACKET_THRESHOLD_OFFSET) |
340                         (csi_lanes - 1));
341
342         if (chan->pg_mode) {
343                 tpg_clk_enable(chan->csi);
344                 csi2_tpg_start_streaming(chan, port_num);
345         }
346
347         pp_write(port, TEGRA_CSI_PIXEL_STREAM_PP_COMMAND,
348                         (0xF << CSI_PP_START_MARKER_FRAME_MAX_OFFSET) |
349                         CSI_PP_SINGLE_SHOT_ENABLE | CSI_PP_ENABLE);
350         return 0;
351 }
352
353 void csi2_stop_streaming(struct tegra_csi_channel *chan,
354                                 enum tegra_csi_port_num port_num)
355 {
356         struct tegra_csi_port *port = &chan->ports[port_num];
357
358
359         if (chan->pg_mode) {
360                 tpg_write(port, TEGRA_CSI_PATTERN_GENERATOR_CTRL, PG_DISABLE);
361                 tpg_clk_disable(chan->csi);
362         }
363         if (!port) {
364                 pr_err("%s:no port\n", __func__);
365                 return;
366         }
367         pp_write(port, TEGRA_CSI_PIXEL_STREAM_PP_COMMAND,
368                         (0xF << CSI_PP_START_MARKER_FRAME_MAX_OFFSET) |
369                         CSI_PP_DISABLE);
370 }
371
372 int csi2_hw_init(struct tegra_csi_device *csi)
373 {
374         int i, csi_port;
375         struct tegra_csi_channel *it;
376         struct tegra_csi_port *port;
377
378         csi->iomem[0] = (csi->iomem_base + TEGRA_CSI_PIXEL_PARSER_0_BASE);
379         csi->iomem[1] = (csi->iomem_base + TEGRA_CSI_PIXEL_PARSER_2_BASE);
380         csi->iomem[2] = (csi->iomem_base + TEGRA_CSI_PIXEL_PARSER_4_BASE);
381         list_for_each_entry(it, &csi->csi_chans, list) {
382                 for (i = 0; i < it->numports; i++) {
383                         port = &it->ports[i];
384                         csi_port = it->ports[i].num;
385                         port->pixel_parser = csi->iomem[csi_port >> 1] +
386                                 (csi_port % 2) * TEGRA_CSI_PORT_OFFSET;
387                         port->cil = port->pixel_parser + TEGRA_CSI_CIL_OFFSET;
388                         port->tpg = port->pixel_parser + TEGRA_CSI_TPG_OFFSET;
389                 }
390         }
391         csi->plld = devm_clk_get(csi->dev, "pll_d");
392         if (IS_ERR(csi->plld)) {
393                 dev_err(csi->dev, "Fail to get pll_d\n");
394                 return PTR_ERR(csi->plld);
395         }
396         csi->plld_dsi = devm_clk_get(csi->dev, "pll_d_dsi_out");
397         if (IS_ERR(csi->plld_dsi)) {
398                 dev_err(csi->dev, "Fail to get pll_d_dsi_out\n");
399                 return PTR_ERR(csi->plld_dsi);
400         }
401         return 0;
402 }
403
404 int csi2_mipi_cal(struct tegra_csi_channel *chan)
405 {
406         unsigned int lanes, num_ports, val, csi_port;
407         struct tegra_csi_port *port;
408         struct tegra_csi_device *csi = chan->csi;
409
410         lanes = 0;
411         num_ports = 0;
412
413         nvhost_module_enable_clk(csi->dev);
414         while (num_ports < chan->numports) {
415                 port = &chan->ports[num_ports];
416                 csi_port = port->num;
417                 dev_dbg(csi->dev, "Calibrate csi port %d\n", port->num);
418
419                 if (chan->numlanes == 2) {
420                         lanes |= CSIA << csi_port;
421                         val = csi_read(chan, TEGRA_CSI_PHY_CIL_COMMAND,
422                                         csi_port >> 1);
423                         csi_write(chan,
424                                 TEGRA_CSI_CIL_OFFSET +
425                                 TEGRA_CSI_CIL_PAD_CONFIG0, 0x0, csi_port >> 1);
426                         val |= ((csi_port & 0x1) == PORT_A) ?
427                                 CSI_A_PHY_CIL_ENABLE : CSI_B_PHY_CIL_ENABLE;
428                         csi_write(chan, TEGRA_CSI_PHY_CIL_COMMAND, val,
429                                 csi_port >> 1);
430                 } else {
431                         lanes |= (CSIA | CSIB) << port->num;
432                         csi_write(chan, TEGRA_CSI_PHY_CIL_COMMAND,
433                                 CSI_A_PHY_CIL_ENABLE | CSI_B_PHY_CIL_ENABLE,
434                                 csi_port >> 1);
435                 }
436                 num_ports++;
437         }
438         if (!lanes) {
439                 dev_err(csi->dev,
440                         "Selected no CSI lane, cannot do calibration");
441                 return -EINVAL;
442         }
443         nvhost_module_disable_clk(csi->dev);
444         return tegra_mipi_calibration(lanes);
445 }
446
447 int csi2_power_on(struct tegra_csi_device *csi)
448 {
449         return 0;
450 }
451 int csi2_power_off(struct tegra_csi_device *csi)
452 {
453         return 0;
454 }
455 const struct tegra_csi_fops csi2_fops = {
456         .csi_power_on = csi2_power_on,
457         .csi_power_off = csi2_power_off,
458         .csi_start_streaming = csi2_start_streaming,
459         .csi_stop_streaming = csi2_stop_streaming,
460         .mipical = csi2_mipi_cal,
461         .hw_init = csi2_hw_init,
462 };
463 EXPORT_SYMBOL(csi2_fops);