All of lore.kernel.org
 help / color / mirror / Atom feed
From: Francisco Iglesias <frasse.iglesias@gmail.com>
To: Vikram Garhwal <vikram.garhwal@amd.com>
Cc: qemu-devel@nongnu.org, peter.maydell@linaro.org,
	Alistair Francis <alistair@alistair23.me>,
	"Edgar E. Iglesias" <edgar.iglesias@gmail.com>,
	"open list:Xilinx ZynqMP and..." <qemu-arm@nongnu.org>
Subject: Re: [QEMU][PATCH v4 3/4] xlnx-versal: Connect Xilinx VERSAL CANFD controllers
Date: Tue, 25 Apr 2023 17:36:24 +0200	[thread overview]
Message-ID: <20230425153623.GB7006@fralle-msi> (raw)
In-Reply-To: <20230425063433.25803-4-vikram.garhwal@amd.com>

Hi Vikram,

On [2023 Apr 24] Mon 23:34:32, Vikram Garhwal wrote:
> Connect CANFD0 and CANFD1 on the Versal-virt machine and update xlnx-versal-virt
> document with CANFD command line examples.
> 
> Signed-off-by: Vikram Garhwal <vikram.garhwal@amd.com>
> Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  docs/system/arm/xlnx-versal-virt.rst | 31 ++++++++++++++++++
>  hw/arm/xlnx-versal-virt.c            | 48 ++++++++++++++++++++++++++++
>  hw/arm/xlnx-versal.c                 | 37 +++++++++++++++++++++
>  include/hw/arm/xlnx-versal.h         | 12 +++++++
>  4 files changed, 128 insertions(+)
> 
> diff --git a/docs/system/arm/xlnx-versal-virt.rst b/docs/system/arm/xlnx-versal-virt.rst
> index 92ad10d2da..d2d1b26692 100644
> --- a/docs/system/arm/xlnx-versal-virt.rst
> +++ b/docs/system/arm/xlnx-versal-virt.rst
> @@ -34,6 +34,7 @@ Implemented devices:
>  - DDR memory
>  - BBRAM (36 bytes of Battery-backed RAM)
>  - eFUSE (3072 bytes of one-time field-programmable bit array)
> +- 2 CANFDs
>  
>  QEMU does not yet model any other devices, including the PL and the AI Engine.
>  
> @@ -224,3 +225,33 @@ To use a different index value, N, from default of 1, add:
>  
>    Better yet, do not use actual product data when running guest image
>    on this Xilinx Versal Virt board.
> +
> +Using CANFDs for Versal Virt
> +""""""""""""""""""""""""""""
> +Versal CANFD controller is developed based on SocketCAN and QEMU CAN bus
> +implementation. Bus connection and socketCAN connection for each CAN module
> +can be set through command lines.
> +
> +To connect both CANFD0 and CANFD1 on the same bus:
> +
> +.. code-block:: bash
> +
> +    -object can-bus,id=canbus -machine canbus0=canbus -machine canbus1=canbus
> +
> +To connect CANFD0 and CANFD1 to separate buses:
> +
> +.. code-block:: bash
> +
> +    -object can-bus,id=canbus0 -object can-bus,id=canbus1 \
> +    -machine canbus0=canbus0 -machine canbus1=canbus1
> +
> +The SocketCAN interface can connect to a Physical or a Virtual CAN interfaces on
> +the host machine. Please check this document to learn about CAN interface on
> +Linux: docs/system/devices/can.rst
> +
> +To connect CANFD0 and CANFD1 to host machine's CAN interface can0:
> +
> +.. code-block:: bash
> +
> +    -object can-bus,id=canbus -machine canbus0=canbus -machine canbus1=canbus
> +    -object can-host-socketcan,id=canhost0,if=can0,canbus=canbus
> diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
> index 668a9d65a4..52c93a590d 100644
> --- a/hw/arm/xlnx-versal-virt.c
> +++ b/hw/arm/xlnx-versal-virt.c
> @@ -40,9 +40,11 @@ struct VersalVirt {
>          uint32_t clk_25Mhz;
>          uint32_t usb;
>          uint32_t dwc;
> +        uint32_t canfd[2];
>      } phandle;
>      struct arm_boot_info binfo;
>  
> +    CanBusState *canbus[XLNX_VERSAL_NR_CANFD];
>      struct {
>          bool secure;
>      } cfg;
> @@ -235,6 +237,33 @@ static void fdt_add_uart_nodes(VersalVirt *s)
>      }
>  }
>  
> +static void fdt_add_canfd_nodes(VersalVirt *s)
> +{

In this function we need to modify the generated dtb a little so the kernel
finds the devices correctly.

> +    uint64_t addrs[] = { MM_CANFD0, MM_CANFD1 };
> +    uint32_t size[] = { MM_CANFD0_SIZE, MM_CANFD1_SIZE };
> +    unsigned int irqs[] = { VERSAL_CANFD0_IRQ_0, VERSAL_CANFD1_IRQ_0 };


Here we can swap above 3 lines for below:

    uint64_t addrs[] = { MM_CANFD1, MM_CANFD0 };
    uint32_t size[] = { MM_CANFD1_SIZE, MM_CANFD0_SIZE };
    unsigned int irqs[] = { VERSAL_CANFD1_IRQ_0, VERSAL_CANFD0_IRQ_0 };
    const char clocknames[] = "can_clk\0s_axi_aclk";


> +    int i;
> +
> +    /* Create and connect CANFD0 and CANFD1 nodes to canbus0. */
> +    for (i = 0; i < ARRAY_SIZE(addrs); i++) {
> +        char *name = g_strdup_printf("/canfd@%" PRIx64, addrs[i]);
> +        qemu_fdt_add_subnode(s->fdt, name);


> +        qemu_fdt_setprop_cell(s->fdt, name, "rx-fifo0", 0x40);
> +        qemu_fdt_setprop_cell(s->fdt, name, "enable-rx-fifo1", 0x1);
> +        qemu_fdt_setprop_cell(s->fdt, name, "rx-fifo1", 0x40);

Here we can swap above for 3 lines for below:

        qemu_fdt_setprop_cell(s->fdt, name, "rx-fifo-depth", 0x40);
        qemu_fdt_setprop_cell(s->fdt, name, "tx-mailbox-count", 0x20);

        qemu_fdt_setprop_cells(s->fdt, name, "clocks",
                               s->phandle.clk_25Mhz, s->phandle.clk_25Mhz);
        qemu_fdt_setprop(s->fdt, name, "clock-names",
                         clocknames, sizeof(clocknames));


> +
> +        qemu_fdt_setprop_cells(s->fdt, name, "interrupts",
> +                               GIC_FDT_IRQ_TYPE_SPI, irqs[i],
> +                               GIC_FDT_IRQ_FLAGS_LEVEL_HI);
> +        qemu_fdt_setprop_sized_cells(s->fdt, name, "reg",
> +                                     2, addrs[i], 2, size[i]);
> +        qemu_fdt_setprop_string(s->fdt, name, "compatible",


> +                                "xlnx,versal-canfd");

And here we can swap above line with (kernel compatible):

                                "xlnx,canfd-2.0");

After changing above the linux kernel will find the devices:

...
[    1.791998] CAN device driver interface
[    1.732791] xilinx_can ff060000.canfd can0: reg_base=0x(____ptrval____) irq=28 clock=25000000, tx buffers: actual 32, using 1
[    1.734668] xilinx_can ff070000.canfd can1: reg_base=0x(____ptrval____) irq=29 clock=25000000, tx buffers: actual 32, using 1
...

...
#  ip a
...
2: can0: <NOARP40000> mtu 16 qdisc noop qlen 10
    link/[280] 
3: can1: <NOARP40000> mtu 16 qdisc noop qlen 10
    link/[280] 
...

Looks good otherwise!

Best regards,
Francisco Iglesias


> +
> +        g_free(name);
> +    }
> +}
> +
>  static void fdt_add_fixed_link_nodes(VersalVirt *s, char *gemname,
>                                       uint32_t phandle)
>  {
> @@ -639,12 +668,17 @@ static void versal_virt_init(MachineState *machine)
>                              TYPE_XLNX_VERSAL);
>      object_property_set_link(OBJECT(&s->soc), "ddr", OBJECT(machine->ram),
>                               &error_abort);
> +    object_property_set_link(OBJECT(&s->soc), "canbus0", OBJECT(s->canbus[0]),
> +                             &error_abort);
> +    object_property_set_link(OBJECT(&s->soc), "canbus1", OBJECT(s->canbus[1]),
> +                             &error_abort);
>      sysbus_realize(SYS_BUS_DEVICE(&s->soc), &error_fatal);
>  
>      fdt_create(s);
>      create_virtio_regions(s);
>      fdt_add_gem_nodes(s);
>      fdt_add_uart_nodes(s);
> +    fdt_add_canfd_nodes(s);
>      fdt_add_gic_nodes(s);
>      fdt_add_timer_nodes(s);
>      fdt_add_zdma_nodes(s);
> @@ -712,6 +746,20 @@ static void versal_virt_init(MachineState *machine)
>  
>  static void versal_virt_machine_instance_init(Object *obj)
>  {
> +    VersalVirt *s = XLNX_VERSAL_VIRT_MACHINE(obj);
> +
> +    /*
> +     * User can set canbus0 and canbus1 properties to can-bus object and connect
> +     * to socketcan(optional) interface via command line.
> +     */
> +    object_property_add_link(obj, "canbus0", TYPE_CAN_BUS,
> +                             (Object **)&s->canbus[0],
> +                             object_property_allow_set_link,
> +                             0);
> +    object_property_add_link(obj, "canbus1", TYPE_CAN_BUS,
> +                             (Object **)&s->canbus[1],
> +                             object_property_allow_set_link,
> +                             0);
>  }
>  
>  static void versal_virt_machine_class_init(ObjectClass *oc, void *data)
> diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
> index 69b1b99e93..1594dd6c5c 100644
> --- a/hw/arm/xlnx-versal.c
> +++ b/hw/arm/xlnx-versal.c
> @@ -184,6 +184,38 @@ static void versal_create_uarts(Versal *s, qemu_irq *pic)
>      }
>  }
>  
> +static void versal_create_canfds(Versal *s, qemu_irq *pic)
> +{
> +    int i;
> +    uint32_t irqs[] = { VERSAL_CANFD0_IRQ_0, VERSAL_CANFD1_IRQ_0};
> +    uint64_t addrs[] = { MM_CANFD0, MM_CANFD1 };
> +
> +    for (i = 0; i < ARRAY_SIZE(s->lpd.iou.canfd); i++) {
> +        char *name = g_strdup_printf("canfd%d", i);
> +        SysBusDevice *sbd;
> +        MemoryRegion *mr;
> +
> +        object_initialize_child(OBJECT(s), name, &s->lpd.iou.canfd[i],
> +                                TYPE_XILINX_CANFD);
> +        sbd = SYS_BUS_DEVICE(&s->lpd.iou.canfd[i]);
> +
> +        object_property_set_int(OBJECT(&s->lpd.iou.canfd[i]), "ext_clk_freq",
> +                                XLNX_VERSAL_CANFD_REF_CLK , &error_abort);
> +
> +        object_property_set_link(OBJECT(&s->lpd.iou.canfd[i]), "canfdbus",
> +                                 OBJECT(s->lpd.iou.canbus[i]),
> +                                 &error_abort);
> +
> +        sysbus_realize(sbd, &error_fatal);
> +
> +        mr = sysbus_mmio_get_region(sbd, 0);
> +        memory_region_add_subregion(&s->mr_ps, addrs[i], mr);
> +
> +        sysbus_connect_irq(sbd, 0, pic[irqs[i]]);
> +        g_free(name);
> +    }
> +}
> +
>  static void versal_create_usbs(Versal *s, qemu_irq *pic)
>  {
>      DeviceState *dev;
> @@ -718,6 +750,7 @@ static void versal_realize(DeviceState *dev, Error **errp)
>      versal_create_apu_gic(s, pic);
>      versal_create_rpu_cpus(s);
>      versal_create_uarts(s, pic);
> +    versal_create_canfds(s, pic);
>      versal_create_usbs(s, pic);
>      versal_create_gems(s, pic);
>      versal_create_admas(s, pic);
> @@ -757,6 +790,10 @@ static void versal_init(Object *obj)
>  static Property versal_properties[] = {
>      DEFINE_PROP_LINK("ddr", Versal, cfg.mr_ddr, TYPE_MEMORY_REGION,
>                       MemoryRegion *),
> +    DEFINE_PROP_LINK("canbus0", Versal, lpd.iou.canbus[0],
> +                      TYPE_CAN_BUS, CanBusState *),
> +    DEFINE_PROP_LINK("canbus1", Versal, lpd.iou.canbus[1],
> +                      TYPE_CAN_BUS, CanBusState *),
>      DEFINE_PROP_END_OF_LIST()
>  };
>  
> diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
> index b6786e9832..39ee31185c 100644
> --- a/include/hw/arm/xlnx-versal.h
> +++ b/include/hw/arm/xlnx-versal.h
> @@ -31,6 +31,7 @@
>  #include "hw/dma/xlnx_csu_dma.h"
>  #include "hw/misc/xlnx-versal-crl.h"
>  #include "hw/misc/xlnx-versal-pmc-iou-slcr.h"
> +#include "hw/net/xlnx-versal-canfd.h"
>  
>  #define TYPE_XLNX_VERSAL "xlnx-versal"
>  OBJECT_DECLARE_SIMPLE_TYPE(Versal, XLNX_VERSAL)
> @@ -43,6 +44,8 @@ OBJECT_DECLARE_SIMPLE_TYPE(Versal, XLNX_VERSAL)
>  #define XLNX_VERSAL_NR_SDS     2
>  #define XLNX_VERSAL_NR_XRAM    4
>  #define XLNX_VERSAL_NR_IRQS    192
> +#define XLNX_VERSAL_NR_CANFD   2
> +#define XLNX_VERSAL_CANFD_REF_CLK (24 * 1000 * 1000)
>  
>  struct Versal {
>      /*< private >*/
> @@ -73,6 +76,8 @@ struct Versal {
>              CadenceGEMState gem[XLNX_VERSAL_NR_GEMS];
>              XlnxZDMA adma[XLNX_VERSAL_NR_ADMAS];
>              VersalUsb2 usb;
> +            CanBusState *canbus[XLNX_VERSAL_NR_CANFD];
> +            XlnxVersalCANFDState canfd[XLNX_VERSAL_NR_CANFD];
>          } iou;
>  
>          /* Real-time Processing Unit.  */
> @@ -133,6 +138,8 @@ struct Versal {
>  #define VERSAL_CRL_IRQ             10
>  #define VERSAL_UART0_IRQ_0         18
>  #define VERSAL_UART1_IRQ_0         19
> +#define VERSAL_CANFD0_IRQ_0        20
> +#define VERSAL_CANFD1_IRQ_0        21
>  #define VERSAL_USB0_IRQ_0          22
>  #define VERSAL_GEM0_IRQ_0          56
>  #define VERSAL_GEM0_WAKE_IRQ_0     57
> @@ -163,6 +170,11 @@ struct Versal {
>  #define MM_UART1                    0xff010000U
>  #define MM_UART1_SIZE               0x10000
>  
> +#define MM_CANFD0                   0xff060000U
> +#define MM_CANFD0_SIZE              0x10000
> +#define MM_CANFD1                   0xff070000U
> +#define MM_CANFD1_SIZE              0x10000
> +
>  #define MM_GEM0                     0xff0c0000U
>  #define MM_GEM0_SIZE                0x10000
>  #define MM_GEM1                     0xff0d0000U
> -- 
> 2.17.1
> 

  reply	other threads:[~2023-04-25 15:36 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-04-25  6:34 [QEMU][PATCH v4 0/4] Introduce Xilinx Versal CANFD Vikram Garhwal
2023-04-25  6:34 ` [QEMU][PATCH v4 1/4] MAINTAINERS: Include canfd tests under Xilinx CAN Vikram Garhwal
2023-04-25 15:05   ` Francisco Iglesias
2023-04-25  6:34 ` [QEMU][PATCH v4 2/4] hw/net/can: Introduce Xilinx Versal CANFD controller Vikram Garhwal
2023-05-02 19:13   ` Francisco Iglesias
2023-04-25  6:34 ` [QEMU][PATCH v4 3/4] xlnx-versal: Connect Xilinx VERSAL CANFD controllers Vikram Garhwal
2023-04-25 15:36   ` Francisco Iglesias [this message]
2023-04-25  6:34 ` [QEMU][PATCH v4 4/4] tests/qtest: Introduce tests for Xilinx VERSAL CANFD controller Vikram Garhwal

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230425153623.GB7006@fralle-msi \
    --to=frasse.iglesias@gmail.com \
    --cc=alistair@alistair23.me \
    --cc=edgar.iglesias@gmail.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-arm@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=vikram.garhwal@amd.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.