2012-02-16 09:56:05 +00:00
|
|
|
/*
|
|
|
|
* Samsung exynos4210 SoC emulation
|
|
|
|
*
|
|
|
|
* Copyright (c) 2011 Samsung Electronics Co., Ltd. All rights reserved.
|
|
|
|
* Maksim Kozlov <m.kozlov@samsung.com>
|
|
|
|
* Evgeny Voevodin <e.voevodin@samsung.com>
|
|
|
|
* Igor Mitsyanko <i.mitsyanko@samsung.com>
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
|
|
* under the terms of the GNU General Public License as published by the
|
|
|
|
* Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
|
|
* for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License along
|
|
|
|
* with this program; if not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2015-12-07 16:23:45 +00:00
|
|
|
#include "qemu/osdep.h"
|
include/qemu/osdep.h: Don't include qapi/error.h
Commit 57cb38b included qapi/error.h into qemu/osdep.h to get the
Error typedef. Since then, we've moved to include qemu/osdep.h
everywhere. Its file comment explains: "To avoid getting into
possible circular include dependencies, this file should not include
any other QEMU headers, with the exceptions of config-host.h,
compiler.h, os-posix.h and os-win32.h, all of which are doing a
similar job to this file and are under similar constraints."
qapi/error.h doesn't do a similar job, and it doesn't adhere to
similar constraints: it includes qapi-types.h. That's in excess of
100KiB of crap most .c files don't actually need.
Add the typedef to qemu/typedefs.h, and include that instead of
qapi/error.h. Include qapi/error.h in .c files that need it and don't
get it now. Include qapi-types.h in qom/object.h for uint16List.
Update scripts/clean-includes accordingly. Update it further to match
reality: replace config.h by config-target.h, add sysemu/os-posix.h,
sysemu/os-win32.h. Update the list of includes in the qemu/osdep.h
comment quoted above similarly.
This reduces the number of objects depending on qapi/error.h from "all
of them" to less than a third. Unfortunately, the number depending on
qapi-types.h shrinks only a little. More work is needed for that one.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
[Fix compilation without the spice devel packages. - Paolo]
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2016-03-14 08:01:28 +00:00
|
|
|
#include "qapi/error.h"
|
2016-01-19 20:51:44 +00:00
|
|
|
#include "cpu.h"
|
2017-06-13 13:56:58 +00:00
|
|
|
#include "hw/cpu/a9mpcore.h"
|
2019-08-12 05:23:42 +00:00
|
|
|
#include "hw/irq.h"
|
2019-08-12 05:23:52 +00:00
|
|
|
#include "sysemu/blockdev.h"
|
2012-12-17 17:20:04 +00:00
|
|
|
#include "sysemu/sysemu.h"
|
2013-02-04 14:40:22 +00:00
|
|
|
#include "hw/sysbus.h"
|
2019-05-23 13:47:43 +00:00
|
|
|
#include "hw/arm/boot.h"
|
2013-02-04 14:40:22 +00:00
|
|
|
#include "hw/loader.h"
|
2019-08-12 05:23:51 +00:00
|
|
|
#include "hw/qdev-properties.h"
|
2013-02-05 16:06:20 +00:00
|
|
|
#include "hw/arm/exynos4210.h"
|
2017-09-04 14:21:53 +00:00
|
|
|
#include "hw/sd/sdhci.h"
|
2013-02-04 14:40:22 +00:00
|
|
|
#include "hw/usb/hcd-ehci.h"
|
2012-02-16 09:56:05 +00:00
|
|
|
|
|
|
|
#define EXYNOS4210_CHIPID_ADDR 0x10000000
|
|
|
|
|
2012-02-16 09:56:05 +00:00
|
|
|
/* PWM */
|
|
|
|
#define EXYNOS4210_PWM_BASE_ADDR 0x139D0000
|
|
|
|
|
2012-07-04 10:43:32 +00:00
|
|
|
/* RTC */
|
|
|
|
#define EXYNOS4210_RTC_BASE_ADDR 0x10070000
|
|
|
|
|
2012-02-16 09:56:05 +00:00
|
|
|
/* MCT */
|
|
|
|
#define EXYNOS4210_MCT_BASE_ADDR 0x10050000
|
|
|
|
|
2012-07-18 08:18:34 +00:00
|
|
|
/* I2C */
|
|
|
|
#define EXYNOS4210_I2C_SHIFT 0x00010000
|
|
|
|
#define EXYNOS4210_I2C_BASE_ADDR 0x13860000
|
|
|
|
/* Interrupt Group of External Interrupt Combiner for I2C */
|
|
|
|
#define EXYNOS4210_I2C_INTG 27
|
|
|
|
#define EXYNOS4210_HDMI_INTG 16
|
|
|
|
|
2012-02-16 09:56:05 +00:00
|
|
|
/* UART's definitions */
|
|
|
|
#define EXYNOS4210_UART0_BASE_ADDR 0x13800000
|
|
|
|
#define EXYNOS4210_UART1_BASE_ADDR 0x13810000
|
|
|
|
#define EXYNOS4210_UART2_BASE_ADDR 0x13820000
|
|
|
|
#define EXYNOS4210_UART3_BASE_ADDR 0x13830000
|
|
|
|
#define EXYNOS4210_UART0_FIFO_SIZE 256
|
|
|
|
#define EXYNOS4210_UART1_FIFO_SIZE 64
|
|
|
|
#define EXYNOS4210_UART2_FIFO_SIZE 16
|
|
|
|
#define EXYNOS4210_UART3_FIFO_SIZE 16
|
|
|
|
/* Interrupt Group of External Interrupt Combiner for UART */
|
|
|
|
#define EXYNOS4210_UART_INT_GRP 26
|
|
|
|
|
2012-02-16 09:56:05 +00:00
|
|
|
/* External GIC */
|
|
|
|
#define EXYNOS4210_EXT_GIC_CPU_BASE_ADDR 0x10480000
|
|
|
|
#define EXYNOS4210_EXT_GIC_DIST_BASE_ADDR 0x10490000
|
|
|
|
|
|
|
|
/* Combiner */
|
|
|
|
#define EXYNOS4210_EXT_COMBINER_BASE_ADDR 0x10440000
|
|
|
|
#define EXYNOS4210_INT_COMBINER_BASE_ADDR 0x10448000
|
|
|
|
|
hw/arm/exynos: Add generic SDHCI devices
Exynos4210 has four SD/MMC controllers supporting:
- SD Standard Host Specification Version 2.0,
- MMC Specification Version 4.3,
- SDIO Card Specification Version 2.0,
- DMA and ADMA.
Add emulation of SDHCI devices which allows accessing storage through SD
cards. Differences from real hardware:
- Devices are shipped with eMMC memory, not SD card.
- The Exynos4210 SDHCI has few more registers, e.g. for
controlling the clocks, additional status (0x80, 0x84, 0x8c). These
are not implemented.
Testing on smdkc210 machine with "-drive file=FILE,if=sd,bus=0,index=2".
Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
Message-id: 20170422190709.8676-1-krzk@kernel.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2017-04-22 19:07:09 +00:00
|
|
|
/* SD/MMC host controllers */
|
|
|
|
#define EXYNOS4210_SDHCI_CAPABILITIES 0x05E80080
|
|
|
|
#define EXYNOS4210_SDHCI_BASE_ADDR 0x12510000
|
|
|
|
#define EXYNOS4210_SDHCI_ADDR(n) (EXYNOS4210_SDHCI_BASE_ADDR + \
|
|
|
|
0x00010000 * (n))
|
|
|
|
#define EXYNOS4210_SDHCI_NUMBER 4
|
|
|
|
|
2012-02-16 09:56:05 +00:00
|
|
|
/* PMU SFR base address */
|
|
|
|
#define EXYNOS4210_PMU_BASE_ADDR 0x10020000
|
|
|
|
|
2017-02-28 12:08:20 +00:00
|
|
|
/* Clock controller SFR base address */
|
|
|
|
#define EXYNOS4210_CLK_BASE_ADDR 0x10030000
|
|
|
|
|
2017-07-11 10:21:26 +00:00
|
|
|
/* PRNG/HASH SFR base address */
|
|
|
|
#define EXYNOS4210_RNG_BASE_ADDR 0x10830400
|
|
|
|
|
2012-02-16 09:56:06 +00:00
|
|
|
/* Display controllers (FIMD) */
|
|
|
|
#define EXYNOS4210_FIMD0_BASE_ADDR 0x11C00000
|
|
|
|
|
2012-12-16 03:49:46 +00:00
|
|
|
/* EHCI */
|
|
|
|
#define EXYNOS4210_EHCI_BASE_ADDR 0x12580000
|
|
|
|
|
hw/arm/exynos4210: Add DMA support for the Exynos4210
QEMU already supports pl330. Instantiate it for Exynos4210.
Relevant part of Linux arch/arm/boot/dts/exynos4.dtsi:
/ {
soc: soc {
amba {
pdma0: pdma@12680000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x12680000 0x1000>;
interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_PDMA0>;
clock-names = "apb_pclk";
#dma-cells = <1>;
#dma-channels = <8>;
#dma-requests = <32>;
};
pdma1: pdma@12690000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x12690000 0x1000>;
interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_PDMA1>;
clock-names = "apb_pclk";
#dma-cells = <1>;
#dma-channels = <8>;
#dma-requests = <32>;
};
mdma1: mdma@12850000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x12850000 0x1000>;
interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_MDMA>;
clock-names = "apb_pclk";
#dma-cells = <1>;
#dma-channels = <8>;
#dma-requests = <1>;
};
};
};
};
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-id: 20190520214342.13709-4-philmd@redhat.com
[PMD: Do not set default qdev properties, create the controllers in the SoC
rather than the board (Peter Maydell), add dtsi in commit message]
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2019-05-23 13:47:44 +00:00
|
|
|
/* DMA */
|
|
|
|
#define EXYNOS4210_PL330_BASE0_ADDR 0x12680000
|
|
|
|
#define EXYNOS4210_PL330_BASE1_ADDR 0x12690000
|
|
|
|
#define EXYNOS4210_PL330_BASE2_ADDR 0x12850000
|
|
|
|
|
2022-04-04 15:46:47 +00:00
|
|
|
enum ExtGicId {
|
|
|
|
EXT_GIC_ID_MDMA_LCD0 = 66,
|
|
|
|
EXT_GIC_ID_PDMA0,
|
|
|
|
EXT_GIC_ID_PDMA1,
|
|
|
|
EXT_GIC_ID_TIMER0,
|
|
|
|
EXT_GIC_ID_TIMER1,
|
|
|
|
EXT_GIC_ID_TIMER2,
|
|
|
|
EXT_GIC_ID_TIMER3,
|
|
|
|
EXT_GIC_ID_TIMER4,
|
|
|
|
EXT_GIC_ID_MCT_L0,
|
|
|
|
EXT_GIC_ID_WDT,
|
|
|
|
EXT_GIC_ID_RTC_ALARM,
|
|
|
|
EXT_GIC_ID_RTC_TIC,
|
|
|
|
EXT_GIC_ID_GPIO_XB,
|
|
|
|
EXT_GIC_ID_GPIO_XA,
|
|
|
|
EXT_GIC_ID_MCT_L1,
|
|
|
|
EXT_GIC_ID_IEM_APC,
|
|
|
|
EXT_GIC_ID_IEM_IEC,
|
|
|
|
EXT_GIC_ID_NFC,
|
|
|
|
EXT_GIC_ID_UART0,
|
|
|
|
EXT_GIC_ID_UART1,
|
|
|
|
EXT_GIC_ID_UART2,
|
|
|
|
EXT_GIC_ID_UART3,
|
|
|
|
EXT_GIC_ID_UART4,
|
|
|
|
EXT_GIC_ID_MCT_G0,
|
|
|
|
EXT_GIC_ID_I2C0,
|
|
|
|
EXT_GIC_ID_I2C1,
|
|
|
|
EXT_GIC_ID_I2C2,
|
|
|
|
EXT_GIC_ID_I2C3,
|
|
|
|
EXT_GIC_ID_I2C4,
|
|
|
|
EXT_GIC_ID_I2C5,
|
|
|
|
EXT_GIC_ID_I2C6,
|
|
|
|
EXT_GIC_ID_I2C7,
|
|
|
|
EXT_GIC_ID_SPI0,
|
|
|
|
EXT_GIC_ID_SPI1,
|
|
|
|
EXT_GIC_ID_SPI2,
|
|
|
|
EXT_GIC_ID_MCT_G1,
|
|
|
|
EXT_GIC_ID_USB_HOST,
|
|
|
|
EXT_GIC_ID_USB_DEVICE,
|
|
|
|
EXT_GIC_ID_MODEMIF,
|
|
|
|
EXT_GIC_ID_HSMMC0,
|
|
|
|
EXT_GIC_ID_HSMMC1,
|
|
|
|
EXT_GIC_ID_HSMMC2,
|
|
|
|
EXT_GIC_ID_HSMMC3,
|
|
|
|
EXT_GIC_ID_SDMMC,
|
|
|
|
EXT_GIC_ID_MIPI_CSI_4LANE,
|
|
|
|
EXT_GIC_ID_MIPI_DSI_4LANE,
|
|
|
|
EXT_GIC_ID_MIPI_CSI_2LANE,
|
|
|
|
EXT_GIC_ID_MIPI_DSI_2LANE,
|
|
|
|
EXT_GIC_ID_ONENAND_AUDI,
|
|
|
|
EXT_GIC_ID_ROTATOR,
|
|
|
|
EXT_GIC_ID_FIMC0,
|
|
|
|
EXT_GIC_ID_FIMC1,
|
|
|
|
EXT_GIC_ID_FIMC2,
|
|
|
|
EXT_GIC_ID_FIMC3,
|
|
|
|
EXT_GIC_ID_JPEG,
|
|
|
|
EXT_GIC_ID_2D,
|
|
|
|
EXT_GIC_ID_PCIe,
|
|
|
|
EXT_GIC_ID_MIXER,
|
|
|
|
EXT_GIC_ID_HDMI,
|
|
|
|
EXT_GIC_ID_HDMI_I2C,
|
|
|
|
EXT_GIC_ID_MFC,
|
|
|
|
EXT_GIC_ID_TVENC,
|
|
|
|
};
|
|
|
|
|
|
|
|
enum ExtInt {
|
|
|
|
EXT_GIC_ID_EXTINT0 = 48,
|
|
|
|
EXT_GIC_ID_EXTINT1,
|
|
|
|
EXT_GIC_ID_EXTINT2,
|
|
|
|
EXT_GIC_ID_EXTINT3,
|
|
|
|
EXT_GIC_ID_EXTINT4,
|
|
|
|
EXT_GIC_ID_EXTINT5,
|
|
|
|
EXT_GIC_ID_EXTINT6,
|
|
|
|
EXT_GIC_ID_EXTINT7,
|
|
|
|
EXT_GIC_ID_EXTINT8,
|
|
|
|
EXT_GIC_ID_EXTINT9,
|
|
|
|
EXT_GIC_ID_EXTINT10,
|
|
|
|
EXT_GIC_ID_EXTINT11,
|
|
|
|
EXT_GIC_ID_EXTINT12,
|
|
|
|
EXT_GIC_ID_EXTINT13,
|
|
|
|
EXT_GIC_ID_EXTINT14,
|
|
|
|
EXT_GIC_ID_EXTINT15
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* External GIC sources which are not from External Interrupt Combiner or
|
|
|
|
* External Interrupts are starting from EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ,
|
|
|
|
* which is INTG16 in Internal Interrupt Combiner.
|
|
|
|
*/
|
|
|
|
|
|
|
|
static const uint32_t
|
|
|
|
combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
|
|
|
|
/* int combiner groups 16-19 */
|
|
|
|
{ }, { }, { }, { },
|
|
|
|
/* int combiner group 20 */
|
|
|
|
{ 0, EXT_GIC_ID_MDMA_LCD0 },
|
|
|
|
/* int combiner group 21 */
|
|
|
|
{ EXT_GIC_ID_PDMA0, EXT_GIC_ID_PDMA1 },
|
|
|
|
/* int combiner group 22 */
|
|
|
|
{ EXT_GIC_ID_TIMER0, EXT_GIC_ID_TIMER1, EXT_GIC_ID_TIMER2,
|
|
|
|
EXT_GIC_ID_TIMER3, EXT_GIC_ID_TIMER4 },
|
|
|
|
/* int combiner group 23 */
|
|
|
|
{ EXT_GIC_ID_RTC_ALARM, EXT_GIC_ID_RTC_TIC },
|
|
|
|
/* int combiner group 24 */
|
|
|
|
{ EXT_GIC_ID_GPIO_XB, EXT_GIC_ID_GPIO_XA },
|
|
|
|
/* int combiner group 25 */
|
|
|
|
{ EXT_GIC_ID_IEM_APC, EXT_GIC_ID_IEM_IEC },
|
|
|
|
/* int combiner group 26 */
|
|
|
|
{ EXT_GIC_ID_UART0, EXT_GIC_ID_UART1, EXT_GIC_ID_UART2, EXT_GIC_ID_UART3,
|
|
|
|
EXT_GIC_ID_UART4 },
|
|
|
|
/* int combiner group 27 */
|
|
|
|
{ EXT_GIC_ID_I2C0, EXT_GIC_ID_I2C1, EXT_GIC_ID_I2C2, EXT_GIC_ID_I2C3,
|
|
|
|
EXT_GIC_ID_I2C4, EXT_GIC_ID_I2C5, EXT_GIC_ID_I2C6,
|
|
|
|
EXT_GIC_ID_I2C7 },
|
|
|
|
/* int combiner group 28 */
|
|
|
|
{ EXT_GIC_ID_SPI0, EXT_GIC_ID_SPI1, EXT_GIC_ID_SPI2 , EXT_GIC_ID_USB_HOST},
|
|
|
|
/* int combiner group 29 */
|
|
|
|
{ EXT_GIC_ID_HSMMC0, EXT_GIC_ID_HSMMC1, EXT_GIC_ID_HSMMC2,
|
|
|
|
EXT_GIC_ID_HSMMC3, EXT_GIC_ID_SDMMC },
|
|
|
|
/* int combiner group 30 */
|
|
|
|
{ EXT_GIC_ID_MIPI_CSI_4LANE, EXT_GIC_ID_MIPI_CSI_2LANE },
|
|
|
|
/* int combiner group 31 */
|
|
|
|
{ EXT_GIC_ID_MIPI_DSI_4LANE, EXT_GIC_ID_MIPI_DSI_2LANE },
|
|
|
|
/* int combiner group 32 */
|
|
|
|
{ EXT_GIC_ID_FIMC0, EXT_GIC_ID_FIMC1 },
|
|
|
|
/* int combiner group 33 */
|
|
|
|
{ EXT_GIC_ID_FIMC2, EXT_GIC_ID_FIMC3 },
|
|
|
|
/* int combiner group 34 */
|
|
|
|
{ EXT_GIC_ID_ONENAND_AUDI, EXT_GIC_ID_NFC },
|
|
|
|
/* int combiner group 35 */
|
hw/arm/exynos4210: Don't connect multiple lines to external GIC inputs
The combiner_grp_to_gic_id[] array includes the EXT_GIC_ID_MCT_G0
and EXT_GIC_ID_MCT_G1 multiple times. This means that we will
connect multiple IRQs up to the same external GIC input, which
is not permitted. We do the same thing in the code in
exynos4210_init_board_irqs() because the conditionals selecting
an irq_id in the first loop match multiple interrupt IDs.
Overall we do this for interrupt IDs
(1, 4), (12, 4), (35, 4), (51, 4), (53, 4) for EXT_GIC_ID_MCT_G0
and
(1, 5), (12, 5), (35, 5), (51, 5), (53, 5) for EXT_GIC_ID_MCT_G1
These correspond to the cases for the multi-core timer that we are
wiring up to multiple inputs on the combiner in
exynos4210_combiner_get_gpioin(). That code already deals with all
these interrupt IDs being the same input source, so we don't need to
connect the external GIC interrupt for any of them except the first
(1, 4) and (1, 5). Remove the array entries and conditionals which
were incorrectly causing us to wire up extra lines.
This bug didn't cause any visible effects, because we only connect
up a device to the "primary" ID values (1, 4) and (1, 5), so the
extra lines would never be set to a level.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20220404154658.565020-16-peter.maydell@linaro.org
2022-04-04 15:46:55 +00:00
|
|
|
{ 0, 0, 0, EXT_GIC_ID_MCT_L1 },
|
2022-04-04 15:46:47 +00:00
|
|
|
/* int combiner group 36 */
|
|
|
|
{ EXT_GIC_ID_MIXER },
|
|
|
|
/* int combiner group 37 */
|
|
|
|
{ EXT_GIC_ID_EXTINT4, EXT_GIC_ID_EXTINT5, EXT_GIC_ID_EXTINT6,
|
|
|
|
EXT_GIC_ID_EXTINT7 },
|
|
|
|
/* groups 38-50 */
|
|
|
|
{ }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { },
|
|
|
|
/* int combiner group 51 */
|
hw/arm/exynos4210: Don't connect multiple lines to external GIC inputs
The combiner_grp_to_gic_id[] array includes the EXT_GIC_ID_MCT_G0
and EXT_GIC_ID_MCT_G1 multiple times. This means that we will
connect multiple IRQs up to the same external GIC input, which
is not permitted. We do the same thing in the code in
exynos4210_init_board_irqs() because the conditionals selecting
an irq_id in the first loop match multiple interrupt IDs.
Overall we do this for interrupt IDs
(1, 4), (12, 4), (35, 4), (51, 4), (53, 4) for EXT_GIC_ID_MCT_G0
and
(1, 5), (12, 5), (35, 5), (51, 5), (53, 5) for EXT_GIC_ID_MCT_G1
These correspond to the cases for the multi-core timer that we are
wiring up to multiple inputs on the combiner in
exynos4210_combiner_get_gpioin(). That code already deals with all
these interrupt IDs being the same input source, so we don't need to
connect the external GIC interrupt for any of them except the first
(1, 4) and (1, 5). Remove the array entries and conditionals which
were incorrectly causing us to wire up extra lines.
This bug didn't cause any visible effects, because we only connect
up a device to the "primary" ID values (1, 4) and (1, 5), so the
extra lines would never be set to a level.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20220404154658.565020-16-peter.maydell@linaro.org
2022-04-04 15:46:55 +00:00
|
|
|
{ EXT_GIC_ID_MCT_L0 },
|
2022-04-04 15:46:47 +00:00
|
|
|
/* group 52 */
|
|
|
|
{ },
|
|
|
|
/* int combiner group 53 */
|
hw/arm/exynos4210: Don't connect multiple lines to external GIC inputs
The combiner_grp_to_gic_id[] array includes the EXT_GIC_ID_MCT_G0
and EXT_GIC_ID_MCT_G1 multiple times. This means that we will
connect multiple IRQs up to the same external GIC input, which
is not permitted. We do the same thing in the code in
exynos4210_init_board_irqs() because the conditionals selecting
an irq_id in the first loop match multiple interrupt IDs.
Overall we do this for interrupt IDs
(1, 4), (12, 4), (35, 4), (51, 4), (53, 4) for EXT_GIC_ID_MCT_G0
and
(1, 5), (12, 5), (35, 5), (51, 5), (53, 5) for EXT_GIC_ID_MCT_G1
These correspond to the cases for the multi-core timer that we are
wiring up to multiple inputs on the combiner in
exynos4210_combiner_get_gpioin(). That code already deals with all
these interrupt IDs being the same input source, so we don't need to
connect the external GIC interrupt for any of them except the first
(1, 4) and (1, 5). Remove the array entries and conditionals which
were incorrectly causing us to wire up extra lines.
This bug didn't cause any visible effects, because we only connect
up a device to the "primary" ID values (1, 4) and (1, 5), so the
extra lines would never be set to a level.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20220404154658.565020-16-peter.maydell@linaro.org
2022-04-04 15:46:55 +00:00
|
|
|
{ EXT_GIC_ID_WDT },
|
2022-04-04 15:46:47 +00:00
|
|
|
/* groups 54-63 */
|
|
|
|
{ }, { }, { }, { }, { }, { }, { }, { }, { }, { }
|
|
|
|
};
|
|
|
|
|
2022-04-04 15:46:50 +00:00
|
|
|
#define EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit) ((grp) * 8 + (bit))
|
|
|
|
#define EXYNOS4210_COMBINER_GET_GRP_NUM(irq) ((irq) / 8)
|
|
|
|
#define EXYNOS4210_COMBINER_GET_BIT_NUM(irq) \
|
|
|
|
((irq) - 8 * EXYNOS4210_COMBINER_GET_GRP_NUM(irq))
|
|
|
|
|
hw/arm/exynos4210: Fold combiner splits into exynos4210_init_board_irqs()
At this point, the function exynos4210_init_board_irqs() splits input
IRQ lines to connect them to the input combiner, output combiner and
external GIC. The function exynos4210_combiner_get_gpioin() splits
some of the combiner input lines further to connect them to multiple
different inputs on the combiner.
Because (unlike qemu_irq_split()) the TYPE_SPLIT_IRQ device has a
configurable number of outputs, we can do all this in one place, by
making exynos4210_init_board_irqs() add extra outputs to the splitter
device when it must be connected to more than one input on each
combiner.
We do this with a new data structure, the combinermap, which is an
array each of whose elements is a list of the interrupt IDs on the
combiner which must be tied together. As we loop through each
interrupt ID, if we find that it is the first one in one of these
lists, we configure the splitter device with eonugh extra outputs and
wire them up to the other interrupt IDs in the list.
Conveniently, for all the cases where this is necessary, the
lowest-numbered interrupt ID in each group is in the range of the
external combiner, so we only need to code for this in the first of
the two loops in exynos4210_init_board_irqs().
The old code in exynos4210_combiner_get_gpioin() which is being
deleted here had several problems which don't exist in the new code
in its handling of the multi-core timer interrupts:
(1) the case labels specified bits 4 ... 8, but bit '8' doesn't
exist; these should have been 4 ... 7
(2) it used the input irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]
multiple times as the input of several different splitters,
which isn't allowed
(3) in an apparent cut-and-paste error, the cases for all the
multi-core timer inputs used "bit + 4" even though the
bit range for the case was (intended to be) 4 ... 7, which
meant it was looking at non-existent bits 8 ... 11.
None of these exist in the new code.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20220404154658.565020-17-peter.maydell@linaro.org
2022-04-04 15:46:56 +00:00
|
|
|
/*
|
|
|
|
* Some interrupt lines go to multiple combiner inputs.
|
|
|
|
* This data structure defines those: each array element is
|
|
|
|
* a list of combiner inputs which are connected together;
|
|
|
|
* the one with the smallest interrupt ID value must be first.
|
|
|
|
* As with combiner_grp_to_gic_id[], we rely on (0, 0) not being
|
|
|
|
* wired to anything so we can use 0 as a terminator.
|
|
|
|
*/
|
|
|
|
#define IRQNO(G, B) EXYNOS4210_COMBINER_GET_IRQ_NUM(G, B)
|
|
|
|
#define IRQNONE 0
|
|
|
|
|
|
|
|
#define COMBINERMAP_SIZE 16
|
|
|
|
|
|
|
|
static const int combinermap[COMBINERMAP_SIZE][6] = {
|
|
|
|
/* MDNIE_LCD1 */
|
|
|
|
{ IRQNO(0, 4), IRQNO(1, 0), IRQNONE },
|
|
|
|
{ IRQNO(0, 5), IRQNO(1, 1), IRQNONE },
|
|
|
|
{ IRQNO(0, 6), IRQNO(1, 2), IRQNONE },
|
|
|
|
{ IRQNO(0, 7), IRQNO(1, 3), IRQNONE },
|
|
|
|
/* TMU */
|
|
|
|
{ IRQNO(2, 4), IRQNO(3, 4), IRQNONE },
|
|
|
|
{ IRQNO(2, 5), IRQNO(3, 5), IRQNONE },
|
|
|
|
{ IRQNO(2, 6), IRQNO(3, 6), IRQNONE },
|
|
|
|
{ IRQNO(2, 7), IRQNO(3, 7), IRQNONE },
|
|
|
|
/* LCD1 */
|
|
|
|
{ IRQNO(11, 4), IRQNO(12, 0), IRQNONE },
|
|
|
|
{ IRQNO(11, 5), IRQNO(12, 1), IRQNONE },
|
|
|
|
{ IRQNO(11, 6), IRQNO(12, 2), IRQNONE },
|
|
|
|
{ IRQNO(11, 7), IRQNO(12, 3), IRQNONE },
|
|
|
|
/* Multi-core timer */
|
|
|
|
{ IRQNO(1, 4), IRQNO(12, 4), IRQNO(35, 4), IRQNO(51, 4), IRQNO(53, 4), IRQNONE },
|
|
|
|
{ IRQNO(1, 5), IRQNO(12, 5), IRQNO(35, 5), IRQNO(51, 5), IRQNO(53, 5), IRQNONE },
|
|
|
|
{ IRQNO(1, 6), IRQNO(12, 6), IRQNO(35, 6), IRQNO(51, 6), IRQNO(53, 6), IRQNONE },
|
|
|
|
{ IRQNO(1, 7), IRQNO(12, 7), IRQNO(35, 7), IRQNO(51, 7), IRQNO(53, 7), IRQNONE },
|
|
|
|
};
|
|
|
|
|
|
|
|
#undef IRQNO
|
|
|
|
|
|
|
|
static const int *combinermap_entry(int irq)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* If the interrupt number passed in is the first entry in some
|
|
|
|
* line of the combinermap, return a pointer to that line;
|
|
|
|
* otherwise return NULL.
|
|
|
|
*/
|
|
|
|
int i;
|
|
|
|
for (i = 0; i < COMBINERMAP_SIZE; i++) {
|
|
|
|
if (combinermap[i][0] == irq) {
|
|
|
|
return combinermap[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int mapline_size(const int *mapline)
|
|
|
|
{
|
|
|
|
/* Return number of entries in this mapline in total */
|
|
|
|
int i = 0;
|
|
|
|
|
|
|
|
if (!mapline) {
|
|
|
|
/* Not in the map? IRQ goes to exactly one combiner input */
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
while (*mapline != IRQNONE) {
|
|
|
|
mapline++;
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
2022-04-04 15:46:47 +00:00
|
|
|
/*
|
|
|
|
* Initialize board IRQs.
|
|
|
|
* These IRQs contain splitted Int/External Combiner and External Gic IRQs.
|
|
|
|
*/
|
|
|
|
static void exynos4210_init_board_irqs(Exynos4210State *s)
|
|
|
|
{
|
|
|
|
uint32_t grp, bit, irq_id, n;
|
2022-04-04 15:46:49 +00:00
|
|
|
DeviceState *extgicdev = DEVICE(&s->ext_gic);
|
2022-04-04 15:46:58 +00:00
|
|
|
DeviceState *intcdev = DEVICE(&s->int_combiner);
|
|
|
|
DeviceState *extcdev = DEVICE(&s->ext_combiner);
|
2022-04-04 15:46:52 +00:00
|
|
|
int splitcount = 0;
|
|
|
|
DeviceState *splitter;
|
hw/arm/exynos4210: Fold combiner splits into exynos4210_init_board_irqs()
At this point, the function exynos4210_init_board_irqs() splits input
IRQ lines to connect them to the input combiner, output combiner and
external GIC. The function exynos4210_combiner_get_gpioin() splits
some of the combiner input lines further to connect them to multiple
different inputs on the combiner.
Because (unlike qemu_irq_split()) the TYPE_SPLIT_IRQ device has a
configurable number of outputs, we can do all this in one place, by
making exynos4210_init_board_irqs() add extra outputs to the splitter
device when it must be connected to more than one input on each
combiner.
We do this with a new data structure, the combinermap, which is an
array each of whose elements is a list of the interrupt IDs on the
combiner which must be tied together. As we loop through each
interrupt ID, if we find that it is the first one in one of these
lists, we configure the splitter device with eonugh extra outputs and
wire them up to the other interrupt IDs in the list.
Conveniently, for all the cases where this is necessary, the
lowest-numbered interrupt ID in each group is in the range of the
external combiner, so we only need to code for this in the first of
the two loops in exynos4210_init_board_irqs().
The old code in exynos4210_combiner_get_gpioin() which is being
deleted here had several problems which don't exist in the new code
in its handling of the multi-core timer interrupts:
(1) the case labels specified bits 4 ... 8, but bit '8' doesn't
exist; these should have been 4 ... 7
(2) it used the input irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]
multiple times as the input of several different splitters,
which isn't allowed
(3) in an apparent cut-and-paste error, the cases for all the
multi-core timer inputs used "bit + 4" even though the
bit range for the case was (intended to be) 4 ... 7, which
meant it was looking at non-existent bits 8 ... 11.
None of these exist in the new code.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20220404154658.565020-17-peter.maydell@linaro.org
2022-04-04 15:46:56 +00:00
|
|
|
const int *mapline;
|
|
|
|
int numlines, splitin, in;
|
2022-04-04 15:46:47 +00:00
|
|
|
|
|
|
|
for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
|
|
|
|
irq_id = 0;
|
hw/arm/exynos4210: Don't connect multiple lines to external GIC inputs
The combiner_grp_to_gic_id[] array includes the EXT_GIC_ID_MCT_G0
and EXT_GIC_ID_MCT_G1 multiple times. This means that we will
connect multiple IRQs up to the same external GIC input, which
is not permitted. We do the same thing in the code in
exynos4210_init_board_irqs() because the conditionals selecting
an irq_id in the first loop match multiple interrupt IDs.
Overall we do this for interrupt IDs
(1, 4), (12, 4), (35, 4), (51, 4), (53, 4) for EXT_GIC_ID_MCT_G0
and
(1, 5), (12, 5), (35, 5), (51, 5), (53, 5) for EXT_GIC_ID_MCT_G1
These correspond to the cases for the multi-core timer that we are
wiring up to multiple inputs on the combiner in
exynos4210_combiner_get_gpioin(). That code already deals with all
these interrupt IDs being the same input source, so we don't need to
connect the external GIC interrupt for any of them except the first
(1, 4) and (1, 5). Remove the array entries and conditionals which
were incorrectly causing us to wire up extra lines.
This bug didn't cause any visible effects, because we only connect
up a device to the "primary" ID values (1, 4) and (1, 5), so the
extra lines would never be set to a level.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20220404154658.565020-16-peter.maydell@linaro.org
2022-04-04 15:46:55 +00:00
|
|
|
if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 4)) {
|
2022-04-04 15:46:47 +00:00
|
|
|
/* MCT_G0 is passed to External GIC */
|
|
|
|
irq_id = EXT_GIC_ID_MCT_G0;
|
|
|
|
}
|
hw/arm/exynos4210: Don't connect multiple lines to external GIC inputs
The combiner_grp_to_gic_id[] array includes the EXT_GIC_ID_MCT_G0
and EXT_GIC_ID_MCT_G1 multiple times. This means that we will
connect multiple IRQs up to the same external GIC input, which
is not permitted. We do the same thing in the code in
exynos4210_init_board_irqs() because the conditionals selecting
an irq_id in the first loop match multiple interrupt IDs.
Overall we do this for interrupt IDs
(1, 4), (12, 4), (35, 4), (51, 4), (53, 4) for EXT_GIC_ID_MCT_G0
and
(1, 5), (12, 5), (35, 5), (51, 5), (53, 5) for EXT_GIC_ID_MCT_G1
These correspond to the cases for the multi-core timer that we are
wiring up to multiple inputs on the combiner in
exynos4210_combiner_get_gpioin(). That code already deals with all
these interrupt IDs being the same input source, so we don't need to
connect the external GIC interrupt for any of them except the first
(1, 4) and (1, 5). Remove the array entries and conditionals which
were incorrectly causing us to wire up extra lines.
This bug didn't cause any visible effects, because we only connect
up a device to the "primary" ID values (1, 4) and (1, 5), so the
extra lines would never be set to a level.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20220404154658.565020-16-peter.maydell@linaro.org
2022-04-04 15:46:55 +00:00
|
|
|
if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 5)) {
|
2022-04-04 15:46:47 +00:00
|
|
|
/* MCT_G1 is passed to External and GIC */
|
|
|
|
irq_id = EXT_GIC_ID_MCT_G1;
|
|
|
|
}
|
2022-04-04 15:46:52 +00:00
|
|
|
|
hw/arm/exynos4210: Fold combiner splits into exynos4210_init_board_irqs()
At this point, the function exynos4210_init_board_irqs() splits input
IRQ lines to connect them to the input combiner, output combiner and
external GIC. The function exynos4210_combiner_get_gpioin() splits
some of the combiner input lines further to connect them to multiple
different inputs on the combiner.
Because (unlike qemu_irq_split()) the TYPE_SPLIT_IRQ device has a
configurable number of outputs, we can do all this in one place, by
making exynos4210_init_board_irqs() add extra outputs to the splitter
device when it must be connected to more than one input on each
combiner.
We do this with a new data structure, the combinermap, which is an
array each of whose elements is a list of the interrupt IDs on the
combiner which must be tied together. As we loop through each
interrupt ID, if we find that it is the first one in one of these
lists, we configure the splitter device with eonugh extra outputs and
wire them up to the other interrupt IDs in the list.
Conveniently, for all the cases where this is necessary, the
lowest-numbered interrupt ID in each group is in the range of the
external combiner, so we only need to code for this in the first of
the two loops in exynos4210_init_board_irqs().
The old code in exynos4210_combiner_get_gpioin() which is being
deleted here had several problems which don't exist in the new code
in its handling of the multi-core timer interrupts:
(1) the case labels specified bits 4 ... 8, but bit '8' doesn't
exist; these should have been 4 ... 7
(2) it used the input irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]
multiple times as the input of several different splitters,
which isn't allowed
(3) in an apparent cut-and-paste error, the cases for all the
multi-core timer inputs used "bit + 4" even though the
bit range for the case was (intended to be) 4 ... 7, which
meant it was looking at non-existent bits 8 ... 11.
None of these exist in the new code.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20220404154658.565020-17-peter.maydell@linaro.org
2022-04-04 15:46:56 +00:00
|
|
|
if (s->irq_table[n]) {
|
|
|
|
/*
|
|
|
|
* This must be some non-first entry in a combinermap line,
|
|
|
|
* and we've already filled it in.
|
|
|
|
*/
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
mapline = combinermap_entry(n);
|
|
|
|
/*
|
|
|
|
* We need to connect the IRQ to multiple inputs on both combiners
|
|
|
|
* and possibly also to the external GIC.
|
|
|
|
*/
|
|
|
|
numlines = 2 * mapline_size(mapline);
|
|
|
|
if (irq_id) {
|
|
|
|
numlines++;
|
|
|
|
}
|
2022-04-04 15:46:52 +00:00
|
|
|
assert(splitcount < EXYNOS4210_NUM_SPLITTERS);
|
|
|
|
splitter = DEVICE(&s->splitter[splitcount]);
|
hw/arm/exynos4210: Fold combiner splits into exynos4210_init_board_irqs()
At this point, the function exynos4210_init_board_irqs() splits input
IRQ lines to connect them to the input combiner, output combiner and
external GIC. The function exynos4210_combiner_get_gpioin() splits
some of the combiner input lines further to connect them to multiple
different inputs on the combiner.
Because (unlike qemu_irq_split()) the TYPE_SPLIT_IRQ device has a
configurable number of outputs, we can do all this in one place, by
making exynos4210_init_board_irqs() add extra outputs to the splitter
device when it must be connected to more than one input on each
combiner.
We do this with a new data structure, the combinermap, which is an
array each of whose elements is a list of the interrupt IDs on the
combiner which must be tied together. As we loop through each
interrupt ID, if we find that it is the first one in one of these
lists, we configure the splitter device with eonugh extra outputs and
wire them up to the other interrupt IDs in the list.
Conveniently, for all the cases where this is necessary, the
lowest-numbered interrupt ID in each group is in the range of the
external combiner, so we only need to code for this in the first of
the two loops in exynos4210_init_board_irqs().
The old code in exynos4210_combiner_get_gpioin() which is being
deleted here had several problems which don't exist in the new code
in its handling of the multi-core timer interrupts:
(1) the case labels specified bits 4 ... 8, but bit '8' doesn't
exist; these should have been 4 ... 7
(2) it used the input irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]
multiple times as the input of several different splitters,
which isn't allowed
(3) in an apparent cut-and-paste error, the cases for all the
multi-core timer inputs used "bit + 4" even though the
bit range for the case was (intended to be) 4 ... 7, which
meant it was looking at non-existent bits 8 ... 11.
None of these exist in the new code.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20220404154658.565020-17-peter.maydell@linaro.org
2022-04-04 15:46:56 +00:00
|
|
|
qdev_prop_set_uint16(splitter, "num-lines", numlines);
|
2022-04-04 15:46:52 +00:00
|
|
|
qdev_realize(splitter, NULL, &error_abort);
|
|
|
|
splitcount++;
|
hw/arm/exynos4210: Fold combiner splits into exynos4210_init_board_irqs()
At this point, the function exynos4210_init_board_irqs() splits input
IRQ lines to connect them to the input combiner, output combiner and
external GIC. The function exynos4210_combiner_get_gpioin() splits
some of the combiner input lines further to connect them to multiple
different inputs on the combiner.
Because (unlike qemu_irq_split()) the TYPE_SPLIT_IRQ device has a
configurable number of outputs, we can do all this in one place, by
making exynos4210_init_board_irqs() add extra outputs to the splitter
device when it must be connected to more than one input on each
combiner.
We do this with a new data structure, the combinermap, which is an
array each of whose elements is a list of the interrupt IDs on the
combiner which must be tied together. As we loop through each
interrupt ID, if we find that it is the first one in one of these
lists, we configure the splitter device with eonugh extra outputs and
wire them up to the other interrupt IDs in the list.
Conveniently, for all the cases where this is necessary, the
lowest-numbered interrupt ID in each group is in the range of the
external combiner, so we only need to code for this in the first of
the two loops in exynos4210_init_board_irqs().
The old code in exynos4210_combiner_get_gpioin() which is being
deleted here had several problems which don't exist in the new code
in its handling of the multi-core timer interrupts:
(1) the case labels specified bits 4 ... 8, but bit '8' doesn't
exist; these should have been 4 ... 7
(2) it used the input irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]
multiple times as the input of several different splitters,
which isn't allowed
(3) in an apparent cut-and-paste error, the cases for all the
multi-core timer inputs used "bit + 4" even though the
bit range for the case was (intended to be) 4 ... 7, which
meant it was looking at non-existent bits 8 ... 11.
None of these exist in the new code.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20220404154658.565020-17-peter.maydell@linaro.org
2022-04-04 15:46:56 +00:00
|
|
|
|
|
|
|
in = n;
|
|
|
|
splitin = 0;
|
|
|
|
for (;;) {
|
|
|
|
s->irq_table[in] = qdev_get_gpio_in(splitter, 0);
|
2022-04-04 15:46:58 +00:00
|
|
|
qdev_connect_gpio_out(splitter, splitin,
|
|
|
|
qdev_get_gpio_in(intcdev, in));
|
|
|
|
qdev_connect_gpio_out(splitter, splitin + 1,
|
|
|
|
qdev_get_gpio_in(extcdev, in));
|
hw/arm/exynos4210: Fold combiner splits into exynos4210_init_board_irqs()
At this point, the function exynos4210_init_board_irqs() splits input
IRQ lines to connect them to the input combiner, output combiner and
external GIC. The function exynos4210_combiner_get_gpioin() splits
some of the combiner input lines further to connect them to multiple
different inputs on the combiner.
Because (unlike qemu_irq_split()) the TYPE_SPLIT_IRQ device has a
configurable number of outputs, we can do all this in one place, by
making exynos4210_init_board_irqs() add extra outputs to the splitter
device when it must be connected to more than one input on each
combiner.
We do this with a new data structure, the combinermap, which is an
array each of whose elements is a list of the interrupt IDs on the
combiner which must be tied together. As we loop through each
interrupt ID, if we find that it is the first one in one of these
lists, we configure the splitter device with eonugh extra outputs and
wire them up to the other interrupt IDs in the list.
Conveniently, for all the cases where this is necessary, the
lowest-numbered interrupt ID in each group is in the range of the
external combiner, so we only need to code for this in the first of
the two loops in exynos4210_init_board_irqs().
The old code in exynos4210_combiner_get_gpioin() which is being
deleted here had several problems which don't exist in the new code
in its handling of the multi-core timer interrupts:
(1) the case labels specified bits 4 ... 8, but bit '8' doesn't
exist; these should have been 4 ... 7
(2) it used the input irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]
multiple times as the input of several different splitters,
which isn't allowed
(3) in an apparent cut-and-paste error, the cases for all the
multi-core timer inputs used "bit + 4" even though the
bit range for the case was (intended to be) 4 ... 7, which
meant it was looking at non-existent bits 8 ... 11.
None of these exist in the new code.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20220404154658.565020-17-peter.maydell@linaro.org
2022-04-04 15:46:56 +00:00
|
|
|
splitin += 2;
|
|
|
|
if (!mapline) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
mapline++;
|
|
|
|
in = *mapline;
|
|
|
|
if (in == IRQNONE) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2022-04-04 15:46:47 +00:00
|
|
|
if (irq_id) {
|
hw/arm/exynos4210: Fold combiner splits into exynos4210_init_board_irqs()
At this point, the function exynos4210_init_board_irqs() splits input
IRQ lines to connect them to the input combiner, output combiner and
external GIC. The function exynos4210_combiner_get_gpioin() splits
some of the combiner input lines further to connect them to multiple
different inputs on the combiner.
Because (unlike qemu_irq_split()) the TYPE_SPLIT_IRQ device has a
configurable number of outputs, we can do all this in one place, by
making exynos4210_init_board_irqs() add extra outputs to the splitter
device when it must be connected to more than one input on each
combiner.
We do this with a new data structure, the combinermap, which is an
array each of whose elements is a list of the interrupt IDs on the
combiner which must be tied together. As we loop through each
interrupt ID, if we find that it is the first one in one of these
lists, we configure the splitter device with eonugh extra outputs and
wire them up to the other interrupt IDs in the list.
Conveniently, for all the cases where this is necessary, the
lowest-numbered interrupt ID in each group is in the range of the
external combiner, so we only need to code for this in the first of
the two loops in exynos4210_init_board_irqs().
The old code in exynos4210_combiner_get_gpioin() which is being
deleted here had several problems which don't exist in the new code
in its handling of the multi-core timer interrupts:
(1) the case labels specified bits 4 ... 8, but bit '8' doesn't
exist; these should have been 4 ... 7
(2) it used the input irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]
multiple times as the input of several different splitters,
which isn't allowed
(3) in an apparent cut-and-paste error, the cases for all the
multi-core timer inputs used "bit + 4" even though the
bit range for the case was (intended to be) 4 ... 7, which
meant it was looking at non-existent bits 8 ... 11.
None of these exist in the new code.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20220404154658.565020-17-peter.maydell@linaro.org
2022-04-04 15:46:56 +00:00
|
|
|
qdev_connect_gpio_out(splitter, splitin,
|
2022-04-04 15:46:52 +00:00
|
|
|
qdev_get_gpio_in(extgicdev, irq_id - 32));
|
2022-04-04 15:46:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
for (; n < EXYNOS4210_MAX_INT_COMBINER_IN_IRQ; n++) {
|
|
|
|
/* these IDs are passed to Internal Combiner and External GIC */
|
|
|
|
grp = EXYNOS4210_COMBINER_GET_GRP_NUM(n);
|
|
|
|
bit = EXYNOS4210_COMBINER_GET_BIT_NUM(n);
|
|
|
|
irq_id = combiner_grp_to_gic_id[grp -
|
|
|
|
EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][bit];
|
|
|
|
|
hw/arm/exynos4210: Fold combiner splits into exynos4210_init_board_irqs()
At this point, the function exynos4210_init_board_irqs() splits input
IRQ lines to connect them to the input combiner, output combiner and
external GIC. The function exynos4210_combiner_get_gpioin() splits
some of the combiner input lines further to connect them to multiple
different inputs on the combiner.
Because (unlike qemu_irq_split()) the TYPE_SPLIT_IRQ device has a
configurable number of outputs, we can do all this in one place, by
making exynos4210_init_board_irqs() add extra outputs to the splitter
device when it must be connected to more than one input on each
combiner.
We do this with a new data structure, the combinermap, which is an
array each of whose elements is a list of the interrupt IDs on the
combiner which must be tied together. As we loop through each
interrupt ID, if we find that it is the first one in one of these
lists, we configure the splitter device with eonugh extra outputs and
wire them up to the other interrupt IDs in the list.
Conveniently, for all the cases where this is necessary, the
lowest-numbered interrupt ID in each group is in the range of the
external combiner, so we only need to code for this in the first of
the two loops in exynos4210_init_board_irqs().
The old code in exynos4210_combiner_get_gpioin() which is being
deleted here had several problems which don't exist in the new code
in its handling of the multi-core timer interrupts:
(1) the case labels specified bits 4 ... 8, but bit '8' doesn't
exist; these should have been 4 ... 7
(2) it used the input irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]
multiple times as the input of several different splitters,
which isn't allowed
(3) in an apparent cut-and-paste error, the cases for all the
multi-core timer inputs used "bit + 4" even though the
bit range for the case was (intended to be) 4 ... 7, which
meant it was looking at non-existent bits 8 ... 11.
None of these exist in the new code.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20220404154658.565020-17-peter.maydell@linaro.org
2022-04-04 15:46:56 +00:00
|
|
|
if (s->irq_table[n]) {
|
|
|
|
/*
|
|
|
|
* This must be some non-first entry in a combinermap line,
|
|
|
|
* and we've already filled it in.
|
|
|
|
*/
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2022-04-04 15:46:47 +00:00
|
|
|
if (irq_id) {
|
2022-04-04 15:46:52 +00:00
|
|
|
assert(splitcount < EXYNOS4210_NUM_SPLITTERS);
|
|
|
|
splitter = DEVICE(&s->splitter[splitcount]);
|
|
|
|
qdev_prop_set_uint16(splitter, "num-lines", 2);
|
|
|
|
qdev_realize(splitter, NULL, &error_abort);
|
|
|
|
splitcount++;
|
|
|
|
s->irq_table[n] = qdev_get_gpio_in(splitter, 0);
|
2022-04-04 15:46:58 +00:00
|
|
|
qdev_connect_gpio_out(splitter, 0, qdev_get_gpio_in(intcdev, n));
|
2022-04-04 15:46:52 +00:00
|
|
|
qdev_connect_gpio_out(splitter, 1,
|
|
|
|
qdev_get_gpio_in(extgicdev, irq_id - 32));
|
hw/arm/exynos4210: Fill in irq_table[] for internal-combiner-only IRQ lines
In exynos4210_init_board_irqs(), the loop that handles IRQ lines that
are in a range that applies to the internal combiner only creates a
splitter for those interrupts which go to both the internal combiner
and to the external GIC, but it does nothing at all for the
interrupts which don't go to the external GIC, leaving the
irq_table[] array element empty for those. (This will result in
those interrupts simply being lost, not in a QEMU crash.)
I don't have a reliable datasheet for this SoC, but since we do wire
up one interrupt line in this category (the HDMI I2C device on
interrupt 16,1), this seems like it must be a bug in the existing
QEMU code. Fill in the irq_table[] entries where we're not splitting
the IRQ to both the internal combiner and the external GIC with the
IRQ line of the internal combiner. (That is, these IRQ lines go to
just one device, not multiple.)
This bug didn't have any visible guest effects because the only
implemented device that was affected was the HDMI I2C controller,
and we never connect any I2C devices to that bus.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20220404154658.565020-14-peter.maydell@linaro.org
2022-04-04 15:46:53 +00:00
|
|
|
} else {
|
2022-04-04 15:46:58 +00:00
|
|
|
s->irq_table[n] = qdev_get_gpio_in(intcdev, n);
|
2022-04-04 15:46:47 +00:00
|
|
|
}
|
|
|
|
}
|
2022-04-04 15:46:52 +00:00
|
|
|
/*
|
|
|
|
* We check this here to avoid a more obscure assert later when
|
|
|
|
* qdev_assert_realized_properly() checks that we realized every
|
|
|
|
* child object we initialized.
|
|
|
|
*/
|
|
|
|
assert(splitcount == EXYNOS4210_NUM_SPLITTERS);
|
2022-04-04 15:46:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Get IRQ number from exynos4210 IRQ subsystem stub.
|
|
|
|
* To identify IRQ source use internal combiner group and bit number
|
|
|
|
* grp - group number
|
|
|
|
* bit - bit number inside group
|
|
|
|
*/
|
|
|
|
uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit)
|
|
|
|
{
|
|
|
|
return EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit);
|
|
|
|
}
|
|
|
|
|
2012-02-16 09:56:05 +00:00
|
|
|
static uint8_t chipid_and_omr[] = { 0x11, 0x02, 0x21, 0x43,
|
|
|
|
0x09, 0x00, 0x00, 0x00 };
|
|
|
|
|
2013-06-03 16:17:46 +00:00
|
|
|
static uint64_t exynos4210_chipid_and_omr_read(void *opaque, hwaddr offset,
|
|
|
|
unsigned size)
|
|
|
|
{
|
|
|
|
assert(offset < sizeof(chipid_and_omr));
|
|
|
|
return chipid_and_omr[offset];
|
|
|
|
}
|
|
|
|
|
|
|
|
static void exynos4210_chipid_and_omr_write(void *opaque, hwaddr offset,
|
|
|
|
uint64_t value, unsigned size)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const MemoryRegionOps exynos4210_chipid_and_omr_ops = {
|
|
|
|
.read = exynos4210_chipid_and_omr_read,
|
|
|
|
.write = exynos4210_chipid_and_omr_write,
|
|
|
|
.endianness = DEVICE_NATIVE_ENDIAN,
|
|
|
|
.impl = {
|
|
|
|
.max_access_size = 1,
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2012-05-13 22:08:10 +00:00
|
|
|
void exynos4210_write_secondary(ARMCPU *cpu,
|
2012-04-13 11:39:06 +00:00
|
|
|
const struct arm_boot_info *info)
|
|
|
|
{
|
|
|
|
int n;
|
|
|
|
uint32_t smpboot[] = {
|
2012-12-11 11:30:37 +00:00
|
|
|
0xe59f3034, /* ldr r3, External gic_cpu_if */
|
|
|
|
0xe59f2034, /* ldr r2, Internal gic_cpu_if */
|
|
|
|
0xe59f0034, /* ldr r0, startaddr */
|
2012-04-13 11:39:06 +00:00
|
|
|
0xe3a01001, /* mov r1, #1 */
|
|
|
|
0xe5821000, /* str r1, [r2] */
|
|
|
|
0xe5831000, /* str r1, [r3] */
|
2012-12-11 11:30:37 +00:00
|
|
|
0xe3a010ff, /* mov r1, #0xff */
|
|
|
|
0xe5821004, /* str r1, [r2, #4] */
|
|
|
|
0xe5831004, /* str r1, [r3, #4] */
|
|
|
|
0xf57ff04f, /* dsb */
|
2012-04-13 11:39:06 +00:00
|
|
|
0xe320f003, /* wfi */
|
|
|
|
0xe5901000, /* ldr r1, [r0] */
|
|
|
|
0xe1110001, /* tst r1, r1 */
|
|
|
|
0x0afffffb, /* beq <wfi> */
|
|
|
|
0xe12fff11, /* bx r1 */
|
|
|
|
EXYNOS4210_EXT_GIC_CPU_BASE_ADDR,
|
|
|
|
0, /* gic_cpu_if: base address of Internal GIC CPU interface */
|
|
|
|
0 /* bootreg: Boot register address is held here */
|
|
|
|
};
|
|
|
|
smpboot[ARRAY_SIZE(smpboot) - 1] = info->smp_bootreg_addr;
|
|
|
|
smpboot[ARRAY_SIZE(smpboot) - 2] = info->gic_cpu_if_addr;
|
|
|
|
for (n = 0; n < ARRAY_SIZE(smpboot); n++) {
|
|
|
|
smpboot[n] = tswap32(smpboot[n]);
|
|
|
|
}
|
|
|
|
rom_add_blob_fixed("smpboot", smpboot, sizeof(smpboot),
|
|
|
|
info->smp_loader_start);
|
|
|
|
}
|
|
|
|
|
2017-02-28 12:08:20 +00:00
|
|
|
static uint64_t exynos4210_calc_affinity(int cpu)
|
|
|
|
{
|
|
|
|
/* Exynos4210 has 0x9 as cluster ID */
|
2018-03-23 14:32:02 +00:00
|
|
|
return (0x9 << ARM_AFF1_SHIFT) | cpu;
|
2017-02-28 12:08:20 +00:00
|
|
|
}
|
|
|
|
|
2020-01-23 15:22:42 +00:00
|
|
|
static DeviceState *pl330_create(uint32_t base, qemu_or_irq *orgate,
|
|
|
|
qemu_irq irq, int nreq, int nevents, int width)
|
hw/arm/exynos4210: Add DMA support for the Exynos4210
QEMU already supports pl330. Instantiate it for Exynos4210.
Relevant part of Linux arch/arm/boot/dts/exynos4.dtsi:
/ {
soc: soc {
amba {
pdma0: pdma@12680000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x12680000 0x1000>;
interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_PDMA0>;
clock-names = "apb_pclk";
#dma-cells = <1>;
#dma-channels = <8>;
#dma-requests = <32>;
};
pdma1: pdma@12690000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x12690000 0x1000>;
interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_PDMA1>;
clock-names = "apb_pclk";
#dma-cells = <1>;
#dma-channels = <8>;
#dma-requests = <32>;
};
mdma1: mdma@12850000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x12850000 0x1000>;
interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_MDMA>;
clock-names = "apb_pclk";
#dma-cells = <1>;
#dma-channels = <8>;
#dma-requests = <1>;
};
};
};
};
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-id: 20190520214342.13709-4-philmd@redhat.com
[PMD: Do not set default qdev properties, create the controllers in the SoC
rather than the board (Peter Maydell), add dtsi in commit message]
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2019-05-23 13:47:44 +00:00
|
|
|
{
|
|
|
|
SysBusDevice *busdev;
|
|
|
|
DeviceState *dev;
|
2020-01-23 15:22:41 +00:00
|
|
|
int i;
|
hw/arm/exynos4210: Add DMA support for the Exynos4210
QEMU already supports pl330. Instantiate it for Exynos4210.
Relevant part of Linux arch/arm/boot/dts/exynos4.dtsi:
/ {
soc: soc {
amba {
pdma0: pdma@12680000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x12680000 0x1000>;
interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_PDMA0>;
clock-names = "apb_pclk";
#dma-cells = <1>;
#dma-channels = <8>;
#dma-requests = <32>;
};
pdma1: pdma@12690000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x12690000 0x1000>;
interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_PDMA1>;
clock-names = "apb_pclk";
#dma-cells = <1>;
#dma-channels = <8>;
#dma-requests = <32>;
};
mdma1: mdma@12850000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x12850000 0x1000>;
interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_MDMA>;
clock-names = "apb_pclk";
#dma-cells = <1>;
#dma-channels = <8>;
#dma-requests = <1>;
};
};
};
};
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-id: 20190520214342.13709-4-philmd@redhat.com
[PMD: Do not set default qdev properties, create the controllers in the SoC
rather than the board (Peter Maydell), add dtsi in commit message]
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2019-05-23 13:47:44 +00:00
|
|
|
|
qdev: Convert uses of qdev_create() with Coccinelle
This is the transformation explained in the commit before previous.
Takes care of just one pattern that needs conversion. More to come in
this series.
Coccinelle script:
@ depends on !(file in "hw/arm/highbank.c")@
expression bus, type_name, dev, expr;
@@
- dev = qdev_create(bus, type_name);
+ dev = qdev_new(type_name);
... when != dev = expr
- qdev_init_nofail(dev);
+ qdev_realize_and_unref(dev, bus, &error_fatal);
@@
expression bus, type_name, dev, expr;
identifier DOWN;
@@
- dev = DOWN(qdev_create(bus, type_name));
+ dev = DOWN(qdev_new(type_name));
... when != dev = expr
- qdev_init_nofail(DEVICE(dev));
+ qdev_realize_and_unref(DEVICE(dev), bus, &error_fatal);
@@
expression bus, type_name, expr;
identifier dev;
@@
- DeviceState *dev = qdev_create(bus, type_name);
+ DeviceState *dev = qdev_new(type_name);
... when != dev = expr
- qdev_init_nofail(dev);
+ qdev_realize_and_unref(dev, bus, &error_fatal);
@@
expression bus, type_name, dev, expr, errp;
symbol true;
@@
- dev = qdev_create(bus, type_name);
+ dev = qdev_new(type_name);
... when != dev = expr
- object_property_set_bool(OBJECT(dev), true, "realized", errp);
+ qdev_realize_and_unref(dev, bus, errp);
@@
expression bus, type_name, expr, errp;
identifier dev;
symbol true;
@@
- DeviceState *dev = qdev_create(bus, type_name);
+ DeviceState *dev = qdev_new(type_name);
... when != dev = expr
- object_property_set_bool(OBJECT(dev), true, "realized", errp);
+ qdev_realize_and_unref(dev, bus, errp);
The first rule exempts hw/arm/highbank.c, because it matches along two
control flow paths there, with different @type_name. Covered by the
next commit's manual conversions.
Missing #include "qapi/error.h" added manually.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <20200610053247.1583243-10-armbru@redhat.com>
[Conflicts in hw/misc/empty_slot.c and hw/sparc/leon3.c resolved]
2020-06-10 05:31:58 +00:00
|
|
|
dev = qdev_new("pl330");
|
2021-08-18 10:17:00 +00:00
|
|
|
object_property_set_link(OBJECT(dev), "memory",
|
|
|
|
OBJECT(get_system_memory()),
|
|
|
|
&error_fatal);
|
2020-01-23 15:22:41 +00:00
|
|
|
qdev_prop_set_uint8(dev, "num_events", nevents);
|
|
|
|
qdev_prop_set_uint8(dev, "num_chnls", 8);
|
hw/arm/exynos4210: Add DMA support for the Exynos4210
QEMU already supports pl330. Instantiate it for Exynos4210.
Relevant part of Linux arch/arm/boot/dts/exynos4.dtsi:
/ {
soc: soc {
amba {
pdma0: pdma@12680000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x12680000 0x1000>;
interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_PDMA0>;
clock-names = "apb_pclk";
#dma-cells = <1>;
#dma-channels = <8>;
#dma-requests = <32>;
};
pdma1: pdma@12690000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x12690000 0x1000>;
interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_PDMA1>;
clock-names = "apb_pclk";
#dma-cells = <1>;
#dma-channels = <8>;
#dma-requests = <32>;
};
mdma1: mdma@12850000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x12850000 0x1000>;
interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_MDMA>;
clock-names = "apb_pclk";
#dma-cells = <1>;
#dma-channels = <8>;
#dma-requests = <1>;
};
};
};
};
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-id: 20190520214342.13709-4-philmd@redhat.com
[PMD: Do not set default qdev properties, create the controllers in the SoC
rather than the board (Peter Maydell), add dtsi in commit message]
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2019-05-23 13:47:44 +00:00
|
|
|
qdev_prop_set_uint8(dev, "num_periph_req", nreq);
|
2020-01-23 15:22:41 +00:00
|
|
|
|
|
|
|
qdev_prop_set_uint8(dev, "wr_cap", 4);
|
|
|
|
qdev_prop_set_uint8(dev, "wr_q_dep", 8);
|
|
|
|
qdev_prop_set_uint8(dev, "rd_cap", 4);
|
|
|
|
qdev_prop_set_uint8(dev, "rd_q_dep", 8);
|
|
|
|
qdev_prop_set_uint8(dev, "data_width", width);
|
|
|
|
qdev_prop_set_uint16(dev, "data_buffer_dep", width);
|
hw/arm/exynos4210: Add DMA support for the Exynos4210
QEMU already supports pl330. Instantiate it for Exynos4210.
Relevant part of Linux arch/arm/boot/dts/exynos4.dtsi:
/ {
soc: soc {
amba {
pdma0: pdma@12680000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x12680000 0x1000>;
interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_PDMA0>;
clock-names = "apb_pclk";
#dma-cells = <1>;
#dma-channels = <8>;
#dma-requests = <32>;
};
pdma1: pdma@12690000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x12690000 0x1000>;
interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_PDMA1>;
clock-names = "apb_pclk";
#dma-cells = <1>;
#dma-channels = <8>;
#dma-requests = <32>;
};
mdma1: mdma@12850000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x12850000 0x1000>;
interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_MDMA>;
clock-names = "apb_pclk";
#dma-cells = <1>;
#dma-channels = <8>;
#dma-requests = <1>;
};
};
};
};
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-id: 20190520214342.13709-4-philmd@redhat.com
[PMD: Do not set default qdev properties, create the controllers in the SoC
rather than the board (Peter Maydell), add dtsi in commit message]
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2019-05-23 13:47:44 +00:00
|
|
|
busdev = SYS_BUS_DEVICE(dev);
|
sysbus: Convert to sysbus_realize() etc. with Coccinelle
Convert from qdev_realize(), qdev_realize_and_unref() with null @bus
argument to sysbus_realize(), sysbus_realize_and_unref().
Coccinelle script:
@@
expression dev, errp;
@@
- qdev_realize(DEVICE(dev), NULL, errp);
+ sysbus_realize(SYS_BUS_DEVICE(dev), errp);
@@
expression sysbus_dev, dev, errp;
@@
+ sysbus_dev = SYS_BUS_DEVICE(dev);
- qdev_realize_and_unref(dev, NULL, errp);
+ sysbus_realize_and_unref(sysbus_dev, errp);
- sysbus_dev = SYS_BUS_DEVICE(dev);
@@
expression sysbus_dev, dev, errp;
expression expr;
@@
sysbus_dev = SYS_BUS_DEVICE(dev);
... when != dev = expr;
- qdev_realize_and_unref(dev, NULL, errp);
+ sysbus_realize_and_unref(sysbus_dev, errp);
@@
expression dev, errp;
@@
- qdev_realize_and_unref(DEVICE(dev), NULL, errp);
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), errp);
@@
expression dev, errp;
@@
- qdev_realize_and_unref(dev, NULL, errp);
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), errp);
Whitespace changes minimized manually.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <20200610053247.1583243-46-armbru@redhat.com>
[Conflicts in hw/misc/empty_slot.c and hw/sparc/leon3.c resolved]
2020-06-10 05:32:34 +00:00
|
|
|
sysbus_realize_and_unref(busdev, &error_fatal);
|
hw/arm/exynos4210: Add DMA support for the Exynos4210
QEMU already supports pl330. Instantiate it for Exynos4210.
Relevant part of Linux arch/arm/boot/dts/exynos4.dtsi:
/ {
soc: soc {
amba {
pdma0: pdma@12680000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x12680000 0x1000>;
interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_PDMA0>;
clock-names = "apb_pclk";
#dma-cells = <1>;
#dma-channels = <8>;
#dma-requests = <32>;
};
pdma1: pdma@12690000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x12690000 0x1000>;
interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_PDMA1>;
clock-names = "apb_pclk";
#dma-cells = <1>;
#dma-channels = <8>;
#dma-requests = <32>;
};
mdma1: mdma@12850000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x12850000 0x1000>;
interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_MDMA>;
clock-names = "apb_pclk";
#dma-cells = <1>;
#dma-channels = <8>;
#dma-requests = <1>;
};
};
};
};
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-id: 20190520214342.13709-4-philmd@redhat.com
[PMD: Do not set default qdev properties, create the controllers in the SoC
rather than the board (Peter Maydell), add dtsi in commit message]
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2019-05-23 13:47:44 +00:00
|
|
|
sysbus_mmio_map(busdev, 0, base);
|
2020-01-23 15:22:41 +00:00
|
|
|
|
qom: Put name parameter before value / visitor parameter
The object_property_set_FOO() setters take property name and value in
an unusual order:
void object_property_set_FOO(Object *obj, FOO_TYPE value,
const char *name, Error **errp)
Having to pass value before name feels grating. Swap them.
Same for object_property_set(), object_property_get(), and
object_property_parse().
Convert callers with this Coccinelle script:
@@
identifier fun = {
object_property_get, object_property_parse, object_property_set_str,
object_property_set_link, object_property_set_bool,
object_property_set_int, object_property_set_uint, object_property_set,
object_property_set_qobject
};
expression obj, v, name, errp;
@@
- fun(obj, v, name, errp)
+ fun(obj, name, v, errp)
Chokes on hw/arm/musicpal.c's lcd_refresh() with the unhelpful error
message "no position information". Convert that one manually.
Fails to convert hw/arm/armsse.c, because Coccinelle gets confused by
ARMSSE being used both as typedef and function-like macro there.
Convert manually.
Fails to convert hw/rx/rx-gdbsim.c, because Coccinelle gets confused
by RXCPU being used both as typedef and function-like macro there.
Convert manually. The other files using RXCPU that way don't need
conversion.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Message-Id: <20200707160613.848843-27-armbru@redhat.com>
[Straightforwad conflict with commit 2336172d9b "audio: set default
value for pcspk.iobase property" resolved]
2020-07-07 16:05:54 +00:00
|
|
|
object_property_set_int(OBJECT(orgate), "num-lines", nevents + 1,
|
2020-01-23 15:22:41 +00:00
|
|
|
&error_abort);
|
qdev: Convert bus-less devices to qdev_realize() with Coccinelle
All remaining conversions to qdev_realize() are for bus-less devices.
Coccinelle script:
// only correct for bus-less @dev!
@@
expression errp;
expression dev;
@@
- qdev_init_nofail(dev);
+ qdev_realize(dev, NULL, &error_fatal);
@ depends on !(file in "hw/core/qdev.c") && !(file in "hw/core/bus.c")@
expression errp;
expression dev;
symbol true;
@@
- object_property_set_bool(OBJECT(dev), true, "realized", errp);
+ qdev_realize(DEVICE(dev), NULL, errp);
@ depends on !(file in "hw/core/qdev.c") && !(file in "hw/core/bus.c")@
expression errp;
expression dev;
symbol true;
@@
- object_property_set_bool(dev, true, "realized", errp);
+ qdev_realize(DEVICE(dev), NULL, errp);
Note that Coccinelle chokes on ARMSSE typedef vs. macro in
hw/arm/armsse.c. Worked around by temporarily renaming the macro for
the spatch run.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <20200610053247.1583243-57-armbru@redhat.com>
2020-06-10 05:32:45 +00:00
|
|
|
qdev_realize(DEVICE(orgate), NULL, &error_abort);
|
2020-01-23 15:22:41 +00:00
|
|
|
|
|
|
|
for (i = 0; i < nevents + 1; i++) {
|
|
|
|
sysbus_connect_irq(busdev, i, qdev_get_gpio_in(DEVICE(orgate), i));
|
|
|
|
}
|
|
|
|
qdev_connect_gpio_out(DEVICE(orgate), 0, irq);
|
2020-01-23 15:22:42 +00:00
|
|
|
return dev;
|
hw/arm/exynos4210: Add DMA support for the Exynos4210
QEMU already supports pl330. Instantiate it for Exynos4210.
Relevant part of Linux arch/arm/boot/dts/exynos4.dtsi:
/ {
soc: soc {
amba {
pdma0: pdma@12680000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x12680000 0x1000>;
interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_PDMA0>;
clock-names = "apb_pclk";
#dma-cells = <1>;
#dma-channels = <8>;
#dma-requests = <32>;
};
pdma1: pdma@12690000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x12690000 0x1000>;
interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_PDMA1>;
clock-names = "apb_pclk";
#dma-cells = <1>;
#dma-channels = <8>;
#dma-requests = <32>;
};
mdma1: mdma@12850000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x12850000 0x1000>;
interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_MDMA>;
clock-names = "apb_pclk";
#dma-cells = <1>;
#dma-channels = <8>;
#dma-requests = <1>;
};
};
};
};
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-id: 20190520214342.13709-4-philmd@redhat.com
[PMD: Do not set default qdev properties, create the controllers in the SoC
rather than the board (Peter Maydell), add dtsi in commit message]
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2019-05-23 13:47:44 +00:00
|
|
|
}
|
|
|
|
|
2019-05-23 13:47:44 +00:00
|
|
|
static void exynos4210_realize(DeviceState *socdev, Error **errp)
|
2012-02-16 09:56:05 +00:00
|
|
|
{
|
2019-05-23 13:47:44 +00:00
|
|
|
Exynos4210State *s = EXYNOS4210_SOC(socdev);
|
|
|
|
MemoryRegion *system_mem = get_system_memory();
|
2012-02-16 09:56:05 +00:00
|
|
|
SysBusDevice *busdev;
|
2020-01-23 15:22:42 +00:00
|
|
|
DeviceState *dev, *uart[4], *pl330[3];
|
2017-06-13 13:56:57 +00:00
|
|
|
int i, n;
|
2014-03-17 16:31:46 +00:00
|
|
|
|
2012-02-16 09:56:05 +00:00
|
|
|
for (n = 0; n < EXYNOS4210_NCPUS; n++) {
|
2017-09-13 16:04:57 +00:00
|
|
|
Object *cpuobj = object_new(ARM_CPU_TYPE_NAME("cortex-a9"));
|
2014-03-17 16:31:46 +00:00
|
|
|
|
2014-12-15 23:09:51 +00:00
|
|
|
/* By default A9 CPUs have EL3 enabled. This board does not currently
|
|
|
|
* support EL3 so the CPU EL3 property is disabled before realization.
|
|
|
|
*/
|
2020-09-14 13:56:17 +00:00
|
|
|
if (object_property_find(cpuobj, "has_el3")) {
|
qom: Put name parameter before value / visitor parameter
The object_property_set_FOO() setters take property name and value in
an unusual order:
void object_property_set_FOO(Object *obj, FOO_TYPE value,
const char *name, Error **errp)
Having to pass value before name feels grating. Swap them.
Same for object_property_set(), object_property_get(), and
object_property_parse().
Convert callers with this Coccinelle script:
@@
identifier fun = {
object_property_get, object_property_parse, object_property_set_str,
object_property_set_link, object_property_set_bool,
object_property_set_int, object_property_set_uint, object_property_set,
object_property_set_qobject
};
expression obj, v, name, errp;
@@
- fun(obj, v, name, errp)
+ fun(obj, name, v, errp)
Chokes on hw/arm/musicpal.c's lcd_refresh() with the unhelpful error
message "no position information". Convert that one manually.
Fails to convert hw/arm/armsse.c, because Coccinelle gets confused by
ARMSSE being used both as typedef and function-like macro there.
Convert manually.
Fails to convert hw/rx/rx-gdbsim.c, because Coccinelle gets confused
by RXCPU being used both as typedef and function-like macro there.
Convert manually. The other files using RXCPU that way don't need
conversion.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Message-Id: <20200707160613.848843-27-armbru@redhat.com>
[Straightforwad conflict with commit 2336172d9b "audio: set default
value for pcspk.iobase property" resolved]
2020-07-07 16:05:54 +00:00
|
|
|
object_property_set_bool(cpuobj, "has_el3", false, &error_fatal);
|
2014-12-15 23:09:51 +00:00
|
|
|
}
|
|
|
|
|
2014-03-17 16:31:46 +00:00
|
|
|
s->cpu[n] = ARM_CPU(cpuobj);
|
qom: Put name parameter before value / visitor parameter
The object_property_set_FOO() setters take property name and value in
an unusual order:
void object_property_set_FOO(Object *obj, FOO_TYPE value,
const char *name, Error **errp)
Having to pass value before name feels grating. Swap them.
Same for object_property_set(), object_property_get(), and
object_property_parse().
Convert callers with this Coccinelle script:
@@
identifier fun = {
object_property_get, object_property_parse, object_property_set_str,
object_property_set_link, object_property_set_bool,
object_property_set_int, object_property_set_uint, object_property_set,
object_property_set_qobject
};
expression obj, v, name, errp;
@@
- fun(obj, v, name, errp)
+ fun(obj, name, v, errp)
Chokes on hw/arm/musicpal.c's lcd_refresh() with the unhelpful error
message "no position information". Convert that one manually.
Fails to convert hw/arm/armsse.c, because Coccinelle gets confused by
ARMSSE being used both as typedef and function-like macro there.
Convert manually.
Fails to convert hw/rx/rx-gdbsim.c, because Coccinelle gets confused
by RXCPU being used both as typedef and function-like macro there.
Convert manually. The other files using RXCPU that way don't need
conversion.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Message-Id: <20200707160613.848843-27-armbru@redhat.com>
[Straightforwad conflict with commit 2336172d9b "audio: set default
value for pcspk.iobase property" resolved]
2020-07-07 16:05:54 +00:00
|
|
|
object_property_set_int(cpuobj, "mp-affinity",
|
|
|
|
exynos4210_calc_affinity(n), &error_abort);
|
|
|
|
object_property_set_int(cpuobj, "reset-cbar",
|
|
|
|
EXYNOS4210_SMP_PRIVATE_BASE_ADDR,
|
|
|
|
&error_abort);
|
qdev: Convert bus-less devices to qdev_realize() with Coccinelle
All remaining conversions to qdev_realize() are for bus-less devices.
Coccinelle script:
// only correct for bus-less @dev!
@@
expression errp;
expression dev;
@@
- qdev_init_nofail(dev);
+ qdev_realize(dev, NULL, &error_fatal);
@ depends on !(file in "hw/core/qdev.c") && !(file in "hw/core/bus.c")@
expression errp;
expression dev;
symbol true;
@@
- object_property_set_bool(OBJECT(dev), true, "realized", errp);
+ qdev_realize(DEVICE(dev), NULL, errp);
@ depends on !(file in "hw/core/qdev.c") && !(file in "hw/core/bus.c")@
expression errp;
expression dev;
symbol true;
@@
- object_property_set_bool(dev, true, "realized", errp);
+ qdev_realize(DEVICE(dev), NULL, errp);
Note that Coccinelle chokes on ARMSSE typedef vs. macro in
hw/arm/armsse.c. Worked around by temporarily renaming the macro for
the spatch run.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <20200610053247.1583243-57-armbru@redhat.com>
2020-06-10 05:32:45 +00:00
|
|
|
qdev_realize(DEVICE(cpuobj), NULL, &error_fatal);
|
2012-02-16 09:56:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* IRQ Gate */
|
2012-05-28 04:11:49 +00:00
|
|
|
for (i = 0; i < EXYNOS4210_NCPUS; i++) {
|
2022-04-04 15:46:41 +00:00
|
|
|
DeviceState *orgate = DEVICE(&s->cpu_irq_orgate[i]);
|
|
|
|
object_property_set_int(OBJECT(orgate), "num-lines",
|
|
|
|
EXYNOS4210_IRQ_GATE_NINPUTS,
|
|
|
|
&error_abort);
|
|
|
|
qdev_realize(orgate, NULL, &error_abort);
|
|
|
|
qdev_connect_gpio_out(orgate, 0,
|
|
|
|
qdev_get_gpio_in(DEVICE(s->cpu[i]), ARM_CPU_IRQ));
|
2012-02-16 09:56:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Private memory region and Internal GIC */
|
2022-04-04 15:46:43 +00:00
|
|
|
qdev_prop_set_uint32(DEVICE(&s->a9mpcore), "num-cpu", EXYNOS4210_NCPUS);
|
|
|
|
busdev = SYS_BUS_DEVICE(&s->a9mpcore);
|
|
|
|
sysbus_realize(busdev, &error_fatal);
|
2012-02-16 09:56:05 +00:00
|
|
|
sysbus_mmio_map(busdev, 0, EXYNOS4210_SMP_PRIVATE_BASE_ADDR);
|
|
|
|
for (n = 0; n < EXYNOS4210_NCPUS; n++) {
|
2022-04-04 15:46:41 +00:00
|
|
|
sysbus_connect_irq(busdev, n,
|
|
|
|
qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 0));
|
2012-02-16 09:56:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Cache controller */
|
|
|
|
sysbus_create_simple("l2x0", EXYNOS4210_L2X0_BASE_ADDR, NULL);
|
|
|
|
|
|
|
|
/* External GIC */
|
2022-04-04 15:46:48 +00:00
|
|
|
qdev_prop_set_uint32(DEVICE(&s->ext_gic), "num-cpu", EXYNOS4210_NCPUS);
|
|
|
|
busdev = SYS_BUS_DEVICE(&s->ext_gic);
|
|
|
|
sysbus_realize(busdev, &error_fatal);
|
2012-02-16 09:56:05 +00:00
|
|
|
/* Map CPU interface */
|
|
|
|
sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_GIC_CPU_BASE_ADDR);
|
|
|
|
/* Map Distributer interface */
|
|
|
|
sysbus_mmio_map(busdev, 1, EXYNOS4210_EXT_GIC_DIST_BASE_ADDR);
|
|
|
|
for (n = 0; n < EXYNOS4210_NCPUS; n++) {
|
2022-04-04 15:46:41 +00:00
|
|
|
sysbus_connect_irq(busdev, n,
|
|
|
|
qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 1));
|
2012-02-16 09:56:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Internal Interrupt Combiner */
|
2022-04-04 15:46:57 +00:00
|
|
|
busdev = SYS_BUS_DEVICE(&s->int_combiner);
|
|
|
|
sysbus_realize(busdev, &error_fatal);
|
2012-02-16 09:56:05 +00:00
|
|
|
for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
|
2022-04-04 15:46:44 +00:00
|
|
|
sysbus_connect_irq(busdev, n,
|
|
|
|
qdev_get_gpio_in(DEVICE(&s->a9mpcore), n));
|
2012-02-16 09:56:05 +00:00
|
|
|
}
|
|
|
|
sysbus_mmio_map(busdev, 0, EXYNOS4210_INT_COMBINER_BASE_ADDR);
|
|
|
|
|
|
|
|
/* External Interrupt Combiner */
|
2022-04-04 15:46:57 +00:00
|
|
|
qdev_prop_set_uint32(DEVICE(&s->ext_combiner), "external", 1);
|
|
|
|
busdev = SYS_BUS_DEVICE(&s->ext_combiner);
|
|
|
|
sysbus_realize(busdev, &error_fatal);
|
2012-02-16 09:56:05 +00:00
|
|
|
for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
|
2022-04-04 15:46:49 +00:00
|
|
|
sysbus_connect_irq(busdev, n, qdev_get_gpio_in(DEVICE(&s->ext_gic), n));
|
2012-02-16 09:56:05 +00:00
|
|
|
}
|
|
|
|
sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_COMBINER_BASE_ADDR);
|
|
|
|
|
|
|
|
/* Initialize board IRQs. */
|
2022-04-04 15:46:45 +00:00
|
|
|
exynos4210_init_board_irqs(s);
|
2012-02-16 09:56:05 +00:00
|
|
|
|
|
|
|
/*** Memory ***/
|
|
|
|
|
|
|
|
/* Chip-ID and OMR */
|
2020-02-24 17:32:23 +00:00
|
|
|
memory_region_init_io(&s->chipid_mem, OBJECT(socdev),
|
|
|
|
&exynos4210_chipid_and_omr_ops, NULL,
|
|
|
|
"exynos4210.chipid", sizeof(chipid_and_omr));
|
2012-02-16 09:56:05 +00:00
|
|
|
memory_region_add_subregion(system_mem, EXYNOS4210_CHIPID_ADDR,
|
|
|
|
&s->chipid_mem);
|
|
|
|
|
|
|
|
/* Internal ROM */
|
2020-02-24 17:32:23 +00:00
|
|
|
memory_region_init_rom(&s->irom_mem, OBJECT(socdev), "exynos4210.irom",
|
Fix bad error handling after memory_region_init_ram()
Symptom:
$ qemu-system-x86_64 -m 10000000
Unexpected error in ram_block_add() at /work/armbru/qemu/exec.c:1456:
upstream-qemu: cannot set up guest memory 'pc.ram': Cannot allocate memory
Aborted (core dumped)
Root cause: commit ef701d7 screwed up handling of out-of-memory
conditions. Before the commit, we report the error and exit(1), in
one place, ram_block_add(). The commit lifts the error handling up
the call chain some, to three places. Fine. Except it uses
&error_abort in these places, changing the behavior from exit(1) to
abort(), and thus undoing the work of commit 3922825 "exec: Don't
abort when we can't allocate guest memory".
The three places are:
* memory_region_init_ram()
Commit 4994653 (right after commit ef701d7) lifted the error
handling further, through memory_region_init_ram(), multiplying the
incorrect use of &error_abort. Later on, imitation of existing
(bad) code may have created more.
* memory_region_init_ram_ptr()
The &error_abort is still there.
* memory_region_init_rom_device()
Doesn't need fixing, because commit 33e0eb5 (soon after commit
ef701d7) lifted the error handling further, and in the process
changed it from &error_abort to passing it up the call chain.
Correct, because the callers are realize() methods.
Fix the error handling after memory_region_init_ram() with a
Coccinelle semantic patch:
@r@
expression mr, owner, name, size, err;
position p;
@@
memory_region_init_ram(mr, owner, name, size,
(
- &error_abort
+ &error_fatal
|
err@p
)
);
@script:python@
p << r.p;
@@
print "%s:%s:%s" % (p[0].file, p[0].line, p[0].column)
When the last argument is &error_abort, it gets replaced by
&error_fatal. This is the fix.
If the last argument is anything else, its position is reported. This
lets us check the fix is complete. Four positions get reported:
* ram_backend_memory_alloc()
Error is passed up the call chain, ultimately through
user_creatable_complete(). As far as I can tell, it's callers all
handle the error sanely.
* fsl_imx25_realize(), fsl_imx31_realize(), dp8393x_realize()
DeviceClass.realize() methods, errors handled sanely further up the
call chain.
We're good. Test case again behaves:
$ qemu-system-x86_64 -m 10000000
qemu-system-x86_64: cannot set up guest memory 'pc.ram': Cannot allocate memory
[Exit 1 ]
The next commits will repair the rest of commit ef701d7's damage.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <1441983105-26376-3-git-send-email-armbru@redhat.com>
Reviewed-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
2015-09-11 14:51:43 +00:00
|
|
|
EXYNOS4210_IROM_SIZE, &error_fatal);
|
2012-02-16 09:56:05 +00:00
|
|
|
memory_region_add_subregion(system_mem, EXYNOS4210_IROM_BASE_ADDR,
|
|
|
|
&s->irom_mem);
|
|
|
|
/* mirror of iROM */
|
2020-02-24 17:32:23 +00:00
|
|
|
memory_region_init_alias(&s->irom_alias_mem, OBJECT(socdev),
|
|
|
|
"exynos4210.irom_alias", &s->irom_mem, 0,
|
2012-02-16 09:56:05 +00:00
|
|
|
EXYNOS4210_IROM_SIZE);
|
|
|
|
memory_region_add_subregion(system_mem, EXYNOS4210_IROM_MIRROR_BASE_ADDR,
|
|
|
|
&s->irom_alias_mem);
|
|
|
|
|
|
|
|
/* Internal RAM */
|
2017-07-07 14:42:53 +00:00
|
|
|
memory_region_init_ram(&s->iram_mem, NULL, "exynos4210.iram",
|
Fix bad error handling after memory_region_init_ram()
Symptom:
$ qemu-system-x86_64 -m 10000000
Unexpected error in ram_block_add() at /work/armbru/qemu/exec.c:1456:
upstream-qemu: cannot set up guest memory 'pc.ram': Cannot allocate memory
Aborted (core dumped)
Root cause: commit ef701d7 screwed up handling of out-of-memory
conditions. Before the commit, we report the error and exit(1), in
one place, ram_block_add(). The commit lifts the error handling up
the call chain some, to three places. Fine. Except it uses
&error_abort in these places, changing the behavior from exit(1) to
abort(), and thus undoing the work of commit 3922825 "exec: Don't
abort when we can't allocate guest memory".
The three places are:
* memory_region_init_ram()
Commit 4994653 (right after commit ef701d7) lifted the error
handling further, through memory_region_init_ram(), multiplying the
incorrect use of &error_abort. Later on, imitation of existing
(bad) code may have created more.
* memory_region_init_ram_ptr()
The &error_abort is still there.
* memory_region_init_rom_device()
Doesn't need fixing, because commit 33e0eb5 (soon after commit
ef701d7) lifted the error handling further, and in the process
changed it from &error_abort to passing it up the call chain.
Correct, because the callers are realize() methods.
Fix the error handling after memory_region_init_ram() with a
Coccinelle semantic patch:
@r@
expression mr, owner, name, size, err;
position p;
@@
memory_region_init_ram(mr, owner, name, size,
(
- &error_abort
+ &error_fatal
|
err@p
)
);
@script:python@
p << r.p;
@@
print "%s:%s:%s" % (p[0].file, p[0].line, p[0].column)
When the last argument is &error_abort, it gets replaced by
&error_fatal. This is the fix.
If the last argument is anything else, its position is reported. This
lets us check the fix is complete. Four positions get reported:
* ram_backend_memory_alloc()
Error is passed up the call chain, ultimately through
user_creatable_complete(). As far as I can tell, it's callers all
handle the error sanely.
* fsl_imx25_realize(), fsl_imx31_realize(), dp8393x_realize()
DeviceClass.realize() methods, errors handled sanely further up the
call chain.
We're good. Test case again behaves:
$ qemu-system-x86_64 -m 10000000
qemu-system-x86_64: cannot set up guest memory 'pc.ram': Cannot allocate memory
[Exit 1 ]
The next commits will repair the rest of commit ef701d7's damage.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <1441983105-26376-3-git-send-email-armbru@redhat.com>
Reviewed-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
2015-09-11 14:51:43 +00:00
|
|
|
EXYNOS4210_IRAM_SIZE, &error_fatal);
|
2012-02-16 09:56:05 +00:00
|
|
|
memory_region_add_subregion(system_mem, EXYNOS4210_IRAM_BASE_ADDR,
|
|
|
|
&s->iram_mem);
|
|
|
|
|
2012-02-16 09:56:05 +00:00
|
|
|
/* PMU.
|
|
|
|
* The only reason of existence at the moment is that secondary CPU boot
|
|
|
|
* loader uses PMU INFORM5 register as a holding pen.
|
|
|
|
*/
|
|
|
|
sysbus_create_simple("exynos4210.pmu", EXYNOS4210_PMU_BASE_ADDR, NULL);
|
|
|
|
|
2017-02-28 12:08:20 +00:00
|
|
|
sysbus_create_simple("exynos4210.clk", EXYNOS4210_CLK_BASE_ADDR, NULL);
|
2017-07-11 10:21:26 +00:00
|
|
|
sysbus_create_simple("exynos4210.rng", EXYNOS4210_RNG_BASE_ADDR, NULL);
|
2017-02-28 12:08:20 +00:00
|
|
|
|
2012-02-16 09:56:05 +00:00
|
|
|
/* PWM */
|
|
|
|
sysbus_create_varargs("exynos4210.pwm", EXYNOS4210_PWM_BASE_ADDR,
|
|
|
|
s->irq_table[exynos4210_get_irq(22, 0)],
|
|
|
|
s->irq_table[exynos4210_get_irq(22, 1)],
|
|
|
|
s->irq_table[exynos4210_get_irq(22, 2)],
|
|
|
|
s->irq_table[exynos4210_get_irq(22, 3)],
|
|
|
|
s->irq_table[exynos4210_get_irq(22, 4)],
|
|
|
|
NULL);
|
2012-07-04 10:43:32 +00:00
|
|
|
/* RTC */
|
|
|
|
sysbus_create_varargs("exynos4210.rtc", EXYNOS4210_RTC_BASE_ADDR,
|
|
|
|
s->irq_table[exynos4210_get_irq(23, 0)],
|
|
|
|
s->irq_table[exynos4210_get_irq(23, 1)],
|
|
|
|
NULL);
|
2012-02-16 09:56:05 +00:00
|
|
|
|
2012-02-16 09:56:05 +00:00
|
|
|
/* Multi Core Timer */
|
qdev: Convert uses of qdev_create() with Coccinelle
This is the transformation explained in the commit before previous.
Takes care of just one pattern that needs conversion. More to come in
this series.
Coccinelle script:
@ depends on !(file in "hw/arm/highbank.c")@
expression bus, type_name, dev, expr;
@@
- dev = qdev_create(bus, type_name);
+ dev = qdev_new(type_name);
... when != dev = expr
- qdev_init_nofail(dev);
+ qdev_realize_and_unref(dev, bus, &error_fatal);
@@
expression bus, type_name, dev, expr;
identifier DOWN;
@@
- dev = DOWN(qdev_create(bus, type_name));
+ dev = DOWN(qdev_new(type_name));
... when != dev = expr
- qdev_init_nofail(DEVICE(dev));
+ qdev_realize_and_unref(DEVICE(dev), bus, &error_fatal);
@@
expression bus, type_name, expr;
identifier dev;
@@
- DeviceState *dev = qdev_create(bus, type_name);
+ DeviceState *dev = qdev_new(type_name);
... when != dev = expr
- qdev_init_nofail(dev);
+ qdev_realize_and_unref(dev, bus, &error_fatal);
@@
expression bus, type_name, dev, expr, errp;
symbol true;
@@
- dev = qdev_create(bus, type_name);
+ dev = qdev_new(type_name);
... when != dev = expr
- object_property_set_bool(OBJECT(dev), true, "realized", errp);
+ qdev_realize_and_unref(dev, bus, errp);
@@
expression bus, type_name, expr, errp;
identifier dev;
symbol true;
@@
- DeviceState *dev = qdev_create(bus, type_name);
+ DeviceState *dev = qdev_new(type_name);
... when != dev = expr
- object_property_set_bool(OBJECT(dev), true, "realized", errp);
+ qdev_realize_and_unref(dev, bus, errp);
The first rule exempts hw/arm/highbank.c, because it matches along two
control flow paths there, with different @type_name. Covered by the
next commit's manual conversions.
Missing #include "qapi/error.h" added manually.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <20200610053247.1583243-10-armbru@redhat.com>
[Conflicts in hw/misc/empty_slot.c and hw/sparc/leon3.c resolved]
2020-06-10 05:31:58 +00:00
|
|
|
dev = qdev_new("exynos4210.mct");
|
2013-01-20 01:47:33 +00:00
|
|
|
busdev = SYS_BUS_DEVICE(dev);
|
sysbus: Convert to sysbus_realize() etc. with Coccinelle
Convert from qdev_realize(), qdev_realize_and_unref() with null @bus
argument to sysbus_realize(), sysbus_realize_and_unref().
Coccinelle script:
@@
expression dev, errp;
@@
- qdev_realize(DEVICE(dev), NULL, errp);
+ sysbus_realize(SYS_BUS_DEVICE(dev), errp);
@@
expression sysbus_dev, dev, errp;
@@
+ sysbus_dev = SYS_BUS_DEVICE(dev);
- qdev_realize_and_unref(dev, NULL, errp);
+ sysbus_realize_and_unref(sysbus_dev, errp);
- sysbus_dev = SYS_BUS_DEVICE(dev);
@@
expression sysbus_dev, dev, errp;
expression expr;
@@
sysbus_dev = SYS_BUS_DEVICE(dev);
... when != dev = expr;
- qdev_realize_and_unref(dev, NULL, errp);
+ sysbus_realize_and_unref(sysbus_dev, errp);
@@
expression dev, errp;
@@
- qdev_realize_and_unref(DEVICE(dev), NULL, errp);
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), errp);
@@
expression dev, errp;
@@
- qdev_realize_and_unref(dev, NULL, errp);
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), errp);
Whitespace changes minimized manually.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <20200610053247.1583243-46-armbru@redhat.com>
[Conflicts in hw/misc/empty_slot.c and hw/sparc/leon3.c resolved]
2020-06-10 05:32:34 +00:00
|
|
|
sysbus_realize_and_unref(busdev, &error_fatal);
|
2012-02-16 09:56:05 +00:00
|
|
|
for (n = 0; n < 4; n++) {
|
|
|
|
/* Connect global timer interrupts to Combiner gpio_in */
|
|
|
|
sysbus_connect_irq(busdev, n,
|
|
|
|
s->irq_table[exynos4210_get_irq(1, 4 + n)]);
|
|
|
|
}
|
|
|
|
/* Connect local timer interrupts to Combiner gpio_in */
|
|
|
|
sysbus_connect_irq(busdev, 4,
|
|
|
|
s->irq_table[exynos4210_get_irq(51, 0)]);
|
|
|
|
sysbus_connect_irq(busdev, 5,
|
|
|
|
s->irq_table[exynos4210_get_irq(35, 3)]);
|
|
|
|
sysbus_mmio_map(busdev, 0, EXYNOS4210_MCT_BASE_ADDR);
|
|
|
|
|
2012-07-18 08:18:34 +00:00
|
|
|
/*** I2C ***/
|
|
|
|
for (n = 0; n < EXYNOS4210_I2C_NUMBER; n++) {
|
|
|
|
uint32_t addr = EXYNOS4210_I2C_BASE_ADDR + EXYNOS4210_I2C_SHIFT * n;
|
|
|
|
qemu_irq i2c_irq;
|
|
|
|
|
|
|
|
if (n < 8) {
|
|
|
|
i2c_irq = s->irq_table[exynos4210_get_irq(EXYNOS4210_I2C_INTG, n)];
|
|
|
|
} else {
|
|
|
|
i2c_irq = s->irq_table[exynos4210_get_irq(EXYNOS4210_HDMI_INTG, 1)];
|
|
|
|
}
|
|
|
|
|
qdev: Convert uses of qdev_create() with Coccinelle
This is the transformation explained in the commit before previous.
Takes care of just one pattern that needs conversion. More to come in
this series.
Coccinelle script:
@ depends on !(file in "hw/arm/highbank.c")@
expression bus, type_name, dev, expr;
@@
- dev = qdev_create(bus, type_name);
+ dev = qdev_new(type_name);
... when != dev = expr
- qdev_init_nofail(dev);
+ qdev_realize_and_unref(dev, bus, &error_fatal);
@@
expression bus, type_name, dev, expr;
identifier DOWN;
@@
- dev = DOWN(qdev_create(bus, type_name));
+ dev = DOWN(qdev_new(type_name));
... when != dev = expr
- qdev_init_nofail(DEVICE(dev));
+ qdev_realize_and_unref(DEVICE(dev), bus, &error_fatal);
@@
expression bus, type_name, expr;
identifier dev;
@@
- DeviceState *dev = qdev_create(bus, type_name);
+ DeviceState *dev = qdev_new(type_name);
... when != dev = expr
- qdev_init_nofail(dev);
+ qdev_realize_and_unref(dev, bus, &error_fatal);
@@
expression bus, type_name, dev, expr, errp;
symbol true;
@@
- dev = qdev_create(bus, type_name);
+ dev = qdev_new(type_name);
... when != dev = expr
- object_property_set_bool(OBJECT(dev), true, "realized", errp);
+ qdev_realize_and_unref(dev, bus, errp);
@@
expression bus, type_name, expr, errp;
identifier dev;
symbol true;
@@
- DeviceState *dev = qdev_create(bus, type_name);
+ DeviceState *dev = qdev_new(type_name);
... when != dev = expr
- object_property_set_bool(OBJECT(dev), true, "realized", errp);
+ qdev_realize_and_unref(dev, bus, errp);
The first rule exempts hw/arm/highbank.c, because it matches along two
control flow paths there, with different @type_name. Covered by the
next commit's manual conversions.
Missing #include "qapi/error.h" added manually.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <20200610053247.1583243-10-armbru@redhat.com>
[Conflicts in hw/misc/empty_slot.c and hw/sparc/leon3.c resolved]
2020-06-10 05:31:58 +00:00
|
|
|
dev = qdev_new("exynos4210.i2c");
|
2013-01-20 01:47:33 +00:00
|
|
|
busdev = SYS_BUS_DEVICE(dev);
|
sysbus: Convert to sysbus_realize() etc. with Coccinelle
Convert from qdev_realize(), qdev_realize_and_unref() with null @bus
argument to sysbus_realize(), sysbus_realize_and_unref().
Coccinelle script:
@@
expression dev, errp;
@@
- qdev_realize(DEVICE(dev), NULL, errp);
+ sysbus_realize(SYS_BUS_DEVICE(dev), errp);
@@
expression sysbus_dev, dev, errp;
@@
+ sysbus_dev = SYS_BUS_DEVICE(dev);
- qdev_realize_and_unref(dev, NULL, errp);
+ sysbus_realize_and_unref(sysbus_dev, errp);
- sysbus_dev = SYS_BUS_DEVICE(dev);
@@
expression sysbus_dev, dev, errp;
expression expr;
@@
sysbus_dev = SYS_BUS_DEVICE(dev);
... when != dev = expr;
- qdev_realize_and_unref(dev, NULL, errp);
+ sysbus_realize_and_unref(sysbus_dev, errp);
@@
expression dev, errp;
@@
- qdev_realize_and_unref(DEVICE(dev), NULL, errp);
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), errp);
@@
expression dev, errp;
@@
- qdev_realize_and_unref(dev, NULL, errp);
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), errp);
Whitespace changes minimized manually.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <20200610053247.1583243-46-armbru@redhat.com>
[Conflicts in hw/misc/empty_slot.c and hw/sparc/leon3.c resolved]
2020-06-10 05:32:34 +00:00
|
|
|
sysbus_realize_and_unref(busdev, &error_fatal);
|
2012-07-18 08:18:34 +00:00
|
|
|
sysbus_connect_irq(busdev, 0, i2c_irq);
|
|
|
|
sysbus_mmio_map(busdev, 0, addr);
|
2013-08-02 22:18:51 +00:00
|
|
|
s->i2c_if[n] = (I2CBus *)qdev_get_child_bus(dev, "i2c");
|
2012-07-18 08:18:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-02-16 09:56:05 +00:00
|
|
|
/*** UARTs ***/
|
2020-01-23 15:22:42 +00:00
|
|
|
uart[0] = exynos4210_uart_create(EXYNOS4210_UART0_BASE_ADDR,
|
2018-09-25 13:02:30 +00:00
|
|
|
EXYNOS4210_UART0_FIFO_SIZE, 0, serial_hd(0),
|
2012-02-16 09:56:05 +00:00
|
|
|
s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 0)]);
|
|
|
|
|
2020-01-23 15:22:42 +00:00
|
|
|
uart[1] = exynos4210_uart_create(EXYNOS4210_UART1_BASE_ADDR,
|
2018-09-25 13:02:30 +00:00
|
|
|
EXYNOS4210_UART1_FIFO_SIZE, 1, serial_hd(1),
|
2012-02-16 09:56:05 +00:00
|
|
|
s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 1)]);
|
|
|
|
|
2020-01-23 15:22:42 +00:00
|
|
|
uart[2] = exynos4210_uart_create(EXYNOS4210_UART2_BASE_ADDR,
|
2018-09-25 13:02:30 +00:00
|
|
|
EXYNOS4210_UART2_FIFO_SIZE, 2, serial_hd(2),
|
2012-02-16 09:56:05 +00:00
|
|
|
s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 2)]);
|
|
|
|
|
2020-01-23 15:22:42 +00:00
|
|
|
uart[3] = exynos4210_uart_create(EXYNOS4210_UART3_BASE_ADDR,
|
2018-09-25 13:02:30 +00:00
|
|
|
EXYNOS4210_UART3_FIFO_SIZE, 3, serial_hd(3),
|
2012-02-16 09:56:05 +00:00
|
|
|
s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 3)]);
|
|
|
|
|
hw/arm/exynos: Add generic SDHCI devices
Exynos4210 has four SD/MMC controllers supporting:
- SD Standard Host Specification Version 2.0,
- MMC Specification Version 4.3,
- SDIO Card Specification Version 2.0,
- DMA and ADMA.
Add emulation of SDHCI devices which allows accessing storage through SD
cards. Differences from real hardware:
- Devices are shipped with eMMC memory, not SD card.
- The Exynos4210 SDHCI has few more registers, e.g. for
controlling the clocks, additional status (0x80, 0x84, 0x8c). These
are not implemented.
Testing on smdkc210 machine with "-drive file=FILE,if=sd,bus=0,index=2".
Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
Message-id: 20170422190709.8676-1-krzk@kernel.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2017-04-22 19:07:09 +00:00
|
|
|
/*** SD/MMC host controllers ***/
|
|
|
|
for (n = 0; n < EXYNOS4210_SDHCI_NUMBER; n++) {
|
|
|
|
DeviceState *carddev;
|
|
|
|
BlockBackend *blk;
|
|
|
|
DriveInfo *di;
|
|
|
|
|
2018-02-08 16:48:03 +00:00
|
|
|
/* Compatible with:
|
|
|
|
* - SD Host Controller Specification Version 2.0
|
|
|
|
* - SDIO Specification Version 2.0
|
|
|
|
* - MMC Specification Version 4.3
|
|
|
|
* - SDMA
|
|
|
|
* - ADMA2
|
|
|
|
*
|
|
|
|
* As this part of the Exynos4210 is not publically available,
|
|
|
|
* we used the "HS-MMC Controller S3C2416X RISC Microprocessor"
|
|
|
|
* public datasheet which is very similar (implementing
|
|
|
|
* MMC Specification Version 4.0 being the only difference noted)
|
|
|
|
*/
|
qdev: Convert uses of qdev_create() with Coccinelle
This is the transformation explained in the commit before previous.
Takes care of just one pattern that needs conversion. More to come in
this series.
Coccinelle script:
@ depends on !(file in "hw/arm/highbank.c")@
expression bus, type_name, dev, expr;
@@
- dev = qdev_create(bus, type_name);
+ dev = qdev_new(type_name);
... when != dev = expr
- qdev_init_nofail(dev);
+ qdev_realize_and_unref(dev, bus, &error_fatal);
@@
expression bus, type_name, dev, expr;
identifier DOWN;
@@
- dev = DOWN(qdev_create(bus, type_name));
+ dev = DOWN(qdev_new(type_name));
... when != dev = expr
- qdev_init_nofail(DEVICE(dev));
+ qdev_realize_and_unref(DEVICE(dev), bus, &error_fatal);
@@
expression bus, type_name, expr;
identifier dev;
@@
- DeviceState *dev = qdev_create(bus, type_name);
+ DeviceState *dev = qdev_new(type_name);
... when != dev = expr
- qdev_init_nofail(dev);
+ qdev_realize_and_unref(dev, bus, &error_fatal);
@@
expression bus, type_name, dev, expr, errp;
symbol true;
@@
- dev = qdev_create(bus, type_name);
+ dev = qdev_new(type_name);
... when != dev = expr
- object_property_set_bool(OBJECT(dev), true, "realized", errp);
+ qdev_realize_and_unref(dev, bus, errp);
@@
expression bus, type_name, expr, errp;
identifier dev;
symbol true;
@@
- DeviceState *dev = qdev_create(bus, type_name);
+ DeviceState *dev = qdev_new(type_name);
... when != dev = expr
- object_property_set_bool(OBJECT(dev), true, "realized", errp);
+ qdev_realize_and_unref(dev, bus, errp);
The first rule exempts hw/arm/highbank.c, because it matches along two
control flow paths there, with different @type_name. Covered by the
next commit's manual conversions.
Missing #include "qapi/error.h" added manually.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <20200610053247.1583243-10-armbru@redhat.com>
[Conflicts in hw/misc/empty_slot.c and hw/sparc/leon3.c resolved]
2020-06-10 05:31:58 +00:00
|
|
|
dev = qdev_new(TYPE_S3C_SDHCI);
|
2018-02-08 16:48:02 +00:00
|
|
|
qdev_prop_set_uint64(dev, "capareg", EXYNOS4210_SDHCI_CAPABILITIES);
|
hw/arm/exynos: Add generic SDHCI devices
Exynos4210 has four SD/MMC controllers supporting:
- SD Standard Host Specification Version 2.0,
- MMC Specification Version 4.3,
- SDIO Card Specification Version 2.0,
- DMA and ADMA.
Add emulation of SDHCI devices which allows accessing storage through SD
cards. Differences from real hardware:
- Devices are shipped with eMMC memory, not SD card.
- The Exynos4210 SDHCI has few more registers, e.g. for
controlling the clocks, additional status (0x80, 0x84, 0x8c). These
are not implemented.
Testing on smdkc210 machine with "-drive file=FILE,if=sd,bus=0,index=2".
Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
Message-id: 20170422190709.8676-1-krzk@kernel.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2017-04-22 19:07:09 +00:00
|
|
|
|
|
|
|
busdev = SYS_BUS_DEVICE(dev);
|
sysbus: Convert to sysbus_realize() etc. with Coccinelle
Convert from qdev_realize(), qdev_realize_and_unref() with null @bus
argument to sysbus_realize(), sysbus_realize_and_unref().
Coccinelle script:
@@
expression dev, errp;
@@
- qdev_realize(DEVICE(dev), NULL, errp);
+ sysbus_realize(SYS_BUS_DEVICE(dev), errp);
@@
expression sysbus_dev, dev, errp;
@@
+ sysbus_dev = SYS_BUS_DEVICE(dev);
- qdev_realize_and_unref(dev, NULL, errp);
+ sysbus_realize_and_unref(sysbus_dev, errp);
- sysbus_dev = SYS_BUS_DEVICE(dev);
@@
expression sysbus_dev, dev, errp;
expression expr;
@@
sysbus_dev = SYS_BUS_DEVICE(dev);
... when != dev = expr;
- qdev_realize_and_unref(dev, NULL, errp);
+ sysbus_realize_and_unref(sysbus_dev, errp);
@@
expression dev, errp;
@@
- qdev_realize_and_unref(DEVICE(dev), NULL, errp);
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), errp);
@@
expression dev, errp;
@@
- qdev_realize_and_unref(dev, NULL, errp);
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), errp);
Whitespace changes minimized manually.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <20200610053247.1583243-46-armbru@redhat.com>
[Conflicts in hw/misc/empty_slot.c and hw/sparc/leon3.c resolved]
2020-06-10 05:32:34 +00:00
|
|
|
sysbus_realize_and_unref(busdev, &error_fatal);
|
hw/arm/exynos: Add generic SDHCI devices
Exynos4210 has four SD/MMC controllers supporting:
- SD Standard Host Specification Version 2.0,
- MMC Specification Version 4.3,
- SDIO Card Specification Version 2.0,
- DMA and ADMA.
Add emulation of SDHCI devices which allows accessing storage through SD
cards. Differences from real hardware:
- Devices are shipped with eMMC memory, not SD card.
- The Exynos4210 SDHCI has few more registers, e.g. for
controlling the clocks, additional status (0x80, 0x84, 0x8c). These
are not implemented.
Testing on smdkc210 machine with "-drive file=FILE,if=sd,bus=0,index=2".
Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
Message-id: 20170422190709.8676-1-krzk@kernel.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2017-04-22 19:07:09 +00:00
|
|
|
sysbus_mmio_map(busdev, 0, EXYNOS4210_SDHCI_ADDR(n));
|
|
|
|
sysbus_connect_irq(busdev, 0, s->irq_table[exynos4210_get_irq(29, n)]);
|
|
|
|
|
|
|
|
di = drive_get(IF_SD, 0, n);
|
|
|
|
blk = di ? blk_by_legacy_dinfo(di) : NULL;
|
qdev: Convert uses of qdev_create() with Coccinelle
This is the transformation explained in the commit before previous.
Takes care of just one pattern that needs conversion. More to come in
this series.
Coccinelle script:
@ depends on !(file in "hw/arm/highbank.c")@
expression bus, type_name, dev, expr;
@@
- dev = qdev_create(bus, type_name);
+ dev = qdev_new(type_name);
... when != dev = expr
- qdev_init_nofail(dev);
+ qdev_realize_and_unref(dev, bus, &error_fatal);
@@
expression bus, type_name, dev, expr;
identifier DOWN;
@@
- dev = DOWN(qdev_create(bus, type_name));
+ dev = DOWN(qdev_new(type_name));
... when != dev = expr
- qdev_init_nofail(DEVICE(dev));
+ qdev_realize_and_unref(DEVICE(dev), bus, &error_fatal);
@@
expression bus, type_name, expr;
identifier dev;
@@
- DeviceState *dev = qdev_create(bus, type_name);
+ DeviceState *dev = qdev_new(type_name);
... when != dev = expr
- qdev_init_nofail(dev);
+ qdev_realize_and_unref(dev, bus, &error_fatal);
@@
expression bus, type_name, dev, expr, errp;
symbol true;
@@
- dev = qdev_create(bus, type_name);
+ dev = qdev_new(type_name);
... when != dev = expr
- object_property_set_bool(OBJECT(dev), true, "realized", errp);
+ qdev_realize_and_unref(dev, bus, errp);
@@
expression bus, type_name, expr, errp;
identifier dev;
symbol true;
@@
- DeviceState *dev = qdev_create(bus, type_name);
+ DeviceState *dev = qdev_new(type_name);
... when != dev = expr
- object_property_set_bool(OBJECT(dev), true, "realized", errp);
+ qdev_realize_and_unref(dev, bus, errp);
The first rule exempts hw/arm/highbank.c, because it matches along two
control flow paths there, with different @type_name. Covered by the
next commit's manual conversions.
Missing #include "qapi/error.h" added manually.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <20200610053247.1583243-10-armbru@redhat.com>
[Conflicts in hw/misc/empty_slot.c and hw/sparc/leon3.c resolved]
2020-06-10 05:31:58 +00:00
|
|
|
carddev = qdev_new(TYPE_SD_CARD);
|
qdev: Make qdev_prop_set_drive() match the other helpers
qdev_prop_set_drive() can fail. None of the other qdev_prop_set_FOO()
can; they abort on error.
To clean up this inconsistency, rename qdev_prop_set_drive() to
qdev_prop_set_drive_err(), and create a qdev_prop_set_drive() that
aborts on error.
Coccinelle script to update callers:
@ depends on !(file in "hw/core/qdev-properties-system.c")@
expression dev, name, value;
symbol error_abort;
@@
- qdev_prop_set_drive(dev, name, value, &error_abort);
+ qdev_prop_set_drive(dev, name, value);
@@
expression dev, name, value, errp;
@@
- qdev_prop_set_drive(dev, name, value, errp);
+ qdev_prop_set_drive_err(dev, name, value, errp);
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-Id: <20200622094227.1271650-14-armbru@redhat.com>
2020-06-22 09:42:24 +00:00
|
|
|
qdev_prop_set_drive(carddev, "drive", blk);
|
qdev: Convert uses of qdev_create() with Coccinelle
This is the transformation explained in the commit before previous.
Takes care of just one pattern that needs conversion. More to come in
this series.
Coccinelle script:
@ depends on !(file in "hw/arm/highbank.c")@
expression bus, type_name, dev, expr;
@@
- dev = qdev_create(bus, type_name);
+ dev = qdev_new(type_name);
... when != dev = expr
- qdev_init_nofail(dev);
+ qdev_realize_and_unref(dev, bus, &error_fatal);
@@
expression bus, type_name, dev, expr;
identifier DOWN;
@@
- dev = DOWN(qdev_create(bus, type_name));
+ dev = DOWN(qdev_new(type_name));
... when != dev = expr
- qdev_init_nofail(DEVICE(dev));
+ qdev_realize_and_unref(DEVICE(dev), bus, &error_fatal);
@@
expression bus, type_name, expr;
identifier dev;
@@
- DeviceState *dev = qdev_create(bus, type_name);
+ DeviceState *dev = qdev_new(type_name);
... when != dev = expr
- qdev_init_nofail(dev);
+ qdev_realize_and_unref(dev, bus, &error_fatal);
@@
expression bus, type_name, dev, expr, errp;
symbol true;
@@
- dev = qdev_create(bus, type_name);
+ dev = qdev_new(type_name);
... when != dev = expr
- object_property_set_bool(OBJECT(dev), true, "realized", errp);
+ qdev_realize_and_unref(dev, bus, errp);
@@
expression bus, type_name, expr, errp;
identifier dev;
symbol true;
@@
- DeviceState *dev = qdev_create(bus, type_name);
+ DeviceState *dev = qdev_new(type_name);
... when != dev = expr
- object_property_set_bool(OBJECT(dev), true, "realized", errp);
+ qdev_realize_and_unref(dev, bus, errp);
The first rule exempts hw/arm/highbank.c, because it matches along two
control flow paths there, with different @type_name. Covered by the
next commit's manual conversions.
Missing #include "qapi/error.h" added manually.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <20200610053247.1583243-10-armbru@redhat.com>
[Conflicts in hw/misc/empty_slot.c and hw/sparc/leon3.c resolved]
2020-06-10 05:31:58 +00:00
|
|
|
qdev_realize_and_unref(carddev, qdev_get_child_bus(dev, "sd-bus"),
|
|
|
|
&error_fatal);
|
hw/arm/exynos: Add generic SDHCI devices
Exynos4210 has four SD/MMC controllers supporting:
- SD Standard Host Specification Version 2.0,
- MMC Specification Version 4.3,
- SDIO Card Specification Version 2.0,
- DMA and ADMA.
Add emulation of SDHCI devices which allows accessing storage through SD
cards. Differences from real hardware:
- Devices are shipped with eMMC memory, not SD card.
- The Exynos4210 SDHCI has few more registers, e.g. for
controlling the clocks, additional status (0x80, 0x84, 0x8c). These
are not implemented.
Testing on smdkc210 machine with "-drive file=FILE,if=sd,bus=0,index=2".
Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
Message-id: 20170422190709.8676-1-krzk@kernel.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2017-04-22 19:07:09 +00:00
|
|
|
}
|
|
|
|
|
2012-02-16 09:56:06 +00:00
|
|
|
/*** Display controller (FIMD) ***/
|
|
|
|
sysbus_create_varargs("exynos4210.fimd", EXYNOS4210_FIMD0_BASE_ADDR,
|
|
|
|
s->irq_table[exynos4210_get_irq(11, 0)],
|
|
|
|
s->irq_table[exynos4210_get_irq(11, 1)],
|
|
|
|
s->irq_table[exynos4210_get_irq(11, 2)],
|
|
|
|
NULL);
|
|
|
|
|
2012-12-16 03:49:46 +00:00
|
|
|
sysbus_create_simple(TYPE_EXYNOS4210_EHCI, EXYNOS4210_EHCI_BASE_ADDR,
|
|
|
|
s->irq_table[exynos4210_get_irq(28, 3)]);
|
|
|
|
|
hw/arm/exynos4210: Add DMA support for the Exynos4210
QEMU already supports pl330. Instantiate it for Exynos4210.
Relevant part of Linux arch/arm/boot/dts/exynos4.dtsi:
/ {
soc: soc {
amba {
pdma0: pdma@12680000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x12680000 0x1000>;
interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_PDMA0>;
clock-names = "apb_pclk";
#dma-cells = <1>;
#dma-channels = <8>;
#dma-requests = <32>;
};
pdma1: pdma@12690000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x12690000 0x1000>;
interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_PDMA1>;
clock-names = "apb_pclk";
#dma-cells = <1>;
#dma-channels = <8>;
#dma-requests = <32>;
};
mdma1: mdma@12850000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x12850000 0x1000>;
interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_MDMA>;
clock-names = "apb_pclk";
#dma-cells = <1>;
#dma-channels = <8>;
#dma-requests = <1>;
};
};
};
};
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-id: 20190520214342.13709-4-philmd@redhat.com
[PMD: Do not set default qdev properties, create the controllers in the SoC
rather than the board (Peter Maydell), add dtsi in commit message]
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2019-05-23 13:47:44 +00:00
|
|
|
/*** DMA controllers ***/
|
2020-01-23 15:22:42 +00:00
|
|
|
pl330[0] = pl330_create(EXYNOS4210_PL330_BASE0_ADDR,
|
|
|
|
&s->pl330_irq_orgate[0],
|
|
|
|
s->irq_table[exynos4210_get_irq(21, 0)],
|
|
|
|
32, 32, 32);
|
|
|
|
pl330[1] = pl330_create(EXYNOS4210_PL330_BASE1_ADDR,
|
|
|
|
&s->pl330_irq_orgate[1],
|
|
|
|
s->irq_table[exynos4210_get_irq(21, 1)],
|
|
|
|
32, 32, 32);
|
|
|
|
pl330[2] = pl330_create(EXYNOS4210_PL330_BASE2_ADDR,
|
|
|
|
&s->pl330_irq_orgate[2],
|
|
|
|
s->irq_table[exynos4210_get_irq(20, 1)],
|
|
|
|
1, 31, 64);
|
|
|
|
|
|
|
|
sysbus_connect_irq(SYS_BUS_DEVICE(uart[0]), 1,
|
|
|
|
qdev_get_gpio_in(pl330[0], 15));
|
|
|
|
sysbus_connect_irq(SYS_BUS_DEVICE(uart[1]), 1,
|
|
|
|
qdev_get_gpio_in(pl330[1], 15));
|
|
|
|
sysbus_connect_irq(SYS_BUS_DEVICE(uart[2]), 1,
|
|
|
|
qdev_get_gpio_in(pl330[0], 17));
|
|
|
|
sysbus_connect_irq(SYS_BUS_DEVICE(uart[3]), 1,
|
|
|
|
qdev_get_gpio_in(pl330[1], 17));
|
2020-01-23 15:22:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void exynos4210_init(Object *obj)
|
|
|
|
{
|
|
|
|
Exynos4210State *s = EXYNOS4210_SOC(obj);
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < ARRAY_SIZE(s->pl330_irq_orgate); i++) {
|
|
|
|
char *name = g_strdup_printf("pl330-irq-orgate%d", i);
|
|
|
|
qemu_or_irq *orgate = &s->pl330_irq_orgate[i];
|
|
|
|
|
qom: Less verbose object_initialize_child()
All users of object_initialize_child() pass the obvious child size
argument. Almost all pass &error_abort and no properties. Tiresome.
Rename object_initialize_child() to
object_initialize_child_with_props() to free the name. New
convenience wrapper object_initialize_child() automates the size
argument, and passes &error_abort and no properties.
Rename object_initialize_childv() to
object_initialize_child_with_propsv() for consistency.
Convert callers with this Coccinelle script:
@@
expression parent, propname, type;
expression child, size;
symbol error_abort;
@@
- object_initialize_child(parent, propname, OBJECT(child), size, type, &error_abort, NULL)
+ object_initialize_child(parent, propname, child, size, type, &error_abort, NULL)
@@
expression parent, propname, type;
expression child;
symbol error_abort;
@@
- object_initialize_child(parent, propname, child, sizeof(*child), type, &error_abort, NULL)
+ object_initialize_child(parent, propname, child, type)
@@
expression parent, propname, type;
expression child;
symbol error_abort;
@@
- object_initialize_child(parent, propname, &child, sizeof(child), type, &error_abort, NULL)
+ object_initialize_child(parent, propname, &child, type)
@@
expression parent, propname, type;
expression child, size, err;
expression list props;
@@
- object_initialize_child(parent, propname, child, size, type, err, props)
+ object_initialize_child_with_props(parent, propname, child, size, type, err, props)
Note that Coccinelle chokes on ARMSSE typedef vs. macro in
hw/arm/armsse.c. Worked around by temporarily renaming the macro for
the spatch run.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
[Rebased: machine opentitan is new (commit fe0fe4735e7)]
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <20200610053247.1583243-37-armbru@redhat.com>
2020-06-10 05:32:25 +00:00
|
|
|
object_initialize_child(obj, name, orgate, TYPE_OR_IRQ);
|
2020-01-23 15:22:41 +00:00
|
|
|
g_free(name);
|
|
|
|
}
|
2022-04-04 15:46:41 +00:00
|
|
|
|
|
|
|
for (i = 0; i < ARRAY_SIZE(s->cpu_irq_orgate); i++) {
|
|
|
|
g_autofree char *name = g_strdup_printf("cpu-irq-orgate%d", i);
|
|
|
|
object_initialize_child(obj, name, &s->cpu_irq_orgate[i], TYPE_OR_IRQ);
|
|
|
|
}
|
2022-04-04 15:46:43 +00:00
|
|
|
|
2022-04-04 15:46:52 +00:00
|
|
|
for (i = 0; i < ARRAY_SIZE(s->splitter); i++) {
|
|
|
|
g_autofree char *name = g_strdup_printf("irq-splitter%d", i);
|
|
|
|
object_initialize_child(obj, name, &s->splitter[i], TYPE_SPLIT_IRQ);
|
|
|
|
}
|
|
|
|
|
2022-04-04 15:46:43 +00:00
|
|
|
object_initialize_child(obj, "a9mpcore", &s->a9mpcore, TYPE_A9MPCORE_PRIV);
|
2022-04-04 15:46:48 +00:00
|
|
|
object_initialize_child(obj, "ext-gic", &s->ext_gic, TYPE_EXYNOS4210_GIC);
|
2022-04-04 15:46:57 +00:00
|
|
|
object_initialize_child(obj, "int-combiner", &s->int_combiner,
|
|
|
|
TYPE_EXYNOS4210_COMBINER);
|
|
|
|
object_initialize_child(obj, "ext-combiner", &s->ext_combiner,
|
|
|
|
TYPE_EXYNOS4210_COMBINER);
|
2019-05-23 13:47:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void exynos4210_class_init(ObjectClass *klass, void *data)
|
|
|
|
{
|
|
|
|
DeviceClass *dc = DEVICE_CLASS(klass);
|
hw/arm/exynos4210: Add DMA support for the Exynos4210
QEMU already supports pl330. Instantiate it for Exynos4210.
Relevant part of Linux arch/arm/boot/dts/exynos4.dtsi:
/ {
soc: soc {
amba {
pdma0: pdma@12680000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x12680000 0x1000>;
interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_PDMA0>;
clock-names = "apb_pclk";
#dma-cells = <1>;
#dma-channels = <8>;
#dma-requests = <32>;
};
pdma1: pdma@12690000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x12690000 0x1000>;
interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_PDMA1>;
clock-names = "apb_pclk";
#dma-cells = <1>;
#dma-channels = <8>;
#dma-requests = <32>;
};
mdma1: mdma@12850000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x12850000 0x1000>;
interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clock CLK_MDMA>;
clock-names = "apb_pclk";
#dma-cells = <1>;
#dma-channels = <8>;
#dma-requests = <1>;
};
};
};
};
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-id: 20190520214342.13709-4-philmd@redhat.com
[PMD: Do not set default qdev properties, create the controllers in the SoC
rather than the board (Peter Maydell), add dtsi in commit message]
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2019-05-23 13:47:44 +00:00
|
|
|
|
2019-05-23 13:47:44 +00:00
|
|
|
dc->realize = exynos4210_realize;
|
2012-02-16 09:56:05 +00:00
|
|
|
}
|
2019-05-23 13:47:44 +00:00
|
|
|
|
|
|
|
static const TypeInfo exynos4210_info = {
|
|
|
|
.name = TYPE_EXYNOS4210_SOC,
|
|
|
|
.parent = TYPE_SYS_BUS_DEVICE,
|
|
|
|
.instance_size = sizeof(Exynos4210State),
|
2020-01-23 15:22:41 +00:00
|
|
|
.instance_init = exynos4210_init,
|
2019-05-23 13:47:44 +00:00
|
|
|
.class_init = exynos4210_class_init,
|
|
|
|
};
|
|
|
|
|
|
|
|
static void exynos4210_register_types(void)
|
|
|
|
{
|
|
|
|
type_register_static(&exynos4210_info);
|
|
|
|
}
|
|
|
|
|
|
|
|
type_init(exynos4210_register_types)
|