From 0dc3d0e7c74bf8d50c3a2bfc335e5e717ab4051f Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 11 Sep 2015 08:49:42 +0000 Subject: [PATCH] ipq806x: delete from CC branch; it is broken and unsupported Signed-off-by: Felix Fietkau git-svn-id: svn://svn.openwrt.org/openwrt/branches/chaos_calmer@46845 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- target/linux/ipq806x/Makefile | 22 - target/linux/ipq806x/base-files.mk | 3 - target/linux/ipq806x/base-files/etc/inittab | 4 - .../base-files/etc/uci-defaults/network | 38 - .../linux/ipq806x/base-files/lib/ipq806x.sh | 43 - .../lib/preinit/03_preinit_do_ipq806x.sh | 12 - target/linux/ipq806x/config-3.18 | 420 ---------- target/linux/ipq806x/image/Makefile | 41 - target/linux/ipq806x/modules.mk | 32 - .../001-spi-qup-Add-DMA-capabilities.patch | 522 ------------ ...pi-qup-Fix-incorrect-block-transfers.patch | 376 --------- .../003-spi-qup-Ensure-done-detection.patch | 56 -- ...og-qcom-use-timer-devicetree-binding.patch | 67 -- ...-description-of-KPSS-WDT-for-IPQ8064.patch | 48 -- ...hdog-entries-to-DT-timer-binding-doc.patch | 50 -- .../patches-3.18/020-add-ap148-bootargs.patch | 46 -- .../021-add-ap148-partitions.patch | 35 - .../patches-3.18/022-add-db149-dts.patch | 160 ---- ...-ipq806x-Disable-i2c-device-on-gsbi4.patch | 53 -- ...-Add-Qualcomm-DWC3-HS-SS-PHY-drivers.patch | 511 ------------ ...-qcom-add-USB-nodes-to-ipq806x-ap148.patch | 125 --- ...gsbi-Add-support-for-ADM-CRCI-muxing.patch | 249 ------ .../103-ARM-DT-ipq8064-Add-TCSR-support.patch | 65 -- ...om-Document-PCIe-devicetree-bindings.patch | 263 ------ ...-Add-Qualcomm-PCIe-controller-driver.patch | 753 ------------------ ...-add-pcie-nodes-to-ipq806x-platforms.patch | 268 ------- ...ically-select-PCI_DOMAINS-if-PCI-is-.patch | 29 - ...qcom-rpm-Driver-for-the-Qualcomm-RPM.patch | 654 --------------- ...mfd-qcom_rpm-Add-support-for-IPQ8064.patch | 71 -- ...bindings-Add-Qualcomm-RPM-DT-binding.patch | 247 ------ ...-qcom_rpm-Document-IPQ8064-resources.patch | 42 - ...dd-support-for-RPM-controller-SMB208.patch | 58 -- ...pm-Add-missing-state-flag-in-call-to.patch | 25 - .../126-add-rpm-to-ipq8064-dts.patch | 87 -- ...parent-doing-the-wrong-thing-when-IN.patch | 55 -- ...Add-__clk_mux_determine_rate_closest.patch | 120 --- ...gister_-divider-gate-mux-to-close-me.patch | 115 --- ...Krait-L2-register-accessor-functions.patch | 144 ---- ...lit-out-register-accessors-for-reuse.patch | 192 ----- ...to-downstream-clocks-during-set_rate.patch | 129 --- .../136-clk-Add-safe-switch-hook.patch | 170 ---- ...pport-for-High-Frequency-PLLs-HFPLLs.patch | 351 -------- .../138-clk-qcom-Add-HFPLL-driver.patch | 206 ----- .../139-clk-qcom-Add-IPQ806X-s-HFPLLs.patch | 127 --- ...lk-qcom-Add-support-for-Krait-clocks.patch | 271 ------- ...141-clk-qcom-Add-KPSS-ACC-GCC-driver.patch | 205 ----- ...om-Add-Krait-clock-controller-driver.patch | 435 ---------- ...le-to-register-cpufreq-on-Krait-CPUs.patch | 304 ------- ...-necessary-DT-data-for-Krait-cpufreq.patch | 100 --- ...-Add-a-cpufreq-krait-based-on-cpufre.patch | 461 ----------- ...arch-arm-force-ZRELADDR-on-arch-qcom.patch | 62 -- ...pport-for-NSS-GMAC-clocks-and-resets.patch | 733 ----------------- ...handle-support-to-the-platform-layer.patch | 105 --- ...r-path-at-the-end-of-stmmac_probe_co.patch | 65 -- ...c-add-fixed-link-device-tree-support.patch | 64 -- .../704-stmmac-add-ipq806x-glue-layer.patch | 427 ---------- ...pq806x-document-device-tree-bindings.patch | 52 -- ...reate-one-debugfs-dir-per-net-device.patch | 171 ---- ...s-qcom-add-mdio-nodes-to-ap148-db149.patch | 145 ---- ...-add-gmac-nodes-to-ipq806x-platforms.patch | 210 ----- target/linux/ipq806x/profiles/default.mk | 19 - 61 files changed, 10913 deletions(-) delete mode 100644 target/linux/ipq806x/Makefile delete mode 100644 target/linux/ipq806x/base-files.mk delete mode 100644 target/linux/ipq806x/base-files/etc/inittab delete mode 100755 target/linux/ipq806x/base-files/etc/uci-defaults/network delete mode 100644 target/linux/ipq806x/base-files/lib/ipq806x.sh delete mode 100644 target/linux/ipq806x/base-files/lib/preinit/03_preinit_do_ipq806x.sh delete mode 100644 target/linux/ipq806x/config-3.18 delete mode 100644 target/linux/ipq806x/image/Makefile delete mode 100644 target/linux/ipq806x/modules.mk delete mode 100644 target/linux/ipq806x/patches-3.18/001-spi-qup-Add-DMA-capabilities.patch delete mode 100644 target/linux/ipq806x/patches-3.18/002-v3-spi-qup-Fix-incorrect-block-transfers.patch delete mode 100644 target/linux/ipq806x/patches-3.18/003-spi-qup-Ensure-done-detection.patch delete mode 100644 target/linux/ipq806x/patches-3.18/011-watchdog-qcom-use-timer-devicetree-binding.patch delete mode 100644 target/linux/ipq806x/patches-3.18/012-ARM-qcom-add-description-of-KPSS-WDT-for-IPQ8064.patch delete mode 100644 target/linux/ipq806x/patches-3.18/013-ARM-msm-add-watchdog-entries-to-DT-timer-binding-doc.patch delete mode 100644 target/linux/ipq806x/patches-3.18/020-add-ap148-bootargs.patch delete mode 100644 target/linux/ipq806x/patches-3.18/021-add-ap148-partitions.patch delete mode 100644 target/linux/ipq806x/patches-3.18/022-add-db149-dts.patch delete mode 100644 target/linux/ipq806x/patches-3.18/023-ARM-dts-ipq806x-Disable-i2c-device-on-gsbi4.patch delete mode 100644 target/linux/ipq806x/patches-3.18/100-usb-phy-Add-Qualcomm-DWC3-HS-SS-PHY-drivers.patch delete mode 100644 target/linux/ipq806x/patches-3.18/101-ARM-qcom-add-USB-nodes-to-ipq806x-ap148.patch delete mode 100644 target/linux/ipq806x/patches-3.18/102-soc-qcom-gsbi-Add-support-for-ADM-CRCI-muxing.patch delete mode 100644 target/linux/ipq806x/patches-3.18/103-ARM-DT-ipq8064-Add-TCSR-support.patch delete mode 100644 target/linux/ipq806x/patches-3.18/110-DT-PCI-qcom-Document-PCIe-devicetree-bindings.patch delete mode 100644 target/linux/ipq806x/patches-3.18/111-PCI-qcom-Add-Qualcomm-PCIe-controller-driver.patch delete mode 100644 target/linux/ipq806x/patches-3.18/112-ARM-dts-qcom-add-pcie-nodes-to-ipq806x-platforms.patch delete mode 100644 target/linux/ipq806x/patches-3.18/113-ARM-qcom-automatically-select-PCI_DOMAINS-if-PCI-is-.patch delete mode 100644 target/linux/ipq806x/patches-3.18/120-mfd-qcom-rpm-Driver-for-the-Qualcomm-RPM.patch delete mode 100644 target/linux/ipq806x/patches-3.18/121-mfd-qcom_rpm-Add-support-for-IPQ8064.patch delete mode 100644 target/linux/ipq806x/patches-3.18/122-mfd-devicetree-bindings-Add-Qualcomm-RPM-DT-binding.patch delete mode 100644 target/linux/ipq806x/patches-3.18/123-mfd-devicetree-qcom_rpm-Document-IPQ8064-resources.patch delete mode 100644 target/linux/ipq806x/patches-3.18/124-regulator-rpm-add-support-for-RPM-controller-SMB208.patch delete mode 100644 target/linux/ipq806x/patches-3.18/125-regulator-qcom-rpm-Add-missing-state-flag-in-call-to.patch delete mode 100644 target/linux/ipq806x/patches-3.18/126-add-rpm-to-ipq8064-dts.patch delete mode 100644 target/linux/ipq806x/patches-3.18/130-clk_mux-Fix-set_parent-doing-the-wrong-thing-when-IN.patch delete mode 100644 target/linux/ipq806x/patches-3.18/131-clk-Add-__clk_mux_determine_rate_closest.patch delete mode 100644 target/linux/ipq806x/patches-3.18/132-clk-Add-clk_unregister_-divider-gate-mux-to-close-me.patch delete mode 100644 target/linux/ipq806x/patches-3.18/133-ARM-Add-Krait-L2-register-accessor-functions.patch delete mode 100644 target/linux/ipq806x/patches-3.18/134-clk-mux-Split-out-register-accessors-for-reuse.patch delete mode 100644 target/linux/ipq806x/patches-3.18/135-clk-Avoid-sending-high-rates-to-downstream-clocks-during-set_rate.patch delete mode 100644 target/linux/ipq806x/patches-3.18/136-clk-Add-safe-switch-hook.patch delete mode 100644 target/linux/ipq806x/patches-3.18/137-clk-qcom-Add-support-for-High-Frequency-PLLs-HFPLLs.patch delete mode 100644 target/linux/ipq806x/patches-3.18/138-clk-qcom-Add-HFPLL-driver.patch delete mode 100644 target/linux/ipq806x/patches-3.18/139-clk-qcom-Add-IPQ806X-s-HFPLLs.patch delete mode 100644 target/linux/ipq806x/patches-3.18/140-clk-qcom-Add-support-for-Krait-clocks.patch delete mode 100644 target/linux/ipq806x/patches-3.18/141-clk-qcom-Add-KPSS-ACC-GCC-driver.patch delete mode 100644 target/linux/ipq806x/patches-3.18/142-clk-qcom-Add-Krait-clock-controller-driver.patch delete mode 100644 target/linux/ipq806x/patches-3.18/143-cpufreq-Add-module-to-register-cpufreq-on-Krait-CPUs.patch delete mode 100644 target/linux/ipq806x/patches-3.18/144-ARM-dts-qcom-Add-necessary-DT-data-for-Krait-cpufreq.patch delete mode 100644 target/linux/ipq806x/patches-3.18/145-cpufreq-Add-a-cpufreq-krait-based-on-cpufre.patch delete mode 100644 target/linux/ipq806x/patches-3.18/300-arch-arm-force-ZRELADDR-on-arch-qcom.patch delete mode 100644 target/linux/ipq806x/patches-3.18/700-clk-qcom-Add-support-for-NSS-GMAC-clocks-and-resets.patch delete mode 100644 target/linux/ipq806x/patches-3.18/701-stmmac-add-phy-handle-support-to-the-platform-layer.patch delete mode 100644 target/linux/ipq806x/patches-3.18/702-stmmac-move-error-path-at-the-end-of-stmmac_probe_co.patch delete mode 100644 target/linux/ipq806x/patches-3.18/703-stmmac-add-fixed-link-device-tree-support.patch delete mode 100644 target/linux/ipq806x/patches-3.18/704-stmmac-add-ipq806x-glue-layer.patch delete mode 100644 target/linux/ipq806x/patches-3.18/705-net-stmmac-ipq806x-document-device-tree-bindings.patch delete mode 100644 target/linux/ipq806x/patches-3.18/706-net-stmmac-create-one-debugfs-dir-per-net-device.patch delete mode 100644 target/linux/ipq806x/patches-3.18/707-ARM-dts-qcom-add-mdio-nodes-to-ap148-db149.patch delete mode 100644 target/linux/ipq806x/patches-3.18/708-ARM-dts-qcom-add-gmac-nodes-to-ipq806x-platforms.patch delete mode 100644 target/linux/ipq806x/profiles/default.mk diff --git a/target/linux/ipq806x/Makefile b/target/linux/ipq806x/Makefile deleted file mode 100644 index b6ddfe26b9..0000000000 --- a/target/linux/ipq806x/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -# Copyright (c) 2013 The Linux Foundation. All rights reserved. -# -include $(TOPDIR)/rules.mk - -ARCH:=arm -BOARD:=ipq806x -BOARDNAME:=Qualcomm Atheros IPQ806X -FEATURES:=squashfs -CPU_TYPE:=cortex-a7 -MAINTAINER:=John Crispin - -KERNEL_PATCHVER:=3.18 - -KERNELNAME:=zImage Image dtbs - -include $(INCLUDE_DIR)/target.mk -DEFAULT_PACKAGES += \ - kmod-leds-gpio kmod-gpio-button-hotplug swconfig \ - kmod-ata-core kmod-ata-ahci kmod-ata-ahci-platform - - -$(eval $(call BuildTarget)) diff --git a/target/linux/ipq806x/base-files.mk b/target/linux/ipq806x/base-files.mk deleted file mode 100644 index fdd2c714b2..0000000000 --- a/target/linux/ipq806x/base-files.mk +++ /dev/null @@ -1,3 +0,0 @@ -define Package/base-files/install-target - rm -f $(1)/etc/config/network -endef diff --git a/target/linux/ipq806x/base-files/etc/inittab b/target/linux/ipq806x/base-files/etc/inittab deleted file mode 100644 index 19a6e11950..0000000000 --- a/target/linux/ipq806x/base-files/etc/inittab +++ /dev/null @@ -1,4 +0,0 @@ -# Copyright (c) 2013 The Linux Foundation. All rights reserved. -::sysinit:/etc/init.d/rcS S boot -::shutdown:/etc/init.d/rcS K shutdown -ttyMSM0::askfirst:/bin/ash --login diff --git a/target/linux/ipq806x/base-files/etc/uci-defaults/network b/target/linux/ipq806x/base-files/etc/uci-defaults/network deleted file mode 100755 index 354cea9e3d..0000000000 --- a/target/linux/ipq806x/base-files/etc/uci-defaults/network +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 2015 The Linux Foundation. All rights reserved. -# Copyright (C) 2011 OpenWrt.org -# - -[ -e /etc/config/network ] && exit 0 - -touch /etc/config/network - -. /lib/functions/uci-defaults.sh -. /lib/ipq806x.sh - -ucidef_set_interface_loopback - -board=$(ipq806x_board_name) - -case "$board" in -ap148) - ucidef_set_interfaces_lan_wan "eth1" "eth0" - ucidef_add_switch "switch0" "1" "1" - ucidef_add_switch_vlan "switch0" "1" "6 1 2 3 4" - ucidef_add_switch_vlan "switch0" "2" "0 5" - ;; -db149) - ucidef_set_interfaces_lan_wan "eth1 eth2 eth3" "eth0" - ucidef_add_switch "switch0" "1" "1" - ucidef_add_switch_vlan "switch0" "1" "6 1 2 3 4" - ucidef_add_switch_vlan "switch0" "2" "0 5" - ;; -*) - echo "Unsupported hardware. Network interfaces not intialized" - ;; -esac - -uci commit network - -exit 0 diff --git a/target/linux/ipq806x/base-files/lib/ipq806x.sh b/target/linux/ipq806x/base-files/lib/ipq806x.sh deleted file mode 100644 index 2790f3f386..0000000000 --- a/target/linux/ipq806x/base-files/lib/ipq806x.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 2014 The Linux Foundation. All rights reserved. -# Copyright (C) 2011 OpenWrt.org -# - -IPQ806X_BOARD_NAME= -IPQ806X_MODEL= - -ipq806x_board_detect() { - local machine - local name - - machine=$(cat /proc/device-tree/model) - - case "$machine" in - *"AP148") - name="ap148" - ;; - *"DB149") - name="db149" - ;; - esac - - [ -z "$name" ] && name="unknown" - - [ -z "$IPQ806X_BOARD_NAME" ] && IPQ806X_BOARD_NAME="$name" - [ -z "$IPQ806X_MODEL" ] && IPQ806X_MODEL="$machine" - - [ -e "/tmp/sysinfo/" ] || mkdir -p "/tmp/sysinfo/" - - echo "$IPQ806X_BOARD_NAME" > /tmp/sysinfo/board_name - echo "$IPQ806X_MODEL" > /tmp/sysinfo/model -} - -ipq806x_board_name() { - local name - - [ -f /tmp/sysinfo/board_name ] && name=$(cat /tmp/sysinfo/board_name) - [ -z "$name" ] && name="unknown" - - echo "$name" -} diff --git a/target/linux/ipq806x/base-files/lib/preinit/03_preinit_do_ipq806x.sh b/target/linux/ipq806x/base-files/lib/preinit/03_preinit_do_ipq806x.sh deleted file mode 100644 index 785f1ebb8b..0000000000 --- a/target/linux/ipq806x/base-files/lib/preinit/03_preinit_do_ipq806x.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 2014 The Linux Foundation. All rights reserved. -# - -do_ipq806x() { - . /lib/ipq806x.sh - - ipq806x_board_detect -} - -boot_hook_add preinit_main do_ipq806x diff --git a/target/linux/ipq806x/config-3.18 b/target/linux/ipq806x/config-3.18 deleted file mode 100644 index 4d3b884dca..0000000000 --- a/target/linux/ipq806x/config-3.18 +++ /dev/null @@ -1,420 +0,0 @@ -CONFIG_ALIGNMENT_TRAP=y -# CONFIG_AMBA_PL08X is not set -# CONFIG_APM_EMULATION is not set -CONFIG_APQ_GCC_8084=y -CONFIG_APQ_MMCC_8084=y -CONFIG_AR8216_PHY=y -CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y -CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y -CONFIG_ARCH_HAS_SG_CHAIN=y -CONFIG_ARCH_HAS_TICK_BROADCAST=y -CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y -CONFIG_ARCH_HIBERNATION_POSSIBLE=y -CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y -CONFIG_ARCH_MSM8960=y -CONFIG_ARCH_MSM8974=y -CONFIG_ARCH_MSM8X60=y -CONFIG_ARCH_MULTIPLATFORM=y -# CONFIG_ARCH_MULTI_CPU_AUTO is not set -CONFIG_ARCH_MULTI_V6_V7=y -CONFIG_ARCH_MULTI_V7=y -CONFIG_ARCH_NR_GPIO=0 -CONFIG_ARCH_QCOM=y -CONFIG_ARCH_REQUIRE_GPIOLIB=y -# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set -# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set -CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y -CONFIG_ARCH_SUPPORTS_UPROBES=y -CONFIG_ARCH_SUSPEND_POSSIBLE=y -CONFIG_ARCH_USE_BUILTIN_BSWAP=y -CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y -CONFIG_ARCH_WANT_GENERAL_HUGETLB=y -CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y -CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y -CONFIG_ARM=y -CONFIG_ARM_AMBA=y -CONFIG_ARM_APPENDED_DTB=y -CONFIG_ARM_ARCH_TIMER=y -CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y -# CONFIG_ARM_ATAG_DTB_COMPAT is not set -CONFIG_ARM_CPU_SUSPEND=y -CONFIG_ARM_GIC=y -CONFIG_ARM_HAS_SG_CHAIN=y -# CONFIG_ARM_KIRKWOOD_CPUFREQ is not set -CONFIG_ARM_L1_CACHE_SHIFT=6 -CONFIG_ARM_L1_CACHE_SHIFT_6=y -# CONFIG_ARM_LPAE is not set -CONFIG_ARM_PATCH_PHYS_VIRT=y -CONFIG_ARM_QCOM_CPUFREQ=y -# CONFIG_ARM_SP805_WATCHDOG is not set -CONFIG_ARM_THUMB=y -# CONFIG_ARM_THUMBEE is not set -CONFIG_ARM_UNWIND=y -CONFIG_ARM_VIRT_EXT=y -CONFIG_AT803X_PHY=y -# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set -CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 -CONFIG_BOUNCE=y -CONFIG_BUILD_BIN2C=y -# CONFIG_CACHE_L2X0 is not set -CONFIG_CLEANCACHE=y -CONFIG_CLKDEV_LOOKUP=y -CONFIG_CLKSRC_OF=y -CONFIG_CLKSRC_QCOM=y -CONFIG_CLONE_BACKWARDS=y -CONFIG_COMMON_CLK=y -CONFIG_COMMON_CLK_QCOM=y -CONFIG_COMPACTION=y -CONFIG_COREDUMP=y -# CONFIG_CPUFREQ_DT is not set -CONFIG_CPU_32v6K=y -CONFIG_CPU_32v7=y -CONFIG_CPU_ABRT_EV7=y -# CONFIG_CPU_BPREDICT_DISABLE is not set -CONFIG_CPU_CACHE_V7=y -CONFIG_CPU_CACHE_VIPT=y -CONFIG_CPU_COPY_V6=y -CONFIG_CPU_CP15=y -CONFIG_CPU_CP15_MMU=y -CONFIG_CPU_FREQ=y -# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set -# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set -CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y -# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set -# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set -# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set -# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set -CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set -# CONFIG_CPU_FREQ_GOV_USERSPACE is not set -CONFIG_CPU_FREQ_STAT=y -# CONFIG_CPU_FREQ_STAT_DETAILS is not set -CONFIG_CPU_HAS_ASID=y -# CONFIG_CPU_ICACHE_DISABLE is not set -CONFIG_CPU_IDLE=y -CONFIG_CPU_IDLE_GOV_LADDER=y -CONFIG_CPU_IDLE_GOV_MENU=y -CONFIG_CPU_PABRT_V7=y -CONFIG_CPU_PM=y -CONFIG_CPU_RMAP=y -# CONFIG_CPU_THERMAL is not set -CONFIG_CPU_TLB_V7=y -CONFIG_CPU_V7=y -CONFIG_CRC16=y -# CONFIG_CRC32_SARWATE is not set -CONFIG_CRC32_SLICEBY8=y -CONFIG_CROSS_MEMORY_ATTACH=y -# CONFIG_CRYPTO_SHA1_ARM_NEON is not set -# CONFIG_CRYPTO_SHA512_ARM_NEON is not set -CONFIG_CRYPTO_XZ=y -CONFIG_DCACHE_WORD_ACCESS=y -CONFIG_DEBUG_BUGVERBOSE=y -CONFIG_DEBUG_GPIO=y -CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S" -CONFIG_DEBUG_PREEMPT=y -# CONFIG_DEBUG_UART_8250 is not set -# CONFIG_DEBUG_UART_PL01X is not set -# CONFIG_DEBUG_USER is not set -CONFIG_DECOMPRESS_GZIP=y -CONFIG_DMADEVICES=y -CONFIG_DMA_ENGINE=y -CONFIG_DMA_OF=y -CONFIG_DMA_VIRTUAL_CHANNELS=y -CONFIG_DTC=y -CONFIG_DWMAC_IPQ806X=y -# CONFIG_DW_DMAC_CORE is not set -# CONFIG_DW_DMAC_PCI is not set -CONFIG_DYNAMIC_DEBUG=y -CONFIG_ETHERNET_PACKET_MANGLE=y -CONFIG_FIXED_PHY=y -CONFIG_FREEZER=y -CONFIG_GENERIC_ALLOCATOR=y -CONFIG_GENERIC_BUG=y -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y -CONFIG_GENERIC_CLOCKEVENTS_BUILD=y -CONFIG_GENERIC_CPUFREQ_KRAIT=y -CONFIG_GENERIC_IDLE_POLL_SETUP=y -CONFIG_GENERIC_IO=y -CONFIG_GENERIC_IRQ_SHOW=y -CONFIG_GENERIC_PCI_IOMAP=y -CONFIG_GENERIC_PHY=y -CONFIG_GENERIC_PINCONF=y -CONFIG_GENERIC_SCHED_CLOCK=y -CONFIG_GENERIC_SMP_IDLE_THREAD=y -CONFIG_GENERIC_STRNCPY_FROM_USER=y -CONFIG_GENERIC_STRNLEN_USER=y -CONFIG_GPIOLIB=y -CONFIG_GPIOLIB_IRQCHIP=y -CONFIG_GPIO_DEVRES=y -# CONFIG_GPIO_MSM_V2 is not set -CONFIG_GPIO_SYSFS=y -CONFIG_HANDLE_DOMAIN_IRQ=y -CONFIG_HARDIRQS_SW_RESEND=y -CONFIG_HAS_DMA=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT_MAP=y -# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set -CONFIG_HAVE_ARCH_AUDITSYSCALL=y -CONFIG_HAVE_ARCH_JUMP_LABEL=y -CONFIG_HAVE_ARCH_KGDB=y -CONFIG_HAVE_ARCH_PFN_VALID=y -CONFIG_HAVE_ARCH_SECCOMP_FILTER=y -CONFIG_HAVE_ARCH_TRACEHOOK=y -CONFIG_HAVE_ARM_ARCH_TIMER=y -# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set -CONFIG_HAVE_BPF_JIT=y -CONFIG_HAVE_CC_STACKPROTECTOR=y -CONFIG_HAVE_CLK=y -CONFIG_HAVE_CLK_PREPARE=y -CONFIG_HAVE_CONTEXT_TRACKING=y -CONFIG_HAVE_C_RECORDMCOUNT=y -CONFIG_HAVE_DEBUG_KMEMLEAK=y -CONFIG_HAVE_DMA_API_DEBUG=y -CONFIG_HAVE_DMA_ATTRS=y -CONFIG_HAVE_DMA_CONTIGUOUS=y -CONFIG_HAVE_DYNAMIC_FTRACE=y -CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y -CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y -CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y -CONFIG_HAVE_FUNCTION_TRACER=y -CONFIG_HAVE_GENERIC_DMA_COHERENT=y -CONFIG_HAVE_HW_BREAKPOINT=y -CONFIG_HAVE_IDE=y -CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y -CONFIG_HAVE_KERNEL_GZIP=y -CONFIG_HAVE_KERNEL_LZ4=y -CONFIG_HAVE_KERNEL_LZMA=y -CONFIG_HAVE_KERNEL_LZO=y -CONFIG_HAVE_KERNEL_XZ=y -CONFIG_HAVE_MEMBLOCK=y -CONFIG_HAVE_MOD_ARCH_SPECIFIC=y -CONFIG_HAVE_NET_DSA=y -CONFIG_HAVE_OPROFILE=y -CONFIG_HAVE_PERF_EVENTS=y -CONFIG_HAVE_PERF_REGS=y -CONFIG_HAVE_PERF_USER_STACK_DUMP=y -CONFIG_HAVE_PROC_CPU=y -CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y -CONFIG_HAVE_SMP=y -CONFIG_HAVE_SYSCALL_TRACEPOINTS=y -CONFIG_HAVE_UID16=y -CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y -CONFIG_HIGHMEM=y -CONFIG_HIGHPTE=y -CONFIG_HOTPLUG_CPU=y -CONFIG_HWMON=y -CONFIG_HW_RANDOM=y -CONFIG_HW_RANDOM_MSM=y -CONFIG_HZ_FIXED=0 -CONFIG_I2C=y -CONFIG_I2C_BOARDINFO=y -CONFIG_I2C_CHARDEV=y -CONFIG_I2C_COMPAT=y -CONFIG_I2C_HELPER_AUTO=y -CONFIG_I2C_QUP=y -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_INITRAMFS_SOURCE="" -CONFIG_IOMMU_API=y -CONFIG_IOMMU_HELPER=y -CONFIG_IOMMU_PGTABLES_L2=y -CONFIG_IOMMU_SUPPORT=y -CONFIG_IPQ_GCC_806X=y -CONFIG_IRQCHIP=y -CONFIG_IRQ_DOMAIN=y -CONFIG_IRQ_FORCED_THREADING=y -CONFIG_IRQ_WORK=y -CONFIG_KPSS_XCC=y -CONFIG_KRAITCC=y -CONFIG_KRAIT_CLOCKS=y -CONFIG_KRAIT_L2_ACCESSORS=y -# CONFIG_LEDS_REGULATOR is not set -CONFIG_LIBFDT=y -CONFIG_LOCKUP_DETECTOR=y -CONFIG_LZO_COMPRESS=y -CONFIG_LZO_DECOMPRESS=y -CONFIG_MDIO_BITBANG=y -CONFIG_MDIO_BOARDINFO=y -CONFIG_MDIO_GPIO=y -CONFIG_MFD_QCOM_RPM=y -# CONFIG_MFD_SPMI_PMIC is not set -CONFIG_MFD_SYSCON=y -CONFIG_MIGHT_HAVE_CACHE_L2X0=y -CONFIG_MIGHT_HAVE_PCI=y -CONFIG_MIGRATION=y -CONFIG_MODULES_USE_ELF_REL=y -CONFIG_MSM_GCC_8660=y -CONFIG_MSM_GCC_8960=y -CONFIG_MSM_GCC_8974=y -CONFIG_MSM_IOMMU=y -CONFIG_MSM_MMCC_8960=y -CONFIG_MSM_MMCC_8974=y -CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_M25P80=y -CONFIG_MTD_SPI_NOR=y -CONFIG_MTD_SPLIT_FIRMWARE=y -CONFIG_MTD_SPLIT_FIT_FW=y -CONFIG_MULTI_IRQ_HANDLER=y -CONFIG_MUTEX_SPIN_ON_OWNER=y -CONFIG_NEED_DMA_MAP_STATE=y -CONFIG_NEON=y -CONFIG_NET_FLOW_LIMIT=y -CONFIG_NET_PTP_CLASSIFY=y -CONFIG_NET_VENDOR_WIZNET=y -CONFIG_NO_BOOTMEM=y -CONFIG_NO_HZ=y -CONFIG_NO_HZ_COMMON=y -CONFIG_NO_HZ_IDLE=y -CONFIG_NR_CPUS=4 -CONFIG_OF=y -CONFIG_OF_ADDRESS=y -CONFIG_OF_ADDRESS_PCI=y -CONFIG_OF_EARLY_FLATTREE=y -CONFIG_OF_FLATTREE=y -CONFIG_OF_GPIO=y -CONFIG_OF_IOMMU=y -CONFIG_OF_IRQ=y -CONFIG_OF_MDIO=y -CONFIG_OF_MTD=y -CONFIG_OF_NET=y -CONFIG_OF_PCI=y -CONFIG_OF_PCI_IRQ=y -CONFIG_OF_RESERVED_MEM=y -CONFIG_OLD_SIGACTION=y -CONFIG_OLD_SIGSUSPEND3=y -CONFIG_PAGEFLAGS_EXTENDED=y -CONFIG_PAGE_OFFSET=0xC0000000 -CONFIG_PCI=y -CONFIG_PCIEAER=y -CONFIG_PCIEPORTBUS=y -CONFIG_PCIE_DW=y -CONFIG_PCIE_QCOM=y -CONFIG_PCI_DOMAINS=y -CONFIG_PCI_MSI=y -CONFIG_PERF_EVENTS=y -CONFIG_PERF_USE_VMALLOC=y -CONFIG_PHYLIB=y -# CONFIG_PHY_QCOM_APQ8064_SATA is not set -CONFIG_PHY_QCOM_IPQ806X_SATA=y -CONFIG_PINCTRL=y -CONFIG_PINCTRL_APQ8064=y -# CONFIG_PINCTRL_APQ8084 is not set -CONFIG_PINCTRL_IPQ8064=y -CONFIG_PINCTRL_MSM=y -# CONFIG_PINCTRL_MSM8960 is not set -CONFIG_PINCTRL_MSM8X74=y -# CONFIG_PL330_DMA is not set -CONFIG_PM=y -CONFIG_PM_CLK=y -# CONFIG_PM_DEBUG is not set -CONFIG_PM_OPP=y -CONFIG_PM_SLEEP=y -CONFIG_PM_SLEEP_SMP=y -CONFIG_POWER_RESET=y -# CONFIG_POWER_RESET_BRCMSTB is not set -# CONFIG_POWER_RESET_GPIO is not set -# CONFIG_POWER_RESET_GPIO_RESTART is not set -# CONFIG_POWER_RESET_LTC2952 is not set -CONFIG_POWER_RESET_MSM=y -# CONFIG_POWER_RESET_SYSCON is not set -CONFIG_POWER_SUPPLY=y -CONFIG_PPS=y -CONFIG_PREEMPT=y -CONFIG_PREEMPT_COUNT=y -# CONFIG_PREEMPT_NONE is not set -CONFIG_PREEMPT_RCU=y -CONFIG_PRINTK_TIME=y -CONFIG_PROC_PAGE_MONITOR=y -CONFIG_PTP_1588_CLOCK=y -CONFIG_QCOM_BAM_DMA=y -CONFIG_QCOM_GSBI=y -CONFIG_QCOM_HFPLL=y -CONFIG_QCOM_SCM=y -CONFIG_QCOM_WDT=y -CONFIG_RAS=y -# CONFIG_RCU_BOOST is not set -CONFIG_RCU_CPU_STALL_TIMEOUT=21 -CONFIG_RCU_CPU_STALL_VERBOSE=y -CONFIG_RCU_STALL_COMMON=y -CONFIG_RD_GZIP=y -CONFIG_REGMAP=y -CONFIG_REGMAP_MMIO=y -CONFIG_REGULATOR=y -# CONFIG_REGULATOR_DEBUG is not set -CONFIG_REGULATOR_QCOM_RPM=y -# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set -CONFIG_RESET_CONTROLLER=y -CONFIG_RFS_ACCEL=y -CONFIG_RPS=y -CONFIG_RTC_CLASS=y -# CONFIG_RTC_DRV_CMOS is not set -CONFIG_RWSEM_SPIN_ON_OWNER=y -CONFIG_RWSEM_XCHGADD_ALGORITHM=y -CONFIG_SCHED_HRTICK=y -# CONFIG_SCSI_DMA is not set -# CONFIG_SERIAL_AMBA_PL010 is not set -# CONFIG_SERIAL_AMBA_PL011 is not set -CONFIG_SERIAL_MSM=y -CONFIG_SERIAL_MSM_CONSOLE=y -# CONFIG_SLAB is not set -CONFIG_SLUB=y -CONFIG_SLUB_CPU_PARTIAL=y -CONFIG_SMP=y -CONFIG_SMP_ON_UP=y -CONFIG_SPARSE_IRQ=y -CONFIG_SPI=y -CONFIG_SPI_MASTER=y -CONFIG_SPI_QUP=y -CONFIG_SPMI=y -CONFIG_SPMI_MSM_PMIC_ARB=y -# CONFIG_STMMAC_DA is not set -CONFIG_STMMAC_DEBUG_FS=y -CONFIG_STMMAC_ETH=y -CONFIG_STMMAC_PLATFORM=y -CONFIG_STOP_MACHINE=y -# CONFIG_STRIP_ASM_SYMS is not set -CONFIG_SUSPEND=y -CONFIG_SUSPEND_FREEZER=y -CONFIG_SWCONFIG=y -CONFIG_SWIOTLB=y -CONFIG_SWP_EMULATE=y -CONFIG_SYS_SUPPORTS_APM_EMULATION=y -CONFIG_THERMAL=y -# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set -CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y -# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set -# CONFIG_THERMAL_EMULATION is not set -# CONFIG_THERMAL_GOV_FAIR_SHARE is not set -CONFIG_THERMAL_GOV_STEP_WISE=y -# CONFIG_THERMAL_GOV_USER_SPACE is not set -CONFIG_THERMAL_HWMON=y -CONFIG_THERMAL_OF=y -# CONFIG_THUMB2_KERNEL is not set -CONFIG_TICK_CPU_ACCOUNTING=y -CONFIG_TIMER_STATS=y -CONFIG_TREE_PREEMPT_RCU=y -CONFIG_UEVENT_HELPER_PATH="" -CONFIG_UID16=y -CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" -CONFIG_UNINLINE_SPIN_UNLOCK=y -CONFIG_USB_SUPPORT=y -CONFIG_USE_OF=y -CONFIG_VECTORS_BASE=0xffff0000 -# CONFIG_VFIO is not set -CONFIG_VFP=y -CONFIG_VFPv3=y -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_WATCHDOG_CORE=y -# CONFIG_WIZNET_W5100 is not set -# CONFIG_WIZNET_W5300 is not set -# CONFIG_WL_TI is not set -# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set -# CONFIG_XEN is not set -CONFIG_XPS=y -CONFIG_XZ_DEC_ARM=y -CONFIG_XZ_DEC_BCJ=y -CONFIG_ZBOOT_ROM_BSS=0 -CONFIG_ZBOOT_ROM_TEXT=0 -CONFIG_ZLIB_INFLATE=y -CONFIG_ZONE_DMA_FLAG=0 diff --git a/target/linux/ipq806x/image/Makefile b/target/linux/ipq806x/image/Makefile deleted file mode 100644 index db5bf0acbc..0000000000 --- a/target/linux/ipq806x/image/Makefile +++ /dev/null @@ -1,41 +0,0 @@ -# Copyright (c) 2014 The Linux Foundation. All rights reserved. -# -include $(TOPDIR)/rules.mk -include $(INCLUDE_DIR)/image.mk - -UBIFS_OPTS = -m 2048 -e 124KiB -c 4096 -U -F -UBINIZE_OPTS = -m 2048 -p 128KiB - -E2SIZE=$(shell echo $$(($(CONFIG_TARGET_ROOTFS_PARTSIZE)*1024))) - -define Image/BuildKernel/FIT - gzip -9 -c $(KDIR)/Image > $(KDIR)/Image.gz - $(call CompressLzma,$(KDIR)/Image,$(KDIR)/Image.gz) - $(call Image/BuildKernel/MkFIT,$(1), $(KDIR)/Image.gz, $(LINUX_DIR)/arch/arm/boot/dts/$(1).dtb,gzip,0x42208000,0x42208000) - $(CP) $(KDIR)/fit-$(1).itb $(BIN_DIR)/$(IMG_PREFIX)-$(1)-fit-uImage.itb -ifneq ($(CONFIG_TARGET_ROOTFS_INITRAMFS),) - $(call Image/BuildKernel/MkFIT,$(1), $(KDIR)/Image-initramfs, $(LINUX_DIR)/arch/arm/boot/dts/$(1).dtb, none,0x42208000,0x42208000) - $(CP) $(KDIR)/fit-$(1).itb $(BIN_DIR)/$(IMG_PREFIX)-$(1)-fit-uImage-initramfs.itb -endif -endef - -define Image/Prepare - $(CP) $(LINUX_DIR)/vmlinux $(KDIR)/$(IMG_PREFIX)-vmlinux.elf -endef - -define Image/BuildKernel - $(CP) $(KDIR)/$(IMG_PREFIX)-vmlinux.elf $(BIN_DIR) - $(call Image/BuildKernel/FIT,qcom-ipq8064-ap148) - $(call Image/BuildKernel/FIT,qcom-ipq8064-db149) -endef - -define Image/Build/squashfs - $(call prepare_generic_squashfs,$(KDIR)/root.squashfs) -endef - -define Image/Build - $(call Image/Build/$(1),$(1)) - dd if=$(KDIR)/root.$(1) of=$(BIN_DIR)/$(IMG_PREFIX)-$(1)-root.img bs=2k conv=sync -endef - -$(eval $(call BuildImage)) diff --git a/target/linux/ipq806x/modules.mk b/target/linux/ipq806x/modules.mk deleted file mode 100644 index 57121bebb0..0000000000 --- a/target/linux/ipq806x/modules.mk +++ /dev/null @@ -1,32 +0,0 @@ -define KernelPackage/usb-phy-qcom-dwc3 - TITLE:=DWC3 USB QCOM PHY driver - DEPENDS:=@TARGET_ipq806x - KCONFIG:= CONFIG_PHY_QCOM_DWC3 - FILES:= $(LINUX_DIR)/drivers/phy/phy-qcom-dwc3.ko - AUTOLOAD:=$(call AutoLoad,45,phy-qcom-dwc3,1) - $(call AddDepends/usb) -endef - -define KernelPackage/usb-phy-qcom-dwc3/description - This driver provides support for the integrated DesignWare - USB3 IP Core within the QCOM SoCs. -endef - -$(eval $(call KernelPackage,usb-phy-qcom-dwc3)) - - -define KernelPackage/usb-dwc3-qcom - TITLE:=DWC3 USB QCOM controller driver - DEPENDS:=@TARGET_ipq806x +kmod-usb-dwc3 +kmod-usb-phy-dwc3-qcom - KCONFIG:= CONFIG_USB_DWC3_QCOM - FILES:= $(LINUX_DIR)/drivers/usb/dwc3/dwc3-qcom.ko - AUTOLOAD:=$(call AutoLoad,53,dwc3-qcom,1) - $(call AddDepends/usb) -endef - -define KernelPackage/usb-dwc3-qcom/description - This driver provides support for the integrated DesignWare - USB3 IP Core within the QCOM SoCs. -endef - -$(eval $(call KernelPackage,usb-dwc3-qcom)) diff --git a/target/linux/ipq806x/patches-3.18/001-spi-qup-Add-DMA-capabilities.patch b/target/linux/ipq806x/patches-3.18/001-spi-qup-Add-DMA-capabilities.patch deleted file mode 100644 index e110bf726c..0000000000 --- a/target/linux/ipq806x/patches-3.18/001-spi-qup-Add-DMA-capabilities.patch +++ /dev/null @@ -1,522 +0,0 @@ -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: spi: qup: Add DMA capabilities -From: Andy Gross -X-Patchwork-Id: 4432401 -Message-Id: <1403816781-31008-1-git-send-email-agross@codeaurora.org> -To: Mark Brown -Cc: linux-spi@vger.kernel.org, Sagar Dharia , - Daniel Sneddon , - Bjorn Andersson , - "Ivan T. Ivanov" , - linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, - linux-arm-msm@vger.kernel.org, Andy Gross -Date: Thu, 26 Jun 2014 16:06:21 -0500 - -This patch adds DMA capabilities to the spi-qup driver. If DMA channels are -present, the QUP will use DMA instead of block mode for transfers to/from SPI -peripherals for transactions larger than the length of a block. - -Signed-off-by: Andy Gross - ---- -.../devicetree/bindings/spi/qcom,spi-qup.txt | 10 + - drivers/spi/spi-qup.c | 361 ++++++++++++++++++-- - 2 files changed, 350 insertions(+), 21 deletions(-) - ---- a/Documentation/devicetree/bindings/spi/qcom,spi-qup.txt -+++ b/Documentation/devicetree/bindings/spi/qcom,spi-qup.txt -@@ -27,6 +27,11 @@ Optional properties: - - spi-max-frequency: Specifies maximum SPI clock frequency, - Units - Hz. Definition as per - Documentation/devicetree/bindings/spi/spi-bus.txt -+- dmas : Two DMA channel specifiers following the convention outlined -+ in bindings/dma/dma.txt -+- dma-names: Names for the dma channels, if present. There must be at -+ least one channel named "tx" for transmit and named "rx" for -+ receive. - - num-cs: total number of chipselects - - cs-gpios: should specify GPIOs used for chipselects. - The gpios will be referred to as reg = in the SPI child -@@ -51,6 +56,10 @@ Example: - clocks = <&gcc GCC_BLSP2_QUP2_SPI_APPS_CLK>, <&gcc GCC_BLSP2_AHB_CLK>; - clock-names = "core", "iface"; - -+ dmas = <&blsp2_bam 2>, -+ <&blsp2_bam 3>; -+ dma-names = "rx", "tx"; -+ - pinctrl-names = "default"; - pinctrl-0 = <&spi8_default>; - ---- a/drivers/spi/spi-qup.c -+++ b/drivers/spi/spi-qup.c -@@ -22,6 +22,8 @@ - #include - #include - #include -+#include -+#include - - #define QUP_CONFIG 0x0000 - #define QUP_STATE 0x0004 -@@ -116,6 +118,8 @@ - - #define SPI_NUM_CHIPSELECTS 4 - -+#define SPI_MAX_XFER (SZ_64K - 64) -+ - /* high speed mode is when bus rate is greater then 26MHz */ - #define SPI_HS_MIN_RATE 26000000 - #define SPI_MAX_RATE 50000000 -@@ -143,6 +147,17 @@ struct spi_qup { - int tx_bytes; - int rx_bytes; - int qup_v1; -+ -+ int use_dma; -+ -+ struct dma_chan *rx_chan; -+ struct dma_slave_config rx_conf; -+ struct dma_chan *tx_chan; -+ struct dma_slave_config tx_conf; -+ dma_addr_t rx_dma; -+ dma_addr_t tx_dma; -+ void *dummy; -+ atomic_t dma_outstanding; - }; - - -@@ -266,6 +281,221 @@ static void spi_qup_fifo_write(struct sp - } - } - -+static void qup_dma_callback(void *data) -+{ -+ struct spi_qup *controller = data; -+ -+ if (atomic_dec_and_test(&controller->dma_outstanding)) -+ complete(&controller->done); -+} -+ -+static int spi_qup_do_dma(struct spi_qup *controller, struct spi_transfer *xfer) -+{ -+ struct dma_async_tx_descriptor *rxd, *txd; -+ dma_cookie_t rx_cookie, tx_cookie; -+ u32 xfer_len, rx_align = 0, tx_align = 0, n_words; -+ struct scatterlist tx_sg[2], rx_sg[2]; -+ int ret = 0; -+ u32 bytes_to_xfer = xfer->len; -+ u32 offset = 0; -+ u32 rx_nents = 0, tx_nents = 0; -+ dma_addr_t rx_dma = 0, tx_dma = 0, rx_dummy_dma = 0, tx_dummy_dma = 0; -+ -+ -+ if (xfer->rx_buf) { -+ rx_dma = dma_map_single(controller->dev, xfer->rx_buf, -+ xfer->len, DMA_FROM_DEVICE); -+ -+ if (dma_mapping_error(controller->dev, rx_dma)) { -+ ret = -ENOMEM; -+ return ret; -+ } -+ -+ /* check to see if we need dummy buffer for leftover bytes */ -+ rx_align = xfer->len % controller->in_blk_sz; -+ if (rx_align) { -+ rx_dummy_dma = dma_map_single(controller->dev, -+ controller->dummy, controller->in_fifo_sz, -+ DMA_FROM_DEVICE); -+ -+ if (dma_mapping_error(controller->dev, rx_dummy_dma)) { -+ ret = -ENOMEM; -+ goto err_map_rx_dummy; -+ } -+ } -+ } -+ -+ if (xfer->tx_buf) { -+ tx_dma = dma_map_single(controller->dev, -+ (void *)xfer->tx_buf, xfer->len, DMA_TO_DEVICE); -+ -+ if (dma_mapping_error(controller->dev, tx_dma)) { -+ ret = -ENOMEM; -+ goto err_map_tx; -+ } -+ -+ /* check to see if we need dummy buffer for leftover bytes */ -+ tx_align = xfer->len % controller->out_blk_sz; -+ if (tx_align) { -+ memcpy(controller->dummy + SZ_1K, -+ xfer->tx_buf + xfer->len - tx_align, -+ tx_align); -+ memset(controller->dummy + SZ_1K + tx_align, 0, -+ controller->out_blk_sz - tx_align); -+ -+ tx_dummy_dma = dma_map_single(controller->dev, -+ controller->dummy + SZ_1K, -+ controller->out_blk_sz, DMA_TO_DEVICE); -+ -+ if (dma_mapping_error(controller->dev, tx_dummy_dma)) { -+ ret = -ENOMEM; -+ goto err_map_tx_dummy; -+ } -+ } -+ } -+ -+ atomic_set(&controller->dma_outstanding, 0); -+ -+ while (bytes_to_xfer > 0) { -+ xfer_len = min_t(u32, bytes_to_xfer, SPI_MAX_XFER); -+ n_words = DIV_ROUND_UP(xfer_len, controller->w_size); -+ -+ /* write out current word count to controller */ -+ writel_relaxed(n_words, controller->base + QUP_MX_INPUT_CNT); -+ writel_relaxed(n_words, controller->base + QUP_MX_OUTPUT_CNT); -+ -+ reinit_completion(&controller->done); -+ -+ if (xfer->tx_buf) { -+ /* recalc align for each transaction */ -+ tx_align = xfer_len % controller->out_blk_sz; -+ -+ if (tx_align) -+ tx_nents = 2; -+ else -+ tx_nents = 1; -+ -+ /* initialize scatterlists */ -+ sg_init_table(tx_sg, tx_nents); -+ sg_dma_len(&tx_sg[0]) = xfer_len - tx_align; -+ sg_dma_address(&tx_sg[0]) = tx_dma + offset; -+ -+ /* account for non block size transfer */ -+ if (tx_align) { -+ sg_dma_len(&tx_sg[1]) = controller->out_blk_sz; -+ sg_dma_address(&tx_sg[1]) = tx_dummy_dma; -+ } -+ -+ txd = dmaengine_prep_slave_sg(controller->tx_chan, -+ tx_sg, tx_nents, DMA_MEM_TO_DEV, 0); -+ if (!txd) { -+ ret = -ENOMEM; -+ goto err_unmap; -+ } -+ -+ atomic_inc(&controller->dma_outstanding); -+ -+ txd->callback = qup_dma_callback; -+ txd->callback_param = controller; -+ -+ tx_cookie = dmaengine_submit(txd); -+ -+ dma_async_issue_pending(controller->tx_chan); -+ } -+ -+ if (xfer->rx_buf) { -+ /* recalc align for each transaction */ -+ rx_align = xfer_len % controller->in_blk_sz; -+ -+ if (rx_align) -+ rx_nents = 2; -+ else -+ rx_nents = 1; -+ -+ /* initialize scatterlists */ -+ sg_init_table(rx_sg, rx_nents); -+ sg_dma_address(&rx_sg[0]) = rx_dma + offset; -+ sg_dma_len(&rx_sg[0]) = xfer_len - rx_align; -+ -+ /* account for non block size transfer */ -+ if (rx_align) { -+ sg_dma_len(&rx_sg[1]) = controller->in_blk_sz; -+ sg_dma_address(&rx_sg[1]) = rx_dummy_dma; -+ } -+ -+ rxd = dmaengine_prep_slave_sg(controller->rx_chan, -+ rx_sg, rx_nents, DMA_DEV_TO_MEM, 0); -+ if (!rxd) { -+ ret = -ENOMEM; -+ goto err_unmap; -+ } -+ -+ atomic_inc(&controller->dma_outstanding); -+ -+ rxd->callback = qup_dma_callback; -+ rxd->callback_param = controller; -+ -+ rx_cookie = dmaengine_submit(rxd); -+ -+ dma_async_issue_pending(controller->rx_chan); -+ } -+ -+ if (spi_qup_set_state(controller, QUP_STATE_RUN)) { -+ dev_warn(controller->dev, "cannot set EXECUTE state\n"); -+ goto err_unmap; -+ } -+ -+ if (!wait_for_completion_timeout(&controller->done, -+ msecs_to_jiffies(1000))) { -+ ret = -ETIMEDOUT; -+ -+ /* clear out all the DMA transactions */ -+ if (xfer->tx_buf) -+ dmaengine_terminate_all(controller->tx_chan); -+ if (xfer->rx_buf) -+ dmaengine_terminate_all(controller->rx_chan); -+ -+ goto err_unmap; -+ } -+ -+ if (rx_align) -+ memcpy(xfer->rx_buf + offset + xfer->len - rx_align, -+ controller->dummy, rx_align); -+ -+ /* adjust remaining bytes to transfer */ -+ bytes_to_xfer -= xfer_len; -+ offset += xfer_len; -+ -+ -+ /* reset mini-core state so we can program next transaction */ -+ if (spi_qup_set_state(controller, QUP_STATE_RESET)) { -+ dev_err(controller->dev, "cannot set RESET state\n"); -+ goto err_unmap; -+ } -+ } -+ -+ ret = 0; -+ -+err_unmap: -+ if (tx_align) -+ dma_unmap_single(controller->dev, tx_dummy_dma, -+ controller->out_fifo_sz, DMA_TO_DEVICE); -+err_map_tx_dummy: -+ if (xfer->tx_buf) -+ dma_unmap_single(controller->dev, tx_dma, xfer->len, -+ DMA_TO_DEVICE); -+err_map_tx: -+ if (rx_align) -+ dma_unmap_single(controller->dev, rx_dummy_dma, -+ controller->in_fifo_sz, DMA_FROM_DEVICE); -+err_map_rx_dummy: -+ if (xfer->rx_buf) -+ dma_unmap_single(controller->dev, rx_dma, xfer->len, -+ DMA_FROM_DEVICE); -+ -+ return ret; -+} -+ - static irqreturn_t spi_qup_qup_irq(int irq, void *dev_id) - { - struct spi_qup *controller = dev_id; -@@ -315,11 +545,13 @@ static irqreturn_t spi_qup_qup_irq(int i - error = -EIO; - } - -- if (opflags & QUP_OP_IN_SERVICE_FLAG) -- spi_qup_fifo_read(controller, xfer); -+ if (!controller->use_dma) { -+ if (opflags & QUP_OP_IN_SERVICE_FLAG) -+ spi_qup_fifo_read(controller, xfer); - -- if (opflags & QUP_OP_OUT_SERVICE_FLAG) -- spi_qup_fifo_write(controller, xfer); -+ if (opflags & QUP_OP_OUT_SERVICE_FLAG) -+ spi_qup_fifo_write(controller, xfer); -+ } - - spin_lock_irqsave(&controller->lock, flags); - controller->error = error; -@@ -339,6 +571,8 @@ static int spi_qup_io_config(struct spi_ - struct spi_qup *controller = spi_master_get_devdata(spi->master); - u32 config, iomode, mode; - int ret, n_words, w_size; -+ size_t dma_align = dma_get_cache_alignment(); -+ u32 dma_available = 0; - - if (spi->mode & SPI_LOOP && xfer->len > controller->in_fifo_sz) { - dev_err(controller->dev, "too big size for loopback %d > %d\n", -@@ -367,6 +601,11 @@ static int spi_qup_io_config(struct spi_ - n_words = xfer->len / w_size; - controller->w_size = w_size; - -+ if (controller->rx_chan && -+ IS_ALIGNED((size_t)xfer->tx_buf, dma_align) && -+ IS_ALIGNED((size_t)xfer->rx_buf, dma_align)) -+ dma_available = 1; -+ - if (n_words <= (controller->in_fifo_sz / sizeof(u32))) { - mode = QUP_IO_M_MODE_FIFO; - writel_relaxed(n_words, controller->base + QUP_MX_READ_CNT); -@@ -374,19 +613,31 @@ static int spi_qup_io_config(struct spi_ - /* must be zero for FIFO */ - writel_relaxed(0, controller->base + QUP_MX_INPUT_CNT); - writel_relaxed(0, controller->base + QUP_MX_OUTPUT_CNT); -- } else { -+ controller->use_dma = 0; -+ } else if (!dma_available) { - mode = QUP_IO_M_MODE_BLOCK; - writel_relaxed(n_words, controller->base + QUP_MX_INPUT_CNT); - writel_relaxed(n_words, controller->base + QUP_MX_OUTPUT_CNT); - /* must be zero for BLOCK and BAM */ - writel_relaxed(0, controller->base + QUP_MX_READ_CNT); - writel_relaxed(0, controller->base + QUP_MX_WRITE_CNT); -+ controller->use_dma = 0; -+ } else { -+ mode = QUP_IO_M_MODE_DMOV; -+ writel_relaxed(0, controller->base + QUP_MX_READ_CNT); -+ writel_relaxed(0, controller->base + QUP_MX_WRITE_CNT); -+ controller->use_dma = 1; - } - - iomode = readl_relaxed(controller->base + QUP_IO_M_MODES); - /* Set input and output transfer mode */ - iomode &= ~(QUP_IO_M_INPUT_MODE_MASK | QUP_IO_M_OUTPUT_MODE_MASK); -- iomode &= ~(QUP_IO_M_PACK_EN | QUP_IO_M_UNPACK_EN); -+ -+ if (!controller->use_dma) -+ iomode &= ~(QUP_IO_M_PACK_EN | QUP_IO_M_UNPACK_EN); -+ else -+ iomode |= QUP_IO_M_PACK_EN | QUP_IO_M_UNPACK_EN; -+ - iomode |= (mode << QUP_IO_M_OUTPUT_MODE_MASK_SHIFT); - iomode |= (mode << QUP_IO_M_INPUT_MODE_MASK_SHIFT); - -@@ -419,6 +670,14 @@ static int spi_qup_io_config(struct spi_ - config &= ~(QUP_CONFIG_NO_INPUT | QUP_CONFIG_NO_OUTPUT | QUP_CONFIG_N); - config |= xfer->bits_per_word - 1; - config |= QUP_CONFIG_SPI_MODE; -+ -+ if (controller->use_dma) { -+ if (!xfer->tx_buf) -+ config |= QUP_CONFIG_NO_OUTPUT; -+ if (!xfer->rx_buf) -+ config |= QUP_CONFIG_NO_INPUT; -+ } -+ - writel_relaxed(config, controller->base + QUP_CONFIG); - - /* only write to OPERATIONAL_MASK when register is present */ -@@ -452,25 +711,29 @@ static int spi_qup_transfer_one(struct s - controller->tx_bytes = 0; - spin_unlock_irqrestore(&controller->lock, flags); - -- if (spi_qup_set_state(controller, QUP_STATE_RUN)) { -- dev_warn(controller->dev, "cannot set RUN state\n"); -- goto exit; -- } -+ if (controller->use_dma) { -+ ret = spi_qup_do_dma(controller, xfer); -+ } else { -+ if (spi_qup_set_state(controller, QUP_STATE_RUN)) { -+ dev_warn(controller->dev, "cannot set RUN state\n"); -+ goto exit; -+ } - -- if (spi_qup_set_state(controller, QUP_STATE_PAUSE)) { -- dev_warn(controller->dev, "cannot set PAUSE state\n"); -- goto exit; -- } -+ if (spi_qup_set_state(controller, QUP_STATE_PAUSE)) { -+ dev_warn(controller->dev, "cannot set PAUSE state\n"); -+ goto exit; -+ } - -- spi_qup_fifo_write(controller, xfer); -+ spi_qup_fifo_write(controller, xfer); - -- if (spi_qup_set_state(controller, QUP_STATE_RUN)) { -- dev_warn(controller->dev, "cannot set EXECUTE state\n"); -- goto exit; -- } -+ if (spi_qup_set_state(controller, QUP_STATE_RUN)) { -+ dev_warn(controller->dev, "cannot set EXECUTE state\n"); -+ goto exit; -+ } - -- if (!wait_for_completion_timeout(&controller->done, timeout)) -- ret = -ETIMEDOUT; -+ if (!wait_for_completion_timeout(&controller->done, timeout)) -+ ret = -ETIMEDOUT; -+ } - exit: - spi_qup_set_state(controller, QUP_STATE_RESET); - spin_lock_irqsave(&controller->lock, flags); -@@ -554,6 +817,7 @@ static int spi_qup_probe(struct platform - master->transfer_one = spi_qup_transfer_one; - master->dev.of_node = pdev->dev.of_node; - master->auto_runtime_pm = true; -+ master->dma_alignment = dma_get_cache_alignment(); - - platform_set_drvdata(pdev, master); - -@@ -619,6 +883,56 @@ static int spi_qup_probe(struct platform - QUP_ERROR_INPUT_UNDER_RUN | QUP_ERROR_OUTPUT_UNDER_RUN, - base + QUP_ERROR_FLAGS_EN); - -+ /* allocate dma resources, if available */ -+ controller->rx_chan = dma_request_slave_channel(&pdev->dev, "rx"); -+ if (controller->rx_chan) { -+ controller->tx_chan = -+ dma_request_slave_channel(&pdev->dev, "tx"); -+ -+ if (!controller->tx_chan) { -+ dev_err(&pdev->dev, "Failed to allocate dma tx chan"); -+ dma_release_channel(controller->rx_chan); -+ } -+ -+ /* set DMA parameters */ -+ controller->rx_conf.device_fc = 1; -+ controller->rx_conf.src_addr = res->start + QUP_INPUT_FIFO; -+ controller->rx_conf.src_maxburst = controller->in_blk_sz; -+ -+ controller->tx_conf.device_fc = 1; -+ controller->tx_conf.dst_addr = res->start + QUP_OUTPUT_FIFO; -+ controller->tx_conf.dst_maxburst = controller->out_blk_sz; -+ -+ if (dmaengine_slave_config(controller->rx_chan, -+ &controller->rx_conf)) { -+ dev_err(&pdev->dev, "failed to configure RX channel\n"); -+ -+ dma_release_channel(controller->rx_chan); -+ dma_release_channel(controller->tx_chan); -+ controller->tx_chan = NULL; -+ controller->rx_chan = NULL; -+ } else if (dmaengine_slave_config(controller->tx_chan, -+ &controller->tx_conf)) { -+ dev_err(&pdev->dev, "failed to configure TX channel\n"); -+ -+ dma_release_channel(controller->rx_chan); -+ dma_release_channel(controller->tx_chan); -+ controller->tx_chan = NULL; -+ controller->rx_chan = NULL; -+ } -+ -+ controller->dummy = devm_kmalloc(controller->dev, PAGE_SIZE, -+ GFP_KERNEL); -+ -+ if (!controller->dummy) { -+ dma_release_channel(controller->rx_chan); -+ dma_release_channel(controller->tx_chan); -+ controller->tx_chan = NULL; -+ controller->rx_chan = NULL; -+ } -+ } -+ -+ - writel_relaxed(0, base + SPI_CONFIG); - writel_relaxed(SPI_IO_C_NO_TRI_STATE, base + SPI_IO_CONTROL); - -@@ -731,6 +1045,11 @@ static int spi_qup_remove(struct platfor - if (ret) - return ret; - -+ if (controller->rx_chan) -+ dma_release_channel(controller->rx_chan); -+ if (controller->tx_chan) -+ dma_release_channel(controller->tx_chan); -+ - clk_disable_unprepare(controller->cclk); - clk_disable_unprepare(controller->iclk); - diff --git a/target/linux/ipq806x/patches-3.18/002-v3-spi-qup-Fix-incorrect-block-transfers.patch b/target/linux/ipq806x/patches-3.18/002-v3-spi-qup-Fix-incorrect-block-transfers.patch deleted file mode 100644 index 62ee5b4fad..0000000000 --- a/target/linux/ipq806x/patches-3.18/002-v3-spi-qup-Fix-incorrect-block-transfers.patch +++ /dev/null @@ -1,376 +0,0 @@ -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [v3] spi: qup: Fix incorrect block transfers -From: Andy Gross -X-Patchwork-Id: 5007321 -Message-Id: <1412112088-25928-1-git-send-email-agross@codeaurora.org> -To: Mark Brown -Cc: linux-spi@vger.kernel.org, linux-kernel@vger.kernel.org, - linux-arm-kernel@lists.infradead.org, linux-arm-msm@vger.kernel.org, - "Ivan T. Ivanov" , - Bjorn Andersson , - Kumar Gala , Andy Gross -Date: Tue, 30 Sep 2014 16:21:28 -0500 - -This patch fixes a number of errors with the QUP block transfer mode. Errors -manifested themselves as input underruns, output overruns, and timed out -transactions. - -The block mode does not require the priming that occurs in FIFO mode. At the -moment that the QUP is placed into the RUN state, the QUP will immediately raise -an interrupt if the request is a write. Therefore, there is no need to prime -the pump. - -In addition, the block transfers require that whole blocks of data are -read/written at a time. The last block of data that completes a transaction may -contain less than a full blocks worth of data. - -Each block of data results in an input/output service interrupt accompanied with -a input/output block flag set. Additional block reads/writes require clearing -of the service flag. It is ok to check for additional blocks of data in the -ISR, but you have to ack every block you transfer. Imbalanced acks result in -early return from complete transactions with pending interrupts that still have -to be ack'd. The next transaction can be affected by these interrupts. -Transactions are deemed complete when the MAX_INPUT or MAX_OUTPUT flag are set. - -Changes from v2: -- Added in additional completion check so that transaction done is not - prematurely signaled. -- Fixed various review comments. - -Changes from v1: -- Split out read/write block function. -- Removed extraneous checks for transfer length - -Signed-off-by: Andy Gross - ---- -drivers/spi/spi-qup.c | 201 ++++++++++++++++++++++++++++++++++++------------- - 1 file changed, 148 insertions(+), 53 deletions(-) - ---- a/drivers/spi/spi-qup.c -+++ b/drivers/spi/spi-qup.c -@@ -82,6 +82,8 @@ - #define QUP_IO_M_MODE_BAM 3 - - /* QUP_OPERATIONAL fields */ -+#define QUP_OP_IN_BLOCK_READ_REQ BIT(13) -+#define QUP_OP_OUT_BLOCK_WRITE_REQ BIT(12) - #define QUP_OP_MAX_INPUT_DONE_FLAG BIT(11) - #define QUP_OP_MAX_OUTPUT_DONE_FLAG BIT(10) - #define QUP_OP_IN_SERVICE_FLAG BIT(9) -@@ -147,6 +149,7 @@ struct spi_qup { - int tx_bytes; - int rx_bytes; - int qup_v1; -+ int mode; - - int use_dma; - -@@ -213,30 +216,14 @@ static int spi_qup_set_state(struct spi_ - return 0; - } - -- --static void spi_qup_fifo_read(struct spi_qup *controller, -- struct spi_transfer *xfer) -+static void spi_qup_fill_read_buffer(struct spi_qup *controller, -+ struct spi_transfer *xfer, u32 data) - { - u8 *rx_buf = xfer->rx_buf; -- u32 word, state; -- int idx, shift, w_size; -- -- w_size = controller->w_size; -- -- while (controller->rx_bytes < xfer->len) { -- -- state = readl_relaxed(controller->base + QUP_OPERATIONAL); -- if (0 == (state & QUP_OP_IN_FIFO_NOT_EMPTY)) -- break; -- -- word = readl_relaxed(controller->base + QUP_INPUT_FIFO); -- -- if (!rx_buf) { -- controller->rx_bytes += w_size; -- continue; -- } -+ int idx, shift; - -- for (idx = 0; idx < w_size; idx++, controller->rx_bytes++) { -+ if (rx_buf) -+ for (idx = 0; idx < controller->w_size; idx++) { - /* - * The data format depends on bytes per SPI word: - * 4 bytes: 0x12345678 -@@ -244,41 +231,139 @@ static void spi_qup_fifo_read(struct spi - * 1 byte : 0x00000012 - */ - shift = BITS_PER_BYTE; -- shift *= (w_size - idx - 1); -- rx_buf[controller->rx_bytes] = word >> shift; -+ shift *= (controller->w_size - idx - 1); -+ rx_buf[controller->rx_bytes + idx] = data >> shift; -+ } -+ -+ controller->rx_bytes += controller->w_size; -+} -+ -+static void spi_qup_prepare_write_data(struct spi_qup *controller, -+ struct spi_transfer *xfer, u32 *data) -+{ -+ const u8 *tx_buf = xfer->tx_buf; -+ u32 val; -+ int idx; -+ -+ *data = 0; -+ -+ if (tx_buf) -+ for (idx = 0; idx < controller->w_size; idx++) { -+ val = tx_buf[controller->tx_bytes + idx]; -+ *data |= val << (BITS_PER_BYTE * (3 - idx)); - } -+ -+ controller->tx_bytes += controller->w_size; -+} -+ -+static void spi_qup_fifo_read(struct spi_qup *controller, -+ struct spi_transfer *xfer) -+{ -+ u32 data; -+ -+ /* clear service request */ -+ writel_relaxed(QUP_OP_IN_SERVICE_FLAG, -+ controller->base + QUP_OPERATIONAL); -+ -+ while (controller->rx_bytes < xfer->len) { -+ if (!(readl_relaxed(controller->base + QUP_OPERATIONAL) & -+ QUP_OP_IN_FIFO_NOT_EMPTY)) -+ break; -+ -+ data = readl_relaxed(controller->base + QUP_INPUT_FIFO); -+ -+ spi_qup_fill_read_buffer(controller, xfer, data); - } - } - - static void spi_qup_fifo_write(struct spi_qup *controller, -- struct spi_transfer *xfer) -+ struct spi_transfer *xfer) - { -- const u8 *tx_buf = xfer->tx_buf; -- u32 word, state, data; -- int idx, w_size; -+ u32 data; - -- w_size = controller->w_size; -+ /* clear service request */ -+ writel_relaxed(QUP_OP_OUT_SERVICE_FLAG, -+ controller->base + QUP_OPERATIONAL); - - while (controller->tx_bytes < xfer->len) { - -- state = readl_relaxed(controller->base + QUP_OPERATIONAL); -- if (state & QUP_OP_OUT_FIFO_FULL) -+ if (readl_relaxed(controller->base + QUP_OPERATIONAL) & -+ QUP_OP_OUT_FIFO_FULL) - break; - -- word = 0; -- for (idx = 0; idx < w_size; idx++, controller->tx_bytes++) { -+ spi_qup_prepare_write_data(controller, xfer, &data); -+ writel_relaxed(data, controller->base + QUP_OUTPUT_FIFO); - -- if (!tx_buf) { -- controller->tx_bytes += w_size; -- break; -- } -+ } -+} - -- data = tx_buf[controller->tx_bytes]; -- word |= data << (BITS_PER_BYTE * (3 - idx)); -- } -+static void spi_qup_block_read(struct spi_qup *controller, -+ struct spi_transfer *xfer) -+{ -+ u32 data; -+ u32 reads_per_blk = controller->in_blk_sz >> 2; -+ u32 num_words = (xfer->len - controller->rx_bytes) / controller->w_size; -+ int i; -+ -+ do { -+ /* ACK by clearing service flag */ -+ writel_relaxed(QUP_OP_IN_SERVICE_FLAG, -+ controller->base + QUP_OPERATIONAL); -+ -+ /* transfer up to a block size of data in a single pass */ -+ for (i = 0; num_words && i < reads_per_blk; i++, num_words--) { -+ -+ /* read data and fill up rx buffer */ -+ data = readl_relaxed(controller->base + QUP_INPUT_FIFO); -+ spi_qup_fill_read_buffer(controller, xfer, data); -+ } -+ -+ /* check to see if next block is ready */ -+ if (!(readl_relaxed(controller->base + QUP_OPERATIONAL) & -+ QUP_OP_IN_BLOCK_READ_REQ)) -+ break; - -- writel_relaxed(word, controller->base + QUP_OUTPUT_FIFO); -- } -+ } while (num_words); -+ -+ /* -+ * Due to extra stickiness of the QUP_OP_IN_SERVICE_FLAG during block -+ * reads, it has to be cleared again at the very end -+ */ -+ if (readl_relaxed(controller->base + QUP_OPERATIONAL) & -+ QUP_OP_MAX_INPUT_DONE_FLAG) -+ writel_relaxed(QUP_OP_IN_SERVICE_FLAG, -+ controller->base + QUP_OPERATIONAL); -+ -+} -+ -+static void spi_qup_block_write(struct spi_qup *controller, -+ struct spi_transfer *xfer) -+{ -+ u32 data; -+ u32 writes_per_blk = controller->out_blk_sz >> 2; -+ u32 num_words = (xfer->len - controller->tx_bytes) / controller->w_size; -+ int i; -+ -+ do { -+ /* ACK by clearing service flag */ -+ writel_relaxed(QUP_OP_OUT_SERVICE_FLAG, -+ controller->base + QUP_OPERATIONAL); -+ -+ /* transfer up to a block size of data in a single pass */ -+ for (i = 0; num_words && i < writes_per_blk; i++, num_words--) { -+ -+ /* swizzle the bytes for output and write out */ -+ spi_qup_prepare_write_data(controller, xfer, &data); -+ writel_relaxed(data, -+ controller->base + QUP_OUTPUT_FIFO); -+ } -+ -+ /* check to see if next block is ready */ -+ if (!(readl_relaxed(controller->base + QUP_OPERATIONAL) & -+ QUP_OP_OUT_BLOCK_WRITE_REQ)) -+ break; -+ -+ } while (num_words); - } - - static void qup_dma_callback(void *data) -@@ -515,9 +600,9 @@ static irqreturn_t spi_qup_qup_irq(int i - - writel_relaxed(qup_err, controller->base + QUP_ERROR_FLAGS); - writel_relaxed(spi_err, controller->base + SPI_ERROR_FLAGS); -- writel_relaxed(opflags, controller->base + QUP_OPERATIONAL); - - if (!xfer) { -+ writel_relaxed(opflags, controller->base + QUP_OPERATIONAL); - dev_err_ratelimited(controller->dev, "unexpected irq %08x %08x %08x\n", - qup_err, spi_err, opflags); - return IRQ_HANDLED; -@@ -546,11 +631,19 @@ static irqreturn_t spi_qup_qup_irq(int i - } - - if (!controller->use_dma) { -- if (opflags & QUP_OP_IN_SERVICE_FLAG) -- spi_qup_fifo_read(controller, xfer); -+ if (opflags & QUP_OP_IN_SERVICE_FLAG) { -+ if (opflags & QUP_OP_IN_BLOCK_READ_REQ) -+ spi_qup_block_read(controller, xfer); -+ else -+ spi_qup_fifo_read(controller, xfer); -+ } - -- if (opflags & QUP_OP_OUT_SERVICE_FLAG) -- spi_qup_fifo_write(controller, xfer); -+ if (opflags & QUP_OP_OUT_SERVICE_FLAG) { -+ if (opflags & QUP_OP_OUT_BLOCK_WRITE_REQ) -+ spi_qup_block_write(controller, xfer); -+ else -+ spi_qup_fifo_write(controller, xfer); -+ } - } - - spin_lock_irqsave(&controller->lock, flags); -@@ -558,7 +651,8 @@ static irqreturn_t spi_qup_qup_irq(int i - controller->xfer = xfer; - spin_unlock_irqrestore(&controller->lock, flags); - -- if (controller->rx_bytes == xfer->len || error) -+ if ((controller->rx_bytes == xfer->len && -+ (opflags & QUP_OP_MAX_INPUT_DONE_FLAG)) || error) - complete(&controller->done); - - return IRQ_HANDLED; -@@ -569,7 +663,7 @@ static irqreturn_t spi_qup_qup_irq(int i - static int spi_qup_io_config(struct spi_device *spi, struct spi_transfer *xfer) - { - struct spi_qup *controller = spi_master_get_devdata(spi->master); -- u32 config, iomode, mode; -+ u32 config, iomode; - int ret, n_words, w_size; - size_t dma_align = dma_get_cache_alignment(); - u32 dma_available = 0; -@@ -607,7 +701,7 @@ static int spi_qup_io_config(struct spi_ - dma_available = 1; - - if (n_words <= (controller->in_fifo_sz / sizeof(u32))) { -- mode = QUP_IO_M_MODE_FIFO; -+ controller->mode = QUP_IO_M_MODE_FIFO; - writel_relaxed(n_words, controller->base + QUP_MX_READ_CNT); - writel_relaxed(n_words, controller->base + QUP_MX_WRITE_CNT); - /* must be zero for FIFO */ -@@ -615,7 +709,7 @@ static int spi_qup_io_config(struct spi_ - writel_relaxed(0, controller->base + QUP_MX_OUTPUT_CNT); - controller->use_dma = 0; - } else if (!dma_available) { -- mode = QUP_IO_M_MODE_BLOCK; -+ controller->mode = QUP_IO_M_MODE_BLOCK; - writel_relaxed(n_words, controller->base + QUP_MX_INPUT_CNT); - writel_relaxed(n_words, controller->base + QUP_MX_OUTPUT_CNT); - /* must be zero for BLOCK and BAM */ -@@ -623,7 +717,7 @@ static int spi_qup_io_config(struct spi_ - writel_relaxed(0, controller->base + QUP_MX_WRITE_CNT); - controller->use_dma = 0; - } else { -- mode = QUP_IO_M_MODE_DMOV; -+ controller->mode = QUP_IO_M_MODE_DMOV; - writel_relaxed(0, controller->base + QUP_MX_READ_CNT); - writel_relaxed(0, controller->base + QUP_MX_WRITE_CNT); - controller->use_dma = 1; -@@ -638,8 +732,8 @@ static int spi_qup_io_config(struct spi_ - else - iomode |= QUP_IO_M_PACK_EN | QUP_IO_M_UNPACK_EN; - -- iomode |= (mode << QUP_IO_M_OUTPUT_MODE_MASK_SHIFT); -- iomode |= (mode << QUP_IO_M_INPUT_MODE_MASK_SHIFT); -+ iomode |= (controller->mode << QUP_IO_M_OUTPUT_MODE_MASK_SHIFT); -+ iomode |= (controller->mode << QUP_IO_M_INPUT_MODE_MASK_SHIFT); - - writel_relaxed(iomode, controller->base + QUP_IO_M_MODES); - -@@ -724,7 +818,8 @@ static int spi_qup_transfer_one(struct s - goto exit; - } - -- spi_qup_fifo_write(controller, xfer); -+ if (controller->mode == QUP_IO_M_MODE_FIFO) -+ spi_qup_fifo_write(controller, xfer); - - if (spi_qup_set_state(controller, QUP_STATE_RUN)) { - dev_warn(controller->dev, "cannot set EXECUTE state\n"); -@@ -741,6 +836,7 @@ exit: - if (!ret) - ret = controller->error; - spin_unlock_irqrestore(&controller->lock, flags); -+ - return ret; - } - diff --git a/target/linux/ipq806x/patches-3.18/003-spi-qup-Ensure-done-detection.patch b/target/linux/ipq806x/patches-3.18/003-spi-qup-Ensure-done-detection.patch deleted file mode 100644 index 7052227810..0000000000 --- a/target/linux/ipq806x/patches-3.18/003-spi-qup-Ensure-done-detection.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 4faba89e3ffbb1c5f6232651375b9b3212b50f02 Mon Sep 17 00:00:00 2001 -From: Andy Gross -Date: Thu, 15 Jan 2015 17:56:02 -0800 -Subject: [PATCH] spi: qup: Ensure done detection - -This patch fixes an issue where a SPI transaction has completed, but the done -condition is missed. This occurs because at the time of interrupt the -MAX_INPUT_DONE_FLAG is not asserted. However, in the process of reading blocks -of data from the FIFO, the last portion of data comes in. - -The opflags read at the beginning of the irq handler no longer matches the -current opflag state. To get around this condition, the block read function -should update the opflags so that done detection is correct after the return. - -Change-Id: If109e0eeb432f96000d765c4b34dbb2269f8093f -Signed-off-by: Andy Gross ---- - drivers/spi/spi-qup.c | 12 +++++++----- - 1 file changed, 7 insertions(+), 5 deletions(-) - ---- a/drivers/spi/spi-qup.c -+++ b/drivers/spi/spi-qup.c -@@ -298,7 +298,7 @@ static void spi_qup_fifo_write(struct sp - } - - static void spi_qup_block_read(struct spi_qup *controller, -- struct spi_transfer *xfer) -+ struct spi_transfer *xfer, u32 *opflags) - { - u32 data; - u32 reads_per_blk = controller->in_blk_sz >> 2; -@@ -327,10 +327,12 @@ static void spi_qup_block_read(struct sp - - /* - * Due to extra stickiness of the QUP_OP_IN_SERVICE_FLAG during block -- * reads, it has to be cleared again at the very end -+ * reads, it has to be cleared again at the very end. However, be sure -+ * to refresh opflags value because MAX_INPUT_DONE_FLAG may now be -+ * present and this is used to determine if transaction is complete - */ -- if (readl_relaxed(controller->base + QUP_OPERATIONAL) & -- QUP_OP_MAX_INPUT_DONE_FLAG) -+ *opflags = readl_relaxed(controller->base + QUP_OPERATIONAL); -+ if (*opflags & QUP_OP_MAX_INPUT_DONE_FLAG) - writel_relaxed(QUP_OP_IN_SERVICE_FLAG, - controller->base + QUP_OPERATIONAL); - -@@ -633,7 +635,7 @@ static irqreturn_t spi_qup_qup_irq(int i - if (!controller->use_dma) { - if (opflags & QUP_OP_IN_SERVICE_FLAG) { - if (opflags & QUP_OP_IN_BLOCK_READ_REQ) -- spi_qup_block_read(controller, xfer); -+ spi_qup_block_read(controller, xfer, &opflags); - else - spi_qup_fifo_read(controller, xfer); - } diff --git a/target/linux/ipq806x/patches-3.18/011-watchdog-qcom-use-timer-devicetree-binding.patch b/target/linux/ipq806x/patches-3.18/011-watchdog-qcom-use-timer-devicetree-binding.patch deleted file mode 100644 index 68489a83b5..0000000000 --- a/target/linux/ipq806x/patches-3.18/011-watchdog-qcom-use-timer-devicetree-binding.patch +++ /dev/null @@ -1,67 +0,0 @@ -From fded70251b1b58f68de1d3757ece9965f0b75452 Mon Sep 17 00:00:00 2001 -From: Mathieu Olivari -Date: Thu, 19 Feb 2015 20:19:30 -0800 -Subject: [PATCH 1/3] watchdog: qcom: use timer devicetree binding - -MSM watchdog configuration happens in the same register block as the -timer, so we'll use the same binding as the existing timer. - -The qcom-wdt will now be probed when devicetree has an entry compatible -with "qcom,kpss-timer" or "qcom-scss-timer". - -Signed-off-by: Mathieu Olivari ---- - drivers/watchdog/qcom-wdt.c | 21 +++++++++++++++------ - 1 file changed, 15 insertions(+), 6 deletions(-) - ---- a/drivers/watchdog/qcom-wdt.c -+++ b/drivers/watchdog/qcom-wdt.c -@@ -20,9 +20,9 @@ - #include - #include - --#define WDT_RST 0x0 --#define WDT_EN 0x8 --#define WDT_BITE_TIME 0x24 -+#define WDT_RST 0x38 -+#define WDT_EN 0x40 -+#define WDT_BITE_TIME 0x5C - - struct qcom_wdt { - struct watchdog_device wdd; -@@ -117,6 +117,8 @@ static int qcom_wdt_probe(struct platfor - { - struct qcom_wdt *wdt; - struct resource *res; -+ struct device_node *np = pdev->dev.of_node; -+ u32 percpu_offset; - int ret; - - wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL); -@@ -124,6 +126,14 @@ static int qcom_wdt_probe(struct platfor - return -ENOMEM; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ -+ /* We use CPU0's DGT for the watchdog */ -+ if (of_property_read_u32(np, "cpu-offset", &percpu_offset)) -+ percpu_offset = 0; -+ -+ res->start += percpu_offset; -+ res->end += percpu_offset; -+ - wdt->base = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(wdt->base)) - return PTR_ERR(wdt->base); -@@ -203,9 +213,8 @@ static int qcom_wdt_remove(struct platfo - } - - static const struct of_device_id qcom_wdt_of_table[] = { -- { .compatible = "qcom,kpss-wdt-msm8960", }, -- { .compatible = "qcom,kpss-wdt-apq8064", }, -- { .compatible = "qcom,kpss-wdt-ipq8064", }, -+ { .compatible = "qcom,kpss-timer" }, -+ { .compatible = "qcom,scss-timer" }, - { }, - }; - MODULE_DEVICE_TABLE(of, qcom_wdt_of_table); diff --git a/target/linux/ipq806x/patches-3.18/012-ARM-qcom-add-description-of-KPSS-WDT-for-IPQ8064.patch b/target/linux/ipq806x/patches-3.18/012-ARM-qcom-add-description-of-KPSS-WDT-for-IPQ8064.patch deleted file mode 100644 index ae9677656e..0000000000 --- a/target/linux/ipq806x/patches-3.18/012-ARM-qcom-add-description-of-KPSS-WDT-for-IPQ8064.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 297cf8136ecd6a56520888fd28948393766b8ee7 Mon Sep 17 00:00:00 2001 -From: Mathieu Olivari -Date: Thu, 19 Feb 2015 20:27:39 -0800 -Subject: [PATCH 2/3] ARM: qcom: add description of KPSS WDT for IPQ8064 - -Add the watchdog related entries to the Krait Processor Sub-system -(KPSS) timer IPQ8064 devicetree section. Also, add a fixed-clock -description of SLEEP_CLK, which will do for now. - -Signed-off-by: Josh Cartwright -Signed-off-by: Mathieu Olivari ---- - arch/arm/boot/dts/qcom-ipq8064.dtsi | 14 +++++++++++++- - 1 file changed, 13 insertions(+), 1 deletion(-) - ---- a/arch/arm/boot/dts/qcom-ipq8064.dtsi -+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi -@@ -60,6 +60,14 @@ - }; - }; - -+ clocks { -+ sleep_clk: sleep_clk { -+ compatible = "fixed-clock"; -+ clock-frequency = <32768>; -+ #clock-cells = <0>; -+ }; -+ }; -+ - soc: soc { - #address-cells = <1>; - #size-cells = <1>; -@@ -89,10 +97,14 @@ - compatible = "qcom,kpss-timer", "qcom,msm-timer"; - interrupts = <1 1 0x301>, - <1 2 0x301>, -- <1 3 0x301>; -+ <1 3 0x301>, -+ <1 4 0x301>, -+ <1 5 0x301>; - reg = <0x0200a000 0x100>; - clock-frequency = <25000000>, - <32768>; -+ clocks = <&sleep_clk>; -+ clock-names = "sleep"; - cpu-offset = <0x80000>; - }; - diff --git a/target/linux/ipq806x/patches-3.18/013-ARM-msm-add-watchdog-entries-to-DT-timer-binding-doc.patch b/target/linux/ipq806x/patches-3.18/013-ARM-msm-add-watchdog-entries-to-DT-timer-binding-doc.patch deleted file mode 100644 index 6876768962..0000000000 --- a/target/linux/ipq806x/patches-3.18/013-ARM-msm-add-watchdog-entries-to-DT-timer-binding-doc.patch +++ /dev/null @@ -1,50 +0,0 @@ -From e535f01dffb6dd9e09934fa219be52af3437a8f6 Mon Sep 17 00:00:00 2001 -From: Mathieu Olivari -Date: Thu, 19 Feb 2015 20:36:27 -0800 -Subject: [PATCH 3/3] ARM: msm: add watchdog entries to DT timer binding doc - -The watchdog has been reworked to use the same DT node as the timer. -This change is updating the device tree doc accordingly. - -Signed-off-by: Mathieu Olivari ---- - Documentation/devicetree/bindings/arm/msm/timer.txt | 16 +++++++++++++--- - 1 file changed, 13 insertions(+), 3 deletions(-) - ---- a/Documentation/devicetree/bindings/arm/msm/timer.txt -+++ b/Documentation/devicetree/bindings/arm/msm/timer.txt -@@ -9,11 +9,17 @@ Properties: - "qcom,scss-timer" - scorpion subsystem - - - interrupts : Interrupts for the the debug timer, the first general purpose -- timer, and optionally a second general purpose timer in that -- order. -+ timer, and optionally a second general purpose timer, and -+ optionally as well, 2 watchdog interrupts, in that order. - - - reg : Specifies the base address of the timer registers. - -+- clocks: Reference to the parent clocks, one per output clock. The parents -+ must appear in the same order as the clock names. -+ -+- clock-names: The name of the clocks as free-form strings. They should be in -+ the same order as the clocks. -+ - - clock-frequency : The frequency of the debug timer and the general purpose - timer(s) in Hz in that order. - -@@ -29,9 +35,13 @@ Example: - compatible = "qcom,scss-timer", "qcom,msm-timer"; - interrupts = <1 1 0x301>, - <1 2 0x301>, -- <1 3 0x301>; -+ <1 3 0x301>, -+ <1 4 0x301>, -+ <1 5 0x301>; - reg = <0x0200a000 0x100>; - clock-frequency = <19200000>, - <32768>; -+ clocks = <&sleep_clk>; -+ clock-names = "sleep"; - cpu-offset = <0x40000>; - }; diff --git a/target/linux/ipq806x/patches-3.18/020-add-ap148-bootargs.patch b/target/linux/ipq806x/patches-3.18/020-add-ap148-bootargs.patch deleted file mode 100644 index a61481e652..0000000000 --- a/target/linux/ipq806x/patches-3.18/020-add-ap148-bootargs.patch +++ /dev/null @@ -1,46 +0,0 @@ ---- a/arch/arm/boot/dts/qcom-ipq8064-ap148.dts -+++ b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts -@@ -14,6 +14,14 @@ - }; - }; - -+ alias { -+ serial0 = &uart4; -+ }; -+ -+ chosen { -+ linux,stdout-path = "serial0:115200n8"; -+ }; -+ - soc { - pinmux@800000 { - i2c4_pins: i2c4_pinmux { ---- a/arch/arm/boot/dts/qcom-ipq8064.dtsi -+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi -@@ -140,7 +140,7 @@ - ranges; - status = "disabled"; - -- serial@12490000 { -+ uart2: serial@12490000 { - compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm"; - reg = <0x12490000 0x1000>, - <0x12480000 0x1000>; -@@ -175,7 +175,7 @@ - ranges; - status = "disabled"; - -- serial@16340000 { -+ uart4: serial@16340000 { - compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm"; - reg = <0x16340000 0x1000>, - <0x16300000 0x1000>; -@@ -209,7 +209,7 @@ - ranges; - status = "disabled"; - -- serial@1a240000 { -+ uart5: serial@1a240000 { - compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm"; - reg = <0x1a240000 0x1000>, - <0x1a200000 0x1000>; diff --git a/target/linux/ipq806x/patches-3.18/021-add-ap148-partitions.patch b/target/linux/ipq806x/patches-3.18/021-add-ap148-partitions.patch deleted file mode 100644 index 34eb9c0dfa..0000000000 --- a/target/linux/ipq806x/patches-3.18/021-add-ap148-partitions.patch +++ /dev/null @@ -1,35 +0,0 @@ ---- a/arch/arm/boot/dts/qcom-ipq8064-ap148.dts -+++ b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts -@@ -78,13 +78,28 @@ - reg = <0>; - - partition@0 { -- label = "rootfs"; -- reg = <0x0 0x1000000>; -+ label = "lowlevel_init"; -+ reg = <0x0 0x1b0000>; - }; - - partition@1 { -- label = "scratch"; -- reg = <0x1000000 0x1000000>; -+ label = "u-boot"; -+ reg = <0x1b0000 0x80000>; -+ }; -+ -+ partition@2 { -+ label = "u-boot-env"; -+ reg = <0x230000 0x40000>; -+ }; -+ -+ partition@3 { -+ label = "caldata"; -+ reg = <0x270000 0x40000>; -+ }; -+ -+ partition@4 { -+ label = "firmware"; -+ reg = <0x2b0000 0x1d50000>; - }; - }; - }; diff --git a/target/linux/ipq806x/patches-3.18/022-add-db149-dts.patch b/target/linux/ipq806x/patches-3.18/022-add-db149-dts.patch deleted file mode 100644 index bd6ec1e94f..0000000000 --- a/target/linux/ipq806x/patches-3.18/022-add-db149-dts.patch +++ /dev/null @@ -1,160 +0,0 @@ -From a32d6e7c8fca6371a2614924b89981bc912b6378 Mon Sep 17 00:00:00 2001 -From: Mathieu Olivari -Date: Tue, 7 Apr 2015 19:58:58 -0700 -Subject: [PATCH] ARM: dts: qcom: add initial DB149 device-tree - -Add basic DB149 (IPQ806x based platform) device-tree. It supports UART, -SATA, USB2, USB3 and NOR flash. - -Signed-off-by: Mathieu Olivari ---- - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/qcom-ipq8064-db149.dts | 257 +++++++++++++++++++++++++++++++ - 2 files changed, 258 insertions(+) - create mode 100644 arch/arm/boot/dts/qcom-ipq8064-db149.dts - ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -360,6 +360,7 @@ dtb-$(CONFIG_ARCH_QCOM) += \ - qcom-apq8084-ifc6540.dtb \ - qcom-apq8084-mtp.dtb \ - qcom-ipq8064-ap148.dtb \ -+ qcom-ipq8064-db149.dtb \ - qcom-msm8660-surf.dtb \ - qcom-msm8960-cdp.dtb \ - qcom-msm8974-sony-xperia-honami.dtb ---- /dev/null -+++ b/arch/arm/boot/dts/qcom-ipq8064-db149.dts -@@ -0,0 +1,132 @@ -+#include "qcom-ipq8064-v1.0.dtsi" -+ -+/ { -+ model = "Qualcomm IPQ8064/DB149"; -+ compatible = "qcom,ipq8064-db149", "qcom,ipq8064"; -+ -+ reserved-memory { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges; -+ rsvd@41200000 { -+ reg = <0x41200000 0x300000>; -+ no-map; -+ }; -+ }; -+ -+ alias { -+ serial0 = &uart2; -+ }; -+ -+ chosen { -+ linux,stdout-path = "serial0:115200n8"; -+ }; -+ -+ soc { -+ pinmux@800000 { -+ i2c4_pins: i2c4_pinmux { -+ pins = "gpio12", "gpio13"; -+ function = "gsbi4"; -+ bias-disable; -+ }; -+ -+ spi_pins: spi_pins { -+ mux { -+ pins = "gpio18", "gpio19", "gpio21"; -+ function = "gsbi5"; -+ drive-strength = <10>; -+ bias-none; -+ }; -+ }; -+ }; -+ -+ gsbi2: gsbi@12480000 { -+ qcom,mode = ; -+ status = "ok"; -+ uart2: serial@12490000 { -+ status = "ok"; -+ }; -+ }; -+ -+ gsbi5: gsbi@1a200000 { -+ qcom,mode = ; -+ status = "ok"; -+ -+ spi4: spi@1a280000 { -+ status = "ok"; -+ spi-max-frequency = <50000000>; -+ -+ pinctrl-0 = <&spi_pins>; -+ pinctrl-names = "default"; -+ -+ cs-gpios = <&qcom_pinmux 20 0>; -+ -+ flash: m25p80@0 { -+ compatible = "s25fl256s1"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ spi-max-frequency = <50000000>; -+ reg = <0>; -+ m25p,fast-read; -+ -+ partition@0 { -+ label = "lowlevel_init"; -+ reg = <0x0 0x1b0000>; -+ }; -+ -+ partition@1 { -+ label = "u-boot"; -+ reg = <0x1b0000 0x80000>; -+ }; -+ -+ partition@2 { -+ label = "u-boot-env"; -+ reg = <0x230000 0x40000>; -+ }; -+ -+ partition@3 { -+ label = "caldata"; -+ reg = <0x270000 0x40000>; -+ }; -+ -+ partition@4 { -+ label = "firmware"; -+ reg = <0x2b0000 0x1d50000>; -+ }; -+ }; -+ }; -+ }; -+ -+ sata-phy@1b400000 { -+ status = "ok"; -+ }; -+ -+ sata@29000000 { -+ status = "ok"; -+ }; -+ -+ phy@100f8800 { /* USB3 port 1 HS phy */ -+ status = "ok"; -+ }; -+ -+ phy@100f8830 { /* USB3 port 1 SS phy */ -+ status = "ok"; -+ }; -+ -+ phy@110f8800 { /* USB3 port 0 HS phy */ -+ status = "ok"; -+ }; -+ -+ phy@110f8830 { /* USB3 port 0 SS phy */ -+ status = "ok"; -+ }; -+ -+ usb30@0 { -+ status = "ok"; -+ }; -+ -+ usb30@1 { -+ status = "ok"; -+ }; -+ }; -+}; diff --git a/target/linux/ipq806x/patches-3.18/023-ARM-dts-ipq806x-Disable-i2c-device-on-gsbi4.patch b/target/linux/ipq806x/patches-3.18/023-ARM-dts-ipq806x-Disable-i2c-device-on-gsbi4.patch deleted file mode 100644 index 319859b109..0000000000 --- a/target/linux/ipq806x/patches-3.18/023-ARM-dts-ipq806x-Disable-i2c-device-on-gsbi4.patch +++ /dev/null @@ -1,53 +0,0 @@ ---- a/arch/arm/boot/dts/qcom-ipq8064-ap148.dts -+++ b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts -@@ -46,15 +46,12 @@ - serial@16340000 { - status = "ok"; - }; -- -- i2c4: i2c@16380000 { -- status = "ok"; -- -- clock-frequency = <200000>; -- -- pinctrl-0 = <&i2c4_pins>; -- pinctrl-names = "default"; -- }; -+ /* -+ * The i2c device on gsbi4 should not be enabled. -+ * On ipq806x designs gsbi4 i2c is meant for exclusive -+ * RPM usage. Turning this on in kernel manifests as -+ * i2c failure for the RPM. -+ */ - }; - - gsbi5: gsbi@1a200000 { ---- a/drivers/clk/qcom/gcc-ipq806x.c -+++ b/drivers/clk/qcom/gcc-ipq806x.c -@@ -794,7 +794,7 @@ static struct clk_rcg gsbi7_qup_src = { - .parent_names = gcc_pxo_pll8, - .num_parents = 2, - .ops = &clk_rcg_ops, -- .flags = CLK_SET_PARENT_GATE, -+ .flags = CLK_SET_PARENT_GATE | CLK_IGNORE_UNUSED, - }, - }, - }; -@@ -810,7 +810,7 @@ static struct clk_branch gsbi7_qup_clk = - .parent_names = (const char *[]){ "gsbi7_qup_src" }, - .num_parents = 1, - .ops = &clk_branch_ops, -- .flags = CLK_SET_RATE_PARENT, -+ .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, - }, - }, - }; -@@ -858,7 +858,7 @@ static struct clk_branch gsbi4_h_clk = { - .hw.init = &(struct clk_init_data){ - .name = "gsbi4_h_clk", - .ops = &clk_branch_ops, -- .flags = CLK_IS_ROOT, -+ .flags = CLK_IS_ROOT | CLK_IGNORE_UNUSED, - }, - }, - }; diff --git a/target/linux/ipq806x/patches-3.18/100-usb-phy-Add-Qualcomm-DWC3-HS-SS-PHY-drivers.patch b/target/linux/ipq806x/patches-3.18/100-usb-phy-Add-Qualcomm-DWC3-HS-SS-PHY-drivers.patch deleted file mode 100644 index 25803b88eb..0000000000 --- a/target/linux/ipq806x/patches-3.18/100-usb-phy-Add-Qualcomm-DWC3-HS-SS-PHY-drivers.patch +++ /dev/null @@ -1,511 +0,0 @@ ---- a/drivers/phy/Kconfig -+++ b/drivers/phy/Kconfig -@@ -256,4 +256,15 @@ config PHY_STIH41X_USB - Enable this to support the USB transceiver that is part of - STMicroelectronics STiH41x SoC series. - -+config PHY_QCOM_DWC3 -+ tristate "QCOM DWC3 USB PHY support" -+ depends on ARCH_QCOM -+ depends on HAS_IOMEM -+ depends on OF -+ select GENERIC_PHY -+ help -+ This option enables support for the Synopsis PHYs present inside the -+ Qualcomm USB3.0 DWC3 controller. This driver supports both HS and SS -+ PHY controllers. -+ - endmenu ---- a/drivers/phy/Makefile -+++ b/drivers/phy/Makefile -@@ -31,3 +31,4 @@ obj-$(CONFIG_PHY_ST_SPEAR1340_MIPHY) += - obj-$(CONFIG_PHY_XGENE) += phy-xgene.o - obj-$(CONFIG_PHY_STIH407_USB) += phy-stih407-usb.o - obj-$(CONFIG_PHY_STIH41X_USB) += phy-stih41x-usb.o -+obj-$(CONFIG_PHY_QCOM_DWC3) += phy-qcom-dwc3.o ---- /dev/null -+++ b/drivers/phy/phy-qcom-dwc3.c -@@ -0,0 +1,483 @@ -+/* Copyright (c) 2013-2014, Code Aurora Forum. All rights reserved. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 and -+ * only version 2 as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/** -+ * USB QSCRATCH Hardware registers -+ */ -+#define QSCRATCH_GENERAL_CFG (0x08) -+#define HSUSB_PHY_CTRL_REG (0x10) -+ -+/* PHY_CTRL_REG */ -+#define HSUSB_CTRL_DMSEHV_CLAMP BIT(24) -+#define HSUSB_CTRL_USB2_SUSPEND BIT(23) -+#define HSUSB_CTRL_UTMI_CLK_EN BIT(21) -+#define HSUSB_CTRL_UTMI_OTG_VBUS_VALID BIT(20) -+#define HSUSB_CTRL_USE_CLKCORE BIT(18) -+#define HSUSB_CTRL_DPSEHV_CLAMP BIT(17) -+#define HSUSB_CTRL_COMMONONN BIT(11) -+#define HSUSB_CTRL_ID_HV_CLAMP BIT(9) -+#define HSUSB_CTRL_OTGSESSVLD_CLAMP BIT(8) -+#define HSUSB_CTRL_CLAMP_EN BIT(7) -+#define HSUSB_CTRL_RETENABLEN BIT(1) -+#define HSUSB_CTRL_POR BIT(0) -+ -+/* QSCRATCH_GENERAL_CFG */ -+#define HSUSB_GCFG_XHCI_REV BIT(2) -+ -+/** -+ * USB QSCRATCH Hardware registers -+ */ -+#define SSUSB_PHY_CTRL_REG (0x00) -+#define SSUSB_PHY_PARAM_CTRL_1 (0x04) -+#define SSUSB_PHY_PARAM_CTRL_2 (0x08) -+#define CR_PROTOCOL_DATA_IN_REG (0x0c) -+#define CR_PROTOCOL_DATA_OUT_REG (0x10) -+#define CR_PROTOCOL_CAP_ADDR_REG (0x14) -+#define CR_PROTOCOL_CAP_DATA_REG (0x18) -+#define CR_PROTOCOL_READ_REG (0x1c) -+#define CR_PROTOCOL_WRITE_REG (0x20) -+ -+/* PHY_CTRL_REG */ -+#define SSUSB_CTRL_REF_USE_PAD BIT(28) -+#define SSUSB_CTRL_TEST_POWERDOWN BIT(27) -+#define SSUSB_CTRL_LANE0_PWR_PRESENT BIT(24) -+#define SSUSB_CTRL_SS_PHY_EN BIT(8) -+#define SSUSB_CTRL_SS_PHY_RESET BIT(7) -+ -+/* SSPHY control registers */ -+#define SSPHY_CTRL_RX_OVRD_IN_HI(lane) (0x1006 + 0x100 * lane) -+#define SSPHY_CTRL_TX_OVRD_DRV_LO(lane) (0x1002 + 0x100 * lane) -+ -+/* RX OVRD IN HI bits */ -+#define RX_OVRD_IN_HI_RX_RESET_OVRD BIT(13) -+#define RX_OVRD_IN_HI_RX_RX_RESET BIT(12) -+#define RX_OVRD_IN_HI_RX_EQ_OVRD BIT(11) -+#define RX_OVRD_IN_HI_RX_EQ_MASK 0x0700 -+#define RX_OVRD_IN_HI_RX_EQ_SHIFT 8 -+#define RX_OVRD_IN_HI_RX_EQ_EN_OVRD BIT(7) -+#define RX_OVRD_IN_HI_RX_EQ_EN BIT(6) -+#define RX_OVRD_IN_HI_RX_LOS_FILTER_OVRD BIT(5) -+#define RX_OVRD_IN_HI_RX_LOS_FILTER_MASK 0x0018 -+#define RX_OVRD_IN_HI_RX_RATE_OVRD BIT(2) -+#define RX_OVRD_IN_HI_RX_RATE_MASK 0x0003 -+ -+/* TX OVRD DRV LO register bits */ -+#define TX_OVRD_DRV_LO_AMPLITUDE_MASK 0x007F -+#define TX_OVRD_DRV_LO_PREEMPH_MASK 0x3F80 -+#define TX_OVRD_DRV_LO_PREEMPH_SHIFT 7 -+#define TX_OVRD_DRV_LO_EN BIT(14) -+ -+struct qcom_dwc3_usb_phy { -+ void __iomem *base; -+ struct device *dev; -+ struct phy *phy; -+ -+ int (*phy_init)(struct qcom_dwc3_usb_phy *phy_dwc3); -+ int (*phy_exit)(struct qcom_dwc3_usb_phy *phy_dwc3); -+ -+ struct clk *xo_clk; -+ struct clk *ref_clk; -+}; -+ -+/** -+ * Write register and read back masked value to confirm it is written -+ * -+ * @base - QCOM DWC3 PHY base virtual address. -+ * @offset - register offset. -+ * @mask - register bitmask specifying what should be updated -+ * @val - value to write. -+ */ -+static inline void qcom_dwc3_phy_write_readback( -+ struct qcom_dwc3_usb_phy *phy_dwc3, u32 offset, -+ const u32 mask, u32 val) -+{ -+ u32 write_val, tmp = readl(phy_dwc3->base + offset); -+ -+ tmp &= ~mask; /* retain other bits */ -+ write_val = tmp | val; -+ -+ writel(write_val, phy_dwc3->base + offset); -+ -+ /* Read back to see if val was written */ -+ tmp = readl(phy_dwc3->base + offset); -+ tmp &= mask; /* clear other bits */ -+ -+ if (tmp != val) -+ dev_err(phy_dwc3->dev, "write: %x to QSCRATCH: %x FAILED\n", -+ val, offset); -+} -+ -+static int wait_for_latch(void __iomem *addr) -+{ -+ u32 retry = 10; -+ -+ while (true) { -+ if (!readl(addr)) -+ break; -+ -+ if (--retry == 0) -+ return -ETIMEDOUT; -+ -+ usleep_range(10, 20); -+ } -+ -+ return 0; -+} -+ -+/** -+ * Write SSPHY register -+ * -+ * @base - QCOM DWC3 PHY base virtual address. -+ * @addr - SSPHY address to write. -+ * @val - value to write. -+ */ -+static int qcom_dwc3_ss_write_phycreg(void __iomem *base, u32 addr, u32 val) -+{ -+ int ret; -+ -+ writel(addr, base + CR_PROTOCOL_DATA_IN_REG); -+ writel(0x1, base + CR_PROTOCOL_CAP_ADDR_REG); -+ -+ ret = wait_for_latch(base + CR_PROTOCOL_CAP_ADDR_REG); -+ if (ret) -+ goto err_wait; -+ -+ writel(val, base + CR_PROTOCOL_DATA_IN_REG); -+ writel(0x1, base + CR_PROTOCOL_CAP_DATA_REG); -+ -+ ret = wait_for_latch(base + CR_PROTOCOL_CAP_DATA_REG); -+ if (ret) -+ goto err_wait; -+ -+ writel(0x1, base + CR_PROTOCOL_WRITE_REG); -+ -+ ret = wait_for_latch(base + CR_PROTOCOL_WRITE_REG); -+ -+err_wait: -+ return ret; -+} -+ -+/** -+ * Read SSPHY register. -+ * -+ * @base - QCOM DWC3 PHY base virtual address. -+ * @addr - SSPHY address to read. -+ */ -+static int qcom_dwc3_ss_read_phycreg(void __iomem *base, u32 addr, u32 *val) -+{ -+ int ret; -+ bool first_read = true; -+ -+ writel(addr, base + CR_PROTOCOL_DATA_IN_REG); -+ writel(0x1, base + CR_PROTOCOL_CAP_ADDR_REG); -+ -+ ret = wait_for_latch(base + CR_PROTOCOL_CAP_ADDR_REG); -+ if (ret) -+ goto err_wait; -+ -+ /* -+ * Due to hardware bug, first read of SSPHY register might be -+ * incorrect. Hence as workaround, SW should perform SSPHY register -+ * read twice, but use only second read and ignore first read. -+ */ -+retry: -+ writel(0x1, base + CR_PROTOCOL_READ_REG); -+ -+ ret = wait_for_latch(base + CR_PROTOCOL_READ_REG); -+ if (ret) -+ goto err_wait; -+ -+ if (first_read) { -+ readl(base + CR_PROTOCOL_DATA_OUT_REG); -+ first_read = false; -+ goto retry; -+ } -+ -+ *val = readl(base + CR_PROTOCOL_DATA_OUT_REG); -+ -+err_wait: -+ return ret; -+} -+ -+static int qcom_dwc3_phy_power_on(struct phy *phy) -+{ -+ int ret; -+ struct qcom_dwc3_usb_phy *phy_dwc3 = phy_get_drvdata(phy); -+ -+ ret = clk_prepare_enable(phy_dwc3->xo_clk); -+ if (ret) -+ return ret; -+ -+ ret = clk_prepare_enable(phy_dwc3->ref_clk); -+ if (ret) -+ clk_disable_unprepare(phy_dwc3->xo_clk); -+ -+ return ret; -+} -+ -+static int qcom_dwc3_phy_power_off(struct phy *phy) -+{ -+ struct qcom_dwc3_usb_phy *phy_dwc3 = phy_get_drvdata(phy); -+ -+ clk_disable_unprepare(phy_dwc3->ref_clk); -+ clk_disable_unprepare(phy_dwc3->xo_clk); -+ -+ return 0; -+} -+ -+static int qcom_dwc3_hs_phy_init(struct qcom_dwc3_usb_phy *phy_dwc3) -+{ -+ u32 val; -+ -+ /* -+ * HSPHY Initialization: Enable UTMI clock, select 19.2MHz fsel -+ * enable clamping, and disable RETENTION (power-on default is ENABLED) -+ */ -+ val = HSUSB_CTRL_DPSEHV_CLAMP | HSUSB_CTRL_DMSEHV_CLAMP | -+ HSUSB_CTRL_RETENABLEN | HSUSB_CTRL_COMMONONN | -+ HSUSB_CTRL_OTGSESSVLD_CLAMP | HSUSB_CTRL_ID_HV_CLAMP | -+ HSUSB_CTRL_DPSEHV_CLAMP | HSUSB_CTRL_UTMI_OTG_VBUS_VALID | -+ HSUSB_CTRL_UTMI_CLK_EN | HSUSB_CTRL_CLAMP_EN | 0x70; -+ -+ /* use core clock if external reference is not present */ -+ if (!phy_dwc3->xo_clk) -+ val |= HSUSB_CTRL_USE_CLKCORE; -+ -+ writel(val, phy_dwc3->base + HSUSB_PHY_CTRL_REG); -+ usleep_range(2000, 2200); -+ -+ /* Disable (bypass) VBUS and ID filters */ -+ writel(HSUSB_GCFG_XHCI_REV, phy_dwc3->base + QSCRATCH_GENERAL_CFG); -+ -+ return 0; -+} -+ -+static int qcom_dwc3_ss_phy_init(struct qcom_dwc3_usb_phy *phy_dwc3) -+{ -+ int ret; -+ u32 data = 0; -+ -+ /* reset phy */ -+ data = readl_relaxed(phy_dwc3->base + SSUSB_PHY_CTRL_REG); -+ writel_relaxed(data | SSUSB_CTRL_SS_PHY_RESET, -+ phy_dwc3->base + SSUSB_PHY_CTRL_REG); -+ usleep_range(2000, 2200); -+ writel_relaxed(data, phy_dwc3->base + SSUSB_PHY_CTRL_REG); -+ -+ /* clear REF_PAD if we don't have XO clk */ -+ if (!phy_dwc3->xo_clk) -+ data &= ~SSUSB_CTRL_REF_USE_PAD; -+ else -+ data |= SSUSB_CTRL_REF_USE_PAD; -+ -+ writel_relaxed(data, phy_dwc3->base + SSUSB_PHY_CTRL_REG); -+ msleep(30); -+ -+ data |= SSUSB_CTRL_SS_PHY_EN | SSUSB_CTRL_LANE0_PWR_PRESENT; -+ writel_relaxed(data, phy_dwc3->base + SSUSB_PHY_CTRL_REG); -+ -+ /* -+ * Fix RX Equalization setting as follows -+ * LANE0.RX_OVRD_IN_HI. RX_EQ_EN set to 0 -+ * LANE0.RX_OVRD_IN_HI.RX_EQ_EN_OVRD set to 1 -+ * LANE0.RX_OVRD_IN_HI.RX_EQ set to 3 -+ * LANE0.RX_OVRD_IN_HI.RX_EQ_OVRD set to 1 -+ */ -+ ret = qcom_dwc3_ss_read_phycreg(phy_dwc3->base, -+ SSPHY_CTRL_RX_OVRD_IN_HI(0), &data); -+ if (ret) -+ goto err_phy_trans; -+ -+ data &= ~RX_OVRD_IN_HI_RX_EQ_EN; -+ data |= RX_OVRD_IN_HI_RX_EQ_EN_OVRD; -+ data &= ~RX_OVRD_IN_HI_RX_EQ_MASK; -+ data |= 0x3 << RX_OVRD_IN_HI_RX_EQ_SHIFT; -+ data |= RX_OVRD_IN_HI_RX_EQ_OVRD; -+ ret = qcom_dwc3_ss_write_phycreg(phy_dwc3->base, -+ SSPHY_CTRL_RX_OVRD_IN_HI(0), data); -+ if (ret) -+ goto err_phy_trans; -+ -+ /* -+ * Set EQ and TX launch amplitudes as follows -+ * LANE0.TX_OVRD_DRV_LO.PREEMPH set to 22 -+ * LANE0.TX_OVRD_DRV_LO.AMPLITUDE set to 127 -+ * LANE0.TX_OVRD_DRV_LO.EN set to 1. -+ */ -+ ret = qcom_dwc3_ss_read_phycreg(phy_dwc3->base, -+ SSPHY_CTRL_TX_OVRD_DRV_LO(0), &data); -+ if (ret) -+ goto err_phy_trans; -+ -+ data &= ~TX_OVRD_DRV_LO_PREEMPH_MASK; -+ data |= 0x16 << TX_OVRD_DRV_LO_PREEMPH_SHIFT; -+ data &= ~TX_OVRD_DRV_LO_AMPLITUDE_MASK; -+ data |= 0x7f; -+ data |= TX_OVRD_DRV_LO_EN; -+ ret = qcom_dwc3_ss_write_phycreg(phy_dwc3->base, -+ SSPHY_CTRL_TX_OVRD_DRV_LO(0), data); -+ if (ret) -+ goto err_phy_trans; -+ -+ /* -+ * Set the QSCRATCH PHY_PARAM_CTRL1 parameters as follows -+ * TX_FULL_SWING [26:20] amplitude to 127 -+ * TX_DEEMPH_3_5DB [13:8] to 22 -+ * LOS_BIAS [2:0] to 0x5 -+ */ -+ qcom_dwc3_phy_write_readback(phy_dwc3, SSUSB_PHY_PARAM_CTRL_1, -+ 0x07f03f07, 0x07f01605); -+ -+err_phy_trans: -+ return ret; -+} -+ -+static int qcom_dwc3_ss_phy_exit(struct qcom_dwc3_usb_phy *phy_dwc3) -+{ -+ /* Sequence to put SSPHY in low power state: -+ * 1. Clear REF_PHY_EN in PHY_CTRL_REG -+ * 2. Clear REF_USE_PAD in PHY_CTRL_REG -+ * 3. Set TEST_POWERED_DOWN in PHY_CTRL_REG to enable PHY retention -+ * 4. Disable SSPHY ref clk -+ */ -+ qcom_dwc3_phy_write_readback(phy_dwc3, SSUSB_PHY_CTRL_REG, -+ SSUSB_CTRL_SS_PHY_EN, 0x0); -+ qcom_dwc3_phy_write_readback(phy_dwc3, SSUSB_PHY_CTRL_REG, -+ SSUSB_CTRL_REF_USE_PAD, 0x0); -+ qcom_dwc3_phy_write_readback(phy_dwc3, SSUSB_PHY_CTRL_REG, -+ 0x0, SSUSB_CTRL_TEST_POWERDOWN); -+ -+ return 0; -+} -+ -+static int qcom_dwc3_phy_init(struct phy *phy) -+{ -+ struct qcom_dwc3_usb_phy *phy_dwc3 = phy_get_drvdata(phy); -+ -+ if (phy_dwc3->phy_init) -+ return phy_dwc3->phy_init(phy_dwc3); -+ -+ return 0; -+} -+ -+static int qcom_dwc3_phy_exit(struct phy *phy) -+{ -+ struct qcom_dwc3_usb_phy *phy_dwc3 = phy_get_drvdata(phy); -+ -+ if (phy_dwc3->phy_exit) -+ return qcom_dwc3_ss_phy_exit(phy_dwc3); -+ -+ return 0; -+} -+ -+static struct phy_ops qcom_dwc3_phy_ops = { -+ .init = qcom_dwc3_phy_init, -+ .exit = qcom_dwc3_phy_exit, -+ .power_on = qcom_dwc3_phy_power_on, -+ .power_off = qcom_dwc3_phy_power_off, -+ .owner = THIS_MODULE, -+}; -+ -+static const struct of_device_id qcom_dwc3_phy_table[] = { -+ { .compatible = "qcom,dwc3-hs-usb-phy", }, -+ { .compatible = "qcom,dwc3-ss-usb-phy", }, -+ { /* Sentinel */ } -+}; -+MODULE_DEVICE_TABLE(of, qcom_dwc3_phy_table); -+ -+static int qcom_dwc3_phy_probe(struct platform_device *pdev) -+{ -+ struct qcom_dwc3_usb_phy *phy_dwc3; -+ struct phy_provider *phy_provider; -+ struct resource *res; -+ -+ phy_dwc3 = devm_kzalloc(&pdev->dev, sizeof(*phy_dwc3), GFP_KERNEL); -+ if (!phy_dwc3) -+ return -ENOMEM; -+ -+ platform_set_drvdata(pdev, phy_dwc3); -+ -+ phy_dwc3->dev = &pdev->dev; -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ phy_dwc3->base = devm_ioremap_resource(phy_dwc3->dev, res); -+ if (IS_ERR(phy_dwc3->base)) -+ return PTR_ERR(phy_dwc3->base); -+ -+ phy_dwc3->ref_clk = devm_clk_get(phy_dwc3->dev, "ref"); -+ if (IS_ERR(phy_dwc3->ref_clk)) { -+ dev_dbg(phy_dwc3->dev, "cannot get reference clock\n"); -+ return PTR_ERR(phy_dwc3->ref_clk); -+ } -+ -+ if (of_device_is_compatible(pdev->dev.of_node, -+ "qcom,dwc3-hs-usb-phy")) { -+ clk_set_rate(phy_dwc3->ref_clk, 60000000); -+ phy_dwc3->phy_init = qcom_dwc3_hs_phy_init; -+ } else if (of_device_is_compatible(pdev->dev.of_node, -+ "qcom,dwc3-ss-usb-phy")) { -+ phy_dwc3->phy_init = qcom_dwc3_ss_phy_init; -+ phy_dwc3->phy_exit = qcom_dwc3_ss_phy_exit; -+ clk_set_rate(phy_dwc3->ref_clk, 125000000); -+ } else { -+ dev_err(phy_dwc3->dev, "Unknown phy\n"); -+ return -EINVAL; -+ } -+ -+ phy_dwc3->xo_clk = devm_clk_get(phy_dwc3->dev, "xo"); -+ if (IS_ERR(phy_dwc3->xo_clk)) { -+ dev_dbg(phy_dwc3->dev, "cannot get TCXO clock\n"); -+ phy_dwc3->xo_clk = NULL; -+ } -+ -+ phy_dwc3->phy = devm_phy_create(phy_dwc3->dev, NULL, &qcom_dwc3_phy_ops, -+ NULL); -+ -+ if (IS_ERR(phy_dwc3->phy)) -+ return PTR_ERR(phy_dwc3->phy); -+ -+ phy_set_drvdata(phy_dwc3->phy, phy_dwc3); -+ -+ phy_provider = devm_of_phy_provider_register(phy_dwc3->dev, -+ of_phy_simple_xlate); -+ -+ if (IS_ERR(phy_provider)) -+ return PTR_ERR(phy_provider); -+ -+ return 0; -+} -+ -+static struct platform_driver qcom_dwc3_phy_driver = { -+ .probe = qcom_dwc3_phy_probe, -+ .driver = { -+ .name = "qcom-dwc3-usb-phy", -+ .owner = THIS_MODULE, -+ .of_match_table = qcom_dwc3_phy_table, -+ }, -+}; -+ -+module_platform_driver(qcom_dwc3_phy_driver); -+ -+MODULE_ALIAS("platform:phy-qcom-dwc3"); -+MODULE_LICENSE("GPL v2"); -+MODULE_AUTHOR("Andy Gross "); -+MODULE_AUTHOR("Ivan T. Ivanov "); -+MODULE_DESCRIPTION("DesignWare USB3 QCOM PHY driver"); diff --git a/target/linux/ipq806x/patches-3.18/101-ARM-qcom-add-USB-nodes-to-ipq806x-ap148.patch b/target/linux/ipq806x/patches-3.18/101-ARM-qcom-add-USB-nodes-to-ipq806x-ap148.patch deleted file mode 100644 index 8f17397380..0000000000 --- a/target/linux/ipq806x/patches-3.18/101-ARM-qcom-add-USB-nodes-to-ipq806x-ap148.patch +++ /dev/null @@ -1,125 +0,0 @@ ---- a/arch/arm/boot/dts/qcom-ipq8064-ap148.dts -+++ b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts -@@ -109,5 +109,29 @@ - sata@29000000 { - status = "ok"; - }; -+ -+ phy@100f8800 { /* USB3 port 1 HS phy */ -+ status = "ok"; -+ }; -+ -+ phy@100f8830 { /* USB3 port 1 SS phy */ -+ status = "ok"; -+ }; -+ -+ phy@110f8800 { /* USB3 port 0 HS phy */ -+ status = "ok"; -+ }; -+ -+ phy@110f8830 { /* USB3 port 0 SS phy */ -+ status = "ok"; -+ }; -+ -+ usb30@0 { -+ status = "ok"; -+ }; -+ -+ usb30@1 { -+ status = "ok"; -+ }; - }; - }; ---- a/arch/arm/boot/dts/qcom-ipq8064.dtsi -+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi -@@ -291,5 +291,90 @@ - #clock-cells = <1>; - #reset-cells = <1>; - }; -+ -+ hs_phy_1: phy@100f8800 { -+ compatible = "qcom,dwc3-hs-usb-phy"; -+ reg = <0x100f8800 0x30>; -+ clocks = <&gcc USB30_1_UTMI_CLK>; -+ clock-names = "ref"; -+ #phy-cells = <0>; -+ -+ status = "disabled"; -+ }; -+ -+ ss_phy_1: phy@100f8830 { -+ compatible = "qcom,dwc3-ss-usb-phy"; -+ reg = <0x100f8830 0x30>; -+ clocks = <&gcc USB30_1_MASTER_CLK>; -+ clock-names = "ref"; -+ #phy-cells = <0>; -+ -+ status = "disabled"; -+ }; -+ -+ hs_phy_0: phy@110f8800 { -+ compatible = "qcom,dwc3-hs-usb-phy"; -+ reg = <0x110f8800 0x30>; -+ clocks = <&gcc USB30_0_UTMI_CLK>; -+ clock-names = "ref"; -+ #phy-cells = <0>; -+ -+ status = "disabled"; -+ }; -+ -+ ss_phy_0: phy@110f8830 { -+ compatible = "qcom,dwc3-ss-usb-phy"; -+ reg = <0x110f8830 0x30>; -+ clocks = <&gcc USB30_0_MASTER_CLK>; -+ clock-names = "ref"; -+ #phy-cells = <0>; -+ -+ status = "disabled"; -+ }; -+ -+ usb3_0: usb30@0 { -+ compatible = "qcom,dwc3"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ clocks = <&gcc USB30_0_MASTER_CLK>; -+ clock-names = "core"; -+ -+ ranges; -+ -+ status = "disabled"; -+ -+ dwc3@11000000 { -+ compatible = "snps,dwc3"; -+ reg = <0x11000000 0xcd00>; -+ interrupts = <0 110 0x4>; -+ phys = <&hs_phy_0>, <&ss_phy_0>; -+ phy-names = "usb2-phy", "usb3-phy"; -+ tx-fifo-resize; -+ dr_mode = "host"; -+ }; -+ }; -+ -+ usb3_1: usb30@1 { -+ compatible = "qcom,dwc3"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ clocks = <&gcc USB30_1_MASTER_CLK>; -+ clock-names = "core"; -+ -+ ranges; -+ -+ status = "disabled"; -+ -+ dwc3@10000000 { -+ compatible = "snps,dwc3"; -+ reg = <0x10000000 0xcd00>; -+ interrupts = <0 205 0x4>; -+ phys = <&hs_phy_1>, <&ss_phy_1>; -+ phy-names = "usb2-phy", "usb3-phy"; -+ tx-fifo-resize; -+ dr_mode = "host"; -+ }; -+ }; -+ - }; - }; diff --git a/target/linux/ipq806x/patches-3.18/102-soc-qcom-gsbi-Add-support-for-ADM-CRCI-muxing.patch b/target/linux/ipq806x/patches-3.18/102-soc-qcom-gsbi-Add-support-for-ADM-CRCI-muxing.patch deleted file mode 100644 index 752f3f74d5..0000000000 --- a/target/linux/ipq806x/patches-3.18/102-soc-qcom-gsbi-Add-support-for-ADM-CRCI-muxing.patch +++ /dev/null @@ -1,249 +0,0 @@ ---- a/Documentation/devicetree/bindings/soc/qcom/qcom,gsbi.txt -+++ b/Documentation/devicetree/bindings/soc/qcom/qcom,gsbi.txt -@@ -6,7 +6,8 @@ configuration settings. The mode settin - the 4 GSBI IOs. - - Required properties: --- compatible: must contain "qcom,gsbi-v1.0.0" for APQ8064/IPQ8064 -+- compatible: Should contain "qcom,gsbi-v1.0.0" -+- cell-index: Should contain the GSBI index - - reg: Address range for GSBI registers - - clocks: required clock - - clock-names: must contain "iface" entry -@@ -16,6 +17,8 @@ Required properties: - Optional properties: - - qcom,crci : indicates CRCI MUX value for QUP CRCI ports. Please reference - dt-bindings/soc/qcom,gsbi.h for valid CRCI mux values. -+- syscon-tcsr: indicates phandle of TCSR syscon node. Required if child uses -+ dma. - - Required properties if child node exists: - - #address-cells: Must be 1 -@@ -39,6 +42,7 @@ Example for APQ8064: - - gsbi4@16300000 { - compatible = "qcom,gsbi-v1.0.0"; -+ cell-index = <4>; - reg = <0x16300000 0x100>; - clocks = <&gcc GSBI4_H_CLK>; - clock-names = "iface"; -@@ -48,6 +52,8 @@ Example for APQ8064: - qcom,mode = ; - qcom,crci = ; - -+ syscon-tcsr = <&tcsr>; -+ - /* child nodes go under here */ - - i2c_qup4: i2c@16380000 { -@@ -76,3 +82,9 @@ Example for APQ8064: - }; - }; - -+ tcsr: syscon@1a400000 { -+ compatible = "qcom,apq8064-tcsr", "syscon"; -+ reg = <0x1a400000 0x100>; -+ }; -+ -+ ---- a/drivers/soc/qcom/Kconfig -+++ b/drivers/soc/qcom/Kconfig -@@ -4,6 +4,7 @@ - config QCOM_GSBI - tristate "QCOM General Serial Bus Interface" - depends on ARCH_QCOM -+ select MFD_SYSCON - help - Say y here to enable GSBI support. The GSBI provides control - functions for connecting the underlying serial UART, SPI, and I2C ---- a/drivers/soc/qcom/qcom_gsbi.c -+++ b/drivers/soc/qcom/qcom_gsbi.c -@@ -18,22 +18,129 @@ - #include - #include - #include -+#include -+#include -+#include - - #define GSBI_CTRL_REG 0x0000 - #define GSBI_PROTOCOL_SHIFT 4 -+#define MAX_GSBI 12 -+ -+#define TCSR_ADM_CRCI_BASE 0x70 -+ -+struct crci_config { -+ u32 num_rows; -+ const u32 (*array)[MAX_GSBI]; -+}; -+ -+static const u32 crci_ipq8064[][MAX_GSBI] = { -+ { -+ 0x000003, 0x00000c, 0x000030, 0x0000c0, -+ 0x000300, 0x000c00, 0x003000, 0x00c000, -+ 0x030000, 0x0c0000, 0x300000, 0xc00000 -+ }, -+ { -+ 0x000003, 0x00000c, 0x000030, 0x0000c0, -+ 0x000300, 0x000c00, 0x003000, 0x00c000, -+ 0x030000, 0x0c0000, 0x300000, 0xc00000 -+ }, -+}; -+ -+static const struct crci_config config_ipq8064 = { -+ .num_rows = ARRAY_SIZE(crci_ipq8064), -+ .array = crci_ipq8064, -+}; -+ -+static const unsigned int crci_apq8064[][MAX_GSBI] = { -+ { -+ 0x001800, 0x006000, 0x000030, 0x0000c0, -+ 0x000300, 0x000400, 0x000000, 0x000000, -+ 0x000000, 0x000000, 0x000000, 0x000000 -+ }, -+ { -+ 0x000000, 0x000000, 0x000000, 0x000000, -+ 0x000000, 0x000020, 0x0000c0, 0x000000, -+ 0x000000, 0x000000, 0x000000, 0x000000 -+ }, -+}; -+ -+static const struct crci_config config_apq8064 = { -+ .num_rows = ARRAY_SIZE(crci_apq8064), -+ .array = crci_apq8064, -+}; -+ -+static const unsigned int crci_msm8960[][MAX_GSBI] = { -+ { -+ 0x000003, 0x00000c, 0x000030, 0x0000c0, -+ 0x000300, 0x000400, 0x000000, 0x000000, -+ 0x000000, 0x000000, 0x000000, 0x000000 -+ }, -+ { -+ 0x000000, 0x000000, 0x000000, 0x000000, -+ 0x000000, 0x000020, 0x0000c0, 0x000300, -+ 0x001800, 0x006000, 0x000000, 0x000000 -+ }, -+}; -+ -+static const struct crci_config config_msm8960 = { -+ .num_rows = ARRAY_SIZE(crci_msm8960), -+ .array = crci_msm8960, -+}; -+ -+static const unsigned int crci_msm8660[][MAX_GSBI] = { -+ { /* ADM 0 - B */ -+ 0x000003, 0x00000c, 0x000030, 0x0000c0, -+ 0x000300, 0x000c00, 0x003000, 0x00c000, -+ 0x030000, 0x0c0000, 0x300000, 0xc00000 -+ }, -+ { /* ADM 0 - B */ -+ 0x000003, 0x00000c, 0x000030, 0x0000c0, -+ 0x000300, 0x000c00, 0x003000, 0x00c000, -+ 0x030000, 0x0c0000, 0x300000, 0xc00000 -+ }, -+ { /* ADM 1 - A */ -+ 0x000003, 0x00000c, 0x000030, 0x0000c0, -+ 0x000300, 0x000c00, 0x003000, 0x00c000, -+ 0x030000, 0x0c0000, 0x300000, 0xc00000 -+ }, -+ { /* ADM 1 - B */ -+ 0x000003, 0x00000c, 0x000030, 0x0000c0, -+ 0x000300, 0x000c00, 0x003000, 0x00c000, -+ 0x030000, 0x0c0000, 0x300000, 0xc00000 -+ }, -+}; -+ -+static const struct crci_config config_msm8660 = { -+ .num_rows = ARRAY_SIZE(crci_msm8660), -+ .array = crci_msm8660, -+}; - - struct gsbi_info { - struct clk *hclk; - u32 mode; - u32 crci; -+ struct regmap *tcsr; -+}; -+ -+static const struct of_device_id tcsr_dt_match[] = { -+ { .compatible = "qcom,tcsr-ipq8064", .data = &config_ipq8064}, -+ { .compatible = "qcom,tcsr-apq8064", .data = &config_apq8064}, -+ { .compatible = "qcom,tcsr-msm8960", .data = &config_msm8960}, -+ { .compatible = "qcom,tcsr-msm8660", .data = &config_msm8660}, -+ { }, - }; - - static int gsbi_probe(struct platform_device *pdev) - { - struct device_node *node = pdev->dev.of_node; -+ struct device_node *tcsr_node; -+ const struct of_device_id *match; - struct resource *res; - void __iomem *base; - struct gsbi_info *gsbi; -+ int i; -+ u32 mask, gsbi_num; -+ const struct crci_config *config = NULL; - - gsbi = devm_kzalloc(&pdev->dev, sizeof(*gsbi), GFP_KERNEL); - -@@ -45,6 +152,32 @@ static int gsbi_probe(struct platform_de - if (IS_ERR(base)) - return PTR_ERR(base); - -+ /* get the tcsr node and setup the config and regmap */ -+ gsbi->tcsr = syscon_regmap_lookup_by_phandle(node, "syscon-tcsr"); -+ -+ if (!IS_ERR(gsbi->tcsr)) { -+ tcsr_node = of_parse_phandle(node, "syscon-tcsr", 0); -+ if (tcsr_node) { -+ match = of_match_node(tcsr_dt_match, tcsr_node); -+ if (match) -+ config = match->data; -+ else -+ dev_warn(&pdev->dev, "no matching TCSR\n"); -+ -+ of_node_put(tcsr_node); -+ } -+ } -+ -+ if (of_property_read_u32(node, "cell-index", &gsbi_num)) { -+ dev_err(&pdev->dev, "missing cell-index\n"); -+ return -EINVAL; -+ } -+ -+ if (gsbi_num < 1 || gsbi_num > MAX_GSBI) { -+ dev_err(&pdev->dev, "invalid cell-index\n"); -+ return -EINVAL; -+ } -+ - if (of_property_read_u32(node, "qcom,mode", &gsbi->mode)) { - dev_err(&pdev->dev, "missing mode configuration\n"); - return -EINVAL; -@@ -64,6 +197,25 @@ static int gsbi_probe(struct platform_de - writel_relaxed((gsbi->mode << GSBI_PROTOCOL_SHIFT) | gsbi->crci, - base + GSBI_CTRL_REG); - -+ /* -+ * modify tcsr to reflect mode and ADM CRCI mux -+ * Each gsbi contains a pair of bits, one for RX and one for TX -+ * SPI mode requires both bits cleared, otherwise they are set -+ */ -+ if (config) { -+ for (i = 0; i < config->num_rows; i++) { -+ mask = config->array[i][gsbi_num - 1]; -+ -+ if (gsbi->mode == GSBI_PROT_SPI) -+ regmap_update_bits(gsbi->tcsr, -+ TCSR_ADM_CRCI_BASE + 4 * i, mask, 0); -+ else -+ regmap_update_bits(gsbi->tcsr, -+ TCSR_ADM_CRCI_BASE + 4 * i, mask, mask); -+ -+ } -+ } -+ - /* make sure the gsbi control write is not reordered */ - wmb(); - diff --git a/target/linux/ipq806x/patches-3.18/103-ARM-DT-ipq8064-Add-TCSR-support.patch b/target/linux/ipq806x/patches-3.18/103-ARM-DT-ipq8064-Add-TCSR-support.patch deleted file mode 100644 index 322e1d9237..0000000000 --- a/target/linux/ipq806x/patches-3.18/103-ARM-DT-ipq8064-Add-TCSR-support.patch +++ /dev/null @@ -1,65 +0,0 @@ ---- a/arch/arm/boot/dts/qcom-ipq8064.dtsi -+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi -@@ -132,6 +132,7 @@ - - gsbi2: gsbi@12480000 { - compatible = "qcom,gsbi-v1.0.0"; -+ cell-index = <2>; - reg = <0x12480000 0x100>; - clocks = <&gcc GSBI2_H_CLK>; - clock-names = "iface"; -@@ -140,6 +141,8 @@ - ranges; - status = "disabled"; - -+ syscon-tcsr = <&tcsr>; -+ - uart2: serial@12490000 { - compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm"; - reg = <0x12490000 0x1000>, -@@ -167,6 +170,7 @@ - - gsbi4: gsbi@16300000 { - compatible = "qcom,gsbi-v1.0.0"; -+ cell-index = <4>; - reg = <0x16300000 0x100>; - clocks = <&gcc GSBI4_H_CLK>; - clock-names = "iface"; -@@ -175,6 +179,8 @@ - ranges; - status = "disabled"; - -+ syscon-tcsr = <&tcsr>; -+ - uart4: serial@16340000 { - compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm"; - reg = <0x16340000 0x1000>, -@@ -201,6 +207,7 @@ - - gsbi5: gsbi@1a200000 { - compatible = "qcom,gsbi-v1.0.0"; -+ cell-index = <5>; - reg = <0x1a200000 0x100>; - clocks = <&gcc GSBI5_H_CLK>; - clock-names = "iface"; -@@ -209,6 +216,8 @@ - ranges; - status = "disabled"; - -+ syscon-tcsr = <&tcsr>; -+ - uart5: serial@1a240000 { - compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm"; - reg = <0x1a240000 0x1000>, -@@ -279,6 +288,11 @@ - status = "disabled"; - }; - -+ tcsr: syscon@1a400000 { -+ compatible = "qcom,tcsr-ipq8064", "syscon"; -+ reg = <0x1a400000 0x100>; -+ }; -+ - qcom,ssbi@500000 { - compatible = "qcom,ssbi"; - reg = <0x00500000 0x1000>; diff --git a/target/linux/ipq806x/patches-3.18/110-DT-PCI-qcom-Document-PCIe-devicetree-bindings.patch b/target/linux/ipq806x/patches-3.18/110-DT-PCI-qcom-Document-PCIe-devicetree-bindings.patch deleted file mode 100644 index 41f91fae7c..0000000000 --- a/target/linux/ipq806x/patches-3.18/110-DT-PCI-qcom-Document-PCIe-devicetree-bindings.patch +++ /dev/null @@ -1,263 +0,0 @@ -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [v2,3/5] DT: PCI: qcom: Document PCIe devicetree bindings -From: Stanimir Varbanov -X-Patchwork-Id: 6326181 -Message-Id: <1430743338-10441-4-git-send-email-svarbanov@mm-sol.com> -To: Rob Herring , Kumar Gala , - Mark Rutland , - Grant Likely , - Bjorn Helgaas , - Kishon Vijay Abraham I , - Russell King , Arnd Bergmann -Cc: linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, - linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org, - linux-pci@vger.kernel.org, Mathieu Olivari , - Srinivas Kandagatla , - Stanimir Varbanov -Date: Mon, 4 May 2015 15:42:16 +0300 - -Document Qualcomm PCIe driver devicetree bindings. - -Signed-off-by: Stanimir Varbanov - ---- -.../devicetree/bindings/pci/qcom,pcie.txt | 231 ++++++++++++++++++++ - 1 files changed, 231 insertions(+), 0 deletions(-) - create mode 100644 Documentation/devicetree/bindings/pci/qcom,pcie.txt - ---- /dev/null -+++ b/Documentation/devicetree/bindings/pci/qcom,pcie.txt -@@ -0,0 +1,231 @@ -+* Qualcomm PCI express root complex -+ -+- compatible: -+ Usage: required -+ Value type: -+ Definition: Value shall include -+ - "qcom,pcie-v0" for apq/ipq8064 -+ - "qcom,pcie-v1" for apq8084 -+ -+- reg: -+ Usage: required -+ Value type: -+ Definition: Register ranges as listed in the reg-names property -+ -+- reg-names: -+ Usage: required -+ Value type: -+ Definition: Must include the following entries -+ - "parf" Qualcomm specific registers -+ - "dbi" Designware PCIe registers -+ - "elbi" External local bus interface registers -+ - "config" PCIe configuration space -+ -+- device_type: -+ Usage: required -+ Value type: -+ Definition: Should be "pci". As specified in designware-pcie.txt -+ -+- #address-cells: -+ Usage: required -+ Value type: -+ Definition: Should be set to 3. As specified in designware-pcie.txt -+ -+- #size-cells: -+ Usage: required -+ Value type: -+ Definition: Should be set 2. As specified in designware-pcie.txt -+ -+- ranges: -+ Usage: required -+ Value type: -+ Definition: As specified in designware-pcie.txt -+ -+- interrupts: -+ Usage: required -+ Value type: -+ Definition: MSI interrupt -+ -+- interrupt-names: -+ Usage: required -+ Value type: -+ Definition: Should contain "msi" -+ -+- #interrupt-cells: -+ Usage: required -+ Value type: -+ Definition: Should be 1. As specified in designware-pcie.txt -+ -+- interrupt-map-mask: -+ Usage: required -+ Value type: -+ Definition: As specified in designware-pcie.txt -+ -+- interrupt-map: -+ Usage: required -+ Value type: -+ Definition: As specified in designware-pcie.txt -+ -+- clocks: -+ Usage: required -+ Value type: -+ Definition: List of phandle and clock specifier pairs as listed -+ in clock-names property -+ -+- clock-names: -+ Usage: required -+ Value type: -+ Definition: Should contain the following entries -+ * should be populated for v0 and v1 -+ - "iface" Configuration AHB clock -+ -+ * should be populated for v0 -+ - "core" Clocks the pcie hw block -+ - "phy" Clocks the pcie PHY block -+ -+ * should be populated for v1 -+ - "aux" Auxiliary (AUX) clock -+ - "bus_master" Master AXI clock -+ - "bus_slave" Slave AXI clock -+ -+- resets: -+ Usage: required -+ Value type: -+ Definition: List of phandle and reset specifier pairs as listed -+ in reset-names property -+ -+- reset-names: -+ Usage: required -+ Value type: -+ Definition: Should contain the following entries -+ * should be populated for v0 -+ - "axi" AXI reset -+ - "ahb" AHB reset -+ - "por" POR reset -+ - "pci" PCI reset -+ - "phy" PHY reset -+ -+ * should be populated for v1 -+ - "core" Core reset -+ -+- power-domains: -+ Usage: required (for v1 only) -+ Value type: -+ Definition: A phandle and power domain specifier pair to the -+ power domain which is responsible for collapsing -+ and restoring power to the peripheral -+ -+- -supply: -+ Usage: required -+ Value type: -+ Definition: List of phandles to the power supply regulator(s) -+ * should be populated for v0 and v1 -+ - "vdda" core analog power supply -+ -+ * should be populated for v0 -+ - "vdda_phy" analog power supply for PHY -+ - "vdda_refclk" analog power supply for IC which generate -+ reference clock -+ -+- phys: -+ Usage: required (for v1 only) -+ Value type: -+ Definition: List of phandle(s) as listed in phy-names property -+ -+- phy-names: -+ Usage: required (for v1 only) -+ Value type: -+ Definition: Should contain "pciephy" -+ -+- -gpio: -+ Usage: optional -+ Value type: -+ Definition: List of phandle and gpio specifier pairs. Should contain -+ - "perst" PCIe endpoint reset signal line -+ - "pewake" PCIe endpoint wake signal line -+ -+- pinctrl-0: -+ Usage: required -+ Value type: -+ Definition: List of phandles pointing at a pin(s) configuration -+ -+- pinctrl-names -+ Usage: required -+ Value type: -+ Definition: List of names of pinctrl-0 state -+ -+* Example for v0 -+ pcie0: pci@1b500000 { -+ compatible = "qcom,pcie-v0"; -+ reg = <0x1b500000 0x1000 -+ 0x1b502000 0x80 -+ 0x1b600000 0x100 -+ 0x0ff00000 0x100000>; -+ reg-names = "dbi", "elbi", "parf", "config"; -+ device_type = "pci"; -+ linux,pci-domain = <0>; -+ bus-range = <0x00 0xff>; -+ num-lanes = <1>; -+ #address-cells = <3>; -+ #size-cells = <2>; -+ ranges = <0x81000000 0 0 0x0fe00000 0 0x00100000 /* I/O */ -+ 0x82000000 0 0x00000000 0x08000000 0 0x07e00000>; /* memory */ -+ interrupts = ; -+ interrupt-names = "msi"; -+ #interrupt-cells = <1>; -+ interrupt-map-mask = <0 0 0 0x7>; -+ interrupt-map = <0 0 0 1 &intc 0 36 IRQ_TYPE_LEVEL_HIGH>, /* int_a */ -+ <0 0 0 2 &intc 0 37 IRQ_TYPE_LEVEL_HIGH>, /* int_b */ -+ <0 0 0 3 &intc 0 38 IRQ_TYPE_LEVEL_HIGH>, /* int_c */ -+ <0 0 0 4 &intc 0 39 IRQ_TYPE_LEVEL_HIGH>; /* int_d */ -+ clocks = <&gcc PCIE_A_CLK>, -+ <&gcc PCIE_H_CLK>, -+ <&gcc PCIE_PHY_CLK>; -+ clock-names = "core", "iface", "phy"; -+ resets = <&gcc PCIE_ACLK_RESET>, -+ <&gcc PCIE_HCLK_RESET>, -+ <&gcc PCIE_POR_RESET>, -+ <&gcc PCIE_PCI_RESET>, -+ <&gcc PCIE_PHY_RESET>; -+ reset-names = "axi", "ahb", "por", "pci", "phy"; -+ }; -+ -+* Example for v1 -+ pcie0@fc520000 { -+ compatible = "qcom,pcie-v1"; -+ reg = <0xfc520000 0x2000>, -+ <0xff000000 0x1000>, -+ <0xff001000 0x1000>, -+ <0xff002000 0x2000>; -+ reg-names = "parf", "dbi", "elbi", "config"; -+ device_type = "pci"; -+ linux,pci-domain = <0>; -+ bus-range = <0x00 0xff>; -+ num-lanes = <1>; -+ #address-cells = <3>; -+ #size-cells = <2>; -+ ranges = <0x81000000 0 0 0xff200000 0 0x00100000 /* I/O */ -+ 0x82000000 0 0x00300000 0xff300000 0 0x00d00000>; /* memory */ -+ interrupts = ; -+ interrupt-names = "msi"; -+ #interrupt-cells = <1>; -+ interrupt-map-mask = <0 0 0 0x7>; -+ interrupt-map = <0 0 0 1 &intc 0 244 IRQ_TYPE_LEVEL_HIGH>, /* int_a */ -+ <0 0 0 2 &intc 0 245 IRQ_TYPE_LEVEL_HIGH>, /* int_b */ -+ <0 0 0 3 &intc 0 247 IRQ_TYPE_LEVEL_HIGH>, /* int_c */ -+ <0 0 0 4 &intc 0 248 IRQ_TYPE_LEVEL_HIGH>; /* int_d */ -+ clocks = <&gcc GCC_PCIE_0_CFG_AHB_CLK>, -+ <&gcc GCC_PCIE_0_MSTR_AXI_CLK>, -+ <&gcc GCC_PCIE_0_SLV_AXI_CLK>, -+ <&gcc GCC_PCIE_0_AUX_CLK>; -+ clock-names = "iface", "master_bus", "slave_bus", "aux"; -+ resets = <&gcc GCC_PCIE_0_BCR>; -+ reset-names = "core"; -+ power-domains = <&gcc PCIE0_GDSC>; -+ vdda-supply = <&pma8084_l3>; -+ phys = <&pciephy0>; -+ phy-names = "pciephy"; -+ perst-gpio = <&tlmm 70 GPIO_ACTIVE_LOW>; -+ pinctrl-0 = <&pcie0_pins_default>; -+ pinctrl-names = "default"; -+ }; diff --git a/target/linux/ipq806x/patches-3.18/111-PCI-qcom-Add-Qualcomm-PCIe-controller-driver.patch b/target/linux/ipq806x/patches-3.18/111-PCI-qcom-Add-Qualcomm-PCIe-controller-driver.patch deleted file mode 100644 index a0c9c7c36e..0000000000 --- a/target/linux/ipq806x/patches-3.18/111-PCI-qcom-Add-Qualcomm-PCIe-controller-driver.patch +++ /dev/null @@ -1,753 +0,0 @@ -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [v2,4/5] PCI: qcom: Add Qualcomm PCIe controller driver -From: Stanimir Varbanov -X-Patchwork-Id: 6326161 -Message-Id: <1430743338-10441-5-git-send-email-svarbanov@mm-sol.com> -To: Rob Herring , Kumar Gala , - Mark Rutland , - Grant Likely , - Bjorn Helgaas , - Kishon Vijay Abraham I , - Russell King , Arnd Bergmann -Cc: linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, - linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org, - linux-pci@vger.kernel.org, Mathieu Olivari , - Srinivas Kandagatla , - Stanimir Varbanov -Date: Mon, 4 May 2015 15:42:17 +0300 - -The PCIe driver reuse the Designware common code for host -and MSI initialization, and also program the Qualcomm -application specific registers. - -Signed-off-by: Stanimir Varbanov - ---- -MAINTAINERS | 7 + - drivers/pci/host/Kconfig | 9 + - drivers/pci/host/Makefile | 1 + - drivers/pci/host/pcie-qcom.c | 677 ++++++++++++++++++++++++++++++++++++++++++ - 4 files changed, 694 insertions(+), 0 deletions(-) - create mode 100644 drivers/pci/host/pcie-qcom.c - ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -7127,6 +7127,13 @@ L: linux-pci@vger.kernel.org - S: Maintained - F: drivers/pci/host/*spear* - -+PCIE DRIVER FOR QUALCOMM MSM -+M: Stanimir Varbanov -+L: linux-pci@vger.kernel.org -+L: linux-arm-msm@vger.kernel.org -+S: Maintained -+F: drivers/pci/host/*qcom* -+ - PCMCIA SUBSYSTEM - P: Linux PCMCIA Team - L: linux-pcmcia@lists.infradead.org ---- a/drivers/pci/host/Kconfig -+++ b/drivers/pci/host/Kconfig -@@ -91,4 +91,13 @@ config PCI_XGENE - There are 5 internal PCIe ports available. Each port is GEN3 capable - and have varied lanes from x1 to x8. - -+config PCIE_QCOM -+ bool "Qualcomm PCIe controller" -+ depends on ARCH_QCOM && OF || (ARM && COMPILE_TEST) -+ select PCIE_DW -+ select PCIEPORTBUS -+ help -+ Say Y here to enable PCIe controller support on Qualcomm SoCs. The -+ PCIe controller use Designware core plus Qualcomm specific hardware -+ wrappers. - endmenu ---- /dev/null -+++ b/drivers/pci/host/pcie-qcom.c -@@ -0,0 +1,677 @@ -+/* -+ * Copyright (c) 2014, The Linux Foundation. All rights reserved. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 and -+ * only version 2 as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "pcie-designware.h" -+ -+#define PCIE20_PARF_PHY_CTRL 0x40 -+#define PCIE20_PARF_PHY_REFCLK 0x4C -+#define PCIE20_PARF_DBI_BASE_ADDR 0x168 -+#define PCIE20_PARF_SLV_ADDR_SPACE_SIZE 0x16c -+#define PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT 0x178 -+ -+#define PCIE20_ELBI_SYS_CTRL 0x04 -+#define PCIE20_ELBI_SYS_STTS 0x08 -+#define XMLH_LINK_UP BIT(10) -+ -+#define PCIE20_CAP 0x70 -+#define PCIE20_CAP_LINKCTRLSTATUS (PCIE20_CAP + 0x10) -+ -+#define PERST_DELAY_MIN_US 1000 -+#define PERST_DELAY_MAX_US 1005 -+ -+#define LINKUP_DELAY_MIN_US 5000 -+#define LINKUP_DELAY_MAX_US 5100 -+#define LINKUP_RETRIES_COUNT 20 -+ -+#define PCIE_V0 0 /* apq8064 */ -+#define PCIE_V1 1 /* apq8084 */ -+ -+struct qcom_pcie_resources_v0 { -+ struct clk *iface_clk; -+ struct clk *core_clk; -+ struct clk *phy_clk; -+ struct reset_control *pci_reset; -+ struct reset_control *axi_reset; -+ struct reset_control *ahb_reset; -+ struct reset_control *por_reset; -+ struct reset_control *phy_reset; -+ struct regulator *vdda; -+ struct regulator *vdda_phy; -+ struct regulator *vdda_refclk; -+}; -+ -+struct qcom_pcie_resources_v1 { -+ struct clk *iface; -+ struct clk *aux; -+ struct clk *master_bus; -+ struct clk *slave_bus; -+ struct reset_control *core; -+ struct regulator *vdda; -+}; -+ -+union pcie_resources { -+ struct qcom_pcie_resources_v0 v0; -+ struct qcom_pcie_resources_v1 v1; -+}; -+ -+struct qcom_pcie { -+ struct pcie_port pp; -+ struct device *dev; -+ union pcie_resources res; -+ void __iomem *parf; -+ void __iomem *dbi; -+ void __iomem *elbi; -+ struct phy *phy; -+ struct gpio_desc *reset; -+ unsigned int version; -+}; -+ -+#define to_qcom_pcie(x) container_of(x, struct qcom_pcie, pp) -+ -+static inline void -+writel_masked(void __iomem *addr, u32 clear_mask, u32 set_mask) -+{ -+ u32 val = readl(addr); -+ -+ val &= ~clear_mask; -+ val |= set_mask; -+ writel(val, addr); -+} -+ -+static void qcom_ep_reset_assert_deassert(struct qcom_pcie *pcie, int assert) -+{ -+ int val, active_low; -+ -+ if (IS_ERR_OR_NULL(pcie->reset)) -+ return; -+ -+ active_low = gpiod_is_active_low(pcie->reset); -+ -+ if (assert) -+ val = !!active_low; -+ else -+ val = !active_low; -+ -+ gpiod_set_value(pcie->reset, val); -+ -+ usleep_range(PERST_DELAY_MIN_US, PERST_DELAY_MAX_US); -+} -+ -+static void qcom_ep_reset_assert(struct qcom_pcie *pcie) -+{ -+ qcom_ep_reset_assert_deassert(pcie, 1); -+} -+ -+static void qcom_ep_reset_deassert(struct qcom_pcie *pcie) -+{ -+ qcom_ep_reset_assert_deassert(pcie, 0); -+} -+ -+static irqreturn_t qcom_pcie_msi_irq_handler(int irq, void *arg) -+{ -+ struct pcie_port *pp = arg; -+ -+ return dw_handle_msi_irq(pp); -+} -+ -+static int qcom_pcie_link_up(struct pcie_port *pp) -+{ -+ struct qcom_pcie *pcie = to_qcom_pcie(pp); -+ u32 val = readl(pcie->dbi + PCIE20_CAP_LINKCTRLSTATUS); -+ -+ return val & BIT(29) ? 1 : 0; -+} -+ -+static void qcom_pcie_disable_resources_v0(struct qcom_pcie *pcie) -+{ -+ struct qcom_pcie_resources_v0 *res = &pcie->res.v0; -+ -+ reset_control_assert(res->pci_reset); -+ reset_control_assert(res->axi_reset); -+ reset_control_assert(res->ahb_reset); -+ reset_control_assert(res->por_reset); -+ reset_control_assert(res->pci_reset); -+ clk_disable_unprepare(res->iface_clk); -+ clk_disable_unprepare(res->core_clk); -+ clk_disable_unprepare(res->phy_clk); -+ regulator_disable(res->vdda); -+ regulator_disable(res->vdda_phy); -+ regulator_disable(res->vdda_refclk); -+} -+ -+static void qcom_pcie_disable_resources_v1(struct qcom_pcie *pcie) -+{ -+ struct qcom_pcie_resources_v1 *res = &pcie->res.v1; -+ -+ reset_control_assert(res->core); -+ clk_disable_unprepare(res->slave_bus); -+ clk_disable_unprepare(res->master_bus); -+ clk_disable_unprepare(res->iface); -+ clk_disable_unprepare(res->aux); -+ regulator_disable(res->vdda); -+} -+ -+static int qcom_pcie_enable_resources_v0(struct qcom_pcie *pcie) -+{ -+ struct qcom_pcie_resources_v0 *res = &pcie->res.v0; -+ struct device *dev = pcie->dev; -+ int ret; -+ -+ ret = regulator_enable(res->vdda); -+ if (ret) { -+ dev_err(dev, "cannot enable vdda regulator\n"); -+ return ret; -+ } -+ -+ ret = regulator_enable(res->vdda_refclk); -+ if (ret) { -+ dev_err(dev, "cannot enable vdda_refclk regulator\n"); -+ goto err_refclk; -+ } -+ -+ ret = regulator_enable(res->vdda_phy); -+ if (ret) { -+ dev_err(dev, "cannot enable vdda_phy regulator\n"); -+ goto err_vdda_phy; -+ } -+ -+ ret = clk_prepare_enable(res->iface_clk); -+ if (ret) { -+ dev_err(dev, "cannot prepare/enable iface clock\n"); -+ goto err_iface; -+ } -+ -+ ret = clk_prepare_enable(res->core_clk); -+ if (ret) { -+ dev_err(dev, "cannot prepare/enable core clock\n"); -+ goto err_clk_core; -+ } -+ -+ ret = clk_prepare_enable(res->phy_clk); -+ if (ret) { -+ dev_err(dev, "cannot prepare/enable phy clock\n"); -+ goto err_clk_phy; -+ } -+ -+ ret = reset_control_deassert(res->ahb_reset); -+ if (ret) { -+ dev_err(dev, "cannot deassert ahb reset\n"); -+ goto err_reset_ahb; -+ } -+ -+ return 0; -+ -+err_reset_ahb: -+ clk_disable_unprepare(res->phy_clk); -+err_clk_phy: -+ clk_disable_unprepare(res->core_clk); -+err_clk_core: -+ clk_disable_unprepare(res->iface_clk); -+err_iface: -+ regulator_disable(res->vdda_phy); -+err_vdda_phy: -+ regulator_disable(res->vdda_refclk); -+err_refclk: -+ regulator_disable(res->vdda); -+ return ret; -+} -+ -+static int qcom_pcie_enable_resources_v1(struct qcom_pcie *pcie) -+{ -+ struct qcom_pcie_resources_v1 *res = &pcie->res.v1; -+ struct device *dev = pcie->dev; -+ int ret; -+ -+ ret = reset_control_deassert(res->core); -+ if (ret) { -+ dev_err(dev, "cannot deassert core reset\n"); -+ return ret; -+ } -+ -+ ret = clk_prepare_enable(res->aux); -+ if (ret) { -+ dev_err(dev, "cannot prepare/enable aux clock\n"); -+ goto err_res; -+ } -+ -+ ret = clk_prepare_enable(res->iface); -+ if (ret) { -+ dev_err(dev, "cannot prepare/enable iface clock\n"); -+ goto err_aux; -+ } -+ -+ ret = clk_prepare_enable(res->master_bus); -+ if (ret) { -+ dev_err(dev, "cannot prepare/enable master_bus clock\n"); -+ goto err_iface; -+ } -+ -+ ret = clk_prepare_enable(res->slave_bus); -+ if (ret) { -+ dev_err(dev, "cannot prepare/enable slave_bus clock\n"); -+ goto err_master; -+ } -+ -+ ret = regulator_enable(res->vdda); -+ if (ret) { -+ dev_err(dev, "cannot enable vdda regulator\n"); -+ goto err_slave; -+ } -+ -+ return 0; -+ -+err_slave: -+ clk_disable_unprepare(res->slave_bus); -+err_master: -+ clk_disable_unprepare(res->master_bus); -+err_iface: -+ clk_disable_unprepare(res->iface); -+err_aux: -+ clk_disable_unprepare(res->aux); -+err_res: -+ reset_control_assert(res->core); -+ -+ return ret; -+} -+ -+static int qcom_pcie_get_resources_v0(struct qcom_pcie *pcie) -+{ -+ struct qcom_pcie_resources_v0 *res = &pcie->res.v0; -+ struct device *dev = pcie->dev; -+ -+ res->vdda = devm_regulator_get(dev, "vdda"); -+ if (IS_ERR(res->vdda)) -+ return PTR_ERR(res->vdda); -+ -+ res->vdda_phy = devm_regulator_get(dev, "vdda_phy"); -+ if (IS_ERR(res->vdda_phy)) -+ return PTR_ERR(res->vdda_phy); -+ -+ res->vdda_refclk = devm_regulator_get(dev, "vdda_refclk"); -+ if (IS_ERR(res->vdda_refclk)) -+ return PTR_ERR(res->vdda_refclk); -+ -+ res->iface_clk = devm_clk_get(dev, "iface"); -+ if (IS_ERR(res->iface_clk)) -+ return PTR_ERR(res->iface_clk); -+ -+ res->core_clk = devm_clk_get(dev, "core"); -+ if (IS_ERR(res->core_clk)) -+ return PTR_ERR(res->core_clk); -+ -+ res->phy_clk = devm_clk_get(dev, "phy"); -+ if (IS_ERR(res->phy_clk)) -+ return PTR_ERR(res->phy_clk); -+ -+ res->pci_reset = devm_reset_control_get(dev, "pci"); -+ if (IS_ERR(res->pci_reset)) -+ return PTR_ERR(res->pci_reset); -+ -+ res->axi_reset = devm_reset_control_get(dev, "axi"); -+ if (IS_ERR(res->axi_reset)) -+ return PTR_ERR(res->axi_reset); -+ -+ res->ahb_reset = devm_reset_control_get(dev, "ahb"); -+ if (IS_ERR(res->ahb_reset)) -+ return PTR_ERR(res->ahb_reset); -+ -+ res->por_reset = devm_reset_control_get(dev, "por"); -+ if (IS_ERR(res->por_reset)) -+ return PTR_ERR(res->por_reset); -+ -+ res->phy_reset = devm_reset_control_get(dev, "phy"); -+ if (IS_ERR(res->phy_reset)) -+ return PTR_ERR(res->phy_reset); -+ -+ return 0; -+} -+ -+static int qcom_pcie_get_resources_v1(struct qcom_pcie *pcie) -+{ -+ struct qcom_pcie_resources_v1 *res = &pcie->res.v1; -+ struct device *dev = pcie->dev; -+ -+ res->vdda = devm_regulator_get(dev, "vdda"); -+ if (IS_ERR(res->vdda)) -+ return PTR_ERR(res->vdda); -+ -+ res->iface = devm_clk_get(dev, "iface"); -+ if (IS_ERR(res->iface)) -+ return PTR_ERR(res->iface); -+ -+ res->aux = devm_clk_get(dev, "aux"); -+ if (IS_ERR(res->aux) && PTR_ERR(res->aux) == -EPROBE_DEFER) -+ return -EPROBE_DEFER; -+ else if (IS_ERR(res->aux)) -+ res->aux = NULL; -+ -+ res->master_bus = devm_clk_get(dev, "master_bus"); -+ if (IS_ERR(res->master_bus)) -+ return PTR_ERR(res->master_bus); -+ -+ res->slave_bus = devm_clk_get(dev, "slave_bus"); -+ if (IS_ERR(res->slave_bus)) -+ return PTR_ERR(res->slave_bus); -+ -+ res->core = devm_reset_control_get(dev, "core"); -+ if (IS_ERR(res->core)) -+ return PTR_ERR(res->core); -+ -+ return 0; -+} -+ -+static int qcom_pcie_enable_link_training(struct pcie_port *pp) -+{ -+ struct qcom_pcie *pcie = to_qcom_pcie(pp); -+ struct device *dev = pp->dev; -+ int retries; -+ u32 val; -+ -+ /* enable link training */ -+ writel_masked(pcie->elbi + PCIE20_ELBI_SYS_CTRL, 0, BIT(0)); -+ -+ /* wait for up to 100ms for the link to come up */ -+ retries = LINKUP_RETRIES_COUNT; -+ do { -+ val = readl(pcie->elbi + PCIE20_ELBI_SYS_STTS); -+ if (val & XMLH_LINK_UP) -+ break; -+ usleep_range(LINKUP_DELAY_MIN_US, LINKUP_DELAY_MAX_US); -+ } while (retries--); -+ -+ if (retries < 0 || !dw_pcie_link_up(pp)) { -+ dev_err(dev, "link initialization failed\n"); -+ return -ENXIO; -+ } -+ -+ return 0; -+} -+ -+static void qcom_pcie_host_init_v1(struct pcie_port *pp) -+{ -+ struct qcom_pcie *pcie = to_qcom_pcie(pp); -+ int ret; -+ -+ qcom_ep_reset_assert(pcie); -+ -+ ret = qcom_pcie_enable_resources_v1(pcie); -+ if (ret) -+ return; -+ -+ /* change DBI base address */ -+ writel(0, pcie->parf + PCIE20_PARF_DBI_BASE_ADDR); -+ -+ if (IS_ENABLED(CONFIG_PCI_MSI)) -+ writel_masked(pcie->parf + PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT, -+ 0, BIT(31)); -+ -+ ret = phy_init(pcie->phy); -+ if (ret) -+ goto err_res; -+ -+ ret = phy_power_on(pcie->phy); -+ if (ret) -+ goto err_phy; -+ -+ dw_pcie_setup_rc(pp); -+ -+ if (IS_ENABLED(CONFIG_PCI_MSI)) -+ dw_pcie_msi_init(pp); -+ -+ qcom_ep_reset_deassert(pcie); -+ -+ ret = qcom_pcie_enable_link_training(pp); -+ if (ret) -+ goto err; -+ -+ return; -+ -+err: -+ qcom_ep_reset_assert(pcie); -+ phy_power_off(pcie->phy); -+err_phy: -+ phy_exit(pcie->phy); -+err_res: -+ qcom_pcie_disable_resources_v1(pcie); -+} -+ -+static void qcom_pcie_host_init_v0(struct pcie_port *pp) -+{ -+ struct qcom_pcie *pcie = to_qcom_pcie(pp); -+ struct qcom_pcie_resources_v0 *res = &pcie->res.v0; -+ struct device *dev = pcie->dev; -+ int ret; -+ -+ qcom_ep_reset_assert(pcie); -+ -+ ret = qcom_pcie_enable_resources_v0(pcie); -+ if (ret) -+ return; -+ -+ writel_masked(pcie->parf + PCIE20_PARF_PHY_CTRL, BIT(0), 0); -+ -+ /* enable external reference clock */ -+ writel_masked(pcie->parf + PCIE20_PARF_PHY_REFCLK, 0, BIT(16)); -+ -+ ret = reset_control_deassert(res->phy_reset); -+ if (ret) { -+ dev_err(dev, "cannot deassert phy reset\n"); -+ return; -+ } -+ -+ ret = reset_control_deassert(res->pci_reset); -+ if (ret) { -+ dev_err(dev, "cannot deassert pci reset\n"); -+ return; -+ } -+ -+ ret = reset_control_deassert(res->por_reset); -+ if (ret) { -+ dev_err(dev, "cannot deassert por reset\n"); -+ return; -+ } -+ -+ ret = reset_control_deassert(res->axi_reset); -+ if (ret) { -+ dev_err(dev, "cannot deassert axi reset\n"); -+ return; -+ } -+ -+ /* wait 150ms for clock acquisition */ -+ usleep_range(10000, 15000); -+ -+ dw_pcie_setup_rc(pp); -+ -+ if (IS_ENABLED(CONFIG_PCI_MSI)) -+ dw_pcie_msi_init(pp); -+ -+ qcom_ep_reset_deassert(pcie); -+ -+ ret = qcom_pcie_enable_link_training(pp); -+ if (ret) -+ goto err; -+ -+ return; -+err: -+ qcom_ep_reset_assert(pcie); -+ qcom_pcie_disable_resources_v0(pcie); -+} -+ -+static void qcom_pcie_host_init(struct pcie_port *pp) -+{ -+ struct qcom_pcie *pcie = to_qcom_pcie(pp); -+ -+ if (pcie->version == PCIE_V0) -+ return qcom_pcie_host_init_v0(pp); -+ else -+ return qcom_pcie_host_init_v1(pp); -+} -+ -+static int -+qcom_pcie_rd_own_conf(struct pcie_port *pp, int where, int size, u32 *val) -+{ -+ /* the device class is not reported correctly from the register */ -+ if (where == PCI_CLASS_REVISION && size == 4) { -+ *val = readl(pp->dbi_base + PCI_CLASS_REVISION); -+ *val &= ~(0xffff << 16); -+ *val |= PCI_CLASS_BRIDGE_PCI << 16; -+ return PCIBIOS_SUCCESSFUL; -+ } -+ -+ return dw_pcie_cfg_read(pp->dbi_base + (where & ~0x3), where, -+ size, val); -+} -+ -+static struct pcie_host_ops qcom_pcie_ops = { -+ .link_up = qcom_pcie_link_up, -+ .host_init = qcom_pcie_host_init, -+ .rd_own_conf = qcom_pcie_rd_own_conf, -+}; -+ -+static const struct of_device_id qcom_pcie_match[] = { -+ { .compatible = "qcom,pcie-v0", .data = (void *)PCIE_V0 }, -+ { .compatible = "qcom,pcie-v1", .data = (void *)PCIE_V1 }, -+ { } -+}; -+ -+static int qcom_pcie_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ const struct of_device_id *match; -+ struct resource *res; -+ struct qcom_pcie *pcie; -+ struct pcie_port *pp; -+ int ret; -+ -+ match = of_match_node(qcom_pcie_match, dev->of_node); -+ if (!match) -+ return -ENXIO; -+ -+ pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL); -+ if (!pcie) -+ return -ENOMEM; -+ -+ pcie->version = (unsigned int)match->data; -+ -+ pcie->reset = devm_gpiod_get_optional(dev, "perst"); -+ if (IS_ERR(pcie->reset) && PTR_ERR(pcie->reset) == -EPROBE_DEFER) -+ return PTR_ERR(pcie->reset); -+ -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "parf"); -+ pcie->parf = devm_ioremap_resource(dev, res); -+ if (IS_ERR(pcie->parf)) -+ return PTR_ERR(pcie->parf); -+ -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi"); -+ pcie->dbi = devm_ioremap_resource(dev, res); -+ if (IS_ERR(pcie->dbi)) -+ return PTR_ERR(pcie->dbi); -+ -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "elbi"); -+ pcie->elbi = devm_ioremap_resource(dev, res); -+ if (IS_ERR(pcie->elbi)) -+ return PTR_ERR(pcie->elbi); -+ -+ pcie->phy = devm_phy_optional_get(dev, "pciephy"); -+ if (IS_ERR(pcie->phy)) -+ return PTR_ERR(pcie->phy); -+ -+ pcie->dev = dev; -+ -+ if (pcie->version == PCIE_V0) -+ ret = qcom_pcie_get_resources_v0(pcie); -+ else -+ ret = qcom_pcie_get_resources_v1(pcie); -+ -+ if (ret) -+ return ret; -+ -+ pp = &pcie->pp; -+ pp->dev = dev; -+ pp->dbi_base = pcie->dbi; -+ pp->root_bus_nr = -1; -+ pp->ops = &qcom_pcie_ops; -+ -+ if (IS_ENABLED(CONFIG_PCI_MSI)) { -+ pp->msi_irq = platform_get_irq_byname(pdev, "msi"); -+ if (pp->msi_irq < 0) { -+ dev_err(dev, "cannot get msi irq\n"); -+ return pp->msi_irq; -+ } -+ -+ ret = devm_request_irq(dev, pp->msi_irq, -+ qcom_pcie_msi_irq_handler, -+ IRQF_SHARED, "qcom-pcie-msi", pp); -+ if (ret) { -+ dev_err(dev, "cannot request msi irq\n"); -+ return ret; -+ } -+ } -+ -+ ret = dw_pcie_host_init(pp); -+ if (ret) { -+ dev_err(dev, "cannot initialize host\n"); -+ return ret; -+ } -+ -+ platform_set_drvdata(pdev, pcie); -+ -+ return 0; -+} -+ -+static int qcom_pcie_remove(struct platform_device *pdev) -+{ -+ struct qcom_pcie *pcie = platform_get_drvdata(pdev); -+ -+ qcom_ep_reset_assert(pcie); -+ phy_power_off(pcie->phy); -+ phy_exit(pcie->phy); -+ if (pcie->version == PCIE_V0) -+ qcom_pcie_disable_resources_v0(pcie); -+ else -+ qcom_pcie_disable_resources_v1(pcie); -+ -+ return 0; -+} -+ -+static struct platform_driver qcom_pcie_driver = { -+ .probe = qcom_pcie_probe, -+ .remove = qcom_pcie_remove, -+ .driver = { -+ .name = "qcom-pcie", -+ .of_match_table = qcom_pcie_match, -+ }, -+}; -+ -+module_platform_driver(qcom_pcie_driver); -+ -+MODULE_AUTHOR("Stanimir Varbanov "); -+MODULE_DESCRIPTION("Qualcomm PCIe root complex driver"); -+MODULE_LICENSE("GPL v2"); -+MODULE_ALIAS("platform:qcom-pcie"); ---- a/drivers/pci/host/Makefile -+++ b/drivers/pci/host/Makefile -@@ -11,3 +11,4 @@ obj-$(CONFIG_PCIE_SPEAR13XX) += pcie-spe - obj-$(CONFIG_PCI_KEYSTONE) += pci-keystone-dw.o pci-keystone.o - obj-$(CONFIG_PCIE_XILINX) += pcie-xilinx.o - obj-$(CONFIG_PCI_XGENE) += pci-xgene.o -+obj-$(CONFIG_PCIE_QCOM) += pcie-qcom.o diff --git a/target/linux/ipq806x/patches-3.18/112-ARM-dts-qcom-add-pcie-nodes-to-ipq806x-platforms.patch b/target/linux/ipq806x/patches-3.18/112-ARM-dts-qcom-add-pcie-nodes-to-ipq806x-platforms.patch deleted file mode 100644 index 80ac25faeb..0000000000 --- a/target/linux/ipq806x/patches-3.18/112-ARM-dts-qcom-add-pcie-nodes-to-ipq806x-platforms.patch +++ /dev/null @@ -1,268 +0,0 @@ -From 5b40516b2f5fb9b2a7d6d3e2e924f12ec9d183a8 Mon Sep 17 00:00:00 2001 -From: Mathieu Olivari -Date: Tue, 21 Apr 2015 19:01:42 -0700 -Subject: [PATCH 8/9] ARM: dts: qcom: add pcie nodes to ipq806x platforms - -qcom-pcie driver now supports version 0 of the controller. This change -adds the corresponding entries to the IPQ806x dtsi file and -corresponding platform (AP148). - -Signed-off-by: Mathieu Olivari ---- - arch/arm/boot/dts/qcom-ipq8064-ap148.dts | 30 ++++++++ - arch/arm/boot/dts/qcom-ipq8064.dtsi | 124 +++++++++++++++++++++++++++++++ - 2 files changed, 154 insertions(+) - ---- a/arch/arm/boot/dts/qcom-ipq8064-ap148.dts -+++ b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts -@@ -30,6 +30,22 @@ - bias-disable; - }; - -+ pcie1_pins: pcie1_pinmux { -+ mux { -+ pins = "gpio3"; -+ drive-strength = <2>; -+ bias-disable; -+ }; -+ }; -+ -+ pcie2_pins: pcie2_pinmux { -+ mux { -+ pins = "gpio48"; -+ drive-strength = <2>; -+ bias-disable; -+ }; -+ }; -+ - spi_pins: spi_pins { - mux { - pins = "gpio18", "gpio19", "gpio21"; -@@ -133,5 +149,19 @@ - usb30@1 { - status = "ok"; - }; -+ -+ pcie0: pci@1b500000 { -+ status = "ok"; -+ reset-gpio = <&qcom_pinmux 3 0>; -+ pinctrl-0 = <&pcie1_pins>; -+ pinctrl-names = "default"; -+ }; -+ -+ pcie1: pci@1b700000 { -+ status = "ok"; -+ reset-gpio = <&qcom_pinmux 48 0>; -+ pinctrl-0 = <&pcie2_pins>; -+ pinctrl-names = "default"; -+ }; - }; - }; ---- a/arch/arm/boot/dts/qcom-ipq8064-db149.dts -+++ b/arch/arm/boot/dts/qcom-ipq8064-db149.dts -@@ -30,6 +30,30 @@ - bias-disable; - }; - -+ pcie1_pins: pcie1_pinmux { -+ mux { -+ pins = "gpio3"; -+ drive-strength = <2>; -+ bias-disable; -+ }; -+ }; -+ -+ pcie2_pins: pcie2_pinmux { -+ mux { -+ pins = "gpio48"; -+ drive-strength = <2>; -+ bias-disable; -+ }; -+ }; -+ -+ pcie3_pins: pcie3_pinmux { -+ mux { -+ pins = "gpio63"; -+ drive-strength = <2>; -+ bias-disable; -+ }; -+ }; -+ - spi_pins: spi_pins { - mux { - pins = "gpio18", "gpio19", "gpio21"; -@@ -128,5 +152,26 @@ - usb30@1 { - status = "ok"; - }; -+ -+ pcie0: pci@1b500000 { -+ status = "ok"; -+ reset-gpio = <&qcom_pinmux 3 0>; -+ pinctrl-0 = <&pcie1_pins>; -+ pinctrl-names = "default"; -+ }; -+ -+ pcie1: pci@1b700000 { -+ status = "ok"; -+ reset-gpio = <&qcom_pinmux 48 0>; -+ pinctrl-0 = <&pcie2_pins>; -+ pinctrl-names = "default"; -+ }; -+ -+ pcie2: pci@1b900000 { -+ status = "ok"; -+ reset-gpio = <&qcom_pinmux 63 0>; -+ pinctrl-0 = <&pcie3_pins>; -+ pinctrl-names = "default"; -+ }; - }; - }; ---- a/arch/arm/boot/dts/qcom-ipq8064.dtsi -+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi -@@ -3,6 +3,8 @@ - #include "skeleton.dtsi" - #include - #include -+#include -+#include - - / { - model = "Qualcomm IPQ8064"; -@@ -306,6 +308,129 @@ - #reset-cells = <1>; - }; - -+ pcie0: pci@1b500000 { -+ compatible = "qcom,pcie-v0"; -+ reg = <0x1b500000 0x1000 -+ 0x1b502000 0x80 -+ 0x1b600000 0x100 -+ 0x0ff00000 0x100000>; -+ reg-names = "dbi", "elbi", "parf", "config"; -+ device_type = "pci"; -+ linux,pci-domain = <0>; -+ bus-range = <0x00 0xff>; -+ num-lanes = <1>; -+ #address-cells = <3>; -+ #size-cells = <2>; -+ -+ ranges = <0x81000000 0 0 0x0fe00000 0 0x00100000 /* downstream I/O */ -+ 0x82000000 0 0x00000000 0x08000000 0 0x07e00000>; /* non-prefetchable memory */ -+ -+ interrupts = ; -+ interrupt-names = "msi"; -+ #interrupt-cells = <1>; -+ interrupt-map-mask = <0 0 0 0x7>; -+ interrupt-map = <0 0 0 1 &intc 0 36 IRQ_TYPE_LEVEL_HIGH>, /* int_a */ -+ <0 0 0 2 &intc 0 37 IRQ_TYPE_LEVEL_HIGH>, /* int_b */ -+ <0 0 0 3 &intc 0 38 IRQ_TYPE_LEVEL_HIGH>, /* int_c */ -+ <0 0 0 4 &intc 0 39 IRQ_TYPE_LEVEL_HIGH>; /* int_d */ -+ -+ clocks = <&gcc PCIE_A_CLK>, -+ <&gcc PCIE_H_CLK>, -+ <&gcc PCIE_PHY_CLK>; -+ clock-names = "core", "iface", "phy"; -+ -+ resets = <&gcc PCIE_ACLK_RESET>, -+ <&gcc PCIE_HCLK_RESET>, -+ <&gcc PCIE_POR_RESET>, -+ <&gcc PCIE_PCI_RESET>, -+ <&gcc PCIE_PHY_RESET>; -+ reset-names = "axi", "ahb", "por", "pci", "phy"; -+ -+ status = "disabled"; -+ }; -+ -+ pcie1: pci@1b700000 { -+ compatible = "qcom,pcie-v0"; -+ reg = <0x1b700000 0x1000 -+ 0x1b702000 0x80 -+ 0x1b800000 0x100 -+ 0x31f00000 0x100000>; -+ reg-names = "dbi", "elbi", "parf", "config"; -+ device_type = "pci"; -+ linux,pci-domain = <1>; -+ bus-range = <0x00 0xff>; -+ num-lanes = <1>; -+ #address-cells = <3>; -+ #size-cells = <2>; -+ -+ ranges = <0x81000000 0 0 0x31e00000 0 0x00100000 /* downstream I/O */ -+ 0x82000000 0 0x00000000 0x2e000000 0 0x03e00000>; /* non-prefetchable memory */ -+ -+ interrupts = ; -+ interrupt-names = "msi"; -+ #interrupt-cells = <1>; -+ interrupt-map-mask = <0 0 0 0x7>; -+ interrupt-map = <0 0 0 1 &intc 0 58 IRQ_TYPE_LEVEL_HIGH>, /* int_a */ -+ <0 0 0 2 &intc 0 59 IRQ_TYPE_LEVEL_HIGH>, /* int_b */ -+ <0 0 0 3 &intc 0 60 IRQ_TYPE_LEVEL_HIGH>, /* int_c */ -+ <0 0 0 4 &intc 0 61 IRQ_TYPE_LEVEL_HIGH>; /* int_d */ -+ -+ clocks = <&gcc PCIE_1_A_CLK>, -+ <&gcc PCIE_1_H_CLK>, -+ <&gcc PCIE_1_PHY_CLK>; -+ clock-names = "core", "iface", "phy"; -+ -+ resets = <&gcc PCIE_1_ACLK_RESET>, -+ <&gcc PCIE_1_HCLK_RESET>, -+ <&gcc PCIE_1_POR_RESET>, -+ <&gcc PCIE_1_PCI_RESET>, -+ <&gcc PCIE_1_PHY_RESET>; -+ reset-names = "axi", "ahb", "por", "pci", "phy"; -+ -+ status = "disabled"; -+ }; -+ -+ pcie2: pci@1b900000 { -+ compatible = "qcom,pcie-v0"; -+ reg = <0x1b900000 0x1000 -+ 0x1b902000 0x80 -+ 0x1ba00000 0x100 -+ 0x35f00000 0x100000>; -+ reg-names = "dbi", "elbi", "parf", "config"; -+ device_type = "pci"; -+ linux,pci-domain = <2>; -+ bus-range = <0x00 0xff>; -+ num-lanes = <1>; -+ #address-cells = <3>; -+ #size-cells = <2>; -+ -+ ranges = <0x81000000 0 0 0x35e00000 0 0x00100000 /* downstream I/O */ -+ 0x82000000 0 0x00000000 0x32000000 0 0x03e00000>; /* non-prefetchable memory */ -+ -+ interrupts = ; -+ interrupt-names = "msi"; -+ #interrupt-cells = <1>; -+ interrupt-map-mask = <0 0 0 0x7>; -+ interrupt-map = <0 0 0 1 &intc 0 72 IRQ_TYPE_LEVEL_HIGH>, /* int_a */ -+ <0 0 0 2 &intc 0 73 IRQ_TYPE_LEVEL_HIGH>, /* int_b */ -+ <0 0 0 3 &intc 0 74 IRQ_TYPE_LEVEL_HIGH>, /* int_c */ -+ <0 0 0 4 &intc 0 75 IRQ_TYPE_LEVEL_HIGH>; /* int_d */ -+ -+ clocks = <&gcc PCIE_2_A_CLK>, -+ <&gcc PCIE_2_H_CLK>, -+ <&gcc PCIE_2_PHY_CLK>; -+ clock-names = "core", "iface", "phy"; -+ -+ resets = <&gcc PCIE_2_ACLK_RESET>, -+ <&gcc PCIE_2_HCLK_RESET>, -+ <&gcc PCIE_2_POR_RESET>, -+ <&gcc PCIE_2_PCI_RESET>, -+ <&gcc PCIE_2_PHY_RESET>; -+ reset-names = "axi", "ahb", "por", "pci", "phy"; -+ -+ status = "disabled"; -+ }; -+ - hs_phy_1: phy@100f8800 { - compatible = "qcom,dwc3-hs-usb-phy"; - reg = <0x100f8800 0x30>; -@@ -389,6 +514,5 @@ - dr_mode = "host"; - }; - }; -- - }; - }; diff --git a/target/linux/ipq806x/patches-3.18/113-ARM-qcom-automatically-select-PCI_DOMAINS-if-PCI-is-.patch b/target/linux/ipq806x/patches-3.18/113-ARM-qcom-automatically-select-PCI_DOMAINS-if-PCI-is-.patch deleted file mode 100644 index 4f0e45f656..0000000000 --- a/target/linux/ipq806x/patches-3.18/113-ARM-qcom-automatically-select-PCI_DOMAINS-if-PCI-is-.patch +++ /dev/null @@ -1,29 +0,0 @@ -From f004aa1dec6e2e206be025de15b115d60f2b21e3 Mon Sep 17 00:00:00 2001 -From: Mathieu Olivari -Date: Tue, 21 Apr 2015 19:09:07 -0700 -Subject: [PATCH 9/9] ARM: qcom: automatically select PCI_DOMAINS if PCI is - enabled - -If multiple PCIe devices are present in the system, the kernel will -panic at boot time when trying to scan the PCI buses. This happens on -IPQ806x based platforms, which has 3 PCIe ports. - -Enabling this option allows the kernel to assign the pci-domains -according to the device-tree content. This allows multiple PCIe -controllers to coexist in the system. - -Signed-off-by: Mathieu Olivari ---- - arch/arm/mach-qcom/Kconfig | 1 + - 1 file changed, 1 insertion(+) - ---- a/arch/arm/mach-qcom/Kconfig -+++ b/arch/arm/mach-qcom/Kconfig -@@ -6,6 +6,7 @@ menuconfig ARCH_QCOM - select CLKSRC_OF - select PINCTRL - select QCOM_SCM if SMP -+ select PCI_DOMAINS if PCI - help - Support for Qualcomm's devicetree based systems. - diff --git a/target/linux/ipq806x/patches-3.18/120-mfd-qcom-rpm-Driver-for-the-Qualcomm-RPM.patch b/target/linux/ipq806x/patches-3.18/120-mfd-qcom-rpm-Driver-for-the-Qualcomm-RPM.patch deleted file mode 100644 index d8191422c4..0000000000 --- a/target/linux/ipq806x/patches-3.18/120-mfd-qcom-rpm-Driver-for-the-Qualcomm-RPM.patch +++ /dev/null @@ -1,654 +0,0 @@ -From 58e214382bdd1eb48c5a3519182bddcb26edabad Mon Sep 17 00:00:00 2001 -From: Bjorn Andersson -Date: Wed, 26 Nov 2014 13:51:00 -0800 -Subject: [PATCH] mfd: qcom-rpm: Driver for the Qualcomm RPM - -Driver for the Resource Power Manager (RPM) found in Qualcomm 8660, 8960 -and 8064 based devices. The driver exposes resources that child drivers -can operate on; to implementing regulator, clock and bus frequency -drivers. - -Signed-off-by: Bjorn Andersson -Signed-off-by: Lee Jones ---- - drivers/mfd/Kconfig | 14 ++ - drivers/mfd/Makefile | 1 + - drivers/mfd/qcom_rpm.c | 581 +++++++++++++++++++++++++++++++++++++++++++ - include/linux/mfd/qcom_rpm.h | 13 + - 4 files changed, 609 insertions(+) - create mode 100644 drivers/mfd/qcom_rpm.c - create mode 100644 include/linux/mfd/qcom_rpm.h - ---- a/drivers/mfd/Kconfig -+++ b/drivers/mfd/Kconfig -@@ -567,6 +567,20 @@ config MFD_PM8921_CORE - Say M here if you want to include support for PM8921 chip as a module. - This will build a module called "pm8921-core". - -+config MFD_QCOM_RPM -+ tristate "Qualcomm Resource Power Manager (RPM)" -+ depends on ARCH_QCOM && OF -+ help -+ If you say yes to this option, support will be included for the -+ Resource Power Manager system found in the Qualcomm 8660, 8960 and -+ 8064 based devices. -+ -+ This is required to access many regulators, clocks and bus -+ frequencies controlled by the RPM on these devices. -+ -+ Say M here if you want to include support for the Qualcomm RPM as a -+ module. This will build a module called "qcom_rpm". -+ - config MFD_SPMI_PMIC - tristate "Qualcomm SPMI PMICs" - depends on ARCH_QCOM || COMPILE_TEST ---- a/drivers/mfd/Makefile -+++ b/drivers/mfd/Makefile -@@ -153,6 +153,7 @@ obj-$(CONFIG_MFD_SI476X_CORE) += si476x- - obj-$(CONFIG_MFD_CS5535) += cs5535-mfd.o - obj-$(CONFIG_MFD_OMAP_USB_HOST) += omap-usb-host.o omap-usb-tll.o - obj-$(CONFIG_MFD_PM8921_CORE) += pm8921-core.o ssbi.o -+obj-$(CONFIG_MFD_QCOM_RPM) += qcom_rpm.o - obj-$(CONFIG_MFD_SPMI_PMIC) += qcom-spmi-pmic.o - obj-$(CONFIG_TPS65911_COMPARATOR) += tps65911-comparator.o - obj-$(CONFIG_MFD_TPS65090) += tps65090.o ---- /dev/null -+++ b/drivers/mfd/qcom_rpm.c -@@ -0,0 +1,581 @@ -+/* -+ * Copyright (c) 2014, Sony Mobile Communications AB. -+ * Copyright (c) 2013, The Linux Foundation. All rights reserved. -+ * Author: Bjorn Andersson -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 and -+ * only version 2 as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+struct qcom_rpm_resource { -+ unsigned target_id; -+ unsigned status_id; -+ unsigned select_id; -+ unsigned size; -+}; -+ -+struct qcom_rpm_data { -+ u32 version; -+ const struct qcom_rpm_resource *resource_table; -+ unsigned n_resources; -+}; -+ -+struct qcom_rpm { -+ struct device *dev; -+ struct regmap *ipc_regmap; -+ unsigned ipc_offset; -+ unsigned ipc_bit; -+ -+ struct completion ack; -+ struct mutex lock; -+ -+ void __iomem *status_regs; -+ void __iomem *ctrl_regs; -+ void __iomem *req_regs; -+ -+ u32 ack_status; -+ -+ const struct qcom_rpm_data *data; -+}; -+ -+#define RPM_STATUS_REG(rpm, i) ((rpm)->status_regs + (i) * 4) -+#define RPM_CTRL_REG(rpm, i) ((rpm)->ctrl_regs + (i) * 4) -+#define RPM_REQ_REG(rpm, i) ((rpm)->req_regs + (i) * 4) -+ -+#define RPM_REQUEST_TIMEOUT (5 * HZ) -+ -+#define RPM_REQUEST_CONTEXT 3 -+#define RPM_REQ_SELECT 11 -+#define RPM_ACK_CONTEXT 15 -+#define RPM_ACK_SELECTOR 23 -+#define RPM_SELECT_SIZE 7 -+ -+#define RPM_NOTIFICATION BIT(30) -+#define RPM_REJECTED BIT(31) -+ -+#define RPM_SIGNAL BIT(2) -+ -+static const struct qcom_rpm_resource apq8064_rpm_resource_table[] = { -+ [QCOM_RPM_CXO_CLK] = { 25, 9, 5, 1 }, -+ [QCOM_RPM_PXO_CLK] = { 26, 10, 6, 1 }, -+ [QCOM_RPM_APPS_FABRIC_CLK] = { 27, 11, 8, 1 }, -+ [QCOM_RPM_SYS_FABRIC_CLK] = { 28, 12, 9, 1 }, -+ [QCOM_RPM_MM_FABRIC_CLK] = { 29, 13, 10, 1 }, -+ [QCOM_RPM_DAYTONA_FABRIC_CLK] = { 30, 14, 11, 1 }, -+ [QCOM_RPM_SFPB_CLK] = { 31, 15, 12, 1 }, -+ [QCOM_RPM_CFPB_CLK] = { 32, 16, 13, 1 }, -+ [QCOM_RPM_MMFPB_CLK] = { 33, 17, 14, 1 }, -+ [QCOM_RPM_EBI1_CLK] = { 34, 18, 16, 1 }, -+ [QCOM_RPM_APPS_FABRIC_HALT] = { 35, 19, 18, 1 }, -+ [QCOM_RPM_APPS_FABRIC_MODE] = { 37, 20, 19, 1 }, -+ [QCOM_RPM_APPS_FABRIC_IOCTL] = { 40, 21, 20, 1 }, -+ [QCOM_RPM_APPS_FABRIC_ARB] = { 41, 22, 21, 12 }, -+ [QCOM_RPM_SYS_FABRIC_HALT] = { 53, 23, 22, 1 }, -+ [QCOM_RPM_SYS_FABRIC_MODE] = { 55, 24, 23, 1 }, -+ [QCOM_RPM_SYS_FABRIC_IOCTL] = { 58, 25, 24, 1 }, -+ [QCOM_RPM_SYS_FABRIC_ARB] = { 59, 26, 25, 30 }, -+ [QCOM_RPM_MM_FABRIC_HALT] = { 89, 27, 26, 1 }, -+ [QCOM_RPM_MM_FABRIC_MODE] = { 91, 28, 27, 1 }, -+ [QCOM_RPM_MM_FABRIC_IOCTL] = { 94, 29, 28, 1 }, -+ [QCOM_RPM_MM_FABRIC_ARB] = { 95, 30, 29, 21 }, -+ [QCOM_RPM_PM8921_SMPS1] = { 116, 31, 30, 2 }, -+ [QCOM_RPM_PM8921_SMPS2] = { 118, 33, 31, 2 }, -+ [QCOM_RPM_PM8921_SMPS3] = { 120, 35, 32, 2 }, -+ [QCOM_RPM_PM8921_SMPS4] = { 122, 37, 33, 2 }, -+ [QCOM_RPM_PM8921_SMPS5] = { 124, 39, 34, 2 }, -+ [QCOM_RPM_PM8921_SMPS6] = { 126, 41, 35, 2 }, -+ [QCOM_RPM_PM8921_SMPS7] = { 128, 43, 36, 2 }, -+ [QCOM_RPM_PM8921_SMPS8] = { 130, 45, 37, 2 }, -+ [QCOM_RPM_PM8921_LDO1] = { 132, 47, 38, 2 }, -+ [QCOM_RPM_PM8921_LDO2] = { 134, 49, 39, 2 }, -+ [QCOM_RPM_PM8921_LDO3] = { 136, 51, 40, 2 }, -+ [QCOM_RPM_PM8921_LDO4] = { 138, 53, 41, 2 }, -+ [QCOM_RPM_PM8921_LDO5] = { 140, 55, 42, 2 }, -+ [QCOM_RPM_PM8921_LDO6] = { 142, 57, 43, 2 }, -+ [QCOM_RPM_PM8921_LDO7] = { 144, 59, 44, 2 }, -+ [QCOM_RPM_PM8921_LDO8] = { 146, 61, 45, 2 }, -+ [QCOM_RPM_PM8921_LDO9] = { 148, 63, 46, 2 }, -+ [QCOM_RPM_PM8921_LDO10] = { 150, 65, 47, 2 }, -+ [QCOM_RPM_PM8921_LDO11] = { 152, 67, 48, 2 }, -+ [QCOM_RPM_PM8921_LDO12] = { 154, 69, 49, 2 }, -+ [QCOM_RPM_PM8921_LDO13] = { 156, 71, 50, 2 }, -+ [QCOM_RPM_PM8921_LDO14] = { 158, 73, 51, 2 }, -+ [QCOM_RPM_PM8921_LDO15] = { 160, 75, 52, 2 }, -+ [QCOM_RPM_PM8921_LDO16] = { 162, 77, 53, 2 }, -+ [QCOM_RPM_PM8921_LDO17] = { 164, 79, 54, 2 }, -+ [QCOM_RPM_PM8921_LDO18] = { 166, 81, 55, 2 }, -+ [QCOM_RPM_PM8921_LDO19] = { 168, 83, 56, 2 }, -+ [QCOM_RPM_PM8921_LDO20] = { 170, 85, 57, 2 }, -+ [QCOM_RPM_PM8921_LDO21] = { 172, 87, 58, 2 }, -+ [QCOM_RPM_PM8921_LDO22] = { 174, 89, 59, 2 }, -+ [QCOM_RPM_PM8921_LDO23] = { 176, 91, 60, 2 }, -+ [QCOM_RPM_PM8921_LDO24] = { 178, 93, 61, 2 }, -+ [QCOM_RPM_PM8921_LDO25] = { 180, 95, 62, 2 }, -+ [QCOM_RPM_PM8921_LDO26] = { 182, 97, 63, 2 }, -+ [QCOM_RPM_PM8921_LDO27] = { 184, 99, 64, 2 }, -+ [QCOM_RPM_PM8921_LDO28] = { 186, 101, 65, 2 }, -+ [QCOM_RPM_PM8921_LDO29] = { 188, 103, 66, 2 }, -+ [QCOM_RPM_PM8921_CLK1] = { 190, 105, 67, 2 }, -+ [QCOM_RPM_PM8921_CLK2] = { 192, 107, 68, 2 }, -+ [QCOM_RPM_PM8921_LVS1] = { 194, 109, 69, 1 }, -+ [QCOM_RPM_PM8921_LVS2] = { 195, 110, 70, 1 }, -+ [QCOM_RPM_PM8921_LVS3] = { 196, 111, 71, 1 }, -+ [QCOM_RPM_PM8921_LVS4] = { 197, 112, 72, 1 }, -+ [QCOM_RPM_PM8921_LVS5] = { 198, 113, 73, 1 }, -+ [QCOM_RPM_PM8921_LVS6] = { 199, 114, 74, 1 }, -+ [QCOM_RPM_PM8921_LVS7] = { 200, 115, 75, 1 }, -+ [QCOM_RPM_PM8821_SMPS1] = { 201, 116, 76, 2 }, -+ [QCOM_RPM_PM8821_SMPS2] = { 203, 118, 77, 2 }, -+ [QCOM_RPM_PM8821_LDO1] = { 205, 120, 78, 2 }, -+ [QCOM_RPM_PM8921_NCP] = { 207, 122, 80, 2 }, -+ [QCOM_RPM_CXO_BUFFERS] = { 209, 124, 81, 1 }, -+ [QCOM_RPM_USB_OTG_SWITCH] = { 210, 125, 82, 1 }, -+ [QCOM_RPM_HDMI_SWITCH] = { 211, 126, 83, 1 }, -+ [QCOM_RPM_DDR_DMM] = { 212, 127, 84, 2 }, -+ [QCOM_RPM_VDDMIN_GPIO] = { 215, 131, 89, 1 }, -+}; -+ -+static const struct qcom_rpm_data apq8064_template = { -+ .version = 3, -+ .resource_table = apq8064_rpm_resource_table, -+ .n_resources = ARRAY_SIZE(apq8064_rpm_resource_table), -+}; -+ -+static const struct qcom_rpm_resource msm8660_rpm_resource_table[] = { -+ [QCOM_RPM_CXO_CLK] = { 32, 12, 5, 1 }, -+ [QCOM_RPM_PXO_CLK] = { 33, 13, 6, 1 }, -+ [QCOM_RPM_PLL_4] = { 34, 14, 7, 1 }, -+ [QCOM_RPM_APPS_FABRIC_CLK] = { 35, 15, 8, 1 }, -+ [QCOM_RPM_SYS_FABRIC_CLK] = { 36, 16, 9, 1 }, -+ [QCOM_RPM_MM_FABRIC_CLK] = { 37, 17, 10, 1 }, -+ [QCOM_RPM_DAYTONA_FABRIC_CLK] = { 38, 18, 11, 1 }, -+ [QCOM_RPM_SFPB_CLK] = { 39, 19, 12, 1 }, -+ [QCOM_RPM_CFPB_CLK] = { 40, 20, 13, 1 }, -+ [QCOM_RPM_MMFPB_CLK] = { 41, 21, 14, 1 }, -+ [QCOM_RPM_SMI_CLK] = { 42, 22, 15, 1 }, -+ [QCOM_RPM_EBI1_CLK] = { 43, 23, 16, 1 }, -+ [QCOM_RPM_APPS_L2_CACHE_CTL] = { 44, 24, 17, 1 }, -+ [QCOM_RPM_APPS_FABRIC_HALT] = { 45, 25, 18, 2 }, -+ [QCOM_RPM_APPS_FABRIC_MODE] = { 47, 26, 19, 3 }, -+ [QCOM_RPM_APPS_FABRIC_ARB] = { 51, 28, 21, 6 }, -+ [QCOM_RPM_SYS_FABRIC_HALT] = { 63, 29, 22, 2 }, -+ [QCOM_RPM_SYS_FABRIC_MODE] = { 65, 30, 23, 3 }, -+ [QCOM_RPM_SYS_FABRIC_ARB] = { 69, 32, 25, 22 }, -+ [QCOM_RPM_MM_FABRIC_HALT] = { 105, 33, 26, 2 }, -+ [QCOM_RPM_MM_FABRIC_MODE] = { 107, 34, 27, 3 }, -+ [QCOM_RPM_MM_FABRIC_ARB] = { 111, 36, 29, 23 }, -+ [QCOM_RPM_PM8901_SMPS0] = { 134, 37, 30, 2 }, -+ [QCOM_RPM_PM8901_SMPS1] = { 136, 39, 31, 2 }, -+ [QCOM_RPM_PM8901_SMPS2] = { 138, 41, 32, 2 }, -+ [QCOM_RPM_PM8901_SMPS3] = { 140, 43, 33, 2 }, -+ [QCOM_RPM_PM8901_SMPS4] = { 142, 45, 34, 2 }, -+ [QCOM_RPM_PM8901_LDO0] = { 144, 47, 35, 2 }, -+ [QCOM_RPM_PM8901_LDO1] = { 146, 49, 36, 2 }, -+ [QCOM_RPM_PM8901_LDO2] = { 148, 51, 37, 2 }, -+ [QCOM_RPM_PM8901_LDO3] = { 150, 53, 38, 2 }, -+ [QCOM_RPM_PM8901_LDO4] = { 152, 55, 39, 2 }, -+ [QCOM_RPM_PM8901_LDO5] = { 154, 57, 40, 2 }, -+ [QCOM_RPM_PM8901_LDO6] = { 156, 59, 41, 2 }, -+ [QCOM_RPM_PM8901_LVS0] = { 158, 61, 42, 1 }, -+ [QCOM_RPM_PM8901_LVS1] = { 159, 62, 43, 1 }, -+ [QCOM_RPM_PM8901_LVS2] = { 160, 63, 44, 1 }, -+ [QCOM_RPM_PM8901_LVS3] = { 161, 64, 45, 1 }, -+ [QCOM_RPM_PM8901_MVS] = { 162, 65, 46, 1 }, -+ [QCOM_RPM_PM8058_SMPS0] = { 163, 66, 47, 2 }, -+ [QCOM_RPM_PM8058_SMPS1] = { 165, 68, 48, 2 }, -+ [QCOM_RPM_PM8058_SMPS2] = { 167, 70, 49, 2 }, -+ [QCOM_RPM_PM8058_SMPS3] = { 169, 72, 50, 2 }, -+ [QCOM_RPM_PM8058_SMPS4] = { 171, 74, 51, 2 }, -+ [QCOM_RPM_PM8058_LDO0] = { 173, 76, 52, 2 }, -+ [QCOM_RPM_PM8058_LDO1] = { 175, 78, 53, 2 }, -+ [QCOM_RPM_PM8058_LDO2] = { 177, 80, 54, 2 }, -+ [QCOM_RPM_PM8058_LDO3] = { 179, 82, 55, 2 }, -+ [QCOM_RPM_PM8058_LDO4] = { 181, 84, 56, 2 }, -+ [QCOM_RPM_PM8058_LDO5] = { 183, 86, 57, 2 }, -+ [QCOM_RPM_PM8058_LDO6] = { 185, 88, 58, 2 }, -+ [QCOM_RPM_PM8058_LDO7] = { 187, 90, 59, 2 }, -+ [QCOM_RPM_PM8058_LDO8] = { 189, 92, 60, 2 }, -+ [QCOM_RPM_PM8058_LDO9] = { 191, 94, 61, 2 }, -+ [QCOM_RPM_PM8058_LDO10] = { 193, 96, 62, 2 }, -+ [QCOM_RPM_PM8058_LDO11] = { 195, 98, 63, 2 }, -+ [QCOM_RPM_PM8058_LDO12] = { 197, 100, 64, 2 }, -+ [QCOM_RPM_PM8058_LDO13] = { 199, 102, 65, 2 }, -+ [QCOM_RPM_PM8058_LDO14] = { 201, 104, 66, 2 }, -+ [QCOM_RPM_PM8058_LDO15] = { 203, 106, 67, 2 }, -+ [QCOM_RPM_PM8058_LDO16] = { 205, 108, 68, 2 }, -+ [QCOM_RPM_PM8058_LDO17] = { 207, 110, 69, 2 }, -+ [QCOM_RPM_PM8058_LDO18] = { 209, 112, 70, 2 }, -+ [QCOM_RPM_PM8058_LDO19] = { 211, 114, 71, 2 }, -+ [QCOM_RPM_PM8058_LDO20] = { 213, 116, 72, 2 }, -+ [QCOM_RPM_PM8058_LDO21] = { 215, 118, 73, 2 }, -+ [QCOM_RPM_PM8058_LDO22] = { 217, 120, 74, 2 }, -+ [QCOM_RPM_PM8058_LDO23] = { 219, 122, 75, 2 }, -+ [QCOM_RPM_PM8058_LDO24] = { 221, 124, 76, 2 }, -+ [QCOM_RPM_PM8058_LDO25] = { 223, 126, 77, 2 }, -+ [QCOM_RPM_PM8058_LVS0] = { 225, 128, 78, 1 }, -+ [QCOM_RPM_PM8058_LVS1] = { 226, 129, 79, 1 }, -+ [QCOM_RPM_PM8058_NCP] = { 227, 130, 80, 2 }, -+ [QCOM_RPM_CXO_BUFFERS] = { 229, 132, 81, 1 }, -+}; -+ -+static const struct qcom_rpm_data msm8660_template = { -+ .version = 2, -+ .resource_table = msm8660_rpm_resource_table, -+ .n_resources = ARRAY_SIZE(msm8660_rpm_resource_table), -+}; -+ -+static const struct qcom_rpm_resource msm8960_rpm_resource_table[] = { -+ [QCOM_RPM_CXO_CLK] = { 25, 9, 5, 1 }, -+ [QCOM_RPM_PXO_CLK] = { 26, 10, 6, 1 }, -+ [QCOM_RPM_APPS_FABRIC_CLK] = { 27, 11, 8, 1 }, -+ [QCOM_RPM_SYS_FABRIC_CLK] = { 28, 12, 9, 1 }, -+ [QCOM_RPM_MM_FABRIC_CLK] = { 29, 13, 10, 1 }, -+ [QCOM_RPM_DAYTONA_FABRIC_CLK] = { 30, 14, 11, 1 }, -+ [QCOM_RPM_SFPB_CLK] = { 31, 15, 12, 1 }, -+ [QCOM_RPM_CFPB_CLK] = { 32, 16, 13, 1 }, -+ [QCOM_RPM_MMFPB_CLK] = { 33, 17, 14, 1 }, -+ [QCOM_RPM_EBI1_CLK] = { 34, 18, 16, 1 }, -+ [QCOM_RPM_APPS_FABRIC_HALT] = { 35, 19, 18, 1 }, -+ [QCOM_RPM_APPS_FABRIC_MODE] = { 37, 20, 19, 1 }, -+ [QCOM_RPM_APPS_FABRIC_IOCTL] = { 40, 21, 20, 1 }, -+ [QCOM_RPM_APPS_FABRIC_ARB] = { 41, 22, 21, 12 }, -+ [QCOM_RPM_SYS_FABRIC_HALT] = { 53, 23, 22, 1 }, -+ [QCOM_RPM_SYS_FABRIC_MODE] = { 55, 24, 23, 1 }, -+ [QCOM_RPM_SYS_FABRIC_IOCTL] = { 58, 25, 24, 1 }, -+ [QCOM_RPM_SYS_FABRIC_ARB] = { 59, 26, 25, 29 }, -+ [QCOM_RPM_MM_FABRIC_HALT] = { 88, 27, 26, 1 }, -+ [QCOM_RPM_MM_FABRIC_MODE] = { 90, 28, 27, 1 }, -+ [QCOM_RPM_MM_FABRIC_IOCTL] = { 93, 29, 28, 1 }, -+ [QCOM_RPM_MM_FABRIC_ARB] = { 94, 30, 29, 23 }, -+ [QCOM_RPM_PM8921_SMPS1] = { 117, 31, 30, 2 }, -+ [QCOM_RPM_PM8921_SMPS2] = { 119, 33, 31, 2 }, -+ [QCOM_RPM_PM8921_SMPS3] = { 121, 35, 32, 2 }, -+ [QCOM_RPM_PM8921_SMPS4] = { 123, 37, 33, 2 }, -+ [QCOM_RPM_PM8921_SMPS5] = { 125, 39, 34, 2 }, -+ [QCOM_RPM_PM8921_SMPS6] = { 127, 41, 35, 2 }, -+ [QCOM_RPM_PM8921_SMPS7] = { 129, 43, 36, 2 }, -+ [QCOM_RPM_PM8921_SMPS8] = { 131, 45, 37, 2 }, -+ [QCOM_RPM_PM8921_LDO1] = { 133, 47, 38, 2 }, -+ [QCOM_RPM_PM8921_LDO2] = { 135, 49, 39, 2 }, -+ [QCOM_RPM_PM8921_LDO3] = { 137, 51, 40, 2 }, -+ [QCOM_RPM_PM8921_LDO4] = { 139, 53, 41, 2 }, -+ [QCOM_RPM_PM8921_LDO5] = { 141, 55, 42, 2 }, -+ [QCOM_RPM_PM8921_LDO6] = { 143, 57, 43, 2 }, -+ [QCOM_RPM_PM8921_LDO7] = { 145, 59, 44, 2 }, -+ [QCOM_RPM_PM8921_LDO8] = { 147, 61, 45, 2 }, -+ [QCOM_RPM_PM8921_LDO9] = { 149, 63, 46, 2 }, -+ [QCOM_RPM_PM8921_LDO10] = { 151, 65, 47, 2 }, -+ [QCOM_RPM_PM8921_LDO11] = { 153, 67, 48, 2 }, -+ [QCOM_RPM_PM8921_LDO12] = { 155, 69, 49, 2 }, -+ [QCOM_RPM_PM8921_LDO13] = { 157, 71, 50, 2 }, -+ [QCOM_RPM_PM8921_LDO14] = { 159, 73, 51, 2 }, -+ [QCOM_RPM_PM8921_LDO15] = { 161, 75, 52, 2 }, -+ [QCOM_RPM_PM8921_LDO16] = { 163, 77, 53, 2 }, -+ [QCOM_RPM_PM8921_LDO17] = { 165, 79, 54, 2 }, -+ [QCOM_RPM_PM8921_LDO18] = { 167, 81, 55, 2 }, -+ [QCOM_RPM_PM8921_LDO19] = { 169, 83, 56, 2 }, -+ [QCOM_RPM_PM8921_LDO20] = { 171, 85, 57, 2 }, -+ [QCOM_RPM_PM8921_LDO21] = { 173, 87, 58, 2 }, -+ [QCOM_RPM_PM8921_LDO22] = { 175, 89, 59, 2 }, -+ [QCOM_RPM_PM8921_LDO23] = { 177, 91, 60, 2 }, -+ [QCOM_RPM_PM8921_LDO24] = { 179, 93, 61, 2 }, -+ [QCOM_RPM_PM8921_LDO25] = { 181, 95, 62, 2 }, -+ [QCOM_RPM_PM8921_LDO26] = { 183, 97, 63, 2 }, -+ [QCOM_RPM_PM8921_LDO27] = { 185, 99, 64, 2 }, -+ [QCOM_RPM_PM8921_LDO28] = { 187, 101, 65, 2 }, -+ [QCOM_RPM_PM8921_LDO29] = { 189, 103, 66, 2 }, -+ [QCOM_RPM_PM8921_CLK1] = { 191, 105, 67, 2 }, -+ [QCOM_RPM_PM8921_CLK2] = { 193, 107, 68, 2 }, -+ [QCOM_RPM_PM8921_LVS1] = { 195, 109, 69, 1 }, -+ [QCOM_RPM_PM8921_LVS2] = { 196, 110, 70, 1 }, -+ [QCOM_RPM_PM8921_LVS3] = { 197, 111, 71, 1 }, -+ [QCOM_RPM_PM8921_LVS4] = { 198, 112, 72, 1 }, -+ [QCOM_RPM_PM8921_LVS5] = { 199, 113, 73, 1 }, -+ [QCOM_RPM_PM8921_LVS6] = { 200, 114, 74, 1 }, -+ [QCOM_RPM_PM8921_LVS7] = { 201, 115, 75, 1 }, -+ [QCOM_RPM_PM8921_NCP] = { 202, 116, 80, 2 }, -+ [QCOM_RPM_CXO_BUFFERS] = { 204, 118, 81, 1 }, -+ [QCOM_RPM_USB_OTG_SWITCH] = { 205, 119, 82, 1 }, -+ [QCOM_RPM_HDMI_SWITCH] = { 206, 120, 83, 1 }, -+ [QCOM_RPM_DDR_DMM] = { 207, 121, 84, 2 }, -+}; -+ -+static const struct qcom_rpm_data msm8960_template = { -+ .version = 3, -+ .resource_table = msm8960_rpm_resource_table, -+ .n_resources = ARRAY_SIZE(msm8960_rpm_resource_table), -+}; -+ -+static const struct of_device_id qcom_rpm_of_match[] = { -+ { .compatible = "qcom,rpm-apq8064", .data = &apq8064_template }, -+ { .compatible = "qcom,rpm-msm8660", .data = &msm8660_template }, -+ { .compatible = "qcom,rpm-msm8960", .data = &msm8960_template }, -+ { } -+}; -+MODULE_DEVICE_TABLE(of, qcom_rpm_of_match); -+ -+int qcom_rpm_write(struct qcom_rpm *rpm, -+ int state, -+ int resource, -+ u32 *buf, size_t count) -+{ -+ const struct qcom_rpm_resource *res; -+ const struct qcom_rpm_data *data = rpm->data; -+ u32 sel_mask[RPM_SELECT_SIZE] = { 0 }; -+ int left; -+ int ret = 0; -+ int i; -+ -+ if (WARN_ON(resource < 0 || resource >= data->n_resources)) -+ return -EINVAL; -+ -+ res = &data->resource_table[resource]; -+ if (WARN_ON(res->size != count)) -+ return -EINVAL; -+ -+ mutex_lock(&rpm->lock); -+ -+ for (i = 0; i < res->size; i++) -+ writel_relaxed(buf[i], RPM_REQ_REG(rpm, res->target_id + i)); -+ -+ bitmap_set((unsigned long *)sel_mask, res->select_id, 1); -+ for (i = 0; i < ARRAY_SIZE(sel_mask); i++) { -+ writel_relaxed(sel_mask[i], -+ RPM_CTRL_REG(rpm, RPM_REQ_SELECT + i)); -+ } -+ -+ writel_relaxed(BIT(state), RPM_CTRL_REG(rpm, RPM_REQUEST_CONTEXT)); -+ -+ reinit_completion(&rpm->ack); -+ regmap_write(rpm->ipc_regmap, rpm->ipc_offset, BIT(rpm->ipc_bit)); -+ -+ left = wait_for_completion_timeout(&rpm->ack, RPM_REQUEST_TIMEOUT); -+ if (!left) -+ ret = -ETIMEDOUT; -+ else if (rpm->ack_status & RPM_REJECTED) -+ ret = -EIO; -+ -+ mutex_unlock(&rpm->lock); -+ -+ return ret; -+} -+EXPORT_SYMBOL(qcom_rpm_write); -+ -+static irqreturn_t qcom_rpm_ack_interrupt(int irq, void *dev) -+{ -+ struct qcom_rpm *rpm = dev; -+ u32 ack; -+ int i; -+ -+ ack = readl_relaxed(RPM_CTRL_REG(rpm, RPM_ACK_CONTEXT)); -+ for (i = 0; i < RPM_SELECT_SIZE; i++) -+ writel_relaxed(0, RPM_CTRL_REG(rpm, RPM_ACK_SELECTOR + i)); -+ writel(0, RPM_CTRL_REG(rpm, RPM_ACK_CONTEXT)); -+ -+ if (ack & RPM_NOTIFICATION) { -+ dev_warn(rpm->dev, "ignoring notification!\n"); -+ } else { -+ rpm->ack_status = ack; -+ complete(&rpm->ack); -+ } -+ -+ return IRQ_HANDLED; -+} -+ -+static irqreturn_t qcom_rpm_err_interrupt(int irq, void *dev) -+{ -+ struct qcom_rpm *rpm = dev; -+ -+ regmap_write(rpm->ipc_regmap, rpm->ipc_offset, BIT(rpm->ipc_bit)); -+ dev_err(rpm->dev, "RPM triggered fatal error\n"); -+ -+ return IRQ_HANDLED; -+} -+ -+static irqreturn_t qcom_rpm_wakeup_interrupt(int irq, void *dev) -+{ -+ return IRQ_HANDLED; -+} -+ -+static int qcom_rpm_probe(struct platform_device *pdev) -+{ -+ const struct of_device_id *match; -+ struct device_node *syscon_np; -+ struct resource *res; -+ struct qcom_rpm *rpm; -+ u32 fw_version[3]; -+ int irq_wakeup; -+ int irq_ack; -+ int irq_err; -+ int ret; -+ -+ rpm = devm_kzalloc(&pdev->dev, sizeof(*rpm), GFP_KERNEL); -+ if (!rpm) -+ return -ENOMEM; -+ -+ rpm->dev = &pdev->dev; -+ mutex_init(&rpm->lock); -+ init_completion(&rpm->ack); -+ -+ irq_ack = platform_get_irq_byname(pdev, "ack"); -+ if (irq_ack < 0) { -+ dev_err(&pdev->dev, "required ack interrupt missing\n"); -+ return irq_ack; -+ } -+ -+ irq_err = platform_get_irq_byname(pdev, "err"); -+ if (irq_err < 0) { -+ dev_err(&pdev->dev, "required err interrupt missing\n"); -+ return irq_err; -+ } -+ -+ irq_wakeup = platform_get_irq_byname(pdev, "wakeup"); -+ if (irq_wakeup < 0) { -+ dev_err(&pdev->dev, "required wakeup interrupt missing\n"); -+ return irq_wakeup; -+ } -+ -+ match = of_match_device(qcom_rpm_of_match, &pdev->dev); -+ rpm->data = match->data; -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ rpm->status_regs = devm_ioremap_resource(&pdev->dev, res); -+ if (IS_ERR(rpm->status_regs)) -+ return PTR_ERR(rpm->status_regs); -+ rpm->ctrl_regs = rpm->status_regs + 0x400; -+ rpm->req_regs = rpm->status_regs + 0x600; -+ -+ syscon_np = of_parse_phandle(pdev->dev.of_node, "qcom,ipc", 0); -+ if (!syscon_np) { -+ dev_err(&pdev->dev, "no qcom,ipc node\n"); -+ return -ENODEV; -+ } -+ -+ rpm->ipc_regmap = syscon_node_to_regmap(syscon_np); -+ if (IS_ERR(rpm->ipc_regmap)) -+ return PTR_ERR(rpm->ipc_regmap); -+ -+ ret = of_property_read_u32_index(pdev->dev.of_node, "qcom,ipc", 1, -+ &rpm->ipc_offset); -+ if (ret < 0) { -+ dev_err(&pdev->dev, "no offset in qcom,ipc\n"); -+ return -EINVAL; -+ } -+ -+ ret = of_property_read_u32_index(pdev->dev.of_node, "qcom,ipc", 2, -+ &rpm->ipc_bit); -+ if (ret < 0) { -+ dev_err(&pdev->dev, "no bit in qcom,ipc\n"); -+ return -EINVAL; -+ } -+ -+ dev_set_drvdata(&pdev->dev, rpm); -+ -+ fw_version[0] = readl(RPM_STATUS_REG(rpm, 0)); -+ fw_version[1] = readl(RPM_STATUS_REG(rpm, 1)); -+ fw_version[2] = readl(RPM_STATUS_REG(rpm, 2)); -+ if (fw_version[0] != rpm->data->version) { -+ dev_err(&pdev->dev, -+ "RPM version %u.%u.%u incompatible with driver version %u", -+ fw_version[0], -+ fw_version[1], -+ fw_version[2], -+ rpm->data->version); -+ return -EFAULT; -+ } -+ -+ dev_info(&pdev->dev, "RPM firmware %u.%u.%u\n", fw_version[0], -+ fw_version[1], -+ fw_version[2]); -+ -+ ret = devm_request_irq(&pdev->dev, -+ irq_ack, -+ qcom_rpm_ack_interrupt, -+ IRQF_TRIGGER_RISING | IRQF_NO_SUSPEND, -+ "qcom_rpm_ack", -+ rpm); -+ if (ret) { -+ dev_err(&pdev->dev, "failed to request ack interrupt\n"); -+ return ret; -+ } -+ -+ ret = irq_set_irq_wake(irq_ack, 1); -+ if (ret) -+ dev_warn(&pdev->dev, "failed to mark ack irq as wakeup\n"); -+ -+ ret = devm_request_irq(&pdev->dev, -+ irq_err, -+ qcom_rpm_err_interrupt, -+ IRQF_TRIGGER_RISING, -+ "qcom_rpm_err", -+ rpm); -+ if (ret) { -+ dev_err(&pdev->dev, "failed to request err interrupt\n"); -+ return ret; -+ } -+ -+ ret = devm_request_irq(&pdev->dev, -+ irq_wakeup, -+ qcom_rpm_wakeup_interrupt, -+ IRQF_TRIGGER_RISING, -+ "qcom_rpm_wakeup", -+ rpm); -+ if (ret) { -+ dev_err(&pdev->dev, "failed to request wakeup interrupt\n"); -+ return ret; -+ } -+ -+ ret = irq_set_irq_wake(irq_wakeup, 1); -+ if (ret) -+ dev_warn(&pdev->dev, "failed to mark wakeup irq as wakeup\n"); -+ -+ return of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev); -+} -+ -+static int qcom_rpm_remove(struct platform_device *pdev) -+{ -+ of_platform_depopulate(&pdev->dev); -+ return 0; -+} -+ -+static struct platform_driver qcom_rpm_driver = { -+ .probe = qcom_rpm_probe, -+ .remove = qcom_rpm_remove, -+ .driver = { -+ .name = "qcom_rpm", -+ .of_match_table = qcom_rpm_of_match, -+ }, -+}; -+ -+static int __init qcom_rpm_init(void) -+{ -+ return platform_driver_register(&qcom_rpm_driver); -+} -+arch_initcall(qcom_rpm_init); -+ -+static void __exit qcom_rpm_exit(void) -+{ -+ platform_driver_unregister(&qcom_rpm_driver); -+} -+module_exit(qcom_rpm_exit) -+ -+MODULE_DESCRIPTION("Qualcomm Resource Power Manager driver"); -+MODULE_LICENSE("GPL v2"); -+MODULE_AUTHOR("Bjorn Andersson "); ---- /dev/null -+++ b/include/linux/mfd/qcom_rpm.h -@@ -0,0 +1,13 @@ -+#ifndef __QCOM_RPM_H__ -+#define __QCOM_RPM_H__ -+ -+#include -+ -+struct qcom_rpm; -+ -+#define QCOM_RPM_ACTIVE_STATE 0 -+#define QCOM_RPM_SLEEP_STATE 1 -+ -+int qcom_rpm_write(struct qcom_rpm *rpm, int state, int resource, u32 *buf, size_t count); -+ -+#endif diff --git a/target/linux/ipq806x/patches-3.18/121-mfd-qcom_rpm-Add-support-for-IPQ8064.patch b/target/linux/ipq806x/patches-3.18/121-mfd-qcom_rpm-Add-support-for-IPQ8064.patch deleted file mode 100644 index e5e9e4e6cc..0000000000 --- a/target/linux/ipq806x/patches-3.18/121-mfd-qcom_rpm-Add-support-for-IPQ8064.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 4d54b0adfa67476e6509bc8646b9dbac642e8a29 Mon Sep 17 00:00:00 2001 -From: Josh Cartwright -Date: Thu, 26 Mar 2015 11:29:26 -0700 -Subject: [PATCH] mfd: qcom_rpm: Add support for IPQ8064 - -The IPQ8064 also includes an RPM following the same message structure as -other chips. In addition, it supports a few new resource types to -support the NSS fabric clocks and the SMB208/SMB209 regulators found on -the reference boards. - -Signed-off-by: Josh Cartwright -Signed-off-by: Stephen Boyd -Signed-off-by: Lee Jones ---- - drivers/mfd/qcom_rpm.c | 41 +++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 41 insertions(+) - ---- a/drivers/mfd/qcom_rpm.c -+++ b/drivers/mfd/qcom_rpm.c -@@ -323,10 +323,51 @@ static const struct qcom_rpm_data msm896 - .n_resources = ARRAY_SIZE(msm8960_rpm_resource_table), - }; - -+static const struct qcom_rpm_resource ipq806x_rpm_resource_table[] = { -+ [QCOM_RPM_CXO_CLK] = { 25, 9, 5, 1 }, -+ [QCOM_RPM_PXO_CLK] = { 26, 10, 6, 1 }, -+ [QCOM_RPM_APPS_FABRIC_CLK] = { 27, 11, 8, 1 }, -+ [QCOM_RPM_SYS_FABRIC_CLK] = { 28, 12, 9, 1 }, -+ [QCOM_RPM_NSS_FABRIC_0_CLK] = { 29, 13, 10, 1 }, -+ [QCOM_RPM_DAYTONA_FABRIC_CLK] = { 30, 14, 11, 1 }, -+ [QCOM_RPM_SFPB_CLK] = { 31, 15, 12, 1 }, -+ [QCOM_RPM_CFPB_CLK] = { 32, 16, 13, 1 }, -+ [QCOM_RPM_NSS_FABRIC_1_CLK] = { 33, 17, 14, 1 }, -+ [QCOM_RPM_EBI1_CLK] = { 34, 18, 16, 1 }, -+ [QCOM_RPM_APPS_FABRIC_HALT] = { 35, 19, 18, 2 }, -+ [QCOM_RPM_APPS_FABRIC_MODE] = { 37, 20, 19, 3 }, -+ [QCOM_RPM_APPS_FABRIC_IOCTL] = { 40, 21, 20, 1 }, -+ [QCOM_RPM_APPS_FABRIC_ARB] = { 41, 22, 21, 12 }, -+ [QCOM_RPM_SYS_FABRIC_HALT] = { 53, 23, 22, 2 }, -+ [QCOM_RPM_SYS_FABRIC_MODE] = { 55, 24, 23, 3 }, -+ [QCOM_RPM_SYS_FABRIC_IOCTL] = { 58, 25, 24, 1 }, -+ [QCOM_RPM_SYS_FABRIC_ARB] = { 59, 26, 25, 30 }, -+ [QCOM_RPM_MM_FABRIC_HALT] = { 89, 27, 26, 2 }, -+ [QCOM_RPM_MM_FABRIC_MODE] = { 91, 28, 27, 3 }, -+ [QCOM_RPM_MM_FABRIC_IOCTL] = { 94, 29, 28, 1 }, -+ [QCOM_RPM_MM_FABRIC_ARB] = { 95, 30, 29, 2 }, -+ [QCOM_RPM_CXO_BUFFERS] = { 209, 33, 31, 1 }, -+ [QCOM_RPM_USB_OTG_SWITCH] = { 210, 34, 32, 1 }, -+ [QCOM_RPM_HDMI_SWITCH] = { 211, 35, 33, 1 }, -+ [QCOM_RPM_DDR_DMM] = { 212, 36, 34, 2 }, -+ [QCOM_RPM_VDDMIN_GPIO] = { 215, 40, 39, 1 }, -+ [QCOM_RPM_SMB208_S1a] = { 216, 41, 90, 2 }, -+ [QCOM_RPM_SMB208_S1b] = { 218, 43, 91, 2 }, -+ [QCOM_RPM_SMB208_S2a] = { 220, 45, 92, 2 }, -+ [QCOM_RPM_SMB208_S2b] = { 222, 47, 93, 2 }, -+}; -+ -+static const struct qcom_rpm_data ipq806x_template = { -+ .version = 3, -+ .resource_table = ipq806x_rpm_resource_table, -+ .n_resources = ARRAY_SIZE(ipq806x_rpm_resource_table), -+}; -+ - static const struct of_device_id qcom_rpm_of_match[] = { - { .compatible = "qcom,rpm-apq8064", .data = &apq8064_template }, - { .compatible = "qcom,rpm-msm8660", .data = &msm8660_template }, - { .compatible = "qcom,rpm-msm8960", .data = &msm8960_template }, -+ { .compatible = "qcom,rpm-ipq8064", .data = &ipq806x_template }, - { } - }; - MODULE_DEVICE_TABLE(of, qcom_rpm_of_match); diff --git a/target/linux/ipq806x/patches-3.18/122-mfd-devicetree-bindings-Add-Qualcomm-RPM-DT-binding.patch b/target/linux/ipq806x/patches-3.18/122-mfd-devicetree-bindings-Add-Qualcomm-RPM-DT-binding.patch deleted file mode 100644 index a65d2c5131..0000000000 --- a/target/linux/ipq806x/patches-3.18/122-mfd-devicetree-bindings-Add-Qualcomm-RPM-DT-binding.patch +++ /dev/null @@ -1,247 +0,0 @@ -From aa0c4b815045420ea54d5ae5362f5a0190609d46 Mon Sep 17 00:00:00 2001 -From: Bjorn Andersson -Date: Wed, 26 Nov 2014 13:50:59 -0800 -Subject: [PATCH] mfd: devicetree: bindings: Add Qualcomm RPM DT binding - -Add binding for the Qualcomm Resource Power Manager (RPM) found in 8660, -8960 and 8064 based devices. - -Signed-off-by: Bjorn Andersson -Signed-off-by: Lee Jones ---- - Documentation/devicetree/bindings/mfd/qcom-rpm.txt | 70 ++++++++++ - include/dt-bindings/mfd/qcom-rpm.h | 154 +++++++++++++++++++++ - 2 files changed, 224 insertions(+) - create mode 100644 Documentation/devicetree/bindings/mfd/qcom-rpm.txt - create mode 100644 include/dt-bindings/mfd/qcom-rpm.h - ---- /dev/null -+++ b/Documentation/devicetree/bindings/mfd/qcom-rpm.txt -@@ -0,0 +1,70 @@ -+Qualcomm Resource Power Manager (RPM) -+ -+This driver is used to interface with the Resource Power Manager (RPM) found in -+various Qualcomm platforms. The RPM allows each component in the system to vote -+for state of the system resources, such as clocks, regulators and bus -+frequencies. -+ -+- compatible: -+ Usage: required -+ Value type: -+ Definition: must be one of: -+ "qcom,rpm-apq8064" -+ "qcom,rpm-msm8660" -+ "qcom,rpm-msm8960" -+ -+- reg: -+ Usage: required -+ Value type: -+ Definition: base address and size of the RPM's message ram -+ -+- interrupts: -+ Usage: required -+ Value type: -+ Definition: three entries specifying the RPM's: -+ 1. acknowledgement interrupt -+ 2. error interrupt -+ 3. wakeup interrupt -+ -+- interrupt-names: -+ Usage: required -+ Value type: -+ Definition: must be the three strings "ack", "err" and "wakeup", in order -+ -+- #address-cells: -+ Usage: required -+ Value type: -+ Definition: must be 1 -+ -+- #size-cells: -+ Usage: required -+ Value type: -+ Definition: must be 0 -+ -+- qcom,ipc: -+ Usage: required -+ Value type: -+ -+ Definition: three entries specifying the outgoing ipc bit used for -+ signaling the RPM: -+ - phandle to a syscon node representing the apcs registers -+ - u32 representing offset to the register within the syscon -+ - u32 representing the ipc bit within the register -+ -+ -+= EXAMPLE -+ -+ #include -+ -+ rpm@108000 { -+ compatible = "qcom,rpm-msm8960"; -+ reg = <0x108000 0x1000>; -+ qcom,ipc = <&apcs 0x8 2>; -+ -+ interrupts = <0 19 0>, <0 21 0>, <0 22 0>; -+ interrupt-names = "ack", "err", "wakeup"; -+ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ ---- /dev/null -+++ b/include/dt-bindings/mfd/qcom-rpm.h -@@ -0,0 +1,154 @@ -+/* -+ * This header provides constants for the Qualcomm RPM bindings. -+ */ -+ -+#ifndef _DT_BINDINGS_MFD_QCOM_RPM_H -+#define _DT_BINDINGS_MFD_QCOM_RPM_H -+ -+/* -+ * Constants use to identify individual resources in the RPM. -+ */ -+#define QCOM_RPM_APPS_FABRIC_ARB 1 -+#define QCOM_RPM_APPS_FABRIC_CLK 2 -+#define QCOM_RPM_APPS_FABRIC_HALT 3 -+#define QCOM_RPM_APPS_FABRIC_IOCTL 4 -+#define QCOM_RPM_APPS_FABRIC_MODE 5 -+#define QCOM_RPM_APPS_L2_CACHE_CTL 6 -+#define QCOM_RPM_CFPB_CLK 7 -+#define QCOM_RPM_CXO_BUFFERS 8 -+#define QCOM_RPM_CXO_CLK 9 -+#define QCOM_RPM_DAYTONA_FABRIC_CLK 10 -+#define QCOM_RPM_DDR_DMM 11 -+#define QCOM_RPM_EBI1_CLK 12 -+#define QCOM_RPM_HDMI_SWITCH 13 -+#define QCOM_RPM_MMFPB_CLK 14 -+#define QCOM_RPM_MM_FABRIC_ARB 15 -+#define QCOM_RPM_MM_FABRIC_CLK 16 -+#define QCOM_RPM_MM_FABRIC_HALT 17 -+#define QCOM_RPM_MM_FABRIC_IOCTL 18 -+#define QCOM_RPM_MM_FABRIC_MODE 19 -+#define QCOM_RPM_PLL_4 20 -+#define QCOM_RPM_PM8058_LDO0 21 -+#define QCOM_RPM_PM8058_LDO1 22 -+#define QCOM_RPM_PM8058_LDO2 23 -+#define QCOM_RPM_PM8058_LDO3 24 -+#define QCOM_RPM_PM8058_LDO4 25 -+#define QCOM_RPM_PM8058_LDO5 26 -+#define QCOM_RPM_PM8058_LDO6 27 -+#define QCOM_RPM_PM8058_LDO7 28 -+#define QCOM_RPM_PM8058_LDO8 29 -+#define QCOM_RPM_PM8058_LDO9 30 -+#define QCOM_RPM_PM8058_LDO10 31 -+#define QCOM_RPM_PM8058_LDO11 32 -+#define QCOM_RPM_PM8058_LDO12 33 -+#define QCOM_RPM_PM8058_LDO13 34 -+#define QCOM_RPM_PM8058_LDO14 35 -+#define QCOM_RPM_PM8058_LDO15 36 -+#define QCOM_RPM_PM8058_LDO16 37 -+#define QCOM_RPM_PM8058_LDO17 38 -+#define QCOM_RPM_PM8058_LDO18 39 -+#define QCOM_RPM_PM8058_LDO19 40 -+#define QCOM_RPM_PM8058_LDO20 41 -+#define QCOM_RPM_PM8058_LDO21 42 -+#define QCOM_RPM_PM8058_LDO22 43 -+#define QCOM_RPM_PM8058_LDO23 44 -+#define QCOM_RPM_PM8058_LDO24 45 -+#define QCOM_RPM_PM8058_LDO25 46 -+#define QCOM_RPM_PM8058_LVS0 47 -+#define QCOM_RPM_PM8058_LVS1 48 -+#define QCOM_RPM_PM8058_NCP 49 -+#define QCOM_RPM_PM8058_SMPS0 50 -+#define QCOM_RPM_PM8058_SMPS1 51 -+#define QCOM_RPM_PM8058_SMPS2 52 -+#define QCOM_RPM_PM8058_SMPS3 53 -+#define QCOM_RPM_PM8058_SMPS4 54 -+#define QCOM_RPM_PM8821_LDO1 55 -+#define QCOM_RPM_PM8821_SMPS1 56 -+#define QCOM_RPM_PM8821_SMPS2 57 -+#define QCOM_RPM_PM8901_LDO0 58 -+#define QCOM_RPM_PM8901_LDO1 59 -+#define QCOM_RPM_PM8901_LDO2 60 -+#define QCOM_RPM_PM8901_LDO3 61 -+#define QCOM_RPM_PM8901_LDO4 62 -+#define QCOM_RPM_PM8901_LDO5 63 -+#define QCOM_RPM_PM8901_LDO6 64 -+#define QCOM_RPM_PM8901_LVS0 65 -+#define QCOM_RPM_PM8901_LVS1 66 -+#define QCOM_RPM_PM8901_LVS2 67 -+#define QCOM_RPM_PM8901_LVS3 68 -+#define QCOM_RPM_PM8901_MVS 69 -+#define QCOM_RPM_PM8901_SMPS0 70 -+#define QCOM_RPM_PM8901_SMPS1 71 -+#define QCOM_RPM_PM8901_SMPS2 72 -+#define QCOM_RPM_PM8901_SMPS3 73 -+#define QCOM_RPM_PM8901_SMPS4 74 -+#define QCOM_RPM_PM8921_CLK1 75 -+#define QCOM_RPM_PM8921_CLK2 76 -+#define QCOM_RPM_PM8921_LDO1 77 -+#define QCOM_RPM_PM8921_LDO2 78 -+#define QCOM_RPM_PM8921_LDO3 79 -+#define QCOM_RPM_PM8921_LDO4 80 -+#define QCOM_RPM_PM8921_LDO5 81 -+#define QCOM_RPM_PM8921_LDO6 82 -+#define QCOM_RPM_PM8921_LDO7 83 -+#define QCOM_RPM_PM8921_LDO8 84 -+#define QCOM_RPM_PM8921_LDO9 85 -+#define QCOM_RPM_PM8921_LDO10 86 -+#define QCOM_RPM_PM8921_LDO11 87 -+#define QCOM_RPM_PM8921_LDO12 88 -+#define QCOM_RPM_PM8921_LDO13 89 -+#define QCOM_RPM_PM8921_LDO14 90 -+#define QCOM_RPM_PM8921_LDO15 91 -+#define QCOM_RPM_PM8921_LDO16 92 -+#define QCOM_RPM_PM8921_LDO17 93 -+#define QCOM_RPM_PM8921_LDO18 94 -+#define QCOM_RPM_PM8921_LDO19 95 -+#define QCOM_RPM_PM8921_LDO20 96 -+#define QCOM_RPM_PM8921_LDO21 97 -+#define QCOM_RPM_PM8921_LDO22 98 -+#define QCOM_RPM_PM8921_LDO23 99 -+#define QCOM_RPM_PM8921_LDO24 100 -+#define QCOM_RPM_PM8921_LDO25 101 -+#define QCOM_RPM_PM8921_LDO26 102 -+#define QCOM_RPM_PM8921_LDO27 103 -+#define QCOM_RPM_PM8921_LDO28 104 -+#define QCOM_RPM_PM8921_LDO29 105 -+#define QCOM_RPM_PM8921_LVS1 106 -+#define QCOM_RPM_PM8921_LVS2 107 -+#define QCOM_RPM_PM8921_LVS3 108 -+#define QCOM_RPM_PM8921_LVS4 109 -+#define QCOM_RPM_PM8921_LVS5 110 -+#define QCOM_RPM_PM8921_LVS6 111 -+#define QCOM_RPM_PM8921_LVS7 112 -+#define QCOM_RPM_PM8921_MVS 113 -+#define QCOM_RPM_PM8921_NCP 114 -+#define QCOM_RPM_PM8921_SMPS1 115 -+#define QCOM_RPM_PM8921_SMPS2 116 -+#define QCOM_RPM_PM8921_SMPS3 117 -+#define QCOM_RPM_PM8921_SMPS4 118 -+#define QCOM_RPM_PM8921_SMPS5 119 -+#define QCOM_RPM_PM8921_SMPS6 120 -+#define QCOM_RPM_PM8921_SMPS7 121 -+#define QCOM_RPM_PM8921_SMPS8 122 -+#define QCOM_RPM_PXO_CLK 123 -+#define QCOM_RPM_QDSS_CLK 124 -+#define QCOM_RPM_SFPB_CLK 125 -+#define QCOM_RPM_SMI_CLK 126 -+#define QCOM_RPM_SYS_FABRIC_ARB 127 -+#define QCOM_RPM_SYS_FABRIC_CLK 128 -+#define QCOM_RPM_SYS_FABRIC_HALT 129 -+#define QCOM_RPM_SYS_FABRIC_IOCTL 130 -+#define QCOM_RPM_SYS_FABRIC_MODE 131 -+#define QCOM_RPM_USB_OTG_SWITCH 132 -+#define QCOM_RPM_VDDMIN_GPIO 133 -+ -+/* -+ * Constants used to select force mode for regulators. -+ */ -+#define QCOM_RPM_FORCE_MODE_NONE 0 -+#define QCOM_RPM_FORCE_MODE_LPM 1 -+#define QCOM_RPM_FORCE_MODE_HPM 2 -+#define QCOM_RPM_FORCE_MODE_AUTO 3 -+#define QCOM_RPM_FORCE_MODE_BYPASS 4 -+ -+#endif diff --git a/target/linux/ipq806x/patches-3.18/123-mfd-devicetree-qcom_rpm-Document-IPQ8064-resources.patch b/target/linux/ipq806x/patches-3.18/123-mfd-devicetree-qcom_rpm-Document-IPQ8064-resources.patch deleted file mode 100644 index c8a9f3f5d0..0000000000 --- a/target/linux/ipq806x/patches-3.18/123-mfd-devicetree-qcom_rpm-Document-IPQ8064-resources.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 30bc3aa5c4ed3072bdff7d915772df1b91307ed4 Mon Sep 17 00:00:00 2001 -From: Josh Cartwright -Date: Thu, 26 Mar 2015 11:29:25 -0700 -Subject: [PATCH] mfd: devicetree: qcom_rpm: Document IPQ8064 resources - -The IPQ8064 SoC has several RPM-controlled resources, an NSS fabrick -clock and four regulator resources. Provide definitions for them. - -Signed-off-by: Josh Cartwright -[sboyd@codeaurora.org: Drop regulator part of binding] -Signed-off-by: Stephen Boyd -Signed-off-by: Lee Jones ---- - Documentation/devicetree/bindings/mfd/qcom-rpm.txt | 1 + - include/dt-bindings/mfd/qcom-rpm.h | 6 ++++++ - 2 files changed, 7 insertions(+) - ---- a/Documentation/devicetree/bindings/mfd/qcom-rpm.txt -+++ b/Documentation/devicetree/bindings/mfd/qcom-rpm.txt -@@ -12,6 +12,7 @@ frequencies. - "qcom,rpm-apq8064" - "qcom,rpm-msm8660" - "qcom,rpm-msm8960" -+ "qcom,rpm-ipq8064" - - - reg: - Usage: required ---- a/include/dt-bindings/mfd/qcom-rpm.h -+++ b/include/dt-bindings/mfd/qcom-rpm.h -@@ -141,6 +141,12 @@ - #define QCOM_RPM_SYS_FABRIC_MODE 131 - #define QCOM_RPM_USB_OTG_SWITCH 132 - #define QCOM_RPM_VDDMIN_GPIO 133 -+#define QCOM_RPM_NSS_FABRIC_0_CLK 134 -+#define QCOM_RPM_NSS_FABRIC_1_CLK 135 -+#define QCOM_RPM_SMB208_S1a 136 -+#define QCOM_RPM_SMB208_S1b 137 -+#define QCOM_RPM_SMB208_S2a 138 -+#define QCOM_RPM_SMB208_S2b 139 - - /* - * Constants used to select force mode for regulators. diff --git a/target/linux/ipq806x/patches-3.18/124-regulator-rpm-add-support-for-RPM-controller-SMB208.patch b/target/linux/ipq806x/patches-3.18/124-regulator-rpm-add-support-for-RPM-controller-SMB208.patch deleted file mode 100644 index e4f094c213..0000000000 --- a/target/linux/ipq806x/patches-3.18/124-regulator-rpm-add-support-for-RPM-controller-SMB208.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 0f5bb5b5de3b18877373f746bdb85d8ea0efeedf Mon Sep 17 00:00:00 2001 -From: Josh Cartwright -Date: Thu, 20 Nov 2014 13:41:25 -0600 -Subject: [PATCH] regulator: rpm: add support for RPM-controller SMB208 - -The IPQ8064 reference boards make use of SMB208 regulators which are -controlled by RPM. Implement support for these regulators in the RPM -regulator driver. - -Signed-off-by: Josh Cartwright -Acked-by: Bjorn Andersson -Signed-off-by: Mark Brown ---- - drivers/regulator/qcom_rpm-regulator.c | 19 +++++++++++++++++++ - 1 file changed, 19 insertions(+) - ---- a/drivers/regulator/qcom_rpm-regulator.c -+++ b/drivers/regulator/qcom_rpm-regulator.c -@@ -183,6 +183,13 @@ static const struct regulator_linear_ran - REGULATOR_LINEAR_RANGE(1500000, 64, 100, 50000), - }; - -+static const struct regulator_linear_range smb208_ranges[] = { -+ REGULATOR_LINEAR_RANGE( 375000, 0, 29, 12500), -+ REGULATOR_LINEAR_RANGE( 750000, 30, 89, 12500), -+ REGULATOR_LINEAR_RANGE(1500000, 90, 153, 25000), -+ REGULATOR_LINEAR_RANGE(3100000, 154, 234, 25000), -+}; -+ - static const struct regulator_linear_range ncp_ranges[] = { - REGULATOR_LINEAR_RANGE(1500000, 0, 31, 50000), - }; -@@ -559,6 +566,16 @@ static const struct qcom_rpm_reg pm8921_ - .parts = &rpm8960_switch_parts, - }; - -+static const struct qcom_rpm_reg smb208_smps = { -+ .desc.linear_ranges = smb208_ranges, -+ .desc.n_linear_ranges = ARRAY_SIZE(smb208_ranges), -+ .desc.n_voltages = 235, -+ .desc.ops = &uV_ops, -+ .parts = &rpm8960_smps_parts, -+ .supports_force_mode_auto = false, -+ .supports_force_mode_bypass = false, -+}; -+ - static const struct of_device_id rpm_of_match[] = { - { .compatible = "qcom,rpm-pm8058-pldo", .data = &pm8058_pldo }, - { .compatible = "qcom,rpm-pm8058-nldo", .data = &pm8058_nldo }, -@@ -578,6 +595,8 @@ static const struct of_device_id rpm_of_ - { .compatible = "qcom,rpm-pm8921-ftsmps", .data = &pm8921_ftsmps }, - { .compatible = "qcom,rpm-pm8921-ncp", .data = &pm8921_ncp }, - { .compatible = "qcom,rpm-pm8921-switch", .data = &pm8921_switch }, -+ -+ { .compatible = "qcom,rpm-smb208", .data = &smb208_smps }, - { } - }; - MODULE_DEVICE_TABLE(of, rpm_of_match); diff --git a/target/linux/ipq806x/patches-3.18/125-regulator-qcom-rpm-Add-missing-state-flag-in-call-to.patch b/target/linux/ipq806x/patches-3.18/125-regulator-qcom-rpm-Add-missing-state-flag-in-call-to.patch deleted file mode 100644 index 48921a8429..0000000000 --- a/target/linux/ipq806x/patches-3.18/125-regulator-qcom-rpm-Add-missing-state-flag-in-call-to.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 803926825fa4db007437f76654e3e63bafb9b906 Mon Sep 17 00:00:00 2001 -From: Bjorn Andersson -Date: Wed, 26 Nov 2014 13:51:01 -0800 -Subject: [PATCH] regulator: qcom-rpm: Add missing state flag in call to RPM - -This adds the missing state parameter to the call down to the RPM. This -is currently hard coded to the active state, as that's all we're -supporting at this moment. - -Signed-off-by: Bjorn Andersson -Signed-off-by: Lee Jones ---- - drivers/regulator/qcom_rpm-regulator.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/regulator/qcom_rpm-regulator.c -+++ b/drivers/regulator/qcom_rpm-regulator.c -@@ -205,6 +205,7 @@ static int rpm_reg_write(struct qcom_rpm - vreg->val[req->word] |= value << req->shift; - - return qcom_rpm_write(vreg->rpm, -+ QCOM_RPM_ACTIVE_STATE, - vreg->resource, - vreg->val, - vreg->parts->request_len); diff --git a/target/linux/ipq806x/patches-3.18/126-add-rpm-to-ipq8064-dts.patch b/target/linux/ipq806x/patches-3.18/126-add-rpm-to-ipq8064-dts.patch deleted file mode 100644 index 7e4c5cb1f6..0000000000 --- a/target/linux/ipq806x/patches-3.18/126-add-rpm-to-ipq8064-dts.patch +++ /dev/null @@ -1,87 +0,0 @@ ---- a/arch/arm/boot/dts/qcom-ipq8064.dtsi -+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi -@@ -2,6 +2,7 @@ - - #include "skeleton.dtsi" - #include -+#include - #include - #include - #include -@@ -76,6 +77,63 @@ - ranges; - compatible = "simple-bus"; - -+ rpm@108000 { -+ compatible = "qcom,rpm-ipq8064"; -+ reg = <0x108000 0x1000>; -+ qcom,ipc = <&l2cc 0x8 2>; -+ -+ interrupts = <0 19 0>, -+ <0 21 0>, -+ <0 22 0>; -+ interrupt-names = "ack", -+ "err", -+ "wakeup"; -+ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ smb208_s1a: smb208-s1a { -+ compatible = "qcom,rpm-smb208"; -+ reg = ; -+ -+ regulator-min-microvolt = <1050000>; -+ regulator-max-microvolt = <1150000>; -+ -+ qcom,switch-mode-frequency = <1200000>; -+ -+ }; -+ -+ smb208_s1b: smb208-s1b { -+ compatible = "qcom,rpm-smb208"; -+ reg = ; -+ -+ regulator-min-microvolt = <1050000>; -+ regulator-max-microvolt = <1150000>; -+ -+ qcom,switch-mode-frequency = <1200000>; -+ }; -+ -+ smb208_s2a: smb208-s2a { -+ compatible = "qcom,rpm-smb208"; -+ reg = ; -+ -+ regulator-min-microvolt = < 800000>; -+ regulator-max-microvolt = <1250000>; -+ -+ qcom,switch-mode-frequency = <1200000>; -+ }; -+ -+ smb208_s2b: smb208-s2b { -+ compatible = "qcom,rpm-smb208"; -+ reg = ; -+ -+ regulator-min-microvolt = < 800000>; -+ regulator-max-microvolt = <1250000>; -+ -+ qcom,switch-mode-frequency = <1200000>; -+ }; -+ }; -+ - qcom_pinmux: pinmux@800000 { - compatible = "qcom,ipq8064-pinctrl"; - reg = <0x800000 0x4000>; -@@ -120,6 +178,12 @@ - reg = <0x02098000 0x1000>, <0x02008000 0x1000>; - }; - -+ l2cc: clock-controller@2011000 { -+ compatible = "qcom,kpss-gcc", "syscon"; -+ reg = <0x2011000 0x1000>; -+ clock-output-names = "acpu_l2_aux"; -+ }; -+ - saw0: regulator@2089000 { - compatible = "qcom,saw2"; - reg = <0x02089000 0x1000>, <0x02009000 0x1000>; diff --git a/target/linux/ipq806x/patches-3.18/130-clk_mux-Fix-set_parent-doing-the-wrong-thing-when-IN.patch b/target/linux/ipq806x/patches-3.18/130-clk_mux-Fix-set_parent-doing-the-wrong-thing-when-IN.patch deleted file mode 100644 index 29f74b760d..0000000000 --- a/target/linux/ipq806x/patches-3.18/130-clk_mux-Fix-set_parent-doing-the-wrong-thing-when-IN.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 6793b3cd5da817c4be218bd8632f07cf4d2b0d26 Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Wed, 19 Nov 2014 14:48:59 +0100 -Subject: [PATCH] clk_mux: Fix set_parent doing the wrong thing when INDEX_BIT - && index >= 3 - -If CLK_MUX_INDEX_BIT is set, then each bit turns on / off a single parent, -so theoretically multiple parents could be enabled at the same time, but in -practice only one bit should ever be 1. So to select parent 0, set -the register (*) to 0x01, to select parent 1 set it 0x02, parent 2, 0x04, -parent 3, 0x08, etc. - -But the current code does: - - if (mux->flags & CLK_MUX_INDEX_BIT) - index = (1 << ffs(index)); - -Which means that: - -For an input index of 0, ffs returns 0, so we set the register -to 0x01, ok. - -For an input index of 1, ffs returns 1, so we set the register -to 0x02, ok. - -For an input index of 2, ffs returns 2, so we set the register -to 0x04, ok. - -For an input index of 3, ffs returns 1, so we set the register -to 0x02, not good! - -The code should simply be: - - if (mux->flags & CLK_MUX_INDEX_BIT) - index = 1 << index; - -Which always does the right thing, this commit fixes this. - -Signed-off-by: Hans de Goede -Signed-off-by: Michael Turquette ---- - drivers/clk/clk-mux.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/clk/clk-mux.c -+++ b/drivers/clk/clk-mux.c -@@ -77,7 +77,7 @@ static int clk_mux_set_parent(struct clk - - else { - if (mux->flags & CLK_MUX_INDEX_BIT) -- index = (1 << ffs(index)); -+ index = 1 << index; - - if (mux->flags & CLK_MUX_INDEX_ONE) - index++; diff --git a/target/linux/ipq806x/patches-3.18/131-clk-Add-__clk_mux_determine_rate_closest.patch b/target/linux/ipq806x/patches-3.18/131-clk-Add-__clk_mux_determine_rate_closest.patch deleted file mode 100644 index 18972f3537..0000000000 --- a/target/linux/ipq806x/patches-3.18/131-clk-Add-__clk_mux_determine_rate_closest.patch +++ /dev/null @@ -1,120 +0,0 @@ -From 15a02c1f6dd7c2bb150c61d00ffb33f584ff2288 Mon Sep 17 00:00:00 2001 -From: Stephen Boyd -Date: Mon, 19 Jan 2015 18:05:28 -0800 -Subject: [PATCH] clk: Add __clk_mux_determine_rate_closest - -Some clock drivers want to find the closest rate on the input of -a mux instead of a rate that's less than or equal to the desired -rate. Add a generic mux function to support this. - -Signed-off-by: Stephen Boyd -Tested-by: Kenneth Westfield -Signed-off-by: Michael Turquette ---- - drivers/clk/clk.c | 47 +++++++++++++++++++++++++++++++++++--------- - include/linux/clk-provider.h | 8 +++++++- - 2 files changed, 45 insertions(+), 10 deletions(-) - ---- a/drivers/clk/clk.c -+++ b/drivers/clk/clk.c -@@ -695,14 +695,20 @@ struct clk *__clk_lookup(const char *nam - return NULL; - } - --/* -- * Helper for finding best parent to provide a given frequency. This can be used -- * directly as a determine_rate callback (e.g. for a mux), or from a more -- * complex clock that may combine a mux with other operations. -- */ --long __clk_mux_determine_rate(struct clk_hw *hw, unsigned long rate, -- unsigned long *best_parent_rate, -- struct clk **best_parent_p) -+static bool mux_is_better_rate(unsigned long rate, unsigned long now, -+ unsigned long best, unsigned long flags) -+{ -+ if (flags & CLK_MUX_ROUND_CLOSEST) -+ return abs(now - rate) < abs(best - rate); -+ -+ return now <= rate && now > best; -+} -+ -+static long -+clk_mux_determine_rate_flags(struct clk_hw *hw, unsigned long rate, -+ unsigned long *best_parent_rate, -+ struct clk **best_parent_p, -+ unsigned long flags) - { - struct clk *clk = hw->clk, *parent, *best_parent = NULL; - int i, num_parents; -@@ -730,7 +736,7 @@ long __clk_mux_determine_rate(struct clk - parent_rate = __clk_round_rate(parent, rate); - else - parent_rate = __clk_get_rate(parent); -- if (parent_rate <= rate && parent_rate > best) { -+ if (mux_is_better_rate(rate, parent_rate, best, flags)) { - best_parent = parent; - best = parent_rate; - } -@@ -743,8 +749,31 @@ out: - - return best; - } -+ -+/* -+ * Helper for finding best parent to provide a given frequency. This can be used -+ * directly as a determine_rate callback (e.g. for a mux), or from a more -+ * complex clock that may combine a mux with other operations. -+ */ -+long __clk_mux_determine_rate(struct clk_hw *hw, unsigned long rate, -+ unsigned long *best_parent_rate, -+ struct clk **best_parent_p) -+{ -+ return clk_mux_determine_rate_flags(hw, rate, best_parent_rate, -+ best_parent_p, 0); -+} - EXPORT_SYMBOL_GPL(__clk_mux_determine_rate); - -+long __clk_mux_determine_rate_closest(struct clk_hw *hw, unsigned long rate, -+ unsigned long *best_parent_rate, -+ struct clk **best_parent_p) -+{ -+ return clk_mux_determine_rate_flags(hw, rate, best_parent_rate, -+ best_parent_p, -+ CLK_MUX_ROUND_CLOSEST); -+} -+EXPORT_SYMBOL_GPL(__clk_mux_determine_rate_closest); -+ - /*** clk api ***/ - - void __clk_unprepare(struct clk *clk) ---- a/include/linux/clk-provider.h -+++ b/include/linux/clk-provider.h -@@ -382,6 +382,8 @@ struct clk *clk_register_divider_table(s - * register, and mask of mux bits are in higher 16-bit of this register. - * While setting the mux bits, higher 16-bit should also be updated to - * indicate changing mux bits. -+ * CLK_MUX_ROUND_CLOSEST - Use the parent rate that is closest to the desired -+ * frequency. - */ - struct clk_mux { - struct clk_hw hw; -@@ -396,7 +398,8 @@ struct clk_mux { - #define CLK_MUX_INDEX_ONE BIT(0) - #define CLK_MUX_INDEX_BIT BIT(1) - #define CLK_MUX_HIWORD_MASK BIT(2) --#define CLK_MUX_READ_ONLY BIT(3) /* mux setting cannot be changed */ -+#define CLK_MUX_READ_ONLY BIT(3) /* mux can't be changed */ -+#define CLK_MUX_ROUND_CLOSEST BIT(4) - - extern const struct clk_ops clk_mux_ops; - extern const struct clk_ops clk_mux_ro_ops; -@@ -554,6 +557,9 @@ struct clk *__clk_lookup(const char *nam - long __clk_mux_determine_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *best_parent_rate, - struct clk **best_parent_p); -+long __clk_mux_determine_rate_closest(struct clk_hw *hw, unsigned long rate, -+ unsigned long *best_parent_rate, -+ struct clk **best_parent_p); - - /* - * FIXME clock api without lock protection diff --git a/target/linux/ipq806x/patches-3.18/132-clk-Add-clk_unregister_-divider-gate-mux-to-close-me.patch b/target/linux/ipq806x/patches-3.18/132-clk-Add-clk_unregister_-divider-gate-mux-to-close-me.patch deleted file mode 100644 index 790f25d28d..0000000000 --- a/target/linux/ipq806x/patches-3.18/132-clk-Add-clk_unregister_-divider-gate-mux-to-close-me.patch +++ /dev/null @@ -1,115 +0,0 @@ -From 4e3c021fb995bcbb5d1f814d00584cb80eb904a8 Mon Sep 17 00:00:00 2001 -From: Krzysztof Kozlowski -Date: Mon, 5 Jan 2015 10:52:40 +0100 -Subject: [PATCH] clk: Add clk_unregister_{divider, gate, mux} to close memory - leak - -The common clk_register_{divider,gate,mux} functions allocated memory -for internal data which wasn't freed anywhere. Drivers using these -helpers could only unregister clocks but the memory would still leak. - -Add corresponding unregister functions which will release all resources. - -Signed-off-by: Krzysztof Kozlowski -Reviewed-by: Stephen Boyd -Signed-off-by: Michael Turquette ---- - drivers/clk/clk-divider.c | 16 ++++++++++++++++ - drivers/clk/clk-gate.c | 16 ++++++++++++++++ - drivers/clk/clk-mux.c | 16 ++++++++++++++++ - include/linux/clk-provider.h | 4 ++++ - 4 files changed, 52 insertions(+) - ---- a/drivers/clk/clk-divider.c -+++ b/drivers/clk/clk-divider.c -@@ -461,3 +461,19 @@ struct clk *clk_register_divider_table(s - width, clk_divider_flags, table, lock); - } - EXPORT_SYMBOL_GPL(clk_register_divider_table); -+ -+void clk_unregister_divider(struct clk *clk) -+{ -+ struct clk_divider *div; -+ struct clk_hw *hw; -+ -+ hw = __clk_get_hw(clk); -+ if (!hw) -+ return; -+ -+ div = to_clk_divider(hw); -+ -+ clk_unregister(clk); -+ kfree(div); -+} -+EXPORT_SYMBOL_GPL(clk_unregister_divider); ---- a/drivers/clk/clk-gate.c -+++ b/drivers/clk/clk-gate.c -@@ -162,3 +162,19 @@ struct clk *clk_register_gate(struct dev - return clk; - } - EXPORT_SYMBOL_GPL(clk_register_gate); -+ -+void clk_unregister_gate(struct clk *clk) -+{ -+ struct clk_gate *gate; -+ struct clk_hw *hw; -+ -+ hw = __clk_get_hw(clk); -+ if (!hw) -+ return; -+ -+ gate = to_clk_gate(hw); -+ -+ clk_unregister(clk); -+ kfree(gate); -+} -+EXPORT_SYMBOL_GPL(clk_unregister_gate); ---- a/drivers/clk/clk-mux.c -+++ b/drivers/clk/clk-mux.c -@@ -177,3 +177,19 @@ struct clk *clk_register_mux(struct devi - NULL, lock); - } - EXPORT_SYMBOL_GPL(clk_register_mux); -+ -+void clk_unregister_mux(struct clk *clk) -+{ -+ struct clk_mux *mux; -+ struct clk_hw *hw; -+ -+ hw = __clk_get_hw(clk); -+ if (!hw) -+ return; -+ -+ mux = to_clk_mux(hw); -+ -+ clk_unregister(clk); -+ kfree(mux); -+} -+EXPORT_SYMBOL_GPL(clk_unregister_mux); ---- a/include/linux/clk-provider.h -+++ b/include/linux/clk-provider.h -@@ -294,6 +294,7 @@ struct clk *clk_register_gate(struct dev - const char *parent_name, unsigned long flags, - void __iomem *reg, u8 bit_idx, - u8 clk_gate_flags, spinlock_t *lock); -+void clk_unregister_gate(struct clk *clk); - - struct clk_div_table { - unsigned int val; -@@ -361,6 +362,7 @@ struct clk *clk_register_divider_table(s - void __iomem *reg, u8 shift, u8 width, - u8 clk_divider_flags, const struct clk_div_table *table, - spinlock_t *lock); -+void clk_unregister_divider(struct clk *clk); - - /** - * struct clk_mux - multiplexer clock -@@ -414,6 +416,8 @@ struct clk *clk_register_mux_table(struc - void __iomem *reg, u8 shift, u32 mask, - u8 clk_mux_flags, u32 *table, spinlock_t *lock); - -+void clk_unregister_mux(struct clk *clk); -+ - void of_fixed_factor_clk_setup(struct device_node *node); - - /** diff --git a/target/linux/ipq806x/patches-3.18/133-ARM-Add-Krait-L2-register-accessor-functions.patch b/target/linux/ipq806x/patches-3.18/133-ARM-Add-Krait-L2-register-accessor-functions.patch deleted file mode 100644 index 36a92c858a..0000000000 --- a/target/linux/ipq806x/patches-3.18/133-ARM-Add-Krait-L2-register-accessor-functions.patch +++ /dev/null @@ -1,144 +0,0 @@ -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [v3,01/13] ARM: Add Krait L2 register accessor functions -From: Stephen Boyd -X-Patchwork-Id: 6063051 -Message-Id: <1426920332-9340-2-git-send-email-sboyd@codeaurora.org> -To: Mike Turquette , Stephen Boyd -Cc: linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, - linux-pm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, - Viresh Kumar , - Mark Rutland , Russell King , - Courtney Cavin -Date: Fri, 20 Mar 2015 23:45:20 -0700 - -Krait CPUs have a handful of L2 cache controller registers that -live behind a cp15 based indirection register. First you program -the indirection register (l2cpselr) to point the L2 'window' -register (l2cpdr) at what you want to read/write. Then you -read/write the 'window' register to do what you want. The -l2cpselr register is not banked per-cpu so we must lock around -accesses to it to prevent other CPUs from re-pointing l2cpdr -underneath us. - -Cc: Mark Rutland -Cc: Russell King -Cc: Courtney Cavin -Signed-off-by: Stephen Boyd - ---- -arch/arm/common/Kconfig | 3 ++ - arch/arm/common/Makefile | 1 + - arch/arm/common/krait-l2-accessors.c | 58 +++++++++++++++++++++++++++++++ - arch/arm/include/asm/krait-l2-accessors.h | 20 +++++++++++ - 4 files changed, 82 insertions(+) - create mode 100644 arch/arm/common/krait-l2-accessors.c - create mode 100644 arch/arm/include/asm/krait-l2-accessors.h - ---- a/arch/arm/common/Kconfig -+++ b/arch/arm/common/Kconfig -@@ -9,6 +9,9 @@ config DMABOUNCE - bool - select ZONE_DMA - -+config KRAIT_L2_ACCESSORS -+ bool -+ - config SHARP_LOCOMO - bool - ---- a/arch/arm/common/Makefile -+++ b/arch/arm/common/Makefile -@@ -7,6 +7,7 @@ obj-y += firmware.o - obj-$(CONFIG_ICST) += icst.o - obj-$(CONFIG_SA1111) += sa1111.o - obj-$(CONFIG_DMABOUNCE) += dmabounce.o -+obj-$(CONFIG_KRAIT_L2_ACCESSORS) += krait-l2-accessors.o - obj-$(CONFIG_SHARP_LOCOMO) += locomo.o - obj-$(CONFIG_SHARP_PARAM) += sharpsl_param.o - obj-$(CONFIG_SHARP_SCOOP) += scoop.o ---- /dev/null -+++ b/arch/arm/common/krait-l2-accessors.c -@@ -0,0 +1,58 @@ -+/* -+ * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 and -+ * only version 2 as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include -+#include -+ -+#include -+#include -+ -+static DEFINE_RAW_SPINLOCK(krait_l2_lock); -+ -+void krait_set_l2_indirect_reg(u32 addr, u32 val) -+{ -+ unsigned long flags; -+ -+ raw_spin_lock_irqsave(&krait_l2_lock, flags); -+ /* -+ * Select the L2 window by poking l2cpselr, then write to the window -+ * via l2cpdr. -+ */ -+ asm volatile ("mcr p15, 3, %0, c15, c0, 6 @ l2cpselr" : : "r" (addr)); -+ isb(); -+ asm volatile ("mcr p15, 3, %0, c15, c0, 7 @ l2cpdr" : : "r" (val)); -+ isb(); -+ -+ raw_spin_unlock_irqrestore(&krait_l2_lock, flags); -+} -+EXPORT_SYMBOL(krait_set_l2_indirect_reg); -+ -+u32 krait_get_l2_indirect_reg(u32 addr) -+{ -+ u32 val; -+ unsigned long flags; -+ -+ raw_spin_lock_irqsave(&krait_l2_lock, flags); -+ /* -+ * Select the L2 window by poking l2cpselr, then read from the window -+ * via l2cpdr. -+ */ -+ asm volatile ("mcr p15, 3, %0, c15, c0, 6 @ l2cpselr" : : "r" (addr)); -+ isb(); -+ asm volatile ("mrc p15, 3, %0, c15, c0, 7 @ l2cpdr" : "=r" (val)); -+ -+ raw_spin_unlock_irqrestore(&krait_l2_lock, flags); -+ -+ return val; -+} -+EXPORT_SYMBOL(krait_get_l2_indirect_reg); ---- /dev/null -+++ b/arch/arm/include/asm/krait-l2-accessors.h -@@ -0,0 +1,20 @@ -+/* -+ * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 and -+ * only version 2 as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef __ASMARM_KRAIT_L2_ACCESSORS_H -+#define __ASMARM_KRAIT_L2_ACCESSORS_H -+ -+extern void krait_set_l2_indirect_reg(u32 addr, u32 val); -+extern u32 krait_get_l2_indirect_reg(u32 addr); -+ -+#endif diff --git a/target/linux/ipq806x/patches-3.18/134-clk-mux-Split-out-register-accessors-for-reuse.patch b/target/linux/ipq806x/patches-3.18/134-clk-mux-Split-out-register-accessors-for-reuse.patch deleted file mode 100644 index 50022e6107..0000000000 --- a/target/linux/ipq806x/patches-3.18/134-clk-mux-Split-out-register-accessors-for-reuse.patch +++ /dev/null @@ -1,192 +0,0 @@ -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [v3,02/13] clk: mux: Split out register accessors for reuse -From: Stephen Boyd -X-Patchwork-Id: 6063111 -Message-Id: <1426920332-9340-3-git-send-email-sboyd@codeaurora.org> -To: Mike Turquette , Stephen Boyd -Cc: linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, - linux-pm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, - Viresh Kumar -Date: Fri, 20 Mar 2015 23:45:21 -0700 - -We want to reuse the logic in clk-mux.c for other clock drivers -that don't use readl as register accessors. Fortunately, there -really isn't much to the mux code besides the table indirection -and quirk flags if you assume any bit shifting and masking has -been done already. Pull that logic out into reusable functions -that operate on an optional table and some flags so that other -drivers can use the same logic. - -Signed-off-by: Stephen Boyd - ---- -drivers/clk/clk-mux.c | 76 +++++++++++++++++++++++++++----------------- - include/linux/clk-provider.h | 9 ++++-- - 2 files changed, 54 insertions(+), 31 deletions(-) - ---- a/drivers/clk/clk-mux.c -+++ b/drivers/clk/clk-mux.c -@@ -29,35 +29,24 @@ - - #define to_clk_mux(_hw) container_of(_hw, struct clk_mux, hw) - --static u8 clk_mux_get_parent(struct clk_hw *hw) -+unsigned int clk_mux_get_parent(struct clk_hw *hw, unsigned int val, -+ unsigned int *table, unsigned long flags) - { -- struct clk_mux *mux = to_clk_mux(hw); - int num_parents = __clk_get_num_parents(hw->clk); -- u32 val; - -- /* -- * FIXME need a mux-specific flag to determine if val is bitwise or numeric -- * e.g. sys_clkin_ck's clksel field is 3 bits wide, but ranges from 0x1 -- * to 0x7 (index starts at one) -- * OTOH, pmd_trace_clk_mux_ck uses a separate bit for each clock, so -- * val = 0x4 really means "bit 2, index starts at bit 0" -- */ -- val = clk_readl(mux->reg) >> mux->shift; -- val &= mux->mask; -- -- if (mux->table) { -+ if (table) { - int i; - - for (i = 0; i < num_parents; i++) -- if (mux->table[i] == val) -+ if (table[i] == val) - return i; - return -EINVAL; - } - -- if (val && (mux->flags & CLK_MUX_INDEX_BIT)) -+ if (val && (flags & CLK_MUX_INDEX_BIT)) - val = ffs(val) - 1; - -- if (val && (mux->flags & CLK_MUX_INDEX_ONE)) -+ if (val && (flags & CLK_MUX_INDEX_ONE)) - val--; - - if (val >= num_parents) -@@ -65,24 +54,53 @@ static u8 clk_mux_get_parent(struct clk_ - - return val; - } -+EXPORT_SYMBOL_GPL(clk_mux_get_parent); - --static int clk_mux_set_parent(struct clk_hw *hw, u8 index) -+static u8 _clk_mux_get_parent(struct clk_hw *hw) - { - struct clk_mux *mux = to_clk_mux(hw); - u32 val; -- unsigned long flags = 0; - -- if (mux->table) -- index = mux->table[index]; -+ /* -+ * FIXME need a mux-specific flag to determine if val is bitwise or numeric -+ * e.g. sys_clkin_ck's clksel field is 3 bits wide, but ranges from 0x1 -+ * to 0x7 (index starts at one) -+ * OTOH, pmd_trace_clk_mux_ck uses a separate bit for each clock, so -+ * val = 0x4 really means "bit 2, index starts at bit 0" -+ */ -+ val = clk_readl(mux->reg) >> mux->shift; -+ val &= mux->mask; -+ -+ return clk_mux_get_parent(hw, val, mux->table, mux->flags); -+} - -- else { -- if (mux->flags & CLK_MUX_INDEX_BIT) -- index = 1 << index; -+unsigned int clk_mux_reindex(u8 index, unsigned int *table, -+ unsigned long flags) -+{ -+ unsigned int val = index; - -- if (mux->flags & CLK_MUX_INDEX_ONE) -- index++; -+ if (table) { -+ val = table[val]; -+ } else { -+ if (flags & CLK_MUX_INDEX_BIT) -+ val = 1 << index; -+ -+ if (flags & CLK_MUX_INDEX_ONE) -+ val++; - } - -+ return val; -+} -+EXPORT_SYMBOL_GPL(clk_mux_reindex); -+ -+static int clk_mux_set_parent(struct clk_hw *hw, u8 index) -+{ -+ struct clk_mux *mux = to_clk_mux(hw); -+ u32 val; -+ unsigned long flags = 0; -+ -+ index = clk_mux_reindex(index, mux->table, mux->flags); -+ - if (mux->lock) - spin_lock_irqsave(mux->lock, flags); - -@@ -102,21 +120,21 @@ static int clk_mux_set_parent(struct clk - } - - const struct clk_ops clk_mux_ops = { -- .get_parent = clk_mux_get_parent, -+ .get_parent = _clk_mux_get_parent, - .set_parent = clk_mux_set_parent, - .determine_rate = __clk_mux_determine_rate, - }; - EXPORT_SYMBOL_GPL(clk_mux_ops); - - const struct clk_ops clk_mux_ro_ops = { -- .get_parent = clk_mux_get_parent, -+ .get_parent = _clk_mux_get_parent, - }; - EXPORT_SYMBOL_GPL(clk_mux_ro_ops); - - struct clk *clk_register_mux_table(struct device *dev, const char *name, - const char **parent_names, u8 num_parents, unsigned long flags, - void __iomem *reg, u8 shift, u32 mask, -- u8 clk_mux_flags, u32 *table, spinlock_t *lock) -+ u8 clk_mux_flags, unsigned int *table, spinlock_t *lock) - { - struct clk_mux *mux; - struct clk *clk; ---- a/include/linux/clk-provider.h -+++ b/include/linux/clk-provider.h -@@ -390,7 +390,7 @@ void clk_unregister_divider(struct clk * - struct clk_mux { - struct clk_hw hw; - void __iomem *reg; -- u32 *table; -+ unsigned int *table; - u32 mask; - u8 shift; - u8 flags; -@@ -406,6 +406,11 @@ struct clk_mux { - extern const struct clk_ops clk_mux_ops; - extern const struct clk_ops clk_mux_ro_ops; - -+unsigned int clk_mux_get_parent(struct clk_hw *hw, unsigned int val, -+ unsigned int *table, unsigned long flags); -+unsigned int clk_mux_reindex(u8 index, unsigned int *table, -+ unsigned long flags); -+ - struct clk *clk_register_mux(struct device *dev, const char *name, - const char **parent_names, u8 num_parents, unsigned long flags, - void __iomem *reg, u8 shift, u8 width, -@@ -414,7 +419,7 @@ struct clk *clk_register_mux(struct devi - struct clk *clk_register_mux_table(struct device *dev, const char *name, - const char **parent_names, u8 num_parents, unsigned long flags, - void __iomem *reg, u8 shift, u32 mask, -- u8 clk_mux_flags, u32 *table, spinlock_t *lock); -+ u8 clk_mux_flags, unsigned int *table, spinlock_t *lock); - - void clk_unregister_mux(struct clk *clk); - diff --git a/target/linux/ipq806x/patches-3.18/135-clk-Avoid-sending-high-rates-to-downstream-clocks-during-set_rate.patch b/target/linux/ipq806x/patches-3.18/135-clk-Avoid-sending-high-rates-to-downstream-clocks-during-set_rate.patch deleted file mode 100644 index 02d96ad08a..0000000000 --- a/target/linux/ipq806x/patches-3.18/135-clk-Avoid-sending-high-rates-to-downstream-clocks-during-set_rate.patch +++ /dev/null @@ -1,129 +0,0 @@ -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [v3, 03/13] clk: Avoid sending high rates to downstream clocks during - set_rate -From: Stephen Boyd -X-Patchwork-Id: 6063271 -Message-Id: <1426920332-9340-4-git-send-email-sboyd@codeaurora.org> -To: Mike Turquette , Stephen Boyd -Cc: linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, - linux-pm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, - Viresh Kumar -Date: Fri, 20 Mar 2015 23:45:22 -0700 - -If a clock is on and we call clk_set_rate() on it we may get into -a situation where the clock temporarily increases in rate -dramatically while we walk the tree and call .set_rate() ops. For -example, consider a case where a PLL feeds into a divider. -Initially the divider is set to divide by 1 and the PLL is -running fairly slow (100MHz). The downstream consumer of the -divider output can only handle rates =< 400 MHz, but the divider -can only choose between divisors of 1 and 4. - - +-----+ +----------------+ - | PLL |-->| div 1 or div 4 |---> consumer device - +-----+ +----------------+ - -To achieve a rate of 400MHz on the output of the divider, we -would have to set the rate of the PLL to 1.6 GHz and then divide -it by 4. The current code would set the PLL to 1.6GHz first while -the divider is still set to 1, thus causing the downstream -consumer of the clock to receive a few clock cycles of 1.6GHz -clock (far beyond it's maximum acceptable rate). We should be -changing the divider first before increasing the PLL rate to -avoid this problem. - -Therefore, set the rate of any child clocks that are increasing -in rate from their current rate so that they can increase their -dividers if necessary. We assume that there isn't such a thing as -minimum rate requirements. - -Signed-off-by: Stephen Boyd - ---- -drivers/clk/clk.c | 34 ++++++++++++++++++++++------------ - 1 file changed, 22 insertions(+), 12 deletions(-) - ---- a/drivers/clk/clk.c -+++ b/drivers/clk/clk.c -@@ -1476,21 +1476,23 @@ static struct clk *clk_propagate_rate_ch - * walk down a subtree and set the new rates notifying the rate - * change on the way - */ --static void clk_change_rate(struct clk *clk) -+static void clk_change_rate(struct clk *clk, unsigned long best_parent_rate) - { - struct clk *child; - struct hlist_node *tmp; - unsigned long old_rate; -- unsigned long best_parent_rate = 0; - bool skip_set_rate = false; - struct clk *old_parent; - -- old_rate = clk->rate; -+ hlist_for_each_entry(child, &clk->children, child_node) { -+ /* Skip children who will be reparented to another clock */ -+ if (child->new_parent && child->new_parent != clk) -+ continue; -+ if (child->new_rate > child->rate) -+ clk_change_rate(child, clk->new_rate); -+ } - -- if (clk->new_parent) -- best_parent_rate = clk->new_parent->rate; -- else if (clk->parent) -- best_parent_rate = clk->parent->rate; -+ old_rate = clk->rate; - - if (clk->new_parent && clk->new_parent != clk->parent) { - old_parent = __clk_set_parent_before(clk, clk->new_parent); -@@ -1510,7 +1512,7 @@ static void clk_change_rate(struct clk * - if (!skip_set_rate && clk->ops->set_rate) - clk->ops->set_rate(clk->hw, clk->new_rate, best_parent_rate); - -- clk->rate = clk_recalc(clk, best_parent_rate); -+ clk->rate = clk->new_rate; - - if (clk->notifier_count && old_rate != clk->rate) - __clk_notify(clk, POST_RATE_CHANGE, old_rate, clk->rate); -@@ -1523,12 +1525,13 @@ static void clk_change_rate(struct clk * - /* Skip children who will be reparented to another clock */ - if (child->new_parent && child->new_parent != clk) - continue; -- clk_change_rate(child); -+ if (child->new_rate != child->rate) -+ clk_change_rate(child, clk->new_rate); - } - - /* handle the new child who might not be in clk->children yet */ -- if (clk->new_child) -- clk_change_rate(clk->new_child); -+ if (clk->new_child && clk->new_child->new_rate != clk->new_child->rate) -+ clk_change_rate(clk->new_child, clk->new_rate); - } - - /** -@@ -1556,6 +1559,7 @@ int clk_set_rate(struct clk *clk, unsign - { - struct clk *top, *fail_clk; - int ret = 0; -+ unsigned long parent_rate; - - if (!clk) - return 0; -@@ -1589,8 +1593,13 @@ int clk_set_rate(struct clk *clk, unsign - goto out; - } - -+ if (top->parent) -+ parent_rate = top->parent->rate; -+ else -+ parent_rate = 0; -+ - /* change the rates */ -- clk_change_rate(top); -+ clk_change_rate(top, parent_rate); - - out: - clk_prepare_unlock(); diff --git a/target/linux/ipq806x/patches-3.18/136-clk-Add-safe-switch-hook.patch b/target/linux/ipq806x/patches-3.18/136-clk-Add-safe-switch-hook.patch deleted file mode 100644 index 227f8cea05..0000000000 --- a/target/linux/ipq806x/patches-3.18/136-clk-Add-safe-switch-hook.patch +++ /dev/null @@ -1,170 +0,0 @@ -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [v3,04/13] clk: Add safe switch hook -From: Stephen Boyd -X-Patchwork-Id: 6063211 -Message-Id: <1426920332-9340-5-git-send-email-sboyd@codeaurora.org> -To: Mike Turquette , Stephen Boyd -Cc: linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, - linux-pm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, - Viresh Kumar -Date: Fri, 20 Mar 2015 23:45:23 -0700 - -Sometimes clocks can't accept their parent source turning off -while the source is reprogrammed to a different rate. Most -notably CPU clocks require a way to switch away from the current -PLL they're running on, reprogram that PLL to a new rate, and -then switch back to the PLL with the new rate once they're done. -Add a hook that drivers can implement allowing them to return a -'safe parent' that they can switch their parent to while the -upstream source is reprogrammed to support this. - -Signed-off-by: Stephen Boyd - ---- -This patch is good enough for Krait, but soon I'll need to -support a "safe rate" where we ask a clock what rate it needs to be running -at to be sure it's within voltage constraints. Right now safe parent -handles that problem on Krait, but on other platforms it won't work. - - drivers/clk/clk.c | 61 ++++++++++++++++++++++++++++++++++++++------ - include/linux/clk-provider.h | 1 + - 2 files changed, 54 insertions(+), 8 deletions(-) - ---- a/drivers/clk/clk.c -+++ b/drivers/clk/clk.c -@@ -1350,7 +1350,8 @@ out: - static void clk_calc_subtree(struct clk *clk, unsigned long new_rate, - struct clk *new_parent, u8 p_index) - { -- struct clk *child; -+ struct clk *child, *parent; -+ struct clk_hw *parent_hw; - - clk->new_rate = new_rate; - clk->new_parent = new_parent; -@@ -1360,6 +1361,18 @@ static void clk_calc_subtree(struct clk - if (new_parent && new_parent != clk->parent) - new_parent->new_child = clk; - -+ if (clk->ops->get_safe_parent) { -+ parent_hw = clk->ops->get_safe_parent(clk->hw); -+ if (parent_hw) { -+ parent = parent_hw->clk; -+ p_index = clk_fetch_parent_index(clk, parent); -+ clk->safe_parent_index = p_index; -+ clk->safe_parent = parent; -+ } -+ } else { -+ clk->safe_parent = NULL; -+ } -+ - hlist_for_each_entry(child, &clk->children, child_node) { - child->new_rate = clk_recalc(child, new_rate); - clk_calc_subtree(child, child->new_rate, NULL, 0); -@@ -1439,17 +1452,47 @@ out: - * so that in case of an error we can walk down the whole tree again and - * abort the change. - */ --static struct clk *clk_propagate_rate_change(struct clk *clk, unsigned long event) -+static struct clk *clk_propagate_rate_change(struct clk *clk, -+ unsigned long event) - { - struct clk *child, *tmp_clk, *fail_clk = NULL; -+ struct clk *old_parent; - int ret = NOTIFY_DONE; - -- if (clk->rate == clk->new_rate) -+ if (clk->rate == clk->new_rate && event != POST_RATE_CHANGE) - return NULL; - -+ switch (event) { -+ case PRE_RATE_CHANGE: -+ if (clk->safe_parent) -+ clk->ops->set_parent(clk->hw, clk->safe_parent_index); -+ clk->old_rate = clk->rate; -+ break; -+ case POST_RATE_CHANGE: -+ if (clk->safe_parent) { -+ old_parent = __clk_set_parent_before(clk, -+ clk->new_parent); -+ if (clk->ops->set_rate_and_parent) { -+ clk->ops->set_rate_and_parent(clk->hw, -+ clk->new_rate, -+ clk->new_parent ? -+ clk->new_parent->rate : 0, -+ clk->new_parent_index); -+ } else if (clk->ops->set_parent) { -+ clk->ops->set_parent(clk->hw, -+ clk->new_parent_index); -+ } -+ __clk_set_parent_after(clk, clk->new_parent, -+ old_parent); -+ } -+ break; -+ } -+ - if (clk->notifier_count) { -- ret = __clk_notify(clk, event, clk->rate, clk->new_rate); -- if (ret & NOTIFY_STOP_MASK) -+ if (event != POST_RATE_CHANGE || clk->old_rate != clk->rate) -+ ret = __clk_notify(clk, event, clk->old_rate, -+ clk->new_rate); -+ if (ret & NOTIFY_STOP_MASK && event != POST_RATE_CHANGE) - fail_clk = clk; - } - -@@ -1494,7 +1537,8 @@ static void clk_change_rate(struct clk * - - old_rate = clk->rate; - -- if (clk->new_parent && clk->new_parent != clk->parent) { -+ if (clk->new_parent && clk->new_parent != clk->parent && -+ !clk->safe_parent) { - old_parent = __clk_set_parent_before(clk, clk->new_parent); - - if (clk->ops->set_rate_and_parent) { -@@ -1514,9 +1558,6 @@ static void clk_change_rate(struct clk * - - clk->rate = clk->new_rate; - -- if (clk->notifier_count && old_rate != clk->rate) -- __clk_notify(clk, POST_RATE_CHANGE, old_rate, clk->rate); -- - /* - * Use safe iteration, as change_rate can actually swap parents - * for certain clock types. -@@ -1601,6 +1642,8 @@ int clk_set_rate(struct clk *clk, unsign - /* change the rates */ - clk_change_rate(top, parent_rate); - -+ clk_propagate_rate_change(top, POST_RATE_CHANGE); -+ - out: - clk_prepare_unlock(); - ---- a/include/linux/clk-provider.h -+++ b/include/linux/clk-provider.h -@@ -179,6 +179,7 @@ struct clk_ops { - struct clk **best_parent_clk); - int (*set_parent)(struct clk_hw *hw, u8 index); - u8 (*get_parent)(struct clk_hw *hw); -+ struct clk_hw *(*get_safe_parent)(struct clk_hw *hw); - int (*set_rate)(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate); - int (*set_rate_and_parent)(struct clk_hw *hw, ---- a/include/linux/clk-private.h -+++ b/include/linux/clk-private.h -@@ -38,8 +38,11 @@ struct clk { - struct clk **parents; - u8 num_parents; - u8 new_parent_index; -+ u8 safe_parent_index; - unsigned long rate; -+ unsigned long old_rate; - unsigned long new_rate; -+ struct clk *safe_parent; - struct clk *new_parent; - struct clk *new_child; - unsigned long flags; diff --git a/target/linux/ipq806x/patches-3.18/137-clk-qcom-Add-support-for-High-Frequency-PLLs-HFPLLs.patch b/target/linux/ipq806x/patches-3.18/137-clk-qcom-Add-support-for-High-Frequency-PLLs-HFPLLs.patch deleted file mode 100644 index 701d5e7046..0000000000 --- a/target/linux/ipq806x/patches-3.18/137-clk-qcom-Add-support-for-High-Frequency-PLLs-HFPLLs.patch +++ /dev/null @@ -1,351 +0,0 @@ -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [v3,05/13] clk: qcom: Add support for High-Frequency PLLs (HFPLLs) -From: Stephen Boyd -X-Patchwork-Id: 6063261 -Message-Id: <1426920332-9340-6-git-send-email-sboyd@codeaurora.org> -To: Mike Turquette , Stephen Boyd -Cc: linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, - linux-pm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, - Viresh Kumar -Date: Fri, 20 Mar 2015 23:45:24 -0700 - -HFPLLs are the main frequency source for Krait CPU clocks. Add -support for changing the rate of these PLLs. - -Signed-off-by: Stephen Boyd - ---- -I'd really like to get rid of __clk_hfpll_init_once() if possible... - - drivers/clk/qcom/Makefile | 1 + - drivers/clk/qcom/clk-hfpll.c | 253 +++++++++++++++++++++++++++++++++++++++++++ - drivers/clk/qcom/clk-hfpll.h | 54 +++++++++ - 3 files changed, 308 insertions(+) - create mode 100644 drivers/clk/qcom/clk-hfpll.c - create mode 100644 drivers/clk/qcom/clk-hfpll.h - ---- a/drivers/clk/qcom/Makefile -+++ b/drivers/clk/qcom/Makefile -@@ -6,6 +6,7 @@ clk-qcom-y += clk-pll.o - clk-qcom-y += clk-rcg.o - clk-qcom-y += clk-rcg2.o - clk-qcom-y += clk-branch.o -+clk-qcom-y += clk-hfpll.o - clk-qcom-y += reset.o - - obj-$(CONFIG_APQ_GCC_8084) += gcc-apq8084.o ---- /dev/null -+++ b/drivers/clk/qcom/clk-hfpll.c -@@ -0,0 +1,253 @@ -+/* -+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 and -+ * only version 2 as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "clk-regmap.h" -+#include "clk-hfpll.h" -+ -+#define PLL_OUTCTRL BIT(0) -+#define PLL_BYPASSNL BIT(1) -+#define PLL_RESET_N BIT(2) -+ -+/* Initialize a HFPLL at a given rate and enable it. */ -+static void __clk_hfpll_init_once(struct clk_hw *hw) -+{ -+ struct clk_hfpll *h = to_clk_hfpll(hw); -+ struct hfpll_data const *hd = h->d; -+ struct regmap *regmap = h->clkr.regmap; -+ -+ if (likely(h->init_done)) -+ return; -+ -+ /* Configure PLL parameters for integer mode. */ -+ if (hd->config_val) -+ regmap_write(regmap, hd->config_reg, hd->config_val); -+ regmap_write(regmap, hd->m_reg, 0); -+ regmap_write(regmap, hd->n_reg, 1); -+ -+ if (hd->user_reg) { -+ u32 regval = hd->user_val; -+ unsigned long rate; -+ -+ rate = __clk_get_rate(hw->clk); -+ -+ /* Pick the right VCO. */ -+ if (hd->user_vco_mask && rate > hd->low_vco_max_rate) -+ regval |= hd->user_vco_mask; -+ regmap_write(regmap, hd->user_reg, regval); -+ } -+ -+ if (hd->droop_reg) -+ regmap_write(regmap, hd->droop_reg, hd->droop_val); -+ -+ h->init_done = true; -+} -+ -+static void __clk_hfpll_enable(struct clk_hw *hw) -+{ -+ struct clk_hfpll *h = to_clk_hfpll(hw); -+ struct hfpll_data const *hd = h->d; -+ struct regmap *regmap = h->clkr.regmap; -+ u32 val; -+ -+ __clk_hfpll_init_once(hw); -+ -+ /* Disable PLL bypass mode. */ -+ regmap_update_bits(regmap, hd->mode_reg, PLL_BYPASSNL, PLL_BYPASSNL); -+ -+ /* -+ * H/W requires a 5us delay between disabling the bypass and -+ * de-asserting the reset. Delay 10us just to be safe. -+ */ -+ udelay(10); -+ -+ /* De-assert active-low PLL reset. */ -+ regmap_update_bits(regmap, hd->mode_reg, PLL_RESET_N, PLL_RESET_N); -+ -+ /* Wait for PLL to lock. */ -+ if (hd->status_reg) { -+ do { -+ regmap_read(regmap, hd->status_reg, &val); -+ } while (!(val & BIT(hd->lock_bit))); -+ } else { -+ udelay(60); -+ } -+ -+ /* Enable PLL output. */ -+ regmap_update_bits(regmap, hd->mode_reg, PLL_OUTCTRL, PLL_OUTCTRL); -+} -+ -+/* Enable an already-configured HFPLL. */ -+static int clk_hfpll_enable(struct clk_hw *hw) -+{ -+ unsigned long flags; -+ struct clk_hfpll *h = to_clk_hfpll(hw); -+ struct hfpll_data const *hd = h->d; -+ struct regmap *regmap = h->clkr.regmap; -+ u32 mode; -+ -+ spin_lock_irqsave(&h->lock, flags); -+ regmap_read(regmap, hd->mode_reg, &mode); -+ if (!(mode & (PLL_BYPASSNL | PLL_RESET_N | PLL_OUTCTRL))) -+ __clk_hfpll_enable(hw); -+ spin_unlock_irqrestore(&h->lock, flags); -+ -+ return 0; -+} -+ -+static void __clk_hfpll_disable(struct clk_hfpll *h) -+{ -+ struct hfpll_data const *hd = h->d; -+ struct regmap *regmap = h->clkr.regmap; -+ -+ /* -+ * Disable the PLL output, disable test mode, enable the bypass mode, -+ * and assert the reset. -+ */ -+ regmap_update_bits(regmap, hd->mode_reg, -+ PLL_BYPASSNL | PLL_RESET_N | PLL_OUTCTRL, 0); -+} -+ -+static void clk_hfpll_disable(struct clk_hw *hw) -+{ -+ struct clk_hfpll *h = to_clk_hfpll(hw); -+ unsigned long flags; -+ -+ spin_lock_irqsave(&h->lock, flags); -+ __clk_hfpll_disable(h); -+ spin_unlock_irqrestore(&h->lock, flags); -+} -+ -+static long clk_hfpll_round_rate(struct clk_hw *hw, unsigned long rate, -+ unsigned long *parent_rate) -+{ -+ struct clk_hfpll *h = to_clk_hfpll(hw); -+ struct hfpll_data const *hd = h->d; -+ unsigned long rrate; -+ -+ rate = clamp(rate, hd->min_rate, hd->max_rate); -+ -+ rrate = DIV_ROUND_UP(rate, *parent_rate) * *parent_rate; -+ if (rrate > hd->max_rate) -+ rrate -= *parent_rate; -+ -+ return rrate; -+} -+ -+/* -+ * For optimization reasons, assumes no downstream clocks are actively using -+ * it. -+ */ -+static int clk_hfpll_set_rate(struct clk_hw *hw, unsigned long rate, -+ unsigned long parent_rate) -+{ -+ struct clk_hfpll *h = to_clk_hfpll(hw); -+ struct hfpll_data const *hd = h->d; -+ struct regmap *regmap = h->clkr.regmap; -+ unsigned long flags; -+ u32 l_val, val; -+ bool enabled; -+ -+ l_val = rate / parent_rate; -+ -+ spin_lock_irqsave(&h->lock, flags); -+ -+ enabled = __clk_is_enabled(hw->clk); -+ if (enabled) -+ __clk_hfpll_disable(h); -+ -+ /* Pick the right VCO. */ -+ if (hd->user_reg && hd->user_vco_mask) { -+ regmap_read(regmap, hd->user_reg, &val); -+ if (rate <= hd->low_vco_max_rate) -+ val &= ~hd->user_vco_mask; -+ else -+ val |= hd->user_vco_mask; -+ regmap_write(regmap, hd->user_reg, val); -+ } -+ -+ regmap_write(regmap, hd->l_reg, l_val); -+ -+ if (enabled) -+ __clk_hfpll_enable(hw); -+ -+ spin_unlock_irqrestore(&h->lock, flags); -+ -+ return 0; -+} -+ -+static unsigned long clk_hfpll_recalc_rate(struct clk_hw *hw, -+ unsigned long parent_rate) -+{ -+ struct clk_hfpll *h = to_clk_hfpll(hw); -+ struct hfpll_data const *hd = h->d; -+ struct regmap *regmap = h->clkr.regmap; -+ u32 l_val; -+ -+ regmap_read(regmap, hd->l_reg, &l_val); -+ -+ return l_val * parent_rate; -+} -+ -+static void clk_hfpll_init(struct clk_hw *hw) -+{ -+ struct clk_hfpll *h = to_clk_hfpll(hw); -+ struct hfpll_data const *hd = h->d; -+ struct regmap *regmap = h->clkr.regmap; -+ u32 mode, status; -+ -+ regmap_read(regmap, hd->mode_reg, &mode); -+ if (mode != (PLL_BYPASSNL | PLL_RESET_N | PLL_OUTCTRL)) { -+ __clk_hfpll_init_once(hw); -+ return; -+ } -+ -+ if (hd->status_reg) { -+ regmap_read(regmap, hd->status_reg, &status); -+ if (!(status & BIT(hd->lock_bit))) { -+ WARN(1, "HFPLL %s is ON, but not locked!\n", -+ __clk_get_name(hw->clk)); -+ clk_hfpll_disable(hw); -+ __clk_hfpll_init_once(hw); -+ } -+ } -+} -+ -+static int hfpll_is_enabled(struct clk_hw *hw) -+{ -+ struct clk_hfpll *h = to_clk_hfpll(hw); -+ struct hfpll_data const *hd = h->d; -+ struct regmap *regmap = h->clkr.regmap; -+ u32 mode; -+ -+ regmap_read(regmap, hd->mode_reg, &mode); -+ mode &= 0x7; -+ return mode == (PLL_BYPASSNL | PLL_RESET_N | PLL_OUTCTRL); -+} -+ -+const struct clk_ops clk_ops_hfpll = { -+ .enable = clk_hfpll_enable, -+ .disable = clk_hfpll_disable, -+ .is_enabled = hfpll_is_enabled, -+ .round_rate = clk_hfpll_round_rate, -+ .set_rate = clk_hfpll_set_rate, -+ .recalc_rate = clk_hfpll_recalc_rate, -+ .init = clk_hfpll_init, -+}; -+EXPORT_SYMBOL_GPL(clk_ops_hfpll); ---- /dev/null -+++ b/drivers/clk/qcom/clk-hfpll.h -@@ -0,0 +1,54 @@ -+/* -+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 and -+ * only version 2 as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+#ifndef __QCOM_CLK_HFPLL_H__ -+#define __QCOM_CLK_HFPLL_H__ -+ -+#include -+#include -+#include "clk-regmap.h" -+ -+struct hfpll_data { -+ u32 mode_reg; -+ u32 l_reg; -+ u32 m_reg; -+ u32 n_reg; -+ u32 user_reg; -+ u32 droop_reg; -+ u32 config_reg; -+ u32 status_reg; -+ u8 lock_bit; -+ -+ u32 droop_val; -+ u32 config_val; -+ u32 user_val; -+ u32 user_vco_mask; -+ unsigned long low_vco_max_rate; -+ -+ unsigned long min_rate; -+ unsigned long max_rate; -+}; -+ -+struct clk_hfpll { -+ struct hfpll_data const *d; -+ int init_done; -+ -+ struct clk_regmap clkr; -+ spinlock_t lock; -+}; -+ -+#define to_clk_hfpll(_hw) \ -+ container_of(to_clk_regmap(_hw), struct clk_hfpll, clkr) -+ -+extern const struct clk_ops clk_ops_hfpll; -+ -+#endif diff --git a/target/linux/ipq806x/patches-3.18/138-clk-qcom-Add-HFPLL-driver.patch b/target/linux/ipq806x/patches-3.18/138-clk-qcom-Add-HFPLL-driver.patch deleted file mode 100644 index a0b1d64dc6..0000000000 --- a/target/linux/ipq806x/patches-3.18/138-clk-qcom-Add-HFPLL-driver.patch +++ /dev/null @@ -1,206 +0,0 @@ -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [v3,06/13] clk: qcom: Add HFPLL driver -From: Stephen Boyd -X-Patchwork-Id: 6063231 -Message-Id: <1426920332-9340-7-git-send-email-sboyd@codeaurora.org> -To: Mike Turquette , Stephen Boyd -Cc: linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, - linux-pm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, - Viresh Kumar , -Date: Fri, 20 Mar 2015 23:45:25 -0700 - -On some devices (MSM8974 for example), the HFPLLs are -instantiated within the Krait processor subsystem as separate -register regions. Add a driver for these PLLs so that we can -provide HFPLL clocks for use by the system. - -Cc: -Signed-off-by: Stephen Boyd - ---- -.../devicetree/bindings/clock/qcom,hfpll.txt | 40 ++++++++ - drivers/clk/qcom/Kconfig | 8 ++ - drivers/clk/qcom/Makefile | 1 + - drivers/clk/qcom/hfpll.c | 109 +++++++++++++++++++++ - 4 files changed, 158 insertions(+) - create mode 100644 Documentation/devicetree/bindings/clock/qcom,hfpll.txt - create mode 100644 drivers/clk/qcom/hfpll.c - ---- /dev/null -+++ b/Documentation/devicetree/bindings/clock/qcom,hfpll.txt -@@ -0,0 +1,40 @@ -+High-Frequency PLL (HFPLL) -+ -+PROPERTIES -+ -+- compatible: -+ Usage: required -+ Value type: -+ Definition: must be "qcom,hfpll" -+ -+- reg: -+ Usage: required -+ Value type: -+ Definition: address and size of HPLL registers. An optional second -+ element specifies the address and size of the alias -+ register region. -+ -+- clock-output-names: -+ Usage: required -+ Value type: -+ Definition: Name of the PLL. Typically hfpllX where X is a CPU number -+ starting at 0. Otherwise hfpll_Y where Y is more specific -+ such as "l2". -+ -+Example: -+ -+1) An HFPLL for the L2 cache. -+ -+ clock-controller@f9016000 { -+ compatible = "qcom,hfpll"; -+ reg = <0xf9016000 0x30>; -+ clock-output-names = "hfpll_l2"; -+ }; -+ -+2) An HFPLL for CPU0. This HFPLL has the alias register region. -+ -+ clock-controller@f908a000 { -+ compatible = "qcom,hfpll"; -+ reg = <0xf908a000 0x30>, <0xf900a000 0x30>; -+ clock-output-names = "hfpll0"; -+ }; ---- a/drivers/clk/qcom/Kconfig -+++ b/drivers/clk/qcom/Kconfig -@@ -70,3 +70,11 @@ config MSM_MMCC_8974 - Support for the multimedia clock controller on msm8974 devices. - Say Y if you want to support multimedia devices such as display, - graphics, video encode/decode, camera, etc. -+ -+config QCOM_HFPLL -+ tristate "High-Frequency PLL (HFPLL) Clock Controller" -+ depends on COMMON_CLK_QCOM -+ help -+ Support for the high-frequency PLLs present on Qualcomm devices. -+ Say Y if you want to support CPU frequency scaling on devices -+ such as MSM8974, APQ8084, etc. ---- a/drivers/clk/qcom/Makefile -+++ b/drivers/clk/qcom/Makefile -@@ -17,3 +17,4 @@ obj-$(CONFIG_MSM_GCC_8960) += gcc-msm896 - obj-$(CONFIG_MSM_GCC_8974) += gcc-msm8974.o - obj-$(CONFIG_MSM_MMCC_8960) += mmcc-msm8960.o - obj-$(CONFIG_MSM_MMCC_8974) += mmcc-msm8974.o -+obj-$(CONFIG_QCOM_HFPLL) += hfpll.o ---- /dev/null -+++ b/drivers/clk/qcom/hfpll.c -@@ -0,0 +1,109 @@ -+/* -+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 and -+ * only version 2 as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "clk-regmap.h" -+#include "clk-hfpll.h" -+ -+static const struct hfpll_data hdata = { -+ .mode_reg = 0x00, -+ .l_reg = 0x04, -+ .m_reg = 0x08, -+ .n_reg = 0x0c, -+ .user_reg = 0x10, -+ .config_reg = 0x14, -+ .config_val = 0x430405d, -+ .status_reg = 0x1c, -+ .lock_bit = 16, -+ -+ .user_val = 0x8, -+ .user_vco_mask = 0x100000, -+ .low_vco_max_rate = 1248000000, -+ .min_rate = 537600000UL, -+ .max_rate = 2900000000UL, -+}; -+ -+static const struct of_device_id qcom_hfpll_match_table[] = { -+ { .compatible = "qcom,hfpll" }, -+ { } -+}; -+MODULE_DEVICE_TABLE(of, qcom_hfpll_match_table); -+ -+static const struct regmap_config hfpll_regmap_config = { -+ .reg_bits = 32, -+ .reg_stride = 4, -+ .val_bits = 32, -+ .max_register = 0x30, -+ .fast_io = true, -+}; -+ -+static int qcom_hfpll_probe(struct platform_device *pdev) -+{ -+ struct clk *clk; -+ struct resource *res; -+ struct device *dev = &pdev->dev; -+ void __iomem *base; -+ struct regmap *regmap; -+ struct clk_hfpll *h; -+ struct clk_init_data init = { -+ .parent_names = (const char *[]){ "xo" }, -+ .num_parents = 1, -+ .ops = &clk_ops_hfpll, -+ }; -+ -+ h = devm_kzalloc(dev, sizeof(*h), GFP_KERNEL); -+ if (!h) -+ return -ENOMEM; -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ base = devm_ioremap_resource(dev, res); -+ if (IS_ERR(base)) -+ return PTR_ERR(base); -+ -+ regmap = devm_regmap_init_mmio(&pdev->dev, base, &hfpll_regmap_config); -+ if (IS_ERR(regmap)) -+ return PTR_ERR(regmap); -+ -+ if (of_property_read_string_index(dev->of_node, "clock-output-names", -+ 0, &init.name)) -+ return -ENODEV; -+ -+ h->d = &hdata; -+ h->clkr.hw.init = &init; -+ spin_lock_init(&h->lock); -+ -+ clk = devm_clk_register_regmap(&pdev->dev, &h->clkr); -+ -+ return PTR_ERR_OR_ZERO(clk); -+} -+ -+static struct platform_driver qcom_hfpll_driver = { -+ .probe = qcom_hfpll_probe, -+ .driver = { -+ .name = "qcom-hfpll", -+ .of_match_table = qcom_hfpll_match_table, -+ }, -+}; -+module_platform_driver(qcom_hfpll_driver); -+ -+MODULE_DESCRIPTION("QCOM HFPLL Clock Driver"); -+MODULE_LICENSE("GPL v2"); -+MODULE_ALIAS("platform:qcom-hfpll"); diff --git a/target/linux/ipq806x/patches-3.18/139-clk-qcom-Add-IPQ806X-s-HFPLLs.patch b/target/linux/ipq806x/patches-3.18/139-clk-qcom-Add-IPQ806X-s-HFPLLs.patch deleted file mode 100644 index 7fd53d1d9c..0000000000 --- a/target/linux/ipq806x/patches-3.18/139-clk-qcom-Add-IPQ806X-s-HFPLLs.patch +++ /dev/null @@ -1,127 +0,0 @@ -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [v3,08/13] clk: qcom: Add IPQ806X's HFPLLs -From: Stephen Boyd -X-Patchwork-Id: 6063241 -Message-Id: <1426920332-9340-9-git-send-email-sboyd@codeaurora.org> -To: Mike Turquette , Stephen Boyd -Cc: linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, - linux-pm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, - Viresh Kumar -Date: Fri, 20 Mar 2015 23:45:27 -0700 - -Describe the HFPLLs present on IPQ806X devices. - -Signed-off-by: Stephen Boyd - ---- -drivers/clk/qcom/gcc-ipq806x.c | 83 ++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 83 insertions(+) - ---- a/drivers/clk/qcom/gcc-ipq806x.c -+++ b/drivers/clk/qcom/gcc-ipq806x.c -@@ -30,6 +30,7 @@ - #include "clk-pll.h" - #include "clk-rcg.h" - #include "clk-branch.h" -+#include "clk-hfpll.h" - #include "reset.h" - - static struct clk_pll pll0 = { -@@ -102,6 +103,85 @@ static struct clk_regmap pll8_vote = { - }, - }; - -+static struct hfpll_data hfpll0_data = { -+ .mode_reg = 0x3200, -+ .l_reg = 0x3208, -+ .m_reg = 0x320c, -+ .n_reg = 0x3210, -+ .config_reg = 0x3204, -+ .status_reg = 0x321c, -+ .config_val = 0x7845c665, -+ .droop_reg = 0x3214, -+ .droop_val = 0x0108c000, -+ .min_rate = 600000000UL, -+ .max_rate = 1800000000UL, -+}; -+ -+static struct clk_hfpll hfpll0 = { -+ .d = &hfpll0_data, -+ .clkr.hw.init = &(struct clk_init_data){ -+ .parent_names = (const char *[]){ "pxo" }, -+ .num_parents = 1, -+ .name = "hfpll0", -+ .ops = &clk_ops_hfpll, -+ .flags = CLK_IGNORE_UNUSED, -+ }, -+ .lock = __SPIN_LOCK_UNLOCKED(hfpll0.lock), -+}; -+ -+static struct hfpll_data hfpll1_data = { -+ .mode_reg = 0x3240, -+ .l_reg = 0x3248, -+ .m_reg = 0x324c, -+ .n_reg = 0x3250, -+ .config_reg = 0x3244, -+ .status_reg = 0x325c, -+ .config_val = 0x7845c665, -+ .droop_reg = 0x3314, -+ .droop_val = 0x0108c000, -+ .min_rate = 600000000UL, -+ .max_rate = 1800000000UL, -+}; -+ -+static struct clk_hfpll hfpll1 = { -+ .d = &hfpll1_data, -+ .clkr.hw.init = &(struct clk_init_data){ -+ .parent_names = (const char *[]){ "pxo" }, -+ .num_parents = 1, -+ .name = "hfpll1", -+ .ops = &clk_ops_hfpll, -+ .flags = CLK_IGNORE_UNUSED, -+ }, -+ .lock = __SPIN_LOCK_UNLOCKED(hfpll1.lock), -+}; -+ -+static struct hfpll_data hfpll_l2_data = { -+ .mode_reg = 0x3300, -+ .l_reg = 0x3308, -+ .m_reg = 0x330c, -+ .n_reg = 0x3310, -+ .config_reg = 0x3304, -+ .status_reg = 0x331c, -+ .config_val = 0x7845c665, -+ .droop_reg = 0x3314, -+ .droop_val = 0x0108c000, -+ .min_rate = 600000000UL, -+ .max_rate = 1800000000UL, -+}; -+ -+static struct clk_hfpll hfpll_l2 = { -+ .d = &hfpll_l2_data, -+ .clkr.hw.init = &(struct clk_init_data){ -+ .parent_names = (const char *[]){ "pxo" }, -+ .num_parents = 1, -+ .name = "hfpll_l2", -+ .ops = &clk_ops_hfpll, -+ .flags = CLK_IGNORE_UNUSED, -+ }, -+ .lock = __SPIN_LOCK_UNLOCKED(hfpll_l2.lock), -+}; -+ -+ - static struct clk_pll pll14 = { - .l_reg = 0x31c4, - .m_reg = 0x31c8, -@@ -2261,6 +2341,9 @@ static struct clk_regmap *gcc_ipq806x_cl - [USB_FS1_XCVR_SRC] = &usb_fs1_xcvr_clk_src.clkr, - [USB_FS1_XCVR_CLK] = &usb_fs1_xcvr_clk.clkr, - [USB_FS1_SYSTEM_CLK] = &usb_fs1_sys_clk.clkr, -+ [PLL9] = &hfpll0.clkr, -+ [PLL10] = &hfpll1.clkr, -+ [PLL12] = &hfpll_l2.clkr, - }; - - static const struct qcom_reset_map gcc_ipq806x_resets[] = { diff --git a/target/linux/ipq806x/patches-3.18/140-clk-qcom-Add-support-for-Krait-clocks.patch b/target/linux/ipq806x/patches-3.18/140-clk-qcom-Add-support-for-Krait-clocks.patch deleted file mode 100644 index 63292e8611..0000000000 --- a/target/linux/ipq806x/patches-3.18/140-clk-qcom-Add-support-for-Krait-clocks.patch +++ /dev/null @@ -1,271 +0,0 @@ -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [v3,09/13] clk: qcom: Add support for Krait clocks -From: Stephen Boyd -X-Patchwork-Id: 6063251 -Message-Id: <1426920332-9340-10-git-send-email-sboyd@codeaurora.org> -To: Mike Turquette , Stephen Boyd -Cc: linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, - linux-pm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, - Viresh Kumar -Date: Fri, 20 Mar 2015 23:45:28 -0700 - -The Krait clocks are made up of a series of muxes and a divider -that choose between a fixed rate clock and dedicated HFPLLs for -each CPU. Instead of using mmio accesses to remux parents, the -Krait implementation exposes the remux control via cp15 -registers. Support these clocks. - -Signed-off-by: Stephen Boyd - ---- -drivers/clk/qcom/Kconfig | 4 ++ - drivers/clk/qcom/Makefile | 1 + - drivers/clk/qcom/clk-krait.c | 166 +++++++++++++++++++++++++++++++++++++++++++ - drivers/clk/qcom/clk-krait.h | 49 +++++++++++++ - 4 files changed, 220 insertions(+) - create mode 100644 drivers/clk/qcom/clk-krait.c - create mode 100644 drivers/clk/qcom/clk-krait.h - ---- a/drivers/clk/qcom/Kconfig -+++ b/drivers/clk/qcom/Kconfig -@@ -78,3 +78,7 @@ config QCOM_HFPLL - Support for the high-frequency PLLs present on Qualcomm devices. - Say Y if you want to support CPU frequency scaling on devices - such as MSM8974, APQ8084, etc. -+ -+config KRAIT_CLOCKS -+ bool -+ select KRAIT_L2_ACCESSORS ---- a/drivers/clk/qcom/Makefile -+++ b/drivers/clk/qcom/Makefile -@@ -6,6 +6,7 @@ clk-qcom-y += clk-pll.o - clk-qcom-y += clk-rcg.o - clk-qcom-y += clk-rcg2.o - clk-qcom-y += clk-branch.o -+clk-qcom-$(CONFIG_KRAIT_CLOCKS) += clk-krait.o - clk-qcom-y += clk-hfpll.o - clk-qcom-y += reset.o - ---- /dev/null -+++ b/drivers/clk/qcom/clk-krait.c -@@ -0,0 +1,166 @@ -+/* -+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 and -+ * only version 2 as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "clk-krait.h" -+ -+/* Secondary and primary muxes share the same cp15 register */ -+static DEFINE_SPINLOCK(krait_clock_reg_lock); -+ -+#define LPL_SHIFT 8 -+static void __krait_mux_set_sel(struct krait_mux_clk *mux, int sel) -+{ -+ unsigned long flags; -+ u32 regval; -+ -+ spin_lock_irqsave(&krait_clock_reg_lock, flags); -+ regval = krait_get_l2_indirect_reg(mux->offset); -+ regval &= ~(mux->mask << mux->shift); -+ regval |= (sel & mux->mask) << mux->shift; -+ if (mux->lpl) { -+ regval &= ~(mux->mask << (mux->shift + LPL_SHIFT)); -+ regval |= (sel & mux->mask) << (mux->shift + LPL_SHIFT); -+ } -+ krait_set_l2_indirect_reg(mux->offset, regval); -+ spin_unlock_irqrestore(&krait_clock_reg_lock, flags); -+ -+ /* Wait for switch to complete. */ -+ mb(); -+ udelay(1); -+} -+ -+static int krait_mux_set_parent(struct clk_hw *hw, u8 index) -+{ -+ struct krait_mux_clk *mux = to_krait_mux_clk(hw); -+ u32 sel; -+ -+ sel = clk_mux_reindex(index, mux->parent_map, 0); -+ mux->en_mask = sel; -+ /* Don't touch mux if CPU is off as it won't work */ -+ if (__clk_is_enabled(hw->clk)) -+ __krait_mux_set_sel(mux, sel); -+ return 0; -+} -+ -+static u8 krait_mux_get_parent(struct clk_hw *hw) -+{ -+ struct krait_mux_clk *mux = to_krait_mux_clk(hw); -+ u32 sel; -+ -+ sel = krait_get_l2_indirect_reg(mux->offset); -+ sel >>= mux->shift; -+ sel &= mux->mask; -+ mux->en_mask = sel; -+ -+ return clk_mux_get_parent(hw, sel, mux->parent_map, 0); -+} -+ -+static struct clk_hw *krait_mux_get_safe_parent(struct clk_hw *hw) -+{ -+ int i; -+ struct krait_mux_clk *mux = to_krait_mux_clk(hw); -+ int num_parents = __clk_get_num_parents(hw->clk); -+ -+ i = mux->safe_sel; -+ for (i = 0; i < num_parents; i++) -+ if (mux->safe_sel == mux->parent_map[i]) -+ break; -+ -+ return __clk_get_hw(clk_get_parent_by_index(hw->clk, i)); -+} -+ -+static int krait_mux_enable(struct clk_hw *hw) -+{ -+ struct krait_mux_clk *mux = to_krait_mux_clk(hw); -+ -+ __krait_mux_set_sel(mux, mux->en_mask); -+ -+ return 0; -+} -+ -+static void krait_mux_disable(struct clk_hw *hw) -+{ -+ struct krait_mux_clk *mux = to_krait_mux_clk(hw); -+ -+ __krait_mux_set_sel(mux, mux->safe_sel); -+} -+ -+const struct clk_ops krait_mux_clk_ops = { -+ .enable = krait_mux_enable, -+ .disable = krait_mux_disable, -+ .set_parent = krait_mux_set_parent, -+ .get_parent = krait_mux_get_parent, -+ .determine_rate = __clk_mux_determine_rate_closest, -+ .get_safe_parent = krait_mux_get_safe_parent, -+}; -+EXPORT_SYMBOL_GPL(krait_mux_clk_ops); -+ -+/* The divider can divide by 2, 4, 6 and 8. But we only really need div-2. */ -+static long krait_div2_round_rate(struct clk_hw *hw, unsigned long rate, -+ unsigned long *parent_rate) -+{ -+ *parent_rate = __clk_round_rate(__clk_get_parent(hw->clk), rate * 2); -+ return DIV_ROUND_UP(*parent_rate, 2); -+} -+ -+static int krait_div2_set_rate(struct clk_hw *hw, unsigned long rate, -+ unsigned long parent_rate) -+{ -+ struct krait_div2_clk *d = to_krait_div2_clk(hw); -+ unsigned long flags; -+ u32 val; -+ u32 mask = BIT(d->width) - 1; -+ -+ if (d->lpl) -+ mask = mask << (d->shift + LPL_SHIFT) | mask << d->shift; -+ -+ spin_lock_irqsave(&krait_clock_reg_lock, flags); -+ val = krait_get_l2_indirect_reg(d->offset); -+ val &= ~mask; -+ krait_set_l2_indirect_reg(d->offset, val); -+ spin_unlock_irqrestore(&krait_clock_reg_lock, flags); -+ -+ return 0; -+} -+ -+static unsigned long -+krait_div2_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) -+{ -+ struct krait_div2_clk *d = to_krait_div2_clk(hw); -+ u32 mask = BIT(d->width) - 1; -+ u32 div; -+ -+ div = krait_get_l2_indirect_reg(d->offset); -+ div >>= d->shift; -+ div &= mask; -+ div = (div + 1) * 2; -+ -+ return DIV_ROUND_UP(parent_rate, div); -+} -+ -+const struct clk_ops krait_div2_clk_ops = { -+ .round_rate = krait_div2_round_rate, -+ .set_rate = krait_div2_set_rate, -+ .recalc_rate = krait_div2_recalc_rate, -+}; -+EXPORT_SYMBOL_GPL(krait_div2_clk_ops); ---- /dev/null -+++ b/drivers/clk/qcom/clk-krait.h -@@ -0,0 +1,49 @@ -+/* -+ * Copyright (c) 2013, The Linux Foundation. All rights reserved. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 and -+ * only version 2 as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef __QCOM_CLK_KRAIT_H -+#define __QCOM_CLK_KRAIT_H -+ -+#include -+ -+struct krait_mux_clk { -+ unsigned int *parent_map; -+ bool has_safe_parent; -+ u8 safe_sel; -+ u32 offset; -+ u32 mask; -+ u32 shift; -+ u32 en_mask; -+ bool lpl; -+ -+ struct clk_hw hw; -+}; -+ -+#define to_krait_mux_clk(_hw) container_of(_hw, struct krait_mux_clk, hw) -+ -+extern const struct clk_ops krait_mux_clk_ops; -+ -+struct krait_div2_clk { -+ u32 offset; -+ u8 width; -+ u32 shift; -+ bool lpl; -+ -+ struct clk_hw hw; -+}; -+ -+#define to_krait_div2_clk(_hw) container_of(_hw, struct krait_div2_clk, hw) -+ -+extern const struct clk_ops krait_div2_clk_ops; -+ -+#endif diff --git a/target/linux/ipq806x/patches-3.18/141-clk-qcom-Add-KPSS-ACC-GCC-driver.patch b/target/linux/ipq806x/patches-3.18/141-clk-qcom-Add-KPSS-ACC-GCC-driver.patch deleted file mode 100644 index 06b14d8b53..0000000000 --- a/target/linux/ipq806x/patches-3.18/141-clk-qcom-Add-KPSS-ACC-GCC-driver.patch +++ /dev/null @@ -1,205 +0,0 @@ -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [v3,10/13] clk: qcom: Add KPSS ACC/GCC driver -From: Stephen Boyd -X-Patchwork-Id: 6063201 -Message-Id: <1426920332-9340-11-git-send-email-sboyd@codeaurora.org> -To: Mike Turquette , Stephen Boyd -Cc: linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, - linux-pm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, - Viresh Kumar , -Date: Fri, 20 Mar 2015 23:45:29 -0700 - -The ACC and GCC regions present in KPSSv1 contain registers to -control clocks and power to each Krait CPU and L2. For CPUfreq -purposes probe these devices and expose a mux clock that chooses -between PXO and PLL8. - -Cc: -Signed-off-by: Stephen Boyd - ---- -.../devicetree/bindings/arm/msm/qcom,kpss-acc.txt | 7 ++ - .../devicetree/bindings/arm/msm/qcom,kpss-gcc.txt | 28 +++++++ - drivers/clk/qcom/Kconfig | 8 ++ - drivers/clk/qcom/Makefile | 1 + - drivers/clk/qcom/kpss-xcc.c | 95 ++++++++++++++++++++++ - 5 files changed, 139 insertions(+) - create mode 100644 Documentation/devicetree/bindings/arm/msm/qcom,kpss-gcc.txt - create mode 100644 drivers/clk/qcom/kpss-xcc.c - ---- a/Documentation/devicetree/bindings/arm/msm/qcom,kpss-acc.txt -+++ b/Documentation/devicetree/bindings/arm/msm/qcom,kpss-acc.txt -@@ -21,10 +21,17 @@ PROPERTIES - the register region. An optional second element specifies - the base address and size of the alias register region. - -+- clock-output-names: -+ Usage: optional -+ Value type: -+ Definition: Name of the output clock. Typically acpuX_aux where X is a -+ CPU number starting at 0. -+ - Example: - - clock-controller@2088000 { - compatible = "qcom,kpss-acc-v2"; - reg = <0x02088000 0x1000>, - <0x02008000 0x1000>; -+ clock-output-names = "acpu0_aux"; - }; ---- /dev/null -+++ b/Documentation/devicetree/bindings/arm/msm/qcom,kpss-gcc.txt -@@ -0,0 +1,28 @@ -+Krait Processor Sub-system (KPSS) Global Clock Controller (GCC) -+ -+PROPERTIES -+ -+- compatible: -+ Usage: required -+ Value type: -+ Definition: should be one of: -+ "qcom,kpss-gcc" -+ -+- reg: -+ Usage: required -+ Value type: -+ Definition: base address and size of the register region -+ -+- clock-output-names: -+ Usage: required -+ Value type: -+ Definition: Name of the output clock. Typically acpu_l2_aux indicating -+ an L2 cache auxiliary clock. -+ -+Example: -+ -+ l2cc: clock-controller@2011000 { -+ compatible = "qcom,kpss-gcc"; -+ reg = <0x2011000 0x1000>; -+ clock-output-names = "acpu_l2_aux"; -+ }; ---- a/drivers/clk/qcom/Kconfig -+++ b/drivers/clk/qcom/Kconfig -@@ -79,6 +79,14 @@ config QCOM_HFPLL - Say Y if you want to support CPU frequency scaling on devices - such as MSM8974, APQ8084, etc. - -+config KPSS_XCC -+ tristate "KPSS Clock Controller" -+ depends on COMMON_CLK_QCOM -+ help -+ Support for the Krait ACC and GCC clock controllers. Say Y -+ if you want to support CPU frequency scaling on devices such -+ as MSM8960, APQ8064, etc. -+ - config KRAIT_CLOCKS - bool - select KRAIT_L2_ACCESSORS ---- a/drivers/clk/qcom/Makefile -+++ b/drivers/clk/qcom/Makefile -@@ -18,4 +18,5 @@ obj-$(CONFIG_MSM_GCC_8960) += gcc-msm896 - obj-$(CONFIG_MSM_GCC_8974) += gcc-msm8974.o - obj-$(CONFIG_MSM_MMCC_8960) += mmcc-msm8960.o - obj-$(CONFIG_MSM_MMCC_8974) += mmcc-msm8974.o -+obj-$(CONFIG_KPSS_XCC) += kpss-xcc.o - obj-$(CONFIG_QCOM_HFPLL) += hfpll.o ---- /dev/null -+++ b/drivers/clk/qcom/kpss-xcc.c -@@ -0,0 +1,95 @@ -+/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 and -+ * only version 2 as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+static const char *aux_parents[] = { -+ "pll8_vote", -+ "pxo", -+}; -+ -+static unsigned int aux_parent_map[] = { -+ 3, -+ 0, -+}; -+ -+static const struct of_device_id kpss_xcc_match_table[] = { -+ { .compatible = "qcom,kpss-acc-v1", .data = (void *)1UL }, -+ { .compatible = "qcom,kpss-gcc" }, -+ {} -+}; -+MODULE_DEVICE_TABLE(of, kpss_xcc_match_table); -+ -+static int kpss_xcc_driver_probe(struct platform_device *pdev) -+{ -+ const struct of_device_id *id; -+ struct clk *clk; -+ struct resource *res; -+ void __iomem *base; -+ const char *name; -+ -+ id = of_match_device(kpss_xcc_match_table, &pdev->dev); -+ if (!id) -+ return -ENODEV; -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ base = devm_ioremap_resource(&pdev->dev, res); -+ if (IS_ERR(base)) -+ return PTR_ERR(base); -+ -+ if (id->data) { -+ if (of_property_read_string_index(pdev->dev.of_node, -+ "clock-output-names", 0, &name)) -+ return -ENODEV; -+ base += 0x14; -+ } else { -+ name = "acpu_l2_aux"; -+ base += 0x28; -+ } -+ -+ clk = clk_register_mux_table(&pdev->dev, name, aux_parents, -+ ARRAY_SIZE(aux_parents), 0, base, 0, 0x3, -+ 0, aux_parent_map, NULL); -+ -+ platform_set_drvdata(pdev, clk); -+ -+ return PTR_ERR_OR_ZERO(clk); -+} -+ -+static int kpss_xcc_driver_remove(struct platform_device *pdev) -+{ -+ clk_unregister_mux(platform_get_drvdata(pdev)); -+ return 0; -+} -+ -+static struct platform_driver kpss_xcc_driver = { -+ .probe = kpss_xcc_driver_probe, -+ .remove = kpss_xcc_driver_remove, -+ .driver = { -+ .name = "kpss-xcc", -+ .of_match_table = kpss_xcc_match_table, -+ }, -+}; -+module_platform_driver(kpss_xcc_driver); -+ -+MODULE_DESCRIPTION("Krait Processor Sub System (KPSS) Clock Driver"); -+MODULE_LICENSE("GPL v2"); -+MODULE_ALIAS("platform:kpss-xcc"); diff --git a/target/linux/ipq806x/patches-3.18/142-clk-qcom-Add-Krait-clock-controller-driver.patch b/target/linux/ipq806x/patches-3.18/142-clk-qcom-Add-Krait-clock-controller-driver.patch deleted file mode 100644 index 98a09ac08e..0000000000 --- a/target/linux/ipq806x/patches-3.18/142-clk-qcom-Add-Krait-clock-controller-driver.patch +++ /dev/null @@ -1,435 +0,0 @@ -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [v3,11/13] clk: qcom: Add Krait clock controller driver -From: Stephen Boyd -X-Patchwork-Id: 6063121 -Message-Id: <1426920332-9340-12-git-send-email-sboyd@codeaurora.org> -To: Mike Turquette , Stephen Boyd -Cc: linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, - linux-pm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, - Viresh Kumar , -Date: Fri, 20 Mar 2015 23:45:30 -0700 - -The Krait CPU clocks are made up of a primary mux and secondary -mux for each CPU and the L2, controlled via cp15 accessors. For -Kraits within KPSSv1 each secondary mux accepts a different aux -source, but on KPSSv2 each secondary mux accepts the same aux -source. - -Cc: -Signed-off-by: Stephen Boyd - ---- -.../devicetree/bindings/clock/qcom,krait-cc.txt | 22 ++ - drivers/clk/qcom/Kconfig | 8 + - drivers/clk/qcom/Makefile | 1 + - drivers/clk/qcom/krait-cc.c | 352 +++++++++++++++++++++ - 4 files changed, 383 insertions(+) - create mode 100644 Documentation/devicetree/bindings/clock/qcom,krait-cc.txt - create mode 100644 drivers/clk/qcom/krait-cc.c - ---- /dev/null -+++ b/Documentation/devicetree/bindings/clock/qcom,krait-cc.txt -@@ -0,0 +1,22 @@ -+Krait Clock Controller -+ -+PROPERTIES -+ -+- compatible: -+ Usage: required -+ Value type: -+ Definition: must be one of: -+ "qcom,krait-cc-v1" -+ "qcom,krait-cc-v2" -+ -+- #clock-cells: -+ Usage: required -+ Value type: -+ Definition: must be 1 -+ -+Example: -+ -+ kraitcc: clock-controller { -+ compatible = "qcom,krait-cc-v1"; -+ #clock-cells = <1>; -+ }; ---- a/drivers/clk/qcom/Kconfig -+++ b/drivers/clk/qcom/Kconfig -@@ -87,6 +87,14 @@ config KPSS_XCC - if you want to support CPU frequency scaling on devices such - as MSM8960, APQ8064, etc. - -+config KRAITCC -+ tristate "Krait Clock Controller" -+ depends on COMMON_CLK_QCOM && ARM -+ select KRAIT_CLOCKS -+ help -+ Support for the Krait CPU clocks on Qualcomm devices. -+ Say Y if you want to support CPU frequency scaling. -+ - config KRAIT_CLOCKS - bool - select KRAIT_L2_ACCESSORS ---- a/drivers/clk/qcom/Makefile -+++ b/drivers/clk/qcom/Makefile -@@ -20,3 +20,4 @@ obj-$(CONFIG_MSM_MMCC_8960) += mmcc-msm8 - obj-$(CONFIG_MSM_MMCC_8974) += mmcc-msm8974.o - obj-$(CONFIG_KPSS_XCC) += kpss-xcc.o - obj-$(CONFIG_QCOM_HFPLL) += hfpll.o -+obj-$(CONFIG_KRAITCC) += krait-cc.o ---- /dev/null -+++ b/drivers/clk/qcom/krait-cc.c -@@ -0,0 +1,352 @@ -+/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 and -+ * only version 2 as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "clk-krait.h" -+ -+static unsigned int sec_mux_map[] = { -+ 2, -+ 0, -+}; -+ -+static unsigned int pri_mux_map[] = { -+ 1, -+ 2, -+ 0, -+}; -+ -+static int -+krait_add_div(struct device *dev, int id, const char *s, unsigned offset) -+{ -+ struct krait_div2_clk *div; -+ struct clk_init_data init = { -+ .num_parents = 1, -+ .ops = &krait_div2_clk_ops, -+ .flags = CLK_SET_RATE_PARENT, -+ }; -+ const char *p_names[1]; -+ struct clk *clk; -+ -+ div = devm_kzalloc(dev, sizeof(*div), GFP_KERNEL); -+ if (!div) -+ return -ENOMEM; -+ -+ div->width = 2; -+ div->shift = 6; -+ div->lpl = id >= 0; -+ div->offset = offset; -+ div->hw.init = &init; -+ -+ init.name = kasprintf(GFP_KERNEL, "hfpll%s_div", s); -+ if (!init.name) -+ return -ENOMEM; -+ -+ init.parent_names = p_names; -+ p_names[0] = kasprintf(GFP_KERNEL, "hfpll%s", s); -+ if (!p_names[0]) { -+ kfree(init.name); -+ return -ENOMEM; -+ } -+ -+ clk = devm_clk_register(dev, &div->hw); -+ kfree(p_names[0]); -+ kfree(init.name); -+ -+ return PTR_ERR_OR_ZERO(clk); -+} -+ -+static int -+krait_add_sec_mux(struct device *dev, int id, const char *s, unsigned offset, -+ bool unique_aux) -+{ -+ struct krait_mux_clk *mux; -+ static const char *sec_mux_list[] = { -+ "acpu_aux", -+ "qsb", -+ }; -+ struct clk_init_data init = { -+ .parent_names = sec_mux_list, -+ .num_parents = ARRAY_SIZE(sec_mux_list), -+ .ops = &krait_mux_clk_ops, -+ .flags = CLK_SET_RATE_PARENT, -+ }; -+ struct clk *clk; -+ -+ mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL); -+ if (!mux) -+ return -ENOMEM; -+ -+ mux->offset = offset; -+ mux->lpl = id >= 0; -+ mux->has_safe_parent = true; -+ mux->safe_sel = 2; -+ mux->mask = 0x3; -+ mux->shift = 2; -+ mux->parent_map = sec_mux_map; -+ mux->hw.init = &init; -+ -+ init.name = kasprintf(GFP_KERNEL, "krait%s_sec_mux", s); -+ if (!init.name) -+ return -ENOMEM; -+ -+ if (unique_aux) { -+ sec_mux_list[0] = kasprintf(GFP_KERNEL, "acpu%s_aux", s); -+ if (!sec_mux_list[0]) { -+ clk = ERR_PTR(-ENOMEM); -+ goto err_aux; -+ } -+ } -+ -+ clk = devm_clk_register(dev, &mux->hw); -+ -+ if (unique_aux) -+ kfree(sec_mux_list[0]); -+err_aux: -+ kfree(init.name); -+ return PTR_ERR_OR_ZERO(clk); -+} -+ -+static struct clk * -+krait_add_pri_mux(struct device *dev, int id, const char *s, unsigned offset) -+{ -+ struct krait_mux_clk *mux; -+ const char *p_names[3]; -+ struct clk_init_data init = { -+ .parent_names = p_names, -+ .num_parents = ARRAY_SIZE(p_names), -+ .ops = &krait_mux_clk_ops, -+ .flags = CLK_SET_RATE_PARENT, -+ }; -+ struct clk *clk; -+ -+ mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL); -+ if (!mux) -+ return ERR_PTR(-ENOMEM); -+ -+ mux->has_safe_parent = true; -+ mux->safe_sel = 0; -+ mux->mask = 0x3; -+ mux->shift = 0; -+ mux->offset = offset; -+ mux->lpl = id >= 0; -+ mux->parent_map = pri_mux_map; -+ mux->hw.init = &init; -+ -+ init.name = kasprintf(GFP_KERNEL, "krait%s_pri_mux", s); -+ if (!init.name) -+ return ERR_PTR(-ENOMEM); -+ -+ p_names[0] = kasprintf(GFP_KERNEL, "hfpll%s", s); -+ if (!p_names[0]) { -+ clk = ERR_PTR(-ENOMEM); -+ goto err_p0; -+ } -+ -+ p_names[1] = kasprintf(GFP_KERNEL, "hfpll%s_div", s); -+ if (!p_names[1]) { -+ clk = ERR_PTR(-ENOMEM); -+ goto err_p1; -+ } -+ -+ p_names[2] = kasprintf(GFP_KERNEL, "krait%s_sec_mux", s); -+ if (!p_names[2]) { -+ clk = ERR_PTR(-ENOMEM); -+ goto err_p2; -+ } -+ -+ clk = devm_clk_register(dev, &mux->hw); -+ -+ kfree(p_names[2]); -+err_p2: -+ kfree(p_names[1]); -+err_p1: -+ kfree(p_names[0]); -+err_p0: -+ kfree(init.name); -+ return clk; -+} -+ -+/* id < 0 for L2, otherwise id == physical CPU number */ -+static struct clk *krait_add_clks(struct device *dev, int id, bool unique_aux) -+{ -+ int ret; -+ unsigned offset; -+ void *p = NULL; -+ const char *s; -+ struct clk *clk; -+ -+ if (id >= 0) { -+ offset = 0x4501 + (0x1000 * id); -+ s = p = kasprintf(GFP_KERNEL, "%d", id); -+ if (!s) -+ return ERR_PTR(-ENOMEM); -+ } else { -+ offset = 0x500; -+ s = "_l2"; -+ } -+ -+ ret = krait_add_div(dev, id, s, offset); -+ if (ret) { -+ clk = ERR_PTR(ret); -+ goto err; -+ } -+ -+ ret = krait_add_sec_mux(dev, id, s, offset, unique_aux); -+ if (ret) { -+ clk = ERR_PTR(ret); -+ goto err; -+ } -+ -+ clk = krait_add_pri_mux(dev, id, s, offset); -+err: -+ kfree(p); -+ return clk; -+} -+ -+static struct clk *krait_of_get(struct of_phandle_args *clkspec, void *data) -+{ -+ unsigned int idx = clkspec->args[0]; -+ struct clk **clks = data; -+ -+ if (idx >= 5) { -+ pr_err("%s: invalid clock index %d\n", __func__, idx); -+ return ERR_PTR(-EINVAL); -+ } -+ -+ return clks[idx] ? : ERR_PTR(-ENODEV); -+} -+ -+static const struct of_device_id krait_cc_match_table[] = { -+ { .compatible = "qcom,krait-cc-v1", (void *)1UL }, -+ { .compatible = "qcom,krait-cc-v2" }, -+ {} -+}; -+MODULE_DEVICE_TABLE(of, krait_cc_match_table); -+ -+static int krait_cc_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ const struct of_device_id *id; -+ unsigned long cur_rate, aux_rate; -+ int cpu; -+ struct clk *clk; -+ struct clk **clks; -+ struct clk *l2_pri_mux_clk; -+ -+ id = of_match_device(krait_cc_match_table, dev); -+ if (!id) -+ return -ENODEV; -+ -+ /* Rate is 1 because 0 causes problems for __clk_mux_determine_rate */ -+ clk = clk_register_fixed_rate(dev, "qsb", NULL, CLK_IS_ROOT, 1); -+ if (IS_ERR(clk)) -+ return PTR_ERR(clk); -+ -+ if (!id->data) { -+ clk = clk_register_fixed_factor(dev, "acpu_aux", -+ "gpll0_vote", 0, 1, 2); -+ if (IS_ERR(clk)) -+ return PTR_ERR(clk); -+ } -+ -+ /* Krait configurations have at most 4 CPUs and one L2 */ -+ clks = devm_kcalloc(dev, 5, sizeof(*clks), GFP_KERNEL); -+ if (!clks) -+ return -ENOMEM; -+ -+ for_each_possible_cpu(cpu) { -+ clk = krait_add_clks(dev, cpu, id->data); -+ if (IS_ERR(clk)) -+ return PTR_ERR(clk); -+ clks[cpu] = clk; -+ } -+ -+ l2_pri_mux_clk = krait_add_clks(dev, -1, id->data); -+ if (IS_ERR(l2_pri_mux_clk)) -+ return PTR_ERR(l2_pri_mux_clk); -+ clks[4] = l2_pri_mux_clk; -+ -+ /* -+ * We don't want the CPU or L2 clocks to be turned off at late init -+ * if CPUFREQ or HOTPLUG configs are disabled. So, bump up the -+ * refcount of these clocks. Any cpufreq/hotplug manager can assume -+ * that the clocks have already been prepared and enabled by the time -+ * they take over. -+ */ -+ for_each_online_cpu(cpu) { -+ clk_prepare_enable(l2_pri_mux_clk); -+ WARN(clk_prepare_enable(clks[cpu]), -+ "Unable to turn on CPU%d clock", cpu); -+ } -+ -+ /* -+ * Force reinit of HFPLLs and muxes to overwrite any potential -+ * incorrect configuration of HFPLLs and muxes by the bootloader. -+ * While at it, also make sure the cores are running at known rates -+ * and print the current rate. -+ * -+ * The clocks are set to aux clock rate first to make sure the -+ * secondary mux is not sourcing off of QSB. The rate is then set to -+ * two different rates to force a HFPLL reinit under all -+ * circumstances. -+ */ -+ cur_rate = clk_get_rate(l2_pri_mux_clk); -+ aux_rate = 384000000; -+ if (cur_rate == 1) { -+ pr_info("L2 @ QSB rate. Forcing new rate.\n"); -+ cur_rate = aux_rate; -+ } -+ clk_set_rate(l2_pri_mux_clk, aux_rate); -+ clk_set_rate(l2_pri_mux_clk, 2); -+ clk_set_rate(l2_pri_mux_clk, cur_rate); -+ pr_info("L2 @ %lu KHz\n", clk_get_rate(l2_pri_mux_clk) / 1000); -+ for_each_possible_cpu(cpu) { -+ clk = clks[cpu]; -+ cur_rate = clk_get_rate(clk); -+ if (cur_rate == 1) { -+ pr_info("CPU%d @ QSB rate. Forcing new rate.\n", cpu); -+ cur_rate = aux_rate; -+ } -+ clk_set_rate(clk, aux_rate); -+ clk_set_rate(clk, 2); -+ clk_set_rate(clk, cur_rate); -+ pr_info("CPU%d @ %lu KHz\n", cpu, clk_get_rate(clk) / 1000); -+ } -+ -+ of_clk_add_provider(dev->of_node, krait_of_get, clks); -+ -+ return 0; -+} -+ -+static struct platform_driver krait_cc_driver = { -+ .probe = krait_cc_probe, -+ .driver = { -+ .name = "krait-cc", -+ .of_match_table = krait_cc_match_table, -+ }, -+}; -+module_platform_driver(krait_cc_driver); -+ -+MODULE_DESCRIPTION("Krait CPU Clock Driver"); -+MODULE_LICENSE("GPL v2"); -+MODULE_ALIAS("platform:krait-cc"); diff --git a/target/linux/ipq806x/patches-3.18/143-cpufreq-Add-module-to-register-cpufreq-on-Krait-CPUs.patch b/target/linux/ipq806x/patches-3.18/143-cpufreq-Add-module-to-register-cpufreq-on-Krait-CPUs.patch deleted file mode 100644 index c3ca9b5f70..0000000000 --- a/target/linux/ipq806x/patches-3.18/143-cpufreq-Add-module-to-register-cpufreq-on-Krait-CPUs.patch +++ /dev/null @@ -1,304 +0,0 @@ -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: [v3,12/13] cpufreq: Add module to register cpufreq on Krait CPUs -From: Stephen Boyd -X-Patchwork-Id: 6063191 -Message-Id: <1426920332-9340-13-git-send-email-sboyd@codeaurora.org> -To: Mike Turquette , Stephen Boyd -Cc: linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, - linux-pm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, - Viresh Kumar , -Date: Fri, 20 Mar 2015 23:45:31 -0700 - -Register a cpufreq-generic device whenever we detect that a -"qcom,krait" compatible CPU is present in DT. - -Cc: -Signed-off-by: Stephen Boyd - ---- -.../devicetree/bindings/arm/msm/qcom,pvs.txt | 38 ++++ - drivers/cpufreq/Kconfig.arm | 9 + - drivers/cpufreq/Makefile | 1 + - drivers/cpufreq/qcom-cpufreq.c | 204 +++++++++++++++++++++ - 4 files changed, 252 insertions(+) - create mode 100644 Documentation/devicetree/bindings/arm/msm/qcom,pvs.txt - create mode 100644 drivers/cpufreq/qcom-cpufreq.c - ---- /dev/null -+++ b/Documentation/devicetree/bindings/arm/msm/qcom,pvs.txt -@@ -0,0 +1,38 @@ -+Qualcomm Process Voltage Scaling Tables -+ -+The node name is required to be "qcom,pvs". There shall only be one -+such node present in the root of the tree. -+ -+PROPERTIES -+ -+- qcom,pvs-format-a or qcom,pvs-format-b: -+ Usage: required -+ Value type: -+ Definition: Indicates the format of qcom,speedX-pvsY-bin-vZ properties. -+ If qcom,pvs-format-a is used the table is two columns -+ (frequency and voltage in that order). If qcom,pvs-format-b is used the table is three columns (frequency, voltage, -+ and current in that order). -+ -+- qcom,speedX-pvsY-bin-vZ: -+ Usage: required -+ Value type: -+ Definition: The PVS table corresponding to the speed bin X, pvs bin Y, -+ and version Z. -+Example: -+ -+ qcom,pvs { -+ qcom,pvs-format-a; -+ qcom,speed0-pvs0-bin-v0 = -+ < 384000000 950000 >, -+ < 486000000 975000 >, -+ < 594000000 1000000 >, -+ < 702000000 1025000 >, -+ < 810000000 1075000 >, -+ < 918000000 1100000 >, -+ < 1026000000 1125000 >, -+ < 1134000000 1175000 >, -+ < 1242000000 1200000 >, -+ < 1350000000 1225000 >, -+ < 1458000000 1237500 >, -+ < 1512000000 1250000 >; -+ }; ---- a/drivers/cpufreq/Kconfig.arm -+++ b/drivers/cpufreq/Kconfig.arm -@@ -129,6 +129,15 @@ config ARM_OMAP2PLUS_CPUFREQ - depends on ARCH_OMAP2PLUS - default ARCH_OMAP2PLUS - -+config ARM_QCOM_CPUFREQ -+ tristate "Qualcomm based" -+ depends on ARCH_QCOM -+ select PM_OPP -+ help -+ This adds the CPUFreq driver for Qualcomm SoC based boards. -+ -+ If in doubt, say N. -+ - config ARM_S3C_CPUFREQ - bool - help ---- a/drivers/cpufreq/Makefile -+++ b/drivers/cpufreq/Makefile -@@ -64,6 +64,7 @@ obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ) += o - obj-$(CONFIG_PXA25x) += pxa2xx-cpufreq.o - obj-$(CONFIG_PXA27x) += pxa2xx-cpufreq.o - obj-$(CONFIG_PXA3xx) += pxa3xx-cpufreq.o -+obj-$(CONFIG_ARM_QCOM_CPUFREQ) += qcom-cpufreq.o - obj-$(CONFIG_ARM_S3C24XX_CPUFREQ) += s3c24xx-cpufreq.o - obj-$(CONFIG_ARM_S3C24XX_CPUFREQ_DEBUGFS) += s3c24xx-cpufreq-debugfs.o - obj-$(CONFIG_ARM_S3C2410_CPUFREQ) += s3c2410-cpufreq.o ---- /dev/null -+++ b/drivers/cpufreq/qcom-cpufreq.c -@@ -0,0 +1,204 @@ -+/* Copyright (c) 2014, The Linux Foundation. All rights reserved. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 and -+ * only version 2 as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+static void __init get_krait_bin_format_a(int *speed, int *pvs, int *pvs_ver) -+{ -+ void __iomem *base; -+ u32 pte_efuse; -+ -+ *speed = *pvs = *pvs_ver = 0; -+ -+ base = ioremap(0x007000c0, 4); -+ if (!base) { -+ pr_warn("Unable to read efuse data. Defaulting to 0!\n"); -+ return; -+ } -+ -+ pte_efuse = readl_relaxed(base); -+ iounmap(base); -+ -+ *speed = pte_efuse & 0xf; -+ if (*speed == 0xf) -+ *speed = (pte_efuse >> 4) & 0xf; -+ -+ if (*speed == 0xf) { -+ *speed = 0; -+ pr_warn("Speed bin: Defaulting to %d\n", *speed); -+ } else { -+ pr_info("Speed bin: %d\n", *speed); -+ } -+ -+ *pvs = (pte_efuse >> 10) & 0x7; -+ if (*pvs == 0x7) -+ *pvs = (pte_efuse >> 13) & 0x7; -+ -+ if (*pvs == 0x7) { -+ *pvs = 0; -+ pr_warn("PVS bin: Defaulting to %d\n", *pvs); -+ } else { -+ pr_info("PVS bin: %d\n", *pvs); -+ } -+} -+ -+static void __init get_krait_bin_format_b(int *speed, int *pvs, int *pvs_ver) -+{ -+ u32 pte_efuse, redundant_sel; -+ void __iomem *base; -+ -+ *speed = 0; -+ *pvs = 0; -+ *pvs_ver = 0; -+ -+ base = ioremap(0xfc4b80b0, 8); -+ if (!base) { -+ pr_warn("Unable to read efuse data. Defaulting to 0!\n"); -+ return; -+ } -+ -+ pte_efuse = readl_relaxed(base); -+ redundant_sel = (pte_efuse >> 24) & 0x7; -+ *speed = pte_efuse & 0x7; -+ /* 4 bits of PVS are in efuse register bits 31, 8-6. */ -+ *pvs = ((pte_efuse >> 28) & 0x8) | ((pte_efuse >> 6) & 0x7); -+ *pvs_ver = (pte_efuse >> 4) & 0x3; -+ -+ switch (redundant_sel) { -+ case 1: -+ *speed = (pte_efuse >> 27) & 0xf; -+ break; -+ case 2: -+ *pvs = (pte_efuse >> 27) & 0xf; -+ break; -+ } -+ -+ /* Check SPEED_BIN_BLOW_STATUS */ -+ if (pte_efuse & BIT(3)) { -+ pr_info("Speed bin: %d\n", *speed); -+ } else { -+ pr_warn("Speed bin not set. Defaulting to 0!\n"); -+ *speed = 0; -+ } -+ -+ /* Check PVS_BLOW_STATUS */ -+ pte_efuse = readl_relaxed(base + 0x4) & BIT(21); -+ if (pte_efuse) { -+ pr_info("PVS bin: %d\n", *pvs); -+ } else { -+ pr_warn("PVS bin not set. Defaulting to 0!\n"); -+ *pvs = 0; -+ } -+ -+ pr_info("PVS version: %d\n", *pvs_ver); -+ iounmap(base); -+} -+ -+static int __init qcom_cpufreq_populate_opps(void) -+{ -+ int len, rows, cols, i, k, speed, pvs, pvs_ver; -+ char table_name[] = "qcom,speedXX-pvsXX-bin-vXX"; -+ struct device_node *np; -+ struct device *dev; -+ int cpu = 0; -+ -+ np = of_find_node_by_name(NULL, "qcom,pvs"); -+ if (!np) -+ return -ENODEV; -+ -+ if (of_property_read_bool(np, "qcom,pvs-format-a")) { -+ get_krait_bin_format_a(&speed, &pvs, &pvs_ver); -+ cols = 2; -+ } else if (of_property_read_bool(np, "qcom,pvs-format-b")) { -+ get_krait_bin_format_b(&speed, &pvs, &pvs_ver); -+ cols = 3; -+ } else { -+ return -ENODEV; -+ } -+ -+ snprintf(table_name, sizeof(table_name), -+ "qcom,speed%d-pvs%d-bin-v%d", speed, pvs, pvs_ver); -+ -+ if (!of_find_property(np, table_name, &len)) -+ return -EINVAL; -+ -+ len /= sizeof(u32); -+ if (len % cols || len == 0) -+ return -EINVAL; -+ -+ rows = len / cols; -+ -+ for (i = 0, k = 0; i < rows; i++) { -+ u32 freq, volt; -+ -+ of_property_read_u32_index(np, table_name, k++, &freq); -+ of_property_read_u32_index(np, table_name, k++, &volt); -+ while (k % cols) -+ k++; /* Skip uA entries if present */ -+ for (cpu = 0; cpu < num_possible_cpus(); cpu++) { -+ dev = get_cpu_device(cpu); -+ if (!dev) -+ return -ENODEV; -+ if (dev_pm_opp_add(dev, freq, volt)) -+ pr_warn("failed to add OPP %u\n", freq); -+ } -+ } -+ -+ return 0; -+} -+ -+static int __init qcom_cpufreq_driver_init(void) -+{ -+ struct cpufreq_dt_platform_data pdata = { .independent_clocks = true }; -+ struct platform_device_info devinfo = { -+ .name = "cpufreq-dt", -+ .data = &pdata, -+ .size_data = sizeof(pdata), -+ }; -+ struct device *cpu_dev; -+ struct device_node *np; -+ int ret; -+ -+ cpu_dev = get_cpu_device(0); -+ if (!cpu_dev) -+ return -ENODEV; -+ -+ np = of_node_get(cpu_dev->of_node); -+ if (!np) -+ return -ENOENT; -+ -+ if (!of_device_is_compatible(np, "qcom,krait")) { -+ of_node_put(np); -+ return -ENODEV; -+ } -+ of_node_put(np); -+ -+ ret = qcom_cpufreq_populate_opps(); -+ if (ret) -+ return ret; -+ -+ return PTR_ERR_OR_ZERO(platform_device_register_full(&devinfo)); -+} -+module_init(qcom_cpufreq_driver_init); -+ -+MODULE_DESCRIPTION("Qualcomm CPUfreq driver"); -+MODULE_LICENSE("GPL v2"); diff --git a/target/linux/ipq806x/patches-3.18/144-ARM-dts-qcom-Add-necessary-DT-data-for-Krait-cpufreq.patch b/target/linux/ipq806x/patches-3.18/144-ARM-dts-qcom-Add-necessary-DT-data-for-Krait-cpufreq.patch deleted file mode 100644 index a3c3bbfc9e..0000000000 --- a/target/linux/ipq806x/patches-3.18/144-ARM-dts-qcom-Add-necessary-DT-data-for-Krait-cpufreq.patch +++ /dev/null @@ -1,100 +0,0 @@ ---- a/arch/arm/boot/dts/qcom-ipq8064.dtsi -+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi -@@ -24,6 +24,11 @@ - next-level-cache = <&L2>; - qcom,acc = <&acc0>; - qcom,saw = <&saw0>; -+ clocks = <&kraitcc 0>; -+ clock-names = "cpu"; -+ clock-latency = <100000>; -+ core-supply = <&smb208_s2a>; -+ voltage-tolerance = <5>; - }; - - cpu@1 { -@@ -34,11 +39,24 @@ - next-level-cache = <&L2>; - qcom,acc = <&acc1>; - qcom,saw = <&saw1>; -+ clocks = <&kraitcc 1>; -+ clock-names = "cpu"; -+ clock-latency = <100000>; -+ core-supply = <&smb208_s2b>; - }; - - L2: l2-cache { - compatible = "cache"; - cache-level = <2>; -+ clocks = <&kraitcc 4>; -+ clock-names = "cache"; -+ cache-points-kHz = < -+ /* kHz uV CPU kHz */ -+ 1200000 1150000 1200000 -+ 1000000 1100000 600000 -+ 384000 1100000 384000 -+ >; -+ vdd_dig-supply = <&smb208_s1a>; - }; - }; - -@@ -71,6 +89,46 @@ - }; - }; - -+ kraitcc: clock-controller { -+ compatible = "qcom,krait-cc-v1"; -+ #clock-cells = <1>; -+ }; -+ -+ qcom,pvs { -+ qcom,pvs-format-a; -+ qcom,speed0-pvs0-bin-v0 = -+ < 1400000000 1250000 >, -+ < 1200000000 1200000 >, -+ < 1000000000 1150000 >, -+ < 800000000 1100000 >, -+ < 600000000 1050000 >, -+ < 384000000 1000000 >; -+ -+ qcom,speed0-pvs1-bin-v0 = -+ < 1400000000 1175000 >, -+ < 1200000000 1125000 >, -+ < 1000000000 1075000 >, -+ < 800000000 1025000 >, -+ < 600000000 975000 >, -+ < 384000000 925000 >; -+ -+ qcom,speed0-pvs2-bin-v0 = -+ < 1400000000 1125000 >, -+ < 1200000000 1075000 >, -+ < 1000000000 1025000 >, -+ < 800000000 995000 >, -+ < 600000000 925000 >, -+ < 384000000 875000 >; -+ -+ qcom,speed0-pvs3-bin-v0 = -+ < 1400000000 1050000 >, -+ < 1200000000 1000000 >, -+ < 1000000000 950000 >, -+ < 800000000 900000 >, -+ < 600000000 850000 >, -+ < 384000000 800000 >; -+ }; -+ - soc: soc { - #address-cells = <1>; - #size-cells = <1>; -@@ -171,11 +229,13 @@ - acc0: clock-controller@2088000 { - compatible = "qcom,kpss-acc-v1"; - reg = <0x02088000 0x1000>, <0x02008000 0x1000>; -+ clock-output-names = "acpu0_aux"; - }; - - acc1: clock-controller@2098000 { - compatible = "qcom,kpss-acc-v1"; - reg = <0x02098000 0x1000>, <0x02008000 0x1000>; -+ clock-output-names = "acpu1_aux"; - }; - - l2cc: clock-controller@2011000 { diff --git a/target/linux/ipq806x/patches-3.18/145-cpufreq-Add-a-cpufreq-krait-based-on-cpufre.patch b/target/linux/ipq806x/patches-3.18/145-cpufreq-Add-a-cpufreq-krait-based-on-cpufre.patch deleted file mode 100644 index 15cabf3eb9..0000000000 --- a/target/linux/ipq806x/patches-3.18/145-cpufreq-Add-a-cpufreq-krait-based-on-cpufre.patch +++ /dev/null @@ -1,461 +0,0 @@ -From dd77db4143290689d3a5e1ec61627233d0711b66 Mon Sep 17 00:00:00 2001 -From: Stephen Boyd -Date: Fri, 30 May 2014 16:36:11 -0700 -Subject: [PATCH] FROMLIST: cpufreq: Add a cpufreq-krait based on cpufreq-cpu0 - -Krait processors have individual clocks for each CPU that can -scale independently from one another. cpufreq-cpu0 is fairly -close to this, but assumes that there is only one clock for all -CPUs. Add a driver to support the Krait configuration. - -TODO: Merge into cpufreq-cpu0? Or make generic? - -Signed-off-by: Stephen Boyd - ---- - drivers/cpufreq/Kconfig | 13 +++ - drivers/cpufreq/Makefile | 1 + - drivers/cpufreq/cpufreq-krait.c | 190 ++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 204 insertions(+) - create mode 100644 drivers/cpufreq/cpufreq-krait.c - ---- a/drivers/cpufreq/Kconfig -+++ b/drivers/cpufreq/Kconfig -@@ -196,6 +196,19 @@ config CPUFREQ_DT - - If in doubt, say N. - -+config GENERIC_CPUFREQ_KRAIT -+ tristate "Krait cpufreq driver" -+ depends on HAVE_CLK && OF -+ # if CPU_THERMAL is on and THERMAL=m, CPU0 cannot be =y: -+ depends on !CPU_THERMAL || THERMAL -+ select PM_OPP -+ help -+ This adds a generic cpufreq driver for CPU0 frequency management. -+ It supports both uniprocessor (UP) and symmetric multiprocessor (SMP) -+ systems which share clock and voltage across all CPUs. -+ -+ If in doubt, say N. -+ - menu "x86 CPU frequency scaling drivers" - depends on X86 - source "drivers/cpufreq/Kconfig.x86" ---- a/drivers/cpufreq/Makefile -+++ b/drivers/cpufreq/Makefile -@@ -14,6 +14,7 @@ obj-$(CONFIG_CPU_FREQ_GOV_CONSERVATIVE) - obj-$(CONFIG_CPU_FREQ_GOV_COMMON) += cpufreq_governor.o - - obj-$(CONFIG_CPUFREQ_DT) += cpufreq-dt.o -+obj-$(CONFIG_GENERIC_CPUFREQ_KRAIT) += cpufreq-krait.o - - ################################################################################## - # x86 drivers. ---- /dev/null -+++ b/drivers/cpufreq/cpufreq-krait.c -@@ -0,0 +1,390 @@ -+/* -+ * Copyright (C) 2012 Freescale Semiconductor, Inc. -+ * Copyright (c) 2014, The Linux Foundation. All rights reserved. -+ * -+ * The OPP code in function krait_set_target() is reused from -+ * drivers/cpufreq/omap-cpufreq.c -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+static unsigned int transition_latency; -+static unsigned int voltage_tolerance; /* in percentage */ -+ -+static struct device *cpu_dev; -+static DEFINE_PER_CPU(struct clk *, krait_cpu_clks); -+static DEFINE_PER_CPU(struct regulator *, krait_supply_core); -+static struct cpufreq_frequency_table *freq_table; -+static struct thermal_cooling_device *cdev; -+ -+struct cache_points { -+ unsigned long cache_freq; -+ unsigned int cache_volt; -+ unsigned long cpu_freq; -+}; -+ -+static struct regulator *krait_l2_reg; -+static struct clk *krait_l2_clk; -+static struct cache_points *krait_l2_points; -+static int nr_krait_l2_points; -+ -+static int krait_parse_cache_points(struct device *dev, -+ struct device_node *of_node) -+{ -+ const struct property *prop; -+ const __be32 *val; -+ int nr, i; -+ -+ prop = of_find_property(of_node, "cache-points-kHz", NULL); -+ if (!prop) -+ return -ENODEV; -+ if (!prop->value) -+ return -ENODATA; -+ -+ /* -+ * Each OPP is a set of tuples consisting of frequency and -+ * cpu-frequency like . -+ */ -+ nr = prop->length / sizeof(u32); -+ if (nr % 3) { -+ dev_err(dev, "%s: Invalid cache points\n", __func__); -+ return -EINVAL; -+ } -+ nr /= 3; -+ -+ krait_l2_points = devm_kcalloc(dev, nr, sizeof(*krait_l2_points), -+ GFP_KERNEL); -+ if (!krait_l2_points) -+ return -ENOMEM; -+ nr_krait_l2_points = nr; -+ -+ for (i = 0, val = prop->value; i < nr; i++) { -+ unsigned long cache_freq = be32_to_cpup(val++) * 1000; -+ unsigned int cache_volt = be32_to_cpup(val++); -+ unsigned long cpu_freq = be32_to_cpup(val++) * 1000; -+ -+ krait_l2_points[i].cache_freq = cache_freq; -+ krait_l2_points[i].cache_volt = cache_volt; -+ krait_l2_points[i].cpu_freq = cpu_freq; -+ } -+ -+ return 0; -+} -+ -+static int krait_set_target(struct cpufreq_policy *policy, unsigned int index) -+{ -+ struct dev_pm_opp *opp; -+ unsigned long volt = 0, volt_old = 0, tol = 0; -+ unsigned long freq, max_cpu_freq = 0; -+ unsigned int old_freq, new_freq; -+ long freq_Hz, freq_exact; -+ int ret, i; -+ struct clk *cpu_clk; -+ struct regulator *core; -+ unsigned int cpu; -+ -+ cpu_clk = per_cpu(krait_cpu_clks, policy->cpu); -+ -+ freq_Hz = clk_round_rate(cpu_clk, freq_table[index].frequency * 1000); -+ if (freq_Hz <= 0) -+ freq_Hz = freq_table[index].frequency * 1000; -+ -+ freq_exact = freq_Hz; -+ new_freq = freq_Hz / 1000; -+ old_freq = clk_get_rate(cpu_clk) / 1000; -+ -+ core = per_cpu(krait_supply_core, policy->cpu); -+ -+ rcu_read_lock(); -+ opp = dev_pm_opp_find_freq_ceil(cpu_dev, &freq_Hz); -+ if (IS_ERR(opp)) { -+ rcu_read_unlock(); -+ pr_err("failed to find OPP for %ld\n", freq_Hz); -+ return PTR_ERR(opp); -+ } -+ volt = dev_pm_opp_get_voltage(opp); -+ rcu_read_unlock(); -+ tol = volt * voltage_tolerance / 100; -+ volt_old = regulator_get_voltage(core); -+ -+ pr_debug("%u MHz, %ld mV --> %u MHz, %ld mV\n", -+ old_freq / 1000, volt_old ? volt_old / 1000 : -1, -+ new_freq / 1000, volt ? volt / 1000 : -1); -+ -+ /* scaling up? scale voltage before frequency */ -+ if (new_freq > old_freq) { -+ ret = regulator_set_voltage_tol(core, volt, tol); -+ if (ret) { -+ pr_err("failed to scale voltage up: %d\n", ret); -+ return ret; -+ } -+ } -+ -+ ret = clk_set_rate(cpu_clk, freq_exact); -+ if (ret) { -+ pr_err("failed to set clock rate: %d\n", ret); -+ return ret; -+ } -+ -+ /* scaling down? scale voltage after frequency */ -+ if (new_freq < old_freq) { -+ ret = regulator_set_voltage_tol(core, volt, tol); -+ if (ret) { -+ pr_err("failed to scale voltage down: %d\n", ret); -+ clk_set_rate(cpu_clk, old_freq * 1000); -+ } -+ } -+ -+ for_each_possible_cpu(cpu) { -+ freq = clk_get_rate(per_cpu(krait_cpu_clks, cpu)); -+ max_cpu_freq = max(max_cpu_freq, freq); -+ } -+ -+ for (i = 0; i < nr_krait_l2_points; i++) { -+ if (max_cpu_freq >= krait_l2_points[i].cpu_freq) { -+ if (krait_l2_reg) { -+ ret = regulator_set_voltage_tol(krait_l2_reg, -+ krait_l2_points[i].cache_volt, -+ tol); -+ if (ret) { -+ pr_err("failed to scale l2 voltage: %d\n", -+ ret); -+ } -+ } -+ ret = clk_set_rate(krait_l2_clk, -+ krait_l2_points[i].cache_freq); -+ if (ret) -+ pr_err("failed to scale l2 clk: %d\n", ret); -+ break; -+ } -+ -+ } -+ -+ return ret; -+} -+ -+static int krait_cpufreq_init(struct cpufreq_policy *policy) -+{ -+ int ret; -+ -+ policy->clk = per_cpu(krait_cpu_clks, policy->cpu); -+ -+ ret = cpufreq_table_validate_and_show(policy, freq_table); -+ if (ret) { -+ pr_err("%s: invalid frequency table: %d\n", __func__, ret); -+ return ret; -+ } -+ -+ policy->cpuinfo.transition_latency = transition_latency; -+ -+ return 0; -+} -+ -+static struct cpufreq_driver krait_cpufreq_driver = { -+ .flags = CPUFREQ_STICKY, -+ .verify = cpufreq_generic_frequency_table_verify, -+ .target_index = krait_set_target, -+ .get = cpufreq_generic_get, -+ .init = krait_cpufreq_init, -+ .name = "generic_krait", -+ .attr = cpufreq_generic_attr, -+}; -+ -+static int krait_cpufreq_probe(struct platform_device *pdev) -+{ -+ struct device_node *np, *cache; -+ int ret, i; -+ unsigned int cpu; -+ struct device *dev; -+ struct clk *clk; -+ struct regulator *core; -+ unsigned long freq_Hz, freq, max_cpu_freq; -+ struct dev_pm_opp *opp; -+ unsigned long volt, tol; -+ -+ cpu_dev = get_cpu_device(0); -+ if (!cpu_dev) { -+ pr_err("failed to get krait device\n"); -+ return -ENODEV; -+ } -+ -+ np = of_node_get(cpu_dev->of_node); -+ if (!np) { -+ pr_err("failed to find krait node\n"); -+ return -ENOENT; -+ } -+ -+ ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table); -+ if (ret) { -+ pr_err("failed to init cpufreq table: %d\n", ret); -+ goto out_put_node; -+ } -+ -+ of_property_read_u32(np, "voltage-tolerance", &voltage_tolerance); -+ -+ if (of_property_read_u32(np, "clock-latency", &transition_latency)) -+ transition_latency = CPUFREQ_ETERNAL; -+ -+ cache = of_find_next_cache_node(np); -+ if (cache) { -+ struct device_node *vdd; -+ -+ vdd = of_parse_phandle(cache, "vdd_dig-supply", 0); -+ if (vdd) { -+ krait_l2_reg = regulator_get(NULL, vdd->name); -+ if (IS_ERR(krait_l2_reg)) { -+ pr_warn("failed to get l2 vdd_dig supply\n"); -+ krait_l2_reg = NULL; -+ } -+ of_node_put(vdd); -+ } -+ -+ krait_l2_clk = of_clk_get(cache, 0); -+ if (!IS_ERR(krait_l2_clk)) { -+ ret = krait_parse_cache_points(&pdev->dev, cache); -+ if (ret) -+ clk_put(krait_l2_clk); -+ } -+ if (IS_ERR(krait_l2_clk) || ret) -+ krait_l2_clk = NULL; -+ } -+ -+ for_each_possible_cpu(cpu) { -+ dev = get_cpu_device(cpu); -+ if (!dev) { -+ pr_err("failed to get krait device\n"); -+ ret = -ENOENT; -+ goto out_free_table; -+ } -+ per_cpu(krait_cpu_clks, cpu) = clk = devm_clk_get(dev, NULL); -+ if (IS_ERR(clk)) { -+ ret = PTR_ERR(clk); -+ goto out_free_table; -+ } -+ core = devm_regulator_get(dev, "core"); -+ if (IS_ERR(core)) { -+ pr_debug("failed to get core regulator\n"); -+ ret = PTR_ERR(core); -+ goto out_free_table; -+ } -+ per_cpu(krait_supply_core, cpu) = core; -+ -+ freq_Hz = clk_get_rate(clk); -+ -+ rcu_read_lock(); -+ opp = dev_pm_opp_find_freq_ceil(cpu_dev, &freq_Hz); -+ if (IS_ERR(opp)) { -+ rcu_read_unlock(); -+ pr_err("failed to find OPP for %ld\n", freq_Hz); -+ ret = PTR_ERR(opp); -+ goto out_free_table; -+ } -+ volt = dev_pm_opp_get_voltage(opp); -+ rcu_read_unlock(); -+ -+ tol = volt * voltage_tolerance / 100; -+ ret = regulator_set_voltage_tol(core, volt, tol); -+ if (ret) { -+ pr_err("failed to scale voltage up: %d\n", ret); -+ goto out_free_table; -+ } -+ ret = regulator_enable(core); -+ if (ret) { -+ pr_err("failed to enable regulator: %d\n", ret); -+ goto out_free_table; -+ } -+ max_cpu_freq = max(max_cpu_freq, freq); -+ } -+ -+ for (i = 0; i < nr_krait_l2_points; i++) { -+ if (max_cpu_freq >= krait_l2_points[i].cpu_freq) { -+ if (krait_l2_reg) { -+ ret = regulator_set_voltage_tol(krait_l2_reg, -+ krait_l2_points[i].cache_volt, -+ tol); -+ if (ret) -+ pr_err("failed to scale l2 voltage: %d\n", -+ ret); -+ ret = regulator_enable(krait_l2_reg); -+ if (ret) -+ pr_err("failed to enable l2 voltage: %d\n", -+ ret); -+ } -+ break; -+ } -+ -+ } -+ -+ ret = cpufreq_register_driver(&krait_cpufreq_driver); -+ if (ret) { -+ pr_err("failed register driver: %d\n", ret); -+ goto out_free_table; -+ } -+ of_node_put(np); -+ -+ /* -+ * For now, just loading the cooling device; -+ * thermal DT code takes care of matching them. -+ */ -+ for_each_possible_cpu(cpu) { -+ dev = get_cpu_device(cpu); -+ np = of_node_get(dev->of_node); -+ if (of_find_property(np, "#cooling-cells", NULL)) { -+ cdev = of_cpufreq_cooling_register(np, cpumask_of(cpu)); -+ if (IS_ERR(cdev)) -+ pr_err("running cpufreq without cooling device: %ld\n", -+ PTR_ERR(cdev)); -+ } -+ of_node_put(np); -+ } -+ -+ return 0; -+ -+out_free_table: -+ regulator_put(krait_l2_reg); -+ clk_put(krait_l2_clk); -+ dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table); -+out_put_node: -+ of_node_put(np); -+ return ret; -+} -+ -+static int krait_cpufreq_remove(struct platform_device *pdev) -+{ -+ cpufreq_cooling_unregister(cdev); -+ cpufreq_unregister_driver(&krait_cpufreq_driver); -+ dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table); -+ clk_put(krait_l2_clk); -+ regulator_put(krait_l2_reg); -+ -+ return 0; -+} -+ -+static struct platform_driver krait_cpufreq_platdrv = { -+ .driver = { -+ .name = "cpufreq-krait", -+ .owner = THIS_MODULE, -+ }, -+ .probe = krait_cpufreq_probe, -+ .remove = krait_cpufreq_remove, -+}; -+module_platform_driver(krait_cpufreq_platdrv); -+ -+MODULE_DESCRIPTION("Krait CPUfreq driver"); -+MODULE_LICENSE("GPL v2"); ---- a/drivers/cpufreq/qcom-cpufreq.c -+++ b/drivers/cpufreq/qcom-cpufreq.c -@@ -168,11 +168,8 @@ static int __init qcom_cpufreq_populate_ - - static int __init qcom_cpufreq_driver_init(void) - { -- struct cpufreq_dt_platform_data pdata = { .independent_clocks = true }; - struct platform_device_info devinfo = { -- .name = "cpufreq-dt", -- .data = &pdata, -- .size_data = sizeof(pdata), -+ .name = "cpufreq-krait", - }; - struct device *cpu_dev; - struct device_node *np; diff --git a/target/linux/ipq806x/patches-3.18/300-arch-arm-force-ZRELADDR-on-arch-qcom.patch b/target/linux/ipq806x/patches-3.18/300-arch-arm-force-ZRELADDR-on-arch-qcom.patch deleted file mode 100644 index cb740dedcc..0000000000 --- a/target/linux/ipq806x/patches-3.18/300-arch-arm-force-ZRELADDR-on-arch-qcom.patch +++ /dev/null @@ -1,62 +0,0 @@ -From b12e230f09d4481424e6a5d7e2ae566b6954e83f Mon Sep 17 00:00:00 2001 -From: Mathieu Olivari -Date: Wed, 29 Apr 2015 15:21:46 -0700 -Subject: [PATCH] HACK: arch: arm: force ZRELADDR on arch-qcom - -ARCH_QCOM is using the ARCH_MULTIPLATFORM option, as now recommended -on most ARM architectures. This automatically calculate ZRELADDR by -masking PHYS_OFFSET with 0xf8000000. - -However, on IPQ806x, the first ~20MB of RAM is reserved for the hardware -network accelerators, and the bootloader removes this section from the -layout passed from the ATAGS (when used). - -For newer bootloader, when DT is used, this is not a problem, we just -reserve this memory in the device tree. But if the bootloader doesn't -have DT support, then ATAGS have to be used. In this case, the ARM -decompressor will position the kernel in this low mem, which will not be -in the RAM section mapped by the bootloader, which means the kernel will -freeze in the middle of the boot process trying to map the memory. - -As a work around, this patch allows disabling AUTO_ZRELADDR when -ARCH_QCOM is selected. It makes the zImage usage possible on bootloaders -which don't support device-tree, which is the case on certain early -IPQ806x based designs. - -Signed-off-by: Mathieu Olivari ---- - arch/arm/Kconfig | 2 +- - arch/arm/Makefile | 2 ++ - arch/arm/mach-qcom/Makefile.boot | 1 + - 3 files changed, 4 insertions(+), 1 deletion(-) - create mode 100644 arch/arm/mach-qcom/Makefile.boot - ---- a/arch/arm/Kconfig -+++ b/arch/arm/Kconfig -@@ -311,7 +311,7 @@ config ARCH_MULTIPLATFORM - select ARCH_WANT_OPTIONAL_GPIOLIB - select ARM_HAS_SG_CHAIN - select ARM_PATCH_PHYS_VIRT -- select AUTO_ZRELADDR -+ select AUTO_ZRELADDR if !ARCH_QCOM - select CLKSRC_OF - select COMMON_CLK - select GENERIC_CLOCKEVENTS ---- a/arch/arm/Makefile -+++ b/arch/arm/Makefile -@@ -240,9 +240,11 @@ MACHINE := arch/arm/mach-$(word 1,$(mac - else - MACHINE := - endif -+ifeq ($(CONFIG_ARCH_QCOM),) - ifeq ($(CONFIG_ARCH_MULTIPLATFORM),y) - MACHINE := - endif -+endif - - machdirs := $(patsubst %,arch/arm/mach-%/,$(machine-y)) - platdirs := $(patsubst %,arch/arm/plat-%/,$(sort $(plat-y))) ---- /dev/null -+++ b/arch/arm/mach-qcom/Makefile.boot -@@ -0,0 +1 @@ -+zreladdr-y+= 0x42208000 diff --git a/target/linux/ipq806x/patches-3.18/700-clk-qcom-Add-support-for-NSS-GMAC-clocks-and-resets.patch b/target/linux/ipq806x/patches-3.18/700-clk-qcom-Add-support-for-NSS-GMAC-clocks-and-resets.patch deleted file mode 100644 index d7d6b69d15..0000000000 --- a/target/linux/ipq806x/patches-3.18/700-clk-qcom-Add-support-for-NSS-GMAC-clocks-and-resets.patch +++ /dev/null @@ -1,733 +0,0 @@ -From 2fbb18f85826a9ba308fedb2cf90d3a661a39fd7 Mon Sep 17 00:00:00 2001 -From: Stephen Boyd -Date: Fri, 27 Mar 2015 00:16:14 -0700 -Subject: [PATCH] clk: qcom: Add support for NSS/GMAC clocks and resets - -Add the NSS/GMAC clocks and the TCM clock and NSS resets. - -Signed-off-by: Stephen Boyd ---- - drivers/clk/qcom/gcc-ipq806x.c | 594 ++++++++++++++++++++++++++- - drivers/clk/qcom/gcc-ipq806x.c.rej | 50 +++ - include/dt-bindings/clock/qcom,gcc-ipq806x.h | 2 + - include/dt-bindings/reset/qcom,gcc-ipq806x.h | 43 ++ - 4 files changed, 688 insertions(+), 1 deletion(-) - create mode 100644 drivers/clk/qcom/gcc-ipq806x.c.rej - ---- a/drivers/clk/qcom/gcc-ipq806x.c -+++ b/drivers/clk/qcom/gcc-ipq806x.c -@@ -209,11 +209,46 @@ static struct clk_regmap pll14_vote = { - }, - }; - -+#define NSS_PLL_RATE(f, _l, _m, _n, i) \ -+ { \ -+ .freq = f, \ -+ .l = _l, \ -+ .m = _m, \ -+ .n = _n, \ -+ .ibits = i, \ -+ } -+ -+static struct pll_freq_tbl pll18_freq_tbl[] = { -+ NSS_PLL_RATE(550000000, 44, 0, 1, 0x01495625), -+ NSS_PLL_RATE(733000000, 58, 16, 25, 0x014b5625), -+}; -+ -+static struct clk_pll pll18 = { -+ .l_reg = 0x31a4, -+ .m_reg = 0x31a8, -+ .n_reg = 0x31ac, -+ .config_reg = 0x31b4, -+ .mode_reg = 0x31a0, -+ .status_reg = 0x31b8, -+ .status_bit = 16, -+ .post_div_shift = 16, -+ .post_div_width = 1, -+ .freq_tbl = pll18_freq_tbl, -+ .clkr.hw.init = &(struct clk_init_data){ -+ .name = "pll18", -+ .parent_names = (const char *[]){ "pxo" }, -+ .num_parents = 1, -+ .ops = &clk_pll_ops, -+ }, -+}; -+ - #define P_PXO 0 - #define P_PLL8 1 - #define P_PLL3 1 - #define P_PLL0 2 - #define P_CXO 2 -+#define P_PLL14 3 -+#define P_PLL18 4 - - static const u8 gcc_pxo_pll8_map[] = { - [P_PXO] = 0, -@@ -264,6 +299,22 @@ static const char *gcc_pxo_pll8_pll0_map - "pll0_vote", - }; - -+static const u8 gcc_pxo_pll8_pll14_pll18_pll0_map[] = { -+ [P_PXO] = 0 , -+ [P_PLL8] = 4, -+ [P_PLL0] = 2, -+ [P_PLL14] = 5, -+ [P_PLL18] = 1, -+}; -+ -+static const char *gcc_pxo_pll8_pll14_pll18_pll0[] = { -+ "pxo", -+ "pll8_vote", -+ "pll0_vote", -+ "pll14", -+ "pll18", -+}; -+ - static struct freq_tbl clk_tbl_gsbi_uart[] = { - { 1843200, P_PLL8, 2, 6, 625 }, - { 3686400, P_PLL8, 2, 12, 625 }, -@@ -2239,6 +2290,472 @@ static struct clk_branch usb_fs1_h_clk = - }, - }; - -+static const struct freq_tbl clk_tbl_gmac[] = { -+ { 133000000, P_PLL0, 1, 50, 301 }, -+ { 266000000, P_PLL0, 1, 127, 382 }, -+ { } -+}; -+ -+static struct clk_dyn_rcg gmac_core1_src = { -+ .ns_reg[0] = 0x3cac, -+ .ns_reg[1] = 0x3cb0, -+ .md_reg[0] = 0x3ca4, -+ .md_reg[1] = 0x3ca8, -+ .bank_reg = 0x3ca0, -+ .mn[0] = { -+ .mnctr_en_bit = 8, -+ .mnctr_reset_bit = 7, -+ .mnctr_mode_shift = 5, -+ .n_val_shift = 16, -+ .m_val_shift = 16, -+ .width = 8, -+ }, -+ .mn[1] = { -+ .mnctr_en_bit = 8, -+ .mnctr_reset_bit = 7, -+ .mnctr_mode_shift = 5, -+ .n_val_shift = 16, -+ .m_val_shift = 16, -+ .width = 8, -+ }, -+ .s[0] = { -+ .src_sel_shift = 0, -+ .parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map, -+ }, -+ .s[1] = { -+ .src_sel_shift = 0, -+ .parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map, -+ }, -+ .p[0] = { -+ .pre_div_shift = 3, -+ .pre_div_width = 2, -+ }, -+ .p[1] = { -+ .pre_div_shift = 3, -+ .pre_div_width = 2, -+ }, -+ .mux_sel_bit = 0, -+ .freq_tbl = clk_tbl_gmac, -+ .clkr = { -+ .enable_reg = 0x3ca0, -+ .enable_mask = BIT(1), -+ .hw.init = &(struct clk_init_data){ -+ .name = "gmac_core1_src", -+ .parent_names = gcc_pxo_pll8_pll14_pll18_pll0, -+ .num_parents = 5, -+ .ops = &clk_dyn_rcg_ops, -+ }, -+ }, -+}; -+ -+static struct clk_branch gmac_core1_clk = { -+ .halt_reg = 0x3c20, -+ .halt_bit = 4, -+ .hwcg_reg = 0x3cb4, -+ .hwcg_bit = 6, -+ .clkr = { -+ .enable_reg = 0x3cb4, -+ .enable_mask = BIT(4), -+ .hw.init = &(struct clk_init_data){ -+ .name = "gmac_core1_clk", -+ .parent_names = (const char *[]){ -+ "gmac_core1_src", -+ }, -+ .num_parents = 1, -+ .ops = &clk_branch_ops, -+ .flags = CLK_SET_RATE_PARENT, -+ }, -+ }, -+}; -+ -+static struct clk_dyn_rcg gmac_core2_src = { -+ .ns_reg[0] = 0x3ccc, -+ .ns_reg[1] = 0x3cd0, -+ .md_reg[0] = 0x3cc4, -+ .md_reg[1] = 0x3cc8, -+ .bank_reg = 0x3ca0, -+ .mn[0] = { -+ .mnctr_en_bit = 8, -+ .mnctr_reset_bit = 7, -+ .mnctr_mode_shift = 5, -+ .n_val_shift = 16, -+ .m_val_shift = 16, -+ .width = 8, -+ }, -+ .mn[1] = { -+ .mnctr_en_bit = 8, -+ .mnctr_reset_bit = 7, -+ .mnctr_mode_shift = 5, -+ .n_val_shift = 16, -+ .m_val_shift = 16, -+ .width = 8, -+ }, -+ .s[0] = { -+ .src_sel_shift = 0, -+ .parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map, -+ }, -+ .s[1] = { -+ .src_sel_shift = 0, -+ .parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map, -+ }, -+ .p[0] = { -+ .pre_div_shift = 3, -+ .pre_div_width = 2, -+ }, -+ .p[1] = { -+ .pre_div_shift = 3, -+ .pre_div_width = 2, -+ }, -+ .mux_sel_bit = 0, -+ .freq_tbl = clk_tbl_gmac, -+ .clkr = { -+ .enable_reg = 0x3cc0, -+ .enable_mask = BIT(1), -+ .hw.init = &(struct clk_init_data){ -+ .name = "gmac_core2_src", -+ .parent_names = gcc_pxo_pll8_pll14_pll18_pll0, -+ .num_parents = 5, -+ .ops = &clk_dyn_rcg_ops, -+ }, -+ }, -+}; -+ -+static struct clk_branch gmac_core2_clk = { -+ .halt_reg = 0x3c20, -+ .halt_bit = 5, -+ .hwcg_reg = 0x3cd4, -+ .hwcg_bit = 6, -+ .clkr = { -+ .enable_reg = 0x3cd4, -+ .enable_mask = BIT(4), -+ .hw.init = &(struct clk_init_data){ -+ .name = "gmac_core2_clk", -+ .parent_names = (const char *[]){ -+ "gmac_core2_src", -+ }, -+ .num_parents = 1, -+ .ops = &clk_branch_ops, -+ .flags = CLK_SET_RATE_PARENT, -+ }, -+ }, -+}; -+ -+static struct clk_dyn_rcg gmac_core3_src = { -+ .ns_reg[0] = 0x3cec, -+ .ns_reg[1] = 0x3cf0, -+ .md_reg[0] = 0x3ce4, -+ .md_reg[1] = 0x3ce8, -+ .bank_reg = 0x3ce0, -+ .mn[0] = { -+ .mnctr_en_bit = 8, -+ .mnctr_reset_bit = 7, -+ .mnctr_mode_shift = 5, -+ .n_val_shift = 16, -+ .m_val_shift = 16, -+ .width = 8, -+ }, -+ .mn[1] = { -+ .mnctr_en_bit = 8, -+ .mnctr_reset_bit = 7, -+ .mnctr_mode_shift = 5, -+ .n_val_shift = 16, -+ .m_val_shift = 16, -+ .width = 8, -+ }, -+ .s[0] = { -+ .src_sel_shift = 0, -+ .parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map, -+ }, -+ .s[1] = { -+ .src_sel_shift = 0, -+ .parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map, -+ }, -+ .p[0] = { -+ .pre_div_shift = 3, -+ .pre_div_width = 2, -+ }, -+ .p[1] = { -+ .pre_div_shift = 3, -+ .pre_div_width = 2, -+ }, -+ .mux_sel_bit = 0, -+ .freq_tbl = clk_tbl_gmac, -+ .clkr = { -+ .enable_reg = 0x3ce0, -+ .enable_mask = BIT(1), -+ .hw.init = &(struct clk_init_data){ -+ .name = "gmac_core3_src", -+ .parent_names = gcc_pxo_pll8_pll14_pll18_pll0, -+ .num_parents = 5, -+ .ops = &clk_dyn_rcg_ops, -+ }, -+ }, -+}; -+ -+static struct clk_branch gmac_core3_clk = { -+ .halt_reg = 0x3c20, -+ .halt_bit = 6, -+ .hwcg_reg = 0x3cf4, -+ .hwcg_bit = 6, -+ .clkr = { -+ .enable_reg = 0x3cf4, -+ .enable_mask = BIT(4), -+ .hw.init = &(struct clk_init_data){ -+ .name = "gmac_core3_clk", -+ .parent_names = (const char *[]){ -+ "gmac_core3_src", -+ }, -+ .num_parents = 1, -+ .ops = &clk_branch_ops, -+ .flags = CLK_SET_RATE_PARENT, -+ }, -+ }, -+}; -+ -+static struct clk_dyn_rcg gmac_core4_src = { -+ .ns_reg[0] = 0x3d0c, -+ .ns_reg[1] = 0x3d10, -+ .md_reg[0] = 0x3d04, -+ .md_reg[1] = 0x3d08, -+ .bank_reg = 0x3d00, -+ .mn[0] = { -+ .mnctr_en_bit = 8, -+ .mnctr_reset_bit = 7, -+ .mnctr_mode_shift = 5, -+ .n_val_shift = 16, -+ .m_val_shift = 16, -+ .width = 8, -+ }, -+ .mn[1] = { -+ .mnctr_en_bit = 8, -+ .mnctr_reset_bit = 7, -+ .mnctr_mode_shift = 5, -+ .n_val_shift = 16, -+ .m_val_shift = 16, -+ .width = 8, -+ }, -+ .s[0] = { -+ .src_sel_shift = 0, -+ .parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map, -+ }, -+ .s[1] = { -+ .src_sel_shift = 0, -+ .parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map, -+ }, -+ .p[0] = { -+ .pre_div_shift = 3, -+ .pre_div_width = 2, -+ }, -+ .p[1] = { -+ .pre_div_shift = 3, -+ .pre_div_width = 2, -+ }, -+ .mux_sel_bit = 0, -+ .freq_tbl = clk_tbl_gmac, -+ .clkr = { -+ .enable_reg = 0x3d00, -+ .enable_mask = BIT(1), -+ .hw.init = &(struct clk_init_data){ -+ .name = "gmac_core4_src", -+ .parent_names = gcc_pxo_pll8_pll14_pll18_pll0, -+ .num_parents = 5, -+ .ops = &clk_dyn_rcg_ops, -+ }, -+ }, -+}; -+ -+static struct clk_branch gmac_core4_clk = { -+ .halt_reg = 0x3c20, -+ .halt_bit = 7, -+ .hwcg_reg = 0x3d14, -+ .hwcg_bit = 6, -+ .clkr = { -+ .enable_reg = 0x3d14, -+ .enable_mask = BIT(4), -+ .hw.init = &(struct clk_init_data){ -+ .name = "gmac_core4_clk", -+ .parent_names = (const char *[]){ -+ "gmac_core4_src", -+ }, -+ .num_parents = 1, -+ .ops = &clk_branch_ops, -+ .flags = CLK_SET_RATE_PARENT, -+ }, -+ }, -+}; -+ -+static const struct freq_tbl clk_tbl_nss_tcm[] = { -+ { 266000000, P_PLL0, 3, 0, 0 }, -+ { 400000000, P_PLL0, 2, 0, 0 }, -+ { } -+}; -+ -+static struct clk_dyn_rcg nss_tcm_src = { -+ .ns_reg[0] = 0x3dc4, -+ .ns_reg[1] = 0x3dc8, -+ .bank_reg = 0x3dc0, -+ .s[0] = { -+ .src_sel_shift = 0, -+ .parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map, -+ }, -+ .s[1] = { -+ .src_sel_shift = 0, -+ .parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map, -+ }, -+ .p[0] = { -+ .pre_div_shift = 3, -+ .pre_div_width = 4, -+ }, -+ .p[1] = { -+ .pre_div_shift = 3, -+ .pre_div_width = 4, -+ }, -+ .mux_sel_bit = 0, -+ .freq_tbl = clk_tbl_nss_tcm, -+ .clkr = { -+ .enable_reg = 0x3dc0, -+ .enable_mask = BIT(1), -+ .hw.init = &(struct clk_init_data){ -+ .name = "nss_tcm_src", -+ .parent_names = gcc_pxo_pll8_pll14_pll18_pll0, -+ .num_parents = 5, -+ .ops = &clk_dyn_rcg_ops, -+ }, -+ }, -+}; -+ -+static struct clk_branch nss_tcm_clk = { -+ .halt_reg = 0x3c20, -+ .halt_bit = 14, -+ .clkr = { -+ .enable_reg = 0x3dd0, -+ .enable_mask = BIT(6) | BIT(4), -+ .hw.init = &(struct clk_init_data){ -+ .name = "nss_tcm_clk", -+ .parent_names = (const char *[]){ -+ "nss_tcm_src", -+ }, -+ .num_parents = 1, -+ .ops = &clk_branch_ops, -+ .flags = CLK_SET_RATE_PARENT, -+ }, -+ }, -+}; -+ -+static const struct freq_tbl clk_tbl_nss[] = { -+ { 110000000, P_PLL18, 1, 1, 5 }, -+ { 275000000, P_PLL18, 2, 0, 0 }, -+ { 550000000, P_PLL18, 1, 0, 0 }, -+ { 733000000, P_PLL18, 1, 0, 0 }, -+ { } -+}; -+ -+static struct clk_dyn_rcg ubi32_core1_src_clk = { -+ .ns_reg[0] = 0x3d2c, -+ .ns_reg[1] = 0x3d30, -+ .md_reg[0] = 0x3d24, -+ .md_reg[1] = 0x3d28, -+ .bank_reg = 0x3d20, -+ .mn[0] = { -+ .mnctr_en_bit = 8, -+ .mnctr_reset_bit = 7, -+ .mnctr_mode_shift = 5, -+ .n_val_shift = 16, -+ .m_val_shift = 16, -+ .width = 8, -+ }, -+ .mn[1] = { -+ .mnctr_en_bit = 8, -+ .mnctr_reset_bit = 7, -+ .mnctr_mode_shift = 5, -+ .n_val_shift = 16, -+ .m_val_shift = 16, -+ .width = 8, -+ }, -+ .s[0] = { -+ .src_sel_shift = 0, -+ .parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map, -+ }, -+ .s[1] = { -+ .src_sel_shift = 0, -+ .parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map, -+ }, -+ .p[0] = { -+ .pre_div_shift = 3, -+ .pre_div_width = 2, -+ }, -+ .p[1] = { -+ .pre_div_shift = 3, -+ .pre_div_width = 2, -+ }, -+ .mux_sel_bit = 0, -+ .freq_tbl = clk_tbl_nss, -+ .clkr = { -+ .enable_reg = 0x3d20, -+ .enable_mask = BIT(1), -+ .hw.init = &(struct clk_init_data){ -+ .name = "ubi32_core1_src_clk", -+ .parent_names = gcc_pxo_pll8_pll14_pll18_pll0, -+ .num_parents = 5, -+ .ops = &clk_dyn_rcg_ops, -+ .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, -+ }, -+ }, -+}; -+ -+static struct clk_dyn_rcg ubi32_core2_src_clk = { -+ .ns_reg[0] = 0x3d4c, -+ .ns_reg[1] = 0x3d50, -+ .md_reg[0] = 0x3d44, -+ .md_reg[1] = 0x3d48, -+ .bank_reg = 0x3d40, -+ .mn[0] = { -+ .mnctr_en_bit = 8, -+ .mnctr_reset_bit = 7, -+ .mnctr_mode_shift = 5, -+ .n_val_shift = 16, -+ .m_val_shift = 16, -+ .width = 8, -+ }, -+ .mn[1] = { -+ .mnctr_en_bit = 8, -+ .mnctr_reset_bit = 7, -+ .mnctr_mode_shift = 5, -+ .n_val_shift = 16, -+ .m_val_shift = 16, -+ .width = 8, -+ }, -+ .s[0] = { -+ .src_sel_shift = 0, -+ .parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map, -+ }, -+ .s[1] = { -+ .src_sel_shift = 0, -+ .parent_map = gcc_pxo_pll8_pll14_pll18_pll0_map, -+ }, -+ .p[0] = { -+ .pre_div_shift = 3, -+ .pre_div_width = 2, -+ }, -+ .p[1] = { -+ .pre_div_shift = 3, -+ .pre_div_width = 2, -+ }, -+ .mux_sel_bit = 0, -+ .freq_tbl = clk_tbl_nss, -+ .clkr = { -+ .enable_reg = 0x3d40, -+ .enable_mask = BIT(1), -+ .hw.init = &(struct clk_init_data){ -+ .name = "ubi32_core2_src_clk", -+ .parent_names = gcc_pxo_pll8_pll14_pll18_pll0, -+ .num_parents = 5, -+ .ops = &clk_dyn_rcg_ops, -+ .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, -+ }, -+ }, -+}; -+ - static struct clk_regmap *gcc_ipq806x_clks[] = { - [PLL0] = &pll0.clkr, - [PLL0_VOTE] = &pll0_vote, -@@ -2247,6 +2764,7 @@ static struct clk_regmap *gcc_ipq806x_cl - [PLL8_VOTE] = &pll8_vote, - [PLL14] = &pll14.clkr, - [PLL14_VOTE] = &pll14_vote, -+ [PLL18] = &pll18.clkr, - [GSBI1_UART_SRC] = &gsbi1_uart_src.clkr, - [GSBI1_UART_CLK] = &gsbi1_uart_clk.clkr, - [GSBI2_UART_SRC] = &gsbi2_uart_src.clkr, -@@ -2344,6 +2862,18 @@ static struct clk_regmap *gcc_ipq806x_cl - [PLL9] = &hfpll0.clkr, - [PLL10] = &hfpll1.clkr, - [PLL12] = &hfpll_l2.clkr, -+ [GMAC_CORE1_CLK_SRC] = &gmac_core1_src.clkr, -+ [GMAC_CORE1_CLK] = &gmac_core1_clk.clkr, -+ [GMAC_CORE2_CLK_SRC] = &gmac_core2_src.clkr, -+ [GMAC_CORE2_CLK] = &gmac_core2_clk.clkr, -+ [GMAC_CORE3_CLK_SRC] = &gmac_core3_src.clkr, -+ [GMAC_CORE3_CLK] = &gmac_core3_clk.clkr, -+ [GMAC_CORE4_CLK_SRC] = &gmac_core4_src.clkr, -+ [GMAC_CORE4_CLK] = &gmac_core4_clk.clkr, -+ [UBI32_CORE1_CLK_SRC] = &ubi32_core1_src_clk.clkr, -+ [UBI32_CORE2_CLK_SRC] = &ubi32_core2_src_clk.clkr, -+ [NSSTCM_CLK_SRC] = &nss_tcm_src.clkr, -+ [NSSTCM_CLK] = &nss_tcm_clk.clkr, - }; - - static const struct qcom_reset_map gcc_ipq806x_resets[] = { -@@ -2462,6 +2992,48 @@ static const struct qcom_reset_map gcc_i - [USB30_1_PHY_RESET] = { 0x3b58, 0 }, - [NSSFB0_RESET] = { 0x3b60, 6 }, - [NSSFB1_RESET] = { 0x3b60, 7 }, -+ [UBI32_CORE1_CLKRST_CLAMP_RESET] = { 0x3d3c, 3}, -+ [UBI32_CORE1_CLAMP_RESET] = { 0x3d3c, 2 }, -+ [UBI32_CORE1_AHB_RESET] = { 0x3d3c, 1 }, -+ [UBI32_CORE1_AXI_RESET] = { 0x3d3c, 0 }, -+ [UBI32_CORE2_CLKRST_CLAMP_RESET] = { 0x3d5c, 3 }, -+ [UBI32_CORE2_CLAMP_RESET] = { 0x3d5c, 2 }, -+ [UBI32_CORE2_AHB_RESET] = { 0x3d5c, 1 }, -+ [UBI32_CORE2_AXI_RESET] = { 0x3d5c, 0 }, -+ [GMAC_CORE1_RESET] = { 0x3cbc, 0 }, -+ [GMAC_CORE2_RESET] = { 0x3cdc, 0 }, -+ [GMAC_CORE3_RESET] = { 0x3cfc, 0 }, -+ [GMAC_CORE4_RESET] = { 0x3d1c, 0 }, -+ [GMAC_AHB_RESET] = { 0x3e24, 0 }, -+ [NSS_CH0_RST_RX_CLK_N_RESET] = { 0x3b60, 0 }, -+ [NSS_CH0_RST_TX_CLK_N_RESET] = { 0x3b60, 1 }, -+ [NSS_CH0_RST_RX_125M_N_RESET] = { 0x3b60, 2 }, -+ [NSS_CH0_HW_RST_RX_125M_N_RESET] = { 0x3b60, 3 }, -+ [NSS_CH0_RST_TX_125M_N_RESET] = { 0x3b60, 4 }, -+ [NSS_CH1_RST_RX_CLK_N_RESET] = { 0x3b60, 5 }, -+ [NSS_CH1_RST_TX_CLK_N_RESET] = { 0x3b60, 6 }, -+ [NSS_CH1_RST_RX_125M_N_RESET] = { 0x3b60, 7 }, -+ [NSS_CH1_HW_RST_RX_125M_N_RESET] = { 0x3b60, 8 }, -+ [NSS_CH1_RST_TX_125M_N_RESET] = { 0x3b60, 9 }, -+ [NSS_CH2_RST_RX_CLK_N_RESET] = { 0x3b60, 10 }, -+ [NSS_CH2_RST_TX_CLK_N_RESET] = { 0x3b60, 11 }, -+ [NSS_CH2_RST_RX_125M_N_RESET] = { 0x3b60, 12 }, -+ [NSS_CH2_HW_RST_RX_125M_N_RESET] = { 0x3b60, 13 }, -+ [NSS_CH2_RST_TX_125M_N_RESET] = { 0x3b60, 14 }, -+ [NSS_CH3_RST_RX_CLK_N_RESET] = { 0x3b60, 15 }, -+ [NSS_CH3_RST_TX_CLK_N_RESET] = { 0x3b60, 16 }, -+ [NSS_CH3_RST_RX_125M_N_RESET] = { 0x3b60, 17 }, -+ [NSS_CH3_HW_RST_RX_125M_N_RESET] = { 0x3b60, 18 }, -+ [NSS_CH3_RST_TX_125M_N_RESET] = { 0x3b60, 19 }, -+ [NSS_RST_RX_250M_125M_N_RESET] = { 0x3b60, 20 }, -+ [NSS_RST_TX_250M_125M_N_RESET] = { 0x3b60, 21 }, -+ [NSS_QSGMII_TXPI_RST_N_RESET] = { 0x3b60, 22 }, -+ [NSS_QSGMII_CDR_RST_N_RESET] = { 0x3b60, 23 }, -+ [NSS_SGMII2_CDR_RST_N_RESET] = { 0x3b60, 24 }, -+ [NSS_SGMII3_CDR_RST_N_RESET] = { 0x3b60, 25 }, -+ [NSS_CAL_PRBS_RST_N_RESET] = { 0x3b60, 26 }, -+ [NSS_LCKDT_RST_N_RESET] = { 0x3b60, 27 }, -+ [NSS_SRDS_N_RESET] = { 0x3b60, 28 }, - }; - - static const struct regmap_config gcc_ipq806x_regmap_config = { -@@ -2490,6 +3062,8 @@ static int gcc_ipq806x_probe(struct plat - { - struct clk *clk; - struct device *dev = &pdev->dev; -+ struct regmap *regmap; -+ int ret; - - /* Temporary until RPM clocks supported */ - clk = clk_register_fixed_rate(dev, "cxo", NULL, CLK_IS_ROOT, 25000000); -@@ -2500,7 +3074,25 @@ static int gcc_ipq806x_probe(struct plat - if (IS_ERR(clk)) - return PTR_ERR(clk); - -- return qcom_cc_probe(pdev, &gcc_ipq806x_desc); -+ ret = qcom_cc_probe(pdev, &gcc_ipq806x_desc); -+ if (ret) -+ return ret; -+ -+ regmap = dev_get_regmap(dev, NULL); -+ if (!regmap) -+ return -ENODEV; -+ -+ /* Setup PLL18 static bits */ -+ regmap_update_bits(regmap, 0x31a4, 0xffffffc0, 0x40000400); -+ regmap_write(regmap, 0x31b0, 0x3080); -+ -+ /* Set GMAC footswitch sleep/wakeup values */ -+ regmap_write(regmap, 0x3cb8, 8); -+ regmap_write(regmap, 0x3cd8, 8); -+ regmap_write(regmap, 0x3cf8, 8); -+ regmap_write(regmap, 0x3d18, 8); -+ -+ return 0; - } - - static int gcc_ipq806x_remove(struct platform_device *pdev) ---- a/include/dt-bindings/clock/qcom,gcc-ipq806x.h -+++ b/include/dt-bindings/clock/qcom,gcc-ipq806x.h -@@ -289,5 +289,7 @@ - #define UBI32_CORE2_CLK_SRC 278 - #define UBI32_CORE1_CLK 279 - #define UBI32_CORE2_CLK 280 -+#define NSSTCM_CLK_SRC 281 -+#define NSSTCM_CLK 282 - - #endif ---- a/include/dt-bindings/reset/qcom,gcc-ipq806x.h -+++ b/include/dt-bindings/reset/qcom,gcc-ipq806x.h -@@ -129,4 +129,47 @@ - #define USB30_1_PHY_RESET 112 - #define NSSFB0_RESET 113 - #define NSSFB1_RESET 114 -+#define UBI32_CORE1_CLKRST_CLAMP_RESET 115 -+#define UBI32_CORE1_CLAMP_RESET 116 -+#define UBI32_CORE1_AHB_RESET 117 -+#define UBI32_CORE1_AXI_RESET 118 -+#define UBI32_CORE2_CLKRST_CLAMP_RESET 119 -+#define UBI32_CORE2_CLAMP_RESET 120 -+#define UBI32_CORE2_AHB_RESET 121 -+#define UBI32_CORE2_AXI_RESET 122 -+#define GMAC_CORE1_RESET 123 -+#define GMAC_CORE2_RESET 124 -+#define GMAC_CORE3_RESET 125 -+#define GMAC_CORE4_RESET 126 -+#define GMAC_AHB_RESET 127 -+#define NSS_CH0_RST_RX_CLK_N_RESET 128 -+#define NSS_CH0_RST_TX_CLK_N_RESET 129 -+#define NSS_CH0_RST_RX_125M_N_RESET 130 -+#define NSS_CH0_HW_RST_RX_125M_N_RESET 131 -+#define NSS_CH0_RST_TX_125M_N_RESET 132 -+#define NSS_CH1_RST_RX_CLK_N_RESET 133 -+#define NSS_CH1_RST_TX_CLK_N_RESET 134 -+#define NSS_CH1_RST_RX_125M_N_RESET 135 -+#define NSS_CH1_HW_RST_RX_125M_N_RESET 136 -+#define NSS_CH1_RST_TX_125M_N_RESET 137 -+#define NSS_CH2_RST_RX_CLK_N_RESET 138 -+#define NSS_CH2_RST_TX_CLK_N_RESET 139 -+#define NSS_CH2_RST_RX_125M_N_RESET 140 -+#define NSS_CH2_HW_RST_RX_125M_N_RESET 141 -+#define NSS_CH2_RST_TX_125M_N_RESET 142 -+#define NSS_CH3_RST_RX_CLK_N_RESET 143 -+#define NSS_CH3_RST_TX_CLK_N_RESET 144 -+#define NSS_CH3_RST_RX_125M_N_RESET 145 -+#define NSS_CH3_HW_RST_RX_125M_N_RESET 146 -+#define NSS_CH3_RST_TX_125M_N_RESET 147 -+#define NSS_RST_RX_250M_125M_N_RESET 148 -+#define NSS_RST_TX_250M_125M_N_RESET 149 -+#define NSS_QSGMII_TXPI_RST_N_RESET 150 -+#define NSS_QSGMII_CDR_RST_N_RESET 151 -+#define NSS_SGMII2_CDR_RST_N_RESET 152 -+#define NSS_SGMII3_CDR_RST_N_RESET 153 -+#define NSS_CAL_PRBS_RST_N_RESET 154 -+#define NSS_LCKDT_RST_N_RESET 155 -+#define NSS_SRDS_N_RESET 156 -+ - #endif diff --git a/target/linux/ipq806x/patches-3.18/701-stmmac-add-phy-handle-support-to-the-platform-layer.patch b/target/linux/ipq806x/patches-3.18/701-stmmac-add-phy-handle-support-to-the-platform-layer.patch deleted file mode 100644 index 8e59b5c48c..0000000000 --- a/target/linux/ipq806x/patches-3.18/701-stmmac-add-phy-handle-support-to-the-platform-layer.patch +++ /dev/null @@ -1,105 +0,0 @@ -From 4f09499bc1d9bb095caccbcd73ff951ee631e521 Mon Sep 17 00:00:00 2001 -From: Mathieu Olivari -Date: Fri, 8 May 2015 15:42:40 -0700 -Subject: [PATCH 1/8] stmmac: add phy-handle support to the platform layer - -On stmmac driver, PHY specification in device-tree was done using the -non-standard property "snps,phy-addr". Specifying a PHY on a different -MDIO bus that the one within the stmmac controller doesn't seem to be -possible when device-tree is used. - -This change adds support for the phy-handle property, as specified in -Documentation/devicetree/bindings/net/ethernet.txt. - -Signed-off-by: Mathieu Olivari ---- - drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 28 ++++++++++++++-------- - .../net/ethernet/stmicro/stmmac/stmmac_platform.c | 6 ++++- - include/linux/stmmac.h | 1 + - 3 files changed, 24 insertions(+), 11 deletions(-) - ---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -@@ -52,6 +52,7 @@ - #include "stmmac_ptp.h" - #include "stmmac.h" - #include -+#include - - #define STMMAC_ALIGN(x) L1_CACHE_ALIGN(x) - -@@ -818,18 +819,25 @@ static int stmmac_init_phy(struct net_de - priv->speed = 0; - priv->oldduplex = -1; - -- if (priv->plat->phy_bus_name) -- snprintf(bus_id, MII_BUS_ID_SIZE, "%s-%x", -- priv->plat->phy_bus_name, priv->plat->bus_id); -- else -- snprintf(bus_id, MII_BUS_ID_SIZE, "stmmac-%x", -- priv->plat->bus_id); -- -- snprintf(phy_id_fmt, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id, -- priv->plat->phy_addr); -- pr_debug("stmmac_init_phy: trying to attach to %s\n", phy_id_fmt); -+ if (priv->plat->phy_node) { -+ phydev = of_phy_connect(dev, priv->plat->phy_node, -+ &stmmac_adjust_link, 0, interface); -+ } else { -+ if (priv->plat->phy_bus_name) -+ snprintf(bus_id, MII_BUS_ID_SIZE, "%s-%x", -+ priv->plat->phy_bus_name, priv->plat->bus_id); -+ else -+ snprintf(bus_id, MII_BUS_ID_SIZE, "stmmac-%x", -+ priv->plat->bus_id); -+ -+ snprintf(phy_id_fmt, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id, -+ priv->plat->phy_addr); -+ pr_debug("stmmac_init_phy: trying to attach to %s\n", -+ phy_id_fmt); - -- phydev = phy_connect(dev, phy_id_fmt, &stmmac_adjust_link, interface); -+ phydev = phy_connect(dev, phy_id_fmt, &stmmac_adjust_link, -+ interface); -+ } - - if (IS_ERR(phydev)) { - pr_err("%s: Could not attach to PHY\n", dev->name); ---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c -+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c -@@ -27,6 +27,7 @@ - #include - #include - #include -+#include - #include "stmmac.h" - - static const struct of_device_id stmmac_dt_ids[] = { -@@ -155,13 +156,16 @@ static int stmmac_probe_config_dt(struct - /* Default to phy auto-detection */ - plat->phy_addr = -1; - -+ /* If we find a phy-handle property, use it as the PHY */ -+ plat->phy_node = of_parse_phandle(np, "phy-handle", 0); -+ - /* "snps,phy-addr" is not a standard property. Mark it as deprecated - * and warn of its use. Remove this when phy node support is added. - */ - if (of_property_read_u32(np, "snps,phy-addr", &plat->phy_addr) == 0) - dev_warn(&pdev->dev, "snps,phy-addr property is deprecated\n"); - -- if (plat->phy_bus_name) -+ if (plat->phy_node || plat->phy_bus_name) - plat->mdio_bus_data = NULL; - else - plat->mdio_bus_data = ---- a/include/linux/stmmac.h -+++ b/include/linux/stmmac.h -@@ -99,6 +99,7 @@ struct plat_stmmacenet_data { - int phy_addr; - int interface; - struct stmmac_mdio_bus_data *mdio_bus_data; -+ struct device_node *phy_node; - struct stmmac_dma_cfg *dma_cfg; - int clk_csr; - int has_gmac; diff --git a/target/linux/ipq806x/patches-3.18/702-stmmac-move-error-path-at-the-end-of-stmmac_probe_co.patch b/target/linux/ipq806x/patches-3.18/702-stmmac-move-error-path-at-the-end-of-stmmac_probe_co.patch deleted file mode 100644 index e8f9b5c29a..0000000000 --- a/target/linux/ipq806x/patches-3.18/702-stmmac-move-error-path-at-the-end-of-stmmac_probe_co.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 0149d275415cd1b2382ce94e5eb32641590097d0 Mon Sep 17 00:00:00 2001 -From: Mathieu Olivari -Date: Fri, 8 May 2015 15:57:12 -0700 -Subject: [PATCH 2/8] stmmac: move error path at the end of - stmmac_probe_config_dt() - -We will want to do additional clean-up on certain errors. Therefore, -this change moves the error path at the end of the function for better -code readability. - -This patch doesn't change anything functionally. - -Signed-off-by: Mathieu Olivari ---- - .../net/ethernet/stmicro/stmmac/stmmac_platform.c | 22 ++++++++++++++++------ - 1 file changed, 16 insertions(+), 6 deletions(-) - ---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c -+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c -@@ -117,13 +117,18 @@ static int stmmac_probe_config_dt(struct - struct device_node *np = pdev->dev.of_node; - struct stmmac_dma_cfg *dma_cfg; - const struct of_device_id *device; -+ int ret; - -- if (!np) -- return -ENODEV; -+ if (!np) { -+ ret = -ENODEV; -+ goto err; -+ } - - device = of_match_device(stmmac_dt_ids, &pdev->dev); -- if (!device) -- return -ENODEV; -+ if (!device) { -+ ret = -ENODEV; -+ goto err; -+ } - - if (device->data) { - const struct stmmac_of_data *data = device->data; -@@ -219,8 +224,10 @@ static int stmmac_probe_config_dt(struct - if (of_find_property(np, "snps,pbl", NULL)) { - dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*dma_cfg), - GFP_KERNEL); -- if (!dma_cfg) -- return -ENOMEM; -+ if (!dma_cfg) { -+ ret = -ENOMEM; -+ goto err; -+ } - plat->dma_cfg = dma_cfg; - of_property_read_u32(np, "snps,pbl", &dma_cfg->pbl); - dma_cfg->fixed_burst = -@@ -235,6 +242,9 @@ static int stmmac_probe_config_dt(struct - } - - return 0; -+ -+err: -+ return ret; - } - #else - static int stmmac_probe_config_dt(struct platform_device *pdev, diff --git a/target/linux/ipq806x/patches-3.18/703-stmmac-add-fixed-link-device-tree-support.patch b/target/linux/ipq806x/patches-3.18/703-stmmac-add-fixed-link-device-tree-support.patch deleted file mode 100644 index 3c20fe477e..0000000000 --- a/target/linux/ipq806x/patches-3.18/703-stmmac-add-fixed-link-device-tree-support.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 3a95f75867be562cb919ff23a738f70357188fbd Mon Sep 17 00:00:00 2001 -From: Mathieu Olivari -Date: Fri, 8 May 2015 16:02:03 -0700 -Subject: [PATCH 3/8] stmmac: add fixed-link device-tree support - -In case DT is used, this change adds the ability to the stmmac driver to -detect a fixed-link PHY, instanciate it, and use it during -phy_connect(). - -Fixed link PHYs DT usage is described in: -Documentation/devicetree/bindings/net/fixed-link.txt - -Signed-off-by: Mathieu Olivari ---- - drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 2 +- - drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c | 12 +++++++++++- - 2 files changed, 12 insertions(+), 2 deletions(-) - ---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -@@ -858,7 +858,7 @@ static int stmmac_init_phy(struct net_de - * device as well. - * Note: phydev->phy_id is the result of reading the UID PHY registers. - */ -- if (phydev->phy_id == 0) { -+ if (!priv->plat->phy_node && phydev->phy_id == 0) { - phy_disconnect(phydev); - return -ENODEV; - } ---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c -+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c -@@ -164,6 +164,14 @@ static int stmmac_probe_config_dt(struct - /* If we find a phy-handle property, use it as the PHY */ - plat->phy_node = of_parse_phandle(np, "phy-handle", 0); - -+ /* If phy-handle is not specified, check if we have a fixed-phy */ -+ if (!plat->phy_node && of_phy_is_fixed_link(np)) { -+ if ((of_phy_register_fixed_link(np) < 0)) -+ return -ENODEV; -+ -+ plat->phy_node = of_node_get(np); -+ } -+ - /* "snps,phy-addr" is not a standard property. Mark it as deprecated - * and warn of its use. Remove this when phy node support is added. - */ -@@ -226,7 +234,7 @@ static int stmmac_probe_config_dt(struct - GFP_KERNEL); - if (!dma_cfg) { - ret = -ENOMEM; -- goto err; -+ goto err2; - } - plat->dma_cfg = dma_cfg; - of_property_read_u32(np, "snps,pbl", &dma_cfg->pbl); -@@ -243,6 +251,8 @@ static int stmmac_probe_config_dt(struct - - return 0; - -+err2: -+ of_node_put(np); - err: - return ret; - } diff --git a/target/linux/ipq806x/patches-3.18/704-stmmac-add-ipq806x-glue-layer.patch b/target/linux/ipq806x/patches-3.18/704-stmmac-add-ipq806x-glue-layer.patch deleted file mode 100644 index fa6740476b..0000000000 --- a/target/linux/ipq806x/patches-3.18/704-stmmac-add-ipq806x-glue-layer.patch +++ /dev/null @@ -1,427 +0,0 @@ -From 69fb970ad3fe05af7cb99ea78230c69c7ca0d03b Mon Sep 17 00:00:00 2001 -From: Mathieu Olivari -Date: Fri, 8 May 2015 16:10:22 -0700 -Subject: [PATCH 4/8] stmmac: add ipq806x glue layer - -The ethernet controller available in IPQ806x is a Synopsys DesignWare -Gigabit MAC IP core, already supported by the stmmac driver. - -This glue layer implements some platform specific settings required to -get the controller working on an IPQ806x based platform. - -Signed-off-by: Mathieu Olivari ---- - drivers/net/ethernet/stmicro/stmmac/Kconfig | 1 + - drivers/net/ethernet/stmicro/stmmac/Makefile | 2 +- - drivers/net/ethernet/stmicro/stmmac/dwmac-ipq.c | 324 +++++++++++++++++++++ - .../net/ethernet/stmicro/stmmac/stmmac_platform.c | 1 + - .../net/ethernet/stmicro/stmmac/stmmac_platform.h | 1 + - 5 files changed, 328 insertions(+), 1 deletion(-) - create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac-ipq.c - ---- a/drivers/net/ethernet/stmicro/stmmac/Kconfig -+++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig -@@ -16,6 +16,7 @@ if STMMAC_ETH - config STMMAC_PLATFORM - bool "STMMAC Platform bus support" - depends on STMMAC_ETH -+ select MFD_SYSCON - default y - ---help--- - This selects the platform specific bus support for -@@ -26,6 +27,15 @@ config STMMAC_PLATFORM - - If unsure, say N. - -+config DWMAC_IPQ806X -+ bool "QCA IPQ806x dwmac support" -+ depends on STMMAC_PLATFORM && ARCH_QCOM -+ help -+ Support for Ethernet controller on QCA IPQ806x SoC. -+ -+ This selects the QCA IPQ806x SoC glue layer support for -+ the stmmac device driver. -+ - config DWMAC_MESON - bool "Amlogic Meson dwmac support" - depends on STMMAC_PLATFORM && ARCH_MESON ---- a/drivers/net/ethernet/stmicro/stmmac/Makefile -+++ b/drivers/net/ethernet/stmicro/stmmac/Makefile -@@ -1,6 +1,7 @@ - obj-$(CONFIG_STMMAC_ETH) += stmmac.o - stmmac-$(CONFIG_STMMAC_PLATFORM) += stmmac_platform.o - stmmac-$(CONFIG_STMMAC_PCI) += stmmac_pci.o -+stmmac-$(CONFIG_DWMAC_IPQ806X) += dwmac-ipq806x.o - stmmac-$(CONFIG_DWMAC_MESON) += dwmac-meson.o - stmmac-$(CONFIG_DWMAC_SUNXI) += dwmac-sunxi.o - stmmac-$(CONFIG_DWMAC_STI) += dwmac-sti.o ---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c -+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c -@@ -46,6 +46,9 @@ static const struct of_device_id stmmac_ - #ifdef CONFIG_DWMAC_SOCFPGA - { .compatible = "altr,socfpga-stmmac", .data = &socfpga_gmac_data }, - #endif -+#ifdef CONFIG_DWMAC_IPQ806X -+ { .compatible = "qcom,ipq806x-gmac", .data = &ipq806x_gmac_data }, -+#endif - /* SoC specific glue layers should come before generic bindings */ - { .compatible = "st,spear600-gmac"}, - { .compatible = "snps,dwmac-3.610"}, ---- /dev/null -+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c -@@ -0,0 +1,343 @@ -+/* -+ * Qualcomm Atheros IPQ806x GMAC glue layer -+ * -+ * Copyright (C) 2015 The Linux Foundation -+ * -+ * Permission to use, copy, modify, and/or distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "stmmac.h" -+ -+#define NSS_COMMON_CLK_GATE 0x8 -+#define NSS_COMMON_CLK_GATE_PTP_EN(x) BIT(0x10 + x) -+#define NSS_COMMON_CLK_GATE_RGMII_RX_EN(x) BIT(0x9 + (x * 2)) -+#define NSS_COMMON_CLK_GATE_RGMII_TX_EN(x) BIT(0x8 + (x * 2)) -+#define NSS_COMMON_CLK_GATE_GMII_RX_EN(x) BIT(0x4 + x) -+#define NSS_COMMON_CLK_GATE_GMII_TX_EN(x) BIT(0x0 + x) -+ -+#define NSS_COMMON_CLK_DIV0 0xC -+#define NSS_COMMON_CLK_DIV_OFFSET(x) (x * 8) -+#define NSS_COMMON_CLK_DIV_MASK 0x7f -+ -+#define NSS_COMMON_CLK_SRC_CTRL 0x14 -+#define NSS_COMMON_CLK_SRC_CTRL_OFFSET(x) (1 << x) -+/* Mode is coded on 1 bit but is different depending on the MAC ID: -+ * MAC0: QSGMII=0 RGMII=1 -+ * MAC1: QSGMII=0 SGMII=0 RGMII=1 -+ * MAC2 & MAC3: QSGMII=0 SGMII=1 -+ */ -+#define NSS_COMMON_CLK_SRC_CTRL_RGMII(x) 1 -+#define NSS_COMMON_CLK_SRC_CTRL_SGMII(x) ((x >= 2) ? 1 : 0) -+ -+#define NSS_COMMON_MACSEC_CTL 0x28 -+#define NSS_COMMON_MACSEC_CTL_EXT_BYPASS_EN(x) (1 << x) -+ -+#define NSS_COMMON_GMAC_CTL(x) (0x30 + (x * 4)) -+#define NSS_COMMON_GMAC_CTL_CSYS_REQ BIT(19) -+#define NSS_COMMON_GMAC_CTL_PHY_IFACE_SEL BIT(16) -+#define NSS_COMMON_GMAC_CTL_IFG_LIMIT_OFFSET 8 -+#define NSS_COMMON_GMAC_CTL_IFG_OFFSET 0 -+#define NSS_COMMON_GMAC_CTL_IFG_MASK 0x3f -+ -+#define NSS_COMMON_CLK_DIV_RGMII_1000 1 -+#define NSS_COMMON_CLK_DIV_RGMII_100 9 -+#define NSS_COMMON_CLK_DIV_RGMII_10 99 -+#define NSS_COMMON_CLK_DIV_SGMII_1000 0 -+#define NSS_COMMON_CLK_DIV_SGMII_100 4 -+#define NSS_COMMON_CLK_DIV_SGMII_10 49 -+ -+#define QSGMII_PCS_MODE_CTL 0x68 -+#define QSGMII_PCS_MODE_CTL_AUTONEG_EN(x) BIT((x * 8) + 7) -+ -+#define QSGMII_PCS_CAL_LCKDT_CTL 0x120 -+#define QSGMII_PCS_CAL_LCKDT_CTL_RST BIT(19) -+ -+/* Only GMAC1/2/3 support SGMII and their CTL register are not contiguous */ -+#define QSGMII_PHY_SGMII_CTL(x) ((x == 1) ? 0x134 : \ -+ (0x13c + (4 * (x - 2)))) -+#define QSGMII_PHY_CDR_EN BIT(0) -+#define QSGMII_PHY_RX_FRONT_EN BIT(1) -+#define QSGMII_PHY_RX_SIGNAL_DETECT_EN BIT(2) -+#define QSGMII_PHY_TX_DRIVER_EN BIT(3) -+#define QSGMII_PHY_QSGMII_EN BIT(7) -+#define QSGMII_PHY_PHASE_LOOP_GAIN_OFFSET 12 -+#define QSGMII_PHY_PHASE_LOOP_GAIN_MASK 0x7 -+#define QSGMII_PHY_RX_DC_BIAS_OFFSET 18 -+#define QSGMII_PHY_RX_DC_BIAS_MASK 0x3 -+#define QSGMII_PHY_RX_INPUT_EQU_OFFSET 20 -+#define QSGMII_PHY_RX_INPUT_EQU_MASK 0x3 -+#define QSGMII_PHY_CDR_PI_SLEW_OFFSET 22 -+#define QSGMII_PHY_CDR_PI_SLEW_MASK 0x3 -+#define QSGMII_PHY_TX_DRV_AMP_OFFSET 28 -+#define QSGMII_PHY_TX_DRV_AMP_MASK 0xf -+ -+struct ipq806x_gmac { -+ struct platform_device *pdev; -+ struct regmap *nss_common; -+ struct regmap *qsgmii_csr; -+ uint32_t id; -+ struct clk *core_clk; -+ phy_interface_t phy_mode; -+}; -+ -+static int get_clk_div_sgmii(struct ipq806x_gmac *gmac, unsigned int speed) -+{ -+ struct device *dev = &gmac->pdev->dev; -+ int div; -+ -+ switch (speed) { -+ case SPEED_1000: -+ div = NSS_COMMON_CLK_DIV_SGMII_1000; -+ break; -+ -+ case SPEED_100: -+ div = NSS_COMMON_CLK_DIV_SGMII_100; -+ break; -+ -+ case SPEED_10: -+ div = NSS_COMMON_CLK_DIV_SGMII_10; -+ break; -+ -+ default: -+ dev_err(dev, "Speed %dMbps not supported in SGMII\n", speed); -+ return -EINVAL; -+ } -+ -+ return div; -+} -+ -+static int get_clk_div_rgmii(struct ipq806x_gmac *gmac, unsigned int speed) -+{ -+ struct device *dev = &gmac->pdev->dev; -+ int div; -+ -+ switch (speed) { -+ case SPEED_1000: -+ div = NSS_COMMON_CLK_DIV_RGMII_1000; -+ break; -+ -+ case SPEED_100: -+ div = NSS_COMMON_CLK_DIV_RGMII_100; -+ break; -+ -+ case SPEED_10: -+ div = NSS_COMMON_CLK_DIV_RGMII_10; -+ break; -+ -+ default: -+ dev_err(dev, "Speed %dMbps not supported in RGMII\n", speed); -+ return -EINVAL; -+ } -+ -+ return div; -+} -+ -+static int ipq806x_gmac_set_speed(struct ipq806x_gmac *gmac, unsigned int speed) -+{ -+ uint32_t clk_bits, val; -+ int div; -+ -+ switch (gmac->phy_mode) { -+ case PHY_INTERFACE_MODE_RGMII: -+ div = get_clk_div_rgmii(gmac, speed); -+ clk_bits = NSS_COMMON_CLK_GATE_RGMII_RX_EN(gmac->id) | -+ NSS_COMMON_CLK_GATE_RGMII_TX_EN(gmac->id); -+ break; -+ -+ case PHY_INTERFACE_MODE_SGMII: -+ div = get_clk_div_sgmii(gmac, speed); -+ clk_bits = NSS_COMMON_CLK_GATE_GMII_RX_EN(gmac->id) | -+ NSS_COMMON_CLK_GATE_GMII_TX_EN(gmac->id); -+ break; -+ -+ default: -+ dev_err(&gmac->pdev->dev, "Unsupported PHY mode: \"%s\"\n", -+ phy_modes(gmac->phy_mode)); -+ return -EINVAL; -+ } -+ -+ /* Disable the clocks */ -+ regmap_read(gmac->nss_common, NSS_COMMON_CLK_GATE, &val); -+ val &= ~clk_bits; -+ regmap_write(gmac->nss_common, NSS_COMMON_CLK_GATE, val); -+ -+ /* Set the divider */ -+ regmap_read(gmac->nss_common, NSS_COMMON_CLK_DIV0, &val); -+ val &= ~(NSS_COMMON_CLK_DIV_MASK -+ << NSS_COMMON_CLK_DIV_OFFSET(gmac->id)); -+ val |= div << NSS_COMMON_CLK_DIV_OFFSET(gmac->id); -+ regmap_write(gmac->nss_common, NSS_COMMON_CLK_DIV0, val); -+ -+ /* Enable the clock back */ -+ regmap_read(gmac->nss_common, NSS_COMMON_CLK_GATE, &val); -+ val |= clk_bits; -+ regmap_write(gmac->nss_common, NSS_COMMON_CLK_GATE, val); -+ -+ return 0; -+} -+ -+static void *ipq806x_gmac_of_parse(struct ipq806x_gmac *gmac) -+{ -+ struct device *dev = &gmac->pdev->dev; -+ -+ gmac->phy_mode = of_get_phy_mode(dev->of_node); -+ if (gmac->phy_mode < 0) { -+ dev_err(dev, "missing phy mode property\n"); -+ return ERR_PTR(-EINVAL); -+ } -+ -+ if (of_property_read_u32(dev->of_node, "qcom,id", &gmac->id) < 0) { -+ dev_err(dev, "missing qcom id property\n"); -+ return ERR_PTR(-EINVAL); -+ } -+ -+ /* The GMACs are called 1 to 4 in the documentation, but to simplify the -+ * code and keep it consistent with the Linux convention, we'll number -+ * them from 0 to 3 here. -+ */ -+ if (gmac->id < 0 || gmac->id > 3) { -+ dev_err(dev, "invalid gmac id\n"); -+ return ERR_PTR(-EINVAL); -+ } -+ -+ gmac->core_clk = devm_clk_get(dev, "stmmaceth"); -+ if (IS_ERR(gmac->core_clk)) { -+ dev_err(dev, "missing stmmaceth clk property\n"); -+ return gmac->core_clk; -+ } -+ clk_set_rate(gmac->core_clk, 266000000); -+ -+ /* Setup the register map for the nss common registers */ -+ gmac->nss_common = syscon_regmap_lookup_by_phandle(dev->of_node, -+ "qcom,nss-common"); -+ if (IS_ERR(gmac->nss_common)) { -+ dev_err(dev, "missing nss-common node\n"); -+ return gmac->nss_common; -+ } -+ -+ /* Setup the register map for the qsgmii csr registers */ -+ gmac->qsgmii_csr = syscon_regmap_lookup_by_phandle(dev->of_node, -+ "qcom,qsgmii-csr"); -+ if (IS_ERR(gmac->qsgmii_csr)) { -+ dev_err(dev, "missing qsgmii-csr node\n"); -+ return gmac->qsgmii_csr; -+ } -+ -+ return NULL; -+} -+ -+static void *ipq806x_gmac_setup(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct ipq806x_gmac *gmac; -+ int val; -+ void *err; -+ -+ gmac = devm_kzalloc(dev, sizeof(*gmac), GFP_KERNEL); -+ if (!gmac) -+ return ERR_PTR(-ENOMEM); -+ -+ gmac->pdev = pdev; -+ -+ err = ipq806x_gmac_of_parse(gmac); -+ if (err) { -+ dev_err(dev, "device tree parsing error\n"); -+ return err; -+ } -+ -+ regmap_write(gmac->qsgmii_csr, QSGMII_PCS_CAL_LCKDT_CTL, -+ QSGMII_PCS_CAL_LCKDT_CTL_RST); -+ -+ /* Inter frame gap is set to 12 */ -+ val = 12 << NSS_COMMON_GMAC_CTL_IFG_OFFSET | -+ 12 << NSS_COMMON_GMAC_CTL_IFG_LIMIT_OFFSET; -+ /* We also initiate an AXI low power exit request */ -+ val |= NSS_COMMON_GMAC_CTL_CSYS_REQ; -+ switch (gmac->phy_mode) { -+ case PHY_INTERFACE_MODE_RGMII: -+ val |= NSS_COMMON_GMAC_CTL_PHY_IFACE_SEL; -+ break; -+ case PHY_INTERFACE_MODE_SGMII: -+ val &= ~NSS_COMMON_GMAC_CTL_PHY_IFACE_SEL; -+ break; -+ default: -+ dev_err(&pdev->dev, "Unsupported PHY mode: \"%s\"\n", -+ phy_modes(gmac->phy_mode)); -+ return NULL; -+ } -+ regmap_write(gmac->nss_common, NSS_COMMON_GMAC_CTL(gmac->id), val); -+ -+ /* Configure the clock src according to the mode */ -+ regmap_read(gmac->nss_common, NSS_COMMON_CLK_SRC_CTRL, &val); -+ val &= ~NSS_COMMON_CLK_SRC_CTRL_OFFSET(gmac->id); -+ switch (gmac->phy_mode) { -+ case PHY_INTERFACE_MODE_RGMII: -+ val |= NSS_COMMON_CLK_SRC_CTRL_RGMII(gmac->id) << -+ NSS_COMMON_CLK_SRC_CTRL_OFFSET(gmac->id); -+ break; -+ case PHY_INTERFACE_MODE_SGMII: -+ val |= NSS_COMMON_CLK_SRC_CTRL_SGMII(gmac->id) << -+ NSS_COMMON_CLK_SRC_CTRL_OFFSET(gmac->id); -+ break; -+ default: -+ dev_err(&pdev->dev, "Unsupported PHY mode: \"%s\"\n", -+ phy_modes(gmac->phy_mode)); -+ return NULL; -+ } -+ regmap_write(gmac->nss_common, NSS_COMMON_CLK_SRC_CTRL, val); -+ -+ /* Enable PTP clock */ -+ regmap_read(gmac->nss_common, NSS_COMMON_CLK_GATE, &val); -+ val |= NSS_COMMON_CLK_GATE_PTP_EN(gmac->id); -+ regmap_write(gmac->nss_common, NSS_COMMON_CLK_GATE, val); -+ -+ if (gmac->phy_mode == PHY_INTERFACE_MODE_SGMII) { -+ regmap_write(gmac->qsgmii_csr, QSGMII_PHY_SGMII_CTL(gmac->id), -+ QSGMII_PHY_CDR_EN | -+ QSGMII_PHY_RX_FRONT_EN | -+ QSGMII_PHY_RX_SIGNAL_DETECT_EN | -+ QSGMII_PHY_TX_DRIVER_EN | -+ QSGMII_PHY_QSGMII_EN | -+ 0x4 << QSGMII_PHY_PHASE_LOOP_GAIN_OFFSET | -+ 0x3 << QSGMII_PHY_RX_DC_BIAS_OFFSET | -+ 0x1 << QSGMII_PHY_RX_INPUT_EQU_OFFSET | -+ 0x2 << QSGMII_PHY_CDR_PI_SLEW_OFFSET | -+ 0xC << QSGMII_PHY_TX_DRV_AMP_OFFSET); -+ } -+ -+ return gmac; -+} -+ -+static void ipq806x_gmac_fix_mac_speed(void *priv, unsigned int speed) -+{ -+ struct ipq806x_gmac *gmac = priv; -+ -+ ipq806x_gmac_set_speed(gmac, speed); -+} -+ -+const struct stmmac_of_data ipq806x_gmac_data = { -+ .has_gmac = 1, -+ .setup = ipq806x_gmac_setup, -+ .fix_mac_speed = ipq806x_gmac_fix_mac_speed, -+}; ---- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h -+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h -@@ -137,6 +137,9 @@ void stmmac_disable_eee_mode(struct stmm - bool stmmac_eee_init(struct stmmac_priv *priv); - - #ifdef CONFIG_STMMAC_PLATFORM -+#ifdef CONFIG_DWMAC_IPQ806X -+extern const struct stmmac_of_data ipq806x_gmac_data; -+#endif - #ifdef CONFIG_DWMAC_MESON - extern const struct stmmac_of_data meson6_dwmac_data; - #endif diff --git a/target/linux/ipq806x/patches-3.18/705-net-stmmac-ipq806x-document-device-tree-bindings.patch b/target/linux/ipq806x/patches-3.18/705-net-stmmac-ipq806x-document-device-tree-bindings.patch deleted file mode 100644 index 3144fa36fe..0000000000 --- a/target/linux/ipq806x/patches-3.18/705-net-stmmac-ipq806x-document-device-tree-bindings.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 0f9605d9409b77a89daef91cc68239fc2ff50457 Mon Sep 17 00:00:00 2001 -From: Mathieu Olivari -Date: Fri, 8 May 2015 16:51:25 -0700 -Subject: [PATCH 5/8] net: stmmac: ipq806x: document device tree bindings - -Add the device tree bindings documentation for the QCA IPQ806x -variant of the Synopsys DesignWare MAC. - -Signed-off-by: Mathieu Olivari ---- - .../devicetree/bindings/net/ipq806x-dwmac.txt | 35 ++++++++++++++++++++++ - 1 file changed, 35 insertions(+) - create mode 100644 Documentation/devicetree/bindings/net/ipq806x-dwmac.txt - ---- /dev/null -+++ b/Documentation/devicetree/bindings/net/ipq806x-dwmac.txt -@@ -0,0 +1,35 @@ -+* IPQ806x DWMAC Ethernet controller -+ -+The device inherits all the properties of the dwmac/stmmac devices -+described in the file net/stmmac.txt with the following changes. -+ -+Required properties: -+ -+- compatible: should be "qcom,ipq806x-gmac" along with "snps,dwmac" -+ and any applicable more detailed version number -+ described in net/stmmac.txt -+ -+- qcom,nss-common: should contain a phandle to a syscon device mapping the -+ nss-common registers. -+ -+- qcom,qsgmii-csr: should contain a phandle to a syscon device mapping the -+ qsgmii-csr registers. -+ -+Example: -+ -+ gmac: ethernet@37000000 { -+ device_type = "network"; -+ compatible = "qcom,ipq806x-gmac"; -+ reg = <0x37000000 0x200000>; -+ interrupts = ; -+ interrupt-names = "macirq"; -+ -+ qcom,nss-common = <&nss_common>; -+ qcom,qsgmii-csr = <&qsgmii_csr>; -+ -+ clocks = <&gcc GMAC_CORE1_CLK>; -+ clock-names = "stmmaceth"; -+ -+ resets = <&gcc GMAC_CORE1_RESET>; -+ reset-names = "stmmaceth"; -+ }; diff --git a/target/linux/ipq806x/patches-3.18/706-net-stmmac-create-one-debugfs-dir-per-net-device.patch b/target/linux/ipq806x/patches-3.18/706-net-stmmac-create-one-debugfs-dir-per-net-device.patch deleted file mode 100644 index 50127fdb08..0000000000 --- a/target/linux/ipq806x/patches-3.18/706-net-stmmac-create-one-debugfs-dir-per-net-device.patch +++ /dev/null @@ -1,171 +0,0 @@ -From df944689d491e6af533173bf2ef448c3dd334f15 Mon Sep 17 00:00:00 2001 -From: Mathieu Olivari -Date: Mon, 11 May 2015 15:15:25 -0700 -Subject: [PATCH 6/8] net: stmmac: create one debugfs dir per net-device - -stmmac DebugFS entries are currently global to the driver. As a result, -having more than one stmmac device in the system creates the following -error: -* ERROR stmmaceth, debugfs create directory failed -* stmmac_hw_setup: failed debugFS registration - -This also results in being able to access the debugfs information for -the first registered device only. - -This patch changes the debugfs structure to have one sub-directory per -net-device. Files under "/sys/kernel/debug/stmmaceth" will now show-up -under /sys/kernel/debug/stmmaceth/ethN/. - -Signed-off-by: Mathieu Olivari ---- - drivers/net/ethernet/stmicro/stmmac/stmmac.h | 6 ++ - drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 76 ++++++++++++++++------- - 2 files changed, 59 insertions(+), 23 deletions(-) - ---- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h -+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h -@@ -116,6 +116,12 @@ struct stmmac_priv { - int use_riwt; - int irq_wake; - spinlock_t ptp_lock; -+ -+#ifdef CONFIG_DEBUG_FS -+ struct dentry *dbgfs_dir; -+ struct dentry *dbgfs_rings_status; -+ struct dentry *dbgfs_dma_cap; -+#endif - }; - - int stmmac_mdio_unregister(struct net_device *ndev); ---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c -@@ -119,7 +119,7 @@ static irqreturn_t stmmac_interrupt(int - - #ifdef CONFIG_STMMAC_DEBUG_FS - static int stmmac_init_fs(struct net_device *dev); --static void stmmac_exit_fs(void); -+static void stmmac_exit_fs(struct net_device *dev); - #endif - - #define STMMAC_COAL_TIMER(x) (jiffies + usecs_to_jiffies(x)) -@@ -1879,7 +1879,7 @@ static int stmmac_release(struct net_dev - netif_carrier_off(dev); - - #ifdef CONFIG_STMMAC_DEBUG_FS -- stmmac_exit_fs(); -+ stmmac_exit_fs(dev); - #endif - - stmmac_release_ptp(priv); -@@ -2467,8 +2467,6 @@ static int stmmac_ioctl(struct net_devic - - #ifdef CONFIG_STMMAC_DEBUG_FS - static struct dentry *stmmac_fs_dir; --static struct dentry *stmmac_rings_status; --static struct dentry *stmmac_dma_cap; - - static void sysfs_display_ring(void *head, int size, int extend_desc, - struct seq_file *seq) -@@ -2607,36 +2605,39 @@ static const struct file_operations stmm - - static int stmmac_init_fs(struct net_device *dev) - { -- /* Create debugfs entries */ -- stmmac_fs_dir = debugfs_create_dir(STMMAC_RESOURCE_NAME, NULL); -+ struct stmmac_priv *priv = netdev_priv(dev); -+ -+ /* Create per netdev entries */ -+ priv->dbgfs_dir = debugfs_create_dir(dev->name, stmmac_fs_dir); - -- if (!stmmac_fs_dir || IS_ERR(stmmac_fs_dir)) { -- pr_err("ERROR %s, debugfs create directory failed\n", -- STMMAC_RESOURCE_NAME); -+ if (!priv->dbgfs_dir || IS_ERR(priv->dbgfs_dir)) { -+ pr_err("ERROR %s/%s, debugfs create directory failed\n", -+ STMMAC_RESOURCE_NAME, dev->name); - - return -ENOMEM; - } - - /* Entry to report DMA RX/TX rings */ -- stmmac_rings_status = debugfs_create_file("descriptors_status", -- S_IRUGO, stmmac_fs_dir, dev, -- &stmmac_rings_status_fops); -+ priv->dbgfs_rings_status = -+ debugfs_create_file("descriptors_status", S_IRUGO, -+ priv->dbgfs_dir, dev, -+ &stmmac_rings_status_fops); - -- if (!stmmac_rings_status || IS_ERR(stmmac_rings_status)) { -+ if (!priv->dbgfs_rings_status || IS_ERR(priv->dbgfs_rings_status)) { - pr_info("ERROR creating stmmac ring debugfs file\n"); -- debugfs_remove(stmmac_fs_dir); -+ debugfs_remove_recursive(priv->dbgfs_dir); - - return -ENOMEM; - } - - /* Entry to report the DMA HW features */ -- stmmac_dma_cap = debugfs_create_file("dma_cap", S_IRUGO, stmmac_fs_dir, -- dev, &stmmac_dma_cap_fops); -+ priv->dbgfs_dma_cap = debugfs_create_file("dma_cap", S_IRUGO, -+ priv->dbgfs_dir, -+ dev, &stmmac_dma_cap_fops); - -- if (!stmmac_dma_cap || IS_ERR(stmmac_dma_cap)) { -+ if (!priv->dbgfs_dma_cap || IS_ERR(priv->dbgfs_dma_cap)) { - pr_info("ERROR creating stmmac MMC debugfs file\n"); -- debugfs_remove(stmmac_rings_status); -- debugfs_remove(stmmac_fs_dir); -+ debugfs_remove_recursive(priv->dbgfs_dir); - - return -ENOMEM; - } -@@ -2644,11 +2645,11 @@ static int stmmac_init_fs(struct net_dev - return 0; - } - --static void stmmac_exit_fs(void) -+static void stmmac_exit_fs(struct net_device *dev) - { -- debugfs_remove(stmmac_rings_status); -- debugfs_remove(stmmac_dma_cap); -- debugfs_remove(stmmac_fs_dir); -+ struct stmmac_priv *priv = netdev_priv(dev); -+ -+ debugfs_remove_recursive(priv->dbgfs_dir); - } - #endif /* CONFIG_STMMAC_DEBUG_FS */ - -@@ -3032,6 +3033,21 @@ static int __init stmmac_init(void) - ret = stmmac_register_pci(); - if (ret) - goto err_pci; -+ -+#ifdef CONFIG_STMMAC_DEBUG_FS -+ /* Create debugfs main directory if it doesn't exist yet */ -+ if (stmmac_fs_dir == NULL) { -+ stmmac_fs_dir = debugfs_create_dir(STMMAC_RESOURCE_NAME, NULL); -+ -+ if (!stmmac_fs_dir || IS_ERR(stmmac_fs_dir)) { -+ pr_err("ERROR %s, debugfs create directory failed\n", -+ STMMAC_RESOURCE_NAME); -+ -+ return -ENOMEM; -+ } -+ } -+#endif -+ - return 0; - err_pci: - stmmac_unregister_platform(); -@@ -3042,6 +3058,9 @@ err: - - static void __exit stmmac_exit(void) - { -+#ifdef CONFIG_STMMAC_DEBUG_FS -+ debugfs_remove_recursive(stmmac_fs_dir); -+#endif - stmmac_unregister_platform(); - stmmac_unregister_pci(); - } diff --git a/target/linux/ipq806x/patches-3.18/707-ARM-dts-qcom-add-mdio-nodes-to-ap148-db149.patch b/target/linux/ipq806x/patches-3.18/707-ARM-dts-qcom-add-mdio-nodes-to-ap148-db149.patch deleted file mode 100644 index 809d74372b..0000000000 --- a/target/linux/ipq806x/patches-3.18/707-ARM-dts-qcom-add-mdio-nodes-to-ap148-db149.patch +++ /dev/null @@ -1,145 +0,0 @@ -From e81de9d28bd0421c236df322872e64edf4ee1852 Mon Sep 17 00:00:00 2001 -From: Mathieu Olivari -Date: Mon, 11 May 2015 16:32:09 -0700 -Subject: [PATCH 7/8] ARM: dts: qcom: add mdio nodes to ap148 & db149 - -Signed-off-by: Mathieu Olivari ---- - arch/arm/boot/dts/qcom-ipq8064-ap148.dts | 40 ++++++++++++++++++++++++++- - arch/arm/boot/dts/qcom-ipq8064-db149.dts | 46 ++++++++++++++++++++++++++++++++ - 2 files changed, 85 insertions(+), 1 deletion(-) - ---- a/arch/arm/boot/dts/qcom-ipq8064-ap148.dts -+++ b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts -@@ -14,8 +14,9 @@ - }; - }; - -- alias { -+ aliases { - serial0 = &uart4; -+ mdio-gpio0 = &mdio0; - }; - - chosen { -@@ -54,6 +55,15 @@ - bias-none; - }; - }; -+ -+ mdio0_pins: mdio0_pins { -+ mux { -+ pins = "gpio0", "gpio1"; -+ function = "gpio"; -+ drive-strength = <8>; -+ bias-disable; -+ }; -+ }; - }; - - gsbi@16300000 { -@@ -163,5 +173,33 @@ - pinctrl-0 = <&pcie2_pins>; - pinctrl-names = "default"; - }; -+ -+ mdio0: mdio { -+ compatible = "virtual,mdio-gpio"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ gpios = <&qcom_pinmux 1 0 &qcom_pinmux 0 0>; -+ pinctrl-0 = <&mdio0_pins>; -+ pinctrl-names = "default"; -+ -+ phy0: ethernet-phy@0 { -+ device_type = "ethernet-phy"; -+ reg = <0>; -+ qca,ar8327-initvals = < -+ 0x00004 0x7600000 /* PAD0_MODE */ -+ 0x00008 0x1000000 /* PAD5_MODE */ -+ 0x0000c 0x80 /* PAD6_MODE */ -+ 0x000e4 0xaa545 /* MAC_POWER_SEL */ -+ 0x000e0 0xc74164de /* SGMII_CTRL */ -+ 0x0007c 0x4e /* PORT0_STATUS */ -+ 0x00094 0x4e /* PORT6_STATUS */ -+ >; -+ }; -+ -+ phy4: ethernet-phy@4 { -+ device_type = "ethernet-phy"; -+ reg = <4>; -+ }; -+ }; - }; - }; ---- a/arch/arm/boot/dts/qcom-ipq8064-db149.dts -+++ b/arch/arm/boot/dts/qcom-ipq8064-db149.dts -@@ -16,6 +16,7 @@ - - alias { - serial0 = &uart2; -+ mdio-gpio0 = &mdio0; - }; - - chosen { -@@ -62,6 +63,15 @@ - bias-none; - }; - }; -+ -+ mdio0_pins: mdio0_pins { -+ mux { -+ pins = "gpio0", "gpio1"; -+ function = "gpio"; -+ drive-strength = <8>; -+ bias-disable; -+ }; -+ }; - }; - - gsbi2: gsbi@12480000 { -@@ -173,5 +183,44 @@ - pinctrl-0 = <&pcie3_pins>; - pinctrl-names = "default"; - }; -+ -+ mdio0: mdio { -+ compatible = "virtual,mdio-gpio"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ gpios = <&qcom_pinmux 1 0 &qcom_pinmux 0 0>; -+ -+ pinctrl-0 = <&mdio0_pins>; -+ pinctrl-names = "default"; -+ -+ phy0: ethernet-phy@0 { -+ device_type = "ethernet-phy"; -+ reg = <0>; -+ qca,ar8327-initvals = < -+ 0x00004 0x7600000 /* PAD0_MODE */ -+ 0x00008 0x1000000 /* PAD5_MODE */ -+ 0x0000c 0x80 /* PAD6_MODE */ -+ 0x000e4 0xaa545 /* MAC_POWER_SEL */ -+ 0x000e0 0xc74164de /* SGMII_CTRL */ -+ 0x0007c 0x4e /* PORT0_STATUS */ -+ 0x00094 0x4e /* PORT6_STATUS */ -+ >; -+ }; -+ -+ phy4: ethernet-phy@4 { -+ device_type = "ethernet-phy"; -+ reg = <4>; -+ }; -+ -+ phy6: ethernet-phy@6 { -+ device_type = "ethernet-phy"; -+ reg = <6>; -+ }; -+ -+ phy7: ethernet-phy@7 { -+ device_type = "ethernet-phy"; -+ reg = <7>; -+ }; -+ }; - }; - }; diff --git a/target/linux/ipq806x/patches-3.18/708-ARM-dts-qcom-add-gmac-nodes-to-ipq806x-platforms.patch b/target/linux/ipq806x/patches-3.18/708-ARM-dts-qcom-add-gmac-nodes-to-ipq806x-platforms.patch deleted file mode 100644 index cce30b09a2..0000000000 --- a/target/linux/ipq806x/patches-3.18/708-ARM-dts-qcom-add-gmac-nodes-to-ipq806x-platforms.patch +++ /dev/null @@ -1,210 +0,0 @@ -From cab1f4720e82f2e17eaeed9a9ad9e4f07c742977 Mon Sep 17 00:00:00 2001 -From: Mathieu Olivari -Date: Mon, 11 May 2015 12:29:18 -0700 -Subject: [PATCH 8/8] ARM: dts: qcom: add gmac nodes to ipq806x platforms - -Signed-off-by: Mathieu Olivari ---- - arch/arm/boot/dts/qcom-ipq8064-ap148.dts | 31 ++++++++++++ - arch/arm/boot/dts/qcom-ipq8064-db149.dts | 43 ++++++++++++++++ - arch/arm/boot/dts/qcom-ipq8064.dtsi | 86 ++++++++++++++++++++++++++++++++ - 3 files changed, 160 insertions(+) - ---- a/arch/arm/boot/dts/qcom-ipq8064-ap148.dts -+++ b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts -@@ -64,6 +64,16 @@ - bias-disable; - }; - }; -+ -+ rgmii2_pins: rgmii2_pins { -+ mux { -+ pins = "gpio27", "gpio28", "gpio29", "gpio30", "gpio31", "gpio32", -+ "gpio51", "gpio52", "gpio59", "gpio60", "gpio61", "gpio62" ; -+ function = "rgmii2"; -+ drive-strength = <8>; -+ bias-disable; -+ }; -+ }; - }; - - gsbi@16300000 { -@@ -201,5 +211,26 @@ - reg = <4>; - }; - }; -+ -+ gmac1: ethernet@37200000 { -+ status = "ok"; -+ phy-mode = "rgmii"; -+ phy-handle = <&phy4>; -+ qcom,id = <1>; -+ -+ pinctrl-0 = <&rgmii2_pins>; -+ pinctrl-names = "default"; -+ }; -+ -+ gmac2: ethernet@37400000 { -+ status = "ok"; -+ phy-mode = "sgmii"; -+ qcom,id = <2>; -+ -+ fixed-link { -+ speed = <1000>; -+ full-duplex; -+ }; -+ }; - }; - }; ---- a/arch/arm/boot/dts/qcom-ipq8064-db149.dts -+++ b/arch/arm/boot/dts/qcom-ipq8064-db149.dts -@@ -72,6 +72,14 @@ - bias-disable; - }; - }; -+ -+ rgmii0_pins: rgmii0_pins { -+ mux { -+ pins = "gpio2", "gpio66"; -+ drive-strength = <8>; -+ bias-disable; -+ }; -+ }; - }; - - gsbi2: gsbi@12480000 { -@@ -222,5 +230,40 @@ - reg = <7>; - }; - }; -+ -+ gmac0: ethernet@37000000 { -+ status = "ok"; -+ phy-mode = "rgmii"; -+ qcom,id = <0>; -+ phy-handle = <&phy4>; -+ -+ pinctrl-0 = <&rgmii0_pins>; -+ pinctrl-names = "default"; -+ }; -+ -+ gmac1: ethernet@37200000 { -+ status = "ok"; -+ phy-mode = "sgmii"; -+ qcom,id = <1>; -+ -+ fixed-link { -+ speed = <1000>; -+ full-duplex; -+ }; -+ }; -+ -+ gmac2: ethernet@37400000 { -+ status = "ok"; -+ phy-mode = "sgmii"; -+ qcom,id = <2>; -+ phy-handle = <&phy6>; -+ }; -+ -+ gmac3: ethernet@37600000 { -+ status = "ok"; -+ phy-mode = "sgmii"; -+ qcom,id = <3>; -+ phy-handle = <&phy7>; -+ }; - }; - }; ---- a/arch/arm/boot/dts/qcom-ipq8064.dtsi -+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi -@@ -638,5 +638,91 @@ - dr_mode = "host"; - }; - }; -+ -+ nss_common: syscon@03000000 { -+ compatible = "syscon"; -+ reg = <0x03000000 0x0000FFFF>; -+ }; -+ -+ qsgmii_csr: syscon@1bb00000 { -+ compatible = "syscon"; -+ reg = <0x1bb00000 0x000001FF>; -+ }; -+ -+ gmac0: ethernet@37000000 { -+ device_type = "network"; -+ compatible = "qcom,ipq806x-gmac"; -+ reg = <0x37000000 0x200000>; -+ interrupts = ; -+ interrupt-names = "macirq"; -+ -+ qcom,nss-common = <&nss_common>; -+ qcom,qsgmii-csr = <&qsgmii_csr>; -+ -+ clocks = <&gcc GMAC_CORE1_CLK>; -+ clock-names = "stmmaceth"; -+ -+ resets = <&gcc GMAC_CORE1_RESET>; -+ reset-names = "stmmaceth"; -+ -+ status = "disabled"; -+ }; -+ -+ gmac1: ethernet@37200000 { -+ device_type = "network"; -+ compatible = "qcom,ipq806x-gmac"; -+ reg = <0x37200000 0x200000>; -+ interrupts = ; -+ interrupt-names = "macirq"; -+ -+ qcom,nss-common = <&nss_common>; -+ qcom,qsgmii-csr = <&qsgmii_csr>; -+ -+ clocks = <&gcc GMAC_CORE2_CLK>; -+ clock-names = "stmmaceth"; -+ -+ resets = <&gcc GMAC_CORE2_RESET>; -+ reset-names = "stmmaceth"; -+ -+ status = "disabled"; -+ }; -+ -+ gmac2: ethernet@37400000 { -+ device_type = "network"; -+ compatible = "qcom,ipq806x-gmac"; -+ reg = <0x37400000 0x200000>; -+ interrupts = ; -+ interrupt-names = "macirq"; -+ -+ qcom,nss-common = <&nss_common>; -+ qcom,qsgmii-csr = <&qsgmii_csr>; -+ -+ clocks = <&gcc GMAC_CORE3_CLK>; -+ clock-names = "stmmaceth"; -+ -+ resets = <&gcc GMAC_CORE3_RESET>; -+ reset-names = "stmmaceth"; -+ -+ status = "disabled"; -+ }; -+ -+ gmac3: ethernet@37600000 { -+ device_type = "network"; -+ compatible = "qcom,ipq806x-gmac"; -+ reg = <0x37600000 0x200000>; -+ interrupts = ; -+ interrupt-names = "macirq"; -+ -+ qcom,nss-common = <&nss_common>; -+ qcom,qsgmii-csr = <&qsgmii_csr>; -+ -+ clocks = <&gcc GMAC_CORE4_CLK>; -+ clock-names = "stmmaceth"; -+ -+ resets = <&gcc GMAC_CORE4_RESET>; -+ reset-names = "stmmaceth"; -+ -+ status = "disabled"; -+ }; - }; - }; diff --git a/target/linux/ipq806x/profiles/default.mk b/target/linux/ipq806x/profiles/default.mk deleted file mode 100644 index 6469bcb5f1..0000000000 --- a/target/linux/ipq806x/profiles/default.mk +++ /dev/null @@ -1,19 +0,0 @@ -# -# Copyright (c) 2014 The Linux Foundation. All rights reserved. -# Copyright (C) 2009 OpenWrt.org -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# - -define Profile/Default - NAME:=Default Profile (minimum package set) - PACKAGES:= \ - kmod-usb-core kmod-usb-ohci kmod-usb2 kmod-ledtrig-usbdev \ - kmod-usb3 kmod-usb-dwc3-qcom kmod-usb-phy-qcom-dwc3 -endef - -define Profile/Default/Description - Default package set compatible with most boards. -endef -$(eval $(call Profile,Default))