enable HiP04 SoC
Subsystems (17)
v4 cover enable HiP04 SoC
Changelog:
v4:
* Add multi_v7_lpae_defconfig.
* Select CONFIG_ARCH_MULTI_V7_LPAE if CONFIG_ARCH_MULTI_V7 is selected.
* Only ARMADA_XP is ARCH_MULTI_V7_LPAE, other ARMADA chips are ARCH_MULTI_V7.
* Remove gich_lr0 variable since we can calculate offset of GICH_LR0 from GICH_APR.
* Cleanup GIC driver to support HiP04 GIC.
* Cleanup HiP04 mcpm implementation.
v3:
* Replace CONFIG_ARCH_MULTI_V7 by CONFIG_ARCH_MULTI_V7_LPAE in some SoC.
* Update MCPM code based on Dave's patch.
* Remove MCPM node in DTS file. Use sysctrl & fabric node instead.
* Move hardcoding on bootwrapper into DTS file.
* Append the CONFIG_MCPM_QUAD_CLUSTER for HiP04.
* Fix the return value from gic_get_cpumask() if it's used in standard gic.
* Add the vgic support on HiP04 GIC.
* Add virtualization support in HiP04 defconfig.
v2:
* Append ARCH_MULTI_V7_LPAE configuration. Define ARCH_MULTI_V7 to only support non-LPAE platform.
* Append document of DT supporting.
* Append ARCH_HISI in hi3xxx_defconfig.
* Enable errata 798181 for HiP04 SoC.
* Add PMU support.
Haojian Zhuang (12):
ARM: debug: add HiP04 debug uart
ARM: append ARCH_MULTI_V7_LPAE
ARM: config: append lpae configuration
irq: gic: use mask field in GICC_IAR
irq: gic: support hip04 gic
ARM: mcpm: support 4 clusters
ARM: hisi: add ARCH_HISI
ARM: hisi: add hip04 SoC support
ARM: dts: add hip04-d01 dts file
ARM: config: append hip04_defconfig
ARM: config: select ARCH_HISI in hi3xxx_defconfig
virt: arm: support hip04 gic
Kefeng Wang (2):
ARM: hisi: enable erratum 798181 of A15 on HiP04
ARM: dts: Add PMU support in HiP04
Documentation/devicetree/bindings/arm/gic.txt | 1 + .../bindings/arm/hisilicon/hisilicon.txt | 10 + .../devicetree/bindings/clock/hip04-clock.txt | 20 ++ arch/arm/Kconfig | 18 +- arch/arm/Kconfig.debug | 10 + arch/arm/Makefile | 2 +- arch/arm/boot/dts/Makefile | 1 + arch/arm/boot/dts/hip04-d01.dts | 74 +++++ arch/arm/boot/dts/hip04.dtsi | 259 +++++++++++++++ arch/arm/configs/hi3xxx_defconfig | 2 + arch/arm/configs/hip04_defconfig | 74 +++++ arch/arm/configs/multi_v7_lpae_defconfig | 348 +++++++++++++++++++++ arch/arm/include/asm/mcpm.h | 5 + arch/arm/kvm/interrupts_head.S | 24 +- arch/arm/mach-berlin/Kconfig | 2 +- arch/arm/mach-highbank/Kconfig | 2 +- arch/arm/mach-hisi/Kconfig | 27 +- arch/arm/mach-hisi/Makefile | 1 + arch/arm/mach-hisi/core.h | 2 + arch/arm/mach-hisi/hisilicon.c | 12 + arch/arm/mach-hisi/platmcpm.c | 318 +++++++++++++++++++ arch/arm/mach-mvebu/Kconfig | 4 +- arch/arm/mach-omap2/Kconfig | 4 +- arch/arm/mach-qcom/Kconfig | 2 +- arch/arm/mach-shmobile/Kconfig | 2 +- arch/arm/mach-tegra/Kconfig | 2 +- arch/arm/mach-vexpress/Kconfig | 2 +- drivers/irqchip/irq-gic.c | 157 ++++++++-- include/linux/irqchip/arm-gic.h | 5 + virt/kvm/arm/vgic.c | 15 +- 30 files changed, 1350 insertions(+), 55 deletions(-) create mode 100644 Documentation/devicetree/bindings/clock/hip04-clock.txt create mode 100644 arch/arm/boot/dts/hip04-d01.dts create mode 100644 arch/arm/boot/dts/hip04.dtsi create mode 100644 arch/arm/configs/hip04_defconfig create mode 100644 arch/arm/configs/multi_v7_lpae_defconfig create mode 100644 arch/arm/mach-hisi/platmcpm.c
Signature · 1 line
1.9.1
PATCH v4 1/14 ARM: debug: add HiP04 debug uart
Add the support of Hisilicon HiP04 debug uart.
--- arch/arm/Kconfig.debug | 10 ++++++++++ 1 file changed, 10 insertions(+)
arch/arm/Kconfig.debug +10 -0
@@ -223,6 +223,14 @@ choice Say Y here if you want kernel low-level debugging support on HI3716 UART. + config DEBUG_HIP04_UART + bool "Hisilicon HiP04 Debug UART" + depends on ARCH_HIP04 + select DEBUG_UART_8250 + help + Say Y here if you want kernel low-level debugging support + on HIP04 UART. + config DEBUG_HIGHBANK_UART bool "Kernel low-level debugging messages via Highbank UART" depends on ARCH_HIGHBANK
@@ -1044,6 +1052,7 @@ config DEBUG_UART_PHYS default 0xd4017000 if DEBUG_MMP_UART2 default 0xd4018000 if DEBUG_MMP_UART3 default 0xe0000000 if ARCH_SPEAR13XX + default 0xe4007000 if DEBUG_HIP04_UART default 0xf0000be0 if ARCH_EBSA110 default 0xf1012000 if DEBUG_MVEBU_UART_ALTERNATE default 0xf1012000 if ARCH_DOVE || ARCH_KIRKWOOD || ARCH_MV78XX0 || \
@@ -1076,6 +1085,7 @@ config DEBUG_UART_VIRT default 0xf4090000 if ARCH_LPC32XX default 0xf4200000 if ARCH_GEMINI default 0xf7fc9000 if DEBUG_BERLIN_UART + default 0xf8007000 if DEBUG_HIP04_UART default 0xf8009000 if DEBUG_VEXPRESS_UART0_CA9 default 0xf8090000 if DEBUG_VEXPRESS_UART0_RS1 default 0xfb009000 if DEBUG_REALVIEW_STD_PORT
Signature · 1 line
1.9.1
PATCH v4 2/14 ARM: append ARCH_MULTI_V7_LPAE
In reply to Haojian ZhuangAdd new ARCH_MULTI_V7_LPAE config. It will select ARM_LPAE only both ARCH_MULTI_V6 & ARCH_MULTI_V7 is disabled.
ARCH_MULTI_V7 means non-LPAE platform.
--- arch/arm/Kconfig | 10 +++++++++- arch/arm/mach-berlin/Kconfig | 2 +- arch/arm/mach-highbank/Kconfig | 2 +- arch/arm/mach-mvebu/Kconfig | 4 ++-- arch/arm/mach-omap2/Kconfig | 4 ++-- arch/arm/mach-qcom/Kconfig | 2 +- arch/arm/mach-shmobile/Kconfig | 2 +- arch/arm/mach-tegra/Kconfig | 2 +- arch/arm/mach-vexpress/Kconfig | 2 +- 9 files changed, 19 insertions(+), 11 deletions(-)
arch/arm/Kconfig +9 -1
@@ -918,12 +918,20 @@ config ARCH_MULTI_V6 select CPU_V6K config ARCH_MULTI_V7 - bool "ARMv7 based platforms (Cortex-A, PJ4, Scorpion, Krait)" + bool "ARMv7 non-LPAE based platforms (Cortex-A5/A8/A9, PJ4, PJ4B, Scorpion)" default y select ARCH_MULTI_V6_V7 + select ARCH_MULTI_V7_LPAE select CPU_V7 select HAVE_SMP +config ARCH_MULTI_V7_LPAE + bool "ARMv7 LPAE based platforms (Cortex-A7/A12/A15/A17, Brahma-B15, PJ4B-MP, Krait)" + select ARCH_MULTI_V6_V7 + select CPU_V7 + select HAVE_SMP + select ARM_LPAE if !(ARCH_MULTI_V6 || ARCH_MULTI_V7) + config ARCH_MULTI_V6_V7 bool select MIGHT_HAVE_CACHE_L2X0
arch/arm/mach-berlin/Kconfig +1 -1
@@ -1,5 +1,5 @@ config ARCH_BERLIN - bool "Marvell Berlin SoCs" if ARCH_MULTI_V7 + bool "Marvell Berlin SoCs" if (ARCH_MULTI_V7 || ARCH_MULTI_V7_LPAE) select ARM_GIC select GENERIC_IRQ_CHIP select DW_APB_ICTL
arch/arm/mach-highbank/Kconfig +1 -1
@@ -1,5 +1,5 @@ config ARCH_HIGHBANK - bool "Calxeda ECX-1000/2000 (Highbank/Midway)" if ARCH_MULTI_V7 + bool "Calxeda ECX-1000/2000 (Highbank/Midway)" if ARCH_MULTI_V7_LPAE select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE select ARCH_HAS_CPUFREQ select ARCH_HAS_HOLES_MEMORYMODEL
arch/arm/mach-mvebu/Kconfig +2 -2
@@ -1,5 +1,5 @@ config ARCH_MVEBU - bool "Marvell Engineering Business Unit (MVEBU) SoCs" if (ARCH_MULTI_V7 || ARCH_MULTI_V5) + bool "Marvell Engineering Business Unit (MVEBU) SoCs" if (ARCH_MULTI_V7 || ARCH_MULTI_V7_LPAE || ARCH_MULTI_V5) select ARCH_SUPPORTS_BIG_ENDIAN select CLKSRC_MMIO select GENERIC_IRQ_CHIP
@@ -59,7 +59,7 @@ config MACH_ARMADA_38X on the Marvell Armada 380/385 SoC with device tree. config MACH_ARMADA_XP - bool "Marvell Armada XP boards" if ARCH_MULTI_V7 + bool "Marvell Armada XP boards" if ARCH_MULTI_V7_LPAE select ARMADA_XP_CLK select CPU_PJ4B select MACH_MVEBU_V7
arch/arm/mach-omap2/Kconfig +2 -2
@@ -41,7 +41,7 @@ config ARCH_OMAP4 config SOC_OMAP5 bool "TI OMAP5" - depends on ARCH_MULTI_V7 + depends on ARCH_MULTI_V7_LPAE select ARCH_OMAP2PLUS select ARCH_HAS_OPP select ARM_CPU_SUSPEND if PM
@@ -68,7 +68,7 @@ config SOC_AM43XX config SOC_DRA7XX bool "TI DRA7XX" - depends on ARCH_MULTI_V7 + depends on ARCH_MULTI_V7_LPAE select ARCH_OMAP2PLUS select ARCH_HAS_OPP select ARM_CPU_SUSPEND if PM
arch/arm/mach-qcom/Kconfig +1 -1
@@ -1,5 +1,5 @@ config ARCH_QCOM - bool "Qualcomm Support" if ARCH_MULTI_V7 + bool "Qualcomm Support" if (ARCH_MULTI_V7 || ARCH_MULTI_V7_LPAE) select ARCH_REQUIRE_GPIOLIB select ARM_GIC select CLKSRC_OF
arch/arm/mach-shmobile/Kconfig +1 -1
@@ -2,7 +2,7 @@ config ARCH_SHMOBILE bool config ARCH_SHMOBILE_MULTI - bool "Renesas ARM SoCs" if ARCH_MULTI_V7 + bool "Renesas ARM SoCs" if (ARCH_MULTI_V7 || ARCH_MULTI_V7_LPAE) depends on MMU select ARCH_SHMOBILE select HAVE_ARM_SCU if SMP
arch/arm/mach-tegra/Kconfig +1 -1
@@ -1,5 +1,5 @@ config ARCH_TEGRA - bool "NVIDIA Tegra" if ARCH_MULTI_V7 + bool "NVIDIA Tegra" if (ARCH_MULTI_V7 || ARCH_MULTI_V7_LPAE) select ARCH_HAS_CPUFREQ select ARCH_REQUIRE_GPIOLIB select ARCH_SUPPORTS_TRUSTED_FOUNDATIONS
arch/arm/mach-vexpress/Kconfig +1 -1
@@ -1,5 +1,5 @@ config ARCH_VEXPRESS - bool "ARM Ltd. Versatile Express family" if ARCH_MULTI_V7 + bool "ARM Ltd. Versatile Express family" if (ARCH_MULTI_V7 || ARCH_MULTI_V7_LPAE) select ARCH_REQUIRE_GPIOLIB select ARCH_SUPPORTS_BIG_ENDIAN select ARM_AMBA
Signature · 1 line
1.9.1
PATCH v4 2/14 ARM: append ARCH_MULTI_V7_LPAE
Quoted 23 lines · Haojian Zhuang
Add new
ARCH_MULTI_V7_LPAEconfig. It will selectARM_LPAEonly bothARCH_MULTI_V6&ARCH_MULTI_V7is disabled.
ARCH_MULTI_V7means non-LPAE platform.Signed-off-by Haojian Zhuang <[email protected]>--- arch/arm/Kconfig | 10 +++++++++- arch/arm/mach-berlin/Kconfig | 2 +- arch/arm/mach-highbank/Kconfig | 2 +- arch/arm/mach-mvebu/Kconfig | 4 ++-- arch/arm/mach-omap2/Kconfig | 4 ++-- arch/arm/mach-qcom/Kconfig | 2 +- arch/arm/mach-shmobile/Kconfig | 2 +- arch/arm/mach-tegra/Kconfig | 2 +- arch/arm/mach-vexpress/Kconfig | 2 +- 9 files changed, 19 insertions(+), 11 deletions(-)arch/arm/Kconfig +0
-0
arch/arm/Kconfig config ARCH_MULTI_V6 · line 924
Quoted 8 lines
arch/arm/Kconfig +2
-1@@ -918,12 +918,20 @@ config ARCH_MULTI_V6 select CPU_V6K config ARCH_MULTI_V7 - bool "ARMv7 based platforms (Cortex-A, PJ4, Scorpion, Krait)" + bool "ARMv7 non-LPAE based platforms (Cortex-A5/A8/A9, PJ4, PJ4B, Scorpion)" default y select ARCH_MULTI_V6_V7 + select ARCH_MULTI_V7_LPAE
This doesn't seem right.
arch/arm/Kconfig config ARCH_MULTI_V6 · line 933
Quoted 9 lines
arch/arm/Kconfig +6
-0select CPU_V7 select HAVE_SMP +config ARCH_MULTI_V7_LPAE + bool "ARMv7 LPAE based platforms (Cortex-A7/A12/A15/A17, Brahma-B15, PJ4B-MP, Krait)" + select ARCH_MULTI_V6_V7 + select CPU_V7 + select HAVE_SMP + select ARM_LPAE if !(ARCH_MULTI_V6 || ARCH_MULTI_V7)
This logic doesn't really seem right either.
Most of the rest of the changes can be avoided if you rename ARCH_MULTI_V7 to ARCH_MULTI_V7_NONLPAE and then add:
config ARCH_MULTI_V7
def_bool y if (ARCH_MULTI_V7_NONLPAE || ARCH_MULTI_V7_LPAE)
Quoted 20 lines
arch/arm/Kconfig +1
-0+ config ARCH_MULTI_V6_V7 bool select MIGHT_HAVE_CACHE_L2X0arch/arm/mach-berlin/Kconfig +1
-1@@ -1,5 +1,5 @@ config ARCH_BERLIN - bool "Marvell Berlin SoCs" if ARCH_MULTI_V7 + bool "Marvell Berlin SoCs" if (ARCH_MULTI_V7 || ARCH_MULTI_V7_LPAE) select ARM_GIC select GENERIC_IRQ_CHIP select DW_APB_ICTLarch/arm/mach-highbank/Kconfig +0
-0
arch/arm/mach-highbank/Kconfig line 2
Quoted 3 lines
arch/arm/mach-highbank/Kconfig +1
-1@@ -1,5 +1,5 @@ config ARCH_HIGHBANK - bool "Calxeda ECX-1000/2000 (Highbank/Midway)" if ARCH_MULTI_V7 + bool "Calxeda ECX-1000/2000 (Highbank/Midway)" if ARCH_MULTI_V7_LPAE
Highbank is not LPAE. Midway is LPAE (and can run non-LPAE kernels).
Quoted 28 lines
arch/arm/mach-highbank/Kconfig +0
-0select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE select ARCH_HAS_CPUFREQ select ARCH_HAS_HOLES_MEMORYMODELarch/arm/mach-mvebu/Kconfig +2
-2@@ -1,5 +1,5 @@ config ARCH_MVEBU - bool "Marvell Engineering Business Unit (MVEBU) SoCs" if (ARCH_MULTI_V7 || ARCH_MULTI_V5) + bool "Marvell Engineering Business Unit (MVEBU) SoCs" if (ARCH_MULTI_V7 || ARCH_MULTI_V7_LPAE || ARCH_MULTI_V5) select ARCH_SUPPORTS_BIG_ENDIAN select CLKSRC_MMIO select GENERIC_IRQ_CHIP@@ -59,7 +59,7 @@ config MACH_ARMADA_38X on the Marvell Armada 380/385 SoC with device tree. config MACH_ARMADA_XP - bool "Marvell Armada XP boards" if ARCH_MULTI_V7 + bool "Marvell Armada XP boards" if ARCH_MULTI_V7_LPAE select ARMADA_XP_CLK select CPU_PJ4B select MACH_MVEBU_V7arch/arm/mach-omap2/Kconfig +0
-0
arch/arm/mach-omap2/Kconfig config ARCH_OMAP4 · line 44
Quoted 5 lines
arch/arm/mach-omap2/Kconfig +1
-1@@ -41,7 +41,7 @@ config ARCH_OMAP4 config SOC_OMAP5 bool "TI OMAP5" - depends on ARCH_MULTI_V7 + depends on ARCH_MULTI_V7_LPAE
Can't OMAP5 run a non-LPAE enabled kernel?
Rob
PATCH v4 3/14 ARM: config: append lpae configuration
In reply to Haojian ZhuangAppend multi_v7_lpae_config. In this configuration, ARCH_MULTI_V7 & ARCH_MULTI_V6 won't be selected.
LPAE configuration will be selected by default.
--- arch/arm/configs/multi_v7_lpae_defconfig | 348 +++++++++++++++++++++++++++++++ 1 file changed, 348 insertions(+) create mode 100644 arch/arm/configs/multi_v7_lpae_defconfig
arch/arm/configs/multi_v7_lpae_defconfig new file +348 -0
@@ -0,0 +1,348 @@ +CONFIG_SYSVIPC=y +CONFIG_FHANDLE=y +CONFIG_IRQ_DOMAIN_DEBUG=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_EMBEDDED=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ARCH_MULTI_V6 is not set +# CONFIG_ARCH_MULTI_V7 is not set +CONFIG_ARCH_MULTI_V7_LPAE=y +CONFIG_ARCH_MVEBU=y +CONFIG_MACH_ARMADA_370=y +CONFIG_MACH_ARMADA_375=y +CONFIG_MACH_ARMADA_38X=y +CONFIG_MACH_ARMADA_XP=y +CONFIG_MACH_DOVE=y +CONFIG_ARCH_BCM=y +CONFIG_ARCH_BCM_5301X=y +CONFIG_ARCH_BCM_MOBILE=y +CONFIG_ARCH_BERLIN=y +CONFIG_MACH_BERLIN_BG2=y +CONFIG_MACH_BERLIN_BG2CD=y +CONFIG_GPIO_PCA953X=y +CONFIG_ARCH_HIGHBANK=y +CONFIG_ARCH_HI3xxx=y +CONFIG_ARCH_KEYSTONE=y +CONFIG_ARCH_MXC=y +CONFIG_MACH_IMX51_DT=y +CONFIG_SOC_IMX53=y +CONFIG_SOC_IMX6Q=y +CONFIG_SOC_IMX6SL=y +CONFIG_SOC_VF610=y +CONFIG_ARCH_OMAP3=y +CONFIG_ARCH_OMAP4=y +CONFIG_SOC_OMAP5=y +CONFIG_SOC_AM33XX=y +CONFIG_SOC_DRA7XX=y +CONFIG_SOC_AM43XX=y +CONFIG_ARCH_QCOM=y +CONFIG_ARCH_MSM8X60=y +CONFIG_ARCH_MSM8960=y +CONFIG_ARCH_MSM8974=y +CONFIG_ARCH_ROCKCHIP=y +CONFIG_ARCH_SOCFPGA=y +CONFIG_PLAT_SPEAR=y +CONFIG_ARCH_SPEAR13XX=y +CONFIG_MACH_SPEAR1310=y +CONFIG_MACH_SPEAR1340=y +CONFIG_ARCH_STI=y +CONFIG_ARCH_SUNXI=y +CONFIG_ARCH_SIRF=y +CONFIG_ARCH_TEGRA=y +CONFIG_ARCH_TEGRA_2x_SOC=y +CONFIG_ARCH_TEGRA_3x_SOC=y +CONFIG_ARCH_TEGRA_114_SOC=y +CONFIG_ARCH_TEGRA_124_SOC=y +CONFIG_TEGRA_EMC_SCALING_ENABLE=y +CONFIG_ARCH_U8500=y +CONFIG_MACH_HREFV60=y +CONFIG_MACH_SNOWBALL=y +CONFIG_MACH_UX500_DT=y +CONFIG_ARCH_VEXPRESS=y +CONFIG_ARCH_VEXPRESS_CA9X4=y +CONFIG_ARCH_VIRT=y +CONFIG_ARCH_WM8850=y +CONFIG_ARCH_ZYNQ=y +CONFIG_NEON=y +CONFIG_TRUSTED_FOUNDATIONS=y +CONFIG_PCI=y +CONFIG_PCI_MSI=y +CONFIG_PCI_MVEBU=y +CONFIG_PCI_TEGRA=y +CONFIG_SMP=y +CONFIG_HIGHPTE=y +CONFIG_CMA=y +CONFIG_ARM_APPENDED_DTB=y +CONFIG_ARM_ATAG_DTB_COMPAT=y +CONFIG_KEXEC=y +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_STAT_DETAILS=y +CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y +CONFIG_CPU_IDLE=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +CONFIG_IPV6_ROUTER_PREF=y +CONFIG_IPV6_OPTIMISTIC_DAD=y +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_IPV6_MIP6=m +CONFIG_IPV6_TUNNEL=m +CONFIG_IPV6_MULTIPLE_TABLES=y +CONFIG_CFG80211=m +CONFIG_MAC80211=m +CONFIG_RFKILL=y +CONFIG_RFKILL_INPUT=y +CONFIG_RFKILL_GPIO=y +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_DMA_CMA=y +CONFIG_CMA_SIZE_MBYTES=64 +CONFIG_OMAP_OCP2SCP=y +CONFIG_MTD=y +CONFIG_MTD_M25P80=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_ICS932S401=y +CONFIG_APDS9802ALS=y +CONFIG_ISL29003=y +CONFIG_BLK_DEV_SD=y +CONFIG_BLK_DEV_SR=y +CONFIG_SCSI_MULTI_LUN=y +CONFIG_ATA=y +CONFIG_SATA_AHCI_PLATFORM=y +CONFIG_SATA_HIGHBANK=y +CONFIG_SATA_MV=y +CONFIG_NETDEVICES=y +CONFIG_SUN4I_EMAC=y +CONFIG_NET_CALXEDA_XGMAC=y +CONFIG_MV643XX_ETH=y +CONFIG_MVNETA=y +CONFIG_KS8851=y +CONFIG_R8169=y +CONFIG_SMSC911X=y +CONFIG_STMMAC_ETH=y +CONFIG_TI_CPSW=y +CONFIG_AT803X_PHY=y +CONFIG_MARVELL_PHY=y +CONFIG_ICPLUS_PHY=y +CONFIG_USB_PEGASUS=y +CONFIG_USB_USBNET=y +CONFIG_USB_NET_SMSC75XX=y +CONFIG_USB_NET_SMSC95XX=y +CONFIG_BRCMFMAC=m +CONFIG_RT2X00=m +CONFIG_RT2800USB=m +CONFIG_INPUT_EVDEV=y +CONFIG_KEYBOARD_GPIO=y +CONFIG_KEYBOARD_TEGRA=y +CONFIG_KEYBOARD_SPEAR=y +CONFIG_KEYBOARD_CROS_EC=y +CONFIG_MOUSE_PS2_ELANTECH=y +CONFIG_INPUT_MISC=y +CONFIG_INPUT_MPU3050=y +CONFIG_SERIO_AMBAKMI=y +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_DW=y +CONFIG_SERIAL_AMBA_PL011=y +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y +CONFIG_SERIAL_SIRFSOC=y +CONFIG_SERIAL_SIRFSOC_CONSOLE=y +CONFIG_SERIAL_TEGRA=y +CONFIG_SERIAL_IMX=y +CONFIG_SERIAL_IMX_CONSOLE=y +CONFIG_SERIAL_MSM=y +CONFIG_SERIAL_MSM_CONSOLE=y +CONFIG_SERIAL_VT8500=y +CONFIG_SERIAL_VT8500_CONSOLE=y +CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_SERIAL_OMAP=y +CONFIG_SERIAL_OMAP_CONSOLE=y +CONFIG_SERIAL_XILINX_PS_UART=y +CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y +CONFIG_SERIAL_FSL_LPUART=y +CONFIG_SERIAL_FSL_LPUART_CONSOLE=y +CONFIG_SERIAL_ST_ASC=y +CONFIG_SERIAL_ST_ASC_CONSOLE=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_MUX=y +CONFIG_I2C_MUX_PCA954x=y +CONFIG_I2C_MUX_PINCTRL=y +CONFIG_I2C_DESIGNWARE_PLATFORM=y +CONFIG_I2C_MV64XXX=y +CONFIG_I2C_SIRF=y +CONFIG_I2C_TEGRA=y +CONFIG_SPI=y +CONFIG_SPI_OMAP24XX=y +CONFIG_SPI_ORION=y +CONFIG_SPI_PL022=y +CONFIG_SPI_SIRF=y +CONFIG_SPI_TEGRA114=y +CONFIG_SPI_TEGRA20_SFLASH=y +CONFIG_SPI_TEGRA20_SLINK=y +CONFIG_PINCTRL_AS3722=y +CONFIG_PINCTRL_PALMAS=y +CONFIG_GPIO_SYSFS=y +CONFIG_GPIO_GENERIC_PLATFORM=y +CONFIG_GPIO_PCA953X_IRQ=y +CONFIG_GPIO_TWL4030=y +CONFIG_GPIO_PALMAS=y +CONFIG_GPIO_TPS6586X=y +CONFIG_GPIO_TPS65910=y +CONFIG_BATTERY_SBS=y +CONFIG_CHARGER_TPS65090=y +CONFIG_POWER_RESET_AS3722=y +CONFIG_POWER_RESET_GPIO=y +CONFIG_SENSORS_LM90=y +CONFIG_THERMAL=y +CONFIG_DOVE_THERMAL=y +CONFIG_ARMADA_THERMAL=y +CONFIG_WATCHDOG=y +CONFIG_ORION_WATCHDOG=y +CONFIG_MFD_AS3722=y +CONFIG_MFD_CROS_EC=y +CONFIG_MFD_CROS_EC_SPI=y +CONFIG_MFD_MAX8907=y +CONFIG_MFD_PALMAS=y +CONFIG_MFD_TPS65090=y +CONFIG_MFD_TPS6586X=y +CONFIG_MFD_TPS65910=y +CONFIG_REGULATOR_VIRTUAL_CONSUMER=y +CONFIG_REGULATOR_AB8500=y +CONFIG_REGULATOR_AS3722=y +CONFIG_REGULATOR_GPIO=y +CONFIG_REGULATOR_MAX8907=y +CONFIG_REGULATOR_PALMAS=y +CONFIG_REGULATOR_TPS51632=y +CONFIG_REGULATOR_TPS62360=y +CONFIG_REGULATOR_TPS65090=y +CONFIG_REGULATOR_TPS6586X=y +CONFIG_REGULATOR_TPS65910=y +CONFIG_REGULATOR_TWL4030=y +CONFIG_REGULATOR_VEXPRESS=y +CONFIG_MEDIA_SUPPORT=y +CONFIG_MEDIA_CAMERA_SUPPORT=y +CONFIG_MEDIA_USB_SUPPORT=y +CONFIG_USB_VIDEO_CLASS=y +CONFIG_USB_GSPCA=y +CONFIG_DRM=y +CONFIG_DRM_TEGRA=y +CONFIG_DRM_PANEL_SIMPLE=y +CONFIG_FB_ARMCLCD=y +CONFIG_FB_WM8505=y +CONFIG_FB_SIMPLE=y +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_PWM=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_SOUND=y +CONFIG_SND=y +CONFIG_SND_SOC=y +CONFIG_SND_SOC_TEGRA=y +CONFIG_SND_SOC_TEGRA_RT5640=y +CONFIG_SND_SOC_TEGRA_WM8753=y +CONFIG_SND_SOC_TEGRA_WM8903=y +CONFIG_SND_SOC_TEGRA_TRIMSLICE=y +CONFIG_SND_SOC_TEGRA_ALC5632=y +CONFIG_SND_SOC_TEGRA_MAX98090=y +CONFIG_USB=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_TEGRA=y +CONFIG_USB_EHCI_HCD_PLATFORM=y +CONFIG_USB_ISP1760_HCD=y +CONFIG_USB_STORAGE=y +CONFIG_USB_CHIPIDEA=y +CONFIG_USB_CHIPIDEA_HOST=y +CONFIG_AB8500_USB=y +CONFIG_OMAP_USB3=y +CONFIG_SAMSUNG_USB2PHY=y +CONFIG_SAMSUNG_USB3PHY=y +CONFIG_USB_GPIO_VBUS=y +CONFIG_USB_ISP1301=y +CONFIG_USB_MXS_PHY=y +CONFIG_MMC=y +CONFIG_MMC_BLOCK_MINORS=16 +CONFIG_MMC_ARMMMCI=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_ESDHC_IMX=y +CONFIG_MMC_SDHCI_TEGRA=y +CONFIG_MMC_SDHCI_DOVE=y +CONFIG_MMC_SDHCI_SPEAR=y +CONFIG_MMC_SDHCI_BCM_KONA=y +CONFIG_MMC_OMAP=y +CONFIG_MMC_OMAP_HS=y +CONFIG_MMC_MVSDIO=y +CONFIG_EDAC=y +CONFIG_EDAC_MM_EDAC=y +CONFIG_EDAC_HIGHBANK_MC=y +CONFIG_EDAC_HIGHBANK_L2=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_AS3722=y +CONFIG_RTC_DRV_MAX8907=y +CONFIG_RTC_DRV_PALMAS=y +CONFIG_RTC_DRV_TWL4030=y +CONFIG_RTC_DRV_TPS6586X=y +CONFIG_RTC_DRV_TPS65910=y +CONFIG_RTC_DRV_EM3027=y +CONFIG_RTC_DRV_PL031=y +CONFIG_RTC_DRV_VT8500=y +CONFIG_RTC_DRV_MV=y +CONFIG_RTC_DRV_TEGRA=y +CONFIG_DMADEVICES=y +CONFIG_DW_DMAC=y +CONFIG_MV_XOR=y +CONFIG_TEGRA20_APB_DMA=y +CONFIG_STE_DMA40=y +CONFIG_SIRF_DMA=y +CONFIG_TI_EDMA=y +CONFIG_PL330_DMA=y +CONFIG_IMX_SDMA=y +CONFIG_IMX_DMA=y +CONFIG_MXS_DMA=y +CONFIG_DMA_OMAP=y +CONFIG_STAGING=y +CONFIG_SENSORS_ISL29018=y +CONFIG_SENSORS_ISL29028=y +CONFIG_MFD_NVEC=y +CONFIG_KEYBOARD_NVEC=y +CONFIG_SERIO_NVEC_PS2=y +CONFIG_NVEC_POWER=y +CONFIG_COMMON_CLK_QCOM=y +CONFIG_MSM_GCC_8660=y +CONFIG_MSM_MMCC_8960=y +CONFIG_MSM_MMCC_8974=y +CONFIG_TEGRA_IOMMU_GART=y +CONFIG_TEGRA_IOMMU_SMMU=y +CONFIG_MEMORY=y +CONFIG_IIO=y +CONFIG_AK8975=y +CONFIG_PWM=y +CONFIG_PWM_TEGRA=y +CONFIG_PWM_VT8500=y +CONFIG_OMAP_USB2=y +CONFIG_EXT4_FS=y +CONFIG_VFAT_FS=y +CONFIG_TMPFS=y +CONFIG_SQUASHFS=y +CONFIG_SQUASHFS_LZO=y +CONFIG_SQUASHFS_XZ=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_ROOT_NFS=y +CONFIG_PRINTK_TIME=y +CONFIG_DEBUG_FS=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_LOCKUP_DETECTOR=y +CONFIG_CRYPTO_DEV_TEGRA_AES=y
Signature · 1 line
1.9.1
PATCH v4 4/14 irq: gic: use mask field in GICC_IAR
In reply to Haojian ZhuangBit[9:0] is interrupt ID field in GICC_IAR. Bit[12:10] is CPU ID field, and others are reserved.
So we should use GICC_IAR_INTID to get interrupt ID. It's not a good way to use ~0x1c00 (CPU ID field) to get interrupt ID.
--- drivers/irqchip/irq-gic.c | 2 +- include/linux/irqchip/arm-gic.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-)
drivers/irqchip/irq-gic.c +1 -1
@@ -287,7 +287,7 @@ static void __exception_irq_entry gic_handle_irq(struct pt_regs *regs) do { irqstat = readl_relaxed(cpu_base + GIC_CPU_INTACK); - irqnr = irqstat & ~0x1c00; + irqnr = irqstat & GICC_IAR_INTID; if (likely(irqnr > 15 && irqnr < 1021)) { irqnr = irq_find_mapping(gic->domain, irqnr);
include/linux/irqchip/arm-gic.h +2 -0
@@ -21,6 +21,8 @@#define GIC_CPU_ACTIVEPRIO 0xd0#define GIC_CPU_IDENT 0xfc +#define GICC_IAR_INTID 0x3ff +#define GIC_DIST_CTRL 0x000#define GIC_DIST_CTR 0x004#define GIC_DIST_IGROUP 0x080
Signature · 1 line
1.9.1
PATCH v4 4/14 irq: gic: use mask field in GICC_IAR
Quoted 30 lines · Haojian Zhuang
Bit[9:0] is interrupt ID field in
GICC_IAR. Bit[12:10] is CPU ID field, and others are reserved.So we should use
GICC_IAR_INTIDto get interrupt ID. It's not a good way to use ~0x1c00 (CPU ID field) to get interrupt ID.Signed-off-by Haojian Zhuang <[email protected]>--- drivers/irqchip/irq-gic.c | 2 +- include/linux/irqchip/arm-gic.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-)drivers/irqchip/irq-gic.c +1
-1@@ -287,7 +287,7 @@ static void __exception_irq_entry gic_handle_irq(struct pt_regs *regs) do { irqstat = readl_relaxed(cpu_base + GIC_CPU_INTACK); - irqnr = irqstat & ~0x1c00; + irqnr = irqstat & GICC_IAR_INTID; if (likely(irqnr > 15 && irqnr < 1021)) { irqnr = irq_find_mapping(gic->domain, irqnr);include/linux/irqchip/arm-gic.h +0
-0
include/linux/irqchip/arm-gic.h line 24
Quoted 4 lines
include/linux/irqchip/arm-gic.h +1
-0@@ -21,6 +21,8 @@#define GIC_CPU_ACTIVEPRIO 0xd0#define GIC_CPU_IDENT 0xfc +#define GICC_IAR_INTID 0x3ff
This is actually a mask, so I'd suggest to reflect this in the name. GICC_IAR_INT_ID_MASK?
include/linux/irqchip/arm-gic.h line 28
Quoted 4 lines
include/linux/irqchip/arm-gic.h +1
-0+#define GIC_DIST_CTRL 0x000#define GIC_DIST_CTR 0x004#define GIC_DIST_IGROUP 0x080
M.
Signature · 1 line
Jazz is not dead. It just smells funny.
PATCH v4 5/14 irq: gic: support hip04 gic
In reply to Haojian ZhuangThere's a little difference between ARM GIC and HiP04 GIC.
* HiP04 GIC could support 16 cores at most, and ARM GIC could support 8 cores at most. So the difination on GIC_DIST_SGIR, GIC_DIST_SGI_PENDING_SET, GIC_DIST_SGI_PENDING_CLEAR
& GIC_DIST_TARGET registers are different since CPU interfaces are increased from 8-bit to 16-bit.
* HiP04 GIC could support 510 interrupts at most, and ARM GIC could support 1020 interrupts at most.
--- drivers/irqchip/irq-gic.c | 155 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 122 insertions(+), 33 deletions(-)
drivers/irqchip/irq-gic.c +122 -33
@@ -68,6 +68,7 @@ struct gic_chip_data {#ifdef CONFIG_GIC_NON_BANKED void __iomem *(*get_base)(union gic_base *);#endif +u32 nr_cpu_if; };static DEFINE_RAW_SPINLOCK (irq_controller_lock);
@@ -76,9 +77,11 @@ static DEFINE_RAW_SPINLOCK(irq_controller_lock);* The GIC mapping of CPU interfaces does not necessarily match * the logical CPU numbering. Let's use a mapping as returned * by the GIC itself. +* +* Hisilicon HiP04 extends the number of CPU interface from 8 to 16. */ -#define NR_GIC_CPU_IF 8 -static u8 gic_cpu_map[NR_GIC_CPU_IF ]__read_mostly ; +#define NR_GIC_CPU_IF 16 +static u16 gic_cpu_map[NR_GIC_CPU_IF ]__read_mostly ;/* * Supported arch specific GIC irq extension.
@@ -242,19 +245,55 @@ static int gic_retrigger(struct irq_data *d) }#ifdef CONFIG_SMP +static inline u32 irq_to_core_offset (struct irq_data *d) +{ +struct gic_chip_data *gic_data =irq_data_get_irq_chip_data (d); +unsigned int i =gic_irq (d); + +/* ARM GIC */ +if (gic_data->nr_cpu_if ==8 ) +return ((i >>2 ) <<2 ); +/* HiP04 GIC (nr_cpu_if == 16) */ +return ((i >>1 ) <<2 ); +} + +static inline u32 irq_to_core_shift (struct irq_data *d) +{ +struct gic_chip_data *gic_data =irq_data_get_irq_chip_data (d); +unsigned int i =gic_irq (d); + +/* ARM GIC */ +if (gic_data->nr_cpu_if ==8 ) +return ((i %4 ) <<3 ); +/* HiP04 GIC (nr_cpu_if == 16) */ +return ((i %2 ) <<4 ); +} + +static inline u32 irq_to_core_mask (struct irq_data *d) +{ +struct gic_chip_data *gic_data =irq_data_get_irq_chip_data (d); +u32 mask; +/* ARM GIC, nr_cpu_if == 8; HiP04 GIC, nr_cpu_if == 16 */ + mask = (1 << gic_data->nr_cpu_if) -1 ; +return (mask <<irq_to_core_shift (d)); +} +static int gic_set_affinity (struct irq_data *d,const struct cpumask *mask_val,bool force) { -void __iomem *reg =gic_dist_base (d) +GIC_DIST_TARGET + (gic_irq (d) & ~3 ); -unsigned int shift = (gic_irq (d) %4 ) *8 ; +void __iomem *reg; +struct gic_chip_data *gic_data =irq_data_get_irq_chip_data (d); +unsigned int shift =irq_to_core_shift (d);unsigned int cpu =cpumask_any_and (mask_val, cpu_online_mask);u32 val, mask, bit; -if (cpu >=NR_GIC_CPU_IF || cpu >= nr_cpu_ids) +if (cpu >= gic_data->nr_cpu_if || cpu >= nr_cpu_ids)return -EINVAL ; + reg =gic_dist_base (d) +GIC_DIST_TARGET +irq_to_core_offset (d); +raw_spin_lock (&irq_controller_lock); - mask =0xff << shift; + mask =irq_to_core_mask (d); bit = gic_cpu_map[cpu] << shift; val =readl_relaxed (reg) & ~mask;writel_relaxed (val | bit, reg);
@@ -354,15 +393,24 @@ void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq)irq_set_chained_handler (irq, gic_handle_cascade_irq); } -static u8 gic_get_cpumask (struct gic_chip_data *gic) +static u16 gic_get_cpumask (struct gic_chip_data *gic) {void __iomem *base =gic_data_dist_base (gic);u32 mask, i; -for (i = mask =0 ; i <32 ; i +=4 ) { - mask =readl_relaxed (base +GIC_DIST_TARGET + i); - mask |= mask >>16 ; - mask |= mask >>8 ; +/* +* ARM GIC uses 8 registers for interrupt 0-31, +* HiP04 GIC uses 16 registers for interrupt 0-31. +*/ +for (i = mask =0 ; i <32 ; i +=32 / gic->nr_cpu_if) { +if (gic->nr_cpu_if ==8 ) {/* ARM GIC */ + mask =readl_relaxed (base +GIC_DIST_TARGET + i); + mask |= mask >>16 ; + mask |= mask >>8 ; + }else {/* HiP04 GIC */ + mask =readl_relaxed (base +GIC_DIST_TARGET + i *2 ); + mask |= mask >>16 ; + }if (mask)break ; }
@@ -370,6 +418,10 @@ static u8 gic_get_cpumask(struct gic_chip_data *gic)if (!mask)pr_crit ("GIC CPU mask not found - kernel will fail to boot.\n" ); +/* ARM GIC needs 8-bit cpu mask, HiP04 GIC needs 16-bit cpu mask. */ +if (gic->nr_cpu_if ==8 ) + mask &=0xff ; +return mask; }
@@ -392,10 +444,20 @@ static void __init gic_dist_init(struct gic_chip_data *gic)* Set all global interrupts to this CPU only. */ cpumask =gic_get_cpumask (gic); - cpumask |= cpumask <<8 ; - cpumask |= cpumask <<16 ; -for (i =32 ; i < gic_irqs; i +=4 ) -writel_relaxed (cpumask, base +GIC_DIST_TARGET + i *4 /4 ); +if (gic->nr_cpu_if ==8 ) {/* ARM GIC */ + cpumask |= cpumask <<8 ; + cpumask |= cpumask <<16 ; + }else {/* HiP04 GIC */ + cpumask |= cpumask <<16 ; + } +for (i =32 ; i < gic_irqs; i +=32 / gic->nr_cpu_if) { +if (gic->nr_cpu_if ==8 ) +writel_relaxed (cpumask, + base +GIC_DIST_TARGET + i /4 *4 ); +else +writel_relaxed (cpumask, + base +GIC_DIST_TARGET + i /2 *4 ); + }/* * Set priority on all global interrupts.
@@ -423,7 +485,7 @@ static void gic_cpu_init(struct gic_chip_data *gic)/* * Get what the GIC says our CPU mask is. */ -BUG_ON (cpu >=NR_GIC_CPU_IF ); +BUG_ON (cpu >= gic->nr_cpu_if); cpu_mask =gic_get_cpumask (gic); gic_cpu_map[cpu] = cpu_mask;
@@ -431,7 +493,7 @@ static void gic_cpu_init(struct gic_chip_data *gic)* Clear our mask from the other map entries in case they're * still undefined. */ -for (i =0 ; i <NR_GIC_CPU_IF ; i++) +for (i =0 ; i < gic->nr_cpu_if; i++)if (i != cpu) gic_cpu_map[i] &= ~cpu_mask;
@@ -467,7 +529,7 @@ void gic_cpu_if_down(void)*/ static void gic_dist_save (unsigned int gic_nr) { -unsigned int gic_irqs; +unsigned int gic_irqs, nr_if =32 / gic_data[gic_nr].nr_cpu_if;void __iomem *dist_base;int i;
@@ -484,7 +546,7 @@ static void gic_dist_save(unsigned int gic_nr) gic_data[gic_nr].saved_spi_conf[i] =readl_relaxed (dist_base +GIC_DIST_CONFIG + i *4 ); -for (i =0 ; i <DIV_ROUND_UP (gic_irqs,4 ); i++) +for (i =0 ; i <DIV_ROUND_UP (gic_irqs, nr_if); i++) gic_data[gic_nr].saved_spi_target[i] =readl_relaxed (dist_base +GIC_DIST_TARGET + i *4 );
@@ -502,7 +564,7 @@ static void gic_dist_save(unsigned int gic_nr)*/ static void gic_dist_restore (unsigned int gic_nr) { -unsigned int gic_irqs; +unsigned int gic_irqs, nr_if =32 / gic_data[gic_nr].nr_cpu_if;unsigned int i;void __iomem *dist_base;
@@ -525,7 +587,7 @@ static void gic_dist_restore(unsigned int gic_nr)writel_relaxed (0xa0a0a0a0 , dist_base +GIC_DIST_PRI + i *4 ); -for (i =0 ; i <DIV_ROUND_UP (gic_irqs,4 ); i++) +for (i =0 ; i <DIV_ROUND_UP (gic_irqs, nr_if); i++)writel_relaxed (gic_data[gic_nr].saved_spi_target[i], dist_base +GIC_DIST_TARGET + i *4 );
@@ -665,9 +727,19 @@ static void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)*/ dmb (ishst); -/* this always happens on GIC0 */ -writel_relaxed (map <<16 | irq,gic_data_dist_base (&gic_data[0 ]) +GIC_DIST_SOFTINT ); - +/* +* CPUTargetList -- bit[23:16] in GIC_DIST_SOFTINT in ARM GIC. +* bit[23:8] in GIC_DIST_SOFTINT in HiP04 GIC. +* NSATT -- bit[15] in GIC_DIST_SOFTINT in ARM GIC. +* bit[7] in GIC_DIST_SOFTINT in HiP04 GIC. +* this always happens on GIC0 +*/ +if (gic_data[0 ].nr_cpu_if ==8 ) + map = map <<16 ; +else + map = map <<8 ; +writel_relaxed (map | irq, +gic_data_dist_base (&gic_data[0 ]) +GIC_DIST_SOFTINT ); raw_spin_unlock_irqrestore(&irq_controller_lock, flags); }#endif
@@ -681,10 +753,15 @@ static void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)*/ void gic_send_sgi (unsigned int cpu_id,unsigned int irq) { -BUG_ON (cpu_id >=NR_GIC_CPU_IF ); +BUG_ON (cpu_id >= gic_data[0 ].nr_cpu_if); cpu_id =1 << cpu_id;/* this always happens on GIC0 */ -writel_relaxed ((cpu_id <<16 ) | irq,gic_data_dist_base (&gic_data[0 ]) +GIC_DIST_SOFTINT ); +if (gic_data[0 ].nr_cpu_if ==8 ) + cpu_id = cpu_id <<16 ; +else + cpu_id = cpu_id <<8 ; +writel_relaxed (cpu_id | irq, +gic_data_dist_base (&gic_data[0 ]) +GIC_DIST_SOFTINT ); }/*
@@ -700,7 +777,7 @@ int gic_get_cpu_id(unsigned int cpu) {unsigned int cpu_bit; -if (cpu >=NR_GIC_CPU_IF ) +if (cpu >= gic_data[0 ].nr_cpu_if)return -1 ; cpu_bit = gic_cpu_map[cpu];if (cpu_bit & (cpu_bit -1 ))
@@ -931,7 +1008,7 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,irq_hw_number_t hwirq_base;struct gic_chip_data *gic;int gic_irqs, irq_base, i; -int nr_routable_irqs; +int nr_routable_irqs, max_nr_irq;BUG_ON (gic_nr >=MAX_GIC_NR );
@@ -967,12 +1044,22 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,gic_set_base_accessor (gic, gic_get_common_base); } +if (of_device_is_compatible (node,"hisilicon,hip04-gic" )) { +/* HiP04 GIC supports 16 CPUs at most */ + gic->nr_cpu_if =16 ; + max_nr_irq =510 ; + }else { +/* ARM/Qualcomm GIC supports 8 CPUs at most */ + gic->nr_cpu_if =8 ; + max_nr_irq =1020 ; + } +/* * Initialize the CPU interface map to all CPUs. * It will be refined as each CPU probes its ID. */ -for (i =0 ; i <NR_GIC_CPU_IF ; i++) - gic_cpu_map[i] =0xff ; +for (i =0 ; i < gic->nr_cpu_if; i++) + gic_cpu_map[i] = (1 << gic->nr_cpu_if) -1 ;/* * For primary GICs, skip over SGIs.
@@ -988,12 +1075,13 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,/* * Find out how many interrupts are supported. -* The GIC only supports up to 1020 interrupt sources. +* The ARM/Qualcomm GIC only supports up to 1020 interrupt sources. +* The HiP04 GIC only supports up to 510 interrupt sources. */ gic_irqs =readl_relaxed (gic_data_dist_base (gic) +GIC_DIST_CTR ) &0x1f ; gic_irqs = (gic_irqs +1 ) *32 ; -if (gic_irqs >1020 ) - gic_irqs =1020 ; +if (gic_irqs > max_nr_irq) + gic_irqs = max_nr_irq; gic->gic_irqs = gic_irqs; gic_irqs -= hwirq_base;/* calculate # of irqs to allocate */
@@ -1069,6 +1157,7 @@ gic_of_init(struct device_node *node, struct device_node *parent) }IRQCHIP_DECLARE (cortex_a15_gic,"arm,cortex-a15-gic" , gic_of_init);IRQCHIP_DECLARE (cortex_a9_gic,"arm,cortex-a9-gic" , gic_of_init); +IRQCHIP_DECLARE (hip04_gic,"hisilicon,hip04-gic" , gic_of_init);IRQCHIP_DECLARE (msm_8660_qgic,"qcom,msm-8660-qgic" , gic_of_init);IRQCHIP_DECLARE (msm_qgic2,"qcom,msm-qgic2" , gic_of_init);
Signature · 1 line
1.9.1
PATCH v4 5/14 irq: gic: support hip04 gic
Hi Haojian,
Quoted 43 lines · Haojian Zhuang
There's a little difference between ARM GIC and HiP04 GIC.
* HiP04 GIC could support 16 cores at most, and ARM GIC could support 8 cores at most. So the difination on
GIC_DIST_SGIR,GIC_DIST_SGI_PENDING_SET,GIC_DIST_SGI_PENDING_CLEAR
&GIC_DIST_TARGETregisters are different since CPU interfaces are increased from 8-bit to 16-bit.* HiP04 GIC could support 510 interrupts at most, and ARM GIC could support 1020 interrupts at most.
Signed-off-by Haojian Zhuang <[email protected]>--- drivers/irqchip/irq-gic.c | 155 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 122 insertions(+), 33 deletions(-)drivers/irqchip/irq-gic.c +5
-2@@ -68,6 +68,7 @@ struct gic_chip_data {#ifdef CONFIG_GIC_NON_BANKED void __iomem *(*get_base)(union gic_base *);#endif +u32 nr_cpu_if; };static DEFINE_RAW_SPINLOCK (irq_controller_lock);@@ -76,9 +77,11 @@ static DEFINE_RAW_SPINLOCK(irq_controller_lock);* The GIC mapping of CPU interfaces does not necessarily match * the logical CPU numbering. Let's use a mapping as returned * by the GIC itself. +* +* Hisilicon HiP04 extends the number of CPU interface from 8 to 16. */ -#define NR_GIC_CPU_IF 8 -static u8 gic_cpu_map[NR_GIC_CPU_IF ]__read_mostly ; +#define NR_GIC_CPU_IF 16 +static u16 gic_cpu_map[NR_GIC_CPU_IF ]__read_mostly ;/* * Supported arch specific GIC irq extension.
drivers/irqchip/irq-gic.c static int gic_retrigger(struct irq_data *d) · line 248
Quoted 4 lines
drivers/irqchip/irq-gic.c +1
-0@@ -242,19 +245,55 @@ static int gic_retrigger(struct irq_data *d) }#ifdef CONFIG_SMP +static inline u32 irq_to_core_offset (struct irq_data *d)
I've come to realize that this function name isn't very meaningful. What you're actually computing is the offset from GICD_TARGETR0.
How about renaming it to "irq_to_target_reg" and return the absolute offset of the register? This would make the following code much simpler (see examples below).
drivers/irqchip/irq-gic.c static int gic_retrigger(struct irq_data *d) · line 254
Quoted 6 lines
drivers/irqchip/irq-gic.c +6
-0+{ +struct gic_chip_data *gic_data =irq_data_get_irq_chip_data (d); +unsigned int i =gic_irq (d); + +/* ARM GIC */ +if (gic_data->nr_cpu_if ==8 )
Given how often this is use throughout the code, I'd suggest having an inline function such as:
static inline bool gic_is_standard(struct gic_chip_data *gic)
{
return gic->nr_cpu_if == 8;
}drivers/irqchip/irq-gic.c static int gic_retrigger(struct irq_data *d) · line 255
Quoted 1 line
drivers/irqchip/irq-gic.c +1
-0+return ((i >>2 ) <<2 );
If you want to mask out some bits, just use (i & ~3U).
drivers/irqchip/irq-gic.c static int gic_retrigger(struct irq_data *d) · line 257
Quoted 2 lines
drivers/irqchip/irq-gic.c +2
-0+/* HiP04 GIC (nr_cpu_if == 16) */ +return ((i >>1 ) <<2 );
Same here: (i & ~1U).
Quoted 30 lines
drivers/irqchip/irq-gic.c +25
-2+} + +static inline u32 irq_to_core_shift (struct irq_data *d) +{ +struct gic_chip_data *gic_data =irq_data_get_irq_chip_data (d); +unsigned int i =gic_irq (d); + +/* ARM GIC */ +if (gic_data->nr_cpu_if ==8 ) +return ((i %4 ) <<3 ); +/* HiP04 GIC (nr_cpu_if == 16) */ +return ((i %2 ) <<4 ); +} + +static inline u32 irq_to_core_mask (struct irq_data *d) +{ +struct gic_chip_data *gic_data =irq_data_get_irq_chip_data (d); +u32 mask; +/* ARM GIC, nr_cpu_if == 8; HiP04 GIC, nr_cpu_if == 16 */ + mask = (1 << gic_data->nr_cpu_if) -1 ; +return (mask <<irq_to_core_shift (d)); +} +static int gic_set_affinity (struct irq_data *d,const struct cpumask *mask_val,bool force) { -void __iomem *reg =gic_dist_base (d) +GIC_DIST_TARGET + (gic_irq (d) & ~3 ); -unsigned int shift = (gic_irq (d) %4 ) *8 ; +void __iomem *reg; +struct gic_chip_data *gic_data =irq_data_get_irq_chip_data (d);
drivers/irqchip/irq-gic.c static int gic_retrigger(struct irq_data *d) · line 294
Quoted 10 lines
drivers/irqchip/irq-gic.c +4
-1+unsigned int shift =irq_to_core_shift (d);unsigned int cpu =cpumask_any_and (mask_val, cpu_online_mask);u32 val, mask, bit; -if (cpu >=NR_GIC_CPU_IF || cpu >= nr_cpu_ids) +if (cpu >= gic_data->nr_cpu_if || cpu >= nr_cpu_ids)return -EINVAL ; + reg =gic_dist_base (d) +GIC_DIST_TARGET +irq_to_core_offset (d); +
See my remark above about this code. You can rewrite it as:
reg = gic_dist_base(d) + irq_to_target_reg(d);
Quoted 23 lines
drivers/irqchip/irq-gic.c +5
-6raw_spin_lock (&irq_controller_lock); - mask =0xff << shift; + mask =irq_to_core_mask (d); bit = gic_cpu_map[cpu] << shift; val =readl_relaxed (reg) & ~mask;writel_relaxed (val | bit, reg);@@ -354,15 +393,24 @@ void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq)irq_set_chained_handler (irq, gic_handle_cascade_irq); } -static u8 gic_get_cpumask (struct gic_chip_data *gic) +static u16 gic_get_cpumask (struct gic_chip_data *gic) {void __iomem *base =gic_data_dist_base (gic);u32 mask, i; -for (i = mask =0 ; i <32 ; i +=4 ) { - mask =readl_relaxed (base +GIC_DIST_TARGET + i); - mask |= mask >>16 ; - mask |= mask >>8 ; +/* +* ARM GIC uses 8 registers for interrupt 0-31, +* HiP04 GIC uses 16 registers for interrupt 0-31.
drivers/irqchip/irq-gic.c void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq) · line 413
Quoted 10 lines
drivers/irqchip/irq-gic.c +10
-0+*/ +for (i = mask =0 ; i <32 ; i +=32 / gic->nr_cpu_if) { +if (gic->nr_cpu_if ==8 ) {/* ARM GIC */ + mask =readl_relaxed (base +GIC_DIST_TARGET + i); + mask |= mask >>16 ; + mask |= mask >>8 ; + }else {/* HiP04 GIC */ + mask =readl_relaxed (base +GIC_DIST_TARGET + i *2 ); + mask |= mask >>16 ; + }
With the above change, you can rewrite it as:
mask = readl_relaxed(base + irq_to_target_reg(i));
mask |= mask >> 16;
if (gic_is_standard(gic))
mask |= mask >> 8;which I think is a bit nicer.
Quoted 18 lines
drivers/irqchip/irq-gic.c +4
-0if (mask)break ; }@@ -370,6 +418,10 @@ static u8 gic_get_cpumask(struct gic_chip_data *gic)if (!mask)pr_crit ("GIC CPU mask not found - kernel will fail to boot.\n" ); +/* ARM GIC needs 8-bit cpu mask, HiP04 GIC needs 16-bit cpu mask. */ +if (gic->nr_cpu_if ==8 ) + mask &=0xff ; +return mask; }@@ -392,10 +444,20 @@ static void __init gic_dist_init(struct gic_chip_data *gic)* Set all global interrupts to this CPU only. */ cpumask =gic_get_cpumask (gic);
drivers/irqchip/irq-gic.c static void __init gic_dist_init(struct gic_chip_data *gic) · line 452
Quoted 10 lines
drivers/irqchip/irq-gic.c +6
-4- cpumask |= cpumask <<8 ; - cpumask |= cpumask <<16 ; -for (i =32 ; i < gic_irqs; i +=4 ) -writel_relaxed (cpumask, base +GIC_DIST_TARGET + i *4 /4 ); +if (gic->nr_cpu_if ==8 ) {/* ARM GIC */ + cpumask |= cpumask <<8 ; + cpumask |= cpumask <<16 ; + }else {/* HiP04 GIC */ + cpumask |= cpumask <<16 ; + }
Move the "cpumask |= cpumask << 16;" out of the if block.
drivers/irqchip/irq-gic.c static void __init gic_dist_init(struct gic_chip_data *gic) · line 453
Quoted 1 line
drivers/irqchip/irq-gic.c +1
-0+for (i =32 ; i < gic_irqs; i +=32 / gic->nr_cpu_if) {
Have an inline function that computes this:
static inline gic_irqs_per_target_reg(struct gic_chip_data *gic)
{
return 32 / gic->nr_cpu_if;
}and use it once outside of the loop. You can reuse it in gic_get_cpumask and gic_dist_{save,restore}.
drivers/irqchip/irq-gic.c static void __init gic_dist_init(struct gic_chip_data *gic) · line 459
Quoted 6 lines
drivers/irqchip/irq-gic.c +6
-0+if (gic->nr_cpu_if ==8 ) +writel_relaxed (cpumask, + base +GIC_DIST_TARGET + i /4 *4 ); +else +writel_relaxed (cpumask, + base +GIC_DIST_TARGET + i /2 *4 );
Change this whole block to:
writel_relaxed(cpumask, base + irq_to_target_reg(i));
Quoted 23 lines
drivers/irqchip/irq-gic.c +3
-2+ }/* * Set priority on all global interrupts. @@ -423,7 +485,7 @@ static void gic_cpu_init(struct gic_chip_data *gic)/* * Get what the GIC says our CPU mask is. */ -BUG_ON (cpu >=NR_GIC_CPU_IF ); +BUG_ON (cpu >= gic->nr_cpu_if); cpu_mask =gic_get_cpumask (gic); gic_cpu_map[cpu] = cpu_mask;@@ -431,7 +493,7 @@ static void gic_cpu_init(struct gic_chip_data *gic)* Clear our mask from the other map entries in case they're * still undefined. */ -for (i =0 ; i <NR_GIC_CPU_IF ; i++) +for (i =0 ; i < gic->nr_cpu_if; i++)if (i != cpu) gic_cpu_map[i] &= ~cpu_mask;
drivers/irqchip/irq-gic.c void gic_cpu_if_down(void) · line 532
Quoted 5 lines
drivers/irqchip/irq-gic.c +1
-1@@ -467,7 +529,7 @@ void gic_cpu_if_down(void)*/ static void gic_dist_save (unsigned int gic_nr) { -unsigned int gic_irqs; +unsigned int gic_irqs, nr_if =32 / gic_data[gic_nr].nr_cpu_if;
nr_if is not the number of interfaces, but the number of interrupts per target register. Please give this variable a name that reflects what it is.
Quoted 13 lines
drivers/irqchip/irq-gic.c +1
-1void __iomem *dist_base;int i;@@ -484,7 +546,7 @@ static void gic_dist_save(unsigned int gic_nr) gic_data[gic_nr].saved_spi_conf[i] =readl_relaxed (dist_base +GIC_DIST_CONFIG + i *4 ); -for (i =0 ; i <DIV_ROUND_UP (gic_irqs,4 ); i++) +for (i =0 ; i <DIV_ROUND_UP (gic_irqs, nr_if); i++) gic_data[gic_nr].saved_spi_target[i] =readl_relaxed (dist_base +GIC_DIST_TARGET + i *4 );
drivers/irqchip/irq-gic.c static void gic_dist_save(unsigned int gic_nr) · line 567
Quoted 5 lines
drivers/irqchip/irq-gic.c +1
-1@@ -502,7 +564,7 @@ static void gic_dist_save(unsigned int gic_nr)*/ static void gic_dist_restore (unsigned int gic_nr) { -unsigned int gic_irqs; +unsigned int gic_irqs, nr_if =32 / gic_data[gic_nr].nr_cpu_if;
Same as above.
Quoted 114 lines
drivers/irqchip/irq-gic.c +39
-13unsigned int i;void __iomem *dist_base;@@ -525,7 +587,7 @@ static void gic_dist_restore(unsigned int gic_nr)writel_relaxed (0xa0a0a0a0 , dist_base +GIC_DIST_PRI + i *4 ); -for (i =0 ; i <DIV_ROUND_UP (gic_irqs,4 ); i++) +for (i =0 ; i <DIV_ROUND_UP (gic_irqs, nr_if); i++)writel_relaxed (gic_data[gic_nr].saved_spi_target[i], dist_base +GIC_DIST_TARGET + i *4 );@@ -665,9 +727,19 @@ static void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)*/ dmb (ishst); -/* this always happens on GIC0 */ -writel_relaxed (map <<16 | irq,gic_data_dist_base (&gic_data[0 ]) +GIC_DIST_SOFTINT ); - +/* +* CPUTargetList -- bit[23:16] in GIC_DIST_SOFTINT in ARM GIC. +* bit[23:8] in GIC_DIST_SOFTINT in HiP04 GIC. +* NSATT -- bit[15] in GIC_DIST_SOFTINT in ARM GIC. +* bit[7] in GIC_DIST_SOFTINT in HiP04 GIC. +* this always happens on GIC0 +*/ +if (gic_data[0 ].nr_cpu_if ==8 ) + map = map <<16 ; +else + map = map <<8 ; +writel_relaxed (map | irq, +gic_data_dist_base (&gic_data[0 ]) +GIC_DIST_SOFTINT ); raw_spin_unlock_irqrestore(&irq_controller_lock, flags); }#endif @@ -681,10 +753,15 @@ static void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)*/ void gic_send_sgi (unsigned int cpu_id,unsigned int irq) { -BUG_ON (cpu_id >=NR_GIC_CPU_IF ); +BUG_ON (cpu_id >= gic_data[0 ].nr_cpu_if); cpu_id =1 << cpu_id;/* this always happens on GIC0 */ -writel_relaxed ((cpu_id <<16 ) | irq,gic_data_dist_base (&gic_data[0 ]) +GIC_DIST_SOFTINT ); +if (gic_data[0 ].nr_cpu_if ==8 ) + cpu_id = cpu_id <<16 ; +else + cpu_id = cpu_id <<8 ; +writel_relaxed (cpu_id | irq, +gic_data_dist_base (&gic_data[0 ]) +GIC_DIST_SOFTINT ); }/* @@ -700,7 +777,7 @@ int gic_get_cpu_id(unsigned int cpu) {unsigned int cpu_bit; -if (cpu >=NR_GIC_CPU_IF ) +if (cpu >= gic_data[0 ].nr_cpu_if)return -1 ; cpu_bit = gic_cpu_map[cpu];if (cpu_bit & (cpu_bit -1 ))@@ -931,7 +1008,7 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,irq_hw_number_t hwirq_base;struct gic_chip_data *gic;int gic_irqs, irq_base, i; -int nr_routable_irqs; +int nr_routable_irqs, max_nr_irq;BUG_ON (gic_nr >=MAX_GIC_NR );@@ -967,12 +1044,22 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,gic_set_base_accessor (gic, gic_get_common_base); } +if (of_device_is_compatible (node,"hisilicon,hip04-gic" )) { +/* HiP04 GIC supports 16 CPUs at most */ + gic->nr_cpu_if =16 ; + max_nr_irq =510 ; + }else { +/* ARM/Qualcomm GIC supports 8 CPUs at most */ + gic->nr_cpu_if =8 ; + max_nr_irq =1020 ; + } +/* * Initialize the CPU interface map to all CPUs. * It will be refined as each CPU probes its ID. */ -for (i =0 ; i <NR_GIC_CPU_IF ; i++) - gic_cpu_map[i] =0xff ; +for (i =0 ; i < gic->nr_cpu_if; i++) + gic_cpu_map[i] = (1 << gic->nr_cpu_if) -1 ;/* * For primary GICs, skip over SGIs. @@ -988,12 +1075,13 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,/* * Find out how many interrupts are supported. -* The GIC only supports up to 1020 interrupt sources. +* The ARM/Qualcomm GIC only supports up to 1020 interrupt sources. +* The HiP04 GIC only supports up to 510 interrupt sources. */ gic_irqs =readl_relaxed (gic_data_dist_base (gic) +GIC_DIST_CTR ) &0x1f ; gic_irqs = (gic_irqs +1 ) *32 ; -if (gic_irqs >1020 ) - gic_irqs =1020 ; +if (gic_irqs > max_nr_irq) + gic_irqs = max_nr_irq; gic->gic_irqs = gic_irqs; gic_irqs -= hwirq_base;/* calculate # of irqs to allocate */
drivers/irqchip/irq-gic.c gic_of_init(struct device_node *node, struct device_node *parent) · line 1162
Quoted 6 lines
drivers/irqchip/irq-gic.c +1
-0@@ -1069,6 +1157,7 @@ gic_of_init(struct device_node *node, struct device_node *parent) }IRQCHIP_DECLARE (cortex_a15_gic,"arm,cortex-a15-gic" , gic_of_init);IRQCHIP_DECLARE (cortex_a9_gic,"arm,cortex-a9-gic" , gic_of_init); +IRQCHIP_DECLARE (hip04_gic,"hisilicon,hip04-gic" , gic_of_init);IRQCHIP_DECLARE (msm_8660_qgic,"qcom,msm-8660-qgic" , gic_of_init);IRQCHIP_DECLARE (msm_qgic2,"qcom,msm-qgic2" , gic_of_init);
So this patch is a lot better than the previous ones. Still some work to do to make it clearer, have the proper abstraction and avoid repetition of similar constructs.
Thanks,
M.
Signature · 1 line
Jazz is not dead. It just smells funny.
PATCH v4 5/14 irq: gic: support hip04 gic
In reply to Haojian ZhuangQuoted 7 lines · Haojian Zhuang
There's a little difference between ARM GIC and HiP04 GIC.
* HiP04 GIC could support 16 cores at most, and ARM GIC could support 8 cores at most. So the difination on
GIC_DIST_SGIR,GIC_DIST_SGI_PENDING_SET,GIC_DIST_SGI_PENDING_CLEAR
&GIC_DIST_TARGETregisters are different since CPU interfaces are increased from 8-bit to 16-bit.
WTF? What is the point of a GIC spec then. It is just a suggestion?
In general, there are a bunch of if/else for handling the 2 versions added here. I think some ops struct of function ptrs to abstract the differences would be cleaner.
Rob
Quoted 331 lines
* HiP04 GIC could support 510 interrupts at most, and ARM GIC could support 1020 interrupts at most.
Signed-off-by Haojian Zhuang <[email protected]>--- drivers/irqchip/irq-gic.c | 155 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 122 insertions(+), 33 deletions(-)drivers/irqchip/irq-gic.c +122
-34@@ -68,6 +68,7 @@ struct gic_chip_data {#ifdef CONFIG_GIC_NON_BANKED void __iomem *(*get_base)(union gic_base *);#endif +u32 nr_cpu_if; };static DEFINE_RAW_SPINLOCK (irq_controller_lock);@@ -76,9 +77,11 @@ static DEFINE_RAW_SPINLOCK(irq_controller_lock);* The GIC mapping of CPU interfaces does not necessarily match * the logical CPU numbering. Let's use a mapping as returned * by the GIC itself. +* +* Hisilicon HiP04 extends the number of CPU interface from 8 to 16. */ -#define NR_GIC_CPU_IF 8 -static u8 gic_cpu_map[NR_GIC_CPU_IF ]__read_mostly ; +#define NR_GIC_CPU_IF 16 +static u16 gic_cpu_map[NR_GIC_CPU_IF ]__read_mostly ;/* * Supported arch specific GIC irq extension. @@ -242,19 +245,55 @@ static int gic_retrigger(struct irq_data *d) }#ifdef CONFIG_SMP +static inline u32 irq_to_core_offset (struct irq_data *d) +{ +struct gic_chip_data *gic_data =irq_data_get_irq_chip_data (d); +unsigned int i =gic_irq (d); + +/* ARM GIC */ +if (gic_data->nr_cpu_if ==8 ) +return ((i >>2 ) <<2 ); +/* HiP04 GIC (nr_cpu_if == 16) */ +return ((i >>1 ) <<2 ); +} + +static inline u32 irq_to_core_shift (struct irq_data *d) +{ +struct gic_chip_data *gic_data =irq_data_get_irq_chip_data (d); +unsigned int i =gic_irq (d); + +/* ARM GIC */ +if (gic_data->nr_cpu_if ==8 ) +return ((i %4 ) <<3 ); +/* HiP04 GIC (nr_cpu_if == 16) */ +return ((i %2 ) <<4 ); +} + +static inline u32 irq_to_core_mask (struct irq_data *d) +{ +struct gic_chip_data *gic_data =irq_data_get_irq_chip_data (d); +u32 mask; +/* ARM GIC, nr_cpu_if == 8; HiP04 GIC, nr_cpu_if == 16 */ + mask = (1 << gic_data->nr_cpu_if) -1 ; +return (mask <<irq_to_core_shift (d)); +} +static int gic_set_affinity (struct irq_data *d,const struct cpumask *mask_val,bool force) { -void __iomem *reg =gic_dist_base (d) +GIC_DIST_TARGET + (gic_irq (d) & ~3 ); -unsigned int shift = (gic_irq (d) %4 ) *8 ; +void __iomem *reg; +struct gic_chip_data *gic_data =irq_data_get_irq_chip_data (d); +unsigned int shift =irq_to_core_shift (d);unsigned int cpu =cpumask_any_and (mask_val, cpu_online_mask);u32 val, mask, bit; -if (cpu >=NR_GIC_CPU_IF || cpu >= nr_cpu_ids) +if (cpu >= gic_data->nr_cpu_if || cpu >= nr_cpu_ids)return -EINVAL ; + reg =gic_dist_base (d) +GIC_DIST_TARGET +irq_to_core_offset (d); +raw_spin_lock (&irq_controller_lock); - mask =0xff << shift; + mask =irq_to_core_mask (d); bit = gic_cpu_map[cpu] << shift; val =readl_relaxed (reg) & ~mask;writel_relaxed (val | bit, reg);@@ -354,15 +393,24 @@ void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq)irq_set_chained_handler (irq, gic_handle_cascade_irq); } -static u8 gic_get_cpumask (struct gic_chip_data *gic) +static u16 gic_get_cpumask (struct gic_chip_data *gic) {void __iomem *base =gic_data_dist_base (gic);u32 mask, i; -for (i = mask =0 ; i <32 ; i +=4 ) { - mask =readl_relaxed (base +GIC_DIST_TARGET + i); - mask |= mask >>16 ; - mask |= mask >>8 ; +/* +* ARM GIC uses 8 registers for interrupt 0-31, +* HiP04 GIC uses 16 registers for interrupt 0-31. +*/ +for (i = mask =0 ; i <32 ; i +=32 / gic->nr_cpu_if) { +if (gic->nr_cpu_if ==8 ) {/* ARM GIC */ + mask =readl_relaxed (base +GIC_DIST_TARGET + i); + mask |= mask >>16 ; + mask |= mask >>8 ; + }else {/* HiP04 GIC */ + mask =readl_relaxed (base +GIC_DIST_TARGET + i *2 ); + mask |= mask >>16 ; + }if (mask)break ; }@@ -370,6 +418,10 @@ static u8 gic_get_cpumask(struct gic_chip_data *gic)if (!mask)pr_crit ("GIC CPU mask not found - kernel will fail to boot.\n" ); +/* ARM GIC needs 8-bit cpu mask, HiP04 GIC needs 16-bit cpu mask. */ +if (gic->nr_cpu_if ==8 ) + mask &=0xff ; +return mask; }@@ -392,10 +444,20 @@ static void __init gic_dist_init(struct gic_chip_data *gic)* Set all global interrupts to this CPU only. */ cpumask =gic_get_cpumask (gic); - cpumask |= cpumask <<8 ; - cpumask |= cpumask <<16 ; -for (i =32 ; i < gic_irqs; i +=4 ) -writel_relaxed (cpumask, base +GIC_DIST_TARGET + i *4 /4 ); +if (gic->nr_cpu_if ==8 ) {/* ARM GIC */ + cpumask |= cpumask <<8 ; + cpumask |= cpumask <<16 ; + }else {/* HiP04 GIC */ + cpumask |= cpumask <<16 ; + } +for (i =32 ; i < gic_irqs; i +=32 / gic->nr_cpu_if) { +if (gic->nr_cpu_if ==8 ) +writel_relaxed (cpumask, + base +GIC_DIST_TARGET + i /4 *4 ); +else +writel_relaxed (cpumask, + base +GIC_DIST_TARGET + i /2 *4 ); + }/* * Set priority on all global interrupts. @@ -423,7 +485,7 @@ static void gic_cpu_init(struct gic_chip_data *gic)/* * Get what the GIC says our CPU mask is. */ -BUG_ON (cpu >=NR_GIC_CPU_IF ); +BUG_ON (cpu >= gic->nr_cpu_if); cpu_mask =gic_get_cpumask (gic); gic_cpu_map[cpu] = cpu_mask;@@ -431,7 +493,7 @@ static void gic_cpu_init(struct gic_chip_data *gic)* Clear our mask from the other map entries in case they're * still undefined. */ -for (i =0 ; i <NR_GIC_CPU_IF ; i++) +for (i =0 ; i < gic->nr_cpu_if; i++)if (i != cpu) gic_cpu_map[i] &= ~cpu_mask;@@ -467,7 +529,7 @@ void gic_cpu_if_down(void)*/ static void gic_dist_save (unsigned int gic_nr) { -unsigned int gic_irqs; +unsigned int gic_irqs, nr_if =32 / gic_data[gic_nr].nr_cpu_if;void __iomem *dist_base;int i;@@ -484,7 +546,7 @@ static void gic_dist_save(unsigned int gic_nr) gic_data[gic_nr].saved_spi_conf[i] =readl_relaxed (dist_base +GIC_DIST_CONFIG + i *4 ); -for (i =0 ; i <DIV_ROUND_UP (gic_irqs,4 ); i++) +for (i =0 ; i <DIV_ROUND_UP (gic_irqs, nr_if); i++) gic_data[gic_nr].saved_spi_target[i] =readl_relaxed (dist_base +GIC_DIST_TARGET + i *4 );@@ -502,7 +564,7 @@ static void gic_dist_save(unsigned int gic_nr)*/ static void gic_dist_restore (unsigned int gic_nr) { -unsigned int gic_irqs; +unsigned int gic_irqs, nr_if =32 / gic_data[gic_nr].nr_cpu_if;unsigned int i;void __iomem *dist_base;@@ -525,7 +587,7 @@ static void gic_dist_restore(unsigned int gic_nr)writel_relaxed (0xa0a0a0a0 , dist_base +GIC_DIST_PRI + i *4 ); -for (i =0 ; i <DIV_ROUND_UP (gic_irqs,4 ); i++) +for (i =0 ; i <DIV_ROUND_UP (gic_irqs, nr_if); i++)writel_relaxed (gic_data[gic_nr].saved_spi_target[i], dist_base +GIC_DIST_TARGET + i *4 );@@ -665,9 +727,19 @@ static void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)*/ dmb (ishst); -/* this always happens on GIC0 */ -writel_relaxed (map <<16 | irq,gic_data_dist_base (&gic_data[0 ]) +GIC_DIST_SOFTINT ); - +/* +* CPUTargetList -- bit[23:16] in GIC_DIST_SOFTINT in ARM GIC. +* bit[23:8] in GIC_DIST_SOFTINT in HiP04 GIC. +* NSATT -- bit[15] in GIC_DIST_SOFTINT in ARM GIC. +* bit[7] in GIC_DIST_SOFTINT in HiP04 GIC. +* this always happens on GIC0 +*/ +if (gic_data[0 ].nr_cpu_if ==8 ) + map = map <<16 ; +else + map = map <<8 ; +writel_relaxed (map | irq, +gic_data_dist_base (&gic_data[0 ]) +GIC_DIST_SOFTINT ); raw_spin_unlock_irqrestore(&irq_controller_lock, flags); }#endif @@ -681,10 +753,15 @@ static void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)*/ void gic_send_sgi (unsigned int cpu_id,unsigned int irq) { -BUG_ON (cpu_id >=NR_GIC_CPU_IF ); +BUG_ON (cpu_id >= gic_data[0 ].nr_cpu_if); cpu_id =1 << cpu_id;/* this always happens on GIC0 */ -writel_relaxed ((cpu_id <<16 ) | irq,gic_data_dist_base (&gic_data[0 ]) +GIC_DIST_SOFTINT ); +if (gic_data[0 ].nr_cpu_if ==8 ) + cpu_id = cpu_id <<16 ; +else + cpu_id = cpu_id <<8 ; +writel_relaxed (cpu_id | irq, +gic_data_dist_base (&gic_data[0 ]) +GIC_DIST_SOFTINT ); }/* @@ -700,7 +777,7 @@ int gic_get_cpu_id(unsigned int cpu) {unsigned int cpu_bit; -if (cpu >=NR_GIC_CPU_IF ) +if (cpu >= gic_data[0 ].nr_cpu_if)return -1 ; cpu_bit = gic_cpu_map[cpu];if (cpu_bit & (cpu_bit -1 ))@@ -931,7 +1008,7 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,irq_hw_number_t hwirq_base;struct gic_chip_data *gic;int gic_irqs, irq_base, i; -int nr_routable_irqs; +int nr_routable_irqs, max_nr_irq;BUG_ON (gic_nr >=MAX_GIC_NR );@@ -967,12 +1044,22 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,gic_set_base_accessor (gic, gic_get_common_base); } +if (of_device_is_compatible (node,"hisilicon,hip04-gic" )) { +/* HiP04 GIC supports 16 CPUs at most */ + gic->nr_cpu_if =16 ; + max_nr_irq =510 ; + }else { +/* ARM/Qualcomm GIC supports 8 CPUs at most */ + gic->nr_cpu_if =8 ; + max_nr_irq =1020 ; + } +/* * Initialize the CPU interface map to all CPUs. * It will be refined as each CPU probes its ID. */ -for (i =0 ; i <NR_GIC_CPU_IF ; i++) - gic_cpu_map[i] =0xff ; +for (i =0 ; i < gic->nr_cpu_if; i++) + gic_cpu_map[i] = (1 << gic->nr_cpu_if) -1 ;/* * For primary GICs, skip over SGIs. @@ -988,12 +1075,13 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,/* * Find out how many interrupts are supported. -* The GIC only supports up to 1020 interrupt sources. +* The ARM/Qualcomm GIC only supports up to 1020 interrupt sources. +* The HiP04 GIC only supports up to 510 interrupt sources. */ gic_irqs =readl_relaxed (gic_data_dist_base (gic) +GIC_DIST_CTR ) &0x1f ; gic_irqs = (gic_irqs +1 ) *32 ; -if (gic_irqs >1020 ) - gic_irqs =1020 ; +if (gic_irqs > max_nr_irq) + gic_irqs = max_nr_irq; gic->gic_irqs = gic_irqs; gic_irqs -= hwirq_base;/* calculate # of irqs to allocate */ @@ -1069,6 +1157,7 @@ gic_of_init(struct device_node *node, struct device_node *parent) }IRQCHIP_DECLARE (cortex_a15_gic,"arm,cortex-a15-gic" , gic_of_init);IRQCHIP_DECLARE (cortex_a9_gic,"arm,cortex-a9-gic" , gic_of_init); +IRQCHIP_DECLARE (hip04_gic,"hisilicon,hip04-gic" , gic_of_init);IRQCHIP_DECLARE (msm_8660_qgic,"qcom,msm-8660-qgic" , gic_of_init);IRQCHIP_DECLARE (msm_qgic2,"qcom,msm-qgic2" , gic_of_init); --1.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
PATCH v4 6/14 ARM: mcpm: support 4 clusters
In reply to Haojian ZhuangAdd the CONFIG_MCPM_QUAD_CLUSTER configuration to enlarge cluster number from 2 to 4.
--- arch/arm/Kconfig | 6 ++++++ arch/arm/include/asm/mcpm.h | 5 +++++ 2 files changed, 11 insertions(+)
arch/arm/Kconfig +6 -0
@@ -1572,6 +1572,12 @@ config MCPM for (multi-)cluster based systems, such as big.LITTLE based systems. +config MCPM_QUAD_CLUSTER + bool "Enable Quad clusters in MCPM" + depends on MCPM + help + This option enables quad clusters in MCPM. + config BIG_LITTLE bool "big.LITTLE support (Experimental)" depends on CPU_V7 && SMP
arch/arm/include/asm/mcpm.h +5 -0
@@ -20,7 +20,12 @@* to consider dynamic allocation. */ #define MAX_CPUS_PER_CLUSTER 4 + +#ifdef CONFIG_MCPM_QUAD_CLUSTER +#define MAX_NR_CLUSTERS 4 +#else #define MAX_NR_CLUSTERS 2 +#endif #ifndef __ASSEMBLY__
Signature · 1 line
1.9.1
PATCH v4 6/14 ARM: mcpm: support 4 clusters
Quoted 14 lines · Haojian Zhuang
Add the
CONFIG_MCPM_QUAD_CLUSTERconfiguration to enlarge cluster number from 2 to 4.Signed-off-by Haojian Zhuang <[email protected]>--- arch/arm/Kconfig | 6 ++++++ arch/arm/include/asm/mcpm.h | 5 +++++ 2 files changed, 11 insertions(+)arch/arm/Kconfig +0
-0
arch/arm/Kconfig config MCPM · line 1579
Quoted 8 lines
arch/arm/Kconfig +5
-0@@ -1572,6 +1572,12 @@ config MCPM for (multi-)cluster based systems, such as big.LITTLE based systems. +config MCPM_QUAD_CLUSTER + bool "Enable Quad clusters in MCPM" + depends on MCPM + help + This option enables quad clusters in MCPM.
This is fairly self-explanatory, but to make things crystal clear you could add an explanatory note about how this option should be used, something like:
To avoid wasting resources unnecessarily, MCPM only supports up to 2 clusters by default.
Platforms with 3 or 4 clusters that use MCPM must select this option to allow the additional clusters to be managed.
Cheers
---Dave
PATCH v4 7/14 ARM: hisi: add ARCH_HISI
In reply to Haojian ZhuangSince multiple ARCH configuration will be appended into mach-hisi directory, add ARCH_HISI as common configuration for different ARCH in mach-hisi.
--- arch/arm/Makefile | 2 +- arch/arm/mach-hisi/Kconfig | 16 ++++++++++++++-- 2 files changed, 15 insertions(+), 3 deletions(-)
arch/arm/Makefile +1 -1
@@ -154,7 +154,7 @@ machine-$(CONFIG_ARCH_EP93XX) += ep93xx machine-$(CONFIG_ARCH_EXYNOS) += exynos machine-$(CONFIG_ARCH_GEMINI) += gemini machine-$(CONFIG_ARCH_HIGHBANK) += highbank -machine-$(CONFIG_ARCH_HI3xxx) += hisi +machine-$(CONFIG_ARCH_HISI) += hisi machine-$(CONFIG_ARCH_INTEGRATOR) += integrator machine-$(CONFIG_ARCH_IOP13XX) += iop13xx machine-$(CONFIG_ARCH_IOP32X) += iop32x
arch/arm/mach-hisi/Kconfig +14 -2
@@ -1,8 +1,16 @@ -config ARCH_HI3xxx - bool "Hisilicon Hi36xx/Hi37xx family" if ARCH_MULTI_V7 +config ARCH_HISI + bool "Hisilicon SoC Support" + depends on ARCH_MULTIPLATFORM select ARM_AMBA select ARM_GIC select ARM_TIMER_SP804 + +if ARCH_HISI + +menu "Hisilicon platform type" + +config ARCH_HI3xxx + bool "Hisilicon Hi36xx/Hi37xx family" if ARCH_MULTI_V7 select CACHE_L2X0 select HAVE_ARM_SCU if SMP select HAVE_ARM_TWD if SMP
@@ -10,3 +18,7 @@ config ARCH_HI3xxx select PINCTRL_SINGLE help Support for Hisilicon Hi36xx/Hi37xx processor family + +endmenu + +endif
Signature · 1 line
1.9.1
PATCH v4 8/14 ARM: hisi: add hip04 SoC support
In reply to Haojian ZhuangHisilicon Hi3xxx is based on Cortex A9 Core. Now HiP04 SoC is based on Cortex A15 Core. Since multiple clusters is used in HiP04 SoC, it could be based on MCPM.
And HiP04 supports LPAE to support large memory.
--- arch/arm/Kconfig | 2 +- arch/arm/mach-hisi/Kconfig | 10 +- arch/arm/mach-hisi/Makefile | 1 + arch/arm/mach-hisi/core.h | 2 + arch/arm/mach-hisi/hisilicon.c | 12 ++ arch/arm/mach-hisi/platmcpm.c | 318 +++++++++++++++++++++++++++++++++++++++++ 6 files changed, 343 insertions(+), 2 deletions(-) create mode 100644 arch/arm/mach-hisi/platmcpm.c
arch/arm/Kconfig +1 -1
@@ -1114,7 +1114,7 @@ source arch/arm/mm/Kconfig config ARM_NR_BANKS int - default 16 if ARCH_EP93XX + default 16 if ARCH_EP93XX || ARCH_HIP04 default 8 config IWMMXT
arch/arm/mach-hisi/Kconfig +9 -1
@@ -17,7 +17,15 @@ config ARCH_HI3xxx select PINCTRL select PINCTRL_SINGLE help - Support for Hisilicon Hi36xx/Hi37xx processor family + Support for Hisilicon Hi36xx/Hi37xx SoC family + +config ARCH_HIP04 + bool "Hisilicon HiP04 Cortex A15 family" if ARCH_MULTI_V7_LPAE + select HAVE_ARM_ARCH_TIMER + select MCPM if SMP + select MCPM_QUAD_CLUSTER if SMP + help + Support for Hisilicon HiP04 SoC family endmenu
arch/arm/mach-hisi/Makefile +1 -0
@@ -3,4 +3,5 @@ # obj-y += hisilicon.o +obj-$(CONFIG_MCPM) += platmcpm.o obj-$(CONFIG_SMP) += platsmp.o hotplug.o
arch/arm/mach-hisi/core.h +2 -0
@@ -12,4 +12,6 @@ extern void hi3xxx_cpu_die(unsigned int cpu);extern int hi3xxx_cpu_kill (unsigned int cpu);extern void hi3xxx_set_cpu (int cpu,bool enable); +extern bool __init hip04_smp_init_ops (void ); +#endif
arch/arm/mach-hisi/hisilicon.c +12 -0
@@ -88,3 +88,15 @@ DT_MACHINE_START(HI3620, "Hisilicon Hi3620 (Flattened Device Tree)") .smp = smp_ops(hi3xxx_smp_ops), .restart = hi3xxx_restart, MACHINE_END + +#ifdef CONFIG_ARCH_HIP04 +static const char *hip04_compat[]__initconst = { +"hisilicon,hip04-d01" , +NULL , +}; + +DT_MACHINE_START (HIP04 ,"Hisilicon HiP04 (Flattened Device Tree)" ) + .dt_compat = hip04_compat, + .smp_init =smp_init_ops (hip04_smp_init_ops), +MACHINE_END +#endif
arch/arm/mach-hisi/platmcpm.c new file +318 -0
318 lines not on this page · raw message
Signature · 1 line
1.9.1
PATCH v4 8/14 ARM: hisi: add hip04 SoC support
Quoted 16 lines · Haojian Zhuang
Hisilicon Hi3xxx is based on Cortex A9 Core. Now HiP04 SoC is based on Cortex A15 Core. Since multiple clusters is used in HiP04 SoC, it could be based on MCPM.
And HiP04 supports LPAE to support large memory.
Signed-off-by Haojian Zhuang <[email protected]>--- arch/arm/Kconfig | 2 +- arch/arm/mach-hisi/Kconfig | 10 +- arch/arm/mach-hisi/Makefile | 1 + arch/arm/mach-hisi/core.h | 2 + arch/arm/mach-hisi/hisilicon.c | 12 ++ arch/arm/mach-hisi/platmcpm.c | 318 +++++++++++++++++++++++++++++++++++++++++ 6 files changed, 343 insertions(+), 2 deletions(-) create mode 100644 arch/arm/mach-hisi/platmcpm.c
[...]
Quoted 4 lines
arch/arm/mach-hisi/hisilicon.c +0
-0
[...]
Quoted 1 line
arch/arm/mach-hisi/hisilicon.c +0
-0@@ -0,0 +1,318 @@
[...]
Quoted 6 lines
arch/arm/mach-hisi/hisilicon.c +6
-0+static int hip04_mcpm_power_up (unsigned int cpu,unsigned int cluster) +{ +unsigned long data, mask; + +if (!relocation || !sysctrl) +return -ENODEV ;
arch/arm/mach-hisi/hisilicon.c
Quoted 10 lines
arch/arm/mach-hisi/hisilicon.c +10
-0+if (cluster >=HIP04_MAX_CLUSTERS || cpu >=HIP04_MAX_CPUS_PER_CLUSTER ) +return -EINVAL ; + +spin_lock_irq (&boot_lock); +writel_relaxed (hip04_boot.bootwrapper_phys, relocation); +writel_relaxed (hip04_boot.bootwrapper_magic, relocation +4 ); +writel_relaxed (virt_to_phys (mcpm_entry_point), relocation +8 ); +writel_relaxed (0 , relocation +12 ); + +if (hip04_cluster_down (cluster)) {
Do you intend to add more functionality to this backend later?
The key facility that MCPM provides is in helping to manage per-cluster resources in the presence of interrupt-driven wakeups.
If you have to explicity reset L2 before the first CPU can power up, this restricts the possibility of interrupt-driven wakeup of a cluster, unless you leave L2 powered up so that there is no need to reset it.
arch/arm/mach-hisi/hisilicon.c
Quoted 2 lines
arch/arm/mach-hisi/hisilicon.c +2
-0+ data =CLUSTER_L2_RESET_BIT |CLUSTER_DEBUG_RESET_BIT ; +writel_relaxed (data, sysctrl +SC_CPU_RESET_DREQ (cluster));
Can this reset operation race with v7_exit_coherency_flush() in hip04_mcpm_power_down()?
The _power_down() method must probably release boot_lock before calling v7_exit_coherency_flush(), because spinlocks may stop working properly as result of disabling the cache -- whether they still work depends on the CPU and the platform, but it is probably best not to rely on it unless you are sure it is safe for your platform.
However, this currently leaves the L2 cache unprotected from racing with _power_up().
Currently MCPM assumes that all cluster setup is done by the powering-up CPU itself. For hardware platforms where this isn't possible, there is a limit on how deep clusters can be powered down for CPUidle which will solve the problem for us. But for hotplug to work safely we might need a C interface for doing the power-up part of the coordination, currently done by mcpm_head.S.
Cheers
---Dave
Quoted 210 lines
arch/arm/mach-hisi/hisilicon.c +202
-0+do { + mask =CLUSTER_L2_RESET_STATUS | \ +CLUSTER_DEBUG_RESET_STATUS ; + data =readl_relaxed (sysctrl + \ +SC_CPU_RESET_STATUS (cluster)); + }while (data & mask); +hip04_set_snoop_filter (cluster,1 ); + } + + hip04_cpu_table[cluster][cpu]++; + + data =CORE_RESET_BIT (cpu) |NEON_RESET_BIT (cpu) | \ +CORE_DEBUG_RESET_BIT (cpu); +writel_relaxed (data, sysctrl +SC_CPU_RESET_DREQ (cluster)); +spin_unlock_irq (&boot_lock); +msleep (POLL_MSEC ); + +return 0 ; +} + +static void hip04_mcpm_power_down (void ) +{ +unsigned int mpidr, cpu, cluster; +bool skip_wfi = false; + + mpidr =read_cpuid_mpidr (); + cpu =MPIDR_AFFINITY_LEVEL (mpidr,0 ); + cluster =MPIDR_AFFINITY_LEVEL (mpidr,1 ); + +__mcpm_cpu_going_down (cpu, cluster); + +spin_lock (&boot_lock); +BUG_ON (__mcpm_cluster_state (cluster) !=CLUSTER_UP ); + hip04_cpu_table[cluster][cpu]--; +if (hip04_cpu_table[cluster][cpu] ==1 ) { +/* A power_up request went ahead of us. */ + skip_wfi = true; + }else if (hip04_cpu_table[cluster][cpu] >1 ) { +pr_err ("Cluster %d CPU%d is still running\n" , cluster, cpu); +BUG (); + } + +spin_unlock (&boot_lock); + +v7_exit_coherency_flush (louis); + +__mcpm_cpu_down (cpu, cluster); + +isb (); +dsb (); + +if (!skip_wfi) +wfi (); +} + +static int hip04_mcpm_wait_for_powerdown (unsigned int cpu,unsigned int cluster) +{ +unsigned int data, tries; + +BUG_ON (cluster >=HIP04_MAX_CLUSTERS || + cpu >=HIP04_MAX_CPUS_PER_CLUSTER ); + +for (tries =0 ; tries <TIMEOUT_MSEC /POLL_MSEC ; tries++) { + data =readl_relaxed (sysctrl +SC_CPU_RESET_STATUS (cluster)); +if (!(data &CORE_WFI_STATUS (cpu))) { +msleep (POLL_MSEC ); +continue ; + } + data =CORE_RESET_BIT (cpu) |NEON_RESET_BIT (cpu) | \ +CORE_DEBUG_RESET_BIT (cpu); +writel_relaxed (data, sysctrl +SC_CPU_RESET_REQ (cluster)); +return 0 ; + } + +return -ETIMEDOUT ; +} + +static void hip04_mcpm_powered_up (void ) +{ +if (!relocation) +return ; +spin_lock (&boot_lock); +writel_relaxed (0 , relocation); +writel_relaxed (0 , relocation +4 ); +writel_relaxed (0 , relocation +8 ); +writel_relaxed (0 , relocation +12 ); +spin_unlock (&boot_lock); +} + +static const struct mcpm_platform_ops hip04_mcpm_ops = { + .power_up = hip04_mcpm_power_up, + .power_down = hip04_mcpm_power_down, + .wait_for_powerdown = hip04_mcpm_wait_for_powerdown, + .powered_up = hip04_mcpm_powered_up, +}; + +static bool __init hip04_cpu_table_init (void ) +{ +unsigned int mpidr, cpu, cluster; + + mpidr =read_cpuid_mpidr (); + cpu =MPIDR_AFFINITY_LEVEL (mpidr,0 ); + cluster =MPIDR_AFFINITY_LEVEL (mpidr,1 ); + +if (cluster >=HIP04_MAX_CLUSTERS || + cpu >=HIP04_MAX_CPUS_PER_CLUSTER ) { +pr_err ("%s: boot CPU is out of bound!\n" , __func__); +return false; + } +hip04_set_snoop_filter (cluster,1 ); + hip04_cpu_table[cluster][cpu] =1 ; +return true; +} + +static int __init hip04_mcpm_init (void ) +{ +struct device_node *np, *np_fab; +int ret = -ENODEV ; + + np =of_find_compatible_node (NULL ,NULL ,"hisilicon,sysctrl" ); +if (!np) + goto err; + np_fab =of_find_compatible_node (NULL ,NULL ,"hisilicon,hip04-fabric" ); +if (!np_fab) + goto err; + +if (of_property_read_u32 (np,"bootwrapper-phys" , + &hip04_boot.bootwrapper_phys)) { +pr_err ("failed to get bootwrapper-phys\n" ); + ret = -EINVAL ; + goto err; + } +if (of_property_read_u32 (np,"bootwrapper-size" , + &hip04_boot.bootwrapper_size)) { +pr_err ("failed to get bootwrapper-size\n" ); + ret = -EINVAL ; + goto err; + } +if (of_property_read_u32 (np,"bootwrapper-magic" , + &hip04_boot.bootwrapper_magic)) { +pr_err ("failed to get bootwrapper-magic\n" ); + ret = -EINVAL ; + goto err; + } +if (of_property_read_u32 (np,"relocation-entry" , + &hip04_boot.relocation_entry)) { +pr_err ("failed to get relocation-entry\n" ); + ret = -EINVAL ; + goto err; + } +if (of_property_read_u32 (np,"relocation-size" , + &hip04_boot.relocation_size)) { +pr_err ("failed to get relocation-size\n" ); + ret = -EINVAL ; + goto err; + } + + relocation =ioremap (hip04_boot.relocation_entry, + hip04_boot.relocation_size); +if (!relocation) { +pr_err ("failed to map relocation space\n" ); + ret = -ENOMEM ; + goto err; + } + sysctrl =of_iomap (np,0 ); +if (!sysctrl) { +pr_err ("failed to get sysctrl base\n" ); + ret = -ENOMEM ; + goto err_sysctrl; + } + fabric =of_iomap (np_fab,0 ); +if (!fabric) { +pr_err ("failed to get fabric base\n" ); + ret = -ENOMEM ; + goto err_fabric; + } + +memblock_reserve (hip04_boot.bootwrapper_phys, + hip04_boot.bootwrapper_size); + +if (!hip04_cpu_table_init ()) +return -EINVAL ; + ret =mcpm_platform_register (&hip04_mcpm_ops); +if (!ret) { +mcpm_sync_init (NULL ); +pr_info ("HiP04 MCPM initialized\n" ); + } +return ret; +err_fabric: +iounmap (sysctrl); +err_sysctrl: +iounmap (relocation); +err: +return ret; +} +early_initcall (hip04_mcpm_init); + +bool __init hip04_smp_init_ops (void ) +{ +mcpm_smp_set_ops (); +return true; +}Signature · 7 lines
1.9.1 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel at lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
PATCH v4 9/14 ARM: dts: add hip04-d01 dts file
In reply to Haojian ZhuangAdd hip04.dtsi & hip04-d01.dts file to support HiP04 SoC platform.
--- Documentation/devicetree/bindings/arm/gic.txt | 1 + .../bindings/arm/hisilicon/hisilicon.txt | 10 + .../devicetree/bindings/clock/hip04-clock.txt | 20 ++ arch/arm/boot/dts/Makefile | 1 + arch/arm/boot/dts/hip04-d01.dts | 74 +++++++ arch/arm/boot/dts/hip04.dtsi | 239 +++++++++++++++++++++ 6 files changed, 345 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/hip04-clock.txt create mode 100644 arch/arm/boot/dts/hip04-d01.dts create mode 100644 arch/arm/boot/dts/hip04.dtsi
Documentation/devicetree/bindings/arm/gic.txt +1 -0
@@ -16,6 +16,7 @@ Main node required properties: "arm,cortex-a9-gic" "arm,cortex-a7-gic" "arm,arm11mp-gic" + "hisilicon,hip04-gic" - interrupt-controller : Identifies the node as an interrupt controller - #interrupt-cells : Specifies the number of cells needed to encode an interrupt source. The type shall be a <u32> and the value shall be 3.
Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt +10 -0
@@ -4,6 +4,10 @@ Hisilicon Platforms Device Tree Bindings Hi4511 Board Required root node properties: - compatible = "hisilicon,hi3620-hi4511"; +HiP04 D01 Board +Required root node properties: + - compatible = "hisilicon,hip04-d01"; + Hisilicon system controller
@@ -19,6 +23,11 @@ Optional properties: If reg value is not zero, cpun exit wfi and go - resume-offset : offset in sysctrl for notifying cpu0 when resume - reboot-offset : offset in sysctrl for system reboot +- relocation-entry : relocation address of secondary cpu boot code +- relocation-size : relocation size of secondary cpu boot code +- bootwrapper-phys : physical address of boot wrapper +- bootwrapper-size : size of boot wrapper +- bootwrapper-magic : magic number for secondary cpu in boot wrapper Example:
@@ -31,6 +40,7 @@ Example: reboot-offset = <0x4>; }; + PCTRL: Peripheral misc control register Required Properties:
Documentation/devicetree/bindings/clock/hip04-clock.txt new file +20 -0
@@ -0,0 +1,20 @@ +* Hisilicon HiP04 Clock Controller + +The HiP04 clock controller generates and supplies clock to various +controllers within the HiP04 SoC. + +Required Properties: + +- compatible: should be one of the following. + - "hisilicon,hip04-clock" - controller compatible with HiP04 SoC. + +- reg: physical base address of the controller and length of memory mapped + region. + +- #clock-cells: should be 1. + + +Each clock is assigned an identifier and client nodes use this identifier +to specify the clock which they consume. + +All these identifier could be found in <dt-bindings/clock/hip04-clock.h>.
arch/arm/boot/dts/Makefile +1 -0
@@ -80,6 +80,7 @@ dtb-$(CONFIG_ARCH_EXYNOS) += exynos4210-origen.dtb \ dtb-$(CONFIG_ARCH_HI3xxx) += hi3620-hi4511.dtb dtb-$(CONFIG_ARCH_HIGHBANK) += highbank.dtb \ ecx-2000.dtb +dtb-$(CONFIG_ARCH_HIP04) += hip04-d01.dtb dtb-$(CONFIG_ARCH_INTEGRATOR) += integratorap.dtb \ integratorcp.dtb dtb-$(CONFIG_ARCH_KEYSTONE) += k2hk-evm.dtb \
arch/arm/boot/dts/hip04-d01.dts new file +74 -0
74 lines not on this page · raw message
arch/arm/boot/dts/hip04.dtsi new file +239 -0
239 lines not on this page · raw message
Signature · 1 line
1.9.1
PATCH v4 9/14 ARM: dts: add hip04-d01 dts file
Hi,
Quoted 14 lines · Haojian Zhuang
Add
hip04.dtsi&hip04-d01.dtsfile to support HiP04 SoC platform.Signed-off-by Haojian Zhuang <[email protected]>--- Documentation/devicetree/bindings/arm/gic.txt | 1 + .../bindings/arm/hisilicon/hisilicon.txt | 10 + .../devicetree/bindings/clock/hip04-clock.txt | 20 ++ arch/arm/boot/dts/Makefile | 1 + arch/arm/boot/dts/hip04-d01.dts | 74 +++++++ arch/arm/boot/dts/hip04.dtsi | 239 +++++++++++++++++++++ 6 files changed, 345 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/hip04-clock.txt create mode 100644 arch/arm/boot/dts/hip04-d01.dts create mode 100644 arch/arm/boot/dts/hip04.dtsi
I would appreciate if you could split the binding and the DTS updates. The binding updates would be better associated with the code which implements support for them.
Documentation/devicetree/bindings/arm/gic.txt Main node required properties: · line 22
Quoted 13 lines
Documentation/devicetree/bindings/arm/gic.txt +1
-0@@ -16,6 +16,7 @@ Main node required properties: "arm,cortex-a9-gic" "arm,cortex-a7-gic" "arm,arm11mp-gic" + "hisilicon,hip04-gic" - interrupt-controller : Identifies the node as an interrupt controller - #interrupt-cells : Specifies the number of cells needed to encode an interrupt source. The type shall be a <u32> and the value shall be 3.
This looks ok, but would be better associated with the GIC driver update.
[...]
Quoted 17 lines
arch/arm/boot/dts/hip04-d01.dts new file +11
-0@@ -0,0 +1,74 @@ +/* + * Copyright (C) 2013-2014 Linaro Ltd. + * Author: Haojian Zhuang <[email protected]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * publishhed by the Free Software Foundation. + */ + +/dts-v1/; +
arch/arm/boot/dts/hip04-d01.dts line 21
Quoted 10 lines
arch/arm/boot/dts/hip04-d01.dts new file +10
-0+#include "hip04.dtsi" + +/ { + /* memory bus is 64-bit */ + #address-cells = <2>; + #size-cells = <1>; + model = "Hisilicon D01 Development Board"; + compatible = "hisilicon,hip04-d01"; + + memory at 0 {
This should be memory at 0,10000000 given the reg entry.
Please read my comments I posted back at v2 [1] regarding the dt, as far as I can see they all still apply. I've repeated a few below, but please refer to my original mail.
arch/arm/boot/dts/hip04-d01.dts line 30
Quoted 9 lines
arch/arm/boot/dts/hip04-d01.dts new file +9
-0+ device_type = "memory"; + /* + * Bootloader loads kernel image into 0x1000_0000 region, + * so disables the region between [0000_0000 - 1000_0000] + * temporarily. + * Because the PHYS_TO_VIRT_OFFSET is calculated based on + * the original region that kenrel is loaded. + * This workaround will be removed only after UEFI updated. + */
Is it necessary to lie to the kernel here?
If this inaccessible memory causes an issue it sounds like a generic problem we should be able to solve without lying to the kernel about the physical memory.
arch/arm/boot/dts/hip04-d01.dts line 34
Quoted 4 lines
arch/arm/boot/dts/hip04-d01.dts new file +4
-0+ reg = <0x00000000 0x10000000 0xc0000000>; + }; + + memory at 00000004c0000000 {
Please place a comma between cells in unit-addresses, it makes them easer to read (e.g. this should be memory at 00000004,c0000000).
Quoted 23 lines
arch/arm/boot/dts/hip04-d01.dts new file +23
-0+ device_type = "memory"; + reg = <0x00000004 0xc0000000 0x40000000>; + }; + + memory at 0000000500000000 { + device_type = "memory"; + reg = <0x00000005 0x00000000 0x80000000>; + }; + + memory at 0000000580000000 { + device_type = "memory"; + reg = <0x00000005 0x80000000 0x80000000>; + }; + + memory at 0000000600000000 { + device_type = "memory"; + reg = <0x00000006 0x00000000 0x80000000>; + }; + + memory at 0000000680000000 { + device_type = "memory"; + reg = <0x00000006 0x80000000 0x80000000>; + };
arch/arm/boot/dts/hip04-d01.dts line 67
Quoted 10 lines
arch/arm/boot/dts/hip04-d01.dts new file +10
-0+ + memory at 0000000700000000 { + device_type = "memory"; + reg = <0x00000007 0x00000000 0x80000000>; + }; + + memory at 0000000780000000 { + device_type = "memory"; + reg = <0x00000007 0x80000000 0x80000000>; + };
Is there any reason for describing these in separate nodes? You can place multiple reg entries in a memory node.
[...]
arch/arm/boot/dts/hip04-d01.dts line 72
Quoted 5 lines
arch/arm/boot/dts/hip04-d01.dts new file +5
-0+ soc { + /* It's a 32-bit SoC. */ + #address-cells = <1>; + #size-cells = <1>; + compatible = "arm,amba-bus", "simple-bus";
This should be one either an AMBA bus or a simple bus, not both.
arch/arm/boot/dts/hip04-d01.dts
Quoted 12 lines
arch/arm/boot/dts/hip04-d01.dts new file +12
-0+ device_type = "soc"; + interrupt-parent = <&gic>; + ranges = <0 0 0xe0000000 0x10000000>; + + gic: interrupt-controller at c01000 { + compatible = "hisilicon,hip04-gic"; + #interrupt-cells = <3>; + #address-cells = <0>; + interrupt-controller; + interrupts = <1 9 0xf04>; + + /* gic dist base, gic cpu base */
And hyp and virt, as there seem to be 4 entries?
Quoted 3 lines
arch/arm/boot/dts/hip04-d01.dts new file +3
-0+ reg = <0xc01000 0x1000>, <0xc02000 0x1000>, + <0xc04000 0x2000>, <0xc06000 0x2000>; + };
[...]
arch/arm/boot/dts/hip04-d01.dts
Quoted 4 lines
arch/arm/boot/dts/hip04-d01.dts new file +4
-0+ clock: clock { + compatible = "hisilicon,hip04-clock"; + /* dummy register */ + reg = <0 0x1000>;
Huh?
Cheers,
Mark.
[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2014-April/246053.html
PATCH v4 9/14 ARM: dts: add hip04-d01 dts file
In reply to Haojian ZhuangQuoted 127 lines · Haojian Zhuang
Add
hip04.dtsi&hip04-d01.dtsfile to support HiP04 SoC platform.Signed-off-by Haojian Zhuang <[email protected]>--- Documentation/devicetree/bindings/arm/gic.txt | 1 + .../bindings/arm/hisilicon/hisilicon.txt | 10 + .../devicetree/bindings/clock/hip04-clock.txt | 20 ++ arch/arm/boot/dts/Makefile | 1 + arch/arm/boot/dts/hip04-d01.dts | 74 +++++++ arch/arm/boot/dts/hip04.dtsi | 239 +++++++++++++++++++++ 6 files changed, 345 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/hip04-clock.txt create mode 100644 arch/arm/boot/dts/hip04-d01.dts create mode 100644 arch/arm/boot/dts/hip04.dtsiDocumentation/devicetree/bindings/arm/gic.txt +1
-0@@ -16,6 +16,7 @@ Main node required properties: "arm,cortex-a9-gic" "arm,cortex-a7-gic" "arm,arm11mp-gic" + "hisilicon,hip04-gic" - interrupt-controller : Identifies the node as an interrupt controller - #interrupt-cells : Specifies the number of cells needed to encode an interrupt source. The type shall be a <u32> and the value shall be 3.Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt +10
-0@@ -4,6 +4,10 @@ Hisilicon Platforms Device Tree Bindings Hi4511 Board Required root node properties: - compatible = "hisilicon,hi3620-hi4511"; +HiP04 D01 Board +Required root node properties: + - compatible = "hisilicon,hip04-d01"; + Hisilicon system controller@@ -19,6 +23,11 @@ Optional properties: If reg value is not zero, cpun exit wfi and go - resume-offset : offset in sysctrl for notifying cpu0 when resume - reboot-offset : offset in sysctrl for system reboot +- relocation-entry : relocation address of secondary cpu boot code +- relocation-size : relocation size of secondary cpu boot code +- bootwrapper-phys : physical address of boot wrapper +- bootwrapper-size : size of boot wrapper +- bootwrapper-magic : magic number for secondary cpu in boot wrapper Example:@@ -31,6 +40,7 @@ Example: reboot-offset = <0x4>; }; + PCTRL: Peripheral misc control register Required Properties:Documentation/devicetree/bindings/clock/hip04-clock.txt new file +20
-0@@ -0,0 +1,20 @@ +* Hisilicon HiP04 Clock Controller + +The HiP04 clock controller generates and supplies clock to various +controllers within the HiP04 SoC. + +Required Properties: + +- compatible: should be one of the following. + - "hisilicon,hip04-clock" - controller compatible with HiP04 SoC. + +- reg: physical base address of the controller and length of memory mapped + region. + +- #clock-cells: should be 1. + + +Each clock is assigned an identifier and client nodes use this identifier +to specify the clock which they consume. + +All these identifier could be found in <dt-bindings/clock/hip04-clock.h>.arch/arm/boot/dts/Makefile +1
-0@@ -80,6 +80,7 @@ dtb-$(CONFIG_ARCH_EXYNOS) += exynos4210-origen.dtb \ dtb-$(CONFIG_ARCH_HI3xxx) += hi3620-hi4511.dtb dtb-$(CONFIG_ARCH_HIGHBANK) += highbank.dtb \ ecx-2000.dtb +dtb-$(CONFIG_ARCH_HIP04) += hip04-d01.dtb dtb-$(CONFIG_ARCH_INTEGRATOR) += integratorap.dtb \ integratorcp.dtb dtb-$(CONFIG_ARCH_KEYSTONE) += k2hk-evm.dtb \arch/arm/boot/dts/hip04-d01.dts new file +21
-0@@ -0,0 +1,74 @@ +/* + * Copyright (C) 2013-2014 Linaro Ltd. + * Author: Haojian Zhuang <[email protected]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * publishhed by the Free Software Foundation. + */ + +/dts-v1/; + +#include "hip04.dtsi" + +/ { + /* memory bus is 64-bit */ + #address-cells = <2>; + #size-cells = <1>; + model = "Hisilicon D01 Development Board"; + compatible = "hisilicon,hip04-d01"; + + memory at 0 {
arch/arm/boot/dts/hip04-d01.dts line 31
Quoted 10 lines
arch/arm/boot/dts/hip04-d01.dts new file +10
-0+ device_type = "memory"; + /* + * Bootloader loads kernel image into 0x1000_0000 region, + * so disables the region between [0000_0000 - 1000_0000] + * temporarily. + * Because the PHYS_TO_VIRT_OFFSET is calculated based on + * the original region that kenrel is loaded. + * This workaround will be removed only after UEFI updated. + */ + reg = <0x00000000 0x10000000 0xc0000000>;
This memory ends at 0xcfffffff which looks a bit odd. It suggests that there is 3.25 GiB of low memory. Is this correct?
There seems to be nothing in the range 0xd0000000..0xdfffffff.
Quoted 1 line
From the "soc" node's ranges, I'm guessing I/O starts at
0xe0000000.
Quoted 232 lines
arch/arm/boot/dts/hip04-d01.dts new file +43
-0+ }; + + memory at 00000004c0000000 { + device_type = "memory"; + reg = <0x00000004 0xc0000000 0x40000000>; + }; + + memory at 0000000500000000 { + device_type = "memory"; + reg = <0x00000005 0x00000000 0x80000000>; + }; + + memory at 0000000580000000 { + device_type = "memory"; + reg = <0x00000005 0x80000000 0x80000000>; + }; + + memory at 0000000600000000 { + device_type = "memory"; + reg = <0x00000006 0x00000000 0x80000000>; + }; + + memory at 0000000680000000 { + device_type = "memory"; + reg = <0x00000006 0x80000000 0x80000000>; + }; + + memory at 0000000700000000 { + device_type = "memory"; + reg = <0x00000007 0x00000000 0x80000000>; + }; + + memory at 0000000780000000 { + device_type = "memory"; + reg = <0x00000007 0x80000000 0x80000000>; + }; + + soc { + uart0: uart at 4007000 { + status = "ok"; + }; + }; +};arch/arm/boot/dts/hip04.dtsi new file +183
-0@@ -0,0 +1,239 @@ +/* + * Hisilicon Ltd. HiP01 SoC + * + * Copyright (C) 2013-2014 Hisilicon Ltd. + * Copyright (C) 2013-2014 Linaro Ltd. + * + * Author: Haojian Zhuang <[email protected]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * publishhed by the Free Software Foundation. + */ + +#include <dt-bindings/clock/hip04-clock.h> + +/ { + /* memory bus is 64-bit */ + #address-cells = <2>; + #size-cells = <1>; + + aliases { + serial0 = &uart0; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu-map { + cluster0 { + core0 { + cpu = <&CPU0>; + }; + core1 { + cpu = <&CPU1>; + }; + core2 { + cpu = <&CPU2>; + }; + core3 { + cpu = <&CPU3>; + }; + }; + cluster1 { + core0 { + cpu = <&CPU4>; + }; + core1 { + cpu = <&CPU5>; + }; + core2 { + cpu = <&CPU6>; + }; + core3 { + cpu = <&CPU7>; + }; + }; + cluster2 { + core0 { + cpu = <&CPU8>; + }; + core1 { + cpu = <&CPU9>; + }; + core2 { + cpu = <&CPU10>; + }; + core3 { + cpu = <&CPU11>; + }; + }; + cluster3 { + core0 { + cpu = <&CPU12>; + }; + core1 { + cpu = <&CPU13>; + }; + core2 { + cpu = <&CPU14>; + }; + core3 { + cpu = <&CPU15>; + }; + }; + }; + CPU0: cpu at 0 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <0>; + }; + CPU1: cpu at 1 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <1>; + }; + CPU2: cpu at 2 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <2>; + }; + CPU3: cpu at 3 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <3>; + }; + CPU4: cpu at 100 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <0x100>; + }; + CPU5: cpu at 101 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <0x101>; + }; + CPU6: cpu at 102 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <0x102>; + }; + CPU7: cpu at 103 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <0x103>; + }; + CPU8: cpu at 200 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <0x200>; + }; + CPU9: cpu at 201 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <0x201>; + }; + CPU10: cpu at 202 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <0x202>; + }; + CPU11: cpu at 203 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <0x203>; + }; + CPU12: cpu at 300 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <0x300>; + }; + CPU13: cpu at 301 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <0x301>; + }; + CPU14: cpu at 302 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <0x302>; + }; + CPU15: cpu at 303 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <0x303>; + }; + }; + + soc { + /* It's a 32-bit SoC. */ + #address-cells = <1>; + #size-cells = <1>; + compatible = "arm,amba-bus", "simple-bus"; + device_type = "soc"; + interrupt-parent = <&gic>; + ranges = <0 0 0xe0000000 0x10000000>; + + gic: interrupt-controller at c01000 { + compatible = "hisilicon,hip04-gic"; + #interrupt-cells = <3>; + #address-cells = <0>; + interrupt-controller; + interrupts = <1 9 0xf04>;
arch/arm/boot/dts/hip04.dtsi line 193
Quoted 10 lines
arch/arm/boot/dts/hip04.dtsi new file +10
-0+ + /* gic dist base, gic cpu base */ + reg = <0xc01000 0x1000>, <0xc02000 0x1000>, + <0xc04000 0x2000>, <0xc06000 0x2000>; + }; + + sysctrl: sysctrl { + compatible = "hisilicon,sysctrl"; + reg = <0x3e00000 0x00100000>; + relocation-entry = <0xe0000100>;
This refers to an absolute address, which is a bit strange: we are inside /soc here, so it may make more sense to describe relative to /soc's address space.
relocation-entry seems to point to a location in side /soc/clock's reg property (?) What is really there?
arch/arm/boot/dts/hip04.dtsi line 197
Quoted 4 lines
arch/arm/boot/dts/hip04.dtsi new file +4
-0+ relocation-size = <0x1000>; + bootwrapper-phys = <0x10c00000>; + bootwrapper-size = <0x10000>; + bootwrapper-magic = <0xa5a5a5a5>;
Are these really handled by the system controller directly, or are they handled by firmware or boot code? If they are handled by firmware or boot code, I think these should be separated out: you could have a separate node and binding descrbing the interface to the resident firmware or boot code.
Also, bootwrapper-size doesn't appear to be used except for calling memblock_reserve().
Is there a risk that it is already too late to reserve that memory by the time hip04_mcpm_init is called? I'm not sure exactly what allocations happen before the early initcalls.
The alternative would be to put a /memreserve/ directly in the DT.
Quoted 14 lines
arch/arm/boot/dts/hip04.dtsi new file +14
-0+ }; + + fabric: fabric { + compatible = "hisilicon,hip04-fabric"; + reg = <0x302a000 0x1000>; + }; + + clock: clock { + compatible = "hisilicon,hip04-clock"; + /* dummy register */ + reg = <0 0x1000>; + #clock-cells = <1>; + }; +
arch/arm/boot/dts/hip04.dtsi line 221
Quoted 10 lines
arch/arm/boot/dts/hip04.dtsi new file +10
-0+ dual_timer0: dual_timer at 3000000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x3000000 0x1000>; + interrupts = <0 224 4>; + clocks = <&clock HIP04_CLK_50M>; + clock-names = "apb_pclk"; + status = "ok"; + }; + + timer {
Possibly this should be in /, not /soc. /soc describes a memory-mapped bus, but the architected timer is not memory-mapped.
Mark might have a view on that. If you do move it, you will need a correct interrupt-parent property pointing to the GIC.
Quoted 5 lines
arch/arm/boot/dts/hip04.dtsi new file +5
-0+ compatible = "arm,armv7-timer"; + interrupts = <1 13 0xf08>, + <1 14 0xf08>, + <1 11 0xf08>, + <1 10 0xf08>;
arch/arm/boot/dts/hip04.dtsi line 236
Quoted 10 lines
arch/arm/boot/dts/hip04.dtsi new file +10
-0+ }; + + uart0: uart at 4007000 { + compatible = "snps,dw-apb-uart"; + reg = <0x4007000 0x1000>; + interrupts = <0 381 4>; + clocks = <&clock HIP04_CLK_168M>; + clock-names = "uartclk"; + reg-shift = <2>; + status = "disabled";
Out of interest, why is this disabled?
Cheers
---Dave
PATCH v4 9/14 ARM: dts: add hip04-d01 dts file
In reply to Haojian ZhuangQuoted 43 lines · Haojian Zhuang
Add
hip04.dtsi&hip04-d01.dtsfile to support HiP04 SoC platform.Signed-off-by Haojian Zhuang <[email protected]>--- Documentation/devicetree/bindings/arm/gic.txt | 1 + .../bindings/arm/hisilicon/hisilicon.txt | 10 + .../devicetree/bindings/clock/hip04-clock.txt | 20 ++ arch/arm/boot/dts/Makefile | 1 + arch/arm/boot/dts/hip04-d01.dts | 74 +++++++ arch/arm/boot/dts/hip04.dtsi | 239 +++++++++++++++++++++ 6 files changed, 345 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/hip04-clock.txt create mode 100644 arch/arm/boot/dts/hip04-d01.dts create mode 100644 arch/arm/boot/dts/hip04.dtsiDocumentation/devicetree/bindings/arm/gic.txt +1
-0@@ -16,6 +16,7 @@ Main node required properties: "arm,cortex-a9-gic" "arm,cortex-a7-gic" "arm,arm11mp-gic" + "hisilicon,hip04-gic" - interrupt-controller : Identifies the node as an interrupt controller - #interrupt-cells : Specifies the number of cells needed to encode an interrupt source. The type shall be a <u32> and the value shall be 3.Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt +4
-0@@ -4,6 +4,10 @@ Hisilicon Platforms Device Tree Bindings Hi4511 Board Required root node properties: - compatible = "hisilicon,hi3620-hi4511"; +HiP04 D01 Board +Required root node properties: + - compatible = "hisilicon,hip04-d01"; + Hisilicon system controller
Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt Optional properties: · line 30
Quoted 8 lines
Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt +5
-0@@ -19,6 +23,11 @@ Optional properties: If reg value is not zero, cpun exit wfi and go - resume-offset : offset in sysctrl for notifying cpu0 when resume - reboot-offset : offset in sysctrl for system reboot +- relocation-entry : relocation address of secondary cpu boot code +- relocation-size : relocation size of secondary cpu boot code +- bootwrapper-phys : physical address of boot wrapper +- bootwrapper-size : size of boot wrapper +- bootwrapper-magic : magic number for secondary cpu in boot wrapper
These need better descriptions.
Can bootwrapper just use /memreserve/?
Quoted 112 lines
Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt +1
-0Example:@@ -31,6 +40,7 @@ Example: reboot-offset = <0x4>; }; + PCTRL: Peripheral misc control register Required Properties:Documentation/devicetree/bindings/clock/hip04-clock.txt new file +20
-0@@ -0,0 +1,20 @@ +* Hisilicon HiP04 Clock Controller + +The HiP04 clock controller generates and supplies clock to various +controllers within the HiP04 SoC. + +Required Properties: + +- compatible: should be one of the following. + - "hisilicon,hip04-clock" - controller compatible with HiP04 SoC. + +- reg: physical base address of the controller and length of memory mapped + region. + +- #clock-cells: should be 1. + + +Each clock is assigned an identifier and client nodes use this identifier +to specify the clock which they consume. + +All these identifier could be found in <dt-bindings/clock/hip04-clock.h>.arch/arm/boot/dts/Makefile +1
-0@@ -80,6 +80,7 @@ dtb-$(CONFIG_ARCH_EXYNOS) += exynos4210-origen.dtb \ dtb-$(CONFIG_ARCH_HI3xxx) += hi3620-hi4511.dtb dtb-$(CONFIG_ARCH_HIGHBANK) += highbank.dtb \ ecx-2000.dtb +dtb-$(CONFIG_ARCH_HIP04) += hip04-d01.dtb dtb-$(CONFIG_ARCH_INTEGRATOR) += integratorap.dtb \ integratorcp.dtb dtb-$(CONFIG_ARCH_KEYSTONE) += k2hk-evm.dtb \arch/arm/boot/dts/hip04-d01.dts new file +57
-0@@ -0,0 +1,74 @@ +/* + * Copyright (C) 2013-2014 Linaro Ltd. + * Author: Haojian Zhuang <[email protected]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * publishhed by the Free Software Foundation. + */ + +/dts-v1/; + +#include "hip04.dtsi" + +/ { + /* memory bus is 64-bit */ + #address-cells = <2>; + #size-cells = <1>; + model = "Hisilicon D01 Development Board"; + compatible = "hisilicon,hip04-d01"; + + memory at 0 { + device_type = "memory"; + /* + * Bootloader loads kernel image into 0x1000_0000 region, + * so disables the region between [0000_0000 - 1000_0000] + * temporarily. + * Because the PHYS_TO_VIRT_OFFSET is calculated based on + * the original region that kenrel is loaded. + * This workaround will be removed only after UEFI updated. + */ + reg = <0x00000000 0x10000000 0xc0000000>; + }; + + memory at 00000004c0000000 { + device_type = "memory"; + reg = <0x00000004 0xc0000000 0x40000000>; + }; + + memory at 0000000500000000 { + device_type = "memory"; + reg = <0x00000005 0x00000000 0x80000000>; + }; + + memory at 0000000580000000 { + device_type = "memory"; + reg = <0x00000005 0x80000000 0x80000000>; + }; + + memory at 0000000600000000 { + device_type = "memory"; + reg = <0x00000006 0x00000000 0x80000000>; + }; + + memory at 0000000680000000 { + device_type = "memory"; + reg = <0x00000006 0x80000000 0x80000000>; + };
arch/arm/boot/dts/hip04-d01.dts line 67
Quoted 10 lines
arch/arm/boot/dts/hip04-d01.dts new file +10
-0+ + memory at 0000000700000000 { + device_type = "memory"; + reg = <0x00000007 0x00000000 0x80000000>; + }; + + memory at 0000000780000000 { + device_type = "memory"; + reg = <0x00000007 0x80000000 0x80000000>; + };
Am I missing something or isn't this just a single region of:
<0x4 0xc0000000 0x3 0x40000000>
[...]
arch/arm/boot/dts/hip04-d01.dts line 72
Quoted 5 lines
arch/arm/boot/dts/hip04-d01.dts new file +5
-0+ soc { + /* It's a 32-bit SoC. */ + #address-cells = <1>; + #size-cells = <1>; + compatible = "arm,amba-bus", "simple-bus";
Drop arm,amba-bus.
arch/arm/boot/dts/hip04-d01.dts line 73
Quoted 1 line
arch/arm/boot/dts/hip04-d01.dts new file +1
-0+ device_type = "soc";
Huh? remove.
Quoted 17 lines
arch/arm/boot/dts/hip04-d01.dts new file +17
-0+ interrupt-parent = <&gic>; + ranges = <0 0 0xe0000000 0x10000000>; + + gic: interrupt-controller at c01000 { + compatible = "hisilicon,hip04-gic"; + #interrupt-cells = <3>; + #address-cells = <0>; + interrupt-controller; + interrupts = <1 9 0xf04>; + + /* gic dist base, gic cpu base */ + reg = <0xc01000 0x1000>, <0xc02000 0x1000>, + <0xc04000 0x2000>, <0xc06000 0x2000>; + }; + + sysctrl: sysctrl { + compatible = "hisilicon,sysctrl";
arch/arm/boot/dts/hip04-d01.dts
Quoted 10 lines
arch/arm/boot/dts/hip04-d01.dts new file +10
-0+ reg = <0x3e00000 0x00100000>; + relocation-entry = <0xe0000100>; + relocation-size = <0x1000>; + bootwrapper-phys = <0x10c00000>; + bootwrapper-size = <0x10000>; + bootwrapper-magic = <0xa5a5a5a5>; + }; + + fabric: fabric { + compatible = "hisilicon,hip04-fabric";
documentation?
arch/arm/boot/dts/hip04-d01.dts
Quoted 6 lines
arch/arm/boot/dts/hip04-d01.dts new file +6
-0+ reg = <0x302a000 0x1000>; + }; + + clock: clock { + compatible = "hisilicon,hip04-clock"; + /* dummy register */
What does that mean? Please fill in valid information.
arch/arm/boot/dts/hip04-d01.dts
Quoted 11 lines
arch/arm/boot/dts/hip04-d01.dts new file +11
-0+ reg = <0 0x1000>; + #clock-cells = <1>; + }; + + dual_timer0: dual_timer at 3000000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x3000000 0x1000>; + interrupts = <0 224 4>; + clocks = <&clock HIP04_CLK_50M>; + clock-names = "apb_pclk"; + status = "ok";
Not needed.
Quoted 29 lines
arch/arm/boot/dts/hip04-d01.dts new file +21
-1+ }; + + timer { + compatible = "arm,armv7-timer"; + interrupts = <1 13 0xf08>, + <1 14 0xf08>, + <1 11 0xf08>, + <1 10 0xf08>; + }; + + uart0: uart at 4007000 { + compatible = "snps,dw-apb-uart"; + reg = <0x4007000 0x1000>; + interrupts = <0 381 4>; + clocks = <&clock HIP04_CLK_168M>; + clock-names = "uartclk"; + reg-shift = <2>; + status = "disabled"; + }; + }; +}; --1.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
PATCH v4 10/14 ARM: config: append hip04_defconfig
In reply to Haojian ZhuangSelect HiP04 SoC configuration by hip04_defconfig.
--- arch/arm/configs/hip04_defconfig | 74 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 arch/arm/configs/hip04_defconfig
arch/arm/configs/hip04_defconfig new file +74 -0
@@ -0,0 +1,74 @@ +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +CONFIG_IRQ_DOMAIN_DEBUG=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_RD_GZIP=y +# CONFIG_ARCH_MULTI_V6 is not set +# CONFIG_ARCH_MULTI_V7 is not set +CONFIG_ARCH_MULTI_V7_LPAE=y +CONFIG_ARCH_HISI=y +CONFIG_ARCH_HIP04=y +CONFIG_SMP=y +CONFIG_NR_CPUS=16 +CONFIG_MCPM=y +CONFIG_MCPM_QUAD_CLUSTER=y +CONFIG_PREEMPT=y +CONFIG_AEABI=y +CONFIG_ARM_APPENDED_DTB=y +CONFIG_ARM_ATAG_DTB_COMPAT=y +CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER=y +CONFIG_HIGHMEM=y +CONFIG_VFP=y +CONFIG_NEON=y +CONFIG_NET=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_BLK_DEV=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_LOOP_MIN_COUNT=8 +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_SD=y +CONFIG_ATA=y +CONFIG_SATA_AHCI_PLATFORM=y +CONFIG_NETDEVICES=y +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=2 +CONFIG_SERIAL_8250_RUNTIME_UARTS=2 +CONFIG_SERIAL_8250_DW=y +CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_I2C_DESIGNWARE_PLATFORM=y +CONFIG_PINCTRL_SINGLE=y +CONFIG_GPIO_GENERIC_PLATFORM=y +CONFIG_REGULATOR_GPIO=y +CONFIG_DRM=y +CONFIG_FB_SIMPLE=y +CONFIG_RTC_CLASS=y +CONFIG_EXT4_FS=y +CONFIG_TMPFS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_ROOT_NFS=y +CONFIG_PRINTK_TIME=y +CONFIG_DEBUG_FS=y +CONFIG_DEBUG_KERNEL=y +CONFIG_DEBUG_LL=y +CONFIG_DEBUG_UART_8250=y +CONFIG_EARLY_PRINTK=y +CONFIG_LOCKUP_DETECTOR=y +CONFIG_DEBUG_USER=y +CONFIG_VIRTUALIZATION=y +CONFIG_KVM=y +CONFIG_KVM_ARM_HOST=y +CONFIG_KVM_ARM_MAX_VCPUS=4 +CONFIG_KVM_ARM_VGIC=y
Signature · 1 line
1.9.1
PATCH v4 11/14 ARM: config: select ARCH_HISI in hi3xxx_defconfig
In reply to Haojian ZhuangSince ARCH_HISI is added as common configuration of both ARCH_HI3xxx and ARCH_HIP04, update it into hi3xxx_defconfig.
--- arch/arm/configs/hi3xxx_defconfig | 2 ++ 1 file changed, 2 insertions(+)
arch/arm/configs/hi3xxx_defconfig +2 -0
@@ -3,10 +3,12 @@ CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_BLK_DEV_INITRD=y CONFIG_RD_LZMA=y +CONFIG_ARCH_HISI=y CONFIG_ARCH_HI3xxx=y CONFIG_SMP=y CONFIG_PREEMPT=y CONFIG_AEABI=y +CONFIG_HIGHMEM=y CONFIG_ARM_APPENDED_DTB=y CONFIG_NET=y CONFIG_UNIX=y
Signature · 1 line
1.9.1
PATCH v4 12/14 ARM: hisi: enable erratum 798181 of A15 on HiP04
In reply to Haojian ZhuangFrom: Kefeng Wang <[email protected]>
The commit 93dc688 (ARM: 7684/1: errata: Workaround for Cortex-A15 erratum 798181 (TLBI/DSB operations)) introduced a workaround for Cortex-A15 erratum 798181. Enable it for HIP04(Cortex-a15 r3p2).
--- arch/arm/mach-hisi/Kconfig | 1 + 1 file changed, 1 insertion(+)
arch/arm/mach-hisi/Kconfig +1 -0
@@ -21,6 +21,7 @@ config ARCH_HI3xxx config ARCH_HIP04 bool "Hisilicon HiP04 Cortex A15 family" if ARCH_MULTI_V7_LPAE + select ARM_ERRATA_798181 if SMP select HAVE_ARM_ARCH_TIMER select MCPM if SMP select MCPM_QUAD_CLUSTER if SMP
Signature · 1 line
1.9.1
PATCH v4 13/14 ARM: dts: Add PMU support in HiP04
In reply to Haojian ZhuangFrom: Kefeng Wang <[email protected]>
ARM Performance Monitor Units are available on the HiP04. So add the support in the dtsi.
Simply tested with perf.
--- arch/arm/boot/dts/hip04.dtsi | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+)
arch/arm/boot/dts/hip04.dtsi +20 -0
@@ -218,6 +218,26 @@ status = "ok"; }; + arm-pmu { + compatible = "arm,cortex-a15-pmu"; + interrupts = <0 64 4>, + <0 65 4>, + <0 66 4>, + <0 67 4>, + <0 68 4>, + <0 69 4>, + <0 70 4>, + <0 71 4>, + <0 72 4>, + <0 73 4>, + <0 74 4>, + <0 75 4>, + <0 76 4>, + <0 77 4>, + <0 78 4>, + <0 79 4>; + }; + timer { compatible = "arm,armv7-timer"; interrupts = <1 13 0xf08>,
Signature · 1 line
1.9.1
PATCH v4 14/14 virt: arm: support hip04 gic
In reply to Haojian ZhuangIn ARM standard GIC, GICH_APR offset is 0xf0 & GICH_LR0 offset is 0x100. In HiP04 GIC, GICH_APR offset is 0x70 & GICH_LR0 offset is 0x80. So add the support of HiP04 SoC in VGIC.
--- arch/arm/kvm/interrupts_head.S | 24 ++++++++++++++++++++---- include/linux/irqchip/arm-gic.h | 3 +++ virt/kvm/arm/vgic.c | 15 ++++++++++++++- 3 files changed, 37 insertions(+), 5 deletions(-)
arch/arm/kvm/interrupts_head.S +20 -4
@@ -419,7 +419,9 @@ vcpu .req r0 @ vcpu pointer always in r0 ldr r7, [r2, #GICH_EISR1] ldr r8, [r2, #GICH_ELRSR0] ldr r9, [r2, #GICH_ELRSR1] - ldr r10, [r2, #GICH_APR] + ldr r10, =gich_apr + ldr r10, [r10] + ldr r10, [r2, r10] str r3, [r11, #VGIC_CPU_HCR] str r4, [r11, #VGIC_CPU_VMCR]
@@ -435,7 +437,11 @@ vcpu .req r0 @ vcpu pointer always in r0 str r5, [r2, #GICH_HCR] /* Save list registers */ - add r2, r2, #GICH_LR0 + ldr r10, =gich_apr + ldr r10, [r10] + /* the offset between GICH_APR & GICH_LR0 is 0x10 */ + add r10, r10, #0x10 + add r2, r2, r10 add r3, r11, #VGIC_CPU_LR ldr r4, [r11, #VGIC_CPU_NR_LR] 1: ldr r6, [r2], #4
@@ -469,10 +475,16 @@ vcpu .req r0 @ vcpu pointer always in r0 str r3, [r2, #GICH_HCR] str r4, [r2, #GICH_VMCR] - str r8, [r2, #GICH_APR] + ldr r6, =gich_apr + ldr r6, [r6] + str r8, [r2, r6] /* Restore list registers */ - add r2, r2, #GICH_LR0 + ldr r6, =gich_apr + ldr r6, [r6] + /* the offset between GICH_APR & GICH_LR0 is 0x10 */ + add r6, r6, #0x10 + add r2, r2, r6 add r3, r11, #VGIC_CPU_LR ldr r4, [r11, #VGIC_CPU_NR_LR] 1: ldr r6, [r3], #4
@@ -618,3 +630,7 @@ vcpu .req r0 @ vcpu pointer always in r0 .macro load_vcpu mrc p15, 4, vcpu, c13, c0, 2 @ HTPIDR .endm + + .global gich_apr +gich_apr: + .long GICH_APR
include/linux/irqchip/arm-gic.h +3 -0
@@ -49,6 +49,8 @@#define GICH_ELRSR1 0x34#define GICH_APR 0xf0#define GICH_LR0 0x100 +#define HIP04_GICH_APR 0x70 +/* GICH_LR0 offset in HiP04 is 0x80 */ #define GICH_HCR_EN (1 << 0)#define GICH_HCR_UIE (1 << 1)
@@ -78,6 +80,7 @@struct device_node ;extern struct irq_chip gic_arch_extn; +extern unsigned int gich_apr;void gic_init_bases (unsigned int ,int ,void __iomem *,void __iomem *,u32 offset,struct device_node *);
virt/kvm/arm/vgic.c +14 -1
@@ -1470,17 +1470,30 @@ static struct notifier_block vgic_cpu_nb = { .notifier_call = vgic_cpu_notify, }; +static const struct of_device_id of_vgic_ids[] = { + { + .compatible ="arm,cortex-a15-gic" , + .data = (void *)GICH_APR , + }, { + .compatible ="hisilicon,hip04-gic" , + .data = (void *)HIP04_GICH_APR , + }, { + }, +}; +int kvm_vgic_hyp_init (void ) {int ret;struct resource vctrl_res;struct resource vcpu_res; +const struct of_device_id *match; - vgic_node =of_find_compatible_node (NULL ,NULL ,"arm,cortex-a15-gic" ); + vgic_node =of_find_matching_node_and_match (NULL , of_vgic_ids, &match);if (!vgic_node) {kvm_err ("error: no compatible vgic node in DT\n" );return -ENODEV ; } + gich_apr = (unsigned int )match->data; vgic_maint_irq =irq_of_parse_and_map (vgic_node,0 );if (!vgic_maint_irq) {
Signature · 1 line
1.9.1
PATCH v4 14/14 virt: arm: support hip04 gic
Quoted 16 lines · Haojian Zhuang
In ARM standard GIC,
GICH_APRoffset is0xf0&GICH_LR0offset is0x100. In HiP04 GIC,GICH_APRoffset is0x70&GICH_LR0offset is0x80. So add the support of HiP04 SoC in VGIC.Signed-off-by Haojian Zhuang <[email protected]>--- arch/arm/kvm/interrupts_head.S | 24 ++++++++++++++++++++---- include/linux/irqchip/arm-gic.h | 3 +++ virt/kvm/arm/vgic.c | 15 ++++++++++++++- 3 files changed, 37 insertions(+), 5 deletions(-)arch/arm/kvm/interrupts_head.S +0
-0
arch/arm/kvm/interrupts_head.S vcpu .req r0 @ vcpu pointer always in r0 · line 424
Quoted 7 lines
arch/arm/kvm/interrupts_head.S +3
-1@@ -419,7 +419,9 @@ vcpu .req r0 @ vcpu pointer always in r0 ldr r7, [r2, #GICH_EISR1] ldr r8, [r2, #GICH_ELRSR0] ldr r9, [r2, #GICH_ELRSR1] - ldr r10, [r2, #GICH_APR] + ldr r10, =gich_apr + ldr r10, [r10] + ldr r10, [r2, r10]
I think you slightly missed the point of my earlier review. I don't want to see another variable containing this offset. We already have nr_lr, and I'd like you to combine this offset into the same field. Use the bottom bits for the number of list registers, and the top bits for the offset. You can then use a bit manipulation instruction to extract the information you want. Rename the field to something sensible like hw_config.
Quoted 86 lines
arch/arm/kvm/interrupts_head.S +17
-3str r3, [r11, #VGIC_CPU_HCR] str r4, [r11, #VGIC_CPU_VMCR]@@ -435,7 +437,11 @@ vcpu .req r0 @ vcpu pointer always in r0 str r5, [r2, #GICH_HCR] /* Save list registers */ - add r2, r2, #GICH_LR0 + ldr r10, =gich_apr + ldr r10, [r10] + /* the offset between GICH_APR & GICH_LR0 is 0x10 */ + add r10, r10, #0x10 + add r2, r2, r10 add r3, r11, #VGIC_CPU_LR ldr r4, [r11, #VGIC_CPU_NR_LR] 1: ldr r6, [r2], #4@@ -469,10 +475,16 @@ vcpu .req r0 @ vcpu pointer always in r0 str r3, [r2, #GICH_HCR] str r4, [r2, #GICH_VMCR] - str r8, [r2, #GICH_APR] + ldr r6, =gich_apr + ldr r6, [r6] + str r8, [r2, r6] /* Restore list registers */ - add r2, r2, #GICH_LR0 + ldr r6, =gich_apr + ldr r6, [r6] + /* the offset between GICH_APR & GICH_LR0 is 0x10 */ + add r6, r6, #0x10 + add r2, r2, r6 add r3, r11, #VGIC_CPU_LR ldr r4, [r11, #VGIC_CPU_NR_LR] 1: ldr r6, [r3], #4@@ -618,3 +630,7 @@ vcpu .req r0 @ vcpu pointer always in r0 .macro load_vcpu mrc p15, 4, vcpu, c13, c0, 2 @ HTPIDR .endm + + .global gich_apr +gich_apr: + .long GICH_APRinclude/linux/irqchip/arm-gic.h +3
-0@@ -49,6 +49,8 @@#define GICH_ELRSR1 0x34#define GICH_APR 0xf0#define GICH_LR0 0x100 +#define HIP04_GICH_APR 0x70 +/* GICH_LR0 offset in HiP04 is 0x80 */ #define GICH_HCR_EN (1 << 0)#define GICH_HCR_UIE (1 << 1)@@ -78,6 +80,7 @@struct device_node ;extern struct irq_chip gic_arch_extn; +extern unsigned int gich_apr;void gic_init_bases (unsigned int ,int ,void __iomem *,void __iomem *,u32 offset,struct device_node *);virt/kvm/arm/vgic.c +11
-0@@ -1470,17 +1470,30 @@ static struct notifier_block vgic_cpu_nb = { .notifier_call = vgic_cpu_notify, }; +static const struct of_device_id of_vgic_ids[] = { + { + .compatible ="arm,cortex-a15-gic" , + .data = (void *)GICH_APR , + }, { + .compatible ="hisilicon,hip04-gic" , + .data = (void *)HIP04_GICH_APR , + }, { + }, +}; +int kvm_vgic_hyp_init (void ) {int ret;
virt/kvm/arm/vgic.c static struct notifier_block vgic_cpu_nb = { · line 1495
Quoted 10 lines
virt/kvm/arm/vgic.c +2
-1struct resource vctrl_res;struct resource vcpu_res; +const struct of_device_id *match; - vgic_node =of_find_compatible_node (NULL ,NULL ,"arm,cortex-a15-gic" ); + vgic_node =of_find_matching_node_and_match (NULL , of_vgic_ids, &match);if (!vgic_node) {kvm_err ("error: no compatible vgic node in DT\n" );return -ENODEV ; }
This looks much better.
virt/kvm/arm/vgic.c static struct notifier_block vgic_cpu_nb = { · line 1499
Quoted 4 lines
virt/kvm/arm/vgic.c +1
-0+ gich_apr = (unsigned int )match->data; vgic_maint_irq =irq_of_parse_and_map (vgic_node,0 );if (!vgic_maint_irq) {
Thanks,
M.
Signature · 1 line
Jazz is not dead. It just smells funny.