Re: Fence wait in mmu_interval_notifier_ops::invalidate
Hi, Christian Thanks for the reply. On 12/10/20 11:53 AM, Christian König wrote: Am 09.12.20 um 17:46 schrieb Thomas Hellström (Intel): On 12/9/20 5:37 PM, Jason Gunthorpe wrote: On Wed, Dec 09, 2020 at 05:36:16PM +0100, Thomas Hellström (Intel) wrote: Jason, Christian In most implementations of the callback mentioned in the subject there's a fence wait. What exactly is it needed for? Invalidate must stop DMA before returning, so presumably drivers using a dma fence are relying on a dma fence mechanism to stop DMA. Yes, so far I follow, but what's the reason drivers need to stop DMA? Well in general an invalidation means that the specified part of the page tables are updated, either with new addresses or new access flags. In both cases you need to stop the DMA because you could otherwise work with stale data, e.g. read/write with the wrong addresses or write to a read only region etc... Yes. That's clear. I'm just trying to understand the complete implications of doing that. Is it for invlidation before breaking COW after fork or something related? This is just one of many use cases which could invalidate a range. But there are many more, both from the kernel as well as userspace. Just imaging that userspace first mmaps() some anonymous memory r/w, starts a DMA to it and while the DMA is ongoing does a readonly mmap() of libc to the same location. My understanding of this particular case is that hardware would continue to DMA to orphaned pages that are pinned until the driver is done with DMA, unless hardware would somehow in-flight pick up the new PTE addresses pointing to libc but not the protection? Thanks, Thomas Since most hardware doesn't have recoverable page faults guess what would happen if we don't wait for the DMA to finish? That would be a security hole you can push an elephant through :) Cheers, Christian. Thanks, Thomas Jason ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v7 18/18] drm/i915/hdcp: Enable HDCP 2.2 MST support
On 2020-12-10 at 11:56:40 +0530, Anshuman Gupta wrote: > Enable HDCP 2.2 over DP MST. > Authenticate and enable port encryption only once for > an active HDCP 2.2 session, once port is authenticated > and encrypted enable encryption for each stream that > requires encryption on this port. > > Similarly disable the stream encryption for each encrypted > stream, once all encrypted stream encryption is disabled, > disable the port HDCP encryption and deauthenticate the port. > Like in the previous patch (for 1.4 MST?) split this patch into 2. one for configuring the stream encryptions status for 2.2 another one for enabling the HDCP2.2 MST support. Ram > v2: > - Add connector details in drm_err. [Ram] > - 's/port_auth/hdcp_auth_status'. [Ram] > - Added a debug print for stream enc. > v3: > - uniformity for connector detail in DMESG. [Ram] > > Cc: Ramalingam C > Reviewed-by: Uma Shankar > Tested-by: Karthik B S > Signed-off-by: Anshuman Gupta > --- > drivers/gpu/drm/i915/display/intel_hdcp.c | 53 ++- > 1 file changed, 51 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c > b/drivers/gpu/drm/i915/display/intel_hdcp.c > index 65dd39b44688..4b221c298835 100644 > --- a/drivers/gpu/drm/i915/display/intel_hdcp.c > +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c > @@ -1700,6 +1700,36 @@ static int hdcp2_authenticate_sink(struct > intel_connector *connector) > return ret; > } > > +static int hdcp2_enable_stream_encryption(struct intel_connector *connector) > +{ > + struct intel_digital_port *dig_port = > intel_attached_dig_port(connector); > + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); > + struct intel_hdcp *hdcp = >hdcp; > + enum transcoder cpu_transcoder = hdcp->cpu_transcoder; > + enum port port = dig_port->base.port; > + int ret = 0; > + > + if (!(intel_de_read(dev_priv, HDCP2_STATUS(dev_priv, cpu_transcoder, > port)) & > + LINK_ENCRYPTION_STATUS)) { > + drm_err(_priv->drm, "[%s:%d] HDCP 2.2 Link is not > encrypted\n", > + connector->base.name, connector->base.base.id); > + return -EPERM; > + } > + > + if (hdcp->shim->stream_2_2_encryption) { > + ret = hdcp->shim->stream_2_2_encryption(connector, true); > + if (ret) { > + drm_err(_priv->drm, "[%s:%d] Failed to enable HDCP > 2.2 stream enc\n", > + connector->base.name, connector->base.base.id); > + return ret; > + } > + drm_dbg_kms(_priv->drm, "HDCP 2.2 transcoder: %s stream > encrypted\n", > + transcoder_name(hdcp->stream_transcoder)); > + } > + > + return ret; > +} > + > static int hdcp2_enable_encryption(struct intel_connector *connector) > { > struct intel_digital_port *dig_port = > intel_attached_dig_port(connector); > @@ -1838,7 +1868,7 @@ static int hdcp2_authenticate_and_encrypt(struct > intel_connector *connector) > drm_dbg_kms(>drm, "Port deauth failed.\n"); > } > > - if (!ret) { > + if (!ret && !dig_port->hdcp_auth_status) { > /* >* Ensuring the required 200mSec min time interval between >* Session Key Exchange and encryption. > @@ -1853,6 +1883,8 @@ static int hdcp2_authenticate_and_encrypt(struct > intel_connector *connector) > } > } > > + ret = hdcp2_enable_stream_encryption(connector); > + > return ret; > } > > @@ -1898,11 +1930,26 @@ static int _intel_hdcp2_disable(struct > intel_connector *connector) > struct intel_digital_port *dig_port = > intel_attached_dig_port(connector); > struct drm_i915_private *i915 = to_i915(connector->base.dev); > struct hdcp_port_data *data = _port->hdcp_port_data; > + struct intel_hdcp *hdcp = >hdcp; > int ret; > > drm_dbg_kms(>drm, "[%s:%d] HDCP2.2 is being Disabled\n", > connector->base.name, connector->base.base.id); > > + if (hdcp->shim->stream_2_2_encryption) { > + ret = hdcp->shim->stream_2_2_encryption(connector, false); > + if (ret) { > + drm_err(>drm, "[%s:%d] Failed to disable HDCP 2.2 > stream enc\n", > + connector->base.name, connector->base.base.id); > + return ret; > + } > + drm_dbg_kms(>drm, "HDCP 2.2 transcoder: %s stream > encryption disabled\n", > + transcoder_name(hdcp->stream_transcoder)); > + } > + > + if (dig_port->num_hdcp_streams > 0) > + return ret; > + > ret = hdcp2_disable_encryption(connector); > > if (hdcp2_deauthenticate_port(connector) < 0) > @@ -1926,6 +1973,7 @@ static int intel_hdcp2_check_link(struct > intel_connector *connector) > int ret = 0; > >
Re: [PATCH v7 17/18] drm/i915/hdcp: Support for HDCP 2.2 MST shim callbacks
On 2020-12-10 at 11:56:39 +0530, Anshuman Gupta wrote: > Add support for HDCP 2.2 DP MST shim callback. > This adds existing DP HDCP shim callback for Link Authentication > and Encryption and HDCP 2.2 stream encryption > callback. > > v2: > - Added a WARN_ON() instead of drm_err. [Uma] > - Cosmetic changes. [Uma] > v3: > - 's/port_data/hdcp_port_data' [Ram] > - skip redundant link check. [Ram] > v4: > - use pipe instead of port to access HDCP2_STREAM_STATUS How this missed the functional test till now? Always true because port's stream status was referred? > > Cc: Ramalingam C > Reviewed-by: Uma Shankar > Tested-by: Karthik B S > Signed-off-by: Anshuman Gupta > --- > .../drm/i915/display/intel_display_types.h| 4 + > drivers/gpu/drm/i915/display/intel_dp_hdcp.c | 89 +-- > 2 files changed, 85 insertions(+), 8 deletions(-) > > diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h > b/drivers/gpu/drm/i915/display/intel_display_types.h > index 63de25b40eff..da91e3f4ff27 100644 > --- a/drivers/gpu/drm/i915/display/intel_display_types.h > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h > @@ -378,6 +378,10 @@ struct intel_hdcp_shim { > int (*config_stream_type)(struct intel_digital_port *dig_port, > bool is_repeater, u8 type); > > + /* Enable/Disable HDCP 2.2 stream encryption on DP MST Transport Link */ > + int (*stream_2_2_encryption)(struct intel_connector *connector, > + bool enable); > + > /* HDCP2.2 Link Integrity Check */ > int (*check_2_2_link)(struct intel_digital_port *dig_port, > struct intel_connector *connector); > diff --git a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c > b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c > index 9ade1ad3a80c..f372e25edab4 100644 > --- a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c > +++ b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c > @@ -698,18 +698,14 @@ intel_dp_mst_hdcp_stream_encryption(struct > intel_connector *connector, > return 0; > } > > -static > -bool intel_dp_mst_hdcp_check_link(struct intel_digital_port *dig_port, > - struct intel_connector *connector) > +static bool intel_dp_mst_get_qses_status(struct intel_digital_port *dig_port, > + struct intel_connector *connector) > { > struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); > - struct intel_dp *intel_dp = _port->dp; > struct drm_dp_query_stream_enc_status_ack_reply reply; > + struct intel_dp *intel_dp = _port->dp; > int ret; > > - if (!intel_dp_hdcp_check_link(dig_port, connector)) > - return false; > - > ret = drm_dp_send_query_stream_enc_status(_dp->mst_mgr, > connector->port, ); > if (ret) { > @@ -726,6 +722,78 @@ bool intel_dp_mst_hdcp_check_link(struct > intel_digital_port *dig_port, > return reply.auth_completed && reply.encryption_enabled; > } > > +static > +bool intel_dp_mst_hdcp_check_link(struct intel_digital_port *dig_port, > + struct intel_connector *connector) > +{ > + if (!intel_dp_hdcp_check_link(dig_port, connector)) > + return false; this also could be optimised for the connector with port authentication only? > + > + return intel_dp_mst_get_qses_status(dig_port, connector); > +} > + > +static int > +intel_dp_mst_hdcp2_stream_encryption(struct intel_connector *connector, > + bool enable) > +{ > + struct intel_digital_port *dig_port = > intel_attached_dig_port(connector); > + struct drm_i915_private *i915 = to_i915(connector->base.dev); > + struct hdcp_port_data *data = _port->hdcp_port_data; > + struct intel_hdcp *hdcp = >hdcp; > + enum transcoder cpu_transcoder = hdcp->stream_transcoder; > + enum pipe pipe = (enum pipe)cpu_transcoder; > + enum port port = dig_port->base.port; > + int ret; > + > + drm_WARN_ON(>drm, enable && > + !!(intel_de_read(i915, HDCP2_AUTH_STREAM(i915, > cpu_transcoder, port)) > + & AUTH_STREAM_TYPE) != data->streams[0].stream_type); > + > + ret = intel_dp_mst_toggle_hdcp_stream_select(connector, enable); > + if (ret) > + return ret; > + > + /* Wait for encryption confirmation */ > + if (intel_de_wait_for_register(i915, > +HDCP2_STREAM_STATUS(i915, > cpu_transcoder, pipe), > +STREAM_ENCRYPTION_STATUS, > +enable ? STREAM_ENCRYPTION_STATUS : 0, > +HDCP_ENCRYPT_STATUS_CHANGE_TIMEOUT_MS)) { > + drm_err(>drm, "Timed out waiting for transcoder: %s > stream encryption %s\n", > + transcoder_name(cpu_transcoder), enable ? "enabled" : >
RE: [Intel-gfx] [PATCH 1/2] drm/framebuffer: Format modifier for Intel Gen 12 render compression with Clear Color
> -Original Message- > From: Imre Deak > Sent: Tuesday, December 1, 2020 4:05 AM > To: Chery, Nanley G ; Chris Wilson wilson.co.uk>; Ville Syrjälä > Cc: Daniel Vetter ; intel-...@lists.freedesktop.org; Nikula, > Jani ; Daniel Vetter ; > Kondapally, Kalyan ; Pandiyan, Dhinakaran > ; dri-devel@lists.freedesktop.org > Subject: Re: [Intel-gfx] [PATCH 1/2] drm/framebuffer: Format modifier for > Intel Gen 12 render compression with Clear Color > > Hi Nanley, > > thanks for the review. > > +Ville, Chris. > > On Tue, Dec 01, 2020 at 02:18:26AM +0200, Chery, Nanley G wrote: > > Hi Imre, > > > > I have a question and a couple comments: > > > > Is the map of the clear color address creating a new synchronization > > point between the GPU and CPU? If so, I wonder how this will impact > > performance. > > The kmap to read the clear value is not adding any sync overhead if > that's what you mean. But the clear value must be in place before we > read it out and that should be guaranteed by the flush we do anyway to wait > for the render result (even considering the explicit L3/RT flush, depth > stall the spec requires for fast clears). > > However now that you mention: atm the kmap/readout happens after the > explicit but before the implicit fence-wait. I think it should happen > after the implicit fence-wait. > > Ville, Chris, could you confirm the above and also that the above flush > is enough to ensure the CPU read is coherent? > > > There was some talk of asynchronously updating the clear color > > register a while back. > > Couldn't find anything with a quick search, do you have a pointer? Just > before the flip we must wait for the render results anyway, as we do > now, so not sure how it could be optimized. > There were some offline discussions, so I don't have a reference unfortunately. Though, given what you shared above it seems like it's actually not an issue. > > We probably don't have to update the header, but we noticed in our > > testing that the clear color prefers an alignment greater than 64B. > > Unfortunately, I can't find any bspec note about this. As long as the > > buffer creators are aware though, I think we should be fine. I don't > > know if this is the best forum to bring it up, but I thought I'd > > share. > > Yes, would be good to clarify this and get it also to the spec. Then the > driver should also check the alignment of the 3rd FB plane. > I plan to run some more tests and file a bug in the spec. I see that the IGT test only clears the fb once. Just to confirm, is the clear color offset read from on every frame? Userspace would like to be able to pass different clear colors for an fb. -Nanley > > Seems like the upper converted clear color is untested due to the lack > > of RGBX16 support. I suppose that if there are any issues there, they > > can be fixed later... > > Yes, a 64bpp RC-CC subtest in IGT is missing, should be easy to add > that. > > --Imre ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v7 14/18] drm/i915/hdcp: MST streams support in hdcp port_data
On 2020-12-10 at 11:56:36 +0530, Anshuman Gupta wrote: > Add support for multiple mst stream in hdcp port data > which will be used by RepeaterAuthStreamManage msg and > HDCP 2.2 security f/w for m' validation. > > Security f/w doesn't have any provision to mark the > stream_type for each stream separately, it just take > single input of stream_type while authenticating the > port. ".. authenticating the port and applies the same stream type to all ports" > So driver mark each stream_type with common > highest supported content type for all streams in > DP MST Topology. > > Security f/w supports RepeaterAuthStreamManage msg and m' You could add "though it is not mandatory" > validation only once during port authentication and encryption. > Ideally it should support dynamic update of content_type > and should support RepeaterAuthStreamManage msg and m' validation > whenever required. > > v2: > - Init the hdcp port data k for HDMI/DP SST stream. > v3: > - Cosmetic changes. [Uma] > v4: > - 's/port_auth/hdcp_port_auth'. [Ram] > - Commit log improvement. > v5: > - Comment and commit log improvement. [Ram] > > Cc: Ramalingam C > Reviewed-by: Uma Shankar > Tested-by: Karthik B S > Signed-off-by: Anshuman Gupta > --- > .../drm/i915/display/intel_display_types.h| 4 +- > drivers/gpu/drm/i915/display/intel_hdcp.c | 113 +++--- > 2 files changed, 102 insertions(+), 15 deletions(-) > > diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h > b/drivers/gpu/drm/i915/display/intel_display_types.h > index b74c10c8b01c..b37a02a73de6 100644 > --- a/drivers/gpu/drm/i915/display/intel_display_types.h > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h > @@ -1502,10 +1502,12 @@ struct intel_digital_port { > enum phy_fia tc_phy_fia; > u8 tc_phy_fia_idx; > > - /* protects num_hdcp_streams reference count, hdcp_port_data */ > + /* protects num_hdcp_streams reference count, hdcp_port_data and > hdcp_auth_status */ > struct mutex hdcp_mutex; > /* the number of pipes using HDCP signalling out of this port */ > unsigned int num_hdcp_streams; > + /* port HDCP auth status */ > + bool hdcp_auth_status; > /* HDCP port data need to pass to security f/w */ > struct hdcp_port_data hdcp_port_data; > > diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c > b/drivers/gpu/drm/i915/display/intel_hdcp.c > index 2bec26123a05..c21a6a6c545c 100644 > --- a/drivers/gpu/drm/i915/display/intel_hdcp.c > +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c > @@ -26,6 +26,74 @@ > #define KEY_LOAD_TRIES 5 > #define HDCP2_LC_RETRY_CNT 3 > > +static int intel_conn_to_vcpi(struct intel_connector *connector) > +{ > + /* For HDMI this is forced to be 0x0. For DP SST also this is 0x0. */ > + return connector->port ? connector->port->vcpi.vcpi : 0; > +} > + > +/* > + * intel_hdcp_required_content_stream select most highest common possible > HDCP selects the most > + * content_type for all streams in DP MST topology because security f/w > doesn't > + * have any provision to mark content_type for each stream separately, it > marks > + * all available streams with the content_type proivided at the time of port > + * authentication. This may prohibit the userspace to use type1 content on > + * HDCP 2.2 capable sink because of other sink are not capable of HDCP 2.2 in > + * DP MST topology. Ideally security f/w should change its policy to mark Though it is not compulsary, security fw should > + * different content_type for different streams. content types with these addressed LGTM. Reviewed-by: Ramalingam C > + */ > +static int > +intel_hdcp_required_content_stream(struct intel_digital_port *dig_port) > +{ > + struct drm_connector_list_iter conn_iter; > + struct intel_digital_port *conn_dig_port; > + struct intel_connector *connector; > + struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); > + struct hdcp_port_data *data = _port->hdcp_port_data; > + bool enforce_type0 = false; > + int k; > + > + if (dig_port->hdcp_auth_status) > + return 0; > + > + drm_connector_list_iter_begin(>drm, _iter); > + for_each_intel_connector_iter(connector, _iter) { > + if (!intel_encoder_is_mst(intel_attached_encoder(connector))) > + continue; > + > + conn_dig_port = intel_attached_dig_port(connector); > + if (conn_dig_port != dig_port) > + continue; > + > + if (connector->base.status == connector_status_disconnected) > + continue; > + > + if (!enforce_type0 && !intel_hdcp2_capable(connector)) > + enforce_type0 = true; > + > + data->streams[data->k].stream_id = > intel_conn_to_vcpi(connector); > + data->k++; > + > + /* if there is only one active stream */ > + if
Re: [PATCH v7 09/18] drm/i915/hdcp: Enable Gen12 HDCP 1.4 DP MST support
On 2020-12-10 at 11:56:31 +0530, Anshuman Gupta wrote: > Enable HDCP 1.4 over DP MST for Gen12. > > v2: > - Enable HDCP for <= Gen12 platforms. [Ram] > > Cc: Ramalingam C > Tested-by: Karthik B S > Signed-off-by: Anshuman Gupta > --- > drivers/gpu/drm/i915/display/intel_dp_mst.c | 6 ++ > 1 file changed, 2 insertions(+), 4 deletions(-) > > diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c > b/drivers/gpu/drm/i915/display/intel_dp_mst.c > index 47beb442094f..ae24e1af49be 100644 > --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c > +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c > @@ -829,12 +829,10 @@ static struct drm_connector > *intel_dp_add_mst_connector(struct drm_dp_mst_topolo > intel_attach_force_audio_property(connector); > intel_attach_broadcast_rgb_property(connector); > > - > - /* TODO: Figure out how to make HDCP work on GEN12+ */ > - if (INTEL_GEN(dev_priv) < 12) { > + if (INTEL_GEN(dev_priv) <= 12) { > ret = intel_dp_init_hdcp(dig_port, intel_connector); > if (ret) > - DRM_DEBUG_KMS("HDCP init failed, skipping.\n"); > + drm_dbg_kms(_priv->drm, "HDCP init failed, > skipping.\n"); "HDCP MST init failed" might be more meaningful with connector name and ID. With that addressed Reviewed-by: Ramalingam C > } > > /* > -- > 2.26.2 > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v7 08/18] drm/i915/hdcp: Enable HDCP 1.4 stream encryption
On 2020-12-10 at 11:56:30 +0530, Anshuman Gupta wrote: > Enable HDCP 1.4 DP MST stream encryption. IMHO tile of "Configure HDCP1.4 MST steram encryption status" would suit more. But i leave that to your call. > > Enable stream encryption once encryption is enabled on > the DP transport driving the link for each stream which > has requested encryption. > > Disable stream encryption for each stream that no longer > requires encryption before disabling HDCP encryption on > the link. > > v2: > - Added debug print for stream encryption. > - Disable the hdcp on port after disabling last stream > encryption. > v3: > - Cosmetic change, removed the value less comment. [Uma] > v4: > - Split the Gen12 HDCP enablement patch. [Ram] > - Add connector details in drm_err. > v5: > - uniformity for connector detail in DMESG. [Ram] > - comments improvement. [Ram] > Patch LGTM. Reviewed-by: Ramalingam C > Cc: Ramalingam C > Reviewed-by: Uma Shankar > Tested-by: Karthik B S > Signed-off-by: Anshuman Gupta > --- > drivers/gpu/drm/i915/display/intel_hdcp.c | 38 +++ > 1 file changed, 25 insertions(+), 13 deletions(-) > > diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c > b/drivers/gpu/drm/i915/display/intel_hdcp.c > index 6e6465b4ecfa..fce444d69521 100644 > --- a/drivers/gpu/drm/i915/display/intel_hdcp.c > +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c > @@ -766,10 +766,17 @@ static int intel_hdcp_auth(struct intel_connector > *connector) > return -ETIMEDOUT; > } > > - /* > - * XXX: If we have MST-connected devices, we need to enable encryption > - * on those as well. > - */ > + /* DP MST Auth Part 1 Step 2.a and Step 2.b */ > + if (shim->stream_encryption) { > + ret = shim->stream_encryption(connector, true); > + if (ret) { > + drm_err(_priv->drm, "[%s:%d] Failed to enable HDCP > 1.4 stream enc\n", > + connector->base.name, connector->base.base.id); > + return ret; > + } > + drm_dbg_kms(_priv->drm, "HDCP 1.4 transcoder: %s stream > encrypted\n", > + transcoder_name(hdcp->stream_transcoder)); > + } > > if (repeater_present) > return intel_hdcp_auth_downstream(connector); > @@ -791,18 +798,23 @@ static int _intel_hdcp_disable(struct intel_connector > *connector) > drm_dbg_kms(_priv->drm, "[%s:%d] HDCP is being disabled...\n", > connector->base.name, connector->base.base.id); > > + if (hdcp->shim->stream_encryption) { > + ret = hdcp->shim->stream_encryption(connector, false); > + if (ret) { > + drm_err(_priv->drm, "[%s:%d] Failed to disable HDCP > 1.4 stream enc\n", > + connector->base.name, connector->base.base.id); > + return ret; > + } > + drm_dbg_kms(_priv->drm, "HDCP 1.4 transcoder: %s stream > encryption disabled\n", > + transcoder_name(hdcp->stream_transcoder)); > + } > + > /* > - * If there are other connectors on this port using HDCP, don't disable > - * it. Instead, toggle the HDCP signalling off on that particular > - * connector/pipe and exit. > + * If there are other connectors on this port using HDCP, don't disable > it > + * until it disabled HDCP encryption for all connectors in MST topology. >*/ > - if (dig_port->num_hdcp_streams > 0) { > - ret = hdcp->shim->toggle_signalling(dig_port, > - cpu_transcoder, false); > - if (ret) > - DRM_ERROR("Failed to disable HDCP signalling\n"); > + if (dig_port->num_hdcp_streams > 0) > return ret; > - } > > hdcp->hdcp_encrypted = false; > intel_de_write(dev_priv, HDCP_CONF(dev_priv, cpu_transcoder, port), 0); > -- > 2.26.2 > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v7 04/18] drm/i915/hdcp: No HDCP when encoder is't initialized
On 2020-12-10 at 11:56:26 +0530, Anshuman Gupta wrote: > There can be situation when DP MST connector is created without > mst modeset being done, in those cases connector->encoder will be > NULL. MST connector->encoder initializes after modeset. > Don't enable HDCP in such cases to prevent any crash. LGTM.. Reviewed-by: Ramalingam C > > Cc: Ramalingam C > Cc: Juston Li > Tested-by: Karthik B S > Signed-off-by: Anshuman Gupta > --- > drivers/gpu/drm/i915/display/intel_hdcp.c | 6 ++ > 1 file changed, 6 insertions(+) > > diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c > b/drivers/gpu/drm/i915/display/intel_hdcp.c > index b9d8825e2bb1..7d63e9495956 100644 > --- a/drivers/gpu/drm/i915/display/intel_hdcp.c > +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c > @@ -2106,6 +2106,12 @@ int intel_hdcp_enable(struct intel_connector > *connector, > if (!hdcp->shim) > return -ENOENT; > > + if (!connector->encoder) { > + drm_err(_priv->drm, "[%s:%d] encoder is not initialized\n", > + connector->base.name, connector->base.base.id); > + return -ENODEV; > + } > + > mutex_lock(>mutex); > mutex_lock(_port->hdcp_mutex); > drm_WARN_ON(_priv->drm, > -- > 2.26.2 > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 210543] amdgpu Kernel panic:__ttm_dma_free_page.isra.0+0xac/0xe8 [ttm]
https://bugzilla.kernel.org/show_bug.cgi?id=210543 --- Comment #4 from Ancheng (acyel...@gmail.com) --- (In reply to Alex Deucher from comment #1) > Please attach your full dmesg output. Thanks for your response, attachment please find the dmesg output. There are some differences in the call trace for each hang. -- You are receiving this mail because: You are watching the assignee of the bug. ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 210543] amdgpu Kernel panic:__ttm_dma_free_page.isra.0+0xac/0xe8 [ttm]
https://bugzilla.kernel.org/show_bug.cgi?id=210543 --- Comment #3 from Ancheng (acyel...@gmail.com) --- Created attachment 294095 --> https://bugzilla.kernel.org/attachment.cgi?id=294095=edit dmesg file1 -- You are receiving this mail because: You are watching the assignee of the bug. ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 210543] amdgpu Kernel panic:__ttm_dma_free_page.isra.0+0xac/0xe8 [ttm]
https://bugzilla.kernel.org/show_bug.cgi?id=210543 --- Comment #2 from Ancheng (acyel...@gmail.com) --- Created attachment 294093 --> https://bugzilla.kernel.org/attachment.cgi?id=294093=edit dmesg file -- You are receiving this mail because: You are watching the assignee of the bug. ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v2 0/3] Experimental freesync video mode optimization
Hello Simon, Hope you are doing well, I was helping out Aurabindo and the team with the design, so I have taken the liberty of adding some comments on behalf of the team, Inline. On 11/12/20 3:31 am, Simon Ser wrote: > Hi, > > (CC dri-devel, Pekka and Martin who might be interested in this as well.) > > On Thursday, December 10th, 2020 at 7:48 PM, Aurabindo Pillai > wrote: > >> This patchset enables freesync video mode usecase where the userspace >> can request a freesync compatible video mode such that switching to this >> mode does not trigger blanking. >> >> This feature is guarded by a module parameter which is disabled by >> default. Enabling this paramters adds additional modes to the driver >> modelist, and also enables the optimization to skip modeset when using >> one of these modes. > Thanks for working on this, it's an interesting feature! However I'd like to > take some time to think about the user-space API for this. > > As I understand it, some new synthetic modes are added, and user-space can > perform a test-only atomic *without* ALLOW_MODESET to figure out whether it > can > switch to a mode without blanking the screen. The implementation is in those lines, but a bit different. The idea is to: - check if the monitor supports VRR, - If it does, add some new modes which are in the VRR tolerance range, as new video modes in the list (with driver flag). - when you get modeset on any of these modes, skip the full modeset, and just adjust the front_porch timing so they are not test-only as such, for any user-space these modes will be as real as any other probed modes of the list. > > However the exact modes amdgpu adds are just some guesses. I think it would be > great if user-space could control the min/max refresh rate values directly. > Not only this would remove the need for the kernel to hard-code "well-known > video refresh rates", but this would also enable more use-cases. For instance > some users might want to mitigate flickering on their screen by reducing the > VRR range. Some users might want to lower their screen refresh rate for power > savings. > > What do you think? Would you be fine with adding min/max VRR range properties? > > If you're scared about the user-space code requirement, I can provide that. This sounds like a reasonable approach, and there is no reason why we can't do this if we have the proper userspace support as you mentioned. But what we thought would be a sensitive approach towards this feature would be: - *Phase 1: *Add this feature experimentally as kernel-only change, to: test out its functionality on all all supported platforms first, without going for the UAPI complexity. gain attention from UAPI stakeholders and get them involved for the UAPI design (so far so good :)). - *Phase 2:* Have a design discussions with user-space stakeholders, examine the use-cases possible, and then create a reasonable UAPI, and make the other solution a fallback method. So I guess we can fork out a parallel discussion for the UAPI thread too. How does this sound to you ? - Shashank > > Thanks, > > Simon Ser ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v8, 2/6] dt-bindings: mediatek: add description for mt8183 display
On Thu, 10 Dec 2020 17:07:38 +0800, Yongqiang Niu wrote: > add description for mt8183 display > > Signed-off-by: Yongqiang Niu > --- > Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > Acked-by: Rob Herring ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v8, 1/6] dt-bindings: mediatek: add rdma_fifo_size description for mt8183 display
On Thu, Dec 10, 2020 at 05:07:37PM +0800, Yongqiang Niu wrote: > rdma fifo size may be different even in same SOC, add this > property to the corresponding rdma > > Signed-off-by: Yongqiang Niu > --- > .../bindings/display/mediatek/mediatek,disp.txt | 16 > > 1 file changed, 16 insertions(+) > > diff --git > a/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt > b/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt > index 1212207..64c64ee 100644 > --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt > +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt > @@ -66,6 +66,13 @@ Required properties (DMA function blocks): >argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.txt >for details. > > +Optional properties (RDMA function blocks): > +- mediatek,rdma_fifo_size: rdma fifo size may be different even in same SOC, > add this mediatek,rdma-fifo-size > + property to the corresponding rdma > + the value is the Max value which defined in hardware data sheet. > + rdma_fifo_size of rdma0 in mt8183 is 5120 > + rdma_fifo_size of rdma1 in mt8183 is 2048 > + > Examples: > > mmsys: clock-controller@1400 { > @@ -207,3 +214,12 @@ od@14023000 { > power-domains = < MT8173_POWER_DOMAIN_MM>; > clocks = < CLK_MM_DISP_OD>; > }; > + > +rdma1: rdma@1400c000 { > + compatible = "mediatek,mt8183-disp-rdma"; > + reg = <0 0x1400c000 0 0x1000>; > + interrupts = ; > + power-domains = < MT8183_POWER_DOMAIN_DISP>; > + clocks = < CLK_MM_DISP_RDMA1>; > + mediatek,rdma_fifo_size = <2048>; > +}; > -- > 1.8.1.1.dirty > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v2 4/5] dt-bindings: phy: mixel: mipi-dsi-phy: Add Mixel combo PHY support for i.MX8qxp
On Wed, 09 Dec 2020 14:24:27 +0800, Liu Ying wrote: > Add support for Mixel MIPI DPHY + LVDS PHY combo IP > as found on Freescale i.MX8qxp SoC. > > Cc: Guido Günther > Cc: Kishon Vijay Abraham I > Cc: Vinod Koul > Cc: Rob Herring > Cc: NXP Linux Team > Signed-off-by: Liu Ying > --- > v1->v2: > * Add the binding for i.MX8qxp Mixel combo PHY based on the converted binding. > (Guido) > > .../bindings/phy/mixel,mipi-dsi-phy.yaml | 41 > -- > 1 file changed, 38 insertions(+), 3 deletions(-) > Reviewed-by: Rob Herring ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v2 3/5] dt-bindings: phy: Convert mixel, mipi-dsi-phy to json-schema
On Wed, 09 Dec 2020 14:24:26 +0800, Liu Ying wrote: > This patch converts the mixel,mipi-dsi-phy binding to > DT schema format using json-schema. > > Comparing to the plain text version, the new binding adds > the 'assigned-clocks', 'assigned-clock-parents' and > 'assigned-clock-rates' properites, otherwise 'make dtbs_check' > would complain that there are mis-matches. Also, the new > binding requires the 'power-domains' property since all potential > SoCs that embed this PHY would provide a power domain for it. > The example of the new binding takes reference to the latest > dphy node in imx8mq.dtsi. > > Cc: Guido Günther > Cc: Kishon Vijay Abraham I > Cc: Vinod Koul > Cc: Rob Herring > Cc: NXP Linux Team > Signed-off-by: Liu Ying > --- > v1->v2: > * Newly introduced in v2. (Guido) > > .../devicetree/bindings/phy/mixel,mipi-dsi-phy.txt | 29 - > .../bindings/phy/mixel,mipi-dsi-phy.yaml | 73 > ++ > 2 files changed, 73 insertions(+), 29 deletions(-) > delete mode 100644 > Documentation/devicetree/bindings/phy/mixel,mipi-dsi-phy.txt > create mode 100644 > Documentation/devicetree/bindings/phy/mixel,mipi-dsi-phy.yaml > Reviewed-by: Rob Herring ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[radeon-alex:amd-staging-drm-next 534/912] drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c:904:6: warning: old-style function definition
Hi Prike, FYI, the error/warning still remains. tree: git://people.freedesktop.org/~agd5f/linux.git amd-staging-drm-next head: 82811178dacd6530cb2702e97e9c25f253c61a6b commit: 16cf2b67735cdd2f97aade032f8d720c8b089523 [534/912] drm/amdgpu: add s0i3 capacity check for s0i3 routine config: i386-randconfig-r005-20201210 (attached as .config) compiler: gcc-9 (Debian 9.3.0-15) 9.3.0 reproduce (this is a W=1 build): git remote add radeon-alex git://people.freedesktop.org/~agd5f/linux.git git fetch --no-tags radeon-alex amd-staging-drm-next git checkout 16cf2b67735cdd2f97aade032f8d720c8b089523 # save the attached .config to linux build tree make W=1 ARCH=i386 If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot All warnings (new ones prefixed by >>): drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c: In function 'amdgpu_acpi_is_s0ix_supported': >> drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c:904:6: warning: old-style function >> definition [-Wold-style-definition] 904 | bool amdgpu_acpi_is_s0ix_supported() | ^ vim +904 drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c 898 899 /** 900 * amdgpu_acpi_is_s0ix_supported 901 * 902 * returns true if supported, false if not. 903 */ > 904 bool amdgpu_acpi_is_s0ix_supported() --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org .config.gz Description: application/gzip ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[git pull] drm fixes for 5.10 final
Hi Linus, Last week of fixes, just amdgpu and i915 collections. We had a i915 regression reported by HJ Lu reported this morning, and this contains a fix for that he has tested. There are a fair few other fixes, but they are spread across the two drivers, and all fairly self contained. I'm going to send you out drm-next for next week in a few hours as I'm going on holidays until next Friday, I likely won't be checking email too closely, but Daniel should be available for any emergency. Dave. drm-fixes-2020-12-11: drm fixes for 5.10 final amdgpu: - Fan fix for CI asics - Fix a warning in possible_crtcs - Build fix for when debugfs is disabled - Display overflow fix - Display watermark fixes for Renoir - SDMA 5.2 fix - Stolen vga memory regression fix - Power profile fixes - Fix a regression from removal of GEM and PRIME callbacks amdkfd: - Fix a memory leak in dmabuf import i915: - rc7 regression fix for modesetting - vdsc/dp slice fixes - gen9 mocs entries fix - preemption timeout fix - unsigned compare against 0 fix - selftest fix - submission error propogating fix - request flow suspend fix The following changes since commit 0477e92881850d44910a7e94fc2c46f96faa131f: Linux 5.10-rc7 (2020-12-06 14:25:12 -0800) are available in the Git repository at: git://anongit.freedesktop.org/drm/drm tags/drm-fixes-2020-12-11 for you to fetch changes up to b1f195fc49812359296a901e26cc7c0b761d8a70: drm/i915/display: Go softly softly on initial modeset failure (2020-12-11 09:54:30 +1000) drm fixes for 5.10 final amdgpu: - Fan fix for CI asics - Fix a warning in possible_crtcs - Build fix for when debugfs is disabled - Display overflow fix - Display watermark fixes for Renoir - SDMA 5.2 fix - Stolen vga memory regression fix - Power profile fixes - Fix a regression from removal of GEM and PRIME callbacks amdkfd: - Fix a memory leak in dmabuf import i915: - rc7 regression fix for modesetting - vdsc/dp slice fixes - gen9 mocs entries fix - preemption timeout fix - unsigned compare against 0 fix - selftest fix - submission error propogatig fix - request flow suspend fix Alex Deucher (3): drm/amdgpu/powerplay: parse fan table for CI asics drm/amdgpu/disply: set num_crtc earlier drm/amdgpu: fix size calculation with stolen vga memory Andrey Grodzovsky (1): drm/amdgpu: Initialise drm_gem_object_funcs for imported BOs Arnd Bergmann (1): drm/amdgpu: fix debugfs creation/removal, again Changfeng (1): drm/amd/pm: update smu10.h WORKLOAD_PPLIB setting for raven Chris Park (1): drm/amd/display: Prevent bandwidth overflow Chris Wilson (5): drm/i915/gem: Propagate error from cancelled submit due to context closure drm/i915/gt: Ignore repeated attempts to suspend request flow across reset drm/i915/gt: Cancel the preemption timeout on responding to it drm/i915/gt: Declare gen9 has 64 mocs entries! drm/i915/display: Go softly softly on initial modeset failure Colin Ian King (1): drm/i915: fix size_t greater or equal to zero comparison Dan Carpenter (1): drm/i915/gem: Check the correct variable in selftest Dave Airlie (2): Merge tag 'amd-drm-fixes-5.10-2020-12-09' of git://people.freedesktop.org/~agd5f/linux into drm-fixes Merge tag 'drm-intel-fixes-2020-12-09' of git://anongit.freedesktop.org/drm/drm-intel into drm-fixes Evan Quan (1): drm/amd/pm: typo fix (CUSTOM -> COMPUTE) Felix Kuehling (1): drm/amdkfd: Fix leak in dmabuf import Manasi Navare (1): drm/i915/display/dp: Compute the correct slice count for VDSC on DP Stanley.Yang (1): drm/amdgpu: fix sdma instance fw version and feature version init Sung Lee (1): drm/amd/display: Add wm table for Renoir drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c| 8 +- drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c| 41 drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c| 3 + drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c| 13 +-- drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h| 6 -- drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c | 2 +- drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 2 + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 9 +- .../drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c | 93 ++- drivers/gpu/drm/amd/display/dc/core/dc_link.c | 7 +- drivers/gpu/drm/amd/pm/inc/smu10.h | 14 ++- .../drm/amd/pm/powerplay/hwmgr/processpptables.c | 103 - .../gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c | 9 +- .../drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c| 2 +- drivers/gpu/drm/i915/display/intel_display.c | 2 +- drivers/gpu/drm/i915/display/intel_dp.c| 2 +- drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c | 7 +- drivers/gpu/drm/i915/gt/intel_lrc.c
Re: [patch 27/30] xen/events: Only force affinity mask for percpu interrupts
On 12/10/20 2:26 PM, Thomas Gleixner wrote: > All event channel setups bind the interrupt on CPU0 or the target CPU for > percpu interrupts and overwrite the affinity mask with the corresponding > cpumask. That does not make sense. > > The XEN implementation of irqchip::irq_set_affinity() already picks a > single target CPU out of the affinity mask and the actual target is stored > in the effective CPU mask, so destroying the user chosen affinity mask > which might contain more than one CPU is wrong. > > Change the implementation so that the channel is bound to CPU0 at the XEN > level and leave the affinity mask alone. At startup of the interrupt > affinity will be assigned out of the affinity mask and the XEN binding will > be updated. If that's the case then I wonder whether we need this call at all and instead bind at startup time. -boris > Only keep the enforcement for real percpu interrupts. ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [patch 24/30] xen/events: Remove unused bind_evtchn_to_irq_lateeoi()
On 12/10/20 2:26 PM, Thomas Gleixner wrote: > Signed-off-by: Thomas Gleixner > Cc: Boris Ostrovsky > Cc: Juergen Gross > Cc: Stefano Stabellini > Cc: xen-de...@lists.xenproject.org > --- > drivers/xen/events/events_base.c |6 -- > 1 file changed, 6 deletions(-) > > --- a/drivers/xen/events/events_base.c > +++ b/drivers/xen/events/events_base.c > @@ -1132,12 +1132,6 @@ int bind_evtchn_to_irq(evtchn_port_t evt > } > EXPORT_SYMBOL_GPL(bind_evtchn_to_irq); > > -int bind_evtchn_to_irq_lateeoi(evtchn_port_t evtchn) > -{ > - return bind_evtchn_to_irq_chip(evtchn, _lateeoi_chip); > -} > -EXPORT_SYMBOL_GPL(bind_evtchn_to_irq_lateeoi); include/xen/events.h also needs to be updated (and in the next patch for xen_set_affinity_evtchn() as well). -boris ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [patch 19/30] PCI: mobiveil: Use irq_data_get_irq_chip_data()
On Thu, Dec 10, 2020 at 1:42 PM Thomas Gleixner wrote: > > Going through a full irq descriptor lookup instead of just using the proper > helper function which provides direct access is suboptimal. > > In fact it _is_ wrong because the chip callback needs to get the chip data > which is relevant for the chip while using the irq descriptor variant > returns the irq chip data of the top level chip of a hierarchy. It does not > matter in this case because the chip is the top level chip, but that > doesn't make it more correct. > > Signed-off-by: Thomas Gleixner > Cc: Karthikeyan Mitran > Cc: Hou Zhiqiang > Cc: Lorenzo Pieralisi > Cc: Rob Herring > Cc: Bjorn Helgaas > Cc: linux-...@vger.kernel.org > --- > drivers/pci/controller/mobiveil/pcie-mobiveil-host.c |8 ++-- > 1 file changed, 2 insertions(+), 6 deletions(-) Reviewed-by: Rob Herring ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [patch 18/30] PCI: xilinx-nwl: Use irq_data_get_irq_chip_data()
On Thu, Dec 10, 2020 at 1:42 PM Thomas Gleixner wrote: > > Going through a full irq descriptor lookup instead of just using the proper > helper function which provides direct access is suboptimal. > > In fact it _is_ wrong because the chip callback needs to get the chip data > which is relevant for the chip while using the irq descriptor variant > returns the irq chip data of the top level chip of a hierarchy. It does not > matter in this case because the chip is the top level chip, but that > doesn't make it more correct. > > Signed-off-by: Thomas Gleixner > Cc: Lorenzo Pieralisi > Cc: Rob Herring > Cc: Bjorn Helgaas > Cc: Michal Simek > Cc: linux-...@vger.kernel.org > Cc: linux-arm-ker...@lists.infradead.org > --- > drivers/pci/controller/pcie-xilinx-nwl.c |8 ++-- > 1 file changed, 2 insertions(+), 6 deletions(-) Reviewed-by: Rob Herring ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v2 0/3] Experimental freesync video mode optimization
Hi, (CC dri-devel, Pekka and Martin who might be interested in this as well.) On Thursday, December 10th, 2020 at 7:48 PM, Aurabindo Pillai wrote: > This patchset enables freesync video mode usecase where the userspace > can request a freesync compatible video mode such that switching to this > mode does not trigger blanking. > > This feature is guarded by a module parameter which is disabled by > default. Enabling this paramters adds additional modes to the driver > modelist, and also enables the optimization to skip modeset when using > one of these modes. Thanks for working on this, it's an interesting feature! However I'd like to take some time to think about the user-space API for this. As I understand it, some new synthetic modes are added, and user-space can perform a test-only atomic *without* ALLOW_MODESET to figure out whether it can switch to a mode without blanking the screen. However the exact modes amdgpu adds are just some guesses. I think it would be great if user-space could control the min/max refresh rate values directly. Not only this would remove the need for the kernel to hard-code "well-known video refresh rates", but this would also enable more use-cases. For instance some users might want to mitigate flickering on their screen by reducing the VRR range. Some users might want to lower their screen refresh rate for power savings. What do you think? Would you be fine with adding min/max VRR range properties? If you're scared about the user-space code requirement, I can provide that. Thanks, Simon Ser ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v3 1/2] drm: automatic legacy gamma support
On 10/12/2020 18:32, Ville Syrjälä wrote: >>> @@ -1053,18 +1052,9 @@ static int setcmap_atomic(struct fb_cmap *cmap, >>> struct fb_info *info) >>> goto out_state; >>> } >>> >>> - crtc_state = drm_atomic_get_crtc_state(state, crtc); >>> - if (IS_ERR(crtc_state)) { >>> - ret = PTR_ERR(crtc_state); >>> + ret = drm_crtc_gamma_ramp_set(state, crtc, gamma_lut); >>> + if (ret) >> >> You're nesting an atomic commit in an atomic commit here, that will go >> boom. I guess ideally we'd move this into drm_client_modeset so it >> remembers the fbdev gamma ramp and does it all in one go. > > IIRC that's pretty much what's in my branch that I mentioned earlier. > Mentioning it again in case someone wants a leg up for implementing > this idea ;) Yep, I think your branch looks good, and I almost started working on it, but I don't think I have the time for it. I have to finish this by early next week, after which I don't know when I could continue with it (if ever, job change...). Tomi -- Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [Intel-gfx] [patch 13/30] drm/i915/lpe_audio: Remove pointless irq_to_desc() usage
On Thu, Dec 10, 2020 at 08:25:49PM +0100, Thomas Gleixner wrote: > Nothing uses the result and nothing should ever use it in driver code. > > Signed-off-by: Thomas Gleixner > Cc: Jani Nikula > Cc: Joonas Lahtinen > Cc: Rodrigo Vivi > Cc: David Airlie > Cc: Daniel Vetter > Cc: Pankaj Bharadiya > Cc: Chris Wilson > Cc: Wambui Karuga > Cc: intel-...@lists.freedesktop.org > Cc: dri-devel@lists.freedesktop.org Reviewed-by: Ville Syrjälä > --- > drivers/gpu/drm/i915/display/intel_lpe_audio.c |4 > 1 file changed, 4 deletions(-) > > --- a/drivers/gpu/drm/i915/display/intel_lpe_audio.c > +++ b/drivers/gpu/drm/i915/display/intel_lpe_audio.c > @@ -297,13 +297,9 @@ int intel_lpe_audio_init(struct drm_i915 > */ > void intel_lpe_audio_teardown(struct drm_i915_private *dev_priv) > { > - struct irq_desc *desc; > - > if (!HAS_LPE_AUDIO(dev_priv)) > return; > > - desc = irq_to_desc(dev_priv->lpe_audio.irq); > - > lpe_audio_platdev_destroy(dev_priv); > > irq_free_desc(dev_priv->lpe_audio.irq); > > ___ > Intel-gfx mailing list > intel-...@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Ville Syrjälä Intel ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v3 1/2] drm: automatic legacy gamma support
On 10/12/2020 17:27, Daniel Vetter wrote: >> diff --git a/drivers/gpu/drm/drm_fb_helper.c >> b/drivers/gpu/drm/drm_fb_helper.c >> index e82db0f4e771..80e3797f0f01 100644 >> --- a/drivers/gpu/drm/drm_fb_helper.c >> +++ b/drivers/gpu/drm/drm_fb_helper.c >> @@ -46,6 +46,7 @@ >> #include >> #include >> >> +#include "drm_crtc_internal.h" > > So this is a bit annoying, because thus far we managed to have a very > clear split between core and helpers. And I think we can keep that. > >> #include "drm_crtc_helper_internal.h" >> #include "drm_internal.h" >> >> @@ -136,15 +137,15 @@ static void drm_fb_helper_restore_lut_atomic(struct >> drm_crtc *crtc) >> { >> uint16_t *r_base, *g_base, *b_base; >> >> -if (crtc->funcs->gamma_set == NULL) >> +if (!drm_crtc_supports_legacy_gamma(crtc)) >> return; >> >> r_base = crtc->gamma_store; >> g_base = r_base + crtc->gamma_size; >> b_base = g_base + crtc->gamma_size; >> >> -crtc->funcs->gamma_set(crtc, r_base, g_base, b_base, >> - crtc->gamma_size, NULL); >> +drm_crtc_legacy_gamma_set(crtc, r_base, g_base, b_base, >> + crtc->gamma_size, NULL); > > This is only used by legacy non-atomic drivers. It's pretty much > impossible to make kgdb work with atomic drivers, so really let's just not > bother and keep the code as-is. You're right. >> } >> >> /** >> @@ -946,7 +947,7 @@ static int setcmap_legacy(struct fb_cmap *cmap, struct >> fb_info *info) >> drm_modeset_lock_all(fb_helper->dev); >> drm_client_for_each_modeset(modeset, _helper->client) { >> crtc = modeset->crtc; >> -if (!crtc->funcs->gamma_set || !crtc->gamma_size) { >> +if (!drm_crtc_supports_legacy_gamma(crtc)) { >> ret = -EINVAL; >> goto out; >> } >> @@ -964,8 +965,8 @@ static int setcmap_legacy(struct fb_cmap *cmap, struct >> fb_info *info) >> memcpy(g + cmap->start, cmap->green, cmap->len * sizeof(*g)); >> memcpy(b + cmap->start, cmap->blue, cmap->len * sizeof(*b)); >> >> -ret = crtc->funcs->gamma_set(crtc, r, g, b, >> - crtc->gamma_size, NULL); >> +ret = drm_crtc_legacy_gamma_set(crtc, r, g, b, crtc->gamma_size, >> +NULL); >> if (ret) >> goto out; > > Same here. Yep. >> } >> @@ -1024,12 +1025,10 @@ static int setcmap_atomic(struct fb_cmap *cmap, >> struct fb_info *info) >> struct drm_device *dev = fb_helper->dev; >> struct drm_property_blob *gamma_lut = NULL; >> struct drm_modeset_acquire_ctx ctx; >> -struct drm_crtc_state *crtc_state; >> struct drm_atomic_state *state; >> struct drm_mode_set *modeset; >> struct drm_crtc *crtc; >> u16 *r, *g, *b; >> -bool replaced; >> int ret = 0; >> >> drm_modeset_acquire_init(, 0); >> @@ -1053,18 +1052,9 @@ static int setcmap_atomic(struct fb_cmap *cmap, >> struct fb_info *info) >> goto out_state; >> } >> >> -crtc_state = drm_atomic_get_crtc_state(state, crtc); >> -if (IS_ERR(crtc_state)) { >> -ret = PTR_ERR(crtc_state); >> +ret = drm_crtc_gamma_ramp_set(state, crtc, gamma_lut); >> +if (ret) > > You're nesting an atomic commit in an atomic commit here, that will go > boom. I guess ideally we'd move this into drm_client_modeset so it > remembers the fbdev gamma ramp and does it all in one go. Otherwise I > guess you need some kind of different helper, not sure what. What do you mean? Are you mixing drm_crtc_legacy_gamma_set with drm_crtc_gamma_ramp_set (yeah, I didn't quite know how to name the latter one...)? drm_crtc_gamma_ramp_set does the same thing as the removed code, it sets the gamma_lut in to the state. It doesn't commit. drm_crtc_gamma_ramp_set does a "setup the state so that this gamma ramp will be on screen", which means setting/clearing GAMMA_LUT, DEGAMMA_LUT and CTM. I wanted to have that logic in one place, which means we need to export it from drm.ko. I could just inline drm_crtc_gamma_ramp_set, but then I need drm_mode_obj_find_prop_id, which is again not exported. I could also inline drm_mode_obj_find_prop_id as it's trivial enough loop. But this sounds uglier than exporting a function. Personally, I don't remember when I have used fbdev the last time (other than simple tests), and I could as well just leave the code here as it is. I have no idea if this fbdev setcmap is a big feature that has to function also with HW that only has a pre-gamma table. Tomi -- Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki ___ dri-devel mailing list dri-devel@lists.freedesktop.org
[PATCH v15 1/4] RDMA/umem: Support importing dma-buf as user memory region
Dma-buf is a standard cross-driver buffer sharing mechanism that can be used to support peer-to-peer access from RDMA devices. Device memory exported via dma-buf is associated with a file descriptor. This is passed to the user space as a property associated with the buffer allocation. When the buffer is registered as a memory region, the file descriptor is passed to the RDMA driver along with other parameters. Implement the common code for importing dma-buf object and mapping dma-buf pages. Signed-off-by: Jianxin Xiong Reviewed-by: Sean Hefty Acked-by: Michael J. Ruhl Acked-by: Christian Koenig Acked-by: Daniel Vetter --- drivers/infiniband/core/Makefile | 2 +- drivers/infiniband/core/umem.c| 3 + drivers/infiniband/core/umem_dmabuf.c | 174 ++ include/rdma/ib_umem.h| 48 +- 4 files changed, 223 insertions(+), 4 deletions(-) create mode 100644 drivers/infiniband/core/umem_dmabuf.c diff --git a/drivers/infiniband/core/Makefile b/drivers/infiniband/core/Makefile index ccf2670..8ab4eea 100644 --- a/drivers/infiniband/core/Makefile +++ b/drivers/infiniband/core/Makefile @@ -40,5 +40,5 @@ ib_uverbs-y :=uverbs_main.o uverbs_cmd.o uverbs_marshall.o \ uverbs_std_types_srq.o \ uverbs_std_types_wq.o \ uverbs_std_types_qp.o -ib_uverbs-$(CONFIG_INFINIBAND_USER_MEM) += umem.o +ib_uverbs-$(CONFIG_INFINIBAND_USER_MEM) += umem.o umem_dmabuf.o ib_uverbs-$(CONFIG_INFINIBAND_ON_DEMAND_PAGING) += umem_odp.o diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c index 7ca4112..cc131f8 100644 --- a/drivers/infiniband/core/umem.c +++ b/drivers/infiniband/core/umem.c @@ -2,6 +2,7 @@ * Copyright (c) 2005 Topspin Communications. All rights reserved. * Copyright (c) 2005 Cisco Systems. All rights reserved. * Copyright (c) 2005 Mellanox Technologies. All rights reserved. + * Copyright (c) 2020 Intel Corporation. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU @@ -278,6 +279,8 @@ void ib_umem_release(struct ib_umem *umem) { if (!umem) return; + if (umem->is_dmabuf) + return ib_umem_dmabuf_release(to_ib_umem_dmabuf(umem)); if (umem->is_odp) return ib_umem_odp_release(to_ib_umem_odp(umem)); diff --git a/drivers/infiniband/core/umem_dmabuf.c b/drivers/infiniband/core/umem_dmabuf.c new file mode 100644 index 000..f9b5162 --- /dev/null +++ b/drivers/infiniband/core/umem_dmabuf.c @@ -0,0 +1,174 @@ +// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) +/* + * Copyright (c) 2020 Intel Corporation. All rights reserved. + */ + +#include +#include +#include + +#include "uverbs.h" + +int ib_umem_dmabuf_map_pages(struct ib_umem_dmabuf *umem_dmabuf) +{ + struct sg_table *sgt; + struct scatterlist *sg; + struct dma_fence *fence; + unsigned long start, end, cur = 0; + unsigned int nmap = 0; + int i; + + dma_resv_assert_held(umem_dmabuf->attach->dmabuf->resv); + + if (umem_dmabuf->sgt) + goto wait_fence; + + sgt = dma_buf_map_attachment(umem_dmabuf->attach, DMA_BIDIRECTIONAL); + if (IS_ERR(sgt)) + return PTR_ERR(sgt); + + /* modify the sg list in-place to match umem address and length */ + + start = ALIGN_DOWN(umem_dmabuf->umem.address, PAGE_SIZE); + end = ALIGN(umem_dmabuf->umem.address + umem_dmabuf->umem.length, + PAGE_SIZE); + for_each_sgtable_dma_sg(sgt, sg, i) { + if (start < cur + sg_dma_len(sg) && cur < end) + nmap++; + if (cur <= start && start < cur + sg_dma_len(sg)) { + unsigned long offset = start - cur; + + umem_dmabuf->first_sg = sg; + umem_dmabuf->first_sg_offset = offset; + sg_dma_address(sg) += offset; + sg_dma_len(sg) -= offset; + cur += offset; + } + if (cur < end && end <= cur + sg_dma_len(sg)) { + unsigned long trim = cur + sg_dma_len(sg) - end; + + umem_dmabuf->last_sg = sg; + umem_dmabuf->last_sg_trim = trim; + sg_dma_len(sg) -= trim; + break; + } + cur += sg_dma_len(sg); + } + + umem_dmabuf->umem.sg_head.sgl = umem_dmabuf->first_sg; + umem_dmabuf->umem.sg_head.nents = nmap; + umem_dmabuf->umem.nmap = nmap; + umem_dmabuf->sgt = sgt; + +wait_fence: + /* +* Although the sg list is valid now, the content of the pages +* may be not up-to-date. Wait for the exporter to finish +*
[PATCH v15 2/4] RDMA/core: Add device method for registering dma-buf based memory region
Dma-buf based memory region requires one extra parameter and is processed quite differently. Adding a separate method allows clean separation from regular memory regions. Signed-off-by: Jianxin Xiong Reviewed-by: Sean Hefty Acked-by: Michael J. Ruhl Acked-by: Christian Koenig Acked-by: Daniel Vetter Reviewed-by: Leon Romanovsky --- drivers/infiniband/core/device.c | 1 + include/rdma/ib_verbs.h | 6 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c index 3ab1ede..23f7440 100644 --- a/drivers/infiniband/core/device.c +++ b/drivers/infiniband/core/device.c @@ -2677,6 +2677,7 @@ void ib_set_device_ops(struct ib_device *dev, const struct ib_device_ops *ops) SET_DEVICE_OP(dev_ops, read_counters); SET_DEVICE_OP(dev_ops, reg_dm_mr); SET_DEVICE_OP(dev_ops, reg_user_mr); + SET_DEVICE_OP(dev_ops, reg_user_mr_dmabuf); SET_DEVICE_OP(dev_ops, req_ncomp_notif); SET_DEVICE_OP(dev_ops, req_notify_cq); SET_DEVICE_OP(dev_ops, rereg_user_mr); diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h index 06a5652..b2f02a7 100644 --- a/include/rdma/ib_verbs.h +++ b/include/rdma/ib_verbs.h @@ -2,7 +2,7 @@ /* * Copyright (c) 2004 Mellanox Technologies Ltd. All rights reserved. * Copyright (c) 2004 Infinicon Corporation. All rights reserved. - * Copyright (c) 2004 Intel Corporation. All rights reserved. + * Copyright (c) 2004, 2020 Intel Corporation. All rights reserved. * Copyright (c) 2004 Topspin Corporation. All rights reserved. * Copyright (c) 2004 Voltaire Corporation. All rights reserved. * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. @@ -2433,6 +2433,10 @@ struct ib_device_ops { struct ib_mr *(*reg_user_mr)(struct ib_pd *pd, u64 start, u64 length, u64 virt_addr, int mr_access_flags, struct ib_udata *udata); + struct ib_mr *(*reg_user_mr_dmabuf)(struct ib_pd *pd, u64 offset, + u64 length, u64 virt_addr, int fd, + int mr_access_flags, + struct ib_udata *udata); struct ib_mr *(*rereg_user_mr)(struct ib_mr *mr, int flags, u64 start, u64 length, u64 virt_addr, int mr_access_flags, struct ib_pd *pd, -- 1.8.3.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v15 3/4] RDMA/uverbs: Add uverbs command for dma-buf based MR registration
Implement a new uverbs ioctl method for memory registration with file descriptor as an extra parameter. Signed-off-by: Jianxin Xiong Reviewed-by: Sean Hefty Acked-by: Michael J. Ruhl Acked-by: Christian Koenig Acked-by: Daniel Vetter Reviewed-by: Leon Romanovsky --- drivers/infiniband/core/uverbs_std_types_mr.c | 117 +- include/uapi/rdma/ib_user_ioctl_cmds.h| 14 +++ 2 files changed, 129 insertions(+), 2 deletions(-) diff --git a/drivers/infiniband/core/uverbs_std_types_mr.c b/drivers/infiniband/core/uverbs_std_types_mr.c index dd4e76b..f782d5e 100644 --- a/drivers/infiniband/core/uverbs_std_types_mr.c +++ b/drivers/infiniband/core/uverbs_std_types_mr.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2018, Mellanox Technologies inc. All rights reserved. + * Copyright (c) 2020, Intel Corporation. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU @@ -182,6 +183,86 @@ static int UVERBS_HANDLER(UVERBS_METHOD_QUERY_MR)( return IS_UVERBS_COPY_ERR(ret) ? ret : 0; } +static int UVERBS_HANDLER(UVERBS_METHOD_REG_DMABUF_MR)( + struct uverbs_attr_bundle *attrs) +{ + struct ib_uobject *uobj = + uverbs_attr_get_uobject(attrs, UVERBS_ATTR_REG_DMABUF_MR_HANDLE); + struct ib_pd *pd = + uverbs_attr_get_obj(attrs, UVERBS_ATTR_REG_DMABUF_MR_PD_HANDLE); + struct ib_device *ib_dev = pd->device; + + u64 offset, length, iova; + u32 fd, access_flags; + struct ib_mr *mr; + int ret; + + if (!ib_dev->ops.reg_user_mr_dmabuf) + return -EOPNOTSUPP; + + ret = uverbs_copy_from(, attrs, + UVERBS_ATTR_REG_DMABUF_MR_OFFSET); + if (ret) + return ret; + + ret = uverbs_copy_from(, attrs, + UVERBS_ATTR_REG_DMABUF_MR_LENGTH); + if (ret) + return ret; + + ret = uverbs_copy_from(, attrs, + UVERBS_ATTR_REG_DMABUF_MR_IOVA); + if (ret) + return ret; + + if ((offset & ~PAGE_MASK) != (iova & ~PAGE_MASK)) + return -EINVAL; + + ret = uverbs_copy_from(, attrs, + UVERBS_ATTR_REG_DMABUF_MR_FD); + if (ret) + return ret; + + ret = uverbs_get_flags32(_flags, attrs, +UVERBS_ATTR_REG_DMABUF_MR_ACCESS_FLAGS, +IB_ACCESS_LOCAL_WRITE | +IB_ACCESS_REMOTE_READ | +IB_ACCESS_REMOTE_WRITE | +IB_ACCESS_REMOTE_ATOMIC | +IB_ACCESS_RELAXED_ORDERING); + if (ret) + return ret; + + ret = ib_check_mr_access(ib_dev, access_flags); + if (ret) + return ret; + + mr = pd->device->ops.reg_user_mr_dmabuf(pd, offset, length, iova, fd, + access_flags, + >driver_udata); + if (IS_ERR(mr)) + return PTR_ERR(mr); + + mr->device = pd->device; + mr->pd = pd; + mr->type = IB_MR_TYPE_USER; + mr->uobject = uobj; + atomic_inc(>usecnt); + + uobj->object = mr; + + uverbs_finalize_uobj_create(attrs, UVERBS_ATTR_REG_DMABUF_MR_HANDLE); + + ret = uverbs_copy_to(attrs, UVERBS_ATTR_REG_DMABUF_MR_RESP_LKEY, +>lkey, sizeof(mr->lkey)); + if (ret) + return ret; + + ret = uverbs_copy_to(attrs, UVERBS_ATTR_REG_DMABUF_MR_RESP_RKEY, +>rkey, sizeof(mr->rkey)); + return ret; +} + DECLARE_UVERBS_NAMED_METHOD( UVERBS_METHOD_ADVISE_MR, UVERBS_ATTR_IDR(UVERBS_ATTR_ADVISE_MR_PD_HANDLE, @@ -247,6 +328,37 @@ static int UVERBS_HANDLER(UVERBS_METHOD_QUERY_MR)( UVERBS_ATTR_TYPE(u32), UA_MANDATORY)); +DECLARE_UVERBS_NAMED_METHOD( + UVERBS_METHOD_REG_DMABUF_MR, + UVERBS_ATTR_IDR(UVERBS_ATTR_REG_DMABUF_MR_HANDLE, + UVERBS_OBJECT_MR, + UVERBS_ACCESS_NEW, + UA_MANDATORY), + UVERBS_ATTR_IDR(UVERBS_ATTR_REG_DMABUF_MR_PD_HANDLE, + UVERBS_OBJECT_PD, + UVERBS_ACCESS_READ, + UA_MANDATORY), + UVERBS_ATTR_PTR_IN(UVERBS_ATTR_REG_DMABUF_MR_OFFSET, + UVERBS_ATTR_TYPE(u64), + UA_MANDATORY), + UVERBS_ATTR_PTR_IN(UVERBS_ATTR_REG_DMABUF_MR_LENGTH, + UVERBS_ATTR_TYPE(u64), + UA_MANDATORY), + UVERBS_ATTR_PTR_IN(UVERBS_ATTR_REG_DMABUF_MR_IOVA, + UVERBS_ATTR_TYPE(u64), + UA_MANDATORY), +
[PATCH v15 4/4] RDMA/mlx5: Support dma-buf based userspace memory region
Implement the new driver method 'reg_user_mr_dmabuf'. Utilize the core functions to import dma-buf based memory region and update the mappings. Add code to handle dma-buf related page fault. Signed-off-by: Jianxin Xiong Reviewed-by: Sean Hefty Acked-by: Michael J. Ruhl Acked-by: Christian Koenig Acked-by: Daniel Vetter --- drivers/infiniband/hw/mlx5/main.c| 2 + drivers/infiniband/hw/mlx5/mlx5_ib.h | 18 ++ drivers/infiniband/hw/mlx5/mr.c | 112 ++- drivers/infiniband/hw/mlx5/odp.c | 89 ++-- 4 files changed, 214 insertions(+), 7 deletions(-) diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c index 4a054eb..c025746 100644 --- a/drivers/infiniband/hw/mlx5/main.c +++ b/drivers/infiniband/hw/mlx5/main.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB /* * Copyright (c) 2013-2020, Mellanox Technologies inc. All rights reserved. + * Copyright (c) 2020, Intel Corporation. All rights reserved. */ #include @@ -4069,6 +4070,7 @@ static int mlx5_ib_enable_driver(struct ib_device *dev) .query_srq = mlx5_ib_query_srq, .query_ucontext = mlx5_ib_query_ucontext, .reg_user_mr = mlx5_ib_reg_user_mr, + .reg_user_mr_dmabuf = mlx5_ib_reg_user_mr_dmabuf, .req_notify_cq = mlx5_ib_arm_cq, .rereg_user_mr = mlx5_ib_rereg_user_mr, .resize_cq = mlx5_ib_resize_cq, diff --git a/drivers/infiniband/hw/mlx5/mlx5_ib.h b/drivers/infiniband/hw/mlx5/mlx5_ib.h index c33d6fd..bddf252 100644 --- a/drivers/infiniband/hw/mlx5/mlx5_ib.h +++ b/drivers/infiniband/hw/mlx5/mlx5_ib.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */ /* * Copyright (c) 2013-2020, Mellanox Technologies inc. All rights reserved. + * Copyright (c) 2020, Intel Corporation. All rights reserved. */ #ifndef MLX5_IB_H @@ -703,6 +704,12 @@ static inline bool is_odp_mr(struct mlx5_ib_mr *mr) mr->umem->is_odp; } +static inline bool is_dmabuf_mr(struct mlx5_ib_mr *mr) +{ + return IS_ENABLED(CONFIG_INFINIBAND_ON_DEMAND_PAGING) && mr->umem && + mr->umem->is_dmabuf; +} + struct mlx5_ib_mw { struct ib_mwibmw; struct mlx5_core_mkey mmkey; @@ -1243,6 +1250,10 @@ int mlx5_ib_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr, struct ib_mr *mlx5_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, u64 virt_addr, int access_flags, struct ib_udata *udata); +struct ib_mr *mlx5_ib_reg_user_mr_dmabuf(struct ib_pd *pd, u64 start, +u64 length, u64 virt_addr, +int fd, int access_flags, +struct ib_udata *udata); int mlx5_ib_advise_mr(struct ib_pd *pd, enum ib_uverbs_advise_mr_advice advice, u32 flags, @@ -1253,11 +1264,13 @@ int mlx5_ib_advise_mr(struct ib_pd *pd, int mlx5_ib_dealloc_mw(struct ib_mw *mw); int mlx5_ib_update_xlt(struct mlx5_ib_mr *mr, u64 idx, int npages, int page_shift, int flags); +int mlx5_ib_update_mr_pas(struct mlx5_ib_mr *mr, unsigned int flags); struct mlx5_ib_mr *mlx5_ib_alloc_implicit_mr(struct mlx5_ib_pd *pd, struct ib_udata *udata, int access_flags); void mlx5_ib_free_implicit_mr(struct mlx5_ib_mr *mr); void mlx5_ib_fence_odp_mr(struct mlx5_ib_mr *mr); +void mlx5_ib_fence_dmabuf_mr(struct mlx5_ib_mr *mr); struct ib_mr *mlx5_ib_rereg_user_mr(struct ib_mr *ib_mr, int flags, u64 start, u64 length, u64 virt_addr, int access_flags, struct ib_pd *pd, struct ib_udata *udata); @@ -1345,6 +1358,7 @@ int mlx5_ib_advise_mr_prefetch(struct ib_pd *pd, enum ib_uverbs_advise_mr_advice advice, u32 flags, struct ib_sge *sg_list, u32 num_sge); int mlx5_ib_init_odp_mr(struct mlx5_ib_mr *mr); +int mlx5_ib_init_dmabuf_mr(struct mlx5_ib_mr *mr); #else /* CONFIG_INFINIBAND_ON_DEMAND_PAGING */ static inline void mlx5_ib_internal_fill_odp_caps(struct mlx5_ib_dev *dev) { @@ -1370,6 +1384,10 @@ static inline int mlx5_ib_init_odp_mr(struct mlx5_ib_mr *mr) { return -EOPNOTSUPP; } +static inline int mlx5_ib_init_dmabuf_mr(struct mlx5_ib_mr *mr) +{ + return -EOPNOTSUPP; +} #endif /* CONFIG_INFINIBAND_ON_DEMAND_PAGING */ extern const struct mmu_interval_notifier_ops mlx5_mn_ops; diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c index 6fa869c..6b9c4dc 100644 --- a/drivers/infiniband/hw/mlx5/mr.c +++ b/drivers/infiniband/hw/mlx5/mr.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2013-2015, Mellanox Technologies. All rights reserved. + * Copyright (c) 2020, Intel
[PATCH v15 0/4] RDMA: Add dma-buf support
This is the fifteenth version of the patch set. Changelog: v15: * Rebase to the latest linux-rdma 'for-next' branch (commit 0583531bb9ef) to pick up RDMA core and mlx5 updates * Let ib_umem_dmabuf_get() return 'struct ib_umem_dmabuf *' instead of 'struct ib_umem *' * Move the check of on demand paging support to mlx5_ib_reg_user_mr_dmabuf() * Check iova alignment at the entry point of the uverb command so that mlx5_umem_dmabuf_default_pgsz() can always succeed v14: https://www.spinics.net/lists/linux-rdma/msg98265.html * Check return value of dma_fence_wait() * Fix a dma-buf leak in ib_umem_dmabuf_get() * Fix return value type cast for ib_umem_dmabuf_get() * Return -EOPNOTSUPP instead of -EINVAL for unimplemented functions * Remove an unnecessary use of unlikely() * Remove left-over commit message resulted from rebase v13: https://www.spinics.net/lists/linux-rdma/msg98227.html * Rebase to the latest linux-rdma 'for-next' branch (5.10.0-rc6+) * Check for device on-demand paging capability at the entry point of the new verbs command to avoid calling device's reg_user_mr_dmabuf() method when CONFIG_INFINIBAND_ON_DEMAND_PAGING is diabled. v12: https://www.spinics.net/lists/linux-rdma/msg97943.html * Move the prototype of function ib_umem_dmabuf_release() to ib_umem.h and remove umem_dmabuf.h * Break a line that is too long v11: https://www.spinics.net/lists/linux-rdma/msg97860.html * Rework the parameter checking code inside ib_umem_dmabuf_get() * Fix incorrect error handling in the new verbs command handler * Put a duplicated code sequence for checking iova and setting page size into a function * In the invalidation callback, check for if the buffer has been mapped and thus the presence of a valid driver mr is ensured * The patch that checks for dma_virt_ops is dropped because it is no longer needed * The patch that documents that dma-buf size is fixed has landed at: https://cgit.freedesktop.org/drm/drm-misc/commit/?id=476b485be03c and thus is no longer included here * The matching user space patch set is sent separately v10: https://www.spinics.net/lists/linux-rdma/msg97483.html * Don't map the pages in ib_umem_dmabuf_get(); use the size information of the dma-buf object to validate the umem size instead * Use PAGE_SIZE directly instead of use ib_umem_find_best_pgsz() when the MR is created since the pages have not been mapped yet and dma-buf requires PAGE_SIZE anyway * Always call mlx5_umem_find_best_pgsz() after mapping the pages to verify that the page size requirement is satisfied * Add a patch to document that dma-buf size is fixed v9: https://www.spinics.net/lists/linux-rdma/msg97432.html * Clean up the code for sg list in-place modification * Prevent dma-buf pages from being mapped multiple times * Map the pages in ib_umem_dmabuf_get() so that inproper values of address/length/iova can be caught early * Check for unsupported flags in the new uverbs command * Add missing uverbs_finalize_uobj_create() * Sort uverbs objects by name * Fix formating issue -- unnecessary alignment of '=' * Unmap pages in mlx5_ib_fence_dmabuf_mr() * Remove address range checking from pagefault_dmabuf_mr() v8: https://www.spinics.net/lists/linux-rdma/msg97370.html * Modify the dma-buf sg list in place to get a proper umem sg list and restore it before calling dma_buf_unmap_attachment() * Validate the umem sg list with ib_umem_find_best_pgsz() * Remove the logic for slicing the sg list at runtime v7: https://www.spinics.net/lists/linux-rdma/msg97297.html * Rebase on top of latest mlx5 MR patch series * Slice dma-buf sg list at runtime instead of creating a new list * Preload the buffer page mapping when the MR is created * Move the 'dma_virt_ops' check into dma_buf_dynamic_attach() v6: https://www.spinics.net/lists/linux-rdma/msg96923.html * Move the dma-buf invalidation callback from the core to the device driver * Move mapping update from work queue to pagefault handler * Add dma-buf based MRs to the xarray of mmkeys so that the pagefault handler can be reached * Update the new driver method and uverbs command signature by changing the paramter 'addr' to 'offset' * Modify the sg list returned from dma_buf_map_attachment() based on the parameters 'offset' and 'length' * Don't import dma-buf if 'dma_virt_ops' is used by the dma device * The patch that clarifies dma-buf sg lists alignment has landed at https://cgit.freedesktop.org/drm/drm-misc/commit/?id=ac80cd17a615 and thus is no longer included with this set v5: https://www.spinics.net/lists/linux-rdma/msg96786.html * Fix a few warnings reported by kernel test robot: - no previous prototype for function 'ib_umem_dmabuf_release' - no previous prototype for function 'ib_umem_dmabuf_map_pages' - comparison of distinct pointer types in 'check_add_overflow' * Add comment for the wait between getting the dma-buf sg tagle and updating the NIC page table v4:
Re: [PATCH v5 1/1] lib/vsprintf: Add support for printing V4L2 and DRM fourccs
On Fri 2020-11-13 12:54:41, Sakari Ailus wrote: > Add a printk modifier %p4cc (for pixel format) for printing V4L2 and DRM > pixel formats denoted by fourccs. The fourcc encoding is the same for both > so the same implementation can be used. > > Suggested-by: Mauro Carvalho Chehab > Signed-off-by: Sakari Ailus Andy, Rasmus, the last version looks fine to me. I am going to push it. Please, speak up if you are against it. Best Regards, Petr ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 2/2] drm: add legacy support for using degamma for gamma
The DRM core handles legacy gamma-set ioctl by setting GAMMA_LUT and clearing CTM and DEGAMMA_LUT. This works fine on HW where we have either: degamma -> ctm -> gamma -> out or ctm -> gamma -> out However, if the HW has gamma table before ctm, the atomic property should be DEGAMMA_LUT, and thus we have: degamma -> ctm -> out This is fine for userspace which sets gamma table using the properties, as the userspace can check for the existence of gamma & degamma, but the legacy gamma-set ioctl does not work. Change the DRM core to use DEGAMMA_LUT instead of GAMMA_LUT when the latter is unavailable. Signed-off-by: Tomi Valkeinen --- drivers/gpu/drm/drm_color_mgmt.c | 20 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c index c4e4d59c4432..8733d9d95b82 100644 --- a/drivers/gpu/drm/drm_color_mgmt.c +++ b/drivers/gpu/drm/drm_color_mgmt.c @@ -238,6 +238,7 @@ EXPORT_SYMBOL(drm_mode_crtc_set_gamma_size); bool drm_crtc_supports_legacy_gamma(struct drm_crtc *crtc) { uint32_t gamma_id = crtc->dev->mode_config.gamma_lut_property->base.id; + uint32_t degamma_id = crtc->dev->mode_config.degamma_lut_property->base.id; if (!crtc->gamma_size) return false; @@ -245,7 +246,8 @@ bool drm_crtc_supports_legacy_gamma(struct drm_crtc *crtc) if (crtc->funcs->gamma_set) return true; - return !!drm_mode_obj_find_prop_id(>base, gamma_id); + return !!(drm_mode_obj_find_prop_id(>base, gamma_id) || + drm_mode_obj_find_prop_id(>base, degamma_id)); } EXPORT_SYMBOL(drm_crtc_supports_legacy_gamma); @@ -256,18 +258,28 @@ EXPORT_SYMBOL(drm_crtc_supports_legacy_gamma); * @blob: property blob for the gamma ramp * * Set given gamma ramp to the crtc using GAMMA_LUT property and resetting - * DEGAMMA_LUT and CTM. + * DEGAMMA_LUT and CTM, or if GAMMA_LUT is not available, using DEGAMMA_LUT + * and resetting GAMMA_LUT and CTM. */ int drm_crtc_gamma_ramp_set(struct drm_atomic_state *state, struct drm_crtc *crtc, struct drm_property_blob *blob) { + uint32_t gamma_id = crtc->dev->mode_config.gamma_lut_property->base.id; + uint32_t degamma_id = crtc->dev->mode_config.degamma_lut_property->base.id; struct drm_crtc_state *crtc_state; struct drm_property_blob *gamma_blob; struct drm_property_blob *degamma_blob; bool replaced; - gamma_blob = blob; - degamma_blob = NULL; + if (drm_mode_obj_find_prop_id(>base, gamma_id)) { + gamma_blob = blob; + degamma_blob = NULL; + } else if (drm_mode_obj_find_prop_id(>base, degamma_id)) { + gamma_blob = NULL; + degamma_blob = blob; + } else { + return -ENODEV; + } crtc_state = drm_atomic_get_crtc_state(state, crtc); if (IS_ERR(crtc_state)) -- Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 0/2] drm: automatic legacy gamma support
Hi, Another try. I dropped the has_gamma_prop and has_degamma_prop variables and use drm_mode_obj_find_prop_id() instead. I also changed the order of the patches, and added a new helper for setting the gamma ramp to the properties. Tomi Tomi Valkeinen (2): drm: automatic legacy gamma support drm: add legacy support for using degamma for gamma .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 1 - .../gpu/drm/arm/display/komeda/komeda_crtc.c | 1 - drivers/gpu/drm/arm/malidp_crtc.c | 1 - drivers/gpu/drm/armada/armada_crtc.c | 1 - drivers/gpu/drm/ast/ast_mode.c| 1 - .../gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c| 1 - drivers/gpu/drm/drm_atomic_helper.c | 70 drivers/gpu/drm/drm_color_mgmt.c | 150 -- drivers/gpu/drm/drm_crtc_internal.h | 10 ++ drivers/gpu/drm/drm_fb_helper.c | 28 ++-- drivers/gpu/drm/i915/display/intel_display.c | 1 - drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 2 - drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 1 - drivers/gpu/drm/nouveau/dispnv50/head.c | 2 - drivers/gpu/drm/omapdrm/omap_crtc.c | 1 - drivers/gpu/drm/rcar-du/rcar_du_crtc.c| 1 - drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 1 - drivers/gpu/drm/stm/ltdc.c| 1 - drivers/gpu/drm/vc4/vc4_crtc.c| 1 - drivers/gpu/drm/vc4/vc4_txp.c | 1 - include/drm/drm_atomic_helper.h | 4 - include/drm/drm_color_mgmt.h | 1 - 22 files changed, 160 insertions(+), 121 deletions(-) -- Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v3 1/2] drm: automatic legacy gamma support
To support legacy gamma ioctls the drivers need to set drm_crtc_funcs.gamma_set either to a custom implementation or to drm_atomic_helper_legacy_gamma_set. Most of the atomic drivers do the latter. We can simplify this by making the core handle it automatically. Add three functions to drm_color_mgmt.c: drm_crtc_supports_legacy_gamma() which tells if the driver supports setting the legacy gamma. drm_crtc_gamma_ramp_set() which sets the given gamma ramp to GAMMA_LUT and resets DEGAMMA_LUT and CTM. drm_crtc_legacy_gamma_set() which sets the given gamma ramp values either using drm_crtc_funcs.gamma_set or drm_crtc_gamma_ramp_set(). These functions are used from the drm_mode_gamma_set_ioctl, and from drm_fb_helper.c when it is dealing with fbdev cmap. We can then drop drm_atomic_helper_legacy_gamma_set() and remove all its uses. Note that we need to EXPORT_SYMBOL all the new functions as they are used from drm_fb_helper, but they are declared in drm_crtc_internal.h as they are not supposed to be used by the drivers. Signed-off-by: Tomi Valkeinen --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 1 - .../gpu/drm/arm/display/komeda/komeda_crtc.c | 1 - drivers/gpu/drm/arm/malidp_crtc.c | 1 - drivers/gpu/drm/armada/armada_crtc.c | 1 - drivers/gpu/drm/ast/ast_mode.c| 1 - .../gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c| 1 - drivers/gpu/drm/drm_atomic_helper.c | 70 - drivers/gpu/drm/drm_color_mgmt.c | 138 -- drivers/gpu/drm/drm_crtc_internal.h | 10 ++ drivers/gpu/drm/drm_fb_helper.c | 28 ++-- drivers/gpu/drm/i915/display/intel_display.c | 1 - drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 2 - drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 1 - drivers/gpu/drm/nouveau/dispnv50/head.c | 2 - drivers/gpu/drm/omapdrm/omap_crtc.c | 1 - drivers/gpu/drm/rcar-du/rcar_du_crtc.c| 1 - drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 1 - drivers/gpu/drm/stm/ltdc.c| 1 - drivers/gpu/drm/vc4/vc4_crtc.c| 1 - drivers/gpu/drm/vc4/vc4_txp.c | 1 - include/drm/drm_atomic_helper.h | 4 - include/drm/drm_color_mgmt.h | 1 - 22 files changed, 148 insertions(+), 121 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 2855bb918535..848b06c51b0e 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -5396,7 +5396,6 @@ static void dm_disable_vblank(struct drm_crtc *crtc) static const struct drm_crtc_funcs amdgpu_dm_crtc_funcs = { .reset = dm_crtc_reset_state, .destroy = amdgpu_dm_crtc_destroy, - .gamma_set = drm_atomic_helper_legacy_gamma_set, .set_config = drm_atomic_helper_set_config, .page_flip = drm_atomic_helper_page_flip, .atomic_duplicate_state = dm_crtc_duplicate_state, diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c index 4b485eb512e2..59172acb9738 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c @@ -550,7 +550,6 @@ static void komeda_crtc_vblank_disable(struct drm_crtc *crtc) } static const struct drm_crtc_funcs komeda_crtc_funcs = { - .gamma_set = drm_atomic_helper_legacy_gamma_set, .destroy= drm_crtc_cleanup, .set_config = drm_atomic_helper_set_config, .page_flip = drm_atomic_helper_page_flip, diff --git a/drivers/gpu/drm/arm/malidp_crtc.c b/drivers/gpu/drm/arm/malidp_crtc.c index 108e7a31bd26..494075ddbef6 100644 --- a/drivers/gpu/drm/arm/malidp_crtc.c +++ b/drivers/gpu/drm/arm/malidp_crtc.c @@ -510,7 +510,6 @@ static void malidp_crtc_disable_vblank(struct drm_crtc *crtc) } static const struct drm_crtc_funcs malidp_crtc_funcs = { - .gamma_set = drm_atomic_helper_legacy_gamma_set, .destroy = drm_crtc_cleanup, .set_config = drm_atomic_helper_set_config, .page_flip = drm_atomic_helper_page_flip, diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c index 3ebcf5a52c8b..b7bb90ae787f 100644 --- a/drivers/gpu/drm/armada/armada_crtc.c +++ b/drivers/gpu/drm/armada/armada_crtc.c @@ -820,7 +820,6 @@ static const struct drm_crtc_funcs armada_crtc_funcs = { .cursor_set = armada_drm_crtc_cursor_set, .cursor_move= armada_drm_crtc_cursor_move, .destroy= armada_drm_crtc_destroy, - .gamma_set = drm_atomic_helper_legacy_gamma_set, .set_config = drm_atomic_helper_set_config, .page_flip = drm_atomic_helper_page_flip, .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, diff --git
Re: [PATCH v2 2/2] drm: automatic legacy gamma support
Hi Tomi, I love your patch! Perhaps something to improve: [auto build test WARNING on drm-intel/for-linux-next] [also build test WARNING on linus/master v5.10-rc7] [cannot apply to drm-tip/drm-tip anholt/for-next next-20201210] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch] url: https://github.com/0day-ci/linux/commits/Tomi-Valkeinen/drm-fix-and-cleanup-legacy-gamma-support/20201208-215917 base: git://anongit.freedesktop.org/drm-intel for-linux-next config: i386-randconfig-m021-20201209 (attached as .config) compiler: gcc-9 (Debian 9.3.0-15) 9.3.0 If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot New smatch warnings: drivers/gpu/drm/drm_color_mgmt.c:307 drm_crtc_legacy_gamma_set() error: potential null dereference 'blob'. (drm_property_create_blob returns null) Old smatch warnings: drivers/gpu/drm/drm_color_mgmt.c:214 drm_mode_crtc_set_gamma_size() warn: double check that we're allocating correct size: 2 vs 6 vim +/blob +307 drivers/gpu/drm/drm_color_mgmt.c 253 254 /** 255 * drm_crtc_legacy_gamma_set - set the legacy gamma correction table 256 * @crtc: CRTC object 257 * @red: red correction table 258 * @green: green correction table 259 * @blue: green correction table 260 * @size: size of the tables 261 * @ctx: lock acquire context 262 * 263 * Implements support for legacy gamma correction table for drivers 264 * that have set drm_crtc_funcs.gamma_set or that support color management 265 * through the DEGAMMA_LUT/GAMMA_LUT properties. See 266 * drm_crtc_enable_color_mgmt() and the containing chapter for 267 * how the atomic color management and gamma tables work. 268 * 269 * This function sets the gamma using the first one available: 270 * - drm_crtc_funcs.gamma_set() 271 * - GAMMA_LUT 272 * - DEGAMMA_LUT 273 */ 274 int drm_crtc_legacy_gamma_set(struct drm_crtc *crtc, 275u16 *red, u16 *green, u16 *blue, 276uint32_t size, 277struct drm_modeset_acquire_ctx *ctx) 278 { 279 struct drm_device *dev = crtc->dev; 280 struct drm_atomic_state *state; 281 struct drm_crtc_state *crtc_state; 282 struct drm_property_blob *blob = NULL; 283 struct drm_color_lut *blob_data; 284 int i, ret = 0; 285 bool replaced; 286 287 if (crtc->funcs->gamma_set) 288 return crtc->funcs->gamma_set(crtc, red, green, blue, size, ctx); 289 290 if (!crtc->has_gamma_prop && !crtc->has_degamma_prop) 291 return -ENODEV; 292 293 state = drm_atomic_state_alloc(crtc->dev); 294 if (!state) 295 return -ENOMEM; 296 297 blob = drm_property_create_blob(dev, 298 sizeof(struct drm_color_lut) * size, 299 NULL); 300 if (IS_ERR(blob)) { 301 ret = PTR_ERR(blob); 302 blob = NULL; 303 goto fail; 304 } 305 306 /* Prepare GAMMA_LUT with the legacy values. */ > 307 blob_data = blob->data; 308 for (i = 0; i < size; i++) { 309 blob_data[i].red = red[i]; 310 blob_data[i].green = green[i]; 311 blob_data[i].blue = blue[i]; 312 } 313 314 state->acquire_ctx = ctx; 315 crtc_state = drm_atomic_get_crtc_state(state, crtc); 316 if (IS_ERR(crtc_state)) { 317 ret = PTR_ERR(crtc_state); 318 goto fail; 319 } 320 321 /* Set GAMMA/DEGAMMA_LUT and reset DEGAMMA/GAMMA_LUT and CTM */ 322 replaced = drm_property_replace_blob(_state->degamma_lut, 323crtc->has_gamma_prop ? NULL : blob); 324 replaced |= drm_property_replace_blob(_state->ctm, NULL); 325 replaced |= drm_property_replace_blob(_state->gamma_lut, 326crtc->has_gamma_prop ? blob : NULL); 327 crtc_state->color_mgmt_changed |= replaced; 328 329 ret = drm_atomic_commit(state); 330 331 fail: 332 drm_atomic_state_put(state); 333 drm_property_blob_put(blob); 334 return ret; 335 } 336 EXPORT_SYMBOL(drm_crtc_legacy_gamma_set); 337 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbui
Re: [PATCH 2/7] Revert "ACPI / OSI: Add OEM _OSI string to enable NVidia HDMI audio"
Hi, bumping the discussion again here because we just ran into this again, as we just had a laptop OEM try to fix another issue by adding an OSI check for these strings instead of helping us fix the issue in nouveau. Note as well the issue I'm referring to is entirely independent of runtime D3, so we just got runtime D3 broken again because of these hacks. Why hasn't this patch been accepted into the kernel? These were added without any sort of discussion with nouveau developers, and nouveau is the canonical nvidia driver in the Linux kernel. These strings shouldn't be here without discussion with the relevant driver maintainers, and need to be removed. On Wed, 2019-08-14 at 23:31 +0200, Karol Herbst wrote: > This reverts commit 887532ca7ca59fcf0547a79211756791128030a3. > > We have a better solution for this: b516ea586d717 > > And same as with the last commit: "NVidia Linux driver" that's Nouveau, any > out of tree driver does _not_ matter. And with Nouveau all of this works even > though it required a proper fix first, but we have that now. > > Signed-off-by: Karol Herbst > CC: Alex Hung > CC: Rafael J. Wysocki > CC: Dave Airlie > CC: Lyude Paul > CC: Ben Skeggs > --- > drivers/acpi/osi.c | 8 > 1 file changed, 8 deletions(-) > > diff --git a/drivers/acpi/osi.c b/drivers/acpi/osi.c > index 9b20ac4d79a0..56cc95b6b724 100644 > --- a/drivers/acpi/osi.c > +++ b/drivers/acpi/osi.c > @@ -53,14 +53,6 @@ osi_setup_entries[OSI_STRING_ENTRIES_MAX] __initdata = { > * be removed if both new and old graphics cards are supported. > */ > {"Linux-Dell-Video", true}, > - /* > - * Linux-Lenovo-NV-HDMI-Audio is used by BIOS to power on NVidia's > HDMI > - * audio device which is turned off for power-saving in Windows OS. > - * This power management feature observed on some Lenovo Thinkpad > - * systems which will not be able to output audio via HDMI without > - * a BIOS workaround. > - */ > - {"Linux-Lenovo-NV-HDMI-Audio", true}, > }; > > static u32 acpi_osi_handler(acpi_string interface, u32 supported) -- Sincerely, Lyude Paul (she/her) Software Engineer at Red Hat Note: I deal with a lot of emails and have a lot of bugs on my plate. If you've asked me a question, are waiting for a review/merge on a patch, etc. and I haven't responded in a while, please feel free to send me another email to check on my status. I don't bite! ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 01/15] irqchip: Allow to compile bcmstb on other platforms
Hi Maxime, On 2020-12-10 13:46, Maxime Ripard wrote: The BCM2711 uses a number of instances of the bcmstb-l2 controller in its display engine. Let's allow the driver to be enabled through KConfig. Signed-off-by: Maxime Ripard --- drivers/irqchip/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index c6098eee0c7c..f1e58de117dc 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -131,7 +131,7 @@ config BCM7120_L2_IRQ select IRQ_DOMAIN config BRCMSTB_L2_IRQ - bool + bool "Broadcom STB L2 Interrupt Controller" select GENERIC_IRQ_CHIP select IRQ_DOMAIN I'm always sceptical of making interrupt controllers user-selectable. Who is going to know that they need to pick that one? I'd be much more in favour of directly selecting this symbol from DRM_VC4_HDMI_CEC, since there is an obvious dependency. Thanks, M. -- Jazz is not dead. It just smells funny... ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [Intel-gfx] [PATCH v3 2/4] drm/i915/pmu: Use kstat_irqs to get interrupt count
On 10/12/2020 17:44, Thomas Gleixner wrote: On Thu, Dec 10 2020 at 17:09, Tvrtko Ursulin wrote: On 10/12/2020 16:35, Thomas Gleixner wrote: I'll send out a series addressing irq_to_desc() (ab)use all over the place shortly. i915 is in there... Yep we don't need atomic, my bad. And we would care about the shared interrupt line. And without atomic the extra accounting falls way below noise. You have to be careful though. If you make the accumulated counter 64 bit wide then you need to be careful vs. 32bit machines. Yep, thanks, I am bad jumping from one thing to another. Forgot about the read side atomicity completely.. So in the light of it all, it sounds best I just quickly replace our abuse with private counting and then you don't have to deal with it in your series. I mostly have it. Still chewing on the 32bit vs. 64bit thing. And keeping it in my series allows me to remove the export of irq_to_desc() at the end without waiting for your tree to be merged. Give me a few. Ok. Regards, Tvrtko ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm/bridge: ti-sn65dsi86: Implement the pwm_chip
On Thu, Dec 10, 2020 at 10:40:36PM +0800, Shawn Guo wrote: > Hi Uwe, > > On Thu, Dec 10, 2020 at 9:05 PM Uwe Kleine-König > wrote: > > > > @@ -111,6 +118,8 @@ > > > > > > > > #define SN_LINK_TRAINING_TRIES 10 > > > > > > > > +#define SN_PWM_GPIO3 > > > > > > So this maps to the GPIO4 described in sn65dsi86 datasheet. I'm > > > wondering if it's more readable to define the following SHIFT constants > > > (your code), and use GPIO_MUX_GPIO4_SHIFT >> 2 where you need GPIO > > > offset? > > > > > > #define GPIO_MUX_GPIO1_SHIFT 0 > > > #define GPIO_MUX_GPIO2_SHIFT 2 > > > #define GPIO_MUX_GPIO3_SHIFT 4 > > > #define GPIO_MUX_GPIO4_SHIFT 6 > > > > > > If you agree, you may consider to integrate this patch beforehand: > > > > > > https://github.com/shawnguo2/linux/commit/7cde887ffb3b27a36e77a08bee3666d14968b586 > > > > My preferred way here would be to add a prefix for the other constants. > > It (IMHO) looks nicer and > > > > GPIO_INPUT_SHIFT > > > > looks like a quite generic name for a hardware specific definition. > > While this looks like a reasonable argument, I also like the naming > choice for these constants in the beginning for that distinction > between registers and bits. And changing the names the other way > around means there will be a much bigger diffstat, which I would like > to avoid. I suggest let's just focus on what really matters here - > keep the naming consistent, so that people do not get confused when > they want to add more constants in there. In my eyes the bigger diffstat is justified. As I wrote, GPIO_INPUT_SHIFT isn't used in other files, but please look how many definitions there are for RESET. The usefulness of ctags/cscope is quite reduced if generic terms are used this way. Best regards Uwe -- Pengutronix e.K. | Uwe Kleine-König| Industrial Linux Solutions | https://www.pengutronix.de/ | signature.asc Description: PGP signature ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH] drm/msm: Fix WARN_ON() splat in _free_object()
From: Rob Clark [ 192.062000] [ cut here ] [ 192.062498] WARNING: CPU: 3 PID: 2039 at drivers/gpu/drm/msm/msm_gem.c:381 put_iova_vmas+0x94/0xa0 [msm] [ 192.062870] Modules linked in: snd_hrtimer snd_seq snd_seq_device rfcomm algif_hash algif_skcipher af_alg bnep xt_CHECKSUM nft_chain_nat xt_MASQUERADE nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 nft_counter xt_tcpudp nft_compat cpufreq_powersave cpufreq_conservative q6asm_dai q6routing q6afe_dai q6adm bridge q6afe q6asm q6dsp_common q6core stp llc nf_tables libcrc32c nfnetlink snd_soc_wsa881x regmap_sdw soundwire_qcom gpio_wcd934x snd_soc_wcd934x wcd934x regmap_slimbus venus_enc venus_dec apr videobuf2_dma_sg qrtr_smd uvcvideo videobuf2_vmalloc videobuf2_memops ath10k_snoc ath10k_core hci_uart btqca btbcm mac80211 bluetooth snd_soc_sdm845 ath snd_soc_rt5663 snd_soc_qcom_common snd_soc_rl6231 soundwire_bus ecdh_generic ecc qcom_spmi_adc5 venus_core qcom_pon qcom_spmi_temp_alarm qcom_vadc_common v4l2_mem2mem videobuf2_v4l2 cfg80211 videobuf2_common hid_multitouch reset_qcom_pdc qcrypto qcom_rng rfkill qcom_q6v5_mss libarc4 libdes qrtr ns qcom_wdt socinfo slim_qcom_ngd_ctrl [ 192.065739] pdr_interface qcom_q6v5_pas slimbus qcom_pil_info qcom_q6v5 qcom_sysmon qcom_common qcom_glink_smem qmi_helpers rmtfs_mem tcp_bbr sch_fq fuse ip_tables x_tables ipv6 crc_ccitt ti_sn65dsi86 i2c_hid msm mdt_loader llcc_qcom rtc_pm8xxx ocmem drm_kms_helper crct10dif_ce phy_qcom_qusb2 i2c_qcom_geni panel_simple drm pwm_bl [ 192.066066] CPU: 3 PID: 2039 Comm: gnome-shell Tainted: GW 5.10.0-rc7-next-20201208 #1 [ 192.066068] Hardware name: LENOVO 81JL/LNVNB161216, BIOS 9UCN33WW(V2.06) 06/ 4/2019 [ 192.066072] pstate: 4045 (nZcv daif +PAN -UAO -TCO BTYPE=--) [ 192.066099] pc : put_iova_vmas+0x94/0xa0 [msm] [ 192.066262] lr : put_iova_vmas+0x1c/0xa0 [msm] [ 192.066403] sp : 800019efbbb0 [ 192.066405] x29: 800019efbbb0 x28: 800019efbd88 [ 192.066411] x27: x26: 109582efa400 [ 192.066417] x25: 0009 x24: 012b [ 192.066422] x23: 109582efa438 x22: 109582efa450 [ 192.066427] x21: 109582efa528 x20: 1095cbd4f200 [ 192.066432] x19: 1095cbd4f200 x18: [ 192.066438] x17: x16: c26c200ca750 [ 192.066727] x15: x14: [ 192.066741] x13: 1096fb8c9100 x12: 0002 [ 192.066754] x11: x10: 0002 [ 192.067046] x9 : 0001 x8 : 0a36 [ 192.067060] x7 : 4e2ad9f11000 x6 : c26c216d4000 [ 192.067212] x5 : c26c2022661c x4 : 1095c2b98000 [ 192.067367] x3 : 1095cbd4f300 x2 : [ 192.067380] x1 : 1095c2b98000 x0 : [ 192.067667] Call trace: [ 192.067734] put_iova_vmas+0x94/0xa0 [msm] [ 192.068078] msm_gem_free_object+0xb4/0x110 [msm] [ 192.068399] drm_gem_object_free+0x1c/0x30 [drm] [ 192.068717] drm_gem_object_handle_put_unlocked+0xf0/0xf8 [drm] [ 192.069032] drm_gem_object_release_handle+0x6c/0x88 [drm] [ 192.069349] drm_gem_handle_delete+0x68/0xc0 [drm] [ 192.069666] drm_gem_close_ioctl+0x30/0x48 [drm] [ 192.069984] drm_ioctl_kernel+0xc0/0x110 [drm] [ 192.070303] drm_ioctl+0x210/0x440 [drm] [ 192.070588] __arm64_sys_ioctl+0xa8/0xf0 [ 192.070599] el0_svc_common.constprop.0+0x74/0x190 [ 192.070608] do_el0_svc+0x24/0x90 [ 192.070618] el0_svc+0x14/0x20 [ 192.070903] el0_sync_handler+0xb0/0xb8 [ 192.070911] el0_sync+0x174/0x180 [ 192.070918] ---[ end trace bee6b12a899001a3 ]--- [ 192.072140] [ cut here ] Fixes: 9b73bde39cf2 ("drm/msm: Fix use-after-free in msm_gem with carveout") Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_gem.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index 68a6c7eacc0a..a21be5b910ff 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c @@ -990,6 +990,8 @@ void msm_gem_free_object(struct drm_gem_object *obj) if (msm_obj->pages) kvfree(msm_obj->pages); + put_iova_vmas(obj); + /* dma_buf_detach() grabs resv lock, so we need to unlock * prior to drm_prime_gem_destroy */ @@ -999,11 +1001,10 @@ void msm_gem_free_object(struct drm_gem_object *obj) } else { msm_gem_vunmap(obj); put_pages(obj); + put_iova_vmas(obj); msm_gem_unlock(obj); } - put_iova_vmas(obj); - drm_gem_object_release(obj); kfree(msm_obj); -- 2.28.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [RFC PATCH] drm/panel: Make backlight attachment lazy
On Thu, Dec 10, 2020 at 05:50:00PM +0100, Daniel Vetter wrote: > On Thu, Dec 10, 2020 at 5:44 PM Thierry Reding > wrote: > > > > On Thu, Dec 10, 2020 at 11:15:38AM +0100, Daniel Vetter wrote: > > > On Wed, Dec 09, 2020 at 02:28:18PM -0600, Bjorn Andersson wrote: > > > > On Tue 08 Dec 17:52 CST 2020, Daniel Vetter wrote: > > > > > > > > > On Tue, Dec 08, 2020 at 04:02:16PM -0600, Bjorn Andersson wrote: > > > > > > On Tue 08 Dec 06:47 CST 2020, Thierry Reding wrote: > > > > > > > > > > > > > On Mon, Dec 07, 2020 at 10:44:46PM -0600, Bjorn Andersson wrote: > > > > > > > > Some bridge chips, such as the TI SN65DSI86 DSI/eDP bridge, > > > > > > > > provides > > > > > > > > means of generating a PWM signal for backlight control of the > > > > > > > > attached > > > > > > > > panel. The provided PWM chip is typically controlled by the > > > > > > > > pwm-backlight driver, which if tied to the panel will provide > > > > > > > > DPMS. > > > > > > > > > > > > > > > > But with the current implementation the panel will refuse to > > > > > > > > probe > > > > > > > > because the bridge driver has yet to probe and register the PWM > > > > > > > > chip, > > > > > > > > and the bridge driver will refuse to probe because it's unable > > > > > > > > to find > > > > > > > > the panel. > > > > > > > > > > > > > > What you're describing is basically a circular dependency. Can't > > > > > > > we get > > > > > > > rid of that in some other way? Why exactly does the bridge driver > > > > > > > refuse > > > > > > > to probe if the panel can't be found? > > > > > > > > > > > > > > In other words, I see how the bridge would /use/ the panel in > > > > > > > that it > > > > > > > forward a video stream to it. But how does the panel /use/ the > > > > > > > bridge? > > > > > > > > > > > > > > > > > > > Yes, this is indeed a circular dependency between the components. > > > > > > > > > > > > The involved parts are: > > > > > > * the bridge driver that implements the PWM chip probe defers on > > > > > > drm_of_find_panel_or_bridge() failing to find the panel. > > > > > > * the pwm-backlight driver that consumes the PWM channel probe defer > > > > > > because the pwm_chip was not registered by the bridge. > > > > > > * the panel that uses the backlight for DPMS purposes probe defer > > > > > > because drm_panel_of_backlight() fails to find the pwm-backlight. > > > > > > > > > > > > I looked at means of postponing drm_of_find_panel_or_bridge() to > > > > > > drm_bridge_funcs->attach(), but at that time "deferral" would be > > > > > > fatal. > > > > > > I looked at registering the pwm_chip earlier, but that would depend > > > > > > on a > > > > > > guarantee of the pwm-backlight and panel driver to probe > > > > > > concurrently. > > > > > > And the current solution of not tying the backlight to the panel > > > > > > means > > > > > > that when userspace decides to DPMS the display the backlight stays > > > > > > on. > > > > > > > > > > > > > > > > > > The proposed solution (hack?) means that DPMS operations happening > > > > > > before the pwm-backlight has probed will be missed, so it's not > > > > > > perfect. > > > > > > It does however allow the backlight on my laptop to turn off, which > > > > > > is a > > > > > > big improvement. > > > > > > > > > > > > But I'm certainly welcome to suggestions. > > > > > > > > > > Entirely hand-waving, why doesn't the following work: > > > > > > > > > > 1. driver for the platform device which is the bridge loads > > > > > 2. that platform driver registers the pwm > > > > > 3. it registers some magic for later on (more below) > > > > > 4. panel driver has deferred loading until step 2 happened > > > > > 5. panel driver registers drm_panel > > > > > 6. the magic from step 3 picks up (after having been deferred for a > > > > > few > > > > > times probably) grabs the panel, and sets up the actual drm_bridge > > > > > driver > > > > > > > > > > Everyone happy, or not? From the description it looks like the problem > > > > > that the pwm that we need for the backlight is tied to the same > > > > > driver as > > > > > the drm_bridge, and always torn down too if the drm_bridge setup fails > > > > > somehow for a reason. And that reason is the circular dependency this > > > > > creates. > > > > > > > > > > Now for the magic in step 3, there's options: > > > > > - change DT to split out that pwm as a separate platform_device, that > > > > > way > > > > > bridge and panel can load indepedently (hopefully) > > > > > > > > > > > > > This is an i2c device, so describing it multiple times would mean we > > > > have multiple devices with the same address... > > > > > > > > > - convert bridge to a multi-function device (mfd), essentially a way > > > > > to > > > > > instantiate more devices with their drivers at runtime. Then the > > > > > actual > > > > > pwm and drm_bridge parts of your bridge driver bind against those > > > > > sub-functions, and can defer indepedently > > >
Re: [Intel-gfx] [PATCH v3 2/4] drm/i915/pmu: Use kstat_irqs to get interrupt count
On 10/12/2020 16:35, Thomas Gleixner wrote: On Thu, Dec 10 2020 at 10:45, Tvrtko Ursulin wrote: On 10/12/2020 07:53, Joonas Lahtinen wrote: I think later in the thread there was a suggestion to replace this with simple counter increment in IRQ handler. It was indeed unsafe until recent b00bccb3f0bb ("drm/i915/pmu: Handle PCI unbind") but now should be fine. If kstat_irqs does not get exported it is easy enough for i915 to keep a local counter. Reasoning was very infrequent per cpu summation is much cheaper than very frequent atomic add. Up to thousands of interrupts per second vs "once per second" PMU read kind of thing. Why do you need a atomic_add? It's ONE interrupt which can only be executed on ONE CPU at a time. Interrupt handlers are non-reentrant. The core code function will just return an accumulated counter nowadays which is only 32bit wide, which is what the interface provided forever. That needs to be fixed first. Aside of that the accounting is wrong when the interrupt line is shared because the core accounts interrupt per line not per device sharing the line. Don't know whether you care or not. I'll send out a series addressing irq_to_desc() (ab)use all over the place shortly. i915 is in there... Yep we don't need atomic, my bad. And we would care about the shared interrupt line. And without atomic the extra accounting falls way below noise. So in the light of it all, it sounds best I just quickly replace our abuse with private counting and then you don't have to deal with it in your series. Regards, Tvrtko ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [RFC PATCH] drm/panel: Make backlight attachment lazy
On Thu, Dec 10, 2020 at 5:44 PM Thierry Reding wrote: > > On Thu, Dec 10, 2020 at 11:15:38AM +0100, Daniel Vetter wrote: > > On Wed, Dec 09, 2020 at 02:28:18PM -0600, Bjorn Andersson wrote: > > > On Tue 08 Dec 17:52 CST 2020, Daniel Vetter wrote: > > > > > > > On Tue, Dec 08, 2020 at 04:02:16PM -0600, Bjorn Andersson wrote: > > > > > On Tue 08 Dec 06:47 CST 2020, Thierry Reding wrote: > > > > > > > > > > > On Mon, Dec 07, 2020 at 10:44:46PM -0600, Bjorn Andersson wrote: > > > > > > > Some bridge chips, such as the TI SN65DSI86 DSI/eDP bridge, > > > > > > > provides > > > > > > > means of generating a PWM signal for backlight control of the > > > > > > > attached > > > > > > > panel. The provided PWM chip is typically controlled by the > > > > > > > pwm-backlight driver, which if tied to the panel will provide > > > > > > > DPMS. > > > > > > > > > > > > > > But with the current implementation the panel will refuse to probe > > > > > > > because the bridge driver has yet to probe and register the PWM > > > > > > > chip, > > > > > > > and the bridge driver will refuse to probe because it's unable to > > > > > > > find > > > > > > > the panel. > > > > > > > > > > > > What you're describing is basically a circular dependency. Can't we > > > > > > get > > > > > > rid of that in some other way? Why exactly does the bridge driver > > > > > > refuse > > > > > > to probe if the panel can't be found? > > > > > > > > > > > > In other words, I see how the bridge would /use/ the panel in that > > > > > > it > > > > > > forward a video stream to it. But how does the panel /use/ the > > > > > > bridge? > > > > > > > > > > > > > > > > Yes, this is indeed a circular dependency between the components. > > > > > > > > > > The involved parts are: > > > > > * the bridge driver that implements the PWM chip probe defers on > > > > > drm_of_find_panel_or_bridge() failing to find the panel. > > > > > * the pwm-backlight driver that consumes the PWM channel probe defer > > > > > because the pwm_chip was not registered by the bridge. > > > > > * the panel that uses the backlight for DPMS purposes probe defer > > > > > because drm_panel_of_backlight() fails to find the pwm-backlight. > > > > > > > > > > I looked at means of postponing drm_of_find_panel_or_bridge() to > > > > > drm_bridge_funcs->attach(), but at that time "deferral" would be > > > > > fatal. > > > > > I looked at registering the pwm_chip earlier, but that would depend > > > > > on a > > > > > guarantee of the pwm-backlight and panel driver to probe concurrently. > > > > > And the current solution of not tying the backlight to the panel means > > > > > that when userspace decides to DPMS the display the backlight stays > > > > > on. > > > > > > > > > > > > > > > The proposed solution (hack?) means that DPMS operations happening > > > > > before the pwm-backlight has probed will be missed, so it's not > > > > > perfect. > > > > > It does however allow the backlight on my laptop to turn off, which > > > > > is a > > > > > big improvement. > > > > > > > > > > But I'm certainly welcome to suggestions. > > > > > > > > Entirely hand-waving, why doesn't the following work: > > > > > > > > 1. driver for the platform device which is the bridge loads > > > > 2. that platform driver registers the pwm > > > > 3. it registers some magic for later on (more below) > > > > 4. panel driver has deferred loading until step 2 happened > > > > 5. panel driver registers drm_panel > > > > 6. the magic from step 3 picks up (after having been deferred for a few > > > > times probably) grabs the panel, and sets up the actual drm_bridge > > > > driver > > > > > > > > Everyone happy, or not? From the description it looks like the problem > > > > that the pwm that we need for the backlight is tied to the same driver > > > > as > > > > the drm_bridge, and always torn down too if the drm_bridge setup fails > > > > somehow for a reason. And that reason is the circular dependency this > > > > creates. > > > > > > > > Now for the magic in step 3, there's options: > > > > - change DT to split out that pwm as a separate platform_device, that > > > > way > > > > bridge and panel can load indepedently (hopefully) > > > > > > > > > > This is an i2c device, so describing it multiple times would mean we > > > have multiple devices with the same address... > > > > > > > - convert bridge to a multi-function device (mfd), essentially a way to > > > > instantiate more devices with their drivers at runtime. Then the > > > > actual > > > > pwm and drm_bridge parts of your bridge driver bind against those > > > > sub-functions, and can defer indepedently > > > > > > > > > > But, this sounds reasonable and would rely on the existing probe > > > deferral logic and if there's ever any improvements in this area we > > > would directly benefit from it. > > > > > > > - we could create a callback/wait function for "pls wait for any panel > > > > to > > > > show up". Then your bridge
Re: [RFC PATCH] drm/panel: Make backlight attachment lazy
On Thu, Dec 10, 2020 at 11:15:38AM +0100, Daniel Vetter wrote: > On Wed, Dec 09, 2020 at 02:28:18PM -0600, Bjorn Andersson wrote: > > On Tue 08 Dec 17:52 CST 2020, Daniel Vetter wrote: > > > > > On Tue, Dec 08, 2020 at 04:02:16PM -0600, Bjorn Andersson wrote: > > > > On Tue 08 Dec 06:47 CST 2020, Thierry Reding wrote: > > > > > > > > > On Mon, Dec 07, 2020 at 10:44:46PM -0600, Bjorn Andersson wrote: > > > > > > Some bridge chips, such as the TI SN65DSI86 DSI/eDP bridge, provides > > > > > > means of generating a PWM signal for backlight control of the > > > > > > attached > > > > > > panel. The provided PWM chip is typically controlled by the > > > > > > pwm-backlight driver, which if tied to the panel will provide DPMS. > > > > > > > > > > > > But with the current implementation the panel will refuse to probe > > > > > > because the bridge driver has yet to probe and register the PWM > > > > > > chip, > > > > > > and the bridge driver will refuse to probe because it's unable to > > > > > > find > > > > > > the panel. > > > > > > > > > > What you're describing is basically a circular dependency. Can't we > > > > > get > > > > > rid of that in some other way? Why exactly does the bridge driver > > > > > refuse > > > > > to probe if the panel can't be found? > > > > > > > > > > In other words, I see how the bridge would /use/ the panel in that it > > > > > forward a video stream to it. But how does the panel /use/ the bridge? > > > > > > > > > > > > > Yes, this is indeed a circular dependency between the components. > > > > > > > > The involved parts are: > > > > * the bridge driver that implements the PWM chip probe defers on > > > > drm_of_find_panel_or_bridge() failing to find the panel. > > > > * the pwm-backlight driver that consumes the PWM channel probe defer > > > > because the pwm_chip was not registered by the bridge. > > > > * the panel that uses the backlight for DPMS purposes probe defer > > > > because drm_panel_of_backlight() fails to find the pwm-backlight. > > > > > > > > I looked at means of postponing drm_of_find_panel_or_bridge() to > > > > drm_bridge_funcs->attach(), but at that time "deferral" would be fatal. > > > > I looked at registering the pwm_chip earlier, but that would depend on a > > > > guarantee of the pwm-backlight and panel driver to probe concurrently. > > > > And the current solution of not tying the backlight to the panel means > > > > that when userspace decides to DPMS the display the backlight stays on. > > > > > > > > > > > > The proposed solution (hack?) means that DPMS operations happening > > > > before the pwm-backlight has probed will be missed, so it's not perfect. > > > > It does however allow the backlight on my laptop to turn off, which is a > > > > big improvement. > > > > > > > > But I'm certainly welcome to suggestions. > > > > > > Entirely hand-waving, why doesn't the following work: > > > > > > 1. driver for the platform device which is the bridge loads > > > 2. that platform driver registers the pwm > > > 3. it registers some magic for later on (more below) > > > 4. panel driver has deferred loading until step 2 happened > > > 5. panel driver registers drm_panel > > > 6. the magic from step 3 picks up (after having been deferred for a few > > > times probably) grabs the panel, and sets up the actual drm_bridge driver > > > > > > Everyone happy, or not? From the description it looks like the problem > > > that the pwm that we need for the backlight is tied to the same driver as > > > the drm_bridge, and always torn down too if the drm_bridge setup fails > > > somehow for a reason. And that reason is the circular dependency this > > > creates. > > > > > > Now for the magic in step 3, there's options: > > > - change DT to split out that pwm as a separate platform_device, that way > > > bridge and panel can load indepedently (hopefully) > > > > > > > This is an i2c device, so describing it multiple times would mean we > > have multiple devices with the same address... > > > > > - convert bridge to a multi-function device (mfd), essentially a way to > > > instantiate more devices with their drivers at runtime. Then the actual > > > pwm and drm_bridge parts of your bridge driver bind against those > > > sub-functions, and can defer indepedently > > > > > > > But, this sounds reasonable and would rely on the existing probe > > deferral logic and if there's ever any improvements in this area we > > would directly benefit from it. > > > > > - we could create a callback/wait function for "pls wait for any panel to > > > show up". Then your bridge driver could launch a work_struct with that > > > wait function, which will do the bridge setup once the panel has shown > > > up. The pwm will be registered right away. It's essentially hand-rolling > > > EPROBE_DEFERRED for work_struct in drm/panel. Maybe we might even have > > > that exported from the driver core, e.g. > > > > > > register_bridge_fn(struct work *)
Re: [PATCH v3 1/2] drm: automatic legacy gamma support
On Thu, Dec 10, 2020 at 4:43 PM Tomi Valkeinen wrote: > > On 10/12/2020 17:27, Daniel Vetter wrote: > > >> diff --git a/drivers/gpu/drm/drm_fb_helper.c > >> b/drivers/gpu/drm/drm_fb_helper.c > >> index e82db0f4e771..80e3797f0f01 100644 > >> --- a/drivers/gpu/drm/drm_fb_helper.c > >> +++ b/drivers/gpu/drm/drm_fb_helper.c > >> @@ -46,6 +46,7 @@ > >> #include > >> #include > >> > >> +#include "drm_crtc_internal.h" > > > > So this is a bit annoying, because thus far we managed to have a very > > clear split between core and helpers. And I think we can keep that. > > > >> #include "drm_crtc_helper_internal.h" > >> #include "drm_internal.h" > >> > >> @@ -136,15 +137,15 @@ static void drm_fb_helper_restore_lut_atomic(struct > >> drm_crtc *crtc) > >> { > >> uint16_t *r_base, *g_base, *b_base; > >> > >> -if (crtc->funcs->gamma_set == NULL) > >> +if (!drm_crtc_supports_legacy_gamma(crtc)) > >> return; > >> > >> r_base = crtc->gamma_store; > >> g_base = r_base + crtc->gamma_size; > >> b_base = g_base + crtc->gamma_size; > >> > >> -crtc->funcs->gamma_set(crtc, r_base, g_base, b_base, > >> - crtc->gamma_size, NULL); > >> +drm_crtc_legacy_gamma_set(crtc, r_base, g_base, b_base, > >> + crtc->gamma_size, NULL); > > > > This is only used by legacy non-atomic drivers. It's pretty much > > impossible to make kgdb work with atomic drivers, so really let's just not > > bother and keep the code as-is. > > You're right. > > >> } > >> > >> /** > >> @@ -946,7 +947,7 @@ static int setcmap_legacy(struct fb_cmap *cmap, struct > >> fb_info *info) > >> drm_modeset_lock_all(fb_helper->dev); > >> drm_client_for_each_modeset(modeset, _helper->client) { > >> crtc = modeset->crtc; > >> -if (!crtc->funcs->gamma_set || !crtc->gamma_size) { > >> +if (!drm_crtc_supports_legacy_gamma(crtc)) { > >> ret = -EINVAL; > >> goto out; > >> } > >> @@ -964,8 +965,8 @@ static int setcmap_legacy(struct fb_cmap *cmap, struct > >> fb_info *info) > >> memcpy(g + cmap->start, cmap->green, cmap->len * sizeof(*g)); > >> memcpy(b + cmap->start, cmap->blue, cmap->len * sizeof(*b)); > >> > >> -ret = crtc->funcs->gamma_set(crtc, r, g, b, > >> - crtc->gamma_size, NULL); > >> +ret = drm_crtc_legacy_gamma_set(crtc, r, g, b, > >> crtc->gamma_size, > >> +NULL); > >> if (ret) > >> goto out; > > > > Same here. > > Yep. > > >> } > >> @@ -1024,12 +1025,10 @@ static int setcmap_atomic(struct fb_cmap *cmap, > >> struct fb_info *info) > >> struct drm_device *dev = fb_helper->dev; > >> struct drm_property_blob *gamma_lut = NULL; > >> struct drm_modeset_acquire_ctx ctx; > >> -struct drm_crtc_state *crtc_state; > >> struct drm_atomic_state *state; > >> struct drm_mode_set *modeset; > >> struct drm_crtc *crtc; > >> u16 *r, *g, *b; > >> -bool replaced; > >> int ret = 0; > >> > >> drm_modeset_acquire_init(, 0); > >> @@ -1053,18 +1052,9 @@ static int setcmap_atomic(struct fb_cmap *cmap, > >> struct fb_info *info) > >> goto out_state; > >> } > >> > >> -crtc_state = drm_atomic_get_crtc_state(state, crtc); > >> -if (IS_ERR(crtc_state)) { > >> -ret = PTR_ERR(crtc_state); > >> +ret = drm_crtc_gamma_ramp_set(state, crtc, gamma_lut); > >> +if (ret) > > > > You're nesting an atomic commit in an atomic commit here, that will go > > boom. I guess ideally we'd move this into drm_client_modeset so it > > remembers the fbdev gamma ramp and does it all in one go. Otherwise I > > guess you need some kind of different helper, not sure what. > > What do you mean? Are you mixing drm_crtc_legacy_gamma_set with > drm_crtc_gamma_ramp_set (yeah, I > didn't quite know how to name the latter one...)? drm_crtc_gamma_ramp_set > does the same thing as the > removed code, it sets the gamma_lut in to the state. It doesn't commit. I mean my brain's not working today at all :-/ You're right. > drm_crtc_gamma_ramp_set does a "setup the state so that this gamma ramp will > be on screen", which > means setting/clearing GAMMA_LUT, DEGAMMA_LUT and CTM. I wanted to have that > logic in one place, > which means we need to export it from drm.ko. > > I could just inline drm_crtc_gamma_ramp_set, but then I need > drm_mode_obj_find_prop_id, which is > again not exported. I could also inline drm_mode_obj_find_prop_id as it's > trivial enough loop. But > this sounds uglier than exporting a function. > > Personally, I don't remember when I have used fbdev the last time (other than > simple tests), and I > could as well just leave the code here as it is. I have no idea if this
Re: [PATCH v3 1/2] drm: automatic legacy gamma support
On Thu, Dec 10, 2020 at 04:27:39PM +0100, Daniel Vetter wrote: > On Thu, Dec 10, 2020 at 04:08:51PM +0200, Tomi Valkeinen wrote: > > To support legacy gamma ioctls the drivers need to set > > drm_crtc_funcs.gamma_set either to a custom implementation or to > > drm_atomic_helper_legacy_gamma_set. Most of the atomic drivers do the > > latter. > > > > We can simplify this by making the core handle it automatically. > > > > Add three functions to drm_color_mgmt.c: > > > > drm_crtc_supports_legacy_gamma() which tells if the driver supports > > setting the legacy gamma. > > > > drm_crtc_gamma_ramp_set() which sets the given gamma ramp to GAMMA_LUT > > and resets DEGAMMA_LUT and CTM. > > > > drm_crtc_legacy_gamma_set() which sets the given gamma ramp values > > either using drm_crtc_funcs.gamma_set or drm_crtc_gamma_ramp_set(). > > > > These functions are used from the drm_mode_gamma_set_ioctl, and from > > drm_fb_helper.c when it is dealing with fbdev cmap. > > > > We can then drop drm_atomic_helper_legacy_gamma_set() and remove all its > > uses. > > > > Note that we need to EXPORT_SYMBOL all the new functions as they are > > used from drm_fb_helper, but they are declared in drm_crtc_internal.h as > > they are not supposed to be used by the drivers. > > > > Signed-off-by: Tomi Valkeinen > > --- > > .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 1 - > > .../gpu/drm/arm/display/komeda/komeda_crtc.c | 1 - > > drivers/gpu/drm/arm/malidp_crtc.c | 1 - > > drivers/gpu/drm/armada/armada_crtc.c | 1 - > > drivers/gpu/drm/ast/ast_mode.c| 1 - > > .../gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c| 1 - > > drivers/gpu/drm/drm_atomic_helper.c | 70 - > > drivers/gpu/drm/drm_color_mgmt.c | 138 -- > > drivers/gpu/drm/drm_crtc_internal.h | 10 ++ > > drivers/gpu/drm/drm_fb_helper.c | 28 ++-- > > drivers/gpu/drm/i915/display/intel_display.c | 1 - > > drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 2 - > > drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 1 - > > drivers/gpu/drm/nouveau/dispnv50/head.c | 2 - > > drivers/gpu/drm/omapdrm/omap_crtc.c | 1 - > > drivers/gpu/drm/rcar-du/rcar_du_crtc.c| 1 - > > drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 1 - > > drivers/gpu/drm/stm/ltdc.c| 1 - > > drivers/gpu/drm/vc4/vc4_crtc.c| 1 - > > drivers/gpu/drm/vc4/vc4_txp.c | 1 - > > include/drm/drm_atomic_helper.h | 4 - > > include/drm/drm_color_mgmt.h | 1 - > > 22 files changed, 148 insertions(+), 121 deletions(-) > > > > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > > b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > > index 2855bb918535..848b06c51b0e 100644 > > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > > @@ -5396,7 +5396,6 @@ static void dm_disable_vblank(struct drm_crtc *crtc) > > static const struct drm_crtc_funcs amdgpu_dm_crtc_funcs = { > > .reset = dm_crtc_reset_state, > > .destroy = amdgpu_dm_crtc_destroy, > > - .gamma_set = drm_atomic_helper_legacy_gamma_set, > > .set_config = drm_atomic_helper_set_config, > > .page_flip = drm_atomic_helper_page_flip, > > .atomic_duplicate_state = dm_crtc_duplicate_state, > > diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c > > b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c > > index 4b485eb512e2..59172acb9738 100644 > > --- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c > > +++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c > > @@ -550,7 +550,6 @@ static void komeda_crtc_vblank_disable(struct drm_crtc > > *crtc) > > } > > > > static const struct drm_crtc_funcs komeda_crtc_funcs = { > > - .gamma_set = drm_atomic_helper_legacy_gamma_set, > > .destroy= drm_crtc_cleanup, > > .set_config = drm_atomic_helper_set_config, > > .page_flip = drm_atomic_helper_page_flip, > > diff --git a/drivers/gpu/drm/arm/malidp_crtc.c > > b/drivers/gpu/drm/arm/malidp_crtc.c > > index 108e7a31bd26..494075ddbef6 100644 > > --- a/drivers/gpu/drm/arm/malidp_crtc.c > > +++ b/drivers/gpu/drm/arm/malidp_crtc.c > > @@ -510,7 +510,6 @@ static void malidp_crtc_disable_vblank(struct drm_crtc > > *crtc) > > } > > > > static const struct drm_crtc_funcs malidp_crtc_funcs = { > > - .gamma_set = drm_atomic_helper_legacy_gamma_set, > > .destroy = drm_crtc_cleanup, > > .set_config = drm_atomic_helper_set_config, > > .page_flip = drm_atomic_helper_page_flip, > > diff --git a/drivers/gpu/drm/armada/armada_crtc.c > > b/drivers/gpu/drm/armada/armada_crtc.c > > index 3ebcf5a52c8b..b7bb90ae787f 100644 > > --- a/drivers/gpu/drm/armada/armada_crtc.c > > +++ b/drivers/gpu/drm/armada/armada_crtc.c > > @@ -820,7 +820,6 @@ static
Re: [PATCH] drm: rework description of primary and cursor planes
On Thu, Dec 10, 2020 at 10:56 AM Daniel Vetter wrote: > > On Thu, Dec 10, 2020 at 4:45 PM Simon Ser wrote: > > On Wednesday, December 9th, 2020 at 8:40 PM, Daniel Vetter > > wrote: > > > > But it's not enough, can't have two CRTCs with the same primary plane. > > > > Well, > > > > I give up, it's just simpler to use Daniel's criteria. > > > > > > Yeah, also with the validation check we'll now real quick if any driver > > > gets it wrong. Then I think we can have a useful discussion about why, and > > > what to do with that case. As-is we're kinda drafting specs in the void, > > > which is always a bit tough ... > > > > > > That's kinda another reason for doing the stricter check I proposed, it's > > > easier to check and guarantee (on both the driver and compositor side > > > hopefully). > > > > Hmm, actually, I'm already hitting a driver which doesn't guarantee that. > > amdgpu with my hardware [1] has the first primary plane linked to the the > > last > > CRTC, the second primary plane linked to the second-to-last CRTC, and so on. > > > > [1]: https://drmdb.emersion.fr/devices/129e158a4d9f > > Huh so crtc are registered forward and planes backward? I guess adding > amd people. And yeah sounds like defacto you can't figure out which > primary plane goes to which crtc, and we just take whatever goes. > Maybe that stricter approach with more guarantees just doesn't work, > ship sailed already :-/ IIRC, we used to register them both the same way, but ended up reversing the order at some point because the direct mapping didn't work for some reason. This was years ago though, so the details are hazy. Maybe Harry or Leo remembers more details? Alex > -Daniel > > -Daniel > -- > Daniel Vetter > Software Engineer, Intel Corporation > http://blog.ffwll.ch ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 12/12] drm/mediatek: Move mtk_ddp_comp_init() from sub driver to DRM driver
From: CK Hu Some ddp component exist in both display path and other path, so sub driver should not directly call DRM driver's function. Moving mtk_ddp_comp_init() from sub driver to DRM driver to achieve this. Signed-off-by: CK Hu Signed-off-by: Chun-Kuang Hu --- drivers/gpu/drm/mediatek/mtk_disp_color.c | 35 --- drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 38 - drivers/gpu/drm/mediatek/mtk_disp_rdma.c| 32 - drivers/gpu/drm/mediatek/mtk_dpi.c | 29 ++-- drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 2 +- drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 38 ++--- drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 4 +-- drivers/gpu/drm/mediatek/mtk_drm_drv.c | 29 +--- drivers/gpu/drm/mediatek/mtk_drm_drv.h | 2 +- drivers/gpu/drm/mediatek/mtk_dsi.c | 32 + 10 files changed, 25 insertions(+), 216 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_color.c b/drivers/gpu/drm/mediatek/mtk_disp_color.c index d28c06d02286..63f411ab393b 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_color.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_color.c @@ -37,7 +37,6 @@ struct mtk_disp_color_data { * @data: platform colour driver data */ struct mtk_disp_color { - struct mtk_ddp_comp ddp_comp; struct drm_crtc *crtc; struct clk *clk; void __iomem*regs; @@ -81,27 +80,12 @@ void mtk_color_start(struct device *dev) static int mtk_disp_color_bind(struct device *dev, struct device *master, void *data) { - struct mtk_disp_color *priv = dev_get_drvdata(dev); - struct drm_device *drm_dev = data; - int ret; - - ret = mtk_ddp_comp_register(drm_dev, >ddp_comp); - if (ret < 0) { - dev_err(dev, "Failed to register component %pOF: %d\n", - dev->of_node, ret); - return ret; - } - return 0; } static void mtk_disp_color_unbind(struct device *dev, struct device *master, void *data) { - struct mtk_disp_color *priv = dev_get_drvdata(dev); - struct drm_device *drm_dev = data; - - mtk_ddp_comp_unregister(drm_dev, >ddp_comp); } static const struct component_ops mtk_disp_color_component_ops = { @@ -114,7 +98,6 @@ static int mtk_disp_color_probe(struct platform_device *pdev) struct device *dev = >dev; struct mtk_disp_color *priv; struct resource *res; - int comp_id; int ret; priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); @@ -139,23 +122,7 @@ static int mtk_disp_color_probe(struct platform_device *pdev) dev_dbg(dev, "get mediatek,gce-client-reg fail!\n"); #endif - comp_id = mtk_ddp_comp_get_id(dev->of_node, MTK_DISP_COLOR); - if (comp_id < 0) { - dev_err(dev, "Failed to identify by alias: %d\n", comp_id); - return comp_id; - } - - ret = mtk_ddp_comp_init(dev->of_node, >ddp_comp, comp_id); - if (ret) { - if (ret != -EPROBE_DEFER) - dev_err(dev, "Failed to initialize component: %d\n", - ret); - - return ret; - } - priv->data = of_device_get_match_data(dev); - platform_set_drvdata(pdev, priv); ret = component_add(dev, _disp_color_component_ops); @@ -167,8 +134,6 @@ static int mtk_disp_color_probe(struct platform_device *pdev) static int mtk_disp_color_remove(struct platform_device *pdev) { - component_del(>dev, _disp_color_component_ops); - return 0; } diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c index a4f806355d2c..266c5c5ca280 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c @@ -71,7 +71,6 @@ struct mtk_disp_ovl_data { * @data: platform data */ struct mtk_disp_ovl { - struct mtk_ddp_comp ddp_comp; struct drm_crtc *crtc; struct clk *clk; void __iomem*regs; @@ -342,27 +341,12 @@ void mtk_ovl_bgclr_in_off(struct device *dev) static int mtk_disp_ovl_bind(struct device *dev, struct device *master, void *data) { - struct mtk_disp_ovl *priv = dev_get_drvdata(dev); - struct drm_device *drm_dev = data; - int ret; - - ret = mtk_ddp_comp_register(drm_dev, >ddp_comp); - if (ret < 0) { - dev_err(dev, "Failed to register component %pOF: %d\n", - dev->of_node, ret); - return ret; - } - return 0; } static void mtk_disp_ovl_unbind(struct device *dev, struct device *master, void
[PATCH v2 11/12] drm/mediatek: DRM driver directly refer to sub driver's function
From: CK Hu Some ddp component exist in both display path and other path, so sub driver should not directly call DRM driver's function. Let DRM driver directly refer to sub driver's function so that sub driver need not register these function to DRM driver. Signed-off-by: CK Hu Signed-off-by: Chun-Kuang Hu --- drivers/gpu/drm/mediatek/mtk_disp_color.c | 23 +++--- drivers/gpu/drm/mediatek/mtk_disp_drv.h | 69 ++ drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 68 +++--- drivers/gpu/drm/mediatek/mtk_disp_rdma.c| 46 +--- drivers/gpu/drm/mediatek/mtk_dpi.c | 13 ++-- drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 80 - drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 2 +- drivers/gpu/drm/mediatek/mtk_drm_drv.c | 3 +- drivers/gpu/drm/mediatek/mtk_dsi.c | 13 ++-- 9 files changed, 193 insertions(+), 124 deletions(-) create mode 100644 drivers/gpu/drm/mediatek/mtk_disp_drv.h diff --git a/drivers/gpu/drm/mediatek/mtk_disp_color.c b/drivers/gpu/drm/mediatek/mtk_disp_color.c index dc2fdde1951c..d28c06d02286 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_color.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_color.c @@ -11,6 +11,7 @@ #include #include +#include "mtk_disp_drv.h" #include "mtk_drm_crtc.h" #include "mtk_drm_ddp_comp.h" @@ -44,23 +45,23 @@ struct mtk_disp_color { const struct mtk_disp_color_data*data; }; -static int mtk_color_clk_enable(struct device *dev) +int mtk_color_clk_enable(struct device *dev) { struct mtk_disp_color *color = dev_get_drvdata(dev); return clk_prepare_enable(color->clk); } -static void mtk_color_clk_disable(struct device *dev) +void mtk_color_clk_disable(struct device *dev) { struct mtk_disp_color *color = dev_get_drvdata(dev); clk_disable_unprepare(color->clk); } -static void mtk_color_config(struct device *dev, unsigned int w, -unsigned int h, unsigned int vrefresh, -unsigned int bpc, struct cmdq_pkt *cmdq_pkt) +void mtk_color_config(struct device *dev, unsigned int w, + unsigned int h, unsigned int vrefresh, + unsigned int bpc, struct cmdq_pkt *cmdq_pkt) { struct mtk_disp_color *color = dev_get_drvdata(dev); @@ -68,7 +69,7 @@ static void mtk_color_config(struct device *dev, unsigned int w, mtk_ddp_write(cmdq_pkt, h, >cmdq_reg, color->regs, DISP_COLOR_HEIGHT(color)); } -static void mtk_color_start(struct device *dev) +void mtk_color_start(struct device *dev) { struct mtk_disp_color *color = dev_get_drvdata(dev); @@ -77,13 +78,6 @@ static void mtk_color_start(struct device *dev) writel(0x1, color->regs + DISP_COLOR_START(color)); } -static const struct mtk_ddp_comp_funcs mtk_disp_color_funcs = { - .clk_enable = mtk_color_clk_enable, - .clk_disable = mtk_color_clk_disable, - .config = mtk_color_config, - .start = mtk_color_start, -}; - static int mtk_disp_color_bind(struct device *dev, struct device *master, void *data) { @@ -151,8 +145,7 @@ static int mtk_disp_color_probe(struct platform_device *pdev) return comp_id; } - ret = mtk_ddp_comp_init(dev->of_node, >ddp_comp, comp_id, - _disp_color_funcs); + ret = mtk_ddp_comp_init(dev->of_node, >ddp_comp, comp_id); if (ret) { if (ret != -EPROBE_DEFER) dev_err(dev, "Failed to initialize component: %d\n", diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h b/drivers/gpu/drm/mediatek/mtk_disp_drv.h new file mode 100644 index ..46d199b7b4a2 --- /dev/null +++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h @@ -0,0 +1,69 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2020 MediaTek Inc. + */ + +#ifndef _MTK_DISP_DRV_H_ +#define _MTK_DISP_DRV_H_ + +#include +#include "mtk_drm_plane.h" + +void mtk_color_bypass_shadow(struct device *dev); +int mtk_color_clk_enable(struct device *dev); +void mtk_color_clk_disable(struct device *dev); +void mtk_color_config(struct device *dev, unsigned int w, + unsigned int h, unsigned int vrefresh, + unsigned int bpc, struct cmdq_pkt *cmdq_pkt); +void mtk_color_start(struct device *dev); + +void mtk_dpi_start(struct device *dev); +void mtk_dpi_stop(struct device *dev); + +void mtk_dsi_ddp_start(struct device *dev); +void mtk_dsi_ddp_stop(struct device *dev); + +void mtk_ovl_bgclr_in_on(struct device *dev); +void mtk_ovl_bgclr_in_off(struct device *dev); +void mtk_ovl_bypass_shadow(struct device *dev); +int mtk_ovl_clk_enable(struct device *dev); +void mtk_ovl_clk_disable(struct device *dev); +void mtk_ovl_config(struct device *dev, unsigned int w, + unsigned int h, unsigned int vrefresh, + unsigned int bpc, struct cmdq_pkt *cmdq_pkt);
[PATCH v2 09/12] drm/mediatek: Change sub driver interface from mtk_ddp_comp to device
From: CK Hu Some ddp component exist in both display path and other path, so sub driver interface should get rid of display info. Using device instead of mtk_ddp_comp make interface general. Signed-off-by: CK Hu Signed-off-by: Chun-Kuang Hu --- drivers/gpu/drm/mediatek/mtk_disp_color.c | 13 +-- drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 57 ++--- drivers/gpu/drm/mediatek/mtk_disp_rdma.c| 39 - drivers/gpu/drm/mediatek/mtk_dpi.c | 8 +- drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 94 ++--- drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 54 ++-- drivers/gpu/drm/mediatek/mtk_dsi.c | 8 +- 7 files changed, 124 insertions(+), 149 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_color.c b/drivers/gpu/drm/mediatek/mtk_disp_color.c index 929379c9c233..dc2fdde1951c 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_color.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_color.c @@ -44,11 +44,6 @@ struct mtk_disp_color { const struct mtk_disp_color_data*data; }; -static inline struct mtk_disp_color *comp_to_color(struct mtk_ddp_comp *comp) -{ - return container_of(comp, struct mtk_disp_color, ddp_comp); -} - static int mtk_color_clk_enable(struct device *dev) { struct mtk_disp_color *color = dev_get_drvdata(dev); @@ -63,19 +58,19 @@ static void mtk_color_clk_disable(struct device *dev) clk_disable_unprepare(color->clk); } -static void mtk_color_config(struct mtk_ddp_comp *comp, unsigned int w, +static void mtk_color_config(struct device *dev, unsigned int w, unsigned int h, unsigned int vrefresh, unsigned int bpc, struct cmdq_pkt *cmdq_pkt) { - struct mtk_disp_color *color = comp_to_color(comp); + struct mtk_disp_color *color = dev_get_drvdata(dev); mtk_ddp_write(cmdq_pkt, w, >cmdq_reg, color->regs, DISP_COLOR_WIDTH(color)); mtk_ddp_write(cmdq_pkt, h, >cmdq_reg, color->regs, DISP_COLOR_HEIGHT(color)); } -static void mtk_color_start(struct mtk_ddp_comp *comp) +static void mtk_color_start(struct device *dev) { - struct mtk_disp_color *color = comp_to_color(comp); + struct mtk_disp_color *color = dev_get_drvdata(dev); writel(COLOR_BYPASS_ALL | COLOR_SEQ_SEL, color->regs + DISP_COLOR_CFG_MAIN); diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c index 0e59b360104a..172d2c9cb988 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c @@ -78,11 +78,6 @@ struct mtk_disp_ovl { const struct mtk_disp_ovl_data *data; }; -static inline struct mtk_disp_ovl *comp_to_ovl(struct mtk_ddp_comp *comp) -{ - return container_of(comp, struct mtk_disp_ovl, ddp_comp); -} - static irqreturn_t mtk_disp_ovl_irq_handler(int irq, void *dev_id) { struct mtk_disp_ovl *priv = dev_id; @@ -99,19 +94,19 @@ static irqreturn_t mtk_disp_ovl_irq_handler(int irq, void *dev_id) return IRQ_HANDLED; } -static void mtk_ovl_enable_vblank(struct mtk_ddp_comp *comp, +static void mtk_ovl_enable_vblank(struct device *dev, struct drm_crtc *crtc) { - struct mtk_disp_ovl *ovl = comp_to_ovl(comp); + struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); ovl->crtc = crtc; writel(0x0, ovl->regs + DISP_REG_OVL_INTSTA); writel_relaxed(OVL_FME_CPL_INT, ovl->regs + DISP_REG_OVL_INTEN); } -static void mtk_ovl_disable_vblank(struct mtk_ddp_comp *comp) +static void mtk_ovl_disable_vblank(struct device *dev) { - struct mtk_disp_ovl *ovl = comp_to_ovl(comp); + struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); ovl->crtc = NULL; writel_relaxed(0x0, ovl->regs + DISP_REG_OVL_INTEN); @@ -131,25 +126,25 @@ static void mtk_ovl_clk_disable(struct device *dev) clk_disable_unprepare(ovl->clk); } -static void mtk_ovl_start(struct mtk_ddp_comp *comp) +static void mtk_ovl_start(struct device *dev) { - struct mtk_disp_ovl *ovl = dev_get_drvdata(comp->dev); + struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); writel_relaxed(0x1, ovl->regs + DISP_REG_OVL_EN); } -static void mtk_ovl_stop(struct mtk_ddp_comp *comp) +static void mtk_ovl_stop(struct device *dev) { - struct mtk_disp_ovl *ovl = dev_get_drvdata(comp->dev); + struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); writel_relaxed(0x0, ovl->regs + DISP_REG_OVL_EN); } -static void mtk_ovl_config(struct mtk_ddp_comp *comp, unsigned int w, +static void mtk_ovl_config(struct device *dev, unsigned int w, unsigned int h, unsigned int vrefresh, unsigned int bpc, struct cmdq_pkt *cmdq_pkt) { - struct mtk_disp_ovl *ovl = dev_get_drvdata(comp->dev); + struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); if (w != 0 && h != 0)
[PATCH v2 10/12] drm/mediatek: Register vblank callback function
From: CK Hu Some ddp component exist in both display path and other path, so sub driver should not directly call crtc function. crtc register callback function to sub driver to prevent sub driver directly call crtc function. Signed-off-by: CK Hu Signed-off-by: Chun-Kuang Hu --- drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 16 +++-- drivers/gpu/drm/mediatek/mtk_disp_rdma.c| 17 +++--- drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 67 +++-- drivers/gpu/drm/mediatek/mtk_drm_crtc.h | 1 - drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 9 ++- 5 files changed, 60 insertions(+), 50 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c index 172d2c9cb988..3c1c1dde6fba 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c @@ -76,30 +76,33 @@ struct mtk_disp_ovl { void __iomem*regs; struct cmdq_client_reg cmdq_reg; const struct mtk_disp_ovl_data *data; + void(*vblank_cb)(void *data); + void*vblank_cb_data; }; static irqreturn_t mtk_disp_ovl_irq_handler(int irq, void *dev_id) { struct mtk_disp_ovl *priv = dev_id; - struct mtk_ddp_comp *ovl = >ddp_comp; /* Clear frame completion interrupt */ writel(0x0, priv->regs + DISP_REG_OVL_INTSTA); - if (!priv->crtc) + if (!priv->vblank_cb) return IRQ_NONE; - mtk_crtc_ddp_irq(priv->crtc, ovl); + priv->vblank_cb(priv->vblank_cb_data); return IRQ_HANDLED; } static void mtk_ovl_enable_vblank(struct device *dev, - struct drm_crtc *crtc) + void (*vblank_cb)(void *), + void *vblank_cb_data) { struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); - ovl->crtc = crtc; + ovl->vblank_cb = vblank_cb; + ovl->vblank_cb_data = vblank_cb_data; writel(0x0, ovl->regs + DISP_REG_OVL_INTSTA); writel_relaxed(OVL_FME_CPL_INT, ovl->regs + DISP_REG_OVL_INTEN); } @@ -108,7 +111,8 @@ static void mtk_ovl_disable_vblank(struct device *dev) { struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); - ovl->crtc = NULL; + ovl->vblank_cb = NULL; + ovl->vblank_cb_data = NULL; writel_relaxed(0x0, ovl->regs + DISP_REG_OVL_INTEN); } diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c index 6e6cf039e1da..f4b3a32eb456 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c @@ -62,25 +62,25 @@ struct mtk_disp_rdma_data { */ struct mtk_disp_rdma { struct mtk_ddp_comp ddp_comp; - struct drm_crtc *crtc; struct clk *clk; void __iomem*regs; struct cmdq_client_reg cmdq_reg; const struct mtk_disp_rdma_data *data; + void(*vblank_cb)(void *data); + void*vblank_cb_data; }; static irqreturn_t mtk_disp_rdma_irq_handler(int irq, void *dev_id) { struct mtk_disp_rdma *priv = dev_id; - struct mtk_ddp_comp *rdma = >ddp_comp; /* Clear frame completion interrupt */ writel(0x0, priv->regs + DISP_REG_RDMA_INT_STATUS); - if (!priv->crtc) + if (!priv->vblank_cb) return IRQ_NONE; - mtk_crtc_ddp_irq(priv->crtc, rdma); + priv->vblank_cb(priv->vblank_cb_data); return IRQ_HANDLED; } @@ -96,11 +96,13 @@ static void rdma_update_bits(struct device *dev, unsigned int reg, } static void mtk_rdma_enable_vblank(struct device *dev, - struct drm_crtc *crtc) + void (*vblank_cb)(void *), + void *vblank_cb_data) { struct mtk_disp_rdma *rdma = dev_get_drvdata(dev); - rdma->crtc = crtc; + rdma->vblank_cb = vblank_cb; + rdma->vblank_cb_data = vblank_cb_data; rdma_update_bits(dev, DISP_REG_RDMA_INT_ENABLE, RDMA_FRAME_END_INT, RDMA_FRAME_END_INT); } @@ -109,7 +111,8 @@ static void mtk_rdma_disable_vblank(struct device *dev) { struct mtk_disp_rdma *rdma = dev_get_drvdata(dev); - rdma->crtc = NULL; + rdma->vblank_cb = NULL; + rdma->vblank_cb_data = NULL; rdma_update_bits(dev, DISP_REG_RDMA_INT_ENABLE, RDMA_FRAME_END_INT, 0); } diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c index f1dd5943ba0c..01c35786be49 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c @@ -166,24 +166,6 @@ static void mtk_drm_crtc_mode_set_nofb(struct drm_crtc *crtc) state->pending_config = true; }
[PATCH v2 08/12] drm/mediatek: Move cmdq_reg info from struct mtk_ddp_comp to sub driver private data
From: CK Hu Some ddp component exist in both display path and other path, so data belonged to sub driver should be moved into sub driver private data so it could be used for multiple path. cmdq_reg info is one of sub driver data, so move it. Signed-off-by: CK Hu Signed-off-by: Chun-Kuang Hu --- drivers/gpu/drm/mediatek/mtk_disp_color.c | 10 ++- drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 34 ++- drivers/gpu/drm/mediatek/mtk_disp_rdma.c| 30 + drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 67 +++-- drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 7 +-- 5 files changed, 84 insertions(+), 64 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_color.c b/drivers/gpu/drm/mediatek/mtk_disp_color.c index 93863dbfb761..929379c9c233 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_color.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_color.c @@ -40,6 +40,7 @@ struct mtk_disp_color { struct drm_crtc *crtc; struct clk *clk; void __iomem*regs; + struct cmdq_client_reg cmdq_reg; const struct mtk_disp_color_data*data; }; @@ -68,8 +69,8 @@ static void mtk_color_config(struct mtk_ddp_comp *comp, unsigned int w, { struct mtk_disp_color *color = comp_to_color(comp); - mtk_ddp_write(cmdq_pkt, w, comp, color->regs, DISP_COLOR_WIDTH(color)); - mtk_ddp_write(cmdq_pkt, h, comp, color->regs, DISP_COLOR_HEIGHT(color)); + mtk_ddp_write(cmdq_pkt, w, >cmdq_reg, color->regs, DISP_COLOR_WIDTH(color)); + mtk_ddp_write(cmdq_pkt, h, >cmdq_reg, color->regs, DISP_COLOR_HEIGHT(color)); } static void mtk_color_start(struct mtk_ddp_comp *comp) @@ -143,6 +144,11 @@ static int mtk_disp_color_probe(struct platform_device *pdev) dev_err(dev, "failed to ioremap color\n"); return PTR_ERR(priv->regs); } +#if IS_REACHABLE(CONFIG_MTK_CMDQ) + ret = cmdq_dev_get_client_reg(dev, >cmdq_reg, 0); + if (ret) + dev_dbg(dev, "get mediatek,gce-client-reg fail!\n"); +#endif comp_id = mtk_ddp_comp_get_id(dev->of_node, MTK_DISP_COLOR); if (comp_id < 0) { diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c index 90a78db0e96b..0e59b360104a 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c @@ -74,6 +74,7 @@ struct mtk_disp_ovl { struct drm_crtc *crtc; struct clk *clk; void __iomem*regs; + struct cmdq_client_reg cmdq_reg; const struct mtk_disp_ovl_data *data; }; @@ -151,12 +152,12 @@ static void mtk_ovl_config(struct mtk_ddp_comp *comp, unsigned int w, struct mtk_disp_ovl *ovl = dev_get_drvdata(comp->dev); if (w != 0 && h != 0) - mtk_ddp_write_relaxed(cmdq_pkt, h << 16 | w, comp, ovl->regs, + mtk_ddp_write_relaxed(cmdq_pkt, h << 16 | w, >cmdq_reg, ovl->regs, DISP_REG_OVL_ROI_SIZE); - mtk_ddp_write_relaxed(cmdq_pkt, 0x0, comp, ovl->regs, DISP_REG_OVL_ROI_BGCLR); + mtk_ddp_write_relaxed(cmdq_pkt, 0x0, >cmdq_reg, ovl->regs, DISP_REG_OVL_ROI_BGCLR); - mtk_ddp_write(cmdq_pkt, 0x1, comp, ovl->regs, DISP_REG_OVL_RST); - mtk_ddp_write(cmdq_pkt, 0x0, comp, ovl->regs, DISP_REG_OVL_RST); + mtk_ddp_write(cmdq_pkt, 0x1, >cmdq_reg, ovl->regs, DISP_REG_OVL_RST); + mtk_ddp_write(cmdq_pkt, 0x0, >cmdq_reg, ovl->regs, DISP_REG_OVL_RST); } static unsigned int mtk_ovl_layer_nr(struct mtk_ddp_comp *comp) @@ -208,7 +209,7 @@ static void mtk_ovl_layer_on(struct mtk_ddp_comp *comp, unsigned int idx, unsigned int gmc_value; struct mtk_disp_ovl *ovl = comp_to_ovl(comp); - mtk_ddp_write(cmdq_pkt, 0x1, comp, ovl->regs, + mtk_ddp_write(cmdq_pkt, 0x1, >cmdq_reg, ovl->regs, DISP_REG_OVL_RDMA_CTRL(idx)); gmc_thrshd_l = GMC_THRESHOLD_LOW >> (GMC_THRESHOLD_BITS - ovl->data->gmc_bits); @@ -220,8 +221,8 @@ static void mtk_ovl_layer_on(struct mtk_ddp_comp *comp, unsigned int idx, gmc_value = gmc_thrshd_l | gmc_thrshd_l << 8 | gmc_thrshd_h << 16 | gmc_thrshd_h << 24; mtk_ddp_write(cmdq_pkt, gmc_value, - comp, ovl->regs, DISP_REG_OVL_RDMA_GMC(idx)); - mtk_ddp_write_mask(cmdq_pkt, BIT(idx), comp, ovl->regs, + >cmdq_reg, ovl->regs, DISP_REG_OVL_RDMA_GMC(idx)); + mtk_ddp_write_mask(cmdq_pkt, BIT(idx), >cmdq_reg, ovl->regs, DISP_REG_OVL_SRC_CON, BIT(idx)); } @@ -230,9 +231,9 @@ static void mtk_ovl_layer_off(struct mtk_ddp_comp *comp, unsigned int idx, { struct mtk_disp_ovl *ovl = dev_get_drvdata(comp->dev); - mtk_ddp_write_mask(cmdq_pkt,
[PATCH v2 07/12] drm/mediatek: Use struct cmdq_client_reg to gather cmdq variable
From: CK Hu struct cmdq_client_reg include subsys and offset, so use it to replace these two variable. Signed-off-by: CK Hu Signed-off-by: Chun-Kuang Hu --- drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 26 ++--- drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 4 ++-- 2 files changed, 9 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c index 775bc37c4045..14371d5863ae 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c @@ -96,8 +96,8 @@ void mtk_ddp_write(struct cmdq_pkt *cmdq_pkt, unsigned int value, { #if IS_REACHABLE(CONFIG_MTK_CMDQ) if (cmdq_pkt) - cmdq_pkt_write(cmdq_pkt, comp->subsys, - comp->regs_pa + offset, value); + cmdq_pkt_write(cmdq_pkt, comp->cmdq_reg.subsys, + comp->cmdq_reg.offset + offset, value); else #endif writel(value, regs + offset); @@ -109,8 +109,8 @@ void mtk_ddp_write_relaxed(struct cmdq_pkt *cmdq_pkt, unsigned int value, { #if IS_REACHABLE(CONFIG_MTK_CMDQ) if (cmdq_pkt) - cmdq_pkt_write(cmdq_pkt, comp->subsys, - comp->regs_pa + offset, value); + cmdq_pkt_write(cmdq_pkt, comp->cmdq_reg.subsys, + comp->cmdq_reg.offset + offset, value); else #endif writel_relaxed(value, regs + offset); @@ -122,8 +122,8 @@ void mtk_ddp_write_mask(struct cmdq_pkt *cmdq_pkt, unsigned int value, { #if IS_REACHABLE(CONFIG_MTK_CMDQ) if (cmdq_pkt) { - cmdq_pkt_write_mask(cmdq_pkt, comp->subsys, - comp->regs_pa + offset, value, mask); + cmdq_pkt_write_mask(cmdq_pkt, comp->cmdq_reg.subsys, + comp->cmdq_reg.offset + offset, value, mask); } else { #endif u32 tmp = readl(regs + offset); @@ -558,10 +558,6 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp, struct platform_device *comp_pdev; enum mtk_ddp_comp_type type; struct mtk_ddp_comp_dev *priv; -#if IS_REACHABLE(CONFIG_MTK_CMDQ) - struct resource res; - struct cmdq_client_reg cmdq_reg; -#endif int ret; if (comp_id < 0 || comp_id >= DDP_COMPONENT_ID_MAX) @@ -591,17 +587,9 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp, comp->dev = _pdev->dev; #if IS_REACHABLE(CONFIG_MTK_CMDQ) - if (of_address_to_resource(node, 0, ) != 0) { - dev_err(comp->dev, "Missing reg in %s node\n", node->full_name); - return -EINVAL; - } - comp->regs_pa = res.start; - - ret = cmdq_dev_get_client_reg(comp->dev, _reg, 0); + ret = cmdq_dev_get_client_reg(comp->dev, >cmdq_reg, 0); if (ret) dev_dbg(comp->dev, "get mediatek,gce-client-reg fail!\n"); - else - comp->subsys = cmdq_reg.subsys; #endif /* Only DMA capable components need the LARB property */ diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h index e18299573d2b..621b07ef807e 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h @@ -7,6 +7,7 @@ #define MTK_DRM_DDP_COMP_H #include +#include struct device; struct device_node; @@ -102,8 +103,7 @@ struct mtk_ddp_comp { struct device *larb_dev; enum mtk_ddp_comp_id id; const struct mtk_ddp_comp_funcs *funcs; - resource_size_t regs_pa; - u8 subsys; + struct cmdq_client_reg cmdq_reg; }; static inline int mtk_ddp_comp_clk_enable(struct mtk_ddp_comp *comp) -- 2.17.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 06/12] drm/mediatek: Remove irq in struct mtk_ddp_comp
From: CK Hu irq in struct mtk_ddp_comp is useless, so remove it. Signed-off-by: CK Hu Signed-off-by: Chun-Kuang Hu --- drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c index eaca3b930c5b..775bc37c4045 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include @@ -581,11 +580,9 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp, comp_id == DDP_COMPONENT_DSI2 || comp_id == DDP_COMPONENT_DSI3 || comp_id == DDP_COMPONENT_PWM0) { - comp->irq = 0; return 0; } - comp->irq = of_irq_get(node, 0); comp_pdev = of_find_device_by_node(node); if (!comp_pdev) { DRM_INFO("Waiting for device %s\n", node->full_name); -- 2.17.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 05/12] drm/mediatek: Move regs info from struct mtk_ddp_comp to sub driver private data
From: CK Hu Some ddp component exist in both display path and other path, so data belonged to sub driver should be moved into sub driver private data so it could be used for multiple path. regs info is one of sub driver data, so move it. Signed-off-by: CK Hu Signed-off-by: Chun-Kuang Hu --- drivers/gpu/drm/mediatek/mtk_disp_color.c | 17 ++- drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 67 +++ drivers/gpu/drm/mediatek/mtk_disp_rdma.c| 42 --- drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 121 +--- drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 11 +- 5 files changed, 165 insertions(+), 93 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_color.c b/drivers/gpu/drm/mediatek/mtk_disp_color.c index 7556976cd461..93863dbfb761 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_color.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_color.c @@ -39,6 +39,7 @@ struct mtk_disp_color { struct mtk_ddp_comp ddp_comp; struct drm_crtc *crtc; struct clk *clk; + void __iomem*regs; const struct mtk_disp_color_data*data; }; @@ -67,8 +68,8 @@ static void mtk_color_config(struct mtk_ddp_comp *comp, unsigned int w, { struct mtk_disp_color *color = comp_to_color(comp); - mtk_ddp_write(cmdq_pkt, w, comp, DISP_COLOR_WIDTH(color)); - mtk_ddp_write(cmdq_pkt, h, comp, DISP_COLOR_HEIGHT(color)); + mtk_ddp_write(cmdq_pkt, w, comp, color->regs, DISP_COLOR_WIDTH(color)); + mtk_ddp_write(cmdq_pkt, h, comp, color->regs, DISP_COLOR_HEIGHT(color)); } static void mtk_color_start(struct mtk_ddp_comp *comp) @@ -76,8 +77,8 @@ static void mtk_color_start(struct mtk_ddp_comp *comp) struct mtk_disp_color *color = comp_to_color(comp); writel(COLOR_BYPASS_ALL | COLOR_SEQ_SEL, - comp->regs + DISP_COLOR_CFG_MAIN); - writel(0x1, comp->regs + DISP_COLOR_START(color)); + color->regs + DISP_COLOR_CFG_MAIN); + writel(0x1, color->regs + DISP_COLOR_START(color)); } static const struct mtk_ddp_comp_funcs mtk_disp_color_funcs = { @@ -122,6 +123,7 @@ static int mtk_disp_color_probe(struct platform_device *pdev) { struct device *dev = >dev; struct mtk_disp_color *priv; + struct resource *res; int comp_id; int ret; @@ -135,6 +137,13 @@ static int mtk_disp_color_probe(struct platform_device *pdev) return PTR_ERR(priv->clk); } + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + priv->regs = devm_ioremap_resource(dev, res); + if (IS_ERR(priv->regs)) { + dev_err(dev, "failed to ioremap color\n"); + return PTR_ERR(priv->regs); + } + comp_id = mtk_ddp_comp_get_id(dev->of_node, MTK_DISP_COLOR); if (comp_id < 0) { dev_err(dev, "Failed to identify by alias: %d\n", comp_id); diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c index 589c33937793..90a78db0e96b 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c @@ -73,6 +73,7 @@ struct mtk_disp_ovl { struct mtk_ddp_comp ddp_comp; struct drm_crtc *crtc; struct clk *clk; + void __iomem*regs; const struct mtk_disp_ovl_data *data; }; @@ -87,7 +88,7 @@ static irqreturn_t mtk_disp_ovl_irq_handler(int irq, void *dev_id) struct mtk_ddp_comp *ovl = >ddp_comp; /* Clear frame completion interrupt */ - writel(0x0, ovl->regs + DISP_REG_OVL_INTSTA); + writel(0x0, priv->regs + DISP_REG_OVL_INTSTA); if (!priv->crtc) return IRQ_NONE; @@ -103,8 +104,8 @@ static void mtk_ovl_enable_vblank(struct mtk_ddp_comp *comp, struct mtk_disp_ovl *ovl = comp_to_ovl(comp); ovl->crtc = crtc; - writel(0x0, comp->regs + DISP_REG_OVL_INTSTA); - writel_relaxed(OVL_FME_CPL_INT, comp->regs + DISP_REG_OVL_INTEN); + writel(0x0, ovl->regs + DISP_REG_OVL_INTSTA); + writel_relaxed(OVL_FME_CPL_INT, ovl->regs + DISP_REG_OVL_INTEN); } static void mtk_ovl_disable_vblank(struct mtk_ddp_comp *comp) @@ -112,7 +113,7 @@ static void mtk_ovl_disable_vblank(struct mtk_ddp_comp *comp) struct mtk_disp_ovl *ovl = comp_to_ovl(comp); ovl->crtc = NULL; - writel_relaxed(0x0, comp->regs + DISP_REG_OVL_INTEN); + writel_relaxed(0x0, ovl->regs + DISP_REG_OVL_INTEN); } static int mtk_ovl_clk_enable(struct device *dev) @@ -131,25 +132,31 @@ static void mtk_ovl_clk_disable(struct device *dev) static void mtk_ovl_start(struct mtk_ddp_comp *comp) { - writel_relaxed(0x1, comp->regs + DISP_REG_OVL_EN); + struct mtk_disp_ovl *ovl = dev_get_drvdata(comp->dev); + + writel_relaxed(0x1, ovl->regs +
[PATCH v2 04/12] drm/mediatek: Move clk info from struct mtk_ddp_comp to sub driver private data
From: CK Hu Some ddp component exist in both display path and other path, so data belonged to sub driver should be moved into sub driver private data so it could be used for multiple path. clk info is one of sub driver data, so move it. Signed-off-by: CK Hu Signed-off-by: Chun-Kuang Hu --- drivers/gpu/drm/mediatek/mtk_disp_color.c | 23 drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 23 drivers/gpu/drm/mediatek/mtk_disp_rdma.c| 23 drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 6 +- drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 63 + drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 18 +- 6 files changed, 141 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_color.c b/drivers/gpu/drm/mediatek/mtk_disp_color.c index 6ee4515dc272..7556976cd461 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_color.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_color.c @@ -38,6 +38,7 @@ struct mtk_disp_color_data { struct mtk_disp_color { struct mtk_ddp_comp ddp_comp; struct drm_crtc *crtc; + struct clk *clk; const struct mtk_disp_color_data*data; }; @@ -46,6 +47,20 @@ static inline struct mtk_disp_color *comp_to_color(struct mtk_ddp_comp *comp) return container_of(comp, struct mtk_disp_color, ddp_comp); } +static int mtk_color_clk_enable(struct device *dev) +{ + struct mtk_disp_color *color = dev_get_drvdata(dev); + + return clk_prepare_enable(color->clk); +} + +static void mtk_color_clk_disable(struct device *dev) +{ + struct mtk_disp_color *color = dev_get_drvdata(dev); + + clk_disable_unprepare(color->clk); +} + static void mtk_color_config(struct mtk_ddp_comp *comp, unsigned int w, unsigned int h, unsigned int vrefresh, unsigned int bpc, struct cmdq_pkt *cmdq_pkt) @@ -66,6 +81,8 @@ static void mtk_color_start(struct mtk_ddp_comp *comp) } static const struct mtk_ddp_comp_funcs mtk_disp_color_funcs = { + .clk_enable = mtk_color_clk_enable, + .clk_disable = mtk_color_clk_disable, .config = mtk_color_config, .start = mtk_color_start, }; @@ -112,6 +129,12 @@ static int mtk_disp_color_probe(struct platform_device *pdev) if (!priv) return -ENOMEM; + priv->clk = devm_clk_get(dev, NULL); + if (IS_ERR(priv->clk)) { + dev_err(dev, "failed to get color clk\n"); + return PTR_ERR(priv->clk); + } + comp_id = mtk_ddp_comp_get_id(dev->of_node, MTK_DISP_COLOR); if (comp_id < 0) { dev_err(dev, "Failed to identify by alias: %d\n", comp_id); diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c index f8e99d67132d..589c33937793 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c @@ -72,6 +72,7 @@ struct mtk_disp_ovl_data { struct mtk_disp_ovl { struct mtk_ddp_comp ddp_comp; struct drm_crtc *crtc; + struct clk *clk; const struct mtk_disp_ovl_data *data; }; @@ -114,6 +115,20 @@ static void mtk_ovl_disable_vblank(struct mtk_ddp_comp *comp) writel_relaxed(0x0, comp->regs + DISP_REG_OVL_INTEN); } +static int mtk_ovl_clk_enable(struct device *dev) +{ + struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); + + return clk_prepare_enable(ovl->clk); +} + +static void mtk_ovl_clk_disable(struct device *dev) +{ + struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); + + clk_disable_unprepare(ovl->clk); +} + static void mtk_ovl_start(struct mtk_ddp_comp *comp) { writel_relaxed(0x1, comp->regs + DISP_REG_OVL_EN); @@ -313,6 +328,8 @@ static void mtk_ovl_bgclr_in_off(struct mtk_ddp_comp *comp) } static const struct mtk_ddp_comp_funcs mtk_disp_ovl_funcs = { + .clk_enable = mtk_ovl_clk_enable, + .clk_disable = mtk_ovl_clk_disable, .config = mtk_ovl_config, .start = mtk_ovl_start, .stop = mtk_ovl_stop, @@ -373,6 +390,12 @@ static int mtk_disp_ovl_probe(struct platform_device *pdev) if (irq < 0) return irq; + priv->clk = devm_clk_get(dev, NULL); + if (IS_ERR(priv->clk)) { + dev_err(dev, "failed to get ovl clk\n"); + return PTR_ERR(priv->clk); + } + priv->data = of_device_get_match_data(dev); comp_id = mtk_ddp_comp_get_id(dev->of_node, diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c index a3c487ea8344..95feacda49b1 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c @@ -63,6 +63,7 @@ struct mtk_disp_rdma_data { struct mtk_disp_rdma { struct mtk_ddp_comp ddp_comp; struct drm_crtc
[PATCH v2 03/12] drm/mediatek: Separate getting larb device to a function
From: CK Hu To make the code cleaner, separate getting larb device to a function. Signed-off-by: CK Hu Signed-off-by: Chun-Kuang Hu --- drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 57 - 1 file changed, 32 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c index 1730b3ddef70..a11b4f8bf959 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c @@ -465,19 +465,41 @@ unsigned int mtk_drm_find_possible_crtc_by_comp(struct drm_device *drm, return ret; } +static int mtk_ddp_get_larb_dev(struct device_node *node, struct mtk_ddp_comp *comp, + struct device *dev) +{ + struct device_node *larb_node; + struct platform_device *larb_pdev; + + larb_node = of_parse_phandle(node, "mediatek,larb", 0); + if (!larb_node) { + dev_err(dev, "Missing mediadek,larb phandle in %pOF node\n", node); + return -EINVAL; + } + + larb_pdev = of_find_device_by_node(larb_node); + if (!larb_pdev) { + dev_warn(dev, "Waiting for larb device %pOF\n", larb_node); + of_node_put(larb_node); + return -EPROBE_DEFER; + } + of_node_put(larb_node); + comp->larb_dev = _pdev->dev; + + return 0; +} + int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp, enum mtk_ddp_comp_id comp_id, const struct mtk_ddp_comp_funcs *funcs) { struct platform_device *comp_pdev; struct device *dev; enum mtk_ddp_comp_type type; - struct device_node *larb_node; - struct platform_device *larb_pdev; #if IS_REACHABLE(CONFIG_MTK_CMDQ) struct resource res; struct cmdq_client_reg cmdq_reg; - int ret; #endif + int ret; if (comp_id < 0 || comp_id >= DDP_COMPONENT_ID_MAX) return -EINVAL; @@ -529,30 +551,15 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp, #endif /* Only DMA capable components need the LARB property */ - comp->larb_dev = NULL; - if (type != MTK_DISP_OVL && - type != MTK_DISP_OVL_2L && - type != MTK_DISP_RDMA && - type != MTK_DISP_WDMA) - return 0; - - larb_node = of_parse_phandle(node, "mediatek,larb", 0); - if (!larb_node) { - dev_err(dev, - "Missing mediadek,larb phandle in %pOF node\n", node); - return -EINVAL; + if (type == MTK_DISP_OVL || + type == MTK_DISP_OVL_2L || + type == MTK_DISP_RDMA || + type == MTK_DISP_WDMA) { + ret = mtk_ddp_get_larb_dev(node, comp, dev); + if (ret) + return ret; } - larb_pdev = of_find_device_by_node(larb_node); - if (!larb_pdev) { - dev_warn(dev, "Waiting for larb device %pOF\n", larb_node); - of_node_put(larb_node); - return -EPROBE_DEFER; - } - of_node_put(larb_node); - - comp->larb_dev = _pdev->dev; - return 0; } -- 2.17.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 02/12] drm/mediatek: Use correct device pointer to get CMDQ client register
Some ddp component use mmsys device pointer to get CMDQ client register, this would get mmsys' CMDQ client register, so use each ddp component's device pointer to get. Signed-off-by: Chun-Kuang Hu --- drivers/gpu/drm/mediatek/mtk_disp_color.c | 2 +- drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 2 +- drivers/gpu/drm/mediatek/mtk_disp_rdma.c| 2 +- drivers/gpu/drm/mediatek/mtk_dpi.c | 2 +- drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 15 +++ drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 5 ++--- drivers/gpu/drm/mediatek/mtk_drm_drv.c | 2 +- drivers/gpu/drm/mediatek/mtk_dsi.c | 2 +- 8 files changed, 19 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_color.c b/drivers/gpu/drm/mediatek/mtk_disp_color.c index 6048cbc9f0ec..6ee4515dc272 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_color.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_color.c @@ -118,7 +118,7 @@ static int mtk_disp_color_probe(struct platform_device *pdev) return comp_id; } - ret = mtk_ddp_comp_init(dev, dev->of_node, >ddp_comp, comp_id, + ret = mtk_ddp_comp_init(dev->of_node, >ddp_comp, comp_id, _disp_color_funcs); if (ret) { if (ret != -EPROBE_DEFER) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c index 74ef6fc0528b..f8e99d67132d 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c @@ -384,7 +384,7 @@ static int mtk_disp_ovl_probe(struct platform_device *pdev) return comp_id; } - ret = mtk_ddp_comp_init(dev, dev->of_node, >ddp_comp, comp_id, + ret = mtk_ddp_comp_init(dev->of_node, >ddp_comp, comp_id, _disp_ovl_funcs); if (ret) { if (ret != -EPROBE_DEFER) diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c index d46b8ae1d080..a3c487ea8344 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c @@ -292,7 +292,7 @@ static int mtk_disp_rdma_probe(struct platform_device *pdev) return comp_id; } - ret = mtk_ddp_comp_init(dev, dev->of_node, >ddp_comp, comp_id, + ret = mtk_ddp_comp_init(dev->of_node, >ddp_comp, comp_id, _disp_rdma_funcs); if (ret) { if (ret != -EPROBE_DEFER) diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c index cf11c4850b40..6852b76fa583 100644 --- a/drivers/gpu/drm/mediatek/mtk_dpi.c +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c @@ -784,7 +784,7 @@ static int mtk_dpi_probe(struct platform_device *pdev) return comp_id; } - ret = mtk_ddp_comp_init(dev, dev->of_node, >ddp_comp, comp_id, + ret = mtk_ddp_comp_init(dev->of_node, >ddp_comp, comp_id, _dpi_funcs); if (ret) { dev_err(dev, "Failed to initialize component: %d\n", ret); diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c index cab53431ceec..1730b3ddef70 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c @@ -465,10 +465,11 @@ unsigned int mtk_drm_find_possible_crtc_by_comp(struct drm_device *drm, return ret; } -int mtk_ddp_comp_init(struct device *dev, struct device_node *node, - struct mtk_ddp_comp *comp, enum mtk_ddp_comp_id comp_id, - const struct mtk_ddp_comp_funcs *funcs) +int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp, + enum mtk_ddp_comp_id comp_id, const struct mtk_ddp_comp_funcs *funcs) { + struct platform_device *comp_pdev; + struct device *dev; enum mtk_ddp_comp_type type; struct device_node *larb_node; struct platform_device *larb_pdev; @@ -506,10 +507,16 @@ int mtk_ddp_comp_init(struct device *dev, struct device_node *node, if (IS_ERR(comp->clk)) return PTR_ERR(comp->clk); + comp_pdev = of_find_device_by_node(node); + if (!comp_pdev) { + DRM_INFO("Waiting for device %s\n", node->full_name); + return -EPROBE_DEFER; + } + dev = _pdev->dev; + #if IS_REACHABLE(CONFIG_MTK_CMDQ) if (of_address_to_resource(node, 0, ) != 0) { dev_err(dev, "Missing reg in %s node\n", node->full_name); - put_device(_pdev->dev); return -EINVAL; } comp->regs_pa = res.start; diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h index 1d9e00b69462..3bd6012d0746 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h @@ -204,9 +204,8 @@ int
[PATCH v2 01/12] drm/mediatek: Get CMDQ client register for all ddp component
Only OVL, RDMA,and WDMA get CMDQ client register information, but all ddp component should work with CMDQ, so get this information for all ddp component. Signed-off-by: Chun-Kuang Hu --- drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 29 +++-- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c index 3064eac1a750..cab53431ceec 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c @@ -506,6 +506,21 @@ int mtk_ddp_comp_init(struct device *dev, struct device_node *node, if (IS_ERR(comp->clk)) return PTR_ERR(comp->clk); +#if IS_REACHABLE(CONFIG_MTK_CMDQ) + if (of_address_to_resource(node, 0, ) != 0) { + dev_err(dev, "Missing reg in %s node\n", node->full_name); + put_device(_pdev->dev); + return -EINVAL; + } + comp->regs_pa = res.start; + + ret = cmdq_dev_get_client_reg(dev, _reg, 0); + if (ret) + dev_dbg(dev, "get mediatek,gce-client-reg fail!\n"); + else + comp->subsys = cmdq_reg.subsys; +#endif + /* Only DMA capable components need the LARB property */ comp->larb_dev = NULL; if (type != MTK_DISP_OVL && @@ -531,20 +546,6 @@ int mtk_ddp_comp_init(struct device *dev, struct device_node *node, comp->larb_dev = _pdev->dev; -#if IS_REACHABLE(CONFIG_MTK_CMDQ) - if (of_address_to_resource(node, 0, ) != 0) { - dev_err(dev, "Missing reg in %s node\n", node->full_name); - put_device(_pdev->dev); - return -EINVAL; - } - comp->regs_pa = res.start; - - ret = cmdq_dev_get_client_reg(dev, _reg, 0); - if (ret) - dev_dbg(dev, "get mediatek,gce-client-reg fail!\n"); - else - comp->subsys = cmdq_reg.subsys; -#endif return 0; } -- 2.17.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 00/12] Decouple Mediatek DRM sub driver
mtk ccorr is controlled by DRM and MDP [1]. In order to share mtk_ccorr driver for DRM and MDP, decouple Mediatek DRM sub driver which include mtk_ccorr, so MDP could use this decoupled mtk_ccorr. Changes in v2: 1. Fix iommu larb problem. 2. Based on mediatek-drm-next-5.11-2 [2]. [1] https://patchwork.kernel.org/patch/11140751/ [2] https://git.kernel.org/pub/scm/linux/kernel/git/chunkuang.hu/linux.git/log/?h=mediatek-drm-next-5.11-2 CK Hu (10): drm/mediatek: Separate getting larb device to a function drm/mediatek: Move clk info from struct mtk_ddp_comp to sub driver private data drm/mediatek: Move regs info from struct mtk_ddp_comp to sub driver private data drm/mediatek: Remove irq in struct mtk_ddp_comp drm/mediatek: Use struct cmdq_client_reg to gather cmdq variable drm/mediatek: Move cmdq_reg info from struct mtk_ddp_comp to sub driver private data drm/mediatek: Change sub driver interface from mtk_ddp_comp to device drm/mediatek: Register vblank callback function drm/mediatek: DRM driver directly refer to sub driver's function drm/mediatek: Move mtk_ddp_comp_init() from sub driver to DRM driver Chun-Kuang Hu (2): drm/mediatek: Get CMDQ client register for all ddp component drm/mediatek: Use correct device pointer to get CMDQ client register drivers/gpu/drm/mediatek/mtk_disp_color.c | 89 ++-- drivers/gpu/drm/mediatek/mtk_disp_drv.h | 69 drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 217 +- drivers/gpu/drm/mediatek/mtk_disp_rdma.c| 169 drivers/gpu/drm/mediatek/mtk_dpi.c | 44 +- drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 75 ++-- drivers/gpu/drm/mediatek/mtk_drm_crtc.h | 1 - drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 429 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 100 +++-- drivers/gpu/drm/mediatek/mtk_drm_drv.c | 30 +- drivers/gpu/drm/mediatek/mtk_drm_drv.h | 2 +- drivers/gpu/drm/mediatek/mtk_dsi.c | 47 +-- 12 files changed, 676 insertions(+), 596 deletions(-) create mode 100644 drivers/gpu/drm/mediatek/mtk_disp_drv.h -- 2.17.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm: rework description of primary and cursor planes
On Thursday, December 10th, 2020 at 4:56 PM, Daniel Vetter wrote: > Huh so crtc are registered forward and planes backward? I guess adding > amd people. And yeah sounds like defacto you can't figure out which > primary plane goes to which crtc, and we just take whatever goes. > Maybe that stricter approach with more guarantees just doesn't work, > ship sailed already :-/ Yeah. Even if we fixed the amdgpu driver and added the check, user-space still couldn't have the guarantee that it can associate the n-th primary plane with the n-th CRTC, because it might run with an old kernel. If we really wanted to allow user-space to discover the internal ->{primary,cursor} pointers, I think we should just expose a new property. That way, the uAPI would be a lot more explicit and a lot less guessing. The cost is that it wouldn't work on older kernels, but with amdgpu user-space can't rely on the implicit rule you've suggested anyways. ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm: rework description of primary and cursor planes
On Thu, Dec 10, 2020 at 4:45 PM Simon Ser wrote: > On Wednesday, December 9th, 2020 at 8:40 PM, Daniel Vetter > wrote: > > > But it's not enough, can't have two CRTCs with the same primary plane. > > > Well, > > > I give up, it's just simpler to use Daniel's criteria. > > > > Yeah, also with the validation check we'll now real quick if any driver > > gets it wrong. Then I think we can have a useful discussion about why, and > > what to do with that case. As-is we're kinda drafting specs in the void, > > which is always a bit tough ... > > > > That's kinda another reason for doing the stricter check I proposed, it's > > easier to check and guarantee (on both the driver and compositor side > > hopefully). > > Hmm, actually, I'm already hitting a driver which doesn't guarantee that. > amdgpu with my hardware [1] has the first primary plane linked to the the last > CRTC, the second primary plane linked to the second-to-last CRTC, and so on. > > [1]: https://drmdb.emersion.fr/devices/129e158a4d9f Huh so crtc are registered forward and planes backward? I guess adding amd people. And yeah sounds like defacto you can't figure out which primary plane goes to which crtc, and we just take whatever goes. Maybe that stricter approach with more guarantees just doesn't work, ship sailed already :-/ -Daniel -Daniel -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 3/3] drm: require a non_NULL drm_crtc.primary
If a CRTC is missing a legacy primary plane pointer, a lot of things will be broken for user-space: fbdev stops working and the entire legacy uAPI stops working. Require all drivers to populate drm_crtc.primary to prevent these issues. Warn if it's NULL. Signed-off-by: Simon Ser Cc: Daniel Vetter Cc: Pekka Paalanen --- drivers/gpu/drm/drm_mode_config.c | 3 +++ drivers/gpu/drm/drm_plane.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c index 2c73a60e8765..fbe680035129 100644 --- a/drivers/gpu/drm/drm_mode_config.c +++ b/drivers/gpu/drm/drm_mode_config.c @@ -639,6 +639,9 @@ void drm_mode_config_validate(struct drm_device *dev) } drm_for_each_crtc(crtc, dev) { + WARN(!crtc->primary, "Missing primary plane on [CRTC:%d:%s]\n", +crtc->base.id, crtc->name); + if (crtc->primary) { WARN(!(crtc->primary->possible_crtcs & BIT(crtc->index)), "Bogus primary plane possible_crtcs: [PLANE:%d:%s] must be compatible with [CRTC:%d:%s]\n", diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c index 5d33ca9f0032..49b0a8b9ac02 100644 --- a/drivers/gpu/drm/drm_plane.c +++ b/drivers/gpu/drm/drm_plane.c @@ -57,7 +57,7 @@ * Legacy uAPI doesn't expose the primary and cursor planes directly. DRM core * relies on the driver to set the primary and optionally the cursor plane used * for legacy IOCTLs. This is done by calling drm_crtc_init_with_planes(). All - * drivers should provide one primary plane per CRTC to avoid surprising legacy + * drivers must provide one primary plane per CRTC to avoid surprising legacy * userspace too much. */ -- 2.29.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 2/3] drm: validate possible_crtcs for primary and cursor planes
If a primary or cursor plane is not compatible with a CRTC it's attached to via the legacy primary/cursor field, things will be broken for legacy user-space. Signed-off-by: Simon Ser Cc: Daniel Vetter Cc: Pekka Paalanen --- drivers/gpu/drm/drm_mode_config.c | 16 1 file changed, 16 insertions(+) diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c index f1affc1bb679..2c73a60e8765 100644 --- a/drivers/gpu/drm/drm_mode_config.c +++ b/drivers/gpu/drm/drm_mode_config.c @@ -625,6 +625,7 @@ static void validate_encoder_possible_crtcs(struct drm_encoder *encoder) void drm_mode_config_validate(struct drm_device *dev) { struct drm_encoder *encoder; + struct drm_crtc *crtc; if (!drm_core_check_feature(dev, DRIVER_MODESET)) return; @@ -636,4 +637,19 @@ void drm_mode_config_validate(struct drm_device *dev) validate_encoder_possible_clones(encoder); validate_encoder_possible_crtcs(encoder); } + + drm_for_each_crtc(crtc, dev) { + if (crtc->primary) { + WARN(!(crtc->primary->possible_crtcs & BIT(crtc->index)), +"Bogus primary plane possible_crtcs: [PLANE:%d:%s] must be compatible with [CRTC:%d:%s]\n", +crtc->primary->base.id, crtc->primary->name, +crtc->base.id, crtc->name); + } + if (crtc->cursor) { + WARN(!(crtc->cursor->possible_crtcs & BIT(crtc->index)), +"Bogus cursor plane possible_crtcs: [PLANE:%d:%s] must be compatible with [CRTC:%d:%s]\n", +crtc->cursor->base.id, crtc->cursor->name, +crtc->base.id, crtc->name); + } + } } -- 2.29.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 1/3] drm: rework description of primary and cursor planes
The previous wording could be understood by user-space evelopers as "a primary/cursor plane is only compatible with a single CRTC" [1]. Reword the planes description to make it clear the DRM-internal drm_crtc.primary and drm_crtc.cursor planes are for legacy uAPI. [1]: https://github.com/swaywm/wlroots/pull/2333#discussion_r456788057 Signed-off-by: Simon Ser Reviewed-by: Daniel Vetter Cc: Pekka Paalanen --- drivers/gpu/drm/drm_crtc.c | 3 +++ drivers/gpu/drm/drm_plane.c | 16 +--- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 8d19d258547f..a6336c7154d6 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -256,6 +256,9 @@ struct dma_fence *drm_crtc_create_fence(struct drm_crtc *crtc) * planes). For really simple hardware which has only 1 plane look at * drm_simple_display_pipe_init() instead. * + * The @primary and @cursor planes are only relevant for legacy uAPI, see + * _crtc.primary and _crtc.cursor. + * * Returns: * Zero on success, error code on failure. */ diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c index 385801dd21f9..5d33ca9f0032 100644 --- a/drivers/gpu/drm/drm_plane.c +++ b/drivers/gpu/drm/drm_plane.c @@ -49,14 +49,16 @@ * drm_plane (possibly as part of a larger structure) and registers it * with a call to drm_universal_plane_init(). * - * Cursor and overlay planes are optional. All drivers should provide one - * primary plane per CRTC to avoid surprising userspace too much. See enum - * drm_plane_type for a more in-depth discussion of these special uapi-relevant - * plane types. Special planes are associated with their CRTC by calling - * drm_crtc_init_with_planes(). - * * The type of a plane is exposed in the immutable "type" enumeration property, - * which has one of the following values: "Overlay", "Primary", "Cursor". + * which has one of the following values: "Overlay", "Primary", "Cursor" (see + * enum drm_plane_type). A plane can be compatible with multiple CRTCs, see + * _plane.possible_crtcs. + * + * Legacy uAPI doesn't expose the primary and cursor planes directly. DRM core + * relies on the driver to set the primary and optionally the cursor plane used + * for legacy IOCTLs. This is done by calling drm_crtc_init_with_planes(). All + * drivers should provide one primary plane per CRTC to avoid surprising legacy + * userspace too much. */ static unsigned int drm_num_planes(struct drm_device *dev) -- 2.29.2 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v8, 5/6] drm/mediatek: add RDMA fifo size error handle
Hi, Yongqiang: Yongqiang Niu 於 2020年12月10日 週四 下午5:08寫道: > > This patch add RDMA fifo size error handle > rdma fifo size will not always bigger than the calculated threshold > if that case happened, we need set fifo size as the threshold > > Signed-off-by: Yongqiang Niu > --- > drivers/gpu/drm/mediatek/mtk_disp_rdma.c | 4 > 1 file changed, 4 insertions(+) > > diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c > b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c > index 794acc5..0508392 100644 > --- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c > +++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c > @@ -151,6 +151,10 @@ static void mtk_rdma_config(struct mtk_ddp_comp *comp, > unsigned int width, > * account for blanking, and with a pixel depth of 4 bytes: > */ > threshold = width * height * vrefresh * 4 * 7 / 100; > + > + if (threshold > rdma_fifo_size) > + threshold = rdma_fifo_size; If the formula is not correct, you should fix the formula not work around. Regards, Chun-Kuang. > + > reg = RDMA_FIFO_UNDERFLOW_EN | > RDMA_FIFO_PSEUDO_SIZE(rdma_fifo_size) | > RDMA_OUTPUT_VALID_FIFO_THRESHOLD(threshold); > -- > 1.8.1.1.dirty > ___ > Linux-mediatek mailing list > linux-media...@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/linux-mediatek ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm: rework description of primary and cursor planes
Additional note, I don't really want to add the same check for cursor planes, because I don't want to forbid a driver from having the CRTC without a cursor plane and the second CRTC with a cursor plane. I don't know if such heterogeneous hardware exists, but it sounds like something we should be able to support. ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm: rework description of primary and cursor planes
On Wednesday, December 9th, 2020 at 8:40 PM, Daniel Vetter wrote: > > But it's not enough, can't have two CRTCs with the same primary plane. Well, > > I give up, it's just simpler to use Daniel's criteria. > > Yeah, also with the validation check we'll now real quick if any driver > gets it wrong. Then I think we can have a useful discussion about why, and > what to do with that case. As-is we're kinda drafting specs in the void, > which is always a bit tough ... > > That's kinda another reason for doing the stricter check I proposed, it's > easier to check and guarantee (on both the driver and compositor side > hopefully). Hmm, actually, I'm already hitting a driver which doesn't guarantee that. amdgpu with my hardware [1] has the first primary plane linked to the the last CRTC, the second primary plane linked to the second-to-last CRTC, and so on. [1]: https://drmdb.emersion.fr/devices/129e158a4d9f ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v8, 1/6] dt-bindings: mediatek: add rdma_fifo_size description for mt8183 display
Hi, Yongqiang: Yongqiang Niu 於 2020年12月10日 週四 下午5:22寫道: > > rdma fifo size may be different even in same SOC, add this > property to the corresponding rdma > > Signed-off-by: Yongqiang Niu > --- > .../bindings/display/mediatek/mediatek,disp.txt | 16 > > 1 file changed, 16 insertions(+) > > diff --git > a/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt > b/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt > index 1212207..64c64ee 100644 > --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt > +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt > @@ -66,6 +66,13 @@ Required properties (DMA function blocks): >argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.txt >for details. > > +Optional properties (RDMA function blocks): > +- mediatek,rdma_fifo_size: rdma fifo size may be different even in same SOC, > add this > + property to the corresponding rdma > + the value is the Max value which defined in hardware data sheet. > + rdma_fifo_size of rdma0 in mt8183 is 5120 > + rdma_fifo_size of rdma1 in mt8183 is 2048 > + > Examples: > > mmsys: clock-controller@1400 { > @@ -207,3 +214,12 @@ od@14023000 { > power-domains = < MT8173_POWER_DOMAIN_MM>; > clocks = < CLK_MM_DISP_OD>; > }; > + > +rdma1: rdma@1400c000 { > + compatible = "mediatek,mt8183-disp-rdma"; > + reg = <0 0x1400c000 0 0x1000>; > + interrupts = ; > + power-domains = < MT8183_POWER_DOMAIN_DISP>; > + clocks = < CLK_MM_DISP_RDMA1>; > + mediatek,rdma_fifo_size = <2048>; > +}; In [1], Rob has suggest that not add example of rdma1, it's better to add mediatek,rdma_fifo_size in rdma0 for example. [1] https://patchwork.kernel.org/project/linux-mediatek/patch/1596855231-5782-2-git-send-email-yongqiang@mediatek.com/ Regards, Chun-Kuang. > -- > 1.8.1.1.dirty > ___ > Linux-mediatek mailing list > linux-media...@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/linux-mediatek ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v5 13/19] drm/imx: parallel-display: move initialization into probe
Parts of the initialization that do not require the drm device can be done once during probe instead of possibly multiple times during bind. The bind function only creates the encoder. Signed-off-by: Philipp Zabel Acked-by: Daniel Vetter --- drivers/gpu/drm/imx/parallel-display.c | 42 -- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/imx/parallel-display.c b/drivers/gpu/drm/imx/parallel-display.c index 16e576f8ee83..42b44dbf45f5 100644 --- a/drivers/gpu/drm/imx/parallel-display.c +++ b/drivers/gpu/drm/imx/parallel-display.c @@ -261,6 +261,10 @@ static int imx_pd_register(struct drm_device *drm, struct drm_bridge *bridge = >bridge; int ret; + memset(connector, 0, sizeof(*connector)); + memset(encoder, 0, sizeof(*encoder)); + memset(bridge, 0, sizeof(*bridge)); + ret = imx_drm_encoder_parse_of(drm, encoder, imxpd->dev->of_node); if (ret) return ret; @@ -301,6 +305,18 @@ static int imx_pd_register(struct drm_device *drm, static int imx_pd_bind(struct device *dev, struct device *master, void *data) { struct drm_device *drm = data; + struct imx_parallel_display *imxpd = dev_get_drvdata(dev); + + return imx_pd_register(drm, imxpd); +} + +static const struct component_ops imx_pd_ops = { + .bind = imx_pd_bind, +}; + +static int imx_pd_probe(struct platform_device *pdev) +{ + struct device *dev = >dev; struct device_node *np = dev->of_node; const u8 *edidp; struct imx_parallel_display *imxpd; @@ -309,8 +325,9 @@ static int imx_pd_bind(struct device *dev, struct device *master, void *data) u32 bus_format = 0; const char *fmt; - imxpd = dev_get_drvdata(dev); - memset(imxpd, 0, sizeof(*imxpd)); + imxpd = devm_kzalloc(dev, sizeof(*imxpd), GFP_KERNEL); + if (!imxpd) + return -ENOMEM; /* port@1 is the output port */ ret = drm_of_find_panel_or_bridge(np, 1, 0, >panel, @@ -337,28 +354,9 @@ static int imx_pd_bind(struct device *dev, struct device *master, void *data) imxpd->dev = dev; - ret = imx_pd_register(drm, imxpd); - if (ret) - return ret; - - return 0; -} - -static const struct component_ops imx_pd_ops = { - .bind = imx_pd_bind, -}; - -static int imx_pd_probe(struct platform_device *pdev) -{ - struct imx_parallel_display *imxpd; - - imxpd = devm_kzalloc(>dev, sizeof(*imxpd), GFP_KERNEL); - if (!imxpd) - return -ENOMEM; - platform_set_drvdata(pdev, imxpd); - return component_add(>dev, _pd_ops); + return component_add(dev, _pd_ops); } static int imx_pd_remove(struct platform_device *pdev) -- 2.20.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v5 18/19] drm/imx: ipuv3-plane: use drm managed resources
Use drmm_universal_plane_alloc() to align plane memory lifetime with the drm device. drm_plane_cleanup() is called automatically before the memory is freed. Also move the call to ipu_plane_get_resources() into ipu_plane_init() and use drm managed resources to put IPU resources automatically when required. Handle error return values of the plane property creation functions. Signed-off-by: Philipp Zabel Acked-by: Daniel Vetter --- drivers/gpu/drm/imx/ipuv3-crtc.c | 27 +--- drivers/gpu/drm/imx/ipuv3-plane.c | 69 +++ drivers/gpu/drm/imx/ipuv3-plane.h | 3 -- 3 files changed, 36 insertions(+), 63 deletions(-) diff --git a/drivers/gpu/drm/imx/ipuv3-crtc.c b/drivers/gpu/drm/imx/ipuv3-crtc.c index 7ebd99ee3240..6ce8fa4348c9 100644 --- a/drivers/gpu/drm/imx/ipuv3-crtc.c +++ b/drivers/gpu/drm/imx/ipuv3-crtc.c @@ -384,29 +384,14 @@ static int ipu_crtc_init(struct ipu_crtc *ipu_crtc, drm_crtc_init_with_planes(drm, crtc, _crtc->plane[0]->base, NULL, _crtc_funcs, NULL); - ret = ipu_plane_get_resources(ipu_crtc->plane[0]); - if (ret) { - dev_err(ipu_crtc->dev, "getting plane 0 resources failed with %d.\n", - ret); - goto err_put_resources; - } - /* If this crtc is using the DP, add an overlay plane */ if (pdata->dp >= 0 && pdata->dma[1] > 0) { ipu_crtc->plane[1] = ipu_plane_init(drm, ipu, pdata->dma[1], IPU_DP_FLOW_SYNC_FG, drm_crtc_mask(_crtc->base), DRM_PLANE_TYPE_OVERLAY); - if (IS_ERR(ipu_crtc->plane[1])) { + if (IS_ERR(ipu_crtc->plane[1])) ipu_crtc->plane[1] = NULL; - } else { - ret = ipu_plane_get_resources(ipu_crtc->plane[1]); - if (ret) { - dev_err(ipu_crtc->dev, "getting plane 1 " - "resources failed with %d.\n", ret); - goto err_put_plane0_res; - } - } } ipu_crtc->irq = ipu_plane_irq(ipu_crtc->plane[0]); @@ -414,18 +399,13 @@ static int ipu_crtc_init(struct ipu_crtc *ipu_crtc, "imx_drm", ipu_crtc); if (ret < 0) { dev_err(ipu_crtc->dev, "irq request failed with %d.\n", ret); - goto err_put_plane1_res; + goto err_put_resources; } /* Only enable IRQ when we actually need it to trigger work. */ disable_irq(ipu_crtc->irq); return 0; -err_put_plane1_res: - if (ipu_crtc->plane[1]) - ipu_plane_put_resources(ipu_crtc->plane[1]); -err_put_plane0_res: - ipu_plane_put_resources(ipu_crtc->plane[0]); err_put_resources: ipu_put_resources(ipu_crtc); @@ -452,9 +432,6 @@ static void ipu_drm_unbind(struct device *dev, struct device *master, struct ipu_crtc *ipu_crtc = dev_get_drvdata(dev); ipu_put_resources(ipu_crtc); - if (ipu_crtc->plane[1]) - ipu_plane_put_resources(ipu_crtc->plane[1]); - ipu_plane_put_resources(ipu_crtc->plane[0]); } static const struct component_ops ipu_crtc_ops = { diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c b/drivers/gpu/drm/imx/ipuv3-plane.c index 8a4235d9d9f1..075508051b5f 100644 --- a/drivers/gpu/drm/imx/ipuv3-plane.c +++ b/drivers/gpu/drm/imx/ipuv3-plane.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -142,8 +143,10 @@ drm_plane_state_to_vbo(struct drm_plane_state *state) fb->format->cpp[2] * x - eba; } -void ipu_plane_put_resources(struct ipu_plane *ipu_plane) +static void ipu_plane_put_resources(struct drm_device *dev, void *ptr) { + struct ipu_plane *ipu_plane = ptr; + if (!IS_ERR_OR_NULL(ipu_plane->dp)) ipu_dp_put(ipu_plane->dp); if (!IS_ERR_OR_NULL(ipu_plane->dmfc)) @@ -154,7 +157,8 @@ void ipu_plane_put_resources(struct ipu_plane *ipu_plane) ipu_idmac_put(ipu_plane->alpha_ch); } -int ipu_plane_get_resources(struct ipu_plane *ipu_plane) +static int ipu_plane_get_resources(struct drm_device *dev, + struct ipu_plane *ipu_plane) { int ret; int alpha_ch; @@ -166,6 +170,10 @@ int ipu_plane_get_resources(struct ipu_plane *ipu_plane) return ret; } + ret = drmm_add_action_or_reset(dev, ipu_plane_put_resources, ipu_plane); + if (ret) + return ret; + alpha_ch = ipu_channel_alpha_channel(ipu_plane->dma); if (alpha_ch >= 0) { ipu_plane->alpha_ch = ipu_idmac_get(ipu_plane->ipu, alpha_ch); @@ -181,7 +189,7 @@ int ipu_plane_get_resources(struct ipu_plane *ipu_plane) if
[PATCH v5 10/19] drm/imx: imx-tve: move initialization into probe
Parts of the initialization that do not require the drm device can be done once during probe instead of possibly multiple times during bind. The bind function only creates the encoder. Signed-off-by: Philipp Zabel Acked-by: Daniel Vetter --- drivers/gpu/drm/imx/imx-tve.c | 42 --- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/imx/imx-tve.c b/drivers/gpu/drm/imx/imx-tve.c index 37771073a525..649e2f56a5da 100644 --- a/drivers/gpu/drm/imx/imx-tve.c +++ b/drivers/gpu/drm/imx/imx-tve.c @@ -438,6 +438,9 @@ static int imx_tve_register(struct drm_device *drm, struct imx_tve *tve) encoder_type = tve->mode == TVE_MODE_VGA ? DRM_MODE_ENCODER_DAC : DRM_MODE_ENCODER_TVDAC; + memset(connector, 0, sizeof(*connector)); + memset(encoder, 0, sizeof(*encoder)); + ret = imx_drm_encoder_parse_of(drm, encoder, tve->dev->of_node); if (ret) return ret; @@ -503,8 +506,19 @@ static int of_get_tve_mode(struct device_node *np) static int imx_tve_bind(struct device *dev, struct device *master, void *data) { - struct platform_device *pdev = to_platform_device(dev); struct drm_device *drm = data; + struct imx_tve *tve = dev_get_drvdata(dev); + + return imx_tve_register(drm, tve); +} + +static const struct component_ops imx_tve_ops = { + .bind = imx_tve_bind, +}; + +static int imx_tve_probe(struct platform_device *pdev) +{ + struct device *dev = >dev; struct device_node *np = dev->of_node; struct device_node *ddc_node; struct imx_tve *tve; @@ -514,8 +528,9 @@ static int imx_tve_bind(struct device *dev, struct device *master, void *data) int irq; int ret; - tve = dev_get_drvdata(dev); - memset(tve, 0, sizeof(*tve)); + tve = devm_kzalloc(dev, sizeof(*tve), GFP_KERNEL); + if (!tve) + return -ENOMEM; tve->dev = dev; @@ -622,28 +637,9 @@ static int imx_tve_bind(struct device *dev, struct device *master, void *data) if (ret) return ret; - ret = imx_tve_register(drm, tve); - if (ret) - return ret; - - return 0; -} - -static const struct component_ops imx_tve_ops = { - .bind = imx_tve_bind, -}; - -static int imx_tve_probe(struct platform_device *pdev) -{ - struct imx_tve *tve; - - tve = devm_kzalloc(>dev, sizeof(*tve), GFP_KERNEL); - if (!tve) - return -ENOMEM; - platform_set_drvdata(pdev, tve); - return component_add(>dev, _tve_ops); + return component_add(dev, _tve_ops); } static int imx_tve_remove(struct platform_device *pdev) -- 2.20.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v5 04/19] drm/plane: add drmm_universal_plane_alloc()
Add an alternative to drm_universal_plane_init() that allocates and initializes a plane and registers drm_plane_cleanup() with drmm_add_action_or_reset(). Signed-off-by: Philipp Zabel Reviewed-by: Laurent Pinchart Reviewed-by: Daniel Vetter --- Changes since v4: - Mention that plane_funcs.destroy should kfree() the plane structure, and that it should not be allocated with devm_kzalloc(), - point out drmm_universal_plane_alloc() in the drm_universal_plane_init() documentation. - WARN_ON(!funcs->destroy) in drm_universal_plane_init(). - WARN_ON(!funcs || funcs->destroy) in drmm_universal_plane_alloc(). --- drivers/gpu/drm/drm_plane.c | 134 include/drm/drm_plane.h | 42 +++ 2 files changed, 147 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c index e6231947f987..8b9471a59919 100644 --- a/drivers/gpu/drm/drm_plane.c +++ b/drivers/gpu/drm/drm_plane.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include "drm_crtc_internal.h" @@ -152,31 +153,16 @@ static int create_in_format_blob(struct drm_device *dev, struct drm_plane *plane return 0; } -/** - * drm_universal_plane_init - Initialize a new universal plane object - * @dev: DRM device - * @plane: plane object to init - * @possible_crtcs: bitmask of possible CRTCs - * @funcs: callbacks for the new plane - * @formats: array of supported formats (DRM_FORMAT\_\*) - * @format_count: number of elements in @formats - * @format_modifiers: array of struct drm_format modifiers terminated by - *DRM_FORMAT_MOD_INVALID - * @type: type of plane (overlay, primary, cursor) - * @name: printf style format string for the plane name, or NULL for default name - * - * Initializes a plane object of type @type. - * - * Returns: - * Zero on success, error code on failure. - */ -int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane, -uint32_t possible_crtcs, -const struct drm_plane_funcs *funcs, -const uint32_t *formats, unsigned int format_count, -const uint64_t *format_modifiers, -enum drm_plane_type type, -const char *name, ...) +__printf(9, 0) +static int __drm_universal_plane_init(struct drm_device *dev, + struct drm_plane *plane, + uint32_t possible_crtcs, + const struct drm_plane_funcs *funcs, + const uint32_t *formats, + unsigned int format_count, + const uint64_t *format_modifiers, + enum drm_plane_type type, + const char *name, va_list ap) { struct drm_mode_config *config = >mode_config; unsigned int format_modifier_count = 0; @@ -237,11 +223,7 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane, } if (name) { - va_list ap; - - va_start(ap, name); plane->name = kvasprintf(GFP_KERNEL, name, ap); - va_end(ap); } else { plane->name = kasprintf(GFP_KERNEL, "plane-%d", drm_num_planes(dev)); @@ -286,8 +268,102 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane, return 0; } + +/** + * drm_universal_plane_init - Initialize a new universal plane object + * @dev: DRM device + * @plane: plane object to init + * @possible_crtcs: bitmask of possible CRTCs + * @funcs: callbacks for the new plane + * @formats: array of supported formats (DRM_FORMAT\_\*) + * @format_count: number of elements in @formats + * @format_modifiers: array of struct drm_format modifiers terminated by + *DRM_FORMAT_MOD_INVALID + * @type: type of plane (overlay, primary, cursor) + * @name: printf style format string for the plane name, or NULL for default name + * + * Initializes a plane object of type @type. The _plane_funcs.destroy hook + * should call drm_plane_cleanup() and kfree() the plane structure. The plane + * structure should not be allocated with devm_kzalloc(). + * + * Note: consider using drmm_universal_plane_alloc() instead of + * drm_universal_plane_init() to let the DRM managed resource infrastructure + * take care of cleanup and deallocation. + * + * Returns: + * Zero on success, error code on failure. + */ +int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane, +uint32_t possible_crtcs, +const struct drm_plane_funcs *funcs, +const uint32_t *formats, unsigned int format_count, +
[PATCH v5 17/19] drm/imx: parallel-display: use drm managed resources
Use drmm_simple_encoder_alloc() to align encoder memory lifetime with the drm device. drm_encoder_cleanup() is called automatically before the memory is freed. Signed-off-by: Philipp Zabel Acked-by: Daniel Vetter --- drivers/gpu/drm/imx/parallel-display.c | 57 +- 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/drivers/gpu/drm/imx/parallel-display.c b/drivers/gpu/drm/imx/parallel-display.c index 42b44dbf45f5..9b1ec7e73c30 100644 --- a/drivers/gpu/drm/imx/parallel-display.c +++ b/drivers/gpu/drm/imx/parallel-display.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -22,10 +23,14 @@ #include "imx-drm.h" -struct imx_parallel_display { +struct imx_parallel_display_encoder { struct drm_connector connector; struct drm_encoder encoder; struct drm_bridge bridge; + struct imx_parallel_display *pd; +}; + +struct imx_parallel_display { struct device *dev; void *edid; u32 bus_format; @@ -37,12 +42,12 @@ struct imx_parallel_display { static inline struct imx_parallel_display *con_to_imxpd(struct drm_connector *c) { - return container_of(c, struct imx_parallel_display, connector); + return container_of(c, struct imx_parallel_display_encoder, connector)->pd; } static inline struct imx_parallel_display *bridge_to_imxpd(struct drm_bridge *b) { - return container_of(b, struct imx_parallel_display, bridge); + return container_of(b, struct imx_parallel_display_encoder, bridge)->pd; } static int imx_pd_connector_get_modes(struct drm_connector *connector) @@ -253,17 +258,25 @@ static const struct drm_bridge_funcs imx_pd_bridge_funcs = { .atomic_get_output_bus_fmts = imx_pd_bridge_atomic_get_output_bus_fmts, }; -static int imx_pd_register(struct drm_device *drm, - struct imx_parallel_display *imxpd) +static int imx_pd_bind(struct device *dev, struct device *master, void *data) { - struct drm_connector *connector = >connector; - struct drm_encoder *encoder = >encoder; - struct drm_bridge *bridge = >bridge; + struct drm_device *drm = data; + struct imx_parallel_display *imxpd = dev_get_drvdata(dev); + struct imx_parallel_display_encoder *imxpd_encoder; + struct drm_connector *connector; + struct drm_encoder *encoder; + struct drm_bridge *bridge; int ret; - memset(connector, 0, sizeof(*connector)); - memset(encoder, 0, sizeof(*encoder)); - memset(bridge, 0, sizeof(*bridge)); + imxpd_encoder = drmm_simple_encoder_alloc(drm, struct imx_parallel_display_encoder, + encoder, DRM_MODE_ENCODER_NONE); + if (IS_ERR(imxpd_encoder)) + return PTR_ERR(imxpd_encoder); + + imxpd_encoder->pd = imxpd; + connector = _encoder->connector; + encoder = _encoder->encoder; + bridge = _encoder->bridge; ret = imx_drm_encoder_parse_of(drm, encoder, imxpd->dev->of_node); if (ret) @@ -276,18 +289,9 @@ static int imx_pd_register(struct drm_device *drm, */ connector->dpms = DRM_MODE_DPMS_OFF; - drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_NONE); - bridge->funcs = _pd_bridge_funcs; drm_bridge_attach(encoder, bridge, NULL, 0); - if (!imxpd->next_bridge) { - drm_connector_helper_add(connector, -_pd_connector_helper_funcs); - drm_connector_init(drm, connector, _pd_connector_funcs, - DRM_MODE_CONNECTOR_DPI); - } - if (imxpd->next_bridge) { ret = drm_bridge_attach(encoder, imxpd->next_bridge, bridge, 0); if (ret < 0) { @@ -296,20 +300,17 @@ static int imx_pd_register(struct drm_device *drm, return ret; } } else { + drm_connector_helper_add(connector, +_pd_connector_helper_funcs); + drm_connector_init(drm, connector, _pd_connector_funcs, + DRM_MODE_CONNECTOR_DPI); + drm_connector_attach_encoder(connector, encoder); } return 0; } -static int imx_pd_bind(struct device *dev, struct device *master, void *data) -{ - struct drm_device *drm = data; - struct imx_parallel_display *imxpd = dev_get_drvdata(dev); - - return imx_pd_register(drm, imxpd); -} - static const struct component_ops imx_pd_ops = { .bind = imx_pd_bind, }; -- 2.20.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v5 16/19] drm/imx: imx-tve: use drm managed resources
Use drmm_simple_encoder_alloc() to align encoder memory lifetime with the drm device. drm_encoder_cleanup() is called automatically before the memory is freed. Also fold imx_tve_register() into imx_tve_bind(). Signed-off-by: Philipp Zabel Acked-by: Daniel Vetter --- drivers/gpu/drm/imx/imx-tve.c | 74 ++- 1 file changed, 39 insertions(+), 35 deletions(-) diff --git a/drivers/gpu/drm/imx/imx-tve.c b/drivers/gpu/drm/imx/imx-tve.c index 3ef71f688f79..bc8c3f802a15 100644 --- a/drivers/gpu/drm/imx/imx-tve.c +++ b/drivers/gpu/drm/imx/imx-tve.c @@ -19,6 +19,7 @@ #include #include +#include #include #include @@ -99,9 +100,13 @@ enum { TVE_MODE_VGA, }; -struct imx_tve { +struct imx_tve_encoder { struct drm_connector connector; struct drm_encoder encoder; + struct imx_tve *tve; +}; + +struct imx_tve { struct device *dev; int mode; int di_hsync_pin; @@ -118,12 +123,12 @@ struct imx_tve { static inline struct imx_tve *con_to_tve(struct drm_connector *c) { - return container_of(c, struct imx_tve, connector); + return container_of(c, struct imx_tve_encoder, connector)->tve; } static inline struct imx_tve *enc_to_tve(struct drm_encoder *e) { - return container_of(e, struct imx_tve, encoder); + return container_of(e, struct imx_tve_encoder, encoder)->tve; } static void tve_enable(struct imx_tve *tve) @@ -428,37 +433,6 @@ static int tve_clk_init(struct imx_tve *tve, void __iomem *base) return 0; } -static int imx_tve_register(struct drm_device *drm, struct imx_tve *tve) -{ - struct drm_encoder *encoder = >encoder; - struct drm_connector *connector = >connector; - int encoder_type; - int ret; - - encoder_type = tve->mode == TVE_MODE_VGA ? - DRM_MODE_ENCODER_DAC : DRM_MODE_ENCODER_TVDAC; - - memset(connector, 0, sizeof(*connector)); - memset(encoder, 0, sizeof(*encoder)); - - ret = imx_drm_encoder_parse_of(drm, encoder, tve->dev->of_node); - if (ret) - return ret; - - drm_encoder_helper_add(encoder, _tve_encoder_helper_funcs); - drm_simple_encoder_init(drm, encoder, encoder_type); - - drm_connector_helper_add(connector, _tve_connector_helper_funcs); - drm_connector_init_with_ddc(drm, connector, - _tve_connector_funcs, - DRM_MODE_CONNECTOR_VGA, - tve->ddc); - - drm_connector_attach_encoder(connector, encoder); - - return 0; -} - static void imx_tve_disable_regulator(void *data) { struct imx_tve *tve = data; @@ -508,8 +482,38 @@ static int imx_tve_bind(struct device *dev, struct device *master, void *data) { struct drm_device *drm = data; struct imx_tve *tve = dev_get_drvdata(dev); + struct imx_tve_encoder *tvee; + struct drm_encoder *encoder; + struct drm_connector *connector; + int encoder_type; + int ret; + + encoder_type = tve->mode == TVE_MODE_VGA ? + DRM_MODE_ENCODER_DAC : DRM_MODE_ENCODER_TVDAC; + + tvee = drmm_simple_encoder_alloc(drm, struct imx_tve_encoder, encoder, +encoder_type); + if (IS_ERR(tvee)) + return PTR_ERR(tvee); + + tvee->tve = tve; + encoder = >encoder; + connector = >connector; + + ret = imx_drm_encoder_parse_of(drm, encoder, tve->dev->of_node); + if (ret) + return ret; + + drm_encoder_helper_add(encoder, _tve_encoder_helper_funcs); + + drm_connector_helper_add(connector, _tve_connector_helper_funcs); + ret = drm_connector_init_with_ddc(drm, connector, + _tve_connector_funcs, + DRM_MODE_CONNECTOR_VGA, tve->ddc); + if (ret) + return ret; - return imx_tve_register(drm, tve); + return drm_connector_attach_encoder(connector, encoder); } static const struct component_ops imx_tve_ops = { -- 2.20.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v5 09/19] drm/imx: imx-tve: use local encoder and connector variables
Introduce local variables for encoder and connector. This simplifies the following commits. Signed-off-by: Philipp Zabel Acked-by: Daniel Vetter --- drivers/gpu/drm/imx/imx-tve.c | 15 --- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/imx/imx-tve.c b/drivers/gpu/drm/imx/imx-tve.c index 2a8d2e32e7b4..37771073a525 100644 --- a/drivers/gpu/drm/imx/imx-tve.c +++ b/drivers/gpu/drm/imx/imx-tve.c @@ -430,27 +430,28 @@ static int tve_clk_init(struct imx_tve *tve, void __iomem *base) static int imx_tve_register(struct drm_device *drm, struct imx_tve *tve) { + struct drm_encoder *encoder = >encoder; + struct drm_connector *connector = >connector; int encoder_type; int ret; encoder_type = tve->mode == TVE_MODE_VGA ? DRM_MODE_ENCODER_DAC : DRM_MODE_ENCODER_TVDAC; - ret = imx_drm_encoder_parse_of(drm, >encoder, tve->dev->of_node); + ret = imx_drm_encoder_parse_of(drm, encoder, tve->dev->of_node); if (ret) return ret; - drm_encoder_helper_add(>encoder, _tve_encoder_helper_funcs); - drm_simple_encoder_init(drm, >encoder, encoder_type); + drm_encoder_helper_add(encoder, _tve_encoder_helper_funcs); + drm_simple_encoder_init(drm, encoder, encoder_type); - drm_connector_helper_add(>connector, - _tve_connector_helper_funcs); - drm_connector_init_with_ddc(drm, >connector, + drm_connector_helper_add(connector, _tve_connector_helper_funcs); + drm_connector_init_with_ddc(drm, connector, _tve_connector_funcs, DRM_MODE_CONNECTOR_VGA, tve->ddc); - drm_connector_attach_encoder(>connector, >encoder); + drm_connector_attach_encoder(connector, encoder); return 0; } -- 2.20.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v5 11/19] drm/imx: imx-tve: use devm_clk_register
Avoid leaking the clock provider when the driver is unbound. Signed-off-by: Philipp Zabel Acked-by: Daniel Vetter --- drivers/gpu/drm/imx/imx-tve.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/imx/imx-tve.c b/drivers/gpu/drm/imx/imx-tve.c index 649e2f56a5da..3ef71f688f79 100644 --- a/drivers/gpu/drm/imx/imx-tve.c +++ b/drivers/gpu/drm/imx/imx-tve.c @@ -418,7 +418,7 @@ static int tve_clk_init(struct imx_tve *tve, void __iomem *base) init.parent_names = (const char **)_di_parent; tve->clk_hw_di.init = - tve->di_clk = clk_register(tve->dev, >clk_hw_di); + tve->di_clk = devm_clk_register(tve->dev, >clk_hw_di); if (IS_ERR(tve->di_clk)) { dev_err(tve->dev, "failed to register TVE output clock: %ld\n", PTR_ERR(tve->di_clk)); -- 2.20.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v5 05/19] drm/crtc: add drmm_crtc_alloc_with_planes()
Add an alternative to drm_crtc_init_with_planes() that allocates and initializes a crtc and registers drm_crtc_cleanup() with drmm_add_action_or_reset(). Signed-off-by: Philipp Zabel Reviewed-by: Laurent Pinchart Reviewed-by: Daniel Vetter --- Changes since v4: - Mention that crtc_funcs.destroy should call drm_crtc_cleanup() kfree() the crtc structure, and that it should not be allocated with devm_kzalloc(), - point out drmm_crtc_alloc_with_planes() in the drm_crtc_alloc_with_planes() documentation. - WARN_ON(!funcs->destroy) in drm_crtc_init_with_planes(). - WARN_ON(!funcs || funcs->destroy) in drmm_crtc_alloc_with_planes(). --- drivers/gpu/drm/drm_crtc.c | 125 - include/drm/drm_crtc.h | 33 ++ 2 files changed, 130 insertions(+), 28 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index f927976eca50..85a76a65636a 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -240,30 +241,12 @@ struct dma_fence *drm_crtc_create_fence(struct drm_crtc *crtc) * */ -/** - * drm_crtc_init_with_planes - Initialise a new CRTC object with - *specified primary and cursor planes. - * @dev: DRM device - * @crtc: CRTC object to init - * @primary: Primary plane for CRTC - * @cursor: Cursor plane for CRTC - * @funcs: callbacks for the new CRTC - * @name: printf style format string for the CRTC name, or NULL for default name - * - * Inits a new object created as base part of a driver crtc object. Drivers - * should use this function instead of drm_crtc_init(), which is only provided - * for backwards compatibility with drivers which do not yet support universal - * planes). For really simple hardware which has only 1 plane look at - * drm_simple_display_pipe_init() instead. - * - * Returns: - * Zero on success, error code on failure. - */ -int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc, - struct drm_plane *primary, - struct drm_plane *cursor, - const struct drm_crtc_funcs *funcs, - const char *name, ...) +__printf(6, 0) +static int __drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc, + struct drm_plane *primary, + struct drm_plane *cursor, + const struct drm_crtc_funcs *funcs, + const char *name, va_list ap) { struct drm_mode_config *config = >mode_config; int ret; @@ -291,11 +274,7 @@ int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc, return ret; if (name) { - va_list ap; - - va_start(ap, name); crtc->name = kvasprintf(GFP_KERNEL, name, ap); - va_end(ap); } else { crtc->name = kasprintf(GFP_KERNEL, "crtc-%d", drm_num_crtcs(dev)); @@ -339,8 +318,98 @@ int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc, return 0; } + +/** + * drm_crtc_init_with_planes - Initialise a new CRTC object with + *specified primary and cursor planes. + * @dev: DRM device + * @crtc: CRTC object to init + * @primary: Primary plane for CRTC + * @cursor: Cursor plane for CRTC + * @funcs: callbacks for the new CRTC + * @name: printf style format string for the CRTC name, or NULL for default name + * + * Inits a new object created as base part of a driver crtc object. Drivers + * should use this function instead of drm_crtc_init(), which is only provided + * for backwards compatibility with drivers which do not yet support universal + * planes). For really simple hardware which has only 1 plane look at + * drm_simple_display_pipe_init() instead. + * The _crtc_funcs.destroy hook should call drm_crtc_cleanup() and kfree() + * the crtc structure. The crtc structure should not be allocated with + * devm_kzalloc(). + * + * Note: consider using drmm_crtc_alloc_with_planes() instead of + * drm_crtc_init_with_planes() to let the DRM managed resource infrastructure + * take care of cleanup and deallocation. + * + * Returns: + * Zero on success, error code on failure. + */ +int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc, + struct drm_plane *primary, + struct drm_plane *cursor, + const struct drm_crtc_funcs *funcs, + const char *name, ...) +{ + va_list ap; + int ret; + + WARN_ON(!funcs->destroy); + + va_start(ap, name); + ret = __drm_crtc_init_with_planes(dev, crtc, primary, cursor, funcs, + name, ap); +
[PATCH v5 12/19] drm/imx: parallel-display: use local bridge and connector variables
Use local variables for bridge and connector. This simplifies the following commits. Signed-off-by: Philipp Zabel Acked-by: Daniel Vetter --- drivers/gpu/drm/imx/parallel-display.c | 20 ++-- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/imx/parallel-display.c b/drivers/gpu/drm/imx/parallel-display.c index 2eb8df4697df..16e576f8ee83 100644 --- a/drivers/gpu/drm/imx/parallel-display.c +++ b/drivers/gpu/drm/imx/parallel-display.c @@ -256,7 +256,9 @@ static const struct drm_bridge_funcs imx_pd_bridge_funcs = { static int imx_pd_register(struct drm_device *drm, struct imx_parallel_display *imxpd) { + struct drm_connector *connector = >connector; struct drm_encoder *encoder = >encoder; + struct drm_bridge *bridge = >bridge; int ret; ret = imx_drm_encoder_parse_of(drm, encoder, imxpd->dev->of_node); @@ -268,31 +270,29 @@ static int imx_pd_register(struct drm_device *drm, * immediately since the current state is ON * at this point. */ - imxpd->connector.dpms = DRM_MODE_DPMS_OFF; + connector->dpms = DRM_MODE_DPMS_OFF; drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_NONE); - imxpd->bridge.funcs = _pd_bridge_funcs; - drm_bridge_attach(encoder, >bridge, NULL, 0); + bridge->funcs = _pd_bridge_funcs; + drm_bridge_attach(encoder, bridge, NULL, 0); if (!imxpd->next_bridge) { - drm_connector_helper_add(>connector, - _pd_connector_helper_funcs); - drm_connector_init(drm, >connector, - _pd_connector_funcs, + drm_connector_helper_add(connector, +_pd_connector_helper_funcs); + drm_connector_init(drm, connector, _pd_connector_funcs, DRM_MODE_CONNECTOR_DPI); } if (imxpd->next_bridge) { - ret = drm_bridge_attach(encoder, imxpd->next_bridge, - >bridge, 0); + ret = drm_bridge_attach(encoder, imxpd->next_bridge, bridge, 0); if (ret < 0) { dev_err(imxpd->dev, "failed to attach bridge: %d\n", ret); return ret; } } else { - drm_connector_attach_encoder(>connector, encoder); + drm_connector_attach_encoder(connector, encoder); } return 0; -- 2.20.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v5 02/19] drm: add drmm_encoder_alloc()
Add an alternative to drm_encoder_init() that allocates and initializes an encoder and registers drm_encoder_cleanup() with drmm_add_action_or_reset(). Signed-off-by: Philipp Zabel Reviewed-by: Laurent Pinchart Reviewed-by: Daniel Vetter --- Changes since v4: - mention that encoder_funcs.destroy should kfree() the encoder structure, that it should not be allocated with devm_kzalloc(). - point out drmm_encoder_alloc in drm_encoder_init() documentation. - WARN_ON(!funcs->destroy) in drm_encoder_init(). - mark funcs parameter as optional in drmm_encoder_alloc() documentation. --- drivers/gpu/drm/drm_encoder.c | 109 +++--- include/drm/drm_encoder.h | 30 ++ 2 files changed, 116 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/drm_encoder.c b/drivers/gpu/drm/drm_encoder.c index b0b86a3c08f5..72e982323a5e 100644 --- a/drivers/gpu/drm/drm_encoder.c +++ b/drivers/gpu/drm/drm_encoder.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "drm_crtc_internal.h" @@ -91,25 +92,11 @@ void drm_encoder_unregister_all(struct drm_device *dev) } } -/** - * drm_encoder_init - Init a preallocated encoder - * @dev: drm device - * @encoder: the encoder to init - * @funcs: callbacks for this encoder - * @encoder_type: user visible type of the encoder - * @name: printf style format string for the encoder name, or NULL for default name - * - * Initialises a preallocated encoder. Encoder should be subclassed as part of - * driver encoder objects. At driver unload time drm_encoder_cleanup() should be - * called from the driver's _encoder_funcs.destroy hook. - * - * Returns: - * Zero on success, error code on failure. - */ -int drm_encoder_init(struct drm_device *dev, -struct drm_encoder *encoder, -const struct drm_encoder_funcs *funcs, -int encoder_type, const char *name, ...) +__printf(5, 0) +static int __drm_encoder_init(struct drm_device *dev, + struct drm_encoder *encoder, + const struct drm_encoder_funcs *funcs, + int encoder_type, const char *name, va_list ap) { int ret; @@ -125,11 +112,7 @@ int drm_encoder_init(struct drm_device *dev, encoder->encoder_type = encoder_type; encoder->funcs = funcs; if (name) { - va_list ap; - - va_start(ap, name); encoder->name = kvasprintf(GFP_KERNEL, name, ap); - va_end(ap); } else { encoder->name = kasprintf(GFP_KERNEL, "%s-%d", drm_encoder_enum_list[encoder_type].name, @@ -150,6 +133,44 @@ int drm_encoder_init(struct drm_device *dev, return ret; } + +/** + * drm_encoder_init - Init a preallocated encoder + * @dev: drm device + * @encoder: the encoder to init + * @funcs: callbacks for this encoder + * @encoder_type: user visible type of the encoder + * @name: printf style format string for the encoder name, or NULL for default name + * + * Initializes a preallocated encoder. Encoder should be subclassed as part of + * driver encoder objects. At driver unload time the driver's + * _encoder_funcs.destroy hook should call drm_encoder_cleanup() and kfree() + * the encoder structure. The encoder structure should not be allocated with + * devm_kzalloc(). + * + * Note: consider using drmm_encoder_alloc() instead of drm_encoder_init() to + * let the DRM managed resource infrastructure take care of cleanup and + * deallocation. + * + * Returns: + * Zero on success, error code on failure. + */ +int drm_encoder_init(struct drm_device *dev, +struct drm_encoder *encoder, +const struct drm_encoder_funcs *funcs, +int encoder_type, const char *name, ...) +{ + va_list ap; + int ret; + + WARN_ON(!funcs->destroy); + + va_start(ap, name); + ret = __drm_encoder_init(dev, encoder, funcs, encoder_type, name, ap); + va_end(ap); + + return ret; +} EXPORT_SYMBOL(drm_encoder_init); /** @@ -181,6 +202,48 @@ void drm_encoder_cleanup(struct drm_encoder *encoder) } EXPORT_SYMBOL(drm_encoder_cleanup); +static void drmm_encoder_alloc_release(struct drm_device *dev, void *ptr) +{ + struct drm_encoder *encoder = ptr; + + if (WARN_ON(!encoder->dev)) + return; + + drm_encoder_cleanup(encoder); +} + +void *__drmm_encoder_alloc(struct drm_device *dev, size_t size, size_t offset, + const struct drm_encoder_funcs *funcs, + int encoder_type, const char *name, ...) +{ + void *container; + struct drm_encoder *encoder; + va_list ap; + int ret; + + if (WARN_ON(funcs && funcs->destroy)) + return ERR_PTR(-EINVAL); + + container = drmm_kzalloc(dev, size, GFP_KERNEL); + if
[PATCH v5 14/19] drm/imx: dw_hdmi-imx: use drm managed resources
Use drmm_simple_encoder_alloc() to align encoder memory lifetime with the drm device. drm_encoder_cleanup() is called automatically. Signed-off-by: Philipp Zabel Acked-by: Daniel Vetter --- drivers/gpu/drm/imx/dw_hdmi-imx.c | 25 + 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/imx/dw_hdmi-imx.c b/drivers/gpu/drm/imx/dw_hdmi-imx.c index bbd0a0cd7c3d..87428fb23d9f 100644 --- a/drivers/gpu/drm/imx/dw_hdmi-imx.c +++ b/drivers/gpu/drm/imx/dw_hdmi-imx.c @@ -18,14 +18,21 @@ #include #include #include +#include #include #include #include "imx-drm.h" +struct imx_hdmi; + +struct imx_hdmi_encoder { + struct drm_encoder encoder; + struct imx_hdmi *hdmi; +}; + struct imx_hdmi { struct device *dev; - struct drm_encoder encoder; struct drm_bridge *bridge; struct dw_hdmi *hdmi; struct regmap *regmap; @@ -33,7 +40,7 @@ struct imx_hdmi { static inline struct imx_hdmi *enc_to_imx_hdmi(struct drm_encoder *e) { - return container_of(e, struct imx_hdmi, encoder); + return container_of(e, struct imx_hdmi_encoder, encoder)->hdmi; } static const struct dw_hdmi_mpll_config imx_mpll_cfg[] = { @@ -185,23 +192,25 @@ static int dw_hdmi_imx_bind(struct device *dev, struct device *master, void *data) { struct drm_device *drm = data; + struct imx_hdmi_encoder *hdmi_encoder; struct drm_encoder *encoder; - struct imx_hdmi *hdmi; int ret; - hdmi = dev_get_drvdata(dev); - memset(>encoder, 0, sizeof(hdmi->encoder)); + hdmi_encoder = drmm_simple_encoder_alloc(drm, struct imx_hdmi_encoder, +encoder, DRM_MODE_ENCODER_TMDS); + if (IS_ERR(hdmi_encoder)) + return PTR_ERR(hdmi_encoder); - encoder = >encoder; + hdmi_encoder->hdmi = dev_get_drvdata(dev); + encoder = _encoder->encoder; ret = imx_drm_encoder_parse_of(drm, encoder, dev->of_node); if (ret) return ret; drm_encoder_helper_add(encoder, _hdmi_imx_encoder_helper_funcs); - drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS); - return drm_bridge_attach(encoder, hdmi->bridge, NULL, 0); + return drm_bridge_attach(encoder, hdmi_encoder->hdmi->bridge, NULL, 0); } static const struct component_ops dw_hdmi_imx_ops = { -- 2.20.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v5 19/19] drm/imx: ipuv3-crtc: use drm managed resources
Use use drmm_crtc_alloc_with_planes() to align crtc memory lifetime with the drm device. drm_crtc_cleanup() is called automatically before the memory is freed. Also use drmm_add_action_or_reset() to make sure IPU resources are released automatically. Signed-off-by: Philipp Zabel Acked-by: Daniel Vetter --- drivers/gpu/drm/imx/ipuv3-crtc.c | 114 --- 1 file changed, 43 insertions(+), 71 deletions(-) diff --git a/drivers/gpu/drm/imx/ipuv3-crtc.c b/drivers/gpu/drm/imx/ipuv3-crtc.c index 6ce8fa4348c9..e6431a227feb 100644 --- a/drivers/gpu/drm/imx/ipuv3-crtc.c +++ b/drivers/gpu/drm/imx/ipuv3-crtc.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -163,7 +164,6 @@ static void ipu_disable_vblank(struct drm_crtc *crtc) static const struct drm_crtc_funcs ipu_crtc_funcs = { .set_config = drm_atomic_helper_set_config, - .destroy = drm_crtc_cleanup, .page_flip = drm_atomic_helper_page_flip, .reset = imx_drm_crtc_reset, .atomic_duplicate_state = imx_drm_crtc_duplicate_state, @@ -322,67 +322,74 @@ static const struct drm_crtc_helper_funcs ipu_helper_funcs = { .atomic_enable = ipu_crtc_atomic_enable, }; -static void ipu_put_resources(struct ipu_crtc *ipu_crtc) +static void ipu_put_resources(struct drm_device *dev, void *ptr) { + struct ipu_crtc *ipu_crtc = ptr; + if (!IS_ERR_OR_NULL(ipu_crtc->dc)) ipu_dc_put(ipu_crtc->dc); if (!IS_ERR_OR_NULL(ipu_crtc->di)) ipu_di_put(ipu_crtc->di); } -static int ipu_get_resources(struct ipu_crtc *ipu_crtc, - struct ipu_client_platformdata *pdata) +static int ipu_get_resources(struct drm_device *dev, struct ipu_crtc *ipu_crtc, +struct ipu_client_platformdata *pdata) { struct ipu_soc *ipu = dev_get_drvdata(ipu_crtc->dev->parent); int ret; ipu_crtc->dc = ipu_dc_get(ipu, pdata->dc); - if (IS_ERR(ipu_crtc->dc)) { - ret = PTR_ERR(ipu_crtc->dc); - goto err_out; - } + if (IS_ERR(ipu_crtc->dc)) + return PTR_ERR(ipu_crtc->dc); + + ret = drmm_add_action_or_reset(dev, ipu_put_resources, ipu_crtc); + if (ret) + return ret; ipu_crtc->di = ipu_di_get(ipu, pdata->di); - if (IS_ERR(ipu_crtc->di)) { - ret = PTR_ERR(ipu_crtc->di); - goto err_out; - } + if (IS_ERR(ipu_crtc->di)) + return PTR_ERR(ipu_crtc->di); return 0; -err_out: - ipu_put_resources(ipu_crtc); - - return ret; } -static int ipu_crtc_init(struct ipu_crtc *ipu_crtc, - struct ipu_client_platformdata *pdata, struct drm_device *drm) +static int ipu_drm_bind(struct device *dev, struct device *master, void *data) { - struct ipu_soc *ipu = dev_get_drvdata(ipu_crtc->dev->parent); - struct drm_crtc *crtc = _crtc->base; + struct ipu_client_platformdata *pdata = dev->platform_data; + struct ipu_soc *ipu = dev_get_drvdata(dev->parent); + struct drm_device *drm = data; + struct ipu_plane *primary_plane; + struct ipu_crtc *ipu_crtc; + struct drm_crtc *crtc; int dp = -EINVAL; int ret; - ret = ipu_get_resources(ipu_crtc, pdata); - if (ret) { - dev_err(ipu_crtc->dev, "getting resources failed with %d.\n", - ret); - return ret; - } - if (pdata->dp >= 0) dp = IPU_DP_FLOW_SYNC_BG; - ipu_crtc->plane[0] = ipu_plane_init(drm, ipu, pdata->dma[0], dp, 0, - DRM_PLANE_TYPE_PRIMARY); - if (IS_ERR(ipu_crtc->plane[0])) { - ret = PTR_ERR(ipu_crtc->plane[0]); - goto err_put_resources; - } + primary_plane = ipu_plane_init(drm, ipu, pdata->dma[0], dp, 0, + DRM_PLANE_TYPE_PRIMARY); + if (IS_ERR(primary_plane)) + return PTR_ERR(primary_plane); + + ipu_crtc = drmm_crtc_alloc_with_planes(drm, struct ipu_crtc, base, + _plane->base, NULL, + _crtc_funcs, NULL); + if (IS_ERR(ipu_crtc)) + return PTR_ERR(ipu_crtc); + + ipu_crtc->dev = dev; + ipu_crtc->plane[0] = primary_plane; + crtc = _crtc->base; crtc->port = pdata->of_node; drm_crtc_helper_add(crtc, _helper_funcs); - drm_crtc_init_with_planes(drm, crtc, _crtc->plane[0]->base, NULL, - _crtc_funcs, NULL); + + ret = ipu_get_resources(drm, ipu_crtc, pdata); + if (ret) { + dev_err(ipu_crtc->dev, "getting resources failed with %d.\n", + ret); + return ret; + } /* If this crtc is using the DP, add an overlay plane */ if
[PATCH v5 07/19] drm/imx: imx-ldb: use local connector variable
Use a local variable for the connector. This simplifies the following commits. Signed-off-by: Philipp Zabel Acked-by: Daniel Vetter --- drivers/gpu/drm/imx/imx-ldb.c | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c index 41e2978cb1eb..288a81f134fe 100644 --- a/drivers/gpu/drm/imx/imx-ldb.c +++ b/drivers/gpu/drm/imx/imx-ldb.c @@ -411,6 +411,7 @@ static int imx_ldb_register(struct drm_device *drm, struct imx_ldb_channel *imx_ldb_ch) { struct imx_ldb *ldb = imx_ldb_ch->ldb; + struct drm_connector *connector = _ldb_ch->connector; struct drm_encoder *encoder = _ldb_ch->encoder; int ret; @@ -432,8 +433,7 @@ static int imx_ldb_register(struct drm_device *drm, drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_LVDS); if (imx_ldb_ch->bridge) { - ret = drm_bridge_attach(_ldb_ch->encoder, - imx_ldb_ch->bridge, NULL, 0); + ret = drm_bridge_attach(encoder, imx_ldb_ch->bridge, NULL, 0); if (ret) { DRM_ERROR("Failed to initialize bridge with drm\n"); return ret; @@ -445,13 +445,13 @@ static int imx_ldb_register(struct drm_device *drm, * historical reasons, the ldb driver can also work without * a panel. */ - drm_connector_helper_add(_ldb_ch->connector, - _ldb_connector_helper_funcs); - drm_connector_init_with_ddc(drm, _ldb_ch->connector, + drm_connector_helper_add(connector, +_ldb_connector_helper_funcs); + drm_connector_init_with_ddc(drm, connector, _ldb_connector_funcs, DRM_MODE_CONNECTOR_LVDS, imx_ldb_ch->ddc); - drm_connector_attach_encoder(_ldb_ch->connector, encoder); + drm_connector_attach_encoder(connector, encoder); } return 0; -- 2.20.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v5 15/19] drm/imx: imx-ldb: use drm managed resources
Use drmm_simple_encoder_alloc() to align encoder memory lifetime with the drm device. drm_encoder_cleanup() is called automatically before the memory is freed. Signed-off-by: Philipp Zabel Acked-by: Daniel Vetter --- drivers/gpu/drm/imx/imx-ldb.c | 31 ++- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c index c3639cc32ddf..dbfe39e2f7f6 100644 --- a/drivers/gpu/drm/imx/imx-ldb.c +++ b/drivers/gpu/drm/imx/imx-ldb.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -47,12 +48,18 @@ #define LDB_DI1_VS_POL_ACT_LOW (1 << 10) #define LDB_BGREF_RMODE_INT(1 << 15) +struct imx_ldb_channel; + +struct imx_ldb_encoder { + struct drm_connector connector; + struct drm_encoder encoder; + struct imx_ldb_channel *channel; +}; + struct imx_ldb; struct imx_ldb_channel { struct imx_ldb *ldb; - struct drm_connector connector; - struct drm_encoder encoder; /* Defines what is connected to the ldb, only one at a time */ struct drm_panel *panel; @@ -70,12 +77,12 @@ struct imx_ldb_channel { static inline struct imx_ldb_channel *con_to_imx_ldb_ch(struct drm_connector *c) { - return container_of(c, struct imx_ldb_channel, connector); + return container_of(c, struct imx_ldb_encoder, connector)->channel; } static inline struct imx_ldb_channel *enc_to_imx_ldb_ch(struct drm_encoder *e) { - return container_of(e, struct imx_ldb_channel, encoder); + return container_of(e, struct imx_ldb_encoder, encoder)->channel; } struct bus_mux { @@ -411,12 +418,19 @@ static int imx_ldb_register(struct drm_device *drm, struct imx_ldb_channel *imx_ldb_ch) { struct imx_ldb *ldb = imx_ldb_ch->ldb; - struct drm_connector *connector = _ldb_ch->connector; - struct drm_encoder *encoder = _ldb_ch->encoder; + struct imx_ldb_encoder *ldb_encoder; + struct drm_connector *connector; + struct drm_encoder *encoder; int ret; - memset(connector, 0, sizeof(*connector)); - memset(encoder, 0, sizeof(*encoder)); + ldb_encoder = drmm_simple_encoder_alloc(drm, struct imx_ldb_encoder, + encoder, DRM_MODE_ENCODER_LVDS); + if (IS_ERR(ldb_encoder)) + return PTR_ERR(ldb_encoder); + + ldb_encoder->channel = imx_ldb_ch; + connector = _encoder->connector; + encoder = _encoder->encoder; ret = imx_drm_encoder_parse_of(drm, encoder, imx_ldb_ch->child); if (ret) @@ -433,7 +447,6 @@ static int imx_ldb_register(struct drm_device *drm, } drm_encoder_helper_add(encoder, _ldb_encoder_helper_funcs); - drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_LVDS); if (imx_ldb_ch->bridge) { ret = drm_bridge_attach(encoder, imx_ldb_ch->bridge, NULL, 0); -- 2.20.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v5 06/19] drm/imx: dw_hdmi-imx: move initialization into probe
Parts of the initialization that do not require the drm device can be done once during probe instead of possibly multiple times during bind. The bind function only creates the encoder and attaches the bridge. Signed-off-by: Philipp Zabel Acked-by: Daniel Vetter --- drivers/gpu/drm/imx/dw_hdmi-imx.c | 74 +++ 1 file changed, 26 insertions(+), 48 deletions(-) diff --git a/drivers/gpu/drm/imx/dw_hdmi-imx.c b/drivers/gpu/drm/imx/dw_hdmi-imx.c index d07b39b8afd2..bbd0a0cd7c3d 100644 --- a/drivers/gpu/drm/imx/dw_hdmi-imx.c +++ b/drivers/gpu/drm/imx/dw_hdmi-imx.c @@ -15,6 +15,7 @@ #include #include +#include #include #include #include @@ -25,6 +26,7 @@ struct imx_hdmi { struct device *dev; struct drm_encoder encoder; + struct drm_bridge *bridge; struct dw_hdmi *hdmi; struct regmap *regmap; }; @@ -98,19 +100,6 @@ static const struct dw_hdmi_phy_config imx_phy_config[] = { { ~0UL, 0x, 0x, 0x} }; -static int dw_hdmi_imx_parse_dt(struct imx_hdmi *hdmi) -{ - struct device_node *np = hdmi->dev->of_node; - - hdmi->regmap = syscon_regmap_lookup_by_phandle(np, "gpr"); - if (IS_ERR(hdmi->regmap)) { - dev_err(hdmi->dev, "Unable to get gpr\n"); - return PTR_ERR(hdmi->regmap); - } - - return 0; -} - static void dw_hdmi_imx_encoder_enable(struct drm_encoder *encoder) { struct imx_hdmi *hdmi = enc_to_imx_hdmi(encoder); @@ -195,65 +184,34 @@ MODULE_DEVICE_TABLE(of, dw_hdmi_imx_dt_ids); static int dw_hdmi_imx_bind(struct device *dev, struct device *master, void *data) { - struct platform_device *pdev = to_platform_device(dev); - const struct dw_hdmi_plat_data *plat_data; - const struct of_device_id *match; struct drm_device *drm = data; struct drm_encoder *encoder; struct imx_hdmi *hdmi; int ret; - if (!pdev->dev.of_node) - return -ENODEV; - hdmi = dev_get_drvdata(dev); - memset(hdmi, 0, sizeof(*hdmi)); + memset(>encoder, 0, sizeof(hdmi->encoder)); - match = of_match_node(dw_hdmi_imx_dt_ids, pdev->dev.of_node); - plat_data = match->data; - hdmi->dev = >dev; encoder = >encoder; ret = imx_drm_encoder_parse_of(drm, encoder, dev->of_node); if (ret) return ret; - ret = dw_hdmi_imx_parse_dt(hdmi); - if (ret < 0) - return ret; - drm_encoder_helper_add(encoder, _hdmi_imx_encoder_helper_funcs); drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS); - hdmi->hdmi = dw_hdmi_bind(pdev, encoder, plat_data); - - /* -* If dw_hdmi_bind() fails we'll never call dw_hdmi_unbind(), -* which would have called the encoder cleanup. Do it manually. -*/ - if (IS_ERR(hdmi->hdmi)) { - ret = PTR_ERR(hdmi->hdmi); - drm_encoder_cleanup(encoder); - } - - return ret; -} - -static void dw_hdmi_imx_unbind(struct device *dev, struct device *master, - void *data) -{ - struct imx_hdmi *hdmi = dev_get_drvdata(dev); - - dw_hdmi_unbind(hdmi->hdmi); + return drm_bridge_attach(encoder, hdmi->bridge, NULL, 0); } static const struct component_ops dw_hdmi_imx_ops = { .bind = dw_hdmi_imx_bind, - .unbind = dw_hdmi_imx_unbind, }; static int dw_hdmi_imx_probe(struct platform_device *pdev) { + struct device_node *np = pdev->dev.of_node; + const struct of_device_id *match = of_match_node(dw_hdmi_imx_dt_ids, np); struct imx_hdmi *hdmi; hdmi = devm_kzalloc(>dev, sizeof(*hdmi), GFP_KERNEL); @@ -261,13 +219,33 @@ static int dw_hdmi_imx_probe(struct platform_device *pdev) return -ENOMEM; platform_set_drvdata(pdev, hdmi); + hdmi->dev = >dev; + + hdmi->regmap = syscon_regmap_lookup_by_phandle(np, "gpr"); + if (IS_ERR(hdmi->regmap)) { + dev_err(hdmi->dev, "Unable to get gpr\n"); + return PTR_ERR(hdmi->regmap); + } + + hdmi->hdmi = dw_hdmi_probe(pdev, match->data); + if (IS_ERR(hdmi->hdmi)) + return PTR_ERR(hdmi->hdmi); + + hdmi->bridge = of_drm_find_bridge(np); + if (!hdmi->bridge) { + dev_err(hdmi->dev, "Unable to find bridge\n"); + return -ENODEV; + } return component_add(>dev, _hdmi_imx_ops); } static int dw_hdmi_imx_remove(struct platform_device *pdev) { + struct imx_hdmi *hdmi = platform_get_drvdata(pdev); + component_del(>dev, _hdmi_imx_ops); + dw_hdmi_remove(hdmi->hdmi); return 0; } -- 2.20.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v5 08/19] drm/imx: imx-ldb: move initialization into probe
Parts of the initialization that do not require the drm device can be done once during probe instead of possibly multiple times during bind. The bind function only creates the encoders. Signed-off-by: Philipp Zabel Acked-by: Daniel Vetter --- drivers/gpu/drm/imx/imx-ldb.c | 72 ++- 1 file changed, 37 insertions(+), 35 deletions(-) diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c index 288a81f134fe..c3639cc32ddf 100644 --- a/drivers/gpu/drm/imx/imx-ldb.c +++ b/drivers/gpu/drm/imx/imx-ldb.c @@ -415,6 +415,9 @@ static int imx_ldb_register(struct drm_device *drm, struct drm_encoder *encoder = _ldb_ch->encoder; int ret; + memset(connector, 0, sizeof(*connector)); + memset(encoder, 0, sizeof(*encoder)); + ret = imx_drm_encoder_parse_of(drm, encoder, imx_ldb_ch->child); if (ret) return ret; @@ -559,17 +562,42 @@ static int imx_ldb_panel_ddc(struct device *dev, static int imx_ldb_bind(struct device *dev, struct device *master, void *data) { struct drm_device *drm = data; + struct imx_ldb *imx_ldb = dev_get_drvdata(dev); + int ret; + int i; + + for (i = 0; i < 2; i++) { + struct imx_ldb_channel *channel = _ldb->channel[i]; + + if (!channel->ldb) + break; + + ret = imx_ldb_register(drm, channel); + if (ret) + return ret; + } + + return 0; +} + +static const struct component_ops imx_ldb_ops = { + .bind = imx_ldb_bind, +}; + +static int imx_ldb_probe(struct platform_device *pdev) +{ + struct device *dev = >dev; struct device_node *np = dev->of_node; - const struct of_device_id *of_id = - of_match_device(imx_ldb_dt_ids, dev); + const struct of_device_id *of_id = of_match_device(imx_ldb_dt_ids, dev); struct device_node *child; struct imx_ldb *imx_ldb; int dual; int ret; int i; - imx_ldb = dev_get_drvdata(dev); - memset(imx_ldb, 0, sizeof(*imx_ldb)); + imx_ldb = devm_kzalloc(dev, sizeof(*imx_ldb), GFP_KERNEL); + if (!imx_ldb) + return -ENOMEM; imx_ldb->regmap = syscon_regmap_lookup_by_phandle(np, "gpr"); if (IS_ERR(imx_ldb->regmap)) { @@ -669,25 +697,20 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data) } channel->bus_format = bus_format; channel->child = child; - - ret = imx_ldb_register(drm, channel); - if (ret) { - channel->child = NULL; - goto free_child; - } } - return 0; + platform_set_drvdata(pdev, imx_ldb); + + return component_add(>dev, _ldb_ops); free_child: of_node_put(child); return ret; } -static void imx_ldb_unbind(struct device *dev, struct device *master, - void *data) +static int imx_ldb_remove(struct platform_device *pdev) { - struct imx_ldb *imx_ldb = dev_get_drvdata(dev); + struct imx_ldb *imx_ldb = platform_get_drvdata(pdev); int i; for (i = 0; i < 2; i++) { @@ -696,28 +719,7 @@ static void imx_ldb_unbind(struct device *dev, struct device *master, kfree(channel->edid); i2c_put_adapter(channel->ddc); } -} - -static const struct component_ops imx_ldb_ops = { - .bind = imx_ldb_bind, - .unbind = imx_ldb_unbind, -}; -static int imx_ldb_probe(struct platform_device *pdev) -{ - struct imx_ldb *imx_ldb; - - imx_ldb = devm_kzalloc(>dev, sizeof(*imx_ldb), GFP_KERNEL); - if (!imx_ldb) - return -ENOMEM; - - platform_set_drvdata(pdev, imx_ldb); - - return component_add(>dev, _ldb_ops); -} - -static int imx_ldb_remove(struct platform_device *pdev) -{ component_del(>dev, _ldb_ops); return 0; } -- 2.20.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v5 03/19] drm/simple_kms_helper: add drmm_simple_encoder_alloc()
Add an alternative to drm_simple_encoder_init() that allocates and initializes a simple encoder and registers drm_encoder_cleanup() with drmm_add_action_or_reset(). Signed-off-by: Philipp Zabel Reviewed-by: Laurent Pinchart Reviewed-by: Daniel Vetter --- Changes since v4: - address FIXME in drm_simple_encoder_init() documentation by pointing out drmm_simple_encoder_alloc() --- drivers/gpu/drm/drm_simple_kms_helper.c | 14 -- include/drm/drm_simple_kms_helper.h | 24 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_simple_kms_helper.c b/drivers/gpu/drm/drm_simple_kms_helper.c index 743e57c1b44f..6ce8f5cd1eb5 100644 --- a/drivers/gpu/drm/drm_simple_kms_helper.c +++ b/drivers/gpu/drm/drm_simple_kms_helper.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -55,8 +56,9 @@ static const struct drm_encoder_funcs drm_simple_encoder_funcs_cleanup = { * stored in the device structure. Free the encoder's memory as part of * the device release function. * - * FIXME: Later improvements to DRM's resource management may allow for - *an automated kfree() of the encoder's memory. + * Note: consider using drmm_simple_encoder_alloc() instead of + * drm_simple_encoder_init() to let the DRM managed resource infrastructure + * take care of cleanup and deallocation. * * Returns: * Zero on success, error code on failure. @@ -71,6 +73,14 @@ int drm_simple_encoder_init(struct drm_device *dev, } EXPORT_SYMBOL(drm_simple_encoder_init); +void *__drmm_simple_encoder_alloc(struct drm_device *dev, size_t size, + size_t offset, int encoder_type) +{ + return __drmm_encoder_alloc(dev, size, offset, NULL, encoder_type, + NULL); +} +EXPORT_SYMBOL(__drmm_simple_encoder_alloc); + static enum drm_mode_status drm_simple_kms_crtc_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode *mode) diff --git a/include/drm/drm_simple_kms_helper.h b/include/drm/drm_simple_kms_helper.h index a026375464ff..e6dbf3161c2f 100644 --- a/include/drm/drm_simple_kms_helper.h +++ b/include/drm/drm_simple_kms_helper.h @@ -185,4 +185,28 @@ int drm_simple_encoder_init(struct drm_device *dev, struct drm_encoder *encoder, int encoder_type); +void *__drmm_simple_encoder_alloc(struct drm_device *dev, size_t size, + size_t offset, int encoder_type); + +/** + * drmm_simple_encoder_alloc - Allocate and initialize an encoder with basic + * functionality. + * @dev: drm device + * @type: the type of the struct which contains struct _encoder + * @member: the name of the _encoder within @type. + * @encoder_type: user visible type of the encoder + * + * Allocates and initializes an encoder that has no further functionality. + * Settings for possible CRTC and clones are left to their initial values. + * Cleanup is automatically handled through registering drm_encoder_cleanup() + * with drmm_add_action(). + * + * Returns: + * Pointer to new encoder, or ERR_PTR on failure. + */ +#define drmm_simple_encoder_alloc(dev, type, member, encoder_type) \ + ((type *)__drmm_simple_encoder_alloc(dev, sizeof(type), \ +offsetof(type, member), \ +encoder_type)) + #endif /* __LINUX_DRM_SIMPLE_KMS_HELPER_H */ -- 2.20.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v5 00/19] drm: managed encoder/plane/crtc allocation
Hi, update of v4 [1] with review feedback integrated. Changes since v4: - Roll back drm_mode_config_cleanup() change, any encoders that are kept on the mode_config.encoder_list until then are still required to have funcs set. - Mention that {encoder,plane,crtc}_funcs.destroy should cleanup and kfree() the structure, and that it should not be allocated with devm_kzalloc(). - Point out drmm_encoder_alloc in the drm_encoder_init() documentation, drmm_universal_plane_alloc() in the drm_universal_plane_init() documentation, and drmm_crtc_alloc_with_planes() in the drm_crtc_alloc_with_planes() documentation. - WARN_ON(!funcs->destroy) in drm_{encoder,universal_plane}_init() and in drm_crtc_init_with_planes(). - WARN_ON(!funcs || funcs->destroy) in drmm_universal_plane_alloc() and in drmm_crtc_allow_with_planes(). - Mark funcs parameter as optional in drmm_encoder_alloc() documentation. - Address FIXME in drm_simple_encoder_init() documentation by pointing out drmm_simple_encoder_alloc(). [1] https://lore.kernel.org/dri-devel/20201208155451.8421-1-p.za...@pengutronix.de/ regards Philipp Philipp Zabel (19): drm/encoder: make encoder control functions optional drm: add drmm_encoder_alloc() drm/simple_kms_helper: add drmm_simple_encoder_alloc() drm/plane: add drmm_universal_plane_alloc() drm/crtc: add drmm_crtc_alloc_with_planes() drm/imx: dw_hdmi-imx: move initialization into probe drm/imx: imx-ldb: use local connector variable drm/imx: imx-ldb: move initialization into probe drm/imx: imx-tve: use local encoder and connector variables drm/imx: imx-tve: move initialization into probe drm/imx: imx-tve: use devm_clk_register drm/imx: parallel-display: use local bridge and connector variables drm/imx: parallel-display: move initialization into probe drm/imx: dw_hdmi-imx: use drm managed resources drm/imx: imx-ldb: use drm managed resources drm/imx: imx-tve: use drm managed resources drm/imx: parallel-display: use drm managed resources drm/imx: ipuv3-plane: use drm managed resources drm/imx: ipuv3-crtc: use drm managed resources drivers/gpu/drm/drm_crtc.c | 125 +- drivers/gpu/drm/drm_encoder.c | 113 +++- drivers/gpu/drm/drm_mode_config.c | 2 +- drivers/gpu/drm/drm_plane.c | 134 +++- drivers/gpu/drm/drm_simple_kms_helper.c | 14 ++- drivers/gpu/drm/imx/dw_hdmi-imx.c | 95 - drivers/gpu/drm/imx/imx-ldb.c | 109 ++- drivers/gpu/drm/imx/imx-tve.c | 109 +-- drivers/gpu/drm/imx/ipuv3-crtc.c| 131 +++ drivers/gpu/drm/imx/ipuv3-plane.c | 69 ++-- drivers/gpu/drm/imx/ipuv3-plane.h | 3 - drivers/gpu/drm/imx/parallel-display.c | 91 include/drm/drm_crtc.h | 33 ++ include/drm/drm_encoder.h | 32 +- include/drm/drm_plane.h | 42 include/drm/drm_simple_kms_helper.h | 24 + 16 files changed, 710 insertions(+), 416 deletions(-) -- 2.20.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v5 01/19] drm/encoder: make encoder control functions optional
Simple managed encoders do not require the .destroy callback, make the whole funcs structure optional. Signed-off-by: Philipp Zabel Reviewed-by: Laurent Pinchart Reviewed-by: Daniel Vetter --- Changes since v4: - Roll back drm_mode_config_cleanup() change, any encoders that are kept on the mode_config.encoder_list until then are still required to have funcs set. --- drivers/gpu/drm/drm_encoder.c | 4 ++-- drivers/gpu/drm/drm_mode_config.c | 2 +- include/drm/drm_encoder.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/drm_encoder.c b/drivers/gpu/drm/drm_encoder.c index e555281f43d4..b0b86a3c08f5 100644 --- a/drivers/gpu/drm/drm_encoder.c +++ b/drivers/gpu/drm/drm_encoder.c @@ -72,7 +72,7 @@ int drm_encoder_register_all(struct drm_device *dev) int ret = 0; drm_for_each_encoder(encoder, dev) { - if (encoder->funcs->late_register) + if (encoder->funcs && encoder->funcs->late_register) ret = encoder->funcs->late_register(encoder); if (ret) return ret; @@ -86,7 +86,7 @@ void drm_encoder_unregister_all(struct drm_device *dev) struct drm_encoder *encoder; drm_for_each_encoder(encoder, dev) { - if (encoder->funcs->early_unregister) + if (encoder->funcs && encoder->funcs->early_unregister) encoder->funcs->early_unregister(encoder); } } diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c index f1affc1bb679..e56a7f877f48 100644 --- a/drivers/gpu/drm/drm_mode_config.c +++ b/drivers/gpu/drm/drm_mode_config.c @@ -195,7 +195,7 @@ void drm_mode_config_reset(struct drm_device *dev) crtc->funcs->reset(crtc); drm_for_each_encoder(encoder, dev) - if (encoder->funcs->reset) + if (encoder->funcs && encoder->funcs->reset) encoder->funcs->reset(encoder); drm_connector_list_iter_begin(dev, _iter); diff --git a/include/drm/drm_encoder.h b/include/drm/drm_encoder.h index 5dfa5f7a80a7..833123637fbf 100644 --- a/include/drm/drm_encoder.h +++ b/include/drm/drm_encoder.h @@ -89,7 +89,7 @@ struct drm_encoder_funcs { * @head: list management * @base: base KMS object * @name: human readable name, can be overwritten by the driver - * @funcs: control functions + * @funcs: control functions, can be NULL for simple managed encoders * @helper_private: mid-layer private data * * CRTCs drive pixels to encoders, which convert them into signals -- 2.20.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v8, 2/6] dt-bindings: mediatek: add description for mt8183 display
Hi, Yongqiang: Yongqiang Niu 於 2020年12月10日 週四 下午5:22寫道: > > add description for mt8183 display Reviewed-by: Chun-Kuang Hu > > Signed-off-by: Yongqiang Niu > --- > Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git > a/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt > b/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt > index 64c64ee..5ca693a 100644 > --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt > +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt > @@ -43,7 +43,7 @@ Required properties (all function blocks): > "mediatek,-dpi" - DPI controller, see > mediatek,dpi.txt > "mediatek,-disp-mutex"- display mutex > "mediatek,-disp-od" - overdrive > - the supported chips are mt2701, mt7623, mt2712 and mt8173. > + the supported chips are mt2701, mt7623, mt2712, mt8173 and mt8183. > - reg: Physical base address and length of the function block register space > - interrupts: The interrupt signal from the function block (required, except > for >merge and split function blocks). > -- > 1.8.1.1.dirty > ___ > Linux-mediatek mailing list > linux-media...@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/linux-mediatek ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v3 1/2] drm: automatic legacy gamma support
On Thu, Dec 10, 2020 at 04:08:51PM +0200, Tomi Valkeinen wrote: > To support legacy gamma ioctls the drivers need to set > drm_crtc_funcs.gamma_set either to a custom implementation or to > drm_atomic_helper_legacy_gamma_set. Most of the atomic drivers do the > latter. > > We can simplify this by making the core handle it automatically. > > Add three functions to drm_color_mgmt.c: > > drm_crtc_supports_legacy_gamma() which tells if the driver supports > setting the legacy gamma. > > drm_crtc_gamma_ramp_set() which sets the given gamma ramp to GAMMA_LUT > and resets DEGAMMA_LUT and CTM. > > drm_crtc_legacy_gamma_set() which sets the given gamma ramp values > either using drm_crtc_funcs.gamma_set or drm_crtc_gamma_ramp_set(). > > These functions are used from the drm_mode_gamma_set_ioctl, and from > drm_fb_helper.c when it is dealing with fbdev cmap. > > We can then drop drm_atomic_helper_legacy_gamma_set() and remove all its > uses. > > Note that we need to EXPORT_SYMBOL all the new functions as they are > used from drm_fb_helper, but they are declared in drm_crtc_internal.h as > they are not supposed to be used by the drivers. > > Signed-off-by: Tomi Valkeinen > --- > .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 1 - > .../gpu/drm/arm/display/komeda/komeda_crtc.c | 1 - > drivers/gpu/drm/arm/malidp_crtc.c | 1 - > drivers/gpu/drm/armada/armada_crtc.c | 1 - > drivers/gpu/drm/ast/ast_mode.c| 1 - > .../gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c| 1 - > drivers/gpu/drm/drm_atomic_helper.c | 70 - > drivers/gpu/drm/drm_color_mgmt.c | 138 -- > drivers/gpu/drm/drm_crtc_internal.h | 10 ++ > drivers/gpu/drm/drm_fb_helper.c | 28 ++-- > drivers/gpu/drm/i915/display/intel_display.c | 1 - > drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 2 - > drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 1 - > drivers/gpu/drm/nouveau/dispnv50/head.c | 2 - > drivers/gpu/drm/omapdrm/omap_crtc.c | 1 - > drivers/gpu/drm/rcar-du/rcar_du_crtc.c| 1 - > drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 1 - > drivers/gpu/drm/stm/ltdc.c| 1 - > drivers/gpu/drm/vc4/vc4_crtc.c| 1 - > drivers/gpu/drm/vc4/vc4_txp.c | 1 - > include/drm/drm_atomic_helper.h | 4 - > include/drm/drm_color_mgmt.h | 1 - > 22 files changed, 148 insertions(+), 121 deletions(-) > > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > index 2855bb918535..848b06c51b0e 100644 > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c > @@ -5396,7 +5396,6 @@ static void dm_disable_vblank(struct drm_crtc *crtc) > static const struct drm_crtc_funcs amdgpu_dm_crtc_funcs = { > .reset = dm_crtc_reset_state, > .destroy = amdgpu_dm_crtc_destroy, > - .gamma_set = drm_atomic_helper_legacy_gamma_set, > .set_config = drm_atomic_helper_set_config, > .page_flip = drm_atomic_helper_page_flip, > .atomic_duplicate_state = dm_crtc_duplicate_state, > diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c > b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c > index 4b485eb512e2..59172acb9738 100644 > --- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c > +++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c > @@ -550,7 +550,6 @@ static void komeda_crtc_vblank_disable(struct drm_crtc > *crtc) > } > > static const struct drm_crtc_funcs komeda_crtc_funcs = { > - .gamma_set = drm_atomic_helper_legacy_gamma_set, > .destroy= drm_crtc_cleanup, > .set_config = drm_atomic_helper_set_config, > .page_flip = drm_atomic_helper_page_flip, > diff --git a/drivers/gpu/drm/arm/malidp_crtc.c > b/drivers/gpu/drm/arm/malidp_crtc.c > index 108e7a31bd26..494075ddbef6 100644 > --- a/drivers/gpu/drm/arm/malidp_crtc.c > +++ b/drivers/gpu/drm/arm/malidp_crtc.c > @@ -510,7 +510,6 @@ static void malidp_crtc_disable_vblank(struct drm_crtc > *crtc) > } > > static const struct drm_crtc_funcs malidp_crtc_funcs = { > - .gamma_set = drm_atomic_helper_legacy_gamma_set, > .destroy = drm_crtc_cleanup, > .set_config = drm_atomic_helper_set_config, > .page_flip = drm_atomic_helper_page_flip, > diff --git a/drivers/gpu/drm/armada/armada_crtc.c > b/drivers/gpu/drm/armada/armada_crtc.c > index 3ebcf5a52c8b..b7bb90ae787f 100644 > --- a/drivers/gpu/drm/armada/armada_crtc.c > +++ b/drivers/gpu/drm/armada/armada_crtc.c > @@ -820,7 +820,6 @@ static const struct drm_crtc_funcs armada_crtc_funcs = { > .cursor_set = armada_drm_crtc_cursor_set, > .cursor_move= armada_drm_crtc_cursor_move, > .destroy= armada_drm_crtc_destroy, > - .gamma_set =
[PATCH] drm/ttm: cleanup BO size handling v3
Based on an idea from Dave, but cleaned up a bit. We had multiple fields for essentially the same thing. Now bo->base.size is the original size of the BO in arbitrary units, usually bytes. bo->mem.num_pages is the size in number of pages in the resource domain of bo->mem.mem_type. v2: use the GEM object size instead of the BO size v3: fix printks in some places Signed-off-by: Christian König Reviewed-by: Huang Rui (v1) Acked-by: Daniel Vetter --- drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_object.c| 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_object.h| 4 +-- drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 6 ++-- drivers/gpu/drm/amd/amdgpu/mes_v10_1.c| 2 +- drivers/gpu/drm/nouveau/nouveau_bo.c | 10 +++--- drivers/gpu/drm/nouveau/nouveau_display.c | 8 ++--- drivers/gpu/drm/nouveau/nouveau_prime.c | 4 +-- drivers/gpu/drm/nouveau/nv17_fence.c | 2 +- drivers/gpu/drm/nouveau/nv50_fence.c | 2 +- drivers/gpu/drm/qxl/qxl_object.h | 2 +- drivers/gpu/drm/radeon/radeon_cs.c| 3 +- drivers/gpu/drm/radeon/radeon_object.c| 13 --- drivers/gpu/drm/radeon/radeon_object.h| 4 +-- drivers/gpu/drm/radeon/radeon_prime.c | 4 +-- drivers/gpu/drm/radeon/radeon_trace.h | 2 +- drivers/gpu/drm/radeon/radeon_ttm.c | 2 +- drivers/gpu/drm/ttm/ttm_bo.c | 35 ++- drivers/gpu/drm/ttm/ttm_bo_util.c | 12 +++ drivers/gpu/drm/ttm/ttm_bo_vm.c | 6 ++-- drivers/gpu/drm/ttm/ttm_tt.c | 2 +- drivers/gpu/drm/vmwgfx/vmwgfx_blit.c | 4 +-- drivers/gpu/drm/vmwgfx/vmwgfx_bo.c| 6 ++-- drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c | 2 +- drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 4 +-- drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c | 5 ++- drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 2 +- drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c| 8 ++--- drivers/gpu/drm/vmwgfx/vmwgfx_resource.c | 2 +- drivers/gpu/drm/vmwgfx/vmwgfx_shader.c| 3 +- drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c | 4 +-- drivers/gpu/drm/vmwgfx/vmwgfx_surface.c | 7 ++-- include/drm/ttm/ttm_bo_api.h | 9 ++--- include/drm/ttm/ttm_resource.h| 1 - 36 files changed, 84 insertions(+), 104 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c index e5919efca870..c4c93f19d273 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c @@ -269,7 +269,7 @@ static struct sg_table *amdgpu_dma_buf_map(struct dma_buf_attachment *attach, case TTM_PL_TT: sgt = drm_prime_pages_to_sg(obj->dev, bo->tbo.ttm->pages, - bo->tbo.num_pages); + bo->tbo.ttm->num_pages); if (IS_ERR(sgt)) return sgt; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c index 056cb87d09ea..52bcd1b5582f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c @@ -121,7 +121,7 @@ uint64_t amdgpu_gmc_agp_addr(struct ttm_buffer_object *bo) { struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev); - if (bo->num_pages != 1 || bo->ttm->caching == ttm_cached) + if (bo->ttm->num_pages != 1 || bo->ttm->caching == ttm_cached) return AMDGPU_BO_INVALID_OFFSET; if (bo->ttm->dma_address[0] + PAGE_SIZE >= adev->gmc.agp_size) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index c6c9723d3d8a..381ecc4788d5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c @@ -787,7 +787,7 @@ int amdgpu_bo_kmap(struct amdgpu_bo *bo, void **ptr) if (r < 0) return r; - r = ttm_bo_kmap(>tbo, 0, bo->tbo.num_pages, >kmap); + r = ttm_bo_kmap(>tbo, 0, bo->tbo.mem.num_pages, >kmap); if (r) return r; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h index ed47cbac4f75..a99a5cde42dd 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h @@ -174,12 +174,12 @@ static inline void amdgpu_bo_unreserve(struct amdgpu_bo *bo) static inline unsigned long amdgpu_bo_size(struct amdgpu_bo *bo) { - return bo->tbo.num_pages << PAGE_SHIFT; + return bo->tbo.base.size; } static inline unsigned amdgpu_bo_ngpu_pages(struct amdgpu_bo *bo) { - return (bo->tbo.num_pages <<
[PATCH v4 0/5] Thermal devfreq cooling improvements with Energy Model
Hi all, This patch set is a continuation of my previous work, which aimed to add Energy Model to all devices [1]. This series is a follow up for the patches which got merged to v5.9-rc1. It aims to change the thermal devfreq cooling and use the Energy Model instead of private power table and structures. The power model is now simplified, static power and dynamic power are removed. The new registration interface in the patch 3/5 helps to register devfreq cooling and the EM in one call. There is also small improvement, patch 2/5 is changing the way how thermal gets the device status (now uses a copy) and normalize the values. The last patch is here for consistency and will probably go through drm tree. The patch set should apply on top of thermal/testing. It does not depend on new EM API change which is queued in the pm/linux-next tree as v5.11 material. Thus, could go in parallel. That was the main motiviation for this v4. changes: v4: - patch 3/5 - removed dependency on the EM API change -- removed em_dev_register_perf_domain() and just use dev_pm_opp_of_register_em() which API has not changed -- removed a helper registration function and renamed devfreq_cooling_em_register_power() to devfreq_cooling_em_register() (was actually suggested by Ionela during review) -- moved energy_model.h to include in devfreq_cooling.c not .h, since there is no EM structure in there anymore - adjusted comments and commit messages v3 [4]: - dropped direct check of device status and used just a copy of 'status'; a separate patch set will be proposed to address this issue - modified _normalize_load() and used 1024 scale to handle ms, us, ns - removed 'em_registered' and called em_dev_unregister_perf_domain() unconditionally, so the drivers will have to make sure the right order of all unregister calls to frameworks which might use EM; this call must be last one; a proper comment added - removed 'em' pointer from struct devfreq_cooling_device, 'dev->em_pd' is used - removed of_node_get/put(), since the code can handle it - removed dfc_em_get_requested_power() (as missed to do it in v2) - collected all Reviewed-by tags v2 [3]: - renamed freq_get_state() and related to perf_idx pattern as suggested by Ionela v1 [2] Regards, Lukasz Luba Lukasz Luba (5): thermal: devfreq_cooling: change tracing function and arguments thermal: devfreq_cooling: use a copy of device status thermal: devfreq_cooling: add new registration functions with Energy Model thermal: devfreq_cooling: remove old power model and use EM drm/panfrost: Register devfreq cooling and attempt to add Energy Model drivers/gpu/drm/panfrost/panfrost_devfreq.c | 2 +- drivers/thermal/devfreq_cooling.c | 391 +--- include/linux/devfreq_cooling.h | 27 +- include/trace/events/thermal.h | 19 +- 4 files changed, 198 insertions(+), 241 deletions(-) -- 2.17.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v2 5/7] drm/vc4: kms: Remove unassigned_channels from the HVS state
On Fri, Dec 04, 2020 at 04:11:36PM +0100, Maxime Ripard wrote: > @@ -893,12 +890,17 @@ static int vc4_pv_muxing_atomic_check(struct drm_device > *dev, > struct vc4_hvs_state *hvs_new_state; > struct drm_crtc_state *old_crtc_state, *new_crtc_state; > struct drm_crtc *crtc; > + unsigned int unassigned_channels; This should be initialized to 0, I'll fix it up while applying if there's no other comment. Maxime signature.asc Description: PGP signature ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 05/15] drm/vc4: hdmi: Restore cec physical address on reconnect
From: Dom Cobley Currently we call cec_phys_addr_invalidate on a hotplug deassert. That may be due to a TV power cycling, or an AVR being switched on (and switching edid). This makes CEC unusable since our controller wouldn't have a physical address anymore. Set it back up again on the hotplug assert. Fixes: 15b4511a4af6 ("drm/vc4: add HDMI CEC support") Signed-off-by: Dom Cobley Signed-off-by: Maxime Ripard --- drivers/gpu/drm/vc4/vc4_hdmi.c | 25 + 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index 28b78ea885ea..eff3bac562c6 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -136,20 +136,29 @@ static enum drm_connector_status vc4_hdmi_connector_detect(struct drm_connector *connector, bool force) { struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector); + bool connected = false; if (vc4_hdmi->hpd_gpio) { if (gpio_get_value_cansleep(vc4_hdmi->hpd_gpio) ^ vc4_hdmi->hpd_active_low) - return connector_status_connected; - cec_phys_addr_invalidate(vc4_hdmi->cec_adap); - return connector_status_disconnected; - } - - if (drm_probe_ddc(vc4_hdmi->ddc)) - return connector_status_connected; - + connected = true; + } else if (drm_probe_ddc(vc4_hdmi->ddc)) + connected = true; if (HDMI_READ(HDMI_HOTPLUG) & VC4_HDMI_HOTPLUG_CONNECTED) + connected = true; + if (connected) { + if (connector->status != connector_status_connected) { + struct edid *edid = drm_get_edid(connector, vc4_hdmi->ddc); + + if (edid) { + cec_s_phys_addr_from_edid(vc4_hdmi->cec_adap, edid); + vc4_hdmi->encoder.hdmi_monitor = drm_detect_hdmi_monitor(edid); + drm_connector_update_edid_property(connector, edid); + kfree(edid); + } + } return connector_status_connected; + } cec_phys_addr_invalidate(vc4_hdmi->cec_adap); return connector_status_disconnected; } -- 2.28.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 07/15] drm/vc4: hdmi: Update the CEC clock divider on HSM rate change
As part of the enable sequence we might change the HSM clock rate if the pixel rate is different than the one we were already dealing with. On the BCM2835 however, the CEC clock derives from the HSM clock so any rate change will need to be reflected in the CEC clock divider to output 40kHz. Fixes: cd4cb49dc5bb ("drm/vc4: hdmi: Adjust HSM clock rate depending on pixel rate") Signed-off-by: Maxime Ripard --- drivers/gpu/drm/vc4/vc4_hdmi.c | 39 +- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index 0c53d7427d15..b93ee3e26e2b 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -132,6 +132,27 @@ static void vc5_hdmi_reset(struct vc4_hdmi *vc4_hdmi) HDMI_READ(HDMI_CLOCK_STOP) | VC4_DVP_HT_CLOCK_STOP_PIXEL); } +#ifdef CONFIG_DRM_VC4_HDMI_CEC +static void vc4_hdmi_cec_update_clk_div(struct vc4_hdmi *vc4_hdmi) +{ + u16 clk_cnt; + u32 value; + + value = HDMI_READ(HDMI_CEC_CNTRL_1); + value &= ~VC4_HDMI_CEC_DIV_CLK_CNT_MASK; + + /* +* Set the clock divider: the hsm_clock rate and this divider +* setting will give a 40 kHz CEC clock. +*/ + clk_cnt = clk_get_rate(vc4_hdmi->hsm_clock) / CEC_CLOCK_FREQ; + value |= clk_cnt << VC4_HDMI_CEC_DIV_CLK_CNT_SHIFT; + HDMI_WRITE(HDMI_CEC_CNTRL_1, value); +} +#else +static void vc4_hdmi_cec_update_clk_div(struct vc4_hdmi *vc4_hdmi) {} +#endif + static enum drm_connector_status vc4_hdmi_connector_detect(struct drm_connector *connector, bool force) { @@ -761,6 +782,8 @@ static void vc4_hdmi_encoder_pre_crtc_configure(struct drm_encoder *encoder, return; } + vc4_hdmi_cec_update_clk_div(vc4_hdmi); + /* * FIXME: When the pixel freq is 594MHz (4k60), this needs to be setup * at 300MHz. @@ -1586,7 +1609,6 @@ static int vc4_hdmi_cec_init(struct vc4_hdmi *vc4_hdmi) { struct cec_connector_info conn_info; struct platform_device *pdev = vc4_hdmi->pdev; - u16 clk_cnt; u32 value; int ret; @@ -1605,17 +1627,14 @@ static int vc4_hdmi_cec_init(struct vc4_hdmi *vc4_hdmi) cec_s_conn_info(vc4_hdmi->cec_adap, _info); HDMI_WRITE(HDMI_CEC_CPU_MASK_SET, 0x); + value = HDMI_READ(HDMI_CEC_CNTRL_1); - value &= ~VC4_HDMI_CEC_DIV_CLK_CNT_MASK; - /* -* Set the logical address to Unregistered and set the clock -* divider: the hsm_clock rate and this divider setting will -* give a 40 kHz CEC clock. -*/ - clk_cnt = clk_get_rate(vc4_hdmi->hsm_clock) / CEC_CLOCK_FREQ; - value |= VC4_HDMI_CEC_ADDR_MASK | -(clk_cnt << VC4_HDMI_CEC_DIV_CLK_CNT_SHIFT); + /* Set the logical address to Unregistered */ + value |= VC4_HDMI_CEC_ADDR_MASK; HDMI_WRITE(HDMI_CEC_CNTRL_1, value); + + vc4_hdmi_cec_update_clk_div(vc4_hdmi); + ret = devm_request_threaded_irq(>dev, platform_get_irq(pdev, 0), vc4_cec_irq_handler, vc4_cec_irq_handler_thread, 0, -- 2.28.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 09/15] drm/vc4: hdmi: Split the interrupt handlers
The BCM2711 has two different interrupt sources to transmit and receive CEC messages, provided through an external interrupt chip shared between the two HDMI interrupt controllers. The rest of the CEC controller is identical though so we need to change a bit the code organisation to share the code as much as possible, yet still allowing to register independant handlers. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/vc4/vc4_hdmi.c | 86 +- 1 file changed, 65 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index 0debd22bc992..80a81fcea315 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -1442,15 +1442,22 @@ static int vc4_hdmi_audio_init(struct vc4_hdmi *vc4_hdmi) } #ifdef CONFIG_DRM_VC4_HDMI_CEC -static irqreturn_t vc4_cec_irq_handler_thread(int irq, void *priv) +static irqreturn_t vc4_cec_irq_handler_rx_thread(int irq, void *priv) { struct vc4_hdmi *vc4_hdmi = priv; - if (vc4_hdmi->cec_irq_was_rx) { - if (vc4_hdmi->cec_rx_msg.len) - cec_received_msg(vc4_hdmi->cec_adap, -_hdmi->cec_rx_msg); - } else if (vc4_hdmi->cec_tx_ok) { + if (vc4_hdmi->cec_rx_msg.len) + cec_received_msg(vc4_hdmi->cec_adap, +_hdmi->cec_rx_msg); + + return IRQ_HANDLED; +} + +static irqreturn_t vc4_cec_irq_handler_tx_thread(int irq, void *priv) +{ + struct vc4_hdmi *vc4_hdmi = priv; + + if (vc4_hdmi->cec_tx_ok) { cec_transmit_done(vc4_hdmi->cec_adap, CEC_TX_STATUS_OK, 0, 0, 0, 0); } else { @@ -1464,6 +1471,19 @@ static irqreturn_t vc4_cec_irq_handler_thread(int irq, void *priv) return IRQ_HANDLED; } +static irqreturn_t vc4_cec_irq_handler_thread(int irq, void *priv) +{ + struct vc4_hdmi *vc4_hdmi = priv; + irqreturn_t ret; + + if (vc4_hdmi->cec_irq_was_rx) + ret = vc4_cec_irq_handler_rx_thread(irq, priv); + else + ret = vc4_cec_irq_handler_tx_thread(irq, priv); + + return ret; +} + static void vc4_cec_read_msg(struct vc4_hdmi *vc4_hdmi, u32 cntrl1) { struct drm_device *dev = vc4_hdmi->connector.dev; @@ -1488,31 +1508,55 @@ static void vc4_cec_read_msg(struct vc4_hdmi *vc4_hdmi, u32 cntrl1) } } +static irqreturn_t vc4_cec_irq_handler_tx_bare(int irq, void *priv) +{ + struct vc4_hdmi *vc4_hdmi = priv; + u32 cntrl1; + + cntrl1 = HDMI_READ(HDMI_CEC_CNTRL_1); + vc4_hdmi->cec_tx_ok = cntrl1 & VC4_HDMI_CEC_TX_STATUS_GOOD; + cntrl1 &= ~VC4_HDMI_CEC_START_XMIT_BEGIN; + HDMI_WRITE(HDMI_CEC_CNTRL_1, cntrl1); + + return IRQ_WAKE_THREAD; +} + +static irqreturn_t vc4_cec_irq_handler_rx_bare(int irq, void *priv) +{ + struct vc4_hdmi *vc4_hdmi = priv; + u32 cntrl1; + + vc4_hdmi->cec_rx_msg.len = 0; + cntrl1 = HDMI_READ(HDMI_CEC_CNTRL_1); + vc4_cec_read_msg(vc4_hdmi, cntrl1); + cntrl1 |= VC4_HDMI_CEC_CLEAR_RECEIVE_OFF; + HDMI_WRITE(HDMI_CEC_CNTRL_1, cntrl1); + cntrl1 &= ~VC4_HDMI_CEC_CLEAR_RECEIVE_OFF; + + HDMI_WRITE(HDMI_CEC_CNTRL_1, cntrl1); + + return IRQ_WAKE_THREAD; +} + static irqreturn_t vc4_cec_irq_handler(int irq, void *priv) { struct vc4_hdmi *vc4_hdmi = priv; u32 stat = HDMI_READ(HDMI_CEC_CPU_STATUS); - u32 cntrl1, cntrl5; + irqreturn_t ret; + u32 cntrl5; if (!(stat & VC4_HDMI_CPU_CEC)) return IRQ_NONE; - vc4_hdmi->cec_rx_msg.len = 0; - cntrl1 = HDMI_READ(HDMI_CEC_CNTRL_1); + cntrl5 = HDMI_READ(HDMI_CEC_CNTRL_5); vc4_hdmi->cec_irq_was_rx = cntrl5 & VC4_HDMI_CEC_RX_CEC_INT; - if (vc4_hdmi->cec_irq_was_rx) { - vc4_cec_read_msg(vc4_hdmi, cntrl1); - cntrl1 |= VC4_HDMI_CEC_CLEAR_RECEIVE_OFF; - HDMI_WRITE(HDMI_CEC_CNTRL_1, cntrl1); - cntrl1 &= ~VC4_HDMI_CEC_CLEAR_RECEIVE_OFF; - } else { - vc4_hdmi->cec_tx_ok = cntrl1 & VC4_HDMI_CEC_TX_STATUS_GOOD; - cntrl1 &= ~VC4_HDMI_CEC_START_XMIT_BEGIN; - } - HDMI_WRITE(HDMI_CEC_CNTRL_1, cntrl1); + if (vc4_hdmi->cec_irq_was_rx) + ret = vc4_cec_irq_handler_rx_bare(irq, priv); + else + ret = vc4_cec_irq_handler_tx_bare(irq, priv); + HDMI_WRITE(HDMI_CEC_CPU_CLEAR, VC4_HDMI_CPU_CEC); - - return IRQ_WAKE_THREAD; + return ret; } static int vc4_hdmi_cec_adap_enable(struct cec_adapter *adap, bool enable) -- 2.28.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v8, 2/6] dt-bindings: mediatek: add description for mt8183 display
add description for mt8183 display Signed-off-by: Yongqiang Niu --- Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt b/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt index 64c64ee..5ca693a 100644 --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt @@ -43,7 +43,7 @@ Required properties (all function blocks): "mediatek,-dpi" - DPI controller, see mediatek,dpi.txt "mediatek,-disp-mutex"- display mutex "mediatek,-disp-od" - overdrive - the supported chips are mt2701, mt7623, mt2712 and mt8173. + the supported chips are mt2701, mt7623, mt2712, mt8173 and mt8183. - reg: Physical base address and length of the function block register space - interrupts: The interrupt signal from the function block (required, except for merge and split function blocks). -- 1.8.1.1.dirty ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 06/15] drm/vc4: hdmi: Compute the CEC clock divider from the clock rate
The CEC clock divider needs to output a frequency of 40kHz from the HSM rate on the BCM2835. The driver used to have a fixed frequency for it, but that changed and we now need to compute it dynamically to maintain the proper rate. Fixes: cd4cb49dc5bb ("drm/vc4: hdmi: Adjust HSM clock rate depending on pixel rate") Signed-off-by: Maxime Ripard --- drivers/gpu/drm/vc4/vc4_hdmi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index eff3bac562c6..0c53d7427d15 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -1586,6 +1586,7 @@ static int vc4_hdmi_cec_init(struct vc4_hdmi *vc4_hdmi) { struct cec_connector_info conn_info; struct platform_device *pdev = vc4_hdmi->pdev; + u16 clk_cnt; u32 value; int ret; @@ -1611,8 +1612,9 @@ static int vc4_hdmi_cec_init(struct vc4_hdmi *vc4_hdmi) * divider: the hsm_clock rate and this divider setting will * give a 40 kHz CEC clock. */ + clk_cnt = clk_get_rate(vc4_hdmi->hsm_clock) / CEC_CLOCK_FREQ; value |= VC4_HDMI_CEC_ADDR_MASK | -(4091 << VC4_HDMI_CEC_DIV_CLK_CNT_SHIFT); +(clk_cnt << VC4_HDMI_CEC_DIV_CLK_CNT_SHIFT); HDMI_WRITE(HDMI_CEC_CNTRL_1, value); ret = devm_request_threaded_irq(>dev, platform_get_irq(pdev, 0), vc4_cec_irq_handler, -- 2.28.0 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel