Re: [PATCH v7 2/6] iommu/arm-smmu: Add pm_runtime/sleep ops
Hi Vivek, Thanks for the patch. Please see some comments inline. On Wed, Feb 7, 2018 at 7:31 PM, Vivek Gautam wrote: > From: Sricharan R > > The smmu needs to be functional only when the respective > master's using it are active. The device_link feature > helps to track such functional dependencies, so that the > iommu gets powered when the master device enables itself > using pm_runtime. So by adapting the smmu driver for > runtime pm, above said dependency can be addressed. > > This patch adds the pm runtime/sleep callbacks to the > driver and also the functions to parse the smmu clocks > from DT and enable them in resume/suspend. > > Signed-off-by: Sricharan R > Signed-off-by: Archit Taneja > [vivek: Clock rework to request bulk of clocks] > Signed-off-by: Vivek Gautam > --- > drivers/iommu/arm-smmu.c | 56 > ++-- > 1 file changed, 54 insertions(+), 2 deletions(-) > > diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c > index 69e7c60792a8..9e2f917e16c2 100644 > --- a/drivers/iommu/arm-smmu.c > +++ b/drivers/iommu/arm-smmu.c > @@ -48,6 +48,7 @@ > #include > #include > #include > +#include > #include > #include > > @@ -205,6 +206,8 @@ struct arm_smmu_device { > u32 num_global_irqs; > u32 num_context_irqs; > unsigned int*irqs; > + struct clk_bulk_data*clocks; > + int num_clks; nit: Perhaps "num_clocks" to be consistent with "clocks"? > > u32 cavium_id_base; /* Specific to Cavium > */ > > @@ -1897,10 +1900,12 @@ static int arm_smmu_device_cfg_probe(struct > arm_smmu_device *smmu) > struct arm_smmu_match_data { > enum arm_smmu_arch_version version; > enum arm_smmu_implementation model; > + const char * const *clks; > + int num_clks; nit: Perhaps s/clks/clocks/ here or s/clocks/clks/ in struct arm_smmu_device? > }; > > #define ARM_SMMU_MATCH_DATA(name, ver, imp)\ > -static struct arm_smmu_match_data name = { .version = ver, .model = imp } > +static const struct arm_smmu_match_data name = { .version = ver, .model = > imp } > > ARM_SMMU_MATCH_DATA(smmu_generic_v1, ARM_SMMU_V1, GENERIC_SMMU); > ARM_SMMU_MATCH_DATA(smmu_generic_v2, ARM_SMMU_V2, GENERIC_SMMU); > @@ -2001,6 +2006,7 @@ static int arm_smmu_device_dt_probe(struct > platform_device *pdev, > data = of_device_get_match_data(dev); > smmu->version = data->version; > smmu->model = data->model; > + smmu->num_clks = data->num_clks; > > parse_driver_options(smmu); > > @@ -2039,6 +2045,28 @@ static void arm_smmu_bus_init(void) > #endif > } > > +static int arm_smmu_init_clks(struct arm_smmu_device *smmu) > +{ > + int i; > + int num = smmu->num_clks; > + const struct arm_smmu_match_data *data; > + > + if (num < 1) > + return 0; > + > + smmu->clocks = devm_kcalloc(smmu->dev, num, > + sizeof(*smmu->clocks), GFP_KERNEL); > + if (!smmu->clocks) > + return -ENOMEM; > + > + data = of_device_get_match_data(smmu->dev); > + > + for (i = 0; i < num; i++) > + smmu->clocks[i].id = data->clks[i]; I'd argue that arm_smmu_device_dt_probe() is a better place for all the code above, since this function is called regardless of whether the device is probed from DT or not. Going further, arm_smmu_device_acpi_probe() could fill smmu->num_clks and ->clocks using ACPI-like way (as opposed to OF match data) if necessary. Best regards, Tomasz ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 0/5] Fix deadlock on runtime suspend in DRM drivers
On Mon, Feb 12, 2018 at 01:58:32PM -0500, Alex Deucher wrote: > On Mon, Feb 12, 2018 at 4:45 AM, Lukas Wunner wrote: > > On Mon, Feb 12, 2018 at 09:03:26AM +, Mike Lothian wrote: > >> On 12 February 2018 at 03:39, Lukas Wunner wrote: > >> > On Mon, Feb 12, 2018 at 12:35:51AM +, Mike Lothian wrote: > >> > > I've not been able to reproduce the original problem you're trying to > >> > > solve on amdgpu thats with or without your patch set and the above > >> > > "trigger" too > > > > Okay the reason you're not seeing deadlocks is because the output poll > > worker is not enabled. And the output poll worker is not enabled > > because your discrete GPU doesn't have any outputs: > > > > [0.265568] [drm:dc_create] *ERROR* DC: Number of connectors is zero! > > > > The outputs are only polled if there are connectors which have the > > DRM_CONNECTOR_POLL_CONNECT or DRM_CONNECTOR_POLL_DISCONNECT flag set. > > And that only ever seems to be the case for VGA and DVI. > > > > We know based on bugzilla reports that hybrid graphics laptops do exist > > which poll outputs with radeon and nouveau. If there are no laptops > > supported by amdgpu whose discrete GPU has polled connectors, then > > patch [5/5] would be unnecessary. That is for Alex to decide. > > Most hybrid laptops don't have display connectors on the dGPU and we > only use polling on analog connectors, so you are not likely to run > into this on recent laptops. That said, I don't know if there is some > OEM system out there with a VGA port on the dGPU in a hybrid laptop. > I guess another option is to just disable polling on hybrid laptops. If we don't know for sure, applying patch [5/5] would seem to be the safest approach. (Assuming it doesn't break anything else.) Right now runtime PM is only used on hybrid graphics dGPUs by nouveau, radeon and amdgpu. Would it be conceivable that its use is expanded beyond that in the future? E.g. on a desktop machine, if DPMS is off on all screens, why keep the GPU in D0? If that is conceivable, chances that analog connectors are present are higher, and then the patch would be necessary again. (Of course this would mean that analog screens wouldn't light up automatically if they're attached while the GPU is in D3hot, but the user may forbid runtime PM via sysfs if that is unwanted.) Thanks, Lukas ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v7 3/6] iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device
Hi Vivek, Thanks for the patch. Please see my comments inline. On Wed, Feb 7, 2018 at 7:31 PM, Vivek Gautam wrote: > From: Sricharan R > > The smmu device probe/remove and add/remove master device callbacks > gets called when the smmu is not linked to its master, that is without > the context of the master device. So calling runtime apis in those places > separately. > > Signed-off-by: Sricharan R > [vivek: Cleanup pm runtime calls] > Signed-off-by: Vivek Gautam > --- > drivers/iommu/arm-smmu.c | 42 ++ > 1 file changed, 38 insertions(+), 4 deletions(-) > > diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c > index 9e2f917e16c2..c024f69c1682 100644 > --- a/drivers/iommu/arm-smmu.c > +++ b/drivers/iommu/arm-smmu.c > @@ -913,11 +913,15 @@ static void arm_smmu_destroy_domain_context(struct > iommu_domain *domain) > struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); > struct arm_smmu_device *smmu = smmu_domain->smmu; > struct arm_smmu_cfg *cfg = &smmu_domain->cfg; > - int irq; > + int ret, irq; > > if (!smmu || domain->type == IOMMU_DOMAIN_IDENTITY) > return; > > + ret = pm_runtime_get_sync(smmu->dev); > + if (ret) > + return; pm_runtime_get_sync() will return 0 if the device was powered off, 1 if it was already/still powered on or runtime PM is not compiled in, or a negative value on error, so shouldn't the test be (ret < 0)? Moreover, I'm actually wondering if it makes any sense to power up the hardware just to program it and power it down again. In a system where the IOMMU is located within a power domain, it would cause the IOMMU block to lose its state anyway. Actually, reflecting back on "[PATCH v7 2/6] iommu/arm-smmu: Add pm_runtime/sleep ops", perhaps it would make more sense to just control the clocks independently of runtime PM? Then, runtime PM could be used for real power management, e.g. really powering the block up and down, for further power saving. +Generally similar comments for other places in this patch. > + > /* > * Disable the context bank and free the page tables before freeing > * it. > @@ -932,6 +936,8 @@ static void arm_smmu_destroy_domain_context(struct > iommu_domain *domain) > > free_io_pgtable_ops(smmu_domain->pgtbl_ops); > __arm_smmu_free_bitmap(smmu->context_map, cfg->cbndx); > + > + pm_runtime_put_sync(smmu->dev); Is there any point in the put being sync here? [snip] > @@ -2131,6 +2152,14 @@ static int arm_smmu_device_probe(struct > platform_device *pdev) > if (err) > return err; > > + platform_set_drvdata(pdev, smmu); > + > + pm_runtime_enable(dev); I suspect this may be a disaster for systems where IOMMUs are located inside power domains, because the driver doesn't take care of the IOMMU block losing its state on physical power down, as I mentioned in my comments above. Best regards, Tomasz ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v7 4/6] iommu/arm-smmu: Add the device_link between masters and smmu
Hi Vivek, Thanks for the patch. Please see my comments inline. On Wed, Feb 7, 2018 at 7:31 PM, Vivek Gautam wrote: > From: Sricharan R > > Finally add the device link between the master device and > smmu, so that the smmu gets runtime enabled/disabled only when the > master needs it. This is done from add_device callback which gets > called once when the master is added to the smmu. > > Signed-off-by: Sricharan R > Signed-off-by: Vivek Gautam > --- > drivers/iommu/arm-smmu.c | 16 > 1 file changed, 16 insertions(+) > > diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c > index c024f69c1682..c7e924d553bd 100644 > --- a/drivers/iommu/arm-smmu.c > +++ b/drivers/iommu/arm-smmu.c > @@ -215,6 +215,9 @@ struct arm_smmu_device { > > /* IOMMU core code handle */ > struct iommu_device iommu; > + > + /* runtime PM link to master */ > + struct device_link *link; > }; > > enum arm_smmu_context_fmt { > @@ -1425,6 +1428,17 @@ static int arm_smmu_add_device(struct device *dev) > > pm_runtime_put_sync(smmu->dev); > > + /* > +* Establish the link between smmu and master, so that the > +* smmu gets runtime enabled/disabled as per the master's > +* needs. > +*/ > + smmu->link = device_link_add(dev, smmu->dev, DL_FLAG_PM_RUNTIME); > + if (!smmu->link) > + dev_warn(smmu->dev, > +"Unable to create device link between %s and %s\n", > +dev_name(smmu->dev), dev_name(dev)); How likely it is that the master can work normally even if the link add fails? Perhaps we should just return an error here? > + > return 0; > > out_rpm_put: > @@ -1449,6 +1463,8 @@ static void arm_smmu_remove_device(struct device *dev) > cfg = fwspec->iommu_priv; > smmu = cfg->smmu; > > + device_link_del(smmu->link); We allowed smmu->link in arm_smmu_add_device(), but here we don't check it. Looking at the code, device_link_del() doesn't seem to check either. Note that this problem would go away if we fail add_device on device_link_add() failure, as I suggested above, so no change would be necessary. Best regards, Tomasz ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH] drm/simple_kms_helper: Fix NULL pointer dereference with no active CRTC
From: Oleksandr Andrushchenko It is possible that drm_simple_kms_plane_atomic_check called with no CRTC set, e.g. when user-space application sets CRTC_ID/FB_ID to 0 before doing any actual drawing. This leads to NULL pointer dereference because in this case new CRTC state is NULL and must be checked before accessing. Signed-off-by: Oleksandr Andrushchenko --- drivers/gpu/drm/drm_simple_kms_helper.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_simple_kms_helper.c b/drivers/gpu/drm/drm_simple_kms_helper.c index 9ca8a4a59b74..a05eca9cec8b 100644 --- a/drivers/gpu/drm/drm_simple_kms_helper.c +++ b/drivers/gpu/drm/drm_simple_kms_helper.c @@ -121,8 +121,10 @@ static int drm_simple_kms_plane_atomic_check(struct drm_plane *plane, pipe = container_of(plane, struct drm_simple_display_pipe, plane); crtc_state = drm_atomic_get_new_crtc_state(plane_state->state, &pipe->crtc); - if (!crtc_state->enable) - return 0; /* nothing to check when disabling or disabled */ + + if (!crtc_state || !crtc_state->enable) + /* nothing to check when disabling or disabled or no CRTC set */ + return 0; if (crtc_state->enable) drm_mode_get_hv_timing(&crtc_state->mode, -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: Thinkpad X1 Carbon 3rd - Reducing the compressed framebuffer size
On Tuesday 06 February 2018 16:21:43 Pali Rohár wrote: > Hi! I'm periodically getting following message in dmesg on Lenovo > Thinkpad X1 Carbon 3rd generation: > > [drm] Reducing the compressed framebuffer size. This may lead to less power > savings than a non-reduced-size. Try to increase stolen memory size if > available in BIOS. > > In BIOS I already set GPU size to 512M, but this did not help. Also > update to last BIOS version did not help. > > So why this message is periodically print in dmesg? And what can I do > with this problem? > > And why cannot Linux kernel allocate itself more memory for GPU (if BIOS > can/could do that)? Is not 512MB for GPU enough? And here is output from lspci, which clearly says that 512MB is already set for GPU: $ lspci -v -s 00:02.0 00:02.0 VGA compatible controller: Intel Corporation HD Graphics 5500 (rev 09) (prog-if 00 [VGA controller]) Subsystem: Lenovo HD Graphics 5500 Flags: bus master, fast devsel, latency 0, IRQ 46 Memory at e000 (64-bit, non-prefetchable) [size=16M] Memory at c000 (64-bit, prefetchable) [size=512M] I/O ports at 3000 [size=64] [virtual] Expansion ROM at 000c [disabled] [size=128K] Capabilities: [90] MSI: Enable+ Count=1/1 Maskable- 64bit- Capabilities: [d0] Power Management version 2 Capabilities: [a4] PCI Advanced Features Kernel driver in use: i915 Kernel modules: i915 -- Pali Rohár pali.ro...@gmail.com ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v8 5/6] iommu/arm-smmu: Add support for qcom, smmu-v2 variant
Hi Vivek, Thanks for the patch. Please see my comments inline. On Fri, Feb 9, 2018 at 7:57 PM, Vivek Gautam wrote: > qcom,smmu-v2 is an arm,smmu-v2 implementation with specific > clock and power requirements. This smmu core is used with > multiple masters on msm8996, viz. mdss, video, etc. > Add bindings for the same. > > Signed-off-by: Vivek Gautam > Reviewed-by: Rob Herring > --- > > Changes in v8: > - Added the missing IOMMU_OF_DECLARE declaration for "qcom,smmu-v2" > > .../devicetree/bindings/iommu/arm,smmu.txt | 43 > ++ > drivers/iommu/arm-smmu.c | 14 +++ > 2 files changed, 57 insertions(+) > > diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.txt > b/Documentation/devicetree/bindings/iommu/arm,smmu.txt > index 8a6ffce12af5..169222ae2706 100644 > --- a/Documentation/devicetree/bindings/iommu/arm,smmu.txt > +++ b/Documentation/devicetree/bindings/iommu/arm,smmu.txt > @@ -17,10 +17,19 @@ conditions. > "arm,mmu-401" > "arm,mmu-500" > "cavium,smmu-v2" > +"qcom,-smmu-v2", "qcom,smmu-v2" > >depending on the particular implementation and/or the >version of the architecture implemented. > > + A number of Qcom SoCs use qcom,smmu-v2 version of the IP. > + "qcom,-smmu-v2" represents a soc specific compatible > + string that should be present along with the "qcom,smmu-v2" > + to facilitate SoC specific clocks/power connections and to > + address specific bug fixes. > + An example string would be - > + "qcom,msm8996-smmu-v2", "qcom,smmu-v2". Hmm, I remember that for and similar wildcards we required explicitly listing allowed values. Rob, has it changed since I stumbled upon such thing last time (or I just got it wrong before)? > + > - reg : Base address and size of the SMMU. > > - #global-interrupts : The number of global interrupts exposed by the > @@ -71,6 +80,23 @@ conditions. >or using stream matching with #iommu-cells = <2>, and >may be ignored if present in such cases. > > +- clock-names:Should be "bus", and "iface" for "qcom,smmu-v2" > + implementation. > + > + "bus" clock for "qcom,smmu-v2" is required for downstream > + bus access and for the smmu ptw. > + > + "iface" clock is required to access smmu's registers > through > + the TCU's programming interface. nit: Could we have it in a bit more structured way? E.g. - clock-names: List of names of clocks input to the device. The required list depends on particular implementation and is as follows: - for "qcom,smmu-v2": - "bus": clock required for downstream bus access and for the smmu ptw, - "iface": clock required to access smmu's registers through the TCU's programming interface. - unspecified for other implementations. (+/- wrapping) > + > +- clocks: Phandles for respective clocks described by clock-names. Phandle is just a pointer to another node. Clocks are however specified using a phandle and a number of arguments, depending on the clock controller. I'd change it to: - clocks: Specifiers for all clocks listed in the clock-names property, as per generic clock bindings. > + > +- power-domains: Phandles to SMMU's power domain specifier. This is > + required even if SMMU belongs to the master's power > + domain, as the SMMU will have to be enabled and > + accessed before master gets enabled and linked to its > + SMMU. From DT point of view, the relationship of SMMU belonging to a master device doesn't exist. The power-domains property needs to be properly specified for all devices within power domains represented in DT, with an exception of the case when the parent-child relationship is explicitly stated in DT by child devices being represented by child nodes of the parent device node. - power-domains: Specifiers for power domains required to be powered on for the SMMU to operate, as per generic power domain bindings. Best regards, Tomasz ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 105021] suspend / rx550 / extremely slow after 2nd thaw
https://bugs.freedesktop.org/show_bug.cgi?id=105021 --- Comment #8 from Michel Dänzer --- (In reply to arne_woerner from comment #4) > in the first few seconds yes, but then no... So the slowness is probably due to the GPU's IRQ no longer working, the question is why that happens... Assuming you're running with DC enabled, does amdgpu.dc=0 make a difference? (Or amdgpu.dc=1 otherwise) If not, since this seems to be a regression, bisecting between 4.14 and 4.15 would probably be the best way forward. -- You are receiving this mail because: You are the assignee for the bug.___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v7 6/6] drm/msm: iommu: Replace runtime calls with runtime suppliers
Hi Vivek, Thanks for the patch. Please see my comments inline. On Wed, Feb 7, 2018 at 7:31 PM, Vivek Gautam wrote: > While handling the concerned iommu, there should not be a > need to power control the drm devices from iommu interface. > If these drm devices need to be powered around this time, > the respective drivers should take care of this. > > Replace the pm_runtime_get/put_sync() with > pm_runtime_get/put_suppliers() calls, to power-up > the connected iommu through the device link interface. > In case the device link is not setup these get/put_suppliers() > calls will be a no-op, and the iommu driver should take care of > powering on its devices accordingly. > > Signed-off-by: Vivek Gautam > --- > drivers/gpu/drm/msm/msm_iommu.c | 16 > 1 file changed, 8 insertions(+), 8 deletions(-) > > diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c > index b23d33622f37..1ab629bbee69 100644 > --- a/drivers/gpu/drm/msm/msm_iommu.c > +++ b/drivers/gpu/drm/msm/msm_iommu.c > @@ -40,9 +40,9 @@ static int msm_iommu_attach(struct msm_mmu *mmu, const char > * const *names, > struct msm_iommu *iommu = to_msm_iommu(mmu); > int ret; > > - pm_runtime_get_sync(mmu->dev); > + pm_runtime_get_suppliers(mmu->dev); > ret = iommu_attach_device(iommu->domain, mmu->dev); > - pm_runtime_put_sync(mmu->dev); > + pm_runtime_put_suppliers(mmu->dev); For me, it looks like a wrong place to handle runtime PM of IOMMU here. iommu_attach_device() calls into IOMMU driver's attach_device() callback and that's where necessary runtime PM gets should happen, if any. In other words, driver A (MSM DRM driver) shouldn't be dealing with power state of device controlled by driver B (ARM SMMU). This is also important for the reasons I stated in my comments to "[PATCH v7 1/6] base: power: runtime: Export pm_runtime_get/put_suppliers". Quoting for everyone's convenience: >> There are however cases in which the consumer wants to power-on >> the supplier, but not itself. >> E.g., A Graphics or multimedia driver wants to power-on the SMMU >> to unmap a buffer and finish the TLB operations without powering >> on itself. > >This sounds strange to me. If the SMMU is powered down, wouldn't the >TLB lose its contents as well (and so no flushing needed)? > >Other than that, what kind of hardware operations would be needed >besides just updating the page tables from the CPU? > In other words, the SMMU driver can deal with hardware state based on return value of pm_runtime_get_sync() or pm_runtime_get_if_in_use() and decide whether some operations are necessary or not, e.g. - a state restore is necessary if the domain was powered off, but we are bringing the master on, - a flush may not be required when (un)mapping with the domain powered off, - etc. Best regards, Tomasz ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[RFC] drm/atomic: Abuse legacy cursor update flag for legacy gamma update too
Programs like redshift set the legacy gamma for X.org every 5 seconds. Because atomic commits wait for vblank completion, we get a frame drop every 5 seconds because of the legacy gamma update. Work around this by setting the legacy_cursor_update flag, to force legacy gamma updates not to be synced against vblank. Reported-by: Tholin #intel-gfx Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/drm_atomic_helper.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index ae3cbfe9e01c..f37ab26ef4d2 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -3806,6 +3806,9 @@ int drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc, if (!state) return -ENOMEM; + /* Don't wait for vblank after updating gamma. */ + state->legacy_cursor_update = true; + blob = drm_property_create_blob(dev, sizeof(struct drm_color_lut) * size, NULL); -- 2.16.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [RFC] drm/atomic: Abuse legacy cursor update flag for legacy gamma update too
Quoting Maarten Lankhorst (2018-02-13 09:12:01) > Programs like redshift set the legacy gamma for X.org every 5 seconds. > Because atomic commits wait for vblank completion, we get a frame drop > every 5 seconds because of the legacy gamma update. > > Work around this by setting the legacy_cursor_update flag, to force > legacy gamma updates not to be synced against vblank. > > Reported-by: Tholin #intel-gfx > Signed-off-by: Maarten Lankhorst Reminiscing: Remember the time we had all those vblank workers patches, one of which was to do async gamma updates (apply the last one on the vblank). Motivated by gnome-shell and the ilk doing a gamma animation for fade-out on logout (which I guess they gave up on since it happened to be so slow as to extend logout ;). -Chris ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: WARNING in drm_modeset_lock_all
On Tue, Oct 31, 2017 at 2:03 PM, Dmitry Vyukov wrote: > On Tue, Oct 31, 2017 at 3:45 PM, Chris Wilson > wrote: >> Quoting syzbot (2017-10-27 09:09:50) >>> This bug is generated by a dumb bot. It may contain errors. >>> See https://goo.gl/tpsmEJ for details. >>> Direct all questions to syzkal...@googlegroups.com. >>> >>> syzbot will keep track of this bug report. >>> Once a fix for this bug is committed, please reply to this email with: >>> #syz fix: exact-commit-title >>> To mark this as a duplicate of another syzbot report, please reply with: >>> #syz dup: exact-subject-of-another-report >>> If it's a one-off invalid bug report, please reply with: >>> #syz invalid >>> Note: if the crash happens again, it will cause creation of a new bug >>> report. >> >> Can we use >> >> Reported-by: syzbot >> >> >> as a unique tag for tracking purposes? > > > Hi, > > Seems to be a common question. I've added the following to bug template: > > Please credit me with: Reported-by: syzbot > > will now be present on newly reported bugs: > > https://groups.google.com/forum/#!topic/syzkaller-bugs/XE8YSiSZDdA This was fixed by: #syz fix: drm: Require __GFP_NOFAIL for the legacy drm_modeset_lock_all Now we indeed can use: Reported-by: syzbot which avoids the need to go back and manually attach fixing commit to the report like this. ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 2/4] drm/mxsfb: Do not use deprecated drm_driver.{enable|disable)_vblank
On 02/12/2018 09:52 AM, Oleksandr Andrushchenko wrote: > From: Oleksandr Andrushchenko > > Do not use deprecated drm_driver.{enable|disable)_vblank callbacks, > but use drm_simple_kms_helpe's pipe callbacks instead. > > Signed-off-by: Oleksandr Andrushchenko > Cc: Marek Vasut Reviewed-by: Marek Vasut > --- > drivers/gpu/drm/mxsfb/mxsfb_drv.c | 54 > --- > 1 file changed, 28 insertions(+), 26 deletions(-) > > diff --git a/drivers/gpu/drm/mxsfb/mxsfb_drv.c > b/drivers/gpu/drm/mxsfb/mxsfb_drv.c > index 1207ffe36250..5cae8db9dcd4 100644 > --- a/drivers/gpu/drm/mxsfb/mxsfb_drv.c > +++ b/drivers/gpu/drm/mxsfb/mxsfb_drv.c > @@ -131,11 +131,37 @@ static int mxsfb_pipe_prepare_fb(struct > drm_simple_display_pipe *pipe, > return drm_gem_fb_prepare_fb(&pipe->plane, plane_state); > } > > +static int mxsfb_pipe_enable_vblank(struct drm_simple_display_pipe *pipe) > +{ > + struct mxsfb_drm_private *mxsfb = drm_pipe_to_mxsfb_drm_private(pipe); > + > + /* Clear and enable VBLANK IRQ */ > + mxsfb_enable_axi_clk(mxsfb); > + writel(CTRL1_CUR_FRAME_DONE_IRQ, mxsfb->base + LCDC_CTRL1 + REG_CLR); > + writel(CTRL1_CUR_FRAME_DONE_IRQ_EN, mxsfb->base + LCDC_CTRL1 + REG_SET); > + mxsfb_disable_axi_clk(mxsfb); > + > + return 0; > +} > + > +static void mxsfb_pipe_disable_vblank(struct drm_simple_display_pipe *pipe) > +{ > + struct mxsfb_drm_private *mxsfb = drm_pipe_to_mxsfb_drm_private(pipe); > + > + /* Disable and clear VBLANK IRQ */ > + mxsfb_enable_axi_clk(mxsfb); > + writel(CTRL1_CUR_FRAME_DONE_IRQ_EN, mxsfb->base + LCDC_CTRL1 + REG_CLR); > + writel(CTRL1_CUR_FRAME_DONE_IRQ, mxsfb->base + LCDC_CTRL1 + REG_CLR); > + mxsfb_disable_axi_clk(mxsfb); > +} > + > static struct drm_simple_display_pipe_funcs mxsfb_funcs = { > .enable = mxsfb_pipe_enable, > .disable= mxsfb_pipe_disable, > .update = mxsfb_pipe_update, > .prepare_fb = mxsfb_pipe_prepare_fb, > + .enable_vblank = mxsfb_pipe_enable_vblank, > + .disable_vblank = mxsfb_pipe_disable_vblank, > }; > > static int mxsfb_load(struct drm_device *drm, unsigned long flags) > @@ -274,33 +300,11 @@ static void mxsfb_lastclose(struct drm_device *drm) > drm_fbdev_cma_restore_mode(mxsfb->fbdev); > } > > -static int mxsfb_enable_vblank(struct drm_device *drm, unsigned int crtc) > -{ > - struct mxsfb_drm_private *mxsfb = drm->dev_private; > - > - /* Clear and enable VBLANK IRQ */ > - mxsfb_enable_axi_clk(mxsfb); > - writel(CTRL1_CUR_FRAME_DONE_IRQ, mxsfb->base + LCDC_CTRL1 + REG_CLR); > - writel(CTRL1_CUR_FRAME_DONE_IRQ_EN, mxsfb->base + LCDC_CTRL1 + REG_SET); > - mxsfb_disable_axi_clk(mxsfb); > - > - return 0; > -} > - > -static void mxsfb_disable_vblank(struct drm_device *drm, unsigned int crtc) > +static void mxsfb_irq_preinstall(struct drm_device *drm) > { > struct mxsfb_drm_private *mxsfb = drm->dev_private; > > - /* Disable and clear VBLANK IRQ */ > - mxsfb_enable_axi_clk(mxsfb); > - writel(CTRL1_CUR_FRAME_DONE_IRQ_EN, mxsfb->base + LCDC_CTRL1 + REG_CLR); > - writel(CTRL1_CUR_FRAME_DONE_IRQ, mxsfb->base + LCDC_CTRL1 + REG_CLR); > - mxsfb_disable_axi_clk(mxsfb); > -} > - > -static void mxsfb_irq_preinstall(struct drm_device *drm) > -{ > - mxsfb_disable_vblank(drm, 0); > + mxsfb_pipe_disable_vblank(&mxsfb->pipe); > } > > static irqreturn_t mxsfb_irq_handler(int irq, void *data) > @@ -333,8 +337,6 @@ static struct drm_driver mxsfb_driver = { > .irq_handler= mxsfb_irq_handler, > .irq_preinstall = mxsfb_irq_preinstall, > .irq_uninstall = mxsfb_irq_preinstall, > - .enable_vblank = mxsfb_enable_vblank, > - .disable_vblank = mxsfb_disable_vblank, > .gem_free_object_unlocked = drm_gem_cma_free_object, > .gem_vm_ops = &drm_gem_cma_vm_ops, > .dumb_create= drm_gem_cma_dumb_create, > -- Best regards, Marek Vasut ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm/rockchip: Don't use spin_lock_irqsave in interrupt context
Hi Heiko, On 10/02/18 16:23, Heiko Stuebner wrote: > Hi Marc, > > Am Samstag, 10. Februar 2018, 15:35:01 CET schrieb Marc Zyngier: >> The rockchip DRM driver is quite careful to disable interrupts >> when taking a lock that is also taken in interrupt context, >> which is a good thing. >> >> What is a bit over the top is to use spin_lock_irqsave when >> already in interrupt context, as you cannot take another >> interrupt again, and disabling interrupt is just pure >> overhead. >> >> Switching to the non _irqsave version in interrupt context is >> more logical, and less heavy handed. >> >> Signed-off-by: Marc Zyngier > > please note, that we had a maintainer swap for the Rockchip drm-component, > where Sandy replaced Mark [0] ... with me acting as sort-of (and not yet > up to speed) backup. > > So I guess Rockchip drm patches should also include > Sandy Huang I guess that update didn't make it into 4.15, which is why I didn't spot it. I'll repost the patches shortly including Sandy on Cc. 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: [RFC] drm/atomic: Abuse legacy cursor update flag for legacy gamma update too
Hey, Op 13-02-18 om 10:16 schreef Chris Wilson: > Quoting Maarten Lankhorst (2018-02-13 09:12:01) >> Programs like redshift set the legacy gamma for X.org every 5 seconds. >> Because atomic commits wait for vblank completion, we get a frame drop >> every 5 seconds because of the legacy gamma update. >> >> Work around this by setting the legacy_cursor_update flag, to force >> legacy gamma updates not to be synced against vblank. >> >> Reported-by: Tholin #intel-gfx >> Signed-off-by: Maarten Lankhorst > Reminiscing: Remember the time we had all those vblank workers patches, > one of which was to do async gamma updates (apply the last one on the > vblank). Motivated by gnome-shell and the ilk doing a gamma animation > for fade-out on logout (which I guess they gave up on since it happened > to be so slow as to extend logout ;). That special case could be handled by userspace with atomic commits, I don't think it's worth optimizing it further.. ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [RFC][PATCH 4/4 v2] drm_hwcomposer: Try to fallback if GLCompisition fails
On Mon, Feb 12, 2018 at 08:43:10PM -0800, John Stultz wrote: > On Wed, Jan 31, 2018 at 11:03 AM, John Stultz wrote: > > On Wed, Jan 31, 2018 at 10:51 AM, Alexandru-Cosmin Gheorghe > > wrote: > >> It seems that we don't pass any explicit fences to the kernel for > >> IN_FENCE_FD property. This particular line seems wrong. > >> > >> @@ -593,14 +594,17 @@ int > >> DrmDisplayCompositor::CommitFrame(DrmDisplayComposition *display_comp, > >>else > >> rotation |= DRM_MODE_ROTATE_0; > >> > >> - if (fence_fd < 0) { > >> + if (fence_fd >= 0) { > > > > I'll give that a whirl. > > So I did give that a whirl after you suggested it, but it ended up > causing nothing to be displayed, and I unfortunately didn't have time > right then to dig much further. > > Rob however re-found this issue today, and I've been digging a bit > more. At least with the HiKey board, it seem the trouble is when the > IN_FENCE_FD is added to the pset, the atomic commit calls start to > fail. I dug in and it seems we're catching in the kernel on the if > (file->f_op != &sync_file_fops) check in sync_file_fdget(). > > I'm now trying to trace back to where the in fence was provided from > to see what might be going wrong there. I would be surprised if this fence is not created by the GPU driver. But, the whole Android stack is new to me, so I might be wrong. > > Curious if this is anything you ran across in your attempts? Sorry, on Hikey960, I don't have this problem. Are you using the same 4.9 kernel from your branch(hikey-hwcomposer-deps)? > > thanks > -john Regards, Alex Gheorghe IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you. ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [Mesa-dev] [PATCH 6/7] vulkan: Add new VK_MESA_query_timestamp extension
On 13/02/18 00:20, Dylan Baker wrote: Quoting Keith Packard (2018-02-09 20:45:15) This extension adds a single function to query the current GPU timestamp, just like glGetInteger64v(GL_TIMESTAMP, ×tamp). This function is needed to complete the implementation of GOOGLE_display_timing, which needs to be able to coorelate GPU and CPU timestamps. I'm assuming the correlation is done outside the vulkan driver? With a clock_gettime() maybe? If that's the case, I'm afraid this will be highly inaccurate. The kernel might execute other tasks when the ioctl() happens and that might introduce (in my experience) a few milliseconds of delay. I think if you want to do something like that, this has to be implemented in the kernel, making sure you disable interruptions while doing the correlation. Signed-off-by: Keith Packard --- include/vulkan/vulkan.h | 6 ++ src/Makefile.am | 1 + src/amd/vulkan/Makefile.am | 3 +++ src/amd/vulkan/meson.build | 8 src/amd/vulkan/radv_device.c| 8 src/amd/vulkan/radv_extensions.py | 1 + src/intel/Makefile.vulkan.am| 7 +++ src/intel/vulkan/anv_extensions.py | 1 + src/intel/vulkan/anv_gem.c | 13 + src/intel/vulkan/anv_private.h | 1 + src/intel/vulkan/genX_query.c | 15 +++ src/intel/vulkan/meson.build| 12 ++-- src/vulkan/meson.build | 1 + src/vulkan/registry/vk_mesa_query_timestamp.xml | 22 ++ 14 files changed, 89 insertions(+), 10 deletions(-) create mode 100644 src/vulkan/registry/vk_mesa_query_timestamp.xml diff --git a/include/vulkan/vulkan.h b/include/vulkan/vulkan.h index d3e2e246cf3..5523eb7586f 100644 --- a/include/vulkan/vulkan.h +++ b/include/vulkan/vulkan.h @@ -7025,6 +7025,12 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryHostPointerPropertiesEXT( VkMemoryHostPointerPropertiesEXT* pMemoryHostPointerProperties); #endif +typedef VkResult (VKAPI_PTR *PFN_vkQueryCurrentTimestampMESA)(VkDevice device, uint64_t *timestamp); + +VKAPI_ATTR VkResult VKAPI_CALL vkQueryCurrentTimestampMESA( +VkDevice_device, +uint64_t*timestamp); + #ifdef __cplusplus } #endif diff --git a/src/Makefile.am b/src/Makefile.am index 014ffaf3e29..74ff305d7c6 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -68,6 +68,7 @@ endif EXTRA_DIST += vulkan/registry/vk.xml EXTRA_DIST += vulkan/registry/vk_android_native_buffer.xml +EXTRA_DIST += vulkan/registry/vk_mesa_query_timestamp.xml if HAVE_AMD_DRIVERS SUBDIRS += amd diff --git a/src/amd/vulkan/Makefile.am b/src/amd/vulkan/Makefile.am index 94ece06e99e..0626fa2b3b3 100644 --- a/src/amd/vulkan/Makefile.am +++ b/src/amd/vulkan/Makefile.am @@ -129,12 +129,14 @@ libvulkan_radeon_la_SOURCES = $(VULKAN_GEM_FILES) vulkan_api_xml = $(top_srcdir)/src/vulkan/registry/vk.xml vk_android_native_buffer_xml = $(top_srcdir)/src/vulkan/registry/vk_android_native_buffer.xml +vk_mesa_query_timestamp_xml = $(top_srcdir)/src/vulkan/registry/vk_mesa_query_timestamps.xml radv_entrypoints.c: radv_entrypoints_gen.py radv_extensions.py $(vulkan_api_xml) $(MKDIR_GEN) $(AM_V_GEN)$(PYTHON2) $(srcdir)/radv_entrypoints_gen.py \ --xml $(vulkan_api_xml) \ --xml $(vk_android_native_buffer_xml) \ + --xml $(vk_mesa_query_timestamp_xml) \ --outdir $(builddir) radv_entrypoints.h: radv_entrypoints.c @@ -144,6 +146,7 @@ radv_extensions.c: radv_extensions.py \ $(AM_V_GEN)$(PYTHON2) $(srcdir)/radv_extensions.py \ --xml $(vulkan_api_xml) \ --xml $(vk_android_native_buffer_xml) \ + --xml $(vk_mesa_query_timestamp_xml) \ --out $@ vk_format_table.c: vk_format_table.py \ diff --git a/src/amd/vulkan/meson.build b/src/amd/vulkan/meson.build index 0b92a1763a1..34f578476c0 100644 --- a/src/amd/vulkan/meson.build +++ b/src/amd/vulkan/meson.build @@ -20,10 +20,10 @@ radv_entrypoints = custom_target( 'radv_entrypoints.[ch]', - input : ['radv_entrypoints_gen.py', vk_api_xml], + input : ['radv_entrypoints_gen.py', vk_api_xml, vk_android_native_buffer_xml, vk_mesa_query_timestamp_xml], some of these lines look a little long, input : [ 'radv_entrypoints_gen.py', vk_api_xml, vk_android_native_buffer_xml, vk_mesa_query_timestamp_xml, ], output : ['radv_entrypoints.h', 'radv_entrypoints.c'], command : [ -prog_python2, '@INPUT0@', '--xml', '@INPUT1@', '--outdir', +prog_python2, '@INPUT0@', '--xml', '@INPUT1@', '--xml', '@INPUT2@', '--xml', '@INPUT3@', '--outdir', meson.current_b
Re: [PATCH 0/5] Fix deadlock on runtime suspend in DRM drivers
Hi Lukas, On Sun, Feb 11, 2018 at 10:38:28AM +0100, Lukas Wunner wrote: > Fix a deadlock on hybrid graphics laptops that's been present since 2013: > > DRM drivers poll connectors in 10 sec intervals. The poll worker is > stopped on ->runtime_suspend with cancel_delayed_work_sync(). However > the poll worker invokes the DRM drivers' ->detect callbacks, which call > pm_runtime_get_sync(). If the poll worker starts after runtime suspend > has begun, pm_runtime_get_sync() will wait for runtime suspend to finish > with the intention of runtime resuming the device afterwards. The result > is a circular wait between poll worker and autosuspend worker. > > I'm seeing this deadlock so often it's not funny anymore. I've also found > 3 nouveau bugzillas about it and 1 radeon bugzilla. (See patch [3/5] and > [4/5].) > > One theoretical solution would be to add a flag to the ->detect callback > to tell it that it's running in the poll worker's context. In that case > it doesn't need to call pm_runtime_get_sync() because the poll worker is > only enabled while runtime active and we know that ->runtime_suspend > waits for it to finish. But this approach would require touching every > single DRM driver's ->detect hook. Moreover the ->detect hook is called > from numerous other places, both in the DRM library as well as in each > driver, making it necessary to trace every possible call chain and check > if it's coming from the poll worker or not. I've tried to do that for > nouveau (see the call sites listed in the commit message of patch [3/5]) > and concluded that this approach is a nightmare to implement. > > Another reason for the infeasibility of this approach is that ->detect > is called from within the DRM library without driver involvement, e.g. > via DRM's sysfs interface. In those cases, pm_runtime_get_sync() would > have to be called by the DRM library, but the DRM library is supposed to > stay generic, wheras runtime PM is driver-specific. > > So instead, I've come up with this much simpler solution which gleans > from the current task's flags if it's a workqueue worker, retrieves the > work_struct and checks if it's the poll worker. All that's needed is > one small helper in the workqueue code and another small helper in the > DRM library. This solution lends itself nicely to stable-backporting. > > The patches for radeon and amdgpu are compile-tested only, I only have a > MacBook Pro with an Nvidia GK107 to test. To test the patches, add an > "msleep(12*1000);" at the top of the driver's ->runtime_suspend hook. > This ensures that the poll worker runs after ->runtime_suspend has begun. > Wait 12 sec after the GPU has begun runtime suspend, then check > /sys/bus/pci/devices/:01:00.0/power/runtime_status. Without this > series, the status will be stuck at "suspending" and you'll get hung task > errors in dmesg after a few minutes. > > i915, malidp and msm "solved" this issue by not stopping the poll worker > on runtime suspend. But this results in the GPU bouncing back and forth > between D0 and D3 continuously. That's a total no-go for GPUs which > runtime suspend to D3cold since every suspend/resume cycle costs a > significant amount of time and energy. (i915 and malidp do not seem > to acquire a runtime PM ref in the ->detect callbacks, which seems > questionable. msm however does and would also deadlock if it disabled > the poll worker on runtime suspend. cc += Archit, Liviu, intel-gfx) I think I understand the problem you are trying to solve, but I'm struggling to understand where malidp makes any specific mistakes. First of all, malidp is only a display engine, so there is no GPU attached to it, but that is only a small clarification. Second, malidp doesn't use directly any of the callbacks that you are referring to, it uses the drm_cma_() API plus the generic drm_() call. So if there are any issues there (as they might well be) I think they would apply to a lot more drivers and the fix will involve more than just malidp, i915 and msm. Would love to get any clarifications on what I might have misunderstood. Best regards, Liviu > > Please review. Thanks, > > Lukas > > Lukas Wunner (5): > workqueue: Allow retrieval of current task's work struct > drm: Allow determining if current task is output poll worker > drm/nouveau: Fix deadlock on runtime suspend > drm/radeon: Fix deadlock on runtime suspend > drm/amdgpu: Fix deadlock on runtime suspend > > drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c | 58 +--- > drivers/gpu/drm/drm_probe_helper.c | 14 + > drivers/gpu/drm/nouveau/nouveau_connector.c| 18 +-- > drivers/gpu/drm/radeon/radeon_connectors.c | 74 > +- > include/drm/drm_crtc_helper.h | 1 + > include/linux/workqueue.h | 1 + > kernel/workqueue.c | 16 ++ > 7 files changed, 132 insertions(+), 50 deletions(-
[Bug 105072] Texture corruption covering screen
https://bugs.freedesktop.org/show_bug.cgi?id=105072 Bug ID: 105072 Summary: Texture corruption covering screen Product: Mesa Version: 17.3 Hardware: x86-64 (AMD64) OS: Linux (All) Status: NEW Severity: normal Priority: medium Component: Drivers/Gallium/radeonsi Assignee: dri-devel@lists.freedesktop.org Reporter: sup...@gmail.com QA Contact: dri-devel@lists.freedesktop.org I tried to play "We need to go deeper" and the menu runs fine, but in game there looks to be some sort of post effect which uses a corrupt texture. I also get a similar problem in silent hunter III, so it is possibly the same bug as this: https://bugs.freedesktop.org/show_bug.cgi?id=104549 I run both of these games through wine. I tried "We need to go deeper" on a Intel iGPU and it ran fine. -- You are receiving this mail because: You are the assignee for the bug.___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 0/5] Fix deadlock on runtime suspend in DRM drivers
On Tue, Feb 13, 2018 at 10:55:06AM +, Liviu Dudau wrote: > On Sun, Feb 11, 2018 at 10:38:28AM +0100, Lukas Wunner wrote: > > DRM drivers poll connectors in 10 sec intervals. The poll worker is > > stopped on ->runtime_suspend with cancel_delayed_work_sync(). However > > the poll worker invokes the DRM drivers' ->detect callbacks, which call > > pm_runtime_get_sync(). If the poll worker starts after runtime suspend > > has begun, pm_runtime_get_sync() will wait for runtime suspend to finish > > with the intention of runtime resuming the device afterwards. The result > > is a circular wait between poll worker and autosuspend worker. > > I think I understand the problem you are trying to solve, but I'm > struggling to understand where malidp makes any specific mistakes. First > of all, malidp is only a display engine, so there is no GPU attached to > it, but that is only a small clarification. Second, malidp doesn't use > directly any of the callbacks that you are referring to, it uses the > drm_cma_() API plus the generic drm_() call. So if there are any > issues there (as they might well be) I think they would apply to a lot > more drivers and the fix will involve more than just malidp, i915 and > msm. I don't know if malidp makes any specific mistakes and didn't mean to cast it in a negative light, sorry. So a lot of DRM drivers acquire a runtime PM ref in the connector ->detect hook because they can't probe connectors while runtime suspended. E.g. for a PCI device, probing might require mmio access, which isn't possible outside of power state D0. There are no ->detect hooks declared in drivers/gpu/drm/arm/, so it's unclear to me whether you're able to probe during runtime suspend. hdlcd_drv.c and malidp_drv.c both enable output polling. Output polling is only necessary if you don't get HPD interrupts. You're not disabling polling upon runtime suspend. Thus, if a runtime PM ref is acquired during polling (such as in a ->detect hook), the GPU will be runtime resumed every 10 secs. You may want to verify that's not the case. If you decide that you do want to stop polling during runtime suspend because it runtime resumes the GPU continuously, you'll need the helper introduced in this series. So by cc'ing you I just wanted to keep you in the loop about an issue that may potentially affect your driver. Let me know if there are any questions. Thanks, Lukas ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 04/30] drm: omapdrm: dss: Pass PLL pointer to dss_ctrl_pll_enable()
This will allow accessing the PLL data to get the DSS device pointer, removing the need to access the global DSS private data. Signed-off-by: Laurent Pinchart Reviewed-by: Sebastian Reichel --- drivers/gpu/drm/omapdrm/dss/dss.c | 13 +++-- drivers/gpu/drm/omapdrm/dss/dss.h | 2 +- drivers/gpu/drm/omapdrm/dss/hdmi_pll.c | 4 ++-- drivers/gpu/drm/omapdrm/dss/video-pll.c | 6 +++--- 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/dss/dss.c b/drivers/gpu/drm/omapdrm/dss/dss.c index 6c28e13d9ae0..29c3a0dba698 100644 --- a/drivers/gpu/drm/omapdrm/dss/dss.c +++ b/drivers/gpu/drm/omapdrm/dss/dss.c @@ -152,17 +152,17 @@ static void dss_restore_context(void) #undef SR #undef RR -void dss_ctrl_pll_enable(enum dss_pll_id pll_id, bool enable) +void dss_ctrl_pll_enable(struct dss_pll *pll, bool enable) { unsigned int shift; unsigned int val; - if (!dss.syscon_pll_ctrl) + if (!pll->dss->syscon_pll_ctrl) return; val = !enable; - switch (pll_id) { + switch (pll->id) { case DSS_PLL_VIDEO1: shift = 0; break; @@ -173,12 +173,13 @@ void dss_ctrl_pll_enable(enum dss_pll_id pll_id, bool enable) shift = 2; break; default: - DSSERR("illegal DSS PLL ID %d\n", pll_id); + DSSERR("illegal DSS PLL ID %d\n", pll->id); return; } - regmap_update_bits(dss.syscon_pll_ctrl, dss.syscon_pll_ctrl_offset, - 1 << shift, val << shift); + regmap_update_bits(pll->dss->syscon_pll_ctrl, + pll->dss->syscon_pll_ctrl_offset, + 1 << shift, val << shift); } static int dss_ctrl_pll_set_control_mux(enum dss_clk_source clk_src, diff --git a/drivers/gpu/drm/omapdrm/dss/dss.h b/drivers/gpu/drm/omapdrm/dss/dss.h index a7aeb0e7e1ae..ea3eb6b0e7f1 100644 --- a/drivers/gpu/drm/omapdrm/dss/dss.h +++ b/drivers/gpu/drm/omapdrm/dss/dss.h @@ -310,7 +310,7 @@ struct dss_pll *dss_video_pll_init(struct dss_device *dss, struct regulator *regulator); void dss_video_pll_uninit(struct dss_pll *pll); -void dss_ctrl_pll_enable(enum dss_pll_id pll_id, bool enable); +void dss_ctrl_pll_enable(struct dss_pll *pll, bool enable); void dss_sdi_init(int datapairs); int dss_sdi_enable(void); diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi_pll.c b/drivers/gpu/drm/omapdrm/dss/hdmi_pll.c index 8ee9743e6fcf..4fb97cd0cc8d 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi_pll.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi_pll.c @@ -48,7 +48,7 @@ static int hdmi_pll_enable(struct dss_pll *dsspll) r = pm_runtime_get_sync(&pll->pdev->dev); WARN_ON(r < 0); - dss_ctrl_pll_enable(DSS_PLL_HDMI, true); + dss_ctrl_pll_enable(dsspll, true); r = hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_BOTHON_ALLCLKS); if (r) @@ -65,7 +65,7 @@ static void hdmi_pll_disable(struct dss_pll *dsspll) hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_ALLOFF); - dss_ctrl_pll_enable(DSS_PLL_HDMI, false); + dss_ctrl_pll_enable(dsspll, false); r = pm_runtime_put_sync(&pll->pdev->dev); WARN_ON(r < 0 && r != -ENOSYS); diff --git a/drivers/gpu/drm/omapdrm/dss/video-pll.c b/drivers/gpu/drm/omapdrm/dss/video-pll.c index 12997668730c..344e7e0bbc4e 100644 --- a/drivers/gpu/drm/omapdrm/dss/video-pll.c +++ b/drivers/gpu/drm/omapdrm/dss/video-pll.c @@ -68,7 +68,7 @@ static int dss_video_pll_enable(struct dss_pll *pll) if (r) return r; - dss_ctrl_pll_enable(pll->id, true); + dss_ctrl_pll_enable(pll, true); dss_dpll_enable_scp_clk(vpll); @@ -82,7 +82,7 @@ static int dss_video_pll_enable(struct dss_pll *pll) err_reset: dss_dpll_disable_scp_clk(vpll); - dss_ctrl_pll_enable(pll->id, false); + dss_ctrl_pll_enable(pll, false); dss_runtime_put(pll->dss); return r; @@ -96,7 +96,7 @@ static void dss_video_pll_disable(struct dss_pll *pll) dss_dpll_disable_scp_clk(vpll); - dss_ctrl_pll_enable(pll->id, false); + dss_ctrl_pll_enable(pll, false); dss_runtime_put(pll->dss); } -- Regards, Laurent Pinchart ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 03/30] drm: omapdrm: dss: Pass DSS private structure to runtime PM functions
To prepare for the removal of the global variable storing DSS private data, pass its pointer to the dss_runtime_{get,put}() functions. As this requires getting hold of the dss_device structure in the callers, we add a new dss_get_device() function to retrieve it. The function currently returns a pointer to the global data structure, and will later be updated to get the pointer from device driver data when the DSS private structure will be allocated dynamically. Signed-off-by: Laurent Pinchart Reviewed-by: Sebastian Reichel --- drivers/gpu/drm/omapdrm/dss/dsi.c | 7 +++-- drivers/gpu/drm/omapdrm/dss/dss.c | 47 +++-- drivers/gpu/drm/omapdrm/dss/dss.h | 12 ++--- drivers/gpu/drm/omapdrm/dss/hdmi.h | 6 +++-- drivers/gpu/drm/omapdrm/dss/hdmi4.c | 3 ++- drivers/gpu/drm/omapdrm/dss/hdmi5.c | 3 ++- drivers/gpu/drm/omapdrm/dss/hdmi_pll.c | 10 --- drivers/gpu/drm/omapdrm/dss/video-pll.c | 12 + 8 files changed, 61 insertions(+), 39 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c index 41d500eea843..7ba33fc5d245 100644 --- a/drivers/gpu/drm/omapdrm/dss/dsi.c +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c @@ -5322,7 +5322,8 @@ static const struct dss_pll_hw dss_omap5_dsi_pll_hw = { .has_refsel = true, }; -static int dsi_init_pll_data(struct platform_device *dsidev) +static int dsi_init_pll_data(struct dss_device *dss, +struct platform_device *dsidev) { struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); struct dss_pll *pll = &dsi->pll; @@ -5341,6 +5342,7 @@ static int dsi_init_pll_data(struct platform_device *dsidev) pll->base = dsi->pll_base; pll->hw = dsi->data->pll_hw; pll->ops = &dsi_pll_ops; + pll->dss = dss; r = dss_pll_register(pll); if (r) @@ -5417,6 +5419,7 @@ static const struct soc_device_attribute dsi_soc_devices[] = { static int dsi_bind(struct device *dev, struct device *master, void *data) { struct platform_device *dsidev = to_platform_device(dev); + struct dss_device *dss = dss_get_device(master); const struct soc_device_attribute *soc; const struct dsi_module_id_data *d; u32 rev; @@ -5525,7 +5528,7 @@ static int dsi_bind(struct device *dev, struct device *master, void *data) if (r) return r; - dsi_init_pll_data(dsidev); + dsi_init_pll_data(dss, dsidev); pm_runtime_enable(&dsidev->dev); diff --git a/drivers/gpu/drm/omapdrm/dss/dss.c b/drivers/gpu/drm/omapdrm/dss/dss.c index 245d8c0ae461..6c28e13d9ae0 100644 --- a/drivers/gpu/drm/omapdrm/dss/dss.c +++ b/drivers/gpu/drm/omapdrm/dss/dss.c @@ -345,7 +345,7 @@ static void dss_dump_clocks(struct seq_file *s) const char *fclk_name; unsigned long fclk_rate; - if (dss_runtime_get()) + if (dss_runtime_get(&dss)) return; seq_printf(s, "- DSS -\n"); @@ -357,7 +357,7 @@ static void dss_dump_clocks(struct seq_file *s) fclk_name, fclk_rate); - dss_runtime_put(); + dss_runtime_put(&dss); } #endif @@ -365,7 +365,7 @@ static void dss_dump_regs(struct seq_file *s) { #define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dss_read_reg(r)) - if (dss_runtime_get()) + if (dss_runtime_get(&dss)) return; DUMPREG(DSS_REVISION); @@ -379,7 +379,7 @@ static void dss_dump_regs(struct seq_file *s) DUMPREG(DSS_SDI_STATUS); } - dss_runtime_put(); + dss_runtime_put(&dss); #undef DUMPREG } @@ -837,27 +837,32 @@ static void dss_put_clocks(void) clk_put(dss.parent_clk); } -int dss_runtime_get(void) +int dss_runtime_get(struct dss_device *dss) { int r; DSSDBG("dss_runtime_get\n"); - r = pm_runtime_get_sync(&dss.pdev->dev); + r = pm_runtime_get_sync(&dss->pdev->dev); WARN_ON(r < 0); return r < 0 ? r : 0; } -void dss_runtime_put(void) +void dss_runtime_put(struct dss_device *dss) { int r; DSSDBG("dss_runtime_put\n"); - r = pm_runtime_put_sync(&dss.pdev->dev); + r = pm_runtime_put_sync(&dss->pdev->dev); WARN_ON(r < 0 && r != -ENOSYS && r != -EBUSY); } +struct dss_device *dss_get_device(struct device *dev) +{ + return &dss; +} + /* DEBUGFS */ #if defined(CONFIG_OMAP2_DSS_DEBUGFS) static void dss_debug_dump_clocks(struct seq_file *s) @@ -1223,13 +1228,15 @@ static int dss_video_pll_probe(struct platform_device *pdev) } if (of_property_match_string(np, "reg-names", "pll1") >= 0) { - dss.video1_pll = dss_video_pll_init(pdev, 0, pll_regulator); + dss.video1_pll = dss_video_pll_init(&dss, pdev, 0, + pll_regulator); if (IS_ERR(dss.video1_pll))
[PATCH v2 01/30] drm: omapdrm: Split init and cleanup from probe and remove functions
When merging the omapdrm and omapdss drivers there will be not omapdrm platform device anymore, and thus no associated probe and remove functions. To prepare for that, split all the initialization code from the probe function to make it usable without a platform device. Similarly, split the cleanup code from the remove function. Signed-off-by: Laurent Pinchart Reviewed-by: Sebastian Reichel --- drivers/gpu/drm/omapdrm/omap_drv.c | 83 +++--- drivers/gpu/drm/omapdrm/omap_drv.h | 2 + 2 files changed, 53 insertions(+), 32 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c index dd68b2556f5b..b571cc04e08d 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.c +++ b/drivers/gpu/drm/omapdrm/omap_drv.c @@ -510,24 +510,16 @@ static const struct soc_device_attribute omapdrm_soc_devices[] = { { /* sentinel */ } }; -static int pdev_probe(struct platform_device *pdev) +static int omapdrm_init(struct omap_drm_private *priv, struct device *dev) { const struct soc_device_attribute *soc; - struct omap_drm_private *priv; struct drm_device *ddev; unsigned int i; int ret; - DBG("%s", pdev->name); - - if (omapdss_is_initialized() == false) - return -EPROBE_DEFER; + DBG("%s", dev_name(dev)); - ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); - if (ret) { - dev_err(&pdev->dev, "Failed to set the DMA mask\n"); - return ret; - } + priv->dev = dev; omap_crtc_pre_init(); @@ -535,13 +527,6 @@ static int pdev_probe(struct platform_device *pdev) if (ret) goto err_crtc_uninit; - /* Allocate and initialize the driver private structure. */ - priv = kzalloc(sizeof(*priv), GFP_KERNEL); - if (!priv) { - ret = -ENOMEM; - goto err_disconnect_dssdevs; - } - priv->dispc_ops = dispc_get_ops(); soc = soc_device_match(omapdrm_soc_devices); @@ -552,14 +537,14 @@ static int pdev_probe(struct platform_device *pdev) INIT_LIST_HEAD(&priv->obj_list); /* Allocate and initialize the DRM device. */ - ddev = drm_dev_alloc(&omap_drm_driver, &pdev->dev); + ddev = drm_dev_alloc(&omap_drm_driver, priv->dev); if (IS_ERR(ddev)) { ret = PTR_ERR(ddev); - goto err_free_priv; + goto err_destroy_wq; } + priv->ddev = ddev; ddev->dev_private = priv; - platform_set_drvdata(pdev, ddev); /* Get memory bandwidth limits */ if (priv->dispc_ops->get_memory_bandwidth_limit) @@ -570,14 +555,14 @@ static int pdev_probe(struct platform_device *pdev) ret = omap_modeset_init(ddev); if (ret) { - dev_err(&pdev->dev, "omap_modeset_init failed: ret=%d\n", ret); + dev_err(priv->dev, "omap_modeset_init failed: ret=%d\n", ret); goto err_free_drm_dev; } /* Initialize vblank handling, start with all CRTCs disabled. */ ret = drm_vblank_init(ddev, priv->num_crtcs); if (ret) { - dev_err(&pdev->dev, "could not init vblank\n"); + dev_err(priv->dev, "could not init vblank\n"); goto err_cleanup_modeset; } @@ -610,20 +595,17 @@ static int pdev_probe(struct platform_device *pdev) err_free_drm_dev: omap_gem_deinit(ddev); drm_dev_unref(ddev); -err_free_priv: +err_destroy_wq: destroy_workqueue(priv->wq); - kfree(priv); -err_disconnect_dssdevs: omap_disconnect_dssdevs(); err_crtc_uninit: omap_crtc_pre_uninit(); return ret; } -static int pdev_remove(struct platform_device *pdev) +static void omapdrm_cleanup(struct omap_drm_private *priv) { - struct drm_device *ddev = platform_get_drvdata(pdev); - struct omap_drm_private *priv = ddev->dev_private; + struct drm_device *ddev = priv->ddev; DBG(""); @@ -645,10 +627,45 @@ static int pdev_remove(struct platform_device *pdev) drm_dev_unref(ddev); destroy_workqueue(priv->wq); - kfree(priv); omap_disconnect_dssdevs(); omap_crtc_pre_uninit(); +} + +static int pdev_probe(struct platform_device *pdev) +{ + struct omap_drm_private *priv; + int ret; + + if (omapdss_is_initialized() == false) + return -EPROBE_DEFER; + + ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); + if (ret) { + dev_err(&pdev->dev, "Failed to set the DMA mask\n"); + return ret; + } + + /* Allocate and initialize the driver private structure. */ + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + platform_set_drvdata(pdev, priv); + + ret = omapdrm_init(priv, &pdev->dev); + if (ret < 0) + kf
[PATCH v2 00/30] omapdrm: Allocate objects dynamically
Hello, Most of this series has previously been posted as part of "[PATCH 00/48] omapdrm: Merge omapdrm and omapdss". With "[PATCH v2 00/15] omapdrm: Miscellaneous fixes and cleanups" posted and merged a few days ago, it completes the rework of the omapdrm and omapdss drivers to replace most global variables with dynamically-allocated objects. The actual merge of the omapdrm and omapdss drivers has been left out for now as it still suffers from unresolved issues. As with the previous series I have other pending patches based on top of this, as passing driver objects around explicitly helps not relying on more global variables that would hinder the effort to move to the DRM bridge and DRM panel APIs. Patches 02/30, 14/30, 22/30 and 23/30 are new. Patch 21/30 has seen significant changes and I have thus dropped the Reviewed-by tag from Sebastian. All other patches have been rebased and reordered, thus sometimes modified to resolve conflicts, but have otherwise seen only minor changes. The series is based on top of the omapdrm-next branch from git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux.git. Tomi, as the series has been stripped of its controversial patches, I think it's now ready to be merged (pending review of the patches mentioned above of course). I have tested it on both a Panda board and an AM57xx EVM without any issues (and this time I made sure to try with the drivers compiled as modules). Laurent Pinchart (30): drm: omapdrm: Split init and cleanup from probe and remove functions drm: omapdrm: dss: Expose DSS data in a dss_device structure drm: omapdrm: dss: Pass DSS private structure to runtime PM functions drm: omapdrm: dss: Pass PLL pointer to dss_ctrl_pll_enable() drm: omapdrm: dss: Pass DSS pointer to dss_sdi_*() functions drm: omapdrm: dss: Pass DSS pointer to dss_ops operations drm: omapdrm: dss: Pass DSS pointer to dss_get_*_clk_source() drm: omapdrm: dss: Pass DSS pointer to dss clock functions drm: omapdrm: dss: Pass DSS pointer to remaining dss functions drm: omapdrm: dss: Allocate the DSS private data structure dynamically drm: omapdrm: dss: Support passing private data to debugfs show handlers drm: omapdrm: dss: Store the registered plls array in struct dss_device drm: omapdrm: dss: Store the debugfs root directory in struct dss_device drm: omapdrm: dss: Don't unnecessarily cast to dev to pdev and back drm: omapdrm: dsi: Pass the dsi_data pointer to internal functions drm: omapdrm: dsi: Combine two commonly used inline functions drm: omapdrm: dsi: Use dev pointer directly in dsi_bind() function drm: omapdrm: dsi: Store the struct device pointer in struct dsi_data drm: omapdrm: dsi: Don't pass channel to dispc init/uninit functions drm: omapdrm: dss: Pass omap_dss_device pointer to dss_mgr_*() functions drm: omapdrm: dss: Pass omap_drm_private pointer to dss_mgr_ops drm: omapdrm: dss: Store DSS device pointer in the omapdrm private data drm: omapdrm: dss: Store dispc ops in dss_device structure drm: omapdrm: dispc: Pass DISPC pointer to dispc_ops operations drm: omapdrm: dispc: Pass DISPC pointer to remaining dispc API functions drm: omapdrm: dispc: Allocate the dispc private data structure dynamically drm: omapdrm: hdmi4: Allocate the omap_hdmi data structure dynamically drm: omapdrm: hdmi5: Allocate the omap_hdmi data structure dynamically drm: omapdrm: sdi: Allocate the sdi private data structure dynamically drm: omapdrm: venc: Allocate the venc private data structure dynamically drivers/gpu/drm/omapdrm/dss/base.c | 27 +- drivers/gpu/drm/omapdrm/dss/dispc.c | 2183 -- drivers/gpu/drm/omapdrm/dss/dpi.c| 89 +- drivers/gpu/drm/omapdrm/dss/dsi.c| 1466 ++-- drivers/gpu/drm/omapdrm/dss/dss.c| 668 - drivers/gpu/drm/omapdrm/dss/dss.h| 229 ++-- drivers/gpu/drm/omapdrm/dss/hdmi.h | 11 +- drivers/gpu/drm/omapdrm/dss/hdmi4.c | 371 ++--- drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c |4 +- drivers/gpu/drm/omapdrm/dss/hdmi4_core.h |4 +- drivers/gpu/drm/omapdrm/dss/hdmi5.c | 379 +++--- drivers/gpu/drm/omapdrm/dss/hdmi_pll.c | 15 +- drivers/gpu/drm/omapdrm/dss/omapdss.h| 171 ++- drivers/gpu/drm/omapdrm/dss/output.c | 52 +- drivers/gpu/drm/omapdrm/dss/pll.c| 40 +- drivers/gpu/drm/omapdrm/dss/sdi.c| 162 ++- drivers/gpu/drm/omapdrm/dss/venc.c | 453 --- drivers/gpu/drm/omapdrm/dss/video-pll.c | 19 +- drivers/gpu/drm/omapdrm/omap_crtc.c | 62 +- drivers/gpu/drm/omapdrm/omap_crtc.h |2 +- drivers/gpu/drm/omapdrm/omap_drv.c | 102 +- drivers/gpu/drm/omapdrm/omap_drv.h |4 + drivers/gpu/drm/omapdrm/omap_irq.c | 32 +- drivers/gpu/drm/omapdrm/omap_plane.c | 12 +- 24 files changed, 3484 insertions(+), 3073 deletions(-) -- Regards, Laurent Pinchart __
[PATCH v2 05/30] drm: omapdrm: dss: Pass DSS pointer to dss_sdi_*() functions
This removes the need to access the global DSS private data in those functions (both for the current accesses and the future ones that will be introduced when allocating the DSS device dynamically). Signed-off-by: Laurent Pinchart Reviewed-by: Sebastian Reichel --- drivers/gpu/drm/omapdrm/dss/dss.c | 8 drivers/gpu/drm/omapdrm/dss/dss.h | 14 -- drivers/gpu/drm/omapdrm/dss/sdi.c | 13 - 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/dss/dss.c b/drivers/gpu/drm/omapdrm/dss/dss.c index 29c3a0dba698..c6a0b004b545 100644 --- a/drivers/gpu/drm/omapdrm/dss/dss.c +++ b/drivers/gpu/drm/omapdrm/dss/dss.c @@ -248,7 +248,7 @@ static int dss_ctrl_pll_set_control_mux(enum dss_clk_source clk_src, return 0; } -void dss_sdi_init(int datapairs) +void dss_sdi_init(struct dss_device *dss, int datapairs) { u32 l; @@ -267,7 +267,7 @@ void dss_sdi_init(int datapairs) dss_write_reg(DSS_PLL_CONTROL, l); } -int dss_sdi_enable(void) +int dss_sdi_enable(struct dss_device *dss) { unsigned long timeout; @@ -325,7 +325,7 @@ int dss_sdi_enable(void) return -ETIMEDOUT; } -void dss_sdi_disable(void) +void dss_sdi_disable(struct dss_device *dss) { dispc_lcd_enable_signal(0); @@ -1150,7 +1150,7 @@ static int dss_init_ports(struct platform_device *pdev) dpi_init_port(pdev, port, dss.feat->model); break; case OMAP_DISPLAY_TYPE_SDI: - sdi_init_port(pdev, port); + sdi_init_port(&dss, pdev, port); break; default: break; diff --git a/drivers/gpu/drm/omapdrm/dss/dss.h b/drivers/gpu/drm/omapdrm/dss/dss.h index ea3eb6b0e7f1..e560803b5127 100644 --- a/drivers/gpu/drm/omapdrm/dss/dss.h +++ b/drivers/gpu/drm/omapdrm/dss/dss.h @@ -312,9 +312,9 @@ void dss_video_pll_uninit(struct dss_pll *pll); void dss_ctrl_pll_enable(struct dss_pll *pll, bool enable); -void dss_sdi_init(int datapairs); -int dss_sdi_enable(void); -void dss_sdi_disable(void); +void dss_sdi_init(struct dss_device *dss, int datapairs); +int dss_sdi_enable(struct dss_device *dss); +void dss_sdi_disable(struct dss_device *dss); void dss_select_dsi_clk_source(int dsi_module, enum dss_clk_source clk_src); @@ -335,11 +335,13 @@ bool dss_div_calc(unsigned long pck, unsigned long fck_min, /* SDI */ #ifdef CONFIG_OMAP2_DSS_SDI -int sdi_init_port(struct platform_device *pdev, struct device_node *port); +int sdi_init_port(struct dss_device *dss, struct platform_device *pdev, + struct device_node *port); void sdi_uninit_port(struct device_node *port); #else -static inline int sdi_init_port(struct platform_device *pdev, - struct device_node *port) +static inline int sdi_init_port(struct dss_device *dss, + struct platform_device *pdev, + struct device_node *port) { return 0; } diff --git a/drivers/gpu/drm/omapdrm/dss/sdi.c b/drivers/gpu/drm/omapdrm/dss/sdi.c index d8ab31f3a813..f0564daa3831 100644 --- a/drivers/gpu/drm/omapdrm/dss/sdi.c +++ b/drivers/gpu/drm/omapdrm/dss/sdi.c @@ -31,6 +31,7 @@ static struct { struct platform_device *pdev; + struct dss_device *dss; bool update_enabled; struct regulator *vdds_sdi_reg; @@ -187,8 +188,8 @@ static int sdi_display_enable(struct omap_dss_device *dssdev) */ dispc_mgr_set_clock_div(channel, &sdi.mgr_config.clock_info); - dss_sdi_init(sdi.datapairs); - r = dss_sdi_enable(); + dss_sdi_init(sdi.dss, sdi.datapairs); + r = dss_sdi_enable(sdi.dss); if (r) goto err_sdi_enable; mdelay(2); @@ -200,7 +201,7 @@ static int sdi_display_enable(struct omap_dss_device *dssdev) return 0; err_mgr_enable: - dss_sdi_disable(); + dss_sdi_disable(sdi.dss); err_sdi_enable: err_set_dss_clock_div: err_calc_clock_div: @@ -217,7 +218,7 @@ static void sdi_display_disable(struct omap_dss_device *dssdev) dss_mgr_disable(channel); - dss_sdi_disable(); + dss_sdi_disable(sdi.dss); dispc_runtime_put(); @@ -345,7 +346,8 @@ static void sdi_uninit_output(struct platform_device *pdev) omapdss_unregister_output(out); } -int sdi_init_port(struct platform_device *pdev, struct device_node *port) +int sdi_init_port(struct dss_device *dss, struct platform_device *pdev, + struct device_node *port) { struct device_node *ep; u32 datapairs; @@ -362,6 +364,7 @@ int sdi_init_port(struct platform_device *pdev, struct device_node *port) } sdi.datapairs = datapairs; + sdi.dss = dss; of_node_put(ep); -- Regards, Laurent Pinchart ___ dri-devel mailing list dri-devel@lists.f
[PATCH v2 02/30] drm: omapdrm: dss: Expose DSS data in a dss_device structure
The anoonymous dss structure in dss.c is the top-level component in the omapdss driver. As such it should store all internal instance-specific data that is currently stored in global variables. This however requires both naming the structure to pass it around functions, and accessing it from various locations in the omapdss driver. While we could implement get and set functions for every field that needs to be accessed outside of dss.c, that would introduce overhead and complexity that we could avoid by exposing the structure to internal components of the omapdss driver. Do so to prepare for removal of global variables. Signed-off-by: Laurent Pinchart --- drivers/gpu/drm/omapdrm/dss/dss.c | 29 + drivers/gpu/drm/omapdrm/dss/dss.h | 29 + 2 files changed, 30 insertions(+), 28 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/dss/dss.c b/drivers/gpu/drm/omapdrm/dss/dss.c index d5490336e7c7..245d8c0ae461 100644 --- a/drivers/gpu/drm/omapdrm/dss/dss.c +++ b/drivers/gpu/drm/omapdrm/dss/dss.c @@ -48,8 +48,6 @@ #include "omapdss.h" #include "dss.h" -#define DSS_SZ_REGSSZ_512 - struct dss_reg { u16 idx; }; @@ -90,32 +88,7 @@ struct dss_features { bool has_lcd_clk_src; }; -static struct { - struct platform_device *pdev; - void __iomem*base; - struct regmap *syscon_pll_ctrl; - u32 syscon_pll_ctrl_offset; - - struct clk *parent_clk; - struct clk *dss_clk; - unsigned long dss_clk_rate; - - unsigned long cache_req_pck; - unsigned long cache_prate; - struct dispc_clock_info cache_dispc_cinfo; - - enum dss_clk_source dsi_clk_source[MAX_NUM_DSI]; - enum dss_clk_source dispc_clk_source; - enum dss_clk_source lcd_clk_source[MAX_DSS_LCD_MANAGERS]; - - boolctx_valid; - u32 ctx[DSS_SZ_REGS / sizeof(u32)]; - - const struct dss_features *feat; - - struct dss_pll *video1_pll; - struct dss_pll *video2_pll; -} dss; +static struct dss_device dss; static const char * const dss_generic_clk_source_names[] = { [DSS_CLK_SRC_FCK] = "FCK", diff --git a/drivers/gpu/drm/omapdrm/dss/dss.h b/drivers/gpu/drm/omapdrm/dss/dss.h index 7f3fa5330408..257ff7c62764 100644 --- a/drivers/gpu/drm/omapdrm/dss/dss.h +++ b/drivers/gpu/drm/omapdrm/dss/dss.h @@ -235,6 +235,35 @@ struct dss_lcd_mgr_config { struct seq_file; struct platform_device; +#define DSS_SZ_REGSSZ_512 + +struct dss_device { + struct platform_device *pdev; + void __iomem*base; + struct regmap *syscon_pll_ctrl; + u32 syscon_pll_ctrl_offset; + + struct clk *parent_clk; + struct clk *dss_clk; + unsigned long dss_clk_rate; + + unsigned long cache_req_pck; + unsigned long cache_prate; + struct dispc_clock_info cache_dispc_cinfo; + + enum dss_clk_source dsi_clk_source[MAX_NUM_DSI]; + enum dss_clk_source dispc_clk_source; + enum dss_clk_source lcd_clk_source[MAX_DSS_LCD_MANAGERS]; + + boolctx_valid; + u32 ctx[DSS_SZ_REGS / sizeof(u32)]; + + const struct dss_features *feat; + + struct dss_pll *video1_pll; + struct dss_pll *video2_pll; +}; + /* core */ static inline int dss_set_min_bus_tput(struct device *dev, unsigned long tput) { -- Regards, Laurent Pinchart ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 09/30] drm: omapdrm: dss: Pass DSS pointer to remaining dss functions
This removes the need to access the global DSS private data in those functions (both for the current accesses and the future ones that will be introduced when allocating the DSS device dynamically). Signed-off-by: Laurent Pinchart Reviewed-by: Sebastian Reichel --- drivers/gpu/drm/omapdrm/dss/dispc.c | 2 +- drivers/gpu/drm/omapdrm/dss/dss.c | 9 + drivers/gpu/drm/omapdrm/dss/dss.h | 7 --- drivers/gpu/drm/omapdrm/dss/venc.c | 11 +++ 4 files changed, 17 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/dss/dispc.c b/drivers/gpu/drm/omapdrm/dss/dispc.c index 8d0de1b790b7..867887151565 100644 --- a/drivers/gpu/drm/omapdrm/dss/dispc.c +++ b/drivers/gpu/drm/omapdrm/dss/dispc.c @@ -2733,7 +2733,7 @@ static int dispc_ovl_enable(enum omap_plane_id plane, bool enable) static enum omap_dss_output_id dispc_mgr_get_supported_outputs(enum omap_channel channel) { - return dss_get_supported_outputs(channel); + return dss_get_supported_outputs(dispc.dss, channel); } static void dispc_lcd_enable_signal_polarity(bool act_high) diff --git a/drivers/gpu/drm/omapdrm/dss/dss.c b/drivers/gpu/drm/omapdrm/dss/dss.c index 0d292da6757d..7820b04c43e2 100644 --- a/drivers/gpu/drm/omapdrm/dss/dss.c +++ b/drivers/gpu/drm/omapdrm/dss/dss.c @@ -666,9 +666,10 @@ unsigned long dss_get_max_fck_rate(struct dss_device *dss) return dss->feat->fck_freq_max; } -enum omap_dss_output_id dss_get_supported_outputs(enum omap_channel channel) +enum omap_dss_output_id dss_get_supported_outputs(struct dss_device *dss, + enum omap_channel channel) { - return dss.feat->outputs[channel]; + return dss->feat->outputs[channel]; } static int dss_setup_default_clock(void) @@ -697,7 +698,7 @@ static int dss_setup_default_clock(void) return 0; } -void dss_set_venc_output(enum omap_dss_venc_type type) +void dss_set_venc_output(struct dss_device *dss, enum omap_dss_venc_type type) { int l = 0; @@ -712,7 +713,7 @@ void dss_set_venc_output(enum omap_dss_venc_type type) REG_FLD_MOD(DSS_CONTROL, l, 6, 6); } -void dss_set_dac_pwrdn_bgz(bool enable) +void dss_set_dac_pwrdn_bgz(struct dss_device *dss, bool enable) { REG_FLD_MOD(DSS_CONTROL, enable, 5, 5); /* DAC Power-Down Control */ } diff --git a/drivers/gpu/drm/omapdrm/dss/dss.h b/drivers/gpu/drm/omapdrm/dss/dss.h index 1d0edf2d145e..89d708e8e970 100644 --- a/drivers/gpu/drm/omapdrm/dss/dss.h +++ b/drivers/gpu/drm/omapdrm/dss/dss.h @@ -299,7 +299,8 @@ void dss_runtime_put(struct dss_device *dss); unsigned long dss_get_dispc_clk_rate(struct dss_device *dss); unsigned long dss_get_max_fck_rate(struct dss_device *dss); -enum omap_dss_output_id dss_get_supported_outputs(enum omap_channel channel); +enum omap_dss_output_id dss_get_supported_outputs(struct dss_device *dss, + enum omap_channel channel); int dss_dpi_select_source(struct dss_device *dss, int port, enum omap_channel channel); void dss_select_hdmi_venc_clk_source(struct dss_device *dss, @@ -329,8 +330,8 @@ enum dss_clk_source dss_get_dsi_clk_source(struct dss_device *dss, enum dss_clk_source dss_get_lcd_clk_source(struct dss_device *dss, enum omap_channel channel); -void dss_set_venc_output(enum omap_dss_venc_type type); -void dss_set_dac_pwrdn_bgz(bool enable); +void dss_set_venc_output(struct dss_device *dss, enum omap_dss_venc_type type); +void dss_set_dac_pwrdn_bgz(struct dss_device *dss, bool enable); int dss_set_fck_rate(struct dss_device *dss, unsigned long rate); diff --git a/drivers/gpu/drm/omapdrm/dss/venc.c b/drivers/gpu/drm/omapdrm/dss/venc.c index 6de9d734ddb9..08bae18be188 100644 --- a/drivers/gpu/drm/omapdrm/dss/venc.c +++ b/drivers/gpu/drm/omapdrm/dss/venc.c @@ -325,6 +325,7 @@ static struct { struct mutex venc_lock; u32 wss_data; struct regulator *vdda_dac_reg; + struct dss_device *dss; struct clk *tv_dac_clk; @@ -468,8 +469,8 @@ static int venc_power_on(struct omap_dss_device *dssdev) venc_reset(); venc_write_config(venc_timings_to_config(&venc.vm)); - dss_set_venc_output(venc.type); - dss_set_dac_pwrdn_bgz(1); + dss_set_venc_output(venc.dss, venc.type); + dss_set_dac_pwrdn_bgz(venc.dss, 1); l = 0; @@ -499,7 +500,7 @@ static int venc_power_on(struct omap_dss_device *dssdev) regulator_disable(venc.vdda_dac_reg); err1: venc_write_reg(VENC_OUTPUT_CONTROL, 0); - dss_set_dac_pwrdn_bgz(0); + dss_set_dac_pwrdn_bgz(venc.dss, 0); venc_runtime_put(); err0: @@ -511,7 +512,7 @@ static void venc_power_off(struct omap_dss_device *dssdev) enum omap_channel channel = dssdev->dispc_channel; venc_write_reg(VENC_OUTPUT_CONTROL, 0); - dss_set_dac_pwrdn_bgz(0); + dss_set_dac_
[PATCH v2 07/30] drm: omapdrm: dss: Pass DSS pointer to dss_get_*_clk_source()
This removes the need to access the global DSS private data in those functions (both for the current accesses and the future ones that will be introduced when allocating the DSS device dynamically). Signed-off-by: Laurent Pinchart Reviewed-by: Sebastian Reichel --- drivers/gpu/drm/omapdrm/dss/dispc.c | 11 +++ drivers/gpu/drm/omapdrm/dss/dsi.c | 8 +--- drivers/gpu/drm/omapdrm/dss/dss.c | 18 ++ drivers/gpu/drm/omapdrm/dss/dss.h | 8 +--- 4 files changed, 27 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/dss/dispc.c b/drivers/gpu/drm/omapdrm/dss/dispc.c index 86d18f2d48ba..048b2e4d1f40 100644 --- a/drivers/gpu/drm/omapdrm/dss/dispc.c +++ b/drivers/gpu/drm/omapdrm/dss/dispc.c @@ -165,6 +165,7 @@ struct dispc_features { static struct { struct platform_device *pdev; void __iomem*base; + struct dss_device *dss; int irq; irq_handler_t user_handler; @@ -3112,7 +3113,7 @@ static unsigned long dispc_fclk_rate(void) unsigned long r; enum dss_clk_source src; - src = dss_get_dispc_clk_source(); + src = dss_get_dispc_clk_source(dispc.dss); if (src == DSS_CLK_SRC_FCK) { r = dss_get_dispc_clk_rate(); @@ -3139,7 +3140,7 @@ static unsigned long dispc_mgr_lclk_rate(enum omap_channel channel) if (!dss_mgr_is_lcd(channel)) return dispc_fclk_rate(); - src = dss_get_lcd_clk_source(channel); + src = dss_get_lcd_clk_source(dispc.dss, channel); if (src == DSS_CLK_SRC_FCK) { r = dss_get_dispc_clk_rate(); @@ -3219,7 +3220,7 @@ static void dispc_dump_clocks_channel(struct seq_file *s, enum omap_channel chan seq_printf(s, "- %s -\n", mgr_desc[channel].name); - lcd_clk_src = dss_get_lcd_clk_source(channel); + lcd_clk_src = dss_get_lcd_clk_source(dispc.dss, channel); seq_printf(s, "%s clk source = %s\n", mgr_desc[channel].name, dss_get_clk_source_name(lcd_clk_src)); @@ -3236,7 +3237,7 @@ void dispc_dump_clocks(struct seq_file *s) { int lcd; u32 l; - enum dss_clk_source dispc_clk_src = dss_get_dispc_clk_source(); + enum dss_clk_source dispc_clk_src = dss_get_dispc_clk_source(dispc.dss); if (dispc_runtime_get()) return; @@ -4549,12 +4550,14 @@ static int dispc_bind(struct device *dev, struct device *master, void *data) { struct platform_device *pdev = to_platform_device(dev); const struct soc_device_attribute *soc; + struct dss_device *dss = dss_get_device(master); u32 rev; int r = 0; struct resource *dispc_mem; struct device_node *np = pdev->dev.of_node; dispc.pdev = pdev; + dispc.dss = dss; spin_lock_init(&dispc.control_lock); diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c index 71f86a5d4029..26f4122f6784 100644 --- a/drivers/gpu/drm/omapdrm/dss/dsi.c +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c @@ -1286,8 +1286,10 @@ static unsigned long dsi_fclk_rate(struct platform_device *dsidev) { unsigned long r; struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); + enum dss_clk_source source; - if (dss_get_dsi_clk_source(dsi->module_id) == DSS_CLK_SRC_FCK) { + source = dss_get_dsi_clk_source(dsi->dss, dsi->module_id); + if (source == DSS_CLK_SRC_FCK) { /* DSI FCLK source is DSS_CLK_FCK */ r = clk_get_rate(dsi->dss_clk); } else { @@ -1506,8 +1508,8 @@ static void dsi_dump_dsidev_clocks(struct platform_device *dsidev, int dsi_module = dsi->module_id; struct dss_pll *pll = &dsi->pll; - dispc_clk_src = dss_get_dispc_clk_source(); - dsi_clk_src = dss_get_dsi_clk_source(dsi_module); + dispc_clk_src = dss_get_dispc_clk_source(dsi->dss); + dsi_clk_src = dss_get_dsi_clk_source(dsi->dss, dsi_module); if (dsi_runtime_get(dsidev)) return; diff --git a/drivers/gpu/drm/omapdrm/dss/dss.c b/drivers/gpu/drm/omapdrm/dss/dss.c index 73698a497e4a..bdf8f66002b6 100644 --- a/drivers/gpu/drm/omapdrm/dss/dss.c +++ b/drivers/gpu/drm/omapdrm/dss/dss.c @@ -570,25 +570,27 @@ void dss_select_lcd_clk_source(struct dss_device *dss, dss->lcd_clk_source[idx] = clk_src; } -enum dss_clk_source dss_get_dispc_clk_source(void) +enum dss_clk_source dss_get_dispc_clk_source(struct dss_device *dss) { - return dss.dispc_clk_source; + return dss->dispc_clk_source; } -enum dss_clk_source dss_get_dsi_clk_source(int dsi_module) +enum dss_clk_source dss_get_dsi_clk_source(struct dss_device *dss, + int dsi_module) { - return dss.dsi_clk_source[dsi_module]; + return dss->dsi_clk_source[dsi_module]; } -enum dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel) +enum dss_clk_source dss_get_lcd_clk_source(
[PATCH v2 11/30] drm: omapdrm: dss: Support passing private data to debugfs show handlers
To simplify implementation of debugfs seq_file show handlers, the driver passes the pointer to the show function through the debugfs_create_file data pointer. This prevents using the pointer to pass driver private data to the show handler, and requires all handlers to use global variables to access private data. To prepare for the removal of global private data in the driver, rework the debugfs infrastructure to allow passing a private data pointer to show handlers. The price to pay is explicit removal of debugfs files to free the internally allocated memory. This is desirable anyway as debugfs entries should be removed when a component driver is unbound, otherwise crashes will occur due to access to freed memory when the components will be dynamically allocated instead of stored in global variables. Signed-off-by: Laurent Pinchart Reviewed-by: Sebastian Reichel --- Changes since v1: - Removed unneeded declaration of struct dentry in dss.h - Removed DSS debugfs files in driver remove handler --- drivers/gpu/drm/omapdrm/dss/dispc.c | 13 -- drivers/gpu/drm/omapdrm/dss/dsi.c | 40 - drivers/gpu/drm/omapdrm/dss/dss.c | 89 - drivers/gpu/drm/omapdrm/dss/dss.h | 31 - drivers/gpu/drm/omapdrm/dss/hdmi.h | 2 + drivers/gpu/drm/omapdrm/dss/hdmi4.c | 9 ++-- drivers/gpu/drm/omapdrm/dss/hdmi5.c | 9 ++-- drivers/gpu/drm/omapdrm/dss/venc.c | 11 +++-- 8 files changed, 141 insertions(+), 63 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/dss/dispc.c b/drivers/gpu/drm/omapdrm/dss/dispc.c index 867887151565..3428ffea70ee 100644 --- a/drivers/gpu/drm/omapdrm/dss/dispc.c +++ b/drivers/gpu/drm/omapdrm/dss/dispc.c @@ -167,6 +167,8 @@ static struct { void __iomem*base; struct dss_device *dss; + struct dss_debugfs_entry *debugfs; + int irq; irq_handler_t user_handler; void *user_data; @@ -3268,7 +3270,7 @@ void dispc_dump_clocks(struct seq_file *s) dispc_runtime_put(); } -static void dispc_dump_regs(struct seq_file *s) +static int dispc_dump_regs(struct seq_file *s, void *p) { int i, j; const char *mgr_names[] = { @@ -3289,7 +3291,7 @@ static void dispc_dump_regs(struct seq_file *s) #define DUMPREG(r) seq_printf(s, "%-50s %08x\n", #r, dispc_read_reg(r)) if (dispc_runtime_get()) - return; + return 0; /* DISPC common registers */ DUMPREG(DISPC_REVISION); @@ -3461,6 +3463,8 @@ static void dispc_dump_regs(struct seq_file *s) #undef DISPC_REG #undef DUMPREG + + return 0; } /* calculate clock rates using dividers in cinfo */ @@ -4620,7 +4624,8 @@ static int dispc_bind(struct device *dev, struct device *master, void *data) dispc_set_ops(&dispc_ops); - dss_debugfs_create_file("dispc", dispc_dump_regs); + dispc.debugfs = dss_debugfs_create_file("dispc", dispc_dump_regs, + &dispc); return 0; @@ -4632,6 +4637,8 @@ static int dispc_bind(struct device *dev, struct device *master, void *data) static void dispc_unbind(struct device *dev, struct device *master, void *data) { + dss_debugfs_remove_file(dispc.debugfs); + dispc_set_ops(NULL); pm_runtime_disable(dev); diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c index 26f4122f6784..a676d27dd479 100644 --- a/drivers/gpu/drm/omapdrm/dss/dsi.c +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c @@ -401,6 +401,10 @@ struct dsi_data { #endif int debug_read; int debug_write; + struct { + struct dss_debugfs_entry *irqs; + struct dss_debugfs_entry *regs; + } debugfs; #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS spinlock_t irq_stats_lock; @@ -1660,18 +1664,20 @@ static void dsi_dump_dsidev_irqs(struct platform_device *dsidev, #undef PIS } -static void dsi1_dump_irqs(struct seq_file *s) +static int dsi1_dump_irqs(struct seq_file *s, void *p) { struct platform_device *dsidev = dsi_get_dsidev_from_id(0); dsi_dump_dsidev_irqs(dsidev, s); + return 0; } -static void dsi2_dump_irqs(struct seq_file *s) +static int dsi2_dump_irqs(struct seq_file *s, void *p) { struct platform_device *dsidev = dsi_get_dsidev_from_id(1); dsi_dump_dsidev_irqs(dsidev, s); + return 0; } #endif @@ -1759,18 +1765,20 @@ static void dsi_dump_dsidev_regs(struct platform_device *dsidev, #undef DUMPREG } -static void dsi1_dump_regs(struct seq_file *s) +static int dsi1_dump_regs(struct seq_file *s, void *p) { struct platform_device *dsidev = dsi_get_dsidev_from_id(0); dsi_dump_dsidev_regs(dsidev, s); + return 0; } -static void dsi2_dump_regs(struct seq_file *s) +static int dsi2_dump_regs(struct seq_file *s, void *p) { struct platform_device *dsidev = dsi_get_dsidev_from_id(1);
[PATCH v2 10/30] drm: omapdrm: dss: Allocate the DSS private data structure dynamically
The DSS private data structure is currently stored as a global variable. While no platform with multiple DSS devices currently exists nor is planned, this doesn't comply with the kernel device model and should thus be fixed. Allocate the DSS private data structure dynamically for each DSS instance and remove the global variable. All code that need access to the structure now retrieves it dynamically so we can remove the global variable. Signed-off-by: Laurent Pinchart Reviewed-by: Sebastian Reichel --- Changes since v1: - Wrap lines at 80 columns limit --- drivers/gpu/drm/omapdrm/dss/dss.c | 341 +- 1 file changed, 186 insertions(+), 155 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/dss/dss.c b/drivers/gpu/drm/omapdrm/dss/dss.c index 7820b04c43e2..4b00faa1a8cc 100644 --- a/drivers/gpu/drm/omapdrm/dss/dss.c +++ b/drivers/gpu/drm/omapdrm/dss/dss.c @@ -62,11 +62,12 @@ struct dss_reg { #define DSS_PLL_CONTROLDSS_REG(0x0048) #define DSS_SDI_STATUS DSS_REG(0x005C) -#define REG_GET(idx, start, end) \ - FLD_GET(dss_read_reg(idx), start, end) +#define REG_GET(dss, idx, start, end) \ + FLD_GET(dss_read_reg(dss, idx), start, end) -#define REG_FLD_MOD(idx, val, start, end) \ - dss_write_reg(idx, FLD_MOD(dss_read_reg(idx), val, start, end)) +#define REG_FLD_MOD(dss, idx, val, start, end) \ + dss_write_reg(dss, idx, \ + FLD_MOD(dss_read_reg(dss, idx), val, start, end)) struct dss_ops { int (*dpi_select_source)(struct dss_device *dss, int port, @@ -90,8 +91,6 @@ struct dss_features { bool has_lcd_clk_src; }; -static struct dss_device dss; - static const char * const dss_generic_clk_source_names[] = { [DSS_CLK_SRC_FCK] = "FCK", [DSS_CLK_SRC_PLL1_1]= "PLL1:1", @@ -103,49 +102,50 @@ static const char * const dss_generic_clk_source_names[] = { [DSS_CLK_SRC_HDMI_PLL] = "HDMI PLL", }; -static inline void dss_write_reg(const struct dss_reg idx, u32 val) +static inline void dss_write_reg(struct dss_device *dss, +const struct dss_reg idx, u32 val) { - __raw_writel(val, dss.base + idx.idx); + __raw_writel(val, dss->base + idx.idx); } -static inline u32 dss_read_reg(const struct dss_reg idx) +static inline u32 dss_read_reg(struct dss_device *dss, const struct dss_reg idx) { - return __raw_readl(dss.base + idx.idx); + return __raw_readl(dss->base + idx.idx); } -#define SR(reg) \ - dss.ctx[(DSS_##reg).idx / sizeof(u32)] = dss_read_reg(DSS_##reg) -#define RR(reg) \ - dss_write_reg(DSS_##reg, dss.ctx[(DSS_##reg).idx / sizeof(u32)]) +#define SR(dss, reg) \ + dss->ctx[(DSS_##reg).idx / sizeof(u32)] = dss_read_reg(dss, DSS_##reg) +#define RR(dss, reg) \ + dss_write_reg(dss, DSS_##reg, dss->ctx[(DSS_##reg).idx / sizeof(u32)]) -static void dss_save_context(void) +static void dss_save_context(struct dss_device *dss) { DSSDBG("dss_save_context\n"); - SR(CONTROL); + SR(dss, CONTROL); - if (dss.feat->outputs[OMAP_DSS_CHANNEL_LCD] & OMAP_DSS_OUTPUT_SDI) { - SR(SDI_CONTROL); - SR(PLL_CONTROL); + if (dss->feat->outputs[OMAP_DSS_CHANNEL_LCD] & OMAP_DSS_OUTPUT_SDI) { + SR(dss, SDI_CONTROL); + SR(dss, PLL_CONTROL); } - dss.ctx_valid = true; + dss->ctx_valid = true; DSSDBG("context saved\n"); } -static void dss_restore_context(void) +static void dss_restore_context(struct dss_device *dss) { DSSDBG("dss_restore_context\n"); - if (!dss.ctx_valid) + if (!dss->ctx_valid) return; - RR(CONTROL); + RR(dss, CONTROL); - if (dss.feat->outputs[OMAP_DSS_CHANNEL_LCD] & OMAP_DSS_OUTPUT_SDI) { - RR(SDI_CONTROL); - RR(PLL_CONTROL); + if (dss->feat->outputs[OMAP_DSS_CHANNEL_LCD] & OMAP_DSS_OUTPUT_SDI) { + RR(dss, SDI_CONTROL); + RR(dss, PLL_CONTROL); } DSSDBG("context restored\n"); @@ -184,12 +184,13 @@ void dss_ctrl_pll_enable(struct dss_pll *pll, bool enable) 1 << shift, val << shift); } -static int dss_ctrl_pll_set_control_mux(enum dss_clk_source clk_src, - enum omap_channel channel) +static int dss_ctrl_pll_set_control_mux(struct dss_device *dss, + enum dss_clk_source clk_src, + enum omap_channel channel) { unsigned int shift, val; - if (!dss.syscon_pll_ctrl) + if (!dss->syscon_pll_ctrl) return -EINVAL; switch (channel) { @@ -244,7 +245,7 @@ static int dss_ctrl_pll_set_control_mux(enum dss_clk_source clk_src, return -EINVAL; } - regmap_update_bits(dss.syscon_pll_ctrl, dss.syscon_pll_ctrl_offset, + regmap_update_bits(ds
[PATCH v2 17/30] drm: omapdrm: dsi: Use dev pointer directly in dsi_bind() function
The dsi_bind() function receives a pointer to a struct device that it casts to a struct platform_device, only to use the platform device's dev field through the code. Use the dev pointer directly. While at it rename the struct platform_device pointer dsidev to pdev to make it more explicit. Signed-off-by: Laurent Pinchart Reviewed-by: Sebastian Reichel --- drivers/gpu/drm/omapdrm/dss/dsi.c | 35 ++- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c index cb250dbf0f9b..62131d7593a7 100644 --- a/drivers/gpu/drm/omapdrm/dss/dsi.c +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c @@ -5299,9 +5299,10 @@ static const struct soc_device_attribute dsi_soc_devices[] = { { .machine = "AM35*", .data = &dsi_of_data_omap34xx }, { /* sentinel */ } }; + static int dsi_bind(struct device *dev, struct device *master, void *data) { - struct platform_device *dsidev = to_platform_device(dev); + struct platform_device *pdev = to_platform_device(dev); struct dss_device *dss = dss_get_device(master); const struct soc_device_attribute *soc; const struct dsi_module_id_data *d; @@ -5311,13 +5312,13 @@ static int dsi_bind(struct device *dev, struct device *master, void *data) struct resource *dsi_mem; struct resource *res; - dsi = devm_kzalloc(&dsidev->dev, sizeof(*dsi), GFP_KERNEL); + dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL); if (!dsi) return -ENOMEM; dsi->dss = dss; - dsi->pdev = dsidev; - dev_set_drvdata(&dsidev->dev, dsi); + dsi->pdev = pdev; + dev_set_drvdata(dev, dsi); spin_lock_init(&dsi->irq_lock); spin_lock_init(&dsi->errors_lock); @@ -5338,29 +5339,29 @@ static int dsi_bind(struct device *dev, struct device *master, void *data) timer_setup(&dsi->te_timer, dsi_te_timeout, 0); #endif - dsi_mem = platform_get_resource_byname(dsidev, IORESOURCE_MEM, "proto"); - dsi->proto_base = devm_ioremap_resource(&dsidev->dev, dsi_mem); + dsi_mem = platform_get_resource_byname(pdev, IORESOURCE_MEM, "proto"); + dsi->proto_base = devm_ioremap_resource(dev, dsi_mem); if (IS_ERR(dsi->proto_base)) return PTR_ERR(dsi->proto_base); - res = platform_get_resource_byname(dsidev, IORESOURCE_MEM, "phy"); - dsi->phy_base = devm_ioremap_resource(&dsidev->dev, res); + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy"); + dsi->phy_base = devm_ioremap_resource(dev, res); if (IS_ERR(dsi->phy_base)) return PTR_ERR(dsi->phy_base); - res = platform_get_resource_byname(dsidev, IORESOURCE_MEM, "pll"); - dsi->pll_base = devm_ioremap_resource(&dsidev->dev, res); + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pll"); + dsi->pll_base = devm_ioremap_resource(dev, res); if (IS_ERR(dsi->pll_base)) return PTR_ERR(dsi->pll_base); - dsi->irq = platform_get_irq(dsi->pdev, 0); + dsi->irq = platform_get_irq(pdev, 0); if (dsi->irq < 0) { DSSERR("platform_get_irq failed\n"); return -ENODEV; } - r = devm_request_irq(&dsidev->dev, dsi->irq, omap_dsi_irq_handler, -IRQF_SHARED, dev_name(&dsidev->dev), dsi); + r = devm_request_irq(dev, dsi->irq, omap_dsi_irq_handler, +IRQF_SHARED, dev_name(dev), dsi); if (r < 0) { DSSERR("request_irq failed\n"); return r; @@ -5414,14 +5415,14 @@ static int dsi_bind(struct device *dev, struct device *master, void *data) dsi_init_pll_data(dss, dsi); - pm_runtime_enable(&dsidev->dev); + pm_runtime_enable(dev); r = dsi_runtime_get(dsi); if (r) goto err_runtime_get; rev = dsi_read_reg(dsi, DSI_REVISION); - dev_dbg(&dsidev->dev, "OMAP DSI rev %d.%d\n", + dev_dbg(dev, "OMAP DSI rev %d.%d\n", FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0)); /* DSI on OMAP3 doesn't have register DSI_GNQ, set number @@ -5442,7 +5443,7 @@ static int dsi_bind(struct device *dev, struct device *master, void *data) goto err_probe_of; } - r = of_platform_populate(dsidev->dev.of_node, NULL, NULL, &dsidev->dev); + r = of_platform_populate(dev->of_node, NULL, NULL, dev); if (r) DSSERR("Failed to populate DSI child devices: %d\n", r); @@ -5474,7 +5475,7 @@ static int dsi_bind(struct device *dev, struct device *master, void *data) dsi_runtime_put(dsi); err_runtime_get: - pm_runtime_disable(&dsidev->dev); + pm_runtime_disable(dev); return r; } -- Regards, Laurent Pinchart ___ dri-devel mailing list dri-devel
[PATCH v2 06/30] drm: omapdrm: dss: Pass DSS pointer to dss_ops operations
This removes the need to access the global DSS private data in those functions (both for the current accesses and the future ones that will be introduced when allocating the DSS device dynamically). Signed-off-by: Laurent Pinchart Reviewed-by: Sebastian Reichel --- drivers/gpu/drm/omapdrm/dss/dpi.c | 12 --- drivers/gpu/drm/omapdrm/dss/dsi.c | 18 +- drivers/gpu/drm/omapdrm/dss/dss.c | 68 ++--- drivers/gpu/drm/omapdrm/dss/dss.h | 25 -- drivers/gpu/drm/omapdrm/dss/hdmi.h | 1 + drivers/gpu/drm/omapdrm/dss/hdmi4.c | 3 +- drivers/gpu/drm/omapdrm/dss/hdmi5.c | 3 +- 7 files changed, 77 insertions(+), 53 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/dss/dpi.c b/drivers/gpu/drm/omapdrm/dss/dpi.c index 0a6eb39be444..e7f50fabca6f 100644 --- a/drivers/gpu/drm/omapdrm/dss/dpi.c +++ b/drivers/gpu/drm/omapdrm/dss/dpi.c @@ -38,6 +38,7 @@ struct dpi_data { struct platform_device *pdev; enum dss_model dss_model; + struct dss_device *dss; struct regulator *vdds_dsi_reg; enum dss_clk_source clk_src; @@ -302,7 +303,7 @@ static int dpi_set_pll_clk(struct dpi_data *dpi, enum omap_channel channel, if (r) return r; - dss_select_lcd_clk_source(channel, dpi->clk_src); + dss_select_lcd_clk_source(dpi->dss, channel, dpi->clk_src); dpi->mgr_config.clock_info = ctx.dispc_cinfo; @@ -412,7 +413,7 @@ static int dpi_display_enable(struct omap_dss_device *dssdev) if (r) goto err_get_dispc; - r = dss_dpi_select_source(out->port_num, channel); + r = dss_dpi_select_source(dpi->dss, out->port_num, channel); if (r) goto err_src_sel; @@ -464,7 +465,7 @@ static void dpi_display_disable(struct omap_dss_device *dssdev) dss_mgr_disable(channel); if (dpi->pll) { - dss_select_lcd_clk_source(channel, DSS_CLK_SRC_FCK); + dss_select_lcd_clk_source(dpi->dss, channel, DSS_CLK_SRC_FCK); dss_pll_disable(dpi->pll); } @@ -748,8 +749,8 @@ static void dpi_uninit_output_port(struct device_node *port) omapdss_unregister_output(out); } -int dpi_init_port(struct platform_device *pdev, struct device_node *port, - enum dss_model dss_model) +int dpi_init_port(struct dss_device *dss, struct platform_device *pdev, + struct device_node *port, enum dss_model dss_model) { struct dpi_data *dpi; struct device_node *ep; @@ -776,6 +777,7 @@ int dpi_init_port(struct platform_device *pdev, struct device_node *port, dpi->pdev = pdev; dpi->dss_model = dss_model; + dpi->dss = dss; port->data = dpi; mutex_init(&dpi->lock); diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c index 7ba33fc5d245..71f86a5d4029 100644 --- a/drivers/gpu/drm/omapdrm/dss/dsi.c +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c @@ -343,6 +343,7 @@ struct dsi_data { struct clk *dss_clk; struct regmap *syscon; + struct dss_device *dss; struct dispc_clock_info user_dispc_cinfo; struct dss_pll_clock_info user_dsi_cinfo; @@ -4206,7 +4207,7 @@ static int dsi_display_init_dispc(struct platform_device *dsidev, struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); int r; - dss_select_lcd_clk_source(channel, dsi->module_id == 0 ? + dss_select_lcd_clk_source(dsi->dss, channel, dsi->module_id == 0 ? DSS_CLK_SRC_PLL1_1 : DSS_CLK_SRC_PLL2_1); @@ -4260,7 +4261,7 @@ static int dsi_display_init_dispc(struct platform_device *dsidev, dss_mgr_unregister_framedone_handler(channel, dsi_framedone_irq_callback, dsidev); err: - dss_select_lcd_clk_source(channel, DSS_CLK_SRC_FCK); + dss_select_lcd_clk_source(dsi->dss, channel, DSS_CLK_SRC_FCK); return r; } @@ -4273,7 +4274,7 @@ static void dsi_display_uninit_dispc(struct platform_device *dsidev, dss_mgr_unregister_framedone_handler(channel, dsi_framedone_irq_callback, dsidev); - dss_select_lcd_clk_source(channel, DSS_CLK_SRC_FCK); + dss_select_lcd_clk_source(dsi->dss, channel, DSS_CLK_SRC_FCK); } static int dsi_configure_dsi_clocks(struct platform_device *dsidev) @@ -4306,9 +4307,9 @@ static int dsi_display_init_dsi(struct platform_device *dsidev) if (r) goto err1; - dss_select_dsi_clk_source(dsi->module_id, dsi->module_id == 0 ? - DSS_CLK_SRC_PLL1_2 : - DSS_CLK_SRC_PLL2_2); + dss_select_dsi_clk_source(dsi->dss, dsi->module_id, + dsi->module_id == 0 ? + DSS_CLK_SRC_PLL1_2 : DSS_CLK_SRC_PLL2_2); DSSDBG("PLL OK\n"); @@ -4340,7 +4341,7 @@ static in
[PATCH v2 12/30] drm: omapdrm: dss: Store the registered plls array in struct dss_device
As part of an effort to remove the usage of global variables in the driver, store the registered plls array in the dss_device structure instead of a global variable. Signed-off-by: Laurent Pinchart Reviewed-by: Sebastian Reichel --- drivers/gpu/drm/omapdrm/dss/dispc.c | 4 ++-- drivers/gpu/drm/omapdrm/dss/dpi.c | 17 +++--- drivers/gpu/drm/omapdrm/dss/dsi.c | 3 +-- drivers/gpu/drm/omapdrm/dss/dss.h | 8 --- drivers/gpu/drm/omapdrm/dss/hdmi_pll.c | 3 +-- drivers/gpu/drm/omapdrm/dss/pll.c | 40 + drivers/gpu/drm/omapdrm/dss/video-pll.c | 3 +-- 7 files changed, 40 insertions(+), 38 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/dss/dispc.c b/drivers/gpu/drm/omapdrm/dss/dispc.c index 3428ffea70ee..285d297db229 100644 --- a/drivers/gpu/drm/omapdrm/dss/dispc.c +++ b/drivers/gpu/drm/omapdrm/dss/dispc.c @@ -3123,7 +3123,7 @@ static unsigned long dispc_fclk_rate(void) struct dss_pll *pll; unsigned int clkout_idx; - pll = dss_pll_find_by_src(src); + pll = dss_pll_find_by_src(dispc.dss, src); clkout_idx = dss_pll_get_clkout_idx_for_src(src); r = pll->cinfo.clkout[clkout_idx]; @@ -3150,7 +3150,7 @@ static unsigned long dispc_mgr_lclk_rate(enum omap_channel channel) struct dss_pll *pll; unsigned int clkout_idx; - pll = dss_pll_find_by_src(src); + pll = dss_pll_find_by_src(dispc.dss, src); clkout_idx = dss_pll_get_clkout_idx_for_src(src); r = pll->cinfo.clkout[clkout_idx]; diff --git a/drivers/gpu/drm/omapdrm/dss/dpi.c b/drivers/gpu/drm/omapdrm/dss/dpi.c index ba5adfb7ee70..338ceb1ba61b 100644 --- a/drivers/gpu/drm/omapdrm/dss/dpi.c +++ b/drivers/gpu/drm/omapdrm/dss/dpi.c @@ -58,7 +58,8 @@ static struct dpi_data *dpi_get_data_from_dssdev(struct omap_dss_device *dssdev) return container_of(dssdev, struct dpi_data, output); } -static enum dss_clk_source dpi_get_clk_src_dra7xx(enum omap_channel channel) +static enum dss_clk_source dpi_get_clk_src_dra7xx(struct dpi_data *dpi, + enum omap_channel channel) { /* * Possible clock sources: @@ -70,23 +71,23 @@ static enum dss_clk_source dpi_get_clk_src_dra7xx(enum omap_channel channel) switch (channel) { case OMAP_DSS_CHANNEL_LCD: { - if (dss_pll_find_by_src(DSS_CLK_SRC_PLL1_1)) + if (dss_pll_find_by_src(dpi->dss, DSS_CLK_SRC_PLL1_1)) return DSS_CLK_SRC_PLL1_1; break; } case OMAP_DSS_CHANNEL_LCD2: { - if (dss_pll_find_by_src(DSS_CLK_SRC_PLL1_3)) + if (dss_pll_find_by_src(dpi->dss, DSS_CLK_SRC_PLL1_3)) return DSS_CLK_SRC_PLL1_3; - if (dss_pll_find_by_src(DSS_CLK_SRC_PLL2_3)) + if (dss_pll_find_by_src(dpi->dss, DSS_CLK_SRC_PLL2_3)) return DSS_CLK_SRC_PLL2_3; break; } case OMAP_DSS_CHANNEL_LCD3: { - if (dss_pll_find_by_src(DSS_CLK_SRC_PLL2_1)) + if (dss_pll_find_by_src(dpi->dss, DSS_CLK_SRC_PLL2_1)) return DSS_CLK_SRC_PLL2_1; - if (dss_pll_find_by_src(DSS_CLK_SRC_PLL1_3)) + if (dss_pll_find_by_src(dpi->dss, DSS_CLK_SRC_PLL1_3)) return DSS_CLK_SRC_PLL1_3; break; } @@ -133,7 +134,7 @@ static enum dss_clk_source dpi_get_clk_src(struct dpi_data *dpi) } case DSS_MODEL_DRA7: - return dpi_get_clk_src_dra7xx(channel); + return dpi_get_clk_src_dra7xx(dpi, channel); default: return DSS_CLK_SRC_FCK; @@ -605,7 +606,7 @@ static void dpi_init_pll(struct dpi_data *dpi) dpi->clk_src = dpi_get_clk_src(dpi); - pll = dss_pll_find_by_src(dpi->clk_src); + pll = dss_pll_find_by_src(dpi->dss, dpi->clk_src); if (!pll) return; diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c index a676d27dd479..448986031a6a 100644 --- a/drivers/gpu/drm/omapdrm/dss/dsi.c +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c @@ -5353,9 +5353,8 @@ static int dsi_init_pll_data(struct dss_device *dss, pll->base = dsi->pll_base; pll->hw = dsi->data->pll_hw; pll->ops = &dsi_pll_ops; - pll->dss = dss; - r = dss_pll_register(pll); + r = dss_pll_register(dss, pll); if (r) return r; diff --git a/drivers/gpu/drm/omapdrm/dss/dss.h b/drivers/gpu/drm/omapdrm/dss/dss.h index ec8e40e09141..8cc4b6ca203e 100644 --- a/drivers/gpu/drm/omapdrm/dss/dss.h +++ b/drivers/gpu/drm/omapdrm/dss/dss.h @@ -267,6 +267,7 @@ struct dss_device { struct dss_debugfs_entry *dss; } de
[PATCH v2 20/30] drm: omapdrm: dss: Pass omap_dss_device pointer to dss_mgr_*() functions
The dss_mgr_*() functions take a channel argument to identify the channel they operate on. This prevents the functions from accessing driver data structures without resorting to global variables. In an effort to remove global variables, pass the omap_dss_device pointer associated with the channel instead. This will be used to look up the omap_drm_private data structure to pass to the dss_mgr_ops. Signed-off-by: Laurent Pinchart Reviewed-by: Sebastian Reichel --- drivers/gpu/drm/omapdrm/dss/dpi.c | 32 ++ drivers/gpu/drm/omapdrm/dss/dsi.c | 30 +++-- drivers/gpu/drm/omapdrm/dss/hdmi4.c | 20 ++--- drivers/gpu/drm/omapdrm/dss/hdmi5.c | 20 ++--- drivers/gpu/drm/omapdrm/dss/omapdss.h | 22 +- drivers/gpu/drm/omapdrm/dss/output.c | 42 ++- drivers/gpu/drm/omapdrm/dss/sdi.c | 28 +-- drivers/gpu/drm/omapdrm/dss/venc.c| 18 +-- 8 files changed, 88 insertions(+), 124 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/dss/dpi.c b/drivers/gpu/drm/omapdrm/dss/dpi.c index 338ceb1ba61b..e818e7836cbb 100644 --- a/drivers/gpu/drm/omapdrm/dss/dpi.c +++ b/drivers/gpu/drm/omapdrm/dss/dpi.c @@ -343,8 +343,6 @@ static int dpi_set_dispc_clk(struct dpi_data *dpi, unsigned long pck_req, static int dpi_set_mode(struct dpi_data *dpi) { - struct omap_dss_device *out = &dpi->output; - enum omap_channel channel = out->dispc_channel; struct videomode *vm = &dpi->vm; int lck_div = 0, pck_div = 0; unsigned long fck = 0; @@ -352,8 +350,8 @@ static int dpi_set_mode(struct dpi_data *dpi) int r = 0; if (dpi->pll) - r = dpi_set_pll_clk(dpi, channel, vm->pixelclock, &fck, - &lck_div, &pck_div); + r = dpi_set_pll_clk(dpi, dpi->output.dispc_channel, + vm->pixelclock, &fck, &lck_div, &pck_div); else r = dpi_set_dispc_clk(dpi, vm->pixelclock, &fck, &lck_div, &pck_div); @@ -369,16 +367,13 @@ static int dpi_set_mode(struct dpi_data *dpi) vm->pixelclock = pck; } - dss_mgr_set_timings(channel, vm); + dss_mgr_set_timings(&dpi->output, vm); return 0; } static void dpi_config_lcd_manager(struct dpi_data *dpi) { - struct omap_dss_device *out = &dpi->output; - enum omap_channel channel = out->dispc_channel; - dpi->mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS; dpi->mgr_config.stallmode = false; @@ -388,14 +383,13 @@ static void dpi_config_lcd_manager(struct dpi_data *dpi) dpi->mgr_config.lcden_sig_polarity = 0; - dss_mgr_set_lcd_config(channel, &dpi->mgr_config); + dss_mgr_set_lcd_config(&dpi->output, &dpi->mgr_config); } static int dpi_display_enable(struct omap_dss_device *dssdev) { struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev); struct omap_dss_device *out = &dpi->output; - enum omap_channel channel = out->dispc_channel; int r; mutex_lock(&dpi->lock); @@ -416,7 +410,7 @@ static int dpi_display_enable(struct omap_dss_device *dssdev) if (r) goto err_get_dispc; - r = dss_dpi_select_source(dpi->dss, out->port_num, channel); + r = dss_dpi_select_source(dpi->dss, out->port_num, out->dispc_channel); if (r) goto err_src_sel; @@ -434,7 +428,7 @@ static int dpi_display_enable(struct omap_dss_device *dssdev) mdelay(2); - r = dss_mgr_enable(channel); + r = dss_mgr_enable(&dpi->output); if (r) goto err_mgr_enable; @@ -461,14 +455,14 @@ static int dpi_display_enable(struct omap_dss_device *dssdev) static void dpi_display_disable(struct omap_dss_device *dssdev) { struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev); - enum omap_channel channel = dpi->output.dispc_channel; mutex_lock(&dpi->lock); - dss_mgr_disable(channel); + dss_mgr_disable(&dpi->output); if (dpi->pll) { - dss_select_lcd_clk_source(dpi->dss, channel, DSS_CLK_SRC_FCK); + dss_select_lcd_clk_source(dpi->dss, dpi->output.dispc_channel, + DSS_CLK_SRC_FCK); dss_pll_disable(dpi->pll); } @@ -658,7 +652,6 @@ static int dpi_connect(struct omap_dss_device *dssdev, struct omap_dss_device *dst) { struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev); - enum omap_channel channel = dpi->output.dispc_channel; int r; r = dpi_init_regulator(dpi); @@ -667,7 +660,7 @@ static int dpi_connect(struct omap_dss_device *dssdev, dpi_init_pll(dpi); - r = dss_mgr_connect(channel, dssdev); + r = dss_mgr_connect(&dpi->output, dssdev); if (r)
[PATCH v2 13/30] drm: omapdrm: dss: Store the debugfs root directory in struct dss_device
As part of an effort to remove the usage of global variables in the driver, store the debugfs root directory in the dss_device structure instead of a global variable. Signed-off-by: Laurent Pinchart Reviewed-by: Sebastian Reichel --- Changes since v1: - Remove static keyword from dss_initialize_debugfs() local variable - Remove NULL check before debugfs_remove_recursive() --- drivers/gpu/drm/omapdrm/dss/dispc.c | 2 +- drivers/gpu/drm/omapdrm/dss/dsi.c | 8 drivers/gpu/drm/omapdrm/dss/dss.c | 38 ++--- drivers/gpu/drm/omapdrm/dss/dss.h | 9 ++--- drivers/gpu/drm/omapdrm/dss/hdmi4.c | 3 ++- drivers/gpu/drm/omapdrm/dss/hdmi5.c | 3 ++- drivers/gpu/drm/omapdrm/dss/venc.c | 3 ++- 7 files changed, 36 insertions(+), 30 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/dss/dispc.c b/drivers/gpu/drm/omapdrm/dss/dispc.c index 285d297db229..8019cc9f4f97 100644 --- a/drivers/gpu/drm/omapdrm/dss/dispc.c +++ b/drivers/gpu/drm/omapdrm/dss/dispc.c @@ -4624,7 +4624,7 @@ static int dispc_bind(struct device *dev, struct device *master, void *data) dispc_set_ops(&dispc_ops); - dispc.debugfs = dss_debugfs_create_file("dispc", dispc_dump_regs, + dispc.debugfs = dss_debugfs_create_file(dss, "dispc", dispc_dump_regs, &dispc); return 0; diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c index 448986031a6a..05030dc25c72 100644 --- a/drivers/gpu/drm/omapdrm/dss/dsi.c +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c @@ -5576,20 +5576,20 @@ static int dsi_bind(struct device *dev, struct device *master, void *data) dsi_runtime_put(dsidev); if (dsi->module_id == 0) - dsi->debugfs.regs = dss_debugfs_create_file("dsi1_regs", + dsi->debugfs.regs = dss_debugfs_create_file(dss, "dsi1_regs", dsi1_dump_regs, &dsi); else - dsi->debugfs.regs = dss_debugfs_create_file("dsi2_regs", + dsi->debugfs.regs = dss_debugfs_create_file(dss, "dsi2_regs", dsi2_dump_regs, &dsi); #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS if (dsi->module_id == 0) - dsi->debugfs.irqs = dss_debugfs_create_file("dsi1_irqs", + dsi->debugfs.irqs = dss_debugfs_create_file(dss, "dsi1_irqs", dsi1_dump_irqs, &dsi); else - dsi->debugfs.irqs = dss_debugfs_create_file("dsi2_irqs", + dsi->debugfs.irqs = dss_debugfs_create_file(dss, "dsi2_irqs", dsi2_dump_irqs, &dsi); #endif diff --git a/drivers/gpu/drm/omapdrm/dss/dss.c b/drivers/gpu/drm/omapdrm/dss/dss.c index 14a86e2c6d83..7a5f5f233ad0 100644 --- a/drivers/gpu/drm/omapdrm/dss/dss.c +++ b/drivers/gpu/drm/omapdrm/dss/dss.c @@ -901,25 +901,22 @@ static int dss_debug_dump_clocks(struct seq_file *s, void *p) return 0; } -static struct dentry *dss_debugfs_dir; - static int dss_initialize_debugfs(struct dss_device *dss) { - dss_debugfs_dir = debugfs_create_dir("omapdss", NULL); - if (IS_ERR(dss_debugfs_dir)) { - int err = PTR_ERR(dss_debugfs_dir); + struct dentry *dir; - dss_debugfs_dir = NULL; - return err; - } + dir = debugfs_create_dir("omapdss", NULL); + if (IS_ERR(dir)) + return PTR_ERR(dir); + + dss->debugfs.root = dir; return 0; } -static void dss_uninitialize_debugfs(void) +static void dss_uninitialize_debugfs(struct dss_device *dss) { - if (dss_debugfs_dir) - debugfs_remove_recursive(dss_debugfs_dir); + debugfs_remove_recursive(dss->debugfs.root); } struct dss_debugfs_entry { @@ -942,8 +939,10 @@ static const struct file_operations dss_debug_fops = { .release= single_release, }; -struct dss_debugfs_entry *dss_debugfs_create_file(const char *name, - int (*show_fn)(struct seq_file *s, void *data), void *data) +struct dss_debugfs_entry * +dss_debugfs_create_file(struct dss_device *dss, const char *name, + int (*show_fn)(struct seq_file *s, void *data), + void *data) { struct dss_debugfs_entry *entry; struct dentry *d; @@ -955,7 +954,7 @@ struct dss_debugfs_entry *dss_debugfs_create_file(const char *name, entry->show_fn = show_fn; entry->data = data; - d = debugfs_create_file(name, 0444, dss_debugfs_dir, entry, + d = debugfs_create_file(name, 0444, dss->debugfs.root
[PATCH v2 19/30] drm: omapdrm: dsi: Don't pass channel to dispc init/uninit functions
The dsi_display_init_dispc() and dsi_display_uninit_dispc() functions take a channel argument that is reduntant as it is always identical to the dsi->output.dispc_channel. Remove the argument and use the field directly in the functions to avoid misuse. Signed-off-by: Laurent Pinchart Reviewed-by: Sebastian Reichel --- drivers/gpu/drm/omapdrm/dss/dsi.c | 21 ++--- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c index ecfdc6ef2500..0c4668e722b9 100644 --- a/drivers/gpu/drm/omapdrm/dss/dsi.c +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c @@ -215,10 +215,8 @@ struct dsi_reg { u16 module; u16 idx; }; typedef void (*omap_dsi_isr_t) (void *arg, u32 mask); struct dsi_data; -static int dsi_display_init_dispc(struct dsi_data *dsi, - enum omap_channel channel); -static void dsi_display_uninit_dispc(struct dsi_data *dsi, - enum omap_channel channel); +static int dsi_display_init_dispc(struct dsi_data *dsi); +static void dsi_display_uninit_dispc(struct dsi_data *dsi); static int dsi_vc_send_null(struct dsi_data *dsi, int channel); @@ -3845,7 +3843,7 @@ static int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel) return -ENODEV; } - r = dsi_display_init_dispc(dsi, dispc_channel); + r = dsi_display_init_dispc(dsi); if (r) goto err_init_dispc; @@ -3895,7 +3893,7 @@ static int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel) dsi_vc_enable(dsi, channel, false); } err_pix_fmt: - dsi_display_uninit_dispc(dsi, dispc_channel); + dsi_display_uninit_dispc(dsi); err_init_dispc: return r; } @@ -3918,7 +3916,7 @@ static void dsi_disable_video_output(struct omap_dss_device *dssdev, int channel dss_mgr_disable(dispc_channel); - dsi_display_uninit_dispc(dsi, dispc_channel); + dsi_display_uninit_dispc(dsi); } static void dsi_update_screen_dispc(struct dsi_data *dsi) @@ -4104,9 +4102,9 @@ static int dsi_configure_dispc_clocks(struct dsi_data *dsi) return 0; } -static int dsi_display_init_dispc(struct dsi_data *dsi, - enum omap_channel channel) +static int dsi_display_init_dispc(struct dsi_data *dsi) { + enum omap_channel channel = dsi->output.dispc_channel; int r; dss_select_lcd_clk_source(dsi->dss, channel, dsi->module_id == 0 ? @@ -4167,9 +4165,10 @@ static int dsi_display_init_dispc(struct dsi_data *dsi, return r; } -static void dsi_display_uninit_dispc(struct dsi_data *dsi, -enum omap_channel channel) +static void dsi_display_uninit_dispc(struct dsi_data *dsi) { + enum omap_channel channel = dsi->output.dispc_channel; + if (dsi->mode == OMAP_DSS_DSI_CMD_MODE) dss_mgr_unregister_framedone_handler(channel, dsi_framedone_irq_callback, dsi); -- Regards, Laurent Pinchart ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 25/30] drm: omapdrm: dispc: Pass DISPC pointer to remaining dispc API functions
This removes the need to access the global DISPC private data in those functions (both for the current accesses and the future ones that will be introduced when allocating the DISPC private data dynamically). Signed-off-by: Laurent Pinchart Reviewed-by: Sebastian Reichel --- drivers/gpu/drm/omapdrm/dss/dispc.c | 102 drivers/gpu/drm/omapdrm/dss/dpi.c | 12 +++-- drivers/gpu/drm/omapdrm/dss/dsi.c | 22 drivers/gpu/drm/omapdrm/dss/dss.c | 14 ++--- drivers/gpu/drm/omapdrm/dss/dss.h | 74 ++ drivers/gpu/drm/omapdrm/dss/hdmi4.c | 4 +- drivers/gpu/drm/omapdrm/dss/hdmi5.c | 4 +- drivers/gpu/drm/omapdrm/dss/sdi.c | 9 ++-- drivers/gpu/drm/omapdrm/dss/venc.c | 2 +- 9 files changed, 133 insertions(+), 110 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/dss/dispc.c b/drivers/gpu/drm/omapdrm/dss/dispc.c index 6d8228f976f9..bd014bfc1cb6 100644 --- a/drivers/gpu/drm/omapdrm/dss/dispc.c +++ b/drivers/gpu/drm/omapdrm/dss/dispc.c @@ -704,7 +704,7 @@ static u32 dispc_mgr_get_sync_lost_irq(struct dispc_device *dispc, return mgr_desc[channel].sync_lost_irq; } -u32 dispc_wb_get_framedone_irq(void) +u32 dispc_wb_get_framedone_irq(struct dispc_device *dispc) { return DISPC_IRQ_FRAMEDONEWB; } @@ -739,12 +739,12 @@ static void dispc_mgr_go(struct dispc_device *dispc, enum omap_channel channel) mgr_fld_write(channel, DISPC_MGR_FLD_GO, 1); } -bool dispc_wb_go_busy(void) +bool dispc_wb_go_busy(struct dispc_device *dispc) { return REG_GET(DISPC_CONTROL2, 6, 6) == 1; } -void dispc_wb_go(void) +void dispc_wb_go(struct dispc_device *dispc) { enum omap_plane_id plane = OMAP_DSS_WB; bool enable, go; @@ -1196,7 +1196,8 @@ static enum omap_channel dispc_ovl_get_channel_out(enum omap_plane_id plane) } } -void dispc_wb_set_channel_in(enum dss_writeback_channel channel) +void dispc_wb_set_channel_in(struct dispc_device *dispc, +enum dss_writeback_channel channel) { enum omap_plane_id plane = OMAP_DSS_WB; @@ -1371,10 +1372,10 @@ static void dispc_init_fifos(void) const bool use_fifomerge = false; const bool manual_update = false; - dispc_ovl_compute_fifo_thresholds(i, &low, &high, + dispc_ovl_compute_fifo_thresholds(&dispc, i, &low, &high, use_fifomerge, manual_update); - dispc_ovl_set_fifo_threshold(i, low, high); + dispc_ovl_set_fifo_threshold(&dispc, i, low, high); } if (dispc.feat->has_writeback) { @@ -1382,10 +1383,11 @@ static void dispc_init_fifos(void) const bool use_fifomerge = false; const bool manual_update = false; - dispc_ovl_compute_fifo_thresholds(OMAP_DSS_WB, &low, &high, - use_fifomerge, manual_update); + dispc_ovl_compute_fifo_thresholds(&dispc, OMAP_DSS_WB, + &low, &high, + use_fifomerge, manual_update); - dispc_ovl_set_fifo_threshold(OMAP_DSS_WB, low, high); + dispc_ovl_set_fifo_threshold(&dispc, OMAP_DSS_WB, low, high); } } @@ -1402,13 +1404,14 @@ static u32 dispc_ovl_get_fifo_size(enum omap_plane_id plane) return size; } -void dispc_ovl_set_fifo_threshold(enum omap_plane_id plane, u32 low, - u32 high) +void dispc_ovl_set_fifo_threshold(struct dispc_device *dispc, + enum omap_plane_id plane, + u32 low, u32 high) { u8 hi_start, hi_end, lo_start, lo_end; u32 unit; - unit = dispc.feat->buffer_size_unit; + unit = dispc->feat->buffer_size_unit; WARN_ON(low % unit != 0); WARN_ON(high % unit != 0); @@ -1436,12 +1439,12 @@ void dispc_ovl_set_fifo_threshold(enum omap_plane_id plane, u32 low, * large for the preload field, set the threshold to the maximum value * that can be held by the preload register */ - if (dispc_has_feature(FEAT_PRELOAD) && dispc.feat->set_max_preload && + if (dispc_has_feature(FEAT_PRELOAD) && dispc->feat->set_max_preload && plane != OMAP_DSS_WB) dispc_write_reg(DISPC_OVL_PRELOAD(plane), min(high, 0xfffu)); } -void dispc_enable_fifomerge(bool enable) +void dispc_enable_fifomerge(struct dispc_device *dispc, bool enable) { if (!dispc_has_feature(FEAT_FIFO_MERGE)) { WARN_ON(enable); @@ -1452,15 +1455,16 @@ void dispc_enable_fifomerge(bool enable) REG_FLD_MOD(DISPC_CONFIG, enable ? 1 : 0, 14, 14); } -void dispc_ovl_compute_fifo_thresholds(enum omap_plane_id plane, - u32 *fifo_low, u32 *fifo_high, bool use_fifomerge, - bool manual_update) +void dispc_ovl_
[PATCH v2 28/30] drm: omapdrm: hdmi5: Allocate the omap_hdmi data structure dynamically
The omap_hdmi private data structure is currently stored as a global variable. While no platform with multiple HDMI5 encoders currently exists nor is planned, this doesn't comply with the kernel device model and should thus be fixed. Signed-off-by: Laurent Pinchart Reviewed-by: Sebastian Reichel --- Changes since v1: - Fixed device name string that had been incorrectly modified --- drivers/gpu/drm/omapdrm/dss/hdmi5.c | 364 +++- 1 file changed, 196 insertions(+), 168 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi5.c b/drivers/gpu/drm/omapdrm/dss/hdmi5.c index a83d70144f85..4a0178ab8016 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi5.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi5.c @@ -46,15 +46,13 @@ #include "hdmi5_core.h" #include "dss.h" -static struct omap_hdmi hdmi; - -static int hdmi_runtime_get(void) +static int hdmi_runtime_get(struct omap_hdmi *hdmi) { int r; DSSDBG("hdmi_runtime_get\n"); - r = pm_runtime_get_sync(&hdmi.pdev->dev); + r = pm_runtime_get_sync(&hdmi->pdev->dev); WARN_ON(r < 0); if (r < 0) return r; @@ -62,19 +60,20 @@ static int hdmi_runtime_get(void) return 0; } -static void hdmi_runtime_put(void) +static void hdmi_runtime_put(struct omap_hdmi *hdmi) { int r; DSSDBG("hdmi_runtime_put\n"); - r = pm_runtime_put_sync(&hdmi.pdev->dev); + r = pm_runtime_put_sync(&hdmi->pdev->dev); WARN_ON(r < 0 && r != -ENOSYS); } static irqreturn_t hdmi_irq_handler(int irq, void *data) { - struct hdmi_wp_data *wp = data; + struct omap_hdmi *hdmi = data; + struct hdmi_wp_data *wp = &hdmi->wp; u32 irqstatus; irqstatus = hdmi_wp_get_irqstatus(wp); @@ -97,17 +96,17 @@ static irqreturn_t hdmi_irq_handler(int irq, void *data) * setting the PHY to LDOON. To ignore those, we force the RXDET * line to 0 until the PHY power state has been changed. */ - v = hdmi_read_reg(hdmi.phy.base, HDMI_TXPHY_PAD_CFG_CTRL); + v = hdmi_read_reg(hdmi->phy.base, HDMI_TXPHY_PAD_CFG_CTRL); v = FLD_MOD(v, 1, 15, 15); /* FORCE_RXDET_HIGH */ v = FLD_MOD(v, 0, 14, 7); /* RXDET_LINE */ - hdmi_write_reg(hdmi.phy.base, HDMI_TXPHY_PAD_CFG_CTRL, v); + hdmi_write_reg(hdmi->phy.base, HDMI_TXPHY_PAD_CFG_CTRL, v); hdmi_wp_set_irqstatus(wp, HDMI_IRQ_LINK_CONNECT | HDMI_IRQ_LINK_DISCONNECT); hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON); - REG_FLD_MOD(hdmi.phy.base, HDMI_TXPHY_PAD_CFG_CTRL, 0, 15, 15); + REG_FLD_MOD(hdmi->phy.base, HDMI_TXPHY_PAD_CFG_CTRL, 0, 15, 15); } else if (irqstatus & HDMI_IRQ_LINK_CONNECT) { hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_TXON); @@ -118,69 +117,69 @@ static irqreturn_t hdmi_irq_handler(int irq, void *data) return IRQ_HANDLED; } -static int hdmi_init_regulator(void) +static int hdmi_init_regulator(struct omap_hdmi *hdmi) { struct regulator *reg; - if (hdmi.vdda_reg != NULL) + if (hdmi->vdda_reg != NULL) return 0; - reg = devm_regulator_get(&hdmi.pdev->dev, "vdda"); + reg = devm_regulator_get(&hdmi->pdev->dev, "vdda"); if (IS_ERR(reg)) { DSSERR("can't get VDDA regulator\n"); return PTR_ERR(reg); } - hdmi.vdda_reg = reg; + hdmi->vdda_reg = reg; return 0; } -static int hdmi_power_on_core(struct omap_dss_device *dssdev) +static int hdmi_power_on_core(struct omap_hdmi *hdmi) { int r; - r = regulator_enable(hdmi.vdda_reg); + r = regulator_enable(hdmi->vdda_reg); if (r) return r; - r = hdmi_runtime_get(); + r = hdmi_runtime_get(hdmi); if (r) goto err_runtime_get; /* Make selection of HDMI in DSS */ - dss_select_hdmi_venc_clk_source(hdmi.dss, DSS_HDMI_M_PCLK); + dss_select_hdmi_venc_clk_source(hdmi->dss, DSS_HDMI_M_PCLK); - hdmi.core_enabled = true; + hdmi->core_enabled = true; return 0; err_runtime_get: - regulator_disable(hdmi.vdda_reg); + regulator_disable(hdmi->vdda_reg); return r; } -static void hdmi_power_off_core(struct omap_dss_device *dssdev) +static void hdmi_power_off_core(struct omap_hdmi *hdmi) { - hdmi.core_enabled = false; + hdmi->core_enabled = false; - hdmi_runtime_put(); - regulator_disable(hdmi.vdda_reg); + hdmi_runtime_put(hdmi); + regulator_disable(hdmi->vdda_reg); } -static int hdmi_power_on_full(struct omap_dss_device *dssdev) +static int hdmi_power_on_full(struct omap_hdmi *hdmi) { int r; struct videomode *vm; struct dss_pll_clock_info hdmi_cinfo = { 0 }; unsigned int pc;
[PATCH v2 15/30] drm: omapdrm: dsi: Pass the dsi_data pointer to internal functions
Internal dsi functions take a pointer to the DSI platform_device and then cast it to a dsi_data pointer. That's pointless as the caller already has the dsi_data pointer. Pass it directly instead of the platform_device pointer. Signed-off-by: Laurent Pinchart Reviewed-by: Sebastian Reichel --- drivers/gpu/drm/omapdrm/dss/dsi.c | 1228 + 1 file changed, 564 insertions(+), 664 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c index 05030dc25c72..7b5656e6abbb 100644 --- a/drivers/gpu/drm/omapdrm/dss/dsi.c +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c @@ -119,11 +119,11 @@ struct dsi_reg { u16 module; u16 idx; }; #define DSI_PLL_CONFIGURATION1 DSI_REG(DSI_PLL, 0x000C) #define DSI_PLL_CONFIGURATION2 DSI_REG(DSI_PLL, 0x0010) -#define REG_GET(dsidev, idx, start, end) \ - FLD_GET(dsi_read_reg(dsidev, idx), start, end) +#define REG_GET(dsi, idx, start, end) \ + FLD_GET(dsi_read_reg(dsi, idx), start, end) -#define REG_FLD_MOD(dsidev, idx, val, start, end) \ - dsi_write_reg(dsidev, idx, FLD_MOD(dsi_read_reg(dsidev, idx), val, start, end)) +#define REG_FLD_MOD(dsi, idx, val, start, end) \ + dsi_write_reg(dsi, idx, FLD_MOD(dsi_read_reg(dsi, idx), val, start, end)) /* Global interrupts */ #define DSI_IRQ_VC0(1 << 0) @@ -213,13 +213,14 @@ struct dsi_reg { u16 module; u16 idx; }; DSI_CIO_IRQ_ERRCONTENTIONLP0_5 | DSI_CIO_IRQ_ERRCONTENTIONLP1_5) typedef void (*omap_dsi_isr_t) (void *arg, u32 mask); +struct dsi_data; -static int dsi_display_init_dispc(struct platform_device *dsidev, +static int dsi_display_init_dispc(struct dsi_data *dsi, enum omap_channel channel); -static void dsi_display_uninit_dispc(struct platform_device *dsidev, +static void dsi_display_uninit_dispc(struct dsi_data *dsi, enum omap_channel channel); -static int dsi_vc_send_null(struct omap_dss_device *dssdev, int channel); +static int dsi_vc_send_null(struct dsi_data *dsi, int channel); /* DSI PLL HSDIV indices */ #define HSDIV_DISPC0 @@ -282,7 +283,7 @@ struct dsi_isr_tables { }; struct dsi_clk_calc_ctx { - struct platform_device *dsidev; + struct dsi_data *dsi; struct dss_pll *pll; /* inputs */ @@ -429,7 +430,7 @@ struct dsi_data { }; struct dsi_packet_sent_handler_data { - struct platform_device *dsidev; + struct dsi_data *dsi; struct completion *completion; }; @@ -448,7 +449,7 @@ static inline struct platform_device *dsi_get_dsidev_from_dssdev(struct omap_dss return to_platform_device(dssdev->dev); } -static struct platform_device *dsi_get_dsidev_from_id(int module) +static struct dsi_data *dsi_get_dsi_from_id(int module) { struct omap_dss_device *out; enum omap_dss_output_id id; @@ -466,13 +467,12 @@ static struct platform_device *dsi_get_dsidev_from_id(int module) out = omap_dss_get_output(id); - return out ? to_platform_device(out->dev) : NULL; + return out ? dsi_get_dsidrv_data(to_platform_device(out->dev)) : NULL; } -static inline void dsi_write_reg(struct platform_device *dsidev, - const struct dsi_reg idx, u32 val) +static inline void dsi_write_reg(struct dsi_data *dsi, +const struct dsi_reg idx, u32 val) { - struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); void __iomem *base; switch(idx.module) { @@ -485,10 +485,8 @@ static inline void dsi_write_reg(struct platform_device *dsidev, __raw_writel(val, base + idx.idx); } -static inline u32 dsi_read_reg(struct platform_device *dsidev, - const struct dsi_reg idx) +static inline u32 dsi_read_reg(struct dsi_data *dsi, const struct dsi_reg idx) { - struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); void __iomem *base; switch(idx.module) { @@ -517,10 +515,8 @@ static void dsi_bus_unlock(struct omap_dss_device *dssdev) up(&dsi->bus_lock); } -static bool dsi_bus_is_locked(struct platform_device *dsidev) +static bool dsi_bus_is_locked(struct dsi_data *dsi) { - struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); - return dsi->bus_lock.count == 0; } @@ -529,8 +525,9 @@ static void dsi_completion_handler(void *data, u32 mask) complete((struct completion *)data); } -static inline bool wait_for_bit_change(struct platform_device *dsidev, - const struct dsi_reg idx, int bitnum, int value) +static inline bool wait_for_bit_change(struct dsi_data *dsi, + const struct dsi_reg idx, + int bitnum, int value) { unsigned long timeout; ktime_t wait; @@ -539,14 +536,14 @@ static inline bool wait_for_bit_change(struct platform_device *dsidev, /* first busyloop to see if the bit changes right away */ t = 100; while (t-- > 0) { -
[PATCH v2 24/30] drm: omapdrm: dispc: Pass DISPC pointer to dispc_ops operations
This removes the need to access the global DISPC private data in those functions (both for the current accesses and the future ones that will be introduced when allocating the DISPC private data dynamically). In order to allow the omapdrm side to call the dispc_ops with a DISPC pointer, we also introduce a new function dss_get_dispc() to retrieve the DISPC corresponding to the DSS. Signed-off-by: Laurent Pinchart Reviewed-by: Sebastian Reichel --- drivers/gpu/drm/omapdrm/dss/base.c| 6 + drivers/gpu/drm/omapdrm/dss/dispc.c | 223 ++ drivers/gpu/drm/omapdrm/dss/dpi.c | 6 +- drivers/gpu/drm/omapdrm/dss/dsi.c | 4 +- drivers/gpu/drm/omapdrm/dss/dss.h | 6 +- drivers/gpu/drm/omapdrm/dss/hdmi4.c | 7 +- drivers/gpu/drm/omapdrm/dss/hdmi5.c | 7 +- drivers/gpu/drm/omapdrm/dss/omapdss.h | 95 +-- drivers/gpu/drm/omapdrm/dss/sdi.c | 6 +- drivers/gpu/drm/omapdrm/dss/venc.c| 4 +- drivers/gpu/drm/omapdrm/omap_crtc.c | 31 +++-- drivers/gpu/drm/omapdrm/omap_drv.c| 13 +- drivers/gpu/drm/omapdrm/omap_drv.h| 1 + drivers/gpu/drm/omapdrm/omap_irq.c| 32 ++--- drivers/gpu/drm/omapdrm/omap_plane.c | 12 +- 15 files changed, 257 insertions(+), 196 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/dss/base.c b/drivers/gpu/drm/omapdrm/dss/base.c index c248c3c31904..99e8cb8dc65b 100644 --- a/drivers/gpu/drm/omapdrm/dss/base.c +++ b/drivers/gpu/drm/omapdrm/dss/base.c @@ -44,6 +44,12 @@ void omapdss_set_dss(struct dss_device *dss) } EXPORT_SYMBOL(omapdss_set_dss); +struct dispc_device *dispc_get_dispc(struct dss_device *dss) +{ + return dss->dispc; +} +EXPORT_SYMBOL(dispc_get_dispc); + const struct dispc_ops *dispc_get_ops(struct dss_device *dss) { return dss->dispc_ops; diff --git a/drivers/gpu/drm/omapdrm/dss/dispc.c b/drivers/gpu/drm/omapdrm/dss/dispc.c index aae6037f499f..6d8228f976f9 100644 --- a/drivers/gpu/drm/omapdrm/dss/dispc.c +++ b/drivers/gpu/drm/omapdrm/dss/dispc.c @@ -162,7 +162,7 @@ struct dispc_features { #define DISPC_MAX_NR_FIFOS 5 #define DISPC_MAX_CHANNEL_GAMMA 4 -static struct { +struct dispc_device { struct platform_device *pdev; void __iomem*base; struct dss_device *dss; @@ -194,7 +194,9 @@ static struct { /* DISPC_CONTROL & DISPC_CONFIG lock*/ spinlock_t control_lock; -} dispc; +}; + +static struct dispc_device dispc; enum omap_color_component { /* used for all color formats for OMAP3 and earlier @@ -361,9 +363,7 @@ static unsigned long dispc_mgr_pclk_rate(enum omap_channel channel); static unsigned long dispc_plane_pclk_rate(enum omap_plane_id plane); static unsigned long dispc_plane_lclk_rate(enum omap_plane_id plane); -static void dispc_clear_irqstatus(u32 mask); -static bool dispc_mgr_is_enabled(enum omap_channel channel); -static void dispc_clear_irqstatus(u32 mask); +static void dispc_clear_irqstatus(struct dispc_device *dispc, u32 mask); static inline void dispc_write_reg(const u16 idx, u32 val) { @@ -396,14 +396,14 @@ static void mgr_fld_write(enum omap_channel channel, spin_unlock_irqrestore(&dispc.control_lock, flags); } -static int dispc_get_num_ovls(void) +static int dispc_get_num_ovls(struct dispc_device *dispc) { - return dispc.feat->num_ovls; + return dispc->feat->num_ovls; } -static int dispc_get_num_mgrs(void) +static int dispc_get_num_mgrs(struct dispc_device *dispc) { - return dispc.feat->num_mgrs; + return dispc->feat->num_mgrs; } static void dispc_get_reg_field(enum dispc_feat_reg_field id, @@ -455,7 +455,7 @@ static void dispc_save_context(void) SR(CONFIG3); } - for (i = 0; i < dispc_get_num_mgrs(); i++) { + for (i = 0; i < dispc_get_num_mgrs(&dispc); i++) { SR(DEFAULT_COLOR(i)); SR(TRANS_COLOR(i)); SR(SIZE_MGR(i)); @@ -477,7 +477,7 @@ static void dispc_save_context(void) } } - for (i = 0; i < dispc_get_num_ovls(); i++) { + for (i = 0; i < dispc_get_num_ovls(&dispc); i++) { SR(OVL_BA0(i)); SR(OVL_BA1(i)); SR(OVL_POSITION(i)); @@ -561,7 +561,7 @@ static void dispc_restore_context(void) if (dispc_has_feature(FEAT_MGR_LCD3)) RR(CONFIG3); - for (i = 0; i < dispc_get_num_mgrs(); i++) { + for (i = 0; i < dispc_get_num_mgrs(&dispc); i++) { RR(DEFAULT_COLOR(i)); RR(TRANS_COLOR(i)); RR(SIZE_MGR(i)); @@ -583,7 +583,7 @@ static void dispc_restore_context(void) } } - for (i = 0; i < dispc_get_num_ovls(); i++) { + for (i = 0; i < dispc_get_num_ovls(&dispc); i++) { RR(OVL_BA0(i)); RR(OVL_BA1(i)); RR(OVL_POSITION(i)); @@ -648,7 +648,7 @@ static void dispc_restore_context(void) if (dispc_has_fea
[PATCH v2 22/30] drm: omapdrm: dss: Store DSS device pointer in the omapdrm private data
The dss_device is the top-level component in the omapdss driver. Give the omapdrm driver access to the dss_device pointer in order to obtain pointers to all other components from it. This requires a new global variable in the omapdss driver that will be removed when merging the omapdrm and omapdss drivers, but will already allow removal of several other global variables. As this partly duplicates the omapdss_is_initialized() API, reimplement it as an inline function wrapping omapdss_get_dss(). Signed-off-by: Laurent Pinchart --- drivers/gpu/drm/omapdrm/dss/base.c| 14 +++--- drivers/gpu/drm/omapdrm/dss/dss.c | 5 +++-- drivers/gpu/drm/omapdrm/dss/omapdss.h | 10 +++--- drivers/gpu/drm/omapdrm/omap_drv.c| 1 + drivers/gpu/drm/omapdrm/omap_drv.h| 1 + 5 files changed, 19 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/dss/base.c b/drivers/gpu/drm/omapdrm/dss/base.c index 67cc87a4f1f6..6346bc967a77 100644 --- a/drivers/gpu/drm/omapdrm/dss/base.c +++ b/drivers/gpu/drm/omapdrm/dss/base.c @@ -20,7 +20,7 @@ #include #include "omapdss.h" -static bool dss_initialized; +static struct dss_device *dss_device; static const struct dispc_ops *ops; static struct list_head omapdss_comp_list; @@ -31,17 +31,17 @@ struct omapdss_comp_node { bool dss_core_component; }; -void omapdss_set_is_initialized(bool set) +struct dss_device *omapdss_get_dss(void) { - dss_initialized = set; + return dss_device; } -EXPORT_SYMBOL(omapdss_set_is_initialized); +EXPORT_SYMBOL(omapdss_get_dss); -bool omapdss_is_initialized(void) +void omapdss_set_dss(struct dss_device *dss) { - return dss_initialized; + dss_device = dss; } -EXPORT_SYMBOL(omapdss_is_initialized); +EXPORT_SYMBOL(omapdss_set_dss); void dispc_set_ops(const struct dispc_ops *o) { diff --git a/drivers/gpu/drm/omapdrm/dss/dss.c b/drivers/gpu/drm/omapdrm/dss/dss.c index 14d2f024eb70..ca2efb937d42 100644 --- a/drivers/gpu/drm/omapdrm/dss/dss.c +++ b/drivers/gpu/drm/omapdrm/dss/dss.c @@ -1316,6 +1316,7 @@ static const struct soc_device_attribute dss_soc_devices[] = { static int dss_bind(struct device *dev) { + struct dss_device *dss = dev_get_drvdata(dev); int r; r = component_bind_all(dev, NULL); @@ -1325,14 +1326,14 @@ static int dss_bind(struct device *dev) pm_set_vt_switch(0); omapdss_gather_components(dev); - omapdss_set_is_initialized(true); + omapdss_set_dss(dss); return 0; } static void dss_unbind(struct device *dev) { - omapdss_set_is_initialized(false); + omapdss_set_dss(NULL); component_unbind_all(dev, NULL); } diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h index 318641f5bc24..312485714703 100644 --- a/drivers/gpu/drm/omapdrm/dss/omapdss.h +++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h @@ -59,6 +59,7 @@ #define DISPC_IRQ_ACBIAS_COUNT_STAT3 (1 << 29) #define DISPC_IRQ_FRAMEDONE3 (1 << 30) +struct dss_device; struct omap_drm_private; struct omap_dss_device; struct dss_lcd_mgr_config; @@ -586,7 +587,12 @@ struct omap_dss_driver { const struct hdmi_avi_infoframe *avi); }; -bool omapdss_is_initialized(void); +struct dss_device *omapdss_get_dss(void); +void omapdss_set_dss(struct dss_device *dss); +static inline bool omapdss_is_initialized(void) +{ + return !!omapdss_get_dss(); +} int omapdss_register_display(struct omap_dss_device *dssdev); void omapdss_unregister_display(struct omap_dss_device *dssdev); @@ -630,8 +636,6 @@ static inline bool omapdss_device_is_enabled(struct omap_dss_device *dssdev) struct omap_dss_device * omapdss_of_find_source_for_first_ep(struct device_node *node); -void omapdss_set_is_initialized(bool set); - struct device_node *dss_of_port_get_parent_device(struct device_node *port); u32 dss_of_port_get_port_number(struct device_node *port); diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c index 39e78f765f7e..003445b70ee7 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.c +++ b/drivers/gpu/drm/omapdrm/omap_drv.c @@ -527,6 +527,7 @@ static int omapdrm_init(struct omap_drm_private *priv, struct device *dev) if (ret) goto err_crtc_uninit; + priv->dss = omapdss_get_dss(); priv->dispc_ops = dispc_get_ops(); soc = soc_device_match(omapdrm_soc_devices); diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h index 49351bb3731e..a7962c14fc7c 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.h +++ b/drivers/gpu/drm/omapdrm/omap_drv.h @@ -50,6 +50,7 @@ struct omap_drm_private { struct device *dev; u32 omaprev; + struct dss_device *dss; const struct dispc_ops *dispc_ops; unsigned int num_crtcs; -- Regards, Laurent Pinchart ___ dri-devel mailing list dri-devel@lists.freede
[PATCH v2 14/30] drm: omapdrm: dss: Don't unnecessarily cast to dev to pdev and back
The dss_unbind() function casts the struct device pointer to a struct platform_device, only to later use the struct device pointer from platform_device. Don't cast at all. Signed-off-by: Laurent Pinchart --- drivers/gpu/drm/omapdrm/dss/dss.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/dss/dss.c b/drivers/gpu/drm/omapdrm/dss/dss.c index 7a5f5f233ad0..14d2f024eb70 100644 --- a/drivers/gpu/drm/omapdrm/dss/dss.c +++ b/drivers/gpu/drm/omapdrm/dss/dss.c @@ -1332,11 +1332,9 @@ static int dss_bind(struct device *dev) static void dss_unbind(struct device *dev) { - struct platform_device *pdev = to_platform_device(dev); - omapdss_set_is_initialized(false); - component_unbind_all(&pdev->dev, NULL); + component_unbind_all(dev, NULL); } static const struct component_master_ops dss_component_ops = { -- Regards, Laurent Pinchart ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 23/30] drm: omapdrm: dss: Store dispc ops in dss_device structure
Remove the global dispc ops variable by storing it in the dss_device structure. Signed-off-by: Laurent Pinchart --- drivers/gpu/drm/omapdrm/dss/base.c| 13 - drivers/gpu/drm/omapdrm/dss/dispc.c | 6 -- drivers/gpu/drm/omapdrm/dss/dss.h | 2 ++ drivers/gpu/drm/omapdrm/dss/omapdss.h | 3 +-- drivers/gpu/drm/omapdrm/omap_crtc.c | 4 +--- drivers/gpu/drm/omapdrm/omap_drv.c| 5 ++--- 6 files changed, 14 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/dss/base.c b/drivers/gpu/drm/omapdrm/dss/base.c index 6346bc967a77..c248c3c31904 100644 --- a/drivers/gpu/drm/omapdrm/dss/base.c +++ b/drivers/gpu/drm/omapdrm/dss/base.c @@ -18,10 +18,11 @@ #include #include #include + +#include "dss.h" #include "omapdss.h" static struct dss_device *dss_device; -static const struct dispc_ops *ops; static struct list_head omapdss_comp_list; @@ -43,15 +44,9 @@ void omapdss_set_dss(struct dss_device *dss) } EXPORT_SYMBOL(omapdss_set_dss); -void dispc_set_ops(const struct dispc_ops *o) -{ - ops = o; -} -EXPORT_SYMBOL(dispc_set_ops); - -const struct dispc_ops *dispc_get_ops(void) +const struct dispc_ops *dispc_get_ops(struct dss_device *dss) { - return ops; + return dss->dispc_ops; } EXPORT_SYMBOL(dispc_get_ops); diff --git a/drivers/gpu/drm/omapdrm/dss/dispc.c b/drivers/gpu/drm/omapdrm/dss/dispc.c index 8019cc9f4f97..aae6037f499f 100644 --- a/drivers/gpu/drm/omapdrm/dss/dispc.c +++ b/drivers/gpu/drm/omapdrm/dss/dispc.c @@ -4622,7 +4622,7 @@ static int dispc_bind(struct device *dev, struct device *master, void *data) dispc_runtime_put(); - dispc_set_ops(&dispc_ops); + dss->dispc_ops = &dispc_ops; dispc.debugfs = dss_debugfs_create_file(dss, "dispc", dispc_dump_regs, &dispc); @@ -4637,9 +4637,11 @@ static int dispc_bind(struct device *dev, struct device *master, void *data) static void dispc_unbind(struct device *dev, struct device *master, void *data) { + struct dss_device *dss = dispc.dss; + dss_debugfs_remove_file(dispc.debugfs); - dispc_set_ops(NULL); + dss->dispc_ops = NULL; pm_runtime_disable(dev); diff --git a/drivers/gpu/drm/omapdrm/dss/dss.h b/drivers/gpu/drm/omapdrm/dss/dss.h index 764c52025a27..348378f1b5a5 100644 --- a/drivers/gpu/drm/omapdrm/dss/dss.h +++ b/drivers/gpu/drm/omapdrm/dss/dss.h @@ -271,6 +271,8 @@ struct dss_device { struct dss_pll *plls[4]; struct dss_pll *video1_pll; struct dss_pll *video2_pll; + + const struct dispc_ops *dispc_ops; }; /* core */ diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h index 312485714703..4bf7843b4aec 100644 --- a/drivers/gpu/drm/omapdrm/dss/omapdss.h +++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h @@ -733,8 +733,7 @@ struct dispc_ops { const u32 *(*ovl_get_color_modes)(enum omap_plane_id plane); }; -void dispc_set_ops(const struct dispc_ops *o); -const struct dispc_ops *dispc_get_ops(void); +const struct dispc_ops *dispc_get_ops(struct dss_device *dss); bool omapdss_component_is_display(struct device_node *node); bool omapdss_component_is_output(struct device_node *node); diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c index 61d8d17a4243..ffe4f698d291 100644 --- a/drivers/gpu/drm/omapdrm/omap_crtc.c +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c @@ -117,12 +117,10 @@ static int omap_crtc_dss_connect(struct omap_drm_private *priv, enum omap_channel channel, struct omap_dss_device *dst) { - const struct dispc_ops *dispc_ops = dispc_get_ops(); - if (omap_crtc_output[channel]) return -EINVAL; - if ((dispc_ops->mgr_get_supported_outputs(channel) & dst->id) == 0) + if (!(priv->dispc_ops->mgr_get_supported_outputs(channel) & dst->id)) return -EINVAL; omap_crtc_output[channel] = dst; diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c index 003445b70ee7..a93916cd0258 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.c +++ b/drivers/gpu/drm/omapdrm/omap_drv.c @@ -520,6 +520,8 @@ static int omapdrm_init(struct omap_drm_private *priv, struct device *dev) DBG("%s", dev_name(dev)); priv->dev = dev; + priv->dss = omapdss_get_dss(); + priv->dispc_ops = dispc_get_ops(priv->dss); omap_crtc_pre_init(priv); @@ -527,9 +529,6 @@ static int omapdrm_init(struct omap_drm_private *priv, struct device *dev) if (ret) goto err_crtc_uninit; - priv->dss = omapdss_get_dss(); - priv->dispc_ops = dispc_get_ops(); - soc = soc_device_match(omapdrm_soc_devices); priv->omaprev = soc ? (unsigned int)soc->data : 0; priv->wq = alloc_ordered_workqueue("omapdrm", 0); -- Regards, Laurent Pinchart __
Re: [PATCH v7 1/6] base: power: runtime: Export pm_runtime_get/put_suppliers
On 13/02/18 07:44, Tomasz Figa wrote: Hi Vivek, On Wed, Feb 7, 2018 at 7:31 PM, Vivek Gautam wrote: The device link allows the pm framework to tie the supplier and consumer. So, whenever the consumer is powered-on the supplier is powered-on first. There are however cases in which the consumer wants to power-on the supplier, but not itself. E.g., A Graphics or multimedia driver wants to power-on the SMMU to unmap a buffer and finish the TLB operations without powering on itself. This sounds strange to me. If the SMMU is powered down, wouldn't the TLB lose its contents as well (and so no flushing needed)? Depends on implementation details - if runtime PM is actually implemented via external clock gating (in the absence of fine-grained power domains), then "suspended" TLBs might both retain state and not receive invalidation requests, which is really the worst case. Other than that, what kind of hardware operations would be needed besides just updating the page tables from the CPU? Domain attach/detach also require updating SMMU hardware state (and possibly TLB maintenance), but don't logically require the master device itself to be active at the time. Robin. ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 30/30] drm: omapdrm: venc: Allocate the venc private data structure dynamically
The venc private data structure is currently stored as a global variable. While no platform with multiple VENC encoders currently exists nor is planned, this doesn't comply with the kernel device model and should thus be fixed. Signed-off-by: Laurent Pinchart Reviewed-by: Sebastian Reichel --- drivers/gpu/drm/omapdrm/dss/venc.c | 442 - 1 file changed, 238 insertions(+), 204 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/dss/venc.c b/drivers/gpu/drm/omapdrm/dss/venc.c index 12a0ac4e1eb1..24d1ced210bd 100644 --- a/drivers/gpu/drm/omapdrm/dss/venc.c +++ b/drivers/gpu/drm/omapdrm/dss/venc.c @@ -319,7 +319,7 @@ static enum venc_videomode venc_get_videomode(const struct videomode *vm) return VENC_MODE_UNKNOWN; } -static struct { +struct venc_device { struct platform_device *pdev; void __iomem *base; struct mutex venc_lock; @@ -337,81 +337,87 @@ static struct { bool requires_tv_dac_clk; struct omap_dss_device output; -} venc; +}; + +#define dssdev_to_venc(dssdev) container_of(dssdev, struct venc_device, output) -static inline void venc_write_reg(int idx, u32 val) +static inline void venc_write_reg(struct venc_device *venc, int idx, u32 val) { - __raw_writel(val, venc.base + idx); + __raw_writel(val, venc->base + idx); } -static inline u32 venc_read_reg(int idx) +static inline u32 venc_read_reg(struct venc_device *venc, int idx) { - u32 l = __raw_readl(venc.base + idx); + u32 l = __raw_readl(venc->base + idx); return l; } -static void venc_write_config(const struct venc_config *config) +static void venc_write_config(struct venc_device *venc, + const struct venc_config *config) { DSSDBG("write venc conf\n"); - venc_write_reg(VENC_LLEN, config->llen); - venc_write_reg(VENC_FLENS, config->flens); - venc_write_reg(VENC_CC_CARR_WSS_CARR, config->cc_carr_wss_carr); - venc_write_reg(VENC_C_PHASE, config->c_phase); - venc_write_reg(VENC_GAIN_U, config->gain_u); - venc_write_reg(VENC_GAIN_V, config->gain_v); - venc_write_reg(VENC_GAIN_Y, config->gain_y); - venc_write_reg(VENC_BLACK_LEVEL, config->black_level); - venc_write_reg(VENC_BLANK_LEVEL, config->blank_level); - venc_write_reg(VENC_M_CONTROL, config->m_control); - venc_write_reg(VENC_BSTAMP_WSS_DATA, config->bstamp_wss_data | - venc.wss_data); - venc_write_reg(VENC_S_CARR, config->s_carr); - venc_write_reg(VENC_L21__WC_CTL, config->l21__wc_ctl); - venc_write_reg(VENC_SAVID__EAVID, config->savid__eavid); - venc_write_reg(VENC_FLEN__FAL, config->flen__fal); - venc_write_reg(VENC_LAL__PHASE_RESET, config->lal__phase_reset); - venc_write_reg(VENC_HS_INT_START_STOP_X, config->hs_int_start_stop_x); - venc_write_reg(VENC_HS_EXT_START_STOP_X, config->hs_ext_start_stop_x); - venc_write_reg(VENC_VS_INT_START_X, config->vs_int_start_x); - venc_write_reg(VENC_VS_INT_STOP_X__VS_INT_START_Y, + venc_write_reg(venc, VENC_LLEN, config->llen); + venc_write_reg(venc, VENC_FLENS, config->flens); + venc_write_reg(venc, VENC_CC_CARR_WSS_CARR, config->cc_carr_wss_carr); + venc_write_reg(venc, VENC_C_PHASE, config->c_phase); + venc_write_reg(venc, VENC_GAIN_U, config->gain_u); + venc_write_reg(venc, VENC_GAIN_V, config->gain_v); + venc_write_reg(venc, VENC_GAIN_Y, config->gain_y); + venc_write_reg(venc, VENC_BLACK_LEVEL, config->black_level); + venc_write_reg(venc, VENC_BLANK_LEVEL, config->blank_level); + venc_write_reg(venc, VENC_M_CONTROL, config->m_control); + venc_write_reg(venc, VENC_BSTAMP_WSS_DATA, config->bstamp_wss_data | + venc->wss_data); + venc_write_reg(venc, VENC_S_CARR, config->s_carr); + venc_write_reg(venc, VENC_L21__WC_CTL, config->l21__wc_ctl); + venc_write_reg(venc, VENC_SAVID__EAVID, config->savid__eavid); + venc_write_reg(venc, VENC_FLEN__FAL, config->flen__fal); + venc_write_reg(venc, VENC_LAL__PHASE_RESET, config->lal__phase_reset); + venc_write_reg(venc, VENC_HS_INT_START_STOP_X, + config->hs_int_start_stop_x); + venc_write_reg(venc, VENC_HS_EXT_START_STOP_X, + config->hs_ext_start_stop_x); + venc_write_reg(venc, VENC_VS_INT_START_X, config->vs_int_start_x); + venc_write_reg(venc, VENC_VS_INT_STOP_X__VS_INT_START_Y, config->vs_int_stop_x__vs_int_start_y); - venc_write_reg(VENC_VS_INT_STOP_Y__VS_EXT_START_X, + venc_write_reg(venc, VENC_VS_INT_STOP_Y__VS_EXT_START_X, config->vs_int_stop_y__vs_ext_start_x); - venc_write_reg(VENC_VS_EXT_STOP_X__VS_EXT_START_Y, + venc_write_reg(venc, VENC_VS_EXT_STOP_X__VS_EXT_START_Y, config->vs_ext_stop_x__vs_ext_start_y); - venc_write_reg(V
[PATCH v2 27/30] drm: omapdrm: hdmi4: Allocate the omap_hdmi data structure dynamically
The omap_hdmi private data structure is currently stored as a global variable. While no platform with multiple HDMI4 encoders currently exists nor is planned, this doesn't comply with the kernel device model and should thus be fixed. Signed-off-by: Laurent Pinchart Reviewed-by: Sebastian Reichel --- Changes since v1: - Fixed device name string that had been incorrectly modified --- drivers/gpu/drm/omapdrm/dss/hdmi.h | 2 + drivers/gpu/drm/omapdrm/dss/hdmi4.c | 356 +-- drivers/gpu/drm/omapdrm/dss/hdmi4_cec.c | 4 +- drivers/gpu/drm/omapdrm/dss/hdmi4_core.h | 4 +- 4 files changed, 200 insertions(+), 166 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi.h b/drivers/gpu/drm/omapdrm/dss/hdmi.h index fa2fbdaa427c..3aeb4cabd59f 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi.h +++ b/drivers/gpu/drm/omapdrm/dss/hdmi.h @@ -389,4 +389,6 @@ struct omap_hdmi { bool display_enabled; }; +#define dssdev_to_hdmi(dssdev) container_of(dssdev, struct omap_hdmi, output) + #endif diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c b/drivers/gpu/drm/omapdrm/dss/hdmi4.c index 815865c09ac1..1f7897c58f2f 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c @@ -45,15 +45,13 @@ #include "dss.h" #include "hdmi.h" -static struct omap_hdmi hdmi; - -static int hdmi_runtime_get(void) +static int hdmi_runtime_get(struct omap_hdmi *hdmi) { int r; DSSDBG("hdmi_runtime_get\n"); - r = pm_runtime_get_sync(&hdmi.pdev->dev); + r = pm_runtime_get_sync(&hdmi->pdev->dev); WARN_ON(r < 0); if (r < 0) return r; @@ -61,13 +59,13 @@ static int hdmi_runtime_get(void) return 0; } -static void hdmi_runtime_put(void) +static void hdmi_runtime_put(struct omap_hdmi *hdmi) { int r; DSSDBG("hdmi_runtime_put\n"); - r = pm_runtime_put_sync(&hdmi.pdev->dev); + r = pm_runtime_put_sync(&hdmi->pdev->dev); WARN_ON(r < 0 && r != -ENOSYS); } @@ -110,14 +108,14 @@ static irqreturn_t hdmi_irq_handler(int irq, void *data) return IRQ_HANDLED; } -static int hdmi_init_regulator(void) +static int hdmi_init_regulator(struct omap_hdmi *hdmi) { struct regulator *reg; - if (hdmi.vdda_reg != NULL) + if (hdmi->vdda_reg != NULL) return 0; - reg = devm_regulator_get(&hdmi.pdev->dev, "vdda"); + reg = devm_regulator_get(&hdmi->pdev->dev, "vdda"); if (IS_ERR(reg)) { if (PTR_ERR(reg) != -EPROBE_DEFER) @@ -125,63 +123,63 @@ static int hdmi_init_regulator(void) return PTR_ERR(reg); } - hdmi.vdda_reg = reg; + hdmi->vdda_reg = reg; return 0; } -static int hdmi_power_on_core(struct omap_dss_device *dssdev) +static int hdmi_power_on_core(struct omap_hdmi *hdmi) { int r; - if (hdmi.core.core_pwr_cnt++) + if (hdmi->core.core_pwr_cnt++) return 0; - r = regulator_enable(hdmi.vdda_reg); + r = regulator_enable(hdmi->vdda_reg); if (r) goto err_reg_enable; - r = hdmi_runtime_get(); + r = hdmi_runtime_get(hdmi); if (r) goto err_runtime_get; - hdmi4_core_powerdown_disable(&hdmi.core); + hdmi4_core_powerdown_disable(&hdmi->core); /* Make selection of HDMI in DSS */ - dss_select_hdmi_venc_clk_source(hdmi.dss, DSS_HDMI_M_PCLK); + dss_select_hdmi_venc_clk_source(hdmi->dss, DSS_HDMI_M_PCLK); - hdmi.core_enabled = true; + hdmi->core_enabled = true; return 0; err_runtime_get: - regulator_disable(hdmi.vdda_reg); + regulator_disable(hdmi->vdda_reg); err_reg_enable: - hdmi.core.core_pwr_cnt--; + hdmi->core.core_pwr_cnt--; return r; } -static void hdmi_power_off_core(struct omap_dss_device *dssdev) +static void hdmi_power_off_core(struct omap_hdmi *hdmi) { - if (--hdmi.core.core_pwr_cnt) + if (--hdmi->core.core_pwr_cnt) return; - hdmi.core_enabled = false; + hdmi->core_enabled = false; - hdmi_runtime_put(); - regulator_disable(hdmi.vdda_reg); + hdmi_runtime_put(hdmi); + regulator_disable(hdmi->vdda_reg); } -static int hdmi_power_on_full(struct omap_dss_device *dssdev) +static int hdmi_power_on_full(struct omap_hdmi *hdmi) { int r; struct videomode *vm; - struct hdmi_wp_data *wp = &hdmi.wp; + struct hdmi_wp_data *wp = &hdmi->wp; struct dss_pll_clock_info hdmi_cinfo = { 0 }; unsigned int pc; - r = hdmi_power_on_core(dssdev); + r = hdmi_power_on_core(hdmi); if (r) return r; @@ -189,7 +187,7 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev) hdmi_wp_clear_irqenable(wp, ~HDMI_IRQ_CORE); hdmi_wp_set_irqstatus(wp, ~HDMI_IRQ_CORE); - vm = &hdmi.cfg.vm
[PATCH v2 16/30] drm: omapdrm: dsi: Combine two commonly used inline functions
The dsi_get_dsidrv_data() and dsi_get_dsidev_from_dssdev() inline functions convert a struct omap_dss_device pointer to the corresponding struct platform_device, and a struct platform_device pointer to the corresponding struct dsi_data. They are nearly always called together without any use of the intermediate platform_device, so combine them into a single function. In the three locations where only dsi_get_dsidrv_data() is used, call dev_get_drvdata() directly. Signed-off-by: Laurent Pinchart Reviewed-by: Sebastian Reichel --- drivers/gpu/drm/omapdrm/dss/dsi.c | 90 +-- 1 file changed, 30 insertions(+), 60 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c index 7b5656e6abbb..cb250dbf0f9b 100644 --- a/drivers/gpu/drm/omapdrm/dss/dsi.c +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c @@ -439,14 +439,9 @@ static bool dsi_perf; module_param(dsi_perf, bool, 0644); #endif -static inline struct dsi_data *dsi_get_dsidrv_data(struct platform_device *dsidev) +static inline struct dsi_data *to_dsi_data(struct omap_dss_device *dssdev) { - return dev_get_drvdata(&dsidev->dev); -} - -static inline struct platform_device *dsi_get_dsidev_from_dssdev(struct omap_dss_device *dssdev) -{ - return to_platform_device(dssdev->dev); + return dev_get_drvdata(dssdev->dev); } static struct dsi_data *dsi_get_dsi_from_id(int module) @@ -467,7 +462,7 @@ static struct dsi_data *dsi_get_dsi_from_id(int module) out = omap_dss_get_output(id); - return out ? dsi_get_dsidrv_data(to_platform_device(out->dev)) : NULL; + return out ? to_dsi_data(out) : NULL; } static inline void dsi_write_reg(struct dsi_data *dsi, @@ -501,16 +496,14 @@ static inline u32 dsi_read_reg(struct dsi_data *dsi, const struct dsi_reg idx) static void dsi_bus_lock(struct omap_dss_device *dssdev) { - struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); - struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); + struct dsi_data *dsi = to_dsi_data(dssdev); down(&dsi->bus_lock); } static void dsi_bus_unlock(struct omap_dss_device *dssdev) { - struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); - struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); + struct dsi_data *dsi = to_dsi_data(dssdev); up(&dsi->bus_lock); } @@ -2534,8 +2527,7 @@ static int dsi_vc_config_source(struct dsi_data *dsi, int channel, static void dsi_vc_enable_hs(struct omap_dss_device *dssdev, int channel, bool enable) { - struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); - struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); + struct dsi_data *dsi = to_dsi_data(dssdev); DSSDBG("dsi_vc_enable_hs(%d, %d)\n", channel, enable); @@ -2658,8 +2650,7 @@ static int dsi_vc_send_bta(struct dsi_data *dsi, int channel) static int dsi_vc_send_bta_sync(struct omap_dss_device *dssdev, int channel) { - struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); - struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); + struct dsi_data *dsi = to_dsi_data(dssdev); DECLARE_COMPLETION_ONSTACK(completion); int r = 0; u32 err; @@ -2861,8 +2852,7 @@ static int dsi_vc_write_nosync_common(struct dsi_data *dsi, int channel, static int dsi_vc_dcs_write_nosync(struct omap_dss_device *dssdev, int channel, u8 *data, int len) { - struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); - struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); + struct dsi_data *dsi = to_dsi_data(dssdev); return dsi_vc_write_nosync_common(dsi, channel, data, len, DSS_DSI_CONTENT_DCS); @@ -2871,8 +2861,7 @@ static int dsi_vc_dcs_write_nosync(struct omap_dss_device *dssdev, int channel, static int dsi_vc_generic_write_nosync(struct omap_dss_device *dssdev, int channel, u8 *data, int len) { - struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); - struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); + struct dsi_data *dsi = to_dsi_data(dssdev); return dsi_vc_write_nosync_common(dsi, channel, data, len, DSS_DSI_CONTENT_GENERIC); @@ -2882,8 +2871,7 @@ static int dsi_vc_write_common(struct omap_dss_device *dssdev, int channel, u8 *data, int len, enum dss_dsi_content_type type) { - struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); - struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); + struct dsi_data *dsi = to_dsi_data(dssdev); int r; r = dsi_vc_write_nosync_common(dsi, channel, data, len, type); @@ -3088,8 +3076,7 @@ static int dsi_vc_read_rx_fifo(struct dsi_data *dsi, int channel, u8 *buf, static int dsi_vc_dcs_read(struct omap_dss_
[PATCH v2 08/30] drm: omapdrm: dss: Pass DSS pointer to dss clock functions
This removes the need to access the global DSS private data in those functions (both for the current accesses and the future ones that will be introduced when allocating the DSS device dynamically). Signed-off-by: Laurent Pinchart Reviewed-by: Sebastian Reichel --- drivers/gpu/drm/omapdrm/dss/dispc.c | 8 drivers/gpu/drm/omapdrm/dss/dpi.c | 14 -- drivers/gpu/drm/omapdrm/dss/dss.c | 37 ++--- drivers/gpu/drm/omapdrm/dss/dss.h | 10 +- drivers/gpu/drm/omapdrm/dss/sdi.c | 5 +++-- 5 files changed, 38 insertions(+), 36 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/dss/dispc.c b/drivers/gpu/drm/omapdrm/dss/dispc.c index 048b2e4d1f40..8d0de1b790b7 100644 --- a/drivers/gpu/drm/omapdrm/dss/dispc.c +++ b/drivers/gpu/drm/omapdrm/dss/dispc.c @@ -3116,7 +3116,7 @@ static unsigned long dispc_fclk_rate(void) src = dss_get_dispc_clk_source(dispc.dss); if (src == DSS_CLK_SRC_FCK) { - r = dss_get_dispc_clk_rate(); + r = dss_get_dispc_clk_rate(dispc.dss); } else { struct dss_pll *pll; unsigned int clkout_idx; @@ -3143,7 +3143,7 @@ static unsigned long dispc_mgr_lclk_rate(enum omap_channel channel) src = dss_get_lcd_clk_source(dispc.dss, channel); if (src == DSS_CLK_SRC_FCK) { - r = dss_get_dispc_clk_rate(); + r = dss_get_dispc_clk_rate(dispc.dss); } else { struct dss_pll *pll; unsigned int clkout_idx; @@ -3499,7 +3499,7 @@ bool dispc_div_calc(unsigned long dispc_freq, pckd_hw_min = dispc.feat->min_pcd; pckd_hw_max = 255; - lck_max = dss_get_max_fck_rate(); + lck_max = dss_get_max_fck_rate(dispc.dss); pck_min = pck_min ? pck_min : 1; pck_max = pck_max ? pck_max : ULONG_MAX; @@ -4460,7 +4460,7 @@ static void dispc_errata_i734_wa(void) /* Set up and enable display manager for LCD1 */ dispc_mgr_setup(OMAP_DSS_CHANNEL_LCD, &i734.mgri); - dispc_calc_clock_rates(dss_get_dispc_clk_rate(), + dispc_calc_clock_rates(dss_get_dispc_clk_rate(dispc.dss), &lcd_conf.clock_info); dispc_mgr_set_lcd_config(OMAP_DSS_CHANNEL_LCD, &lcd_conf); dispc_mgr_set_timings(OMAP_DSS_CHANNEL_LCD, &i734.vm); diff --git a/drivers/gpu/drm/omapdrm/dss/dpi.c b/drivers/gpu/drm/omapdrm/dss/dpi.c index e7f50fabca6f..ba5adfb7ee70 100644 --- a/drivers/gpu/drm/omapdrm/dss/dpi.c +++ b/drivers/gpu/drm/omapdrm/dss/dpi.c @@ -207,7 +207,7 @@ static bool dpi_calc_pll_cb(int n, int m, unsigned long fint, ctx->pll_cinfo.clkdco = clkdco; return dss_pll_hsdiv_calc_a(ctx->pll, clkdco, - ctx->pck_min, dss_get_max_fck_rate(), + ctx->pck_min, dss_get_max_fck_rate(ctx->pll->dss), dpi_calc_hsdiv_cb, ctx); } @@ -256,7 +256,8 @@ static bool dpi_pll_clk_calc(struct dpi_data *dpi, unsigned long pck, } } -static bool dpi_dss_clk_calc(unsigned long pck, struct dpi_clk_calc_ctx *ctx) +static bool dpi_dss_clk_calc(struct dpi_data *dpi, unsigned long pck, +struct dpi_clk_calc_ctx *ctx) { int i; @@ -277,7 +278,8 @@ static bool dpi_dss_clk_calc(unsigned long pck, struct dpi_clk_calc_ctx *ctx) ctx->pck_min = 0; ctx->pck_max = pck + 1000 * i * i * i; - ok = dss_div_calc(pck, ctx->pck_min, dpi_calc_dss_cb, ctx); + ok = dss_div_calc(dpi->dss, pck, ctx->pck_min, + dpi_calc_dss_cb, ctx); if (ok) return ok; } @@ -321,11 +323,11 @@ static int dpi_set_dispc_clk(struct dpi_data *dpi, unsigned long pck_req, int r; bool ok; - ok = dpi_dss_clk_calc(pck_req, &ctx); + ok = dpi_dss_clk_calc(dpi, pck_req, &ctx); if (!ok) return -EINVAL; - r = dss_set_fck_rate(ctx.fck); + r = dss_set_fck_rate(dpi->dss, ctx.fck); if (r) return r; @@ -530,7 +532,7 @@ static int dpi_check_timings(struct omap_dss_device *dssdev, fck = ctx.pll_cinfo.clkout[ctx.clkout_idx]; } else { - ok = dpi_dss_clk_calc(vm->pixelclock, &ctx); + ok = dpi_dss_clk_calc(dpi, vm->pixelclock, &ctx); if (!ok) return -EINVAL; diff --git a/drivers/gpu/drm/omapdrm/dss/dss.c b/drivers/gpu/drm/omapdrm/dss/dss.c index bdf8f66002b6..0d292da6757d 100644 --- a/drivers/gpu/drm/omapdrm/dss/dss.c +++ b/drivers/gpu/drm/omapdrm/dss/dss.c @@ -594,8 +594,8 @@ enum dss_clk_source dss_get_lcd_clk_source(struct dss_device *dss, } } -bool dss_div_calc(unsigned long pck, unsigned long fck_min, - dss_div_calc_func func, void *data) +bool dss_div_calc(struct dss_device *dss, unsigned long pck, + unsigned long fc
[PATCH v2 29/30] drm: omapdrm: sdi: Allocate the sdi private data structure dynamically
The sdi private data structure is currently stored as a global variable. While no platform with multiple SDI encoders currently exists nor is planned, this doesn't comply with the kernel device model and should thus be fixed. Signed-off-by: Laurent Pinchart Reviewed-by: Sebastian Reichel --- drivers/gpu/drm/omapdrm/dss/sdi.c | 151 ++ 1 file changed, 86 insertions(+), 65 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/dss/sdi.c b/drivers/gpu/drm/omapdrm/dss/sdi.c index 9c2ed56a70c1..68a40ae26f5b 100644 --- a/drivers/gpu/drm/omapdrm/dss/sdi.c +++ b/drivers/gpu/drm/omapdrm/dss/sdi.c @@ -29,7 +29,7 @@ #include "omapdss.h" #include "dss.h" -static struct { +struct sdi_device { struct platform_device *pdev; struct dss_device *dss; @@ -41,11 +41,12 @@ static struct { int datapairs; struct omap_dss_device output; +}; - bool port_initialized; -} sdi; +#define dssdev_to_sdi(dssdev) container_of(dssdev, struct sdi_device, output) struct sdi_clk_calc_ctx { + struct sdi_device *sdi; unsigned long pck_min, pck_max; unsigned long fck; @@ -71,17 +72,17 @@ static bool dpi_calc_dss_cb(unsigned long fck, void *data) ctx->fck = fck; - return dispc_div_calc(sdi.dss->dispc, fck, + return dispc_div_calc(ctx->sdi->dss->dispc, fck, ctx->pck_min, ctx->pck_max, dpi_calc_dispc_cb, ctx); } -static int sdi_calc_clock_div(unsigned long pclk, - unsigned long *fck, - struct dispc_clock_info *dispc_cinfo) +static int sdi_calc_clock_div(struct sdi_device *sdi, unsigned long pclk, + unsigned long *fck, + struct dispc_clock_info *dispc_cinfo) { int i; - struct sdi_clk_calc_ctx ctx; + struct sdi_clk_calc_ctx ctx = { .sdi = sdi }; /* * DSS fclk gives us very few possibilities, so finding a good pixel @@ -100,7 +101,7 @@ static int sdi_calc_clock_div(unsigned long pclk, ctx.pck_min = 0; ctx.pck_max = pclk + 1000 * i * i * i; - ok = dss_div_calc(sdi.dss, pclk, ctx.pck_min, + ok = dss_div_calc(sdi->dss, pclk, ctx.pck_min, dpi_calc_dss_cb, &ctx); if (ok) { *fck = ctx.fck; @@ -112,48 +113,49 @@ static int sdi_calc_clock_div(unsigned long pclk, return -EINVAL; } -static void sdi_config_lcd_manager(struct omap_dss_device *dssdev) +static void sdi_config_lcd_manager(struct sdi_device *sdi) { - sdi.mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS; + sdi->mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS; - sdi.mgr_config.stallmode = false; - sdi.mgr_config.fifohandcheck = false; + sdi->mgr_config.stallmode = false; + sdi->mgr_config.fifohandcheck = false; - sdi.mgr_config.video_port_width = 24; - sdi.mgr_config.lcden_sig_polarity = 1; + sdi->mgr_config.video_port_width = 24; + sdi->mgr_config.lcden_sig_polarity = 1; - dss_mgr_set_lcd_config(&sdi.output, &sdi.mgr_config); + dss_mgr_set_lcd_config(&sdi->output, &sdi->mgr_config); } static int sdi_display_enable(struct omap_dss_device *dssdev) { - struct videomode *vm = &sdi.vm; + struct sdi_device *sdi = dssdev_to_sdi(dssdev); + struct videomode *vm = &sdi->vm; unsigned long fck; struct dispc_clock_info dispc_cinfo; unsigned long pck; int r; - if (!sdi.output.dispc_channel_connected) { + if (!sdi->output.dispc_channel_connected) { DSSERR("failed to enable display: no output/manager\n"); return -ENODEV; } - r = regulator_enable(sdi.vdds_sdi_reg); + r = regulator_enable(sdi->vdds_sdi_reg); if (r) goto err_reg_enable; - r = dispc_runtime_get(sdi.dss->dispc); + r = dispc_runtime_get(sdi->dss->dispc); if (r) goto err_get_dispc; /* 15.5.9.1.2 */ vm->flags |= DISPLAY_FLAGS_PIXDATA_POSEDGE | DISPLAY_FLAGS_SYNC_POSEDGE; - r = sdi_calc_clock_div(vm->pixelclock, &fck, &dispc_cinfo); + r = sdi_calc_clock_div(sdi, vm->pixelclock, &fck, &dispc_cinfo); if (r) goto err_calc_clock_div; - sdi.mgr_config.clock_info = dispc_cinfo; + sdi->mgr_config.clock_info = dispc_cinfo; pck = fck / dispc_cinfo.lck_div / dispc_cinfo.pck_div; @@ -165,13 +167,13 @@ static int sdi_display_enable(struct omap_dss_device *dssdev) } - dss_mgr_set_timings(&sdi.output, vm); + dss_mgr_set_timings(&sdi->output, vm); - r = dss_set_fck_rate(sdi.dss, fck); + r = dss_set_fck_rate(sdi->dss, fck); if (r) goto err_set_dss_clock_div; - sdi_config_lcd_manager(dssdev); +
[PATCH v2 18/30] drm: omapdrm: dsi: Store the struct device pointer in struct dsi_data
The dsi_data structure stores a pointer to a struct platform_device. The driver only uses the dev member of the platform device structure. Store the struct device pointer instead and use it directly. Signed-off-by: Laurent Pinchart Reviewed-by: Sebastian Reichel --- drivers/gpu/drm/omapdrm/dss/dsi.c | 26 +- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c index 62131d7593a7..ecfdc6ef2500 100644 --- a/drivers/gpu/drm/omapdrm/dss/dsi.c +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c @@ -330,7 +330,7 @@ struct dsi_of_data { }; struct dsi_data { - struct platform_device *pdev; + struct device *dev; void __iomem *proto_base; void __iomem *phy_base; void __iomem *pll_base; @@ -1144,7 +1144,7 @@ static int dsi_runtime_get(struct dsi_data *dsi) DSSDBG("dsi_runtime_get\n"); - r = pm_runtime_get_sync(&dsi->pdev->dev); + r = pm_runtime_get_sync(dsi->dev); WARN_ON(r < 0); return r < 0 ? r : 0; } @@ -1155,7 +1155,7 @@ static void dsi_runtime_put(struct dsi_data *dsi) DSSDBG("dsi_runtime_put\n"); - r = pm_runtime_put_sync(&dsi->pdev->dev); + r = pm_runtime_put_sync(dsi->dev); WARN_ON(r < 0 && r != -ENOSYS); } @@ -1166,7 +1166,7 @@ static int dsi_regulator_init(struct dsi_data *dsi) if (dsi->vdds_dsi_reg != NULL) return 0; - vdds_dsi = devm_regulator_get(&dsi->pdev->dev, "vdd"); + vdds_dsi = devm_regulator_get(dsi->dev, "vdd"); if (IS_ERR(vdds_dsi)) { if (PTR_ERR(vdds_dsi) != -EPROBE_DEFER) @@ -4951,7 +4951,7 @@ static int dsi_get_clocks(struct dsi_data *dsi) { struct clk *clk; - clk = devm_clk_get(&dsi->pdev->dev, "fck"); + clk = devm_clk_get(dsi->dev, "fck"); if (IS_ERR(clk)) { DSSERR("can't get fck\n"); return PTR_ERR(clk); @@ -5046,7 +5046,7 @@ static void dsi_init_output(struct dsi_data *dsi) { struct omap_dss_device *out = &dsi->output; - out->dev = &dsi->pdev->dev; + out->dev = dsi->dev; out->id = dsi->module_id == 0 ? OMAP_DSS_OUTPUT_DSI1 : OMAP_DSS_OUTPUT_DSI2; @@ -5068,7 +5068,7 @@ static void dsi_uninit_output(struct dsi_data *dsi) static int dsi_probe_of(struct dsi_data *dsi) { - struct device_node *node = dsi->pdev->dev.of_node; + struct device_node *node = dsi->dev->of_node; struct property *prop; u32 lane_arr[10]; int len, num_pins; @@ -5082,7 +5082,7 @@ static int dsi_probe_of(struct dsi_data *dsi) prop = of_find_property(ep, "lanes", &len); if (prop == NULL) { - dev_err(&dsi->pdev->dev, "failed to find lane data\n"); + dev_err(dsi->dev, "failed to find lane data\n"); r = -EINVAL; goto err; } @@ -5091,14 +5091,14 @@ static int dsi_probe_of(struct dsi_data *dsi) if (num_pins < 4 || num_pins % 2 != 0 || num_pins > dsi->num_lanes_supported * 2) { - dev_err(&dsi->pdev->dev, "bad number of lanes\n"); + dev_err(dsi->dev, "bad number of lanes\n"); r = -EINVAL; goto err; } r = of_property_read_u32_array(ep, "lanes", lane_arr, num_pins); if (r) { - dev_err(&dsi->pdev->dev, "failed to read lane data\n"); + dev_err(dsi->dev, "failed to read lane data\n"); goto err; } @@ -5108,7 +5108,7 @@ static int dsi_probe_of(struct dsi_data *dsi) r = dsi_configure_pins(&dsi->output, &pin_cfg); if (r) { - dev_err(&dsi->pdev->dev, "failed to configure pins"); + dev_err(dsi->dev, "failed to configure pins"); goto err; } @@ -5214,7 +5214,7 @@ static int dsi_init_pll_data(struct dss_device *dss, struct dsi_data *dsi) struct clk *clk; int r; - clk = devm_clk_get(&dsi->pdev->dev, "sys_clk"); + clk = devm_clk_get(dsi->dev, "sys_clk"); if (IS_ERR(clk)) { DSSERR("can't get sys_clk\n"); return PTR_ERR(clk); @@ -5317,7 +5317,7 @@ static int dsi_bind(struct device *dev, struct device *master, void *data) return -ENOMEM; dsi->dss = dss; - dsi->pdev = pdev; + dsi->dev = dev; dev_set_drvdata(dev, dsi); spin_lock_init(&dsi->irq_lock); -- Regards, Laurent Pinchart ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 21/30] drm: omapdrm: dss: Pass omap_drm_private pointer to dss_mgr_ops
The dss_mgr_ops operations implemented by the omapdrm side have to look up the omap_crtc objects from global variables as they are only passed a channel number. In order to remove global variables in the omapdrm driver pass the omap_drm_private pointer to the dss_mgr_ops. This requires storing a pointer to the omap_drm_private in a global variable on the DSS side as a temporary measure until the omapdrm and omapdss drivers get merged. Signed-off-by: Laurent Pinchart --- drivers/gpu/drm/omapdrm/dss/omapdss.h | 41 ++- drivers/gpu/drm/omapdrm/dss/output.c | 28 +++- drivers/gpu/drm/omapdrm/omap_crtc.c | 31 +++--- drivers/gpu/drm/omapdrm/omap_crtc.h | 2 +- drivers/gpu/drm/omapdrm/omap_drv.c| 2 +- 5 files changed, 64 insertions(+), 40 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h index aeaa337b29c7..318641f5bc24 100644 --- a/drivers/gpu/drm/omapdrm/dss/omapdss.h +++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h @@ -59,6 +59,7 @@ #define DISPC_IRQ_ACBIAS_COUNT_STAT3 (1 << 29) #define DISPC_IRQ_FRAMEDONE3 (1 << 30) +struct omap_drm_private; struct omap_dss_device; struct dss_lcd_mgr_config; struct snd_aes_iec958; @@ -635,25 +636,35 @@ struct device_node *dss_of_port_get_parent_device(struct device_node *port); u32 dss_of_port_get_port_number(struct device_node *port); struct dss_mgr_ops { - int (*connect)(enum omap_channel channel, - struct omap_dss_device *dst); - void (*disconnect)(enum omap_channel channel, - struct omap_dss_device *dst); - - void (*start_update)(enum omap_channel channel); - int (*enable)(enum omap_channel channel); - void (*disable)(enum omap_channel channel); - void (*set_timings)(enum omap_channel channel, - const struct videomode *vm); - void (*set_lcd_config)(enum omap_channel channel, - const struct dss_lcd_mgr_config *config); - int (*register_framedone_handler)(enum omap_channel channel, + int (*connect)(struct omap_drm_private *priv, + enum omap_channel channel, + struct omap_dss_device *dst); + void (*disconnect)(struct omap_drm_private *priv, + enum omap_channel channel, + struct omap_dss_device *dst); + + void (*start_update)(struct omap_drm_private *priv, +enum omap_channel channel); + int (*enable)(struct omap_drm_private *priv, + enum omap_channel channel); + void (*disable)(struct omap_drm_private *priv, + enum omap_channel channel); + void (*set_timings)(struct omap_drm_private *priv, + enum omap_channel channel, + const struct videomode *vm); + void (*set_lcd_config)(struct omap_drm_private *priv, + enum omap_channel channel, + const struct dss_lcd_mgr_config *config); + int (*register_framedone_handler)(struct omap_drm_private *priv, + enum omap_channel channel, void (*handler)(void *), void *data); - void (*unregister_framedone_handler)(enum omap_channel channel, + void (*unregister_framedone_handler)(struct omap_drm_private *priv, + enum omap_channel channel, void (*handler)(void *), void *data); }; -int dss_install_mgr_ops(const struct dss_mgr_ops *mgr_ops); +int dss_install_mgr_ops(const struct dss_mgr_ops *mgr_ops, + struct omap_drm_private *priv); void dss_uninstall_mgr_ops(void); int dss_mgr_connect(struct omap_dss_device *dssdev, diff --git a/drivers/gpu/drm/omapdrm/dss/output.c b/drivers/gpu/drm/omapdrm/dss/output.c index 9ff29dea28ce..96b9d4cd505f 100644 --- a/drivers/gpu/drm/omapdrm/dss/output.c +++ b/drivers/gpu/drm/omapdrm/dss/output.c @@ -170,13 +170,16 @@ struct omap_dss_device *omapdss_find_output_from_display(struct omap_dss_device EXPORT_SYMBOL(omapdss_find_output_from_display); static const struct dss_mgr_ops *dss_mgr_ops; +static struct omap_drm_private *dss_mgr_ops_priv; -int dss_install_mgr_ops(const struct dss_mgr_ops *mgr_ops) +int dss_install_mgr_ops(const struct dss_mgr_ops *mgr_ops, + struct omap_drm_private *priv) { if (dss_mgr_ops) return -EBUSY; dss_mgr_ops = mgr_ops; + dss_mgr_ops_priv = priv; return 0; } @@ -185,58 +188,62 @@ EXPORT_SYMBOL(dss_install_mgr_ops); void dss_uninstall_mgr_ops(void) { dss_mgr_ops = NULL; + dss_mgr_ops_priv = NULL; } EXPORT_SYMBOL(dss_uninstall_mgr_ops); int dss_mgr_connect(struct omap_dss_device *dssdev, struct omap_dss_device *dst) { - return dss_mgr_ops->connect(dssdev->dispc_c
Re: [PATCH v3 1/5] dt-bindings: media: adv7604: Add support for i2c_new_secondary_device
Hi Kieran, Thank you for the patch. On Tuesday, 13 February 2018 00:07:49 EET Kieran Bingham wrote: > From: Jean-Michel Hautbois > > The ADV7604 has thirteen 256-byte maps that can be accessed via the main > I²C ports. Each map has it own I²C address and acts as a standard slave > device on the I²C bus. > > Extend the device tree node bindings to be able to override the default > addresses so that address conflicts with other devices on the same bus > may be resolved at the board description level. > > Signed-off-by: Jean-Michel Hautbois > [Kieran: Re-adapted for mainline] > Signed-off-by: Kieran Bingham > Reviewed-by: Rob Herring Nitpicking, I might not mention i2c_new_secondary_device in the subject, as this is a DT bindings change. I don't mind too much though, as long as the bindings themselves don't contain Linux-specific information, and they don't, so Reviewed-by: Laurent Pinchart > --- > Based upon the original posting : > https://lkml.org/lkml/2014/10/22/469 > > v2: > - DT Binding update separated from code change > - Minor reword to commit message to account for DT only change. > - Collected Rob's RB tag. > > v3: > - Split map register addresses into individual declarations. > > .../devicetree/bindings/media/i2c/adv7604.txt | 18 > -- 1 file changed, 16 insertions(+), 2 deletions(-) > > diff --git a/Documentation/devicetree/bindings/media/i2c/adv7604.txt > b/Documentation/devicetree/bindings/media/i2c/adv7604.txt index > 9cbd92eb5d05..ebb5f070c05b 100644 > --- a/Documentation/devicetree/bindings/media/i2c/adv7604.txt > +++ b/Documentation/devicetree/bindings/media/i2c/adv7604.txt > @@ -13,7 +13,11 @@ Required Properties: > - "adi,adv7611" for the ADV7611 > - "adi,adv7612" for the ADV7612 > > - - reg: I2C slave address > + - reg: I2C slave addresses > +The ADV76xx has up to thirteen 256-byte maps that can be accessed via > the +main I²C ports. Each map has it own I²C address and acts as a > standard +slave device on the I²C bus. The main address is mandatory, > others are +optional and revert to defaults if not specified. > >- hpd-gpios: References to the GPIOs that control the HDMI hot-plug > detection pins, one per HDMI input. The active flag indicates the GPIO > @@ -35,6 +39,11 @@ Optional Properties: > >- reset-gpios: Reference to the GPIO connected to the device's reset pin. > - default-input: Select which input is selected after reset. > + - reg-names : Names of maps with programmable addresses. > + It can contain any map needing a non-default address. > + Possible maps names are : > + "main", "avlink", "cec", "infoframe", "esdp", "dpp", "afe", > + "rep", "edid", "hdmi", "test", "cp", "vdp" > > Optional Endpoint Properties: > > @@ -52,7 +61,12 @@ Example: > > hdmi_receiver@4c { > compatible = "adi,adv7611"; > - reg = <0x4c>; > + /* > + * The edid page will be accessible @ 0x66 on the i2c bus. All > + * other maps will retain their default addresses. > + */ > + reg = <0x4c>, <0x66>; > + reg-names "main", "edid"; > > reset-gpios = <&ioexp 0 GPIO_ACTIVE_LOW>; > hpd-gpios = <&ioexp 2 GPIO_ACTIVE_HIGH>; -- Regards, Laurent Pinchart ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v3] Fix loading of module radeonfb on PowerMac
On Saturday, February 10, 2018 01:48:55 PM Mathieu Malaterre wrote: > Hi, > > On Thu, Feb 8, 2018 at 2:28 PM, Bartlomiej Zolnierkiewicz > wrote: > > On Wednesday, January 31, 2018 08:51:23 PM Mathieu Malaterre wrote: > >> Bartlomiej, > >> > >> On Wed, Jan 31, 2018 at 12:57 PM, Bartlomiej Zolnierkiewicz > >> wrote: > >> > On Tuesday, January 30, 2018 02:14:10 PM Mathieu Malaterre wrote: > >> >> Bartlomiej, > >> >> > >> >> On Wed, Jan 3, 2018 at 3:47 PM, Bartlomiej Zolnierkiewicz > >> >> wrote: > >> >> > > >> >> > On Thursday, December 21, 2017 11:07:56 PM Mathieu Malaterre wrote: > >> >> >> When the linux kernel is build with (typical kernel ship with Debian > >> >> >> installer): > >> >> >> > >> >> >> CONFIG_FB_OF=y > >> >> >> CONFIG_VT_HW_CONSOLE_BINDING=y > >> >> >> CONFIG_FB_RADEON=m > >> >> >> > >> >> >> The offb driver takes precedence over module radeonfb. It is then > >> >> >> impossible to load the module, error reported is: > >> >> >> > >> >> >> [ 96.551486] radeonfb :00:10.0: enabling device (0006 -> 0007) > >> >> >> [ 96.551526] radeonfb :00:10.0: BAR 0: can't reserve [mem > >> >> >> 0x9800-0x9fff pref] > >> >> >> [ 96.551531] radeonfb (:00:10.0): cannot request region 0. > >> >> >> [ 96.551545] radeonfb: probe of :00:10.0 failed with error -16 > >> >> >> > >> >> >> This patch reproduce the behavior of the module radeon, so as to > >> >> >> make it > >> >> >> possible to load radeonfb when offb is first loaded. > >> >> >> > >> >> >> It should be noticed that `offb_destroy` is never called which > >> >> >> explain the > >> >> >> need to skip error detection on the radeon side. > >> >> > > >> >> > This still needs to be explained more, from my last mail: > >> >> > > >> >> > "The last put_fb_info() on fb_info should call ->fb_destroy > >> >> > (offb_destroy in our case) and remove_conflicting_framebuffers() > >> >> > is calling put_fb_info() so there is some extra reference on > >> >> > fb_info somewhere preventing it from going away. > >> >> > > >> >> > Please look into fixing this." > >> >> > >> >> I am not familiar with the fb stuff internals but here is what I see: > >> >> > >> >> # modprobe radeonfb > >> >> > >> >> leads to: > >> >> > >> >> [ 52.058546] bus: 'pci': add driver radeonfb > >> >> [ 52.058588] bus: 'pci': driver_probe_device: matched device > >> >> :00:10.0 with driver radeonfb > >> >> [ 52.058595] bus: 'pci': really_probe: probing driver radeonfb with > >> >> device :00:10.0 > >> >> [ 52.058608] devices_kset: Moving :00:10.0 to end of list > >> >> [ 52.058613] radeonfb_pci_register BEGIN > >> >> [ 52.058634] radeonfb :00:10.0: enabling device (0006 -> 0007) > >> >> > >> >> [ 52.058666] checking generic (9c008000 96000) vs hw (9800 > >> >> 800) > >> >> [ 52.058667] fb: switching to radeonfb from OFfb ATY,RockHo > >> >> [ 52.058844] Console: switching to colour dummy device 80x25 > >> >> [ 52.058860] device: 'fb0': device_unregister > >> >> [ 52.058956] PM: Removing info for No Bus:fb0 > >> >> [ 52.059014] device: 'fb0': device_create_release > >> >> > >> >> > >> >> [ 52.059048] device: 'vtcon1': device_unregister > >> >> [ 52.059076] PM: Removing info for No Bus:vtcon1 > >> >> [ 52.059091] device: 'vtcon1': device_create_release > >> >> [ 52.059107] radeonfb :00:10.0: BAR 0: can't reserve [mem > >> >> 0x9800-0x9fff pref] > >> >> [ 52.256151] aper_base: 9800 MC_FB_LOC to: 9bff9800, MC_AGP_LOC > >> >> to: a000 > >> >> [ 52.256157] radeonfb (:00:10.0): Found 32768k of DDR 64 bits > >> >> wide videoram > >> >> > >> >> I can confirm that offb_destroy is never called (not sure exactly > >> >> why), but in any case the call to radeon_kick_out_firmware_fb happen > >> >> much earlier, at least before the put_fb_info. > >> > > >> > It is okay, put_fb_info() is called indirectly by > >> > radeon_kick_out_firmware_fb() > >> > > >> > radeon_kick_out_firmware_fb() > >> > remove_conflicting_framebuffers() > >> > do_remove_conflicting_framebuffers() > >> > do_unregister_framebuffer() > >> > put_fb_info() > >> > > >> > offb_destroy() is not called because there is an extra reference on old > >> > fb_info (->count == 2): > >> > > >> > static void put_fb_info(struct fb_info *fb_info) > >> > { > >> > if (!atomic_dec_and_test(&fb_info->count)) > >> > return; > >> > if (fb_info->fbops->fb_destroy) > >> > fb_info->fbops->fb_destroy(fb_info); > >> > } > >> > > >> > The question is why there is an extra reference, probably user-space > >> > is still holding the fb_info reference obtained in fb_open() call and > >> > fb_release() is never called. Besides not calling fbops->fb_destroy() > >> > this also causes missing call of fbops->fb_release() (in fb_release()) > >> > which some fb drivers are implementing (but not offb.c). > >> > > >> >> Could you descr
Re: [PATCH v3 2/5] dt-bindings: adv7511: Add support for i2c_new_secondary_device
Hi Kieran, Thank you for the patch. On Tuesday, 13 February 2018 00:07:50 EET Kieran Bingham wrote: > From: Kieran Bingham > > The ADV7511 has four 256-byte maps that can be accessed via the main I²C > ports. Each map has it own I²C address and acts as a standard slave > device on the I²C bus. > > Extend the device tree node bindings to be able to override the default > addresses so that address conflicts with other devices on the same bus > may be resolved at the board description level. > > Signed-off-by: Kieran Bingham > Reviewed-by: Rob Herring Same comment as for 1/5 about the subject line. > --- > v2: > - Fixed up reg: property description to account for multiple optional >addresses. > - Minor reword to commit message to account for DT only change > - Collected Robs RB tag > > v3: > - Split map register addresses into individual declarations. > > .../devicetree/bindings/display/bridge/adi,adv7511.txt | 18 +-- > 1 file changed, 16 insertions(+), 2 deletions(-) > > diff --git > a/Documentation/devicetree/bindings/display/bridge/adi,adv7511.txt > b/Documentation/devicetree/bindings/display/bridge/adi,adv7511.txt index > 0047b1394c70..3f85c351dd39 100644 > --- a/Documentation/devicetree/bindings/display/bridge/adi,adv7511.txt > +++ b/Documentation/devicetree/bindings/display/bridge/adi,adv7511.txt > @@ -14,7 +14,13 @@ Required properties: > "adi,adv7513" > "adi,adv7533" > > -- reg: I2C slave address > +- reg: I2C slave addresses > + The ADV7511 internal registers are split into four pages exposed through > + different I2C addresses, creating four register maps. Each map has it own > + I2C address and acts as a standard slave device on the I²C bus. The main > + address is mandatory, others are optional and revert to defaults if not > + specified. Nitpicking again, you're mixing I2C and I²C. > + > > The ADV7511 supports a large number of input data formats that differ by > their color depth, color format, clock mode, bit justification and random > @@ -70,6 +76,9 @@ Optional properties: >rather than generate its own timings for HDMI output. > - clocks: from common clock binding: reference to the CEC clock. > - clock-names: from common clock binding: must be "cec". > +- reg-names : Names of maps with programmable addresses. > + It can contain any map needing a non-default address. > + Possible maps names are : "main", "edid", "cec", "packet" > > Required nodes: > > @@ -88,7 +97,12 @@ Example > > adv7511w: hdmi@39 { > compatible = "adi,adv7511w"; > - reg = <39>; > + /* > + * The EDID page will be accessible on address 0x66 on the i2c And now you're using lowercase :-) > + * bus. All other maps continue to use their default addresses. > + */ > + reg = <0x39>, <0x66>; > + reg-names = "main", "edid"; > interrupt-parent = <&gpio3>; > interrupts = <29 IRQ_TYPE_EDGE_FALLING>; > clocks = <&cec_clock>; With these fixed (or not, up to you), Reviewed-by: Laurent Pinchart -- Regards, Laurent Pinchart ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v3 3/5] [RFT] ARM: dts: wheat: Fix ADV7513 address usage
Hi Kieran, Thank you for the patch. On Tuesday, 13 February 2018 00:07:51 EET Kieran Bingham wrote: > From: Kieran Bingham > > The r8a7792 Wheat board has two ADV7513 devices sharing a single i2c > bus, however in low power mode the ADV7513 will reset it's slave maps to > use the hardware defined default addresses. > > The ADV7511 driver was adapted to allow the two devices to be registered > correctly - but it did not take into account the fault whereby the > devices reset the addresses. > > This results in an address conflict between the device using the default > addresses, and the other device if it is in low-power-mode. > > Repair this issue by moving both devices away from the default address > definitions. > > Signed-off-by: Kieran Bingham Reviewed-by: Laurent Pinchart > --- > v2: > - Addition to series > > v3: > - Split map register addresses into individual declarations. > > arch/arm/boot/dts/r8a7792-wheat.dts | 12 ++-- > 1 file changed, 10 insertions(+), 2 deletions(-) > > diff --git a/arch/arm/boot/dts/r8a7792-wheat.dts > b/arch/arm/boot/dts/r8a7792-wheat.dts index b9471b67b728..42fff8837eab > 100644 > --- a/arch/arm/boot/dts/r8a7792-wheat.dts > +++ b/arch/arm/boot/dts/r8a7792-wheat.dts > @@ -240,9 +240,16 @@ > status = "okay"; > clock-frequency = <40>; > > + /* > + * The adv75xx resets its addresses to defaults during low power power > + * mode. Because we have two ADV7513 devices on the same bus, we must > + * change both of them away from the defaults so that they do not > + * conflict. > + */ > hdmi@3d { > compatible = "adi,adv7513"; > - reg = <0x3d>; > + reg = <0x3d>, <0x2d>, <0x4d>, <0x5d>; > + reg-names = "main", "cec", "edid", "packet"; > > adi,input-depth = <8>; > adi,input-colorspace = "rgb"; > @@ -272,7 +279,8 @@ > > hdmi@39 { > compatible = "adi,adv7513"; > - reg = <0x39>; > + reg = <0x39>, <0x29>, <0x49>, <0x59>; > + reg-names = "main", "cec", "edid", "packet"; > > adi,input-depth = <8>; > adi,input-colorspace = "rgb"; -- Regards, Laurent Pinchart ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v3 4/5] media: adv7604: Add support for i2c_new_secondary_device
Hi Kieran, Thank you for the patch. On Tuesday, 13 February 2018 00:07:52 EET Kieran Bingham wrote: > From: Jean-Michel Hautbois > > The ADV7604 has thirteen 256-byte maps that can be accessed via the main > I²C ports. Each map has it own I²C address and acts as a standard slave > device on the I²C bus. > > Allow a device tree node to override the default addresses so that > address conflicts with other devices on the same bus may be resolved at > the board description level. > > Signed-off-by: Jean-Michel Hautbois > [Kieran: Re-adapted for mainline] > Signed-off-by: Kieran Bingham > > --- > Based upon the original posting : > https://lkml.org/lkml/2014/10/22/469 > > v2: > - Split out DT bindings from driver updates > - Return -EINVAL on error paths from adv76xx_dummy_client() > > drivers/media/i2c/adv7604.c | 62 ++ > 1 file changed, 40 insertions(+), 22 deletions(-) > > diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c > index 1544920ec52d..872e124793f8 100644 > --- a/drivers/media/i2c/adv7604.c > +++ b/drivers/media/i2c/adv7604.c > @@ -2734,6 +2734,27 @@ static const struct v4l2_ctrl_config > adv76xx_ctrl_free_run_color = { > > /* - */ > > +struct adv76xx_register { adv76xx_register seems to imply that this describes a particular register, while the structure describes a registers map. How about adv76xx_register_map, adv76xx_register_bank or adv76xx_register_page ? > + const char *name; > + u8 default_addr; > +}; > + > +static const struct adv76xx_register adv76xx_secondary_names[] = { The table doesn't contain secondary names only as there's an entry for the main map. How about calling it adv76xx_default_addresses or something along the same line ? > + [ADV76XX_PAGE_IO] = { "main", 0x4c }, > + [ADV7604_PAGE_AVLINK] = { "avlink", 0x42 }, > + [ADV76XX_PAGE_CEC] = { "cec", 0x40 }, > + [ADV76XX_PAGE_INFOFRAME] = { "infoframe", 0x3e }, > + [ADV7604_PAGE_ESDP] = { "esdp", 0x38 }, > + [ADV7604_PAGE_DPP] = { "dpp", 0x3c }, > + [ADV76XX_PAGE_AFE] = { "afe", 0x26 }, > + [ADV76XX_PAGE_REP] = { "rep", 0x32 }, > + [ADV76XX_PAGE_EDID] = { "edid", 0x36 }, > + [ADV76XX_PAGE_HDMI] = { "hdmi", 0x34 }, > + [ADV76XX_PAGE_TEST] = { "test", 0x30 }, > + [ADV76XX_PAGE_CP] = { "cp", 0x22 }, > + [ADV7604_PAGE_VDP] = { "vdp", 0x24 }, > +}; > + > static int adv76xx_core_init(struct v4l2_subdev *sd) > { > struct adv76xx_state *state = to_state(sd); > @@ -2834,13 +2855,26 @@ static void adv76xx_unregister_clients(struct > adv76xx_state *state) } > > static struct i2c_client *adv76xx_dummy_client(struct v4l2_subdev *sd, > - u8 addr, u8 io_reg) > +unsigned int i) Maybe unsigned int page ? With these fixed, Reviewed-by: Laurent Pinchart > { > struct i2c_client *client = v4l2_get_subdevdata(sd); > + struct adv76xx_state *state = to_state(sd); > + struct adv76xx_platform_data *pdata = &state->pdata; > + unsigned int io_reg = 0xf2 + i; > + struct i2c_client *new_client; > + > + if (pdata && pdata->i2c_addresses[i]) > + new_client = i2c_new_dummy(client->adapter, > +pdata->i2c_addresses[i]); > + else > + new_client = i2c_new_secondary_device(client, > + adv76xx_secondary_names[i].name, > + adv76xx_secondary_names[i].default_addr); > > - if (addr) > - io_write(sd, io_reg, addr << 1); > - return i2c_new_dummy(client->adapter, io_read(sd, io_reg) >> 1); > + if (new_client) > + io_write(sd, io_reg, new_client->addr << 1); > + > + return new_client; > } > > static const struct adv76xx_reg_seq adv7604_recommended_settings_afe[] = { > @@ -3115,20 +3149,6 @@ static int adv76xx_parse_dt(struct adv76xx_state > *state) /* Disable the interrupt for now as no DT-based board uses it. */ > state->pdata.int1_config = ADV76XX_INT1_CONFIG_DISABLED; > > - /* Use the default I2C addresses. */ > - state->pdata.i2c_addresses[ADV7604_PAGE_AVLINK] = 0x42; > - state->pdata.i2c_addresses[ADV76XX_PAGE_CEC] = 0x40; > - state->pdata.i2c_addresses[ADV76XX_PAGE_INFOFRAME] = 0x3e; > - state->pdata.i2c_addresses[ADV7604_PAGE_ESDP] = 0x38; > - state->pdata.i2c_addresses[ADV7604_PAGE_DPP] = 0x3c; > - state->pdata.i2c_addresses[ADV76XX_PAGE_AFE] = 0x26; > - state->pdata.i2c_addresses[ADV76XX_PAGE_REP] = 0x32; > - state->pdata.i2c_addresses[ADV76XX_PAGE_EDID] = 0x36; > - state->pdata.i2c_addresses[ADV76XX_PAGE_HDMI] = 0x34; > - state->pdata.i2c_addresses[ADV76XX_PAGE_TEST] = 0x30; > - state->pdata.i2c_addresses[ADV76XX_PAGE_CP] = 0x22; > - state->pdata.i2c_addresses[ADV7604_PAGE_VDP] = 0x24; > - > /* Har
[Bug 117591] amdgpu: Black screens on A10-8700P (Carrizo) + R7 M260/M265 (Topaz) Combo
https://bugzilla.kernel.org/show_bug.cgi?id=117591 Jani Väinölä (jani.vain...@gmail.com) changed: What|Removed |Added Status|NEW |RESOLVED Resolution|--- |CODE_FIX --- Comment #13 from Jani Väinölä (jani.vain...@gmail.com) --- I installed Kernel 4.15 on this machine now and it worked flawlessly. So I consider this bug resolved on 4.15. -- 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 117591] amdgpu: Black screens on A10-8700P (Carrizo) + R7 M260/M265 (Topaz) Combo
https://bugzilla.kernel.org/show_bug.cgi?id=117591 Jani Väinölä (jani.vain...@gmail.com) changed: What|Removed |Added Resolution|CODE_FIX|UNREPRODUCIBLE -- 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 v3 5/5] drm: adv7511: Add support for i2c_new_secondary_device
Hi Kieran, Thank you for the patch. On Tuesday, 13 February 2018 00:07:53 EET Kieran Bingham wrote: > From: Kieran Bingham > > The ADV7511 has four 256-byte maps that can be accessed via the main I²C > ports. Each map has it own I²C address and acts as a standard slave > device on the I²C bus. > > Allow a device tree node to override the default addresses so that > address conflicts with other devices on the same bus may be resolved at > the board description level. > > Signed-off-by: Kieran Bingham > --- > v2: > - Update missing edid-i2c address setting > - Split out DT bindings > - Rename and move the I2C default addresses to their own section > > drivers/gpu/drm/bridge/adv7511/adv7511.h | 6 > drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 42 > 2 files changed, 33 insertions(+), 15 deletions(-) > > diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h > b/drivers/gpu/drm/bridge/adv7511/adv7511.h index d034b2cb5eee..04e6759ee45b > 100644 > --- a/drivers/gpu/drm/bridge/adv7511/adv7511.h > +++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h > @@ -93,6 +93,11 @@ > #define ADV7511_REG_CHIP_ID_HIGH 0xf5 > #define ADV7511_REG_CHIP_ID_LOW 0xf6 > > +/* Hardware defined default addresses for i2c register maps */ s/i2c/I2C/ ? That's really because I had to find something :-) Reviewed-by: Laurent Pinchart > +#define ADV7511_CEC_I2C_ADDR_DEFAULT 0x3c > +#define ADV7511_EDID_I2C_ADDR_DEFAULT0x3f > +#define ADV7511_PACKET_I2C_ADDR_DEFAULT 0x38 > + > #define ADV7511_CSC_ENABLE BIT(7) > #define ADV7511_CSC_UPDATE_MODE BIT(5) > > @@ -322,6 +327,7 @@ struct adv7511 { > struct i2c_client *i2c_main; > struct i2c_client *i2c_edid; > struct i2c_client *i2c_cec; > + struct i2c_client *i2c_packet; > > struct regmap *regmap; > struct regmap *regmap_cec; > diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c > b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index > efa29db5fc2b..5e61b928c9c0 100644 > --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c > +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c > @@ -586,7 +586,7 @@ static int adv7511_get_modes(struct adv7511 *adv7511, > /* Reading the EDID only works if the device is powered */ > if (!adv7511->powered) { > unsigned int edid_i2c_addr = > - (adv7511->i2c_main->addr << 1) + 4; > + (adv7511->i2c_edid->addr << 1); > > __adv7511_power_on(adv7511); > > @@ -969,10 +969,10 @@ static int adv7511_init_cec_regmap(struct adv7511 > *adv) { > int ret; > > - adv->i2c_cec = i2c_new_dummy(adv->i2c_main->adapter, > - adv->i2c_main->addr - 1); > + adv->i2c_cec = i2c_new_secondary_device(adv->i2c_main, "cec", > + ADV7511_CEC_I2C_ADDR_DEFAULT); > if (!adv->i2c_cec) > - return -ENOMEM; > + return -EINVAL; > i2c_set_clientdata(adv->i2c_cec, adv); > > adv->regmap_cec = devm_regmap_init_i2c(adv->i2c_cec, > @@ -1082,8 +1082,6 @@ static int adv7511_probe(struct i2c_client *i2c, const > struct i2c_device_id *id) struct adv7511_link_config link_config; > struct adv7511 *adv7511; > struct device *dev = &i2c->dev; > - unsigned int main_i2c_addr = i2c->addr << 1; > - unsigned int edid_i2c_addr = main_i2c_addr + 4; > unsigned int val; > int ret; > > @@ -1153,24 +1151,35 @@ static int adv7511_probe(struct i2c_client *i2c, > const struct i2c_device_id *id) if (ret) > goto uninit_regulators; > > - regmap_write(adv7511->regmap, ADV7511_REG_EDID_I2C_ADDR, edid_i2c_addr); > - regmap_write(adv7511->regmap, ADV7511_REG_PACKET_I2C_ADDR, > - main_i2c_addr - 0xa); > - regmap_write(adv7511->regmap, ADV7511_REG_CEC_I2C_ADDR, > - main_i2c_addr - 2); > - > adv7511_packet_disable(adv7511, 0x); > > - adv7511->i2c_edid = i2c_new_dummy(i2c->adapter, edid_i2c_addr >> 1); > + adv7511->i2c_edid = i2c_new_secondary_device(i2c, "edid", > + ADV7511_EDID_I2C_ADDR_DEFAULT); > if (!adv7511->i2c_edid) { > - ret = -ENOMEM; > + ret = -EINVAL; > goto uninit_regulators; > } > > + regmap_write(adv7511->regmap, ADV7511_REG_EDID_I2C_ADDR, > + adv7511->i2c_edid->addr << 1); > + > ret = adv7511_init_cec_regmap(adv7511); > if (ret) > goto err_i2c_unregister_edid; > > + regmap_write(adv7511->regmap, ADV7511_REG_CEC_I2C_ADDR, > + adv7511->i2c_cec->addr << 1); > + > + adv7511->i2c_packet = i2c_new_secondary_device(i2c, "packet", > + ADV7511_PACKET_I2C_ADDR_DEFAULT); > + if (!adv7511->i2c_packet) { > +
Re: [PATCH 02/11] video: fbdev: kconfig: Remove blank help text
On Thursday, February 01, 2018 05:56:18 PM Ulf Magnusson wrote: > On Thu, Feb 1, 2018 at 4:52 PM, Bartlomiej Zolnierkiewicz > wrote: > > > > Hi, > > > > On Wednesday, January 31, 2018 10:34:21 AM Ulf Magnusson wrote: > >> Blank help texts are probably either a typo, a Kconfig misunderstanding, > >> or some kind of half-committing to adding a help text (in which case a > >> TODO comment would be clearer, if the help text really can't be added > >> right away). > >> > >> Best to remove them, IMO. > > > > How about actually adding some meaningful help texts instead > > (as a general rule each user visible option should have valid > > help text)? > > > >> Signed-off-by: Ulf Magnusson > >> --- > >> drivers/video/fbdev/Kconfig | 1 - > >> 1 file changed, 1 deletion(-) > >> > >> diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig > >> index 6962b4583fd7..11e699f1062b 100644 > >> --- a/drivers/video/fbdev/Kconfig > >> +++ b/drivers/video/fbdev/Kconfig > >> @@ -1156,7 +1156,6 @@ config FB_I810_I2C > >> bool "Enable DDC Support" > >> depends on FB_I810 && FB_I810_GTF > >> select FB_DDC > >> - help > > > > Please add a missing help text instead (take a look at FB_SAVAGE_I2C > > config option to see how a valid help text entry should look like). > > The FB_I810_I2C option was added in 74f6ae84b23 ("[PATCH] i810fb: Add > i2c/DDC support"). What do you think about adding this bit from the > commit message as the help text? > > Add DDC/I2C support for i810fb. This will allow the driver to get display > information, especially for monitors with fickle timings. Seems fine to me, please add: If unsure, say Y. and send it as a proper patch. > I'm not familiar with this code, so I don't want to do too much > guessing myself. :) :) > > In the longer term we should consider removing *_I2C config options > > and just make the main config options always enable I2C subsystem > > directly if needed/useful (some fbdev drivers are doing it this way > > already). > > > >> config FB_LE80578 > >> tristate "Intel LE80578 (Vermilion) support" > > > > Best regards, > > -- > > Bartlomiej Zolnierkiewicz > > Samsung R&D Institute Poland > > Samsung Electronics > > > > Cheers, > Ulf Best regards, -- Bartlomiej Zolnierkiewicz Samsung R&D Institute Poland Samsung Electronics ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 99353] Kaveri 7400K shows random colored noise instead of GUI in X or Wayland
https://bugs.freedesktop.org/show_bug.cgi?id=99353 --- Comment #27 from Bong Cosca --- Created attachment 137313 --> https://bugs.freedesktop.org/attachment.cgi?id=137313&action=edit drm.debug=0x1e Output generated by: dmesg | grep drm Additional trace log to aid perhaps in finding the root cause. I would gladly help out in tracking this bug; already tried looking at the sources but really don't know what to look for. Perhaps a nudge from someone knowledgeable so we can narrow it down. -- You are receiving this mail because: You are the assignee for the bug.___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v7 1/6] base: power: runtime: Export pm_runtime_get/put_suppliers
On Tue, Feb 13, 2018 at 9:00 PM, Robin Murphy wrote: > On 13/02/18 07:44, Tomasz Figa wrote: >> >> Hi Vivek, >> >> On Wed, Feb 7, 2018 at 7:31 PM, Vivek Gautam >> wrote: >>> >>> The device link allows the pm framework to tie the supplier and >>> consumer. So, whenever the consumer is powered-on the supplier >>> is powered-on first. >>> >>> There are however cases in which the consumer wants to power-on >>> the supplier, but not itself. >>> E.g., A Graphics or multimedia driver wants to power-on the SMMU >>> to unmap a buffer and finish the TLB operations without powering >>> on itself. >> >> >> This sounds strange to me. If the SMMU is powered down, wouldn't the >> TLB lose its contents as well (and so no flushing needed)? > > > Depends on implementation details - if runtime PM is actually implemented > via external clock gating (in the absence of fine-grained power domains), > then "suspended" TLBs might both retain state and not receive invalidation > requests, which is really the worst case. Agreed. That's why in "[PATCH v7 3/6] iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device" I actually suggested managing clocks separately from runtime PM. At least until runtime PM framework arrives at a state, where multiple power states can be managed, i.e. full power state, clock-gated state, domain-off state. (I think I might have seen some ongoing work on this on LWN though...) > >> Other than that, what kind of hardware operations would be needed >> besides just updating the page tables from the CPU? > > > Domain attach/detach also require updating SMMU hardware state (and possibly > TLB maintenance), but don't logically require the master device itself to be > active at the time. Wouldn't this hardware state need to be reinitialized anyway after respective power domain power cycles? (In other words, hardware would only need programming if it's powered on at the moment.) Best regards, Tomasz ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v7 3/6] iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device
On 13/02/18 08:24, Tomasz Figa wrote: Hi Vivek, Thanks for the patch. Please see my comments inline. On Wed, Feb 7, 2018 at 7:31 PM, Vivek Gautam wrote: From: Sricharan R The smmu device probe/remove and add/remove master device callbacks gets called when the smmu is not linked to its master, that is without the context of the master device. So calling runtime apis in those places separately. Signed-off-by: Sricharan R [vivek: Cleanup pm runtime calls] Signed-off-by: Vivek Gautam --- drivers/iommu/arm-smmu.c | 42 ++ 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 9e2f917e16c2..c024f69c1682 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -913,11 +913,15 @@ static void arm_smmu_destroy_domain_context(struct iommu_domain *domain) struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); struct arm_smmu_device *smmu = smmu_domain->smmu; struct arm_smmu_cfg *cfg = &smmu_domain->cfg; - int irq; + int ret, irq; if (!smmu || domain->type == IOMMU_DOMAIN_IDENTITY) return; + ret = pm_runtime_get_sync(smmu->dev); + if (ret) + return; pm_runtime_get_sync() will return 0 if the device was powered off, 1 if it was already/still powered on or runtime PM is not compiled in, or a negative value on error, so shouldn't the test be (ret < 0)? Moreover, I'm actually wondering if it makes any sense to power up the hardware just to program it and power it down again. In a system where the IOMMU is located within a power domain, it would cause the IOMMU block to lose its state anyway. This is generally for the case where the SMMU internal state remains active, but the programming interface needs to be powered up in order to access it. Actually, reflecting back on "[PATCH v7 2/6] iommu/arm-smmu: Add pm_runtime/sleep ops", perhaps it would make more sense to just control the clocks independently of runtime PM? Then, runtime PM could be used for real power management, e.g. really powering the block up and down, for further power saving. Unfortunately that ends up pretty much unmanageable, because there are numerous different SMMU microarchitectures with fundamentally different clock/power domain schemes (multiplied by individual SoC integration possibilities). Since this is fundamentally a generic architectural driver, adding explicit clock support would probably make the whole thing about 50% clock code, with complicated decision trees around every hardware access calculating which clocks are necessary for a given operation on a given system. That maintainability aspect is why we've already nacked such a fine-grained approach in the past. Robin. ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v2 5/5] drm: adv7511: Add support for i2c_new_secondary_device
Hi Dan Thank you for the review, On 13/02/18 07:23, Dan Carpenter wrote: > On Mon, Feb 12, 2018 at 06:11:57PM +, Kieran Bingham wrote: >> +adv7511->i2c_packet = i2c_new_secondary_device(i2c, "packet", >> +ADV7511_PACKET_I2C_ADDR_DEFAULT); >> +if (!adv7511->i2c_packet) { >> +ret = -EINVAL; >> +goto err_unregister_cec; >> +} >> + >> +regmap_write(adv7511->regmap, ADV7511_REG_PACKET_I2C_ADDR, >> + adv7511->i2c_packet->addr << 1); >> + >> INIT_WORK(&adv7511->hpd_work, adv7511_hpd_work); >> >> if (i2c->irq) { >> @@ -1181,7 +1190,7 @@ static int adv7511_probe(struct i2c_client *i2c, const >> struct i2c_device_id *id) >> IRQF_ONESHOT, dev_name(dev), >> adv7511); >> if (ret) >> -goto err_unregister_cec; >> +goto err_unregister_packet; >> } >> >> adv7511_power_off(adv7511); > > There is another goto which needs to be updated if adv7511_cec_init() > fails. Aha - thanks - I'll look into this now. > >> @@ -1203,6 +1212,8 @@ static int adv7511_probe(struct i2c_client *i2c, const >> struct i2c_device_id *id) >> adv7511_audio_init(dev, adv7511); >> return 0; >> >> +err_unregister_packet: >> +i2c_unregister_device(adv7511->i2c_packet); >> err_unregister_cec: >> i2c_unregister_device(adv7511->i2c_cec); >> if (adv7511->cec_clk) > > > regards, > dan carpenter > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v3 1/5] dt-bindings: media: adv7604: Add support for i2c_new_secondary_device
Hi Laurent, On 13/02/18 12:06, Laurent Pinchart wrote: > Hi Kieran, > > Thank you for the patch. Thank you for your review, > On Tuesday, 13 February 2018 00:07:49 EET Kieran Bingham wrote: >> From: Jean-Michel Hautbois >> >> The ADV7604 has thirteen 256-byte maps that can be accessed via the main >> I²C ports. Each map has it own I²C address and acts as a standard slave >> device on the I²C bus. >> >> Extend the device tree node bindings to be able to override the default >> addresses so that address conflicts with other devices on the same bus >> may be resolved at the board description level. >> >> Signed-off-by: Jean-Michel Hautbois >> [Kieran: Re-adapted for mainline] >> Signed-off-by: Kieran Bingham >> Reviewed-by: Rob Herring > > Nitpicking, I might not mention i2c_new_secondary_device in the subject, as > this is a DT bindings change. I don't mind too much though, as long as the > bindings themselves don't contain Linux-specific information, and they don't, > so How about: ... adv7604: Extend bindings to allow specifying slave map addresses > Reviewed-by: Laurent Pinchart Collected, thanks. -- Kieran > >> --- >> Based upon the original posting : >> https://lkml.org/lkml/2014/10/22/469 >> >> v2: >> - DT Binding update separated from code change >> - Minor reword to commit message to account for DT only change. >> - Collected Rob's RB tag. >> >> v3: >> - Split map register addresses into individual declarations. >> >> .../devicetree/bindings/media/i2c/adv7604.txt | 18 >> -- 1 file changed, 16 insertions(+), 2 deletions(-) >> >> diff --git a/Documentation/devicetree/bindings/media/i2c/adv7604.txt >> b/Documentation/devicetree/bindings/media/i2c/adv7604.txt index >> 9cbd92eb5d05..ebb5f070c05b 100644 >> --- a/Documentation/devicetree/bindings/media/i2c/adv7604.txt >> +++ b/Documentation/devicetree/bindings/media/i2c/adv7604.txt >> @@ -13,7 +13,11 @@ Required Properties: >> - "adi,adv7611" for the ADV7611 >> - "adi,adv7612" for the ADV7612 >> >> - - reg: I2C slave address >> + - reg: I2C slave addresses >> +The ADV76xx has up to thirteen 256-byte maps that can be accessed via >> the +main I²C ports. Each map has it own I²C address and acts as a >> standard +slave device on the I²C bus. The main address is mandatory, >> others are +optional and revert to defaults if not specified. >> >>- hpd-gpios: References to the GPIOs that control the HDMI hot-plug >> detection pins, one per HDMI input. The active flag indicates the GPIO >> @@ -35,6 +39,11 @@ Optional Properties: >> >>- reset-gpios: Reference to the GPIO connected to the device's reset pin. >> - default-input: Select which input is selected after reset. >> + - reg-names : Names of maps with programmable addresses. >> +It can contain any map needing a non-default address. >> +Possible maps names are : >> + "main", "avlink", "cec", "infoframe", "esdp", "dpp", "afe", >> + "rep", "edid", "hdmi", "test", "cp", "vdp" >> >> Optional Endpoint Properties: >> >> @@ -52,7 +61,12 @@ Example: >> >> hdmi_receiver@4c { >> compatible = "adi,adv7611"; >> -reg = <0x4c>; >> +/* >> + * The edid page will be accessible @ 0x66 on the i2c bus. All >> + * other maps will retain their default addresses. >> + */ >> +reg = <0x4c>, <0x66>; >> +reg-names "main", "edid"; >> >> reset-gpios = <&ioexp 0 GPIO_ACTIVE_LOW>; >> hpd-gpios = <&ioexp 2 GPIO_ACTIVE_HIGH>; > > ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v3 5/8] drm: Handle aspect ratio info in atomic and legacy modeset paths
On Tue, Feb 13, 2018 at 10:21:15AM +0530, Nautiyal, Ankit K wrote: > Hi Ville, > > As per our last discussion, following points were discussed: > > 1. To suppress the aspect-ratio info from getblob ioctl to a user that > does not support it: > > i. A new flag must be added to drm_blob_property to mark if the > blob has mode data. > > ii. This flag must be set when the user tries do an atomic modeset. > > iii. In the getblob ioctl, based on the above flag, it can be > determined that if the blob > > has mode data, and the aspect ratio info can be suppressed in > getblob ioctl, if user does not support it. > > 2. Instead of adding aspect ratio capabilities in drm_atomic_state, pass > on the file_priv which already has > > the required information to the function drm_mode_convert_umode. > > It will require addition of an new argument file_priv to several > functions, but that is right thing to do, > > as file_priv is the correct structure for the capability information. > > 3. Changing the usermode aspect ratio flag bits, without change in the > picture_aspect_ratio would not matter, and does not need to be handled > in this patch. > > > I just have one query here. We have agreed to modify > drm_mode_convert_umode, to filter out the aspect-ratio > > info if user has not set aspect-ratio capability, but do we need a > similar change the drm_mode_convert_to_umode? I think you maybe had those backwards. drm_mode_convert_umode(), or more likely its relevant callers setcrtc and setproperty, need to reject the mode if the client cap is not set. drm_mode_convert_to_umode(), or rather its callers getblob and getcrtc, need to filter out the flags. > > If we do, I am not sure if it would be possible to have the file_priv to > /drm_atomic_set_mode_for_crtc/, which calls > > drm_mode_convert_to_umode. The function /drm_atomic_set_mode_for_crtc/ > is used to set mode, originating by kernel, > > and make a blob from the kernel mode, which it saves in crtc_state. > > This function /: drm_atomic_set_mode_for_crtc, /is called by several > helper functions and driver functions, and passing > > file_priv from all these functions does not seem to be plausible. I don't think we need to plumb it quite that deep. Doing the check in drm_atomic_crtc_set_property() should be sufficient. > > Any suggestions on how to handle this situation? > > > Regards, > > Ankit > > > On 2/8/2018 9:59 AM, Nautiyal, Ankit K wrote: > > Hi Ville, > > > > I still have some queries regarding the handling of aspect ratio flags > > in getblob ioctl. > > > > Please find below my responses inline. > > > > > > On 2/1/2018 6:24 PM, Ville Syrjälä wrote: > >> On Thu, Feb 01, 2018 at 04:35:22PM +0530, Nautiyal, Ankit K wrote: > >>> Hi Ville, > >>> > >>> Appreciate your time and the suggestions. > >>> Please find my response inline: > >>> > >>> On 1/31/2018 6:39 PM, Ville Syrjälä wrote: > On Wed, Jan 31, 2018 at 12:04:52PM +0530, Nautiyal, Ankit K wrote: > > On 1/30/2018 12:23 AM, Ville Syrjälä wrote: > >> On Fri, Jan 12, 2018 at 11:51:33AM +0530, Nautiyal, Ankit K wrote: > >>> From: Ankit Nautiyal > >>> > >>> If the user mode does not support aspect-ratio, and requests for > >>> a modeset, then the flag bits representing aspect ratio in the > >>> given user-mode must be rejected. > >>> Similarly, while preparing a user-mode from kernel mode, the > >>> aspect-ratio info must not be given, if aspect-ratio is not > >>> supported by the user. > >>> > >>> This patch: > >>> 1. adds a new bit field aspect_ratio_allowed in drm_atomic_state, > >>> which is set only if the aspect-ratio is supported by the user. > >>> 2. discards the aspect-ratio info from the user mode while > >>> preparing kernel mode structure, during modeset, if the > >>> user does not support aspect ratio. > >>> 3. avoids setting the aspect-ratio info in user-mode, while > >>> converting user-mode from the kernel-mode. > >>> > >>> Signed-off-by: Ankit Nautiyal > >>> > >>> V3: Addressed review comments from Ville: > >>> -Do not corrupt the current crtc state by updating aspect ratio > >>> on the fly. > >>> --- > >>> drivers/gpu/drm/drm_atomic.c | 61 > >>> +--- > >>> drivers/gpu/drm/drm_crtc.c | 19 ++ > >>> include/drm/drm_atomic.h | 2 ++ > >>> 3 files changed, 79 insertions(+), 3 deletions(-) > >>> > >>> diff --git a/drivers/gpu/drm/drm_atomic.c > >>> b/drivers/gpu/drm/drm_atomic.c > >>> index 69ff763..39313e2 100644 > >>> --- a/drivers/gpu/drm/drm_atomic.c > >>> +++ b/drivers/gpu/drm/drm_atomic.c > >>> @@ -316,6 +316,35 @@ static s32 __user > >>> *get_out_fence_for_crtc(struct drm_atomic_state *state, > >>> return fence_ptr; > >>> } > >>> +/** > >>> + * drm_atomic_allow_a
Re: Thinkpad X1 Carbon 3rd - Reducing the compressed framebuffer size
On Tue, Feb 13, 2018 at 09:50:30AM +0100, Pali Rohár wrote: > On Tuesday 06 February 2018 16:21:43 Pali Rohár wrote: > > Hi! I'm periodically getting following message in dmesg on Lenovo > > Thinkpad X1 Carbon 3rd generation: > > > > [drm] Reducing the compressed framebuffer size. This may lead to less power > > savings than a non-reduced-size. Try to increase stolen memory size if > > available in BIOS. > > > > In BIOS I already set GPU size to 512M, but this did not help. Also > > update to last BIOS version did not help. > > > > So why this message is periodically print in dmesg? And what can I do > > with this problem? > > > > And why cannot Linux kernel allocate itself more memory for GPU (if BIOS > > can/could do that)? Is not 512MB for GPU enough? > > And here is output from lspci, which clearly says that 512MB is already > set for GPU: The PCI BAR size has nothing to do with the size of the stolen memory. The BAR just provides a window into the global GTT address space of the GPU. Stolen memory is a contiguous chunk of physical memory carved out by the BIOS. The BIOS may or may not provide a knob to change the size of the stolen memory. > > $ lspci -v -s 00:02.0 > 00:02.0 VGA compatible controller: Intel Corporation HD Graphics 5500 (rev > 09) (prog-if 00 [VGA controller]) > Subsystem: Lenovo HD Graphics 5500 > Flags: bus master, fast devsel, latency 0, IRQ 46 > Memory at e000 (64-bit, non-prefetchable) [size=16M] > Memory at c000 (64-bit, prefetchable) [size=512M] > I/O ports at 3000 [size=64] > [virtual] Expansion ROM at 000c [disabled] [size=128K] > Capabilities: [90] MSI: Enable+ Count=1/1 Maskable- 64bit- > Capabilities: [d0] Power Management version 2 > Capabilities: [a4] PCI Advanced Features > Kernel driver in use: i915 > Kernel modules: i915 > > -- > Pali Rohár > pali.ro...@gmail.com > ___ > dri-devel mailing list > dri-devel@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/dri-devel -- Ville Syrjälä Intel OTC ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [RFC] drm/atomic: Abuse legacy cursor update flag for legacy gamma update too
On Tue, Feb 13, 2018 at 10:33:28AM +0100, Maarten Lankhorst wrote: > Hey, > > Op 13-02-18 om 10:16 schreef Chris Wilson: > > Quoting Maarten Lankhorst (2018-02-13 09:12:01) > >> Programs like redshift set the legacy gamma for X.org every 5 seconds. > >> Because atomic commits wait for vblank completion, we get a frame drop > >> every 5 seconds because of the legacy gamma update. > >> > >> Work around this by setting the legacy_cursor_update flag, to force > >> legacy gamma updates not to be synced against vblank. > >> > >> Reported-by: Tholin #intel-gfx > >> Signed-off-by: Maarten Lankhorst > > Reminiscing: Remember the time we had all those vblank workers patches, > > one of which was to do async gamma updates (apply the last one on the > > vblank). Motivated by gnome-shell and the ilk doing a gamma animation > > for fade-out on logout (which I guess they gave up on since it happened > > to be so slow as to extend logout ;). > > That special case could be handled by userspace with atomic commits, I don't > think it's worth optimizing it further.. We need to eventually move the gamma updates (and other single buffered registers) to a vblank worker or something similar. Otherwise they will tear. -- Ville Syrjälä Intel OTC ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v3 1/5] dt-bindings: media: adv7604: Add support for i2c_new_secondary_device
Hi Kieran, On Tuesday, 13 February 2018 15:14:43 EET Kieran Bingham wrote: > On 13/02/18 12:06, Laurent Pinchart wrote: > > On Tuesday, 13 February 2018 00:07:49 EET Kieran Bingham wrote: > >> From: Jean-Michel Hautbois > >> > >> The ADV7604 has thirteen 256-byte maps that can be accessed via the main > >> I²C ports. Each map has it own I²C address and acts as a standard slave > >> device on the I²C bus. > >> > >> Extend the device tree node bindings to be able to override the default > >> addresses so that address conflicts with other devices on the same bus > >> may be resolved at the board description level. > >> > >> Signed-off-by: Jean-Michel Hautbois > >> [Kieran: Re-adapted for mainline] > >> Signed-off-by: Kieran Bingham > >> Reviewed-by: Rob Herring > > > > Nitpicking, I might not mention i2c_new_secondary_device in the subject, > > as this is a DT bindings change. I don't mind too much though, as long as > > the bindings themselves don't contain Linux-specific information, and they > > don't, so > > How about: ... adv7604: Extend bindings to allow specifying slave map > addresses Sounds good to me. > > Reviewed-by: Laurent Pinchart > > Collected, thanks. > > -- > Kieran > > >> --- > >> > >> Based upon the original posting : > >> https://lkml.org/lkml/2014/10/22/469 > >> > >> v2: > >> - DT Binding update separated from code change > >> - Minor reword to commit message to account for DT only change. > >> - Collected Rob's RB tag. > >> > >> v3: > >> - Split map register addresses into individual declarations. > >> > >> .../devicetree/bindings/media/i2c/adv7604.txt | 18 > >> > >> -- 1 file changed, 16 insertions(+), 2 deletions(-) > >> > >> diff --git a/Documentation/devicetree/bindings/media/i2c/adv7604.txt > >> b/Documentation/devicetree/bindings/media/i2c/adv7604.txt index > >> 9cbd92eb5d05..ebb5f070c05b 100644 > >> --- a/Documentation/devicetree/bindings/media/i2c/adv7604.txt > >> +++ b/Documentation/devicetree/bindings/media/i2c/adv7604.txt > >> > >> @@ -13,7 +13,11 @@ Required Properties: > >> - "adi,adv7611" for the ADV7611 > >> - "adi,adv7612" for the ADV7612 > >> > >> - - reg: I2C slave address > >> + - reg: I2C slave addresses > >> +The ADV76xx has up to thirteen 256-byte maps that can be accessed > >> via > >> the +main I²C ports. Each map has it own I²C address and acts as a > >> standard +slave device on the I²C bus. The main address is mandatory, > >> others are +optional and revert to defaults if not specified. > >> > >>- hpd-gpios: References to the GPIOs that control the HDMI hot-plug > >> > >> detection pins, one per HDMI input. The active flag indicates the > >> GPIO > >> > >> @@ -35,6 +39,11 @@ Optional Properties: > >>- reset-gpios: Reference to the GPIO connected to the device's reset > >>pin. > >> > >> - default-input: Select which input is selected after reset. > >> + - reg-names : Names of maps with programmable addresses. > >> + It can contain any map needing a non-default address. > >> + Possible maps names are : > >> +"main", "avlink", "cec", "infoframe", "esdp", "dpp", "afe", > >> +"rep", "edid", "hdmi", "test", "cp", "vdp" > >> > >> Optional Endpoint Properties: > >> @@ -52,7 +61,12 @@ Example: > >>hdmi_receiver@4c { > >> > >>compatible = "adi,adv7611"; > >> > >> - reg = <0x4c>; > >> + /* > >> + * The edid page will be accessible @ 0x66 on the i2c bus. All > >> + * other maps will retain their default addresses. > >> + */ > >> + reg = <0x4c>, <0x66>; > >> + reg-names "main", "edid"; > >> > >>reset-gpios = <&ioexp 0 GPIO_ACTIVE_LOW>; > >>hpd-gpios = <&ioexp 2 GPIO_ACTIVE_HIGH>; -- Regards, Laurent Pinchart ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v7 1/6] base: power: runtime: Export pm_runtime_get/put_suppliers
On 13/02/18 12:54, Tomasz Figa wrote: On Tue, Feb 13, 2018 at 9:00 PM, Robin Murphy wrote: On 13/02/18 07:44, Tomasz Figa wrote: Hi Vivek, On Wed, Feb 7, 2018 at 7:31 PM, Vivek Gautam wrote: The device link allows the pm framework to tie the supplier and consumer. So, whenever the consumer is powered-on the supplier is powered-on first. There are however cases in which the consumer wants to power-on the supplier, but not itself. E.g., A Graphics or multimedia driver wants to power-on the SMMU to unmap a buffer and finish the TLB operations without powering on itself. This sounds strange to me. If the SMMU is powered down, wouldn't the TLB lose its contents as well (and so no flushing needed)? Depends on implementation details - if runtime PM is actually implemented via external clock gating (in the absence of fine-grained power domains), then "suspended" TLBs might both retain state and not receive invalidation requests, which is really the worst case. Agreed. That's why in "[PATCH v7 3/6] iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device" I actually suggested managing clocks separately from runtime PM. At least until runtime PM framework arrives at a state, where multiple power states can be managed, i.e. full power state, clock-gated state, domain-off state. (I think I might have seen some ongoing work on this on LWN though...) Other than that, what kind of hardware operations would be needed besides just updating the page tables from the CPU? Domain attach/detach also require updating SMMU hardware state (and possibly TLB maintenance), but don't logically require the master device itself to be active at the time. Wouldn't this hardware state need to be reinitialized anyway after respective power domain power cycles? (In other words, hardware would only need programming if it's powered on at the moment.) Yes, if the entire SMMU was fully powered down because all masters were inactive, then all that should need to be done is to update the software shadow state in the expectation that arm_smmu_reset() would re-sync it upon TCU powerup. If at least some part of the internal logic remains active, though, then you may or may not need to fiddle with zero or more clocks and/or power domains (depending on microarchitecture and integration) in order to be sure that everything from the programming slave interface through to wherever that state is kept works correctly so that it can be changed. The main motivation here is that the Qualcomm SMMU microarchitecture apparently allows the programming interface to be shut down separately from the TCU core (context banks, page table walker, etc.), and they get an appreciable power saving from doing so. This is different from, say, the Arm Ltd. implementations, where the entire TCU is a single clock/power domain internally (although you could maybe still gate the external APB interface clock). As the previous discussions have shown, this is really, really hard to do properly in a generic manner. Robin. ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: Thinkpad X1 Carbon 3rd - Reducing the compressed framebuffer size
On Tuesday 13 February 2018 15:27:26 Ville Syrjälä wrote: > On Tue, Feb 13, 2018 at 09:50:30AM +0100, Pali Rohár wrote: > > On Tuesday 06 February 2018 16:21:43 Pali Rohár wrote: > > > Hi! I'm periodically getting following message in dmesg on Lenovo > > > Thinkpad X1 Carbon 3rd generation: > > > > > > [drm] Reducing the compressed framebuffer size. This may lead to less > > > power savings than a non-reduced-size. Try to increase stolen memory size > > > if available in BIOS. > > > > > > In BIOS I already set GPU size to 512M, but this did not help. Also > > > update to last BIOS version did not help. > > > > > > So why this message is periodically print in dmesg? And what can I do > > > with this problem? > > > > > > And why cannot Linux kernel allocate itself more memory for GPU (if BIOS > > > can/could do that)? Is not 512MB for GPU enough? > > > > And here is output from lspci, which clearly says that 512MB is already > > set for GPU: > > The PCI BAR size has nothing to do with the size of the stolen memory. > The BAR just provides a window into the global GTT address space of the > GPU. Stolen memory is a contiguous chunk of physical memory carved out > by the BIOS. Ok, how could I detect how much memory was stolen? In dmesg I see following lines: [0.00] e820: BIOS-provided physical RAM map: [0.00] BIOS-e820: [mem 0x-0x00057fff] usable [0.00] BIOS-e820: [mem 0x00058000-0x00058fff] reserved [0.00] BIOS-e820: [mem 0x00059000-0x0008bfff] usable [0.00] BIOS-e820: [mem 0x0008c000-0x0009] reserved [0.00] BIOS-e820: [mem 0x000e-0x000f] reserved [0.00] BIOS-e820: [mem 0x0010-0xab908fff] usable [0.00] BIOS-e820: [mem 0xab909000-0xabb08fff] type 20 [0.00] BIOS-e820: [mem 0xabb09000-0xacbfefff] reserved [0.00] BIOS-e820: [mem 0xacbff000-0xacd7efff] ACPI NVS [0.00] BIOS-e820: [mem 0xacd7f000-0xacdfefff] ACPI data [0.00] BIOS-e820: [mem 0xacdff000-0xacdf] usable [0.00] BIOS-e820: [mem 0xf80f8000-0xf80f8fff] reserved [0.00] BIOS-e820: [mem 0xfed1c000-0xfed1] reserved [0.00] BIOS-e820: [mem 0x0001-0x00024dff] usable [0.00] Reserving Intel graphics memory at 0xae00-0xafff [0.00] Memory: 7972840K/8282704K available (6196K kernel code, 1159K rwdata, 2848K rodata, 1408K init, 688K bss, 309864K reserved, 0K cma-reserved) > The BIOS may or may not provide a knob to change the size > of the stolen memory. In BIOS Setup screen I have option to choose GPU memory and I set it to max 512MB. So this is not the right option... And why cannot kernel use some continuous check of RAM itself? > > > > $ lspci -v -s 00:02.0 > > 00:02.0 VGA compatible controller: Intel Corporation HD Graphics 5500 (rev > > 09) (prog-if 00 [VGA controller]) > > Subsystem: Lenovo HD Graphics 5500 > > Flags: bus master, fast devsel, latency 0, IRQ 46 > > Memory at e000 (64-bit, non-prefetchable) [size=16M] > > Memory at c000 (64-bit, prefetchable) [size=512M] > > I/O ports at 3000 [size=64] > > [virtual] Expansion ROM at 000c [disabled] [size=128K] > > Capabilities: [90] MSI: Enable+ Count=1/1 Maskable- 64bit- > > Capabilities: [d0] Power Management version 2 > > Capabilities: [a4] PCI Advanced Features > > Kernel driver in use: i915 > > Kernel modules: i915 > > > > -- > > Pali Rohár > > pali.ro...@gmail.com > > ___ > > dri-devel mailing list > > dri-devel@lists.freedesktop.org > > https://lists.freedesktop.org/mailman/listinfo/dri-devel > -- Pali Rohár pali.ro...@gmail.com ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] drm: Use idr_init_base(1) when using id==0 for invalid
Am 12.02.2018 um 18:14 schrieb Ville Syrjälä: On Mon, Feb 12, 2018 at 02:55:33PM +, Chris Wilson wrote: Use the new idr_init_base() function to create an IDR that knows id==0 is never allocated as it maps to an invalid identifier. By knowing that id==0 is invalid, the IDR can start from id=1 instead avoiding the issue of having to start each lookup from the zeroth leaf as id==0 is always unused (and thus the tree-of-bitmaps indicate that is the first available). References: 6ce711f27500 ("idr: Make 1-based IDRs more efficient") Signed-off-by: Chris Wilson Cc: Daniel Vetter Cc: Christian Konig Cc: Dave Airlie Yep, looks like all of these pass start==1 to idr_alloc(). Reviewed-by: Ville Syrjälä Acked-by: Christian König as well. Probably going to do this for the command submission context handles in amdgpu as well. Thanks, Christian. Looks like at least tile_idr and crtc_idr could use this as well, although I suppose they're not hit nearly as hard as the gem stuff. Also someone should really s/crtc_idr/obj_id_idr/ or something along those lines. --- Note this requires 4.16-rc1. --- drivers/gpu/drm/drm_gem.c | 4 ++-- drivers/gpu/drm/drm_syncobj.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index 01f8d9481211..4975ba9a7bc8 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c @@ -98,7 +98,7 @@ drm_gem_init(struct drm_device *dev) struct drm_vma_offset_manager *vma_offset_manager; mutex_init(&dev->object_name_lock); - idr_init(&dev->object_name_idr); + idr_init_base(&dev->object_name_idr, 1); vma_offset_manager = kzalloc(sizeof(*vma_offset_manager), GFP_KERNEL); if (!vma_offset_manager) { @@ -776,7 +776,7 @@ drm_gem_open_ioctl(struct drm_device *dev, void *data, void drm_gem_open(struct drm_device *dev, struct drm_file *file_private) { - idr_init(&file_private->object_idr); + idr_init_base(&file_private->object_idr, 1); spin_lock_init(&file_private->table_lock); } diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index 0b7b0d1ad2d5..d4f4ce484529 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -546,7 +546,7 @@ static int drm_syncobj_export_sync_file(struct drm_file *file_private, void drm_syncobj_open(struct drm_file *file_private) { - idr_init(&file_private->syncobj_idr); + idr_init_base(&file_private->syncobj_idr, 1); spin_lock_init(&file_private->syncobj_table_lock); } -- 2.16.1 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 3/4] drm/tve200: Do not use deprecated drm_driver.{enable|disable)_vblank
On Mon, Feb 12, 2018 at 9:52 AM, Oleksandr Andrushchenko wrote: > From: Oleksandr Andrushchenko > > Do not use deprecated drm_driver.{enable|disable)_vblank callbacks, > but use drm_simple_kms_helpe's pipe callbacks instead. > > Signed-off-by: Oleksandr Andrushchenko > Cc: Linus Walleij The new way of doing these abstractions seem good, so if people agree on the general subject (other patches in the series I guess) Reviewed-by: Linus Walleij Yours, Linus Walleij ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v7 3/6] iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device
On Tue, Feb 13, 2018 at 9:57 PM, Robin Murphy wrote: > On 13/02/18 08:24, Tomasz Figa wrote: >> >> Hi Vivek, >> >> Thanks for the patch. Please see my comments inline. >> >> On Wed, Feb 7, 2018 at 7:31 PM, Vivek Gautam >> wrote: >>> >>> From: Sricharan R >>> >>> The smmu device probe/remove and add/remove master device callbacks >>> gets called when the smmu is not linked to its master, that is without >>> the context of the master device. So calling runtime apis in those places >>> separately. >>> >>> Signed-off-by: Sricharan R >>> [vivek: Cleanup pm runtime calls] >>> Signed-off-by: Vivek Gautam >>> --- >>> drivers/iommu/arm-smmu.c | 42 >>> ++ >>> 1 file changed, 38 insertions(+), 4 deletions(-) >>> >>> diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c >>> index 9e2f917e16c2..c024f69c1682 100644 >>> --- a/drivers/iommu/arm-smmu.c >>> +++ b/drivers/iommu/arm-smmu.c >>> @@ -913,11 +913,15 @@ static void arm_smmu_destroy_domain_context(struct >>> iommu_domain *domain) >>> struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); >>> struct arm_smmu_device *smmu = smmu_domain->smmu; >>> struct arm_smmu_cfg *cfg = &smmu_domain->cfg; >>> - int irq; >>> + int ret, irq; >>> >>> if (!smmu || domain->type == IOMMU_DOMAIN_IDENTITY) >>> return; >>> >>> + ret = pm_runtime_get_sync(smmu->dev); >>> + if (ret) >>> + return; >> >> >> pm_runtime_get_sync() will return 0 if the device was powered off, 1 >> if it was already/still powered on or runtime PM is not compiled in, >> or a negative value on error, so shouldn't the test be (ret < 0)? >> >> Moreover, I'm actually wondering if it makes any sense to power up the >> hardware just to program it and power it down again. In a system where >> the IOMMU is located within a power domain, it would cause the IOMMU >> block to lose its state anyway. > > > This is generally for the case where the SMMU internal state remains active, > but the programming interface needs to be powered up in order to access it. That's true for Qualcomm SMMU, but I think that would be different for existing users of the driver? > >> Actually, reflecting back on "[PATCH v7 2/6] iommu/arm-smmu: Add >> pm_runtime/sleep ops", perhaps it would make more sense to just >> control the clocks independently of runtime PM? Then, runtime PM could >> be used for real power management, e.g. really powering the block up >> and down, for further power saving. > > > Unfortunately that ends up pretty much unmanageable, because there are > numerous different SMMU microarchitectures with fundamentally different > clock/power domain schemes (multiplied by individual SoC integration > possibilities). Since this is fundamentally a generic architectural driver, > adding explicit clock support would probably make the whole thing about 50% > clock code, with complicated decision trees around every hardware access > calculating which clocks are necessary for a given operation on a given > system. That maintainability aspect is why we've already nacked such a > fine-grained approach in the past. Hmm, I think we are talking about different things here. My suggestion would not add much more code to the driver than this patch does, calls to arm_smmu_enable_clocks() instead of pm_runtime_get_sync() and arm_smmu_disable_clocks() instead of pm_runtime_put(). The implementation of both functions would be a simple call to clk_bulk_ API (possibly even no need to put this into functions, just call directly). Best regards, Tomasz ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 105076] [CI] results file indicate incomplete run.log says pass
https://bugs.freedesktop.org/show_bug.cgi?id=105076 Marta Löfstedt changed: What|Removed |Added Whiteboard||ReadyForDev Component|DRM/Intel |IGT Assignee|intel-gfx-bugs@lists.freede |dri-devel@lists.freedesktop |sktop.org |.org QA Contact|intel-gfx-bugs@lists.freede | |sktop.org | --- Comment #1 from Marta Löfstedt --- Theory is that the individual jason file for the subtest wasn't written due to disc/mem malfunction. Piglit the reprots incomplete on the tests however testing goes on reporting pass to Jenkins over network... -- You are receiving this mail because: You are the assignee for the bug.___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 3/4] drm/tve200: Do not use deprecated drm_driver.{enable|disable)_vblank
On 02/13/2018 03:51 PM, Linus Walleij wrote: On Mon, Feb 12, 2018 at 9:52 AM, Oleksandr Andrushchenko wrote: From: Oleksandr Andrushchenko Do not use deprecated drm_driver.{enable|disable)_vblank callbacks, but use drm_simple_kms_helpe's pipe callbacks instead. Signed-off-by: Oleksandr Andrushchenko Cc: Linus Walleij The new way of doing these abstractions seem good, so if people agree on the general subject (other patches in the series I guess) fair enough, thank you Reviewed-by: Linus Walleij Yours, Linus Walleij ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 105076] [CI] results file indicate incomplete run.log say pass
https://bugs.freedesktop.org/show_bug.cgi?id=105076 Marta Löfstedt changed: What|Removed |Added Summary|[CI] results file indicate |[CI] results file indicate |incomplete run.log says |incomplete run.log say pass |pass| -- You are receiving this mail because: You are the assignee for the bug.___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v3 5/5] drm: adv7511: Add support for i2c_new_secondary_device
Hi Laurent, Thanks for the review, On 13/02/18 12:23, Laurent Pinchart wrote: > Hi Kieran, > > Thank you for the patch. > > On Tuesday, 13 February 2018 00:07:53 EET Kieran Bingham wrote: >> From: Kieran Bingham >> >> The ADV7511 has four 256-byte maps that can be accessed via the main I²C >> ports. Each map has it own I²C address and acts as a standard slave >> device on the I²C bus. >> >> Allow a device tree node to override the default addresses so that >> address conflicts with other devices on the same bus may be resolved at >> the board description level. >> >> Signed-off-by: Kieran Bingham >> --- >> v2: >> - Update missing edid-i2c address setting >> - Split out DT bindings >> - Rename and move the I2C default addresses to their own section >> >> drivers/gpu/drm/bridge/adv7511/adv7511.h | 6 >> drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 42 >> 2 files changed, 33 insertions(+), 15 deletions(-) >> >> diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h >> b/drivers/gpu/drm/bridge/adv7511/adv7511.h index d034b2cb5eee..04e6759ee45b >> 100644 >> --- a/drivers/gpu/drm/bridge/adv7511/adv7511.h >> +++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h >> @@ -93,6 +93,11 @@ >> #define ADV7511_REG_CHIP_ID_HIGH0xf5 >> #define ADV7511_REG_CHIP_ID_LOW 0xf6 >> >> +/* Hardware defined default addresses for i2c register maps */ > > s/i2c/I2C/ ? That's really because I had to find something :-) The I²C comes from JMH's original patch, but is much harder to grep for, so normalising to I2C throughout. > > Reviewed-by: Laurent Pinchart >> +#define ADV7511_CEC_I2C_ADDR_DEFAULT0x3c >> +#define ADV7511_EDID_I2C_ADDR_DEFAULT 0x3f >> +#define ADV7511_PACKET_I2C_ADDR_DEFAULT 0x38 >> + >> #define ADV7511_CSC_ENABLE BIT(7) >> #define ADV7511_CSC_UPDATE_MODE BIT(5) >> >> @@ -322,6 +327,7 @@ struct adv7511 { >> struct i2c_client *i2c_main; >> struct i2c_client *i2c_edid; >> struct i2c_client *i2c_cec; >> +struct i2c_client *i2c_packet; >> >> struct regmap *regmap; >> struct regmap *regmap_cec; >> diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c >> b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index >> efa29db5fc2b..5e61b928c9c0 100644 >> --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c >> +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c >> @@ -586,7 +586,7 @@ static int adv7511_get_modes(struct adv7511 *adv7511, >> /* Reading the EDID only works if the device is powered */ >> if (!adv7511->powered) { >> unsigned int edid_i2c_addr = >> -(adv7511->i2c_main->addr << 1) + 4; >> +(adv7511->i2c_edid->addr << 1); >> >> __adv7511_power_on(adv7511); >> >> @@ -969,10 +969,10 @@ static int adv7511_init_cec_regmap(struct adv7511 >> *adv) { >> int ret; >> >> -adv->i2c_cec = i2c_new_dummy(adv->i2c_main->adapter, >> - adv->i2c_main->addr - 1); >> +adv->i2c_cec = i2c_new_secondary_device(adv->i2c_main, "cec", >> +ADV7511_CEC_I2C_ADDR_DEFAULT); >> if (!adv->i2c_cec) >> -return -ENOMEM; >> +return -EINVAL; >> i2c_set_clientdata(adv->i2c_cec, adv); >> >> adv->regmap_cec = devm_regmap_init_i2c(adv->i2c_cec, >> @@ -1082,8 +1082,6 @@ static int adv7511_probe(struct i2c_client *i2c, const >> struct i2c_device_id *id) struct adv7511_link_config link_config; >> struct adv7511 *adv7511; >> struct device *dev = &i2c->dev; >> -unsigned int main_i2c_addr = i2c->addr << 1; >> -unsigned int edid_i2c_addr = main_i2c_addr + 4; >> unsigned int val; >> int ret; >> >> @@ -1153,24 +1151,35 @@ static int adv7511_probe(struct i2c_client *i2c, >> const struct i2c_device_id *id) if (ret) >> goto uninit_regulators; >> >> -regmap_write(adv7511->regmap, ADV7511_REG_EDID_I2C_ADDR, edid_i2c_addr); >> -regmap_write(adv7511->regmap, ADV7511_REG_PACKET_I2C_ADDR, >> - main_i2c_addr - 0xa); >> -regmap_write(adv7511->regmap, ADV7511_REG_CEC_I2C_ADDR, >> - main_i2c_addr - 2); >> - >> adv7511_packet_disable(adv7511, 0x); >> >> -adv7511->i2c_edid = i2c_new_dummy(i2c->adapter, edid_i2c_addr >> 1); >> +adv7511->i2c_edid = i2c_new_secondary_device(i2c, "edid", >> +ADV7511_EDID_I2C_ADDR_DEFAULT); >> if (!adv7511->i2c_edid) { >> -ret = -ENOMEM; >> +ret = -EINVAL; >> goto uninit_regulators; >> } >> >> +regmap_write(adv7511->regmap, ADV7511_REG_EDID_I2C_ADDR, >> + adv7511->i2c_edid->addr << 1); >> + >> ret = adv7511_init_cec_regmap(adv7511); >> if (ret) >> goto err_i2c_unregister_edid; >> >> +regmap_write(adv7511->regmap, ADV7511_REG_
Re: [PATCH v3 1/2] drm/virtio: Add window server support
On 02/12/2018 12:45 PM, Gerd Hoffmann wrote: Hi, (a) software rendering: client allocates shared memory buffer, renders into it, then passes a file handle for that shmem block together with some meta data (size, format, ...) to the wayland server. (b) gpu rendering: client opens a render node, allocates a buffer, asks the cpu to renders into it, exports the buffer as dma-buf (DRM_IOCTL_PRIME_HANDLE_TO_FD), passes this to the wayland server (again including meta data of course). Is that correct? Both are correct descriptions of typical behaviors. But it isn't spec'ed anywhere who has to do the buffer allocation. Well, according to Pekka's reply it is spec'ed that way, for the existing buffer types. So for server allocated buffers you need (a) a wayland protocol extension and (b) support for the extension in the clients. That's to say that if we cannot come up with a zero-copy solution for unmodified clients, we should at least support zero-copy for cooperative clients. "cooperative clients" == "client which has support for the wayland protocol extension", correct? Guess it could be that, but I was rather thinking of clients that would allocate the buffer for wl_shm_pool with DRM_VIRTGPU_RESOURCE_CREATE or equivalent. Then that buffer would be exported and the fd passed using the standard wl_shm protocol. 4. QEMU maps that buffer to the guest's address space (KVM_SET_USER_MEMORY_REGION), passes the guest PFN to the virtio driver That part is problematic. The host can't simply allocate something in the physical address space, because most physical address space management is done by the guest. All pci bars are mapped by the guest firmware for example (or by the guest OS in case of hotplug). How can KVM_SET_USER_MEMORY_REGION ever be safely used then? I would have expected that callers of that ioctl have enough knowledge to be able to choose a physical address that won't conflict with the guest's kernel. Depends on the kind of region. Guest RAM is allocated and mapped by qemu, guest firmware can query qemu about RAM mappings using a special interface, then create a e820 memory map for the guest os. PCI device bars are mapped according to the pci config space registers, which in turn are initialized by the guest firmware, so it is basically in the guests hand where they show up. I see that the ivshmem device in QEMU registers the memory region in BAR 2 of a PCI device instead. Would that be better in your opinion? Yes. Would it make sense for virtio-gpu to map buffers to the guest via PCI BARs? So we can use a single drm driver for both 2d and 3d. 4. QEMU pops data+buffers from the virtqueue, looks up shmem FD for each resource, sends data + FDs to the compositor with SCM_RIGHTS BTW: Is there a 1:1 relationship between buffers and shmem blocks? Or does the wayland protocol allow for offsets in buffer meta data, so you can place multiple buffers in a single shmem block? The latter: https://wayland.freedesktop.org/docs/html/apa.html#protocol-spec-wl_shm_pool Ah, good, that makes it alot easier. So, yes, using ivshmem would be one option. Tricky part here is the buffer management though. It's just a raw piece of memory. The guest proxy could mmap the pci bar and manage it. But then it is again either unmodified guest + copying the data, or modified client (which requests buffers from guest proxy) for zero-copy. Another idea would be extending stdvga. Basically qemu would have to use shmem as backing storage for vga memory instead of anonymous memory, so it would be very simliar to ivshmem on the host side. But on the guest side we have a drm driver for it (bochs-drm). So clients can allocate dumb drm buffers for software rendering, and the buffer would already be backed by a host shmem segment. Given that wayland already supports drm buffers for 3d rendering that could work without extending the wayland protocol. The client proxy would have to translate the drm buffer into an pci bar offset and pass it to the host side. The host proxy could register the pci bar as wl_shm_pool, then just pass through the offset to reference the individual buffers. Drawback of both approaches would be that software rendering and gpu rendering would use quite different code paths. Yeah, would be great if we could find a way to avoid that. We also need a solution for the keymap shmem block. I guess the keymap doesn't change all that often, so maybe it is easiest to just copy it over (host proxy -> guest proxy) instead of trying to map the host shmem into the guest? I think that should be fine for now. Something similar will have to happen for the clipboard, which currently uses pipes to exchange data. Thanks, Tomeu ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 99353] Kaveri 7400K shows random colored noise instead of GUI in X or Wayland
https://bugs.freedesktop.org/show_bug.cgi?id=99353 --- Comment #28 from Bong Cosca --- I find this message particularly interesting because it occurs several times in the dmesg log: [drm:radeon_crtc_handle_flip [radeon]] radeon_crtc->flip_status = 0 != RADEON_FLIP_SUBMITTED(2) -- You are receiving this mail because: You are the assignee for the bug.___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 0/5] Fix deadlock on runtime suspend in DRM drivers
On Tue, Feb 13, 2018 at 3:17 AM, Lukas Wunner wrote: > On Mon, Feb 12, 2018 at 01:58:32PM -0500, Alex Deucher wrote: >> On Mon, Feb 12, 2018 at 4:45 AM, Lukas Wunner wrote: >> > On Mon, Feb 12, 2018 at 09:03:26AM +, Mike Lothian wrote: >> >> On 12 February 2018 at 03:39, Lukas Wunner wrote: >> >> > On Mon, Feb 12, 2018 at 12:35:51AM +, Mike Lothian wrote: >> >> > > I've not been able to reproduce the original problem you're trying to >> >> > > solve on amdgpu thats with or without your patch set and the above >> >> > > "trigger" too >> > >> > Okay the reason you're not seeing deadlocks is because the output poll >> > worker is not enabled. And the output poll worker is not enabled >> > because your discrete GPU doesn't have any outputs: >> > >> > [0.265568] [drm:dc_create] *ERROR* DC: Number of connectors is zero! >> > >> > The outputs are only polled if there are connectors which have the >> > DRM_CONNECTOR_POLL_CONNECT or DRM_CONNECTOR_POLL_DISCONNECT flag set. >> > And that only ever seems to be the case for VGA and DVI. >> > >> > We know based on bugzilla reports that hybrid graphics laptops do exist >> > which poll outputs with radeon and nouveau. If there are no laptops >> > supported by amdgpu whose discrete GPU has polled connectors, then >> > patch [5/5] would be unnecessary. That is for Alex to decide. >> >> Most hybrid laptops don't have display connectors on the dGPU and we >> only use polling on analog connectors, so you are not likely to run >> into this on recent laptops. That said, I don't know if there is some >> OEM system out there with a VGA port on the dGPU in a hybrid laptop. >> I guess another option is to just disable polling on hybrid laptops. > > If we don't know for sure, applying patch [5/5] would seem to be the > safest approach. (Assuming it doesn't break anything else.) I don't have any objections. I see no reason to leave out the amdgpu changes. Alex ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 99353] Kaveri 7400K shows random colored noise instead of GUI in X or Wayland
https://bugs.freedesktop.org/show_bug.cgi?id=99353 --- Comment #29 from Michel Dänzer --- (In reply to Bong Cosca from comment #28) > [drm:radeon_crtc_handle_flip [radeon]] radeon_crtc->flip_status = 0 != > RADEON_FLIP_SUBMITTED(2) This is harmless and not related to the issue this report is about. -- You are receiving this mail because: You are the assignee for the bug.___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: Thinkpad X1 Carbon 3rd - Reducing the compressed framebuffer size
On Tue, Feb 13, 2018 at 02:38:42PM +0100, Pali Rohár wrote: > On Tuesday 13 February 2018 15:27:26 Ville Syrjälä wrote: > > On Tue, Feb 13, 2018 at 09:50:30AM +0100, Pali Rohár wrote: > > > On Tuesday 06 February 2018 16:21:43 Pali Rohár wrote: > > > > Hi! I'm periodically getting following message in dmesg on Lenovo > > > > Thinkpad X1 Carbon 3rd generation: > > > > > > > > [drm] Reducing the compressed framebuffer size. This may lead to less > > > > power savings than a non-reduced-size. Try to increase stolen memory > > > > size if available in BIOS. > > > > > > > > In BIOS I already set GPU size to 512M, but this did not help. Also > > > > update to last BIOS version did not help. > > > > > > > > So why this message is periodically print in dmesg? And what can I do > > > > with this problem? > > > > > > > > And why cannot Linux kernel allocate itself more memory for GPU (if BIOS > > > > can/could do that)? Is not 512MB for GPU enough? > > > > > > And here is output from lspci, which clearly says that 512MB is already > > > set for GPU: > > > > The PCI BAR size has nothing to do with the size of the stolen memory. > > The BAR just provides a window into the global GTT address space of the > > GPU. Stolen memory is a contiguous chunk of physical memory carved out > > by the BIOS. > > Ok, how could I detect how much memory was stolen? > > In dmesg I see following lines: > > [0.00] e820: BIOS-provided physical RAM map: > [0.00] BIOS-e820: [mem 0x-0x00057fff] usable > [0.00] BIOS-e820: [mem 0x00058000-0x00058fff] reserved > [0.00] BIOS-e820: [mem 0x00059000-0x0008bfff] usable > [0.00] BIOS-e820: [mem 0x0008c000-0x0009] reserved > [0.00] BIOS-e820: [mem 0x000e-0x000f] reserved > [0.00] BIOS-e820: [mem 0x0010-0xab908fff] usable > [0.00] BIOS-e820: [mem 0xab909000-0xabb08fff] type 20 > [0.00] BIOS-e820: [mem 0xabb09000-0xacbfefff] reserved > [0.00] BIOS-e820: [mem 0xacbff000-0xacd7efff] ACPI NVS > [0.00] BIOS-e820: [mem 0xacd7f000-0xacdfefff] ACPI > data > [0.00] BIOS-e820: [mem 0xacdff000-0xacdf] usable > [0.00] BIOS-e820: [mem 0xf80f8000-0xf80f8fff] reserved > [0.00] BIOS-e820: [mem 0xfed1c000-0xfed1] reserved > [0.00] BIOS-e820: [mem 0x0001-0x00024dff] usable > > [0.00] Reserving Intel graphics memory at > 0xae00-0xafff That's the one. Since you have a BDW the amount FBC can actually use will be 8MiB less than what's reported here. So looks like you should have 24MiB total, minus whatever else we end up allocating from stolen. Check /sys/kernel/debug/dri/0/i915_gem_stolen to see what's there. Most likely you'll have the fbdev framebuffer taking up a sizeable chunk. You could get some back by reducing fbdev depth to 16bpp, or even 8bpp, but I'm not convinced the fbdev gamma LUT stuff really works currently so you might end up with bogus colors in your vts with that. > > [0.00] Memory: 7972840K/8282704K available (6196K kernel code, 1159K > rwdata, 2848K rodata, 1408K init, 688K bss, 309864K reserved, 0K cma-reserved) > > > The BIOS may or may not provide a knob to change the size > > of the stolen memory. > > In BIOS Setup screen I have option to choose GPU memory and I set it to > max 512MB. So this is not the right option... > > And why cannot kernel use some continuous check of RAM itself? Because the hardware won't allow it. > > > > > > > $ lspci -v -s 00:02.0 > > > 00:02.0 VGA compatible controller: Intel Corporation HD Graphics 5500 > > > (rev 09) (prog-if 00 [VGA controller]) > > > Subsystem: Lenovo HD Graphics 5500 > > > Flags: bus master, fast devsel, latency 0, IRQ 46 > > > Memory at e000 (64-bit, non-prefetchable) [size=16M] > > > Memory at c000 (64-bit, prefetchable) [size=512M] > > > I/O ports at 3000 [size=64] > > > [virtual] Expansion ROM at 000c [disabled] [size=128K] > > > Capabilities: [90] MSI: Enable+ Count=1/1 Maskable- 64bit- > > > Capabilities: [d0] Power Management version 2 > > > Capabilities: [a4] PCI Advanced Features > > > Kernel driver in use: i915 > > > Kernel modules: i915 > > > > > > -- > > > Pali Rohár > > > pali.ro...@gmail.com > > > ___ > > > dri-devel mailing list > > > dri-devel@lists.freedesktop.org > > > https://lists.freedesktop.org/mailman/listinfo/dri-devel > > > > -- > Pali Rohár > pali.ro...@gmail.com -- Ville Syrjälä Intel OTC ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri
Re: [PATCH 0/5] Fix deadlock on runtime suspend in DRM drivers
On Tue, Feb 13, 2018 at 12:52:06PM +0100, Lukas Wunner wrote: > On Tue, Feb 13, 2018 at 10:55:06AM +, Liviu Dudau wrote: > > On Sun, Feb 11, 2018 at 10:38:28AM +0100, Lukas Wunner wrote: > > > DRM drivers poll connectors in 10 sec intervals. The poll worker is > > > stopped on ->runtime_suspend with cancel_delayed_work_sync(). However > > > the poll worker invokes the DRM drivers' ->detect callbacks, which call > > > pm_runtime_get_sync(). If the poll worker starts after runtime suspend > > > has begun, pm_runtime_get_sync() will wait for runtime suspend to finish > > > with the intention of runtime resuming the device afterwards. The result > > > is a circular wait between poll worker and autosuspend worker. > > > > I think I understand the problem you are trying to solve, but I'm > > struggling to understand where malidp makes any specific mistakes. First > > of all, malidp is only a display engine, so there is no GPU attached to > > it, but that is only a small clarification. Second, malidp doesn't use > > directly any of the callbacks that you are referring to, it uses the > > drm_cma_() API plus the generic drm_() call. So if there are any > > issues there (as they might well be) I think they would apply to a lot > > more drivers and the fix will involve more than just malidp, i915 and > > msm. > > I don't know if malidp makes any specific mistakes and didn't mean to > cast it in a negative light, sorry. I did not take what you've said as a negative thing, only wanted to understand how you came to your conclusions. > > So a lot of DRM drivers acquire a runtime PM ref in the connector ->detect > hook because they can't probe connectors while runtime suspended. > E.g. for a PCI device, probing might require mmio access, which isn't > possible outside of power state D0. There are no ->detect hooks declared > in drivers/gpu/drm/arm/, so it's unclear to me whether you're able to probe > during runtime suspend. That's because the drivers in drivers/gpu/drm/arm do not have connectors, they are only the CRTC part of the driver. Both hdlcd and mali-dp use the component framework to locate an encoder in device tree that will then provide the connectors. > > hdlcd_drv.c and malidp_drv.c both enable output polling. Output polling > is only necessary if you don't get HPD interrupts. That's right, hdlcd and mali-dp don't receive HPD interrupts because they don't have any. And because we don't know ahead of time which encoder/connector will be paired with the driver, we enable polling as a safe fallback. > > You're not disabling polling upon runtime suspend. Thus, if a runtime PM > ref is acquired during polling (such as in a ->detect hook), the GPU will > be runtime resumed every 10 secs. You may want to verify that's not the > case. If you decide that you do want to stop polling during runtime > suspend because it runtime resumes the GPU continuously, you'll need the > helper introduced in this series. So by cc'ing you I just wanted to keep > you in the loop about an issue that may potentially affect your driver. Again, we have no GPU linked to us and the polling during runtime suspend should be handled by the driver for the paired encoder, not by us. I understand the potential issue but I'm struggling to understand if it really applies to the drivers/gpu/drm/arm drivers other than in an abstract way. Best regards, Liviu > > Let me know if there are any questions. > > Thanks, > > Lukas -- | I would like to | | fix the world, | | but they're not | | giving me the | \ source code! / --- ¯\_(ツ)_/¯ ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: Thinkpad X1 Carbon 3rd - Reducing the compressed framebuffer size
On Tuesday 13 February 2018 17:36:54 Ville Syrjälä wrote: > On Tue, Feb 13, 2018 at 02:38:42PM +0100, Pali Rohár wrote: > > On Tuesday 13 February 2018 15:27:26 Ville Syrjälä wrote: > > > On Tue, Feb 13, 2018 at 09:50:30AM +0100, Pali Rohár wrote: > > > > On Tuesday 06 February 2018 16:21:43 Pali Rohár wrote: > > > > > Hi! I'm periodically getting following message in dmesg on Lenovo > > > > > Thinkpad X1 Carbon 3rd generation: > > > > > > > > > > [drm] Reducing the compressed framebuffer size. This may lead to less > > > > > power savings than a non-reduced-size. Try to increase stolen memory > > > > > size if available in BIOS. > > > > > > > > > > In BIOS I already set GPU size to 512M, but this did not help. Also > > > > > update to last BIOS version did not help. > > > > > > > > > > So why this message is periodically print in dmesg? And what can I do > > > > > with this problem? > > > > > > > > > > And why cannot Linux kernel allocate itself more memory for GPU (if > > > > > BIOS > > > > > can/could do that)? Is not 512MB for GPU enough? > > > > > > > > And here is output from lspci, which clearly says that 512MB is already > > > > set for GPU: > > > > > > The PCI BAR size has nothing to do with the size of the stolen memory. > > > The BAR just provides a window into the global GTT address space of the > > > GPU. Stolen memory is a contiguous chunk of physical memory carved out > > > by the BIOS. > > > > Ok, how could I detect how much memory was stolen? > > > > In dmesg I see following lines: > > > > [0.00] e820: BIOS-provided physical RAM map: > > [0.00] BIOS-e820: [mem 0x-0x00057fff] usable > > [0.00] BIOS-e820: [mem 0x00058000-0x00058fff] > > reserved > > [0.00] BIOS-e820: [mem 0x00059000-0x0008bfff] usable > > [0.00] BIOS-e820: [mem 0x0008c000-0x0009] > > reserved > > [0.00] BIOS-e820: [mem 0x000e-0x000f] > > reserved > > [0.00] BIOS-e820: [mem 0x0010-0xab908fff] usable > > [0.00] BIOS-e820: [mem 0xab909000-0xabb08fff] type > > 20 > > [0.00] BIOS-e820: [mem 0xabb09000-0xacbfefff] > > reserved > > [0.00] BIOS-e820: [mem 0xacbff000-0xacd7efff] ACPI > > NVS > > [0.00] BIOS-e820: [mem 0xacd7f000-0xacdfefff] ACPI > > data > > [0.00] BIOS-e820: [mem 0xacdff000-0xacdf] usable > > [0.00] BIOS-e820: [mem 0xf80f8000-0xf80f8fff] > > reserved > > [0.00] BIOS-e820: [mem 0xfed1c000-0xfed1] > > reserved > > [0.00] BIOS-e820: [mem 0x0001-0x00024dff] usable > > > > [0.00] Reserving Intel graphics memory at > > 0xae00-0xafff > > That's the one. Since you have a BDW the amount FBC can actually use > will be 8MiB less than what's reported here. So looks like you should > have 24MiB total, minus whatever else we end up allocating from stolen. > > Check /sys/kernel/debug/dri/0/i915_gem_stolen to see what's there. Most $ cat /sys/kernel/debug/dri/0/i915_gem_stolen Stolen: 8b55bf17e080:g16KiB 40 40 [ 0 0 0 0 ] 0 LLC dirty (pinned x 1) (ggtt offset: 00083000, size: 4000, type: 0) (stolen: 1000) 8b55c2693040:g16KiB 40 40 [ 0 0 0 0 ] 0 LLC dirty (pinned x 1) (ggtt offset: 02b9f000, size: 4000, type: 0) (stolen: 5000) 8b55bf9a7300:g16KiB 40 40 [ 0 0 0 0 ] 0 LLC dirty (pinned x 0) (ggtt offset: 0f6b4000, size: 4000, type: 0) (stolen: 9000) 8b55a6161040:g16KiB 40 40 [ 0 0 0 0 ] 0 LLC dirty (pinned x 0) (ggtt offset: 0937f000, size: 4000, type: 0) (stolen: d000) 8b5563e0dac0:g16KiB 40 40 [ 0 0 0 0 ] 0 LLC dirty (pinned x 0) (ggtt offset: 0f714000, size: 4000, type: 0) (stolen: 00019000) 8b55bf17e800:g 4KiB 41 00 [ 0 0 0 0 ] 0 LLC (pinned x 1) (ggtt offset: e000, size: 1000, type: 0) (stolen: 0012c000) 8b55bf02d540:g16KiB 40 40 [ 0 0 0 0 ] 0 LLC dirty (pinned x 1) (ggtt offset: 00141000, size: 4000, type: 0) (stolen: 0012d000) 8b55c2989340:g16KiB 40 40 [ 0 0 0 0 ] 0 LLC dirty (pinned x 1) (ggtt offset: 00148000, size: 4000, type: 0) (stolen: 00131000) 8b55c29890c0:g16KiB 40 40 [ 0 0 0 0 ] 0 LLC dirty (pinned x 1) (ggtt offset: 0014f000, size: 4000, type: 0) (stolen: 00135000) 8b55c2989840:g16KiB 40 40 [ 0 0 0 0 ] 0 LLC dirty (pinned x 1) (ggtt offset: 00156000, size: 4000, type: 0) (stolen: 00139000) 8b55bf02da40: p g 14400KiB 77 00 [ 0 0 0 0 ] 0 uncached dirty (name: 1) (pinned x 1) (display) (ggtt offset: 0015a000, size: 00e1, type: 0) (stolen: 0013d000) (p mappable) 8b556dfba780:g16KiB 40 40 [
Re: Thinkpad X1 Carbon 3rd - Reducing the compressed framebuffer size
On Tue, Feb 13, 2018 at 05:04:37PM +0100, Pali Rohár wrote: > On Tuesday 13 February 2018 17:36:54 Ville Syrjälä wrote: > > On Tue, Feb 13, 2018 at 02:38:42PM +0100, Pali Rohár wrote: > > > On Tuesday 13 February 2018 15:27:26 Ville Syrjälä wrote: > > > > On Tue, Feb 13, 2018 at 09:50:30AM +0100, Pali Rohár wrote: > > > > > On Tuesday 06 February 2018 16:21:43 Pali Rohár wrote: > > > > > > Hi! I'm periodically getting following message in dmesg on Lenovo > > > > > > Thinkpad X1 Carbon 3rd generation: > > > > > > > > > > > > [drm] Reducing the compressed framebuffer size. This may lead to > > > > > > less power savings than a non-reduced-size. Try to increase stolen > > > > > > memory size if available in BIOS. > > > > > > > > > > > > In BIOS I already set GPU size to 512M, but this did not help. Also > > > > > > update to last BIOS version did not help. > > > > > > > > > > > > So why this message is periodically print in dmesg? And what can I > > > > > > do > > > > > > with this problem? > > > > > > > > > > > > And why cannot Linux kernel allocate itself more memory for GPU (if > > > > > > BIOS > > > > > > can/could do that)? Is not 512MB for GPU enough? > > > > > > > > > > And here is output from lspci, which clearly says that 512MB is > > > > > already > > > > > set for GPU: > > > > > > > > The PCI BAR size has nothing to do with the size of the stolen memory. > > > > The BAR just provides a window into the global GTT address space of the > > > > GPU. Stolen memory is a contiguous chunk of physical memory carved out > > > > by the BIOS. > > > > > > Ok, how could I detect how much memory was stolen? > > > > > > In dmesg I see following lines: > > > > > > [0.00] e820: BIOS-provided physical RAM map: > > > [0.00] BIOS-e820: [mem 0x-0x00057fff] > > > usable > > > [0.00] BIOS-e820: [mem 0x00058000-0x00058fff] > > > reserved > > > [0.00] BIOS-e820: [mem 0x00059000-0x0008bfff] > > > usable > > > [0.00] BIOS-e820: [mem 0x0008c000-0x0009] > > > reserved > > > [0.00] BIOS-e820: [mem 0x000e-0x000f] > > > reserved > > > [0.00] BIOS-e820: [mem 0x0010-0xab908fff] > > > usable > > > [0.00] BIOS-e820: [mem 0xab909000-0xabb08fff] > > > type 20 > > > [0.00] BIOS-e820: [mem 0xabb09000-0xacbfefff] > > > reserved > > > [0.00] BIOS-e820: [mem 0xacbff000-0xacd7efff] > > > ACPI NVS > > > [0.00] BIOS-e820: [mem 0xacd7f000-0xacdfefff] > > > ACPI data > > > [0.00] BIOS-e820: [mem 0xacdff000-0xacdf] > > > usable > > > [0.00] BIOS-e820: [mem 0xf80f8000-0xf80f8fff] > > > reserved > > > [0.00] BIOS-e820: [mem 0xfed1c000-0xfed1] > > > reserved > > > [0.00] BIOS-e820: [mem 0x0001-0x00024dff] > > > usable > > > > > > [0.00] Reserving Intel graphics memory at > > > 0xae00-0xafff > > > > That's the one. Since you have a BDW the amount FBC can actually use > > will be 8MiB less than what's reported here. So looks like you should > > have 24MiB total, minus whatever else we end up allocating from stolen. > > > > Check /sys/kernel/debug/dri/0/i915_gem_stolen to see what's there. Most > > $ cat /sys/kernel/debug/dri/0/i915_gem_stolen > Stolen: >8b55bf17e080:g16KiB 40 40 [ 0 0 0 0 ] 0 LLC dirty (pinned > x 1) (ggtt offset: 00083000, size: 4000, type: 0) (stolen: 1000) >8b55c2693040:g16KiB 40 40 [ 0 0 0 0 ] 0 LLC dirty (pinned > x 1) (ggtt offset: 02b9f000, size: 4000, type: 0) (stolen: 5000) >8b55bf9a7300:g16KiB 40 40 [ 0 0 0 0 ] 0 LLC dirty (pinned > x 0) (ggtt offset: 0f6b4000, size: 4000, type: 0) (stolen: 9000) >8b55a6161040:g16KiB 40 40 [ 0 0 0 0 ] 0 LLC dirty (pinned > x 0) (ggtt offset: 0937f000, size: 4000, type: 0) (stolen: d000) >8b5563e0dac0:g16KiB 40 40 [ 0 0 0 0 ] 0 LLC dirty (pinned > x 0) (ggtt offset: 0f714000, size: 4000, type: 0) (stolen: 00019000) >8b55bf17e800:g 4KiB 41 00 [ 0 0 0 0 ] 0 LLC (pinned x 1) > (ggtt offset: e000, size: 1000, type: 0) (stolen: 0012c000) >8b55bf02d540:g16KiB 40 40 [ 0 0 0 0 ] 0 LLC dirty (pinned > x 1) (ggtt offset: 00141000, size: 4000, type: 0) (stolen: 0012d000) >8b55c2989340:g16KiB 40 40 [ 0 0 0 0 ] 0 LLC dirty (pinned > x 1) (ggtt offset: 00148000, size: 4000, type: 0) (stolen: 00131000) >8b55c29890c0:g16KiB 40 40 [ 0 0 0 0 ] 0 LLC dirty (pinned > x 1) (ggtt offset: 0014f000, size: 4000, type: 0) (stolen: 00135000) >8b55c2989840:g16KiB 40 40 [ 0 0 0 0 ] 0 LLC dirty (pinned > x 1) (ggtt
[Bug 105018] Kernel panic when waking up after screen goes blank.
https://bugs.freedesktop.org/show_bug.cgi?id=105018 --- Comment #8 from Harry Wentland --- Created attachment 137322 --> https://bugs.freedesktop.org/attachment.cgi?id=137322&action=edit Patch 1 Use crtc enable/disable_vblank hooks -- You are receiving this mail because: You are the assignee for the bug.___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 105018] Kernel panic when waking up after screen goes blank.
https://bugs.freedesktop.org/show_bug.cgi?id=105018 --- Comment #9 from Harry Wentland --- Created attachment 137323 --> https://bugs.freedesktop.org/attachment.cgi?id=137323&action=edit Patch 2 Return success when enabling interrupt -- You are receiving this mail because: You are the assignee for the bug.___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 105018] Kernel panic when waking up after screen goes blank.
https://bugs.freedesktop.org/show_bug.cgi?id=105018 --- Comment #10 from Harry Wentland --- Created attachment 137324 --> https://bugs.freedesktop.org/attachment.cgi?id=137324&action=edit Patch 3 Clean up formatting in irq_service_dce110.c -- You are receiving this mail because: You are the assignee for the bug.___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 105018] Kernel panic when waking up after screen goes blank.
https://bugs.freedesktop.org/show_bug.cgi?id=105018 --- Comment #11 from Harry Wentland --- Created attachment 137325 --> https://bugs.freedesktop.org/attachment.cgi?id=137325&action=edit Patch 4 Don't blow up if TG is NULL in dce110_vblank_set -- You are receiving this mail because: You are the assignee for the bug.___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[Bug 105018] Kernel panic when waking up after screen goes blank.
https://bugs.freedesktop.org/show_bug.cgi?id=105018 --- Comment #12 from Harry Wentland --- Are you able to rebuild the kernel with the attached patches and see if that fixes things? -- You are receiving this mail because: You are the assignee for the bug.___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v3 5/8] drm: Handle aspect ratio info in atomic and legacy modeset paths
Hi Ville, Thanks yet again to look into this. I am still skeptical about rejecting the mode, if aspect ratio cap is not set. Perhaps I am not aware with the userspace expectations. Please find my response inline: On 2/13/2018 6:48 PM, Ville Syrjälä wrote: On Tue, Feb 13, 2018 at 10:21:15AM +0530, Nautiyal, Ankit K wrote: Hi Ville, As per our last discussion, following points were discussed: 1. To suppress the aspect-ratio info from getblob ioctl to a user that does not support it: i. A new flag must be added to drm_blob_property to mark if the blob has mode data. ii. This flag must be set when the user tries do an atomic modeset. iii. In the getblob ioctl, based on the above flag, it can be determined that if the blob has mode data, and the aspect ratio info can be suppressed in getblob ioctl, if user does not support it. 2. Instead of adding aspect ratio capabilities in drm_atomic_state, pass on the file_priv which already has the required information to the function drm_mode_convert_umode. It will require addition of an new argument file_priv to several functions, but that is right thing to do, as file_priv is the correct structure for the capability information. 3. Changing the usermode aspect ratio flag bits, without change in the picture_aspect_ratio would not matter, and does not need to be handled in this patch. I just have one query here. We have agreed to modify drm_mode_convert_umode, to filter out the aspect-ratio info if user has not set aspect-ratio capability, but do we need a similar change the drm_mode_convert_to_umode? I think you maybe had those backwards. drm_mode_convert_umode(), or more likely its relevant callers setcrtc and setproperty, need to reject the mode if the client cap is not set. I guess, rejecting the mode, altogether can break the existing user-spaces. Current user-spaces, oblivious of the aspect-ratio capability in drm, will not set the aspect-ratio capability. Some of them, might have some garbage value in the aspect ratio bits of the user mode. If we reject such modes, the user-spaces that were earlier working will break. (But if we are sure, that the aspect ratio flag bits will all be reset, then it makes sense to reject the mode.) Instead of rejecting such modes, if we just only ignore the aspect ratio bits in such cases, and carry on with the modeset for the given user mode, the behaviour would be intact, just as prior to the aspect ratio changes. drm_mode_convert_to_umode(), or rather its callers getblob and getcrtc, need to filter out the flags. Yes right. I'll be filtering out the flags in the getblob and getcrtc functions. Thanks & Regards, Ankit If we do, I am not sure if it would be possible to have the file_priv to /drm_atomic_set_mode_for_crtc/, which calls drm_mode_convert_to_umode. The function /drm_atomic_set_mode_for_crtc/ is used to set mode, originating by kernel, and make a blob from the kernel mode, which it saves in crtc_state. This function /: drm_atomic_set_mode_for_crtc, /is called by several helper functions and driver functions, and passing file_priv from all these functions does not seem to be plausible. I don't think we need to plumb it quite that deep. Doing the check in drm_atomic_crtc_set_property() should be sufficient. Any suggestions on how to handle this situation? Regards, Ankit On 2/8/2018 9:59 AM, Nautiyal, Ankit K wrote: Hi Ville, I still have some queries regarding the handling of aspect ratio flags in getblob ioctl. Please find below my responses inline. On 2/1/2018 6:24 PM, Ville Syrjälä wrote: On Thu, Feb 01, 2018 at 04:35:22PM +0530, Nautiyal, Ankit K wrote: Hi Ville, Appreciate your time and the suggestions. Please find my response inline: On 1/31/2018 6:39 PM, Ville Syrjälä wrote: On Wed, Jan 31, 2018 at 12:04:52PM +0530, Nautiyal, Ankit K wrote: On 1/30/2018 12:23 AM, Ville Syrjälä wrote: On Fri, Jan 12, 2018 at 11:51:33AM +0530, Nautiyal, Ankit K wrote: From: Ankit Nautiyal If the user mode does not support aspect-ratio, and requests for a modeset, then the flag bits representing aspect ratio in the given user-mode must be rejected. Similarly, while preparing a user-mode from kernel mode, the aspect-ratio info must not be given, if aspect-ratio is not supported by the user. This patch: 1. adds a new bit field aspect_ratio_allowed in drm_atomic_state, which is set only if the aspect-ratio is supported by the user. 2. discards the aspect-ratio info from the user mode while preparing kernel mode structure, during modeset, if the user does not support aspect ratio. 3. avoids setting the aspect-ratio info in user-mode, while converting user-mode from the kernel-mode. Signed-off-by: Ankit Nautiyal V3: Addressed review comments from Ville: -Do not corrupt the current crtc state by updating aspect ratio on the fly. --- drivers/gpu/drm/drm_atomic.c | 61 +--- drivers/gpu/drm/drm_crtc.c
Re: [RFC][PATCH v3] drm_hwcomposer: Add platformhisi buffer importer for hikey and hikey960
Hi John, Some comments bellow, On Thu, Feb 08, 2018 at 04:40:05PM -0800, John Stultz wrote: > This allows for importing buffers allocated from the > hikey and hikey960 gralloc implelementations. > > Feedback or comments would be greatly appreciated! > > Cc: Marissa Wall > Cc: Sean Paul > Cc: Dmitry Shmidt > Cc: Robert Foss > Cc: Matt Szczesiak > Cc: Liviu Dudau > Cc: David Hanna > Cc: Rob Herring > Change-Id: I81abdd4d1dc7d9f2ef31078c91679b532d3262fd > Signed-off-by: John Stultz > --- > The full patchset I'm testing with can be found here: > https://github.com/johnstultz-work/drm_hwcomposer/commits/drm_hwc > > v2: > * Make platformhisi and the generic importer exclusive in the build > * Fixup vendor check > v3: > * Unify format conversions > * Subclass the platformdrmgeneric importer implementation to reduce > code duplication > * Rework to avoid board specific logic (tweak gralloc to be consistent > between the two) > --- > Android.mk | 13 + > platformdrmgeneric.h | 2 +- > platformhisi.cpp | 132 > +++ > platformhisi.h | 48 +++ > 4 files changed, 194 insertions(+), 1 deletion(-) > create mode 100644 platformhisi.cpp > create mode 100644 platformhisi.h > > diff --git a/Android.mk b/Android.mk > index ee5b8bf..f37e4c3 100644 > --- a/Android.mk > +++ b/Android.mk > @@ -74,7 +74,20 @@ LOCAL_CPPFLAGS += \ > -DHWC2_USE_CPP11 \ > -DHWC2_INCLUDE_STRINGIFICATION > > + > +ifeq ($(TARGET_PRODUCT),hikey960) > +LOCAL_CPPFLAGS += -DUSE_HISI_IMPORTER > +LOCAL_SRC_FILES += platformhisi.cpp > +LOCAL_C_INCLUDES += device/linaro/hikey/gralloc960/ > +else > +ifeq ($(TARGET_PRODUCT),hikey) > +LOCAL_CPPFLAGS += -DUSE_HISI_IMPORTER > +LOCAL_SRC_FILES += platformhisi.cpp > +LOCAL_C_INCLUDES += device/linaro/hikey/gralloc/ > +else > LOCAL_CPPFLAGS += -DUSE_DRM_GENERIC_IMPORTER > +endif > +endif > > LOCAL_MODULE := hwcomposer.drm > LOCAL_MODULE_TAGS := optional > diff --git a/platformdrmgeneric.h b/platformdrmgeneric.h > index 8376580..fbe059b 100644 > --- a/platformdrmgeneric.h > +++ b/platformdrmgeneric.h > @@ -35,8 +35,8 @@ class DrmGenericImporter : public Importer { >int ImportBuffer(buffer_handle_t handle, hwc_drm_bo_t *bo) override; >int ReleaseBuffer(hwc_drm_bo_t *bo) override; > > - private: >uint32_t ConvertHalFormatToDrm(uint32_t hal_format); > + private: > >DrmResources *drm_; > > diff --git a/platformhisi.cpp b/platformhisi.cpp > new file mode 100644 > index 000..5f17c20 > --- /dev/null > +++ b/platformhisi.cpp > @@ -0,0 +1,132 @@ > +/* > + * Copyright (C) 2015 The Android Open Source Project > + * > + * Licensed under the Apache License, Version 2.0 (the "License"); > + * you may not use this file except in compliance with the License. > + * You may obtain a copy of the License at > + * > + * http://www.apache.org/licenses/LICENSE-2.0 > + * > + * Unless required by applicable law or agreed to in writing, software > + * distributed under the License is distributed on an "AS IS" BASIS, > + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. > + * See the License for the specific language governing permissions and > + * limitations under the License. > + */ > + > +#define LOG_TAG "hwc-platform-hisi" > + > +#include "drmresources.h" > +#include "platform.h" > +#include "platformhisi.h" > + > + > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include > +#include "gralloc_priv.h" > + > + > +namespace android { > + > +#ifdef USE_HISI_IMPORTER Isn't this pointless this file seems to be added only of if USE_HISI_IMPORTER. > +// static > +Importer *Importer::CreateInstance(DrmResources *drm) { > + HisiImporter *importer = new HisiImporter(drm); > + if (!importer) > +return NULL; > + > + int ret = importer->Init(); > + if (ret) { > +ALOGE("Failed to initialize the hisi importer %d", ret); > +delete importer; > +return NULL; > + } > + return importer; > +} > +#endif > + > +HisiImporter::HisiImporter(DrmResources *drm) : DrmGenericImporter(drm), > drm_(drm) { > +} > + > +HisiImporter::~HisiImporter() { > +} > + > +int HisiImporter::Init() { > + int ret = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, > + (const hw_module_t **)&gralloc_); > + if (ret) { > +ALOGE("Failed to open gralloc module %d", ret); > +return ret; > + } > + > + if (strcasecmp(gralloc_->common.author, "ARM Ltd.")) > +ALOGW("Using non-ARM gralloc module: %s/%s\n", gralloc_->common.name, > + gralloc_->common.author); > + > + return 0; > +} > + > +EGLImageKHR HisiImporter::ImportImage(EGLDisplay egl_display, > buffer_handle_t handle) { If the scope is reusing, I think you could go further and create an overload/helper ImportImage(EGLDisplay, width, height, fd, bystride), that's called for both HisiImport and DrmGenericImporter. > + private_handle_t const *hnd = reinte
Re: [PATCH v7 6/6] drm/msm: iommu: Replace runtime calls with runtime suppliers
On Tue, Feb 13, 2018 at 06:10:38PM +0900, Tomasz Figa wrote: > Hi Vivek, > > Thanks for the patch. Please see my comments inline. > > On Wed, Feb 7, 2018 at 7:31 PM, Vivek Gautam > wrote: > > While handling the concerned iommu, there should not be a > > need to power control the drm devices from iommu interface. > > If these drm devices need to be powered around this time, > > the respective drivers should take care of this. > > > > Replace the pm_runtime_get/put_sync() with > > pm_runtime_get/put_suppliers() calls, to power-up > > the connected iommu through the device link interface. > > In case the device link is not setup these get/put_suppliers() > > calls will be a no-op, and the iommu driver should take care of > > powering on its devices accordingly. > > > > Signed-off-by: Vivek Gautam > > --- > > drivers/gpu/drm/msm/msm_iommu.c | 16 > > 1 file changed, 8 insertions(+), 8 deletions(-) > > > > diff --git a/drivers/gpu/drm/msm/msm_iommu.c > > b/drivers/gpu/drm/msm/msm_iommu.c > > index b23d33622f37..1ab629bbee69 100644 > > --- a/drivers/gpu/drm/msm/msm_iommu.c > > +++ b/drivers/gpu/drm/msm/msm_iommu.c > > @@ -40,9 +40,9 @@ static int msm_iommu_attach(struct msm_mmu *mmu, const > > char * const *names, > > struct msm_iommu *iommu = to_msm_iommu(mmu); > > int ret; > > > > - pm_runtime_get_sync(mmu->dev); > > + pm_runtime_get_suppliers(mmu->dev); > > ret = iommu_attach_device(iommu->domain, mmu->dev); > > - pm_runtime_put_sync(mmu->dev); > > + pm_runtime_put_suppliers(mmu->dev); > > For me, it looks like a wrong place to handle runtime PM of IOMMU > here. iommu_attach_device() calls into IOMMU driver's attach_device() > callback and that's where necessary runtime PM gets should happen, if > any. In other words, driver A (MSM DRM driver) shouldn't be dealing > with power state of device controlled by driver B (ARM SMMU). This whole thing is confused by the fact that on MSM the GPU and the GPU IOMMU share some of the same clocks and power rail so turning on the GPU also turned on the IOMMU register banks by extension. But if we put that aside the question is who should be responsible for controlling the power in this relationship and there are several good reasons to leave it up to the client device. The most important reason is when we move to the per-instance model where the GPU self-programmings the SMMU registers. In that case, the driver will need to make sure that the SMMU is powered up before submitting the command and then removing the power vote when the commands are done to save energy. Additionally, there might be legitimate reasons in the driver to batch operations - you may wish to attach the device and then map several global buffers immediately - having driver side control prevents several unneeded power transitions. Perhaps the right answer is to do both - allow for the driver to enable the supplier but also do the right power operations at the appropriately places in the IOMMU driver. > This is also important for the reasons I stated in my comments to > "[PATCH v7 1/6] base: power: runtime: Export > pm_runtime_get/put_suppliers". Quoting for everyone's convenience: > > >> There are however cases in which the consumer wants to power-on > >> the supplier, but not itself. > >> E.g., A Graphics or multimedia driver wants to power-on the SMMU > >> to unmap a buffer and finish the TLB operations without powering > >> on itself. > > > >This sounds strange to me. If the SMMU is powered down, wouldn't the > >TLB lose its contents as well (and so no flushing needed)? > > > >Other than that, what kind of hardware operations would be needed > >besides just updating the page tables from the CPU? > > > In other words, the SMMU driver can deal with hardware state based on > return value of pm_runtime_get_sync() or pm_runtime_get_if_in_use() > and decide whether some operations are necessary or not, e.g. > - a state restore is necessary if the domain was powered off, but we > are bringing the master on, > - a flush may not be required when (un)mapping with the domain powered off, > - etc. I agree that there is probably some advanced logic that we can do to conclusively figure out the state of the hardware and improve the behavior. I would love to see the SMMU driver get smarter but for the moment we can't trust it and so we need to force the behavior from the GPU driver. The current code works for a5x and earlier but on sdm845 we can (no longer) treat the GPU and the SMMU as the same device for power purposes so we need this code. If at some point in the future we can start to selectively remove the supplier calls I wouldn't mind one bit. Jordan -- The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v3 5/8] drm: Handle aspect ratio info in atomic and legacy modeset paths
On Tue, Feb 13, 2018 at 09:53:53PM +0530, Nautiyal, Ankit K wrote: > Hi Ville, > > Thanks yet again to look into this. > > I am still skeptical about rejecting the mode, if aspect ratio cap is > not set. > Perhaps I am not aware with the userspace expectations. > > Please find my response inline: > > On 2/13/2018 6:48 PM, Ville Syrjälä wrote: > > On Tue, Feb 13, 2018 at 10:21:15AM +0530, Nautiyal, Ankit K wrote: > >> Hi Ville, > >> > >> As per our last discussion, following points were discussed: > >> > >> 1. To suppress the aspect-ratio info from getblob ioctl to a user that > >> does not support it: > >> > >> i. A new flag must be added to drm_blob_property to mark if the > >> blob has mode data. > >> > >> ii. This flag must be set when the user tries do an atomic modeset. > >> > >> iii. In the getblob ioctl, based on the above flag, it can be > >> determined that if the blob > >> > >> has mode data, and the aspect ratio info can be suppressed in > >> getblob ioctl, if user does not support it. > >> > >> 2. Instead of adding aspect ratio capabilities in drm_atomic_state, pass > >> on the file_priv which already has > >> > >> the required information to the function drm_mode_convert_umode. > >> > >> It will require addition of an new argument file_priv to several > >> functions, but that is right thing to do, > >> > >> as file_priv is the correct structure for the capability information. > >> > >> 3. Changing the usermode aspect ratio flag bits, without change in the > >> picture_aspect_ratio would not matter, and does not need to be handled > >> in this patch. > >> > >> > >> I just have one query here. We have agreed to modify > >> drm_mode_convert_umode, to filter out the aspect-ratio > >> > >> info if user has not set aspect-ratio capability, but do we need a > >> similar change the drm_mode_convert_to_umode? > > I think you maybe had those backwards. > > > > drm_mode_convert_umode(), or more likely its relevant callers setcrtc > > and setproperty, need to reject the mode if the client cap is not set. > I guess, rejecting the mode, altogether can break the existing user-spaces. > Current user-spaces, oblivious of the aspect-ratio capability in drm, > will not set the aspect-ratio capability. > Some of them, might have some garbage value in the aspect ratio bits of > the user mode. If we reject such > modes, the user-spaces that were earlier working will break. > (But if we are sure, that the aspect ratio flag bits will all be reset, > then it makes sense to reject the mode.) We already reject all unspecified flags. > > Instead of rejecting such modes, if we just only ignore the aspect ratio > bits in such cases, and carry on with the > modeset for the given user mode, the behaviour would be intact, just as > prior to the aspect ratio changes. > > > drm_mode_convert_to_umode(), or rather its callers getblob and getcrtc, > > need to filter out the flags. > > Yes right. I'll be filtering out the flags in the getblob and getcrtc > functions. > > Thanks & Regards, > Ankit > >> If we do, I am not sure if it would be possible to have the file_priv to > >> /drm_atomic_set_mode_for_crtc/, which calls > >> > >> drm_mode_convert_to_umode. The function /drm_atomic_set_mode_for_crtc/ > >> is used to set mode, originating by kernel, > >> > >> and make a blob from the kernel mode, which it saves in crtc_state. > >> > >> This function /: drm_atomic_set_mode_for_crtc, /is called by several > >> helper functions and driver functions, and passing > >> > >> file_priv from all these functions does not seem to be plausible. > > I don't think we need to plumb it quite that deep. Doing the > > check in drm_atomic_crtc_set_property() should be sufficient. > > > >> Any suggestions on how to handle this situation? > >> > >> > >> Regards, > >> > >> Ankit > >> > >> > >> On 2/8/2018 9:59 AM, Nautiyal, Ankit K wrote: > >>> Hi Ville, > >>> > >>> I still have some queries regarding the handling of aspect ratio flags > >>> in getblob ioctl. > >>> > >>> Please find below my responses inline. > >>> > >>> > >>> On 2/1/2018 6:24 PM, Ville Syrjälä wrote: > On Thu, Feb 01, 2018 at 04:35:22PM +0530, Nautiyal, Ankit K wrote: > > Hi Ville, > > > > Appreciate your time and the suggestions. > > Please find my response inline: > > > > On 1/31/2018 6:39 PM, Ville Syrjälä wrote: > >> On Wed, Jan 31, 2018 at 12:04:52PM +0530, Nautiyal, Ankit K wrote: > >>> On 1/30/2018 12:23 AM, Ville Syrjälä wrote: > On Fri, Jan 12, 2018 at 11:51:33AM +0530, Nautiyal, Ankit K wrote: > > From: Ankit Nautiyal > > > > If the user mode does not support aspect-ratio, and requests for > > a modeset, then the flag bits representing aspect ratio in the > > given user-mode must be rejected. > > Similarly, while preparing a user-mode from kernel mode, the > > aspect-ratio info must not be given, if aspect-ratio is not > > sup
Re: Thinkpad X1 Carbon 3rd - Reducing the compressed framebuffer size
On Tuesday 13 February 2018 18:12:21 Ville Syrjälä wrote: > On Tue, Feb 13, 2018 at 05:04:37PM +0100, Pali Rohár wrote: > > $ cat /sys/kernel/debug/dri/0/i915_gem_stolen > > Stolen: > >8b55bf17e080:g16KiB 40 40 [ 0 0 0 0 ] 0 LLC dirty > > (pinned x 1) (ggtt offset: 00083000, size: 4000, type: 0) (stolen: > > 1000) > >8b55c2693040:g16KiB 40 40 [ 0 0 0 0 ] 0 LLC dirty > > (pinned x 1) (ggtt offset: 02b9f000, size: 4000, type: 0) (stolen: > > 5000) > >8b55bf9a7300:g16KiB 40 40 [ 0 0 0 0 ] 0 LLC dirty > > (pinned x 0) (ggtt offset: 0f6b4000, size: 4000, type: 0) (stolen: > > 9000) > >8b55a6161040:g16KiB 40 40 [ 0 0 0 0 ] 0 LLC dirty > > (pinned x 0) (ggtt offset: 0937f000, size: 4000, type: 0) (stolen: > > d000) > >8b5563e0dac0:g16KiB 40 40 [ 0 0 0 0 ] 0 LLC dirty > > (pinned x 0) (ggtt offset: 0f714000, size: 4000, type: 0) (stolen: > > 00019000) > >8b55bf17e800:g 4KiB 41 00 [ 0 0 0 0 ] 0 LLC (pinned x > > 1) (ggtt offset: e000, size: 1000, type: 0) (stolen: 0012c000) > >8b55bf02d540:g16KiB 40 40 [ 0 0 0 0 ] 0 LLC dirty > > (pinned x 1) (ggtt offset: 00141000, size: 4000, type: 0) (stolen: > > 0012d000) > >8b55c2989340:g16KiB 40 40 [ 0 0 0 0 ] 0 LLC dirty > > (pinned x 1) (ggtt offset: 00148000, size: 4000, type: 0) (stolen: > > 00131000) > >8b55c29890c0:g16KiB 40 40 [ 0 0 0 0 ] 0 LLC dirty > > (pinned x 1) (ggtt offset: 0014f000, size: 4000, type: 0) (stolen: > > 00135000) > >8b55c2989840:g16KiB 40 40 [ 0 0 0 0 ] 0 LLC dirty > > (pinned x 1) (ggtt offset: 00156000, size: 4000, type: 0) (stolen: > > 00139000) > >8b55bf02da40: p g 14400KiB 77 00 [ 0 0 0 0 ] 0 uncached dirty > > (name: 1) (pinned x 1) (display) (ggtt offset: 0015a000, size: 00e1, > > type: 0) (stolen: 0013d000) (p mappable) > >8b556dfba780:g16KiB 40 40 [ 0 0 0 0 ] 0 LLC dirty > > (pinned x 0) (ggtt offset: 0ad2a000, size: 4000, type: 0) (stolen: > > 01655000) > > > > > likely you'll have the fbdev framebuffer taking up a sizeable chunk. > > > > Seems 14MB. > > > > > You could get some back by reducing fbdev depth to 16bpp, or even 8bpp, > > > but I'm not convinced the fbdev gamma LUT stuff really works currently > > > so you might end up with bogus colors in your vts with that. > > > > Ok, I could try it. Via fbset tool? > > Kernel command line. We don't allow resizing the fbdev fb once it's > created. Ok, will try. > > > > > > > > > > [0.00] Memory: 7972840K/8282704K available (6196K kernel code, > > > > 1159K rwdata, 2848K rodata, 1408K init, 688K bss, 309864K reserved, 0K > > > > cma-reserved) > > > > > > > > > The BIOS may or may not provide a knob to change the size > > > > > of the stolen memory. > > > > > > > > In BIOS Setup screen I have option to choose GPU memory and I set it to > > > > max 512MB. So this is not the right option... > > > > > > > > And why cannot kernel use some continuous check of RAM itself? > > > > > > Because the hardware won't allow it. > > > > So it can be done only once after reboot? Or only prior to booting kernel? > > Never. Never? Now I'm lost. Why then dmesg message instruct user to try set up it in BIOS if you say it is never possible? -- Pali Rohár pali.ro...@gmail.com signature.asc Description: PGP signature ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: Thinkpad X1 Carbon 3rd - Reducing the compressed framebuffer size
On Tue, Feb 13, 2018 at 06:43:41PM +0100, Pali Rohár wrote: > On Tuesday 13 February 2018 18:12:21 Ville Syrjälä wrote: > > On Tue, Feb 13, 2018 at 05:04:37PM +0100, Pali Rohár wrote: > > > $ cat /sys/kernel/debug/dri/0/i915_gem_stolen > > > Stolen: > > >8b55bf17e080:g16KiB 40 40 [ 0 0 0 0 ] 0 LLC dirty > > > (pinned x 1) (ggtt offset: 00083000, size: 4000, type: 0) (stolen: > > > 1000) > > >8b55c2693040:g16KiB 40 40 [ 0 0 0 0 ] 0 LLC dirty > > > (pinned x 1) (ggtt offset: 02b9f000, size: 4000, type: 0) (stolen: > > > 5000) > > >8b55bf9a7300:g16KiB 40 40 [ 0 0 0 0 ] 0 LLC dirty > > > (pinned x 0) (ggtt offset: 0f6b4000, size: 4000, type: 0) (stolen: > > > 9000) > > >8b55a6161040:g16KiB 40 40 [ 0 0 0 0 ] 0 LLC dirty > > > (pinned x 0) (ggtt offset: 0937f000, size: 4000, type: 0) (stolen: > > > d000) > > >8b5563e0dac0:g16KiB 40 40 [ 0 0 0 0 ] 0 LLC dirty > > > (pinned x 0) (ggtt offset: 0f714000, size: 4000, type: 0) (stolen: > > > 00019000) > > >8b55bf17e800:g 4KiB 41 00 [ 0 0 0 0 ] 0 LLC (pinned x > > > 1) (ggtt offset: e000, size: 1000, type: 0) (stolen: 0012c000) > > >8b55bf02d540:g16KiB 40 40 [ 0 0 0 0 ] 0 LLC dirty > > > (pinned x 1) (ggtt offset: 00141000, size: 4000, type: 0) (stolen: > > > 0012d000) > > >8b55c2989340:g16KiB 40 40 [ 0 0 0 0 ] 0 LLC dirty > > > (pinned x 1) (ggtt offset: 00148000, size: 4000, type: 0) (stolen: > > > 00131000) > > >8b55c29890c0:g16KiB 40 40 [ 0 0 0 0 ] 0 LLC dirty > > > (pinned x 1) (ggtt offset: 0014f000, size: 4000, type: 0) (stolen: > > > 00135000) > > >8b55c2989840:g16KiB 40 40 [ 0 0 0 0 ] 0 LLC dirty > > > (pinned x 1) (ggtt offset: 00156000, size: 4000, type: 0) (stolen: > > > 00139000) > > >8b55bf02da40: p g 14400KiB 77 00 [ 0 0 0 0 ] 0 uncached > > > dirty (name: 1) (pinned x 1) (display) (ggtt offset: 0015a000, size: > > > 00e1, type: 0) (stolen: 0013d000) (p mappable) > > >8b556dfba780:g16KiB 40 40 [ 0 0 0 0 ] 0 LLC dirty > > > (pinned x 0) (ggtt offset: 0ad2a000, size: 4000, type: 0) (stolen: > > > 01655000) > > > > > > > likely you'll have the fbdev framebuffer taking up a sizeable chunk. > > > > > > Seems 14MB. > > > > > > > You could get some back by reducing fbdev depth to 16bpp, or even 8bpp, > > > > but I'm not convinced the fbdev gamma LUT stuff really works currently > > > > so you might end up with bogus colors in your vts with that. > > > > > > Ok, I could try it. Via fbset tool? > > > > Kernel command line. We don't allow resizing the fbdev fb once it's > > created. > > Ok, will try. > > > > > > > > > > > > > > [0.00] Memory: 7972840K/8282704K available (6196K kernel > > > > > code, 1159K rwdata, 2848K rodata, 1408K init, 688K bss, 309864K > > > > > reserved, 0K cma-reserved) > > > > > > > > > > > The BIOS may or may not provide a knob to change the size > > > > > > of the stolen memory. > > > > > > > > > > In BIOS Setup screen I have option to choose GPU memory and I set it > > > > > to > > > > > max 512MB. So this is not the right option... > > > > > > > > > > And why cannot kernel use some continuous check of RAM itself? > > > > > > > > Because the hardware won't allow it. > > > > > > So it can be done only once after reboot? Or only prior to booting kernel? > > > > Never. > > Never? Now I'm lost. Why then dmesg message instruct user to try set up > it in BIOS if you say it is never possible? You can change it in the BIOS. No way to change it from the operating system. -- Ville Syrjälä Intel OTC ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v4 2/5] dt-bindings: adv7511: Extend bindings to allow specifying slave map addresses
From: Kieran Bingham The ADV7511 has four 256-byte maps that can be accessed via the main I2C ports. Each map has it own I2C address and acts as a standard slave device on the I2C bus. Extend the device tree node bindings to be able to override the default addresses so that address conflicts with other devices on the same bus may be resolved at the board description level. Signed-off-by: Kieran Bingham Reviewed-by: Rob Herring Reviewed-by: Laurent Pinchart --- v2: - Fixed up reg: property description to account for multiple optional addresses. - Minor reword to commit message to account for DT only change - Collected Robs RB tag v3: - Split map register addresses into individual declarations. v4: - Update commit title - Collect Laurent's RB tag - Fix nitpickings - Normalise I2C usage (I²C is harder to grep for) .../devicetree/bindings/display/bridge/adi,adv7511.txt | 18 -- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/display/bridge/adi,adv7511.txt b/Documentation/devicetree/bindings/display/bridge/adi,adv7511.txt index 0047b1394c70..2c887536258c 100644 --- a/Documentation/devicetree/bindings/display/bridge/adi,adv7511.txt +++ b/Documentation/devicetree/bindings/display/bridge/adi,adv7511.txt @@ -14,7 +14,13 @@ Required properties: "adi,adv7513" "adi,adv7533" -- reg: I2C slave address +- reg: I2C slave addresses + The ADV7511 internal registers are split into four pages exposed through + different I2C addresses, creating four register maps. Each map has it own + I2C address and acts as a standard slave device on the I2C bus. The main + address is mandatory, others are optional and revert to defaults if not + specified. + The ADV7511 supports a large number of input data formats that differ by their color depth, color format, clock mode, bit justification and random @@ -70,6 +76,9 @@ Optional properties: rather than generate its own timings for HDMI output. - clocks: from common clock binding: reference to the CEC clock. - clock-names: from common clock binding: must be "cec". +- reg-names : Names of maps with programmable addresses. + It can contain any map needing a non-default address. + Possible maps names are : "main", "edid", "cec", "packet" Required nodes: @@ -88,7 +97,12 @@ Example adv7511w: hdmi@39 { compatible = "adi,adv7511w"; - reg = <39>; + /* +* The EDID page will be accessible on address 0x66 on the I2C +* bus. All other maps continue to use their default addresses. +*/ + reg = <0x39>, <0x66>; + reg-names = "main", "edid"; interrupt-parent = <&gpio3>; interrupts = <29 IRQ_TYPE_EDGE_FALLING>; clocks = <&cec_clock>; -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v4 3/5] [RFT] ARM: dts: wheat: Fix ADV7513 address usage
From: Kieran Bingham The r8a7792 Wheat board has two ADV7513 devices sharing a single I2C bus, however in low power mode the ADV7513 will reset it's slave maps to use the hardware defined default addresses. The ADV7511 driver was adapted to allow the two devices to be registered correctly - but it did not take into account the fault whereby the devices reset the addresses. This results in an address conflict between the device using the default addresses, and the other device if it is in low-power-mode. Repair this issue by moving both devices away from the default address definitions. Signed-off-by: Kieran Bingham Reviewed-by: Laurent Pinchart --- v2: - Addition to series v3: - Split map register addresses into individual declarations. v4: - Normalise I2C usage arch/arm/boot/dts/r8a7792-wheat.dts | 12 ++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/r8a7792-wheat.dts b/arch/arm/boot/dts/r8a7792-wheat.dts index b9471b67b728..42fff8837eab 100644 --- a/arch/arm/boot/dts/r8a7792-wheat.dts +++ b/arch/arm/boot/dts/r8a7792-wheat.dts @@ -240,9 +240,16 @@ status = "okay"; clock-frequency = <40>; + /* +* The adv75xx resets its addresses to defaults during low power power +* mode. Because we have two ADV7513 devices on the same bus, we must +* change both of them away from the defaults so that they do not +* conflict. +*/ hdmi@3d { compatible = "adi,adv7513"; - reg = <0x3d>; + reg = <0x3d>, <0x2d>, <0x4d>, <0x5d>; + reg-names = "main", "cec", "edid", "packet"; adi,input-depth = <8>; adi,input-colorspace = "rgb"; @@ -272,7 +279,8 @@ hdmi@39 { compatible = "adi,adv7513"; - reg = <0x39>; + reg = <0x39>, <0x29>, <0x49>, <0x59>; + reg-names = "main", "cec", "edid", "packet"; adi,input-depth = <8>; adi,input-colorspace = "rgb"; -- 2.7.4 ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v4 5/5] drm: adv7511: Add support for i2c_new_secondary_device
From: Kieran Bingham The ADV7511 has four 256-byte maps that can be accessed via the main I2C ports. Each map has it own I2C address and acts as a standard slave device on the I2C bus. Allow a device tree node to override the default addresses so that address conflicts with other devices on the same bus may be resolved at the board description level. Signed-off-by: Kieran Bingham Reviewed-by: Laurent Pinchart --- v2: - Update missing edid-i2c address setting - Split out DT bindings - Rename and move the I2C default addresses to their own section v3: - No change v4: - Change registration order of packet/cec to fix error path and simplify code change. - Collect Laurent's RB tag drivers/gpu/drm/bridge/adv7511/adv7511.h | 6 drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 42 ++-- 2 files changed, 33 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h b/drivers/gpu/drm/bridge/adv7511/adv7511.h index d034b2cb5eee..73d8ccb97742 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511.h +++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h @@ -93,6 +93,11 @@ #define ADV7511_REG_CHIP_ID_HIGH 0xf5 #define ADV7511_REG_CHIP_ID_LOW0xf6 +/* Hardware defined default addresses for I2C register maps */ +#define ADV7511_CEC_I2C_ADDR_DEFAULT 0x3c +#define ADV7511_EDID_I2C_ADDR_DEFAULT 0x3f +#define ADV7511_PACKET_I2C_ADDR_DEFAULT0x38 + #define ADV7511_CSC_ENABLE BIT(7) #define ADV7511_CSC_UPDATE_MODEBIT(5) @@ -321,6 +326,7 @@ enum adv7511_type { struct adv7511 { struct i2c_client *i2c_main; struct i2c_client *i2c_edid; + struct i2c_client *i2c_packet; struct i2c_client *i2c_cec; struct regmap *regmap; diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index efa29db5fc2b..802bc433f54a 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c @@ -586,7 +586,7 @@ static int adv7511_get_modes(struct adv7511 *adv7511, /* Reading the EDID only works if the device is powered */ if (!adv7511->powered) { unsigned int edid_i2c_addr = - (adv7511->i2c_main->addr << 1) + 4; + (adv7511->i2c_edid->addr << 1); __adv7511_power_on(adv7511); @@ -969,10 +969,10 @@ static int adv7511_init_cec_regmap(struct adv7511 *adv) { int ret; - adv->i2c_cec = i2c_new_dummy(adv->i2c_main->adapter, -adv->i2c_main->addr - 1); + adv->i2c_cec = i2c_new_secondary_device(adv->i2c_main, "cec", + ADV7511_CEC_I2C_ADDR_DEFAULT); if (!adv->i2c_cec) - return -ENOMEM; + return -EINVAL; i2c_set_clientdata(adv->i2c_cec, adv); adv->regmap_cec = devm_regmap_init_i2c(adv->i2c_cec, @@ -1082,8 +1082,6 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id) struct adv7511_link_config link_config; struct adv7511 *adv7511; struct device *dev = &i2c->dev; - unsigned int main_i2c_addr = i2c->addr << 1; - unsigned int edid_i2c_addr = main_i2c_addr + 4; unsigned int val; int ret; @@ -1153,23 +1151,34 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id) if (ret) goto uninit_regulators; - regmap_write(adv7511->regmap, ADV7511_REG_EDID_I2C_ADDR, edid_i2c_addr); - regmap_write(adv7511->regmap, ADV7511_REG_PACKET_I2C_ADDR, -main_i2c_addr - 0xa); - regmap_write(adv7511->regmap, ADV7511_REG_CEC_I2C_ADDR, -main_i2c_addr - 2); - adv7511_packet_disable(adv7511, 0x); - adv7511->i2c_edid = i2c_new_dummy(i2c->adapter, edid_i2c_addr >> 1); + adv7511->i2c_edid = i2c_new_secondary_device(i2c, "edid", + ADV7511_EDID_I2C_ADDR_DEFAULT); if (!adv7511->i2c_edid) { - ret = -ENOMEM; + ret = -EINVAL; goto uninit_regulators; } + regmap_write(adv7511->regmap, ADV7511_REG_EDID_I2C_ADDR, +adv7511->i2c_edid->addr << 1); + + adv7511->i2c_packet = i2c_new_secondary_device(i2c, "packet", + ADV7511_PACKET_I2C_ADDR_DEFAULT); + if (!adv7511->i2c_packet) { + ret = -EINVAL; + goto err_i2c_unregister_edid; + } + + regmap_write(adv7511->regmap, ADV7511_REG_PACKET_I2C_ADDR, +adv7511->i2c_packet->addr << 1); + ret = adv7511_init_cec_regmap(adv7511); if (ret) - goto err_i2c_unregister_edid; + goto err_i2c_unregister