mvebu: new subtarget cortex A53
This commit introduces new subtarget for Marvell EBU Armada Cortex A53
processor based devices.
The first device is Globalscale ESPRESSObin. Some hardware specs:
SoC: Marvell Armada 3700LP (88F3720) dual core ARM Cortex A53
     processor up to 1.2GHz
RAM: 512MB, 1GB or 2GB DDR3
Storage: SATA interface
         µSD card slot with footprint for an optional 4GB EMMC
         4MB SPI NOR flash for bootloader
Ethernet: Topaz Networking Switch (88E6341) with 3x GbE ports
Connectors: USB 3.0
            USB 2.0
            µUSB port connected to PL2303SA (USB to serial bridge
            controller) for UART access
Expansion: 2x 46-pin GPIO headers for accessories and shields with
           I2C, GPIOs, PWM, UART, SPI, MMC, etc
           MiniPCIe slot
Misc: Reset button, JTAG interface
Currently booting only from µSD card is supported.
The boards depending on date of dispatch can come with various U-Boot
versions. For the newest version 2017.03-armada-17.10 no manual
intervention should be needed to boot OpenWrt image. For the older ones
it's necessary to modify default U-Boot environment:
 1. Interrupt boot process to run U-Boot command line,
 2. Run following commands:
    (for version 2017.03-armada-17.06 and 2017.03-armada-17.08)
     setenv bootcmd "load mmc 0:1 0x4d00000 boot.scr; source 0x4d00000"
     saveenv
    (for version 2015.01-armada-17.02 and 2015.01-armada-17.04)
     setenv bootargs "console=ttyMV0,115200 root=/dev/mmcblk0p2 rw rootwait"
     setenv bootcmd "ext4load mmc 0:1 ${fdt_addr} armada-3720-espressobin.dtb; ext4load mmc 0:1 ${kernel_addr} Image; booti ${kernel_addr} - ${fdt_addr}"
     saveenv
 3. Poweroff, insert SD card with OpenWrt image, boot and enjoy.
Signed-off-by: Tomasz Maciej Nowak <tomek_n@o2.pl>
			
			
This commit is contained in:
		 Tomasz Maciej Nowak
					Tomasz Maciej Nowak
				
			
				
					committed by
					
						 Hauke Mehrtens
						Hauke Mehrtens
					
				
			
			
				
	
			
			
			 Hauke Mehrtens
						Hauke Mehrtens
					
				
			
						parent
						
							be3da900cd
						
					
				
				
					commit
					584d7c53bd
				
			| @@ -7,9 +7,9 @@ | |||||||
