hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/gpu/drm/bridge/tc358768.c
....@@ -9,6 +9,8 @@
99 #include <linux/gpio/consumer.h>
1010 #include <linux/i2c.h>
1111 #include <linux/kernel.h>
12
+#include <linux/media-bus-format.h>
13
+#include <linux/minmax.h>
1214 #include <linux/module.h>
1315 #include <linux/regmap.h>
1416 #include <linux/regulator/consumer.h>
....@@ -147,6 +149,7 @@
147149
148150 u32 pd_lines; /* number of Parallel Port Input Data Lines */
149151 u32 dsi_lanes; /* number of DSI Lanes */
152
+ u32 dsi_bpp; /* number of Bits Per Pixel over DSI */
150153
151154 /* Parameters for PLL programming */
152155 u32 fbd; /* PLL feedback divider */
....@@ -279,12 +282,12 @@
279282
280283 static u32 tc358768_pll_to_pclk(struct tc358768_priv *priv, u32 pll_clk)
281284 {
282
- return (u32)div_u64((u64)pll_clk * priv->dsi_lanes, priv->pd_lines);
285
+ return (u32)div_u64((u64)pll_clk * priv->dsi_lanes, priv->dsi_bpp);
283286 }
284287
285288 static u32 tc358768_pclk_to_pll(struct tc358768_priv *priv, u32 pclk)
286289 {
287
- return (u32)div_u64((u64)pclk * priv->pd_lines, priv->dsi_lanes);
290
+ return (u32)div_u64((u64)pclk * priv->dsi_bpp, priv->dsi_lanes);
288291 }
289292
290293 static int tc358768_calc_pll(struct tc358768_priv *priv,
....@@ -329,11 +332,15 @@
329332 u32 fbd;
330333
331334 for (fbd = 0; fbd < 512; ++fbd) {
332
- u32 pll, diff;
335
+ u32 pll, diff, pll_in;
333336
334337 pll = (u32)div_u64((u64)refclk * (fbd + 1), divisor);
335338
336339 if (pll >= max_pll || pll < min_pll)
340
+ continue;
341
+
342
+ pll_in = (u32)div_u64((u64)refclk, prd + 1);
343
+ if (pll_in < 4000000)
337344 continue;
338345
339346 diff = max(pll, target_pll) - min(pll, target_pll);
....@@ -417,6 +424,7 @@
417424 priv->output.panel = panel;
418425
419426 priv->dsi_lanes = dev->lanes;
427
+ priv->dsi_bpp = mipi_dsi_pixel_format_to_bpp(dev->format);
420428
421429 /* get input ep (port0/endpoint0) */
422430 ret = -EINVAL;
....@@ -428,7 +436,7 @@
428436 }
429437
430438 if (ret)
431
- priv->pd_lines = mipi_dsi_pixel_format_to_bpp(dev->format);
439
+ priv->pd_lines = priv->dsi_bpp;
432440
433441 drm_bridge_add(&priv->bridge);
434442
....@@ -626,6 +634,7 @@
626634 struct tc358768_priv *priv = bridge_to_tc358768(bridge);
627635 struct mipi_dsi_device *dsi_dev = priv->output.dev;
628636 u32 val, val2, lptxcnt, hact, data_type;
637
+ s32 raw_val;
629638 const struct drm_display_mode *mode;
630639 u32 dsibclk_nsk, dsiclk_nsk, ui_nsk, phy_delay_nsk;
631640 u32 dsiclk, dsibclk;
....@@ -719,25 +728,26 @@
719728
720729 /* 38ns < TCLK_PREPARE < 95ns */
721730 val = tc358768_ns_to_cnt(65, dsibclk_nsk) - 1;
722
- /* TCLK_PREPARE > 300ns */
723
- val2 = tc358768_ns_to_cnt(300 + tc358768_to_ns(3 * ui_nsk),
724
- dsibclk_nsk);
725
- val |= (val2 - tc358768_to_ns(phy_delay_nsk - dsibclk_nsk)) << 8;
731
+ /* TCLK_PREPARE + TCLK_ZERO > 300ns */
732
+ val2 = tc358768_ns_to_cnt(300 - tc358768_to_ns(2 * ui_nsk),
733
+ dsibclk_nsk) - 2;
734
+ val |= val2 << 8;
726735 dev_dbg(priv->dev, "TCLK_HEADERCNT: 0x%x\n", val);
727736 tc358768_write(priv, TC358768_TCLK_HEADERCNT, val);
728737
729
- /* TCLK_TRAIL > 60ns + 3*UI */
730
- val = 60 + tc358768_to_ns(3 * ui_nsk);
731
- val = tc358768_ns_to_cnt(val, dsibclk_nsk) - 5;
738
+ /* TCLK_TRAIL > 60ns AND TEOT <= 105 ns + 12*UI */
739
+ raw_val = tc358768_ns_to_cnt(60 + tc358768_to_ns(2 * ui_nsk), dsibclk_nsk) - 5;
740
+ val = clamp(raw_val, 0, 127);
732741 dev_dbg(priv->dev, "TCLK_TRAILCNT: 0x%x\n", val);
733742 tc358768_write(priv, TC358768_TCLK_TRAILCNT, val);
734743
735744 /* 40ns + 4*UI < THS_PREPARE < 85ns + 6*UI */
736745 val = 50 + tc358768_to_ns(4 * ui_nsk);
737746 val = tc358768_ns_to_cnt(val, dsibclk_nsk) - 1;
738
- /* THS_ZERO > 145ns + 10*UI */
739
- val2 = tc358768_ns_to_cnt(145 - tc358768_to_ns(ui_nsk), dsibclk_nsk);
740
- val |= (val2 - tc358768_to_ns(phy_delay_nsk)) << 8;
747
+ /* THS_PREPARE + THS_ZERO > 145ns + 10*UI */
748
+ raw_val = tc358768_ns_to_cnt(145 - tc358768_to_ns(3 * ui_nsk), dsibclk_nsk) - 10;
749
+ val2 = clamp(raw_val, 0, 127);
750
+ val |= val2 << 8;
741751 dev_dbg(priv->dev, "THS_HEADERCNT: 0x%x\n", val);
742752 tc358768_write(priv, TC358768_THS_HEADERCNT, val);
743753
....@@ -753,9 +763,10 @@
753763 dev_dbg(priv->dev, "TCLK_POSTCNT: 0x%x\n", val);
754764 tc358768_write(priv, TC358768_TCLK_POSTCNT, val);
755765
756
- /* 60ns + 4*UI < THS_PREPARE < 105ns + 12*UI */
757
- val = tc358768_ns_to_cnt(60 + tc358768_to_ns(15 * ui_nsk),
758
- dsibclk_nsk) - 5;
766
+ /* max(60ns + 4*UI, 8*UI) < THS_TRAILCNT < 105ns + 12*UI */
767
+ raw_val = tc358768_ns_to_cnt(60 + tc358768_to_ns(18 * ui_nsk),
768
+ dsibclk_nsk) - 4;
769
+ val = clamp(raw_val, 0, 15);
759770 dev_dbg(priv->dev, "THS_TRAILCNT: 0x%x\n", val);
760771 tc358768_write(priv, TC358768_THS_TRAILCNT, val);
761772
....@@ -769,7 +780,7 @@
769780
770781 /* TXTAGOCNT[26:16] RXTASURECNT[10:0] */
771782 val = tc358768_to_ns((lptxcnt + 1) * dsibclk_nsk * 4);
772
- val = tc358768_ns_to_cnt(val, dsibclk_nsk) - 1;
783
+ val = tc358768_ns_to_cnt(val, dsibclk_nsk) / 4 - 1;
773784 val2 = tc358768_ns_to_cnt(tc358768_to_ns((lptxcnt + 1) * dsibclk_nsk),
774785 dsibclk_nsk) - 2;
775786 val |= val2 << 16;
....@@ -819,8 +830,7 @@
819830 val = TC358768_DSI_CONFW_MODE_SET | TC358768_DSI_CONFW_ADDR_DSI_CONTROL;
820831 val |= (dsi_dev->lanes - 1) << 1;
821832
822
- if (!(dsi_dev->mode_flags & MIPI_DSI_MODE_LPM))
823
- val |= TC358768_DSI_CONTROL_TXMD;
833
+ val |= TC358768_DSI_CONTROL_TXMD;
824834
825835 if (!(dsi_dev->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS))
826836 val |= TC358768_DSI_CONTROL_HSCKMD;
....@@ -866,6 +876,44 @@
866876 }
867877 }
868878
879
+#define MAX_INPUT_SEL_FORMATS 1
880
+
881
+static u32 *
882
+tc358768_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
883
+ struct drm_bridge_state *bridge_state,
884
+ struct drm_crtc_state *crtc_state,
885
+ struct drm_connector_state *conn_state,
886
+ u32 output_fmt,
887
+ unsigned int *num_input_fmts)
888
+{
889
+ struct tc358768_priv *priv = bridge_to_tc358768(bridge);
890
+ u32 *input_fmts;
891
+
892
+ *num_input_fmts = 0;
893
+
894
+ input_fmts = kcalloc(MAX_INPUT_SEL_FORMATS, sizeof(*input_fmts),
895
+ GFP_KERNEL);
896
+ if (!input_fmts)
897
+ return NULL;
898
+
899
+ switch (priv->pd_lines) {
900
+ case 16:
901
+ input_fmts[0] = MEDIA_BUS_FMT_RGB565_1X16;
902
+ break;
903
+ case 18:
904
+ input_fmts[0] = MEDIA_BUS_FMT_RGB666_1X18;
905
+ break;
906
+ default:
907
+ case 24:
908
+ input_fmts[0] = MEDIA_BUS_FMT_RGB888_1X24;
909
+ break;
910
+ };
911
+
912
+ *num_input_fmts = MAX_INPUT_SEL_FORMATS;
913
+
914
+ return input_fmts;
915
+}
916
+
869917 static const struct drm_bridge_funcs tc358768_bridge_funcs = {
870918 .attach = tc358768_bridge_attach,
871919 .mode_valid = tc358768_bridge_mode_valid,
....@@ -873,6 +921,11 @@
873921 .enable = tc358768_bridge_enable,
874922 .disable = tc358768_bridge_disable,
875923 .post_disable = tc358768_bridge_post_disable,
924
+
925
+ .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
926
+ .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
927
+ .atomic_reset = drm_atomic_helper_bridge_reset,
928
+ .atomic_get_input_bus_fmts = tc358768_atomic_get_input_bus_fmts,
876929 };
877930
878931 static const struct drm_bridge_timings default_tc358768_timings = {