enable HiP04 SoC
Subsystems (9)
v5 cover enable HiP04 SoC
Changelog:
v5:
* Add ARCH_MULTI_V7_NONLPAE to avoid change too much things in Kconfig.
* Use memreserve in DTS.
* Remove L2 reset operation in mcpm implementation.
* Re-use nr_lr field to cover HIP04 GICH_APR implementation.
* Add more comments.
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: add V7_NONLPAE && V7_LPAE sub config
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: append hip04 dts
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 | 19 ++ .../devicetree/bindings/clock/hip04-clock.txt | 20 ++ arch/arm/Kconfig | 22 +- arch/arm/Kconfig.debug | 10 + arch/arm/Makefile | 2 +- arch/arm/boot/dts/Makefile | 1 + arch/arm/boot/dts/hip04-d01.dts | 39 +++ arch/arm/boot/dts/hip04.dtsi | 260 +++++++++++++++ arch/arm/configs/hi3xxx_defconfig | 2 + arch/arm/configs/hip04_defconfig | 75 +++++ arch/arm/configs/multi_v7_lpae_defconfig | 349 +++++++++++++++++++++ arch/arm/include/asm/mcpm.h | 5 + arch/arm/kvm/interrupts_head.S | 32 +- 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 | 314 ++++++++++++++++++ arch/arm/mm/Kconfig | 2 +- drivers/irqchip/irq-gic.c | 162 ++++++++-- include/kvm/arm_vgic.h | 5 +- include/linux/irqchip/arm-gic.h | 8 + virt/kvm/arm/vgic.c | 47 ++- 24 files changed, 1357 insertions(+), 60 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 v5 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 v5 2/14 ARM: add V7_NONLPAE && V7_LPAE sub config
In reply to Haojian ZhuangSince CONFIG_ARM_LPAE could be set in ARM V7, add new two configurations CONFIG_ARCH_MULTI_V7_NONLPAE & CONFIG_ARCH_MULTI_V7_LPAE.
If we want to enable CONFIG_ARM_LPAE configuration, we should enable CONFIG_ARCH_MULTI_V7 & disable both CONFIG_ARCH_MULTI_V6 and CONFIG_ARCH_MULTI_V7_NONLPAE.
--- arch/arm/Kconfig | 13 ++++++++++++- arch/arm/mm/Kconfig | 2 +- 2 files changed, 13 insertions(+), 2 deletions(-)
arch/arm/Kconfig +12 -1
@@ -918,12 +918,23 @@ config ARCH_MULTI_V6 select CPU_V6K config ARCH_MULTI_V7 - bool "ARMv7 based platforms (Cortex-A, PJ4, Scorpion, Krait)" + bool "ARMv7 based platforms" default y select ARCH_MULTI_V6_V7 select CPU_V7 select HAVE_SMP +config ARCH_MULTI_V7_NONLPAE + bool "ARMv7 non-LPAE based platforms (Cortex-A5/A8/A9, PJ4, PJ4B, Scorpion)" + depends on ARCH_MULTI_V7 + default y + +config ARCH_MULTI_V7_LPAE + bool "ARMv7 LPAE based platforms (Cortex-A7/A12/A15/A17, Brahma-B15, PJ4B-MP, Krait)" + depends on ARCH_MULTI_V7 + default y + select ARM_LPAE if !(ARCH_MULTI_V6 || ARCH_MULTI_V7_NONLPAE) + config ARCH_MULTI_V6_V7 bool select MIGHT_HAVE_CACHE_L2X0
arch/arm/mm/Kconfig +1 -1
@@ -615,7 +615,7 @@ comment "Processor Features" config ARM_LPAE bool "Support for the Large Physical Address Extension" depends on MMU && CPU_32v7 && !CPU_32v6 && !CPU_32v5 && \ - !CPU_32v4 && !CPU_32v3 + !CPU_32v4 && !CPU_32v3 && !ARCH_MULTI_V7_NONLPAE help Say Y if you have an ARMv7 processor supporting the LPAE page table format and you would like to access memory beyond the
Signature · 1 line
1.9.1
PATCH v5 2/14 ARM: add V7_NONLPAE && V7_LPAE sub config
Quoted 8 lines · Haojian Zhuang
Since
CONFIG_ARM_LPAEcould be set in ARM V7, add new two configurationsCONFIG_ARCH_MULTI_V7_NONLPAE&CONFIG_ARCH_MULTI_V7_LPAE.If we want to enable
CONFIG_ARM_LPAEconfiguration, we should enableCONFIG_ARCH_MULTI_V7& disable bothCONFIG_ARCH_MULTI_V6andCONFIG_ARCH_MULTI_V7_NONLPAE.Signed-off-by Haojian Zhuang <[email protected]>
I don't like this. Platforms should just depend on CONFIG_ARCH_MULTI_V7 && LPAE (or && !LPAE) instead.
Platforms that _can_ boot without LPAE should not require it, even if they boot with less available memory.
-Olof
PATCH v5 2/14 ARM: add V7_NONLPAE && V7_LPAE sub config
Quoted 10 lines · Olof Johansson
Quoted 8 lines · Haojian Zhuang
Since
CONFIG_ARM_LPAEcould be set in ARM V7, add new two configurationsCONFIG_ARCH_MULTI_V7_NONLPAE&CONFIG_ARCH_MULTI_V7_LPAE.If we want to enable
CONFIG_ARM_LPAEconfiguration, we should enableCONFIG_ARCH_MULTI_V7& disable bothCONFIG_ARCH_MULTI_V6andCONFIG_ARCH_MULTI_V7_NONLPAE.Signed-off-by Haojian Zhuang <[email protected]>
Quoted 8 lines
I don't like this. Platforms should just depend on
CONFIG_ARCH_MULTI_V7&& LPAE (or && !LPAE) instead.Platforms that _can_ boot without LPAE should not require it, even if they boot with less available memory.
-Olof
Do you mean that I should remove CONFIG_ARCH_MULTI_V7_NONLPAE & CONFIG_ARCH_MULTI_V7_LPAE & multi_v7_lpae_defconfig?
Regards
Haojian
PATCH v5 2/14 ARM: add V7_NONLPAE && V7_LPAE sub config
Quoted 14 lines · Haojian Zhuang
Quoted 13 lines · Olof Johansson
Quoted 8 lines · Haojian Zhuang
Since
CONFIG_ARM_LPAEcould be set in ARM V7, add new two configurationsCONFIG_ARCH_MULTI_V7_NONLPAE&CONFIG_ARCH_MULTI_V7_LPAE.If we want to enable
CONFIG_ARM_LPAEconfiguration, we should enableCONFIG_ARCH_MULTI_V7& disable bothCONFIG_ARCH_MULTI_V6andCONFIG_ARCH_MULTI_V7_NONLPAE.Signed-off-by Haojian Zhuang <[email protected]>I don't like this. Platforms should just depend on
CONFIG_ARCH_MULTI_V7&& LPAE (or && !LPAE) instead.
Quoted 8 lines
Quoted 5 lines
Platforms that _can_ boot without LPAE should not require it, even if they boot with less available memory.
-Olof
Do you mean that I should remove
CONFIG_ARCH_MULTI_V7_NONLPAE&CONFIG_ARCH_MULTI_V7_LPAE&multi_v7_lpae_defconfig?
Yes.
Once platforms have been flagged whether they support LPAE or not we can easily create a lpae-enabled defconfig that doesn't enable a bunch of extra platforms that it will never work on.
-Olof
PATCH v5 3/14 ARM: config: append lpae configuration
In reply to Haojian ZhuangAppend multi_v7_lpae_config. In this default configuration, CONFIG_ARCH_MULTI_V7_NONLPAE & CONFIG_ARCH_MULTI_V6 won't be selected.
CONFIG_ARM_LPAE configuration will be selected by default.
--- arch/arm/configs/multi_v7_lpae_defconfig | 349 +++++++++++++++++++++++++++++++ 1 file changed, 349 insertions(+) create mode 100644 arch/arm/configs/multi_v7_lpae_defconfig
arch/arm/configs/multi_v7_lpae_defconfig new file +349 -0
@@ -0,0 +1,349 @@ +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=y +# CONFIG_ARCH_MULTI_V7_NONLPAE 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 v5 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_INT_ID_MASK 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_INT_ID_MASK; 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_INT_ID_MASK 0x3ff +#define GIC_DIST_CTRL 0x000#define GIC_DIST_CTR 0x004#define GIC_DIST_IGROUP 0x080
Signature · 1 line
1.9.1
PATCH v5 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_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.
--- Documentation/devicetree/bindings/arm/gic.txt | 1 + drivers/irqchip/irq-gic.c | 160 ++++++++++++++++++++------ 2 files changed, 129 insertions(+), 32 deletions(-)
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.
drivers/irqchip/irq-gic.c +128 -32
311 lines not on this page · raw message
Signature · 1 line
1.9.1
PATCH v5 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 | 9 +++++++++ arch/arm/include/asm/mcpm.h | 5 +++++ 2 files changed, 14 insertions(+)
arch/arm/Kconfig +9 -0
@@ -1575,6 +1575,15 @@ 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 + 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. + 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 v5 6/14 ARM: mcpm: support 4 clusters
Quoted 16 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 | 9 +++++++++ arch/arm/include/asm/mcpm.h | 5 +++++ 2 files changed, 14 insertions(+)arch/arm/Kconfig +0
-0@@ -1575,6 +1575,15 @@ config MCPM for (multi-)cluster based systems, such as big.LITTLE based systems.
arch/arm/Kconfig config MCPM · line 1586
Quoted 10 lines
arch/arm/Kconfig +9
-0+config MCPM_QUAD_CLUSTER + bool "Enable Quad clusters in MCPM" + depends on MCPM + help + 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. +
Why don't you add an integer config instead, i.e. MCPM_MAX_CLUSTERS, and let that set MAX_NR_CLUSTERS?
-Olof
PATCH v5 6/14 ARM: mcpm: support 4 clusters
Quoted 18 lines · Olof Johansson
Quoted 17 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 | 9 +++++++++ arch/arm/include/asm/mcpm.h | 5 +++++ 2 files changed, 14 insertions(+)arch/arm/Kconfig +0
-0@@ -1575,6 +1575,15 @@ config MCPM for (multi-)cluster based systems, such as big.LITTLE based systems.
Quoted 12 lines
arch/arm/Kconfig config MCPM · line 1586
Quoted 9 lines
arch/arm/Kconfig +9
-0+config MCPM_QUAD_CLUSTER + bool "Enable Quad clusters in MCPM" + depends on MCPM + help + 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. +Why don't you add an integer config instead, i.e.
MCPM_MAX_CLUSTERS, and let that setMAX_NR_CLUSTERS?
I requested for this config symbol not to be visible to users (the prompt string should be removed) and be selected by those platforms that need it instead. And there is no way to specify an actual value with 'select'. And that wouldn't work in a multi-platform config where different platforms could fight over a different value anyway.
I also prefer to keep some control on the actual number that can be used here so not to let people go overboard with it. If this grows too big we'll have to consider some dynamic allocation instead.
See previous discussion here:
http://article.gmane.org/gmane.linux.ports.arm.kernel/315228
Nicolas
PATCH v5 6/14 ARM: mcpm: support 4 clusters
Quoted 39 lines · Nicolas Pitre
Quoted 18 lines · Olof Johansson
Quoted 17 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 | 9 +++++++++ arch/arm/include/asm/mcpm.h | 5 +++++ 2 files changed, 14 insertions(+)arch/arm/Kconfig +0
-0@@ -1575,6 +1575,15 @@ config MCPM for (multi-)cluster based systems, such as big.LITTLE based systems.Quoted 12 lines
arch/arm/Kconfig config MCPM · line 1586
Quoted 9 lines
arch/arm/Kconfig +9
-0+config MCPM_QUAD_CLUSTER + bool "Enable Quad clusters in MCPM" + depends on MCPM + help + 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. +Why don't you add an integer config instead, i.e.
MCPM_MAX_CLUSTERS, and let that setMAX_NR_CLUSTERS?I requested for this config symbol not to be visible to users (the prompt string should be removed) and be selected by those platforms that need it instead. And there is no way to specify an actual value with 'select'. And that wouldn't work in a multi-platform config where different platforms could fight over a different value anyway.
Quoted 7 lines
I also prefer to keep some control on the actual number that can be used here so not to let people go overboard with it. If this grows too big we'll have to consider some dynamic allocation instead.
See previous discussion here:
http://article.gmane.org/gmane.linux.ports.arm.kernel/315228
Ok, fair enough.
-Olof
PATCH v5 6/14 ARM: mcpm: support 4 clusters
In reply to Haojian ZhuangQuoted 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 | 9 +++++++++ arch/arm/include/asm/mcpm.h | 5 +++++ 2 files changed, 14 insertions(+)arch/arm/Kconfig +0
-0
arch/arm/Kconfig config MCPM · line 1579
Quoted 5 lines
arch/arm/Kconfig +2
-0@@ -1575,6 +1575,15 @@ config MCPM for (multi-)cluster based systems, such as big.LITTLE based systems. +config MCPM_QUAD_CLUSTER + bool "Enable Quad clusters in MCPM"
Please remove the prompt string, keeping only the bool alone. This config option shouldn't be visible to users. After that you may add:
Quoted 30 lines
arch/arm/Kconfig +7
-0+ depends on MCPM + help + 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. + config BIG_LITTLE bool "big.LITTLE support (Experimental)" depends on CPU_V7 && SMParch/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 v5 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 v5 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.
--- .../bindings/arm/hisilicon/hisilicon.txt | 19 ++ .../devicetree/bindings/clock/hip04-clock.txt | 20 ++ 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 | 314 +++++++++++++++++++++ 7 files changed, 377 insertions(+), 1 deletion(-) create mode 100644 Documentation/devicetree/bindings/clock/hip04-clock.txt create mode 100644 arch/arm/mach-hisi/platmcpm.c
Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt +19 -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,13 @@ 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 +The memory area of [bootwrapper-phys : bootwrapper-phys+bootwrapper-size] +should be reserved. This should be set in /memreserve/ node in DTS file. Example:
@@ -31,6 +42,7 @@ Example: reboot-offset = <0x4>; }; + PCTRL: Peripheral misc control register Required Properties:
@@ -44,3 +56,10 @@ Example: compatible = "hisilicon,pctrl"; reg = <0xfca09000 0x1000>; }; + + +Fabric: + +Required Properties: +- compatible: "hisilicon,hip04-fabric"; +- reg: Address and size of Fabric
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/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 +314 -0
314 lines not on this page · raw message
Signature · 1 line
1.9.1
PATCH v5 8/14 ARM: hisi: add hip04 SoC support
Quoted 35 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]>--- .../bindings/arm/hisilicon/hisilicon.txt | 19 ++ .../devicetree/bindings/clock/hip04-clock.txt | 20 ++ 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 | 314 +++++++++++++++++++++ 7 files changed, 377 insertions(+), 1 deletion(-) create mode 100644 Documentation/devicetree/bindings/clock/hip04-clock.txt create mode 100644 arch/arm/mach-hisi/platmcpm.cDocumentation/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 32
Quoted 10 lines
Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt +7
-0@@ -19,6 +23,13 @@ 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 +The memory area of [bootwrapper-phys : bootwrapper-phys+bootwrapper-size] +should be reserved. This should be set in /memreserve/ node in DTS file.
This binding spec should be split up in separate files, it's hard to tell from the patch what part of the binding this is appending to. Please do that in a preceding patch, and then add new contents on top.
-Olof
PATCH v5 8/14 ARM: hisi: add hip04 SoC support
In reply to Haojian ZhuangQuoted 5 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.
This makes for a large patch with multiple things mixed together (DT bindings, MCPM backend, etc.) That might help reviewing if split into separate patches.
Quoted 12 lines
Signed-off-by Haojian Zhuang <[email protected]>--- .../bindings/arm/hisilicon/hisilicon.txt | 19 ++ .../devicetree/bindings/clock/hip04-clock.txt | 20 ++ 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 | 314 +++++++++++++++++++++ 7 files changed, 377 insertions(+), 1 deletion(-) create mode 100644 Documentation/devicetree/bindings/clock/hip04-clock.txt create mode 100644 arch/arm/mach-hisi/platmcpm.c
[...]
Quoted 119 lines
arch/arm/mach-hisi/platmcpm.c new file +113
-0@@ -0,0 +1,314 @@ +/* +* Copyright (c) 2013-2014 Linaro Ltd. +* Copyright (c) 2013-2014 Hisilicon Limited. +* +* This program is free software; you can redistribute it and/or modify it +* under the terms and conditions of the GNU General Public License, +* version 2, as published by the Free Software Foundation. +*/ +#include <linux/delay.h> +#include <linux/io.h> +#include <linux/memblock.h> +#include <linux/of_address.h> + +#include <asm/cputype.h> +#include <asm/cp15.h> +#include <asm/mcpm.h> + +#include "core.h" + +/* bits definition in SC_CPU_RESET_REQ[x]/SC_CPU_RESET_DREQ[x] +* 1 -- unreset; 0 -- reset +*/ +#define CORE_RESET_BIT (x) (1 << x) +#define NEON_RESET_BIT (x) (1 << (x + 4)) +#define CORE_DEBUG_RESET_BIT (x) (1 << (x + 9)) +#define CLUSTER_L2_RESET_BIT (1 << 8) +#define CLUSTER_DEBUG_RESET_BIT (1 << 13) + +/* +* bits definition in SC_CPU_RESET_STATUS[x] +* 1 -- reset status; 0 -- unreset status +*/ +#define CORE_RESET_STATUS (x) (1 << x) +#define NEON_RESET_STATUS (x) (1 << (x + 4)) +#define CORE_DEBUG_RESET_STATUS (x) (1 << (x + 9)) +#define CLUSTER_L2_RESET_STATUS (1 << 8) +#define CLUSTER_DEBUG_RESET_STATUS (1 << 13) +#define CORE_WFI_STATUS (x) (1 << (x + 16)) +#define CORE_WFE_STATUS (x) (1 << (x + 20)) +#define CORE_DEBUG_ACK (x) (1 << (x + 24)) + +#define SC_CPU_RESET_REQ (x) (0x520 + (x << 3))/* reset */ +#define SC_CPU_RESET_DREQ (x) (0x524 + (x << 3))/* unreset */ +#define SC_CPU_RESET_STATUS (x) (0x1520 + (x << 3)) + +#define FAB_SF_MODE 0x0c +#define FAB_SF_INVLD 0x10 + +/* bits definition in FB_SF_INVLD */ +#define FB_SF_INVLD_START (1 << 8) + +#define HIP04_MAX_CLUSTERS 4 +#define HIP04_MAX_CPUS_PER_CLUSTER 4 + +#define POLL_MSEC 10 +#define TIMEOUT_MSEC 1000 + +struct hip04_secondary_cpu_data { +u32 bootwrapper_phys; +u32 bootwrapper_size; +u32 bootwrapper_magic; +u32 relocation_entry; +u32 relocation_size; +}; + +static void __iomem *relocation, *sysctrl, *fabric; +static int hip04_cpu_table[HIP04_MAX_CLUSTERS ][HIP04_MAX_CPUS_PER_CLUSTER ]; +static DEFINE_SPINLOCK (boot_lock); +static struct hip04_secondary_cpu_data hip04_boot; + +static bool hip04_cluster_down (unsigned int cluster) +{ +int i; + +for (i =0 ; i <HIP04_MAX_CPUS_PER_CLUSTER ; i++) +if (hip04_cpu_table[cluster][i]) +return false; +return true; +} + +static void hip04_set_snoop_filter (unsigned int cluster,unsigned int on) +{ +unsigned long data; + +if (!fabric) +return ; + data =readl_relaxed (fabric +FAB_SF_MODE ); +if (on) + data |=1 << cluster; +else + data &= ~(1 << cluster); +writel_relaxed (data, fabric +FAB_SF_MODE ); +while (1 ) { +if (data ==readl_relaxed (fabric +FAB_SF_MODE )) +break ; + } +} + +static int hip04_mcpm_power_up (unsigned int cpu,unsigned int cluster) +{ +unsigned long data, mask; + +if (!relocation || !sysctrl) +return -ENODEV ; +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 ); +
arch/arm/mach-hisi/platmcpm.c line 123
Quoted 10 lines
arch/arm/mach-hisi/platmcpm.c new file +10
-0+if (hip04_cluster_down (cluster)) { + data =CLUSTER_DEBUG_RESET_BIT ; +writel_relaxed (data, sysctrl +SC_CPU_RESET_DREQ (cluster)); +do { + mask =CLUSTER_DEBUG_RESET_STATUS ; + data =readl_relaxed (sysctrl + \ +SC_CPU_RESET_STATUS (cluster)); + }while (data & mask); +hip04_set_snoop_filter (cluster,1 ); + }
Isn't this racy? What if the new CPU starts executing code before snoops are enabled for it?
Normally we solve this race by letting the waking-up CPU turn on its snoops by itself from an assembly code callback provided as argument to mcpm_sync_init(). This is also the only way to eventually support deep C-states with cpuidle.
arch/arm/mach-hisi/platmcpm.c line 131
Quoted 8 lines
arch/arm/mach-hisi/platmcpm.c new file +8
-0+ + 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 );
What is that msleep() for?
Quoted 18 lines
arch/arm/mach-hisi/platmcpm.c new file +18
-0+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 ) {
arch/arm/mach-hisi/platmcpm.c line 160
Quoted 10 lines
arch/arm/mach-hisi/platmcpm.c new file +10
-0+/* 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);
Don't you have to turn off snoop filters in the case of a complete cluster down as well?
arch/arm/mach-hisi/platmcpm.c line 165
Quoted 5 lines
arch/arm/mach-hisi/platmcpm.c new file +5
-0+ +__mcpm_cpu_down (cpu, cluster); + +isb (); +dsb ();
Those isb/dsb are redundant here. They're implicit from __mcpm_cpu_down().
Quoted 11 lines
arch/arm/mach-hisi/platmcpm.c new file +11
-0+ +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 );
arch/arm/mach-hisi/platmcpm.c line 186
Quoted 10 lines
arch/arm/mach-hisi/platmcpm.c new file +10
-0+ +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));
You are not supposed to perform any changes here. This method is there only to wait for given CPU to be down. It is not guaranteed it will be called. Furthermore this can race with the power_up method.
Normally you should perform this reset business from hip04_mcpm_power_down() while the lock is held. Now... this assumes that any power/reset would be effective only when the CPU executes a WFI. Is this the case on this hardware? If not then we'll have to think about a different strategy.
Quoted 118 lines
arch/arm/mach-hisi/platmcpm.c new file +118
-0+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; + } + +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);
arch/arm/mach-hisi/platmcpm.c line 314
Quoted 10 lines
arch/arm/mach-hisi/platmcpm.c new file +10
-0+err: +return ret; +} +early_initcall (hip04_mcpm_init); + +bool __init hip04_smp_init_ops (void ) +{ +mcpm_smp_set_ops (); +return true; +}
You should be able to call mcpm_smp_set_ops() directly from hip04_mcpm_init(), and only if there was no errors.
Nicolas
A message that is not in the archive (sent off-list or not yet received): CAD6h2NQU0NR1PO=x6pz62B4QWqkPz7F+Fp65YeQJ62vumF8_Aw@mail.gmail.com
PATCH v5 8/14 ARM: hisi: add hip04 SoC support
Quoted 57 lines · Haojian Zhuang
Quoted 33 lines · Nicolas Pitre
Quoted 17 lines · Haojian Zhuang
arch/arm/mach-hisi/platmcpm.c new file +8
-0+ +static int hip04_mcpm_power_up(unsigned int cpu, unsigned int cluster) +{ + unsigned long data, mask; + + if (!relocation || !sysctrl) + return -ENODEV; + if (cluster >= HIP04_MAX_CLUSTERS || cpu >=
HIP04_MAX_CPUS_PER_CLUSTER)arch/arm/mach-hisi/platmcpm.c new file +8
-0+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 ); +arch/arm/mach-hisi/platmcpm.c line 123
Quoted 10 lines
arch/arm/mach-hisi/platmcpm.c new file +10
-0+if (hip04_cluster_down (cluster)) { + data =CLUSTER_DEBUG_RESET_BIT ; +writel_relaxed (data, sysctrl +SC_CPU_RESET_DREQ (cluster)); +do { + mask =CLUSTER_DEBUG_RESET_STATUS ; + data =readl_relaxed (sysctrl + \ +SC_CPU_RESET_STATUS (cluster)); + }while (data & mask); +hip04_set_snoop_filter (cluster,1 ); + }Isn't this racy? What if the new CPU starts executing code before snoops are enabled for it?
Quoted 5 lines
Normally we solve this race by letting the waking-up CPU turn on its snoops by itself from an assembly code callback provided as argument to
mcpm_sync_init(). This is also the only way to eventually support deep C-states with cpuidle.There's no race. At here, I enable snoop without unreset new CPU.
Quoted 6 lines
arch/arm/mach-hisi/platmcpm.c line 129
Quoted 6 lines
arch/arm/mach-hisi/platmcpm.c new file +6
-0+ + 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));At here, I make new CPU out of reset state.
Quoted 3 lines
Quoted 2 lines
(quoted diff) +2
-0+ spin_unlock_irq(&boot_lock); + msleep(POLL_MSEC);
Quoted 8 lines
Quoted 2 lines
What is that
msleep()for?Without this delay, I'll meet hang.
Since I'm using reset to wakeup CPU from wfi/wfe status, I don't need IPI at here. If I remove the
msleep()here, it seems that IPI caused my system hang. So it's a workaround in my system.
I'm sorry that it's not hang. It results that new CPU cannot be online.
Quoted 235 lines
Quoted 24 lines
Quoted 24 lines
arch/arm/mach-hisi/platmcpm.c new file +22
-0+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();Quoted 9 lines
arch/arm/mach-hisi/platmcpm.c line 160
Quoted 5 lines
arch/arm/mach-hisi/platmcpm.c new file +5
-0+ } + +spin_unlock (&boot_lock); + +v7_exit_coherency_flush (louis);Don't you have to turn off snoop filters in the case of a complete cluster down as well?
I still have some issue on disabling a whole cluster. So making it completely
will be finished later in additional patch.Quoted 9 lines
arch/arm/mach-hisi/platmcpm.c line 165
Quoted 5 lines
arch/arm/mach-hisi/platmcpm.c new file +5
-0+ +__mcpm_cpu_down (cpu, cluster); + +isb (); +dsb ();Those isb/dsb are redundant here. They're implicit from
__mcpm_cpu_down().OK. I'll remove it.
Quoted 28 lines
Quoted 16 lines
arch/arm/mach-hisi/platmcpm.c new file +6
-0+ +if (!skip_wfi) +wfi (); +} + +static int hip04_mcpm_wait_for_powerdown(unsigned int cpu, unsigned intcluster)
arch/arm/mach-hisi/platmcpm.c new file +8
-0+{ +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));arch/arm/mach-hisi/platmcpm.c line 186
Quoted 7 lines
arch/arm/mach-hisi/platmcpm.c new file +7
-0+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));You are not supposed to perform any changes here. This method is there only to wait for given CPU to be down. It is not guaranteed it will be called. Furthermore this can race with the
power_upmethod.Quoted 6 lines
Normally you should perform this reset business from
hip04_mcpm_power_down()while the lock is held. Now... this assumes that any power/reset would be effective only when the CPU executes a WFI. Is this the case on this hardware? If not then we'll have to think about a different strategy.OK. I can move reset operation in
hip04_mcpm_power_down().Quoted 124 lines
Quoted 124 lines
arch/arm/mach-hisi/platmcpm.c new file +52
-0+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");
arch/arm/mach-hisi/platmcpm.c new file +71
-0+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; + } + +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); +Quoted 9 lines
arch/arm/mach-hisi/platmcpm.c line 314
Quoted 5 lines
arch/arm/mach-hisi/platmcpm.c new file +5
-0+bool __init hip04_smp_init_ops (void ) +{ +mcpm_smp_set_ops (); +return true; +}You should be able to call
mcpm_smp_set_ops()directly fromhip04_mcpm_init(), and only if there was no errors.if (!mdesc->smp_init || !mdesc->smp_init()) { if (psci_smp_available()) smp_set_ops(&psci_smp_ops); else if (mdesc->smp) smp_set_ops(mdesc->smp); }Since the above code checks the return value of
mdesc->smp_init(), I think it's better to callmcpm_smp_set_ops()inmdesc->smp_init().Otherwise, my
mdesc->smp_init()only return true without doing anything. It'll confuse others to understand the code.Quoted 2 lines
Nicolas
PATCH v5 8/14 ARM: hisi: add hip04 SoC support
Quoted 45 lines · Haojian Zhuang
Quoted 44 lines · Haojian Zhuang
Quoted 33 lines · Nicolas Pitre
Quoted 17 lines · Haojian Zhuang
arch/arm/mach-hisi/platmcpm.c new file +8
-0+ +static int hip04_mcpm_power_up(unsigned int cpu, unsigned int cluster) +{ + unsigned long data, mask; + + if (!relocation || !sysctrl) + return -ENODEV; + if (cluster >= HIP04_MAX_CLUSTERS || cpu >=
HIP04_MAX_CPUS_PER_CLUSTER)arch/arm/mach-hisi/platmcpm.c new file +8
-0+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 ); +arch/arm/mach-hisi/platmcpm.c line 123
Quoted 10 lines
arch/arm/mach-hisi/platmcpm.c new file +10
-0+if (hip04_cluster_down (cluster)) { + data =CLUSTER_DEBUG_RESET_BIT ; +writel_relaxed (data, sysctrl +SC_CPU_RESET_DREQ (cluster)); +do { + mask =CLUSTER_DEBUG_RESET_STATUS ; + data =readl_relaxed (sysctrl + \ +SC_CPU_RESET_STATUS (cluster)); + }while (data & mask); +hip04_set_snoop_filter (cluster,1 ); + }Isn't this racy? What if the new CPU starts executing code before snoops are enabled for it?
Quoted 5 lines
Normally we solve this race by letting the waking-up CPU turn on its snoops by itself from an assembly code callback provided as argument to
mcpm_sync_init(). This is also the only way to eventually support deep C-states with cpuidle.There's no race. At here, I enable snoop without unreset new CPU.
Quoted 8 lines
Quoted 8 lines
Quoted 6 lines
arch/arm/mach-hisi/platmcpm.c line 129
Quoted 6 lines
arch/arm/mach-hisi/platmcpm.c new file +6
-0+ + 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));At here, I make new CPU out of reset state.
That's my point. At least on systems with the CCI, you risk hanging the system if you enable snoops for a CPU that is not yet running.
Yet you cannot enable the CPU and then turn on snoops as you have the opposite race in that case.
So the only way to be absolutely safe is to let the waking-up CPU turn on snoops for itself _before_ it starts using the cache. That is what the power_up_setup callback provided to mcpm_sync_init() is all about.
It must be written all in assembly as there is no stack available yet when it is called. See arch/arm/mach-vexpress/dcscb_setup.S for an example skeleton where cci_enable_port_for_self is called when the affinity level is 1 (cluster level) and nothing special is done when the affinity level is 0 (CPU level). All the synchronization and race avoidance is all handled for you in arch/arm/common/mcpm_head.S already.
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
Quoted 4 lines
(quoted diff) +2
-0+ spin_unlock_irq(&boot_lock); + msleep(POLL_MSEC);
Quoted 7 lines
Quoted 7 lines
Quoted 2 lines
What is that
msleep()for?Without this delay, I'll meet hang.
Since I'm using reset to wakeup CPU from wfi/wfe status, I don't need IPI at here. If I remove the
msleep()here, it seems that IPI caused my system hang. So it's a workaround in my system.
Could you confirm that the IPI is actually what causes you trouble?
If so maybe you should make sure that the CPU is actually masking out IRQs at all times before they're unmasked by the kernel.
Quoted 34 lines
Quoted 34 lines
Quoted 33 lines
Quoted 23 lines
arch/arm/mach-hisi/platmcpm.c new file +22
-0+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);
arch/arm/mach-hisi/platmcpm.c line 160
Quoted 6 lines
arch/arm/mach-hisi/platmcpm.c new file +6
-0+BUG (); + } + +spin_unlock (&boot_lock); + +v7_exit_coherency_flush (louis);Don't you have to turn off snoop filters in the case of a complete cluster down as well?
Quoted 3 lines
Quoted 3 lines
I still have some issue on disabling a whole cluster. So making it completely
will be finished later in additional patch.
Most likely related to my commentabove.
Quoted 190 lines
Quoted 190 lines
Quoted 11 lines
arch/arm/mach-hisi/platmcpm.c line 165
Quoted 7 lines
arch/arm/mach-hisi/platmcpm.c new file +5
-0+ +__mcpm_cpu_down (cpu, cluster); + +isb (); +dsb ();Those isb/dsb are redundant here. They're implicit from
__mcpm_cpu_down().OK. I'll remove it.
Quoted 28 lines
Quoted 16 lines
arch/arm/mach-hisi/platmcpm.c new file +6
-0+ +if (!skip_wfi) +wfi (); +} + +static int hip04_mcpm_wait_for_powerdown(unsigned int cpu, unsigned intcluster)
arch/arm/mach-hisi/platmcpm.c new file +8
-0+{ +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));arch/arm/mach-hisi/platmcpm.c line 186
Quoted 7 lines
arch/arm/mach-hisi/platmcpm.c new file +7
-0+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));You are not supposed to perform any changes here. This method is there only to wait for given CPU to be down. It is not guaranteed it will be called. Furthermore this can race with the
power_upmethod.Quoted 6 lines
Normally you should perform this reset business from
hip04_mcpm_power_down()while the lock is held. Now... this assumes that any power/reset would be effective only when the CPU executes a WFI. Is this the case on this hardware? If not then we'll have to think about a different strategy.OK. I can move reset operation in
hip04_mcpm_power_down().Quoted 124 lines
Quoted 124 lines
arch/arm/mach-hisi/platmcpm.c new file +52
-0+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");
arch/arm/mach-hisi/platmcpm.c new file +71
-0+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; + } + +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); +Quoted 9 lines
arch/arm/mach-hisi/platmcpm.c line 314
Quoted 5 lines
arch/arm/mach-hisi/platmcpm.c new file +5
-0+bool __init hip04_smp_init_ops (void ) +{ +mcpm_smp_set_ops (); +return true; +}You should be able to call
mcpm_smp_set_ops()directly fromhip04_mcpm_init(), and only if there was no errors.if (!mdesc->smp_init || !mdesc->smp_init()) { if (psci_smp_available()) smp_set_ops(&psci_smp_ops); else if (mdesc->smp) smp_set_ops(mdesc->smp); }
Quoted 5 lines
Quoted 5 lines
Since the above code checks the return value of
mdesc->smp_init(), I think it's better to callmcpm_smp_set_ops()inmdesc->smp_init().Otherwise, my
mdesc->smp_init()only return true without doing anything. It'll confuse others to understand the code.
Simply don't provide a mdesc->smp_init at all. If you have a default value for mdesc->smp then it'll be replaced when hip04_mcpm_init() completes successfully.
Nicolas
PATCH v5 8/14 ARM: hisi: add hip04 SoC support
Quoted 66 lines · Nicolas Pitre
Quoted 45 lines · Haojian Zhuang
Quoted 44 lines · Haojian Zhuang
Quoted 33 lines · Nicolas Pitre
Quoted 17 lines · Haojian Zhuang
arch/arm/mach-hisi/platmcpm.c new file +8
-0+ +static int hip04_mcpm_power_up(unsigned int cpu, unsigned int cluster) +{ + unsigned long data, mask; + + if (!relocation || !sysctrl) + return -ENODEV; + if (cluster >= HIP04_MAX_CLUSTERS || cpu >=
HIP04_MAX_CPUS_PER_CLUSTER)arch/arm/mach-hisi/platmcpm.c new file +8
-0+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 ); +arch/arm/mach-hisi/platmcpm.c line 123
Quoted 10 lines
arch/arm/mach-hisi/platmcpm.c new file +10
-0+if (hip04_cluster_down (cluster)) { + data =CLUSTER_DEBUG_RESET_BIT ; +writel_relaxed (data, sysctrl +SC_CPU_RESET_DREQ (cluster)); +do { + mask =CLUSTER_DEBUG_RESET_STATUS ; + data =readl_relaxed (sysctrl + \ +SC_CPU_RESET_STATUS (cluster)); + }while (data & mask); +hip04_set_snoop_filter (cluster,1 ); + }Isn't this racy? What if the new CPU starts executing code before snoops are enabled for it?
Quoted 5 lines
Normally we solve this race by letting the waking-up CPU turn on its snoops by itself from an assembly code callback provided as argument to
mcpm_sync_init(). This is also the only way to eventually support deep C-states with cpuidle.There's no race. At here, I enable snoop without unreset new CPU.
Quoted 8 lines
Quoted 8 lines
Quoted 6 lines
arch/arm/mach-hisi/platmcpm.c line 129
Quoted 6 lines
arch/arm/mach-hisi/platmcpm.c new file +6
-0+ + 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));At here, I make new CPU out of reset state.
That's my point. At least on systems with the CCI, you risk hanging the system if you enable snoops for a CPU that is not yet running.
Yet you cannot enable the CPU and then turn on snoops as you have the opposite race in that case.
So the only way to be absolutely safe is to let the waking-up CPU turn on snoops for itself _before_ it starts using the cache. That is what the
power_up_setupcallback provided tomcpm_sync_init()is all about.
Quoted 7 lines
It must be written all in assembly as there is no stack available yet when it is called. See
arch/arm/mach-vexpress/dcscb_setup.Sfor an example skeleton wherecci_enable_port_for_selfis called when the affinity level is 1 (cluster level) and nothing special is done when the affinity level is 0 (CPU level). All the synchronization and race avoidance is all handled for you inarch/arm/common/mcpm_head.Salready.
There's no CCI in HiP04. Their own fabric is used instead.
Quoted 9 lines
Quoted 9 lines
Quoted 9 lines
Quoted 7 lines
Review
Quoted 4 lines
(quoted diff) +2
-0+ spin_unlock_irq(&boot_lock); + msleep(POLL_MSEC);What is that
msleep()for?Without this delay, I'll meet hang.
Quoted 9 lines
Quoted 3 lines
Quoted 3 lines
Since I'm using reset to wakeup CPU from wfi/wfe status, I don't need IPI at here. If I remove the
msleep()here, it seems that IPI caused my system hang. So it's a workaround in my system.Could you confirm that the IPI is actually what causes you trouble?
If so maybe you should make sure that the CPU is actually masking out IRQs at all times before they're unmasked by the kernel.
I think so. But I don't have any hardware debugger to confirm it.
I think that unnecessary interrupt causes new CPU in interrupt mode, then this CPU can't be online.
If I remove the code to send IPI, the new CPU could be online right.
Quoted 34 lines
Quoted 34 lines
Quoted 34 lines
Quoted 33 lines
Quoted 23 lines
arch/arm/mach-hisi/platmcpm.c new file +22
-0+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);
arch/arm/mach-hisi/platmcpm.c line 160
Quoted 6 lines
arch/arm/mach-hisi/platmcpm.c new file +6
-0+BUG (); + } + +spin_unlock (&boot_lock); + +v7_exit_coherency_flush (louis);Don't you have to turn off snoop filters in the case of a complete cluster down as well?
Quoted 6 lines
Quoted 3 lines
Quoted 3 lines
I still have some issue on disabling a whole cluster. So making it completely
will be finished later in additional patch.Most likely related to my commentabove.
Maybe it's not. In my original code, I call hip04_set_snoop_filter() at here. But it doesn't help me.
Before I root cause this issue, I don't plan to add hip04_set_snoop_filter() here.
Quoted 22 lines
Quoted 10 lines
Quoted 10 lines
Quoted 3 lines
You should be able to call
mcpm_smp_set_ops()directly fromhip04_mcpm_init(), and only if there was no errors.if (!mdesc->smp_init || !mdesc->smp_init()) { if (psci_smp_available()) smp_set_ops(&psci_smp_ops); else if (mdesc->smp) smp_set_ops(mdesc->smp); }Quoted 5 lines
Quoted 5 lines
Since the above code checks the return value of
mdesc->smp_init(), I think it's better to callmcpm_smp_set_ops()inmdesc->smp_init().Otherwise, my
mdesc->smp_init()only return true without doing anything. It'll confuse others to understand the code.Simply don't provide a
mdesc->smp_initat all. If you have a default value formdesc->smpthen it'll be replaced whenhip04_mcpm_init()completes successfully.Nicolas
PATCH v5 8/14 ARM: hisi: add hip04 SoC support
Quoted 75 lines · Haojian Zhuang
Quoted 66 lines · Nicolas Pitre
Quoted 45 lines · Haojian Zhuang
Quoted 44 lines · Haojian Zhuang
Quoted 33 lines · Nicolas Pitre
Quoted 17 lines · Haojian Zhuang
arch/arm/mach-hisi/platmcpm.c new file +8
-0+ +static int hip04_mcpm_power_up(unsigned int cpu, unsigned int cluster) +{ + unsigned long data, mask; + + if (!relocation || !sysctrl) + return -ENODEV; + if (cluster >= HIP04_MAX_CLUSTERS || cpu >=
HIP04_MAX_CPUS_PER_CLUSTER)arch/arm/mach-hisi/platmcpm.c new file +8
-0+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 ); +arch/arm/mach-hisi/platmcpm.c line 123
Quoted 10 lines
arch/arm/mach-hisi/platmcpm.c new file +10
-0+if (hip04_cluster_down (cluster)) { + data =CLUSTER_DEBUG_RESET_BIT ; +writel_relaxed (data, sysctrl +SC_CPU_RESET_DREQ (cluster)); +do { + mask =CLUSTER_DEBUG_RESET_STATUS ; + data =readl_relaxed (sysctrl + \ +SC_CPU_RESET_STATUS (cluster)); + }while (data & mask); +hip04_set_snoop_filter (cluster,1 ); + }Isn't this racy? What if the new CPU starts executing code before snoops are enabled for it?
Quoted 5 lines
Normally we solve this race by letting the waking-up CPU turn on its snoops by itself from an assembly code callback provided as argument to
mcpm_sync_init(). This is also the only way to eventually support deep C-states with cpuidle.There's no race. At here, I enable snoop without unreset new CPU.
Quoted 8 lines
Quoted 8 lines
Quoted 6 lines
arch/arm/mach-hisi/platmcpm.c line 129
Quoted 6 lines
arch/arm/mach-hisi/platmcpm.c new file +6
-0+ + 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));At here, I make new CPU out of reset state.
That's my point. At least on systems with the CCI, you risk hanging the system if you enable snoops for a CPU that is not yet running.
Yet you cannot enable the CPU and then turn on snoops as you have the opposite race in that case.
So the only way to be absolutely safe is to let the waking-up CPU turn on snoops for itself _before_ it starts using the cache. That is what the
power_up_setupcallback provided tomcpm_sync_init()is all about.Quoted 7 lines
It must be written all in assembly as there is no stack available yet when it is called. See
arch/arm/mach-vexpress/dcscb_setup.Sfor an example skeleton wherecci_enable_port_for_selfis called when the affinity level is 1 (cluster level) and nothing special is done when the affinity level is 0 (CPU level). All the synchronization and race avoidance is all handled for you inarch/arm/common/mcpm_head.Salready.
Quoted 1 line
There's no CCI in HiP04. Their own fabric is used instead.
OK. Still, in order to support deep C-States with cpuidle, the waking-up of CPUs must happen asynchronously, and in that case the CPU being awaken must do snooping setup by itself. So I'd be interested to see if that can be down that way as well for HiP04, at least to be similar in structure to other backend implementations, and possibly for being cpuidle ready as well.
Quoted 19 lines
Quoted 9 lines
Quoted 9 lines
Quoted 9 lines
Quoted 7 lines
Review
Quoted 4 lines
(quoted diff) +2
-0+ spin_unlock_irq(&boot_lock); + msleep(POLL_MSEC);What is that
msleep()for?Without this delay, I'll meet hang.
Quoted 9 lines
Quoted 3 lines
Quoted 3 lines
Since I'm using reset to wakeup CPU from wfi/wfe status, I don't need IPI at here. If I remove the
msleep()here, it seems that IPI caused my system hang. So it's a workaround in my system.Could you confirm that the IPI is actually what causes you trouble?
If so maybe you should make sure that the CPU is actually masking out IRQs at all times before they're unmasked by the kernel.
Quoted 6 lines
I think so. But I don't have any hardware debugger to confirm it.
I think that unnecessary interrupt causes new CPU in interrupt mode, then this CPU can't be online.
If I remove the code to send IPI, the new CPU could be online right.
If so that's a bug in the firmware/bootloader/whatever code that needs to be fixed. CPUs must never unmasq IRQs if they're not ready to cope with them.
Nicolas
PATCH v5 8/14 ARM: hisi: add hip04 SoC support
Quoted 77 lines · Nicolas Pitre
Quoted 75 lines · Haojian Zhuang
Quoted 73 lines · Nicolas Pitre
Quoted 45 lines · Haojian Zhuang
Quoted 44 lines · Haojian Zhuang
Quoted 33 lines · Nicolas Pitre
Quoted 17 lines · Haojian Zhuang
(quoted diff) +8
-0+ +static int hip04_mcpm_power_up(unsigned int cpu, unsigned int cluster) +{ + unsigned long data, mask; + + if (!relocation || !sysctrl) + return -ENODEV; + if (cluster >= HIP04_MAX_CLUSTERS || cpu >=
HIP04_MAX_CPUS_PER_CLUSTER)(quoted diff) +8
-0+ 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); +Review
Quoted 10 lines
(quoted diff) +10
-0+ if (hip04_cluster_down(cluster)) { + data = CLUSTER_DEBUG_RESET_BIT; + writel_relaxed(data, sysctrl + SC_CPU_RESET_DREQ(cluster)); + do { + mask = CLUSTER_DEBUG_RESET_STATUS; + data = readl_relaxed(sysctrl + \ + SC_CPU_RESET_STATUS(cluster)); + } while (data & mask); + hip04_set_snoop_filter(cluster, 1); + }Isn't this racy? What if the new CPU starts executing code before snoops are enabled for it?
Quoted 5 lines
Normally we solve this race by letting the waking-up CPU turn on its snoops by itself from an assembly code callback provided as argument to
mcpm_sync_init(). This is also the only way to eventually support deep C-states with cpuidle.There's no race. At here, I enable snoop without unreset new CPU.
Quoted 8 lines
Quoted 8 lines
Quoted 6 lines
Review
Quoted 6 lines
(quoted diff) +6
-0+ + 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));At here, I make new CPU out of reset state.
That's my point. At least on systems with the CCI, you risk hanging the system if you enable snoops for a CPU that is not yet running.
Yet you cannot enable the CPU and then turn on snoops as you have the opposite race in that case.
So the only way to be absolutely safe is to let the waking-up CPU turn on snoops for itself _before_ it starts using the cache. That is what the
power_up_setupcallback provided tomcpm_sync_init()is all about.It must be written all in assembly as there is no stack available yet when it is called. See
arch/arm/mach-vexpress/dcscb_setup.Sfor an example skeleton wherecci_enable_port_for_selfis called when the affinity level is 1 (cluster level) and nothing special is done when the affinity level is 0 (CPU level). All the synchronization and race avoidance is all handled for you inarch/arm/common/mcpm_head.Salready.
Quoted 9 lines
Quoted 1 line
There's no CCI in HiP04. Their own fabric is used instead.
OK. Still, in order to support deep C-States with cpuidle, the waking-up of CPUs must happen asynchronously, and in that case the CPU being awaken must do snooping setup by itself. So I'd be interested to see if that can be down that way as well for HiP04, at least to be similar in structure to other backend implementations, and possibly for being cpuidle ready as well.
But it fails on my platform if I execute snooping setup on the new CPU.
Quoted 21 lines
Quoted 21 lines
Quoted 9 lines
Quoted 9 lines
Quoted 9 lines
Quoted 7 lines
Review
Quoted 4 lines
(quoted diff) +2
-0+ spin_unlock_irq(&boot_lock); + msleep(POLL_MSEC);What is that
msleep()for?Without this delay, I'll meet hang.
Quoted 9 lines
Quoted 3 lines
Quoted 3 lines
Since I'm using reset to wakeup CPU from wfi/wfe status, I don't need IPI at here. If I remove the
msleep()here, it seems that IPI caused my system hang. So it's a workaround in my system.Could you confirm that the IPI is actually what causes you trouble?
If so maybe you should make sure that the CPU is actually masking out IRQs at all times before they're unmasked by the kernel.
I think so. But I don't have any hardware debugger to confirm it.
Quoted 9 lines
Quoted 4 lines
I think that unnecessary interrupt causes new CPU in interrupt mode, then this CPU can't be online.
If I remove the code to send IPI, the new CPU could be online right.
If so that's a bug in the
firmware/bootloader/whatevercode that needs to be fixed. CPUs must never unmasq IRQs if they're not ready to cope with them.
I agree that it should be fixed in firmware. But I need some time. So I want to keep the workaround until the bug is fixed in firmware.
Regards
Haojian
PATCH v5 8/14 ARM: hisi: add hip04 SoC support
Quoted 88 lines · Haojian Zhuang
Quoted 77 lines · Nicolas Pitre
Quoted 75 lines · Haojian Zhuang
Quoted 73 lines · Nicolas Pitre
Quoted 45 lines · Haojian Zhuang
Quoted 44 lines · Haojian Zhuang
Quoted 33 lines · Nicolas Pitre
Quoted 17 lines · Haojian Zhuang
(quoted diff) +8
-0+ +static int hip04_mcpm_power_up(unsigned int cpu, unsigned int cluster) +{ + unsigned long data, mask; + + if (!relocation || !sysctrl) + return -ENODEV; + if (cluster >= HIP04_MAX_CLUSTERS || cpu >=
HIP04_MAX_CPUS_PER_CLUSTER)(quoted diff) +8
-0+ 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); +Review
Quoted 10 lines
(quoted diff) +10
-0+ if (hip04_cluster_down(cluster)) { + data = CLUSTER_DEBUG_RESET_BIT; + writel_relaxed(data, sysctrl + SC_CPU_RESET_DREQ(cluster)); + do { + mask = CLUSTER_DEBUG_RESET_STATUS; + data = readl_relaxed(sysctrl + \ + SC_CPU_RESET_STATUS(cluster)); + } while (data & mask); + hip04_set_snoop_filter(cluster, 1); + }Isn't this racy? What if the new CPU starts executing code before snoops are enabled for it?
Quoted 5 lines
Normally we solve this race by letting the waking-up CPU turn on its snoops by itself from an assembly code callback provided as argument to
mcpm_sync_init(). This is also the only way to eventually support deep C-states with cpuidle.There's no race. At here, I enable snoop without unreset new CPU.
Quoted 8 lines
Quoted 8 lines
Quoted 6 lines
Review
Quoted 6 lines
(quoted diff) +6
-0+ + 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));At here, I make new CPU out of reset state.
That's my point. At least on systems with the CCI, you risk hanging the system if you enable snoops for a CPU that is not yet running.
Yet you cannot enable the CPU and then turn on snoops as you have the opposite race in that case.
So the only way to be absolutely safe is to let the waking-up CPU turn on snoops for itself _before_ it starts using the cache. That is what the
power_up_setupcallback provided tomcpm_sync_init()is all about.It must be written all in assembly as there is no stack available yet when it is called. See
arch/arm/mach-vexpress/dcscb_setup.Sfor an example skeleton wherecci_enable_port_for_selfis called when the affinity level is 1 (cluster level) and nothing special is done when the affinity level is 0 (CPU level). All the synchronization and race avoidance is all handled for you inarch/arm/common/mcpm_head.Salready.Quoted 9 lines
Quoted 1 line
There's no CCI in HiP04. Their own fabric is used instead.
OK. Still, in order to support deep C-States with cpuidle, the waking-up of CPUs must happen asynchronously, and in that case the CPU being awaken must do snooping setup by itself. So I'd be interested to see if that can be down that way as well for HiP04, at least to be similar in structure to other backend implementations, and possibly for being cpuidle ready as well.
Quoted 1 line
But it fails on my platform if I execute snooping setup on the new CPU.
It fails how? I want to make sure if the problem is with the hardware design or the code.
Quoted 25 lines
Quoted 25 lines
Quoted 24 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 6 lines
Review
Quoted 3 lines
(quoted diff) +2
-0+ spin_unlock_irq(&boot_lock); + msleep(POLL_MSEC);What is that
msleep()for?Without this delay, I'll meet hang.
Quoted 9 lines
Quoted 3 lines
Quoted 3 lines
Since I'm using reset to wakeup CPU from wfi/wfe status, I don't need IPI at here. If I remove the
msleep()here, it seems that IPI caused my system hang. So it's a workaround in my system.Could you confirm that the IPI is actually what causes you trouble?
If so maybe you should make sure that the CPU is actually masking out IRQs at all times before they're unmasked by the kernel.
I think so. But I don't have any hardware debugger to confirm it.
I think that unnecessary interrupt causes new CPU in interrupt mode, then this CPU can't be online.
If I remove the code to send IPI, the new CPU could be online right.
Quoted 7 lines
Quoted 4 lines
If so that's a bug in the
firmware/bootloader/whatevercode that needs to be fixed. CPUs must never unmasq IRQs if they're not ready to cope with them.I agree that it should be fixed in firmware. But I need some time. So I want to keep the workaround until the bug is fixed in firmware.
This is still a very bad workaround. As an alternative, there might be a way to simply mask the IPI at the GIC level and unmask it from the powered_up method.
Also... if this is going to be fixed in the firmware, maybe not including such a workaround into the upstream submission will keep the incentive alive for having it actually fixed.
Nicolas
PATCH v5 8/14 ARM: hisi: add hip04 SoC support
Quoted 14 lines · Nicolas Pitre
Quoted 12 lines · Haojian Zhuang
Quoted 10 lines · Nicolas Pitre
Quoted 2 lines
There's no CCI in HiP04. Their own fabric is used instead.
OK. Still, in order to support deep C-States with cpuidle, the waking-up of CPUs must happen asynchronously, and in that case the CPU being awaken must do snooping setup by itself. So I'd be interested to see if that can be down that way as well for HiP04, at least to be similar in structure to other backend implementations, and possibly for being cpuidle ready as well.
Quoted 5 lines
Quoted 1 line
But it fails on my platform if I execute snooping setup on the new CPU.
It fails how? I want to make sure if the problem is with the hardware design or the code.
The failure isn't caused by your assembly code. I even rewrite it.
It's caused by hardware design. Hisilicon guys said the snooping setup should be set before new CPU on. I tried and got the same result.
Quoted 33 lines
Quoted 25 lines
Quoted 25 lines
Quoted 24 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 6 lines
Review
Quoted 3 lines
(quoted diff) +2
-0+ spin_unlock_irq(&boot_lock); + msleep(POLL_MSEC);What is that
msleep()for?Without this delay, I'll meet hang.
Quoted 9 lines
Quoted 3 lines
Quoted 3 lines
Since I'm using reset to wakeup CPU from wfi/wfe status, I don't need IPI at here. If I remove the
msleep()here, it seems that IPI caused my system hang. So it's a workaround in my system.Could you confirm that the IPI is actually what causes you trouble?
If so maybe you should make sure that the CPU is actually masking out IRQs at all times before they're unmasked by the kernel.
I think so. But I don't have any hardware debugger to confirm it.
I think that unnecessary interrupt causes new CPU in interrupt mode, then this CPU can't be online.
If I remove the code to send IPI, the new CPU could be online right.
Quoted 7 lines
Quoted 4 lines
If so that's a bug in the
firmware/bootloader/whatevercode that needs to be fixed. CPUs must never unmasq IRQs if they're not ready to cope with them.I agree that it should be fixed in firmware. But I need some time. So I want to keep the workaround until the bug is fixed in firmware.
Quoted 8 lines
This is still a very bad workaround. As an alternative, there might be a way to simply mask the IPI at the GIC level and unmask it from the
powered_upmethod.Also... if this is going to be fixed in the firmware, maybe not including such a workaround into the upstream submission will keep the incentive alive for having it actually fixed.
OK. Let me remove the workaround.
Regards
Haojian
PATCH v5 8/14 ARM: hisi: add hip04 SoC support
Quoted 17 lines · Haojian Zhuang
Quoted 16 lines · Nicolas Pitre
Quoted 13 lines · Haojian Zhuang
Quoted 10 lines · Nicolas Pitre
Quoted 2 lines
There's no CCI in HiP04. Their own fabric is used instead.
OK. Still, in order to support deep C-States with cpuidle, the waking-up of CPUs must happen asynchronously, and in that case the CPU being awaken must do snooping setup by itself. So I'd be interested to see if that can be down that way as well for HiP04, at least to be similar in structure to other backend implementations, and possibly for being cpuidle ready as well.
But it fails on my platform if I execute snooping setup on the new CPU.
Quoted 7 lines
Quoted 3 lines
It fails how? I want to make sure if the problem is with the hardware design or the code.
The failure isn't caused by your assembly code. I even rewrite it.
It's caused by hardware design. Hisilicon guys said the snooping setup should be set before new CPU on. I tried and got the same result.
How does this design support cluster powerdown during idle, then ... or is this just not intended to be supported?
Unless there is some extra logic in the hardware taking care of snoop control races, it's not clear who interrupt-driven wakeup from a cluster powerdown could work safely.
Cheers
---Dave
PATCH v5 9/14 ARM: dts: append hip04 dts
In reply to Haojian ZhuangAdd hip04-d01.dts & hip04.dtsi for hip04 SoC platform.
--- arch/arm/boot/dts/Makefile | 1 + arch/arm/boot/dts/hip04-d01.dts | 39 +++++++ arch/arm/boot/dts/hip04.dtsi | 240 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 280 insertions(+) create mode 100644 arch/arm/boot/dts/hip04-d01.dts create mode 100644 arch/arm/boot/dts/hip04.dtsi
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 +39 -0
@@ -0,0 +1,39 @@ +/* + * 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/; + +/* For bootwrapper */ +/memreserve/ 0x10c00000 0x00010000; + +#include "hip04.dtsi" + +/ { + /* memory bus is 64-bit */ + #address-cells = <2>; + #size-cells = <2>; + model = "Hisilicon D01 Development Board"; + compatible = "hisilicon,hip04-d01"; + + memory at 00000000,10000000 { + device_type = "memory"; + reg = <0x00000000 0x10000000 0x00000000 0xc0000000>; + }; + + memory at 00000004,c0000000 { + device_type = "memory"; + reg = <0x00000004 0xc0000000 0x00000003 0x40000000>; + }; + + soc { + uart0: uart at 4007000 { + status = "ok"; + }; + }; +};
arch/arm/boot/dts/hip04.dtsi new file +240 -0
240 lines not on this page · raw message
Signature · 1 line
1.9.1
PATCH v5 10/14 ARM: config: append hip04_defconfig
In reply to Haojian ZhuangSelect HiP04 SoC configuration by hip04_defconfig.
--- arch/arm/configs/hip04_defconfig | 75 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 arch/arm/configs/hip04_defconfig
arch/arm/configs/hip04_defconfig new file +75 -0
@@ -0,0 +1,75 @@ +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=y +# CONFIG_ARCH_MULTI_V7_NONLPAE 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 v5 10/14 ARM: config: append hip04_defconfig
Quoted 3 lines · Haojian Zhuang
Select HiP04 SoC configuration by
hip04_defconfig.Signed-off-by Haojian Zhuang <[email protected]>
We're letting each vendor have one defconfig. This should coexist and/or add to the hi3xxx defconfig instead of creating a new one.
-Olof
PATCH v5 10/14 ARM: config: append hip04_defconfig
Quoted 10 lines · Olof Johansson
Quoted 3 lines · Haojian Zhuang
Select HiP04 SoC configuration by
hip04_defconfig.Signed-off-by Haojian Zhuang <[email protected]>We're letting each vendor have one defconfig. This should coexist and/or add to the hi3xxx defconfig instead of creating a new one.
-Olof
In HiP04, I need to enable 16 CPUs & LPAE.
16 CPU are specified by CONFIG_NR_CPUS. And Hi3xxx SoC don't need LPAE.
Regards
Haojian
PATCH v5 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 v5 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 v5 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
@@ -227,6 +227,26 @@ clock-names = "apb_pclk"; }; + 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>; + }; + uart0: uart at 4007000 { compatible = "snps,dw-apb-uart"; reg = <0x4007000 0x1000>;
Signature · 1 line
1.9.1
PATCH v5 13/14 ARM: dts: Add PMU support in HiP04
Quoted 9 lines · Haojian Zhuang
From: Kefeng Wang <[email protected]>
ARM Performance Monitor Units are available on the HiP04. So add the support in the dtsi.
Simply tested with perf.
Signed-off-by Kefeng Wang <[email protected]>Signed-off-by Haojian Zhuang <[email protected]>
This should be squashed into the original dts introduction patch, no need to add these separately.
-Olof
PATCH v5 13/14 ARM: dts: Add PMU support in HiP04
Quoted 8 lines · Olof Johansson
Quoted 7 lines · Haojian Zhuang
From: Kefeng Wang <[email protected]>
ARM Performance Monitor Units are available on the HiP04. So add the support in the dtsi.
Simply tested with perf.
Quoted 8 lines
Quoted 2 lines
Signed-off-by Kefeng Wang <[email protected]>Signed-off-by Haojian Zhuang <[email protected]>This should be squashed into the original dts introduction patch, no need to add these separately.
-Olof
OK.
Regards
Haojian
PATCH v5 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.
Now reuse the nr_lr field in struct vgic_cpu. Bit[31:16] is used to store GICH_APR offset in HiP04, and bit[15:0] is used to store real nr_lr variable. In ARM standard GIC, don't set bit[31:16]. So we could avoid to change the VGIC implementation in arm64.
--- arch/arm/kvm/interrupts_head.S | 32 ++++++++++++++++++++++------ include/kvm/arm_vgic.h | 5 ++++- include/linux/irqchip/arm-gic.h | 6 ++++++ virt/kvm/arm/vgic.c | 47 +++++++++++++++++++++++++++++------------ 4 files changed, 69 insertions(+), 21 deletions(-)
arch/arm/kvm/interrupts_head.S +26 -6
@@ -419,7 +419,10 @@ 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, [r11, #VGIC_CPU_NR_LR] + movs r10, r10, lsr #HWCFG_APR_SHIFT + ldrne r10, [r2, r10] + ldreq r10, [r2, #GICH_APR] str r3, [r11, #VGIC_CPU_HCR] str r4, [r11, #VGIC_CPU_VMCR]
@@ -435,9 +438,16 @@ vcpu .req r0 @ vcpu pointer always in r0 str r5, [r2, #GICH_HCR] /* Save list registers */ - add r2, r2, #GICH_LR0 - add r3, r11, #VGIC_CPU_LR ldr r4, [r11, #VGIC_CPU_NR_LR] + addeq r2, r2, #GICH_LR0 + movne r10, r4, lsr #HWCFG_APR_SHIFT + /* the offset between GICH_APR & GICH_LR0 is 0x10 */ + addne r10, r10, #0x10 + addne r2, r2, r10 + add r3, r11, #VGIC_CPU_LR + /* Get NR_LR from VGIC_CPU_NR_LR */ + ldr r6, =HWCFG_NR_LR_MASK + and r4, r4, r6 1: ldr r6, [r2], #4 str r6, [r3], #4 subs r4, r4, #1
@@ -469,12 +479,22 @@ 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, [r11, #VGIC_CPU_NR_LR] + movs r6, r6, lsr #HWCFG_APR_SHIFT + strne r8, [r2, r6] + streq r8, [r2, #GICH_APR] /* Restore list registers */ - add r2, r2, #GICH_LR0 - add r3, r11, #VGIC_CPU_LR ldr r4, [r11, #VGIC_CPU_NR_LR] + addeq r2, r2, #GICH_LR0 + movne r6, r4, lsr #HWCFG_APR_SHIFT + /* the offset between GICH_APR & GICH_LR0 is 0x10 */ + addne r6, r6, #0x10 + addne r2, r2, r6 + /* Get NR_LR from VGIC_CPU_NR_LR */ + add r3, r11, #VGIC_CPU_LR + ldr r6, =HWCFG_NR_LR_MASK + and r4, r4, r6 1: ldr r6, [r3], #4 str r6, [r2], #4 subs r4, r4, #1
include/kvm/arm_vgic.h +4 -1
@@ -122,7 +122,10 @@ struct vgic_cpu {/* Bitmap of used/free list registers */ DECLARE_BITMAP ( lr_used,VGIC_MAX_LRS ); -/* Number of list registers on this CPU */ +/* +* bit[31:16]: GICH_APR offset +* bit[15:0]: Number of list registers on this CPU +*/ int nr_lr;/* CPU vif control registers for world switch */
include/linux/irqchip/arm-gic.h +6 -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)
@@ -73,6 +75,10 @@#define GICH_MISR_EOI (1 << 0)#define GICH_MISR_U (1 << 1) +#define HWCFG_NR_LR_MASK 0xffff +#define HWCFG_APR_MASK 0xffff +#define HWCFG_APR_SHIFT 16 +#ifndef __ASSEMBLY__struct device_node ;
virt/kvm/arm/vgic.c +33 -14
132 lines not on this page · raw message
Signature · 1 line
1.9.1