Add the connection between the slcr's output clocks and the uarts inputs.
Also add the main board clock 'ps_clk', which is hard-coded to 33.33MHz
(the default frequency). This clock is used to feed the slcr's input
clock.
Signed-off-by: Damien Hedde <damien.hedde@greensocs.com>
---
v7
+ update ClockIn/ClockOut types
+ simplify the ps_clk frequency init
---
hw/arm/xilinx_zynq.c | 57 +++++++++++++++++++++++++++++++++++++-------
1 file changed, 49 insertions(+), 8 deletions(-)
diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
index 3a0fa5b23f..261a1690a8 100644
--- a/hw/arm/xilinx_zynq.c
+++ b/hw/arm/xilinx_zynq.c
@@ -34,6 +34,15 @@
#include "hw/char/cadence_uart.h"
#include "hw/net/cadence_gem.h"
#include "hw/cpu/a9mpcore.h"
+#include "hw/qdev-clock.h"
+#include "sysemu/reset.h"
+
+#define TYPE_ZYNQ_MACHINE MACHINE_TYPE_NAME("xilinx-zynq-a9")
+#define ZYNQ_MACHINE(obj) \
+ OBJECT_CHECK(ZynqMachineState, (obj), TYPE_ZYNQ_MACHINE)
+
+/* board base frequency: 33.333333 MHz */
+#define PS_CLK_FREQUENCY (100 * 1000 * 1000 / 3)
#define NUM_SPI_FLASHES 4
#define NUM_QSPI_FLASHES 2
@@ -74,6 +83,11 @@ static const int dma_irqs[8] = {
0xe3401000 + ARMV7_IMM16(extract32((val), 16, 16)), /* movt r1 ... */ \
0xe5801000 + (addr)
+typedef struct ZynqMachineState {
+ MachineState parent;
+ Clock *ps_clk;
+} ZynqMachineState;
+
static void zynq_write_board_setup(ARMCPU *cpu,
const struct arm_boot_info *info)
{
@@ -158,12 +172,13 @@ static inline void zynq_init_spi_flashes(uint32_t base_addr, qemu_irq irq,
static void zynq_init(MachineState *machine)
{
+ ZynqMachineState *zynq_machine = ZYNQ_MACHINE(machine);
ram_addr_t ram_size = machine->ram_size;
ARMCPU *cpu;
MemoryRegion *address_space_mem = get_system_memory();
MemoryRegion *ext_ram = g_new(MemoryRegion, 1);
MemoryRegion *ocm_ram = g_new(MemoryRegion, 1);
- DeviceState *dev;
+ DeviceState *dev, *slcr;
SysBusDevice *busdev;
qemu_irq pic[64];
int n;
@@ -208,9 +223,18 @@ static void zynq_init(MachineState *machine)
1, 0x0066, 0x0022, 0x0000, 0x0000, 0x0555, 0x2aa,
0);
- dev = qdev_create(NULL, "xilinx,zynq_slcr");
- qdev_init_nofail(dev);
- sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, 0xF8000000);
+ /* Create slcr, keep a pointer to connect clocks */
+ slcr = qdev_create(NULL, "xilinx,zynq_slcr");
+ qdev_init_nofail(slcr);
+ sysbus_mmio_map(SYS_BUS_DEVICE(slcr), 0, 0xF8000000);
+
+ /* Create the main clock source, and feed slcr with it */
+ zynq_machine->ps_clk = CLOCK(object_new(TYPE_CLOCK));
+ object_property_add_child(OBJECT(zynq_machine), "ps_clk",
+ OBJECT(zynq_machine->ps_clk), &error_abort);
+ object_unref(OBJECT(zynq_machine->ps_clk));
+ clock_set_hz(zynq_machine->ps_clk, PS_CLK_FREQUENCY);
+ qdev_connect_clock_in(slcr, "ps_clk", zynq_machine->ps_clk);
dev = qdev_create(NULL, TYPE_A9MPCORE_PRIV);
qdev_prop_set_uint32(dev, "num-cpu", 1);
@@ -231,8 +255,12 @@ static void zynq_init(MachineState *machine)
sysbus_create_simple("xlnx,ps7-usb", 0xE0002000, pic[53-IRQ_OFFSET]);
sysbus_create_simple("xlnx,ps7-usb", 0xE0003000, pic[76-IRQ_OFFSET]);
- cadence_uart_create(0xE0000000, pic[59 - IRQ_OFFSET], serial_hd(0));
- cadence_uart_create(0xE0001000, pic[82 - IRQ_OFFSET], serial_hd(1));
+ dev = cadence_uart_create(0xE0000000, pic[59 - IRQ_OFFSET], serial_hd(0));
+ qdev_connect_clock_in(dev, "refclk",
+ qdev_get_clock_out(slcr, "uart0_ref_clk"));
+ dev = cadence_uart_create(0xE0001000, pic[82 - IRQ_OFFSET], serial_hd(1));
+ qdev_connect_clock_in(dev, "refclk",
+ qdev_get_clock_out(slcr, "uart1_ref_clk"));
sysbus_create_varargs("cadence_ttc", 0xF8001000,
pic[42-IRQ_OFFSET], pic[43-IRQ_OFFSET], pic[44-IRQ_OFFSET], NULL);
@@ -310,8 +338,9 @@ static void zynq_init(MachineState *machine)
arm_load_kernel(ARM_CPU(first_cpu), machine, &zynq_binfo);
}
-static void zynq_machine_init(MachineClass *mc)
+static void zynq_machine_class_init(ObjectClass *oc, void *data)
{
+ MachineClass *mc = MACHINE_CLASS(oc);
mc->desc = "Xilinx Zynq Platform Baseboard for Cortex-A9";
mc->init = zynq_init;
mc->max_cpus = 1;
@@ -320,4 +349,16 @@ static void zynq_machine_init(MachineClass *mc)
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a9");
}
-DEFINE_MACHINE("xilinx-zynq-a9", zynq_machine_init)
+static const TypeInfo zynq_machine_type = {
+ .name = TYPE_ZYNQ_MACHINE,
+ .parent = TYPE_MACHINE,
+ .class_init = zynq_machine_class_init,
+ .instance_size = sizeof(ZynqMachineState),
+};
+
+static void zynq_machine_register_types(void)
+{
+ type_register_static(&zynq_machine_type);
+}
+
+type_init(zynq_machine_register_types)
--
2.25.1
On Tue, Feb 25, 2020 at 5:40 AM Damien Hedde <damien.hedde@greensocs.com> wrote:
>
> Add the connection between the slcr's output clocks and the uarts inputs.
>
> Also add the main board clock 'ps_clk', which is hard-coded to 33.33MHz
> (the default frequency). This clock is used to feed the slcr's input
> clock.
>
> Signed-off-by: Damien Hedde <damien.hedde@greensocs.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Alistair
>
> ---
> v7
> + update ClockIn/ClockOut types
> + simplify the ps_clk frequency init
> ---
> hw/arm/xilinx_zynq.c | 57 +++++++++++++++++++++++++++++++++++++-------
> 1 file changed, 49 insertions(+), 8 deletions(-)
>
> diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
> index 3a0fa5b23f..261a1690a8 100644
> --- a/hw/arm/xilinx_zynq.c
> +++ b/hw/arm/xilinx_zynq.c
> @@ -34,6 +34,15 @@
> #include "hw/char/cadence_uart.h"
> #include "hw/net/cadence_gem.h"
> #include "hw/cpu/a9mpcore.h"
> +#include "hw/qdev-clock.h"
> +#include "sysemu/reset.h"
> +
> +#define TYPE_ZYNQ_MACHINE MACHINE_TYPE_NAME("xilinx-zynq-a9")
> +#define ZYNQ_MACHINE(obj) \
> + OBJECT_CHECK(ZynqMachineState, (obj), TYPE_ZYNQ_MACHINE)
> +
> +/* board base frequency: 33.333333 MHz */
> +#define PS_CLK_FREQUENCY (100 * 1000 * 1000 / 3)
>
> #define NUM_SPI_FLASHES 4
> #define NUM_QSPI_FLASHES 2
> @@ -74,6 +83,11 @@ static const int dma_irqs[8] = {
> 0xe3401000 + ARMV7_IMM16(extract32((val), 16, 16)), /* movt r1 ... */ \
> 0xe5801000 + (addr)
>
> +typedef struct ZynqMachineState {
> + MachineState parent;
> + Clock *ps_clk;
> +} ZynqMachineState;
> +
> static void zynq_write_board_setup(ARMCPU *cpu,
> const struct arm_boot_info *info)
> {
> @@ -158,12 +172,13 @@ static inline void zynq_init_spi_flashes(uint32_t base_addr, qemu_irq irq,
>
> static void zynq_init(MachineState *machine)
> {
> + ZynqMachineState *zynq_machine = ZYNQ_MACHINE(machine);
> ram_addr_t ram_size = machine->ram_size;
> ARMCPU *cpu;
> MemoryRegion *address_space_mem = get_system_memory();
> MemoryRegion *ext_ram = g_new(MemoryRegion, 1);
> MemoryRegion *ocm_ram = g_new(MemoryRegion, 1);
> - DeviceState *dev;
> + DeviceState *dev, *slcr;
> SysBusDevice *busdev;
> qemu_irq pic[64];
> int n;
> @@ -208,9 +223,18 @@ static void zynq_init(MachineState *machine)
> 1, 0x0066, 0x0022, 0x0000, 0x0000, 0x0555, 0x2aa,
> 0);
>
> - dev = qdev_create(NULL, "xilinx,zynq_slcr");
> - qdev_init_nofail(dev);
> - sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, 0xF8000000);
> + /* Create slcr, keep a pointer to connect clocks */
> + slcr = qdev_create(NULL, "xilinx,zynq_slcr");
> + qdev_init_nofail(slcr);
> + sysbus_mmio_map(SYS_BUS_DEVICE(slcr), 0, 0xF8000000);
> +
> + /* Create the main clock source, and feed slcr with it */
> + zynq_machine->ps_clk = CLOCK(object_new(TYPE_CLOCK));
> + object_property_add_child(OBJECT(zynq_machine), "ps_clk",
> + OBJECT(zynq_machine->ps_clk), &error_abort);
> + object_unref(OBJECT(zynq_machine->ps_clk));
> + clock_set_hz(zynq_machine->ps_clk, PS_CLK_FREQUENCY);
> + qdev_connect_clock_in(slcr, "ps_clk", zynq_machine->ps_clk);
>
> dev = qdev_create(NULL, TYPE_A9MPCORE_PRIV);
> qdev_prop_set_uint32(dev, "num-cpu", 1);
> @@ -231,8 +255,12 @@ static void zynq_init(MachineState *machine)
> sysbus_create_simple("xlnx,ps7-usb", 0xE0002000, pic[53-IRQ_OFFSET]);
> sysbus_create_simple("xlnx,ps7-usb", 0xE0003000, pic[76-IRQ_OFFSET]);
>
> - cadence_uart_create(0xE0000000, pic[59 - IRQ_OFFSET], serial_hd(0));
> - cadence_uart_create(0xE0001000, pic[82 - IRQ_OFFSET], serial_hd(1));
> + dev = cadence_uart_create(0xE0000000, pic[59 - IRQ_OFFSET], serial_hd(0));
> + qdev_connect_clock_in(dev, "refclk",
> + qdev_get_clock_out(slcr, "uart0_ref_clk"));
> + dev = cadence_uart_create(0xE0001000, pic[82 - IRQ_OFFSET], serial_hd(1));
> + qdev_connect_clock_in(dev, "refclk",
> + qdev_get_clock_out(slcr, "uart1_ref_clk"));
>
> sysbus_create_varargs("cadence_ttc", 0xF8001000,
> pic[42-IRQ_OFFSET], pic[43-IRQ_OFFSET], pic[44-IRQ_OFFSET], NULL);
> @@ -310,8 +338,9 @@ static void zynq_init(MachineState *machine)
> arm_load_kernel(ARM_CPU(first_cpu), machine, &zynq_binfo);
> }
>
> -static void zynq_machine_init(MachineClass *mc)
> +static void zynq_machine_class_init(ObjectClass *oc, void *data)
> {
> + MachineClass *mc = MACHINE_CLASS(oc);
> mc->desc = "Xilinx Zynq Platform Baseboard for Cortex-A9";
> mc->init = zynq_init;
> mc->max_cpus = 1;
> @@ -320,4 +349,16 @@ static void zynq_machine_init(MachineClass *mc)
> mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a9");
> }
>
> -DEFINE_MACHINE("xilinx-zynq-a9", zynq_machine_init)
> +static const TypeInfo zynq_machine_type = {
> + .name = TYPE_ZYNQ_MACHINE,
> + .parent = TYPE_MACHINE,
> + .class_init = zynq_machine_class_init,
> + .instance_size = sizeof(ZynqMachineState),
> +};
> +
> +static void zynq_machine_register_types(void)
> +{
> + type_register_static(&zynq_machine_type);
> +}
> +
> +type_init(zynq_machine_register_types)
> --
> 2.25.1
>
>
© 2016 - 2025 Red Hat, Inc.