[PATCH v4 11/12] drm/bridge: tc358768: Fix tc358768_ns_to_cnt()

2023-09-05 Thread Tomi Valkeinen
The tc358768_ns_to_cnt() is, most likely, supposed to do a div-round-up
operation, but it misses subtracting one from the dividend.

Fix this by just using DIV_ROUND_UP().

Fixes: ff1ca6397b1d ("drm/bridge: Add tc358768 driver")
Reviewed-by: Peter Ujfalusi 
Tested-by: Maxim Schwalm  # Asus TF700T
Tested-by: Marcel Ziswiler 
Signed-off-by: Tomi Valkeinen 
---
 drivers/gpu/drm/bridge/tc358768.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/tc358768.c 
b/drivers/gpu/drm/bridge/tc358768.c
index 9ce8d120b50c..f41bf56b7d6b 100644
--- a/drivers/gpu/drm/bridge/tc358768.c
+++ b/drivers/gpu/drm/bridge/tc358768.c
@@ -630,7 +630,7 @@ static int tc358768_setup_pll(struct tc358768_priv *priv,
 
 static u32 tc358768_ns_to_cnt(u32 ns, u32 period_ps)
 {
-   return (ns * 1000 + period_ps) / period_ps;
+   return DIV_ROUND_UP(ns * 1000, period_ps);
 }
 
 static u32 tc358768_ps_to_ns(u32 ps)

-- 
2.34.1



[PATCH v4 07/12] drm/bridge: tc358768: Print logical values, not raw register values

2023-09-05 Thread Tomi Valkeinen
The driver debug prints DSI related timings as raw register values in
hex. It is much more useful to see the "logical" value of the timing,
not the register value.

Change the prints to print the values separately, in case a single
register contains multiple values, and use %u to have it in a more human
consumable form.

Reviewed-by: Peter Ujfalusi 
Tested-by: Maxim Schwalm  # Asus TF700T
Tested-by: Marcel Ziswiler 
Signed-off-by: Tomi Valkeinen 
---
 drivers/gpu/drm/bridge/tc358768.c | 21 -
 1 file changed, 12 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/bridge/tc358768.c 
b/drivers/gpu/drm/bridge/tc358768.c
index b98c517c4726..88060f961064 100644
--- a/drivers/gpu/drm/bridge/tc358768.c
+++ b/drivers/gpu/drm/bridge/tc358768.c
@@ -739,57 +739,59 @@ static void tc358768_bridge_pre_enable(struct drm_bridge 
*bridge)
 
/* LP11 > 100us for D-PHY Rx Init */
val = tc358768_ns_to_cnt(100 * 1000, dsibclk_nsk) - 1;
-   dev_dbg(priv->dev, "LINEINITCNT: 0x%x\n", val);
+   dev_dbg(priv->dev, "LINEINITCNT: %u\n", val);
tc358768_write(priv, TC358768_LINEINITCNT, val);
 
/* LPTimeCnt > 50ns */
val = tc358768_ns_to_cnt(50, dsibclk_nsk) - 1;
lptxcnt = val;
-   dev_dbg(priv->dev, "LPTXTIMECNT: 0x%x\n", val);
+   dev_dbg(priv->dev, "LPTXTIMECNT: %u\n", val);
tc358768_write(priv, TC358768_LPTXTIMECNT, val);
 
/* 38ns < TCLK_PREPARE < 95ns */
val = tc358768_ns_to_cnt(65, dsibclk_nsk) - 1;
+   dev_dbg(priv->dev, "TCLK_PREPARECNT %u\n", val);
/* TCLK_PREPARE + TCLK_ZERO > 300ns */
val2 = tc358768_ns_to_cnt(300 - tc358768_to_ns(2 * ui_nsk),
  dsibclk_nsk) - 2;
+   dev_dbg(priv->dev, "TCLK_ZEROCNT %u\n", val2);
val |= val2 << 8;
-   dev_dbg(priv->dev, "TCLK_HEADERCNT: 0x%x\n", val);
tc358768_write(priv, TC358768_TCLK_HEADERCNT, val);
 
/* TCLK_TRAIL > 60ns AND TEOT <= 105 ns + 12*UI */
raw_val = tc358768_ns_to_cnt(60 + tc358768_to_ns(2 * ui_nsk), 
dsibclk_nsk) - 5;
val = clamp(raw_val, 0, 127);
-   dev_dbg(priv->dev, "TCLK_TRAILCNT: 0x%x\n", val);
+   dev_dbg(priv->dev, "TCLK_TRAILCNT: %u\n", val);
tc358768_write(priv, TC358768_TCLK_TRAILCNT, val);
 
/* 40ns + 4*UI < THS_PREPARE < 85ns + 6*UI */
val = 50 + tc358768_to_ns(4 * ui_nsk);
val = tc358768_ns_to_cnt(val, dsibclk_nsk) - 1;
+   dev_dbg(priv->dev, "THS_PREPARECNT %u\n", val);
/* THS_PREPARE + THS_ZERO > 145ns + 10*UI */
raw_val = tc358768_ns_to_cnt(145 - tc358768_to_ns(3 * ui_nsk), 
dsibclk_nsk) - 10;
val2 = clamp(raw_val, 0, 127);
+   dev_dbg(priv->dev, "THS_ZEROCNT %u\n", val2);
val |= val2 << 8;
-   dev_dbg(priv->dev, "THS_HEADERCNT: 0x%x\n", val);
tc358768_write(priv, TC358768_THS_HEADERCNT, val);
 
/* TWAKEUP > 1ms in lptxcnt steps */
val = tc358768_ns_to_cnt(102, dsibclk_nsk);
val = val / (lptxcnt + 1) - 1;
-   dev_dbg(priv->dev, "TWAKEUP: 0x%x\n", val);
+   dev_dbg(priv->dev, "TWAKEUP: %u\n", val);
tc358768_write(priv, TC358768_TWAKEUP, val);
 
/* TCLK_POSTCNT > 60ns + 52*UI */
val = tc358768_ns_to_cnt(60 + tc358768_to_ns(52 * ui_nsk),
 dsibclk_nsk) - 3;
-   dev_dbg(priv->dev, "TCLK_POSTCNT: 0x%x\n", val);
+   dev_dbg(priv->dev, "TCLK_POSTCNT: %u\n", val);
tc358768_write(priv, TC358768_TCLK_POSTCNT, val);
 
/* max(60ns + 4*UI, 8*UI) < THS_TRAILCNT < 105ns + 12*UI */
raw_val = tc358768_ns_to_cnt(60 + tc358768_to_ns(18 * ui_nsk),
 dsibclk_nsk) - 4;
val = clamp(raw_val, 0, 15);
-   dev_dbg(priv->dev, "THS_TRAILCNT: 0x%x\n", val);
+   dev_dbg(priv->dev, "THS_TRAILCNT: %u\n", val);
tc358768_write(priv, TC358768_THS_TRAILCNT, val);
 
val = BIT(0);
@@ -803,10 +805,11 @@ static void tc358768_bridge_pre_enable(struct drm_bridge 
*bridge)
/* TXTAGOCNT[26:16] RXTASURECNT[10:0] */
val = tc358768_to_ns((lptxcnt + 1) * dsibclk_nsk * 4);
val = tc358768_ns_to_cnt(val, dsibclk_nsk) / 4 - 1;
+   dev_dbg(priv->dev, "TXTAGOCNT: %u\n", val);
val2 = tc358768_ns_to_cnt(tc358768_to_ns((lptxcnt + 1) * dsibclk_nsk),
  dsibclk_nsk) - 2;
+   dev_dbg(priv->dev, "RXTASURECNT: %u\n", val2);
val = val << 16 | val2;
-   dev_dbg(priv->dev, "BTACNTRL1: 0x%x\n", val);
tc358768_write(priv, TC358768_BTACNTRL1, val);
 
/* START[0] */

-- 
2.34.1



[PATCH v4 09/12] drm/bridge: tc358768: Rename dsibclk to hsbyteclk

2023-09-05 Thread Tomi Valkeinen
The Toshiba documentation talks about HSByteClk when referring to the
DSI HS byte clock, whereas the driver uses 'dsibclk' name. Also, in a
few places the driver calculates the byte clock from the DSI clock, even
if the byte clock is already available in a variable.

To align the driver with the documentation, change the 'dsibclk'
variable to 'hsbyteclk'. This also make it easier to visually separate
'dsibclk' and 'dsiclk' variables.

Reviewed-by: Peter Ujfalusi 
Tested-by: Maxim Schwalm  # Asus TF700T
Tested-by: Marcel Ziswiler 
Signed-off-by: Tomi Valkeinen 
---
 drivers/gpu/drm/bridge/tc358768.c | 48 +++
 1 file changed, 24 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/bridge/tc358768.c 
b/drivers/gpu/drm/bridge/tc358768.c
index 6297d28250e9..0f117d673b14 100644
--- a/drivers/gpu/drm/bridge/tc358768.c
+++ b/drivers/gpu/drm/bridge/tc358768.c
@@ -604,7 +604,7 @@ static int tc358768_setup_pll(struct tc358768_priv *priv,
 
dev_dbg(priv->dev, "PLL: refclk %lu, fbd %u, prd %u, frs %u\n",
clk_get_rate(priv->refclk), fbd, prd, frs);
-   dev_dbg(priv->dev, "PLL: pll_clk: %u, DSIClk %u, DSIByteClk %u\n",
+   dev_dbg(priv->dev, "PLL: pll_clk: %u, DSIClk %u, HSByteClk %u\n",
priv->dsiclk * 2, priv->dsiclk, priv->dsiclk / 4);
dev_dbg(priv->dev, "PLL: pclk %u (panel: %u)\n",
tc358768_pll_to_pclk(priv, priv->dsiclk * 2),
@@ -646,8 +646,8 @@ static void tc358768_bridge_pre_enable(struct drm_bridge 
*bridge)
u32 val, val2, lptxcnt, hact, data_type;
s32 raw_val;
const struct drm_display_mode *mode;
-   u32 dsibclk_nsk, dsiclk_nsk, ui_nsk;
-   u32 dsiclk, dsibclk, video_start;
+   u32 hsbyteclk_nsk, dsiclk_nsk, ui_nsk;
+   u32 dsiclk, hsbyteclk, video_start;
const u32 internal_delay = 40;
int ret, i;
struct videomode vm;
@@ -678,7 +678,7 @@ static void tc358768_bridge_pre_enable(struct drm_bridge 
*bridge)
drm_display_mode_to_videomode(mode, &vm);
 
dsiclk = priv->dsiclk;
-   dsibclk = dsiclk / 4;
+   hsbyteclk = dsiclk / 4;
 
/* Data Format Control Register */
val = BIT(2) | BIT(1) | BIT(0); /* rdswap_en | dsitx_en | txdt_en */
@@ -730,67 +730,67 @@ static void tc358768_bridge_pre_enable(struct drm_bridge 
*bridge)
tc358768_write(priv, TC358768_D0W_CNTRL + i * 4, 0x);
 
/* DSI Timings */
-   dsibclk_nsk = (u32)div_u64((u64)10 * TC358768_PRECISION,
- dsibclk);
+   hsbyteclk_nsk = (u32)div_u64((u64)10 * TC358768_PRECISION,
+ hsbyteclk);
dsiclk_nsk = (u32)div_u64((u64)10 * TC358768_PRECISION, dsiclk);
ui_nsk = dsiclk_nsk / 2;
dev_dbg(dev, "dsiclk_nsk: %u\n", dsiclk_nsk);
dev_dbg(dev, "ui_nsk: %u\n", ui_nsk);
-   dev_dbg(dev, "dsibclk_nsk: %u\n", dsibclk_nsk);
+   dev_dbg(dev, "hsbyteclk_nsk: %u\n", hsbyteclk_nsk);
 
/* LP11 > 100us for D-PHY Rx Init */
-   val = tc358768_ns_to_cnt(100 * 1000, dsibclk_nsk) - 1;
+   val = tc358768_ns_to_cnt(100 * 1000, hsbyteclk_nsk) - 1;
dev_dbg(dev, "LINEINITCNT: %u\n", val);
tc358768_write(priv, TC358768_LINEINITCNT, val);
 
/* LPTimeCnt > 50ns */
-   val = tc358768_ns_to_cnt(50, dsibclk_nsk) - 1;
+   val = tc358768_ns_to_cnt(50, hsbyteclk_nsk) - 1;
lptxcnt = val;
dev_dbg(dev, "LPTXTIMECNT: %u\n", val);
tc358768_write(priv, TC358768_LPTXTIMECNT, val);
 
/* 38ns < TCLK_PREPARE < 95ns */
-   val = tc358768_ns_to_cnt(65, dsibclk_nsk) - 1;
+   val = tc358768_ns_to_cnt(65, hsbyteclk_nsk) - 1;
dev_dbg(dev, "TCLK_PREPARECNT %u\n", val);
/* TCLK_PREPARE + TCLK_ZERO > 300ns */
val2 = tc358768_ns_to_cnt(300 - tc358768_to_ns(2 * ui_nsk),
- dsibclk_nsk) - 2;
+ hsbyteclk_nsk) - 2;
dev_dbg(dev, "TCLK_ZEROCNT %u\n", val2);
val |= val2 << 8;
tc358768_write(priv, TC358768_TCLK_HEADERCNT, val);
 
/* TCLK_TRAIL > 60ns AND TEOT <= 105 ns + 12*UI */
-   raw_val = tc358768_ns_to_cnt(60 + tc358768_to_ns(2 * ui_nsk), 
dsibclk_nsk) - 5;
+   raw_val = tc358768_ns_to_cnt(60 + tc358768_to_ns(2 * ui_nsk), 
hsbyteclk_nsk) - 5;
val = clamp(raw_val, 0, 127);
dev_dbg(dev, "TCLK_TRAILCNT: %u\n", val);
tc358768_write(priv, TC358768_TCLK_TRAILCNT, val);
 
/* 40ns + 4*UI < THS_PREPARE < 85ns + 6*UI */
val = 50 + tc358768_to_ns(4 * ui_nsk);
-   val = tc358768_ns_to_cnt(val, dsibclk_nsk) - 1;
+   val = tc358768_ns_to_cnt(val, hsbyteclk_nsk) - 1;
dev_dbg(dev, "THS_PREPARECNT %u\n", val);
/* THS_PREPARE + THS_ZERO > 145ns + 10*UI */
-   raw_val = tc358768_ns_to_cnt(145 - tc358768_to_ns(3 * ui_nsk), 
dsibclk_nsk) - 10;
+   raw_val = tc358768_ns_to_cnt(145 - tc35876

[PATCH v4 10/12] drm/bridge: tc358768: Clean up clock period code

2023-09-05 Thread Tomi Valkeinen
The driver defines TC358768_PRECISION as 1000, and uses "nsk" to refer
to clock periods. The original author does not remember where all this
came from. Effectively the driver is using picoseconds as the unit for
clock periods, yet referring to them by "nsk".

Clean this up by just saying the periods are in picoseconds.

Reviewed-by: Peter Ujfalusi 
Tested-by: Maxim Schwalm  # Asus TF700T
Tested-by: Marcel Ziswiler 
Signed-off-by: Tomi Valkeinen 
---
 drivers/gpu/drm/bridge/tc358768.c | 60 +++
 1 file changed, 29 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/bridge/tc358768.c 
b/drivers/gpu/drm/bridge/tc358768.c
index 0f117d673b14..9ce8d120b50c 100644
--- a/drivers/gpu/drm/bridge/tc358768.c
+++ b/drivers/gpu/drm/bridge/tc358768.c
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -627,15 +628,14 @@ static int tc358768_setup_pll(struct tc358768_priv *priv,
return tc358768_clear_error(priv);
 }
 
-#define TC358768_PRECISION 1000
-static u32 tc358768_ns_to_cnt(u32 ns, u32 period_nsk)
+static u32 tc358768_ns_to_cnt(u32 ns, u32 period_ps)
 {
-   return (ns * TC358768_PRECISION + period_nsk) / period_nsk;
+   return (ns * 1000 + period_ps) / period_ps;
 }
 
-static u32 tc358768_to_ns(u32 nsk)
+static u32 tc358768_ps_to_ns(u32 ps)
 {
-   return (nsk / TC358768_PRECISION);
+   return ps / 1000;
 }
 
 static void tc358768_bridge_pre_enable(struct drm_bridge *bridge)
@@ -646,7 +646,7 @@ static void tc358768_bridge_pre_enable(struct drm_bridge 
*bridge)
u32 val, val2, lptxcnt, hact, data_type;
s32 raw_val;
const struct drm_display_mode *mode;
-   u32 hsbyteclk_nsk, dsiclk_nsk, ui_nsk;
+   u32 hsbyteclk_ps, dsiclk_ps, ui_ps;
u32 dsiclk, hsbyteclk, video_start;
const u32 internal_delay = 40;
int ret, i;
@@ -730,67 +730,65 @@ static void tc358768_bridge_pre_enable(struct drm_bridge 
*bridge)
tc358768_write(priv, TC358768_D0W_CNTRL + i * 4, 0x);
 
/* DSI Timings */
-   hsbyteclk_nsk = (u32)div_u64((u64)10 * TC358768_PRECISION,
- hsbyteclk);
-   dsiclk_nsk = (u32)div_u64((u64)10 * TC358768_PRECISION, dsiclk);
-   ui_nsk = dsiclk_nsk / 2;
-   dev_dbg(dev, "dsiclk_nsk: %u\n", dsiclk_nsk);
-   dev_dbg(dev, "ui_nsk: %u\n", ui_nsk);
-   dev_dbg(dev, "hsbyteclk_nsk: %u\n", hsbyteclk_nsk);
+   hsbyteclk_ps = (u32)div_u64(PICO, hsbyteclk);
+   dsiclk_ps = (u32)div_u64(PICO, dsiclk);
+   ui_ps = dsiclk_ps / 2;
+   dev_dbg(dev, "dsiclk: %u ps, ui %u ps, hsbyteclk %u ps\n", dsiclk_ps,
+   ui_ps, hsbyteclk_ps);
 
/* LP11 > 100us for D-PHY Rx Init */
-   val = tc358768_ns_to_cnt(100 * 1000, hsbyteclk_nsk) - 1;
+   val = tc358768_ns_to_cnt(100 * 1000, hsbyteclk_ps) - 1;
dev_dbg(dev, "LINEINITCNT: %u\n", val);
tc358768_write(priv, TC358768_LINEINITCNT, val);
 
/* LPTimeCnt > 50ns */
-   val = tc358768_ns_to_cnt(50, hsbyteclk_nsk) - 1;
+   val = tc358768_ns_to_cnt(50, hsbyteclk_ps) - 1;
lptxcnt = val;
dev_dbg(dev, "LPTXTIMECNT: %u\n", val);
tc358768_write(priv, TC358768_LPTXTIMECNT, val);
 
/* 38ns < TCLK_PREPARE < 95ns */
-   val = tc358768_ns_to_cnt(65, hsbyteclk_nsk) - 1;
+   val = tc358768_ns_to_cnt(65, hsbyteclk_ps) - 1;
dev_dbg(dev, "TCLK_PREPARECNT %u\n", val);
/* TCLK_PREPARE + TCLK_ZERO > 300ns */
-   val2 = tc358768_ns_to_cnt(300 - tc358768_to_ns(2 * ui_nsk),
- hsbyteclk_nsk) - 2;
+   val2 = tc358768_ns_to_cnt(300 - tc358768_ps_to_ns(2 * ui_ps),
+ hsbyteclk_ps) - 2;
dev_dbg(dev, "TCLK_ZEROCNT %u\n", val2);
val |= val2 << 8;
tc358768_write(priv, TC358768_TCLK_HEADERCNT, val);
 
/* TCLK_TRAIL > 60ns AND TEOT <= 105 ns + 12*UI */
-   raw_val = tc358768_ns_to_cnt(60 + tc358768_to_ns(2 * ui_nsk), 
hsbyteclk_nsk) - 5;
+   raw_val = tc358768_ns_to_cnt(60 + tc358768_ps_to_ns(2 * ui_ps), 
hsbyteclk_ps) - 5;
val = clamp(raw_val, 0, 127);
dev_dbg(dev, "TCLK_TRAILCNT: %u\n", val);
tc358768_write(priv, TC358768_TCLK_TRAILCNT, val);
 
/* 40ns + 4*UI < THS_PREPARE < 85ns + 6*UI */
-   val = 50 + tc358768_to_ns(4 * ui_nsk);
-   val = tc358768_ns_to_cnt(val, hsbyteclk_nsk) - 1;
+   val = 50 + tc358768_ps_to_ns(4 * ui_ps);
+   val = tc358768_ns_to_cnt(val, hsbyteclk_ps) - 1;
dev_dbg(dev, "THS_PREPARECNT %u\n", val);
/* THS_PREPARE + THS_ZERO > 145ns + 10*UI */
-   raw_val = tc358768_ns_to_cnt(145 - tc358768_to_ns(3 * ui_nsk), 
hsbyteclk_nsk) - 10;
+   raw_val = tc358768_ns_to_cnt(145 - tc358768_ps_to_ns(3 * ui_ps), 
hsbyteclk_ps) - 10;
val2 = clamp(raw_val, 0, 127);
dev_dbg(dev, "THS_ZEROCNT %u\n", val2);
val |= val2 << 8;
tc358768_writ

[PATCH v4 12/12] drm/bridge: tc358768: Attempt to fix DSI horizontal timings

2023-09-05 Thread Tomi Valkeinen
The DSI horizontal timing calculations done by the driver seem to often
lead to underflows or overflows, depending on the videomode.

There are two main things the current driver doesn't seem to get right:
DSI HSW and HFP, and VSDly. However, even following Toshiba's
documentation it seems we don't always get a working display.

This patch attempts to fix the horizontal timings for DSI event mode, and
on a system with a DSI->HDMI encoder, a lot of standard HDMI modes now
seem to work. The work relies on Toshiba's documentation, but also quite
a bit on empirical testing.

This also adds timing related debug prints to make it easier to improve
on this later.

The DSI pulse mode has only been tested with a fixed-resolution panel,
which limits the testing of different modes on DSI pulse mode. However,
as the VSDly calculation also affects pulse mode, so this might cause a
regression.

Reviewed-by: Peter Ujfalusi 
Tested-by: Marcel Ziswiler 
Tested-by: Maxim Schwalm  # Asus TF700T
Signed-off-by: Tomi Valkeinen 
---
 drivers/gpu/drm/bridge/tc358768.c | 211 +-
 1 file changed, 183 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/bridge/tc358768.c 
b/drivers/gpu/drm/bridge/tc358768.c
index f41bf56b7d6b..e5ecf1a79e82 100644
--- a/drivers/gpu/drm/bridge/tc358768.c
+++ b/drivers/gpu/drm/bridge/tc358768.c
@@ -9,6 +9,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -157,6 +158,7 @@ struct tc358768_priv {
u32 frs;/* PLL Freqency range for HSCK (post divider) */
 
u32 dsiclk; /* pll_clk / 2 */
+   u32 pclk;   /* incoming pclk rate */
 };
 
 static inline struct tc358768_priv *dsi_host_to_tc358768(struct mipi_dsi_host
@@ -380,6 +382,7 @@ static int tc358768_calc_pll(struct tc358768_priv *priv,
priv->prd = best_prd;
priv->frs = frs;
priv->dsiclk = best_pll / 2;
+   priv->pclk = mode->clock * 1000;
 
return 0;
 }
@@ -638,6 +641,28 @@ static u32 tc358768_ps_to_ns(u32 ps)
return ps / 1000;
 }
 
+static u32 tc358768_dpi_to_ns(u32 val, u32 pclk)
+{
+   return (u32)div_u64((u64)val * NANO, pclk);
+}
+
+/* Convert value in DPI pixel clock units to DSI byte count */
+static u32 tc358768_dpi_to_dsi_bytes(struct tc358768_priv *priv, u32 val)
+{
+   u64 m = (u64)val * priv->dsiclk / 4 * priv->dsi_lanes;
+   u64 n = priv->pclk;
+
+   return (u32)div_u64(m + n - 1, n);
+}
+
+static u32 tc358768_dsi_bytes_to_ns(struct tc358768_priv *priv, u32 val)
+{
+   u64 m = (u64)val * NANO;
+   u64 n = priv->dsiclk / 4 * priv->dsi_lanes;
+
+   return (u32)div_u64(m, n);
+}
+
 static void tc358768_bridge_pre_enable(struct drm_bridge *bridge)
 {
struct tc358768_priv *priv = bridge_to_tc358768(bridge);
@@ -647,11 +672,19 @@ static void tc358768_bridge_pre_enable(struct drm_bridge 
*bridge)
s32 raw_val;
const struct drm_display_mode *mode;
u32 hsbyteclk_ps, dsiclk_ps, ui_ps;
-   u32 dsiclk, hsbyteclk, video_start;
-   const u32 internal_delay = 40;
+   u32 dsiclk, hsbyteclk;
int ret, i;
struct videomode vm;
struct device *dev = priv->dev;
+   /* In pixelclock units */
+   u32 dpi_htot, dpi_data_start;
+   /* In byte units */
+   u32 dsi_dpi_htot, dsi_dpi_data_start;
+   u32 dsi_hsw, dsi_hbp, dsi_hact, dsi_hfp;
+   const u32 dsi_hss = 4; /* HSS is a short packet (4 bytes) */
+   /* In hsbyteclk units */
+   u32 dsi_vsdly;
+   const u32 internal_dly = 40;
 
if (mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) {
dev_warn_once(dev, "Non-continuous mode unimplemented, falling 
back to continuous\n");
@@ -686,27 +719,23 @@ static void tc358768_bridge_pre_enable(struct drm_bridge 
*bridge)
case MIPI_DSI_FMT_RGB888:
val |= (0x3 << 4);
hact = vm.hactive * 3;
-   video_start = (vm.hsync_len + vm.hback_porch) * 3;
data_type = MIPI_DSI_PACKED_PIXEL_STREAM_24;
break;
case MIPI_DSI_FMT_RGB666:
val |= (0x4 << 4);
hact = vm.hactive * 3;
-   video_start = (vm.hsync_len + vm.hback_porch) * 3;
data_type = MIPI_DSI_PACKED_PIXEL_STREAM_18;
break;
 
case MIPI_DSI_FMT_RGB666_PACKED:
val |= (0x4 << 4) | BIT(3);
hact = vm.hactive * 18 / 8;
-   video_start = (vm.hsync_len + vm.hback_porch) * 18 / 8;
data_type = MIPI_DSI_PIXEL_STREAM_3BYTE_18;
break;
 
case MIPI_DSI_FMT_RGB565:
val |= (0x5 << 4);
hact = vm.hactive * 2;
-   video_start = (vm.hsync_len + vm.hback_porch) * 2;
data_type = MIPI_DSI_PACKED_PIXEL_STREAM_16;
break;
default:
@@ -716,9 +745,150 @@ static void tc358768_bridge_pre_enable(struct drm_bridge 
*bridge)

[PATCH v4 06/12] drm/bridge: tc358768: Use struct videomode

2023-09-05 Thread Tomi Valkeinen
The TC358768 documentation uses HFP, HBP, etc. values to deal with the
video mode, while the driver currently uses the DRM display mode
(htotal, hsync_start, etc).

Change the driver to convert the DRM display mode to struct videomode,
which then allows us to use the same units the documentation uses. This
makes it much easier to work on the code when using the TC358768
documentation as a reference.

Reviewed-by: Peter Ujfalusi 
Tested-by: Maxim Schwalm  # Asus TF700T
Tested-by: Marcel Ziswiler 
Signed-off-by: Tomi Valkeinen 
---
 drivers/gpu/drm/bridge/tc358768.c | 45 +--
 1 file changed, 24 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/bridge/tc358768.c 
b/drivers/gpu/drm/bridge/tc358768.c
index a465674f1e2e..b98c517c4726 100644
--- a/drivers/gpu/drm/bridge/tc358768.c
+++ b/drivers/gpu/drm/bridge/tc358768.c
@@ -650,6 +650,7 @@ static void tc358768_bridge_pre_enable(struct drm_bridge 
*bridge)
u32 dsiclk, dsibclk, video_start;
const u32 internal_delay = 40;
int ret, i;
+   struct videomode vm;
 
if (mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) {
dev_warn_once(priv->dev, "Non-continuous mode unimplemented, 
falling back to continuous\n");
@@ -673,6 +674,8 @@ static void tc358768_bridge_pre_enable(struct drm_bridge 
*bridge)
return;
}
 
+   drm_display_mode_to_videomode(mode, &vm);
+
dsiclk = priv->dsiclk;
dsibclk = dsiclk / 4;
 
@@ -681,28 +684,28 @@ static void tc358768_bridge_pre_enable(struct drm_bridge 
*bridge)
switch (dsi_dev->format) {
case MIPI_DSI_FMT_RGB888:
val |= (0x3 << 4);
-   hact = mode->hdisplay * 3;
-   video_start = (mode->htotal - mode->hsync_start) * 3;
+   hact = vm.hactive * 3;
+   video_start = (vm.hsync_len + vm.hback_porch) * 3;
data_type = MIPI_DSI_PACKED_PIXEL_STREAM_24;
break;
case MIPI_DSI_FMT_RGB666:
val |= (0x4 << 4);
-   hact = mode->hdisplay * 3;
-   video_start = (mode->htotal - mode->hsync_start) * 3;
+   hact = vm.hactive * 3;
+   video_start = (vm.hsync_len + vm.hback_porch) * 3;
data_type = MIPI_DSI_PACKED_PIXEL_STREAM_18;
break;
 
case MIPI_DSI_FMT_RGB666_PACKED:
val |= (0x4 << 4) | BIT(3);
-   hact = mode->hdisplay * 18 / 8;
-   video_start = (mode->htotal - mode->hsync_start) * 18 / 8;
+   hact = vm.hactive * 18 / 8;
+   video_start = (vm.hsync_len + vm.hback_porch) * 18 / 8;
data_type = MIPI_DSI_PIXEL_STREAM_3BYTE_18;
break;
 
case MIPI_DSI_FMT_RGB565:
val |= (0x5 << 4);
-   hact = mode->hdisplay * 2;
-   video_start = (mode->htotal - mode->hsync_start) * 2;
+   hact = vm.hactive * 2;
+   video_start = (vm.hsync_len + vm.hback_porch) * 2;
data_type = MIPI_DSI_PACKED_PIXEL_STREAM_16;
break;
default:
@@ -814,43 +817,43 @@ static void tc358768_bridge_pre_enable(struct drm_bridge 
*bridge)
tc358768_write(priv, TC358768_DSI_EVENT, 0);
 
/* vact */
-   tc358768_write(priv, TC358768_DSI_VACT, mode->vdisplay);
+   tc358768_write(priv, TC358768_DSI_VACT, vm.vactive);
 
/* vsw */
-   tc358768_write(priv, TC358768_DSI_VSW,
-  mode->vsync_end - mode->vsync_start);
+   tc358768_write(priv, TC358768_DSI_VSW, vm.vsync_len);
+
/* vbp */
-   tc358768_write(priv, TC358768_DSI_VBPR,
-  mode->vtotal - mode->vsync_end);
+   tc358768_write(priv, TC358768_DSI_VBPR, vm.vback_porch);
 
/* hsw * byteclk * ndl / pclk */
-   val = (u32)div_u64((mode->hsync_end - mode->hsync_start) *
+   val = (u32)div_u64(vm.hsync_len *
   ((u64)priv->dsiclk / 4) * priv->dsi_lanes,
-  mode->clock * 1000);
+  vm.pixelclock);
tc358768_write(priv, TC358768_DSI_HSW, val);
 
/* hbp * byteclk * ndl / pclk */
-   val = (u32)div_u64((mode->htotal - mode->hsync_end) *
+   val = (u32)div_u64(vm.hback_porch *
   ((u64)priv->dsiclk / 4) * priv->dsi_lanes,
-  mode->clock * 1000);
+  vm.pixelclock);
tc358768_write(priv, TC358768_DSI_HBPR, val);
} else {
/* Set event mode */
tc358768_write(priv, TC358768_DSI_EVENT, 1);
 
/* vact */
-   tc358768_write(priv, TC358768_DSI_VACT, mode->vdisplay);
+  

[PATCH v4 03/12] drm/bridge: tc358768: Default to positive h/v syncs

2023-09-05 Thread Tomi Valkeinen
As the TC358768 is a DPI to DSI bridge, the DSI side does not need to
define h/v sync polarities. This means that sometimes we have a mode
without defined sync polarities, which does not work on the DPI side.

Add a mode_fixup hook to default to positive sync polarities.

Reviewed-by: Peter Ujfalusi 
Tested-by: Maxim Schwalm  # Asus TF700T
Tested-by: Marcel Ziswiler 
Signed-off-by: Tomi Valkeinen 
---
 drivers/gpu/drm/bridge/tc358768.c | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/drivers/gpu/drm/bridge/tc358768.c 
b/drivers/gpu/drm/bridge/tc358768.c
index bc97a837955b..963ac550509b 100644
--- a/drivers/gpu/drm/bridge/tc358768.c
+++ b/drivers/gpu/drm/bridge/tc358768.c
@@ -963,9 +963,27 @@ tc358768_atomic_get_input_bus_fmts(struct drm_bridge 
*bridge,
return input_fmts;
 }
 
+static bool tc358768_mode_fixup(struct drm_bridge *bridge,
+   const struct drm_display_mode *mode,
+   struct drm_display_mode *adjusted_mode)
+{
+   /* Default to positive sync */
+
+   if (!(adjusted_mode->flags &
+ (DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NHSYNC)))
+   adjusted_mode->flags |= DRM_MODE_FLAG_PHSYNC;
+
+   if (!(adjusted_mode->flags &
+ (DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_NVSYNC)))
+   adjusted_mode->flags |= DRM_MODE_FLAG_PVSYNC;
+
+   return true;
+}
+
 static const struct drm_bridge_funcs tc358768_bridge_funcs = {
.attach = tc358768_bridge_attach,
.mode_valid = tc358768_bridge_mode_valid,
+   .mode_fixup = tc358768_mode_fixup,
.pre_enable = tc358768_bridge_pre_enable,
.enable = tc358768_bridge_enable,
.disable = tc358768_bridge_disable,

-- 
2.34.1



[PATCH v4 08/12] drm/bridge: tc358768: Use dev for dbg prints, not priv->dev

2023-09-05 Thread Tomi Valkeinen
Simplify the code by capturing the priv->dev value to dev variable, and
use it.

Reviewed-by: Peter Ujfalusi 
Tested-by: Maxim Schwalm  # Asus TF700T
Tested-by: Marcel Ziswiler 
Signed-off-by: Tomi Valkeinen 
---
 drivers/gpu/drm/bridge/tc358768.c | 41 ---
 1 file changed, 21 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/bridge/tc358768.c 
b/drivers/gpu/drm/bridge/tc358768.c
index 88060f961064..6297d28250e9 100644
--- a/drivers/gpu/drm/bridge/tc358768.c
+++ b/drivers/gpu/drm/bridge/tc358768.c
@@ -651,9 +651,10 @@ static void tc358768_bridge_pre_enable(struct drm_bridge 
*bridge)
const u32 internal_delay = 40;
int ret, i;
struct videomode vm;
+   struct device *dev = priv->dev;
 
if (mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) {
-   dev_warn_once(priv->dev, "Non-continuous mode unimplemented, 
falling back to continuous\n");
+   dev_warn_once(dev, "Non-continuous mode unimplemented, falling 
back to continuous\n");
mode_flags &= ~MIPI_DSI_CLOCK_NON_CONTINUOUS;
}
 
@@ -661,7 +662,7 @@ static void tc358768_bridge_pre_enable(struct drm_bridge 
*bridge)
 
ret = tc358768_sw_reset(priv);
if (ret) {
-   dev_err(priv->dev, "Software reset failed: %d\n", ret);
+   dev_err(dev, "Software reset failed: %d\n", ret);
tc358768_hw_disable(priv);
return;
}
@@ -669,7 +670,7 @@ static void tc358768_bridge_pre_enable(struct drm_bridge 
*bridge)
mode = &bridge->encoder->crtc->state->adjusted_mode;
ret = tc358768_setup_pll(priv, mode);
if (ret) {
-   dev_err(priv->dev, "PLL setup failed: %d\n", ret);
+   dev_err(dev, "PLL setup failed: %d\n", ret);
tc358768_hw_disable(priv);
return;
}
@@ -709,7 +710,7 @@ static void tc358768_bridge_pre_enable(struct drm_bridge 
*bridge)
data_type = MIPI_DSI_PACKED_PIXEL_STREAM_16;
break;
default:
-   dev_err(priv->dev, "Invalid data format (%u)\n",
+   dev_err(dev, "Invalid data format (%u)\n",
dsi_dev->format);
tc358768_hw_disable(priv);
return;
@@ -733,65 +734,65 @@ static void tc358768_bridge_pre_enable(struct drm_bridge 
*bridge)
  dsibclk);
dsiclk_nsk = (u32)div_u64((u64)10 * TC358768_PRECISION, dsiclk);
ui_nsk = dsiclk_nsk / 2;
-   dev_dbg(priv->dev, "dsiclk_nsk: %u\n", dsiclk_nsk);
-   dev_dbg(priv->dev, "ui_nsk: %u\n", ui_nsk);
-   dev_dbg(priv->dev, "dsibclk_nsk: %u\n", dsibclk_nsk);
+   dev_dbg(dev, "dsiclk_nsk: %u\n", dsiclk_nsk);
+   dev_dbg(dev, "ui_nsk: %u\n", ui_nsk);
+   dev_dbg(dev, "dsibclk_nsk: %u\n", dsibclk_nsk);
 
/* LP11 > 100us for D-PHY Rx Init */
val = tc358768_ns_to_cnt(100 * 1000, dsibclk_nsk) - 1;
-   dev_dbg(priv->dev, "LINEINITCNT: %u\n", val);
+   dev_dbg(dev, "LINEINITCNT: %u\n", val);
tc358768_write(priv, TC358768_LINEINITCNT, val);
 
/* LPTimeCnt > 50ns */
val = tc358768_ns_to_cnt(50, dsibclk_nsk) - 1;
lptxcnt = val;
-   dev_dbg(priv->dev, "LPTXTIMECNT: %u\n", val);
+   dev_dbg(dev, "LPTXTIMECNT: %u\n", val);
tc358768_write(priv, TC358768_LPTXTIMECNT, val);
 
/* 38ns < TCLK_PREPARE < 95ns */
val = tc358768_ns_to_cnt(65, dsibclk_nsk) - 1;
-   dev_dbg(priv->dev, "TCLK_PREPARECNT %u\n", val);
+   dev_dbg(dev, "TCLK_PREPARECNT %u\n", val);
/* TCLK_PREPARE + TCLK_ZERO > 300ns */
val2 = tc358768_ns_to_cnt(300 - tc358768_to_ns(2 * ui_nsk),
  dsibclk_nsk) - 2;
-   dev_dbg(priv->dev, "TCLK_ZEROCNT %u\n", val2);
+   dev_dbg(dev, "TCLK_ZEROCNT %u\n", val2);
val |= val2 << 8;
tc358768_write(priv, TC358768_TCLK_HEADERCNT, val);
 
/* TCLK_TRAIL > 60ns AND TEOT <= 105 ns + 12*UI */
raw_val = tc358768_ns_to_cnt(60 + tc358768_to_ns(2 * ui_nsk), 
dsibclk_nsk) - 5;
val = clamp(raw_val, 0, 127);
-   dev_dbg(priv->dev, "TCLK_TRAILCNT: %u\n", val);
+   dev_dbg(dev, "TCLK_TRAILCNT: %u\n", val);
tc358768_write(priv, TC358768_TCLK_TRAILCNT, val);
 
/* 40ns + 4*UI < THS_PREPARE < 85ns + 6*UI */
val = 50 + tc358768_to_ns(4 * ui_nsk);
val = tc358768_ns_to_cnt(val, dsibclk_nsk) - 1;
-   dev_dbg(priv->dev, "THS_PREPARECNT %u\n", val);
+   dev_dbg(dev, "THS_PREPARECNT %u\n", val);
/* THS_PREPARE + THS_ZERO > 145ns + 10*UI */
raw_val = tc358768_ns_to_cnt(145 - tc358768_to_ns(3 * ui_nsk), 
dsibclk_nsk) - 10;
val2 = clamp(raw_val, 0, 127);
-   dev_dbg(priv->dev, "THS_ZEROCNT %u\n", val2);
+   dev_dbg(dev, "THS_ZEROCNT %u\n", val2);
val |= val2 << 8;
tc358768_write(priv, TC358768_THS_HEADERCNT, val);
 
/* TWAKE

[PATCH v4 04/12] drm/bridge: tc358768: Fix bit updates

2023-09-05 Thread Tomi Valkeinen
The driver has a few places where it does:

if (thing_is_enabled_in_config)
update_thing_bit_in_hw()

This means that if the thing is _not_ enabled, the bit never gets
cleared. This affects the h/vsyncs and continuous DSI clock bits.

Fix the driver to always update the bit.

Fixes: ff1ca6397b1d ("drm/bridge: Add tc358768 driver")
Reviewed-by: Peter Ujfalusi 
Tested-by: Maxim Schwalm  # Asus TF700T
Tested-by: Marcel Ziswiler 
Signed-off-by: Tomi Valkeinen 
---
 drivers/gpu/drm/bridge/tc358768.c | 13 +++--
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/bridge/tc358768.c 
b/drivers/gpu/drm/bridge/tc358768.c
index 963ac550509b..2af23f1e 100644
--- a/drivers/gpu/drm/bridge/tc358768.c
+++ b/drivers/gpu/drm/bridge/tc358768.c
@@ -794,8 +794,8 @@ static void tc358768_bridge_pre_enable(struct drm_bridge 
*bridge)
val |= BIT(i + 1);
tc358768_write(priv, TC358768_HSTXVREGEN, val);
 
-   if (!(mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS))
-   tc358768_write(priv, TC358768_TXOPTIONCNTRL, 0x1);
+   tc358768_write(priv, TC358768_TXOPTIONCNTRL,
+  (mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) ? 0 : 
BIT(0));
 
/* TXTAGOCNT[26:16] RXTASURECNT[10:0] */
val = tc358768_to_ns((lptxcnt + 1) * dsibclk_nsk * 4);
@@ -861,11 +861,12 @@ static void tc358768_bridge_pre_enable(struct drm_bridge 
*bridge)
tc358768_write(priv, TC358768_DSI_HACT, hact);
 
/* VSYNC polarity */
-   if (!(mode->flags & DRM_MODE_FLAG_NVSYNC))
-   tc358768_update_bits(priv, TC358768_CONFCTL, BIT(5), BIT(5));
+   tc358768_update_bits(priv, TC358768_CONFCTL, BIT(5),
+(mode->flags & DRM_MODE_FLAG_PVSYNC) ? BIT(5) : 0);
+
/* HSYNC polarity */
-   if (mode->flags & DRM_MODE_FLAG_PHSYNC)
-   tc358768_update_bits(priv, TC358768_PP_MISC, BIT(0), BIT(0));
+   tc358768_update_bits(priv, TC358768_PP_MISC, BIT(0),
+(mode->flags & DRM_MODE_FLAG_PHSYNC) ? BIT(0) : 0);
 
/* Start DSI Tx */
tc358768_write(priv, TC358768_DSI_START, 0x1);

-- 
2.34.1



[PATCH v4 01/12] drm/tegra: rgb: Parameterize V- and H-sync polarities

2023-09-05 Thread Tomi Valkeinen
From: Thierry Reding 

The polarities of the V- and H-sync signals are encoded as flags in the
display mode, so use the existing information to setup the signals for
the RGB interface.

Signed-off-by: Thierry Reding 
Cc: Thierry Reding 
[tomi.valkei...@ideasonboard.com: default to positive sync]
Reviewed-by: Peter Ujfalusi 
Tested-by: Maxim Schwalm  # Asus TF700T
Tested-by: Marcel Ziswiler 
Signed-off-by: Tomi Valkeinen 
---
 drivers/gpu/drm/tegra/rgb.c | 16 +---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/tegra/rgb.c b/drivers/gpu/drm/tegra/rgb.c
index 79566c9ea8ff..fc66bbd913b2 100644
--- a/drivers/gpu/drm/tegra/rgb.c
+++ b/drivers/gpu/drm/tegra/rgb.c
@@ -99,6 +99,7 @@ static void tegra_rgb_encoder_disable(struct drm_encoder 
*encoder)
 
 static void tegra_rgb_encoder_enable(struct drm_encoder *encoder)
 {
+   struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode;
struct tegra_output *output = encoder_to_output(encoder);
struct tegra_rgb *rgb = to_rgb(output);
u32 value;
@@ -108,10 +109,19 @@ static void tegra_rgb_encoder_enable(struct drm_encoder 
*encoder)
value = DE_SELECT_ACTIVE | DE_CONTROL_NORMAL;
tegra_dc_writel(rgb->dc, value, DC_DISP_DATA_ENABLE_OPTIONS);
 
-   /* XXX: parameterize? */
+   /* configure H- and V-sync signal polarities */
value = tegra_dc_readl(rgb->dc, DC_COM_PIN_OUTPUT_POLARITY(1));
-   value &= ~LVS_OUTPUT_POLARITY_LOW;
-   value &= ~LHS_OUTPUT_POLARITY_LOW;
+
+   if (mode->flags & DRM_MODE_FLAG_NHSYNC)
+   value |= LHS_OUTPUT_POLARITY_LOW;
+   else
+   value &= ~LHS_OUTPUT_POLARITY_LOW;
+
+   if (mode->flags & DRM_MODE_FLAG_NVSYNC)
+   value |= LVS_OUTPUT_POLARITY_LOW;
+   else
+   value &= ~LVS_OUTPUT_POLARITY_LOW;
+
tegra_dc_writel(rgb->dc, value, DC_COM_PIN_OUTPUT_POLARITY(1));
 
/* XXX: parameterize? */

-- 
2.34.1



[PATCH v4 05/12] drm/bridge: tc358768: Cleanup PLL calculations

2023-09-05 Thread Tomi Valkeinen
As is quite common, some of TC358768's PLL register fields are to be
programmed with (value - 1). Specifically, the FBD and PRD, multiplier
and divider, are such fields.

However, what the driver currently does is that it considers that the
formula used for PLL rate calculation is:

RefClk * [(FBD + 1)/ (PRD + 1)] * [1 / (2^FRS)]

where FBD and PRD are values directly from the registers, while a more
sensible way to look at it is:

RefClk * FBD / PRD * (1 / (2^FRS))

and when the FBD and PRD values are written to the registers, they will
be subtracted by one.

Change the driver accordingly, as it simplifies the PLL code.

Reviewed-by: Peter Ujfalusi 
Tested-by: Maxim Schwalm  # Asus TF700T
Tested-by: Marcel Ziswiler 
Signed-off-by: Tomi Valkeinen 
---
 drivers/gpu/drm/bridge/tc358768.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/bridge/tc358768.c 
b/drivers/gpu/drm/bridge/tc358768.c
index 2af23f1e..a465674f1e2e 100644
--- a/drivers/gpu/drm/bridge/tc358768.c
+++ b/drivers/gpu/drm/bridge/tc358768.c
@@ -316,7 +316,7 @@ static int tc358768_calc_pll(struct tc358768_priv *priv,
 
target_pll = tc358768_pclk_to_pll(priv, mode->clock * 1000);
 
-   /* pll_clk = RefClk * [(FBD + 1)/ (PRD + 1)] * [1 / (2^FRS)] */
+   /* pll_clk = RefClk * FBD / PRD * (1 / (2^FRS)) */
 
for (i = 0; i < ARRAY_SIZE(frs_limits); i++)
if (target_pll >= frs_limits[i])
@@ -336,19 +336,19 @@ static int tc358768_calc_pll(struct tc358768_priv *priv,
best_prd = 0;
best_fbd = 0;
 
-   for (prd = 0; prd < 16; ++prd) {
-   u32 divisor = (prd + 1) * (1 << frs);
+   for (prd = 1; prd <= 16; ++prd) {
+   u32 divisor = prd * (1 << frs);
u32 fbd;
 
-   for (fbd = 0; fbd < 512; ++fbd) {
+   for (fbd = 1; fbd <= 512; ++fbd) {
u32 pll, diff, pll_in;
 
-   pll = (u32)div_u64((u64)refclk * (fbd + 1), divisor);
+   pll = (u32)div_u64((u64)refclk * fbd, divisor);
 
if (pll >= max_pll || pll < min_pll)
continue;
 
-   pll_in = (u32)div_u64((u64)refclk, prd + 1);
+   pll_in = (u32)div_u64((u64)refclk, prd);
if (pll_in < 400)
continue;
 
@@ -611,7 +611,7 @@ static int tc358768_setup_pll(struct tc358768_priv *priv,
mode->clock * 1000);
 
/* PRD[15:12] FBD[8:0] */
-   tc358768_write(priv, TC358768_PLLCTL0, (prd << 12) | fbd);
+   tc358768_write(priv, TC358768_PLLCTL0, ((prd - 1) << 12) | (fbd - 1));
 
/* FRS[11:10] LBWS[9:8] CKEN[4] RESETB[1] EN[0] */
tc358768_write(priv, TC358768_PLLCTL1,

-- 
2.34.1



[PATCH v4 02/12] drm/bridge: tc358768: Fix use of uninitialized variable

2023-09-05 Thread Tomi Valkeinen
smatch reports:

drivers/gpu/drm/bridge/tc358768.c:223 tc358768_update_bits() error: 
uninitialized symbol 'orig'.

Fix this by bailing out from tc358768_update_bits() if the
tc358768_read() produces an error.

Fixes: ff1ca6397b1d ("drm/bridge: Add tc358768 driver")
Reviewed-by: Peter Ujfalusi 
Tested-by: Maxim Schwalm  # Asus TF700T
Tested-by: Marcel Ziswiler 
Signed-off-by: Tomi Valkeinen 
---
 drivers/gpu/drm/bridge/tc358768.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/bridge/tc358768.c 
b/drivers/gpu/drm/bridge/tc358768.c
index 819a4b6ec2a0..bc97a837955b 100644
--- a/drivers/gpu/drm/bridge/tc358768.c
+++ b/drivers/gpu/drm/bridge/tc358768.c
@@ -216,6 +216,10 @@ static void tc358768_update_bits(struct tc358768_priv 
*priv, u32 reg, u32 mask,
u32 tmp, orig;
 
tc358768_read(priv, reg, &orig);
+
+   if (priv->error)
+   return;
+
tmp = orig & ~mask;
tmp |= val & mask;
if (tmp != orig)

-- 
2.34.1



[PATCH v4 00/12] drm/bridge: tc358768: Fixes and timings improvements

2023-09-05 Thread Tomi Valkeinen
This series contains various fixes and cleanups for TC358768. The target
of this work is to get TC358768 working on Toradex's AM62 based board,
which has the following display pipeline:

AM62 DPI -> TC358768 -> LT8912B -> HDMI connector

The main thing the series does is to improve the DSI HSW, HFP and VSDly
calculations.

 Tomi

Signed-off-by: Tomi Valkeinen 
---
Changes in v4:
- Add Tested-by tags
- Fix a typo in a comment 
- Link to v3: 
https://lore.kernel.org/r/20230822-tc358768-v3-0-c82405dac...@ideasonboard.com

Changes in v3:
- Add Peter's reviewed-bys
- Move "Default to positive h/v syncs" earlier in the series to avoid
  regression in the middle of the series
- Link to v2: 
https://lore.kernel.org/r/20230816-tc358768-v2-0-242b9d5f7...@ideasonboard.com

Changes in v2:
- Add "drm/tegra: rgb: Parameterize V- and H-sync polarities" so that
  Tegra can configure the polarities correctly.
- Add "drm/bridge: tc358768: Default to positive h/v syncs" as we don't
  (necessarily) have the polarities set in the mode.
- Drop "drm/bridge: tc358768: Add DRM_BRIDGE_ATTACH_NO_CONNECTOR
  support" as it's not needed for DRM_BRIDGE_ATTACH_NO_CONNECTOR
  support.
- Link to v1: 
https://lore.kernel.org/r/20230804-tc358768-v1-0-1afd44b78...@ideasonboard.com

---
Thierry Reding (1):
  drm/tegra: rgb: Parameterize V- and H-sync polarities

Tomi Valkeinen (11):
  drm/bridge: tc358768: Fix use of uninitialized variable
  drm/bridge: tc358768: Default to positive h/v syncs
  drm/bridge: tc358768: Fix bit updates
  drm/bridge: tc358768: Cleanup PLL calculations
  drm/bridge: tc358768: Use struct videomode
  drm/bridge: tc358768: Print logical values, not raw register values
  drm/bridge: tc358768: Use dev for dbg prints, not priv->dev
  drm/bridge: tc358768: Rename dsibclk to hsbyteclk
  drm/bridge: tc358768: Clean up clock period code
  drm/bridge: tc358768: Fix tc358768_ns_to_cnt()
  drm/bridge: tc358768: Attempt to fix DSI horizontal timings

 drivers/gpu/drm/bridge/tc358768.c | 381 --
 drivers/gpu/drm/tegra/rgb.c   |  16 +-
 2 files changed, 295 insertions(+), 102 deletions(-)
---
base-commit: f45acf7acf75921c0409d452f0165f51a19a74fd
change-id: 20230804-tc358768-1b6949ef2e3d

Best regards,
-- 
Tomi Valkeinen 



Re: [Intel-gfx] [PATCH v5] drm/i915: Avoid circular locking dependency when flush delayed work on gt reset

2023-09-05 Thread Daniel Vetter
On Mon, Aug 28, 2023 at 04:01:38PM -0700, John Harrison wrote:
> On 8/23/2023 10:37, John Harrison wrote:
> > On 8/23/2023 09:00, Daniel Vetter wrote:
> > > On Tue, Aug 22, 2023 at 11:53:24AM -0700, John Harrison wrote:
> > > > On 8/11/2023 11:20, Zhanjun Dong wrote:
> > > > > This attempts to avoid circular locking dependency between
> > > > > flush delayed
> > > > > work and intel_gt_reset.
> > > > > When intel_gt_reset was called, task will hold a lock.
> > > > > To cacel delayed work here, the _sync version will also
> > > > > acquire a lock,
> > > > > which might trigger the possible cirular locking dependency warning.
> > > > > When intel_gt_reset called, reset_in_progress flag will be
> > > > > set, add code
> > > > > to check the flag, call async verion if reset is in progress.
> > > > > 
> > > > > Signed-off-by: Zhanjun Dong
> > > > > Cc: John Harrison
> > > > > Cc: Andi Shyti
> > > > > Cc: Daniel Vetter
> > > > > ---
> > > > >    drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c | 11 ++-
> > > > >    1 file changed, 10 insertions(+), 1 deletion(-)
> > > > > 
> > > > > diff --git
> > > > > a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
> > > > > b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
> > > > > index a0e3ef1c65d2..600388c849f7 100644
> > > > > --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
> > > > > +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
> > > > > @@ -1359,7 +1359,16 @@ static void
> > > > > guc_enable_busyness_worker(struct intel_guc *guc)
> > > > >    static void guc_cancel_busyness_worker(struct intel_guc *guc)
> > > > >    {
> > > > > -    cancel_delayed_work_sync(&guc->timestamp.work);
> > > > > +    /*
> > > > > + * When intel_gt_reset was called, task will hold a lock.
> > > > > + * To cacel delayed work here, the _sync version will
> > > > > also acquire a lock, which might
> > > > > + * trigger the possible cirular locking dependency warning.
> > > > > + * Check the reset_in_progress flag, call async verion
> > > > > if reset is in progress.
> > > > > + */
> > > > This needs to explain in much more detail what is going on and
> > > > why it is not
> > > > a problem. E.g.:
> > > > 
> > > >     The busyness worker needs to be cancelled. In general that means
> > > >     using the synchronous cancel version to ensure that an in-progress
> > > >     worker will not keep executing beyond whatever is happening that
> > > >     needs the cancel. E.g. suspend, driver unload, etc. However, in the
> > > >     case of a reset, the synchronous version is not required and can
> > > >     trigger a false deadlock detection warning.
> > > > 
> > > >     The business worker takes the reset mutex to protect against resets
> > > >     interfering with it. However, it does a trylock and bails
> > > > out if the
> > > >     reset lock is already acquired. Thus there is no actual deadlock or
> > > >     other concern with the worker running concurrently with a reset. So
> > > >     an asynchronous cancel is safe in the case of a reset rather than a
> > > >     driver unload or suspend type operation. On the other hand, if the
> > > >     cancel_sync version is used when a reset is in progress then the
> > > >     mutex deadlock detection sees the mutex being acquired through
> > > >     multiple paths and complains.
> > > > 
> > > >     So just don't bother. That keeps the detection code happy and is
> > > >     safe because of the trylock code described above.
> > > So why do we even need to cancel anything if it doesn't do anything
> > > while
> > > the reset is in progress?
> > It still needs to be cancelled. The worker only aborts if it is actively
> > executing concurrently with the reset. It might not start to execute
> > until after the reset has completed. And there is presumably a reason
> > why the cancel is being called, a reason not necessarily related to
> > resets at all. Leaving the worker to run arbitrarily after the driver is
> > expecting it to be stopped will lead to much worse things than a fake
> > lockdep splat, e.g. a use after free pointer deref.
> > 
> > John.
> @Daniel Vetter - ping? Is this explanation sufficient? Are you okay with
> this change now?

Sorry for the late reply, I'm constantly behind on mails :-/ Ping me on
irc next time around if I don't reply, that's quicker.

"presumably" isn't good enough for locking design. Either you know, and
can prove it all, or you shouldn't touch the code and its locking design
before you've figured this out.

Again, either this is a deadlock, race condition, or the cancel isn't
necessary. And this argument works in full generality. All this patch does
it replace the dealock with one of the other two, and that's not good
enough if you don't even know which one it is.

- if you need the cancel, you have a race condition

- if you don't have a race condition, you don't need the cancel

- currently you have the deadlock

"presumably" and "maybe" aint enoug for locking design

Re: [RFC, drm-misc-next v4 0/9] PCI/VGA: Allowing the user to select the primary video adapter at boot time

2023-09-05 Thread Christian König

Am 05.09.23 um 16:28 schrieb Sui Jingfeng:

Hi,

On 2023/9/5 21:28, Christian König wrote:


2) Typically, those non-86 machines don't have a good UEFI firmware
    support, which doesn't support select primary GPU as firmware 
stage.
    Even on x86, there are old UEFI firmwares which already made 
undesired

    decision for you.

3) This series is attempt to solve the remain problems at the 
driver level,
    while another series[1] of me is target to solve the majority 
of the

    problems at device level.

Tested (limited) on x86 with four video card mounted, Intel UHD 
Graphics

630 is the default boot VGA, successfully override by ast2400 with
ast.modeset=10 append at the kernel cmd line.

The value 10 is incredibly arbitrary, and multiplied as a magic number
all over the place.


+1 



This is the exact reason why I made this series as RFC, because this 
is a open-ended problem.
The choices of 3,4,5,6,7,8 and 9 are as arbitrary as the number of 
'10'. '1' and '2' is

definitely not suitable, because the seat has already been taken.


Well you are completely missing the point. *DON'T* abuse the modeset 
module parameters for this!


If you use 10 or any other value doesn't matter.

Regards,
Christian.



Take the drm/nouveau as an example:


```

MODULE_PARM_DESC(modeset, "enable driver (default: auto, "
  "0 = disabled, 1 = enabled, 2 = headless)");
int nouveau_modeset = -1;
module_param_named(modeset, nouveau_modeset, int, 0400);

```


'1' is for enable the drm driver, some driver even override the 
'nomodeset' parameter.


'2' is not suitable, because nouveau use it as headless GPU 
(render-only or compute class GPU?)


'3' is also not likely the best, the concerns is that
what if a specific drm driver want to expand the usage in the future?


The reason I pick up the digit '10' is that


1) The modeset parameter is unlikely to get expanded up to 10 usages.

Other drm drivers only use the '-1', '0' and 1, choose '2' will 
conflict with drm/nouveau.
By pick the digit '10', it leave some space(room) to various device 
driver authors.

It also helps to keep the usage consistent across various drivers.


2) An int taken up 4 byte, I don't want to waste even a single byte,

While in the process of defencing my patch, I have to say
draft another kernel command line would cause the wasting of precious 
RAM storage.


An int can have 2^31 usage, why we can't improve the utilization rate?

3) Please consider the fact that the modeset is the most common and 
attractive parameter


No name is better than the 'modeset', as other name is not easy to 
remember.


Again, this is for Linux user, thus it is not arbitrary.
Despite simple and trivial, I think about it more than one week.





Re: [Nouveau] [RFC, drm-misc-next v4 0/9] PCI/VGA: Allowing the user to select the primary video adapter at boot time

2023-09-05 Thread Christian König

Am 05.09.23 um 15:30 schrieb suijingfeng:

Hi,


On 2023/9/5 18:45, Thomas Zimmermann wrote:

Hi

Am 04.09.23 um 21:57 schrieb Sui Jingfeng:

From: Sui Jingfeng 

On a machine with multiple GPUs, a Linux user has no control over which
one is primary at boot time. This series tries to solve above mentioned


If anything, the primary graphics adapter is the one initialized by 
the firmware. I think our boot-up graphics also make this assumption 
implicitly.




Yes, but by the time of DRM drivers get loaded successfully,the 
boot-up graphics already finished.


This is an incorrect assumption.

drm_aperture_remove_conflicting_pci_framebuffers() and co don't kill the 
framebuffer, they just remove the current framebuffer driver to avoid 
further updates.


So what happens (at least for amdgpu) is that we take over the 
framebuffer, including both mode and it's contents, and provide a new 
framebuffer interface until DRM masters like X or Wayland take over.


Firmware framebuffer device already get killed by the 
drm_aperture_remove_conflicting_pci_framebuffers()
function (or its siblings). So, this series is definitely not to 
interact with the firmware framebuffer
(or more intelligent framebuffer drivers).  It is for user space 
program, such as X server and Wayland
compositor. Its for Linux user or drm drivers testers, which allow 
them to direct graphic display server

using right hardware of interested as primary video card.

Also, I believe that X server and Wayland compositor are the best test 
examples.

If a specific DRM driver can't work with X server as a primary,
then there probably have something wrong.



But what's the use case for overriding this setting?



On a specific machine with multiple GPUs mounted,
only the primary graphics get POST-ed (initialized) by the firmware.
Therefore, the DRM drivers for the rest video cards, have to choose to
work without the prerequisite setups done by firmware, This is called 
as POST.


Well, you don't seem to understand the background here. This is 
perfectly normal behavior.


Secondary cards are posted after loading the appropriate DRM driver. At 
least for amdgpu this is done by calling the appropriate functions in 
the BIOS.




One of the use cases of this series is to test if a specific DRM 
driver could works properly,
even though there is no prerequisite works have been done by firmware 
at all.

And it seems that the results is not satisfying in all cases.

drm/ast is the first drm drivers which refused to work if not being 
POST-ed by the firmware.


As far as I know this is expected as well. AST is a relatively simple 
driver and when it's not the primary one during boot the assumption is 
that it isn't used at all.


Regards,
Christian.



Before apply this series, I was unable make drm/ast as the primary 
video card easily. On a
multiple video card configuration, the monitor connected with the 
AST2400 not light up.

While confusing, a naive programmer may suspect the PRIME is not working.

After applied this series and passing ast.modeset=10 on the kernel cmd 
line,
I found that the monitor connected with my ast2400 video card still 
black,

It doesn't display and doesn't show image to me.

While in the process of study drm/ast, I know that drm/ast driver has 
the POST code shipped.
See the ast_post_gpu() function, then, I was wondering why this 
function doesn't works.
After a short-time (hasty) debugging, I found that the the 
ast_post_gpu() function
didn't get run. Because it have something to do with the 
ast->config_mode.


Without thinking too much, I hardcoded the ast->config_mode as 
ast_use_p2a to

force the ast_post_gpu() function get run.

```

--- a/drivers/gpu/drm/ast/ast_main.c
+++ b/drivers/gpu/drm/ast/ast_main.c
@@ -132,6 +132,8 @@ static int ast_device_config_init(struct 
ast_device *ast)

    }
    }

+   ast->config_mode = ast_use_p2a;
+
    switch (ast->config_mode) {
    case ast_use_defaults:
    drm_info(dev, "Using default configuration\n");

```

Then, the monitor light up, it display the Ubuntu greeter to me.
Therefore, my patch is helpful, at lease for the Linux drm driver 
tester and developer.

It allow programmers to test the specific part of the specific drive
without changing a line of the source code and without the need of 
sudo authority.

It helps to improve efficiency of the testing and patch verification.

I know the PrimaryGPU option of Xorg conf, but this approach will 
remember the setup
have been made, you need modify it with root authority each time you 
want to switch
the primary. But on rapid developing and/or testing multiple video 
drivers, with
only one computer hardware resource available. What we really want 
probably is a

one-shoot command as this series provide.

So, this is the first use case. This probably also help to test full 
modeset,

PRIME and reverse PRIME on multiple video card machine.



Best regards
Thomas







Re: [RFT PATCH 13/15] drm/imx/ipuv3: Call drm_atomic_helper_shutdown() at shutdown/unbind time

2023-09-05 Thread Philipp Zabel
Hi,

On Di, 2023-09-05 at 13:29 -0700, Doug Anderson wrote:
> Hi,
> 
> On Mon, Sep 4, 2023 at 1:30 AM Philipp Zabel  wrote:
> > 
> > On Fr, 2023-09-01 at 16:41 -0700, Douglas Anderson wrote:
> > > Based on grepping through the source code this driver appears to be
> > > missing a call to drm_atomic_helper_shutdown() at system shutdown time
> > > and at driver unbind time. Among other things, this means that if a
> > > panel is in use that it won't be cleanly powered off at system
> > > shutdown time.
> > > 
> > > The fact that we should call drm_atomic_helper_shutdown() in the case
> > > of OS shutdown/restart and at driver remove (or unbind) time comes
> > > straight out of the kernel doc "driver instance overview" in
> > > drm_drv.c.
> > > 
> > > A few notes about this fix:
> > > - When adding drm_atomic_helper_shutdown() to the unbind path, I added
> > >   it after drm_kms_helper_poll_fini() since that's when other drivers
> > >   seemed to have it.
> > > - Technically with a previous patch, ("drm/atomic-helper:
> > >   drm_atomic_helper_shutdown(NULL) should be a noop"), we don't
> > >   actually need to check to see if our "drm" pointer is NULL before
> > >   calling drm_atomic_helper_shutdown(). We'll leave the "if" test in,
> > >   though, so that this patch can land without any dependencies. It
> > >   could potentially be removed later.
> > > - This patch also makes sure to set the drvdata to NULL in the case of
> > >   bind errors to make sure that shutdown can't access freed data.
> > > 
> > > Suggested-by: Maxime Ripard 
> > > Signed-off-by: Douglas Anderson 
> > 
> > Thank you,
> > Tested-by: Philipp Zabel 
> 
> Thanks! I notice that:
> 
> ./scripts/get_maintainer.pl --scm -f drivers/gpu/drm/imx/ipuv3/imx-drm-core.c
> 
> Doesn't say drm-misc but also when I look at the MAINTAINERS file and
> find the section for "DRM DRIVERS FOR FREESCALE IMX"

That should probably say "IMX5/6" nowadays. There are a lot more i.MX
that do not use IPUv3 than those that do.

> it doesn't explicitly list a different git tree.

I used to send pull requests from git.pengutronix.de/git/pza/linux,
same as for the reset controller framework. I might still have to do
that for changes in drivers/gpu/ipu-v3 that need coordination between
drm and v4l2, but usually pure drm/imx/ipuv3 changes are pushed to drm-
misc.

> I guess the "shawnguo" git tree listed by get_maintainer.pl is just
> from regex matching?

The "N: imx" pattern in "ARM/FREESCALE IMX / MXC ARM ARCHITECTURE", I
think.

> Would you expect this to go through drm-misc? If so, I'll probably
> land it sooner rather than later. I can also post up a patch making it
> obvious that "DRM DRIVERS FOR FREESCALE IMX" goes through drm-misc if
> you don't object.

Yes, both would be great.

regards
Philipp


Re: [PATCH v2 2/7] drm: ci: Force db410c to host mode

2023-09-05 Thread Vignesh Raman

Hi Maxime,

On 05/09/23 19:10, Maxime Ripard wrote:

With,
&usb {
dr_mode = "host";
};

The target is <0x> and fdtoverlay fails to apply the dtbo.


You do have /plugin/ and have compiled the base device tree with overlay
support, right?


After compiling base dtbs with overlay support (make DTC_FLAGS=-@ dtbs) 
it works.





With,
&{/soc@0/usb} {
  dr_mode = "host";
};

The target-path is "/soc@0/usb" (usb: usb@78d9000)


Right, and that's not the path you want to modify. The path you want to
modify is /soc@0/usb@78d9000. usb is the label, it's absolute, and you
can't mix and match a path ("/soc@0/") and a label ("usb")


Thanks for the clarification.

Regards,
Vignesh



Re: [Nouveau] [RFC, drm-misc-next v4 0/9] PCI/VGA: Allowing the user to select the primary video adapter at boot time

2023-09-05 Thread Sui Jingfeng

Hi,

On 2023/9/5 23:05, Thomas Zimmermann wrote:
You might have found a bug in the ast driver. Ast has means to detect 
if the device has been POSTed and maybe do that. If this doesn't work 
correctly, it needs a fix.



That sounds fine.

The bug is not a big deal, I'm just take it as an example and report it to you.
But a real fix can be complex, because there are quite a lot of servers
ship with ASpeed BMC hardware.

Honestly I don't have the time fix it on formal way.
I have already tons patches in pending and I will focus on solve VGAARB related 
problem.


Because I want to test your patch occasionally.
So this series is useful for myself at corner cases.



Re: [RFC, drm-misc-next v4 0/9] PCI/VGA: Allowing the user to select the primary video adapter at boot time

2023-09-05 Thread Sui Jingfeng

Hi,


On 2023/9/5 22:52, Alex Williamson wrote:

On Tue,  5 Sep 2023 03:57:15 +0800
Sui Jingfeng  wrote:


From: Sui Jingfeng 

On a machine with multiple GPUs, a Linux user has no control over which
one is primary at boot time. This series tries to solve above mentioned
problem by introduced the ->be_primary() function stub. The specific
device drivers can provide an implementation to hook up with this stub by
calling the vga_client_register() function.

Once the driver bound the device successfully, VGAARB will call back to
the device driver. To query if the device drivers want to be primary or
not. Device drivers can just pass NULL if have no such needs.

Please note that:

1) The ARM64, Loongarch, Mips servers have a lot PCIe slot, and I would
like to mount at least three video cards.

2) Typically, those non-86 machines don't have a good UEFI firmware
support, which doesn't support select primary GPU as firmware stage.
Even on x86, there are old UEFI firmwares which already made undesired
decision for you.

3) This series is attempt to solve the remain problems at the driver level,
while another series[1] of me is target to solve the majority of the
problems at device level.

Tested (limited) on x86 with four video card mounted, Intel UHD Graphics
630 is the default boot VGA, successfully override by ast2400 with
ast.modeset=10 append at the kernel cmd line.

$ lspci | grep VGA

  00:02.0 VGA compatible controller: Intel Corporation CoffeeLake-S GT2 [UHD 
Graphics 630]

In all my previous experiments with VGA routing and IGD I found that
IGD can't actually release VGA routing and Intel confirmed the hardware
doesn't have the ability to do so.


Which model of the IGD you are using? even for the IGD in Atom D2550,
the legacy 128KB VGA memory range can be tuned to be mapped to IGD
or to the DMI Interface. See the 1.7.3.2 section of the N2000 datasheet[1].

If a specific model of Intel has a bug in the VGA routing hardware logic unit,
I would like to ignore it. Or switch to the UEFI firmware on such hardware.

It is the hardware engineer's responsibility, I will not worry about it.
Thanks for you tell this.

[1] 
https://www.intel.com/content/dam/doc/datasheet/atom-d2000-n2000-vol-2-datasheet.pdf



  It will always be primary from a
VGA routing perspective.  Was this actually tested with non-UEFI?



As you already said, the generous Intel already have confirmed that the 
hardware defect.
So probably this is a good chance to switch to UEFI to solve the problem. Then, 
no
testing for legacy is needed.



I suspect it might only work in UEFI mode where we probably don't
actually have a dependency on VGA routing.  This is essentially why
vfio requires UEFI ROMs when assigning GPUs to VMs, VGA routing is too
broken to use on Intel systems with IGD.  Thanks,


Thanks for you tell me this.

To be honest, I have only tested my patch on machines with UEFI firmware.
Since UEFI because the main stream, but if this patch is really useful for
majority machine, I'm satisfied. The results is not too bad.

Thanks.


Alex



Re: [Nouveau] [RFC, drm-misc-next v4 0/9] PCI/VGA: Allowing the user to select the primary video adapter at boot time

2023-09-05 Thread suijingfeng

Hi,


On 2023/9/5 23:05, Thomas Zimmermann wrote:
However, on modern Linux systems the primary display does not really 
exist. 'Primary' is the device that is available via VGA, VESA or EFI. 


I may miss the point, what do you means by choose the word "modern"?
Are you trying to tell me that X server is too old and Wayland is the modern 
display server?



Our drivers don't use these interfaces, but the native registers.



Yes and no?

Yes for the machine with the UEFI firmware,
but I not sure if this statement is true for the machine with the legacy 
firmware.

As the display controller in the ASpeed BMC is VGA compatible.
Therefore, in theory, it should works with the VGA console on the machine
with another VGA compatible video card. So the ast_vga_set_decode() function
provided in the 0007 patch probably useful on legacy firmware environment.

To be honest, I have tested this on various machine with UEFI firmware.
But I didn't realized that I should do the testing on legacy firmware 
environment
before sending this patch. It seems that the testing effort needed are quite
exhausting, since all my machines come with the UEFI firmware.

So is it OK to leave the legacy part to someone else who interested in it?
Probably Alex is more professional at legacy VGA routing stuff?
:-)




Re: [PATCH] drm/vmwgfx: fix typo of sizeof argument

2023-09-05 Thread Zack Rusin
On Tue, 2023-09-05 at 18:02 +0800, Konstantin Meskhidze wrote:
> Since size of 'header' pointer and '*header' structure is equal on 64-bit
> machines issue probably didn't cause any wrong behavior. But anyway,
> fixing typo is required.
> 
> Fixes: 7a73ba7469cb ("drm/vmwgfx: Use TTM handles instead of SIDs as 
> user-space
> surface handles.")
> Co-developed-by: Ivanov Mikhail 
> Signed-off-by: Konstantin Meskhidze 
> ---
>  drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
> b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
> index 98e0723ca6f5..cc3f301ca163 100644
> --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
> +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
> @@ -1619,7 +1619,7 @@ static int vmw_cmd_tex_state(struct vmw_private 
> *dev_priv,
>  {
> VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdSetTextureState);
> SVGA3dTextureState *last_state = (SVGA3dTextureState *)
> - ((unsigned long) header + header->size + sizeof(header));
> + ((unsigned long) header + header->size + sizeof(*header));
> SVGA3dTextureState *cur_state = (SVGA3dTextureState *)
> ((unsigned long) header + sizeof(*cmd));
> struct vmw_resource *ctx;

Hah, yea, that's an old one. Thanks! I can push it through the drm-misc tree.

Reviewed-by: Zack Rusin 

z


Re: [Nouveau] [RFC, drm-misc-next v4 0/9] PCI/VGA: Allowing the user to select the primary video adapter at boot time

2023-09-05 Thread suijingfeng



On 2023/9/5 23:05, Thomas Zimmermann wrote:

Hi

Am 05.09.23 um 15:30 schrieb suijingfeng:

Hi,


On 2023/9/5 18:45, Thomas Zimmermann wrote:

Hi

Am 04.09.23 um 21:57 schrieb Sui Jingfeng:

From: Sui Jingfeng 

On a machine with multiple GPUs, a Linux user has no control over 
which
one is primary at boot time. This series tries to solve above 
mentioned


If anything, the primary graphics adapter is the one initialized by 
the firmware. I think our boot-up graphics also make this assumption 
implicitly.




Yes, but by the time of DRM drivers get loaded successfully,the 
boot-up graphics already finished.
Firmware framebuffer device already get killed by the 
drm_aperture_remove_conflicting_pci_framebuffers()
function (or its siblings). So, this series is definitely not to 
interact with the firmware framebuffer


Yes and no. The helpers you mention will attempt to remove the 
firmware framebuffer on the given PCI device. If you have multiple PCI 
devices, the other devices would not be affected.



Yes and no.


For the yes part: drm_aperture_remove_conflicting_pci_framebuffers() only kill 
the conflict one.
But for a specific machine with the modern UEFI firmware,
there should be only one firmware framebuffer driver.
That shoudd be the EFIFB(UEFI GOP). I do have multiple PCI devices,
but I don't understand when and why a system will have more than one firmware 
framebuffer.

Even for the machines with the legacy BIOS, the fixed VGA aperture address range
can only be owned by one firmware driver. It is just that we need to handle the
routing, the ->set_decode() callback of vga_client_register() is used to do such
work. Am I correct?




Re: [Nouveau] [RFC, drm-misc-next v4 0/9] PCI/VGA: Allowing the user to select the primary video adapter at boot time

2023-09-05 Thread suijingfeng

Hi,


On 2023/9/5 23:05, Thomas Zimmermann wrote:
However, on modern Linux systems the primary display does not really 
exist.



No, it do exist.  X server need to know which one is the primary GPU.
The '*' character at the of (4@0:0:0) PCI device is the Primary.
The '*' denote primary, see the log below.

(II) xfree86: Adding drm device (/dev/dri/card2)
(II) xfree86: Adding drm device (/dev/dri/card0)
(II) Platform probe for 
/sys/devices/pci:00/:00:1c.5/:003:00.0/:04:00.0/drm/card0

(II) xfree86: Adding drm device (/dev/dri/card3)
(II) Platform probe for 
/sys/devices/pci:00/:00:1c.6/:005:00.0/drm/card3
(--) PCI: (0@0:2:0) 8086:3e91:8086:3e91 rev 0, Mem @ 
0xdb00/16216, 0xa000/536870912, I/O @ 0xf000/64, BIOS @ 
0x/131072
(--) PCI: (1@0:0:0) 1002:6771:1043:8636 rev 0, Mem @ 
0xc000/2688435456, 0xdf22/131072, I/O @ 0xe000/256, BIOS @ 
0x/131072
(--) PCI:*(4@0:0:0) 1a03:2000:1a03:2000 rev 48, Mem @ 
0xde00/166777216, 0xdf02/131072, I/O @ 0xc000/128, BIOS @ 
0x/131072
(--) PCI: (5@0:0:0) 10de:1288:174b:b324 rev 161, Mem @ 
0xdc00/116777216, 0xd000/134217728, 0xd800/33554432, I/O @ 
0xb000/128, BIOS @@0x/524288


The modesetting driver of X server will create framebuffer on the primary video 
adapter.
If a 2D video adapter (like the aspeed BMC) is not the primary, then it 
probably will not
be used. The only chance to be able to display something is to functional as a 
output slave.
But the output slave technology need the PRIME support for cross driver buffer 
sharing.

So, there do have some difference between the primary and non-primary video 
adapters.


'Primary' is the device that is available via VGA, VESA or EFI. Our 
drivers don't use these interfaces, but the native registers. As you 
said yourself, these firmware devices (VGA, VESA, EFI) are removed 
ASAP by the native drivers. 




Re: [PATCH v3 1/8] drm/msm/dpu: populate SSPP scaler block version

2023-09-05 Thread Marijn Suijten
On 2023-09-05 04:25:19, Dmitry Baryshkov wrote:
> The function _dpu_hw_sspp_setup_scaler3() passes and
> dpu_hw_setup_scaler3() uses scaler_blk.version to determine in which way
> the scaler (QSEED3) block should be programmed. However up to now we
> were not setting this field. Set it now, splitting the vig_sblk data
> which has different version fields.
> 
> Reported-by: Marijn Suijten 
> Fixes: 9b6f4fedaac2 ("drm/msm/dpu: Add SM6125 support")
> Fixes: 27f0df03f3ff ("drm/msm/dpu: Add SM6375 support")
> Fixes: 3186acba5cdc ("drm/msm/dpu: Add SM6350 support")
> Fixes: efcd0107727c ("drm/msm/dpu: add support for SM8550")
> Fixes: 4a352c2fc15a ("drm/msm/dpu: Introduce SC8280XP")
> Fixes: 0e91bcbb0016 ("drm/msm/dpu: Add SM8350 to hw catalog")
> Fixes: 100d7ef6995d ("drm/msm/dpu: add support for SM8450")
> Fixes: 3581b7062cec ("drm/msm/disp/dpu1: add support for display on SM6115")
> Fixes: dabfdd89eaa9 ("drm/msm/disp/dpu1: add inline rotation support for 
> sc7280")
> Fixes: f3af2d6ee9ab ("drm/msm/dpu: Add SC8180x to hw catalog")
> Fixes: 94391a14fc27 ("drm/msm/dpu1: Add MSM8998 to hw catalog")
> Fixes: af776a3e1c30 ("drm/msm/dpu: add SM8250 to hw catalog")
> Fixes: 386fced3f76f ("drm/msm/dpu: add SM8150 to hw catalog")
> Fixes: b75ab05a3479 ("msm:disp:dpu1: add scaler support on SC7180 display")
> Fixes: 25fdd5933e4c ("drm/msm: Add SDM845 DPU support")
> Signed-off-by: Dmitry Baryshkov 

So as it turns out this patch is basically [1] with review comments
applied, though no mention whatsoever that .version isn't just a
convenient way to represent the version but what the register read by
_dpu_hw_sspp_get_scaler3_ver() contains? (That was the review: hardcode the
constants instead of doing runtime register reads)

With that, `_dpu_hw_sspp_get_scaler3_ver()` and `dpu_hw_sspp->get_scaler_ver`
must now be completely unused?

[1]: 
https://lore.kernel.org/linux-arm-msm/caa8ejpobxpsyeqzq3zgwsqg6fc7pzqumwr9ddpdmgoemts-...@mail.gmail.com/#t

It seems patch 6 in this series also has a matching - r-b'd - patch in that
series ;)

- Marijn

> ---
>  .../msm/disp/dpu1/catalog/dpu_5_0_sm8150.h|  8 +-
>  .../msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h   |  8 +-
>  .../msm/disp/dpu1/catalog/dpu_8_1_sm8450.h|  8 +-
>  .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c| 95 ++-
>  4 files changed, 85 insertions(+), 34 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h 
> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h
> index 99acaf917e43..f0c3804f4258 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h
> @@ -77,7 +77,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = {
>   .name = "sspp_0", .id = SSPP_VIG0,
>   .base = 0x4000, .len = 0x1f0,
>   .features = VIG_SDM845_MASK,
> - .sblk = &sdm845_vig_sblk_0,
> + .sblk = &sm8150_vig_sblk_0,
>   .xin_id = 0,
>   .type = SSPP_TYPE_VIG,
>   .clk_ctrl = DPU_CLK_CTRL_VIG0,
> @@ -85,7 +85,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = {
>   .name = "sspp_1", .id = SSPP_VIG1,
>   .base = 0x6000, .len = 0x1f0,
>   .features = VIG_SDM845_MASK,
> - .sblk = &sdm845_vig_sblk_1,
> + .sblk = &sm8150_vig_sblk_1,
>   .xin_id = 4,
>   .type = SSPP_TYPE_VIG,
>   .clk_ctrl = DPU_CLK_CTRL_VIG1,
> @@ -93,7 +93,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = {
>   .name = "sspp_2", .id = SSPP_VIG2,
>   .base = 0x8000, .len = 0x1f0,
>   .features = VIG_SDM845_MASK,
> - .sblk = &sdm845_vig_sblk_2,
> + .sblk = &sm8150_vig_sblk_2,
>   .xin_id = 8,
>   .type = SSPP_TYPE_VIG,
>   .clk_ctrl = DPU_CLK_CTRL_VIG2,
> @@ -101,7 +101,7 @@ static const struct dpu_sspp_cfg sm8150_sspp[] = {
>   .name = "sspp_3", .id = SSPP_VIG3,
>   .base = 0xa000, .len = 0x1f0,
>   .features = VIG_SDM845_MASK,
> - .sblk = &sdm845_vig_sblk_3,
> + .sblk = &sm8150_vig_sblk_3,
>   .xin_id = 12,
>   .type = SSPP_TYPE_VIG,
>   .clk_ctrl = DPU_CLK_CTRL_VIG3,
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h 
> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
> index f3de21025ca7..3ec954722a8e 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
> @@ -76,7 +76,7 @@ static const struct dpu_sspp_cfg sc8180x_sspp[] = {
>   .name = "sspp_0", .id = SSPP_VIG0,
>   .base = 0x4000, .len = 0x1f0,
>   .features = VIG_SDM845_MASK,
> - .sblk = &sdm845_vig_sblk_0,
> + .sblk = &sm8150_vig_sblk_0,
>   .xin_id = 0,
>   .type = SSPP_TY

Re: [PATCH v2 6/6] drm/drm-file: Allow size unit selection in drm_show_memory_stats

2023-09-05 Thread Rob Clark
On Wed, Aug 30, 2023 at 8:51 AM Adrián Larumbe
 wrote:
>
> >> The current implementation will try to pick the highest available
> >> unit. This is rather unflexible, and allowing drivers to display BO size
> >> statistics through fdinfo in units of their choice might be desirable.
> >>
> >> The new argument to drm_show_memory_stats is to be interpreted as the
> >> integer multiplier of a 10-power of 2, so 1 would give us size in Kib and 2
> >> in Mib. If we want drm-file functions to pick the highest unit, then 0
> >> should be passed.
> >>
> >> Signed-off-by: Adrián Larumbe 
> >> ---
> >>  drivers/gpu/drm/drm_file.c  | 22 +-
> >>  drivers/gpu/drm/msm/msm_drv.c   |  2 +-
> >>  drivers/gpu/drm/panfrost/panfrost_drv.c |  2 +-
> >>  include/drm/drm_file.h  |  5 +++--
> >>  4 files changed, 18 insertions(+), 13 deletions(-)
> >>
> >> diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c
> >> index 762965e3d503..517e1fb8072a 100644
> >> --- a/drivers/gpu/drm/drm_file.c
> >> +++ b/drivers/gpu/drm/drm_file.c
> >> @@ -873,7 +873,7 @@ void drm_send_event(struct drm_device *dev, struct 
> >> drm_pending_event *e)
> >>  EXPORT_SYMBOL(drm_send_event);
> >>
> >>  static void print_size(struct drm_printer *p, const char *stat,
> >> -  const char *region, u64 sz)
> >> +  const char *region, u64 sz, unsigned int unit)
> >>  {
> >> const char *units[] = {"", " KiB", " MiB"};
> >> unsigned u;
> >> @@ -881,6 +881,8 @@ static void print_size(struct drm_printer *p, const 
> >> char *stat,
> >> for (u = 0; u < ARRAY_SIZE(units) - 1; u++) {
> >> if (sz < SZ_1K)
> >> break;
> >> +   if (unit > 0 && unit == u)
> >> +   break;
> >> sz = div_u64(sz, SZ_1K);
> >> }
> >>
> >> @@ -898,17 +900,18 @@ static void print_size(struct drm_printer *p, const 
> >> char *stat,
> >>  void drm_print_memory_stats(struct drm_printer *p,
> >> const struct drm_memory_stats *stats,
> >> enum drm_gem_object_status supported_status,
> >> -   const char *region)
> >> +   const char *region,
> >> +   unsigned int unit)
> >
> >I'm not really adverse to changing what units we use.. or perhaps
> >changing the threshold to go to higher units to be 1x or 10x
> >of the previous unit.  But I'm less excited about having different
> >drivers using different units.
> >
> >BR,
> >-R
>
> Would it be alright if I left it set to the default unit, and allow changing 
> it
> at runtime with a debugfs file?

I suppose we could, but it does seem a bit like overkill.  OTOH I
think it would make sense to increase the threshold, ie. switch to MiB
after 10MiB instead of 1MiB.. at that point the fractional component
is less significant..

BR,
-R

> >>  {
> >> -   print_size(p, "total", region, stats->private + stats->shared);
> >> -   print_size(p, "shared", region, stats->shared);
> >> -   print_size(p, "active", region, stats->active);
> >> +   print_size(p, "total", region, stats->private + stats->shared, 
> >> unit);
> >> +   print_size(p, "shared", region, stats->shared, unit);
> >> +   print_size(p, "active", region, stats->active, unit);
> >>
> >> if (supported_status & DRM_GEM_OBJECT_RESIDENT)
> >> -   print_size(p, "resident", region, stats->resident);
> >> +   print_size(p, "resident", region, stats->resident, unit);
> >>
> >> if (supported_status & DRM_GEM_OBJECT_PURGEABLE)
> >> -   print_size(p, "purgeable", region, stats->purgeable);
> >> +   print_size(p, "purgeable", region, stats->purgeable, unit);
> >>  }
> >>  EXPORT_SYMBOL(drm_print_memory_stats);
> >>
> >> @@ -916,11 +919,12 @@ EXPORT_SYMBOL(drm_print_memory_stats);
> >>   * drm_show_memory_stats - Helper to collect and show standard fdinfo 
> >> memory stats
> >>   * @p: the printer to print output to
> >>   * @file: the DRM file
> >> + * @unit: multipliyer of power of two exponent of desired unit
> >>   *
> >>   * Helper to iterate over GEM objects with a handle allocated in the 
> >> specified
> >>   * file.
> >>   */
> >> -void drm_show_memory_stats(struct drm_printer *p, struct drm_file *file)
> >> +void drm_show_memory_stats(struct drm_printer *p, struct drm_file *file, 
> >> unsigned int unit)
> >>  {
> >> struct drm_gem_object *obj;
> >> struct drm_memory_stats status = {};
> >> @@ -967,7 +971,7 @@ void drm_show_memory_stats(struct drm_printer *p, 
> >> struct drm_file *file)
> >> }
> >> spin_unlock(&file->table_lock);
> >>
> >> -   drm_print_memory_stats(p, &status, supported_status, "memory");
> >> +   drm_print_memory_stats(p, &status, supported_status, "memory", 
> >> unit);
> >>  }
> >>  EXPORT_SYMBOL(drm_show_

Re: [PATCH 7/7] drm/msm/dp: Remove dp_display_is_ds_bridge()

2023-09-05 Thread Stephen Boyd
Quoting Dmitry Baryshkov (2023-09-03 15:40:49)
> On 29/08/2023 21:47, Stephen Boyd wrote:
> > This function is simply drm_dp_is_branch() so use that instead of
> > open-coding it.
> >
> > Cc: Vinod Polimera 
> > Cc: Kuogee Hsieh 
> > Signed-off-by: Stephen Boyd 
> > ---
> >   drivers/gpu/drm/msm/dp/dp_display.c | 9 +
> >   1 file changed, 1 insertion(+), 8 deletions(-)
>
> Reviewed-by: Dmitry Baryshkov 

Thanks.

>
> >
> > diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
> > b/drivers/gpu/drm/msm/dp/dp_display.c
> > index 76f13954015b..96bbf6fec2f1 100644
> > --- a/drivers/gpu/drm/msm/dp/dp_display.c
> > +++ b/drivers/gpu/drm/msm/dp/dp_display.c
> > @@ -341,19 +341,12 @@ static const struct component_ops dp_display_comp_ops 
> > = {
> >   .unbind = dp_display_unbind,
> >   };
> >
> > -static bool dp_display_is_ds_bridge(struct dp_panel *panel)
> > -{
> > - return (panel->dpcd[DP_DOWNSTREAMPORT_PRESENT] &
> > - DP_DWN_STRM_PORT_PRESENT);
> > -}
> > -
> >   static bool dp_display_is_sink_count_zero(struct dp_display_private *dp)
>
> Nit: you might as well inline this function

Ok. I'll send a followup to this series with a patch for that. I found
that with an Apple dongle it always prints out a message to the kernel
log when I have HDMI disconnected that there isn't a sink connected,
which is annoying.

So at least two more patches are incoming.


[PATCH v3 2/2] drm/v3d: Expose the total GPU usage stats on sysfs

2023-09-05 Thread Maíra Canal
The previous patch exposed the accumulated amount of active time per
client for each V3D queue. But this doesn't provide a global notion of
the GPU usage.

Therefore, provide the accumulated amount of active time for each V3D
queue (BIN, RENDER, CSD, TFU and CACHE_CLEAN), considering all the jobs
submitted to the queue, independent of the client.

This data is exposed through the sysfs interface, so that if the
interface is queried at two different points of time the usage percentage
of each of the queues can be calculated.

Co-developed-by: Jose Maria Casanova Crespo 
Signed-off-by: Jose Maria Casanova Crespo 
Signed-off-by: Maíra Canal 
---
 drivers/gpu/drm/v3d/Makefile|  3 +-
 drivers/gpu/drm/v3d/v3d_drv.c   |  9 +
 drivers/gpu/drm/v3d/v3d_drv.h   |  8 
 drivers/gpu/drm/v3d/v3d_gem.c   |  6 ++-
 drivers/gpu/drm/v3d/v3d_irq.c   | 28 +
 drivers/gpu/drm/v3d/v3d_sched.c | 15 ++-
 drivers/gpu/drm/v3d/v3d_sysfs.c | 69 +
 7 files changed, 135 insertions(+), 3 deletions(-)
 create mode 100644 drivers/gpu/drm/v3d/v3d_sysfs.c

diff --git a/drivers/gpu/drm/v3d/Makefile b/drivers/gpu/drm/v3d/Makefile
index e8b314137020..4b21b20e4998 100644
--- a/drivers/gpu/drm/v3d/Makefile
+++ b/drivers/gpu/drm/v3d/Makefile
@@ -11,7 +11,8 @@ v3d-y := \
v3d_mmu.o \
v3d_perfmon.o \
v3d_trace_points.o \
-   v3d_sched.o
+   v3d_sched.o \
+   v3d_sysfs.o

 v3d-$(CONFIG_DEBUG_FS) += v3d_debugfs.o

diff --git a/drivers/gpu/drm/v3d/v3d_drv.c b/drivers/gpu/drm/v3d/v3d_drv.c
index 5003c9ef1914..c7d22952b3ae 100644
--- a/drivers/gpu/drm/v3d/v3d_drv.c
+++ b/drivers/gpu/drm/v3d/v3d_drv.c
@@ -315,8 +315,14 @@ static int v3d_platform_drm_probe(struct platform_device 
*pdev)
if (ret)
goto irq_disable;

+   ret = v3d_sysfs_init(dev);
+   if (ret)
+   goto drm_unregister;
+
return 0;

+drm_unregister:
+   drm_dev_unregister(drm);
 irq_disable:
v3d_irq_disable(v3d);
 gem_destroy:
@@ -330,6 +336,9 @@ static void v3d_platform_drm_remove(struct platform_device 
*pdev)
 {
struct drm_device *drm = platform_get_drvdata(pdev);
struct v3d_dev *v3d = to_v3d_dev(drm);
+   struct device *dev = &pdev->dev;
+
+   v3d_sysfs_destroy(dev);

drm_dev_unregister(drm);

diff --git a/drivers/gpu/drm/v3d/v3d_drv.h b/drivers/gpu/drm/v3d/v3d_drv.h
index 7f2897e5b2cb..adebcdde4ebd 100644
--- a/drivers/gpu/drm/v3d/v3d_drv.h
+++ b/drivers/gpu/drm/v3d/v3d_drv.h
@@ -38,6 +38,10 @@ struct v3d_queue_state {

u64 fence_context;
u64 emit_seqno;
+
+   u64 start_ns;
+   u64 enabled_ns;
+   u64 jobs_sent;
 };

 /* Performance monitor object. The perform lifetime is controlled by userspace
@@ -441,3 +445,7 @@ int v3d_perfmon_destroy_ioctl(struct drm_device *dev, void 
*data,
  struct drm_file *file_priv);
 int v3d_perfmon_get_values_ioctl(struct drm_device *dev, void *data,
 struct drm_file *file_priv);
+
+/* v3d_sysfs.c */
+int v3d_sysfs_init(struct device *dev);
+void v3d_sysfs_destroy(struct device *dev);
diff --git a/drivers/gpu/drm/v3d/v3d_gem.c b/drivers/gpu/drm/v3d/v3d_gem.c
index 40ed0c7c3fad..da6376909e10 100644
--- a/drivers/gpu/drm/v3d/v3d_gem.c
+++ b/drivers/gpu/drm/v3d/v3d_gem.c
@@ -1014,8 +1014,12 @@ v3d_gem_init(struct drm_device *dev)
u32 pt_size = 4096 * 1024;
int ret, i;

-   for (i = 0; i < V3D_MAX_QUEUES; i++)
+   for (i = 0; i < V3D_MAX_QUEUES; i++) {
v3d->queue[i].fence_context = dma_fence_context_alloc(1);
+   v3d->queue[i].start_ns = 0;
+   v3d->queue[i].enabled_ns = 0;
+   v3d->queue[i].jobs_sent = 0;
+   }

spin_lock_init(&v3d->mm_lock);
spin_lock_init(&v3d->job_lock);
diff --git a/drivers/gpu/drm/v3d/v3d_irq.c b/drivers/gpu/drm/v3d/v3d_irq.c
index c724f65058f4..622111e613e3 100644
--- a/drivers/gpu/drm/v3d/v3d_irq.c
+++ b/drivers/gpu/drm/v3d/v3d_irq.c
@@ -102,10 +102,17 @@ v3d_irq(int irq, void *arg)
struct v3d_fence *fence =
to_v3d_fence(v3d->bin_job->base.irq_fence);
struct v3d_file_priv *file = 
v3d->bin_job->base.file->driver_priv;
+   u64 runtime = local_clock() - file->start_ns[V3D_BIN];

file->enabled_ns[V3D_BIN] += local_clock() - 
file->start_ns[V3D_BIN];
file->jobs_sent[V3D_BIN]++;
+   v3d->queue[V3D_BIN].jobs_sent++;
+
file->start_ns[V3D_BIN] = 0;
+   v3d->queue[V3D_BIN].start_ns = 0;
+
+   file->enabled_ns[V3D_BIN] += runtime;
+   v3d->queue[V3D_BIN].enabled_ns += runtime;

trace_v3d_bcl_irq(&v3d->drm, fence->seqno);
dma_fence_signal(&fence->base);
@@ -116,10 +123,17 @@ v3d_irq(int irq, void *arg)
struct v3d_fence *fence =
to_v3d_fence(v3d->render

[PATCH v3 0/2] drm/v3d: Expose GPU usage stats

2023-09-05 Thread Maíra Canal
This patchset exposes GPU usages stats both globally and per-file
descriptor.

The first patch exposes the accumulated amount of active time per client
through the fdinfo infrastructure. The amount of active time is exposed
for each V3D queue. Moreover, it exposes the number of jobs submitted to
each queue.

The second patch exposes the accumulated amount of active time for each
V3D queue, independent of the client. This data is exposed through the
sysfs interface.

With these patches, it is possible to calculate the GPU usage percentage
per queue globally and per-file descriptor.

* Example fdinfo output:

$ cat /proc/1140/fdinfo/4
pos:0
flags:  0242
mnt_id: 24
ino:209
drm-driver: v3d
drm-client-id:  44
drm-engine-bin: 1661076898 ns
v3d-jobs-bin:   19576 jobs
drm-engine-render:  31469427170 ns
v3d-jobs-render:19575 jobs
drm-engine-tfu: 5002964 ns
v3d-jobs-tfu:   13 jobs
drm-engine-csd: 188038329691 ns
v3d-jobs-csd:   250393 jobs
drm-engine-cache_clean: 27736024038 ns
v3d-jobs-cache_clean:   250392 job

* Example gputop output:

DRM minor 128
 PID bin   render   tfucsd  
  cache_clean NAME
1140 |▎||██▋   || ||█▍  
 ||█▋   | computecloth
1158 |▍||▉ || ||
 || | gears
1002 |▏||█▎|| ||
 || | chromium-browse

Best Regards,
- Maíra

---

v1 -> v2: 
https://lore.kernel.org/dri-devel/20230727142929.1275149-1-mca...@igalia.com/T/

* Use sysfs to expose global GPU stats (Tvrtko Ursulin)

v2 -> v3: 
https://lore.kernel.org/dri-devel/20230807211849.49867-1-mca...@igalia.com/T/

* Document the expected behavior in case of a GPU reset (Melissa Wen)
* Add a brief description about the sysfs outputs (Melissa Wen)
* Instead of having multiple sysfs files, use only one sysfs file,
  called gpu_stats, with all the information (Chema Casanova)
* Add the number of jobs submitted in the global GPU stats (Chema Casanova)
* Now, the number of jobs submitted is only incremented if the job was
  completed

Maíra Canal (2):
  drm/v3d: Implement show_fdinfo() callback for GPU usage stats
  drm/v3d: Expose the total GPU usage stats on sysfs

 drivers/gpu/drm/v3d/Makefile|  3 +-
 drivers/gpu/drm/v3d/v3d_drv.c   | 45 -
 drivers/gpu/drm/v3d/v3d_drv.h   | 31 +++
 drivers/gpu/drm/v3d/v3d_gem.c   |  7 +++-
 drivers/gpu/drm/v3d/v3d_irq.c   | 49 +++
 drivers/gpu/drm/v3d/v3d_sched.c | 33 
 drivers/gpu/drm/v3d/v3d_sysfs.c | 69 +
 7 files changed, 234 insertions(+), 3 deletions(-)
 create mode 100644 drivers/gpu/drm/v3d/v3d_sysfs.c

--
2.41.0



[PATCH v3 1/2] drm/v3d: Implement show_fdinfo() callback for GPU usage stats

2023-09-05 Thread Maíra Canal
This patch exposes the accumulated amount of active time per client
through the fdinfo infrastructure. The amount of active time is exposed
for each V3D queue: BIN, RENDER, CSD, TFU and CACHE_CLEAN.

In order to calculate the amount of active time per client, a CPU clock
is used through the function local_clock(). The point where the jobs has
started is marked and is finally compared with the time that the job had
finished.

Moreover, the number of jobs submitted to each queue is also exposed on
fdinfo through the identifier "v3d-jobs-".

Co-developed-by: Jose Maria Casanova Crespo 
Signed-off-by: Jose Maria Casanova Crespo 
Signed-off-by: Maíra Canal 
---
 drivers/gpu/drm/v3d/v3d_drv.c   | 36 -
 drivers/gpu/drm/v3d/v3d_drv.h   | 23 +
 drivers/gpu/drm/v3d/v3d_gem.c   |  1 +
 drivers/gpu/drm/v3d/v3d_irq.c   | 21 +++
 drivers/gpu/drm/v3d/v3d_sched.c | 20 ++
 5 files changed, 100 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/v3d/v3d_drv.c b/drivers/gpu/drm/v3d/v3d_drv.c
index ffbbe9d527d3..5003c9ef1914 100644
--- a/drivers/gpu/drm/v3d/v3d_drv.c
+++ b/drivers/gpu/drm/v3d/v3d_drv.c
@@ -19,6 +19,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include 
@@ -111,6 +112,10 @@ v3d_open(struct drm_device *dev, struct drm_file *file)
v3d_priv->v3d = v3d;
 
for (i = 0; i < V3D_MAX_QUEUES; i++) {
+   v3d_priv->enabled_ns[i] = 0;
+   v3d_priv->start_ns[i] = 0;
+   v3d_priv->jobs_sent[i] = 0;
+
sched = &v3d->queue[i].sched;
drm_sched_entity_init(&v3d_priv->sched_entity[i],
  DRM_SCHED_PRIORITY_NORMAL, &sched,
@@ -136,7 +141,35 @@ v3d_postclose(struct drm_device *dev, struct drm_file 
*file)
kfree(v3d_priv);
 }
 
-DEFINE_DRM_GEM_FOPS(v3d_drm_fops);
+static void v3d_show_fdinfo(struct drm_printer *p, struct drm_file *file)
+{
+   struct v3d_file_priv *file_priv = file->driver_priv;
+   u64 timestamp = local_clock();
+   enum v3d_queue queue;
+
+   for (queue = 0; queue < V3D_MAX_QUEUES; queue++) {
+   /* Note that, in case of a GPU reset, the time spent during an
+* attempt of executing the job is not computed in the runtime.
+*/
+   drm_printf(p, "drm-engine-%s: \t%llu ns\n",
+  v3d_queue_to_string(queue),
+  file_priv->start_ns[queue] ? 
file_priv->enabled_ns[queue]
+ + timestamp - 
file_priv->start_ns[queue]
+ : 
file_priv->enabled_ns[queue]);
+
+   /* Note that we only count jobs that completed. Therefore, jobs
+* that were resubmitted due to a GPU reset are not computed.
+*/
+   drm_printf(p, "v3d-jobs-%s: \t%llu jobs\n",
+  v3d_queue_to_string(queue), 
file_priv->jobs_sent[queue]);
+   }
+}
+
+static const struct file_operations v3d_drm_fops = {
+   .owner = THIS_MODULE,
+   DRM_GEM_FOPS,
+   .show_fdinfo = drm_show_fdinfo,
+};
 
 /* DRM_AUTH is required on SUBMIT_CL for now, while we don't have GMP
  * protection between clients.  Note that render nodes would be
@@ -176,6 +209,7 @@ static const struct drm_driver v3d_drm_driver = {
.ioctls = v3d_drm_ioctls,
.num_ioctls = ARRAY_SIZE(v3d_drm_ioctls),
.fops = &v3d_drm_fops,
+   .show_fdinfo = v3d_show_fdinfo,
 
.name = DRIVER_NAME,
.desc = DRIVER_DESC,
diff --git a/drivers/gpu/drm/v3d/v3d_drv.h b/drivers/gpu/drm/v3d/v3d_drv.h
index 7f664a4b2a75..7f2897e5b2cb 100644
--- a/drivers/gpu/drm/v3d/v3d_drv.h
+++ b/drivers/gpu/drm/v3d/v3d_drv.h
@@ -21,6 +21,18 @@ struct reset_control;
 
 #define V3D_MAX_QUEUES (V3D_CACHE_CLEAN + 1)
 
+static inline char *v3d_queue_to_string(enum v3d_queue queue)
+{
+   switch (queue) {
+   case V3D_BIN: return "bin";
+   case V3D_RENDER: return "render";
+   case V3D_TFU: return "tfu";
+   case V3D_CSD: return "csd";
+   case V3D_CACHE_CLEAN: return "cache_clean";
+   }
+   return "UNKNOWN";
+}
+
 struct v3d_queue_state {
struct drm_gpu_scheduler sched;
 
@@ -167,6 +179,12 @@ struct v3d_file_priv {
} perfmon;
 
struct drm_sched_entity sched_entity[V3D_MAX_QUEUES];
+
+   u64 start_ns[V3D_MAX_QUEUES];
+
+   u64 enabled_ns[V3D_MAX_QUEUES];
+
+   u64 jobs_sent[V3D_MAX_QUEUES];
 };
 
 struct v3d_bo {
@@ -238,6 +256,11 @@ struct v3d_job {
 */
struct v3d_perfmon *perfmon;
 
+   /* File descriptor of the process that submitted the job that could be 
used
+* for collecting stats by process of GPU usage.
+*/
+   struct drm_file *file;
+
/* Callback for the freeing of the job on refcount going to 0. */
void (*free)(struct kref *ref);
 };
diff 

[PATCH v2 2/2] drm/tests: Add new format conversion tests to better cover drm_fb_blit()

2023-09-05 Thread Arthur Grillo
To fully cover drm_fb_blit(), add format conversion tests that are only
supported through drm_fb_blit().

Signed-off-by: Arthur Grillo 
---
 drivers/gpu/drm/tests/drm_format_helper_test.c | 142 +
 1 file changed, 142 insertions(+)

diff --git a/drivers/gpu/drm/tests/drm_format_helper_test.c 
b/drivers/gpu/drm/tests/drm_format_helper_test.c
index b888f7334510..889287245b1e 100644
--- a/drivers/gpu/drm/tests/drm_format_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_format_helper_test.c
@@ -81,6 +81,16 @@ struct fb_swab_result {
const u32 expected[TEST_BUF_SIZE];
 };
 
+struct convert_to_xbgr_result {
+   unsigned int dst_pitch;
+   const u32 expected[TEST_BUF_SIZE];
+};
+
+struct convert_to_abgr_result {
+   unsigned int dst_pitch;
+   const u32 expected[TEST_BUF_SIZE];
+};
+
 struct convert_xrgb_case {
const char *name;
unsigned int pitch;
@@ -98,6 +108,8 @@ struct convert_xrgb_case {
struct convert_to_argb2101010_result argb2101010_result;
struct convert_to_mono_result mono_result;
struct fb_swab_result swab_result;
+   struct convert_to_xbgr_result xbgr_result;
+   struct convert_to_abgr_result abgr_result;
 };
 
 static struct convert_xrgb_case convert_xrgb_cases[] = {
@@ -155,6 +167,14 @@ static struct convert_xrgb_case 
convert_xrgb_cases[] = {
.dst_pitch =  TEST_USE_DEFAULT_PITCH,
.expected = { 0xFF01 },
},
+   .xbgr_result = {
+   .dst_pitch =  TEST_USE_DEFAULT_PITCH,
+   .expected = { 0x01FF },
+   },
+   .abgr_result = {
+   .dst_pitch =  TEST_USE_DEFAULT_PITCH,
+   .expected = { 0xFFFF },
+   },
},
{
.name = "single_pixel_clip_rectangle",
@@ -213,6 +233,14 @@ static struct convert_xrgb_case 
convert_xrgb_cases[] = {
.dst_pitch =  TEST_USE_DEFAULT_PITCH,
.expected = { 0xFF10 },
},
+   .xbgr_result = {
+   .dst_pitch =  TEST_USE_DEFAULT_PITCH,
+   .expected = { 0x10FF },
+   },
+   .abgr_result = {
+   .dst_pitch =  TEST_USE_DEFAULT_PITCH,
+   .expected = { 0xFFFF },
+   },
},
{
/* Well known colors: White, black, red, green, blue, magenta,
@@ -343,6 +371,24 @@ static struct convert_xrgb_case 
convert_xrgb_cases[] = {
0x0077, 0x0088,
},
},
+   .xbgr_result = {
+   .dst_pitch =  TEST_USE_DEFAULT_PITCH,
+   .expected = {
+   0x11FF, 0x2200,
+   0x33FF, 0x4400FF00,
+   0x55FF, 0x66FF00FF,
+   0x7700, 0x8800,
+   },
+   },
+   .abgr_result = {
+   .dst_pitch =  TEST_USE_DEFAULT_PITCH,
+   .expected = {
+   0x, 0xFF00,
+   0xFFFF, 0xFF00FF00,
+   0x, 0x00FF,
+   0xFF00, 0xFF00,
+   },
+   },
},
{
/* Randomly picked colors. Full buffer within the clip area. */
@@ -458,6 +504,22 @@ static struct convert_xrgb_case 
convert_xrgb_cases[] = {
0x0303A8C2, 0x73F06CD2, 0x9C440EA3, 0x, 
0x,
},
},
+   .xbgr_result = {
+   .dst_pitch =  20,
+   .expected = {
+   0xA19C440E, 0xB1054D11, 0xC103F3A8, 0x, 
0x,
+   0xD173F06C, 0xA29C440E, 0xB2054D11, 0x, 
0x,
+   0xC20303A8, 0xD273F06C, 0xA39C440E, 0x, 
0x,
+   },
+   },
+   .abgr_result = {
+   .dst_pitch =  20,
+   .expected = {
+   0xFF9C440E, 0xFF054D11, 0xFF03F3A8, 0x, 
0x,
+   0xFF73F06C, 0xFF9C440E, 0xFF054D11, 0x, 
0x,
+   0xFF0303A8, 0xFF73F06C, 0xFF9C440E, 0x, 
0x,
+   },
+   },
},
 };
 
@@ -1082,6 +1144,84 @@ static void drm_test_fb_swab(struct kunit *test)
KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
 }
 
+st

[PATCH v2 1/2] drm/tests: Add calls to drm_fb_blit() on supported format conversion tests

2023-09-05 Thread Arthur Grillo
Add a call to drm_fb_blit() on existing format conversion tests that
has support.

Signed-off-by: Arthur Grillo 
---
 drivers/gpu/drm/tests/drm_format_helper_test.c | 142 +
 1 file changed, 142 insertions(+)

diff --git a/drivers/gpu/drm/tests/drm_format_helper_test.c 
b/drivers/gpu/drm/tests/drm_format_helper_test.c
index 79bc9d4bbd71..b888f7334510 100644
--- a/drivers/gpu/drm/tests/drm_format_helper_test.c
+++ b/drivers/gpu/drm/tests/drm_format_helper_test.c
@@ -643,6 +643,18 @@ static void drm_test_fb_xrgb_to_rgb565(struct kunit 
*test)
drm_fb_xrgb_to_rgb565(&dst, &result->dst_pitch, &src, &fb, 
¶ms->clip, true);
buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / 
sizeof(__le16));
KUNIT_EXPECT_MEMEQ(test, buf, result->expected_swab, dst_size);
+
+   buf = dst.vaddr;
+   memset(buf, 0, TEST_BUF_SIZE);
+
+   int blit_result = 0;
+
+   blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_RGB565, &src, 
&fb, ¶ms->clip);
+
+   buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / 
sizeof(__le16));
+
+   KUNIT_EXPECT_FALSE(test, blit_result);
+   KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
 }
 
 static void drm_test_fb_xrgb_to_xrgb1555(struct kunit *test)
@@ -677,6 +689,18 @@ static void drm_test_fb_xrgb_to_xrgb1555(struct kunit 
*test)
drm_fb_xrgb_to_xrgb1555(&dst, dst_pitch, &src, &fb, ¶ms->clip);
buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / 
sizeof(__le16));
KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
+
+   buf = dst.vaddr; /* restore original value of buf */
+   memset(buf, 0, TEST_BUF_SIZE);
+
+   int blit_result = 0;
+
+   blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_XRGB1555, &src, 
&fb, ¶ms->clip);
+
+   buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / 
sizeof(__le16));
+
+   KUNIT_EXPECT_FALSE(test, blit_result);
+   KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
 }
 
 static void drm_test_fb_xrgb_to_argb1555(struct kunit *test)
@@ -711,6 +735,18 @@ static void drm_test_fb_xrgb_to_argb1555(struct kunit 
*test)
drm_fb_xrgb_to_argb1555(&dst, dst_pitch, &src, &fb, ¶ms->clip);
buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / 
sizeof(__le16));
KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
+
+   buf = dst.vaddr; /* restore original value of buf */
+   memset(buf, 0, TEST_BUF_SIZE);
+
+   int blit_result = 0;
+
+   blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_ARGB1555, &src, 
&fb, ¶ms->clip);
+
+   buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / 
sizeof(__le16));
+
+   KUNIT_EXPECT_FALSE(test, blit_result);
+   KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
 }
 
 static void drm_test_fb_xrgb_to_rgba5551(struct kunit *test)
@@ -745,6 +781,18 @@ static void drm_test_fb_xrgb_to_rgba5551(struct kunit 
*test)
drm_fb_xrgb_to_rgba5551(&dst, dst_pitch, &src, &fb, ¶ms->clip);
buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / 
sizeof(__le16));
KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
+
+   buf = dst.vaddr; /* restore original value of buf */
+   memset(buf, 0, TEST_BUF_SIZE);
+
+   int blit_result = 0;
+
+   blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_RGBA5551, &src, 
&fb, ¶ms->clip);
+
+   buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / 
sizeof(__le16));
+
+   KUNIT_EXPECT_FALSE(test, blit_result);
+   KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
 }
 
 static void drm_test_fb_xrgb_to_rgb888(struct kunit *test)
@@ -782,6 +830,16 @@ static void drm_test_fb_xrgb_to_rgb888(struct kunit 
*test)
 
drm_fb_xrgb_to_rgb888(&dst, dst_pitch, &src, &fb, ¶ms->clip);
KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
+
+   buf = dst.vaddr; /* restore original value of buf */
+   memset(buf, 0, TEST_BUF_SIZE);
+
+   int blit_result = 0;
+
+   blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_RGB888, &src, 
&fb, ¶ms->clip);
+
+   KUNIT_EXPECT_FALSE(test, blit_result);
+   KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
 }
 
 static void drm_test_fb_xrgb_to_argb(struct kunit *test)
@@ -816,6 +874,18 @@ static void drm_test_fb_xrgb_to_argb(struct kunit 
*test)
drm_fb_xrgb_to_argb(&dst, dst_pitch, &src, &fb, ¶ms->clip);
buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / 
sizeof(u32));
KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
+
+   buf = dst.vaddr; /* restore original value of buf */
+   memset(buf, 0, TEST_BUF_SIZE);
+
+   int blit_result = 0;
+
+   blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_ARGB, &src, 
&fb, ¶ms->c

[PATCH v2 0/2] Add KUnit tests for drm_fb_blit()

2023-09-05 Thread Arthur Grillo
This patchset tests the drm_fb_blit() function.

As this function can be used with already tested formats, the first
patch adds calls to drm_fb_blit() on the tests of supported formats.

Some supported formats were not yet covered by the existing tests
because they are only supported by drm_fb_blit(). The second patch
adds those format conversion tests.

Signed-off-by: Arthur Grillo 
---
Changes in v2:
- Split the patch into two (Maíra Canal)
- Link to v1: 
https://lore.kernel.org/r/20230901-final-gsoc-v1-1-e310c7685...@riseup.net

---
Arthur Grillo (2):
  drm/tests: Add calls to drm_fb_blit() on supported format conversion tests
  drm/tests: Add new format conversion tests to better cover drm_fb_blit()

 drivers/gpu/drm/tests/drm_format_helper_test.c | 284 +
 1 file changed, 284 insertions(+)
---
base-commit: f45acf7acf75921c0409d452f0165f51a19a74fd
change-id: 20230901-final-gsoc-395a84443c8f

Best regards,
-- 
Arthur Grillo 



Re: [RFT PATCH 1/6] drm/atomic-helper: drm_atomic_helper_shutdown(NULL) should be a noop

2023-09-05 Thread Doug Anderson
Hi,

On Mon, Sep 4, 2023 at 12:55 AM Maxime Ripard  wrote:
>
> On Fri, 1 Sep 2023 16:39:52 -0700, Douglas Anderson wrote:
> > As with other places in the Linux kernel--kfree(NULL) being the most
> > famous example--it's convenient to treat being passed a NULL argument
> > as a noop in cleanup functions. Let's make
> > drm_atomic_helper_shutdown() work like this.
> >
> >
> > [ ... ]
>
> Acked-by: Maxime Ripard 

Thanks! If there are no objections, I'd tend to land this patch
sometime early next week just to get it out of the queue, even if
other patches in the series are still being discussed / need spinning.
If anyone objects to that idea, please shout.

-Doug


Re: [RFT PATCH 15/15] drm/renesas/shmobile: Call drm_helper_force_disable_all() at shutdown/remove time

2023-09-05 Thread Doug Anderson
Hi,

On Mon, Sep 4, 2023 at 12:28 AM Geert Uytterhoeven  wrote:
>
> Hi Douglas,
>
> On Sat, Sep 2, 2023 at 1:42 AM Douglas Anderson  wrote:
> > Based on grepping through the source code, this driver appears to be
> > missing a call to drm_atomic_helper_shutdown(), or in this case the
> > non-atomic equivalent drm_helper_force_disable_all(), at system
> > shutdown time and at driver remove time. This is important because
> > drm_helper_force_disable_all() will cause panels to get disabled
> > cleanly which may be important for their power sequencing. Future
> > changes will remove any custom powering off in individual panel
> > drivers so the DRM drivers need to start getting this right.
> >
> > The fact that we should call drm_atomic_helper_shutdown(), or in this
> > case the non-atomic equivalent drm_helper_force_disable_all(), in the
> > case of OS shutdown/restart comes straight out of the kernel doc
> > "driver instance overview" in drm_drv.c.
> >
> > Suggested-by: Maxime Ripard 
> > Signed-off-by: Douglas Anderson 
>
> Thanks for your patch!
>
> > --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> > +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
> > @@ -179,12 +180,20 @@ static int shmob_drm_remove(struct platform_device 
> > *pdev)
> >
> > drm_dev_unregister(ddev);
> > drm_kms_helper_poll_fini(ddev);
> > +   drm_helper_force_disable_all(ddev);
>
> After "[PATCH v3 36/41] drm: renesas: shmobile: Atomic conversion part
> 1"[1], this function will already call drm_atomic_helper_shutdown()...
>
> > free_irq(sdev->irq, ddev);
> > drm_dev_put(ddev);
> >
> > return 0;
> >  }
> >
> > +static void shmob_drm_shutdown(struct platform_device *pdev)
> > +{
> > +   struct shmob_drm_device *sdev = platform_get_drvdata(pdev);
> > +
> > +   drm_helper_force_disable_all(sdev->ddev);
>
> ... and this should be replaced by a call to drm_atomic_helper_shutdown().
>
> [1] 
> https://lore.kernel.org/dri-devel/fd7a6702490bd431f314d6591551bb39e77e3304.1692178020.git.geert+rene...@glider.be

Ah, thanks! I will put this patch on hold and check back in a few
weeks to see how things are looking. If you wanted to fold it into
your series I certainly wouldn't object to it, but if not that's fine
too. ;-)

-Doug


Re: [RFC PATCH 3/3] drm/virtio: drm_gem_plane_helper_prepare_fb for obj synchronization

2023-09-05 Thread Kim, Dongwon

Hi Dmitry,

On 8/31/2023 3:51 PM, Dmitry Osipenko wrote:

On 8/24/23 20:58, Kim, Dongwon wrote:
...

You can do fence-wait in the guest userspace/Mesa after blitting/drawing
to the udmabuf.

There is already synchronization between QEMU and virtio-gpu driver on
the guest. Upon resource flush, virtio-gpu waits for the response for
the message from the QEMU and QEMU sends out the response once rendering
is done. The problem we are seeing is not that the rendering part is
reusing the buffer before it's displayed by the QEMU. Problem we are
facing is more like some frame is often not finished when
"resource-flush" is issued. So unless there is a way for QEMU to wait
for this fence (guest drm), I think we should have some synchronization
point in the guest side.

I saw other DRM drivers, omap, tegra, vc4 and so on are doing the
similar so I guess this is a generic solution for such cases. But I do
understand your concern as the primary use case of virtio-gpu driver is
for virgl. So this extra wait would cost some performance drop. But I
have a couple of points here as well.

1. Wouldn't this extra wait caused by drm_gem_plane_helper_prepare_fb be
minimal as the actual
rendering is done in the host?

2. Can we just make this helper called only if virgl is not used as 3D
driver?

The problem you described above shouldn't be resolved by your patch. You
need to wait for FB to be released by the host's display and not to
before GPU finished rendering on guest. I.e. you're swapping display
buffers and your dGPU starts rendering to the buffer that is in active
use by host's display, correct?


I don't believe the guest will start rendering on the same FB while host is
consuming it because the virtio-gpu driver on the guest won't release the FB 
for the next
frame before it gets the virtio resp for the resource flush command and the 
host (QEMU)
will hold the response until the rendering is finished.

And having this helper clearly fixes the issue we encountered (some old frame is
sometimes shown..). But you might be right. The way I understood the original 
problem
might not be 100% correct as it's based on my assumption on how things were 
fixed
with addition of the helper. Then can you help me to approach to the real 
problem?
If it's really fixed by the helper, then what would the original issue be?



Maybe you need to do glFinish() on host after swapping buffers? But that
will block host for a long time.


I can try glFinish everytime after it draws a frame on the host. But..
If that is the issue, then wouldn't I expect some skipped frames, not old 
frames?


For now I don't have solution.


Virglrender today supports native contexts. The method you're using for
GPU priming was proven to be slow in comparison to multi-gpu native
contexts. There is ongoing work for supporting fence passing from guest
to host [1] that allows to do fence-syncing on host. You'll find links
to the WIP virtio-intel native context in [1] as well. You won't find
GPU priming support using native context in [1], patches hasn't been
published yet.

[1]
https://gitlab.freedesktop.org/virgl/virglrenderer/-/merge_requests/1138

Note that in general it's not acceptable to upstream patches that serve
downstream only. Yours display sync issue is irrelevant to the upstream
stack unless you're going to upstream all the VMM and guest userspace
patches, and in such case you should always publish all the patches and
provide links.

So, you need to check the performance impact and publish all the patches
to the relevant upstream projects.

QEMU has all patches regarding this (blob scanout support) but guest Mesa
patch for KMSRO is still outstanding.

https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9592

I understand this specific patch would need more
discussion/justification but
what about other two, are you generally ok with those in the same series?

The first patch should be dropped. The second one could be useful,


Yes, the first one will be gone. I will upload a revised version of the second 
one
only with proper explanation.


you'll need to provide step-by-step instruction for how to reproduce the
multi-display issue, please write it in the cover-letter for the next
patch version.


Thanks. Always appreciate your feedback!!



Re: [RFT PATCH 2/6] drm: Call drm_atomic_helper_shutdown() at shutdown time for misc drivers

2023-09-05 Thread Jernej Škrabec
Dne sobota, 02. september 2023 ob 01:39:53 CEST je Douglas Anderson 
napisal(a):
> Based on grepping through the source code these drivers appear to be
> missing a call to drm_atomic_helper_shutdown() at system shutdown
> time. Among other things, this means that if a panel is in use that it
> won't be cleanly powered off at system shutdown time.
> 
> The fact that we should call drm_atomic_helper_shutdown() in the case
> of OS shutdown/restart comes straight out of the kernel doc "driver
> instance overview" in drm_drv.c.
> 
> All of the drivers in this patch were fairly straightforward to fix
> since they already had a call to drm_atomic_helper_shutdown() at
> remove/unbind time but were just lacking one at system shutdown. The
> only hitch is that some of these drivers use the component model to
> register/unregister their DRM devices. The shutdown callback is part
> of the original device. The typical solution here, based on how other
> DRM drivers do this, is to keep track of whether the device is bound
> based on drvdata. In most cases the drvdata is the drm_device, so we
> can just make sure it is NULL when the device is not bound. In some
> drivers, this required minor code changes. To make things simpler,
> drm_atomic_helper_shutdown() has been modified to consider a NULL
> drm_device as a noop in the patch ("drm/atomic-helper:
> drm_atomic_helper_shutdown(NULL) should be a noop").
> 
> Suggested-by: Maxime Ripard 
> Signed-off-by: Douglas Anderson 
> ---
> This commit is only compile-time tested.
> 
> Note that checkpatch yells that "drivers/gpu/drm/tiny/cirrus.c" is
> marked as 'obsolete', but it seems silly not to include the fix if
> it's already been written. If someone wants me to take that out,
> though, I can.
> 
>  drivers/gpu/drm/arm/display/komeda/komeda_drv.c | 9 +
>  drivers/gpu/drm/arm/display/komeda/komeda_kms.c | 7 +++
>  drivers/gpu/drm/arm/display/komeda/komeda_kms.h | 1 +
>  drivers/gpu/drm/arm/hdlcd_drv.c | 6 ++
>  drivers/gpu/drm/arm/malidp_drv.c| 6 ++
>  drivers/gpu/drm/ast/ast_drv.c   | 6 ++
>  drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c| 6 ++
>  drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c   | 8 
>  drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c | 6 ++
>  drivers/gpu/drm/hyperv/hyperv_drm_drv.c | 6 ++
>  drivers/gpu/drm/logicvc/logicvc_drm.c   | 9 +
>  drivers/gpu/drm/loongson/lsdc_drv.c | 6 ++
>  drivers/gpu/drm/mcde/mcde_drv.c | 9 +
>  drivers/gpu/drm/omapdrm/omap_drv.c  | 8 
>  drivers/gpu/drm/qxl/qxl_drv.c   | 7 +++
>  drivers/gpu/drm/sti/sti_drv.c   | 7 +++
>  drivers/gpu/drm/sun4i/sun4i_drv.c   | 6 ++

For sun4i:
Tested-by: Jernej Skrabec 
Reviewed-by: Jernej Skrabec 

Best regards,
Jernej

>  drivers/gpu/drm/tiny/bochs.c| 6 ++
>  drivers/gpu/drm/tiny/cirrus.c   | 6 ++
>  19 files changed, 125 insertions(+)





Re: [PATCH 2/2] drm/panel: Add AUO G156HAN04.0 LVDS display support

2023-09-05 Thread Jessica Zhang

Hi Elmar,

Just had a few minor comments:

Looking at past panel-simple changes, I think the prefix here should be 
"drm/panel: simple:"


On 8/28/2023 2:49 AM, Elmar Albert wrote:

From: Elmar Albert 

G156HAN04.0 is a Color Active Matrix Liquid Crystal Display composed of
a TFT LCD panel, a driver circuit, and LED backlight system. The screen
format is intended to supportthe 16:9 FHD, 1920(H) x 1080(V) screen


nit: "support the"


and 16.7M colors (RGB 8-bits ) with LED backlight driving circuit.
All input signals are LVDS interface compatible.

G156HAN04.0 is designed for a display unit of notebook style
personal computer and industrial machine.

Signed-off-by: Elmar Albert 
---
Cc: Conor Dooley 
Cc: Daniel Vetter 
Cc: David Airlie 
Cc: devicet...@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: Krzysztof Kozlowski 
Cc: Neil Armstrong 
Cc: Rob Herring 
Cc: Sam Ravnborg 
Cc: Thierry Reding 
---
  drivers/gpu/drm/panel/panel-simple.c | 36 
  1 file changed, 36 insertions(+)

diff --git a/drivers/gpu/drm/panel/panel-simple.c 
b/drivers/gpu/drm/panel/panel-simple.c
index 52572fde9705..4fe6dafcabf6 100644
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -1050,6 +1050,39 @@ static const struct panel_desc auo_g133han01 = {
.connector_type = DRM_MODE_CONNECTOR_LVDS,
  };
  
+static const struct display_timing auo_g156han04_timings = {

+   .pixelclock = { 13700, 14100, 14600 },
+
+   .hactive = { 1920, 1920, 1920 },
+   .hfront_porch = { 60, 60, 60 },
+   .hback_porch =  { 90, 92, 111 },
+   .hsync_len ={ 32, 32, 32 },
+
+   .vactive = { 1080, 1080, 1080 },
+   .vfront_porch = { 12, 12, 12 },
+   .vback_porch =  { 24, 36, 56 },
+   .vsync_len ={  8,  8,  8 },
+};
+
+static const struct panel_desc auo_g156han04 = {
+   .timings = &auo_g156han04_timings,
+   .num_timings = 1,
+   .bpc = 8,
+   .size = {
+   .width = 344,
+   .height = 194,
+   },
+   .delay = {
+   .prepare = 50,  /* T2 */
+   .enable = 200,  /* T3 */
+   .disable = 110, /* T10 */
+   .unprepare = 1000,  /* T13 */


The inclusion of the comments seems unnecessary.

Thanks,

Jessica Zhang


+   },
+   .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
+   .bus_flags = DRM_BUS_FLAG_DE_HIGH,
+   .connector_type = DRM_MODE_CONNECTOR_LVDS,
+};
+
  static const struct drm_display_mode auo_g156xtn01_mode = {
.clock = 76000,
.hdisplay = 1366,
@@ -4118,6 +4151,9 @@ static const struct of_device_id platform_of_match[] = {
}, {
.compatible = "auo,g133han01",
.data = &auo_g133han01,
+   }, {
+   .compatible = "auo,g156han04",
+   .data = &auo_g156han04,
}, {
.compatible = "auo,g156xtn01",
.data = &auo_g156xtn01,
--
2.34.1



Re: [RFT PATCH 13/15] drm/imx/ipuv3: Call drm_atomic_helper_shutdown() at shutdown/unbind time

2023-09-05 Thread Doug Anderson
Hi,

On Mon, Sep 4, 2023 at 1:30 AM Philipp Zabel  wrote:
>
> On Fr, 2023-09-01 at 16:41 -0700, Douglas Anderson wrote:
> > Based on grepping through the source code this driver appears to be
> > missing a call to drm_atomic_helper_shutdown() at system shutdown time
> > and at driver unbind time. Among other things, this means that if a
> > panel is in use that it won't be cleanly powered off at system
> > shutdown time.
> >
> > The fact that we should call drm_atomic_helper_shutdown() in the case
> > of OS shutdown/restart and at driver remove (or unbind) time comes
> > straight out of the kernel doc "driver instance overview" in
> > drm_drv.c.
> >
> > A few notes about this fix:
> > - When adding drm_atomic_helper_shutdown() to the unbind path, I added
> >   it after drm_kms_helper_poll_fini() since that's when other drivers
> >   seemed to have it.
> > - Technically with a previous patch, ("drm/atomic-helper:
> >   drm_atomic_helper_shutdown(NULL) should be a noop"), we don't
> >   actually need to check to see if our "drm" pointer is NULL before
> >   calling drm_atomic_helper_shutdown(). We'll leave the "if" test in,
> >   though, so that this patch can land without any dependencies. It
> >   could potentially be removed later.
> > - This patch also makes sure to set the drvdata to NULL in the case of
> >   bind errors to make sure that shutdown can't access freed data.
> >
> > Suggested-by: Maxime Ripard 
> > Signed-off-by: Douglas Anderson 
>
> Thank you,
> Tested-by: Philipp Zabel 

Thanks! I notice that:

./scripts/get_maintainer.pl --scm -f drivers/gpu/drm/imx/ipuv3/imx-drm-core.c

Doesn't say drm-misc but also when I look at the MAINTAINERS file and
find the section for "DRM DRIVERS FOR FREESCALE IMX" it doesn't
explicitly list a different git tree. I guess the "shawnguo" git tree
listed by get_maintainer.pl is just from regex matching?

Would you expect this to go through drm-misc? If so, I'll probably
land it sooner rather than later. I can also post up a patch making it
obvious that "DRM DRIVERS FOR FREESCALE IMX" goes through drm-misc if
you don't object.

Thanks!

-Doug


Re: [PATCH v3 2/5] dt-bindings: display: tegra: nvidia,tegra20-dc: Add parallel RGB output port node

2023-09-05 Thread Maxim Schwalm
Hi Rob,

On 21.08.23 18:14, Rob Herring wrote:
> On Mon, Aug 07, 2023 at 05:35:12PM +0300, Svyatoslav Ryhel wrote:
>> From: Maxim Schwalm 
>>
>> Either this node, which is optional, or the nvidia,panel property can be
>> present.
>>
>> Signed-off-by: Maxim Schwalm 
>> Signed-off-by: Svyatoslav Ryhel 
>> ---
>>  .../display/tegra/nvidia,tegra20-dc.yaml  | 31 +++
>>  1 file changed, 31 insertions(+)
>>
>> diff --git 
>> a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-dc.yaml 
>> b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-dc.yaml
>> index 69be95afd562..102304703062 100644
>> --- a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-dc.yaml
>> +++ b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-dc.yaml
>> @@ -127,6 +127,37 @@ allOf:
>>$ref: /schemas/types.yaml#/definitions/phandle
>>description: phandle of a display panel
>>  
>> +port:
>> +  $ref: /schemas/graph.yaml#/$defs/port-base
>> +  description: Parallel RGB output port
>> +
>> +  properties:
>> +endpoint:
>> +  $ref: /schemas/media/video-interfaces.yaml#
> 
> Just to make sure, what properties are you using from this? Usually 
> we'll list them though not a hard requirement. If none, then you just 
> need to ref graph.yaml#/properties/port instead and can drop the rest.

currently, just bus-width is used in devicetrees, but I don't think that
it is needed at the moment. So perhaps the property can be dropped.

>> +  unevaluatedProperties: false
>> +
>> +  unevaluatedProperties: false
> 
> In the indented cases, it's easier to read if this is before 
> properties/patternProperties.
> 
>> +
>> +  anyOf:
>> +- if:
>> +not:
>> +  properties:
>> +nvidia,panel: false
>> +  then:
>> +not:
>> +  properties:
>> +port: true
>> +- if:
>> +not:
>> +  properties:
>> +port: false
>> +  then:
>> +not:
>> +  properties:
>> +nvidia,panel: true
> 
> I would prefer to drop this and mark "nvidia,panel" as deprecated. 
> Eventually I plan to add a mode to the tools to warn on using deprecated 
> properties. Having both could be perfectly fine too. You have the 
> "nvidia,panel" for compatibility with an old OS version and 'port' to 
> work with newer users.

The reason for adding this was that just one of them can be utilized at
the same time. Having both could potentially break the display output.
I think that all the other nvidia,* properties could marked as
deprecated as well because they don't seem to be doing much since commit
d9f980ebcd01 ("drm/tegra: output: rgb: Wrap directly-connected panel
into DRM bridge").

>> +
>> +  additionalProperties: false
> 
> Move this up too.
> 

Best regards,
Maxim


Re: [RFT PATCH 03/15] drm/ingenic: Call drm_atomic_helper_shutdown() at shutdown time

2023-09-05 Thread Doug Anderson
Paul,

On Mon, Sep 4, 2023 at 2:15 AM Paul Cercueil  wrote:
>
> Hi Douglas,
>
> Le vendredi 01 septembre 2023 à 16:41 -0700, Douglas Anderson a écrit :
> > Based on grepping through the source code this driver appears to be
> > missing a call to drm_atomic_helper_shutdown() at system shutdown
> > time. Among other things, this means that if a panel is in use that
> > it
> > won't be cleanly powered off at system shutdown time.
> >
> > The fact that we should call drm_atomic_helper_shutdown() in the case
> > of OS shutdown/restart comes straight out of the kernel doc "driver
> > instance overview" in drm_drv.c.
> >
> > Since this driver uses the component model and shutdown happens at
> > the
> > base driver, we communicate whether we have to call
> > drm_atomic_helper_shutdown() by seeing if drvdata is non-NULL.
> >
> > Suggested-by: Maxime Ripard 
> > Signed-off-by: Douglas Anderson 
>
> LGTM.
> Acked-by: Paul Cercueil 

Thanks for the Ack! Would you expect this patch to land through
"drm-misc", or do you expect it to go through some other tree?
Running:

./scripts/get_maintainer.pl --scm -f drivers/gpu/drm/ingenic/ingenic-drm-drv.c

...does not show that this driver normally goes through drm-misc, but
it also doesn't show that it goes through any other tree so maybe it's
just an artifact of the way it's tagged in the MAINTAINERS file? If
it's fine for this to go through drm-misc, I'll probably land it (with
your Ack and Maxime's Review) sooner rather than later just to make
this patch series less unwieldy.


> > ---
> > This commit is only compile-time tested.
> >
> > NOTE: this patch touches a lot more than other similar patches since
> > the bind() function is long and we want to make sure that we unset
> > the
> > drvdata if bind() fails.
> >
> > While making this patch, I noticed that the bind() function of this
> > driver is using "devm" and thus assumes it doesn't need to do much
> > explicit error handling. That's actually a bug. As per kernel docs
> > [1]
> > "the lifetime of the aggregate driver does not align with any of the
> > underlying struct device instances. Therefore devm cannot be used and
> > all resources acquired or allocated in this callback must be
> > explicitly released in the unbind callback". Fixing that is outside
> > the scope of this commit.
> >
> > [1] https://docs.kernel.org/driver-api/component.html
> >
>
> Noted, thanks.

FWIW, I think that at least a few other DRM drivers handle this by
doing some of their resource allocation / acquiring in the probe()
function and then only doing things in the bind() that absolutely need
to be in the bind. ;-)


-Doug


Re: [PATCH v2] Documentation/gpu: VM_BIND locking document

2023-09-05 Thread Danilo Krummrich
On Wed, Aug 16, 2023 at 11:15:47AM +0200, Thomas Hellström wrote:
> Add the first version of the VM_BIND locking document which is
> intended to be part of the xe driver upstreaming agreement.
> 
> The document describes and discuss the locking used during exec-
> functions, evicton and for userptr gpu-vmas. Intention is to be using the
> same nomenclature as the drm-vm-bind-async.rst.
> 
> v2:
> - s/gvm/gpu_vm/g (Rodrigo Vivi)
> - Clarify the userptr seqlock with a pointer to mm/mmu_notifier.c
>   (Rodrigo Vivi)
> - Adjust commit message accordingly.
> - Add SPDX license header.
> 
> Cc: Rodrigo Vivi 
> Signed-off-by: Thomas Hellström 
> ---
>  Documentation/gpu/drm-vm-bind-locking.rst | 351 ++
>  1 file changed, 351 insertions(+)
>  create mode 100644 Documentation/gpu/drm-vm-bind-locking.rst
> 
> diff --git a/Documentation/gpu/drm-vm-bind-locking.rst 
> b/Documentation/gpu/drm-vm-bind-locking.rst
> new file mode 100644
> index ..b813961a9ec2
> --- /dev/null
> +++ b/Documentation/gpu/drm-vm-bind-locking.rst
> @@ -0,0 +1,351 @@
> +.. SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +
> +===
> +VM_BIND locking
> +===
> +
> +This document attempts to describe what's needed to get VM_BIND locking 
> right,
> +including the userptr mmu_notifier locking and it will also discuss some
> +optimizations to get rid of the looping through of all userptr mappings and
> +external / shared object mappings that is needed in the simplest
> +implementation. It will also discuss some implications for faulting gpu_vms.
> +
> +Nomenclature
> +
> +
> +* ``Context``: GPU execution context.
> +* ``gpu_vm``: Abstraction of a virtual GPU address space with
> +  meta-data. Typically one per client (DRM file-private), or one per
> +  context.
> +* ``gpu_vma``: Abstraction of a GPU address range within a gpu_vm with

The same nomenclature was used within the VM_BIND async document as well. I
wonder if it would make sense to align the naming with the GPUVA manager, such
that ('drm_gpuva_manager' -> 'drm_gpuvm'). This would also result into better
function names, such as drm_gpuvm_resv_lock() or drm_gpuvm_prepare_objects() and
potentially way better naming for the VM_BO abstraction 'drm_gpuvm_bo'.

However, I'd like to keep 'drm_gpuva' rather than 'drm_gpu_vma', but I think
this is close enough anyway.

> +  associated meta-data. The backing storage of a gpu_vma can either be
> +  a gem buffer object or anonymous pages mapped also into the CPU
> +  address space for the process.
> +* ``userptr gpu_vma or just userptr``: A gpu_vma, the backing store of
> +  which is anonymous pages as described above.
> +* ``revalidating``: Revalidating a gpu_vma means making the latest version
> +  of the backing store resident and making sure the gpu_vma's
> +  page-table entries point to that backing store.
> +* ``dma_fence``: A struct dma_fence that is similar to a struct completion
> +  and which tracks GPU activity. When the GPU activity is finished,
> +  the dma_fence signals.
> +* ``dma_resv``: A struct dma_resv (AKA reservation object) that is used
> +  to track GPU activity in the form of multiple dma_fences on a
> +  gpu_vm or a gem buffer object. The dma_resv contains an array / list
> +  of dma_fences and a lock that needs to be held when adding
> +  additional dma_fences to the dma_resv. The lock is of a type that
> +  allows deadlock-safe locking of multiple dma_resvs in arbitrary order.
> +* ``exec function``: An exec function is a function that revalidates all
> +  affected gpu_vmas, submits a GPU command batch and registers the
> +  dma_fence representing the GPU command's activity with all affected
> +  dma_resvs. For completeness, although not covered by this document,
> +  it's worth mentioning that an exec function may also be the
> +  revalidation worker that is used by some drivers in compute /
> +  long-running mode.
> +* ``local object``: A GEM object which is local to a gpu_vm. Shared gem
> +  objects also share the gpu_vm's dma_resv.
> +* ``shared object``: AKA external object: A GEM object which may be shared
> +  by multiple gpu_vms and whose backing storage may be shared with
> +  other drivers.
> +
> +
> +Introducing the locks
> +=
> +
> +One of the benefits of VM_BIND is that local GEM objects share the gpu_vm's
> +dma_resv object and hence the dma_resv lock. So even with a huge
> +number of local GEM objects, only one lock is needed to make the exec
> +sequence atomic.
> +
> +The following locks and locking orders are used:
> +
> +* The ``gpu_vm->lock`` (optionally an rwsem). Protects how the gpu_vm is
> +  partitioned into gpu_vmas, protects the gpu_vm's list of external objects,
> +  and can also with some simplification protect the gpu_vm's list of
> +  userptr gpu_vmas. With the CPU mm analogy this would correspond to the
> +  mmap_lock.
> +* The ``userptr_seqlock``. This lock is taken in read mode for each
> +  userptr gpu_vma on t

[PATCH] drm/i915/mtl: Drop force_probe requirement

2023-09-05 Thread Radhakrishna Sripada
Meteorlake has been very usable for a while now, all of uapi changes
related to fundamental platform usage have been finalized and all
required firmware blobs are available. Recent CI results have also
been healthy, so we're ready to drop the force_probe requirement and
enable the platform by default.

Cc: Rodrigo Vivi 
Cc: Tvrtko Ursulin 
Cc: Joonas Lahtinen 
Cc: Jani Nikula 
Signed-off-by: Radhakrishna Sripada 
---
 drivers/gpu/drm/i915/i915_pci.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c
index df7c261410f7..fe748906c06f 100644
--- a/drivers/gpu/drm/i915/i915_pci.c
+++ b/drivers/gpu/drm/i915/i915_pci.c
@@ -836,7 +836,6 @@ static const struct intel_device_info mtl_info = {
.has_pxp = 1,
.memory_regions = REGION_SMEM | REGION_STOLEN_LMEM,
.platform_engine_mask = BIT(RCS0) | BIT(BCS0) | BIT(CCS0),
-   .require_force_probe = 1,
MTL_CACHELEVEL,
 };
 
-- 
2.34.1



Re: [PATCH] drm/amd/display: prevent potential division by zero errors

2023-09-05 Thread Aurabindo Pillai




On 2023-09-05 14:53, Hamza Mahfooz wrote:

There are two places in apply_below_the_range() where it's possible for
a divide by zero error to occur. So, to fix this make sure the divisor
is non-zero before attempting the computation in both cases.

Cc: sta...@vger.kernel.org
Link: https://gitlab.freedesktop.org/drm/amd/-/issues/2637
Fixes: a463b263032f ("drm/amd/display: Fix frames_to_insert math")
Fixes: ded6119e825a ("drm/amd/display: Reinstate LFC optimization")
Signed-off-by: Hamza Mahfooz 
---
  drivers/gpu/drm/amd/display/modules/freesync/freesync.c | 9 ++---
  1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c 
b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
index dbd60811f95d..ef3a67409021 100644
--- a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
+++ b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
@@ -338,7 +338,9 @@ static void apply_below_the_range(struct core_freesync 
*core_freesync,
 *  - Delta for CEIL: delta_from_mid_point_in_us_1
 *  - Delta for FLOOR: delta_from_mid_point_in_us_2
 */
-   if ((last_render_time_in_us / mid_point_frames_ceil) < 
in_out_vrr->min_duration_in_us) {
+   if (mid_point_frames_ceil &&
+   (last_render_time_in_us / mid_point_frames_ceil) <
+   in_out_vrr->min_duration_in_us) {
/* Check for out of range.
 * If using CEIL produces a value that is out of range,
 * then we are forced to use FLOOR.
@@ -385,8 +387,9 @@ static void apply_below_the_range(struct core_freesync 
*core_freesync,
/* Either we've calculated the number of frames to insert,
 * or we need to insert min duration frames
 */
-   if (last_render_time_in_us / frames_to_insert <
-   in_out_vrr->min_duration_in_us){
+   if (frames_to_insert &&
+   (last_render_time_in_us / frames_to_insert) <
+   in_out_vrr->min_duration_in_us){
frames_to_insert -= (frames_to_insert > 1) ?
1 : 0;
}



Reviewed-by: Aurabindo Pillai 

--

Thanks & Regards,
Jay


Re: [RFC PATCH 00/10] drm/panel: Remove most store/double-check of prepared/enabled state

2023-09-05 Thread Doug Anderson
Hi,

On Thu, Aug 10, 2023 at 1:23 AM Linus Walleij  wrote:
>
> On Fri, Aug 4, 2023 at 11:07 PM Douglas Anderson  
> wrote:
>
> > As talked about in commit d2aacaf07395 ("drm/panel: Check for already
> > prepared/enabled in drm_panel"), we want to remove needless code from
> > panel drivers that was storing and double-checking the
> > prepared/enabled state. Even if someone was relying on the
> > double-check before, that double-check is now in the core and not
> > needed in individual drivers.
> >
> > This series attempts to do just that. While the original grep, AKA:
> >   git grep 'if.*>prepared' -- drivers/gpu/drm/panel
> >   git grep 'if.*>enabled' -- drivers/gpu/drm/panel
> > ...still produces a few hits after my series, they are _mostly_ all
> > gone. The ones that are left are less trivial to fix.
> >
> > One of the main reasons that many panels probably needed to store and
> > double-check their prepared/enabled appears to have been to handle
> > shutdown and/or remove. Panels drivers often wanted to force the power
> > off for panels in these cases and this was a good reason for the
> > double-check. As part of this series a new helper is added that uses
> > the state tracking that the drm_panel core is doing so each individual
> > panel driver doesn't need to do it.
> >
> > This series changes a lot of drivers and obviously the author can't
> > test on all of them. The changes here are also not completely trivial
> > in all cases. Please double-check your drivers carefully to make sure
> > something wasn't missed. After looking at over 40 drivers I'll admit
> > that my eyes glazed over a little.
> >
> > I've attempted to organize these patches like to group together panels
> > that needed similar handling. Panels that had code that didn't seem to
> > match anyone else got their own patch. I made judgement calls on what
> > I considered "similar".
> >
> > As noted in individual patches, there are some cases here where I
> > expect behavior to change a little bit. I'm hoping these changes are
> > for the better and don't cause any problems. Fingers crossed.
> >
> > I have at least confirmed that "allmodconfig" for arm64 doesn't fall
> > on its face with this series. I haven't done a ton of other testing.
>
> The series:
> Reviewed-by: Linus Walleij 
>
> Please send out a non-RFC version, this is clearly the right thing to
> do.

As per the long discussion in response to patch #4, I think there are
still open questions about the later patches in this series. However,
I could land patches #1 - #3 if there are no concerns. Would anyone
object if I just landed them straight from this series with Linus's
review, or would I need to repost just patches #1 - #3 without the
"RFC" tag?

Thanks!

-Doug


Re: [RFC PATCH 04/10] drm/panel_helper: Introduce drm_panel_helper

2023-09-05 Thread Doug Anderson
Hi,

On Tue, Sep 5, 2023 at 9:45 AM Doug Anderson  wrote:
>
> As per our discussion, in V2 we will make drm_panel_remove() actually
> unprepare / disable a panel if it was left enabled. This would
> essentially fold in the drm_panel_helper_shutdown() from my RFC patch.
> This would make tdo_tl070wsh30_panel_remove() behave the same as it
> did before. Ugh, though I may have to think about this more when I get
> to implementation since I don't think there's a guarantee of the
> ordering of shutdown calls between the DRM driver and the panel.
> Anyway, something to discuss later.

Ugh, ignore the above paragraph. I managed to confuse myself and was
thinking about shutdown but talking about remove. Sigh. :( Instead,
pretend the above paragraph said:

As per our discussion, in V2 we will make drm_panel_remove() actually
unprepare / disable a panel (and print a warning) if it was left
enabled. This would essentially fold in the
drm_panel_helper_shutdown() from my RFC patch (but add a warning).
This would make tdo_tl070wsh30_panel_remove() behave the same as it
did before with the addition of a warning if someone tries to remove a
currently powered panel.

-Doug


[PATCH] drm/amd/display: prevent potential division by zero errors

2023-09-05 Thread Hamza Mahfooz
There are two places in apply_below_the_range() where it's possible for
a divide by zero error to occur. So, to fix this make sure the divisor
is non-zero before attempting the computation in both cases.

Cc: sta...@vger.kernel.org
Link: https://gitlab.freedesktop.org/drm/amd/-/issues/2637
Fixes: a463b263032f ("drm/amd/display: Fix frames_to_insert math")
Fixes: ded6119e825a ("drm/amd/display: Reinstate LFC optimization")
Signed-off-by: Hamza Mahfooz 
---
 drivers/gpu/drm/amd/display/modules/freesync/freesync.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c 
b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
index dbd60811f95d..ef3a67409021 100644
--- a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
+++ b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
@@ -338,7 +338,9 @@ static void apply_below_the_range(struct core_freesync 
*core_freesync,
 *  - Delta for CEIL: delta_from_mid_point_in_us_1
 *  - Delta for FLOOR: delta_from_mid_point_in_us_2
 */
-   if ((last_render_time_in_us / mid_point_frames_ceil) < 
in_out_vrr->min_duration_in_us) {
+   if (mid_point_frames_ceil &&
+   (last_render_time_in_us / mid_point_frames_ceil) <
+   in_out_vrr->min_duration_in_us) {
/* Check for out of range.
 * If using CEIL produces a value that is out of range,
 * then we are forced to use FLOOR.
@@ -385,8 +387,9 @@ static void apply_below_the_range(struct core_freesync 
*core_freesync,
/* Either we've calculated the number of frames to insert,
 * or we need to insert min duration frames
 */
-   if (last_render_time_in_us / frames_to_insert <
-   in_out_vrr->min_duration_in_us){
+   if (frames_to_insert &&
+   (last_render_time_in_us / frames_to_insert) <
+   in_out_vrr->min_duration_in_us){
frames_to_insert -= (frames_to_insert > 1) ?
1 : 0;
}
-- 
2.41.0



[PATCH v3 6/8] drm/drm_file: Add DRM obj's RSS reporting function for fdinfo

2023-09-05 Thread Adrián Larumbe
Some BO's might be mapped onto physical memory chunkwise and on demand,
like Panfrost's tiler heap. In this case, even though the
drm_gem_shmem_object page array might already be allocated, only a very
small fraction of the BO is currently backed by system memory, but
drm_show_memory_stats will then proceed to add its entire virtual size to
the file's total resident size regardless.

This led to very unrealistic RSS sizes being reckoned for Panfrost, where
said tiler heap buffer is initially allocated with a virtual size of 128
MiB, but only a small part of it will eventually be backed by system memory
after successive GPU page faults.

Provide a new DRM object generic function that would allow drivers to
return a more accurate RSS size for their BOs.

Signed-off-by: Adrián Larumbe 
Reviewed-by: Boris Brezillon 
---
 drivers/gpu/drm/drm_file.c | 5 -
 include/drm/drm_gem.h  | 9 +
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c
index 883d83bc0e3d..762965e3d503 100644
--- a/drivers/gpu/drm/drm_file.c
+++ b/drivers/gpu/drm/drm_file.c
@@ -944,7 +944,10 @@ void drm_show_memory_stats(struct drm_printer *p, struct 
drm_file *file)
}
 
if (s & DRM_GEM_OBJECT_RESIDENT) {
-   status.resident += obj->size;
+   if (obj->funcs && obj->funcs->rss)
+   status.resident += obj->funcs->rss(obj);
+   else
+   status.resident += obj->size;
} else {
/* If already purged or not yet backed by pages, don't
 * count it as purgeable:
diff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h
index bc9f6aa2f3fe..16364487fde9 100644
--- a/include/drm/drm_gem.h
+++ b/include/drm/drm_gem.h
@@ -208,6 +208,15 @@ struct drm_gem_object_funcs {
 */
enum drm_gem_object_status (*status)(struct drm_gem_object *obj);
 
+   /**
+* @rss:
+*
+* Return resident size of the object in physical memory.
+*
+* Called by drm_show_memory_stats().
+*/
+   size_t (*rss)(struct drm_gem_object *obj);
+
/**
 * @vm_ops:
 *
-- 
2.42.0



[PATCH v3 8/8] drm/drm-file: Show finer-grained BO sizes in drm_show_memory_stats

2023-09-05 Thread Adrián Larumbe
The current implementation will try to pick the highest available size
display unit as soon as the BO size exceeds that of the previous
multiplier.

By selecting a higher threshold, we could show more accurate size numbers.

Signed-off-by: Adrián Larumbe 
---
 drivers/gpu/drm/drm_file.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c
index 762965e3d503..0b5fbd493e05 100644
--- a/drivers/gpu/drm/drm_file.c
+++ b/drivers/gpu/drm/drm_file.c
@@ -879,7 +879,7 @@ static void print_size(struct drm_printer *p, const char 
*stat,
unsigned u;
 
for (u = 0; u < ARRAY_SIZE(units) - 1; u++) {
-   if (sz < SZ_1K)
+   if (sz < (SZ_1K * 1))
break;
sz = div_u64(sz, SZ_1K);
}
-- 
2.42.0



[PATCH v3 7/8] drm/panfrost: Implement generic DRM object RSS reporting function

2023-09-05 Thread Adrián Larumbe
BO's RSS is updated every time new pages are allocated on demand and mapped
for the object at GPU page fault's IRQ handler, but only for heap buffers.
The reason this is unnecessary for non-heap buffers is that they are mapped
onto the GPU's VA space and backed by physical memory in their entirety at
BO creation time.

This calculation is unnecessary for imported PRIME objects, since heap
buffers cannot be exported by our driver, and the actual BO RSS size is the
one reported in its attached dmabuf structure.

Signed-off-by: Adrián Larumbe 
---
 drivers/gpu/drm/panfrost/panfrost_gem.c | 14 ++
 drivers/gpu/drm/panfrost/panfrost_gem.h |  5 +
 drivers/gpu/drm/panfrost/panfrost_mmu.c | 12 
 3 files changed, 27 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.c 
b/drivers/gpu/drm/panfrost/panfrost_gem.c
index 7d8f83d20539..cb92c0ed7615 100644
--- a/drivers/gpu/drm/panfrost/panfrost_gem.c
+++ b/drivers/gpu/drm/panfrost/panfrost_gem.c
@@ -208,6 +208,19 @@ static enum drm_gem_object_status 
panfrost_gem_status(struct drm_gem_object *obj
return res;
 }
 
+static size_t panfrost_gem_rss(struct drm_gem_object *obj)
+{
+   struct panfrost_gem_object *bo = to_panfrost_bo(obj);
+
+   if (bo->is_heap)
+   return bo->heap_rss_size;
+   else if (bo->base.pages) {
+   WARN_ON(bo->heap_rss_size);
+   return bo->base.base.size;
+   } else
+   return 0;
+}
+
 static const struct drm_gem_object_funcs panfrost_gem_funcs = {
.free = panfrost_gem_free_object,
.open = panfrost_gem_open,
@@ -220,6 +233,7 @@ static const struct drm_gem_object_funcs panfrost_gem_funcs 
= {
.vunmap = drm_gem_shmem_object_vunmap,
.mmap = drm_gem_shmem_object_mmap,
.status = panfrost_gem_status,
+   .rss = panfrost_gem_rss,
.vm_ops = &drm_gem_shmem_vm_ops,
 };
 
diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.h 
b/drivers/gpu/drm/panfrost/panfrost_gem.h
index ad2877eeeccd..13c0a8149c3a 100644
--- a/drivers/gpu/drm/panfrost/panfrost_gem.h
+++ b/drivers/gpu/drm/panfrost/panfrost_gem.h
@@ -36,6 +36,11 @@ struct panfrost_gem_object {
 */
atomic_t gpu_usecount;
 
+   /*
+* Object chunk size currently mapped onto physical memory
+*/
+   size_t heap_rss_size;
+
bool noexec :1;
bool is_heap:1;
 };
diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.c 
b/drivers/gpu/drm/panfrost/panfrost_mmu.c
index d54d4e7b2195..67c206124781 100644
--- a/drivers/gpu/drm/panfrost/panfrost_mmu.c
+++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c
@@ -285,17 +285,19 @@ static void panfrost_mmu_flush_range(struct 
panfrost_device *pfdev,
pm_runtime_put_autosuspend(pfdev->dev);
 }
 
-static int mmu_map_sg(struct panfrost_device *pfdev, struct panfrost_mmu *mmu,
+static size_t mmu_map_sg(struct panfrost_device *pfdev, struct panfrost_mmu 
*mmu,
  u64 iova, int prot, struct sg_table *sgt)
 {
unsigned int count;
struct scatterlist *sgl;
struct io_pgtable_ops *ops = mmu->pgtbl_ops;
u64 start_iova = iova;
+   size_t total = 0;
 
for_each_sgtable_dma_sg(sgt, sgl, count) {
unsigned long paddr = sg_dma_address(sgl);
size_t len = sg_dma_len(sgl);
+   total += len;
 
dev_dbg(pfdev->dev, "map: as=%d, iova=%llx, paddr=%lx, 
len=%zx", mmu->as, iova, paddr, len);
 
@@ -315,7 +317,7 @@ static int mmu_map_sg(struct panfrost_device *pfdev, struct 
panfrost_mmu *mmu,
 
panfrost_mmu_flush_range(pfdev, mmu, start_iova, iova - start_iova);
 
-   return 0;
+   return total;
 }
 
 int panfrost_mmu_map(struct panfrost_gem_mapping *mapping)
@@ -447,6 +449,7 @@ static int panfrost_mmu_map_fault_addr(struct 
panfrost_device *pfdev, int as,
pgoff_t page_offset;
struct sg_table *sgt;
struct page **pages;
+   size_t mapped_size;
 
bomapping = addr_to_mapping(pfdev, as, addr);
if (!bomapping)
@@ -518,10 +521,11 @@ static int panfrost_mmu_map_fault_addr(struct 
panfrost_device *pfdev, int as,
if (ret)
goto err_map;
 
-   mmu_map_sg(pfdev, bomapping->mmu, addr,
-  IOMMU_WRITE | IOMMU_READ | IOMMU_NOEXEC, sgt);
+   mapped_size = mmu_map_sg(pfdev, bomapping->mmu, addr,
+IOMMU_WRITE | IOMMU_READ | IOMMU_NOEXEC, sgt);
 
bomapping->active = true;
+   bo->heap_rss_size += mapped_size;
 
dev_dbg(pfdev->dev, "mapped page fault @ AS%d %llx", as, addr);
 
-- 
2.42.0



[PATCH v3 3/8] drm/panfrost: Enable debugfs toggling of cycle counter register

2023-09-05 Thread Adrián Larumbe
Allow user space to decide whether the cycle counting register should be
enabled. The main goal is letting tools like nvtop or IGT's gputop access
this information in debug builds to obtain engine utilisation numbers.

Signed-off-by: Adrián Larumbe 
---
 drivers/gpu/drm/panfrost/Makefile   |  2 +
 drivers/gpu/drm/panfrost/panfrost_debugfs.c | 51 +
 drivers/gpu/drm/panfrost/panfrost_debugfs.h | 13 ++
 drivers/gpu/drm/panfrost/panfrost_drv.c |  5 ++
 4 files changed, 71 insertions(+)
 create mode 100644 drivers/gpu/drm/panfrost/panfrost_debugfs.c
 create mode 100644 drivers/gpu/drm/panfrost/panfrost_debugfs.h

diff --git a/drivers/gpu/drm/panfrost/Makefile 
b/drivers/gpu/drm/panfrost/Makefile
index 7da2b3f02ed9..2c01c1e7523e 100644
--- a/drivers/gpu/drm/panfrost/Makefile
+++ b/drivers/gpu/drm/panfrost/Makefile
@@ -12,4 +12,6 @@ panfrost-y := \
panfrost_perfcnt.o \
panfrost_dump.o
 
+panfrost-$(CONFIG_DEBUG_FS) += panfrost_debugfs.o
+
 obj-$(CONFIG_DRM_PANFROST) += panfrost.o
diff --git a/drivers/gpu/drm/panfrost/panfrost_debugfs.c 
b/drivers/gpu/drm/panfrost/panfrost_debugfs.c
new file mode 100644
index ..48d5ddfcb1c6
--- /dev/null
+++ b/drivers/gpu/drm/panfrost/panfrost_debugfs.c
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright 2023 Collabora ltd. */
+
+#include 
+#include 
+#include 
+#include 
+
+#include "panfrost_device.h"
+#include "panfrost_gpu.h"
+#include "panfrost_debugfs.h"
+
+static int
+profile_get(void *data, u64 *val)
+{
+   struct drm_device *dev = data;
+   struct panfrost_device *pfdev = dev->dev_private;
+
+   *val = atomic_read(&pfdev->profile_mode);
+
+   return 0;
+}
+
+static int
+profile_set(void *data, u64 val)
+{
+   struct drm_device *dev = data;
+   struct panfrost_device *pfdev = dev->dev_private;
+
+   if (atomic_read(&pfdev->profile_mode) == val)
+   return 0;
+
+   if (val == false)
+   panfrost_cycle_counter_stop(pfdev);
+   else
+   atomic_set(&pfdev->profile_mode, 1);
+
+   return 0;
+}
+
+DEFINE_DEBUGFS_ATTRIBUTE(profile_fops,
+profile_get, profile_set,
+"%llu\n");
+
+void panfrost_debugfs_init(struct drm_minor *minor)
+{
+   struct drm_device *dev = minor->dev;
+
+   debugfs_create_file("profile", 0600, minor->debugfs_root,
+   dev, &profile_fops);
+}
diff --git a/drivers/gpu/drm/panfrost/panfrost_debugfs.h 
b/drivers/gpu/drm/panfrost/panfrost_debugfs.h
new file mode 100644
index ..db1c158bcf2f
--- /dev/null
+++ b/drivers/gpu/drm/panfrost/panfrost_debugfs.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2023 Collabora ltd.
+ */
+
+#ifndef PANFROST_DEBUGFS_H
+#define PANFROST_DEBUGFS_H
+
+#ifdef CONFIG_DEBUG_FS
+void panfrost_debugfs_init(struct drm_minor *minor);
+#endif
+
+#endif  /* PANFROST_DEBUGFS_H */
diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c 
b/drivers/gpu/drm/panfrost/panfrost_drv.c
index a2ab99698ca8..2dfd9f79a31b 100644
--- a/drivers/gpu/drm/panfrost/panfrost_drv.c
+++ b/drivers/gpu/drm/panfrost/panfrost_drv.c
@@ -20,6 +20,7 @@
 #include "panfrost_job.h"
 #include "panfrost_gpu.h"
 #include "panfrost_perfcnt.h"
+#include "panfrost_debugfs.h"
 
 static bool unstable_ioctls;
 module_param_unsafe(unstable_ioctls, bool, 0600);
@@ -546,6 +547,10 @@ static const struct drm_driver panfrost_drm_driver = {
 
.gem_create_object  = panfrost_gem_create_object,
.gem_prime_import_sg_table = panfrost_gem_prime_import_sg_table,
+
+#ifdef CONFIG_DEBUG_FS
+   .debugfs_init   = panfrost_debugfs_init,
+#endif
 };
 
 static int panfrost_probe(struct platform_device *pdev)
-- 
2.42.0



[PATCH v3 5/8] drm/panfrost: Add fdinfo support for memory stats

2023-09-05 Thread Adrián Larumbe
A new DRM GEM object function is added so that drm_show_memory_stats can
provide more accurate memory usage numbers.

Ideally, in panfrost_gem_status, the BO's purgeable flag would be checked
after locking the driver's shrinker mutex, but drm_show_memory_stats takes
over the drm file's object handle database spinlock, so there's potential
for a race condition here.

Signed-off-by: Adrián Larumbe 
---
 drivers/gpu/drm/panfrost/panfrost_drv.c |  1 +
 drivers/gpu/drm/panfrost/panfrost_gem.c | 14 ++
 2 files changed, 15 insertions(+)

diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c 
b/drivers/gpu/drm/panfrost/panfrost_drv.c
index 94787f4aee27..3de7e821ef23 100644
--- a/drivers/gpu/drm/panfrost/panfrost_drv.c
+++ b/drivers/gpu/drm/panfrost/panfrost_drv.c
@@ -574,6 +574,7 @@ static void panfrost_show_fdinfo(struct drm_printer *p, 
struct drm_file *file)
 
panfrost_gpu_show_fdinfo(pfdev, file->driver_priv, p);
 
+   drm_show_memory_stats(p, file);
 }
 
 static const struct file_operations panfrost_drm_driver_fops = {
diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.c 
b/drivers/gpu/drm/panfrost/panfrost_gem.c
index 3c812fbd126f..7d8f83d20539 100644
--- a/drivers/gpu/drm/panfrost/panfrost_gem.c
+++ b/drivers/gpu/drm/panfrost/panfrost_gem.c
@@ -195,6 +195,19 @@ static int panfrost_gem_pin(struct drm_gem_object *obj)
return drm_gem_shmem_pin(&bo->base);
 }
 
+static enum drm_gem_object_status panfrost_gem_status(struct drm_gem_object 
*obj)
+{
+   struct panfrost_gem_object *bo = to_panfrost_bo(obj);
+   enum drm_gem_object_status res = 0;
+
+   res |= (bo->base.madv == PANFROST_MADV_DONTNEED) ?
+   DRM_GEM_OBJECT_PURGEABLE : 0;
+
+   res |= (bo->base.pages) ? DRM_GEM_OBJECT_RESIDENT : 0;
+
+   return res;
+}
+
 static const struct drm_gem_object_funcs panfrost_gem_funcs = {
.free = panfrost_gem_free_object,
.open = panfrost_gem_open,
@@ -206,6 +219,7 @@ static const struct drm_gem_object_funcs panfrost_gem_funcs 
= {
.vmap = drm_gem_shmem_object_vmap,
.vunmap = drm_gem_shmem_object_vunmap,
.mmap = drm_gem_shmem_object_mmap,
+   .status = panfrost_gem_status,
.vm_ops = &drm_gem_shmem_vm_ops,
 };
 
-- 
2.42.0



[PATCH v3 2/8] drm/panfrost: Enable cycle counter register upon job submission

2023-09-05 Thread Adrián Larumbe
In a future development, we will want to keep track of the number of GPU
cycles spent on a given job. That means we should enable it only when the
GPU has work to do, and switch it off whenever it is idle to avoid power
waste.

To avoid race conditions during enablement/disabling, a reference counting
mechanism was introduced, and a job flag that tells us whether a given job
increased the refcount. This is necessary, because a future development
will let user space toggle cycle counting through a debugfs file, and a
given job might have been in flight by the time cycle counting was
disabled.

Toggling of GPU cycle counting has to be done through a module parameter.

Signed-off-by: Adrián Larumbe 
---
 drivers/gpu/drm/panfrost/panfrost_device.c |  5 +++
 drivers/gpu/drm/panfrost/panfrost_device.h |  6 +++
 drivers/gpu/drm/panfrost/panfrost_gpu.c| 43 ++
 drivers/gpu/drm/panfrost/panfrost_gpu.h|  6 +++
 drivers/gpu/drm/panfrost/panfrost_job.c| 10 +
 drivers/gpu/drm/panfrost/panfrost_job.h|  1 +
 6 files changed, 71 insertions(+)

diff --git a/drivers/gpu/drm/panfrost/panfrost_device.c 
b/drivers/gpu/drm/panfrost/panfrost_device.c
index fa1a086a862b..1ea2ac3804f0 100644
--- a/drivers/gpu/drm/panfrost/panfrost_device.c
+++ b/drivers/gpu/drm/panfrost/panfrost_device.c
@@ -18,6 +18,9 @@
 #include "panfrost_mmu.h"
 #include "panfrost_perfcnt.h"
 
+static bool profile;
+module_param(profile, bool, 0600);
+
 static int panfrost_reset_init(struct panfrost_device *pfdev)
 {
pfdev->rstc = 
devm_reset_control_array_get_optional_exclusive(pfdev->dev);
@@ -207,6 +210,8 @@ int panfrost_device_init(struct panfrost_device *pfdev)
 
spin_lock_init(&pfdev->as_lock);
 
+   atomic_set(&pfdev->profile_mode, profile);
+
err = panfrost_clk_init(pfdev);
if (err) {
dev_err(pfdev->dev, "clk init failed %d\n", err);
diff --git a/drivers/gpu/drm/panfrost/panfrost_device.h 
b/drivers/gpu/drm/panfrost/panfrost_device.h
index b0126b9fbadc..5c09c9f3ae08 100644
--- a/drivers/gpu/drm/panfrost/panfrost_device.h
+++ b/drivers/gpu/drm/panfrost/panfrost_device.h
@@ -107,6 +107,7 @@ struct panfrost_device {
struct list_head scheduled_jobs;
 
struct panfrost_perfcnt *perfcnt;
+   atomic_t profile_mode;
 
struct mutex sched_lock;
 
@@ -121,6 +122,11 @@ struct panfrost_device {
struct shrinker shrinker;
 
struct panfrost_devfreq pfdevfreq;
+
+   struct {
+   atomic_t use_count;
+   spinlock_t lock;
+   } cycle_counter;
 };
 
 struct panfrost_mmu {
diff --git a/drivers/gpu/drm/panfrost/panfrost_gpu.c 
b/drivers/gpu/drm/panfrost/panfrost_gpu.c
index 2faa344d89ee..fddbc72bf093 100644
--- a/drivers/gpu/drm/panfrost/panfrost_gpu.c
+++ b/drivers/gpu/drm/panfrost/panfrost_gpu.c
@@ -73,6 +73,8 @@ int panfrost_gpu_soft_reset(struct panfrost_device *pfdev)
gpu_write(pfdev, GPU_INT_CLEAR, GPU_IRQ_MASK_ALL);
gpu_write(pfdev, GPU_INT_MASK, GPU_IRQ_MASK_ALL);
 
+   atomic_set(&pfdev->cycle_counter.use_count, 0);
+
return 0;
 }
 
@@ -321,6 +323,46 @@ static void panfrost_gpu_init_features(struct 
panfrost_device *pfdev)
 pfdev->features.shader_present, pfdev->features.l2_present);
 }
 
+void panfrost_cycle_counter_get(struct panfrost_device *pfdev)
+{
+   if (atomic_inc_not_zero(&pfdev->cycle_counter.use_count))
+   return;
+
+   spin_lock(&pfdev->cycle_counter.lock);
+   if (atomic_inc_return(&pfdev->cycle_counter.use_count) == 1)
+   gpu_write(pfdev, GPU_CMD, GPU_CMD_CYCLE_COUNT_START);
+   spin_unlock(&pfdev->cycle_counter.lock);
+}
+
+void panfrost_cycle_counter_put(struct panfrost_device *pfdev)
+{
+   if (atomic_add_unless(&pfdev->cycle_counter.use_count, -1, 1))
+   return;
+
+   spin_lock(&pfdev->cycle_counter.lock);
+   if (atomic_dec_return(&pfdev->cycle_counter.use_count) == 0)
+   gpu_write(pfdev, GPU_CMD, GPU_CMD_CYCLE_COUNT_STOP);
+   spin_unlock(&pfdev->cycle_counter.lock);
+}
+
+void panfrost_cycle_counter_stop(struct panfrost_device *pfdev)
+{
+   atomic_set(&pfdev->profile_mode, 0);
+   gpu_write(pfdev, GPU_CMD, GPU_CMD_CYCLE_COUNT_STOP);
+}
+
+unsigned long long panfrost_cycle_counter_read(struct panfrost_device *pfdev)
+{
+   u32 hi, lo;
+
+   do {
+   hi = gpu_read(pfdev, GPU_CYCLE_COUNT_HI);
+   lo = gpu_read(pfdev, GPU_CYCLE_COUNT_LO);
+   } while (hi != gpu_read(pfdev, GPU_CYCLE_COUNT_HI));
+
+   return ((u64)hi << 32) | lo;
+}
+
 void panfrost_gpu_power_on(struct panfrost_device *pfdev)
 {
int ret;
@@ -367,6 +409,7 @@ void panfrost_gpu_power_on(struct panfrost_device *pfdev)
 
 void panfrost_gpu_power_off(struct panfrost_device *pfdev)
 {
+   panfrost_cycle_counter_stop(pfdev);
gpu_write(pfdev, TILER_PWROFF_LO, 0);
gpu_write(pfdev, SHADER_PWROFF_LO, 0);
gpu_write(pfdev, L

[PATCH v3 4/8] drm/panfrost: Add fdinfo support GPU load metrics

2023-09-05 Thread Adrián Larumbe
The drm-stats fdinfo tags made available to user space are drm-engine,
drm-cycles, drm-max-freq and drm-curfreq, one per job slot.

This deviates from standard practice in other DRM drivers, where a single
set of key:value pairs is provided for the whole render engine. However,
Panfrost has separate queues for fragment and vertex/tiler jobs, so a
decision was made to calculate bus cycles and workload times separately.

Maximum operating frequency is calculated at devfreq initialisation time.
Current frequency is made available to user space because nvtop uses it
when performing engine usage calculations.

It is important to bear in mind that both GPU cycle and kernel time numbers
provided are at best rough estimations, and always reported in excess from
the actual figure because of two reasons:
 - Excess time because of the delay between the end of a job processing,
   the subsequent job IRQ and the actual time of the sample.
 - Time spent in the engine queue waiting for the GPU to pick up the next
   job.

Signed-off-by: Adrián Larumbe 
---
 drivers/gpu/drm/panfrost/panfrost_devfreq.c |  8 +++
 drivers/gpu/drm/panfrost/panfrost_devfreq.h |  3 ++
 drivers/gpu/drm/panfrost/panfrost_device.h  | 13 +
 drivers/gpu/drm/panfrost/panfrost_drv.c | 59 -
 drivers/gpu/drm/panfrost/panfrost_job.c | 27 ++
 drivers/gpu/drm/panfrost/panfrost_job.h |  4 ++
 6 files changed, 113 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.c 
b/drivers/gpu/drm/panfrost/panfrost_devfreq.c
index 58dfb15a8757..28caffc689e2 100644
--- a/drivers/gpu/drm/panfrost/panfrost_devfreq.c
+++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.c
@@ -58,6 +58,7 @@ static int panfrost_devfreq_get_dev_status(struct device *dev,
spin_lock_irqsave(&pfdevfreq->lock, irqflags);
 
panfrost_devfreq_update_utilization(pfdevfreq);
+   pfdevfreq->current_frequency = status->current_frequency;
 
status->total_time = ktime_to_ns(ktime_add(pfdevfreq->busy_time,
   pfdevfreq->idle_time));
@@ -117,6 +118,7 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev)
struct devfreq *devfreq;
struct thermal_cooling_device *cooling;
struct panfrost_devfreq *pfdevfreq = &pfdev->pfdevfreq;
+   unsigned long freq = ULONG_MAX;
 
if (pfdev->comp->num_supplies > 1) {
/*
@@ -172,6 +174,12 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev)
return ret;
}
 
+   /* Find the fastest defined rate  */
+   opp = dev_pm_opp_find_freq_floor(dev, &freq);
+   if (IS_ERR(opp))
+   return PTR_ERR(opp);
+   pfdevfreq->fast_rate = freq;
+
dev_pm_opp_put(opp);
 
/*
diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.h 
b/drivers/gpu/drm/panfrost/panfrost_devfreq.h
index 1514c1f9d91c..48dbe185f206 100644
--- a/drivers/gpu/drm/panfrost/panfrost_devfreq.h
+++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.h
@@ -19,6 +19,9 @@ struct panfrost_devfreq {
struct devfreq_simple_ondemand_data gov_data;
bool opp_of_table_added;
 
+   unsigned long current_frequency;
+   unsigned long fast_rate;
+
ktime_t busy_time;
ktime_t idle_time;
ktime_t time_last_update;
diff --git a/drivers/gpu/drm/panfrost/panfrost_device.h 
b/drivers/gpu/drm/panfrost/panfrost_device.h
index 5c09c9f3ae08..7ad3973b1a3a 100644
--- a/drivers/gpu/drm/panfrost/panfrost_device.h
+++ b/drivers/gpu/drm/panfrost/panfrost_device.h
@@ -24,6 +24,7 @@ struct panfrost_perfcnt;
 
 #define NUM_JOB_SLOTS 3
 #define MAX_PM_DOMAINS 5
+#define MAX_SLOT_NAME_LEN 25
 
 struct panfrost_features {
u16 id;
@@ -141,12 +142,24 @@ struct panfrost_mmu {
struct list_head list;
 };
 
+struct drm_info_gpu {
+   unsigned long maxfreq;
+
+   struct engine_info {
+   unsigned long long elapsed_ns;
+   unsigned long long cycles;
+   char name[MAX_SLOT_NAME_LEN];
+   } engines[NUM_JOB_SLOTS];
+};
+
 struct panfrost_file_priv {
struct panfrost_device *pfdev;
 
struct drm_sched_entity sched_entity[NUM_JOB_SLOTS];
 
struct panfrost_mmu *mmu;
+
+   struct drm_info_gpu fdinfo;
 };
 
 static inline struct panfrost_device *to_panfrost_device(struct drm_device 
*ddev)
diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c 
b/drivers/gpu/drm/panfrost/panfrost_drv.c
index 2dfd9f79a31b..94787f4aee27 100644
--- a/drivers/gpu/drm/panfrost/panfrost_drv.c
+++ b/drivers/gpu/drm/panfrost/panfrost_drv.c
@@ -268,6 +268,7 @@ static int panfrost_ioctl_submit(struct drm_device *dev, 
void *data,
job->requirements = args->requirements;
job->flush_id = panfrost_gpu_get_latest_flush_id(pfdev);
job->mmu = file_priv->mmu;
+   job->priv = file_priv;
 
slot = panfrost_job_get_slot(job);
 
@@ -484,6 +485,14 @@ panfrost_open(struct drm_device *dev, struc

[PATCH v3 0/8] Add fdinfo support to Panfrost

2023-09-05 Thread Adrián Larumbe
This patch series adds fdinfo support to the Panfrost DRM driver. It will
display a series of key:value pairs under /proc/pid/fdinfo/fd for render
processes that open the Panfrost DRM file.

The pairs contain basic drm gpu engine and memory region information that
can either be cat by a privileged user or accessed with IGT's gputop
utility.

Changelog:

v1: https://lore.kernel.org/lkml/bb52b872-e41b-3894-285e-b52cfc849...@arm.com/T/

v2: https://lore.kernel.org/lkml/20230901084457.5bc1a...@collabora.com/T/
 - Changed the way gpu cycles and engine time are calculated, using GPU
 registers and taking into account potential resets.
 - Split render engine values into fragment and vertex/tiler ones.
 - Added more fine-grained calculation of RSS size for BO's.
 - Implemente selection of drm-memory region size units
 - Removed locking of shrinker's mutex in GEM obj status function

v3:
 - Changed fdinfo engine names to something more descriptive
 - Mentioned GPU cycle counts aren't an exact measure
 - Handled the case when job->priv might be NULL
 - Handled 32 bit overflow of cycle register
 - Kept fdinfo drm memory stats size unit display within 10k times the
   previous multiplier for more accurate BO size numbers
 - Removed special handling of Prime imported BO RSS
 - Use rss_size only for heap objects
 - Use bo->base.madv instead of specific purgeable flag
 - Fixed kernel test robot warnings

Adrián Larumbe (8):
  drm/panfrost: Add cycle count GPU register definitions
  drm/panfrost: Enable cycle counter register upon job submission
  drm/panfrost: Enable debugfs toggling of cycle counter register
  drm/panfrost: Add fdinfo support GPU load metrics
  drm/panfrost: Add fdinfo support for memory stats
  drm/drm_file: Add DRM obj's RSS reporting function for fdinfo
  drm/panfrost: Implement generic DRM object RSS reporting function
  drm/drm-file: Show finer-grained BO sizes in drm_show_memory_stats

 drivers/gpu/drm/drm_file.c  |  7 ++-
 drivers/gpu/drm/panfrost/Makefile   |  2 +
 drivers/gpu/drm/panfrost/panfrost_debugfs.c | 51 
 drivers/gpu/drm/panfrost/panfrost_debugfs.h | 13 +
 drivers/gpu/drm/panfrost/panfrost_devfreq.c |  8 +++
 drivers/gpu/drm/panfrost/panfrost_devfreq.h |  3 +
 drivers/gpu/drm/panfrost/panfrost_device.c  |  5 ++
 drivers/gpu/drm/panfrost/panfrost_device.h  | 19 ++
 drivers/gpu/drm/panfrost/panfrost_drv.c | 65 -
 drivers/gpu/drm/panfrost/panfrost_gem.c | 28 +
 drivers/gpu/drm/panfrost/panfrost_gem.h |  5 ++
 drivers/gpu/drm/panfrost/panfrost_gpu.c | 43 ++
 drivers/gpu/drm/panfrost/panfrost_gpu.h |  6 ++
 drivers/gpu/drm/panfrost/panfrost_job.c | 37 
 drivers/gpu/drm/panfrost/panfrost_job.h |  5 ++
 drivers/gpu/drm/panfrost/panfrost_mmu.c | 12 ++--
 drivers/gpu/drm/panfrost/panfrost_regs.h|  5 ++
 include/drm/drm_gem.h   |  9 +++
 18 files changed, 316 insertions(+), 7 deletions(-)
 create mode 100644 drivers/gpu/drm/panfrost/panfrost_debugfs.c
 create mode 100644 drivers/gpu/drm/panfrost/panfrost_debugfs.h


base-commit: f45acf7acf75921c0409d452f0165f51a19a74fd
-- 
2.42.0



[PATCH v3 1/8] drm/panfrost: Add cycle count GPU register definitions

2023-09-05 Thread Adrián Larumbe
These GPU registers will be used when programming the cycle counter, which
we need for providing accurate fdinfo drm-cycles values to user space.

Signed-off-by: Adrián Larumbe 
Reviewed-by: Boris Brezillon 
Reviewed-by: Steven Price 
---
 drivers/gpu/drm/panfrost/panfrost_regs.h | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/panfrost/panfrost_regs.h 
b/drivers/gpu/drm/panfrost/panfrost_regs.h
index 919f44ac853d..55ec807550b3 100644
--- a/drivers/gpu/drm/panfrost/panfrost_regs.h
+++ b/drivers/gpu/drm/panfrost/panfrost_regs.h
@@ -46,6 +46,8 @@
 #define   GPU_CMD_SOFT_RESET   0x01
 #define   GPU_CMD_PERFCNT_CLEAR0x03
 #define   GPU_CMD_PERFCNT_SAMPLE   0x04
+#define   GPU_CMD_CYCLE_COUNT_START0x05
+#define   GPU_CMD_CYCLE_COUNT_STOP 0x06
 #define   GPU_CMD_CLEAN_CACHES 0x07
 #define   GPU_CMD_CLEAN_INV_CACHES 0x08
 #define GPU_STATUS 0x34
@@ -73,6 +75,9 @@
 #define GPU_PRFCNT_TILER_EN0x74
 #define GPU_PRFCNT_MMU_L2_EN   0x7c
 
+#define GPU_CYCLE_COUNT_LO 0x90
+#define GPU_CYCLE_COUNT_HI 0x94
+
 #define GPU_THREAD_MAX_THREADS 0x0A0   /* (RO) Maximum number of 
threads per core */
 #define GPU_THREAD_MAX_WORKGROUP_SIZE  0x0A4   /* (RO) Maximum workgroup size 
*/
 #define GPU_THREAD_MAX_BARRIER_SIZE0x0A8   /* (RO) Maximum threads waiting 
at a barrier */
-- 
2.42.0



[drm-misc:drm-misc-next 3/3] drivers/gpu/drm/tegra/dsi.c:259:43: error: passing argument 3 of 'drm_debugfs_remove_files' from incompatible pointer type

2023-09-05 Thread kernel test robot
tree:   git://anongit.freedesktop.org/drm/drm-misc drm-misc-next
head:   f45acf7acf75921c0409d452f0165f51a19a74fd
commit: 8e455145d8f163aefa6b9cc29478e0a9f82276e6 [3/3] drm/debugfs: rework 
drm_debugfs_create_files implementation v2
config: openrisc-randconfig-r015-20230906 
(https://download.01.org/0day-ci/archive/20230906/202309060212.6xvtsnab-...@intel.com/config)
compiler: or1k-linux-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): 
(https://download.01.org/0day-ci/archive/20230906/202309060212.6xvtsnab-...@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot 
| Closes: 
https://lore.kernel.org/oe-kbuild-all/202309060212.6xvtsnab-...@intel.com/

All errors (new ones prefixed by >>):

   drivers/gpu/drm/tegra/dsi.c: In function 'tegra_dsi_early_unregister':
>> drivers/gpu/drm/tegra/dsi.c:259:43: error: passing argument 3 of 
>> 'drm_debugfs_remove_files' from incompatible pointer type 
>> [-Werror=incompatible-pointer-types]
 259 |  connector->debugfs_entry,
 |  ~^~~
 |   |
 |   struct dentry *
   In file included from drivers/gpu/drm/tegra/dsi.c:21:
   include/drm/drm_debugfs.h:163:73: note: expected 'struct drm_minor *' but 
argument is of type 'struct dentry *'
 163 |int count, struct 
drm_minor *minor)
 |   
~~^
>> drivers/gpu/drm/tegra/dsi.c:258:9: error: too many arguments to function 
>> 'drm_debugfs_remove_files'
 258 | drm_debugfs_remove_files(dsi->debugfs_files, count,
 | ^~~~
   include/drm/drm_debugfs.h:162:19: note: declared here
 162 | static inline int drm_debugfs_remove_files(const struct 
drm_info_list *files,
 |   ^~~~
   cc1: some warnings being treated as errors
--
   drivers/gpu/drm/tegra/dc.c: In function 'tegra_dc_early_unregister':
>> drivers/gpu/drm/tegra/dc.c:1757:60: error: passing argument 3 of 
>> 'drm_debugfs_remove_files' from incompatible pointer type 
>> [-Werror=incompatible-pointer-types]
1757 | drm_debugfs_remove_files(dc->debugfs_files, count, root, 
minor);
 |^~~~
 ||
 |struct 
dentry *
   In file included from drivers/gpu/drm/tegra/dc.c:27:
   include/drm/drm_debugfs.h:163:73: note: expected 'struct drm_minor *' but 
argument is of type 'struct dentry *'
 163 |int count, struct 
drm_minor *minor)
 |   
~~^
>> drivers/gpu/drm/tegra/dc.c:1757:9: error: too many arguments to function 
>> 'drm_debugfs_remove_files'
1757 | drm_debugfs_remove_files(dc->debugfs_files, count, root, 
minor);
 | ^~~~
   include/drm/drm_debugfs.h:162:19: note: declared here
 162 | static inline int drm_debugfs_remove_files(const struct 
drm_info_list *files,
 |   ^~~~
   cc1: some warnings being treated as errors
--
   drivers/gpu/drm/tegra/hdmi.c: In function 'tegra_hdmi_early_unregister':
>> drivers/gpu/drm/tegra/hdmi.c:1120:43: error: passing argument 3 of 
>> 'drm_debugfs_remove_files' from incompatible pointer type 
>> [-Werror=incompatible-pointer-types]
1120 |  connector->debugfs_entry, minor);
 |  ~^~~
 |   |
 |   struct dentry *
   In file included from drivers/gpu/drm/tegra/hdmi.c:26:
   include/drm/drm_debugfs.h:163:73: note: expected 'struct drm_minor *' but 
argument is of type 'struct dentry *'
 163 |int count, struct 
drm_minor *minor)
 |   
~~^
>> drivers/gpu/drm/tegra/hdmi.c:1119:9: error: too many arguments to function 
>> 'drm_debugfs_remove_files'
1119 | drm_debugfs_remove_files(hdmi->debugfs_files, count,
 | ^~~~
   include/drm/drm_debugfs.h:162:19: note: declared here
 162 | static inline int drm_debugfs_remove_files(const struct 
drm_info_list *files,
 |   ^~~~
   cc1: some warnings being treated as errors
--
   drivers/gpu/drm/tegra/sor.c: In function 'tegra_sor_early_unregister':
>> drivers

[PATCH 6/6] drm/msm/dpu: Add MSM8996 support

2023-09-05 Thread Dmitry Baryshkov
From: Konrad Dybcio 

Add support for MSM8996, which - fun fact - was the SoC that this driver
(or rather SDE, its downstream origin) was meant for and first tested on.

It has some hardware that differs from the modern SoCs, so not a lot of
current structs could have been reused. It's also seemingly the only SoC
supported by DPU that uses RGB pipes.

Note, by default this platform is still handled by the MDP5 driver
unless the `msm.prefer_mdp5=false' parameter is provided.

Signed-off-by: Konrad Dybcio 
Signed-off-by: Konrad Dybcio 
[DB: rebased on top of sblk changes, add dpu_rgb_sblk]
Signed-off-by: Dmitry Baryshkov 
---
 .../msm/disp/dpu1/catalog/dpu_1_7_msm8996.h   | 353 ++
 .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c|  95 +
 .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h|   1 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c   |   1 +
 drivers/gpu/drm/msm/msm_drv.c |   1 +
 5 files changed, 451 insertions(+)
 create mode 100644 drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_7_msm8996.h

diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_7_msm8996.h 
b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_7_msm8996.h
new file mode 100644
index ..43e952fcce9b
--- /dev/null
+++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_7_msm8996.h
@@ -0,0 +1,353 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2023, Linaro Limited
+ * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DPU_1_7_MSM8996_H
+#define _DPU_1_7_MSM8996_H
+
+static const struct dpu_caps msm8996_dpu_caps = {
+   .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
+   .max_mixer_blendstages = 0x7,
+   .has_src_split = true,
+   .max_linewidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
+   .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
+   .max_hdeci_exp = MAX_HORZ_DECIMATION,
+   .max_vdeci_exp = MAX_VERT_DECIMATION,
+};
+
+static const struct dpu_mdp_cfg msm8996_mdp[] = {
+   {
+   .name = "top_0",
+   .base = 0x0, .len = 0x454,
+   .features = BIT(DPU_MDP_VSYNC_SEL),
+   .clk_ctrls = {
+   [DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0 
},
+   [DPU_CLK_CTRL_VIG1] = { .reg_off = 0x2b4, .bit_off = 0 
},
+   [DPU_CLK_CTRL_VIG2] = { .reg_off = 0x2bc, .bit_off = 0 
},
+   [DPU_CLK_CTRL_VIG3] = { .reg_off = 0x2c4, .bit_off = 0 
},
+   [DPU_CLK_CTRL_RGB0] = { .reg_off = 0x2ac, .bit_off = 4 
},
+   [DPU_CLK_CTRL_RGB1] = { .reg_off = 0x2b4, .bit_off = 4 
},
+   [DPU_CLK_CTRL_RGB2] = { .reg_off = 0x2bc, .bit_off = 4 
},
+   [DPU_CLK_CTRL_RGB3] = { .reg_off = 0x2c4, .bit_off = 4 
},
+   [DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 
},
+   [DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 
},
+   [DPU_CLK_CTRL_CURSOR0] = { .reg_off = 0x3a8, .bit_off = 
16 },
+   [DPU_CLK_CTRL_CURSOR1] = { .reg_off = 0x3b0, .bit_off = 
16 },
+   },
+   },
+};
+
+static const struct dpu_ctl_cfg msm8996_ctl[] = {
+   {
+   .name = "ctl_0", .id = CTL_0,
+   .base = 0x1000, .len = 0x64,
+   .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9),
+   }, {
+   .name = "ctl_1", .id = CTL_1,
+   .base = 0x1200, .len = 0x64,
+   .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10),
+   }, {
+   .name = "ctl_2", .id = CTL_2,
+   .base = 0x1400, .len = 0x64,
+   .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 11),
+   }, {
+   .name = "ctl_3", .id = CTL_3,
+   .base = 0x1600, .len = 0x64,
+   .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 12),
+   }, {
+   .name = "ctl_4", .id = CTL_4,
+   .base = 0x1800, .len = 0x64,
+   .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 13),
+   },
+};
+
+static const struct dpu_sspp_cfg msm8996_sspp[] = {
+   {
+   .name = "sspp_0", .id = SSPP_VIG0,
+   .base = 0x4000, .len = 0x150,
+   .features = VIG_MSM8996_MASK,
+   .sblk = &dpu_vig_sblk_qseed2,
+   .xin_id = 0,
+   .type = SSPP_TYPE_VIG,
+   .clk_ctrl = DPU_CLK_CTRL_VIG0,
+   }, {
+   .name = "sspp_1", .id = SSPP_VIG1,
+   .base = 0x6000, .len = 0x150,
+   .features = VIG_MSM8996_MASK,
+   .sblk = &dpu_vig_sblk_qseed2,
+   .xin_id = 4,
+   .type = SSPP_TYPE_VIG,
+   .clk_ctrl = DPU_CLK_CTRL_VIG1,
+   }, {
+   .name = "sspp_2", .id = SSPP_VIG2,
+   .base = 0x8000, .len = 0x150,
+ 

[PATCH 1/6] drm/msm/mdss: fix highest-bank-bit for msm8998

2023-09-05 Thread Dmitry Baryshkov
According to the vendor DT files, msm8998 has highest-bank-bit equal to
2. Update the data accordingly.

Fixes: 6f410b246209 ("drm/msm/mdss: populate missing data")
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/msm_mdss.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/msm_mdss.c b/drivers/gpu/drm/msm/msm_mdss.c
index 2e87dd6cb17b..348c66b14683 100644
--- a/drivers/gpu/drm/msm/msm_mdss.c
+++ b/drivers/gpu/drm/msm/msm_mdss.c
@@ -511,7 +511,7 @@ static int mdss_remove(struct platform_device *pdev)
 static const struct msm_mdss_data msm8998_data = {
.ubwc_enc_version = UBWC_1_0,
.ubwc_dec_version = UBWC_1_0,
-   .highest_bank_bit = 1,
+   .highest_bank_bit = 2,
 };
 
 static const struct msm_mdss_data qcm2290_data = {
-- 
2.39.2



[PATCH 5/6] drm/msm/dpu: add support for SDM660 and SDM630 platforms

2023-09-05 Thread Dmitry Baryshkov
Bring in hardware support for the SDM660 and SDM630 platforms, which
belong to the same DPU generation as MSM8998.

Note, by default these platforms are still handled by the MDP5 driver
unless the `msm.prefer_mdp5=false' parameter is provided.

Co-developed-by: Konrad Dybcio 
Signed-off-by: Konrad Dybcio 
Signed-off-by: Dmitry Baryshkov 
---
 .../msm/disp/dpu1/catalog/dpu_3_2_sdm660.h| 291 ++
 .../msm/disp/dpu1/catalog/dpu_3_3_sdm630.h| 225 ++
 .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c|   2 +
 .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h|   2 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c   |   2 +
 drivers/gpu/drm/msm/msm_drv.c |   2 +
 6 files changed, 524 insertions(+)
 create mode 100644 drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_2_sdm660.h
 create mode 100644 drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_3_sdm630.h

diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_2_sdm660.h 
b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_2_sdm660.h
new file mode 100644
index ..bd38fb753849
--- /dev/null
+++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_2_sdm660.h
@@ -0,0 +1,291 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2023. Linaro Inc. All rights reserved.
+ */
+
+#ifndef _DPU_3_2_SDM660_H
+#define _DPU_3_2_SDM660_H
+
+static const struct dpu_caps sdm660_dpu_caps = {
+   .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
+   .max_mixer_blendstages = 0x7,
+   .has_src_split = true,
+   .has_dim_layer = true,
+   .has_idle_pc = true,
+   .has_3d_merge = true,
+   .max_linewidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
+   .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
+   .max_hdeci_exp = MAX_HORZ_DECIMATION,
+   .max_vdeci_exp = MAX_VERT_DECIMATION,
+};
+
+static const struct dpu_mdp_cfg sdm660_mdp = {
+   .name = "top_0",
+   .base = 0x0, .len = 0x458,
+   .features = BIT(DPU_MDP_VSYNC_SEL),
+   .clk_ctrls = {
+   [DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0 },
+   [DPU_CLK_CTRL_VIG1] = { .reg_off = 0x2b4, .bit_off = 0 },
+   [DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 },
+   [DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 },
+   [DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2c4, .bit_off = 8 },
+   [DPU_CLK_CTRL_CURSOR0] = { .reg_off = 0x3a8, .bit_off = 16 },
+   },
+};
+
+static const struct dpu_ctl_cfg sdm660_ctl[] = {
+   {
+   .name = "ctl_0", .id = CTL_0,
+   .base = 0x1000, .len = 0x94,
+   .features = BIT(DPU_CTL_SPLIT_DISPLAY),
+   .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9),
+   }, {
+   .name = "ctl_1", .id = CTL_1,
+   .base = 0x1200, .len = 0x94,
+   .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10),
+   }, {
+   .name = "ctl_2", .id = CTL_2,
+   .base = 0x1400, .len = 0x94,
+   .features = BIT(DPU_CTL_SPLIT_DISPLAY),
+   .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 11),
+   }, {
+   .name = "ctl_3", .id = CTL_3,
+   .base = 0x1600, .len = 0x94,
+   .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 12),
+   }, {
+   .name = "ctl_4", .id = CTL_4,
+   .base = 0x1800, .len = 0x94,
+   .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 13),
+   },
+};
+
+static const struct dpu_sspp_cfg sdm660_sspp[] = {
+   {
+   .name = "sspp_0", .id = SSPP_VIG0,
+   .base = 0x4000, .len = 0x1ac,
+   .features = VIG_MSM8998_MASK,
+   .sblk = &dpu_vig_sblk_1_2,
+   .xin_id = 0,
+   .type = SSPP_TYPE_VIG,
+   .clk_ctrl = DPU_CLK_CTRL_VIG0,
+   }, {
+   .name = "sspp_1", .id = SSPP_VIG1,
+   .base = 0x6000, .len = 0x1ac,
+   .features = VIG_MSM8998_MASK,
+   .sblk = &dpu_vig_sblk_1_2,
+   .xin_id = 4,
+   .type = SSPP_TYPE_VIG,
+   .clk_ctrl = DPU_CLK_CTRL_VIG1,
+   }, {
+   .name = "sspp_8", .id = SSPP_DMA0,
+   .base = 0x24000, .len = 0x1ac,
+   .features = DMA_MSM8998_MASK,
+   .sblk = &dpu_dma_sblk,
+   .xin_id = 1,
+   .type = SSPP_TYPE_DMA,
+   .clk_ctrl = DPU_CLK_CTRL_DMA0,
+   }, {
+   .name = "sspp_9", .id = SSPP_DMA1,
+   .base = 0x26000, .len = 0x1ac,
+   .features = DMA_MSM8998_MASK,
+   .sblk = &dpu_dma_sblk,
+   .xin_id = 5,
+   .type = SSPP_TYPE_DMA,
+   .clk_ctrl = DPU_CLK_CTRL_DMA1,
+   }, {
+   .name = "sspp_10", .id = SSPP_DMA2,
+   .base = 0x28000, .len = 0x1ac,
+   .features = DMA_CURSOR_MSM8998_MASK,
+   .sblk = &dpu_dma_sblk,
+   .

[PATCH 4/6] drm/msm: add a kernel param to select between MDP5 and DPU drivers

2023-09-05 Thread Dmitry Baryshkov
For some of the platforms (e.g. SDM660, SDM630, MSM8996, etc.) it is
possible to support this platform via the DPU driver (e.g. to provide
support for DP, multirect, etc). Add a modparam to be able to switch
between these two drivers.

All platforms supported by both drivers are by default handled by the
MDP5 driver. To let them be handled by the DPU driver pass the
`msm.prefer_mdp5=false` kernel param.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c  |  3 +++
 drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c |  3 +++
 drivers/gpu/drm/msm/msm_drv.c| 31 
 drivers/gpu/drm/msm/msm_drv.h|  1 +
 4 files changed, 38 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index a9ba67e24e11..f3cb8c2ada5e 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -1351,6 +1351,9 @@ static int dpu_kms_init(struct drm_device *ddev)
 
 static int dpu_dev_probe(struct platform_device *pdev)
 {
+   if (!msm_disp_drv_should_bind(&pdev->dev, true))
+   return -ENODEV;
+
return msm_drv_probe(&pdev->dev, dpu_kms_init);
 }
 
diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c 
b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
index 92bf9d949d09..3828725683a7 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
@@ -935,6 +935,9 @@ static int mdp5_dev_probe(struct platform_device *pdev)
 
DBG("");
 
+   if (!msm_disp_drv_should_bind(&pdev->dev, false))
+   return -ENODEV;
+
ret = mdp5_setup_interconnect(pdev);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 4bd028fa7500..1b8ec55704ba 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -1184,6 +1184,37 @@ static int add_components_mdp(struct device *master_dev,
return 0;
 }
 
+#if !IS_REACHABLE(CONFIG_DRM_MSM_MDP5) || !IS_REACHABLE(CONFIG_DRM_MSM_DPU)
+bool msm_disp_drv_should_bind(struct device *dev, bool mdp5_driver)
+{
+   /* If just a single driver is enabled, use it no matter what */
+   return true;
+}
+#else
+
+static bool prefer_mdp5 = true;
+MODULE_PARM_DESC(prefer_mdp5, "Select whether MDP5 or DPU driver should be 
preferred");
+module_param(prefer_mdp5, bool, 0444);
+
+/* list all platforms supported by both mdp5 and dpu drivers */
+static const char *const msm_mdp5_dpu_migration[] = {
+   NULL,
+};
+
+bool msm_disp_drv_should_bind(struct device *dev, bool dpu_driver)
+{
+   /* If it is not an MDP5 device, do not try MDP5 driver */
+   if (!of_device_is_compatible(dev->of_node, "qcom,mdp5"))
+   return dpu_driver;
+
+   /* If it is not in the migration list, use MDP5 */
+   if (!of_device_compatible_match(dev->of_node, msm_mdp5_dpu_migration))
+   return !dpu_driver;
+
+   return prefer_mdp5 ? !dpu_driver : dpu_driver;
+}
+#endif
+
 /*
  * We don't know what's the best binding to link the gpu with the drm device.
  * Fow now, we just hunt for all the possible gpus that we support, and add 
them
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index fdcbb02fa396..05370a03fb44 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -571,5 +571,6 @@ int msm_drv_probe(struct device *dev,
int (*kms_init)(struct drm_device *dev));
 void msm_drv_shutdown(struct platform_device *pdev);
 
+bool msm_disp_drv_should_bind(struct device *dev, bool dpu_driver);
 
 #endif /* __MSM_DRV_H__ */
-- 
2.39.2



[PATCH 2/6] drm/msm/mdss: generate MDSS data for MDP5 platforms

2023-09-05 Thread Dmitry Baryshkov
Older (mdp5) platforms do not use per-SoC compatible strings. Instead
they use a single compat entry 'qcom,mdss'. To facilitate migrating
these platforms to the DPU driver provide a way to generate the MDSS /
UBWC data at runtime, when the DPU driver asks for it.

It is not possible to generate this data structure at the probe time,
since some platforms might not have MDP_CLK enabled, which makes reading
HW_REV register return 0.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/msm_mdss.c | 37 ++
 1 file changed, 37 insertions(+)

diff --git a/drivers/gpu/drm/msm/msm_mdss.c b/drivers/gpu/drm/msm/msm_mdss.c
index 348c66b14683..fb6ee93b5abc 100644
--- a/drivers/gpu/drm/msm/msm_mdss.c
+++ b/drivers/gpu/drm/msm/msm_mdss.c
@@ -222,6 +222,36 @@ static void msm_mdss_setup_ubwc_dec_40(struct msm_mdss 
*msm_mdss)
}
 }
 
+static struct msm_mdss_data *msm_mdss_generate_mdp5_mdss_data(struct msm_mdss 
*mdss)
+{
+   struct msm_mdss_data *data;
+   u32 hw_rev;
+
+   data = devm_kzalloc(mdss->dev, sizeof(*data), GFP_KERNEL);
+   if (!data)
+   return NULL;
+
+   hw_rev = readl_relaxed(mdss->mmio + HW_REV) >> 16;
+
+   if (hw_rev == 0x1007 || /* msm8996 */
+   hw_rev == 0x100e || /* msm8937 */
+   hw_rev == 0x1010 || /* msm8953 */
+   hw_rev == 0x3000 || /* msm8998 */
+   hw_rev == 0x3002 || /* sdm660 */
+   hw_rev == 0x3003) { /* sdm630 */
+   data->ubwc_dec_version = UBWC_1_0;
+   data->ubwc_enc_version = UBWC_1_0;
+   }
+
+   if (hw_rev == 0x1007 || /* msm8996 */
+   hw_rev == 0x3000) /* msm8998 */
+   data->highest_bank_bit = 2;
+   else
+   data->highest_bank_bit = 1;
+
+   return data;
+}
+
 const struct msm_mdss_data *msm_mdss_get_mdss_data(struct device *dev)
 {
struct msm_mdss *mdss;
@@ -231,6 +261,13 @@ const struct msm_mdss_data *msm_mdss_get_mdss_data(struct 
device *dev)
 
mdss = dev_get_drvdata(dev);
 
+   /*
+* We could not do it at the probe time, since hw revision register was
+* not readable. Fill data structure now for the MDP5 platforms.
+*/
+   if (!mdss->mdss_data && mdss->is_mdp5)
+   mdss->mdss_data = msm_mdss_generate_mdp5_mdss_data(mdss);
+
return mdss->mdss_data;
 }
 
-- 
2.39.2



[PATCH 3/6] drm/msm/dpu: support binding to the mdp5 devices

2023-09-05 Thread Dmitry Baryshkov
Existing MDP5 devices have slightly different bindings. The main
register region is called `mdp_phys' instead of `mdp'. Also vbif
register regions are a part of the parent, MDSS device. Add support for
handling this binding differences.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 88 -
 drivers/gpu/drm/msm/msm_drv.h   |  3 +
 drivers/gpu/drm/msm/msm_io_utils.c  | 18 +
 3 files changed, 91 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index aa6ba2cf4b84..a9ba67e24e11 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -1054,37 +1054,53 @@ unsigned long dpu_kms_get_clk_rate(struct dpu_kms 
*dpu_kms, char *clock_name)
 
 #defineDPU_PERF_DEFAULT_MAX_CORE_CLK_RATE  41250
 
-static int dpu_kms_hw_init(struct msm_kms *kms)
+static int dpu_kms_mmap_mdp5(struct dpu_kms *dpu_kms)
 {
-   struct dpu_kms *dpu_kms;
-   struct drm_device *dev;
-   int i, rc = -EINVAL;
-   unsigned long max_core_clk_rate;
-   u32 core_rev;
+   struct platform_device *mdss_dev;
+   int rc;
 
-   if (!kms) {
-   DPU_ERROR("invalid kms\n");
+   mdss_dev = to_platform_device(dpu_kms->pdev->dev.parent);
+
+   dpu_kms->mmio = msm_ioremap(dpu_kms->pdev, "mdp_phys");
+   if (IS_ERR(dpu_kms->mmio)) {
+   rc = PTR_ERR(dpu_kms->mmio);
+   DPU_ERROR("mdp register memory map failed: %d\n", rc);
+   dpu_kms->mmio = NULL;
return rc;
}
+   DRM_DEBUG("mapped dpu address space @%pK\n", dpu_kms->mmio);
 
-   dpu_kms = to_dpu_kms(kms);
-   dev = dpu_kms->dev;
+   dpu_kms->vbif[VBIF_RT] = msm_ioremap_mdss(mdss_dev,
+ dpu_kms->pdev,
+ "vbif_phys");
+   if (IS_ERR(dpu_kms->vbif[VBIF_RT])) {
+   rc = PTR_ERR(dpu_kms->vbif[VBIF_RT]);
+   DPU_ERROR("vbif register memory map failed: %d\n", rc);
+   dpu_kms->vbif[VBIF_RT] = NULL;
+   return rc;
+   }
 
-   dev->mode_config.cursor_width = 512;
-   dev->mode_config.cursor_height = 512;
+   dpu_kms->vbif[VBIF_NRT] = msm_ioremap_mdss(mdss_dev,
+  dpu_kms->pdev,
+  "vbif_nrt_phys");
+   if (IS_ERR(dpu_kms->vbif[VBIF_NRT])) {
+   dpu_kms->vbif[VBIF_NRT] = NULL;
+   DPU_DEBUG("VBIF NRT is not defined");
+   }
 
-   rc = dpu_kms_global_obj_init(dpu_kms);
-   if (rc)
-   return rc;
+   return 0;
+}
 
-   atomic_set(&dpu_kms->bandwidth_ref, 0);
+static int dpu_kms_mmap_dpu(struct dpu_kms *dpu_kms)
+{
+   int rc;
 
dpu_kms->mmio = msm_ioremap(dpu_kms->pdev, "mdp");
if (IS_ERR(dpu_kms->mmio)) {
rc = PTR_ERR(dpu_kms->mmio);
DPU_ERROR("mdp register memory map failed: %d\n", rc);
dpu_kms->mmio = NULL;
-   goto error;
+   return rc;
}
DRM_DEBUG("mapped dpu address space @%pK\n", dpu_kms->mmio);
 
@@ -1093,14 +1109,50 @@ static int dpu_kms_hw_init(struct msm_kms *kms)
rc = PTR_ERR(dpu_kms->vbif[VBIF_RT]);
DPU_ERROR("vbif register memory map failed: %d\n", rc);
dpu_kms->vbif[VBIF_RT] = NULL;
-   goto error;
+   return rc;
}
+
dpu_kms->vbif[VBIF_NRT] = msm_ioremap_quiet(dpu_kms->pdev, "vbif_nrt");
if (IS_ERR(dpu_kms->vbif[VBIF_NRT])) {
dpu_kms->vbif[VBIF_NRT] = NULL;
DPU_DEBUG("VBIF NRT is not defined");
}
 
+   return 0;
+}
+
+static int dpu_kms_hw_init(struct msm_kms *kms)
+{
+   struct dpu_kms *dpu_kms;
+   struct drm_device *dev;
+   int i, rc = -EINVAL;
+   unsigned long max_core_clk_rate;
+   u32 core_rev;
+
+   if (!kms) {
+   DPU_ERROR("invalid kms\n");
+   return rc;
+   }
+
+   dpu_kms = to_dpu_kms(kms);
+   dev = dpu_kms->dev;
+
+   dev->mode_config.cursor_width = 512;
+   dev->mode_config.cursor_height = 512;
+
+   rc = dpu_kms_global_obj_init(dpu_kms);
+   if (rc)
+   return rc;
+
+   atomic_set(&dpu_kms->bandwidth_ref, 0);
+
+   if (of_device_is_compatible(dpu_kms->pdev->dev.of_node, "qcom,mdp5"))
+   rc = dpu_kms_mmap_mdp5(dpu_kms);
+   else
+   rc = dpu_kms_mmap_dpu(dpu_kms);
+   if (rc)
+   return rc;
+
dpu_kms_parse_data_bus_icc_path(dpu_kms);
 
rc = pm_runtime_resume_and_get(&dpu_kms->pdev->dev);
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index 02fd6c7d0bb7..fdcbb02fa396 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/driver

[PATCH 0/6] drm/msm: provide migration path from MDP5 to DPU driver

2023-09-05 Thread Dmitry Baryshkov
Over the last several years the DPU driver has been actively developed,
while the MDP5 is mostly in the maintenance mode. This results in some
features being available only in the DPU driver. For example, bandwidth
scaling, writeback support, properly supported bonded DSI aka dual DSI
support.

All the pre-SDM845 platforms were originally supported by the MDP5
driver only. However it is possible and easy to support some of the
older SoCs in the DPU driver. For example in the v5.18 it got
support for MSM8998.  This can not be considered as a proper migration,
since there msm8998.dtsi didn't describe the display hardware
beforehand. Instead new bindings were added, making MSM8998 just another
display hardware to be supported by the DPU driver.

This series provides a way to gradually migrate support for several
existing and well-supported SoCs from the MDP5 to the DPU driver without
changing the DT. From the user experience point of view this is
facilitated by the `msm.prefer_mdp5' kernel param. If the parameter is
set to `true' (current default), all `shared' platforms will be handled
by the MDP5 driver. If the switch is flipped to `false' (or if the MDP5
driver is disabled), these platforms will be handled by the DPU driver.
Handling this by the modparam (rather than solely by kernel config)
allows one to easly switch between the drivers, simplifying testing.

This series implements support for two DPU 3.n platforms, SDM660 and
SDM630, and a classical MDP5 1.7 (MSM8996) SoC. It should be easy to
implement similar support for MSM8937 aka SDM430, MSM8917 aka SDM425,
MSM8953 aka SDM625 / SDM632 / SDM450 and QCS405. They were left out
beacuse of the lack of the hardware on my side. Then it should be
relatively easy to also add support for MSM8992, MSM8994, MSM8956 and
MSM8976. The major missing piece is the SharedMemoryPool, SMP.

In theory after additional testing we can drop most of migration code
and some parts of MDP5 driver. The proposed boundary is to move all
platforms supporting cursor planes to the DPU driver, while limiting
MDP5 to support only the older platforms which implement cursor as a
part of the LM hardware block (MSM8974, APQ8084, MSM8x26, MSM8x16 and
MSM8x39).

Dependencies: [1]

[1] https://patchwork.freedesktop.org/series/119804/

Dmitry Baryshkov (5):
  drm/msm/mdss: fix highest-bank-bit for msm8998
  drm/msm/mdss: generate MDSS data for MDP5 platforms
  drm/msm/dpu: support binding to the mdp5 devices
  drm/msm: add a kernel param to select between MDP5 and DPU drivers
  drm/msm/dpu: add support for SDM660 and SDM630 platforms

Konrad Dybcio (1):
  drm/msm/dpu: Add MSM8996 support

 .../msm/disp/dpu1/catalog/dpu_1_7_msm8996.h   | 353 ++
 .../msm/disp/dpu1/catalog/dpu_3_2_sdm660.h| 291 +++
 .../msm/disp/dpu1/catalog/dpu_3_3_sdm630.h| 225 +++
 .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c|  97 +
 .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h|   3 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c   |  94 -
 drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c  |   3 +
 drivers/gpu/drm/msm/msm_drv.c |  34 ++
 drivers/gpu/drm/msm/msm_drv.h |   4 +
 drivers/gpu/drm/msm/msm_io_utils.c|  18 +
 drivers/gpu/drm/msm/msm_mdss.c|  39 +-
 11 files changed, 1142 insertions(+), 19 deletions(-)
 create mode 100644 drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_1_7_msm8996.h
 create mode 100644 drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_2_sdm660.h
 create mode 100644 drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_3_sdm630.h

-- 
2.39.2



Re: [PATCH -next 5/5] drm/amd/display: clean up one inconsistent indenting

2023-09-05 Thread Alex Deucher
Applied the series.  Thanks!

Alex

On Thu, Aug 31, 2023 at 9:29 PM Yang Li  wrote:
>
> drivers/gpu/drm/amd/amdgpu/../display/dc/dml/dcn35/dcn35_fpu.c:260 
> dcn35_update_bw_bounding_box_fpu() warn: inconsistent indenting
>
> Signed-off-by: Yang Li 
> ---
>  drivers/gpu/drm/amd/display/dc/dml/dcn35/dcn35_fpu.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn35/dcn35_fpu.c 
> b/drivers/gpu/drm/amd/display/dc/dml/dcn35/dcn35_fpu.c
> index 525ca0ed9ea9..46eb2d0592f3 100644
> --- a/drivers/gpu/drm/amd/display/dc/dml/dcn35/dcn35_fpu.c
> +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn35/dcn35_fpu.c
> @@ -348,8 +348,8 @@ void dcn35_update_bw_bounding_box_fpu(struct dc *dc,
> dc->debug.dram_clock_change_latency_ns / 1000.0;
> }
> /*temp till dml2 fully work without dml1*/
> -   dml_init_instance(&dc->dml, &dcn3_5_soc, &dcn3_5_ip,
> - DML_PROJECT_DCN31);
> +   dml_init_instance(&dc->dml, &dcn3_5_soc, &dcn3_5_ip,
> +   DML_PROJECT_DCN31);
>  }
>
>  static bool is_dual_plane(enum surface_pixel_format format)
> --
> 2.20.1.7.g153144c
>


Re: [PATCH -next 4/4] drm/amd/display: Remove duplicated include in dcn35_clk_mgr.c

2023-09-05 Thread Alex Deucher
Applied.  Thanks!

On Thu, Aug 31, 2023 at 8:52 PM Yang Li  wrote:
>
> ./drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c: 
> dcn35_clk_mgr.h is included more than once.
>
> Signed-off-by: Yang Li 
> ---
>  drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c | 1 -
>  1 file changed, 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c 
> b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c
> index 3b2463c03694..9314e75195cd 100644
> --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c
> +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c
> @@ -46,7 +46,6 @@
>  /* TODO: remove this include once we ported over remaining clk mgr 
> functions*/
>  #include "dcn30/dcn30_clk_mgr.h"
>  #include "dcn31/dcn31_clk_mgr.h"
> -#include "dcn35_clk_mgr.h"
>
>  #include "dc_dmub_srv.h"
>  #include "link.h"
> --
> 2.20.1.7.g153144c
>


Re: [PATCH -next 3/4] drm/amd/display: Remove duplicated include in dcn35_hwseq.c

2023-09-05 Thread Alex Deucher
Applied.  Thanks!

On Thu, Aug 31, 2023 at 8:52 PM Yang Li  wrote:
>
> ./drivers/gpu/drm/amd/display/dc/dcn35/dcn35_hwseq.c: clk_mgr.h is included 
> more than once.
>
> Signed-off-by: Yang Li 
> ---
>  drivers/gpu/drm/amd/display/dc/dcn35/dcn35_hwseq.c | 1 -
>  1 file changed, 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_hwseq.c 
> b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_hwseq.c
> index cacb557a3014..666e2809d9dc 100644
> --- a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_hwseq.c
> +++ b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_hwseq.c
> @@ -31,7 +31,6 @@
>  #include "clk_mgr.h"
>  #include "reg_helper.h"
>  #include "abm.h"
> -#include "clk_mgr.h"
>  #include "hubp.h"
>  #include "dchubbub.h"
>  #include "timing_generator.h"
> --
> 2.20.1.7.g153144c
>


Re: [PATCH -next 2/4] drm/amd/display: Remove duplicated include in dcn35_optc.c

2023-09-05 Thread Alex Deucher
Applied.  Thanks!

On Thu, Aug 31, 2023 at 8:52 PM Yang Li  wrote:
>
> ./drivers/gpu/drm/amd/display/dc/dcn35/dcn35_optc.c: dcn35_optc.h is included 
> more than once.
>
> Signed-off-by: Yang Li 
> ---
>  drivers/gpu/drm/amd/display/dc/dcn35/dcn35_optc.c | 1 -
>  1 file changed, 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_optc.c 
> b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_optc.c
> index d64be1a5071c..2bea1e475096 100644
> --- a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_optc.c
> +++ b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_optc.c
> @@ -23,7 +23,6 @@
>   */
>
>  #include "dcn35_optc.h"
> -#include "dcn35_optc.h"
>
>  #include "dcn30/dcn30_optc.h"
>  #include "dcn31/dcn31_optc.h"
> --
> 2.20.1.7.g153144c
>


Re: [PATCH -next 1/4] drm/amd/display: Remove duplicated include in dcn35_resource.c

2023-09-05 Thread Alex Deucher
Applied.  Thanks!

On Thu, Aug 31, 2023 at 8:52 PM Yang Li  wrote:
>
> ./drivers/gpu/drm/amd/display/dc/dcn35/dcn35_resource.c: 
> dcn31/dcn31_dio_link_encoder.h is included more than once.
>
> Signed-off-by: Yang Li 
> ---
>  drivers/gpu/drm/amd/display/dc/dcn35/dcn35_resource.c | 1 -
>  1 file changed, 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_resource.c 
> b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_resource.c
> index 0386b8fb270d..7f059fc2fc75 100644
> --- a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_resource.c
> +++ b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_resource.c
> @@ -61,7 +61,6 @@
>  #include "dcn32/dcn32_hpo_dp_link_encoder.h"
>  #include "link.h"
>  #include "dcn31/dcn31_apg.h"
> -#include "dcn31/dcn31_dio_link_encoder.h"
>  #include "dcn32/dcn32_dio_link_encoder.h"
>  #include "dcn31/dcn31_vpg.h"
>  #include "dcn31/dcn31_afmt.h"
> --
> 2.20.1.7.g153144c
>


Re: [RFC,drm-misc-next v4 3/9] drm/radeon: Implement .be_primary() callback

2023-09-05 Thread suijingfeng

Hi,


On 2023/9/5 13:50, Christian König wrote:

Am 04.09.23 um 21:57 schrieb Sui Jingfeng:

From: Sui Jingfeng 

On a machine with multiple GPUs, a Linux user has no control over 
which one

is primary at boot time.


Question is why is that useful? Should we give users the ability to 
control that?


I don't see an use case for this.



On a specific machine with multiple GPUs mounted, only the
primary graphics get POST-ed (initialized) by the firmware.
Therefore the DRM drivers for the rest video cards have to
work without the prerequisite setups done by firmware, This
is called as POST.

One of the use cases is to test if a specific DRM driver
would works properly, under the circumstance of not being
POST-ed, The ast drm driver is the first one which refused
to work if not being POST-ed by the firmware.

Before apply this series, I was unable make drm/ast as the
primary video card easily. The problem is that on a multiple
video card configuration, the monitor connected with my
AST2400 card not light up. While confusing, a naive programmer
may suspect the PRIME is not working.

After applied this series and passing ast.modeset=10 on the
kernel cmd line, I found that the monitor connected with my
ast2400 video card still black, It doesn't display and It
doesn't show image to me.

While in the process of study drm/ast, I know that drm/ast
driver has the POST code shipped, See the ast_post_gpu() function.
Then, I was wondering why this function doesn't works.

After a short-time (hasty) debugging, I found that the ast_post_gpu()
function didn't get run. Because it have something to do with the
ast->config_mode. Without thinking too much, I hardcoded the
ast->config_mode as ast_use_p2a, the key point is to force the
ast_post_gpu() function to run.


```

--- a/drivers/gpu/drm/ast/ast_main.c
+++ b/drivers/gpu/drm/ast/ast_main.c
@@ -132,6 +132,8 @@ static int ast_device_config_init(struct ast_device 
*ast)

    }
    }

+   ast->config_mode = ast_use_p2a;
+
    switch (ast->config_mode) {
    case ast_use_defaults:
    drm_info(dev, "Using default configuration\n");

```

Then, the monitor light up, it display the Ubuntu greeter to me. Therefore
my patch is useful, at least for the Linux drm driver tester and developer.
It allow programmers to test the specific part of a specific driver without
changing a line of the source code and without the need of sudo authority.

It improves the efficiency of the testing and patch verification. I know
the PrimaryGPU option of Xorg conf, but this approach will remember the
setup have been made, you need modify it with root authority each time
you want to switch the primary. But on the process of rapid developing
and/or testing for multiple video drivers, with only one computer hardware
resource available. What we really want is a one-shot command, as provided
by this series.  So, this is the first use case.


The second use case is that sometime the firmware is not reliable.
While there are thousands of ARM64, PowerPC and Mips servers machine,
Most of them don't have a good UEFI firmware support. I haven't test the
drm/amdgpu and drm/radeon at my ARM64 server yet. Because this ARM64
server always use the platform(BMC) integrated display controller as primary.
The UEFI firmware of it does not provide options menu to tune.
So, for the first time, the discrete card because useless, despite more 
powerful.
I will take time to carry on the testing, so I will be able to tell more
in the future.


Even on X86, when select the PEG as primary on the UEFI BIOS menu.
There is no way to tell the bios which one of my three
discrete video be the primary. Not to mention some old UEFI
firmware, which doesn't provide a setting at all.
While the benefit of my approach is the flexibility.
Yes the i915, amdgpu and radeon are good quality,
but there may have programmers want to try nouveau.


The third use case is that VGAARB is also not reliable, It will
select a wrong device as primary. Especially on Arm64, Loongarch
and mips arch etc. And the X server will use this wrong device
as primary and completely crash there. Either because of lacking
a driver or the driver has a bug which can not bear the graphic
environment up. VGAARB is firmware dependent.
My patch provide a temporary method to rescue.


The forth is probably the PRIME and reverse PRIME development
and developing driver for new video cards.



Re: [PATCH] drm/amdgpu: clean up some inconsistent indenting

2023-09-05 Thread Alex Deucher
Applied and dropped the printk.

Alex

On Fri, Sep 1, 2023 at 3:40 AM Christian König  wrote:
>
> Am 01.09.23 um 09:02 schrieb Jiapeng Chong:
> > No functional modification involved.
> >
> > drivers/gpu/drm/amd/amdgpu/nbio_v7_11.c:34 nbio_v7_11_get_rev_id() warn: 
> > inconsistent indenting.
>
>
> We should probably not have a printk here in the first place.
>
> Christian.
>
> >
> > Reported-by: Abaci Robot 
> > Closes: https://bugzilla.openanolis.cn/show_bug.cgi?id=6316
> > Signed-off-by: Jiapeng Chong 
> > ---
> >   drivers/gpu/drm/amd/amdgpu/nbio_v7_11.c | 5 ++---
> >   1 file changed, 2 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v7_11.c 
> > b/drivers/gpu/drm/amd/amdgpu/nbio_v7_11.c
> > index 7c08e5f95e97..76e21357dd4d 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/nbio_v7_11.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/nbio_v7_11.c
> > @@ -31,10 +31,9 @@
> >   static u32 nbio_v7_11_get_rev_id(struct amdgpu_device *adev)
> >   {
> >   u32 tmp;
> > - printk("%s, getid\n",__func__);
> > -
> > - tmp = RREG32_SOC15(NBIO, 0, 
> > regRCC_STRAP1_RCC_DEV0_EPF0_STRAP0);
> >
> > + printk("%s, getid\n", __func__);
> > + tmp = RREG32_SOC15(NBIO, 0, regRCC_STRAP1_RCC_DEV0_EPF0_STRAP0);
> >   tmp &= RCC_STRAP0_RCC_DEV0_EPF0_STRAP0__STRAP_ATI_REV_ID_DEV0_F0_MASK;
> >   tmp >>= 
> > RCC_STRAP0_RCC_DEV0_EPF0_STRAP0__STRAP_ATI_REV_ID_DEV0_F0__SHIFT;
> >
>


[PATCH] drm/amd/display: Remove unwanted drm edid references

2023-09-05 Thread Alex Hung
[WHY]
edid_override and drm_edid_override_connector_update, according to drm
documentation, should not be referred outside drm_edid.

[HOW]
Remove and replace them accordingly.

Signed-off-by: Alex Hung 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 23 ++-
 1 file changed, 2 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 1bb1a394f55f..f6a255773242 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -6372,15 +6372,12 @@ amdgpu_dm_connector_late_register(struct drm_connector 
*connector)
 static void amdgpu_dm_connector_funcs_force(struct drm_connector *connector)
 {
struct amdgpu_dm_connector *aconnector = 
to_amdgpu_dm_connector(connector);
+   struct amdgpu_connector *amdgpu_connector = 
to_amdgpu_connector(connector);
struct dc_link *dc_link = aconnector->dc_link;
struct dc_sink *dc_em_sink = aconnector->dc_em_sink;
struct edid *edid;
 
-   if (!connector->edid_override)
-   return;
-
-   drm_edid_override_connector_update(&aconnector->base);
-   edid = aconnector->base.edid_blob_ptr->data;
+   edid = drm_get_edid(connector, &amdgpu_connector->ddc_bus->aux.ddc);
aconnector->edid = edid;
 
/* Update emulated (virtual) sink's EDID */
@@ -6421,22 +6418,6 @@ static void create_eml_sink(struct amdgpu_dm_connector 
*aconnector)
};
struct edid *edid;
 
-   if (!aconnector->base.edid_blob_ptr) {
-   /* if connector->edid_override valid, pass
-* it to edid_override to edid_blob_ptr
-*/
-
-   drm_edid_override_connector_update(&aconnector->base);
-
-   if (!aconnector->base.edid_blob_ptr) {
-   DRM_ERROR("No EDID firmware found on connector: %s 
,forcing to OFF!\n",
-   aconnector->base.name);
-
-   aconnector->base.force = DRM_FORCE_OFF;
-   return;
-   }
-   }
-
edid = (struct edid *) aconnector->base.edid_blob_ptr->data;
 
aconnector->edid = edid;
-- 
2.42.0



Re: [RFC PATCH 04/10] drm/panel_helper: Introduce drm_panel_helper

2023-09-05 Thread Doug Anderson
Hi,

On Mon, Sep 4, 2023 at 8:33 AM Maxime Ripard  wrote:
>
> > I don't understand the benefit of switching to refcounting, though. We
> > don't ever expect the "prepare" or "enable" function to be called more
> > than once and all we're guarding against is a double-unprepare and a
> > double-enable. Switching this to refcounting would make the reader
> > think that there was a legitimate case for things to be prepared or
> > enabled twice. As far as I know, there isn't.
>
> Sure, eventually we'll want to remove it.
>
> I even said it as such here:
> https://lore.kernel.org/dri-devel/wwzbd7dt5qyimshnd7sbgkf5gxk7tq5dxtrerz76uw5p6s7tzt@cbiezkfeuqqn/
>
> However, we have a number of panels following various anti-patterns
> where disable and unprepare would be called multiple times. A boolean
> would just ignore the second, refcounting would warn over it, and that's
> what we want.

Can you provide a concrete example of a case where refcounting would
give a better error? I'm still having a hard time understanding why
you are saying that refcounting is better and something concrete would
help me. Can you point at a driver you have in mind that follows an
anti-pattern where refcount would be better?

I'll try to be more concrete too and maybe you can point out where I'm
confused. As far as I understand the only difference between the
boolean and the refcount would be if someone _enabled_ or _prepared_
more than once, right? That would cause a refcount to increment to 2
but the boolean would stay at "true". I'm not aware of anyone calling
enable or prepare more than once, but maybe you are? ...or maybe
there's some other difference that I'm not aware of?

Said another way...

With a boolean and _not_ having more than one enable:

1. enable() => set "enabled" to true and enable panel.
2. disable() => set "enabled" to false and disable panel.
3. disable() => WARN, leave "enabled" as false.
4. disable() => WARN, leave "enabled" as false

With a refcount and _not_ having more than one enable:

1. enable() => refcount becomes 1 and enable panel
2. disable() => refcount becomes 0 and disable panel
3. disable() => WARN, refcount stays 0
4. disable() => WARN, refcount stays 0

So with only one enable the behavior is the same.

With a boolean and more than one enable:

1. enable() => set "enabled" to true and enable panel.
2. enable() => WARN, leave "enabled" as true
3. disable() => set "enabled" to false and disable panel.
4. disable() => WARN, leave "enabled" as false.
5. disable() => WARN, leave "enabled" as false

With a refcount and more than one enable:

1. enable() => refcount becomes 1 and enable panel
2. enable() => refcount becomes 2
3. disable() => refcount becomes 1
4. disable() => refcount becomes 0 and disable panel
5. disable() => WARN, refcount stays 0

In the case that there is more than one enable, I think the "boolean"
is better. Specifically:

a) It doesn't change behavior from today. Perhaps you can show me a
counterexample, but lacking that I'd assert that everyone today is
expecting things to work like the "boolean" case. If we change to a
refcount I think it could break someone. Even if nobody is relying on
things working like the "boolean" case today, I would assert that I
don't think anyone is expecting things to work like the "refcount"
case.

b) With a boolean we WARN at more appropriate times. Sure we could add
a warning when the refcount becomes 2, but at that point why aren't we
just using a boolean?

c) The "boolean" case is already implemented today so no patches need
to be sent for it.


> > In any case, I don't think there's any need to switch this to
> > refcounting as part of this effort. Someone could, in theory, do it as
> > a separate patch series.
>
> I'm sorry, but I'll insist on getting a solution that will warn panels
> that call drm_atomic_helper_shutdown or drm_panel_disable/unprepare by
> hand. It doesn't have to be refcounting though if you have a better idea
> in mind.

As per above, I think this already happens with the boolean? Won't you
see an error message like this:

dev_warn(panel->dev, "Skipping unprepare of already unprepared panel\n");

...from drm_panel_unprepare()


> > > > The above solves the problem with panels wanting to power sequence
> > > > themselves at remove() time, but not at shutdown() time. Thus we'd
> > > > still have a dependency on having all drivers use
> > > > drm_atomic_helper_shutdown() so that work becomes a dependency.
> > >
> > > Does it? I think it can be done in parallel?
> >
> > I don't think it can be in parallel. While it makes sense for panels
> > to call drm_panel_remove() at remove time, it doesn't make sense for
> > them to call it at shutdown time. That means that the trick of having
> > the panel get powered off in drm_panel_remove() won't help for
> > shutdown. For shutdown, which IMO is the more important case, we need
> > to wait until all drm drivers call drm_atomic_helper_shutdown()
> > properly.
>
> Right, my point was more

Re: [RFC, drm-misc-next v4 0/9] PCI/VGA: Allowing the user to select the primary video adapter at boot time

2023-09-05 Thread Alex Williamson
On Wed, 6 Sep 2023 00:21:09 +0800
suijingfeng  wrote:

> Hi,
> 
> On 2023/9/5 22:52, Alex Williamson wrote:
> > On Tue,  5 Sep 2023 03:57:15 +0800
> > Sui Jingfeng  wrote:
> >  
> >> From: Sui Jingfeng 
> >>
> >> On a machine with multiple GPUs, a Linux user has no control over which
> >> one is primary at boot time. This series tries to solve above mentioned
> >> problem by introduced the ->be_primary() function stub. The specific
> >> device drivers can provide an implementation to hook up with this stub by
> >> calling the vga_client_register() function.
> >>
> >> Once the driver bound the device successfully, VGAARB will call back to
> >> the device driver. To query if the device drivers want to be primary or
> >> not. Device drivers can just pass NULL if have no such needs.
> >>
> >> Please note that:
> >>
> >> 1) The ARM64, Loongarch, Mips servers have a lot PCIe slot, and I would
> >> like to mount at least three video cards.
> >>
> >> 2) Typically, those non-86 machines don't have a good UEFI firmware
> >> support, which doesn't support select primary GPU as firmware stage.
> >> Even on x86, there are old UEFI firmwares which already made undesired
> >> decision for you.
> >>
> >> 3) This series is attempt to solve the remain problems at the driver level,
> >> while another series[1] of me is target to solve the majority of the
> >> problems at device level.
> >>
> >> Tested (limited) on x86 with four video card mounted, Intel UHD Graphics
> >> 630 is the default boot VGA, successfully override by ast2400 with
> >> ast.modeset=10 append at the kernel cmd line.
> >>
> >> $ lspci | grep VGA
> >>
> >>   00:02.0 VGA compatible controller: Intel Corporation CoffeeLake-S GT2 
> >> [UHD Graphics 630]  
> > In all my previous experiments with VGA routing and IGD I found that
> > IGD can't actually release VGA routing and Intel confirmed the hardware
> > doesn't have the ability to do so.  It will always be primary from a
> > VGA routing perspective.  Was this actually tested with non-UEFI?  
> 
> Yes, I have tested on my aspire e471 notebook (i5 5200U),
> because that notebook using legacy firmware (also have UEFI, double firmware).
> But this machine have difficult in install ubuntu under UEFI firmware in the 
> past.
> So I keep it using the legacy firmware.
> 
> It have two video card, IGD and nvidia video card(GFORCE 840M).
> nvidia call its video card as 3D controller (pci->class = 0x030200)
> 
> I have tested this patch and another patch mention at [1] together.
> I can tell you that the firmware framebuffer of this notebook using vesafb, 
> not efifb.
> And the framebuffer size (lfb.size) is very small. This is very strange,
> but I don't have enough time to look in details. But still works.
> 
> I'm using and tesing my patch whenever and wherever possible.

So you're testing VGA routing using a non-VGA 3D controller through the
VESA address space?  How does that test anything about VGA routing?

> > I suspect it might only work in UEFI mode where we probably don't
> > actually have a dependency on VGA routing.  This is essentially why
> > vfio requires UEFI ROMs when assigning GPUs to VMs, VGA routing is too
> > broken to use on Intel systems with IGD.  Thanks,  
> 
> 
> What you tell me here is the side effect come with the VGA-compatible,
> but I'm focus on the arbitration itself. I think there no need to keep
> the VGA routing hardware features nowadays except that hardware vendor
> want keep the backward compatibility and/or comply the PCI VGA compatible 
> spec.

"VGA arbitration" is the mediation of VGA routing between devices, so
I'm confused how you can be focused on the arbitration without the
routing itself.  Thanks,

Alex



Re: [PATCH v5 09/17] drm/imagination: Implement power management

2023-09-05 Thread Frank Binns
Hi Paul,

On Wed, 2023-08-16 at 12:56 +0200, Paul Cercueil wrote:
> Hi Sarah,
> 
> Le mercredi 16 août 2023 à 09:25 +0100, Sarah Walker a écrit :
> > Add power management to the driver, using runtime pm. The power off
> > sequence depends on firmware commands which are not implemented in
> > this
> > patch.
> > 
> > Changes since v4:
> > - Suspend runtime PM before unplugging device on rmmod
> > 
> > Changes since v3:
> > - Don't power device when calling pvr_device_gpu_fini()
> > - Documentation for pvr_dev->lost has been improved
> > - pvr_power_init() renamed to pvr_watchdog_init()
> > - Use drm_dev_{enter,exit}
> > 
> > Changes since v2:
> > - Use runtime PM
> > - Implement watchdog
> > 
> > Signed-off-by: Sarah Walker 
> > ---
> >  drivers/gpu/drm/imagination/Makefile |   1 +
> >  drivers/gpu/drm/imagination/pvr_device.c |  23 +-
> >  drivers/gpu/drm/imagination/pvr_device.h |  22 ++
> >  drivers/gpu/drm/imagination/pvr_drv.c|  20 +-
> >  drivers/gpu/drm/imagination/pvr_power.c  | 271
> > +++
> >  drivers/gpu/drm/imagination/pvr_power.h  |  39 
> >  6 files changed, 373 insertions(+), 3 deletions(-)
> >  create mode 100644 drivers/gpu/drm/imagination/pvr_power.c
> >  create mode 100644 drivers/gpu/drm/imagination/pvr_power.h
> > 
> > diff --git a/drivers/gpu/drm/imagination/Makefile
> > b/drivers/gpu/drm/imagination/Makefile
> > index 8fcabc1bea36..235e2d329e29 100644
> > --- a/drivers/gpu/drm/imagination/Makefile
> > +++ b/drivers/gpu/drm/imagination/Makefile
> > @@ -10,6 +10,7 @@ powervr-y := \
> > pvr_fw.o \
> > pvr_gem.o \
> > pvr_mmu.o \
> > +   pvr_power.o \
> > pvr_vm.o
> >  
> >  obj-$(CONFIG_DRM_POWERVR) += powervr.o
> > diff --git a/drivers/gpu/drm/imagination/pvr_device.c
> > b/drivers/gpu/drm/imagination/pvr_device.c
> > index ef8f7a2ff1a9..5dbd05f21238 100644
> > --- a/drivers/gpu/drm/imagination/pvr_device.c
> > +++ b/drivers/gpu/drm/imagination/pvr_device.c
> > @@ -5,6 +5,7 @@
> >  #include "pvr_device_info.h"
> >  
> >  #include "pvr_fw.h"
> > +#include "pvr_power.h"
> >  #include "pvr_rogue_cr_defs.h"
> >  #include "pvr_vm.h"
> >  
> > @@ -357,6 +358,8 @@ pvr_device_gpu_fini(struct pvr_device *pvr_dev)
> >  int
> >  pvr_device_init(struct pvr_device *pvr_dev)
> >  {
> > +   struct drm_device *drm_dev = from_pvr_device(pvr_dev);
> > +   struct device *dev = drm_dev->dev;
> > int err;
> >  
> > /* Enable and initialize clocks required for the device to
> > operate. */
> > @@ -364,13 +367,29 @@ pvr_device_init(struct pvr_device *pvr_dev)
> > if (err)
> > return err;
> >  
> > +   /* Explicitly power the GPU so we can access control
> > registers before the FW is booted. */
> > +   err = pm_runtime_resume_and_get(dev);
> > +   if (err)
> > +   return err;
> > +
> > /* Map the control registers into memory. */
> > err = pvr_device_reg_init(pvr_dev);
> > if (err)
> > -   return err;
> > +   goto err_pm_runtime_put;
> >  
> > /* Perform GPU-specific initialization steps. */
> > -   return pvr_device_gpu_init(pvr_dev);
> > +   err = pvr_device_gpu_init(pvr_dev);
> > +   if (err)
> > +   goto err_pm_runtime_put;
> > +
> > +   pm_runtime_put(dev);
> > +
> > +   return 0;
> > +
> > +err_pm_runtime_put:
> > +   pm_runtime_put_sync_suspend(dev);
> > +
> > +   return err;
> >  }
> >  
> >  /**
> > diff --git a/drivers/gpu/drm/imagination/pvr_device.h
> > b/drivers/gpu/drm/imagination/pvr_device.h
> > index 990363e433d7..6d58ecfbc838 100644
> > --- a/drivers/gpu/drm/imagination/pvr_device.h
> > +++ b/drivers/gpu/drm/imagination/pvr_device.h
> > @@ -135,6 +135,28 @@ struct pvr_device {
> >  
> > /** @fw_dev: Firmware related data. */
> > struct pvr_fw_device fw_dev;
> > +
> > +   struct {
> > +   /** @work: Work item for watchdog callback. */
> > +   struct delayed_work work;
> > +
> > +   /** @old_kccb_cmds_executed: KCCB command execution
> > count at last watchdog poll. */
> > +   u32 old_kccb_cmds_executed;
> > +
> > +   /** @kccb_stall_count: Number of watchdog polls KCCB
> > has been stalled for. */
> > +   u32 kccb_stall_count;
> > +   } watchdog;
> > +
> > +   /**
> > +* @lost: %true if the device has been lost.
> > +*
> > +* This variable is set if the device has become
> > irretrievably unavailable, e.g. if the
> > +* firmware processor has stopped responding and can not be
> > revived via a hard reset.
> > +*/
> > +   bool lost;
> > +
> > +   /** @sched_wq: Workqueue for schedulers. */
> > +   struct workqueue_struct *sched_wq;
> >  };
> >  
> >  /**
> > diff --git a/drivers/gpu/drm/imagination/pvr_drv.c
> > b/drivers/gpu/drm/imagination/pvr_drv.c
> > index 0d51177b506c..0331dc549116 100644
> > --- a/drivers/

Re: [PATCH v5 02/17] dt-bindings: gpu: Add Imagination Technologies PowerVR GPU

2023-09-05 Thread Frank Binns
Hi Linus,

Thank you for your feedback (comments below).

On Fri, 2023-08-18 at 11:36 +0200, Linus Walleij wrote:
> Hi Sarah,
> 
> thanks for your patch!
> 
> Patches adding device tree bindings need to be CC:ed to
> devicet...@vger.kernel.org
> and the DT binding maintainers, I have added it for now.

Thank you - it looks like something went wrong when the patch was sent.

> 
> On Wed, Aug 16, 2023 at 10:26 AM Sarah Walker  wrote:
> 
> > Add the device tree binding documentation for the Series AXE GPU used in
> > TI AM62 SoCs.
> > 
> > Co-developed-by: Frank Binns 
> > Signed-off-by: Frank Binns 
> > Signed-off-by: Sarah Walker 
> (...)
> > +properties:
> > +  compatible:
> > +items:
> > +  - enum:
> > +  - ti,am62-gpu
> > +  - const: img,powervr-seriesaxe
> 
> Should there not at least be a dash there?
> 
> img,powervr-series-axe?
> 
> It is spelled in two words in the commit message,
> Series AXE not SeriesAXE?

We've now changed the string to address your earlier feedback (see below).

> 
> Moreover, if this pertains to the AXE-1-16 and AXE-2-16 it is kind of a 
> wildcard
> and we usually don't do that, I would use the exact version instead,
> such as:
> const: img,powervr-axe-1-16
> any reason not to do this?

The exact GPU model/revision is fully discoverable via a register. We saw the
same is also true for Mali Bifrost, where they have a single string covering
multiple models [1], so we took the same approach. We'll add a comment in v6
along the lines of the one in the Mali Bifrost bindings.

> 
> I asked about the relationship between these strings and the product
> designations earlier I think :/

Sorry about that, I honestly thought we'd addressed that bit of feedback by
changing the compatibility string, but clearly we hadn't :( Thank you for
catching this.

We've now changed the string to "img,img-axe" to align with the marketing name,
along with updating the commit message and various other places to refer to
PowerVR and IMG GPUs (the DRM driver supporting both).

Thanks
Frank

[1] 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/gpu/arm,mali-bifrost.yaml?h=v6.5#n29



Re: [RFC, drm-misc-next v4 0/9] PCI/VGA: Allowing the user to select the primary video adapter at boot time

2023-09-05 Thread suijingfeng

Hi,

On 2023/9/5 22:52, Alex Williamson wrote:

On Tue,  5 Sep 2023 03:57:15 +0800
Sui Jingfeng  wrote:


From: Sui Jingfeng 

On a machine with multiple GPUs, a Linux user has no control over which
one is primary at boot time. This series tries to solve above mentioned
problem by introduced the ->be_primary() function stub. The specific
device drivers can provide an implementation to hook up with this stub by
calling the vga_client_register() function.

Once the driver bound the device successfully, VGAARB will call back to
the device driver. To query if the device drivers want to be primary or
not. Device drivers can just pass NULL if have no such needs.

Please note that:

1) The ARM64, Loongarch, Mips servers have a lot PCIe slot, and I would
like to mount at least three video cards.

2) Typically, those non-86 machines don't have a good UEFI firmware
support, which doesn't support select primary GPU as firmware stage.
Even on x86, there are old UEFI firmwares which already made undesired
decision for you.

3) This series is attempt to solve the remain problems at the driver level,
while another series[1] of me is target to solve the majority of the
problems at device level.

Tested (limited) on x86 with four video card mounted, Intel UHD Graphics
630 is the default boot VGA, successfully override by ast2400 with
ast.modeset=10 append at the kernel cmd line.

$ lspci | grep VGA

  00:02.0 VGA compatible controller: Intel Corporation CoffeeLake-S GT2 [UHD 
Graphics 630]

In all my previous experiments with VGA routing and IGD I found that
IGD can't actually release VGA routing and Intel confirmed the hardware
doesn't have the ability to do so.  It will always be primary from a
VGA routing perspective.  Was this actually tested with non-UEFI?


Yes, I have tested on my aspire e471 notebook (i5 5200U),
because that notebook using legacy firmware (also have UEFI, double firmware).
But this machine have difficult in install ubuntu under UEFI firmware in the 
past.
So I keep it using the legacy firmware.

It have two video card, IGD and nvidia video card(GFORCE 840M).
nvidia call its video card as 3D controller (pci->class = 0x030200)

I have tested this patch and another patch mention at [1] together.
I can tell you that the firmware framebuffer of this notebook using vesafb, not 
efifb.
And the framebuffer size (lfb.size) is very small. This is very strange,
but I don't have enough time to look in details. But still works.

I'm using and tesing my patch whenever and wherever possible.


I suspect it might only work in UEFI mode where we probably don't
actually have a dependency on VGA routing.  This is essentially why
vfio requires UEFI ROMs when assigning GPUs to VMs, VGA routing is too
broken to use on Intel systems with IGD.  Thanks,



What you tell me here is the side effect come with the VGA-compatible,
but I'm focus on the arbitration itself. I think there no need to keep
the VGA routing hardware features nowadays except that hardware vendor
want keep the backward compatibility and/or comply the PCI VGA compatible spec.



Alex





Re: [Nouveau] [RFC, drm-misc-next v4 0/9] PCI/VGA: Allowing the user to select the primary video adapter at boot time

2023-09-05 Thread suijingfeng



On 2023/9/5 18:49, Thomas Zimmermann wrote:

Hi

Am 04.09.23 um 21:57 schrieb Sui Jingfeng:

From: Sui Jingfeng 

On a machine with multiple GPUs, a Linux user has no control over which
one is primary at boot time. This series tries to solve above mentioned
problem by introduced the ->be_primary() function stub. The specific
device drivers can provide an implementation to hook up with this 
stub by

calling the vga_client_register() function.

Once the driver bound the device successfully, VGAARB will call back to
the device driver. To query if the device drivers want to be primary or
not. Device drivers can just pass NULL if have no such needs.

Please note that:

1) The ARM64, Loongarch, Mips servers have a lot PCIe slot, and I would
    like to mount at least three video cards.

2) Typically, those non-86 machines don't have a good UEFI firmware
    support, which doesn't support select primary GPU as firmware stage.
    Even on x86, there are old UEFI firmwares which already made 
undesired

    decision for you.

3) This series is attempt to solve the remain problems at the driver 
level,

    while another series[1] of me is target to solve the majority of the
    problems at device level.

Tested (limited) on x86 with four video card mounted, Intel UHD Graphics
630 is the default boot VGA, successfully override by ast2400 with
ast.modeset=10 append at the kernel cmd line.


FYI: per-driver modeset parameters are deprecated and not to be used. 
Please don't promote them.



Well, please wait, I want to explain.



drm/nouveau already promote it a little bit.

Despite no code of conduct or specification guiding how the modules parameters 
should be.
Noticed that there already have a lot of DRM drivers support the modeset 
parameters,
for the modeset parameter, authors of various device driver try to make the 
usage not
conflict with others. I believe that this is good thing for Linux users.
It is probably the responsibility of the drm core maintainers to force various 
drm
drivers to reach a minimal consensus. Probably it pains to do so and doesn't 
pay off.
But reach a minimal consensus do benefit to Linux users.


You can use modprobe.blacklist or initcall_blacklist on the kernel 
command line.



There are some cases where the modprobe.blacklist doesn't works,
I have come cross several time during the past.
Because the device selected by the VGAARB is device-level thing,
it is not the driver's problem.

Sometimes when VGAARB has a bug, it will select a wrong device as primary.
And the X server will use this wrong device as primary and completely crash
there, due to lack a driver. Take my old S3 Graphics as an example:

$ lspci | grep VGA

 00:06.1 VGA compatible controller: Loongson Technology LLC DC (Display 
Controller) (rev 01)
 03:00.0 VGA compatible controller: Advanced Micro Devices, Inc. [AMD/ATI] 
Caicos XT [Radeon HD 7470/8470 / R5 235/310 OEM]
 07:00.0 VGA compatible controller: S3 Graphics Ltd. Device 9070 (rev 01)
 08:00.0 VGA compatible controller: S3 Graphics Ltd. Device 9070 (rev 01)

Before apply this patch:

[0.361748] pci :00:06.1: vgaarb: setting as boot VGA device
[0.361753] pci :00:06.1: vgaarb: VGA device added: 
decodes=io+mem,owns=io+mem,locks=none
[0.361765] pci :03:00.0: vgaarb: VGA device added: 
decodes=io+mem,owns=none,locks=none
[0.361773] pci :07:00.0: vgaarb: VGA device added: 
decodes=io+mem,owns=none,locks=none
[0.361779] pci :08:00.0: vgaarb: VGA device added: 
decodes=io+mem,owns=none,locks=none
[0.361781] vgaarb: loaded
[0.367838] pci :00:06.1: Overriding boot device as 1002:6778
[0.367841] pci :00:06.1: Overriding boot device as 5333:9070
[0.367843] pci :00:06.1: Overriding boot device as 5333:9070


For known reason, one of my system select the S3 Graphics as primary GPU.
But this S3 Graphics not even have a decent drm upstream driver yet.
Under such a case, I begin to believe that only the device who has a
driver deserve the primary.

Under such a condition, I want to reboot and enter the graphic environment
with other working video cards. Either platform integrated and discrete GPU.
This don't means I should compromise by un-mount the S3 graphics card from
the motherboard, this also don't means that I should update my BIOS setting.
As sometimes, the BIOS is more worse.

With this series applied, all I need to do is to reboot the computer and
pass a command line. By force override another video card (who has a
decent driver support) as primary, I'm able to do the debugging under
graphic environment. I would like to examine what's wrong with the vgaarb
on a specific platform under X server graphic environment.

Probably try compile a driver for this card and see it works, simply reboot
without the need to change anything. It is so efficient. So this is probably
the second usage of my patch. It hand the right of control back to the
graphic developer.




Re: [RFC PATCH 0/5] drm/amd/display: improve DTN color state log

2023-09-05 Thread Melissa Wen
On 09/05, Melissa Wen wrote:
> Hi,
> 
> I'm updating the color state part of DTN log to match DCN3.0 HW better.
> Currently, the DTN log considers the DCN10 color pipeline, which is
> useless for DCN3.0 because of all the differences in color caps between
> DCN versions. In addition to new color blocks and caps, some semantic
> differences made the DCN10 output not fit DCN30.
> 
> In this RFC, the first patch adds new color state elements to DPP and
> implements the reading of registers according to HW blocks. Similarly to
> MPC, the second patch also creates a DCN3-specific function to read the
> MPC state and add the MPC color state logging to it. With DPP and MPC
> color-register reading, I detach DCN10 color state logging from the HW
> log and create a `.log_color_state` hook for logging color state
> according to HW color blocks with DCN30 as the first use case. Finally,
> the last patch adds DPP and MPC color caps output to facilitate
> understanding of the color state log.
> 
> This version works well with the driver-specific color properties[1] and
> steamdeck/gamescope[2] together, where we can see color state changing
> from default values.

For comparison, here is the before and after of DPP and MPC section in
the DTN log on Steam Deck + driver-specific color properties:

Without this series:
===
DPP:IGAM format  IGAM modeDGAM modeRGAM mode  GAMUT mode  C11 C12   
C13 C14   C21 C22   C23 C24   C31 C32   C33 C34
[ 0]:0h  BypassFixed  Bypass   Bypass0h 
h h h h h
[ 3]:0h  BypassFixed  Bypass   Bypass0h 
h h h h h

MPCC:  OPP  DPP  MPCCBOT  MODE  ALPHA_MODE  PREMULT  OVERLAP_ONLY  IDLE
[ 0]:   0h   0h   3h 3   20 0 0
[ 3]:   0h   3h   fh 2   20 0 0


With this series (Steamdeck/Gamescope):
==

DPP:  DGAM ROM  DGAM ROM type  DGAM LUT  SHAPER mode  3DLUT mode  3DLUT bit 
depth  3DLUT size  RGAM mode  GAMUT mode  C11 C12   C13 C14   C21 C22   C23 C24 
  C31 C32   C33 C34
[ 0]:1   sRGBBypassRAM B   RAM A   
12-bit17x17x17 Bypass   0  h h h 
h h h
[ 3]:1   sRGBBypassRAM B   RAM A   
12-bit17x17x17 Bypass   0  h h h 
h h h

DPP Color Caps: input_lut_shared:0  icsc:1  dgam_ram:0  dgam_rom: 
srgb:1,bt2020:1,gamma2_2:1,pq:1,hlg:1  post_csc:1  gamcor:1  dgam_rom_for_yuv:0 
 3d_lut:1  blnd_lut:1  oscs:0

MPCC:  OPP  DPP  MPCCBOT  MODE  ALPHA_MODE  PREMULT  OVERLAP_ONLY  IDLE  SHAPER 
mode  3DLUT_mode  3DLUT bit-depth  3DLUT size  OGAM mode  OGAM LUT  GAMUT mode  
C11 C12   C33 C34
[ 0]:   0h   0h   3h 3   20 0 0   
Bypass  Bypass   12-bit17x17x17 Bypass A   
0 h h
[ 3]:   0h   3h   fh 2   20 0 0   
Bypass  Bypass   12-bit17x17x17 Bypass A   
0 h h

MPC Color Caps: gamut_remap:1, 3dlut:2, ogam_ram:1, ocsc:1

With this series (Steamdeck/KDE):


DPP:  DGAM ROM  DGAM ROM type  DGAM LUT  SHAPER mode  3DLUT mode  3DLUT bit 
depth  3DLUT size  RGAM mode  GAMUT mode  C11 C12   C13 C14   C21 C22   C23 C24 
  C31 C32   C33 C34
[ 0]:0   sRGBBypass   Bypass  Bypass   
12-bit   9x9x9 Bypass   0  h h h 
h h h
[ 3]:0   sRGBBypass   Bypass  Bypass   
12-bit   9x9x9 Bypass   0  h h h 
h h h

DPP Color Caps: input_lut_shared:0  icsc:1  dgam_ram:0  dgam_rom: 
srgb:1,bt2020:1,gamma2_2:1,pq:1,hlg:1  post_csc:1  gamcor:1  dgam_rom_for_yuv:0 
 3d_lut:1  blnd_lut:1  oscs:0

MPCC:  OPP  DPP  MPCCBOT  MODE  ALPHA_MODE  PREMULT  OVERLAP_ONLY  IDLE  SHAPER 
mode  3DLUT_mode  3DLUT bit-depth  3DLUT size  OGAM mode  OGAM LUT  GAMUT mode  
C11 C12   C33 C34
[ 0]:   0h   0h   3h 3   20 0 0   
Bypass  Bypass   12-bit17x17x17RAM A   
1 2000h 2000h
[ 3]:   0h   3h   fh 2   20 0 0   
Bypass  Bypass   12-bit17x17x17 Bypass A   
0 h h

MPC Color Caps: gamut_remap:1, 3dlut:2, ogam_ram:1, ocsc:1

> 
> Before extending it to other DCN families, I have some doubts. Does this
> approach of the `.log_color_state` hook make sense for you? Is there any
> conflict between logging color state by HW version and DTN log usage? Is
> there a template/style f

Re: [Nouveau] [RFC, drm-misc-next v4 0/9] PCI/VGA: Allowing the user to select the primary video adapter at boot time

2023-09-05 Thread Thomas Zimmermann

Hi

Am 05.09.23 um 15:30 schrieb suijingfeng:

Hi,


On 2023/9/5 18:45, Thomas Zimmermann wrote:

Hi

Am 04.09.23 um 21:57 schrieb Sui Jingfeng:

From: Sui Jingfeng 

On a machine with multiple GPUs, a Linux user has no control over which
one is primary at boot time. This series tries to solve above mentioned


If anything, the primary graphics adapter is the one initialized by 
the firmware. I think our boot-up graphics also make this assumption 
implicitly.




Yes, but by the time of DRM drivers get loaded successfully,the boot-up 
graphics already finished.
Firmware framebuffer device already get killed by the 
drm_aperture_remove_conflicting_pci_framebuffers()
function (or its siblings). So, this series is definitely not to 
interact with the firmware framebuffer


Yes and no. The helpers you mention will attempt to remove the firmware 
framebuffer on the given PCI device. If you have multiple PCI devices, 
the other devices would not be affected.


This also means that probing a non-primary card will not affect the 
firmware framebuffer on the primary card. You can have all these drivers 
co-exist next to each other. If you link a full DRM driver into the 
kernel image, it might even be loaded before the firmware-framebuffer's 
driver.  We had some funny bugs from these interactions.



(or more intelligent framebuffer drivers).  It is for user space 
program, such as X server and Wayland
compositor. Its for Linux user or drm drivers testers, which allow them 
to direct graphic display server

using right hardware of interested as primary video card.

Also, I believe that X server and Wayland compositor are the best test 
examples.

If a specific DRM driver can't work with X server as a primary,
then there probably have something wrong.


If you want to run a userspace compositor or X11 on a certain device, 
you best configure this in the program's config files. But not on the 
kernel command line.


The whole concept of a 'primary' display is bogus IMHO. It only exists 
because old VGA and BIOS (and their equivalents on non-PC systems) were 
unable to use more than one graphics device. Hence, as you write below, 
only the first device got POSTed by the BIOS. If you had an additional 
card, the device driver needed to perform the POSTing.


However, on modern Linux systems the primary display does not really 
exist. 'Primary' is the device that is available via VGA, VESA or EFI. 
Our drivers don't use these interfaces, but the native registers. As you 
said yourself, these firmware devices (VGA, VESA, EFI) are removed ASAP 
by the native drivers.






But what's the use case for overriding this setting?



On a specific machine with multiple GPUs mounted,
only the primary graphics get POST-ed (initialized) by the firmware.
Therefore, the DRM drivers for the rest video cards, have to choose to
work without the prerequisite setups done by firmware, This is called as 
POST.


One of the use cases of this series is to test if a specific DRM driver 
could works properly,
even though there is no prerequisite works have been done by firmware at 
all.

And it seems that the results is not satisfying in all cases.

drm/ast is the first drm drivers which refused to work if not being 
POST-ed by the firmware.


You might have found a bug in the ast driver. Ast has means to detect if 
the device has been POSTed and maybe do that. If this doesn't work 
correctly, it needs a fix.


As Christian mentioned, if anything, you might add an option to specify 
the default card to vgaarb (e.g., as PCI slot). But userspace should 
avoid the idea of a primary card IMHO.


Best regards
Thomas



Before apply this series, I was unable make drm/ast as the primary video 
card easily. On a
multiple video card configuration, the monitor connected with the 
AST2400 not light up.

While confusing, a naive programmer may suspect the PRIME is not working.

After applied this series and passing ast.modeset=10 on the kernel cmd 
line,

I found that the monitor connected with my ast2400 video card still black,
It doesn't display and doesn't show image to me.

While in the process of study drm/ast, I know that drm/ast driver has 
the POST code shipped.
See the ast_post_gpu() function, then, I was wondering why this function 
doesn't works.
After a short-time (hasty) debugging, I found that the the 
ast_post_gpu() function

didn't get run. Because it have something to do with the ast->config_mode.

Without thinking too much, I hardcoded the ast->config_mode as 
ast_use_p2a to

force the ast_post_gpu() function get run.

```

--- a/drivers/gpu/drm/ast/ast_main.c
+++ b/drivers/gpu/drm/ast/ast_main.c
@@ -132,6 +132,8 @@ static int ast_device_config_init(struct ast_device 
*ast)

     }
     }

+   ast->config_mode = ast_use_p2a;
+
     switch (ast->config_mode) {
     case ast_use_defaults:
     drm_info(dev, "Using default configuration\n");

```

Then, the monitor light up, it display the Ubuntu gr

Re: [RFC, drm-misc-next v4 0/9] PCI/VGA: Allowing the user to select the primary video adapter at boot time

2023-09-05 Thread Alex Williamson
On Tue,  5 Sep 2023 03:57:15 +0800
Sui Jingfeng  wrote:

> From: Sui Jingfeng 
> 
> On a machine with multiple GPUs, a Linux user has no control over which
> one is primary at boot time. This series tries to solve above mentioned
> problem by introduced the ->be_primary() function stub. The specific
> device drivers can provide an implementation to hook up with this stub by
> calling the vga_client_register() function.
> 
> Once the driver bound the device successfully, VGAARB will call back to
> the device driver. To query if the device drivers want to be primary or
> not. Device drivers can just pass NULL if have no such needs.
> 
> Please note that:
> 
> 1) The ARM64, Loongarch, Mips servers have a lot PCIe slot, and I would
>like to mount at least three video cards.
> 
> 2) Typically, those non-86 machines don't have a good UEFI firmware
>support, which doesn't support select primary GPU as firmware stage.
>Even on x86, there are old UEFI firmwares which already made undesired
>decision for you.
> 
> 3) This series is attempt to solve the remain problems at the driver level,
>while another series[1] of me is target to solve the majority of the
>problems at device level.
> 
> Tested (limited) on x86 with four video card mounted, Intel UHD Graphics
> 630 is the default boot VGA, successfully override by ast2400 with
> ast.modeset=10 append at the kernel cmd line.
> 
> $ lspci | grep VGA
> 
>  00:02.0 VGA compatible controller: Intel Corporation CoffeeLake-S GT2 [UHD 
> Graphics 630]

In all my previous experiments with VGA routing and IGD I found that
IGD can't actually release VGA routing and Intel confirmed the hardware
doesn't have the ability to do so.  It will always be primary from a
VGA routing perspective.  Was this actually tested with non-UEFI?

I suspect it might only work in UEFI mode where we probably don't
actually have a dependency on VGA routing.  This is essentially why
vfio requires UEFI ROMs when assigning GPUs to VMs, VGA routing is too
broken to use on Intel systems with IGD.  Thanks,

Alex

>  01:00.0 VGA compatible controller: Advanced Micro Devices, Inc. [AMD/ATI] 
> Caicos XTX [Radeon HD 8490 / R5 235X OEM]
>  04:00.0 VGA compatible controller: ASPEED Technology, Inc. ASPEED Graphics 
> Family (rev 30)
>  05:00.0 VGA compatible controller: NVIDIA Corporation GK208B [GeForce GT 
> 720] (rev a1)
> 
> $ sudo dmesg | grep vgaarb
> 
>  pci :00:02.0: vgaarb: setting as boot VGA device
>  pci :00:02.0: vgaarb: VGA device added: 
> decodes=io+mem,owns=io+mem,locks=none
>  pci :01:00.0: vgaarb: VGA device added: 
> decodes=io+mem,owns=none,locks=none
>  pci :04:00.0: vgaarb: VGA device added: 
> decodes=io+mem,owns=none,locks=none
>  pci :05:00.0: vgaarb: VGA device added: 
> decodes=io+mem,owns=none,locks=none
>  vgaarb: loaded
>  ast :04:00.0: vgaarb: Override as primary by driver
>  i915 :00:02.0: vgaarb: changed VGA decodes: 
> olddecodes=io+mem,decodes=none:owns=io+mem
>  radeon :01:00.0: vgaarb: changed VGA decodes: 
> olddecodes=io+mem,decodes=none:owns=none
>  ast :04:00.0: vgaarb: changed VGA decodes: 
> olddecodes=io+mem,decodes=none:owns=none
> 
> v2:
>   * Add a simple implemment for drm/i915 and drm/ast
>   * Pick up all tags (Mario)
> v3:
>   * Fix a mistake for drm/i915 implement
>   * Fix patch can not be applied problem because of merge conflect.
> v4:
>   * Focus on solve the real problem.
> 
> v1,v2 at https://patchwork.freedesktop.org/series/120059/
>v3 at https://patchwork.freedesktop.org/series/120562/
> 
> [1] https://patchwork.freedesktop.org/series/122845/
> 
> Sui Jingfeng (9):
>   PCI/VGA: Allowing the user to select the primary video adapter at boot
> time
>   drm/nouveau: Implement .be_primary() callback
>   drm/radeon: Implement .be_primary() callback
>   drm/amdgpu: Implement .be_primary() callback
>   drm/i915: Implement .be_primary() callback
>   drm/loongson: Implement .be_primary() callback
>   drm/ast: Register as a VGA client by calling vga_client_register()
>   drm/hibmc: Register as a VGA client by calling vga_client_register()
>   drm/gma500: Register as a VGA client by calling vga_client_register()
> 
>  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c| 11 +++-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c   | 13 -
>  drivers/gpu/drm/ast/ast_drv.c | 31 ++
>  drivers/gpu/drm/gma500/psb_drv.c  | 57 ++-
>  .../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c   | 15 +
>  drivers/gpu/drm/i915/display/intel_vga.c  | 15 -
>  drivers/gpu/drm/loongson/loongson_module.c|  2 +-
>  drivers/gpu/drm/loongson/loongson_module.h|  1 +
>  drivers/gpu/drm/loongson/lsdc_drv.c   | 10 +++-
>  drivers/gpu/drm/nouveau/nouveau_vga.c | 11 +++-
>  drivers/gpu/drm/radeon/radeon_device.c| 10 +++-
>  drivers/pci/vgaarb.c  | 43 --
>  drivers/vfio/pci/vfio_pci_core.c   

Re: [RFC][PATCH 0/2] drm/panic: Add a drm panic handler

2023-09-05 Thread Jocelyn Falempe

On 04/09/2023 16:29, Thomas Zimmermann wrote:

Hi Jocelyn,

thanks for moving this effort forward. It's much appreciated. I looked 
through the patches and tried the patchset on my test machine.


Thanks for taking the time to review and test it.


Am 09.08.23 um 21:17 schrieb Jocelyn Falempe:
This introduces a new drm panic handler, which displays a message when 
a panic occurs.

So when fbcon is disabled, you can still see a kernel panic.

This is one of the missing feature, when disabling VT/fbcon in the 
kernel:

https://www.reddit.com/r/linux/comments/10eccv9/config_vtn_in_2023/
Fbcon can be replaced by a userspace kms console, but the panic screen 
must be done in the kernel.


This is a proof of concept, and works only with simpledrm, using the 
drm_client API.
This implementation with the drm client API, allocates new 
framebuffers, and looks a bit too complex to run in a panic handler.
Maybe we should add an API to "steal" the current framebuffer instead, 
because in a panic handler user-space is already stopped.


Yes, that was also my first thought. I'd use an extra callback in struct 
drm_driver, like this:


struct drm_driver {
   int (*get_scanout_buffer)(/* return HW scanout */)
}

The scanout buffer would be described by kernel virtual address address, 
resolution, color format and scanline pitch. And that's what the panic 
handler uses.


Thanks, I will try this solution. It shouldn't be too hard for simpledrm.


Any driver implementing this interface would support the panic handler. 
If there's a concurrent display update, we'd have to synchronize.


Normally in the panic handler, the kernel is already single-threaded, so 
there won't be another task doing things in parallel. (But the GPU might 
still be busy doing other stuff, if we're in the middle of a game).
I think this drm_panic should be a "best effort", we can't guarantee the 
user will see the panic screen in all panic situations.






To test it, make sure you're using the simpledrm driver, and trigger a 
panic:

echo c > /proc/sysrq-trigger


The penguin was cute. :)

This only works if the display is already running. I had to start Gnome 
to set a display mode. Then let the panic handler take over the output.


oh, I didn't expect this limitation. I will try to test that too. It 
might also get fixed by using the get_scanout_buffer() above.


But with simpledrm, we could even display a message without an output, 
as the framebuffer is always there.




There is one thing I don't know how to do, is to unregister the 
drm_panic when the graphic driver is unloaded.
drm_client_register() says it will automatically unregister on driver 
unload. But then I don't know how to remove it from my linked list, 
and free the drm_client_dev struct.


Unregistering wouldn't be necessary with this proposed 
get_scanout_buffer. In the case of a panic, just remain silent if 
there's no driver that provides such a callback.


Is there a way to loop over all drm_devices ?
otherwise drm_panic may still call get_scanout_buffer() on a freed 
device, which would be problematic.




This is a first draft, so let me know what do you think about it.


One thing that will need serious work is the raw output. The current 
blitting for XRGB is really just a quick-and-dirty hack.


I think we should try to reuse fbdev's blitting code, if possible. The 
fbdev core, helpers and console come with all the features we need. We 
really only need to make them work without the struct fb_info, which is 
a full fbdev device.


I'm a bit reluctant to re-use the fbdev code, for a few reasons:
 * I want drm_panic to work if CONFIG_FB and CONFIG_DRM_FBDEV_EMULATION 
are not set.
 * drm_panic only needs two things, to clear the framebuffer, and then 
draw white pixels where needed. As the frame is static, and the amount 
of white pixels is low, that should be good enough. So copy_area() or 
image_blit() are not that useful.
 * For this particular use-case, performances are not a priority, it 
doesn't matter if it takes 10us or 100ms to draw the panic screen, as it 
will stay the same until the user reboots.
 * Some aggressive optimizations might cause issues in a panic handler, 
like if you use workqueue/tasklet.


On the other hand, writing the code for all supported formats is a bit 
tedious. drm_log [1] did it in ~300 lines, which should keep code 
duplication low.




In struct fb_ops, there are callbacks for modifying the framebuffer. [1] 
They are used by fbcon foir drawing. But they operate on fb_info.


For a while I've been thinking about using something like a drawable to 
provide some abstractions:


struct drawable {
 /* store buffer parameters here */
 ...

 struct drawable_funcs *funcs;
};

struct drawable_funcs {
 /* have function pointers similar to struct fb_ops */
 fill_rect()
 copy_area()
 image_blit()
};

We cannot rewrite all the existing fbdev drivers. To make this work with 
fbdev, we'd need adapter code that conver

Re: [PATCH 0/4] drm/bridge: lt8912b: Init & remove related fixes

2023-09-05 Thread Robert Foss
On Fri, 04 Aug 2023 13:48:09 +0300, Tomi Valkeinen wrote:
> Fix various issues in lt8912b driver.
> 
>  Tomi
> 
> 

Fixed the mentioned commit message typos, and an incorrect has
for a "Fixes" tag.

Applied, thanks!

[1/4] drm/bridge: lt8912b: Fix bridge_detach
  https://cgit.freedesktop.org/drm/drm-misc/commit/?id=941882a0e96d
[2/4] drm/bridge: lt8912b: Fix crash on bridge detach
  https://cgit.freedesktop.org/drm/drm-misc/commit/?id=44283993144a
[3/4] drm/bridge: lt8912b: Manually disable HPD only if it was enabled
  https://cgit.freedesktop.org/drm/drm-misc/commit/?id=6985c5efc405
[4/4] drm/bridge: lt8912b: Add missing drm_bridge_attach call
  https://cgit.freedesktop.org/drm/drm-misc/commit/?id=f45acf7acf75



Rob



Re: [PATCH v2] drm: bridge: it66121: Fix invalid connector dereference

2023-09-05 Thread Robert Foss
On Fri, 1 Sep 2023 15:01:23 +0530, Jai Luthra wrote:
> Fix the NULL pointer dereference when no monitor is connected, and the
> sound card is opened from userspace.
> 
> Instead return an empty buffer (of zeroes) as the EDID information to
> the sound framework if there is no connector attached.
> 
> 
> [...]

Applied, thanks!

[1/1] drm: bridge: it66121: Fix invalid connector dereference
  https://cgit.freedesktop.org/drm/drm-misc/commit/?id=d0375f6858c4



Rob



Re: [PATCH 3/3] drm/drm_exec: Work around a WW mutex lockdep oddity

2023-09-05 Thread Thomas Hellström

Hi, Christian

On 9/5/23 15:14, Christian König wrote:

Am 05.09.23 um 10:58 schrieb Thomas Hellström:

If *any* object of a certain WW mutex class is locked, lockdep will
consider *all* mutexes of that class as locked. Also the lock allocation
tracking code will apparently register only the address of the first
mutex locked in a sequence.
This has the odd consequence that if that first mutex is unlocked and
its memory then freed, the lock alloc tracking code will assume that 
memory

is freed with a held lock in there.

For now, work around that for drm_exec by releasing the first grabbed
object lock last.

Related lock alloc tracking warning:
[  322.660067] =
[  322.660070] WARNING: held lock freed!
[  322.660074] 6.5.0-rc7+ #155 Tainted: G U   N
[  322.660078] -
[  322.660081] kunit_try_catch/4981 is freeing memory 
888112adc000-888112adc3ff, with a lock still held there!
[  322.660089] 888112adc1a0 
(reservation_ww_class_mutex){+.+.}-{3:3}, at: 
drm_exec_lock_obj+0x11a/0x600 [drm_exec]

[  322.660104] 2 locks held by kunit_try_catch/4981:
[  322.660108]  #0: c9000343fe18 
(reservation_ww_class_acquire){+.+.}-{0:0}, at: 
test_early_put+0x22f/0x490 [drm_exec_test]
[  322.660123]  #1: 888112adc1a0 
(reservation_ww_class_mutex){+.+.}-{3:3}, at: 
drm_exec_lock_obj+0x11a/0x600 [drm_exec]

[  322.660135]
    stack backtrace:
[  322.660139] CPU: 7 PID: 4981 Comm: kunit_try_catch Tainted: G 
U   N 6.5.0-rc7+ #155
[  322.660146] Hardware name: ASUS System Product Name/PRIME B560M-A 
AC, BIOS 0403 01/26/2021

[  322.660152] Call Trace:
[  322.660155]  
[  322.660158]  dump_stack_lvl+0x57/0x90
[  322.660164]  debug_check_no_locks_freed+0x20b/0x2b0
[  322.660172]  slab_free_freelist_hook+0xa1/0x160
[  322.660179]  ? drm_exec_unlock_all+0x168/0x2a0 [drm_exec]
[  322.660186]  __kmem_cache_free+0xb2/0x290
[  322.660192]  drm_exec_unlock_all+0x168/0x2a0 [drm_exec]
[  322.660200]  drm_exec_fini+0xf/0x1c0 [drm_exec]
[  322.660206]  test_early_put+0x289/0x490 [drm_exec_test]
[  322.660215]  ? __pfx_test_early_put+0x10/0x10 [drm_exec_test]
[  322.660222]  ? __kasan_check_byte+0xf/0x40
[  322.660227]  ? __ksize+0x63/0x140
[  322.660233]  ? drmm_add_final_kfree+0x3e/0xa0 [drm]
[  322.660289]  ? _raw_spin_unlock_irqrestore+0x30/0x60
[  322.660294]  ? lockdep_hardirqs_on+0x7d/0x100
[  322.660301]  ? __pfx_kunit_try_run_case+0x10/0x10 [kunit]
[  322.660310]  ? __pfx_kunit_generic_run_threadfn_adapter+0x10/0x10 
[kunit]

[  322.660319]  kunit_generic_run_threadfn_adapter+0x4a/0x90 [kunit]
[  322.660328]  kthread+0x2e7/0x3c0
[  322.660334]  ? __pfx_kthread+0x10/0x10
[  322.660339]  ret_from_fork+0x2d/0x70
[  322.660345]  ? __pfx_kthread+0x10/0x10
[  322.660349]  ret_from_fork_asm+0x1b/0x30
[  322.660358]  
[  322.660818] ok 8 test_early_put

Cc: Christian König 
Cc: Boris Brezillon 
Cc: Danilo Krummrich 
Cc: dri-devel@lists.freedesktop.org
Signed-off-by: Thomas Hellström 
---
  drivers/gpu/drm/drm_exec.c |  2 +-
  include/drm/drm_exec.h | 35 +++
  2 files changed, 32 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/drm_exec.c b/drivers/gpu/drm/drm_exec.c
index ff69cf0fb42a..5d2809de4517 100644
--- a/drivers/gpu/drm/drm_exec.c
+++ b/drivers/gpu/drm/drm_exec.c
@@ -56,7 +56,7 @@ static void drm_exec_unlock_all(struct drm_exec *exec)
  struct drm_gem_object *obj;
  unsigned long index;
  -    drm_exec_for_each_locked_object(exec, index, obj) {
+    drm_exec_for_each_locked_object_reverse(exec, index, obj) {


Well that's a really good catch, just one more additional thought below.


  dma_resv_unlock(obj->resv);
  drm_gem_object_put(obj);
  }
diff --git a/include/drm/drm_exec.h b/include/drm/drm_exec.h
index e0462361adf9..55764cf7c374 100644
--- a/include/drm/drm_exec.h
+++ b/include/drm/drm_exec.h
@@ -51,6 +51,20 @@ struct drm_exec {
  struct drm_gem_object *prelocked;
  };
  +/**
+ * drm_exec_obj() - Return the object for a give drm_exec index
+ * @exec: Pointer to the drm_exec context
+ * @index: The index.
+ *
+ * Return: Pointer to the locked object corresponding to @index if
+ * index is within the number of locked objects. NULL otherwise.
+ */
+static inline struct drm_gem_object *
+drm_exec_obj(struct drm_exec *exec, unsigned long index)
+{
+    return index < exec->num_objects ? exec->objects[index] : NULL;
+}
+
  /**
   * drm_exec_for_each_locked_object - iterate over all the locked 
objects

   * @exec: drm_exec object
@@ -59,10 +73,23 @@ struct drm_exec {
   *
   * Iterate over all the locked GEM objects inside the drm_exec object.
   */
-#define drm_exec_for_each_locked_object(exec, index, obj)    \
-    for (index = 0, obj = (exec)->objects[0];    \
- index < (exec)->num_objects;    \
- ++index, obj = (exec)->objects[index])
+#define drm_exec_for_each_locked_object(exec, index, obj)    \
+    for ((index

Re: [RFC, drm-misc-next v4 0/9] PCI/VGA: Allowing the user to select the primary video adapter at boot time

2023-09-05 Thread Sui Jingfeng

Hi,

On 2023/9/5 21:28, Christian König wrote:


2) Typically, those non-86 machines don't have a good UEFI firmware
    support, which doesn't support select primary GPU as firmware 
stage.
    Even on x86, there are old UEFI firmwares which already made 
undesired

    decision for you.

3) This series is attempt to solve the remain problems at the driver 
level,
    while another series[1] of me is target to solve the majority of 
the

    problems at device level.

Tested (limited) on x86 with four video card mounted, Intel UHD 
Graphics

630 is the default boot VGA, successfully override by ast2400 with
ast.modeset=10 append at the kernel cmd line.

The value 10 is incredibly arbitrary, and multiplied as a magic number
all over the place.


+1 



This is the exact reason why I made this series as RFC, because this is a 
open-ended problem.
The choices of 3,4,5,6,7,8 and 9 are as arbitrary as the number of '10'. '1' 
and '2' is
definitely not suitable, because the seat has already been taken.

Take the drm/nouveau as an example:


```

MODULE_PARM_DESC(modeset, "enable driver (default: auto, "
  "0 = disabled, 1 = enabled, 2 = headless)");
int nouveau_modeset = -1;
module_param_named(modeset, nouveau_modeset, int, 0400);

```


'1' is for enable the drm driver, some driver even override the 'nomodeset' 
parameter.

'2' is not suitable, because nouveau use it as headless GPU (render-only or 
compute class GPU?)

'3' is also not likely the best, the concerns is that
what if a specific drm driver want to expand the usage in the future?


The reason I pick up the digit '10' is that


1) The modeset parameter is unlikely to get expanded up to 10 usages.

Other drm drivers only use the '-1', '0' and 1, choose '2' will conflict with 
drm/nouveau.
By pick the digit '10', it leave some space(room) to various device driver 
authors.
It also helps to keep the usage consistent across various drivers.


2) An int taken up 4 byte, I don't want to waste even a single byte,

While in the process of defencing my patch, I have to say
draft another kernel command line would cause the wasting of precious RAM 
storage.

An int can have 2^31 usage, why we can't improve the utilization rate?

3) Please consider the fact that the modeset is the most common and attractive 
parameter

No name is better than the 'modeset', as other name is not easy to remember.

Again, this is for Linux user, thus it is not arbitrary.
Despite simple and trivial, I think about it more than one week.



[RFC PATCH 5/5] drm/amd/display: add DPP and MPC color caps to DTN log

2023-09-05 Thread Melissa Wen
Add color caps information for DPP and MPC block to show HW color caps.

Signed-off-by: Melissa Wen 
---
 .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 23 +++
 .../drm/amd/display/dc/dcn30/dcn30_hwseq.c| 23 +++
 2 files changed, 46 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c 
b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
index b2f3f1f85f4f..6caac6cb8873 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
@@ -329,6 +329,24 @@ dcn10_log_color_state(struct dc *dc,
DTN_INFO("\n");
}
DTN_INFO("\n");
+   DTN_INFO("DPP Color Caps: input_lut_shared:%d  icsc:%d"
+"  dgam_ram:%d  dgam_rom: 
srgb:%d,bt2020:%d,gamma2_2:%d,pq:%d,hlg:%d"
+"  post_csc:%d  gamcor:%d  dgam_rom_for_yuv:%d  3d_lut:%d"
+"  blnd_lut:%d  oscs:%d\n\n",
+dc->caps.color.dpp.input_lut_shared,
+dc->caps.color.dpp.icsc,
+dc->caps.color.dpp.dgam_ram,
+dc->caps.color.dpp.dgam_rom_caps.srgb,
+dc->caps.color.dpp.dgam_rom_caps.bt2020,
+dc->caps.color.dpp.dgam_rom_caps.gamma2_2,
+dc->caps.color.dpp.dgam_rom_caps.pq,
+dc->caps.color.dpp.dgam_rom_caps.hlg,
+dc->caps.color.dpp.post_csc,
+dc->caps.color.dpp.gamma_corr,
+dc->caps.color.dpp.dgam_rom_for_yuv,
+dc->caps.color.dpp.hw_3d_lut,
+dc->caps.color.dpp.ogam_ram,
+dc->caps.color.dpp.ocsc);
 
DTN_INFO("MPCC:  OPP  DPP  MPCCBOT  MODE  ALPHA_MODE  PREMULT  
OVERLAP_ONLY  IDLE\n");
for (i = 0; i < pool->pipe_count; i++) {
@@ -342,6 +360,11 @@ dcn10_log_color_state(struct dc *dc,
s.idle);
}
DTN_INFO("\n");
+   DTN_INFO("MPC Color Caps: gamut_remap:%d, 3dlut:%d, ogam_ram:%d, 
ocsc:%d\n\n",
+dc->caps.color.mpc.gamut_remap,
+dc->caps.color.mpc.num_3dluts,
+dc->caps.color.mpc.ogam_ram,
+dc->caps.color.mpc.ocsc);
 }
 
 void dcn10_log_hw_state(struct dc *dc,
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c 
b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
index e1a2a68c1d45..dfccf0d3f0d5 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
@@ -125,6 +125,24 @@ dcn30_log_color_state(struct dc *dc,
DTN_INFO("\n");
}
DTN_INFO("\n");
+   DTN_INFO("DPP Color Caps: input_lut_shared:%d  icsc:%d"
+"  dgam_ram:%d  dgam_rom: 
srgb:%d,bt2020:%d,gamma2_2:%d,pq:%d,hlg:%d"
+"  post_csc:%d  gamcor:%d  dgam_rom_for_yuv:%d  3d_lut:%d"
+"  blnd_lut:%d  oscs:%d\n\n",
+dc->caps.color.dpp.input_lut_shared,
+dc->caps.color.dpp.icsc,
+dc->caps.color.dpp.dgam_ram,
+dc->caps.color.dpp.dgam_rom_caps.srgb,
+dc->caps.color.dpp.dgam_rom_caps.bt2020,
+dc->caps.color.dpp.dgam_rom_caps.gamma2_2,
+dc->caps.color.dpp.dgam_rom_caps.pq,
+dc->caps.color.dpp.dgam_rom_caps.hlg,
+dc->caps.color.dpp.post_csc,
+dc->caps.color.dpp.gamma_corr,
+dc->caps.color.dpp.dgam_rom_for_yuv,
+dc->caps.color.dpp.hw_3d_lut,
+dc->caps.color.dpp.ogam_ram,
+dc->caps.color.dpp.ocsc);
 
DTN_INFO("MPCC:  OPP  DPP  MPCCBOT  MODE  ALPHA_MODE  PREMULT  
OVERLAP_ONLY  IDLE"
 "  SHAPER mode  3DLUT_mode  3DLUT bit-depth  3DLUT size  OGAM 
mode  OGAM LUT"
@@ -156,6 +174,11 @@ dcn30_log_color_state(struct dc *dc,
s.gamut_remap_c11_c12, s.gamut_remap_c33_c34);
}
DTN_INFO("\n");
+   DTN_INFO("MPC Color Caps: gamut_remap:%d, 3dlut:%d, ogam_ram:%d, 
ocsc:%d\n\n",
+dc->caps.color.mpc.gamut_remap,
+dc->caps.color.mpc.num_3dluts,
+dc->caps.color.mpc.ogam_ram,
+dc->caps.color.mpc.ocsc);
 }
 
 bool dcn30_set_blend_lut(
-- 
2.40.1



[RFC PATCH 4/5] drm/amd/display: hook DCN30 color state logging to DTN log

2023-09-05 Thread Melissa Wen
Color caps changed between HW versions which caused DCN10 color state
sections on DTN log no longer fit DCN3.0 versions. Create a
DCN3.0-specific color state logging and hook it to drivers of DCN3.0
family.

Signed-off-by: Melissa Wen 
---
 .../amd/display/dc/dcn10/dcn10_hw_sequencer.c |  5 +-
 .../drm/amd/display/dc/dcn30/dcn30_hwseq.c| 89 +++
 .../drm/amd/display/dc/dcn30/dcn30_hwseq.h|  3 +
 .../gpu/drm/amd/display/dc/dcn30/dcn30_init.c |  1 +
 .../drm/amd/display/dc/dcn301/dcn301_init.c   |  1 +
 .../gpu/drm/amd/display/dc/inc/hw_sequencer.h |  2 +
 6 files changed, 100 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c 
b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
index d82e49045fbc..b2f3f1f85f4f 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
@@ -357,7 +357,10 @@ void dcn10_log_hw_state(struct dc *dc,
 
dcn10_log_hubp_states(dc, log_ctx);
 
-   dcn10_log_color_state(dc, log_ctx);
+   if (dc->hwss.log_color_state)
+   dc->hwss.log_color_state(dc, log_ctx);
+   else
+   dcn10_log_color_state(dc, log_ctx);
 
DTN_INFO("OTG:  v_bs  v_be  v_ss  v_se  vpol  vmax  vmin  vmax_sel  
vmin_sel  h_bs  h_be  h_ss  h_se  hpol  htot  vtot  underflow blank_en\n");
 
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c 
b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
index 255713ec29bb..e1a2a68c1d45 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
@@ -69,6 +69,95 @@
 #define FN(reg_name, field_name) \
hws->shifts->field_name, hws->masks->field_name
 
+void
+dcn30_log_color_state(struct dc *dc,
+ struct dc_log_buffer_ctx *log_ctx)
+{
+   struct dc_context *dc_ctx = dc->ctx;
+   struct resource_pool *pool = dc->res_pool;
+   int i;
+
+   DTN_INFO("DPP:  DGAM ROM  DGAM ROM type  DGAM LUT  SHAPER mode"
+"  3DLUT mode  3DLUT bit depth  3DLUT size  RGAM mode"
+"  GAMUT mode  "
+"C11 C12   C13 C14   C21 C22   C23 C24   C31 C32   C33 C34\n");
+
+   for (i = 0; i < pool->pipe_count; i++) {
+   struct dpp *dpp = pool->dpps[i];
+   struct dcn_dpp_state s = {-1};
+
+   dpp->funcs->dpp_read_state(dpp, &s);
+
+   if (!s.is_enabled)
+   continue;
+
+   DTN_INFO("[%2d]:  %7x  %13s  %8s  %11s  %10s  %15s  %10s  %9s"
+"  %10x  %08xh %08xh %08xh %08xh %08xh %08xh",
+   dpp->inst,
+   s.pre_dgam_mode,
+   (s.pre_dgam_select == 0) ? "sRGB" :
+((s.pre_dgam_select == 1) ? "Gamma 2.2" :
+((s.pre_dgam_select == 2) ? "Gamma 2.4" :
+((s.pre_dgam_select == 3) ? "Gamma 2.6" :
+((s.pre_dgam_select == 4) ? "BT.709" :
+((s.pre_dgam_select == 5) ? "PQ" :
+((s.pre_dgam_select == 6) ? "HLG" :
+"Unknown")),
+   (s.gamcor_lut_mode == 0) ? "Bypass" :
+((s.gamcor_lut_mode == 2) ? "RAM" :
+"Unknown"),
+   (s.shaper_lut_mode == 1) ? "RAM A" :
+((s.shaper_lut_mode == 2) ? "RAM B" :
+"Bypass"),
+   (s.lut3d_mode == 1) ? "RAM A" :
+((s.lut3d_mode == 2) ? "RAM B" :
+   "Bypass"),
+   (s.lut3d_bit_depth <= 0) ? "12-bit" : "10-bit",
+   (s.lut3d_size == 0) ? "17x17x17" : "9x9x9",
+   (s.rgam_lut_mode == 0) ? "Bypass" :
+((s.rgam_lut_mode == 1) ? "RAM A" :
+((s.rgam_lut_mode == 2) ? "RAM B" :
+  "Unknown")),
+   s.gamut_remap_mode,
+   s.gamut_remap_c11_c12, s.gamut_remap_c13_c14,
+   s.gamut_remap_c21_c22, s.gamut_remap_c23_c24,
+   s.gamut_remap_c31_c32, s.gamut_remap_c33_c34);
+   DTN_INFO("\n");
+   }
+   DTN_INFO("\n");
+
+   DTN_INFO("MPCC:  OPP  DPP  MPCCBOT  MODE  ALPHA_MODE  PREMULT  
OVERLAP_ONLY  IDLE"
+"  SHAPER mode  3DLUT_mode  3DLUT bit-depth  3DLUT size  OGAM 
mode  OGAM LUT"
+"  GAMUT mode  C11 C12   C33 C34\n");
+
+   for (i = 0; i < pool->pipe_count; i++) {
+   struct mpcc_state s = {0};
+
+   pool->mpc->funcs->read_mpcc_state(pool->mpc, i, &s);
+   if (s.opp_id != 0xf)
+  

[RFC PATCH 3/5] drm/amd/display: create DCN3-specific log for MPC state

2023-09-05 Thread Melissa Wen
Logging DCN3 MPC state was following DCN1 implementation that doesn't
consider new DCN3 MPC color blocks. Create new elements according to
DCN3 MPC color caps and a new DCN3-specific function for reading MPC
data.

Signed-off-by: Melissa Wen 
---
 .../gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c  | 55 ++-
 drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h   | 13 +
 2 files changed, 67 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c 
b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c
index d1500b223858..d164fbf89212 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c
@@ -1382,8 +1382,61 @@ static void mpc3_set_mpc_mem_lp_mode(struct mpc *mpc)
}
 }
 
+static void mpc3_read_mpcc_state(
+   struct mpc *mpc,
+   int mpcc_inst,
+   struct mpcc_state *s)
+{
+   struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
+   uint32_t rmu_status = 0xf;
+
+   REG_GET(MPCC_OPP_ID[mpcc_inst], MPCC_OPP_ID, &s->opp_id);
+   REG_GET(MPCC_TOP_SEL[mpcc_inst], MPCC_TOP_SEL, &s->dpp_id);
+   REG_GET(MPCC_BOT_SEL[mpcc_inst], MPCC_BOT_SEL, &s->bot_mpcc_id);
+   REG_GET_4(MPCC_CONTROL[mpcc_inst], MPCC_MODE, &s->mode,
+   MPCC_ALPHA_BLND_MODE, &s->alpha_mode,
+   MPCC_ALPHA_MULTIPLIED_MODE, &s->pre_multiplied_alpha,
+   MPCC_BLND_ACTIVE_OVERLAP_ONLY, &s->overlap_only);
+   REG_GET_2(MPCC_STATUS[mpcc_inst], MPCC_IDLE, &s->idle,
+   MPCC_BUSY, &s->busy);
+
+   /* Color blocks state */
+   REG_GET(MPC_RMU_CONTROL, MPC_RMU0_MUX_STATUS, &rmu_status);
+   if (rmu_status == mpcc_inst) {
+   REG_GET(SHAPER_CONTROL[0],
+   MPC_RMU_SHAPER_LUT_MODE_CURRENT, &s->shaper_lut_mode);
+   REG_GET(RMU_3DLUT_MODE[0],
+   MPC_RMU_3DLUT_MODE_CURRENT,  &s->lut3d_mode);
+   REG_GET(RMU_3DLUT_READ_WRITE_CONTROL[0],
+   MPC_RMU_3DLUT_30BIT_EN, &s->lut3d_bit_depth);
+   REG_GET(RMU_3DLUT_MODE[0],
+   MPC_RMU_3DLUT_SIZE, &s->lut3d_size);
+   } else {
+   REG_GET(SHAPER_CONTROL[1],
+   MPC_RMU_SHAPER_LUT_MODE_CURRENT, &s->shaper_lut_mode);
+   REG_GET(RMU_3DLUT_MODE[1],
+   MPC_RMU_3DLUT_MODE_CURRENT,  &s->lut3d_mode);
+   REG_GET(RMU_3DLUT_READ_WRITE_CONTROL[1],
+   MPC_RMU_3DLUT_30BIT_EN, &s->lut3d_bit_depth);
+   REG_GET(RMU_3DLUT_MODE[1],
+   MPC_RMU_3DLUT_SIZE, &s->lut3d_size);
+   }
+ REG_GET_2(MPCC_OGAM_CONTROL[mpcc_inst],
+  MPCC_OGAM_MODE_CURRENT, &s->rgam_mode,
+  MPCC_OGAM_SELECT_CURRENT, &s->rgam_lut);
+   REG_GET(MPCC_GAMUT_REMAP_MODE[mpcc_inst],
+   MPCC_GAMUT_REMAP_MODE_CURRENT, &s->gamut_remap_mode);
+   if (s->gamut_remap_mode == 1) {
+   s->gamut_remap_c11_c12 = 
REG_READ(MPC_GAMUT_REMAP_C11_C12_A[mpcc_inst]);
+   s->gamut_remap_c33_c34 = 
REG_READ(MPC_GAMUT_REMAP_C33_C34_A[mpcc_inst]);
+   } else if (s->gamut_remap_mode == 2) {
+   s->gamut_remap_c11_c12 = 
REG_READ(MPC_GAMUT_REMAP_C11_C12_B[mpcc_inst]);
+   s->gamut_remap_c33_c34 = 
REG_READ(MPC_GAMUT_REMAP_C33_C34_B[mpcc_inst]);
+   }
+}
+
 static const struct mpc_funcs dcn30_mpc_funcs = {
-   .read_mpcc_state = mpc1_read_mpcc_state,
+   .read_mpcc_state = mpc3_read_mpcc_state,
.insert_plane = mpc1_insert_plane,
.remove_mpcc = mpc1_remove_mpcc,
.mpc_init = mpc1_mpc_init,
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h 
b/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
index 8d86159d9de0..e60b3503605b 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
@@ -193,6 +193,19 @@ struct mpcc_state {
uint32_t overlap_only;
uint32_t idle;
uint32_t busy;
+   uint32_t shaper_lut_mode;
+   uint32_t lut3d_mode;
+   uint32_t lut3d_bit_depth;
+   uint32_t lut3d_size;
+   uint32_t rgam_mode;
+   uint32_t rgam_lut;
+   uint32_t gamut_remap_mode;
+   uint32_t gamut_remap_c11_c12;
+   uint32_t gamut_remap_c13_c14;
+   uint32_t gamut_remap_c21_c22;
+   uint32_t gamut_remap_c23_c24;
+   uint32_t gamut_remap_c31_c32;
+   uint32_t gamut_remap_c33_c34;
 };
 
 /**
-- 
2.40.1



[RFC PATCH 2/5] drm/amd/display: fill up DCN3 DPP color state

2023-09-05 Thread Melissa Wen
DCN3 DPP color state was uncollected and some state elements from DCN1
doesn't fit DCN3. Create new elements according to DCN3 color caps and
fill them up for DTN log output.

Signed-off-by: Melissa Wen 
---
 .../gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c  | 28 +--
 drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h   |  8 ++
 2 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c 
b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c
index 50dc83404644..a91d72f44bbd 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c
@@ -46,9 +46,31 @@ void dpp30_read_state(struct dpp *dpp_base, struct 
dcn_dpp_state *s)
struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
 
REG_GET(DPP_CONTROL,
-   DPP_CLOCK_ENABLE, &s->is_enabled);
-
-   // TODO: Implement for DCN3
+   DPP_CLOCK_ENABLE, &s->is_enabled);
+   REG_GET_2(PRE_DEGAM,
+ PRE_DEGAM_MODE, &s->pre_dgam_mode,
+ PRE_DEGAM_SELECT, &s->pre_dgam_select);
+   REG_GET(CM_SHAPER_CONTROL,
+   CM_SHAPER_LUT_MODE, &s->shaper_lut_mode);
+   REG_GET(CM_3DLUT_MODE,
+   CM_3DLUT_MODE_CURRENT, &s->lut3d_mode);
+   REG_GET(CM_3DLUT_READ_WRITE_CONTROL,
+   CM_3DLUT_30BIT_EN, &s->lut3d_bit_depth);
+   REG_GET(CM_3DLUT_MODE,
+   CM_3DLUT_SIZE, &s->lut3d_size);
+   // BGAM has no ROM, and definition is different, can't reuse same dump
+REG_GET(CM_BLNDGAM_CONTROL,
+   CM_BLNDGAM_LUT_MODE, &s->rgam_lut_mode);
+   REG_GET(CM_GAMUT_REMAP_CONTROL,
+   CM_GAMUT_REMAP_MODE, &s->gamut_remap_mode);
+   if (s->gamut_remap_mode) {
+   s->gamut_remap_c11_c12 = REG_READ(CM_GAMUT_REMAP_C11_C12);
+   s->gamut_remap_c13_c14 = REG_READ(CM_GAMUT_REMAP_C13_C14);
+   s->gamut_remap_c21_c22 = REG_READ(CM_GAMUT_REMAP_C21_C22);
+   s->gamut_remap_c23_c24 = REG_READ(CM_GAMUT_REMAP_C23_C24);
+   s->gamut_remap_c31_c32 = REG_READ(CM_GAMUT_REMAP_C31_C32);
+   s->gamut_remap_c33_c34 = REG_READ(CM_GAMUT_REMAP_C33_C34);
+   }
 }
 /*program post scaler scs block in dpp CM*/
 void dpp3_program_post_csc(
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h 
b/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h
index f4aa76e02518..7e69d9e28f5b 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h
@@ -148,6 +148,14 @@ struct dcn_dpp_state {
uint32_t gamut_remap_c23_c24;
uint32_t gamut_remap_c31_c32;
uint32_t gamut_remap_c33_c34;
+   uint32_t shaper_lut_mode;
+   uint32_t lut3d_mode;
+   uint32_t lut3d_bit_depth;
+   uint32_t lut3d_size;
+   uint32_t blnd_lut_mode;
+   uint32_t pre_dgam_mode;
+   uint32_t pre_dgam_select;
+   uint32_t gamcor_lut_mode;
 };
 
 struct CM_bias_params {
-- 
2.40.1



[RFC PATCH 1/5] drm/amd/display: detach color state from hw state logging

2023-09-05 Thread Melissa Wen
Prepare to hook color state logging according to DCN version.

Signed-off-by: Melissa Wen 
---
 .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 27 +--
 1 file changed, 19 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c 
b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
index 9834b75f1837..d82e49045fbc 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
@@ -278,19 +278,14 @@ static void dcn10_log_hubp_states(struct dc *dc, void 
*log_ctx)
DTN_INFO("\n");
 }
 
-void dcn10_log_hw_state(struct dc *dc,
-   struct dc_log_buffer_ctx *log_ctx)
+static void
+dcn10_log_color_state(struct dc *dc,
+ struct dc_log_buffer_ctx *log_ctx)
 {
struct dc_context *dc_ctx = dc->ctx;
struct resource_pool *pool = dc->res_pool;
int i;
 
-   DTN_INFO_BEGIN();
-
-   dcn10_log_hubbub_state(dc, log_ctx);
-
-   dcn10_log_hubp_states(dc, log_ctx);
-
DTN_INFO("DPP:IGAM format  IGAM modeDGAM modeRGAM mode"
"  GAMUT mode  C11 C12   C13 C14   C21 C22   C23 C24   "
"C31 C32   C33 C34\n");
@@ -347,6 +342,22 @@ void dcn10_log_hw_state(struct dc *dc,
s.idle);
}
DTN_INFO("\n");
+}
+
+void dcn10_log_hw_state(struct dc *dc,
+   struct dc_log_buffer_ctx *log_ctx)
+{
+   struct dc_context *dc_ctx = dc->ctx;
+   struct resource_pool *pool = dc->res_pool;
+   int i;
+
+   DTN_INFO_BEGIN();
+
+   dcn10_log_hubbub_state(dc, log_ctx);
+
+   dcn10_log_hubp_states(dc, log_ctx);
+
+   dcn10_log_color_state(dc, log_ctx);
 
DTN_INFO("OTG:  v_bs  v_be  v_ss  v_se  vpol  vmax  vmin  vmax_sel  
vmin_sel  h_bs  h_be  h_ss  h_se  hpol  htot  vtot  underflow blank_en\n");
 
-- 
2.40.1



[RFC PATCH 0/5] drm/amd/display: improve DTN color state log

2023-09-05 Thread Melissa Wen
Hi,

I'm updating the color state part of DTN log to match DCN3.0 HW better.
Currently, the DTN log considers the DCN10 color pipeline, which is
useless for DCN3.0 because of all the differences in color caps between
DCN versions. In addition to new color blocks and caps, some semantic
differences made the DCN10 output not fit DCN30.

In this RFC, the first patch adds new color state elements to DPP and
implements the reading of registers according to HW blocks. Similarly to
MPC, the second patch also creates a DCN3-specific function to read the
MPC state and add the MPC color state logging to it. With DPP and MPC
color-register reading, I detach DCN10 color state logging from the HW
log and create a `.log_color_state` hook for logging color state
according to HW color blocks with DCN30 as the first use case. Finally,
the last patch adds DPP and MPC color caps output to facilitate
understanding of the color state log.

This version works well with the driver-specific color properties[1] and
steamdeck/gamescope[2] together, where we can see color state changing
from default values.

Before extending it to other DCN families, I have some doubts. Does this
approach of the `.log_color_state` hook make sense for you? Is there any
conflict between logging color state by HW version and DTN log usage? Is
there a template/style for DTN log output that I should follow?

Let me know your thoughts.

Thanks,

Melissa

[1] https://lore.kernel.org/amd-gfx/20230810160314.48225-1-m...@igalia.com/
[2] https://github.com/ValveSoftware/gamescope

Melissa Wen (5):
  drm/amd/display: detach color state from hw state logging
  drm/amd/display: fill up DCN3 DPP color state
  drm/amd/display: create DCN3-specific log for MPC state
  drm/amd/display: hook DCN30 color state logging to DTN log
  drm/amd/display: add DPP and MPC color caps to DTN log

 .../amd/display/dc/dcn10/dcn10_hw_sequencer.c |  53 +++--
 .../gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c  |  28 -
 .../drm/amd/display/dc/dcn30/dcn30_hwseq.c| 112 ++
 .../drm/amd/display/dc/dcn30/dcn30_hwseq.h|   3 +
 .../gpu/drm/amd/display/dc/dcn30/dcn30_init.c |   1 +
 .../gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c  |  55 -
 .../drm/amd/display/dc/dcn301/dcn301_init.c   |   1 +
 drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h   |   8 ++
 drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h   |  13 ++
 .../gpu/drm/amd/display/dc/inc/hw_sequencer.h |   2 +
 10 files changed, 264 insertions(+), 12 deletions(-)

-- 
2.40.1



Re: [RFT PATCH 01/15] drm/armada: Call drm_atomic_helper_shutdown() at shutdown time

2023-09-05 Thread Doug Anderson
Hi,

On Sun, Sep 3, 2023 at 8:53 AM Russell King (Oracle)
 wrote:
>
> On Fri, Sep 01, 2023 at 04:41:12PM -0700, Douglas Anderson wrote:
> > Based on grepping through the source code this driver appears to be
> > missing a call to drm_atomic_helper_shutdown() at system shutdown
> > time. Among other things, this means that if a panel is in use that it
> > won't be cleanly powered off at system shutdown time.
> >
> > The fact that we should call drm_atomic_helper_shutdown() in the case
> > of OS shutdown/restart comes straight out of the kernel doc "driver
> > instance overview" in drm_drv.c.
> >
> > This driver was fairly easy to update. The drm_device is stored in the
> > drvdata so we just have to make sure the drvdata is NULL whenever the
> > device is not bound.
>
> ... and there I think you have a misunderstanding of the driver model.
> Please have a look at device_unbind_cleanup() which will be called if
> probe fails, or when the device is removed (in other words, when it is
> not bound to a driver.)

...and there I think you didn't read this patch closely enough and
perhaps that you have a misunderstanding of the component model.
Please have a look at the difference between armada_drm_unbind() and
armada_drm_remove() and also check which of those two functions is
being modified by my patch. Were this patch adding a call to
"dev_set_drvdata(dev, NULL)" in armada_drm_remove() then your NAK
would be justified. However, I am not aware of anything in the
component unbind path nor in the failure case of component bind that
would NULL the drvdata.

Kindly look at the patch a second time with this in mind.

-Doug


Re: [PATCH v3 0/2] Match data improvements for it66121 driver

2023-09-05 Thread Robert Foss
On Fri, 18 Aug 2023 20:18:15 +0100, Biju Das wrote:
> This patch series aims to add match data improvements for it66121 driver.
> 
> v2->v3:
>  * Removed fixes tag from patch#1 as nothing broken.
>  * Added Rb tag from Andy.
> v1->v2:
>  * Split the patch into two.
>  * patch#1 extend match support for OF tables compared to legacy ID
>lookup and fixes tag.
>  * patch#2 simplifies the probe() by using i2c_get_match_data.
>  * Dropped sentence for dropping local variable as it is integral part of
>the patch.
> 
> [...]

Applied, thanks!

[1/2] drm: bridge: it66121: Extend match support for OF tables
  https://cgit.freedesktop.org/drm/drm-misc/commit/?id=c11c1a50573e
[2/2] drm: bridge: it66121: Simplify probe()
  https://cgit.freedesktop.org/drm/drm-misc/commit/?id=29ff3b7e23af



Rob



[Bug 217872] New: RIP: 0010:amdgpu_vm_pde_update [amdgpu]

2023-09-05 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=217872

Bug ID: 217872
   Summary: RIP: 0010:amdgpu_vm_pde_update [amdgpu]
   Product: Drivers
   Version: 2.5
  Hardware: AMD
OS: Linux
Status: NEW
  Severity: high
  Priority: P3
 Component: Video(DRI - non Intel)
  Assignee: drivers_video-...@kernel-bugs.osdl.org
  Reporter: jrch2...@gmail.com
Regression: No

[ 2164.137975] [ cut here ]
[ 2164.137985] list_del corruption, 88d17d048738->next is LIST_POISON1
(dead0100)
[ 2164.138004] WARNING: CPU: 8 PID: 10745 at lib/list_debug.c:55
__list_del_entry_valid+0x89/0xd0
[ 2164.138014] Modules linked in: xt_nat xt_tcpudp veth xt_conntrack
nft_chain_nat xt_MASQUERADE nf_nat nf_conntrack_netlink nf_conntrack
nf_defrag_ipv6 nf_defrag_ipv4 xt_addrtype nft_compat nf_tables nfnetlink
br_netfilter bridge stp llc tun rfcomm cmac algif_hash algif_skcipher af_alg
bnep snd_seq_dummy snd_hrtimer snd_seq overlay nct6775 nct6775_core hwmon_vid
nls_iso8859_1 vfat fat intel_rapl_msr intel_rapl_common x86_pkg_temp_thermal
intel_powerclamp coretemp kvm_intel kvm irqbypass crct10dif_pclmul crc32_pclmul
joydev polyval_clmulni polyval_generic gf128mul ghash_clmulni_intel
snd_hda_codec_realtek sha512_ssse3 iTCO_wdt ath3k aesni_intel btusb
snd_hda_codec_generic crypto_simd intel_pmc_bxt cryptd iTCO_vendor_support
btintel ledtrig_audio btbcm btrtl rapl snd_hda_codec_hdmi btmtk intel_cstate
r8169 snd_hda_intel realtek snd_intel_dspcfg snd_intel_sdw_acpi mdio_devres
bluetooth snd_usb_audio psmouse intel_uncore mxm_wmi snd_hda_codec snd_ump
pcspkr i2c_i801 ecdh_generic snd_usbmidi_lib rfkill snd_rawmidi i2c_smbus
[ 2164.138092]  crc16 intel_pch_thermal snd_hda_core libphy lpc_ich
snd_seq_device snd_hwdep ioatdma dca mousedev mac_hid dm_multipath snd_aloop
snd_pcm snd_timer snd soundcore v4l2loopback_dc(OE) videodev mc fuse
crypto_user dm_mod loop ip_tables x_tables usbhid serio_raw atkbd libps2
vivaldi_fmap nvme nvme_core xhci_pci xhci_pci_renesas nvme_common i8042 serio
eeprom amdgpu drm_buddy drm_suballoc_helper video wmi drm_ttm_helper ttm
i2c_algo_bit gpu_sched amdxcp drm_display_helper cec xfs libcrc32c
crc32c_generic crc32c_intel
[ 2164.138145] CPU: 8 PID: 10745 Comm: kworker/8:0H Tainted: G  D W  OE
 6.5.1-1-cachyos-lto #1 165231ec090ac1fb173574db6e4d823c96776a31
[ 2164.138150] Hardware name: ATERMITER ZX-99EV3/ZX-99EV3, BIOS X99AT011
10/15/2020
[ 2164.138153] Workqueue: ttm ttm_bo_delayed_delete [ttm]
[ 2164.138172] RIP: 0010:__list_del_entry_valid+0x89/0xd0
[ 2164.138177] Code: 31 c0 c3 cc cc cc cc cc 48 c7 c7 3f 3f 64 9b e8 fd 4d 9f
ff 0f 0b 31 c0 c3 cc cc cc cc cc 48 c7 c7 5d 3c 6e 9b e8 e7 4d 9f ff <0f> 0b 31
c0 c3 cc cc cc cc cc 48 c7 c7 7a 80 65 9b e8 d1 4d 9f ff
[ 2164.138180] RSP: :a1ebca067db8 EFLAGS: 00010246
[ 2164.138183] RAX: a2c219e743f99b00 RBX: 88d17d048720 RCX:
0027
[ 2164.138185] RDX: a1ebca067c98 RSI: 0002 RDI:
88d35fc21708
[ 2164.138188] RBP:  R08: 1fff R09:
88d37ff7c680
[ 2164.138190] R10: 5ffd R11: 0004 R12:
88d17d048000
[ 2164.138192] R13: 88cc1130eed0 R14: 88d17d048738 R15:
88d176136000
[ 2164.138194] FS:  () GS:88d35fc0()
knlGS:
[ 2164.138196] CS:  0010 DS:  ES:  CR0: 80050033
[ 2164.138199] CR2: 256100fce000 CR3: 000349ca8005 CR4:
001706e0
[ 2164.138202] Call Trace:
[ 2164.138206]  
[ 2164.138210]  ? __warn+0xcf/0x1c0
[ 2164.138216]  ? __list_del_entry_valid+0x89/0xd0
[ 2164.138221]  ? report_bug+0x15f/0x200
[ 2164.138228]  ? handle_bug+0x42/0x70
[ 2164.138232]  ? exc_invalid_op+0x1a/0x50
[ 2164.138235]  ? asm_exc_invalid_op+0x1a/0x20
[ 2164.138243]  ? __list_del_entry_valid+0x89/0xd0
[ 2164.138247]  ? __list_del_entry_valid+0x89/0xd0
[ 2164.138251]  amdgpu_vm_bo_relocated+0x35/0xf0 [amdgpu
2f75e5fa96b9ffccc7e67d417353e101c7ac828e]
[ 2164.138816]  amdgpu_vm_bo_invalidate+0xb7/0x160 [amdgpu
2f75e5fa96b9ffccc7e67d417353e101c7ac828e]
[ 2164.139297]  amdgpu_bo_move_notify+0x6b/0x120 [amdgpu
2f75e5fa96b9ffccc7e67d417353e101c7ac828e]
[ 2164.139789]  ttm_bo_delayed_delete+0x58/0xb0 [ttm
b5edc8a71b12f4467124bbbdec9e03389e118e3e]
[ 2164.139806]  process_one_work+0x241/0x440
[ 2164.139812]  worker_thread+0x291/0x5e0
[ 2164.139816]  ? __pfx_worker_thread+0x10/0x10
[ 2164.139820]  kthread+0x14a/0x170
[ 2164.139825]  ? __pfx_kthread+0x10/0x10
[ 2164.139829]  ret_from_fork+0x37/0x50
[ 2164.139834]  ? __pfx_kthread+0x10/0x10
[ 2164.139838]  ret_from_fork_asm+0x1b/0x30
[ 2164.139844]  
[ 2164.139846] ---[ end trace  ]---
[ 2164.139922] BUG: kernel NULL pointer dereference, address: 0248
[ 2164.139927] #PF: supervisor read access in kernel mode
[ 2164.139929] #PF: error_code(0x) - not-present page
[ 2164.139931] PGD 0 P4D 0 
[ 2164.139933] Oop

Re: [Intel-xe] [PATCH 2/3] drm/tests/drm_exec: Add a test for object freeing within drm_exec_fini()

2023-09-05 Thread Thomas Hellström

Hi, Maxime

On 9/5/23 15:16, Maxime Ripard wrote:

On Tue, Sep 05, 2023 at 02:32:38PM +0200, Thomas Hellström wrote:

Hi,

On 9/5/23 14:05, Maxime Ripard wrote:

Hi,

On Tue, Sep 05, 2023 at 10:58:31AM +0200, Thomas Hellström wrote:

Check that object freeing from within drm_exec_fini() works as expected
and doesn't generate any warnings.

Cc: Christian König 
Cc: dri-devel@lists.freedesktop.org
Signed-off-by: Thomas Hellström 
---
   drivers/gpu/drm/tests/drm_exec_test.c | 47 +++
   1 file changed, 47 insertions(+)

diff --git a/drivers/gpu/drm/tests/drm_exec_test.c 
b/drivers/gpu/drm/tests/drm_exec_test.c
index 563949d777dd..294c25f49cc7 100644
--- a/drivers/gpu/drm/tests/drm_exec_test.c
+++ b/drivers/gpu/drm/tests/drm_exec_test.c
@@ -170,6 +170,52 @@ static void test_prepare_array(struct kunit *test)
drm_gem_private_object_fini(&gobj2);
   }
+static const struct drm_gem_object_funcs put_funcs = {
+   .free = (void *)kfree,
+};
+
+/*
+ * Check that freeing objects from within drm_exec_fini()
+ * behaves as expected.
+ */
+static void test_early_put(struct kunit *test)
+{
+   struct drm_exec_priv *priv = test->priv;
+   struct drm_gem_object *gobj1;
+   struct drm_gem_object *gobj2;
+   struct drm_gem_object *array[2];
+   struct drm_exec exec;
+   int ret;
+
+   gobj1 = kzalloc(sizeof(*gobj1), GFP_KERNEL);
+   KUNIT_EXPECT_NOT_ERR_OR_NULL(test, gobj1);
+   if (!gobj1)
+   return;
+
+   gobj2 = kzalloc(sizeof(*gobj2), GFP_KERNEL);
+   KUNIT_EXPECT_NOT_ERR_OR_NULL(test, gobj2);
+   if (!gobj2) {
+   kfree(gobj1);
+   return;
+   }
+
+   gobj1->funcs = &put_funcs;
+   gobj2->funcs = &put_funcs;
+   array[0] = gobj1;
+   array[1] = gobj2;
+   drm_gem_private_object_init(priv->drm, gobj1, PAGE_SIZE);
+   drm_gem_private_object_init(priv->drm, gobj2, PAGE_SIZE);
+
+   drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT);
+   drm_exec_until_all_locked(&exec)
+   ret = drm_exec_prepare_array(&exec, array, ARRAY_SIZE(array),
+1);
+   KUNIT_EXPECT_EQ(test, ret, 0);
+   drm_gem_object_put(gobj1);
+   drm_gem_object_put(gobj2);
+   drm_exec_fini(&exec);

It doesn't look like you actually check that "freeing objects from
within drm_exec_fini() behaves as expected." What is the expectation
here, and how is it checked?

Hm. Good question, I've been manually checking dmesg for lockdep splats. Is
there a way to automate that?

I'm not familiar with the drm_exec API, but judging by the code I'd
assume you want to check that gobj1 and gobj2 are actually freed using
kfree?


Actually not. What's important here is that the call to drm_exec_fini(), 
which puts the last references to gobj1 and gobj2 doesn't trigger any 
lockdep splats, like the one in the commit message of patch 3/3. So to 
make more sense, the test could perhaps be conditioned on 
CONFIG_DEBUG_LOCK_ALLOC. Still it would require manual checking of 
dmesg() after being run.


/Thomas





Re: [PATCH v2 2/7] drm: ci: Force db410c to host mode

2023-09-05 Thread Maxime Ripard
On Tue, Sep 05, 2023 at 07:06:43PM +0530, Vignesh Raman wrote:
> Hi Maxime,
> 
> On 05/09/23 17:27, Maxime Ripard wrote:
> > On Tue, Sep 05, 2023 at 05:11:43PM +0530, Vignesh Raman wrote:
> > > > > Also, that node actually has a label ("usb"), defined here:
> > > > > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm64/boot/dts/qcom/msm8916.dtsi#n2322
> > > > > 
> > > > > So you can end up with
> > > > > 
> > > > > &usb {
> > > > >   dr_mode = "host";
> > > > > };
> > > > 
> > > > ... which is the simplest and thus more robust one.
> > > > 
> > > 
> > > Should it be,
> > > &{/soc@0/usb} {
> > >   dr_mode = "host";
> > > };
> > 
> > No. The &{/...} syntax refers to a path. &... refers to a label. They
> > are not equivalent.
> 
> Sorry I was not clear before.
> 
> With,
> &usb {
>   dr_mode = "host";
> };
> 
> The target is <0x> and fdtoverlay fails to apply the dtbo.

You do have /plugin/ and have compiled the base device tree with overlay
support, right?

> With,
> &{/soc@0/usb} {
>  dr_mode = "host";
> };
> 
> The target-path is "/soc@0/usb" (usb: usb@78d9000)

Right, and that's not the path you want to modify. The path you want to
modify is /soc@0/usb@78d9000. usb is the label, it's absolute, and you
can't mix and match a path ("/soc@0/") and a label ("usb")

Maxime


signature.asc
Description: PGP signature


Re: [PATCH v2 2/7] drm: ci: Force db410c to host mode

2023-09-05 Thread Vignesh Raman

Hi Maxime,

On 05/09/23 17:27, Maxime Ripard wrote:

On Tue, Sep 05, 2023 at 05:11:43PM +0530, Vignesh Raman wrote:

Also, that node actually has a label ("usb"), defined here:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm64/boot/dts/qcom/msm8916.dtsi#n2322

So you can end up with

&usb {
  dr_mode = "host";
};


... which is the simplest and thus more robust one.



Should it be,
&{/soc@0/usb} {
dr_mode = "host";
};


No. The &{/...} syntax refers to a path. &... refers to a label. They
are not equivalent.


Sorry I was not clear before.

With,
&usb {
dr_mode = "host";
};

The target is <0x> and fdtoverlay fails to apply the dtbo.

With,
&{/soc@0/usb} {
 dr_mode = "host";
};

The target-path is "/soc@0/usb" (usb: usb@78d9000)

/ {

fragment@0 {
target-path = "/soc@0/usb";

__overlay__ {
dr_mode = "host";
};
};
};

So will use  &{/...} syntax in this case.

Regards,
Vignesh


Re: [Nouveau] [RFC, drm-misc-next v4 0/9] PCI/VGA: Allowing the user to select the primary video adapter at boot time

2023-09-05 Thread suijingfeng

Hi,


On 2023/9/5 18:45, Thomas Zimmermann wrote:

Hi

Am 04.09.23 um 21:57 schrieb Sui Jingfeng:

From: Sui Jingfeng 

On a machine with multiple GPUs, a Linux user has no control over which
one is primary at boot time. This series tries to solve above mentioned


If anything, the primary graphics adapter is the one initialized by 
the firmware. I think our boot-up graphics also make this assumption 
implicitly.




Yes, but by the time of DRM drivers get loaded successfully,the boot-up 
graphics already finished.
Firmware framebuffer device already get killed by the 
drm_aperture_remove_conflicting_pci_framebuffers()
function (or its siblings). So, this series is definitely not to interact with 
the firmware framebuffer
(or more intelligent framebuffer drivers).  It is for user space program, such 
as X server and Wayland
compositor. Its for Linux user or drm drivers testers, which allow them to 
direct graphic display server
using right hardware of interested as primary video card.

Also, I believe that X server and Wayland compositor are the best test examples.
If a specific DRM driver can't work with X server as a primary,
then there probably have something wrong.



But what's the use case for overriding this setting?



On a specific machine with multiple GPUs mounted,
only the primary graphics get POST-ed (initialized) by the firmware.
Therefore, the DRM drivers for the rest video cards, have to choose to
work without the prerequisite setups done by firmware, This is called as POST.

One of the use cases of this series is to test if a specific DRM driver could 
works properly,
even though there is no prerequisite works have been done by firmware at all.
And it seems that the results is not satisfying in all cases.

drm/ast is the first drm drivers which refused to work if not being POST-ed by 
the firmware.

Before apply this series, I was unable make drm/ast as the primary video card 
easily. On a
multiple video card configuration, the monitor connected with the AST2400 not 
light up.
While confusing, a naive programmer may suspect the PRIME is not working.

After applied this series and passing ast.modeset=10 on the kernel cmd line,
I found that the monitor connected with my ast2400 video card still black,
It doesn't display and doesn't show image to me.

While in the process of study drm/ast, I know that drm/ast driver has the POST 
code shipped.
See the ast_post_gpu() function, then, I was wondering why this function 
doesn't works.
After a short-time (hasty) debugging, I found that the the ast_post_gpu() 
function
didn't get run. Because it have something to do with the ast->config_mode.

Without thinking too much, I hardcoded the ast->config_mode as ast_use_p2a to
force the ast_post_gpu() function get run.

```

--- a/drivers/gpu/drm/ast/ast_main.c
+++ b/drivers/gpu/drm/ast/ast_main.c
@@ -132,6 +132,8 @@ static int ast_device_config_init(struct ast_device 
*ast)

    }
    }

+   ast->config_mode = ast_use_p2a;
+
    switch (ast->config_mode) {
    case ast_use_defaults:
    drm_info(dev, "Using default configuration\n");

```

Then, the monitor light up, it display the Ubuntu greeter to me.
Therefore, my patch is helpful, at lease for the Linux drm driver tester and 
developer.
It allow programmers to test the specific part of the specific drive
without changing a line of the source code and without the need of sudo 
authority.
It helps to improve efficiency of the testing and patch verification.

I know the PrimaryGPU option of Xorg conf, but this approach will remember the 
setup
have been made, you need modify it with root authority each time you want to 
switch
the primary. But on rapid developing and/or testing multiple video drivers, with
only one computer hardware resource available. What we really want probably is a
one-shoot command as this series provide.

So, this is the first use case. This probably also help to test full modeset,
PRIME and reverse PRIME on multiple video card machine.



Best regards
Thomas





Re: [RFC, drm-misc-next v4 0/9] PCI/VGA: Allowing the user to select the primary video adapter at boot time

2023-09-05 Thread Christian König

Am 05.09.23 um 12:38 schrieb Jani Nikula:

On Tue, 05 Sep 2023, Sui Jingfeng  wrote:

From: Sui Jingfeng 

On a machine with multiple GPUs, a Linux user has no control over which
one is primary at boot time. This series tries to solve above mentioned
problem by introduced the ->be_primary() function stub. The specific
device drivers can provide an implementation to hook up with this stub by
calling the vga_client_register() function.

Once the driver bound the device successfully, VGAARB will call back to
the device driver. To query if the device drivers want to be primary or
not. Device drivers can just pass NULL if have no such needs.

Please note that:

1) The ARM64, Loongarch, Mips servers have a lot PCIe slot, and I would
like to mount at least three video cards.


Well, you rarely find a board which can actually handle a single one :)



2) Typically, those non-86 machines don't have a good UEFI firmware
support, which doesn't support select primary GPU as firmware stage.
Even on x86, there are old UEFI firmwares which already made undesired
decision for you.

3) This series is attempt to solve the remain problems at the driver level,
while another series[1] of me is target to solve the majority of the
problems at device level.

Tested (limited) on x86 with four video card mounted, Intel UHD Graphics
630 is the default boot VGA, successfully override by ast2400 with
ast.modeset=10 append at the kernel cmd line.

The value 10 is incredibly arbitrary, and multiplied as a magic number
all over the place.


+1




$ lspci | grep VGA

  00:02.0 VGA compatible controller: Intel Corporation CoffeeLake-S GT2 [UHD 
Graphics 630]
  01:00.0 VGA compatible controller: Advanced Micro Devices, Inc. [AMD/ATI] 
Caicos XTX [Radeon HD 8490 / R5 235X OEM]
  04:00.0 VGA compatible controller: ASPEED Technology, Inc. ASPEED Graphics 
Family (rev 30)
  05:00.0 VGA compatible controller: NVIDIA Corporation GK208B [GeForce GT 720] 
(rev a1)

In this example, all of the GPUs are driven by different drivers. What
good does a module parameter do if you have multiple GPUs of the same
model, all driven by the same driver module?


Completely agree. Question is what is the benefit for the end user to 
actually specify this?


If you want the initial console on a different device than implement a 
kernel options for vgaarb and *not* the drivers.


Regards,
Christian.



BR,
Jani.


$ sudo dmesg | grep vgaarb

  pci :00:02.0: vgaarb: setting as boot VGA device
  pci :00:02.0: vgaarb: VGA device added: 
decodes=io+mem,owns=io+mem,locks=none
  pci :01:00.0: vgaarb: VGA device added: 
decodes=io+mem,owns=none,locks=none
  pci :04:00.0: vgaarb: VGA device added: 
decodes=io+mem,owns=none,locks=none
  pci :05:00.0: vgaarb: VGA device added: 
decodes=io+mem,owns=none,locks=none
  vgaarb: loaded
  ast :04:00.0: vgaarb: Override as primary by driver
  i915 :00:02.0: vgaarb: changed VGA decodes: 
olddecodes=io+mem,decodes=none:owns=io+mem
  radeon :01:00.0: vgaarb: changed VGA decodes: 
olddecodes=io+mem,decodes=none:owns=none
  ast :04:00.0: vgaarb: changed VGA decodes: 
olddecodes=io+mem,decodes=none:owns=none

v2:
* Add a simple implemment for drm/i915 and drm/ast
* Pick up all tags (Mario)
v3:
* Fix a mistake for drm/i915 implement
* Fix patch can not be applied problem because of merge conflect.
v4:
* Focus on solve the real problem.

v1,v2 at https://patchwork.freedesktop.org/series/120059/
v3 at https://patchwork.freedesktop.org/series/120562/

[1] https://patchwork.freedesktop.org/series/122845/

Sui Jingfeng (9):
   PCI/VGA: Allowing the user to select the primary video adapter at boot
 time
   drm/nouveau: Implement .be_primary() callback
   drm/radeon: Implement .be_primary() callback
   drm/amdgpu: Implement .be_primary() callback
   drm/i915: Implement .be_primary() callback
   drm/loongson: Implement .be_primary() callback
   drm/ast: Register as a VGA client by calling vga_client_register()
   drm/hibmc: Register as a VGA client by calling vga_client_register()
   drm/gma500: Register as a VGA client by calling vga_client_register()

  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c| 11 +++-
  drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c   | 13 -
  drivers/gpu/drm/ast/ast_drv.c | 31 ++
  drivers/gpu/drm/gma500/psb_drv.c  | 57 ++-
  .../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c   | 15 +
  drivers/gpu/drm/i915/display/intel_vga.c  | 15 -
  drivers/gpu/drm/loongson/loongson_module.c|  2 +-
  drivers/gpu/drm/loongson/loongson_module.h|  1 +
  drivers/gpu/drm/loongson/lsdc_drv.c   | 10 +++-
  drivers/gpu/drm/nouveau/nouveau_vga.c | 11 +++-
  drivers/gpu/drm/radeon/radeon_device.c| 10 +++-
  drivers/pci/vgaarb.c  | 43 --
  drivers/vfio/pci/vfio_pci_core.c  |  2 +-
  include/linux/vga

  1   2   >