Skip to contentSkip to conversation

enable HiP04 SoC

PATCH Superseded Haojian Zhuang 4 participants 36 messages May 7, 2014 – May 21, 2014 1 message not in the archive

Subsystems (9)

v5 of 17 Superseded Latest is v17 →

lore
Share & tools
lore
#0 lore raw

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
#1 lore raw

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
index 4a2fc0b..5a311af 100644
@@ -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
#2 lore raw

PATCH v5 2/14 ARM: add V7_NONLPAE && V7_LPAE sub config

In reply to Haojian Zhuang

Since 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
index ab438cb..0e52a2c 100644
@@ -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
index f5ad9ee..1c1576c 100644
@@ -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
#3 lore raw

PATCH v5 2/14 ARM: add V7_NONLPAE && V7_LPAE sub config

Quoted 8 lines · Haojian Zhuang

Since 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.

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

#4 lore raw

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_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.

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

#5 lore raw

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_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.

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

#6 lore raw

PATCH v5 3/14 ARM: config: append lpae configuration

In reply to Haojian Zhuang

Append 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
new file mode 100644
index 0000000..fb03bad
@@ -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
#7 lore raw

PATCH v5 4/14 irq: gic: use mask field in GICC_IAR

In reply to Haojian Zhuang

Bit[9:0] is interrupt ID field in GICC_IAR. Bit[12:10] is CPU ID field, and others are reserved.

So we should use GICC_IAR_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
index 4300b66..f711fb6 100644
@@ -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
index 7ed92d0..45e2d8c 100644
@@ -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
#8 lore raw

PATCH v5 5/14 irq: gic: support hip04 gic

In reply to Haojian Zhuang

There's a little difference between ARM GIC and HiP04 GIC.

* HiP04 GIC could support 16 cores at most, and ARM GIC could support 8 cores at most. So the difination on GIC_DIST_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
index 5573c08..150f7d6 100644
@@ -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
#9 lore raw

PATCH v5 6/14 ARM: mcpm: support 4 clusters

In reply to Haojian Zhuang

Add 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
index 0e52a2c..624829f 100644
@@ -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
index 608516e..fc8d70d 100644
@@ -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
#10 lore raw

PATCH v5 6/14 ARM: mcpm: support 4 clusters

Quoted 16 lines · Haojian Zhuang

Add 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 +0 -0
index 0e52a2c..624829f 100644
@@ -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

#11 lore raw

PATCH v5 6/14 ARM: mcpm: support 4 clusters

Quoted 18 lines · Olof Johansson
Quoted 17 lines · Haojian Zhuang

Add 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 +0 -0
index 0e52a2c..624829f 100644
@@ -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 set MAX_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

#12 lore raw

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_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 +0 -0
index 0e52a2c..624829f 100644
@@ -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 set MAX_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

#13 lore raw

PATCH v5 6/14 ARM: mcpm: support 4 clusters

In reply to Haojian Zhuang
Quoted 14 lines · Haojian Zhuang

Add 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 +0 -0
index 0e52a2c..624829f 100644

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 && SMP
arch/arm/include/asm/mcpm.h +5 -0
index 608516e..fc8d70d 100644
@@ -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
#14 lore raw

PATCH v5 7/14 ARM: hisi: add ARCH_HISI

In reply to Haojian Zhuang

Since 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
index 41c1931..4c2798a 100644
@@ -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
index feee4db..da16efd 100644
@@ -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
#15 lore raw

PATCH v5 8/14 ARM: hisi: add hip04 SoC support

In reply to 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.

---
 .../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
index df0a452..20736b0 100644
@@ -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
new file mode 100644
index 0000000..4d31ae3
@@ -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
index da16efd..17af1d2 100644
@@ -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
index 2ae1b59..e7a8640 100644
@@ -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
index af23ec2..1e60795 100644
@@ -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
index 741faf3..6489e57 100644
@@ -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
#16 lore raw

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.

---
 .../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 +4 -0
index df0a452..20736b0 100644
@@ -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

#17 lore raw

PATCH v5 8/14 ARM: hisi: add hip04 SoC support

In reply to Haojian Zhuang
Quoted 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
---
 .../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
new file mode 100644
index 0000000..e0d7afd
@@ -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

#19 lore raw

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 int

cluster)

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_up method.

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 from hip04_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 call mcpm_smp_set_ops() in mdesc->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

#20 lore raw

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 int

cluster)

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_up method.

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 from hip04_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 call mcpm_smp_set_ops() in mdesc->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

#21 lore raw

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_setup callback provided to mcpm_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.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.

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 from hip04_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 call mcpm_smp_set_ops() in mdesc->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

#22 lore raw

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_setup callback provided to mcpm_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.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 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

#23 lore raw

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_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 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/whatever code 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

#24 lore raw

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_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 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/whatever code 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

#25 lore raw

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/whatever code 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_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.

OK. Let me remove the workaround.

Regards
Haojian

#26 lore raw

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

#27 lore raw

PATCH v5 9/14 ARM: dts: append hip04 dts

In reply to Haojian Zhuang

Add 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
index 35c146f..7119bca 100644
@@ -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
new file mode 100644
index 0000000..661c8e5
@@ -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
#28 lore raw

PATCH v5 10/14 ARM: config: append hip04_defconfig

In reply to Haojian Zhuang

Select 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
new file mode 100644
index 0000000..96073b5
@@ -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
#29 lore raw

PATCH v5 10/14 ARM: config: append hip04_defconfig

Quoted 3 lines · Haojian Zhuang

Select HiP04 SoC configuration by hip04_defconfig.

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

#30 lore raw

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.

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

#31 lore raw

PATCH v5 11/14 ARM: config: select ARCH_HISI in hi3xxx_defconfig

In reply to Haojian Zhuang

Since 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
index f186bdf..553e1b6 100644
@@ -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
#32 lore raw

PATCH v5 12/14 ARM: hisi: enable erratum 798181 of A15 on HiP04

In reply to Haojian Zhuang

From: 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
index 17af1d2..5c0602d 100644
@@ -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
#33 lore raw

PATCH v5 13/14 ARM: dts: Add PMU support in HiP04

In reply to 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.

---
 arch/arm/boot/dts/hip04.dtsi | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)
arch/arm/boot/dts/hip04.dtsi +20 -0
index 55a39ed..eee69e5 100644
@@ -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
#35 lore raw

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

This should be squashed into the original dts introduction patch, no need to add these separately.

-Olof

OK.

Regards
Haojian

#36 lore raw

PATCH v5 14/14 virt: arm: support hip04 gic

In reply to Haojian Zhuang

In 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
index 76af9302..7aacaff 100644
@@ -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
index f27000f..089de25 100644
@@ -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
index 45e2d8c..5530388 100644
@@ -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