hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/phy/rockchip/phy-rockchip-csi2-dphy.c
....@@ -21,7 +21,20 @@
2121 #include <media/v4l2-fwnode.h>
2222 #include <media/v4l2-subdev.h>
2323 #include <media/v4l2-device.h>
24
+#include <linux/phy/phy.h>
2425 #include "phy-rockchip-csi2-dphy-common.h"
26
+#include "phy-rockchip-samsung-dcphy.h"
27
+
28
+static struct rkmodule_csi_dphy_param rk3588_dcphy_param = {
29
+ .vendor = PHY_VENDOR_SAMSUNG,
30
+ .lp_vol_ref = 3,
31
+ .lp_hys_sw = {3, 0, 0, 0},
32
+ .lp_escclk_pol_sel = {1, 0, 0, 0},
33
+ .skew_data_cal_clk = {0, 3, 3, 3},
34
+ .clk_hs_term_sel = 2,
35
+ .data_hs_term_sel = {2, 2, 2, 2},
36
+ .reserved = {0},
37
+};
2538
2639 struct sensor_async_subdev {
2740 struct v4l2_async_subdev asd;
....@@ -29,7 +42,6 @@
2942 int lanes;
3043 };
3144
32
-static DEFINE_MUTEX(csi2dphy_dev_mutex);
3345 static LIST_HEAD(csi2dphy_device_list);
3446
3547 static inline struct csi2_dphy *to_csi2_dphy(struct v4l2_subdev *subdev)
....@@ -41,7 +53,10 @@
4153 {
4254 struct media_pad *local, *remote;
4355 struct media_entity *sensor_me;
56
+ struct csi2_dphy *dphy = to_csi2_dphy(sd);
4457
58
+ if (dphy->num_sensors == 0)
59
+ return NULL;
4560 local = &sd->entity.pads[CSI2_DPHY_RX_PAD_SINK];
4661 remote = media_entity_remote_pad(local);
4762 if (!remote) {
....@@ -71,7 +86,10 @@
7186 struct v4l2_subdev *sensor_sd = get_remote_sensor(sd);
7287 struct v4l2_ctrl *link_freq;
7388 struct v4l2_querymenu qm = { .id = V4L2_CID_LINK_FREQ, };
74
- int ret;
89
+ int ret = 0;
90
+
91
+ if (!sensor_sd)
92
+ return -ENODEV;
7593
7694 link_freq = v4l2_ctrl_find(sensor_sd->ctrl_handler, V4L2_CID_LINK_FREQ);
7795 if (!link_freq) {
....@@ -97,15 +115,260 @@
97115 return 0;
98116 }
99117
118
+static int rockchip_csi2_dphy_attach_hw(struct csi2_dphy *dphy, int csi_idx, int index)
119
+{
120
+ struct csi2_dphy_hw *dphy_hw;
121
+ struct samsung_mipi_dcphy *dcphy_hw;
122
+ struct v4l2_subdev *sensor_sd = get_remote_sensor(&dphy->sd);
123
+ struct csi2_sensor *sensor = NULL;
124
+ int lanes = 2;
125
+
126
+ if (sensor_sd) {
127
+ sensor = sd_to_sensor(dphy, sensor_sd);
128
+ lanes = sensor->lanes;
129
+ }
130
+
131
+ if (dphy->drv_data->chip_id == CHIP_ID_RK3568 ||
132
+ dphy->drv_data->chip_id == CHIP_ID_RV1106) {
133
+ dphy_hw = dphy->dphy_hw_group[0];
134
+ mutex_lock(&dphy_hw->mutex);
135
+ dphy_hw->dphy_dev[dphy_hw->dphy_dev_num] = dphy;
136
+ dphy_hw->dphy_dev_num++;
137
+ switch (dphy->phy_index) {
138
+ case 0:
139
+ dphy->lane_mode = PHY_FULL_MODE;
140
+ dphy_hw->lane_mode = LANE_MODE_FULL;
141
+ break;
142
+ case 1:
143
+ dphy->lane_mode = PHY_SPLIT_01;
144
+ dphy_hw->lane_mode = LANE_MODE_SPLIT;
145
+ break;
146
+ case 2:
147
+ dphy->lane_mode = PHY_SPLIT_23;
148
+ dphy_hw->lane_mode = LANE_MODE_SPLIT;
149
+ break;
150
+ default:
151
+ dphy->lane_mode = PHY_FULL_MODE;
152
+ dphy_hw->lane_mode = LANE_MODE_FULL;
153
+ break;
154
+ }
155
+ dphy->dphy_hw = dphy_hw;
156
+ dphy->phy_hw[index] = (void *)dphy_hw;
157
+ dphy->csi_info.dphy_vendor[index] = PHY_VENDOR_INNO;
158
+ mutex_unlock(&dphy_hw->mutex);
159
+ } else if (dphy->drv_data->chip_id == CHIP_ID_RK3588) {
160
+ if (csi_idx < 2) {
161
+ dcphy_hw = dphy->samsung_phy_group[csi_idx];
162
+ mutex_lock(&dcphy_hw->mutex);
163
+ dcphy_hw->dphy_dev[dcphy_hw->dphy_dev_num] = dphy;
164
+ dcphy_hw->dphy_dev_num++;
165
+ mutex_unlock(&dcphy_hw->mutex);
166
+ dphy->samsung_phy = dcphy_hw;
167
+ dphy->phy_hw[index] = (void *)dcphy_hw;
168
+ dphy->dphy_param = rk3588_dcphy_param;
169
+ dphy->csi_info.dphy_vendor[index] = PHY_VENDOR_SAMSUNG;
170
+ } else {
171
+ dphy_hw = dphy->dphy_hw_group[(csi_idx - 2) / 2];
172
+ mutex_lock(&dphy_hw->mutex);
173
+ if (csi_idx == 2 || csi_idx == 4) {
174
+ if (lanes == 4) {
175
+ dphy->lane_mode = PHY_FULL_MODE;
176
+ dphy_hw->lane_mode = LANE_MODE_FULL;
177
+ if (csi_idx == 2)
178
+ dphy->phy_index = 0;
179
+ else
180
+ dphy->phy_index = 3;
181
+ } else {
182
+ dphy->lane_mode = PHY_SPLIT_01;
183
+ dphy_hw->lane_mode = LANE_MODE_SPLIT;
184
+ if (csi_idx == 2)
185
+ dphy->phy_index = 1;
186
+ else
187
+ dphy->phy_index = 4;
188
+ }
189
+ } else if (csi_idx == 3 || csi_idx == 5) {
190
+ if (lanes == 4) {
191
+ dev_info(dphy->dev, "%s csi host%d only support PHY_SPLIT_23\n",
192
+ __func__, csi_idx);
193
+ mutex_unlock(&dphy_hw->mutex);
194
+ return -EINVAL;
195
+ }
196
+ dphy->lane_mode = PHY_SPLIT_23;
197
+ dphy_hw->lane_mode = LANE_MODE_SPLIT;
198
+ if (csi_idx == 3)
199
+ dphy->phy_index = 2;
200
+ else
201
+ dphy->phy_index = 5;
202
+ }
203
+ dphy_hw->dphy_dev[dphy_hw->dphy_dev_num] = dphy;
204
+ dphy_hw->dphy_dev_num++;
205
+ dphy->dphy_hw = dphy_hw;
206
+ dphy->phy_hw[index] = (void *)dphy_hw;
207
+ dphy->csi_info.dphy_vendor[index] = PHY_VENDOR_INNO;
208
+ mutex_unlock(&dphy_hw->mutex);
209
+ }
210
+ } else {
211
+ dphy_hw = dphy->dphy_hw_group[csi_idx / 2];
212
+ mutex_lock(&dphy_hw->mutex);
213
+ if (csi_idx == 0 || csi_idx == 2) {
214
+ if (lanes == 4) {
215
+ dphy->lane_mode = PHY_FULL_MODE;
216
+ dphy_hw->lane_mode = LANE_MODE_FULL;
217
+ if (csi_idx == 0)
218
+ dphy->phy_index = 0;
219
+ else
220
+ dphy->phy_index = 3;
221
+ } else {
222
+ dphy->lane_mode = PHY_SPLIT_01;
223
+ dphy_hw->lane_mode = LANE_MODE_SPLIT;
224
+ if (csi_idx == 0)
225
+ dphy->phy_index = 1;
226
+ else
227
+ dphy->phy_index = 4;
228
+ }
229
+ } else if (csi_idx == 1 || csi_idx == 3) {
230
+ if (lanes == 4) {
231
+ dev_info(dphy->dev, "%s csi host%d only support PHY_SPLIT_23\n",
232
+ __func__, csi_idx);
233
+ mutex_unlock(&dphy_hw->mutex);
234
+ return -EINVAL;
235
+ }
236
+ dphy->lane_mode = PHY_SPLIT_23;
237
+ dphy_hw->lane_mode = LANE_MODE_SPLIT;
238
+ if (csi_idx == 1)
239
+ dphy->phy_index = 2;
240
+ else
241
+ dphy->phy_index = 5;
242
+ } else {
243
+ dev_info(dphy->dev, "%s error csi host%d\n",
244
+ __func__, csi_idx);
245
+ mutex_unlock(&dphy_hw->mutex);
246
+ return -EINVAL;
247
+ }
248
+ dphy_hw->dphy_dev[dphy_hw->dphy_dev_num] = dphy;
249
+ dphy_hw->dphy_dev_num++;
250
+ dphy->phy_hw[index] = (void *)dphy_hw;
251
+ dphy->csi_info.dphy_vendor[index] = PHY_VENDOR_INNO;
252
+ mutex_unlock(&dphy_hw->mutex);
253
+ }
254
+
255
+ return 0;
256
+}
257
+
258
+static void rockchip_csi2_samsung_phy_remove_dphy_dev(struct csi2_dphy *dphy,
259
+ struct samsung_mipi_dcphy *dcphy_hw)
260
+{
261
+ int i = 0;
262
+ bool is_find_dev = false;
263
+ struct csi2_dphy *csi2_dphy = NULL;
264
+
265
+ for (i = 0; i < dcphy_hw->dphy_dev_num; i++) {
266
+ csi2_dphy = dcphy_hw->dphy_dev[i];
267
+ if (csi2_dphy &&
268
+ csi2_dphy->phy_index == dphy->phy_index)
269
+ is_find_dev = true;
270
+ if (is_find_dev) {
271
+ if (i < dcphy_hw->dphy_dev_num - 1)
272
+ dcphy_hw->dphy_dev[i] = dcphy_hw->dphy_dev[i + 1];
273
+ else
274
+ dcphy_hw->dphy_dev[i] = NULL;
275
+ }
276
+ }
277
+ if (is_find_dev)
278
+ dcphy_hw->dphy_dev_num--;
279
+}
280
+
281
+static void rockchip_csi2_inno_phy_remove_dphy_dev(struct csi2_dphy *dphy,
282
+ struct csi2_dphy_hw *dphy_hw)
283
+{
284
+ int i = 0;
285
+ bool is_find_dev = false;
286
+ struct csi2_dphy *csi2_dphy = NULL;
287
+
288
+ for (i = 0; i < dphy_hw->dphy_dev_num; i++) {
289
+ csi2_dphy = dphy_hw->dphy_dev[i];
290
+ if (csi2_dphy &&
291
+ csi2_dphy->phy_index == dphy->phy_index)
292
+ is_find_dev = true;
293
+ if (is_find_dev) {
294
+ if (i < dphy_hw->dphy_dev_num - 1)
295
+ dphy_hw->dphy_dev[i] = dphy_hw->dphy_dev[i + 1];
296
+ else
297
+ dphy_hw->dphy_dev[i] = NULL;
298
+ }
299
+ }
300
+ if (is_find_dev)
301
+ dphy_hw->dphy_dev_num--;
302
+}
303
+
304
+static int rockchip_csi2_dphy_detach_hw(struct csi2_dphy *dphy, int csi_idx, int index)
305
+{
306
+ struct csi2_dphy_hw *dphy_hw = NULL;
307
+ struct samsung_mipi_dcphy *dcphy_hw = NULL;
308
+
309
+ if (dphy->drv_data->chip_id == CHIP_ID_RK3568 ||
310
+ dphy->drv_data->chip_id == CHIP_ID_RV1106) {
311
+ dphy_hw = (struct csi2_dphy_hw *)dphy->phy_hw[index];
312
+ if (!dphy_hw) {
313
+ dev_err(dphy->dev, "%s csi_idx %d detach hw failed\n",
314
+ __func__, csi_idx);
315
+ return -EINVAL;
316
+ }
317
+ mutex_lock(&dphy_hw->mutex);
318
+ rockchip_csi2_inno_phy_remove_dphy_dev(dphy, dphy_hw);
319
+ mutex_unlock(&dphy_hw->mutex);
320
+ } else if (dphy->drv_data->chip_id == CHIP_ID_RK3588) {
321
+ if (csi_idx < 2) {
322
+ dcphy_hw = (struct samsung_mipi_dcphy *)dphy->phy_hw[index];
323
+ if (!dcphy_hw) {
324
+ dev_err(dphy->dev, "%s csi_idx %d detach hw failed\n",
325
+ __func__, csi_idx);
326
+ return -EINVAL;
327
+ }
328
+ mutex_lock(&dcphy_hw->mutex);
329
+ rockchip_csi2_samsung_phy_remove_dphy_dev(dphy, dcphy_hw);
330
+ mutex_unlock(&dcphy_hw->mutex);
331
+ } else {
332
+ dphy_hw = (struct csi2_dphy_hw *)dphy->phy_hw[index];
333
+ if (!dphy_hw) {
334
+ dev_err(dphy->dev, "%s csi_idx %d detach hw failed\n",
335
+ __func__, csi_idx);
336
+ return -EINVAL;
337
+ }
338
+ mutex_lock(&dphy_hw->mutex);
339
+ rockchip_csi2_inno_phy_remove_dphy_dev(dphy, dphy_hw);
340
+ mutex_unlock(&dphy_hw->mutex);
341
+ }
342
+ } else {
343
+ dphy_hw = (struct csi2_dphy_hw *)dphy->phy_hw[index];
344
+ if (!dphy_hw) {
345
+ dev_err(dphy->dev, "%s csi_idx %d detach hw failed\n",
346
+ __func__, csi_idx);
347
+ return -EINVAL;
348
+ }
349
+ mutex_lock(&dphy_hw->mutex);
350
+ rockchip_csi2_inno_phy_remove_dphy_dev(dphy, dphy_hw);
351
+ mutex_unlock(&dphy_hw->mutex);
352
+ }
353
+
354
+ return 0;
355
+}
356
+
100357 static int csi2_dphy_update_sensor_mbus(struct v4l2_subdev *sd)
101358 {
102359 struct csi2_dphy *dphy = to_csi2_dphy(sd);
103360 struct v4l2_subdev *sensor_sd = get_remote_sensor(sd);
104
- struct csi2_sensor *sensor = sd_to_sensor(dphy, sensor_sd);
361
+ struct csi2_sensor *sensor;
105362 struct v4l2_mbus_config mbus;
106
- int ret;
363
+ int ret = 0;
107364
108
- ret = v4l2_subdev_call(sensor_sd, video, g_mbus_config, &mbus);
365
+ if (!sensor_sd)
366
+ return -ENODEV;
367
+ sensor = sd_to_sensor(dphy, sensor_sd);
368
+ if (!sensor)
369
+ return -ENODEV;
370
+
371
+ ret = v4l2_subdev_call(sensor_sd, pad, get_mbus_config, 0, &mbus);
109372 if (ret)
110373 return ret;
111374
....@@ -130,23 +393,80 @@
130393 return 0;
131394 }
132395
396
+static int csi2_dphy_update_config(struct v4l2_subdev *sd)
397
+{
398
+ struct csi2_dphy *dphy = to_csi2_dphy(sd);
399
+ struct v4l2_subdev *sensor_sd = get_remote_sensor(sd);
400
+ struct rkmodule_csi_dphy_param dphy_param;
401
+ struct rkmodule_bus_config bus_config;
402
+ int csi_idx = 0;
403
+ int ret = 0;
404
+ int i = 0;
405
+
406
+ for (i = 0; i < dphy->csi_info.csi_num; i++) {
407
+ if (dphy->drv_data->chip_id != CHIP_ID_RK3568 &&
408
+ dphy->drv_data->chip_id != CHIP_ID_RV1106) {
409
+ csi_idx = dphy->csi_info.csi_idx[i];
410
+ rockchip_csi2_dphy_attach_hw(dphy, csi_idx, i);
411
+ }
412
+ if (dphy->csi_info.dphy_vendor[i] == PHY_VENDOR_INNO) {
413
+ ret = v4l2_subdev_call(sensor_sd, core, ioctl,
414
+ RKMODULE_GET_BUS_CONFIG, &bus_config);
415
+ if (!ret) {
416
+ dev_info(dphy->dev, "phy_mode %d,lane %d\n",
417
+ bus_config.bus.phy_mode, bus_config.bus.lanes);
418
+ if (bus_config.bus.phy_mode == PHY_FULL_MODE) {
419
+ if (dphy->phy_index % 3 == 2) {
420
+ dev_err(dphy->dev, "%s dphy%d only use for PHY_SPLIT_23\n",
421
+ __func__, dphy->phy_index);
422
+ return -EINVAL;
423
+ }
424
+ dphy->lane_mode = PHY_FULL_MODE;
425
+ dphy->dphy_hw->lane_mode = LANE_MODE_FULL;
426
+ } else if (bus_config.bus.phy_mode == PHY_SPLIT_01) {
427
+ if (dphy->phy_index % 3 == 2) {
428
+ dev_err(dphy->dev, "%s dphy%d only use for PHY_SPLIT_23\n",
429
+ __func__, dphy->phy_index);
430
+ return -EINVAL;
431
+ }
432
+ dphy->lane_mode = PHY_SPLIT_01;
433
+ dphy->dphy_hw->lane_mode = LANE_MODE_SPLIT;
434
+ } else if (bus_config.bus.phy_mode == PHY_SPLIT_23) {
435
+ if (dphy->phy_index % 3 != 2) {
436
+ dev_err(dphy->dev, "%s dphy%d not support PHY_SPLIT_23\n",
437
+ __func__, dphy->phy_index);
438
+ return -EINVAL;
439
+ }
440
+ dphy->lane_mode = PHY_SPLIT_23;
441
+ dphy->dphy_hw->lane_mode = LANE_MODE_SPLIT;
442
+ }
443
+ }
444
+ }
445
+ }
446
+ ret = v4l2_subdev_call(sensor_sd, core, ioctl,
447
+ RKMODULE_GET_CSI_DPHY_PARAM,
448
+ &dphy_param);
449
+ if (!ret)
450
+ dphy->dphy_param = dphy_param;
451
+ return 0;
452
+}
453
+
133454 static int csi2_dphy_s_stream_start(struct v4l2_subdev *sd)
134455 {
135456 struct csi2_dphy *dphy = to_csi2_dphy(sd);
136
- struct csi2_dphy_hw *hw = dphy->dphy_hw;
137
- int ret = 0;
457
+ int i = 0;
138458
139
- if (dphy->is_streaming)
140
- return 0;
141
-
142
- ret = csi2_dphy_get_sensor_data_rate(sd);
143
- if (ret < 0)
144
- return ret;
145
-
146
- csi2_dphy_update_sensor_mbus(sd);
147
-
148
- if (hw->stream_on)
149
- hw->stream_on(dphy, sd);
459
+ for (i = 0; i < dphy->csi_info.csi_num; i++) {
460
+ if (dphy->csi_info.dphy_vendor[i] == PHY_VENDOR_SAMSUNG) {
461
+ dphy->samsung_phy = (struct samsung_mipi_dcphy *)dphy->phy_hw[i];
462
+ if (dphy->samsung_phy && dphy->samsung_phy->stream_on)
463
+ dphy->samsung_phy->stream_on(dphy, sd);
464
+ } else {
465
+ dphy->dphy_hw = (struct csi2_dphy_hw *)dphy->phy_hw[i];
466
+ if (dphy->dphy_hw && dphy->dphy_hw->stream_on)
467
+ dphy->dphy_hw->stream_on(dphy, sd);
468
+ }
469
+ }
150470
151471 dphy->is_streaming = true;
152472
....@@ -156,13 +476,22 @@
156476 static int csi2_dphy_s_stream_stop(struct v4l2_subdev *sd)
157477 {
158478 struct csi2_dphy *dphy = to_csi2_dphy(sd);
159
- struct csi2_dphy_hw *hw = dphy->dphy_hw;
479
+ int i = 0;
160480
161
- if (!dphy->is_streaming)
162
- return 0;
163
-
164
- if (hw->stream_off)
165
- hw->stream_off(dphy, sd);
481
+ for (i = 0; i < dphy->csi_info.csi_num; i++) {
482
+ if (dphy->csi_info.dphy_vendor[i] == PHY_VENDOR_SAMSUNG) {
483
+ dphy->samsung_phy = (struct samsung_mipi_dcphy *)dphy->phy_hw[i];
484
+ if (dphy->samsung_phy && dphy->samsung_phy->stream_off)
485
+ dphy->samsung_phy->stream_off(dphy, sd);
486
+ } else {
487
+ dphy->dphy_hw = (struct csi2_dphy_hw *)dphy->phy_hw[i];
488
+ if (dphy->dphy_hw && dphy->dphy_hw->stream_off)
489
+ dphy->dphy_hw->stream_off(dphy, sd);
490
+ }
491
+ if (dphy->drv_data->chip_id != CHIP_ID_RK3568 &&
492
+ dphy->drv_data->chip_id != CHIP_ID_RV1106)
493
+ rockchip_csi2_dphy_detach_hw(dphy, dphy->csi_info.csi_idx[i], i);
494
+ }
166495
167496 dphy->is_streaming = false;
168497
....@@ -172,20 +501,94 @@
172501 return 0;
173502 }
174503
504
+static int csi2_dphy_enable_clk(struct csi2_dphy *dphy)
505
+{
506
+ struct csi2_dphy_hw *hw = NULL;
507
+ struct samsung_mipi_dcphy *samsung_phy = NULL;
508
+ int ret;
509
+ int i = 0;
510
+
511
+ for (i = 0; i < dphy->csi_info.csi_num; i++) {
512
+ if (dphy->csi_info.dphy_vendor[i] == PHY_VENDOR_SAMSUNG) {
513
+ samsung_phy = (struct samsung_mipi_dcphy *)dphy->phy_hw[i];
514
+ if (samsung_phy)
515
+ clk_prepare_enable(samsung_phy->pclk);
516
+ } else {
517
+ hw = (struct csi2_dphy_hw *)dphy->phy_hw[i];
518
+ if (hw) {
519
+ ret = clk_bulk_prepare_enable(hw->num_clks, hw->clks_bulk);
520
+ if (ret) {
521
+ dev_err(hw->dev, "failed to enable clks\n");
522
+ return ret;
523
+ }
524
+ }
525
+ }
526
+ }
527
+ return 0;
528
+}
529
+
530
+static void csi2_dphy_disable_clk(struct csi2_dphy *dphy)
531
+{
532
+ struct csi2_dphy_hw *hw = NULL;
533
+ struct samsung_mipi_dcphy *samsung_phy = NULL;
534
+ int i = 0;
535
+
536
+ for (i = 0; i < dphy->csi_info.csi_num; i++) {
537
+ if (dphy->csi_info.dphy_vendor[i] == PHY_VENDOR_SAMSUNG) {
538
+ samsung_phy = (struct samsung_mipi_dcphy *)dphy->phy_hw[i];
539
+ if (samsung_phy)
540
+ clk_disable_unprepare(samsung_phy->pclk);
541
+ } else {
542
+ hw = (struct csi2_dphy_hw *)dphy->phy_hw[i];
543
+ if (hw)
544
+ clk_bulk_disable_unprepare(hw->num_clks, hw->clks_bulk);
545
+ }
546
+ }
547
+}
548
+
175549 static int csi2_dphy_s_stream(struct v4l2_subdev *sd, int on)
176550 {
177551 struct csi2_dphy *dphy = to_csi2_dphy(sd);
178552 int ret = 0;
179553
180554 mutex_lock(&dphy->mutex);
181
- if (on)
555
+ if (on) {
556
+ if (dphy->is_streaming) {
557
+ mutex_unlock(&dphy->mutex);
558
+ return 0;
559
+ }
560
+
561
+ ret = csi2_dphy_get_sensor_data_rate(sd);
562
+ if (ret < 0) {
563
+ mutex_unlock(&dphy->mutex);
564
+ return ret;
565
+ }
566
+
567
+ csi2_dphy_update_sensor_mbus(sd);
568
+ ret = csi2_dphy_update_config(sd);
569
+ if (ret < 0) {
570
+ mutex_unlock(&dphy->mutex);
571
+ return ret;
572
+ }
573
+
574
+ ret = csi2_dphy_enable_clk(dphy);
575
+ if (ret) {
576
+ mutex_unlock(&dphy->mutex);
577
+ return ret;
578
+ }
182579 ret = csi2_dphy_s_stream_start(sd);
183
- else
580
+ } else {
581
+ if (!dphy->is_streaming) {
582
+ mutex_unlock(&dphy->mutex);
583
+ return 0;
584
+ }
184585 ret = csi2_dphy_s_stream_stop(sd);
586
+ csi2_dphy_disable_clk(dphy);
587
+ }
185588 mutex_unlock(&dphy->mutex);
186589
187
- dev_info(dphy->dev, "%s stream on:%d, dphy%d\n",
188
- __func__, on, dphy->phy_index);
590
+ dev_info(dphy->dev, "%s stream on:%d, dphy%d, ret %d\n",
591
+ __func__, on, dphy->phy_index, ret);
189592
190593 return ret;
191594 }
....@@ -202,7 +605,8 @@
202605 }
203606
204607 static int csi2_dphy_g_mbus_config(struct v4l2_subdev *sd,
205
- struct v4l2_mbus_config *config)
608
+ unsigned int pad_id,
609
+ struct v4l2_mbus_config *config)
206610 {
207611 struct csi2_dphy *dphy = to_csi2_dphy(sd);
208612 struct v4l2_subdev *sensor_sd = get_remote_sensor(sd);
....@@ -211,6 +615,8 @@
211615 if (!sensor_sd)
212616 return -ENODEV;
213617 sensor = sd_to_sensor(dphy, sensor_sd);
618
+ if (!sensor)
619
+ return -ENODEV;
214620 csi2_dphy_update_sensor_mbus(sd);
215621 *config = sensor->mbus;
216622
....@@ -232,30 +638,17 @@
232638 struct media_entity *me = dev_get_drvdata(dev);
233639 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(me);
234640 struct csi2_dphy *dphy = to_csi2_dphy(sd);
235
- struct csi2_dphy_hw *hw = dphy->dphy_hw;
236641
237
- if (hw)
238
- clk_bulk_disable_unprepare(hw->num_clks, hw->clks);
642
+ if (dphy->is_streaming) {
643
+ csi2_dphy_s_stream(sd, 0);
644
+ dphy->is_streaming = false;
645
+ }
239646
240647 return 0;
241648 }
242649
243650 static __maybe_unused int csi2_dphy_runtime_resume(struct device *dev)
244651 {
245
- struct media_entity *me = dev_get_drvdata(dev);
246
- struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(me);
247
- struct csi2_dphy *dphy = to_csi2_dphy(sd);
248
- struct csi2_dphy_hw *hw = dphy->dphy_hw;
249
- int ret;
250
-
251
- if (hw) {
252
- ret = clk_bulk_prepare_enable(hw->num_clks, hw->clks);
253
- if (ret) {
254
- dev_err(hw->dev, "failed to enable clks\n");
255
- return ret;
256
- }
257
- }
258
-
259652 return 0;
260653 }
261654
....@@ -266,7 +659,7 @@
266659 {
267660 struct csi2_dphy *dphy = to_csi2_dphy(sd);
268661 struct v4l2_subdev *sensor_sd = get_remote_sensor(sd);
269
- struct csi2_sensor *sensor = sd_to_sensor(dphy, sensor_sd);
662
+ struct csi2_sensor *sensor;
270663 int ret;
271664 /*
272665 * Do not allow format changes and just relay whatever
....@@ -274,8 +667,11 @@
274667 */
275668 if (!sensor_sd)
276669 return -ENODEV;
670
+ sensor = sd_to_sensor(dphy, sensor_sd);
671
+ if (!sensor)
672
+ return -ENODEV;
277673 ret = v4l2_subdev_call(sensor_sd, pad, get_fmt, NULL, fmt);
278
- if (!ret && fmt->pad == 0)
674
+ if (!ret && fmt->pad == 0 && fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE)
279675 sensor->format = fmt->format;
280676 return ret;
281677 }
....@@ -289,13 +685,79 @@
289685 return v4l2_subdev_call(sensor, pad, get_selection, NULL, sel);
290686 }
291687
688
+static long rkcif_csi2_dphy_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
689
+{
690
+ struct csi2_dphy *dphy = to_csi2_dphy(sd);
691
+ long ret = 0;
692
+ int i = 0;
693
+ int on = 0;
694
+
695
+ switch (cmd) {
696
+ case RKCIF_CMD_SET_CSI_IDX:
697
+ if (dphy->drv_data->chip_id != CHIP_ID_RK3568 &&
698
+ dphy->drv_data->chip_id != CHIP_ID_RV1106)
699
+ dphy->csi_info = *((struct rkcif_csi_info *)arg);
700
+ break;
701
+ case RKMODULE_SET_QUICK_STREAM:
702
+ for (i = 0; i < dphy->csi_info.csi_num; i++) {
703
+ if (dphy->csi_info.dphy_vendor[i] == PHY_VENDOR_INNO) {
704
+ dphy->dphy_hw = (struct csi2_dphy_hw *)dphy->phy_hw[i];
705
+ if (!dphy->dphy_hw ||
706
+ !dphy->dphy_hw->quick_stream_off ||
707
+ !dphy->dphy_hw->quick_stream_on) {
708
+ ret = -EINVAL;
709
+ break;
710
+ }
711
+ on = *(int *)arg;
712
+ if (on)
713
+ dphy->dphy_hw->quick_stream_on(dphy, sd);
714
+ else
715
+ dphy->dphy_hw->quick_stream_off(dphy, sd);
716
+ }
717
+ }
718
+ break;
719
+ default:
720
+ ret = -ENOIOCTLCMD;
721
+ break;
722
+ }
723
+
724
+ return ret;
725
+}
726
+
727
+#ifdef CONFIG_COMPAT
728
+static long rkcif_csi2_dphy_compat_ioctl32(struct v4l2_subdev *sd,
729
+ unsigned int cmd, unsigned long arg)
730
+{
731
+ void __user *up = compat_ptr(arg);
732
+ struct rkcif_csi_info csi_info = {0};
733
+ long ret;
734
+
735
+ switch (cmd) {
736
+ case RKCIF_CMD_SET_CSI_IDX:
737
+ if (copy_from_user(&csi_info, up, sizeof(struct rkcif_csi_info)))
738
+ return -EFAULT;
739
+
740
+ ret = rkcif_csi2_dphy_ioctl(sd, cmd, &csi_info);
741
+ break;
742
+ default:
743
+ ret = -ENOIOCTLCMD;
744
+ break;
745
+ }
746
+
747
+ return ret;
748
+}
749
+#endif
750
+
292751 static const struct v4l2_subdev_core_ops csi2_dphy_core_ops = {
293752 .s_power = csi2_dphy_s_power,
753
+ .ioctl = rkcif_csi2_dphy_ioctl,
754
+#ifdef CONFIG_COMPAT
755
+ .compat_ioctl32 = rkcif_csi2_dphy_compat_ioctl32,
756
+#endif
294757 };
295758
296759 static const struct v4l2_subdev_video_ops csi2_dphy_video_ops = {
297760 .g_frame_interval = csi2_dphy_g_frame_interval,
298
- .g_mbus_config = csi2_dphy_g_mbus_config,
299761 .s_stream = csi2_dphy_s_stream,
300762 };
301763
....@@ -303,6 +765,7 @@
303765 .set_fmt = csi2_dphy_get_set_fmt,
304766 .get_fmt = csi2_dphy_get_set_fmt,
305767 .get_selection = csi2_dphy_get_selection,
768
+ .get_mbus_config = csi2_dphy_g_mbus_config,
306769 };
307770
308771 static const struct v4l2_subdev_ops csi2_dphy_subdev_ops = {
....@@ -373,7 +836,8 @@
373836 notifier);
374837 struct csi2_sensor *sensor = sd_to_sensor(dphy, sd);
375838
376
- sensor->sd = NULL;
839
+ if (sensor)
840
+ sensor->sd = NULL;
377841 }
378842
379843 static const struct
....@@ -395,10 +859,14 @@
395859 return -EINVAL;
396860 }
397861
398
- if (vep->bus_type == V4L2_MBUS_CSI2) {
399
- config->type = V4L2_MBUS_CSI2;
862
+ if (vep->bus_type == V4L2_MBUS_CSI2_DPHY ||
863
+ vep->bus_type == V4L2_MBUS_CSI2_CPHY) {
864
+ config->type = vep->bus_type;
400865 config->flags = vep->bus.mipi_csi2.flags;
401866 s_asd->lanes = vep->bus.mipi_csi2.num_data_lanes;
867
+ } else if (vep->bus_type == V4L2_MBUS_CCP2) {
868
+ config->type = V4L2_MBUS_CCP2;
869
+ s_asd->lanes = vep->bus.mipi_csi1.data_lane;
402870 } else {
403871 dev_err(dev, "Only CSI2 type is currently supported\n");
404872 return -EINVAL;
....@@ -438,15 +906,14 @@
438906 if (ret < 0)
439907 return ret;
440908
909
+ v4l2_async_notifier_init(&dphy->notifier);
910
+
441911 ret = v4l2_async_notifier_parse_fwnode_endpoints_by_port(
442912 dphy->dev, &dphy->notifier,
443913 sizeof(struct sensor_async_subdev), 0,
444914 rockchip_csi2_dphy_fwnode_parse);
445915 if (ret < 0)
446916 return ret;
447
-
448
- if (!dphy->notifier.num_subdevs)
449
- return -ENODEV; /* no endpoint */
450917
451918 dphy->sd.subdev_notifier = &dphy->notifier;
452919 dphy->notifier.ops = &rockchip_csi2_dphy_async_ops;
....@@ -461,99 +928,127 @@
461928 return v4l2_async_register_subdev(&dphy->sd);
462929 }
463930
464
-static int rockchip_csi2_dphy_attach_hw(struct csi2_dphy *dphy)
931
+static struct dphy_drv_data rk3568_dphy_drv_data = {
932
+ .dev_name = "csi2dphy",
933
+ .chip_id = CHIP_ID_RK3568,
934
+ .num_inno_phy = 1,
935
+ .num_samsung_phy = 0,
936
+};
937
+
938
+static struct dphy_drv_data rk3588_dphy_drv_data = {
939
+ .dev_name = "csi2dphy",
940
+ .chip_id = CHIP_ID_RK3588,
941
+ .num_inno_phy = 2,
942
+ .num_samsung_phy = 2,
943
+};
944
+
945
+static struct dphy_drv_data rv1106_dphy_drv_data = {
946
+ .dev_name = "csi2dphy",
947
+ .chip_id = CHIP_ID_RV1106,
948
+ .num_inno_phy = 1,
949
+ .num_samsung_phy = 0,
950
+};
951
+
952
+static struct dphy_drv_data rk3562_dphy_drv_data = {
953
+ .dev_name = "csi2dphy",
954
+ .chip_id = CHIP_ID_RK3562,
955
+ .num_inno_phy = 2,
956
+ .num_samsung_phy = 0,
957
+};
958
+
959
+static const struct of_device_id rockchip_csi2_dphy_match_id[] = {
960
+ {
961
+ .compatible = "rockchip,rk3568-csi2-dphy",
962
+ .data = &rk3568_dphy_drv_data,
963
+ },
964
+ {
965
+ .compatible = "rockchip,rk3588-csi2-dphy",
966
+ .data = &rk3588_dphy_drv_data,
967
+ },
968
+ {
969
+ .compatible = "rockchip,rv1106-csi2-dphy",
970
+ .data = &rv1106_dphy_drv_data,
971
+ },
972
+ {
973
+ .compatible = "rockchip,rk3562-csi2-dphy",
974
+ .data = &rk3562_dphy_drv_data,
975
+ },
976
+ {}
977
+};
978
+MODULE_DEVICE_TABLE(of, rockchip_csi2_dphy_match_id);
979
+
980
+static int rockchip_csi2_dphy_get_samsung_phy_hw(struct csi2_dphy *dphy)
981
+{
982
+ struct phy *dcphy;
983
+ struct device *dev = dphy->dev;
984
+ struct samsung_mipi_dcphy *dcphy_hw;
985
+ char phy_name[32];
986
+ int i = 0;
987
+ int ret = 0;
988
+
989
+ for (i = 0; i < dphy->drv_data->num_samsung_phy; i++) {
990
+ sprintf(phy_name, "dcphy%d", i);
991
+ dcphy = devm_phy_optional_get(dev, phy_name);
992
+ if (IS_ERR(dcphy)) {
993
+ ret = PTR_ERR(dcphy);
994
+ dev_err(dphy->dev, "failed to get mipi dcphy: %d\n", ret);
995
+ return ret;
996
+ }
997
+ dcphy_hw = phy_get_drvdata(dcphy);
998
+ dphy->samsung_phy_group[i] = dcphy_hw;
999
+ }
1000
+ return 0;
1001
+}
1002
+
1003
+static int rockchip_csi2_dphy_get_inno_phy_hw(struct csi2_dphy *dphy)
4651004 {
4661005 struct platform_device *plat_dev;
4671006 struct device *dev = dphy->dev;
4681007 struct csi2_dphy_hw *dphy_hw;
4691008 struct device_node *np;
470
- enum csi2_dphy_lane_mode target_mode;
471
- int i;
1009
+ int i = 0;
4721010
473
- if (dphy->phy_index == 0)
474
- target_mode = LANE_MODE_FULL;
475
- else
476
- target_mode = LANE_MODE_SPLIT;
477
-
478
- np = of_parse_phandle(dev->of_node, "rockchip,hw", 0);
479
- if (!np || !of_device_is_available(np)) {
480
- dev_err(dphy->dev,
481
- "failed to get dphy%d hw node\n", dphy->phy_index);
482
- return -ENODEV;
483
- }
484
-
485
- plat_dev = of_find_device_by_node(np);
486
- of_node_put(np);
487
- if (!plat_dev) {
488
- dev_err(dphy->dev,
489
- "failed to get dphy%d hw from node\n",
490
- dphy->phy_index);
491
- return -ENODEV;
492
- }
493
-
494
- dphy_hw = platform_get_drvdata(plat_dev);
495
- if (!dphy_hw) {
496
- dev_err(dphy->dev,
497
- "failed attach dphy%d hw\n",
498
- dphy->phy_index);
499
- return -EINVAL;
500
- }
501
-
502
- if (dphy_hw->lane_mode == LANE_MODE_UNDEF) {
503
- dphy_hw->lane_mode = target_mode;
504
- } else {
505
- struct csi2_dphy *phy = dphy_hw->dphy_dev[0];
506
-
507
- for (i = 0; i < dphy_hw->dphy_dev_num; i++) {
508
- if (dphy_hw->dphy_dev[i]->lane_mode == dphy_hw->lane_mode) {
509
- phy = dphy_hw->dphy_dev[i];
510
- break;
511
- }
512
- }
513
-
514
- if (target_mode != dphy_hw->lane_mode) {
1011
+ for (i = 0; i < dphy->drv_data->num_inno_phy; i++) {
1012
+ np = of_parse_phandle(dev->of_node, "rockchip,hw", i);
1013
+ if (!np || !of_device_is_available(np)) {
5151014 dev_err(dphy->dev,
516
- "Err:csi2 dphy hw has been set as %s mode by phy%d, target mode is:%s\n",
517
- dphy_hw->lane_mode == LANE_MODE_FULL ? "full" : "split",
518
- phy->phy_index,
519
- target_mode == LANE_MODE_FULL ? "full" : "split");
1015
+ "failed to get dphy%d hw node\n", dphy->phy_index);
5201016 return -ENODEV;
5211017 }
522
- }
523
-
524
- dphy_hw->dphy_dev[dphy_hw->dphy_dev_num] = dphy;
525
- dphy_hw->dphy_dev_num++;
526
- dphy->dphy_hw = dphy_hw;
527
-
528
- return 0;
529
-}
530
-
531
-static int rockchip_csi2_dphy_detach_hw(struct csi2_dphy *dphy)
532
-{
533
- struct csi2_dphy_hw *dphy_hw = dphy->dphy_hw;
534
- struct csi2_dphy *csi2_dphy = NULL;
535
- int i;
536
-
537
- for (i = 0; i < dphy_hw->dphy_dev_num; i++) {
538
- csi2_dphy = dphy_hw->dphy_dev[i];
539
- if (csi2_dphy &&
540
- csi2_dphy->phy_index == dphy->phy_index) {
541
- dphy_hw->dphy_dev[i] = NULL;
542
- dphy_hw->dphy_dev_num--;
543
- break;
1018
+ plat_dev = of_find_device_by_node(np);
1019
+ of_node_put(np);
1020
+ if (!plat_dev) {
1021
+ dev_err(dphy->dev,
1022
+ "failed to get dphy%d hw from node\n",
1023
+ dphy->phy_index);
1024
+ return -ENODEV;
5441025 }
1026
+ dphy_hw = platform_get_drvdata(plat_dev);
1027
+ if (!dphy_hw) {
1028
+ dev_err(dphy->dev,
1029
+ "failed attach dphy%d hw\n",
1030
+ dphy->phy_index);
1031
+ return -EINVAL;
1032
+ }
1033
+ dphy->dphy_hw_group[i] = dphy_hw;
5451034 }
546
-
5471035 return 0;
5481036 }
5491037
550
-static const struct of_device_id rockchip_csi2_dphy_match_id[] = {
551
- {
552
- .compatible = "rockchip,rk3568-csi2-dphy",
553
- },
554
- {}
555
-};
556
-MODULE_DEVICE_TABLE(of, rockchip_csi2_dphy_match_id);
1038
+static int rockchip_csi2_dphy_get_hw(struct csi2_dphy *dphy)
1039
+{
1040
+ int ret = 0;
1041
+
1042
+ if (dphy->drv_data->chip_id == CHIP_ID_RK3588) {
1043
+ ret = rockchip_csi2_dphy_get_samsung_phy_hw(dphy);
1044
+ if (ret)
1045
+ return ret;
1046
+ ret = rockchip_csi2_dphy_get_inno_phy_hw(dphy);
1047
+ } else {
1048
+ ret = rockchip_csi2_dphy_get_inno_phy_hw(dphy);
1049
+ }
1050
+ return ret;
1051
+}
5571052
5581053 static int rockchip_csi2_dphy_probe(struct platform_device *pdev)
5591054 {
....@@ -561,6 +1056,7 @@
5611056 const struct of_device_id *of_id;
5621057 struct csi2_dphy *csi2dphy;
5631058 struct v4l2_subdev *sd;
1059
+ const struct dphy_drv_data *drv_data;
5641060 int ret;
5651061
5661062 csi2dphy = devm_kzalloc(dev, sizeof(*csi2dphy), GFP_KERNEL);
....@@ -571,19 +1067,24 @@
5711067 of_id = of_match_device(rockchip_csi2_dphy_match_id, dev);
5721068 if (!of_id)
5731069 return -EINVAL;
1070
+ drv_data = of_id->data;
1071
+ csi2dphy->drv_data = drv_data;
5741072
575
- csi2dphy->phy_index = of_alias_get_id(dev->of_node, "csi2dphy");
576
- if (csi2dphy->phy_index < 0 || csi2dphy->phy_index > 2)
1073
+ csi2dphy->phy_index = of_alias_get_id(dev->of_node, drv_data->dev_name);
1074
+ if (csi2dphy->phy_index < 0 || csi2dphy->phy_index >= PHY_MAX)
5771075 csi2dphy->phy_index = 0;
5781076
579
- ret = rockchip_csi2_dphy_attach_hw(csi2dphy);
580
- if (ret) {
581
- dev_err(dev,
582
- "csi2 dphy hw can't be attached, register dphy%d failed!\n",
583
- csi2dphy->phy_index);
584
- return -ENODEV;
1077
+ ret = rockchip_csi2_dphy_get_hw(csi2dphy);
1078
+ if (ret)
1079
+ return -EINVAL;
1080
+ if (csi2dphy->drv_data->chip_id == CHIP_ID_RK3568 ||
1081
+ csi2dphy->drv_data->chip_id == CHIP_ID_RV1106) {
1082
+ csi2dphy->csi_info.csi_num = 1;
1083
+ csi2dphy->csi_info.dphy_vendor[0] = PHY_VENDOR_INNO;
1084
+ rockchip_csi2_dphy_attach_hw(csi2dphy, 0, 0);
1085
+ } else {
1086
+ csi2dphy->csi_info.csi_num = 0;
5851087 }
586
-
5871088 sd = &csi2dphy->sd;
5881089 mutex_init(&csi2dphy->mutex);
5891090 v4l2_subdev_init(sd, &csi2_dphy_subdev_ops);
....@@ -606,9 +1107,7 @@
6061107
6071108 detach_hw:
6081109 mutex_destroy(&csi2dphy->mutex);
609
- rockchip_csi2_dphy_detach_hw(csi2dphy);
610
-
611
- return 0;
1110
+ return -EINVAL;
6121111 }
6131112
6141113 static int rockchip_csi2_dphy_remove(struct platform_device *pdev)
....@@ -616,49 +1115,16 @@
6161115 struct media_entity *me = platform_get_drvdata(pdev);
6171116 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(me);
6181117 struct csi2_dphy *dphy = to_csi2_dphy(sd);
1118
+ int i = 0;
6191119
1120
+ for (i = 0; i < dphy->csi_info.csi_num; i++)
1121
+ rockchip_csi2_dphy_detach_hw(dphy, dphy->csi_info.csi_idx[i], i);
6201122 media_entity_cleanup(&sd->entity);
6211123
6221124 pm_runtime_disable(&pdev->dev);
6231125 mutex_destroy(&dphy->mutex);
6241126 return 0;
6251127 }
626
-static int __maybe_unused __rockchip_csi2dphy_clr_unready_dev(void)
627
-{
628
- struct csi2_dphy *csi2dphy;
629
-
630
- mutex_lock(&csi2dphy_dev_mutex);
631
- list_for_each_entry(csi2dphy, &csi2dphy_device_list, list)
632
- v4l2_async_notifier_clr_unready_dev(&csi2dphy->notifier);
633
- mutex_unlock(&csi2dphy_dev_mutex);
634
-
635
- return 0;
636
-}
637
-
638
-static int rockchip_csi2dphy_clr_unready_dev_param_set(const char *val,
639
- const struct kernel_param *kp)
640
-{
641
-#ifdef MODULE
642
- __rockchip_csi2dphy_clr_unready_dev();
643
-#endif
644
-
645
- return 0;
646
-}
647
-
648
-module_param_call(clr_unready_dev,
649
- rockchip_csi2dphy_clr_unready_dev_param_set,
650
- NULL, NULL, 0200);
651
-MODULE_PARM_DESC(clr_unready_dev, "clear unready devices");
652
-
653
-#ifndef MODULE
654
-static int __init rockchip_csi2_dphy_clr_unready_dev(void)
655
-{
656
- __rockchip_csi2dphy_clr_unready_dev();
657
-
658
- return 0;
659
-}
660
-late_initcall_sync(rockchip_csi2_dphy_clr_unready_dev);
661
-#endif
6621128
6631129 static const struct dev_pm_ops rockchip_csi2_dphy_pm_ops = {
6641130 SET_RUNTIME_PM_OPS(csi2_dphy_runtime_suspend,
....@@ -674,7 +1140,19 @@
6741140 .of_match_table = rockchip_csi2_dphy_match_id,
6751141 },
6761142 };
677
-EXPORT_SYMBOL(rockchip_csi2_dphy_driver);
1143
+
1144
+int rockchip_csi2_dphy_init(void)
1145
+{
1146
+ return platform_driver_register(&rockchip_csi2_dphy_driver);
1147
+}
1148
+
1149
+#if defined(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP) && !defined(CONFIG_INITCALL_ASYNC)
1150
+subsys_initcall(rockchip_csi2_dphy_init);
1151
+#else
1152
+#if !defined(CONFIG_VIDEO_REVERSE_IMAGE)
1153
+module_platform_driver(rockchip_csi2_dphy_driver);
1154
+#endif
1155
+#endif
6781156
6791157 MODULE_AUTHOR("Rockchip Camera/ISP team");
6801158 MODULE_DESCRIPTION("Rockchip MIPI CSI2 DPHY driver");