Re: [PATCH v5 3/7] drm: sun4i: dsi: Convert to bridge driver

2021-11-29 Thread Jagan Teki
On Fri, Nov 26, 2021 at 9:34 PM Maxime Ripard  wrote:
>
> On Thu, Nov 25, 2021 at 09:44:14PM +0530, Jagan Teki wrote:
> > On Thu, Nov 25, 2021 at 9:40 PM Maxime Ripard  wrote:
> > >
> > > On Thu, Nov 25, 2021 at 07:55:41PM +0530, Jagan Teki wrote:
> > > > Hi,
> > > >
> > > > On Thu, Nov 25, 2021 at 7:45 PM Maxime Ripard  wrote:
> > > > >
> > > > > On Wed, Nov 24, 2021 at 12:02:47AM +0530, Jagan Teki wrote:
> > > > > > > > > > > + dsi->panel = of_drm_find_panel(remote);
> > > > > > > > > > > + if (IS_ERR(dsi->panel)) {
> > > > > > > > > > > + dsi->panel = NULL;
> > > > > > > > > > > +
> > > > > > > > > > > + dsi->next_bridge = 
> > > > > > > > > > > of_drm_find_bridge(remote);
> > > > > > > > > > > + if (IS_ERR(dsi->next_bridge)) {
> > > > > > > > > > > + dev_err(dsi->dev, "failed to find 
> > > > > > > > > > > bridge\n");
> > > > > > > > > > > + return PTR_ERR(dsi->next_bridge);
> > > > > > > > > > > + }
> > > > > > > > > > > + } else {
> > > > > > > > > > > + dsi->next_bridge = NULL;
> > > > > > > > > > > + }
> > > > > > > > > > > +
> > > > > > > > > > > + of_node_put(remote);
> > > > > > > > > >
> > > > > > > > > > Using devm_drm_of_get_bridge would greatly simplify the 
> > > > > > > > > > driver
> > > > > > > > >
> > > > > > > > > I'm aware of this and this would break the existing sunxi dsi 
> > > > > > > > > binding,
> > > > > > > > > we are not using ports based pipeline in dsi node. Of-course 
> > > > > > > > > you have
> > > > > > > > > pointed the same before, please check below
> > > > > > > > > https://patchwork.kernel.org/project/dri-devel/patch/20210322140152.101709-2-ja...@amarulasolutions.com/
> > > > > > > >
> > > > > > > > Then drm_of_find_panel_or_bridge needs to be adjusted to handle 
> > > > > > > > the DSI
> > > > > > > > bindings and look for a panel or bridge not only through the OF 
> > > > > > > > graph,
> > > > > > > > but also on the child nodes
> > > > > > >
> > > > > > > Okay. I need to check this.
> > > > > >
> > > > > > devm_drm_of_get_bridge is not working with legacy binding like the 
> > > > > > one
> > > > > > used in sun6i dsi
> > > > >
> > > > > There's nothing legacy about it.
> > > >
> > > > What I'm mean legacy here with current binding used in sun6i-dsi like 
> > > > this.
> > > >
> > > > &dsi {
> > > >   vcc-dsi-supply = <®_dcdc1>; /* VCC-DSI */
> > > >   status = "okay";
> > > >
> > > >  panel@0 {
> > > >compatible = "bananapi,s070wv20-ct16-icn6211";
> > > >reg = <0>;
> > > >reset-gpios = <&r_pio 0 5 GPIO_ACTIVE_HIGH>; /*
> > > > LCD-RST: PL5 */
> > > >   enable-gpios = <&pio 1 7 GPIO_ACTIVE_HIGH>; /*
> > > > LCD-PWR-EN: PB7 */
> > > >   backlight = <&backlight>;
> > > > };
> > > > };
> > >
> > > Yes, I know, it's the generic DSI binding. It's still not legacy.
> > >
> > > > devm_drm_of_get_bridge cannot find the device with above binding and
> > > > able to find the device with below binding.
> > > >
> > > > &dsi {
> > > >vcc-dsi-supply = <®_dcdc1>; /* VCC-DSI */
> > > >status = "okay";
> > > >
> > > >   ports {
> > > > #address-cells = <1>;
> > > > #size-cells = <0>;
> > > >
> > > >dsi_out: port@0 {
> > > >reg = <0>;
> > > >
> > > >   dsi_out_bridge: endpoint {
> > > > remote-endpoint = <&bridge_out_dsi>;
> > > >   };
> > > >};
> > > >   };
> > > >
> > > >   panel@0 {
> > > >  compatible = "bananapi,s070wv20-ct16-icn6211";
> > > >  reg = <0>;
> > > >  reset-gpios = <&r_pio 0 5 GPIO_ACTIVE_HIGH>; /* LCD-RST: 
> > > > PL5 */
> > > >  enable-gpios = <&pio 1 7 GPIO_ACTIVE_HIGH>; /* LCD-PWR-EN: 
> > > > PB7 */
> > > >  backlight = <&backlight>;
> > > >
> > > >   port {
> > > > bridge_out_dsi: endpoint {
> > > > remote-endpoint = <&dsi_out_bridge>;
> > > > };
> > > > };
> > > >};
> > > > };
> > >
> > > Yes, I know, and that's because ...
> >
> > Okay. I will use find panel and bridge separately instead of
> > devm_drm_of_get_bridge in version patches.
>
> That's not been my point, at all?
>
> I mean, that whole discussion has been because you shouldn't do that.
>
> > >
> > > > >
> > > > > > https://patchwork.kernel.org/project/dri-devel/patch/20211122065223.88059-6-ja...@amarulasolutions.com/
> > > > > >
> > > > > > dsi->next_bridge = devm_drm_of_get_bridge(dsi->dev, 
> > > > > > dsi->dev->of_node, 0, 0);
> > > > > > if (IS_ERR(dsi->next_bridge))
> > > > > >return PTR_ERR(dsi->next_bridge);
> > > > > >
> > > > > > It is only working if we have ports on the pipeline, something like 
> > > > 

Re: [PATCH 4/4] drm: rcar-du: mipi-dsi: Support bridge probe ordering

2021-11-29 Thread Jagan Teki
Hi Kieran,

On Fri, Nov 26, 2021 at 3:45 PM Kieran Bingham
 wrote:
>
> The bridge probe ordering for DSI devices has been clarified and further
> documented in
>
> To support connecting with the SN65DSI86 device after commit c3b75d4734cb
> ("drm/bridge: sn65dsi86: Register and attach our DSI device at probe"),
> update to the new probe ordering to remove a perpetual -EPROBE_DEFER
> loop between the two devices.
>
> Signed-off-by: Kieran Bingham 
> ---
>  drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c | 48 +
>  1 file changed, 26 insertions(+), 22 deletions(-)
>
> diff --git a/drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c 
> b/drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c
> index 833f4480bdf3..f783bacee8da 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c
> @@ -639,6 +639,8 @@ static int rcar_mipi_dsi_host_attach(struct mipi_dsi_host 
> *host,
> struct mipi_dsi_device *device)
>  {
> struct rcar_mipi_dsi *dsi = host_to_rcar_mipi_dsi(host);
> +   struct drm_panel *panel;
> +   int ret;
>
> if (device->lanes > dsi->num_data_lanes)
> return -EINVAL;
> @@ -646,12 +648,36 @@ static int rcar_mipi_dsi_host_attach(struct 
> mipi_dsi_host *host,
> dsi->lanes = device->lanes;
> dsi->format = device->format;
>
> +   ret = drm_of_find_panel_or_bridge(dsi->dev->of_node, 1, 0, &panel,
> + &dsi->next_bridge);
> +   if (ret) {
> +   dev_err_probe(dsi->dev, ret, "could not find next bridge\n");
> +   return ret;
> +   }
> +
> +   if (!dsi->next_bridge) {
> +   dsi->next_bridge = devm_drm_panel_bridge_add(dsi->dev, panel);
> +   if (IS_ERR(dsi->next_bridge)) {
> +   dev_err(dsi->dev, "failed to create panel bridge\n");
> +   return PTR_ERR(dsi->next_bridge);
> +   }
> +   }

Can we use the new function devm_drm_of_get_bridge instead of the entire code?

Jagan.


Re: [PATCH] fbdev: replace snprintf in show functions with sysfs_emit

2021-11-29 Thread Greg KH
On Tue, Nov 30, 2021 at 08:05:08AM +0800, davidcomponent...@gmail.com wrote:
> From: Yang Guang 
> 
> coccinelle report:
> ./drivers/video/fbdev/core/fbcon.c:2680:8-16:
> WARNING: use scnprintf or sprintf
> ./drivers/video/fbdev/core/fbcon.c:2655:8-16:
> WARNING: use scnprintf or sprintf
> 
> Use sysfs_emit instead of scnprintf or sprintf makes more sense.
> 
> Reported-by: Zeal Robot 
> Signed-off-by: Yang Guang 

As said before, your email does not match these lines, nor was this
reported by this bot, but by the existing tools in the kernel tree.

thanks,

greg k-h


Re: [PATCH 1/3] drm/simpledrm: Bind to OF framebuffers in /chosen

2021-11-29 Thread Javier Martinez Canillas
> > >
> > > Simpledrm is just a driver, but this is platform setup code. Why is this
> > > code located here and not under arch/ or drivers/firmware/?
> > >

Agreed. Creating platform devices is something for platform code and
not really a DRM driver.

> > > I know that other drivers do similar things, it doesn't seem to belong 
> > > here.
> >

Yeah, the simplefb driver does this but that seems like something that
should be changed.

> > This definitely doesn't belong in either of those, since it is not arch-
> > or firmware-specific. It is implementing support for the standard
> > simple-framebuffer OF binding, which specifies that it must be located
> > within the /chosen node (and thus the default OF setup code won't do the
> > matching for you); this applies to all OF platforms [1]
> >
> > Adding Rob; do you think this should move from simplefb/simpledrm to
> > common OF code? (where?)
>
> of_platform_default_populate_init() should work.

That should work but I still wonder if it is the correct place to add
this logic.

I think that instead it could be done in the sysfb_create_simplefb()
function [0], which already creates the "simple-framebuffer" device
for x86 legacy BIOS and x86/arm64/riscv EFI so it makes sense to do
the same for OF. That way the simplefb platform device registration
code could also be dropped from the driver and users would just need
to enable CONFIG_SYSFB and CONFIG_SYSFB_SIMPLEFB to have the same.

I have a couple of boards with a bootloader that populates a
"simple-framebuffer" in the /chosen node so I could attempt to write
the patches. But probably won't happen until next week.

[0]: 
https://elixir.bootlin.com/linux/v5.16-rc3/source/drivers/firmware/sysfb_simplefb.c#L60

Best regards,
Javier


Re: [PATCH] lontium-lt9611: check a different register bit for HDMI sensing

2021-11-29 Thread Vinod Koul
On 16-11-21, 18:07, Peter Collingbourne wrote:
> It has been observed that with certain monitors such as the HP Z27n,
> the register 0x825e reads a value of 0x79 when the HDMI cable is
> connected and 0x78 when it is disconnected, i.e. bit 0 appears
> to correspond to the HDMI connection status and bit 2 is never
> set. Therefore, change the driver to check bit 0 instead of bit 2.

So we have got limited information on this but BIT-2 seems to be related
to HPD and empirical data from various monitors supports this, so this
seems the right thing to do.

Reviewed-by: Vinod Koul 

-- 
~Vinod


Re: [PATCH] drm: rcar-du: crtc: Support external DSI dot clock

2021-11-29 Thread Laurent Pinchart
Hi Kieran,

Thank you for the patch.

On Fri, Nov 26, 2021 at 09:35:14AM +, Kieran Bingham wrote:
> On platforms with an external clock, both the group and crtc must be
> handled accordingly to correctly pass through the external clock and
> configure the DU to use the external rate.
> 
> The CRTC support was missed while adding the DSI support on the r8a779a0
> which led to the output clocks being incorrectly determined.
> 
> Ensure that when a CRTC is routed through the DSI encoder, the external
> clock is used without any further divider being applied.
> 
> Fixes: b291fdcf5114 ("drm: rcar-du: Add r8a779a0 device support")
> Signed-off-by: Kieran Bingham 

Reviewed-by: Laurent Pinchart 

> ---
>  drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 11 ++-
>  1 file changed, 6 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c 
> b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> index 5672830ca184..5236f917cc68 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
> @@ -261,12 +261,13 @@ static void rcar_du_crtc_set_display_timing(struct 
> rcar_du_crtc *rcrtc)
>   rcar_du_group_write(rcrtc->group, DPLLCR, dpllcr);
>  
>   escr = ESCR_DCLKSEL_DCLKIN | div;
> - } else if (rcdu->info->lvds_clk_mask & BIT(rcrtc->index)) {
> + } else if (rcdu->info->lvds_clk_mask & BIT(rcrtc->index) ||
> +rcdu->info->dsi_clk_mask & BIT(rcrtc->index)) {
>   /*
> -  * Use the LVDS PLL output as the dot clock when outputting to
> -  * the LVDS encoder on an SoC that supports this clock routing
> -  * option. We use the clock directly in that case, without any
> -  * additional divider.
> +  * Use the external LVDS or DSI PLL output as the dot clock when
> +  * outputting to the LVDS or DSI encoder on an SoC that supports
> +  * this clock routing option. We use the clock directly in that
> +  * case, without any additional divider.
>*/
>   escr = ESCR_DCLKSEL_DCLKIN;
>   } else {

-- 
Regards,

Laurent Pinchart


[PATCH v9 19/22] drm/mediatek: modify mediatek-drm for mt8195 multi mmsys support

2021-11-29 Thread Nancy . Lin
MT8195 have two mmsys. Modify drm for MT8195 multi-mmsys support.
The two mmsys (vdosys0 and vdosys1) will bring up two drm drivers,
only one drm driver register as the drm device.
Each drm driver binds its own component. The last bind drm driver
allocates and registers the drm device to drm core.
Each crtc path is created with the corresponding drm driver data.

Signed-off-by: Nancy.Lin 
---
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c |  24 +-
 drivers/gpu/drm/mediatek/mtk_drm_crtc.h |   3 +-
 drivers/gpu/drm/mediatek/mtk_drm_drv.c  | 300 ++--
 drivers/gpu/drm/mediatek/mtk_drm_drv.h  |  10 +-
 4 files changed, 246 insertions(+), 91 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c 
b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index d661edf7e0fe..fe2871aca859 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -847,21 +847,28 @@ static int mtk_drm_crtc_init_comp_planes(struct 
drm_device *drm_dev,
 }
 
 int mtk_drm_crtc_create(struct drm_device *drm_dev,
-   const enum mtk_ddp_comp_id *path, unsigned int path_len)
+   const enum mtk_ddp_comp_id *path, unsigned int path_len,
+   int priv_data_index)
 {
struct mtk_drm_private *priv = drm_dev->dev_private;
struct device *dev = drm_dev->dev;
struct mtk_drm_crtc *mtk_crtc;
unsigned int num_comp_planes = 0;
-   int pipe = priv->num_pipes;
int ret;
int i;
bool has_ctm = false;
uint gamma_lut_size = 0;
+   struct drm_crtc *tmp;
+   int crtc_i = 0;
 
if (!path)
return 0;
 
+   priv = priv->all_drm_private[priv_data_index];
+
+   drm_for_each_crtc(tmp, drm_dev)
+   crtc_i++;
+
for (i = 0; i < path_len; i++) {
enum mtk_ddp_comp_id comp_id = path[i];
struct device_node *node;
@@ -873,7 +880,7 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
if (!node) {
dev_info(dev,
 "Not creating crtc %d because component %d is 
disabled or missing\n",
-pipe, comp_id);
+crtc_i, comp_id);
return 0;
}
 
@@ -926,29 +933,28 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
 
for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
ret = mtk_drm_crtc_init_comp_planes(drm_dev, mtk_crtc, i,
-   pipe);
+   crtc_i);
if (ret)
return ret;
}
 
-   ret = mtk_drm_crtc_init(drm_dev, mtk_crtc, pipe);
+   ret = mtk_drm_crtc_init(drm_dev, mtk_crtc, crtc_i);
if (ret < 0)
return ret;
 
if (gamma_lut_size)
drm_mode_crtc_set_gamma_size(&mtk_crtc->base, gamma_lut_size);
drm_crtc_enable_color_mgmt(&mtk_crtc->base, 0, has_ctm, gamma_lut_size);
-   priv->num_pipes++;
mutex_init(&mtk_crtc->hw_lock);
 
 #if IS_REACHABLE(CONFIG_MTK_CMDQ)
+   i = (priv->data->mbox_index) ? 
priv->data->mbox_index[drm_crtc_index(&mtk_crtc->base)] : 0;
mtk_crtc->cmdq_client.client.dev = mtk_crtc->mmsys_dev;
mtk_crtc->cmdq_client.client.tx_block = false;
mtk_crtc->cmdq_client.client.knows_txdone = true;
mtk_crtc->cmdq_client.client.rx_callback = ddp_cmdq_cb;
mtk_crtc->cmdq_client.chan =
-   mbox_request_channel(&mtk_crtc->cmdq_client.client,
-drm_crtc_index(&mtk_crtc->base));
+   mbox_request_channel(&mtk_crtc->cmdq_client.client, i);
if (IS_ERR(mtk_crtc->cmdq_client.chan)) {
dev_dbg(dev, "mtk_crtc %d failed to create mailbox client, 
writing register by CPU now\n",
drm_crtc_index(&mtk_crtc->base));
@@ -958,7 +964,7 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
if (mtk_crtc->cmdq_client.chan) {
ret = of_property_read_u32_index(priv->mutex_node,
 "mediatek,gce-events",
-
drm_crtc_index(&mtk_crtc->base),
+i,
 &mtk_crtc->cmdq_event);
if (ret) {
dev_dbg(dev, "mtk_crtc %d failed to get 
mediatek,gce-events property\n",
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.h 
b/drivers/gpu/drm/mediatek/mtk_drm_crtc.h
index cb9a36c48d4f..a57eb12d7c05 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.h
@@ -17,7 +17,8 @@
 void mtk_drm_crtc_commit(struct drm_crtc *crtc);
 int mtk_drm_crtc_create(struct drm_device *drm_dev,
const enum m

[PATCH v9 15/22] drm/mediatek: add display merge async reset control

2021-11-29 Thread Nancy . Lin
Add merge async reset control in mtk_merge_stop. Async hw doesn't do self
reset on each sof signal(start of frame), so need to reset the async to
clear the hw status for the next merge start.

Signed-off-by: Nancy.Lin 
---
 drivers/gpu/drm/mediatek/mtk_disp_merge.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_merge.c 
b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
index 9dca145cfb71..177473fa8160 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_merge.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
@@ -8,6 +8,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include "mtk_drm_ddp_comp.h"
@@ -79,6 +80,9 @@ void mtk_merge_stop(struct device *dev)
struct mtk_disp_merge *priv = dev_get_drvdata(dev);
 
mtk_merge_stop_cmdq(dev, NULL);
+
+   if (priv->async_clk)
+   device_reset_optional(dev);
 }
 
 void mtk_merge_start_cmdq(struct device *dev, struct cmdq_pkt *cmdq_pkt)
-- 
2.18.0



[PATCH v9 09/22] soc: mediatek: change the mutex defines and the mutex_mod type

2021-11-29 Thread Nancy . Lin
This is a preparation for adding support for mt8195 vdosys1 mutex.
The vdosys1 path component contains ovl_adaptor, merge5,
and dp_intf1. Ovl_adaptor is composed of several sub-elements,
so change it to support multi-bit control.

Signed-off-by: Nancy.Lin 
---
 drivers/soc/mediatek/mtk-mutex.c | 242 +++
 1 file changed, 121 insertions(+), 121 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-mutex.c b/drivers/soc/mediatek/mtk-mutex.c
index 36502b27fe20..ff2f74668e8a 100644
--- a/drivers/soc/mediatek/mtk-mutex.c
+++ b/drivers/soc/mediatek/mtk-mutex.c
@@ -29,113 +29,113 @@
 
 #define INT_MUTEX  BIT(1)
 
-#define MT8167_MUTEX_MOD_DISP_PWM  1
-#define MT8167_MUTEX_MOD_DISP_OVL0 6
-#define MT8167_MUTEX_MOD_DISP_OVL1 7
-#define MT8167_MUTEX_MOD_DISP_RDMA08
-#define MT8167_MUTEX_MOD_DISP_RDMA19
-#define MT8167_MUTEX_MOD_DISP_WDMA010
-#define MT8167_MUTEX_MOD_DISP_CCORR11
-#define MT8167_MUTEX_MOD_DISP_COLOR12
-#define MT8167_MUTEX_MOD_DISP_AAL  13
-#define MT8167_MUTEX_MOD_DISP_GAMMA14
-#define MT8167_MUTEX_MOD_DISP_DITHER   15
-#define MT8167_MUTEX_MOD_DISP_UFOE 16
-
-#define MT8192_MUTEX_MOD_DISP_OVL0 0
-#define MT8192_MUTEX_MOD_DISP_OVL0_2L  1
-#define MT8192_MUTEX_MOD_DISP_RDMA02
-#define MT8192_MUTEX_MOD_DISP_COLOR0   4
-#define MT8192_MUTEX_MOD_DISP_CCORR0   5
-#define MT8192_MUTEX_MOD_DISP_AAL0 6
-#define MT8192_MUTEX_MOD_DISP_GAMMA0   7
-#define MT8192_MUTEX_MOD_DISP_POSTMASK08
-#define MT8192_MUTEX_MOD_DISP_DITHER0  9
-#define MT8192_MUTEX_MOD_DISP_OVL2_2L  16
-#define MT8192_MUTEX_MOD_DISP_RDMA417
-
-#define MT8183_MUTEX_MOD_DISP_RDMA00
-#define MT8183_MUTEX_MOD_DISP_RDMA11
-#define MT8183_MUTEX_MOD_DISP_OVL0 9
-#define MT8183_MUTEX_MOD_DISP_OVL0_2L  10
-#define MT8183_MUTEX_MOD_DISP_OVL1_2L  11
-#define MT8183_MUTEX_MOD_DISP_WDMA012
-#define MT8183_MUTEX_MOD_DISP_COLOR0   13
-#define MT8183_MUTEX_MOD_DISP_CCORR0   14
-#define MT8183_MUTEX_MOD_DISP_AAL0 15
-#define MT8183_MUTEX_MOD_DISP_GAMMA0   16
-#define MT8183_MUTEX_MOD_DISP_DITHER0  17
-
-#define MT8173_MUTEX_MOD_DISP_OVL0 11
-#define MT8173_MUTEX_MOD_DISP_OVL1 12
-#define MT8173_MUTEX_MOD_DISP_RDMA013
-#define MT8173_MUTEX_MOD_DISP_RDMA114
-#define MT8173_MUTEX_MOD_DISP_RDMA215
-#define MT8173_MUTEX_MOD_DISP_WDMA016
-#define MT8173_MUTEX_MOD_DISP_WDMA117
-#define MT8173_MUTEX_MOD_DISP_COLOR0   18
-#define MT8173_MUTEX_MOD_DISP_COLOR1   19
-#define MT8173_MUTEX_MOD_DISP_AAL  20
-#define MT8173_MUTEX_MOD_DISP_GAMMA21
-#define MT8173_MUTEX_MOD_DISP_UFOE 22
-#define MT8173_MUTEX_MOD_DISP_PWM0 23
-#define MT8173_MUTEX_MOD_DISP_PWM1 24
-#define MT8173_MUTEX_MOD_DISP_OD   25
-
-#define MT8195_MUTEX_MOD_DISP_OVL0 0
-#define MT8195_MUTEX_MOD_DISP_WDMA01
-#define MT8195_MUTEX_MOD_DISP_RDMA02
-#define MT8195_MUTEX_MOD_DISP_COLOR0   3
-#define MT8195_MUTEX_MOD_DISP_CCORR0   4
-#define MT8195_MUTEX_MOD_DISP_AAL0 5
-#define MT8195_MUTEX_MOD_DISP_GAMMA0   6
-#define MT8195_MUTEX_MOD_DISP_DITHER0  7
-#define MT8195_MUTEX_MOD_DISP_DSI0 8
-#define MT8195_MUTEX_MOD_DISP_DSC_WRAP0_CORE0  9
-#define MT8195_MUTEX_MOD_DISP_OVL1 10
-#define MT8195_MUTEX_MOD_DISP_WDMA111
-#define MT8195_MUTEX_MOD_DISP_RDMA112
-#define MT8195_MUTEX_MOD_DISP_COLOR1   13
-#define MT8195_MUTEX_MOD_DISP_CCORR1   14
-#define MT8195_MUTEX_MOD_DISP_AAL1 15
-#define MT8195_MUTEX_MOD_DISP_GAMMA1   16
-#define MT8195_MUTEX_MOD_DISP_DITHER1  17
-#define MT8195_MUTEX_MOD_DISP_DSI1 18
-#define MT8195_MUTEX_MOD_DISP_DSC_WRAP0_CORE1  19
-#define MT8195_MUTEX_MOD_DISP_VPP_MERGE20
-#define MT8195_MUTEX_MOD_DISP_DP_INTF0 21
-#define MT8195_MUTEX_MOD_DISP_VPP1_DL_RELAY0   22
-#define MT8195_MUTEX_MOD_DISP_VPP1_DL_RELAY1   23
-#define MT8195_MUTEX_MOD_DISP_VDO1_DL_RELAY2   24
-#define MT8195_MUTEX_MOD_DISP_VDO0_DL_RELAY3   25
-#define MT8195_MUTEX_MOD_DISP_VDO0_DL_RELAY4   26
-#define MT8195_MUTEX_MOD_DISP_PWM0 27
-#define MT8195_MUTEX_MOD_DISP_PWM1 28
-
-#define MT2712_MUTEX_MOD_DISP_PWM2 10
-#define MT2712_MUTEX_MOD_DISP_OVL0 11
-#define MT2712_MUTEX_MOD_DISP_OVL1 12
-#define MT2712_MUTEX_MOD_DISP_RDMA013
-#define MT2712_MUTEX_MOD_DISP_RDMA114
-#define MT2712_MUTEX_MOD_DISP_RDMA215
-#define MT2712_MUTEX_MOD_DISP_WDMA01

[PATCH v9 17/22] drm/mediatek: add mediatek-drm plane color encoding info

2021-11-29 Thread Nancy . Lin
Add plane color encoding information for color space conversion.
It's a preparation for adding support for mt8195 ovl_adaptor mdp_rdma
csc control.

Signed-off-by: Nancy.Lin 
Reviewed-by: Chun-Kuang Hu 
---
 drivers/gpu/drm/mediatek/mtk_drm_plane.c | 1 +
 drivers/gpu/drm/mediatek/mtk_drm_plane.h | 1 +
 2 files changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_plane.c 
b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
index 734a1fb052df..81bd5d6e8df5 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_plane.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
@@ -137,6 +137,7 @@ static void mtk_plane_update_new_state(struct 
drm_plane_state *new_state,
mtk_plane_state->pending.width = drm_rect_width(&new_state->dst);
mtk_plane_state->pending.height = drm_rect_height(&new_state->dst);
mtk_plane_state->pending.rotation = new_state->rotation;
+   mtk_plane_state->pending.color_encoding = new_state->color_encoding;
 }
 
 static void mtk_plane_atomic_async_update(struct drm_plane *plane,
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_plane.h 
b/drivers/gpu/drm/mediatek/mtk_drm_plane.h
index d454bece9535..2d5ec66e3df1 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_plane.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_plane.h
@@ -24,6 +24,7 @@ struct mtk_plane_pending_state {
booldirty;
boolasync_dirty;
boolasync_config;
+   enum drm_color_encoding color_encoding;
 };
 
 struct mtk_plane_state {
-- 
2.18.0



[PATCH v9 05/22] soc: mediatek: add mtk-mmsys support for mt8195 vdosys1

2021-11-29 Thread Nancy . Lin
Add mt8195 vdosys1 clock driver name and routing table to
the driver data of mtk-mmsys.

Signed-off-by: Nancy.Lin 
---
 drivers/soc/mediatek/mt8195-mmsys.h| 136 +
 drivers/soc/mediatek/mtk-mmsys.c   |  10 ++
 include/linux/soc/mediatek/mtk-mmsys.h |   2 +
 3 files changed, 148 insertions(+)

diff --git a/drivers/soc/mediatek/mt8195-mmsys.h 
b/drivers/soc/mediatek/mt8195-mmsys.h
index e04cabdfa2dc..65da65754d6e 100644
--- a/drivers/soc/mediatek/mt8195-mmsys.h
+++ b/drivers/soc/mediatek/mt8195-mmsys.h
@@ -165,6 +165,70 @@
 #define MT8195_SOUT_DSC_WRAP1_OUT_TO_SINA_VIRTUAL0 BIT(17)
 #define MT8195_SOUT_DSC_WRAP1_OUT_TO_VPP_MERGE (BIT(17) | 
BIT(16))
 
+#define MT8195_VDO1_VPP_MERGE0_P0_SEL_IN   0xf04
+#define MT8195_VPP_MERGE0_P0_SEL_IN_FROM_MDP_RDMA0 1
+
+#define MT8195_VDO1_VPP_MERGE0_P1_SEL_IN   0xf08
+#define MT8195_VPP_MERGE0_P1_SEL_IN_FROM_MDP_RDMA1 1
+
+#define MT8195_VDO1_DISP_DPI1_SEL_IN   0xf10
+#define MT8195_DISP_DPI1_SEL_IN_FROM_VPP_MERGE4_MOUT   0
+
+#define MT8195_VDO1_DISP_DP_INTF0_SEL_IN   0xf14
+#define MT8195_DISP_DP_INTF0_SEL_IN_FROM_VPP_MERGE4_MOUT   0
+
+#define MT8195_VDO1_MERGE4_SOUT_SEL0xf18
+#define MT8195_MERGE4_SOUT_TO_DPI1_SEL 2
+#define MT8195_MERGE4_SOUT_TO_DP_INTF0_SEL 3
+
+#define MT8195_VDO1_MIXER_IN1_SEL_IN   0xf24
+#define MT8195_MIXER_IN1_SEL_IN_FROM_MERGE0_ASYNC_SOUT 1
+
+#define MT8195_VDO1_MIXER_IN2_SEL_IN   0xf28
+#define MT8195_MIXER_IN2_SEL_IN_FROM_MERGE1_ASYNC_SOUT 1
+
+#define MT8195_VDO1_MIXER_IN3_SEL_IN   0xf2c
+#define MT8195_MIXER_IN3_SEL_IN_FROM_MERGE2_ASYNC_SOUT 1
+
+#define MT8195_VDO1_MIXER_IN4_SEL_IN   0xf30
+#define MT8195_MIXER_IN4_SEL_IN_FROM_MERGE3_ASYNC_SOUT 1
+
+#define MT8195_VDO1_MIXER_OUT_SOUT_SEL 0xf34
+#define MT8195_MIXER_SOUT_TO_MERGE4_ASYNC_SEL  1
+
+#define MT8195_VDO1_VPP_MERGE1_P0_SEL_IN   0xf3c
+#define MT8195_VPP_MERGE1_P0_SEL_IN_FROM_MDP_RDMA2 1
+
+#define MT8195_VDO1_MERGE0_ASYNC_SOUT_SEL  0xf40
+#define MT8195_SOUT_TO_MIXER_IN1_SEL   1
+
+#define MT8195_VDO1_MERGE1_ASYNC_SOUT_SEL  0xf44
+#define MT8195_SOUT_TO_MIXER_IN2_SEL   1
+
+#define MT8195_VDO1_MERGE2_ASYNC_SOUT_SEL  0xf48
+#define MT8195_SOUT_TO_MIXER_IN3_SEL   1
+
+#define MT8195_VDO1_MERGE3_ASYNC_SOUT_SEL  0xf4c
+#define MT8195_SOUT_TO_MIXER_IN4_SEL   1
+
+#define MT8195_VDO1_MERGE4_ASYNC_SEL_IN0xf50
+#define MT8195_MERGE4_ASYNC_SEL_IN_FROM_MIXER_OUT_SOUT 1
+
+#define MT8195_VDO1_MIXER_IN1_SOUT_SEL 0xf58
+#define MT8195_MIXER_IN1_SOUT_TO_DISP_MIXER0
+
+#define MT8195_VDO1_MIXER_IN2_SOUT_SEL 0xf5c
+#define MT8195_MIXER_IN2_SOUT_TO_DISP_MIXER0
+
+#define MT8195_VDO1_MIXER_IN3_SOUT_SEL 0xf60
+#define MT8195_MIXER_IN3_SOUT_TO_DISP_MIXER0
+
+#define MT8195_VDO1_MIXER_IN4_SOUT_SEL 0xf64
+#define MT8195_MIXER_IN4_SOUT_TO_DISP_MIXER0
+
+#define MT8195_VDO1_MIXER_SOUT_SEL_IN  0xf68
+#define MT8195_MIXER_SOUT_SEL_IN_FROM_DISP_MIXER   0
+
 static const struct mtk_mmsys_routes mmsys_mt8195_routing_table[] = {
{
DDP_COMPONENT_OVL0, DDP_COMPONENT_RDMA0,
@@ -214,6 +278,78 @@ static const struct mtk_mmsys_routes 
mmsys_mt8195_routing_table[] = {
DDP_COMPONENT_MERGE0, DDP_COMPONENT_DP_INTF0,
MT8195_VDO0_SEL_OUT, MT8195_SOUT_VPP_MERGE_TO_DP_INTF0,
MT8195_SOUT_VPP_MERGE_TO_DP_INTF0
+   }, {
+   DDP_COMPONENT_OVL_ADAPTOR, DDP_COMPONENT_MERGE5,
+   MT8195_VDO1_VPP_MERGE0_P0_SEL_IN, GENMASK(0, 0),
+   MT8195_VPP_MERGE0_P0_SEL_IN_FROM_MDP_RDMA0
+   }, {
+   DDP_COMPONENT_OVL_ADAPTOR, DDP_COMPONENT_MERGE5,
+   MT8195_VDO1_VPP_MERGE0_P1_SEL_IN, GENMASK(0, 0),
+   MT8195_VPP_MERGE0_P1_SEL_IN_FROM_MDP_RDMA1
+   }, {
+   DDP_COMPONENT_OVL_ADAPTOR, DDP_COMPONENT_MERGE5,
+   MT8195_VDO1_VPP_MERGE1_P0_SEL_IN, GENMASK(0, 0),
+   MT8195_VPP_MERGE1_P0_SEL_IN_FROM_MDP_RDMA2
+   }, {
+   DDP_COMPONENT_OVL_ADAPTOR, DDP_COMPONENT_MERGE5,
+   MT8195_VDO1_MERGE0_A

[PATCH v9 12/22] drm/mediatek: add display merge advance config API for MT8195

2021-11-29 Thread Nancy . Lin
Add merge new advance config API. The original merge API is
mtk_ddp_comp_funcs function prototype. The API interface parameters
cannot be modified, so add a new config API for extension. This is
the preparation for ovl_adaptor merge control.

Signed-off-by: Nancy.Lin 
Reviewed-by: Chun-Kuang Hu 
---
 drivers/gpu/drm/mediatek/mtk_disp_drv.h   |  3 ++
 drivers/gpu/drm/mediatek/mtk_disp_merge.c | 52 ---
 2 files changed, 48 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h 
b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
index b3a372cab0bd..c2de53a5892e 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
@@ -63,6 +63,9 @@ void mtk_merge_config(struct device *dev, unsigned int width,
  unsigned int bpc, struct cmdq_pkt *cmdq_pkt);
 void mtk_merge_start(struct device *dev);
 void mtk_merge_stop(struct device *dev);
+void mtk_merge_advance_config(struct device *dev, unsigned int l_w, unsigned 
int r_w,
+ unsigned int h, unsigned int vrefresh, unsigned 
int bpc,
+ struct cmdq_pkt *cmdq_pkt);
 
 void mtk_ovl_bgclr_in_on(struct device *dev);
 void mtk_ovl_bgclr_in_off(struct device *dev);
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_merge.c 
b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
index 45face638153..40da0555416d 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_merge.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
@@ -17,6 +17,7 @@
 #define DISP_REG_MERGE_CTRL0x000
 #define MERGE_EN   1
 #define DISP_REG_MERGE_CFG_0   0x010
+#define DISP_REG_MERGE_CFG_1   0x014
 #define DISP_REG_MERGE_CFG_4   0x020
 #define DISP_REG_MERGE_CFG_10  0x038
 /* no swap */
@@ -25,9 +26,12 @@
 #define DISP_REG_MERGE_CFG_12  0x040
 #define CFG_10_10_1PI_2PO_BUF_MODE 6
 #define CFG_10_10_2PI_2PO_BUF_MODE 8
+#define CFG_11_10_1PI_2PO_MERGE18
 #define FLD_CFG_MERGE_MODE GENMASK(4, 0)
 #define DISP_REG_MERGE_CFG_24  0x070
 #define DISP_REG_MERGE_CFG_25  0x074
+#define DISP_REG_MERGE_CFG_26  0x078
+#define DISP_REG_MERGE_CFG_27  0x07c
 #define DISP_REG_MERGE_CFG_36  0x0a0
 #define ULTRA_EN   BIT(0)
 #define PREULTRA_ENBIT(4)
@@ -98,12 +102,19 @@ static void mtk_merge_fifo_setting(struct mtk_disp_merge 
*priv,
 void mtk_merge_config(struct device *dev, unsigned int w,
  unsigned int h, unsigned int vrefresh,
  unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
+{
+   mtk_merge_advance_config(dev, w, 0, h, vrefresh, bpc, cmdq_pkt);
+}
+
+void mtk_merge_advance_config(struct device *dev, unsigned int l_w, unsigned 
int r_w,
+ unsigned int h, unsigned int vrefresh, unsigned 
int bpc,
+ struct cmdq_pkt *cmdq_pkt)
 {
struct mtk_disp_merge *priv = dev_get_drvdata(dev);
unsigned int mode = CFG_10_10_1PI_2PO_BUF_MODE;
 
-   if (!h || !w) {
-   dev_err(dev, "%s: input width(%d) or height(%d) is invalid\n", 
__func__, w, h);
+   if (!h || !l_w) {
+   dev_err(dev, "%s: input width(%d) or height(%d) is invalid\n", 
__func__, l_w, h);
return;
}
 
@@ -112,14 +123,41 @@ void mtk_merge_config(struct device *dev, unsigned int w,
mode = CFG_10_10_2PI_2PO_BUF_MODE;
}
 
-   mtk_ddp_write(cmdq_pkt, h << 16 | w, &priv->cmdq_reg, priv->regs,
+   if (r_w)
+   mode = CFG_11_10_1PI_2PO_MERGE;
+
+   mtk_ddp_write(cmdq_pkt, h << 16 | l_w, &priv->cmdq_reg, priv->regs,
  DISP_REG_MERGE_CFG_0);
-   mtk_ddp_write(cmdq_pkt, h << 16 | w, &priv->cmdq_reg, priv->regs,
+   mtk_ddp_write(cmdq_pkt, h << 16 | r_w, &priv->cmdq_reg, priv->regs,
+ DISP_REG_MERGE_CFG_1);
+   mtk_ddp_write(cmdq_pkt, h << 16 | (l_w + r_w), &priv->cmdq_reg, 
priv->regs,
  DISP_REG_MERGE_CFG_4);
-   mtk_ddp_write(cmdq_pkt, h << 16 | w, &priv->cmdq_reg, priv->regs,
+   /*
+* DISP_REG_MERGE_CFG_24 is merge SRAM0 w/h
+* DISP_REG_MERGE_CFG_25 is merge SRAM1 w/h.
+* If r_w > 0, the merge is in merge mode (input0 and input1 merge 
together),
+* the input0 goes to SRAM0, and input1 goes to SRAM1.
+* If r_w = 0, the merge is in buffer mode, the input goes through 
SRAM0 and
+* then to SRAM1. Both SRAM0 and SRAM1 are set to the same size.
+*/
+   mtk_ddp_write(cmdq_pkt, h << 16 | l_w, &priv->cmdq_reg, priv->regs,
  DISP_REG_MERGE_CFG_24);
-   mtk_ddp_write(cmdq_pkt, h << 16 | w, &priv->cmdq_reg, priv->regs,
- DISP_REG_MERGE_CFG_25);
+   if (r_w)
+   mtk_ddp_write(cmdq_pkt, h << 16 | r_w, &priv->cmdq

[PATCH v9 00/22] Add MediaTek SoC DRM (vdosys1) support for mt8195

2021-11-29 Thread Nancy . Lin
The hardware path of vdosys1 with DPTx output need to go through by several 
modules, such as, OVL_ADAPTOR and MERGE.

Add DRM and these modules support by the patches below:

Changes in v9:
- rebase on kernel-5.16-rc1
- rebase on vdosys0 series v13. (ref [5])
- fix ovl_adaptor sub driver is brought up unintentionally
- fix clang build test fail- duplicate ethdr/mdp_rdma 
init_module/cleanup_module symbol issue 

Changes in v8:
- separate merge async reset to new patch.
- separate drm ovl_adaptor sub driver to new patch.
- fix reviewer comment in v7.

Changes in v7:
- rebase on vdosys0 series v12 (ref[5])
- add dma description in ethdr binding document.
- refine vdosys1 bit definition of mmsys routing table.
- separate merge modification into 3 pathces.
- separate mutex modification into 2 patches.
- add plane color coding for mdp_rdma csc.
- move mdp_rdma pm control to ovl_adaptor.
- fix reviewer comment in v6.

Changes in v6:
- rebase on kernel-5.15-rc1.
- change mbox label to gce0 for dts node of vdosys1.
- modify mmsys reset num for mt8195.
- rebase on vdosys0 series v10. (ref [5])
- use drm to bring up ovl_adaptor driver.
- move drm iommu/mutex check from kms init to drm bind.
- modify rdma binding doc location. (Documentation/devicetree/bindings/arm/)
- modify for reviewer's comment in v5.

Changes in v5:
- add mmsys reset controller reference.

Changes in v4:
- use merge common driver for merge1~4.
- refine ovl_adaptor rdma driver.
- use ovl_adaptor ddp_comp function instead of ethdr.
- modify for reviewer's comment in v3.

Changes in v3:
- modify for reviewer's comment in v2.
- add vdosys1 2 pixels align limit.
- add mixer odd offset support.

Changes in v2:
- Merge PSEUDO_OVL and ETHDR into one DRM component.
- Add mmsys config API for vdosys1 hardware setting.
- Add mmsys reset control using linux reset framework.

Signed-off-by: Nancy.Lin 

This series are based on the following patch:
[1] arm64: dts: Add Mediatek SoC MT8195 and evaluation board dts and Makefile

https://patchwork.kernel.org/project/linux-mediatek/patch/20210601075350.31515-2-seiya.w...@mediatek.com/
[2] arm64: dts: mt8195: add IOMMU and smi nodes

https://patchwork.kernel.org/project/linux-mediatek/patch/20210615173233.26682-15-tinghan.s...@mediatek.com/
[3] [01/24] dt-bindings: mediatek: mt8195: Add binding for MM IOMMU

https://patchwork.kernel.org/project/linux-mediatek/patch/20210630023504.18177-2-yong...@mediatek.com/
[4] Add gce support for mt8195
https://patchwork.kernel.org/project/linux-mediatek/list/?series=537069
[5] Add MediaTek SoC DRM (vdosys0) support for mt8195
https://patchwork.kernel.org/project/linux-mediatek/list/?series=587313
[6] [v8,1/2] dt-bindings: reset: mt8195: add toprgu reset-controller header file

https://patchwork.kernel.org/project/linux-mediatek/patch/20210806023606.16867-2-christine@mediatek.com/

Nancy.Lin (22):
  dt-bindings: mediatek: add vdosys1 RDMA definition for mt8195
  dt-bindings: mediatek: add vdosys1 MERGE property for mt8195
  dt-bindings: mediatek: add ethdr definition for mt8195
  dt-bindings: reset: mt8195: add vdosys1 reset control bit
  soc: mediatek: add mtk-mmsys support for mt8195 vdosys1
  soc: mediatek: add mtk-mmsys config API for mt8195 vdosys1
  soc: mediatek: add cmdq support of mtk-mmsys config API for mt8195
vdosys1
  soc: mediatek: mmsys: modify reset controller for MT8195 vdosys1
  soc: mediatek: change the mutex defines and the mutex_mod type
  soc: mediatek: add mtk-mutex support for mt8195 vdosys1
  drm/mediatek: add display MDP RDMA support for MT8195
  drm/mediatek: add display merge advance config API for MT8195
  drm/mediatek: add display merge start/stop API for cmdq support
  drm/mediatek: add display merge mute/unmute support for MT8195
  drm/mediatek: add display merge async reset control
  drm/mediatek: add ETHDR support for MT8195
  drm/mediatek: add mediatek-drm plane color encoding info
  drm/mediatek: add ovl_adaptor support for MT8195
  drm/mediatek: modify mediatek-drm for mt8195 multi mmsys support
  drm/mediatek: add drm ovl_adaptor sub driver for MT8195
  drm/mediatek: add mediatek-drm of vdosys1 support for MT8195
  arm64: dts: mt8195: add display node for vdosys1

 .../arm/mediatek/mediatek,mdp-rdma.yaml   |  77 
 .../display/mediatek/mediatek,ethdr.yaml  | 147 ++
 .../display/mediatek/mediatek,merge.yaml  |   4 +
 arch/arm64/boot/dts/mediatek/mt8195.dtsi  | 222 +
 drivers/gpu/drm/mediatek/Makefile |   5 +-
 drivers/gpu/drm/mediatek/mtk_disp_drv.h   |  28 ++
 drivers/gpu/drm/mediatek/mtk_disp_merge.c |  89 +++-
 .../gpu/drm/mediatek/mtk_disp_ovl_adaptor.c   | 436 ++
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c   |  38 +-
 drivers/gpu/drm/mediatek/mtk_drm_crtc.h   |   3 +-
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c   |  30 +-
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h   |   1 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c| 343 +

[PATCH v9 18/22] drm/mediatek: add ovl_adaptor support for MT8195

2021-11-29 Thread Nancy . Lin
Add ovl_adaptor driver for MT8195.
Ovl_adaptor is an encapsulated module and designed for simplified
DRM control flow. This module is composed of 8 RDMAs, 4 MERGEs and
an ETHDR. Two RDMAs merge into one layer, so this module support 4
layers.

Signed-off-by: Nancy.Lin 
Reviewed-by: Chun-Kuang Hu 
---
 drivers/gpu/drm/mediatek/Makefile |   1 +
 drivers/gpu/drm/mediatek/mtk_disp_drv.h   |  16 +
 .../gpu/drm/mediatek/mtk_disp_ovl_adaptor.c   | 436 ++
 drivers/gpu/drm/mediatek/mtk_drm_drv.h|   1 +
 4 files changed, 454 insertions(+)
 create mode 100644 drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c

diff --git a/drivers/gpu/drm/mediatek/Makefile 
b/drivers/gpu/drm/mediatek/Makefile
index fb158a1e7f06..3abd27d7c91d 100644
--- a/drivers/gpu/drm/mediatek/Makefile
+++ b/drivers/gpu/drm/mediatek/Makefile
@@ -6,6 +6,7 @@ mediatek-drm-y := mtk_disp_aal.o \
  mtk_disp_gamma.o \
  mtk_disp_merge.o \
  mtk_disp_ovl.o \
+ mtk_disp_ovl_adaptor.o \
  mtk_disp_rdma.o \
  mtk_drm_crtc.o \
  mtk_drm_ddp_comp.o \
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h 
b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
index 224a710bb537..cd9827402626 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
@@ -112,6 +112,22 @@ void mtk_rdma_enable_vblank(struct device *dev,
void *vblank_cb_data);
 void mtk_rdma_disable_vblank(struct device *dev);
 
+int mtk_ovl_adaptor_clk_enable(struct device *dev);
+void mtk_ovl_adaptor_clk_disable(struct device *dev);
+void mtk_ovl_adaptor_config(struct device *dev, unsigned int w,
+   unsigned int h, unsigned int vrefresh,
+   unsigned int bpc, struct cmdq_pkt *cmdq_pkt);
+void mtk_ovl_adaptor_layer_config(struct device *dev, unsigned int idx,
+ struct mtk_plane_state *state,
+ struct cmdq_pkt *cmdq_pkt);
+void mtk_ovl_adaptor_enable_vblank(struct device *dev,
+  void (*vblank_cb)(void *),
+  void *vblank_cb_data);
+void mtk_ovl_adaptor_disable_vblank(struct device *dev);
+void mtk_ovl_adaptor_start(struct device *dev);
+void mtk_ovl_adaptor_stop(struct device *dev);
+unsigned int mtk_ovl_adaptor_layer_nr(struct device *dev);
+
 int mtk_mdp_rdma_clk_enable(struct device *dev);
 void mtk_mdp_rdma_clk_disable(struct device *dev);
 void mtk_mdp_rdma_start(struct device *dev, struct cmdq_pkt *cmdq_pkt);
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c 
b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
new file mode 100644
index ..fd93aa034039
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
@@ -0,0 +1,436 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "mtk_disp_drv.h"
+#include "mtk_drm_crtc.h"
+#include "mtk_drm_ddp_comp.h"
+#include "mtk_drm_drv.h"
+#include "mtk_ethdr.h"
+
+#define MTK_OVL_ADAPTOR_RDMA_MAX_WIDTH 1920
+#define MTK_OVL_ADAPTOR_LAYER_NUM 4
+
+enum mtk_ovl_adaptor_comp_type {
+   OVL_ADAPTOR_TYPE_RDMA = 0,
+   OVL_ADAPTOR_TYPE_MERGE,
+   OVL_ADAPTOR_TYPE_ETHDR,
+   OVL_ADAPTOR_TYPE_NUM,
+};
+
+enum mtk_ovl_adaptor_comp_id {
+   OVL_ADAPTOR_MDP_RDMA0,
+   OVL_ADAPTOR_MDP_RDMA1,
+   OVL_ADAPTOR_MDP_RDMA2,
+   OVL_ADAPTOR_MDP_RDMA3,
+   OVL_ADAPTOR_MDP_RDMA4,
+   OVL_ADAPTOR_MDP_RDMA5,
+   OVL_ADAPTOR_MDP_RDMA6,
+   OVL_ADAPTOR_MDP_RDMA7,
+   OVL_ADAPTOR_MERGE0,
+   OVL_ADAPTOR_MERGE1,
+   OVL_ADAPTOR_MERGE2,
+   OVL_ADAPTOR_MERGE3,
+   OVL_ADAPTOR_ETHDR0,
+   OVL_ADAPTOR_ID_MAX
+};
+
+struct ovl_adaptor_comp_match {
+   enum mtk_ovl_adaptor_comp_type type;
+   int alias_id;
+};
+
+struct mtk_disp_ovl_adaptor {
+   struct device *ovl_adaptor_comp[OVL_ADAPTOR_ID_MAX];
+   struct device *mmsys_dev;
+};
+
+static const char * const private_comp_stem[OVL_ADAPTOR_TYPE_NUM] = {
+   [OVL_ADAPTOR_TYPE_RDMA] = "vdo1_rdma",
+   [OVL_ADAPTOR_TYPE_MERGE]= "merge",
+   [OVL_ADAPTOR_TYPE_ETHDR]= "ethdr",
+};
+
+static const struct ovl_adaptor_comp_match comp_matches[OVL_ADAPTOR_ID_MAX] = {
+   [OVL_ADAPTOR_MDP_RDMA0] = { OVL_ADAPTOR_TYPE_RDMA, 0 },
+   [OVL_ADAPTOR_MDP_RDMA1] = { OVL_ADAPTOR_TYPE_RDMA, 1 },
+   [OVL_ADAPTOR_MDP_RDMA2] = { OVL_ADAPTOR_TYPE_RDMA, 2 },
+   [OVL_ADAPTOR_MDP_RDMA3] = { OVL_ADAPTOR_TYPE_RDMA, 3 },
+   [OVL_ADAPTOR_MDP_RDMA4] = { OVL_ADAPTOR_TYPE_RDMA, 4 },
+   [OVL_ADAPTOR_MDP_RDMA5] = { OVL_ADAPTOR_TYPE_RDMA, 5 },
+   [OVL_ADAPTOR_MDP_RDMA6] = { OVL_ADAPTOR_TYPE_RDMA, 6 },
+   [OVL_ADAPTOR_MDP_RDMA7] = { OVL_ADAPTO

[PATCH v9 22/22] arm64: dts: mt8195: add display node for vdosys1

2021-11-29 Thread Nancy . Lin
Add display node for vdosys1.

Signed-off-by: Nancy.Lin 
---
 arch/arm64/boot/dts/mediatek/mt8195.dtsi | 222 +++
 1 file changed, 222 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi 
b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
index e136761345db..a69a7b57e070 100644
--- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
@@ -10,6 +10,7 @@
 #include 
 #include 
 #include 
+#include 
 
 / {
compatible = "mediatek,mt8195";
@@ -20,6 +21,22 @@
aliases {
gce0 = &gce0;
gce1 = &gce1;
+   ethdr0 = ðdr0;
+   mutex0 = &mutex;
+   mutex1 = &mutex1;
+   merge1 = &merge1;
+   merge2 = &merge2;
+   merge3 = &merge3;
+   merge4 = &merge4;
+   merge5 = &merge5;
+   vdo1_rdma0 = &vdo1_rdma0;
+   vdo1_rdma1 = &vdo1_rdma1;
+   vdo1_rdma2 = &vdo1_rdma2;
+   vdo1_rdma3 = &vdo1_rdma3;
+   vdo1_rdma4 = &vdo1_rdma4;
+   vdo1_rdma5 = &vdo1_rdma5;
+   vdo1_rdma6 = &vdo1_rdma6;
+   vdo1_rdma7 = &vdo1_rdma7;
};
 
clocks {
@@ -1235,7 +1252,212 @@
vdosys1: syscon@1c10 {
compatible = "mediatek,mt8195-vdosys1", "syscon";
reg = <0 0x1c10 0 0x1000>;
+   mboxes = <&gce0 1 CMDQ_THR_PRIO_4>;
+   mediatek,gce-client-reg = <&gce0 SUBSYS_1c10 0x 
0x1000>;
#clock-cells = <1>;
+   #reset-cells = <1>;
+   };
+
+   mutex1: disp_mutex0@1c101000 {
+   compatible = "mediatek,mt8195-disp-mutex";
+   reg = <0 0x1c101000 0 0x1000>;
+   reg-names = "vdo1_mutex";
+   interrupts = ;
+   power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+   clocks = <&vdosys1 CLK_VDO1_DISP_MUTEX>;
+   clock-names = "vdo1_mutex";
+   mediatek,gce-events = 
;
+   };
+
+   vdo1_rdma0: vdo1_rdma@1c104000 {
+   compatible = "mediatek,mt8195-vdo1-rdma";
+   reg = <0 0x1c104000 0 0x1000>;
+   interrupts = ;
+   clocks = <&vdosys1 CLK_VDO1_MDP_RDMA0>;
+   power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+   iommus = <&iommu_vdo M4U_PORT_L2_MDP_RDMA0>;
+   mediatek,gce-client-reg = <&gce0 SUBSYS_1c10 0x4000 
0x1000>;
+   };
+
+   vdo1_rdma1: vdo1_rdma@1c105000 {
+   compatible = "mediatek,mt8195-vdo1-rdma";
+   reg = <0 0x1c105000 0 0x1000>;
+   interrupts = ;
+   clocks = <&vdosys1 CLK_VDO1_MDP_RDMA1>;
+   power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+   iommus = <&iommu_vpp M4U_PORT_L3_MDP_RDMA1>;
+   mediatek,gce-client-reg = <&gce0 SUBSYS_1c10 0x5000 
0x1000>;
+   };
+
+   vdo1_rdma2: vdo1_rdma@1c106000 {
+   compatible = "mediatek,mt8195-vdo1-rdma";
+   reg = <0 0x1c106000 0 0x1000>;
+   interrupts = ;
+   clocks = <&vdosys1 CLK_VDO1_MDP_RDMA2>;
+   power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+   iommus = <&iommu_vdo M4U_PORT_L2_MDP_RDMA2>;
+   mediatek,gce-client-reg = <&gce0 SUBSYS_1c10 0x6000 
0x1000>;
+   };
+
+   vdo1_rdma3: vdo1_rdma@1c107000 {
+   compatible = "mediatek,mt8195-vdo1-rdma";
+   reg = <0 0x1c107000 0 0x1000>;
+   interrupts = ;
+   clocks = <&vdosys1 CLK_VDO1_MDP_RDMA3>;
+   power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+   iommus = <&iommu_vpp M4U_PORT_L3_MDP_RDMA3>;
+   mediatek,gce-client-reg = <&gce0 SUBSYS_1c10 0x7000 
0x1000>;
+   };
+
+   vdo1_rdma4: vdo1_rdma@1c108000 {
+   compatible = "mediatek,mt8195-vdo1-rdma";
+   reg = <0 0x1c108000 0 0x1000>;
+   interrupts = ;
+   clocks = <&vdosys1 CLK_VDO1_MDP_RDMA4>;
+   power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+   iommus = <&iommu_vdo M4U_PORT_L2_MDP_RDMA4>;
+   mediatek,gce-client-reg = <&gce0 SUBSYS_1c10 0x8000 
0x1000>;
+   };
+
+   vdo1_rdma5: vdo1_rdma@1c109000 {
+   compatible = "mediatek,mt8195-vdo1-rdma";
+ 

[PATCH v9 03/22] dt-bindings: mediatek: add ethdr definition for mt8195

2021-11-29 Thread Nancy . Lin
Add vdosys1 ETHDR definition.

Signed-off-by: Nancy.Lin 
Reviewed-by: Chun-Kuang Hu 
---
 .../display/mediatek/mediatek,ethdr.yaml  | 147 ++
 1 file changed, 147 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/display/mediatek/mediatek,ethdr.yaml

diff --git 
a/Documentation/devicetree/bindings/display/mediatek/mediatek,ethdr.yaml 
b/Documentation/devicetree/bindings/display/mediatek/mediatek,ethdr.yaml
new file mode 100644
index ..131eed5eeeb7
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ethdr.yaml
@@ -0,0 +1,147 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,ethdr.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Ethdr Device Tree Bindings
+
+maintainers:
+  - Chun-Kuang Hu 
+  - Philipp Zabel 
+
+description: |
+  ETHDR is designed for HDR video and graphics conversion in the external 
display path.
+  It handles multiple HDR input types and performs tone mapping, color 
space/color
+  format conversion, and then combine different layers, output the required 
HDR or
+  SDR signal to the subsequent display path. This engine is composed of two 
video
+  frontends, two graphic frontends, one video backend and a mixer. ETHDR has 
two
+  DMA function blocks, DS and ADL. These two function blocks read the 
pre-programmed
+  registers from DRAM and set them to HW in the v-blanking period.
+
+properties:
+  compatible:
+items:
+  - const: mediatek,mt8195-disp-ethdr
+  reg:
+maxItems: 7
+  reg-names:
+items:
+  - const: mixer
+  - const: vdo_fe0
+  - const: vdo_fe1
+  - const: gfx_fe0
+  - const: gfx_fe1
+  - const: vdo_be
+  - const: adl_ds
+  interrupts:
+minItems: 1
+  iommus:
+description: The compatible property is DMA function blocks.
+  Should point to the respective IOMMU block with master port as argument,
+  see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml for
+  details.
+minItems: 1
+maxItems: 2
+  clocks:
+items:
+  - description: mixer clock
+  - description: video frontend 0 clock
+  - description: video frontend 1 clock
+  - description: graphic frontend 0 clock
+  - description: graphic frontend 1 clock
+  - description: video backend clock
+  - description: autodownload and menuload clock
+  - description: video frontend 0 async clock
+  - description: video frontend 1 async clock
+  - description: graphic frontend 0 async clock
+  - description: graphic frontend 1 async clock
+  - description: video backend async clock
+  - description: ethdr top clock
+  clock-names:
+items:
+  - const: mixer
+  - const: vdo_fe0
+  - const: vdo_fe1
+  - const: gfx_fe0
+  - const: gfx_fe1
+  - const: vdo_be
+  - const: adl_ds
+  - const: vdo_fe0_async
+  - const: vdo_fe1_async
+  - const: gfx_fe0_async
+  - const: gfx_fe1_async
+  - const: vdo_be_async
+  - const: ethdr_top
+  power-domains:
+maxItems: 1
+  resets:
+maxItems: 5
+  mediatek,gce-client-reg:
+$ref: /schemas/types.yaml#/definitions/phandle-array
+description: The register of display function block to be set by gce.
+  There are 4 arguments in this property, gce node, subsys id, offset and
+  register size. The subsys id is defined in the gce header of each chips
+  include/include/dt-bindings/gce/-gce.h, mapping to the register of
+  display function block.
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - interrupts
+  - power-domains
+
+additionalProperties: false
+
+examples:
+  - |
+
+disp_ethdr@1c114000 {
+compatible = "mediatek,mt8195-disp-ethdr";
+reg = <0 0x1c114000 0 0x1000>,
+  <0 0x1c115000 0 0x1000>,
+  <0 0x1c117000 0 0x1000>,
+  <0 0x1c119000 0 0x1000>,
+  <0 0x1c11A000 0 0x1000>,
+  <0 0x1c11B000 0 0x1000>,
+  <0 0x1c11C000 0 0x1000>;
+reg-names = "mixer", "vdo_fe0", "vdo_fe1", "gfx_fe0", "gfx_fe1",
+"vdo_be", "adl_ds";
+mediatek,gce-client-reg = <&gce0 SUBSYS_1c11 0x4000 0x1000>,
+  <&gce0 SUBSYS_1c11 0x5000 0x1000>,
+  <&gce0 SUBSYS_1c11 0x7000 0x1000>,
+  <&gce0 SUBSYS_1c11 0x9000 0x1000>,
+  <&gce0 SUBSYS_1c11 0xA000 0x1000>,
+  <&gce0 SUBSYS_1c11 0xB000 0x1000>,
+  <&gce0 SUBSYS_1c11 0xC000 0x1000>;
+clocks = <&vdosys1 CLK_VDO1_DISP_MIXER>,
+ <&vdosys1 CLK_VDO1_HDR_VDO_FE0>,
+ <&vdosys1 CLK_VDO1_HDR_VDO_FE1>,
+  

[PATCH v9 20/22] drm/mediatek: add drm ovl_adaptor sub driver for MT8195

2021-11-29 Thread Nancy . Lin
Add drm ovl_adaptor sub driver. Bring up ovl_adaptor sub driver if
the component exists in the path.

Signed-off-by: Nancy.Lin 
---
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 16 
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 30 ---
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |  1 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c  | 41 +++--
 4 files changed, 62 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c 
b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index fe2871aca859..62529a954b62 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -877,15 +877,13 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
node = priv->comp_node[comp_id];
comp = &priv->ddp_comp[comp_id];
 
-   if (!node) {
-   dev_info(dev,
-"Not creating crtc %d because component %d is 
disabled or missing\n",
-crtc_i, comp_id);
-   return 0;
-   }
-
-   if (!comp->dev) {
-   dev_err(dev, "Component %pOF not initialized\n", node);
+   /* Not all drm components have a DTS device node, such as 
ovl_adaptor,
+* which is the drm bring up sub driver
+*/
+   if (!node && !comp->dev) {
+   dev_err(dev,
+   "Not creating crtc %d because component %d is 
disabled, missing or not initialized\n",
+   crtc_i, comp_id);
return -ENODEV;
}
}
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c 
b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index 26d197da41c0..ce40bab9c56b 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -385,6 +385,18 @@ static const struct mtk_ddp_comp_funcs ddp_ufoe = {
.start = mtk_ufoe_start,
 };
 
+static const struct mtk_ddp_comp_funcs ddp_ovl_adaptor = {
+   .clk_enable = mtk_ovl_adaptor_clk_enable,
+   .clk_disable = mtk_ovl_adaptor_clk_disable,
+   .config = mtk_ovl_adaptor_config,
+   .start = mtk_ovl_adaptor_start,
+   .stop = mtk_ovl_adaptor_stop,
+   .layer_nr = mtk_ovl_adaptor_layer_nr,
+   .layer_config = mtk_ovl_adaptor_layer_config,
+   .enable_vblank = mtk_ovl_adaptor_enable_vblank,
+   .disable_vblank = mtk_ovl_adaptor_disable_vblank,
+};
+
 static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
[MTK_DISP_AAL] = "aal",
[MTK_DISP_BLS] = "bls",
@@ -398,6 +410,7 @@ static const char * const 
mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
[MTK_DISP_OD] = "od",
[MTK_DISP_OVL] = "ovl",
[MTK_DISP_OVL_2L] = "ovl-2l",
+   [MTK_DISP_OVL_ADAPTOR] = "ovl_adaptor",
[MTK_DISP_POSTMASK] = "postmask",
[MTK_DISP_PWM] = "pwm",
[MTK_DISP_RDMA] = "rdma",
@@ -443,6 +456,7 @@ static const struct mtk_ddp_comp_match 
mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = {
[DDP_COMPONENT_OVL_2L0] = { MTK_DISP_OVL_2L,0, &ddp_ovl },
[DDP_COMPONENT_OVL_2L1] = { MTK_DISP_OVL_2L,1, &ddp_ovl },
[DDP_COMPONENT_OVL_2L2] = { MTK_DISP_OVL_2L,2, &ddp_ovl },
+   [DDP_COMPONENT_OVL_ADAPTOR] = { MTK_DISP_OVL_ADAPTOR,   0, 
&ddp_ovl_adaptor },
[DDP_COMPONENT_POSTMASK0]   = { MTK_DISP_POSTMASK,  0, 
&ddp_postmask },
[DDP_COMPONENT_PWM0]= { MTK_DISP_PWM,   0, NULL },
[DDP_COMPONENT_PWM1]= { MTK_DISP_PWM,   1, NULL },
@@ -548,12 +562,17 @@ int mtk_ddp_comp_init(struct device_node *node, struct 
mtk_ddp_comp *comp,
 
comp->id = comp_id;
comp->funcs = mtk_ddp_matches[comp_id].funcs;
-   comp_pdev = of_find_device_by_node(node);
-   if (!comp_pdev) {
-   DRM_INFO("Waiting for device %s\n", node->full_name);
-   return -EPROBE_DEFER;
+   /* Not all drm components have a DTS device node, such as ovl_adaptor,
+* which is the drm bring up sub driver
+*/
+   if (node) {
+   comp_pdev = of_find_device_by_node(node);
+   if (!comp_pdev) {
+   DRM_INFO("Waiting for device %s\n", node->full_name);
+   return -EPROBE_DEFER;
+   }
+   comp->dev = &comp_pdev->dev;
}
-   comp->dev = &comp_pdev->dev;
 
/* Only DMA capable components need the LARB property */
if (type == MTK_DISP_OVL ||
@@ -573,6 +592,7 @@ int mtk_ddp_comp_init(struct device_node *node, struct 
mtk_ddp_comp *comp,
type == MTK_DISP_MERGE ||
type == MTK_DISP_OVL ||
type == MTK_DISP_OVL_2L ||
+   type == MTK_DISP_OVL_ADAPTOR ||
type == MTK_DISP_PWM ||
type == MTK_DISP_RDMA ||

[PATCH v9 14/22] drm/mediatek: add display merge mute/unmute support for MT8195

2021-11-29 Thread Nancy . Lin
Add merge mute/unmute setting for MT8195.
MT8195 Vdosys1 merge1~merge4 support HW mute function.

Signed-off-by: Nancy.Lin 
Reviewed-by: Chun-Kuang Hu 
---
 drivers/gpu/drm/mediatek/mtk_disp_merge.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_merge.c 
b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
index c0d9b43b2a66..9dca145cfb71 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_merge.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
@@ -58,12 +58,15 @@
 #define FLD_PREULTRA_TH_LOWGENMASK(15, 0)
 #define FLD_PREULTRA_TH_HIGH   GENMASK(31, 16)
 
+#define DISP_REG_MERGE_MUTE_0  0xf00
+
 struct mtk_disp_merge {
void __iomem*regs;
struct clk  *clk;
struct clk  *async_clk;
struct cmdq_client_reg  cmdq_reg;
boolfifo_en;
+   boolmute_support;
 };
 
 void mtk_merge_start(struct device *dev)
@@ -82,6 +85,10 @@ void mtk_merge_start_cmdq(struct device *dev, struct 
cmdq_pkt *cmdq_pkt)
 {
struct mtk_disp_merge *priv = dev_get_drvdata(dev);
 
+   if (priv->mute_support)
+   mtk_ddp_write(cmdq_pkt, 0x0, &priv->cmdq_reg, priv->regs,
+ DISP_REG_MERGE_MUTE_0);
+
mtk_ddp_write(cmdq_pkt, 1, &priv->cmdq_reg, priv->regs,
  DISP_REG_MERGE_CTRL);
 }
@@ -90,6 +97,10 @@ void mtk_merge_stop_cmdq(struct device *dev, struct cmdq_pkt 
*cmdq_pkt)
 {
struct mtk_disp_merge *priv = dev_get_drvdata(dev);
 
+   if (priv->mute_support)
+   mtk_ddp_write(cmdq_pkt, 0x1, &priv->cmdq_reg, priv->regs,
+ DISP_REG_MERGE_MUTE_0);
+
mtk_ddp_write(cmdq_pkt, 0, &priv->cmdq_reg, priv->regs,
  DISP_REG_MERGE_CTRL);
 }
@@ -264,6 +275,8 @@ static int mtk_disp_merge_probe(struct platform_device 
*pdev)
priv->fifo_en = of_property_read_bool(dev->of_node,
  "mediatek,merge-fifo-en");
 
+   priv->mute_support = of_property_read_bool(dev->of_node,
+  "mediatek,merge-mute");
platform_set_drvdata(pdev, priv);
 
ret = component_add(dev, &mtk_disp_merge_component_ops);
-- 
2.18.0



[PATCH v9 21/22] drm/mediatek: add mediatek-drm of vdosys1 support for MT8195

2021-11-29 Thread Nancy . Lin
Add driver data of mt8195 vdosys1 to mediatek-drm.

Signed-off-by: Nancy.Lin 
---
 drivers/gpu/drm/mediatek/mtk_drm_drv.c | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c 
b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index 36430f956b4f..e851c56f00b1 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -190,6 +190,14 @@ static const enum mtk_ddp_comp_id mt8195_mtk_ddp_main[] = {
DDP_COMPONENT_DP_INTF0,
 };
 
+static const enum mtk_ddp_comp_id mt8195_mtk_ddp_ext[] = {
+   DDP_COMPONENT_OVL_ADAPTOR,
+   DDP_COMPONENT_MERGE5,
+   DDP_COMPONENT_DP_INTF1,
+};
+
+static const int mt8195_vdosys1_mtk_cmdq_mbox[] = {-1, 0, -1};
+
 static const struct mtk_mmsys_driver_data mt2701_mmsys_driver_data = {
.main_path = mt2701_mtk_ddp_main,
.main_len = ARRAY_SIZE(mt2701_mtk_ddp_main),
@@ -254,6 +262,14 @@ static const struct mtk_mmsys_driver_data 
mt8195_vdosys0_driver_data = {
.mmsys_dev_num = 2,
 };
 
+static const struct mtk_mmsys_driver_data mt8195_vdosys1_driver_data = {
+   .ext_path = mt8195_mtk_ddp_ext,
+   .ext_len = ARRAY_SIZE(mt8195_mtk_ddp_ext),
+   .mmsys_id = 1,
+   .mmsys_dev_num = 2,
+   .mbox_index = mt8195_vdosys1_mtk_cmdq_mbox,
+};
+
 static const struct of_device_id mtk_drm_of_ids[] = {
{ .compatible = "mediatek,mt2701-mmsys",
  .data = &mt2701_mmsys_driver_data},
@@ -271,6 +287,8 @@ static const struct of_device_id mtk_drm_of_ids[] = {
  .data = &mt8192_mmsys_driver_data},
{ .compatible = "mediatek,mt8195-vdosys0",
  .data = &mt8195_vdosys0_driver_data},
+   { .compatible = "mediatek,mt8195-vdosys1",
+ .data = &mt8195_vdosys1_driver_data},
{ }
 };
 MODULE_DEVICE_TABLE(of, mtk_drm_of_ids);
-- 
2.18.0



[PATCH v9 01/22] dt-bindings: mediatek: add vdosys1 RDMA definition for mt8195

2021-11-29 Thread Nancy . Lin
Add vdosys1 RDMA definition.

Signed-off-by: Nancy.Lin 
---
 .../arm/mediatek/mediatek,mdp-rdma.yaml   | 77 +++
 1 file changed, 77 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/arm/mediatek/mediatek,mdp-rdma.yaml

diff --git 
a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mdp-rdma.yaml 
b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mdp-rdma.yaml
new file mode 100644
index ..d70b81ec1914
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mdp-rdma.yaml
@@ -0,0 +1,77 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/arm/mediatek/mediatek,mdp-rdma.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek MDP RDMA
+
+maintainers:
+  - Matthias Brugger 
+
+description: |
+  The mediatek MDP RDMA stands for Read Direct Memory Access.
+  It provides real time data to the back-end panel driver, such as DSI,
+  DPI and DP_INTF.
+  It contains one line buffer to store the sufficient pixel data.
+  RDMA device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml for 
details.
+
+properties:
+  compatible:
+oneOf:
+  - items:
+  - const: mediatek,mt8195-vdo1-rdma
+
+  reg:
+maxItems: 1
+
+  interrupts:
+maxItems: 1
+
+  power-domains:
+description: A phandle and PM domain specifier as defined by bindings of
+  the power controller specified by phandle. See
+  Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+items:
+  - description: RDMA Clock
+
+  iommus:
+description:
+  This property should point to the respective IOMMU block with master 
port as argument,
+  see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml for 
details.
+
+  mediatek,gce-client-reg:
+description:
+  The register of display function block to be set by gce. There are 4 
arguments,
+  such as gce node, subsys id, offset and register size. The subsys id 
that is
+  mapping to the register of display function blocks is defined in the gce 
header
+  include/include/dt-bindings/gce/-gce.h of each chips.
+$ref: /schemas/types.yaml#/definitions/phandle-array
+maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - power-domains
+  - clocks
+  - iommus
+
+additionalProperties: false
+
+examples:
+  - |
+
+vdo1_rdma0: vdo1_rdma@1c104000 {
+compatible = "mediatek,mt8195-vdo1-rdma";
+reg = <0 0x1c104000 0 0x1000>;
+interrupts = ;
+clocks = <&vdosys1 CLK_VDO1_MDP_RDMA0>;
+power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+iommus = <&iommu_vdo M4U_PORT_L2_MDP_RDMA0>;
+mediatek,gce-client-reg = <&gce0 SUBSYS_1c10 0x4000 0x1000>;
+};
+
-- 
2.18.0



[PATCH v9 11/22] drm/mediatek: add display MDP RDMA support for MT8195

2021-11-29 Thread Nancy . Lin
Add MDP_RDMA driver for MT8195. MDP_RDMA is the DMA engine of
the ovl_adaptor component.

Signed-off-by: Nancy.Lin 
Reviewed-by: Chun-Kuang Hu 
---
 drivers/gpu/drm/mediatek/Makefile   |   3 +-
 drivers/gpu/drm/mediatek/mtk_disp_drv.h |   7 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c  |   1 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.h  |   1 +
 drivers/gpu/drm/mediatek/mtk_mdp_rdma.c | 315 
 drivers/gpu/drm/mediatek/mtk_mdp_rdma.h |  20 ++
 6 files changed, 346 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/mediatek/mtk_mdp_rdma.c
 create mode 100644 drivers/gpu/drm/mediatek/mtk_mdp_rdma.h

diff --git a/drivers/gpu/drm/mediatek/Makefile 
b/drivers/gpu/drm/mediatek/Makefile
index a38e88e82d12..6e604a933ed0 100644
--- a/drivers/gpu/drm/mediatek/Makefile
+++ b/drivers/gpu/drm/mediatek/Makefile
@@ -13,7 +13,8 @@ mediatek-drm-y := mtk_disp_aal.o \
  mtk_drm_gem.o \
  mtk_drm_plane.o \
  mtk_dsi.o \
- mtk_dpi.o
+ mtk_dpi.o \
+ mtk_mdp_rdma.o
 
 obj-$(CONFIG_DRM_MEDIATEK) += mediatek-drm.o
 
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h 
b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
index a33b13fe2b6e..b3a372cab0bd 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
@@ -8,6 +8,7 @@
 
 #include 
 #include "mtk_drm_plane.h"
+#include "mtk_mdp_rdma.h"
 
 int mtk_aal_clk_enable(struct device *dev);
 void mtk_aal_clk_disable(struct device *dev);
@@ -106,4 +107,10 @@ void mtk_rdma_enable_vblank(struct device *dev,
void *vblank_cb_data);
 void mtk_rdma_disable_vblank(struct device *dev);
 
+int mtk_mdp_rdma_clk_enable(struct device *dev);
+void mtk_mdp_rdma_clk_disable(struct device *dev);
+void mtk_mdp_rdma_start(struct device *dev, struct cmdq_pkt *cmdq_pkt);
+void mtk_mdp_rdma_stop(struct device *dev, struct cmdq_pkt *cmdq_pkt);
+void mtk_mdp_rdma_config(struct device *dev, struct mtk_mdp_rdma_cfg *cfg,
+struct cmdq_pkt *cmdq_pkt);
 #endif
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c 
b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index 274a5bb10851..fa41306422df 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -743,6 +743,7 @@ static struct platform_driver * const mtk_drm_drivers[] = {
&mtk_dpi_driver,
&mtk_drm_platform_driver,
&mtk_dsi_driver,
+   &mtk_mdp_rdma_driver,
 };
 
 static int __init mtk_drm_init(void)
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h 
b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
index a58cebd01d35..64a1f66df26a 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
@@ -55,5 +55,6 @@ extern struct platform_driver mtk_disp_ovl_driver;
 extern struct platform_driver mtk_disp_rdma_driver;
 extern struct platform_driver mtk_dpi_driver;
 extern struct platform_driver mtk_dsi_driver;
+extern struct platform_driver mtk_mdp_rdma_driver;
 
 #endif /* MTK_DRM_DRV_H */
diff --git a/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c 
b/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c
new file mode 100644
index ..eecfa98ff52e
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c
@@ -0,0 +1,315 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "mtk_disp_drv.h"
+#include "mtk_drm_drv.h"
+#include "mtk_mdp_rdma.h"
+
+#define MDP_RDMA_EN0x000
+#define FLD_ROT_ENABLE BIT(0)
+#define MDP_RDMA_RESET 0x008
+#define MDP_RDMA_CON   0x020
+#define FLD_OUTPUT_10B BIT(5)
+#define FLD_SIMPLE_MODEBIT(4)
+#define MDP_RDMA_GMCIF_CON 0x028
+#define FLD_COMMAND_DIVBIT(0)
+#define FLD_EXT_PREULTRA_ENBIT(3)
+#define FLD_RD_REQ_TYPEGENMASK(7, 4)
+#define VAL_RD_REQ_TYPE_BURST_8_ACCESS 7
+#define FLD_ULTRA_EN   GENMASK(13, 12)
+#define VAL_ULTRA_EN_ENABLE1
+#define FLD_PRE_ULTRA_EN   GENMASK(17, 16)
+#define VAL_PRE_ULTRA_EN_ENABLE1
+#define FLD_EXT_ULTRA_EN   BIT(18)
+#define MDP_RDMA_SRC_CON   0x030
+#define FLD_OUTPUT_ARGBBIT(25)
+#define FLD_BIT_NUMBER GENMASK(19, 18)
+#define FLD_SWAP   BIT(14)
+#define FLD_UNIFORM_CONFIG BIT(17)
+#define RDMA_INPUT_10BIT   BIT(18)
+#define FLD_SRC_FORMAT GENMASK(3, 0)
+#define MDP_RDMA_COMP_CON  0x038
+#define FLD_AFBC_ENBIT(22)
+#define FLD_AFBC_YUV_TRANSFORM 

[PATCH v9 13/22] drm/mediatek: add display merge start/stop API for cmdq support

2021-11-29 Thread Nancy . Lin
Add merge start/stop API for cmdq support. The ovl_adaptor merges
are configured with each drm plane update. Need to enable/disable
merge with cmdq making sure all the settings taken effect in the
same vblank.

Signed-off-by: Nancy.Lin 
Reviewed-by: Chun-Kuang Hu 
---
 drivers/gpu/drm/mediatek/mtk_disp_drv.h   |  2 ++
 drivers/gpu/drm/mediatek/mtk_disp_merge.c | 20 +---
 2 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h 
b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
index c2de53a5892e..224a710bb537 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
@@ -66,6 +66,8 @@ void mtk_merge_stop(struct device *dev);
 void mtk_merge_advance_config(struct device *dev, unsigned int l_w, unsigned 
int r_w,
  unsigned int h, unsigned int vrefresh, unsigned 
int bpc,
  struct cmdq_pkt *cmdq_pkt);
+void mtk_merge_start_cmdq(struct device *dev, struct cmdq_pkt *cmdq_pkt);
+void mtk_merge_stop_cmdq(struct device *dev, struct cmdq_pkt *cmdq_pkt);
 
 void mtk_ovl_bgclr_in_on(struct device *dev);
 void mtk_ovl_bgclr_in_off(struct device *dev);
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_merge.c 
b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
index 40da0555416d..c0d9b43b2a66 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_merge.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
@@ -67,17 +67,31 @@ struct mtk_disp_merge {
 };
 
 void mtk_merge_start(struct device *dev)
+{
+   mtk_merge_start_cmdq(dev, NULL);
+}
+
+void mtk_merge_stop(struct device *dev)
 {
struct mtk_disp_merge *priv = dev_get_drvdata(dev);
 
-   writel(MERGE_EN, priv->regs + DISP_REG_MERGE_CTRL);
+   mtk_merge_stop_cmdq(dev, NULL);
 }
 
-void mtk_merge_stop(struct device *dev)
+void mtk_merge_start_cmdq(struct device *dev, struct cmdq_pkt *cmdq_pkt)
+{
+   struct mtk_disp_merge *priv = dev_get_drvdata(dev);
+
+   mtk_ddp_write(cmdq_pkt, 1, &priv->cmdq_reg, priv->regs,
+ DISP_REG_MERGE_CTRL);
+}
+
+void mtk_merge_stop_cmdq(struct device *dev, struct cmdq_pkt *cmdq_pkt)
 {
struct mtk_disp_merge *priv = dev_get_drvdata(dev);
 
-   writel(0x0, priv->regs + DISP_REG_MERGE_CTRL);
+   mtk_ddp_write(cmdq_pkt, 0, &priv->cmdq_reg, priv->regs,
+ DISP_REG_MERGE_CTRL);
 }
 
 static void mtk_merge_fifo_setting(struct mtk_disp_merge *priv,
-- 
2.18.0



[PATCH v9 16/22] drm/mediatek: add ETHDR support for MT8195

2021-11-29 Thread Nancy . Lin
ETHDR is a part of ovl_adaptor.
ETHDR is designed for HDR video and graphics conversion in the external
display path. It handles multiple HDR input types and performs tone
mapping, color space/color format conversion, and then combine
different layers, output the required HDR or SDR signal to the
subsequent display path.

Signed-off-by: Nancy.Lin 
Reviewed-by: Chun-Kuang Hu 
---
 drivers/gpu/drm/mediatek/Makefile  |   1 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c |   1 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.h |   1 +
 drivers/gpu/drm/mediatek/mtk_ethdr.c   | 386 +
 drivers/gpu/drm/mediatek/mtk_ethdr.h   |  25 ++
 5 files changed, 414 insertions(+)
 create mode 100644 drivers/gpu/drm/mediatek/mtk_ethdr.c
 create mode 100644 drivers/gpu/drm/mediatek/mtk_ethdr.h

diff --git a/drivers/gpu/drm/mediatek/Makefile 
b/drivers/gpu/drm/mediatek/Makefile
index 6e604a933ed0..fb158a1e7f06 100644
--- a/drivers/gpu/drm/mediatek/Makefile
+++ b/drivers/gpu/drm/mediatek/Makefile
@@ -14,6 +14,7 @@ mediatek-drm-y := mtk_disp_aal.o \
  mtk_drm_plane.o \
  mtk_dsi.o \
  mtk_dpi.o \
+ mtk_ethdr.o \
  mtk_mdp_rdma.o
 
 obj-$(CONFIG_DRM_MEDIATEK) += mediatek-drm.o
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c 
b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index fa41306422df..390cda4bae57 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -743,6 +743,7 @@ static struct platform_driver * const mtk_drm_drivers[] = {
&mtk_dpi_driver,
&mtk_drm_platform_driver,
&mtk_dsi_driver,
+   &mtk_ethdr_driver,
&mtk_mdp_rdma_driver,
 };
 
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h 
b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
index 64a1f66df26a..3fb85776b8b3 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
@@ -55,6 +55,7 @@ extern struct platform_driver mtk_disp_ovl_driver;
 extern struct platform_driver mtk_disp_rdma_driver;
 extern struct platform_driver mtk_dpi_driver;
 extern struct platform_driver mtk_dsi_driver;
+extern struct platform_driver mtk_ethdr_driver;
 extern struct platform_driver mtk_mdp_rdma_driver;
 
 #endif /* MTK_DRM_DRV_H */
diff --git a/drivers/gpu/drm/mediatek/mtk_ethdr.c 
b/drivers/gpu/drm/mediatek/mtk_ethdr.c
new file mode 100644
index ..489285cd32b3
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_ethdr.c
@@ -0,0 +1,386 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "mtk_drm_crtc.h"
+#include "mtk_drm_ddp_comp.h"
+#include "mtk_drm_drv.h"
+#include "mtk_ethdr.h"
+
+#define MIX_INTEN  0x4
+#define MIX_FME_CPL_INTEN  BIT(1)
+#define MIX_INTSTA 0x8
+#define MIX_EN 0xc
+#define MIX_RST0x14
+#define MIX_ROI_SIZE   0x18
+#define MIX_DATAPATH_CON   0x1c
+#define OUTPUT_NO_RND  BIT(3)
+#define SOURCE_RGB_SEL BIT(7)
+#define BACKGROUND_RELAY   (4 << 9)
+#define MIX_ROI_BGCLR  0x20
+#define BGCLR_BLACK0xff00
+#define MIX_SRC_CON0x24
+#define MIX_SRC_L0_EN  BIT(0)
+#define MIX_L_SRC_CON(n)   (0x28 + 0x18 * (n))
+#define NON_PREMULTI_SOURCE(2 << 12)
+#define MIX_L_SRC_SIZE(n)  (0x30 + 0x18 * (n))
+#define MIX_L_SRC_OFFSET(n)(0x34 + 0x18 * (n))
+#define MIX_FUNC_DCM0  0x120
+#define MIX_FUNC_DCM1  0x124
+#define MIX_FUNC_DCM_ENABLE0x
+
+#define HDR_VDO_FE_0804_HDR_DM_FE  0x804
+#define HDR_VDO_FE_0804_BYPASS_ALL 0xfd
+#define HDR_GFX_FE_0204_GFX_HDR_FE 0x204
+#define HDR_GFX_FE_0204_BYPASS_ALL 0xfd
+#define HDR_VDO_BE_0204_VDO_DM_BE  0x204
+#define HDR_VDO_BE_0204_BYPASS_ALL 0x7e
+
+#define MIXER_INX_MODE_BYPASS  0
+#define MIXER_INX_MODE_EVEN_EXTEND 1
+#define DEFAULT_9BIT_ALPHA 0x100
+#defineMIXER_ALPHA_AEN BIT(8)
+#defineMIXER_ALPHA 0xff
+#define ETHDR_CLK_NUM  13
+
+enum mtk_ethdr_comp_id {
+   ETHDR_MIXER,
+   ETHDR_VDO_FE0,
+   ETHDR_VDO_FE1,
+   ETHDR_GFX_FE0,
+   ETHDR_GFX_FE1,
+   ETHDR_VDO_BE,
+   ETHDR_ADL_DS,
+   ETHDR_ID_MAX
+};
+
+struct mtk_ethdr_comp {
+   struct device   *dev;
+   void __iomem*regs;
+   struct cmdq_client_reg  cmdq_base;
+};
+
+struct mtk_ethdr {
+   struct mtk_ethdr_comp   ethdr_comp[ETHDR_ID_MAX];
+   struct clk_bulk_data

[PATCH v9 06/22] soc: mediatek: add mtk-mmsys config API for mt8195 vdosys1

2021-11-29 Thread Nancy . Lin
Add mmsys config API. The config API is used for config mmsys reg.
Some mmsys regs need to be setting according to the HW engine binding
to the mmsys simultaneously.

Signed-off-by: Nancy.Lin 
---
 drivers/soc/mediatek/mt8195-mmsys.h| 62 ++
 drivers/soc/mediatek/mtk-mmsys.c   | 34 ++
 drivers/soc/mediatek/mtk-mmsys.h   | 10 +
 include/linux/soc/mediatek/mtk-mmsys.h | 16 +++
 4 files changed, 122 insertions(+)

diff --git a/drivers/soc/mediatek/mt8195-mmsys.h 
b/drivers/soc/mediatek/mt8195-mmsys.h
index 65da65754d6e..11ba79e3275e 100644
--- a/drivers/soc/mediatek/mt8195-mmsys.h
+++ b/drivers/soc/mediatek/mt8195-mmsys.h
@@ -229,6 +229,21 @@
 #define MT8195_VDO1_MIXER_SOUT_SEL_IN  0xf68
 #define MT8195_MIXER_SOUT_SEL_IN_FROM_DISP_MIXER   0
 
+#define MT8195_VDO1_MERGE0_ASYNC_CFG_WD0xe30
+#define MT8195_VDO1_MERGE1_ASYNC_CFG_WD0xe40
+#define MT8195_VDO1_MERGE2_ASYNC_CFG_WD0xe50
+#define MT8195_VDO1_MERGE3_ASYNC_CFG_WD0xe60
+#define MT8195_VDO1_HDRBE_ASYNC_CFG_WD 0xe70
+#define MT8195_VDO1_HDR_TOP_CFG0xd00
+#define MT8195_VDO1_MIXER_IN1_ALPHA0xd30
+#define MT8195_VDO1_MIXER_IN2_ALPHA0xd34
+#define MT8195_VDO1_MIXER_IN3_ALPHA0xd38
+#define MT8195_VDO1_MIXER_IN4_ALPHA0xd3c
+#define MT8195_VDO1_MIXER_IN1_PAD  0xd40
+#define MT8195_VDO1_MIXER_IN2_PAD  0xd44
+#define MT8195_VDO1_MIXER_IN3_PAD  0xd48
+#define MT8195_VDO1_MIXER_IN4_PAD  0xd4c
+
 static const struct mtk_mmsys_routes mmsys_mt8195_routing_table[] = {
{
DDP_COMPONENT_OVL0, DDP_COMPONENT_RDMA0,
@@ -353,4 +368,51 @@ static const struct mtk_mmsys_routes 
mmsys_mt8195_routing_table[] = {
}
 };
 
+/*
+ * mtk_mmsys_config table is used for config mmsys reg in runtime.
+ * MMSYS_CONFIG_MERGE_ASYNC_WIDTH: config merge async width
+ * MMSYS_CONFIG_MERGE_ASYNC_HEIGHT: config merge async height
+ * MMSYS_CONFIG_HDR_BE_ASYNC_WIDTH: config hdr_be async width
+ * MMSYS_CONFIG_HDR_BE_ASYNC_HEIGHT: config hdr_be async height
+ * MMSYS_CONFIG_MIXER_IN_ALPHA_ODD: config mixer odd channel 9bit alpha value
+ * MMSYS_CONFIG_MIXER_IN_ALPHA_EVEN: config mixer even channel 9bit alpha value
+ * MMSYS_CONFIG_MIXER_IN_CH_SWAP: config mixer input RGB channel swap
+ * MMSYS_CONFIG_HDR_ALPHA_SEL: config alpha source
+ * MMSYS_CONFIG_MIXER_IN_MODE: config mixer pad mode(bypass/even extend mode)
+ * MMSYS_CONFIG_MIXER_IN_BIWIDTH: config mixer pad width. formula: width / 2 - 
1
+ */
+static const struct mtk_mmsys_config mmsys_mt8195_config_table[] = {
+   { MMSYS_CONFIG_MERGE_ASYNC_WIDTH, 0, MT8195_VDO1_MERGE0_ASYNC_CFG_WD, 
GENMASK(13, 0), 0},
+   { MMSYS_CONFIG_MERGE_ASYNC_HEIGHT, 0, MT8195_VDO1_MERGE0_ASYNC_CFG_WD, 
GENMASK(29, 16), 16},
+   { MMSYS_CONFIG_MERGE_ASYNC_WIDTH, 1, MT8195_VDO1_MERGE1_ASYNC_CFG_WD, 
GENMASK(13, 0), 0},
+   { MMSYS_CONFIG_MERGE_ASYNC_HEIGHT, 1, MT8195_VDO1_MERGE1_ASYNC_CFG_WD, 
GENMASK(29, 16), 16},
+   { MMSYS_CONFIG_MERGE_ASYNC_WIDTH, 2, MT8195_VDO1_MERGE2_ASYNC_CFG_WD, 
GENMASK(13, 0), 0},
+   { MMSYS_CONFIG_MERGE_ASYNC_HEIGHT, 2, MT8195_VDO1_MERGE2_ASYNC_CFG_WD, 
GENMASK(29, 16), 16},
+   { MMSYS_CONFIG_MERGE_ASYNC_WIDTH, 3, MT8195_VDO1_MERGE3_ASYNC_CFG_WD, 
GENMASK(13, 0), 0},
+   { MMSYS_CONFIG_MERGE_ASYNC_HEIGHT, 3, MT8195_VDO1_MERGE3_ASYNC_CFG_WD, 
GENMASK(29, 16), 16},
+   { MMSYS_CONFIG_HDR_BE_ASYNC_WIDTH, 0, MT8195_VDO1_HDRBE_ASYNC_CFG_WD, 
GENMASK(13, 0), 0},
+   { MMSYS_CONFIG_HDR_BE_ASYNC_HEIGHT, 0, MT8195_VDO1_HDRBE_ASYNC_CFG_WD, 
GENMASK(29, 16), 16},
+   { MMSYS_CONFIG_MIXER_IN_ALPHA_ODD, 1, MT8195_VDO1_MIXER_IN1_ALPHA, 
GENMASK(8, 0), 0},
+   { MMSYS_CONFIG_MIXER_IN_ALPHA_EVEN, 1, MT8195_VDO1_MIXER_IN1_ALPHA, 
GENMASK(24, 16), 16},
+   { MMSYS_CONFIG_MIXER_IN_ALPHA_ODD, 2, MT8195_VDO1_MIXER_IN2_ALPHA, 
GENMASK(8, 0), 0},
+   { MMSYS_CONFIG_MIXER_IN_ALPHA_EVEN, 2, MT8195_VDO1_MIXER_IN2_ALPHA, 
GENMASK(24, 16), 16},
+   { MMSYS_CONFIG_MIXER_IN_ALPHA_ODD, 3, MT8195_VDO1_MIXER_IN3_ALPHA, 
GENMASK(8, 0), 0},
+   { MMSYS_CONFIG_MIXER_IN_ALPHA_EVEN, 3, MT8195_VDO1_MIXER_IN3_ALPHA, 
GENMASK(24, 16), 16},
+   { MMSYS_CONFIG_MIXER_IN_ALPHA_ODD, 4, MT8195_VDO1_MIXER_IN4_ALPHA, 
GENMASK(8, 0), 0},
+   { MMSYS_CONFIG_MIXER_IN_ALPHA_EVEN, 4, MT8195_VDO1_MIXER_IN4_ALPHA, 
GENMASK(24, 16), 16},
+   { MMSYS_CONFIG_MIXER_IN_CH_SWAP, 4, MT8195_VDO1_MIXER_IN4_PAD, 
GENMASK(4, 4), 4},
+   { MMSYS_CONFIG_HDR_ALPHA_SEL, 1, MT8195_VDO1_HDR_TOP_CFG, GENMASK(20, 
20), 20},
+   { MMSYS_CONFIG_HDR_ALPHA_SEL, 2, MT8195_VDO1_HDR_TOP_CFG, GENMASK(21, 
21), 21},
+   { MMSYS_CONFIG_HDR_ALPHA_SEL, 3, MT8195_VDO1_HDR_TOP_CFG, GENMASK(22, 
22), 22},
+   { MMSYS_CONFIG_HDR_ALPHA_SEL, 4, MT8195_VDO1_HDR_TOP_CFG, GENMASK(23, 
23), 23},
+   { MMSYS_CONFIG_MIXER_IN_MODE, 1, MT8195_VDO1_MIXER_IN1_PAD, GENMASK(1, 
0), 0},
+   { MMSYS_CONFIG_MIXER_IN_MODE, 2, MT8195_VDO1_MIXER

[PATCH v9 10/22] soc: mediatek: add mtk-mutex support for mt8195 vdosys1

2021-11-29 Thread Nancy . Lin
Add mtk-mutex support for mt8195 vdosys1.
The vdosys1 path component contains ovl_adaptor, merge5,
and dp_intf1. Ovl_adaptor is composed of several sub-elements.

Signed-off-by: Nancy.Lin 
---
 drivers/soc/mediatek/mtk-mutex.c | 54 
 1 file changed, 54 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-mutex.c b/drivers/soc/mediatek/mtk-mutex.c
index ff2f74668e8a..7767fedbd14f 100644
--- a/drivers/soc/mediatek/mtk-mutex.c
+++ b/drivers/soc/mediatek/mtk-mutex.c
@@ -112,6 +112,35 @@
 #define MT8195_MUTEX_MOD_DISP_PWM0 BIT(27)
 #define MT8195_MUTEX_MOD_DISP_PWM1 BIT(28)
 
+#define MT8195_MUTEX_MOD_DISP1_MDP_RDMA0   BIT(0)
+#define MT8195_MUTEX_MOD_DISP1_MDP_RDMA1   BIT(1)
+#define MT8195_MUTEX_MOD_DISP1_MDP_RDMA2   BIT(2)
+#define MT8195_MUTEX_MOD_DISP1_MDP_RDMA3   BIT(3)
+#define MT8195_MUTEX_MOD_DISP1_MDP_RDMA4   BIT(4)
+#define MT8195_MUTEX_MOD_DISP1_MDP_RDMA5   BIT(5)
+#define MT8195_MUTEX_MOD_DISP1_MDP_RDMA6   BIT(6)
+#define MT8195_MUTEX_MOD_DISP1_MDP_RDMA7   BIT(7)
+#define MT8195_MUTEX_MOD_DISP1_VPP_MERGE0  BIT(8)
+#define MT8195_MUTEX_MOD_DISP1_VPP_MERGE1  BIT(9)
+#define MT8195_MUTEX_MOD_DISP1_VPP_MERGE2  BIT(10)
+#define MT8195_MUTEX_MOD_DISP1_VPP_MERGE3  BIT(11)
+#define MT8195_MUTEX_MOD_DISP1_VPP_MERGE4  BIT(12)
+#define MT8195_MUTEX_MOD_DISP1_VPP2_DL_RELAY   BIT(13)
+#define MT8195_MUTEX_MOD_DISP1_VPP3_DL_RELAY   BIT(14)
+#define MT8195_MUTEX_MOD_DISP1_VDO0_DSC_DL_ASYNC   BIT(15)
+#define MT8195_MUTEX_MOD_DISP1_VDO0_MERGE_DL_ASYNC BIT(16)
+#define MT8195_MUTEX_MOD_DISP1_VDO1_OUT_DL_RELAY   BIT(17)
+#define MT8195_MUTEX_MOD_DISP1_DISP_MIXER  BIT(18)
+#define MT8195_MUTEX_MOD_DISP1_HDR_VDO_FE0 BIT(19)
+#define MT8195_MUTEX_MOD_DISP1_HDR_VDO_FE1 BIT(20)
+#define MT8195_MUTEX_MOD_DISP1_HDR_GFX_FE0 BIT(21)
+#define MT8195_MUTEX_MOD_DISP1_HDR_GFX_FE1 BIT(22)
+#define MT8195_MUTEX_MOD_DISP1_HDR_VDO_BE0 BIT(23)
+#define MT8195_MUTEX_MOD_DISP1_HDR_MLOAD   BIT(24)
+#define MT8195_MUTEX_MOD_DISP1_DPI0BIT(25)
+#define MT8195_MUTEX_MOD_DISP1_DPI1BIT(26)
+#define MT8195_MUTEX_MOD_DISP1_DP_INTF0BIT(27)
+
 #define MT2712_MUTEX_MOD_DISP_PWM2 BIT(10)
 #define MT2712_MUTEX_MOD_DISP_OVL0 BIT(11)
 #define MT2712_MUTEX_MOD_DISP_OVL1 BIT(12)
@@ -302,6 +331,27 @@ static const unsigned long 
mt8195_mutex_mod[DDP_COMPONENT_ID_MAX] = {
[DDP_COMPONENT_DSI0] = MT8195_MUTEX_MOD_DISP_DSI0,
[DDP_COMPONENT_PWM0] = MT8195_MUTEX_MOD_DISP_PWM0,
[DDP_COMPONENT_DP_INTF0] = MT8195_MUTEX_MOD_DISP_DP_INTF0,
+   [DDP_COMPONENT_OVL_ADAPTOR] = MT8195_MUTEX_MOD_DISP1_MDP_RDMA0 |
+ MT8195_MUTEX_MOD_DISP1_MDP_RDMA1 |
+ MT8195_MUTEX_MOD_DISP1_MDP_RDMA2 |
+ MT8195_MUTEX_MOD_DISP1_MDP_RDMA3 |
+ MT8195_MUTEX_MOD_DISP1_MDP_RDMA4 |
+ MT8195_MUTEX_MOD_DISP1_MDP_RDMA5 |
+ MT8195_MUTEX_MOD_DISP1_MDP_RDMA6 |
+ MT8195_MUTEX_MOD_DISP1_MDP_RDMA7 |
+ MT8195_MUTEX_MOD_DISP1_VPP_MERGE0 |
+ MT8195_MUTEX_MOD_DISP1_VPP_MERGE1 |
+ MT8195_MUTEX_MOD_DISP1_VPP_MERGE2 |
+ MT8195_MUTEX_MOD_DISP1_VPP_MERGE3 |
+ MT8195_MUTEX_MOD_DISP1_HDR_VDO_FE0 |
+ MT8195_MUTEX_MOD_DISP1_HDR_VDO_FE1 |
+ MT8195_MUTEX_MOD_DISP1_HDR_GFX_FE0 |
+ MT8195_MUTEX_MOD_DISP1_HDR_GFX_FE1 |
+ MT8195_MUTEX_MOD_DISP1_HDR_VDO_BE0 |
+ MT8195_MUTEX_MOD_DISP1_HDR_MLOAD |
+ MT8195_MUTEX_MOD_DISP1_DISP_MIXER,
+   [DDP_COMPONENT_MERGE5] = MT8195_MUTEX_MOD_DISP1_VPP_MERGE4,
+   [DDP_COMPONENT_DP_INTF1] = MT8195_MUTEX_MOD_DISP1_DP_INTF0,
 };
 
 static const unsigned int mt2712_mutex_sof[DDP_MUTEX_SOF_MAX] = {
@@ -466,6 +516,9 @@ void mtk_mutex_add_comp(struct mtk_mutex *mutex,
case DDP_COMPONENT_DP_INTF0:
sof_id = MUTEX_SOF_DP_INTF0;
break;
+   case DDP_COMPONENT_DP_INTF1:
+   sof_id = MUTEX_SOF_DP_INTF1;
+   break;
default:
if (mtx->data->mutex_mod[id] <= BIT(31)) {
offset = DISP_REG_MUTEX_MOD(mtx->data->mutex_mod_reg,
@@ -506,6 +559,7 @@ void mtk_mutex_remove_comp(struct mtk_mutex *mutex,
case DDP_COMPONENT_DPI0:
case DDP_COMPONENT_DPI1:
case DDP_COMPONENT_DP_INTF0:
+   case DDP_COMPONENT_DP_INTF1:
writel_relaxed(MUTEX_SOF_SINGLE_MODE,
   

[PATCH v9 08/22] soc: mediatek: mmsys: modify reset controller for MT8195 vdosys1

2021-11-29 Thread Nancy . Lin
MT8195 vdosys1 has more than 32 reset bits and a different reset base
than other chips. Modify mmsys for support 64 bit and different reset
base.

Signed-off-by: Nancy.Lin 
---
 drivers/soc/mediatek/mt8195-mmsys.h |  1 +
 drivers/soc/mediatek/mtk-mmsys.c| 21 -
 drivers/soc/mediatek/mtk-mmsys.h|  2 ++
 3 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/drivers/soc/mediatek/mt8195-mmsys.h 
b/drivers/soc/mediatek/mt8195-mmsys.h
index 11ba79e3275e..628098260f61 100644
--- a/drivers/soc/mediatek/mt8195-mmsys.h
+++ b/drivers/soc/mediatek/mt8195-mmsys.h
@@ -229,6 +229,7 @@
 #define MT8195_VDO1_MIXER_SOUT_SEL_IN  0xf68
 #define MT8195_MIXER_SOUT_SEL_IN_FROM_DISP_MIXER   0
 
+#define MT8195_VDO1_SW0_RST_B  0x1d0
 #define MT8195_VDO1_MERGE0_ASYNC_CFG_WD0xe30
 #define MT8195_VDO1_MERGE1_ASYNC_CFG_WD0xe40
 #define MT8195_VDO1_MERGE2_ASYNC_CFG_WD0xe50
diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c
index 1b0024ee47a9..3f85171c980e 100644
--- a/drivers/soc/mediatek/mtk-mmsys.c
+++ b/drivers/soc/mediatek/mtk-mmsys.c
@@ -19,6 +19,8 @@
 #include "mt8195-mmsys.h"
 #include "mt8365-mmsys.h"
 
+#define MMSYS_SW_RESET_PER_REG 32
+
 static const struct mtk_mmsys_driver_data mt2701_mmsys_driver_data = {
.clk_driver = "clk-mt2701-mm",
.routes = mmsys_default_routing_table,
@@ -49,12 +51,16 @@ static const struct mtk_mmsys_driver_data 
mt8173_mmsys_driver_data = {
.clk_driver = "clk-mt8173-mm",
.routes = mmsys_default_routing_table,
.num_routes = ARRAY_SIZE(mmsys_default_routing_table),
+   .sw_reset_start = MMSYS_SW0_RST_B,
+   .num_resets = 32,
 };
 
 static const struct mtk_mmsys_driver_data mt8183_mmsys_driver_data = {
.clk_driver = "clk-mt8183-mm",
.routes = mmsys_mt8183_routing_table,
.num_routes = ARRAY_SIZE(mmsys_mt8183_routing_table),
+   .sw_reset_start = MMSYS_SW0_RST_B,
+   .num_resets = 32,
 };
 
 static const struct mtk_mmsys_driver_data mt8192_mmsys_driver_data = {
@@ -75,6 +81,8 @@ static const struct mtk_mmsys_driver_data 
mt8195_vdosys1_driver_data = {
.num_routes = ARRAY_SIZE(mmsys_mt8195_routing_table),
.config = mmsys_mt8195_config_table,
.num_configs = ARRAY_SIZE(mmsys_mt8195_config_table),
+   .sw_reset_start = MT8195_VDO1_SW0_RST_B,
+   .num_resets = 64,
 };
 
 static const struct mtk_mmsys_driver_data mt8365_mmsys_driver_data = {
@@ -133,18 +141,22 @@ static int mtk_mmsys_reset_update(struct 
reset_controller_dev *rcdev, unsigned l
 {
struct mtk_mmsys *mmsys = container_of(rcdev, struct mtk_mmsys, rcdev);
unsigned long flags;
+   u32 offset;
u32 reg;
 
+   offset = (id / MMSYS_SW_RESET_PER_REG) * sizeof(u32);
+   id = id % MMSYS_SW_RESET_PER_REG;
+
spin_lock_irqsave(&mmsys->lock, flags);
 
-   reg = readl_relaxed(mmsys->regs + MMSYS_SW0_RST_B);
+   reg = readl_relaxed(mmsys->regs + mmsys->data->sw_reset_start + offset);
 
if (assert)
reg &= ~BIT(id);
else
reg |= BIT(id);
 
-   writel_relaxed(reg, mmsys->regs + MMSYS_SW0_RST_B);
+   writel_relaxed(reg, mmsys->regs + mmsys->data->sw_reset_start + offset);
 
spin_unlock_irqrestore(&mmsys->lock, flags);
 
@@ -240,10 +252,11 @@ static int mtk_mmsys_probe(struct platform_device *pdev)
return ret;
}
 
+   mmsys->data = of_device_get_match_data(&pdev->dev);
spin_lock_init(&mmsys->lock);
 
mmsys->rcdev.owner = THIS_MODULE;
-   mmsys->rcdev.nr_resets = 32;
+   mmsys->rcdev.nr_resets = mmsys->data->num_resets;
mmsys->rcdev.ops = &mtk_mmsys_reset_ops;
mmsys->rcdev.of_node = pdev->dev.of_node;
ret = devm_reset_controller_register(&pdev->dev, &mmsys->rcdev);
@@ -252,8 +265,6 @@ static int mtk_mmsys_probe(struct platform_device *pdev)
return ret;
}
 
-   mmsys->data = of_device_get_match_data(&pdev->dev);
-
 #if IS_REACHABLE(CONFIG_MTK_CMDQ)
ret = cmdq_dev_get_client_reg(dev, &mmsys->cmdq_base, 0);
if (ret)
diff --git a/drivers/soc/mediatek/mtk-mmsys.h b/drivers/soc/mediatek/mtk-mmsys.h
index 2694021435d2..4842102cd451 100644
--- a/drivers/soc/mediatek/mtk-mmsys.h
+++ b/drivers/soc/mediatek/mtk-mmsys.h
@@ -102,6 +102,8 @@ struct mtk_mmsys_driver_data {
const unsigned int num_routes;
const struct mtk_mmsys_config *config;
const unsigned int num_configs;
+   u32 sw_reset_start;
+   u32 num_resets;
 };
 
 /*
-- 
2.18.0



[PATCH v9 04/22] dt-bindings: reset: mt8195: add vdosys1 reset control bit

2021-11-29 Thread Nancy . Lin
Add vdosys1 reset control bit for MT8195 platform.

Signed-off-by: Nancy.Lin 
Reviewed-by: Chun-Kuang Hu 
---
 include/dt-bindings/reset/mt8195-resets.h | 12 
 1 file changed, 12 insertions(+)

diff --git a/include/dt-bindings/reset/mt8195-resets.h 
b/include/dt-bindings/reset/mt8195-resets.h
index a26bccc8b957..aab8d74496a6 100644
--- a/include/dt-bindings/reset/mt8195-resets.h
+++ b/include/dt-bindings/reset/mt8195-resets.h
@@ -26,4 +26,16 @@
 
 #define MT8195_TOPRGU_SW_RST_NUM   16
 
+/* VDOSYS1 */
+#define MT8195_VDOSYS1_SW0_RST_B_MERGE0_DL_ASYNC  25
+#define MT8195_VDOSYS1_SW0_RST_B_MERGE1_DL_ASYNC  26
+#define MT8195_VDOSYS1_SW0_RST_B_MERGE2_DL_ASYNC  27
+#define MT8195_VDOSYS1_SW0_RST_B_MERGE3_DL_ASYNC  28
+#define MT8195_VDOSYS1_SW0_RST_B_MERGE4_DL_ASYNC  29
+#define MT8195_VDOSYS1_SW1_RST_B_HDR_VDO_FE0_DL_ASYNC 51
+#define MT8195_VDOSYS1_SW1_RST_B_HDR_VDO_FE1_DL_ASYNC 52
+#define MT8195_VDOSYS1_SW1_RST_B_HDR_GFX_FE0_DL_ASYNC 53
+#define MT8195_VDOSYS1_SW1_RST_B_HDR_GFX_FE1_DL_ASYNC 54
+#define MT8195_VDOSYS1_SW1_RST_B_HDR_VDO_BE_DL_ASYNC  55
+
 #endif  /* _DT_BINDINGS_RESET_CONTROLLER_MT8195 */
-- 
2.18.0



[PATCH v9 02/22] dt-bindings: mediatek: add vdosys1 MERGE property for mt8195

2021-11-29 Thread Nancy . Lin
MT8195 vdosys1 merge1 to merge4 have HW mute function.
Add MERGE additional mute property description.

Signed-off-by: Nancy.Lin 
Reviewed-by: Chun-Kuang Hu 
Acked-By: AngeloGioacchino Del Regno 
---
 .../devicetree/bindings/display/mediatek/mediatek,merge.yaml  | 4 
 1 file changed, 4 insertions(+)

diff --git 
a/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml 
b/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
index 28be8ffeb429..f5b1e632bcd5 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
@@ -61,6 +61,10 @@ properties:
   command to SMI to speed up the data rate.
 type: boolean
 
+  mediatek,merge-mute:
+description: Support mute function. Mute the content of merge output.
+type: boolean
+
   mediatek,gce-client-reg:
 description:
   The register of client driver can be configured by gce with 4 arguments
-- 
2.18.0



[PATCH v9 07/22] soc: mediatek: add cmdq support of mtk-mmsys config API for mt8195 vdosys1

2021-11-29 Thread Nancy . Lin
Add cmdq support for mtk-mmsys config API.
The mmsys config register settings need to take effect with the other
HW settings(like OVL_ADAPTOR...) at the same vblanking time.

If we use CPU to write the mmsys reg, we can't guarantee all the
settings can be written in the same vblanking time.
Cmdq is used for this purpose. We prepare all the related HW settings
in one cmdq packet. The first command in the packet is "wait stream done",
and then following with all the HW settings. After the cmdq packet is
flush to GCE HW. The GCE waits for the "stream done event" to coming
and then starts flushing all the HW settings. This can guarantee all
the settings flush in the same vblanking.

Signed-off-by: Nancy.Lin 
---
 drivers/soc/mediatek/mtk-mmsys.c   | 29 --
 include/linux/soc/mediatek/mtk-mmsys.h |  6 +-
 2 files changed, 28 insertions(+), 7 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c
index 725a99fcbc6d..1b0024ee47a9 100644
--- a/drivers/soc/mediatek/mtk-mmsys.c
+++ b/drivers/soc/mediatek/mtk-mmsys.c
@@ -88,6 +88,7 @@ struct mtk_mmsys {
const struct mtk_mmsys_driver_data *data;
spinlock_t lock; /* protects mmsys_sw_rst_b reg */
struct reset_controller_dev rcdev;
+   struct cmdq_client_reg cmdq_base;
 };
 
 void mtk_mmsys_ddp_connect(struct device *dev,
@@ -180,7 +181,7 @@ static const struct reset_control_ops mtk_mmsys_reset_ops = 
{
 };
 
 void mtk_mmsys_ddp_config(struct device *dev, enum mtk_mmsys_config_type 
config,
- u32 id, u32 val)
+ u32 id, u32 val, struct cmdq_pkt *cmdq_pkt)
 {
struct mtk_mmsys *mmsys = dev_get_drvdata(dev);
const struct mtk_mmsys_config *mmsys_config = mmsys->data->config;
@@ -188,7 +189,6 @@ void mtk_mmsys_ddp_config(struct device *dev, enum 
mtk_mmsys_config_type config,
u32 mask;
u32 offset;
int i;
-   u32 tmp;
 
if (!mmsys->data->num_configs)
return;
@@ -204,10 +204,20 @@ void mtk_mmsys_ddp_config(struct device *dev, enum 
mtk_mmsys_config_type config,
mask = mmsys_config[i].mask;
reg_val = val << mmsys_config[i].shift;
 
-   tmp = readl(mmsys->regs + offset);
-
-   tmp = (tmp & ~mask) | reg_val;
-   writel(tmp, mmsys->regs + offset);
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+   if (cmdq_pkt && mmsys->cmdq_base.size) {
+   cmdq_pkt_write_mask(cmdq_pkt, mmsys->cmdq_base.subsys,
+   mmsys->cmdq_base.offset + offset, reg_val,
+   mask);
+   } else {
+#endif
+   u32 tmp = readl(mmsys->regs + offset);
+
+   tmp = (tmp & ~mask) | reg_val;
+   writel(tmp, mmsys->regs + offset);
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+   }
+#endif
 }
 EXPORT_SYMBOL_GPL(mtk_mmsys_ddp_config);
 
@@ -243,6 +253,13 @@ static int mtk_mmsys_probe(struct platform_device *pdev)
}
 
mmsys->data = of_device_get_match_data(&pdev->dev);
+
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+   ret = cmdq_dev_get_client_reg(dev, &mmsys->cmdq_base, 0);
+   if (ret)
+   dev_dbg(dev, "No mediatek,gce-client-reg!\n");
+#endif
+
platform_set_drvdata(pdev, mmsys);
 
clks = platform_device_register_data(&pdev->dev, 
mmsys->data->clk_driver,
diff --git a/include/linux/soc/mediatek/mtk-mmsys.h 
b/include/linux/soc/mediatek/mtk-mmsys.h
index b2d2310d7e7a..3e998bfb795a 100644
--- a/include/linux/soc/mediatek/mtk-mmsys.h
+++ b/include/linux/soc/mediatek/mtk-mmsys.h
@@ -6,6 +6,10 @@
 #ifndef __MTK_MMSYS_H
 #define __MTK_MMSYS_H
 
+#include 
+#include 
+#include 
+
 enum mtk_ddp_comp_id;
 struct device;
 
@@ -78,6 +82,6 @@ void mtk_mmsys_ddp_disconnect(struct device *dev,
  enum mtk_ddp_comp_id next);
 
 void mtk_mmsys_ddp_config(struct device *dev, enum mtk_mmsys_config_type 
config,
- u32 id, u32 val);
+ u32 id, u32 val, struct cmdq_pkt *cmdq_pkt);
 
 #endif /* __MTK_MMSYS_H */
-- 
2.18.0



Re: [PATCH 4/4] drm: rcar-du: mipi-dsi: Support bridge probe ordering

2021-11-29 Thread Laurent Pinchart
Hi Kieran,

Thank you for the patch.

On Fri, Nov 26, 2021 at 10:15:18AM +, Kieran Bingham wrote:
> The bridge probe ordering for DSI devices has been clarified and further
> documented in

In what ? :-)

> To support connecting with the SN65DSI86 device after commit c3b75d4734cb
> ("drm/bridge: sn65dsi86: Register and attach our DSI device at probe"),
> update to the new probe ordering to remove a perpetual -EPROBE_DEFER
> loop between the two devices.
> 
> Signed-off-by: Kieran Bingham 

Will you send a new version of this patch with Biju's comments taken
into account ? I've already applied 1/4 to 3/4 to my tree, so there's no
need to repost them.

> ---
>  drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c | 48 +
>  1 file changed, 26 insertions(+), 22 deletions(-)
> 
> diff --git a/drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c 
> b/drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c
> index 833f4480bdf3..f783bacee8da 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c
> @@ -639,6 +639,8 @@ static int rcar_mipi_dsi_host_attach(struct mipi_dsi_host 
> *host,
>   struct mipi_dsi_device *device)
>  {
>   struct rcar_mipi_dsi *dsi = host_to_rcar_mipi_dsi(host);
> + struct drm_panel *panel;
> + int ret;
>  
>   if (device->lanes > dsi->num_data_lanes)
>   return -EINVAL;
> @@ -646,12 +648,36 @@ static int rcar_mipi_dsi_host_attach(struct 
> mipi_dsi_host *host,
>   dsi->lanes = device->lanes;
>   dsi->format = device->format;
>  
> + ret = drm_of_find_panel_or_bridge(dsi->dev->of_node, 1, 0, &panel,
> +   &dsi->next_bridge);
> + if (ret) {
> + dev_err_probe(dsi->dev, ret, "could not find next bridge\n");
> + return ret;
> + }
> +
> + if (!dsi->next_bridge) {
> + dsi->next_bridge = devm_drm_panel_bridge_add(dsi->dev, panel);
> + if (IS_ERR(dsi->next_bridge)) {
> + dev_err(dsi->dev, "failed to create panel bridge\n");
> + return PTR_ERR(dsi->next_bridge);
> + }
> + }
> +
> + /* Initialize the DRM bridge. */
> + dsi->bridge.funcs = &rcar_mipi_dsi_bridge_ops;
> + dsi->bridge.of_node = dsi->dev->of_node;
> + drm_bridge_add(&dsi->bridge);
> +
>   return 0;
>  }
>  
>  static int rcar_mipi_dsi_host_detach(struct mipi_dsi_host *host,
>   struct mipi_dsi_device *device)
>  {
> + struct rcar_mipi_dsi *dsi = host_to_rcar_mipi_dsi(host);
> +
> + drm_bridge_remove(&dsi->bridge);
> +
>   return 0;
>  }
>  
> @@ -766,21 +792,6 @@ static int rcar_mipi_dsi_probe(struct platform_device 
> *pdev)
>   return PTR_ERR(dsi->rstc);
>   }
>  
> - ret = drm_of_find_panel_or_bridge(dsi->dev->of_node, 1, 0, &panel,
> -   &dsi->next_bridge);
> - if (ret) {
> - dev_err_probe(dsi->dev, ret, "could not find next bridge\n");
> - return ret;
> - }
> -
> - if (!dsi->next_bridge) {
> - dsi->next_bridge = devm_drm_panel_bridge_add(dsi->dev, panel);
> - if (IS_ERR(dsi->next_bridge)) {
> - dev_err(dsi->dev, "failed to create panel bridge\n");
> - return PTR_ERR(dsi->next_bridge);
> - }
> - }
> -
>   /* Initialize the DSI host. */
>   dsi->host.dev = dsi->dev;
>   dsi->host.ops = &rcar_mipi_dsi_host_ops;
> @@ -788,11 +799,6 @@ static int rcar_mipi_dsi_probe(struct platform_device 
> *pdev)
>   if (ret < 0)
>   return ret;
>  
> - /* Initialize the DRM bridge. */
> - dsi->bridge.funcs = &rcar_mipi_dsi_bridge_ops;
> - dsi->bridge.of_node = dsi->dev->of_node;
> - drm_bridge_add(&dsi->bridge);
> -
>   return 0;
>  }
>  
> @@ -800,8 +806,6 @@ static int rcar_mipi_dsi_remove(struct platform_device 
> *pdev)
>  {
>   struct rcar_mipi_dsi *dsi = platform_get_drvdata(pdev);
>  
> - drm_bridge_remove(&dsi->bridge);
> -
>   mipi_dsi_host_unregister(&dsi->host);
>  
>   return 0;

-- 
Regards,

Laurent Pinchart


Re: [PATCH 3/4] drm: rcar-du: mipi-dsi: Ensure correct fout is reported

2021-11-29 Thread Laurent Pinchart
Hi Kieran,

Thank you for the patch.

On Fri, Nov 26, 2021 at 10:15:17AM +, Kieran Bingham wrote:
> The debug reporting for the clock calculations was erroneously reporting
> the last calculation of fout, rather than the fout that was determined
> to have the least error, and therefore be the values chosen to operate
> with.
> 
> Fix the reporting to show the correct output by storing the determined
> fout, along with the error value.
> 
> Signed-off-by: Kieran Bingham 
> ---
> 
> I spent /way/ too long confused why my clock values didn't make sense
> before I noticed this.. :-(

Oops :-S Sorry about that.

>  drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c 
> b/drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c
> index e94245029f95..833f4480bdf3 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c
> @@ -168,6 +168,7 @@ static int rcar_mipi_dsi_phtw_test(struct rcar_mipi_dsi 
> *dsi, u32 phtw)
>   */
>  
>  struct dsi_setup_info {
> + unsigned long fout;
>   unsigned int err;
>   u16 vco_cntrl;
>   u16 prop_cntrl;
> @@ -247,6 +248,7 @@ static void rcar_mipi_dsi_parameters_calc(struct 
> rcar_mipi_dsi *dsi,
>   setup_info->m = m - 2;
>   setup_info->n = n - 1;
>   setup_info->err = err;
> + setup_info->fout = fout;
>   if (err == 0)
>   goto done;
>   }
> @@ -256,7 +258,7 @@ static void rcar_mipi_dsi_parameters_calc(struct 
> rcar_mipi_dsi *dsi,
>  done:
>   dev_dbg(dsi->dev,
>   "%pC %lu Hz -> Fout %lu Hz (target %lu Hz, error %d.%02u%%), 
> PLL M/N/DIV %u/%u/%u\n",
> - clk, fin, fout, fout_target, setup_info->err / 100,
> + clk, fin, setup_info->fout, fout_target, setup_info->err / 100,

We don't need the fout in the caller, so it could be a local variable
(best_fout for instance). I can however imagine that we the frequency
could become useful in the caller, so

Reviewed-by: Laurent Pinchart 

>   setup_info->err % 100, setup_info->m,
>   setup_info->n, setup_info->div);
>   dev_dbg(dsi->dev,

-- 
Regards,

Laurent Pinchart


Re: [PATCH 2/4] drm: rcar-du: Select DRM_MIPI_DSI with DRM_RCAR_MIPI_DSI

2021-11-29 Thread Laurent Pinchart
Hi Kieran,

Thank you for the patch.

On Fri, Nov 26, 2021 at 10:15:16AM +, Kieran Bingham wrote:
> The RCAR_MIPI_DSI uses the DRM_MIPI_DSI interface.
> 
> Ensure that it is selected when the option is enabled.
> 
> Signed-off-by: Kieran Bingham 

Reviewed-by: Laurent Pinchart 

I'll squash it with the appropriate patch.

> ---
>  drivers/gpu/drm/rcar-du/Kconfig | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/gpu/drm/rcar-du/Kconfig b/drivers/gpu/drm/rcar-du/Kconfig
> index 8cb94fe90639..8145c6d4cbc8 100644
> --- a/drivers/gpu/drm/rcar-du/Kconfig
> +++ b/drivers/gpu/drm/rcar-du/Kconfig
> @@ -41,6 +41,7 @@ config DRM_RCAR_LVDS
>  config DRM_RCAR_MIPI_DSI
>   tristate "R-Car DU MIPI DSI Encoder Support"
>   depends on DRM && DRM_BRIDGE && OF
> + select DRM_MIPI_DSI
>   help
> Enable support for the R-Car Display Unit embedded MIPI DSI encoders.
>  

-- 
Regards,

Laurent Pinchart


Re: [PATCH 1/4] drm: rcar-du: Fix Makefile indentation for DSI

2021-11-29 Thread Laurent Pinchart
Hi Kieran,

Thank you for the patch.

On Fri, Nov 26, 2021 at 10:15:15AM +, Kieran Bingham wrote:
> From: Kieran Bingham 
> 
> Signed-off-by: Kieran Bingham 

Reviewed-by: Laurent Pinchart 

> ---
>  drivers/gpu/drm/rcar-du/Makefile | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/rcar-du/Makefile 
> b/drivers/gpu/drm/rcar-du/Makefile
> index adc1b49d02cf..286bc81b3e7c 100644
> --- a/drivers/gpu/drm/rcar-du/Makefile
> +++ b/drivers/gpu/drm/rcar-du/Makefile
> @@ -19,7 +19,7 @@ obj-$(CONFIG_DRM_RCAR_CMM)  += rcar_cmm.o
>  obj-$(CONFIG_DRM_RCAR_DU)+= rcar-du-drm.o
>  obj-$(CONFIG_DRM_RCAR_DW_HDMI)   += rcar_dw_hdmi.o
>  obj-$(CONFIG_DRM_RCAR_LVDS)  += rcar_lvds.o
> -obj-$(CONFIG_DRM_RCAR_MIPI_DSI)  += rcar_mipi_dsi.o
> +obj-$(CONFIG_DRM_RCAR_MIPI_DSI)  += rcar_mipi_dsi.o
>  
>  # 'remote-endpoint' is fixed up at run-time
>  DTC_FLAGS_rcar_du_of_lvds_r8a7790 += -Wno-graph_endpoint

-- 
Regards,

Laurent Pinchart


Re: [PATCH] drm: rcar-du: Add DSI support to rcar_du_output_name

2021-11-29 Thread Laurent Pinchart
Hi Kieran,

Thank you for the patch.

On Mon, Nov 29, 2021 at 05:08:45PM +, Kieran Bingham wrote:
> The DSI output names were not added when the DSI pipeline support was
> introduced.
> 
> Add the correct labels for these outputs, and fix the sort order to
> match 'enum rcar_du_output' while we are here.
> 
> Fixes: b291fdcf5114 ("drm: rcar-du: Add r8a779a0 device support")
> Suggested-by: Biju Das 
> Signed-off-by: Kieran Bingham 

Reviewed-by: Laurent Pinchart 

> ---
>  drivers/gpu/drm/rcar-du/rcar_du_drv.c | 6 --
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c 
> b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> index 5612a9e7a905..5a8131ef81d5 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> @@ -544,10 +544,12 @@ const char *rcar_du_output_name(enum rcar_du_output 
> output)
>   static const char * const names[] = {
>   [RCAR_DU_OUTPUT_DPAD0] = "DPAD0",
>   [RCAR_DU_OUTPUT_DPAD1] = "DPAD1",
> - [RCAR_DU_OUTPUT_LVDS0] = "LVDS0",
> - [RCAR_DU_OUTPUT_LVDS1] = "LVDS1",
> + [RCAR_DU_OUTPUT_DSI0] = "DSI0",
> + [RCAR_DU_OUTPUT_DSI1] = "DSI1",
>   [RCAR_DU_OUTPUT_HDMI0] = "HDMI0",
>   [RCAR_DU_OUTPUT_HDMI1] = "HDMI1",
> + [RCAR_DU_OUTPUT_LVDS0] = "LVDS0",
> + [RCAR_DU_OUTPUT_LVDS1] = "LVDS1",
>   [RCAR_DU_OUTPUT_TCON] = "TCON",
>   };
>  

-- 
Regards,

Laurent Pinchart


Re: [Freedreno] [PATCH v3 01/13] drm/msm/dsi: add support for dsc data

2021-11-29 Thread Abhinav Kumar

Hi Vinod

On 11/15/2021 10:22 PM, Vinod Koul wrote:

Display Stream Compression (DSC) parameters need to be calculated. Add
helpers and struct msm_display_dsc_config in msm_drv for this
msm_display_dsc_config uses drm_dsc_config for DSC parameters.

Signed-off-by: Vinod Koul 
---
  drivers/gpu/drm/msm/dsi/dsi_host.c | 132 +
  drivers/gpu/drm/msm/msm_drv.h  |  20 +
  2 files changed, 152 insertions(+)

diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
b/drivers/gpu/drm/msm/dsi/dsi_host.c
index f69a125f9559..30c1e299aa52 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -31,6 +31,8 @@
  
  #define DSI_RESET_TOGGLE_DELAY_MS 20
  
+static int dsi_populate_dsc_params(struct msm_display_dsc_config *dsc);

+
  static int dsi_get_version(const void __iomem *base, u32 *major, u32 *minor)
  {
u32 ver;
@@ -157,6 +159,7 @@ struct msm_dsi_host {
struct regmap *sfpb;
  
  	struct drm_display_mode *mode;

+   struct msm_display_dsc_config *dsc;
  
  	/* connected device info */

struct device_node *device_node;
@@ -1710,6 +1713,135 @@ static int dsi_host_parse_lane_data(struct msm_dsi_host 
*msm_host,
return -EINVAL;
  }
  
+static u32 dsi_dsc_rc_buf_thresh[DSC_NUM_BUF_RANGES - 1] = {

+   0x0e, 0x1c, 0x2a, 0x38, 0x46, 0x54, 0x62,
+   0x69, 0x70, 0x77, 0x79, 0x7b, 0x7d, 0x7e
+};
+
+/* only 8bpc, 8bpp added */
+static char min_qp[DSC_NUM_BUF_RANGES] = {
+   0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 13
+};
+
+static char max_qp[DSC_NUM_BUF_RANGES] = {
+   4, 4, 5, 6, 7, 7, 7, 8, 9, 10, 11, 12, 13, 13, 15
+};
+
+static char bpg_offset[DSC_NUM_BUF_RANGES] = {
+   2, 0, 0, -2, -4, -6, -8, -8, -8, -10, -10, -12, -12, -12, -12
+};
+
+static int dsi_populate_dsc_params(struct msm_display_dsc_config *dsc)
+{
+   int mux_words_size;
+   int groups_per_line, groups_total;
+   int min_rate_buffer_size;
+   int hrd_delay;
+   int pre_num_extra_mux_bits, num_extra_mux_bits;
+   int slice_bits;
+   int target_bpp_x16;
+   int data;
+   int final_value, final_scale;
+   int i;
+
+   dsc->drm->rc_model_size = 8192;
+   dsc->drm->first_line_bpg_offset = 12;
+   dsc->drm->rc_edge_factor = 6;
+   dsc->drm->rc_tgt_offset_high = 3;
+   dsc->drm->rc_tgt_offset_low = 3;
+   dsc->drm->simple_422 = 0;
+   dsc->drm->convert_rgb = 1;
+   dsc->drm->vbr_enable = 0;
+
+   /* handle only bpp = bpc = 8 */
+   for (i = 0; i < DSC_NUM_BUF_RANGES - 1 ; i++)
+   dsc->drm->rc_buf_thresh[i] = dsi_dsc_rc_buf_thresh[i];
+
+   for (i = 0; i < DSC_NUM_BUF_RANGES; i++) {
+   dsc->drm->rc_range_params[i].range_min_qp = min_qp[i];
+   dsc->drm->rc_range_params[i].range_max_qp = max_qp[i];
+   dsc->drm->rc_range_params[i].range_bpg_offset = bpg_offset[i];
+   }
+
+   dsc->drm->initial_offset = 6144; /* Not bpp 12 */
+   if (dsc->drm->bits_per_pixel != 8)
+   dsc->drm->initial_offset = 2048;  /* bpp = 12 */
+
+   mux_words_size = 48;/* bpc == 8/10 */
+   if (dsc->drm->bits_per_component == 12)
+   mux_words_size = 64;
+
+   dsc->drm->initial_xmit_delay = 512;
+   dsc->drm->initial_scale_value = 32;
+   dsc->drm->first_line_bpg_offset = 12;
+   dsc->drm->line_buf_depth = dsc->drm->bits_per_component + 1;
+
+   /* bpc 8 */
+   dsc->drm->flatness_min_qp = 3;
+   dsc->drm->flatness_max_qp = 12;
+   dsc->det_thresh_flatness = 7 + 2 * (dsc->drm->bits_per_component - 8);
+   dsc->drm->rc_quant_incr_limit0 = 11;
+   dsc->drm->rc_quant_incr_limit1 = 11;
+   dsc->drm->mux_word_size = DSC_MUX_WORD_SIZE_8_10_BPC;
+
+   /* FIXME: need to call drm_dsc_compute_rc_parameters() so that rest of
+* params are calculated
+*/
since its been a while on this, before moving ahead with a FIXME 
comment, I wanted to know if you had a chance to check what is the 
discrepancy between this and drm_dsc_compute_rc_parameters().


The LOC saved can be quite a bit if we move to
drm_dsc_compute_rc_parameters(). Last time we synced, I think only one 
parameter was mismatching. The code-churn to avoid one mismatch seems a 
lot. If there are more conflicting parameters than one or two, we can go 
ahead with this custom calculation with your FIXME.




+   dsc->slice_last_group_size = 3 - (dsc->drm->slice_width % 3);
+   groups_per_line = DIV_ROUND_UP(dsc->drm->slice_width, 3);
+   dsc->drm->slice_chunk_size = dsc->drm->slice_width * 
dsc->drm->bits_per_pixel / 8;
+   if ((dsc->drm->slice_width * dsc->drm->bits_per_pixel) % 8)
+   dsc->drm->slice_chunk_size++;
+
+   /* rbs-min */
+   min_rate_buffer_size =  dsc->drm->rc_model_size - 
dsc->drm->initial_offset +
+   dsc->drm->initial_xmit_delay * 
dsc->drm->bits_per_pixel +
+   groups_per

[PATCH v2] drm/i915/dp: Perform 30ms delay after source OUI write

2021-11-29 Thread Lyude Paul
While working on supporting the Intel HDR backlight interface, I noticed
that there's a couple of laptops that will very rarely manage to boot up
without detecting Intel HDR backlight support - even though it's supported
on the system. One example of such a laptop is the Lenovo P17 1st
generation.

Following some investigation Ville Syrjälä did through the docs they have
available to them, they discovered that there's actually supposed to be a
30ms wait after writing the source OUI before we begin setting up the rest
of the backlight interface.

This seems to be correct, as adding this 30ms delay seems to have
completely fixed the probing issues I was previously seeing. So - let's
start performing a 30ms wait after writing the OUI, which we do in a manner
similar to how we keep track of PPS delays (e.g. record the timestamp of
the OUI write, and then wait for however many ms are left since that
timestamp right before we interact with the backlight) in order to avoid
waiting any longer then we need to. As well, this also avoids us performing
this delay on systems where we don't end up using the HDR backlight
interface.

V2:
* Move panel delays into intel_pps

Signed-off-by: Lyude Paul 
Fixes: 4a8d79901d5b ("drm/i915/dp: Enable Intel's HDR backlight interface (only 
SDR for now)")
Cc: Ville Syrjälä 
Cc:  # v5.12+
---
 drivers/gpu/drm/i915/display/intel_display_types.h|  4 
 drivers/gpu/drm/i915/display/intel_dp.c   | 11 +++
 drivers/gpu/drm/i915/display/intel_dp.h   |  2 ++
 drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c |  5 +
 4 files changed, 22 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h 
b/drivers/gpu/drm/i915/display/intel_display_types.h
index ea1e8a6e10b0..ad64f9caa7ff 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1485,6 +1485,7 @@ struct intel_pps {
bool want_panel_vdd;
unsigned long last_power_on;
unsigned long last_backlight_off;
+   unsigned long last_oui_write;
ktime_t panel_power_off_time;
intel_wakeref_t vdd_wakeref;
 
@@ -1653,6 +1654,9 @@ struct intel_dp {
struct intel_dp_pcon_frl frl;
 
struct intel_psr psr;
+
+   /* When we last wrote the OUI for eDP */
+   unsigned long last_oui_write;
 };
 
 enum lspcon_vendor {
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 0a424bf69396..45318891ba07 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -29,6 +29,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include 
@@ -2010,6 +2011,16 @@ intel_edp_init_source_oui(struct intel_dp *intel_dp, 
bool careful)
 
if (drm_dp_dpcd_write(&intel_dp->aux, DP_SOURCE_OUI, oui, sizeof(oui)) 
< 0)
drm_err(&i915->drm, "Failed to write source OUI\n");
+
+   intel_dp->pps.last_oui_write = jiffies;
+}
+
+void intel_dp_wait_source_oui(struct intel_dp *intel_dp)
+{
+   struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+
+   drm_dbg_kms(&i915->drm, "Performing OUI wait\n");
+   wait_remaining_ms_from_jiffies(intel_dp->last_oui_write, 30);
 }
 
 /* If the device supports it, try to set the power state appropriately */
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h 
b/drivers/gpu/drm/i915/display/intel_dp.h
index ce229026dc91..b64145a3869a 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -119,4 +119,6 @@ void intel_dp_pcon_dsc_configure(struct intel_dp *intel_dp,
 const struct intel_crtc_state *crtc_state);
 void intel_dp_phy_test(struct intel_encoder *encoder);
 
+void intel_dp_wait_source_oui(struct intel_dp *intel_dp);
+
 #endif /* __INTEL_DP_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c 
b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
index 8b9c925c4c16..62c112daacf2 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
@@ -36,6 +36,7 @@
 
 #include "intel_backlight.h"
 #include "intel_display_types.h"
+#include "intel_dp.h"
 #include "intel_dp_aux_backlight.h"
 
 /* TODO:
@@ -106,6 +107,8 @@ intel_dp_aux_supports_hdr_backlight(struct intel_connector 
*connector)
int ret;
u8 tcon_cap[4];
 
+   intel_dp_wait_source_oui(intel_dp);
+
ret = drm_dp_dpcd_read(aux, INTEL_EDP_HDR_TCON_CAP0, tcon_cap, 
sizeof(tcon_cap));
if (ret != sizeof(tcon_cap))
return false;
@@ -204,6 +207,8 @@ intel_dp_aux_hdr_enable_backlight(const struct 
intel_crtc_state *crtc_state,
int ret;
u8 old_ctrl, ctrl;
 
+   intel_dp_wait_source_oui(intel_dp);
+
ret = drm_dp_dpcd_readb(&intel_dp->aux, 
INTEL_EDP_HDR_GETSET_CTRL_PARAMS, &old_ctrl);
if (ret != 1) {
drm_err(&i9

linux-next: manual merge of the drm tree with the drm-misc-fixes tree

2021-11-29 Thread Stephen Rothwell
Hi all,

Today's linux-next merge of the drm tree got a conflict in:

  drivers/gpu/drm/vc4/vc4_kms.c

between commits:

  f927767978d2 ("drm/vc4: kms: Fix return code check")
  d354699e2292 ("drm/vc4: kms: Don't duplicate pending commit")

from the drm-misc-fixes tree and commit:

  16e101051f32 ("drm/vc4: Increase the core clock based on HVS load")

from the drm tree.

I fixed it up (see below) and can carry the fix as necessary. This
is now fixed as far as linux-next is concerned, but any non trivial
conflicts should be mentioned to your upstream maintainer when your tree
is submitted for merging.  You may also want to consider cooperating
with the maintainer of the conflicting tree to minimise any particularly
complex conflicts.

-- 
Cheers,
Stephen Rothwell

diff --cc drivers/gpu/drm/vc4/vc4_kms.c
index b61792d2aa65,79d4d9dd1394..
--- a/drivers/gpu/drm/vc4/vc4_kms.c
+++ b/drivers/gpu/drm/vc4/vc4_kms.c
@@@ -337,12 -340,21 +340,21 @@@ static void vc4_atomic_commit_tail(stru
struct drm_device *dev = state->dev;
struct vc4_dev *vc4 = to_vc4_dev(dev);
struct vc4_hvs *hvs = vc4->hvs;
 -  struct drm_crtc_state *old_crtc_state;
struct drm_crtc_state *new_crtc_state;
+   struct vc4_hvs_state *new_hvs_state;
struct drm_crtc *crtc;
struct vc4_hvs_state *old_hvs_state;
 +  unsigned int channel;
int i;
  
+   old_hvs_state = vc4_hvs_get_old_global_state(state);
 -  if (WARN_ON(!old_hvs_state))
++  if (WARN_ON(IS_ERR(old_hvs_state)))
+   return;
+ 
+   new_hvs_state = vc4_hvs_get_new_global_state(state);
 -  if (WARN_ON(!new_hvs_state))
++  if (WARN_ON(IS_ERR(new_hvs_state)))
+   return;
+ 
for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
struct vc4_crtc_state *vc4_crtc_state;
  
@@@ -353,32 -365,31 +365,36 @@@
vc4_hvs_mask_underrun(dev, vc4_crtc_state->assigned_channel);
}
  
-   old_hvs_state = vc4_hvs_get_old_global_state(state);
-   if (IS_ERR(old_hvs_state))
-   return;
+   if (vc4->hvs->hvs5) {
+   unsigned long core_rate = max_t(unsigned long,
+   5,
+   new_hvs_state->core_clock_rate);
+ 
+   clk_set_min_rate(hvs->core_clk, core_rate);
+   }
  
 -  for_each_old_crtc_in_state(state, crtc, old_crtc_state, i) {
 -  struct vc4_crtc_state *vc4_crtc_state =
 -  to_vc4_crtc_state(old_crtc_state);
 -  unsigned int channel = vc4_crtc_state->assigned_channel;
 +  for (channel = 0; channel < HVS_NUM_CHANNELS; channel++) {
 +  struct drm_crtc_commit *commit;
int ret;
  
 -  if (channel == VC4_HVS_CHANNEL_DISABLED)
 +  if (!old_hvs_state->fifo_state[channel].in_use)
continue;
  
 -  if (!old_hvs_state->fifo_state[channel].in_use)
 +  commit = old_hvs_state->fifo_state[channel].pending_commit;
 +  if (!commit)
continue;
  
 -  ret = 
drm_crtc_commit_wait(old_hvs_state->fifo_state[channel].pending_commit);
 +  ret = drm_crtc_commit_wait(commit);
if (ret)
drm_err(dev, "Timed out waiting for commit\n");
 +
 +  drm_crtc_commit_put(commit);
 +  old_hvs_state->fifo_state[channel].pending_commit = NULL;
}
  
 +  if (vc4->hvs->hvs5)
 +  clk_set_min_rate(hvs->core_clk, 5);
 +
drm_atomic_helper_commit_modeset_disables(dev, state);
  
vc4_ctm_commit(vc4, state);
@@@ -667,11 -673,19 +678,13 @@@ vc4_hvs_channels_duplicate_state(struc
  
__drm_atomic_helper_private_obj_duplicate_state(obj, &state->base);
  
- 
for (i = 0; i < HVS_NUM_CHANNELS; i++) {
state->fifo_state[i].in_use = old_state->fifo_state[i].in_use;
+   state->fifo_state[i].fifo_load = 
old_state->fifo_state[i].fifo_load;
 -
 -  if (!old_state->fifo_state[i].pending_commit)
 -  continue;
 -
 -  state->fifo_state[i].pending_commit =
 -  
drm_crtc_commit_get(old_state->fifo_state[i].pending_commit);
}
  
+   state->core_clock_rate = old_state->core_clock_rate;
+ 
return &state->base;
  }
  
@@@ -826,6 -840,76 +839,76 @@@ static int vc4_pv_muxing_atomic_check(s
return 0;
  }
  
+ static int
+ vc4_core_clock_atomic_check(struct drm_atomic_state *state)
+ {
+   struct vc4_dev *vc4 = to_vc4_dev(state->dev);
+   struct drm_private_state *priv_state;
+   struct vc4_hvs_state *hvs_new_state;
+   struct vc4_load_tracker_state *load_state;
+   struct drm_crtc_state *old_crtc_state, *new_crtc_state;
+   struct drm_crtc *crtc;
+   unsigned int num_outputs;
+   unsigned lon

Re: [PATCH 1/5] dt-bindings: display: vc4: Add optional phandle to firmware

2021-11-29 Thread Rob Herring
On Wed, Nov 17, 2021 at 03:50:36PM +0100, Maxime Ripard wrote:
> The firmware can free all the resources it was using to run the display
> engine that won't be needed once the kernel has taken over.
> 
> Thus, we need a phandle to the firmware DT node to be able to send that
> message when relevant.

Why? Just use of_find_compatible_node(). 

> 
> Signed-off-by: Maxime Ripard 
> ---
>  .../devicetree/bindings/display/brcm,bcm2835-vc4.yaml| 5 +
>  1 file changed, 5 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/display/brcm,bcm2835-vc4.yaml 
> b/Documentation/devicetree/bindings/display/brcm,bcm2835-vc4.yaml
> index 49a5e041aa49..18de6912b833 100644
> --- a/Documentation/devicetree/bindings/display/brcm,bcm2835-vc4.yaml
> +++ b/Documentation/devicetree/bindings/display/brcm,bcm2835-vc4.yaml
> @@ -21,6 +21,11 @@ properties:
>- brcm,bcm2835-vc4
>- brcm,cygnus-vc4
>  
> +  raspberrypi,firmware:
> +$ref: "/schemas/types.yaml#/definitions/phandle"
> +description: >
> +  Phandle to the firmware node
> +
>  required:
>- compatible
>  
> -- 
> 2.33.1
> 
> 


Re: [PATCH 04/12] drm/rockchip: dw_hdmi: add regulator support

2021-11-29 Thread Rob Herring
On Wed, Nov 17, 2021 at 03:33:39PM +0100, Sascha Hauer wrote:
> The RK3568 has HDMI_TX_AVDD0V9 and HDMI_TX_AVDD_1V8 supply inputs needed
> for the HDMI port. add support for these to the driver for boards which
> have them supplied by switchable regulators.
> 
> Signed-off-by: Sascha Hauer 
> ---
>  .../display/rockchip/rockchip,dw-hdmi.yaml|  6 ++

Bindings should be a separate patch. Include this as part of adding 
RK3568 support to the binding.

>  drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c   | 58 ++-
>  2 files changed, 61 insertions(+), 3 deletions(-)
> 
> diff --git 
> a/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml 
> b/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml
> index 53fa42479d5b7..293b2cfbf739f 100644
> --- a/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml
> +++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml
> @@ -28,6 +28,12 @@ properties:
>reg-io-width:
>  const: 4
>  
> +  avdd-0v9-supply:
> +description: A 0.9V supply that powers up the SoC internal circuitry.
> +
> +  avdd-1v8-supply:
> +description: A 0.9V supply that powers up the SoC internal circuitry.

0.9V ???

> +
>clocks:
>  minItems: 2
>  items:


[PATCH] drm: rcar-du: Fix CRTC timings when CMM is used

2021-11-29 Thread Laurent Pinchart
When the CMM is enabled, an offset of 25 pixels must be subtracted from
the HDS (horizontal display start) and HDE (horizontal display end)
registers. Fix the timings calculation, and take this into account in
the mode validation.

This fixes a visible horizontal offset in the image with VGA monitors.
HDMI monitors seem to be generally more tolerant to incorrect timings,
but may be affected too.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 20 
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c 
b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
index 5672830ca184..ee6ba74627a2 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
@@ -215,6 +215,7 @@ static void rcar_du_crtc_set_display_timing(struct 
rcar_du_crtc *rcrtc)
const struct drm_display_mode *mode = &rcrtc->crtc.state->adjusted_mode;
struct rcar_du_device *rcdu = rcrtc->dev;
unsigned long mode_clock = mode->clock * 1000;
+   unsigned int hdse_offset;
u32 dsmr;
u32 escr;
 
@@ -298,10 +299,15 @@ static void rcar_du_crtc_set_display_timing(struct 
rcar_du_crtc *rcrtc)
 | DSMR_DIPM_DISP | DSMR_CSPM;
rcar_du_crtc_write(rcrtc, DSMR, dsmr);
 
+   hdse_offset = 19;
+   if (rcrtc->group->cmms_mask & BIT(rcrtc->index % 2))
+   hdse_offset += 25;
+
/* Display timings */
-   rcar_du_crtc_write(rcrtc, HDSR, mode->htotal - mode->hsync_start - 19);
+   rcar_du_crtc_write(rcrtc, HDSR, mode->htotal - mode->hsync_start -
+   hdse_offset);
rcar_du_crtc_write(rcrtc, HDER, mode->htotal - mode->hsync_start +
-   mode->hdisplay - 19);
+   mode->hdisplay - hdse_offset);
rcar_du_crtc_write(rcrtc, HSWR, mode->hsync_end -
mode->hsync_start - 1);
rcar_du_crtc_write(rcrtc, HCR,  mode->htotal - 1);
@@ -836,6 +842,7 @@ rcar_du_crtc_mode_valid(struct drm_crtc *crtc,
struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
struct rcar_du_device *rcdu = rcrtc->dev;
bool interlaced = mode->flags & DRM_MODE_FLAG_INTERLACE;
+   unsigned int min_sync_porch;
unsigned int vbp;
 
if (interlaced && !rcar_du_has(rcdu, RCAR_DU_FEATURE_INTERLACED))
@@ -843,9 +850,14 @@ rcar_du_crtc_mode_valid(struct drm_crtc *crtc,
 
/*
 * The hardware requires a minimum combined horizontal sync and back
-* porch of 20 pixels and a minimum vertical back porch of 3 lines.
+* porch of 20 pixels (when CMM isn't used) or 45 pixels (when CMM is
+* used), and a minimum vertical back porch of 3 lines.
 */
-   if (mode->htotal - mode->hsync_start < 20)
+   min_sync_porch = 20;
+   if (rcrtc->group->cmms_mask & BIT(rcrtc->index % 2))
+   min_sync_porch += 25;
+
+   if (mode->htotal - mode->hsync_start < min_sync_porch)
return MODE_HBLANK_NARROW;
 
vbp = (mode->vtotal - mode->vsync_end) / (interlaced ? 2 : 1);

base-commit: c18c889bb5e014e144716044991112f16833
prerequisite-patch-id: dc9121a1b85ea05bf3eae2b0ac2168d47101ee87
-- 
Regards,

Laurent Pinchart



Re: [PATCH v4.5 12/14] dt-bindings: msm/dp: Add bindings for HDCP registers

2021-11-29 Thread Rob Herring
On Mon, 15 Nov 2021 20:21:48 +, Sean Paul wrote:
> From: Sean Paul 
> 
> This patch adds the bindings for the MSM DisplayPort HDCP registers
> which are required to write the HDCP key into the display controller as
> well as the registers to enable HDCP authentication/key
> exchange/encryption.
> 
> We'll use a new compatible string for this since the fields are optional.
> 
> Cc: Rob Herring 
> Cc: Stephen Boyd 
> Signed-off-by: Sean Paul 
> Link: 
> https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-13-s...@poorly.run
>  #v1
> Link: 
> https://patchwork.freedesktop.org/patch/msgid/20210915203834.1439-13-s...@poorly.run
>  #v2
> Link: 
> https://patchwork.freedesktop.org/patch/msgid/20211001151145.55916-13-s...@poorly.run
>  #v3
> Link: 
> https://patchwork.freedesktop.org/patch/msgid/20211105030434.2828845-13-s...@poorly.run
>  #v4
> 
> Changes in v2:
> -Drop register range names (Stephen)
> -Fix yaml errors (Rob)
> Changes in v3:
> -Add new compatible string for dp-hdcp
> -Add descriptions to reg
> -Add minItems/maxItems to reg
> -Make reg depend on the new hdcp compatible string
> Changes in v4:
> -Rebase on Bjorn's multi-dp patchset
> Changes in v4.5:
> -Remove maxItems from reg (Rob)
> -Remove leading zeros in example (Rob)
> ---
>  .../devicetree/bindings/display/msm/dp-controller.yaml | 7 ++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
> 

Reviewed-by: Rob Herring 


Re: [PATCH v1 1/2] dt-bindings: sharp,lq101r1sx01: Add compatible for LQ101R1SX03

2021-11-29 Thread Rob Herring
On Sun, Nov 14, 2021 at 11:07:16PM +0300, Dmitry Osipenko wrote:
> From: Anton Bambura 
> 
> LQ101R1SX03 is compatible with LQ101R1SX01, document it.

Then sounds like '"sharp,lq101r1sx03", "sharp,lq101r1sx01"' would be the 
appropriate compatible value. Do that, and you don't need a driver 
change.

> 
> Signed-off-by: Anton Bambura 
> ---
>  .../devicetree/bindings/display/panel/sharp,lq101r1sx01.yaml  | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git 
> a/Documentation/devicetree/bindings/display/panel/sharp,lq101r1sx01.yaml 
> b/Documentation/devicetree/bindings/display/panel/sharp,lq101r1sx01.yaml
> index a679d3647dbd..f7514eb9ebda 100644
> --- a/Documentation/devicetree/bindings/display/panel/sharp,lq101r1sx01.yaml
> +++ b/Documentation/devicetree/bindings/display/panel/sharp,lq101r1sx01.yaml
> @@ -30,7 +30,9 @@ allOf:
>  
>  properties:
>compatible:
> -const: sharp,lq101r1sx01
> +enum:
> +  - sharp,lq101r1sx01
> +  - sharp,lq101r1sx03
>  
>reg: true
>power-supply: true
> -- 
> 2.33.1
> 
> 


Re: [PATCH v1 1/2] dt-bindings: display: simple: Add HannStar HSD101PWW2

2021-11-29 Thread Rob Herring
On Sun, 14 Nov 2021 23:04:30 +0300, Dmitry Osipenko wrote:
> From: Svyatoslav Ryhel 
> 
> Add HannStar HSD101PWW2 10.1" WXGA (1280x800) TFT-LCD LVDS panel
> to the list of compatibles.
> 
> Signed-off-by: Svyatoslav Ryhel 
> ---
>  .../devicetree/bindings/display/panel/panel-simple.yaml | 2 ++
>  1 file changed, 2 insertions(+)
> 

Acked-by: Rob Herring 


Re: [PATCH] drm/msm/gpu: Don't allow zero fence_id

2021-11-29 Thread Rob Clark
On Mon, Nov 29, 2021 at 10:18 AM Rob Clark  wrote:
>
> From: Rob Clark 
>
> Elsewhere we treat zero as "no fence" and __msm_gem_submit_destroy()
> skips removal from fence_idr.  We could alternately change this to use
> negative values for "no fence" but I think it is more clear to not allow
> zero as a valid fence_id.
>

probably should have added:

Fixes: a61acbbe9cf8 ("drm/msm: Track "seqno" fences by idr")

> Signed-off-by: Rob Clark 
> ---
>  drivers/gpu/drm/msm/msm_gem_submit.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c 
> b/drivers/gpu/drm/msm/msm_gem_submit.c
> index 282628d6b72c..6cfa984dee6a 100644
> --- a/drivers/gpu/drm/msm/msm_gem_submit.c
> +++ b/drivers/gpu/drm/msm/msm_gem_submit.c
> @@ -881,7 +881,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void 
> *data,
>  * to the underlying fence.
>  */
> submit->fence_id = idr_alloc_cyclic(&queue->fence_idr,
> -   submit->user_fence, 0, INT_MAX, GFP_KERNEL);
> +   submit->user_fence, 1, INT_MAX, GFP_KERNEL);
> if (submit->fence_id < 0) {
> ret = submit->fence_id = 0;
> submit->fence_id = 0;
> --
> 2.33.1
>


Re: [PATCH 6/6] Documentation/gpu: Add DC glossary

2021-11-29 Thread ydirson
Hi Rodrigo,

That will really be helpful!

I know drawing the line is a difficult problem (and can even make things
harder when searching), but maybe it would make sense to keep generic
acronyms not specific to amdgpu in a separate list.  I bet a number of
them would be useful in the scope of other drm drivers (e.g. CRTC, DCC,
MST), and some are not restricted to the drm subsystem at all (e.g. FEC,
LUT), but still have value as not necessarily easy to look up.

Maybe "DC glossary" should just be "Glossary", since quite some entries
help to read adm/amdgpu/ too.  Which brings me to the result of my recent
searches as suggested entries:

 KIQ (Kernel Interface Queue), MQD (memory queue descriptor), HQD (hardware
 queue descriptor), EOP (still no clue :)

Maybe some more specific ones just to be spelled out in clear where they
are used ?  KCQ (compute queue?), KGQ (gfx queue?)

More suggestions inlined.

Best regards,
-- 
Yann

> On Thu, Nov 25, 2021 at 10:40 AM Rodrigo Siqueira
>  wrote:
> >
> > In the DC driver, we have multiple acronyms that are not obvious
> > most of
> > the time. This commit introduces a DC glossary in order to make it
> > easier to navigate through our driver.
> >
> > Signed-off-by: Rodrigo Siqueira 
> > ---
> >  Documentation/gpu/amdgpu-dc/amdgpu-dc.rst   |   2 +-
> >  Documentation/gpu/amdgpu-dc/dc-glossary.rst | 257
> >  
> >  2 files changed, 258 insertions(+), 1 deletion(-)
> >  create mode 100644 Documentation/gpu/amdgpu-dc/dc-glossary.rst
> >
> > diff --git a/Documentation/gpu/amdgpu-dc/amdgpu-dc.rst
> > b/Documentation/gpu/amdgpu-dc/amdgpu-dc.rst
> > index 2e45e83d9a2a..15405c43786a 100644
> > --- a/Documentation/gpu/amdgpu-dc/amdgpu-dc.rst
> > +++ b/Documentation/gpu/amdgpu-dc/amdgpu-dc.rst
> > @@ -26,4 +26,4 @@ table of content:
> > amdgpu-dcn-overview.rst
> > amdgpu-dm.rst
> > amdgpu-dc-debug.rst
> > -
> > +   dc-glossary.rst
> > diff --git a/Documentation/gpu/amdgpu-dc/dc-glossary.rst
> > b/Documentation/gpu/amdgpu-dc/dc-glossary.rst
> > new file mode 100644
> > index ..48698fc1799f
> > --- /dev/null
> > +++ b/Documentation/gpu/amdgpu-dc/dc-glossary.rst
> > @@ -0,0 +1,257 @@
> > +===
> > +DC Glossary
> > +===
> > +
> > +.. glossary::
> > +
> > +ABM
> > +  Adaptive Backlight Modulation
> > +
> > +APU
> > +  Accelerated Processing Unit
> > +
> > +ASIC
> > +  Application-Specific Integrated Circuit
> > +
> > +ASSR
> > +  Alternate Scrambler Seed Reset
> > +
> > +AZ
> > +  Azalia (HD audio DMA engine)
> > +
> > +BPC
> > +  Bits Per Colour/Component
> > +
> > +BPP
> > +  Bits Per Pixel
> > +
> > +Clocks
> > +  * PCLK: Pixel Clock
> > +  * SYMCLK: Symbol Clock
> > +  * SOCCLK: GPU Engine Clock
> > +  * DISPCLK: Display Clock
> > +  * DPPCLK: DPP Clock
> > +  * DCFCLK: Display Controller Fabric Clock
> > +  * REFCLK: Real Time Reference Clock
> > +  * PPLL: Pixel PLL
> > +  * FCLK: Fabric Clock
> > +  * MCLK: Memory Clock
> > +  * CPLIB: Content Protection Library
> 
> CPLIB is not a clock.  It should be split out as its own item.
> 
> > +
> > +CRC
> > +  Cyclic Redundancy Check
> > +
> > +CRTC
> > +  Cathode Ray Tube Controller - commonly called "Controller" -
> > Generates
> > +  raw stream of pixels, clocked at pixel clock
> > +
> > +CVT
> > +  Coordinated Video Timings
> > +
> > +DAL
> > +  Display Abstraction layer

I recall this as the old name for DC, maybe this should be mentioned ?

> > +
> > +DC (Software)
> > +  Display Core
> > +
> > +DC (Hardware)
> > +  Display Controller
> > +
> > +DCC
> > +  Delta Colour Compression
> > +
> > +DCE
> > +  Display Controller Engine
> > +
> > +DCHUB
> > +  Display Controller Hub
> > +
> > +ARB
> > +  Arbiter
> > +
> > +VTG
> > +  Vertical Timing Generator
> > +
> > +DCN
> > +  Display Core Next
> > +
> > +DCCG
> > +  Display Clock Generator block
> > +
> > +DDC
> > +  Display Data Channel
> > +
> > +DFS
> > +  Digital Frequency Synthesizer
> > +
> > +DIO
> > +  Display IO
> > +
> > +DPP
> > +  Display Pipes and Planes
> > +
> > +DSC
> > +  Display Stream Compression (Reduce the amount of bits to
> > represent pixel
> > +  count while at the same pixel clock)
> > +
> > +dGPU
> > +  discrete GPU
> > +
> > +DMIF
> > +  Display Memory Interface
> > +
> > +DML
> > +  Display Mode Library
> > +
> > +DMCU
> > +  Display Micro Controller Unit
> > +
> > +DMCUB
> > +  Display Micro-Controller Unit, version B
> 
> Make Micro Controller vs. Micro-Controller consistent for these.
> 
> > +
> > +DPCD
> > +  DisplayPort Configuration Data
> > +
> > +DPM(S)
> > +  Display Power Management (Signaling)
> > +
> > +DRR
> > +  Dynamic Refresh Rate
> > +
> > +DWB
> > +  Displa

[PATCH v7] drm/i915: Update error capture code to avoid using the current vma state

2021-11-29 Thread Thomas Hellström
With asynchronous migrations, the vma state may be several migrations
ahead of the state that matches the request we're capturing.
Address that by introducing an i915_vma_snapshot structure that
can be used to snapshot relevant state at request submission.
In order to make sure we access the correct memory, the snapshots take
references on relevant sg-tables and memory regions.

Also move the capture list allocation out of the fence signaling
critical path and use the CONFIG_DRM_I915_CAPTURE_ERROR define to
avoid compiling in members and functions used for error capture
when they're not used.

Finally, Introduce lockdep annotation.

v4:
- Break out the capture allocation mode change to a separate patch.
v5:
- Fix compilation error in the !CONFIG_DRM_I915_CAPTURE_ERROR case
  (kernel test robot)
v6:
- Use #if IS_ENABLED() instead of #ifdef to match driver style.
- Move yet another change of allocation mode to the separate patch.
- Commit message rework due to patch reordering.
v7:
- Adjust for removal of region refcounting.

Signed-off-by: Thomas Hellström 
Reviewed-by: Ramalingam C 
---
 drivers/gpu/drm/i915/Makefile |   1 +
 .../gpu/drm/i915/gem/i915_gem_execbuffer.c| 135 +++---
 drivers/gpu/drm/i915/gt/intel_engine_cs.c |   8 +-
 drivers/gpu/drm/i915/i915_gpu_error.c | 176 +-
 drivers/gpu/drm/i915/i915_request.c   |  63 +--
 drivers/gpu/drm/i915/i915_request.h   |  20 +-
 drivers/gpu/drm/i915/i915_vma_snapshot.c  | 134 +
 drivers/gpu/drm/i915/i915_vma_snapshot.h  | 112 +++
 8 files changed, 554 insertions(+), 95 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/i915_vma_snapshot.c
 create mode 100644 drivers/gpu/drm/i915/i915_vma_snapshot.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 3f57e85d4846..3b5857da4123 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -173,6 +173,7 @@ i915-y += \
  i915_trace_points.o \
  i915_ttm_buddy_manager.o \
  i915_vma.o \
+ i915_vma_snapshot.o \
  intel_wopcm.o
 
 # general-purpose microcontroller (GuC) support
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c 
b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
index 9f7c6ecadb90..6a0ed537c199 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
@@ -29,6 +29,7 @@
 #include "i915_gem_ioctls.h"
 #include "i915_trace.h"
 #include "i915_user_extensions.h"
+#include "i915_vma_snapshot.h"
 
 struct eb_vma {
struct i915_vma *vma;
@@ -307,11 +308,15 @@ struct i915_execbuffer {
 
struct eb_fence *fences;
unsigned long num_fences;
+#if IS_ENABLED(CONFIG_DRM_I915_CAPTURE_ERROR)
+   struct i915_capture_list *capture_lists[MAX_ENGINE_INSTANCE + 1];
+#endif
 };
 
 static int eb_parse(struct i915_execbuffer *eb);
 static int eb_pin_engine(struct i915_execbuffer *eb, bool throttle);
 static void eb_unpin_engine(struct i915_execbuffer *eb);
+static void eb_capture_release(struct i915_execbuffer *eb);
 
 static inline bool eb_use_cmdparser(const struct i915_execbuffer *eb)
 {
@@ -1054,6 +1059,7 @@ static void eb_release_vmas(struct i915_execbuffer *eb, 
bool final)
i915_vma_put(vma);
}
 
+   eb_capture_release(eb);
eb_unpin_engine(eb);
 }
 
@@ -1891,36 +1897,113 @@ eb_find_first_request_added(struct i915_execbuffer *eb)
return NULL;
 }
 
-static int eb_move_to_gpu(struct i915_execbuffer *eb)
+#if IS_ENABLED(CONFIG_DRM_I915_CAPTURE_ERROR)
+
+/* Stage with GFP_KERNEL allocations before we enter the signaling critical 
path */
+static void eb_capture_stage(struct i915_execbuffer *eb)
 {
const unsigned int count = eb->buffer_count;
-   unsigned int i = count;
-   int err = 0, j;
+   unsigned int i = count, j;
+   struct i915_vma_snapshot *vsnap;
 
while (i--) {
struct eb_vma *ev = &eb->vma[i];
struct i915_vma *vma = ev->vma;
unsigned int flags = ev->flags;
-   struct drm_i915_gem_object *obj = vma->obj;
 
-   assert_vma_held(vma);
+   if (!(flags & EXEC_OBJECT_CAPTURE))
+   continue;
 
-   if (flags & EXEC_OBJECT_CAPTURE) {
+   vsnap = i915_vma_snapshot_alloc(GFP_KERNEL);
+   if (!vsnap)
+   continue;
+
+   i915_vma_snapshot_init(vsnap, vma, "user");
+   for_each_batch_create_order(eb, j) {
struct i915_capture_list *capture;
 
-   for_each_batch_create_order(eb, j) {
-   if (!eb->requests[j])
-   break;
+   capture = kmalloc(sizeof(*capture), GFP_KERNEL);
+   if (!capture)
+   continue;
 
-  

Re: [PATCH] dt-bindings: display: sync formats with simplefb.h

2021-11-29 Thread Rob Herring
On Mon, 08 Nov 2021 19:33:22 +0100, David Heidelberg wrote:
> Sync all formats from simplefb.h into documentation.
> 
> Signed-off-by: David Heidelberg 
> ---
>  .../bindings/display/simple-framebuffer.yaml | 12 
>  1 file changed, 12 insertions(+)
> 

Applied, thanks!


Re: [PATCH 6/6] Documentation/gpu: Add DC glossary

2021-11-29 Thread Alex Deucher
On Thu, Nov 25, 2021 at 10:40 AM Rodrigo Siqueira
 wrote:
>
> In the DC driver, we have multiple acronyms that are not obvious most of
> the time. This commit introduces a DC glossary in order to make it
> easier to navigate through our driver.
>
> Signed-off-by: Rodrigo Siqueira 
> ---
>  Documentation/gpu/amdgpu-dc/amdgpu-dc.rst   |   2 +-
>  Documentation/gpu/amdgpu-dc/dc-glossary.rst | 257 
>  2 files changed, 258 insertions(+), 1 deletion(-)
>  create mode 100644 Documentation/gpu/amdgpu-dc/dc-glossary.rst
>
> diff --git a/Documentation/gpu/amdgpu-dc/amdgpu-dc.rst 
> b/Documentation/gpu/amdgpu-dc/amdgpu-dc.rst
> index 2e45e83d9a2a..15405c43786a 100644
> --- a/Documentation/gpu/amdgpu-dc/amdgpu-dc.rst
> +++ b/Documentation/gpu/amdgpu-dc/amdgpu-dc.rst
> @@ -26,4 +26,4 @@ table of content:
> amdgpu-dcn-overview.rst
> amdgpu-dm.rst
> amdgpu-dc-debug.rst
> -
> +   dc-glossary.rst
> diff --git a/Documentation/gpu/amdgpu-dc/dc-glossary.rst 
> b/Documentation/gpu/amdgpu-dc/dc-glossary.rst
> new file mode 100644
> index ..48698fc1799f
> --- /dev/null
> +++ b/Documentation/gpu/amdgpu-dc/dc-glossary.rst
> @@ -0,0 +1,257 @@
> +===
> +DC Glossary
> +===
> +
> +.. glossary::
> +
> +ABM
> +  Adaptive Backlight Modulation
> +
> +APU
> +  Accelerated Processing Unit
> +
> +ASIC
> +  Application-Specific Integrated Circuit
> +
> +ASSR
> +  Alternate Scrambler Seed Reset
> +
> +AZ
> +  Azalia (HD audio DMA engine)
> +
> +BPC
> +  Bits Per Colour/Component
> +
> +BPP
> +  Bits Per Pixel
> +
> +Clocks
> +  * PCLK: Pixel Clock
> +  * SYMCLK: Symbol Clock
> +  * SOCCLK: GPU Engine Clock
> +  * DISPCLK: Display Clock
> +  * DPPCLK: DPP Clock
> +  * DCFCLK: Display Controller Fabric Clock
> +  * REFCLK: Real Time Reference Clock
> +  * PPLL: Pixel PLL
> +  * FCLK: Fabric Clock
> +  * MCLK: Memory Clock
> +  * CPLIB: Content Protection Library

CPLIB is not a clock.  It should be split out as its own item.

> +
> +CRC
> +  Cyclic Redundancy Check
> +
> +CRTC
> +  Cathode Ray Tube Controller - commonly called "Controller" - Generates
> +  raw stream of pixels, clocked at pixel clock
> +
> +CVT
> +  Coordinated Video Timings
> +
> +DAL
> +  Display Abstraction layer
> +
> +DC (Software)
> +  Display Core
> +
> +DC (Hardware)
> +  Display Controller
> +
> +DCC
> +  Delta Colour Compression
> +
> +DCE
> +  Display Controller Engine
> +
> +DCHUB
> +  Display Controller Hub
> +
> +ARB
> +  Arbiter
> +
> +VTG
> +  Vertical Timing Generator
> +
> +DCN
> +  Display Core Next
> +
> +DCCG
> +  Display Clock Generator block
> +
> +DDC
> +  Display Data Channel
> +
> +DFS
> +  Digital Frequency Synthesizer
> +
> +DIO
> +  Display IO
> +
> +DPP
> +  Display Pipes and Planes
> +
> +DSC
> +  Display Stream Compression (Reduce the amount of bits to represent 
> pixel
> +  count while at the same pixel clock)
> +
> +dGPU
> +  discrete GPU
> +
> +DMIF
> +  Display Memory Interface
> +
> +DML
> +  Display Mode Library
> +
> +DMCU
> +  Display Micro Controller Unit
> +
> +DMCUB
> +  Display Micro-Controller Unit, version B

Make Micro Controller vs. Micro-Controller consistent for these.

> +
> +DPCD
> +  DisplayPort Configuration Data
> +
> +DPM(S)
> +  Display Power Management (Signaling)
> +
> +DRR
> +  Dynamic Refresh Rate
> +
> +DWB
> +  Display writeback
> +
> +ECP
> +  Enhanced Content Protection
> +
> +FB
> +  Frame Buffer
> +
> +FBC
> +  Frame Buffer Compression
> +
> +FEC
> +  Forward Error Correction
> +
> +FRL
> +  Fixed Rate Link
> +
> +GCO
> +  Graphical Controller Object
> +
> +GMC
> +  Graphic Memory Controller
> +
> +GSL
> +  Global Swap Lock
> +
> +iGPU
> +  integrated GPU
> +
> +IH
> +  Interrupt Handler
> +
> +ISR
> +  Interrupt Service Request
> +
> +ISV
> +  Independent Software Vendor
> +
> +KMD
> +  Kernel Mode Driver
> +
> +LB
> +  Line Buffer
> +
> +LFC
> +  Low Framerate Compensation
> +
> +LTTPR
> +  Link Training Tunable Phy Repeater
> +
> +LUT
> +  Lookup Table
> +
> +MALL
> +  Memory Access at Last Level
> +
> +MC
> +  Memory Controller
> +
> +MPC
> +  Multiple pipes and plane combine
> +
> +MPO
> +  Multi Plane Overlay
> +
> +MST
> +  Multi Stream Transport
> +
> +NBP State
> +  Northbridge Power State
> +
> +NBIO
> +  North Bridge Input/Output
> +
> +ODM
> +  Output Data Mapping
> +
> +OPM
> +  Output Protection Manager
> +
> +OPP
> +  Output Plane Processor
> +
> +OPTC
> +  Output Pipe Timing Combiner
> +
> +O

[Bug 211277] sometimes crash at s2ram-wake (Ryzen 3500U): amdgpu, drm, commit_tail, amdgpu_dm_atomic_commit_tail

2021-11-29 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=211277

--- Comment #86 from James Zhu (jam...@amd.com) ---
Hi @kolAflash, thanks so much for your effort on this verification!
Would you mind help apply those patches on 5.12 stable to check also?
it should be automatically merged.  Thanks! James

-- 
You may reply to this email to add a comment.

You are receiving this mail because:
You are watching the assignee of the bug.

Re: [PATCH 1/3] drm/simpledrm: Bind to OF framebuffers in /chosen

2021-11-29 Thread Rob Herring
On Fri, Nov 19, 2021 at 9:24 PM Hector Martin  wrote:
>
> On 18/11/2021 18.19, Thomas Zimmermann wrote:
> > Hi
> >
> > Am 17.11.21 um 15:58 schrieb Hector Martin:
> >> @@ -897,5 +898,21 @@ static struct platform_driver 
> >> simpledrm_platform_driver = {
> >>
> >>module_platform_driver(simpledrm_platform_driver);
> >>
> >> +static int __init simpledrm_init(void)
> >> +{
> >> +struct device_node *np;
> >> +
> >> +if (IS_ENABLED(CONFIG_OF_ADDRESS) && of_chosen) {
> >> +for_each_child_of_node(of_chosen, np) {
> >> +if (of_device_is_compatible(np, "simple-framebuffer"))
> >> +of_platform_device_create(np, NULL, NULL);
> >> +}
> >> +}
> >> +
> >> +return 0;
> >> +}
> >> +
> >> +fs_initcall(simpledrm_init);
> >> +
> >
> > Simpledrm is just a driver, but this is platform setup code. Why is this
> > code located here and not under arch/ or drivers/firmware/?
> >
> > I know that other drivers do similar things, it doesn't seem to belong here.
>
> This definitely doesn't belong in either of those, since it is not arch-
> or firmware-specific. It is implementing support for the standard
> simple-framebuffer OF binding, which specifies that it must be located
> within the /chosen node (and thus the default OF setup code won't do the
> matching for you); this applies to all OF platforms [1]
>
> Adding Rob; do you think this should move from simplefb/simpledrm to
> common OF code? (where?)

of_platform_default_populate_init() should work.


[PATCH] drm: fix error found in some cases after the patch d1af5cd86997

2021-11-29 Thread Claudio Suarez
The patch d1af5cd86997 ("drm: get rid of DRM_DEBUG_* log
calls in drm core, files drm_a*.c") fails when the drm_device
cannot be found in the parameter plane_state. Fix it.

Reported-by: kernel test robot 
Fixes: d1af5cd86997 ("drm: get rid of DRM_DEBUG_* log calls in drm core, files 
drm_a*.c")
Signed-off-by: Claudio Suarez 
---
 drivers/gpu/drm/drm_atomic_helper.c | 12 +---
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
b/drivers/gpu/drm/drm_atomic_helper.c
index aef2fbd676e5..8bd4472d7949 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -312,7 +312,7 @@ update_connector_routing(struct drm_atomic_state *state,
 
if (!new_connector_state->crtc) {
drm_dbg_atomic(connector->dev, "Disabling [CONNECTOR:%d:%s]\n",
-   connector->base.id, connector->name);
+  connector->base.id, connector->name);
 
set_best_encoder(state, new_connector_state, NULL);
 
@@ -805,6 +805,7 @@ int drm_atomic_helper_check_plane_state(struct 
drm_plane_state *plane_state,
bool can_update_disabled)
 {
struct drm_framebuffer *fb = plane_state->fb;
+   struct drm_device *dev = plane_state->plane ? plane_state->plane->dev : 
NULL;
struct drm_rect *src = &plane_state->src;
struct drm_rect *dst = &plane_state->dst;
unsigned int rotation = plane_state->rotation;
@@ -828,8 +829,7 @@ int drm_atomic_helper_check_plane_state(struct 
drm_plane_state *plane_state,
}
 
if (!crtc_state->enable && !can_update_disabled) {
-   drm_dbg_kms(plane_state->crtc->dev,
-  "Cannot update plane of a disabled CRTC.\n");
+   drm_dbg_kms(dev, "Cannot update plane of a disabled CRTC.\n");
return -EINVAL;
}
 
@@ -839,8 +839,7 @@ int drm_atomic_helper_check_plane_state(struct 
drm_plane_state *plane_state,
hscale = drm_rect_calc_hscale(src, dst, min_scale, max_scale);
vscale = drm_rect_calc_vscale(src, dst, min_scale, max_scale);
if (hscale < 0 || vscale < 0) {
-   drm_dbg_kms(plane_state->crtc->dev,
-  "Invalid scaling of plane\n");
+   drm_dbg_kms(dev, "Invalid scaling of plane\n");
drm_rect_debug_print("src: ", &plane_state->src, true);
drm_rect_debug_print("dst: ", &plane_state->dst, false);
return -ERANGE;
@@ -864,8 +863,7 @@ int drm_atomic_helper_check_plane_state(struct 
drm_plane_state *plane_state,
return 0;
 
if (!can_position && !drm_rect_equals(dst, &clip)) {
-   drm_dbg_kms(plane_state->crtc->dev,
-  "Plane must cover entire CRTC\n");
+   drm_dbg_kms(dev, "Plane must cover entire CRTC\n");
drm_rect_debug_print("dst: ", dst, false);
drm_rect_debug_print("clip: ", &clip, false);
return -EINVAL;
-- 
2.33.0





[Bug 211277] sometimes crash at s2ram-wake (Ryzen 3500U): amdgpu, drm, commit_tail, amdgpu_dm_atomic_commit_tail

2021-11-29 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=211277

--- Comment #85 from kolAflash (kolafl...@kolahilft.de) ---
(In reply to James Zhu from comment #77)
> Created attachment 299697 [details]
> backport patch for 5.10 stable.
> 
> Hi @kolAflash, before I send out them to public for review,. could you help
> take a test? Thanks so much! James

Works excellent!

Tested with Linux-5.10.82 on Debian-11.

-- 
You may reply to this email to add a comment.

You are receiving this mail because:
You are watching the assignee of the bug.

Re: [PATCH] drm/etnaviv: constify static struct cooling_ops

2021-11-29 Thread Christian Gmeiner
Am So., 28. Nov. 2021 um 21:20 Uhr schrieb Rikard Falkeborn
:
>
> The only usage of cooling_ops is to pass its address to
> thermal_of_cooling_device_register(), which takes a pointer to const
> struct thermal_cooling_device_ops as input. Make it const to allow the
> compiler to put it in read-only memory.
>
> Signed-off-by: Rikard Falkeborn 

Reviewed-by: Christian Gmeiner 

> ---
>  drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c 
> b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
> index 06bde46df451..37018bc55810 100644
> --- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
> +++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
> @@ -1658,7 +1658,7 @@ etnaviv_gpu_cooling_set_cur_state(struct 
> thermal_cooling_device *cdev,
> return 0;
>  }
>
> -static struct thermal_cooling_device_ops cooling_ops = {
> +static const struct thermal_cooling_device_ops cooling_ops = {
> .get_max_state = etnaviv_gpu_cooling_get_max_state,
> .get_cur_state = etnaviv_gpu_cooling_get_cur_state,
> .set_cur_state = etnaviv_gpu_cooling_set_cur_state,
> --
> 2.34.1
>


-- 
greets
--
Christian Gmeiner, MSc

https://christian-gmeiner.info/privacypolicy


[PATCH] drm/msm/gpu: Don't allow zero fence_id

2021-11-29 Thread Rob Clark
From: Rob Clark 

Elsewhere we treat zero as "no fence" and __msm_gem_submit_destroy()
skips removal from fence_idr.  We could alternately change this to use
negative values for "no fence" but I think it is more clear to not allow
zero as a valid fence_id.

Signed-off-by: Rob Clark 
---
 drivers/gpu/drm/msm/msm_gem_submit.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c 
b/drivers/gpu/drm/msm/msm_gem_submit.c
index 282628d6b72c..6cfa984dee6a 100644
--- a/drivers/gpu/drm/msm/msm_gem_submit.c
+++ b/drivers/gpu/drm/msm/msm_gem_submit.c
@@ -881,7 +881,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
 * to the underlying fence.
 */
submit->fence_id = idr_alloc_cyclic(&queue->fence_idr,
-   submit->user_fence, 0, INT_MAX, GFP_KERNEL);
+   submit->user_fence, 1, INT_MAX, GFP_KERNEL);
if (submit->fence_id < 0) {
ret = submit->fence_id = 0;
submit->fence_id = 0;
-- 
2.33.1



Re: [PATCH v4] dma-buf: system_heap: Use 'for_each_sgtable_sg' in pages free flow

2021-11-29 Thread John Stultz
On Thu, Nov 25, 2021 at 11:48 PM  wrote:
>
> From: Guangming 
>
> For previous version, it uses 'sg_table.nent's to traverse sg_table in pages
> free flow.
> However, 'sg_table.nents' is reassigned in 'dma_map_sg', it means the number 
> of
> created entries in the DMA adderess space.
> So, use 'sg_table.nents' in pages free flow will case some pages can't be 
> freed.
>
> Here we should use sg_table.orig_nents to free pages memory, but use the
> sgtable helper 'for each_sgtable_sg'(, instead of the previous rather common
> helper 'for_each_sg' which maybe cause memory leak) is much better.
>
> Fixes: d963ab0f15fb0 ("dma-buf: system_heap: Allocate higher order pages if 
> available")
> Signed-off-by: Guangming 
> Reviewed-by: Robin Murphy 
> Cc:  # 5.11.*

Thanks so much for catching this and sending in all the revisions!

Reviewed-by: John Stultz 


Re: [PATCH v2 0/3] drm: Make DRM hashtable legacy

2021-11-29 Thread Alex Deucher
On Mon, Nov 29, 2021 at 4:48 AM Thomas Zimmermann  wrote:
>
> Clean up the last non-legacy users of DRM's hashtable code and put
> the code behind CONFIG_DRM_LEGACY.
>
> TTM only includes the header file, but does not use the hashtable.
> The vmwgfx driver uses the hashtable internally. Copy the DRM code
> into the driver. A later patchset should probably update vmwgfx to
> use Linux' hashtable. Finally, make the core hashtable code legacy.
>
> Built with/without CONFIG_DRM_LEGACY set.
>
> v2:
> * add TODO item for updating vmwgfx (Sam)
>
> Thomas Zimmermann (3):
>   drm/ttm: Don't include drm_hashtab.h
>   drm/vmwgfx: Copy DRM hash-table code into driver
>   drm: Declare hashtable as legacy

Series is:
Acked-by: Alex Deucher 

>
>  Documentation/gpu/todo.rst|  11 +
>  drivers/gpu/drm/Makefile  |   6 +-
>  drivers/gpu/drm/drm_hashtab.c |  10 +-
>  drivers/gpu/drm/drm_legacy.h  |  40 +++-
>  drivers/gpu/drm/vmwgfx/Makefile   |   2 +-
>  drivers/gpu/drm/vmwgfx/ttm_object.c   |  52 ++---
>  drivers/gpu/drm/vmwgfx/ttm_object.h   |   3 +-
>  drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c|  24 +--
>  drivers/gpu/drm/vmwgfx/vmwgfx_drv.c   |   2 +-
>  drivers/gpu/drm/vmwgfx/vmwgfx_drv.h   |   6 +-
>  drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c   |   2 +-
>  drivers/gpu/drm/vmwgfx/vmwgfx_hashtab.c   | 199 ++
>  .../gpu/drm/vmwgfx/vmwgfx_hashtab.h   |  54 ++---
>  drivers/gpu/drm/vmwgfx/vmwgfx_validation.c|  22 +-
>  drivers/gpu/drm/vmwgfx/vmwgfx_validation.h|   7 +-
>  include/drm/drm_device.h  |   5 +-
>  include/drm/drm_legacy.h  |  15 +-
>  include/drm/ttm/ttm_bo_api.h  |   1 -
>  18 files changed, 358 insertions(+), 103 deletions(-)
>  create mode 100644 drivers/gpu/drm/vmwgfx/vmwgfx_hashtab.c
>  rename include/drm/drm_hashtab.h => drivers/gpu/drm/vmwgfx/vmwgfx_hashtab.h 
> (58%)
>
>
> base-commit: 6a8f90ec433e2f5de5fc16d7a4839771b7027cc0
> --
> 2.34.0
>


Re: [RE]: [PATCH v3 10/10] vfio/ccw: Move the lifecycle of the struct vfio_ccw_private to the mdev

2021-11-29 Thread Eric Farman
On Wed, 2021-11-24 at 12:25 +, Liu, Yi L wrote:
> > From: Jason Gunthorpe 
> > Sent: Fri, 1 Oct 2021 14:52:51 -0300
> > 
> > The css_driver's main purpose is to create/destroy the mdev and
> > relay the
> > shutdown, irq, sch_event, and chp_event css_driver ops to the
> > single
> > created vfio_device, if it exists.
> > 
> > Reframe the boundary where the css_driver domain switches to the
> > vfio
> > domain by using rcu to read and refcount the vfio_device out of the
> > sch's
> > drvdata. The mdev probe/remove will manage the drvdata of the
> > parent.
> > 
> > The vfio core code refcounting thus guarantees that when a
> > css_driver
> > callback is running the vfio_device is registered, simplifying the
> > understanding of the whole lifecycle.
> > 
> > Finally the vfio_ccw_private is allocated/freed during probe/remove
> > of the
> > mdev like any other vfio_device struct.
> 
> Hi Eric,
> 
> how about the status of this patch? 

Hi YiLiu,

To be honest I never got this far in the series, as the middle of the
series got into some more involved rework than I had the bandwidth to
consider. Not sure I'll be able to do anything with it before the year
end holiday, but I've noted your interest in getting this in line with
the rest of vfio_device so I don't drop it too far down the list.

Thanks,
Eric

> I found it is a good clean up to make
> vfio ccw behave same with other vfio_device users. Also, I'd like to
> do a
> clean up to consolidate the vfio_device allocation which needs the
> vfio
> ccw private allocation happen in the mdev probe. So it would be nice
> to
> build the cleanup based on this patch.
> 
> Regards,
> Yi Liu
> 
> > Signed-off-by: Jason Gunthorpe 
> > ---
> >  drivers/s390/cio/vfio_ccw_drv.c | 67 ++---
> > 
> >  drivers/s390/cio/vfio_ccw_ops.c | 40 +++--
> >  drivers/s390/cio/vfio_ccw_private.h | 23 +-
> >  3 files changed, 69 insertions(+), 61 deletions(-)
> > 
> > diff --git a/drivers/s390/cio/vfio_ccw_drv.c
> > b/drivers/s390/cio/vfio_ccw_drv.c
> > index 18ad047811d111..c5582fc9c46c9e 100644
> > --- a/drivers/s390/cio/vfio_ccw_drv.c
> > +++ b/drivers/s390/cio/vfio_ccw_drv.c
> > @@ -86,13 +86,19 @@ static void vfio_ccw_crw_todo(struct
> > work_struct *work)
> >   */
> >  static void vfio_ccw_sch_irq(struct subchannel *sch)
> >  {
> > -   struct vfio_ccw_private *private = dev_get_drvdata(&sch->dev);
> > +   struct vfio_ccw_private *private = vfio_ccw_get_priv(sch);
> > +
> > +   /* IRQ should not be delivered after the mdev is destroyed */
> > +   if (WARN_ON(!private))
> > +   return;
> >  
> > inc_irq_stat(IRQIO_CIO);
> > vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_INTERRUPT);
> > +   vfio_device_put(&private->vdev);
> >  }
> >  
> > -static struct vfio_ccw_private *vfio_ccw_alloc_private(struct
> > subchannel *sch)
> > +struct vfio_ccw_private *vfio_ccw_alloc_private(struct mdev_device
> > *mdev,
> > +   struct subchannel *sch)
> >  {
> > struct vfio_ccw_private *private;
> >  
> > @@ -100,6 +106,8 @@ static struct vfio_ccw_private
> > *vfio_ccw_alloc_private(struct subchannel *sch)
> > if (!private)
> > return ERR_PTR(-ENOMEM);
> >  
> > +   vfio_init_group_dev(&private->vdev, &mdev->dev,
> > +   &vfio_ccw_dev_ops);
> > private->sch = sch;
> > mutex_init(&private->io_mutex);
> > private->state = VFIO_CCW_STATE_CLOSED;
> > @@ -145,11 +153,12 @@ static struct vfio_ccw_private
> > *vfio_ccw_alloc_private(struct subchannel *sch)
> > kfree(private->cp.guest_cp);
> >  out_free_private:
> > mutex_destroy(&private->io_mutex);
> > +   vfio_uninit_group_dev(&private->vdev);
> > kfree(private);
> > return ERR_PTR(-ENOMEM);
> >  }
> >  
> > -static void vfio_ccw_free_private(struct vfio_ccw_private
> > *private)
> > +void vfio_ccw_free_private(struct vfio_ccw_private *private)
> >  {
> > struct vfio_ccw_crw *crw, *temp;
> >  
> > @@ -164,14 +173,14 @@ static void vfio_ccw_free_private(struct
> > vfio_ccw_private *private)
> > kmem_cache_free(vfio_ccw_io_region, private->io_region);
> > kfree(private->cp.guest_cp);
> > mutex_destroy(&private->io_mutex);
> > -   kfree(private);
> > +   vfio_uninit_group_dev(&private->vdev);
> > +   kfree_rcu(private, rcu);
> >  }
> >  
> >  static int vfio_ccw_sch_probe(struct subchannel *sch)
> >  {
> > struct pmcw *pmcw = &sch->schib.pmcw;
> > -   struct vfio_ccw_private *private;
> > -   int ret = -ENOMEM;
> > +   int ret;
> >  
> > if (pmcw->qf) {
> > dev_warn(&sch->dev, "vfio: ccw: does not support QDIO:
> > %s\n",
> > @@ -179,15 +188,9 @@ static int vfio_ccw_sch_probe(struct
> > subchannel *sch)
> > return -ENODEV;
> > }
> >  
> > -   private = vfio_ccw_alloc_private(sch);
> > -   if (IS_ERR(private))
> > -   return PTR_ERR(private);
> > -
> > -   dev_set_drvdata(&sch->dev, private);
> > -
> > -   ret = vfio_ccw_mdev_reg(s

[PATCH] drm: rcar-du: Add DSI support to rcar_du_output_name

2021-11-29 Thread Kieran Bingham
The DSI output names were not added when the DSI pipeline support was
introduced.

Add the correct labels for these outputs, and fix the sort order to
match 'enum rcar_du_output' while we are here.

Fixes: b291fdcf5114 ("drm: rcar-du: Add r8a779a0 device support")
Suggested-by: Biju Das 
Signed-off-by: Kieran Bingham 
---
 drivers/gpu/drm/rcar-du/rcar_du_drv.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c 
b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
index 5612a9e7a905..5a8131ef81d5 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
@@ -544,10 +544,12 @@ const char *rcar_du_output_name(enum rcar_du_output 
output)
static const char * const names[] = {
[RCAR_DU_OUTPUT_DPAD0] = "DPAD0",
[RCAR_DU_OUTPUT_DPAD1] = "DPAD1",
-   [RCAR_DU_OUTPUT_LVDS0] = "LVDS0",
-   [RCAR_DU_OUTPUT_LVDS1] = "LVDS1",
+   [RCAR_DU_OUTPUT_DSI0] = "DSI0",
+   [RCAR_DU_OUTPUT_DSI1] = "DSI1",
[RCAR_DU_OUTPUT_HDMI0] = "HDMI0",
[RCAR_DU_OUTPUT_HDMI1] = "HDMI1",
+   [RCAR_DU_OUTPUT_LVDS0] = "LVDS0",
+   [RCAR_DU_OUTPUT_LVDS1] = "LVDS1",
[RCAR_DU_OUTPUT_TCON] = "TCON",
};
 
-- 
2.30.2



[PATCH v5] drm/msm/dp: employ bridge mechanism for display enable and disable

2021-11-29 Thread Kuogee Hsieh
Currently the msm_dp_*** functions implement the same sequence which would
happen when drm_bridge is used. hence get rid of this intermediate layer
and align with the drm_bridge usage to avoid customized implementation.

Signed-off-by: Kuogee Hsieh 

Changes in v2:
-- revise commit text
-- rename dp_bridge to msm_dp_bridge
-- delete empty functions

Changes in v3:
-- replace kzalloc() with devm_kzalloc()
-- replace __dp_display_enable() with dp_display_enable()
-- replace __dp_display_disable() with dp_display_disable()

Changes in v4:
-- msm_dp_bridge_init() called from msm_dp_modeset_init() same as dsi

Changes in v5:
-- delete attach, mode_fixup and pre_enable from dp_bridge_ops
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 21 
 drivers/gpu/drm/msm/dp/dp_display.c | 16 +-
 drivers/gpu/drm/msm/dp/dp_display.h |  1 +
 drivers/gpu/drm/msm/dp/dp_drm.c | 77 +
 drivers/gpu/drm/msm/msm_drv.h   | 12 +++--
 5 files changed, 100 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 31050aa..c4e08c4 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -1003,9 +1003,6 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder 
*drm_enc,
 
trace_dpu_enc_mode_set(DRMID(drm_enc));
 
-   if (drm_enc->encoder_type == DRM_MODE_ENCODER_TMDS)
-   msm_dp_display_mode_set(dpu_enc->dp, drm_enc, mode, adj_mode);
-
list_for_each_entry(conn_iter, connector_list, head)
if (conn_iter->encoder == drm_enc)
conn = conn_iter;
@@ -1181,14 +1178,6 @@ static void dpu_encoder_virt_enable(struct drm_encoder 
*drm_enc)
 
_dpu_encoder_virt_enable_helper(drm_enc);
 
-   if (drm_enc->encoder_type == DRM_MODE_ENCODER_TMDS) {
-   ret = msm_dp_display_enable(dpu_enc->dp, drm_enc);
-   if (ret) {
-   DPU_ERROR_ENC(dpu_enc, "dp display enable failed: %d\n",
-   ret);
-   goto out;
-   }
-   }
dpu_enc->enabled = true;
 
 out:
@@ -1214,11 +1203,6 @@ static void dpu_encoder_virt_disable(struct drm_encoder 
*drm_enc)
/* wait for idle */
dpu_encoder_wait_for_event(drm_enc, MSM_ENC_TX_COMPLETE);
 
-   if (drm_enc->encoder_type == DRM_MODE_ENCODER_TMDS) {
-   if (msm_dp_display_pre_disable(dpu_enc->dp, drm_enc))
-   DPU_ERROR_ENC(dpu_enc, "dp display push idle failed\n");
-   }
-
dpu_encoder_resource_control(drm_enc, DPU_ENC_RC_EVENT_PRE_STOP);
 
for (i = 0; i < dpu_enc->num_phys_encs; i++) {
@@ -1243,11 +1227,6 @@ static void dpu_encoder_virt_disable(struct drm_encoder 
*drm_enc)
 
DPU_DEBUG_ENC(dpu_enc, "encoder disabled\n");
 
-   if (drm_enc->encoder_type == DRM_MODE_ENCODER_TMDS) {
-   if (msm_dp_display_disable(dpu_enc->dp, drm_enc))
-   DPU_ERROR_ENC(dpu_enc, "dp display disable failed\n");
-   }
-
mutex_unlock(&dpu_enc->enc_lock);
 }
 
diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
b/drivers/gpu/drm/msm/dp/dp_display.c
index 2f113ff..89a8d43 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -1571,6 +1571,18 @@ int msm_dp_modeset_init(struct msm_dp *dp_display, 
struct drm_device *dev,
}
 
priv->connectors[priv->num_connectors++] = dp_display->connector;
+
+   dp_display->bridge = msm_dp_bridge_init(dp_display, dev, encoder);
+   if (IS_ERR(dp_display->bridge)) {
+   ret = PTR_ERR(dp_display->bridge);
+   DRM_DEV_ERROR(dev->dev,
+   "failed to create dp bridge: %d\n", ret);
+   dp_display->bridge = NULL;
+   return ret;
+   }
+
+   priv->bridges[priv->num_bridges++] = dp_display->bridge;
+
return 0;
 }
 
@@ -1674,8 +1686,8 @@ int msm_dp_display_disable(struct msm_dp *dp, struct 
drm_encoder *encoder)
 }
 
 void msm_dp_display_mode_set(struct msm_dp *dp, struct drm_encoder *encoder,
-   struct drm_display_mode *mode,
-   struct drm_display_mode *adjusted_mode)
+   const struct drm_display_mode *mode,
+   const struct drm_display_mode *adjusted_mode)
 {
struct dp_display_private *dp_display;
 
diff --git a/drivers/gpu/drm/msm/dp/dp_display.h 
b/drivers/gpu/drm/msm/dp/dp_display.h
index 76f45f9..2237e80 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.h
+++ b/drivers/gpu/drm/msm/dp/dp_display.h
@@ -13,6 +13,7 @@
 struct msm_dp {
struct drm_device *drm_dev;
struct device *codec_dev;
+   struct drm_bridge *bridge;
struct drm_connector *connector;
struct drm_encoder *encoder;
struct drm_panel *d

Re: [PATCH v3] drm/msm/dp: employ bridge mechanism for display enable and disable

2021-11-29 Thread Kuogee Hsieh



On 11/24/2021 11:45 AM, Dmitry Baryshkov wrote:

On 15/11/2021 21:48, Kuogee Hsieh wrote:
Currently the msm_dp_*** functions implement the same sequence which 
would

happen when drm_bridge is used. hence get rid of this intermediate layer
and align with the drm_bridge usage to avoid customized implementation.

Signed-off-by: Kuogee Hsieh 

Changes in v2:
-- revise commit text
-- rename dp_bridge to msm_dp_bridge
-- delete empty functions

Changes in 3:
-- replace kzalloc() with devm_kzalloc()
-- replace __dp_display_enable() with dp_display_enable()
-- replace __dp_display_disable() with dp_display_disable()
---
  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 21 ---
  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c |  7 +++
  drivers/gpu/drm/msm/dp/dp_display.c |  4 +-
  drivers/gpu/drm/msm/dp/dp_display.h |  1 +
  drivers/gpu/drm/msm/dp/dp_drm.c | 91 
+

  drivers/gpu/drm/msm/msm_drv.h   | 16 +++--
  6 files changed, 113 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c

index 31050aa..c4e08c4 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -1003,9 +1003,6 @@ static void dpu_encoder_virt_mode_set(struct 
drm_encoder *drm_enc,

    trace_dpu_enc_mode_set(DRMID(drm_enc));
  -    if (drm_enc->encoder_type == DRM_MODE_ENCODER_TMDS)
-    msm_dp_display_mode_set(dpu_enc->dp, drm_enc, mode, adj_mode);
-
  list_for_each_entry(conn_iter, connector_list, head)
  if (conn_iter->encoder == drm_enc)
  conn = conn_iter;
@@ -1181,14 +1178,6 @@ static void dpu_encoder_virt_enable(struct 
drm_encoder *drm_enc)

    _dpu_encoder_virt_enable_helper(drm_enc);
  -    if (drm_enc->encoder_type == DRM_MODE_ENCODER_TMDS) {
-    ret = msm_dp_display_enable(dpu_enc->dp, drm_enc);
-    if (ret) {
-    DPU_ERROR_ENC(dpu_enc, "dp display enable failed: %d\n",
-    ret);
-    goto out;
-    }
-    }
  dpu_enc->enabled = true;
    out:
@@ -1214,11 +1203,6 @@ static void dpu_encoder_virt_disable(struct 
drm_encoder *drm_enc)

  /* wait for idle */
  dpu_encoder_wait_for_event(drm_enc, MSM_ENC_TX_COMPLETE);
  -    if (drm_enc->encoder_type == DRM_MODE_ENCODER_TMDS) {
-    if (msm_dp_display_pre_disable(dpu_enc->dp, drm_enc))
-    DPU_ERROR_ENC(dpu_enc, "dp display push idle failed\n");
-    }
-
  dpu_encoder_resource_control(drm_enc, DPU_ENC_RC_EVENT_PRE_STOP);
    for (i = 0; i < dpu_enc->num_phys_encs; i++) {
@@ -1243,11 +1227,6 @@ static void dpu_encoder_virt_disable(struct 
drm_encoder *drm_enc)

    DPU_DEBUG_ENC(dpu_enc, "encoder disabled\n");
  -    if (drm_enc->encoder_type == DRM_MODE_ENCODER_TMDS) {
-    if (msm_dp_display_disable(dpu_enc->dp, drm_enc))
-    DPU_ERROR_ENC(dpu_enc, "dp display disable failed\n");
-    }
-
  mutex_unlock(&dpu_enc->enc_lock);
  }
  diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c

index 27d98b5..d16337f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -557,6 +557,13 @@ static int 
_dpu_kms_initialize_displayport(struct drm_device *dev,

    encoder->base.id, rc);
  return rc;
  }
+
+    rc = msm_dp_bridge_init(priv->dp[i], dev, encoder);
+    if (rc) {
+    DPU_ERROR("failed to setup DPU bridge %d: rc:%d\n",
+    encoder->base.id, rc);
+    return rc;
+    }


There is no need to teach DPU driver about all the gory details of DP 
internals. Move this call to the msm_dp_modeset_init().


This has been done at v4.

I will submit v5 to address other commands.




  }
    return rc;
diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
b/drivers/gpu/drm/msm/dp/dp_display.c

index 2f113ff..51770a4 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -1674,8 +1674,8 @@ int msm_dp_display_disable(struct msm_dp *dp, 
struct drm_encoder *encoder)

  }
    void msm_dp_display_mode_set(struct msm_dp *dp, struct 
drm_encoder *encoder,

-    struct drm_display_mode *mode,
-    struct drm_display_mode *adjusted_mode)
+    const struct drm_display_mode *mode,
+    const struct drm_display_mode *adjusted_mode)
  {
  struct dp_display_private *dp_display;
  diff --git a/drivers/gpu/drm/msm/dp/dp_display.h 
b/drivers/gpu/drm/msm/dp/dp_display.h

index 76f45f9..2237e80 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.h
+++ b/drivers/gpu/drm/msm/dp/dp_display.h
@@ -13,6 +13,7 @@
  struct msm_dp {
  struct drm_device *drm_dev;
  struct device *codec_dev;
+    struct drm_bridge *bridge;
  struct drm_connector *connector;
  struct drm_encoder *encoder;
  struct drm_panel *drm_panel;
diff --git

[PATCH v2] dma_fence_array: Fix PENDING_ERROR leak in dma_fence_array_signaled()

2021-11-29 Thread Thomas Hellström
If a dma_fence_array is reported signaled by a call to
dma_fence_is_signaled(), it may leak the PENDING_ERROR status.

Fix this by clearing the PENDING_ERROR status if we return true in
dma_fence_array_signaled().

v2:
- Update Cc list, and add R-b.

Fixes: 1f70b8b812f3 ("dma-fence: Propagate errors to dma-fence-array container")
Cc: Chris Wilson 
Cc: Sumit Semwal 
Cc: Gustavo Padovan 
Cc: Christian König 
Cc: "Christian König" 
Cc: linux-me...@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: linaro-mm-...@lists.linaro.org
Cc:  # v5.4+
Signed-off-by: Thomas Hellström 
Reviewed-by: Christian König 
---
 drivers/dma-buf/dma-fence-array.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/dma-buf/dma-fence-array.c 
b/drivers/dma-buf/dma-fence-array.c
index d3fbd950be94..3e07f961e2f3 100644
--- a/drivers/dma-buf/dma-fence-array.c
+++ b/drivers/dma-buf/dma-fence-array.c
@@ -104,7 +104,11 @@ static bool dma_fence_array_signaled(struct dma_fence 
*fence)
 {
struct dma_fence_array *array = to_dma_fence_array(fence);
 
-   return atomic_read(&array->num_pending) <= 0;
+   if (atomic_read(&array->num_pending) > 0)
+   return false;
+
+   dma_fence_array_clear_pending_error(array);
+   return true;
 }
 
 static void dma_fence_array_release(struct dma_fence *fence)
-- 
2.31.1



Re: [i-g-t 00/14] Add IGT support for plane color management

2021-11-29 Thread Harry Wentland



On 2021-11-29 04:20, Pekka Paalanen wrote:
> On Fri, 26 Nov 2021 11:54:55 -0500
> Harry Wentland  wrote:
> 
>> On 2021-11-18 04:50, Pekka Paalanen wrote:
>>> On Mon, 15 Nov 2021 15:17:45 +0530
>>> Bhanuprakash Modem  wrote:
>>>   
 From the Plane Color Management feature design, userspace can
 take the smart blending decisions based on hardware supported
 plane color features to obtain an accurate color profile.

 These IGT patches extend the existing pipe color management
 tests to the plane level.

 Kernel implementation:
 https://patchwork.freedesktop.org/series/90825/  
> 
> ...
> 
>>> I also found some things that looked hardware-specific in this code
>>> that to my understanding is supposed to be generic, and some concerns
>>> about UAPI as well.
>>>   
>>
>> I left some comments on intellisms in these patches.
>>
>> Do you have any specifics about your concerns about UAPI?
> 
> Yeah, the comments I left in the patches:
> 
> patch 3:
> 
>> Having to explicitly special-case index zero feels odd to me. Why does
>> it need explicit special-casing?
>>
>> To me it's a hint that the definitions of .start and .end are somehow
>> inconsistent.
> 
> patch 4 and 8:
> 
>>> +static bool is_hdr_plane(const igt_plane_t *plane)
>>> +{
>>> +   return plane->index >= 0 && plane->index < SDR_PLANE_BASE;  
>>
>> How can this be right for all KMS drivers?
>>
>> What is a HDR plane?
> 
> patch 12:
> 
>>> +struct drm_color_lut *coeffs_to_logarithmic_lut(data_t *data,
>>> +   const gamma_lut_t *gamma,
>>> +   uint32_t color_depth,
>>> +   int off)
>>> +{
>>> +   struct drm_color_lut *lut;
>>> +   int i, lut_size = gamma->size;
>>> +   /* This is the maximum value due to 16 bit precision in hardware. */  
>>
>> In whose hardware?
>>
>> Are igt tests not supposed to be generic for everything that exposes
>> the particular KMS properties?
>>
>> This also hints that the UAPI design is lacking, because userspace
>> needs to know hardware specific things out of thin air. Display servers
>> are not going to have hardware-specific code. They specialise based on
>> the existence of KMS properties instead.
> 
> ...
> 
>>> +void set_advance_gamma(data_t *data, igt_pipe_t *pipe, enum gamma_type 
>>> type)
>>> +{
>>> +   igt_display_t *display = &data->display;
>>> +   gamma_lut_t *gamma_log;
>>> +   drmModePropertyPtr gamma_mode = NULL;
>>> +   segment_data_t *segment_info = NULL;
>>> +   struct drm_color_lut *lut = NULL;
>>> +   int lut_size = 0;
>>> +
>>> +   drmSetClientCap(data->drm_fd, DRM_CLIENT_CAP_ADVANCE_GAMMA_MODES, 1);  
>>
>> Is this how we are going to do cross-software DRM-master hand-over or
>> switching compatibility in general?
>>
>> Add a new client cap for every new KMS property, and if the KMS client
>> does not set the property, the kernel will magically reset it to ensure
>> the client's expectations are met? Is that how it works?
>>
>> Or why does this exist?
> 
> ...
> 
>>> +   drmSetClientCap(data->drm_fd, DRM_CLIENT_CAP_ADVANCE_GAMMA_MODES, 0);  
>>
>> I've never seen this done before. I did not know client caps could be
>> reset.
> 
> 
> So, patch 12 has the biggest UAPI questions, and patch 3 may need a
> UAPI change as well. The comments in patches 4 and 8 could be addressed
> with just removing that code since the concept of HDR/SDR planes does
> not exist in UAPI. Or, if that concept is needed then it's another UAPI
> problem.
> 

Thanks for reiterating your points. I missed your earlier replies and
found them in my IGT folder just now.

Looks like we're on the same page.

Harry

> 
> Thanks,
> pq
> 



Re: [PATCH] drm/msm: Initialize MDSS irq domain at probe time

2021-11-29 Thread AngeloGioacchino Del Regno

Il 29/11/21 15:53, Dmitry Baryshkov ha scritto:

Hi,

On Mon, 29 Nov 2021 at 17:15, AngeloGioacchino Del Regno
 wrote:


Il 29/11/21 03:20, Dmitry Baryshkov ha scritto:

Hi,

On 25/11/2021 18:09, AngeloGioacchino Del Regno wrote:

Since commit 8f59ee9a570c ("drm/msm/dsi: Adjust probe order"), the
DSI host gets initialized earlier, but this caused unability to probe
the entire stack of components because they all depend on interrupts
coming from the main `mdss` node (mdp5, or dpu1).

To fix this issue, also anticipate probing mdp5 or dpu1 by initializing
them at msm_pdev_probe() time: this will make sure that we add the
required interrupt controller mapping before dsi and/or other components
try to initialize, finally satisfying the dependency.

While at it, also change the allocation of msm_drm_private to use the
devm variant of kzalloc().

Fixes: 8f59ee9a570c ("drm/msm/dsi: Adjust probe order")
Signed-off-by: AngeloGioacchino Del Regno 



I have been thinking about this. I do not feel that this is the correct 
approach.
Currently DRM device exists only when all components are bound. If any of the
subdevices is removed, corresponding component is delteted (and thus all 
components
are unbound), the DRM device is taken down. This results in the state cleanup,
userspace notifications, etc.

With your changes, DRM device will continue to exist even after one of 
subdevices
is removed. This is not an expected behaviour, since subdrivers do not perform 
full
cleanup, delegating that to DRM device takedown.

I suppose that proper solution would be to split msm_drv.c into into:
- generic components & drm code to be called from mdp4/mdp5/dpu driver (making
mdp4, mdp5 or dpu1 the components master)

- bare mdss driver, taking care only about IRQs, OF devices population - calling
proper mdss_init/mdss_destroy functions. Most probably we can drop this part
altogether and just make md5_mdss.c/dpu_mdss.c proper platform drivers.




Hmm... getting a better look on how things are structured... yes, I mostly agree
with you, though I'm not sure about making MDP{4,5}/DPU1 the component master; 
that
would result in a major change in drm-msm, which may be "a bit too much".

Don't misunderstand me here, please, major changes are fine - but I feel urgency
to get this bug solved ASAP (since drm-msm is currently broken at least for drm
bridges) and, if we do anything major, that would require a very careful slow
review process that will leave this driver broken for a lot of time.


Yep. I wanted to hear your and Rob's opinion, that's why I did not
rush into implementing it.
I still think this is the way to go in the long term. What I really
liked in your patchset was untying the knot between component binds
returning EPROBE_DEFER and mdss subdevices being in place. This solved
the "dsi host registration" infinite loop for me.



Thanks. I'm also curious about Rob's opinion on this, as that'd be very 
valuable.



I actually tried something else that "simplifies" the former approach, so here's
my proposal:
* we introduce {mdp5,dpu}_mdss_early_init(struct device, struct msm_drm_private)
* allocate only msm_drm_private in msm_pdev_probe, leaving the drm_dev_alloc 
call
into msm_drm_init(), so that the drm_dev_put() stays in msm_drm_uninit()
* pass msm_drm_private as drvdata instead of drm_device
* change all the drvdata users to get drm_device from priv->dev, instead of 
getting
msm_drm_private from drm_device->dev_private (like many other drm drivers 
are
currently doing)


This sounds in a way that it should work. I'm looking forward to
seeing (and testing) your patches.



Alright then, I'm running some more tests and cleaning up the patches.
Expect a v2 between today and tomorrow at max! :))



This way, we keep the current flow of creating the DRM device at msm_drm_init 
time
and tearing it down at msm_drm_unbind time, solving the issue that you are
describing.

If you're okay with this kind of approach, I have two patches here that are 95%
ready, can finish them off and send briefly.

Though, something else must be noted here... in the last mail where I'm pasting
a crash that happens when running 'rmmod panel_edp ti_sn65dsi86', I have implied
that this is happening due to the patch that I've sent: after some more 
research,
I'm not convinced anymore that this is a consequence of that. That crash may not
be related to my fix at all, but to something else (perhaps also related to 
commit
8f59ee9a570c, the one that we're fixing here).

Of course, that crash still happens even with the approach that I've just 
proposed.


Looking forward for your opinion!

Cheers,
- Angelo







--
AngeloGioacchino Del Regno
Software Engineer

Collabora Ltd.
Platinum Building, St John's Innovation Park, Cambridge CB4 0DS, UK
Registered in England & Wales, no. 5513718


Re: [igt-dev] [i-g-t 07/14] tests/kms_color: New negative tests for plane level color mgmt

2021-11-29 Thread Harry Wentland



On 2021-11-18 04:19, Pekka Paalanen wrote:
> On Mon, 15 Nov 2021 15:17:52 +0530
> Bhanuprakash Modem  wrote:
> 
>> Negative check for:
>>  * plane gamma lut sizes
>>  * plane degamma lut sizes
>>  * plane ctm matrix sizes
>>
>> Cc: Harry Wentland 
>> Cc: Ville Syrjälä 
>> Cc: Juha-Pekka Heikkila 
>> Cc: Uma Shankar 
>> Signed-off-by: Bhanuprakash Modem 
>> ---
>>  tests/kms_color.c | 127 ++
>>  1 file changed, 127 insertions(+)
>>
>> diff --git a/tests/kms_color.c b/tests/kms_color.c
>> index e14b37cb6f..d9fe417ba9 100644
>> --- a/tests/kms_color.c
>> +++ b/tests/kms_color.c
>> @@ -736,6 +736,118 @@ static void test_pipe_limited_range_ctm(data_t *data,
>>  }
>>  #endif
>>  
>> +static bool invalid_plane_gamma_test(data_t *data, igt_plane_t *plane)
>> +{
>> +igt_display_t *display = &data->display;
>> +drmModePropertyPtr gamma_mode = NULL;
>> +uint32_t i;
>> +
>> +igt_info("Plane invalid gamma test is running on pipe-%s 
>> plane-%s(%s)\n",
>> +kmstest_pipe_name(plane->pipe->pipe),
>> +kmstest_plane_type_name(plane->type),
>> +is_hdr_plane(plane) ? "hdr":"sdr");
>> +
>> +igt_require(igt_plane_has_prop(plane, IGT_PLANE_GAMMA_MODE));
>> +igt_require(igt_plane_has_prop(plane, IGT_PLANE_GAMMA_LUT));
>> +
>> +gamma_mode = get_plane_gamma_degamma_mode(plane, IGT_PLANE_GAMMA_MODE);
>> +
>> +/* Iterate all supported gamma modes. */
>> +for (i = 0; i < gamma_mode->count_enums; i++) {
>> +segment_data_t *segment_info = NULL;
>> +size_t lut_size = 0;
>> +
>> +/* Ignore 'no gamma' from enum list. */
>> +if (!strcmp(gamma_mode->enums[i].name, "no gamma"))
>> +continue;
>> +
>> +igt_info("Trying to use gamma mode: \'%s\'\n", 
>> gamma_mode->enums[i].name);
>> +
>> +segment_info = get_segment_data(data, 
>> gamma_mode->enums[i].value,
>> +gamma_mode->enums[i].name);
>> +lut_size = sizeof(struct drm_color_lut_ext) * 
>> segment_info->entries_count;
>> +
>> +igt_plane_set_prop_enum(plane, IGT_PLANE_GAMMA_MODE, 
>> gamma_mode->enums[i].name);
>> +invalid_plane_lut_sizes(display, plane,
>> +IGT_PLANE_GAMMA_LUT,
>> +lut_size);
>> +
>> +clear_segment_data(segment_info);
>> +
>> +/* One enum is enough. */
>> +break;
>> +}
>> +
>> +drmModeFreeProperty(gamma_mode);
>> +
>> +return true;
>> +}
>> +
>> +static bool invalid_plane_degamma_test(data_t *data, igt_plane_t *plane)
>> +{
>> +igt_display_t *display = &data->display;
>> +drmModePropertyPtr degamma_mode = NULL;
>> +uint32_t i;
>> +
>> +igt_info("Plane invalid degamma test is running on pipe-%s 
>> plane-%s(%s)\n",
>> +kmstest_pipe_name(plane->pipe->pipe),
>> +kmstest_plane_type_name(plane->type),
>> +is_hdr_plane(plane) ? "hdr":"sdr");
>> +
>> +igt_require(igt_plane_has_prop(plane, IGT_PLANE_DEGAMMA_MODE));
>> +igt_require(igt_plane_has_prop(plane, IGT_PLANE_DEGAMMA_LUT));
>> +
>> +degamma_mode = get_plane_gamma_degamma_mode(plane, 
>> IGT_PLANE_DEGAMMA_MODE);
>> +
>> +/* Iterate all supported degamma modes. */
>> +for (i = 0; i < degamma_mode->count_enums; i++) {
>> +segment_data_t *segment_info = NULL;
>> +size_t lut_size = 0;
>> +
>> +/* Ignore 'no degamma' from enum list. */
>> +if (!strcmp(degamma_mode->enums[i].name, "no degamma"))
>> +continue;
>> +
>> +igt_info("Trying to use degamma mode: \'%s\'\n", 
>> degamma_mode->enums[i].name);
>> +
>> +segment_info = get_segment_data(data,
>> +degamma_mode->enums[i].value,
>> +degamma_mode->enums[i].name);
>> +lut_size = sizeof(struct drm_color_lut_ext) * 
>> segment_info->entries_count * 2;
>> +
>> +igt_plane_set_prop_enum(plane,
>> +IGT_PLANE_DEGAMMA_MODE,
>> +degamma_mode->enums[i].name);
>> +invalid_plane_lut_sizes(display, plane,
>> +IGT_PLANE_DEGAMMA_LUT,
>> +lut_size);
>> +
>> +clear_segment_data(segment_info);
>> +
>> +/* One enum is enough. */
>> +break;
> 
> Why is one enum enough?
> 

I think it's another intellism since Uma's patches only
report one enum.

Since the API is designed to allow for multiple enums the test
should just run on all of them. It'd be a trivial change to the
test.

Harry

> The same question for the other case in this patch.
> 
> 
>> +}
>> +
>> +drmModeFreeProperty(degamma_mode);
>> +
>> +   

Re: [PATCH] drm/msm: Initialize MDSS irq domain at probe time

2021-11-29 Thread Dmitry Baryshkov
Hi,

On Mon, 29 Nov 2021 at 17:15, AngeloGioacchino Del Regno
 wrote:
>
> Il 29/11/21 03:20, Dmitry Baryshkov ha scritto:
> > Hi,
> >
> > On 25/11/2021 18:09, AngeloGioacchino Del Regno wrote:
> >> Since commit 8f59ee9a570c ("drm/msm/dsi: Adjust probe order"), the
> >> DSI host gets initialized earlier, but this caused unability to probe
> >> the entire stack of components because they all depend on interrupts
> >> coming from the main `mdss` node (mdp5, or dpu1).
> >>
> >> To fix this issue, also anticipate probing mdp5 or dpu1 by initializing
> >> them at msm_pdev_probe() time: this will make sure that we add the
> >> required interrupt controller mapping before dsi and/or other components
> >> try to initialize, finally satisfying the dependency.
> >>
> >> While at it, also change the allocation of msm_drm_private to use the
> >> devm variant of kzalloc().
> >>
> >> Fixes: 8f59ee9a570c ("drm/msm/dsi: Adjust probe order")
> >> Signed-off-by: AngeloGioacchino Del Regno 
> >> 
> >
> > I have been thinking about this. I do not feel that this is the correct 
> > approach.
> > Currently DRM device exists only when all components are bound. If any of 
> > the
> > subdevices is removed, corresponding component is delteted (and thus all 
> > components
> > are unbound), the DRM device is taken down. This results in the state 
> > cleanup,
> > userspace notifications, etc.
> >
> > With your changes, DRM device will continue to exist even after one of 
> > subdevices
> > is removed. This is not an expected behaviour, since subdrivers do not 
> > perform full
> > cleanup, delegating that to DRM device takedown.
> >
> > I suppose that proper solution would be to split msm_drv.c into into:
> > - generic components & drm code to be called from mdp4/mdp5/dpu driver 
> > (making
> > mdp4, mdp5 or dpu1 the components master)
> >
> > - bare mdss driver, taking care only about IRQs, OF devices population - 
> > calling
> > proper mdss_init/mdss_destroy functions. Most probably we can drop this part
> > altogether and just make md5_mdss.c/dpu_mdss.c proper platform drivers.
> >
>
>
> Hmm... getting a better look on how things are structured... yes, I mostly 
> agree
> with you, though I'm not sure about making MDP{4,5}/DPU1 the component 
> master; that
> would result in a major change in drm-msm, which may be "a bit too much".
>
> Don't misunderstand me here, please, major changes are fine - but I feel 
> urgency
> to get this bug solved ASAP (since drm-msm is currently broken at least for 
> drm
> bridges) and, if we do anything major, that would require a very careful slow
> review process that will leave this driver broken for a lot of time.

Yep. I wanted to hear your and Rob's opinion, that's why I did not
rush into implementing it.
I still think this is the way to go in the long term. What I really
liked in your patchset was untying the knot between component binds
returning EPROBE_DEFER and mdss subdevices being in place. This solved
the "dsi host registration" infinite loop for me.

>
> I actually tried something else that "simplifies" the former approach, so 
> here's
> my proposal:
> * we introduce {mdp5,dpu}_mdss_early_init(struct device, struct 
> msm_drm_private)
> * allocate only msm_drm_private in msm_pdev_probe, leaving the drm_dev_alloc 
> call
>into msm_drm_init(), so that the drm_dev_put() stays in msm_drm_uninit()
> * pass msm_drm_private as drvdata instead of drm_device
> * change all the drvdata users to get drm_device from priv->dev, instead of 
> getting
>msm_drm_private from drm_device->dev_private (like many other drm drivers 
> are
>currently doing)

This sounds in a way that it should work. I'm looking forward to
seeing (and testing) your patches.

>
> This way, we keep the current flow of creating the DRM device at msm_drm_init 
> time
> and tearing it down at msm_drm_unbind time, solving the issue that you are
> describing.
>
> If you're okay with this kind of approach, I have two patches here that are 
> 95%
> ready, can finish them off and send briefly.
>
> Though, something else must be noted here... in the last mail where I'm 
> pasting
> a crash that happens when running 'rmmod panel_edp ti_sn65dsi86', I have 
> implied
> that this is happening due to the patch that I've sent: after some more 
> research,
> I'm not convinced anymore that this is a consequence of that. That crash may 
> not
> be related to my fix at all, but to something else (perhaps also related to 
> commit
> 8f59ee9a570c, the one that we're fixing here).
>
> Of course, that crash still happens even with the approach that I've just 
> proposed.
>
>
> Looking forward for your opinion!
>
> Cheers,
> - Angelo



-- 
With best wishes
Dmitry


Re: [PATCH v2 0/6] drm/vc4: kms: Misc fixes for HVS commits

2021-11-29 Thread Maxime Ripard
On Wed, 17 Nov 2021 10:45:21 +0100, Maxime Ripard wrote:
> The conversion to DRM commit helpers (f3c420fe19f8, "drm/vc4: kms: Convert to
> atomic helpers") introduced a number of issues in corner cases, most of them
> showing themselves in the form of either a vblank timeout or use-after-free
> error.
> 
> These patches should fix most of them, some of them still being debugged.
> 
> [...]

Applied to drm/drm-misc (drm-misc-fixes).

Thanks!
Maxime


Re: [PATCH] drm/msm: Initialize MDSS irq domain at probe time

2021-11-29 Thread AngeloGioacchino Del Regno

Il 29/11/21 03:20, Dmitry Baryshkov ha scritto:

Hi,

On 25/11/2021 18:09, AngeloGioacchino Del Regno wrote:

Since commit 8f59ee9a570c ("drm/msm/dsi: Adjust probe order"), the
DSI host gets initialized earlier, but this caused unability to probe
the entire stack of components because they all depend on interrupts
coming from the main `mdss` node (mdp5, or dpu1).

To fix this issue, also anticipate probing mdp5 or dpu1 by initializing
them at msm_pdev_probe() time: this will make sure that we add the
required interrupt controller mapping before dsi and/or other components
try to initialize, finally satisfying the dependency.

While at it, also change the allocation of msm_drm_private to use the
devm variant of kzalloc().

Fixes: 8f59ee9a570c ("drm/msm/dsi: Adjust probe order")
Signed-off-by: AngeloGioacchino Del Regno 



I have been thinking about this. I do not feel that this is the correct approach. 
Currently DRM device exists only when all components are bound. If any of the 
subdevices is removed, corresponding component is delteted (and thus all components 
are unbound), the DRM device is taken down. This results in the state cleanup, 
userspace notifications, etc.


With your changes, DRM device will continue to exist even after one of subdevices 
is removed. This is not an expected behaviour, since subdrivers do not perform full 
cleanup, delegating that to DRM device takedown.


I suppose that proper solution would be to split msm_drv.c into into:
- generic components & drm code to be called from mdp4/mdp5/dpu driver (making 
mdp4, mdp5 or dpu1 the components master)


- bare mdss driver, taking care only about IRQs, OF devices population - calling 
proper mdss_init/mdss_destroy functions. Most probably we can drop this part 
altogether and just make md5_mdss.c/dpu_mdss.c proper platform drivers.





Hmm... getting a better look on how things are structured... yes, I mostly agree
with you, though I'm not sure about making MDP{4,5}/DPU1 the component master; 
that
would result in a major change in drm-msm, which may be "a bit too much".

Don't misunderstand me here, please, major changes are fine - but I feel urgency
to get this bug solved ASAP (since drm-msm is currently broken at least for drm 
bridges) and, if we do anything major, that would require a very careful slow

review process that will leave this driver broken for a lot of time.

I actually tried something else that "simplifies" the former approach, so here's
my proposal:
* we introduce {mdp5,dpu}_mdss_early_init(struct device, struct msm_drm_private)
* allocate only msm_drm_private in msm_pdev_probe, leaving the drm_dev_alloc 
call
  into msm_drm_init(), so that the drm_dev_put() stays in msm_drm_uninit()
* pass msm_drm_private as drvdata instead of drm_device
* change all the drvdata users to get drm_device from priv->dev, instead of 
getting
  msm_drm_private from drm_device->dev_private (like many other drm drivers are
  currently doing)

This way, we keep the current flow of creating the DRM device at msm_drm_init 
time
and tearing it down at msm_drm_unbind time, solving the issue that you are
describing.

If you're okay with this kind of approach, I have two patches here that are 95%
ready, can finish them off and send briefly.

Though, something else must be noted here... in the last mail where I'm pasting
a crash that happens when running 'rmmod panel_edp ti_sn65dsi86', I have implied
that this is happening due to the patch that I've sent: after some more 
research,
I'm not convinced anymore that this is a consequence of that. That crash may not
be related to my fix at all, but to something else (perhaps also related to 
commit
8f59ee9a570c, the one that we're fixing here).

Of course, that crash still happens even with the approach that I've just 
proposed.


Looking forward for your opinion!

Cheers,
- Angelo


[PATCH v2 09/16] drm/i915: Ensure i915_vma tests do not get -ENOSPC with the locking changes.

2021-11-29 Thread Maarten Lankhorst
Now that we require locking to evict, multiple vmas from the same object
might not be evicted. This is expected and required, because execbuf will
move to short-term pinning by using the lock only. This will cause these
tests to fail, because they create a ton of vma's for the same object.

Unbind manually to prevent spurious -ENOSPC in those mock tests.

Signed-off-by: Maarten Lankhorst 
---
 drivers/gpu/drm/i915/selftests/i915_vma.c | 17 -
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/selftests/i915_vma.c 
b/drivers/gpu/drm/i915/selftests/i915_vma.c
index 1f10fe36619b..5c5809dfe9b2 100644
--- a/drivers/gpu/drm/i915/selftests/i915_vma.c
+++ b/drivers/gpu/drm/i915/selftests/i915_vma.c
@@ -691,7 +691,11 @@ static int igt_vma_rotate_remap(void *arg)
}
 
i915_vma_unpin(vma);
-
+   err = i915_vma_unbind(vma);
+   if (err) {
+   pr_err("Unbinding returned 
%i\n", err);
+   goto out_object;
+   }
cond_resched();
}
}
@@ -848,6 +852,11 @@ static int igt_vma_partial(void *arg)
 
i915_vma_unpin(vma);
nvma++;
+   err = i915_vma_unbind(vma);
+   if (err) {
+   pr_err("Unbinding returned %i\n", err);
+   goto out_object;
+   }
 
cond_resched();
}
@@ -882,6 +891,12 @@ static int igt_vma_partial(void *arg)
 
i915_vma_unpin(vma);
 
+   err = i915_vma_unbind(vma);
+   if (err) {
+   pr_err("Unbinding returned %i\n", err);
+   goto out_object;
+   }
+
count = 0;
list_for_each_entry(vma, &obj->vma.list, obj_link)
count++;
-- 
2.34.0



[PATCH v2 15/16] drm/i915: Remove support for unlocked i915_vma unbind

2021-11-29 Thread Maarten Lankhorst
Now that we require the object lock for all ops, some code handling
race conditions can be removed.

This is required to not take short-term pins inside execbuf.

Signed-off-by: Maarten Lankhorst 
Acked-by: Niranjana Vishwanathapura 
---
 drivers/gpu/drm/i915/i915_vma.c | 40 +
 1 file changed, 5 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index 100739b3e084..3236cf1c1400 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -776,7 +776,6 @@ i915_vma_detach(struct i915_vma *vma)
 static bool try_qad_pin(struct i915_vma *vma, unsigned int flags)
 {
unsigned int bound;
-   bool pinned = true;
 
bound = atomic_read(&vma->flags);
do {
@@ -786,34 +785,10 @@ static bool try_qad_pin(struct i915_vma *vma, unsigned 
int flags)
if (unlikely(bound & (I915_VMA_OVERFLOW | I915_VMA_ERROR)))
return false;
 
-   if (!(bound & I915_VMA_PIN_MASK))
-   goto unpinned;
-
GEM_BUG_ON(((bound + 1) & I915_VMA_PIN_MASK) == 0);
} while (!atomic_try_cmpxchg(&vma->flags, &bound, bound + 1));
 
return true;
-
-unpinned:
-   /*
-* If pin_count==0, but we are bound, check under the lock to avoid
-* racing with a concurrent i915_vma_unbind().
-*/
-   mutex_lock(&vma->vm->mutex);
-   do {
-   if (unlikely(bound & (I915_VMA_OVERFLOW | I915_VMA_ERROR))) {
-   pinned = false;
-   break;
-   }
-
-   if (unlikely(flags & ~bound)) {
-   pinned = false;
-   break;
-   }
-   } while (!atomic_try_cmpxchg(&vma->flags, &bound, bound + 1));
-   mutex_unlock(&vma->vm->mutex);
-
-   return pinned;
 }
 
 static struct scatterlist *
@@ -1194,13 +1169,7 @@ __i915_vma_get_pages(struct i915_vma *vma)
vma->ggtt_view.type, ret);
}
 
-   pages = xchg(&vma->pages, pages);
-
-   /* did we race against a put_pages? */
-   if (pages && pages != vma->obj->mm.pages) {
-   sg_free_table(vma->pages);
-   kfree(vma->pages);
-   }
+   vma->pages = pages;
 
return ret;
 }
@@ -1234,13 +1203,14 @@ I915_SELFTEST_EXPORT int i915_vma_get_pages(struct 
i915_vma *vma)
 static void __vma_put_pages(struct i915_vma *vma, unsigned int count)
 {
/* We allocate under vma_get_pages, so beware the shrinker */
-   struct sg_table *pages = READ_ONCE(vma->pages);
+   struct sg_table *pages = vma->pages;
 
GEM_BUG_ON(atomic_read(&vma->pages_count) < count);
 
if (atomic_sub_return(count, &vma->pages_count) == 0) {
-   if (pages == cmpxchg(&vma->pages, pages, NULL) &&
-   pages != vma->obj->mm.pages) {
+   vma->pages = NULL;
+
+   if (pages != vma->obj->mm.pages) {
sg_free_table(pages);
kfree(pages);
}
-- 
2.34.0



[PATCH v2 10/16] drm/i915: Make i915_gem_evict_vm work correctly for already locked objects

2021-11-29 Thread Maarten Lankhorst
i915_gem_execbuf will call i915_gem_evict_vm() after failing to pin
all objects in the first round. We are about to remove those short-term
pins, but even without those the objects are still locked. Add a special
case to allow i915_gem_evict_vm to evict locked objects as well.

This might also allow multiple objects sharing the same resv to be evicted.

Signed-off-by: Maarten Lankhorst 
---
 drivers/gpu/drm/i915/i915_gem_evict.c | 23 ++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c 
b/drivers/gpu/drm/i915/i915_gem_evict.c
index 24f5e3345e43..f502a617b35c 100644
--- a/drivers/gpu/drm/i915/i915_gem_evict.c
+++ b/drivers/gpu/drm/i915/i915_gem_evict.c
@@ -410,21 +410,42 @@ int i915_gem_evict_vm(struct i915_address_space *vm, 
struct i915_gem_ww_ctx *ww)
do {
struct i915_vma *vma, *vn;
LIST_HEAD(eviction_list);
+   LIST_HEAD(locked_eviction_list);
 
list_for_each_entry(vma, &vm->bound_list, vm_link) {
if (i915_vma_is_pinned(vma))
continue;
 
+   /*
+* If we already own the lock, trylock fails. In case 
the resv
+* is shared among multiple objects, we still need the 
object ref.
+*/
+   if (ww && (dma_resv_locking_ctx(vma->obj->base.resv) == 
&ww->ctx)) {
+   __i915_vma_pin(vma);
+   list_add(&vma->evict_link, 
&locked_eviction_list);
+   continue;
+   }
+
if (!i915_gem_object_trylock(vma->obj, ww))
continue;
 
__i915_vma_pin(vma);
list_add(&vma->evict_link, &eviction_list);
}
-   if (list_empty(&eviction_list))
+   if (list_empty(&eviction_list) && 
list_empty(&locked_eviction_list))
break;
 
ret = 0;
+   /* Unbind locked objects first, before unlocking the 
eviction_list */
+   list_for_each_entry_safe(vma, vn, &locked_eviction_list, 
evict_link) {
+   __i915_vma_unpin(vma);
+
+   if (ret == 0)
+   ret = __i915_vma_unbind(vma);
+   if (ret != -EINTR) /* "Get me out of here!" */
+   ret = 0;
+   }
+
list_for_each_entry_safe(vma, vn, &eviction_list, evict_link) {
__i915_vma_unpin(vma);
if (ret == 0)
-- 
2.34.0



[PATCH v2 12/16] drm/i915: Add i915_vma_unbind_unlocked, and take obj lock for i915_vma_unbind

2021-11-29 Thread Maarten Lankhorst
We want to remove more members of i915_vma, which requires the locking to be
held more often.

Start requiring gem object lock for i915_vma_unbind, as it's one of the
callers that may unpin pages.

Some special care is needed when evicting, because the last reference to the
object may be held by the VMA, so after __i915_vma_unbind, vma may be garbage,
and we need to cache vma->obj before unlocking.

Signed-off-by: Maarten Lankhorst 
---
 drivers/gpu/drm/i915/display/intel_fb_pin.c   |  2 +-
 .../gpu/drm/i915/gem/selftests/huge_pages.c   |  2 +-
 .../i915/gem/selftests/i915_gem_client_blt.c  |  2 +-
 .../drm/i915/gem/selftests/i915_gem_mman.c|  6 +++
 drivers/gpu/drm/i915/gt/intel_ggtt.c  | 45 ---
 drivers/gpu/drm/i915/i915_gem.c   |  2 +
 drivers/gpu/drm/i915/i915_vma.c   | 27 ++-
 drivers/gpu/drm/i915/i915_vma.h   |  1 +
 drivers/gpu/drm/i915/selftests/i915_gem_gtt.c | 22 -
 drivers/gpu/drm/i915/selftests/i915_vma.c |  8 ++--
 10 files changed, 92 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_fb_pin.c 
b/drivers/gpu/drm/i915/display/intel_fb_pin.c
index 3b20f69e0240..3aec972d9382 100644
--- a/drivers/gpu/drm/i915/display/intel_fb_pin.c
+++ b/drivers/gpu/drm/i915/display/intel_fb_pin.c
@@ -47,7 +47,7 @@ intel_pin_fb_obj_dpt(struct drm_framebuffer *fb,
goto err;
 
if (i915_vma_misplaced(vma, 0, alignment, 0)) {
-   ret = i915_vma_unbind(vma);
+   ret = i915_vma_unbind_unlocked(vma);
if (ret) {
vma = ERR_PTR(ret);
goto err;
diff --git a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c 
b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
index c69c7d45aabc..0db62652e3ba 100644
--- a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
+++ b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
@@ -647,7 +647,7 @@ static int igt_mock_ppgtt_misaligned_dma(void *arg)
 * pages.
 */
for (offset = 4096; offset < page_size; offset += 4096) {
-   err = i915_vma_unbind(vma);
+   err = i915_vma_unbind_unlocked(vma);
if (err)
goto out_unpin;
 
diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_client_blt.c 
b/drivers/gpu/drm/i915/gem/selftests/i915_gem_client_blt.c
index 8402ed925a69..8fb5be799b3c 100644
--- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_client_blt.c
+++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_client_blt.c
@@ -318,7 +318,7 @@ static int pin_buffer(struct i915_vma *vma, u64 addr)
int err;
 
if (drm_mm_node_allocated(&vma->node) && vma->node.start != addr) {
-   err = i915_vma_unbind(vma);
+   err = i915_vma_unbind_unlocked(vma);
if (err)
return err;
}
diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c
index 6d30cdfa80f3..e69e8861352d 100644
--- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c
@@ -165,7 +165,9 @@ static int check_partial_mapping(struct drm_i915_gem_object 
*obj,
kunmap(p);
 
 out:
+   i915_gem_object_lock(obj, NULL);
__i915_vma_put(vma);
+   i915_gem_object_unlock(obj);
return err;
 }
 
@@ -259,7 +261,9 @@ static int check_partial_mappings(struct 
drm_i915_gem_object *obj,
if (err)
return err;
 
+   i915_gem_object_lock(obj, NULL);
__i915_vma_put(vma);
+   i915_gem_object_unlock(obj);
 
if (igt_timeout(end_time,
"%s: timed out after tiling=%d stride=%d\n",
@@ -1349,7 +1353,9 @@ static int __igt_mmap_revoke(struct drm_i915_private 
*i915,
 * for other objects. Ergo we have to revoke the previous mmap PTE
 * access as it no longer points to the same object.
 */
+   i915_gem_object_lock(obj, NULL);
err = i915_gem_object_unbind(obj, I915_GEM_OBJECT_UNBIND_ACTIVE);
+   i915_gem_object_unlock(obj);
if (err) {
pr_err("Failed to unbind object!\n");
goto out_unmap;
diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c 
b/drivers/gpu/drm/i915/gt/intel_ggtt.c
index 17e2e01b8d25..f9790f45a492 100644
--- a/drivers/gpu/drm/i915/gt/intel_ggtt.c
+++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c
@@ -129,22 +129,47 @@ void i915_ggtt_suspend_vm(struct i915_address_space *vm)
 
drm_WARN_ON(&vm->i915->drm, !vm->is_ggtt && !vm->is_dpt);
 
+retry:
+   i915_gem_drain_freed_objects(vm->i915);
+
mutex_lock(&vm->mutex);
 
/* Skip rewriting PTE on VMA unbind. */
open = atomic_xchg(&vm->open, 0);
 
list_for_each_entry_safe(vma, vn, &vm->bound_list, vm_link) {
+ 

[PATCH v2 16/16] drm/i915: Remove short-term pins from execbuf, v5.

2021-11-29 Thread Maarten Lankhorst
Add a flag PIN_VALIDATE, to indicate we don't need to pin and only
protected by the object lock.

This removes the need to unpin, which is done by just releasing the
lock.

eb_reserve is slightly reworked for readability, but the same steps
are still done:
- First pass pins with NONBLOCK.
- Second pass unbinds all objects first, then pins.
- Third pass is only called when not all objects are softpinned, and
  unbinds all objects, then calls i915_gem_evict_vm(), then pins.

When evicting the entire vm in eb_reserve() we do temporarily pin objects
that are marked with EXEC_OBJECT_PINNED. This is because they are already
at their destination, and i915_gem_evict_vm() would otherwise unbind them.

However, we reduce the visibility of those pins by limiting the pin
to our call to i915_gem_evict_vm() only, and pin with vm->mutex held,
instead of the entire duration of the execbuf.

Not sure the latter matters, one can hope..
In theory we could kill the pinning by adding an extra flag to the vma
to temporarily prevent unbinding for gtt for i915_gem_evict_vm only, but
I think that might be overkill. We're still holding the object lock, and
we don't have blocking eviction yet. It's likely sufficient to simply
enforce EXEC_OBJECT_PINNED for all objects on >= gen12.

Changes since v1:
- Split out eb_reserve() into separate functions for readability.
Changes since v2:
- Make batch buffer mappable on platforms where only GGTT is available,
  to prevent moving the batch buffer during relocations.
Changes since v3:
- Preserve current behavior for batch buffer, instead be cautious when
  calling i915_gem_object_ggtt_pin_ww, and re-use the current batch vma
  if it's inside ggtt and map-and-fenceable.
- Remove impossible condition check from eb_reserve. (Matt)

Signed-off-by: Maarten Lankhorst 
---
 .../gpu/drm/i915/gem/i915_gem_execbuffer.c| 250 ++
 drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c  |   1 -
 drivers/gpu/drm/i915/i915_gem_gtt.h   |   1 +
 drivers/gpu/drm/i915/i915_vma.c   |  24 +-
 4 files changed, 158 insertions(+), 118 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c 
b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
index 91ab43d67f47..b6a50631c21b 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
@@ -436,7 +436,7 @@ eb_pin_vma(struct i915_execbuffer *eb,
else
pin_flags = entry->offset & PIN_OFFSET_MASK;
 
-   pin_flags |= PIN_USER | PIN_NOEVICT | PIN_OFFSET_FIXED;
+   pin_flags |= PIN_USER | PIN_NOEVICT | PIN_OFFSET_FIXED | PIN_VALIDATE;
if (unlikely(ev->flags & EXEC_OBJECT_NEEDS_GTT))
pin_flags |= PIN_GLOBAL;
 
@@ -454,17 +454,15 @@ eb_pin_vma(struct i915_execbuffer *eb,
 entry->pad_to_size,
 entry->alignment,
 eb_pin_flags(entry, ev->flags) |
-PIN_USER | PIN_NOEVICT);
+PIN_USER | PIN_NOEVICT | 
PIN_VALIDATE);
if (unlikely(err))
return err;
}
 
if (unlikely(ev->flags & EXEC_OBJECT_NEEDS_FENCE)) {
err = i915_vma_pin_fence(vma);
-   if (unlikely(err)) {
-   i915_vma_unpin(vma);
+   if (unlikely(err))
return err;
-   }
 
if (vma->fence)
ev->flags |= __EXEC_OBJECT_HAS_FENCE;
@@ -480,13 +478,9 @@ eb_pin_vma(struct i915_execbuffer *eb,
 static inline void
 eb_unreserve_vma(struct eb_vma *ev)
 {
-   if (!(ev->flags & __EXEC_OBJECT_HAS_PIN))
-   return;
-
if (unlikely(ev->flags & __EXEC_OBJECT_HAS_FENCE))
__i915_vma_unpin_fence(ev->vma);
 
-   __i915_vma_unpin(ev->vma);
ev->flags &= ~__EXEC_OBJECT_RESERVED;
 }
 
@@ -679,10 +673,8 @@ static int eb_reserve_vma(struct i915_execbuffer *eb,
 
if (unlikely(ev->flags & EXEC_OBJECT_NEEDS_FENCE)) {
err = i915_vma_pin_fence(vma);
-   if (unlikely(err)) {
-   i915_vma_unpin(vma);
+   if (unlikely(err))
return err;
-   }
 
if (vma->fence)
ev->flags |= __EXEC_OBJECT_HAS_FENCE;
@@ -694,85 +686,125 @@ static int eb_reserve_vma(struct i915_execbuffer *eb,
return 0;
 }
 
-static int eb_reserve(struct i915_execbuffer *eb)
+static int eb_evict_vm(struct i915_execbuffer *eb)
 {
const unsigned int count = eb->buffer_count;
-   unsigned int pin_flags = PIN_USER | PIN_NONBLOCK;
+   unsigned int i;
+   int err;
+
+   err = mutex_lock_interruptible(&eb->context->vm->mutex);
+   if (err)
+   return err;
+
+   /* pin to protect against i915_gem_evict_vm evicting be

[PATCH v2 04/16] drm/i915: Take object lock in i915_ggtt_pin if ww is not set

2021-11-29 Thread Maarten Lankhorst
i915_vma_wait_for_bind needs the vma lock held, fix the caller.

Signed-off-by: Maarten Lankhorst 
---
 drivers/gpu/drm/i915/i915_vma.c | 40 +++--
 1 file changed, 28 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index feb43b5334dd..ecf97b3bf64f 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -1438,23 +1438,15 @@ static void flush_idle_contexts(struct intel_gt *gt)
intel_gt_wait_for_idle(gt, MAX_SCHEDULE_TIMEOUT);
 }
 
-int i915_ggtt_pin(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
- u32 align, unsigned int flags)
+static int __i915_ggtt_pin(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
+  u32 align, unsigned int flags)
 {
struct i915_address_space *vm = vma->vm;
int err;
 
-   GEM_BUG_ON(!i915_vma_is_ggtt(vma));
-
-#ifdef CONFIG_LOCKDEP
-   WARN_ON(!ww && dma_resv_held(vma->obj->base.resv));
-#endif
-
do {
-   if (ww)
-   err = i915_vma_pin_ww(vma, ww, 0, align, flags | 
PIN_GLOBAL);
-   else
-   err = i915_vma_pin(vma, 0, align, flags | PIN_GLOBAL);
+   err = i915_vma_pin_ww(vma, ww, 0, align, flags | PIN_GLOBAL);
+
if (err != -ENOSPC) {
if (!err) {
err = i915_vma_wait_for_bind(vma);
@@ -1473,6 +1465,30 @@ int i915_ggtt_pin(struct i915_vma *vma, struct 
i915_gem_ww_ctx *ww,
} while (1);
 }
 
+int i915_ggtt_pin(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
+ u32 align, unsigned int flags)
+{
+   struct i915_gem_ww_ctx _ww;
+   int err;
+
+   GEM_BUG_ON(!i915_vma_is_ggtt(vma));
+
+   if (ww)
+   return __i915_ggtt_pin(vma, ww, align, flags);
+
+#ifdef CONFIG_LOCKDEP
+   WARN_ON(dma_resv_held(vma->obj->base.resv));
+#endif
+
+   for_i915_gem_ww(&_ww, err, true) {
+   err = i915_gem_object_lock(vma->obj, &_ww);
+   if (!err)
+   err = __i915_ggtt_pin(vma, &_ww, align, flags);
+   }
+
+   return err;
+}
+
 static void __vma_close(struct i915_vma *vma, struct intel_gt *gt)
 {
/*
-- 
2.34.0



[PATCH v2 13/16] drm/i915: Require object lock when freeing pages during destruction

2021-11-29 Thread Maarten Lankhorst
TTM already requires this, and we require it for delayed destroy.

Signed-off-by: Maarten Lankhorst 
Reviewed-by: Matthew Auld 
---
 drivers/gpu/drm/i915/gem/i915_gem_object.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c 
b/drivers/gpu/drm/i915/gem/i915_gem_object.c
index 5fac9b560b73..39cd563544a5 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c
@@ -262,6 +262,8 @@ static void __i915_gem_object_free_mmaps(struct 
drm_i915_gem_object *obj)
  */
 void __i915_gem_object_pages_fini(struct drm_i915_gem_object *obj)
 {
+   assert_object_held(obj);
+
if (!list_empty(&obj->vma.list)) {
struct i915_vma *vma;
 
@@ -328,7 +330,10 @@ static void __i915_gem_free_objects(struct 
drm_i915_private *i915,
obj->ops->delayed_free(obj);
continue;
}
+
+   i915_gem_object_lock(obj, NULL);
__i915_gem_object_pages_fini(obj);
+   i915_gem_object_unlock(obj);
__i915_gem_free_object(obj);
 
/* But keep the pointer alive for RCU-protected lookups */
-- 
2.34.0



[PATCH v2 05/16] drm/i915: Force ww lock for i915_gem_object_ggtt_pin_ww

2021-11-29 Thread Maarten Lankhorst
We will need the lock to unbind the vma, and wait for bind to complete.
Remove the special casing for the !ww path, and force ww locking for all.

Signed-off-by: Maarten Lankhorst 
---
 drivers/gpu/drm/i915/i915_drv.h |  7 ++-
 drivers/gpu/drm/i915/i915_gem.c | 26 ++
 2 files changed, 24 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 1bfadd9127fc..8322abe194da 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1842,13 +1842,10 @@ i915_gem_object_ggtt_pin_ww(struct drm_i915_gem_object 
*obj,
const struct i915_ggtt_view *view,
u64 size, u64 alignment, u64 flags);
 
-static inline struct i915_vma * __must_check
+struct i915_vma * __must_check
 i915_gem_object_ggtt_pin(struct drm_i915_gem_object *obj,
 const struct i915_ggtt_view *view,
-u64 size, u64 alignment, u64 flags)
-{
-   return i915_gem_object_ggtt_pin_ww(obj, NULL, view, size, alignment, 
flags);
-}
+u64 size, u64 alignment, u64 flags);
 
 int i915_gem_object_unbind(struct drm_i915_gem_object *obj,
   unsigned long flags);
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 527228d4da7e..e83522953cde 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -877,6 +877,8 @@ i915_gem_object_ggtt_pin_ww(struct drm_i915_gem_object *obj,
struct i915_vma *vma;
int ret;
 
+   GEM_WARN_ON(!ww);
+
if (flags & PIN_MAPPABLE &&
(!view || view->type == I915_GGTT_VIEW_NORMAL)) {
/*
@@ -936,10 +938,7 @@ i915_gem_object_ggtt_pin_ww(struct drm_i915_gem_object 
*obj,
return ERR_PTR(ret);
}
 
-   if (ww)
-   ret = i915_vma_pin_ww(vma, ww, size, alignment, flags | 
PIN_GLOBAL);
-   else
-   ret = i915_vma_pin(vma, size, alignment, flags | PIN_GLOBAL);
+   ret = i915_vma_pin_ww(vma, ww, size, alignment, flags | PIN_GLOBAL);
 
if (ret)
return ERR_PTR(ret);
@@ -959,6 +958,25 @@ i915_gem_object_ggtt_pin_ww(struct drm_i915_gem_object 
*obj,
return vma;
 }
 
+struct i915_vma * __must_check
+i915_gem_object_ggtt_pin(struct drm_i915_gem_object *obj,
+const struct i915_ggtt_view *view,
+u64 size, u64 alignment, u64 flags)
+{
+   struct i915_gem_ww_ctx ww;
+   struct i915_vma *ret;
+   int err;
+
+   for_i915_gem_ww(&ww, err, true) {
+   err = i915_gem_object_lock(obj, &ww);
+   if (!err)
+   ret = i915_gem_object_ggtt_pin_ww(obj, &ww, view, size,
+ alignment, flags);
+   }
+
+   return err ? ERR_PTR(err) : ret;
+}
+
 int
 i915_gem_madvise_ioctl(struct drm_device *dev, void *data,
   struct drm_file *file_priv)
-- 
2.34.0



[PATCH v2 08/16] drm/i915: Pass trylock context to callers

2021-11-29 Thread Maarten Lankhorst
We are moving away from short term pinning, and need a way to evict
objects locked by the current context. Pass the ww context to all
eviction functions, so that they can evict objects that are already
locked by the current ww context.

On top of that, this slightly improves ww handling because the locked
objects are marked as locked by the correct ww.

Signed-off-by: Maarten Lankhorst 
---
 .../gpu/drm/i915/gem/i915_gem_execbuffer.c|  2 +-
 drivers/gpu/drm/i915/gem/i915_gem_object.h|  8 --
 drivers/gpu/drm/i915/gem/i915_gem_shrinker.c  |  4 +--
 drivers/gpu/drm/i915/gem/i915_gem_stolen.c|  2 +-
 drivers/gpu/drm/i915/gt/intel_engine_pm.c |  2 +-
 drivers/gpu/drm/i915/gt/intel_ggtt.c  |  2 +-
 drivers/gpu/drm/i915/gt/mock_engine.c |  2 +-
 drivers/gpu/drm/i915/gt/selftest_hangcheck.c  |  2 +-
 drivers/gpu/drm/i915/gt/selftest_migrate.c|  2 +-
 drivers/gpu/drm/i915/gvt/aperture_gm.c|  2 +-
 drivers/gpu/drm/i915/i915_drv.h   |  5 +++-
 drivers/gpu/drm/i915/i915_gem_evict.c | 15 ++-
 drivers/gpu/drm/i915/i915_gem_gtt.c   |  8 +++---
 drivers/gpu/drm/i915/i915_gem_gtt.h   |  3 +++
 drivers/gpu/drm/i915/i915_vgpu.c  |  2 +-
 drivers/gpu/drm/i915/i915_vma.c   | 13 +
 .../gpu/drm/i915/selftests/i915_gem_evict.c   | 27 ---
 drivers/gpu/drm/i915/selftests/i915_gem_gtt.c | 14 +-
 18 files changed, 70 insertions(+), 45 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c 
b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
index 9f7c6ecadb90..91ab43d67f47 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
@@ -761,7 +761,7 @@ static int eb_reserve(struct i915_execbuffer *eb)
case 1:
/* Too fragmented, unbind everything and retry */
mutex_lock(&eb->context->vm->mutex);
-   err = i915_gem_evict_vm(eb->context->vm);
+   err = i915_gem_evict_vm(eb->context->vm, &eb->ww);
mutex_unlock(&eb->context->vm->mutex);
if (err)
return err;
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h 
b/drivers/gpu/drm/i915/gem/i915_gem_object.h
index 66f20b803b01..f66d46882ea7 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h
@@ -210,9 +210,13 @@ static inline int 
i915_gem_object_lock_interruptible(struct drm_i915_gem_object
return __i915_gem_object_lock(obj, ww, true);
 }
 
-static inline bool i915_gem_object_trylock(struct drm_i915_gem_object *obj)
+static inline bool i915_gem_object_trylock(struct drm_i915_gem_object *obj,
+  struct i915_gem_ww_ctx *ww)
 {
-   return dma_resv_trylock(obj->base.resv);
+   if (!ww)
+   return dma_resv_trylock(obj->base.resv);
+   else
+   return ww_mutex_trylock(&obj->base.resv->lock, &ww->ctx);
 }
 
 static inline void i915_gem_object_unlock(struct drm_i915_gem_object *obj)
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c 
b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
index ad2123369e0d..85ff182ddbc2 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
@@ -216,7 +216,7 @@ i915_gem_shrink(struct i915_gem_ww_ctx *ww,
 
/* May arrive from get_pages on another bo */
if (!ww) {
-   if (!i915_gem_object_trylock(obj))
+   if (!i915_gem_object_trylock(obj, NULL))
goto skip;
} else {
err = i915_gem_object_lock(obj, ww);
@@ -410,7 +410,7 @@ i915_gem_shrinker_vmap(struct notifier_block *nb, unsigned 
long event, void *ptr
if (!vma->iomap || i915_vma_is_active(vma))
continue;
 
-   if (!i915_gem_object_trylock(obj))
+   if (!i915_gem_object_trylock(obj, NULL))
continue;
 
if (__i915_vma_unbind(vma) == 0)
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c 
b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
index 80680395bb3b..42b0b770929c 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
@@ -653,7 +653,7 @@ static int __i915_gem_object_create_stolen(struct 
intel_memory_region *mem,
cache_level = HAS_LLC(mem->i915) ? I915_CACHE_LLC : I915_CACHE_NONE;
i915_gem_object_set_cache_coherency(obj, cache_level);
 
-   if (WARN_ON(!i915_gem_object_trylock(obj)))
+   if (WARN_ON(!i915_gem_object_trylock(obj, NULL)))
return -EBUSY;
 
i915_gem_object_init_memory_region(obj, mem);
diff --git a/drivers/gpu/drm/i915/gt/intel_

[PATCH v2 02/16] drm/i915: Change shrink ordering to use locking around unbinding.

2021-11-29 Thread Maarten Lankhorst
Call drop_pages with the gem object lock held, instead of the other
way around. This will allow us to drop the vma bindings with the
gem object lock held.

We plan to require the object lock for unpinning in the future,
and this is an easy target.

Signed-off-by: Maarten Lankhorst 
Reviewed-by: Niranjana Vishwanathapura 
---
 drivers/gpu/drm/i915/gem/i915_gem_shrinker.c | 38 ++--
 1 file changed, 18 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c 
b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
index 157a9765f483..eebff4735781 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
@@ -36,8 +36,8 @@ static bool can_release_pages(struct drm_i915_gem_object *obj)
return swap_available() || obj->mm.madv == I915_MADV_DONTNEED;
 }
 
-static bool unsafe_drop_pages(struct drm_i915_gem_object *obj,
- unsigned long shrink, bool trylock_vm)
+static int drop_pages(struct drm_i915_gem_object *obj,
+  unsigned long shrink, bool trylock_vm)
 {
unsigned long flags;
 
@@ -214,26 +214,24 @@ i915_gem_shrink(struct i915_gem_ww_ctx *ww,
 
spin_unlock_irqrestore(&i915->mm.obj_lock, flags);
 
-   err = 0;
-   if (unsafe_drop_pages(obj, shrink, trylock_vm)) {
-   /* May arrive from get_pages on another bo */
-   if (!ww) {
-   if (!i915_gem_object_trylock(obj))
-   goto skip;
-   } else {
-   err = i915_gem_object_lock(obj, ww);
-   if (err)
-   goto skip;
-   }
-
-   if (!__i915_gem_object_put_pages(obj)) {
-   if (!try_to_writeback(obj, shrink))
-   count += obj->base.size >> 
PAGE_SHIFT;
-   }
-   if (!ww)
-   i915_gem_object_unlock(obj);
+   /* May arrive from get_pages on another bo */
+   if (!ww) {
+   if (!i915_gem_object_trylock(obj))
+   goto skip;
+   } else {
+   err = i915_gem_object_lock(obj, ww);
+   if (err)
+   goto skip;
}
 
+   if (drop_pages(obj, shrink, trylock_vm) &&
+   !__i915_gem_object_put_pages(obj) &&
+   !try_to_writeback(obj, shrink))
+   count += obj->base.size >> PAGE_SHIFT;
+
+   if (!ww)
+   i915_gem_object_unlock(obj);
+
scanned += obj->base.size >> PAGE_SHIFT;
 skip:
i915_gem_object_put(obj);
-- 
2.34.0



[PATCH v2 11/16] drm/i915: Call i915_gem_evict_vm in vm_fault_gtt to prevent new ENOSPC errors

2021-11-29 Thread Maarten Lankhorst
Now that we cannot unbind kill the currently locked object directly
because we're removing short term pinning, we may have to unbind the
object from gtt manually, using a i915_gem_evict_vm() call.

Signed-off-by: Maarten Lankhorst 
---
 drivers/gpu/drm/i915/gem/i915_gem_mman.c | 18 --
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c 
b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index 65fc6ff5f59d..6d557bb9926f 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -357,8 +357,22 @@ static vm_fault_t vm_fault_gtt(struct vm_fault *vmf)
vma = i915_gem_object_ggtt_pin_ww(obj, &ww, &view, 0, 
0, flags);
}
 
-   /* The entire mappable GGTT is pinned? Unexpected! */
-   GEM_BUG_ON(vma == ERR_PTR(-ENOSPC));
+   /*
+* The entire mappable GGTT is pinned? Unexpected!
+* Try to evict the object we locked too, as normally we skip it
+* due to lack of short term pinning inside execbuf.
+*/
+   if (vma == ERR_PTR(-ENOSPC)) {
+   ret = mutex_lock_interruptible(&ggtt->vm.mutex);
+   if (!ret) {
+   ret = i915_gem_evict_vm(&ggtt->vm, &ww);
+   mutex_unlock(&ggtt->vm.mutex);
+   }
+   if (ret)
+   goto err_reset;
+   vma = i915_gem_object_ggtt_pin_ww(obj, &ww, &view, 0, 
0, flags);
+   }
+   GEM_WARN_ON(vma == ERR_PTR(-ENOSPC));
}
if (IS_ERR(vma)) {
ret = PTR_ERR(vma);
-- 
2.34.0



[PATCH v2 03/16] drm/i915: Remove pages_mutex and intel_gtt->vma_ops.set/clear_pages members, v2.

2021-11-29 Thread Maarten Lankhorst
Big delta, but boils down to moving set_pages to i915_vma.c, and removing
the special handling, all callers use the defaults anyway. We only remap
in ggtt, so default case will fall through.

Because we still don't require locking in i915_vma_unpin(), handle this by
using xchg in get_pages(), as it's locked with obj->mutex, and cmpxchg in
unpin, which only fails if we race a against a new pin.

Changes since v1:
- aliasing gtt sets ZERO_SIZE_PTR, not -ENODEV, remove special case
  from __i915_vma_get_pages(). (Matt)

Signed-off-by: Maarten Lankhorst 
---
 drivers/gpu/drm/i915/display/intel_dpt.c  |   2 -
 drivers/gpu/drm/i915/gt/gen6_ppgtt.c  |  15 -
 drivers/gpu/drm/i915/gt/intel_ggtt.c  | 403 
 drivers/gpu/drm/i915/gt/intel_gtt.c   |  13 -
 drivers/gpu/drm/i915/gt/intel_gtt.h   |   7 -
 drivers/gpu/drm/i915/gt/intel_ppgtt.c |  12 -
 drivers/gpu/drm/i915/i915_vma.c   | 444 --
 drivers/gpu/drm/i915/i915_vma.h   |   3 +
 drivers/gpu/drm/i915/i915_vma_types.h |   1 -
 drivers/gpu/drm/i915/selftests/i915_gem_gtt.c |  12 +-
 drivers/gpu/drm/i915/selftests/mock_gtt.c |   4 -
 11 files changed, 424 insertions(+), 492 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dpt.c 
b/drivers/gpu/drm/i915/display/intel_dpt.c
index 56755788547d..f2ff70bcbac5 100644
--- a/drivers/gpu/drm/i915/display/intel_dpt.c
+++ b/drivers/gpu/drm/i915/display/intel_dpt.c
@@ -273,8 +273,6 @@ intel_dpt_create(struct intel_framebuffer *fb)
 
vm->vma_ops.bind_vma= dpt_bind_vma;
vm->vma_ops.unbind_vma  = dpt_unbind_vma;
-   vm->vma_ops.set_pages   = ggtt_set_pages;
-   vm->vma_ops.clear_pages = clear_pages;
 
vm->pte_encode = gen8_ggtt_pte_encode;
 
diff --git a/drivers/gpu/drm/i915/gt/gen6_ppgtt.c 
b/drivers/gpu/drm/i915/gt/gen6_ppgtt.c
index 4a166d25fe60..cfc9cc5880ec 100644
--- a/drivers/gpu/drm/i915/gt/gen6_ppgtt.c
+++ b/drivers/gpu/drm/i915/gt/gen6_ppgtt.c
@@ -269,19 +269,6 @@ static void gen6_ppgtt_cleanup(struct i915_address_space 
*vm)
free_pd(&ppgtt->base.vm, ppgtt->base.pd);
 }
 
-static int pd_vma_set_pages(struct i915_vma *vma)
-{
-   vma->pages = ERR_PTR(-ENODEV);
-   return 0;
-}
-
-static void pd_vma_clear_pages(struct i915_vma *vma)
-{
-   GEM_BUG_ON(!vma->pages);
-
-   vma->pages = NULL;
-}
-
 static void pd_vma_bind(struct i915_address_space *vm,
struct i915_vm_pt_stash *stash,
struct i915_vma *vma,
@@ -321,8 +308,6 @@ static void pd_vma_unbind(struct i915_address_space *vm, 
struct i915_vma *vma)
 }
 
 static const struct i915_vma_ops pd_vma_ops = {
-   .set_pages = pd_vma_set_pages,
-   .clear_pages = pd_vma_clear_pages,
.bind_vma = pd_vma_bind,
.unbind_vma = pd_vma_unbind,
 };
diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c 
b/drivers/gpu/drm/i915/gt/intel_ggtt.c
index 555111c3bee5..d9596087df08 100644
--- a/drivers/gpu/drm/i915/gt/intel_ggtt.c
+++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c
@@ -22,9 +22,6 @@
 #include "intel_gtt.h"
 #include "gen8_ppgtt.h"
 
-static int
-i915_get_ggtt_vma_pages(struct i915_vma *vma);
-
 static void i915_ggtt_color_adjust(const struct drm_mm_node *node,
   unsigned long color,
   u64 *start,
@@ -892,21 +889,6 @@ static int ggtt_probe_common(struct i915_ggtt *ggtt, u64 
size)
return 0;
 }
 
-int ggtt_set_pages(struct i915_vma *vma)
-{
-   int ret;
-
-   GEM_BUG_ON(vma->pages);
-
-   ret = i915_get_ggtt_vma_pages(vma);
-   if (ret)
-   return ret;
-
-   vma->page_sizes = vma->obj->mm.page_sizes;
-
-   return 0;
-}
-
 static void gen6_gmch_remove(struct i915_address_space *vm)
 {
struct i915_ggtt *ggtt = i915_vm_to_ggtt(vm);
@@ -967,8 +949,6 @@ static int gen8_gmch_probe(struct i915_ggtt *ggtt)
 
ggtt->vm.vma_ops.bind_vma= ggtt_bind_vma;
ggtt->vm.vma_ops.unbind_vma  = ggtt_unbind_vma;
-   ggtt->vm.vma_ops.set_pages   = ggtt_set_pages;
-   ggtt->vm.vma_ops.clear_pages = clear_pages;
 
ggtt->vm.pte_encode = gen8_ggtt_pte_encode;
 
@@ -1117,8 +1097,6 @@ static int gen6_gmch_probe(struct i915_ggtt *ggtt)
 
ggtt->vm.vma_ops.bind_vma= ggtt_bind_vma;
ggtt->vm.vma_ops.unbind_vma  = ggtt_unbind_vma;
-   ggtt->vm.vma_ops.set_pages   = ggtt_set_pages;
-   ggtt->vm.vma_ops.clear_pages = clear_pages;
 
return ggtt_probe_common(ggtt, size);
 }
@@ -1162,8 +1140,6 @@ static int i915_gmch_probe(struct i915_ggtt *ggtt)
 
ggtt->vm.vma_ops.bind_vma= ggtt_bind_vma;
ggtt->vm.vma_ops.unbind_vma  = ggtt_unbind_vma;
-   ggtt->vm.vma_ops.set_pages   = ggtt_set_pages;
-   ggtt->vm.vma_ops.clear_pages = clear_pages;
 
if (unlikely(ggtt->do_idle_maps))
drm_notice(&i915->drm,
@@ -1333,382 +1309,3 @@ void i915_ggtt_resume(struct i915_ggt

[PATCH v2 01/16] drm/i915: Remove unused bits of i915_vma/active api

2021-11-29 Thread Maarten Lankhorst
When reworking the code to move the eviction fence to the object,
the best code is removed code.

Remove some functions that are unused, and change the function definition
if it's only used in 1 place.

Signed-off-by: Maarten Lankhorst 
Reviewed-by: Niranjana Vishwanathapura 
[mlankhorst: Remove new use of i915_active_has_exclusive]
---
 drivers/gpu/drm/i915/i915_active.c | 28 +++-
 drivers/gpu/drm/i915/i915_active.h | 17 +
 drivers/gpu/drm/i915/i915_vma.c| 24 ++--
 drivers/gpu/drm/i915/i915_vma.h|  2 --
 4 files changed, 14 insertions(+), 57 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_active.c 
b/drivers/gpu/drm/i915/i915_active.c
index 3103c1e1fd14..ee2b3a375362 100644
--- a/drivers/gpu/drm/i915/i915_active.c
+++ b/drivers/gpu/drm/i915/i915_active.c
@@ -426,8 +426,9 @@ replace_barrier(struct i915_active *ref, struct 
i915_active_fence *active)
return true;
 }
 
-int i915_active_ref(struct i915_active *ref, u64 idx, struct dma_fence *fence)
+int i915_active_add_request(struct i915_active *ref, struct i915_request *rq)
 {
+   struct dma_fence *fence = &rq->fence;
struct i915_active_fence *active;
int err;
 
@@ -436,7 +437,7 @@ int i915_active_ref(struct i915_active *ref, u64 idx, 
struct dma_fence *fence)
if (err)
return err;
 
-   active = active_instance(ref, idx);
+   active = active_instance(ref, i915_request_timeline(rq)->fence_context);
if (!active) {
err = -ENOMEM;
goto out;
@@ -477,29 +478,6 @@ __i915_active_set_fence(struct i915_active *ref,
return prev;
 }
 
-static struct i915_active_fence *
-__active_fence(struct i915_active *ref, u64 idx)
-{
-   struct active_node *it;
-
-   it = __active_lookup(ref, idx);
-   if (unlikely(!it)) { /* Contention with parallel tree builders! */
-   spin_lock_irq(&ref->tree_lock);
-   it = __active_lookup(ref, idx);
-   spin_unlock_irq(&ref->tree_lock);
-   }
-   GEM_BUG_ON(!it); /* slot must be preallocated */
-
-   return &it->base;
-}
-
-struct dma_fence *
-__i915_active_ref(struct i915_active *ref, u64 idx, struct dma_fence *fence)
-{
-   /* Only valid while active, see i915_active_acquire_for_context() */
-   return __i915_active_set_fence(ref, __active_fence(ref, idx), fence);
-}
-
 struct dma_fence *
 i915_active_set_exclusive(struct i915_active *ref, struct dma_fence *f)
 {
diff --git a/drivers/gpu/drm/i915/i915_active.h 
b/drivers/gpu/drm/i915/i915_active.h
index 5fcdb0e2bc9e..7eb44132183a 100644
--- a/drivers/gpu/drm/i915/i915_active.h
+++ b/drivers/gpu/drm/i915/i915_active.h
@@ -164,26 +164,11 @@ void __i915_active_init(struct i915_active *ref,
__i915_active_init(ref, active, retire, flags, &__mkey, &__wkey);   
\
 } while (0)
 
-struct dma_fence *
-__i915_active_ref(struct i915_active *ref, u64 idx, struct dma_fence *fence);
-int i915_active_ref(struct i915_active *ref, u64 idx, struct dma_fence *fence);
-
-static inline int
-i915_active_add_request(struct i915_active *ref, struct i915_request *rq)
-{
-   return i915_active_ref(ref,
-  i915_request_timeline(rq)->fence_context,
-  &rq->fence);
-}
+int i915_active_add_request(struct i915_active *ref, struct i915_request *rq);
 
 struct dma_fence *
 i915_active_set_exclusive(struct i915_active *ref, struct dma_fence *f);
 
-static inline bool i915_active_has_exclusive(struct i915_active *ref)
-{
-   return rcu_access_pointer(ref->excl.fence);
-}
-
 int __i915_active_wait(struct i915_active *ref, int state);
 static inline int i915_active_wait(struct i915_active *ref)
 {
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index 927f0d4f8e11..921d5b946c32 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -356,22 +356,18 @@ int i915_vma_wait_for_bind(struct i915_vma *vma)
 #if IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)
 static int i915_vma_verify_bind_complete(struct i915_vma *vma)
 {
-   int err = 0;
-
-   if (i915_active_has_exclusive(&vma->active)) {
-   struct dma_fence *fence =
-   i915_active_fence_get(&vma->active.excl);
+   struct dma_fence *fence = i915_active_fence_get(&vma->active.excl);
+   int err;
 
-   if (!fence)
-   return 0;
+   if (!fence)
+   return 0;
 
-   if (dma_fence_is_signaled(fence))
-   err = fence->error;
-   else
-   err = -EBUSY;
+   if (dma_fence_is_signaled(fence))
+   err = fence->error;
+   else
+   err = -EBUSY;
 
-   dma_fence_put(fence);
-   }
+   dma_fence_put(fence);
 
return err;
 }
@@ -1249,7 +1245,7 @@ __i915_request_await_bind(struct i915_request *rq, struct 
i915_vma

[PATCH v2 07/16] drm/i915: Take trylock during eviction, v2.

2021-11-29 Thread Maarten Lankhorst
Now that freeing objects takes the object lock when destroying the
backing pages, we can confidently take the object lock even for dead
objects.

Use this fact to take the object lock in the shrinker, without requiring
a reference to the object, so all calls to unbind take the object lock.

This is the last step to requiring the object lock for vma_unbind.

Changes since v1:
- No longer require the refcount, as every freed object now holds the lock
  when unbinding VMA's.

Signed-off-by: Maarten Lankhorst 
---
 drivers/gpu/drm/i915/gem/i915_gem_shrinker.c |  6 
 drivers/gpu/drm/i915/i915_gem_evict.c| 34 +---
 2 files changed, 35 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c 
b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
index eebff4735781..ad2123369e0d 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
@@ -405,12 +405,18 @@ i915_gem_shrinker_vmap(struct notifier_block *nb, 
unsigned long event, void *ptr
list_for_each_entry_safe(vma, next,
 &i915->ggtt.vm.bound_list, vm_link) {
unsigned long count = vma->node.size >> PAGE_SHIFT;
+   struct drm_i915_gem_object *obj = vma->obj;
 
if (!vma->iomap || i915_vma_is_active(vma))
continue;
 
+   if (!i915_gem_object_trylock(obj))
+   continue;
+
if (__i915_vma_unbind(vma) == 0)
freed_pages += count;
+
+   i915_gem_object_unlock(obj);
}
mutex_unlock(&i915->ggtt.vm.mutex);
 
diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c 
b/drivers/gpu/drm/i915/i915_gem_evict.c
index 2b73ddb11c66..286efa462eca 100644
--- a/drivers/gpu/drm/i915/i915_gem_evict.c
+++ b/drivers/gpu/drm/i915/i915_gem_evict.c
@@ -58,6 +58,9 @@ mark_free(struct drm_mm_scan *scan,
if (i915_vma_is_pinned(vma))
return false;
 
+   if (!i915_gem_object_trylock(vma->obj))
+   return false;
+
list_add(&vma->evict_link, unwind);
return drm_mm_scan_add_block(scan, &vma->node);
 }
@@ -178,6 +181,7 @@ i915_gem_evict_something(struct i915_address_space *vm,
list_for_each_entry_safe(vma, next, &eviction_list, evict_link) {
ret = drm_mm_scan_remove_block(&scan, &vma->node);
BUG_ON(ret);
+   i915_gem_object_unlock(vma->obj);
}
 
/*
@@ -222,10 +226,12 @@ i915_gem_evict_something(struct i915_address_space *vm,
 * of any of our objects, thus corrupting the list).
 */
list_for_each_entry_safe(vma, next, &eviction_list, evict_link) {
-   if (drm_mm_scan_remove_block(&scan, &vma->node))
+   if (drm_mm_scan_remove_block(&scan, &vma->node)) {
__i915_vma_pin(vma);
-   else
+   } else {
list_del(&vma->evict_link);
+   i915_gem_object_unlock(vma->obj);
+   }
}
 
/* Unbinding will emit any required flushes */
@@ -234,16 +240,22 @@ i915_gem_evict_something(struct i915_address_space *vm,
__i915_vma_unpin(vma);
if (ret == 0)
ret = __i915_vma_unbind(vma);
+
+   i915_gem_object_unlock(vma->obj);
}
 
while (ret == 0 && (node = drm_mm_scan_color_evict(&scan))) {
vma = container_of(node, struct i915_vma, node);
 
+
/* If we find any non-objects (!vma), we cannot evict them */
-   if (vma->node.color != I915_COLOR_UNEVICTABLE)
+   if (vma->node.color != I915_COLOR_UNEVICTABLE &&
+   i915_gem_object_trylock(vma->obj)) {
ret = __i915_vma_unbind(vma);
-   else
-   ret = -ENOSPC; /* XXX search failed, try again? */
+   i915_gem_object_unlock(vma->obj);
+   } else {
+   ret = -ENOSPC;
+   }
}
 
return ret;
@@ -333,6 +345,11 @@ int i915_gem_evict_for_node(struct i915_address_space *vm,
break;
}
 
+   if (!i915_gem_object_trylock(vma->obj)) {
+   ret = -ENOSPC;
+   break;
+   }
+
/*
 * Never show fear in the face of dragons!
 *
@@ -350,6 +367,8 @@ int i915_gem_evict_for_node(struct i915_address_space *vm,
__i915_vma_unpin(vma);
if (ret == 0)
ret = __i915_vma_unbind(vma);
+
+   i915_gem_object_unlock(vma->obj);
}
 
return ret;
@@ -393,6 +412,9 @@ int i915_gem_evict_vm(struct i915_address_space *vm)
if (i915_vma_is_pinned(vma))
continue;
 
+   

[PATCH v2 14/16] drm/i915: Remove assert_object_held_shared

2021-11-29 Thread Maarten Lankhorst
This duck tape workaround is no longer required, unbind and destroy are
fixed to take the obj->resv mutex before destroying and obj->mm.lock has
been removed, always requiring obj->resv as well.

Signed-off-by: Maarten Lankhorst 
---
 drivers/gpu/drm/i915/gem/i915_gem_object.c  |  4 ++--
 drivers/gpu/drm/i915/gem/i915_gem_object.h  | 14 --
 drivers/gpu/drm/i915/gem/i915_gem_pages.c   | 12 ++--
 drivers/gpu/drm/i915/gem/i915_gem_userptr.c |  2 +-
 drivers/gpu/drm/i915/i915_vma.c |  6 +++---
 5 files changed, 12 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c 
b/drivers/gpu/drm/i915/gem/i915_gem_object.c
index 39cd563544a5..0ae86812ed66 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c
@@ -544,7 +544,7 @@ bool i915_gem_object_has_struct_page(const struct 
drm_i915_gem_object *obj)
 #ifdef CONFIG_LOCKDEP
if (IS_DGFX(to_i915(obj->base.dev)) &&
i915_gem_object_evictable((void __force *)obj))
-   assert_object_held_shared(obj);
+   assert_object_held(obj);
 #endif
return obj->mem_flags & I915_BO_FLAG_STRUCT_PAGE;
 }
@@ -563,7 +563,7 @@ bool i915_gem_object_has_iomem(const struct 
drm_i915_gem_object *obj)
 #ifdef CONFIG_LOCKDEP
if (IS_DGFX(to_i915(obj->base.dev)) &&
i915_gem_object_evictable((void __force *)obj))
-   assert_object_held_shared(obj);
+   assert_object_held(obj);
 #endif
return obj->mem_flags & I915_BO_FLAG_IOMEM;
 }
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h 
b/drivers/gpu/drm/i915/gem/i915_gem_object.h
index f66d46882ea7..09cf1c92373a 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h
@@ -157,20 +157,6 @@ i915_gem_object_put(struct drm_i915_gem_object *obj)
 
 #define assert_object_held(obj) dma_resv_assert_held((obj)->base.resv)
 
-/*
- * If more than one potential simultaneous locker, assert held.
- */
-static inline void assert_object_held_shared(const struct drm_i915_gem_object 
*obj)
-{
-   /*
-* Note mm list lookup is protected by
-* kref_get_unless_zero().
-*/
-   if (IS_ENABLED(CONFIG_LOCKDEP) &&
-   kref_read(&obj->base.refcount) > 0)
-   assert_object_held(obj);
-}
-
 static inline int __i915_gem_object_lock(struct drm_i915_gem_object *obj,
 struct i915_gem_ww_ctx *ww,
 bool intr)
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pages.c 
b/drivers/gpu/drm/i915/gem/i915_gem_pages.c
index 49c6e55c68ce..6805b46170be 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_pages.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_pages.c
@@ -19,7 +19,7 @@ void __i915_gem_object_set_pages(struct drm_i915_gem_object 
*obj,
bool shrinkable;
int i;
 
-   assert_object_held_shared(obj);
+   assert_object_held(obj);
 
if (i915_gem_object_is_volatile(obj))
obj->mm.madv = I915_MADV_DONTNEED;
@@ -95,7 +95,7 @@ int i915_gem_object_get_pages(struct drm_i915_gem_object 
*obj)
struct drm_i915_private *i915 = to_i915(obj->base.dev);
int err;
 
-   assert_object_held_shared(obj);
+   assert_object_held(obj);
 
if (unlikely(obj->mm.madv != I915_MADV_WILLNEED)) {
drm_dbg(&i915->drm,
@@ -122,7 +122,7 @@ int __i915_gem_object_get_pages(struct drm_i915_gem_object 
*obj)
 
assert_object_held(obj);
 
-   assert_object_held_shared(obj);
+   assert_object_held(obj);
 
if (unlikely(!i915_gem_object_has_pages(obj))) {
GEM_BUG_ON(i915_gem_object_has_pinned_pages(obj));
@@ -171,7 +171,7 @@ int i915_gem_object_truncate(struct drm_i915_gem_object 
*obj)
 /* Try to discard unwanted pages */
 void i915_gem_object_writeback(struct drm_i915_gem_object *obj)
 {
-   assert_object_held_shared(obj);
+   assert_object_held(obj);
GEM_BUG_ON(i915_gem_object_has_pages(obj));
 
if (obj->ops->writeback)
@@ -202,7 +202,7 @@ __i915_gem_object_unset_pages(struct drm_i915_gem_object 
*obj)
 {
struct sg_table *pages;
 
-   assert_object_held_shared(obj);
+   assert_object_held(obj);
 
pages = fetch_and_zero(&obj->mm.pages);
if (IS_ERR_OR_NULL(pages))
@@ -233,7 +233,7 @@ int __i915_gem_object_put_pages(struct drm_i915_gem_object 
*obj)
return -EBUSY;
 
/* May be called by shrinker from within get_pages() (on another bo) */
-   assert_object_held_shared(obj);
+   assert_object_held(obj);
 
i915_gem_object_release_mmap_offset(obj);
 
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c 
b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c
index 3173c9f9a040..a315c010f635 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c
@@ -109,7 +109,7 @@ static void i915_

[PATCH v2 00/16] drm/i915: Remove short term pins from execbuf.

2021-11-29 Thread Maarten Lankhorst
New version of the series, with feedback from previous series added.

First 11 patches are clean, some small fixes might required still for all to 
pass.

Maarten Lankhorst (16):
  drm/i915: Remove unused bits of i915_vma/active api
  drm/i915: Change shrink ordering to use locking around unbinding.
  drm/i915: Remove pages_mutex and intel_gtt->vma_ops.set/clear_pages
members, v2.
  drm/i915: Take object lock in i915_ggtt_pin if ww is not set
  drm/i915: Force ww lock for i915_gem_object_ggtt_pin_ww
  drm/i915: Ensure gem_contexts selftests work with unbind changes.
  drm/i915: Take trylock during eviction, v2.
  drm/i915: Pass trylock context to callers
  drm/i915: Ensure i915_vma tests do not get -ENOSPC with the locking
changes.
  drm/i915: Make i915_gem_evict_vm work correctly for already locked
objects
  drm/i915: Call i915_gem_evict_vm in vm_fault_gtt to prevent new ENOSPC
errors
  drm/i915: Add i915_vma_unbind_unlocked, and take obj lock for
i915_vma_unbind
  drm/i915: Require object lock when freeing pages during destruction
  drm/i915: Remove assert_object_held_shared
  drm/i915: Remove support for unlocked i915_vma unbind
  drm/i915: Remove short-term pins from execbuf, v5.

 drivers/gpu/drm/i915/display/intel_dpt.c  |   2 -
 drivers/gpu/drm/i915/display/intel_fb_pin.c   |   2 +-
 .../gpu/drm/i915/gem/i915_gem_execbuffer.c| 250 
 drivers/gpu/drm/i915/gem/i915_gem_mman.c  |  18 +-
 drivers/gpu/drm/i915/gem/i915_gem_object.c|   9 +-
 drivers/gpu/drm/i915/gem/i915_gem_object.h|  22 +-
 drivers/gpu/drm/i915/gem/i915_gem_pages.c |  12 +-
 drivers/gpu/drm/i915/gem/i915_gem_shrinker.c  |  44 +-
 drivers/gpu/drm/i915/gem/i915_gem_stolen.c|   2 +-
 drivers/gpu/drm/i915/gem/i915_gem_userptr.c   |   2 +-
 .../gpu/drm/i915/gem/selftests/huge_pages.c   |   2 +-
 .../i915/gem/selftests/i915_gem_client_blt.c  |   2 +-
 .../drm/i915/gem/selftests/i915_gem_context.c |  54 +-
 .../drm/i915/gem/selftests/i915_gem_mman.c|   6 +
 drivers/gpu/drm/i915/gt/gen6_ppgtt.c  |  15 -
 drivers/gpu/drm/i915/gt/intel_engine_pm.c |   2 +-
 drivers/gpu/drm/i915/gt/intel_ggtt.c  | 450 ++
 drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c  |   1 -
 drivers/gpu/drm/i915/gt/intel_gtt.c   |  13 -
 drivers/gpu/drm/i915/gt/intel_gtt.h   |   7 -
 drivers/gpu/drm/i915/gt/intel_ppgtt.c |  12 -
 drivers/gpu/drm/i915/gt/mock_engine.c |   2 +-
 drivers/gpu/drm/i915/gt/selftest_hangcheck.c  |   2 +-
 drivers/gpu/drm/i915/gt/selftest_migrate.c|   2 +-
 drivers/gpu/drm/i915/gvt/aperture_gm.c|   2 +-
 drivers/gpu/drm/i915/i915_active.c|  28 +-
 drivers/gpu/drm/i915/i915_active.h|  17 +-
 drivers/gpu/drm/i915/i915_drv.h   |  12 +-
 drivers/gpu/drm/i915/i915_gem.c   |  28 +-
 drivers/gpu/drm/i915/i915_gem_evict.c |  64 +-
 drivers/gpu/drm/i915/i915_gem_gtt.c   |   8 +-
 drivers/gpu/drm/i915/i915_gem_gtt.h   |   4 +
 drivers/gpu/drm/i915/i915_vgpu.c  |   2 +-
 drivers/gpu/drm/i915/i915_vma.c   | 580 +++---
 drivers/gpu/drm/i915/i915_vma.h   |   6 +-
 drivers/gpu/drm/i915/i915_vma_types.h |   1 -
 .../gpu/drm/i915/selftests/i915_gem_evict.c   |  27 +-
 drivers/gpu/drm/i915/selftests/i915_gem_gtt.c |  48 +-
 drivers/gpu/drm/i915/selftests/i915_vma.c |  19 +-
 drivers/gpu/drm/i915/selftests/mock_gtt.c |   4 -
 40 files changed, 942 insertions(+), 841 deletions(-)

-- 
2.34.0



[PATCH v2 06/16] drm/i915: Ensure gem_contexts selftests work with unbind changes.

2021-11-29 Thread Maarten Lankhorst
In the next commit, we don't evict when refcount = 0.

igt_vm_isolation() continuously tries to pin/unpin at same address,
but also calls put() on the object, which means the object may not
be unpinned in time.

Instead of this, re-use the same object over and over, so they can
be unbound as required.

Signed-off-by: Maarten Lankhorst 
---
 .../drm/i915/gem/selftests/i915_gem_context.c | 54 +++
 1 file changed, 32 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c 
b/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c
index b32f7fed2d9c..3fc595b57cf4 100644
--- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c
@@ -1481,10 +1481,10 @@ static int check_scratch(struct i915_address_space *vm, 
u64 offset)
 
 static int write_to_scratch(struct i915_gem_context *ctx,
struct intel_engine_cs *engine,
+   struct drm_i915_gem_object *obj,
u64 offset, u32 value)
 {
struct drm_i915_private *i915 = ctx->i915;
-   struct drm_i915_gem_object *obj;
struct i915_address_space *vm;
struct i915_request *rq;
struct i915_vma *vma;
@@ -1497,15 +1497,9 @@ static int write_to_scratch(struct i915_gem_context *ctx,
if (err)
return err;
 
-   obj = i915_gem_object_create_internal(i915, PAGE_SIZE);
-   if (IS_ERR(obj))
-   return PTR_ERR(obj);
-
cmd = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WB);
-   if (IS_ERR(cmd)) {
-   err = PTR_ERR(cmd);
-   goto out;
-   }
+   if (IS_ERR(cmd))
+   return PTR_ERR(cmd);
 
*cmd++ = MI_STORE_DWORD_IMM_GEN4;
if (GRAPHICS_VER(i915) >= 8) {
@@ -1569,17 +1563,19 @@ static int write_to_scratch(struct i915_gem_context 
*ctx,
i915_vma_unpin(vma);
 out_vm:
i915_vm_put(vm);
-out:
-   i915_gem_object_put(obj);
+
+   if (!err)
+   err = i915_gem_object_wait(obj, 0, MAX_SCHEDULE_TIMEOUT);
+
return err;
 }
 
 static int read_from_scratch(struct i915_gem_context *ctx,
 struct intel_engine_cs *engine,
+struct drm_i915_gem_object *obj,
 u64 offset, u32 *value)
 {
struct drm_i915_private *i915 = ctx->i915;
-   struct drm_i915_gem_object *obj;
struct i915_address_space *vm;
const u32 result = 0x100;
struct i915_request *rq;
@@ -1594,10 +1590,6 @@ static int read_from_scratch(struct i915_gem_context 
*ctx,
if (err)
return err;
 
-   obj = i915_gem_object_create_internal(i915, PAGE_SIZE);
-   if (IS_ERR(obj))
-   return PTR_ERR(obj);
-
if (GRAPHICS_VER(i915) >= 8) {
const u32 GPR0 = engine->mmio_base + 0x600;
 
@@ -1615,7 +1607,7 @@ static int read_from_scratch(struct i915_gem_context *ctx,
cmd = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WB);
if (IS_ERR(cmd)) {
err = PTR_ERR(cmd);
-   goto out;
+   goto err_unpin;
}
 
memset(cmd, POISON_INUSE, PAGE_SIZE);
@@ -1651,7 +1643,7 @@ static int read_from_scratch(struct i915_gem_context *ctx,
cmd = i915_gem_object_pin_map_unlocked(obj, I915_MAP_WB);
if (IS_ERR(cmd)) {
err = PTR_ERR(cmd);
-   goto out;
+   goto err_unpin;
}
 
memset(cmd, POISON_INUSE, PAGE_SIZE);
@@ -1722,8 +1714,10 @@ static int read_from_scratch(struct i915_gem_context 
*ctx,
i915_vma_unpin(vma);
 out_vm:
i915_vm_put(vm);
-out:
-   i915_gem_object_put(obj);
+
+   if (!err)
+   err = i915_gem_object_wait(obj, 0, MAX_SCHEDULE_TIMEOUT);
+
return err;
 }
 
@@ -1765,6 +1759,7 @@ static int igt_vm_isolation(void *arg)
u64 vm_total;
u32 expected;
int err;
+   struct drm_i915_gem_object *obj_a, *obj_b;
 
if (GRAPHICS_VER(i915) < 7)
return 0;
@@ -1810,6 +1805,18 @@ static int igt_vm_isolation(void *arg)
vm_total = ctx_a->vm->total;
GEM_BUG_ON(ctx_b->vm->total != vm_total);
 
+   obj_a = i915_gem_object_create_internal(i915, PAGE_SIZE);
+   if (IS_ERR(obj_a)) {
+   err = PTR_ERR(obj_a);
+   goto out_file;
+   }
+
+   obj_b = i915_gem_object_create_internal(i915, PAGE_SIZE);
+   if (IS_ERR(obj_b)) {
+   err = PTR_ERR(obj_b);
+   goto put_a;
+   }
+
count = 0;
num_engines = 0;
for_each_uabi_engine(engine, i915) {
@@ -1832,10 +1839,10 @@ static int igt_vm_isolation(void *arg)
   I915_GTT_PAGE_SIZE, vm_total,

Re: [PATCH 28/28] drm/i915: Remove short-term pins from execbuf, v4.

2021-11-29 Thread Maarten Lankhorst
On 25-10-2021 17:02, Matthew Auld wrote:
> On Thu, 21 Oct 2021 at 11:37, Maarten Lankhorst
>  wrote:
>> Add a flag PIN_VALIDATE, to indicate we don't need to pin and only
>> protected by the object lock.
>>
>> This removes the need to unpin, which is done by just releasing the
>> lock.
>>
>> eb_reserve is slightly reworked for readability, but the same steps
>> are still done:
>> - First pass pins with NONBLOCK.
>> - Second pass unbinds all objects first, then pins.
>> - Third pass is only called when not all objects are softpinned, and
>>   unbinds all objects, then calls i915_gem_evict_vm(), then pins.
>>
>> When evicting the entire vm in eb_reserve() we do temporarily pin objects
>> that are marked with EXEC_OBJECT_PINNED. This is because they are already
>> at their destination, and i915_gem_evict_vm() would otherwise unbind them.
>>
>> However, we reduce the visibility of those pins by limiting the pin
>> to our call to i915_gem_evict_vm() only, and pin with vm->mutex held,
>> instead of the entire duration of the execbuf.
>>
>> Not sure the latter matters, one can hope..
>> In theory we could kill the pinning by adding an extra flag to the vma
>> to temporarily prevent unbinding for gtt for i915_gem_evict_vm only, but
>> I think that might be overkill. We're still holding the object lock, and
>> we don't have blocking eviction yet. It's likely sufficient to simply
>> enforce EXEC_OBJECT_PINNED for all objects on >= gen12.
>>
>> Changes since v1:
>> - Split out eb_reserve() into separate functions for readability.
>> Changes since v2:
>> - Make batch buffer mappable on platforms where only GGTT is available,
>>   to prevent moving the batch buffer during relocations.
>> Changes since v3:
>> - Preserve current behavior for batch buffer, instead be cautious when
>>   calling i915_gem_object_ggtt_pin_ww, and re-use the current batch vma
>>   if it's inside ggtt and map-and-fenceable.
>>
>> Signed-off-by: Maarten Lankhorst 
>> ---
>>  .../gpu/drm/i915/gem/i915_gem_execbuffer.c| 252 ++
>>  drivers/gpu/drm/i915/i915_gem_gtt.h   |   1 +
>>  drivers/gpu/drm/i915/i915_vma.c   |  24 +-
>>  3 files changed, 161 insertions(+), 116 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c 
>> b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
>> index bbf2a10738f7..19f91143cfcf 100644
>> --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
>> @@ -439,7 +439,7 @@ eb_pin_vma(struct i915_execbuffer *eb,
>> else
>> pin_flags = entry->offset & PIN_OFFSET_MASK;
>>
>> -   pin_flags |= PIN_USER | PIN_NOEVICT | PIN_OFFSET_FIXED;
>> +   pin_flags |= PIN_USER | PIN_NOEVICT | PIN_OFFSET_FIXED | 
>> PIN_VALIDATE;
>> if (unlikely(ev->flags & EXEC_OBJECT_NEEDS_GTT))
>> pin_flags |= PIN_GLOBAL;
>>
>> @@ -457,17 +457,15 @@ eb_pin_vma(struct i915_execbuffer *eb,
>>  entry->pad_to_size,
>>  entry->alignment,
>>  eb_pin_flags(entry, ev->flags) |
>> -PIN_USER | PIN_NOEVICT);
>> +PIN_USER | PIN_NOEVICT | 
>> PIN_VALIDATE);
>> if (unlikely(err))
>> return err;
>> }
>>
>> if (unlikely(ev->flags & EXEC_OBJECT_NEEDS_FENCE)) {
>> err = i915_vma_pin_fence(vma);
>> -   if (unlikely(err)) {
>> -   i915_vma_unpin(vma);
>> +   if (unlikely(err))
>> return err;
>> -   }
>>
>> if (vma->fence)
>> ev->flags |= __EXEC_OBJECT_HAS_FENCE;
>> @@ -483,13 +481,9 @@ eb_pin_vma(struct i915_execbuffer *eb,
>>  static inline void
>>  eb_unreserve_vma(struct eb_vma *ev)
>>  {
>> -   if (!(ev->flags & __EXEC_OBJECT_HAS_PIN))
>> -   return;
>> -
>> if (unlikely(ev->flags & __EXEC_OBJECT_HAS_FENCE))
>> __i915_vma_unpin_fence(ev->vma);
>>
>> -   __i915_vma_unpin(ev->vma);
>> ev->flags &= ~__EXEC_OBJECT_RESERVED;
>>  }
>>
>> @@ -682,10 +676,8 @@ static int eb_reserve_vma(struct i915_execbuffer *eb,
>>
>> if (unlikely(ev->flags & EXEC_OBJECT_NEEDS_FENCE)) {
>> err = i915_vma_pin_fence(vma);
>> -   if (unlikely(err)) {
>> -   i915_vma_unpin(vma);
>> +   if (unlikely(err))
>> return err;
>> -   }
>>
>> if (vma->fence)
>> ev->flags |= __EXEC_OBJECT_HAS_FENCE;
>> @@ -697,85 +689,129 @@ static int eb_reserve_vma(struct i915_execbuffer *eb,
>> return 0;
>>  }
>>
>> -static int eb_reserve(struct i915_execbuffer *eb)
>> +static int eb_evict_vm(struct i915_execbuffer *eb)
>> +{
>> +   const unsigned 

Re: [Intel-gfx] [PATCH 15/28] drm/i915: Add lock for unbinding to i915_gem_object_ggtt_pin_ww

2021-11-29 Thread Maarten Lankhorst
On 21-10-2021 19:48, Matthew Auld wrote:
> On Thu, 21 Oct 2021 at 11:37, Maarten Lankhorst
>  wrote:
>> Signed-off-by: Maarten Lankhorst 
> Needs a proper commit message.

What about this?


>> ---
>>  drivers/gpu/drm/i915/i915_gem.c | 9 -
>>  1 file changed, 8 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/i915/i915_gem.c 
>> b/drivers/gpu/drm/i915/i915_gem.c
>> index 981e383d1a5d..6aa9e465b48e 100644
>> --- a/drivers/gpu/drm/i915/i915_gem.c
>> +++ b/drivers/gpu/drm/i915/i915_gem.c
>> @@ -931,7 +931,14 @@ i915_gem_object_ggtt_pin_ww(struct drm_i915_gem_object 
>> *obj,
>> goto new_vma;
>> }
>>
>> -   ret = i915_vma_unbind(vma);
>> +   ret = 0;
>> +   if (!ww)
>> +   ret = i915_gem_object_lock_interruptible(obj, NULL);
>> +   if (!ret) {
>> +   ret = i915_vma_unbind(vma);
>> +   if (!ww)
>> +   i915_gem_object_unlock(obj);
>> +   }
> There is also a wait_for_bind below. Do we need the lock for that also?

Hmm good find.

Not sure if required in this patch series. I have some patches on top that 
require the lock because of async binding / unbinding, that would need it for 
sure.

I will fix this function to use WARN_ON(!ww), and add ww handling to 
i915_gem_object_ggtt_pin(). That should fix all issues without special casing 
!ww.

~Maarten



Re: [PATCH] dma_fence_array: Fix PENDING_ERROR leak in dma_fence_array_signaled()

2021-11-29 Thread Joonas Lahtinen
(Switching to my @linux.intel.com address)

Quoting Christian König (2021-11-29 14:55:37)
> Am 29.11.21 um 13:46 schrieb Thomas Hellström:
> > On Mon, 2021-11-29 at 13:33 +0100, Christian König wrote:
> >> Am 29.11.21 um 13:23 schrieb Thomas Hellström:
> >>> Hi, Christian,
> >>>
> >>> On Mon, 2021-11-29 at 09:21 +0100, Christian König wrote:
>  Am 29.11.21 um 08:35 schrieb Thomas Hellström:
> > If a dma_fence_array is reported signaled by a call to
> > dma_fence_is_signaled(), it may leak the PENDING_ERROR status.
> >
> > Fix this by clearing the PENDING_ERROR status if we return true
> > in
> > dma_fence_array_signaled().
> >
> > Fixes: 1f70b8b812f3 ("dma-fence: Propagate errors to dma-fence-
> > array container")
> > Cc: linaro-mm-...@lists.linaro.org
> > Cc: Christian König 
> > Cc: Chris Wilson 
> > Signed-off-by: Thomas Hellström
> > 
>  Reviewed-by: Christian König 
> >>> How are the dma-buf / dma-fence patches typically merged? If i915
> >>> is
> >>> the only fence->error user, could we take this through drm-intel to
> >>> avoid a backmerge for upcoming i915 work?
> >> Well that one here looks like a bugfix to me, so either through
> >> drm-misc-fixes ore some i915 -fixes branch sounds fine to me.
> >>
> >> If you have any new development based on that a backmerge of the -
> >> fixes
> >> into your -next branch is unavoidable anyway.
> > Ok, I'll check with Joonas if I can take it through
> > drm-intel-gt-next, since fixes are cherry-picked from that one. Patch
> > will then appear in both the -fixes and the -next branch.
> 
> Well exactly that's the stuff Daniel told me to avoid :)
> 
> But maybe your i915 workflow is somehow better handling that than the 
> AMD workflow.

If it's a bugfix to a patch that merged through drm-misc-next, I'd
always be inclined to merge the fixup using the same process (which
would be drm-next-fixes).

In i915 we do always merge the patches to -next first, and never do a
backmerge of -fixes (as it's a cherry-picked branch) so the workflows
differ there.

Here the time between the fixup and the previous patch is so long that
either way is fine with. So feel free to apply to drm-intel-gt-next.

Regards, Joonas

> Christian.
> 
> >
> > Thanks,
> > /Thomas
> >
> >
> >> Regards,
> >> Christian.
> >>
> >>> /Thomas
> >>>
> >>>
> > ---
> >     drivers/dma-buf/dma-fence-array.c | 6 +-
> >     1 file changed, 5 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/dma-buf/dma-fence-array.c b/drivers/dma-
> > buf/dma-fence-array.c
> > index d3fbd950be94..3e07f961e2f3 100644
> > --- a/drivers/dma-buf/dma-fence-array.c
> > +++ b/drivers/dma-buf/dma-fence-array.c
> > @@ -104,7 +104,11 @@ static bool
> > dma_fence_array_signaled(struct
> > dma_fence *fence)
> >     {
> >   struct dma_fence_array *array =
> > to_dma_fence_array(fence);
> > 
> > -   return atomic_read(&array->num_pending) <= 0;
> > +   if (atomic_read(&array->num_pending) > 0)
> > +   return false;
> > +
> > +   dma_fence_array_clear_pending_error(array);
> > +   return true;
> >     }
> > 
> >     static void dma_fence_array_release(struct dma_fence *fence)
> >
> 


Re: [PATCH v3 1/9] drm: vkms: Replace the deprecated drm_mode_config_init

2021-11-29 Thread Igor Torrente
Hi Nícolas,

On Thu, Nov 25, 2021 at 1:37 AM Nícolas F. R. A. Prado  
wrote:
>
> Hi Igor,
>
> just some nits on the commit message.
>
> On Mon, Nov 22, 2021 at 04:43:52PM -0300, Igor Torrente wrote:
> > The `drm_mode_config_init` was deprecated since c3b790e commit, and it's
>
> When referring to other commits, it's best to write it as 'commit 
> <12-digit-SHA>
> ("description")' [1]. Also, imperative mood works best, so my suggestion would
> be:
>
> `drm_mode_config_init` is deprecated since commit c3b790ea07a1 ("drm: Manage
> drm_mode_config_init with drmm_") in favor of `drmm_mode_config_init`. Update
> the former to the latter.

Looks better indeed. I will change it to V4. Thanks!


>
> Thanks,
> Nícolas
>
> [1] 
> https://www.kernel.org/doc/html/latest/process/submitting-patches.html#describe-your-changes
>
> > being replaced by the `drmm_mode_config_init`.
> >
> > Signed-off-by: Igor Torrente 
> > ---
> > V2: Change the code style(Thomas Zimmermann).
> > ---
> >  drivers/gpu/drm/vkms/vkms_drv.c | 6 +-
> >  1 file changed, 5 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/gpu/drm/vkms/vkms_drv.c 
> > b/drivers/gpu/drm/vkms/vkms_drv.c
> > index 0ffe5f0e33f7..ee4d96dabe19 100644
> > --- a/drivers/gpu/drm/vkms/vkms_drv.c
> > +++ b/drivers/gpu/drm/vkms/vkms_drv.c
> > @@ -140,8 +140,12 @@ static const struct drm_mode_config_helper_funcs 
> > vkms_mode_config_helpers = {
> >  static int vkms_modeset_init(struct vkms_device *vkmsdev)
> >  {
> >   struct drm_device *dev = &vkmsdev->drm;
> > + int ret;
> > +
> > + ret = drmm_mode_config_init(dev);
> > + if (ret < 0)
> > + return ret;
> >
> > - drm_mode_config_init(dev);
> >   dev->mode_config.funcs = &vkms_mode_funcs;
> >   dev->mode_config.min_width = XRES_MIN;
> >   dev->mode_config.min_height = YRES_MIN;
> > --
> > 2.30.2
> >


Re: [PATCH] dma_fence_array: Fix PENDING_ERROR leak in dma_fence_array_signaled()

2021-11-29 Thread Christian König

Am 29.11.21 um 13:46 schrieb Thomas Hellström:

On Mon, 2021-11-29 at 13:33 +0100, Christian König wrote:

Am 29.11.21 um 13:23 schrieb Thomas Hellström:

Hi, Christian,

On Mon, 2021-11-29 at 09:21 +0100, Christian König wrote:

Am 29.11.21 um 08:35 schrieb Thomas Hellström:

If a dma_fence_array is reported signaled by a call to
dma_fence_is_signaled(), it may leak the PENDING_ERROR status.

Fix this by clearing the PENDING_ERROR status if we return true
in
dma_fence_array_signaled().

Fixes: 1f70b8b812f3 ("dma-fence: Propagate errors to dma-fence-
array container")
Cc: linaro-mm-...@lists.linaro.org
Cc: Christian König 
Cc: Chris Wilson 
Signed-off-by: Thomas Hellström


Reviewed-by: Christian König 

How are the dma-buf / dma-fence patches typically merged? If i915
is
the only fence->error user, could we take this through drm-intel to
avoid a backmerge for upcoming i915 work?

Well that one here looks like a bugfix to me, so either through
drm-misc-fixes ore some i915 -fixes branch sounds fine to me.

If you have any new development based on that a backmerge of the -
fixes
into your -next branch is unavoidable anyway.

Ok, I'll check with Joonas if I can take it through
drm-intel-gt-next, since fixes are cherry-picked from that one. Patch
will then appear in both the -fixes and the -next branch.


Well exactly that's the stuff Daniel told me to avoid :)

But maybe your i915 workflow is somehow better handling that than the 
AMD workflow.


Christian.



Thanks,
/Thomas



Regards,
Christian.


/Thomas



---
    drivers/dma-buf/dma-fence-array.c | 6 +-
    1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/dma-buf/dma-fence-array.c b/drivers/dma-
buf/dma-fence-array.c
index d3fbd950be94..3e07f961e2f3 100644
--- a/drivers/dma-buf/dma-fence-array.c
+++ b/drivers/dma-buf/dma-fence-array.c
@@ -104,7 +104,11 @@ static bool
dma_fence_array_signaled(struct
dma_fence *fence)
    {
  struct dma_fence_array *array =
to_dma_fence_array(fence);

-   return atomic_read(&array->num_pending) <= 0;

+   if (atomic_read(&array->num_pending) > 0)
+   return false;
+
+   dma_fence_array_clear_pending_error(array);
+   return true;
    }

    static void dma_fence_array_release(struct dma_fence *fence)






Re: [PATCH] dma_fence_array: Fix PENDING_ERROR leak in dma_fence_array_signaled()

2021-11-29 Thread Thomas Hellström
On Mon, 2021-11-29 at 13:33 +0100, Christian König wrote:
> Am 29.11.21 um 13:23 schrieb Thomas Hellström:
> > Hi, Christian,
> > 
> > On Mon, 2021-11-29 at 09:21 +0100, Christian König wrote:
> > > Am 29.11.21 um 08:35 schrieb Thomas Hellström:
> > > > If a dma_fence_array is reported signaled by a call to
> > > > dma_fence_is_signaled(), it may leak the PENDING_ERROR status.
> > > > 
> > > > Fix this by clearing the PENDING_ERROR status if we return true
> > > > in
> > > > dma_fence_array_signaled().
> > > > 
> > > > Fixes: 1f70b8b812f3 ("dma-fence: Propagate errors to dma-fence-
> > > > array container")
> > > > Cc: linaro-mm-...@lists.linaro.org
> > > > Cc: Christian König 
> > > > Cc: Chris Wilson 
> > > > Signed-off-by: Thomas Hellström
> > > > 
> > > Reviewed-by: Christian König 
> > How are the dma-buf / dma-fence patches typically merged? If i915
> > is
> > the only fence->error user, could we take this through drm-intel to
> > avoid a backmerge for upcoming i915 work?
> 
> Well that one here looks like a bugfix to me, so either through 
> drm-misc-fixes ore some i915 -fixes branch sounds fine to me.
> 
> If you have any new development based on that a backmerge of the -
> fixes 
> into your -next branch is unavoidable anyway.

Ok, I'll check with Joonas if I can take it through
drm-intel-gt-next, since fixes are cherry-picked from that one. Patch
will then appear in both the -fixes and the -next branch.

Thanks,
/Thomas


> 
> Regards,
> Christian.
> 
> > 
> > /Thomas
> > 
> > 
> > > > ---
> > > >    drivers/dma-buf/dma-fence-array.c | 6 +-
> > > >    1 file changed, 5 insertions(+), 1 deletion(-)
> > > > 
> > > > diff --git a/drivers/dma-buf/dma-fence-array.c b/drivers/dma-
> > > > buf/dma-fence-array.c
> > > > index d3fbd950be94..3e07f961e2f3 100644
> > > > --- a/drivers/dma-buf/dma-fence-array.c
> > > > +++ b/drivers/dma-buf/dma-fence-array.c
> > > > @@ -104,7 +104,11 @@ static bool
> > > > dma_fence_array_signaled(struct
> > > > dma_fence *fence)
> > > >    {
> > > >  struct dma_fence_array *array =
> > > > to_dma_fence_array(fence);
> > > >    
> > > > -   return atomic_read(&array->num_pending) <= 0;
> > > > +   if (atomic_read(&array->num_pending) > 0)
> > > > +   return false;
> > > > +
> > > > +   dma_fence_array_clear_pending_error(array);
> > > > +   return true;
> > > >    }
> > > >    
> > > >    static void dma_fence_array_release(struct dma_fence *fence)
> > 
> 




Re: [Intel-gfx] [PATCH 14/28] drm/i915: Take object lock in i915_ggtt_pin if ww is not set

2021-11-29 Thread Maarten Lankhorst
On 21-10-2021 19:39, Matthew Auld wrote:
> On Thu, 21 Oct 2021 at 11:37, Maarten Lankhorst
>  wrote:
>> i915_vma_wait_for_bind needs the vma lock held, fix the caller.
>>
>> Signed-off-by: Maarten Lankhorst 
>> ---
>>  drivers/gpu/drm/i915/i915_vma.c | 40 +++--
>>  1 file changed, 28 insertions(+), 12 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/i915_vma.c 
>> b/drivers/gpu/drm/i915/i915_vma.c
>> index bacc8d68e495..2877dcd62acb 100644
>> --- a/drivers/gpu/drm/i915/i915_vma.c
>> +++ b/drivers/gpu/drm/i915/i915_vma.c
>> @@ -1348,23 +1348,15 @@ static void flush_idle_contexts(struct intel_gt *gt)
>> intel_gt_wait_for_idle(gt, MAX_SCHEDULE_TIMEOUT);
>>  }
>>
>> -int i915_ggtt_pin(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
>> - u32 align, unsigned int flags)
>> +static int __i915_ggtt_pin(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
>> +  u32 align, unsigned int flags)
>>  {
>> struct i915_address_space *vm = vma->vm;
>> int err;
>>
>> -   GEM_BUG_ON(!i915_vma_is_ggtt(vma));
>> -
>> -#ifdef CONFIG_LOCKDEP
>> -   WARN_ON(!ww && dma_resv_held(vma->obj->base.resv));
>> -#endif
>> -
>> do {
>> -   if (ww)
>> -   err = i915_vma_pin_ww(vma, ww, 0, align, flags | 
>> PIN_GLOBAL);
>> -   else
>> -   err = i915_vma_pin(vma, 0, align, flags | 
>> PIN_GLOBAL);
>> +   err = i915_vma_pin_ww(vma, ww, 0, align, flags | PIN_GLOBAL);
>> +
>> if (err != -ENOSPC) {
>> if (!err) {
>> err = i915_vma_wait_for_bind(vma);
>> @@ -1383,6 +1375,30 @@ int i915_ggtt_pin(struct i915_vma *vma, struct 
>> i915_gem_ww_ctx *ww,
>> } while (1);
>>  }
>>
>> +int i915_ggtt_pin(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
>> + u32 align, unsigned int flags)
>> +{
>> +   struct i915_gem_ww_ctx _ww;
>> +   int err;
>> +
>> +   GEM_BUG_ON(!i915_vma_is_ggtt(vma));
>> +
>> +   if (ww)
>> +   return __i915_ggtt_pin(vma, ww, align, flags);
>> +
>> +#ifdef CONFIG_LOCKDEP
>> +   WARN_ON(dma_resv_held(vma->obj->base.resv));
> Hmm, so this can't trigger, say if shrinker grabs the lock, or some
> other concurrent user?

No, it checks internally in lockdep that the current task doesn't hold the 
lock. Others can lock just fine.

dma_resv_is_locked() would check if anyone locked it. :)

~Maarten



Re: [Intel-gfx] [PATCH 13/28] drm/i915: Remove pages_mutex and intel_gtt->vma_ops.set/clear_pages members

2021-11-29 Thread Maarten Lankhorst
On 22-10-2021 12:59, Matthew Auld wrote:
> On Thu, 21 Oct 2021 at 18:30, Matthew Auld
>  wrote:
>> On Thu, 21 Oct 2021 at 11:36, Maarten Lankhorst
>>  wrote:
>>> Big delta, but boils down to moving set_pages to i915_vma.c, and removing
>>> the special handling, all callers use the defaults anyway. We only remap
>>> in ggtt, so default case will fall through.
>>>
>>> Because we still don't require locking in i915_vma_unpin(), handle this by
>>> using xchg in get_pages(), as it's locked with obj->mutex, and cmpxchg in
>>> unpin, which only fails if we race a against a new pin.
>>>
>>> Signed-off-by: Maarten Lankhorst 
>>> ---
>>>  drivers/gpu/drm/i915/display/intel_dpt.c  |   2 -
>>>  drivers/gpu/drm/i915/gt/gen6_ppgtt.c  |  15 -
>>>  drivers/gpu/drm/i915/gt/intel_ggtt.c  | 345 
>>>  drivers/gpu/drm/i915/gt/intel_gtt.c   |  13 -
>>>  drivers/gpu/drm/i915/gt/intel_gtt.h   |   7 -
>>>  drivers/gpu/drm/i915/gt/intel_ppgtt.c |  12 -
>>>  drivers/gpu/drm/i915/i915_vma.c   | 388 --
>>>  drivers/gpu/drm/i915/i915_vma.h   |   3 +
>>>  drivers/gpu/drm/i915/i915_vma_types.h |   1 -
>>>  drivers/gpu/drm/i915/selftests/i915_gem_gtt.c |  12 +-
>>>  drivers/gpu/drm/i915/selftests/mock_gtt.c |   4 -
>>>  11 files changed, 368 insertions(+), 434 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/i915/display/intel_dpt.c 
>>> b/drivers/gpu/drm/i915/display/intel_dpt.c
>>> index 8f7b1f7534a4..ef428f3fc538 100644
>>> --- a/drivers/gpu/drm/i915/display/intel_dpt.c
>>> +++ b/drivers/gpu/drm/i915/display/intel_dpt.c
>>> @@ -221,8 +221,6 @@ intel_dpt_create(struct intel_framebuffer *fb)
>>>
>>> vm->vma_ops.bind_vma= dpt_bind_vma;
>>> vm->vma_ops.unbind_vma  = dpt_unbind_vma;
>>> -   vm->vma_ops.set_pages   = ggtt_set_pages;
>>> -   vm->vma_ops.clear_pages = clear_pages;
>>>
>>> vm->pte_encode = gen8_ggtt_pte_encode;
>>>
>>> diff --git a/drivers/gpu/drm/i915/gt/gen6_ppgtt.c 
>>> b/drivers/gpu/drm/i915/gt/gen6_ppgtt.c
>>> index 5caa1703716e..5c048b4ccd4d 100644
>>> --- a/drivers/gpu/drm/i915/gt/gen6_ppgtt.c
>>> +++ b/drivers/gpu/drm/i915/gt/gen6_ppgtt.c
>>> @@ -270,19 +270,6 @@ static void gen6_ppgtt_cleanup(struct 
>>> i915_address_space *vm)
>>> free_pd(&ppgtt->base.vm, ppgtt->base.pd);
>>>  }
>>>
>>> -static int pd_vma_set_pages(struct i915_vma *vma)
>>> -{
>>> -   vma->pages = ERR_PTR(-ENODEV);
>>> -   return 0;
>>> -}
>>> -
>>> -static void pd_vma_clear_pages(struct i915_vma *vma)
>>> -{
>>> -   GEM_BUG_ON(!vma->pages);
>>> -
>>> -   vma->pages = NULL;
>>> -}
>>> -
>>>  static void pd_vma_bind(struct i915_address_space *vm,
>>> struct i915_vm_pt_stash *stash,
>>> struct i915_vma *vma,
>>> @@ -322,8 +309,6 @@ static void pd_vma_unbind(struct i915_address_space 
>>> *vm, struct i915_vma *vma)
>>>  }
>>>
>>>  static const struct i915_vma_ops pd_vma_ops = {
>>> -   .set_pages = pd_vma_set_pages,
>>> -   .clear_pages = pd_vma_clear_pages,
>>> .bind_vma = pd_vma_bind,
>>> .unbind_vma = pd_vma_unbind,
>>>  };
>>> diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c 
>>> b/drivers/gpu/drm/i915/gt/intel_ggtt.c
>>> index f17383e76eb7..6da57199bb33 100644
>>> --- a/drivers/gpu/drm/i915/gt/intel_ggtt.c
>>> +++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c
>>> @@ -20,9 +20,6 @@
>>>  #include "intel_gtt.h"
>>>  #include "gen8_ppgtt.h"
>>>
>>> -static int
>>> -i915_get_ggtt_vma_pages(struct i915_vma *vma);
>>> -
>>>  static void i915_ggtt_color_adjust(const struct drm_mm_node *node,
>>>unsigned long color,
>>>u64 *start,
>>> @@ -875,21 +872,6 @@ static int ggtt_probe_common(struct i915_ggtt *ggtt, 
>>> u64 size)
>>> return 0;
>>>  }
>>>
>>> -int ggtt_set_pages(struct i915_vma *vma)
>>> -{
>>> -   int ret;
>>> -
>>> -   GEM_BUG_ON(vma->pages);
>>> -
>>> -   ret = i915_get_ggtt_vma_pages(vma);
>>> -   if (ret)
>>> -   return ret;
>>> -
>>> -   vma->page_sizes = vma->obj->mm.page_sizes;
>>> -
>>> -   return 0;
>>> -}
>>> -
>>>  static void gen6_gmch_remove(struct i915_address_space *vm)
>>>  {
>>> struct i915_ggtt *ggtt = i915_vm_to_ggtt(vm);
>>> @@ -950,8 +932,6 @@ static int gen8_gmch_probe(struct i915_ggtt *ggtt)
>>>
>>> ggtt->vm.vma_ops.bind_vma= ggtt_bind_vma;
>>> ggtt->vm.vma_ops.unbind_vma  = ggtt_unbind_vma;
>>> -   ggtt->vm.vma_ops.set_pages   = ggtt_set_pages;
>>> -   ggtt->vm.vma_ops.clear_pages = clear_pages;
>>>
>>> ggtt->vm.pte_encode = gen8_ggtt_pte_encode;
>>>
>>> @@ -1100,8 +1080,6 @@ static int gen6_gmch_probe(struct i915_ggtt *ggtt)
>>>
>>> ggtt->vm.vma_ops.bind_vma= ggtt_bind_vma;
>>> ggtt->vm.vma_ops.unbind_vma  = ggtt_unbind_vma;
>>> -   ggtt->vm.vma_ops.set_pages   = ggtt_set_pages;
>>> -   ggtt->vm.vma_ops.cl

[PATCH v4 1/2] i915/gvt: Introduce the mmio_info_table.c to support VFIO new mdev API

2021-11-29 Thread Zhi Wang
From: Zhi Wang 

To support the new mdev interfaces and the re-factor patches from
Christoph, which moves the GVT-g code into a dedicated module, the GVT-g
initialization path has to be separated into two phases:

a) Early initialization.

The early initialization of GVT requires to be done when loading i915.
Mostly it's because the initial clean HW state needs to be saved before
i915 touches the HW.

b) Late initalization.

This phases of initalization will setup the rest components of GVT-g,
which can be done later when the dedicated module is being loaded.

v4:

- Fix the errors of patch checking scripts.

v3:

- Fix the errors when CONFIG_DRM_I915_WERROR is turned on. (Jani)

v2:

- Implement a mmio table instead of generating it by marco in i915. (Jani)

Cc: Christoph Hellwig 
Cc: Jason Gunthorpe 
Cc: Jani Nikula 
Cc: Joonas Lahtinen 
Cc: Vivi Rodrigo 
Cc: Zhenyu Wang 
Cc: Zhi Wang 
Tested-by: Terrence Xu 
Signed-off-by: Zhi Wang 
---
 drivers/gpu/drm/i915/Makefile  |2 +-
 drivers/gpu/drm/i915/gvt/gvt.c |   38 +-
 drivers/gpu/drm/i915/gvt/gvt.h |1 +
 drivers/gpu/drm/i915/gvt/handlers.c| 1780 +++-
 drivers/gpu/drm/i915/gvt/mmio.h|5 +-
 drivers/gpu/drm/i915/gvt/mmio_info_table.c | 1461 
 drivers/gpu/drm/i915/gvt/mmio_info_table.h |   37 +
 drivers/gpu/drm/i915/gvt/reg.h |9 +-
 drivers/gpu/drm/i915/intel_gvt.c   |   42 +-
 9 files changed, 1777 insertions(+), 1598 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gvt/mmio_info_table.c
 create mode 100644 drivers/gpu/drm/i915/gvt/mmio_info_table.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index cdc244bbbfc1..55603aebe3e4 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -309,7 +309,7 @@ i915-$(CONFIG_DRM_I915_SELFTEST) += \
 i915-y += i915_vgpu.o
 
 ifeq ($(CONFIG_DRM_I915_GVT),y)
-i915-y += intel_gvt.o
+i915-y += intel_gvt.o gvt/mmio_info_table.o
 include $(src)/gvt/Makefile
 endif
 
diff --git a/drivers/gpu/drm/i915/gvt/gvt.c b/drivers/gpu/drm/i915/gvt/gvt.c
index cbac409f6c8a..c7580db355c0 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.c
+++ b/drivers/gpu/drm/i915/gvt/gvt.c
@@ -63,23 +63,6 @@ static const struct intel_gvt_ops intel_gvt_ops = {
.emulate_hotplug = intel_vgpu_emulate_hotplug,
 };
 
-static void init_device_info(struct intel_gvt *gvt)
-{
-   struct intel_gvt_device_info *info = &gvt->device_info;
-   struct pci_dev *pdev = to_pci_dev(gvt->gt->i915->drm.dev);
-
-   info->max_support_vgpus = 8;
-   info->cfg_space_size = PCI_CFG_SPACE_EXP_SIZE;
-   info->mmio_size = 2 * 1024 * 1024;
-   info->mmio_bar = 0;
-   info->gtt_start_offset = 8 * 1024 * 1024;
-   info->gtt_entry_size = 8;
-   info->gtt_entry_size_shift = 3;
-   info->gmadr_bytes_in_cmd = 8;
-   info->max_surface_size = 36 * 1024 * 1024;
-   info->msi_cap_offset = pdev->msi_cap;
-}
-
 static void intel_gvt_test_and_emulate_vblank(struct intel_gvt *gvt)
 {
struct intel_vgpu *vgpu;
@@ -169,7 +152,6 @@ void intel_gvt_clean_device(struct drm_i915_private *i915)
intel_gvt_clean_workload_scheduler(gvt);
intel_gvt_clean_gtt(gvt);
intel_gvt_free_firmware(gvt);
-   intel_gvt_clean_mmio_info(gvt);
idr_destroy(&gvt->vgpu_idr);
 
kfree(i915->gvt);
@@ -188,16 +170,12 @@ void intel_gvt_clean_device(struct drm_i915_private *i915)
  */
 int intel_gvt_init_device(struct drm_i915_private *i915)
 {
-   struct intel_gvt *gvt;
+   struct intel_gvt *gvt = i915->gvt;
struct intel_vgpu *vgpu;
int ret;
 
-   if (drm_WARN_ON(&i915->drm, i915->gvt))
-   return -EEXIST;
-
-   gvt = kzalloc(sizeof(struct intel_gvt), GFP_KERNEL);
-   if (!gvt)
-   return -ENOMEM;
+   if (drm_WARN_ON(&i915->drm, !i915->gvt))
+   return -ENODEV;
 
gvt_dbg_core("init gvt device\n");
 
@@ -205,12 +183,8 @@ int intel_gvt_init_device(struct drm_i915_private *i915)
spin_lock_init(&gvt->scheduler.mmio_context_lock);
mutex_init(&gvt->lock);
mutex_init(&gvt->sched_lock);
-   gvt->gt = &i915->gt;
-   i915->gvt = gvt;
-
-   init_device_info(gvt);
 
-   ret = intel_gvt_setup_mmio_info(gvt);
+   ret = intel_gvt_setup_mmio_handlers(gvt);
if (ret)
goto out_clean_idr;
 
@@ -218,7 +192,7 @@ int intel_gvt_init_device(struct drm_i915_private *i915)
 
ret = intel_gvt_load_firmware(gvt);
if (ret)
-   goto out_clean_mmio_info;
+   goto out_clean_idr;
 
ret = intel_gvt_init_irq(gvt);
if (ret)
@@ -277,8 +251,6 @@ int intel_gvt_init_device(struct drm_i915_private *i915)
intel_gvt_clean_gtt(gvt);
 out_free_firmware:
intel_gvt_free_firmware(gvt);
-out_clean_mmio_info:
-   intel_gvt_clean_mmio_info(gvt);
 out_clean_idr:
idr_destroy(&gv

[PATCH v4 2/2] i915/gvt: save the MMIO snapshot in the early init of GVT-g

2021-11-29 Thread Zhi Wang
From: Zhi Wang 

To support the early init of GVT-g, which will be put in i915, after the
GVT-g is moved into a dedicated module, we need to save the MMIO snapshot
in the early init of GVT-g, when the HW hasn't been touched.

v3:

- Fix errors when CONFIG_DRM_I915_WERROR is turned on. (Jani)

Cc: Christoph Hellwig 
Cc: Jason Gunthorpe 
Cc: Jani Nikula 
Cc: Joonas Lahtinen 
Cc: Vivi Rodrigo 
Cc: Zhenyu Wang 
Cc: Zhi Wang 
Tested-by: Terrence Xu 
Signed-off-by: Zhi Wang 
---
 drivers/gpu/drm/i915/gvt/firmware.c| 40 +---
 drivers/gpu/drm/i915/gvt/handlers.c| 39 
 drivers/gpu/drm/i915/gvt/mmio_info_table.c | 72 +-
 drivers/gpu/drm/i915/gvt/mmio_info_table.h |  3 +
 4 files changed, 77 insertions(+), 77 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/firmware.c 
b/drivers/gpu/drm/i915/gvt/firmware.c
index 1a8274a3f4b1..28719c2f253f 100644
--- a/drivers/gpu/drm/i915/gvt/firmware.c
+++ b/drivers/gpu/drm/i915/gvt/firmware.c
@@ -66,12 +66,6 @@ static struct bin_attribute firmware_attr = {
.mmap = NULL,
 };
 
-static int mmio_snapshot_handler(struct intel_gvt *gvt, u32 offset, void *data)
-{
-   *(u32 *)(data + offset) = intel_uncore_read_notrace(gvt->gt->uncore,
-   _MMIO(offset));
-   return 0;
-}
 
 static int expose_firmware_sysfs(struct intel_gvt *gvt)
 {
@@ -81,7 +75,7 @@ static int expose_firmware_sysfs(struct intel_gvt *gvt)
void *firmware;
void *p;
unsigned long size, crc32_start;
-   int i, ret;
+   int ret;
 
size = sizeof(*h) + info->mmio_size + info->cfg_space_size;
firmware = vzalloc(size);
@@ -99,17 +93,11 @@ static int expose_firmware_sysfs(struct intel_gvt *gvt)
 
p = firmware + h->cfg_space_offset;
 
-   for (i = 0; i < h->cfg_space_size; i += 4)
-   pci_read_config_dword(pdev, i, p + i);
-
-   memcpy(gvt->firmware.cfg_space, p, info->cfg_space_size);
+   memcpy(p, gvt->firmware.cfg_space, info->cfg_space_size);
 
p = firmware + h->mmio_offset;
 
-   /* Take a snapshot of hw mmio registers. */
-   intel_gvt_for_each_tracked_mmio(gvt, mmio_snapshot_handler, p);
-
-   memcpy(gvt->firmware.mmio, p, info->mmio_size);
+   memcpy(p, gvt->firmware.mmio, info->mmio_size);
 
crc32_start = offsetof(struct gvt_firmware_header, crc32) + 4;
h->crc32 = crc32_le(0, firmware + crc32_start, size - crc32_start);
@@ -142,9 +130,6 @@ void intel_gvt_free_firmware(struct intel_gvt *gvt)
 {
if (!gvt->firmware.firmware_loaded)
clean_firmware_sysfs(gvt);
-
-   kfree(gvt->firmware.cfg_space);
-   vfree(gvt->firmware.mmio);
 }
 
 static int verify_firmware(struct intel_gvt *gvt,
@@ -204,36 +189,17 @@ static int verify_firmware(struct intel_gvt *gvt,
  */
 int intel_gvt_load_firmware(struct intel_gvt *gvt)
 {
-   struct intel_gvt_device_info *info = &gvt->device_info;
struct pci_dev *pdev = to_pci_dev(gvt->gt->i915->drm.dev);
struct intel_gvt_firmware *firmware = &gvt->firmware;
struct gvt_firmware_header *h;
const struct firmware *fw;
char *path;
-   void *mem;
int ret;
 
path = kmalloc(PATH_MAX, GFP_KERNEL);
if (!path)
return -ENOMEM;
 
-   mem = kmalloc(info->cfg_space_size, GFP_KERNEL);
-   if (!mem) {
-   kfree(path);
-   return -ENOMEM;
-   }
-
-   firmware->cfg_space = mem;
-
-   mem = vmalloc(info->mmio_size);
-   if (!mem) {
-   kfree(path);
-   kfree(firmware->cfg_space);
-   return -ENOMEM;
-   }
-
-   firmware->mmio = mem;
-
sprintf(path, "%s/vid_0x%04x_did_0x%04x_rid_0x%02x.golden_hw_state",
 GVT_FIRMWARE_PATH, pdev->vendor, pdev->device,
 pdev->revision);
diff --git a/drivers/gpu/drm/i915/gvt/handlers.c 
b/drivers/gpu/drm/i915/gvt/handlers.c
index 2c064da3db6d..ba7b330a2c71 100644
--- a/drivers/gpu/drm/i915/gvt/handlers.c
+++ b/drivers/gpu/drm/i915/gvt/handlers.c
@@ -2406,45 +2406,6 @@ int intel_gvt_setup_mmio_handlers(struct intel_gvt *gvt)
return ret;
 }
 
-/**
- * intel_gvt_for_each_tracked_mmio - iterate each tracked mmio
- * @gvt: a GVT device
- * @handler: the handler
- * @data: private data given to handler
- *
- * Returns:
- * Zero on success, negative error code if failed.
- */
-int intel_gvt_for_each_tracked_mmio(struct intel_gvt *gvt,
-   int (*handler)(struct intel_gvt *gvt, u32 offset, void *data),
-   void *data)
-{
-   struct gvt_mmio_block *block = gvt->mmio.mmio_block;
-   struct intel_gvt_mmio_info *e;
-   int i, j, ret;
-
-   hash_for_each(gvt->mmio.mmio_info_table, i, e, node) {
-   ret = handler(gvt, e->offset, data);
-   if (ret)
-   return ret;
-   }
-
-   for (i = 0; i < gvt->mmio.num_mmio_block; i++, block++) {

Re: [PATCH] dma_fence_array: Fix PENDING_ERROR leak in dma_fence_array_signaled()

2021-11-29 Thread Christian König

Am 29.11.21 um 13:23 schrieb Thomas Hellström:

Hi, Christian,

On Mon, 2021-11-29 at 09:21 +0100, Christian König wrote:

Am 29.11.21 um 08:35 schrieb Thomas Hellström:

If a dma_fence_array is reported signaled by a call to
dma_fence_is_signaled(), it may leak the PENDING_ERROR status.

Fix this by clearing the PENDING_ERROR status if we return true in
dma_fence_array_signaled().

Fixes: 1f70b8b812f3 ("dma-fence: Propagate errors to dma-fence-
array container")
Cc: linaro-mm-...@lists.linaro.org
Cc: Christian König 
Cc: Chris Wilson 
Signed-off-by: Thomas Hellström 

Reviewed-by: Christian König 

How are the dma-buf / dma-fence patches typically merged? If i915 is
the only fence->error user, could we take this through drm-intel to
avoid a backmerge for upcoming i915 work?


Well that one here looks like a bugfix to me, so either through 
drm-misc-fixes ore some i915 -fixes branch sounds fine to me.


If you have any new development based on that a backmerge of the -fixes 
into your -next branch is unavoidable anyway.


Regards,
Christian.



/Thomas



---
   drivers/dma-buf/dma-fence-array.c | 6 +-
   1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/dma-buf/dma-fence-array.c b/drivers/dma-
buf/dma-fence-array.c
index d3fbd950be94..3e07f961e2f3 100644
--- a/drivers/dma-buf/dma-fence-array.c
+++ b/drivers/dma-buf/dma-fence-array.c
@@ -104,7 +104,11 @@ static bool dma_fence_array_signaled(struct
dma_fence *fence)
   {
 struct dma_fence_array *array = to_dma_fence_array(fence);
   
-   return atomic_read(&array->num_pending) <= 0;

+   if (atomic_read(&array->num_pending) > 0)
+   return false;
+
+   dma_fence_array_clear_pending_error(array);
+   return true;
   }
   
   static void dma_fence_array_release(struct dma_fence *fence)






Re: [PATCH] dma_fence_array: Fix PENDING_ERROR leak in dma_fence_array_signaled()

2021-11-29 Thread Thomas Hellström
Hi, Christian,

On Mon, 2021-11-29 at 09:21 +0100, Christian König wrote:
> Am 29.11.21 um 08:35 schrieb Thomas Hellström:
> > If a dma_fence_array is reported signaled by a call to
> > dma_fence_is_signaled(), it may leak the PENDING_ERROR status.
> > 
> > Fix this by clearing the PENDING_ERROR status if we return true in
> > dma_fence_array_signaled().
> > 
> > Fixes: 1f70b8b812f3 ("dma-fence: Propagate errors to dma-fence-
> > array container")
> > Cc: linaro-mm-...@lists.linaro.org
> > Cc: Christian König 
> > Cc: Chris Wilson 
> > Signed-off-by: Thomas Hellström 
> 
> Reviewed-by: Christian König 

How are the dma-buf / dma-fence patches typically merged? If i915 is
the only fence->error user, could we take this through drm-intel to
avoid a backmerge for upcoming i915 work?

/Thomas


> 
> > ---
> >   drivers/dma-buf/dma-fence-array.c | 6 +-
> >   1 file changed, 5 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/dma-buf/dma-fence-array.c b/drivers/dma-
> > buf/dma-fence-array.c
> > index d3fbd950be94..3e07f961e2f3 100644
> > --- a/drivers/dma-buf/dma-fence-array.c
> > +++ b/drivers/dma-buf/dma-fence-array.c
> > @@ -104,7 +104,11 @@ static bool dma_fence_array_signaled(struct
> > dma_fence *fence)
> >   {
> > struct dma_fence_array *array = to_dma_fence_array(fence);
> >   
> > -   return atomic_read(&array->num_pending) <= 0;
> > +   if (atomic_read(&array->num_pending) > 0)
> > +   return false;
> > +
> > +   dma_fence_array_clear_pending_error(array);
> > +   return true;
> >   }
> >   
> >   static void dma_fence_array_release(struct dma_fence *fence)
> 




Re: [PATCH 22/26] dma-buf: add enum dma_resv_usage

2021-11-29 Thread Christian König

Am 25.11.21 um 16:59 schrieb Daniel Vetter:

[SNIP]

+ *
+ * For example when asking for WRITE fences then the KERNEL fences are returned
+ * as well. Similar when asked for READ fences then both WRITE and KERNEL
+ * fences are returned as well.
+ */
+enum dma_resv_usage {
+   /**
+* @DMA_RESV_USAGE_KERNEL: For in kernel memory management only.
+*
+* This should only be used for things like copying or clearing memory
+* with a DMA hardware engine for the purpose of kernel memory
+* management.
+*
+ * Drivers *always* need to wait for those fences before accessing the
+* resource protected by the dma_resv object. The only exception for
+* that is when the resource is known to be locked down in place by
+* pinning it previously.

Should dma_buf_pin also do the wait for kernel fences? I think that would
also ba e bit clearer semantics in the dma-buf patch which does these
waits for us.

Or should dma_buf_pin be pipelined and it's up to callers to wait? For kms
that's definitely the semantics we want, but it's a bit playing with fire
situation, so maybe dma-buf should get the more idiot proof semantics?


Yeah, good question. I've already added a wait after mapping an 
attachment for static importers.


But for dynamic importers I'm not sure what we want to do. On the one 
hand waiting for moves to finish is certainly the more defensive 
approach on the other hand when you have a dynamic importer you 
absolutely need to handle those dependencies correctly anyway.


Regards,
Christian.


[PATCH 23/28] dma-buf: specify usage while adding fences to dma_resv obj v2

2021-11-29 Thread Christian König
Instead of distingting between shared and exclusive fences specify
the fence usage while adding fences.

Rework all drivers to use this interface instead and deprecate the old one.

v2: some kerneldoc comments suggested by Daniel

Signed-off-by: Christian König 
---
 drivers/dma-buf/dma-resv.c| 374 --
 drivers/dma-buf/st-dma-resv.c | 109 ++---
 .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c  |   6 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c|   6 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_object.c|   8 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c|   4 +-
 drivers/gpu/drm/amd/amdkfd/kfd_svm.c  |   2 +-
 drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c  |  12 +-
 drivers/gpu/drm/i915/gem/i915_gem_busy.c  |  13 +-
 drivers/gpu/drm/i915/gem/i915_gem_clflush.c   |   5 +-
 .../gpu/drm/i915/gem/i915_gem_execbuffer.c|   4 +-
 .../drm/i915/gem/selftests/i915_gem_migrate.c |   2 +-
 drivers/gpu/drm/i915/i915_vma.c   |  10 +-
 .../drm/i915/selftests/intel_memory_region.c  |   2 +-
 drivers/gpu/drm/lima/lima_gem.c   |   4 +-
 drivers/gpu/drm/msm/msm_gem_submit.c  |   4 +-
 drivers/gpu/drm/nouveau/nouveau_bo.c  |   9 +-
 drivers/gpu/drm/nouveau/nouveau_fence.c   |   2 +-
 drivers/gpu/drm/panfrost/panfrost_job.c   |   2 +-
 drivers/gpu/drm/qxl/qxl_release.c |   5 +-
 drivers/gpu/drm/radeon/radeon_object.c|   6 +-
 drivers/gpu/drm/radeon/radeon_vm.c|   2 +-
 drivers/gpu/drm/ttm/ttm_bo.c  |   6 +-
 drivers/gpu/drm/ttm/ttm_bo_util.c |   7 +-
 drivers/gpu/drm/ttm/ttm_execbuf_util.c|  10 +-
 drivers/gpu/drm/v3d/v3d_gem.c |   6 +-
 drivers/gpu/drm/vc4/vc4_gem.c |   4 +-
 drivers/gpu/drm/vgem/vgem_fence.c |  11 +-
 drivers/gpu/drm/virtio/virtgpu_gem.c  |   5 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_bo.c|   5 +-
 include/linux/dma-resv.h  |  88 ++---
 31 files changed, 307 insertions(+), 426 deletions(-)

diff --git a/drivers/dma-buf/dma-resv.c b/drivers/dma-buf/dma-resv.c
index 33a17db89fb4..a2a0b5b6c107 100644
--- a/drivers/dma-buf/dma-resv.c
+++ b/drivers/dma-buf/dma-resv.c
@@ -44,12 +44,12 @@
 /**
  * DOC: Reservation Object Overview
  *
- * The reservation object provides a mechanism to manage shared and
- * exclusive fences associated with a buffer.  A reservation object
- * can have attached one exclusive fence (normally associated with
- * write operations) or N shared fences (read operations).  The RCU
- * mechanism is used to protect read access to fences from locked
- * write-side updates.
+ * The reservation object provides a mechanism to manage a container of
+ * dma_fence object associated with a resource. A reservation object
+ * can have any number of fences attaches to it. Each fence carring an usage
+ * parameter determining how the operation represented by the fence is using 
the
+ * resource. The RCU mechanism is used to protect read access to fences from
+ * locked write-side updates.
  *
  * See struct dma_resv for more details.
  */
@@ -57,36 +57,80 @@
 DEFINE_WD_CLASS(reservation_ww_class);
 EXPORT_SYMBOL(reservation_ww_class);
 
+/* Mask for the lower fence pointer bits */
+#define DMA_RESV_LIST_MASK 0x3
+
 /**
- * struct dma_resv_list - a list of shared fences
+ * struct dma_resv_list - an array of fences
  * @rcu: for internal use
- * @shared_count: table of shared fences
- * @shared_max: for growing shared fence table
- * @shared: shared fence table
+ * @num_fences: table of fences
+ * @max_fences: for growing fence table
+ * @table: fence table
  */
 struct dma_resv_list {
struct rcu_head rcu;
-   u32 shared_count, shared_max;
-   struct dma_fence __rcu *shared[];
+   u32 num_fences, max_fences;
+   struct dma_fence __rcu *table[];
 };
 
+/**
+ * dma_resv_list_entry - extract fence and usage from a list entry
+ * @list: the list to extract and entry from
+ * @index: which entry we want
+ * @check: lockdep check that the access is allowed
+ * @fence: the resulting fence
+ * @usage: the resulting usage
+ *
+ * Extract the fence and usage flags from an RCU protected entry in the list.
+ */
+static void dma_resv_list_entry(struct dma_resv_list *list, unsigned int index,
+   bool check, struct dma_fence **fence,
+   enum dma_resv_usage *usage)
+{
+   long tmp;
+
+   tmp = (long)rcu_dereference_check(list->table[index], check);
+   *fence = (struct dma_fence *)(tmp & ~DMA_RESV_LIST_MASK);
+   if (usage)
+   *usage = tmp & DMA_RESV_LIST_MASK;
+}
+
+/**
+ * dma_resv_list_set - set fence and usage at a specific index
+ * @list: the list to modify
+ * @index: where to make the change
+ * @fence: the fence to set
+ * @usage: the usage to set
+ *
+ * Set the fence and usage flags at the specific index in the list.
+ */
+static void dma_resv

[PATCH 22/28] dma-buf: add enum dma_resv_usage v3

2021-11-29 Thread Christian König
This change adds the dma_resv_usage enum and allows us to specify why a
dma_resv object is queried for its containing fences.

Additional to that a dma_resv_usage_rw() helper function is added to aid
retrieving the fences for a read or write userspace submission.

This is then deployed to the different query functions of the dma_resv
object and all of their users. When the write paratermer was previously
true we now use DMA_RESV_USAGE_WRITE and DMA_RESV_USAGE_READ otherwise.

v2: add KERNEL/OTHER in separate patch
v3: some kerneldoc suggestions by Daniel

Signed-off-by: Christian König 
---
 drivers/dma-buf/dma-buf.c |  3 +-
 drivers/dma-buf/dma-resv.c| 33 +
 drivers/dma-buf/st-dma-resv.c | 48 ++---
 drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c|  4 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   |  3 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c   |  3 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c   |  5 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c|  4 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_object.c|  4 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c  |  3 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c   |  3 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c   |  3 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c|  7 +-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  3 +-
 drivers/gpu/drm/drm_gem.c |  6 +-
 drivers/gpu/drm/drm_gem_atomic_helper.c   |  2 +-
 drivers/gpu/drm/etnaviv/etnaviv_gem.c |  6 +-
 drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c  |  7 +-
 .../gpu/drm/i915/display/intel_atomic_plane.c |  3 +-
 drivers/gpu/drm/i915/gem/i915_gem_busy.c  |  4 +-
 drivers/gpu/drm/i915/gem/i915_gem_lmem.c  |  2 +-
 drivers/gpu/drm/i915/gem/i915_gem_userptr.c   |  2 +-
 drivers/gpu/drm/i915/gem/i915_gem_wait.c  |  6 +-
 .../drm/i915/gem/selftests/i915_gem_dmabuf.c  |  3 +-
 drivers/gpu/drm/i915/i915_request.c   |  3 +-
 drivers/gpu/drm/i915/i915_sw_fence.c  |  2 +-
 drivers/gpu/drm/msm/msm_gem.c |  3 +-
 drivers/gpu/drm/nouveau/dispnv50/wndw.c   |  3 +-
 drivers/gpu/drm/nouveau/nouveau_bo.c  |  8 +--
 drivers/gpu/drm/nouveau/nouveau_fence.c   |  3 +-
 drivers/gpu/drm/nouveau/nouveau_gem.c |  3 +-
 drivers/gpu/drm/panfrost/panfrost_drv.c   |  3 +-
 drivers/gpu/drm/qxl/qxl_debugfs.c |  3 +-
 drivers/gpu/drm/radeon/radeon_display.c   |  3 +-
 drivers/gpu/drm/radeon/radeon_gem.c   |  9 ++-
 drivers/gpu/drm/radeon/radeon_mn.c|  4 +-
 drivers/gpu/drm/radeon/radeon_sync.c  |  2 +-
 drivers/gpu/drm/radeon/radeon_uvd.c   |  4 +-
 drivers/gpu/drm/scheduler/sched_main.c|  3 +-
 drivers/gpu/drm/ttm/ttm_bo.c  | 18 ++---
 drivers/gpu/drm/vgem/vgem_fence.c |  4 +-
 drivers/gpu/drm/virtio/virtgpu_ioctl.c|  5 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_bo.c|  4 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_resource.c  |  4 +-
 drivers/infiniband/core/umem_dmabuf.c |  3 +-
 include/linux/dma-resv.h  | 69 +++
 46 files changed, 205 insertions(+), 125 deletions(-)

diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
index 602b12d7470d..528983d3ba64 100644
--- a/drivers/dma-buf/dma-buf.c
+++ b/drivers/dma-buf/dma-buf.c
@@ -1124,7 +1124,8 @@ static int __dma_buf_begin_cpu_access(struct dma_buf 
*dmabuf,
long ret;
 
/* Wait on any implicit rendering fences */
-   ret = dma_resv_wait_timeout(resv, write, true, MAX_SCHEDULE_TIMEOUT);
+   ret = dma_resv_wait_timeout(resv, dma_resv_usage_rw(write),
+   true, MAX_SCHEDULE_TIMEOUT);
if (ret < 0)
return ret;
 
diff --git a/drivers/dma-buf/dma-resv.c b/drivers/dma-buf/dma-resv.c
index ecb2ff606bac..33a17db89fb4 100644
--- a/drivers/dma-buf/dma-resv.c
+++ b/drivers/dma-buf/dma-resv.c
@@ -408,7 +408,7 @@ static void dma_resv_iter_restart_unlocked(struct 
dma_resv_iter *cursor)
cursor->seq = read_seqcount_begin(&cursor->obj->seq);
cursor->index = -1;
cursor->shared_count = 0;
-   if (cursor->all_fences) {
+   if (cursor->usage >= DMA_RESV_USAGE_READ) {
cursor->fences = dma_resv_shared_list(cursor->obj);
if (cursor->fences)
cursor->shared_count = cursor->fences->shared_count;
@@ -515,7 +515,7 @@ struct dma_fence *dma_resv_iter_first(struct dma_resv_iter 
*cursor)
dma_resv_assert_held(cursor->obj);
 
cursor->index = 0;
-   if (cursor->all_fences)
+   if (cursor->usage >= DMA_RESV_USAGE_READ)
cursor->fences = dma_resv_shared_list(cursor->obj);
else
cursor->fences = NULL;
@@ -570,7 +570,7 @@ int dma_resv_copy_fences(struct dma_resv *dst, struct 
dma_resv *src)
list = NULL;
excl = NULL;
 
-   dma_resv_iter_begin(

[PATCH 27/28] amdgpu: remove DMA-buf fence workaround

2021-11-29 Thread Christian König
Not needed any more now we have that inside the framework.

Signed-off-by: Christian König 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h |  1 -
 drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c  | 52 +++--
 2 files changed, 6 insertions(+), 47 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h
index 044b41f0bfd9..529d52a204cf 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h
@@ -34,7 +34,6 @@ struct amdgpu_fpriv;
 struct amdgpu_bo_list_entry {
struct ttm_validate_buffer  tv;
struct amdgpu_bo_va *bo_va;
-   struct dma_fence_chain  *chain;
uint32_tpriority;
struct page **user_pages;
booluser_invalidated;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index 92091e800022..413606d10080 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -576,14 +576,6 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
struct amdgpu_bo *bo = ttm_to_amdgpu_bo(e->tv.bo);
 
e->bo_va = amdgpu_vm_bo_find(vm, bo);
-
-   if (bo->tbo.base.dma_buf && !amdgpu_bo_explicit_sync(bo)) {
-   e->chain = dma_fence_chain_alloc();
-   if (!e->chain) {
-   r = -ENOMEM;
-   goto error_validate;
-   }
-   }
}
 
amdgpu_cs_get_threshold_for_moves(p->adev, &p->bytes_moved_threshold,
@@ -634,13 +626,8 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
}
 
 error_validate:
-   if (r) {
-   amdgpu_bo_list_for_each_entry(e, p->bo_list) {
-   dma_fence_chain_free(e->chain);
-   e->chain = NULL;
-   }
+   if (r)
ttm_eu_backoff_reservation(&p->ticket, &p->validated);
-   }
 out:
return r;
 }
@@ -680,17 +667,9 @@ static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser 
*parser, int error,
 {
unsigned i;
 
-   if (error && backoff) {
-   struct amdgpu_bo_list_entry *e;
-
-   amdgpu_bo_list_for_each_entry(e, parser->bo_list) {
-   dma_fence_chain_free(e->chain);
-   e->chain = NULL;
-   }
-
+   if (error && backoff)
ttm_eu_backoff_reservation(&parser->ticket,
   &parser->validated);
-   }
 
for (i = 0; i < parser->num_post_deps; i++) {
drm_syncobj_put(parser->post_deps[i].syncobj);
@@ -1265,29 +1244,10 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
 
amdgpu_vm_move_to_lru_tail(p->adev, &fpriv->vm);
 
-   amdgpu_bo_list_for_each_entry(e, p->bo_list) {
-   struct dma_resv *resv = e->tv.bo->base.resv;
-   struct dma_fence_chain *chain = e->chain;
-   struct dma_resv_iter cursor;
-   struct dma_fence *fence;
-
-   if (!chain)
-   continue;
-
-   /*
-* Work around dma_resv shortcommings by wrapping up the
-* submission in a dma_fence_chain and add it as exclusive
-* fence.
-*/
-   dma_resv_for_each_fence(&cursor, resv,
-   DMA_RESV_USAGE_WRITE,
-   fence) {
-   break;
-   }
-   dma_fence_chain_init(chain, fence, dma_fence_get(p->fence), 1);
-   dma_resv_add_fence(resv, &chain->base, DMA_RESV_USAGE_WRITE);
-   e->chain = NULL;
-   }
+   /* For now manually add the resulting fence as writer as well */
+   amdgpu_bo_list_for_each_entry(e, p->bo_list)
+   dma_resv_add_fence(e->tv.bo->base.resv, p->fence,
+  DMA_RESV_USAGE_WRITE);
 
ttm_eu_fence_buffer_objects(&p->ticket, &p->validated, p->fence);
mutex_unlock(&p->adev->notifier_lock);
-- 
2.25.1



  1   2   >