| include $(TOPDIR)/rules.mk | include $(TOPDIR)/rules.mk | ||||||
|  |  | ||||||
| BOARD:=mvebu | BOARD:=mvebu | ||||||
| BOARDNAME:=Marvell Armada 37x/38x/XP | BOARDNAME:=Marvell EBU Armada | ||||||
| FEATURES:=fpu usb pci pcie gpio nand squashfs ramdisk | FEATURES:=fpu usb pci pcie gpio nand squashfs ramdisk | ||||||
| SUBTARGETS:=cortexa9 | SUBTARGETS:=cortexa9 cortexa53 | ||||||
| MAINTAINER:=Imre Kaloz <kaloz@openwrt.org> | MAINTAINER:=Imre Kaloz <kaloz@openwrt.org> | ||||||
|  |  | ||||||
| KERNEL_PATCHVER:=4.14 | KERNEL_PATCHVER:=4.14 | ||||||
|   | |||||||
| @@ -42,6 +42,9 @@ armada-388-clearfog-*) | |||||||
| armada-xp-gp) | armada-xp-gp) | ||||||
| 	ucidef_set_interface_lan "eth0 eth1 eth2 eth3" | 	ucidef_set_interface_lan "eth0 eth1 eth2 eth3" | ||||||
| 	;; | 	;; | ||||||
|  | globalscale,espressobin) | ||||||
|  | 	ucidef_set_interfaces_lan_wan "lan0 lan1" "wan" | ||||||
|  | 	;; | ||||||
| *) | *) | ||||||
| 	ucidef_set_interface_lan "eth0" | 	ucidef_set_interface_lan "eth0" | ||||||
| 	;; | 	;; | ||||||
|   | |||||||
| @@ -17,6 +17,9 @@ mvebu_board_detect() { | |||||||
| 	*"Marvell Armada 370 Evaluation Board") | 	*"Marvell Armada 370 Evaluation Board") | ||||||
| 		name="armada-370-db" | 		name="armada-370-db" | ||||||
| 		;; | 		;; | ||||||
|  | 	*"Globalscale Marvell ESPRESSOBin Board") | ||||||
|  | 		name="globalscale,espressobin" | ||||||
|  | 		;; | ||||||
| 	*"Globalscale Mirabox") | 	*"Globalscale Mirabox") | ||||||
| 		name="mirabox" | 		name="mirabox" | ||||||
| 		;; | 		;; | ||||||
|   | |||||||
| @@ -16,7 +16,7 @@ platform_do_upgrade() { | |||||||
| 	armada-385-linksys-caiman|armada-385-linksys-cobra|armada-385-linksys-rango|armada-385-linksys-shelby|armada-xp-linksys-mamba) | 	armada-385-linksys-caiman|armada-385-linksys-cobra|armada-385-linksys-rango|armada-385-linksys-shelby|armada-xp-linksys-mamba) | ||||||
| 		platform_do_upgrade_linksys "$ARGV" | 		platform_do_upgrade_linksys "$ARGV" | ||||||
| 		;; | 		;; | ||||||
| 	armada-385-turris-omnia|armada-388-clearfog-base|armada-388-clearfog-pro) | 	armada-385-turris-omnia|armada-388-clearfog-base|armada-388-clearfog-pro|globalscale,espressobin) | ||||||
| 		platform_do_upgrade_sdcard "$ARGV" | 		platform_do_upgrade_sdcard "$ARGV" | ||||||
| 		;; | 		;; | ||||||
| 	*) | 	*) | ||||||
| @@ -29,7 +29,7 @@ platform_copy_config() { | |||||||
| 	armada-385-linksys-caiman|armada-385-linksys-cobra|armada-385-linksys-rango|armada-385-linksys-shelby|armada-xp-linksys-mamba) | 	armada-385-linksys-caiman|armada-385-linksys-cobra|armada-385-linksys-rango|armada-385-linksys-shelby|armada-xp-linksys-mamba) | ||||||
| 		platform_copy_config_linksys | 		platform_copy_config_linksys | ||||||
| 		;; | 		;; | ||||||
| 	armada-385-turris-omnia|armada-388-clearfog-base|armada-388-clearfog-pro) | 	armada-385-turris-omnia|armada-388-clearfog-base|armada-388-clearfog-pro|globalscale,espressobin) | ||||||
| 		platform_copy_config_sdcard "$ARGV" | 		platform_copy_config_sdcard "$ARGV" | ||||||
| 		;; | 		;; | ||||||
| 	esac | 	esac | ||||||
|   | |||||||
| @@ -39,6 +39,7 @@ CONFIG_ARMADA_38X_CLK=y | |||||||
| CONFIG_ARMADA_THERMAL=y | CONFIG_ARMADA_THERMAL=y | ||||||
| CONFIG_ARMADA_XP_CLK=y | CONFIG_ARMADA_XP_CLK=y | ||||||
| CONFIG_ARM_APPENDED_DTB=y | CONFIG_ARM_APPENDED_DTB=y | ||||||
|  | # CONFIG_ARM_ARMADA_37XX_CPUFREQ is not set | ||||||
| CONFIG_ARM_ATAG_DTB_COMPAT=y | CONFIG_ARM_ATAG_DTB_COMPAT=y | ||||||
| # CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set | # CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set | ||||||
| CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER=y | CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER=y | ||||||
|   | |||||||
							
								
								
									
										112
									
								
								target/linux/mvebu/cortexa53/config-default
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										112
									
								
								target/linux/mvebu/cortexa53/config-default
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,112 @@ | |||||||
|  | CONFIG_64BIT=y | ||||||
|  | # CONFIG_ACPI is not set | ||||||
|  | CONFIG_ARCH_DMA_ADDR_T_64BIT=y | ||||||
|  | CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y | ||||||
|  | CONFIG_ARCH_HAS_FORTIFY_SOURCE=y | ||||||
|  | CONFIG_ARCH_HAS_HOLES_MEMORYMODEL=y | ||||||
|  | CONFIG_ARCH_HAS_KCOV=y | ||||||
|  | CONFIG_ARCH_MMAP_RND_BITS=18 | ||||||
|  | CONFIG_ARCH_MMAP_RND_BITS_MAX=24 | ||||||
|  | CONFIG_ARCH_MMAP_RND_BITS_MIN=18 | ||||||
|  | CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11 | ||||||
|  | # CONFIG_ARCH_OPTIONAL_KERNEL_RWX is not set | ||||||
|  | # CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT is not set | ||||||
|  | CONFIG_ARCH_PHYS_ADDR_T_64BIT=y | ||||||
|  | CONFIG_ARCH_PROC_KCORE_TEXT=y | ||||||
|  | CONFIG_ARCH_SELECT_MEMORY_MODEL=y | ||||||
|  | CONFIG_ARCH_SPARSEMEM_DEFAULT=y | ||||||
|  | CONFIG_ARCH_SPARSEMEM_ENABLE=y | ||||||
|  | CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y | ||||||
|  | CONFIG_ARCH_SUPPORTS_MEMORY_FAILURE=y | ||||||
|  | CONFIG_ARCH_SUPPORTS_NUMA_BALANCING=y | ||||||
|  | CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION=y | ||||||
|  | CONFIG_ARCH_WANT_FRAME_POINTERS=y | ||||||
|  | CONFIG_ARCH_WANT_HUGE_PMD_SHARE=y | ||||||
|  | CONFIG_ARM64=y | ||||||
|  | # CONFIG_ARM64_16K_PAGES is not set | ||||||
|  | CONFIG_ARM64_4K_PAGES=y | ||||||
|  | # CONFIG_ARM64_64K_PAGES is not set | ||||||
|  | CONFIG_ARM64_CONT_SHIFT=4 | ||||||
|  | # CONFIG_ARM64_CRYPTO is not set | ||||||
|  | # CONFIG_ARM64_HW_AFDBM is not set | ||||||
|  | # CONFIG_ARM64_LSE_ATOMICS is not set | ||||||
|  | CONFIG_ARM64_PAGE_SHIFT=12 | ||||||
|  | # CONFIG_ARM64_PAN is not set | ||||||
|  | # CONFIG_ARM64_PMEM is not set | ||||||
|  | # CONFIG_ARM64_PTDUMP_CORE is not set | ||||||
|  | # CONFIG_ARM64_PTDUMP_DEBUGFS is not set | ||||||
|  | # CONFIG_ARM64_RANDOMIZE_TEXT_OFFSET is not set | ||||||
|  | # CONFIG_ARM64_SW_TTBR0_PAN is not set | ||||||
|  | # CONFIG_ARM64_UAO is not set | ||||||
|  | CONFIG_ARM64_VA_BITS=39 | ||||||
|  | CONFIG_ARM64_VA_BITS_39=y | ||||||
|  | # CONFIG_ARM64_VA_BITS_48 is not set | ||||||
|  | # CONFIG_ARM64_VHE is not set | ||||||
|  | CONFIG_ARMADA_37XX_CLK=y | ||||||
|  | CONFIG_ARMADA_AP806_SYSCON=y | ||||||
|  | CONFIG_ARMADA_CP110_SYSCON=y | ||||||
|  | CONFIG_ARM_AMBA=y | ||||||
|  | CONFIG_ARM_ARCH_TIMER=y | ||||||
|  | CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y | ||||||
|  | CONFIG_ARM_ARMADA_37XX_CPUFREQ=y | ||||||
|  | CONFIG_ARM_GIC_V2M=y | ||||||
|  | CONFIG_ARM_GIC_V3=y | ||||||
|  | CONFIG_ARM_GIC_V3_ITS=y | ||||||
|  | # CONFIG_ARM_PL172_MPMC is not set | ||||||
|  | CONFIG_ARM_PSCI_FW=y | ||||||
|  | # CONFIG_ARM_SP805_WATCHDOG is not set | ||||||
|  | CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y | ||||||
|  | # CONFIG_COMPAT is not set | ||||||
|  | # CONFIG_DEBUG_ALIGN_RODATA is not set | ||||||
|  | CONFIG_FRAME_POINTER=y | ||||||
|  | CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y | ||||||
|  | CONFIG_GENERIC_CSUM=y | ||||||
|  | CONFIG_GENERIC_IRQ_MIGRATION=y | ||||||
|  | CONFIG_GENERIC_PINCONF=y | ||||||
|  | CONFIG_GENERIC_TIME_VSYSCALL=y | ||||||
|  | CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y | ||||||
|  | CONFIG_HAVE_ARCH_HUGE_VMAP=y | ||||||
|  | CONFIG_HAVE_ARCH_KASAN=y | ||||||
|  | CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y | ||||||
|  | CONFIG_HAVE_ARCH_VMAP_STACK=y | ||||||
|  | CONFIG_HAVE_CMPXCHG_DOUBLE=y | ||||||
|  | CONFIG_HAVE_CMPXCHG_LOCAL=y | ||||||
|  | CONFIG_HAVE_DEBUG_BUGVERBOSE=y | ||||||
|  | CONFIG_HAVE_GENERIC_GUP=y | ||||||
|  | CONFIG_HAVE_MEMORY_PRESENT=y | ||||||
|  | CONFIG_HAVE_PATA_PLATFORM=y | ||||||
|  | CONFIG_HAVE_RCU_TABLE_FREE=y | ||||||
|  | # CONFIG_HUGETLBFS is not set | ||||||
|  | CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 | ||||||
|  | CONFIG_MFD_SYSCON=y | ||||||
|  | CONFIG_MMC_SDHCI_XENON=y | ||||||
|  | CONFIG_MODULES_USE_ELF_RELA=y | ||||||
|  | CONFIG_MVEBU_GICP=y | ||||||
|  | CONFIG_MVEBU_ICU=y | ||||||
|  | CONFIG_MVEBU_ODMI=y | ||||||
|  | CONFIG_MVEBU_PIC=y | ||||||
|  | CONFIG_NEED_SG_DMA_LENGTH=y | ||||||
|  | # CONFIG_NUMA is not set | ||||||
|  | CONFIG_PARTITION_PERCPU=y | ||||||
|  | CONFIG_PCI_AARDVARK=y | ||||||
|  | CONFIG_PCI_BUS_ADDR_T_64BIT=y | ||||||
|  | CONFIG_PGTABLE_LEVELS=3 | ||||||
|  | CONFIG_PHYS_ADDR_T_64BIT=y | ||||||
|  | CONFIG_PINCTRL_ARMADA_37XX=y | ||||||
|  | CONFIG_PINCTRL_ARMADA_AP806=y | ||||||
|  | CONFIG_PINCTRL_ARMADA_CP110=y | ||||||
|  | CONFIG_POWER_RESET=y | ||||||
|  | CONFIG_POWER_SUPPLY=y | ||||||
|  | # CONFIG_RANDOMIZE_BASE is not set | ||||||
|  | CONFIG_REGULATOR_GPIO=y | ||||||
|  | # CONFIG_SERIAL_AMBA_PL011 is not set | ||||||
|  | CONFIG_SPARSEMEM=y | ||||||
|  | CONFIG_SPARSEMEM_EXTREME=y | ||||||
|  | CONFIG_SPARSEMEM_MANUAL=y | ||||||
|  | CONFIG_SPARSEMEM_VMEMMAP=y | ||||||
|  | CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y | ||||||
|  | CONFIG_SPI_ARMADA_3700=y | ||||||
|  | CONFIG_SYSCTL_EXCEPTION_TRACE=y | ||||||
|  | CONFIG_SYS_SUPPORTS_HUGETLBFS=y | ||||||
|  | CONFIG_THREAD_INFO_IN_TASK=y | ||||||
|  | CONFIG_VMAP_STACK=y | ||||||
							
								
								
									
										15
									
								
								target/linux/mvebu/cortexa53/target.mk
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								target/linux/mvebu/cortexa53/target.mk
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | |||||||
|  | # | ||||||
|  | # Copyright (C) 2017 Hauke Mehrtens | ||||||
|  | # | ||||||
|  | # This is free software, licensed under the GNU General Public License v2. | ||||||
|  | # See /LICENSE for more information. | ||||||
|  | # | ||||||
|  |  | ||||||
|  | include $(TOPDIR)/rules.mk | ||||||
|  |  | ||||||
|  | ARCH:=aarch64 | ||||||
|  | BOARDNAME:=Marvell Armada 3700LP (ARM64) | ||||||
|  | CPU_TYPE:=cortex-a53 | ||||||
|  | FEATURES+=ext4 | ||||||
|  |  | ||||||
|  | KERNELNAME:=Image dtbs | ||||||
| @@ -27,17 +27,28 @@ endef | |||||||
|  |  | ||||||
| define Build/boot-scr | define Build/boot-scr | ||||||
| 	rm -f $@-boot.scr | 	rm -f $@-boot.scr | ||||||
| 	mkimage -A arm -O linux -T script -C none -a 0 -e 0 -d $(DEVICE_NAME).bootscript $@-boot.scr | 	sed -e 's#@ROOT@#$(SIGNATURE)#g' \ | ||||||
|  | 		$(DEVICE_NAME).bootscript > $@-new.bootscript | ||||||
|  | 	mkimage -A arm -O linux -T script -C none -a 0 -e 0 -d $@-new.bootscript $@-boot.scr | ||||||
| endef | endef | ||||||
|  |  | ||||||
| define Build/boot-img | define Build/boot-img | ||||||
| 	rm -f $@.boot | 	rm -f $@.boot | ||||||
| 	mkfs.fat -C $@.boot 16384 | 	mkfs.fat -C $@.boot 16384 | ||||||
| 	$(foreach dts,$(DEVICE_DTS), mcopy -i $@.boot $(DTS_DIR)/$(dts).dtb ::$(dts).dtb;) | 	$(foreach dts,$(DEVICE_DTS), mcopy -i $@.boot $(DTS_DIR)/$(dts).dtb ::$(dts).dtb;) | ||||||
| 	mcopy -i $@.boot $(IMAGE_KERNEL) ::zImage | 	mcopy -i $@.boot $(IMAGE_KERNEL) ::$(KERNEL_NAME) | ||||||
| 	-mcopy -i $@.boot $@-boot.scr ::boot.scr | 	-mcopy -i $@.boot $@-boot.scr ::boot.scr | ||||||
| endef | endef | ||||||
|  |  | ||||||
|  | define Build/boot-img-ext4 | ||||||
|  | 	rm -fR $@.boot | ||||||
|  | 	mkdir -p $@.boot | ||||||
|  | 	$(foreach dts,$(DEVICE_DTS), $(CP) $(DTS_DIR)/$(dts).dtb $@.boot;) | ||||||
|  | 	$(CP) $(IMAGE_KERNEL) $@.boot/$(KERNEL_NAME) | ||||||
|  | 	-$(CP) $@-boot.scr $@.boot/boot.scr | ||||||
|  | 	make_ext4fs -J -l 16384K $@.bootimg $@.boot | ||||||
|  | endef | ||||||
|  |  | ||||||
| define Build/sdcard-img | define Build/sdcard-img | ||||||
| 	if [ -n "$(UBOOT)" ]; then UBOOT="$(STAGING_DIR_IMAGE)/$(UBOOT)"; fi; \ | 	if [ -n "$(UBOOT)" ]; then UBOOT="$(STAGING_DIR_IMAGE)/$(UBOOT)"; fi; \ | ||||||
| 	ROOTFS_SIZE=$$(( $(CONFIG_TARGET_ROOTFS_PARTSIZE) * 1024 * 2 )); \ | 	ROOTFS_SIZE=$$(( $(CONFIG_TARGET_ROOTFS_PARTSIZE) * 1024 * 2 )); \ | ||||||
| @@ -48,6 +59,16 @@ define Build/sdcard-img | |||||||
| 		83 $$ROOTFS_SIZE $(IMAGE_ROOTFS) | 		83 $$ROOTFS_SIZE $(IMAGE_ROOTFS) | ||||||
| endef | endef | ||||||
|  |  | ||||||
|  | define Build/sdcard-img-ext4 | ||||||
|  | 	if [ -n "$(UBOOT)" ]; then UBOOT="$(STAGING_DIR_IMAGE)/$(UBOOT)"; fi; \ | ||||||
|  | 	ROOTFS_SIZE=$$(( $(CONFIG_TARGET_ROOTFS_PARTSIZE) * 1024 * 2 )); \ | ||||||
|  | 	SIGNATURE="$(SIGNATURE)" \ | ||||||
|  | 	./gen_mvebu_sdcard_img.sh $@ \ | ||||||
|  | 		$$UBOOT \ | ||||||
|  | 		83 32768 $@.bootimg \ | ||||||
|  | 		83 $$ROOTFS_SIZE $(IMAGE_ROOTFS) | ||||||
|  | endef | ||||||
|  |  | ||||||
| define Build/omnia-medkit-initramfs | define Build/omnia-medkit-initramfs | ||||||
| 	$(TAR) -c -T /dev/null -f $@ | 	$(TAR) -c -T /dev/null -f $@ | ||||||
| 	rm -rf $(dir $(IMAGE_KERNEL))boot | 	rm -rf $(dir $(IMAGE_KERNEL))boot | ||||||
| @@ -101,5 +122,6 @@ define Device/NAND-512K | |||||||
| endef | endef | ||||||
|  |  | ||||||
| include cortex-a9.mk | include cortex-a9.mk | ||||||
|  | include cortex-a53.mk | ||||||
|  |  | ||||||
| $(eval $(call BuildImage)) | $(eval $(call BuildImage)) | ||||||
|   | |||||||
							
								
								
									
										16
									
								
								target/linux/mvebu/image/cortex-a53.mk
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								target/linux/mvebu/image/cortex-a53.mk
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | |||||||
|  | ifeq ($(SUBTARGET),cortexa53) | ||||||
|  |  | ||||||
|  | define Device/globalscale-espressobin | ||||||
|  |   KERNEL_NAME := Image | ||||||
|  |   KERNEL := kernel-bin | ||||||
|  |   DEVICE_TITLE := ESPRESSObin (Marvell Armada 3700 Community Board) | ||||||
|  |   DEVICE_PACKAGES := e2fsprogs ethtool mkf2fs kmod-fs-vfat kmod-usb2 kmod-usb3 kmod-usb-storage | ||||||
|  |   IMAGES := sdcard.img.gz | ||||||
|  |   IMAGE/sdcard.img.gz := boot-scr | boot-img-ext4 | sdcard-img-ext4 | gzip | append-metadata | ||||||
|  |   DEVICE_DTS := armada-3720-espressobin | ||||||
|  |   DTS_DIR := $(DTS_DIR)/marvell | ||||||
|  |   SUPPORTED_DEVICES := globalscale,espressobin | ||||||
|  | endef | ||||||
|  | TARGET_DEVICES += globalscale-espressobin | ||||||
|  |  | ||||||
|  | endif | ||||||
							
								
								
									
										10
									
								
								target/linux/mvebu/image/globalscale-espressobin.bootscript
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								target/linux/mvebu/image/globalscale-espressobin.bootscript
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | |||||||
|  | setenv bootargs "root=PARTUUID=@ROOT@-02 rw rootwait" | ||||||
|  |  | ||||||
|  | if test -n "${console}"; then | ||||||
|  | 	setenv bootargs "${bootargs} ${console}" | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | load mmc 0:1 ${fdt_addr} armada-3720-espressobin.dtb | ||||||
|  | load mmc 0:1 ${kernel_addr} Image | ||||||
|  |  | ||||||
|  | booti ${kernel_addr} - ${fdt_addr} | ||||||
| @@ -0,0 +1,78 @@ | |||||||
|  | From adf4e289dd7f801c3fe12e0e6b491e11e548cd3d Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Gregory CLEMENT <gregory.clement@free-electrons.com> | ||||||
|  | Date: Thu, 30 Nov 2017 14:40:27 +0100 | ||||||
|  | Subject: clk: mvebu: armada-37xx-periph: cosmetic changes | ||||||
|  |  | ||||||
|  | This patches fixes few cosmetic issues such as alignment, blank lines | ||||||
|  | and required space. | ||||||
|  |  | ||||||
|  | Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com> | ||||||
|  | Signed-off-by: Stephen Boyd <sboyd@codeaurora.org> | ||||||
|  | --- | ||||||
|  |  drivers/clk/mvebu/armada-37xx-periph.c | 17 +++++++++-------- | ||||||
|  |  1 file changed, 9 insertions(+), 8 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/drivers/clk/mvebu/armada-37xx-periph.c | ||||||
|  | +++ b/drivers/clk/mvebu/armada-37xx-periph.c | ||||||
|  | @@ -79,6 +79,7 @@ static const struct clk_div_table clk_ta | ||||||
|  |  	{ .val = 1, .div = 4, }, | ||||||
|  |  	{ .val = 0, .div = 0, }, /* last entry */ | ||||||
|  |  }; | ||||||
|  | + | ||||||
|  |  static const struct clk_ops clk_double_div_ops; | ||||||
|  |   | ||||||
|  |  #define PERIPH_GATE(_name, _bit)		\ | ||||||
|  | @@ -217,7 +218,7 @@ PERIPH_CLK_FULL(counter, 23, 20, DIV_SEL | ||||||
|  |  PERIPH_CLK_FULL_DD(eip97, 24, 24, DIV_SEL2, DIV_SEL2, 22, 19); | ||||||
|  |  PERIPH_CLK_MUX_DIV(cpu, 22, DIV_SEL0, 28, clk_table6); | ||||||
|  |   | ||||||
|  | -static struct clk_periph_data data_nb[] ={ | ||||||
|  | +static struct clk_periph_data data_nb[] = { | ||||||
|  |  	REF_CLK_FULL_DD(mmc), | ||||||
|  |  	REF_CLK_FULL_DD(sata_host), | ||||||
|  |  	REF_CLK_FULL_DD(sec_at), | ||||||
|  | @@ -281,7 +282,7 @@ static unsigned int get_div(void __iomem | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  static unsigned long clk_double_div_recalc_rate(struct clk_hw *hw, | ||||||
|  | -		unsigned long parent_rate) | ||||||
|  | +						unsigned long parent_rate) | ||||||
|  |  { | ||||||
|  |  	struct clk_double_div *double_div = to_clk_double_div(hw); | ||||||
|  |  	unsigned int div; | ||||||
|  | @@ -303,6 +304,7 @@ static const struct of_device_id armada_ | ||||||
|  |  	.data = data_sb, }, | ||||||
|  |  	{ } | ||||||
|  |  }; | ||||||
|  | + | ||||||
|  |  static int armada_3700_add_composite_clk(const struct clk_periph_data *data, | ||||||
|  |  					 void __iomem *reg, spinlock_t *lock, | ||||||
|  |  					 struct device *dev, struct clk_hw **hw) | ||||||
|  | @@ -355,9 +357,9 @@ static int armada_3700_add_composite_clk | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	*hw = clk_hw_register_composite(dev, data->name, data->parent_names, | ||||||
|  | -				       data->num_parents, mux_hw, | ||||||
|  | -				       mux_ops, rate_hw, rate_ops, | ||||||
|  | -				       gate_hw, gate_ops, CLK_IGNORE_UNUSED); | ||||||
|  | +					data->num_parents, mux_hw, | ||||||
|  | +					mux_ops, rate_hw, rate_ops, | ||||||
|  | +					gate_hw, gate_ops, CLK_IGNORE_UNUSED); | ||||||
|  |   | ||||||
|  |  	if (IS_ERR(*hw)) | ||||||
|  |  		return PTR_ERR(*hw); | ||||||
|  | @@ -406,12 +408,11 @@ static int armada_3700_periph_clock_prob | ||||||
|  |  		if (armada_3700_add_composite_clk(&data[i], reg, | ||||||
|  |  						  &driver_data->lock, dev, hw)) | ||||||
|  |  			dev_err(dev, "Can't register periph clock %s\n", | ||||||
|  | -			       data[i].name); | ||||||
|  | - | ||||||
|  | +				data[i].name); | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, | ||||||
|  | -				  driver_data->hw_data); | ||||||
|  | +				     driver_data->hw_data); | ||||||
|  |  	if (ret) { | ||||||
|  |  		for (i = 0; i < num_periph; i++) | ||||||
|  |  			clk_hw_unregister(driver_data->hw_data->hws[i]); | ||||||
| @@ -0,0 +1,178 @@ | |||||||
|  | From 9818a7a4fd10f72537cdf2a5ec3402f2c245ea24 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Gregory CLEMENT <gregory.clement@free-electrons.com> | ||||||
|  | Date: Thu, 30 Nov 2017 14:40:28 +0100 | ||||||
|  | Subject: clk: mvebu: armada-37xx-periph: prepare cpu clk to be | ||||||
|  |  used with DVFS | ||||||
|  |  | ||||||
|  | When DVFS will be enabled then the cpu clk will use a different set of | ||||||
|  | register at run time. That means that we won't be able to use the common | ||||||
|  | callback and need to use our own ones. | ||||||
|  |  | ||||||
|  | This patch prepares this change by switching on our own set of callbacks | ||||||
|  | without modifying the behavior of the clocks. | ||||||
|  |  | ||||||
|  | Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com> | ||||||
|  | Signed-off-by: Stephen Boyd <sboyd@codeaurora.org> | ||||||
|  | --- | ||||||
|  |  drivers/clk/mvebu/armada-37xx-periph.c | 82 ++++++++++++++++++++++++++++++---- | ||||||
|  |  1 file changed, 73 insertions(+), 9 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/drivers/clk/mvebu/armada-37xx-periph.c | ||||||
|  | +++ b/drivers/clk/mvebu/armada-37xx-periph.c | ||||||
|  | @@ -46,7 +46,17 @@ struct clk_double_div { | ||||||
|  |  	u8 shift2; | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  | +struct clk_pm_cpu { | ||||||
|  | +	struct clk_hw hw; | ||||||
|  | +	void __iomem *reg_mux; | ||||||
|  | +	u8 shift_mux; | ||||||
|  | +	u32 mask_mux; | ||||||
|  | +	void __iomem *reg_div; | ||||||
|  | +	u8 shift_div; | ||||||
|  | +}; | ||||||
|  | + | ||||||
|  |  #define to_clk_double_div(_hw) container_of(_hw, struct clk_double_div, hw) | ||||||
|  | +#define to_clk_pm_cpu(_hw) container_of(_hw, struct clk_pm_cpu, hw) | ||||||
|  |   | ||||||
|  |  struct clk_periph_data { | ||||||
|  |  	const char *name; | ||||||
|  | @@ -55,6 +65,7 @@ struct clk_periph_data { | ||||||
|  |  	struct clk_hw *mux_hw; | ||||||
|  |  	struct clk_hw *rate_hw; | ||||||
|  |  	struct clk_hw *gate_hw; | ||||||
|  | +	struct clk_hw *muxrate_hw; | ||||||
|  |  	bool is_double_div; | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  | @@ -81,6 +92,7 @@ static const struct clk_div_table clk_ta | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  |  static const struct clk_ops clk_double_div_ops; | ||||||
|  | +static const struct clk_ops clk_pm_cpu_ops; | ||||||
|  |   | ||||||
|  |  #define PERIPH_GATE(_name, _bit)		\ | ||||||
|  |  struct clk_gate gate_##_name = {		\ | ||||||
|  | @@ -122,6 +134,18 @@ struct clk_divider rate_##_name = {		\ | ||||||
|  |  	}					\ | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  | +#define PERIPH_PM_CPU(_name, _shift1, _reg, _shift2)	\ | ||||||
|  | +struct clk_pm_cpu muxrate_##_name = {		\ | ||||||
|  | +	.reg_mux = (void *)TBG_SEL,		\ | ||||||
|  | +	.mask_mux = 3,				\ | ||||||
|  | +	.shift_mux = _shift1,			\ | ||||||
|  | +	.reg_div = (void *)_reg,		\ | ||||||
|  | +	.shift_div = _shift2,			\ | ||||||
|  | +	.hw.init = &(struct clk_init_data){	\ | ||||||
|  | +		.ops =  &clk_pm_cpu_ops,	\ | ||||||
|  | +	}					\ | ||||||
|  | +}; | ||||||
|  | + | ||||||
|  |  #define PERIPH_CLK_FULL_DD(_name, _bit, _shift, _reg1, _reg2, _shift1, _shift2)\ | ||||||
|  |  static PERIPH_GATE(_name, _bit);			    \ | ||||||
|  |  static PERIPH_MUX(_name, _shift);			    \ | ||||||
|  | @@ -136,10 +160,6 @@ static PERIPH_DIV(_name, _reg, _shift1, | ||||||
|  |  static PERIPH_GATE(_name, _bit);			\ | ||||||
|  |  static PERIPH_DIV(_name, _reg, _shift, _table); | ||||||
|  |   | ||||||
|  | -#define PERIPH_CLK_MUX_DIV(_name, _shift,  _reg, _shift_div, _table)	\ | ||||||
|  | -static PERIPH_MUX(_name, _shift);			    \ | ||||||
|  | -static PERIPH_DIV(_name, _reg, _shift_div, _table); | ||||||
|  | - | ||||||
|  |  #define PERIPH_CLK_MUX_DD(_name, _shift, _reg1, _reg2, _shift1, _shift2)\ | ||||||
|  |  static PERIPH_MUX(_name, _shift);			    \ | ||||||
|  |  static PERIPH_DOUBLEDIV(_name, _reg1, _reg2, _shift1, _shift2); | ||||||
|  | @@ -180,13 +200,12 @@ static PERIPH_DOUBLEDIV(_name, _reg1, _r | ||||||
|  |  	  .rate_hw = &rate_##_name.hw,				\ | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | -#define REF_CLK_MUX_DIV(_name)				\ | ||||||
|  | +#define REF_CLK_PM_CPU(_name)				\ | ||||||
|  |  	{ .name = #_name,				\ | ||||||
|  |  	  .parent_names = (const char *[]){ "TBG-A-P",	\ | ||||||
|  |  	      "TBG-B-P", "TBG-A-S", "TBG-B-S"},		\ | ||||||
|  |  	  .num_parents = 4,				\ | ||||||
|  | -	  .mux_hw = &mux_##_name.hw,			\ | ||||||
|  | -	  .rate_hw = &rate_##_name.hw,			\ | ||||||
|  | +	  .muxrate_hw = &muxrate_##_name.hw,		\ | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  #define REF_CLK_MUX_DD(_name)				\ | ||||||
|  | @@ -216,7 +235,7 @@ PERIPH_CLK_FULL_DD(ddr_fclk, 21, 16, DIV | ||||||
|  |  PERIPH_CLK_FULL(trace, 22, 18, DIV_SEL0, 20, clk_table6); | ||||||
|  |  PERIPH_CLK_FULL(counter, 23, 20, DIV_SEL0, 23, clk_table6); | ||||||
|  |  PERIPH_CLK_FULL_DD(eip97, 24, 24, DIV_SEL2, DIV_SEL2, 22, 19); | ||||||
|  | -PERIPH_CLK_MUX_DIV(cpu, 22, DIV_SEL0, 28, clk_table6); | ||||||
|  | +static PERIPH_PM_CPU(cpu, 22, DIV_SEL0, 28); | ||||||
|  |   | ||||||
|  |  static struct clk_periph_data data_nb[] = { | ||||||
|  |  	REF_CLK_FULL_DD(mmc), | ||||||
|  | @@ -235,7 +254,7 @@ static struct clk_periph_data data_nb[] | ||||||
|  |  	REF_CLK_FULL(trace), | ||||||
|  |  	REF_CLK_FULL(counter), | ||||||
|  |  	REF_CLK_FULL_DD(eip97), | ||||||
|  | -	REF_CLK_MUX_DIV(cpu), | ||||||
|  | +	REF_CLK_PM_CPU(cpu), | ||||||
|  |  	{ }, | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  | @@ -297,6 +316,37 @@ static const struct clk_ops clk_double_d | ||||||
|  |  	.recalc_rate = clk_double_div_recalc_rate, | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  | +static u8 clk_pm_cpu_get_parent(struct clk_hw *hw) | ||||||
|  | +{ | ||||||
|  | +	struct clk_pm_cpu *pm_cpu = to_clk_pm_cpu(hw); | ||||||
|  | +	int num_parents = clk_hw_get_num_parents(hw); | ||||||
|  | +	u32 val; | ||||||
|  | + | ||||||
|  | +	val = readl(pm_cpu->reg_mux) >> pm_cpu->shift_mux; | ||||||
|  | +	val &= pm_cpu->mask_mux; | ||||||
|  | + | ||||||
|  | +	if (val >= num_parents) | ||||||
|  | +		return -EINVAL; | ||||||
|  | + | ||||||
|  | +	return val; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static unsigned long clk_pm_cpu_recalc_rate(struct clk_hw *hw, | ||||||
|  | +					    unsigned long parent_rate) | ||||||
|  | +{ | ||||||
|  | +	struct clk_pm_cpu *pm_cpu = to_clk_pm_cpu(hw); | ||||||
|  | +	unsigned int div; | ||||||
|  | + | ||||||
|  | +	div = get_div(pm_cpu->reg_div, pm_cpu->shift_div); | ||||||
|  | + | ||||||
|  | +	return DIV_ROUND_UP_ULL((u64)parent_rate, div); | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static const struct clk_ops clk_pm_cpu_ops = { | ||||||
|  | +	.get_parent = clk_pm_cpu_get_parent, | ||||||
|  | +	.recalc_rate = clk_pm_cpu_recalc_rate, | ||||||
|  | +}; | ||||||
|  | + | ||||||
|  |  static const struct of_device_id armada_3700_periph_clock_of_match[] = { | ||||||
|  |  	{ .compatible = "marvell,armada-3700-periph-clock-nb", | ||||||
|  |  	  .data = data_nb, }, | ||||||
|  | @@ -356,6 +406,20 @@ static int armada_3700_add_composite_clk | ||||||
|  |  		} | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | +	if (data->muxrate_hw) { | ||||||
|  | +		struct clk_pm_cpu *pmcpu_clk; | ||||||
|  | +		struct clk_hw *muxrate_hw = data->muxrate_hw; | ||||||
|  | + | ||||||
|  | +		pmcpu_clk =  to_clk_pm_cpu(muxrate_hw); | ||||||
|  | +		pmcpu_clk->reg_mux = reg + (u64)pmcpu_clk->reg_mux; | ||||||
|  | +		pmcpu_clk->reg_div = reg + (u64)pmcpu_clk->reg_div; | ||||||
|  | + | ||||||
|  | +		mux_hw = muxrate_hw; | ||||||
|  | +		rate_hw = muxrate_hw; | ||||||
|  | +		mux_ops = muxrate_hw->init->ops; | ||||||
|  | +		rate_ops = muxrate_hw->init->ops; | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  |  	*hw = clk_hw_register_composite(dev, data->name, data->parent_names, | ||||||
|  |  					data->num_parents, mux_hw, | ||||||
|  |  					mux_ops, rate_hw, rate_ops, | ||||||
| @@ -0,0 +1,315 @@ | |||||||
|  | From 2089dc33ea0e3917465929d4020fbff3d6dbf7f4 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Gregory CLEMENT <gregory.clement@free-electrons.com> | ||||||
|  | Date: Thu, 30 Nov 2017 14:40:29 +0100 | ||||||
|  | Subject: clk: mvebu: armada-37xx-periph: add DVFS support for cpu clocks | ||||||
|  |  | ||||||
|  | When DVFS is enabled the CPU clock setting is done using an other set of | ||||||
|  | registers. | ||||||
|  |  | ||||||
|  | These Power Management registers are exposed through a syscon as they | ||||||
|  | will also be used by other drivers such as the cpufreq. | ||||||
|  |  | ||||||
|  | This patch add the possibility to modify the CPU frequency using the | ||||||
|  | associate load level matching the target frequency. Then all the | ||||||
|  | frequency switch is handle by the hardware. | ||||||
|  |  | ||||||
|  | Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com> | ||||||
|  | [sboyd@codeaurora.org: Grow a local variable for regmap pointer | ||||||
|  | to keep lines shorter] | ||||||
|  | Signed-off-by: Stephen Boyd <sboyd@codeaurora.org> | ||||||
|  | --- | ||||||
|  |  drivers/clk/mvebu/armada-37xx-periph.c | 221 ++++++++++++++++++++++++++++++++- | ||||||
|  |  1 file changed, 217 insertions(+), 4 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/drivers/clk/mvebu/armada-37xx-periph.c | ||||||
|  | +++ b/drivers/clk/mvebu/armada-37xx-periph.c | ||||||
|  | @@ -21,9 +21,11 @@ | ||||||
|  |   */ | ||||||
|  |   | ||||||
|  |  #include <linux/clk-provider.h> | ||||||
|  | +#include <linux/mfd/syscon.h> | ||||||
|  |  #include <linux/of.h> | ||||||
|  |  #include <linux/of_device.h> | ||||||
|  |  #include <linux/platform_device.h> | ||||||
|  | +#include <linux/regmap.h> | ||||||
|  |  #include <linux/slab.h> | ||||||
|  |   | ||||||
|  |  #define TBG_SEL		0x0 | ||||||
|  | @@ -33,6 +35,26 @@ | ||||||
|  |  #define CLK_SEL		0x10 | ||||||
|  |  #define CLK_DIS		0x14 | ||||||
|  |   | ||||||
|  | +#define LOAD_LEVEL_NR	4 | ||||||
|  | + | ||||||
|  | +#define ARMADA_37XX_NB_L0L1	0x18 | ||||||
|  | +#define ARMADA_37XX_NB_L2L3	0x1C | ||||||
|  | +#define		ARMADA_37XX_NB_TBG_DIV_OFF	13 | ||||||
|  | +#define		ARMADA_37XX_NB_TBG_DIV_MASK	0x7 | ||||||
|  | +#define		ARMADA_37XX_NB_CLK_SEL_OFF	11 | ||||||
|  | +#define		ARMADA_37XX_NB_CLK_SEL_MASK	0x1 | ||||||
|  | +#define		ARMADA_37XX_NB_TBG_SEL_OFF	9 | ||||||
|  | +#define		ARMADA_37XX_NB_TBG_SEL_MASK	0x3 | ||||||
|  | +#define		ARMADA_37XX_NB_CONFIG_SHIFT	16 | ||||||
|  | +#define ARMADA_37XX_NB_DYN_MOD	0x24 | ||||||
|  | +#define		ARMADA_37XX_NB_DFS_EN	31 | ||||||
|  | +#define ARMADA_37XX_NB_CPU_LOAD	0x30 | ||||||
|  | +#define		ARMADA_37XX_NB_CPU_LOAD_MASK	0x3 | ||||||
|  | +#define		ARMADA_37XX_DVFS_LOAD_0		0 | ||||||
|  | +#define		ARMADA_37XX_DVFS_LOAD_1		1 | ||||||
|  | +#define		ARMADA_37XX_DVFS_LOAD_2		2 | ||||||
|  | +#define		ARMADA_37XX_DVFS_LOAD_3		3 | ||||||
|  | + | ||||||
|  |  struct clk_periph_driver_data { | ||||||
|  |  	struct clk_hw_onecell_data *hw_data; | ||||||
|  |  	spinlock_t lock; | ||||||
|  | @@ -53,6 +75,7 @@ struct clk_pm_cpu { | ||||||
|  |  	u32 mask_mux; | ||||||
|  |  	void __iomem *reg_div; | ||||||
|  |  	u8 shift_div; | ||||||
|  | +	struct regmap *nb_pm_base; | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  |  #define to_clk_double_div(_hw) container_of(_hw, struct clk_double_div, hw) | ||||||
|  | @@ -316,14 +339,94 @@ static const struct clk_ops clk_double_d | ||||||
|  |  	.recalc_rate = clk_double_div_recalc_rate, | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  | +static void armada_3700_pm_dvfs_update_regs(unsigned int load_level, | ||||||
|  | +					    unsigned int *reg, | ||||||
|  | +					    unsigned int *offset) | ||||||
|  | +{ | ||||||
|  | +	if (load_level <= ARMADA_37XX_DVFS_LOAD_1) | ||||||
|  | +		*reg = ARMADA_37XX_NB_L0L1; | ||||||
|  | +	else | ||||||
|  | +		*reg = ARMADA_37XX_NB_L2L3; | ||||||
|  | + | ||||||
|  | +	if (load_level == ARMADA_37XX_DVFS_LOAD_0 || | ||||||
|  | +	    load_level ==  ARMADA_37XX_DVFS_LOAD_2) | ||||||
|  | +		*offset += ARMADA_37XX_NB_CONFIG_SHIFT; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static bool armada_3700_pm_dvfs_is_enabled(struct regmap *base) | ||||||
|  | +{ | ||||||
|  | +	unsigned int val, reg = ARMADA_37XX_NB_DYN_MOD; | ||||||
|  | + | ||||||
|  | +	if (IS_ERR(base)) | ||||||
|  | +		return false; | ||||||
|  | + | ||||||
|  | +	regmap_read(base, reg, &val); | ||||||
|  | + | ||||||
|  | +	return !!(val & BIT(ARMADA_37XX_NB_DFS_EN)); | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static unsigned int armada_3700_pm_dvfs_get_cpu_div(struct regmap *base) | ||||||
|  | +{ | ||||||
|  | +	unsigned int reg = ARMADA_37XX_NB_CPU_LOAD; | ||||||
|  | +	unsigned int offset = ARMADA_37XX_NB_TBG_DIV_OFF; | ||||||
|  | +	unsigned int load_level, div; | ||||||
|  | + | ||||||
|  | +	/* | ||||||
|  | +	 * This function is always called after the function | ||||||
|  | +	 * armada_3700_pm_dvfs_is_enabled, so no need to check again | ||||||
|  | +	 * if the base is valid. | ||||||
|  | +	 */ | ||||||
|  | +	regmap_read(base, reg, &load_level); | ||||||
|  | + | ||||||
|  | +	/* | ||||||
|  | +	 * The register and the offset inside this register accessed to | ||||||
|  | +	 * read the current divider depend on the load level | ||||||
|  | +	 */ | ||||||
|  | +	load_level &= ARMADA_37XX_NB_CPU_LOAD_MASK; | ||||||
|  | +	armada_3700_pm_dvfs_update_regs(load_level, ®, &offset); | ||||||
|  | + | ||||||
|  | +	regmap_read(base, reg, &div); | ||||||
|  | + | ||||||
|  | +	return (div >> offset) & ARMADA_37XX_NB_TBG_DIV_MASK; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static unsigned int armada_3700_pm_dvfs_get_cpu_parent(struct regmap *base) | ||||||
|  | +{ | ||||||
|  | +	unsigned int reg = ARMADA_37XX_NB_CPU_LOAD; | ||||||
|  | +	unsigned int offset = ARMADA_37XX_NB_TBG_SEL_OFF; | ||||||
|  | +	unsigned int load_level, sel; | ||||||
|  | + | ||||||
|  | +	/* | ||||||
|  | +	 * This function is always called after the function | ||||||
|  | +	 * armada_3700_pm_dvfs_is_enabled, so no need to check again | ||||||
|  | +	 * if the base is valid | ||||||
|  | +	 */ | ||||||
|  | +	regmap_read(base, reg, &load_level); | ||||||
|  | + | ||||||
|  | +	/* | ||||||
|  | +	 * The register and the offset inside this register accessed to | ||||||
|  | +	 * read the current divider depend on the load level | ||||||
|  | +	 */ | ||||||
|  | +	load_level &= ARMADA_37XX_NB_CPU_LOAD_MASK; | ||||||
|  | +	armada_3700_pm_dvfs_update_regs(load_level, ®, &offset); | ||||||
|  | + | ||||||
|  | +	regmap_read(base, reg, &sel); | ||||||
|  | + | ||||||
|  | +	return (sel >> offset) & ARMADA_37XX_NB_TBG_SEL_MASK; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  |  static u8 clk_pm_cpu_get_parent(struct clk_hw *hw) | ||||||
|  |  { | ||||||
|  |  	struct clk_pm_cpu *pm_cpu = to_clk_pm_cpu(hw); | ||||||
|  |  	int num_parents = clk_hw_get_num_parents(hw); | ||||||
|  |  	u32 val; | ||||||
|  |   | ||||||
|  | -	val = readl(pm_cpu->reg_mux) >> pm_cpu->shift_mux; | ||||||
|  | -	val &= pm_cpu->mask_mux; | ||||||
|  | +	if (armada_3700_pm_dvfs_is_enabled(pm_cpu->nb_pm_base)) { | ||||||
|  | +		val = armada_3700_pm_dvfs_get_cpu_parent(pm_cpu->nb_pm_base); | ||||||
|  | +	} else { | ||||||
|  | +		val = readl(pm_cpu->reg_mux) >> pm_cpu->shift_mux; | ||||||
|  | +		val &= pm_cpu->mask_mux; | ||||||
|  | +	} | ||||||
|  |   | ||||||
|  |  	if (val >= num_parents) | ||||||
|  |  		return -EINVAL; | ||||||
|  | @@ -331,19 +434,124 @@ static u8 clk_pm_cpu_get_parent(struct c | ||||||
|  |  	return val; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +static int clk_pm_cpu_set_parent(struct clk_hw *hw, u8 index) | ||||||
|  | +{ | ||||||
|  | +	struct clk_pm_cpu *pm_cpu = to_clk_pm_cpu(hw); | ||||||
|  | +	struct regmap *base = pm_cpu->nb_pm_base; | ||||||
|  | +	int load_level; | ||||||
|  | + | ||||||
|  | +	/* | ||||||
|  | +	 * We set the clock parent only if the DVFS is available but | ||||||
|  | +	 * not enabled. | ||||||
|  | +	 */ | ||||||
|  | +	if (IS_ERR(base) || armada_3700_pm_dvfs_is_enabled(base)) | ||||||
|  | +		return -EINVAL; | ||||||
|  | + | ||||||
|  | +	/* Set the parent clock for all the load level */ | ||||||
|  | +	for (load_level = 0; load_level < LOAD_LEVEL_NR; load_level++) { | ||||||
|  | +		unsigned int reg, mask,  val, | ||||||
|  | +			offset = ARMADA_37XX_NB_TBG_SEL_OFF; | ||||||
|  | + | ||||||
|  | +		armada_3700_pm_dvfs_update_regs(load_level, ®, &offset); | ||||||
|  | + | ||||||
|  | +		val = index << offset; | ||||||
|  | +		mask = ARMADA_37XX_NB_TBG_SEL_MASK << offset; | ||||||
|  | +		regmap_update_bits(base, reg, mask, val); | ||||||
|  | +	} | ||||||
|  | +	return 0; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  |  static unsigned long clk_pm_cpu_recalc_rate(struct clk_hw *hw, | ||||||
|  |  					    unsigned long parent_rate) | ||||||
|  |  { | ||||||
|  |  	struct clk_pm_cpu *pm_cpu = to_clk_pm_cpu(hw); | ||||||
|  |  	unsigned int div; | ||||||
|  |   | ||||||
|  | -	div = get_div(pm_cpu->reg_div, pm_cpu->shift_div); | ||||||
|  | - | ||||||
|  | +	if (armada_3700_pm_dvfs_is_enabled(pm_cpu->nb_pm_base)) | ||||||
|  | +		div = armada_3700_pm_dvfs_get_cpu_div(pm_cpu->nb_pm_base); | ||||||
|  | +	else | ||||||
|  | +		div = get_div(pm_cpu->reg_div, pm_cpu->shift_div); | ||||||
|  |  	return DIV_ROUND_UP_ULL((u64)parent_rate, div); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +static long clk_pm_cpu_round_rate(struct clk_hw *hw, unsigned long rate, | ||||||
|  | +				  unsigned long *parent_rate) | ||||||
|  | +{ | ||||||
|  | +	struct clk_pm_cpu *pm_cpu = to_clk_pm_cpu(hw); | ||||||
|  | +	struct regmap *base = pm_cpu->nb_pm_base; | ||||||
|  | +	unsigned int div = *parent_rate / rate; | ||||||
|  | +	unsigned int load_level; | ||||||
|  | +	/* only available when DVFS is enabled */ | ||||||
|  | +	if (!armada_3700_pm_dvfs_is_enabled(base)) | ||||||
|  | +		return -EINVAL; | ||||||
|  | + | ||||||
|  | +	for (load_level = 0; load_level < LOAD_LEVEL_NR; load_level++) { | ||||||
|  | +		unsigned int reg, val, offset = ARMADA_37XX_NB_TBG_DIV_OFF; | ||||||
|  | + | ||||||
|  | +		armada_3700_pm_dvfs_update_regs(load_level, ®, &offset); | ||||||
|  | + | ||||||
|  | +		regmap_read(base, reg, &val); | ||||||
|  | + | ||||||
|  | +		val >>= offset; | ||||||
|  | +		val &= ARMADA_37XX_NB_TBG_DIV_MASK; | ||||||
|  | +		if (val == div) | ||||||
|  | +			/* | ||||||
|  | +			 * We found a load level matching the target | ||||||
|  | +			 * divider, switch to this load level and | ||||||
|  | +			 * return. | ||||||
|  | +			 */ | ||||||
|  | +			return *parent_rate / div; | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	/* We didn't find any valid divider */ | ||||||
|  | +	return -EINVAL; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static int clk_pm_cpu_set_rate(struct clk_hw *hw, unsigned long rate, | ||||||
|  | +			       unsigned long parent_rate) | ||||||
|  | +{ | ||||||
|  | +	struct clk_pm_cpu *pm_cpu = to_clk_pm_cpu(hw); | ||||||
|  | +	struct regmap *base = pm_cpu->nb_pm_base; | ||||||
|  | +	unsigned int div = parent_rate / rate; | ||||||
|  | +	unsigned int load_level; | ||||||
|  | + | ||||||
|  | +	/* only available when DVFS is enabled */ | ||||||
|  | +	if (!armada_3700_pm_dvfs_is_enabled(base)) | ||||||
|  | +		return -EINVAL; | ||||||
|  | + | ||||||
|  | +	for (load_level = 0; load_level < LOAD_LEVEL_NR; load_level++) { | ||||||
|  | +		unsigned int reg, mask, val, | ||||||
|  | +			offset = ARMADA_37XX_NB_TBG_DIV_OFF; | ||||||
|  | + | ||||||
|  | +		armada_3700_pm_dvfs_update_regs(load_level, ®, &offset); | ||||||
|  | + | ||||||
|  | +		regmap_read(base, reg, &val); | ||||||
|  | +		val >>= offset; | ||||||
|  | +		val &= ARMADA_37XX_NB_TBG_DIV_MASK; | ||||||
|  | + | ||||||
|  | +		if (val == div) { | ||||||
|  | +			/* | ||||||
|  | +			 * We found a load level matching the target | ||||||
|  | +			 * divider, switch to this load level and | ||||||
|  | +			 * return. | ||||||
|  | +			 */ | ||||||
|  | +			reg = ARMADA_37XX_NB_CPU_LOAD; | ||||||
|  | +			mask = ARMADA_37XX_NB_CPU_LOAD_MASK; | ||||||
|  | +			regmap_update_bits(base, reg, mask, load_level); | ||||||
|  | + | ||||||
|  | +			return rate; | ||||||
|  | +		} | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	/* We didn't find any valid divider */ | ||||||
|  | +	return -EINVAL; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  |  static const struct clk_ops clk_pm_cpu_ops = { | ||||||
|  |  	.get_parent = clk_pm_cpu_get_parent, | ||||||
|  | +	.set_parent = clk_pm_cpu_set_parent, | ||||||
|  | +	.round_rate = clk_pm_cpu_round_rate, | ||||||
|  | +	.set_rate = clk_pm_cpu_set_rate, | ||||||
|  |  	.recalc_rate = clk_pm_cpu_recalc_rate, | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  | @@ -409,6 +617,7 @@ static int armada_3700_add_composite_clk | ||||||
|  |  	if (data->muxrate_hw) { | ||||||
|  |  		struct clk_pm_cpu *pmcpu_clk; | ||||||
|  |  		struct clk_hw *muxrate_hw = data->muxrate_hw; | ||||||
|  | +		struct regmap *map; | ||||||
|  |   | ||||||
|  |  		pmcpu_clk =  to_clk_pm_cpu(muxrate_hw); | ||||||
|  |  		pmcpu_clk->reg_mux = reg + (u64)pmcpu_clk->reg_mux; | ||||||
|  | @@ -418,6 +627,10 @@ static int armada_3700_add_composite_clk | ||||||
|  |  		rate_hw = muxrate_hw; | ||||||
|  |  		mux_ops = muxrate_hw->init->ops; | ||||||
|  |  		rate_ops = muxrate_hw->init->ops; | ||||||
|  | + | ||||||
|  | +		map = syscon_regmap_lookup_by_compatible( | ||||||
|  | +				"marvell,armada-3700-nb-pm"); | ||||||
|  | +		pmcpu_clk->nb_pm_base = map; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	*hw = clk_hw_register_composite(dev, data->name, data->parent_names, | ||||||
| @@ -0,0 +1,297 @@ | |||||||
|  | From 92ce45fb875d7c3e021cc454482fe0687ff54f29 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Gregory CLEMENT <gregory.clement@free-electrons.com> | ||||||
|  | Date: Thu, 14 Dec 2017 16:00:05 +0100 | ||||||
|  | Subject: cpufreq: Add DVFS support for Armada 37xx | ||||||
|  |  | ||||||
|  | This patch adds DVFS support for the Armada 37xx SoCs | ||||||
|  |  | ||||||
|  | There are up to four CPU frequency loads for Armada 37xx controlled by | ||||||
|  | the hardware. | ||||||
|  |  | ||||||
|  | This driver associates the CPU load level to a frequency, then the | ||||||
|  | hardware will switch while selecting a load level. | ||||||
|  |  | ||||||
|  | The hardware also can associate a voltage for each level (AVS support) | ||||||
|  | but it is not yet supported | ||||||
|  |  | ||||||
|  | Tested-by: Andre Heider <a.heider@gmail.com> | ||||||
|  | Acked-by: Viresh Kumar <viresh.kumar@linaro.org> | ||||||
|  | Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com> | ||||||
|  | Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> | ||||||
|  | --- | ||||||
|  |  drivers/cpufreq/Kconfig.arm           |   7 + | ||||||
|  |  drivers/cpufreq/Makefile              |   1 + | ||||||
|  |  drivers/cpufreq/armada-37xx-cpufreq.c | 241 ++++++++++++++++++++++++++++++++++ | ||||||
|  |  3 files changed, 249 insertions(+) | ||||||
|  |  create mode 100644 drivers/cpufreq/armada-37xx-cpufreq.c | ||||||
|  |  | ||||||
|  | --- a/drivers/cpufreq/Kconfig.arm | ||||||
|  | +++ b/drivers/cpufreq/Kconfig.arm | ||||||
|  | @@ -2,6 +2,13 @@ | ||||||
|  |  # ARM CPU Frequency scaling drivers | ||||||
|  |  # | ||||||
|  |   | ||||||
|  | +config ARM_ARMADA_37XX_CPUFREQ | ||||||
|  | +	tristate "Armada 37xx CPUFreq support" | ||||||
|  | +	depends on ARCH_MVEBU | ||||||
|  | +	help | ||||||
|  | +	  This adds the CPUFreq driver support for Marvell Armada 37xx SoCs. | ||||||
|  | +	  The Armada 37xx PMU supports 4 frequency and VDD levels. | ||||||
|  | + | ||||||
|  |  # big LITTLE core layer and glue drivers | ||||||
|  |  config ARM_BIG_LITTLE_CPUFREQ | ||||||
|  |  	tristate "Generic ARM big LITTLE CPUfreq driver" | ||||||
|  | --- a/drivers/cpufreq/Makefile | ||||||
|  | +++ b/drivers/cpufreq/Makefile | ||||||
|  | @@ -52,6 +52,7 @@ obj-$(CONFIG_ARM_BIG_LITTLE_CPUFREQ)	+= | ||||||
|  |  # LITTLE drivers, so that it is probed last. | ||||||
|  |  obj-$(CONFIG_ARM_DT_BL_CPUFREQ)		+= arm_big_little_dt.o | ||||||
|  |   | ||||||
|  | +obj-$(CONFIG_ARM_ARMADA_37XX_CPUFREQ)	+= armada-37xx-cpufreq.o | ||||||
|  |  obj-$(CONFIG_ARM_BRCMSTB_AVS_CPUFREQ)	+= brcmstb-avs-cpufreq.o | ||||||
|  |  obj-$(CONFIG_ARCH_DAVINCI)		+= davinci-cpufreq.o | ||||||
|  |  obj-$(CONFIG_ARM_EXYNOS5440_CPUFREQ)	+= exynos5440-cpufreq.o | ||||||
|  | --- /dev/null | ||||||
|  | +++ b/drivers/cpufreq/armada-37xx-cpufreq.c | ||||||
|  | @@ -0,0 +1,241 @@ | ||||||
|  | +// SPDX-License-Identifier: GPL-2.0+ | ||||||
|  | +/* | ||||||
|  | + * CPU frequency scaling support for Armada 37xx platform. | ||||||
|  | + * | ||||||
|  | + * Copyright (C) 2017 Marvell | ||||||
|  | + * | ||||||
|  | + * Gregory CLEMENT <gregory.clement@free-electrons.com> | ||||||
|  | + */ | ||||||
|  | + | ||||||
|  | +#include <linux/clk.h> | ||||||
|  | +#include <linux/cpu.h> | ||||||
|  | +#include <linux/cpufreq.h> | ||||||
|  | +#include <linux/err.h> | ||||||
|  | +#include <linux/interrupt.h> | ||||||
|  | +#include <linux/io.h> | ||||||
|  | +#include <linux/mfd/syscon.h> | ||||||
|  | +#include <linux/module.h> | ||||||
|  | +#include <linux/of_address.h> | ||||||
|  | +#include <linux/of_device.h> | ||||||
|  | +#include <linux/of_irq.h> | ||||||
|  | +#include <linux/platform_device.h> | ||||||
|  | +#include <linux/pm_opp.h> | ||||||
|  | +#include <linux/regmap.h> | ||||||
|  | +#include <linux/slab.h> | ||||||
|  | + | ||||||
|  | +/* Power management in North Bridge register set */ | ||||||
|  | +#define ARMADA_37XX_NB_L0L1	0x18 | ||||||
|  | +#define ARMADA_37XX_NB_L2L3	0x1C | ||||||
|  | +#define  ARMADA_37XX_NB_TBG_DIV_OFF	13 | ||||||
|  | +#define  ARMADA_37XX_NB_TBG_DIV_MASK	0x7 | ||||||
|  | +#define  ARMADA_37XX_NB_CLK_SEL_OFF	11 | ||||||
|  | +#define  ARMADA_37XX_NB_CLK_SEL_MASK	0x1 | ||||||
|  | +#define  ARMADA_37XX_NB_CLK_SEL_TBG	0x1 | ||||||
|  | +#define  ARMADA_37XX_NB_TBG_SEL_OFF	9 | ||||||
|  | +#define  ARMADA_37XX_NB_TBG_SEL_MASK	0x3 | ||||||
|  | +#define  ARMADA_37XX_NB_VDD_SEL_OFF	6 | ||||||
|  | +#define  ARMADA_37XX_NB_VDD_SEL_MASK	0x3 | ||||||
|  | +#define  ARMADA_37XX_NB_CONFIG_SHIFT	16 | ||||||
|  | +#define ARMADA_37XX_NB_DYN_MOD	0x24 | ||||||
|  | +#define  ARMADA_37XX_NB_CLK_SEL_EN	BIT(26) | ||||||
|  | +#define  ARMADA_37XX_NB_TBG_EN		BIT(28) | ||||||
|  | +#define  ARMADA_37XX_NB_DIV_EN		BIT(29) | ||||||
|  | +#define  ARMADA_37XX_NB_VDD_EN		BIT(30) | ||||||
|  | +#define  ARMADA_37XX_NB_DFS_EN		BIT(31) | ||||||
|  | +#define ARMADA_37XX_NB_CPU_LOAD 0x30 | ||||||
|  | +#define  ARMADA_37XX_NB_CPU_LOAD_MASK	0x3 | ||||||
|  | +#define  ARMADA_37XX_DVFS_LOAD_0	0 | ||||||
|  | +#define  ARMADA_37XX_DVFS_LOAD_1	1 | ||||||
|  | +#define  ARMADA_37XX_DVFS_LOAD_2	2 | ||||||
|  | +#define  ARMADA_37XX_DVFS_LOAD_3	3 | ||||||
|  | + | ||||||
|  | +/* | ||||||
|  | + * On Armada 37xx the Power management manages 4 level of CPU load, | ||||||
|  | + * each level can be associated with a CPU clock source, a CPU | ||||||
|  | + * divider, a VDD level, etc... | ||||||
|  | + */ | ||||||
|  | +#define LOAD_LEVEL_NR	4 | ||||||
|  | + | ||||||
|  | +struct armada_37xx_dvfs { | ||||||
|  | +	u32 cpu_freq_max; | ||||||
|  | +	u8 divider[LOAD_LEVEL_NR]; | ||||||
|  | +}; | ||||||
|  | + | ||||||
|  | +static struct armada_37xx_dvfs armada_37xx_dvfs[] = { | ||||||
|  | +	{.cpu_freq_max = 1200*1000*1000, .divider = {1, 2, 4, 6} }, | ||||||
|  | +	{.cpu_freq_max = 1000*1000*1000, .divider = {1, 2, 4, 5} }, | ||||||
|  | +	{.cpu_freq_max = 800*1000*1000,  .divider = {1, 2, 3, 4} }, | ||||||
|  | +	{.cpu_freq_max = 600*1000*1000,  .divider = {2, 4, 5, 6} }, | ||||||
|  | +}; | ||||||
|  | + | ||||||
|  | +static struct armada_37xx_dvfs *armada_37xx_cpu_freq_info_get(u32 freq) | ||||||
|  | +{ | ||||||
|  | +	int i; | ||||||
|  | + | ||||||
|  | +	for (i = 0; i < ARRAY_SIZE(armada_37xx_dvfs); i++) { | ||||||
|  | +		if (freq == armada_37xx_dvfs[i].cpu_freq_max) | ||||||
|  | +			return &armada_37xx_dvfs[i]; | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	pr_err("Unsupported CPU frequency %d MHz\n", freq/1000000); | ||||||
|  | +	return NULL; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +/* | ||||||
|  | + * Setup the four level managed by the hardware. Once the four level | ||||||
|  | + * will be configured then the DVFS will be enabled. | ||||||
|  | + */ | ||||||
|  | +static void __init armada37xx_cpufreq_dvfs_setup(struct regmap *base, | ||||||
|  | +						 struct clk *clk, u8 *divider) | ||||||
|  | +{ | ||||||
|  | +	int load_lvl; | ||||||
|  | +	struct clk *parent; | ||||||
|  | + | ||||||
|  | +	for (load_lvl = 0; load_lvl < LOAD_LEVEL_NR; load_lvl++) { | ||||||
|  | +		unsigned int reg, mask, val, offset = 0; | ||||||
|  | + | ||||||
|  | +		if (load_lvl <= ARMADA_37XX_DVFS_LOAD_1) | ||||||
|  | +			reg = ARMADA_37XX_NB_L0L1; | ||||||
|  | +		else | ||||||
|  | +			reg = ARMADA_37XX_NB_L2L3; | ||||||
|  | + | ||||||
|  | +		if (load_lvl == ARMADA_37XX_DVFS_LOAD_0 || | ||||||
|  | +		    load_lvl == ARMADA_37XX_DVFS_LOAD_2) | ||||||
|  | +			offset += ARMADA_37XX_NB_CONFIG_SHIFT; | ||||||
|  | + | ||||||
|  | +		/* Set cpu clock source, for all the level we use TBG */ | ||||||
|  | +		val = ARMADA_37XX_NB_CLK_SEL_TBG << ARMADA_37XX_NB_CLK_SEL_OFF; | ||||||
|  | +		mask = (ARMADA_37XX_NB_CLK_SEL_MASK | ||||||
|  | +			<< ARMADA_37XX_NB_CLK_SEL_OFF); | ||||||
|  | + | ||||||
|  | +		/* | ||||||
|  | +		 * Set cpu divider based on the pre-computed array in | ||||||
|  | +		 * order to have balanced step. | ||||||
|  | +		 */ | ||||||
|  | +		val |= divider[load_lvl] << ARMADA_37XX_NB_TBG_DIV_OFF; | ||||||
|  | +		mask |= (ARMADA_37XX_NB_TBG_DIV_MASK | ||||||
|  | +			<< ARMADA_37XX_NB_TBG_DIV_OFF); | ||||||
|  | + | ||||||
|  | +		/* Set VDD divider which is actually the load level. */ | ||||||
|  | +		val |= load_lvl << ARMADA_37XX_NB_VDD_SEL_OFF; | ||||||
|  | +		mask |= (ARMADA_37XX_NB_VDD_SEL_MASK | ||||||
|  | +			<< ARMADA_37XX_NB_VDD_SEL_OFF); | ||||||
|  | + | ||||||
|  | +		val <<= offset; | ||||||
|  | +		mask <<= offset; | ||||||
|  | + | ||||||
|  | +		regmap_update_bits(base, reg, mask, val); | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	/* | ||||||
|  | +	 * Set cpu clock source, for all the level we keep the same | ||||||
|  | +	 * clock source that the one already configured. For this one | ||||||
|  | +	 * we need to use the clock framework | ||||||
|  | +	 */ | ||||||
|  | +	parent = clk_get_parent(clk); | ||||||
|  | +	clk_set_parent(clk, parent); | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static void __init armada37xx_cpufreq_disable_dvfs(struct regmap *base) | ||||||
|  | +{ | ||||||
|  | +	unsigned int reg = ARMADA_37XX_NB_DYN_MOD, | ||||||
|  | +		mask = ARMADA_37XX_NB_DFS_EN; | ||||||
|  | + | ||||||
|  | +	regmap_update_bits(base, reg, mask, 0); | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static void __init armada37xx_cpufreq_enable_dvfs(struct regmap *base) | ||||||
|  | +{ | ||||||
|  | +	unsigned int val, reg = ARMADA_37XX_NB_CPU_LOAD, | ||||||
|  | +		mask = ARMADA_37XX_NB_CPU_LOAD_MASK; | ||||||
|  | + | ||||||
|  | +	/* Start with the highest load (0) */ | ||||||
|  | +	val = ARMADA_37XX_DVFS_LOAD_0; | ||||||
|  | +	regmap_update_bits(base, reg, mask, val); | ||||||
|  | + | ||||||
|  | +	/* Now enable DVFS for the CPUs */ | ||||||
|  | +	reg = ARMADA_37XX_NB_DYN_MOD; | ||||||
|  | +	mask =	ARMADA_37XX_NB_CLK_SEL_EN | ARMADA_37XX_NB_TBG_EN | | ||||||
|  | +		ARMADA_37XX_NB_DIV_EN | ARMADA_37XX_NB_VDD_EN | | ||||||
|  | +		ARMADA_37XX_NB_DFS_EN; | ||||||
|  | + | ||||||
|  | +	regmap_update_bits(base, reg, mask, mask); | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static int __init armada37xx_cpufreq_driver_init(void) | ||||||
|  | +{ | ||||||
|  | +	struct armada_37xx_dvfs *dvfs; | ||||||
|  | +	struct platform_device *pdev; | ||||||
|  | +	unsigned int cur_frequency; | ||||||
|  | +	struct regmap *nb_pm_base; | ||||||
|  | +	struct device *cpu_dev; | ||||||
|  | +	int load_lvl, ret; | ||||||
|  | +	struct clk *clk; | ||||||
|  | + | ||||||
|  | +	nb_pm_base = | ||||||
|  | +		syscon_regmap_lookup_by_compatible("marvell,armada-3700-nb-pm"); | ||||||
|  | + | ||||||
|  | +	if (IS_ERR(nb_pm_base)) | ||||||
|  | +		return -ENODEV; | ||||||
|  | + | ||||||
|  | +	/* Before doing any configuration on the DVFS first, disable it */ | ||||||
|  | +	armada37xx_cpufreq_disable_dvfs(nb_pm_base); | ||||||
|  | + | ||||||
|  | +	/* | ||||||
|  | +	 * On CPU 0 register the operating points supported (which are | ||||||
|  | +	 * the nominal CPU frequency and full integer divisions of | ||||||
|  | +	 * it). | ||||||
|  | +	 */ | ||||||
|  | +	cpu_dev = get_cpu_device(0); | ||||||
|  | +	if (!cpu_dev) { | ||||||
|  | +		dev_err(cpu_dev, "Cannot get CPU\n"); | ||||||
|  | +		return -ENODEV; | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	clk = clk_get(cpu_dev, 0); | ||||||
|  | +	if (IS_ERR(clk)) { | ||||||
|  | +		dev_err(cpu_dev, "Cannot get clock for CPU0\n"); | ||||||
|  | +		return PTR_ERR(clk); | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	/* Get nominal (current) CPU frequency */ | ||||||
|  | +	cur_frequency = clk_get_rate(clk); | ||||||
|  | +	if (!cur_frequency) { | ||||||
|  | +		dev_err(cpu_dev, "Failed to get clock rate for CPU\n"); | ||||||
|  | +		return -EINVAL; | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	dvfs = armada_37xx_cpu_freq_info_get(cur_frequency); | ||||||
|  | +	if (!dvfs) | ||||||
|  | +		return -EINVAL; | ||||||
|  | + | ||||||
|  | +	armada37xx_cpufreq_dvfs_setup(nb_pm_base, clk, dvfs->divider); | ||||||
|  | + | ||||||
|  | +	for (load_lvl = ARMADA_37XX_DVFS_LOAD_0; load_lvl < LOAD_LEVEL_NR; | ||||||
|  | +	     load_lvl++) { | ||||||
|  | +		unsigned long freq = cur_frequency / dvfs->divider[load_lvl]; | ||||||
|  | + | ||||||
|  | +		ret = dev_pm_opp_add(cpu_dev, freq, 0); | ||||||
|  | +		if (ret) { | ||||||
|  | +			/* clean-up the already added opp before leaving */ | ||||||
|  | +			while (load_lvl-- > ARMADA_37XX_DVFS_LOAD_0) { | ||||||
|  | +				freq = cur_frequency / dvfs->divider[load_lvl]; | ||||||
|  | +				dev_pm_opp_remove(cpu_dev, freq); | ||||||
|  | +			} | ||||||
|  | +			return ret; | ||||||
|  | +		} | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	/* Now that everything is setup, enable the DVFS at hardware level */ | ||||||
|  | +	armada37xx_cpufreq_enable_dvfs(nb_pm_base); | ||||||
|  | + | ||||||
|  | +	pdev = platform_device_register_simple("cpufreq-dt", -1, NULL, 0); | ||||||
|  | + | ||||||
|  | +	return PTR_ERR_OR_ZERO(pdev); | ||||||
|  | +} | ||||||
|  | +/* late_initcall, to guarantee the driver is loaded after A37xx clock driver */ | ||||||
|  | +late_initcall(armada37xx_cpufreq_driver_init); | ||||||
|  | + | ||||||
|  | +MODULE_AUTHOR("Gregory CLEMENT <gregory.clement@free-electrons.com>"); | ||||||
|  | +MODULE_DESCRIPTION("Armada 37xx cpufreq driver"); | ||||||
|  | +MODULE_LICENSE("GPL"); | ||||||
| @@ -0,0 +1,70 @@ | |||||||
|  | From dd7aa8d4b53b3484ba31ba56f3ff1be7deb38530 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Maxime Chevallier <maxime.chevallier@smile.fr> | ||||||
|  | Date: Tue, 10 Oct 2017 10:43:18 +0200 | ||||||
|  | Subject: spi: a3700: Change SPI mode before asserting chip-select | ||||||
|  |  | ||||||
|  | The spi device mode should be configured in the controller before the | ||||||
|  | chip-select is asserted, so that a clock polarity configuration change | ||||||
|  | is not interpreted as a clock tick by the device. | ||||||
|  |  | ||||||
|  | This patch moves the mode setting to the 'prepare_message' function | ||||||
|  | instead of the 'transfer_one' function. | ||||||
|  |  | ||||||
|  | By doing so, this patch also removes redundant code in | ||||||
|  | a3700_spi_clock_set. | ||||||
|  |  | ||||||
|  | This was tested on EspressoBin board, with spidev. | ||||||
|  |  | ||||||
|  | Signed-off-by: Maxime Chevallier <maxime.chevallier@smile.fr> | ||||||
|  | Signed-off-by: Mark Brown <broonie@kernel.org> | ||||||
|  | --- | ||||||
|  |  drivers/spi/spi-armada-3700.c | 17 ++++------------- | ||||||
|  |  1 file changed, 4 insertions(+), 13 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/drivers/spi/spi-armada-3700.c | ||||||
|  | +++ b/drivers/spi/spi-armada-3700.c | ||||||
|  | @@ -214,7 +214,7 @@ static void a3700_spi_mode_set(struct a3 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  static void a3700_spi_clock_set(struct a3700_spi *a3700_spi, | ||||||
|  | -				unsigned int speed_hz, u16 mode) | ||||||
|  | +				unsigned int speed_hz) | ||||||
|  |  { | ||||||
|  |  	u32 val; | ||||||
|  |  	u32 prescale; | ||||||
|  | @@ -239,17 +239,6 @@ static void a3700_spi_clock_set(struct a | ||||||
|  |  		val |= A3700_SPI_CLK_CAPT_EDGE; | ||||||
|  |  		spireg_write(a3700_spi, A3700_SPI_IF_TIME_REG, val); | ||||||
|  |  	} | ||||||
|  | - | ||||||
|  | -	val = spireg_read(a3700_spi, A3700_SPI_IF_CFG_REG); | ||||||
|  | -	val &= ~(A3700_SPI_CLK_POL | A3700_SPI_CLK_PHA); | ||||||
|  | - | ||||||
|  | -	if (mode & SPI_CPOL) | ||||||
|  | -		val |= A3700_SPI_CLK_POL; | ||||||
|  | - | ||||||
|  | -	if (mode & SPI_CPHA) | ||||||
|  | -		val |= A3700_SPI_CLK_PHA; | ||||||
|  | - | ||||||
|  | -	spireg_write(a3700_spi, A3700_SPI_IF_CFG_REG, val); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  static void a3700_spi_bytelen_set(struct a3700_spi *a3700_spi, unsigned int len) | ||||||
|  | @@ -431,7 +420,7 @@ static void a3700_spi_transfer_setup(str | ||||||
|  |   | ||||||
|  |  	a3700_spi = spi_master_get_devdata(spi->master); | ||||||
|  |   | ||||||
|  | -	a3700_spi_clock_set(a3700_spi, xfer->speed_hz, spi->mode); | ||||||
|  | +	a3700_spi_clock_set(a3700_spi, xfer->speed_hz); | ||||||
|  |   | ||||||
|  |  	byte_len = xfer->bits_per_word >> 3; | ||||||
|  |   | ||||||
|  | @@ -592,6 +581,8 @@ static int a3700_spi_prepare_message(str | ||||||
|  |   | ||||||
|  |  	a3700_spi_bytelen_set(a3700_spi, 4); | ||||||
|  |   | ||||||
|  | +	a3700_spi_mode_set(a3700_spi, spi->mode); | ||||||
|  | + | ||||||
|  |  	return 0; | ||||||
|  |  } | ||||||
|  |   | ||||||
| @@ -0,0 +1,39 @@ | |||||||
|  | From c737abc193d16e62e23e2fb585b8b7398ab380d8 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: allen yan <yanwei@marvell.com> | ||||||
|  | Date: Thu, 7 Sep 2017 15:04:53 +0200 | ||||||
|  | Subject: arm64: dts: marvell: Fix A37xx UART0 register size | ||||||
|  |  | ||||||
|  | Armada-37xx UART0 registers are 0x200 bytes wide. Right next to them are | ||||||
|  | the UART1 registers that should not be declared in this node. | ||||||
|  |  | ||||||
|  | Update the example in DT bindings document accordingly. | ||||||
|  |  | ||||||
|  | Signed-off-by: allen yan <yanwei@marvell.com> | ||||||
|  | Signed-off-by: Miquel Raynal <miquel.raynal@free-electrons.com> | ||||||
|  | Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com> | ||||||
|  | --- | ||||||
|  |  Documentation/devicetree/bindings/serial/mvebu-uart.txt | 2 +- | ||||||
|  |  arch/arm64/boot/dts/marvell/armada-37xx.dtsi            | 2 +- | ||||||
|  |  2 files changed, 2 insertions(+), 2 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/Documentation/devicetree/bindings/serial/mvebu-uart.txt | ||||||
|  | +++ b/Documentation/devicetree/bindings/serial/mvebu-uart.txt | ||||||
|  | @@ -8,6 +8,6 @@ Required properties: | ||||||
|  |  Example: | ||||||
|  |  	serial@12000 { | ||||||
|  |  		compatible = "marvell,armada-3700-uart"; | ||||||
|  | -		reg = <0x12000 0x400>; | ||||||
|  | +		reg = <0x12000 0x200>; | ||||||
|  |  		interrupts = <43>; | ||||||
|  |  	}; | ||||||
|  | --- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi | ||||||
|  | +++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi | ||||||
|  | @@ -134,7 +134,7 @@ | ||||||
|  |   | ||||||
|  |  			uart0: serial@12000 { | ||||||
|  |  				compatible = "marvell,armada-3700-uart"; | ||||||
|  | -				reg = <0x12000 0x400>; | ||||||
|  | +				reg = <0x12000 0x200>; | ||||||
|  |  				interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>; | ||||||
|  |  				status = "disabled"; | ||||||
|  |  			}; | ||||||
| @@ -0,0 +1,27 @@ | |||||||
|  | From 2ff0d0b5bb397c3dc5c9b97bd0f20948f0b77740 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Miquel Raynal <miquel.raynal@free-electrons.com> | ||||||
|  | Date: Fri, 13 Oct 2017 11:01:57 +0200 | ||||||
|  | Subject: arm64: dts: marvell: armada-37xx: add UART clock | ||||||
|  |  | ||||||
|  | Add the missing clock property to armada-3700 UART node. | ||||||
|  |  | ||||||
|  | This clock will be used to derive the prescaler value to comply with | ||||||
|  | the requested baudrate. | ||||||
|  |  | ||||||
|  | Signed-off-by: Miquel Raynal <miquel.raynal@free-electrons.com> | ||||||
|  | Acked-by: Gregory CLEMENT <gregory.clement@free-electrons.com> | ||||||
|  | Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com> | ||||||
|  | --- | ||||||
|  |  arch/arm64/boot/dts/marvell/armada-37xx.dtsi | 1 + | ||||||
|  |  1 file changed, 1 insertion(+) | ||||||
|  |  | ||||||
|  | --- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi | ||||||
|  | +++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi | ||||||
|  | @@ -135,6 +135,7 @@ | ||||||
|  |  			uart0: serial@12000 { | ||||||
|  |  				compatible = "marvell,armada-3700-uart"; | ||||||
|  |  				reg = <0x12000 0x200>; | ||||||
|  | +				clocks = <&xtalclk>; | ||||||
|  |  				interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>; | ||||||
|  |  				status = "disabled"; | ||||||
|  |  			}; | ||||||
| @@ -0,0 +1,48 @@ | |||||||
|  | From e8d66e7927b2a15310df0eb44a67d120ea147a59 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Gregory CLEMENT <gregory.clement@free-electrons.com> | ||||||
|  | Date: Thu, 14 Dec 2017 16:00:06 +0100 | ||||||
|  | Subject: arm64: dts: marvell: armada-37xx: add nodes allowing cpufreq | ||||||
|  |  support | ||||||
|  |  | ||||||
|  | In order to be able to use cpu freq, we need to associate a clock to each | ||||||
|  | CPU and to expose the power management registers. | ||||||
|  |  | ||||||
|  | Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com> | ||||||
|  | --- | ||||||
|  |  arch/arm64/boot/dts/marvell/armada-372x.dtsi | 1 + | ||||||
|  |  arch/arm64/boot/dts/marvell/armada-37xx.dtsi | 7 +++++++ | ||||||
|  |  2 files changed, 8 insertions(+) | ||||||
|  |  | ||||||
|  | --- a/arch/arm64/boot/dts/marvell/armada-372x.dtsi | ||||||
|  | +++ b/arch/arm64/boot/dts/marvell/armada-372x.dtsi | ||||||
|  | @@ -56,6 +56,7 @@ | ||||||
|  |  			device_type = "cpu"; | ||||||
|  |  			compatible = "arm,cortex-a53","arm,armv8"; | ||||||
|  |  			reg = <0x1>; | ||||||
|  | +			clocks = <&nb_periph_clk 16>; | ||||||
|  |  			enable-method = "psci"; | ||||||
|  |  		}; | ||||||
|  |  	}; | ||||||
|  | --- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi | ||||||
|  | +++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi | ||||||
|  | @@ -64,6 +64,7 @@ | ||||||
|  |  			device_type = "cpu"; | ||||||
|  |  			compatible = "arm,cortex-a53", "arm,armv8"; | ||||||
|  |  			reg = <0>; | ||||||
|  | +			clocks = <&nb_periph_clk 16>; | ||||||
|  |  			enable-method = "psci"; | ||||||
|  |  		}; | ||||||
|  |  	}; | ||||||
|  | @@ -219,6 +220,12 @@ | ||||||
|  |  				}; | ||||||
|  |  			}; | ||||||
|  |   | ||||||
|  | +			nb_pm: syscon@14000 { | ||||||
|  | +				compatible = "marvell,armada-3700-nb-pm", | ||||||
|  | +					     "syscon"; | ||||||
|  | +				reg = <0x14000 0x60>; | ||||||
|  | +			}; | ||||||
|  | + | ||||||
|  |  			pinctrl_sb: pinctrl@18800 { | ||||||
|  |  				compatible = "marvell,armada3710-sb-pinctrl", | ||||||
|  |  					     "syscon", "simple-mfd"; | ||||||
| @@ -0,0 +1,20 @@ | |||||||
|  | From be893f672e340b56ca60f2f6c32fdd713a5852f5 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Kevin Mihelich <kevin@archlinuxarm.org> | ||||||
|  | Date: Tue, 4 Jul 2017 19:25:28 -0600 | ||||||
|  | Subject: arm64: dts: marvell: armada37xx: Add eth0 alias | ||||||
|  |  | ||||||
|  | Signed-off-by: Kevin Mihelich <kevin@archlinuxarm.org> | ||||||
|  | --- | ||||||
|  |  arch/arm64/boot/dts/marvell/armada-37xx.dtsi | 1 + | ||||||
|  |  1 file changed, 1 insertion(+) | ||||||
|  |  | ||||||
|  | --- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi | ||||||
|  | +++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi | ||||||
|  | @@ -54,6 +54,7 @@ | ||||||
|  |  	#size-cells = <2>; | ||||||
|  |   | ||||||
|  |  	aliases { | ||||||
|  | +		ethernet0 = ð0; | ||||||
|  |  		serial0 = &uart0; | ||||||
|  |  	}; | ||||||
|  |   | ||||||
| @@ -0,0 +1,29 @@ | |||||||
|  | --- a/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts | ||||||
|  | +++ b/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts | ||||||
|  | @@ -111,6 +111,26 @@ | ||||||
|  |  	status = "okay"; | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  | +&spi0 { | ||||||
|  | +	status = "okay"; | ||||||
|  | + | ||||||
|  | +	w25q32dw@0 { | ||||||
|  | +		#address-cells = <1>; | ||||||
|  | +		#size-cells = <1>; | ||||||
|  | +		compatible = "jedec,spi-nor"; | ||||||
|  | +		reg = <0>; | ||||||
|  | +		spi-max-frequency = <104000000>; | ||||||
|  | +		m25,fast-read; | ||||||
|  | + | ||||||
|  | +		pinctrl-names = "default"; | ||||||
|  | +		pinctrl-0 = <&spi_quad_pins>; | ||||||
|  | +	}; | ||||||
|  | +}; | ||||||
|  | + | ||||||
|  | +&i2c0 { | ||||||
|  | +	status = "okay"; | ||||||
|  | +}; | ||||||
|  | + | ||||||
|  |  &mdio { | ||||||
|  |  	switch0: switch0@1 { | ||||||
|  |  		compatible = "marvell,mv88e6085"; | ||||||
| @@ -0,0 +1,66 @@ | |||||||
|  | From patchwork Thu Sep 28 12:58:32 2017 | ||||||
|  | Content-Type: text/plain; charset="utf-8" | ||||||
|  | MIME-Version: 1.0 | ||||||
|  | Content-Transfer-Encoding: 7bit | ||||||
|  | Subject: [v2, 1/7] PCI: aardvark: fix logic in PCI configuration read/write | ||||||
|  |  functions | ||||||
|  | X-Patchwork-Submitter: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | ||||||
|  | X-Patchwork-Id: 819586 | ||||||
|  | Message-Id: <20170928125838.11887-2-thomas.petazzoni@free-electrons.com> | ||||||
|  | To: Bjorn Helgaas <bhelgaas@google.com>, linux-pci@vger.kernel.org | ||||||
|  | Cc: Jason Cooper <jason@lakedaemon.net>, Andrew Lunn <andrew@lunn.ch>, | ||||||
|  |  Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>, Gregory Clement | ||||||
|  |  <gregory.clement@free-electrons.com>,  | ||||||
|  |  Nadav Haklai <nadavh@marvell.com>, Hanna Hawa <hannah@marvell.com>, | ||||||
|  |  Yehuda Yitschak <yehuday@marvell.com>, | ||||||
|  |  linux-arm-kernel@lists.infradead.org, Antoine Tenart | ||||||
|  |  <antoine.tenart@free-electrons.com>, =?utf-8?q?Miqu=C3=A8l_Raynal?= | ||||||
|  |  <miquel.raynal@free-electrons.com>, Victor Gu <xigu@marvell.com>, | ||||||
|  |  stable@vger.kernel.org, Thomas Petazzoni | ||||||
|  |  <thomas.petazzoni@free-electrons.com> | ||||||
|  | Date: Thu, 28 Sep 2017 14:58:32 +0200 | ||||||
|  | From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | ||||||
|  | List-Id: <linux-pci.vger.kernel.org> | ||||||
|  |  | ||||||
|  | From: Victor Gu <xigu@marvell.com> | ||||||
|  |  | ||||||
|  | The PCI configuration space read/write functions were special casing | ||||||
|  | the situation where PCI_SLOT(devfn) != 0, and returned | ||||||
|  | PCIBIOS_DEVICE_NOT_FOUND in this case. | ||||||
|  |  | ||||||
|  | However, will this is what is intended for the root bus, it is not | ||||||
|  | intended for the child busses, as it prevents discovering devices with | ||||||
|  | PCI_SLOT(x) != 0. Therefore, we return PCIBIOS_DEVICE_NOT_FOUND only | ||||||
|  | if we're on the root bus. | ||||||
|  |  | ||||||
|  | Fixes: 8c39d710363c1 ("PCI: aardvark: Add Aardvark PCI host controller driver") | ||||||
|  | Cc: <stable@vger.kernel.org> | ||||||
|  | Signed-off-by: Victor Gu <xigu@marvell.com> | ||||||
|  | Reviewed-by: Wilson Ding <dingwei@marvell.com> | ||||||
|  | Reviewed-by: Nadav Haklai <nadavh@marvell.com> | ||||||
|  | [Thomas: tweak commit log.] | ||||||
|  | Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | ||||||
|  | --- | ||||||
|  |  drivers/pci/host/pci-aardvark.c | 4 ++-- | ||||||
|  |  1 file changed, 2 insertions(+), 2 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/drivers/pci/host/pci-aardvark.c | ||||||
|  | +++ b/drivers/pci/host/pci-aardvark.c | ||||||
|  | @@ -440,7 +440,7 @@ static int advk_pcie_rd_conf(struct pci_ | ||||||
|  |  	u32 reg; | ||||||
|  |  	int ret; | ||||||
|  |   | ||||||
|  | -	if (PCI_SLOT(devfn) != 0) { | ||||||
|  | +	if ((bus->number == pcie->root_bus_nr) && (PCI_SLOT(devfn) != 0)) { | ||||||
|  |  		*val = 0xffffffff; | ||||||
|  |  		return PCIBIOS_DEVICE_NOT_FOUND; | ||||||
|  |  	} | ||||||
|  | @@ -494,7 +494,7 @@ static int advk_pcie_wr_conf(struct pci_ | ||||||
|  |  	int offset; | ||||||
|  |  	int ret; | ||||||
|  |   | ||||||
|  | -	if (PCI_SLOT(devfn) != 0) | ||||||
|  | +	if ((bus->number == pcie->root_bus_nr) && (PCI_SLOT(devfn) != 0)) | ||||||
|  |  		return PCIBIOS_DEVICE_NOT_FOUND; | ||||||
|  |   | ||||||
|  |  	if (where % size) | ||||||
| @@ -0,0 +1,53 @@ | |||||||
|  | From patchwork Thu Sep 28 12:58:33 2017 | ||||||
|  | Content-Type: text/plain; charset="utf-8" | ||||||
|  | MIME-Version: 1.0 | ||||||
|  | Content-Transfer-Encoding: 7bit | ||||||
|  | Subject: [v2, | ||||||
|  |  2/7] PCI: aardvark: set PIO_ADDR_LS correctly in advk_pcie_rd_conf() | ||||||
|  | X-Patchwork-Submitter: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | ||||||
|  | X-Patchwork-Id: 819589 | ||||||
|  | Message-Id: <20170928125838.11887-3-thomas.petazzoni@free-electrons.com> | ||||||
|  | To: Bjorn Helgaas <bhelgaas@google.com>, linux-pci@vger.kernel.org | ||||||
|  | Cc: Jason Cooper <jason@lakedaemon.net>, Andrew Lunn <andrew@lunn.ch>, | ||||||
|  |  Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>, Gregory Clement | ||||||
|  |  <gregory.clement@free-electrons.com>,  | ||||||
|  |  Nadav Haklai <nadavh@marvell.com>, Hanna Hawa <hannah@marvell.com>, | ||||||
|  |  Yehuda Yitschak <yehuday@marvell.com>, | ||||||
|  |  linux-arm-kernel@lists.infradead.org, Antoine Tenart | ||||||
|  |  <antoine.tenart@free-electrons.com>, =?utf-8?q?Miqu=C3=A8l_Raynal?= | ||||||
|  |  <miquel.raynal@free-electrons.com>, Victor Gu <xigu@marvell.com>, | ||||||
|  |  stable@vger.kernel.org, Thomas Petazzoni | ||||||
|  |  <thomas.petazzoni@free-electrons.com> | ||||||
|  | Date: Thu, 28 Sep 2017 14:58:33 +0200 | ||||||
|  | From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | ||||||
|  | List-Id: <linux-pci.vger.kernel.org> | ||||||
|  |  | ||||||
|  | From: Victor Gu <xigu@marvell.com> | ||||||
|  |  | ||||||
|  | When setting the PIO_ADDR_LS register during a configuration read, we | ||||||
|  | were properly passing the device number, function number and register | ||||||
|  | number, but not the bus number, causing issues when reading the | ||||||
|  | configuration of PCIe devices. | ||||||
|  |  | ||||||
|  | Fixes: 8c39d710363c1 ("PCI: aardvark: Add Aardvark PCI host controller driver") | ||||||
|  | Cc: <stable@vger.kernel.org> | ||||||
|  | Signed-off-by: Victor Gu <xigu@marvell.com> | ||||||
|  | Reviewed-by: Wilson Ding <dingwei@marvell.com> | ||||||
|  | Reviewed-by: Nadav Haklai <nadavh@marvell.com> | ||||||
|  | [Thomas: tweak commit log.] | ||||||
|  | Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | ||||||
|  | --- | ||||||
|  |  drivers/pci/host/pci-aardvark.c | 2 +- | ||||||
|  |  1 file changed, 1 insertion(+), 1 deletion(-) | ||||||
|  |  | ||||||
|  | --- a/drivers/pci/host/pci-aardvark.c | ||||||
|  | +++ b/drivers/pci/host/pci-aardvark.c | ||||||
|  | @@ -459,7 +459,7 @@ static int advk_pcie_rd_conf(struct pci_ | ||||||
|  |  	advk_writel(pcie, reg, PIO_CTRL); | ||||||
|  |   | ||||||
|  |  	/* Program the address registers */ | ||||||
|  | -	reg = PCIE_BDF(devfn) | PCIE_CONF_REG(where); | ||||||
|  | +	reg = PCIE_CONF_ADDR(bus->number, devfn, where); | ||||||
|  |  	advk_writel(pcie, reg, PIO_ADDR_LS); | ||||||
|  |  	advk_writel(pcie, 0, PIO_ADDR_MS); | ||||||
|  |   | ||||||
| @@ -0,0 +1,137 @@ | |||||||
|  | From patchwork Thu Sep 28 12:58:34 2017 | ||||||
|  | Content-Type: text/plain; charset="utf-8" | ||||||
|  | MIME-Version: 1.0 | ||||||
|  | Content-Transfer-Encoding: 7bit | ||||||
|  | Subject: [v2, | ||||||
|  |  3/7] PCI: aardvark: set host and device to the same MAX payload size | ||||||
|  | X-Patchwork-Submitter: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | ||||||
|  | X-Patchwork-Id: 819587 | ||||||
|  | Message-Id: <20170928125838.11887-4-thomas.petazzoni@free-electrons.com> | ||||||
|  | To: Bjorn Helgaas <bhelgaas@google.com>, linux-pci@vger.kernel.org | ||||||
|  | Cc: Jason Cooper <jason@lakedaemon.net>, Andrew Lunn <andrew@lunn.ch>, | ||||||
|  |  Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>, Gregory Clement | ||||||
|  |  <gregory.clement@free-electrons.com>,  | ||||||
|  |  Nadav Haklai <nadavh@marvell.com>, Hanna Hawa <hannah@marvell.com>, | ||||||
|  |  Yehuda Yitschak <yehuday@marvell.com>, | ||||||
|  |  linux-arm-kernel@lists.infradead.org, Antoine Tenart | ||||||
|  |  <antoine.tenart@free-electrons.com>, =?utf-8?q?Miqu=C3=A8l_Raynal?= | ||||||
|  |  <miquel.raynal@free-electrons.com>, Victor Gu <xigu@marvell.com>, | ||||||
|  |  Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | ||||||
|  | Date: Thu, 28 Sep 2017 14:58:34 +0200 | ||||||
|  | From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | ||||||
|  | List-Id: <linux-pci.vger.kernel.org> | ||||||
|  |  | ||||||
|  | From: Victor Gu <xigu@marvell.com> | ||||||
|  |  | ||||||
|  | Since the Aardvark does not implement a PCIe root bus, the Linux PCIe | ||||||
|  | subsystem will not align the MAX payload size between the host and the | ||||||
|  | device. This patch ensures that the host and device have the same MAX | ||||||
|  | payload size, fixing a number of problems with various PCIe devices. | ||||||
|  |  | ||||||
|  | This is part of fixing bug | ||||||
|  | https://bugzilla.kernel.org/show_bug.cgi?id=196339, this commit was | ||||||
|  | reported as the user to be important to get a Intel 7260 mini-PCIe | ||||||
|  | WiFi card working. | ||||||
|  |  | ||||||
|  | Fixes: Fixes: 8c39d710363c1 ("PCI: aardvark: Add Aardvark PCI host controller driver") | ||||||
|  | Signed-off-by: Victor Gu <xigu@marvell.com> | ||||||
|  | Reviewed-by: Evan Wang <xswang@marvell.com> | ||||||
|  | Reviewed-by: Nadav Haklai <nadavh@marvell.com> | ||||||
|  | [Thomas: tweak commit log.] | ||||||
|  | Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | ||||||
|  | --- | ||||||
|  |  drivers/pci/host/pci-aardvark.c | 60 ++++++++++++++++++++++++++++++++++++++++- | ||||||
|  |  1 file changed, 59 insertions(+), 1 deletion(-) | ||||||
|  |  | ||||||
|  | --- a/drivers/pci/host/pci-aardvark.c | ||||||
|  | +++ b/drivers/pci/host/pci-aardvark.c | ||||||
|  | @@ -30,8 +30,10 @@ | ||||||
|  |  #define PCIE_CORE_DEV_CTRL_STATS_REG				0xc8 | ||||||
|  |  #define     PCIE_CORE_DEV_CTRL_STATS_RELAX_ORDER_DISABLE	(0 << 4) | ||||||
|  |  #define     PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ_SHIFT	5 | ||||||
|  | +#define     PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ		0x2 | ||||||
|  |  #define     PCIE_CORE_DEV_CTRL_STATS_SNOOP_DISABLE		(0 << 11) | ||||||
|  |  #define     PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SIZE_SHIFT	12 | ||||||
|  | +#define     PCIE_CORE_MPS_UNIT_BYTE				128 | ||||||
|  |  #define PCIE_CORE_LINK_CTRL_STAT_REG				0xd0 | ||||||
|  |  #define     PCIE_CORE_LINK_L0S_ENTRY				BIT(0) | ||||||
|  |  #define     PCIE_CORE_LINK_TRAINING				BIT(5) | ||||||
|  | @@ -297,7 +299,8 @@ static void advk_pcie_setup_hw(struct ad | ||||||
|  |   | ||||||
|  |  	/* Set PCIe Device Control and Status 1 PF0 register */ | ||||||
|  |  	reg = PCIE_CORE_DEV_CTRL_STATS_RELAX_ORDER_DISABLE | | ||||||
|  | -		(7 << PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ_SHIFT) | | ||||||
|  | +		(PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ << | ||||||
|  | +		 PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ_SHIFT) | | ||||||
|  |  		PCIE_CORE_DEV_CTRL_STATS_SNOOP_DISABLE | | ||||||
|  |  		PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SIZE_SHIFT; | ||||||
|  |  	advk_writel(pcie, reg, PCIE_CORE_DEV_CTRL_STATS_REG); | ||||||
|  | @@ -879,6 +882,58 @@ out_release_res: | ||||||
|  |  	return err; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +static int advk_pcie_find_smpss(struct pci_dev *dev, void *data) | ||||||
|  | +{ | ||||||
|  | +	u8 *smpss = data; | ||||||
|  | + | ||||||
|  | +	if (!dev) | ||||||
|  | +		return 0; | ||||||
|  | + | ||||||
|  | +	if (!pci_is_pcie(dev)) | ||||||
|  | +		return 0; | ||||||
|  | + | ||||||
|  | +	if (*smpss > dev->pcie_mpss) | ||||||
|  | +		*smpss = dev->pcie_mpss; | ||||||
|  | + | ||||||
|  | +	return 0; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static int advk_pcie_bus_configure_mps(struct pci_dev *dev, void *data) | ||||||
|  | +{ | ||||||
|  | +	int mps; | ||||||
|  | + | ||||||
|  | +	if (!dev) | ||||||
|  | +		return 0; | ||||||
|  | + | ||||||
|  | +	if (!pci_is_pcie(dev)) | ||||||
|  | +		return 0; | ||||||
|  | + | ||||||
|  | +	mps = PCIE_CORE_MPS_UNIT_BYTE << *(u8 *)data; | ||||||
|  | +	pcie_set_mps(dev, mps); | ||||||
|  | + | ||||||
|  | +	return 0; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static void advk_pcie_configure_mps(struct pci_bus *bus, struct advk_pcie *pcie) | ||||||
|  | +{ | ||||||
|  | +	u8 smpss = PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ; | ||||||
|  | +	u32 reg; | ||||||
|  | + | ||||||
|  | +	/* Find the minimal supported MAX payload size */ | ||||||
|  | +	advk_pcie_find_smpss(bus->self, &smpss); | ||||||
|  | +	pci_walk_bus(bus, advk_pcie_find_smpss, &smpss); | ||||||
|  | + | ||||||
|  | +	/* Configure RC MAX payload size */ | ||||||
|  | +	reg = advk_readl(pcie, PCIE_CORE_DEV_CTRL_STATS_REG); | ||||||
|  | +	reg &= ~PCI_EXP_DEVCTL_PAYLOAD; | ||||||
|  | +	reg |= smpss << PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ_SHIFT; | ||||||
|  | +	advk_writel(pcie, reg, PCIE_CORE_DEV_CTRL_STATS_REG); | ||||||
|  | + | ||||||
|  | +	/* Configure device MAX payload size */ | ||||||
|  | +	advk_pcie_bus_configure_mps(bus->self, &smpss); | ||||||
|  | +	pci_walk_bus(bus, advk_pcie_bus_configure_mps, &smpss); | ||||||
|  | +} | ||||||
|  | + | ||||||
|  |  static int advk_pcie_probe(struct platform_device *pdev) | ||||||
|  |  { | ||||||
|  |  	struct device *dev = &pdev->dev; | ||||||
|  | @@ -952,6 +1007,9 @@ static int advk_pcie_probe(struct platfo | ||||||
|  |  	list_for_each_entry(child, &bus->children, node) | ||||||
|  |  		pcie_bus_configure_settings(child); | ||||||
|  |   | ||||||
|  | +	/* Configure the MAX pay load size */ | ||||||
|  | +	advk_pcie_configure_mps(bus, pcie); | ||||||
|  | + | ||||||
|  |  	pci_bus_add_devices(bus); | ||||||
|  |  	return 0; | ||||||
|  |  } | ||||||
| @@ -0,0 +1,143 @@ | |||||||
|  | From patchwork Thu Sep 28 12:58:35 2017 | ||||||
|  | Content-Type: text/plain; charset="utf-8" | ||||||
|  | MIME-Version: 1.0 | ||||||
|  | Content-Transfer-Encoding: 7bit | ||||||
|  | Subject: [v2, | ||||||
|  |  4/7] PCI: aardvark: use isr1 instead of isr0 interrupt in legacy irq | ||||||
|  |  mode | ||||||
|  | X-Patchwork-Submitter: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | ||||||
|  | X-Patchwork-Id: 819592 | ||||||
|  | Message-Id: <20170928125838.11887-5-thomas.petazzoni@free-electrons.com> | ||||||
|  | To: Bjorn Helgaas <bhelgaas@google.com>, linux-pci@vger.kernel.org | ||||||
|  | Cc: Jason Cooper <jason@lakedaemon.net>, Andrew Lunn <andrew@lunn.ch>, | ||||||
|  |  Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>, Gregory Clement | ||||||
|  |  <gregory.clement@free-electrons.com>,  | ||||||
|  |  Nadav Haklai <nadavh@marvell.com>, Hanna Hawa <hannah@marvell.com>, | ||||||
|  |  Yehuda Yitschak <yehuday@marvell.com>, | ||||||
|  |  linux-arm-kernel@lists.infradead.org, Antoine Tenart | ||||||
|  |  <antoine.tenart@free-electrons.com>, =?utf-8?q?Miqu=C3=A8l_Raynal?= | ||||||
|  |  <miquel.raynal@free-electrons.com>, Victor Gu <xigu@marvell.com>, | ||||||
|  |  Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | ||||||
|  | Date: Thu, 28 Sep 2017 14:58:35 +0200 | ||||||
|  | From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | ||||||
|  | List-Id: <linux-pci.vger.kernel.org> | ||||||
|  |  | ||||||
|  | From: Victor Gu <xigu@marvell.com> | ||||||
|  |  | ||||||
|  | The Aardvark has two interrupts sets: | ||||||
|  |  | ||||||
|  |  - first set is bit[23:16] of PCIe ISR 0 register(RD0074840h) | ||||||
|  |  | ||||||
|  |  - second set is bit[11:8] of PCIe ISR 1 register(RD0074848h) | ||||||
|  |  | ||||||
|  | Only one set should be used, while another set should be masked. | ||||||
|  |  | ||||||
|  | The second set, ISR1, is more advanced, the Legacy INT_X status bit is | ||||||
|  | asserted once Assert_INTX message is received, and de-asserted after | ||||||
|  | Deassert_INTX message is received. Therefore, it matches what the | ||||||
|  | driver is currently doing in the ->irq_mask() and ->irq_unmask() | ||||||
|  | functions. The ISR0 requires additional work to deassert the | ||||||
|  | interrupt, which the driver doesn't do currently. | ||||||
|  |  | ||||||
|  | This commit resolves a number of issues with legacy interrupts. | ||||||
|  |  | ||||||
|  | This is part of fixing bug | ||||||
|  | https://bugzilla.kernel.org/show_bug.cgi?id=196339, this commit was | ||||||
|  | reported as the user to be important to get a Intel 7260 mini-PCIe | ||||||
|  | WiFi card working. | ||||||
|  |  | ||||||
|  | Fixes: 8c39d710363c1 ("PCI: aardvark: Add Aardvark PCI host controller driver") | ||||||
|  | Signed-off-by: Victor Gu <xigu@marvell.com> | ||||||
|  | Reviewed-by: Evan Wang <xswang@marvell.com> | ||||||
|  | Reviewed-by: Nadav Haklai <nadavh@marvell.com> | ||||||
|  | [Thomas: tweak commit log.] | ||||||
|  | Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | ||||||
|  | --- | ||||||
|  |  drivers/pci/host/pci-aardvark.c | 41 ++++++++++++++++++++++++----------------- | ||||||
|  |  1 file changed, 24 insertions(+), 17 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/drivers/pci/host/pci-aardvark.c | ||||||
|  | +++ b/drivers/pci/host/pci-aardvark.c | ||||||
|  | @@ -105,7 +105,8 @@ | ||||||
|  |  #define PCIE_ISR1_MASK_REG			(CONTROL_BASE_ADDR + 0x4C) | ||||||
|  |  #define     PCIE_ISR1_POWER_STATE_CHANGE	BIT(4) | ||||||
|  |  #define     PCIE_ISR1_FLUSH			BIT(5) | ||||||
|  | -#define     PCIE_ISR1_ALL_MASK			GENMASK(5, 4) | ||||||
|  | +#define     PCIE_ISR1_INTX_ASSERT(val)		BIT(8 + (val)) | ||||||
|  | +#define     PCIE_ISR1_ALL_MASK			GENMASK(11, 4) | ||||||
|  |  #define PCIE_MSI_ADDR_LOW_REG			(CONTROL_BASE_ADDR + 0x50) | ||||||
|  |  #define PCIE_MSI_ADDR_HIGH_REG			(CONTROL_BASE_ADDR + 0x54) | ||||||
|  |  #define PCIE_MSI_STATUS_REG			(CONTROL_BASE_ADDR + 0x58) | ||||||
|  | @@ -615,9 +616,9 @@ static void advk_pcie_irq_mask(struct ir | ||||||
|  |  	irq_hw_number_t hwirq = irqd_to_hwirq(d); | ||||||
|  |  	u32 mask; | ||||||
|  |   | ||||||
|  | -	mask = advk_readl(pcie, PCIE_ISR0_MASK_REG); | ||||||
|  | -	mask |= PCIE_ISR0_INTX_ASSERT(hwirq); | ||||||
|  | -	advk_writel(pcie, mask, PCIE_ISR0_MASK_REG); | ||||||
|  | +	mask = advk_readl(pcie, PCIE_ISR1_MASK_REG); | ||||||
|  | +	mask |= PCIE_ISR1_INTX_ASSERT(hwirq); | ||||||
|  | +	advk_writel(pcie, mask, PCIE_ISR1_MASK_REG); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  static void advk_pcie_irq_unmask(struct irq_data *d) | ||||||
|  | @@ -626,9 +627,9 @@ static void advk_pcie_irq_unmask(struct | ||||||
|  |  	irq_hw_number_t hwirq = irqd_to_hwirq(d); | ||||||
|  |  	u32 mask; | ||||||
|  |   | ||||||
|  | -	mask = advk_readl(pcie, PCIE_ISR0_MASK_REG); | ||||||
|  | -	mask &= ~PCIE_ISR0_INTX_ASSERT(hwirq); | ||||||
|  | -	advk_writel(pcie, mask, PCIE_ISR0_MASK_REG); | ||||||
|  | +	mask = advk_readl(pcie, PCIE_ISR1_MASK_REG); | ||||||
|  | +	mask &= ~PCIE_ISR1_INTX_ASSERT(hwirq); | ||||||
|  | +	advk_writel(pcie, mask, PCIE_ISR1_MASK_REG); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  static int advk_pcie_irq_map(struct irq_domain *h, | ||||||
|  | @@ -771,29 +772,35 @@ static void advk_pcie_handle_msi(struct | ||||||
|  |   | ||||||
|  |  static void advk_pcie_handle_int(struct advk_pcie *pcie) | ||||||
|  |  { | ||||||
|  | -	u32 val, mask, status; | ||||||
|  | +	u32 isr0_val, isr0_mask, isr0_status; | ||||||
|  | +	u32 isr1_val, isr1_mask, isr1_status; | ||||||
|  |  	int i, virq; | ||||||
|  |   | ||||||
|  | -	val = advk_readl(pcie, PCIE_ISR0_REG); | ||||||
|  | -	mask = advk_readl(pcie, PCIE_ISR0_MASK_REG); | ||||||
|  | -	status = val & ((~mask) & PCIE_ISR0_ALL_MASK); | ||||||
|  | - | ||||||
|  | -	if (!status) { | ||||||
|  | -		advk_writel(pcie, val, PCIE_ISR0_REG); | ||||||
|  | +	isr0_val = advk_readl(pcie, PCIE_ISR0_REG); | ||||||
|  | +	isr0_mask = advk_readl(pcie, PCIE_ISR0_MASK_REG); | ||||||
|  | +	isr0_status = isr0_val & ((~isr0_mask) & PCIE_ISR0_ALL_MASK); | ||||||
|  | + | ||||||
|  | +	isr1_val = advk_readl(pcie, PCIE_ISR1_REG); | ||||||
|  | +	isr1_mask = advk_readl(pcie, PCIE_ISR1_MASK_REG); | ||||||
|  | +	isr1_status = isr1_val & ((~isr1_mask) & PCIE_ISR1_ALL_MASK); | ||||||
|  | + | ||||||
|  | +	if (!isr0_status && !isr1_status) { | ||||||
|  | +		advk_writel(pcie, isr0_val, PCIE_ISR0_REG); | ||||||
|  | +		advk_writel(pcie, isr1_val, PCIE_ISR1_REG); | ||||||
|  |  		return; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	/* Process MSI interrupts */ | ||||||
|  | -	if (status & PCIE_ISR0_MSI_INT_PENDING) | ||||||
|  | +	if (isr0_status & PCIE_ISR0_MSI_INT_PENDING) | ||||||
|  |  		advk_pcie_handle_msi(pcie); | ||||||
|  |   | ||||||
|  |  	/* Process legacy interrupts */ | ||||||
|  |  	for (i = 0; i < PCI_NUM_INTX; i++) { | ||||||
|  | -		if (!(status & PCIE_ISR0_INTX_ASSERT(i))) | ||||||
|  | +		if (!(isr1_status & PCIE_ISR1_INTX_ASSERT(i))) | ||||||
|  |  			continue; | ||||||
|  |   | ||||||
|  | -		advk_writel(pcie, PCIE_ISR0_INTX_ASSERT(i), | ||||||
|  | -			    PCIE_ISR0_REG); | ||||||
|  | +		advk_writel(pcie, PCIE_ISR1_INTX_ASSERT(i), | ||||||
|  | +			    PCIE_ISR1_REG); | ||||||
|  |   | ||||||
|  |  		virq = irq_find_mapping(pcie->irq_domain, i); | ||||||
|  |  		generic_handle_irq(virq); | ||||||
| @@ -0,0 +1,55 @@ | |||||||
|  | From patchwork Thu Sep 28 12:58:36 2017 | ||||||
|  | Content-Type: text/plain; charset="utf-8" | ||||||
|  | MIME-Version: 1.0 | ||||||
|  | Content-Transfer-Encoding: 7bit | ||||||
|  | Subject: [v2,5/7] PCI: aardvark: disable LOS state by default | ||||||
|  | X-Patchwork-Submitter: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | ||||||
|  | X-Patchwork-Id: 819590 | ||||||
|  | Message-Id: <20170928125838.11887-6-thomas.petazzoni@free-electrons.com> | ||||||
|  | To: Bjorn Helgaas <bhelgaas@google.com>, linux-pci@vger.kernel.org | ||||||
|  | Cc: Jason Cooper <jason@lakedaemon.net>, Andrew Lunn <andrew@lunn.ch>, | ||||||
|  |  Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>, Gregory Clement | ||||||
|  |  <gregory.clement@free-electrons.com>,  | ||||||
|  |  Nadav Haklai <nadavh@marvell.com>, Hanna Hawa <hannah@marvell.com>, | ||||||
|  |  Yehuda Yitschak <yehuday@marvell.com>, | ||||||
|  |  linux-arm-kernel@lists.infradead.org, Antoine Tenart | ||||||
|  |  <antoine.tenart@free-electrons.com>, =?utf-8?q?Miqu=C3=A8l_Raynal?= | ||||||
|  |  <miquel.raynal@free-electrons.com>, Victor Gu <xigu@marvell.com>, | ||||||
|  |  Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | ||||||
|  | Date: Thu, 28 Sep 2017 14:58:36 +0200 | ||||||
|  | From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | ||||||
|  | List-Id: <linux-pci.vger.kernel.org> | ||||||
|  |  | ||||||
|  | From: Victor Gu <xigu@marvell.com> | ||||||
|  |  | ||||||
|  | Some PCIe devices do not support LOS, and will cause timeouts if the | ||||||
|  | root complex forces the LOS state. This patch disables the LOS state | ||||||
|  | by default. | ||||||
|  |  | ||||||
|  | This is part of fixing bug | ||||||
|  | https://bugzilla.kernel.org/show_bug.cgi?id=196339, this commit was | ||||||
|  | reported as the user to be important to get a Intel 7260 mini-PCIe | ||||||
|  | WiFi card working. | ||||||
|  |  | ||||||
|  | Fixes: 8c39d710363c1 ("PCI: aardvark: Add Aardvark PCI host controller driver") | ||||||
|  | Signed-off-by: Victor Gu <xigu@marvell.com> | ||||||
|  | Reviewed-by: Evan Wang <xswang@marvell.com> | ||||||
|  | Reviewed-by: Nadav Haklai <nadavh@marvell.com> | ||||||
|  | [Thomas: tweak commit log.] | ||||||
|  | Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | ||||||
|  | --- | ||||||
|  |  drivers/pci/host/pci-aardvark.c | 3 +-- | ||||||
|  |  1 file changed, 1 insertion(+), 2 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/drivers/pci/host/pci-aardvark.c | ||||||
|  | +++ b/drivers/pci/host/pci-aardvark.c | ||||||
|  | @@ -368,8 +368,7 @@ static void advk_pcie_setup_hw(struct ad | ||||||
|  |   | ||||||
|  |  	advk_pcie_wait_for_link(pcie); | ||||||
|  |   | ||||||
|  | -	reg = PCIE_CORE_LINK_L0S_ENTRY | | ||||||
|  | -		(1 << PCIE_CORE_LINK_WIDTH_SHIFT); | ||||||
|  | +	reg = (1 << PCIE_CORE_LINK_WIDTH_SHIFT); | ||||||
|  |  	advk_writel(pcie, reg, PCIE_CORE_LINK_CTRL_STAT_REG); | ||||||
|  |   | ||||||
|  |  	reg = advk_readl(pcie, PCIE_CORE_CMD_STATUS_REG); | ||||||
| @@ -0,0 +1,63 @@ | |||||||
|  | From patchwork Thu Sep 28 12:58:37 2017 | ||||||
|  | Content-Type: text/plain; charset="utf-8" | ||||||
|  | MIME-Version: 1.0 | ||||||
|  | Content-Transfer-Encoding: 7bit | ||||||
|  | Subject: [v2,6/7] PCI: aardvark: fix PCIe max read request size setting | ||||||
|  | X-Patchwork-Submitter: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | ||||||
|  | X-Patchwork-Id: 819591 | ||||||
|  | Message-Id: <20170928125838.11887-7-thomas.petazzoni@free-electrons.com> | ||||||
|  | To: Bjorn Helgaas <bhelgaas@google.com>, linux-pci@vger.kernel.org | ||||||
|  | Cc: Jason Cooper <jason@lakedaemon.net>, Andrew Lunn <andrew@lunn.ch>, | ||||||
|  |  Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>, Gregory Clement | ||||||
|  |  <gregory.clement@free-electrons.com>,  | ||||||
|  |  Nadav Haklai <nadavh@marvell.com>, Hanna Hawa <hannah@marvell.com>, | ||||||
|  |  Yehuda Yitschak <yehuday@marvell.com>, | ||||||
|  |  linux-arm-kernel@lists.infradead.org, Antoine Tenart | ||||||
|  |  <antoine.tenart@free-electrons.com>, =?utf-8?q?Miqu=C3=A8l_Raynal?= | ||||||
|  |  <miquel.raynal@free-electrons.com>, Evan Wang <xswang@marvell.com>, | ||||||
|  |  Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | ||||||
|  | Date: Thu, 28 Sep 2017 14:58:37 +0200 | ||||||
|  | From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | ||||||
|  | List-Id: <linux-pci.vger.kernel.org> | ||||||
|  |  | ||||||
|  | From: Evan Wang <xswang@marvell.com> | ||||||
|  |  | ||||||
|  | There is an obvious typo issue in the definition of the PCIe maximum | ||||||
|  | read request size: a bit shift is directly used as a value, while it | ||||||
|  | should be used to shift the correct value. | ||||||
|  |  | ||||||
|  | This is part of fixing bug | ||||||
|  | https://bugzilla.kernel.org/show_bug.cgi?id=196339, this commit was | ||||||
|  | reported as the user to be important to get a Intel 7260 mini-PCIe | ||||||
|  | WiFi card working. | ||||||
|  |  | ||||||
|  | Fixes: 8c39d710363c1 ("PCI: aardvark: Add Aardvark PCI host controller driver") | ||||||
|  | Signed-off-by: Evan Wang <xswang@marvell.com> | ||||||
|  | Reviewed-by: Victor Gu <xigu@marvell.com> | ||||||
|  | Reviewed-by: Nadav Haklai <nadavh@marvell.com> | ||||||
|  | [Thomas: tweak commit log.] | ||||||
|  | Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | ||||||
|  | --- | ||||||
|  |  drivers/pci/host/pci-aardvark.c | 4 +++- | ||||||
|  |  1 file changed, 3 insertions(+), 1 deletion(-) | ||||||
|  |  | ||||||
|  | --- a/drivers/pci/host/pci-aardvark.c | ||||||
|  | +++ b/drivers/pci/host/pci-aardvark.c | ||||||
|  | @@ -33,6 +33,7 @@ | ||||||
|  |  #define     PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ		0x2 | ||||||
|  |  #define     PCIE_CORE_DEV_CTRL_STATS_SNOOP_DISABLE		(0 << 11) | ||||||
|  |  #define     PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SIZE_SHIFT	12 | ||||||
|  | +#define     PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SZ		0x2 | ||||||
|  |  #define     PCIE_CORE_MPS_UNIT_BYTE				128 | ||||||
|  |  #define PCIE_CORE_LINK_CTRL_STAT_REG				0xd0 | ||||||
|  |  #define     PCIE_CORE_LINK_L0S_ENTRY				BIT(0) | ||||||
|  | @@ -303,7 +304,8 @@ static void advk_pcie_setup_hw(struct ad | ||||||
|  |  		(PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ << | ||||||
|  |  		 PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ_SHIFT) | | ||||||
|  |  		PCIE_CORE_DEV_CTRL_STATS_SNOOP_DISABLE | | ||||||
|  | -		PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SIZE_SHIFT; | ||||||
|  | +		(PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SZ << | ||||||
|  | +		 PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SIZE_SHIFT); | ||||||
|  |  	advk_writel(pcie, reg, PCIE_CORE_DEV_CTRL_STATS_REG); | ||||||
|  |   | ||||||
|  |  	/* Program PCIe Control 2 to disable strict ordering */ | ||||||
		Reference in New Issue
	
	Block a user