* Re: [PATCH v4 06/13] mips: Add CP0 Write Merge config support
From: Thomas Bogendoerfer @ 2020-05-22 7:28 UTC (permalink / raw)
To: Serge Semin
Cc: Serge Semin, Alexey Malahov, Paul Burton, Ralf Baechle,
Arnd Bergmann, Rob Herring, devicetree, Jiaxun Yang,
Philippe Mathieu-Daudé, Huacai Chen, Paul Cercueil,
Masahiro Yamada, Zhou Yanjie, WANG Xuerui,
周琰杰 (Zhou Yanjie), YunQiang Su,
Liangliang Huang, Thomas Gleixner, linux-mips, linux-kernel
In-Reply-To: <20200521140725.29571-7-Sergey.Semin@baikalelectronics.ru>
On Thu, May 21, 2020 at 05:07:17PM +0300, Serge Semin wrote:
> CP0 config register may indicate whether write-through merging
> is allowed. Currently there are two types of the merging available:
> SysAD Valid and Full modes. Whether each of them are supported by
> the core is implementation dependent. Moreover whether the ability
> to change the mode also depends on the chip family instance. Taking
> into account all of this we created a dedicated mm_config() method
> to detect and enable merging if it's supported. It is called for
> MIPS-type processors at CPU-probe stage and attempts to detect whether
> the write merging is available. If it's known to be supported and
> switchable, then switch on the full mode. Otherwise just perform the
> CP0.Config.MM field analysis.
>
> In addition there are platforms like InterAptiv/ProAptiv, which do have
> the MM bit field set by default, but having write-through cacheing
> unsupported makes write-merging also unsupported. In this case we just
> ignore the MM field value.
>
> Co-developed-by: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru>
> Signed-off-by: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru>
> Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
> Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
> Cc: Paul Burton <paulburton@kernel.org>
> Cc: Ralf Baechle <ralf@linux-mips.org>
> Cc: Arnd Bergmann <arnd@arndb.de>
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: devicetree@vger.kernel.org
> ---
> arch/mips/include/asm/cpu-features.h | 8 +++++
> arch/mips/include/asm/cpu.h | 4 ++-
> arch/mips/include/asm/mipsregs.h | 3 ++
> arch/mips/kernel/cpu-probe.c | 48 ++++++++++++++++++++++++++++
> 4 files changed, 62 insertions(+), 1 deletion(-)
applied to mips-next.
Thomas.
--
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea. [ RFC1925, 2.3 ]
^ permalink raw reply
* Re: [PATCH v4 11/13] mips: Add udelay lpj numbers adjustment
From: Thomas Bogendoerfer @ 2020-05-22 7:29 UTC (permalink / raw)
To: Serge Semin
Cc: Serge Semin, Alexey Malahov, Jiaxun Yang, Paul Burton,
Ralf Baechle, Arnd Bergmann, Rob Herring, devicetree,
Allison Randal, Thomas Gleixner, linux-mips, linux-kernel
In-Reply-To: <20200521140725.29571-12-Sergey.Semin@baikalelectronics.ru>
On Thu, May 21, 2020 at 05:07:22PM +0300, Serge Semin wrote:
> Loops-per-jiffies is a special number which represents a number of
> noop-loop cycles per CPU-scheduler quantum - jiffies. As you
> understand aside from CPU-specific implementation it depends on
> the CPU frequency. So when a platform has the CPU frequency fixed,
> we have no problem and the current udelay interface will work
> just fine. But as soon as CPU-freq driver is enabled and the cores
> frequency changes, we'll end up with distorted udelay's. In order
> to fix this we have to accordinly adjust the per-CPU udelay_val
> (the same as the global loops_per_jiffy) number. This can be done
> in the CPU-freq transition event handler. We subscribe to that event
> in the MIPS arch time-inititalization method.
>
> Co-developed-by: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru>
> Signed-off-by: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru>
> Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
> Reviewed-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
> Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
> Cc: Paul Burton <paulburton@kernel.org>
> Cc: Ralf Baechle <ralf@linux-mips.org>
> Cc: Arnd Bergmann <arnd@arndb.de>
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: devicetree@vger.kernel.org
> ---
> arch/mips/kernel/time.c | 70 +++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 70 insertions(+)
applied to mips-next.
Thomas.
--
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea. [ RFC1925, 2.3 ]
^ permalink raw reply
* Re: [PATCH v4 08/13] mips: Add CPS_NS16550_WIDTH config
From: Thomas Bogendoerfer @ 2020-05-22 7:29 UTC (permalink / raw)
To: Serge Semin
Cc: Serge Semin, Alexey Malahov, Paul Burton, Ralf Baechle,
Arnd Bergmann, Rob Herring, devicetree,
Philippe Mathieu-Daudé, Thomas Gleixner, Allison Randal,
Greg Kroah-Hartman, linux-mips, linux-kernel
In-Reply-To: <20200521140725.29571-9-Sergey.Semin@baikalelectronics.ru>
On Thu, May 21, 2020 at 05:07:19PM +0300, Serge Semin wrote:
> On some platforms IO-memory might require to use a proper load/store
> instructions (like Baikal-T1 IO-memory). To fix the cps-vec UART debug
> printout let's add the CONFIG_CPS_NS16550_WIDTH config to determine which
> instructions lb/sb, lh/sh or lw/sw are required for MMIO operations.
>
> Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
> Cc: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru>
> Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
> Cc: Paul Burton <paulburton@kernel.org>
> Cc: Ralf Baechle <ralf@linux-mips.org>
> Cc: Arnd Bergmann <arnd@arndb.de>
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: devicetree@vger.kernel.org
> ---
> arch/mips/Kconfig.debug | 10 ++++++++++
> arch/mips/kernel/cps-vec-ns16550.S | 18 ++++++++++++++++--
> 2 files changed, 26 insertions(+), 2 deletions(-)
applied to mips-next.
Thomas.
--
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea. [ RFC1925, 2.3 ]
^ permalink raw reply
* Re: [PATCH 5/5] dt-bindings: timer: Add CLINT bindings
From: Anup Patel @ 2020-05-22 6:36 UTC (permalink / raw)
To: Sean Anderson
Cc: Anup Patel, Palmer Dabbelt, Paul Walmsley, Albert Ou, Rob Herring,
Daniel Lezcano, Thomas Gleixner, devicetree, Damien Le Moal,
linux-kernel@vger.kernel.org List, Atish Patra, Alistair Francis,
linux-riscv
In-Reply-To: <c0e9e625-daf8-b72f-2237-06018ff5d8a0@gmail.com>
On Fri, May 22, 2020 at 11:59 AM Sean Anderson <seanga2@gmail.com> wrote:
>
> On 5/22/20 1:54 AM, Anup Patel wrote:
> > On Fri, May 22, 2020 at 1:35 AM Sean Anderson <seanga2@gmail.com> wrote:
> >>
> >> On 5/21/20 9:45 AM, Anup Patel wrote:
> >>> +Required properties:
> >>> +- compatible : "sifive,clint-1.0.0" and a string identifying the actual
> >>> + detailed implementation in case that specific bugs need to be worked around.
> >>
> >> Should the "riscv,clint0" compatible string be documented here? This
> >
> > Yes, I forgot to add this compatible string. I will add in v2.
> >
> >> peripheral is not really specific to sifive, as it is present in most
> >> rocket-chip cores.
> >
> > I agree that CLINT is present in a lot of non-SiFive RISC-V SOCs and
> > FPGAs but this IP is only documented as part of SiFive FU540 SOC.
> > (Refer, https://static.dev.sifive.com/FU540-C000-v1.0.pdf)
> >
> > The RISC-V foundation should host the CLINT spec independently
> > under https://github.com/riscv and make CLINT spec totally open.
> >
> > For now, I have documented it just like PLIC DT bindings found at:
> > Documentation/devicetree/bindings/interrupt-controller/sifive,plic-1.0.0.txt
>
> The PLIC seems to have its own RISC-V-sponsored documentation [1] which
> was split off from the older privileged specs. By your logic above,
> should it be renamed to riscv,plic0.txt (with a corresponding change in
> the documented compatible strings)?
>
> [1] https://github.com/riscv/riscv-plic-spec
For PLIC bindings, we can certainly do the renaming because now
we have PLIC v1 specification hosted on RISC-V Foundation Github.
Regards,
Anup
^ permalink raw reply
* Re: [PATCH 5/5] dt-bindings: timer: Add CLINT bindings
From: Sean Anderson @ 2020-05-22 6:29 UTC (permalink / raw)
To: Anup Patel
Cc: Anup Patel, Palmer Dabbelt, Paul Walmsley, Albert Ou, Rob Herring,
Daniel Lezcano, Thomas Gleixner, devicetree, Damien Le Moal,
linux-kernel@vger.kernel.org List, Atish Patra, Alistair Francis,
linux-riscv
In-Reply-To: <CAAhSdy0OuxCwMVPBrvPpYMfVrhUuY3pONysk75yognOM5-0U+g@mail.gmail.com>
On 5/22/20 1:54 AM, Anup Patel wrote:
> On Fri, May 22, 2020 at 1:35 AM Sean Anderson <seanga2@gmail.com> wrote:
>>
>> On 5/21/20 9:45 AM, Anup Patel wrote:
>>> +Required properties:
>>> +- compatible : "sifive,clint-1.0.0" and a string identifying the actual
>>> + detailed implementation in case that specific bugs need to be worked around.
>>
>> Should the "riscv,clint0" compatible string be documented here? This
>
> Yes, I forgot to add this compatible string. I will add in v2.
>
>> peripheral is not really specific to sifive, as it is present in most
>> rocket-chip cores.
>
> I agree that CLINT is present in a lot of non-SiFive RISC-V SOCs and
> FPGAs but this IP is only documented as part of SiFive FU540 SOC.
> (Refer, https://static.dev.sifive.com/FU540-C000-v1.0.pdf)
>
> The RISC-V foundation should host the CLINT spec independently
> under https://github.com/riscv and make CLINT spec totally open.
>
> For now, I have documented it just like PLIC DT bindings found at:
> Documentation/devicetree/bindings/interrupt-controller/sifive,plic-1.0.0.txt
The PLIC seems to have its own RISC-V-sponsored documentation [1] which
was split off from the older privileged specs. By your logic above,
should it be renamed to riscv,plic0.txt (with a corresponding change in
the documented compatible strings)?
[1] https://github.com/riscv/riscv-plic-spec
>
> If RISC-V maintainers agree then I will document it as "RISC-V CLINT".
>
> @Palmer ?? @Paul ??
>
> Regards,
> Anup
>
--Sean
^ permalink raw reply
* Re: [PATCH v8 5/5] dt-bindings: arm: fsl: add different Protonic boards
From: Oleksij Rempel @ 2020-05-22 6:03 UTC (permalink / raw)
To: robh
Cc: Mark Rutland, devicetree, Shawn Guo, Sascha Hauer, linux-kernel,
Rob Herring, NXP Linux Team, Pengutronix Kernel Team,
Fabio Estevam, linux-arm-kernel
In-Reply-To: <20200521200002.GA2800876@bogus>
[-- Attachment #1: Type: text/plain, Size: 1050 bytes --]
On Thu, May 21, 2020 at 02:00:02PM -0600, robh@kernel.org wrote:
> On Wed, 20 May 2020 17:41:16 +0200, Oleksij Rempel wrote:
> > Add Protonic PRTI6Q, WD2, RVT, VT7 boards.
> >
> > Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
> > ---
> > Documentation/devicetree/bindings/arm/fsl.yaml | 4 ++++
> > 1 file changed, 4 insertions(+)
> >
>
>
> Please add Acked-by/Reviewed-by tags when posting new versions. However,
> there's no need to repost patches *only* to add the tags. The upstream
> maintainer will do that for acks received on the version they apply.
>
> If a tag was not added on purpose, please state why and what changed.
Sorry, there is no special reason. I just missed it.
Regards,
Oleksij
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply
* Re: [RFC PATCH V4 1/4] media: v4l2-mem2mem: add v4l2_m2m_suspend, v4l2_m2m_resume
From: Jerry-ch Chen @ 2020-05-22 6:01 UTC (permalink / raw)
To: Tomasz Figa
Cc: Hans Verkuil, laurent.pinchart+renesas, matthias.bgg, mchehab,
pihsun, yuzhao, zwisler, linux-mediatek, linux-arm-kernel,
Sean.Cheng, sj.huang, christie.yu, frederic.chen, jungo.lin,
Rynn.Wu, linux-media, srv_heupstream, devicetree, Jerry-ch Chen
In-Reply-To: <20200521171101.GA243874@chromium.org>
Hi Tomasz,
On Thu, 2020-05-21 at 17:11 +0000, Tomasz Figa wrote:
> Hi Jerry,
>
> On Wed, Dec 04, 2019 at 08:47:29PM +0800, Jerry-ch Chen wrote:
> > From: Pi-Hsun Shih <pihsun@chromium.org>
> >
> > Add two functions that can be used to stop new jobs from being queued /
> > continue running queued job. This can be used while a driver using m2m
> > helper is going to suspend / wake up from resume, and can ensure that
> > there's no job running in suspend process.
> >
> > BUG=b:143046833
> > TEST=build
> >
> > Signed-off-by: Pi-Hsun Shih <pihsun@chromium.org>
> > Signed-off-by: Jerry-ch Chen <jerry-ch.chen@mediatek.corp-partner.google.com>
> > ---
> > drivers/media/v4l2-core/v4l2-mem2mem.c | 40 ++++++++++++++++++++++++++
> > include/media/v4l2-mem2mem.h | 22 ++++++++++++++
> > 2 files changed, 62 insertions(+)
> >
> > diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
> > index 5bbdec55b7d7..76ba203e0035 100644
> > --- a/drivers/media/v4l2-core/v4l2-mem2mem.c
> > +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
> > @@ -47,6 +47,10 @@ module_param(debug, bool, 0644);
> > #define TRANS_ABORT (1 << 2)
> >
> >
> > +/* The job queue is not running new jobs */
> > +#define QUEUE_PAUSED (1 << 0)
> > +
> > +
> > /* Offset base for buffers on the destination queue - used to distinguish
> > * between source and destination buffers when mmapping - they receive the same
> > * offsets but for different queues */
> > @@ -88,6 +92,7 @@ static const char * const m2m_entity_name[] = {
> > * @job_queue: instances queued to run
> > * @job_spinlock: protects job_queue
> > * @job_work: worker to run queued jobs.
> > + * @job_queue_flags: flags of the queue status, %QUEUE_PAUSED.
> > * @m2m_ops: driver callbacks
> > */
> > struct v4l2_m2m_dev {
> > @@ -105,6 +110,7 @@ struct v4l2_m2m_dev {
> > struct list_head job_queue;
> > spinlock_t job_spinlock;
> > struct work_struct job_work;
> > + unsigned long job_queue_flags;
> >
> > const struct v4l2_m2m_ops *m2m_ops;
> > };
> > @@ -267,6 +273,12 @@ static void v4l2_m2m_try_run(struct v4l2_m2m_dev *m2m_dev)
> > return;
> > }
> >
> > + if (m2m_dev->job_queue_flags & QUEUE_PAUSED) {
> > + spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags);
> > + dprintk("Running new jobs is paused\n");
> > + return;
> > + }
> > +
> > m2m_dev->curr_ctx = list_first_entry(&m2m_dev->job_queue,
> > struct v4l2_m2m_ctx, queue);
> > m2m_dev->curr_ctx->job_flags |= TRANS_RUNNING;
> > @@ -447,6 +459,34 @@ void v4l2_m2m_job_finish(struct v4l2_m2m_dev *m2m_dev,
> > }
> > EXPORT_SYMBOL(v4l2_m2m_job_finish);
> >
> > +void v4l2_m2m_suspend(struct v4l2_m2m_dev *m2m_dev)
> > +{
> > + unsigned long flags;
> > + struct v4l2_m2m_ctx *curr_ctx;
> > +
> > + spin_lock_irqsave(&m2m_dev->job_spinlock, flags);
> > + m2m_dev->job_queue_flags |= QUEUE_PAUSED;
> > + curr_ctx = m2m_dev->curr_ctx;
> > + spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags);
> > +
> > + if (curr_ctx)
> > + wait_event(curr_ctx->finished,
> > + !(curr_ctx->job_flags & TRANS_RUNNING));
> > +}
> > +EXPORT_SYMBOL(v4l2_m2m_suspend);
> > +
> > +void v4l2_m2m_resume(struct v4l2_m2m_dev *m2m_dev)
> > +{
> > + unsigned long flags;
> > +
> > + spin_lock_irqsave(&m2m_dev->job_spinlock, flags);
> > + m2m_dev->job_queue_flags &= ~QUEUE_PAUSED;
> > + spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags);
> > +
> > + v4l2_m2m_try_run(m2m_dev);
> > +}
> > +EXPORT_SYMBOL(v4l2_m2m_resume);
> > +
> > int v4l2_m2m_reqbufs(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
> > struct v4l2_requestbuffers *reqbufs)
> > {
> > diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h
> > index 5467264771ec..119a195da390 100644
> > --- a/include/media/v4l2-mem2mem.h
> > +++ b/include/media/v4l2-mem2mem.h
> > @@ -183,6 +183,28 @@ v4l2_m2m_buf_done(struct vb2_v4l2_buffer *buf, enum vb2_buffer_state state)
> > vb2_buffer_done(&buf->vb2_buf, state);
> > }
> >
> > +/**
> > + * v4l2_m2m_suspend() - stop new jobs from being run and wait for current job
> > + * to finish
> > + *
> > + * @m2m_dev: opaque pointer to the internal data to handle M2M context
> > + *
> > + * Called by a driver in the suspend hook. Stop new jobs from being run, and
> > + * wait for current running job to finish.
> > + */
> > +void v4l2_m2m_suspend(struct v4l2_m2m_dev *m2m_dev);
> > +
> > +/**
> > + * v4l2_m2m_resume() - resume job running and try to run a queued job
> > + *
> > + * @m2m_dev: opaque pointer to the internal data to handle M2M context
> > + *
> > + * Called by a driver in the resume hook. This reverts the operation of
> > + * v4l2_m2m_suspend() and allows job to be run. Also try to run a queued job if
> > + * there is any.
> > + */
> > +void v4l2_m2m_resume(struct v4l2_m2m_dev *m2m_dev);
> > +
> > /**
> > * v4l2_m2m_reqbufs() - multi-queue-aware REQBUFS multiplexer
> > *
> > --
> > 2.18.0
>
> Reviewed-by: Tomasz Figa <tfiga@chromium.org>
>
Ok, I've added it in the commit message.
Thanks and Best regards,
Jerry
> [Corrected Hans's email address.]
> Hans, does this look good to you?
>
> Best regards,
> Tomasz
>
^ permalink raw reply
* Re: [PATCH 5/5] dt-bindings: timer: Add CLINT bindings
From: Anup Patel @ 2020-05-22 5:54 UTC (permalink / raw)
To: Sean Anderson
Cc: Anup Patel, Palmer Dabbelt, Paul Walmsley, Albert Ou, Rob Herring,
Daniel Lezcano, Thomas Gleixner, devicetree, Damien Le Moal,
linux-kernel@vger.kernel.org List, Atish Patra, Alistair Francis,
linux-riscv
In-Reply-To: <2aec08b7-7197-4b60-89d9-c3b0d5a8a258@gmail.com>
On Fri, May 22, 2020 at 1:35 AM Sean Anderson <seanga2@gmail.com> wrote:
>
> On 5/21/20 9:45 AM, Anup Patel wrote:
> > We add DT bindings documentation for CLINT device.
> >
> > Signed-off-by: Anup Patel <anup.patel@wdc.com>
> > ---
> > .../bindings/timer/sifive,clint.txt | 33 +++++++++++++++++++
> > 1 file changed, 33 insertions(+)
> > create mode 100644 Documentation/devicetree/bindings/timer/sifive,clint.txt
> >
> > diff --git a/Documentation/devicetree/bindings/timer/sifive,clint.txt b/Documentation/devicetree/bindings/timer/sifive,clint.txt
> > new file mode 100644
> > index 000000000000..cae2dad1223a
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/timer/sifive,clint.txt
> > @@ -0,0 +1,33 @@
> > +SiFive Core Local Interruptor (CLINT)
> > +-------------------------------------
> > +
> > +SiFive (and other RISC-V) SOCs include an implementation of the SiFive Core
> > +Local Interruptor (CLINT) for M-mode timer and inter-processor interrupts.
> > +
> > +It directly connects to the timer and inter-processor interrupt lines of
> > +various HARTs (or CPUs) so RISC-V per-HART (or per-CPU) local interrupt
> > +controller is the parent interrupt controller for CLINT device.
> > +
> > +The clock frequency of CLINT is specified via "timebase-frequency" DT
> > +property of "/cpus" DT node. The "timebase-frequency" DT property is
> > +described in: Documentation/devicetree/bindings/riscv/cpus.yaml
> > +
> > +Required properties:
> > +- compatible : "sifive,clint-1.0.0" and a string identifying the actual
> > + detailed implementation in case that specific bugs need to be worked around.
>
> Should the "riscv,clint0" compatible string be documented here? This
Yes, I forgot to add this compatible string. I will add in v2.
> peripheral is not really specific to sifive, as it is present in most
> rocket-chip cores.
I agree that CLINT is present in a lot of non-SiFive RISC-V SOCs and
FPGAs but this IP is only documented as part of SiFive FU540 SOC.
(Refer, https://static.dev.sifive.com/FU540-C000-v1.0.pdf)
The RISC-V foundation should host the CLINT spec independently
under https://github.com/riscv and make CLINT spec totally open.
For now, I have documented it just like PLIC DT bindings found at:
Documentation/devicetree/bindings/interrupt-controller/sifive,plic-1.0.0.txt
If RISC-V maintainers agree then I will document it as "RISC-V CLINT".
@Palmer ?? @Paul ??
>
> > +- reg : Should contain 1 register range (address and length).
> > +- interrupts-extended : Specifies which HARTs (or CPUs) are connected to
> > + the CLINT. Each node pointed to should be a riscv,cpu-intc node, which
> > + has a riscv node as parent.
> > +
> > +Example:
> > +
> > + clint@2000000 {
> > + compatible = "sifive,clint-1.0.0", "sifive,fu540-c000-clint";
> > + interrupts-extended = <
> > + &cpu1-intc 3 &cpu1-intc 7
> > + &cpu2-intc 3 &cpu2-intc 7
> > + &cpu3-intc 3 &cpu3-intc 7
> > + &cpu4-intc 3 &cpu4-intc 7>;
> > + reg = <0x2000000 0x4000000>;
> > + };
> >
>
> --Sean
Regards,
Anup
^ permalink raw reply
* Re: [PATCH 01/19] dt-bindings: PCI: Endpoint: Add DT bindings for PCI EPF NTB Device
From: Kishon Vijay Abraham I @ 2020-05-22 5:53 UTC (permalink / raw)
To: Lorenzo Pieralisi, Arnd Bergmann, Jon Mason, Dave Jiang,
Allen Hubbe, Tom Joseph, Bjorn Helgaas, Rob Herring
Cc: Greg Kroah-Hartman, Jonathan Corbet, linux-pci, linux-doc,
linux-kernel, devicetree, linux-ntb
In-Reply-To: <20200514145927.17555-2-kishon@ti.com>
Hi RobH,
On 5/14/2020 8:29 PM, Kishon Vijay Abraham I wrote:
> Add device tree schema for PCI endpoint function bus to which
> endpoint function devices should be attached. Then add device tree
> schema for PCI endpoint function device to include bindings thats
> generic to all endpoint functions. Finally add device tree schema
> for PCI endpoint NTB function device by including the generic
> device tree schema for PCIe endpoint function.
>
> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
> ---
> .../bindings/pci/endpoint/pci-epf-bus.yaml | 42 +++++++++++
> .../bindings/pci/endpoint/pci-epf-device.yaml | 69 +++++++++++++++++++
> .../bindings/pci/endpoint/pci-epf-ntb.yaml | 68 ++++++++++++++++++
> 3 files changed, 179 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/pci/endpoint/pci-epf-bus.yaml
> create mode 100644 Documentation/devicetree/bindings/pci/endpoint/pci-epf-device.yaml
> create mode 100644 Documentation/devicetree/bindings/pci/endpoint/pci-epf-ntb.yaml
>
> diff --git a/Documentation/devicetree/bindings/pci/endpoint/pci-epf-bus.yaml b/Documentation/devicetree/bindings/pci/endpoint/pci-epf-bus.yaml
> new file mode 100644
> index 000000000000..1c504f2e85e4
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pci/endpoint/pci-epf-bus.yaml
> @@ -0,0 +1,42 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +# Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com/
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/pci/endpoint/pci-epf-bus.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: PCI Endpoint Function Bus
> +
> +maintainers:
> + - Kishon Vijay Abraham I <kishon@ti.com>
> +
> +properties:
> + compatible:
> + const: pci-epf-bus
> +
> +patternProperties:
> + "^func@[0-9a-f]+$":
> + type: object
> + description: |
> + PCI Endpoint Function Bus node should have subnodes for each of
> + the implemented endpoint function. It should follow the bindings
> + specified for endpoint function in
> + Documentation/devicetree/bindings/pci/endpoint/
> +
> +examples:
> + - |
> + epf_bus {
> + compatible = "pci-epf-bus";
> +
> + func@0 {
> + compatible = "pci-epf-ntb";
> + epcs = <&pcie0_ep>, <&pcie1_ep>;
> + epc-names = "primary", "secondary";
> + reg = <0>;
I'm not sure how to represent "reg" property properly for cases like this where
it represents ID and not a memory resource. I seem to get warning for
"reg_format" even after adding address-cells and size-cells property in
epf_bus. Can you give some hints here please?
> + epf,vendor-id = /bits/ 16 <0x104c>;
I want to make vendor-id and device-id as 16 bits from the beginning at-least
for PCIe endpoint. So I'm prefixing these properties with "epf,". However I get
this "do not match any of the regexes:". Can we add "epf" as a standard prefix?
Thanks
Kishon
> + epf,device-id = /bits/ 16 <0xb00d>;
> + num-mws = <4>;
> + mws-size = <0x0 0x100000>, <0x0 0x100000>, <0x0 0x100000>, <0x0 0x100000>;
> + };
> + };
> +...
> diff --git a/Documentation/devicetree/bindings/pci/endpoint/pci-epf-device.yaml b/Documentation/devicetree/bindings/pci/endpoint/pci-epf-device.yaml
> new file mode 100644
> index 000000000000..cee72864c8ca
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pci/endpoint/pci-epf-device.yaml
> @@ -0,0 +1,69 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +# Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com/
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/pci/endpoint/pci-epf-device.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: PCI Endpoint Function Device
> +
> +maintainers:
> + - Kishon Vijay Abraham I <kishon@ti.com>
> +
> +properties:
> + compatible:
> + const: pci-epf-bus
> +
> +properties:
> + $nodename:
> + pattern: "^func@"
> +
> + epcs:
> + description:
> + Phandle to the endpoint controller device. Should have "2" entries for
> + NTB endpoint function and "1" entry for others.
> + minItems: 1
> + maxItems: 2
> +
> + epc-names:
> + description:
> + Must contain an entry for each entry in "epcs" when "epcs" have more than
> + one entry.
> +
> + reg:
> + maxItems: 0
> + description: Must contain the index number of the function.
> +
> + epf,vendor-id:
> + description:
> + The PCI vendor ID
> + allOf:
> + - $ref: /schemas/types.yaml#/definitions/uint16
> +
> + epf,device-id:
> + description:
> + The PCI device ID
> + allOf:
> + - $ref: /schemas/types.yaml#/definitions/uint16
> +
> + epf,baseclass-code:
> + description: Code to classify the type of operation the function performs
> + allOf:
> + - $ref: /schemas/types.yaml#/definitions/uint8
> +
> + epf,subclass-code:
> + description:
> + Specifies a base class sub-class, which identifies more specifically the
> + operation of the Function
> + allOf:
> + - $ref: /schemas/types.yaml#/definitions/uint8
> +
> + epf,subsys-vendor-id:
> + description: Code to identify vendor of the add-in card or subsystem
> + allOf:
> + - $ref: /schemas/types.yaml#/definitions/uint16
> +
> + epf,subsys-id:
> + description: Code to specify an id that is specific to a vendor
> + allOf:
> + - $ref: /schemas/types.yaml#/definitions/uint16
> diff --git a/Documentation/devicetree/bindings/pci/endpoint/pci-epf-ntb.yaml b/Documentation/devicetree/bindings/pci/endpoint/pci-epf-ntb.yaml
> new file mode 100644
> index 000000000000..92c2e522b9e5
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pci/endpoint/pci-epf-ntb.yaml
> @@ -0,0 +1,68 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +# Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com/
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/pci/endpoint/pci-epf-ntb.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: PCI Endpoint NTB Function Device
> +
> +maintainers:
> + - Kishon Vijay Abraham I <kishon@ti.com>
> +
> +allOf:
> + - $ref: "pci-epf-device.yaml#"
> +
> +properties:
> + compatible:
> + const: pci-epf-ntb
> +
> + epcs:
> + minItems: 2
> + maxItems: 2
> +
> + epc-names:
> + items:
> + - const: primary
> + - const: secondary
> +
> + num-mws:
> + description:
> + Specify the number of memory windows
> + allOf:
> + - $ref: /schemas/types.yaml#/definitions/uint8
> + minimum: 1
> + maximum: 4
> +
> + mws-size:
> + description:
> + List of 'num-mws' entries containing size of each memory window.
> + minItems: 1
> + maxItems: 4
> +
> +required:
> + - compatible
> + - epcs
> + - epc-names
> + - epf,vendor-id
> + - epf,device-id
> + - num-mws
> + - mws-size
> +
> +examples:
> + - |
> + epf_bus {
> + compatible = "pci-epf-bus";
> +
> + func@0 {
> + compatible = "pci-epf-ntb";
> + reg = <0>;
> + epcs = <&pcie0_ep>, <&pcie1_ep>;
> + epc-names = "primary", "secondary";
> + epf,vendor-id = /bits/ 16 <0x104c>;
> + epf,device-id = /bits/ 16 <0xb00d>;
> + num-mws = <4>;
> + mws-size = <0x0 0x100000>, <0x0 0x100000>, <0x0 0x100000>, <0x0 0x100000>;
> + };
> + };
> +...
>
^ permalink raw reply
* RE: [PATCH 12/12] bus: fsl-mc: Add ACPI support for fsl-mc
From: Makarand Pawagi @ 2020-05-22 5:32 UTC (permalink / raw)
To: Laurentiu Tudor, Lorenzo Pieralisi,
linux-arm-kernel@lists.infradead.org
Cc: Diana Madalina Craciun (OSS), iommu@lists.linux-foundation.org,
linux-acpi@vger.kernel.org, devicetree@vger.kernel.org,
linux-pci@vger.kernel.org, Rob Herring, Rafael J. Wysocki,
Joerg Roedel, Hanjun Guo, Bjorn Helgaas, Sudeep Holla,
Robin Murphy, Catalin Marinas, Will Deacon, Marc Zyngier
In-Reply-To: <3045acd5-0bcf-40c1-e65f-0b740200b2e0@nxp.com>
Hi Lorenzo,
> -----Original Message-----
> From: Laurentiu Tudor <laurentiu.tudor@nxp.com>
> Sent: Thursday, May 21, 2020 8:33 PM
> To: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>; linux-arm-
> kernel@lists.infradead.org
> Cc: Diana Madalina Craciun (OSS) <diana.craciun@oss.nxp.com>; Makarand
> Pawagi <makarand.pawagi@nxp.com>; iommu@lists.linux-foundation.org;
> linux-acpi@vger.kernel.org; devicetree@vger.kernel.org; linux-
> pci@vger.kernel.org; Rob Herring <robh+dt@kernel.org>; Rafael J. Wysocki
> <rjw@rjwysocki.net>; Joerg Roedel <joro@8bytes.org>; Hanjun Guo
> <guohanjun@huawei.com>; Bjorn Helgaas <bhelgaas@google.com>; Sudeep
> Holla <sudeep.holla@arm.com>; Robin Murphy <robin.murphy@arm.com>;
> Catalin Marinas <catalin.marinas@arm.com>; Will Deacon <will@kernel.org>;
> Marc Zyngier <maz@kernel.org>
> Subject: Re: [PATCH 12/12] bus: fsl-mc: Add ACPI support for fsl-mc
>
> Hi Lorenzo,
>
> On 5/21/2020 4:00 PM, Lorenzo Pieralisi wrote:
> > From: Diana Craciun <diana.craciun@oss.nxp.com>
> >
> > Add ACPI support in the fsl-mc driver. Driver parses MC DSDT table to
> > extract memory and other resources.
> >
> > Interrupt (GIC ITS) information is extracted from the MADT table by
> > drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c.
> >
> > IORT table is parsed to configure DMA.
> >
> > Signed-off-by: Makarand Pawagi <makarand.pawagi@nxp.com>
> > Signed-off-by: Diana Craciun <diana.craciun@oss.nxp.com>
> > Signed-off-by: Laurentiu Tudor <laurentiu.tudor@nxp.com>
> > ---
>
> The author of this patch should be Makarand. I think I accidentaly broke it when
> we exchanged the patches. Very sorry about it.
>
Will you be able to correct this or should I post another patch?
> ---
> Best Regards, Laurentiu
>
>
> > drivers/bus/fsl-mc/fsl-mc-bus.c | 73 +++++++++++++++-----
> > drivers/bus/fsl-mc/fsl-mc-msi.c | 37 +++++-----
> > drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c | 75
> > ++++++++++++++++++++-
> > 3 files changed, 150 insertions(+), 35 deletions(-)
> >
> > diff --git a/drivers/bus/fsl-mc/fsl-mc-bus.c
> > b/drivers/bus/fsl-mc/fsl-mc-bus.c index 824ff77bbe86..324d49d6df89
> > 100644
> > --- a/drivers/bus/fsl-mc/fsl-mc-bus.c
> > +++ b/drivers/bus/fsl-mc/fsl-mc-bus.c
> > @@ -18,6 +18,8 @@
> > #include <linux/bitops.h>
> > #include <linux/msi.h>
> > #include <linux/dma-mapping.h>
> > +#include <linux/acpi.h>
> > +#include <linux/iommu.h>
> >
> > #include "fsl-mc-private.h"
> >
> > @@ -38,6 +40,7 @@ struct fsl_mc {
> > struct fsl_mc_device *root_mc_bus_dev;
> > u8 num_translation_ranges;
> > struct fsl_mc_addr_translation_range *translation_ranges;
> > + void *fsl_mc_regs;
> > };
> >
> > /**
> > @@ -56,6 +59,10 @@ struct fsl_mc_addr_translation_range {
> > phys_addr_t start_phys_addr;
> > };
> >
> > +#define FSL_MC_FAPR 0x28
> > +#define MC_FAPR_PL BIT(18)
> > +#define MC_FAPR_BMT BIT(17)
> > +
> > /**
> > * fsl_mc_bus_match - device to driver matching callback
> > * @dev: the fsl-mc device to match against @@ -124,7 +131,10 @@
> > static int fsl_mc_dma_configure(struct device *dev)
> > while (dev_is_fsl_mc(dma_dev))
> > dma_dev = dma_dev->parent;
> >
> > - return of_dma_configure_id(dev, dma_dev->of_node, 0, &input_id);
> > + if (dev_of_node(dma_dev))
> > + return of_dma_configure_id(dev, dma_dev->of_node, 0,
> &input_id);
> > +
> > + return acpi_dma_configure_id(dev, DEV_DMA_COHERENT, &input_id);
> > }
> >
> > static ssize_t modalias_show(struct device *dev, struct
> > device_attribute *attr, @@ -865,8 +875,11 @@ static int
> fsl_mc_bus_probe(struct platform_device *pdev)
> > struct fsl_mc_io *mc_io = NULL;
> > int container_id;
> > phys_addr_t mc_portal_phys_addr;
> > - u32 mc_portal_size;
> > - struct resource res;
> > + u32 mc_portal_size, mc_stream_id;
> > + struct resource *plat_res;
> > +
> > + if (!iommu_present(&fsl_mc_bus_type))
> > + return -EPROBE_DEFER;
> >
> > mc = devm_kzalloc(&pdev->dev, sizeof(*mc), GFP_KERNEL);
> > if (!mc)
> > @@ -874,19 +887,33 @@ static int fsl_mc_bus_probe(struct
> > platform_device *pdev)
> >
> > platform_set_drvdata(pdev, mc);
> >
> > + plat_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
> > + mc->fsl_mc_regs = devm_ioremap_resource(&pdev->dev, plat_res);
> > + if (IS_ERR(mc->fsl_mc_regs))
> > + return PTR_ERR(mc->fsl_mc_regs);
> > +
> > + if (IS_ENABLED(CONFIG_ACPI) && !dev_of_node(&pdev->dev)) {
> > + mc_stream_id = readl(mc->fsl_mc_regs + FSL_MC_FAPR);
> > + /*
> > + * HW ORs the PL and BMT bit, places the result in bit 15 of
> > + * the StreamID and ORs in the ICID. Calculate it accordingly.
> > + */
> > + mc_stream_id = (mc_stream_id & 0xffff) |
> > + ((mc_stream_id & (MC_FAPR_PL |
> MC_FAPR_BMT)) ?
> > + 0x4000 : 0);
> > + error = acpi_dma_configure_id(&pdev->dev,
> DEV_DMA_COHERENT,
> > + &mc_stream_id);
> > + if (error)
> > + dev_warn(&pdev->dev, "failed to configure
> dma: %d.\n",
> > + error);
> > + }
> > +
> > /*
> > * Get physical address of MC portal for the root DPRC:
> > */
> > - error = of_address_to_resource(pdev->dev.of_node, 0, &res);
> > - if (error < 0) {
> > - dev_err(&pdev->dev,
> > - "of_address_to_resource() failed for %pOF\n",
> > - pdev->dev.of_node);
> > - return error;
> > - }
> > -
> > - mc_portal_phys_addr = res.start;
> > - mc_portal_size = resource_size(&res);
> > + plat_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > + mc_portal_phys_addr = plat_res->start;
> > + mc_portal_size = resource_size(plat_res);
> > error = fsl_create_mc_io(&pdev->dev, mc_portal_phys_addr,
> > mc_portal_size, NULL,
> > FSL_MC_IO_ATOMIC_CONTEXT_PORTAL,
> &mc_io); @@ -903,11 +930,13 @@
> > static int fsl_mc_bus_probe(struct platform_device *pdev)
> > dev_info(&pdev->dev, "MC firmware version: %u.%u.%u\n",
> > mc_version.major, mc_version.minor, mc_version.revision);
> >
> > - error = get_mc_addr_translation_ranges(&pdev->dev,
> > - &mc->translation_ranges,
> > - &mc->num_translation_ranges);
> > - if (error < 0)
> > - goto error_cleanup_mc_io;
> > + if (dev_of_node(&pdev->dev)) {
> > + error = get_mc_addr_translation_ranges(&pdev->dev,
> > + &mc->translation_ranges,
> > + &mc-
> >num_translation_ranges);
> > + if (error < 0)
> > + goto error_cleanup_mc_io;
> > + }
> >
> > error = dprc_get_container_id(mc_io, 0, &container_id);
> > if (error < 0) {
> > @@ -934,6 +963,7 @@ static int fsl_mc_bus_probe(struct platform_device
> *pdev)
> > goto error_cleanup_mc_io;
> >
> > mc->root_mc_bus_dev = mc_bus_dev;
> > + mc_bus_dev->dev.fwnode = pdev->dev.fwnode;
> > return 0;
> >
> > error_cleanup_mc_io:
> > @@ -967,11 +997,18 @@ static const struct of_device_id
> > fsl_mc_bus_match_table[] = {
> >
> > MODULE_DEVICE_TABLE(of, fsl_mc_bus_match_table);
> >
> > +static const struct acpi_device_id fsl_mc_bus_acpi_match_table[] = {
> > + {"NXP0008", 0 },
> > + { }
> > +};
> > +MODULE_DEVICE_TABLE(acpi, fsl_mc_bus_acpi_match_table);
> > +
> > static struct platform_driver fsl_mc_bus_driver = {
> > .driver = {
> > .name = "fsl_mc_bus",
> > .pm = NULL,
> > .of_match_table = fsl_mc_bus_match_table,
> > + .acpi_match_table = fsl_mc_bus_acpi_match_table,
> > },
> > .probe = fsl_mc_bus_probe,
> > .remove = fsl_mc_bus_remove,
> > diff --git a/drivers/bus/fsl-mc/fsl-mc-msi.c
> > b/drivers/bus/fsl-mc/fsl-mc-msi.c index e7bbff445a83..8edadf05cbb7
> > 100644
> > --- a/drivers/bus/fsl-mc/fsl-mc-msi.c
> > +++ b/drivers/bus/fsl-mc/fsl-mc-msi.c
> > @@ -13,6 +13,7 @@
> > #include <linux/irq.h>
> > #include <linux/irqdomain.h>
> > #include <linux/msi.h>
> > +#include <linux/acpi_iort.h>
> >
> > #include "fsl-mc-private.h"
> >
> > @@ -179,25 +180,31 @@ struct irq_domain
> > *fsl_mc_msi_create_irq_domain(struct fwnode_handle *fwnode,
> >
> > struct irq_domain *fsl_mc_find_msi_domain(struct device *dev) {
> > - struct irq_domain *msi_domain = NULL;
> > + struct device *root_dprc_dev;
> > + struct device *bus_dev;
> > + struct irq_domain *msi_domain;
> > struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
> >
> > - msi_domain = of_msi_map_get_device_domain(dev, mc_dev->icid,
> > + fsl_mc_get_root_dprc(dev, &root_dprc_dev);
> > + bus_dev = root_dprc_dev->parent;
> > +
> > + if (bus_dev->of_node) {
> > + msi_domain = of_msi_map_get_device_domain(dev,
> > + mc_dev->icid,
> > DOMAIN_BUS_FSL_MC_MSI);
> >
> > - /*
> > - * if the msi-map property is missing assume that all the
> > - * child containers inherit the domain from the parent
> > - */
> > - if (!msi_domain) {
> > - struct device *root_dprc_dev;
> > - struct device *bus_dev;
> > -
> > - fsl_mc_get_root_dprc(dev, &root_dprc_dev);
> > - bus_dev = root_dprc_dev->parent;
> > - msi_domain = of_msi_get_domain(bus_dev,
> > - bus_dev->of_node,
> > - DOMAIN_BUS_FSL_MC_MSI);
> > + /*
> > + * if the msi-map property is missing assume that all the
> > + * child containers inherit the domain from the parent
> > + */
> > + if (!msi_domain)
> > +
> > + msi_domain = of_msi_get_domain(bus_dev,
> > + bus_dev->of_node,
> > + DOMAIN_BUS_FSL_MC_MSI);
> > + } else {
> > + msi_domain = iort_get_device_domain(dev, mc_dev->icid,
> > +
> DOMAIN_BUS_FSL_MC_MSI);
> > }
> >
> > return msi_domain;
> > diff --git a/drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c
> > b/drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c
> > index a5c8d577e424..b8b948fb6b2d 100644
> > --- a/drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c
> > +++ b/drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c
> > @@ -7,6 +7,8 @@
> > *
> > */
> >
> > +#include <linux/acpi.h>
> > +#include <linux/acpi_iort.h>
> > #include <linux/of_device.h>
> > #include <linux/of_address.h>
> > #include <linux/irq.h>
> > @@ -30,7 +32,8 @@ static u32 fsl_mc_msi_domain_get_msi_id(struct
> irq_domain *domain,
> > u32 out_id;
> >
> > of_node = irq_domain_get_of_node(domain);
> > - out_id = of_msi_map_id(&mc_dev->dev, of_node, mc_dev->icid);
> > + out_id = of_node ? of_msi_map_id(&mc_dev->dev, of_node, mc_dev-
> >icid) :
> > + iort_msi_map_id(&mc_dev->dev, mc_dev->icid);
> >
> > return out_id;
> > }
> > @@ -79,7 +82,67 @@ static const struct of_device_id its_device_id[] = {
> > {},
> > };
> >
> > -static int __init its_fsl_mc_msi_init(void)
> > +static int __init its_fsl_mc_msi_init_one(struct fwnode_handle *handle,
> > + const char *name)
> > +{
> > + struct irq_domain *parent;
> > + struct irq_domain *mc_msi_domain;
> > +
> > + parent = irq_find_matching_fwnode(handle, DOMAIN_BUS_NEXUS);
> > + if (!parent || !msi_get_domain_info(parent)) {
> > + pr_err("%s: Unable to locate ITS domain\n", name);
> > + return -ENXIO;
> > + }
> > +
> > + mc_msi_domain = fsl_mc_msi_create_irq_domain(handle,
> > + &its_fsl_mc_msi_domain_info,
> > + parent);
> > + if (!mc_msi_domain)
> > + pr_err("ACPIF: unable to create fsl-mc domain\n");
> > +
> > + pr_info("fsl-mc MSI: domain created\n");
> > +
> > + return 0;
> > +}
> > +
> > +static int __init
> > +its_fsl_mc_msi_parse_madt(union acpi_subtable_headers *header,
> > + const unsigned long end)
> > +{
> > + struct acpi_madt_generic_translator *its_entry;
> > + struct fwnode_handle *dom_handle;
> > + const char *node_name;
> > + int err = -ENXIO;
> > +
> > + its_entry = (struct acpi_madt_generic_translator *)header;
> > + node_name = kasprintf(GFP_KERNEL, "ITS@0x%lx",
> > + (long)its_entry->base_address);
> > +
> > + dom_handle = iort_find_domain_token(its_entry->translation_id);
> > + if (!dom_handle) {
> > + pr_err("%s: Unable to locate ITS domain handle\n",
> node_name);
> > + goto out;
> > + }
> > +
> > + err = its_fsl_mc_msi_init_one(dom_handle, node_name);
> > + if (!err)
> > + pr_info("fsl-mc MSI: %s domain created\n", node_name);
> > +
> > +out:
> > + kfree(node_name);
> > + return err;
> > +}
> > +
> > +
> > +static int __init its_fsl_mc_acpi_msi_init(void) {
> > + acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_TRANSLATOR,
> > + its_fsl_mc_msi_parse_madt, 0);
> > +
> > + return 0;
> > +}
> > +
> > +static int __init its_fsl_mc_of_msi_init(void)
> > {
> > struct device_node *np;
> > struct irq_domain *parent;
> > @@ -113,4 +176,12 @@ static int __init its_fsl_mc_msi_init(void)
> > return 0;
> > }
> >
> > +static int __init its_fsl_mc_msi_init(void) {
> > + its_fsl_mc_of_msi_init();
> > + its_fsl_mc_acpi_msi_init();
> > +
> > + return 0;
> > +}
> > +
> > early_initcall(its_fsl_mc_msi_init);
> >
^ permalink raw reply
* Re: [v4,0/7] Add Mediatek thermal dirver and dtsi
From: Michael Kao @ 2020-05-22 4:09 UTC (permalink / raw)
To: Matthias Brugger
Cc: Zhang Rui, Eduardo Valentin, Daniel Lezcano, Rob Herring,
Mark Rutland, hsinyi, linux-pm, srv_heupstream, devicetree,
linux-kernel, linux-arm-kernel, linux-mediatek
In-Reply-To: <7e205390-c7a7-b8c9-3ba2-344a04dc6696@gmail.com>
On Thu, 2020-05-21 at 14:51 +0200, Matthias Brugger wrote:
> Hi Michael,
>
> On 23/03/2020 13:15, Michael Kao wrote:
> > This patchset supports for MT8183 chip to mtk_thermal.c.
> > Add thermal zone of all the thermal sensor in SoC for
> > another get temperatrue. They don't need to thermal throttle.
> > And we bind coolers for thermal zone nodes of cpu_thermal.
> >
> > Rebase to kernel-5.6-rc1.
> >
> > Update content:
> >
> > [1/7]
> > - Squash thermal zone settings in the dtsi from [v3,5/8]
> > arm64: dts: mt8183: Increase polling frequency for CPU thermal zone
> >
> > - Remove the property of interrupts and mediatek,hw-reset-temp
> >
> > [2/7]
> > - Correct commit message
> >
> > [4/7]
> > - Change the target temperature to the 80C and change the commit message
> >
> > [6/7]
> > - Adjust newline alignment
> >
> > - Fix the judgement on the return value of registering thermal zone
> >
> > This patch series base on these patches [1].
> >
> > [v7,3/3] PM / AVS: SVS: Introduce SVS engine (https://patchwork.kernel.org/patch/11439829/)
> >
> > Matthias Kaehlcke (1):
> > arm64: dts: mt8183: Configure CPU cooling
> >
> > Michael Kao (6):
> > arm64: dts: mt8183: add thermal zone node
> > arm64: dts: mt8183: add dynamic power coefficients
> > arm64: dts: mt8183: Add #cooling-cells to CPU nodes
> > thermal: mediatek: mt8183: fix bank number settings
>
> Do I understand correctly that we need to fix the bank number before we can add
> the device tree changes. And that the last two patches are enhancements for the
> driver but needed to get a working version?
>
> Regards,
> Matthias
>
Hi Matthias,
There is one bank setting of mt8183 config.
If the device tree merged first. I worry that it will crash when the
thermal zone read temperature.
It will access the invalid index of bank.
So please wait the patch "fix bank number settings " merged first.
Thanks!
/* MT8183 thermal sensor data */
static const int mt8183_bank_data[MT8183_NUM_SENSORS] = {
MT8183_TS1, MT8183_TS2, MT8183_TS3, MT8183_TS4, MT8183_TS5,
MT8183_TSABB
};
Best Regards,
Michael
> > thermal: mediatek: add another get_temp ops for thermal sensors
> > thermal: mediatek: use spinlock to protect PTPCORESEL
> >
> > arch/arm64/boot/dts/mediatek/mt8183.dtsi | 156 +++++++++++++++++++++++
> > drivers/thermal/mtk_thermal.c | 88 +++++++++++--
> > 2 files changed, 231 insertions(+), 13 deletions(-)
> >
^ permalink raw reply
* Re: [v4,0/7] Add Mediatek thermal dirver and dtsi
From: Michael Kao @ 2020-05-22 4:07 UTC (permalink / raw)
To: Matthias Brugger
Cc: Zhang Rui, Eduardo Valentin, Daniel Lezcano, Rob Herring,
Mark Rutland, hsinyi, linux-pm, srv_heupstream, devicetree,
linux-kernel, linux-arm-kernel, linux-mediatek
In-Reply-To: <7e205390-c7a7-b8c9-3ba2-344a04dc6696@gmail.com>
On Thu, 2020-05-21 at 14:51 +0200, Matthias Brugger wrote:
> Hi Michael,
>
> On 23/03/2020 13:15, Michael Kao wrote:
> > This patchset supports for MT8183 chip to mtk_thermal.c.
> > Add thermal zone of all the thermal sensor in SoC for
> > another get temperatrue. They don't need to thermal throttle.
> > And we bind coolers for thermal zone nodes of cpu_thermal.
> >
> > Rebase to kernel-5.6-rc1.
> >
> > Update content:
> >
> > [1/7]
> > - Squash thermal zone settings in the dtsi from [v3,5/8]
> > arm64: dts: mt8183: Increase polling frequency for CPU thermal zone
> >
> > - Remove the property of interrupts and mediatek,hw-reset-temp
> >
> > [2/7]
> > - Correct commit message
> >
> > [4/7]
> > - Change the target temperature to the 80C and change the commit message
> >
> > [6/7]
> > - Adjust newline alignment
> >
> > - Fix the judgement on the return value of registering thermal zone
> >
> > This patch series base on these patches [1].
> >
> > [v7,3/3] PM / AVS: SVS: Introduce SVS engine (https://patchwork.kernel.org/patch/11439829/)
> >
> > Matthias Kaehlcke (1):
> > arm64: dts: mt8183: Configure CPU cooling
> >
> > Michael Kao (6):
> > arm64: dts: mt8183: add thermal zone node
> > arm64: dts: mt8183: add dynamic power coefficients
> > arm64: dts: mt8183: Add #cooling-cells to CPU nodes
> > thermal: mediatek: mt8183: fix bank number settings
>
> Do I understand correctly that we need to fix the bank number before we can add
> the device tree changes. And that the last two patches are enhancements for the
> driver but needed to get a working version?
>
> Regards,
> Matthias
Hi Matthias,
There is one bank setting of mt8183 config.
If the device tree merged first. I worry that it will crash when the
thermal zone read temperature.
It will access the invalid index of bank.
So please add the patch "fix bank number settings "
first.222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222
>
> > thermal: mediatek: add another get_temp ops for thermal sensors
> > thermal: mediatek: use spinlock to protect PTPCORESEL
> >
> > arch/arm64/boot/dts/mediatek/mt8183.dtsi | 156 +++++++++++++++++++++++
> > drivers/thermal/mtk_thermal.c | 88 +++++++++++--
> > 2 files changed, 231 insertions(+), 13 deletions(-)
> >
^ permalink raw reply
* Re: [PATCH v4 2/2] mailbox: sprd: Add Spreadtrum mailbox driver
From: Jassi Brar @ 2020-05-22 3:48 UTC (permalink / raw)
To: Baolin Wang; +Cc: Rob Herring, Orson Zhai, Chunyan Zhang, Devicetree List, LKML
In-Reply-To: <CADBw62rZuhaeSEppy+AhSkv1uNgaj9qrHFf7pz9nwKm8q3OrTA@mail.gmail.com>
On Thu, May 21, 2020 at 7:24 AM Baolin Wang <baolin.wang7@gmail.com> wrote:
>
> Hi Jassi,
>
> On Wed, May 13, 2020 at 2:32 PM Baolin Wang <baolin.wang7@gmail.com> wrote:
> >
> > On Wed, May 13, 2020 at 2:05 PM Jassi Brar <jassisinghbrar@gmail.com> wrote:
> > >
> > > On Tue, May 12, 2020 at 11:14 PM Baolin Wang <baolin.wang7@gmail.com> wrote:
> > > >
> > > > Hi Jassi,
> > > >
> > > > On Thu, May 7, 2020 at 11:23 AM Baolin Wang <baolin.wang7@gmail.com> wrote:
> > > > >
> > > > > Hi Jassi,
> > > > >
> > > > > On Thu, May 7, 2020 at 7:25 AM Jassi Brar <jassisinghbrar@gmail.com> wrote:
> > > > > >
> > > > > > On Wed, May 6, 2020 at 8:29 AM Baolin Wang <baolin.wang7@gmail.com> wrote:
> > > > > > >
> > > > > > > Hi Jassi,
> > > > > > >
> > > > > > > On Tue, Apr 28, 2020 at 11:10 AM Baolin Wang <baolin.wang7@gmail.com> wrote:
> > > > > > > >
> > > > > > > > From: Baolin Wang <baolin.wang@unisoc.com>
> > > > > > > >
> > > > > > > > The Spreadtrum mailbox controller supports 8 channels to communicate
> > > > > > > > with MCUs, and it contains 2 different parts: inbox and outbox, which
> > > > > > > > are used to send and receive messages by IRQ mode.
> > > > > > > >
> > > > > > > > Signed-off-by: Baolin Wang <baolin.wang@unisoc.com>
> > > > > > > > Signed-off-by: Baolin Wang <baolin.wang7@gmail.com>
> > > > > > > > ---
> > > > > > > > Changes from v3:
> > > > > > > > - Save the id in mbox_chan.con_priv and remove the 'sprd_mbox_chan'
> > > > > > > >
> > > > > > > > Changes from v2:
> > > > > > > > - None.
> > > > > > > >
> > > > > > > > Changes from v1:
> > > > > > > > - None
> > > > > > >
> > > > > > > Gentle ping, do you have any other comments? Thanks.
> > > > > > >
> > > > > > Yea, I am still not sure about the error returned in send_data(). It
> > > > > > will either never hit or there will be no easy recovery from it. The
> > > > > > api expects the driver to tell it the last-tx was done only when it
> > > > > > can send the next message. (There may be case like sending depend on
> > > > > > remote, which can't be ensured before hand).
> > > > >
> > > > > Actually this is an unusual case, suppose the remote target did not
> > > > > fetch the message as soon as possile, which will cause the FIFO
> > > > > overflow, so in this case we can not send messages to the remote
> > > > > target any more, otherwise messages will be lost. Thus we can return
> > > > > errors to users to indicate that something wrong with the remote
> > > > > target need to be checked.
> > > > >
> > > > > So this validation in send_data() is mostly for debugging for this
> > > > > abnormal case and we will not trigger this issue if the remote target
> > > > > works well. So I think it is useful to keep this validation in
> > > > > send_data(). Thanks.
> > > >
> > > > Any comments? Thanks.
> > > >
> > > Same as my last post.
> >
> > I think I've explained the reason why we need add this validation in
> > my previous email, I am not sure how do you think? You still want to
> > remove this validation?
>
> Gentle ping.
>
> As I explained in previous email, this validation is for an unusual
> case, suppose the remote target did not fetch the message as soon as
> possile, which will cause the FIFO overflow, so in this case we can
> not send messages to the remote
> target any more, otherwise messages will be lost. Thus we can return
> errors to users to indicate that something wrong with the remote
> target need to be checked.
>
> So this validation in send_data() is mostly for debugging for this
> abnormal case and we will not trigger this issue if the remote target
> works well. So I think it is useful to keep this validation in
> send_data(). What do you think? Thanks.
>
I still think the same as before.
You should do this check before you call mbox_chan_txdone() and wait
if busy ... which is exactly the purpose of txdone().
It seems harmless to be paranoid and place a block of code in
practically "if 0", but that sets bad precedence for other drivers. So
please move the check before txdone().
thanks.
^ permalink raw reply
* [PATCH v5 04/14] PCI: cadence: Add support to start link and verify link status
From: Kishon Vijay Abraham I @ 2020-05-22 3:36 UTC (permalink / raw)
To: Tom Joseph, Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas
Cc: linux-pci, linux-kernel, Arnd Bergmann, Greg Kroah-Hartman,
devicetree, linux-omap, linux-arm-kernel, Kishon Vijay Abraham I
In-Reply-To: <20200522033631.32574-1-kishon@ti.com>
Add cdns_pcie_ops to start link and verify link status. The registers
to start link and to check link status is in Platform specific PCIe
wrapper. Add support for platform specific drivers to add callback
functions for the PCIe Cadence core to start link and verify link status.
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Reviewed-by: Rob Herring <robh@kernel.org>
---
.../pci/controller/cadence/pcie-cadence-ep.c | 8 ++++
.../controller/cadence/pcie-cadence-host.c | 28 ++++++++++++++
drivers/pci/controller/cadence/pcie-cadence.h | 37 ++++++++++++++++++-
3 files changed, 72 insertions(+), 1 deletion(-)
diff --git a/drivers/pci/controller/cadence/pcie-cadence-ep.c b/drivers/pci/controller/cadence/pcie-cadence-ep.c
index 1fdae37843ef..14021d760482 100644
--- a/drivers/pci/controller/cadence/pcie-cadence-ep.c
+++ b/drivers/pci/controller/cadence/pcie-cadence-ep.c
@@ -354,8 +354,10 @@ static int cdns_pcie_ep_start(struct pci_epc *epc)
{
struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
struct cdns_pcie *pcie = &ep->pcie;
+ struct device *dev = pcie->dev;
struct pci_epf *epf;
u32 cfg;
+ int ret;
/*
* BIT(0) is hardwired to 1, hence function 0 is always enabled
@@ -366,6 +368,12 @@ static int cdns_pcie_ep_start(struct pci_epc *epc)
cfg |= BIT(epf->func_no);
cdns_pcie_writel(pcie, CDNS_PCIE_LM_EP_FUNC_CFG, cfg);
+ ret = cdns_pcie_start_link(pcie);
+ if (ret) {
+ dev_err(dev, "Failed to start link\n");
+ return ret;
+ }
+
return 0;
}
diff --git a/drivers/pci/controller/cadence/pcie-cadence-host.c b/drivers/pci/controller/cadence/pcie-cadence-host.c
index 8e73a680b567..93a9414932a9 100644
--- a/drivers/pci/controller/cadence/pcie-cadence-host.c
+++ b/drivers/pci/controller/cadence/pcie-cadence-host.c
@@ -3,6 +3,7 @@
// Cadence PCIe host controller driver.
// Author: Cyrille Pitchen <cyrille.pitchen@free-electrons.com>
+#include <linux/delay.h>
#include <linux/kernel.h>
#include <linux/of_address.h>
#include <linux/of_pci.h>
@@ -422,6 +423,23 @@ static int cdns_pcie_host_init(struct device *dev,
return err;
}
+static int cdns_pcie_host_wait_for_link(struct cdns_pcie *pcie)
+{
+ struct device *dev = pcie->dev;
+ int retries;
+
+ /* Check if the link is up or not */
+ for (retries = 0; retries < LINK_WAIT_MAX_RETRIES; retries++) {
+ if (cdns_pcie_link_up(pcie)) {
+ dev_info(dev, "Link up\n");
+ return 0;
+ }
+ usleep_range(LINK_WAIT_USLEEP_MIN, LINK_WAIT_USLEEP_MAX);
+ }
+
+ return -ETIMEDOUT;
+}
+
int cdns_pcie_host_setup(struct cdns_pcie_rc *rc)
{
struct device *dev = rc->pcie.dev;
@@ -470,6 +488,16 @@ int cdns_pcie_host_setup(struct cdns_pcie_rc *rc)
pcie->mem_res = res;
+ ret = cdns_pcie_start_link(pcie);
+ if (ret) {
+ dev_err(dev, "Failed to start link\n");
+ return ret;
+ }
+
+ ret = cdns_pcie_host_wait_for_link(pcie);
+ if (ret)
+ dev_dbg(dev, "PCIe link never came up\n");
+
for (bar = RP_BAR0; bar <= RP_NO_BAR; bar++)
rc->avail_ib_bar[bar] = true;
diff --git a/drivers/pci/controller/cadence/pcie-cadence.h b/drivers/pci/controller/cadence/pcie-cadence.h
index 737e9561092b..c013e629e9fa 100644
--- a/drivers/pci/controller/cadence/pcie-cadence.h
+++ b/drivers/pci/controller/cadence/pcie-cadence.h
@@ -10,6 +10,11 @@
#include <linux/pci.h>
#include <linux/phy/phy.h>
+/* Parameters for the waiting for link up routine */
+#define LINK_WAIT_MAX_RETRIES 10
+#define LINK_WAIT_USLEEP_MIN 90000
+#define LINK_WAIT_USLEEP_MAX 100000
+
/*
* Local Management Registers
*/
@@ -245,12 +250,20 @@ enum cdns_pcie_msg_routing {
MSG_ROUTING_GATHER,
};
+struct cdns_pcie_ops {
+ int (*start_link)(struct cdns_pcie *pcie);
+ void (*stop_link)(struct cdns_pcie *pcie);
+ bool (*link_up)(struct cdns_pcie *pcie);
+};
+
/**
* struct cdns_pcie - private data for Cadence PCIe controller drivers
* @reg_base: IO mapped register base
* @mem_res: start/end offsets in the physical system memory to map PCI accesses
* @is_rc: tell whether the PCIe controller mode is Root Complex or Endpoint.
* @bus: In Root Complex mode, the bus number
+ * @ops: Platform specific ops to control various inputs from Cadence PCIe
+ * wrapper
*/
struct cdns_pcie {
void __iomem *reg_base;
@@ -261,7 +274,7 @@ struct cdns_pcie {
int phy_count;
struct phy **phy;
struct device_link **link;
- const struct cdns_pcie_common_ops *ops;
+ const struct cdns_pcie_ops *ops;
};
/**
@@ -421,6 +434,28 @@ static inline u32 cdns_pcie_ep_fn_readl(struct cdns_pcie *pcie, u8 fn, u32 reg)
return readl(pcie->reg_base + CDNS_PCIE_EP_FUNC_BASE(fn) + reg);
}
+static inline int cdns_pcie_start_link(struct cdns_pcie *pcie)
+{
+ if (pcie->ops->start_link)
+ return pcie->ops->start_link(pcie);
+
+ return 0;
+}
+
+static inline void cdns_pcie_stop_link(struct cdns_pcie *pcie)
+{
+ if (pcie->ops->stop_link)
+ pcie->ops->stop_link(pcie);
+}
+
+static inline bool cdns_pcie_link_up(struct cdns_pcie *pcie)
+{
+ if (pcie->ops->link_up)
+ return pcie->ops->link_up(pcie);
+
+ return true;
+}
+
#ifdef CONFIG_PCIE_CADENCE_HOST
int cdns_pcie_host_setup(struct cdns_pcie_rc *rc);
#else
--
2.17.1
^ permalink raw reply related
* [PATCH v5 08/14] PCI: cadence: Fix updating Vendor ID and Subsystem Vendor ID register
From: Kishon Vijay Abraham I @ 2020-05-22 3:36 UTC (permalink / raw)
To: Tom Joseph, Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas
Cc: linux-pci, linux-kernel, Arnd Bergmann, Greg Kroah-Hartman,
devicetree, linux-omap, linux-arm-kernel, Kishon Vijay Abraham I
In-Reply-To: <20200522033631.32574-1-kishon@ti.com>
Commit 1b79c5284439 ("PCI: cadence: Add host driver for Cadence PCIe
controller") in order to update Vendor ID, directly wrote to
PCI_VENDOR_ID register. However PCI_VENDOR_ID in root port configuration
space is read-only register and writing to it will have no effect.
Use local management register to configure Vendor ID and Subsystem Vendor
ID.
Fixes: 1b79c5284439 ("PCI: cadence: Add host driver for Cadence PCIe controller")
Reviewed-by: Rob Herring <robh@kernel.org>
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
---
drivers/pci/controller/cadence/pcie-cadence-host.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/pci/controller/cadence/pcie-cadence-host.c b/drivers/pci/controller/cadence/pcie-cadence-host.c
index 3003fafa3bfa..7ee9e06f1285 100644
--- a/drivers/pci/controller/cadence/pcie-cadence-host.c
+++ b/drivers/pci/controller/cadence/pcie-cadence-host.c
@@ -76,6 +76,7 @@ static int cdns_pcie_host_init_root_port(struct cdns_pcie_rc *rc)
{
struct cdns_pcie *pcie = &rc->pcie;
u32 value, ctrl;
+ u32 id;
/*
* Set the root complex BAR configuration register:
@@ -95,8 +96,12 @@ static int cdns_pcie_host_init_root_port(struct cdns_pcie_rc *rc)
cdns_pcie_writel(pcie, CDNS_PCIE_LM_RC_BAR_CFG, value);
/* Set root port configuration space */
- if (rc->vendor_id != 0xffff)
- cdns_pcie_rp_writew(pcie, PCI_VENDOR_ID, rc->vendor_id);
+ if (rc->vendor_id != 0xffff) {
+ id = CDNS_PCIE_LM_ID_VENDOR(rc->vendor_id) |
+ CDNS_PCIE_LM_ID_SUBSYS(rc->vendor_id);
+ cdns_pcie_writel(pcie, CDNS_PCIE_LM_ID, id);
+ }
+
if (rc->device_id != 0xffff)
cdns_pcie_rp_writew(pcie, PCI_DEVICE_ID, rc->device_id);
--
2.17.1
^ permalink raw reply related
* [PATCH v5 13/14] misc: pci_endpoint_test: Add J721E in pci_device_id table
From: Kishon Vijay Abraham I @ 2020-05-22 3:36 UTC (permalink / raw)
To: Tom Joseph, Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas
Cc: linux-pci, linux-kernel, Arnd Bergmann, Greg Kroah-Hartman,
devicetree, linux-omap, linux-arm-kernel, Kishon Vijay Abraham I
In-Reply-To: <20200522033631.32574-1-kishon@ti.com>
Add J721E in pci_device_id table so that pci-epf-test can be used
for testing PCIe EP in J721E.
Reviewed-by: Rob Herring <robh@kernel.org>
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
---
drivers/misc/pci_endpoint_test.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/misc/pci_endpoint_test.c b/drivers/misc/pci_endpoint_test.c
index ef5a1af6bab7..a70b17e5dd9a 100644
--- a/drivers/misc/pci_endpoint_test.c
+++ b/drivers/misc/pci_endpoint_test.c
@@ -68,6 +68,7 @@
#define PCI_ENDPOINT_TEST_FLAGS 0x2c
#define FLAG_USE_DMA BIT(0)
+#define PCI_DEVICE_ID_TI_J721E 0xb00d
#define PCI_DEVICE_ID_TI_AM654 0xb00c
#define is_am654_pci_dev(pdev) \
@@ -930,6 +931,11 @@ static const struct pci_endpoint_test_data am654_data = {
.irq_type = IRQ_TYPE_MSI,
};
+static const struct pci_endpoint_test_data j721e_data = {
+ .alignment = 256,
+ .irq_type = IRQ_TYPE_MSI,
+};
+
static const struct pci_device_id pci_endpoint_test_tbl[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_DRA74x),
.driver_data = (kernel_ulong_t)&default_data,
@@ -942,6 +948,9 @@ static const struct pci_device_id pci_endpoint_test_tbl[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_AM654),
.driver_data = (kernel_ulong_t)&am654_data
},
+ { PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_J721E),
+ .driver_data = (kernel_ulong_t)&j721e_data,
+ },
{ }
};
MODULE_DEVICE_TABLE(pci, pci_endpoint_test_tbl);
--
2.17.1
^ permalink raw reply related
* [PATCH v5 11/14] dt-bindings: PCI: Add EP mode dt-bindings for TI's J721E SoC
From: Kishon Vijay Abraham I @ 2020-05-22 3:36 UTC (permalink / raw)
To: Tom Joseph, Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas
Cc: linux-pci, linux-kernel, Arnd Bergmann, Greg Kroah-Hartman,
devicetree, linux-omap, linux-arm-kernel, Kishon Vijay Abraham I
In-Reply-To: <20200522033631.32574-1-kishon@ti.com>
Add PCIe EP mode dt-bindings for TI's J721E SoC.
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Reviewed-by: Rob Herring <robh@kernel.org>
---
.../bindings/pci/ti,j721e-pci-ep.yaml | 89 +++++++++++++++++++
1 file changed, 89 insertions(+)
create mode 100644 Documentation/devicetree/bindings/pci/ti,j721e-pci-ep.yaml
diff --git a/Documentation/devicetree/bindings/pci/ti,j721e-pci-ep.yaml b/Documentation/devicetree/bindings/pci/ti,j721e-pci-ep.yaml
new file mode 100644
index 000000000000..c09d25b2c1b2
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/ti,j721e-pci-ep.yaml
@@ -0,0 +1,89 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com/
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/pci/ti,j721e-pci-ep.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: TI J721E PCI EP (PCIe Wrapper)
+
+maintainers:
+ - Kishon Vijay Abraham I <kishon@ti.com>
+
+allOf:
+ - $ref: "cdns-pcie-ep.yaml#"
+
+properties:
+ compatible:
+ enum:
+ - ti,j721e-pcie-ep
+
+ reg:
+ maxItems: 4
+
+ reg-names:
+ items:
+ - const: intd_cfg
+ - const: user_cfg
+ - const: reg
+ - const: mem
+
+ ti,syscon-pcie-ctrl:
+ description: Phandle to the SYSCON entry required for configuring PCIe mode
+ and link speed.
+ allOf:
+ - $ref: /schemas/types.yaml#/definitions/phandle
+
+ power-domains:
+ maxItems: 1
+
+ clocks:
+ maxItems: 1
+ description: clock-specifier to represent input to the PCIe
+
+ clock-names:
+ items:
+ - const: fck
+
+ dma-coherent:
+ description: Indicates that the PCIe IP block can ensure the coherency
+
+required:
+ - compatible
+ - reg
+ - reg-names
+ - ti,syscon-pcie-ctrl
+ - max-link-speed
+ - num-lanes
+ - power-domains
+ - clocks
+ - clock-names
+ - cdns,max-outbound-regions
+ - dma-coherent
+ - max-functions
+ - phys
+ - phy-names
+
+examples:
+ - |
+ #include <dt-bindings/soc/ti,sci_pm_domain.h>
+
+ pcie0_ep: pcie-ep@d000000 {
+ compatible = "ti,j721e-pcie-ep";
+ reg = <0x00 0x02900000 0x00 0x1000>,
+ <0x00 0x02907000 0x00 0x400>,
+ <0x00 0x0d000000 0x00 0x00800000>,
+ <0x00 0x10000000 0x00 0x08000000>;
+ reg-names = "intd_cfg", "user_cfg", "reg", "mem";
+ ti,syscon-pcie-ctrl = <&pcie0_ctrl>;
+ max-link-speed = <3>;
+ num-lanes = <2>;
+ power-domains = <&k3_pds 239 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 239 1>;
+ clock-names = "fck";
+ cdns,max-outbound-regions = <16>;
+ max-functions = /bits/ 8 <6>;
+ dma-coherent;
+ phys = <&serdes0_pcie_link>;
+ phy-names = "pcie-phy";
+ };
--
2.17.1
^ permalink raw reply related
* [PATCH v5 12/14] PCI: j721e: Add TI J721E PCIe driver
From: Kishon Vijay Abraham I @ 2020-05-22 3:36 UTC (permalink / raw)
To: Tom Joseph, Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas
Cc: linux-pci, linux-kernel, Arnd Bergmann, Greg Kroah-Hartman,
devicetree, linux-omap, linux-arm-kernel, Kishon Vijay Abraham I
In-Reply-To: <20200522033631.32574-1-kishon@ti.com>
Add support for PCIe controller in J721E SoC. The controller uses the
Cadence PCIe core programmed by pcie-cadence*.c. The PCIe controller
will work in both host mode and device mode.
Some of the features of the controller are:
*) Supports both RC mode and EP mode
*) Supports MSI and MSI-X support
*) Supports upto GEN3 speed mode
*) Supports SR-IOV capability
*) Ability to route all transactions via SMMU (support will be added
in a later patch).
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
---
drivers/pci/controller/cadence/Kconfig | 23 +
drivers/pci/controller/cadence/Makefile | 1 +
drivers/pci/controller/cadence/pci-j721e.c | 490 ++++++++++++++++++
.../controller/cadence/pcie-cadence-host.c | 4 +-
drivers/pci/controller/cadence/pcie-cadence.h | 8 +
5 files changed, 524 insertions(+), 2 deletions(-)
create mode 100644 drivers/pci/controller/cadence/pci-j721e.c
diff --git a/drivers/pci/controller/cadence/Kconfig b/drivers/pci/controller/cadence/Kconfig
index b76b3cf55ce5..5d30564190e1 100644
--- a/drivers/pci/controller/cadence/Kconfig
+++ b/drivers/pci/controller/cadence/Kconfig
@@ -42,4 +42,27 @@ config PCIE_CADENCE_PLAT_EP
endpoint mode. This PCIe controller may be embedded into many
different vendors SoCs.
+config PCI_J721E
+ bool
+
+config PCI_J721E_HOST
+ bool "TI J721E PCIe platform host controller"
+ depends on OF
+ select PCIE_CADENCE_HOST
+ select PCI_J721E
+ help
+ Say Y here if you want to support the TI J721E PCIe platform
+ controller in host mode. TI J721E PCIe controller uses Cadence PCIe
+ core.
+
+config PCI_J721E_EP
+ bool "TI J721E PCIe platform endpoint controller"
+ depends on OF
+ depends on PCI_ENDPOINT
+ select PCIE_CADENCE_EP
+ select PCI_J721E
+ help
+ Say Y here if you want to support the TI J721E PCIe platform
+ controller in endpoint mode. TI J721E PCIe controller uses Cadence PCIe
+ core.
endmenu
diff --git a/drivers/pci/controller/cadence/Makefile b/drivers/pci/controller/cadence/Makefile
index 232a3f20876a..9bac5fb2f13d 100644
--- a/drivers/pci/controller/cadence/Makefile
+++ b/drivers/pci/controller/cadence/Makefile
@@ -3,3 +3,4 @@ obj-$(CONFIG_PCIE_CADENCE) += pcie-cadence.o
obj-$(CONFIG_PCIE_CADENCE_HOST) += pcie-cadence-host.o
obj-$(CONFIG_PCIE_CADENCE_EP) += pcie-cadence-ep.o
obj-$(CONFIG_PCIE_CADENCE_PLAT) += pcie-cadence-plat.o
+obj-$(CONFIG_PCI_J721E) += pci-j721e.o
diff --git a/drivers/pci/controller/cadence/pci-j721e.c b/drivers/pci/controller/cadence/pci-j721e.c
new file mode 100644
index 000000000000..9b3ab880a3c5
--- /dev/null
+++ b/drivers/pci/controller/cadence/pci-j721e.c
@@ -0,0 +1,490 @@
+// SPDX-License-Identifier: GPL-2.0
+/**
+ * pci-j721e - PCIe controller driver for TI's J721E SoCs
+ *
+ * Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com
+ * Author: Kishon Vijay Abraham I <kishon@ti.com>
+ */
+
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/io.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/irqdomain.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of_device.h>
+#include <linux/of_irq.h>
+#include <linux/pci.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+
+#include "../../pci.h"
+#include "pcie-cadence.h"
+
+#define ENABLE_REG_SYS_2 0x108
+#define STATUS_REG_SYS_2 0x508
+#define STATUS_CLR_REG_SYS_2 0x708
+#define LINK_DOWN BIT(1)
+
+#define J721E_PCIE_USER_CMD_STATUS 0x4
+#define LINK_TRAINING_ENABLE BIT(0)
+
+#define J721E_PCIE_USER_LINKSTATUS 0x14
+#define LINK_STATUS GENMASK(1, 0)
+
+enum link_status {
+ NO_RECEIVERS_DETECTED,
+ LINK_TRAINING_IN_PROGRESS,
+ LINK_UP_DL_IN_PROGRESS,
+ LINK_UP_DL_COMPLETED,
+};
+
+#define J721E_MODE_RC BIT(7)
+#define LANE_COUNT_MASK BIT(8)
+#define LANE_COUNT(n) ((n) << 8)
+
+#define GENERATION_SEL_MASK GENMASK(1, 0)
+
+#define MAX_LANES 2
+
+struct j721e_pcie {
+ struct device *dev;
+ u32 mode;
+ u32 num_lanes;
+ struct cdns_pcie *cdns_pcie;
+ void __iomem *user_cfg_base;
+ void __iomem *intd_cfg_base;
+};
+
+enum j721e_pcie_mode {
+ PCI_MODE_RC,
+ PCI_MODE_EP,
+};
+
+struct j721e_pcie_data {
+ enum j721e_pcie_mode mode;
+};
+
+static inline u32 j721e_pcie_user_readl(struct j721e_pcie *pcie, u32 offset)
+{
+ return readl(pcie->user_cfg_base + offset);
+}
+
+static inline void j721e_pcie_user_writel(struct j721e_pcie *pcie, u32 offset,
+ u32 value)
+{
+ writel(value, pcie->user_cfg_base + offset);
+}
+
+static inline u32 j721e_pcie_intd_readl(struct j721e_pcie *pcie, u32 offset)
+{
+ return readl(pcie->intd_cfg_base + offset);
+}
+
+static inline void j721e_pcie_intd_writel(struct j721e_pcie *pcie, u32 offset,
+ u32 value)
+{
+ writel(value, pcie->intd_cfg_base + offset);
+}
+
+static irqreturn_t j721e_pcie_link_irq_handler(int irq, void *priv)
+{
+ struct j721e_pcie *pcie = priv;
+ struct device *dev = pcie->dev;
+ u32 reg;
+
+ reg = j721e_pcie_intd_readl(pcie, STATUS_REG_SYS_2);
+ if (!(reg & LINK_DOWN))
+ return IRQ_NONE;
+
+ dev_err(dev, "LINK DOWN!\n");
+
+ j721e_pcie_intd_writel(pcie, STATUS_CLR_REG_SYS_2, LINK_DOWN);
+ return IRQ_HANDLED;
+}
+
+static void j721e_pcie_config_link_irq(struct j721e_pcie *pcie)
+{
+ u32 reg;
+
+ reg = j721e_pcie_intd_readl(pcie, ENABLE_REG_SYS_2);
+ reg |= LINK_DOWN;
+ j721e_pcie_intd_writel(pcie, ENABLE_REG_SYS_2, reg);
+}
+
+static int j721e_pcie_start_link(struct cdns_pcie *cdns_pcie)
+{
+ struct j721e_pcie *pcie = dev_get_drvdata(cdns_pcie->dev);
+ u32 reg;
+
+ reg = j721e_pcie_user_readl(pcie, J721E_PCIE_USER_CMD_STATUS);
+ reg |= LINK_TRAINING_ENABLE;
+ j721e_pcie_user_writel(pcie, J721E_PCIE_USER_CMD_STATUS, reg);
+
+ return 0;
+}
+
+static void j721e_pcie_stop_link(struct cdns_pcie *cdns_pcie)
+{
+ struct j721e_pcie *pcie = dev_get_drvdata(cdns_pcie->dev);
+ u32 reg;
+
+ reg = j721e_pcie_user_readl(pcie, J721E_PCIE_USER_CMD_STATUS);
+ reg &= ~LINK_TRAINING_ENABLE;
+ j721e_pcie_user_writel(pcie, J721E_PCIE_USER_CMD_STATUS, reg);
+}
+
+static bool j721e_pcie_link_up(struct cdns_pcie *cdns_pcie)
+{
+ struct j721e_pcie *pcie = dev_get_drvdata(cdns_pcie->dev);
+ u32 reg;
+
+ reg = j721e_pcie_user_readl(pcie, J721E_PCIE_USER_LINKSTATUS);
+ reg &= LINK_STATUS;
+ if (reg == LINK_UP_DL_COMPLETED)
+ return true;
+
+ return false;
+}
+
+static const struct cdns_pcie_ops j721e_ops_ops = {
+ .start_link = j721e_pcie_start_link,
+ .stop_link = j721e_pcie_stop_link,
+ .link_up = j721e_pcie_link_up,
+};
+
+static int j721e_pcie_set_mode(struct j721e_pcie *pcie, struct regmap *syscon)
+{
+ struct device *dev = pcie->dev;
+ u32 mask = J721E_MODE_RC;
+ u32 mode = pcie->mode;
+ u32 val = 0;
+ int ret = 0;
+
+ if (mode == PCI_MODE_RC)
+ val = J721E_MODE_RC;
+
+ ret = regmap_update_bits(syscon, 0, mask, val);
+ if (ret)
+ dev_err(dev, "failed to set pcie mode\n");
+
+ return ret;
+}
+
+static int j721e_pcie_set_link_speed(struct j721e_pcie *pcie,
+ struct regmap *syscon)
+{
+ struct device *dev = pcie->dev;
+ struct device_node *np = dev->of_node;
+ int link_speed;
+ u32 val = 0;
+ int ret;
+
+ link_speed = of_pci_get_max_link_speed(np);
+ if (link_speed < 2)
+ link_speed = 2;
+
+ val = link_speed - 1;
+ ret = regmap_update_bits(syscon, 0, GENERATION_SEL_MASK, val);
+ if (ret)
+ dev_err(dev, "failed to set link speed\n");
+
+ return ret;
+}
+
+static int j721e_pcie_set_lane_count(struct j721e_pcie *pcie,
+ struct regmap *syscon)
+{
+ struct device *dev = pcie->dev;
+ u32 lanes = pcie->num_lanes;
+ u32 val = 0;
+ int ret;
+
+ val = LANE_COUNT(lanes - 1);
+ ret = regmap_update_bits(syscon, 0, LANE_COUNT_MASK, val);
+ if (ret)
+ dev_err(dev, "failed to set link count\n");
+
+ return ret;
+}
+
+static int j721e_pcie_ctrl_init(struct j721e_pcie *pcie)
+{
+ struct device *dev = pcie->dev;
+ struct device_node *node = dev->of_node;
+ struct regmap *syscon;
+ int ret;
+
+ syscon = syscon_regmap_lookup_by_phandle(node, "ti,syscon-pcie-ctrl");
+ if (IS_ERR(syscon)) {
+ dev_err(dev, "Unable to get ti,syscon-pcie-ctrl regmap\n");
+ return PTR_ERR(syscon);
+ }
+
+ ret = j721e_pcie_set_mode(pcie, syscon);
+ if (ret < 0) {
+ dev_err(dev, "Failed to set pci mode\n");
+ return ret;
+ }
+
+ ret = j721e_pcie_set_link_speed(pcie, syscon);
+ if (ret < 0) {
+ dev_err(dev, "Failed to set link speed\n");
+ return ret;
+ }
+
+ ret = j721e_pcie_set_lane_count(pcie, syscon);
+ if (ret < 0) {
+ dev_err(dev, "Failed to set num-lanes\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int cdns_ti_pcie_config_read(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 *value)
+{
+ struct pci_host_bridge *bridge = pci_find_host_bridge(bus);
+ struct cdns_pcie_rc *rc = pci_host_bridge_priv(bridge);
+ unsigned int busn = bus->number;
+
+ if (busn == rc->bus_range->start)
+ return pci_generic_config_read32(bus, devfn, where, size,
+ value);
+
+ return pci_generic_config_read(bus, devfn, where, size, value);
+}
+
+static int cdns_ti_pcie_config_write(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 value)
+{
+ struct pci_host_bridge *bridge = pci_find_host_bridge(bus);
+ struct cdns_pcie_rc *rc = pci_host_bridge_priv(bridge);
+ unsigned int busn = bus->number;
+
+ if (busn == rc->bus_range->start)
+ return pci_generic_config_write32(bus, devfn, where, size,
+ value);
+
+ return pci_generic_config_write(bus, devfn, where, size, value);
+}
+
+static struct pci_ops cdns_ti_pcie_host_ops = {
+ .map_bus = cdns_pci_map_bus,
+ .read = cdns_ti_pcie_config_read,
+ .write = cdns_ti_pcie_config_write,
+};
+
+static const struct j721e_pcie_data j721e_pcie_rc_data = {
+ .mode = PCI_MODE_RC,
+};
+
+static const struct j721e_pcie_data j721e_pcie_ep_data = {
+ .mode = PCI_MODE_EP,
+};
+
+static const struct of_device_id of_j721e_pcie_match[] = {
+ {
+ .compatible = "ti,j721e-pcie-host",
+ .data = &j721e_pcie_rc_data,
+ },
+ {
+ .compatible = "ti,j721e-pcie-ep",
+ .data = &j721e_pcie_ep_data,
+ },
+ {},
+};
+
+static int j721e_pcie_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *node = dev->of_node;
+ struct pci_host_bridge *bridge;
+ struct j721e_pcie_data *data;
+ struct cdns_pcie *cdns_pcie;
+ struct j721e_pcie *pcie;
+ struct cdns_pcie_rc *rc;
+ struct cdns_pcie_ep *ep;
+ struct gpio_desc *gpiod;
+ void __iomem *base;
+ u32 num_lanes;
+ u32 mode;
+ int ret;
+ int irq;
+
+ data = (struct j721e_pcie_data *)of_device_get_match_data(dev);
+ if (!data)
+ return -EINVAL;
+
+ mode = (u32)data->mode;
+
+ pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
+ if (!pcie)
+ return -ENOMEM;
+
+ pcie->dev = dev;
+ pcie->mode = mode;
+
+ base = devm_platform_ioremap_resource_byname(pdev, "intd_cfg");
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+ pcie->intd_cfg_base = base;
+
+ base = devm_platform_ioremap_resource_byname(pdev, "user_cfg");
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+ pcie->user_cfg_base = base;
+
+ ret = of_property_read_u32(node, "num-lanes", &num_lanes);
+ if (ret || num_lanes > MAX_LANES)
+ num_lanes = 1;
+ pcie->num_lanes = num_lanes;
+
+ irq = platform_get_irq_byname(pdev, "link_state");
+ if (irq < 0)
+ return irq;
+
+ dev_set_drvdata(dev, pcie);
+ pm_runtime_enable(dev);
+ ret = pm_runtime_get_sync(dev);
+ if (ret < 0) {
+ dev_err(dev, "pm_runtime_get_sync failed\n");
+ goto err_get_sync;
+ }
+
+ ret = j721e_pcie_ctrl_init(pcie);
+ if (ret < 0) {
+ dev_err(dev, "pm_runtime_get_sync failed\n");
+ goto err_get_sync;
+ }
+
+ ret = devm_request_irq(dev, irq, j721e_pcie_link_irq_handler, 0,
+ "j721e-pcie-link-down-irq", pcie);
+ if (ret < 0) {
+ dev_err(dev, "failed to request link state IRQ %d\n", irq);
+ goto err_get_sync;
+ }
+
+ j721e_pcie_config_link_irq(pcie);
+
+ switch (mode) {
+ case PCI_MODE_RC:
+ if (!IS_ENABLED(CONFIG_PCIE_CADENCE_HOST)) {
+ ret = -ENODEV;
+ goto err_get_sync;
+ }
+
+ bridge = devm_pci_alloc_host_bridge(dev, sizeof(*rc));
+ if (!bridge) {
+ ret = -ENOMEM;
+ goto err_get_sync;
+ }
+
+ bridge->ops = &cdns_ti_pcie_host_ops;
+ rc = pci_host_bridge_priv(bridge);
+
+ cdns_pcie = &rc->pcie;
+ cdns_pcie->dev = dev;
+ cdns_pcie->ops = &j721e_ops_ops;
+ pcie->cdns_pcie = cdns_pcie;
+
+ gpiod = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
+ if (IS_ERR(gpiod)) {
+ ret = PTR_ERR(gpiod);
+ if (ret != -EPROBE_DEFER)
+ dev_err(dev, "Failed to get reset GPIO\n");
+ goto err_get_sync;
+ }
+
+ ret = cdns_pcie_init_phy(dev, cdns_pcie);
+ if (ret) {
+ dev_err(dev, "Failed to init phy\n");
+ goto err_get_sync;
+ }
+
+ /*
+ * "Power Sequencing and Reset Signal Timings" table in
+ * PCI EXPRESS CARD ELECTROMECHANICAL SPECIFICATION, REV. 3.0
+ * indicates PERST# should be deasserted after minimum of 100us
+ * once REFCLK is stable. The REFCLK to the connector in RC
+ * mode is selected while enabling the PHY. So deassert PERST#
+ * after 100 us.
+ */
+ if (gpiod) {
+ usleep_range(100, 200);
+ gpiod_set_value_cansleep(gpiod, 1);
+ }
+
+ ret = cdns_pcie_host_setup(rc);
+ if (ret < 0)
+ goto err_pcie_setup;
+
+ break;
+ case PCI_MODE_EP:
+ if (!IS_ENABLED(CONFIG_PCIE_CADENCE_EP)) {
+ ret = -ENODEV;
+ goto err_get_sync;
+ }
+
+ ep = devm_kzalloc(dev, sizeof(*ep), GFP_KERNEL);
+ if (!ep) {
+ ret = -ENOMEM;
+ goto err_get_sync;
+ }
+
+ cdns_pcie = &ep->pcie;
+ cdns_pcie->dev = dev;
+ cdns_pcie->ops = &j721e_ops_ops;
+ pcie->cdns_pcie = cdns_pcie;
+
+ ret = cdns_pcie_init_phy(dev, cdns_pcie);
+ if (ret) {
+ dev_err(dev, "Failed to init phy\n");
+ goto err_get_sync;
+ }
+
+ ret = cdns_pcie_ep_setup(ep);
+ if (ret < 0)
+ goto err_pcie_setup;
+
+ break;
+ default:
+ dev_err(dev, "INVALID device type %d\n", mode);
+ }
+
+ return 0;
+
+err_pcie_setup:
+ cdns_pcie_disable_phy(cdns_pcie);
+
+err_get_sync:
+ pm_runtime_put(dev);
+ pm_runtime_disable(dev);
+
+ return ret;
+}
+
+static int j721e_pcie_remove(struct platform_device *pdev)
+{
+ struct j721e_pcie *pcie = platform_get_drvdata(pdev);
+ struct cdns_pcie *cdns_pcie = pcie->cdns_pcie;
+ struct device *dev = &pdev->dev;
+
+ cdns_pcie_disable_phy(cdns_pcie);
+ pm_runtime_put(dev);
+ pm_runtime_disable(dev);
+
+ return 0;
+}
+
+static struct platform_driver j721e_pcie_driver = {
+ .probe = j721e_pcie_probe,
+ .remove = j721e_pcie_remove,
+ .driver = {
+ .name = "j721e-pcie",
+ .of_match_table = of_j721e_pcie_match,
+ .suppress_bind_attrs = true,
+ },
+};
+builtin_platform_driver(j721e_pcie_driver);
diff --git a/drivers/pci/controller/cadence/pcie-cadence-host.c b/drivers/pci/controller/cadence/pcie-cadence-host.c
index 7ee9e06f1285..cf8b34b71b8f 100644
--- a/drivers/pci/controller/cadence/pcie-cadence-host.c
+++ b/drivers/pci/controller/cadence/pcie-cadence-host.c
@@ -17,8 +17,8 @@ static u64 bar_max_size[] = {
[RP_NO_BAR] = _BITULL(63),
};
-static void __iomem *cdns_pci_map_bus(struct pci_bus *bus, unsigned int devfn,
- int where)
+void __iomem *cdns_pci_map_bus(struct pci_bus *bus, unsigned int devfn,
+ int where)
{
struct pci_host_bridge *bridge = pci_find_host_bridge(bus);
struct cdns_pcie_rc *rc = pci_host_bridge_priv(bridge);
diff --git a/drivers/pci/controller/cadence/pcie-cadence.h b/drivers/pci/controller/cadence/pcie-cadence.h
index 1bf7d4e09b8a..f8e8144e222d 100644
--- a/drivers/pci/controller/cadence/pcie-cadence.h
+++ b/drivers/pci/controller/cadence/pcie-cadence.h
@@ -469,11 +469,19 @@ static inline bool cdns_pcie_link_up(struct cdns_pcie *pcie)
#ifdef CONFIG_PCIE_CADENCE_HOST
int cdns_pcie_host_setup(struct cdns_pcie_rc *rc);
+void __iomem *cdns_pci_map_bus(struct pci_bus *bus, unsigned int devfn,
+ int where);
#else
static inline int cdns_pcie_host_setup(struct cdns_pcie_rc *rc)
{
return 0;
}
+
+static void __iomem *cdns_pci_map_bus(struct pci_bus *bus, unsigned int devfn,
+ int where)
+{
+ return NULL;
+}
#endif
#ifdef CONFIG_PCIE_CADENCE_EP
--
2.17.1
^ permalink raw reply related
* [PATCH v5 14/14] MAINTAINERS: Add Kishon Vijay Abraham I for TI J721E SoC PCIe
From: Kishon Vijay Abraham I @ 2020-05-22 3:36 UTC (permalink / raw)
To: Tom Joseph, Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas
Cc: linux-pci, linux-kernel, Arnd Bergmann, Greg Kroah-Hartman,
devicetree, linux-omap, linux-arm-kernel, Kishon Vijay Abraham I
In-Reply-To: <20200522033631.32574-1-kishon@ti.com>
Add Kishon Vijay Abraham I as MAINTAINER for TI J721E SoC PCIe.
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
---
MAINTAINERS | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/MAINTAINERS b/MAINTAINERS
index 2926327e4976..9d40e1318f7c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12978,12 +12978,14 @@ S: Maintained
F: Documentation/devicetree/bindings/pci/designware-pcie.txt
F: drivers/pci/controller/dwc/*designware*
-PCI DRIVER FOR TI DRA7XX
+PCI DRIVER FOR TI DRA7XX/J721E
M: Kishon Vijay Abraham I <kishon@ti.com>
L: linux-omap@vger.kernel.org
L: linux-pci@vger.kernel.org
+L: linux-arm-kernel@lists.infradead.org
S: Supported
F: Documentation/devicetree/bindings/pci/ti-pci.txt
+F: drivers/pci/controller/cadence/pci-j721e.c
F: drivers/pci/controller/dwc/pci-dra7xx.c
PCI DRIVER FOR TI KEYSTONE
--
2.17.1
^ permalink raw reply related
* [PATCH v5 09/14] PCI: cadence: Add MSI-X support to Endpoint driver
From: Kishon Vijay Abraham I @ 2020-05-22 3:36 UTC (permalink / raw)
To: Tom Joseph, Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas
Cc: linux-pci, linux-kernel, Arnd Bergmann, Greg Kroah-Hartman,
devicetree, linux-omap, linux-arm-kernel, Kishon Vijay Abraham I,
Alan Douglas
In-Reply-To: <20200522033631.32574-1-kishon@ti.com>
From: Alan Douglas <adouglas@cadence.com>
Implement ->set_msix() and ->get_msix() callback functions in order
to configure MSIX capability in the PCIe endpoint controller.
Add cdns_pcie_ep_send_msix_irq() to send MSIX interrupts to Host.
cdns_pcie_ep_send_msix_irq() gets the MSIX table address (virtual
address) from "struct cdns_pcie_epf" that gets initialized in
->set_bar() call back function.
Signed-off-by: Alan Douglas <adouglas@cadence.com>
[kishon@ti.com: Re-implement MSIX support in accordance with the
re-designed core MSI-X interfaces]
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
---
.../pci/controller/cadence/pcie-cadence-ep.c | 108 +++++++++++++++++-
drivers/pci/controller/cadence/pcie-cadence.h | 10 ++
2 files changed, 117 insertions(+), 1 deletion(-)
diff --git a/drivers/pci/controller/cadence/pcie-cadence-ep.c b/drivers/pci/controller/cadence/pcie-cadence-ep.c
index 14021d760482..c5696274d81f 100644
--- a/drivers/pci/controller/cadence/pcie-cadence-ep.c
+++ b/drivers/pci/controller/cadence/pcie-cadence-ep.c
@@ -51,6 +51,7 @@ static int cdns_pcie_ep_set_bar(struct pci_epc *epc, u8 fn,
struct pci_epf_bar *epf_bar)
{
struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
+ struct cdns_pcie_epf *epf = &ep->epf[fn];
struct cdns_pcie *pcie = &ep->pcie;
dma_addr_t bar_phys = epf_bar->phys_addr;
enum pci_barno bar = epf_bar->barno;
@@ -111,6 +112,8 @@ static int cdns_pcie_ep_set_bar(struct pci_epc *epc, u8 fn,
CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL(b, ctrl));
cdns_pcie_writel(pcie, reg, cfg);
+ epf->epf_bar[bar] = epf_bar;
+
return 0;
}
@@ -118,6 +121,7 @@ static void cdns_pcie_ep_clear_bar(struct pci_epc *epc, u8 fn,
struct pci_epf_bar *epf_bar)
{
struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
+ struct cdns_pcie_epf *epf = &ep->epf[fn];
struct cdns_pcie *pcie = &ep->pcie;
enum pci_barno bar = epf_bar->barno;
u32 reg, cfg, b, ctrl;
@@ -139,6 +143,8 @@ static void cdns_pcie_ep_clear_bar(struct pci_epc *epc, u8 fn,
cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR0(fn, bar), 0);
cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR1(fn, bar), 0);
+
+ epf->epf_bar[bar] = NULL;
}
static int cdns_pcie_ep_map_addr(struct pci_epc *epc, u8 fn, phys_addr_t addr,
@@ -224,6 +230,50 @@ static int cdns_pcie_ep_get_msi(struct pci_epc *epc, u8 fn)
return mme;
}
+static int cdns_pcie_ep_get_msix(struct pci_epc *epc, u8 func_no)
+{
+ struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
+ struct cdns_pcie *pcie = &ep->pcie;
+ u32 cap = CDNS_PCIE_EP_FUNC_MSIX_CAP_OFFSET;
+ u32 val, reg;
+
+ reg = cap + PCI_MSIX_FLAGS;
+ val = cdns_pcie_ep_fn_readw(pcie, func_no, reg);
+ if (!(val & PCI_MSIX_FLAGS_ENABLE))
+ return -EINVAL;
+
+ val &= PCI_MSIX_FLAGS_QSIZE;
+
+ return val;
+}
+
+static int cdns_pcie_ep_set_msix(struct pci_epc *epc, u8 fn, u16 interrupts,
+ enum pci_barno bir, u32 offset)
+{
+ struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
+ struct cdns_pcie *pcie = &ep->pcie;
+ u32 cap = CDNS_PCIE_EP_FUNC_MSIX_CAP_OFFSET;
+ u32 val, reg;
+
+ reg = cap + PCI_MSIX_FLAGS;
+ val = cdns_pcie_ep_fn_readw(pcie, fn, reg);
+ val &= ~PCI_MSIX_FLAGS_QSIZE;
+ val |= interrupts;
+ cdns_pcie_ep_fn_writew(pcie, fn, reg, val);
+
+ /* Set MSIX BAR and offset */
+ reg = cap + PCI_MSIX_TABLE;
+ val = offset | bir;
+ cdns_pcie_ep_fn_writel(pcie, fn, reg, val);
+
+ /* Set PBA BAR and offset. BAR must match MSIX BAR */
+ reg = cap + PCI_MSIX_PBA;
+ val = (offset + (interrupts * PCI_MSIX_ENTRY_SIZE)) | bir;
+ cdns_pcie_ep_fn_writel(pcie, fn, reg, val);
+
+ return 0;
+}
+
static void cdns_pcie_ep_assert_intx(struct cdns_pcie_ep *ep, u8 fn,
u8 intx, bool is_asserted)
{
@@ -330,6 +380,52 @@ static int cdns_pcie_ep_send_msi_irq(struct cdns_pcie_ep *ep, u8 fn,
return 0;
}
+static int cdns_pcie_ep_send_msix_irq(struct cdns_pcie_ep *ep, u8 fn,
+ u16 interrupt_num)
+{
+ u32 cap = CDNS_PCIE_EP_FUNC_MSIX_CAP_OFFSET;
+ u32 tbl_offset, msg_data, reg, vec_ctrl;
+ struct cdns_pcie *pcie = &ep->pcie;
+ struct pci_epf_msix_tbl *msix_tbl;
+ struct cdns_pcie_epf *epf;
+ u64 pci_addr_mask = 0xff;
+ u64 msg_addr;
+ u16 flags;
+ u8 bir;
+
+ /* Check whether the MSI-X feature has been enabled by the PCI host. */
+ flags = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_MSIX_FLAGS);
+ if (!(flags & PCI_MSIX_FLAGS_ENABLE))
+ return -EINVAL;
+
+ reg = cap + PCI_MSIX_TABLE;
+ tbl_offset = cdns_pcie_ep_fn_readl(pcie, fn, reg);
+ bir = tbl_offset & PCI_MSIX_TABLE_BIR;
+ tbl_offset &= PCI_MSIX_TABLE_OFFSET;
+
+ epf = &ep->epf[fn];
+ msix_tbl = epf->epf_bar[bir]->addr + tbl_offset;
+ msg_addr = msix_tbl[(interrupt_num - 1)].msg_addr;
+ msg_data = msix_tbl[(interrupt_num - 1)].msg_data;
+ vec_ctrl = msix_tbl[(interrupt_num - 1)].vector_ctrl;
+
+ /* Set the outbound region if needed. */
+ if (ep->irq_pci_addr != (msg_addr & ~pci_addr_mask) ||
+ ep->irq_pci_fn != fn) {
+ /* First region was reserved for IRQ writes. */
+ cdns_pcie_set_outbound_region(pcie, fn, 0,
+ false,
+ ep->irq_phys_addr,
+ msg_addr & ~pci_addr_mask,
+ pci_addr_mask + 1);
+ ep->irq_pci_addr = (msg_addr & ~pci_addr_mask);
+ ep->irq_pci_fn = fn;
+ }
+ writel(msg_data, ep->irq_cpu_addr + (msg_addr & pci_addr_mask));
+
+ return 0;
+}
+
static int cdns_pcie_ep_raise_irq(struct pci_epc *epc, u8 fn,
enum pci_epc_irq_type type,
u16 interrupt_num)
@@ -343,6 +439,9 @@ static int cdns_pcie_ep_raise_irq(struct pci_epc *epc, u8 fn,
case PCI_EPC_IRQ_MSI:
return cdns_pcie_ep_send_msi_irq(ep, fn, interrupt_num);
+ case PCI_EPC_IRQ_MSIX:
+ return cdns_pcie_ep_send_msix_irq(ep, fn, interrupt_num);
+
default:
break;
}
@@ -380,7 +479,7 @@ static int cdns_pcie_ep_start(struct pci_epc *epc)
static const struct pci_epc_features cdns_pcie_epc_features = {
.linkup_notifier = false,
.msi_capable = true,
- .msix_capable = false,
+ .msix_capable = true,
};
static const struct pci_epc_features*
@@ -397,6 +496,8 @@ static const struct pci_epc_ops cdns_pcie_epc_ops = {
.unmap_addr = cdns_pcie_ep_unmap_addr,
.set_msi = cdns_pcie_ep_set_msi,
.get_msi = cdns_pcie_ep_get_msi,
+ .set_msix = cdns_pcie_ep_set_msix,
+ .get_msix = cdns_pcie_ep_get_msix,
.raise_irq = cdns_pcie_ep_raise_irq,
.start = cdns_pcie_ep_start,
.get_features = cdns_pcie_ep_get_features,
@@ -455,6 +556,11 @@ int cdns_pcie_ep_setup(struct cdns_pcie_ep *ep)
if (of_property_read_u8(np, "max-functions", &epc->max_functions) < 0)
epc->max_functions = 1;
+ ep->epf = devm_kcalloc(dev, epc->max_functions, sizeof(*ep->epf),
+ GFP_KERNEL);
+ if (!ep->epf)
+ return -ENOMEM;
+
ret = pci_epc_mem_init(epc, pcie->mem_res->start,
resource_size(pcie->mem_res));
if (ret < 0) {
diff --git a/drivers/pci/controller/cadence/pcie-cadence.h b/drivers/pci/controller/cadence/pcie-cadence.h
index 3490723169c6..1bf7d4e09b8a 100644
--- a/drivers/pci/controller/cadence/pcie-cadence.h
+++ b/drivers/pci/controller/cadence/pcie-cadence.h
@@ -113,6 +113,7 @@
#define CDNS_PCIE_EP_FUNC_BASE(fn) (((fn) << 12) & GENMASK(19, 12))
#define CDNS_PCIE_EP_FUNC_MSI_CAP_OFFSET 0x90
+#define CDNS_PCIE_EP_FUNC_MSIX_CAP_OFFSET 0xb0
/*
* Root Port Registers (PCI configuration space for the root port function)
@@ -302,6 +303,14 @@ struct cdns_pcie_rc {
bool avail_ib_bar[CDNS_PCIE_RP_MAX_IB];
};
+/**
+ * struct cdns_pcie_epf - Structure to hold info about endpoint function
+ * @epf_bar: reference to the pci_epf_bar for the six Base Address Registers
+ */
+struct cdns_pcie_epf {
+ struct pci_epf_bar *epf_bar[PCI_STD_NUM_BARS];
+};
+
/**
* struct cdns_pcie_ep - private data for this PCIe endpoint controller driver
* @pcie: Cadence PCIe controller
@@ -329,6 +338,7 @@ struct cdns_pcie_ep {
u64 irq_pci_addr;
u8 irq_pci_fn;
u8 irq_pending;
+ struct cdns_pcie_epf *epf;
};
--
2.17.1
^ permalink raw reply related
* [PATCH v5 10/14] dt-bindings: PCI: Add host mode dt-bindings for TI's J721E SoC
From: Kishon Vijay Abraham I @ 2020-05-22 3:36 UTC (permalink / raw)
To: Tom Joseph, Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas
Cc: linux-pci, linux-kernel, Arnd Bergmann, Greg Kroah-Hartman,
devicetree, linux-omap, linux-arm-kernel, Kishon Vijay Abraham I
In-Reply-To: <20200522033631.32574-1-kishon@ti.com>
Add host mode dt-bindings for TI's J721E SoC.
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Reviewed-by: Rob Herring <robh@kernel.org>
---
.../bindings/pci/ti,j721e-pci-host.yaml | 113 ++++++++++++++++++
1 file changed, 113 insertions(+)
create mode 100644 Documentation/devicetree/bindings/pci/ti,j721e-pci-host.yaml
diff --git a/Documentation/devicetree/bindings/pci/ti,j721e-pci-host.yaml b/Documentation/devicetree/bindings/pci/ti,j721e-pci-host.yaml
new file mode 100644
index 000000000000..d7b60487c6c3
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/ti,j721e-pci-host.yaml
@@ -0,0 +1,113 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/pci/ti,j721e-pci-host.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: TI J721E PCI Host (PCIe Wrapper)
+
+maintainers:
+ - Kishon Vijay Abraham I <kishon@ti.com>
+
+allOf:
+ - $ref: "cdns-pcie-host.yaml#"
+
+properties:
+ compatible:
+ enum:
+ - ti,j721e-pcie-host
+
+ reg:
+ maxItems: 4
+
+ reg-names:
+ items:
+ - const: intd_cfg
+ - const: user_cfg
+ - const: reg
+ - const: cfg
+
+ ti,syscon-pcie-ctrl:
+ description: Phandle to the SYSCON entry required for configuring PCIe mode
+ and link speed.
+ allOf:
+ - $ref: /schemas/types.yaml#/definitions/phandle
+
+ power-domains:
+ maxItems: 1
+
+ clocks:
+ maxItems: 1
+ description: clock-specifier to represent input to the PCIe
+
+ clock-names:
+ items:
+ - const: fck
+
+ vendor-id:
+ const: 0x104c
+
+ device-id:
+ const: 0xb00d
+
+ msi-map: true
+
+required:
+ - compatible
+ - reg
+ - reg-names
+ - ti,syscon-pcie-ctrl
+ - max-link-speed
+ - num-lanes
+ - power-domains
+ - clocks
+ - clock-names
+ - vendor-id
+ - device-id
+ - msi-map
+ - dma-coherent
+ - dma-ranges
+ - ranges
+ - reset-gpios
+ - phys
+ - phy-names
+
+examples:
+ - |
+ #include <dt-bindings/soc/ti,sci_pm_domain.h>
+ #include <dt-bindings/gpio/gpio.h>
+
+ bus {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ pcie0_rc: pcie@2900000 {
+ compatible = "ti,j721e-pcie-host";
+ reg = <0x00 0x02900000 0x00 0x1000>,
+ <0x00 0x02907000 0x00 0x400>,
+ <0x00 0x0d000000 0x00 0x00800000>,
+ <0x00 0x10000000 0x00 0x00001000>;
+ reg-names = "intd_cfg", "user_cfg", "reg", "cfg";
+ ti,syscon-pcie-ctrl = <&pcie0_ctrl>;
+ max-link-speed = <3>;
+ num-lanes = <2>;
+ power-domains = <&k3_pds 239 TI_SCI_PD_EXCLUSIVE>;
+ clocks = <&k3_clks 239 1>;
+ clock-names = "fck";
+ device_type = "pci";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ bus-range = <0x0 0xf>;
+ vendor-id = <0x104c>;
+ device-id = <0xb00d>;
+ msi-map = <0x0 &gic_its 0x0 0x10000>;
+ dma-coherent;
+ reset-gpios = <&exp1 6 GPIO_ACTIVE_HIGH>;
+ phys = <&serdes0_pcie_link>;
+ phy-names = "pcie-phy";
+ ranges = <0x01000000 0x0 0x10001000 0x00 0x10001000 0x0 0x0010000>,
+ <0x02000000 0x0 0x10011000 0x00 0x10011000 0x0 0x7fef000>;
+ dma-ranges = <0x02000000 0x0 0x0 0x0 0x0 0x10000 0x0>;
+ };
+ };
--
2.17.1
^ permalink raw reply related
* [PATCH v5 07/14] PCI: cadence: Add new *ops* for CPU addr fixup
From: Kishon Vijay Abraham I @ 2020-05-22 3:36 UTC (permalink / raw)
To: Tom Joseph, Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas
Cc: linux-pci, linux-kernel, Arnd Bergmann, Greg Kroah-Hartman,
devicetree, linux-omap, linux-arm-kernel, Kishon Vijay Abraham I
In-Reply-To: <20200522033631.32574-1-kishon@ti.com>
Cadence driver uses "mem" memory resource to obtain the offset of
configuration space address region, memory space address region and
message space address region. The obtained offset is used to program
the Address Translation Unit (ATU). However certain platforms like TI's
J721E SoC require the absolute address to be programmed in the ATU and not
just the offset.
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
---
.../pci/controller/cadence/pcie-cadence-host.c | 15 ++++-----------
.../pci/controller/cadence/pcie-cadence-plat.c | 13 +++++++++++++
drivers/pci/controller/cadence/pcie-cadence.c | 8 ++++++--
drivers/pci/controller/cadence/pcie-cadence.h | 1 +
4 files changed, 24 insertions(+), 13 deletions(-)
diff --git a/drivers/pci/controller/cadence/pcie-cadence-host.c b/drivers/pci/controller/cadence/pcie-cadence-host.c
index 62796791f02c..3003fafa3bfa 100644
--- a/drivers/pci/controller/cadence/pcie-cadence-host.c
+++ b/drivers/pci/controller/cadence/pcie-cadence-host.c
@@ -330,15 +330,14 @@ static int cdns_pcie_host_map_dma_ranges(struct cdns_pcie_rc *rc)
static int cdns_pcie_host_init_address_translation(struct cdns_pcie_rc *rc)
{
struct cdns_pcie *pcie = &rc->pcie;
- struct resource *mem_res = pcie->mem_res;
struct resource *bus_range = rc->bus_range;
struct resource *cfg_res = rc->cfg_res;
struct device *dev = pcie->dev;
struct device_node *np = dev->of_node;
struct of_pci_range_parser parser;
+ u64 cpu_addr = cfg_res->start;
struct of_pci_range range;
u32 addr0, addr1, desc1;
- u64 cpu_addr;
int r, err;
/*
@@ -351,7 +350,9 @@ static int cdns_pcie_host_init_address_translation(struct cdns_pcie_rc *rc)
cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_PCI_ADDR1(0), addr1);
cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_DESC1(0), desc1);
- cpu_addr = cfg_res->start - mem_res->start;
+ if (pcie->ops->cpu_addr_fixup)
+ cpu_addr = pcie->ops->cpu_addr_fixup(pcie, cpu_addr);
+
addr0 = CDNS_PCIE_AT_OB_REGION_CPU_ADDR0_NBITS(12) |
(lower_32_bits(cpu_addr) & GENMASK(31, 8));
addr1 = upper_32_bits(cpu_addr);
@@ -480,14 +481,6 @@ int cdns_pcie_host_setup(struct cdns_pcie_rc *rc)
}
rc->cfg_res = res;
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mem");
- if (!res) {
- dev_err(dev, "missing \"mem\"\n");
- return -EINVAL;
- }
-
- pcie->mem_res = res;
-
ret = cdns_pcie_start_link(pcie);
if (ret) {
dev_err(dev, "Failed to start link\n");
diff --git a/drivers/pci/controller/cadence/pcie-cadence-plat.c b/drivers/pci/controller/cadence/pcie-cadence-plat.c
index f5c6bf6dfcb8..6f5f07b3eed1 100644
--- a/drivers/pci/controller/cadence/pcie-cadence-plat.c
+++ b/drivers/pci/controller/cadence/pcie-cadence-plat.c
@@ -13,6 +13,8 @@
#include <linux/of_device.h>
#include "pcie-cadence.h"
+#define CDNS_PLAT_CPU_TO_BUS_ADDR 0x0FFFFFFF
+
/**
* struct cdns_plat_pcie - private data for this PCIe platform driver
* @pcie: Cadence PCIe controller
@@ -30,6 +32,15 @@ struct cdns_plat_pcie_of_data {
static const struct of_device_id cdns_plat_pcie_of_match[];
+static u64 cdns_plat_cpu_addr_fixup(struct cdns_pcie *pcie, u64 cpu_addr)
+{
+ return cpu_addr & CDNS_PLAT_CPU_TO_BUS_ADDR;
+}
+
+static const struct cdns_pcie_ops cdns_plat_ops = {
+ .cpu_addr_fixup = cdns_plat_cpu_addr_fixup,
+};
+
static int cdns_plat_pcie_probe(struct platform_device *pdev)
{
const struct cdns_plat_pcie_of_data *data;
@@ -66,6 +77,7 @@ static int cdns_plat_pcie_probe(struct platform_device *pdev)
rc = pci_host_bridge_priv(bridge);
rc->pcie.dev = dev;
+ rc->pcie.ops = &cdns_plat_ops;
cdns_plat_pcie->pcie = &rc->pcie;
cdns_plat_pcie->is_rc = is_rc;
@@ -93,6 +105,7 @@ static int cdns_plat_pcie_probe(struct platform_device *pdev)
return -ENOMEM;
ep->pcie.dev = dev;
+ ep->pcie.ops = &cdns_plat_ops;
cdns_plat_pcie->pcie = &ep->pcie;
cdns_plat_pcie->is_rc = is_rc;
diff --git a/drivers/pci/controller/cadence/pcie-cadence.c b/drivers/pci/controller/cadence/pcie-cadence.c
index cd795f6fc1e2..8a02981fd456 100644
--- a/drivers/pci/controller/cadence/pcie-cadence.c
+++ b/drivers/pci/controller/cadence/pcie-cadence.c
@@ -73,7 +73,9 @@ void cdns_pcie_set_outbound_region(struct cdns_pcie *pcie, u8 fn,
cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_DESC1(r), desc1);
/* Set the CPU address */
- cpu_addr -= pcie->mem_res->start;
+ if (pcie->ops->cpu_addr_fixup)
+ cpu_addr = pcie->ops->cpu_addr_fixup(pcie, cpu_addr);
+
addr0 = CDNS_PCIE_AT_OB_REGION_CPU_ADDR0_NBITS(nbits) |
(lower_32_bits(cpu_addr) & GENMASK(31, 8));
addr1 = upper_32_bits(cpu_addr);
@@ -100,7 +102,9 @@ void cdns_pcie_set_outbound_region_for_normal_msg(struct cdns_pcie *pcie, u8 fn,
}
/* Set the CPU address */
- cpu_addr -= pcie->mem_res->start;
+ if (pcie->ops->cpu_addr_fixup)
+ cpu_addr = pcie->ops->cpu_addr_fixup(pcie, cpu_addr);
+
addr0 = CDNS_PCIE_AT_OB_REGION_CPU_ADDR0_NBITS(17) |
(lower_32_bits(cpu_addr) & GENMASK(31, 8));
addr1 = upper_32_bits(cpu_addr);
diff --git a/drivers/pci/controller/cadence/pcie-cadence.h b/drivers/pci/controller/cadence/pcie-cadence.h
index c013e629e9fa..3490723169c6 100644
--- a/drivers/pci/controller/cadence/pcie-cadence.h
+++ b/drivers/pci/controller/cadence/pcie-cadence.h
@@ -254,6 +254,7 @@ struct cdns_pcie_ops {
int (*start_link)(struct cdns_pcie *pcie);
void (*stop_link)(struct cdns_pcie *pcie);
bool (*link_up)(struct cdns_pcie *pcie);
+ u64 (*cpu_addr_fixup)(struct cdns_pcie *pcie, u64 cpu_addr);
};
/**
--
2.17.1
^ permalink raw reply related
* [PATCH v5 06/14] dt-bindings: PCI: cadence: Remove "mem" from reg binding
From: Kishon Vijay Abraham I @ 2020-05-22 3:36 UTC (permalink / raw)
To: Tom Joseph, Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas
Cc: linux-pci, linux-kernel, Arnd Bergmann, Greg Kroah-Hartman,
devicetree, linux-omap, linux-arm-kernel, Kishon Vijay Abraham I
In-Reply-To: <20200522033631.32574-1-kishon@ti.com>
"mem" is not a memory resource and it overlaps with PCIe config space
and memory region. Removve "mem" from reg binding.
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
---
.../devicetree/bindings/pci/cdns,cdns-pcie-host.yaml | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-host.yaml b/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-host.yaml
index 84a8f095d031..6d67067843bf 100644
--- a/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-host.yaml
+++ b/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-host.yaml
@@ -18,13 +18,12 @@ properties:
const: cdns,cdns-pcie-host
reg:
- maxItems: 3
+ maxItems: 2
reg-names:
items:
- const: reg
- const: cfg
- - const: mem
msi-parent: true
@@ -49,9 +48,8 @@ examples:
device-id = <0x0200>;
reg = <0x0 0xfb000000 0x0 0x01000000>,
- <0x0 0x41000000 0x0 0x00001000>,
- <0x0 0x40000000 0x0 0x04000000>;
- reg-names = "reg", "cfg", "mem";
+ <0x0 0x41000000 0x0 0x00001000>;
+ reg-names = "reg", "cfg";
ranges = <0x02000000 0x0 0x42000000 0x0 0x42000000 0x0 0x1000000>,
<0x01000000 0x0 0x43000000 0x0 0x43000000 0x0 0x0010000>;
--
2.17.1
^ permalink raw reply related
* [PATCH v5 05/14] PCI: cadence: Allow pci_host_bridge to have custom pci_ops
From: Kishon Vijay Abraham I @ 2020-05-22 3:36 UTC (permalink / raw)
To: Tom Joseph, Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas
Cc: linux-pci, linux-kernel, Arnd Bergmann, Greg Kroah-Hartman,
devicetree, linux-omap, linux-arm-kernel, Kishon Vijay Abraham I
In-Reply-To: <20200522033631.32574-1-kishon@ti.com>
Certain platforms like TI's J721E allows only 32-bit configuration
space access. In such cases pci_generic_config_read and
pci_generic_config_write cannot be used. Add support in Cadence core
to let pci_host_bridge have custom pci_ops.
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
---
drivers/pci/controller/cadence/pcie-cadence-host.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/pci/controller/cadence/pcie-cadence-host.c b/drivers/pci/controller/cadence/pcie-cadence-host.c
index 93a9414932a9..62796791f02c 100644
--- a/drivers/pci/controller/cadence/pcie-cadence-host.c
+++ b/drivers/pci/controller/cadence/pcie-cadence-host.c
@@ -508,7 +508,8 @@ int cdns_pcie_host_setup(struct cdns_pcie_rc *rc)
list_splice_init(&resources, &bridge->windows);
bridge->dev.parent = dev;
bridge->busnr = pcie->bus;
- bridge->ops = &cdns_pcie_host_ops;
+ if (!bridge->ops)
+ bridge->ops = &cdns_pcie_host_ops;
bridge->map_irq = of_irq_parse_and_map_pci;
bridge->swizzle_irq = pci_common_swizzle;
--
2.17.1
^ permalink raw reply related
* [PATCH v5 03/14] PCI: cadence: Convert all r/w accessors to perform only 32-bit accesses
From: Kishon Vijay Abraham I @ 2020-05-22 3:36 UTC (permalink / raw)
To: Tom Joseph, Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas
Cc: linux-pci, linux-kernel, Arnd Bergmann, Greg Kroah-Hartman,
devicetree, linux-omap, linux-arm-kernel, Kishon Vijay Abraham I
In-Reply-To: <20200522033631.32574-1-kishon@ti.com>
Certain platforms like TI's J721E using Cadence PCIe IP can perform only
32-bit accesses for reading or writing to Cadence registers. Convert all
read and write accesses to 32-bit in Cadence PCIe driver in preparation
for adding PCIe support in TI's J721E SoC.
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
---
drivers/pci/controller/cadence/pcie-cadence.h | 71 ++++++++++++++-----
1 file changed, 53 insertions(+), 18 deletions(-)
diff --git a/drivers/pci/controller/cadence/pcie-cadence.h b/drivers/pci/controller/cadence/pcie-cadence.h
index bc49c22e48a9..737e9561092b 100644
--- a/drivers/pci/controller/cadence/pcie-cadence.h
+++ b/drivers/pci/controller/cadence/pcie-cadence.h
@@ -319,50 +319,88 @@ struct cdns_pcie_ep {
/* Register access */
-static inline void cdns_pcie_writeb(struct cdns_pcie *pcie, u32 reg, u8 value)
+static inline void cdns_pcie_writel(struct cdns_pcie *pcie, u32 reg, u32 value)
{
- writeb(value, pcie->reg_base + reg);
+ writel(value, pcie->reg_base + reg);
}
-static inline void cdns_pcie_writew(struct cdns_pcie *pcie, u32 reg, u16 value)
+static inline u32 cdns_pcie_readl(struct cdns_pcie *pcie, u32 reg)
{
- writew(value, pcie->reg_base + reg);
+ return readl(pcie->reg_base + reg);
}
-static inline void cdns_pcie_writel(struct cdns_pcie *pcie, u32 reg, u32 value)
+static inline u32 cdns_pcie_read_sz(void __iomem *addr, int size)
{
- writel(value, pcie->reg_base + reg);
+ void __iomem *aligned_addr = PTR_ALIGN_DOWN(addr, 0x4);
+ unsigned int offset = (unsigned long)addr & 0x3;
+ u32 val = readl(aligned_addr);
+
+ if (!IS_ALIGNED((uintptr_t)addr, size)) {
+ WARN(1, "Address %p and size %d are not aligned\n", addr, size);
+ return 0;
+ }
+
+ if (size > 2)
+ return val;
+
+ return (val >> (8 * offset)) & ((1 << (size * 8)) - 1);
}
-static inline u32 cdns_pcie_readl(struct cdns_pcie *pcie, u32 reg)
+static inline void cdns_pcie_write_sz(void __iomem *addr, int size, u32 value)
{
- return readl(pcie->reg_base + reg);
+ void __iomem *aligned_addr = PTR_ALIGN_DOWN(addr, 0x4);
+ unsigned int offset = (unsigned long)addr & 0x3;
+ u32 mask;
+ u32 val;
+
+ if (!IS_ALIGNED((uintptr_t)addr, size)) {
+ WARN(1, "Address %p and size %d are not aligned\n", addr, size);
+ return;
+ }
+
+ if (size > 2) {
+ writel(value, addr);
+ return;
+ }
+
+ mask = ~(((1 << (size * 8)) - 1) << (offset * 8));
+ val = readl(aligned_addr) & mask;
+ val |= value << (offset * 8);
+ writel(val, aligned_addr);
}
/* Root Port register access */
static inline void cdns_pcie_rp_writeb(struct cdns_pcie *pcie,
u32 reg, u8 value)
{
- writeb(value, pcie->reg_base + CDNS_PCIE_RP_BASE + reg);
+ void __iomem *addr = pcie->reg_base + CDNS_PCIE_RP_BASE + reg;
+
+ cdns_pcie_write_sz(addr, 0x1, value);
}
static inline void cdns_pcie_rp_writew(struct cdns_pcie *pcie,
u32 reg, u16 value)
{
- writew(value, pcie->reg_base + CDNS_PCIE_RP_BASE + reg);
+ void __iomem *addr = pcie->reg_base + CDNS_PCIE_RP_BASE + reg;
+
+ cdns_pcie_write_sz(addr, 0x2, value);
}
/* Endpoint Function register access */
static inline void cdns_pcie_ep_fn_writeb(struct cdns_pcie *pcie, u8 fn,
u32 reg, u8 value)
{
- writeb(value, pcie->reg_base + CDNS_PCIE_EP_FUNC_BASE(fn) + reg);
+ void __iomem *addr = pcie->reg_base + CDNS_PCIE_EP_FUNC_BASE(fn) + reg;
+
+ cdns_pcie_write_sz(addr, 0x1, value);
}
static inline void cdns_pcie_ep_fn_writew(struct cdns_pcie *pcie, u8 fn,
u32 reg, u16 value)
{
- writew(value, pcie->reg_base + CDNS_PCIE_EP_FUNC_BASE(fn) + reg);
+ void __iomem *addr = pcie->reg_base + CDNS_PCIE_EP_FUNC_BASE(fn) + reg;
+
+ cdns_pcie_write_sz(addr, 0x2, value);
}
static inline void cdns_pcie_ep_fn_writel(struct cdns_pcie *pcie, u8 fn,
@@ -371,14 +409,11 @@ static inline void cdns_pcie_ep_fn_writel(struct cdns_pcie *pcie, u8 fn,
writel(value, pcie->reg_base + CDNS_PCIE_EP_FUNC_BASE(fn) + reg);
}
-static inline u8 cdns_pcie_ep_fn_readb(struct cdns_pcie *pcie, u8 fn, u32 reg)
-{
- return readb(pcie->reg_base + CDNS_PCIE_EP_FUNC_BASE(fn) + reg);
-}
-
static inline u16 cdns_pcie_ep_fn_readw(struct cdns_pcie *pcie, u8 fn, u32 reg)
{
- return readw(pcie->reg_base + CDNS_PCIE_EP_FUNC_BASE(fn) + reg);
+ void __iomem *addr = pcie->reg_base + CDNS_PCIE_EP_FUNC_BASE(fn) + reg;
+
+ return cdns_pcie_read_sz(addr, 0x2);
}
static inline u32 cdns_pcie_ep_fn_readl(struct cdns_pcie *pcie, u8 fn, u32 reg)
--
2.17.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox