Re: [PATCH 15/18] hw/riscv: microchip_pfsoc: Connect 2 Cadence GEMs

2020-08-21 Thread Alistair Francis
On Fri, Aug 14, 2020 at 9:51 AM Bin Meng  wrote:
>
> From: Bin Meng 
>
> Microchip PolarFire SoC integrates 2 Candence GEMs to provide
> IEEE 802.3 standard-compliant 10/100/1000 Mbps ethernet interface.
>
> On the Icicle Kit board, GEM0 connects to a PHY at address 8 while
> GEM1 connects to a PHY at address 9.
>
> The 2nd stage bootloader (U-Boot) is using GEM1 by default, so we
> must specify 2 '-nic' options from the command line in order to get
> a working ethernet.
>
> Signed-off-by: Bin Meng 

Reviewed-by: Alistair Francis 

Alistair

> ---
>
>  hw/riscv/microchip_pfsoc.c | 39 
> ++
>  include/hw/riscv/microchip_pfsoc.h |  7 +++
>  2 files changed, 46 insertions(+)
>
> diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
> index 1c67cbc..625b511 100644
> --- a/hw/riscv/microchip_pfsoc.c
> +++ b/hw/riscv/microchip_pfsoc.c
> @@ -14,6 +14,7 @@
>   * 3) MMUARTs (Multi-Mode UART)
>   * 4) Cadence eMMC/SDHC controller and an SD card connected to it
>   * 5) DMA (Direct Memory Access Controller)
> + * 6) GEM (Gigabit Ethernet MAC Controller)
>   *
>   * This board currently generates devicetree dynamically that indicates at 
> least
>   * two harts and up to five harts.
> @@ -59,6 +60,9 @@
>  #define BIOS_FILENAME   "hss.bin"
>  #define RESET_VECTOR0x2022
>
> +/* GEM version */
> +#define GEM_REVISION0x0107010c
> +
>  static const struct MemmapEntry {
>  hwaddr base;
>  hwaddr size;
> @@ -83,6 +87,8 @@ static const struct MemmapEntry {
>  [MICROCHIP_PFSOC_MMUART2] = { 0x20102000, 0x1000 },
>  [MICROCHIP_PFSOC_MMUART3] = { 0x20104000, 0x1000 },
>  [MICROCHIP_PFSOC_MMUART4] = { 0x20106000, 0x1000 },
> +[MICROCHIP_PFSOC_GEM0] ={ 0x2011, 0x2000 },
> +[MICROCHIP_PFSOC_GEM1] ={ 0x20112000, 0x2000 },
>  [MICROCHIP_PFSOC_ENVM_CFG] ={ 0x2020, 0x1000 },
>  [MICROCHIP_PFSOC_ENVM_DATA] =   { 0x2022,0x2 },
>  [MICROCHIP_PFSOC_IOSCB_CFG] =   { 0x3708, 0x1000 },
> @@ -119,6 +125,9 @@ static void microchip_pfsoc_soc_instance_init(Object *obj)
>  object_initialize_child(obj, "dma-controller", >dma,
>  TYPE_MCHP_PFSOC_DMA);
>
> +object_initialize_child(obj, "gem0", >gem0, TYPE_CADENCE_GEM);
> +object_initialize_child(obj, "gem1", >gem1, TYPE_CADENCE_GEM);
> +
>  object_initialize_child(obj, "sd-controller", >sdhci,
>  TYPE_CADENCE_SDHCI);
>  object_initialize_child(OBJECT(>sdhci), "sd-controller.sdhci",
> @@ -136,6 +145,7 @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, 
> Error **errp)
>  MemoryRegion *envm_data = g_new(MemoryRegion, 1);
>  char *plic_hart_config;
>  size_t plic_hart_config_len;
> +NICInfo *nd;
>  int i;
>
>  sysbus_realize(SYS_BUS_DEVICE(>e_cpus), _abort);
> @@ -269,6 +279,35 @@ static void microchip_pfsoc_soc_realize(DeviceState 
> *dev, Error **errp)
>  qdev_get_gpio_in(DEVICE(s->plic), MICROCHIP_PFSOC_MMUART4_IRQ),
>  serial_hd(4));
>
> +/* GEMs */
> +
> +nd = _table[0];
> +if (nd->used) {
> +qemu_check_nic_model(nd, TYPE_CADENCE_GEM);
> +qdev_set_nic_properties(DEVICE(>gem0), nd);
> +}
> +nd = _table[1];
> +if (nd->used) {
> +qemu_check_nic_model(nd, TYPE_CADENCE_GEM);
> +qdev_set_nic_properties(DEVICE(>gem1), nd);
> +}
> +
> +object_property_set_int(OBJECT(>gem0), "revision", GEM_REVISION, 
> errp);
> +object_property_set_int(OBJECT(>gem0), "phy-addr", 8, errp);
> +sysbus_realize(SYS_BUS_DEVICE(>gem0), errp);
> +sysbus_mmio_map(SYS_BUS_DEVICE(>gem0), 0,
> +memmap[MICROCHIP_PFSOC_GEM0].base);
> +sysbus_connect_irq(SYS_BUS_DEVICE(>gem0), 0,
> +qdev_get_gpio_in(DEVICE(s->plic), MICROCHIP_PFSOC_GEM0_IRQ));
> +
> +object_property_set_int(OBJECT(>gem1), "revision", GEM_REVISION, 
> errp);
> +object_property_set_int(OBJECT(>gem1), "phy-addr", 9, errp);
> +sysbus_realize(SYS_BUS_DEVICE(>gem1), errp);
> +sysbus_mmio_map(SYS_BUS_DEVICE(>gem1), 0,
> +memmap[MICROCHIP_PFSOC_GEM1].base);
> +sysbus_connect_irq(SYS_BUS_DEVICE(>gem1), 0,
> +qdev_get_gpio_in(DEVICE(s->plic), MICROCHIP_PFSOC_GEM1_IRQ));
> +
>  /* eNVM */
>  memory_region_init_rom(envm_data, OBJECT(dev), 
> "microchip.pfsoc.envm.data",
> memmap[MICROCHIP_PFSOC_ENVM_DATA].size,
> diff --git a/include/hw/riscv/microchip_pfsoc.h 
> b/include/hw/riscv/microchip_pfsoc.h
> index 7825935..60f994c 100644
> --- a/include/hw/riscv/microchip_pfsoc.h
> +++ b/include/hw/riscv/microchip_pfsoc.h
> @@ -24,6 +24,7 @@
>
>  #include "hw/char/mchp_pfsoc_mmuart.h"
>  #include "hw/dma/mchp_pfsoc_dma.h"
> +#include "hw/net/cadence_gem.h"
>  #include "hw/sd/cadence_sdhci.h"
>
>  typedef struct MicrochipPFSoCState {
> @@ -42,6 +43,8 

[PATCH 15/18] hw/riscv: microchip_pfsoc: Connect 2 Cadence GEMs

2020-08-14 Thread Bin Meng
From: Bin Meng 

Microchip PolarFire SoC integrates 2 Candence GEMs to provide
IEEE 802.3 standard-compliant 10/100/1000 Mbps ethernet interface.

On the Icicle Kit board, GEM0 connects to a PHY at address 8 while
GEM1 connects to a PHY at address 9.

The 2nd stage bootloader (U-Boot) is using GEM1 by default, so we
must specify 2 '-nic' options from the command line in order to get
a working ethernet.

Signed-off-by: Bin Meng 
---

 hw/riscv/microchip_pfsoc.c | 39 ++
 include/hw/riscv/microchip_pfsoc.h |  7 +++
 2 files changed, 46 insertions(+)

diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
index 1c67cbc..625b511 100644
--- a/hw/riscv/microchip_pfsoc.c
+++ b/hw/riscv/microchip_pfsoc.c
@@ -14,6 +14,7 @@
  * 3) MMUARTs (Multi-Mode UART)
  * 4) Cadence eMMC/SDHC controller and an SD card connected to it
  * 5) DMA (Direct Memory Access Controller)
+ * 6) GEM (Gigabit Ethernet MAC Controller)
  *
  * This board currently generates devicetree dynamically that indicates at 
least
  * two harts and up to five harts.
@@ -59,6 +60,9 @@
 #define BIOS_FILENAME   "hss.bin"
 #define RESET_VECTOR0x2022
 
+/* GEM version */
+#define GEM_REVISION0x0107010c
+
 static const struct MemmapEntry {
 hwaddr base;
 hwaddr size;
@@ -83,6 +87,8 @@ static const struct MemmapEntry {
 [MICROCHIP_PFSOC_MMUART2] = { 0x20102000, 0x1000 },
 [MICROCHIP_PFSOC_MMUART3] = { 0x20104000, 0x1000 },
 [MICROCHIP_PFSOC_MMUART4] = { 0x20106000, 0x1000 },
+[MICROCHIP_PFSOC_GEM0] ={ 0x2011, 0x2000 },
+[MICROCHIP_PFSOC_GEM1] ={ 0x20112000, 0x2000 },
 [MICROCHIP_PFSOC_ENVM_CFG] ={ 0x2020, 0x1000 },
 [MICROCHIP_PFSOC_ENVM_DATA] =   { 0x2022,0x2 },
 [MICROCHIP_PFSOC_IOSCB_CFG] =   { 0x3708, 0x1000 },
@@ -119,6 +125,9 @@ static void microchip_pfsoc_soc_instance_init(Object *obj)
 object_initialize_child(obj, "dma-controller", >dma,
 TYPE_MCHP_PFSOC_DMA);
 
+object_initialize_child(obj, "gem0", >gem0, TYPE_CADENCE_GEM);
+object_initialize_child(obj, "gem1", >gem1, TYPE_CADENCE_GEM);
+
 object_initialize_child(obj, "sd-controller", >sdhci,
 TYPE_CADENCE_SDHCI);
 object_initialize_child(OBJECT(>sdhci), "sd-controller.sdhci",
@@ -136,6 +145,7 @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, 
Error **errp)
 MemoryRegion *envm_data = g_new(MemoryRegion, 1);
 char *plic_hart_config;
 size_t plic_hart_config_len;
+NICInfo *nd;
 int i;
 
 sysbus_realize(SYS_BUS_DEVICE(>e_cpus), _abort);
@@ -269,6 +279,35 @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, 
Error **errp)
 qdev_get_gpio_in(DEVICE(s->plic), MICROCHIP_PFSOC_MMUART4_IRQ),
 serial_hd(4));
 
+/* GEMs */
+
+nd = _table[0];
+if (nd->used) {
+qemu_check_nic_model(nd, TYPE_CADENCE_GEM);
+qdev_set_nic_properties(DEVICE(>gem0), nd);
+}
+nd = _table[1];
+if (nd->used) {
+qemu_check_nic_model(nd, TYPE_CADENCE_GEM);
+qdev_set_nic_properties(DEVICE(>gem1), nd);
+}
+
+object_property_set_int(OBJECT(>gem0), "revision", GEM_REVISION, errp);
+object_property_set_int(OBJECT(>gem0), "phy-addr", 8, errp);
+sysbus_realize(SYS_BUS_DEVICE(>gem0), errp);
+sysbus_mmio_map(SYS_BUS_DEVICE(>gem0), 0,
+memmap[MICROCHIP_PFSOC_GEM0].base);
+sysbus_connect_irq(SYS_BUS_DEVICE(>gem0), 0,
+qdev_get_gpio_in(DEVICE(s->plic), MICROCHIP_PFSOC_GEM0_IRQ));
+
+object_property_set_int(OBJECT(>gem1), "revision", GEM_REVISION, errp);
+object_property_set_int(OBJECT(>gem1), "phy-addr", 9, errp);
+sysbus_realize(SYS_BUS_DEVICE(>gem1), errp);
+sysbus_mmio_map(SYS_BUS_DEVICE(>gem1), 0,
+memmap[MICROCHIP_PFSOC_GEM1].base);
+sysbus_connect_irq(SYS_BUS_DEVICE(>gem1), 0,
+qdev_get_gpio_in(DEVICE(s->plic), MICROCHIP_PFSOC_GEM1_IRQ));
+
 /* eNVM */
 memory_region_init_rom(envm_data, OBJECT(dev), "microchip.pfsoc.envm.data",
memmap[MICROCHIP_PFSOC_ENVM_DATA].size,
diff --git a/include/hw/riscv/microchip_pfsoc.h 
b/include/hw/riscv/microchip_pfsoc.h
index 7825935..60f994c 100644
--- a/include/hw/riscv/microchip_pfsoc.h
+++ b/include/hw/riscv/microchip_pfsoc.h
@@ -24,6 +24,7 @@
 
 #include "hw/char/mchp_pfsoc_mmuart.h"
 #include "hw/dma/mchp_pfsoc_dma.h"
+#include "hw/net/cadence_gem.h"
 #include "hw/sd/cadence_sdhci.h"
 
 typedef struct MicrochipPFSoCState {
@@ -42,6 +43,8 @@ typedef struct MicrochipPFSoCState {
 MchpPfSoCMMUartState *serial3;
 MchpPfSoCMMUartState *serial4;
 MchpPfSoCDMAState dma;
+CadenceGEMState gem0;
+CadenceGEMState gem1;
 CadenceSDHCIState sdhci;
 } MicrochipPFSoCState;
 
@@ -84,6 +87,8 @@ enum {
 MICROCHIP_PFSOC_MMUART2,