hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/phy/rockchip/phy-rockchip-csi2-dphy.c
....@@ -21,7 +21,9 @@
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"
2527
2628 struct sensor_async_subdev {
2729 struct v4l2_async_subdev asd;
....@@ -29,7 +31,6 @@
2931 int lanes;
3032 };
3133
32
-static DEFINE_MUTEX(csi2dphy_dev_mutex);
3334 static LIST_HEAD(csi2dphy_device_list);
3435
3536 static inline struct csi2_dphy *to_csi2_dphy(struct v4l2_subdev *subdev)
....@@ -73,6 +74,9 @@
7374 struct v4l2_querymenu qm = { .id = V4L2_CID_LINK_FREQ, };
7475 int ret;
7576
77
+ if (!sensor_sd)
78
+ return -ENODEV;
79
+
7680 link_freq = v4l2_ctrl_find(sensor_sd->ctrl_handler, V4L2_CID_LINK_FREQ);
7781 if (!link_freq) {
7882 v4l2_warn(sd, "No pixel rate control in subdev\n");
....@@ -101,11 +105,18 @@
101105 {
102106 struct csi2_dphy *dphy = to_csi2_dphy(sd);
103107 struct v4l2_subdev *sensor_sd = get_remote_sensor(sd);
104
- struct csi2_sensor *sensor = sd_to_sensor(dphy, sensor_sd);
108
+ struct csi2_sensor *sensor;
105109 struct v4l2_mbus_config mbus;
110
+ struct rkmodule_bus_config bus_config;
106111 int ret;
107112
108
- ret = v4l2_subdev_call(sensor_sd, video, g_mbus_config, &mbus);
113
+ if (!sensor_sd)
114
+ return -ENODEV;
115
+ sensor = sd_to_sensor(dphy, sensor_sd);
116
+ if (!sensor)
117
+ return -ENODEV;
118
+
119
+ ret = v4l2_subdev_call(sensor_sd, pad, get_mbus_config, 0, &mbus);
109120 if (ret)
110121 return ret;
111122
....@@ -126,14 +137,69 @@
126137 default:
127138 return -EINVAL;
128139 }
129
-
130
- return 0;
140
+ if (dphy->drv_data->vendor == PHY_VENDOR_INNO) {
141
+ ret = v4l2_subdev_call(sensor_sd, core, ioctl,
142
+ RKMODULE_GET_BUS_CONFIG, &bus_config);
143
+ if (!ret) {
144
+ dev_info(dphy->dev, "phy_mode %d,lane %d\n",
145
+ bus_config.bus.phy_mode, bus_config.bus.lanes);
146
+ if (bus_config.bus.phy_mode == PHY_FULL_MODE) {
147
+ if (dphy->dphy_hw->drv_data->chip_id == CHIP_ID_RK3588 &&
148
+ dphy->phy_index % 3 == 2) {
149
+ dev_err(dphy->dev, "%s dphy%d only use for PHY_SPLIT_23\n",
150
+ __func__, dphy->phy_index);
151
+ ret = -EINVAL;
152
+ }
153
+ dphy->lane_mode = LANE_MODE_FULL;
154
+ } else if (bus_config.bus.phy_mode == PHY_SPLIT_01) {
155
+ if (dphy->dphy_hw->drv_data->chip_id == CHIP_ID_RK3588_DCPHY) {
156
+ dev_err(dphy->dev, "%s The chip not support split mode\n",
157
+ __func__);
158
+ ret = -EINVAL;
159
+ } else if (dphy->phy_index % 3 == 2) {
160
+ dev_err(dphy->dev, "%s dphy%d only use for PHY_SPLIT_23\n",
161
+ __func__, dphy->phy_index);
162
+ ret = -EINVAL;
163
+ } else {
164
+ dphy->lane_mode = LANE_MODE_SPLIT;
165
+ }
166
+ } else if (bus_config.bus.phy_mode == PHY_SPLIT_23) {
167
+ if (dphy->dphy_hw->drv_data->chip_id == CHIP_ID_RK3588_DCPHY) {
168
+ dev_err(dphy->dev, "%s The chip not support split mode\n",
169
+ __func__);
170
+ ret = -EINVAL;
171
+ } else if (dphy->phy_index % 3 != 2) {
172
+ dev_err(dphy->dev, "%s dphy%d not support PHY_SPLIT_23\n",
173
+ __func__, dphy->phy_index);
174
+ ret = -EINVAL;
175
+ } else {
176
+ dphy->lane_mode = LANE_MODE_SPLIT;
177
+ }
178
+ }
179
+ if (!ret)
180
+ dphy->dphy_hw->lane_mode = dphy->lane_mode;
181
+ } else {
182
+ ret = 0;
183
+ }
184
+ }
185
+ if (dphy->drv_data->vendor == PHY_VENDOR_SAMSUNG) {
186
+ ret = v4l2_subdev_call(sensor_sd, core, ioctl,
187
+ RKMODULE_GET_CSI_DPHY_PARAM,
188
+ &dphy->dphy_param);
189
+ if (ret) {
190
+ dev_dbg(dphy->dev, "%s fail to get dphy param, used default value\n",
191
+ __func__);
192
+ ret = 0;
193
+ }
194
+ }
195
+ return ret;
131196 }
132197
133198 static int csi2_dphy_s_stream_start(struct v4l2_subdev *sd)
134199 {
135200 struct csi2_dphy *dphy = to_csi2_dphy(sd);
136201 struct csi2_dphy_hw *hw = dphy->dphy_hw;
202
+ struct samsung_mipi_dcphy *samsung_phy = dphy->samsung_phy;
137203 int ret = 0;
138204
139205 if (dphy->is_streaming)
....@@ -145,8 +211,13 @@
145211
146212 csi2_dphy_update_sensor_mbus(sd);
147213
148
- if (hw->stream_on)
149
- hw->stream_on(dphy, sd);
214
+ if (dphy->drv_data->vendor == PHY_VENDOR_SAMSUNG) {
215
+ if (samsung_phy && samsung_phy->stream_on)
216
+ samsung_phy->stream_on(dphy, sd);
217
+ } else {
218
+ if (hw->stream_on)
219
+ hw->stream_on(dphy, sd);
220
+ }
150221
151222 dphy->is_streaming = true;
152223
....@@ -157,12 +228,18 @@
157228 {
158229 struct csi2_dphy *dphy = to_csi2_dphy(sd);
159230 struct csi2_dphy_hw *hw = dphy->dphy_hw;
231
+ struct samsung_mipi_dcphy *samsung_phy = dphy->samsung_phy;
160232
161233 if (!dphy->is_streaming)
162234 return 0;
163235
164
- if (hw->stream_off)
165
- hw->stream_off(dphy, sd);
236
+ if (dphy->drv_data->vendor == PHY_VENDOR_SAMSUNG) {
237
+ if (samsung_phy && samsung_phy->stream_off)
238
+ samsung_phy->stream_off(dphy, sd);
239
+ } else {
240
+ if (hw->stream_off)
241
+ hw->stream_off(dphy, sd);
242
+ }
166243
167244 dphy->is_streaming = false;
168245
....@@ -202,7 +279,8 @@
202279 }
203280
204281 static int csi2_dphy_g_mbus_config(struct v4l2_subdev *sd,
205
- struct v4l2_mbus_config *config)
282
+ unsigned int pad_id,
283
+ struct v4l2_mbus_config *config)
206284 {
207285 struct csi2_dphy *dphy = to_csi2_dphy(sd);
208286 struct v4l2_subdev *sensor_sd = get_remote_sensor(sd);
....@@ -211,6 +289,8 @@
211289 if (!sensor_sd)
212290 return -ENODEV;
213291 sensor = sd_to_sensor(dphy, sensor_sd);
292
+ if (!sensor)
293
+ return -ENODEV;
214294 csi2_dphy_update_sensor_mbus(sd);
215295 *config = sensor->mbus;
216296
....@@ -233,9 +313,15 @@
233313 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(me);
234314 struct csi2_dphy *dphy = to_csi2_dphy(sd);
235315 struct csi2_dphy_hw *hw = dphy->dphy_hw;
316
+ struct samsung_mipi_dcphy *samsung_phy = dphy->samsung_phy;
236317
237
- if (hw)
238
- clk_bulk_disable_unprepare(hw->num_clks, hw->clks);
318
+ if (dphy->drv_data->vendor == PHY_VENDOR_SAMSUNG) {
319
+ if (samsung_phy)
320
+ clk_disable_unprepare(samsung_phy->pclk);
321
+ } else {
322
+ if (hw)
323
+ clk_bulk_disable_unprepare(hw->num_clks, hw->clks_bulk);
324
+ }
239325
240326 return 0;
241327 }
....@@ -246,13 +332,19 @@
246332 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(me);
247333 struct csi2_dphy *dphy = to_csi2_dphy(sd);
248334 struct csi2_dphy_hw *hw = dphy->dphy_hw;
335
+ struct samsung_mipi_dcphy *samsung_phy = dphy->samsung_phy;
249336 int ret;
250337
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;
338
+ if (dphy->drv_data->vendor == PHY_VENDOR_SAMSUNG) {
339
+ if (samsung_phy)
340
+ clk_prepare_enable(samsung_phy->pclk);
341
+ } else {
342
+ if (hw) {
343
+ ret = clk_bulk_prepare_enable(hw->num_clks, hw->clks_bulk);
344
+ if (ret) {
345
+ dev_err(hw->dev, "failed to enable clks\n");
346
+ return ret;
347
+ }
256348 }
257349 }
258350
....@@ -266,7 +358,7 @@
266358 {
267359 struct csi2_dphy *dphy = to_csi2_dphy(sd);
268360 struct v4l2_subdev *sensor_sd = get_remote_sensor(sd);
269
- struct csi2_sensor *sensor = sd_to_sensor(dphy, sensor_sd);
361
+ struct csi2_sensor *sensor;
270362 int ret;
271363 /*
272364 * Do not allow format changes and just relay whatever
....@@ -274,8 +366,11 @@
274366 */
275367 if (!sensor_sd)
276368 return -ENODEV;
369
+ sensor = sd_to_sensor(dphy, sensor_sd);
370
+ if (!sensor)
371
+ return -ENODEV;
277372 ret = v4l2_subdev_call(sensor_sd, pad, get_fmt, NULL, fmt);
278
- if (!ret && fmt->pad == 0)
373
+ if (!ret && fmt->pad == 0 && fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE)
279374 sensor->format = fmt->format;
280375 return ret;
281376 }
....@@ -295,7 +390,6 @@
295390
296391 static const struct v4l2_subdev_video_ops csi2_dphy_video_ops = {
297392 .g_frame_interval = csi2_dphy_g_frame_interval,
298
- .g_mbus_config = csi2_dphy_g_mbus_config,
299393 .s_stream = csi2_dphy_s_stream,
300394 };
301395
....@@ -303,6 +397,7 @@
303397 .set_fmt = csi2_dphy_get_set_fmt,
304398 .get_fmt = csi2_dphy_get_set_fmt,
305399 .get_selection = csi2_dphy_get_selection,
400
+ .get_mbus_config = csi2_dphy_g_mbus_config,
306401 };
307402
308403 static const struct v4l2_subdev_ops csi2_dphy_subdev_ops = {
....@@ -373,7 +468,8 @@
373468 notifier);
374469 struct csi2_sensor *sensor = sd_to_sensor(dphy, sd);
375470
376
- sensor->sd = NULL;
471
+ if (sensor)
472
+ sensor->sd = NULL;
377473 }
378474
379475 static const struct
....@@ -395,10 +491,13 @@
395491 return -EINVAL;
396492 }
397493
398
- if (vep->bus_type == V4L2_MBUS_CSI2) {
399
- config->type = V4L2_MBUS_CSI2;
494
+ if (vep->bus_type == V4L2_MBUS_CSI2_DPHY) {
495
+ config->type = V4L2_MBUS_CSI2_DPHY;
400496 config->flags = vep->bus.mipi_csi2.flags;
401497 s_asd->lanes = vep->bus.mipi_csi2.num_data_lanes;
498
+ } else if (vep->bus_type == V4L2_MBUS_CCP2) {
499
+ config->type = V4L2_MBUS_CCP2;
500
+ s_asd->lanes = vep->bus.mipi_csi1.data_lane;
402501 } else {
403502 dev_err(dev, "Only CSI2 type is currently supported\n");
404503 return -EINVAL;
....@@ -438,15 +537,14 @@
438537 if (ret < 0)
439538 return ret;
440539
540
+ v4l2_async_notifier_init(&dphy->notifier);
541
+
441542 ret = v4l2_async_notifier_parse_fwnode_endpoints_by_port(
442543 dphy->dev, &dphy->notifier,
443544 sizeof(struct sensor_async_subdev), 0,
444545 rockchip_csi2_dphy_fwnode_parse);
445546 if (ret < 0)
446547 return ret;
447
-
448
- if (!dphy->notifier.num_subdevs)
449
- return -ENODEV; /* no endpoint */
450548
451549 dphy->sd.subdev_notifier = &dphy->notifier;
452550 dphy->notifier.ops = &rockchip_csi2_dphy_async_ops;
....@@ -461,6 +559,47 @@
461559 return v4l2_async_register_subdev(&dphy->sd);
462560 }
463561
562
+static int rockchip_csi2_dphy_attach_samsung_phy(struct csi2_dphy *dphy)
563
+{
564
+ struct device *dev = dphy->dev;
565
+ struct phy *dcphy;
566
+ struct samsung_mipi_dcphy *dphy_hw;
567
+ int ret = 0;
568
+
569
+ dcphy = devm_phy_optional_get(dev, "dcphy");
570
+ if (IS_ERR(dcphy)) {
571
+ ret = PTR_ERR(dcphy);
572
+ dev_err(dphy->dev, "failed to get mipi dcphy: %d\n", ret);
573
+ return ret;
574
+ }
575
+
576
+ dphy_hw = phy_get_drvdata(dcphy);
577
+ dphy_hw->dphy_dev[dphy_hw->dphy_dev_num] = dphy;
578
+ dphy_hw->dphy_dev_num++;
579
+ dphy->samsung_phy = dphy_hw;
580
+
581
+ return 0;
582
+}
583
+
584
+static int rockchip_csi2_dphy_detach_samsung_phy(struct csi2_dphy *dphy)
585
+{
586
+ struct samsung_mipi_dcphy *dphy_hw = dphy->samsung_phy;
587
+ struct csi2_dphy *csi2_dphy = NULL;
588
+ int i;
589
+
590
+ for (i = 0; i < dphy_hw->dphy_dev_num; i++) {
591
+ csi2_dphy = dphy_hw->dphy_dev[i];
592
+ if (csi2_dphy &&
593
+ csi2_dphy->phy_index == dphy->phy_index) {
594
+ dphy_hw->dphy_dev[i] = NULL;
595
+ dphy_hw->dphy_dev_num--;
596
+ break;
597
+ }
598
+ }
599
+
600
+ return 0;
601
+}
602
+
464603 static int rockchip_csi2_dphy_attach_hw(struct csi2_dphy *dphy)
465604 {
466605 struct platform_device *plat_dev;
....@@ -470,7 +609,7 @@
470609 enum csi2_dphy_lane_mode target_mode;
471610 int i;
472611
473
- if (dphy->phy_index == 0)
612
+ if (dphy->phy_index % 3 == 0)
474613 target_mode = LANE_MODE_FULL;
475614 else
476615 target_mode = LANE_MODE_SPLIT;
....@@ -547,9 +686,53 @@
547686 return 0;
548687 }
549688
689
+static struct dphy_drv_data rk3568_dphy_drv_data = {
690
+ .dev_name = "csi2dphy",
691
+ .vendor = PHY_VENDOR_INNO,
692
+};
693
+
694
+static struct dphy_drv_data rk3588_dcphy_drv_data = {
695
+ .dev_name = "csi2dcphy",
696
+ .vendor = PHY_VENDOR_SAMSUNG,
697
+};
698
+
699
+static struct rkmodule_csi_dphy_param rk3588_dcphy_param = {
700
+ .vendor = PHY_VENDOR_SAMSUNG,
701
+ .lp_vol_ref = 3,
702
+ .lp_hys_sw = {3, 0, 0, 0},
703
+ .lp_escclk_pol_sel = {1, 0, 0, 0},
704
+ .skew_data_cal_clk = {0, 3, 3, 3},
705
+ .clk_hs_term_sel = 2,
706
+ .data_hs_term_sel = {2, 2, 2, 2},
707
+ .reserved = {0},
708
+};
709
+
710
+static struct dphy_drv_data rv1106_dphy_drv_data = {
711
+ .dev_name = "csi2dphy",
712
+ .vendor = PHY_VENDOR_INNO,
713
+};
714
+
715
+static struct dphy_drv_data rk3562_dphy_drv_data = {
716
+ .dev_name = "csi2dphy",
717
+ .vendor = PHY_VENDOR_INNO,
718
+};
719
+
550720 static const struct of_device_id rockchip_csi2_dphy_match_id[] = {
551721 {
552722 .compatible = "rockchip,rk3568-csi2-dphy",
723
+ .data = &rk3568_dphy_drv_data,
724
+ },
725
+ {
726
+ .compatible = "rockchip,rk3588-csi2-dcphy",
727
+ .data = &rk3588_dcphy_drv_data,
728
+ },
729
+ {
730
+ .compatible = "rockchip,rv1106-csi2-dphy",
731
+ .data = &rv1106_dphy_drv_data,
732
+ },
733
+ {
734
+ .compatible = "rockchip,rk3562-csi2-dphy",
735
+ .data = &rk3562_dphy_drv_data,
553736 },
554737 {}
555738 };
....@@ -561,6 +744,7 @@
561744 const struct of_device_id *of_id;
562745 struct csi2_dphy *csi2dphy;
563746 struct v4l2_subdev *sd;
747
+ const struct dphy_drv_data *drv_data;
564748 int ret;
565749
566750 csi2dphy = devm_kzalloc(dev, sizeof(*csi2dphy), GFP_KERNEL);
....@@ -571,12 +755,17 @@
571755 of_id = of_match_device(rockchip_csi2_dphy_match_id, dev);
572756 if (!of_id)
573757 return -EINVAL;
574
-
575
- csi2dphy->phy_index = of_alias_get_id(dev->of_node, "csi2dphy");
576
- if (csi2dphy->phy_index < 0 || csi2dphy->phy_index > 2)
758
+ drv_data = of_id->data;
759
+ csi2dphy->drv_data = drv_data;
760
+ csi2dphy->phy_index = of_alias_get_id(dev->of_node, drv_data->dev_name);
761
+ if (csi2dphy->phy_index < 0 || csi2dphy->phy_index >= PHY_MAX)
577762 csi2dphy->phy_index = 0;
578
-
579
- ret = rockchip_csi2_dphy_attach_hw(csi2dphy);
763
+ if (csi2dphy->drv_data->vendor == PHY_VENDOR_SAMSUNG) {
764
+ ret = rockchip_csi2_dphy_attach_samsung_phy(csi2dphy);
765
+ csi2dphy->dphy_param = rk3588_dcphy_param;
766
+ } else {
767
+ ret = rockchip_csi2_dphy_attach_hw(csi2dphy);
768
+ }
580769 if (ret) {
581770 dev_err(dev,
582771 "csi2 dphy hw can't be attached, register dphy%d failed!\n",
....@@ -606,7 +795,10 @@
606795
607796 detach_hw:
608797 mutex_destroy(&csi2dphy->mutex);
609
- rockchip_csi2_dphy_detach_hw(csi2dphy);
798
+ if (csi2dphy->drv_data->vendor == PHY_VENDOR_SAMSUNG)
799
+ rockchip_csi2_dphy_detach_samsung_phy(csi2dphy);
800
+ else
801
+ rockchip_csi2_dphy_detach_hw(csi2dphy);
610802
611803 return 0;
612804 }
....@@ -623,42 +815,6 @@
623815 mutex_destroy(&dphy->mutex);
624816 return 0;
625817 }
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
662818
663819 static const struct dev_pm_ops rockchip_csi2_dphy_pm_ops = {
664820 SET_RUNTIME_PM_OPS(csi2_dphy_runtime_suspend,
....@@ -674,7 +830,19 @@
674830 .of_match_table = rockchip_csi2_dphy_match_id,
675831 },
676832 };
677
-EXPORT_SYMBOL(rockchip_csi2_dphy_driver);
833
+
834
+int rockchip_csi2_dphy_init(void)
835
+{
836
+ return platform_driver_register(&rockchip_csi2_dphy_driver);
837
+}
838
+
839
+#if defined(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP) && !defined(CONFIG_INITCALL_ASYNC)
840
+subsys_initcall(rockchip_csi2_dphy_init);
841
+#else
842
+#if !defined(CONFIG_VIDEO_REVERSE_IMAGE)
843
+module_platform_driver(rockchip_csi2_dphy_driver);
844
+#endif
845
+#endif
678846
679847 MODULE_AUTHOR("Rockchip Camera/ISP team");
680848 MODULE_DESCRIPTION("Rockchip MIPI CSI2 DPHY driver");