Re: [PATCH v6 4/5] drm/bridge: anx7625: add HDCP support

2021-03-29 Thread Sean Paul
On Mon, Mar 29, 2021 at 6:27 AM Xin Ji  wrote:
>
> On Thu, Mar 25, 2021 at 02:19:23PM -0400, Sean Paul wrote:
> > On Fri, Mar 19, 2021 at 2:35 AM Xin Ji  wrote:
> > >
> > > Add HDCP feature, enable HDCP function through chip internal key
> > > and downstream's capability.
> > >
> > > Signed-off-by: Xin Ji 
> > > ---

/snip

> > >  static void anx7625_dp_start(struct anx7625_data *ctx)
> > >  {
> > > int ret;
> > > @@ -643,6 +787,9 @@ static void anx7625_dp_start(struct anx7625_data *ctx)
> > > return;
> > > }
> > >
> > > +   /* HDCP config */
> > > +   anx7625_hdcp_setting(ctx);
> >
> > You should really use the "Content Protection" property to
> > enable/disable HDCP instead of force-enabling it at all times.
> >
> > Sean
> Hi Sean, it's hard to implement "Content Protection" property, we have
> implemented HDCP in firmware, it is not compatible with it. We don't
> have interface to get Downstream Cert.
> Thanks,
> Xin

Hi Xin,
I'm sorry, I don't understand what you mean when you say you don't
have an interface to get Downstream Cert.

The Content Protection property is just a means through which
userspace can turn on and turn off HDCP when it needs. As far as I can
tell, your patch turns on HDCP when the display is enabled and leaves
it on until it is disabled. This is undesirable since it forces HDCP
on the user.

Is it impossible to enable/disable HDCP outside of display
enable/disable on your hardware?

Thanks,

Sean

> >
> > > +
> > > if (ctx->pdata.is_dpi)
> > > ret = anx7625_dpi_config(ctx);
> > > else

/snip


Re: [PATCH v6 4/5] drm/bridge: anx7625: add HDCP support

2021-03-25 Thread Sean Paul
On Fri, Mar 19, 2021 at 2:35 AM Xin Ji  wrote:
>
> Add HDCP feature, enable HDCP function through chip internal key
> and downstream's capability.
>
> Signed-off-by: Xin Ji 
> ---
>  drivers/gpu/drm/bridge/analogix/anx7625.c | 147 ++
>  drivers/gpu/drm/bridge/analogix/anx7625.h |  36 ++
>  2 files changed, 183 insertions(+)
>
> diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c 
> b/drivers/gpu/drm/bridge/analogix/anx7625.c
> index 8c514b46d361..b424a570effa 100644
> --- a/drivers/gpu/drm/bridge/analogix/anx7625.c
> +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c
> @@ -633,6 +633,150 @@ static int anx7625_dpi_config(struct anx7625_data *ctx)
> return ret;
>  }
>
> +static int anx7625_aux_dpcd_read(struct anx7625_data *ctx,
> +u8 addrh, u8 addrm, u8 addrl,
> +u8 len, u8 *buf)
> +{
> +   struct device *dev = >client->dev;
> +   int ret;
> +   u8 cmd;
> +
> +   if (len > MAX_DPCD_BUFFER_SIZE) {
> +   DRM_DEV_ERROR(dev, "exceed aux buffer len.\n");
> +   return -E2BIG;
> +   }
> +
> +   cmd = ((len - 1) << 4) | 0x09;
> +
> +   /* Set command and length */
> +   ret = anx7625_reg_write(ctx, ctx->i2c.rx_p0_client,
> +   AP_AUX_COMMAND, cmd);
> +
> +   /* Set aux access address */
> +   ret |= anx7625_reg_write(ctx, ctx->i2c.rx_p0_client,
> +AP_AUX_ADDR_7_0, addrl);
> +   ret |= anx7625_reg_write(ctx, ctx->i2c.rx_p0_client,
> +AP_AUX_ADDR_15_8, addrm);
> +   ret |= anx7625_reg_write(ctx, ctx->i2c.rx_p0_client,
> +AP_AUX_ADDR_19_16, addrh);
> +
> +   /* Enable aux access */
> +   ret |= anx7625_write_or(ctx, ctx->i2c.rx_p0_client,
> +   AP_AUX_CTRL_STATUS, AP_AUX_CTRL_OP_EN);
> +
> +   if (ret < 0) {
> +   DRM_DEV_ERROR(dev, "cannot access aux related register.\n");
> +   return -EIO;
> +   }
> +
> +   usleep_range(2000, 2100);
> +
> +   ret = wait_aux_op_finish(ctx);
> +   if (ret) {
> +   DRM_DEV_ERROR(dev, "aux IO error: wait aux op finish.\n");
> +   return ret;
> +   }
> +
> +   ret = anx7625_reg_block_read(ctx, ctx->i2c.rx_p0_client,
> +AP_AUX_BUFF_START, len, buf);
> +   if (ret < 0) {
> +   DRM_DEV_ERROR(dev, "read dpcd register failed\n");
> +   return -EIO;
> +   }
> +
> +   return 0;
> +}
> +
> +static int anx7625_read_flash_status(struct anx7625_data *ctx)
> +{
> +   return anx7625_reg_read(ctx, ctx->i2c.rx_p0_client, R_RAM_CTRL);
> +}
> +
> +static int anx7625_hdcp_key_probe(struct anx7625_data *ctx)
> +{
> +   int ret, val;
> +   struct device *dev = >client->dev;
> +   u8 ident[32];
> +
> +   ret = anx7625_reg_write(ctx, ctx->i2c.rx_p0_client,
> +   FLASH_ADDR_HIGH, 0x91);
> +   ret |= anx7625_reg_write(ctx, ctx->i2c.rx_p0_client,
> +FLASH_ADDR_LOW, 0xA0);
> +   if (ret < 0) {
> +   DRM_DEV_ERROR(dev, "IO error : set key flash address.\n");
> +   return ret;
> +   }
> +
> +   ret = anx7625_reg_write(ctx, ctx->i2c.rx_p0_client,
> +   FLASH_LEN_HIGH, (FLASH_BUF_LEN - 1) >> 8);
> +   ret |= anx7625_reg_write(ctx, ctx->i2c.rx_p0_client,
> +FLASH_LEN_LOW, (FLASH_BUF_LEN - 1) & 0xFF);
> +   if (ret < 0) {
> +   DRM_DEV_ERROR(dev, "IO error : set key flash len.\n");
> +   return ret;
> +   }
> +
> +   ret = anx7625_reg_write(ctx, ctx->i2c.rx_p0_client,
> +   R_FLASH_RW_CTRL, FLASH_READ);
> +   ret |= readx_poll_timeout(anx7625_read_flash_status,
> + ctx, val,
> + ((val & FLASH_DONE) || (val < 0)),
> + 2000,
> + 2000 * 150);
> +   if (ret) {
> +   DRM_DEV_ERROR(dev, "flash read access fail!\n");
> +   return -EIO;
> +   }
> +
> +   ret = anx7625_reg_block_read(ctx, ctx->i2c.rx_p0_client,
> +FLASH_BUF_BASE_ADDR,
> +FLASH_BUF_LEN, ident);
> +   if (ret < 0) {
> +   DRM_DEV_ERROR(dev, "read flash data fail!\n");
> +   return -EIO;
> +   }
> +
> +   if (ident[29] == 0xFF && ident[30] == 0xFF && ident[31] == 0xFF)
> +   return -EINVAL;
> +
> +   return 0;
> +}
> +
> +static int anx7625_hdcp_setting(struct anx7625_data *ctx)
> +{
> +   u8 bcap;
> +   int ret;
> +   struct device *dev = >client->dev;
> +
> +   ret = anx7625_hdcp_key_probe(ctx);
> +   if (ret) {
> +   

Re: [Freedreno] [PATCH v2 2/2] drm/msm/dp: add supported max link rate specified from dtsi

2021-02-22 Thread Sean Paul
On Mon, Feb 22, 2021 at 11:31 AM  wrote:
>
> On 2021-02-19 14:46, Stephen Boyd wrote:
> > Quoting khs...@codeaurora.org (2021-02-19 08:39:38)
> >> On 2021-02-18 15:02, Stephen Boyd wrote:
> >> > Quoting Kuogee Hsieh (2021-02-18 12:55:04)
> >> >> Allow supported link rate to be limited to the value specified at
> >> >> dtsi. If it is not specified, then link rate is derived from dpcd
> >> >> directly. Below are examples,
> >> >> link-rate = <162000> for max link rate limited at 1.62G
> >> >> link-rate = <27> for max link rate limited at 2.7G
> >> >> link-rate = <54> for max link rate limited at 5.4G
> >> >> link-rate = <81> for max link rate limited at 8.1G
> >> >>
> >> >> Changes in V2:
> >> >> -- allow supported max link rate specified from dtsi
> >> >
> >> > Please don't roll this into the patch that removes the limit. The
> >> > previous version of this patch was fine. The part that lowers the limit
> >> > back down should be another patch.
> >> >
> >> > We rejected link-rate in DT before and we should reject it upstream
> >> > again. As far as I can tell, the maximum link rate should be determined
> >> > based on the panel or the type-c port on the board. The dp controller
> >> > can always achieve HBR3, so limiting it at the dp controller is
> >> > incorrect. The driver should query the endpoints to figure out if they
> >> > want to limit the link rate. Is that done automatically sometimes by
> >> > intercepting the DPCD?
> >>
> >> ok, i will roll back to original patch and add the second patch for
> >> max
> >> link rate limited purpose.
> >> panel dpcd specified max link rate it supported.
> >> At driver, link rate is derived from dpcd directly since driver will
> >> try
> >> to use the maximum supported link rate and less lane to save power.
> >> Therefore it is not possible that limit link rate base on dpcd.
> >> AS i understand we are going to do max link rate limitation is due to
> >> old redriver chip can not support HBR3.
> >> How can I acquire which type-c port on the board so that I can trigger
> >> max link rate limitation?
> >>
> >>
> >
> > The driver already seems to support lowering the link rate during link
> > training. Can't we try to train at the highest rate and then downgrade
> > the link speed until it trains properly? I sort of fail to see why we
> > need to introduce a bunch of complexity around limiting the link rate
> > on
> > certain boards if the driver can figure out that link training doesn't
> > work at HBR3 so it should try to train at HBR2 instead.
>
> yes, dp driver did support down grade link rate during link training
> procedure.
> But link training is kind of setting up agreement between host and panel
> with assumption that there are no other limitations in between.
> The problem we are discussing here is the limitation of usb re driver
> link rate support.
> Since we do not know how usb re driver behavior, I am not sure link
> training will work appropriately for this case.
> It may end up link status keep toggling up and down.
>

IMO we should just fail link training if the redriver doesn't support
a link count/rate and fallback to the next count/rate. This should be
handled the same as if there were a cable incapable of achieving a
link rate. Adding the link rate to the device tree (at least on the dp
block) seems suspicious.

If you really wanted to model the redriver's limitations in software,
you'd probably want to introduce a bridge driver/connector which
rejects modes that cannot be achieved by the redriver. This should
prevent the dp driver from trying to train at the unsupported rates.

Sean


> Both link-lane and link-rate specified at dtsi are for the limitation of
> Trogdor hardware platform.
> Both link-lane and link-rate specified at dtsi are NOT for panel since
> panel have specified its capability at its DPCD.
>
>
>
>
>
>
>
>
> ___
> Freedreno mailing list
> freedr...@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Intel-gfx] [RFC v2 13/20] drm/i915/dp: Extract drm_dp_downstream_read_info()

2020-08-21 Thread Sean Paul
On Thu, Aug 20, 2020 at 2:31 PM Lyude Paul  wrote:
>
> We're going to be doing the same probing process in nouveau for
> determining downstream DP port capabilities, so let's deduplicate the
> work by moving i915's code for handling this into a shared helper:
> drm_dp_downstream_read_info().
>
> Note that when we do this, we also do make some functional changes while
> we're at it:
> * We always clear the downstream port info before trying to read it,
>   just to make things easier for the caller
> * We skip reading downstream port info if the DPCD indicates that we
>   don't support downstream port info
> * We only read as many bytes as needed for the reported number of
>   downstream ports, no sense in reading the whole thing every time
>
> v2:
> * Fixup logic for calculating the downstream port length to account for
>   the fact that downstream port caps can be either 1 byte or 4 bytes
>   long. We can actually skip fixing the max_clock/max_bpc helpers here
>   since they all check for DP_DETAILED_CAP_INFO_AVAILABLE anyway.
> * Fix ret code check for drm_dp_dpcd_read
>

Thanks for sorting this out!

Reviewed-by: Sean Paul 

> Signed-off-by: Lyude Paul 
> ---
>  drivers/gpu/drm/drm_dp_helper.c | 46 +
>  drivers/gpu/drm/i915/display/intel_dp.c | 14 ++--
>  include/drm/drm_dp_helper.h |  3 ++
>  3 files changed, 51 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
> index 4c21cf69dad5a..4f845995f1f66 100644
> --- a/drivers/gpu/drm/drm_dp_helper.c
> +++ b/drivers/gpu/drm/drm_dp_helper.c
> @@ -423,6 +423,52 @@ bool drm_dp_send_real_edid_checksum(struct drm_dp_aux 
> *aux,
>  }
>  EXPORT_SYMBOL(drm_dp_send_real_edid_checksum);
>
> +static u8 drm_dp_downstream_port_count(const u8 dpcd[DP_RECEIVER_CAP_SIZE])
> +{
> +   u8 port_count = dpcd[DP_DOWN_STREAM_PORT_COUNT] & DP_PORT_COUNT_MASK;
> +
> +   if (dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DETAILED_CAP_INFO_AVAILABLE 
> && port_count > 4)
> +   port_count = 4;
> +
> +   return port_count;
> +}
> +
> +/**
> + * drm_dp_downstream_read_info() - read DPCD downstream port info if 
> available
> + * @aux: DisplayPort AUX channel
> + * @dpcd: A cached copy of the port's DPCD
> + * @downstream_ports: buffer to store the downstream port info in
> + *
> + * Returns: 0 if either the downstream port info was read successfully or
> + * there was no downstream info to read, or a negative error code otherwise.
> + */
> +int drm_dp_downstream_read_info(struct drm_dp_aux *aux,
> +   const u8 dpcd[DP_RECEIVER_CAP_SIZE],
> +   u8 downstream_ports[DP_MAX_DOWNSTREAM_PORTS])
> +{
> +   int ret;
> +   u8 len;
> +
> +   memset(downstream_ports, 0, DP_MAX_DOWNSTREAM_PORTS);
> +
> +   /* No downstream info to read */
> +   if (!drm_dp_is_branch(dpcd) ||
> +   dpcd[DP_DPCD_REV] < DP_DPCD_REV_10 ||
> +   !(dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_PRESENT))
> +   return 0;
> +
> +   len = drm_dp_downstream_port_count(dpcd);
> +   if (dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DETAILED_CAP_INFO_AVAILABLE)
> +   len *= 4;
> +
> +   ret = drm_dp_dpcd_read(aux, DP_DOWNSTREAM_PORT_0, downstream_ports, 
> len);
> +   if (ret < 0)
> +   return ret;
> +
> +   return ret == len ? 0 : -EIO;
> +}
> +EXPORT_SYMBOL(drm_dp_downstream_read_info);
> +
>  /**
>   * drm_dp_downstream_max_clock() - extract branch device max
>   * pixel rate for legacy VGA
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
> b/drivers/gpu/drm/i915/display/intel_dp.c
> index 1e29d3a012856..984e49194ca31 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -4685,18 +4685,8 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp)
> return false;
> }
>
> -   if (!drm_dp_is_branch(intel_dp->dpcd))
> -   return true; /* native DP sink */
> -
> -   if (intel_dp->dpcd[DP_DPCD_REV] == 0x10)
> -   return true; /* no per-port downstream info */
> -
> -   if (drm_dp_dpcd_read(_dp->aux, DP_DOWNSTREAM_PORT_0,
> -intel_dp->downstream_ports,
> -DP_MAX_DOWNSTREAM_PORTS) < 0)
> -   return false; /* downstream port status fetch failed */
> -
> -   return true;
> +   return drm_dp_downstream_read_info(_dp->aux, intel_dp->dpcd,
> +

Re: [RFC 19/20] drm/i915/dp: Extract drm_dp_read_dpcd_caps()

2020-08-19 Thread Sean Paul
On Tue, Aug 11, 2020 at 04:04:56PM -0400, Lyude Paul wrote:
> Since DP 1.3, it's been possible for DP receivers to specify an
> additional set of DPCD capabilities, which can take precedence over the
> capabilities reported at DP_DPCD_REV.
> 
> Basically any device supporting DP is going to need to read these in an
> identical manner, in particular nouveau, so let's go ahead and just move
> this code out of i915 into a shared DRM DP helper that we can use in
> other drivers.
> 
> Signed-off-by: Lyude Paul 
> ---
>  drivers/gpu/drm/drm_dp_helper.c | 76 +
>  drivers/gpu/drm/i915/display/intel_dp.c | 60 +---
>  drivers/gpu/drm/i915/display/intel_dp.h |  1 -
>  drivers/gpu/drm/i915/display/intel_lspcon.c |  2 +-
>  include/drm/drm_dp_helper.h |  3 +
>  5 files changed, 82 insertions(+), 60 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
> index 0ff2959c8f8e8..f9445915c6c26 100644
> --- a/drivers/gpu/drm/drm_dp_helper.c
> +++ b/drivers/gpu/drm/drm_dp_helper.c
> @@ -423,6 +423,82 @@ bool drm_dp_send_real_edid_checksum(struct drm_dp_aux 
> *aux,
>  }
>  EXPORT_SYMBOL(drm_dp_send_real_edid_checksum);
>  
> +static int drm_dp_read_extended_dpcd_caps(struct drm_dp_aux *aux,
> +   u8 dpcd[DP_RECEIVER_CAP_SIZE])
> +{
> + u8 dpcd_ext[6];
> + int ret;
> +
> + /*
> +  * Prior to DP1.3 the bit represented by
> +  * DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT was reserved.
> +  * If it is set DP_DPCD_REV at h could be at a value less than
> +  * the true capability of the panel. The only way to check is to
> +  * then compare h and 2200h.
> +  */
> + if (!(dpcd[DP_TRAINING_AUX_RD_INTERVAL] &
> +   DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT))
> + return 0;
> +
> + ret = drm_dp_dpcd_read(aux, DP_DP13_DPCD_REV, _ext,
> +sizeof(dpcd_ext));
> + if (ret != sizeof(dpcd_ext))
> + return -EIO;
> +
> + if (dpcd[DP_DPCD_REV] > dpcd_ext[DP_DPCD_REV]) {
> + DRM_DEBUG_KMS("%s: Extended DPCD rev less than base DPCD rev 
> (%d > %d)\n",
> +   aux->name, dpcd[DP_DPCD_REV],
> +   dpcd_ext[DP_DPCD_REV]);

Might be a good opportunity to convert all of these to drm_dbg_dp()?

> + return 0;
> + }
> +
> + if (!memcmp(dpcd, dpcd_ext, sizeof(dpcd_ext)))
> + return 0;
> +
> + DRM_DEBUG_KMS("%s: Base DPCD: %*ph\n",
> +   aux->name, DP_RECEIVER_CAP_SIZE, dpcd);
> +
> + memcpy(dpcd, dpcd_ext, sizeof(dpcd_ext));
> +
> + return 0;
> +}
> +
> +/**
> + * drm_dp_read_dpcd_caps() - read DPCD caps and extended DPCD caps if
> + * available
> + * @aux: DisplayPort AUX channel
> + * @dpcd: Buffer to store the resulting DPCD in
> + *
> + * Attempts to read the base DPCD caps for @aux. Additionally, this function
> + * checks for and reads the extended DPRX caps (%DP_DP13_DPCD_REV) if
> + * present.
> + *
> + * Returns: %0 if the DPCD was read successfully, negative error code
> + * otherwise.
> + */
> +int drm_dp_read_dpcd_caps(struct drm_dp_aux *aux,
> +   u8 dpcd[DP_RECEIVER_CAP_SIZE])
> +{
> + int ret;
> +
> + ret = drm_dp_dpcd_read(aux, DP_DPCD_REV, dpcd, DP_RECEIVER_CAP_SIZE);
> + if (ret != DP_RECEIVER_CAP_SIZE || dpcd[DP_DPCD_REV] == 0)
> + return -EIO;
> +
> + ret = drm_dp_read_extended_dpcd_caps(aux, dpcd);
> + if (ret < 0)
> + return ret;

I wonder if we should just go with the "regular" dpcd caps we just read in this
case?

Regardless of my nits,

Reviewed-by: Sean Paul 

> +
> + DRM_DEBUG_KMS("%s: DPCD: %*ph\n",
> +   aux->name, DP_RECEIVER_CAP_SIZE, dpcd);
> +
> + if (dpcd[DP_DPCD_REV] == 0)
> + ret = -EIO;
> +
> + return ret;
> +}
> +EXPORT_SYMBOL(drm_dp_read_dpcd_caps);
> +
>  /**
>   * drm_dp_downstream_read_info() - read DPCD downstream port info if 
> available
>   * @aux: DisplayPort AUX channel
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
> b/drivers/gpu/drm/i915/display/intel_dp.c
> index e343965a483df..230aa0360dc61 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -4449,62 +4449,6 @@ intel_dp_link_down(struct intel_encoder *encoder,
>   }
>  }
>  
> -static void
> -intel_dp_extended_receiver_capabilities(struct intel_dp *intel_dp)
> -{
> - struct drm

Re: [RFC 16/20] drm/i915/dp: Extract drm_dp_get_sink_count()

2020-08-19 Thread Sean Paul
On Tue, Aug 11, 2020 at 04:04:53PM -0400, Lyude Paul wrote:
> And of course, we'll also need to read the sink count from other drivers
> as well if we're checking whether or not it's supported. So, let's
> extract the code for this into another helper.
> 
> Signed-off-by: Lyude Paul 
> ---
>  drivers/gpu/drm/drm_dp_helper.c | 20 
>  drivers/gpu/drm/i915/display/intel_dp.c | 17 +
>  include/drm/drm_dp_helper.h |  1 +
>  3 files changed, 26 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
> index 05bb47e589731..0ff2959c8f8e8 100644
> --- a/drivers/gpu/drm/drm_dp_helper.c
> +++ b/drivers/gpu/drm/drm_dp_helper.c
> @@ -722,6 +722,26 @@ bool drm_dp_has_sink_count(struct drm_connector 
> *connector,
>  }
>  EXPORT_SYMBOL(drm_dp_has_sink_count);
>  
> +/**
> + * drm_dp_get_sink_count() - Retrieve the sink count for a given sink
> + * @aux: The DP AUX channel to use
> + *
> + * Returns: The current sink count reported by @aux, or a negative error code
> + * otherwise.
> + */
> +int drm_dp_get_sink_count(struct drm_dp_aux *aux)
> +{
> + u8 count;
> + int ret;
> +
> + ret = drm_dp_dpcd_readb(aux, DP_SINK_COUNT, );
> + if (ret < 1)
> + return -EIO;

This should probably be:
if (ret < 0)
return ret;
else if (ret != 1)
return -EIO;


> +
> + return DP_GET_SINK_COUNT(count);
> +}
> +EXPORT_SYMBOL(drm_dp_get_sink_count);
> +
>  /*
>   * I2C-over-AUX implementation
>   */
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
> b/drivers/gpu/drm/i915/display/intel_dp.c
> index 35a4779a442e2..e343965a483df 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -4648,6 +4648,8 @@ intel_dp_has_sink_count(struct intel_dp *intel_dp)
>  static bool
>  intel_dp_get_dpcd(struct intel_dp *intel_dp)
>  {
> + int ret;
> +
>   if (!intel_dp_read_dpcd(intel_dp))
>   return false;
>  
> @@ -4664,20 +4666,10 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp)
>   }
>  
>   if (intel_dp_has_sink_count(intel_dp)) {
> - u8 count;
> - ssize_t r;
> -
> - r = drm_dp_dpcd_readb(_dp->aux, DP_SINK_COUNT, );
> - if (r < 1)
> + ret = drm_dp_get_sink_count(_dp->aux);
> + if (ret < 0)
>   return false;
>  
> - /*
> -  * Sink count can change between short pulse hpd hence
> -  * a member variable in intel_dp will track any changes
> -  * between short pulse interrupts.
> -  */

I think you could probably keep this comment and relocate the 
intel_dp->sink_count
assignment back.

With these nits (or something like them),

Reviewed-by: Sean Paul 

> - intel_dp->sink_count = DP_GET_SINK_COUNT(count);
> -
>   /*
>* SINK_COUNT == 0 and DOWNSTREAM_PORT_PRESENT == 1 implies that
>* a dongle is present but no display. Unless we require to know
> @@ -4685,6 +4677,7 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp)
>* downstream port information. So, an early return here saves
>* time from performing other operations which are not required.
>*/
> + intel_dp->sink_count = ret;
>   if (!intel_dp->sink_count)
>   return false;
>   }
> diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
> index a1413a531eaf4..0c141fc81aaa8 100644
> --- a/include/drm/drm_dp_helper.h
> +++ b/include/drm/drm_dp_helper.h
> @@ -1635,6 +1635,7 @@ struct drm_dp_desc;
>  bool drm_dp_has_sink_count(struct drm_connector *connector,
>  const u8 dpcd[DP_RECEIVER_CAP_SIZE],
>  const struct drm_dp_desc *desc);
> +int drm_dp_get_sink_count(struct drm_dp_aux *aux);
>  
>  void drm_dp_remote_aux_init(struct drm_dp_aux *aux);
>  void drm_dp_aux_init(struct drm_dp_aux *aux);
> -- 
> 2.26.2
> 
> ___
> dri-devel mailing list
> dri-de...@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [RFC 15/20] drm/i915/dp: Extract drm_dp_has_sink_count()

2020-08-19 Thread Sean Paul
On Tue, Aug 11, 2020 at 04:04:52PM -0400, Lyude Paul wrote:
> Since other drivers are also going to need to be aware of the sink count
> in order to do proper dongle detection, we might as well steal i915's
> DP_SINK_COUNT helpers and move them into DRM helpers so that other
> dirvers can use them as well.
> 
> Note that this also starts using intel_dp_has_sink_count() in
> intel_dp_detect_dpcd(), which is a functional change.
> 

Reviewed-by: Sean Paul 

> Signed-off-by: Lyude Paul 
> ---
>  drivers/gpu/drm/drm_dp_helper.c | 22 ++
>  drivers/gpu/drm/i915/display/intel_dp.c | 21 -
>  include/drm/drm_dp_helper.h |  8 +++-
>  3 files changed, 41 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
> index 9703b33599c3b..05bb47e589731 100644
> --- a/drivers/gpu/drm/drm_dp_helper.c
> +++ b/drivers/gpu/drm/drm_dp_helper.c
> @@ -700,6 +700,28 @@ void drm_dp_set_subconnector_property(struct 
> drm_connector *connector,
>  }
>  EXPORT_SYMBOL(drm_dp_set_subconnector_property);
>  
> +/**
> + * drm_dp_has_sink_count() - Check whether a given connector has a valid sink
> + * count
> + * @connector: The DRM connector to check
> + * @dpcd: A cached copy of the connector's DPCD RX capabilities
> + * @desc: A cached copy of the connector's DP descriptor
> + *
> + * Returns: %True if the (e)DP connector has a valid sink count that should
> + * be probed, %false otherwise.
> + */
> +bool drm_dp_has_sink_count(struct drm_connector *connector,
> +const u8 dpcd[DP_RECEIVER_CAP_SIZE],
> +const struct drm_dp_desc *desc)
> +{
> + /* Some eDP panels don't set a valid value for the sink count */
> + return connector->connector_type != DRM_MODE_CONNECTOR_eDP &&
> + dpcd[DP_DPCD_REV] >= DP_DPCD_REV_11 &&
> + dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_PRESENT &&
> + !drm_dp_has_quirk(desc, 0, DP_DPCD_QUIRK_NO_SINK_COUNT);
> +}
> +EXPORT_SYMBOL(drm_dp_has_sink_count);
> +
>  /*
>   * I2C-over-AUX implementation
>   */
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
> b/drivers/gpu/drm/i915/display/intel_dp.c
> index 984e49194ca31..35a4779a442e2 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -4634,6 +4634,16 @@ intel_edp_init_dpcd(struct intel_dp *intel_dp)
>   return true;
>  }
>  
> +static bool
> +intel_dp_has_sink_count(struct intel_dp *intel_dp)
> +{
> + if (!intel_dp->attached_connector)
> + return false;
> +
> + return drm_dp_has_sink_count(_dp->attached_connector->base,
> +  intel_dp->dpcd,
> +  _dp->desc);
> +}
>  
>  static bool
>  intel_dp_get_dpcd(struct intel_dp *intel_dp)
> @@ -4653,13 +4663,7 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp)
>   intel_dp_set_common_rates(intel_dp);
>   }
>  
> - /*
> -  * Some eDP panels do not set a valid value for sink count, that is why
> -  * it don't care about read it here and in intel_edp_init_dpcd().
> -  */
> - if (!intel_dp_is_edp(intel_dp) &&
> - !drm_dp_has_quirk(_dp->desc, 0,
> -   DP_DPCD_QUIRK_NO_SINK_COUNT)) {
> + if (intel_dp_has_sink_count(intel_dp)) {
>   u8 count;
>   ssize_t r;
>  
> @@ -5939,9 +5943,8 @@ intel_dp_detect_dpcd(struct intel_dp *intel_dp)
>   return connector_status_connected;
>  
>   /* If we're HPD-aware, SINK_COUNT changes dynamically */
> - if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11 &&
> + if (intel_dp_has_sink_count(intel_dp) &&
>   intel_dp->downstream_ports[0] & DP_DS_PORT_HPD) {
> -
>   return intel_dp->sink_count ?
>   connector_status_connected : connector_status_disconnected;
>   }
> diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
> index 1349f16564ace..a1413a531eaf4 100644
> --- a/include/drm/drm_dp_helper.h
> +++ b/include/drm/drm_dp_helper.h
> @@ -1631,6 +1631,11 @@ void drm_dp_set_subconnector_property(struct 
> drm_connector *connector,
> const u8 *dpcd,
> const u8 port_cap[4]);
>  
> +struct drm_dp_desc;
> +bool drm_dp_has_sink_count(struct drm_connector *connector,
> +const u8 dpcd[DP_RECEIVER_CAP_SIZE],
> +const struct drm_dp_desc *desc);
> +
>  

Re: [RFC 13/20] drm/i915/dp: Extract drm_dp_downstream_read_info()

2020-08-19 Thread Sean Paul
_downstream_max_clock(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
>   const u8 port_cap[4]);
>  int drm_dp_downstream_max_bpc(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
> -- 
> 2.26.2
> 
> ___
> dri-devel mailing list
> dri-de...@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [RFC 09/20] drm/i915/dp: Extract drm_dp_has_mst()

2020-08-19 Thread Sean Paul
On Tue, Aug 11, 2020 at 04:04:46PM -0400, Lyude Paul wrote:
> Just a tiny drive-by cleanup, we can consolidate i915's code for
> checking for MST support into a helper to be shared across drivers.
> 

Reviewed-by: Sean Paul 

> Signed-off-by: Lyude Paul 
> ---
>  drivers/gpu/drm/i915/display/intel_dp.c | 18 ++
>  include/drm/drm_dp_mst_helper.h | 22 ++
>  2 files changed, 24 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
> b/drivers/gpu/drm/i915/display/intel_dp.c
> index 79c27f91f42c0..1e29d3a012856 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -4699,20 +4699,6 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp)
>   return true;
>  }
>  
> -static bool
> -intel_dp_sink_can_mst(struct intel_dp *intel_dp)
> -{
> - u8 mstm_cap;
> -
> - if (intel_dp->dpcd[DP_DPCD_REV] < 0x12)
> - return false;
> -
> - if (drm_dp_dpcd_readb(_dp->aux, DP_MSTM_CAP, _cap) != 1)
> - return false;
> -
> - return mstm_cap & DP_MST_CAP;
> -}
> -
>  static bool
>  intel_dp_can_mst(struct intel_dp *intel_dp)
>  {
> @@ -4720,7 +4706,7 @@ intel_dp_can_mst(struct intel_dp *intel_dp)
>  
>   return i915->params.enable_dp_mst &&
>   intel_dp->can_mst &&
> - intel_dp_sink_can_mst(intel_dp);
> + drm_dp_has_mst(_dp->aux, intel_dp->dpcd);
>  }
>  
>  static void
> @@ -4729,7 +4715,7 @@ intel_dp_configure_mst(struct intel_dp *intel_dp)
>   struct drm_i915_private *i915 = dp_to_i915(intel_dp);
>   struct intel_encoder *encoder =
>   _to_dig_port(intel_dp)->base;
> - bool sink_can_mst = intel_dp_sink_can_mst(intel_dp);
> + bool sink_can_mst = drm_dp_has_mst(_dp->aux, intel_dp->dpcd);
>  
>   drm_dbg_kms(>drm,
>   "[ENCODER:%d:%s] MST support: port: %s, sink: %s, modparam: 
> %s\n",
> diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h
> index 8b9eb4db3381c..2d8983a713e8c 100644
> --- a/include/drm/drm_dp_mst_helper.h
> +++ b/include/drm/drm_dp_mst_helper.h
> @@ -911,4 +911,26 @@ __drm_dp_mst_state_iter_get(struct drm_atomic_state 
> *state,
>   for ((__i) = 0; (__i) < (__state)->num_private_objs; (__i)++) \
>   for_each_if(__drm_dp_mst_state_iter_get((__state), &(mgr), 
> NULL, &(new_state), (__i)))
>  
> +/**
> + * drm_dp_has_mst() - check whether or not a sink supports MST
> + * @aux: The DP AUX channel to use
> + * @dpcd: A cached copy of the DPCD capabilities for this sink
> + *
> + * Returns: %True if the sink supports MST, %false otherwise
> + */
> +static inline bool
> +drm_dp_has_mst(struct drm_dp_aux *aux,
> +const u8 dpcd[DP_RECEIVER_CAP_SIZE])
> +{
> + u8 mstm_cap;
> +
> + if (dpcd[DP_DPCD_REV] < DP_DPCD_REV_12)
> + return false;
> +
> + if (drm_dp_dpcd_readb(aux, DP_MSTM_CAP, _cap) != 1)
> + return false;
> +
> + return !!(mstm_cap & DP_MST_CAP);
> +}
> +
>  #endif
> -- 
> 2.26.2
> 
> ___
> dri-devel mailing list
> dri-de...@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Sean Paul, Software Engineer, Google / Chromium OS


[PATCH v8 12/17] drm/i915: Factor out HDCP shim functions from dp for use by dp_mst

2020-08-18 Thread Sean Paul
From: Sean Paul 

These functions are all the same for dp and dp_mst, so move them into a
dedicated file for both sst and mst to use.

Reviewed-by: Ramalingam C 
Signed-off-by: Sean Paul 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20191203173638.94919-11-s...@poorly.run
 #v1
Link: 
https://patchwork.freedesktop.org/patch/msgid/20191212190230.188505-12-s...@poorly.run
 #v2
Link: 
https://patchwork.freedesktop.org/patch/msgid/20200117193103.156821-12-s...@poorly.run
 #v3
Link: 
https://patchwork.freedesktop.org/patch/msgid/20200218220242.107265-12-s...@poorly.run
 #v4
Link: 
https://patchwork.freedesktop.org/patch/msgid/20200305201236.152307-12-s...@poorly.run
 #v5
Link: 
https://patchwork.freedesktop.org/patch/msgid/20200429195502.39919-12-s...@poorly.run
 #v6
Link: 
https://patchwork.freedesktop.org/patch/msgid/20200623155907.22961-13-s...@poorly.run
 #v7

Changes in v2:
-None
Changes in v3:
-Created intel_dp_hdcp.c for the shared functions to live (Ville)
Changes in v4:
-Rebased on new drm logging change
Changes in v5:
-None
Changes in v6:
-None
Changes in v7:
-Rebased patch
Changes in v8:
-None
---
 drivers/gpu/drm/i915/Makefile|   1 +
 drivers/gpu/drm/i915/display/intel_dp.c  | 607 +-
 drivers/gpu/drm/i915/display/intel_dp.h  |   3 +
 drivers/gpu/drm/i915/display/intel_dp_hdcp.c | 637 +++
 4 files changed, 642 insertions(+), 606 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/display/intel_dp_hdcp.c

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index bda4c0e408f8..e5574e506a5c 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -234,6 +234,7 @@ i915-y += \
display/intel_ddi.o \
display/intel_dp.o \
display/intel_dp_aux_backlight.o \
+   display/intel_dp_hdcp.o \
display/intel_dp_link_training.o \
display/intel_dp_mst.o \
display/intel_dsi.o \
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index b54577a04ccf..41d76df7423e 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -38,7 +38,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 
 #include "i915_debugfs.h"
@@ -6401,610 +6400,6 @@ void intel_dp_encoder_suspend(struct intel_encoder 
*intel_encoder)
edp_panel_vdd_off_sync(intel_dp);
 }
 
-static void intel_dp_hdcp_wait_for_cp_irq(struct intel_hdcp *hdcp, int timeout)
-{
-   long ret;
-
-#define C (hdcp->cp_irq_count_cached != atomic_read(>cp_irq_count))
-   ret = wait_event_interruptible_timeout(hdcp->cp_irq_queue, C,
-  msecs_to_jiffies(timeout));
-
-   if (!ret)
-   DRM_DEBUG_KMS("Timedout at waiting for CP_IRQ\n");
-}
-
-static
-int intel_dp_hdcp_write_an_aksv(struct intel_digital_port *dig_port,
-   u8 *an)
-{
-   struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
-   u8 aksv[DRM_HDCP_KSV_LEN] = {};
-   ssize_t dpcd_ret;
-
-   /* Output An first, that's easy */
-   dpcd_ret = drm_dp_dpcd_write(_port->dp.aux, DP_AUX_HDCP_AN,
-an, DRM_HDCP_AN_LEN);
-   if (dpcd_ret != DRM_HDCP_AN_LEN) {
-   drm_dbg_kms(>drm,
-   "Failed to write An over DP/AUX (%zd)\n",
-   dpcd_ret);
-   return dpcd_ret >= 0 ? -EIO : dpcd_ret;
-   }
-
-   /*
-* Since Aksv is Oh-So-Secret, we can't access it in software. So we
-* send an empty buffer of the correct length through the DP helpers. On
-* the other side, in the transfer hook, we'll generate a flag based on
-* the destination address which will tickle the hardware to output the
-* Aksv on our behalf after the header is sent.
-*/
-   dpcd_ret = drm_dp_dpcd_write(_port->dp.aux, DP_AUX_HDCP_AKSV,
-aksv, DRM_HDCP_KSV_LEN);
-   if (dpcd_ret != DRM_HDCP_KSV_LEN) {
-   drm_dbg_kms(>drm,
-   "Failed to write Aksv over DP/AUX (%zd)\n",
-   dpcd_ret);
-   return dpcd_ret >= 0 ? -EIO : dpcd_ret;
-   }
-   return 0;
-}
-
-static int intel_dp_hdcp_read_bksv(struct intel_digital_port *dig_port,
-  u8 *bksv)
-{
-   struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
-   ssize_t ret;
-
-   ret = drm_dp_dpcd_read(_port->dp.aux, DP_AUX_HDCP_BKSV, bksv,
-  DRM_HDCP_KSV_LEN);
-   if (ret != DRM_HDCP_KSV_LEN) {
-   drm_dbg_kms(>drm,
-   "Read Bksv from DP/AUX failed (%zd)\n", ret);
-   return ret >= 0 ? -EIO : ret;
-   }
-

Re: [PATCH] drm/msm/dpu: fix unitialized variable error

2020-08-11 Thread Sean Paul
On Tue, Aug 11, 2020 at 5:08 PM Rob Clark  wrote:
>
> From: Rob Clark 
>
>  drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c:817 dpu_crtc_enable() error: 
> uninitialized symbol 'request_bandwidth'.
>
> Reported-by: kernel test robot 

Reviewed-by: Sean Paul 

> Signed-off-by: Rob Clark 
> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> index f272a8d0f95b..c2729f71e2fa 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> @@ -827,7 +827,7 @@ static void dpu_crtc_enable(struct drm_crtc *crtc,
>  {
> struct dpu_crtc *dpu_crtc;
> struct drm_encoder *encoder;
> -   bool request_bandwidth;
> +   bool request_bandwidth = false;
>
> if (!crtc) {
> DPU_ERROR("invalid crtc\n");
> --
> 2.26.2
>


Re: [PATCH v2] tracing: Add trace_array_init_printk() to initialize instance trace_printk() buffers

2020-08-06 Thread Sean Paul
On Thu, Aug 6, 2020 at 2:46 PM Steven Rostedt  wrote:
>
> From: "Steven Rostedt (VMware)" 
>
> As trace_array_printk() used with not global instances will not add noise to
> the main buffer, they are OK to have in the kernel (unlike trace_printk()).
> This require the subsystem to create their own tracing instance, and the
> trace_array_printk() only writes into those instances.
>
> Add trace_array_init_printk() to initialize the trace_printk() buffers
> without printing out the WARNING message.
>
> Reported-by: Sean Paul 
> Signed-off-by: Steven Rostedt (VMware) 
> ---
> Changes since v1:
>   Added EXPORT_SYMBOL_GPL() to trace_array_init_printk() as it is
>   required for another function that is exported.

Could we also add this to trace.h?

>
>  kernel/trace/trace.c | 44 
>  1 file changed, 44 insertions(+)
>
> diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
> index 06c0feae5ff9..c5f822736261 100644
> --- a/kernel/trace/trace.c
> +++ b/kernel/trace/trace.c
> @@ -3129,6 +3129,9 @@ static int alloc_percpu_trace_buffer(void)
>  {
> struct trace_buffer_struct *buffers;
>
> +   if (trace_percpu_buffer)
> +   return 0;
> +
> buffers = alloc_percpu(struct trace_buffer_struct);
> if (MEM_FAIL(!buffers, "Could not allocate percpu trace_printk 
> buffer"))
> return -ENOMEM;
> @@ -3331,6 +3334,26 @@ int trace_array_vprintk(struct trace_array *tr,
> return __trace_array_vprintk(tr->array_buffer.buffer, ip, fmt, args);
>  }
>
> +/**
> + * trace_array_printk - Print a message to a specific instance
> + * @tr: The instance trace_array descriptor
> + * @ip: The instruction pointer that this is called from.
> + * @fmt: The format to print (printf format)
> + *
> + * If a subsystem sets up its own instance, they have the right to
> + * printk strings into their tracing instance buffer using this
> + * function. Note, this function will not write into the top level
> + * buffer (use trace_printk() for that), as writing into the top level
> + * buffer should only have events that can be individually disabled.
> + * trace_printk() is only used for debugging a kernel, and should not
> + * be ever encorporated in normal use.
> + *
> + * trace_array_printk() can be used, as it will not add noise to the
> + * top level tracing buffer.
> + *
> + * Note, trace_array_init_printk() must be called on @tr before this
> + * can be used.
> + */
>  __printf(3, 0)
>  int trace_array_printk(struct trace_array *tr,
>unsigned long ip, const char *fmt, ...)
> @@ -3355,6 +3378,27 @@ int trace_array_printk(struct trace_array *tr,
>  }
>  EXPORT_SYMBOL_GPL(trace_array_printk);
>
> +/**
> + * trace_array_init_printk - Initialize buffers for trace_array_printk()
> + * @tr: The trace array to initialize the buffers for
> + *
> + * As trace_array_printk() only writes into instances, they are OK to
> + * have in the kernel (unlike trace_printk()). This needs to be called
> + * before trace_array_printk() can be used on a trace_array.
> + */
> +int trace_array_init_printk(struct trace_array *tr)
> +{
> +   if (!tr)
> +   return -ENOENT;
> +
> +   /* This is only allowed for created instances */
> +   if (tr == _trace)
> +   return -EINVAL;
> +
> +   return alloc_percpu_trace_buffer();
> +}
> +EXPORT_SYMBOL_GPL(trace_array_init_printk);
> +
>  __printf(3, 4)
>  int trace_array_printk_buf(struct trace_buffer *buffer,
>unsigned long ip, const char *fmt, ...)
> --
> 2.25.4
>


Re: tracing: Add trace_array_init_printk() to initialize instance trace_printk() buffers

2020-08-06 Thread Sean Paul
On Thu, Aug 6, 2020 at 12:57 PM Steven Rostedt  wrote:
>
> From: "Steven Rostedt (VMware)" 
>
> As trace_array_printk() used with not global instances will not add noise to
> the main buffer, they are OK to have in the kernel (unlike trace_printk()).
> This require the subsystem to create their own tracing instance, and the
> trace_array_printk() only writes into those instances.
>
> Add trace_array_init_printk() to initialize the trace_printk() buffers
> without printing out the WARNING message.
>
> Reported-by: Sean Paul 

With the addition of exporting the symbol (which you pointed out on
IRC), this LGTM. Thanks again for being so accommodating!

Reviewed-by: Sean Paul 


> Signed-off-by: Steven Rostedt (VMware) 
> ---
>  kernel/trace/trace.c | 43 +++
>  1 file changed, 43 insertions(+)
>
> diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
> index 06c0feae5ff9..48b608d9c5b1 100644
> --- a/kernel/trace/trace.c
> +++ b/kernel/trace/trace.c
> @@ -3129,6 +3129,9 @@ static int alloc_percpu_trace_buffer(void)
>  {
> struct trace_buffer_struct *buffers;
>
> +   if (trace_percpu_buffer)
> +   return 0;
> +
> buffers = alloc_percpu(struct trace_buffer_struct);
> if (MEM_FAIL(!buffers, "Could not allocate percpu trace_printk 
> buffer"))
> return -ENOMEM;
> @@ -3331,6 +3334,26 @@ int trace_array_vprintk(struct trace_array *tr,
> return __trace_array_vprintk(tr->array_buffer.buffer, ip, fmt, args);
>  }
>
> +/**
> + * trace_array_printk - Print a message to a specific instance
> + * @tr: The instance trace_array descriptor
> + * @ip: The instruction pointer that this is called from.
> + * @fmt: The format to print (printf format)
> + *
> + * If a subsystem sets up its own instance, they have the right to
> + * printk strings into their tracing instance buffer using this
> + * function. Note, this function will not write into the top level
> + * buffer (use trace_printk() for that), as writing into the top level
> + * buffer should only have events that can be individually disabled.
> + * trace_printk() is only used for debugging a kernel, and should not
> + * be ever encorporated in normal use.
> + *
> + * trace_array_printk() can be used, as it will not add noise to the
> + * top level tracing buffer.
> + *
> + * Note, trace_array_init_printk() must be called on @tr before this
> + * can be used.
> + */
>  __printf(3, 0)
>  int trace_array_printk(struct trace_array *tr,
>unsigned long ip, const char *fmt, ...)
> @@ -3355,6 +3378,26 @@ int trace_array_printk(struct trace_array *tr,
>  }
>  EXPORT_SYMBOL_GPL(trace_array_printk);
>
> +/**
> + * trace_array_init_printk - Initialize buffers for trace_array_printk()
> + * @tr: The trace array to initialize the buffers for
> + *
> + * As trace_array_printk() only writes into instances, they are OK to
> + * have in the kernel (unlike trace_printk()). This needs to be called
> + * before trace_array_printk() can be used on a trace_array.
> + */
> +int trace_array_init_printk(struct trace_array *tr)
> +{
> +   if (!tr)
> +   return -ENOENT;
> +
> +   /* This is only allowed for created instances */
> +   if (tr == _trace)
> +   return -EINVAL;
> +
> +   return alloc_percpu_trace_buffer();
> +}
> +
>  __printf(3, 4)
>  int trace_array_printk_buf(struct trace_buffer *buffer,
>unsigned long ip, const char *fmt, ...)
> --
> 2.25.4
>


Re: [PATCH v10 0/2] Panel rotation patches

2020-05-12 Thread Sean Paul
On Thu, Apr 16, 2020 at 7:03 PM Dmitry Osipenko  wrote:
>
> 15.04.2020 00:32, dbasehore . пишет:
> > On Tue, Apr 14, 2020 at 2:18 PM Dmitry Osipenko  wrote:
> >>
> >> 14.04.2020 22:32, dbasehore . пишет:
> >>> Hi Dmitry, sorry for the late reply.
> >>>
> >>> On Sun, Mar 8, 2020 at 12:25 PM Dmitry Osipenko  wrote:
> >>>>
> >>>> 06.03.2020 03:21, Derek Basehore пишет:
> >>>>> This adds the plumbing for reading panel rotation from the devicetree
> >>>>> and sets up adding a panel property for the panel orientation on
> >>>>> Mediatek SoCs when a rotation is present.
> >>>>
> >>>> Hello Derek and everyone,
> >>>>
> >>>> I'm looking at adding display rotation support to NVIDIA Tegra DRM
> >>>> driver because some devices have display panel physically mounted
> >>>> upside-down, and thus, display controller's scan-out needs to be rotated
> >>>> by 180° in this case.
> >>>>
> >>>> Derek, yours panel-rotation patches add support for assigning panel's
> >>>> orientation to the connector, but then only primary display plane
> >>>> receives rotation value in [1], while rotation needs to be applied to
> >>>> all available overlay/cursor planes and this should happen in other
> >>>> places than [1] as well.
> >>>
> >>> This is intended. We don't correct the output in the kernel. We
> >>> instead rely on notifying userspace that the panel is rotated, then we
> >>> handle it there.
> >>>
> >>>>
> >>>> [1] drm_client_modeset_commit_atomic()
> >>>>
> >>>> Please also note that in a case of the scan-out rotation, plane's
> >>>> coordinates need to be changed in accordance to the display's rotation.
> >>>>
> >>>> I looked briefly through the DRM code and my understanding that the DRM
> >>>> core currently doesn't support use-case where scan-out needs to rotated
> >>>> based on a panel's orientation, correct? Is it the use-case you're
> >>>> working on for the Mediatek driver?
> >>>
> >>> Yes, we rely on userspace to rotate the output. The major reason for
> >>> this is because there may not be a "free" hardware rotation that can
> >>> be applied to the overlay. Sean Paul and others also preferred that
> >>> userspace control what is output to the screen instead of the kernel
> >>> taking care of it. This code just adds the drm property to the panel.
> >>>
> >>
> >> Could you please explain what that userspace is?
> >
> > This was added for Chrome OS, which uses its own graphics stack,
> > Ozone, instead of Xorg.
> >
>
> Thank you very much for the clarification.
>
> It's probably not a big problem for something monolithic and customized
> like ChromeOS to issue a software update in order to take into account
> all specifics of a particular device, but this doesn't work nicely for a
> generic software, like a usual Linux distro.
>
> >> AFAIK, things like Xorg modesetting don't support that orientation 
> >> property.
>
> In my case it's not only the display panel which is upside-down, but
> also the touchscreen. Hence both display output and touchscreen input
> need to be rotated at once, otherwise you'll end up with either display
> or input being upside-down.
>
> The 180° rotation should be free on NVIDIA Tegra. There are no known
> limitations for the planes and BSP kernel video driver handles the
> plane's coordinates/framebuffer rotation within the driver.
>
> The kernel's input subsystem allows us to transparently (for userspace)
> remap the touchscreen input (by specifying generic touchscreen
> device-tree properties), while this is not the case for the DRM subsystem.
>
> @Thierry, @Sean, @Daniel, could you please help me to understand how a
> coordinated display / input rotation could be implemented, making the
> rotation transparent to the user (i.e. avoiding xorg.conf hacking and
> etc)? It should be nice if display's output could be flipped within the
> DRM driver, hiding this fact from userspace.

I think the right thing to do is to fix userspace to respect this
property, since that has the most communal benefit.

However(!!) if you don't want to do that, how about inspecting the
info->panel_orientation value after drm_panel_attach in tegra driver
and then adjusting rotation values in the driver. Of course, you
wouldn't want to expose the panel orientation property since you don't
want userspaces to be double-rotating on you, but it's optional so
you'd be fine.

>
> Will it be okay if we'll add a transparent-rotation support specifically
> to the Tegra DRM driver? For example if device-tree contains
> nvidia,display-flip-y property, then the Tegra DRM driver will take care
> of rotating coordinates/framebuffer of the display planes.

I don't think this is necessary, but it also wouldn't really be
appropriate to put software attributes into devicetree anyways.

Sean


Re: [PATCH] drm: Replace drm_modeset_lock/unlock_all with DRM_MODESET_LOCK_ALL_* helpers

2020-04-30 Thread Sean Paul
On Wed, Apr 29, 2020 at 4:57 AM Jani Nikula  wrote:
>
> On Tue, 28 Apr 2020, Michal Orzel  wrote:
> > As suggested by the TODO list for the kernel DRM subsystem, replace
> > the deprecated functions that take/drop modeset locks with new helpers.
> >
> > Signed-off-by: Michal Orzel 
> > ---
> >  drivers/gpu/drm/drm_mode_object.c | 10 ++
> >  1 file changed, 6 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/drm_mode_object.c 
> > b/drivers/gpu/drm/drm_mode_object.c
> > index 35c2719..901b078 100644
> > --- a/drivers/gpu/drm/drm_mode_object.c
> > +++ b/drivers/gpu/drm/drm_mode_object.c
> > @@ -402,12 +402,13 @@ int drm_mode_obj_get_properties_ioctl(struct 
> > drm_device *dev, void *data,
> >  {
> >   struct drm_mode_obj_get_properties *arg = data;
> >   struct drm_mode_object *obj;
> > + struct drm_modeset_acquire_ctx ctx;
> >   int ret = 0;
> >
> >   if (!drm_core_check_feature(dev, DRIVER_MODESET))
> >   return -EOPNOTSUPP;
> >
> > - drm_modeset_lock_all(dev);
> > + DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, 0, ret);
>
> I cry a little every time I look at the DRM_MODESET_LOCK_ALL_BEGIN and
> DRM_MODESET_LOCK_ALL_END macros. :(
>
> Currently only six users... but there are ~60 calls to
> drm_modeset_lock_all{,_ctx} that I presume are to be replaced. I wonder
> if this will come back and haunt us.
>

What's the alternative? Seems like the options without the macros is
to use incorrect scope or have a bunch of retry/backoff cargo-cult
everywhere (and hope the copy source is done correctly).

Sean

> BR,
> Jani.
>
>
> >
> >   obj = drm_mode_object_find(dev, file_priv, arg->obj_id, 
> > arg->obj_type);
> >   if (!obj) {
> > @@ -427,7 +428,7 @@ int drm_mode_obj_get_properties_ioctl(struct drm_device 
> > *dev, void *data,
> >  out_unref:
> >   drm_mode_object_put(obj);
> >  out:
> > - drm_modeset_unlock_all(dev);
> > + DRM_MODESET_LOCK_ALL_END(ctx, ret);
> >   return ret;
> >  }
> >
> > @@ -449,12 +450,13 @@ static int set_property_legacy(struct drm_mode_object 
> > *obj,
> >  {
> >   struct drm_device *dev = prop->dev;
> >   struct drm_mode_object *ref;
> > + struct drm_modeset_acquire_ctx ctx;
> >   int ret = -EINVAL;
> >
> >   if (!drm_property_change_valid_get(prop, prop_value, ))
> >   return -EINVAL;
> >
> > - drm_modeset_lock_all(dev);
> > + DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, 0, ret);
> >   switch (obj->type) {
> >   case DRM_MODE_OBJECT_CONNECTOR:
> >   ret = drm_connector_set_obj_prop(obj, prop, prop_value);
> > @@ -468,7 +470,7 @@ static int set_property_legacy(struct drm_mode_object 
> > *obj,
> >   break;
> >   }
> >   drm_property_change_valid_put(prop, ref);
> > - drm_modeset_unlock_all(dev);
> > + DRM_MODESET_LOCK_ALL_END(ctx, ret);
> >
> >   return ret;
> >  }
>
> --
> Jani Nikula, Intel Open Source Graphics Center


Re: [PATCH] MAINTAINERS: Add Mihail to Komeda DRM driver

2019-10-21 Thread Sean Paul
On Mon, Oct 21, 2019 at 03:01:56PM +, Mihail Atanassov wrote:
> I'll be the main point of contact.
> 
> Cc: James Qian Wang (Arm Technology China) 
> Cc: Liviu Dudau 
> Signed-off-by: Mihail Atanassov 

Acked-by: Sean Paul 

> ---
>  MAINTAINERS | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 94fb077c0817..d32f263f0022 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1251,6 +1251,7 @@ F:  
> Documentation/devicetree/bindings/display/arm,hdlcd.txt
>  ARM KOMEDA DRM-KMS DRIVER
>  M:   James (Qian) Wang 
>  M:   Liviu Dudau 
> +M:   Mihail Atanassov 
>  L:   Mali DP Maintainers 
>  S:   Supported
>  T:   git git://anongit.freedesktop.org/drm/drm-misc
> -- 
> 2.23.0
> 

-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [PATCH] drm/msm/dsi: Implement reset correctly

2019-10-10 Thread Sean Paul
On Wed, Oct 09, 2019 at 02:34:54PM -0700, Jeffrey Hugo wrote:
> On msm8998, vblank timeouts are observed because the DSI controller is not
> reset properly, which ends up stalling the MDP.  This is because the reset
> logic is not correct per the hardware documentation.
> 
> The documentation states that after asserting reset, software should wait
> some time (no indication of how long), or poll the status register until it
> returns 0 before deasserting reset.
> 
> wmb() is insufficient for this purpose since it just ensures ordering, not
> timing between writes.  Since asserting and deasserting reset occurs on the
> same register, ordering is already guaranteed by the architecture, making
> the wmb extraneous.
> 
> Since we would define a timeout for polling the status register to avoid a
> possible infinite loop, lets just use a static delay of 20 ms, since 16.666
> ms is the time available to process one frame at 60 fps.
> 
> Fixes: a689554ba6ed (drm/msm: Initial add DSI connector support)
> Signed-off-by: Jeffrey Hugo 
> ---
> 
> Rob et al, is it possible for this to go into a 5.4-rc?
> 
>  drivers/gpu/drm/msm/dsi/dsi_host.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
> b/drivers/gpu/drm/msm/dsi/dsi_host.c
> index 663ff9f4fac9..68ded9b4735d 100644
> --- a/drivers/gpu/drm/msm/dsi/dsi_host.c
> +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
> @@ -986,7 +986,7 @@ static void dsi_sw_reset(struct msm_dsi_host *msm_host)
>   wmb(); /* clocks need to be enabled before reset */
>  
>   dsi_write(msm_host, REG_DSI_RESET, 1);
> - wmb(); /* make sure reset happen */
> + msleep(20); /* make sure reset happen */

Could you please pull this out into a #define used for both in case we decide to
tweak it? I don't want these 2 values to drift.

Thanks,
Sean

>   dsi_write(msm_host, REG_DSI_RESET, 0);
>  }
>  
> @@ -1396,7 +1396,7 @@ static void dsi_sw_reset_restore(struct msm_dsi_host 
> *msm_host)
>  
>   /* dsi controller can only be reset while clocks are running */
>   dsi_write(msm_host, REG_DSI_RESET, 1);
> - wmb();  /* make sure reset happen */
> + msleep(20); /* make sure reset happen */
>   dsi_write(msm_host, REG_DSI_RESET, 0);
>   wmb();  /* controller out of reset */
>   dsi_write(msm_host, REG_DSI_CTRL, data0);
> -- 
> 2.17.1
> 

-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [v8,2/4] drm/panel: set display info in panel attach

2019-10-08 Thread Sean Paul
/snip

> > > > > diff --git a/include/drm/drm_panel.h b/include/drm/drm_panel.h
> > > > > index d16158deacdc..f3587a54b8ac 100644
> > > > > --- a/include/drm/drm_panel.h
> > > > > +++ b/include/drm/drm_panel.h
> > > > > @@ -141,6 +141,56 @@ struct drm_panel {
> > > > >*/
> > > > >   const struct drm_panel_funcs *funcs;
> > > > >
> > > >
> > > > All these new added members seems dupliated with drm_display_info,
> > > > So I think, can we add a new drm_plane_funcs func:
> > > >
> > > > int (*set_display_info)(struct drm_panel *panel,
> > > > struct drm_display_info *info);
> > >
> > > I don't disagree personally, since I originally wrote it this way, but
> > > 2 maintainers, Daniel Vetter and Thierry Reding, requested that it be
> > > changed. Unless that decision is reversed, I won't be changing this.
> > >
> >
> > Reading back the feedback on v1, I don't think anyone said they were against
> > storing a drm_display_info struct in drm_panel (no one really weighed in on
> > it one way or another). IMO duplicating a bunch of fields feels pretty icky.
> 
> Thanks for the review. Should we duplicate the entire struct, or just
> create a sub-struct, say, physical_properties that will be part of
> drm_display_info and drm_panel?

That's a good idea, but I think you can use the entire struct. Everything has
reasonable default values and I think it might be difficult to draw a line in
the sand as to which fields will or won't be useful for panels going forward.
Best for drivers to just treat the info in drm_display_info as best effort and
have good defaults IMO.

Sean

> 
> >
> > I think most fields in drm_display_info have pretty reasonable defaults, so 
> > I'd
> > recommend just storing a copy in drm_panel. As Thierry suggests, we can
> > populate the dt parts in probe (orientation) and then copy over all or a 
> > subset
> > of the struct to connector on attach.
> >
> > Sean
> >
> > > >
> > > > Then in drm_panel_attach(), via this interface the specific panel
> > > > driver can directly set connector->display_info. like
> > > >
> > > >...
> > > >if (panel->funcs && panel->funcs->set_display_info)
> > > > panel->funcs->unprepare(panel, connector->display_info);
> > > >...
> > > >
> > > > Thanks
> > > > James
> > > >
> > > > > + /**
> > > > > +  * @width_mm:
> > > > > +  *
> > > > > +  * Physical width in mm.
> > > > > +  */
> > > > > + unsigned int width_mm;
> > > > > +
> > > > > + /**
> > > > > +  * @height_mm:
> > > > > +  *
> > > > > +  * Physical height in mm.
> > > > > +  */
> > > > > + unsigned int height_mm;
> > > > > +
> > > > > + /**
> > > > > +  * @bpc:
> > > > > +  *
> > > > > +  * Maximum bits per color channel. Used by HDMI and DP outputs.
> > > > > +  */
> > > > > + unsigned int bpc;
> > > > > +
> > > > > + /**
> > > > > +  * @orientation
> > > > > +  *
> > > > > +  * Installation orientation of the panel with respect to the 
> > > > > chassis.
> > > > > +  */
> > > > > + int orientation;
> > > > > +
> > > > > + /**
> > > > > +  * @bus_formats
> > > > > +  *
> > > > > +  * Pixel data format on the wire.
> > > > > +  */
> > > > > + const u32 *bus_formats;
> > > > > +
> > > > > + /**
> > > > > +  * @num_bus_formats:
> > > > > +  *
> > > > > +  * Number of elements pointed to by @bus_formats
> > > > > +  */
> > > > > + unsigned int num_bus_formats;
> > > > > +
> > > > > + /**
> > > > > +  * @bus_flags:
> > > > > +  *
> > > > > +  * Additional information (like pixel signal polarity) for the 
> > > > > pixel
> > > > > +  * data on the bus.
> > > > > +  */
> > > > > + u32 bus_flags;
> > > > > +
> > > > >   /**
> > > > >* @list:
> > > > >*
> > >
> > > Thanks for the review
> >
> > --
> > Sean Paul, Software Engineer, Google / Chromium OS

-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [PATCH v8 1/4] drm/panel: Add helper for reading DT rotation

2019-10-08 Thread Sean Paul
On Mon, Oct 07, 2019 at 03:12:00PM -0700, dbasehore . wrote:
> On Mon, Oct 7, 2019 at 9:38 AM Sean Paul  wrote:
> >
> > On Wed, Sep 25, 2019 at 03:58:30PM -0700, Derek Basehore wrote:
> > > This adds a helper function for reading the rotation (panel
> > > orientation) from the device tree.
> > >
> > > Signed-off-by: Derek Basehore 
> > > Reviewed-by: Sam Ravnborg 
> >
> > The patch LGTM, but I don't see it used anywhere later in the patch? Is 
> > there a
> > panel driver incoming?
> 
> Yeah, the boe-tv101wum-nl6 panel will use it. It's not in the patch
> currently sent upstream since I don't want to step on their toes, but
> I plan on sending a patch to add it as soon as that is merged.
> 
> I could hold back on this patch until that panel driver is merged too.

Yeah, I think it's probably best. I don't anticipate any changes will be
required, but it's always best to review the code end-to-end.

I haven't checked in on that review, but if it's close to landing, you can also
add a patch to this stack that is based on the in-flight patches. That way we 
can
get all the review out of the way and then when the panel lands, we can apply
your add-on with the rest of the series.

Sean

> Another alternative is to throw this into the generic drm_panel code,
> but there's no obvious place to put it since DRM seems to leave
> reading the DTS up to the panel drivers themselves.
> 
> >
> > Sean
> >
> > > ---
> > >  drivers/gpu/drm/drm_panel.c | 43 +
> > >  include/drm/drm_panel.h |  9 
> > >  2 files changed, 52 insertions(+)
> > >
> > > diff --git a/drivers/gpu/drm/drm_panel.c b/drivers/gpu/drm/drm_panel.c
> > > index 6b0bf42039cf..0909b53b74e6 100644
> > > --- a/drivers/gpu/drm/drm_panel.c
> > > +++ b/drivers/gpu/drm/drm_panel.c
> > > @@ -264,6 +264,49 @@ struct drm_panel *of_drm_find_panel(const struct 
> > > device_node *np)
> > >   return ERR_PTR(-EPROBE_DEFER);
> > >  }
> > >  EXPORT_SYMBOL(of_drm_find_panel);
> > > +
> > > +/**
> > > + * of_drm_get_panel_orientation - look up the orientation of the panel 
> > > through
> > > + * the "rotation" binding from a device tree node
> > > + * @np: device tree node of the panel
> > > + * @orientation: orientation enum to be filled in
> > > + *
> > > + * Looks up the rotation of a panel in the device tree. The orientation 
> > > of the
> > > + * panel is expressed as a property name "rotation" in the device tree. 
> > > The
> > > + * rotation in the device tree is counter clockwise.
> > > + *
> > > + * Return: 0 when a valid rotation value (0, 90, 180, or 270) is read or 
> > > the
> > > + * rotation property doesn't exist. -EERROR otherwise.
> > > + */
> > > +int of_drm_get_panel_orientation(const struct device_node *np,
> > > +  enum drm_panel_orientation *orientation)
> > > +{
> > > + int rotation, ret;
> > > +
> > > + ret = of_property_read_u32(np, "rotation", );
> > > + if (ret == -EINVAL) {
> > > + /* Don't return an error if there's no rotation property. */
> > > + *orientation = DRM_MODE_PANEL_ORIENTATION_UNKNOWN;
> > > + return 0;
> > > + }
> > > +
> > > + if (ret < 0)
> > > + return ret;
> > > +
> > > + if (rotation == 0)
> > > + *orientation = DRM_MODE_PANEL_ORIENTATION_NORMAL;
> > > + else if (rotation == 90)
> > > + *orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP;
> > > + else if (rotation == 180)
> > > + *orientation = DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP;
> > > + else if (rotation == 270)
> > > + *orientation = DRM_MODE_PANEL_ORIENTATION_LEFT_UP;
> > > + else
> > > + return -EINVAL;
> > > +
> > > + return 0;
> > > +}
> > > +EXPORT_SYMBOL(of_drm_get_panel_orientation);
> > >  #endif
> > >
> > >  MODULE_AUTHOR("Thierry Reding ");
> > > diff --git a/include/drm/drm_panel.h b/include/drm/drm_panel.h
> > > index 624bd15ecfab..d16158deacdc 100644
> > > --- a/include/drm/drm_panel.h
> > > +++ b/include/drm/drm_panel.h
> > > @@ -34,6 +34,8 @@ struct drm_device;
> > >  struct drm_panel;
> > >  struct display_timing;
> 

Re: [PATCH v8 3/4] drm/connector: Split out orientation quirk detection

2019-10-07 Thread Sean Paul
On Wed, Sep 25, 2019 at 03:58:32PM -0700, Derek Basehore wrote:
> Not every platform needs quirk detection for panel orientation, so
> split the drm_connector_init_panel_orientation_property into two
> functions. One for platforms without the need for quirks, and the
> other for platforms that need quirks.
> 
> Signed-off-by: Derek Basehore 
> Acked-by: Sam Ravnborg 

Reviewed-by: Sean Paul 

> ---
>  drivers/gpu/drm/drm_connector.c | 45 ++---
>  drivers/gpu/drm/i915/display/icl_dsi.c  |  2 +-
>  drivers/gpu/drm/i915/display/intel_dp.c |  4 +--
>  drivers/gpu/drm/i915/display/vlv_dsi.c  |  2 +-
>  include/drm/drm_connector.h |  2 ++
>  5 files changed, 39 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> index 4c766624b20d..faef25683faf 100644
> --- a/drivers/gpu/drm/drm_connector.c
> +++ b/drivers/gpu/drm/drm_connector.c
> @@ -1989,31 +1989,23 @@ EXPORT_SYMBOL(drm_connector_set_vrr_capable_property);
>   * drm_connector_init_panel_orientation_property -
>   *   initialize the connecters panel_orientation property
>   * @connector: connector for which to init the panel-orientation property.
> - * @width: width in pixels of the panel, used for panel quirk detection
> - * @height: height in pixels of the panel, used for panel quirk detection
>   *
>   * This function should only be called for built-in panels, after setting
>   * connector->display_info.panel_orientation first (if known).
>   *
> - * This function will check for platform specific (e.g. DMI based) quirks
> - * overriding display_info.panel_orientation first, then if panel_orientation
> - * is not DRM_MODE_PANEL_ORIENTATION_UNKNOWN it will attach the
> - * "panel orientation" property to the connector.
> + * This function will check if the panel_orientation is not
> + * DRM_MODE_PANEL_ORIENTATION_UNKNOWN. If not, it will attach the "panel
> + * orientation" property to the connector.
>   *
>   * Returns:
>   * Zero on success, negative errno on failure.
>   */
>  int drm_connector_init_panel_orientation_property(
> - struct drm_connector *connector, int width, int height)
> + struct drm_connector *connector)
>  {
>   struct drm_device *dev = connector->dev;
>   struct drm_display_info *info = >display_info;
>   struct drm_property *prop;
> - int orientation_quirk;
> -
> - orientation_quirk = drm_get_panel_orientation_quirk(width, height);
> - if (orientation_quirk != DRM_MODE_PANEL_ORIENTATION_UNKNOWN)
> - info->panel_orientation = orientation_quirk;
>  
>   if (info->panel_orientation == DRM_MODE_PANEL_ORIENTATION_UNKNOWN)
>   return 0;
> @@ -2036,6 +2028,35 @@ int drm_connector_init_panel_orientation_property(
>  }
>  EXPORT_SYMBOL(drm_connector_init_panel_orientation_property);
>  
> +/**
> + * drm_connector_init_panel_orientation_property_quirk -
> + *   initialize the connecters panel_orientation property with a quirk
> + *   override
> + * @connector: connector for which to init the panel-orientation property.
> + * @width: width in pixels of the panel, used for panel quirk detection
> + * @height: height in pixels of the panel, used for panel quirk detection
> + *
> + * This function will check for platform specific (e.g. DMI based) quirks
> + * overriding display_info.panel_orientation first, then if panel_orientation
> + * is not DRM_MODE_PANEL_ORIENTATION_UNKNOWN it will attach the
> + * "panel orientation" property to the connector.
> + *
> + * Returns:
> + * Zero on success, negative errno on failure.
> + */
> +int drm_connector_init_panel_orientation_property_quirk(
> + struct drm_connector *connector, int width, int height)
> +{
> + int orientation_quirk;
> +
> + orientation_quirk = drm_get_panel_orientation_quirk(width, height);
> + if (orientation_quirk != DRM_MODE_PANEL_ORIENTATION_UNKNOWN)
> + connector->display_info.panel_orientation = orientation_quirk;
> +
> + return drm_connector_init_panel_orientation_property(connector);
> +}
> +EXPORT_SYMBOL(drm_connector_init_panel_orientation_property_quirk);
> +
>  int drm_connector_set_obj_prop(struct drm_mode_object *obj,
>   struct drm_property *property,
>   uint64_t value)
> diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c 
> b/drivers/gpu/drm/i915/display/icl_dsi.c
> index 6e398c33a524..483287984090 100644
> --- a/drivers/gpu/drm/i915/display/icl_dsi.c
> +++ b/drivers/gpu/drm/i915/display/icl_dsi.c
> @@ -1538,7 +1538,7 @@ static void icl_dsi_add_properties(struct 
> intel_connec

Re: [PATCH v2 17/27] drm/dp_mst: Rename drm_dp_add_port and drm_dp_update_port

2019-09-25 Thread Sean Paul
On Tue, Sep 03, 2019 at 04:45:55PM -0400, Lyude Paul wrote:
> The names for these functions are rather confusing. drm_dp_add_port()
> sounds like a function that would simply create a port and add it to a
> topology, and do nothing more. Similarly, drm_dp_update_port() would be
> assumed to be the function that should be used to update port
> information after initial creation.
> 
> While those assumptions are currently correct in how these functions are
> used, a quick glance at drm_dp_add_port() reveals that drm_dp_add_port()
> can also update the information on a port, and seems explicitly designed
> to do so. This can be explained pretty simply by the fact that there's
> more situations that would involve updating the port information based
> on a link address response as opposed to a connection status
> notification than the driver's initial topology probe. Case in point:
> reprobing link addresses after suspend/resume.
> 
> Since we're about to start using drm_dp_add_port() differently for
> suspend/resume reprobing, let's rename both functions to clarify what
> they actually do.
> 
> Cc: Juston Li 
> Cc: Imre Deak 
> Cc: Ville Syrjälä 
> Cc: Harry Wentland 
> Cc: Daniel Vetter 
> Signed-off-by: Lyude Paul 

Reviewed-by: Sean Paul 

> ---
>  drivers/gpu/drm/drm_dp_mst_topology.c | 17 ++---
>  1 file changed, 10 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c 
> b/drivers/gpu/drm/drm_dp_mst_topology.c
> index 9944ef2ce885..cfaf9eb7ace9 100644
> --- a/drivers/gpu/drm/drm_dp_mst_topology.c
> +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
> @@ -1900,9 +1900,10 @@ void drm_dp_mst_connector_early_unregister(struct 
> drm_connector *connector,
>  }
>  EXPORT_SYMBOL(drm_dp_mst_connector_early_unregister);
>  
> -static void drm_dp_add_port(struct drm_dp_mst_branch *mstb,
> - struct drm_device *dev,
> - struct drm_dp_link_addr_reply_port *port_msg)
> +static void
> +drm_dp_mst_handle_link_address_port(struct drm_dp_mst_branch *mstb,
> + struct drm_device *dev,
> + struct drm_dp_link_addr_reply_port 
> *port_msg)
>  {
>   struct drm_dp_mst_topology_mgr *mgr = mstb->mgr;
>   struct drm_dp_mst_port *port;
> @@ -2011,8 +2012,9 @@ static void drm_dp_add_port(struct drm_dp_mst_branch 
> *mstb,
>   drm_dp_mst_topology_put_port(port);
>  }
>  
> -static void drm_dp_update_port(struct drm_dp_mst_branch *mstb,
> -struct drm_dp_connection_status_notify 
> *conn_stat)
> +static void
> +drm_dp_mst_handle_conn_stat(struct drm_dp_mst_branch *mstb,
> + struct drm_dp_connection_status_notify *conn_stat)
>  {
>   struct drm_dp_mst_port *port;
>   int old_ddps;
> @@ -2464,7 +2466,8 @@ static void drm_dp_send_link_address(struct 
> drm_dp_mst_topology_mgr *mgr,
>   drm_dp_check_mstb_guid(mstb, reply->guid);
>  
>   for (i = 0; i < reply->nports; i++)
> - drm_dp_add_port(mstb, mgr->dev, >ports[i]);
> + drm_dp_mst_handle_link_address_port(mstb, mgr->dev,
> + >ports[i]);
>  
>   drm_kms_helper_hotplug_event(mgr->dev);
>  
> @@ -3324,7 +3327,7 @@ static int drm_dp_mst_handle_up_req(struct 
> drm_dp_mst_topology_mgr *mgr)
>   }
>  
>   if (msg.req_type == DP_CONNECTION_STATUS_NOTIFY) {
> - drm_dp_update_port(mstb, _stat);
> + drm_dp_mst_handle_conn_stat(mstb, _stat);
>  
>   DRM_DEBUG_KMS("Got CSN: pn: %d ldps:%d ddps: %d mcs: %d ip: %d 
> pdt: %d\n",
> msg.u.conn_stat.port_number,
> -- 
> 2.21.0
> 

-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [PATCH v2 02/27] drm/dp_mst: Get rid of list clear in destroy_connector_work

2019-09-25 Thread Sean Paul
On Tue, Sep 03, 2019 at 04:45:40PM -0400, Lyude Paul wrote:
> This seems to be some leftover detritus from before the port/mstb kref
> cleanup and doesn't do anything anymore, so get rid of it.
> 
> Cc: Juston Li 
> Cc: Imre Deak 
> Cc: Ville Syrjälä 
> Cc: Harry Wentland 
> Reviewed-by: Daniel Vetter 
> Signed-off-by: Lyude Paul 

Reviewed-by: Sean Paul 

> ---
>  drivers/gpu/drm/drm_dp_mst_topology.c | 2 --
>  1 file changed, 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c 
> b/drivers/gpu/drm/drm_dp_mst_topology.c
> index 36db66a0ddb1..3054ec622506 100644
> --- a/drivers/gpu/drm/drm_dp_mst_topology.c
> +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
> @@ -3760,8 +3760,6 @@ static void drm_dp_destroy_connector_work(struct 
> work_struct *work)
>   list_del(>next);
>   mutex_unlock(>destroy_connector_lock);
>  
> - INIT_LIST_HEAD(>next);
> -
>   mgr->cbs->destroy_connector(mgr, port->connector);
>  
>   drm_dp_port_teardown_pdt(port, port->pdt);
> -- 
> 2.21.0
> 

-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [PATCH 09/10] drm/msm/dpu: async commit support

2019-09-03 Thread Sean Paul
On Thu, Aug 29, 2019 at 09:45:17AM -0700, Rob Clark wrote:
> From: Rob Clark 
> 
> In addition, moving to kms->flush_commit() lets us drop the only user
> of kms->commit().
> 
> Signed-off-by: Rob Clark 

Reviewed-by: Sean Paul 

> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c| 13 --
>  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c |  7 ++--
>  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h |  5 +++
>  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 46 +++--
>  drivers/gpu/drm/msm/msm_atomic.c|  5 +--
>  drivers/gpu/drm/msm/msm_kms.h   |  3 --
>  6 files changed, 34 insertions(+), 45 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> index 31debd31ab8c..f38a7d27a1c0 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> @@ -606,7 +606,6 @@ void dpu_crtc_commit_kickoff(struct drm_crtc *crtc)
>   struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
>   struct dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc);
>   struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc->state);
> - int ret;
>  
>   /*
>* If no mixers has been allocated in dpu_crtc_atomic_check(),
> @@ -626,17 +625,6 @@ void dpu_crtc_commit_kickoff(struct drm_crtc *crtc)
> crtc->state->encoder_mask)
>   dpu_encoder_prepare_for_kickoff(encoder);
>  
> - /* wait for previous frame_event_done completion */
> - DPU_ATRACE_BEGIN("wait_for_frame_done_event");
> - ret = _dpu_crtc_wait_for_frame_done(crtc);
> - DPU_ATRACE_END("wait_for_frame_done_event");
> - if (ret) {
> - DPU_ERROR("crtc%d wait for frame done failed;frame_pending%d\n",
> - crtc->base.id,
> - atomic_read(_crtc->frame_pending));
> - goto end;
> - }
> -
>   if (atomic_inc_return(_crtc->frame_pending) == 1) {
>   /* acquire bandwidth and other resources */
>   DPU_DEBUG("crtc%d first commit\n", crtc->base.id);
> @@ -650,7 +638,6 @@ void dpu_crtc_commit_kickoff(struct drm_crtc *crtc)
>   drm_for_each_encoder_mask(encoder, crtc->dev, crtc->state->encoder_mask)
>   dpu_encoder_kickoff(encoder);
>  
> -end:
>   reinit_completion(_crtc->frame_done_comp);
>   DPU_ATRACE_END("crtc_commit");
>  }
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> index ac2d534bf59e..3a69b93d8fb6 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> @@ -1678,8 +1678,7 @@ static u32 _dpu_encoder_calculate_linetime(struct 
> dpu_encoder_virt *dpu_enc,
>   return line_time;
>  }
>  
> -static int _dpu_encoder_wakeup_time(struct drm_encoder *drm_enc,
> - ktime_t *wakeup_time)
> +int dpu_encoder_vsync_time(struct drm_encoder *drm_enc, ktime_t *wakeup_time)
>  {
>   struct drm_display_mode *mode;
>   struct dpu_encoder_virt *dpu_enc;
> @@ -1766,7 +1765,7 @@ static void dpu_encoder_vsync_event_work_handler(struct 
> kthread_work *work)
>   return;
>   }
>  
> - if (_dpu_encoder_wakeup_time(_enc->base, _time))
> + if (dpu_encoder_vsync_time(_enc->base, _time))
>   return;
>  
>   trace_dpu_enc_vsync_event_work(DRMID(_enc->base), wakeup_time);
> @@ -1840,7 +1839,7 @@ void dpu_encoder_kickoff(struct drm_encoder *drm_enc)
>   }
>  
>   if (dpu_enc->disp_info.intf_type == DRM_MODE_ENCODER_DSI &&
> - !_dpu_encoder_wakeup_time(drm_enc, _time)) {
> + !dpu_encoder_vsync_time(drm_enc, _time)) {
>   trace_dpu_enc_early_kickoff(DRMID(drm_enc),
>   ktime_to_ms(wakeup_time));
>   mod_timer(_enc->vsync_event_timer,
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h 
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
> index 8465b37adf3b..b4913465e602 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
> @@ -85,6 +85,11 @@ void dpu_encoder_trigger_kickoff_pending(struct 
> drm_encoder *encoder);
>   */
>  void dpu_encoder_kickoff(struct drm_encoder *encoder);
>  
> +/**
> + * dpu_encoder_wakeup_time - get the time of the next vsync
> + */
> +int dpu_encoder_vsync_time(struct drm_encoder *drm_enc, ktime_t 
> *wakeup_time);
> +
>  /**
>   * dpu_encoder_wait_for_event - Waits for enc

Re: [PATCH 07/10] drm/msm: split power control from prepare/complete_commit

2019-09-03 Thread Sean Paul
On Thu, Aug 29, 2019 at 09:45:15AM -0700, Rob Clark wrote:
> From: Rob Clark 
> 
> With atomic commit, ->prepare_commit() and ->complete_commit() may not
> be evenly balanced (although ->complete_commit() will complete each
> crtc that had been previously prepared).  So these will no longer be
> a good place to enable/disable clocks needed for hw access.
> 
> Signed-off-by: Rob Clark 

Reviewed-by: Sean Paul 

> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c  | 17 ++---
>  drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c | 19 ++-
>  drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c | 20 ++--
>  drivers/gpu/drm/msm/msm_atomic.c |  2 ++
>  drivers/gpu/drm/msm/msm_kms.h| 10 ++
>  5 files changed, 54 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c 
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
> index efbf8fd343de..d54741f3ad9f 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
> @@ -248,6 +248,18 @@ static void dpu_kms_disable_vblank(struct msm_kms *kms, 
> struct drm_crtc *crtc)
>   dpu_crtc_vblank(crtc, false);
>  }
>  
> +static void dpu_kms_enable_commit(struct msm_kms *kms)
> +{
> + struct dpu_kms *dpu_kms = to_dpu_kms(kms);
> + pm_runtime_get_sync(_kms->pdev->dev);
> +}
> +
> +static void dpu_kms_disable_commit(struct msm_kms *kms)
> +{
> + struct dpu_kms *dpu_kms = to_dpu_kms(kms);
> + pm_runtime_put_sync(_kms->pdev->dev);
> +}
> +
>  static void dpu_kms_prepare_commit(struct msm_kms *kms,
>   struct drm_atomic_state *state)
>  {
> @@ -267,7 +279,6 @@ static void dpu_kms_prepare_commit(struct msm_kms *kms,
>   if (!dev || !dev->dev_private)
>   return;
>   priv = dev->dev_private;
> - pm_runtime_get_sync(_kms->pdev->dev);
>  
>   /* Call prepare_commit for all affected encoders */
>   for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
> @@ -335,8 +346,6 @@ static void dpu_kms_complete_commit(struct msm_kms *kms, 
> unsigned crtc_mask)
>   for_each_crtc_mask(dpu_kms->dev, crtc, crtc_mask)
>   dpu_crtc_complete_commit(crtc);
>  
> - pm_runtime_put_sync(_kms->pdev->dev);
> -
>   DPU_ATRACE_END("kms_complete_commit");
>  }
>  
> @@ -682,6 +691,8 @@ static const struct msm_kms_funcs kms_funcs = {
>   .irq_preinstall  = dpu_irq_preinstall,
>   .irq_uninstall   = dpu_irq_uninstall,
>   .irq = dpu_irq,
> + .enable_commit   = dpu_kms_enable_commit,
> + .disable_commit  = dpu_kms_disable_commit,
>   .prepare_commit  = dpu_kms_prepare_commit,
>   .flush_commit= dpu_kms_flush_commit,
>   .commit  = dpu_kms_commit,
> diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c 
> b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c
> index 78ce2c8a9a38..500e5b08c11f 100644
> --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c
> +++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c
> @@ -93,15 +93,24 @@ static int mdp4_hw_init(struct msm_kms *kms)
>   return ret;
>  }
>  
> -static void mdp4_prepare_commit(struct msm_kms *kms, struct drm_atomic_state 
> *state)
> +static void mdp4_enable_commit(struct msm_kms *kms)
> +{
> + struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms));
> + mdp4_enable(mdp4_kms);
> +}
> +
> +static void mdp4_disable_commit(struct msm_kms *kms)
>  {
>   struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms));
> + mdp4_disable(mdp4_kms);
> +}
> +
> +static void mdp4_prepare_commit(struct msm_kms *kms, struct drm_atomic_state 
> *state)
> +{
>   int i;
>   struct drm_crtc *crtc;
>   struct drm_crtc_state *crtc_state;
>  
> - mdp4_enable(mdp4_kms);
> -
>   /* see 119ecb7fd */
>   for_each_new_crtc_in_state(state, crtc, crtc_state, i)
>   drm_crtc_vblank_get(crtc);
> @@ -129,8 +138,6 @@ static void mdp4_complete_commit(struct msm_kms *kms, 
> unsigned crtc_mask)
>   /* see 119ecb7fd */
>   for_each_crtc_mask(mdp4_kms->dev, crtc, crtc_mask)
>   drm_crtc_vblank_put(crtc);
> -
> - mdp4_disable(mdp4_kms);
>  }
>  
>  static long mdp4_round_pixclk(struct msm_kms *kms, unsigned long rate,
> @@ -182,6 +189,8 @@ static const struct mdp_kms_funcs kms_funcs = {
>   .irq = mdp4_irq,
>   .enable_vblank   = mdp4_enable_vblank,
>   .disable_vblank  = mdp4_disable_vblank,
> + .enable_commit   = mdp4_enable_commit,
> + .disable_commit  = mdp4_disable_commit,
>   .prepar

Re: [PATCH 1/9] drm/msm/dpu: unwind async commit handling

2019-08-29 Thread Sean Paul
On Tue, Aug 27, 2019 at 02:33:31PM -0700, Rob Clark wrote:
> From: Rob Clark 
> 
> It attempted to avoid fps drops in the presence of cursor updates.  But
> it is racing, and can result in hw updates after flush before vblank,
> which leads to underruns.
> 
> Signed-off-by: Rob Clark 

Reviewed-by: Sean Paul 

> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c| 41 ++---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h|  3 +-
>  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 39 +++-
>  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h |  3 +-
>  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c |  5 +--
>  drivers/gpu/drm/msm/msm_atomic.c|  3 +-
>  6 files changed, 37 insertions(+), 57 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> index a52439e029c9..c3f7154017c4 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> @@ -610,7 +610,7 @@ static int _dpu_crtc_wait_for_frame_done(struct drm_crtc 
> *crtc)
>   return rc;
>  }
>  
> -void dpu_crtc_commit_kickoff(struct drm_crtc *crtc, bool async)
> +void dpu_crtc_commit_kickoff(struct drm_crtc *crtc)
>  {
>   struct drm_encoder *encoder;
>   struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
> @@ -636,35 +636,32 @@ void dpu_crtc_commit_kickoff(struct drm_crtc *crtc, 
> bool async)
> crtc->state->encoder_mask)
>   dpu_encoder_prepare_for_kickoff(encoder);
>  
> - if (!async) {
> - /* wait for previous frame_event_done completion */
> - DPU_ATRACE_BEGIN("wait_for_frame_done_event");
> - ret = _dpu_crtc_wait_for_frame_done(crtc);
> - DPU_ATRACE_END("wait_for_frame_done_event");
> - if (ret) {
> - DPU_ERROR("crtc%d wait for frame done 
> failed;frame_pending%d\n",
> - crtc->base.id,
> - atomic_read(_crtc->frame_pending));
> - goto end;
> - }
> + /* wait for previous frame_event_done completion */
> + DPU_ATRACE_BEGIN("wait_for_frame_done_event");
> + ret = _dpu_crtc_wait_for_frame_done(crtc);
> + DPU_ATRACE_END("wait_for_frame_done_event");
> + if (ret) {
> + DPU_ERROR("crtc%d wait for frame done failed;frame_pending%d\n",
> + crtc->base.id,
> + atomic_read(_crtc->frame_pending));
> + goto end;
> + }
>  
> - if (atomic_inc_return(_crtc->frame_pending) == 1) {
> - /* acquire bandwidth and other resources */
> - DPU_DEBUG("crtc%d first commit\n", crtc->base.id);
> - } else
> - DPU_DEBUG("crtc%d commit\n", crtc->base.id);
> + if (atomic_inc_return(_crtc->frame_pending) == 1) {
> + /* acquire bandwidth and other resources */
> + DPU_DEBUG("crtc%d first commit\n", crtc->base.id);
> + } else
> + DPU_DEBUG("crtc%d commit\n", crtc->base.id);
>  
> - dpu_crtc->play_count++;
> - }
> + dpu_crtc->play_count++;
>  
>   dpu_vbif_clear_errors(dpu_kms);
>  
>   drm_for_each_encoder_mask(encoder, crtc->dev, crtc->state->encoder_mask)
> - dpu_encoder_kickoff(encoder, async);
> + dpu_encoder_kickoff(encoder);
>  
>  end:
> - if (!async)
> - reinit_completion(_crtc->frame_done_comp);
> + reinit_completion(_crtc->frame_done_comp);
>   DPU_ATRACE_END("crtc_commit");
>  }
>  
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h 
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
> index 5181f079a6a1..10f78459f6c2 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
> @@ -238,9 +238,8 @@ void dpu_crtc_vblank_callback(struct drm_crtc *crtc);
>  /**
>   * dpu_crtc_commit_kickoff - trigger kickoff of the commit for this crtc
>   * @crtc: Pointer to drm crtc object
> - * @async: true if the commit is asynchronous, false otherwise
>   */
> -void dpu_crtc_commit_kickoff(struct drm_crtc *crtc, bool async);
> +void dpu_crtc_commit_kickoff(struct drm_crtc *crtc);
>  
>  /**
>   * dpu_crtc_complete_commit - callback signalling completion of current 
> commit
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder

Re: [PATCH] drm/modes: Fix unterminated strncpy

2019-07-30 Thread Sean Paul
On Tue, Jul 30, 2019 at 04:40:32PM +0800, Chuhong Yuan wrote:
> strncpy(dest, src, strlen(src)) leads to unterminated
> dest, which is dangerous.
> Fix it by using strscpy.
> 
> Signed-off-by: Chuhong Yuan 
> ---
>  drivers/gpu/drm/drm_modes.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
> index 80fcd5dc1558..170fc24e0f31 100644
> --- a/drivers/gpu/drm/drm_modes.c
> +++ b/drivers/gpu/drm/drm_modes.c
> @@ -1770,7 +1770,7 @@ bool drm_mode_parse_command_line_for_connector(const 
> char *mode_option,
>   }
>  
>   if (named_mode) {
> - strncpy(mode->name, name, mode_end);
> + strscpy(mode->name, name, mode_end + 1);

Shouldn't you be checking that mode_end + 1 is not > than the size of mode->name
(ie: DRM_DISPLAY_MODE_LEN)? This still seems unsafe.

Sean

>   } else {
>   ret = drm_mode_parse_cmdline_res_mode(name, mode_end,
>     parse_extras,
> -- 
> 2.20.1
> 

-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [PATCH v3 04/10] drm: Convert connector_helper_funcs->atomic_check to accept drm_atomic_state

2019-05-16 Thread Sean Paul
On Thu, May 16, 2019 at 03:00:01PM +0300, Laurent Pinchart wrote:
> Hi Sean,
> 
> On Mon, May 13, 2019 at 10:38:58AM -0400, Sean Paul wrote:
> > On Sat, May 11, 2019 at 3:12 PM Laurent Pinchart wrote:
> > > On Thu, May 02, 2019 at 03:49:46PM -0400, Sean Paul wrote:
> > >> From: Sean Paul 
> > >>
> > >> Everyone who implements connector_helper_funcs->atomic_check reaches
> > >> into the connector state to get the atomic state. Instead of continuing
> > >> this pattern, change the callback signature to just give atomic state
> > >> and let the driver determine what it does and does not need from it.
> > >>
> > >> Eventually all atomic functions should do this, but that's just too much
> > >> busy work for me.
> > >
> > > Given that drivers also access the connector state, isn't this slightly
> > > more inefficient ?
> > 
> > Inefficient in terms of what?
> 
> In terms of the operation having to lookup the connector state, when the
> caller has it and can easily pass it. As Daniel commented, this may be
> the price to pay for a cleaner API, but I wonder how much overhead all
> the state tracking is costing.
> 

It'd be interesting to quantify, but iirc the last time we benchmarked
atomic check commits they were virtually free (~thousands/s).

> > Agree that in isolation this patch might seem unnecessary, but it ties
> > in with the encoder and bridge CLs which accept drm_atomic_state in
> 
> CLs ?

Googleism for patches, I usually catch these before sending... guess I missed
one.

Sean

> 
> > their hooks. In general the idea is to convert all atomic functions to
> > take overall atomic state instead of just their object state. Reality
> > has proven to be more complicated and we need more access than what
> > the current implementation provides.
> > 
> > Sean
> > 
> > >> Changes in v3:
> > >> - Added to the set
> > >>
> > >> Cc: Daniel Vetter 
> > >> Cc: Ville Syrjälä 
> > >> Cc: Jani Nikula 
> > >> Cc: Joonas Lahtinen 
> > >> Cc: Rodrigo Vivi 
> > >> Cc: Ben Skeggs 
> > >> Cc: Laurent Pinchart 
> > >> Cc: Kieran Bingham 
> > >> Cc: Eric Anholt 
> > >> Signed-off-by: Sean Paul 
> > >> ---
> > >>  drivers/gpu/drm/drm_atomic_helper.c  |  4 ++--
> > >>  drivers/gpu/drm/i915/intel_atomic.c  |  8 +---
> > >>  drivers/gpu/drm/i915/intel_dp_mst.c  |  7 ---
> > >>  drivers/gpu/drm/i915/intel_drv.h |  2 +-
> > >>  drivers/gpu/drm/i915/intel_sdvo.c|  9 +
> > >>  drivers/gpu/drm/i915/intel_tv.c  |  8 +---
> > >>  drivers/gpu/drm/nouveau/dispnv50/disp.c  |  5 +++--
> > >>  drivers/gpu/drm/rcar-du/rcar_lvds.c  | 12 +++-
> > >>  drivers/gpu/drm/vc4/vc4_txp.c|  7 ---
> > >>  include/drm/drm_modeset_helper_vtables.h |  2 +-
> > >>  10 files changed, 37 insertions(+), 27 deletions(-)
> > >>
> > >> diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
> > >> b/drivers/gpu/drm/drm_atomic_helper.c
> > >> index 9d9e47276839..fa5a367507c1 100644
> > >> --- a/drivers/gpu/drm/drm_atomic_helper.c
> > >> +++ b/drivers/gpu/drm/drm_atomic_helper.c
> > >> @@ -683,7 +683,7 @@ drm_atomic_helper_check_modeset(struct drm_device 
> > >> *dev,
> > >>   }
> > >>
> > >>   if (funcs->atomic_check)
> > >> - ret = funcs->atomic_check(connector, 
> > >> new_connector_state);
> > >> + ret = funcs->atomic_check(connector, state);
> > >>   if (ret)
> > >>   return ret;
> > >>
> > >> @@ -725,7 +725,7 @@ drm_atomic_helper_check_modeset(struct drm_device 
> > >> *dev,
> > >>   continue;
> > >>
> > >>   if (funcs->atomic_check)
> > >> - ret = funcs->atomic_check(connector, 
> > >> new_connector_state);
> > >> + ret = funcs->atomic_check(connector, state);
> > >>   if (ret)
> > >>   return ret;
> > >>   }
> > >> diff --git a/drivers/gpu/drm/i915/intel_atomic.c 
> > >> b/drivers/gpu/drm/i915/intel_atomic.c
&

Re: [PATCH 5/5] ARM: dts: rockchip: Add HDMI i2c unwedging for rk3288-veyron

2019-05-15 Thread Sean Paul
On Thu, May 02, 2019 at 03:53:36PM -0700, Douglas Anderson wrote:
> Veyron uses the builtin i2c controller that's part of dw-hdmi.  Hook
> up the unwedging feature.
> 
> Signed-off-by: Douglas Anderson 

Reviewed-by: Sean Paul 

> ---
> 
>  arch/arm/boot/dts/rk3288-veyron.dtsi | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm/boot/dts/rk3288-veyron.dtsi 
> b/arch/arm/boot/dts/rk3288-veyron.dtsi
> index e1bee663d2c5..340b276b6333 100644
> --- a/arch/arm/boot/dts/rk3288-veyron.dtsi
> +++ b/arch/arm/boot/dts/rk3288-veyron.dtsi
> @@ -163,8 +163,9 @@
>  };
>  
>   {
> - pinctrl-names = "default";
> + pinctrl-names = "default", "unwedge";
>   pinctrl-0 = <_ddc>;
> + pinctrl-1 = <_ddc_unwedge>;
>   status = "okay";
>  };
>  
> -- 
> 2.21.0.1020.gf2820cf01a-goog
> 

-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [PATCH 4/5] ARM: dts: rockchip: Add unwedge pinctrl entries for dw_hdmi on rk3288

2019-05-15 Thread Sean Paul
On Thu, May 02, 2019 at 03:53:35PM -0700, Douglas Anderson wrote:
> This adds the "unwedge" pinctrl entries introduced by a recent dw_hdmi
> change that can unwedge the dw_hdmi i2c bus in some cases.  It's
> expected that any boards using this would add:
> 
>   pinctrl-names = "default", "unwedge";
>   pinctrl-0 = <_ddc>;
>   pinctrl-1 = <_ddc_unwedge>;
> 
> Note that this isn't added by default because some boards may choose
> to mux i2c5 for their DDC bus (if that is more tested for them).
> 
> Signed-off-by: Douglas Anderson 

Reviewed-by: Sean Paul 

> ---
> 
>  arch/arm/boot/dts/rk3288.dtsi | 9 +
>  1 file changed, 9 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi
> index 74c9517c4f92..eebc04fa1e4d 100644
> --- a/arch/arm/boot/dts/rk3288.dtsi
> +++ b/arch/arm/boot/dts/rk3288.dtsi
> @@ -1545,6 +1545,15 @@
>   rockchip,pins = <7 RK_PC3 2 _pull_none>,
>   <7 RK_PC4 2 _pull_none>;
>   };
> +
> + hdmi_ddc_unwedge: hdmi-ddc-unwedge {
> + rockchip,pins = <7 RK_PC3 RK_FUNC_GPIO 
> _output_low>,
> + <7 RK_PC4 2 _pull_none>;
> + };
> + };
> +
> + pcfg_output_low: pcfg-output-low {
> + output-low;
>   };
>  
>   pcfg_pull_up: pcfg-pull-up {
> -- 
> 2.21.0.1020.gf2820cf01a-goog
> 

-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [PATCH 3/5] ARM: dts: rockchip: Switch to builtin HDMI DDC bus on rk3288-veyron

2019-05-15 Thread Sean Paul
On Thu, May 02, 2019 at 03:53:34PM -0700, Douglas Anderson wrote:
> Downstream Chrome OS kernels use the builtin DDC bus from dw_hdmi on
> veyron.  This is the only way to get them to negotiate HDCP.
> 
> Although HDCP isn't currently all supported upstream, it still seems
> like it makes sense to use dw_hdmi's builtin I2C.  Maybe eventually we
> can get HDCP negotiation working.
> 
> Signed-off-by: Douglas Anderson 

Reviewed-by: Sean Paul 

> ---
> 
>  arch/arm/boot/dts/rk3288-veyron.dtsi | 11 ++-
>  1 file changed, 2 insertions(+), 9 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/rk3288-veyron.dtsi 
> b/arch/arm/boot/dts/rk3288-veyron.dtsi
> index 1252522392c7..e1bee663d2c5 100644
> --- a/arch/arm/boot/dts/rk3288-veyron.dtsi
> +++ b/arch/arm/boot/dts/rk3288-veyron.dtsi
> @@ -163,7 +163,8 @@
>  };
>  
>   {
> - ddc-i2c-bus = <>;
> + pinctrl-names = "default";
> + pinctrl-0 = <_ddc>;
>   status = "okay";
>  };
>  
> @@ -334,14 +335,6 @@
>   i2c-scl-rising-time-ns = <300>; /* 225ns measured */
>  };
>  
> - {
> - status = "okay";
> -
> - clock-frequency = <10>;
> - i2c-scl-falling-time-ns = <300>;
> - i2c-scl-rising-time-ns = <1000>;
> -};
> -
>  _domains {
>   status = "okay";
>  
> -- 
> 2.21.0.1020.gf2820cf01a-goog
> 

-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [PATCH 2/5] drm/msm/dpu: Integrate interconnect API in MDSS

2019-05-13 Thread Sean Paul
t;clk_config, mp->num_clk);
>   devm_kfree(>dev, mp->clk_config);
>  
> + for (i = 0; i < dpu_mdss->num_paths; i++)
> + icc_put(dpu_mdss->path[i]);
> +
>   if (dpu_mdss->mmio)
>   devm_iounmap(>dev, dpu_mdss->mmio);
>   dpu_mdss->mmio = NULL;
> @@ -211,6 +248,10 @@ int dpu_mdss_init(struct drm_device *dev)
>   }
>   dpu_mdss->mmio_len = resource_size(res);
>  
> + ret = dpu_mdss_parse_data_bus_icc_path(dev, dpu_mdss);
> + if (ret)
> + return ret;
> +
>   mp = _mdss->mp;
>   ret = msm_dss_parse_clock(pdev, mp);
>   if (ret) {
> @@ -232,14 +273,14 @@ int dpu_mdss_init(struct drm_device *dev)
>   irq_set_chained_handler_and_data(irq, dpu_mdss_irq,
>dpu_mdss);
>  
> + priv->mdss = _mdss->base;
> +
>   pm_runtime_enable(dev->dev);
>  
>   pm_runtime_get_sync(dev->dev);
>   dpu_mdss->hwversion = readl_relaxed(dpu_mdss->mmio);
>   pm_runtime_put_sync(dev->dev);
>  
> - priv->mdss = _mdss->base;
> -
>   return ret;
>  
>  irq_error:
> -- 
> 2.20.1
> 

-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [PATCH v3 04/10] drm: Convert connector_helper_funcs->atomic_check to accept drm_atomic_state

2019-05-13 Thread Sean Paul
On Sat, May 11, 2019 at 3:12 PM Laurent Pinchart
 wrote:
>
> Hi Sean,
>
> Thank you for the patch.
>

Hey Laurent,
Thanks for looking!


> On Thu, May 02, 2019 at 03:49:46PM -0400, Sean Paul wrote:
> > From: Sean Paul 
> >
> > Everyone who implements connector_helper_funcs->atomic_check reaches
> > into the connector state to get the atomic state. Instead of continuing
> > this pattern, change the callback signature to just give atomic state
> > and let the driver determine what it does and does not need from it.
> >
> > Eventually all atomic functions should do this, but that's just too much
> > busy work for me.
>
> Given that drivers also access the connector state, isn't this slightly
> more inefficient ?
>

Inefficient in terms of what?

Agree that in isolation this patch might seem unnecessary, but it ties
in with the encoder and bridge CLs which accept drm_atomic_state in
their hooks. In general the idea is to convert all atomic functions to
take overall atomic state instead of just their object state. Reality
has proven to be more complicated and we need more access than what
the current implementation provides.

Sean

> > Changes in v3:
> > - Added to the set
> >
> > Cc: Daniel Vetter 
> > Cc: Ville Syrjälä 
> > Cc: Jani Nikula 
> > Cc: Joonas Lahtinen 
> > Cc: Rodrigo Vivi 
> > Cc: Ben Skeggs 
> > Cc: Laurent Pinchart 
> > Cc: Kieran Bingham 
> > Cc: Eric Anholt 
> > Signed-off-by: Sean Paul 
> > ---
> >  drivers/gpu/drm/drm_atomic_helper.c  |  4 ++--
> >  drivers/gpu/drm/i915/intel_atomic.c  |  8 +---
> >  drivers/gpu/drm/i915/intel_dp_mst.c  |  7 ---
> >  drivers/gpu/drm/i915/intel_drv.h |  2 +-
> >  drivers/gpu/drm/i915/intel_sdvo.c|  9 +
> >  drivers/gpu/drm/i915/intel_tv.c  |  8 +---
> >  drivers/gpu/drm/nouveau/dispnv50/disp.c  |  5 +++--
> >  drivers/gpu/drm/rcar-du/rcar_lvds.c  | 12 +++-
> >  drivers/gpu/drm/vc4/vc4_txp.c|  7 ---
> >  include/drm/drm_modeset_helper_vtables.h |  2 +-
> >  10 files changed, 37 insertions(+), 27 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
> > b/drivers/gpu/drm/drm_atomic_helper.c
> > index 9d9e47276839..fa5a367507c1 100644
> > --- a/drivers/gpu/drm/drm_atomic_helper.c
> > +++ b/drivers/gpu/drm/drm_atomic_helper.c
> > @@ -683,7 +683,7 @@ drm_atomic_helper_check_modeset(struct drm_device *dev,
> >   }
> >
> >   if (funcs->atomic_check)
> > - ret = funcs->atomic_check(connector, 
> > new_connector_state);
> > + ret = funcs->atomic_check(connector, state);
> >   if (ret)
> >   return ret;
> >
> > @@ -725,7 +725,7 @@ drm_atomic_helper_check_modeset(struct drm_device *dev,
> >   continue;
> >
> >   if (funcs->atomic_check)
> > - ret = funcs->atomic_check(connector, 
> > new_connector_state);
> > + ret = funcs->atomic_check(connector, state);
> >   if (ret)
> >   return ret;
> >   }
> > diff --git a/drivers/gpu/drm/i915/intel_atomic.c 
> > b/drivers/gpu/drm/i915/intel_atomic.c
> > index b844e8840c6f..e8a5b82e9242 100644
> > --- a/drivers/gpu/drm/i915/intel_atomic.c
> > +++ b/drivers/gpu/drm/i915/intel_atomic.c
> > @@ -103,12 +103,14 @@ int 
> > intel_digital_connector_atomic_set_property(struct drm_connector *connector,
> >  }
> >
> >  int intel_digital_connector_atomic_check(struct drm_connector *conn,
> > -  struct drm_connector_state 
> > *new_state)
> > +  struct drm_atomic_state *state)
> >  {
> > + struct drm_connector_state *new_state =
> > + drm_atomic_get_new_connector_state(state, conn);
> >   struct intel_digital_connector_state *new_conn_state =
> >   to_intel_digital_connector_state(new_state);
> >   struct drm_connector_state *old_state =
> > - drm_atomic_get_old_connector_state(new_state->state, conn);
> > + drm_atomic_get_old_connector_state(state, conn);
> >   struct intel_digital_connector_state *old_conn_state =
> >   to_intel_digital_connector_state(old_state);
> >   struct drm_crtc_state *crtc_state;
> > @@ -118,7 +120,7 @@ int intel_digital_connector_atomic_check(struct 
> > drm_connector *conn,
> >   if (!n

Re: [PATCH] drm/msm/a6xx: No zap shader is not an error

2019-05-08 Thread Sean Paul
On Wed, May 08, 2019 at 06:06:52AM -0700, Rob Clark wrote:
> From: Rob Clark 
> 
> Depending on platform firmware, a zap shader may not be required to take
> the GPU out of secure mode on boot, in which case we can just write
> RBBM_SECVID_TRUST_CNTL directly.  Which we *mostly* handled, but missed
> clearing 'ret' resulting that hw_init() returned an error on these
> devices.
> 
> Fixes: abccb9fe3267 drm/msm/a6xx: Add zap shader load
> Signed-off-by: Rob Clark 

Reviewed-by: Sean Paul 

> ---
>  drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c 
> b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> index ec24508b9d68..e74dce474250 100644
> --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> @@ -527,6 +527,7 @@ static int a6xx_hw_init(struct msm_gpu *gpu)
>   dev_warn_once(gpu->dev->dev,
>   "Zap shader not enabled - using SECVID_TRUST_CNTL 
> instead\n");
>   gpu_write(gpu, REG_A6XX_RBBM_SECVID_TRUST_CNTL, 0x0);
> + ret = 0;
>   }
>  
>  out:
> -- 
> 2.20.1
> 

-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [PATCH v3 5/5] drm: don't block fb changes for async plane updates

2019-05-07 Thread Sean Paul
plane_state->fb;
> + struct drm_framebuffer *old_fb = plane->state->fb;
> +
>   funcs = plane->helper_private;
>   funcs->atomic_async_update(plane, plane_state);
>  
> @@ -1665,11 +1661,17 @@ void drm_atomic_helper_async_commit(struct drm_device 
> *dev,
>* plane->state in-place, make sure at least common
>* properties have been properly updated.
>*/
> - WARN_ON_ONCE(plane->state->fb != plane_state->fb);
> + WARN_ON_ONCE(plane->state->fb != new_fb);
>   WARN_ON_ONCE(plane->state->crtc_x != plane_state->crtc_x);
>   WARN_ON_ONCE(plane->state->crtc_y != plane_state->crtc_y);
>   WARN_ON_ONCE(plane->state->src_x != plane_state->src_x);
>   WARN_ON_ONCE(plane->state->src_y != plane_state->src_y);
> +
> + /*
> +  * Make sure the FBs have been swapped so that cleanups in the
> +  * new_state performs a cleanup in the old FB.
> +  */
> + WARN_ON_ONCE(plane_state->fb != old_fb);
>   }
>  }
>  EXPORT_SYMBOL(drm_atomic_helper_async_commit);
> diff --git a/include/drm/drm_modeset_helper_vtables.h 
> b/include/drm/drm_modeset_helper_vtables.h
> index cfb7be40bed7..ce582e8e8f2f 100644
> --- a/include/drm/drm_modeset_helper_vtables.h
> +++ b/include/drm/drm_modeset_helper_vtables.h
> @@ -1174,6 +1174,11 @@ struct drm_plane_helper_funcs {
>* current one with the new plane configurations in the new
>* plane_state.
>*
> +  * Drivers should also swap the framebuffers between plane state

Perhaps add "current" before plane state and then after add "(_plane.state)"
so it's more clear what you're referring to here?

> +  * and new_state. This is required because prepare and cleanup calls
> +  * are performed on the new_state object, then to cleanup the old
> +  * framebuffer, it needs to be placed inside the new_state object.

I'd change this bit to:

* This is required since cleanup for async commits is performed on
* the new state, rather than old state like for traditional commits.
* Since we want to give up the reference on the current (old) fb instead
* of our brand new one, swap them in the driver during the async commit.

> +  *
>* FIXME:
>*  - It only works for single plane updates
>*  - Async Pageflips are not supported yet
> -- 
> 2.20.1
> 

-- 
Sean Paul, Software Engineer, Google / Chromium OS


[PATCH v3 05/10] drm: Add helpers to kick off self refresh mode in drivers

2019-05-02 Thread Sean Paul
From: Sean Paul 

This patch adds a new drm helper library to help drivers implement
self refresh. Drivers choosing to use it will register crtcs and
will receive callbacks when it's time to enter or exit self refresh
mode.

In its current form, it has a timer which will trigger after a
driver-specified amount of inactivity. When the timer triggers, the
helpers will submit a new atomic commit to shut the refreshing pipe
off. On the next atomic commit, the drm core will revert the self
refresh state and bring everything back up to be actively driven.

>From the driver's perspective, this works like a regular disable/enable
cycle. The driver need only check the 'self_refresh_active' state in
crtc_state. It should initiate self refresh mode on the panel and enter
an off or low-power state.

Changes in v2:
- s/psr/self_refresh/ (Daniel)
- integrated the psr exit into the commit that wakes it up (Jose/Daniel)
- made the psr state per-crtc (Jose/Daniel)
Changes in v3:
- Remove the self_refresh_(active|changed) from connector state (Daniel)
- Simplify loop in drm_self_refresh_helper_alter_state (Daniel)
- Improve self_refresh_aware comment (Daniel)
- s/self_refresh_state/self_refresh_data/ (Daniel)

Link to v1: 
https://patchwork.freedesktop.org/patch/msgid/20190228210939.83386-2-s...@poorly.run
Link to v2: 
https://patchwork.freedesktop.org/patch/msgid/20190326204509.96515-1-s...@poorly.run

Cc: Daniel Vetter 
Cc: Jose Souza 
Cc: Zain Wang 
Cc: Tomasz Figa 
Cc: Ville Syrjälä 
Signed-off-by: Sean Paul 
---
 Documentation/gpu/drm-kms-helpers.rst |   9 +
 drivers/gpu/drm/Makefile  |   2 +-
 drivers/gpu/drm/drm_atomic.c  |   2 +
 drivers/gpu/drm/drm_atomic_helper.c   |  35 +++-
 drivers/gpu/drm/drm_atomic_state_helper.c |   4 +
 drivers/gpu/drm/drm_atomic_uapi.c |   7 +-
 drivers/gpu/drm/drm_self_refresh_helper.c | 205 ++
 include/drm/drm_atomic.h  |  15 ++
 include/drm/drm_connector.h   |  14 ++
 include/drm/drm_crtc.h|  19 ++
 include/drm/drm_self_refresh_helper.h |  22 +++
 11 files changed, 329 insertions(+), 5 deletions(-)
 create mode 100644 drivers/gpu/drm/drm_self_refresh_helper.c
 create mode 100644 include/drm/drm_self_refresh_helper.h

diff --git a/Documentation/gpu/drm-kms-helpers.rst 
b/Documentation/gpu/drm-kms-helpers.rst
index 14102ae035dc..d8a13c6b4db3 100644
--- a/Documentation/gpu/drm-kms-helpers.rst
+++ b/Documentation/gpu/drm-kms-helpers.rst
@@ -113,6 +113,15 @@ format Helper Functions Reference
 .. kernel-doc:: drivers/gpu/drm/drm_format_helper.c
:export:
 
+Panel Self Refresh Helper Reference
+===
+
+.. kernel-doc:: drivers/gpu/drm/drm_self_refresh_helper.c
+   :doc: overview
+
+.. kernel-doc:: drivers/gpu/drm/drm_self_refresh_helper.c
+   :export:
+
 Framebuffer CMA Helper Functions Reference
 ==
 
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 3d0c75cd687c..c4852604fc1d 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -39,7 +39,7 @@ drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o 
drm_dsc.o drm_probe_helper
drm_simple_kms_helper.o drm_modeset_helper.o \
drm_scdc_helper.o drm_gem_framebuffer_helper.o \
drm_atomic_state_helper.o drm_damage_helper.o \
-   drm_format_helper.o
+   drm_format_helper.o drm_self_refresh_helper.o
 
 drm_kms_helper-$(CONFIG_DRM_PANEL_BRIDGE) += bridge/panel.o
 drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 5eb40130fafb..4449956241f2 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -379,6 +379,7 @@ static void drm_atomic_crtc_print_state(struct drm_printer 
*p,
drm_printf(p, "crtc[%u]: %s\n", crtc->base.id, crtc->name);
drm_printf(p, "\tenable=%d\n", state->enable);
drm_printf(p, "\tactive=%d\n", state->active);
+   drm_printf(p, "\tself_refresh_active=%d\n", state->self_refresh_active);
drm_printf(p, "\tplanes_changed=%d\n", state->planes_changed);
drm_printf(p, "\tmode_changed=%d\n", state->mode_changed);
drm_printf(p, "\tactive_changed=%d\n", state->active_changed);
@@ -881,6 +882,7 @@ static void drm_atomic_connector_print_state(struct 
drm_printer *p,
 
drm_printf(p, "connector[%u]: %s\n", connector->base.id, 
connector->name);
drm_printf(p, "\tcrtc=%s\n", state->crtc ? state->crtc->name : 
"(null)");
+   drm_printf(p, "\tself_refresh_aware=%d\n", state->self_refresh_aware);
 
if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
if (state->writeback_job &&

[PATCH v3 01/10] drm: Add atomic variants of enable/disable to encoder helper funcs

2019-05-02 Thread Sean Paul
From: Sean Paul 

This patch adds atomic_enable and atomic_disable callbacks to the
encoder helpers. This will allow encoders to make informed decisions in
their start-up/shutdown based on the committed state.

Aside from the new hooks, this patch also introduces the new signature
for .atomic_* functions going forward. Instead of passing object state
(well, encoders don't have atomic state, but let's ignore that), we pass
the entire atomic state so the driver can inspect more than what's
happening locally.

This is particularly important for the upcoming self refresh helpers.

Changes in v3:
- Added patch to the set

Cc: Daniel Vetter 
Cc: Ville Syrjälä 
Signed-off-by: Sean Paul 
---
 drivers/gpu/drm/drm_atomic_helper.c  |  6 +++-
 include/drm/drm_modeset_helper_vtables.h | 45 
 2 files changed, 50 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
b/drivers/gpu/drm/drm_atomic_helper.c
index 553415fe8ede..71cc7d6b0644 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -1001,6 +1001,8 @@ disable_outputs(struct drm_device *dev, struct 
drm_atomic_state *old_state)
if (funcs) {
if (new_conn_state->crtc && funcs->prepare)
funcs->prepare(encoder);
+   else if (funcs->atomic_disable)
+   funcs->atomic_disable(encoder, old_state);
else if (funcs->disable)
funcs->disable(encoder);
else if (funcs->dpms)
@@ -1309,7 +1311,9 @@ void drm_atomic_helper_commit_modeset_enables(struct 
drm_device *dev,
drm_bridge_pre_enable(encoder->bridge);
 
if (funcs) {
-   if (funcs->enable)
+   if (funcs->atomic_enable)
+   funcs->atomic_enable(encoder, old_state);
+   else if (funcs->enable)
funcs->enable(encoder);
else if (funcs->commit)
funcs->commit(encoder);
diff --git a/include/drm/drm_modeset_helper_vtables.h 
b/include/drm/drm_modeset_helper_vtables.h
index 8f3602811eb5..de57fb40cb6e 100644
--- a/include/drm/drm_modeset_helper_vtables.h
+++ b/include/drm/drm_modeset_helper_vtables.h
@@ -675,6 +675,51 @@ struct drm_encoder_helper_funcs {
enum drm_connector_status (*detect)(struct drm_encoder *encoder,
struct drm_connector *connector);
 
+   /**
+* @atomic_disable:
+*
+* This callback should be used to disable the encoder. With the atomic
+* drivers it is called before this encoder's CRTC has been shut off
+* using their own _crtc_helper_funcs.atomic_disable hook. If that
+* sequence is too simple drivers can just add their own driver private
+* encoder hooks and call them from CRTC's callback by looping over all
+* encoders connected to it using for_each_encoder_on_crtc().
+*
+* This callback is a variant of @disable that provides the atomic state
+* to the driver. It takes priority over @disable during atomic commits.
+*
+* This hook is used only by atomic helpers. Atomic drivers don't need
+* to implement it if there's no need to disable anything at the encoder
+* level. To ensure that runtime PM handling (using either DPMS or the
+* new "ACTIVE" property) works @atomic_disable must be the inverse of
+* @atomic_enable.
+*/
+   void (*atomic_disable)(struct drm_encoder *encoder,
+  struct drm_atomic_state *state);
+
+   /**
+* @atomic_enable:
+*
+* This callback should be used to enable the encoder. It is called
+* after this encoder's CRTC has been enabled using their own
+* _crtc_helper_funcs.atomic_enable hook. If that sequence is
+* too simple drivers can just add their own driver private encoder
+* hooks and call them from CRTC's callback by looping over all encoders
+* connected to it using for_each_encoder_on_crtc().
+*
+* This callback is a variant of @enable that provides the atomic state
+* to the driver. It is called in place of @enable during atomic
+* commits.
+*
+* This hook is used only by atomic helpers, for symmetry with @disable.
+* Atomic drivers don't need to implement it if there's no need to
+* enable anything at the encoder level. To ensure that runtime PM
+* handling (using either DPMS or the new "ACTIVE" property) works
+* @enable must be the inverse of @disable for atomic drivers.
+*/
+   void (*atomic_enable)(struct drm_en

[PATCH v3 03/10] drm: Add atomic variants for bridge enable/disable

2019-05-02 Thread Sean Paul
From: Sean Paul 

This patch adds atomic variants for all of
pre_enable/enable/disable/post_disable bridge functions. These will be
called from the appropriate atomic helper functions. If the bridge
driver doesn't implement the atomic version of the function, we will
fall back to the vanilla implementation.

Note that some drivers call drm_bridge_disable directly, and these cases
are not covered. It's up to the driver to decide whether to implement
both atomic_disable and disable, or if it's not necessary.

Changes in v3:
- Added to the patchset

Cc: Daniel Vetter 
Cc: Ville Syrjälä 
Signed-off-by: Sean Paul 
---
 drivers/gpu/drm/drm_atomic_helper.c |   8 +-
 drivers/gpu/drm/drm_bridge.c| 110 +++
 include/drm/drm_bridge.h| 114 
 3 files changed, 228 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
b/drivers/gpu/drm/drm_atomic_helper.c
index 1f81ca8daad7..9d9e47276839 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -995,7 +995,7 @@ disable_outputs(struct drm_device *dev, struct 
drm_atomic_state *old_state)
 * Each encoder has at most one connector (since we always steal
 * it away), so we won't call disable hooks twice.
 */
-   drm_bridge_disable(encoder->bridge);
+   drm_atomic_bridge_disable(encoder->bridge, old_state);
 
/* Right function depends upon target state. */
if (funcs) {
@@ -1009,7 +1009,7 @@ disable_outputs(struct drm_device *dev, struct 
drm_atomic_state *old_state)
funcs->dpms(encoder, DRM_MODE_DPMS_OFF);
}
 
-   drm_bridge_post_disable(encoder->bridge);
+   drm_atomic_bridge_post_disable(encoder->bridge, old_state);
}
 
for_each_oldnew_crtc_in_state(old_state, crtc, old_crtc_state, 
new_crtc_state, i) {
@@ -1308,7 +1308,7 @@ void drm_atomic_helper_commit_modeset_enables(struct 
drm_device *dev,
 * Each encoder has at most one connector (since we always steal
 * it away), so we won't call enable hooks twice.
 */
-   drm_bridge_pre_enable(encoder->bridge);
+   drm_atomic_bridge_pre_enable(encoder->bridge, old_state);
 
if (funcs) {
if (funcs->atomic_enable)
@@ -1319,7 +1319,7 @@ void drm_atomic_helper_commit_modeset_enables(struct 
drm_device *dev,
funcs->commit(encoder);
}
 
-   drm_bridge_enable(encoder->bridge);
+   drm_atomic_bridge_enable(encoder->bridge, old_state);
}
 
drm_atomic_helper_commit_writebacks(dev, old_state);
diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
index 138b2711d389..ab586adf 100644
--- a/drivers/gpu/drm/drm_bridge.c
+++ b/drivers/gpu/drm/drm_bridge.c
@@ -352,6 +352,116 @@ void drm_bridge_enable(struct drm_bridge *bridge)
 }
 EXPORT_SYMBOL(drm_bridge_enable);
 
+/**
+ * drm_atomic_bridge_disable - disables all bridges in the encoder chain
+ * @bridge: bridge control structure
+ * @state: atomic state being committed
+ *
+ * Calls _bridge_funcs.atomic_disable (falls back on
+ * _bridge_funcs.disable) op for all the bridges in the encoder chain,
+ * starting from the last bridge to the first. These are called before calling
+ * the encoder's prepare op.
+ *
+ * Note: the bridge passed should be the one closest to the encoder
+ */
+void drm_atomic_bridge_disable(struct drm_bridge *bridge,
+  struct drm_atomic_state *state)
+{
+   if (!bridge)
+   return;
+
+   drm_atomic_bridge_disable(bridge->next, state);
+
+   if (bridge->funcs->atomic_disable)
+   bridge->funcs->atomic_disable(bridge, state);
+   else if (bridge->funcs->disable)
+   bridge->funcs->disable(bridge);
+}
+EXPORT_SYMBOL(drm_atomic_bridge_disable);
+
+/**
+ * drm_atomic_bridge_post_disable - cleans up after disabling all bridges in 
the
+ * encoder chain
+ * @bridge: bridge control structure
+ * @state: atomic state being committed
+ *
+ * Calls _bridge_funcs.atomic_post_disable (falls back on
+ * _bridge_funcs.post_disable) op for all the bridges in the encoder chain,
+ * starting from the first bridge to the last. These are called after 
completing
+ * the encoder's prepare op.
+ *
+ * Note: the bridge passed should be the one closest to the encoder
+ */
+void drm_atomic_bridge_post_disable(struct drm_bridge *bridge,
+   struct drm_atomic_state *state)
+{
+   if (!bridge)
+   return;
+
+   if (bridge->funcs->atomic_post_disable)
+   bridge->funcs->atomic_post_disable(bridge, state);
+  

[PATCH v3 10/10] drm/rockchip: Use drm_atomic_helper_commit_tail_rpm

2019-05-02 Thread Sean Paul
From: Sean Paul 

Now that we use the drm psr helpers, we no longer need to hand-roll our
atomic_commit_tail implementation. So use the helper

Changes in v2:
- None
Changes in v3:
- None

Link to v1: 
https://patchwork.freedesktop.org/patch/msgid/20190228210939.83386-6-s...@poorly.run
Link to v2: 
https://patchwork.freedesktop.org/patch/msgid/20190326204509.96515-5-s...@poorly.run

Cc: Zain Wang 
Cc: Tomasz Figa 
Signed-off-by: Sean Paul 
---
 drivers/gpu/drm/rockchip/rockchip_drm_fb.c | 21 +
 1 file changed, 1 insertion(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
index 214064d599ee..1c63d9e833bc 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
@@ -117,27 +117,8 @@ rockchip_user_fb_create(struct drm_device *dev, struct 
drm_file *file_priv,
return ERR_PTR(ret);
 }
 
-static void
-rockchip_atomic_helper_commit_tail_rpm(struct drm_atomic_state *old_state)
-{
-   struct drm_device *dev = old_state->dev;
-
-   drm_atomic_helper_commit_modeset_disables(dev, old_state);
-
-   drm_atomic_helper_commit_modeset_enables(dev, old_state);
-
-   drm_atomic_helper_commit_planes(dev, old_state,
-   DRM_PLANE_COMMIT_ACTIVE_ONLY);
-
-   drm_atomic_helper_commit_hw_done(old_state);
-
-   drm_atomic_helper_wait_for_vblanks(dev, old_state);
-
-   drm_atomic_helper_cleanup_planes(dev, old_state);
-}
-
 static const struct drm_mode_config_helper_funcs rockchip_mode_config_helpers 
= {
-   .atomic_commit_tail = rockchip_atomic_helper_commit_tail_rpm,
+   .atomic_commit_tail = drm_atomic_helper_commit_tail_rpm,
 };
 
 static const struct drm_mode_config_funcs rockchip_drm_mode_config_funcs = {
-- 
Sean Paul, Software Engineer, Google / Chromium OS



[PATCH v3 08/10] drm/rockchip: Use the helpers for PSR

2019-05-02 Thread Sean Paul
From: Sean Paul 

Instead of rolling our own implementation for tracking when PSR should
be [in]active, use the new self refresh helpers to do the heavy lifting.

Changes in v2:
- updated to reflect changes made in the helpers
Changes in v3:
- use the new atomic hooks to inspect crtc state instead of needing conn state 
(Daniel)

Link to v1: 
https://patchwork.freedesktop.org/patch/msgid/20190228210939.83386-4-s...@poorly.run
Link to v2: 
https://patchwork.freedesktop.org/patch/msgid/20190326204509.96515-3-s...@poorly.run

Cc: Zain Wang 
Cc: Tomasz Figa 
Signed-off-by: Sean Paul 
---
 .../drm/bridge/analogix/analogix_dp_core.c| 265 +++-
 .../drm/bridge/analogix/analogix_dp_core.h|   2 +-
 drivers/gpu/drm/rockchip/Makefile |   3 +-
 .../gpu/drm/rockchip/analogix_dp-rockchip.c   |  86 +++---
 drivers/gpu/drm/rockchip/rockchip_drm_fb.c|   5 -
 drivers/gpu/drm/rockchip/rockchip_drm_psr.c   | 290 --
 drivers/gpu/drm/rockchip/rockchip_drm_psr.h   |  30 --
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c   |  33 +-
 include/drm/bridge/analogix_dp.h  |   4 -
 9 files changed, 243 insertions(+), 475 deletions(-)
 delete mode 100644 drivers/gpu/drm/rockchip/rockchip_drm_psr.c
 delete mode 100644 drivers/gpu/drm/rockchip/rockchip_drm_psr.h

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index af34554a5a02..e66c105c3b68 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -24,6 +24,7 @@
 #include 
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -106,63 +107,7 @@ static int analogix_dp_detect_hpd(struct 
analogix_dp_device *dp)
return 0;
 }
 
-int analogix_dp_psr_enabled(struct analogix_dp_device *dp)
-{
-
-   return dp->psr_enable;
-}
-EXPORT_SYMBOL_GPL(analogix_dp_psr_enabled);
-
-int analogix_dp_enable_psr(struct analogix_dp_device *dp)
-{
-   struct edp_vsc_psr psr_vsc;
-
-   if (!dp->psr_enable)
-   return 0;
-
-   /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */
-   memset(_vsc, 0, sizeof(psr_vsc));
-   psr_vsc.sdp_header.HB0 = 0;
-   psr_vsc.sdp_header.HB1 = 0x7;
-   psr_vsc.sdp_header.HB2 = 0x2;
-   psr_vsc.sdp_header.HB3 = 0x8;
-
-   psr_vsc.DB0 = 0;
-   psr_vsc.DB1 = EDP_VSC_PSR_STATE_ACTIVE | EDP_VSC_PSR_CRC_VALUES_VALID;
-
-   return analogix_dp_send_psr_spd(dp, _vsc, true);
-}
-EXPORT_SYMBOL_GPL(analogix_dp_enable_psr);
-
-int analogix_dp_disable_psr(struct analogix_dp_device *dp)
-{
-   struct edp_vsc_psr psr_vsc;
-   int ret;
-
-   if (!dp->psr_enable)
-   return 0;
-
-   /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */
-   memset(_vsc, 0, sizeof(psr_vsc));
-   psr_vsc.sdp_header.HB0 = 0;
-   psr_vsc.sdp_header.HB1 = 0x7;
-   psr_vsc.sdp_header.HB2 = 0x2;
-   psr_vsc.sdp_header.HB3 = 0x8;
-
-   psr_vsc.DB0 = 0;
-   psr_vsc.DB1 = 0;
-
-   ret = drm_dp_dpcd_writeb(>aux, DP_SET_POWER, DP_SET_POWER_D0);
-   if (ret != 1) {
-   dev_err(dp->dev, "Failed to set DP Power0 %d\n", ret);
-   return ret;
-   }
-
-   return analogix_dp_send_psr_spd(dp, _vsc, false);
-}
-EXPORT_SYMBOL_GPL(analogix_dp_disable_psr);
-
-static int analogix_dp_detect_sink_psr(struct analogix_dp_device *dp)
+static bool analogix_dp_detect_sink_psr(struct analogix_dp_device *dp)
 {
unsigned char psr_version;
int ret;
@@ -170,14 +115,11 @@ static int analogix_dp_detect_sink_psr(struct 
analogix_dp_device *dp)
ret = drm_dp_dpcd_readb(>aux, DP_PSR_SUPPORT, _version);
if (ret != 1) {
dev_err(dp->dev, "failed to get PSR version, disable it\n");
-   return ret;
+   return false;
}
 
dev_dbg(dp->dev, "Panel PSR version : %x\n", psr_version);
-
-   dp->psr_enable = (psr_version & DP_PSR_IS_SUPPORTED) ? true : false;
-
-   return 0;
+   return psr_version & DP_PSR_IS_SUPPORTED;
 }
 
 static int analogix_dp_enable_sink_psr(struct analogix_dp_device *dp)
@@ -200,7 +142,7 @@ static int analogix_dp_enable_sink_psr(struct 
analogix_dp_device *dp)
}
 
/* Main-Link transmitter remains active during PSR active states */
-   psr_en = DP_PSR_MAIN_LINK_ACTIVE | DP_PSR_CRC_VERIFICATION;
+   psr_en = DP_PSR_CRC_VERIFICATION;
ret = drm_dp_dpcd_writeb(>aux, DP_PSR_EN_CFG, psr_en);
if (ret != 1) {
dev_err(dp->dev, "failed to set panel psr\n");
@@ -208,8 +150,7 @@ static int analogix_dp_enable_sink_psr(struct 
analogix_dp_device *dp)
}
 
/* Enable psr function */
-   psr_en = DP_PSR_ENABLE | DP_PSR_MAIN_LINK_ACTIVE |
-DP_PSR_CRC_VERIFICATION;
+   psr_en = DP_PSR_ENABLE | DP_PSR_CRC_VERIFICATION;
  

[PATCH v3 09/10] drm/rockchip: Don't fully disable vop on self refresh

2019-05-02 Thread Sean Paul
From: Sean Paul 

Instead of fully disabling and re-enabling the vop on self refresh
transitions, only disable the active windows. This will speed up
self refresh exits substantially and is still a power-savings win.

This patch integrates portions of Zain's patch from here:
https://patchwork.kernel.org/patch/9615063/

Changes in v2:
- None
Changes in v3:
- None

Link to v1: 
https://patchwork.freedesktop.org/patch/msgid/20190228210939.83386-5-s...@poorly.run
Link to v2: 
https://patchwork.freedesktop.org/patch/msgid/20190326204509.96515-4-s...@poorly.run

Cc: Zain Wang 
Cc: Tomasz Figa 
Cc: Kristian H. Kristensen 
Signed-off-by: Sean Paul 
---
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 38 +
 1 file changed, 38 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 45a38a332827..d171d90418c8 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -134,6 +134,7 @@ struct vop {
bool is_enabled;
 
struct completion dsp_hold_completion;
+   unsigned int win_enabled;
 
/* protected by dev->event_lock */
struct drm_pending_vblank_event *event;
@@ -594,6 +595,7 @@ static int vop_enable(struct drm_crtc *crtc, struct 
drm_crtc_state *old_state)
const struct vop_win_data *win = vop_win->data;
 
VOP_WIN_SET(vop, win, enable, 0);
+   vop->win_enabled &= ~BIT(i);
}
}
spin_unlock(>reg_lock);
@@ -624,6 +626,25 @@ static int vop_enable(struct drm_crtc *crtc, struct 
drm_crtc_state *old_state)
return ret;
 }
 
+static void rockchip_drm_set_win_enabled(struct drm_crtc *crtc, bool enabled)
+{
+struct vop *vop = to_vop(crtc);
+int i;
+
+spin_lock(>reg_lock);
+
+for (i = 0; i < vop->data->win_size; i++) {
+struct vop_win *vop_win = >win[i];
+const struct vop_win_data *win = vop_win->data;
+
+VOP_WIN_SET(vop, win, enable,
+enabled && (vop->win_enabled & BIT(i)));
+}
+vop_cfg_done(vop);
+
+spin_unlock(>reg_lock);
+}
+
 static void vop_crtc_atomic_disable(struct drm_crtc *crtc,
struct drm_crtc_state *old_state)
 {
@@ -631,9 +652,15 @@ static void vop_crtc_atomic_disable(struct drm_crtc *crtc,
 
WARN_ON(vop->event);
 
+   if (crtc->state->self_refresh_active)
+   rockchip_drm_set_win_enabled(crtc, false);
+
mutex_lock(>vop_lock);
drm_crtc_vblank_off(crtc);
 
+   if (crtc->state->self_refresh_active)
+   goto out;
+
/*
 * Vop standby will take effect at end of current frame,
 * if dsp hold valid irq happen, it means standby complete.
@@ -664,6 +691,8 @@ static void vop_crtc_atomic_disable(struct drm_crtc *crtc,
clk_disable(vop->dclk);
vop_core_clks_disable(vop);
pm_runtime_put(vop->dev);
+
+out:
mutex_unlock(>vop_lock);
 
if (crtc->state->event && !crtc->state->active) {
@@ -744,6 +773,7 @@ static void vop_plane_atomic_disable(struct drm_plane 
*plane,
spin_lock(>reg_lock);
 
VOP_WIN_SET(vop, win, enable, 0);
+   vop->win_enabled &= ~BIT(VOP_WIN_TO_INDEX(vop_win));
 
spin_unlock(>reg_lock);
 }
@@ -882,6 +912,7 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
}
 
VOP_WIN_SET(vop, win, enable, 1);
+   vop->win_enabled |= BIT(win_index);
spin_unlock(>reg_lock);
 }
 
@@ -1038,6 +1069,12 @@ static void vop_crtc_atomic_enable(struct drm_crtc *crtc,
int dither_bpc = s->output_bpc ? s->output_bpc : 10;
int ret;
 
+   if (old_state && old_state->self_refresh_active) {
+   drm_crtc_vblank_on(crtc);
+   rockchip_drm_set_win_enabled(crtc, true);
+   return;
+   }
+
mutex_lock(>vop_lock);
 
WARN_ON(vop->event);
@@ -1648,6 +1685,7 @@ static int vop_initial(struct vop *vop)
VOP_WIN_SET(vop, win, channel, (channel + 1) << 4 | channel);
VOP_WIN_SET(vop, win, enable, 0);
VOP_WIN_SET(vop, win, gate, 1);
+   vop->win_enabled &= ~BIT(i);
}
 
vop_cfg_done(vop);
-- 
Sean Paul, Software Engineer, Google / Chromium OS



Re: [PATCH RESEND] drm/msm: Truncate the buffer object name if the copy from user failed

2019-03-04 Thread Sean Paul
On Tue, Feb 19, 2019 at 11:40:19AM -0700, Jordan Crouse wrote:
> (Resend since there was a compile error that I forgot to commit before 
> sending)
> 
> If there is a error while doing a copy_from_user() for MSM_INFO_SET_NAME
> make sure to truncate the object name so that there isn't a chance that
> we'll have random data in the string.
> 
> This is on top of [1] reported and fixed by Dan Carpenter.
> 
> [1] https://patchwork.freedesktop.org/series/56656/
> 
> Fixes: f05c83e77460 ("drm/msm: add uapi to get/set debug name")
> Reported-by: Dan Carpenter 
> Signed-off-by: Jordan Crouse 

Reviewed-by: Sean Paul 

> ---
> 
>  drivers/gpu/drm/msm/msm_drv.c | 5 -
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
> index 87eae44..906b2bb 100644
> --- a/drivers/gpu/drm/msm/msm_drv.c
> +++ b/drivers/gpu/drm/msm/msm_drv.c
> @@ -852,8 +852,11 @@ static int msm_ioctl_gem_info(struct drm_device *dev, 
> void *data,
>   break;
>   }
>   if (copy_from_user(msm_obj->name, u64_to_user_ptr(args->value),
> -args->len))
> +args->len)) {
> + msm_obj->name[0] = '\0';
>   ret = -EFAULT;
> + break;
> + }
>   msm_obj->name[args->len] = '\0';
>   for (i = 0; i < args->len; i++) {
>   if (!isprint(msm_obj->name[i])) {
> -- 
> 2.7.4
> 

-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [PATCH] drm: fix spelling mistake "intead" -> "instead"

2019-03-04 Thread Sean Paul
On Sun, Feb 17, 2019 at 10:55:54PM +, Colin King wrote:
> From: Colin Ian King 
> 
> There is a spelling mistake in a DRM_NOTE message. Fix this.
> 
> Signed-off-by: Colin Ian King 

Applied to drm-misc-next, thanks.

Sean

> ---
>  drivers/gpu/drm/drm_kms_helper_common.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/drm_kms_helper_common.c 
> b/drivers/gpu/drm/drm_kms_helper_common.c
> index 93e2b30fe1a5..9c5ae825c507 100644
> --- a/drivers/gpu/drm/drm_kms_helper_common.c
> +++ b/drivers/gpu/drm/drm_kms_helper_common.c
> @@ -39,7 +39,7 @@ MODULE_LICENSE("GPL and additional rights");
>  /* Backward compatibility for drm_kms_helper.edid_firmware */
>  static int edid_firmware_set(const char *val, const struct kernel_param *kp)
>  {
> - DRM_NOTE("drm_kms_firmware.edid_firmware is deprecated, please use 
> drm.edid_firmware intead.\n");
> + DRM_NOTE("drm_kms_firmware.edid_firmware is deprecated, please use 
> drm.edid_firmware instead.\n");
>  
>   return __drm_set_edid_firmware_path(val);
>  }
> -- 
> 2.20.1
> 

-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [PATCH 1/3] drm/mediatek: move mipi_dsi_host_register to probe

2019-02-14 Thread Sean Paul
ROBE_DEFER;
> + goto err_unregister_host;
>   }
>  
>   irq_set_status_flags(irq_num, IRQ_TYPE_LEVEL_LOW);
> @@ -1163,14 +1163,25 @@ static int mtk_dsi_probe(struct platform_device *pdev)
>  IRQF_TRIGGER_LOW, dev_name(>dev), dsi);
>   if (ret) {
>   dev_err(>dev, "failed to request mediatek dsi irq\n");
> - return -EPROBE_DEFER;
> + ret = -EPROBE_DEFER;
> + goto err_unregister_host;
>   }
>  
>   init_waitqueue_head(>irq_wait_queue);
>  
>   platform_set_drvdata(pdev, dsi);
>  
> - return component_add(>dev, _dsi_component_ops);
> + ret = component_add(>dev, _dsi_component_ops);
> + if (ret) {
> + ret = -EPROBE_DEFER;
> + goto err_unregister_host;
> + }
> +
> + return 0;
> +
> +err_unregister_host:
> + mipi_dsi_host_unregister(>host);
> + return ret;
>  }
>  
>  static int mtk_dsi_remove(struct platform_device *pdev)
> -- 
> 2.20.1
> 

-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [PATCH] drm/mediatek: add mt8183 dpi support

2019-02-14 Thread Sean Paul
On Mon, Feb 11, 2019 at 12:50:59PM +0800, Jitao Shi wrote:
> MT8183 sample on rising and falling edge. It can reduce half data io.
> 
> Signed-off-by: Jitao Shi 
> ---
>  drivers/gpu/drm/mediatek/mtk_dpi.c | 29 +
>  1 file changed, 29 insertions(+)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c 
> b/drivers/gpu/drm/mediatek/mtk_dpi.c
> index 62a9d47df948..610c23334047 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> @@ -117,6 +117,7 @@ struct mtk_dpi_conf {
>   unsigned int (*cal_factor)(int clock);
>   u32 reg_h_fre_con;
>   bool edge_sel_en;
> + bool dual_edge;
>  };
>  
>  static void mtk_dpi_mask(struct mtk_dpi *dpi, u32 offset, u32 val, u32 mask)
> @@ -353,6 +354,13 @@ static void mtk_dpi_config_disable_edge(struct mtk_dpi 
> *dpi)
>   mtk_dpi_mask(dpi, dpi->conf->reg_h_fre_con, 0, EDGE_SEL_EN);
>  }
>  
> +static void mtk_dpi_enable_dual_edge(struct mtk_dpi *dpi)
> +{
> + mtk_dpi_mask(dpi, DPI_DDR_SETTING, DDR_EN | DDR_4PHASE,
> +  DDR_EN | DDR_4PHASE);
> + mtk_dpi_mask(dpi, DPI_OUTPUT_SETTING, EDGE_SEL, EDGE_SEL);
> +}
> +
>  static void mtk_dpi_config_color_format(struct mtk_dpi *dpi,
>   enum mtk_dpi_out_color_format format)
>  {
> @@ -509,6 +517,8 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
>   mtk_dpi_config_color_format(dpi, dpi->color_format);
>   mtk_dpi_config_2n_h_fre(dpi);
>   mtk_dpi_config_disable_edge(dpi);
> + if (dpi->conf->dual_edge)
> + mtk_dpi_enable_dual_edge(dpi);
>   mtk_dpi_sw_reset(dpi, false);
>  
>   return 0;
> @@ -671,6 +681,16 @@ static unsigned int mt2701_calculate_factor(int clock)
>   return 2;
>  }
>  
> +static unsigned int mt8183_calculate_factor(int clock)
> +{
> + if (clock <= 27000)
> + return 8;
> + else if (clock <= 167000)
> + return 4;
> + else
> + return 2;
> +}
> +
>  static const struct mtk_dpi_conf mt8173_conf = {
>   .cal_factor = mt8173_calculate_factor,
>   .reg_h_fre_con = 0xe0,
> @@ -682,6 +702,12 @@ static const struct mtk_dpi_conf mt2701_conf = {
>   .edge_sel_en = true,
>  };
>  
> +static const struct mtk_dpi_conf mt8183_conf = {
> + .cal_factor = mt8183_calculate_factor,
> + .reg_h_fre_con = 0xe0,
> + .dual_edge = true,
> +};
> +
>  static int mtk_dpi_probe(struct platform_device *pdev)
>  {
>   struct device *dev = >dev;
> @@ -777,6 +803,9 @@ static const struct of_device_id mtk_dpi_of_ids[] = {
>   { .compatible = "mediatek,mt8173-dpi",
> .data = _conf,
>   },
> + { .compatible = "mediatek,mt8183-dpi",

Do you need to add this compatible value to the dt binding? If you can do as CK
suggested, maybe you don't need this at all (and mt8183 can use the mt8173
compatible string in the dt).

Sean

> +   .data = _conf,
> + },
>   { },
>  };
>  
> -- 
> 2.12.5
> 

-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [PATCH] MAINTAINERS: update entry for drm/msm

2019-02-13 Thread Sean Paul
On Wed, Feb 13, 2019 at 05:04:59PM +0100, Daniel Vetter wrote:
> On Wed, Feb 13, 2019 at 4:43 PM Rob Clark via dri-devel
>  wrote:
> >
> > On Wed, Feb 13, 2019 at 10:28 AM Daniel Vetter  wrote:
> > >
> > > On Wed, Feb 13, 2019 at 10:10:44AM -0500, Rob Clark via dri-devel wrote:
> > > > We've moved the tree to a shared gitlab tree, so that Sean can help out
> > > > with maintainer duties.
> > > >
> > > > Cc: Sean Paul 
> > > > Signed-off-by: Rob Clark 
> > > > ---
> > > > I can include this patch in msm-next for v5.1, but wanted to get it
> > > > ack'd on list
> > >
> > > Is the plan to also add this to dim, for full group maintainership fun?
> > > It's more or less adding a few lines to nightly.conf and done (plus
> > > everyone being ok with using the dim tooling).
> >
> > I think drm/msm is big enough, that it wouldn't make sense to move to
> > drm-misc..  but possibly using the dim tooling could make sense.
> 
> This was about using the dim tooling, not about moving msm to
> drm-misc. That indeed doesn't make much sense. And Sean already knows
> that tooling. Plus you pretty much need a big script if you want to
> add more committers (which imo you guys totally should), since
> otherwise you spend up endless amounts of time training people on
> trivial hiccups.

Yeah, we've talked about switching to dim a few times already. IMO, the big win
for msm would be inclusion in drm-tip to catch integration issues early, and
dim's sanity checks around tags. Selfishly, this would also reduce dim's
complaints when backmerging drm into drm-misc  :-).

That said, would the committers we'd want to add to msm (Qualcomm employees) be
receptive to (or even able to install/download) dim? I'm not sure on this one.

At any rate, last time we discussed dim, we agreed the first step was to get
msm on gitlab so we can easily add commit access and go from there. I think
we're probably just at the end of that transition period, so everything is on
track!

Sean


> -Daniel
> 
> > BR,
> > -R
> >
> > > -Daniel
> > >
> > > >
> > > >  MAINTAINERS | 3 ++-
> > > >  1 file changed, 2 insertions(+), 1 deletion(-)
> > > >
> > > > diff --git a/MAINTAINERS b/MAINTAINERS
> > > > index 9919840d54cd..2141a1b6653d 100644
> > > > --- a/MAINTAINERS
> > > > +++ b/MAINTAINERS
> > > > @@ -4838,10 +4838,11 @@ F:
> > > > Documentation/devicetree/bindings/display/multi-inno,mi0283qt.txt
> > > >
> > > >  DRM DRIVER FOR MSM ADRENO GPU
> > > >  M:   Rob Clark 
> > > > +M:   Sean Paul 
> > > >  L:   linux-arm-...@vger.kernel.org
> > > >  L:   dri-de...@lists.freedesktop.org
> > > >  L:   freedr...@lists.freedesktop.org
> > > > -T:   git git://people.freedesktop.org/~robclark/linux
> > > > +T:   git https://gitlab.freedesktop.org/drm/msm.git
> > > >  S:   Maintained
> > > >  F:   drivers/gpu/drm/msm/
> > > >  F:   include/uapi/drm/msm_drm.h
> > > > --
> > > > A
> > > > 2.20.1
> > > >
> > > > ___
> > > > dri-devel mailing list
> > > > dri-de...@lists.freedesktop.org
> > > > https://lists.freedesktop.org/mailman/listinfo/dri-devel
> > >
> > > --
> > > Daniel Vetter
> > > Software Engineer, Intel Corporation
> > > http://blog.ffwll.ch
> > ___
> > dri-devel mailing list
> > dri-de...@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/dri-devel
> 
> 
> 
> -- 
> Daniel Vetter
> Software Engineer, Intel Corporation
> +41 (0) 79 365 57 48 - http://blog.ffwll.ch
> ___
> dri-devel mailing list
> dri-de...@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [PATCH] MAINTAINERS: update entry for drm/msm

2019-02-13 Thread Sean Paul
On Wed, Feb 13, 2019 at 10:10:44AM -0500, Rob Clark via dri-devel wrote:
> We've moved the tree to a shared gitlab tree, so that Sean can help out
> with maintainer duties.
> 
> Cc: Sean Paul 

Acked-by: Sean Paul 

> Signed-off-by: Rob Clark 
> ---
> I can include this patch in msm-next for v5.1, but wanted to get it
> ack'd on list
> 
>  MAINTAINERS | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 9919840d54cd..2141a1b6653d 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -4838,10 +4838,11 @@ F:
> Documentation/devicetree/bindings/display/multi-inno,mi0283qt.txt
>  
>  DRM DRIVER FOR MSM ADRENO GPU
>  M:   Rob Clark 
> +M:   Sean Paul 
>  L:   linux-arm-...@vger.kernel.org
>  L:   dri-de...@lists.freedesktop.org
>  L:   freedr...@lists.freedesktop.org
> -T:   git git://people.freedesktop.org/~robclark/linux
> +T:   git https://gitlab.freedesktop.org/drm/msm.git
>  S:   Maintained
>  F:   drivers/gpu/drm/msm/
>  F:   include/uapi/drm/msm_drm.h
> -- 
> A
> 2.20.1
> 
> ___
> dri-devel mailing list
> dri-de...@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [PATCH] drm/dp_mst: Remove rebase-detritus in VCPI helper kernel-docs

2019-02-07 Thread Sean Paul
On Wed, Feb 06, 2019 at 01:31:01PM -0500, Lyude Paul wrote:
> Looks like when making the final revision of:
> 
> 022debad063e ("drm/atomic: Add drm_atomic_state->duplicated")
> 
> I forgot to remove some of the comments that I had added to
> drm_dp_atomic_find_vcpi_slots() and drm_dp_atomic_release_vcpi_slots()
> that were no longer valid due to us having removed the state->duplicated
> checks from each function. This also introduced an error while building
> the docs with sphinx:
> 
> ./drivers/gpu/drm/drm_dp_mst_topology.c:3100: WARNING: Inline literal
> start-string without end-string.
> 
> So, fix that by just removing the kerneldoc comments.
> 
> Signed-off-by: Lyude Paul 

Reviewed-by: Sean Paul 

> Fixes: 022debad063e ("drm/atomic: Add drm_atomic_state->duplicated")
> Cc: Daniel Vetter 
> ---
>  drivers/gpu/drm/drm_dp_mst_topology.c | 9 -
>  1 file changed, 9 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c 
> b/drivers/gpu/drm/drm_dp_mst_topology.c
> index 5a99135d39cd..dc7ac0c60547 100644
> --- a/drivers/gpu/drm/drm_dp_mst_topology.c
> +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
> @@ -3097,10 +3097,6 @@ static int drm_dp_init_vcpi(struct 
> drm_dp_mst_topology_mgr *mgr,
>   * @port as needed. It is not OK however, to call this function and
>   * drm_dp_atomic_release_vcpi_slots() in the same atomic check phase.
>   *
> - * When _atomic_state.duplicated is set to %true%, this function will not
> - * perform any error checking and will instead simply return the previously
> - * recorded VCPI allocations.
> - *
>   * See also:
>   * drm_dp_atomic_release_vcpi_slots()
>   * drm_dp_mst_atomic_check()
> @@ -3185,11 +3181,6 @@ EXPORT_SYMBOL(drm_dp_atomic_find_vcpi_slots);
>   * drm_dp_atomic_find_vcpi_slots() on the same @port in a single atomic check
>   * phase.
>   *
> - * When _atomic_state.duplicated is set, this function will not
> - * modify the VCPI allocations in _dp_mst_topology_state.vcpis, so that
> - * those VCPI allocations may be restored as-is from the duplicated state. In
> - * this scenario, this function will always return 0.
> - *
>   * See also:
>   * drm_dp_atomic_find_vcpi_slots()
>   * drm_dp_mst_atomic_check()
> -- 
> 2.20.1
> 

-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [PATCH v1 0/19] drm/panel: drmP.h removal and DRM_DEV*

2019-01-31 Thread Sean Paul
On Thu, Jan 31, 2019 at 08:26:00PM +0100, Sam Ravnborg wrote:
> Hi Thierry et al.
> 
> While reviewing a number of new panel drivers there was a
> certain pattern in the feedback:
> - the now deprecated drmP.h file was used
> - dev_err() and friends was used
> 
> This patch-set address the above items in the panel
> drivers in drm/panel/
> The hope is that new panel drivers will no longer inherit bad
> patterns from the existing drivers.
> 
> The use of DRM_DEV* is not accepted by everyone, so this conversion
> was split up in smaller bits.
> If some drivers do not want to use DRM_DEV* then just drop the relevant patch.
> 
> All patches are build tested on x86/arm.
> 
> The DRM_DEV* patches depends on the drmP.h removal.
> 
> One extra patch sneaked in "panel-innolux: drop unused variable"
> This is a fix for an unused variable and was added to flush my panel patches.
> 
> Note: Waiting for key storage (for gpg key) before I start the process getting
> commit rights, so I rely on someone else (Thierry?) to commit this.
> 
> Patches are made on top of drm-misc-next as of a few days ago.
> 
> Comments welcome!

Hey Sam,
Thanks for the patchset, this will make dmesg grepping easier! One comment, and
you're going to hate me for it: Why use DRM_DEV* instead of DRM_*?

When I introduced DRM_DEV, it was to cover the case where there are multiple
instances of the same driver (ie: dual-channel mipi, multiple crtcs, etc). I
suppose that _could_ happen in the panel space, but it seems more unlikely than
not.

It's quite possible I'm overthinking this, but just something I figured I would
point out. Either way, I think this is an improvement over dev_*.

Sean

> 
>   Sam
> 
> Sam Ravnborg (19):
>   drm/panel: drop drmP.h usage
>   drm/panel: panel-innolux: drop unused variable
>   drm/panel: samsung: use DRM_DEV*
>   drm/panel: arm-versatile: use DRM_DEV*
>   drm/panel: truly: use DRM_DEV*
>   drm/panel: sitronix: use DRM_DEV*
>   drm/panel: ilitek: use DRM_DEV*
>   drm/panel: innolux: use DRM_DEV*
>   drm/panel: jdi: use DRM_DEV*
>   drm/panel: lg: use DRM_DEV*
>   drm/panel: lvds: use DRM_DEV*
>   drm/panel: olimex: use DRM_DEV*
>   drm/panel: orisetech: use DRM_DEV*
>   drm/panel: panasonic: use DRM_DEV*
>   drm/panel: raspberrypi: use DRM_DEV*
>   drm/panel: raydium: use DRM_DEV*
>   drm/panel: seiko: use DRM_DEV*
>   drm/panel: sharp: use DRM_DEV*
>   drm/panel: simple: use DRM_DEV*
> 
>  drivers/gpu/drm/panel/panel-arm-versatile.c| 21 +++--
>  drivers/gpu/drm/panel/panel-ilitek-ili9322.c   | 97 
> --
>  drivers/gpu/drm/panel/panel-ilitek-ili9881c.c  | 14 ++--
>  drivers/gpu/drm/panel/panel-innolux-p079zca.c  | 17 ++--
>  drivers/gpu/drm/panel/panel-jdi-lt070me05000.c | 66 ---
>  drivers/gpu/drm/panel/panel-kingdisplay-kd097d04.c |  4 +-
>  drivers/gpu/drm/panel/panel-lg-lg4573.c| 25 +++---
>  drivers/gpu/drm/panel/panel-lvds.c | 39 +
>  drivers/gpu/drm/panel/panel-olimex-lcd-olinuxino.c | 28 ---
>  drivers/gpu/drm/panel/panel-orisetech-otm8009a.c   | 15 ++--
>  .../gpu/drm/panel/panel-panasonic-vvx10f034n00.c   | 19 +++--
>  .../gpu/drm/panel/panel-raspberrypi-touchscreen.c  | 25 +++---
>  drivers/gpu/drm/panel/panel-raydium-rm68200.c  | 11 ++-
>  drivers/gpu/drm/panel/panel-samsung-ld9040.c   | 18 ++--
>  drivers/gpu/drm/panel/panel-samsung-s6e3ha2.c  | 21 +++--
>  drivers/gpu/drm/panel/panel-samsung-s6e63j0x03.c   | 15 ++--
>  drivers/gpu/drm/panel/panel-samsung-s6e8aa0.c  | 32 ---
>  drivers/gpu/drm/panel/panel-seiko-43wvf1g.c| 18 ++--
>  drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c| 66 ++-
>  drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c| 27 +++---
>  drivers/gpu/drm/panel/panel-simple.c   | 22 +++--
>  drivers/gpu/drm/panel/panel-sitronix-st7789v.c | 16 ++--
>  drivers/gpu/drm/panel/panel-truly-nt35597.c| 10 ++-
>  23 files changed, 375 insertions(+), 251 deletions(-)

-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [PATCH v5 0/8] drm/msm/dsi: Get PHY ref clocks from the DT

2019-01-31 Thread Sean Paul
On Mon, Jan 28, 2019 at 04:05:34PM -0800, Matthias Kaehlcke wrote:
> Hi,
> 
> this series has gone through multiple rounds of review and there are
> no outstanding comments. It seems it should be ready to land, or is
> there anything left that needs to be addressed?

>From the drm side, I think we'll need Andy to pick up the dt-bindings
and dts changes, and then the msm/dsi changes can be picked once that's
merged. We could also do a topic branch if that suits everyone.

Sean

> 
> Thanks
> 
> Matthias
> 
> On Wed, Dec 19, 2018 at 03:55:20PM -0800, Matthias Kaehlcke wrote:
> > The MSM DSI PHY drivers currently hardcode the name and the rate of
> > the PHY ref clock. Get the ref clock from the device tree instead.
> > 
> > Note: testing of this series was limited to SDM845 and the 10nm PHY
> > 
> > Major changes in v5:
> > - none (see per-patch change log for minor changes)
> > 
> > Major changes in v4:
> > - always use parent rate for 28nm and 28nm 8960 PHYs
> > 
> > Major changes in v3:
> > - keep supporting DTs without ref clock for the 28nm and the 28nm
> >   8960 PHYs
> > - added patch to add ref clock to qcom-apq8064.dtsi
> > 
> > Major changes in v2:
> > - apply to all MSM DSI PHY drivers, not only 10nm
> > 
> > Matthias Kaehlcke (8):
> >   dt-bindings: msm/dsi: Add ref clock for PHYs
> >   drm/msm/dsi: 28nm 8960 PHY: Get ref clock from the DT
> >   drm/msm/dsi: 28nm PHY: Get ref clock from the DT
> >   drm/msm/dsi: 14nm PHY: Get ref clock from the DT
> >   drm/msm/dsi: 10nm PHY: Get ref clock from the DT
> >   arm64: dts: qcom: msm8916: Set 'xo_board' as ref clock of the DSI PHY
> >   arm64: dts: sdm845: Set 'bi_tcxo' as ref clock of the DSI PHYs
> >   ARM: dts: qcom-apq8064: Set 'xo_board' as ref clock of the DSI PHY
> > 
> >  .../devicetree/bindings/display/msm/dsi.txt   |  1 +
> >  arch/arm/boot/dts/qcom-apq8064.dtsi   |  5 +--
> >  arch/arm64/boot/dts/qcom/msm8916.dtsi |  5 +--
> >  arch/arm64/boot/dts/qcom/sdm845.dtsi  | 10 +++---
> >  drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c| 20 +--
> >  drivers/gpu/drm/msm/dsi/pll/dsi_pll_14nm.c| 23 +---
> >  drivers/gpu/drm/msm/dsi/pll/dsi_pll_28nm.c| 36 +--
> >  .../gpu/drm/msm/dsi/pll/dsi_pll_28nm_8960.c   | 24 ++---
> >  8 files changed, 92 insertions(+), 32 deletions(-)
> > 

-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [PATCH AUTOSEL 4.19 083/258] drm: Move drm_mode_setcrtc() local re-init to failure path

2019-01-28 Thread Sean Paul
On Mon, Jan 28, 2019 at 10:56:29AM -0500, Sasha Levin wrote:
> From: Sean Paul 
> 
> [ Upstream commit c232e9f41b136c141df9938024e521191a7b910d ]
> 
> Instead of always re-initializing the variables we need to clean up on
> out, move the re-initialization into the branch that goes back to retry
> label.
> 
> This is a lateral move right now, but will allow us to pull out the
> modeset locking into common code. I kept this change separate to make
> things easier to review.
> 
> Changes in v2:
> - None
> 
> Reviewed-by: Daniel Vetter 
> Signed-off-by: Sean Paul 
> Link: 
> https://patchwork.freedesktop.org/patch/msgid/20181129150423.239081-2-s...@poorly.run
> Signed-off-by: Sasha Levin 

This probably doesn't need to get pulled back to stable. It was a pre-cursor for
some new helper macros that also don't need to be pulled back.

(Same comment for the 4.20 version)

Sean

> ---
>  drivers/gpu/drm/drm_crtc.c | 16 +---
>  1 file changed, 9 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
> index 9cbe8f5c9aca..ed9d7fc4cb2c 100644
> --- a/drivers/gpu/drm/drm_crtc.c
> +++ b/drivers/gpu/drm/drm_crtc.c
> @@ -567,9 +567,9 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
>   struct drm_mode_crtc *crtc_req = data;
>   struct drm_crtc *crtc;
>   struct drm_plane *plane;
> - struct drm_connector **connector_set, *connector;
> - struct drm_framebuffer *fb;
> - struct drm_display_mode *mode;
> + struct drm_connector **connector_set = NULL, *connector;
> + struct drm_framebuffer *fb = NULL;
> + struct drm_display_mode *mode = NULL;
>   struct drm_mode_set set;
>   uint32_t __user *set_connectors_ptr;
>   struct drm_modeset_acquire_ctx ctx;
> @@ -598,10 +598,6 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
>   mutex_lock(>dev->mode_config.mutex);
>   drm_modeset_acquire_init(, DRM_MODESET_ACQUIRE_INTERRUPTIBLE);
>  retry:
> - connector_set = NULL;
> - fb = NULL;
> - mode = NULL;
> -
>   ret = drm_modeset_lock_all_ctx(crtc->dev, );
>   if (ret)
>   goto out;
> @@ -763,6 +759,12 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
>   }
>   kfree(connector_set);
>   drm_mode_destroy(dev, mode);
> +
> + /* In case we need to retry... */
> + connector_set = NULL;
> + fb = NULL;
> + mode = NULL;
> +
>   if (ret == -EDEADLK) {
>   ret = drm_modeset_backoff();
>   if (!ret)
> -- 
> 2.19.1
> 
> ___
> dri-devel mailing list
> dri-de...@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [PATCH v5 6/6] drm: remove drmP.h from drm_modeset_helper.h

2019-01-24 Thread Sean Paul
On Thu, Jan 24, 2019 at 09:17:49PM +0100, Sam Ravnborg wrote:
> Hi Sean.
> 
> > > 
> > > Merge the previous 5 patches from this series, but this now goes boom on
> > > vbox in staging. Needs another prep patch I think.
> > 
> > Soo, can we drop vboxvideo yet?
> 
> Hans de Goede sent out patches in September to convert it to a proper
> atomic driver.
> I recall that the feedback was mostly positive and that there was only
> minor things to left to do. Hans?

Ah, even better if we can move it from staging into drm. Would be nice to know
what it's hung up on so we can avoid these refactor breakages.

Sean

> 
>   Sam

-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [PATCH v5 6/6] drm: remove drmP.h from drm_modeset_helper.h

2019-01-24 Thread Sean Paul
On Thu, Jan 24, 2019 at 03:03:20PM +0100, Daniel Vetter wrote:
> On Sat, Jan 19, 2019 at 09:40:14AM +0100, Sam Ravnborg wrote:
> > With the removal of drmP.h from drm_modeset_helper.h
> > the drmP.h are no longer included by any include files
> > in include/drm.
> > The drmP.h file is thus only included explicit
> > either in .c files or in local .h files.
> > This makes the process of deleting the drmP.h includes easier
> > as we have a more local dependency chain.
> > 
> > Include build failure fixes in drm files after the drmP.h removal.
> > 
> > Signed-off-by: Sam Ravnborg 
> > Reviewed-by: Laurent Pinchart 
> > Cc: Maarten Lankhorst 
> > Cc: Maxime Ripard 
> > Cc: Sean Paul 
> > Cc: David Airlie 
> > Cc: Daniel Vetter 
> 
> Merge the previous 5 patches from this series, but this now goes boom on
> vbox in staging. Needs another prep patch I think.

Soo, can we drop vboxvideo yet?

Sean

> -Daniel
> 
> > ---
> >  drivers/gpu/drm/drm_damage_helper.c  | 1 +
> >  drivers/gpu/drm/drm_modeset_helper.c | 2 ++
> >  include/drm/drm_modeset_helper.h | 6 +-
> >  3 files changed, 8 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/drm_damage_helper.c 
> > b/drivers/gpu/drm/drm_damage_helper.c
> > index e16aa5ae00b4..ee67c96841fa 100644
> > --- a/drivers/gpu/drm/drm_damage_helper.c
> > +++ b/drivers/gpu/drm/drm_damage_helper.c
> > @@ -32,6 +32,7 @@
> >  
> >  #include 
> >  #include 
> > +#include 
> >  
> >  /**
> >   * DOC: overview
> > diff --git a/drivers/gpu/drm/drm_modeset_helper.c 
> > b/drivers/gpu/drm/drm_modeset_helper.c
> > index 9150fa385bba..9bc1ef788c77 100644
> > --- a/drivers/gpu/drm/drm_modeset_helper.c
> > +++ b/drivers/gpu/drm/drm_modeset_helper.c
> > @@ -23,8 +23,10 @@
> >  #include 
> >  #include 
> >  #include 
> > +#include 
> >  #include 
> >  #include 
> > +#include 
> >  
> >  /**
> >   * DOC: aux kms helpers
> > diff --git a/include/drm/drm_modeset_helper.h 
> > b/include/drm/drm_modeset_helper.h
> > index efa337f03129..995fd981cab0 100644
> > --- a/include/drm/drm_modeset_helper.h
> > +++ b/include/drm/drm_modeset_helper.h
> > @@ -23,7 +23,11 @@
> >  #ifndef __DRM_KMS_HELPER_H__
> >  #define __DRM_KMS_HELPER_H__
> >  
> > -#include 
> > +struct drm_crtc;
> > +struct drm_crtc_funcs;
> > +struct drm_device;
> > +struct drm_framebuffer;
> > +struct drm_mode_fb_cmd2;
> >  
> >  void drm_helper_move_panel_connectors_to_head(struct drm_device *);
> >  
> > -- 
> > 2.12.0
> > 
> 
> -- 
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch

-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [PATCH v4 RESEND] drm/panel: add Kingdisplay kd097d04 panel driver

2019-01-24 Thread Sean Paul
On Thu, Jan 24, 2019 at 05:18:12PM +0100, Thierry Reding wrote:
> On Thu, Jan 24, 2019 at 12:01:55PM -0300, Ezequiel Garcia wrote:
> > On Tue, 2018-10-30 at 10:15 +0100, Heiko Stuebner wrote:
> > > From: Nickey Yang 
> > > 
> > > Support Kingdisplay kd097d04 9.7" 1536x2048 TFT LCD panel,
> > > it is a MIPI dual-DSI panel.
> > > 
> > > v4-resend:
> > > - Thierry noted missing dt-bindings for v4 but forgot that he
> > >   already had applied them one kernel release back in
> > >   
> > > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=ebc950fdff6d5f9250cd5a5a348af97f7d8508df
> > > v4:
> > > - address Philipp's comments
> > >   - real range for usleep_range and
> > >   - poweroff ordering in kingdisplay_panel_prepare
> > >   - return value beautification in panel_probe
> > > - update author naming for full name
> > > v3:
> > > - address Thierry's comments
> > >   - error handling for init dsi writes in init
> > >   - unconditionally remove the panel
> > >   - don't use drm_panel_detach
> > >   - a bit of variable signednes wiggling
> > > - I did talk to ChromeOS people and the delays really should be as short
> > >   as possible, so dropped the 100ms from the delay comments
> > > v2:
> > > - update timing + cmds from chromeos kernel
> > > - new backlight API including switch to devm_of_find_backlight
> > > - fix most of Sean Paul's comments
> > >   enable/prepare tracking seems something all panels do
> > > - document origins of the init sequence
> > > - lanes per dsi interface to 4 (two interfaces). Matches how tegra
> > >   and pending rockchip dual-dsi handle (dual-)dsi lanes
> > > - spdx header instead of license boilerplate
> > > 
> > > Signed-off-by: Nickey Yang 
> > > Signed-off-by: Heiko Stuebner 
> > 
> > Hm, this v4 patch has been stalling here for *four full months*.
> > 
> > Which deity do we need to pray to get this one moving? ;-)
> > 
> > Seriously, can someone please apply this?
> 
> If you care about this driver, perhaps you'd like to review and provide
> a Reviewed-by?

Looks good to me,

Reviewed-by: Sean Paul 

> 
> Thierry



-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [PATCH resend] drm/panel: panel-innolux: set display off in innolux_panel_unprepare

2019-01-22 Thread Sean Paul
On Fri, Jan 18, 2019 at 12:58:10PM -0500, Sean Paul wrote:
> On Wed, Jan 9, 2019 at 1:59 AM Hsin-Yi, Wang  wrote:
> >
> > Move mipi_dsi_dcs_set_display_off() from innolux_panel_disable()
> > to innolux_panel_unprepare(), so they are consistent with
> > innolux_panel_enable() and innolux_panel_prepare().
> >
> > This also fixes some mode check and irq timeout issue in MTK dsi code.
> >
> > Since some dsi code (e.g. mtk_dsi) have following call trace:
> > 1. drm_panel_disable(), which calls innolux_panel_disable()
> > 2. switch to cmd mode
> > 3. drm_panel_unprepare(), which calls innolux_panel_unprepare()
> >
> > However, mtk_dsi needs to be in cmd mode to be able to send commands
> > (e.g. mipi_dsi_dcs_set_display_off() and mipi_dsi_dcs_enter_sleep_mode()),
> > so we need these functions to be called after the switch to cmd mode 
> > happens,
> > i.e. in innolux_panel_unprepare.
> >
> >
> > Signed-off-by: Hsin-Yi, Wang 
> 
> Reviewed-by: Sean Paul 

Applied to drm-misc-next, thanks for your patch.

Sean

> 
> > ---
> > Resend for review.
> > ---
> >  drivers/gpu/drm/panel/panel-innolux-p079zca.c | 11 +--
> >  1 file changed, 5 insertions(+), 6 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/panel/panel-innolux-p079zca.c 
> > b/drivers/gpu/drm/panel/panel-innolux-p079zca.c
> > index ca4ae45dd307..8e5724b63f1f 100644
> > --- a/drivers/gpu/drm/panel/panel-innolux-p079zca.c
> > +++ b/drivers/gpu/drm/panel/panel-innolux-p079zca.c
> > @@ -70,18 +70,12 @@ static inline struct innolux_panel 
> > *to_innolux_panel(struct drm_panel *panel)
> >  static int innolux_panel_disable(struct drm_panel *panel)
> >  {
> > struct innolux_panel *innolux = to_innolux_panel(panel);
> > -   int err;
> >
> > if (!innolux->enabled)
> > return 0;
> >
> > backlight_disable(innolux->backlight);
> >
> > -   err = mipi_dsi_dcs_set_display_off(innolux->link);
> > -   if (err < 0)
> > -   DRM_DEV_ERROR(panel->dev, "failed to set display off: %d\n",
> > - err);
> > -
> > innolux->enabled = false;
> >
> > return 0;
> > @@ -95,6 +89,11 @@ static int innolux_panel_unprepare(struct drm_panel 
> > *panel)
> > if (!innolux->prepared)
> > return 0;
> >
> > +   err = mipi_dsi_dcs_set_display_off(innolux->link);
> > +   if (err < 0)
> > +   DRM_DEV_ERROR(panel->dev, "failed to set display off: %d\n",
> > + err);
> > +
> > err = mipi_dsi_dcs_enter_sleep_mode(innolux->link);
> > if (err < 0) {
> > DRM_DEV_ERROR(panel->dev, "failed to enter sleep mode: 
> > %d\n",
> > --
> > 2.18.1
> >
> ___
> dri-devel mailing list
> dri-de...@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [Freedreno] [v3] drm/msm/dpu: Clean up dpu hw interrupts

2019-01-22 Thread Sean Paul
gt; @@ -96,18 +89,6 @@ enum dpu_intr_type {
>   */
>  struct dpu_hw_intr_ops {
>   /**
> -  * set_mask - Programs the given interrupt register with the
> -  *given interrupt mask. Register value will get overwritten.
> -  * @intr:   HW interrupt handle
> -  * @reg_off:MDSS HW register offset
> -  * @irqmask:IRQ mask value
> -  */
> - void (*set_mask)(
> - struct dpu_hw_intr *intr,
> - uint32_t reg,
> - uint32_t irqmask);
> -
> - /**
>* irq_idx_lookup - Lookup IRQ index on the HW interrupt type
>* Used for all irq related ops
>* @intr_type:  Interrupt type defined in dpu_intr_type
> @@ -177,16 +158,6 @@ struct dpu_hw_intr_ops {
>   struct dpu_hw_intr *intr);
>  
>   /**
> -  * clear_interrupt_status - Clears HW interrupt status based on given
> -  *  lookup IRQ index.
> -  * @intr:   HW interrupt handle
> -  * @irq_idx:Lookup irq index return from irq_idx_lookup
> -  */
> - void (*clear_interrupt_status)(
> - struct dpu_hw_intr *intr,
> - int irq_idx);
> -
> - /**
>* clear_intr_status_nolock() - clears the HW interrupts without lock
>* @intr:   HW interrupt handle
>* @irq_idx:Lookup irq index return from irq_idx_lookup
> @@ -206,21 +177,6 @@ struct dpu_hw_intr_ops {
>   struct dpu_hw_intr *intr,
>   int irq_idx,
>   bool clear);
> -
> - /**
> -  * get_valid_interrupts - Gets a mask of all valid interrupt sources
> -  *within DPU. These are actually status bits
> -  *within interrupt registers that specify the
> -  *source of the interrupt in IRQs. For example,
> -  *valid interrupt sources can be MDP, DSI,
> -  *HDMI etc.
> -  * @intr:   HW interrupt handle
> -  * @mask:   Returning the interrupt source MASK
> -  * @return: 0 for success, otherwise failure
> -  */
> - int (*get_valid_interrupts)(
> - struct dpu_hw_intr *intr,
> - uint32_t *mask);
>  };
>  
>  /**
> -- 
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> a Linux Foundation Collaborative Project
> 
> ___
> Freedreno mailing list
> freedr...@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/freedreno

-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [Freedreno] [v1] drm/msm/dpu: Cleanup dpu plane interface

2019-01-22 Thread Sean Paul
On Tue, Dec 18, 2018 at 06:50:38PM +0530, Jayant Shekhar wrote:
> Remove unused functions from dpu plane interface
> and unused variables from dpu plane state structure.
> 
> Signed-off-by: Jayant Shekhar 

Applied to dpu-staging, thanks!

Sean
> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h | 27 ---
>  1 file changed, 27 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h 
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
> index 7fed0b6..0e6063a 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
> @@ -28,23 +28,18 @@
>  /**
>   * struct dpu_plane_state: Define dpu extension of drm plane state object
>   * @base:base drm plane state object
> - * @property_state: Local storage for msm_prop properties
> - * @property_values: cached plane property values
>   * @aspace:  pointer to address space for input/output buffers
> - * @input_fence: dereferenced input fence pointer
>   * @stage:   assigned by crtc blender
>   * @multirect_index: index of the rectangle of SSPP
>   * @multirect_mode: parallel or time multiplex multirect mode
>   * @pending: whether the current update is still pending
>   * @scaler3_cfg: configuration data for scaler3
>   * @pixel_ext: configuration data for pixel extensions
> - * @scaler_check_state: indicates status of user provided pixel extension 
> data
>   * @cdp_cfg: CDP configuration
>   */
>  struct dpu_plane_state {
>   struct drm_plane_state base;
>   struct msm_gem_address_space *aspace;
> - void *input_fence;
>   enum dpu_stage stage;
>   uint32_t multirect_index;
>   uint32_t multirect_mode;
> @@ -107,12 +102,6 @@ void dpu_plane_get_ctl_flush(struct drm_plane *plane, 
> struct dpu_hw_ctl *ctl,
>  void dpu_plane_flush(struct drm_plane *plane);
>  
>  /**
> - * dpu_plane_kickoff - final plane operations before commit kickoff
> - * @plane: Pointer to drm plane structure
> - */
> -void dpu_plane_kickoff(struct drm_plane *plane);
> -
> -/**
>   * dpu_plane_set_error: enable/disable error condition
>   * @plane: pointer to drm_plane structure
>   */
> @@ -147,14 +136,6 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
>  void dpu_plane_clear_multirect(const struct drm_plane_state *drm_state);
>  
>  /**
> - * dpu_plane_wait_input_fence - wait for input fence object
> - * @plane:   Pointer to DRM plane object
> - * @wait_ms: Wait timeout value
> - * Returns: Zero on success
> - */
> -int dpu_plane_wait_input_fence(struct drm_plane *plane, uint32_t wait_ms);
> -
> -/**
>   * dpu_plane_color_fill - enables color fill on plane
>   * @plane:  Pointer to DRM plane object
>   * @color:  RGB fill color value, [23..16] Blue, [15..8] Green, [7..0] Red
> @@ -164,12 +145,4 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
>  int dpu_plane_color_fill(struct drm_plane *plane,
>   uint32_t color, uint32_t alpha);
>  
> -/**
> - * dpu_plane_set_revalidate - sets revalidate flag which forces a full
> - *   validation of the plane properties in the next atomic check
> - * @plane: Pointer to DRM plane object
> - * @enable: Boolean to set/unset the flag
> - */
> -void dpu_plane_set_revalidate(struct drm_plane *plane, bool enable);
> -
>  #endif /* _DPU_PLANE_H_ */
> -- 
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> a Linux Foundation Collaborative Project
> 
> ___
> Freedreno mailing list
> freedr...@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/freedreno

-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [Freedreno] [v1] drm/msm/dpu: Remove unused enum and comment from dpu mdss

2019-01-22 Thread Sean Paul
On Wed, Dec 19, 2018 at 12:23:53AM +0530, Jayant Shekhar wrote:
> Remove enum dpu_iommu_domain from dpu mdss as its unused.
> 
> Remove unnecessary comment for variable which is already
> removed.
> 
> Signed-off-by: Jayant Shekhar 

Applied to dpu-staging, thanks!

Sean

> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h | 7 ---
>  1 file changed, 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h 
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
> index 68c54d2..1ab8d4a 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
> @@ -258,12 +258,6 @@ enum dpu_vbif {
>   VBIF_NRT = VBIF_1
>  };
>  
> -enum dpu_iommu_domain {
> - DPU_IOMMU_DOMAIN_UNSECURE,
> - DPU_IOMMU_DOMAIN_SECURE,
> - DPU_IOMMU_DOMAIN_MAX
> -};
> -
>  /**
>   * DPU HW,Component order color map
>   */
> @@ -358,7 +352,6 @@ enum dpu_3d_blend_mode {
>   * @alpha_enable: whether the format has an alpha channel
>   * @num_planes: number of planes (including meta data planes)
>   * @fetch_mode: linear, tiled, or ubwc hw fetch behavior
> - * @is_yuv: is format a yuv variant
>   * @flag: usage bit flags
>   * @tile_width: format tile width
>   * @tile_height: format tile height
> -- 
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> a Linux Foundation Collaborative Project
> 
> ___
> Freedreno mailing list
> freedr...@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/freedreno

-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [PATCH] drm/msm/dpu: Convert to a chained irq chip

2019-01-22 Thread Sean Paul
On Thu, Jan 03, 2019 at 11:06:02AM -0800, Stephen Boyd wrote:
> Devices that make up DPU, i.e. graphics card, request their interrupts
> from this "virtual" interrupt chip. The interrupt chip builds upon a GIC
> SPI interrupt that raises high when any of the interrupts in the DPU's
> irq status register are triggered. From the kernel's perspective this is
> a chained irq chip, so requesting a flow handler for the GIC SPI and
> then calling generic IRQ handling code from that irq handler is not
> completely proper. It's better to convert this to a chained irq so that
> the GIC SPI irq doesn't appear in /proc/interrupts, can't have CPU
> affinity changed, and won't be accounted for with irq stats. Doing this
> also silences a recursive lockdep warning because we can specify a
> different lock class for the chained interrupts, silencing a warning
> that is easy to see with 'threadirqs' on the kernel commandline.
> 
>  WARNING: inconsistent lock state
>  4.19.10 #76 Tainted: GW
>  
>  inconsistent {IN-HARDIRQ-W} -> {HARDIRQ-ON-W} usage.
>  irq/40-dpu_mdss/203 [HC0[0]:SC0[2]:HE1:SE0] takes:
>  53ea9021 (_desc_lock_class){?.-.}, at: 
> handle_level_irq+0x34/0x26c
>  {IN-HARDIRQ-W} state was registered at:
>lock_acquire+0x244/0x360
>_raw_spin_lock+0x64/0xa0
>handle_fasteoi_irq+0x54/0x2ec
>generic_handle_irq+0x44/0x5c
>__handle_domain_irq+0x9c/0x11c
>gic_handle_irq+0x208/0x260
>el1_irq+0xb4/0x130
>arch_cpu_idle+0x178/0x3cc
>default_idle_call+0x3c/0x54
>do_idle+0x1a8/0x3dc
>cpu_startup_entry+0x24/0x28
>rest_init+0x240/0x270
>start_kernel+0x5a8/0x6bc
>  irq event stamp: 18
>  hardirqs last  enabled at (17): [] 
> _raw_spin_unlock_irq+0x40/0xc0
>  hardirqs last disabled at (16): [] __schedule+0x20c/0x1bbc
>  softirqs last  enabled at (0): [] copy_process+0xb50/0x3964
>  softirqs last disabled at (18): [] 
> local_bh_disable+0x8/0x20
> 
>  other info that might help us debug this:
>   Possible unsafe locking scenario:
> 
> CPU0
> 
>lock(_desc_lock_class);
>
>  lock(_desc_lock_class);
> 
>   *** DEADLOCK ***
> 
>  no locks held by irq/40-dpu_mdss/203.
> 
>  stack backtrace:
>  CPU: 0 PID: 203 Comm: irq/40-dpu_mdss Tainted: GW 4.19.10 #76
>  Call trace:
>   dump_backtrace+0x0/0x2f8
>   show_stack+0x20/0x2c
>   __dump_stack+0x20/0x28
>   dump_stack+0xcc/0x10c
>   mark_lock+0xbe0/0xe24
>   __lock_acquire+0x4cc/0x2708
>   lock_acquire+0x244/0x360
>   _raw_spin_lock+0x64/0xa0
>   handle_level_irq+0x34/0x26c
>   generic_handle_irq+0x44/0x5c
>   dpu_mdss_irq+0x64/0xec
>   irq_forced_thread_fn+0x58/0x9c
>   irq_thread+0x120/0x1dc
>   kthread+0x248/0x260
>   ret_from_fork+0x10/0x18
>  [ cut here ]
>  irq 169 handler irq_default_primary_handler+0x0/0x18 enabled interrupts
> 
> Cc: Sean Paul 
> Cc: Jordan Crouse 
> Cc: Jayant Shekhar 
> Cc: Rajesh Yadav 
> Cc: Jeykumar Sankaran 
> Signed-off-by: Stephen Boyd 

LGTM, applied to dpu-staging.

Thanks,

Sean

> ---
> 
>  drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c | 36 ++--
>  1 file changed, 21 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c 
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c
> index cb307a2abf06..7316b4ab1b85 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c
> @@ -23,11 +23,14 @@ struct dpu_mdss {
>   struct dpu_irq_controller irq_controller;
>  };
>  
> -static irqreturn_t dpu_mdss_irq(int irq, void *arg)
> +static void dpu_mdss_irq(struct irq_desc *desc)
>  {
> - struct dpu_mdss *dpu_mdss = arg;
> + struct dpu_mdss *dpu_mdss = irq_desc_get_handler_data(desc);
> + struct irq_chip *chip = irq_desc_get_chip(desc);
>   u32 interrupts;
>  
> + chained_irq_enter(chip, desc);
> +
>   interrupts = readl_relaxed(dpu_mdss->mmio + HW_INTR_STATUS);
>  
>   while (interrupts) {
> @@ -39,20 +42,20 @@ static irqreturn_t dpu_mdss_irq(int irq, void *arg)
>  hwirq);
>   if (mapping == 0) {
>   DRM_ERROR("couldn't find irq mapping for %lu\n", hwirq);
> - return IRQ_NONE;
> + break;
>   }
>  
>   rc = generic_handle_irq(mapping);
>   if (rc < 0) {
>   DRM_ERROR("handle irq fail: irq=%lu mapping=%u rc=%d\n",
> hwirq, mapping, rc);
> - return IRQ_NONE;
> + 

Re: [PATCH resend] drm/panel: panel-innolux: set display off in innolux_panel_unprepare

2019-01-18 Thread Sean Paul
On Wed, Jan 9, 2019 at 1:59 AM Hsin-Yi, Wang  wrote:
>
> Move mipi_dsi_dcs_set_display_off() from innolux_panel_disable()
> to innolux_panel_unprepare(), so they are consistent with
> innolux_panel_enable() and innolux_panel_prepare().
>
> This also fixes some mode check and irq timeout issue in MTK dsi code.
>
> Since some dsi code (e.g. mtk_dsi) have following call trace:
> 1. drm_panel_disable(), which calls innolux_panel_disable()
> 2. switch to cmd mode
> 3. drm_panel_unprepare(), which calls innolux_panel_unprepare()
>
> However, mtk_dsi needs to be in cmd mode to be able to send commands
> (e.g. mipi_dsi_dcs_set_display_off() and mipi_dsi_dcs_enter_sleep_mode()),
> so we need these functions to be called after the switch to cmd mode happens,
> i.e. in innolux_panel_unprepare.
>
>
> Signed-off-by: Hsin-Yi, Wang 

Reviewed-by: Sean Paul 

> ---
> Resend for review.
> ---
>  drivers/gpu/drm/panel/panel-innolux-p079zca.c | 11 +--
>  1 file changed, 5 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/panel/panel-innolux-p079zca.c 
> b/drivers/gpu/drm/panel/panel-innolux-p079zca.c
> index ca4ae45dd307..8e5724b63f1f 100644
> --- a/drivers/gpu/drm/panel/panel-innolux-p079zca.c
> +++ b/drivers/gpu/drm/panel/panel-innolux-p079zca.c
> @@ -70,18 +70,12 @@ static inline struct innolux_panel 
> *to_innolux_panel(struct drm_panel *panel)
>  static int innolux_panel_disable(struct drm_panel *panel)
>  {
> struct innolux_panel *innolux = to_innolux_panel(panel);
> -   int err;
>
> if (!innolux->enabled)
> return 0;
>
> backlight_disable(innolux->backlight);
>
> -   err = mipi_dsi_dcs_set_display_off(innolux->link);
> -   if (err < 0)
> -   DRM_DEV_ERROR(panel->dev, "failed to set display off: %d\n",
> - err);
> -
> innolux->enabled = false;
>
> return 0;
> @@ -95,6 +89,11 @@ static int innolux_panel_unprepare(struct drm_panel *panel)
> if (!innolux->prepared)
> return 0;
>
> +   err = mipi_dsi_dcs_set_display_off(innolux->link);
> +   if (err < 0)
> +   DRM_DEV_ERROR(panel->dev, "failed to set display off: %d\n",
> + err);
> +
> err = mipi_dsi_dcs_enter_sleep_mode(innolux->link);
> if (err < 0) {
> DRM_DEV_ERROR(panel->dev, "failed to enter sleep mode: %d\n",
> --
> 2.18.1
>


Re: [PATCH v4 9/9] drm/bridge: cdns: Convert to phy framework

2019-01-17 Thread Sean Paul
On Wed, Jan 09, 2019 at 10:33:26AM +0100, Maxime Ripard wrote:
> Now that we have everything we need in the phy framework to allow to tune
> the phy parameters, let's convert the Cadence DSI bridge to that API
> instead of creating a ad-hoc driver for its phy.
> 
> Signed-off-by: Maxime Ripard 

Aside from the wakeup change mentioned in patch 8,

Acked-by: Sean Paul 


> ---
>  drivers/gpu/drm/bridge/Kconfig|   1 +-
>  drivers/gpu/drm/bridge/cdns-dsi.c | 485 +++
>  drivers/phy/cadence/cdns-dphy.c   |   2 +-
>  3 files changed, 61 insertions(+), 427 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
> index 2fee47b0d50b..8840f396a7b6 100644
> --- a/drivers/gpu/drm/bridge/Kconfig
> +++ b/drivers/gpu/drm/bridge/Kconfig
> @@ -30,6 +30,7 @@ config DRM_CDNS_DSI
>   select DRM_KMS_HELPER
>   select DRM_MIPI_DSI
>   select DRM_PANEL_BRIDGE
> + select GENERIC_PHY_MIPI_DPHY
>   depends on OF
>   help
> Support Cadence DPI to DSI bridge. This is an internal
> diff --git a/drivers/gpu/drm/bridge/cdns-dsi.c 
> b/drivers/gpu/drm/bridge/cdns-dsi.c
> index 3ac6dd524b6d..7b432257ffbe 100644
> --- a/drivers/gpu/drm/bridge/cdns-dsi.c
> +++ b/drivers/gpu/drm/bridge/cdns-dsi.c
> @@ -21,6 +21,9 @@
>  #include 
>  #include 
>  
> +#include 
> +#include 
> +
>  #define IP_CONF  0x0
>  #define SP_HS_FIFO_DEPTH(x)  (((x) & GENMASK(30, 26)) >> 26)
>  #define SP_LP_FIFO_DEPTH(x)  (((x) & GENMASK(25, 21)) >> 21)
> @@ -419,44 +422,11 @@
>  #define DSI_NULL_FRAME_OVERHEAD  6
>  #define DSI_EOT_PKT_SIZE 4
>  
> -#define REG_WAKEUP_TIME_NS   800
> -#define DPHY_PLL_RATE_HZ 10800
> -
> -/* DPHY registers */
> -#define DPHY_PMA_CMN(reg)(reg)
> -#define DPHY_PMA_LCLK(reg)   (0x100 + (reg))
> -#define DPHY_PMA_LDATA(lane, reg)(0x200 + ((lane) * 0x100) + (reg))
> -#define DPHY_PMA_RCLK(reg)   (0x600 + (reg))
> -#define DPHY_PMA_RDATA(lane, reg)(0x700 + ((lane) * 0x100) + (reg))
> -#define DPHY_PCS(reg)(0xb00 + (reg))
> -
> -#define DPHY_CMN_SSM DPHY_PMA_CMN(0x20)
> -#define DPHY_CMN_SSM_EN  BIT(0)
> -#define DPHY_CMN_TX_MODE_EN  BIT(9)
> -
> -#define DPHY_CMN_PWM DPHY_PMA_CMN(0x40)
> -#define DPHY_CMN_PWM_DIV(x)  ((x) << 20)
> -#define DPHY_CMN_PWM_LOW(x)  ((x) << 10)
> -#define DPHY_CMN_PWM_HIGH(x) (x)
> -
> -#define DPHY_CMN_FBDIV   DPHY_PMA_CMN(0x4c)
> -#define DPHY_CMN_FBDIV_VAL(low, high)(((high) << 11) | ((low) << 22))
> -#define DPHY_CMN_FBDIV_FROM_REG  (BIT(10) | BIT(21))
> -
> -#define DPHY_CMN_OPIPDIV DPHY_PMA_CMN(0x50)
> -#define DPHY_CMN_IPDIV_FROM_REG  BIT(0)
> -#define DPHY_CMN_IPDIV(x)((x) << 1)
> -#define DPHY_CMN_OPDIV_FROM_REG  BIT(6)
> -#define DPHY_CMN_OPDIV(x)((x) << 7)
> -
> -#define DPHY_PSM_CFG DPHY_PCS(0x4)
> -#define DPHY_PSM_CFG_FROM_REGBIT(0)
> -#define DPHY_PSM_CLK_DIV(x)  ((x) << 1)
> -
>  struct cdns_dsi_output {
>   struct mipi_dsi_device *dev;
>   struct drm_panel *panel;
>   struct drm_bridge *bridge;
> + union phy_configure_opts phy_opts;
>  };
>  
>  enum cdns_dsi_input_id {
> @@ -465,14 +435,6 @@ enum cdns_dsi_input_id {
>   CDNS_DSC_INPUT,
>  };
>  
> -struct cdns_dphy_cfg {
> - u8 pll_ipdiv;
> - u8 pll_opdiv;
> - u16 pll_fbdiv;
> - unsigned long lane_bps;
> - unsigned int nlanes;
> -};
> -
>  struct cdns_dsi_cfg {
>   unsigned int hfp;
>   unsigned int hsa;
> @@ -481,34 +443,6 @@ struct cdns_dsi_cfg {
>   unsigned int htotal;
>  };
>  
> -struct cdns_dphy;
> -
> -enum cdns_dphy_clk_lane_cfg {
> - DPHY_CLK_CFG_LEFT_DRIVES_ALL = 0,
> - DPHY_CLK_CFG_LEFT_DRIVES_RIGHT = 1,
> - DPHY_CLK_CFG_LEFT_DRIVES_LEFT = 2,
> - DPHY_CLK_CFG_RIGHT_DRIVES_ALL = 3,
> -};
> -
> -struct cdns_dphy_ops {
> - int (*probe)(struct cdns_dphy *dphy);
> - void (*remove)(struct cdns_dphy *dphy);
> - void (*set_psm_div)(struct cdns_dphy *dphy, u8 div);
> - void (*set_clk_lane_cfg)(struct cdns_dphy *dphy,
> -  enum cdns_dphy_clk_lane_cfg cfg);
> - void (*set_pll_cfg)(struct cdns_dphy *dphy,
> - const struct cdns_dphy_cfg *cfg);
> - unsigned long (*get_wakeup_time_ns)(struct cdns_dphy *dphy);
>

Re: [PATCH v4 8/9] phy: Add Cadence D-PHY support

2019-01-17 Thread Sean Paul
-EINVAL;
> +
> + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + dphy->regs = devm_ioremap_resource(>dev, res);
> + if (IS_ERR(dphy->regs))
> + return PTR_ERR(dphy->regs);
> +
> + dphy->psm_clk = devm_clk_get(>dev, "psm");
> + if (IS_ERR(dphy->psm_clk))
> + return PTR_ERR(dphy->psm_clk);
> +
> + dphy->pll_ref_clk = devm_clk_get(>dev, "pll_ref");
> + if (IS_ERR(dphy->pll_ref_clk))
> + return PTR_ERR(dphy->pll_ref_clk);
> +
> + if (dphy->ops->probe) {
> + ret = dphy->ops->probe(dphy);
> + if (ret)
> + return ret;
> +     }
> +
> + dphy->phy = devm_phy_create(>dev, NULL, _dphy_ops);
> + if (IS_ERR(dphy->phy)) {
> + dev_err(>dev, "failed to create PHY\n");
> + if (dphy->ops->remove)
> + dphy->ops->remove(dphy);
> + return PTR_ERR(dphy->phy);
> + }
> +
> + phy_set_drvdata(dphy->phy, dphy);
> + phy_provider = devm_of_phy_provider_register(>dev, 
> of_phy_simple_xlate);
> +
> + return PTR_ERR_OR_ZERO(phy_provider);
> +}
> +
> +static int cdns_dphy_remove(struct platform_device *pdev)
> +{
> + struct cdns_dphy *dphy = dev_get_drvdata(>dev);
> +
> + if (dphy->ops->remove)
> + dphy->ops->remove(dphy);
> +
> + return 0;
> +}
> +
> +static const struct of_device_id cdns_dphy_of_match[] = {
> + { .compatible = "cdns,dphy", .data = _dphy_ops },
> + { /* sentinel */ },
> +};
> +MODULE_DEVICE_TABLE(of, cdns_dphy_of_match);
> +
> +static struct platform_driver cdns_dphy_platform_driver = {
> + .probe  = cdns_dphy_probe,
> + .remove = cdns_dphy_remove,
> + .driver = {
> + .name   = "cdns-mipi-dphy",
> + .of_match_table = cdns_dphy_of_match,
> + },
> +};
> +module_platform_driver(cdns_dphy_platform_driver);
> +
> +MODULE_AUTHOR("Maxime Ripard ");
> +MODULE_DESCRIPTION("Cadence MIPI D-PHY Driver");
> +MODULE_LICENSE("GPL");
> -- 
> git-series 0.9.1
> ___
> dri-devel mailing list
> dri-de...@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [PATCH v4 6/9] drm/bridge: cdns: Separate DSI and D-PHY configuration

2019-01-17 Thread Sean Paul
  dsi_htotal, nlanes,
> + 
> mipi_dsi_pixel_format_to_bpp(output->dev->format),
> + dsi_htotal,
> + output->dev->lanes,
>   _hfp_ext);
>   else
>   ret = cdns_dsi_get_dphy_pll_cfg(dsi->dphy, dphy_cfg,
> - mode->crtc_htotal, bpp,
> + mode->crtc_htotal,
> + 
> mipi_dsi_pixel_format_to_bpp(output->dev->format),
>   mode->crtc_clock * 1000,
> - dsi_htotal, nlanes,
> + dsi_htotal,
> + output->dev->lanes,
>   _hfp_ext);
> -
>   if (ret)
>   return ret;
>  
>   dsi_cfg->hfp += dsi_hfp_ext;
> - dsi_htotal += dsi_hfp_ext;
> - dsi_cfg->htotal = dsi_htotal;
> + dsi_cfg->htotal = dsi_htotal + dsi_hfp_ext;
> +
> + return 0;
> +}
> +
> +static int cdns_dsi_check_conf(struct cdns_dsi *dsi,
> +const struct drm_display_mode *mode,
> +struct cdns_dsi_cfg *dsi_cfg,
> +struct cdns_dphy_cfg *dphy_cfg,
> +bool mode_valid_check)
> +{
> + struct cdns_dsi_output *output = >output;
> + unsigned long dsi_hss_hsa_hse_hbp;
> + unsigned int nlanes = output->dev->lanes;
> + int ret;
> +
> + ret = cdns_dsi_mode2cfg(dsi, mode, dsi_cfg, mode_valid_check);
> + if (ret)
> + return ret;
> +
> + ret = cdns_dphy_validate(dsi, dsi_cfg, dphy_cfg, mode, 
> mode_valid_check);
> + if (ret)
> + return ret;
> +
> + dsi_hss_hsa_hse_hbp = dsi_cfg->hbp + DSI_HBP_FRAME_OVERHEAD;
> + if (output->dev->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE)
> + dsi_hss_hsa_hse_hbp += dsi_cfg->hsa + DSI_HSA_FRAME_OVERHEAD;
>  
>   /*
>* Make sure DPI(HFP) > DSI(HSS+HSA+HSE+HBP) to guarantee that the FIFO
>* is empty before we start a receiving a new line on the DPI
>* interface.
>*/
> - if ((u64)dphy_cfg->lane_bps * dpi_hfp * nlanes <
> + if ((u64)dphy_cfg->lane_bps * mode_to_dpi_hfp(mode) * nlanes <
>   (u64)dsi_hss_hsa_hse_hbp *
>   (mode_valid_check ? mode->clock : mode->crtc_clock) * 1000)
>   return -EINVAL;
> @@ -842,7 +884,7 @@ cdns_dsi_bridge_mode_valid(struct drm_bridge *bridge,
>   struct cdns_dsi_output *output = >output;
>   struct cdns_dphy_cfg dphy_cfg;
>   struct cdns_dsi_cfg dsi_cfg;
> - int bpp, nlanes, ret;
> + int bpp, ret;
>  
>   /*
>* VFP_DSI should be less than VFP_DPI and VFP_DSI should be at
> @@ -860,11 +902,9 @@ cdns_dsi_bridge_mode_valid(struct drm_bridge *bridge,
>   if ((mode->hdisplay * bpp) % 32)
>   return MODE_H_ILLEGAL;
>  
> - nlanes = output->dev->lanes;
> -
> - ret = cdns_dsi_mode2cfg(dsi, mode, _cfg, _cfg, true);
> + ret = cdns_dsi_check_conf(dsi, mode, _cfg, _cfg, true);
>   if (ret)
> - return MODE_CLOCK_RANGE;
> + return MODE_BAD;
>  
>   return MODE_OK;
>  }
> @@ -990,7 +1030,7 @@ static void cdns_dsi_bridge_enable(struct drm_bridge 
> *bridge)
>   bpp = mipi_dsi_pixel_format_to_bpp(output->dev->format);
>   nlanes = output->dev->lanes;
>  
> - WARN_ON_ONCE(cdns_dsi_mode2cfg(dsi, mode, _cfg, _cfg, false));
> + WARN_ON_ONCE(cdns_dsi_check_conf(dsi, mode, _cfg, _cfg, 
> false));
>  
>   cdns_dsi_hs_init(dsi, _cfg);
>   cdns_dsi_init_link(dsi);
> -- 
> git-series 0.9.1

-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [PATCH v3 2/2] drm/panel: Add Feiyang FY07024DI26A30-D MIPI-DSI LCD panel

2018-12-20 Thread Sean Paul
On Tue, Dec 18, 2018 at 05:06:38PM +0530, Jagan Teki wrote:
> On Sat, Dec 15, 2018 at 3:32 AM Sean Paul  wrote:
> >
> > On Sat, Dec 15, 2018 at 02:11:01AM +0530, Jagan Teki wrote:
> > > Feiyang FY07024DI26A30-D is 1024x600, 4-lane MIPI-DSI LCD panel.
> > >
> > > Add panel driver for it.
> > >
> > > Signed-off-by: Jagan Teki 
> > > ---
> > > Changes for v2:
> > > - use simple structure for command init
> > > - update proper comments on power, reset delay sequnce
> > > - fix to use set_display_off in disable function
> > > - move mode type to structure
> > > - drop refres rate value, let drm compute
> > >
> > >  MAINTAINERS   |   6 +
> > >  drivers/gpu/drm/panel/Kconfig |   9 +
> > >  drivers/gpu/drm/panel/Makefile|   1 +
> > >  .../drm/panel/panel-feiyang-fy07024di26a30d.c | 296 ++
> > >  4 files changed, 312 insertions(+)
> > >  create mode 100644 drivers/gpu/drm/panel/panel-feiyang-fy07024di26a30d.c
> > >
> > > diff --git a/MAINTAINERS b/MAINTAINERS
> > > index d2928a4d2847..e643238855ea 100644
> > > --- a/MAINTAINERS
> > > +++ b/MAINTAINERS
> > > @@ -4732,6 +4732,12 @@ T: git 
> > > git://anongit.freedesktop.org/drm/drm-misc
> > >  S:   Maintained
> > >  F:   drivers/gpu/drm/tve200/
> > >
> > > +DRM DRIVER FOR FEIYANG FY07024DI26A30-D MIPI-DSI LCD PANELS
> > > +M:   Jagan Teki 
> > > +S:   Maintained
> > > +F:   drivers/gpu/drm/panel/panel-feiyang-fy07024di26a30d.c
> > > +F:   
> > > Documentation/devicetree/bindings/display/panel/feiyang,fy07024di26a30d.txt
> > > +
> > >  DRM DRIVER FOR ILITEK ILI9225 PANELS
> > >  M:   David Lechner 
> > >  S:   Maintained
> >
> > As I mentioned on IRC, this will be drm-misc maintained with the other 
> > panels,
> > no need to have a dedicated MAINTAINERS entry. You'll get pulled from
> > get_maintainers.pl as a majority commit signer
> 
> This I missed it on IRC, sorry will drop.
> 
> >
> > > diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
> > > index d93b2ba709bc..cb8ca93550cf 100644
> > > --- a/drivers/gpu/drm/panel/Kconfig
> > > +++ b/drivers/gpu/drm/panel/Kconfig
> > > @@ -38,6 +38,15 @@ config DRM_PANEL_SIMPLE
> > > that it can be automatically turned off when the panel goes into a
> > > low power state.
> > >
> > > +config DRM_PANEL_FEIYANG_FY07024DI26A30D
> > > + tristate "Feiyang FY07024DI26A30-D MIPI-DSI LCD panel"
> > > + depends on OF
> > > + depends on DRM_MIPI_DSI
> > > + depends on BACKLIGHT_CLASS_DEVICE
> > > + help
> > > +   Say Y if you want to enable support for panels based on the
> > > +   Feiyang FY07024DI26A30-D MIPI-DSI interface.
> > > +
> > >  config DRM_PANEL_ILITEK_IL9322
> > >   tristate "Ilitek ILI9322 320x240 QVGA panels"
> > >   depends on OF && SPI
> > > diff --git a/drivers/gpu/drm/panel/Makefile 
> > > b/drivers/gpu/drm/panel/Makefile
> > > index 6a9b4cec1891..0fa0ef69e109 100644
> > > --- a/drivers/gpu/drm/panel/Makefile
> > > +++ b/drivers/gpu/drm/panel/Makefile
> > > @@ -2,6 +2,7 @@
> > >  obj-$(CONFIG_DRM_PANEL_ARM_VERSATILE) += panel-arm-versatile.o
> > >  obj-$(CONFIG_DRM_PANEL_LVDS) += panel-lvds.o
> > >  obj-$(CONFIG_DRM_PANEL_SIMPLE) += panel-simple.o
> > > +obj-$(CONFIG_DRM_PANEL_FEIYANG_FY07024DI26A30D) += 
> > > panel-feiyang-fy07024di26a30d.o
> > >  obj-$(CONFIG_DRM_PANEL_ILITEK_IL9322) += panel-ilitek-ili9322.o
> > >  obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9881C) += panel-ilitek-ili9881c.o
> > >  obj-$(CONFIG_DRM_PANEL_INNOLUX_P079ZCA) += panel-innolux-p079zca.o
> > > diff --git a/drivers/gpu/drm/panel/panel-feiyang-fy07024di26a30d.c 
> > > b/drivers/gpu/drm/panel/panel-feiyang-fy07024di26a30d.c
> > > new file mode 100644
> > > index ..4abccbf62c3c
> > > --- /dev/null
> > > +++ b/drivers/gpu/drm/panel/panel-feiyang-fy07024di26a30d.c
> > > @@ -0,0 +1,296 @@

/snip

> > > +static const struct drm_display_mode feiyang_default_mode = {
> > > + .clock = 55000,
> > > +
> > > + .hdisplay = 1024,
> > > + .hsync_start = 1024 + 396,
> > > + .hsync_end = 1024 + 396 + 20,
> > > + .htotal = 1024 + 396 + 20 + 100,
> > > +
> > > + .vdisplay = 600,
> > > + .vsync_start = 600 + 12,
> > > + .vsync_end = 600 + 12 + 2,
> > > + .vtotal = 600 + 12 + 2 + 21,
> >
> > These timings are still incorrect, they'll give a 56.2Hz refresh rate. Is 
> > that
> > really what you want?
> 
> I would like to go with same rate as of now since BSP is using the
> same, since I don't have any information from chip vendor(even I wrote
> it and waiting for response). I will update accordingly once I get the
> information from vendor.
> 
> Let me know your inputs.

Not totally on board with this, tbh. It seems wrong, so I'm not sure why we'd
apply code that seems wrong. We're not in a rush, we've already cut 4.21, so I
think we should just wait for vendor confirmation on these values.

Sean

-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [PATCH v3 2/2] drm/panel: Add Feiyang FY07024DI26A30-D MIPI-DSI LCD panel

2018-12-14 Thread Sean Paul
 + struct device_node *np;
> + struct feiyang *ctx;
> + int ret;
> +
> + ctx = devm_kzalloc(>dev, sizeof(*ctx), GFP_KERNEL);
> + if (!ctx)
> + return -ENOMEM;
> + mipi_dsi_set_drvdata(dsi, ctx);
> + ctx->dsi = dsi;
> +
> + drm_panel_init(>panel);
> + ctx->panel.dev = >dev;
> + ctx->panel.funcs = _funcs;
> +
> + ctx->dvdd = devm_regulator_get(>dev, "dvdd");
> + if (IS_ERR(ctx->dvdd)) {
> + DRM_DEV_ERROR(>dev, "Couldn't get dvdd regulator\n");
> + return PTR_ERR(ctx->dvdd);
> + }
> +
> + ctx->avdd = devm_regulator_get(>dev, "avdd");
> + if (IS_ERR(ctx->avdd)) {
> + DRM_DEV_ERROR(>dev, "Couldn't get avdd regulator\n");
> + return PTR_ERR(ctx->avdd);
> + }
> +
> + ctx->reset = devm_gpiod_get(>dev, "reset", GPIOD_OUT_LOW);
> + if (IS_ERR(ctx->reset)) {
> + DRM_DEV_ERROR(>dev, "Couldn't get our reset GPIO\n");
> + return PTR_ERR(ctx->reset);
> + }
> +
> + np = of_parse_phandle(dsi->dev.of_node, "backlight", 0);
> + if (np) {
> + ctx->backlight = of_find_backlight_by_node(np);
> + of_node_put(np);
> +
> + if (!ctx->backlight)
> + return -EPROBE_DEFER;
> + }
> +
> + ret = drm_panel_add(>panel);
> + if (ret < 0)
> + goto put_backlight;
> +
> + dsi->mode_flags = MIPI_DSI_MODE_VIDEO_BURST;
> + dsi->format = MIPI_DSI_FMT_RGB888;
> + dsi->lanes = 4;
> +
> + ret = mipi_dsi_attach(dsi);
> + if (ret < 0)
> + goto panel_remove;
> +
> + return ret;
> +
> +panel_remove:
> + drm_panel_remove(>panel);
> +put_backlight:
> + if (ctx->backlight)
> + put_device(>backlight->dev);
> +
> + return ret;
> +}
> +
> +static int feiyang_dsi_remove(struct mipi_dsi_device *dsi)
> +{
> + struct feiyang *ctx = mipi_dsi_get_drvdata(dsi);
> +
> + mipi_dsi_detach(dsi);
> + drm_panel_remove(>panel);
> +
> + if (ctx->backlight)
> + put_device(>backlight->dev);
> +
> + return 0;
> +}
> +
> +static const struct of_device_id feiyang_of_match[] = {
> + { .compatible = "feiyang,fy07024di26a30d", },
> + { }
> +};
> +MODULE_DEVICE_TABLE(of, feiyang_of_match);
> +
> +static struct mipi_dsi_driver feiyang_driver = {
> + .probe = feiyang_dsi_probe,
> + .remove = feiyang_dsi_remove,
> + .driver = {
> + .name = "feiyang-fy07024di26a30d",
> + .of_match_table = feiyang_of_match,
> + },
> +};
> +module_mipi_dsi_driver(feiyang_driver);
> +
> +MODULE_AUTHOR("Jagan Teki ");
> +MODULE_DESCRIPTION("Feiyang FY07024DI26A30-D MIPI-DSI LCD panel");
> +MODULE_LICENSE("GPL");
> -- 
> 2.18.0.321.gffc6fa0e3
> 

-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [DPU PATCH ] drm/msm/dpu: Ignore alpha for XBGR8888 format

2018-12-14 Thread Sean Paul
On Fri, Nov 30, 2018 at 05:22:50PM +0530, Jayant Shekhar wrote:
> Alpha enable in the pixel format will help in
> selecting the blend rule. By keeping alpha enable
> to true we are allowing foreground alpha to blend
> with the layer. If alpha is don't care, then we
> should not allow pixel alpha to be part of blend
> equation.
> 
> Signed-off-by: Jayant Shekhar 

Pushed to dpu-staging/for-next.

Thanks for your patch!

Sean

> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c 
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c
> index bfcd165..d743e7c 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c
> @@ -216,7 +216,7 @@ struct dpu_media_color_map {
>   INTERLEAVED_RGB_FMT(XBGR,
>   COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
>   C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
> - true, 4, 0,
> + false, 4, 0,
>   DPU_FETCH_LINEAR, 1),
>  
>   INTERLEAVED_RGB_FMT(RGBA,
> -- 
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> a Linux Foundation Collaborative Project
> 

-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [PATCH v2 11/12] drm/panel: Add Feiyang FY07024DI26A30-D MIPI-DSI LCD panel

2018-12-14 Thread Sean Paul
On Fri, Dec 14, 2018 at 04:35:11PM +0530, Jagan Teki wrote:
> On Fri, Dec 14, 2018 at 1:25 AM Sean Paul  wrote:
> >
> > On Fri, Dec 14, 2018 at 12:56:03AM +0530, Jagan Teki wrote:
> > > On Thu, Dec 13, 2018 at 8:37 PM Sean Paul  wrote:
> > > >
> > > > On Fri, Nov 16, 2018 at 10:09:15PM +0530, Jagan Teki wrote:
> > > > > Feiyang FY07024DI26A30-D is 1024x600, 4-lane MIPI-DSI LCD panel.
> > > > >
> > > > > Add panel driver for it.
> > > > >
> > > > > Signed-off-by: Jagan Teki 
> > > > > ---
> > > > >  MAINTAINERS   |   6 +
> > > > >  drivers/gpu/drm/panel/Kconfig |   9 +
> > > > >  drivers/gpu/drm/panel/Makefile|   1 +
> > > > >  .../drm/panel/panel-feiyang-fy07024di26a30d.c | 286 
> > > > > ++
> > > > >  4 files changed, 302 insertions(+)
> > > > >  create mode 100644 
> > > > > drivers/gpu/drm/panel/panel-feiyang-fy07024di26a30d.c
> > > > >
> >
> > /snip
> >
> > > > > diff --git a/drivers/gpu/drm/panel/panel-feiyang-fy07024di26a30d.c 
> > > > > b/drivers/gpu/drm/panel/panel-feiyang-fy07024di26a30d.c
> > > > > new file mode 100644
> > > > > index ..a4b46bd8fdbe
> > > > > --- /dev/null
> > > > > +++ b/drivers/gpu/drm/panel/panel-feiyang-fy07024di26a30d.c
> >
> > /snip
> >
> > > > > +static int feiyang_prepare(struct drm_panel *panel)
> > > > > +{
> > > > > + struct feiyang *ctx = panel_to_feiyang(panel);
> > > > > + struct mipi_dsi_device *dsi = ctx->dsi;
> > > > > + unsigned int i;
> > > > > + int ret;
> > > > > +
> > > > > + ret = regulator_enable(ctx->dvdd);
> > > > > + if (ret)
> > > > > + return ret;
> > > > > +
> > > > > + msleep(100);
> > > >
> > > > nit: You should do your best to correlate the sleeps with the timing 
> > > > parameters
> > > > from the datasheet with a comment.
> > > >
> > > > ie:
> > > > /* T1: > 100ms */
> > > > msleep(100);
> > >
> > > Sorry, what does this mean?
> >
> > On page 9 of the datasheet you sent me [1], it has the delays required to 
> > safely
> > power up the panel. This delay is the time between dvdd going high and avdd
> > going high. On the figure in the datasheet, this would be T2 (T1 is dvdd 
> > rise
> 
> time between dvdd going high and avdd going high is T1 + T3 right?
> 
> T2 > 0ms
> T3 > 20ms
> 
> In this case the delay can be msleep(20) ?

Hmm, yeah, I didn't notice that T3 was > 20ms, that's kind of confusing. So I
think you're right, this should be T2 + T3 > 20ms (T1 is covered in the
regulator_enable of dvdd).

> 
> > time and should be handled in the regulator subsystem (iirc)). Also 
> > according to
> > the datasheet, T2 just needs to be > 0, so you don't even need this delay. 
> > You
> > could replace this with a comment like:
> >
> > /* T1 (dvdd rise time) + T2 (dvdd->avdd) > 0 */
> >
> > So for all of the msleeps below you should get the delays from the 
> > datasheet and
> > add a comment referencing them.
> 
> T5 and T6 are delay between avdd to reset enable it can be 10 + 10
> = 20ms and finally T12 which is 200 after reset.
> 
> What about the delay between resets, I need to understand it a bit.

These are usually accounted for at the end of disable. Take a look at the sleep
parameters in panel-simple for an example.

Sean

-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [PATCH v2 11/12] drm/panel: Add Feiyang FY07024DI26A30-D MIPI-DSI LCD panel

2018-12-13 Thread Sean Paul
On Fri, Dec 14, 2018 at 12:56:03AM +0530, Jagan Teki wrote:
> On Thu, Dec 13, 2018 at 8:37 PM Sean Paul  wrote:
> >
> > On Fri, Nov 16, 2018 at 10:09:15PM +0530, Jagan Teki wrote:
> > > Feiyang FY07024DI26A30-D is 1024x600, 4-lane MIPI-DSI LCD panel.
> > >
> > > Add panel driver for it.
> > >
> > > Signed-off-by: Jagan Teki 
> > > ---
> > >  MAINTAINERS   |   6 +
> > >  drivers/gpu/drm/panel/Kconfig |   9 +
> > >  drivers/gpu/drm/panel/Makefile|   1 +
> > >  .../drm/panel/panel-feiyang-fy07024di26a30d.c | 286 ++
> > >  4 files changed, 302 insertions(+)
> > >  create mode 100644 drivers/gpu/drm/panel/panel-feiyang-fy07024di26a30d.c
> > >

/snip

> > > diff --git a/drivers/gpu/drm/panel/panel-feiyang-fy07024di26a30d.c 
> > > b/drivers/gpu/drm/panel/panel-feiyang-fy07024di26a30d.c
> > > new file mode 100644
> > > index ..a4b46bd8fdbe
> > > --- /dev/null
> > > +++ b/drivers/gpu/drm/panel/panel-feiyang-fy07024di26a30d.c

/snip

> > > +static int feiyang_prepare(struct drm_panel *panel)
> > > +{
> > > + struct feiyang *ctx = panel_to_feiyang(panel);
> > > + struct mipi_dsi_device *dsi = ctx->dsi;
> > > + unsigned int i;
> > > + int ret;
> > > +
> > > + ret = regulator_enable(ctx->dvdd);
> > > + if (ret)
> > > + return ret;
> > > +
> > > + msleep(100);
> >
> > nit: You should do your best to correlate the sleeps with the timing 
> > parameters
> > from the datasheet with a comment.
> >
> > ie:
> > /* T1: > 100ms */
> > msleep(100);
> 
> Sorry, what does this mean?

On page 9 of the datasheet you sent me [1], it has the delays required to safely
power up the panel. This delay is the time between dvdd going high and avdd
going high. On the figure in the datasheet, this would be T2 (T1 is dvdd rise
time and should be handled in the regulator subsystem (iirc)). Also according to
the datasheet, T2 just needs to be > 0, so you don't even need this delay. You
could replace this with a comment like:

/* T1 (dvdd rise time) + T2 (dvdd->avdd) > 0 */

So for all of the msleeps below you should get the delays from the datasheet and
add a comment referencing them.

Sean

[1] - 
http://files.pine64.org/doc/datasheet/pine64/FY07024DI26A30-D_feiyang_LCD_panel.pdf

> 
> >
> > > +
> > > + ret = regulator_enable(ctx->avdd);
> > > + if (ret)
> > > + return ret;
> > > +
> > > + msleep(20);
> > > +
> > > + gpiod_set_value(ctx->reset, 1);
> > > + msleep(50);
> > > +
> > > + gpiod_set_value(ctx->reset, 0);
> > > + msleep(20);
> > > +
> > > + gpiod_set_value(ctx->reset, 1);
> > > + msleep(200);
> > > +
> > > + for (i = 0; i < ARRAY_SIZE(feiyang_init_cmds); i++) {
> > > + const struct feiyang_init_cmd *cmd =
> > > + _init_cmds[i];
> > > +
> > > + ret = mipi_dsi_dcs_write_buffer(dsi, cmd->data, cmd->len);
> >
> > ret = mipi_dsi_dcs_write_buffer(dsi, cmd->data,
> > FEIYANG_INIT_CMD_LEN);
> >
> > > + if (ret < 0)
> > > + return ret;
> > > + }
> > > +
> > > + return 0;
> > > +}
> > > +
> > > +static int feiyang_enable(struct drm_panel *panel)
> > > +{
> > > + struct feiyang *ctx = panel_to_feiyang(panel);
> > > +
> > > + msleep(120);
> > > +
> > > + mipi_dsi_dcs_set_display_on(ctx->dsi);
> > > + backlight_enable(ctx->backlight);
> > > +
> > > + return 0;
> > > +}
> > > +
> > > +static int feiyang_disable(struct drm_panel *panel)
> > > +{
> > > + struct feiyang *ctx = panel_to_feiyang(panel);
> > > +
> > > + backlight_disable(ctx->backlight);
> > > + return mipi_dsi_dcs_set_display_on(ctx->dsi);
> >
> > set_display_on? You probably want set_display_off here :)
> >
> > > +}
> > > +
> > > +static int feiyang_unprepare(struct drm_panel *panel)
> > > +{
> > > + struct feiyang *ctx = panel_to_feiyang(panel);
> > > 

Re: [PATCH v2 11/12] drm/panel: Add Feiyang FY07024DI26A30-D MIPI-DSI LCD panel

2018-12-13 Thread Sean Paul
yang_unprepare,
> + .prepare = feiyang_prepare,
> + .enable = feiyang_enable,
> + .get_modes = feiyang_get_modes,
> +};
> +
> +static int feiyang_dsi_probe(struct mipi_dsi_device *dsi)
> +{
> + struct device_node *np;
> + struct feiyang *ctx;
> + int ret;
> +
> + ctx = devm_kzalloc(>dev, sizeof(*ctx), GFP_KERNEL);
> + if (!ctx)
> + return -ENOMEM;
> + mipi_dsi_set_drvdata(dsi, ctx);
> + ctx->dsi = dsi;
> +
> + drm_panel_init(>panel);
> + ctx->panel.dev = >dev;
> + ctx->panel.funcs = _funcs;
> +
> + ctx->dvdd = devm_regulator_get(>dev, "dvdd");
> + if (IS_ERR(ctx->dvdd)) {
> + DRM_DEV_ERROR(>dev, "Couldn't get dvdd regulator\n");
> + return PTR_ERR(ctx->dvdd);
> + }
> +
> + ctx->avdd = devm_regulator_get(>dev, "avdd");
> + if (IS_ERR(ctx->avdd)) {
> + DRM_DEV_ERROR(>dev, "Couldn't get avdd regulator\n");
> + return PTR_ERR(ctx->avdd);
> + }
> +
> + ctx->reset = devm_gpiod_get(>dev, "reset", GPIOD_OUT_LOW);
> + if (IS_ERR(ctx->reset)) {
> + DRM_DEV_ERROR(>dev, "Couldn't get our reset GPIO\n");
> + return PTR_ERR(ctx->reset);
> + }
> +
> + np = of_parse_phandle(dsi->dev.of_node, "backlight", 0);
> + if (np) {
> + ctx->backlight = of_find_backlight_by_node(np);
> + of_node_put(np);
> +
> + if (!ctx->backlight)
> + return -EPROBE_DEFER;
> + }
> +
> + ret = drm_panel_add(>panel);
> + if (ret < 0)
> + goto put_backlight;
> +
> + dsi->mode_flags = MIPI_DSI_MODE_VIDEO_BURST;
> + dsi->format = MIPI_DSI_FMT_RGB888;
> + dsi->lanes = 4;
> +
> + ret = mipi_dsi_attach(dsi);
> + if (ret < 0)
> + goto panel_remove;
> +
> + return ret;
> +
> +panel_remove:
> + drm_panel_remove(>panel);
> +put_backlight:
> + if (ctx->backlight)
> + put_device(>backlight->dev);
> +
> + return ret;
> +}
> +
> +static int feiyang_dsi_remove(struct mipi_dsi_device *dsi)
> +{
> + struct feiyang *ctx = mipi_dsi_get_drvdata(dsi);
> +
> + mipi_dsi_detach(dsi);
> + drm_panel_remove(>panel);
> +
> + if (ctx->backlight)
> + put_device(>backlight->dev);
> +
> + return 0;
> +}
> +
> +static const struct of_device_id feiyang_of_match[] = {
> + { .compatible = "feiyang,fy07024di26a30d", },
> + { }
> +};
> +MODULE_DEVICE_TABLE(of, feiyang_of_match);
> +
> +static struct mipi_dsi_driver feiyang_driver = {
> + .probe = feiyang_dsi_probe,
> + .remove = feiyang_dsi_remove,
> + .driver = {
> + .name = "feiyang-fy07024di26a30d",
> + .of_match_table = feiyang_of_match,
> + },
> +};
> +module_mipi_dsi_driver(feiyang_driver);
> +
> +MODULE_AUTHOR("Jagan Teki ");
> +MODULE_DESCRIPTION("Feiyang FY07024DI26A30-D MIPI-DSI LCD panel");
> +MODULE_LICENSE("GPL");
> -- 
> 2.18.0.321.gffc6fa0e3
> 

-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [DPU PATCH] drm/msm/dpu: Fix vblank refcount mismatch

2018-12-06 Thread Sean Paul
On Thu, Dec 06, 2018 at 12:16:53PM +0530, Jayant Shekhar wrote:
> _dpu_crtc_vblank_enable_no_lock releases crtc_lock as
> its needed for power handle operations. This opens up a
> window where in a thread running dpu_crtc_disable and a thread
> running dpu_crtc_vblank can race in using dpu_crtc->enabled.

Looks like you're using an old kernel. Both power_handle and
vblank_enable_no_lock were removed.

If you want something more up-to-date for testing, grab the mtp-testing
branch from my dpu-staging tree [1]

Sean

[1]- https://gitlab.freedesktop.org/seanpaul/dpu-staging.git

> 
> dpu_crtc_disable will change the state, where as dpu_crtc_vblank
> use the variable. The fix is to cache the crtc enabled state
> while holding the lock and use it as a gate in calling
> _dpu_crtc_vblank_enable_no_lock.
> 
> This issue was introduced with the commit cf871c48
> (drm/msm/dpu: Remove suspend state tracking from crtc).
> 
> Below are stack traces of thread 1 and thread 2 in good case
> and bad case:
> 
> Bad case:
> -
> Thread 1
> dpu_encoder_phys_vid_control_vblank_irq+0xd0/0x170
> dpu_encoder_register_vblank_callback+0xb8/0x100
> _dpu_crtc_vblank_enable_no_lock+0x240/0x288
> dpu_crtc_disable+0xc4/0x288
> drm_atomic_helper_commit_modeset_disables+0x19c/0x350
> msm_atomic_commit_tail+0x48/0x144
> commit_tail+0x44/0x70
> drm_atomic_helper_commit+0xf0/0xf8
> drm_atomic_commit+0x40/0x4c
> drm_mode_atomic_ioctl+0x374/0x90c
> drm_ioctl_kernel+0xac/0xec
> drm_ioctl+0x218/0x384
> drm_compat_ioctl+0xd8/0xe8
> 
> Thread 2:
> dpu_encoder_phys_vid_control_vblank_irq+0x74/0x170
> dpu_encoder_register_vblank_callback+0xb8/0x100
> _dpu_crtc_vblank_enable_no_lock+0x240/0x288
> dpu_crtc_vblank+0xa8/0x118
> dpu_kms_disable_vblank+0x20/0x2c
> vblank_ctrl_worker+0xa0/0xe0
> kthread_worker_fn+0xe4/0x1a4
> kthread+0x11c/0x12c
> ret_from_fork+0x10/0x18
> 
> Good case:
> --
> Thread 1:
> dpu_encoder_phys_vid_control_vblank_irq+0xd0/0x170
> dpu_encoder_phys_vid_irq_control+0xc8/0x110
> _dpu_encoder_irq_control+0x48/0xa0
> _dpu_encoder_resource_control_helper+0xb4/0x10c
> dpu_encoder_resource_control+0x4e0/0x664
> dpu_encoder_virt_enable+0xb8/0x120
> dpu_kms_encoder_enable+0x34/0xcc
> drm_atomic_helper_commit_modeset_enables+0x120/0x1b8
> msm_atomic_commit_tail+0x5c/0x144
> commit_tail+0x44/0x70
> drm_atomic_helper_commit+0xf0/0xf8
> drm_atomic_commit+0x40/0x4c
> drm_mode_atomic_ioctl+0x374/0x90c
> 
> Thread 2:
> dpu_crtc_vblank+0xc8/0x118
> dpu_kms_disable_vblank+0x20/0x2c
> vblank_ctrl_worker+0xa0/0xe0
> kthread_worker_fn+0xe4/0x1a4
> kthread+0x11c/0x12c
> 
> Signed-off-by: Jayant Shekhar 
> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 17 ++---
>  1 file changed, 14 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> index 630cbaa..e81ad8c 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> @@ -877,6 +877,7 @@ static void dpu_crtc_disable(struct drm_crtc *crtc)
>   struct drm_encoder *encoder;
>   struct msm_drm_private *priv;
>   unsigned long flags;
> + bool crtc_en;
>  
>   if (!crtc || !crtc->dev || !crtc->dev->dev_private || !crtc->state) {
>   DPU_ERROR("invalid crtc\n");
> @@ -901,11 +902,21 @@ static void dpu_crtc_disable(struct drm_crtc *crtc)
>   atomic_read(_crtc->frame_pending));
>  
>   trace_dpu_crtc_disable(DRMID(crtc), false, dpu_crtc);
> - if (dpu_crtc->enabled && dpu_crtc->vblank_requested) {
> - _dpu_crtc_vblank_enable_no_lock(dpu_crtc, false);
> - }
> +
> + /*
> +  * Cache vblank enabled before calling _dpu_crtc_vblank_enable_no_lock,
> +  * because we release crtc_lock inside and acquire it back. While lock
> +  * is released, there are cases where dpu_crtc_vblank comes in between
> +  * while disable is going on. dpu_crtc_vblank further calls
> +  * _dpu_crtc_vblank_enable_no_lock which tries vblank disable again
> +  * resulting in refcount mismatch.
> +  */
> + crtc_en = dpu_crtc->enabled;
>   dpu_crtc->enabled = false;
>  
> + if (crtc_en && dpu_crtc->vblank_requested)
> + _dpu_crtc_vblank_enable_no_lock(dpu_crtc, false);
> +
>   if (atomic_read(_crtc->frame_pending)) {
>   trace_dpu_crtc_disable_frame_pending(DRMID(crtc),
>atomic_read(_crtc->frame_pending));
> -- 
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> a Linux Foundation Collaborative Project
> 

-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [DPU PATCH ] drm/msm/dpu: Fix clock issue after bind failure

2018-12-06 Thread Sean Paul
On Wed, Dec 05, 2018 at 09:51:47PM +0530, Jayant Shekhar wrote:
> In case of msm drm bind failure, pm runtime put sync
> is called from dsi driver which issues an asynchronous
> put on mdss device. Subsequently when dpu_mdss_destroy
> is triggered the change will make sure to put the mdss
> device in suspend and clearing pending work if not
> scheduled.
> 
> Signed-off-by: Jayant Shekhar 

Thanks for sending this, pushed to dpu-staging/for-next

Sean

> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c 
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c
> index 2d66025..030229a 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c
> @@ -191,6 +191,7 @@ static void dpu_mdss_destroy(struct drm_device *dev)
>   struct dss_module_power *mp = _mdss->mp;
>   int i;
>  
> + pm_runtime_suspend(dev->dev);
>   pm_runtime_disable(dev->dev);
>   _dpu_mdss_irq_domain_fini(dpu_mdss);
>   free_irq(platform_get_irq(pdev, 0), dpu_mdss);
> -- 
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> a Linux Foundation Collaborative Project
> 

-- 
Sean Paul, Software Engineer, Google / Chromium OS


[PATCH v2 09/24] drm/msm: dpu: Remove dpu_power_handle

2018-11-16 Thread Sean Paul
From: Sean Paul 

Now that we don't have any event handlers, remove dpu_power_handle!

Changes in v2:
- None

Reviewed-by: Jeykumar Sankaran 
Signed-off-by: Sean Paul 
---
 drivers/gpu/drm/msm/Makefile  |   1 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c   |  11 --
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h   |   3 -
 .../gpu/drm/msm/disp/dpu1/dpu_power_handle.c  | 136 --
 .../gpu/drm/msm/disp/dpu1/dpu_power_handle.h  | 113 ---
 5 files changed, 264 deletions(-)
 delete mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.c
 delete mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.h

diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
index 19ab521d4c3a..7d02ef3655b5 100644
--- a/drivers/gpu/drm/msm/Makefile
+++ b/drivers/gpu/drm/msm/Makefile
@@ -72,7 +72,6 @@ msm-y := \
disp/dpu1/dpu_kms.o \
disp/dpu1/dpu_mdss.o \
disp/dpu1/dpu_plane.o \
-   disp/dpu1/dpu_power_handle.o \
disp/dpu1/dpu_rm.o \
disp/dpu1/dpu_vbif.o \
msm_atomic.o \
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index af666d917a0b..9f7da56bb453 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -1060,8 +1060,6 @@ static int dpu_bind(struct device *dev, struct device 
*master, void *data)
return ret;
}
 
-   dpu_power_resource_init(pdev, _kms->phandle);
-
platform_set_drvdata(pdev, dpu_kms);
 
msm_kms_init(_kms->base, _funcs);
@@ -1081,7 +1079,6 @@ static void dpu_unbind(struct device *dev, struct device 
*master, void *data)
struct dpu_kms *dpu_kms = platform_get_drvdata(pdev);
struct dss_module_power *mp = _kms->mp;
 
-   dpu_power_resource_deinit(pdev, _kms->phandle);
msm_dss_put_clk(mp->clk_config, mp->num_clk);
devm_kfree(>dev, mp->clk_config);
mp->num_clk = 0;
@@ -1120,10 +1117,6 @@ static int __maybe_unused dpu_runtime_suspend(struct 
device *dev)
return rc;
}
 
-   rc = dpu_power_resource_enable(_kms->phandle, false);
-   if (rc)
-   DPU_ERROR("resource disable failed: %d\n", rc);
-
rc = msm_dss_enable_clk(mp->clk_config, mp->num_clk, false);
if (rc)
DPU_ERROR("clock disable failed rc:%d\n", rc);
@@ -1157,10 +1150,6 @@ static int __maybe_unused dpu_runtime_resume(struct 
device *dev)
drm_for_each_crtc(crtc, ddev)
dpu_crtc_runtime_resume(crtc);
 
-   rc = dpu_power_resource_enable(_kms->phandle, true);
-   if (rc)
-   DPU_ERROR("resource enable failed: %d\n", rc);
-
return rc;
 }
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
index 4e5acacb3065..59e18e2d3c59 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
@@ -31,7 +31,6 @@
 #include "dpu_hw_top.h"
 #include "dpu_io_util.h"
 #include "dpu_rm.h"
-#include "dpu_power_handle.h"
 #include "dpu_irq.h"
 #include "dpu_core_perf.h"
 
@@ -114,8 +113,6 @@ struct dpu_kms {
int core_rev;
struct dpu_mdss_cfg *catalog;
 
-   struct dpu_power_handle phandle;
-
/* directory entry for debugfs */
struct dentry *debugfs_root;
struct dentry *debugfs_danger;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.c
deleted file mode 100644
index 8e64f0a52147..
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-
-#define pr_fmt(fmt)"[drm:%s:%d]: " fmt, __func__, __LINE__
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-
-#include "dpu_power_handle.h"
-#include "dpu_trace.h"
-
-static void dpu_power_event_trigger_locked(struct dpu_power_handle *phandle,
-   u32 event_type)
-{
-   struct dpu_power_event *event;
-
-   list_for_each_entry(event, >event_list, list) {
-   if (event->event_type & event_type)
-   event->cb_fnc(event_type, event->usr);
-   }
-}
-
-void dpu_power_resource_init(struct platform

[PATCH v2 09/24] drm/msm: dpu: Remove dpu_power_handle

2018-11-16 Thread Sean Paul
From: Sean Paul 

Now that we don't have any event handlers, remove dpu_power_handle!

Changes in v2:
- None

Reviewed-by: Jeykumar Sankaran 
Signed-off-by: Sean Paul 
---
 drivers/gpu/drm/msm/Makefile  |   1 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c   |  11 --
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h   |   3 -
 .../gpu/drm/msm/disp/dpu1/dpu_power_handle.c  | 136 --
 .../gpu/drm/msm/disp/dpu1/dpu_power_handle.h  | 113 ---
 5 files changed, 264 deletions(-)
 delete mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.c
 delete mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.h

diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
index 19ab521d4c3a..7d02ef3655b5 100644
--- a/drivers/gpu/drm/msm/Makefile
+++ b/drivers/gpu/drm/msm/Makefile
@@ -72,7 +72,6 @@ msm-y := \
disp/dpu1/dpu_kms.o \
disp/dpu1/dpu_mdss.o \
disp/dpu1/dpu_plane.o \
-   disp/dpu1/dpu_power_handle.o \
disp/dpu1/dpu_rm.o \
disp/dpu1/dpu_vbif.o \
msm_atomic.o \
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index af666d917a0b..9f7da56bb453 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -1060,8 +1060,6 @@ static int dpu_bind(struct device *dev, struct device 
*master, void *data)
return ret;
}
 
-   dpu_power_resource_init(pdev, _kms->phandle);
-
platform_set_drvdata(pdev, dpu_kms);
 
msm_kms_init(_kms->base, _funcs);
@@ -1081,7 +1079,6 @@ static void dpu_unbind(struct device *dev, struct device 
*master, void *data)
struct dpu_kms *dpu_kms = platform_get_drvdata(pdev);
struct dss_module_power *mp = _kms->mp;
 
-   dpu_power_resource_deinit(pdev, _kms->phandle);
msm_dss_put_clk(mp->clk_config, mp->num_clk);
devm_kfree(>dev, mp->clk_config);
mp->num_clk = 0;
@@ -1120,10 +1117,6 @@ static int __maybe_unused dpu_runtime_suspend(struct 
device *dev)
return rc;
}
 
-   rc = dpu_power_resource_enable(_kms->phandle, false);
-   if (rc)
-   DPU_ERROR("resource disable failed: %d\n", rc);
-
rc = msm_dss_enable_clk(mp->clk_config, mp->num_clk, false);
if (rc)
DPU_ERROR("clock disable failed rc:%d\n", rc);
@@ -1157,10 +1150,6 @@ static int __maybe_unused dpu_runtime_resume(struct 
device *dev)
drm_for_each_crtc(crtc, ddev)
dpu_crtc_runtime_resume(crtc);
 
-   rc = dpu_power_resource_enable(_kms->phandle, true);
-   if (rc)
-   DPU_ERROR("resource enable failed: %d\n", rc);
-
return rc;
 }
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
index 4e5acacb3065..59e18e2d3c59 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
@@ -31,7 +31,6 @@
 #include "dpu_hw_top.h"
 #include "dpu_io_util.h"
 #include "dpu_rm.h"
-#include "dpu_power_handle.h"
 #include "dpu_irq.h"
 #include "dpu_core_perf.h"
 
@@ -114,8 +113,6 @@ struct dpu_kms {
int core_rev;
struct dpu_mdss_cfg *catalog;
 
-   struct dpu_power_handle phandle;
-
/* directory entry for debugfs */
struct dentry *debugfs_root;
struct dentry *debugfs_danger;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.c
deleted file mode 100644
index 8e64f0a52147..
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-
-#define pr_fmt(fmt)"[drm:%s:%d]: " fmt, __func__, __LINE__
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-
-#include "dpu_power_handle.h"
-#include "dpu_trace.h"
-
-static void dpu_power_event_trigger_locked(struct dpu_power_handle *phandle,
-   u32 event_type)
-{
-   struct dpu_power_event *event;
-
-   list_for_each_entry(event, >event_list, list) {
-   if (event->event_type & event_type)
-   event->cb_fnc(event_type, event->usr);
-   }
-}
-
-void dpu_power_resource_init(struct platform

Re: [PATCH 4/6] drm/bridge: ti-sn65dsi86: Remove the mystery delay

2018-10-25 Thread Sean Paul
On Mon, Oct 22, 2018 at 01:46:37PM -0700, Douglas Anderson wrote:
> Let's solve the mystery of commit bf1178c98930 ("drm/bridge:
> ti-sn65dsi86: Add mystery delay to enable()").  Specifically the
> reason we needed that mystery delay is that we weren't paying
> attention to HPD.
> 
> Looking at the datasheet for the same panel that was tested for the
> original commit, I see there's a timing "t3" that times from power on
> to the aux channel being operational.  This time is specced as 0 - 200
> ms.  The datasheet says that the aux channel is operational at exactly
> the same time that HPD is asserted.
> 
> Scoping the signals on this board showed that HPD was asserted 84 ms
> after power was asserted.  That very closely matches the magic 70 ms
> delay that we had.  ...and actually, in my testing the 70 ms wasn't
> quite enough of a delay and some percentage of the time the display
> didn't come up until I bumped it to 100 ms (presumably 84 ms would
> have worked too).
> 
> To solve this, we tried to hook up the HPD signal in the bridge.
> ...but in doing so we found that that the bridge didn't report that
> HPD was asserted until ~280 ms after we powered it (!).  This is
> explained by looking at the sn65dsi86 datasheet section "8.4.5.1 HPD
> (Hot Plug/Unplug Detection)".  Reading there we see that the bridge
> isn't even intended to report HPD until 100 ms after it's asserted.
> ...but that would have left us at 184 ms.  The extra 100 ms
> (presumably) comes from this part in the datasheet:
> 
> > The HPD state machine operates off an internal ring oscillator. The
> > ring oscillator frequency will vary [ ... ]. The min/max range in
> > the HPD State Diagram refers to the possible times based off
> > variation in the ring oscillator frequency.
> 
> Given that the 280 ms we'll end up delaying if we hook up HPD is
> _slower_ than the 200 ms we could just hardcode, for now we'll solve
> the problem by just hardcoding a 200 ms delay in the panel driver
> using the patch in this series ("drm/panel: simple: Support panels
> with HPD where HPD isn't connected").
> 
> If we later find a panel that needs to use this bridge where we need
> HPD then we'll have to come up with some new code to handle it.  Given
> the silly debouncing in the bridge chip, though, it seems unlikely.
> 
> One last note is that I tried to solve this through another way: In
> ti_sn_bridge_enable() I tried to use various combinations of
> dp_dpcd_writeb() and dp_dpcd_readb() to detect when the aux channel
> was up.  In theory that would let me detect _exactly_ when I could
> continue and do link training.  Unfortunately even if I did an aux
> transfer w/out waiting I couldn't see any errors.  Possibly I could
> keep looping over link training until it came back with success, but
> that seemed a little overly hacky to me.
> 
> Signed-off-by: Douglas Anderson 

Awesome commit message and comment, thanks for solving the mystery!

Reviewed-by: Sean Paul 


> ---
> 
>  drivers/gpu/drm/bridge/ti-sn65dsi86.c | 29 +++
>  1 file changed, 16 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c 
> b/drivers/gpu/drm/bridge/ti-sn65dsi86.c
> index f8a931cf3665..680566d97adc 100644
> --- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c
> +++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c
> @@ -458,18 +458,6 @@ static void ti_sn_bridge_enable(struct drm_bridge 
> *bridge)
>   unsigned int val;
>   int ret;
>  
> - /*
> -  * FIXME:
> -  * This 70ms was found necessary by experimentation. If it's not
> -  * present, link training fails. It seems like it can go anywhere from
> -  * pre_enable() up to semi-auto link training initiation below.
> -  *
> -  * Neither the datasheet for the bridge nor the panel tested mention a
> -  * delay of this magnitude in the timing requirements. So for now, add
> -  * the mystery delay until someone figures out a better fix.
> -  */
> - msleep(70);
> -
>   /* DSI_A lane config */
>   val = CHA_DSI_LANES(4 - pdata->dsi->lanes);
>   regmap_update_bits(pdata->regmap, SN_DSI_LANES_REG,
> @@ -536,7 +524,22 @@ static void ti_sn_bridge_pre_enable(struct drm_bridge 
> *bridge)
>   /* configure bridge ref_clk */
>   ti_sn_bridge_set_refclk_freq(pdata);
>  
> - /* in case drm_panel is connected then HPD is not supported */
> + /*
> +  * HPD on this bridge chip is a bit useless.  This is an eDP bridge
> +  * so the HPD is an internal signal that's only there to signal that
> +  * the panel is done powering up.  ...but the bridge chip debounces
> +  * this sign

Re: [PATCH 4/6] drm/bridge: ti-sn65dsi86: Remove the mystery delay

2018-10-25 Thread Sean Paul
On Mon, Oct 22, 2018 at 01:46:37PM -0700, Douglas Anderson wrote:
> Let's solve the mystery of commit bf1178c98930 ("drm/bridge:
> ti-sn65dsi86: Add mystery delay to enable()").  Specifically the
> reason we needed that mystery delay is that we weren't paying
> attention to HPD.
> 
> Looking at the datasheet for the same panel that was tested for the
> original commit, I see there's a timing "t3" that times from power on
> to the aux channel being operational.  This time is specced as 0 - 200
> ms.  The datasheet says that the aux channel is operational at exactly
> the same time that HPD is asserted.
> 
> Scoping the signals on this board showed that HPD was asserted 84 ms
> after power was asserted.  That very closely matches the magic 70 ms
> delay that we had.  ...and actually, in my testing the 70 ms wasn't
> quite enough of a delay and some percentage of the time the display
> didn't come up until I bumped it to 100 ms (presumably 84 ms would
> have worked too).
> 
> To solve this, we tried to hook up the HPD signal in the bridge.
> ...but in doing so we found that that the bridge didn't report that
> HPD was asserted until ~280 ms after we powered it (!).  This is
> explained by looking at the sn65dsi86 datasheet section "8.4.5.1 HPD
> (Hot Plug/Unplug Detection)".  Reading there we see that the bridge
> isn't even intended to report HPD until 100 ms after it's asserted.
> ...but that would have left us at 184 ms.  The extra 100 ms
> (presumably) comes from this part in the datasheet:
> 
> > The HPD state machine operates off an internal ring oscillator. The
> > ring oscillator frequency will vary [ ... ]. The min/max range in
> > the HPD State Diagram refers to the possible times based off
> > variation in the ring oscillator frequency.
> 
> Given that the 280 ms we'll end up delaying if we hook up HPD is
> _slower_ than the 200 ms we could just hardcode, for now we'll solve
> the problem by just hardcoding a 200 ms delay in the panel driver
> using the patch in this series ("drm/panel: simple: Support panels
> with HPD where HPD isn't connected").
> 
> If we later find a panel that needs to use this bridge where we need
> HPD then we'll have to come up with some new code to handle it.  Given
> the silly debouncing in the bridge chip, though, it seems unlikely.
> 
> One last note is that I tried to solve this through another way: In
> ti_sn_bridge_enable() I tried to use various combinations of
> dp_dpcd_writeb() and dp_dpcd_readb() to detect when the aux channel
> was up.  In theory that would let me detect _exactly_ when I could
> continue and do link training.  Unfortunately even if I did an aux
> transfer w/out waiting I couldn't see any errors.  Possibly I could
> keep looping over link training until it came back with success, but
> that seemed a little overly hacky to me.
> 
> Signed-off-by: Douglas Anderson 

Awesome commit message and comment, thanks for solving the mystery!

Reviewed-by: Sean Paul 


> ---
> 
>  drivers/gpu/drm/bridge/ti-sn65dsi86.c | 29 +++
>  1 file changed, 16 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c 
> b/drivers/gpu/drm/bridge/ti-sn65dsi86.c
> index f8a931cf3665..680566d97adc 100644
> --- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c
> +++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c
> @@ -458,18 +458,6 @@ static void ti_sn_bridge_enable(struct drm_bridge 
> *bridge)
>   unsigned int val;
>   int ret;
>  
> - /*
> -  * FIXME:
> -  * This 70ms was found necessary by experimentation. If it's not
> -  * present, link training fails. It seems like it can go anywhere from
> -  * pre_enable() up to semi-auto link training initiation below.
> -  *
> -  * Neither the datasheet for the bridge nor the panel tested mention a
> -  * delay of this magnitude in the timing requirements. So for now, add
> -  * the mystery delay until someone figures out a better fix.
> -  */
> - msleep(70);
> -
>   /* DSI_A lane config */
>   val = CHA_DSI_LANES(4 - pdata->dsi->lanes);
>   regmap_update_bits(pdata->regmap, SN_DSI_LANES_REG,
> @@ -536,7 +524,22 @@ static void ti_sn_bridge_pre_enable(struct drm_bridge 
> *bridge)
>   /* configure bridge ref_clk */
>   ti_sn_bridge_set_refclk_freq(pdata);
>  
> - /* in case drm_panel is connected then HPD is not supported */
> + /*
> +  * HPD on this bridge chip is a bit useless.  This is an eDP bridge
> +  * so the HPD is an internal signal that's only there to signal that
> +  * the panel is done powering up.  ...but the bridge chip debounces
> +  * this sign

Re: [PATCH 4.18 74/88] drm/atomic: Use drm_drv_uses_atomic_modeset() for debugfs creation

2018-09-27 Thread Sean Paul
On Thu, Sep 27, 2018 at 03:53:26PM +0200, Holger Hoffstätte wrote:
> On 09/27/18 15:26, Holger Hoffstätte wrote:
> > On 09/27/18 14:37, Greg Kroah-Hartman wrote:
> > > On Thu, Sep 27, 2018 at 12:43:33PM +0200, Holger Hoffstätte wrote:
> > > > On 09/27/18 11:03, Greg Kroah-Hartman wrote:
> > > > > 4.18-stable review patch.  If anyone has any objections, please let 
> > > > > me know.
> > > > > 
> > > > > --
> > > > > 
> > > > > From: Lyude Paul 
> > > > > 
> > > > > commit 3c499ea0c662e2f38aafbd4f516b08aab8cfa0e5 upstream.
> > > > > 
> > > > > As pointed out by Daniel Vetter, we should be usinng
> > > > > drm_drv_uses_atomic_modeset() for determining whether or not we want 
> > > > > to
> > > > > make the debugfs nodes for atomic instead of checking DRIVER_ATOMIC, 
> > > > > as
> > > > > the former isn't an accurate representation of whether or not the 
> > > > > driver
> > > > > is actually using atomic modesetting internally (even though it might
> > > > > not be exposing atomic capabilities).
> > > > > 
> > > > > Signed-off-by: Lyude Paul 
> > > > > Cc: Daniel Vetter 
> > > > > Cc: sta...@vger.kernel.org
> > > > > Reviewed-by: Sean Paul 
> > > > > Link: 
> > > > > https://patchwork.freedesktop.org/patch/msgid/20180917173733.21293-1-ly...@redhat.com
> > > > > Signed-off-by: Greg Kroah-Hartman 
> > > > 
> > > > This patch breaks switching the console to high resolution during boot 
> > > > on my
> > > > workstation with a Radeon card; it worked fine with 4.18.10 and 
> > > > reverting it
> > > > fixes the problem:
> > > 
> > > Is 4.19-rc5 also a problem?
> > > 
> > 
> > No, 4.19-rc5 with the same config works fine and properly switches the
> > console during boot.
> > 
> > Interestingly another machine with i915 chip seemed to work fine with this
> > patch included (rebooted that one first), so it might well be related to
> > different motherboard/chipset or the Radeon card (an admittedly old, but
> > otherwise completely functional fanless r600).
> > 
> > I'll try to find more clues, but for now that's all I got.
> 
> Looking at mainline include/drm I see several recent movements and cleanups
> related to drm_drv_uses_atomic_modeset(), moving it out of drmP.h and into
> drm, changes to atomic modesetting and such, all part of the 4.19 merge
> window. I'm reasonably sure some relatred changes went missing here wrt.
> this patch.

Hey all,
Thanks for testing, Holger.

This was fixed with https://patchwork.freedesktop.org/patch/250350/ which is not
Cc stable.

I think it'd be best to just drop the initial patch from stable, it
doesn't need to go back afaict.

Sean

> 
> -h

-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [PATCH 4.18 74/88] drm/atomic: Use drm_drv_uses_atomic_modeset() for debugfs creation

2018-09-27 Thread Sean Paul
On Thu, Sep 27, 2018 at 03:53:26PM +0200, Holger Hoffstätte wrote:
> On 09/27/18 15:26, Holger Hoffstätte wrote:
> > On 09/27/18 14:37, Greg Kroah-Hartman wrote:
> > > On Thu, Sep 27, 2018 at 12:43:33PM +0200, Holger Hoffstätte wrote:
> > > > On 09/27/18 11:03, Greg Kroah-Hartman wrote:
> > > > > 4.18-stable review patch.  If anyone has any objections, please let 
> > > > > me know.
> > > > > 
> > > > > --
> > > > > 
> > > > > From: Lyude Paul 
> > > > > 
> > > > > commit 3c499ea0c662e2f38aafbd4f516b08aab8cfa0e5 upstream.
> > > > > 
> > > > > As pointed out by Daniel Vetter, we should be usinng
> > > > > drm_drv_uses_atomic_modeset() for determining whether or not we want 
> > > > > to
> > > > > make the debugfs nodes for atomic instead of checking DRIVER_ATOMIC, 
> > > > > as
> > > > > the former isn't an accurate representation of whether or not the 
> > > > > driver
> > > > > is actually using atomic modesetting internally (even though it might
> > > > > not be exposing atomic capabilities).
> > > > > 
> > > > > Signed-off-by: Lyude Paul 
> > > > > Cc: Daniel Vetter 
> > > > > Cc: sta...@vger.kernel.org
> > > > > Reviewed-by: Sean Paul 
> > > > > Link: 
> > > > > https://patchwork.freedesktop.org/patch/msgid/20180917173733.21293-1-ly...@redhat.com
> > > > > Signed-off-by: Greg Kroah-Hartman 
> > > > 
> > > > This patch breaks switching the console to high resolution during boot 
> > > > on my
> > > > workstation with a Radeon card; it worked fine with 4.18.10 and 
> > > > reverting it
> > > > fixes the problem:
> > > 
> > > Is 4.19-rc5 also a problem?
> > > 
> > 
> > No, 4.19-rc5 with the same config works fine and properly switches the
> > console during boot.
> > 
> > Interestingly another machine with i915 chip seemed to work fine with this
> > patch included (rebooted that one first), so it might well be related to
> > different motherboard/chipset or the Radeon card (an admittedly old, but
> > otherwise completely functional fanless r600).
> > 
> > I'll try to find more clues, but for now that's all I got.
> 
> Looking at mainline include/drm I see several recent movements and cleanups
> related to drm_drv_uses_atomic_modeset(), moving it out of drmP.h and into
> drm, changes to atomic modesetting and such, all part of the 4.19 merge
> window. I'm reasonably sure some relatred changes went missing here wrt.
> this patch.

Hey all,
Thanks for testing, Holger.

This was fixed with https://patchwork.freedesktop.org/patch/250350/ which is not
Cc stable.

I think it'd be best to just drop the initial patch from stable, it
doesn't need to go back afaict.

Sean

> 
> -h

-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [lkp-robot] [fs] 3deb642f0d: will-it-scale.per_process_ops -8.8% regression

2018-06-22 Thread Sean Paul
On Fri, Jun 22, 2018 at 7:01 AM Al Viro  wrote:
>
> On Fri, Jun 22, 2018 at 12:00:14PM +0200, Christoph Hellwig wrote:
> > And a version with select() also covered:
>
> For fuck sake, if you want vfs_poll() inlined, *make* *it* *inlined*.
> Is there any reason for not doing that other than EXPORT_SYMBOL_GPL
> fetish?  Because if there isn't, I would like to draw your attention
> to the fact that _this_ pwecious inchewlekshul pwopewty can be trivially
> open-coded by out-of-tree shite even if it happens to be non-GPL one.
>

Was this suggestion so bad that you have to insult not only the
author, but also people with speech impediments?

Sean


> >   mask = vfs_poll(f.file, wait);
> > + if (f.file->f_op->poll) {
>
> ... not to mention that here you forgot to remove the call itself while
> expanding it.
>
> Said that, you are not attacking the worst part of it - it's a static
> branch, not the considerably more costly indirect ones.  Remember when
> I asked you about the price of those?  Method calls are costly.
>
> Another problem with with ->get_poll_head() calling conventions is
> that originally you wanted to return ERR_PTR(-mask) as a way to report
> not needing to call ->poll_mask(); that got shot down since quite
> a few of those don't fit into 12 bits that ERR_PTR() gives us.
>
> IIRC, the real reason for non-constant ->get_poll_head() was the sockets,
> with
>
> static struct wait_queue_head *sock_get_poll_head(struct file *file,
> __poll_t events)
> {
> struct socket *sock = file->private_data;
>
> if (!sock->ops->poll_mask)
> return NULL;
> sock_poll_busy_loop(sock, events);
> return sk_sleep(sock->sk);
> }
>
> The first part isn't a problem (it is constant).  The second is
> static inline void sock_poll_busy_loop(struct socket *sock, __poll_t events)
> {
> if (sk_can_busy_loop(sock->sk) &&
> events && (events & POLL_BUSY_LOOP)) {
> /* once, only if requested by syscall */
> sk_busy_loop(sock->sk, 1);
> }
> }
>
> and the third -
>
> static inline wait_queue_head_t *sk_sleep(struct sock *sk)
> {
> BUILD_BUG_ON(offsetof(struct socket_wq, wait) != 0);
> return _dereference_raw(sk->sk_wq)->wait;
> }
>
> Now, ->sk_wq is modified only in sock_init_data() and sock_graft();
> the latter, IIRC, is ->accept() helper.  Do we ever call either of
> those on a sock of already opened file?  IOW, is there any real
> reason for socket ->get_poll_head() not to be constant, other
> than wanting to keep POLL_BUSY_LOOP handling out of ->poll_mask()?
> I agree that POLL_BUSY_LOOP is ugly as hell, but you *still* have
> sock_poll_mask() not free from it...


Re: [lkp-robot] [fs] 3deb642f0d: will-it-scale.per_process_ops -8.8% regression

2018-06-22 Thread Sean Paul
On Fri, Jun 22, 2018 at 7:01 AM Al Viro  wrote:
>
> On Fri, Jun 22, 2018 at 12:00:14PM +0200, Christoph Hellwig wrote:
> > And a version with select() also covered:
>
> For fuck sake, if you want vfs_poll() inlined, *make* *it* *inlined*.
> Is there any reason for not doing that other than EXPORT_SYMBOL_GPL
> fetish?  Because if there isn't, I would like to draw your attention
> to the fact that _this_ pwecious inchewlekshul pwopewty can be trivially
> open-coded by out-of-tree shite even if it happens to be non-GPL one.
>

Was this suggestion so bad that you have to insult not only the
author, but also people with speech impediments?

Sean


> >   mask = vfs_poll(f.file, wait);
> > + if (f.file->f_op->poll) {
>
> ... not to mention that here you forgot to remove the call itself while
> expanding it.
>
> Said that, you are not attacking the worst part of it - it's a static
> branch, not the considerably more costly indirect ones.  Remember when
> I asked you about the price of those?  Method calls are costly.
>
> Another problem with with ->get_poll_head() calling conventions is
> that originally you wanted to return ERR_PTR(-mask) as a way to report
> not needing to call ->poll_mask(); that got shot down since quite
> a few of those don't fit into 12 bits that ERR_PTR() gives us.
>
> IIRC, the real reason for non-constant ->get_poll_head() was the sockets,
> with
>
> static struct wait_queue_head *sock_get_poll_head(struct file *file,
> __poll_t events)
> {
> struct socket *sock = file->private_data;
>
> if (!sock->ops->poll_mask)
> return NULL;
> sock_poll_busy_loop(sock, events);
> return sk_sleep(sock->sk);
> }
>
> The first part isn't a problem (it is constant).  The second is
> static inline void sock_poll_busy_loop(struct socket *sock, __poll_t events)
> {
> if (sk_can_busy_loop(sock->sk) &&
> events && (events & POLL_BUSY_LOOP)) {
> /* once, only if requested by syscall */
> sk_busy_loop(sock->sk, 1);
> }
> }
>
> and the third -
>
> static inline wait_queue_head_t *sk_sleep(struct sock *sk)
> {
> BUILD_BUG_ON(offsetof(struct socket_wq, wait) != 0);
> return _dereference_raw(sk->sk_wq)->wait;
> }
>
> Now, ->sk_wq is modified only in sock_init_data() and sock_graft();
> the latter, IIRC, is ->accept() helper.  Do we ever call either of
> those on a sock of already opened file?  IOW, is there any real
> reason for socket ->get_poll_head() not to be constant, other
> than wanting to keep POLL_BUSY_LOOP handling out of ->poll_mask()?
> I agree that POLL_BUSY_LOOP is ugly as hell, but you *still* have
> sock_poll_mask() not free from it...


Re: [PATCH v2 1/5] media: cec-notifier: Get notifier by device and connector name

2018-05-18 Thread Sean Paul
 void cec_register_cec_notifier(struct 
> cec_adapter *adap,
>  #endif
>  
>  /**
> + * cec_notifier_get - find or create a new cec_notifier for the given device.
> + * @dev: device that sends the events.
> + *
> + * If a notifier for device @dev already exists, then increase the refcount
> + * and return that notifier.
> + *
> + * If it doesn't exist, then allocate a new notifier struct and return a
> + * pointer to that new struct.

You might also want to cover the case where you have multiple named notifiers
for the same device. It looks like it just grabs the first one?

Sean

> + *
> + * Return NULL if the memory could not be allocated.
> + */
> +static inline struct cec_notifier *cec_notifier_get(struct device *dev)
> +{
> + return cec_notifier_get_conn(dev, NULL);
> +}
> +
> +/**
>   * cec_notifier_phys_addr_invalidate() - set the physical address to INVALID
>   *
>   * @n: the CEC notifier
> -- 
> 2.7.4
> 

-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [PATCH v2 1/5] media: cec-notifier: Get notifier by device and connector name

2018-05-18 Thread Sean Paul
_notifier(struct 
> cec_adapter *adap,
>  #endif
>  
>  /**
> + * cec_notifier_get - find or create a new cec_notifier for the given device.
> + * @dev: device that sends the events.
> + *
> + * If a notifier for device @dev already exists, then increase the refcount
> + * and return that notifier.
> + *
> + * If it doesn't exist, then allocate a new notifier struct and return a
> + * pointer to that new struct.

You might also want to cover the case where you have multiple named notifiers
for the same device. It looks like it just grabs the first one?

Sean

> + *
> + * Return NULL if the memory could not be allocated.
> + */
> +static inline struct cec_notifier *cec_notifier_get(struct device *dev)
> +{
> + return cec_notifier_get_conn(dev, NULL);
> +}
> +
> +/**
>   * cec_notifier_phys_addr_invalidate() - set the physical address to INVALID
>   *
>   * @n: the CEC notifier
> -- 
> 2.7.4
> 

-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [PATCH v5 4/4] drm/rockchip: support dp training outside dp firmware

2018-05-18 Thread Sean Paul
On Fri, May 18, 2018 at 10:52:17AM +0200, Heiko Stuebner wrote:
> Am Freitag, 18. Mai 2018, 03:45:46 CEST schrieb Brian Norris:
> > On Thu, May 17, 2018 at 6:41 PM, hl <h...@rock-chips.com> wrote:
> > > On Thursday, May 17, 2018 09:51 PM, Sean Paul wrote:
> > >> On Thu, May 17, 2018 at 05:18:00PM +0800, Lin Huang wrote:
> > >>> DP firmware uses fixed phy config values to do training, but some
> > >>> boards need to adjust these values to fit for their unique hardware
> > >>> design. So get phy config values from dts and use software link training
> > >>> instead of relying on firmware, if software training fail, keep firmware
> > >>> training as a fallback if sw training fails.
> > >>>
> > >>> Signed-off-by: Chris Zhong <z...@rock-chips.com>
> > >>> Signed-off-by: Lin Huang <h...@rock-chips.com>
> > >>> ---
> > >>> Changes in v2:
> > >>> - update patch following Enric suggest
> > >>> Changes in v3:
> > >>> - use variable fw_training instead sw_training_success
> > >>> - base on DP SPCE, if training fail use lower link rate to retry 
> > >>> training
> > >>> Changes in v4:
> > >>> - improve cdn_dp_get_lower_link_rate() and cdn_dp_software_train_link() 
> > >>> follow Sean suggest
> > >>> Changes in v5:
> > >>> - fix some whitespcae issue
> > >>>
> > >>>   drivers/gpu/drm/rockchip/Makefile   |   3 +-
> > >>>   drivers/gpu/drm/rockchip/cdn-dp-core.c  |  24 +-
> > >>>   drivers/gpu/drm/rockchip/cdn-dp-core.h  |   2 +
> > >>>   drivers/gpu/drm/rockchip/cdn-dp-link-training.c | 420 
> > >>> 
> > >>>   drivers/gpu/drm/rockchip/cdn-dp-reg.c   |  31 +-
> > >>>   drivers/gpu/drm/rockchip/cdn-dp-reg.h   |  38 ++-
> > >>>   6 files changed, 505 insertions(+), 13 deletions(-)
> > >>>   create mode 100644 drivers/gpu/drm/rockchip/cdn-dp-link-training.c
> > >>>
> > ...
> > >>> diff --git a/drivers/gpu/drm/rockchip/cdn-dp-link-training.c 
> > >>> b/drivers/gpu/drm/rockchip/cdn-dp-link-training.c
> > >>> new file mode 100644
> > >>> index 000..73c3290
> > >>> --- /dev/null
> > >>> +++ b/drivers/gpu/drm/rockchip/cdn-dp-link-training.c
> > >>> @@ -0,0 +1,420 @@
> > >>> +// SPDX-License-Identifier: GPL-2.0
> > >>> +/*
> > >>> + * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
> > >>> + * Author: Chris Zhong <z...@rock-chips.com>
> > >>> + */
> > >>> +
> > >>> +#include 
> > >>> +#include 
> > >>> +#include 
> > >>> +#include 
> > >>> +
> > >>> +#include "cdn-dp-core.h"
> > >>> +#include "cdn-dp-reg.h"
> > >>> +
> > >>> +static void cdn_dp_set_signal_levels(struct cdn_dp_device *dp)
> > >>> +{
> > >>> +   struct cdn_dp_port *port = dp->port[dp->active_port];
> > >>> +   struct rockchip_typec_phy *tcphy = phy_get_drvdata(port->phy);
> > >>
> > >> You ignored Brian's comment on the previous patch:
> > >>This is still antithetical to the PHY framework; you're assuming that
> > >>this is a particular type of PHY here.
> > >>
> > >> FWIW, the mediatek drm driver also assumes a certain PHY type. A quick 
> > >> grep of
> > >> drivers/ shows that the only other non-phy/ driver using this function
> > >> (pinctrl-tegra-xusb.c) also casts it.
> > >>
> > >> Sean
> > >
> > > Thanks Sean, except phy framework have new API to handle it, i have not
> > > idea how to do it in a better way.
> > 
> > Well, if Mediatek can do it for their MIPI and HDMI, then maybe we just do 
> > it...
> 
> I'd think so too. This is in Rockchip-specific code so it will always be
> possible to easily get the soc-type and thus phy-type, if that combination
> really changes down the road.
> 

So in the absence of a better solution, and with prior art,

Reviewed-by: Sean Paul <seanp...@chromium.org>


We just need some eyes on the dt and phy changes in this set. Heiko, can you
help out with that?

Sean

> 
> Heiko
> 
> 

-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [PATCH v5 4/4] drm/rockchip: support dp training outside dp firmware

2018-05-18 Thread Sean Paul
On Fri, May 18, 2018 at 10:52:17AM +0200, Heiko Stuebner wrote:
> Am Freitag, 18. Mai 2018, 03:45:46 CEST schrieb Brian Norris:
> > On Thu, May 17, 2018 at 6:41 PM, hl  wrote:
> > > On Thursday, May 17, 2018 09:51 PM, Sean Paul wrote:
> > >> On Thu, May 17, 2018 at 05:18:00PM +0800, Lin Huang wrote:
> > >>> DP firmware uses fixed phy config values to do training, but some
> > >>> boards need to adjust these values to fit for their unique hardware
> > >>> design. So get phy config values from dts and use software link training
> > >>> instead of relying on firmware, if software training fail, keep firmware
> > >>> training as a fallback if sw training fails.
> > >>>
> > >>> Signed-off-by: Chris Zhong 
> > >>> Signed-off-by: Lin Huang 
> > >>> ---
> > >>> Changes in v2:
> > >>> - update patch following Enric suggest
> > >>> Changes in v3:
> > >>> - use variable fw_training instead sw_training_success
> > >>> - base on DP SPCE, if training fail use lower link rate to retry 
> > >>> training
> > >>> Changes in v4:
> > >>> - improve cdn_dp_get_lower_link_rate() and cdn_dp_software_train_link() 
> > >>> follow Sean suggest
> > >>> Changes in v5:
> > >>> - fix some whitespcae issue
> > >>>
> > >>>   drivers/gpu/drm/rockchip/Makefile   |   3 +-
> > >>>   drivers/gpu/drm/rockchip/cdn-dp-core.c  |  24 +-
> > >>>   drivers/gpu/drm/rockchip/cdn-dp-core.h  |   2 +
> > >>>   drivers/gpu/drm/rockchip/cdn-dp-link-training.c | 420 
> > >>> 
> > >>>   drivers/gpu/drm/rockchip/cdn-dp-reg.c   |  31 +-
> > >>>   drivers/gpu/drm/rockchip/cdn-dp-reg.h   |  38 ++-
> > >>>   6 files changed, 505 insertions(+), 13 deletions(-)
> > >>>   create mode 100644 drivers/gpu/drm/rockchip/cdn-dp-link-training.c
> > >>>
> > ...
> > >>> diff --git a/drivers/gpu/drm/rockchip/cdn-dp-link-training.c 
> > >>> b/drivers/gpu/drm/rockchip/cdn-dp-link-training.c
> > >>> new file mode 100644
> > >>> index 000..73c3290
> > >>> --- /dev/null
> > >>> +++ b/drivers/gpu/drm/rockchip/cdn-dp-link-training.c
> > >>> @@ -0,0 +1,420 @@
> > >>> +// SPDX-License-Identifier: GPL-2.0
> > >>> +/*
> > >>> + * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
> > >>> + * Author: Chris Zhong 
> > >>> + */
> > >>> +
> > >>> +#include 
> > >>> +#include 
> > >>> +#include 
> > >>> +#include 
> > >>> +
> > >>> +#include "cdn-dp-core.h"
> > >>> +#include "cdn-dp-reg.h"
> > >>> +
> > >>> +static void cdn_dp_set_signal_levels(struct cdn_dp_device *dp)
> > >>> +{
> > >>> +   struct cdn_dp_port *port = dp->port[dp->active_port];
> > >>> +   struct rockchip_typec_phy *tcphy = phy_get_drvdata(port->phy);
> > >>
> > >> You ignored Brian's comment on the previous patch:
> > >>This is still antithetical to the PHY framework; you're assuming that
> > >>this is a particular type of PHY here.
> > >>
> > >> FWIW, the mediatek drm driver also assumes a certain PHY type. A quick 
> > >> grep of
> > >> drivers/ shows that the only other non-phy/ driver using this function
> > >> (pinctrl-tegra-xusb.c) also casts it.
> > >>
> > >> Sean
> > >
> > > Thanks Sean, except phy framework have new API to handle it, i have not
> > > idea how to do it in a better way.
> > 
> > Well, if Mediatek can do it for their MIPI and HDMI, then maybe we just do 
> > it...
> 
> I'd think so too. This is in Rockchip-specific code so it will always be
> possible to easily get the soc-type and thus phy-type, if that combination
> really changes down the road.
> 

So in the absence of a better solution, and with prior art,

Reviewed-by: Sean Paul 


We just need some eyes on the dt and phy changes in this set. Heiko, can you
help out with that?

Sean

> 
> Heiko
> 
> 

-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [PATCH v5 4/4] drm/rockchip: support dp training outside dp firmware

2018-05-17 Thread Sean Paul
VID_REF_CYC(x)(((x) & (BIT(24) - 1)) << 0)
> +#define NMVID_MEAS_TOLERANCE(x)(((x) & 0xf) << 24)
> +
> +/* register DP_TX_PHY_CONFIG_REG */
> +#define DP_TX_PHY_TRAINING_ENABLE(x)   ((x) & 1)
> +#define DP_TX_PHY_TRAINING_TYPE_PRBS7  (0 << 1)
> +#define DP_TX_PHY_TRAINING_TYPE_TPS1   (1 << 1)
> +#define DP_TX_PHY_TRAINING_TYPE_TPS2   (2 << 1)
> +#define DP_TX_PHY_TRAINING_TYPE_TPS3   (3 << 1)
> +#define DP_TX_PHY_TRAINING_TYPE_TPS4   (4 << 1)
> +#define DP_TX_PHY_TRAINING_TYPE_PLTPAT (5 << 1)
> +#define DP_TX_PHY_TRAINING_TYPE_D10_2  (6 << 1)
> +#define DP_TX_PHY_TRAINING_TYPE_HBR2CPAT   (8 << 1)
> +#define DP_TX_PHY_TRAINING_PATTERN(x)  ((x) << 1)
> +#define DP_TX_PHY_SCRAMBLER_BYPASS(x)  (((x) & 1) << 5)
> +#define DP_TX_PHY_ENCODER_BYPASS(x)(((x) & 1) << 6)
> +#define DP_TX_PHY_SKEW_BYPASS(x)   (((x) & 1) << 7)
> +#define DP_TX_PHY_DISPARITY_RST(x) (((x) & 1) << 8)
> +#define DP_TX_PHY_LANE0_SKEW(x)(((x) & 7) << 9)
> +#define DP_TX_PHY_LANE1_SKEW(x)(((x) & 7) << 12)
> +#define DP_TX_PHY_LANE2_SKEW(x)(((x) & 7) << 15)
> +#define DP_TX_PHY_LANE3_SKEW(x)(((x) & 7) << 18)
> +#define DP_TX_PHY_10BIT_ENABLE(x)  (((x) & 1) << 21)
> +
> +/* register DP_FRAMER_GLOBAL_CONFIG */
> +#define NUM_LANES(x)   ((x) & 3)
> +#define SST_MODE   (0 << 2)
> +#define RG_EN  (0 << 4)
> +#define GLOBAL_EN  BIT(3)
> +#define NO_VIDEO   BIT(5)
> +#define ENC_RST_DISBIT(6)
> +#define WR_VHSYNC_FALL BIT(7)
> +
>  enum voltage_swing_level {
>   VOLTAGE_LEVEL_0,
>   VOLTAGE_LEVEL_1,
> @@ -476,6 +510,7 @@ int cdn_dp_set_host_cap(struct cdn_dp_device *dp, u8 
> lanes, bool flip);
>  int cdn_dp_event_config(struct cdn_dp_device *dp);
>  u32 cdn_dp_get_event(struct cdn_dp_device *dp);
>  int cdn_dp_get_hpd_status(struct cdn_dp_device *dp);
> +int cdn_dp_reg_write(struct cdn_dp_device *dp, u16 addr, u32 val);
>  ssize_t cdn_dp_dpcd_write(struct cdn_dp_device *dp, u32 addr,
> u8 *data, u16 len);
>  ssize_t cdn_dp_dpcd_read(struct cdn_dp_device *dp, u32 addr,
> @@ -489,4 +524,5 @@ int cdn_dp_config_video(struct cdn_dp_device *dp);
>  int cdn_dp_audio_stop(struct cdn_dp_device *dp, struct audio_info *audio);
>  int cdn_dp_audio_mute(struct cdn_dp_device *dp, bool enable);
>  int cdn_dp_audio_config(struct cdn_dp_device *dp, struct audio_info *audio);
> +int cdn_dp_software_train_link(struct cdn_dp_device *dp);
>  #endif /* _CDN_DP_REG_H */
> -- 
> 2.7.4
> 

-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [PATCH v5 4/4] drm/rockchip: support dp training outside dp firmware

2018-05-17 Thread Sean Paul
TOLERANCE(x)(((x) & 0xf) << 24)
> +
> +/* register DP_TX_PHY_CONFIG_REG */
> +#define DP_TX_PHY_TRAINING_ENABLE(x)   ((x) & 1)
> +#define DP_TX_PHY_TRAINING_TYPE_PRBS7  (0 << 1)
> +#define DP_TX_PHY_TRAINING_TYPE_TPS1   (1 << 1)
> +#define DP_TX_PHY_TRAINING_TYPE_TPS2   (2 << 1)
> +#define DP_TX_PHY_TRAINING_TYPE_TPS3   (3 << 1)
> +#define DP_TX_PHY_TRAINING_TYPE_TPS4   (4 << 1)
> +#define DP_TX_PHY_TRAINING_TYPE_PLTPAT (5 << 1)
> +#define DP_TX_PHY_TRAINING_TYPE_D10_2  (6 << 1)
> +#define DP_TX_PHY_TRAINING_TYPE_HBR2CPAT   (8 << 1)
> +#define DP_TX_PHY_TRAINING_PATTERN(x)  ((x) << 1)
> +#define DP_TX_PHY_SCRAMBLER_BYPASS(x)  (((x) & 1) << 5)
> +#define DP_TX_PHY_ENCODER_BYPASS(x)(((x) & 1) << 6)
> +#define DP_TX_PHY_SKEW_BYPASS(x)   (((x) & 1) << 7)
> +#define DP_TX_PHY_DISPARITY_RST(x) (((x) & 1) << 8)
> +#define DP_TX_PHY_LANE0_SKEW(x)(((x) & 7) << 9)
> +#define DP_TX_PHY_LANE1_SKEW(x)(((x) & 7) << 12)
> +#define DP_TX_PHY_LANE2_SKEW(x)(((x) & 7) << 15)
> +#define DP_TX_PHY_LANE3_SKEW(x)(((x) & 7) << 18)
> +#define DP_TX_PHY_10BIT_ENABLE(x)  (((x) & 1) << 21)
> +
> +/* register DP_FRAMER_GLOBAL_CONFIG */
> +#define NUM_LANES(x)   ((x) & 3)
> +#define SST_MODE   (0 << 2)
> +#define RG_EN  (0 << 4)
> +#define GLOBAL_EN  BIT(3)
> +#define NO_VIDEO   BIT(5)
> +#define ENC_RST_DISBIT(6)
> +#define WR_VHSYNC_FALL BIT(7)
> +
>  enum voltage_swing_level {
>   VOLTAGE_LEVEL_0,
>   VOLTAGE_LEVEL_1,
> @@ -476,6 +510,7 @@ int cdn_dp_set_host_cap(struct cdn_dp_device *dp, u8 
> lanes, bool flip);
>  int cdn_dp_event_config(struct cdn_dp_device *dp);
>  u32 cdn_dp_get_event(struct cdn_dp_device *dp);
>  int cdn_dp_get_hpd_status(struct cdn_dp_device *dp);
> +int cdn_dp_reg_write(struct cdn_dp_device *dp, u16 addr, u32 val);
>  ssize_t cdn_dp_dpcd_write(struct cdn_dp_device *dp, u32 addr,
> u8 *data, u16 len);
>  ssize_t cdn_dp_dpcd_read(struct cdn_dp_device *dp, u32 addr,
> @@ -489,4 +524,5 @@ int cdn_dp_config_video(struct cdn_dp_device *dp);
>  int cdn_dp_audio_stop(struct cdn_dp_device *dp, struct audio_info *audio);
>  int cdn_dp_audio_mute(struct cdn_dp_device *dp, bool enable);
>  int cdn_dp_audio_config(struct cdn_dp_device *dp, struct audio_info *audio);
> +int cdn_dp_software_train_link(struct cdn_dp_device *dp);
>  #endif /* _CDN_DP_REG_H */
> -- 
> 2.7.4
> 

-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [PATCH v3 4/4] drm/rockchip: support dp training outside dp firmware

2018-05-14 Thread Sean Paul
(!cdn_dp_get_lower_link_rate(dp))
continue;

DRM_ERROR("training channel eq failed: %d\n", ret);
break;
}

return 0;
}

stop_err = cdn_dp_stop_link_train(dp);
if (stop_err) {
DRM_ERROR("stop training fail, error: %d\n", stop_err);
return stop_err;
}

return ret;

> +
> +stop_training:
> + stop_err = cdn_dp_stop_link_train(dp);
> + if (stop_err) {
> + DRM_ERROR("stop training fail, error: %d\n", stop_err);
> + return stop_err;
> + }
> +
> + return ret;

> +}
> diff --git a/drivers/gpu/drm/rockchip/cdn-dp-reg.c 
> b/drivers/gpu/drm/rockchip/cdn-dp-reg.c
> index 979355d..e1273e6 100644
> --- a/drivers/gpu/drm/rockchip/cdn-dp-reg.c
> +++ b/drivers/gpu/drm/rockchip/cdn-dp-reg.c
> @@ -17,7 +17,9 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
> +#include 
>  
>  #include "cdn-dp-core.h"
>  #include "cdn-dp-reg.h"
> @@ -189,7 +191,7 @@ static int cdn_dp_mailbox_send(struct cdn_dp_device *dp, 
> u8 module_id,
>   return 0;
>  }
>  
> -static int cdn_dp_reg_write(struct cdn_dp_device *dp, u16 addr, u32 val)
> +int cdn_dp_reg_write(struct cdn_dp_device *dp, u16 addr, u32 val)
>  {
>   u8 msg[6];
>  
> @@ -609,6 +611,31 @@ int cdn_dp_train_link(struct cdn_dp_device *dp)
>  {
>   int ret;
>  
> + /*
> +  * DP firmware uses fixed phy config values to do training, but some
> +  * boards need to adjust these values to fit for their unique hardware
> +  * design. So if the phy is using custom config values, do software
> +  * link training instead of relying on firmware, if software training

This comment is no longer accurate.

> +  * fail, keep firmware training as a fallback if sw training fails.
> +  */
> + ret = cdn_dp_software_train_link(dp);
> + if (ret) {
> + DRM_DEV_ERROR(dp->dev,
> + "Failed to do software training %d\n", ret);
> + goto do_fw_training;
> + }
> + ret = cdn_dp_reg_write(dp, SOURCE_HDTX_CAR, 0xf);
> + if (ret) {
> + DRM_DEV_ERROR(dp->dev,
> + "Failed to write SOURCE_HDTX_CAR register %d\n", ret);
> + goto do_fw_training;
> + }
> + dp->use_fw_training = false;
> + return 0;
> +
> +do_fw_training:
> + dp->use_fw_training = true;
> + DRM_DEV_DEBUG_KMS(dp->dev, "use fw training\n");
>   ret = cdn_dp_training_start(dp);
>   if (ret) {
>   DRM_DEV_ERROR(dp->dev, "Failed to start training %d\n", ret);
> @@ -623,7 +650,7 @@ int cdn_dp_train_link(struct cdn_dp_device *dp)
>  
>   DRM_DEV_DEBUG_KMS(dp->dev, "rate:0x%x, lanes:%d\n", dp->link.rate,
> dp->link.num_lanes);
> - return ret;
> + return 0;
>  }
>  
>  int cdn_dp_set_video_status(struct cdn_dp_device *dp, int active)
> 

/snip

-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [PATCH v3 4/4] drm/rockchip: support dp training outside dp firmware

2018-05-14 Thread Sean Paul
   continue;

DRM_ERROR("training channel eq failed: %d\n", ret);
break;
}

return 0;
}

stop_err = cdn_dp_stop_link_train(dp);
if (stop_err) {
DRM_ERROR("stop training fail, error: %d\n", stop_err);
return stop_err;
}

return ret;

> +
> +stop_training:
> + stop_err = cdn_dp_stop_link_train(dp);
> + if (stop_err) {
> + DRM_ERROR("stop training fail, error: %d\n", stop_err);
> + return stop_err;
> + }
> +
> + return ret;

> +}
> diff --git a/drivers/gpu/drm/rockchip/cdn-dp-reg.c 
> b/drivers/gpu/drm/rockchip/cdn-dp-reg.c
> index 979355d..e1273e6 100644
> --- a/drivers/gpu/drm/rockchip/cdn-dp-reg.c
> +++ b/drivers/gpu/drm/rockchip/cdn-dp-reg.c
> @@ -17,7 +17,9 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
> +#include 
>  
>  #include "cdn-dp-core.h"
>  #include "cdn-dp-reg.h"
> @@ -189,7 +191,7 @@ static int cdn_dp_mailbox_send(struct cdn_dp_device *dp, 
> u8 module_id,
>   return 0;
>  }
>  
> -static int cdn_dp_reg_write(struct cdn_dp_device *dp, u16 addr, u32 val)
> +int cdn_dp_reg_write(struct cdn_dp_device *dp, u16 addr, u32 val)
>  {
>   u8 msg[6];
>  
> @@ -609,6 +611,31 @@ int cdn_dp_train_link(struct cdn_dp_device *dp)
>  {
>   int ret;
>  
> + /*
> +  * DP firmware uses fixed phy config values to do training, but some
> +  * boards need to adjust these values to fit for their unique hardware
> +  * design. So if the phy is using custom config values, do software
> +  * link training instead of relying on firmware, if software training

This comment is no longer accurate.

> +  * fail, keep firmware training as a fallback if sw training fails.
> +  */
> + ret = cdn_dp_software_train_link(dp);
> + if (ret) {
> + DRM_DEV_ERROR(dp->dev,
> + "Failed to do software training %d\n", ret);
> + goto do_fw_training;
> + }
> + ret = cdn_dp_reg_write(dp, SOURCE_HDTX_CAR, 0xf);
> + if (ret) {
> + DRM_DEV_ERROR(dp->dev,
> + "Failed to write SOURCE_HDTX_CAR register %d\n", ret);
> + goto do_fw_training;
> + }
> + dp->use_fw_training = false;
> + return 0;
> +
> +do_fw_training:
> + dp->use_fw_training = true;
> + DRM_DEV_DEBUG_KMS(dp->dev, "use fw training\n");
>   ret = cdn_dp_training_start(dp);
>   if (ret) {
>   DRM_DEV_ERROR(dp->dev, "Failed to start training %d\n", ret);
> @@ -623,7 +650,7 @@ int cdn_dp_train_link(struct cdn_dp_device *dp)
>  
>   DRM_DEV_DEBUG_KMS(dp->dev, "rate:0x%x, lanes:%d\n", dp->link.rate,
> dp->link.num_lanes);
> - return ret;
> + return 0;
>  }
>  
>  int cdn_dp_set_video_status(struct cdn_dp_device *dp, int active)
> 

/snip

-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [PATCH v3 3/4] phy: rockchip-typec: support variable phy config value

2018-05-14 Thread Sean Paul
On Mon, May 14, 2018 at 05:53:54PM +0800, Lin Huang wrote:
> the phy config values used to fix in dp firmware, but some boards
> need change these values to do training and get the better eye diagram
> result. So support that in phy driver.
> 
> Signed-off-by: Chris Zhong <z...@rock-chips.com>
> Signed-off-by: Lin Huang <h...@rock-chips.com>
> ---
> Changes in v2:
> - update patch following Enric suggest
> Changes in v3:
> - delete need_software_training variable
> - add default phy config value, if dts do not define phy config value, use 
> these value
> 
>  drivers/phy/rockchip/phy-rockchip-typec.c | 305 
> --
>  include/soc/rockchip/rockchip_phy_typec.h |  63 ++
>  2 files changed, 270 insertions(+), 98 deletions(-)
>  create mode 100644 include/soc/rockchip/rockchip_phy_typec.h
> 
> diff --git a/drivers/phy/rockchip/phy-rockchip-typec.c 
> b/drivers/phy/rockchip/phy-rockchip-typec.c
> index 76a4b58..10253ad 100644
> --- a/drivers/phy/rockchip/phy-rockchip-typec.c
> +++ b/drivers/phy/rockchip/phy-rockchip-typec.c

/snip

>  
> +/* default phy config */
> +struct phy_config configs[3][4] = {

static const

Also, configs isn't a good name. How about tcphy_default_config?


> + {{ 0x2a, 0x00 },

Can you please expand the assignment for all of these, ie:

 { .swing = 0x2a, .pe = 0x00 },

> +  { 0x1f, 0x15 },
> +  { 0x14, 0x22 },
> +  { 0x02, 0x2b } },
> +
> + {{ 0x21, 0x00 },
> +  { 0x12, 0x15 },
> +  { 0x02, 0x22 },
> +  {0,0 } },
> +
> + {{ 0x15, 0x00 },
> +  { 0x00, 0x15 },
> +  {0,0 },
> +  {0,0 } },
> +};
> +

/snip

-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [PATCH v3 3/4] phy: rockchip-typec: support variable phy config value

2018-05-14 Thread Sean Paul
On Mon, May 14, 2018 at 05:53:54PM +0800, Lin Huang wrote:
> the phy config values used to fix in dp firmware, but some boards
> need change these values to do training and get the better eye diagram
> result. So support that in phy driver.
> 
> Signed-off-by: Chris Zhong 
> Signed-off-by: Lin Huang 
> ---
> Changes in v2:
> - update patch following Enric suggest
> Changes in v3:
> - delete need_software_training variable
> - add default phy config value, if dts do not define phy config value, use 
> these value
> 
>  drivers/phy/rockchip/phy-rockchip-typec.c | 305 
> --
>  include/soc/rockchip/rockchip_phy_typec.h |  63 ++
>  2 files changed, 270 insertions(+), 98 deletions(-)
>  create mode 100644 include/soc/rockchip/rockchip_phy_typec.h
> 
> diff --git a/drivers/phy/rockchip/phy-rockchip-typec.c 
> b/drivers/phy/rockchip/phy-rockchip-typec.c
> index 76a4b58..10253ad 100644
> --- a/drivers/phy/rockchip/phy-rockchip-typec.c
> +++ b/drivers/phy/rockchip/phy-rockchip-typec.c

/snip

>  
> +/* default phy config */
> +struct phy_config configs[3][4] = {

static const

Also, configs isn't a good name. How about tcphy_default_config?


> + {{ 0x2a, 0x00 },

Can you please expand the assignment for all of these, ie:

 { .swing = 0x2a, .pe = 0x00 },

> +  { 0x1f, 0x15 },
> +  { 0x14, 0x22 },
> +  { 0x02, 0x2b } },
> +
> + {{ 0x21, 0x00 },
> +  { 0x12, 0x15 },
> +  { 0x02, 0x22 },
> +  {0,0 } },
> +
> + {{ 0x15, 0x00 },
> +  { 0x00, 0x15 },
> +  {0,0 },
> +  {0,0 } },
> +};
> +

/snip

-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [PATCH v2 4/4] drm/rockchip: support dp training outside dp firmware

2018-05-11 Thread Sean Paul
t;  
>   DRM_DEV_DEBUG_KMS(dp->dev, "rate:0x%x, lanes:%d\n", dp->link.rate,
> dp->link.num_lanes);
> - return ret;
> + return 0;
>  }
>  
>  int cdn_dp_set_video_status(struct cdn_dp_device *dp, int active)
> diff --git a/drivers/gpu/drm/rockchip/cdn-dp-reg.h 
> b/drivers/gpu/drm/rockchip/cdn-dp-reg.h
> index 6580b11..3420771 100644
> --- a/drivers/gpu/drm/rockchip/cdn-dp-reg.h
> +++ b/drivers/gpu/drm/rockchip/cdn-dp-reg.h
> @@ -137,7 +137,7 @@
>  #define HPD_EVENT_MASK   0x211c
>  #define HPD_EVENT_DET0x2120
>  
> -/* dpyx framer addr */
> +/* dptx framer addr */
>  #define DP_FRAMER_GLOBAL_CONFIG  0x2200
>  #define DP_SW_RESET  0x2204
>  #define DP_FRAMER_TU 0x2208
> @@ -431,6 +431,40 @@
>  /* Reference cycles when using lane clock as reference */
>  #define LANE_REF_CYC 0x8000
>  
> +/* register CM_VID_CTRL */
> +#define LANE_VID_REF_CYC(x)(((x) & (BIT(24) - 1)) << 0)
> +#define NMVID_MEAS_TOLERANCE(x)(((x) & 0xf) << 24)
> +
> +/* register DP_TX_PHY_CONFIG_REG */
> +#define DP_TX_PHY_TRAINING_ENABLE(x)   ((x) & 1)
> +#define DP_TX_PHY_TRAINING_TYPE_PRBS7  (0 << 1)
> +#define DP_TX_PHY_TRAINING_TYPE_TPS1   (1 << 1)
> +#define DP_TX_PHY_TRAINING_TYPE_TPS2   (2 << 1)
> +#define DP_TX_PHY_TRAINING_TYPE_TPS3   (3 << 1)
> +#define DP_TX_PHY_TRAINING_TYPE_TPS4   (4 << 1)
> +#define DP_TX_PHY_TRAINING_TYPE_PLTPAT (5 << 1)
> +#define DP_TX_PHY_TRAINING_TYPE_D10_2  (6 << 1)
> +#define DP_TX_PHY_TRAINING_TYPE_HBR2CPAT   (8 << 1)
> +#define DP_TX_PHY_TRAINING_PATTERN(x)  ((x) << 1)
> +#define DP_TX_PHY_SCRAMBLER_BYPASS(x)  (((x) & 1) << 5)
> +#define DP_TX_PHY_ENCODER_BYPASS(x)(((x) & 1) << 6)
> +#define DP_TX_PHY_SKEW_BYPASS(x)   (((x) & 1) << 7)
> +#define DP_TX_PHY_DISPARITY_RST(x) (((x) & 1) << 8)
> +#define DP_TX_PHY_LANE0_SKEW(x)(((x) & 7) << 9)
> +#define DP_TX_PHY_LANE1_SKEW(x)(((x) & 7) << 12)
> +#define DP_TX_PHY_LANE2_SKEW(x)(((x) & 7) << 15)
> +#define DP_TX_PHY_LANE3_SKEW(x)(((x) & 7) << 18)
> +#define DP_TX_PHY_10BIT_ENABLE(x)  (((x) & 1) << 21)
> +
> +/* register DP_FRAMER_GLOBAL_CONFIG */
> +#define NUM_LANES(x)   ((x) & 3)
> +#define SST_MODE   (0 << 2)
> +#define RG_EN  (0 << 4)
> +#define GLOBAL_EN  BIT(3)
> +#define NO_VIDEO   BIT(5)
> +#define ENC_RST_DISBIT(6)
> +#define WR_VHSYNC_FALL BIT(7)
> +
>  enum voltage_swing_level {
>   VOLTAGE_LEVEL_0,
>   VOLTAGE_LEVEL_1,
> @@ -476,6 +510,7 @@ int cdn_dp_set_host_cap(struct cdn_dp_device *dp, u8 
> lanes, bool flip);
>  int cdn_dp_event_config(struct cdn_dp_device *dp);
>  u32 cdn_dp_get_event(struct cdn_dp_device *dp);
>  int cdn_dp_get_hpd_status(struct cdn_dp_device *dp);
> +int cdn_dp_reg_write(struct cdn_dp_device *dp, u16 addr, u32 val);
>  ssize_t cdn_dp_dpcd_write(struct cdn_dp_device *dp, u32 addr,
> u8 *data, u16 len);
>  ssize_t cdn_dp_dpcd_read(struct cdn_dp_device *dp, u32 addr,
> @@ -489,4 +524,5 @@ int cdn_dp_config_video(struct cdn_dp_device *dp);
>  int cdn_dp_audio_stop(struct cdn_dp_device *dp, struct audio_info *audio);
>  int cdn_dp_audio_mute(struct cdn_dp_device *dp, bool enable);
>  int cdn_dp_audio_config(struct cdn_dp_device *dp, struct audio_info *audio);
> +int cdn_dp_software_train_link(struct cdn_dp_device *dp);
>  #endif /* _CDN_DP_REG_H */
> -- 
> 2.7.4
> 

-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [PATCH v2 4/4] drm/rockchip: support dp training outside dp firmware

2018-05-11 Thread Sean Paul
x%x, lanes:%d\n", dp->link.rate,
> dp->link.num_lanes);
> - return ret;
> + return 0;
>  }
>  
>  int cdn_dp_set_video_status(struct cdn_dp_device *dp, int active)
> diff --git a/drivers/gpu/drm/rockchip/cdn-dp-reg.h 
> b/drivers/gpu/drm/rockchip/cdn-dp-reg.h
> index 6580b11..3420771 100644
> --- a/drivers/gpu/drm/rockchip/cdn-dp-reg.h
> +++ b/drivers/gpu/drm/rockchip/cdn-dp-reg.h
> @@ -137,7 +137,7 @@
>  #define HPD_EVENT_MASK   0x211c
>  #define HPD_EVENT_DET0x2120
>  
> -/* dpyx framer addr */
> +/* dptx framer addr */
>  #define DP_FRAMER_GLOBAL_CONFIG  0x2200
>  #define DP_SW_RESET  0x2204
>  #define DP_FRAMER_TU 0x2208
> @@ -431,6 +431,40 @@
>  /* Reference cycles when using lane clock as reference */
>  #define LANE_REF_CYC 0x8000
>  
> +/* register CM_VID_CTRL */
> +#define LANE_VID_REF_CYC(x)(((x) & (BIT(24) - 1)) << 0)
> +#define NMVID_MEAS_TOLERANCE(x)(((x) & 0xf) << 24)
> +
> +/* register DP_TX_PHY_CONFIG_REG */
> +#define DP_TX_PHY_TRAINING_ENABLE(x)   ((x) & 1)
> +#define DP_TX_PHY_TRAINING_TYPE_PRBS7  (0 << 1)
> +#define DP_TX_PHY_TRAINING_TYPE_TPS1   (1 << 1)
> +#define DP_TX_PHY_TRAINING_TYPE_TPS2   (2 << 1)
> +#define DP_TX_PHY_TRAINING_TYPE_TPS3   (3 << 1)
> +#define DP_TX_PHY_TRAINING_TYPE_TPS4   (4 << 1)
> +#define DP_TX_PHY_TRAINING_TYPE_PLTPAT (5 << 1)
> +#define DP_TX_PHY_TRAINING_TYPE_D10_2  (6 << 1)
> +#define DP_TX_PHY_TRAINING_TYPE_HBR2CPAT   (8 << 1)
> +#define DP_TX_PHY_TRAINING_PATTERN(x)  ((x) << 1)
> +#define DP_TX_PHY_SCRAMBLER_BYPASS(x)  (((x) & 1) << 5)
> +#define DP_TX_PHY_ENCODER_BYPASS(x)(((x) & 1) << 6)
> +#define DP_TX_PHY_SKEW_BYPASS(x)   (((x) & 1) << 7)
> +#define DP_TX_PHY_DISPARITY_RST(x) (((x) & 1) << 8)
> +#define DP_TX_PHY_LANE0_SKEW(x)(((x) & 7) << 9)
> +#define DP_TX_PHY_LANE1_SKEW(x)(((x) & 7) << 12)
> +#define DP_TX_PHY_LANE2_SKEW(x)(((x) & 7) << 15)
> +#define DP_TX_PHY_LANE3_SKEW(x)(((x) & 7) << 18)
> +#define DP_TX_PHY_10BIT_ENABLE(x)  (((x) & 1) << 21)
> +
> +/* register DP_FRAMER_GLOBAL_CONFIG */
> +#define NUM_LANES(x)   ((x) & 3)
> +#define SST_MODE   (0 << 2)
> +#define RG_EN  (0 << 4)
> +#define GLOBAL_EN  BIT(3)
> +#define NO_VIDEO   BIT(5)
> +#define ENC_RST_DISBIT(6)
> +#define WR_VHSYNC_FALL BIT(7)
> +
>  enum voltage_swing_level {
>   VOLTAGE_LEVEL_0,
>   VOLTAGE_LEVEL_1,
> @@ -476,6 +510,7 @@ int cdn_dp_set_host_cap(struct cdn_dp_device *dp, u8 
> lanes, bool flip);
>  int cdn_dp_event_config(struct cdn_dp_device *dp);
>  u32 cdn_dp_get_event(struct cdn_dp_device *dp);
>  int cdn_dp_get_hpd_status(struct cdn_dp_device *dp);
> +int cdn_dp_reg_write(struct cdn_dp_device *dp, u16 addr, u32 val);
>  ssize_t cdn_dp_dpcd_write(struct cdn_dp_device *dp, u32 addr,
> u8 *data, u16 len);
>  ssize_t cdn_dp_dpcd_read(struct cdn_dp_device *dp, u32 addr,
> @@ -489,4 +524,5 @@ int cdn_dp_config_video(struct cdn_dp_device *dp);
>  int cdn_dp_audio_stop(struct cdn_dp_device *dp, struct audio_info *audio);
>  int cdn_dp_audio_mute(struct cdn_dp_device *dp, bool enable);
>  int cdn_dp_audio_config(struct cdn_dp_device *dp, struct audio_info *audio);
> +int cdn_dp_software_train_link(struct cdn_dp_device *dp);
>  #endif /* _CDN_DP_REG_H */
> -- 
> 2.7.4
> 

-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [PATCH v2 3/4] Documentation: bindings: add phy_config for Rockchip USB Type-C PHY

2018-05-11 Thread Sean Paul
On Wed, May 09, 2018 at 06:22:43PM +0800, Lin Huang wrote:
> If want to do training outside DP Firmware, need phy voltage swing
> and pre_emphasis value.
> 
> Signed-off-by: Lin Huang <h...@rock-chips.com>

Adding Rob Herring so he has a hope of seeing this.

> ---
> Changes in v2:
> - rebase
> 
>  Documentation/devicetree/bindings/phy/phy-rockchip-typec.txt | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/phy/phy-rockchip-typec.txt 
> b/Documentation/devicetree/bindings/phy/phy-rockchip-typec.txt
> index 960da7f..eda26dd 100644
> --- a/Documentation/devicetree/bindings/phy/phy-rockchip-typec.txt
> +++ b/Documentation/devicetree/bindings/phy/phy-rockchip-typec.txt
> @@ -17,7 +17,9 @@ Required properties:
>  
>  Optional properties:
>   - extcon : extcon specifier for the Power Delivery
> -
> + - rockchip,phy_config : That's phy voltage swing and pre_emphasis
> +  setting, if want to do dp training outside
> +  dp firmware, need to add these value.

What are the units?

Sean

>  Required nodes : a sub-node is required for each port the phy provides.
>The sub-node name is used to identify dp or usb3 port,
>and shall be the following entries:
> -- 
> 2.7.4
> 

-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [PATCH v2 3/4] Documentation: bindings: add phy_config for Rockchip USB Type-C PHY

2018-05-11 Thread Sean Paul
On Wed, May 09, 2018 at 06:22:43PM +0800, Lin Huang wrote:
> If want to do training outside DP Firmware, need phy voltage swing
> and pre_emphasis value.
> 
> Signed-off-by: Lin Huang 

Adding Rob Herring so he has a hope of seeing this.

> ---
> Changes in v2:
> - rebase
> 
>  Documentation/devicetree/bindings/phy/phy-rockchip-typec.txt | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/phy/phy-rockchip-typec.txt 
> b/Documentation/devicetree/bindings/phy/phy-rockchip-typec.txt
> index 960da7f..eda26dd 100644
> --- a/Documentation/devicetree/bindings/phy/phy-rockchip-typec.txt
> +++ b/Documentation/devicetree/bindings/phy/phy-rockchip-typec.txt
> @@ -17,7 +17,9 @@ Required properties:
>  
>  Optional properties:
>   - extcon : extcon specifier for the Power Delivery
> -
> + - rockchip,phy_config : That's phy voltage swing and pre_emphasis
> +  setting, if want to do dp training outside
> +  dp firmware, need to add these value.

What are the units?

Sean

>  Required nodes : a sub-node is required for each port the phy provides.
>The sub-node name is used to identify dp or usb3 port,
>    and shall be the following entries:
> -- 
> 2.7.4
> 

-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [PATCH v2 2/4] phy: rockchip-typec: support variable phy config value

2018-05-11 Thread Sean Paul
On Wed, May 09, 2018 at 06:22:42PM +0800, Lin Huang wrote:
> the phy config values used to fix in dp firmware, but some boards
> need change these values to do training and get the better eye diagram
> result. So support that in phy driver.
> 
FTR, I've previously reviewed this at
https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/985573

This patch should come _after_ the dt binding addition.

> Signed-off-by: Chris Zhong <z...@rock-chips.com>
> Signed-off-by: Lin Huang <h...@rock-chips.com>
> ---
> Changes in v2:
> - update patch following Enric suggest
> 
>  drivers/phy/rockchip/phy-rockchip-typec.c | 284 
> +++---
>  include/soc/rockchip/rockchip_phy_typec.h |  64 +++
>  2 files changed, 250 insertions(+), 98 deletions(-)
>  create mode 100644 include/soc/rockchip/rockchip_phy_typec.h
> 

/snip

> diff --git a/include/soc/rockchip/rockchip_phy_typec.h 
> b/include/soc/rockchip/rockchip_phy_typec.h
> new file mode 100644
> index 000..4a328221
> --- /dev/null
> +++ b/include/soc/rockchip/rockchip_phy_typec.h
> @@ -0,0 +1,64 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
> + * Author: Lin Huang <h...@rock-chips.com>
> + */
> +
> +#ifndef __SOC_ROCKCHIP_PHY_TYPEC_H
> +#define __SOC_ROCKCHIP_PHY_TYPEC_H
> +
> +struct usb3phy_reg {
> + u32 offset;
> + u32 enable_bit;
> + u32 write_enable;
> +};
> +
> +/**
> + * struct rockchip_usb3phy_port_cfg: usb3-phy port configuration.
> + * @reg: the base address for usb3-phy config.
> + * @typec_conn_dir: the register of type-c connector direction.
> + * @usb3tousb2_en: the register of type-c force usb2 to usb2 enable.
> + * @external_psm: the register of type-c phy external psm clock.
> + * @pipe_status: the register of type-c phy pipe status.
> + * @usb3_host_disable: the register of type-c usb3 host disable.
> + * @usb3_host_port: the register of type-c usb3 host port.
> + * @uphy_dp_sel: the register of type-c phy DP select control.
> + */
> +struct rockchip_usb3phy_port_cfg {
> + unsigned int reg;
> + struct usb3phy_reg typec_conn_dir;
> + struct usb3phy_reg usb3tousb2_en;
> + struct usb3phy_reg external_psm;
> + struct usb3phy_reg pipe_status;
> + struct usb3phy_reg usb3_host_disable;
> + struct usb3phy_reg usb3_host_port;
> + struct usb3phy_reg uphy_dp_sel;
> +};
> +
> +struct phy_config {
> + int swing;
> + int pe;
> +};
> +
> +struct rockchip_typec_phy {
> + struct device *dev;
> + void __iomem *base;
> + struct extcon_dev *extcon;
> + struct regmap *grf_regs;
> + struct clk *clk_core;
> + struct clk *clk_ref;
> + struct reset_control *uphy_rst;
> + struct reset_control *pipe_rst;
> + struct reset_control *tcphy_rst;
> + const struct rockchip_usb3phy_port_cfg *port_cfgs;
> + /* mutex to protect access to individual PHYs */
> + struct mutex lock;
> + struct phy_config config[3][4];
> + u8 need_software_training;

I thought we decided to always do sw training and then fallback to fw training.
If so, we don't need this.

Sean

> + bool flip;
> + u8 mode;
> + int (*typec_phy_config)(struct phy *phy, int link_rate,
> + int lanes, u8 swing, u8 pre_emp);
> +};
> +
> +#endif
> -- 
> 2.7.4
> 

-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [PATCH v2 2/4] phy: rockchip-typec: support variable phy config value

2018-05-11 Thread Sean Paul
On Wed, May 09, 2018 at 06:22:42PM +0800, Lin Huang wrote:
> the phy config values used to fix in dp firmware, but some boards
> need change these values to do training and get the better eye diagram
> result. So support that in phy driver.
> 
FTR, I've previously reviewed this at
https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/985573

This patch should come _after_ the dt binding addition.

> Signed-off-by: Chris Zhong 
> Signed-off-by: Lin Huang 
> ---
> Changes in v2:
> - update patch following Enric suggest
> 
>  drivers/phy/rockchip/phy-rockchip-typec.c | 284 
> +++---
>  include/soc/rockchip/rockchip_phy_typec.h |  64 +++
>  2 files changed, 250 insertions(+), 98 deletions(-)
>  create mode 100644 include/soc/rockchip/rockchip_phy_typec.h
> 

/snip

> diff --git a/include/soc/rockchip/rockchip_phy_typec.h 
> b/include/soc/rockchip/rockchip_phy_typec.h
> new file mode 100644
> index 000..4a328221
> --- /dev/null
> +++ b/include/soc/rockchip/rockchip_phy_typec.h
> @@ -0,0 +1,64 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
> + * Author: Lin Huang 
> + */
> +
> +#ifndef __SOC_ROCKCHIP_PHY_TYPEC_H
> +#define __SOC_ROCKCHIP_PHY_TYPEC_H
> +
> +struct usb3phy_reg {
> + u32 offset;
> + u32 enable_bit;
> + u32 write_enable;
> +};
> +
> +/**
> + * struct rockchip_usb3phy_port_cfg: usb3-phy port configuration.
> + * @reg: the base address for usb3-phy config.
> + * @typec_conn_dir: the register of type-c connector direction.
> + * @usb3tousb2_en: the register of type-c force usb2 to usb2 enable.
> + * @external_psm: the register of type-c phy external psm clock.
> + * @pipe_status: the register of type-c phy pipe status.
> + * @usb3_host_disable: the register of type-c usb3 host disable.
> + * @usb3_host_port: the register of type-c usb3 host port.
> + * @uphy_dp_sel: the register of type-c phy DP select control.
> + */
> +struct rockchip_usb3phy_port_cfg {
> + unsigned int reg;
> + struct usb3phy_reg typec_conn_dir;
> + struct usb3phy_reg usb3tousb2_en;
> + struct usb3phy_reg external_psm;
> + struct usb3phy_reg pipe_status;
> + struct usb3phy_reg usb3_host_disable;
> + struct usb3phy_reg usb3_host_port;
> + struct usb3phy_reg uphy_dp_sel;
> +};
> +
> +struct phy_config {
> + int swing;
> + int pe;
> +};
> +
> +struct rockchip_typec_phy {
> + struct device *dev;
> + void __iomem *base;
> + struct extcon_dev *extcon;
> + struct regmap *grf_regs;
> + struct clk *clk_core;
> + struct clk *clk_ref;
> + struct reset_control *uphy_rst;
> + struct reset_control *pipe_rst;
> + struct reset_control *tcphy_rst;
> + const struct rockchip_usb3phy_port_cfg *port_cfgs;
> + /* mutex to protect access to individual PHYs */
> + struct mutex lock;
> + struct phy_config config[3][4];
> + u8 need_software_training;

I thought we decided to always do sw training and then fallback to fw training.
If so, we don't need this.

Sean

> + bool flip;
> + u8 mode;
> + int (*typec_phy_config)(struct phy *phy, int link_rate,
> + int lanes, u8 swing, u8 pre_emp);
> +};
> +
> +#endif
> -- 
> 2.7.4
> 

-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [PATCH v2 1/4] drm/rockchip: add transfer function for cdn-dp

2018-05-11 Thread Sean Paul
On Wed, May 09, 2018 at 06:22:41PM +0800, Lin Huang wrote:
> From: Chris Zhong <z...@rock-chips.com>
> 
> We may support training outside firmware, so we need support
> dpcd read/write to get the message or do some setting with
> display.
> 
> Signed-off-by: Chris Zhong <z...@rock-chips.com>
> Signed-off-by: Lin Huang <h...@rock-chips.com>

FTR, I've already done one pass at [1]. All of those nits look fixed, so 

Reviewed-by: Sean Paul <seanp...@chromium.org>

[1]- 
https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/985572

> ---
> 
> Changes in v2: 
> - update patch following Enric suggest
> 
>  drivers/gpu/drm/rockchip/cdn-dp-core.c | 55 
>  drivers/gpu/drm/rockchip/cdn-dp-core.h |  1 +
>  drivers/gpu/drm/rockchip/cdn-dp-reg.c  | 67 
> ++
>  drivers/gpu/drm/rockchip/cdn-dp-reg.h  | 14 ++-
>  4 files changed, 120 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c 
> b/drivers/gpu/drm/rockchip/cdn-dp-core.c
> index c6fbdcd..cce64c1 100644
> --- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
> +++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
> @@ -176,8 +176,8 @@ static int cdn_dp_get_sink_count(struct cdn_dp_device 
> *dp, u8 *sink_count)
>   u8 value;
>  
>   *sink_count = 0;
> - ret = cdn_dp_dpcd_read(dp, DP_SINK_COUNT, , 1);
> - if (ret)
> + ret = drm_dp_dpcd_read(>aux, DP_SINK_COUNT, , 1);
> + if (ret < 0)
>   return ret;
>  
>   *sink_count = DP_GET_SINK_COUNT(value);
> @@ -374,9 +374,9 @@ static int cdn_dp_get_sink_capability(struct 
> cdn_dp_device *dp)
>   if (!cdn_dp_check_sink_connection(dp))
>   return -ENODEV;
>  
> - ret = cdn_dp_dpcd_read(dp, DP_DPCD_REV, dp->dpcd,
> -DP_RECEIVER_CAP_SIZE);
> - if (ret) {
> + ret = drm_dp_dpcd_read(>aux, DP_DPCD_REV, dp->dpcd,
> +sizeof(dp->dpcd));
> + if (ret < 0) {
>   DRM_DEV_ERROR(dp->dev, "Failed to get caps %d\n", ret);
>   return ret;
>   }
> @@ -582,8 +582,8 @@ static bool cdn_dp_check_link_status(struct cdn_dp_device 
> *dp)
>   if (!port || !dp->link.rate || !dp->link.num_lanes)
>   return false;
>  
> - if (cdn_dp_dpcd_read(dp, DP_LANE0_1_STATUS, link_status,
> -  DP_LINK_STATUS_SIZE)) {
> + if (drm_dp_dpcd_read_link_status(>aux, link_status) !=
> + DP_LINK_STATUS_SIZE) {
>   DRM_ERROR("Failed to get link status\n");
>   return false;
>   }
> @@ -1012,6 +1012,40 @@ static int cdn_dp_pd_event(struct notifier_block *nb,
>   return NOTIFY_DONE;
>  }
>  
> +static ssize_t cdn_dp_aux_transfer(struct drm_dp_aux *aux,
> +struct drm_dp_aux_msg *msg)
> +{
> + struct cdn_dp_device *dp = container_of(aux, struct cdn_dp_device, aux);
> + int ret;
> + u8 status;
> +
> + switch (msg->request & ~DP_AUX_I2C_MOT) {
> + case DP_AUX_NATIVE_WRITE:
> + case DP_AUX_I2C_WRITE:
> + case DP_AUX_I2C_WRITE_STATUS_UPDATE:
> + ret = cdn_dp_dpcd_write(dp, msg->address, msg->buffer,
> + msg->size);
> + break;
> + case DP_AUX_NATIVE_READ:
> + case DP_AUX_I2C_READ:
> + ret = cdn_dp_dpcd_read(dp, msg->address, msg->buffer,
> +msg->size);
> + break;
> + default:
> + return -EINVAL;
> + }
> +
> + status = cdn_dp_get_aux_status(dp);
> + if (status == AUX_STATUS_ACK)
> + msg->reply = DP_AUX_NATIVE_REPLY_ACK;
> + else if (status == AUX_STATUS_NACK)
> + msg->reply = DP_AUX_NATIVE_REPLY_NACK;
> + else if (status == AUX_STATUS_DEFER)
> + msg->reply = DP_AUX_NATIVE_REPLY_DEFER;
> +
> + return ret;
> +}
> +
>  static int cdn_dp_bind(struct device *dev, struct device *master, void *data)
>  {
>   struct cdn_dp_device *dp = dev_get_drvdata(dev);
> @@ -1030,6 +1064,13 @@ static int cdn_dp_bind(struct device *dev, struct 
> device *master, void *data)
>   dp->active = false;
>   dp->active_port = -1;
>   dp->fw_loaded = false;
> + dp->aux.name = "DP-AUX";
> + dp->aux.transfer = cdn_dp_aux_transfer;
> + dp->aux.dev = dev;
> +
> + ret = drm_dp_aux_register(>aux);
> + if (ret)
> + return ret;
>  
>   INIT_WORK(>event_work, cdn_dp_pd_event_work)

Re: [PATCH v2 1/4] drm/rockchip: add transfer function for cdn-dp

2018-05-11 Thread Sean Paul
On Wed, May 09, 2018 at 06:22:41PM +0800, Lin Huang wrote:
> From: Chris Zhong 
> 
> We may support training outside firmware, so we need support
> dpcd read/write to get the message or do some setting with
> display.
> 
> Signed-off-by: Chris Zhong 
> Signed-off-by: Lin Huang 

FTR, I've already done one pass at [1]. All of those nits look fixed, so 

Reviewed-by: Sean Paul 

[1]- 
https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/985572

> ---
> 
> Changes in v2: 
> - update patch following Enric suggest
> 
>  drivers/gpu/drm/rockchip/cdn-dp-core.c | 55 
>  drivers/gpu/drm/rockchip/cdn-dp-core.h |  1 +
>  drivers/gpu/drm/rockchip/cdn-dp-reg.c  | 67 
> ++
>  drivers/gpu/drm/rockchip/cdn-dp-reg.h  | 14 ++-
>  4 files changed, 120 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c 
> b/drivers/gpu/drm/rockchip/cdn-dp-core.c
> index c6fbdcd..cce64c1 100644
> --- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
> +++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
> @@ -176,8 +176,8 @@ static int cdn_dp_get_sink_count(struct cdn_dp_device 
> *dp, u8 *sink_count)
>   u8 value;
>  
>   *sink_count = 0;
> - ret = cdn_dp_dpcd_read(dp, DP_SINK_COUNT, , 1);
> - if (ret)
> + ret = drm_dp_dpcd_read(>aux, DP_SINK_COUNT, , 1);
> + if (ret < 0)
>   return ret;
>  
>   *sink_count = DP_GET_SINK_COUNT(value);
> @@ -374,9 +374,9 @@ static int cdn_dp_get_sink_capability(struct 
> cdn_dp_device *dp)
>   if (!cdn_dp_check_sink_connection(dp))
>   return -ENODEV;
>  
> - ret = cdn_dp_dpcd_read(dp, DP_DPCD_REV, dp->dpcd,
> -DP_RECEIVER_CAP_SIZE);
> - if (ret) {
> + ret = drm_dp_dpcd_read(>aux, DP_DPCD_REV, dp->dpcd,
> +sizeof(dp->dpcd));
> + if (ret < 0) {
>   DRM_DEV_ERROR(dp->dev, "Failed to get caps %d\n", ret);
>   return ret;
>   }
> @@ -582,8 +582,8 @@ static bool cdn_dp_check_link_status(struct cdn_dp_device 
> *dp)
>   if (!port || !dp->link.rate || !dp->link.num_lanes)
>   return false;
>  
> - if (cdn_dp_dpcd_read(dp, DP_LANE0_1_STATUS, link_status,
> -  DP_LINK_STATUS_SIZE)) {
> + if (drm_dp_dpcd_read_link_status(>aux, link_status) !=
> + DP_LINK_STATUS_SIZE) {
>   DRM_ERROR("Failed to get link status\n");
>   return false;
>   }
> @@ -1012,6 +1012,40 @@ static int cdn_dp_pd_event(struct notifier_block *nb,
>   return NOTIFY_DONE;
>  }
>  
> +static ssize_t cdn_dp_aux_transfer(struct drm_dp_aux *aux,
> +struct drm_dp_aux_msg *msg)
> +{
> + struct cdn_dp_device *dp = container_of(aux, struct cdn_dp_device, aux);
> + int ret;
> + u8 status;
> +
> + switch (msg->request & ~DP_AUX_I2C_MOT) {
> + case DP_AUX_NATIVE_WRITE:
> + case DP_AUX_I2C_WRITE:
> + case DP_AUX_I2C_WRITE_STATUS_UPDATE:
> + ret = cdn_dp_dpcd_write(dp, msg->address, msg->buffer,
> + msg->size);
> + break;
> + case DP_AUX_NATIVE_READ:
> + case DP_AUX_I2C_READ:
> + ret = cdn_dp_dpcd_read(dp, msg->address, msg->buffer,
> +msg->size);
> + break;
> + default:
> + return -EINVAL;
> + }
> +
> + status = cdn_dp_get_aux_status(dp);
> + if (status == AUX_STATUS_ACK)
> + msg->reply = DP_AUX_NATIVE_REPLY_ACK;
> + else if (status == AUX_STATUS_NACK)
> + msg->reply = DP_AUX_NATIVE_REPLY_NACK;
> + else if (status == AUX_STATUS_DEFER)
> + msg->reply = DP_AUX_NATIVE_REPLY_DEFER;
> +
> + return ret;
> +}
> +
>  static int cdn_dp_bind(struct device *dev, struct device *master, void *data)
>  {
>   struct cdn_dp_device *dp = dev_get_drvdata(dev);
> @@ -1030,6 +1064,13 @@ static int cdn_dp_bind(struct device *dev, struct 
> device *master, void *data)
>   dp->active = false;
>   dp->active_port = -1;
>   dp->fw_loaded = false;
> + dp->aux.name = "DP-AUX";
> + dp->aux.transfer = cdn_dp_aux_transfer;
> + dp->aux.dev = dev;
> +
> + ret = drm_dp_aux_register(>aux);
> + if (ret)
> + return ret;
>  
>   INIT_WORK(>event_work, cdn_dp_pd_event_work);
>  
> diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.h 
> b/drivers/gpu/drm/rockchip/cdn-dp

Re: [PATCH] gpu: drm: vgem: Change return type to vm_fault_t

2018-05-10 Thread Sean Paul
On Thu, May 10, 2018 at 07:58:11PM +0530, Souptick Joarder wrote:
> Hi Sean,
> 
> On Mon, Apr 16, 2018 at 8:32 PM, Souptick Joarder <jrdr.li...@gmail.com> 
> wrote:
> > Use new return type vm_fault_t for fault handler.
> >
> > Signed-off-by: Souptick Joarder <jrdr.li...@gmail.com>
> > Reviewed-by: Matthew Wilcox <mawil...@microsoft.com>
> > ---
> >  drivers/gpu/drm/vgem/vgem_drv.c | 5 ++---
> >  1 file changed, 2 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/vgem/vgem_drv.c 
> > b/drivers/gpu/drm/vgem/vgem_drv.c
> > index 2524ff1..c64a859 100644
> > --- a/drivers/gpu/drm/vgem/vgem_drv.c
> > +++ b/drivers/gpu/drm/vgem/vgem_drv.c
> > @@ -61,13 +61,13 @@ static void vgem_gem_free_object(struct drm_gem_object 
> > *obj)
> > kfree(vgem_obj);
> >  }
> >
> > -static int vgem_gem_fault(struct vm_fault *vmf)
> > +static vm_fault_t vgem_gem_fault(struct vm_fault *vmf)
> >  {
> > struct vm_area_struct *vma = vmf->vma;
> > struct drm_vgem_gem_object *obj = vma->vm_private_data;
> > /* We don't use vmf->pgoff since that has the fake offset */
> > unsigned long vaddr = vmf->address;
> > -   int ret;
> > +   vm_fault_t ret = VM_FAULT_SIGBUS;
> > loff_t num_pages;
> > pgoff_t page_offset;
> > page_offset = (vaddr - vma->vm_start) >> PAGE_SHIFT;
> > @@ -77,7 +77,6 @@ static int vgem_gem_fault(struct vm_fault *vmf)
> > if (page_offset > num_pages)
> > return VM_FAULT_SIGBUS;
> >
> > -   ret = -ENOENT;
> > mutex_lock(>pages_lock);
> > if (obj->pages) {
> >     get_page(obj->pages[page_offset]);
> > --
> > 1.9.1
> >
> 
> Any further comment on this patch ?

Patch looks good to me. My build test fails, though, since vm_fault_t doesn't
exist in drm-misc-next yet.

So, for now,

Reviewed-by: Sean Paul <seanp...@chromium.org>


-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [PATCH] gpu: drm: vgem: Change return type to vm_fault_t

2018-05-10 Thread Sean Paul
On Thu, May 10, 2018 at 07:58:11PM +0530, Souptick Joarder wrote:
> Hi Sean,
> 
> On Mon, Apr 16, 2018 at 8:32 PM, Souptick Joarder  
> wrote:
> > Use new return type vm_fault_t for fault handler.
> >
> > Signed-off-by: Souptick Joarder 
> > Reviewed-by: Matthew Wilcox 
> > ---
> >  drivers/gpu/drm/vgem/vgem_drv.c | 5 ++---
> >  1 file changed, 2 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/vgem/vgem_drv.c 
> > b/drivers/gpu/drm/vgem/vgem_drv.c
> > index 2524ff1..c64a859 100644
> > --- a/drivers/gpu/drm/vgem/vgem_drv.c
> > +++ b/drivers/gpu/drm/vgem/vgem_drv.c
> > @@ -61,13 +61,13 @@ static void vgem_gem_free_object(struct drm_gem_object 
> > *obj)
> > kfree(vgem_obj);
> >  }
> >
> > -static int vgem_gem_fault(struct vm_fault *vmf)
> > +static vm_fault_t vgem_gem_fault(struct vm_fault *vmf)
> >  {
> > struct vm_area_struct *vma = vmf->vma;
> > struct drm_vgem_gem_object *obj = vma->vm_private_data;
> > /* We don't use vmf->pgoff since that has the fake offset */
> > unsigned long vaddr = vmf->address;
> > -   int ret;
> > +   vm_fault_t ret = VM_FAULT_SIGBUS;
> > loff_t num_pages;
> > pgoff_t page_offset;
> > page_offset = (vaddr - vma->vm_start) >> PAGE_SHIFT;
> > @@ -77,7 +77,6 @@ static int vgem_gem_fault(struct vm_fault *vmf)
> > if (page_offset > num_pages)
> > return VM_FAULT_SIGBUS;
> >
> > -   ret = -ENOENT;
> > mutex_lock(>pages_lock);
> > if (obj->pages) {
> > get_page(obj->pages[page_offset]);
> > --
> > 1.9.1
> >
> 
> Any further comment on this patch ?

Patch looks good to me. My build test fails, though, since vm_fault_t doesn't
exist in drm-misc-next yet.

So, for now,

Reviewed-by: Sean Paul 


-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [PATCH] drm/vc4: Fix oops dereferencing DPI's connector since panel_bridge.

2018-05-02 Thread Sean Paul
On Fri, Mar 09, 2018 at 03:32:56PM -0800, Eric Anholt wrote:
> In the cleanup, I didn't notice that we needed to dereference the
> connector for the bus_format.  Fix the regression by looking up the
> first (and only) connector attached to us, and assume that its
> bus_format is what we want.  Some day it would be good to have that
> part of display_info attached to the bridge, instead.
> 
> Signed-off-by: Eric Anholt <e...@anholt.net>
> Fixes: 7b1298e05310 ("drm/vc4: Switch DPI to using the panel-bridge helper.")
> Cc: Boris Brezillon <boris.brezil...@bootlin.com>
> ---
>  drivers/gpu/drm/vc4/vc4_dpi.c | 27 +++
>  1 file changed, 23 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/vc4/vc4_dpi.c b/drivers/gpu/drm/vc4/vc4_dpi.c
> index 72c9dbd81d7f..88783e143cc2 100644
> --- a/drivers/gpu/drm/vc4/vc4_dpi.c
> +++ b/drivers/gpu/drm/vc4/vc4_dpi.c
> @@ -96,7 +96,6 @@ struct vc4_dpi {
>   struct platform_device *pdev;
>  
>   struct drm_encoder *encoder;
> - struct drm_connector *connector;
>  
>   void __iomem *regs;
>  
> @@ -164,14 +163,31 @@ static void vc4_dpi_encoder_disable(struct drm_encoder 
> *encoder)
>  
>  static void vc4_dpi_encoder_enable(struct drm_encoder *encoder)
>  {
> + struct drm_device *dev = encoder->dev;
>   struct drm_display_mode *mode = >crtc->mode;
>   struct vc4_dpi_encoder *vc4_encoder = to_vc4_dpi_encoder(encoder);
>   struct vc4_dpi *dpi = vc4_encoder->dpi;
> + struct drm_connector_list_iter conn_iter;
> + struct drm_connector *connector = NULL, *connector_scan;
>   u32 dpi_c = DPI_ENABLE | DPI_OUTPUT_ENABLE_MODE;
>   int ret;
>  
> - if (dpi->connector->display_info.num_bus_formats) {
> - u32 bus_format = dpi->connector->display_info.bus_formats[0];
> + /* Look up the connector attached to DPI so we can get the
> +  * bus_format.  Ideally the bridge would tell us the
> +  * bus_format we want, but it doesn't yet, so assume that it's
> +  * uniform throughout the bridge chain.
> +  */
> + drm_connector_list_iter_begin(dev, _iter);
> + drm_for_each_connector_iter(connector_scan, _iter) {
> + if (connector_scan->encoder == encoder) {
> + connector = connector_scan;
> + break;
> + }
> + }
> + drm_connector_list_iter_end(_iter);
> +
> + if (connector && connector->display_info.num_bus_formats) {
> + u32 bus_format = connector->display_info.bus_formats[0];
>  
>   switch (bus_format) {
>   case MEDIA_BUS_FMT_RGB888_1X24:
> @@ -199,6 +215,9 @@ static void vc4_dpi_encoder_enable(struct drm_encoder 
> *encoder)
>   DRM_ERROR("Unknown media bus format %d\n", bus_format);
>   break;
>   }
> + } else {
> + /* Default to 24bit if no connector found. */
> + dpi_c |= VC4_SET_FIELD(DPI_FORMAT_24BIT_888_RGB, DPI_FORMAT);
>   }
>  
>   if (mode->flags & DRM_MODE_FLAG_NHSYNC)
> @@ -264,7 +283,7 @@ static int vc4_dpi_init_bridge(struct vc4_dpi *dpi)
>   return ret;
>   }
>  
> - if (panel)
> + if (panel) 

whitespace creep, with that fixed:

Reviewed-by: Sean Paul <seanp...@chromium.org>

>   bridge = drm_panel_bridge_add(panel, DRM_MODE_CONNECTOR_DPI);
>  
>   return drm_bridge_attach(dpi->encoder, bridge, NULL);
> -- 
> 2.16.2
> 
> ___
> dri-devel mailing list
> dri-de...@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Sean Paul, Software Engineer, Google / Chromium OS


Re: [PATCH] drm/vc4: Fix oops dereferencing DPI's connector since panel_bridge.

2018-05-02 Thread Sean Paul
On Fri, Mar 09, 2018 at 03:32:56PM -0800, Eric Anholt wrote:
> In the cleanup, I didn't notice that we needed to dereference the
> connector for the bus_format.  Fix the regression by looking up the
> first (and only) connector attached to us, and assume that its
> bus_format is what we want.  Some day it would be good to have that
> part of display_info attached to the bridge, instead.
> 
> Signed-off-by: Eric Anholt 
> Fixes: 7b1298e05310 ("drm/vc4: Switch DPI to using the panel-bridge helper.")
> Cc: Boris Brezillon 
> ---
>  drivers/gpu/drm/vc4/vc4_dpi.c | 27 +++
>  1 file changed, 23 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/vc4/vc4_dpi.c b/drivers/gpu/drm/vc4/vc4_dpi.c
> index 72c9dbd81d7f..88783e143cc2 100644
> --- a/drivers/gpu/drm/vc4/vc4_dpi.c
> +++ b/drivers/gpu/drm/vc4/vc4_dpi.c
> @@ -96,7 +96,6 @@ struct vc4_dpi {
>   struct platform_device *pdev;
>  
>   struct drm_encoder *encoder;
> - struct drm_connector *connector;
>  
>   void __iomem *regs;
>  
> @@ -164,14 +163,31 @@ static void vc4_dpi_encoder_disable(struct drm_encoder 
> *encoder)
>  
>  static void vc4_dpi_encoder_enable(struct drm_encoder *encoder)
>  {
> + struct drm_device *dev = encoder->dev;
>   struct drm_display_mode *mode = >crtc->mode;
>   struct vc4_dpi_encoder *vc4_encoder = to_vc4_dpi_encoder(encoder);
>   struct vc4_dpi *dpi = vc4_encoder->dpi;
> + struct drm_connector_list_iter conn_iter;
> + struct drm_connector *connector = NULL, *connector_scan;
>   u32 dpi_c = DPI_ENABLE | DPI_OUTPUT_ENABLE_MODE;
>   int ret;
>  
> - if (dpi->connector->display_info.num_bus_formats) {
> - u32 bus_format = dpi->connector->display_info.bus_formats[0];
> + /* Look up the connector attached to DPI so we can get the
> +  * bus_format.  Ideally the bridge would tell us the
> +  * bus_format we want, but it doesn't yet, so assume that it's
> +  * uniform throughout the bridge chain.
> +  */
> + drm_connector_list_iter_begin(dev, _iter);
> + drm_for_each_connector_iter(connector_scan, _iter) {
> + if (connector_scan->encoder == encoder) {
> + connector = connector_scan;
> + break;
> + }
> + }
> + drm_connector_list_iter_end(_iter);
> +
> + if (connector && connector->display_info.num_bus_formats) {
> + u32 bus_format = connector->display_info.bus_formats[0];
>  
>   switch (bus_format) {
>   case MEDIA_BUS_FMT_RGB888_1X24:
> @@ -199,6 +215,9 @@ static void vc4_dpi_encoder_enable(struct drm_encoder 
> *encoder)
>   DRM_ERROR("Unknown media bus format %d\n", bus_format);
>   break;
>   }
> + } else {
> + /* Default to 24bit if no connector found. */
> + dpi_c |= VC4_SET_FIELD(DPI_FORMAT_24BIT_888_RGB, DPI_FORMAT);
>   }
>  
>   if (mode->flags & DRM_MODE_FLAG_NHSYNC)
> @@ -264,7 +283,7 @@ static int vc4_dpi_init_bridge(struct vc4_dpi *dpi)
>   return ret;
>   }
>  
> - if (panel)
> + if (panel) 

whitespace creep, with that fixed:

Reviewed-by: Sean Paul 

>   bridge = drm_panel_bridge_add(panel, DRM_MODE_CONNECTOR_DPI);
>  
>   return drm_bridge_attach(dpi->encoder, bridge, NULL);
> -- 
> 2.16.2
> 
> ___
> dri-devel mailing list
> dri-de...@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Sean Paul, Software Engineer, Google / Chromium OS


  1   2   3   4   5   6   7   8   9   10   >