hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/gpu/drm/bridge/lontium-lt9611.c
....@@ -11,13 +11,14 @@
1111 #include <linux/platform_device.h>
1212 #include <linux/regmap.h>
1313 #include <linux/regulator/consumer.h>
14
-#include <drm/drm_crtc_helper.h>
14
+
1515 #include <sound/hdmi-codec.h>
1616
1717 #include <drm/drm_atomic_helper.h>
1818 #include <drm/drm_bridge.h>
1919 #include <drm/drm_mipi_dsi.h>
2020 #include <drm/drm_print.h>
21
+#include <drm/drm_probe_helper.h>
2122
2223 #define EDID_SEG_SIZE 256
2324 #define EDID_LEN 32
....@@ -46,6 +47,7 @@
4647 struct gpio_desc *enable_gpio;
4748
4849 bool power_on;
50
+ bool sleep;
4951
5052 struct regulator_bulk_data supplies[2];
5153
....@@ -93,8 +95,6 @@
9395 { 1920, 1080, 60, 4, 1 }, /* 1080P 24bit 60Hz 4lane 1port */
9496 { 1920, 1080, 30, 3, 1 }, /* 1080P 24bit 30Hz 3lane 1port */
9597 { 1920, 1080, 24, 3, 1 },
96
- { 1280, 720, 60, 4, 1 },
97
- { 1280, 720, 30, 4, 1 },
9898 { 720, 480, 60, 4, 1 },
9999 { 720, 576, 50, 2, 1 },
100100 { 640, 480, 60, 2, 1 },
....@@ -230,14 +230,8 @@
230230 case 640:
231231 regmap_write(lt9611->regmap, 0x8326, 0x14);
232232 break;
233
- case 1280:
234
- regmap_write(lt9611->regmap, 0x8326, 0x1c);
235
- break;
236233 case 1920:
237
- if (drm_mode_vrefresh(mode) == 30)
238
- regmap_write(lt9611->regmap, 0x8326, 0x1c);
239
- else
240
- regmap_write(lt9611->regmap, 0x8326, 0x37);
234
+ regmap_write(lt9611->regmap, 0x8326, 0x37);
241235 break;
242236 case 3840:
243237 regmap_multi_reg_write(lt9611->regmap, reg_cfg2, ARRAY_SIZE(reg_cfg2));
....@@ -443,6 +437,26 @@
443437 regmap_write(lt9611->regmap, 0x8203, val);
444438 regmap_write(lt9611->regmap, 0x8207, 0xff); /* clear */
445439 regmap_write(lt9611->regmap, 0x8207, 0x3f);
440
+}
441
+
442
+static void lt9611_sleep_setup(struct lt9611 *lt9611)
443
+{
444
+ const struct reg_sequence sleep_setup[] = {
445
+ { 0x8024, 0x76 },
446
+ { 0x8023, 0x01 },
447
+ { 0x8157, 0x03 }, /* set addr pin as output */
448
+ { 0x8149, 0x0b },
449
+ { 0x8151, 0x30 }, /* disable IRQ */
450
+ { 0x8102, 0x48 }, /* MIPI Rx power down */
451
+ { 0x8123, 0x80 },
452
+ { 0x8130, 0x00 },
453
+ { 0x8100, 0x01 }, /* bandgap power down */
454
+ { 0x8101, 0x00 }, /* system clk power down */
455
+ };
456
+
457
+ regmap_multi_reg_write(lt9611->regmap,
458
+ sleep_setup, ARRAY_SIZE(sleep_setup));
459
+ lt9611->sleep = true;
446460 }
447461
448462 static int lt9611_power_on(struct lt9611 *lt9611)
....@@ -762,7 +776,8 @@
762776
763777 dsi->lanes = 4;
764778 dsi->format = MIPI_DSI_FMT_RGB888;
765
- dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST;
779
+ dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
780
+ MIPI_DSI_MODE_VIDEO_HSE;
766781
767782 ret = mipi_dsi_attach(dsi);
768783 if (ret < 0) {
....@@ -801,20 +816,28 @@
801816
802817 drm_connector_helper_add(&lt9611->connector,
803818 &lt9611_bridge_connector_helper_funcs);
804
- drm_connector_attach_encoder(&lt9611->connector, bridge->encoder);
805819
806820 if (!bridge->encoder) {
807821 DRM_ERROR("Parent encoder object not found");
808822 return -ENODEV;
809823 }
810824
825
+ drm_connector_attach_encoder(&lt9611->connector, bridge->encoder);
826
+
811827 return 0;
812828 }
813829
814
-static int lt9611_bridge_attach(struct drm_bridge *bridge)
830
+static int lt9611_bridge_attach(struct drm_bridge *bridge,
831
+ enum drm_bridge_attach_flags flags)
815832 {
816833 struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
817834 int ret;
835
+
836
+ if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) {
837
+ ret = lt9611_connector_init(bridge, lt9611);
838
+ if (ret < 0)
839
+ return ret;
840
+ }
818841
819842 /* Attach primary DSI */
820843 lt9611->dsi0 = lt9611_attach_dsi(lt9611, lt9611->dsi0_node);
....@@ -830,9 +853,7 @@
830853 }
831854 }
832855
833
- ret = lt9611_connector_init(bridge, lt9611);
834
-
835
- return ret;
856
+ return 0;
836857
837858 err_unregister_dsi0:
838859 lt9611_bridge_detach(bridge);
....@@ -843,30 +864,43 @@
843864 }
844865
845866 static enum drm_mode_status lt9611_bridge_mode_valid(struct drm_bridge *bridge,
867
+ const struct drm_display_info *info,
846868 const struct drm_display_mode *mode)
847869 {
848870 struct lt9611_mode *lt9611_mode = lt9611_find_mode(mode);
871
+ struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
849872
850
- return lt9611_mode ? MODE_OK : MODE_BAD;
873
+ if (!lt9611_mode)
874
+ return MODE_BAD;
875
+ else if (lt9611_mode->intfs > 1 && !lt9611->dsi1)
876
+ return MODE_PANEL;
877
+ else
878
+ return MODE_OK;
851879 }
852880
853881 static void lt9611_bridge_pre_enable(struct drm_bridge *bridge)
854882 {
855883 struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
856884
885
+ if (!lt9611->sleep)
886
+ return;
887
+
857888 lt9611_reset(lt9611);
858889 regmap_write(lt9611->regmap, 0x80ee, 0x01);
859
- lt9611_enable_hpd_interrupts(lt9611);
860890
891
+ lt9611->sleep = false;
861892 }
862893
863894 static void lt9611_bridge_post_disable(struct drm_bridge *bridge)
864895 {
896
+ struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
897
+
898
+ lt9611_sleep_setup(lt9611);
865899 }
866900
867901 static void lt9611_bridge_mode_set(struct drm_bridge *bridge,
868
- struct drm_display_mode *mode,
869
- struct drm_display_mode *adj_mode)
902
+ const struct drm_display_mode *mode,
903
+ const struct drm_display_mode *adj_mode)
870904 {
871905 struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
872906 struct hdmi_avi_infoframe avi_frame;
....@@ -879,9 +913,42 @@
879913 lt9611_mipi_video_setup(lt9611, mode);
880914 lt9611_pcr_setup(lt9611, mode);
881915
882
- ret = drm_hdmi_avi_infoframe_from_display_mode(&avi_frame, mode, false);
916
+ ret = drm_hdmi_avi_infoframe_from_display_mode(&avi_frame,
917
+ &lt9611->connector,
918
+ mode);
883919 if (!ret)
884920 lt9611->vic = avi_frame.video_code;
921
+}
922
+
923
+static enum drm_connector_status lt9611_bridge_detect(struct drm_bridge *bridge)
924
+{
925
+ struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
926
+ unsigned int reg_val = 0;
927
+ int connected;
928
+
929
+ regmap_read(lt9611->regmap, 0x825e, &reg_val);
930
+ connected = reg_val & BIT(2);
931
+
932
+ lt9611->status = connected ? connector_status_connected :
933
+ connector_status_disconnected;
934
+
935
+ return lt9611->status;
936
+}
937
+
938
+static struct edid *lt9611_bridge_get_edid(struct drm_bridge *bridge,
939
+ struct drm_connector *connector)
940
+{
941
+ struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
942
+
943
+ lt9611_power_on(lt9611);
944
+ return drm_do_get_edid(connector, lt9611_get_edid_block, lt9611);
945
+}
946
+
947
+static void lt9611_bridge_hpd_enable(struct drm_bridge *bridge)
948
+{
949
+ struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
950
+
951
+ lt9611_enable_hpd_interrupts(lt9611);
885952 }
886953
887954 static const struct drm_bridge_funcs lt9611_bridge_funcs = {
....@@ -892,6 +959,9 @@
892959 .disable = lt9611_bridge_disable,
893960 .post_disable = lt9611_bridge_post_disable,
894961 .mode_set = lt9611_bridge_mode_set,
962
+ .detect = lt9611_bridge_detect,
963
+ .get_edid = lt9611_bridge_get_edid,
964
+ .hpd_enable = lt9611_bridge_hpd_enable,
895965 };
896966
897967 static int lt9611_parse_dt(struct device *dev,
....@@ -1058,6 +1128,7 @@
10581128
10591129 lt9611->dev = &client->dev;
10601130 lt9611->client = client;
1131
+ lt9611->sleep = false;
10611132
10621133 lt9611->regmap = devm_regmap_init_i2c(client, &lt9611_regmap_config);
10631134 if (IS_ERR(lt9611->regmap)) {
....@@ -1095,8 +1166,7 @@
10951166
10961167 ret = devm_request_threaded_irq(dev, client->irq, NULL,
10971168 lt9611_irq_thread_handler,
1098
- IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
1099
- "lt9611", lt9611);
1169
+ IRQF_ONESHOT, "lt9611", lt9611);
11001170 if (ret) {
11011171 dev_err(dev, "failed to request irq\n");
11021172 goto err_disable_regulators;
....@@ -1106,6 +1176,9 @@
11061176
11071177 lt9611->bridge.funcs = &lt9611_bridge_funcs;
11081178 lt9611->bridge.of_node = client->dev.of_node;
1179
+ lt9611->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID |
1180
+ DRM_BRIDGE_OP_HPD | DRM_BRIDGE_OP_MODES;
1181
+ lt9611->bridge.type = DRM_MODE_CONNECTOR_HDMIA;
11091182
11101183 drm_bridge_add(&lt9611->bridge);
11111184