* Re: Kernel crash due to memory corruption with v5.4.26-rt17 and PowerPC e500
From: Sebastian Andrzej Siewior @ 2020-05-29 16:37 UTC (permalink / raw)
To: Mark Marshall
Cc: linux-rt-users, Mark Marshall, thomas.graziadei, Thomas Gleixner,
linux-kernel, rostedt
In-Reply-To: <20200529161518.svpxhkeljafbtdz2@linutronix.de>
On 2020-05-29 18:15:18 [+0200], To Mark Marshall wrote:
> In order to get it back into the RT queue I need to understand why it is
> required. What exactly is it fixing. Let me stare at for a little…
it used to be local_irq_disable() which then became preempt_disable()
local_irq_disable() due to ARM's limitation.
> > Best regards,
> > Mark
>
Sebastian
^ permalink raw reply
* Re: Re: [PATCH] PCI: Relax ACS requirement for Intel RCiEP devices.
From: Darrel Goeddel @ 2020-05-29 15:59 UTC (permalink / raw)
To: Ashok Raj
Cc: Darrel Goeddel, linux-pci, iommu, linux-kernel, Alex Williamson,
Mark Scott, Romil Sharma, Bjorn Helgaas
In-Reply-To: <20200528153826.257a0145@x1.home>
On 5/28/20 4:38 PM, Alex Williamson wrote:
> On Thu, 28 May 2020 13:57:42 -0700
> Ashok Raj <ashok.raj@intel.com> wrote:
>
>> All Intel platforms guarantee that all root complex implementations
>> must send transactions up to IOMMU for address translations. Hence for
>> RCiEP devices that are Vendor ID Intel, can claim exception for lack of
>> ACS support.
>>
>>
>> 3.16 Root-Complex Peer to Peer Considerations
>> When DMA remapping is enabled, peer-to-peer requests through the
>> Root-Complex must be handled
>> as follows:
>> • The input address in the request is translated (through first-level,
>> second-level or nested translation) to a host physical address (HPA).
>> The address decoding for peer addresses must be done only on the
>> translated HPA. Hardware implementations are free to further limit
>> peer-to-peer accesses to specific host physical address regions
>> (or to completely disallow peer-forwarding of translated requests).
>> • Since address translation changes the contents (address field) of
>> the PCI Express Transaction Layer Packet (TLP), for PCI Express
>> peer-to-peer requests with ECRC, the Root-Complex hardware must use
>> the new ECRC (re-computed with the translated address) if it
>> decides to forward the TLP as a peer request.
>> • Root-ports, and multi-function root-complex integrated endpoints, may
>> support additional peerto-peer control features by supporting PCI Express
>> Access Control Services (ACS) capability. Refer to ACS capability in
>> PCI Express specifications for details.
>>
>> Since Linux didn't give special treatment to allow this exception, certain
>> RCiEP MFD devices are getting grouped in a single iommu group. This
>> doesn't permit a single device to be assigned to a guest for instance.
>>
>> In one vendor system: Device 14.x were grouped in a single IOMMU group.
>>
>> /sys/kernel/iommu_groups/5/devices/0000:00:14.0
>> /sys/kernel/iommu_groups/5/devices/0000:00:14.2
>> /sys/kernel/iommu_groups/5/devices/0000:00:14.3
>>
>> After the patch:
>> /sys/kernel/iommu_groups/5/devices/0000:00:14.0
>> /sys/kernel/iommu_groups/5/devices/0000:00:14.2
>> /sys/kernel/iommu_groups/6/devices/0000:00:14.3 <<< new group
>>
>> 14.0 and 14.2 are integrated devices, but legacy end points.
>> Whereas 14.3 was a PCIe compliant RCiEP.
>>
>> 00:14.3 Network controller: Intel Corporation Device 9df0 (rev 30)
>> Capabilities: [40] Express (v2) Root Complex Integrated Endpoint, MSI 00
>>
>> This permits assigning this device to a guest VM.
>>
>> Fixes: f096c061f552 ("iommu: Rework iommu_group_get_for_pci_dev()")
>
> I don't really understand this Fixes tag. This seems like a feature,
> not a fix. If you want it in stable releases as a feature, request it
> via Cc: stable@vger.kernel.org. I'd drop that tag, that's my nit.
> Otherwise:
>
> Reviewed-by: Alex Williamson <alex.williamson@redhat.com>
I have tested this patch with 5.6.14 as well as a slightly modified
version (without pci_acs_ctrl_enabled()) in a 3.10 enterprise linux
kernel.
Tested-by: Darrel Goeddel <dgoeddel@forcepoint.com>
>> Signed-off-by: Ashok Raj <ashok.raj@intel.com>
>> To: Joerg Roedel <joro@8bytes.org>
>> To: Bjorn Helgaas <bhelgaas@google.com>
>> Cc: linux-kernel@vger.kernel.org
>> Cc: iommu@lists.linux-foundation.org
>> Cc: Lu Baolu <baolu.lu@linux.intel.com>
>> Cc: Alex Williamson <alex.williamson@redhat.com>
>> Cc: Darrel Goeddel <DGoeddel@forcepoint.com>
>> Cc: Mark Scott <mscott@forcepoint.com>,
>> Cc: Romil Sharma <rsharma@forcepoint.com>
>> Cc: Ashok Raj <ashok.raj@intel.com>
>> ---
>> v2: Moved functionality from iommu to pci quirks - Alex Williamson
>>
>> drivers/pci/quirks.c | 15 +++++++++++++++
>> 1 file changed, 15 insertions(+)
>>
>> diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
>> index 28c9a2409c50..63373ca0a3fe 100644
>> --- a/drivers/pci/quirks.c
>> +++ b/drivers/pci/quirks.c
>> @@ -4682,6 +4682,20 @@ static int pci_quirk_mf_endpoint_acs(struct pci_dev *dev, u16 acs_flags)
>> PCI_ACS_CR | PCI_ACS_UF | PCI_ACS_DT);
>> }
>>
>> +static int pci_quirk_rciep_acs(struct pci_dev *dev, u16 acs_flags)
>> +{
>> + /*
>> + * RCiEP's are required to allow p2p only on translated addresses.
>> + * Refer to Intel VT-d specification Section 3.16 Root-Complex Peer
>> + * to Peer Considerations
>> + */
>> + if (pci_pcie_type(dev) != PCI_EXP_TYPE_RC_END)
>> + return -ENOTTY;
>> +
>> + return pci_acs_ctrl_enabled(acs_flags,
>> + PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF);
>> +}
>> +
>> static int pci_quirk_brcm_acs(struct pci_dev *dev, u16 acs_flags)
>> {
>> /*
>> @@ -4764,6 +4778,7 @@ static const struct pci_dev_acs_enabled {
>> /* I219 */
>> { PCI_VENDOR_ID_INTEL, 0x15b7, pci_quirk_mf_endpoint_acs },
>> { PCI_VENDOR_ID_INTEL, 0x15b8, pci_quirk_mf_endpoint_acs },
>> + { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_quirk_rciep_acs },
>> /* QCOM QDF2xxx root ports */
>> { PCI_VENDOR_ID_QCOM, 0x0400, pci_quirk_qcom_rp_acs },
>> { PCI_VENDOR_ID_QCOM, 0x0401, pci_quirk_qcom_rp_acs },
>
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu
^ permalink raw reply
* Re: [PULL 00/21] Vga 20200528 patches
From: Peter Maydell @ 2020-05-29 16:36 UTC (permalink / raw)
To: Philippe Mathieu-Daudé
Cc: Igor Mitsyanko, Alistair Francis, Mark Cave-Ayland,
QEMU Developers, BALATON Zoltan, qemu-arm, qemu-ppc,
Gerd Hoffmann, Andrzej Zaborowski
In-Reply-To: <bf43132b-71c2-d411-7cf3-e9a00066ccdc@amsat.org>
On Fri, 29 May 2020 at 17:15, Philippe Mathieu-Daudé <f4bug@amsat.org> wrote:
> On 5/29/20 12:29 PM, Peter Maydell wrote:
> > Could somebody send a followup patch to fix the indentation
> > error checkpatch notices, please?
>
> If this is part of your scripts, this is a nice feature :)
No, I just noticed the patchew email.
> >
> > 5/21 Checking commit 97f369f2479d (hw/display/cirrus_vga: Use
> > qemu_log_mask(ERROR) instead of debug printf)
> > ERROR: suspect code indent for conditional statements (16, 12)
> > #34: FILE: hw/display/cirrus_vga.c:1038:
> > if (s->cirrus_blt_pixelwidth > 2) {
> > + qemu_log_mask(LOG_GUEST_ERROR,
>
> I explained on the patches:
>
> False positive.
The code is
if (s->cirrus_blt_mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) {
if (s->cirrus_blt_pixelwidth > 2) {
qemu_log_mask(LOG_GUEST_ERROR,
"cirrus: src transparent without colorexpand "
"must be 8bpp or 16bpp\n");
goto bitblt_ignore;
}
checkpatch seems correct; the qemu_log_mask line is misindented,
and looking at the commit this is a misindent introduced in
commit 2b55f4d3504a9f34 "hw/display/cirrus_vga: Use
qemu_log_mask(ERROR) instead of debug printf". The old
fprintf() line was using indent of tab+tab+4 spaces, but
the new qemu_log_mask line is indented by 12 spaces, not 20.
(Tabs are always 8 spaces equivalent.)
Some days I wonder whether we should just do a bulk detabify
of the QEMU sources.
thanks
-- PMM
^ permalink raw reply
* [PATCH v2] block: improve discard bio alignment in __blkdev_issue_discard()
From: Coly Li @ 2020-05-29 16:34 UTC (permalink / raw)
To: linux-block
Cc: Coly Li, Acshai Manoj, Bart Van Assche, Christoph Hellwig,
Enzo Matsumiya, Hannes Reinecke, Jens Axboe, Ming Lei, Xiao Ni
This patch improves discard bio split for address and size alignment in
__blkdev_issue_discard(). The aligned discard bio may help underlying
device controller to perform better discard and internal garbage
collection, and avoid unnecessary internal fragment.
Current discard bio split algorithm in __blkdev_issue_discard() may have
non-discarded fregment on device even the discard bio LBA and size are
both aligned to device's discard granularity size.
Here is the example steps on how to reproduce the above problem.
- On a VMWare ESXi 6.5 update3 installation, create a 51GB virtual disk
with thin mode and give it to a Linux virtual machine.
- Inside the Linux virtual machine, if the 50GB virtual disk shows up as
/dev/sdb, fill data into the first 50GB by,
# dd if=/dev/zero of=/dev/sdb bs=4096 count=13107200
- Discard the 50GB range from offset 0 on /dev/sdb,
# blkdiscard /dev/sdb -o 0 -l 53687091200
- Observe the underlying mapping status of the device
# sg_get_lba_status /dev/sdb -m 1048 --lba=0
descriptor LBA: 0x0000000000000000 blocks: 2048 mapped (or unknown)
descriptor LBA: 0x0000000000000800 blocks: 16773120 deallocated
descriptor LBA: 0x0000000000fff800 blocks: 2048 mapped (or unknown)
descriptor LBA: 0x0000000001000000 blocks: 8386560 deallocated
descriptor LBA: 0x00000000017ff800 blocks: 2048 mapped (or unknown)
descriptor LBA: 0x0000000001800000 blocks: 8386560 deallocated
descriptor LBA: 0x0000000001fff800 blocks: 2048 mapped (or unknown)
descriptor LBA: 0x0000000002000000 blocks: 8386560 deallocated
descriptor LBA: 0x00000000027ff800 blocks: 2048 mapped (or unknown)
descriptor LBA: 0x0000000002800000 blocks: 8386560 deallocated
descriptor LBA: 0x0000000002fff800 blocks: 2048 mapped (or unknown)
descriptor LBA: 0x0000000003000000 blocks: 8386560 deallocated
descriptor LBA: 0x00000000037ff800 blocks: 2048 mapped (or unknown)
descriptor LBA: 0x0000000003800000 blocks: 8386560 deallocated
descriptor LBA: 0x0000000003fff800 blocks: 2048 mapped (or unknown)
descriptor LBA: 0x0000000004000000 blocks: 8386560 deallocated
descriptor LBA: 0x00000000047ff800 blocks: 2048 mapped (or unknown)
descriptor LBA: 0x0000000004800000 blocks: 8386560 deallocated
descriptor LBA: 0x0000000004fff800 blocks: 2048 mapped (or unknown)
descriptor LBA: 0x0000000005000000 blocks: 8386560 deallocated
descriptor LBA: 0x00000000057ff800 blocks: 2048 mapped (or unknown)
descriptor LBA: 0x0000000005800000 blocks: 8386560 deallocated
descriptor LBA: 0x0000000005fff800 blocks: 2048 mapped (or unknown)
descriptor LBA: 0x0000000006000000 blocks: 6291456 deallocated
descriptor LBA: 0x0000000006600000 blocks: 0 deallocated
Although the discard bio starts at LBA 0 and has 50<<30 bytes size which
are perfect aligned to the discard granularity, from the above list
these are many 1MB (2048 sectors) internal fragments exist unexpectedly.
The problem is in __blkdev_issue_discard(), an improper algorithm causes
an improper bio size which is not aligned.
25 int __blkdev_issue_discard(struct block_device *bdev, sector_t sector,
26 sector_t nr_sects, gfp_t gfp_mask, int flags,
27 struct bio **biop)
28 {
29 struct request_queue *q = bdev_get_queue(bdev);
[snipped]
56
57 while (nr_sects) {
58 sector_t req_sects = min_t(sector_t, nr_sects,
59 bio_allowed_max_sectors(q));
60
61 WARN_ON_ONCE((req_sects << 9) > UINT_MAX);
62
63 bio = blk_next_bio(bio, 0, gfp_mask);
64 bio->bi_iter.bi_sector = sector;
65 bio_set_dev(bio, bdev);
66 bio_set_op_attrs(bio, op, 0);
67
68 bio->bi_iter.bi_size = req_sects << 9;
69 sector += req_sects;
70 nr_sects -= req_sects;
[snipped]
79 }
80
81 *biop = bio;
82 return 0;
83 }
84 EXPORT_SYMBOL(__blkdev_issue_discard);
At line 58-59, to discard a 50GB range, req_sets is set as return value
of bio_allowed_max_sectors(q), which is 8388607 sectors. In the above
case, the discard granularity is 2048 sectors, although the start LBA
and discard length are aligned to discard granularity, seq_sets never
has chance to be aligned to discard granularity. This is why there are
some still-mapped 2048 sectors segment in every 4 or 8 GB range.
Because queue's max_discard_sectors is aligned to discard granularity,
if req_sects at line 58 is set to a value closest to UINT_MAX and
aligned to q->limits.max_discard_sectors, then all consequent split bios
inside device driver are (almostly) aligned to discard_granularity of
the device queue.
This patch introduces bio_aligned_discard_max_sectors() to return the
closet to UINT_MAX and aligned to q->limits.discard_granularity value,
and replace bio_allowed_max_sectors() with this new inline routine to
decide the split bio length.
But we still need to handle the situation when discard start LBA is not
aligned to q->limits.discard_granularity, otherwise even the length is
aligned, current code may still leave 2048 segment around every 4BG
range. Thereforeto calculate req_sects, firstly the start LBA of discard
request command is checked, if it is not aligned to discard granularity,
the first split location should make sure following bio has bi_sector
aligned to discard granularity. Then there won't be still-mapped segment
in the middle of the discard range.
The above is how this patch improves discard bio alignment in
__blkdev_issue_discard(). Now with this patch, after discard with same
command line mentiond previously, sg_get_lba_status returns,
descriptor LBA: 0x0000000000000000 blocks: 106954752 deallocated
descriptor LBA: 0x0000000006600000 blocks: 0 deallocated
We an see there is no 2048 sectors segment anymore, everything is clean.
Reported-by: Acshai Manoj <acshai.manoj@microfocus.com>
Signed-off-by: Coly Li <colyli@suse.de>
Cc: Bart Van Assche <bvanassche@acm.org>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Enzo Matsumiya <ematsumiya@suse.com>
Cc: Hannes Reinecke <hare@suse.com>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: Ming Lei <ming.lei@redhat.com>
Cc: Xiao Ni <xni@redhat.com>
---
Changelog:
v2: replace 9 with SECTOR_SHIFT as suggested by Bart Van Assche.
v1: initial version.
block/blk-lib.c | 25 +++++++++++++++++++++++--
block/blk.h | 15 +++++++++++++++
2 files changed, 38 insertions(+), 2 deletions(-)
diff --git a/block/blk-lib.c b/block/blk-lib.c
index 5f2c429d4378..2fc0e3cc1ed8 100644
--- a/block/blk-lib.c
+++ b/block/blk-lib.c
@@ -55,8 +55,29 @@ int __blkdev_issue_discard(struct block_device *bdev, sector_t sector,
return -EINVAL;
while (nr_sects) {
- sector_t req_sects = min_t(sector_t, nr_sects,
- bio_allowed_max_sectors(q));
+ sector_t granularity_aligned_lba;
+ sector_t req_sects;
+
+ granularity_aligned_lba =
+ round_up(sector, q->limits.discard_granularity);
+
+ /*
+ * Check whether the discard bio starts at a discard_granularity
+ * aligned LBA,
+ * - If no: set (granularity_aligned_lba - sector) to bi_size of
+ * the first split bio, then the second bio will start at a
+ * discard_granularity aligned LBA.
+ * - If yes: use bio_aligned_discard_max_sectors() as the max
+ * possible bi_size of th first split bio. Then when this bio
+ * is split in device drive, the split ones are always easier
+ * to be aligned to max_discard_sectors of the device's queue.
+ */
+ if (granularity_aligned_lba == sector)
+ req_sects = min_t(sector_t, nr_sects,
+ bio_aligned_discard_max_sectors(q));
+ else
+ req_sects = min_t(sector_t, nr_sects,
+ granularity_aligned_lba - sector);
WARN_ON_ONCE((req_sects << 9) > UINT_MAX);
diff --git a/block/blk.h b/block/blk.h
index 0a94ec68af32..dc5369e7e1fb 100644
--- a/block/blk.h
+++ b/block/blk.h
@@ -292,6 +292,21 @@ static inline unsigned int bio_allowed_max_sectors(struct request_queue *q)
return round_down(UINT_MAX, queue_logical_block_size(q)) >> 9;
}
+/*
+ * The max bio size which is aligned to q->limits.max_discard_sectors. This
+ * is a hint to split large discard bio in generic block layer, then if device
+ * driver needs to split the discard bio into smaller ones, their bi_size can
+ * be very probably and easily ligned to max_discard_sectors of the device's
+ * queue.
+ */
+static inline unsigned int bio_aligned_discard_max_sectors(
+ struct request_queue *q)
+{
+ return round_down(UINT_MAX,
+ (q->limits.max_discard_sectors << SECTOR_SHIFT))
+ >> SECTOR_SHIFT;
+}
+
/*
* Internal io_context interface
*/
--
2.25.0
^ permalink raw reply related
* [RFC PATCH v5 6/6] drm: exynos: mixer: Add interconnect support
From: Sylwester Nawrocki @ 2020-05-29 16:32 UTC (permalink / raw)
To: georgi.djakov, cw00.choi, krzk
Cc: linux-samsung-soc, b.zolnierkie, sw0312.kim, a.swigon, dri-devel,
linux-kernel, inki.dae, myungjoo.ham, s.nawrocki,
linux-arm-kernel, m.szyprowski
In-Reply-To: <20200529163200.18031-1-s.nawrocki@samsung.com>
From: Marek Szyprowski <m.szyprowski@samsung.com>
This patch adds interconnect support to exynos-mixer. The mixer works
the same as before when CONFIG_INTERCONNECT is 'n'.
For proper operation of the video mixer block we need to ensure the
interconnect busses like DMC or LEFTBUS provide enough bandwidth so
as to avoid DMA buffer underruns in the mixer block. i.e we need to
prevent those busses from operating in low perfomance OPPs when
the mixer is running.
In this patch the bus bandwidth request is done through the interconnect
API, the bandiwidth value is calculated from selected DRM mode, i.e.
video plane width, height, refresh rate and pixel format.
Co-developed-by: Artur Świgoń <a.swigon@samsung.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
[s.nawrocki: renamed soc_path variable to icc_path, edited commit desc.]
Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
Changes for v5:
- renamed soc_path variable to icc_path
---
drivers/gpu/drm/exynos/exynos_mixer.c | 73 ++++++++++++++++++++++++++++++++---
1 file changed, 68 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
index 21b726b..bdae683 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -13,6 +13,7 @@
#include <linux/component.h>
#include <linux/delay.h>
#include <linux/i2c.h>
+#include <linux/interconnect.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/kernel.h>
@@ -98,6 +99,7 @@ struct mixer_context {
struct exynos_drm_crtc *crtc;
struct exynos_drm_plane planes[MIXER_WIN_NR];
unsigned long flags;
+ struct icc_path *icc_path;
int irq;
void __iomem *mixer_regs;
@@ -934,6 +936,42 @@ static void mixer_disable_vblank(struct exynos_drm_crtc *crtc)
mixer_reg_writemask(mixer_ctx, MXR_INT_EN, 0, MXR_INT_EN_VSYNC);
}
+static void mixer_set_memory_bandwidth(struct exynos_drm_crtc *crtc)
+{
+ struct drm_display_mode *mode = &crtc->base.state->adjusted_mode;
+ struct mixer_context *ctx = crtc->ctx;
+ unsigned long bw, bandwidth = 0;
+ u32 avg_bw, peak_bw;
+ int i, j, sub;
+
+ if (!ctx->icc_path)
+ return;
+
+ for (i = 0; i < MIXER_WIN_NR; i++) {
+ struct drm_plane *plane = &ctx->planes[i].base;
+ const struct drm_format_info *format;
+
+ if (plane->state && plane->state->crtc && plane->state->fb) {
+ format = plane->state->fb->format;
+ bw = mode->hdisplay * mode->vdisplay *
+ drm_mode_vrefresh(mode);
+ if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+ bw /= 2;
+ for (j = 0; j < format->num_planes; j++) {
+ sub = j ? (format->vsub * format->hsub) : 1;
+ bandwidth += format->cpp[j] * bw / sub;
+ }
+ }
+ }
+
+ /* add 20% safety margin */
+ bandwidth = bandwidth / 4 * 5;
+ dev_dbg(ctx->dev, "exynos-mixer: safe bandwidth %ld Bps\n", bandwidth);
+
+ avg_bw = peak_bw = Bps_to_icc(bandwidth);
+ icc_set_bw(ctx->icc_path, avg_bw, peak_bw);
+}
+
static void mixer_atomic_begin(struct exynos_drm_crtc *crtc)
{
struct mixer_context *ctx = crtc->ctx;
@@ -985,6 +1023,7 @@ static void mixer_atomic_flush(struct exynos_drm_crtc *crtc)
if (!test_bit(MXR_BIT_POWERED, &mixer_ctx->flags))
return;
+ mixer_set_memory_bandwidth(crtc);
mixer_enable_sync(mixer_ctx);
exynos_crtc_handle_event(crtc);
}
@@ -1032,6 +1071,7 @@ static void mixer_atomic_disable(struct exynos_drm_crtc *crtc)
for (i = 0; i < MIXER_WIN_NR; i++)
mixer_disable_plane(crtc, &ctx->planes[i]);
+ mixer_set_memory_bandwidth(crtc);
exynos_drm_pipe_clk_enable(crtc, false);
pm_runtime_put(ctx->dev);
@@ -1223,12 +1263,22 @@ static int mixer_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
const struct mixer_drv_data *drv;
struct mixer_context *ctx;
+ struct icc_path *path;
int ret;
+ /*
+ * Returns NULL if CONFIG_INTERCONNECT is disabled.
+ * May return ERR_PTR(-EPROBE_DEFER).
+ */
+ path = of_icc_get(dev, NULL);
+ if (IS_ERR(path))
+ return PTR_ERR(path);
+
ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
if (!ctx) {
DRM_DEV_ERROR(dev, "failed to alloc mixer context.\n");
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto err;
}
drv = of_device_get_match_data(dev);
@@ -1236,6 +1286,7 @@ static int mixer_probe(struct platform_device *pdev)
ctx->pdev = pdev;
ctx->dev = dev;
ctx->mxr_ver = drv->version;
+ ctx->icc_path = path;
if (drv->is_vp_enabled)
__set_bit(MXR_BIT_VP_ENABLED, &ctx->flags);
@@ -1245,17 +1296,29 @@ static int mixer_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, ctx);
ret = component_add(&pdev->dev, &mixer_component_ops);
- if (!ret)
- pm_runtime_enable(dev);
+ if (ret < 0)
+ goto err;
+
+ pm_runtime_enable(dev);
+
+ return 0;
+
+err:
+ icc_put(path);
return ret;
}
static int mixer_remove(struct platform_device *pdev)
{
- pm_runtime_disable(&pdev->dev);
+ struct device *dev = &pdev->dev;
+ struct mixer_context *ctx = dev_get_drvdata(dev);
+
+ pm_runtime_disable(dev);
+
+ component_del(dev, &mixer_component_ops);
- component_del(&pdev->dev, &mixer_component_ops);
+ icc_put(ctx->icc_path);
return 0;
}
--
2.7.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [RFC PATCH v5 5/6] ARM: dts: exynos: Add interconnects to Exynos4412 mixer
From: Sylwester Nawrocki @ 2020-05-29 16:31 UTC (permalink / raw)
To: georgi.djakov, cw00.choi, krzk
Cc: linux-samsung-soc, b.zolnierkie, sw0312.kim, a.swigon, dri-devel,
linux-kernel, inki.dae, myungjoo.ham, s.nawrocki,
linux-arm-kernel, m.szyprowski
In-Reply-To: <20200529163200.18031-1-s.nawrocki@samsung.com>
From: Artur Świgoń <a.swigon@samsung.com>
This patch adds an 'interconnects' property to Exynos4412 DTS in order to
declare the interconnect path used by the mixer. Please note that the
'interconnect-names' property is not needed when there is only one path in
'interconnects', in which case calling of_icc_get() with a NULL name simply
returns the right path.
Signed-off-by: Artur Świgoń <a.swigon@samsung.com>
Reviewed-by: Chanwoo Choi <cw00.choi@samsung.com>
---
Changes for v5:
- none.
---
arch/arm/boot/dts/exynos4412.dtsi | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm/boot/dts/exynos4412.dtsi b/arch/arm/boot/dts/exynos4412.dtsi
index a7496d3..eee86d2 100644
--- a/arch/arm/boot/dts/exynos4412.dtsi
+++ b/arch/arm/boot/dts/exynos4412.dtsi
@@ -776,6 +776,7 @@
clock-names = "mixer", "hdmi", "sclk_hdmi", "vp";
clocks = <&clock CLK_MIXER>, <&clock CLK_HDMI>,
<&clock CLK_SCLK_HDMI>, <&clock CLK_VP>;
+ interconnects = <&bus_display &bus_dmc>;
};
&pmu {
--
2.7.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* Re: [PATCH v2] virtio_vsock: Fix race condition in virtio_transport_recv_pkt
From: Stefano Garzarella @ 2020-05-29 16:34 UTC (permalink / raw)
To: Jia He
Cc: Stefan Hajnoczi, David S. Miller, Jakub Kicinski, kvm,
virtualization, netdev, linux-kernel, Kaly Xin, stable
In-Reply-To: <20200529152102.58397-1-justin.he@arm.com>
On Fri, May 29, 2020 at 11:21:02PM +0800, Jia He wrote:
> When client tries to connect(SOCK_STREAM) the server in the guest with
> NONBLOCK mode, there will be a panic on a ThunderX2 (armv8a server):
> [ 463.718844][ T5040] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000
> [ 463.718848][ T5040] Mem abort info:
> [ 463.718849][ T5040] ESR = 0x96000044
> [ 463.718852][ T5040] EC = 0x25: DABT (current EL), IL = 32 bits
> [ 463.718853][ T5040] SET = 0, FnV = 0
> [ 463.718854][ T5040] EA = 0, S1PTW = 0
> [ 463.718855][ T5040] Data abort info:
> [ 463.718856][ T5040] ISV = 0, ISS = 0x00000044
> [ 463.718857][ T5040] CM = 0, WnR = 1
> [ 463.718859][ T5040] user pgtable: 4k pages, 48-bit VAs, pgdp=0000008f6f6e9000
> [ 463.718861][ T5040] [0000000000000000] pgd=0000000000000000
> [ 463.718866][ T5040] Internal error: Oops: 96000044 [#1] SMP
> [...]
> [ 463.718977][ T5040] CPU: 213 PID: 5040 Comm: vhost-5032 Tainted: G O 5.7.0-rc7+ #139
> [ 463.718980][ T5040] Hardware name: GIGABYTE R281-T91-00/MT91-FS1-00, BIOS F06 09/25/2018
> [ 463.718982][ T5040] pstate: 60400009 (nZCv daif +PAN -UAO)
> [ 463.718995][ T5040] pc : virtio_transport_recv_pkt+0x4c8/0xd40 [vmw_vsock_virtio_transport_common]
> [ 463.718999][ T5040] lr : virtio_transport_recv_pkt+0x1fc/0xd40 [vmw_vsock_virtio_transport_common]
> [ 463.719000][ T5040] sp : ffff80002dbe3c40
> [...]
> [ 463.719025][ T5040] Call trace:
> [ 463.719030][ T5040] virtio_transport_recv_pkt+0x4c8/0xd40 [vmw_vsock_virtio_transport_common]
> [ 463.719034][ T5040] vhost_vsock_handle_tx_kick+0x360/0x408 [vhost_vsock]
> [ 463.719041][ T5040] vhost_worker+0x100/0x1a0 [vhost]
> [ 463.719048][ T5040] kthread+0x128/0x130
> [ 463.719052][ T5040] ret_from_fork+0x10/0x18
^ ^
Maybe we can remove these two columns from the commit message.
>
> The race condition as follows:
> Task1 Task2
> ===== =====
> __sock_release virtio_transport_recv_pkt
> __vsock_release vsock_find_bound_socket (found)
> lock_sock_nested
> vsock_remove_sock
> sock_orphan
> sk_set_socket(sk, NULL)
Here we can add:
sk->sk_shutdown = SHUTDOWN_MASK;
> ...
> release_sock
> lock_sock
> virtio_transport_recv_connecting
> sk->sk_socket->state (panic)
>
> The root cause is that vsock_find_bound_socket can't hold the lock_sock,
> so there is a small race window between vsock_find_bound_socket() and
> lock_sock(). If there is __vsock_release() in another task, sk->sk_socket
> will be set to NULL inadvertently.
>
> This fixes it by checking sk->sk_shutdown.
>
> Signed-off-by: Jia He <justin.he@arm.com>
> Cc: stable@vger.kernel.org
> Cc: Stefano Garzarella <sgarzare@redhat.com>
> ---
> v2: use lightweight checking suggested by Stefano Garzarella
>
> net/vmw_vsock/virtio_transport_common.c | 8 ++++++++
> 1 file changed, 8 insertions(+)
>
> diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c
> index 69efc891885f..0edda1edf988 100644
> --- a/net/vmw_vsock/virtio_transport_common.c
> +++ b/net/vmw_vsock/virtio_transport_common.c
> @@ -1132,6 +1132,14 @@ void virtio_transport_recv_pkt(struct virtio_transport *t,
>
> lock_sock(sk);
>
> + /* Check if sk has been released before lock_sock */
> + if (sk->sk_shutdown == SHUTDOWN_MASK) {
> + (void)virtio_transport_reset_no_sock(t, pkt);
> + release_sock(sk);
> + sock_put(sk);
> + goto free_pkt;
> + }
> +
> /* Update CID in case it has changed after a transport reset event */
> vsk->local_addr.svm_cid = dst.svm_cid;
>
> --
> 2.17.1
>
Anyway, the patch LGTM, let see what David and other say.
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
Thanks,
Stefano
^ permalink raw reply
* [RFC PATCH v5 4/6] ARM: dts: exynos: Add interconnect properties to Exynos4412 bus nodes
From: Sylwester Nawrocki @ 2020-05-29 16:31 UTC (permalink / raw)
To: georgi.djakov, cw00.choi, krzk
Cc: linux-samsung-soc, b.zolnierkie, sw0312.kim, a.swigon, dri-devel,
linux-kernel, inki.dae, myungjoo.ham, s.nawrocki,
linux-arm-kernel, m.szyprowski
In-Reply-To: <20200529163200.18031-1-s.nawrocki@samsung.com>
This patch adds the following properties for Exynos4412 interconnect
bus nodes:
- samsung,interconnect-parent: to declare connections between
nodes in order to guarantee PM QoS requirements between nodes;
- #interconnect-cells: required by the interconnect framework.
Note that #interconnect-cells is always zero and node IDs are not
hardcoded anywhere.
Signed-off-by: Artur Świgoń <a.swigon@samsung.com>
Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
Changes for v5:
- adjust to renamed exynos,interconnect-parent-node property,
- add properties in common exynos4412.dtsi file rather than
in Odroid specific odroid4412-odroid-common.dtsi.
---
arch/arm/boot/dts/exynos4412.dtsi | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/arch/arm/boot/dts/exynos4412.dtsi b/arch/arm/boot/dts/exynos4412.dtsi
index 4886894..a7496d3 100644
--- a/arch/arm/boot/dts/exynos4412.dtsi
+++ b/arch/arm/boot/dts/exynos4412.dtsi
@@ -381,6 +381,7 @@
clocks = <&clock CLK_DIV_DMC>;
clock-names = "bus";
operating-points-v2 = <&bus_dmc_opp_table>;
+ #interconnect-cells = <0>;
status = "disabled";
};
@@ -450,6 +451,8 @@
clocks = <&clock CLK_DIV_GDL>;
clock-names = "bus";
operating-points-v2 = <&bus_leftbus_opp_table>;
+ samsung,interconnect-parent = <&bus_dmc>;
+ #interconnect-cells = <0>;
status = "disabled";
};
@@ -466,6 +469,8 @@
clocks = <&clock CLK_ACLK160>;
clock-names = "bus";
operating-points-v2 = <&bus_display_opp_table>;
+ samsung,interconnect-parent = <&bus_leftbus>;
+ #interconnect-cells = <0>;
status = "disabled";
};
--
2.7.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* Re: [PATCH net] net: mvpp2: Enable autoneg bypass for 1000BaseX/2500BaseX ports
From: Andrew Lunn @ 2020-05-29 16:33 UTC (permalink / raw)
To: Thomas Bogendoerfer
Cc: Russell King - ARM Linux admin, David S. Miller, Jakub Kicinski,
netdev, linux-kernel
In-Reply-To: <20200529175225.a3be1b4faaa0408e165435ad@suse.de>
> > By propagated, you mean if the external link is down, the link between
> > the switch and node 1 will also be forced down, at the SERDES level?
>
> yes
>
> > And if external ports are down, the nodes cannot talk to each other?
>
> correct
>
> > External link down causes the whole in box network to fall apart? That
> > seems a rather odd design.
>
> as I'm not an expert in ceph, I can't judge. But I'll bring it up.
I guess for a single use appliance this is O.K. But it makes the
hardware unusable as a general purpose server.
Is there a variant of the hardware to be used as a general purpose
server, rather than as a Ceph appliance? If so, does it share the same
DT files?
> > What you are actually interested in is the sync state of the SERDES?
> > The link is up if the SERDES has sync.
>
> yes, that's what I need. How can I do that ?
Given the current code, you cannot. Now we understand the
requirements, we can come up with some ideas how to do this properly.
Andrew
^ permalink raw reply
* [RFC PATCH v5 3/6] PM / devfreq: exynos-bus: Add registration of interconnect child device
From: Sylwester Nawrocki @ 2020-05-29 16:31 UTC (permalink / raw)
To: georgi.djakov, cw00.choi, krzk
Cc: linux-samsung-soc, b.zolnierkie, sw0312.kim, a.swigon, dri-devel,
linux-kernel, inki.dae, myungjoo.ham, s.nawrocki,
linux-arm-kernel, m.szyprowski
In-Reply-To: <20200529163200.18031-1-s.nawrocki@samsung.com>
This patch adds registration of a child platform device for the exynos
interconnect driver. It is assumed that the interconnect provider will
only be needed when #interconnect-cells property is present in the bus
DT node, hence the child device will be created only when such a property
is present.
Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Changes for v5:
- new patch.
---
drivers/devfreq/exynos-bus.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/drivers/devfreq/exynos-bus.c b/drivers/devfreq/exynos-bus.c
index 8fa8eb5..856e37d 100644
--- a/drivers/devfreq/exynos-bus.c
+++ b/drivers/devfreq/exynos-bus.c
@@ -24,6 +24,7 @@
struct exynos_bus {
struct device *dev;
+ struct platform_device *icc_pdev;
struct devfreq *devfreq;
struct devfreq_event_dev **edev;
@@ -156,6 +157,8 @@ static void exynos_bus_exit(struct device *dev)
if (ret < 0)
dev_warn(dev, "failed to disable the devfreq-event devices\n");
+ platform_device_unregister(bus->icc_pdev);
+
dev_pm_opp_of_remove_table(dev);
clk_disable_unprepare(bus->clk);
if (bus->opp_table) {
@@ -168,6 +171,8 @@ static void exynos_bus_passive_exit(struct device *dev)
{
struct exynos_bus *bus = dev_get_drvdata(dev);
+ platform_device_unregister(bus->icc_pdev);
+
dev_pm_opp_of_remove_table(dev);
clk_disable_unprepare(bus->clk);
}
@@ -431,6 +436,18 @@ static int exynos_bus_probe(struct platform_device *pdev)
if (ret < 0)
goto err;
+ /* Create child platform device for the interconnect provider */
+ if (of_get_property(dev->of_node, "#interconnect-cells", NULL)) {
+ bus->icc_pdev = platform_device_register_data(
+ dev, "exynos-generic-icc",
+ PLATFORM_DEVID_AUTO, NULL, 0);
+
+ if (IS_ERR(bus->icc_pdev)) {
+ ret = PTR_ERR(bus->icc_pdev);
+ goto err;
+ }
+ }
+
max_state = bus->devfreq->profile->max_state;
min_freq = (bus->devfreq->profile->freq_table[0] / 1000);
max_freq = (bus->devfreq->profile->freq_table[max_state - 1] / 1000);
--
2.7.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH] board: dh_stm32mp1: update the gpio hog support
From: Patrick Delaunay @ 2020-05-29 16:33 UTC (permalink / raw)
To: u-boot
This patch update the current gpio hog implementation with
the new API gpio_hog_probe_all() actviated with CONFIG_GPIO_HOG.
Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
---
board/dhelectronics/dh_stm32mp1/board.c | 10 ++--------
1 file changed, 2 insertions(+), 8 deletions(-)
diff --git a/board/dhelectronics/dh_stm32mp1/board.c b/board/dhelectronics/dh_stm32mp1/board.c
index 26e827bc38..ac9dc4b52c 100644
--- a/board/dhelectronics/dh_stm32mp1/board.c
+++ b/board/dhelectronics/dh_stm32mp1/board.c
@@ -513,17 +513,11 @@ static void board_init_fmc2(void)
/* board dependent setup after realloc */
int board_init(void)
{
- struct udevice *dev;
-
/* address of boot parameters */
gd->bd->bi_boot_params = STM32_DDR_BASE + 0x100;
- /* probe all PINCTRL for hog */
- for (uclass_first_device(UCLASS_PINCTRL, &dev);
- dev;
- uclass_next_device(&dev)) {
- pr_debug("probe pincontrol = %s\n", dev->name);
- }
+ if (CONFIG_IS_ENABLED(DM_GPIO_HOG))
+ gpio_hog_probe_all();
board_key_check();
--
2.17.1
^ permalink raw reply related
* [RFC PATCH v5 2/6] interconnect: Add generic interconnect driver for Exynos SoCs
From: Sylwester Nawrocki @ 2020-05-29 16:31 UTC (permalink / raw)
To: georgi.djakov, cw00.choi, krzk
Cc: linux-samsung-soc, b.zolnierkie, sw0312.kim, a.swigon, dri-devel,
linux-kernel, inki.dae, myungjoo.ham, s.nawrocki,
linux-arm-kernel, m.szyprowski
In-Reply-To: <20200529163200.18031-1-s.nawrocki@samsung.com>
This patch adds a generic interconnect driver for Exynos SoCs in order
to provide interconnect functionality for each "samsung,exynos-bus"
compatible device.
The SoC topology is a graph (or more specifically, a tree) and its
edges are specified using the 'samsung,interconnect-parent' in the
DT. Due to unspecified relative probing order, -EPROBE_DEFER may be
propagated to ensure that the parent is probed before its children.
Each bus is now an interconnect provider and an interconnect node as
well (cf. Documentation/interconnect/interconnect.rst), i.e. every bus
registers itself as a node. Node IDs are not hardcoded but rather
assigned dynamically at runtime. This approach allows for using this
driver with various Exynos SoCs.
Frequencies requested via the interconnect API for a given node are
propagated to devfreq using dev_pm_qos_update_request(). Please note
that it is not an error when CONFIG_INTERCONNECT is 'n', in which
case all interconnect API functions are no-op.
Signed-off-by: Artur Świgoń <a.swigon@samsung.com>
Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Changes for v5:
- adjust to renamed exynos,interconnect-parent-node property,
- use automatically generated platform device id as the interconect
node id instead of a now unavailable devfreq->id field,
- add icc_ prefix to some variables to make the code more self-commenting,
- use icc_nodes_remove() instead of icc_node_del() + icc_node_destroy(),
- adjust to exynos,interconnect-parent-node property rename to
samsung,interconnect-parent,
- converted to a separate platform driver in drivers/interconnect.
---
drivers/interconnect/Kconfig | 1 +
drivers/interconnect/Makefile | 1 +
drivers/interconnect/exynos/Kconfig | 6 ++
drivers/interconnect/exynos/Makefile | 4 +
drivers/interconnect/exynos/exynos.c | 185 +++++++++++++++++++++++++++++++++++
5 files changed, 197 insertions(+)
create mode 100644 drivers/interconnect/exynos/Kconfig
create mode 100644 drivers/interconnect/exynos/Makefile
create mode 100644 drivers/interconnect/exynos/exynos.c
diff --git a/drivers/interconnect/Kconfig b/drivers/interconnect/Kconfig
index 5b7204e..eca6eda 100644
--- a/drivers/interconnect/Kconfig
+++ b/drivers/interconnect/Kconfig
@@ -11,6 +11,7 @@ menuconfig INTERCONNECT
if INTERCONNECT
+source "drivers/interconnect/exynos/Kconfig"
source "drivers/interconnect/imx/Kconfig"
source "drivers/interconnect/qcom/Kconfig"
diff --git a/drivers/interconnect/Makefile b/drivers/interconnect/Makefile
index 4825c28..2ba1de6 100644
--- a/drivers/interconnect/Makefile
+++ b/drivers/interconnect/Makefile
@@ -4,5 +4,6 @@ CFLAGS_core.o := -I$(src)
icc-core-objs := core.o
obj-$(CONFIG_INTERCONNECT) += icc-core.o
+obj-$(CONFIG_INTERCONNECT_EXYNOS) += exynos/
obj-$(CONFIG_INTERCONNECT_IMX) += imx/
obj-$(CONFIG_INTERCONNECT_QCOM) += qcom/
diff --git a/drivers/interconnect/exynos/Kconfig b/drivers/interconnect/exynos/Kconfig
new file mode 100644
index 0000000..e51e52e
--- /dev/null
+++ b/drivers/interconnect/exynos/Kconfig
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0-only
+config INTERCONNECT_EXYNOS
+ tristate "Exynos generic interconnect driver"
+ depends on ARCH_EXYNOS || COMPILE_TEST
+ help
+ Generic interconnect driver for Exynos SoCs.
diff --git a/drivers/interconnect/exynos/Makefile b/drivers/interconnect/exynos/Makefile
new file mode 100644
index 0000000..e19d1df
--- /dev/null
+++ b/drivers/interconnect/exynos/Makefile
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
+exynos-interconnect-objs := exynos.o
+
+obj-$(CONFIG_INTERCONNECT_EXYNOS) += exynos-interconnect.o
diff --git a/drivers/interconnect/exynos/exynos.c b/drivers/interconnect/exynos/exynos.c
new file mode 100644
index 0000000..8278194
--- /dev/null
+++ b/drivers/interconnect/exynos/exynos.c
@@ -0,0 +1,185 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Exynos generic interconnect provider driver
+ *
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Authors: Artur Świgoń <a.swigon@samsung.com>
+ * Sylwester Nawrocki <s.nawrocki@samsung.com>
+ */
+#include <linux/device.h>
+#include <linux/interconnect-provider.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm_qos.h>
+
+#define kbps_to_khz(x) ((x) / 8)
+
+struct exynos_icc_priv {
+ struct device *dev;
+
+ /* One interconnect node per provider */
+ struct icc_provider provider;
+ struct icc_node *node;
+
+ struct dev_pm_qos_request qos_req;
+};
+
+static struct icc_node *exynos_icc_get_parent(struct device_node *np)
+{
+ struct of_phandle_args args;
+ int num, ret;
+
+ num = of_count_phandle_with_args(np, "samsung,interconnect-parent",
+ "#interconnect-cells");
+ if (num != 1)
+ return NULL; /* parent nodes are optional */
+
+ ret = of_parse_phandle_with_args(np, "samsung,interconnect-parent",
+ "#interconnect-cells", 0, &args);
+ if (ret < 0)
+ return ERR_PTR(ret);
+
+ of_node_put(args.np);
+
+ return of_icc_get_from_provider(&args);
+}
+
+
+static int exynos_generic_icc_set(struct icc_node *src, struct icc_node *dst)
+{
+ struct exynos_icc_priv *src_priv = src->data, *dst_priv = dst->data;
+ s32 src_freq = kbps_to_khz(max(src->avg_bw, src->peak_bw));
+ s32 dst_freq = kbps_to_khz(max(dst->avg_bw, dst->peak_bw));
+ int ret;
+
+ ret = dev_pm_qos_update_request(&src_priv->qos_req, src_freq);
+ if (ret < 0) {
+ dev_err(src_priv->dev, "failed to update PM QoS of %s\n",
+ src->name);
+ return ret;
+ }
+
+ ret = dev_pm_qos_update_request(&dst_priv->qos_req, dst_freq);
+ if (ret < 0) {
+ dev_err(dst_priv->dev, "failed to update PM QoS of %s\n",
+ dst->name);
+ return ret;
+ }
+
+ return 0;
+}
+
+static struct icc_node *exynos_generic_icc_xlate(struct of_phandle_args *spec,
+ void *data)
+{
+ struct exynos_icc_priv *priv = data;
+
+ if (spec->np != priv->dev->parent->of_node)
+ return ERR_PTR(-EINVAL);
+
+ return priv->node;
+}
+
+static int exynos_generic_icc_remove(struct platform_device *pdev)
+{
+ struct exynos_icc_priv *priv = platform_get_drvdata(pdev);
+ struct icc_node *parent_node, *node = priv->node;
+
+ parent_node = exynos_icc_get_parent(priv->dev->parent->of_node);
+ if (parent_node && !IS_ERR(parent_node))
+ icc_link_destroy(node, parent_node);
+
+ icc_nodes_remove(&priv->provider);
+ icc_provider_del(&priv->provider);
+
+ return 0;
+}
+
+static int exynos_generic_icc_probe(struct platform_device *pdev)
+{
+ struct device *bus_dev = pdev->dev.parent;
+ struct exynos_icc_priv *priv;
+ struct icc_provider *provider;
+ struct icc_node *icc_node, *icc_parent_node;
+ int ret;
+
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->dev = &pdev->dev;
+ platform_set_drvdata(pdev, priv);
+
+ provider = &priv->provider;
+
+ provider->set = exynos_generic_icc_set;
+ provider->aggregate = icc_std_aggregate;
+ provider->xlate = exynos_generic_icc_xlate;
+ provider->dev = bus_dev;
+ provider->inter_set = true;
+ provider->data = priv;
+
+ ret = icc_provider_add(provider);
+ if (ret < 0)
+ return ret;
+
+ icc_node = icc_node_create(pdev->id);
+ if (IS_ERR(icc_node)) {
+ ret = PTR_ERR(icc_node);
+ goto err_prov_del;
+ }
+
+ priv->node = icc_node;
+ icc_node->name = bus_dev->of_node->name;
+ icc_node->data = priv;
+ icc_node_add(icc_node, provider);
+
+ icc_parent_node = exynos_icc_get_parent(bus_dev->of_node);
+ if (IS_ERR(icc_parent_node)) {
+ ret = PTR_ERR(icc_parent_node);
+ goto err_node_del;
+ }
+ if (icc_parent_node) {
+ ret = icc_link_create(icc_node, icc_parent_node->id);
+ if (ret < 0)
+ goto err_node_del;
+ }
+
+ /*
+ * Register a PM QoS request for the bus device for which also devfreq
+ * functionality is registered.
+ */
+ ret = dev_pm_qos_add_request(bus_dev, &priv->qos_req,
+ DEV_PM_QOS_MIN_FREQUENCY, 0);
+ if (ret < 0)
+ goto err_link_destroy;
+
+ return 0;
+
+err_link_destroy:
+ if (icc_parent_node)
+ icc_link_destroy(icc_node, icc_parent_node);
+err_node_del:
+ icc_nodes_remove(provider);
+err_prov_del:
+ icc_provider_del(provider);
+
+ return ret;
+}
+
+static struct platform_driver exynos_generic_icc_driver = {
+ .driver = {
+ .name = "exynos-generic-icc",
+ },
+ .probe = exynos_generic_icc_probe,
+ .remove = exynos_generic_icc_remove,
+};
+module_platform_driver(exynos_generic_icc_driver);
+
+MODULE_DESCRIPTION("Exynos generic interconnect driver");
+MODULE_AUTHOR("Artur Świgoń <a.swigon@samsung.com>");
+MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:exynos-generic-icc");
--
2.7.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* Re: [PATCH v2 for-4.14] tools/libxl: fix setting altp2m param broken by 1e9bc407cf0
From: Ian Jackson @ 2020-05-29 16:32 UTC (permalink / raw)
To: Andrew Cooper
Cc: Anthony Perard, xen-devel@lists.xenproject.org, Tamas K Lengyel,
Wei Liu
In-Reply-To: <00da0381-e132-03e1-3717-02f4e968ec32@citrix.com>
Andrew Cooper writes ("Re: [PATCH v2 for-4.14] tools/libxl: fix setting altp2m param broken by 1e9bc407cf0"):
> On 29/05/2020 17:22, Tamas K Lengyel wrote:
> > The patch 1e9bc407cf0 mistakenly converted the altp2m config option to a
> > boolean. This is incorrect and breaks external-only usecases of altp2m that
> > is set with a value of 2.
> >
> > Signed-off-by: Tamas K Lengyel <tamas@tklengyel.com>
>
> Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
>
> Sorry for breaking it to begin with.
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
and pushed.
^ permalink raw reply
* [RFC PATCH v5 1/6] dt-bindings: exynos-bus: Add documentation for interconnect properties
From: Sylwester Nawrocki @ 2020-05-29 16:31 UTC (permalink / raw)
To: georgi.djakov, cw00.choi, krzk
Cc: linux-samsung-soc, b.zolnierkie, sw0312.kim, a.swigon, dri-devel,
linux-kernel, inki.dae, myungjoo.ham, s.nawrocki,
linux-arm-kernel, m.szyprowski
In-Reply-To: <20200529163200.18031-1-s.nawrocki@samsung.com>
Add documentation for new optional properties in the exynos bus nodes:
samsung,interconnect-parent, #interconnect-cells.
These properties allow to specify the SoC interconnect structure which
then allows the interconnect consumer devices to request specific
bandwidth requirements.
Signed-off-by: Artur Świgoń <a.swigon@samsung.com>
Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
Changes for v5:
- exynos,interconnect-parent-node renamed to samsung,interconnect-parent
---
Documentation/devicetree/bindings/devfreq/exynos-bus.txt | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/Documentation/devicetree/bindings/devfreq/exynos-bus.txt b/Documentation/devicetree/bindings/devfreq/exynos-bus.txt
index e71f752..e0d2daa 100644
--- a/Documentation/devicetree/bindings/devfreq/exynos-bus.txt
+++ b/Documentation/devicetree/bindings/devfreq/exynos-bus.txt
@@ -51,6 +51,11 @@ Optional properties only for parent bus device:
- exynos,saturation-ratio: the percentage value which is used to calibrate
the performance count against total cycle count.
+Optional properties for interconnect functionality (QoS frequency constraints):
+- samsung,interconnect-parent: phandle to the parent interconnect node; for
+ passive devices should point to same node as the exynos,parent-bus property.
+- #interconnect-cells: should be 0
+
Detailed correlation between sub-blocks and power line according to Exynos SoC:
- In case of Exynos3250, there are two power line as following:
VDD_MIF |--- DMC
@@ -185,8 +190,9 @@ Example1:
----------------------------------------------------------
Example2 :
- The bus of DMC (Dynamic Memory Controller) block in exynos3250.dtsi
- is listed below:
+ The bus of DMC (Dynamic Memory Controller) block in exynos3250.dtsi is
+ listed below. An interconnect path "bus_lcd0 -- bus_leftbus -- bus_dmc"
+ is defined for demonstration purposes.
bus_dmc: bus_dmc {
compatible = "samsung,exynos-bus";
@@ -376,12 +382,15 @@ Example2 :
&bus_dmc {
devfreq-events = <&ppmu_dmc0_3>, <&ppmu_dmc1_3>;
vdd-supply = <&buck1_reg>; /* VDD_MIF */
+ #interconnect-cells = <0>;
status = "okay";
};
&bus_leftbus {
devfreq-events = <&ppmu_leftbus_3>, <&ppmu_rightbus_3>;
vdd-supply = <&buck3_reg>;
+ samsung,interconnect-parent = <&bus_dmc>;
+ #interconnect-cells = <0>;
status = "okay";
};
@@ -392,6 +401,8 @@ Example2 :
&bus_lcd0 {
devfreq = <&bus_leftbus>;
+ samsung,interconnect-parent = <&bus_leftbus>;
+ #interconnect-cells = <0>;
status = "okay";
};
--
2.7.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [RFC PATCH v5 4/6] ARM: dts: exynos: Add interconnect properties to Exynos4412 bus nodes
From: Sylwester Nawrocki @ 2020-05-29 16:31 UTC (permalink / raw)
To: georgi.djakov, cw00.choi, krzk
Cc: a.swigon, myungjoo.ham, inki.dae, sw0312.kim, b.zolnierkie,
m.szyprowski, s.nawrocki, linux-kernel, linux-samsung-soc,
dri-devel, linux-arm-kernel
In-Reply-To: <20200529163200.18031-1-s.nawrocki@samsung.com>
This patch adds the following properties for Exynos4412 interconnect
bus nodes:
- samsung,interconnect-parent: to declare connections between
nodes in order to guarantee PM QoS requirements between nodes;
- #interconnect-cells: required by the interconnect framework.
Note that #interconnect-cells is always zero and node IDs are not
hardcoded anywhere.
Signed-off-by: Artur Świgoń <a.swigon@samsung.com>
Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
Changes for v5:
- adjust to renamed exynos,interconnect-parent-node property,
- add properties in common exynos4412.dtsi file rather than
in Odroid specific odroid4412-odroid-common.dtsi.
---
arch/arm/boot/dts/exynos4412.dtsi | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/arch/arm/boot/dts/exynos4412.dtsi b/arch/arm/boot/dts/exynos4412.dtsi
index 4886894..a7496d3 100644
--- a/arch/arm/boot/dts/exynos4412.dtsi
+++ b/arch/arm/boot/dts/exynos4412.dtsi
@@ -381,6 +381,7 @@
clocks = <&clock CLK_DIV_DMC>;
clock-names = "bus";
operating-points-v2 = <&bus_dmc_opp_table>;
+ #interconnect-cells = <0>;
status = "disabled";
};
@@ -450,6 +451,8 @@
clocks = <&clock CLK_DIV_GDL>;
clock-names = "bus";
operating-points-v2 = <&bus_leftbus_opp_table>;
+ samsung,interconnect-parent = <&bus_dmc>;
+ #interconnect-cells = <0>;
status = "disabled";
};
@@ -466,6 +469,8 @@
clocks = <&clock CLK_ACLK160>;
clock-names = "bus";
operating-points-v2 = <&bus_display_opp_table>;
+ samsung,interconnect-parent = <&bus_leftbus>;
+ #interconnect-cells = <0>;
status = "disabled";
};
--
2.7.4
^ permalink raw reply related
* [RFC PATCH v5 3/6] PM / devfreq: exynos-bus: Add registration of interconnect child device
From: Sylwester Nawrocki @ 2020-05-29 16:31 UTC (permalink / raw)
To: georgi.djakov, cw00.choi, krzk
Cc: a.swigon, myungjoo.ham, inki.dae, sw0312.kim, b.zolnierkie,
m.szyprowski, s.nawrocki, linux-kernel, linux-samsung-soc,
dri-devel, linux-arm-kernel
In-Reply-To: <20200529163200.18031-1-s.nawrocki@samsung.com>
This patch adds registration of a child platform device for the exynos
interconnect driver. It is assumed that the interconnect provider will
only be needed when #interconnect-cells property is present in the bus
DT node, hence the child device will be created only when such a property
is present.
Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Changes for v5:
- new patch.
---
drivers/devfreq/exynos-bus.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/drivers/devfreq/exynos-bus.c b/drivers/devfreq/exynos-bus.c
index 8fa8eb5..856e37d 100644
--- a/drivers/devfreq/exynos-bus.c
+++ b/drivers/devfreq/exynos-bus.c
@@ -24,6 +24,7 @@
struct exynos_bus {
struct device *dev;
+ struct platform_device *icc_pdev;
struct devfreq *devfreq;
struct devfreq_event_dev **edev;
@@ -156,6 +157,8 @@ static void exynos_bus_exit(struct device *dev)
if (ret < 0)
dev_warn(dev, "failed to disable the devfreq-event devices\n");
+ platform_device_unregister(bus->icc_pdev);
+
dev_pm_opp_of_remove_table(dev);
clk_disable_unprepare(bus->clk);
if (bus->opp_table) {
@@ -168,6 +171,8 @@ static void exynos_bus_passive_exit(struct device *dev)
{
struct exynos_bus *bus = dev_get_drvdata(dev);
+ platform_device_unregister(bus->icc_pdev);
+
dev_pm_opp_of_remove_table(dev);
clk_disable_unprepare(bus->clk);
}
@@ -431,6 +436,18 @@ static int exynos_bus_probe(struct platform_device *pdev)
if (ret < 0)
goto err;
+ /* Create child platform device for the interconnect provider */
+ if (of_get_property(dev->of_node, "#interconnect-cells", NULL)) {
+ bus->icc_pdev = platform_device_register_data(
+ dev, "exynos-generic-icc",
+ PLATFORM_DEVID_AUTO, NULL, 0);
+
+ if (IS_ERR(bus->icc_pdev)) {
+ ret = PTR_ERR(bus->icc_pdev);
+ goto err;
+ }
+ }
+
max_state = bus->devfreq->profile->max_state;
min_freq = (bus->devfreq->profile->freq_table[0] / 1000);
max_freq = (bus->devfreq->profile->freq_table[max_state - 1] / 1000);
--
2.7.4
^ permalink raw reply related
* [RFC PATCH v5 6/6] drm: exynos: mixer: Add interconnect support
From: Sylwester Nawrocki @ 2020-05-29 16:32 UTC (permalink / raw)
To: georgi.djakov, cw00.choi, krzk
Cc: a.swigon, myungjoo.ham, inki.dae, sw0312.kim, b.zolnierkie,
m.szyprowski, s.nawrocki, linux-kernel, linux-samsung-soc,
dri-devel, linux-arm-kernel
In-Reply-To: <20200529163200.18031-1-s.nawrocki@samsung.com>
From: Marek Szyprowski <m.szyprowski@samsung.com>
This patch adds interconnect support to exynos-mixer. The mixer works
the same as before when CONFIG_INTERCONNECT is 'n'.
For proper operation of the video mixer block we need to ensure the
interconnect busses like DMC or LEFTBUS provide enough bandwidth so
as to avoid DMA buffer underruns in the mixer block. i.e we need to
prevent those busses from operating in low perfomance OPPs when
the mixer is running.
In this patch the bus bandwidth request is done through the interconnect
API, the bandiwidth value is calculated from selected DRM mode, i.e.
video plane width, height, refresh rate and pixel format.
Co-developed-by: Artur Świgoń <a.swigon@samsung.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
[s.nawrocki: renamed soc_path variable to icc_path, edited commit desc.]
Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
Changes for v5:
- renamed soc_path variable to icc_path
---
drivers/gpu/drm/exynos/exynos_mixer.c | 73 ++++++++++++++++++++++++++++++++---
1 file changed, 68 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
index 21b726b..bdae683 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -13,6 +13,7 @@
#include <linux/component.h>
#include <linux/delay.h>
#include <linux/i2c.h>
+#include <linux/interconnect.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/kernel.h>
@@ -98,6 +99,7 @@ struct mixer_context {
struct exynos_drm_crtc *crtc;
struct exynos_drm_plane planes[MIXER_WIN_NR];
unsigned long flags;
+ struct icc_path *icc_path;
int irq;
void __iomem *mixer_regs;
@@ -934,6 +936,42 @@ static void mixer_disable_vblank(struct exynos_drm_crtc *crtc)
mixer_reg_writemask(mixer_ctx, MXR_INT_EN, 0, MXR_INT_EN_VSYNC);
}
+static void mixer_set_memory_bandwidth(struct exynos_drm_crtc *crtc)
+{
+ struct drm_display_mode *mode = &crtc->base.state->adjusted_mode;
+ struct mixer_context *ctx = crtc->ctx;
+ unsigned long bw, bandwidth = 0;
+ u32 avg_bw, peak_bw;
+ int i, j, sub;
+
+ if (!ctx->icc_path)
+ return;
+
+ for (i = 0; i < MIXER_WIN_NR; i++) {
+ struct drm_plane *plane = &ctx->planes[i].base;
+ const struct drm_format_info *format;
+
+ if (plane->state && plane->state->crtc && plane->state->fb) {
+ format = plane->state->fb->format;
+ bw = mode->hdisplay * mode->vdisplay *
+ drm_mode_vrefresh(mode);
+ if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+ bw /= 2;
+ for (j = 0; j < format->num_planes; j++) {
+ sub = j ? (format->vsub * format->hsub) : 1;
+ bandwidth += format->cpp[j] * bw / sub;
+ }
+ }
+ }
+
+ /* add 20% safety margin */
+ bandwidth = bandwidth / 4 * 5;
+ dev_dbg(ctx->dev, "exynos-mixer: safe bandwidth %ld Bps\n", bandwidth);
+
+ avg_bw = peak_bw = Bps_to_icc(bandwidth);
+ icc_set_bw(ctx->icc_path, avg_bw, peak_bw);
+}
+
static void mixer_atomic_begin(struct exynos_drm_crtc *crtc)
{
struct mixer_context *ctx = crtc->ctx;
@@ -985,6 +1023,7 @@ static void mixer_atomic_flush(struct exynos_drm_crtc *crtc)
if (!test_bit(MXR_BIT_POWERED, &mixer_ctx->flags))
return;
+ mixer_set_memory_bandwidth(crtc);
mixer_enable_sync(mixer_ctx);
exynos_crtc_handle_event(crtc);
}
@@ -1032,6 +1071,7 @@ static void mixer_atomic_disable(struct exynos_drm_crtc *crtc)
for (i = 0; i < MIXER_WIN_NR; i++)
mixer_disable_plane(crtc, &ctx->planes[i]);
+ mixer_set_memory_bandwidth(crtc);
exynos_drm_pipe_clk_enable(crtc, false);
pm_runtime_put(ctx->dev);
@@ -1223,12 +1263,22 @@ static int mixer_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
const struct mixer_drv_data *drv;
struct mixer_context *ctx;
+ struct icc_path *path;
int ret;
+ /*
+ * Returns NULL if CONFIG_INTERCONNECT is disabled.
+ * May return ERR_PTR(-EPROBE_DEFER).
+ */
+ path = of_icc_get(dev, NULL);
+ if (IS_ERR(path))
+ return PTR_ERR(path);
+
ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
if (!ctx) {
DRM_DEV_ERROR(dev, "failed to alloc mixer context.\n");
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto err;
}
drv = of_device_get_match_data(dev);
@@ -1236,6 +1286,7 @@ static int mixer_probe(struct platform_device *pdev)
ctx->pdev = pdev;
ctx->dev = dev;
ctx->mxr_ver = drv->version;
+ ctx->icc_path = path;
if (drv->is_vp_enabled)
__set_bit(MXR_BIT_VP_ENABLED, &ctx->flags);
@@ -1245,17 +1296,29 @@ static int mixer_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, ctx);
ret = component_add(&pdev->dev, &mixer_component_ops);
- if (!ret)
- pm_runtime_enable(dev);
+ if (ret < 0)
+ goto err;
+
+ pm_runtime_enable(dev);
+
+ return 0;
+
+err:
+ icc_put(path);
return ret;
}
static int mixer_remove(struct platform_device *pdev)
{
- pm_runtime_disable(&pdev->dev);
+ struct device *dev = &pdev->dev;
+ struct mixer_context *ctx = dev_get_drvdata(dev);
+
+ pm_runtime_disable(dev);
+
+ component_del(dev, &mixer_component_ops);
- component_del(&pdev->dev, &mixer_component_ops);
+ icc_put(ctx->icc_path);
return 0;
}
--
2.7.4
^ permalink raw reply related
* [RFC PATCH v5 6/6] drm: exynos: mixer: Add interconnect support
From: Sylwester Nawrocki @ 2020-05-29 16:32 UTC (permalink / raw)
To: georgi.djakov, cw00.choi, krzk
Cc: linux-samsung-soc, b.zolnierkie, sw0312.kim, a.swigon, dri-devel,
linux-kernel, myungjoo.ham, s.nawrocki, linux-arm-kernel,
m.szyprowski
In-Reply-To: <20200529163200.18031-1-s.nawrocki@samsung.com>
From: Marek Szyprowski <m.szyprowski@samsung.com>
This patch adds interconnect support to exynos-mixer. The mixer works
the same as before when CONFIG_INTERCONNECT is 'n'.
For proper operation of the video mixer block we need to ensure the
interconnect busses like DMC or LEFTBUS provide enough bandwidth so
as to avoid DMA buffer underruns in the mixer block. i.e we need to
prevent those busses from operating in low perfomance OPPs when
the mixer is running.
In this patch the bus bandwidth request is done through the interconnect
API, the bandiwidth value is calculated from selected DRM mode, i.e.
video plane width, height, refresh rate and pixel format.
Co-developed-by: Artur Świgoń <a.swigon@samsung.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
[s.nawrocki: renamed soc_path variable to icc_path, edited commit desc.]
Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
Changes for v5:
- renamed soc_path variable to icc_path
---
drivers/gpu/drm/exynos/exynos_mixer.c | 73 ++++++++++++++++++++++++++++++++---
1 file changed, 68 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
index 21b726b..bdae683 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -13,6 +13,7 @@
#include <linux/component.h>
#include <linux/delay.h>
#include <linux/i2c.h>
+#include <linux/interconnect.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/kernel.h>
@@ -98,6 +99,7 @@ struct mixer_context {
struct exynos_drm_crtc *crtc;
struct exynos_drm_plane planes[MIXER_WIN_NR];
unsigned long flags;
+ struct icc_path *icc_path;
int irq;
void __iomem *mixer_regs;
@@ -934,6 +936,42 @@ static void mixer_disable_vblank(struct exynos_drm_crtc *crtc)
mixer_reg_writemask(mixer_ctx, MXR_INT_EN, 0, MXR_INT_EN_VSYNC);
}
+static void mixer_set_memory_bandwidth(struct exynos_drm_crtc *crtc)
+{
+ struct drm_display_mode *mode = &crtc->base.state->adjusted_mode;
+ struct mixer_context *ctx = crtc->ctx;
+ unsigned long bw, bandwidth = 0;
+ u32 avg_bw, peak_bw;
+ int i, j, sub;
+
+ if (!ctx->icc_path)
+ return;
+
+ for (i = 0; i < MIXER_WIN_NR; i++) {
+ struct drm_plane *plane = &ctx->planes[i].base;
+ const struct drm_format_info *format;
+
+ if (plane->state && plane->state->crtc && plane->state->fb) {
+ format = plane->state->fb->format;
+ bw = mode->hdisplay * mode->vdisplay *
+ drm_mode_vrefresh(mode);
+ if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+ bw /= 2;
+ for (j = 0; j < format->num_planes; j++) {
+ sub = j ? (format->vsub * format->hsub) : 1;
+ bandwidth += format->cpp[j] * bw / sub;
+ }
+ }
+ }
+
+ /* add 20% safety margin */
+ bandwidth = bandwidth / 4 * 5;
+ dev_dbg(ctx->dev, "exynos-mixer: safe bandwidth %ld Bps\n", bandwidth);
+
+ avg_bw = peak_bw = Bps_to_icc(bandwidth);
+ icc_set_bw(ctx->icc_path, avg_bw, peak_bw);
+}
+
static void mixer_atomic_begin(struct exynos_drm_crtc *crtc)
{
struct mixer_context *ctx = crtc->ctx;
@@ -985,6 +1023,7 @@ static void mixer_atomic_flush(struct exynos_drm_crtc *crtc)
if (!test_bit(MXR_BIT_POWERED, &mixer_ctx->flags))
return;
+ mixer_set_memory_bandwidth(crtc);
mixer_enable_sync(mixer_ctx);
exynos_crtc_handle_event(crtc);
}
@@ -1032,6 +1071,7 @@ static void mixer_atomic_disable(struct exynos_drm_crtc *crtc)
for (i = 0; i < MIXER_WIN_NR; i++)
mixer_disable_plane(crtc, &ctx->planes[i]);
+ mixer_set_memory_bandwidth(crtc);
exynos_drm_pipe_clk_enable(crtc, false);
pm_runtime_put(ctx->dev);
@@ -1223,12 +1263,22 @@ static int mixer_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
const struct mixer_drv_data *drv;
struct mixer_context *ctx;
+ struct icc_path *path;
int ret;
+ /*
+ * Returns NULL if CONFIG_INTERCONNECT is disabled.
+ * May return ERR_PTR(-EPROBE_DEFER).
+ */
+ path = of_icc_get(dev, NULL);
+ if (IS_ERR(path))
+ return PTR_ERR(path);
+
ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
if (!ctx) {
DRM_DEV_ERROR(dev, "failed to alloc mixer context.\n");
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto err;
}
drv = of_device_get_match_data(dev);
@@ -1236,6 +1286,7 @@ static int mixer_probe(struct platform_device *pdev)
ctx->pdev = pdev;
ctx->dev = dev;
ctx->mxr_ver = drv->version;
+ ctx->icc_path = path;
if (drv->is_vp_enabled)
__set_bit(MXR_BIT_VP_ENABLED, &ctx->flags);
@@ -1245,17 +1296,29 @@ static int mixer_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, ctx);
ret = component_add(&pdev->dev, &mixer_component_ops);
- if (!ret)
- pm_runtime_enable(dev);
+ if (ret < 0)
+ goto err;
+
+ pm_runtime_enable(dev);
+
+ return 0;
+
+err:
+ icc_put(path);
return ret;
}
static int mixer_remove(struct platform_device *pdev)
{
- pm_runtime_disable(&pdev->dev);
+ struct device *dev = &pdev->dev;
+ struct mixer_context *ctx = dev_get_drvdata(dev);
+
+ pm_runtime_disable(dev);
+
+ component_del(dev, &mixer_component_ops);
- component_del(&pdev->dev, &mixer_component_ops);
+ icc_put(ctx->icc_path);
return 0;
}
--
2.7.4
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply related
* [RFC PATCH v5 5/6] ARM: dts: exynos: Add interconnects to Exynos4412 mixer
From: Sylwester Nawrocki @ 2020-05-29 16:31 UTC (permalink / raw)
To: georgi.djakov, cw00.choi, krzk
Cc: a.swigon, myungjoo.ham, inki.dae, sw0312.kim, b.zolnierkie,
m.szyprowski, s.nawrocki, linux-kernel, linux-samsung-soc,
dri-devel, linux-arm-kernel
In-Reply-To: <20200529163200.18031-1-s.nawrocki@samsung.com>
From: Artur Świgoń <a.swigon@samsung.com>
This patch adds an 'interconnects' property to Exynos4412 DTS in order to
declare the interconnect path used by the mixer. Please note that the
'interconnect-names' property is not needed when there is only one path in
'interconnects', in which case calling of_icc_get() with a NULL name simply
returns the right path.
Signed-off-by: Artur Świgoń <a.swigon@samsung.com>
Reviewed-by: Chanwoo Choi <cw00.choi@samsung.com>
---
Changes for v5:
- none.
---
arch/arm/boot/dts/exynos4412.dtsi | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm/boot/dts/exynos4412.dtsi b/arch/arm/boot/dts/exynos4412.dtsi
index a7496d3..eee86d2 100644
--- a/arch/arm/boot/dts/exynos4412.dtsi
+++ b/arch/arm/boot/dts/exynos4412.dtsi
@@ -776,6 +776,7 @@
clock-names = "mixer", "hdmi", "sclk_hdmi", "vp";
clocks = <&clock CLK_MIXER>, <&clock CLK_HDMI>,
<&clock CLK_SCLK_HDMI>, <&clock CLK_VP>;
+ interconnects = <&bus_display &bus_dmc>;
};
&pmu {
--
2.7.4
^ permalink raw reply related
* [RFC PATCH v5 2/6] interconnect: Add generic interconnect driver for Exynos SoCs
From: Sylwester Nawrocki @ 2020-05-29 16:31 UTC (permalink / raw)
To: georgi.djakov, cw00.choi, krzk
Cc: a.swigon, myungjoo.ham, inki.dae, sw0312.kim, b.zolnierkie,
m.szyprowski, s.nawrocki, linux-kernel, linux-samsung-soc,
dri-devel, linux-arm-kernel
In-Reply-To: <20200529163200.18031-1-s.nawrocki@samsung.com>
This patch adds a generic interconnect driver for Exynos SoCs in order
to provide interconnect functionality for each "samsung,exynos-bus"
compatible device.
The SoC topology is a graph (or more specifically, a tree) and its
edges are specified using the 'samsung,interconnect-parent' in the
DT. Due to unspecified relative probing order, -EPROBE_DEFER may be
propagated to ensure that the parent is probed before its children.
Each bus is now an interconnect provider and an interconnect node as
well (cf. Documentation/interconnect/interconnect.rst), i.e. every bus
registers itself as a node. Node IDs are not hardcoded but rather
assigned dynamically at runtime. This approach allows for using this
driver with various Exynos SoCs.
Frequencies requested via the interconnect API for a given node are
propagated to devfreq using dev_pm_qos_update_request(). Please note
that it is not an error when CONFIG_INTERCONNECT is 'n', in which
case all interconnect API functions are no-op.
Signed-off-by: Artur Świgoń <a.swigon@samsung.com>
Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Changes for v5:
- adjust to renamed exynos,interconnect-parent-node property,
- use automatically generated platform device id as the interconect
node id instead of a now unavailable devfreq->id field,
- add icc_ prefix to some variables to make the code more self-commenting,
- use icc_nodes_remove() instead of icc_node_del() + icc_node_destroy(),
- adjust to exynos,interconnect-parent-node property rename to
samsung,interconnect-parent,
- converted to a separate platform driver in drivers/interconnect.
---
drivers/interconnect/Kconfig | 1 +
drivers/interconnect/Makefile | 1 +
drivers/interconnect/exynos/Kconfig | 6 ++
drivers/interconnect/exynos/Makefile | 4 +
drivers/interconnect/exynos/exynos.c | 185 +++++++++++++++++++++++++++++++++++
5 files changed, 197 insertions(+)
create mode 100644 drivers/interconnect/exynos/Kconfig
create mode 100644 drivers/interconnect/exynos/Makefile
create mode 100644 drivers/interconnect/exynos/exynos.c
diff --git a/drivers/interconnect/Kconfig b/drivers/interconnect/Kconfig
index 5b7204e..eca6eda 100644
--- a/drivers/interconnect/Kconfig
+++ b/drivers/interconnect/Kconfig
@@ -11,6 +11,7 @@ menuconfig INTERCONNECT
if INTERCONNECT
+source "drivers/interconnect/exynos/Kconfig"
source "drivers/interconnect/imx/Kconfig"
source "drivers/interconnect/qcom/Kconfig"
diff --git a/drivers/interconnect/Makefile b/drivers/interconnect/Makefile
index 4825c28..2ba1de6 100644
--- a/drivers/interconnect/Makefile
+++ b/drivers/interconnect/Makefile
@@ -4,5 +4,6 @@ CFLAGS_core.o := -I$(src)
icc-core-objs := core.o
obj-$(CONFIG_INTERCONNECT) += icc-core.o
+obj-$(CONFIG_INTERCONNECT_EXYNOS) += exynos/
obj-$(CONFIG_INTERCONNECT_IMX) += imx/
obj-$(CONFIG_INTERCONNECT_QCOM) += qcom/
diff --git a/drivers/interconnect/exynos/Kconfig b/drivers/interconnect/exynos/Kconfig
new file mode 100644
index 0000000..e51e52e
--- /dev/null
+++ b/drivers/interconnect/exynos/Kconfig
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0-only
+config INTERCONNECT_EXYNOS
+ tristate "Exynos generic interconnect driver"
+ depends on ARCH_EXYNOS || COMPILE_TEST
+ help
+ Generic interconnect driver for Exynos SoCs.
diff --git a/drivers/interconnect/exynos/Makefile b/drivers/interconnect/exynos/Makefile
new file mode 100644
index 0000000..e19d1df
--- /dev/null
+++ b/drivers/interconnect/exynos/Makefile
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
+exynos-interconnect-objs := exynos.o
+
+obj-$(CONFIG_INTERCONNECT_EXYNOS) += exynos-interconnect.o
diff --git a/drivers/interconnect/exynos/exynos.c b/drivers/interconnect/exynos/exynos.c
new file mode 100644
index 0000000..8278194
--- /dev/null
+++ b/drivers/interconnect/exynos/exynos.c
@@ -0,0 +1,185 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Exynos generic interconnect provider driver
+ *
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Authors: Artur Świgoń <a.swigon@samsung.com>
+ * Sylwester Nawrocki <s.nawrocki@samsung.com>
+ */
+#include <linux/device.h>
+#include <linux/interconnect-provider.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm_qos.h>
+
+#define kbps_to_khz(x) ((x) / 8)
+
+struct exynos_icc_priv {
+ struct device *dev;
+
+ /* One interconnect node per provider */
+ struct icc_provider provider;
+ struct icc_node *node;
+
+ struct dev_pm_qos_request qos_req;
+};
+
+static struct icc_node *exynos_icc_get_parent(struct device_node *np)
+{
+ struct of_phandle_args args;
+ int num, ret;
+
+ num = of_count_phandle_with_args(np, "samsung,interconnect-parent",
+ "#interconnect-cells");
+ if (num != 1)
+ return NULL; /* parent nodes are optional */
+
+ ret = of_parse_phandle_with_args(np, "samsung,interconnect-parent",
+ "#interconnect-cells", 0, &args);
+ if (ret < 0)
+ return ERR_PTR(ret);
+
+ of_node_put(args.np);
+
+ return of_icc_get_from_provider(&args);
+}
+
+
+static int exynos_generic_icc_set(struct icc_node *src, struct icc_node *dst)
+{
+ struct exynos_icc_priv *src_priv = src->data, *dst_priv = dst->data;
+ s32 src_freq = kbps_to_khz(max(src->avg_bw, src->peak_bw));
+ s32 dst_freq = kbps_to_khz(max(dst->avg_bw, dst->peak_bw));
+ int ret;
+
+ ret = dev_pm_qos_update_request(&src_priv->qos_req, src_freq);
+ if (ret < 0) {
+ dev_err(src_priv->dev, "failed to update PM QoS of %s\n",
+ src->name);
+ return ret;
+ }
+
+ ret = dev_pm_qos_update_request(&dst_priv->qos_req, dst_freq);
+ if (ret < 0) {
+ dev_err(dst_priv->dev, "failed to update PM QoS of %s\n",
+ dst->name);
+ return ret;
+ }
+
+ return 0;
+}
+
+static struct icc_node *exynos_generic_icc_xlate(struct of_phandle_args *spec,
+ void *data)
+{
+ struct exynos_icc_priv *priv = data;
+
+ if (spec->np != priv->dev->parent->of_node)
+ return ERR_PTR(-EINVAL);
+
+ return priv->node;
+}
+
+static int exynos_generic_icc_remove(struct platform_device *pdev)
+{
+ struct exynos_icc_priv *priv = platform_get_drvdata(pdev);
+ struct icc_node *parent_node, *node = priv->node;
+
+ parent_node = exynos_icc_get_parent(priv->dev->parent->of_node);
+ if (parent_node && !IS_ERR(parent_node))
+ icc_link_destroy(node, parent_node);
+
+ icc_nodes_remove(&priv->provider);
+ icc_provider_del(&priv->provider);
+
+ return 0;
+}
+
+static int exynos_generic_icc_probe(struct platform_device *pdev)
+{
+ struct device *bus_dev = pdev->dev.parent;
+ struct exynos_icc_priv *priv;
+ struct icc_provider *provider;
+ struct icc_node *icc_node, *icc_parent_node;
+ int ret;
+
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->dev = &pdev->dev;
+ platform_set_drvdata(pdev, priv);
+
+ provider = &priv->provider;
+
+ provider->set = exynos_generic_icc_set;
+ provider->aggregate = icc_std_aggregate;
+ provider->xlate = exynos_generic_icc_xlate;
+ provider->dev = bus_dev;
+ provider->inter_set = true;
+ provider->data = priv;
+
+ ret = icc_provider_add(provider);
+ if (ret < 0)
+ return ret;
+
+ icc_node = icc_node_create(pdev->id);
+ if (IS_ERR(icc_node)) {
+ ret = PTR_ERR(icc_node);
+ goto err_prov_del;
+ }
+
+ priv->node = icc_node;
+ icc_node->name = bus_dev->of_node->name;
+ icc_node->data = priv;
+ icc_node_add(icc_node, provider);
+
+ icc_parent_node = exynos_icc_get_parent(bus_dev->of_node);
+ if (IS_ERR(icc_parent_node)) {
+ ret = PTR_ERR(icc_parent_node);
+ goto err_node_del;
+ }
+ if (icc_parent_node) {
+ ret = icc_link_create(icc_node, icc_parent_node->id);
+ if (ret < 0)
+ goto err_node_del;
+ }
+
+ /*
+ * Register a PM QoS request for the bus device for which also devfreq
+ * functionality is registered.
+ */
+ ret = dev_pm_qos_add_request(bus_dev, &priv->qos_req,
+ DEV_PM_QOS_MIN_FREQUENCY, 0);
+ if (ret < 0)
+ goto err_link_destroy;
+
+ return 0;
+
+err_link_destroy:
+ if (icc_parent_node)
+ icc_link_destroy(icc_node, icc_parent_node);
+err_node_del:
+ icc_nodes_remove(provider);
+err_prov_del:
+ icc_provider_del(provider);
+
+ return ret;
+}
+
+static struct platform_driver exynos_generic_icc_driver = {
+ .driver = {
+ .name = "exynos-generic-icc",
+ },
+ .probe = exynos_generic_icc_probe,
+ .remove = exynos_generic_icc_remove,
+};
+module_platform_driver(exynos_generic_icc_driver);
+
+MODULE_DESCRIPTION("Exynos generic interconnect driver");
+MODULE_AUTHOR("Artur Świgoń <a.swigon@samsung.com>");
+MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:exynos-generic-icc");
--
2.7.4
^ permalink raw reply related
* [RFC PATCH v5 1/6] dt-bindings: exynos-bus: Add documentation for interconnect properties
From: Sylwester Nawrocki @ 2020-05-29 16:31 UTC (permalink / raw)
To: georgi.djakov, cw00.choi, krzk
Cc: a.swigon, myungjoo.ham, inki.dae, sw0312.kim, b.zolnierkie,
m.szyprowski, s.nawrocki, linux-kernel, linux-samsung-soc,
dri-devel, linux-arm-kernel
In-Reply-To: <20200529163200.18031-1-s.nawrocki@samsung.com>
Add documentation for new optional properties in the exynos bus nodes:
samsung,interconnect-parent, #interconnect-cells.
These properties allow to specify the SoC interconnect structure which
then allows the interconnect consumer devices to request specific
bandwidth requirements.
Signed-off-by: Artur Świgoń <a.swigon@samsung.com>
Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
Changes for v5:
- exynos,interconnect-parent-node renamed to samsung,interconnect-parent
---
Documentation/devicetree/bindings/devfreq/exynos-bus.txt | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/Documentation/devicetree/bindings/devfreq/exynos-bus.txt b/Documentation/devicetree/bindings/devfreq/exynos-bus.txt
index e71f752..e0d2daa 100644
--- a/Documentation/devicetree/bindings/devfreq/exynos-bus.txt
+++ b/Documentation/devicetree/bindings/devfreq/exynos-bus.txt
@@ -51,6 +51,11 @@ Optional properties only for parent bus device:
- exynos,saturation-ratio: the percentage value which is used to calibrate
the performance count against total cycle count.
+Optional properties for interconnect functionality (QoS frequency constraints):
+- samsung,interconnect-parent: phandle to the parent interconnect node; for
+ passive devices should point to same node as the exynos,parent-bus property.
+- #interconnect-cells: should be 0
+
Detailed correlation between sub-blocks and power line according to Exynos SoC:
- In case of Exynos3250, there are two power line as following:
VDD_MIF |--- DMC
@@ -185,8 +190,9 @@ Example1:
----------------------------------------------------------
Example2 :
- The bus of DMC (Dynamic Memory Controller) block in exynos3250.dtsi
- is listed below:
+ The bus of DMC (Dynamic Memory Controller) block in exynos3250.dtsi is
+ listed below. An interconnect path "bus_lcd0 -- bus_leftbus -- bus_dmc"
+ is defined for demonstration purposes.
bus_dmc: bus_dmc {
compatible = "samsung,exynos-bus";
@@ -376,12 +382,15 @@ Example2 :
&bus_dmc {
devfreq-events = <&ppmu_dmc0_3>, <&ppmu_dmc1_3>;
vdd-supply = <&buck1_reg>; /* VDD_MIF */
+ #interconnect-cells = <0>;
status = "okay";
};
&bus_leftbus {
devfreq-events = <&ppmu_leftbus_3>, <&ppmu_rightbus_3>;
vdd-supply = <&buck3_reg>;
+ samsung,interconnect-parent = <&bus_dmc>;
+ #interconnect-cells = <0>;
status = "okay";
};
@@ -392,6 +401,8 @@ Example2 :
&bus_lcd0 {
devfreq = <&bus_leftbus>;
+ samsung,interconnect-parent = <&bus_leftbus>;
+ #interconnect-cells = <0>;
status = "okay";
};
--
2.7.4
^ permalink raw reply related
* [RFC PATCH v5 0/6] Exynos: Simple QoS for exynos-bus using interconnect
From: Sylwester Nawrocki @ 2020-05-29 16:31 UTC (permalink / raw)
To: georgi.djakov, cw00.choi, krzk
Cc: linux-samsung-soc, b.zolnierkie, sw0312.kim, a.swigon, dri-devel,
linux-kernel, inki.dae, myungjoo.ham, s.nawrocki,
linux-arm-kernel, m.szyprowski
In-Reply-To: <CGME20200529163213eucas1p1ac148f9238214ac84f3d0cc199c4398b@eucas1p1.samsung.com>
This patchset adds interconnect API support for the Exynos SoC "samsung,
exynos-bus" compatible devices, which already have their corresponding
exynos-bus driver in the devfreq subsystem. Complementing the devfreq driver
with an interconnect functionality allows to ensure the QoS requirements
of devices accessing the system memory (e.g. video processing devices)
are fulfilled and to avoid issues like the one discussed in thread [1].
This patch series depends on 3 patches from Artur for the interconnect API
[2], which introduce following changes:
- exporting of_icc_get_from_provider() to avoid hard coding every graph
edge in the DT or driver source,
- relaxing the requirement on #interconnect-cells, so there is no need
to provide dummy node IDs in the DT,
- adding new field in struct icc_provider to explicitly allow configuring
node pairs from two different providers.
This series adds implementation of interconnect provider per each "samsung,
exynos-bus" compatible DT node, with one interconnect node per provider.
The interconnect code which was previously added as a part of the devfreq
driver has been converted to a separate platform driver. In the devfreq
a corresponding virtual child platform device is registered. Integration
of devfreq and interconnect frameworks is achieved through the PM QoS API.
A sample interconnect consumer for exynos-mixer is added in patches 5/6,
6/6, it is currently added only for exynos4412 and allows to address the
mixer DMA underrun error issues [1].
The series has been tested on Odroid U3 board. It is based on icc-next
branch with devfreq-next branch merged and patches [2] applied.
--
Regards,
Sylwester
--
Changes since v3 [3] (v4 skipped to align with patchset [1]), detailed
changes are listed at each patch:
- conversion to a separate interconnect (platform) driver,
- an update of the DT binding documenting new optional properties:
#interconnect-cells, samsung,interconnect-parent in "samsung,exynos-bus"
nodes,
- new DT properties added to the SoC, rather than to the board specific
files.
Changes since v2 [5]:
- Use icc_std_aggregate().
- Implement a different modification of apply_constraints() in
drivers/interconnect/core.c (patch 03).
- Use 'exynos,interconnect-parent-node' in the DT instead of
'devfreq'/'parent', depending on the bus.
- Rebase on DT patches that deprecate the 'devfreq' DT property.
- Improve error handling, including freeing generated IDs on failure.
- Remove exynos_bus_icc_connect() and add exynos_bus_icc_get_parent().
Changes since v1 [4]:
- Rebase on coupled regulators patches.
- Use dev_pm_qos_*() API instead of overriding frequency in
exynos_bus_target().
- Use IDR for node ID allocation.
- Reverse order of multiplication and division in
mixer_set_memory_bandwidth() (patch 07) to avoid integer overflow.
References:
[1] https://patchwork.kernel.org/patch/10861757/ (original issue)
[2] https://www.spinics.net/lists/linux-samsung-soc/msg70014.html
[3] https://lore.kernel.org/linux-pm/20191220115653.6487-1-a.swigon@samsung.com
[4] https://patchwork.kernel.org/cover/11054417/ (v1 of this RFC)
[5] https://patchwork.kernel.org/cover/11152595/ (v2 of this RFC)
Artur Świgoń (1):
ARM: dts: exynos: Add interconnects to Exynos4412 mixer
Marek Szyprowski (1):
drm: exynos: mixer: Add interconnect support
Sylwester Nawrocki (4):
dt-bindings: exynos-bus: Add documentation for interconnect properties
interconnect: Add generic interconnect driver for Exynos SoCs
PM / devfreq: exynos-bus: Add registration of interconnect child
device
ARM: dts: exynos: Add interconnect properties to Exynos4412 bus nodes
.../devicetree/bindings/devfreq/exynos-bus.txt | 15 +-
arch/arm/boot/dts/exynos4412.dtsi | 6 +
drivers/devfreq/exynos-bus.c | 17 ++
drivers/gpu/drm/exynos/exynos_mixer.c | 73 +++++++-
drivers/interconnect/Kconfig | 1 +
drivers/interconnect/Makefile | 1 +
drivers/interconnect/exynos/Kconfig | 6 +
drivers/interconnect/exynos/Makefile | 4 +
drivers/interconnect/exynos/exynos.c | 185 +++++++++++++++++++++
9 files changed, 301 insertions(+), 7 deletions(-)
create mode 100644 drivers/interconnect/exynos/Kconfig
create mode 100644 drivers/interconnect/exynos/Makefile
create mode 100644 drivers/interconnect/exynos/exynos.c
--
2.7.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [RFC PATCH v5 0/6] Exynos: Simple QoS for exynos-bus using interconnect
From: Sylwester Nawrocki @ 2020-05-29 16:31 UTC (permalink / raw)
To: georgi.djakov, cw00.choi, krzk
Cc: linux-samsung-soc, b.zolnierkie, sw0312.kim, a.swigon, dri-devel,
linux-kernel, myungjoo.ham, s.nawrocki, linux-arm-kernel,
m.szyprowski
In-Reply-To: <CGME20200529163213eucas1p1ac148f9238214ac84f3d0cc199c4398b@eucas1p1.samsung.com>
This patchset adds interconnect API support for the Exynos SoC "samsung,
exynos-bus" compatible devices, which already have their corresponding
exynos-bus driver in the devfreq subsystem. Complementing the devfreq driver
with an interconnect functionality allows to ensure the QoS requirements
of devices accessing the system memory (e.g. video processing devices)
are fulfilled and to avoid issues like the one discussed in thread [1].
This patch series depends on 3 patches from Artur for the interconnect API
[2], which introduce following changes:
- exporting of_icc_get_from_provider() to avoid hard coding every graph
edge in the DT or driver source,
- relaxing the requirement on #interconnect-cells, so there is no need
to provide dummy node IDs in the DT,
- adding new field in struct icc_provider to explicitly allow configuring
node pairs from two different providers.
This series adds implementation of interconnect provider per each "samsung,
exynos-bus" compatible DT node, with one interconnect node per provider.
The interconnect code which was previously added as a part of the devfreq
driver has been converted to a separate platform driver. In the devfreq
a corresponding virtual child platform device is registered. Integration
of devfreq and interconnect frameworks is achieved through the PM QoS API.
A sample interconnect consumer for exynos-mixer is added in patches 5/6,
6/6, it is currently added only for exynos4412 and allows to address the
mixer DMA underrun error issues [1].
The series has been tested on Odroid U3 board. It is based on icc-next
branch with devfreq-next branch merged and patches [2] applied.
--
Regards,
Sylwester
--
Changes since v3 [3] (v4 skipped to align with patchset [1]), detailed
changes are listed at each patch:
- conversion to a separate interconnect (platform) driver,
- an update of the DT binding documenting new optional properties:
#interconnect-cells, samsung,interconnect-parent in "samsung,exynos-bus"
nodes,
- new DT properties added to the SoC, rather than to the board specific
files.
Changes since v2 [5]:
- Use icc_std_aggregate().
- Implement a different modification of apply_constraints() in
drivers/interconnect/core.c (patch 03).
- Use 'exynos,interconnect-parent-node' in the DT instead of
'devfreq'/'parent', depending on the bus.
- Rebase on DT patches that deprecate the 'devfreq' DT property.
- Improve error handling, including freeing generated IDs on failure.
- Remove exynos_bus_icc_connect() and add exynos_bus_icc_get_parent().
Changes since v1 [4]:
- Rebase on coupled regulators patches.
- Use dev_pm_qos_*() API instead of overriding frequency in
exynos_bus_target().
- Use IDR for node ID allocation.
- Reverse order of multiplication and division in
mixer_set_memory_bandwidth() (patch 07) to avoid integer overflow.
References:
[1] https://patchwork.kernel.org/patch/10861757/ (original issue)
[2] https://www.spinics.net/lists/linux-samsung-soc/msg70014.html
[3] https://lore.kernel.org/linux-pm/20191220115653.6487-1-a.swigon@samsung.com
[4] https://patchwork.kernel.org/cover/11054417/ (v1 of this RFC)
[5] https://patchwork.kernel.org/cover/11152595/ (v2 of this RFC)
Artur Świgoń (1):
ARM: dts: exynos: Add interconnects to Exynos4412 mixer
Marek Szyprowski (1):
drm: exynos: mixer: Add interconnect support
Sylwester Nawrocki (4):
dt-bindings: exynos-bus: Add documentation for interconnect properties
interconnect: Add generic interconnect driver for Exynos SoCs
PM / devfreq: exynos-bus: Add registration of interconnect child
device
ARM: dts: exynos: Add interconnect properties to Exynos4412 bus nodes
.../devicetree/bindings/devfreq/exynos-bus.txt | 15 +-
arch/arm/boot/dts/exynos4412.dtsi | 6 +
drivers/devfreq/exynos-bus.c | 17 ++
drivers/gpu/drm/exynos/exynos_mixer.c | 73 +++++++-
drivers/interconnect/Kconfig | 1 +
drivers/interconnect/Makefile | 1 +
drivers/interconnect/exynos/Kconfig | 6 +
drivers/interconnect/exynos/Makefile | 4 +
drivers/interconnect/exynos/exynos.c | 185 +++++++++++++++++++++
9 files changed, 301 insertions(+), 7 deletions(-)
create mode 100644 drivers/interconnect/exynos/Kconfig
create mode 100644 drivers/interconnect/exynos/Makefile
create mode 100644 drivers/interconnect/exynos/exynos.c
--
2.7.4
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply
* [RFC PATCH v5 0/6] Exynos: Simple QoS for exynos-bus using interconnect
From: Sylwester Nawrocki @ 2020-05-29 16:31 UTC (permalink / raw)
To: georgi.djakov, cw00.choi, krzk
Cc: a.swigon, myungjoo.ham, inki.dae, sw0312.kim, b.zolnierkie,
m.szyprowski, s.nawrocki, linux-kernel, linux-samsung-soc,
dri-devel, linux-arm-kernel
In-Reply-To: <CGME20200529163213eucas1p1ac148f9238214ac84f3d0cc199c4398b@eucas1p1.samsung.com>
This patchset adds interconnect API support for the Exynos SoC "samsung,
exynos-bus" compatible devices, which already have their corresponding
exynos-bus driver in the devfreq subsystem. Complementing the devfreq driver
with an interconnect functionality allows to ensure the QoS requirements
of devices accessing the system memory (e.g. video processing devices)
are fulfilled and to avoid issues like the one discussed in thread [1].
This patch series depends on 3 patches from Artur for the interconnect API
[2], which introduce following changes:
- exporting of_icc_get_from_provider() to avoid hard coding every graph
edge in the DT or driver source,
- relaxing the requirement on #interconnect-cells, so there is no need
to provide dummy node IDs in the DT,
- adding new field in struct icc_provider to explicitly allow configuring
node pairs from two different providers.
This series adds implementation of interconnect provider per each "samsung,
exynos-bus" compatible DT node, with one interconnect node per provider.
The interconnect code which was previously added as a part of the devfreq
driver has been converted to a separate platform driver. In the devfreq
a corresponding virtual child platform device is registered. Integration
of devfreq and interconnect frameworks is achieved through the PM QoS API.
A sample interconnect consumer for exynos-mixer is added in patches 5/6,
6/6, it is currently added only for exynos4412 and allows to address the
mixer DMA underrun error issues [1].
The series has been tested on Odroid U3 board. It is based on icc-next
branch with devfreq-next branch merged and patches [2] applied.
--
Regards,
Sylwester
--
Changes since v3 [3] (v4 skipped to align with patchset [1]), detailed
changes are listed at each patch:
- conversion to a separate interconnect (platform) driver,
- an update of the DT binding documenting new optional properties:
#interconnect-cells, samsung,interconnect-parent in "samsung,exynos-bus"
nodes,
- new DT properties added to the SoC, rather than to the board specific
files.
Changes since v2 [5]:
- Use icc_std_aggregate().
- Implement a different modification of apply_constraints() in
drivers/interconnect/core.c (patch 03).
- Use 'exynos,interconnect-parent-node' in the DT instead of
'devfreq'/'parent', depending on the bus.
- Rebase on DT patches that deprecate the 'devfreq' DT property.
- Improve error handling, including freeing generated IDs on failure.
- Remove exynos_bus_icc_connect() and add exynos_bus_icc_get_parent().
Changes since v1 [4]:
- Rebase on coupled regulators patches.
- Use dev_pm_qos_*() API instead of overriding frequency in
exynos_bus_target().
- Use IDR for node ID allocation.
- Reverse order of multiplication and division in
mixer_set_memory_bandwidth() (patch 07) to avoid integer overflow.
References:
[1] https://patchwork.kernel.org/patch/10861757/ (original issue)
[2] https://www.spinics.net/lists/linux-samsung-soc/msg70014.html
[3] https://lore.kernel.org/linux-pm/20191220115653.6487-1-a.swigon@samsung.com
[4] https://patchwork.kernel.org/cover/11054417/ (v1 of this RFC)
[5] https://patchwork.kernel.org/cover/11152595/ (v2 of this RFC)
Artur Świgoń (1):
ARM: dts: exynos: Add interconnects to Exynos4412 mixer
Marek Szyprowski (1):
drm: exynos: mixer: Add interconnect support
Sylwester Nawrocki (4):
dt-bindings: exynos-bus: Add documentation for interconnect properties
interconnect: Add generic interconnect driver for Exynos SoCs
PM / devfreq: exynos-bus: Add registration of interconnect child
device
ARM: dts: exynos: Add interconnect properties to Exynos4412 bus nodes
.../devicetree/bindings/devfreq/exynos-bus.txt | 15 +-
arch/arm/boot/dts/exynos4412.dtsi | 6 +
drivers/devfreq/exynos-bus.c | 17 ++
drivers/gpu/drm/exynos/exynos_mixer.c | 73 +++++++-
drivers/interconnect/Kconfig | 1 +
drivers/interconnect/Makefile | 1 +
drivers/interconnect/exynos/Kconfig | 6 +
drivers/interconnect/exynos/Makefile | 4 +
drivers/interconnect/exynos/exynos.c | 185 +++++++++++++++++++++
9 files changed, 301 insertions(+), 7 deletions(-)
create mode 100644 drivers/interconnect/exynos/Kconfig
create mode 100644 drivers/interconnect/exynos/Makefile
create mode 100644 drivers/interconnect/exynos/exynos.c
--
2.7.4
^ permalink raw reply
* Re: [RFC v3 1/3] usb: dwc3: Resize TX FIFOs to meet EP bursting requirements
From: Jack Pham @ 2020-05-29 16:28 UTC (permalink / raw)
To: Wesley Cheng
Cc: robh+dt, bjorn.andersson, balbi, gregkh, agross, linux-kernel,
linux-arm-msm, devicetree, linux-usb
In-Reply-To: <1590630363-3934-2-git-send-email-wcheng@codeaurora.org>
Hi Wesley,
On Wed, May 27, 2020 at 06:46:01PM -0700, Wesley Cheng wrote:
> Some devices have USB compositions which may require multiple endpoints
> that support EP bursting. HW defined TX FIFO sizes may not always be
> sufficient for these compositions. By utilizing flexible TX FIFO
> allocation, this allows for endpoints to request the required FIFO depth to
> achieve higher bandwidth. With some higher bMaxBurst configurations, using
> a larger TX FIFO size results in better TX throughput.
>
> Ensure that one TX FIFO is reserved for every IN endpoint. This allows for
> the FIFO logic to prevent running out of FIFO space.
>
> Signed-off-by: Wesley Cheng <wcheng@codeaurora.org>
> ---
<snip>
> diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
> index 00746c2..9b09528 100644
> --- a/drivers/usb/dwc3/gadget.c
> +++ b/drivers/usb/dwc3/gadget.c
> @@ -540,6 +540,117 @@ static int dwc3_gadget_start_config(struct dwc3_ep *dep)
> return 0;
> }
>
> +/*
> + * dwc3_gadget_resize_tx_fifos - reallocate fifo spaces for current use-case
> + * @dwc: pointer to our context structure
> + *
> + * This function will a best effort FIFO allocation in order
> + * to improve FIFO usage and throughput, while still allowing
> + * us to enable as many endpoints as possible.
> + *
> + * Keep in mind that this operation will be highly dependent
> + * on the configured size for RAM1 - which contains TxFifo -,
> + * the amount of endpoints enabled on coreConsultant tool, and
> + * the width of the Master Bus.
> + *
> + * In general, FIFO depths are represented with the following equation:
> + *
> + * fifo_size = mult * ((max_packet + mdwidth)/mdwidth + 1) + 1
> + *
> + * Conversions can be done to the equation to derive the number of packets that
> + * will fit to a particular FIFO size value.
> + */
> +static int dwc3_gadget_resize_tx_fifos(struct dwc3 *dwc, struct dwc3_ep *dep)
The 'dep' param should be sufficient; we can just get 'dwc' from
dep->dwc. That will make it more clear this function operates on each
endpoint that needs resizing.
> +{
> + int ram1_depth, mdwidth, fifo_0_start, tmp, num_in_ep;
> + int min_depth, remaining, fifo_size, mult = 1, fifo, max_packet = 1024;
> +
> + if (!dwc->needs_fifo_resize)
> + return 0;
> +
> + /* resize IN endpoints except ep0 */
> + if (!usb_endpoint_dir_in(dep->endpoint.desc) || dep->number <= 1)
> + return 0;
> +
> + /* Don't resize already resized IN endpoint */
> + if (dep->fifo_depth)
> + return 0;
> +
> + ram1_depth = DWC3_RAM1_DEPTH(dwc->hwparams.hwparams7);
> + mdwidth = DWC3_MDWIDTH(dwc->hwparams.hwparams0);
> + /* MDWIDTH is represented in bits, we need it in bytes */
> + mdwidth >>= 3;
> +
> + if (((dep->endpoint.maxburst > 1) &&
> + usb_endpoint_xfer_bulk(dep->endpoint.desc))
> + || usb_endpoint_xfer_isoc(dep->endpoint.desc))
> + mult = 3;
> +
> + if ((dep->endpoint.maxburst > 6) &&
> + usb_endpoint_xfer_bulk(dep->endpoint.desc)
> + && dwc3_is_usb31(dwc))
> + mult = 6;
> +
> + /* FIFO size for a single buffer */
> + fifo = (max_packet + mdwidth)/mdwidth;
> + fifo++;
> +
> + /* Calculate the number of remaining EPs w/o any FIFO */
> + num_in_ep = dwc->num_eps/2;
> + num_in_ep -= dwc->num_ep_resized;
> + /* Ignore EP0 IN */
> + num_in_ep--;
> +
> + /* Reserve at least one FIFO for the number of IN EPs */
> + min_depth = num_in_ep * (fifo+1);
> + remaining = ram1_depth - min_depth - dwc->last_fifo_depth;
> +
> + /* We've already reserved 1 FIFO per EP, so check what we can fit in
> + * addition to it. If there is not enough remaining space, allocate
> + * all the remaining space to the EP.
> + */
> + fifo_size = (mult-1) * fifo;
> + if (remaining < fifo_size) {
> + if (remaining > 0)
> + fifo_size = remaining;
> + else
> + fifo_size = 0;
> + }
> +
> + fifo_size += fifo;
> + fifo_size++;
> + dep->fifo_depth = fifo_size;
> +
> + /* Check if TXFIFOs start at non-zero addr */
> + tmp = dwc3_readl(dwc->regs, DWC3_GTXFIFOSIZ(0));
> + fifo_0_start = DWC3_GTXFIFOSIZ_TXFSTADDR(tmp);
> +
> + fifo_size |= (fifo_0_start + (dwc->last_fifo_depth << 16));
> + if (dwc3_is_usb31(dwc))
> + dwc->last_fifo_depth += DWC31_GTXFIFOSIZ_TXFDEP(fifo_size);
> + else
> + dwc->last_fifo_depth += DWC3_GTXFIFOSIZ_TXFDEP(fifo_size);
> +
> + /* Check fifo size allocation doesn't exceed available RAM size. */
> + if (dwc->last_fifo_depth >= ram1_depth) {
> + dev_err(dwc->dev, "Fifosize(%d) > RAM size(%d) %s depth:%d\n",
> + (dwc->last_fifo_depth * mdwidth), ram1_depth,
> + dep->endpoint.name, fifo_size);
Use dev_WARN() here and eliminate the WARN_ON(1) below?
> + if (dwc3_is_usb31(dwc))
> + fifo_size = DWC31_GTXFIFOSIZ_TXFDEP(fifo_size);
> + else
> + fifo_size = DWC3_GTXFIFOSIZ_TXFDEP(fifo_size);
> + dwc->last_fifo_depth -= fifo_size;
> + dep->fifo_depth = 0;
> + WARN_ON(1);
> + return -ENOMEM;
> + }
> +
> + dwc3_writel(dwc->regs, DWC3_GTXFIFOSIZ(dep->number >> 1), fifo_size);
> + dwc->num_ep_resized++;
> + return 0;
> +}
> +
> static int dwc3_gadget_set_ep_config(struct dwc3_ep *dep, unsigned int action)
> {
> const struct usb_ss_ep_comp_descriptor *comp_desc;
> @@ -620,6 +731,10 @@ static int __dwc3_gadget_ep_enable(struct dwc3_ep *dep, unsigned int action)
> int ret;
>
> if (!(dep->flags & DWC3_EP_ENABLED)) {
> + ret = dwc3_gadget_resize_tx_fifos(dwc, dep);
> + if (ret)
> + return ret;
> +
> ret = dwc3_gadget_start_config(dep);
> if (ret)
> return ret;
Jack
--
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.