mirror of
https://github.com/hanwckf/immortalwrt-mt798x.git
synced 2025-01-10 03:09:08 +08:00
layerscape: drop kernel 4.9 support
This patch is to drop kernel 4.9 support. Signed-off-by: Biwen Li <biwen.li@nxp.com> Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
This commit is contained in:
parent
328530c6e7
commit
68904cb8fd
@ -1,952 +0,0 @@
|
||||
CONFIG_ABX500_CORE=y
|
||||
CONFIG_AD525X_DPOT=y
|
||||
CONFIG_AD525X_DPOT_I2C=y
|
||||
# CONFIG_AD525X_DPOT_SPI is not set
|
||||
CONFIG_AHCI_IMX=y
|
||||
CONFIG_AHCI_QORIQ=y
|
||||
CONFIG_AK8975=y
|
||||
CONFIG_ALIGNMENT_TRAP=y
|
||||
CONFIG_APDS9802ALS=y
|
||||
CONFIG_AQUANTIA_PHY=y
|
||||
# CONFIG_ARCH_AXXIA is not set
|
||||
CONFIG_ARCH_CLOCKSOURCE_DATA=y
|
||||
CONFIG_ARCH_DMA_ADDR_T_64BIT=y
|
||||
CONFIG_ARCH_HAS_ELF_RANDOMIZE=y
|
||||
CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y
|
||||
CONFIG_ARCH_HAS_RESET_CONTROLLER=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_MULTIPLATFORM=y
|
||||
# CONFIG_ARCH_MULTI_CPU_AUTO is not set
|
||||
CONFIG_ARCH_MULTI_V6_V7=y
|
||||
CONFIG_ARCH_MULTI_V7=y
|
||||
CONFIG_ARCH_MXC=y
|
||||
CONFIG_ARCH_NR_GPIO=0
|
||||
CONFIG_ARCH_PHYS_ADDR_T_64BIT=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_BIG_ENDIAN=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_ARM=y
|
||||
CONFIG_ARM_APPENDED_DTB=y
|
||||
CONFIG_ARM_ARCH_TIMER=y
|
||||
CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
|
||||
CONFIG_ARM_ATAG_DTB_COMPAT=y
|
||||
# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set
|
||||
CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER=y
|
||||
CONFIG_ARM_CPUIDLE=y
|
||||
CONFIG_ARM_CPU_SUSPEND=y
|
||||
CONFIG_ARM_CRYPTO=y
|
||||
CONFIG_ARM_ERRATA_430973=y
|
||||
CONFIG_ARM_ERRATA_643719=y
|
||||
CONFIG_ARM_ERRATA_720789=y
|
||||
CONFIG_ARM_ERRATA_754322=y
|
||||
CONFIG_ARM_ERRATA_754327=y
|
||||
CONFIG_ARM_ERRATA_764369=y
|
||||
CONFIG_ARM_ERRATA_775420=y
|
||||
CONFIG_ARM_ERRATA_798181=y
|
||||
CONFIG_ARM_GIC=y
|
||||
CONFIG_ARM_HAS_SG_CHAIN=y
|
||||
CONFIG_ARM_HEAVY_MB=y
|
||||
# CONFIG_ARM_HIGHBANK_CPUIDLE is not set
|
||||
CONFIG_ARM_IMX6Q_CPUFREQ=y
|
||||
CONFIG_ARM_L1_CACHE_SHIFT=6
|
||||
CONFIG_ARM_L1_CACHE_SHIFT_6=y
|
||||
CONFIG_ARM_LPAE=y
|
||||
CONFIG_ARM_PATCH_IDIV=y
|
||||
CONFIG_ARM_PATCH_PHYS_VIRT=y
|
||||
CONFIG_ARM_PMU=y
|
||||
CONFIG_ARM_PSCI=y
|
||||
CONFIG_ARM_PSCI_FW=y
|
||||
# CONFIG_ARM_SMMU is not set
|
||||
CONFIG_ARM_THUMB=y
|
||||
CONFIG_ARM_THUMBEE=y
|
||||
CONFIG_ARM_TIMER_SP804=y
|
||||
CONFIG_ARM_UNWIND=y
|
||||
CONFIG_ARM_VIRT_EXT=y
|
||||
CONFIG_ASSOCIATIVE_ARRAY=y
|
||||
CONFIG_AT803X_PHY=y
|
||||
CONFIG_ATA=y
|
||||
CONFIG_ATAGS=y
|
||||
CONFIG_ATA_VERBOSE_ERROR=y
|
||||
CONFIG_AUTOFS4_FS=y
|
||||
CONFIG_AUTO_ZRELADDR=y
|
||||
# CONFIG_AXP20X_POWER is not set
|
||||
CONFIG_BATTERY_ACT8945A=y
|
||||
CONFIG_BATTERY_SBS=y
|
||||
CONFIG_BCM_NET_PHYLIB=y
|
||||
# CONFIG_BLK_CGROUP is not set
|
||||
CONFIG_BLK_CMDLINE_PARSER=y
|
||||
CONFIG_BLK_DEV_BSG=y
|
||||
CONFIG_BLK_DEV_LOOP=y
|
||||
CONFIG_BLK_DEV_RAM=y
|
||||
CONFIG_BLK_DEV_RAM_COUNT=16
|
||||
CONFIG_BLK_DEV_RAM_SIZE=262144
|
||||
CONFIG_BLK_DEV_SD=y
|
||||
CONFIG_BLK_DEV_SR=y
|
||||
# CONFIG_BLK_DEV_SR_VENDOR is not set
|
||||
CONFIG_BLK_MQ_PCI=y
|
||||
# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
|
||||
CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
|
||||
# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
|
||||
CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
|
||||
CONFIG_BOUNCE=y
|
||||
# CONFIG_BPF_SYSCALL is not set
|
||||
CONFIG_BRCMSTB_GISB_ARB=y
|
||||
CONFIG_BROADCOM_PHY=y
|
||||
CONFIG_BUILD_BIN2C=y
|
||||
CONFIG_CACHE_L2X0=y
|
||||
# CONFIG_CACHE_L2X0_PMU is not set
|
||||
CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y
|
||||
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
|
||||
# CONFIG_CFS_BANDWIDTH is not set
|
||||
CONFIG_CGROUPS=y
|
||||
CONFIG_CGROUP_CPUACCT=y
|
||||
CONFIG_CGROUP_DEVICE=y
|
||||
CONFIG_CGROUP_FREEZER=y
|
||||
# CONFIG_CGROUP_PERF is not set
|
||||
CONFIG_CGROUP_PIDS=y
|
||||
CONFIG_CGROUP_SCHED=y
|
||||
# CONFIG_CHARGER_MAX14577 is not set
|
||||
CONFIG_CHARGER_TPS65090=y
|
||||
# CONFIG_CHARGER_TPS65217 is not set
|
||||
CONFIG_CHECKPOINT_RESTORE=y
|
||||
CONFIG_CHROME_PLATFORMS=y
|
||||
CONFIG_CHR_DEV_SG=y
|
||||
CONFIG_CLKDEV_LOOKUP=y
|
||||
CONFIG_CLKSRC_IMX_GPT=y
|
||||
CONFIG_CLKSRC_MMIO=y
|
||||
CONFIG_CLKSRC_OF=y
|
||||
CONFIG_CLKSRC_PROBE=y
|
||||
CONFIG_CLKSRC_VERSATILE=y
|
||||
CONFIG_CLK_QORIQ=y
|
||||
CONFIG_CLONE_BACKWARDS=y
|
||||
CONFIG_CMA=y
|
||||
CONFIG_CMA_ALIGNMENT=8
|
||||
CONFIG_CMA_AREAS=7
|
||||
# CONFIG_CMA_DEBUG is not set
|
||||
# CONFIG_CMA_DEBUGFS is not set
|
||||
CONFIG_CMA_SIZE_MBYTES=64
|
||||
# CONFIG_CMA_SIZE_SEL_MAX is not set
|
||||
CONFIG_CMA_SIZE_SEL_MBYTES=y
|
||||
# CONFIG_CMA_SIZE_SEL_MIN is not set
|
||||
# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set
|
||||
CONFIG_CMDLINE_PARTITION=y
|
||||
CONFIG_COMMON_CLK=y
|
||||
CONFIG_COMMON_CLK_MAX77686=y
|
||||
# CONFIG_COMMON_CLK_PALMAS is not set
|
||||
# CONFIG_COMMON_CLK_RK808 is not set
|
||||
# CONFIG_COMMON_CLK_S2MPS11 is not set
|
||||
CONFIG_COMPAT_BRK=y
|
||||
CONFIG_CONFIGFS_FS=y
|
||||
CONFIG_CONSOLE_TRANSLATIONS=y
|
||||
CONFIG_COREDUMP=y
|
||||
CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
|
||||
# CONFIG_CORTINA_PHY is not set
|
||||
CONFIG_CPUFREQ_DT=y
|
||||
CONFIG_CPUFREQ_DT_PLATDEV=y
|
||||
CONFIG_CPUSETS=y
|
||||
CONFIG_CPU_32v6K=y
|
||||
CONFIG_CPU_32v7=y
|
||||
CONFIG_CPU_ABRT_EV7=y
|
||||
# CONFIG_CPU_BIG_ENDIAN is not set
|
||||
# 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_ONDEMAND=y
|
||||
# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
|
||||
CONFIG_CPU_FREQ_GOV_ATTR_SET=y
|
||||
CONFIG_CPU_FREQ_GOV_COMMON=y
|
||||
# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
|
||||
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
|
||||
CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
|
||||
# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
|
||||
CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
|
||||
# CONFIG_CPU_FREQ_GOV_USERSPACE is not set
|
||||
CONFIG_CPU_FREQ_STAT=y
|
||||
CONFIG_CPU_HAS_ASID=y
|
||||
# CONFIG_CPU_HOTPLUG_STATE_CONTROL is not set
|
||||
# CONFIG_CPU_ICACHE_DISABLE is not set
|
||||
CONFIG_CPU_IDLE=y
|
||||
# CONFIG_CPU_IDLE_GOV_LADDER is not set
|
||||
CONFIG_CPU_IDLE_GOV_MENU=y
|
||||
CONFIG_CPU_PABRT_V7=y
|
||||
CONFIG_CPU_PM=y
|
||||
CONFIG_CPU_RMAP=y
|
||||
CONFIG_CPU_THERMAL=y
|
||||
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_AEAD=y
|
||||
CONFIG_CRYPTO_AEAD2=y
|
||||
# CONFIG_CRYPTO_AES_ARM_CE is not set
|
||||
CONFIG_CRYPTO_CRC32C=y
|
||||
CONFIG_CRYPTO_DEFLATE=y
|
||||
# CONFIG_CRYPTO_GHASH_ARM_CE is not set
|
||||
CONFIG_CRYPTO_HASH=y
|
||||
CONFIG_CRYPTO_HASH2=y
|
||||
CONFIG_CRYPTO_LZO=y
|
||||
CONFIG_CRYPTO_MANAGER=y
|
||||
CONFIG_CRYPTO_MANAGER2=y
|
||||
CONFIG_CRYPTO_NULL2=y
|
||||
# CONFIG_CRYPTO_PCRYPT is not set
|
||||
CONFIG_CRYPTO_RNG2=y
|
||||
# CONFIG_CRYPTO_SHA1_ARM_CE is not set
|
||||
# CONFIG_CRYPTO_SHA1_ARM_NEON is not set
|
||||
# CONFIG_CRYPTO_SHA256_ARM is not set
|
||||
# CONFIG_CRYPTO_SHA2_ARM_CE is not set
|
||||
# CONFIG_CRYPTO_SHA512_ARM is not set
|
||||
# CONFIG_CRYPTO_TLS is not set
|
||||
CONFIG_CRYPTO_WORKQUEUE=y
|
||||
CONFIG_DCACHE_WORD_ACCESS=y
|
||||
CONFIG_DEBUG_ALIGN_RODATA=y
|
||||
CONFIG_DEBUG_BUGVERBOSE=y
|
||||
CONFIG_DEBUG_IMX_UART_PORT=1
|
||||
CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
|
||||
CONFIG_DEBUG_RODATA=y
|
||||
# CONFIG_DEBUG_UART_8250 is not set
|
||||
# CONFIG_DEBUG_USER is not set
|
||||
CONFIG_DECOMPRESS_BZIP2=y
|
||||
CONFIG_DECOMPRESS_GZIP=y
|
||||
CONFIG_DECOMPRESS_LZMA=y
|
||||
CONFIG_DECOMPRESS_LZO=y
|
||||
CONFIG_DECOMPRESS_XZ=y
|
||||
CONFIG_DEFAULT_CFQ=y
|
||||
# CONFIG_DEFAULT_DEADLINE is not set
|
||||
CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120
|
||||
CONFIG_DEFAULT_IOSCHED="cfq"
|
||||
CONFIG_DETECT_HUNG_TASK=y
|
||||
# CONFIG_DEVFREQ_GOV_PASSIVE is not set
|
||||
# CONFIG_DEVFREQ_GOV_PERFORMANCE is not set
|
||||
# CONFIG_DEVFREQ_GOV_POWERSAVE is not set
|
||||
# CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND is not set
|
||||
# CONFIG_DEVFREQ_GOV_USERSPACE is not set
|
||||
# CONFIG_DEVFREQ_THERMAL is not set
|
||||
CONFIG_DEVKMEM=y
|
||||
CONFIG_DEVMEM=y
|
||||
CONFIG_DEVTMPFS=y
|
||||
CONFIG_DEVTMPFS_MOUNT=y
|
||||
CONFIG_DMADEVICES=y
|
||||
CONFIG_DMA_CMA=y
|
||||
CONFIG_DMA_ENGINE=y
|
||||
CONFIG_DMA_OF=y
|
||||
CONFIG_DMA_SHARED_BUFFER=y
|
||||
CONFIG_DMA_VIRTUAL_CHANNELS=y
|
||||
CONFIG_DNOTIFY=y
|
||||
CONFIG_DNS_RESOLVER=y
|
||||
CONFIG_DTC=y
|
||||
CONFIG_DT_IDLE_STATES=y
|
||||
CONFIG_DUMMY_CONSOLE=y
|
||||
CONFIG_DW_DMAC=y
|
||||
CONFIG_DW_DMAC_CORE=y
|
||||
CONFIG_DW_WATCHDOG=y
|
||||
CONFIG_EDAC=y
|
||||
CONFIG_EDAC_ATOMIC_SCRUB=y
|
||||
# CONFIG_EDAC_DEBUG is not set
|
||||
CONFIG_EDAC_LEGACY_SYSFS=y
|
||||
# CONFIG_EDAC_MM_EDAC is not set
|
||||
CONFIG_EDAC_SUPPORT=y
|
||||
CONFIG_EEPROM_93CX6=y
|
||||
CONFIG_EEPROM_AT24=y
|
||||
CONFIG_EFI=y
|
||||
# CONFIG_EFIVAR_FS is not set
|
||||
CONFIG_EFI_ARMSTUB=y
|
||||
# CONFIG_EFI_CAPSULE_LOADER is not set
|
||||
CONFIG_EFI_ESRT=y
|
||||
CONFIG_EFI_PARAMS_FROM_FDT=y
|
||||
CONFIG_EFI_RUNTIME_WRAPPERS=y
|
||||
CONFIG_EFI_STUB=y
|
||||
# CONFIG_EFI_TEST is not set
|
||||
# CONFIG_EFI_VARS is not set
|
||||
CONFIG_ELF_CORE=y
|
||||
# CONFIG_ENABLE_DEFAULT_TRACERS is not set
|
||||
CONFIG_ENABLE_MUST_CHECK=y
|
||||
CONFIG_EXPORTFS=y
|
||||
CONFIG_EXT4_FS=y
|
||||
CONFIG_EXT4_FS_POSIX_ACL=y
|
||||
CONFIG_EXT4_FS_SECURITY=y
|
||||
CONFIG_EXTCON=y
|
||||
# CONFIG_EXTCON_MAX14577 is not set
|
||||
# CONFIG_EXTCON_MAX8997 is not set
|
||||
# CONFIG_EXTCON_PALMAS is not set
|
||||
CONFIG_FAIR_GROUP_SCHED=y
|
||||
CONFIG_FAT_FS=y
|
||||
# CONFIG_FEC is not set
|
||||
CONFIG_FHANDLE=y
|
||||
CONFIG_FIRMWARE_IN_KERNEL=y
|
||||
CONFIG_FIXED_PHY=y
|
||||
CONFIG_FIX_EARLYCON_MEM=y
|
||||
CONFIG_FORCE_MAX_ZONEORDER=12
|
||||
CONFIG_FREEZER=y
|
||||
CONFIG_FSL_EDMA=y
|
||||
CONFIG_FSL_GUTS=y
|
||||
CONFIG_FSL_IFC=y
|
||||
# CONFIG_FSL_PPFE is not set
|
||||
CONFIG_FSL_PQ_MDIO=y
|
||||
# CONFIG_FSL_QDMA is not set
|
||||
# CONFIG_FSL_SDK_DPA is not set
|
||||
CONFIG_FSL_XGMAC_MDIO=y
|
||||
CONFIG_FS_MBCACHE=y
|
||||
CONFIG_FS_POSIX_ACL=y
|
||||
CONFIG_FTM_ALARM=y
|
||||
CONFIG_FTRACE=y
|
||||
# CONFIG_FTRACE_SYSCALLS is not set
|
||||
CONFIG_FUSE_FS=y
|
||||
# CONFIG_FW_LOADER_USER_HELPER_FALLBACK is not set
|
||||
CONFIG_GENERIC_ALLOCATOR=y
|
||||
CONFIG_GENERIC_BUG=y
|
||||
CONFIG_GENERIC_CLOCKEVENTS=y
|
||||
CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
|
||||
CONFIG_GENERIC_EARLY_IOREMAP=y
|
||||
CONFIG_GENERIC_IDLE_POLL_SETUP=y
|
||||
CONFIG_GENERIC_IO=y
|
||||
CONFIG_GENERIC_IRQ_CHIP=y
|
||||
# CONFIG_GENERIC_IRQ_DEBUGFS is not set
|
||||
CONFIG_GENERIC_IRQ_SHOW=y
|
||||
CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
|
||||
CONFIG_GENERIC_MSI_IRQ=y
|
||||
CONFIG_GENERIC_MSI_IRQ_DOMAIN=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_GENERIC_TIME_VSYSCALL=y
|
||||
CONFIG_GIANFAR=y
|
||||
CONFIG_GLOB=y
|
||||
CONFIG_GPIOLIB=y
|
||||
CONFIG_GPIOLIB_IRQCHIP=y
|
||||
# CONFIG_GPIO_AXP209 is not set
|
||||
CONFIG_GPIO_DWAPB=y
|
||||
CONFIG_GPIO_EM=y
|
||||
CONFIG_GPIO_GENERIC=y
|
||||
CONFIG_GPIO_GENERIC_PLATFORM=y
|
||||
CONFIG_GPIO_MXC=y
|
||||
CONFIG_GPIO_PALMAS=y
|
||||
CONFIG_GPIO_PCA953X=y
|
||||
CONFIG_GPIO_PCA953X_IRQ=y
|
||||
CONFIG_GPIO_PCF857X=y
|
||||
# CONFIG_GPIO_STMPE is not set
|
||||
CONFIG_GPIO_SYSCON=y
|
||||
# CONFIG_GPIO_TPS65218 is not set
|
||||
CONFIG_GPIO_TPS6586X=y
|
||||
CONFIG_GPIO_TPS65910=y
|
||||
CONFIG_GPIO_TWL4030=y
|
||||
CONFIG_GPIO_XILINX=y
|
||||
CONFIG_HANDLE_DOMAIN_IRQ=y
|
||||
CONFIG_HARDEN_BRANCH_PREDICTOR=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_BITREVERSE=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_ARCH_TRANSPARENT_HUGEPAGE=y
|
||||
CONFIG_HAVE_ARM_ARCH_TIMER=y
|
||||
CONFIG_HAVE_ARM_SMCCC=y
|
||||
# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
|
||||
CONFIG_HAVE_CBPF_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_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_GENERIC_RCU_GUP=y
|
||||
CONFIG_HAVE_HW_BREAKPOINT=y
|
||||
CONFIG_HAVE_IDE=y
|
||||
CONFIG_HAVE_IMX_SRC=y
|
||||
CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
|
||||
CONFIG_HAVE_KVM_ARCH_TLB_FLUSH_ALL=y
|
||||
CONFIG_HAVE_KVM_CPU_RELAX_INTERCEPT=y
|
||||
CONFIG_HAVE_KVM_EVENTFD=y
|
||||
CONFIG_HAVE_KVM_IRQCHIP=y
|
||||
CONFIG_HAVE_KVM_IRQFD=y
|
||||
CONFIG_HAVE_KVM_IRQ_ROUTING=y
|
||||
CONFIG_HAVE_MEMBLOCK=y
|
||||
CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
|
||||
CONFIG_HAVE_NET_DSA=y
|
||||
CONFIG_HAVE_OPROFILE=y
|
||||
CONFIG_HAVE_OPTPROBES=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_RCU_TABLE_FREE=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_HID=y
|
||||
CONFIG_HID_GENERIC=y
|
||||
CONFIG_HIGHMEM=y
|
||||
CONFIG_HIGHPTE=y
|
||||
CONFIG_HOTPLUG_CPU=y
|
||||
# CONFIG_HUGETLBFS is not set
|
||||
CONFIG_HVC_DRIVER=y
|
||||
CONFIG_HWMON=y
|
||||
CONFIG_HW_CONSOLE=y
|
||||
CONFIG_HW_RANDOM=y
|
||||
CONFIG_HZ_FIXED=0
|
||||
CONFIG_I2C=y
|
||||
CONFIG_I2C_BOARDINFO=y
|
||||
CONFIG_I2C_CHARDEV=y
|
||||
CONFIG_I2C_COMPAT=y
|
||||
CONFIG_I2C_DEMUX_PINCTRL=y
|
||||
CONFIG_I2C_DESIGNWARE_CORE=y
|
||||
CONFIG_I2C_DESIGNWARE_PLATFORM=y
|
||||
CONFIG_I2C_HELPER_AUTO=y
|
||||
CONFIG_I2C_IMX=y
|
||||
CONFIG_I2C_MUX=y
|
||||
CONFIG_I2C_MUX_PCA954x=y
|
||||
CONFIG_I2C_MUX_PINCTRL=y
|
||||
CONFIG_I2C_RK3X=y
|
||||
CONFIG_I2C_SLAVE=y
|
||||
CONFIG_I2C_SLAVE_EEPROM=y
|
||||
CONFIG_I2C_XILINX=y
|
||||
CONFIG_ICPLUS_PHY=y
|
||||
CONFIG_ICS932S401=y
|
||||
CONFIG_IIO=y
|
||||
CONFIG_IIO_BUFFER=y
|
||||
CONFIG_IIO_CONFIGFS=y
|
||||
CONFIG_IIO_HRTIMER_TRIGGER=y
|
||||
CONFIG_IIO_KFIFO_BUF=y
|
||||
CONFIG_IIO_SW_TRIGGER=y
|
||||
# CONFIG_IIO_TIGHTLOOP_TRIGGER is not set
|
||||
CONFIG_IIO_TRIGGER=y
|
||||
CONFIG_IIO_TRIGGERED_BUFFER=y
|
||||
CONFIG_IKCONFIG=y
|
||||
CONFIG_IKCONFIG_PROC=y
|
||||
CONFIG_IMX2_WDT=y
|
||||
CONFIG_IMX_DMA=y
|
||||
CONFIG_IMX_SDMA=y
|
||||
# CONFIG_IMX_WEIM is not set
|
||||
CONFIG_INITRAMFS_SOURCE=""
|
||||
CONFIG_INPUT=y
|
||||
# CONFIG_INPUT_MISC is not set
|
||||
CONFIG_IOMMU_HELPER=y
|
||||
# CONFIG_IOMMU_IO_PGTABLE_ARMV7S is not set
|
||||
# CONFIG_IOMMU_IO_PGTABLE_LPAE is not set
|
||||
CONFIG_IOMMU_SUPPORT=y
|
||||
CONFIG_IOSCHED_CFQ=y
|
||||
CONFIG_IPC_NS=y
|
||||
CONFIG_IRQCHIP=y
|
||||
CONFIG_IRQ_DOMAIN=y
|
||||
CONFIG_IRQ_DOMAIN_DEBUG=y
|
||||
CONFIG_IRQ_DOMAIN_HIERARCHY=y
|
||||
CONFIG_IRQ_FORCED_THREADING=y
|
||||
CONFIG_IRQ_WORK=y
|
||||
# CONFIG_ISDN is not set
|
||||
CONFIG_ISL29003=y
|
||||
CONFIG_JBD2=y
|
||||
CONFIG_KALLSYMS=y
|
||||
CONFIG_KERNEL_GZIP=y
|
||||
# CONFIG_KERNEL_XZ is not set
|
||||
CONFIG_KEXEC=y
|
||||
CONFIG_KEXEC_CORE=y
|
||||
CONFIG_KEYS=y
|
||||
CONFIG_KVM=y
|
||||
CONFIG_KVM_ARM_HOST=y
|
||||
CONFIG_KVM_GENERIC_DIRTYLOG_READ_PROTECT=y
|
||||
CONFIG_KVM_MMIO=y
|
||||
CONFIG_KVM_VFIO=y
|
||||
CONFIG_LEDS_GPIO=y
|
||||
# CONFIG_LEDS_MAX8997 is not set
|
||||
CONFIG_LEDS_PWM=y
|
||||
CONFIG_LEDS_TRIGGER_BACKLIGHT=y
|
||||
CONFIG_LEDS_TRIGGER_CAMERA=y
|
||||
CONFIG_LEDS_TRIGGER_CPU=y
|
||||
CONFIG_LEDS_TRIGGER_GPIO=y
|
||||
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
|
||||
CONFIG_LEDS_TRIGGER_ONESHOT=y
|
||||
CONFIG_LEDS_TRIGGER_TRANSIENT=y
|
||||
CONFIG_LEGACY_PTYS=y
|
||||
CONFIG_LEGACY_PTY_COUNT=256
|
||||
CONFIG_LIBFDT=y
|
||||
CONFIG_LOCALVERSION_AUTO=y
|
||||
CONFIG_LOCKUP_DETECTOR=y
|
||||
CONFIG_LOCK_SPIN_ON_OWNER=y
|
||||
CONFIG_LS_SCFG_MSI=y
|
||||
CONFIG_LS_SOC_DRIVERS=y
|
||||
CONFIG_LZO_COMPRESS=y
|
||||
CONFIG_LZO_DECOMPRESS=y
|
||||
CONFIG_MACVLAN=y
|
||||
CONFIG_MACVTAP=y
|
||||
CONFIG_MAGIC_SYSRQ=y
|
||||
CONFIG_MAILBOX=y
|
||||
# CONFIG_MAILBOX_TEST is not set
|
||||
CONFIG_MANDATORY_FILE_LOCKING=y
|
||||
CONFIG_MARVELL_PHY=y
|
||||
CONFIG_MCPM=y
|
||||
CONFIG_MDIO_BITBANG=y
|
||||
CONFIG_MDIO_BOARDINFO=y
|
||||
# CONFIG_MDIO_FSL_BACKPLANE is not set
|
||||
# CONFIG_MDIO_GPIO is not set
|
||||
CONFIG_MEMCG=y
|
||||
# CONFIG_MEMCG_SWAP is not set
|
||||
CONFIG_MEMORY=y
|
||||
CONFIG_MEMORY_ISOLATION=y
|
||||
CONFIG_MFD_ACT8945A=y
|
||||
CONFIG_MFD_AS3711=y
|
||||
CONFIG_MFD_AS3722=y
|
||||
CONFIG_MFD_ATMEL_FLEXCOM=y
|
||||
CONFIG_MFD_AXP20X=y
|
||||
CONFIG_MFD_AXP20X_I2C=y
|
||||
CONFIG_MFD_BCM590XX=y
|
||||
CONFIG_MFD_CORE=y
|
||||
CONFIG_MFD_MAX14577=y
|
||||
CONFIG_MFD_MAX77686=y
|
||||
CONFIG_MFD_MAX8907=y
|
||||
CONFIG_MFD_MAX8997=y
|
||||
CONFIG_MFD_MAX8998=y
|
||||
CONFIG_MFD_PALMAS=y
|
||||
CONFIG_MFD_RK808=y
|
||||
CONFIG_MFD_SEC_CORE=y
|
||||
CONFIG_MFD_STMPE=y
|
||||
CONFIG_MFD_SYSCON=y
|
||||
CONFIG_MFD_TPS65090=y
|
||||
CONFIG_MFD_TPS65217=y
|
||||
CONFIG_MFD_TPS65218=y
|
||||
CONFIG_MFD_TPS6586X=y
|
||||
CONFIG_MFD_TPS65910=y
|
||||
# CONFIG_MFD_TWL4030_AUDIO is not set
|
||||
CONFIG_MFD_VEXPRESS_SYSREG=y
|
||||
CONFIG_MICREL_PHY=y
|
||||
CONFIG_MIGHT_HAVE_CACHE_L2X0=y
|
||||
CONFIG_MIGHT_HAVE_PCI=y
|
||||
CONFIG_MIGRATION=y
|
||||
CONFIG_MMC=y
|
||||
CONFIG_MMC_BLOCK=y
|
||||
CONFIG_MMC_BLOCK_MINORS=16
|
||||
# CONFIG_MMC_MXC is not set
|
||||
CONFIG_MMC_SDHCI=y
|
||||
# CONFIG_MMC_SDHCI_ESDHC_IMX is not set
|
||||
CONFIG_MMC_SDHCI_IO_ACCESSORS=y
|
||||
CONFIG_MMC_SDHCI_OF_ESDHC=y
|
||||
# CONFIG_MMC_SDHCI_PCI is not set
|
||||
CONFIG_MMC_SDHCI_PLTFM=y
|
||||
# CONFIG_MMC_TIFM_SD is not set
|
||||
CONFIG_MMU_NOTIFIER=y
|
||||
CONFIG_MODULES_TREE_LOOKUP=y
|
||||
CONFIG_MODULES_USE_ELF_REL=y
|
||||
CONFIG_MSDOS_FS=y
|
||||
CONFIG_MTD_CFI_ADV_OPTIONS=y
|
||||
CONFIG_MTD_CFI_GEOMETRY=y
|
||||
CONFIG_MTD_CFI_STAA=y
|
||||
CONFIG_MTD_CMDLINE_PARTS=y
|
||||
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
|
||||
CONFIG_MTD_DATAFLASH=y
|
||||
# CONFIG_MTD_DATAFLASH_OTP is not set
|
||||
# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set
|
||||
CONFIG_MTD_M25P80=y
|
||||
CONFIG_MTD_NAND=y
|
||||
CONFIG_MTD_NAND_BRCMNAND=y
|
||||
CONFIG_MTD_NAND_DENALI=y
|
||||
CONFIG_MTD_NAND_DENALI_DT=y
|
||||
CONFIG_MTD_NAND_ECC=y
|
||||
CONFIG_MTD_NAND_FSL_IFC=y
|
||||
CONFIG_MTD_SPI_NOR=y
|
||||
CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y
|
||||
CONFIG_MTD_SST25L=y
|
||||
CONFIG_MTD_UBI=y
|
||||
CONFIG_MTD_UBI_BEB_LIMIT=20
|
||||
# CONFIG_MTD_UBI_BLOCK is not set
|
||||
# CONFIG_MTD_UBI_FASTMAP is not set
|
||||
# CONFIG_MTD_UBI_GLUEBI is not set
|
||||
CONFIG_MTD_UBI_WL_THRESHOLD=4096
|
||||
CONFIG_MULTI_IRQ_HANDLER=y
|
||||
CONFIG_MUTEX_SPIN_ON_OWNER=y
|
||||
CONFIG_MX3_IPU=y
|
||||
CONFIG_MX3_IPU_IRQS=4
|
||||
CONFIG_NAMESPACES=y
|
||||
CONFIG_NATIONAL_PHY=y
|
||||
CONFIG_NEED_DMA_MAP_STATE=y
|
||||
CONFIG_NEON=y
|
||||
# CONFIG_NET_CLS_CGROUP is not set
|
||||
CONFIG_NET_FLOW_LIMIT=y
|
||||
CONFIG_NET_NS=y
|
||||
CONFIG_NET_PTP_CLASSIFY=y
|
||||
CONFIG_NET_SWITCHDEV=y
|
||||
CONFIG_NLS=y
|
||||
CONFIG_NLS_CODEPAGE_437=y
|
||||
CONFIG_NLS_ISO8859_1=y
|
||||
CONFIG_NLS_UTF8=y
|
||||
CONFIG_NO_BOOTMEM=y
|
||||
CONFIG_NO_HZ=y
|
||||
CONFIG_NO_HZ_COMMON=y
|
||||
CONFIG_NO_HZ_IDLE=y
|
||||
CONFIG_NR_CPUS=16
|
||||
CONFIG_NTFS_FS=y
|
||||
CONFIG_NVMEM=y
|
||||
CONFIG_OF=y
|
||||
CONFIG_OF_ADDRESS=y
|
||||
CONFIG_OF_ADDRESS_PCI=y
|
||||
CONFIG_OF_DYNAMIC=y
|
||||
CONFIG_OF_EARLY_FLATTREE=y
|
||||
CONFIG_OF_FLATTREE=y
|
||||
CONFIG_OF_GPIO=y
|
||||
CONFIG_OF_IRQ=y
|
||||
CONFIG_OF_MDIO=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_OUTER_CACHE=y
|
||||
CONFIG_OUTER_CACHE_SYNC=y
|
||||
CONFIG_PACKET_DIAG=y
|
||||
CONFIG_PAGE_COUNTER=y
|
||||
CONFIG_PAGE_OFFSET=0xC0000000
|
||||
# CONFIG_PANIC_ON_OOPS is not set
|
||||
CONFIG_PANIC_ON_OOPS_VALUE=0
|
||||
CONFIG_PANIC_TIMEOUT=0
|
||||
CONFIG_PCI=y
|
||||
CONFIG_PCIEAER=y
|
||||
CONFIG_PCIEASPM=y
|
||||
# CONFIG_PCIEASPM_DEBUG is not set
|
||||
CONFIG_PCIEASPM_DEFAULT=y
|
||||
# CONFIG_PCIEASPM_PERFORMANCE is not set
|
||||
# CONFIG_PCIEASPM_POWERSAVE is not set
|
||||
CONFIG_PCIEPORTBUS=y
|
||||
CONFIG_PCIE_DW=y
|
||||
CONFIG_PCIE_PME=y
|
||||
CONFIG_PCI_BUS_ADDR_T_64BIT=y
|
||||
CONFIG_PCI_DOMAINS=y
|
||||
CONFIG_PCI_DOMAINS_GENERIC=y
|
||||
CONFIG_PCI_ECAM=y
|
||||
CONFIG_PCI_HOST_COMMON=y
|
||||
CONFIG_PCI_HOST_GENERIC=y
|
||||
CONFIG_PCI_LAYERSCAPE=y
|
||||
CONFIG_PCI_MSI=y
|
||||
CONFIG_PCI_MSI_IRQ_DOMAIN=y
|
||||
CONFIG_PERF_EVENTS=y
|
||||
CONFIG_PERF_USE_VMALLOC=y
|
||||
CONFIG_PGTABLE_LEVELS=3
|
||||
CONFIG_PHYLIB=y
|
||||
CONFIG_PHYS_ADDR_T_64BIT=y
|
||||
CONFIG_PID_NS=y
|
||||
CONFIG_PINCTRL=y
|
||||
CONFIG_PINCTRL_AS3722=y
|
||||
CONFIG_PINCTRL_PALMAS=y
|
||||
CONFIG_PL310_ERRATA_588369=y
|
||||
CONFIG_PL310_ERRATA_727915=y
|
||||
CONFIG_PL310_ERRATA_753970=y
|
||||
CONFIG_PL310_ERRATA_769419=y
|
||||
CONFIG_PM=y
|
||||
CONFIG_PM_CLK=y
|
||||
# CONFIG_PM_DEBUG is not set
|
||||
CONFIG_PM_DEVFREQ=y
|
||||
# CONFIG_PM_DEVFREQ_EVENT is not set
|
||||
CONFIG_PM_OPP=y
|
||||
CONFIG_PM_SLEEP=y
|
||||
CONFIG_PM_SLEEP_SMP=y
|
||||
CONFIG_POSIX_MQUEUE=y
|
||||
CONFIG_POSIX_MQUEUE_SYSCTL=y
|
||||
CONFIG_POWER_RESET=y
|
||||
CONFIG_POWER_RESET_AS3722=y
|
||||
CONFIG_POWER_RESET_BRCMKONA=y
|
||||
CONFIG_POWER_RESET_BRCMSTB=y
|
||||
CONFIG_POWER_RESET_GPIO=y
|
||||
CONFIG_POWER_RESET_GPIO_RESTART=y
|
||||
CONFIG_POWER_RESET_SYSCON=y
|
||||
CONFIG_POWER_RESET_SYSCON_POWEROFF=y
|
||||
CONFIG_POWER_RESET_VEXPRESS=y
|
||||
CONFIG_POWER_SUPPLY=y
|
||||
CONFIG_PPS=y
|
||||
CONFIG_PREEMPT_NOTIFIERS=y
|
||||
CONFIG_PRINTK_TIME=y
|
||||
# CONFIG_PROBE_EVENTS is not set
|
||||
CONFIG_PROC_CHILDREN=y
|
||||
CONFIG_PROC_PAGE_MONITOR=y
|
||||
CONFIG_PROC_PID_CPUSET=y
|
||||
CONFIG_PSTORE=y
|
||||
CONFIG_PSTORE_CONSOLE=y
|
||||
# CONFIG_PSTORE_LZ4_COMPRESS is not set
|
||||
# CONFIG_PSTORE_LZO_COMPRESS is not set
|
||||
CONFIG_PSTORE_PMSG=y
|
||||
CONFIG_PSTORE_RAM=y
|
||||
CONFIG_PSTORE_ZLIB_COMPRESS=y
|
||||
CONFIG_PTP_1588_CLOCK=y
|
||||
CONFIG_PTP_1588_CLOCK_GIANFAR=y
|
||||
CONFIG_PWM=y
|
||||
# CONFIG_PWM_IMX is not set
|
||||
# CONFIG_PWM_STMPE is not set
|
||||
CONFIG_PWM_SYSFS=y
|
||||
# CONFIG_PWM_TWL is not set
|
||||
# CONFIG_PWM_TWL_LED is not set
|
||||
CONFIG_QORIQ_CPUFREQ=y
|
||||
# CONFIG_QUICC_ENGINE is not set
|
||||
CONFIG_RAS=y
|
||||
CONFIG_RATIONAL=y
|
||||
CONFIG_RCU_CPU_STALL_TIMEOUT=21
|
||||
# CONFIG_RCU_EXPERT is not set
|
||||
CONFIG_RCU_STALL_COMMON=y
|
||||
CONFIG_RD_BZIP2=y
|
||||
CONFIG_RD_GZIP=y
|
||||
CONFIG_RD_LZMA=y
|
||||
CONFIG_RD_LZO=y
|
||||
CONFIG_RD_XZ=y
|
||||
CONFIG_REALTEK_PHY=y
|
||||
CONFIG_REED_SOLOMON=y
|
||||
CONFIG_REED_SOLOMON_DEC8=y
|
||||
CONFIG_REED_SOLOMON_ENC8=y
|
||||
CONFIG_REGMAP=y
|
||||
CONFIG_REGMAP_I2C=y
|
||||
CONFIG_REGMAP_IRQ=y
|
||||
CONFIG_REGMAP_MMIO=y
|
||||
CONFIG_REGMAP_SPI=y
|
||||
CONFIG_REGULATOR=y
|
||||
CONFIG_REGULATOR_ACT8865=y
|
||||
CONFIG_REGULATOR_ACT8945A=y
|
||||
CONFIG_REGULATOR_ANATOP=y
|
||||
CONFIG_REGULATOR_AS3711=y
|
||||
CONFIG_REGULATOR_AS3722=y
|
||||
CONFIG_REGULATOR_AXP20X=y
|
||||
CONFIG_REGULATOR_BCM590XX=y
|
||||
CONFIG_REGULATOR_DA9210=y
|
||||
CONFIG_REGULATOR_FAN53555=y
|
||||
CONFIG_REGULATOR_FIXED_VOLTAGE=y
|
||||
CONFIG_REGULATOR_GPIO=y
|
||||
CONFIG_REGULATOR_LP872X=y
|
||||
# CONFIG_REGULATOR_MAX14577 is not set
|
||||
CONFIG_REGULATOR_MAX77686=y
|
||||
# CONFIG_REGULATOR_MAX77802 is not set
|
||||
CONFIG_REGULATOR_MAX8907=y
|
||||
CONFIG_REGULATOR_MAX8973=y
|
||||
# CONFIG_REGULATOR_MAX8997 is not set
|
||||
# CONFIG_REGULATOR_MAX8998 is not set
|
||||
CONFIG_REGULATOR_PALMAS=y
|
||||
CONFIG_REGULATOR_PWM=y
|
||||
# CONFIG_REGULATOR_QCOM_SPMI is not set
|
||||
CONFIG_REGULATOR_RK808=y
|
||||
# CONFIG_REGULATOR_S2MPA01 is not set
|
||||
CONFIG_REGULATOR_S2MPS11=y
|
||||
CONFIG_REGULATOR_S5M8767=y
|
||||
CONFIG_REGULATOR_TPS51632=y
|
||||
CONFIG_REGULATOR_TPS62360=y
|
||||
CONFIG_REGULATOR_TPS65090=y
|
||||
CONFIG_REGULATOR_TPS65217=y
|
||||
CONFIG_REGULATOR_TPS65218=y
|
||||
CONFIG_REGULATOR_TPS6586X=y
|
||||
CONFIG_REGULATOR_TPS65910=y
|
||||
CONFIG_REGULATOR_TWL4030=y
|
||||
CONFIG_REGULATOR_VEXPRESS=y
|
||||
CONFIG_RESET_CONTROLLER=y
|
||||
CONFIG_RFS_ACCEL=y
|
||||
CONFIG_RPS=y
|
||||
CONFIG_RTC_CLASS=y
|
||||
CONFIG_RTC_DRV_AS3722=y
|
||||
# CONFIG_RTC_DRV_CMOS is not set
|
||||
CONFIG_RTC_DRV_DS1307=y
|
||||
CONFIG_RTC_DRV_DS1307_HWMON=y
|
||||
CONFIG_RTC_DRV_DS3232=y
|
||||
# CONFIG_RTC_DRV_EFI is not set
|
||||
CONFIG_RTC_DRV_EM3027=y
|
||||
# CONFIG_RTC_DRV_IMXDI is not set
|
||||
CONFIG_RTC_DRV_MAX77686=y
|
||||
CONFIG_RTC_DRV_MAX8907=y
|
||||
# CONFIG_RTC_DRV_MAX8997 is not set
|
||||
# CONFIG_RTC_DRV_MAX8998 is not set
|
||||
# CONFIG_RTC_DRV_MXC is not set
|
||||
CONFIG_RTC_DRV_PALMAS=y
|
||||
CONFIG_RTC_DRV_PCF2127=y
|
||||
CONFIG_RTC_DRV_PCF85263=y
|
||||
# CONFIG_RTC_DRV_RK808 is not set
|
||||
# CONFIG_RTC_DRV_S5M is not set
|
||||
CONFIG_RTC_DRV_TPS6586X=y
|
||||
CONFIG_RTC_DRV_TPS65910=y
|
||||
CONFIG_RTC_DRV_TWL4030=y
|
||||
CONFIG_RTC_I2C_AND_SPI=y
|
||||
# CONFIG_RT_GROUP_SCHED is not set
|
||||
CONFIG_RWSEM_SPIN_ON_OWNER=y
|
||||
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
|
||||
CONFIG_SATA_AHCI=y
|
||||
CONFIG_SATA_AHCI_PLATFORM=y
|
||||
CONFIG_SATA_PMP=y
|
||||
CONFIG_SATA_SIL24=y
|
||||
CONFIG_SCHED_DEBUG=y
|
||||
# CONFIG_SCHED_INFO is not set
|
||||
CONFIG_SCSI=y
|
||||
CONFIG_SECCOMP=y
|
||||
CONFIG_SECCOMP_FILTER=y
|
||||
# CONFIG_SECURITY_DMESG_RESTRICT is not set
|
||||
CONFIG_SENSORS_IIO_HWMON=y
|
||||
CONFIG_SENSORS_ISL29018=y
|
||||
CONFIG_SENSORS_ISL29028=y
|
||||
CONFIG_SENSORS_LM90=y
|
||||
CONFIG_SENSORS_LM95245=y
|
||||
CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y
|
||||
CONFIG_SERIAL_8250_DW=y
|
||||
CONFIG_SERIAL_8250_EM=y
|
||||
CONFIG_SERIAL_8250_FSL=y
|
||||
CONFIG_SERIAL_8250_NR_UARTS=4
|
||||
CONFIG_SERIAL_8250_PCI=y
|
||||
CONFIG_SERIAL_8250_RUNTIME_UARTS=4
|
||||
CONFIG_SERIAL_BCM63XX=y
|
||||
CONFIG_SERIAL_BCM63XX_CONSOLE=y
|
||||
CONFIG_SERIAL_CONEXANT_DIGICOLOR=y
|
||||
CONFIG_SERIAL_CONEXANT_DIGICOLOR_CONSOLE=y
|
||||
CONFIG_SERIAL_FSL_LPUART=y
|
||||
CONFIG_SERIAL_FSL_LPUART_CONSOLE=y
|
||||
CONFIG_SERIAL_IMX=y
|
||||
CONFIG_SERIAL_IMX_CONSOLE=y
|
||||
CONFIG_SERIAL_MCTRL_GPIO=y
|
||||
CONFIG_SERIAL_OF_PLATFORM=y
|
||||
CONFIG_SERIAL_ST_ASC=y
|
||||
CONFIG_SERIAL_ST_ASC_CONSOLE=y
|
||||
CONFIG_SERIAL_XILINX_PS_UART=y
|
||||
CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y
|
||||
CONFIG_SG_POOL=y
|
||||
CONFIG_SLUB_DEBUG=y
|
||||
CONFIG_SMP=y
|
||||
CONFIG_SMP_ON_UP=y
|
||||
CONFIG_SMSC_PHY=y
|
||||
CONFIG_SOCK_DIAG=y
|
||||
CONFIG_SOC_BRCMSTB=y
|
||||
CONFIG_SOC_BUS=y
|
||||
# CONFIG_SOC_IMX50 is not set
|
||||
# CONFIG_SOC_IMX51 is not set
|
||||
# CONFIG_SOC_IMX53 is not set
|
||||
# CONFIG_SOC_IMX6Q is not set
|
||||
# CONFIG_SOC_IMX6SL is not set
|
||||
# CONFIG_SOC_IMX6SX is not set
|
||||
# CONFIG_SOC_IMX6UL is not set
|
||||
# CONFIG_SOC_IMX7D is not set
|
||||
CONFIG_SOC_LS1021A=y
|
||||
# CONFIG_SOC_VF610 is not set
|
||||
CONFIG_SPARSE_IRQ=y
|
||||
CONFIG_SPI=y
|
||||
CONFIG_SPI_BITBANG=y
|
||||
CONFIG_SPI_CADENCE=y
|
||||
# CONFIG_SPI_FSL_QUADSPI is not set
|
||||
# CONFIG_SPI_IMX is not set
|
||||
CONFIG_SPI_MASTER=y
|
||||
CONFIG_SPI_SPIDEV=y
|
||||
CONFIG_SPI_XILINX=y
|
||||
CONFIG_SPMI=y
|
||||
# CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU is not set
|
||||
CONFIG_SQUASHFS_DECOMP_SINGLE=y
|
||||
CONFIG_SQUASHFS_FILE_CACHE=y
|
||||
# CONFIG_SQUASHFS_FILE_DIRECT is not set
|
||||
CONFIG_SQUASHFS_LZO=y
|
||||
CONFIG_SQUASHFS_ZLIB=y
|
||||
CONFIG_SRAM=y
|
||||
CONFIG_SRCU=y
|
||||
CONFIG_STAGING_BOARD=y
|
||||
CONFIG_STMPE_I2C=y
|
||||
# CONFIG_STMPE_SPI is not set
|
||||
# CONFIG_STRIP_ASM_SYMS is not set
|
||||
CONFIG_SUSPEND=y
|
||||
CONFIG_SUSPEND_FREEZER=y
|
||||
CONFIG_SWIOTLB=y
|
||||
CONFIG_SWPHY=y
|
||||
CONFIG_SWP_EMULATE=y
|
||||
# CONFIG_SW_SYNC is not set
|
||||
CONFIG_SYNC_FILE=y
|
||||
# CONFIG_SYN_COOKIES is not set
|
||||
CONFIG_SYSFS_SYSCALL=y
|
||||
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
|
||||
CONFIG_SYS_SUPPORTS_HUGETLBFS=y
|
||||
# CONFIG_TCP_CONG_ADVANCED is not set
|
||||
CONFIG_THERMAL=y
|
||||
CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
|
||||
CONFIG_THERMAL_GOV_STEP_WISE=y
|
||||
CONFIG_THERMAL_HWMON=y
|
||||
CONFIG_THERMAL_OF=y
|
||||
# CONFIG_THUMB2_KERNEL is not set
|
||||
CONFIG_TICK_CPU_ACCOUNTING=y
|
||||
CONFIG_TMPFS_POSIX_ACL=y
|
||||
CONFIG_TRACING_EVENTS_GPIO=y
|
||||
CONFIG_TREE_RCU=y
|
||||
CONFIG_TUN=y
|
||||
CONFIG_TWL4030_CORE=y
|
||||
CONFIG_TWL4030_POWER=y
|
||||
# CONFIG_TWL4030_WATCHDOG is not set
|
||||
CONFIG_UBIFS_FS=y
|
||||
# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set
|
||||
CONFIG_UBIFS_FS_LZO=y
|
||||
CONFIG_UBIFS_FS_ZLIB=y
|
||||
CONFIG_UCS2_STRING=y
|
||||
CONFIG_UEVENT_HELPER_PATH=""
|
||||
CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
|
||||
CONFIG_UNIX_DIAG=y
|
||||
CONFIG_USB_SUPPORT=y
|
||||
CONFIG_USER_NS=y
|
||||
CONFIG_USE_OF=y
|
||||
CONFIG_UTS_NS=y
|
||||
CONFIG_VDSO=y
|
||||
CONFIG_VECTORS_BASE=0xffff0000
|
||||
CONFIG_VETH=y
|
||||
CONFIG_VEXPRESS_CONFIG=y
|
||||
CONFIG_VEXPRESS_SYSCFG=y
|
||||
CONFIG_VFAT_FS=y
|
||||
CONFIG_VFP=y
|
||||
CONFIG_VFPv3=y
|
||||
CONFIG_VHOST=y
|
||||
CONFIG_VHOST_NET=y
|
||||
CONFIG_VIRTIO=y
|
||||
CONFIG_VIRTIO_BLK=y
|
||||
CONFIG_VIRTIO_CONSOLE=y
|
||||
CONFIG_VIRTIO_MMIO=y
|
||||
# CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES is not set
|
||||
CONFIG_VIRTIO_NET=y
|
||||
CONFIG_VIRTIO_PCI=y
|
||||
CONFIG_VIRTIO_PCI_LEGACY=y
|
||||
CONFIG_VIRTUALIZATION=y
|
||||
CONFIG_VITESSE_PHY=y
|
||||
CONFIG_VM_EVENT_COUNTERS=y
|
||||
CONFIG_VT=y
|
||||
CONFIG_VT_CONSOLE=y
|
||||
CONFIG_VT_CONSOLE_SLEEP=y
|
||||
CONFIG_VT_HW_CONSOLE_BINDING=y
|
||||
CONFIG_WATCHDOG_CORE=y
|
||||
# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set
|
||||
CONFIG_XFRM_ALGO=y
|
||||
CONFIG_XFRM_USER=y
|
||||
CONFIG_XILINX_WATCHDOG=y
|
||||
CONFIG_XPS=y
|
||||
CONFIG_XZ_DEC_ARM=y
|
||||
CONFIG_XZ_DEC_ARMTHUMB=y
|
||||
CONFIG_XZ_DEC_BCJ=y
|
||||
CONFIG_XZ_DEC_IA64=y
|
||||
CONFIG_XZ_DEC_POWERPC=y
|
||||
CONFIG_XZ_DEC_SPARC=y
|
||||
CONFIG_XZ_DEC_X86=y
|
||||
CONFIG_ZBOOT_ROM_BSS=0
|
||||
CONFIG_ZBOOT_ROM_TEXT=0
|
||||
CONFIG_ZLIB_DEFLATE=y
|
||||
CONFIG_ZLIB_INFLATE=y
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,374 +0,0 @@
|
||||
From 0774b97305507af18f8c43efb69aa00e6c57ae90 Mon Sep 17 00:00:00 2001
|
||||
From: Yangbo Lu <yangbo.lu@nxp.com>
|
||||
Date: Fri, 6 Jul 2018 15:31:14 +0800
|
||||
Subject: [PATCH] config: support layerscape
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This is an integrated patch for layerscape config/makefile support.
|
||||
|
||||
Signed-off-by: Yuantian Tang <andy.tang@nxp.com>
|
||||
Signed-off-by: Zhang Ying-22455 <ying.zhang22455@nxp.com>
|
||||
Signed-off-by: Zhao Qiang <qiang.zhao@nxp.com>
|
||||
Signed-off-by: Bogdan Purcareata <bogdan.purcareata@nxp.com>
|
||||
Signed-off-by: Zhao Qiang <qiang.zhao@nxp.com>
|
||||
Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
|
||||
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
|
||||
---
|
||||
arch/arm/mach-imx/Kconfig | 1 +
|
||||
drivers/base/Kconfig | 1 +
|
||||
drivers/crypto/Makefile | 2 +-
|
||||
drivers/net/ethernet/freescale/Kconfig | 4 +-
|
||||
drivers/net/ethernet/freescale/Makefile | 2 +
|
||||
drivers/ptp/Kconfig | 29 +++++++++++
|
||||
drivers/rtc/Kconfig | 8 +++
|
||||
drivers/rtc/Makefile | 1 +
|
||||
drivers/soc/Kconfig | 3 +-
|
||||
drivers/soc/fsl/Kconfig | 30 ++++++++++++
|
||||
drivers/soc/fsl/Kconfig.arm | 16 ++++++
|
||||
drivers/soc/fsl/Makefile | 5 ++
|
||||
drivers/soc/fsl/layerscape/Kconfig | 10 ++++
|
||||
drivers/soc/fsl/layerscape/Makefile | 1 +
|
||||
drivers/staging/Kconfig | 6 +++
|
||||
drivers/staging/Makefile | 3 ++
|
||||
drivers/staging/fsl-dpaa2/Kconfig | 65 +++++++++++++++++++++++++
|
||||
drivers/staging/fsl-dpaa2/Makefile | 9 ++++
|
||||
18 files changed, 192 insertions(+), 4 deletions(-)
|
||||
create mode 100644 drivers/soc/fsl/Kconfig
|
||||
create mode 100644 drivers/soc/fsl/Kconfig.arm
|
||||
create mode 100644 drivers/soc/fsl/layerscape/Kconfig
|
||||
create mode 100644 drivers/soc/fsl/layerscape/Makefile
|
||||
create mode 100644 drivers/staging/fsl-dpaa2/Kconfig
|
||||
create mode 100644 drivers/staging/fsl-dpaa2/Makefile
|
||||
|
||||
--- a/arch/arm/mach-imx/Kconfig
|
||||
+++ b/arch/arm/mach-imx/Kconfig
|
||||
@@ -1,6 +1,7 @@
|
||||
menuconfig ARCH_MXC
|
||||
bool "Freescale i.MX family"
|
||||
depends on ARCH_MULTI_V4_V5 || ARCH_MULTI_V6_V7 || ARM_SINGLE_ARMV7M
|
||||
+ select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE
|
||||
select ARCH_SUPPORTS_BIG_ENDIAN
|
||||
select CLKSRC_IMX_GPT
|
||||
select GENERIC_IRQ_CHIP
|
||||
--- a/drivers/base/Kconfig
|
||||
+++ b/drivers/base/Kconfig
|
||||
@@ -240,6 +240,7 @@ config GENERIC_CPU_VULNERABILITIES
|
||||
|
||||
config SOC_BUS
|
||||
bool
|
||||
+ select GLOB
|
||||
|
||||
source "drivers/base/regmap/Kconfig"
|
||||
|
||||
--- a/drivers/crypto/Makefile
|
||||
+++ b/drivers/crypto/Makefile
|
||||
@@ -3,7 +3,7 @@ obj-$(CONFIG_CRYPTO_DEV_ATMEL_SHA) += at
|
||||
obj-$(CONFIG_CRYPTO_DEV_ATMEL_TDES) += atmel-tdes.o
|
||||
obj-$(CONFIG_CRYPTO_DEV_BFIN_CRC) += bfin_crc.o
|
||||
obj-$(CONFIG_CRYPTO_DEV_CCP) += ccp/
|
||||
-obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM) += caam/
|
||||
+obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_COMMON) += caam/
|
||||
obj-$(CONFIG_CRYPTO_DEV_GEODE) += geode-aes.o
|
||||
obj-$(CONFIG_CRYPTO_DEV_HIFN_795X) += hifn_795x.o
|
||||
obj-$(CONFIG_CRYPTO_DEV_IMGTEC_HASH) += img-hash.o
|
||||
--- a/drivers/net/ethernet/freescale/Kconfig
|
||||
+++ b/drivers/net/ethernet/freescale/Kconfig
|
||||
@@ -5,7 +5,7 @@
|
||||
config NET_VENDOR_FREESCALE
|
||||
bool "Freescale devices"
|
||||
default y
|
||||
- depends on FSL_SOC || QUICC_ENGINE || CPM1 || CPM2 || PPC_MPC512x || \
|
||||
+ depends on FSL_SOC || (QUICC_ENGINE && PPC32) || CPM1 || CPM2 || PPC_MPC512x || \
|
||||
M523x || M527x || M5272 || M528x || M520x || M532x || \
|
||||
ARCH_MXC || ARCH_MXS || (PPC_MPC52xx && PPC_BESTCOMM) || \
|
||||
ARCH_LAYERSCAPE
|
||||
@@ -93,4 +93,6 @@ config GIANFAR
|
||||
and MPC86xx family of chips, the eTSEC on LS1021A and the FEC
|
||||
on the 8540.
|
||||
|
||||
+source "drivers/net/ethernet/freescale/sdk_fman/Kconfig"
|
||||
+source "drivers/net/ethernet/freescale/sdk_dpaa/Kconfig"
|
||||
endif # NET_VENDOR_FREESCALE
|
||||
--- a/drivers/net/ethernet/freescale/Makefile
|
||||
+++ b/drivers/net/ethernet/freescale/Makefile
|
||||
@@ -21,4 +21,6 @@ gianfar_driver-objs := gianfar.o \
|
||||
obj-$(CONFIG_UCC_GETH) += ucc_geth_driver.o
|
||||
ucc_geth_driver-objs := ucc_geth.o ucc_geth_ethtool.o
|
||||
|
||||
+obj-$(if $(CONFIG_FSL_SDK_FMAN),y) += sdk_fman/
|
||||
+obj-$(if $(CONFIG_FSL_SDK_DPAA_ETH),y) += sdk_dpaa/
|
||||
obj-$(CONFIG_FSL_FMAN) += fman/
|
||||
--- a/drivers/ptp/Kconfig
|
||||
+++ b/drivers/ptp/Kconfig
|
||||
@@ -39,6 +39,35 @@ config PTP_1588_CLOCK_GIANFAR
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called gianfar_ptp.
|
||||
|
||||
+config PTP_1588_CLOCK_DPAA
|
||||
+ tristate "Freescale DPAA as PTP clock"
|
||||
+ depends on FSL_SDK_DPAA_ETH
|
||||
+ select PTP_1588_CLOCK
|
||||
+ select FSL_DPAA_TS
|
||||
+ default n
|
||||
+ help
|
||||
+ This driver adds support for using the DPAA 1588 timer module
|
||||
+ as a PTP clock. This clock is only useful if your PTP programs are
|
||||
+ getting hardware time stamps on the PTP Ethernet packets
|
||||
+ using the SO_TIMESTAMPING API.
|
||||
+
|
||||
+ To compile this driver as a module, choose M here: the module
|
||||
+ will be called dpaa_ptp.
|
||||
+
|
||||
+config PTP_1588_CLOCK_DPAA2
|
||||
+ tristate "Freescale DPAA2 as PTP clock"
|
||||
+ depends on FSL_DPAA2_ETH
|
||||
+ select PTP_1588_CLOCK
|
||||
+ default y
|
||||
+ help
|
||||
+ This driver adds support for using the DPAA2 1588 timer module
|
||||
+ as a PTP clock. This clock is only useful if your PTP programs are
|
||||
+ getting hardware time stamps on the PTP Ethernet packets
|
||||
+ using the SO_TIMESTAMPING API.
|
||||
+
|
||||
+ To compile this driver as a module, choose M here: the module
|
||||
+ will be called dpaa2-rtc.
|
||||
+
|
||||
config PTP_1588_CLOCK_IXP46X
|
||||
tristate "Intel IXP46x as PTP clock"
|
||||
depends on IXP4XX_ETH
|
||||
--- a/drivers/rtc/Kconfig
|
||||
+++ b/drivers/rtc/Kconfig
|
||||
@@ -414,6 +414,14 @@ config RTC_DRV_PCF85063
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called rtc-pcf85063.
|
||||
|
||||
+config RTC_DRV_PCF85263
|
||||
+ tristate "NXP PCF85263"
|
||||
+ help
|
||||
+ If you say yes here you get support for the PCF85263 RTC chip
|
||||
+
|
||||
+ This driver can also be built as a module. If so, the module
|
||||
+ will be called rtc-pcf85263.
|
||||
+
|
||||
config RTC_DRV_PCF8563
|
||||
tristate "Philips PCF8563/Epson RTC8564"
|
||||
help
|
||||
--- a/drivers/rtc/Makefile
|
||||
+++ b/drivers/rtc/Makefile
|
||||
@@ -111,6 +111,7 @@ obj-$(CONFIG_RTC_DRV_PCF2127) += rtc-pcf
|
||||
obj-$(CONFIG_RTC_DRV_PCF50633) += rtc-pcf50633.o
|
||||
obj-$(CONFIG_RTC_DRV_PCF85063) += rtc-pcf85063.o
|
||||
obj-$(CONFIG_RTC_DRV_PCF8523) += rtc-pcf8523.o
|
||||
+obj-$(CONFIG_RTC_DRV_PCF85263) += rtc-pcf85263.o
|
||||
obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o
|
||||
obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o
|
||||
obj-$(CONFIG_RTC_DRV_PIC32) += rtc-pic32.o
|
||||
--- a/drivers/soc/Kconfig
|
||||
+++ b/drivers/soc/Kconfig
|
||||
@@ -1,8 +1,7 @@
|
||||
menu "SOC (System On Chip) specific Drivers"
|
||||
|
||||
source "drivers/soc/bcm/Kconfig"
|
||||
-source "drivers/soc/fsl/qbman/Kconfig"
|
||||
-source "drivers/soc/fsl/qe/Kconfig"
|
||||
+source "drivers/soc/fsl/Kconfig"
|
||||
source "drivers/soc/mediatek/Kconfig"
|
||||
source "drivers/soc/qcom/Kconfig"
|
||||
source "drivers/soc/rockchip/Kconfig"
|
||||
--- /dev/null
|
||||
+++ b/drivers/soc/fsl/Kconfig
|
||||
@@ -0,0 +1,30 @@
|
||||
+#
|
||||
+# Freescale SOC drivers
|
||||
+#
|
||||
+
|
||||
+source "drivers/soc/fsl/qbman/Kconfig"
|
||||
+source "drivers/soc/fsl/qe/Kconfig"
|
||||
+source "drivers/soc/fsl/ls2-console/Kconfig"
|
||||
+
|
||||
+config FSL_GUTS
|
||||
+ bool
|
||||
+ select SOC_BUS
|
||||
+ help
|
||||
+ The global utilities block controls power management, I/O device
|
||||
+ enabling, power-onreset(POR) configuration monitoring, alternate
|
||||
+ function selection for multiplexed signals,and clock control.
|
||||
+ This driver is to manage and access global utilities block.
|
||||
+ Initially only reading SVR and registering soc device are supported.
|
||||
+ Other guts accesses, such as reading RCW, should eventually be moved
|
||||
+ into this driver as well.
|
||||
+
|
||||
+config FSL_SLEEP_FSM
|
||||
+ bool
|
||||
+ help
|
||||
+ This driver configures a hardware FSM (Finite State Machine) for deep sleep.
|
||||
+ The FSM is used to finish clean-ups at the last stage of system entering deep
|
||||
+ sleep, and also wakes up system when a wake up event happens.
|
||||
+
|
||||
+if ARM || ARM64
|
||||
+source "drivers/soc/fsl/Kconfig.arm"
|
||||
+endif
|
||||
--- /dev/null
|
||||
+++ b/drivers/soc/fsl/Kconfig.arm
|
||||
@@ -0,0 +1,16 @@
|
||||
+#
|
||||
+# Freescale ARM SOC Drivers
|
||||
+#
|
||||
+
|
||||
+config LS_SOC_DRIVERS
|
||||
+ bool "Layerscape Soc Drivers"
|
||||
+ depends on ARCH_LAYERSCAPE || SOC_LS1021A
|
||||
+ default n
|
||||
+ help
|
||||
+ Say y here to enable Freescale Layerscape Soc Device Drivers support.
|
||||
+ The Soc Drivers provides the device driver that is a specific block
|
||||
+ or feature on Layerscape platform.
|
||||
+
|
||||
+if LS_SOC_DRIVERS
|
||||
+ source "drivers/soc/fsl/layerscape/Kconfig"
|
||||
+endif
|
||||
--- a/drivers/soc/fsl/Makefile
|
||||
+++ b/drivers/soc/fsl/Makefile
|
||||
@@ -5,3 +5,8 @@
|
||||
obj-$(CONFIG_FSL_DPAA) += qbman/
|
||||
obj-$(CONFIG_QUICC_ENGINE) += qe/
|
||||
obj-$(CONFIG_CPM) += qe/
|
||||
+obj-$(CONFIG_FSL_GUTS) += guts.o
|
||||
+obj-$(CONFIG_FSL_LS2_CONSOLE) += ls2-console/
|
||||
+obj-$(CONFIG_SUSPEND) += rcpm.o
|
||||
+obj-$(CONFIG_LS_SOC_DRIVERS) += layerscape/
|
||||
+obj-$(CONFIG_FSL_SLEEP_FSM) += sleep_fsm.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/soc/fsl/layerscape/Kconfig
|
||||
@@ -0,0 +1,10 @@
|
||||
+#
|
||||
+# Layerscape Soc drivers
|
||||
+#
|
||||
+config FTM_ALARM
|
||||
+ bool "FTM alarm driver"
|
||||
+ default n
|
||||
+ help
|
||||
+ Say y here to enable FTM alarm support. The FTM alarm provides
|
||||
+ alarm functions for wakeup system from deep sleep. There is only
|
||||
+ one FTM can be used in ALARM(FTM 0).
|
||||
--- /dev/null
|
||||
+++ b/drivers/soc/fsl/layerscape/Makefile
|
||||
@@ -0,0 +1 @@
|
||||
+obj-$(CONFIG_FTM_ALARM) += ftm_alarm.o
|
||||
--- a/drivers/staging/Kconfig
|
||||
+++ b/drivers/staging/Kconfig
|
||||
@@ -94,6 +94,8 @@ source "drivers/staging/fbtft/Kconfig"
|
||||
|
||||
source "drivers/staging/fsl-mc/Kconfig"
|
||||
|
||||
+source "drivers/staging/fsl-dpaa2/Kconfig"
|
||||
+
|
||||
source "drivers/staging/wilc1000/Kconfig"
|
||||
|
||||
source "drivers/staging/most/Kconfig"
|
||||
@@ -106,4 +108,8 @@ source "drivers/staging/greybus/Kconfig"
|
||||
|
||||
source "drivers/staging/vc04_services/Kconfig"
|
||||
|
||||
+source "drivers/staging/fsl_qbman/Kconfig"
|
||||
+
|
||||
+source "drivers/staging/fsl_ppfe/Kconfig"
|
||||
+
|
||||
endif # STAGING
|
||||
--- a/drivers/staging/Makefile
|
||||
+++ b/drivers/staging/Makefile
|
||||
@@ -36,9 +36,12 @@ obj-$(CONFIG_UNISYSSPAR) += unisys/
|
||||
obj-$(CONFIG_COMMON_CLK_XLNX_CLKWZRD) += clocking-wizard/
|
||||
obj-$(CONFIG_FB_TFT) += fbtft/
|
||||
obj-$(CONFIG_FSL_MC_BUS) += fsl-mc/
|
||||
+obj-$(CONFIG_FSL_DPAA2) += fsl-dpaa2/
|
||||
obj-$(CONFIG_WILC1000) += wilc1000/
|
||||
obj-$(CONFIG_MOST) += most/
|
||||
obj-$(CONFIG_ISDN_I4L) += i4l/
|
||||
obj-$(CONFIG_KS7010) += ks7010/
|
||||
obj-$(CONFIG_GREYBUS) += greybus/
|
||||
obj-$(CONFIG_BCM2708_VCHIQ) += vc04_services/
|
||||
+obj-$(CONFIG_FSL_SDK_DPA) += fsl_qbman/
|
||||
+obj-$(CONFIG_FSL_PPFE) += fsl_ppfe/
|
||||
--- /dev/null
|
||||
+++ b/drivers/staging/fsl-dpaa2/Kconfig
|
||||
@@ -0,0 +1,65 @@
|
||||
+#
|
||||
+# Freescale DataPath Acceleration Architecture Gen2 (DPAA2) drivers
|
||||
+#
|
||||
+
|
||||
+config FSL_DPAA2
|
||||
+ bool "Freescale DPAA2 devices"
|
||||
+ depends on FSL_MC_BUS
|
||||
+ ---help---
|
||||
+ Build drivers for Freescale DataPath Acceleration
|
||||
+ Architecture (DPAA2) family of SoCs.
|
||||
+
|
||||
+config FSL_DPAA2_ETH
|
||||
+ tristate "Freescale DPAA2 Ethernet"
|
||||
+ depends on FSL_DPAA2 && FSL_MC_DPIO
|
||||
+ ---help---
|
||||
+ Ethernet driver for Freescale DPAA2 SoCs, using the
|
||||
+ Freescale MC bus driver
|
||||
+
|
||||
+if FSL_DPAA2_ETH
|
||||
+config FSL_DPAA2_ETH_USE_ERR_QUEUE
|
||||
+ bool "Enable Rx error queue"
|
||||
+ default n
|
||||
+ ---help---
|
||||
+ Allow Rx error frames to be enqueued on an error queue
|
||||
+ and processed by the driver (by default they are dropped
|
||||
+ in hardware).
|
||||
+ This may impact performance, recommended for debugging
|
||||
+ purposes only.
|
||||
+
|
||||
+# QBMAN_DEBUG requires some additional DPIO APIs
|
||||
+config FSL_DPAA2_ETH_DEBUGFS
|
||||
+ depends on DEBUG_FS
|
||||
+ bool "Enable debugfs support"
|
||||
+ default n
|
||||
+ ---help---
|
||||
+ Enable advanced statistics through debugfs interface.
|
||||
+
|
||||
+config FSL_DPAA2_ETH_DCB
|
||||
+ bool "Data Center Bridging (DCB) Support"
|
||||
+ default n
|
||||
+ depends on DCB
|
||||
+ ---help---
|
||||
+ Say Y here if you want to use Data Center Bridging (DCB) features
|
||||
+ (PFC) in the driver.
|
||||
+
|
||||
+ If unsure, say N.
|
||||
+
|
||||
+config FSL_DPAA2_ETH_CEETM
|
||||
+ depends on NET_SCHED
|
||||
+ bool "DPAA2 Ethernet CEETM QoS"
|
||||
+ default n
|
||||
+ ---help---
|
||||
+ Enable QoS offloading support through the CEETM hardware block.
|
||||
+endif
|
||||
+
|
||||
+source "drivers/staging/fsl-dpaa2/mac/Kconfig"
|
||||
+source "drivers/staging/fsl-dpaa2/evb/Kconfig"
|
||||
+
|
||||
+config FSL_DPAA2_ETHSW
|
||||
+ tristate "Freescale DPAA2 Ethernet Switch"
|
||||
+ depends on FSL_DPAA2
|
||||
+ depends on NET_SWITCHDEV
|
||||
+ ---help---
|
||||
+ Driver for Freescale DPAA2 Ethernet Switch. Select
|
||||
+ BRIDGE to have support for bridge tools.
|
||||
--- /dev/null
|
||||
+++ b/drivers/staging/fsl-dpaa2/Makefile
|
||||
@@ -0,0 +1,9 @@
|
||||
+#
|
||||
+# Freescale DataPath Acceleration Architecture Gen2 (DPAA2) drivers
|
||||
+#
|
||||
+
|
||||
+obj-$(CONFIG_FSL_DPAA2_ETH) += ethernet/
|
||||
+obj-$(CONFIG_FSL_DPAA2_MAC) += mac/
|
||||
+obj-$(CONFIG_FSL_DPAA2_EVB) += evb/
|
||||
+obj-$(CONFIG_PTP_1588_CLOCK_DPAA2) += rtc/
|
||||
+obj-$(CONFIG_FSL_DPAA2_ETHSW) += ethsw/
|
File diff suppressed because it is too large
Load Diff
@ -1,517 +0,0 @@
|
||||
From 2f2a0ab9e4b3186be981f7151a4f4f794d4b6caa Mon Sep 17 00:00:00 2001
|
||||
From: Yangbo Lu <yangbo.lu@nxp.com>
|
||||
Date: Thu, 5 Jul 2018 16:18:37 +0800
|
||||
Subject: [PATCH 03/32] arch: support layerscape
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This is an integrated patch for layerscape arch support.
|
||||
|
||||
Signed-off-by: Madalin Bucur <madalin.bucur@nxp.com>
|
||||
Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
|
||||
Signed-off-by: Zhao Qiang <B45475@freescale.com>
|
||||
Signed-off-by: Camelia Groza <camelia.groza@nxp.com>
|
||||
Signed-off-by: Haiying Wang <Haiying.wang@freescale.com>
|
||||
Signed-off-by: Pan Jiafei <Jiafei.Pan@nxp.com>
|
||||
Signed-off-by: Po Liu <po.liu@nxp.com>
|
||||
Signed-off-by: Bharat Bhushan <Bharat.Bhushan@nxp.com>
|
||||
Signed-off-by: Jianhua Xie <jianhua.xie@nxp.com>
|
||||
Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
|
||||
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
|
||||
---
|
||||
arch/arm/include/asm/delay.h | 16 +++++++
|
||||
arch/arm/include/asm/dma-mapping.h | 6 ---
|
||||
arch/arm/include/asm/io.h | 31 +++++++++++++
|
||||
arch/arm/include/asm/mach/map.h | 4 +-
|
||||
arch/arm/include/asm/pgtable.h | 7 +++
|
||||
arch/arm/kernel/bios32.c | 43 ++++++++++++++++++
|
||||
arch/arm/mm/dma-mapping.c | 1 +
|
||||
arch/arm/mm/ioremap.c | 7 +++
|
||||
arch/arm/mm/mmu.c | 9 ++++
|
||||
arch/arm64/include/asm/cache.h | 2 +-
|
||||
arch/arm64/include/asm/io.h | 30 +++++++++++++
|
||||
arch/arm64/include/asm/pci.h | 4 ++
|
||||
arch/arm64/include/asm/pgtable-prot.h | 2 +
|
||||
arch/arm64/include/asm/pgtable.h | 5 +++
|
||||
arch/arm64/kernel/pci.c | 62 ++++++++++++++++++++++++++
|
||||
arch/arm64/mm/dma-mapping.c | 6 +++
|
||||
arch/powerpc/include/asm/dma-mapping.h | 5 ---
|
||||
arch/tile/include/asm/dma-mapping.h | 5 ---
|
||||
18 files changed, 226 insertions(+), 19 deletions(-)
|
||||
|
||||
--- a/arch/arm/include/asm/delay.h
|
||||
+++ b/arch/arm/include/asm/delay.h
|
||||
@@ -57,6 +57,22 @@ extern void __bad_udelay(void);
|
||||
__const_udelay((n) * UDELAY_MULT)) : \
|
||||
__udelay(n))
|
||||
|
||||
+#define spin_event_timeout(condition, timeout, delay) \
|
||||
+({ \
|
||||
+ typeof(condition) __ret; \
|
||||
+ int i = 0; \
|
||||
+ while (!(__ret = (condition)) && (i++ < timeout)) { \
|
||||
+ if (delay) \
|
||||
+ udelay(delay); \
|
||||
+ else \
|
||||
+ cpu_relax(); \
|
||||
+ udelay(1); \
|
||||
+ } \
|
||||
+ if (!__ret) \
|
||||
+ __ret = (condition); \
|
||||
+ __ret; \
|
||||
+})
|
||||
+
|
||||
/* Loop-based definitions for assembly code. */
|
||||
extern void __loop_delay(unsigned long loops);
|
||||
extern void __loop_udelay(unsigned long usecs);
|
||||
--- a/arch/arm/include/asm/dma-mapping.h
|
||||
+++ b/arch/arm/include/asm/dma-mapping.h
|
||||
@@ -31,12 +31,6 @@ static inline struct dma_map_ops *get_dm
|
||||
return __generic_dma_ops(dev);
|
||||
}
|
||||
|
||||
-static inline void set_dma_ops(struct device *dev, struct dma_map_ops *ops)
|
||||
-{
|
||||
- BUG_ON(!dev);
|
||||
- dev->archdata.dma_ops = ops;
|
||||
-}
|
||||
-
|
||||
#define HAVE_ARCH_DMA_SUPPORTED 1
|
||||
extern int dma_supported(struct device *dev, u64 mask);
|
||||
|
||||
--- a/arch/arm/include/asm/io.h
|
||||
+++ b/arch/arm/include/asm/io.h
|
||||
@@ -129,6 +129,7 @@ static inline u32 __raw_readl(const vola
|
||||
#define MT_DEVICE_NONSHARED 1
|
||||
#define MT_DEVICE_CACHED 2
|
||||
#define MT_DEVICE_WC 3
|
||||
+#define MT_MEMORY_RW_NS 4
|
||||
/*
|
||||
* types 4 onwards can be found in asm/mach/map.h and are undefined
|
||||
* for ioremap
|
||||
@@ -220,6 +221,34 @@ extern int pci_ioremap_io(unsigned int o
|
||||
#endif
|
||||
#endif
|
||||
|
||||
+/* access ports */
|
||||
+#define setbits32(_addr, _v) iowrite32be(ioread32be(_addr) | (_v), (_addr))
|
||||
+#define clrbits32(_addr, _v) iowrite32be(ioread32be(_addr) & ~(_v), (_addr))
|
||||
+
|
||||
+#define setbits16(_addr, _v) iowrite16be(ioread16be(_addr) | (_v), (_addr))
|
||||
+#define clrbits16(_addr, _v) iowrite16be(ioread16be(_addr) & ~(_v), (_addr))
|
||||
+
|
||||
+#define setbits8(_addr, _v) iowrite8(ioread8(_addr) | (_v), (_addr))
|
||||
+#define clrbits8(_addr, _v) iowrite8(ioread8(_addr) & ~(_v), (_addr))
|
||||
+
|
||||
+/* Clear and set bits in one shot. These macros can be used to clear and
|
||||
+ * set multiple bits in a register using a single read-modify-write. These
|
||||
+ * macros can also be used to set a multiple-bit bit pattern using a mask,
|
||||
+ * by specifying the mask in the 'clear' parameter and the new bit pattern
|
||||
+ * in the 'set' parameter.
|
||||
+ */
|
||||
+
|
||||
+#define clrsetbits_be32(addr, clear, set) \
|
||||
+ iowrite32be((ioread32be(addr) & ~(clear)) | (set), (addr))
|
||||
+#define clrsetbits_le32(addr, clear, set) \
|
||||
+ iowrite32le((ioread32le(addr) & ~(clear)) | (set), (addr))
|
||||
+#define clrsetbits_be16(addr, clear, set) \
|
||||
+ iowrite16be((ioread16be(addr) & ~(clear)) | (set), (addr))
|
||||
+#define clrsetbits_le16(addr, clear, set) \
|
||||
+ iowrite16le((ioread16le(addr) & ~(clear)) | (set), (addr))
|
||||
+#define clrsetbits_8(addr, clear, set) \
|
||||
+ iowrite8((ioread8(addr) & ~(clear)) | (set), (addr))
|
||||
+
|
||||
/*
|
||||
* IO port access primitives
|
||||
* -------------------------
|
||||
@@ -408,6 +437,8 @@ void __iomem *ioremap_wc(resource_size_t
|
||||
#define ioremap_wc ioremap_wc
|
||||
#define ioremap_wt ioremap_wc
|
||||
|
||||
+void __iomem *ioremap_cache_ns(resource_size_t res_cookie, size_t size);
|
||||
+
|
||||
void iounmap(volatile void __iomem *iomem_cookie);
|
||||
#define iounmap iounmap
|
||||
|
||||
--- a/arch/arm/include/asm/mach/map.h
|
||||
+++ b/arch/arm/include/asm/mach/map.h
|
||||
@@ -21,9 +21,9 @@ struct map_desc {
|
||||
unsigned int type;
|
||||
};
|
||||
|
||||
-/* types 0-3 are defined in asm/io.h */
|
||||
+/* types 0-4 are defined in asm/io.h */
|
||||
enum {
|
||||
- MT_UNCACHED = 4,
|
||||
+ MT_UNCACHED = 5,
|
||||
MT_CACHECLEAN,
|
||||
MT_MINICLEAN,
|
||||
MT_LOW_VECTORS,
|
||||
--- a/arch/arm/include/asm/pgtable.h
|
||||
+++ b/arch/arm/include/asm/pgtable.h
|
||||
@@ -118,6 +118,13 @@ extern pgprot_t pgprot_s2_device;
|
||||
#define pgprot_noncached(prot) \
|
||||
__pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_UNCACHED)
|
||||
|
||||
+#define pgprot_cached(prot) \
|
||||
+ __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_DEV_CACHED)
|
||||
+
|
||||
+#define pgprot_cached_ns(prot) \
|
||||
+ __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_DEV_CACHED | \
|
||||
+ L_PTE_MT_DEV_NONSHARED)
|
||||
+
|
||||
#define pgprot_writecombine(prot) \
|
||||
__pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_BUFFERABLE)
|
||||
|
||||
--- a/arch/arm/kernel/bios32.c
|
||||
+++ b/arch/arm/kernel/bios32.c
|
||||
@@ -11,6 +11,8 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
+#include <linux/of_irq.h>
|
||||
+#include <linux/pcieport_if.h>
|
||||
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/map.h>
|
||||
@@ -64,6 +66,47 @@ void pcibios_report_status(u_int status_
|
||||
}
|
||||
|
||||
/*
|
||||
+ * Check device tree if the service interrupts are there
|
||||
+ */
|
||||
+int pcibios_check_service_irqs(struct pci_dev *dev, int *irqs, int mask)
|
||||
+{
|
||||
+ int ret, count = 0;
|
||||
+ struct device_node *np = NULL;
|
||||
+
|
||||
+ if (dev->bus->dev.of_node)
|
||||
+ np = dev->bus->dev.of_node;
|
||||
+
|
||||
+ if (np == NULL)
|
||||
+ return 0;
|
||||
+
|
||||
+ if (!IS_ENABLED(CONFIG_OF_IRQ))
|
||||
+ return 0;
|
||||
+
|
||||
+ /* If root port doesn't support MSI/MSI-X/INTx in RC mode,
|
||||
+ * request irq for aer
|
||||
+ */
|
||||
+ if (mask & PCIE_PORT_SERVICE_AER) {
|
||||
+ ret = of_irq_get_byname(np, "aer");
|
||||
+ if (ret > 0) {
|
||||
+ irqs[PCIE_PORT_SERVICE_AER_SHIFT] = ret;
|
||||
+ count++;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (mask & PCIE_PORT_SERVICE_PME) {
|
||||
+ ret = of_irq_get_byname(np, "pme");
|
||||
+ if (ret > 0) {
|
||||
+ irqs[PCIE_PORT_SERVICE_PME_SHIFT] = ret;
|
||||
+ count++;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* TODO: add more service interrupts if there it is in the device tree*/
|
||||
+
|
||||
+ return count;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
* We don't use this to fix the device, but initialisation of it.
|
||||
* It's not the correct use for this, but it works.
|
||||
* Note that the arbiter/ISA bridge appears to be buggy, specifically in
|
||||
--- a/arch/arm/mm/dma-mapping.c
|
||||
+++ b/arch/arm/mm/dma-mapping.c
|
||||
@@ -2410,6 +2410,7 @@ void arch_setup_dma_ops(struct device *d
|
||||
|
||||
set_dma_ops(dev, dma_ops);
|
||||
}
|
||||
+EXPORT_SYMBOL(arch_setup_dma_ops);
|
||||
|
||||
void arch_teardown_dma_ops(struct device *dev)
|
||||
{
|
||||
--- a/arch/arm/mm/ioremap.c
|
||||
+++ b/arch/arm/mm/ioremap.c
|
||||
@@ -398,6 +398,13 @@ void __iomem *ioremap_wc(resource_size_t
|
||||
}
|
||||
EXPORT_SYMBOL(ioremap_wc);
|
||||
|
||||
+void __iomem *ioremap_cache_ns(resource_size_t res_cookie, size_t size)
|
||||
+{
|
||||
+ return arch_ioremap_caller(res_cookie, size, MT_MEMORY_RW_NS,
|
||||
+ __builtin_return_address(0));
|
||||
+}
|
||||
+EXPORT_SYMBOL(ioremap_cache_ns);
|
||||
+
|
||||
/*
|
||||
* Remap an arbitrary physical address space into the kernel virtual
|
||||
* address space as memory. Needed when the kernel wants to execute
|
||||
--- a/arch/arm/mm/mmu.c
|
||||
+++ b/arch/arm/mm/mmu.c
|
||||
@@ -313,6 +313,13 @@ static struct mem_type mem_types[] __ro_
|
||||
.prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE,
|
||||
.domain = DOMAIN_KERNEL,
|
||||
},
|
||||
+ [MT_MEMORY_RW_NS] = {
|
||||
+ .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
|
||||
+ L_PTE_XN,
|
||||
+ .prot_l1 = PMD_TYPE_TABLE,
|
||||
+ .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_XN,
|
||||
+ .domain = DOMAIN_KERNEL,
|
||||
+ },
|
||||
[MT_ROM] = {
|
||||
.prot_sect = PMD_TYPE_SECT,
|
||||
.domain = DOMAIN_KERNEL,
|
||||
@@ -644,6 +651,7 @@ static void __init build_mem_type_table(
|
||||
}
|
||||
kern_pgprot |= PTE_EXT_AF;
|
||||
vecs_pgprot |= PTE_EXT_AF;
|
||||
+ mem_types[MT_MEMORY_RW_NS].prot_pte |= PTE_EXT_AF | cp->pte;
|
||||
|
||||
/*
|
||||
* Set PXN for user mappings
|
||||
@@ -672,6 +680,7 @@ static void __init build_mem_type_table(
|
||||
mem_types[MT_MEMORY_RWX].prot_pte |= kern_pgprot;
|
||||
mem_types[MT_MEMORY_RW].prot_sect |= ecc_mask | cp->pmd;
|
||||
mem_types[MT_MEMORY_RW].prot_pte |= kern_pgprot;
|
||||
+ mem_types[MT_MEMORY_RW_NS].prot_sect |= ecc_mask | cp->pmd;
|
||||
mem_types[MT_MEMORY_DMA_READY].prot_pte |= kern_pgprot;
|
||||
mem_types[MT_MEMORY_RWX_NONCACHED].prot_sect |= ecc_mask;
|
||||
mem_types[MT_ROM].prot_sect |= cp->pmd;
|
||||
--- a/arch/arm64/include/asm/cache.h
|
||||
+++ b/arch/arm64/include/asm/cache.h
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
#include <asm/cachetype.h>
|
||||
|
||||
-#define L1_CACHE_SHIFT 7
|
||||
+#define L1_CACHE_SHIFT 6
|
||||
#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
|
||||
|
||||
/*
|
||||
--- a/arch/arm64/include/asm/io.h
|
||||
+++ b/arch/arm64/include/asm/io.h
|
||||
@@ -171,6 +171,8 @@ extern void __iomem *ioremap_cache(phys_
|
||||
#define ioremap_nocache(addr, size) __ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))
|
||||
#define ioremap_wc(addr, size) __ioremap((addr), (size), __pgprot(PROT_NORMAL_NC))
|
||||
#define ioremap_wt(addr, size) __ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))
|
||||
+#define ioremap_cache_ns(addr, size) __ioremap((addr), (size), \
|
||||
+ __pgprot(PROT_NORMAL_NS))
|
||||
#define iounmap __iounmap
|
||||
|
||||
/*
|
||||
@@ -184,6 +186,34 @@ extern void __iomem *ioremap_cache(phys_
|
||||
#define iowrite32be(v,p) ({ __iowmb(); __raw_writel((__force __u32)cpu_to_be32(v), p); })
|
||||
#define iowrite64be(v,p) ({ __iowmb(); __raw_writeq((__force __u64)cpu_to_be64(v), p); })
|
||||
|
||||
+/* access ports */
|
||||
+#define setbits32(_addr, _v) iowrite32be(ioread32be(_addr) | (_v), (_addr))
|
||||
+#define clrbits32(_addr, _v) iowrite32be(ioread32be(_addr) & ~(_v), (_addr))
|
||||
+
|
||||
+#define setbits16(_addr, _v) iowrite16be(ioread16be(_addr) | (_v), (_addr))
|
||||
+#define clrbits16(_addr, _v) iowrite16be(ioread16be(_addr) & ~(_v), (_addr))
|
||||
+
|
||||
+#define setbits8(_addr, _v) iowrite8(ioread8(_addr) | (_v), (_addr))
|
||||
+#define clrbits8(_addr, _v) iowrite8(ioread8(_addr) & ~(_v), (_addr))
|
||||
+
|
||||
+/* Clear and set bits in one shot. These macros can be used to clear and
|
||||
+ * set multiple bits in a register using a single read-modify-write. These
|
||||
+ * macros can also be used to set a multiple-bit bit pattern using a mask,
|
||||
+ * by specifying the mask in the 'clear' parameter and the new bit pattern
|
||||
+ * in the 'set' parameter.
|
||||
+ */
|
||||
+
|
||||
+#define clrsetbits_be32(addr, clear, set) \
|
||||
+ iowrite32be((ioread32be(addr) & ~(clear)) | (set), (addr))
|
||||
+#define clrsetbits_le32(addr, clear, set) \
|
||||
+ iowrite32le((ioread32le(addr) & ~(clear)) | (set), (addr))
|
||||
+#define clrsetbits_be16(addr, clear, set) \
|
||||
+ iowrite16be((ioread16be(addr) & ~(clear)) | (set), (addr))
|
||||
+#define clrsetbits_le16(addr, clear, set) \
|
||||
+ iowrite16le((ioread16le(addr) & ~(clear)) | (set), (addr))
|
||||
+#define clrsetbits_8(addr, clear, set) \
|
||||
+ iowrite8((ioread8(addr) & ~(clear)) | (set), (addr))
|
||||
+
|
||||
#include <asm-generic/io.h>
|
||||
|
||||
/*
|
||||
--- a/arch/arm64/include/asm/pci.h
|
||||
+++ b/arch/arm64/include/asm/pci.h
|
||||
@@ -31,6 +31,10 @@ static inline int pci_get_legacy_ide_irq
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
+#define HAVE_PCI_MMAP
|
||||
+extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
|
||||
+ enum pci_mmap_state mmap_state,
|
||||
+ int write_combine);
|
||||
static inline int pci_proc_domain(struct pci_bus *bus)
|
||||
{
|
||||
return 1;
|
||||
--- a/arch/arm64/include/asm/pgtable-prot.h
|
||||
+++ b/arch/arm64/include/asm/pgtable-prot.h
|
||||
@@ -48,6 +48,7 @@
|
||||
#define PROT_NORMAL_NC (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL_NC))
|
||||
#define PROT_NORMAL_WT (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL_WT))
|
||||
#define PROT_NORMAL (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL))
|
||||
+#define PROT_NORMAL_NS (PTE_TYPE_PAGE | PTE_AF | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL))
|
||||
|
||||
#define PROT_SECT_DEVICE_nGnRE (PROT_SECT_DEFAULT | PMD_SECT_PXN | PMD_SECT_UXN | PMD_ATTRINDX(MT_DEVICE_nGnRE))
|
||||
#define PROT_SECT_NORMAL (PROT_SECT_DEFAULT | PMD_SECT_PXN | PMD_SECT_UXN | PMD_ATTRINDX(MT_NORMAL))
|
||||
@@ -68,6 +69,7 @@
|
||||
#define PAGE_HYP_DEVICE __pgprot(PROT_DEVICE_nGnRE | PTE_HYP)
|
||||
|
||||
#define PAGE_S2 __pgprot(_PROT_DEFAULT | PTE_S2_MEMATTR(MT_S2_NORMAL) | PTE_S2_RDONLY)
|
||||
+#define PAGE_S2_NS __pgprot(PTE_S2_MEMATTR(MT_S2_NORMAL) | PTE_S2_RDWR | PTE_TYPE_PAGE | PTE_AF)
|
||||
#define PAGE_S2_DEVICE __pgprot(_PROT_DEFAULT | PTE_S2_MEMATTR(MT_S2_DEVICE_nGnRE) | PTE_S2_RDONLY | PTE_UXN)
|
||||
|
||||
#define PAGE_NONE __pgprot(((_PAGE_DEFAULT) & ~PTE_VALID) | PTE_PROT_NONE | PTE_NG | PTE_PXN | PTE_UXN)
|
||||
--- a/arch/arm64/include/asm/pgtable.h
|
||||
+++ b/arch/arm64/include/asm/pgtable.h
|
||||
@@ -370,6 +370,11 @@ static inline int pmd_protnone(pmd_t pmd
|
||||
__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRnE) | PTE_PXN | PTE_UXN)
|
||||
#define pgprot_writecombine(prot) \
|
||||
__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC) | PTE_PXN | PTE_UXN)
|
||||
+#define pgprot_cached(prot) \
|
||||
+ __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL) | \
|
||||
+ PTE_PXN | PTE_UXN)
|
||||
+#define pgprot_cached_ns(prot) \
|
||||
+ __pgprot(pgprot_val(pgprot_cached(prot)) ^ PTE_SHARED)
|
||||
#define pgprot_device(prot) \
|
||||
__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRE) | PTE_PXN | PTE_UXN)
|
||||
#define __HAVE_PHYS_MEM_ACCESS_PROT
|
||||
--- a/arch/arm64/kernel/pci.c
|
||||
+++ b/arch/arm64/kernel/pci.c
|
||||
@@ -17,6 +17,8 @@
|
||||
#include <linux/mm.h>
|
||||
#include <linux/of_pci.h>
|
||||
#include <linux/of_platform.h>
|
||||
+#include <linux/of_irq.h>
|
||||
+#include <linux/pcieport_if.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/pci-acpi.h>
|
||||
#include <linux/pci-ecam.h>
|
||||
@@ -53,6 +55,66 @@ int pcibios_alloc_irq(struct pci_dev *de
|
||||
|
||||
return 0;
|
||||
}
|
||||
+
|
||||
+/*
|
||||
+ * Check device tree if the service interrupts are there
|
||||
+ */
|
||||
+int pcibios_check_service_irqs(struct pci_dev *dev, int *irqs, int mask)
|
||||
+{
|
||||
+ int ret, count = 0;
|
||||
+ struct device_node *np = NULL;
|
||||
+
|
||||
+ if (dev->bus->dev.of_node)
|
||||
+ np = dev->bus->dev.of_node;
|
||||
+
|
||||
+ if (np == NULL)
|
||||
+ return 0;
|
||||
+
|
||||
+ if (!IS_ENABLED(CONFIG_OF_IRQ))
|
||||
+ return 0;
|
||||
+
|
||||
+ /* If root port doesn't support MSI/MSI-X/INTx in RC mode,
|
||||
+ * request irq for aer
|
||||
+ */
|
||||
+ if (mask & PCIE_PORT_SERVICE_AER) {
|
||||
+ ret = of_irq_get_byname(np, "aer");
|
||||
+ if (ret > 0) {
|
||||
+ irqs[PCIE_PORT_SERVICE_AER_SHIFT] = ret;
|
||||
+ count++;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (mask & PCIE_PORT_SERVICE_PME) {
|
||||
+ ret = of_irq_get_byname(np, "pme");
|
||||
+ if (ret > 0) {
|
||||
+ irqs[PCIE_PORT_SERVICE_PME_SHIFT] = ret;
|
||||
+ count++;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* TODO: add more service interrupts if there it is in the device tree*/
|
||||
+
|
||||
+ return count;
|
||||
+}
|
||||
+
|
||||
+int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
|
||||
+ enum pci_mmap_state mmap_state, int write_combine)
|
||||
+{
|
||||
+ if (mmap_state == pci_mmap_io)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ /*
|
||||
+ * Mark this as IO
|
||||
+ */
|
||||
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
|
||||
+
|
||||
+ if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
|
||||
+ vma->vm_end - vma->vm_start,
|
||||
+ vma->vm_page_prot))
|
||||
+ return -EAGAIN;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
|
||||
/*
|
||||
* raw_pci_read/write - Platform-specific PCI config space access.
|
||||
--- a/arch/arm64/mm/dma-mapping.c
|
||||
+++ b/arch/arm64/mm/dma-mapping.c
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <linux/swiotlb.h>
|
||||
|
||||
#include <asm/cacheflush.h>
|
||||
+#include <linux/fsl/mc.h>
|
||||
|
||||
static int swiotlb __ro_after_init;
|
||||
|
||||
@@ -925,6 +926,10 @@ static int __init __iommu_dma_init(void)
|
||||
if (!ret)
|
||||
ret = register_iommu_dma_ops_notifier(&pci_bus_type);
|
||||
#endif
|
||||
+#ifdef CONFIG_FSL_MC_BUS
|
||||
+ if (!ret)
|
||||
+ ret = register_iommu_dma_ops_notifier(&fsl_mc_bus_type);
|
||||
+#endif
|
||||
return ret;
|
||||
}
|
||||
arch_initcall(__iommu_dma_init);
|
||||
@@ -978,3 +983,4 @@ void arch_setup_dma_ops(struct device *d
|
||||
dev->archdata.dma_coherent = coherent;
|
||||
__iommu_setup_dma_ops(dev, dma_base, size, iommu);
|
||||
}
|
||||
+EXPORT_SYMBOL(arch_setup_dma_ops);
|
||||
--- a/arch/powerpc/include/asm/dma-mapping.h
|
||||
+++ b/arch/powerpc/include/asm/dma-mapping.h
|
||||
@@ -91,11 +91,6 @@ static inline struct dma_map_ops *get_dm
|
||||
return dev->archdata.dma_ops;
|
||||
}
|
||||
|
||||
-static inline void set_dma_ops(struct device *dev, struct dma_map_ops *ops)
|
||||
-{
|
||||
- dev->archdata.dma_ops = ops;
|
||||
-}
|
||||
-
|
||||
/*
|
||||
* get_dma_offset()
|
||||
*
|
||||
--- a/arch/tile/include/asm/dma-mapping.h
|
||||
+++ b/arch/tile/include/asm/dma-mapping.h
|
||||
@@ -59,11 +59,6 @@ static inline phys_addr_t dma_to_phys(st
|
||||
|
||||
static inline void dma_mark_clean(void *addr, size_t size) {}
|
||||
|
||||
-static inline void set_dma_ops(struct device *dev, struct dma_map_ops *ops)
|
||||
-{
|
||||
- dev->archdata.dma_ops = ops;
|
||||
-}
|
||||
-
|
||||
static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
|
||||
{
|
||||
if (!dev->dma_mask)
|
File diff suppressed because it is too large
Load Diff
@ -1,95 +0,0 @@
|
||||
From c0612164b379ebc8964da6bc6f6ced9736dce488 Mon Sep 17 00:00:00 2001
|
||||
From: Mathew McBride <matt@traverse.com.au>
|
||||
Date: Tue, 17 Apr 2018 10:01:03 +1000
|
||||
Subject: [PATCH] add DTS for Traverse LS1043 Boards
|
||||
|
||||
Signed-off-by: Mathew McBride <matt@traverse.com.au>
|
||||
---
|
||||
arch/arm64/boot/dts/freescale/Makefile | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
create mode 100644 arch/arm64/boot/dts/freescale/traverse-ls1043v.dts
|
||||
|
||||
--- a/arch/arm64/boot/dts/freescale/Makefile
|
||||
+++ b/arch/arm64/boot/dts/freescale/Makefile
|
||||
@@ -21,7 +21,10 @@ dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls2
|
||||
dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls2080a-simu.dtb
|
||||
dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls2088a-qds.dtb
|
||||
dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls2088a-rdb.dtb
|
||||
-
|
||||
+
|
||||
+dtb-$(CONFIG_ARCH_LAYERSCAPE) += traverse-ls1043v.dtb
|
||||
+dtb-$(CONFIG_ARCH_LAYERSCAPE) += traverse-ls1043s.dtb
|
||||
+
|
||||
always := $(dtb-y)
|
||||
subdir-y := $(dts-dirs)
|
||||
clean-files := *.dtb
|
||||
--- a/arch/arm64/boot/dts/freescale/traverse-ls1043s.dts
|
||||
+++ b/arch/arm64/boot/dts/freescale/traverse-ls1043s.dts
|
||||
@@ -330,3 +330,32 @@
|
||||
&sata {
|
||||
status = "disabled";
|
||||
};
|
||||
+
|
||||
+/* Additions for Layerscape SDK (4.4/4.9) Kernel only
|
||||
+ * These kernels need additional setup for FMan/QMan DMA shared memory
|
||||
+ */
|
||||
+
|
||||
+#include "qoriq-qman-portals-sdk.dtsi"
|
||||
+#include "qoriq-bman-portals-sdk.dtsi"
|
||||
+
|
||||
+&bman_fbpr {
|
||||
+ compatible = "fsl,bman-fbpr";
|
||||
+ alloc-ranges = <0 0 0x10000 0>;
|
||||
+};
|
||||
+&qman_fqd {
|
||||
+ compatible = "fsl,qman-fqd";
|
||||
+ alloc-ranges = <0 0 0x10000 0>;
|
||||
+};
|
||||
+&qman_pfdr {
|
||||
+ compatible = "fsl,qman-pfdr";
|
||||
+ alloc-ranges = <0 0 0x10000 0>;
|
||||
+};
|
||||
+
|
||||
+&soc {
|
||||
+#include "qoriq-dpaa-eth.dtsi"
|
||||
+#include "qoriq-fman3-0-6oh.dtsi"
|
||||
+};
|
||||
+
|
||||
+&fman0 {
|
||||
+ compatible = "fsl,fman", "simple-bus";
|
||||
+};
|
||||
--- a/arch/arm64/boot/dts/freescale/traverse-ls1043v.dts
|
||||
+++ b/arch/arm64/boot/dts/freescale/traverse-ls1043v.dts
|
||||
@@ -251,3 +251,32 @@
|
||||
&sata {
|
||||
status = "disabled";
|
||||
};
|
||||
+
|
||||
+/* Additions for Layerscape SDK (4.4/4.9) Kernel only
|
||||
+ * These kernels need additional setup for FMan/QMan DMA shared memory
|
||||
+ */
|
||||
+
|
||||
+#include "qoriq-qman-portals-sdk.dtsi"
|
||||
+#include "qoriq-bman-portals-sdk.dtsi"
|
||||
+
|
||||
+&bman_fbpr {
|
||||
+ compatible = "fsl,bman-fbpr";
|
||||
+ alloc-ranges = <0 0 0x10000 0>;
|
||||
+};
|
||||
+&qman_fqd {
|
||||
+ compatible = "fsl,qman-fqd";
|
||||
+ alloc-ranges = <0 0 0x10000 0>;
|
||||
+};
|
||||
+&qman_pfdr {
|
||||
+ compatible = "fsl,qman-pfdr";
|
||||
+ alloc-ranges = <0 0 0x10000 0>;
|
||||
+};
|
||||
+
|
||||
+&soc {
|
||||
+#include "qoriq-dpaa-eth.dtsi"
|
||||
+#include "qoriq-fman3-0-6oh.dtsi"
|
||||
+};
|
||||
+
|
||||
+&fman0 {
|
||||
+ compatible = "fsl,fman", "simple-bus";
|
||||
+};
|
@ -1,993 +0,0 @@
|
||||
From c03c545e064a81515fe109ddcc4ecb3895528e58 Mon Sep 17 00:00:00 2001
|
||||
From: Yangbo Lu <yangbo.lu@nxp.com>
|
||||
Date: Fri, 6 Jul 2018 15:32:05 +0800
|
||||
Subject: [PATCH] mtd: spi-nor: support layerscape
|
||||
|
||||
This is an integrated patch for layerscape qspi support.
|
||||
|
||||
Signed-off-by: Suresh Gupta <suresh.gupta@nxp.com>
|
||||
Signed-off-by: Yunhui Cui <B56489@freescale.com>
|
||||
Signed-off-by: mar.krzeminski <mar.krzeminski@gmail.com>
|
||||
Signed-off-by: Alison Wang <b18965@freescale.com>
|
||||
Signed-off-by: Nobuhiro Iwamatsu <nobuhiro.iwamatsu.kw@hitachi.com>
|
||||
Signed-off-by: LABBE Corentin <clabbe.montjoie@gmail.com>
|
||||
Signed-off-by: Yuan Yao <yao.yuan@nxp.com>
|
||||
Signed-off-by: Alexander Kurz <akurz@blala.de>
|
||||
Signed-off-by: L. D. Pinney <ldpinney@gmail.com>
|
||||
Signed-off-by: Ash Benz <ash.benz@bk.ru>
|
||||
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
|
||||
---
|
||||
drivers/mtd/devices/m25p80.c | 3 +-
|
||||
drivers/mtd/mtdchar.c | 2 +-
|
||||
drivers/mtd/spi-nor/fsl-quadspi.c | 327 ++++++++++++++++++++++++------
|
||||
drivers/mtd/spi-nor/spi-nor.c | 141 ++++++++++++-
|
||||
include/linux/mtd/spi-nor.h | 14 +-
|
||||
5 files changed, 416 insertions(+), 71 deletions(-)
|
||||
|
||||
--- a/drivers/mtd/mtdchar.c
|
||||
+++ b/drivers/mtd/mtdchar.c
|
||||
@@ -455,7 +455,7 @@ static int mtdchar_readoob(struct file *
|
||||
* data. For our userspace tools it is important to dump areas
|
||||
* with ECC errors!
|
||||
* For kernel internal usage it also might return -EUCLEAN
|
||||
- * to signal the caller that a bitflip has occured and has
|
||||
+ * to signal the caller that a bitflip has occurred and has
|
||||
* been corrected by the ECC algorithm.
|
||||
*
|
||||
* Note: currently the standard NAND function, nand_read_oob_std,
|
||||
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
|
||||
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
|
||||
@@ -41,6 +41,8 @@
|
||||
#define QUADSPI_QUIRK_TKT253890 (1 << 2)
|
||||
/* Controller cannot wake up from wait mode, TKT245618 */
|
||||
#define QUADSPI_QUIRK_TKT245618 (1 << 3)
|
||||
+/* QSPI_AMBA_BASE is internally added by SOC design */
|
||||
+#define QUADSPI_AMBA_BASE_INTERNAL (0x10000)
|
||||
|
||||
/* The registers */
|
||||
#define QUADSPI_MCR 0x00
|
||||
@@ -193,7 +195,7 @@
|
||||
#define QUADSPI_LUT_NUM 64
|
||||
|
||||
/* SEQID -- we can have 16 seqids at most. */
|
||||
-#define SEQID_QUAD_READ 0
|
||||
+#define SEQID_READ 0
|
||||
#define SEQID_WREN 1
|
||||
#define SEQID_WRDI 2
|
||||
#define SEQID_RDSR 3
|
||||
@@ -205,15 +207,22 @@
|
||||
#define SEQID_RDCR 9
|
||||
#define SEQID_EN4B 10
|
||||
#define SEQID_BRWR 11
|
||||
+#define SEQID_RDAR_OR_RD_EVCR 12
|
||||
+#define SEQID_WRAR 13
|
||||
+#define SEQID_WD_EVCR 14
|
||||
|
||||
#define QUADSPI_MIN_IOMAP SZ_4M
|
||||
|
||||
+#define FLASH_VENDOR_SPANSION_FS "s25fs"
|
||||
+#define SPANSION_S25FS_FAMILY (1 << 1)
|
||||
+
|
||||
enum fsl_qspi_devtype {
|
||||
FSL_QUADSPI_VYBRID,
|
||||
FSL_QUADSPI_IMX6SX,
|
||||
FSL_QUADSPI_IMX7D,
|
||||
FSL_QUADSPI_IMX6UL,
|
||||
FSL_QUADSPI_LS1021A,
|
||||
+ FSL_QUADSPI_LS2080A,
|
||||
};
|
||||
|
||||
struct fsl_qspi_devtype_data {
|
||||
@@ -224,7 +233,7 @@ struct fsl_qspi_devtype_data {
|
||||
int driver_data;
|
||||
};
|
||||
|
||||
-static struct fsl_qspi_devtype_data vybrid_data = {
|
||||
+static const struct fsl_qspi_devtype_data vybrid_data = {
|
||||
.devtype = FSL_QUADSPI_VYBRID,
|
||||
.rxfifo = 128,
|
||||
.txfifo = 64,
|
||||
@@ -232,7 +241,7 @@ static struct fsl_qspi_devtype_data vybr
|
||||
.driver_data = QUADSPI_QUIRK_SWAP_ENDIAN,
|
||||
};
|
||||
|
||||
-static struct fsl_qspi_devtype_data imx6sx_data = {
|
||||
+static const struct fsl_qspi_devtype_data imx6sx_data = {
|
||||
.devtype = FSL_QUADSPI_IMX6SX,
|
||||
.rxfifo = 128,
|
||||
.txfifo = 512,
|
||||
@@ -241,7 +250,7 @@ static struct fsl_qspi_devtype_data imx6
|
||||
| QUADSPI_QUIRK_TKT245618,
|
||||
};
|
||||
|
||||
-static struct fsl_qspi_devtype_data imx7d_data = {
|
||||
+static const struct fsl_qspi_devtype_data imx7d_data = {
|
||||
.devtype = FSL_QUADSPI_IMX7D,
|
||||
.rxfifo = 512,
|
||||
.txfifo = 512,
|
||||
@@ -250,7 +259,7 @@ static struct fsl_qspi_devtype_data imx7
|
||||
| QUADSPI_QUIRK_4X_INT_CLK,
|
||||
};
|
||||
|
||||
-static struct fsl_qspi_devtype_data imx6ul_data = {
|
||||
+static const struct fsl_qspi_devtype_data imx6ul_data = {
|
||||
.devtype = FSL_QUADSPI_IMX6UL,
|
||||
.rxfifo = 128,
|
||||
.txfifo = 512,
|
||||
@@ -267,6 +276,14 @@ static struct fsl_qspi_devtype_data ls10
|
||||
.driver_data = 0,
|
||||
};
|
||||
|
||||
+static struct fsl_qspi_devtype_data ls2080a_data = {
|
||||
+ .devtype = FSL_QUADSPI_LS2080A,
|
||||
+ .rxfifo = 128,
|
||||
+ .txfifo = 64,
|
||||
+ .ahb_buf_size = 1024,
|
||||
+ .driver_data = QUADSPI_AMBA_BASE_INTERNAL | QUADSPI_QUIRK_TKT253890,
|
||||
+};
|
||||
+
|
||||
#define FSL_QSPI_MAX_CHIP 4
|
||||
struct fsl_qspi {
|
||||
struct spi_nor nor[FSL_QSPI_MAX_CHIP];
|
||||
@@ -282,6 +299,7 @@ struct fsl_qspi {
|
||||
u32 nor_size;
|
||||
u32 nor_num;
|
||||
u32 clk_rate;
|
||||
+ u32 ddr_smp;
|
||||
unsigned int chip_base_addr; /* We may support two chips. */
|
||||
bool has_second_chip;
|
||||
bool big_endian;
|
||||
@@ -309,6 +327,23 @@ static inline int needs_wakeup_wait_mode
|
||||
return q->devtype_data->driver_data & QUADSPI_QUIRK_TKT245618;
|
||||
}
|
||||
|
||||
+static inline int has_added_amba_base_internal(struct fsl_qspi *q)
|
||||
+{
|
||||
+ return q->devtype_data->driver_data & QUADSPI_AMBA_BASE_INTERNAL;
|
||||
+}
|
||||
+
|
||||
+static u32 fsl_get_nor_vendor(struct spi_nor *nor)
|
||||
+{
|
||||
+ u32 vendor_id;
|
||||
+
|
||||
+ if (nor->vendor) {
|
||||
+ if (memcmp(nor->vendor, FLASH_VENDOR_SPANSION_FS,
|
||||
+ sizeof(FLASH_VENDOR_SPANSION_FS) - 1))
|
||||
+ vendor_id = SPANSION_S25FS_FAMILY;
|
||||
+ }
|
||||
+ return vendor_id;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* R/W functions for big- or little-endian registers:
|
||||
* The qSPI controller's endian is independent of the CPU core's endian.
|
||||
@@ -331,6 +366,31 @@ static u32 qspi_readl(struct fsl_qspi *q
|
||||
return ioread32(addr);
|
||||
}
|
||||
|
||||
+static inline u32 *u8tou32(u32 *dest, const u8 *src, size_t n)
|
||||
+{
|
||||
+ size_t i;
|
||||
+ *dest = 0;
|
||||
+
|
||||
+ n = n > 4 ? 4 : n;
|
||||
+ for (i = 0; i < n; i++)
|
||||
+ *dest |= *src++ << i * 8;
|
||||
+
|
||||
+ return dest;
|
||||
+
|
||||
+}
|
||||
+
|
||||
+static inline u8 *u32tou8(u8 *dest, const u32 *src, size_t n)
|
||||
+{
|
||||
+ size_t i;
|
||||
+ u8 *xdest = dest;
|
||||
+
|
||||
+ n = n > 4 ? 4 : n;
|
||||
+ for (i = 0; i < n; i++)
|
||||
+ *xdest++ = *src >> i * 8;
|
||||
+
|
||||
+ return dest;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* An IC bug makes us to re-arrange the 32-bit data.
|
||||
* The following chips, such as IMX6SLX, have fixed this bug.
|
||||
@@ -373,8 +433,15 @@ static void fsl_qspi_init_lut(struct fsl
|
||||
void __iomem *base = q->iobase;
|
||||
int rxfifo = q->devtype_data->rxfifo;
|
||||
u32 lut_base;
|
||||
- u8 cmd, addrlen, dummy;
|
||||
int i;
|
||||
+ u32 vendor;
|
||||
+
|
||||
+ struct spi_nor *nor = &q->nor[0];
|
||||
+ u8 addrlen = (nor->addr_width == 3) ? ADDR24BIT : ADDR32BIT;
|
||||
+ u8 read_op = nor->read_opcode;
|
||||
+ u8 read_dm = nor->read_dummy;
|
||||
+
|
||||
+ vendor = fsl_get_nor_vendor(nor);
|
||||
|
||||
fsl_qspi_unlock_lut(q);
|
||||
|
||||
@@ -382,24 +449,50 @@ static void fsl_qspi_init_lut(struct fsl
|
||||
for (i = 0; i < QUADSPI_LUT_NUM; i++)
|
||||
qspi_writel(q, 0, base + QUADSPI_LUT_BASE + i * 4);
|
||||
|
||||
- /* Quad Read */
|
||||
- lut_base = SEQID_QUAD_READ * 4;
|
||||
+ /* Read */
|
||||
+ lut_base = SEQID_READ * 4;
|
||||
|
||||
- if (q->nor_size <= SZ_16M) {
|
||||
- cmd = SPINOR_OP_READ_1_1_4;
|
||||
- addrlen = ADDR24BIT;
|
||||
- dummy = 8;
|
||||
- } else {
|
||||
- /* use the 4-byte address */
|
||||
- cmd = SPINOR_OP_READ_1_1_4;
|
||||
- addrlen = ADDR32BIT;
|
||||
- dummy = 8;
|
||||
- }
|
||||
-
|
||||
- qspi_writel(q, LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen),
|
||||
+ if (nor->flash_read == SPI_NOR_FAST) {
|
||||
+ qspi_writel(q, LUT0(CMD, PAD1, read_op) |
|
||||
+ LUT1(ADDR, PAD1, addrlen),
|
||||
+ base + QUADSPI_LUT(lut_base));
|
||||
+ qspi_writel(q, LUT0(DUMMY, PAD1, read_dm) |
|
||||
+ LUT1(FSL_READ, PAD1, rxfifo),
|
||||
+ base + QUADSPI_LUT(lut_base + 1));
|
||||
+ } else if (nor->flash_read == SPI_NOR_QUAD) {
|
||||
+ if (q->nor_size == 0x4000000) {
|
||||
+ read_op = 0xEC;
|
||||
+ qspi_writel(q,
|
||||
+ LUT0(CMD, PAD1, read_op) | LUT1(ADDR, PAD4, addrlen),
|
||||
base + QUADSPI_LUT(lut_base));
|
||||
- qspi_writel(q, LUT0(DUMMY, PAD1, dummy) | LUT1(FSL_READ, PAD4, rxfifo),
|
||||
+ qspi_writel(q,
|
||||
+ LUT0(MODE, PAD4, 0xff) | LUT1(DUMMY, PAD4, read_dm),
|
||||
base + QUADSPI_LUT(lut_base + 1));
|
||||
+ qspi_writel(q,
|
||||
+ LUT0(FSL_READ, PAD4, rxfifo),
|
||||
+ base + QUADSPI_LUT(lut_base + 2));
|
||||
+ } else {
|
||||
+ qspi_writel(q, LUT0(CMD, PAD1, read_op) |
|
||||
+ LUT1(ADDR, PAD1, addrlen),
|
||||
+ base + QUADSPI_LUT(lut_base));
|
||||
+ qspi_writel(q, LUT0(DUMMY, PAD1, read_dm) |
|
||||
+ LUT1(FSL_READ, PAD4, rxfifo),
|
||||
+ base + QUADSPI_LUT(lut_base + 1));
|
||||
+ }
|
||||
+ } else if (nor->flash_read == SPI_NOR_DDR_QUAD) {
|
||||
+ /* read mode : 1-4-4, such as Spansion s25fl128s. */
|
||||
+ qspi_writel(q, LUT0(CMD, PAD1, read_op)
|
||||
+ | LUT1(ADDR_DDR, PAD4, addrlen),
|
||||
+ base + QUADSPI_LUT(lut_base));
|
||||
+
|
||||
+ qspi_writel(q, LUT0(MODE_DDR, PAD4, 0xff)
|
||||
+ | LUT1(DUMMY, PAD1, read_dm),
|
||||
+ base + QUADSPI_LUT(lut_base + 1));
|
||||
+
|
||||
+ qspi_writel(q, LUT0(FSL_READ_DDR, PAD4, rxfifo)
|
||||
+ | LUT1(JMP_ON_CS, PAD1, 0),
|
||||
+ base + QUADSPI_LUT(lut_base + 2));
|
||||
+ }
|
||||
|
||||
/* Write enable */
|
||||
lut_base = SEQID_WREN * 4;
|
||||
@@ -409,16 +502,8 @@ static void fsl_qspi_init_lut(struct fsl
|
||||
/* Page Program */
|
||||
lut_base = SEQID_PP * 4;
|
||||
|
||||
- if (q->nor_size <= SZ_16M) {
|
||||
- cmd = SPINOR_OP_PP;
|
||||
- addrlen = ADDR24BIT;
|
||||
- } else {
|
||||
- /* use the 4-byte address */
|
||||
- cmd = SPINOR_OP_PP;
|
||||
- addrlen = ADDR32BIT;
|
||||
- }
|
||||
-
|
||||
- qspi_writel(q, LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen),
|
||||
+ qspi_writel(q, LUT0(CMD, PAD1, nor->program_opcode) |
|
||||
+ LUT1(ADDR, PAD1, addrlen),
|
||||
base + QUADSPI_LUT(lut_base));
|
||||
qspi_writel(q, LUT0(FSL_WRITE, PAD1, 0),
|
||||
base + QUADSPI_LUT(lut_base + 1));
|
||||
@@ -432,10 +517,8 @@ static void fsl_qspi_init_lut(struct fsl
|
||||
/* Erase a sector */
|
||||
lut_base = SEQID_SE * 4;
|
||||
|
||||
- cmd = q->nor[0].erase_opcode;
|
||||
- addrlen = q->nor_size <= SZ_16M ? ADDR24BIT : ADDR32BIT;
|
||||
-
|
||||
- qspi_writel(q, LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen),
|
||||
+ qspi_writel(q, LUT0(CMD, PAD1, nor->erase_opcode) |
|
||||
+ LUT1(ADDR, PAD1, addrlen),
|
||||
base + QUADSPI_LUT(lut_base));
|
||||
|
||||
/* Erase the whole chip */
|
||||
@@ -476,6 +559,44 @@ static void fsl_qspi_init_lut(struct fsl
|
||||
qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_BRWR),
|
||||
base + QUADSPI_LUT(lut_base));
|
||||
|
||||
+
|
||||
+ /*
|
||||
+ * Flash Micron and Spansion command confilict
|
||||
+ * use the same value 0x65. But it indicates different meaning.
|
||||
+ */
|
||||
+ lut_base = SEQID_RDAR_OR_RD_EVCR * 4;
|
||||
+
|
||||
+ if (vendor == SPANSION_S25FS_FAMILY) {
|
||||
+ /*
|
||||
+ * Read any device register.
|
||||
+ * Used for Spansion S25FS-S family flash only.
|
||||
+ */
|
||||
+ qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_SPANSION_RDAR) |
|
||||
+ LUT1(ADDR, PAD1, ADDR24BIT),
|
||||
+ base + QUADSPI_LUT(lut_base));
|
||||
+ qspi_writel(q, LUT0(DUMMY, PAD1, 8) | LUT1(FSL_READ, PAD1, 1),
|
||||
+ base + QUADSPI_LUT(lut_base + 1));
|
||||
+ } else {
|
||||
+ qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_RD_EVCR),
|
||||
+ base + QUADSPI_LUT(lut_base));
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Write any device register.
|
||||
+ * Used for Spansion S25FS-S family flash only.
|
||||
+ */
|
||||
+ lut_base = SEQID_WRAR * 4;
|
||||
+ qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_SPANSION_WRAR) |
|
||||
+ LUT1(ADDR, PAD1, ADDR24BIT),
|
||||
+ base + QUADSPI_LUT(lut_base));
|
||||
+ qspi_writel(q, LUT0(FSL_WRITE, PAD1, 1),
|
||||
+ base + QUADSPI_LUT(lut_base + 1));
|
||||
+
|
||||
+ /* Write EVCR register */
|
||||
+ lut_base = SEQID_WD_EVCR * 4;
|
||||
+ qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_WD_EVCR),
|
||||
+ base + QUADSPI_LUT(lut_base));
|
||||
+
|
||||
fsl_qspi_lock_lut(q);
|
||||
}
|
||||
|
||||
@@ -483,8 +604,24 @@ static void fsl_qspi_init_lut(struct fsl
|
||||
static int fsl_qspi_get_seqid(struct fsl_qspi *q, u8 cmd)
|
||||
{
|
||||
switch (cmd) {
|
||||
+ case SPINOR_OP_READ_1_4_4_D:
|
||||
+ case SPINOR_OP_READ4_1_4_4_D:
|
||||
+ case SPINOR_OP_READ4_1_1_4:
|
||||
case SPINOR_OP_READ_1_1_4:
|
||||
- return SEQID_QUAD_READ;
|
||||
+ case SPINOR_OP_READ_FAST:
|
||||
+ case SPINOR_OP_READ4_FAST:
|
||||
+ return SEQID_READ;
|
||||
+ /*
|
||||
+ * Spansion & Micron use the same command value 0x65
|
||||
+ * Spansion: SPINOR_OP_SPANSION_RDAR, read any register.
|
||||
+ * Micron: SPINOR_OP_RD_EVCR,
|
||||
+ * read enhanced volatile configuration register.
|
||||
+ * case SPINOR_OP_RD_EVCR:
|
||||
+ */
|
||||
+ case SPINOR_OP_SPANSION_RDAR:
|
||||
+ return SEQID_RDAR_OR_RD_EVCR;
|
||||
+ case SPINOR_OP_SPANSION_WRAR:
|
||||
+ return SEQID_WRAR;
|
||||
case SPINOR_OP_WREN:
|
||||
return SEQID_WREN;
|
||||
case SPINOR_OP_WRDI:
|
||||
@@ -496,6 +633,7 @@ static int fsl_qspi_get_seqid(struct fsl
|
||||
case SPINOR_OP_CHIP_ERASE:
|
||||
return SEQID_CHIP_ERASE;
|
||||
case SPINOR_OP_PP:
|
||||
+ case SPINOR_OP_PP_4B:
|
||||
return SEQID_PP;
|
||||
case SPINOR_OP_RDID:
|
||||
return SEQID_RDID;
|
||||
@@ -507,6 +645,8 @@ static int fsl_qspi_get_seqid(struct fsl
|
||||
return SEQID_EN4B;
|
||||
case SPINOR_OP_BRWR:
|
||||
return SEQID_BRWR;
|
||||
+ case SPINOR_OP_WD_EVCR:
|
||||
+ return SEQID_WD_EVCR;
|
||||
default:
|
||||
if (cmd == q->nor[0].erase_opcode)
|
||||
return SEQID_SE;
|
||||
@@ -531,8 +671,11 @@ fsl_qspi_runcmd(struct fsl_qspi *q, u8 c
|
||||
/* save the reg */
|
||||
reg = qspi_readl(q, base + QUADSPI_MCR);
|
||||
|
||||
- qspi_writel(q, q->memmap_phy + q->chip_base_addr + addr,
|
||||
- base + QUADSPI_SFAR);
|
||||
+ if (has_added_amba_base_internal(q))
|
||||
+ qspi_writel(q, q->chip_base_addr + addr, base + QUADSPI_SFAR);
|
||||
+ else
|
||||
+ qspi_writel(q, q->memmap_phy + q->chip_base_addr + addr,
|
||||
+ base + QUADSPI_SFAR);
|
||||
qspi_writel(q, QUADSPI_RBCT_WMRK_MASK | QUADSPI_RBCT_RXBRD_USEIPS,
|
||||
base + QUADSPI_RBCT);
|
||||
qspi_writel(q, reg | QUADSPI_MCR_CLR_RXF_MASK, base + QUADSPI_MCR);
|
||||
@@ -582,10 +725,10 @@ static void fsl_qspi_read_data(struct fs
|
||||
q->chip_base_addr, tmp);
|
||||
|
||||
if (len >= 4) {
|
||||
- *((u32 *)rxbuf) = tmp;
|
||||
+ u32tou8(rxbuf, &tmp, 4);
|
||||
rxbuf += 4;
|
||||
} else {
|
||||
- memcpy(rxbuf, &tmp, len);
|
||||
+ u32tou8(rxbuf, &tmp, len);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -619,11 +762,12 @@ static inline void fsl_qspi_invalid(stru
|
||||
}
|
||||
|
||||
static ssize_t fsl_qspi_nor_write(struct fsl_qspi *q, struct spi_nor *nor,
|
||||
- u8 opcode, unsigned int to, u32 *txbuf,
|
||||
+ u8 opcode, unsigned int to, u8 *txbuf,
|
||||
unsigned count)
|
||||
{
|
||||
int ret, i, j;
|
||||
u32 tmp;
|
||||
+ u8 byts;
|
||||
|
||||
dev_dbg(q->dev, "to 0x%.8x:0x%.8x, len : %d\n",
|
||||
q->chip_base_addr, to, count);
|
||||
@@ -633,10 +777,13 @@ static ssize_t fsl_qspi_nor_write(struct
|
||||
qspi_writel(q, tmp | QUADSPI_MCR_CLR_TXF_MASK, q->iobase + QUADSPI_MCR);
|
||||
|
||||
/* fill the TX data to the FIFO */
|
||||
+ byts = count;
|
||||
for (j = 0, i = ((count + 3) / 4); j < i; j++) {
|
||||
- tmp = fsl_qspi_endian_xchg(q, *txbuf);
|
||||
+ u8tou32(&tmp, txbuf, byts);
|
||||
+ tmp = fsl_qspi_endian_xchg(q, tmp);
|
||||
qspi_writel(q, tmp, q->iobase + QUADSPI_TBDR);
|
||||
- txbuf++;
|
||||
+ txbuf += 4;
|
||||
+ byts -= 4;
|
||||
}
|
||||
|
||||
/* fill the TXFIFO upto 16 bytes for i.MX7d */
|
||||
@@ -657,11 +804,43 @@ static void fsl_qspi_set_map_addr(struct
|
||||
{
|
||||
int nor_size = q->nor_size;
|
||||
void __iomem *base = q->iobase;
|
||||
+ u32 mem_base;
|
||||
+
|
||||
+ if (has_added_amba_base_internal(q))
|
||||
+ mem_base = 0x0;
|
||||
+ else
|
||||
+ mem_base = q->memmap_phy;
|
||||
+
|
||||
+ qspi_writel(q, nor_size + mem_base, base + QUADSPI_SFA1AD);
|
||||
+ qspi_writel(q, nor_size * 2 + mem_base, base + QUADSPI_SFA2AD);
|
||||
+ qspi_writel(q, nor_size * 3 + mem_base, base + QUADSPI_SFB1AD);
|
||||
+ qspi_writel(q, nor_size * 4 + mem_base, base + QUADSPI_SFB2AD);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * enable controller ddr quad mode to support different
|
||||
+ * vender flashes ddr quad mode.
|
||||
+ */
|
||||
+static void set_ddr_quad_mode(struct fsl_qspi *q)
|
||||
+{
|
||||
+ u32 reg, reg2;
|
||||
+
|
||||
+ reg = qspi_readl(q, q->iobase + QUADSPI_MCR);
|
||||
+
|
||||
+ /* Firstly, disable the module */
|
||||
+ qspi_writel(q, reg | QUADSPI_MCR_MDIS_MASK, q->iobase + QUADSPI_MCR);
|
||||
+
|
||||
+ /* Set the Sampling Register for DDR */
|
||||
+ reg2 = qspi_readl(q, q->iobase + QUADSPI_SMPR);
|
||||
+ reg2 &= ~QUADSPI_SMPR_DDRSMP_MASK;
|
||||
+ reg2 |= (((q->ddr_smp) << QUADSPI_SMPR_DDRSMP_SHIFT) &
|
||||
+ QUADSPI_SMPR_DDRSMP_MASK);
|
||||
+ qspi_writel(q, reg2, q->iobase + QUADSPI_SMPR);
|
||||
+
|
||||
+ /* Enable the module again (enable the DDR too) */
|
||||
+ reg |= QUADSPI_MCR_DDR_EN_MASK;
|
||||
+ qspi_writel(q, reg, q->iobase + QUADSPI_MCR);
|
||||
|
||||
- qspi_writel(q, nor_size + q->memmap_phy, base + QUADSPI_SFA1AD);
|
||||
- qspi_writel(q, nor_size * 2 + q->memmap_phy, base + QUADSPI_SFA2AD);
|
||||
- qspi_writel(q, nor_size * 3 + q->memmap_phy, base + QUADSPI_SFB1AD);
|
||||
- qspi_writel(q, nor_size * 4 + q->memmap_phy, base + QUADSPI_SFB2AD);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -704,6 +883,11 @@ static void fsl_qspi_init_abh_read(struc
|
||||
seqid = fsl_qspi_get_seqid(q, q->nor[0].read_opcode);
|
||||
qspi_writel(q, seqid << QUADSPI_BFGENCR_SEQID_SHIFT,
|
||||
q->iobase + QUADSPI_BFGENCR);
|
||||
+
|
||||
+ /* enable the DDR quad read */
|
||||
+ if (q->nor->flash_read == SPI_NOR_DDR_QUAD)
|
||||
+ set_ddr_quad_mode(q);
|
||||
+
|
||||
}
|
||||
|
||||
/* This function was used to prepare and enable QSPI clock */
|
||||
@@ -822,6 +1006,7 @@ static const struct of_device_id fsl_qsp
|
||||
{ .compatible = "fsl,imx7d-qspi", .data = (void *)&imx7d_data, },
|
||||
{ .compatible = "fsl,imx6ul-qspi", .data = (void *)&imx6ul_data, },
|
||||
{ .compatible = "fsl,ls1021a-qspi", .data = (void *)&ls1021a_data, },
|
||||
+ { .compatible = "fsl,ls2080a-qspi", .data = (void *)&ls2080a_data, },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, fsl_qspi_dt_ids);
|
||||
@@ -835,8 +1020,12 @@ static int fsl_qspi_read_reg(struct spi_
|
||||
{
|
||||
int ret;
|
||||
struct fsl_qspi *q = nor->priv;
|
||||
+ u32 to = 0;
|
||||
|
||||
- ret = fsl_qspi_runcmd(q, opcode, 0, len);
|
||||
+ if (opcode == SPINOR_OP_SPANSION_RDAR)
|
||||
+ u8tou32(&to, nor->cmd_buf, 4);
|
||||
+
|
||||
+ ret = fsl_qspi_runcmd(q, opcode, to, len);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -848,9 +1037,13 @@ static int fsl_qspi_write_reg(struct spi
|
||||
{
|
||||
struct fsl_qspi *q = nor->priv;
|
||||
int ret;
|
||||
+ u32 to = 0;
|
||||
+
|
||||
+ if (opcode == SPINOR_OP_SPANSION_WRAR)
|
||||
+ u8tou32(&to, nor->cmd_buf, 4);
|
||||
|
||||
if (!buf) {
|
||||
- ret = fsl_qspi_runcmd(q, opcode, 0, 1);
|
||||
+ ret = fsl_qspi_runcmd(q, opcode, to, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -859,7 +1052,7 @@ static int fsl_qspi_write_reg(struct spi
|
||||
|
||||
} else if (len > 0) {
|
||||
ret = fsl_qspi_nor_write(q, nor, opcode, 0,
|
||||
- (u32 *)buf, len);
|
||||
+ buf, len);
|
||||
if (ret > 0)
|
||||
return 0;
|
||||
} else {
|
||||
@@ -875,7 +1068,7 @@ static ssize_t fsl_qspi_write(struct spi
|
||||
{
|
||||
struct fsl_qspi *q = nor->priv;
|
||||
ssize_t ret = fsl_qspi_nor_write(q, nor, nor->program_opcode, to,
|
||||
- (u32 *)buf, len);
|
||||
+ (u8 *)buf, len);
|
||||
|
||||
/* invalid the data in the AHB buffer. */
|
||||
fsl_qspi_invalid(q);
|
||||
@@ -922,7 +1115,7 @@ static ssize_t fsl_qspi_read(struct spi_
|
||||
len);
|
||||
|
||||
/* Read out the data directly from the AHB buffer.*/
|
||||
- memcpy(buf, q->ahb_addr + q->chip_base_addr + from - q->memmap_offs,
|
||||
+ memcpy_toio(buf, q->ahb_addr + q->chip_base_addr + from - q->memmap_offs,
|
||||
len);
|
||||
|
||||
return len;
|
||||
@@ -980,6 +1173,8 @@ static int fsl_qspi_probe(struct platfor
|
||||
struct spi_nor *nor;
|
||||
struct mtd_info *mtd;
|
||||
int ret, i = 0;
|
||||
+ int find_node;
|
||||
+ enum read_mode mode = SPI_NOR_QUAD;
|
||||
|
||||
q = devm_kzalloc(dev, sizeof(*q), GFP_KERNEL);
|
||||
if (!q)
|
||||
@@ -1027,6 +1222,12 @@ static int fsl_qspi_probe(struct platfor
|
||||
goto clk_failed;
|
||||
}
|
||||
|
||||
+ /* find ddrsmp value */
|
||||
+ ret = of_property_read_u32(dev->of_node, "fsl,ddr-sampling-point",
|
||||
+ &q->ddr_smp);
|
||||
+ if (ret)
|
||||
+ q->ddr_smp = 0;
|
||||
+
|
||||
/* find the irq */
|
||||
ret = platform_get_irq(pdev, 0);
|
||||
if (ret < 0) {
|
||||
@@ -1050,6 +1251,7 @@ static int fsl_qspi_probe(struct platfor
|
||||
|
||||
mutex_init(&q->lock);
|
||||
|
||||
+ find_node = 0;
|
||||
/* iterate the subnodes. */
|
||||
for_each_available_child_of_node(dev->of_node, np) {
|
||||
/* skip the holes */
|
||||
@@ -1076,18 +1278,25 @@ static int fsl_qspi_probe(struct platfor
|
||||
ret = of_property_read_u32(np, "spi-max-frequency",
|
||||
&q->clk_rate);
|
||||
if (ret < 0)
|
||||
- goto mutex_failed;
|
||||
+ continue;
|
||||
|
||||
/* set the chip address for READID */
|
||||
fsl_qspi_set_base_addr(q, nor);
|
||||
|
||||
- ret = spi_nor_scan(nor, NULL, SPI_NOR_QUAD);
|
||||
+ ret = of_property_read_bool(np, "m25p,fast-read");
|
||||
+ mode = (ret) ? SPI_NOR_FAST : SPI_NOR_QUAD;
|
||||
+ /* Can we enable the DDR Quad Read? */
|
||||
+ ret = of_property_read_bool(np, "ddr-quad-read");
|
||||
if (ret)
|
||||
- goto mutex_failed;
|
||||
+ mode = SPI_NOR_DDR_QUAD;
|
||||
+
|
||||
+ ret = spi_nor_scan(nor, NULL, mode);
|
||||
+ if (ret)
|
||||
+ continue;
|
||||
|
||||
ret = mtd_device_register(mtd, NULL, 0);
|
||||
if (ret)
|
||||
- goto mutex_failed;
|
||||
+ continue;
|
||||
|
||||
/* Set the correct NOR size now. */
|
||||
if (q->nor_size == 0) {
|
||||
@@ -1110,8 +1319,12 @@ static int fsl_qspi_probe(struct platfor
|
||||
nor->page_size = q->devtype_data->txfifo;
|
||||
|
||||
i++;
|
||||
+ find_node++;
|
||||
}
|
||||
|
||||
+ if (find_node == 0)
|
||||
+ goto mutex_failed;
|
||||
+
|
||||
/* finish the rest init. */
|
||||
ret = fsl_qspi_nor_setup_last(q);
|
||||
if (ret)
|
||||
--- a/drivers/mtd/spi-nor/spi-nor.c
|
||||
+++ b/drivers/mtd/spi-nor/spi-nor.c
|
||||
@@ -40,6 +40,13 @@
|
||||
#define SPI_NOR_MAX_ID_LEN 6
|
||||
#define SPI_NOR_MAX_ADDR_WIDTH 4
|
||||
|
||||
+#define SPI_NOR_MICRON_WRITE_ENABLE 0x7f
|
||||
+/* Added for S25FS-S family flash */
|
||||
+#define SPINOR_CONFIG_REG3_OFFSET 0x800004
|
||||
+#define CR3V_4KB_ERASE_UNABLE 0x8
|
||||
+#define SPINOR_S25FS_FAMILY_ID 0x81
|
||||
+
|
||||
+
|
||||
struct flash_info {
|
||||
char *name;
|
||||
|
||||
@@ -68,7 +75,8 @@ struct flash_info {
|
||||
#define SECT_4K_PMC BIT(4) /* SPINOR_OP_BE_4K_PMC works uniformly */
|
||||
#define SPI_NOR_DUAL_READ BIT(5) /* Flash supports Dual Read */
|
||||
#define SPI_NOR_QUAD_READ BIT(6) /* Flash supports Quad Read */
|
||||
-#define USE_FSR BIT(7) /* use flag status register */
|
||||
+#define USE_FSR BIT(13) /* use flag status register */
|
||||
+#define SPI_NOR_DDR_QUAD_READ BIT(7) /* Flash supports DDR Quad Read */
|
||||
#define SPI_NOR_HAS_LOCK BIT(8) /* Flash supports lock/unlock via SR */
|
||||
#define SPI_NOR_HAS_TB BIT(9) /*
|
||||
* Flash SR has Top/Bottom (TB) protect
|
||||
@@ -85,9 +93,11 @@ struct flash_info {
|
||||
* Use dedicated 4byte address op codes
|
||||
* to support memory size above 128Mib.
|
||||
*/
|
||||
+#define NO_CHIP_ERASE BIT(12) /* Chip does not support chip erase */
|
||||
};
|
||||
|
||||
#define JEDEC_MFR(info) ((info)->id[0])
|
||||
+#define EXT_ID(info) ((info)->id[5])
|
||||
|
||||
static const struct flash_info *spi_nor_match_id(const char *name);
|
||||
|
||||
@@ -132,7 +142,7 @@ static int read_fsr(struct spi_nor *nor)
|
||||
/*
|
||||
* Read configuration register, returning its value in the
|
||||
* location. Return the configuration register value.
|
||||
- * Returns negative if error occured.
|
||||
+ * Returns negative if error occurred.
|
||||
*/
|
||||
static int read_cr(struct spi_nor *nor)
|
||||
{
|
||||
@@ -160,6 +170,8 @@ static inline int spi_nor_read_dummy_cyc
|
||||
case SPI_NOR_DUAL:
|
||||
case SPI_NOR_QUAD:
|
||||
return 8;
|
||||
+ case SPI_NOR_DDR_QUAD:
|
||||
+ return 6;
|
||||
case SPI_NOR_NORMAL:
|
||||
return 0;
|
||||
}
|
||||
@@ -962,6 +974,8 @@ static const struct flash_info spi_nor_i
|
||||
|
||||
/* ESMT */
|
||||
{ "f25l32pa", INFO(0x8c2016, 0, 64 * 1024, 64, SECT_4K | SPI_NOR_HAS_LOCK) },
|
||||
+ { "f25l32qa", INFO(0x8c4116, 0, 64 * 1024, 64, SECT_4K | SPI_NOR_HAS_LOCK) },
|
||||
+ { "f25l64qa", INFO(0x8c4117, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_HAS_LOCK) },
|
||||
|
||||
/* Everspin */
|
||||
{ "mr25h256", CAT25_INFO( 32 * 1024, 1, 256, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
|
||||
@@ -1021,12 +1035,15 @@ static const struct flash_info spi_nor_i
|
||||
{ "mx25l3205d", INFO(0xc22016, 0, 64 * 1024, 64, SECT_4K) },
|
||||
{ "mx25l3255e", INFO(0xc29e16, 0, 64 * 1024, 64, SECT_4K) },
|
||||
{ "mx25l6405d", INFO(0xc22017, 0, 64 * 1024, 128, SECT_4K) },
|
||||
+ { "mx25u2033e", INFO(0xc22532, 0, 64 * 1024, 4, SECT_4K) },
|
||||
+ { "mx25u4035", INFO(0xc22533, 0, 64 * 1024, 8, SECT_4K) },
|
||||
+ { "mx25u8035", INFO(0xc22534, 0, 64 * 1024, 16, SECT_4K) },
|
||||
{ "mx25u3235f", INFO(0xc22536, 0, 64 * 1024, 64, 0) },
|
||||
{ "mx25u6435f", INFO(0xc22537, 0, 64 * 1024, 128, SECT_4K) },
|
||||
{ "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) },
|
||||
{ "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) },
|
||||
{ "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, 0) },
|
||||
- { "mx25u25635f", INFO(0xc22539, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_4B_OPCODES) },
|
||||
+ { "mx25u25635f", INFO(0xc22539, 0, 64 * 1024, 512, SECT_4K) },
|
||||
{ "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) },
|
||||
{ "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, SPI_NOR_QUAD_READ) },
|
||||
{ "mx66l1g55g", INFO(0xc2261b, 0, 64 * 1024, 2048, SPI_NOR_QUAD_READ) },
|
||||
@@ -1040,10 +1057,11 @@ static const struct flash_info spi_nor_i
|
||||
{ "n25q128a11", INFO(0x20bb18, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_QUAD_READ) },
|
||||
{ "n25q128a13", INFO(0x20ba18, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_QUAD_READ) },
|
||||
{ "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_QUAD_READ) },
|
||||
+ { "n25q256ax1", INFO(0x20bb19, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_QUAD_READ) },
|
||||
{ "n25q512a", INFO(0x20bb20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
|
||||
{ "n25q512ax3", INFO(0x20ba20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
|
||||
- { "n25q00", INFO(0x20ba21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
|
||||
- { "n25q00a", INFO(0x20bb21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
|
||||
+ { "n25q00", INFO(0x20ba21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | NO_CHIP_ERASE) },
|
||||
+ { "n25q00a", INFO(0x20bb21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | NO_CHIP_ERASE) },
|
||||
|
||||
/* PMC */
|
||||
{ "pm25lv512", INFO(0, 0, 32 * 1024, 2, SECT_4K_PMC) },
|
||||
@@ -1061,8 +1079,11 @@ static const struct flash_info spi_nor_i
|
||||
{ "s70fl01gs", INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) },
|
||||
{ "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024, 64, 0) },
|
||||
{ "s25sl12801", INFO(0x012018, 0x0301, 64 * 1024, 256, 0) },
|
||||
- { "s25fl128s", INFO6(0x012018, 0x4d0180, 64 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
|
||||
+ { "s25fs256s1", INFO6(0x010219, 0x4d0181, 64 * 1024, 512, 0)},
|
||||
+ { "s25fl128s", INFO6(0x012018, 0x4d0180, 64 * 1024, 256, SPI_NOR_QUAD_READ
|
||||
+ | SPI_NOR_DDR_QUAD_READ) },
|
||||
{ "s25fl129p0", INFO(0x012018, 0x4d00, 256 * 1024, 64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
|
||||
+ { "s25fs512s", INFO6(0x010220, 0x4d0081, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)},
|
||||
{ "s25fl129p1", INFO(0x012018, 0x4d01, 64 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
|
||||
{ "s25sl004a", INFO(0x010212, 0, 64 * 1024, 8, 0) },
|
||||
{ "s25sl008a", INFO(0x010213, 0, 64 * 1024, 16, 0) },
|
||||
@@ -1136,7 +1157,15 @@ static const struct flash_info spi_nor_i
|
||||
{ "w25x40", INFO(0xef3013, 0, 64 * 1024, 8, SECT_4K) },
|
||||
{ "w25x80", INFO(0xef3014, 0, 64 * 1024, 16, SECT_4K) },
|
||||
{ "w25x16", INFO(0xef3015, 0, 64 * 1024, 32, SECT_4K) },
|
||||
+ {
|
||||
+ "w25q16dw", INFO(0xef6015, 0, 64 * 1024, 32,
|
||||
+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
|
||||
+ SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
|
||||
+ },
|
||||
{ "w25x32", INFO(0xef3016, 0, 64 * 1024, 64, SECT_4K) },
|
||||
+ { "w25q20cl", INFO(0xef4012, 0, 64 * 1024, 4, SECT_4K) },
|
||||
+ { "w25q20bw", INFO(0xef5012, 0, 64 * 1024, 4, SECT_4K) },
|
||||
+ { "w25q20ew", INFO(0xef6012, 0, 64 * 1024, 4, SECT_4K) },
|
||||
{ "w25q32", INFO(0xef4016, 0, 64 * 1024, 64, SECT_4K) },
|
||||
{
|
||||
"w25q32dw", INFO(0xef6016, 0, 64 * 1024, 64,
|
||||
@@ -1208,6 +1237,53 @@ static const struct flash_info *spi_nor_
|
||||
id[0], id[1], id[2]);
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
+/*
|
||||
+ * The S25FS-S family physical sectors may be configured as a
|
||||
+ * hybrid combination of eight 4-kB parameter sectors
|
||||
+ * at the top or bottom of the address space with all
|
||||
+ * but one of the remaining sectors being uniform size.
|
||||
+ * The Parameter Sector Erase commands (20h or 21h) must
|
||||
+ * be used to erase the 4-kB parameter sectors individually.
|
||||
+ * The Sector (uniform sector) Erase commands (D8h or DCh)
|
||||
+ * must be used to erase any of the remaining
|
||||
+ * sectors, including the portion of highest or lowest address
|
||||
+ * sector that is not overlaid by the parameter sectors.
|
||||
+ * The uniform sector erase command has no effect on parameter sectors.
|
||||
+ */
|
||||
+static int spansion_s25fs_disable_4kb_erase(struct spi_nor *nor)
|
||||
+{
|
||||
+ struct fsl_qspi *q;
|
||||
+ u32 cr3v_addr = SPINOR_CONFIG_REG3_OFFSET;
|
||||
+ u8 cr3v = 0x0;
|
||||
+ int ret = 0x0;
|
||||
+
|
||||
+ q = nor->priv;
|
||||
+
|
||||
+ nor->cmd_buf[2] = cr3v_addr >> 16;
|
||||
+ nor->cmd_buf[1] = cr3v_addr >> 8;
|
||||
+ nor->cmd_buf[0] = cr3v_addr >> 0;
|
||||
+
|
||||
+ ret = nor->read_reg(nor, SPINOR_OP_SPANSION_RDAR, &cr3v, 1);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ if (cr3v & CR3V_4KB_ERASE_UNABLE)
|
||||
+ return 0;
|
||||
+ ret = nor->write_reg(nor, SPINOR_OP_WREN, NULL, 0);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ cr3v = CR3V_4KB_ERASE_UNABLE;
|
||||
+ nor->program_opcode = SPINOR_OP_SPANSION_WRAR;
|
||||
+ nor->write(nor, cr3v_addr, 1, &cr3v);
|
||||
+
|
||||
+ ret = nor->read_reg(nor, SPINOR_OP_SPANSION_RDAR, &cr3v, 1);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ if (!(cr3v & CR3V_4KB_ERASE_UNABLE))
|
||||
+ return -EPERM;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
|
||||
static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len,
|
||||
size_t *retlen, u_char *buf)
|
||||
@@ -1427,7 +1503,7 @@ static int macronix_quad_enable(struct s
|
||||
* Write status Register and configuration register with 2 bytes
|
||||
* The first byte will be written to the status register, while the
|
||||
* second byte will be written to the configuration register.
|
||||
- * Return negative if error occured.
|
||||
+ * Return negative if error occurred.
|
||||
*/
|
||||
static int write_sr_cr(struct spi_nor *nor, u16 val)
|
||||
{
|
||||
@@ -1475,6 +1551,24 @@ static int spansion_quad_enable(struct s
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int set_ddr_quad_mode(struct spi_nor *nor, const struct flash_info *info)
|
||||
+{
|
||||
+ int status;
|
||||
+
|
||||
+ switch (JEDEC_MFR(info)) {
|
||||
+ case SNOR_MFR_SPANSION:
|
||||
+ status = spansion_quad_enable(nor);
|
||||
+ if (status) {
|
||||
+ dev_err(nor->dev, "Spansion DDR quad-read not enabled\n");
|
||||
+ return status;
|
||||
+ }
|
||||
+ return status;
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+
|
||||
static int set_quad_mode(struct spi_nor *nor, const struct flash_info *info)
|
||||
{
|
||||
int status;
|
||||
@@ -1621,9 +1715,25 @@ int spi_nor_scan(struct spi_nor *nor, co
|
||||
write_sr(nor, 0);
|
||||
spi_nor_wait_till_ready(nor);
|
||||
}
|
||||
+ if (JEDEC_MFR(info) == SNOR_MFR_MICRON) {
|
||||
+ ret = read_sr(nor);
|
||||
+ ret &= SPI_NOR_MICRON_WRITE_ENABLE;
|
||||
+
|
||||
+ write_enable(nor);
|
||||
+ write_sr(nor, ret);
|
||||
+ }
|
||||
+
|
||||
+ if (EXT_ID(info) == SPINOR_S25FS_FAMILY_ID) {
|
||||
+ ret = spansion_s25fs_disable_4kb_erase(nor);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
|
||||
if (!mtd->name)
|
||||
mtd->name = dev_name(dev);
|
||||
+ if (info->name)
|
||||
+ nor->vendor = info->name;
|
||||
mtd->priv = nor;
|
||||
mtd->type = MTD_NORFLASH;
|
||||
mtd->writesize = 1;
|
||||
@@ -1657,6 +1767,8 @@ int spi_nor_scan(struct spi_nor *nor, co
|
||||
nor->flags |= SNOR_F_USE_FSR;
|
||||
if (info->flags & SPI_NOR_HAS_TB)
|
||||
nor->flags |= SNOR_F_HAS_SR_TB;
|
||||
+ if (info->flags & NO_CHIP_ERASE)
|
||||
+ nor->flags |= SNOR_F_NO_OP_CHIP_ERASE;
|
||||
|
||||
#ifdef CONFIG_MTD_SPI_NOR_USE_4K_SECTORS
|
||||
/* prefer "small sector" erase if possible */
|
||||
@@ -1696,9 +1808,15 @@ int spi_nor_scan(struct spi_nor *nor, co
|
||||
/* Some devices cannot do fast-read, no matter what DT tells us */
|
||||
if (info->flags & SPI_NOR_NO_FR)
|
||||
nor->flash_read = SPI_NOR_NORMAL;
|
||||
-
|
||||
- /* Quad/Dual-read mode takes precedence over fast/normal */
|
||||
- if (mode == SPI_NOR_QUAD && info->flags & SPI_NOR_QUAD_READ) {
|
||||
+ /* DDR Quad/Quad/Dual-read mode takes precedence over fast/normal */
|
||||
+ if (mode == SPI_NOR_DDR_QUAD && info->flags & SPI_NOR_DDR_QUAD_READ) {
|
||||
+ ret = set_ddr_quad_mode(nor, info);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev, "DDR quad mode not supported\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+ nor->flash_read = SPI_NOR_DDR_QUAD;
|
||||
+ } else if (mode == SPI_NOR_QUAD && info->flags & SPI_NOR_QUAD_READ) {
|
||||
ret = set_quad_mode(nor, info);
|
||||
if (ret) {
|
||||
dev_err(dev, "quad mode not supported\n");
|
||||
@@ -1711,6 +1829,9 @@ int spi_nor_scan(struct spi_nor *nor, co
|
||||
|
||||
/* Default commands */
|
||||
switch (nor->flash_read) {
|
||||
+ case SPI_NOR_DDR_QUAD:
|
||||
+ nor->read_opcode = SPINOR_OP_READ4_1_4_4_D;
|
||||
+ break;
|
||||
case SPI_NOR_QUAD:
|
||||
nor->read_opcode = SPINOR_OP_READ_1_1_4;
|
||||
break;
|
||||
--- a/include/linux/mtd/spi-nor.h
|
||||
+++ b/include/linux/mtd/spi-nor.h
|
||||
@@ -31,10 +31,10 @@
|
||||
|
||||
/*
|
||||
* Note on opcode nomenclature: some opcodes have a format like
|
||||
- * SPINOR_OP_FUNCTION{4,}_x_y_z. The numbers x, y, and z stand for the number
|
||||
+ * SPINOR_OP_FUNCTION{4,}_x_y_z{_D}. The numbers x, y,and z stand for the number
|
||||
* of I/O lines used for the opcode, address, and data (respectively). The
|
||||
* FUNCTION has an optional suffix of '4', to represent an opcode which
|
||||
- * requires a 4-byte (32-bit) address.
|
||||
+ * requires a 4-byte (32-bit) address. The suffix of 'D' stands for the
|
||||
*/
|
||||
|
||||
/* Flash opcodes. */
|
||||
@@ -46,7 +46,9 @@
|
||||
#define SPINOR_OP_READ_1_1_2 0x3b /* Read data bytes (Dual Output SPI) */
|
||||
#define SPINOR_OP_READ_1_2_2 0xbb /* Read data bytes (Dual I/O SPI) */
|
||||
#define SPINOR_OP_READ_1_1_4 0x6b /* Read data bytes (Quad Output SPI) */
|
||||
+#define SPINOR_OP_READ_1_4_4_D 0xed /* Read data bytes (DDR Quad SPI) */
|
||||
#define SPINOR_OP_READ_1_4_4 0xeb /* Read data bytes (Quad I/O SPI) */
|
||||
+#define SPINOR_OP_READ4_1_4_4_D 0xee /* Read data bytes (DDR Quad SPI) */
|
||||
#define SPINOR_OP_PP 0x02 /* Page program (up to 256 bytes) */
|
||||
#define SPINOR_OP_PP_1_1_4 0x32 /* Quad page program */
|
||||
#define SPINOR_OP_PP_1_4_4 0x38 /* Quad page program */
|
||||
@@ -62,9 +64,11 @@
|
||||
/* 4-byte address opcodes - used on Spansion and some Macronix flashes. */
|
||||
#define SPINOR_OP_READ_4B 0x13 /* Read data bytes (low frequency) */
|
||||
#define SPINOR_OP_READ_FAST_4B 0x0c /* Read data bytes (high frequency) */
|
||||
+#define SPINOR_OP_READ4_FAST 0x0c /* Read data bytes (high frequency) */
|
||||
#define SPINOR_OP_READ_1_1_2_4B 0x3c /* Read data bytes (Dual Output SPI) */
|
||||
#define SPINOR_OP_READ_1_2_2_4B 0xbc /* Read data bytes (Dual I/O SPI) */
|
||||
#define SPINOR_OP_READ_1_1_4_4B 0x6c /* Read data bytes (Quad Output SPI) */
|
||||
+#define SPINOR_OP_READ4_1_1_4 0x6c /* Read data bytes (Quad SPI) */
|
||||
#define SPINOR_OP_READ_1_4_4_4B 0xec /* Read data bytes (Quad I/O SPI) */
|
||||
#define SPINOR_OP_PP_4B 0x12 /* Page program (up to 256 bytes) */
|
||||
#define SPINOR_OP_PP_1_1_4_4B 0x34 /* Quad page program */
|
||||
@@ -94,6 +98,10 @@
|
||||
/* Used for Spansion flashes only. */
|
||||
#define SPINOR_OP_BRWR 0x17 /* Bank register write */
|
||||
|
||||
+/* Used for Spansion S25FS-S family flash only. */
|
||||
+#define SPINOR_OP_SPANSION_RDAR 0x65 /* Read any device register */
|
||||
+#define SPINOR_OP_SPANSION_WRAR 0x71 /* Write any device register */
|
||||
+
|
||||
/* Used for Micron flashes only. */
|
||||
#define SPINOR_OP_RD_EVCR 0x65 /* Read EVCR register */
|
||||
#define SPINOR_OP_WD_EVCR 0x61 /* Write EVCR register */
|
||||
@@ -124,6 +132,7 @@ enum read_mode {
|
||||
SPI_NOR_FAST,
|
||||
SPI_NOR_DUAL,
|
||||
SPI_NOR_QUAD,
|
||||
+ SPI_NOR_DDR_QUAD,
|
||||
};
|
||||
|
||||
#define SPI_NOR_MAX_CMD_SIZE 8
|
||||
@@ -189,6 +198,7 @@ struct spi_nor {
|
||||
bool sst_write_second;
|
||||
u32 flags;
|
||||
u8 cmd_buf[SPI_NOR_MAX_CMD_SIZE];
|
||||
+ char *vendor;
|
||||
|
||||
int (*prepare)(struct spi_nor *nor, enum spi_nor_ops ops);
|
||||
void (*unprepare)(struct spi_nor *nor, enum spi_nor_ops ops);
|
@ -1,392 +0,0 @@
|
||||
From d9d0181f74146507026c31cccd52dda27ec3d966 Mon Sep 17 00:00:00 2001
|
||||
From: Yangbo Lu <yangbo.lu@nxp.com>
|
||||
Date: Wed, 17 Jan 2018 14:57:31 +0800
|
||||
Subject: [PATCH 06/30] mtd: support layerscape
|
||||
|
||||
This is an integrated patch for layerscape ifc-nor-nand support.
|
||||
|
||||
Signed-off-by: Alison Wang <b18965@freescale.com>
|
||||
Signed-off-by: Prabhakar Kushwaha <prabhakar.kushwaha@nxp.com>
|
||||
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
|
||||
---
|
||||
drivers/memory/Kconfig | 2 +-
|
||||
drivers/memory/fsl_ifc.c | 263 ++++++++++++++++++++++++++++++++++++++++
|
||||
drivers/mtd/maps/physmap_of.c | 4 +
|
||||
drivers/mtd/nand/Kconfig | 2 +-
|
||||
drivers/mtd/nand/fsl_ifc_nand.c | 5 +-
|
||||
include/linux/fsl_ifc.h | 7 ++
|
||||
6 files changed, 280 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/drivers/memory/Kconfig
|
||||
+++ b/drivers/memory/Kconfig
|
||||
@@ -115,7 +115,7 @@ config FSL_CORENET_CF
|
||||
|
||||
config FSL_IFC
|
||||
bool
|
||||
- depends on FSL_SOC || ARCH_LAYERSCAPE
|
||||
+ depends on FSL_SOC || ARCH_LAYERSCAPE || SOC_LS1021A
|
||||
|
||||
config JZ4780_NEMC
|
||||
bool "Ingenic JZ4780 SoC NEMC driver"
|
||||
--- a/drivers/memory/fsl_ifc.c
|
||||
+++ b/drivers/memory/fsl_ifc.c
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/spinlock.h>
|
||||
+#include <linux/delay.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/io.h>
|
||||
@@ -37,6 +38,8 @@
|
||||
|
||||
struct fsl_ifc_ctrl *fsl_ifc_ctrl_dev;
|
||||
EXPORT_SYMBOL(fsl_ifc_ctrl_dev);
|
||||
+#define FSL_IFC_V1_3_0 0x01030000
|
||||
+#define IFC_TIMEOUT_MSECS 1000 /* 1000ms */
|
||||
|
||||
/*
|
||||
* convert_ifc_address - convert the base address
|
||||
@@ -311,6 +314,261 @@ err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_PM_SLEEP
|
||||
+/* save ifc registers */
|
||||
+static int fsl_ifc_suspend(struct device *dev)
|
||||
+{
|
||||
+ struct fsl_ifc_ctrl *ctrl = dev_get_drvdata(dev);
|
||||
+ struct fsl_ifc_global __iomem *fcm = ctrl->gregs;
|
||||
+ struct fsl_ifc_runtime __iomem *runtime = ctrl->rregs;
|
||||
+ __be32 nand_evter_intr_en, cm_evter_intr_en, nor_evter_intr_en,
|
||||
+ gpcm_evter_intr_en;
|
||||
+ uint32_t ifc_bank, i;
|
||||
+
|
||||
+ ctrl->saved_gregs = kzalloc(sizeof(struct fsl_ifc_global), GFP_KERNEL);
|
||||
+ if (!ctrl->saved_gregs)
|
||||
+ return -ENOMEM;
|
||||
+ ctrl->saved_rregs = kzalloc(sizeof(struct fsl_ifc_runtime), GFP_KERNEL);
|
||||
+ if (!ctrl->saved_rregs)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ cm_evter_intr_en = ifc_in32(&fcm->cm_evter_intr_en);
|
||||
+ nand_evter_intr_en = ifc_in32(&runtime->ifc_nand.nand_evter_intr_en);
|
||||
+ nor_evter_intr_en = ifc_in32(&runtime->ifc_nor.nor_evter_intr_en);
|
||||
+ gpcm_evter_intr_en = ifc_in32(&runtime->ifc_gpcm.gpcm_evter_intr_en);
|
||||
+
|
||||
+/* IFC interrupts disabled */
|
||||
+
|
||||
+ ifc_out32(0x0, &fcm->cm_evter_intr_en);
|
||||
+ ifc_out32(0x0, &runtime->ifc_nand.nand_evter_intr_en);
|
||||
+ ifc_out32(0x0, &runtime->ifc_nor.nor_evter_intr_en);
|
||||
+ ifc_out32(0x0, &runtime->ifc_gpcm.gpcm_evter_intr_en);
|
||||
+
|
||||
+ if (ctrl->saved_gregs) {
|
||||
+ for (ifc_bank = 0; ifc_bank < FSL_IFC_BANK_COUNT; ifc_bank++) {
|
||||
+ ctrl->saved_gregs->cspr_cs[ifc_bank].cspr_ext =
|
||||
+ ifc_in32(&fcm->cspr_cs[ifc_bank].cspr_ext);
|
||||
+ ctrl->saved_gregs->cspr_cs[ifc_bank].cspr =
|
||||
+ ifc_in32(&fcm->cspr_cs[ifc_bank].cspr);
|
||||
+ ctrl->saved_gregs->amask_cs[ifc_bank].amask =
|
||||
+ ifc_in32(&fcm->amask_cs[ifc_bank].amask);
|
||||
+ ctrl->saved_gregs->csor_cs[ifc_bank].csor_ext =
|
||||
+ ifc_in32(&fcm->csor_cs[ifc_bank].csor_ext);
|
||||
+ ctrl->saved_gregs->csor_cs[ifc_bank].csor =
|
||||
+ ifc_in32(&fcm->csor_cs[ifc_bank].csor);
|
||||
+ for (i = 0; i < 4; i++) {
|
||||
+ ctrl->saved_gregs->ftim_cs[ifc_bank].ftim[i] =
|
||||
+ ifc_in32(
|
||||
+ &fcm->ftim_cs[ifc_bank].ftim[i]);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ ctrl->saved_gregs->rb_map = ifc_in32(&fcm->rb_map);
|
||||
+ ctrl->saved_gregs->wb_map = ifc_in32(&fcm->wb_map);
|
||||
+ ctrl->saved_gregs->ifc_gcr = ifc_in32(&fcm->ifc_gcr);
|
||||
+ ctrl->saved_gregs->ddr_ccr_low = ifc_in32(&fcm->ddr_ccr_low);
|
||||
+ ctrl->saved_gregs->cm_evter_en = ifc_in32(&fcm->cm_evter_en);
|
||||
+ }
|
||||
+
|
||||
+ if (ctrl->saved_rregs) {
|
||||
+ /* IFC controller NAND machine registers */
|
||||
+ ctrl->saved_rregs->ifc_nand.ncfgr =
|
||||
+ ifc_in32(&runtime->ifc_nand.ncfgr);
|
||||
+ ctrl->saved_rregs->ifc_nand.nand_fcr0 =
|
||||
+ ifc_in32(&runtime->ifc_nand.nand_fcr0);
|
||||
+ ctrl->saved_rregs->ifc_nand.nand_fcr1 =
|
||||
+ ifc_in32(&runtime->ifc_nand.nand_fcr1);
|
||||
+ ctrl->saved_rregs->ifc_nand.row0 =
|
||||
+ ifc_in32(&runtime->ifc_nand.row0);
|
||||
+ ctrl->saved_rregs->ifc_nand.row1 =
|
||||
+ ifc_in32(&runtime->ifc_nand.row1);
|
||||
+ ctrl->saved_rregs->ifc_nand.col0 =
|
||||
+ ifc_in32(&runtime->ifc_nand.col0);
|
||||
+ ctrl->saved_rregs->ifc_nand.col1 =
|
||||
+ ifc_in32(&runtime->ifc_nand.col1);
|
||||
+ ctrl->saved_rregs->ifc_nand.row2 =
|
||||
+ ifc_in32(&runtime->ifc_nand.row2);
|
||||
+ ctrl->saved_rregs->ifc_nand.col2 =
|
||||
+ ifc_in32(&runtime->ifc_nand.col2);
|
||||
+ ctrl->saved_rregs->ifc_nand.row3 =
|
||||
+ ifc_in32(&runtime->ifc_nand.row3);
|
||||
+ ctrl->saved_rregs->ifc_nand.col3 =
|
||||
+ ifc_in32(&runtime->ifc_nand.col3);
|
||||
+
|
||||
+ ctrl->saved_rregs->ifc_nand.nand_fbcr =
|
||||
+ ifc_in32(&runtime->ifc_nand.nand_fbcr);
|
||||
+ ctrl->saved_rregs->ifc_nand.nand_fir0 =
|
||||
+ ifc_in32(&runtime->ifc_nand.nand_fir0);
|
||||
+ ctrl->saved_rregs->ifc_nand.nand_fir1 =
|
||||
+ ifc_in32(&runtime->ifc_nand.nand_fir1);
|
||||
+ ctrl->saved_rregs->ifc_nand.nand_fir2 =
|
||||
+ ifc_in32(&runtime->ifc_nand.nand_fir2);
|
||||
+ ctrl->saved_rregs->ifc_nand.nand_csel =
|
||||
+ ifc_in32(&runtime->ifc_nand.nand_csel);
|
||||
+ ctrl->saved_rregs->ifc_nand.nandseq_strt =
|
||||
+ ifc_in32(
|
||||
+ &runtime->ifc_nand.nandseq_strt);
|
||||
+ ctrl->saved_rregs->ifc_nand.nand_evter_en =
|
||||
+ ifc_in32(
|
||||
+ &runtime->ifc_nand.nand_evter_en);
|
||||
+ ctrl->saved_rregs->ifc_nand.nanndcr =
|
||||
+ ifc_in32(&runtime->ifc_nand.nanndcr);
|
||||
+ ctrl->saved_rregs->ifc_nand.nand_dll_lowcfg0 =
|
||||
+ ifc_in32(
|
||||
+ &runtime->ifc_nand.nand_dll_lowcfg0);
|
||||
+ ctrl->saved_rregs->ifc_nand.nand_dll_lowcfg1 =
|
||||
+ ifc_in32(
|
||||
+ &runtime->ifc_nand.nand_dll_lowcfg1);
|
||||
+
|
||||
+ /* IFC controller NOR machine registers */
|
||||
+ ctrl->saved_rregs->ifc_nor.nor_evter_en =
|
||||
+ ifc_in32(
|
||||
+ &runtime->ifc_nor.nor_evter_en);
|
||||
+ ctrl->saved_rregs->ifc_nor.norcr =
|
||||
+ ifc_in32(&runtime->ifc_nor.norcr);
|
||||
+
|
||||
+ /* IFC controller GPCM Machine registers */
|
||||
+ ctrl->saved_rregs->ifc_gpcm.gpcm_evter_en =
|
||||
+ ifc_in32(
|
||||
+ &runtime->ifc_gpcm.gpcm_evter_en);
|
||||
+ }
|
||||
+
|
||||
+/* save the interrupt values */
|
||||
+ ctrl->saved_gregs->cm_evter_intr_en = cm_evter_intr_en;
|
||||
+ ctrl->saved_rregs->ifc_nand.nand_evter_intr_en = nand_evter_intr_en;
|
||||
+ ctrl->saved_rregs->ifc_nor.nor_evter_intr_en = nor_evter_intr_en;
|
||||
+ ctrl->saved_rregs->ifc_gpcm.gpcm_evter_intr_en = gpcm_evter_intr_en;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/* restore ifc registers */
|
||||
+static int fsl_ifc_resume(struct device *dev)
|
||||
+{
|
||||
+ struct fsl_ifc_ctrl *ctrl = dev_get_drvdata(dev);
|
||||
+ struct fsl_ifc_global __iomem *fcm = ctrl->gregs;
|
||||
+ struct fsl_ifc_runtime __iomem *runtime = ctrl->rregs;
|
||||
+ struct fsl_ifc_global *savd_gregs = ctrl->saved_gregs;
|
||||
+ struct fsl_ifc_runtime *savd_rregs = ctrl->saved_rregs;
|
||||
+ uint32_t ver = 0, ncfgr, timeout, ifc_bank, i;
|
||||
+
|
||||
+/*
|
||||
+ * IFC interrupts disabled
|
||||
+ */
|
||||
+ ifc_out32(0x0, &fcm->cm_evter_intr_en);
|
||||
+ ifc_out32(0x0, &runtime->ifc_nand.nand_evter_intr_en);
|
||||
+ ifc_out32(0x0, &runtime->ifc_nor.nor_evter_intr_en);
|
||||
+ ifc_out32(0x0, &runtime->ifc_gpcm.gpcm_evter_intr_en);
|
||||
+
|
||||
+
|
||||
+ if (ctrl->saved_gregs) {
|
||||
+ for (ifc_bank = 0; ifc_bank < FSL_IFC_BANK_COUNT; ifc_bank++) {
|
||||
+ ifc_out32(savd_gregs->cspr_cs[ifc_bank].cspr_ext,
|
||||
+ &fcm->cspr_cs[ifc_bank].cspr_ext);
|
||||
+ ifc_out32(savd_gregs->cspr_cs[ifc_bank].cspr,
|
||||
+ &fcm->cspr_cs[ifc_bank].cspr);
|
||||
+ ifc_out32(savd_gregs->amask_cs[ifc_bank].amask,
|
||||
+ &fcm->amask_cs[ifc_bank].amask);
|
||||
+ ifc_out32(savd_gregs->csor_cs[ifc_bank].csor_ext,
|
||||
+ &fcm->csor_cs[ifc_bank].csor_ext);
|
||||
+ ifc_out32(savd_gregs->csor_cs[ifc_bank].csor,
|
||||
+ &fcm->csor_cs[ifc_bank].csor);
|
||||
+ for (i = 0; i < 4; i++) {
|
||||
+ ifc_out32(savd_gregs->ftim_cs[ifc_bank].ftim[i],
|
||||
+ &fcm->ftim_cs[ifc_bank].ftim[i]);
|
||||
+ }
|
||||
+ }
|
||||
+ ifc_out32(savd_gregs->rb_map, &fcm->rb_map);
|
||||
+ ifc_out32(savd_gregs->wb_map, &fcm->wb_map);
|
||||
+ ifc_out32(savd_gregs->ifc_gcr, &fcm->ifc_gcr);
|
||||
+ ifc_out32(savd_gregs->ddr_ccr_low, &fcm->ddr_ccr_low);
|
||||
+ ifc_out32(savd_gregs->cm_evter_en, &fcm->cm_evter_en);
|
||||
+ }
|
||||
+
|
||||
+ if (ctrl->saved_rregs) {
|
||||
+ /* IFC controller NAND machine registers */
|
||||
+ ifc_out32(savd_rregs->ifc_nand.ncfgr,
|
||||
+ &runtime->ifc_nand.ncfgr);
|
||||
+ ifc_out32(savd_rregs->ifc_nand.nand_fcr0,
|
||||
+ &runtime->ifc_nand.nand_fcr0);
|
||||
+ ifc_out32(savd_rregs->ifc_nand.nand_fcr1,
|
||||
+ &runtime->ifc_nand.nand_fcr1);
|
||||
+ ifc_out32(savd_rregs->ifc_nand.row0, &runtime->ifc_nand.row0);
|
||||
+ ifc_out32(savd_rregs->ifc_nand.row1, &runtime->ifc_nand.row1);
|
||||
+ ifc_out32(savd_rregs->ifc_nand.col0, &runtime->ifc_nand.col0);
|
||||
+ ifc_out32(savd_rregs->ifc_nand.col1, &runtime->ifc_nand.col1);
|
||||
+ ifc_out32(savd_rregs->ifc_nand.row2, &runtime->ifc_nand.row2);
|
||||
+ ifc_out32(savd_rregs->ifc_nand.col2, &runtime->ifc_nand.col2);
|
||||
+ ifc_out32(savd_rregs->ifc_nand.row3, &runtime->ifc_nand.row3);
|
||||
+ ifc_out32(savd_rregs->ifc_nand.col3, &runtime->ifc_nand.col3);
|
||||
+ ifc_out32(savd_rregs->ifc_nand.nand_fbcr,
|
||||
+ &runtime->ifc_nand.nand_fbcr);
|
||||
+ ifc_out32(savd_rregs->ifc_nand.nand_fir0,
|
||||
+ &runtime->ifc_nand.nand_fir0);
|
||||
+ ifc_out32(savd_rregs->ifc_nand.nand_fir1,
|
||||
+ &runtime->ifc_nand.nand_fir1);
|
||||
+ ifc_out32(savd_rregs->ifc_nand.nand_fir2,
|
||||
+ &runtime->ifc_nand.nand_fir2);
|
||||
+ ifc_out32(savd_rregs->ifc_nand.nand_csel,
|
||||
+ &runtime->ifc_nand.nand_csel);
|
||||
+ ifc_out32(savd_rregs->ifc_nand.nandseq_strt,
|
||||
+ &runtime->ifc_nand.nandseq_strt);
|
||||
+ ifc_out32(savd_rregs->ifc_nand.nand_evter_en,
|
||||
+ &runtime->ifc_nand.nand_evter_en);
|
||||
+ ifc_out32(savd_rregs->ifc_nand.nanndcr,
|
||||
+ &runtime->ifc_nand.nanndcr);
|
||||
+ ifc_out32(savd_rregs->ifc_nand.nand_dll_lowcfg0,
|
||||
+ &runtime->ifc_nand.nand_dll_lowcfg0);
|
||||
+ ifc_out32(savd_rregs->ifc_nand.nand_dll_lowcfg1,
|
||||
+ &runtime->ifc_nand.nand_dll_lowcfg1);
|
||||
+
|
||||
+ /* IFC controller NOR machine registers */
|
||||
+ ifc_out32(savd_rregs->ifc_nor.nor_evter_en,
|
||||
+ &runtime->ifc_nor.nor_evter_en);
|
||||
+ ifc_out32(savd_rregs->ifc_nor.norcr, &runtime->ifc_nor.norcr);
|
||||
+
|
||||
+ /* IFC controller GPCM Machine registers */
|
||||
+ ifc_out32(savd_rregs->ifc_gpcm.gpcm_evter_en,
|
||||
+ &runtime->ifc_gpcm.gpcm_evter_en);
|
||||
+
|
||||
+ /* IFC interrupts enabled */
|
||||
+ ifc_out32(ctrl->saved_gregs->cm_evter_intr_en,
|
||||
+ &fcm->cm_evter_intr_en);
|
||||
+ ifc_out32(ctrl->saved_rregs->ifc_nand.nand_evter_intr_en,
|
||||
+ &runtime->ifc_nand.nand_evter_intr_en);
|
||||
+ ifc_out32(ctrl->saved_rregs->ifc_nor.nor_evter_intr_en,
|
||||
+ &runtime->ifc_nor.nor_evter_intr_en);
|
||||
+ ifc_out32(ctrl->saved_rregs->ifc_gpcm.gpcm_evter_intr_en,
|
||||
+ &runtime->ifc_gpcm.gpcm_evter_intr_en);
|
||||
+
|
||||
+ kfree(ctrl->saved_gregs);
|
||||
+ kfree(ctrl->saved_rregs);
|
||||
+ ctrl->saved_gregs = NULL;
|
||||
+ ctrl->saved_rregs = NULL;
|
||||
+ }
|
||||
+
|
||||
+ ver = ifc_in32(&fcm->ifc_rev);
|
||||
+ ncfgr = ifc_in32(&runtime->ifc_nand.ncfgr);
|
||||
+ if (ver >= FSL_IFC_V1_3_0) {
|
||||
+
|
||||
+ ifc_out32(ncfgr | IFC_NAND_SRAM_INIT_EN,
|
||||
+ &runtime->ifc_nand.ncfgr);
|
||||
+ /* wait for SRAM_INIT bit to be clear or timeout */
|
||||
+ timeout = 10;
|
||||
+ while ((ifc_in32(&runtime->ifc_nand.ncfgr) &
|
||||
+ IFC_NAND_SRAM_INIT_EN) && timeout) {
|
||||
+ mdelay(IFC_TIMEOUT_MSECS);
|
||||
+ timeout--;
|
||||
+ }
|
||||
+
|
||||
+ if (!timeout)
|
||||
+ dev_err(ctrl->dev, "Timeout waiting for IFC SRAM INIT");
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+#endif /* CONFIG_PM_SLEEP */
|
||||
+
|
||||
static const struct of_device_id fsl_ifc_match[] = {
|
||||
{
|
||||
.compatible = "fsl,ifc",
|
||||
@@ -318,10 +576,15 @@ static const struct of_device_id fsl_ifc
|
||||
{},
|
||||
};
|
||||
|
||||
+static const struct dev_pm_ops ifc_pm_ops = {
|
||||
+ SET_SYSTEM_SLEEP_PM_OPS(fsl_ifc_suspend, fsl_ifc_resume)
|
||||
+};
|
||||
+
|
||||
static struct platform_driver fsl_ifc_ctrl_driver = {
|
||||
.driver = {
|
||||
.name = "fsl-ifc",
|
||||
.of_match_table = fsl_ifc_match,
|
||||
+ .pm = &ifc_pm_ops,
|
||||
},
|
||||
.probe = fsl_ifc_ctrl_probe,
|
||||
.remove = fsl_ifc_ctrl_remove,
|
||||
--- a/drivers/mtd/maps/physmap_of.c
|
||||
+++ b/drivers/mtd/maps/physmap_of.c
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <linux/mtd/map.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
#include <linux/mtd/concat.h>
|
||||
+#include <linux/mtd/cfi_endian.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_platform.h>
|
||||
@@ -209,6 +210,9 @@ static int of_flash_probe(struct platfor
|
||||
return err;
|
||||
}
|
||||
|
||||
+ if (of_property_read_bool(dp->parent, "big-endian"))
|
||||
+ info->list[i].map.swap = CFI_BIG_ENDIAN;
|
||||
+
|
||||
err = -ENOMEM;
|
||||
info->list[i].map.virt = ioremap(info->list[i].map.phys,
|
||||
info->list[i].map.size);
|
||||
--- a/drivers/mtd/nand/Kconfig
|
||||
+++ b/drivers/mtd/nand/Kconfig
|
||||
@@ -438,7 +438,7 @@ config MTD_NAND_FSL_ELBC
|
||||
|
||||
config MTD_NAND_FSL_IFC
|
||||
tristate "NAND support for Freescale IFC controller"
|
||||
- depends on FSL_SOC || ARCH_LAYERSCAPE
|
||||
+ depends on FSL_SOC || ARCH_LAYERSCAPE || SOC_LS1021A
|
||||
select FSL_IFC
|
||||
select MEMORY
|
||||
help
|
||||
--- a/drivers/mtd/nand/fsl_ifc_nand.c
|
||||
+++ b/drivers/mtd/nand/fsl_ifc_nand.c
|
||||
@@ -901,7 +901,7 @@ static int fsl_ifc_chip_init(struct fsl_
|
||||
chip->ecc.algo = NAND_ECC_HAMMING;
|
||||
}
|
||||
|
||||
- if (ctrl->version == FSL_IFC_VERSION_1_1_0)
|
||||
+ if (ctrl->version >= FSL_IFC_VERSION_1_1_0)
|
||||
fsl_ifc_sram_init(priv);
|
||||
|
||||
/*
|
||||
--- a/include/linux/fsl_ifc.h
|
||||
+++ b/include/linux/fsl_ifc.h
|
||||
@@ -274,6 +274,8 @@
|
||||
*/
|
||||
/* Auto Boot Mode */
|
||||
#define IFC_NAND_NCFGR_BOOT 0x80000000
|
||||
+/* SRAM INIT EN */
|
||||
+#define IFC_NAND_SRAM_INIT_EN 0x20000000
|
||||
/* Addressing Mode-ROW0+n/COL0 */
|
||||
#define IFC_NAND_NCFGR_ADDR_MODE_RC0 0x00000000
|
||||
/* Addressing Mode-ROW0+n/COL0+n */
|
||||
@@ -857,6 +859,11 @@ struct fsl_ifc_ctrl {
|
||||
u32 nand_stat;
|
||||
wait_queue_head_t nand_wait;
|
||||
bool little_endian;
|
||||
+#ifdef CONFIG_PM_SLEEP
|
||||
+ /*save regs when system goes to deep sleep*/
|
||||
+ struct fsl_ifc_global *saved_gregs;
|
||||
+ struct fsl_ifc_runtime *saved_rregs;
|
||||
+#endif
|
||||
};
|
||||
|
||||
extern struct fsl_ifc_ctrl *fsl_ifc_ctrl_dev;
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,144 +0,0 @@
|
||||
From 4c3979602db05bca439bfc98db88dc14a8663db0 Mon Sep 17 00:00:00 2001
|
||||
From: Yangbo Lu <yangbo.lu@nxp.com>
|
||||
Date: Wed, 17 Jan 2018 15:14:57 +0800
|
||||
Subject: [PATCH 13/30] ata: support layerscape
|
||||
|
||||
This is an integrated patch for layerscape sata support.
|
||||
|
||||
Signed-off-by: Tang Yuantian <Yuantian.Tang@nxp.com>
|
||||
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
|
||||
---
|
||||
drivers/ata/ahci_qoriq.c | 63 ++++++++++++++++++++++++++++++++++++++++++------
|
||||
1 file changed, 56 insertions(+), 7 deletions(-)
|
||||
|
||||
--- a/drivers/ata/ahci_qoriq.c
|
||||
+++ b/drivers/ata/ahci_qoriq.c
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Freescale QorIQ AHCI SATA platform driver
|
||||
*
|
||||
- * Copyright 2015 Freescale, Inc.
|
||||
+ * Copyright (C) 2015 Freescale Semiconductor, Inc.
|
||||
* Tang Yuantian <Yuantian.Tang@freescale.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -46,23 +46,32 @@
|
||||
#define LS1021A_AXICC_ADDR 0xC0
|
||||
|
||||
#define SATA_ECC_DISABLE 0x00020000
|
||||
+#define ECC_DIS_ARMV8_CH2 0x80000000
|
||||
+#define ECC_DIS_LS1088A 0x40000000
|
||||
|
||||
enum ahci_qoriq_type {
|
||||
AHCI_LS1021A,
|
||||
AHCI_LS1043A,
|
||||
AHCI_LS2080A,
|
||||
+ AHCI_LS1046A,
|
||||
+ AHCI_LS1088A,
|
||||
+ AHCI_LS2088A,
|
||||
};
|
||||
|
||||
struct ahci_qoriq_priv {
|
||||
struct ccsr_ahci *reg_base;
|
||||
enum ahci_qoriq_type type;
|
||||
void __iomem *ecc_addr;
|
||||
+ bool is_dmacoherent;
|
||||
};
|
||||
|
||||
static const struct of_device_id ahci_qoriq_of_match[] = {
|
||||
{ .compatible = "fsl,ls1021a-ahci", .data = (void *)AHCI_LS1021A},
|
||||
{ .compatible = "fsl,ls1043a-ahci", .data = (void *)AHCI_LS1043A},
|
||||
{ .compatible = "fsl,ls2080a-ahci", .data = (void *)AHCI_LS2080A},
|
||||
+ { .compatible = "fsl,ls1046a-ahci", .data = (void *)AHCI_LS1046A},
|
||||
+ { .compatible = "fsl,ls1088a-ahci", .data = (void *)AHCI_LS1088A},
|
||||
+ { .compatible = "fsl,ls2088a-ahci", .data = (void *)AHCI_LS2088A},
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, ahci_qoriq_of_match);
|
||||
@@ -154,6 +163,8 @@ static int ahci_qoriq_phy_init(struct ah
|
||||
|
||||
switch (qpriv->type) {
|
||||
case AHCI_LS1021A:
|
||||
+ if (!qpriv->ecc_addr)
|
||||
+ return -EINVAL;
|
||||
writel(SATA_ECC_DISABLE, qpriv->ecc_addr);
|
||||
writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
|
||||
writel(LS1021A_PORT_PHY2, reg_base + PORT_PHY2);
|
||||
@@ -161,19 +172,56 @@ static int ahci_qoriq_phy_init(struct ah
|
||||
writel(LS1021A_PORT_PHY4, reg_base + PORT_PHY4);
|
||||
writel(LS1021A_PORT_PHY5, reg_base + PORT_PHY5);
|
||||
writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS);
|
||||
- writel(AHCI_PORT_AXICC_CFG, reg_base + LS1021A_AXICC_ADDR);
|
||||
+ if (qpriv->is_dmacoherent)
|
||||
+ writel(AHCI_PORT_AXICC_CFG,
|
||||
+ reg_base + LS1021A_AXICC_ADDR);
|
||||
break;
|
||||
|
||||
case AHCI_LS1043A:
|
||||
+ if (!qpriv->ecc_addr)
|
||||
+ return -EINVAL;
|
||||
+ writel(readl(qpriv->ecc_addr) | ECC_DIS_ARMV8_CH2,
|
||||
+ qpriv->ecc_addr);
|
||||
writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
|
||||
writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS);
|
||||
- writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
|
||||
+ if (qpriv->is_dmacoherent)
|
||||
+ writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
|
||||
break;
|
||||
|
||||
case AHCI_LS2080A:
|
||||
writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
|
||||
writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS);
|
||||
- writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
|
||||
+ if (qpriv->is_dmacoherent)
|
||||
+ writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
|
||||
+ break;
|
||||
+
|
||||
+ case AHCI_LS1046A:
|
||||
+ if (!qpriv->ecc_addr)
|
||||
+ return -EINVAL;
|
||||
+ writel(readl(qpriv->ecc_addr) | ECC_DIS_ARMV8_CH2,
|
||||
+ qpriv->ecc_addr);
|
||||
+ writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
|
||||
+ writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS);
|
||||
+ if (qpriv->is_dmacoherent)
|
||||
+ writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
|
||||
+ break;
|
||||
+
|
||||
+ case AHCI_LS1088A:
|
||||
+ if (!qpriv->ecc_addr)
|
||||
+ return -EINVAL;
|
||||
+ writel(readl(qpriv->ecc_addr) | ECC_DIS_LS1088A,
|
||||
+ qpriv->ecc_addr);
|
||||
+ writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
|
||||
+ writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS);
|
||||
+ if (qpriv->is_dmacoherent)
|
||||
+ writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
|
||||
+ break;
|
||||
+
|
||||
+ case AHCI_LS2088A:
|
||||
+ writel(AHCI_PORT_PHY_1_CFG, reg_base + PORT_PHY1);
|
||||
+ writel(AHCI_PORT_TRANS_CFG, reg_base + PORT_TRANS);
|
||||
+ if (qpriv->is_dmacoherent)
|
||||
+ writel(AHCI_PORT_AXICC_CFG, reg_base + PORT_AXICC);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -204,13 +252,14 @@ static int ahci_qoriq_probe(struct platf
|
||||
|
||||
qoriq_priv->type = (enum ahci_qoriq_type)of_id->data;
|
||||
|
||||
- if (qoriq_priv->type == AHCI_LS1021A) {
|
||||
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
|
||||
- "sata-ecc");
|
||||
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
|
||||
+ "sata-ecc");
|
||||
+ if (res) {
|
||||
qoriq_priv->ecc_addr = devm_ioremap_resource(dev, res);
|
||||
if (IS_ERR(qoriq_priv->ecc_addr))
|
||||
return PTR_ERR(qoriq_priv->ecc_addr);
|
||||
}
|
||||
+ qoriq_priv->is_dmacoherent = of_dma_is_coherent(np);
|
||||
|
||||
rc = ahci_platform_enable_resources(hpriv);
|
||||
if (rc)
|
@ -1,323 +0,0 @@
|
||||
From 82a391a067491f4c46b75d0dfe2bf9e5a11aca8e Mon Sep 17 00:00:00 2001
|
||||
From: Yangbo Lu <yangbo.lu@nxp.com>
|
||||
Date: Wed, 17 Jan 2018 15:15:44 +0800
|
||||
Subject: [PATCH 14/30] clk: support layerscape
|
||||
|
||||
This is an integrated patch for layerscape clock support.
|
||||
|
||||
Signed-off-by: Yuantian Tang <andy.tang@nxp.com>
|
||||
Signed-off-by: Mingkai Hu <mingkai.hu@nxp.com>
|
||||
Signed-off-by: Scott Wood <oss@buserror.net>
|
||||
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
|
||||
---
|
||||
drivers/clk/clk-qoriq.c | 179 ++++++++++++++++++++++++++++++++++++++++++++----
|
||||
1 file changed, 164 insertions(+), 15 deletions(-)
|
||||
|
||||
--- a/drivers/clk/clk-qoriq.c
|
||||
+++ b/drivers/clk/clk-qoriq.c
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
+#include <linux/clkdev.h>
|
||||
#include <linux/fsl/guts.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/kernel.h>
|
||||
@@ -40,7 +41,7 @@ struct clockgen_pll_div {
|
||||
};
|
||||
|
||||
struct clockgen_pll {
|
||||
- struct clockgen_pll_div div[4];
|
||||
+ struct clockgen_pll_div div[8];
|
||||
};
|
||||
|
||||
#define CLKSEL_VALID 1
|
||||
@@ -87,7 +88,7 @@ struct clockgen {
|
||||
struct device_node *node;
|
||||
void __iomem *regs;
|
||||
struct clockgen_chipinfo info; /* mutable copy */
|
||||
- struct clk *sysclk;
|
||||
+ struct clk *sysclk, *coreclk;
|
||||
struct clockgen_pll pll[6];
|
||||
struct clk *cmux[NUM_CMUX];
|
||||
struct clk *hwaccel[NUM_HWACCEL];
|
||||
@@ -266,6 +267,39 @@ static const struct clockgen_muxinfo ls1
|
||||
},
|
||||
};
|
||||
|
||||
+static const struct clockgen_muxinfo ls1046a_hwa1 = {
|
||||
+ {
|
||||
+ {},
|
||||
+ {},
|
||||
+ { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 },
|
||||
+ { CLKSEL_VALID, CGA_PLL1, PLL_DIV3 },
|
||||
+ { CLKSEL_VALID, CGA_PLL1, PLL_DIV4 },
|
||||
+ { CLKSEL_VALID, PLATFORM_PLL, PLL_DIV1 },
|
||||
+ { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 },
|
||||
+ { CLKSEL_VALID, CGA_PLL2, PLL_DIV3 },
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static const struct clockgen_muxinfo ls1046a_hwa2 = {
|
||||
+ {
|
||||
+ {},
|
||||
+ { CLKSEL_VALID, CGA_PLL2, PLL_DIV1 },
|
||||
+ { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 },
|
||||
+ { CLKSEL_VALID, CGA_PLL2, PLL_DIV3 },
|
||||
+ {},
|
||||
+ {},
|
||||
+ { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 },
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static const struct clockgen_muxinfo ls1012a_cmux = {
|
||||
+ {
|
||||
+ [0] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 },
|
||||
+ {},
|
||||
+ [2] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 },
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
static const struct clockgen_muxinfo t1023_hwa1 = {
|
||||
{
|
||||
{},
|
||||
@@ -489,6 +523,42 @@ static const struct clockgen_chipinfo ch
|
||||
.flags = CG_PLL_8BIT,
|
||||
},
|
||||
{
|
||||
+ .compat = "fsl,ls1046a-clockgen",
|
||||
+ .init_periph = t2080_init_periph,
|
||||
+ .cmux_groups = {
|
||||
+ &t1040_cmux
|
||||
+ },
|
||||
+ .hwaccel = {
|
||||
+ &ls1046a_hwa1, &ls1046a_hwa2
|
||||
+ },
|
||||
+ .cmux_to_group = {
|
||||
+ 0, -1
|
||||
+ },
|
||||
+ .pll_mask = 0x07,
|
||||
+ .flags = CG_PLL_8BIT,
|
||||
+ },
|
||||
+ {
|
||||
+ .compat = "fsl,ls1088a-clockgen",
|
||||
+ .cmux_groups = {
|
||||
+ &clockgen2_cmux_cga12
|
||||
+ },
|
||||
+ .cmux_to_group = {
|
||||
+ 0, 0, -1
|
||||
+ },
|
||||
+ .pll_mask = 0x07,
|
||||
+ .flags = CG_VER3 | CG_LITTLE_ENDIAN,
|
||||
+ },
|
||||
+ {
|
||||
+ .compat = "fsl,ls1012a-clockgen",
|
||||
+ .cmux_groups = {
|
||||
+ &ls1012a_cmux
|
||||
+ },
|
||||
+ .cmux_to_group = {
|
||||
+ 0, -1
|
||||
+ },
|
||||
+ .pll_mask = 0x03,
|
||||
+ },
|
||||
+ {
|
||||
.compat = "fsl,ls2080a-clockgen",
|
||||
.cmux_groups = {
|
||||
&clockgen2_cmux_cga12, &clockgen2_cmux_cgb
|
||||
@@ -846,7 +916,12 @@ static void __init create_muxes(struct c
|
||||
|
||||
static void __init clockgen_init(struct device_node *np);
|
||||
|
||||
-/* Legacy nodes may get probed before the parent clockgen node */
|
||||
+/*
|
||||
+ * Legacy nodes may get probed before the parent clockgen node.
|
||||
+ * It is assumed that device trees with legacy nodes will not
|
||||
+ * contain a "clocks" property -- otherwise the input clocks may
|
||||
+ * not be initialized at this point.
|
||||
+ */
|
||||
static void __init legacy_init_clockgen(struct device_node *np)
|
||||
{
|
||||
if (!clockgen.node)
|
||||
@@ -887,18 +962,13 @@ static struct clk __init
|
||||
return clk_register_fixed_rate(NULL, name, NULL, 0, rate);
|
||||
}
|
||||
|
||||
-static struct clk *sysclk_from_parent(const char *name)
|
||||
+static struct clk __init *input_clock(const char *name, struct clk *clk)
|
||||
{
|
||||
- struct clk *clk;
|
||||
- const char *parent_name;
|
||||
-
|
||||
- clk = of_clk_get(clockgen.node, 0);
|
||||
- if (IS_ERR(clk))
|
||||
- return clk;
|
||||
+ const char *input_name;
|
||||
|
||||
/* Register the input clock under the desired name. */
|
||||
- parent_name = __clk_get_name(clk);
|
||||
- clk = clk_register_fixed_factor(NULL, name, parent_name,
|
||||
+ input_name = __clk_get_name(clk);
|
||||
+ clk = clk_register_fixed_factor(NULL, name, input_name,
|
||||
0, 1, 1);
|
||||
if (IS_ERR(clk))
|
||||
pr_err("%s: Couldn't register %s: %ld\n", __func__, name,
|
||||
@@ -907,6 +977,29 @@ static struct clk *sysclk_from_parent(co
|
||||
return clk;
|
||||
}
|
||||
|
||||
+static struct clk __init *input_clock_by_name(const char *name,
|
||||
+ const char *dtname)
|
||||
+{
|
||||
+ struct clk *clk;
|
||||
+
|
||||
+ clk = of_clk_get_by_name(clockgen.node, dtname);
|
||||
+ if (IS_ERR(clk))
|
||||
+ return clk;
|
||||
+
|
||||
+ return input_clock(name, clk);
|
||||
+}
|
||||
+
|
||||
+static struct clk __init *input_clock_by_index(const char *name, int idx)
|
||||
+{
|
||||
+ struct clk *clk;
|
||||
+
|
||||
+ clk = of_clk_get(clockgen.node, 0);
|
||||
+ if (IS_ERR(clk))
|
||||
+ return clk;
|
||||
+
|
||||
+ return input_clock(name, clk);
|
||||
+}
|
||||
+
|
||||
static struct clk * __init create_sysclk(const char *name)
|
||||
{
|
||||
struct device_node *sysclk;
|
||||
@@ -916,7 +1009,11 @@ static struct clk * __init create_sysclk
|
||||
if (!IS_ERR(clk))
|
||||
return clk;
|
||||
|
||||
- clk = sysclk_from_parent(name);
|
||||
+ clk = input_clock_by_name(name, "sysclk");
|
||||
+ if (!IS_ERR(clk))
|
||||
+ return clk;
|
||||
+
|
||||
+ clk = input_clock_by_index(name, 0);
|
||||
if (!IS_ERR(clk))
|
||||
return clk;
|
||||
|
||||
@@ -927,7 +1024,27 @@ static struct clk * __init create_sysclk
|
||||
return clk;
|
||||
}
|
||||
|
||||
- pr_err("%s: No input clock\n", __func__);
|
||||
+ pr_err("%s: No input sysclk\n", __func__);
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+static struct clk * __init create_coreclk(const char *name)
|
||||
+{
|
||||
+ struct clk *clk;
|
||||
+
|
||||
+ clk = input_clock_by_name(name, "coreclk");
|
||||
+ if (!IS_ERR(clk))
|
||||
+ return clk;
|
||||
+
|
||||
+ /*
|
||||
+ * This indicates a mix of legacy nodes with the new coreclk
|
||||
+ * mechanism, which should never happen. If this error occurs,
|
||||
+ * don't use the wrong input clock just because coreclk isn't
|
||||
+ * ready yet.
|
||||
+ */
|
||||
+ if (WARN_ON(PTR_ERR(clk) == -EPROBE_DEFER))
|
||||
+ return clk;
|
||||
+
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -950,11 +1067,19 @@ static void __init create_one_pll(struct
|
||||
u32 __iomem *reg;
|
||||
u32 mult;
|
||||
struct clockgen_pll *pll = &cg->pll[idx];
|
||||
+ const char *input = "cg-sysclk";
|
||||
int i;
|
||||
|
||||
if (!(cg->info.pll_mask & (1 << idx)))
|
||||
return;
|
||||
|
||||
+ if (cg->coreclk && idx != PLATFORM_PLL) {
|
||||
+ if (IS_ERR(cg->coreclk))
|
||||
+ return;
|
||||
+
|
||||
+ input = "cg-coreclk";
|
||||
+ }
|
||||
+
|
||||
if (cg->info.flags & CG_VER3) {
|
||||
switch (idx) {
|
||||
case PLATFORM_PLL:
|
||||
@@ -1000,12 +1125,20 @@ static void __init create_one_pll(struct
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(pll->div); i++) {
|
||||
struct clk *clk;
|
||||
+ int ret;
|
||||
+
|
||||
+ /*
|
||||
+ * For platform PLL, there are 8 divider clocks.
|
||||
+ * For core PLL, there are 4 divider clocks at most.
|
||||
+ */
|
||||
+ if (idx != 0 && i >= 4)
|
||||
+ break;
|
||||
|
||||
snprintf(pll->div[i].name, sizeof(pll->div[i].name),
|
||||
"cg-pll%d-div%d", idx, i + 1);
|
||||
|
||||
clk = clk_register_fixed_factor(NULL,
|
||||
- pll->div[i].name, "cg-sysclk", 0, mult, i + 1);
|
||||
+ pll->div[i].name, input, 0, mult, i + 1);
|
||||
if (IS_ERR(clk)) {
|
||||
pr_err("%s: %s: register failed %ld\n",
|
||||
__func__, pll->div[i].name, PTR_ERR(clk));
|
||||
@@ -1013,6 +1146,11 @@ static void __init create_one_pll(struct
|
||||
}
|
||||
|
||||
pll->div[i].clk = clk;
|
||||
+ ret = clk_register_clkdev(clk, pll->div[i].name, NULL);
|
||||
+ if (ret != 0)
|
||||
+ pr_err("%s: %s: register to lookup table failed %ld\n",
|
||||
+ __func__, pll->div[i].name, PTR_ERR(clk));
|
||||
+
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1142,6 +1280,13 @@ static struct clk *clockgen_clk_get(stru
|
||||
goto bad_args;
|
||||
clk = pll->div[idx].clk;
|
||||
break;
|
||||
+ case 5:
|
||||
+ if (idx != 0)
|
||||
+ goto bad_args;
|
||||
+ clk = cg->coreclk;
|
||||
+ if (IS_ERR(clk))
|
||||
+ clk = NULL;
|
||||
+ break;
|
||||
default:
|
||||
goto bad_args;
|
||||
}
|
||||
@@ -1253,6 +1398,7 @@ static void __init clockgen_init(struct
|
||||
clockgen.info.flags |= CG_CMUX_GE_PLAT;
|
||||
|
||||
clockgen.sysclk = create_sysclk("cg-sysclk");
|
||||
+ clockgen.coreclk = create_coreclk("cg-coreclk");
|
||||
create_plls(&clockgen);
|
||||
create_muxes(&clockgen);
|
||||
|
||||
@@ -1273,8 +1419,11 @@ err:
|
||||
|
||||
CLK_OF_DECLARE(qoriq_clockgen_1, "fsl,qoriq-clockgen-1.0", clockgen_init);
|
||||
CLK_OF_DECLARE(qoriq_clockgen_2, "fsl,qoriq-clockgen-2.0", clockgen_init);
|
||||
+CLK_OF_DECLARE(qoriq_clockgen_ls1012a, "fsl,ls1012a-clockgen", clockgen_init);
|
||||
CLK_OF_DECLARE(qoriq_clockgen_ls1021a, "fsl,ls1021a-clockgen", clockgen_init);
|
||||
CLK_OF_DECLARE(qoriq_clockgen_ls1043a, "fsl,ls1043a-clockgen", clockgen_init);
|
||||
+CLK_OF_DECLARE(qoriq_clockgen_ls1046a, "fsl,ls1046a-clockgen", clockgen_init);
|
||||
+CLK_OF_DECLARE(qoriq_clockgen_ls1088a, "fsl,ls1088a-clockgen", clockgen_init);
|
||||
CLK_OF_DECLARE(qoriq_clockgen_ls2080a, "fsl,ls2080a-clockgen", clockgen_init);
|
||||
|
||||
/* Legacy nodes */
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,404 +0,0 @@
|
||||
From b92e223750a07b28f175eae97d5ce3978df41be8 Mon Sep 17 00:00:00 2001
|
||||
From: Yangbo Lu <yangbo.lu@nxp.com>
|
||||
Date: Wed, 17 Jan 2018 15:32:05 +0800
|
||||
Subject: [PATCH 18/30] flextimer: support layerscape
|
||||
|
||||
This is an integrated patch for layerscape flextimer support.
|
||||
|
||||
Signed-off-by: Wang Dongsheng <dongsheng.wang@nxp.com>
|
||||
Signed-off-by: Meng Yi <meng.yi@nxp.com>
|
||||
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
|
||||
---
|
||||
drivers/clocksource/fsl_ftm_timer.c | 8 +-
|
||||
drivers/soc/fsl/layerscape/ftm_alarm.c | 367 +++++++++++++++++++++++++++++++++
|
||||
2 files changed, 371 insertions(+), 4 deletions(-)
|
||||
create mode 100644 drivers/soc/fsl/layerscape/ftm_alarm.c
|
||||
|
||||
--- a/drivers/clocksource/fsl_ftm_timer.c
|
||||
+++ b/drivers/clocksource/fsl_ftm_timer.c
|
||||
@@ -83,11 +83,11 @@ static inline void ftm_counter_disable(v
|
||||
|
||||
static inline void ftm_irq_acknowledge(void __iomem *base)
|
||||
{
|
||||
- u32 val;
|
||||
+ unsigned int timeout = 100;
|
||||
|
||||
- val = ftm_readl(base + FTM_SC);
|
||||
- val &= ~FTM_SC_TOF;
|
||||
- ftm_writel(val, base + FTM_SC);
|
||||
+ while ((FTM_SC_TOF & ftm_readl(base + FTM_SC)) && timeout--)
|
||||
+ ftm_writel(ftm_readl(base + FTM_SC) & (~FTM_SC_TOF),
|
||||
+ base + FTM_SC);
|
||||
}
|
||||
|
||||
static inline void ftm_irq_enable(void __iomem *base)
|
||||
--- /dev/null
|
||||
+++ b/drivers/soc/fsl/layerscape/ftm_alarm.c
|
||||
@@ -0,0 +1,367 @@
|
||||
+/*
|
||||
+ * Freescale FlexTimer Module (FTM) Alarm driver.
|
||||
+ *
|
||||
+ * Copyright 2014 Freescale Semiconductor, Inc.
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU General Public License
|
||||
+ * as published by the Free Software Foundation; either version 2
|
||||
+ * of the License, or (at your option) any later version.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/device.h>
|
||||
+#include <linux/err.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/of_address.h>
|
||||
+#include <linux/of_irq.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/of_device.h>
|
||||
+#include <linux/libata.h>
|
||||
+#include <linux/module.h>
|
||||
+
|
||||
+#define FTM_SC 0x00
|
||||
+#define FTM_SC_CLK_SHIFT 3
|
||||
+#define FTM_SC_CLK_MASK (0x3 << FTM_SC_CLK_SHIFT)
|
||||
+#define FTM_SC_CLK(c) ((c) << FTM_SC_CLK_SHIFT)
|
||||
+#define FTM_SC_PS_MASK 0x7
|
||||
+#define FTM_SC_TOIE BIT(6)
|
||||
+#define FTM_SC_TOF BIT(7)
|
||||
+
|
||||
+#define FTM_SC_CLKS_FIXED_FREQ 0x02
|
||||
+
|
||||
+#define FTM_CNT 0x04
|
||||
+#define FTM_MOD 0x08
|
||||
+#define FTM_CNTIN 0x4C
|
||||
+
|
||||
+#define FIXED_FREQ_CLK 32000
|
||||
+#define MAX_FREQ_DIV (1 << FTM_SC_PS_MASK)
|
||||
+#define MAX_COUNT_VAL 0xffff
|
||||
+
|
||||
+static void __iomem *ftm1_base;
|
||||
+static void __iomem *rcpm_ftm_addr;
|
||||
+static u32 alarm_freq;
|
||||
+static bool big_endian;
|
||||
+
|
||||
+enum pmu_endian_type {
|
||||
+ BIG_ENDIAN,
|
||||
+ LITTLE_ENDIAN,
|
||||
+};
|
||||
+
|
||||
+struct rcpm_cfg {
|
||||
+ enum pmu_endian_type big_endian; /* Big/Little endian of PMU module */
|
||||
+ u32 flextimer_set_bit; /* FlexTimer1 is not powerdown during device LPM20 */
|
||||
+};
|
||||
+
|
||||
+static struct rcpm_cfg ls1012a_rcpm_cfg = {
|
||||
+ .big_endian = BIG_ENDIAN,
|
||||
+ .flextimer_set_bit = 0x20000,
|
||||
+};
|
||||
+
|
||||
+static struct rcpm_cfg ls1021a_rcpm_cfg = {
|
||||
+ .big_endian = BIG_ENDIAN,
|
||||
+ .flextimer_set_bit = 0x20000,
|
||||
+};
|
||||
+
|
||||
+static struct rcpm_cfg ls1043a_rcpm_cfg = {
|
||||
+ .big_endian = BIG_ENDIAN,
|
||||
+ .flextimer_set_bit = 0x20000,
|
||||
+};
|
||||
+
|
||||
+static struct rcpm_cfg ls1046a_rcpm_cfg = {
|
||||
+ .big_endian = BIG_ENDIAN,
|
||||
+ .flextimer_set_bit = 0x20000,
|
||||
+};
|
||||
+
|
||||
+static struct rcpm_cfg ls1088a_rcpm_cfg = {
|
||||
+ .big_endian = LITTLE_ENDIAN,
|
||||
+ .flextimer_set_bit = 0x4000,
|
||||
+};
|
||||
+
|
||||
+static struct rcpm_cfg ls208xa_rcpm_cfg = {
|
||||
+ .big_endian = LITTLE_ENDIAN,
|
||||
+ .flextimer_set_bit = 0x4000,
|
||||
+};
|
||||
+
|
||||
+static const struct of_device_id ippdexpcr_of_match[] = {
|
||||
+ { .compatible = "fsl,ls1012a-ftm", .data = &ls1012a_rcpm_cfg},
|
||||
+ { .compatible = "fsl,ls1021a-ftm", .data = &ls1021a_rcpm_cfg},
|
||||
+ { .compatible = "fsl,ls1043a-ftm", .data = &ls1043a_rcpm_cfg},
|
||||
+ { .compatible = "fsl,ls1046a-ftm", .data = &ls1046a_rcpm_cfg},
|
||||
+ { .compatible = "fsl,ls1088a-ftm", .data = &ls1088a_rcpm_cfg},
|
||||
+ { .compatible = "fsl,ls208xa-ftm", .data = &ls208xa_rcpm_cfg},
|
||||
+ {},
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, ippdexpcr_of_match);
|
||||
+
|
||||
+static inline u32 ftm_readl(void __iomem *addr)
|
||||
+{
|
||||
+ if (big_endian)
|
||||
+ return ioread32be(addr);
|
||||
+
|
||||
+ return ioread32(addr);
|
||||
+}
|
||||
+
|
||||
+static inline void ftm_writel(u32 val, void __iomem *addr)
|
||||
+{
|
||||
+ if (big_endian)
|
||||
+ iowrite32be(val, addr);
|
||||
+ else
|
||||
+ iowrite32(val, addr);
|
||||
+}
|
||||
+
|
||||
+static inline void ftm_counter_enable(void __iomem *base)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ /* select and enable counter clock source */
|
||||
+ val = ftm_readl(base + FTM_SC);
|
||||
+ val &= ~(FTM_SC_PS_MASK | FTM_SC_CLK_MASK);
|
||||
+ val |= (FTM_SC_PS_MASK | FTM_SC_CLK(FTM_SC_CLKS_FIXED_FREQ));
|
||||
+ ftm_writel(val, base + FTM_SC);
|
||||
+}
|
||||
+
|
||||
+static inline void ftm_counter_disable(void __iomem *base)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ /* disable counter clock source */
|
||||
+ val = ftm_readl(base + FTM_SC);
|
||||
+ val &= ~(FTM_SC_PS_MASK | FTM_SC_CLK_MASK);
|
||||
+ ftm_writel(val, base + FTM_SC);
|
||||
+}
|
||||
+
|
||||
+static inline void ftm_irq_acknowledge(void __iomem *base)
|
||||
+{
|
||||
+ unsigned int timeout = 100;
|
||||
+
|
||||
+ while ((FTM_SC_TOF & ftm_readl(base + FTM_SC)) && timeout--)
|
||||
+ ftm_writel(ftm_readl(base + FTM_SC) & (~FTM_SC_TOF),
|
||||
+ base + FTM_SC);
|
||||
+}
|
||||
+
|
||||
+static inline void ftm_irq_enable(void __iomem *base)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ val = ftm_readl(base + FTM_SC);
|
||||
+ val |= FTM_SC_TOIE;
|
||||
+ ftm_writel(val, base + FTM_SC);
|
||||
+}
|
||||
+
|
||||
+static inline void ftm_irq_disable(void __iomem *base)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ val = ftm_readl(base + FTM_SC);
|
||||
+ val &= ~FTM_SC_TOIE;
|
||||
+ ftm_writel(val, base + FTM_SC);
|
||||
+}
|
||||
+
|
||||
+static inline void ftm_reset_counter(void __iomem *base)
|
||||
+{
|
||||
+ /*
|
||||
+ * The CNT register contains the FTM counter value.
|
||||
+ * Reset clears the CNT register. Writing any value to COUNT
|
||||
+ * updates the counter with its initial value, CNTIN.
|
||||
+ */
|
||||
+ ftm_writel(0x00, base + FTM_CNT);
|
||||
+}
|
||||
+
|
||||
+static u32 time_to_cycle(unsigned long time)
|
||||
+{
|
||||
+ u32 cycle;
|
||||
+
|
||||
+ cycle = time * alarm_freq;
|
||||
+ if (cycle > MAX_COUNT_VAL) {
|
||||
+ pr_err("Out of alarm range.\n");
|
||||
+ cycle = 0;
|
||||
+ }
|
||||
+
|
||||
+ return cycle;
|
||||
+}
|
||||
+
|
||||
+static u32 cycle_to_time(u32 cycle)
|
||||
+{
|
||||
+ return cycle / alarm_freq + 1;
|
||||
+}
|
||||
+
|
||||
+static void ftm_clean_alarm(void)
|
||||
+{
|
||||
+ ftm_counter_disable(ftm1_base);
|
||||
+
|
||||
+ ftm_writel(0x00, ftm1_base + FTM_CNTIN);
|
||||
+ ftm_writel(~0U, ftm1_base + FTM_MOD);
|
||||
+
|
||||
+ ftm_reset_counter(ftm1_base);
|
||||
+}
|
||||
+
|
||||
+static int ftm_set_alarm(u64 cycle)
|
||||
+{
|
||||
+ ftm_irq_disable(ftm1_base);
|
||||
+
|
||||
+ /*
|
||||
+ * The counter increments until the value of MOD is reached,
|
||||
+ * at which point the counter is reloaded with the value of CNTIN.
|
||||
+ * The TOF (the overflow flag) bit is set when the FTM counter
|
||||
+ * changes from MOD to CNTIN. So we should using the cycle - 1.
|
||||
+ */
|
||||
+ ftm_writel(cycle - 1, ftm1_base + FTM_MOD);
|
||||
+
|
||||
+ ftm_counter_enable(ftm1_base);
|
||||
+
|
||||
+ ftm_irq_enable(ftm1_base);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static irqreturn_t ftm_alarm_interrupt(int irq, void *dev_id)
|
||||
+{
|
||||
+ ftm_irq_acknowledge(ftm1_base);
|
||||
+ ftm_irq_disable(ftm1_base);
|
||||
+ ftm_clean_alarm();
|
||||
+
|
||||
+ return IRQ_HANDLED;
|
||||
+}
|
||||
+
|
||||
+static ssize_t ftm_alarm_show(struct device *dev,
|
||||
+ struct device_attribute *attr,
|
||||
+ char *buf)
|
||||
+{
|
||||
+ u32 count, val;
|
||||
+
|
||||
+ count = ftm_readl(ftm1_base + FTM_MOD);
|
||||
+ val = ftm_readl(ftm1_base + FTM_CNT);
|
||||
+ val = (count & MAX_COUNT_VAL) - val;
|
||||
+ val = cycle_to_time(val);
|
||||
+
|
||||
+ return sprintf(buf, "%u\n", val);
|
||||
+}
|
||||
+
|
||||
+static ssize_t ftm_alarm_store(struct device *dev,
|
||||
+ struct device_attribute *attr,
|
||||
+ const char *buf, size_t count)
|
||||
+{
|
||||
+ u32 cycle;
|
||||
+ unsigned long time;
|
||||
+
|
||||
+ if (kstrtoul(buf, 0, &time))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ ftm_clean_alarm();
|
||||
+
|
||||
+ cycle = time_to_cycle(time);
|
||||
+ if (!cycle)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ ftm_set_alarm(cycle);
|
||||
+
|
||||
+ return count;
|
||||
+}
|
||||
+
|
||||
+static struct device_attribute ftm_alarm_attributes = __ATTR(ftm_alarm, 0644,
|
||||
+ ftm_alarm_show, ftm_alarm_store);
|
||||
+
|
||||
+static int ftm_alarm_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct device_node *np = pdev->dev.of_node;
|
||||
+ struct resource *r;
|
||||
+ int irq;
|
||||
+ int ret;
|
||||
+ struct rcpm_cfg *rcpm_cfg;
|
||||
+ u32 ippdexpcr, flextimer;
|
||||
+ const struct of_device_id *of_id;
|
||||
+ enum pmu_endian_type endian;
|
||||
+
|
||||
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
+ if (!r)
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ ftm1_base = devm_ioremap_resource(&pdev->dev, r);
|
||||
+ if (IS_ERR(ftm1_base))
|
||||
+ return PTR_ERR(ftm1_base);
|
||||
+
|
||||
+ of_id = of_match_node(ippdexpcr_of_match, np);
|
||||
+ if (!of_id)
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ rcpm_cfg = devm_kzalloc(&pdev->dev, sizeof(*rcpm_cfg), GFP_KERNEL);
|
||||
+ if (!rcpm_cfg)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ rcpm_cfg = (struct rcpm_cfg*)of_id->data;
|
||||
+ endian = rcpm_cfg->big_endian;
|
||||
+ flextimer = rcpm_cfg->flextimer_set_bit;
|
||||
+
|
||||
+ r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "FlexTimer1");
|
||||
+ if (r) {
|
||||
+ rcpm_ftm_addr = devm_ioremap_resource(&pdev->dev, r);
|
||||
+ if (IS_ERR(rcpm_ftm_addr))
|
||||
+ return PTR_ERR(rcpm_ftm_addr);
|
||||
+ if (endian == BIG_ENDIAN)
|
||||
+ ippdexpcr = ioread32be(rcpm_ftm_addr);
|
||||
+ else
|
||||
+ ippdexpcr = ioread32(rcpm_ftm_addr);
|
||||
+ ippdexpcr |= flextimer;
|
||||
+ if (endian == BIG_ENDIAN)
|
||||
+ iowrite32be(ippdexpcr, rcpm_ftm_addr);
|
||||
+ else
|
||||
+ iowrite32(ippdexpcr, rcpm_ftm_addr);
|
||||
+ }
|
||||
+
|
||||
+ irq = irq_of_parse_and_map(np, 0);
|
||||
+ if (irq <= 0) {
|
||||
+ pr_err("ftm: unable to get IRQ from DT, %d\n", irq);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ big_endian = of_property_read_bool(np, "big-endian");
|
||||
+
|
||||
+ ret = devm_request_irq(&pdev->dev, irq, ftm_alarm_interrupt,
|
||||
+ IRQF_NO_SUSPEND, dev_name(&pdev->dev), NULL);
|
||||
+ if (ret < 0) {
|
||||
+ dev_err(&pdev->dev, "failed to request irq\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = device_create_file(&pdev->dev, &ftm_alarm_attributes);
|
||||
+ if (ret) {
|
||||
+ dev_err(&pdev->dev, "create sysfs fail.\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ alarm_freq = (u32)FIXED_FREQ_CLK / (u32)MAX_FREQ_DIV;
|
||||
+
|
||||
+ ftm_clean_alarm();
|
||||
+
|
||||
+ device_init_wakeup(&pdev->dev, true);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id ftm_alarm_match[] = {
|
||||
+ { .compatible = "fsl,ls1012a-ftm", },
|
||||
+ { .compatible = "fsl,ls1021a-ftm", },
|
||||
+ { .compatible = "fsl,ls1043a-ftm", },
|
||||
+ { .compatible = "fsl,ls1046a-ftm", },
|
||||
+ { .compatible = "fsl,ls1088a-ftm", },
|
||||
+ { .compatible = "fsl,ls208xa-ftm", },
|
||||
+ { .compatible = "fsl,ftm-timer", },
|
||||
+ { },
|
||||
+};
|
||||
+
|
||||
+static struct platform_driver ftm_alarm_driver = {
|
||||
+ .probe = ftm_alarm_probe,
|
||||
+ .driver = {
|
||||
+ .name = "ftm-alarm",
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .of_match_table = ftm_alarm_match,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static int __init ftm_alarm_init(void)
|
||||
+{
|
||||
+ return platform_driver_register(&ftm_alarm_driver);
|
||||
+}
|
||||
+device_initcall(ftm_alarm_init);
|
@ -1,58 +0,0 @@
|
||||
From 177f92a14d8177124f37db0fafc11182e2dcdd62 Mon Sep 17 00:00:00 2001
|
||||
From: Yangbo Lu <yangbo.lu@nxp.com>
|
||||
Date: Wed, 17 Jan 2018 15:33:05 +0800
|
||||
Subject: [PATCH 19/30] gpu: support layerscape
|
||||
|
||||
This is an integrated patch for layerscape dcu support.
|
||||
|
||||
Signed-off-by: Alison Wang <b18965@freescale.com>
|
||||
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
|
||||
---
|
||||
drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c | 15 ++++++++++++++-
|
||||
1 file changed, 14 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
|
||||
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
|
||||
@@ -225,7 +225,6 @@ static int fsl_dcu_drm_pm_suspend(struct
|
||||
if (!fsl_dev)
|
||||
return 0;
|
||||
|
||||
- disable_irq(fsl_dev->irq);
|
||||
drm_kms_helper_poll_disable(fsl_dev->drm);
|
||||
|
||||
console_lock();
|
||||
@@ -243,6 +242,8 @@ static int fsl_dcu_drm_pm_suspend(struct
|
||||
return PTR_ERR(fsl_dev->state);
|
||||
}
|
||||
|
||||
+ disable_irq(fsl_dev->irq);
|
||||
+
|
||||
clk_disable_unprepare(fsl_dev->clk);
|
||||
|
||||
return 0;
|
||||
@@ -262,6 +263,12 @@ static int fsl_dcu_drm_pm_resume(struct
|
||||
return ret;
|
||||
}
|
||||
|
||||
+ ret = clk_prepare_enable(fsl_dev->pix_clk);
|
||||
+ if (ret < 0) {
|
||||
+ dev_err(dev, "failed to enable dcu pix clk\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
if (fsl_dev->tcon)
|
||||
fsl_tcon_bypass_enable(fsl_dev->tcon);
|
||||
fsl_dcu_drm_init_planes(fsl_dev->drm);
|
||||
@@ -388,6 +395,12 @@ static int fsl_dcu_drm_probe(struct plat
|
||||
goto disable_clk;
|
||||
}
|
||||
|
||||
+ ret = clk_prepare_enable(fsl_dev->pix_clk);
|
||||
+ if (ret < 0) {
|
||||
+ dev_err(dev, "failed to enable dcu pix clk\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
fsl_dev->tcon = fsl_tcon_init(dev);
|
||||
|
||||
drm = drm_dev_alloc(driver, dev);
|
@ -1,421 +0,0 @@
|
||||
From 45b0e1589b25ea3106a8c8d18bf653fde95baa9f Mon Sep 17 00:00:00 2001
|
||||
From: Yangbo Lu <yangbo.lu@nxp.com>
|
||||
Date: Wed, 17 Jan 2018 15:34:22 +0800
|
||||
Subject: [PATCH 20/30] guts: support layerscape
|
||||
|
||||
This is an integrated patch for layerscape guts support.
|
||||
|
||||
Signed-off-by: Roy Pledge <roy.pledge@nxp.com>
|
||||
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
|
||||
Signed-off-by: Amrita Kumari <amrita.kumari@nxp.com>
|
||||
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
|
||||
---
|
||||
drivers/soc/fsl/guts.c | 238 +++++++++++++++++++++++++++++++++++++++++++++++
|
||||
include/linux/fsl/guts.h | 125 +++++++++++++++----------
|
||||
2 files changed, 315 insertions(+), 48 deletions(-)
|
||||
create mode 100644 drivers/soc/fsl/guts.c
|
||||
|
||||
--- /dev/null
|
||||
+++ b/drivers/soc/fsl/guts.c
|
||||
@@ -0,0 +1,238 @@
|
||||
+/*
|
||||
+ * Freescale QorIQ Platforms GUTS Driver
|
||||
+ *
|
||||
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License as published by
|
||||
+ * the Free Software Foundation; either version 2 of the License, or
|
||||
+ * (at your option) any later version.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/of_fdt.h>
|
||||
+#include <linux/sys_soc.h>
|
||||
+#include <linux/of_address.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/fsl/guts.h>
|
||||
+
|
||||
+struct guts {
|
||||
+ struct ccsr_guts __iomem *regs;
|
||||
+ bool little_endian;
|
||||
+};
|
||||
+
|
||||
+struct fsl_soc_die_attr {
|
||||
+ char *die;
|
||||
+ u32 svr;
|
||||
+ u32 mask;
|
||||
+};
|
||||
+
|
||||
+static struct guts *guts;
|
||||
+static struct soc_device_attribute soc_dev_attr;
|
||||
+static struct soc_device *soc_dev;
|
||||
+
|
||||
+
|
||||
+/* SoC die attribute definition for QorIQ platform */
|
||||
+static const struct fsl_soc_die_attr fsl_soc_die[] = {
|
||||
+ /*
|
||||
+ * Power Architecture-based SoCs T Series
|
||||
+ */
|
||||
+
|
||||
+ /* Die: T4240, SoC: T4240/T4160/T4080 */
|
||||
+ { .die = "T4240",
|
||||
+ .svr = 0x82400000,
|
||||
+ .mask = 0xfff00000,
|
||||
+ },
|
||||
+ /* Die: T1040, SoC: T1040/T1020/T1042/T1022 */
|
||||
+ { .die = "T1040",
|
||||
+ .svr = 0x85200000,
|
||||
+ .mask = 0xfff00000,
|
||||
+ },
|
||||
+ /* Die: T2080, SoC: T2080/T2081 */
|
||||
+ { .die = "T2080",
|
||||
+ .svr = 0x85300000,
|
||||
+ .mask = 0xfff00000,
|
||||
+ },
|
||||
+ /* Die: T1024, SoC: T1024/T1014/T1023/T1013 */
|
||||
+ { .die = "T1024",
|
||||
+ .svr = 0x85400000,
|
||||
+ .mask = 0xfff00000,
|
||||
+ },
|
||||
+
|
||||
+ /*
|
||||
+ * ARM-based SoCs LS Series
|
||||
+ */
|
||||
+
|
||||
+ /* Die: LS1043A, SoC: LS1043A/LS1023A */
|
||||
+ { .die = "LS1043A",
|
||||
+ .svr = 0x87920000,
|
||||
+ .mask = 0xffff0000,
|
||||
+ },
|
||||
+ /* Die: LS2080A, SoC: LS2080A/LS2040A/LS2085A */
|
||||
+ { .die = "LS2080A",
|
||||
+ .svr = 0x87010000,
|
||||
+ .mask = 0xff3f0000,
|
||||
+ },
|
||||
+ /* Die: LS1088A, SoC: LS1088A/LS1048A/LS1084A/LS1044A */
|
||||
+ { .die = "LS1088A",
|
||||
+ .svr = 0x87030000,
|
||||
+ .mask = 0xff3f0000,
|
||||
+ },
|
||||
+ /* Die: LS1012A, SoC: LS1012A */
|
||||
+ { .die = "LS1012A",
|
||||
+ .svr = 0x87040000,
|
||||
+ .mask = 0xffff0000,
|
||||
+ },
|
||||
+ /* Die: LS1046A, SoC: LS1046A/LS1026A */
|
||||
+ { .die = "LS1046A",
|
||||
+ .svr = 0x87070000,
|
||||
+ .mask = 0xffff0000,
|
||||
+ },
|
||||
+ /* Die: LS2088A, SoC: LS2088A/LS2048A/LS2084A/LS2044A */
|
||||
+ { .die = "LS2088A",
|
||||
+ .svr = 0x87090000,
|
||||
+ .mask = 0xff3f0000,
|
||||
+ },
|
||||
+ /* Die: LS1021A, SoC: LS1021A/LS1020A/LS1022A */
|
||||
+ { .die = "LS1021A",
|
||||
+ .svr = 0x87000000,
|
||||
+ .mask = 0xfff70000,
|
||||
+ },
|
||||
+ { },
|
||||
+};
|
||||
+
|
||||
+static const struct fsl_soc_die_attr *fsl_soc_die_match(
|
||||
+ u32 svr, const struct fsl_soc_die_attr *matches)
|
||||
+{
|
||||
+ while (matches->svr) {
|
||||
+ if (matches->svr == (svr & matches->mask))
|
||||
+ return matches;
|
||||
+ matches++;
|
||||
+ };
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+u32 fsl_guts_get_svr(void)
|
||||
+{
|
||||
+ u32 svr = 0;
|
||||
+
|
||||
+ if (!guts || !guts->regs)
|
||||
+ return svr;
|
||||
+
|
||||
+ if (guts->little_endian)
|
||||
+ svr = ioread32(&guts->regs->svr);
|
||||
+ else
|
||||
+ svr = ioread32be(&guts->regs->svr);
|
||||
+
|
||||
+ return svr;
|
||||
+}
|
||||
+EXPORT_SYMBOL(fsl_guts_get_svr);
|
||||
+
|
||||
+static int fsl_guts_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct device_node *np = pdev->dev.of_node;
|
||||
+ struct device *dev = &pdev->dev;
|
||||
+ struct resource *res;
|
||||
+ const struct fsl_soc_die_attr *soc_die;
|
||||
+ const char *machine;
|
||||
+ u32 svr;
|
||||
+
|
||||
+ /* Initialize guts */
|
||||
+ guts = devm_kzalloc(dev, sizeof(*guts), GFP_KERNEL);
|
||||
+ if (!guts)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ guts->little_endian = of_property_read_bool(np, "little-endian");
|
||||
+
|
||||
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
+ guts->regs = devm_ioremap_resource(dev, res);
|
||||
+ if (IS_ERR(guts->regs))
|
||||
+ return PTR_ERR(guts->regs);
|
||||
+
|
||||
+ /* Register soc device */
|
||||
+ machine = of_flat_dt_get_machine_name();
|
||||
+ if (machine)
|
||||
+ soc_dev_attr.machine = devm_kstrdup(dev, machine, GFP_KERNEL);
|
||||
+
|
||||
+ svr = fsl_guts_get_svr();
|
||||
+ soc_die = fsl_soc_die_match(svr, fsl_soc_die);
|
||||
+ if (soc_die) {
|
||||
+ soc_dev_attr.family = devm_kasprintf(dev, GFP_KERNEL,
|
||||
+ "QorIQ %s", soc_die->die);
|
||||
+ } else {
|
||||
+ soc_dev_attr.family = devm_kasprintf(dev, GFP_KERNEL, "QorIQ");
|
||||
+ }
|
||||
+ soc_dev_attr.soc_id = devm_kasprintf(dev, GFP_KERNEL,
|
||||
+ "svr:0x%08x", svr);
|
||||
+ soc_dev_attr.revision = devm_kasprintf(dev, GFP_KERNEL, "%d.%d",
|
||||
+ (svr >> 4) & 0xf, svr & 0xf);
|
||||
+
|
||||
+ soc_dev = soc_device_register(&soc_dev_attr);
|
||||
+ if (IS_ERR(soc_dev))
|
||||
+ return PTR_ERR(soc_dev);
|
||||
+
|
||||
+ pr_info("Machine: %s\n", soc_dev_attr.machine);
|
||||
+ pr_info("SoC family: %s\n", soc_dev_attr.family);
|
||||
+ pr_info("SoC ID: %s, Revision: %s\n",
|
||||
+ soc_dev_attr.soc_id, soc_dev_attr.revision);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int fsl_guts_remove(struct platform_device *dev)
|
||||
+{
|
||||
+ soc_device_unregister(soc_dev);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Table for matching compatible strings, for device tree
|
||||
+ * guts node, for Freescale QorIQ SOCs.
|
||||
+ */
|
||||
+static const struct of_device_id fsl_guts_of_match[] = {
|
||||
+ { .compatible = "fsl,qoriq-device-config-1.0", },
|
||||
+ { .compatible = "fsl,qoriq-device-config-2.0", },
|
||||
+ { .compatible = "fsl,p1010-guts", },
|
||||
+ { .compatible = "fsl,p1020-guts", },
|
||||
+ { .compatible = "fsl,p1021-guts", },
|
||||
+ { .compatible = "fsl,p1022-guts", },
|
||||
+ { .compatible = "fsl,p1023-guts", },
|
||||
+ { .compatible = "fsl,p2020-guts", },
|
||||
+ { .compatible = "fsl,bsc9131-guts", },
|
||||
+ { .compatible = "fsl,bsc9132-guts", },
|
||||
+ { .compatible = "fsl,mpc8536-guts", },
|
||||
+ { .compatible = "fsl,mpc8544-guts", },
|
||||
+ { .compatible = "fsl,mpc8548-guts", },
|
||||
+ { .compatible = "fsl,mpc8568-guts", },
|
||||
+ { .compatible = "fsl,mpc8569-guts", },
|
||||
+ { .compatible = "fsl,mpc8572-guts", },
|
||||
+ { .compatible = "fsl,ls1021a-dcfg", },
|
||||
+ { .compatible = "fsl,ls1043a-dcfg", },
|
||||
+ { .compatible = "fsl,ls1046a-dcfg", },
|
||||
+ { .compatible = "fsl,ls2080a-dcfg", },
|
||||
+ { .compatible = "fsl,ls1088a-dcfg", },
|
||||
+ {}
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, fsl_guts_of_match);
|
||||
+
|
||||
+static struct platform_driver fsl_guts_driver = {
|
||||
+ .driver = {
|
||||
+ .name = "fsl-guts",
|
||||
+ .of_match_table = fsl_guts_of_match,
|
||||
+ },
|
||||
+ .probe = fsl_guts_probe,
|
||||
+ .remove = fsl_guts_remove,
|
||||
+};
|
||||
+
|
||||
+static int __init fsl_guts_init(void)
|
||||
+{
|
||||
+ return platform_driver_register(&fsl_guts_driver);
|
||||
+}
|
||||
+core_initcall(fsl_guts_init);
|
||||
+
|
||||
+static void __exit fsl_guts_exit(void)
|
||||
+{
|
||||
+ platform_driver_unregister(&fsl_guts_driver);
|
||||
+}
|
||||
+module_exit(fsl_guts_exit);
|
||||
--- a/include/linux/fsl/guts.h
|
||||
+++ b/include/linux/fsl/guts.h
|
||||
@@ -30,83 +30,112 @@
|
||||
* #ifdefs.
|
||||
*/
|
||||
struct ccsr_guts {
|
||||
- __be32 porpllsr; /* 0x.0000 - POR PLL Ratio Status Register */
|
||||
- __be32 porbmsr; /* 0x.0004 - POR Boot Mode Status Register */
|
||||
- __be32 porimpscr; /* 0x.0008 - POR I/O Impedance Status and Control Register */
|
||||
- __be32 pordevsr; /* 0x.000c - POR I/O Device Status Register */
|
||||
- __be32 pordbgmsr; /* 0x.0010 - POR Debug Mode Status Register */
|
||||
- __be32 pordevsr2; /* 0x.0014 - POR device status register 2 */
|
||||
+ u32 porpllsr; /* 0x.0000 - POR PLL Ratio Status Register */
|
||||
+ u32 porbmsr; /* 0x.0004 - POR Boot Mode Status Register */
|
||||
+ u32 porimpscr; /* 0x.0008 - POR I/O Impedance Status and
|
||||
+ * Control Register
|
||||
+ */
|
||||
+ u32 pordevsr; /* 0x.000c - POR I/O Device Status Register */
|
||||
+ u32 pordbgmsr; /* 0x.0010 - POR Debug Mode Status Register */
|
||||
+ u32 pordevsr2; /* 0x.0014 - POR device status register 2 */
|
||||
u8 res018[0x20 - 0x18];
|
||||
- __be32 porcir; /* 0x.0020 - POR Configuration Information Register */
|
||||
+ u32 porcir; /* 0x.0020 - POR Configuration Information
|
||||
+ * Register
|
||||
+ */
|
||||
u8 res024[0x30 - 0x24];
|
||||
- __be32 gpiocr; /* 0x.0030 - GPIO Control Register */
|
||||
+ u32 gpiocr; /* 0x.0030 - GPIO Control Register */
|
||||
u8 res034[0x40 - 0x34];
|
||||
- __be32 gpoutdr; /* 0x.0040 - General-Purpose Output Data Register */
|
||||
+ u32 gpoutdr; /* 0x.0040 - General-Purpose Output Data
|
||||
+ * Register
|
||||
+ */
|
||||
u8 res044[0x50 - 0x44];
|
||||
- __be32 gpindr; /* 0x.0050 - General-Purpose Input Data Register */
|
||||
+ u32 gpindr; /* 0x.0050 - General-Purpose Input Data
|
||||
+ * Register
|
||||
+ */
|
||||
u8 res054[0x60 - 0x54];
|
||||
- __be32 pmuxcr; /* 0x.0060 - Alternate Function Signal Multiplex Control */
|
||||
- __be32 pmuxcr2; /* 0x.0064 - Alternate function signal multiplex control 2 */
|
||||
- __be32 dmuxcr; /* 0x.0068 - DMA Mux Control Register */
|
||||
+ u32 pmuxcr; /* 0x.0060 - Alternate Function Signal
|
||||
+ * Multiplex Control
|
||||
+ */
|
||||
+ u32 pmuxcr2; /* 0x.0064 - Alternate function signal
|
||||
+ * multiplex control 2
|
||||
+ */
|
||||
+ u32 dmuxcr; /* 0x.0068 - DMA Mux Control Register */
|
||||
u8 res06c[0x70 - 0x6c];
|
||||
- __be32 devdisr; /* 0x.0070 - Device Disable Control */
|
||||
+ u32 devdisr; /* 0x.0070 - Device Disable Control */
|
||||
#define CCSR_GUTS_DEVDISR_TB1 0x00001000
|
||||
#define CCSR_GUTS_DEVDISR_TB0 0x00004000
|
||||
- __be32 devdisr2; /* 0x.0074 - Device Disable Control 2 */
|
||||
+ u32 devdisr2; /* 0x.0074 - Device Disable Control 2 */
|
||||
u8 res078[0x7c - 0x78];
|
||||
- __be32 pmjcr; /* 0x.007c - 4 Power Management Jog Control Register */
|
||||
- __be32 powmgtcsr; /* 0x.0080 - Power Management Status and Control Register */
|
||||
- __be32 pmrccr; /* 0x.0084 - Power Management Reset Counter Configuration Register */
|
||||
- __be32 pmpdccr; /* 0x.0088 - Power Management Power Down Counter Configuration Register */
|
||||
- __be32 pmcdr; /* 0x.008c - 4Power management clock disable register */
|
||||
- __be32 mcpsumr; /* 0x.0090 - Machine Check Summary Register */
|
||||
- __be32 rstrscr; /* 0x.0094 - Reset Request Status and Control Register */
|
||||
- __be32 ectrstcr; /* 0x.0098 - Exception reset control register */
|
||||
- __be32 autorstsr; /* 0x.009c - Automatic reset status register */
|
||||
- __be32 pvr; /* 0x.00a0 - Processor Version Register */
|
||||
- __be32 svr; /* 0x.00a4 - System Version Register */
|
||||
+ u32 pmjcr; /* 0x.007c - 4 Power Management Jog Control
|
||||
+ * Register
|
||||
+ */
|
||||
+ u32 powmgtcsr; /* 0x.0080 - Power Management Status and
|
||||
+ * Control Register
|
||||
+ */
|
||||
+ u32 pmrccr; /* 0x.0084 - Power Management Reset Counter
|
||||
+ * Configuration Register
|
||||
+ */
|
||||
+ u32 pmpdccr; /* 0x.0088 - Power Management Power Down Counter
|
||||
+ * Configuration Register
|
||||
+ */
|
||||
+ u32 pmcdr; /* 0x.008c - 4Power management clock disable
|
||||
+ * register
|
||||
+ */
|
||||
+ u32 mcpsumr; /* 0x.0090 - Machine Check Summary Register */
|
||||
+ u32 rstrscr; /* 0x.0094 - Reset Request Status and
|
||||
+ * Control Register
|
||||
+ */
|
||||
+ u32 ectrstcr; /* 0x.0098 - Exception reset control register */
|
||||
+ u32 autorstsr; /* 0x.009c - Automatic reset status register */
|
||||
+ u32 pvr; /* 0x.00a0 - Processor Version Register */
|
||||
+ u32 svr; /* 0x.00a4 - System Version Register */
|
||||
u8 res0a8[0xb0 - 0xa8];
|
||||
- __be32 rstcr; /* 0x.00b0 - Reset Control Register */
|
||||
+ u32 rstcr; /* 0x.00b0 - Reset Control Register */
|
||||
u8 res0b4[0xc0 - 0xb4];
|
||||
- __be32 iovselsr; /* 0x.00c0 - I/O voltage select status register
|
||||
+ u32 iovselsr; /* 0x.00c0 - I/O voltage select status register
|
||||
Called 'elbcvselcr' on 86xx SOCs */
|
||||
u8 res0c4[0x100 - 0xc4];
|
||||
- __be32 rcwsr[16]; /* 0x.0100 - Reset Control Word Status registers
|
||||
+ u32 rcwsr[16]; /* 0x.0100 - Reset Control Word Status registers
|
||||
There are 16 registers */
|
||||
u8 res140[0x224 - 0x140];
|
||||
- __be32 iodelay1; /* 0x.0224 - IO delay control register 1 */
|
||||
- __be32 iodelay2; /* 0x.0228 - IO delay control register 2 */
|
||||
+ u32 iodelay1; /* 0x.0224 - IO delay control register 1 */
|
||||
+ u32 iodelay2; /* 0x.0228 - IO delay control register 2 */
|
||||
u8 res22c[0x604 - 0x22c];
|
||||
- __be32 pamubypenr; /* 0x.604 - PAMU bypass enable register */
|
||||
+ u32 pamubypenr; /* 0x.604 - PAMU bypass enable register */
|
||||
u8 res608[0x800 - 0x608];
|
||||
- __be32 clkdvdr; /* 0x.0800 - Clock Divide Register */
|
||||
+ u32 clkdvdr; /* 0x.0800 - Clock Divide Register */
|
||||
u8 res804[0x900 - 0x804];
|
||||
- __be32 ircr; /* 0x.0900 - Infrared Control Register */
|
||||
+ u32 ircr; /* 0x.0900 - Infrared Control Register */
|
||||
u8 res904[0x908 - 0x904];
|
||||
- __be32 dmacr; /* 0x.0908 - DMA Control Register */
|
||||
+ u32 dmacr; /* 0x.0908 - DMA Control Register */
|
||||
u8 res90c[0x914 - 0x90c];
|
||||
- __be32 elbccr; /* 0x.0914 - eLBC Control Register */
|
||||
+ u32 elbccr; /* 0x.0914 - eLBC Control Register */
|
||||
u8 res918[0xb20 - 0x918];
|
||||
- __be32 ddr1clkdr; /* 0x.0b20 - DDR1 Clock Disable Register */
|
||||
- __be32 ddr2clkdr; /* 0x.0b24 - DDR2 Clock Disable Register */
|
||||
- __be32 ddrclkdr; /* 0x.0b28 - DDR Clock Disable Register */
|
||||
+ u32 ddr1clkdr; /* 0x.0b20 - DDR1 Clock Disable Register */
|
||||
+ u32 ddr2clkdr; /* 0x.0b24 - DDR2 Clock Disable Register */
|
||||
+ u32 ddrclkdr; /* 0x.0b28 - DDR Clock Disable Register */
|
||||
u8 resb2c[0xe00 - 0xb2c];
|
||||
- __be32 clkocr; /* 0x.0e00 - Clock Out Select Register */
|
||||
+ u32 clkocr; /* 0x.0e00 - Clock Out Select Register */
|
||||
u8 rese04[0xe10 - 0xe04];
|
||||
- __be32 ddrdllcr; /* 0x.0e10 - DDR DLL Control Register */
|
||||
+ u32 ddrdllcr; /* 0x.0e10 - DDR DLL Control Register */
|
||||
u8 rese14[0xe20 - 0xe14];
|
||||
- __be32 lbcdllcr; /* 0x.0e20 - LBC DLL Control Register */
|
||||
- __be32 cpfor; /* 0x.0e24 - L2 charge pump fuse override register */
|
||||
+ u32 lbcdllcr; /* 0x.0e20 - LBC DLL Control Register */
|
||||
+ u32 cpfor; /* 0x.0e24 - L2 charge pump fuse override
|
||||
+ * register
|
||||
+ */
|
||||
u8 rese28[0xf04 - 0xe28];
|
||||
- __be32 srds1cr0; /* 0x.0f04 - SerDes1 Control Register 0 */
|
||||
- __be32 srds1cr1; /* 0x.0f08 - SerDes1 Control Register 0 */
|
||||
+ u32 srds1cr0; /* 0x.0f04 - SerDes1 Control Register 0 */
|
||||
+ u32 srds1cr1; /* 0x.0f08 - SerDes1 Control Register 0 */
|
||||
u8 resf0c[0xf2c - 0xf0c];
|
||||
- __be32 itcr; /* 0x.0f2c - Internal transaction control register */
|
||||
+ u32 itcr; /* 0x.0f2c - Internal transaction control
|
||||
+ * register
|
||||
+ */
|
||||
u8 resf30[0xf40 - 0xf30];
|
||||
- __be32 srds2cr0; /* 0x.0f40 - SerDes2 Control Register 0 */
|
||||
- __be32 srds2cr1; /* 0x.0f44 - SerDes2 Control Register 0 */
|
||||
+ u32 srds2cr0; /* 0x.0f40 - SerDes2 Control Register 0 */
|
||||
+ u32 srds2cr1; /* 0x.0f44 - SerDes2 Control Register 0 */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
+u32 fsl_guts_get_svr(void);
|
||||
|
||||
/* Alternate function signal multiplex control */
|
||||
#define MPC85xx_PMUXCR_QE(x) (0x8000 >> (x))
|
@ -1,360 +0,0 @@
|
||||
From 659aa30c59fb188b533a7edcb9bd38ac007a2739 Mon Sep 17 00:00:00 2001
|
||||
From: Yangbo Lu <yangbo.lu@nxp.com>
|
||||
Date: Wed, 17 Jan 2018 15:35:11 +0800
|
||||
Subject: [PATCH 21/30] i2c: support layerscape
|
||||
|
||||
This is an integrated patch for layerscape i2c support.
|
||||
|
||||
Signed-off-by: Zhang Ying-22455 <ying.zhang22455@nxp.com>
|
||||
Signed-off-by: Priyanka Jain <Priyanka.Jain@freescale.com>
|
||||
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
|
||||
---
|
||||
drivers/i2c/busses/i2c-imx.c | 195 +++++++++++++++++++++++++++++++++++-
|
||||
drivers/i2c/muxes/i2c-mux-pca954x.c | 43 ++++++++
|
||||
2 files changed, 237 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/i2c/busses/i2c-imx.c
|
||||
+++ b/drivers/i2c/busses/i2c-imx.c
|
||||
@@ -53,6 +53,11 @@
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/slab.h>
|
||||
+#include <linux/gpio.h>
|
||||
+#include <linux/of_address.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/of_device.h>
|
||||
+#include <linux/libata.h>
|
||||
|
||||
/* This will be the driver name the kernel reports */
|
||||
#define DRIVER_NAME "imx-i2c"
|
||||
@@ -117,6 +122,54 @@
|
||||
|
||||
#define I2C_PM_TIMEOUT 10 /* ms */
|
||||
|
||||
+enum pinmux_endian_type {
|
||||
+ BIG_ENDIAN,
|
||||
+ LITTLE_ENDIAN,
|
||||
+};
|
||||
+
|
||||
+struct pinmux_cfg {
|
||||
+ enum pinmux_endian_type endian; /* endian of RCWPMUXCR0 */
|
||||
+ u32 pmuxcr_offset;
|
||||
+ u32 pmuxcr_set_bit; /* pin mux of RCWPMUXCR0 */
|
||||
+};
|
||||
+
|
||||
+static struct pinmux_cfg ls1012a_pinmux_cfg = {
|
||||
+ .endian = BIG_ENDIAN,
|
||||
+ .pmuxcr_offset = 0x430,
|
||||
+ .pmuxcr_set_bit = 0x10,
|
||||
+};
|
||||
+
|
||||
+static struct pinmux_cfg ls1043a_pinmux_cfg = {
|
||||
+ .endian = BIG_ENDIAN,
|
||||
+ .pmuxcr_offset = 0x40C,
|
||||
+ .pmuxcr_set_bit = 0x10,
|
||||
+};
|
||||
+
|
||||
+static struct pinmux_cfg ls1046a_pinmux_cfg = {
|
||||
+ .endian = BIG_ENDIAN,
|
||||
+ .pmuxcr_offset = 0x40C,
|
||||
+ .pmuxcr_set_bit = 0x80000000,
|
||||
+};
|
||||
+
|
||||
+static const struct of_device_id pinmux_of_match[] = {
|
||||
+ { .compatible = "fsl,ls1012a-vf610-i2c", .data = &ls1012a_pinmux_cfg},
|
||||
+ { .compatible = "fsl,ls1043a-vf610-i2c", .data = &ls1043a_pinmux_cfg},
|
||||
+ { .compatible = "fsl,ls1046a-vf610-i2c", .data = &ls1046a_pinmux_cfg},
|
||||
+ {},
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, pinmux_of_match);
|
||||
+
|
||||
+/* The SCFG, Supplemental Configuration Unit, provides SoC specific
|
||||
+ * configuration and status registers for the device. There is a
|
||||
+ * SDHC IO VSEL control register on SCFG for some platforms. It's
|
||||
+ * used to support SDHC IO voltage switching.
|
||||
+ */
|
||||
+static const struct of_device_id scfg_device_ids[] = {
|
||||
+ { .compatible = "fsl,ls1012a-scfg", },
|
||||
+ { .compatible = "fsl,ls1043a-scfg", },
|
||||
+ { .compatible = "fsl,ls1046a-scfg", },
|
||||
+ {}
|
||||
+};
|
||||
/*
|
||||
* sorted list of clock divider, register value pairs
|
||||
* taken from table 26-5, p.26-9, Freescale i.MX
|
||||
@@ -210,6 +263,12 @@ struct imx_i2c_struct {
|
||||
struct pinctrl_state *pinctrl_pins_gpio;
|
||||
|
||||
struct imx_i2c_dma *dma;
|
||||
+ int layerscape_bus_recover;
|
||||
+ int gpio;
|
||||
+ int need_set_pmuxcr;
|
||||
+ int pmuxcr_set;
|
||||
+ int pmuxcr_endian;
|
||||
+ void __iomem *pmuxcr_addr;
|
||||
};
|
||||
|
||||
static const struct imx_i2c_hwdata imx1_i2c_hwdata = {
|
||||
@@ -878,6 +937,78 @@ static int i2c_imx_read(struct imx_i2c_s
|
||||
return 0;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Based on the I2C specification, if the data line (SDA) is
|
||||
+ * stuck low, the master should send nine * clock pulses.
|
||||
+ * The I2C slave device that held the bus low should release it
|
||||
+ * sometime within * those nine clocks. Due to this erratum,
|
||||
+ * the I2C controller cannot generate nine clock pulses.
|
||||
+ */
|
||||
+static int i2c_imx_recovery_for_layerscape(struct imx_i2c_struct *i2c_imx)
|
||||
+{
|
||||
+ u32 pmuxcr = 0;
|
||||
+ int ret;
|
||||
+ unsigned int i, temp;
|
||||
+
|
||||
+ /* configure IICx_SCL/GPIO pin as a GPIO */
|
||||
+ if (i2c_imx->need_set_pmuxcr == 1) {
|
||||
+ pmuxcr = ioread32be(i2c_imx->pmuxcr_addr);
|
||||
+ if (i2c_imx->pmuxcr_endian == BIG_ENDIAN)
|
||||
+ iowrite32be(i2c_imx->pmuxcr_set|pmuxcr,
|
||||
+ i2c_imx->pmuxcr_addr);
|
||||
+ else
|
||||
+ iowrite32(i2c_imx->pmuxcr_set|pmuxcr,
|
||||
+ i2c_imx->pmuxcr_addr);
|
||||
+ }
|
||||
+
|
||||
+ ret = gpio_request(i2c_imx->gpio, i2c_imx->adapter.name);
|
||||
+ if (ret) {
|
||||
+ dev_err(&i2c_imx->adapter.dev,
|
||||
+ "can't get gpio: %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ /* Configure GPIO pin as an output and open drain. */
|
||||
+ gpio_direction_output(i2c_imx->gpio, 1);
|
||||
+ udelay(10);
|
||||
+
|
||||
+ /* Write data to generate 9 pulses */
|
||||
+ for (i = 0; i < 9; i++) {
|
||||
+ gpio_set_value(i2c_imx->gpio, 1);
|
||||
+ udelay(10);
|
||||
+ gpio_set_value(i2c_imx->gpio, 0);
|
||||
+ udelay(10);
|
||||
+ }
|
||||
+ /* ensure that the last level sent is always high */
|
||||
+ gpio_set_value(i2c_imx->gpio, 1);
|
||||
+
|
||||
+ /*
|
||||
+ * Set I2Cx_IBCR = 0h00 to generate a STOP and then
|
||||
+ * set I2Cx_IBCR = 0h80 to reset
|
||||
+ */
|
||||
+ temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR);
|
||||
+ temp &= ~(I2CR_MSTA | I2CR_MTX);
|
||||
+ imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
|
||||
+
|
||||
+ /* Restore the saved value of the register SCFG_RCWPMUXCR0 */
|
||||
+ if (i2c_imx->need_set_pmuxcr == 1) {
|
||||
+ if (i2c_imx->pmuxcr_endian == BIG_ENDIAN)
|
||||
+ iowrite32be(pmuxcr, i2c_imx->pmuxcr_addr);
|
||||
+ else
|
||||
+ iowrite32(pmuxcr, i2c_imx->pmuxcr_addr);
|
||||
+ }
|
||||
+ /*
|
||||
+ * Set I2C_IBSR[IBAL] to clear the IBAL bit if-
|
||||
+ * I2C_IBSR[IBAL] = 1
|
||||
+ */
|
||||
+ temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2SR);
|
||||
+ if (temp & I2SR_IAL) {
|
||||
+ temp &= ~I2SR_IAL;
|
||||
+ imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2SR);
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int i2c_imx_xfer(struct i2c_adapter *adapter,
|
||||
struct i2c_msg *msgs, int num)
|
||||
{
|
||||
@@ -888,6 +1019,19 @@ static int i2c_imx_xfer(struct i2c_adapt
|
||||
|
||||
dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
|
||||
|
||||
+ /*
|
||||
+ * workround for ERR010027: ensure that the I2C BUS is idle
|
||||
+ * before switching to master mode and attempting a Start cycle
|
||||
+ */
|
||||
+ result = i2c_imx_bus_busy(i2c_imx, 0);
|
||||
+ if (result) {
|
||||
+ /* timeout */
|
||||
+ if ((result == -ETIMEDOUT) && (i2c_imx->layerscape_bus_recover == 1))
|
||||
+ i2c_imx_recovery_for_layerscape(i2c_imx);
|
||||
+ else
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
result = pm_runtime_get_sync(i2c_imx->adapter.dev.parent);
|
||||
if (result < 0)
|
||||
goto out;
|
||||
@@ -1030,6 +1174,50 @@ static int i2c_imx_init_recovery_info(st
|
||||
return 0;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * switch SCL and SDA to their GPIO function and do some bitbanging
|
||||
+ * for bus recovery.
|
||||
+ * There are platforms such as Layerscape that don't support pinctrl, so add
|
||||
+ * workaround for layerscape, it has no effect for other platforms.
|
||||
+ */
|
||||
+static int i2c_imx_init_recovery_for_layerscape(
|
||||
+ struct imx_i2c_struct *i2c_imx,
|
||||
+ struct platform_device *pdev)
|
||||
+{
|
||||
+ const struct of_device_id *of_id;
|
||||
+ struct device_node *np = pdev->dev.of_node;
|
||||
+ struct pinmux_cfg *pinmux_cfg;
|
||||
+ struct device_node *scfg_node;
|
||||
+ void __iomem *scfg_base = NULL;
|
||||
+
|
||||
+ i2c_imx->gpio = of_get_named_gpio(np, "fsl-scl-gpio", 0);
|
||||
+ if (!gpio_is_valid(i2c_imx->gpio)) {
|
||||
+ dev_info(&pdev->dev, "fsl-scl-gpio not found\n");
|
||||
+ return 0;
|
||||
+ }
|
||||
+ pinmux_cfg = devm_kzalloc(&pdev->dev, sizeof(*pinmux_cfg), GFP_KERNEL);
|
||||
+ if (!pinmux_cfg)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ i2c_imx->need_set_pmuxcr = 0;
|
||||
+ of_id = of_match_node(pinmux_of_match, np);
|
||||
+ if (of_id) {
|
||||
+ pinmux_cfg = (struct pinmux_cfg *)of_id->data;
|
||||
+ i2c_imx->pmuxcr_endian = pinmux_cfg->endian;
|
||||
+ i2c_imx->pmuxcr_set = pinmux_cfg->pmuxcr_set_bit;
|
||||
+ scfg_node = of_find_matching_node(NULL, scfg_device_ids);
|
||||
+ if (scfg_node) {
|
||||
+ scfg_base = of_iomap(scfg_node, 0);
|
||||
+ if (scfg_base) {
|
||||
+ i2c_imx->pmuxcr_addr = scfg_base + pinmux_cfg->pmuxcr_offset;
|
||||
+ i2c_imx->need_set_pmuxcr = 1;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ i2c_imx->layerscape_bus_recover = 1;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static u32 i2c_imx_func(struct i2c_adapter *adapter)
|
||||
{
|
||||
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL
|
||||
@@ -1085,6 +1273,11 @@ static int i2c_imx_probe(struct platform
|
||||
i2c_imx->adapter.dev.of_node = pdev->dev.of_node;
|
||||
i2c_imx->base = base;
|
||||
|
||||
+ /* Init optional bus recovery for layerscape */
|
||||
+ ret = i2c_imx_init_recovery_for_layerscape(i2c_imx, pdev);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
/* Get I2C clock */
|
||||
i2c_imx->clk = devm_clk_get(&pdev->dev, NULL);
|
||||
if (IS_ERR(i2c_imx->clk)) {
|
||||
@@ -1099,7 +1292,7 @@ static int i2c_imx_probe(struct platform
|
||||
}
|
||||
|
||||
/* Request IRQ */
|
||||
- ret = devm_request_irq(&pdev->dev, irq, i2c_imx_isr, 0,
|
||||
+ ret = devm_request_irq(&pdev->dev, irq, i2c_imx_isr, IRQF_SHARED,
|
||||
pdev->name, i2c_imx);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "can't claim irq %d\n", irq);
|
||||
--- a/drivers/i2c/muxes/i2c-mux-pca954x.c
|
||||
+++ b/drivers/i2c/muxes/i2c-mux-pca954x.c
|
||||
@@ -74,6 +74,7 @@ struct pca954x {
|
||||
u8 last_chan; /* last register value */
|
||||
u8 deselect;
|
||||
struct i2c_client *client;
|
||||
+ u8 disable_mux; /* do not disable mux if val not 0 */
|
||||
};
|
||||
|
||||
/* Provide specs for the PCA954x types we know about */
|
||||
@@ -196,6 +197,13 @@ static int pca954x_deselect_mux(struct i
|
||||
if (!(data->deselect & (1 << chan)))
|
||||
return 0;
|
||||
|
||||
+#ifdef CONFIG_ARCH_LAYERSCAPE
|
||||
+ if (data->disable_mux != 0)
|
||||
+ data->last_chan = data->chip->nchans;
|
||||
+ else
|
||||
+ data->last_chan = 0;
|
||||
+ return pca954x_reg_write(muxc->parent, client, data->disable_mux);
|
||||
+#endif
|
||||
/* Deselect active channel */
|
||||
data->last_chan = 0;
|
||||
return pca954x_reg_write(muxc->parent, client, data->last_chan);
|
||||
@@ -228,6 +236,28 @@ static int pca954x_probe(struct i2c_clie
|
||||
return -ENOMEM;
|
||||
data = i2c_mux_priv(muxc);
|
||||
|
||||
+#ifdef CONFIG_ARCH_LAYERSCAPE
|
||||
+ /* The point here is that you must not disable a mux if there
|
||||
+ * are no pullups on the input or you mess up the I2C. This
|
||||
+ * needs to be put into the DTS really as the kernel cannot
|
||||
+ * know this otherwise.
|
||||
+ */
|
||||
+ match = of_match_device(of_match_ptr(pca954x_of_match), &client->dev);
|
||||
+ if (match)
|
||||
+ data->chip = of_device_get_match_data(&client->dev);
|
||||
+ else
|
||||
+ data->chip = &chips[id->driver_data];
|
||||
+
|
||||
+ data->disable_mux = of_node &&
|
||||
+ of_property_read_bool(of_node, "i2c-mux-never-disable") &&
|
||||
+ data->chip->muxtype == pca954x_ismux ?
|
||||
+ data->chip->enable : 0;
|
||||
+ /* force the first selection */
|
||||
+ if (data->disable_mux != 0)
|
||||
+ data->last_chan = data->chip->nchans;
|
||||
+ else
|
||||
+ data->last_chan = 0;
|
||||
+#endif
|
||||
i2c_set_clientdata(client, muxc);
|
||||
data->client = client;
|
||||
|
||||
@@ -240,11 +270,16 @@ static int pca954x_probe(struct i2c_clie
|
||||
* that the mux is in fact present. This also
|
||||
* initializes the mux to disconnected state.
|
||||
*/
|
||||
+#ifdef CONFIG_ARCH_LAYERSCAPE
|
||||
+ if (i2c_smbus_write_byte(client, data->disable_mux) < 0) {
|
||||
+#else
|
||||
if (i2c_smbus_write_byte(client, 0) < 0) {
|
||||
+#endif
|
||||
dev_warn(&client->dev, "probe failed\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
+#ifndef CONFIG_ARCH_LAYERSCAPE
|
||||
match = of_match_device(of_match_ptr(pca954x_of_match), &client->dev);
|
||||
if (match)
|
||||
data->chip = of_device_get_match_data(&client->dev);
|
||||
@@ -252,6 +287,7 @@ static int pca954x_probe(struct i2c_clie
|
||||
data->chip = &chips[id->driver_data];
|
||||
|
||||
data->last_chan = 0; /* force the first selection */
|
||||
+#endif
|
||||
|
||||
idle_disconnect_dt = of_node &&
|
||||
of_property_read_bool(of_node, "i2c-mux-idle-disconnect");
|
||||
@@ -312,6 +348,13 @@ static int pca954x_resume(struct device
|
||||
struct i2c_mux_core *muxc = i2c_get_clientdata(client);
|
||||
struct pca954x *data = i2c_mux_priv(muxc);
|
||||
|
||||
+#ifdef CONFIG_ARCH_LAYERSCAPE
|
||||
+ if (data->disable_mux != 0)
|
||||
+ data->last_chan = data->chip->nchans;
|
||||
+ else
|
||||
+ data->last_chan = 0;
|
||||
+ return i2c_smbus_write_byte(client, data->disable_mux);
|
||||
+#endif
|
||||
data->last_chan = 0;
|
||||
return i2c_smbus_write_byte(client, 0);
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,182 +0,0 @@
|
||||
From dab02a7cc54494740e849cd51b554d100eb5541d Mon Sep 17 00:00:00 2001
|
||||
From: Yangbo Lu <yangbo.lu@nxp.com>
|
||||
Date: Thu, 5 Jul 2018 17:36:09 +0800
|
||||
Subject: [PATCH 23/32] irqchip: support layerscape
|
||||
|
||||
This is an integrated patch for layerscape gic support.
|
||||
|
||||
Signed-off-by: Eric Auger <eric.auger@redhat.com>
|
||||
Signed-off-by: Zhao Qiang <qiang.zhao@nxp.com>
|
||||
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
|
||||
---
|
||||
drivers/irqchip/Makefile | 1 +
|
||||
drivers/irqchip/irq-gic-v3-its.c | 1 +
|
||||
include/linux/irqchip/arm-gic-v3.h | 3 +++
|
||||
include/linux/irqdomain.h | 36 +++++++++++++++++++++++++++
|
||||
kernel/irq/irqdomain.c | 39 ++++++++++++++++++++++++++++++
|
||||
kernel/irq/msi.c | 4 +--
|
||||
6 files changed, 82 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/irqchip/Makefile
|
||||
+++ b/drivers/irqchip/Makefile
|
||||
@@ -75,3 +75,4 @@ obj-$(CONFIG_LS_SCFG_MSI) += irq-ls-scf
|
||||
obj-$(CONFIG_EZNPS_GIC) += irq-eznps.o
|
||||
obj-$(CONFIG_ARCH_ASPEED) += irq-aspeed-vic.o
|
||||
obj-$(CONFIG_STM32_EXTI) += irq-stm32-exti.o
|
||||
+obj-$(CONFIG_QUICC_ENGINE) += irq-qeic.o
|
||||
--- a/drivers/irqchip/irq-gic-v3-its.c
|
||||
+++ b/drivers/irqchip/irq-gic-v3-its.c
|
||||
@@ -1658,6 +1658,7 @@ static int its_init_domain(struct fwnode
|
||||
|
||||
inner_domain->parent = its_parent;
|
||||
inner_domain->bus_token = DOMAIN_BUS_NEXUS;
|
||||
+ inner_domain->flags |= IRQ_DOMAIN_FLAG_MSI_REMAP;
|
||||
info->ops = &its_msi_domain_ops;
|
||||
info->data = its;
|
||||
inner_domain->host_data = info;
|
||||
--- a/include/linux/irqchip/arm-gic-v3.h
|
||||
+++ b/include/linux/irqchip/arm-gic-v3.h
|
||||
@@ -133,6 +133,9 @@
|
||||
#define GIC_BASER_SHAREABILITY(reg, type) \
|
||||
(GIC_BASER_##type << reg##_SHAREABILITY_SHIFT)
|
||||
|
||||
+/* encode a size field of width @w containing @n - 1 units */
|
||||
+#define GIC_ENCODE_SZ(n, w) (((unsigned long)(n) - 1) & GENMASK_ULL(((w) - 1), 0))
|
||||
+
|
||||
#define GICR_PROPBASER_SHAREABILITY_SHIFT (10)
|
||||
#define GICR_PROPBASER_INNER_CACHEABILITY_SHIFT (7)
|
||||
#define GICR_PROPBASER_OUTER_CACHEABILITY_SHIFT (56)
|
||||
--- a/include/linux/irqdomain.h
|
||||
+++ b/include/linux/irqdomain.h
|
||||
@@ -187,6 +187,12 @@ enum {
|
||||
/* Irq domain is an IPI domain with single virq */
|
||||
IRQ_DOMAIN_FLAG_IPI_SINGLE = (1 << 3),
|
||||
|
||||
+ /* Irq domain implements MSIs */
|
||||
+ IRQ_DOMAIN_FLAG_MSI = (1 << 4),
|
||||
+
|
||||
+ /* Irq domain implements MSI remapping */
|
||||
+ IRQ_DOMAIN_FLAG_MSI_REMAP = (1 << 5),
|
||||
+
|
||||
/*
|
||||
* Flags starting from IRQ_DOMAIN_FLAG_NONCORE are reserved
|
||||
* for implementation specific purposes and ignored by the
|
||||
@@ -220,6 +226,7 @@ struct irq_domain *irq_domain_add_legacy
|
||||
void *host_data);
|
||||
extern struct irq_domain *irq_find_matching_fwspec(struct irq_fwspec *fwspec,
|
||||
enum irq_domain_bus_token bus_token);
|
||||
+extern bool irq_domain_check_msi_remap(void);
|
||||
extern void irq_set_default_host(struct irq_domain *host);
|
||||
extern int irq_domain_alloc_descs(int virq, unsigned int nr_irqs,
|
||||
irq_hw_number_t hwirq, int node,
|
||||
@@ -453,6 +460,19 @@ static inline bool irq_domain_is_ipi_sin
|
||||
{
|
||||
return domain->flags & IRQ_DOMAIN_FLAG_IPI_SINGLE;
|
||||
}
|
||||
+
|
||||
+static inline bool irq_domain_is_msi(struct irq_domain *domain)
|
||||
+{
|
||||
+ return domain->flags & IRQ_DOMAIN_FLAG_MSI;
|
||||
+}
|
||||
+
|
||||
+static inline bool irq_domain_is_msi_remap(struct irq_domain *domain)
|
||||
+{
|
||||
+ return domain->flags & IRQ_DOMAIN_FLAG_MSI_REMAP;
|
||||
+}
|
||||
+
|
||||
+extern bool irq_domain_hierarchical_is_msi_remap(struct irq_domain *domain);
|
||||
+
|
||||
#else /* CONFIG_IRQ_DOMAIN_HIERARCHY */
|
||||
static inline void irq_domain_activate_irq(struct irq_data *data) { }
|
||||
static inline void irq_domain_deactivate_irq(struct irq_data *data) { }
|
||||
@@ -484,6 +504,22 @@ static inline bool irq_domain_is_ipi_sin
|
||||
{
|
||||
return false;
|
||||
}
|
||||
+
|
||||
+static inline bool irq_domain_is_msi(struct irq_domain *domain)
|
||||
+{
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+static inline bool irq_domain_is_msi_remap(struct irq_domain *domain)
|
||||
+{
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+static inline bool
|
||||
+irq_domain_hierarchical_is_msi_remap(struct irq_domain *domain)
|
||||
+{
|
||||
+ return false;
|
||||
+}
|
||||
#endif /* CONFIG_IRQ_DOMAIN_HIERARCHY */
|
||||
|
||||
#else /* CONFIG_IRQ_DOMAIN */
|
||||
--- a/kernel/irq/irqdomain.c
|
||||
+++ b/kernel/irq/irqdomain.c
|
||||
@@ -319,6 +319,31 @@ struct irq_domain *irq_find_matching_fws
|
||||
EXPORT_SYMBOL_GPL(irq_find_matching_fwspec);
|
||||
|
||||
/**
|
||||
+ * irq_domain_check_msi_remap - Check whether all MSI irq domains implement
|
||||
+ * IRQ remapping
|
||||
+ *
|
||||
+ * Return: false if any MSI irq domain does not support IRQ remapping,
|
||||
+ * true otherwise (including if there is no MSI irq domain)
|
||||
+ */
|
||||
+bool irq_domain_check_msi_remap(void)
|
||||
+{
|
||||
+ struct irq_domain *h;
|
||||
+ bool ret = true;
|
||||
+
|
||||
+ mutex_lock(&irq_domain_mutex);
|
||||
+ list_for_each_entry(h, &irq_domain_list, link) {
|
||||
+ if (irq_domain_is_msi(h) &&
|
||||
+ !irq_domain_hierarchical_is_msi_remap(h)) {
|
||||
+ ret = false;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ mutex_unlock(&irq_domain_mutex);
|
||||
+ return ret;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(irq_domain_check_msi_remap);
|
||||
+
|
||||
+/**
|
||||
* irq_set_default_host() - Set a "default" irq domain
|
||||
* @domain: default domain pointer
|
||||
*
|
||||
@@ -1420,6 +1445,20 @@ static void irq_domain_check_hierarchy(s
|
||||
if (domain->ops->alloc)
|
||||
domain->flags |= IRQ_DOMAIN_FLAG_HIERARCHY;
|
||||
}
|
||||
+
|
||||
+/**
|
||||
+ * irq_domain_hierarchical_is_msi_remap - Check if the domain or any
|
||||
+ * parent has MSI remapping support
|
||||
+ * @domain: domain pointer
|
||||
+ */
|
||||
+bool irq_domain_hierarchical_is_msi_remap(struct irq_domain *domain)
|
||||
+{
|
||||
+ for (; domain; domain = domain->parent) {
|
||||
+ if (irq_domain_is_msi_remap(domain))
|
||||
+ return true;
|
||||
+ }
|
||||
+ return false;
|
||||
+}
|
||||
#else /* CONFIG_IRQ_DOMAIN_HIERARCHY */
|
||||
/**
|
||||
* irq_domain_get_irq_data - Get irq_data associated with @virq and @domain
|
||||
--- a/kernel/irq/msi.c
|
||||
+++ b/kernel/irq/msi.c
|
||||
@@ -272,8 +272,8 @@ struct irq_domain *msi_create_irq_domain
|
||||
if (info->flags & MSI_FLAG_USE_DEF_CHIP_OPS)
|
||||
msi_domain_update_chip_ops(info);
|
||||
|
||||
- return irq_domain_create_hierarchy(parent, 0, 0, fwnode,
|
||||
- &msi_domain_ops, info);
|
||||
+ return irq_domain_create_hierarchy(parent, IRQ_DOMAIN_FLAG_MSI, 0,
|
||||
+ fwnode, &msi_domain_ops, info);
|
||||
}
|
||||
|
||||
int msi_domain_prepare_irqs(struct irq_domain *domain, struct device *dev,
|
@ -1,594 +0,0 @@
|
||||
From 4215d5757595e7ec7ca146c2b901beb177f415d8 Mon Sep 17 00:00:00 2001
|
||||
From: Yangbo Lu <yangbo.lu@nxp.com>
|
||||
Date: Wed, 17 Jan 2018 15:37:13 +0800
|
||||
Subject: [PATCH 24/30] mmc: layerscape support
|
||||
|
||||
This is an integrated patch for layerscape mmc support.
|
||||
|
||||
Adrian Hunter <adrian.hunter@intel.com>
|
||||
Jaehoon Chung <jh80.chung@samsung.com>
|
||||
Masahiro Yamada <yamada.masahiro@socionext.com>
|
||||
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
|
||||
---
|
||||
drivers/mmc/host/Kconfig | 1 +
|
||||
drivers/mmc/host/sdhci-esdhc.h | 52 +++++---
|
||||
drivers/mmc/host/sdhci-of-esdhc.c | 265 ++++++++++++++++++++++++++++++++++++--
|
||||
drivers/mmc/host/sdhci.c | 45 ++++---
|
||||
drivers/mmc/host/sdhci.h | 3 +
|
||||
5 files changed, 320 insertions(+), 46 deletions(-)
|
||||
|
||||
--- a/drivers/mmc/host/Kconfig
|
||||
+++ b/drivers/mmc/host/Kconfig
|
||||
@@ -144,6 +144,7 @@ config MMC_SDHCI_OF_ESDHC
|
||||
depends on MMC_SDHCI_PLTFM
|
||||
depends on PPC || ARCH_MXC || ARCH_LAYERSCAPE
|
||||
select MMC_SDHCI_IO_ACCESSORS
|
||||
+ select FSL_GUTS
|
||||
help
|
||||
This selects the Freescale eSDHC controller support.
|
||||
|
||||
--- a/drivers/mmc/host/sdhci-esdhc.h
|
||||
+++ b/drivers/mmc/host/sdhci-esdhc.h
|
||||
@@ -24,30 +24,46 @@
|
||||
SDHCI_QUIRK_PIO_NEEDS_DELAY | \
|
||||
SDHCI_QUIRK_NO_HISPD_BIT)
|
||||
|
||||
-#define ESDHC_PROCTL 0x28
|
||||
-
|
||||
-#define ESDHC_SYSTEM_CONTROL 0x2c
|
||||
-#define ESDHC_CLOCK_MASK 0x0000fff0
|
||||
-#define ESDHC_PREDIV_SHIFT 8
|
||||
-#define ESDHC_DIVIDER_SHIFT 4
|
||||
-#define ESDHC_CLOCK_PEREN 0x00000004
|
||||
-#define ESDHC_CLOCK_HCKEN 0x00000002
|
||||
-#define ESDHC_CLOCK_IPGEN 0x00000001
|
||||
-
|
||||
/* pltfm-specific */
|
||||
#define ESDHC_HOST_CONTROL_LE 0x20
|
||||
|
||||
/*
|
||||
- * P2020 interpretation of the SDHCI_HOST_CONTROL register
|
||||
+ * eSDHC register definition
|
||||
*/
|
||||
-#define ESDHC_CTRL_4BITBUS (0x1 << 1)
|
||||
-#define ESDHC_CTRL_8BITBUS (0x2 << 1)
|
||||
-#define ESDHC_CTRL_BUSWIDTH_MASK (0x3 << 1)
|
||||
-
|
||||
-/* OF-specific */
|
||||
-#define ESDHC_DMA_SYSCTL 0x40c
|
||||
-#define ESDHC_DMA_SNOOP 0x00000040
|
||||
|
||||
-#define ESDHC_HOST_CONTROL_RES 0x01
|
||||
+/* Present State Register */
|
||||
+#define ESDHC_PRSSTAT 0x24
|
||||
+#define ESDHC_CLOCK_STABLE 0x00000008
|
||||
+
|
||||
+/* Protocol Control Register */
|
||||
+#define ESDHC_PROCTL 0x28
|
||||
+#define ESDHC_VOLT_SEL 0x00000400
|
||||
+#define ESDHC_CTRL_4BITBUS (0x1 << 1)
|
||||
+#define ESDHC_CTRL_8BITBUS (0x2 << 1)
|
||||
+#define ESDHC_CTRL_BUSWIDTH_MASK (0x3 << 1)
|
||||
+#define ESDHC_HOST_CONTROL_RES 0x01
|
||||
+
|
||||
+/* System Control Register */
|
||||
+#define ESDHC_SYSTEM_CONTROL 0x2c
|
||||
+#define ESDHC_CLOCK_MASK 0x0000fff0
|
||||
+#define ESDHC_PREDIV_SHIFT 8
|
||||
+#define ESDHC_DIVIDER_SHIFT 4
|
||||
+#define ESDHC_CLOCK_SDCLKEN 0x00000008
|
||||
+#define ESDHC_CLOCK_PEREN 0x00000004
|
||||
+#define ESDHC_CLOCK_HCKEN 0x00000002
|
||||
+#define ESDHC_CLOCK_IPGEN 0x00000001
|
||||
+
|
||||
+/* Host Controller Capabilities Register 2 */
|
||||
+#define ESDHC_CAPABILITIES_1 0x114
|
||||
+
|
||||
+/* Tuning Block Control Register */
|
||||
+#define ESDHC_TBCTL 0x120
|
||||
+#define ESDHC_TB_EN 0x00000004
|
||||
+
|
||||
+/* Control Register for DMA transfer */
|
||||
+#define ESDHC_DMA_SYSCTL 0x40c
|
||||
+#define ESDHC_PERIPHERAL_CLK_SEL 0x00080000
|
||||
+#define ESDHC_FLUSH_ASYNC_FIFO 0x00040000
|
||||
+#define ESDHC_DMA_SNOOP 0x00000040
|
||||
|
||||
#endif /* _DRIVERS_MMC_SDHCI_ESDHC_H */
|
||||
--- a/drivers/mmc/host/sdhci-of-esdhc.c
|
||||
+++ b/drivers/mmc/host/sdhci-of-esdhc.c
|
||||
@@ -16,8 +16,12 @@
|
||||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of.h>
|
||||
+#include <linux/of_address.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/module.h>
|
||||
+#include <linux/sys_soc.h>
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/ktime.h>
|
||||
#include <linux/mmc/host.h>
|
||||
#include "sdhci-pltfm.h"
|
||||
#include "sdhci-esdhc.h"
|
||||
@@ -28,8 +32,12 @@
|
||||
struct sdhci_esdhc {
|
||||
u8 vendor_ver;
|
||||
u8 spec_ver;
|
||||
+ bool quirk_incorrect_hostver;
|
||||
+ unsigned int peripheral_clock;
|
||||
};
|
||||
|
||||
+static void esdhc_clock_enable(struct sdhci_host *host, bool enable);
|
||||
+
|
||||
/**
|
||||
* esdhc_read*_fixup - Fixup the value read from incompatible eSDHC register
|
||||
* to make it compatible with SD spec.
|
||||
@@ -80,6 +88,17 @@ static u32 esdhc_readl_fixup(struct sdhc
|
||||
return ret;
|
||||
}
|
||||
|
||||
+ /*
|
||||
+ * DTS properties of mmc host are used to enable each speed mode
|
||||
+ * according to soc and board capability. So clean up
|
||||
+ * SDR50/SDR104/DDR50 support bits here.
|
||||
+ */
|
||||
+ if (spec_reg == SDHCI_CAPABILITIES_1) {
|
||||
+ ret = value & (~(SDHCI_SUPPORT_SDR50 | SDHCI_SUPPORT_SDR104 |
|
||||
+ SDHCI_SUPPORT_DDR50));
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
ret = value;
|
||||
return ret;
|
||||
}
|
||||
@@ -87,6 +106,8 @@ static u32 esdhc_readl_fixup(struct sdhc
|
||||
static u16 esdhc_readw_fixup(struct sdhci_host *host,
|
||||
int spec_reg, u32 value)
|
||||
{
|
||||
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
|
||||
+ struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host);
|
||||
u16 ret;
|
||||
int shift = (spec_reg & 0x2) * 8;
|
||||
|
||||
@@ -94,6 +115,12 @@ static u16 esdhc_readw_fixup(struct sdhc
|
||||
ret = value & 0xffff;
|
||||
else
|
||||
ret = (value >> shift) & 0xffff;
|
||||
+ /* Workaround for T4240-R1.0-R2.0 eSDHC which has incorrect
|
||||
+ * vendor version and spec version information.
|
||||
+ */
|
||||
+ if ((spec_reg == SDHCI_HOST_VERSION) &&
|
||||
+ (esdhc->quirk_incorrect_hostver))
|
||||
+ ret = (VENDOR_V_23 << SDHCI_VENDOR_VER_SHIFT) | SDHCI_SPEC_200;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -235,7 +262,11 @@ static u32 esdhc_be_readl(struct sdhci_h
|
||||
u32 ret;
|
||||
u32 value;
|
||||
|
||||
- value = ioread32be(host->ioaddr + reg);
|
||||
+ if (reg == SDHCI_CAPABILITIES_1)
|
||||
+ value = ioread32be(host->ioaddr + ESDHC_CAPABILITIES_1);
|
||||
+ else
|
||||
+ value = ioread32be(host->ioaddr + reg);
|
||||
+
|
||||
ret = esdhc_readl_fixup(host, reg, value);
|
||||
|
||||
return ret;
|
||||
@@ -246,7 +277,11 @@ static u32 esdhc_le_readl(struct sdhci_h
|
||||
u32 ret;
|
||||
u32 value;
|
||||
|
||||
- value = ioread32(host->ioaddr + reg);
|
||||
+ if (reg == SDHCI_CAPABILITIES_1)
|
||||
+ value = ioread32(host->ioaddr + ESDHC_CAPABILITIES_1);
|
||||
+ else
|
||||
+ value = ioread32(host->ioaddr + reg);
|
||||
+
|
||||
ret = esdhc_readl_fixup(host, reg, value);
|
||||
|
||||
return ret;
|
||||
@@ -404,15 +439,25 @@ static int esdhc_of_enable_dma(struct sd
|
||||
static unsigned int esdhc_of_get_max_clock(struct sdhci_host *host)
|
||||
{
|
||||
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
|
||||
+ struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host);
|
||||
|
||||
- return pltfm_host->clock;
|
||||
+ if (esdhc->peripheral_clock)
|
||||
+ return esdhc->peripheral_clock;
|
||||
+ else
|
||||
+ return pltfm_host->clock;
|
||||
}
|
||||
|
||||
static unsigned int esdhc_of_get_min_clock(struct sdhci_host *host)
|
||||
{
|
||||
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
|
||||
+ struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host);
|
||||
+ unsigned int clock;
|
||||
|
||||
- return pltfm_host->clock / 256 / 16;
|
||||
+ if (esdhc->peripheral_clock)
|
||||
+ clock = esdhc->peripheral_clock;
|
||||
+ else
|
||||
+ clock = pltfm_host->clock;
|
||||
+ return clock / 256 / 16;
|
||||
}
|
||||
|
||||
static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)
|
||||
@@ -421,12 +466,15 @@ static void esdhc_of_set_clock(struct sd
|
||||
struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host);
|
||||
int pre_div = 1;
|
||||
int div = 1;
|
||||
+ ktime_t timeout;
|
||||
u32 temp;
|
||||
|
||||
host->mmc->actual_clock = 0;
|
||||
|
||||
- if (clock == 0)
|
||||
+ if (clock == 0) {
|
||||
+ esdhc_clock_enable(host, false);
|
||||
return;
|
||||
+ }
|
||||
|
||||
/* Workaround to start pre_div at 2 for VNN < VENDOR_V_23 */
|
||||
if (esdhc->vendor_ver < VENDOR_V_23)
|
||||
@@ -454,9 +502,15 @@ static void esdhc_of_set_clock(struct sd
|
||||
clock -= 5000000;
|
||||
}
|
||||
|
||||
+ /* Workaround to reduce the clock frequency for ls1021a esdhc */
|
||||
+ if (of_find_compatible_node(NULL, NULL, "fsl,ls1021a-esdhc")) {
|
||||
+ if (clock == 50000000)
|
||||
+ clock = 46500000;
|
||||
+ }
|
||||
+
|
||||
temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL);
|
||||
- temp &= ~(ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN
|
||||
- | ESDHC_CLOCK_MASK);
|
||||
+ temp &= ~(ESDHC_CLOCK_SDCLKEN | ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN |
|
||||
+ ESDHC_CLOCK_PEREN | ESDHC_CLOCK_MASK);
|
||||
sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
|
||||
|
||||
while (host->max_clk / pre_div / 16 > clock && pre_div < 256)
|
||||
@@ -476,7 +530,20 @@ static void esdhc_of_set_clock(struct sd
|
||||
| (div << ESDHC_DIVIDER_SHIFT)
|
||||
| (pre_div << ESDHC_PREDIV_SHIFT));
|
||||
sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
|
||||
- mdelay(1);
|
||||
+
|
||||
+ /* Wait max 20 ms */
|
||||
+ timeout = ktime_add_ms(ktime_get(), 20);
|
||||
+ while (!(sdhci_readl(host, ESDHC_PRSSTAT) & ESDHC_CLOCK_STABLE)) {
|
||||
+ if (ktime_after(ktime_get(), timeout)) {
|
||||
+ pr_err("%s: Internal clock never stabilised.\n",
|
||||
+ mmc_hostname(host->mmc));
|
||||
+ return;
|
||||
+ }
|
||||
+ udelay(10);
|
||||
+ }
|
||||
+
|
||||
+ temp |= ESDHC_CLOCK_SDCLKEN;
|
||||
+ sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
|
||||
}
|
||||
|
||||
static void esdhc_pltfm_set_bus_width(struct sdhci_host *host, int width)
|
||||
@@ -501,12 +568,136 @@ static void esdhc_pltfm_set_bus_width(st
|
||||
sdhci_writel(host, ctrl, ESDHC_PROCTL);
|
||||
}
|
||||
|
||||
+static void esdhc_clock_enable(struct sdhci_host *host, bool enable)
|
||||
+{
|
||||
+ u32 val;
|
||||
+ ktime_t timeout;
|
||||
+
|
||||
+ val = sdhci_readl(host, ESDHC_SYSTEM_CONTROL);
|
||||
+
|
||||
+ if (enable)
|
||||
+ val |= ESDHC_CLOCK_SDCLKEN;
|
||||
+ else
|
||||
+ val &= ~ESDHC_CLOCK_SDCLKEN;
|
||||
+
|
||||
+ sdhci_writel(host, val, ESDHC_SYSTEM_CONTROL);
|
||||
+
|
||||
+ /* Wait max 20 ms */
|
||||
+ timeout = ktime_add_ms(ktime_get(), 20);
|
||||
+ val = ESDHC_CLOCK_STABLE;
|
||||
+ while (!(sdhci_readl(host, ESDHC_PRSSTAT) & val)) {
|
||||
+ if (ktime_after(ktime_get(), timeout)) {
|
||||
+ pr_err("%s: Internal clock never stabilised.\n",
|
||||
+ mmc_hostname(host->mmc));
|
||||
+ break;
|
||||
+ }
|
||||
+ udelay(10);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void esdhc_reset(struct sdhci_host *host, u8 mask)
|
||||
{
|
||||
+ u32 val;
|
||||
+
|
||||
sdhci_reset(host, mask);
|
||||
|
||||
sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
|
||||
sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
|
||||
+
|
||||
+ if (mask & SDHCI_RESET_ALL) {
|
||||
+ val = sdhci_readl(host, ESDHC_TBCTL);
|
||||
+ val &= ~ESDHC_TB_EN;
|
||||
+ sdhci_writel(host, val, ESDHC_TBCTL);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/* The SCFG, Supplemental Configuration Unit, provides SoC specific
|
||||
+ * configuration and status registers for the device. There is a
|
||||
+ * SDHC IO VSEL control register on SCFG for some platforms. It's
|
||||
+ * used to support SDHC IO voltage switching.
|
||||
+ */
|
||||
+static const struct of_device_id scfg_device_ids[] = {
|
||||
+ { .compatible = "fsl,t1040-scfg", },
|
||||
+ { .compatible = "fsl,ls1012a-scfg", },
|
||||
+ { .compatible = "fsl,ls1046a-scfg", },
|
||||
+ {}
|
||||
+};
|
||||
+
|
||||
+/* SDHC IO VSEL control register definition */
|
||||
+#define SCFG_SDHCIOVSELCR 0x408
|
||||
+#define SDHCIOVSELCR_TGLEN 0x80000000
|
||||
+#define SDHCIOVSELCR_VSELVAL 0x60000000
|
||||
+#define SDHCIOVSELCR_SDHC_VS 0x00000001
|
||||
+
|
||||
+static int esdhc_signal_voltage_switch(struct mmc_host *mmc,
|
||||
+ struct mmc_ios *ios)
|
||||
+{
|
||||
+ struct sdhci_host *host = mmc_priv(mmc);
|
||||
+ struct device_node *scfg_node;
|
||||
+ void __iomem *scfg_base = NULL;
|
||||
+ u32 sdhciovselcr;
|
||||
+ u32 val;
|
||||
+
|
||||
+ /*
|
||||
+ * Signal Voltage Switching is only applicable for Host Controllers
|
||||
+ * v3.00 and above.
|
||||
+ */
|
||||
+ if (host->version < SDHCI_SPEC_300)
|
||||
+ return 0;
|
||||
+
|
||||
+ val = sdhci_readl(host, ESDHC_PROCTL);
|
||||
+
|
||||
+ switch (ios->signal_voltage) {
|
||||
+ case MMC_SIGNAL_VOLTAGE_330:
|
||||
+ val &= ~ESDHC_VOLT_SEL;
|
||||
+ sdhci_writel(host, val, ESDHC_PROCTL);
|
||||
+ return 0;
|
||||
+ case MMC_SIGNAL_VOLTAGE_180:
|
||||
+ scfg_node = of_find_matching_node(NULL, scfg_device_ids);
|
||||
+ if (scfg_node)
|
||||
+ scfg_base = of_iomap(scfg_node, 0);
|
||||
+ if (scfg_base) {
|
||||
+ sdhciovselcr = SDHCIOVSELCR_TGLEN |
|
||||
+ SDHCIOVSELCR_VSELVAL;
|
||||
+ iowrite32be(sdhciovselcr,
|
||||
+ scfg_base + SCFG_SDHCIOVSELCR);
|
||||
+
|
||||
+ val |= ESDHC_VOLT_SEL;
|
||||
+ sdhci_writel(host, val, ESDHC_PROCTL);
|
||||
+ mdelay(5);
|
||||
+
|
||||
+ sdhciovselcr = SDHCIOVSELCR_TGLEN |
|
||||
+ SDHCIOVSELCR_SDHC_VS;
|
||||
+ iowrite32be(sdhciovselcr,
|
||||
+ scfg_base + SCFG_SDHCIOVSELCR);
|
||||
+ iounmap(scfg_base);
|
||||
+ } else {
|
||||
+ val |= ESDHC_VOLT_SEL;
|
||||
+ sdhci_writel(host, val, ESDHC_PROCTL);
|
||||
+ }
|
||||
+ return 0;
|
||||
+ default:
|
||||
+ return 0;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int esdhc_execute_tuning(struct mmc_host *mmc, u32 opcode)
|
||||
+{
|
||||
+ struct sdhci_host *host = mmc_priv(mmc);
|
||||
+ u32 val;
|
||||
+
|
||||
+ /* Use tuning block for tuning procedure */
|
||||
+ esdhc_clock_enable(host, false);
|
||||
+ val = sdhci_readl(host, ESDHC_DMA_SYSCTL);
|
||||
+ val |= ESDHC_FLUSH_ASYNC_FIFO;
|
||||
+ sdhci_writel(host, val, ESDHC_DMA_SYSCTL);
|
||||
+
|
||||
+ val = sdhci_readl(host, ESDHC_TBCTL);
|
||||
+ val |= ESDHC_TB_EN;
|
||||
+ sdhci_writel(host, val, ESDHC_TBCTL);
|
||||
+ esdhc_clock_enable(host, true);
|
||||
+
|
||||
+ return sdhci_execute_tuning(mmc, opcode);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
@@ -589,10 +780,19 @@ static const struct sdhci_pltfm_data sdh
|
||||
.ops = &sdhci_esdhc_le_ops,
|
||||
};
|
||||
|
||||
+static struct soc_device_attribute soc_incorrect_hostver[] = {
|
||||
+ { .family = "QorIQ T4240", .revision = "1.0", },
|
||||
+ { .family = "QorIQ T4240", .revision = "2.0", },
|
||||
+ { },
|
||||
+};
|
||||
+
|
||||
static void esdhc_init(struct platform_device *pdev, struct sdhci_host *host)
|
||||
{
|
||||
struct sdhci_pltfm_host *pltfm_host;
|
||||
struct sdhci_esdhc *esdhc;
|
||||
+ struct device_node *np;
|
||||
+ struct clk *clk;
|
||||
+ u32 val;
|
||||
u16 host_ver;
|
||||
|
||||
pltfm_host = sdhci_priv(host);
|
||||
@@ -602,6 +802,36 @@ static void esdhc_init(struct platform_d
|
||||
esdhc->vendor_ver = (host_ver & SDHCI_VENDOR_VER_MASK) >>
|
||||
SDHCI_VENDOR_VER_SHIFT;
|
||||
esdhc->spec_ver = host_ver & SDHCI_SPEC_VER_MASK;
|
||||
+ if (soc_device_match(soc_incorrect_hostver))
|
||||
+ esdhc->quirk_incorrect_hostver = true;
|
||||
+ else
|
||||
+ esdhc->quirk_incorrect_hostver = false;
|
||||
+
|
||||
+ np = pdev->dev.of_node;
|
||||
+ clk = of_clk_get(np, 0);
|
||||
+ if (!IS_ERR(clk)) {
|
||||
+ /*
|
||||
+ * esdhc->peripheral_clock would be assigned with a value
|
||||
+ * which is eSDHC base clock when use periperal clock.
|
||||
+ * For ls1046a, the clock value got by common clk API is
|
||||
+ * peripheral clock while the eSDHC base clock is 1/2
|
||||
+ * peripheral clock.
|
||||
+ */
|
||||
+ if (of_device_is_compatible(np, "fsl,ls1046a-esdhc"))
|
||||
+ esdhc->peripheral_clock = clk_get_rate(clk) / 2;
|
||||
+ else
|
||||
+ esdhc->peripheral_clock = clk_get_rate(clk);
|
||||
+
|
||||
+ clk_put(clk);
|
||||
+ }
|
||||
+
|
||||
+ if (esdhc->peripheral_clock) {
|
||||
+ esdhc_clock_enable(host, false);
|
||||
+ val = sdhci_readl(host, ESDHC_DMA_SYSCTL);
|
||||
+ val |= ESDHC_PERIPHERAL_CLK_SEL;
|
||||
+ sdhci_writel(host, val, ESDHC_DMA_SYSCTL);
|
||||
+ esdhc_clock_enable(host, true);
|
||||
+ }
|
||||
}
|
||||
|
||||
static int sdhci_esdhc_probe(struct platform_device *pdev)
|
||||
@@ -624,6 +854,11 @@ static int sdhci_esdhc_probe(struct plat
|
||||
if (IS_ERR(host))
|
||||
return PTR_ERR(host);
|
||||
|
||||
+ host->mmc_host_ops.start_signal_voltage_switch =
|
||||
+ esdhc_signal_voltage_switch;
|
||||
+ host->mmc_host_ops.execute_tuning = esdhc_execute_tuning;
|
||||
+ host->tuning_delay = 1;
|
||||
+
|
||||
esdhc_init(pdev, host);
|
||||
|
||||
sdhci_get_of_property(pdev);
|
||||
--- a/drivers/mmc/host/sdhci.c
|
||||
+++ b/drivers/mmc/host/sdhci.c
|
||||
@@ -1631,26 +1631,24 @@ static void sdhci_set_ios(struct mmc_hos
|
||||
|
||||
ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
|
||||
|
||||
- if ((ios->timing == MMC_TIMING_SD_HS ||
|
||||
- ios->timing == MMC_TIMING_MMC_HS)
|
||||
- && !(host->quirks & SDHCI_QUIRK_NO_HISPD_BIT))
|
||||
- ctrl |= SDHCI_CTRL_HISPD;
|
||||
- else
|
||||
- ctrl &= ~SDHCI_CTRL_HISPD;
|
||||
+ if (!(host->quirks & SDHCI_QUIRK_NO_HISPD_BIT)) {
|
||||
+ if ((ios->timing == MMC_TIMING_SD_HS ||
|
||||
+ ios->timing == MMC_TIMING_MMC_HS ||
|
||||
+ ios->timing == MMC_TIMING_MMC_HS400 ||
|
||||
+ ios->timing == MMC_TIMING_MMC_HS200 ||
|
||||
+ ios->timing == MMC_TIMING_MMC_DDR52 ||
|
||||
+ ios->timing == MMC_TIMING_UHS_SDR50 ||
|
||||
+ ios->timing == MMC_TIMING_UHS_SDR104 ||
|
||||
+ ios->timing == MMC_TIMING_UHS_DDR50 ||
|
||||
+ ios->timing == MMC_TIMING_UHS_SDR25))
|
||||
+ ctrl |= SDHCI_CTRL_HISPD;
|
||||
+ else
|
||||
+ ctrl &= ~SDHCI_CTRL_HISPD;
|
||||
+ }
|
||||
|
||||
if (host->version >= SDHCI_SPEC_300) {
|
||||
u16 clk, ctrl_2;
|
||||
|
||||
- /* In case of UHS-I modes, set High Speed Enable */
|
||||
- if ((ios->timing == MMC_TIMING_MMC_HS400) ||
|
||||
- (ios->timing == MMC_TIMING_MMC_HS200) ||
|
||||
- (ios->timing == MMC_TIMING_MMC_DDR52) ||
|
||||
- (ios->timing == MMC_TIMING_UHS_SDR50) ||
|
||||
- (ios->timing == MMC_TIMING_UHS_SDR104) ||
|
||||
- (ios->timing == MMC_TIMING_UHS_DDR50) ||
|
||||
- (ios->timing == MMC_TIMING_UHS_SDR25))
|
||||
- ctrl |= SDHCI_CTRL_HISPD;
|
||||
-
|
||||
if (!host->preset_enabled) {
|
||||
sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
|
||||
/*
|
||||
@@ -1963,7 +1961,7 @@ static int sdhci_prepare_hs400_tuning(st
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
|
||||
+int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
|
||||
{
|
||||
struct sdhci_host *host = mmc_priv(mmc);
|
||||
u16 ctrl;
|
||||
@@ -2022,6 +2020,9 @@ static int sdhci_execute_tuning(struct m
|
||||
return err;
|
||||
}
|
||||
|
||||
+ if (host->tuning_delay < 0)
|
||||
+ host->tuning_delay = opcode == MMC_SEND_TUNING_BLOCK;
|
||||
+
|
||||
ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
|
||||
ctrl |= SDHCI_CTRL_EXEC_TUNING;
|
||||
if (host->quirks2 & SDHCI_QUIRK2_TUNING_WORK_AROUND)
|
||||
@@ -2134,9 +2135,10 @@ static int sdhci_execute_tuning(struct m
|
||||
|
||||
ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
|
||||
|
||||
- /* eMMC spec does not require a delay between tuning cycles */
|
||||
- if (opcode == MMC_SEND_TUNING_BLOCK)
|
||||
- mdelay(1);
|
||||
+ /* Spec does not require a delay between tuning cycles */
|
||||
+ if (host->tuning_delay > 0)
|
||||
+ mdelay(host->tuning_delay);
|
||||
+
|
||||
} while (ctrl & SDHCI_CTRL_EXEC_TUNING);
|
||||
|
||||
/*
|
||||
@@ -2172,6 +2174,7 @@ out_unlock:
|
||||
spin_unlock_irqrestore(&host->lock, flags);
|
||||
return err;
|
||||
}
|
||||
+EXPORT_SYMBOL_GPL(sdhci_execute_tuning);
|
||||
|
||||
static int sdhci_select_drive_strength(struct mmc_card *card,
|
||||
unsigned int max_dtr, int host_drv,
|
||||
@@ -3004,6 +3007,8 @@ struct sdhci_host *sdhci_alloc_host(stru
|
||||
|
||||
host->flags = SDHCI_SIGNALING_330;
|
||||
|
||||
+ host->tuning_delay = -1;
|
||||
+
|
||||
return host;
|
||||
}
|
||||
|
||||
--- a/drivers/mmc/host/sdhci.h
|
||||
+++ b/drivers/mmc/host/sdhci.h
|
||||
@@ -524,6 +524,8 @@ struct sdhci_host {
|
||||
#define SDHCI_TUNING_MODE_1 0
|
||||
#define SDHCI_TUNING_MODE_2 1
|
||||
#define SDHCI_TUNING_MODE_3 2
|
||||
+ /* Delay (ms) between tuning commands */
|
||||
+ int tuning_delay;
|
||||
|
||||
unsigned long private[0] ____cacheline_aligned;
|
||||
};
|
||||
@@ -689,6 +691,7 @@ void sdhci_set_power_noreg(struct sdhci_
|
||||
void sdhci_set_bus_width(struct sdhci_host *host, int width);
|
||||
void sdhci_reset(struct sdhci_host *host, u8 mask);
|
||||
void sdhci_set_uhs_signaling(struct sdhci_host *host, unsigned timing);
|
||||
+int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode);
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
extern int sdhci_suspend_host(struct sdhci_host *host);
|
File diff suppressed because it is too large
Load Diff
@ -1,682 +0,0 @@
|
||||
From bda12381598c3df43f4e60362a8cd4af58b7f5b0 Mon Sep 17 00:00:00 2001
|
||||
From: Yangbo Lu <yangbo.lu@nxp.com>
|
||||
Date: Wed, 17 Jan 2018 15:38:54 +0800
|
||||
Subject: [PATCH 26/30] rtc: support layerscape
|
||||
|
||||
This is an integrated patch for layerscape rtc support.
|
||||
|
||||
Signed-off-by: Zhang Ying-22455 <ying.zhang22455@nxp.com>
|
||||
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
|
||||
---
|
||||
drivers/rtc/rtc-pcf85263.c | 665 +++++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 665 insertions(+)
|
||||
create mode 100644 drivers/rtc/rtc-pcf85263.c
|
||||
|
||||
--- /dev/null
|
||||
+++ b/drivers/rtc/rtc-pcf85263.c
|
||||
@@ -0,0 +1,665 @@
|
||||
+/*
|
||||
+ * rtc-pcf85263 Driver for the NXP PCF85263 RTC
|
||||
+ * Copyright 2016 Parkeon
|
||||
+ *
|
||||
+ * 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 <linux/module.h>
|
||||
+#include <linux/mutex.h>
|
||||
+#include <linux/rtc.h>
|
||||
+#include <linux/i2c.h>
|
||||
+#include <linux/bcd.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/of_device.h>
|
||||
+#include <linux/regmap.h>
|
||||
+
|
||||
+
|
||||
+#define DRV_NAME "rtc-pcf85263"
|
||||
+
|
||||
+/* Quartz capacitance */
|
||||
+#define PCF85263_QUARTZCAP_7pF 0
|
||||
+#define PCF85263_QUARTZCAP_6pF 1
|
||||
+#define PCF85263_QUARTZCAP_12p5pF 2
|
||||
+
|
||||
+/* Quartz drive strength */
|
||||
+#define PCF85263_QUARTZDRIVE_NORMAL 0
|
||||
+#define PCF85263_QUARTZDRIVE_LOW 1
|
||||
+#define PCF85263_QUARTZDRIVE_HIGH 2
|
||||
+
|
||||
+
|
||||
+#define PCF85263_REG_RTC_SC 0x01 /* Seconds */
|
||||
+#define PCF85263_REG_RTC_SC_OS BIT(7) /* Oscilator stopped flag */
|
||||
+
|
||||
+#define PCF85263_REG_RTC_MN 0x02 /* Minutes */
|
||||
+#define PCF85263_REG_RTC_HR 0x03 /* Hours */
|
||||
+#define PCF85263_REG_RTC_DT 0x04 /* Day of month 1-31 */
|
||||
+#define PCF85263_REG_RTC_DW 0x05 /* Day of week 0-6 */
|
||||
+#define PCF85263_REG_RTC_MO 0x06 /* Month 1-12 */
|
||||
+#define PCF85263_REG_RTC_YR 0x07 /* Year 0-99 */
|
||||
+
|
||||
+#define PCF85263_REG_ALM1_SC 0x08 /* Seconds */
|
||||
+#define PCF85263_REG_ALM1_MN 0x09 /* Minutes */
|
||||
+#define PCF85263_REG_ALM1_HR 0x0a /* Hours */
|
||||
+#define PCF85263_REG_ALM1_DT 0x0b /* Day of month 1-31 */
|
||||
+#define PCF85263_REG_ALM1_MO 0x0c /* Month 1-12 */
|
||||
+
|
||||
+#define PCF85263_REG_ALM_CTL 0x10
|
||||
+#define PCF85263_REG_ALM_CTL_ALL_A1E 0x1f /* sec,min,hr,day,mon alarm 1 */
|
||||
+
|
||||
+#define PCF85263_REG_OSC 0x25
|
||||
+#define PCF85263_REG_OSC_CL_MASK (BIT(0) | BIT(1))
|
||||
+#define PCF85263_REG_OSC_CL_SHIFT 0
|
||||
+#define PCF85263_REG_OSC_OSCD_MASK (BIT(2) | BIT(3))
|
||||
+#define PCF85263_REG_OSC_OSCD_SHIFT 2
|
||||
+#define PCF85263_REG_OSC_LOWJ BIT(4)
|
||||
+#define PCF85263_REG_OSC_12H BIT(5)
|
||||
+
|
||||
+#define PCF85263_REG_PINIO 0x27
|
||||
+#define PCF85263_REG_PINIO_INTAPM_MASK (BIT(0) | BIT(1))
|
||||
+#define PCF85263_REG_PINIO_INTAPM_SHIFT 0
|
||||
+#define PCF85263_INTAPM_INTA (0x2 << PCF85263_REG_PINIO_INTAPM_SHIFT)
|
||||
+#define PCF85263_INTAPM_HIGHZ (0x3 << PCF85263_REG_PINIO_INTAPM_SHIFT)
|
||||
+#define PCF85263_REG_PINIO_TSPM_MASK (BIT(2) | BIT(3))
|
||||
+#define PCF85263_REG_PINIO_TSPM_SHIFT 2
|
||||
+#define PCF85263_TSPM_DISABLED (0x0 << PCF85263_REG_PINIO_TSPM_SHIFT)
|
||||
+#define PCF85263_TSPM_INTB (0x1 << PCF85263_REG_PINIO_TSPM_SHIFT)
|
||||
+#define PCF85263_REG_PINIO_CLKDISABLE BIT(7)
|
||||
+
|
||||
+#define PCF85263_REG_FUNCTION 0x28
|
||||
+#define PCF85263_REG_FUNCTION_COF_MASK 0x7
|
||||
+#define PCF85263_REG_FUNCTION_COF_OFF 0x7 /* No clock output */
|
||||
+
|
||||
+#define PCF85263_REG_INTA_CTL 0x29
|
||||
+#define PCF85263_REG_INTB_CTL 0x2A
|
||||
+#define PCF85263_REG_INTx_CTL_A1E BIT(4) /* Alarm 1 */
|
||||
+#define PCF85263_REG_INTx_CTL_ILP BIT(7) /* 0=pulse, 1=level */
|
||||
+
|
||||
+#define PCF85263_REG_FLAGS 0x2B
|
||||
+#define PCF85263_REG_FLAGS_A1F BIT(5)
|
||||
+
|
||||
+#define PCF85263_REG_RAM_BYTE 0x2c
|
||||
+
|
||||
+#define PCF85263_REG_STOPENABLE 0x2e
|
||||
+#define PCF85263_REG_STOPENABLE_STOP BIT(0)
|
||||
+
|
||||
+#define PCF85263_REG_RESET 0x2f /* Reset command */
|
||||
+#define PCF85263_REG_RESET_CMD_CPR 0xa4 /* Clear prescaler */
|
||||
+
|
||||
+#define PCF85263_MAX_REG 0x2f
|
||||
+
|
||||
+#define PCF85263_HR_PM BIT(5)
|
||||
+
|
||||
+enum pcf85263_irqpin {
|
||||
+ PCF85263_IRQPIN_NONE,
|
||||
+ PCF85263_IRQPIN_INTA,
|
||||
+ PCF85263_IRQPIN_INTB
|
||||
+};
|
||||
+
|
||||
+static const char *const pcf85263_irqpin_names[] = {
|
||||
+ [PCF85263_IRQPIN_NONE] = "None",
|
||||
+ [PCF85263_IRQPIN_INTA] = "INTA",
|
||||
+ [PCF85263_IRQPIN_INTB] = "INTB"
|
||||
+};
|
||||
+
|
||||
+struct pcf85263 {
|
||||
+ struct device *dev;
|
||||
+ struct rtc_device *rtc;
|
||||
+ struct regmap *regmap;
|
||||
+ enum pcf85263_irqpin irq_pin;
|
||||
+ int irq;
|
||||
+ bool mode_12h;
|
||||
+};
|
||||
+
|
||||
+/*
|
||||
+ * Helpers to convert 12h to 24h and vice versa.
|
||||
+ * Values in register are stored in BCD with a PM flag in bit 5
|
||||
+ *
|
||||
+ * 23:00 <=> 11PM <=> 0x31
|
||||
+ * 00:00 <=> 12AM <=> 0x12
|
||||
+ * 01:00 <=> 1AM <=> 0x01
|
||||
+ * 12:00 <=> 12PM <=> 0x32
|
||||
+ * 13:00 <=> 1PM <=> 0x21
|
||||
+ */
|
||||
+static int pcf85263_bcd12h_to_bin24h(int regval)
|
||||
+{
|
||||
+ int hr = bcd2bin(regval & 0x1f);
|
||||
+ bool pm = regval & PCF85263_HR_PM;
|
||||
+
|
||||
+ if (hr == 12)
|
||||
+ return pm ? 12 : 0;
|
||||
+
|
||||
+ return pm ? hr + 12 : hr;
|
||||
+}
|
||||
+
|
||||
+static int pcf85263_bin24h_to_bcd12h(int hr24)
|
||||
+{
|
||||
+ bool pm = hr24 >= 12;
|
||||
+ int hr12 = hr24 % 12;
|
||||
+
|
||||
+ if (!hr12)
|
||||
+ hr12++;
|
||||
+
|
||||
+ return bin2bcd(hr12) | pm ? 0 : PCF85263_HR_PM;
|
||||
+}
|
||||
+
|
||||
+static int pcf85263_read_time(struct device *dev, struct rtc_time *tm)
|
||||
+{
|
||||
+ struct pcf85263 *pcf85263 = dev_get_drvdata(dev);
|
||||
+ const int first = PCF85263_REG_RTC_SC;
|
||||
+ const int last = PCF85263_REG_RTC_YR;
|
||||
+ const int len = last - first + 1;
|
||||
+ u8 regs[len];
|
||||
+ u8 hr_reg;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = regmap_bulk_read(pcf85263->regmap, first, regs, len);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ if (regs[PCF85263_REG_RTC_SC - first] & PCF85263_REG_RTC_SC_OS) {
|
||||
+ dev_warn(dev, "Oscillator stop detected, date/time is not reliable.\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ tm->tm_sec = bcd2bin(regs[PCF85263_REG_RTC_SC - first] & 0x7f);
|
||||
+ tm->tm_min = bcd2bin(regs[PCF85263_REG_RTC_MN - first] & 0x7f);
|
||||
+
|
||||
+ hr_reg = regs[PCF85263_REG_RTC_HR - first];
|
||||
+ if (pcf85263->mode_12h)
|
||||
+ tm->tm_hour = pcf85263_bcd12h_to_bin24h(hr_reg);
|
||||
+ else
|
||||
+ tm->tm_hour = bcd2bin(hr_reg & 0x3f);
|
||||
+
|
||||
+ tm->tm_mday = bcd2bin(regs[PCF85263_REG_RTC_DT - first]);
|
||||
+ tm->tm_wday = bcd2bin(regs[PCF85263_REG_RTC_DW - first]);
|
||||
+ tm->tm_mon = bcd2bin(regs[PCF85263_REG_RTC_MO - first]) - 1;
|
||||
+ tm->tm_year = bcd2bin(regs[PCF85263_REG_RTC_YR - first]);
|
||||
+
|
||||
+ tm->tm_year += 100; /* Assume 21st century */
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int pcf85263_set_time(struct device *dev, struct rtc_time *tm)
|
||||
+{
|
||||
+ struct pcf85263 *pcf85263 = dev_get_drvdata(dev);
|
||||
+
|
||||
+ /*
|
||||
+ * Before setting time need to stop RTC and disable prescaler
|
||||
+ * Do this all in a single I2C transaction exploiting wraparound
|
||||
+ * as described in data sheet.
|
||||
+ * This means that the array below must be in register order
|
||||
+ */
|
||||
+ u8 regs[] = {
|
||||
+ PCF85263_REG_STOPENABLE_STOP, /* STOP */
|
||||
+ PCF85263_REG_RESET_CMD_CPR, /* Disable prescaler */
|
||||
+ /* Wrap around to register 0 (1/100s) */
|
||||
+ 0, /* 1/100s always zero. */
|
||||
+ bin2bcd(tm->tm_sec),
|
||||
+ bin2bcd(tm->tm_min),
|
||||
+ bin2bcd(tm->tm_hour), /* 24-hour */
|
||||
+ bin2bcd(tm->tm_mday),
|
||||
+ bin2bcd(tm->tm_wday + 1),
|
||||
+ bin2bcd(tm->tm_mon + 1),
|
||||
+ bin2bcd(tm->tm_year % 100)
|
||||
+ };
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = regmap_bulk_write(pcf85263->regmap, PCF85263_REG_STOPENABLE,
|
||||
+ regs, sizeof(regs));
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* As we have set the time in 24H update the hardware for that */
|
||||
+ if (pcf85263->mode_12h) {
|
||||
+ pcf85263->mode_12h = false;
|
||||
+ ret = regmap_update_bits(pcf85263->regmap, PCF85263_REG_OSC,
|
||||
+ PCF85263_REG_OSC_12H, 0);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ /* Start it again */
|
||||
+ return regmap_write(pcf85263->regmap, PCF85263_REG_STOPENABLE, 0);
|
||||
+}
|
||||
+
|
||||
+static int pcf85263_enable_alarm(struct pcf85263 *pcf85263, bool enable)
|
||||
+{
|
||||
+ int reg;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = regmap_update_bits(pcf85263->regmap, PCF85263_REG_ALM_CTL,
|
||||
+ PCF85263_REG_ALM_CTL_ALL_A1E,
|
||||
+ enable ? PCF85263_REG_ALM_CTL_ALL_A1E : 0);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ switch (pcf85263->irq_pin) {
|
||||
+ case PCF85263_IRQPIN_NONE:
|
||||
+ return 0;
|
||||
+
|
||||
+ case PCF85263_IRQPIN_INTA:
|
||||
+ reg = PCF85263_REG_INTA_CTL;
|
||||
+ break;
|
||||
+
|
||||
+ case PCF85263_IRQPIN_INTB:
|
||||
+ reg = PCF85263_REG_INTB_CTL;
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ return regmap_update_bits(pcf85263->regmap, reg,
|
||||
+ PCF85263_REG_INTx_CTL_A1E,
|
||||
+ enable ? PCF85263_REG_INTx_CTL_A1E : 0);
|
||||
+}
|
||||
+
|
||||
+static int pcf85263_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
|
||||
+{
|
||||
+ struct pcf85263 *pcf85263 = dev_get_drvdata(dev);
|
||||
+ struct rtc_time *tm = &alarm->time;
|
||||
+ const int first = PCF85263_REG_ALM1_SC;
|
||||
+ const int last = PCF85263_REG_ALM1_MO;
|
||||
+ const int len = last - first + 1;
|
||||
+ u8 regs[len];
|
||||
+ u8 hr_reg;
|
||||
+ unsigned int regval;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = regmap_bulk_read(pcf85263->regmap, first, regs, len);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ tm->tm_sec = bcd2bin(regs[PCF85263_REG_ALM1_SC - first] & 0x7f);
|
||||
+ tm->tm_min = bcd2bin(regs[PCF85263_REG_ALM1_MN - first] & 0x7f);
|
||||
+
|
||||
+ hr_reg = regs[PCF85263_REG_ALM1_HR - first];
|
||||
+ if (pcf85263->mode_12h)
|
||||
+ tm->tm_hour = pcf85263_bcd12h_to_bin24h(hr_reg);
|
||||
+ else
|
||||
+ tm->tm_hour = bcd2bin(hr_reg & 0x3f);
|
||||
+
|
||||
+ tm->tm_mday = bcd2bin(regs[PCF85263_REG_ALM1_DT - first]);
|
||||
+ tm->tm_mon = bcd2bin(regs[PCF85263_REG_ALM1_MO - first]) - 1;
|
||||
+ tm->tm_year = -1;
|
||||
+ tm->tm_wday = -1;
|
||||
+
|
||||
+ ret = regmap_read(pcf85263->regmap, PCF85263_REG_ALM_CTL, ®val);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ alarm->enabled = !!(regval & PCF85263_REG_ALM_CTL_ALL_A1E);
|
||||
+
|
||||
+ ret = regmap_read(pcf85263->regmap, PCF85263_REG_FLAGS, ®val);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ alarm->pending = !!(regval & PCF85263_REG_FLAGS_A1F);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int pcf85263_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
|
||||
+{
|
||||
+ struct pcf85263 *pcf85263 = dev_get_drvdata(dev);
|
||||
+ struct rtc_time *tm = &alarm->time;
|
||||
+ const int first = PCF85263_REG_ALM1_SC;
|
||||
+ const int last = PCF85263_REG_ALM1_MO;
|
||||
+ const int len = last - first + 1;
|
||||
+ u8 regs[len];
|
||||
+ int ret;
|
||||
+
|
||||
+ /* Disable alarm comparison during update */
|
||||
+ ret = pcf85263_enable_alarm(pcf85263, false);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* Clear any pending alarm (write 0=>clr, 1=>no change) */
|
||||
+ ret = regmap_write(pcf85263->regmap, PCF85263_REG_FLAGS,
|
||||
+ (unsigned int)(~PCF85263_REG_FLAGS_A1F));
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* Set the alarm time registers */
|
||||
+ regs[PCF85263_REG_ALM1_SC - first] = bin2bcd(tm->tm_sec);
|
||||
+ regs[PCF85263_REG_ALM1_MN - first] = bin2bcd(tm->tm_min);
|
||||
+ regs[PCF85263_REG_ALM1_HR - first] = pcf85263->mode_12h ?
|
||||
+ pcf85263_bin24h_to_bcd12h(tm->tm_hour) :
|
||||
+ bin2bcd(tm->tm_hour);
|
||||
+ regs[PCF85263_REG_ALM1_DT - first] = bin2bcd(tm->tm_mday);
|
||||
+ regs[PCF85263_REG_ALM1_MO - first] = bin2bcd(tm->tm_mon + 1);
|
||||
+
|
||||
+ ret = regmap_bulk_write(pcf85263->regmap, first, regs, sizeof(regs));
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ if (alarm->enabled)
|
||||
+ ret = pcf85263_enable_alarm(pcf85263, true);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int pcf85263_alarm_irq_enable(struct device *dev, unsigned int enable)
|
||||
+{
|
||||
+ struct pcf85263 *pcf85263 = dev_get_drvdata(dev);
|
||||
+
|
||||
+ return pcf85263_enable_alarm(pcf85263, !!enable);
|
||||
+}
|
||||
+
|
||||
+static irqreturn_t pcf85263_irq(int irq, void *data)
|
||||
+{
|
||||
+ struct pcf85263 *pcf85263 = data;
|
||||
+ unsigned int regval;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = regmap_read(pcf85263->regmap, PCF85263_REG_FLAGS, ®val);
|
||||
+ if (ret)
|
||||
+ return IRQ_NONE;
|
||||
+
|
||||
+ if (regval & PCF85263_REG_FLAGS_A1F) {
|
||||
+ regmap_write(pcf85263->regmap, PCF85263_REG_FLAGS,
|
||||
+ (unsigned int)(~PCF85263_REG_FLAGS_A1F));
|
||||
+
|
||||
+ rtc_update_irq(pcf85263->rtc, 1, RTC_IRQF | RTC_AF);
|
||||
+
|
||||
+ return IRQ_HANDLED;
|
||||
+ }
|
||||
+
|
||||
+ return IRQ_NONE;
|
||||
+}
|
||||
+
|
||||
+static int pcf85263_check_osc_stopped(struct pcf85263 *pcf85263)
|
||||
+{
|
||||
+ unsigned int regval;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = regmap_read(pcf85263->regmap, PCF85263_REG_RTC_SC, ®val);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = regval & PCF85263_REG_RTC_SC_OS ? 1 : 0;
|
||||
+ if (ret)
|
||||
+ dev_warn(pcf85263->dev, "Oscillator stop detected, date/time is not reliable.\n");
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+#ifdef CONFIG_RTC_INTF_DEV
|
||||
+static int pcf85263_ioctl(struct device *dev,
|
||||
+ unsigned int cmd, unsigned long arg)
|
||||
+{
|
||||
+ struct pcf85263 *pcf85263 = dev_get_drvdata(dev);
|
||||
+ int ret;
|
||||
+
|
||||
+ switch (cmd) {
|
||||
+ case RTC_VL_READ:
|
||||
+ ret = pcf85263_check_osc_stopped(pcf85263);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ if (copy_to_user((void __user *)arg, &ret, sizeof(int)))
|
||||
+ return -EFAULT;
|
||||
+ return 0;
|
||||
+
|
||||
+ case RTC_VL_CLR:
|
||||
+ return regmap_update_bits(pcf85263->regmap,
|
||||
+ PCF85263_REG_RTC_SC,
|
||||
+ PCF85263_REG_RTC_SC_OS, 0);
|
||||
+ default:
|
||||
+ return -ENOIOCTLCMD;
|
||||
+ }
|
||||
+}
|
||||
+#else
|
||||
+#define pcf85263_ioctl NULL
|
||||
+#endif
|
||||
+
|
||||
+static int pcf85263_init_hw(struct pcf85263 *pcf85263)
|
||||
+{
|
||||
+ struct device_node *np = pcf85263->dev->of_node;
|
||||
+ unsigned int regval;
|
||||
+ u32 propval;
|
||||
+ int ret;
|
||||
+
|
||||
+ /* Determine if oscilator has been stopped (probably low power) */
|
||||
+ ret = pcf85263_check_osc_stopped(pcf85263);
|
||||
+ if (ret < 0) {
|
||||
+ /* Log here since this is the first hw access on probe */
|
||||
+ dev_err(pcf85263->dev, "Unable to read register\n");
|
||||
+
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ /* Determine 12/24H mode */
|
||||
+ ret = regmap_read(pcf85263->regmap, PCF85263_REG_OSC, ®val);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ pcf85263->mode_12h = !!(regval & PCF85263_REG_OSC_12H);
|
||||
+
|
||||
+ /* Set oscilator register */
|
||||
+ regval &= ~PCF85263_REG_OSC_12H; /* keep current 12/24 h setting */
|
||||
+
|
||||
+ propval = PCF85263_QUARTZCAP_12p5pF;
|
||||
+ of_property_read_u32(np, "quartz-load-capacitance", &propval);
|
||||
+ regval |= ((propval << PCF85263_REG_OSC_CL_SHIFT)
|
||||
+ & PCF85263_REG_OSC_CL_MASK);
|
||||
+
|
||||
+ propval = PCF85263_QUARTZDRIVE_NORMAL;
|
||||
+ of_property_read_u32(np, "quartz-drive-strength", &propval);
|
||||
+ regval |= ((propval << PCF85263_REG_OSC_OSCD_SHIFT)
|
||||
+ & PCF85263_REG_OSC_OSCD_MASK);
|
||||
+
|
||||
+ if (of_property_read_bool(np, "quartz-low-jitter"))
|
||||
+ regval |= PCF85263_REG_OSC_LOWJ;
|
||||
+
|
||||
+ ret = regmap_write(pcf85263->regmap, PCF85263_REG_OSC, regval);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* Set function register (RTC mode, 1s tick, clock output static) */
|
||||
+ ret = regmap_write(pcf85263->regmap, PCF85263_REG_FUNCTION,
|
||||
+ PCF85263_REG_FUNCTION_COF_OFF);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* Set all interrupts to disabled, level mode */
|
||||
+ ret = regmap_write(pcf85263->regmap, PCF85263_REG_INTA_CTL,
|
||||
+ PCF85263_REG_INTx_CTL_ILP);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ ret = regmap_write(pcf85263->regmap, PCF85263_REG_INTB_CTL,
|
||||
+ PCF85263_REG_INTx_CTL_ILP);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* Setup IO pin config register */
|
||||
+ regval = PCF85263_REG_PINIO_CLKDISABLE;
|
||||
+ switch (pcf85263->irq_pin) {
|
||||
+ case PCF85263_IRQPIN_INTA:
|
||||
+ regval |= (PCF85263_INTAPM_INTA | PCF85263_TSPM_DISABLED);
|
||||
+ break;
|
||||
+ case PCF85263_IRQPIN_INTB:
|
||||
+ regval |= (PCF85263_INTAPM_HIGHZ | PCF85263_TSPM_INTB);
|
||||
+ break;
|
||||
+ case PCF85263_IRQPIN_NONE:
|
||||
+ regval |= (PCF85263_INTAPM_HIGHZ | PCF85263_TSPM_DISABLED);
|
||||
+ break;
|
||||
+ }
|
||||
+ ret = regmap_write(pcf85263->regmap, PCF85263_REG_PINIO, regval);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static const struct rtc_class_ops rtc_ops = {
|
||||
+ .ioctl = pcf85263_ioctl,
|
||||
+ .read_time = pcf85263_read_time,
|
||||
+ .set_time = pcf85263_set_time,
|
||||
+ .read_alarm = pcf85263_read_alarm,
|
||||
+ .set_alarm = pcf85263_set_alarm,
|
||||
+ .alarm_irq_enable = pcf85263_alarm_irq_enable,
|
||||
+};
|
||||
+
|
||||
+static const struct regmap_config pcf85263_regmap_cfg = {
|
||||
+ .reg_bits = 8,
|
||||
+ .val_bits = 8,
|
||||
+ .max_register = PCF85263_MAX_REG,
|
||||
+};
|
||||
+
|
||||
+/*
|
||||
+ * On some boards the interrupt line may not be wired to the CPU but only to
|
||||
+ * a power supply circuit.
|
||||
+ * In that case no interrupt will be specified in the device tree but the
|
||||
+ * wakeup-source DT property may be used to enable wakeup programming in
|
||||
+ * sysfs
|
||||
+ */
|
||||
+static bool pcf85263_can_wakeup_machine(struct pcf85263 *pcf85263)
|
||||
+{
|
||||
+ return pcf85263->irq ||
|
||||
+ of_property_read_bool(pcf85263->dev->of_node, "wakeup-source");
|
||||
+}
|
||||
+
|
||||
+static int pcf85263_probe(struct i2c_client *client,
|
||||
+ const struct i2c_device_id *id)
|
||||
+{
|
||||
+ struct device *dev = &client->dev;
|
||||
+ struct pcf85263 *pcf85263;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C |
|
||||
+ I2C_FUNC_SMBUS_BYTE_DATA |
|
||||
+ I2C_FUNC_SMBUS_I2C_BLOCK))
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ pcf85263 = devm_kzalloc(dev, sizeof(*pcf85263), GFP_KERNEL);
|
||||
+ if (!pcf85263)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ pcf85263->dev = dev;
|
||||
+ pcf85263->irq = client->irq;
|
||||
+ dev_set_drvdata(dev, pcf85263);
|
||||
+
|
||||
+ pcf85263->regmap = devm_regmap_init_i2c(client, &pcf85263_regmap_cfg);
|
||||
+ if (IS_ERR(pcf85263->regmap)) {
|
||||
+ ret = PTR_ERR(pcf85263->regmap);
|
||||
+ dev_err(dev, "regmap allocation failed (%d)\n", ret);
|
||||
+
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ /* Determine which interrupt pin the board uses */
|
||||
+ if (pcf85263_can_wakeup_machine(pcf85263)) {
|
||||
+ if (of_property_match_string(dev->of_node,
|
||||
+ "interrupt-names", "INTB") >= 0)
|
||||
+ pcf85263->irq_pin = PCF85263_IRQPIN_INTB;
|
||||
+ else
|
||||
+ pcf85263->irq_pin = PCF85263_IRQPIN_INTA;
|
||||
+ } else {
|
||||
+ pcf85263->irq_pin = PCF85263_IRQPIN_NONE;
|
||||
+ }
|
||||
+
|
||||
+ ret = pcf85263_init_hw(pcf85263);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ if (pcf85263->irq) {
|
||||
+ ret = devm_request_threaded_irq(dev, pcf85263->irq, NULL,
|
||||
+ pcf85263_irq,
|
||||
+ IRQF_ONESHOT,
|
||||
+ dev->driver->name, pcf85263);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev, "irq %d unavailable (%d)\n",
|
||||
+ pcf85263->irq, ret);
|
||||
+ pcf85263->irq = 0;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (pcf85263_can_wakeup_machine(pcf85263))
|
||||
+ device_init_wakeup(dev, true);
|
||||
+
|
||||
+ pcf85263->rtc = devm_rtc_device_register(dev, dev->driver->name,
|
||||
+ &rtc_ops, THIS_MODULE);
|
||||
+ ret = PTR_ERR_OR_ZERO(pcf85263->rtc);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* We cannot support UIE mode if we do not have an IRQ line */
|
||||
+ if (!pcf85263->irq)
|
||||
+ pcf85263->rtc->uie_unsupported = 1;
|
||||
+
|
||||
+ dev_info(pcf85263->dev,
|
||||
+ "PCF85263 RTC (irqpin=%s irq=%d)\n",
|
||||
+ pcf85263_irqpin_names[pcf85263->irq_pin],
|
||||
+ pcf85263->irq);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int pcf85263_remove(struct i2c_client *client)
|
||||
+{
|
||||
+ struct pcf85263 *pcf85263 = i2c_get_clientdata(client);
|
||||
+
|
||||
+ if (pcf85263_can_wakeup_machine(pcf85263))
|
||||
+ device_init_wakeup(pcf85263->dev, false);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#ifdef CONFIG_PM_SLEEP
|
||||
+static int pcf85263_suspend(struct device *dev)
|
||||
+{
|
||||
+ struct pcf85263 *pcf85263 = dev_get_drvdata(dev);
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ if (device_may_wakeup(dev))
|
||||
+ ret = enable_irq_wake(pcf85263->irq);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int pcf85263_resume(struct device *dev)
|
||||
+{
|
||||
+ struct pcf85263 *pcf85263 = dev_get_drvdata(dev);
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ if (device_may_wakeup(dev))
|
||||
+ ret = disable_irq_wake(pcf85263->irq);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
+static const struct i2c_device_id pcf85263_id[] = {
|
||||
+ { "pcf85263", 0 },
|
||||
+ { }
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(i2c, pcf85263_id);
|
||||
+
|
||||
+#ifdef CONFIG_OF
|
||||
+static const struct of_device_id pcf85263_of_match[] = {
|
||||
+ { .compatible = "nxp,pcf85263" },
|
||||
+ {}
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, pcf85263_of_match);
|
||||
+#endif
|
||||
+
|
||||
+static SIMPLE_DEV_PM_OPS(pcf85263_pm_ops, pcf85263_suspend, pcf85263_resume);
|
||||
+
|
||||
+static struct i2c_driver pcf85263_driver = {
|
||||
+ .driver = {
|
||||
+ .name = "rtc-pcf85263",
|
||||
+ .of_match_table = of_match_ptr(pcf85263_of_match),
|
||||
+ .pm = &pcf85263_pm_ops,
|
||||
+ },
|
||||
+ .probe = pcf85263_probe,
|
||||
+ .remove = pcf85263_remove,
|
||||
+ .id_table = pcf85263_id,
|
||||
+};
|
||||
+
|
||||
+module_i2c_driver(pcf85263_driver);
|
||||
+
|
||||
+MODULE_AUTHOR("Martin Fuzzey <mfuzzey@parkeon.com>");
|
||||
+MODULE_DESCRIPTION("PCF85263 RTC Driver");
|
||||
+MODULE_LICENSE("GPL");
|
||||
+
|
@ -1,427 +0,0 @@
|
||||
From 027b679f248f15dea36c6cd6782d6643e2151057 Mon Sep 17 00:00:00 2001
|
||||
From: Yangbo Lu <yangbo.lu@nxp.com>
|
||||
Date: Wed, 17 Jan 2018 15:39:43 +0800
|
||||
Subject: [PATCH 27/30] spi: support layerscape
|
||||
|
||||
This is an integrated patch for layerscape dspi support.
|
||||
|
||||
Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
|
||||
Signed-off-by: Sanchayan Maity <maitysanchayan@gmail.com>
|
||||
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
|
||||
Signed-off-by: Sanchayan Maity <maitysanchayan@gmail.com>
|
||||
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
|
||||
---
|
||||
drivers/spi/spi-fsl-dspi.c | 309 ++++++++++++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 304 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/drivers/spi/spi-fsl-dspi.c
|
||||
+++ b/drivers/spi/spi-fsl-dspi.c
|
||||
@@ -15,6 +15,8 @@
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
+#include <linux/dmaengine.h>
|
||||
+#include <linux/dma-mapping.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/interrupt.h>
|
||||
@@ -40,6 +42,7 @@
|
||||
#define TRAN_STATE_WORD_ODD_NUM 0x04
|
||||
|
||||
#define DSPI_FIFO_SIZE 4
|
||||
+#define DSPI_DMA_BUFSIZE (DSPI_FIFO_SIZE * 1024)
|
||||
|
||||
#define SPI_MCR 0x00
|
||||
#define SPI_MCR_MASTER (1 << 31)
|
||||
@@ -72,6 +75,11 @@
|
||||
#define SPI_SR_TCFQF 0x80000000
|
||||
#define SPI_SR_CLEAR 0xdaad0000
|
||||
|
||||
+#define SPI_RSER_TFFFE BIT(25)
|
||||
+#define SPI_RSER_TFFFD BIT(24)
|
||||
+#define SPI_RSER_RFDFE BIT(17)
|
||||
+#define SPI_RSER_RFDFD BIT(16)
|
||||
+
|
||||
#define SPI_RSER 0x30
|
||||
#define SPI_RSER_EOQFE 0x10000000
|
||||
#define SPI_RSER_TCFQE 0x80000000
|
||||
@@ -109,6 +117,8 @@
|
||||
|
||||
#define SPI_TCR_TCNT_MAX 0x10000
|
||||
|
||||
+#define DMA_COMPLETION_TIMEOUT msecs_to_jiffies(3000)
|
||||
+
|
||||
struct chip_data {
|
||||
u32 mcr_val;
|
||||
u32 ctar_val;
|
||||
@@ -118,6 +128,7 @@ struct chip_data {
|
||||
enum dspi_trans_mode {
|
||||
DSPI_EOQ_MODE = 0,
|
||||
DSPI_TCFQ_MODE,
|
||||
+ DSPI_DMA_MODE,
|
||||
};
|
||||
|
||||
struct fsl_dspi_devtype_data {
|
||||
@@ -126,7 +137,7 @@ struct fsl_dspi_devtype_data {
|
||||
};
|
||||
|
||||
static const struct fsl_dspi_devtype_data vf610_data = {
|
||||
- .trans_mode = DSPI_EOQ_MODE,
|
||||
+ .trans_mode = DSPI_DMA_MODE,
|
||||
.max_clock_factor = 2,
|
||||
};
|
||||
|
||||
@@ -140,6 +151,23 @@ static const struct fsl_dspi_devtype_dat
|
||||
.max_clock_factor = 8,
|
||||
};
|
||||
|
||||
+struct fsl_dspi_dma {
|
||||
+ /* Length of transfer in words of DSPI_FIFO_SIZE */
|
||||
+ u32 curr_xfer_len;
|
||||
+
|
||||
+ u32 *tx_dma_buf;
|
||||
+ struct dma_chan *chan_tx;
|
||||
+ dma_addr_t tx_dma_phys;
|
||||
+ struct completion cmd_tx_complete;
|
||||
+ struct dma_async_tx_descriptor *tx_desc;
|
||||
+
|
||||
+ u32 *rx_dma_buf;
|
||||
+ struct dma_chan *chan_rx;
|
||||
+ dma_addr_t rx_dma_phys;
|
||||
+ struct completion cmd_rx_complete;
|
||||
+ struct dma_async_tx_descriptor *rx_desc;
|
||||
+};
|
||||
+
|
||||
struct fsl_dspi {
|
||||
struct spi_master *master;
|
||||
struct platform_device *pdev;
|
||||
@@ -166,8 +194,11 @@ struct fsl_dspi {
|
||||
u32 waitflags;
|
||||
|
||||
u32 spi_tcnt;
|
||||
+ struct fsl_dspi_dma *dma;
|
||||
};
|
||||
|
||||
+static u32 dspi_data_to_pushr(struct fsl_dspi *dspi, int tx_word);
|
||||
+
|
||||
static inline int is_double_byte_mode(struct fsl_dspi *dspi)
|
||||
{
|
||||
unsigned int val;
|
||||
@@ -177,6 +208,255 @@ static inline int is_double_byte_mode(st
|
||||
return ((val & SPI_FRAME_BITS_MASK) == SPI_FRAME_BITS(8)) ? 0 : 1;
|
||||
}
|
||||
|
||||
+static void dspi_tx_dma_callback(void *arg)
|
||||
+{
|
||||
+ struct fsl_dspi *dspi = arg;
|
||||
+ struct fsl_dspi_dma *dma = dspi->dma;
|
||||
+
|
||||
+ complete(&dma->cmd_tx_complete);
|
||||
+}
|
||||
+
|
||||
+static void dspi_rx_dma_callback(void *arg)
|
||||
+{
|
||||
+ struct fsl_dspi *dspi = arg;
|
||||
+ struct fsl_dspi_dma *dma = dspi->dma;
|
||||
+ int rx_word;
|
||||
+ int i;
|
||||
+ u16 d;
|
||||
+
|
||||
+ rx_word = is_double_byte_mode(dspi);
|
||||
+
|
||||
+ if (!(dspi->dataflags & TRAN_STATE_RX_VOID)) {
|
||||
+ for (i = 0; i < dma->curr_xfer_len; i++) {
|
||||
+ d = dspi->dma->rx_dma_buf[i];
|
||||
+ rx_word ? (*(u16 *)dspi->rx = d) :
|
||||
+ (*(u8 *)dspi->rx = d);
|
||||
+ dspi->rx += rx_word + 1;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ complete(&dma->cmd_rx_complete);
|
||||
+}
|
||||
+
|
||||
+static int dspi_next_xfer_dma_submit(struct fsl_dspi *dspi)
|
||||
+{
|
||||
+ struct fsl_dspi_dma *dma = dspi->dma;
|
||||
+ struct device *dev = &dspi->pdev->dev;
|
||||
+ int time_left;
|
||||
+ int tx_word;
|
||||
+ int i;
|
||||
+
|
||||
+ tx_word = is_double_byte_mode(dspi);
|
||||
+
|
||||
+ for (i = 0; i < dma->curr_xfer_len; i++) {
|
||||
+ dspi->dma->tx_dma_buf[i] = dspi_data_to_pushr(dspi, tx_word);
|
||||
+ if ((dspi->cs_change) && (!dspi->len))
|
||||
+ dspi->dma->tx_dma_buf[i] &= ~SPI_PUSHR_CONT;
|
||||
+ }
|
||||
+
|
||||
+ dma->tx_desc = dmaengine_prep_slave_single(dma->chan_tx,
|
||||
+ dma->tx_dma_phys,
|
||||
+ dma->curr_xfer_len *
|
||||
+ DMA_SLAVE_BUSWIDTH_4_BYTES,
|
||||
+ DMA_MEM_TO_DEV,
|
||||
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
|
||||
+ if (!dma->tx_desc) {
|
||||
+ dev_err(dev, "Not able to get desc for DMA xfer\n");
|
||||
+ return -EIO;
|
||||
+ }
|
||||
+
|
||||
+ dma->tx_desc->callback = dspi_tx_dma_callback;
|
||||
+ dma->tx_desc->callback_param = dspi;
|
||||
+ if (dma_submit_error(dmaengine_submit(dma->tx_desc))) {
|
||||
+ dev_err(dev, "DMA submit failed\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ dma->rx_desc = dmaengine_prep_slave_single(dma->chan_rx,
|
||||
+ dma->rx_dma_phys,
|
||||
+ dma->curr_xfer_len *
|
||||
+ DMA_SLAVE_BUSWIDTH_4_BYTES,
|
||||
+ DMA_DEV_TO_MEM,
|
||||
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
|
||||
+ if (!dma->rx_desc) {
|
||||
+ dev_err(dev, "Not able to get desc for DMA xfer\n");
|
||||
+ return -EIO;
|
||||
+ }
|
||||
+
|
||||
+ dma->rx_desc->callback = dspi_rx_dma_callback;
|
||||
+ dma->rx_desc->callback_param = dspi;
|
||||
+ if (dma_submit_error(dmaengine_submit(dma->rx_desc))) {
|
||||
+ dev_err(dev, "DMA submit failed\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ reinit_completion(&dspi->dma->cmd_rx_complete);
|
||||
+ reinit_completion(&dspi->dma->cmd_tx_complete);
|
||||
+
|
||||
+ dma_async_issue_pending(dma->chan_rx);
|
||||
+ dma_async_issue_pending(dma->chan_tx);
|
||||
+
|
||||
+ time_left = wait_for_completion_timeout(&dspi->dma->cmd_tx_complete,
|
||||
+ DMA_COMPLETION_TIMEOUT);
|
||||
+ if (time_left == 0) {
|
||||
+ dev_err(dev, "DMA tx timeout\n");
|
||||
+ dmaengine_terminate_all(dma->chan_tx);
|
||||
+ dmaengine_terminate_all(dma->chan_rx);
|
||||
+ return -ETIMEDOUT;
|
||||
+ }
|
||||
+
|
||||
+ time_left = wait_for_completion_timeout(&dspi->dma->cmd_rx_complete,
|
||||
+ DMA_COMPLETION_TIMEOUT);
|
||||
+ if (time_left == 0) {
|
||||
+ dev_err(dev, "DMA rx timeout\n");
|
||||
+ dmaengine_terminate_all(dma->chan_tx);
|
||||
+ dmaengine_terminate_all(dma->chan_rx);
|
||||
+ return -ETIMEDOUT;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int dspi_dma_xfer(struct fsl_dspi *dspi)
|
||||
+{
|
||||
+ struct fsl_dspi_dma *dma = dspi->dma;
|
||||
+ struct device *dev = &dspi->pdev->dev;
|
||||
+ int curr_remaining_bytes;
|
||||
+ int bytes_per_buffer;
|
||||
+ int word = 1;
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ if (is_double_byte_mode(dspi))
|
||||
+ word = 2;
|
||||
+ curr_remaining_bytes = dspi->len;
|
||||
+ bytes_per_buffer = DSPI_DMA_BUFSIZE / DSPI_FIFO_SIZE;
|
||||
+ while (curr_remaining_bytes) {
|
||||
+ /* Check if current transfer fits the DMA buffer */
|
||||
+ dma->curr_xfer_len = curr_remaining_bytes / word;
|
||||
+ if (dma->curr_xfer_len > bytes_per_buffer)
|
||||
+ dma->curr_xfer_len = bytes_per_buffer;
|
||||
+
|
||||
+ ret = dspi_next_xfer_dma_submit(dspi);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev, "DMA transfer failed\n");
|
||||
+ goto exit;
|
||||
+
|
||||
+ } else {
|
||||
+ curr_remaining_bytes -= dma->curr_xfer_len * word;
|
||||
+ if (curr_remaining_bytes < 0)
|
||||
+ curr_remaining_bytes = 0;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+exit:
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int dspi_request_dma(struct fsl_dspi *dspi, phys_addr_t phy_addr)
|
||||
+{
|
||||
+ struct fsl_dspi_dma *dma;
|
||||
+ struct dma_slave_config cfg;
|
||||
+ struct device *dev = &dspi->pdev->dev;
|
||||
+ int ret;
|
||||
+
|
||||
+ dma = devm_kzalloc(dev, sizeof(*dma), GFP_KERNEL);
|
||||
+ if (!dma)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ dma->chan_rx = dma_request_slave_channel(dev, "rx");
|
||||
+ if (!dma->chan_rx) {
|
||||
+ dev_err(dev, "rx dma channel not available\n");
|
||||
+ ret = -ENODEV;
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ dma->chan_tx = dma_request_slave_channel(dev, "tx");
|
||||
+ if (!dma->chan_tx) {
|
||||
+ dev_err(dev, "tx dma channel not available\n");
|
||||
+ ret = -ENODEV;
|
||||
+ goto err_tx_channel;
|
||||
+ }
|
||||
+
|
||||
+ dma->tx_dma_buf = dma_alloc_coherent(dev, DSPI_DMA_BUFSIZE,
|
||||
+ &dma->tx_dma_phys, GFP_KERNEL);
|
||||
+ if (!dma->tx_dma_buf) {
|
||||
+ ret = -ENOMEM;
|
||||
+ goto err_tx_dma_buf;
|
||||
+ }
|
||||
+
|
||||
+ dma->rx_dma_buf = dma_alloc_coherent(dev, DSPI_DMA_BUFSIZE,
|
||||
+ &dma->rx_dma_phys, GFP_KERNEL);
|
||||
+ if (!dma->rx_dma_buf) {
|
||||
+ ret = -ENOMEM;
|
||||
+ goto err_rx_dma_buf;
|
||||
+ }
|
||||
+
|
||||
+ cfg.src_addr = phy_addr + SPI_POPR;
|
||||
+ cfg.dst_addr = phy_addr + SPI_PUSHR;
|
||||
+ cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
|
||||
+ cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
|
||||
+ cfg.src_maxburst = 1;
|
||||
+ cfg.dst_maxburst = 1;
|
||||
+
|
||||
+ cfg.direction = DMA_DEV_TO_MEM;
|
||||
+ ret = dmaengine_slave_config(dma->chan_rx, &cfg);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev, "can't configure rx dma channel\n");
|
||||
+ ret = -EINVAL;
|
||||
+ goto err_slave_config;
|
||||
+ }
|
||||
+
|
||||
+ cfg.direction = DMA_MEM_TO_DEV;
|
||||
+ ret = dmaengine_slave_config(dma->chan_tx, &cfg);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev, "can't configure tx dma channel\n");
|
||||
+ ret = -EINVAL;
|
||||
+ goto err_slave_config;
|
||||
+ }
|
||||
+
|
||||
+ dspi->dma = dma;
|
||||
+ init_completion(&dma->cmd_tx_complete);
|
||||
+ init_completion(&dma->cmd_rx_complete);
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+err_slave_config:
|
||||
+ dma_free_coherent(dev, DSPI_DMA_BUFSIZE,
|
||||
+ dma->rx_dma_buf, dma->rx_dma_phys);
|
||||
+err_rx_dma_buf:
|
||||
+ dma_free_coherent(dev, DSPI_DMA_BUFSIZE,
|
||||
+ dma->tx_dma_buf, dma->tx_dma_phys);
|
||||
+err_tx_dma_buf:
|
||||
+ dma_release_channel(dma->chan_tx);
|
||||
+err_tx_channel:
|
||||
+ dma_release_channel(dma->chan_rx);
|
||||
+
|
||||
+ devm_kfree(dev, dma);
|
||||
+ dspi->dma = NULL;
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static void dspi_release_dma(struct fsl_dspi *dspi)
|
||||
+{
|
||||
+ struct fsl_dspi_dma *dma = dspi->dma;
|
||||
+ struct device *dev = &dspi->pdev->dev;
|
||||
+
|
||||
+ if (dma) {
|
||||
+ if (dma->chan_tx) {
|
||||
+ dma_unmap_single(dev, dma->tx_dma_phys,
|
||||
+ DSPI_DMA_BUFSIZE, DMA_TO_DEVICE);
|
||||
+ dma_release_channel(dma->chan_tx);
|
||||
+ }
|
||||
+
|
||||
+ if (dma->chan_rx) {
|
||||
+ dma_unmap_single(dev, dma->rx_dma_phys,
|
||||
+ DSPI_DMA_BUFSIZE, DMA_FROM_DEVICE);
|
||||
+ dma_release_channel(dma->chan_rx);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void hz_to_spi_baud(char *pbr, char *br, int speed_hz,
|
||||
unsigned long clkrate)
|
||||
{
|
||||
@@ -425,6 +705,12 @@ static int dspi_transfer_one_message(str
|
||||
regmap_write(dspi->regmap, SPI_RSER, SPI_RSER_TCFQE);
|
||||
dspi_tcfq_write(dspi);
|
||||
break;
|
||||
+ case DSPI_DMA_MODE:
|
||||
+ regmap_write(dspi->regmap, SPI_RSER,
|
||||
+ SPI_RSER_TFFFE | SPI_RSER_TFFFD |
|
||||
+ SPI_RSER_RFDFE | SPI_RSER_RFDFD);
|
||||
+ status = dspi_dma_xfer(dspi);
|
||||
+ break;
|
||||
default:
|
||||
dev_err(&dspi->pdev->dev, "unsupported trans_mode %u\n",
|
||||
trans_mode);
|
||||
@@ -432,9 +718,13 @@ static int dspi_transfer_one_message(str
|
||||
goto out;
|
||||
}
|
||||
|
||||
- if (wait_event_interruptible(dspi->waitq, dspi->waitflags))
|
||||
- dev_err(&dspi->pdev->dev, "wait transfer complete fail!\n");
|
||||
- dspi->waitflags = 0;
|
||||
+ if (trans_mode != DSPI_DMA_MODE) {
|
||||
+ if (wait_event_interruptible(dspi->waitq,
|
||||
+ dspi->waitflags))
|
||||
+ dev_err(&dspi->pdev->dev,
|
||||
+ "wait transfer complete fail!\n");
|
||||
+ dspi->waitflags = 0;
|
||||
+ }
|
||||
|
||||
if (transfer->delay_usecs)
|
||||
udelay(transfer->delay_usecs);
|
||||
@@ -712,7 +1002,8 @@ static int dspi_probe(struct platform_de
|
||||
if (IS_ERR(dspi->regmap)) {
|
||||
dev_err(&pdev->dev, "failed to init regmap: %ld\n",
|
||||
PTR_ERR(dspi->regmap));
|
||||
- return PTR_ERR(dspi->regmap);
|
||||
+ ret = PTR_ERR(dspi->regmap);
|
||||
+ goto out_master_put;
|
||||
}
|
||||
|
||||
dspi->clk = devm_clk_get(&pdev->dev, "dspi");
|
||||
@@ -740,6 +1031,13 @@ static int dspi_probe(struct platform_de
|
||||
goto out_clk_put;
|
||||
}
|
||||
|
||||
+ if (dspi->devtype_data->trans_mode == DSPI_DMA_MODE) {
|
||||
+ if (dspi_request_dma(dspi, res->start)) {
|
||||
+ dev_err(&pdev->dev, "can't get dma channels\n");
|
||||
+ goto out_clk_put;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
master->max_speed_hz =
|
||||
clk_get_rate(dspi->clk) / dspi->devtype_data->max_clock_factor;
|
||||
|
||||
@@ -768,6 +1066,7 @@ static int dspi_remove(struct platform_d
|
||||
struct fsl_dspi *dspi = spi_master_get_devdata(master);
|
||||
|
||||
/* Disconnect from the SPI framework */
|
||||
+ dspi_release_dma(dspi);
|
||||
clk_disable_unprepare(dspi->clk);
|
||||
spi_unregister_master(dspi->master);
|
||||
|
@ -1,162 +0,0 @@
|
||||
From c35aec61e5bb0faafb2847a0d750ebd7345a4b0f Mon Sep 17 00:00:00 2001
|
||||
From: Yangbo Lu <yangbo.lu@nxp.com>
|
||||
Date: Wed, 17 Jan 2018 15:40:24 +0800
|
||||
Subject: [PATCH 28/30] tty: serial: support layerscape
|
||||
|
||||
This is an integrated patch for layerscape uart support.
|
||||
|
||||
Signed-off-by: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
|
||||
Signed-off-by: Yuan Yao <yao.yuan@nxp.com>
|
||||
Signed-off-by: Stefan Agner <stefan@agner.ch>
|
||||
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
|
||||
---
|
||||
drivers/tty/serial/fsl_lpuart.c | 66 ++++++++++++++++++++++++++++-------------
|
||||
1 file changed, 46 insertions(+), 20 deletions(-)
|
||||
|
||||
--- a/drivers/tty/serial/fsl_lpuart.c
|
||||
+++ b/drivers/tty/serial/fsl_lpuart.c
|
||||
@@ -231,6 +231,8 @@
|
||||
#define DEV_NAME "ttyLP"
|
||||
#define UART_NR 6
|
||||
|
||||
+static DECLARE_BITMAP(linemap, UART_NR);
|
||||
+
|
||||
struct lpuart_port {
|
||||
struct uart_port port;
|
||||
struct clk *clk;
|
||||
@@ -1349,6 +1351,18 @@ lpuart_set_termios(struct uart_port *por
|
||||
/* ask the core to calculate the divisor */
|
||||
baud = uart_get_baud_rate(port, termios, old, 50, port->uartclk / 16);
|
||||
|
||||
+ /*
|
||||
+ * Need to update the Ring buffer length according to the selected
|
||||
+ * baud rate and restart Rx DMA path.
|
||||
+ *
|
||||
+ * Since timer function acqures sport->port.lock, need to stop before
|
||||
+ * acquring same lock because otherwise del_timer_sync() can deadlock.
|
||||
+ */
|
||||
+ if (old && sport->lpuart_dma_rx_use) {
|
||||
+ del_timer_sync(&sport->lpuart_timer);
|
||||
+ lpuart_dma_rx_free(&sport->port);
|
||||
+ }
|
||||
+
|
||||
spin_lock_irqsave(&sport->port.lock, flags);
|
||||
|
||||
sport->port.read_status_mask = 0;
|
||||
@@ -1398,22 +1412,11 @@ lpuart_set_termios(struct uart_port *por
|
||||
/* restore control register */
|
||||
writeb(old_cr2, sport->port.membase + UARTCR2);
|
||||
|
||||
- /*
|
||||
- * If new baud rate is set, we will also need to update the Ring buffer
|
||||
- * length according to the selected baud rate and restart Rx DMA path.
|
||||
- */
|
||||
- if (old) {
|
||||
- if (sport->lpuart_dma_rx_use) {
|
||||
- del_timer_sync(&sport->lpuart_timer);
|
||||
- lpuart_dma_rx_free(&sport->port);
|
||||
- }
|
||||
-
|
||||
- if (sport->dma_rx_chan && !lpuart_start_rx_dma(sport)) {
|
||||
- sport->lpuart_dma_rx_use = true;
|
||||
+ if (old && sport->lpuart_dma_rx_use) {
|
||||
+ if (!lpuart_start_rx_dma(sport))
|
||||
rx_dma_timer_init(sport);
|
||||
- } else {
|
||||
+ else
|
||||
sport->lpuart_dma_rx_use = false;
|
||||
- }
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&sport->port.lock, flags);
|
||||
@@ -1641,6 +1644,13 @@ lpuart_console_write(struct console *co,
|
||||
{
|
||||
struct lpuart_port *sport = lpuart_ports[co->index];
|
||||
unsigned char old_cr2, cr2;
|
||||
+ unsigned long flags;
|
||||
+ int locked = 1;
|
||||
+
|
||||
+ if (sport->port.sysrq || oops_in_progress)
|
||||
+ locked = spin_trylock_irqsave(&sport->port.lock, flags);
|
||||
+ else
|
||||
+ spin_lock_irqsave(&sport->port.lock, flags);
|
||||
|
||||
/* first save CR2 and then disable interrupts */
|
||||
cr2 = old_cr2 = readb(sport->port.membase + UARTCR2);
|
||||
@@ -1655,6 +1665,9 @@ lpuart_console_write(struct console *co,
|
||||
barrier();
|
||||
|
||||
writeb(old_cr2, sport->port.membase + UARTCR2);
|
||||
+
|
||||
+ if (locked)
|
||||
+ spin_unlock_irqrestore(&sport->port.lock, flags);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1662,6 +1675,13 @@ lpuart32_console_write(struct console *c
|
||||
{
|
||||
struct lpuart_port *sport = lpuart_ports[co->index];
|
||||
unsigned long old_cr, cr;
|
||||
+ unsigned long flags;
|
||||
+ int locked = 1;
|
||||
+
|
||||
+ if (sport->port.sysrq || oops_in_progress)
|
||||
+ locked = spin_trylock_irqsave(&sport->port.lock, flags);
|
||||
+ else
|
||||
+ spin_lock_irqsave(&sport->port.lock, flags);
|
||||
|
||||
/* first save CR2 and then disable interrupts */
|
||||
cr = old_cr = lpuart32_read(sport->port.membase + UARTCTRL);
|
||||
@@ -1676,6 +1696,9 @@ lpuart32_console_write(struct console *c
|
||||
barrier();
|
||||
|
||||
lpuart32_write(old_cr, sport->port.membase + UARTCTRL);
|
||||
+
|
||||
+ if (locked)
|
||||
+ spin_unlock_irqrestore(&sport->port.lock, flags);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1900,13 +1923,13 @@ static int lpuart_probe(struct platform_
|
||||
|
||||
ret = of_alias_get_id(np, "serial");
|
||||
if (ret < 0) {
|
||||
- dev_err(&pdev->dev, "failed to get alias id, errno %d\n", ret);
|
||||
- return ret;
|
||||
- }
|
||||
- if (ret >= ARRAY_SIZE(lpuart_ports)) {
|
||||
- dev_err(&pdev->dev, "serial%d out of range\n", ret);
|
||||
- return -EINVAL;
|
||||
+ ret = find_first_zero_bit(linemap, UART_NR);
|
||||
+ if (ret >= UART_NR) {
|
||||
+ dev_err(&pdev->dev, "port line is full, add device failed\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
}
|
||||
+ set_bit(ret, linemap);
|
||||
sport->port.line = ret;
|
||||
sport->lpuart32 = of_device_is_compatible(np, "fsl,ls1021a-lpuart");
|
||||
|
||||
@@ -1988,6 +2011,7 @@ static int lpuart_remove(struct platform
|
||||
struct lpuart_port *sport = platform_get_drvdata(pdev);
|
||||
|
||||
uart_remove_one_port(&lpuart_reg, &sport->port);
|
||||
+ clear_bit(sport->port.line, linemap);
|
||||
|
||||
clk_disable_unprepare(sport->clk);
|
||||
|
||||
@@ -2072,12 +2096,10 @@ static int lpuart_resume(struct device *
|
||||
|
||||
if (sport->lpuart_dma_rx_use) {
|
||||
if (sport->port.irq_wake) {
|
||||
- if (!lpuart_start_rx_dma(sport)) {
|
||||
- sport->lpuart_dma_rx_use = true;
|
||||
+ if (!lpuart_start_rx_dma(sport))
|
||||
rx_dma_timer_init(sport);
|
||||
- } else {
|
||||
+ else
|
||||
sport->lpuart_dma_rx_use = false;
|
||||
- }
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,542 +0,0 @@
|
||||
From 2887442bd13bc8be687afc7172cb01c2b7f0dd3b Mon Sep 17 00:00:00 2001
|
||||
From: Yangbo Lu <yangbo.lu@nxp.com>
|
||||
Date: Thu, 5 Jul 2018 17:41:14 +0800
|
||||
Subject: [PATCH 31/32] flexcan: support layerscape
|
||||
|
||||
This is an integrated patch for layerscape flexcan support.
|
||||
|
||||
Signed-off-by: Pankaj Bansal <pankaj.bansal@nxp.com>
|
||||
Signed-off-by: Bhupesh Sharma <bhupesh.sharma@freescale.com>
|
||||
Signed-off-by: Sakar Arora <Sakar.Arora@freescale.com>
|
||||
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
|
||||
---
|
||||
drivers/net/can/flexcan.c | 212 ++++++++++++++++++++++----------------
|
||||
1 file changed, 123 insertions(+), 89 deletions(-)
|
||||
|
||||
--- a/drivers/net/can/flexcan.c
|
||||
+++ b/drivers/net/can/flexcan.c
|
||||
@@ -184,6 +184,7 @@
|
||||
* MX53 FlexCAN2 03.00.00.00 yes no no no
|
||||
* MX6s FlexCAN3 10.00.12.00 yes yes no yes
|
||||
* VF610 FlexCAN3 ? no yes yes yes?
|
||||
+ * LS1021A FlexCAN2 03.00.04.00 no yes no yes
|
||||
*
|
||||
* Some SOCs do not have the RX_WARN & TX_WARN interrupt line connected.
|
||||
*/
|
||||
@@ -260,6 +261,10 @@ struct flexcan_priv {
|
||||
struct flexcan_platform_data *pdata;
|
||||
const struct flexcan_devtype_data *devtype_data;
|
||||
struct regulator *reg_xceiver;
|
||||
+
|
||||
+ /* Read and Write APIs */
|
||||
+ u32 (*read)(void __iomem *addr);
|
||||
+ void (*write)(u32 val, void __iomem *addr);
|
||||
};
|
||||
|
||||
static struct flexcan_devtype_data fsl_p1010_devtype_data = {
|
||||
@@ -276,6 +281,10 @@ static struct flexcan_devtype_data fsl_v
|
||||
.quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_DISABLE_MECR,
|
||||
};
|
||||
|
||||
+static const struct flexcan_devtype_data fsl_ls1021a_r2_devtype_data = {
|
||||
+ .quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_DISABLE_MECR,
|
||||
+};
|
||||
+
|
||||
static const struct can_bittiming_const flexcan_bittiming_const = {
|
||||
.name = DRV_NAME,
|
||||
.tseg1_min = 4,
|
||||
@@ -288,32 +297,38 @@ static const struct can_bittiming_const
|
||||
.brp_inc = 1,
|
||||
};
|
||||
|
||||
-/* Abstract off the read/write for arm versus ppc. This
|
||||
- * assumes that PPC uses big-endian registers and everything
|
||||
- * else uses little-endian registers, independent of CPU
|
||||
- * endianness.
|
||||
+/* FlexCAN module is essentially modelled as a little-endian IP in most
|
||||
+ * SoCs, i.e the registers as well as the message buffer areas are
|
||||
+ * implemented in a little-endian fashion.
|
||||
+ *
|
||||
+ * However there are some SoCs (e.g. LS1021A) which implement the FlexCAN
|
||||
+ * module in a big-endian fashion (i.e the registers as well as the
|
||||
+ * message buffer areas are implemented in a big-endian way).
|
||||
+ *
|
||||
+ * In addition, the FlexCAN module can be found on SoCs having ARM or
|
||||
+ * PPC cores. So, we need to abstract off the register read/write
|
||||
+ * functions, ensuring that these cater to all the combinations of module
|
||||
+ * endianness and underlying CPU endianness.
|
||||
*/
|
||||
-#if defined(CONFIG_PPC)
|
||||
-static inline u32 flexcan_read(void __iomem *addr)
|
||||
+static inline u32 flexcan_read_be(void __iomem *addr)
|
||||
{
|
||||
- return in_be32(addr);
|
||||
+ return ioread32be(addr);
|
||||
}
|
||||
|
||||
-static inline void flexcan_write(u32 val, void __iomem *addr)
|
||||
+static inline void flexcan_write_be(u32 val, void __iomem *addr)
|
||||
{
|
||||
- out_be32(addr, val);
|
||||
+ iowrite32be(val, addr);
|
||||
}
|
||||
-#else
|
||||
-static inline u32 flexcan_read(void __iomem *addr)
|
||||
+
|
||||
+static inline u32 flexcan_read_le(void __iomem *addr)
|
||||
{
|
||||
- return readl(addr);
|
||||
+ return ioread32(addr);
|
||||
}
|
||||
|
||||
-static inline void flexcan_write(u32 val, void __iomem *addr)
|
||||
+static inline void flexcan_write_le(u32 val, void __iomem *addr)
|
||||
{
|
||||
- writel(val, addr);
|
||||
+ iowrite32(val, addr);
|
||||
}
|
||||
-#endif
|
||||
|
||||
static inline int flexcan_transceiver_enable(const struct flexcan_priv *priv)
|
||||
{
|
||||
@@ -344,14 +359,14 @@ static int flexcan_chip_enable(struct fl
|
||||
unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
|
||||
u32 reg;
|
||||
|
||||
- reg = flexcan_read(®s->mcr);
|
||||
+ reg = priv->read(®s->mcr);
|
||||
reg &= ~FLEXCAN_MCR_MDIS;
|
||||
- flexcan_write(reg, ®s->mcr);
|
||||
+ priv->write(reg, ®s->mcr);
|
||||
|
||||
- while (timeout-- && (flexcan_read(®s->mcr) & FLEXCAN_MCR_LPM_ACK))
|
||||
+ while (timeout-- && (priv->read(®s->mcr) & FLEXCAN_MCR_LPM_ACK))
|
||||
udelay(10);
|
||||
|
||||
- if (flexcan_read(®s->mcr) & FLEXCAN_MCR_LPM_ACK)
|
||||
+ if (priv->read(®s->mcr) & FLEXCAN_MCR_LPM_ACK)
|
||||
return -ETIMEDOUT;
|
||||
|
||||
return 0;
|
||||
@@ -363,14 +378,14 @@ static int flexcan_chip_disable(struct f
|
||||
unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
|
||||
u32 reg;
|
||||
|
||||
- reg = flexcan_read(®s->mcr);
|
||||
+ reg = priv->read(®s->mcr);
|
||||
reg |= FLEXCAN_MCR_MDIS;
|
||||
- flexcan_write(reg, ®s->mcr);
|
||||
+ priv->write(reg, ®s->mcr);
|
||||
|
||||
- while (timeout-- && !(flexcan_read(®s->mcr) & FLEXCAN_MCR_LPM_ACK))
|
||||
+ while (timeout-- && !(priv->read(®s->mcr) & FLEXCAN_MCR_LPM_ACK))
|
||||
udelay(10);
|
||||
|
||||
- if (!(flexcan_read(®s->mcr) & FLEXCAN_MCR_LPM_ACK))
|
||||
+ if (!(priv->read(®s->mcr) & FLEXCAN_MCR_LPM_ACK))
|
||||
return -ETIMEDOUT;
|
||||
|
||||
return 0;
|
||||
@@ -382,14 +397,14 @@ static int flexcan_chip_freeze(struct fl
|
||||
unsigned int timeout = 1000 * 1000 * 10 / priv->can.bittiming.bitrate;
|
||||
u32 reg;
|
||||
|
||||
- reg = flexcan_read(®s->mcr);
|
||||
+ reg = priv->read(®s->mcr);
|
||||
reg |= FLEXCAN_MCR_HALT;
|
||||
- flexcan_write(reg, ®s->mcr);
|
||||
+ priv->write(reg, ®s->mcr);
|
||||
|
||||
- while (timeout-- && !(flexcan_read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK))
|
||||
+ while (timeout-- && !(priv->read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK))
|
||||
udelay(100);
|
||||
|
||||
- if (!(flexcan_read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK))
|
||||
+ if (!(priv->read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK))
|
||||
return -ETIMEDOUT;
|
||||
|
||||
return 0;
|
||||
@@ -401,14 +416,14 @@ static int flexcan_chip_unfreeze(struct
|
||||
unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
|
||||
u32 reg;
|
||||
|
||||
- reg = flexcan_read(®s->mcr);
|
||||
+ reg = priv->read(®s->mcr);
|
||||
reg &= ~FLEXCAN_MCR_HALT;
|
||||
- flexcan_write(reg, ®s->mcr);
|
||||
+ priv->write(reg, ®s->mcr);
|
||||
|
||||
- while (timeout-- && (flexcan_read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK))
|
||||
+ while (timeout-- && (priv->read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK))
|
||||
udelay(10);
|
||||
|
||||
- if (flexcan_read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK)
|
||||
+ if (priv->read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK)
|
||||
return -ETIMEDOUT;
|
||||
|
||||
return 0;
|
||||
@@ -419,11 +434,11 @@ static int flexcan_chip_softreset(struct
|
||||
struct flexcan_regs __iomem *regs = priv->regs;
|
||||
unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
|
||||
|
||||
- flexcan_write(FLEXCAN_MCR_SOFTRST, ®s->mcr);
|
||||
- while (timeout-- && (flexcan_read(®s->mcr) & FLEXCAN_MCR_SOFTRST))
|
||||
+ priv->write(FLEXCAN_MCR_SOFTRST, ®s->mcr);
|
||||
+ while (timeout-- && (priv->read(®s->mcr) & FLEXCAN_MCR_SOFTRST))
|
||||
udelay(10);
|
||||
|
||||
- if (flexcan_read(®s->mcr) & FLEXCAN_MCR_SOFTRST)
|
||||
+ if (priv->read(®s->mcr) & FLEXCAN_MCR_SOFTRST)
|
||||
return -ETIMEDOUT;
|
||||
|
||||
return 0;
|
||||
@@ -434,7 +449,7 @@ static int __flexcan_get_berr_counter(co
|
||||
{
|
||||
const struct flexcan_priv *priv = netdev_priv(dev);
|
||||
struct flexcan_regs __iomem *regs = priv->regs;
|
||||
- u32 reg = flexcan_read(®s->ecr);
|
||||
+ u32 reg = priv->read(®s->ecr);
|
||||
|
||||
bec->txerr = (reg >> 0) & 0xff;
|
||||
bec->rxerr = (reg >> 8) & 0xff;
|
||||
@@ -491,24 +506,24 @@ static int flexcan_start_xmit(struct sk_
|
||||
|
||||
if (cf->can_dlc > 0) {
|
||||
data = be32_to_cpup((__be32 *)&cf->data[0]);
|
||||
- flexcan_write(data, ®s->mb[FLEXCAN_TX_BUF_ID].data[0]);
|
||||
+ priv->write(data, ®s->mb[FLEXCAN_TX_BUF_ID].data[0]);
|
||||
}
|
||||
if (cf->can_dlc > 4) {
|
||||
data = be32_to_cpup((__be32 *)&cf->data[4]);
|
||||
- flexcan_write(data, ®s->mb[FLEXCAN_TX_BUF_ID].data[1]);
|
||||
+ priv->write(data, ®s->mb[FLEXCAN_TX_BUF_ID].data[1]);
|
||||
}
|
||||
|
||||
can_put_echo_skb(skb, dev, 0);
|
||||
|
||||
- flexcan_write(can_id, ®s->mb[FLEXCAN_TX_BUF_ID].can_id);
|
||||
- flexcan_write(ctrl, ®s->mb[FLEXCAN_TX_BUF_ID].can_ctrl);
|
||||
+ priv->write(can_id, ®s->mb[FLEXCAN_TX_BUF_ID].can_id);
|
||||
+ priv->write(ctrl, ®s->mb[FLEXCAN_TX_BUF_ID].can_ctrl);
|
||||
|
||||
/* Errata ERR005829 step8:
|
||||
* Write twice INACTIVE(0x8) code to first MB.
|
||||
*/
|
||||
- flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
|
||||
+ priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
|
||||
®s->mb[FLEXCAN_TX_BUF_RESERVED].can_ctrl);
|
||||
- flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
|
||||
+ priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
|
||||
®s->mb[FLEXCAN_TX_BUF_RESERVED].can_ctrl);
|
||||
|
||||
return NETDEV_TX_OK;
|
||||
@@ -632,8 +647,8 @@ static void flexcan_read_fifo(const stru
|
||||
struct flexcan_mb __iomem *mb = ®s->mb[0];
|
||||
u32 reg_ctrl, reg_id;
|
||||
|
||||
- reg_ctrl = flexcan_read(&mb->can_ctrl);
|
||||
- reg_id = flexcan_read(&mb->can_id);
|
||||
+ reg_ctrl = priv->read(&mb->can_ctrl);
|
||||
+ reg_id = priv->read(&mb->can_id);
|
||||
if (reg_ctrl & FLEXCAN_MB_CNT_IDE)
|
||||
cf->can_id = ((reg_id >> 0) & CAN_EFF_MASK) | CAN_EFF_FLAG;
|
||||
else
|
||||
@@ -643,12 +658,12 @@ static void flexcan_read_fifo(const stru
|
||||
cf->can_id |= CAN_RTR_FLAG;
|
||||
cf->can_dlc = get_can_dlc((reg_ctrl >> 16) & 0xf);
|
||||
|
||||
- *(__be32 *)(cf->data + 0) = cpu_to_be32(flexcan_read(&mb->data[0]));
|
||||
- *(__be32 *)(cf->data + 4) = cpu_to_be32(flexcan_read(&mb->data[1]));
|
||||
+ *(__be32 *)(cf->data + 0) = cpu_to_be32(priv->read(&mb->data[0]));
|
||||
+ *(__be32 *)(cf->data + 4) = cpu_to_be32(priv->read(&mb->data[1]));
|
||||
|
||||
/* mark as read */
|
||||
- flexcan_write(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, ®s->iflag1);
|
||||
- flexcan_read(®s->timer);
|
||||
+ priv->write(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, ®s->iflag1);
|
||||
+ priv->read(®s->timer);
|
||||
}
|
||||
|
||||
static int flexcan_read_frame(struct net_device *dev)
|
||||
@@ -685,17 +700,17 @@ static int flexcan_poll(struct napi_stru
|
||||
/* The error bits are cleared on read,
|
||||
* use saved value from irq handler.
|
||||
*/
|
||||
- reg_esr = flexcan_read(®s->esr) | priv->reg_esr;
|
||||
+ reg_esr = priv->read(®s->esr) | priv->reg_esr;
|
||||
|
||||
/* handle state changes */
|
||||
work_done += flexcan_poll_state(dev, reg_esr);
|
||||
|
||||
/* handle RX-FIFO */
|
||||
- reg_iflag1 = flexcan_read(®s->iflag1);
|
||||
+ reg_iflag1 = priv->read(®s->iflag1);
|
||||
while (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE &&
|
||||
work_done < quota) {
|
||||
work_done += flexcan_read_frame(dev);
|
||||
- reg_iflag1 = flexcan_read(®s->iflag1);
|
||||
+ reg_iflag1 = priv->read(®s->iflag1);
|
||||
}
|
||||
|
||||
/* report bus errors */
|
||||
@@ -705,8 +720,8 @@ static int flexcan_poll(struct napi_stru
|
||||
if (work_done < quota) {
|
||||
napi_complete_done(napi, work_done);
|
||||
/* enable IRQs */
|
||||
- flexcan_write(FLEXCAN_IFLAG_DEFAULT, ®s->imask1);
|
||||
- flexcan_write(priv->reg_ctrl_default, ®s->ctrl);
|
||||
+ priv->write(FLEXCAN_IFLAG_DEFAULT, ®s->imask1);
|
||||
+ priv->write(priv->reg_ctrl_default, ®s->ctrl);
|
||||
}
|
||||
|
||||
return work_done;
|
||||
@@ -720,12 +735,12 @@ static irqreturn_t flexcan_irq(int irq,
|
||||
struct flexcan_regs __iomem *regs = priv->regs;
|
||||
u32 reg_iflag1, reg_esr;
|
||||
|
||||
- reg_iflag1 = flexcan_read(®s->iflag1);
|
||||
- reg_esr = flexcan_read(®s->esr);
|
||||
+ reg_iflag1 = priv->read(®s->iflag1);
|
||||
+ reg_esr = priv->read(®s->esr);
|
||||
|
||||
/* ACK all bus error and state change IRQ sources */
|
||||
if (reg_esr & FLEXCAN_ESR_ALL_INT)
|
||||
- flexcan_write(reg_esr & FLEXCAN_ESR_ALL_INT, ®s->esr);
|
||||
+ priv->write(reg_esr & FLEXCAN_ESR_ALL_INT, ®s->esr);
|
||||
|
||||
/* schedule NAPI in case of:
|
||||
* - rx IRQ
|
||||
@@ -739,16 +754,16 @@ static irqreturn_t flexcan_irq(int irq,
|
||||
* save them for later use.
|
||||
*/
|
||||
priv->reg_esr = reg_esr & FLEXCAN_ESR_ERR_BUS;
|
||||
- flexcan_write(FLEXCAN_IFLAG_DEFAULT &
|
||||
+ priv->write(FLEXCAN_IFLAG_DEFAULT &
|
||||
~FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, ®s->imask1);
|
||||
- flexcan_write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL,
|
||||
+ priv->write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL,
|
||||
®s->ctrl);
|
||||
napi_schedule(&priv->napi);
|
||||
}
|
||||
|
||||
/* FIFO overflow */
|
||||
if (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_OVERFLOW) {
|
||||
- flexcan_write(FLEXCAN_IFLAG_RX_FIFO_OVERFLOW, ®s->iflag1);
|
||||
+ priv->write(FLEXCAN_IFLAG_RX_FIFO_OVERFLOW, ®s->iflag1);
|
||||
dev->stats.rx_over_errors++;
|
||||
dev->stats.rx_errors++;
|
||||
}
|
||||
@@ -760,9 +775,9 @@ static irqreturn_t flexcan_irq(int irq,
|
||||
can_led_event(dev, CAN_LED_EVENT_TX);
|
||||
|
||||
/* after sending a RTR frame MB is in RX mode */
|
||||
- flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
|
||||
+ priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
|
||||
®s->mb[FLEXCAN_TX_BUF_ID].can_ctrl);
|
||||
- flexcan_write((1 << FLEXCAN_TX_BUF_ID), ®s->iflag1);
|
||||
+ priv->write((1 << FLEXCAN_TX_BUF_ID), ®s->iflag1);
|
||||
netif_wake_queue(dev);
|
||||
}
|
||||
|
||||
@@ -776,7 +791,7 @@ static void flexcan_set_bittiming(struct
|
||||
struct flexcan_regs __iomem *regs = priv->regs;
|
||||
u32 reg;
|
||||
|
||||
- reg = flexcan_read(®s->ctrl);
|
||||
+ reg = priv->read(®s->ctrl);
|
||||
reg &= ~(FLEXCAN_CTRL_PRESDIV(0xff) |
|
||||
FLEXCAN_CTRL_RJW(0x3) |
|
||||
FLEXCAN_CTRL_PSEG1(0x7) |
|
||||
@@ -800,11 +815,11 @@ static void flexcan_set_bittiming(struct
|
||||
reg |= FLEXCAN_CTRL_SMP;
|
||||
|
||||
netdev_dbg(dev, "writing ctrl=0x%08x\n", reg);
|
||||
- flexcan_write(reg, ®s->ctrl);
|
||||
+ priv->write(reg, ®s->ctrl);
|
||||
|
||||
/* print chip status */
|
||||
netdev_dbg(dev, "%s: mcr=0x%08x ctrl=0x%08x\n", __func__,
|
||||
- flexcan_read(®s->mcr), flexcan_read(®s->ctrl));
|
||||
+ priv->read(®s->mcr), priv->read(®s->ctrl));
|
||||
}
|
||||
|
||||
/* flexcan_chip_start
|
||||
@@ -842,13 +857,13 @@ static int flexcan_chip_start(struct net
|
||||
* choose format C
|
||||
* set max mailbox number
|
||||
*/
|
||||
- reg_mcr = flexcan_read(®s->mcr);
|
||||
+ reg_mcr = priv->read(®s->mcr);
|
||||
reg_mcr &= ~FLEXCAN_MCR_MAXMB(0xff);
|
||||
reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_FEN | FLEXCAN_MCR_HALT |
|
||||
FLEXCAN_MCR_SUPV | FLEXCAN_MCR_WRN_EN | FLEXCAN_MCR_SRX_DIS |
|
||||
FLEXCAN_MCR_IDAM_C | FLEXCAN_MCR_MAXMB(FLEXCAN_TX_BUF_ID);
|
||||
netdev_dbg(dev, "%s: writing mcr=0x%08x", __func__, reg_mcr);
|
||||
- flexcan_write(reg_mcr, ®s->mcr);
|
||||
+ priv->write(reg_mcr, ®s->mcr);
|
||||
|
||||
/* CTRL
|
||||
*
|
||||
@@ -861,7 +876,7 @@ static int flexcan_chip_start(struct net
|
||||
* enable bus off interrupt
|
||||
* (== FLEXCAN_CTRL_ERR_STATE)
|
||||
*/
|
||||
- reg_ctrl = flexcan_read(®s->ctrl);
|
||||
+ reg_ctrl = priv->read(®s->ctrl);
|
||||
reg_ctrl &= ~FLEXCAN_CTRL_TSYN;
|
||||
reg_ctrl |= FLEXCAN_CTRL_BOFF_REC | FLEXCAN_CTRL_LBUF |
|
||||
FLEXCAN_CTRL_ERR_STATE;
|
||||
@@ -881,29 +896,29 @@ static int flexcan_chip_start(struct net
|
||||
/* leave interrupts disabled for now */
|
||||
reg_ctrl &= ~FLEXCAN_CTRL_ERR_ALL;
|
||||
netdev_dbg(dev, "%s: writing ctrl=0x%08x", __func__, reg_ctrl);
|
||||
- flexcan_write(reg_ctrl, ®s->ctrl);
|
||||
+ priv->write(reg_ctrl, ®s->ctrl);
|
||||
|
||||
/* clear and invalidate all mailboxes first */
|
||||
for (i = FLEXCAN_TX_BUF_ID; i < ARRAY_SIZE(regs->mb); i++) {
|
||||
- flexcan_write(FLEXCAN_MB_CODE_RX_INACTIVE,
|
||||
+ priv->write(FLEXCAN_MB_CODE_RX_INACTIVE,
|
||||
®s->mb[i].can_ctrl);
|
||||
}
|
||||
|
||||
/* Errata ERR005829: mark first TX mailbox as INACTIVE */
|
||||
- flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
|
||||
+ priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
|
||||
®s->mb[FLEXCAN_TX_BUF_RESERVED].can_ctrl);
|
||||
|
||||
/* mark TX mailbox as INACTIVE */
|
||||
- flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE,
|
||||
+ priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
|
||||
®s->mb[FLEXCAN_TX_BUF_ID].can_ctrl);
|
||||
|
||||
/* acceptance mask/acceptance code (accept everything) */
|
||||
- flexcan_write(0x0, ®s->rxgmask);
|
||||
- flexcan_write(0x0, ®s->rx14mask);
|
||||
- flexcan_write(0x0, ®s->rx15mask);
|
||||
+ priv->write(0x0, ®s->rxgmask);
|
||||
+ priv->write(0x0, ®s->rx14mask);
|
||||
+ priv->write(0x0, ®s->rx15mask);
|
||||
|
||||
if (priv->devtype_data->quirks & FLEXCAN_QUIRK_DISABLE_RXFG)
|
||||
- flexcan_write(0x0, ®s->rxfgmask);
|
||||
+ priv->write(0x0, ®s->rxfgmask);
|
||||
|
||||
/* On Vybrid, disable memory error detection interrupts
|
||||
* and freeze mode.
|
||||
@@ -916,16 +931,16 @@ static int flexcan_chip_start(struct net
|
||||
* and Correction of Memory Errors" to write to
|
||||
* MECR register
|
||||
*/
|
||||
- reg_ctrl2 = flexcan_read(®s->ctrl2);
|
||||
+ reg_ctrl2 = priv->read(®s->ctrl2);
|
||||
reg_ctrl2 |= FLEXCAN_CTRL2_ECRWRE;
|
||||
- flexcan_write(reg_ctrl2, ®s->ctrl2);
|
||||
+ priv->write(reg_ctrl2, ®s->ctrl2);
|
||||
|
||||
- reg_mecr = flexcan_read(®s->mecr);
|
||||
+ reg_mecr = priv->read(®s->mecr);
|
||||
reg_mecr &= ~FLEXCAN_MECR_ECRWRDIS;
|
||||
- flexcan_write(reg_mecr, ®s->mecr);
|
||||
+ priv->write(reg_mecr, ®s->mecr);
|
||||
reg_mecr &= ~(FLEXCAN_MECR_NCEFAFRZ | FLEXCAN_MECR_HANCEI_MSK |
|
||||
FLEXCAN_MECR_FANCEI_MSK);
|
||||
- flexcan_write(reg_mecr, ®s->mecr);
|
||||
+ priv->write(reg_mecr, ®s->mecr);
|
||||
}
|
||||
|
||||
err = flexcan_transceiver_enable(priv);
|
||||
@@ -941,13 +956,13 @@ static int flexcan_chip_start(struct net
|
||||
|
||||
/* enable interrupts atomically */
|
||||
disable_irq(dev->irq);
|
||||
- flexcan_write(priv->reg_ctrl_default, ®s->ctrl);
|
||||
- flexcan_write(FLEXCAN_IFLAG_DEFAULT, ®s->imask1);
|
||||
+ priv->write(priv->reg_ctrl_default, ®s->ctrl);
|
||||
+ priv->write(FLEXCAN_IFLAG_DEFAULT, ®s->imask1);
|
||||
enable_irq(dev->irq);
|
||||
|
||||
/* print chip status */
|
||||
netdev_dbg(dev, "%s: reading mcr=0x%08x ctrl=0x%08x\n", __func__,
|
||||
- flexcan_read(®s->mcr), flexcan_read(®s->ctrl));
|
||||
+ priv->read(®s->mcr), priv->read(®s->ctrl));
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -972,8 +987,8 @@ static void flexcan_chip_stop(struct net
|
||||
flexcan_chip_disable(priv);
|
||||
|
||||
/* Disable all interrupts */
|
||||
- flexcan_write(0, ®s->imask1);
|
||||
- flexcan_write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL,
|
||||
+ priv->write(0, ®s->imask1);
|
||||
+ priv->write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL,
|
||||
®s->ctrl);
|
||||
|
||||
flexcan_transceiver_disable(priv);
|
||||
@@ -1089,25 +1104,25 @@ static int register_flexcandev(struct ne
|
||||
err = flexcan_chip_disable(priv);
|
||||
if (err)
|
||||
goto out_disable_per;
|
||||
- reg = flexcan_read(®s->ctrl);
|
||||
+ reg = priv->read(®s->ctrl);
|
||||
reg |= FLEXCAN_CTRL_CLK_SRC;
|
||||
- flexcan_write(reg, ®s->ctrl);
|
||||
+ priv->write(reg, ®s->ctrl);
|
||||
|
||||
err = flexcan_chip_enable(priv);
|
||||
if (err)
|
||||
goto out_chip_disable;
|
||||
|
||||
/* set freeze, halt and activate FIFO, restrict register access */
|
||||
- reg = flexcan_read(®s->mcr);
|
||||
+ reg = priv->read(®s->mcr);
|
||||
reg |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT |
|
||||
FLEXCAN_MCR_FEN | FLEXCAN_MCR_SUPV;
|
||||
- flexcan_write(reg, ®s->mcr);
|
||||
+ priv->write(reg, ®s->mcr);
|
||||
|
||||
/* Currently we only support newer versions of this core
|
||||
* featuring a RX FIFO. Older cores found on some Coldfire
|
||||
* derivates are not yet supported.
|
||||
*/
|
||||
- reg = flexcan_read(®s->mcr);
|
||||
+ reg = priv->read(®s->mcr);
|
||||
if (!(reg & FLEXCAN_MCR_FEN)) {
|
||||
netdev_err(dev, "Could not enable RX FIFO, unsupported core\n");
|
||||
err = -ENODEV;
|
||||
@@ -1135,8 +1150,12 @@ static void unregister_flexcandev(struct
|
||||
static const struct of_device_id flexcan_of_match[] = {
|
||||
{ .compatible = "fsl,imx6q-flexcan", .data = &fsl_imx6q_devtype_data, },
|
||||
{ .compatible = "fsl,imx28-flexcan", .data = &fsl_imx28_devtype_data, },
|
||||
+ { .compatible = "fsl,imx53-flexcan", .data = &fsl_p1010_devtype_data, },
|
||||
+ { .compatible = "fsl,imx35-flexcan", .data = &fsl_p1010_devtype_data, },
|
||||
+ { .compatible = "fsl,imx25-flexcan", .data = &fsl_p1010_devtype_data, },
|
||||
{ .compatible = "fsl,p1010-flexcan", .data = &fsl_p1010_devtype_data, },
|
||||
{ .compatible = "fsl,vf610-flexcan", .data = &fsl_vf610_devtype_data, },
|
||||
+ { .compatible = "fsl,ls1021ar2-flexcan", .data = &fsl_ls1021a_r2_devtype_data, },
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, flexcan_of_match);
|
||||
@@ -1213,6 +1232,21 @@ static int flexcan_probe(struct platform
|
||||
dev->flags |= IFF_ECHO;
|
||||
|
||||
priv = netdev_priv(dev);
|
||||
+
|
||||
+ if (of_property_read_bool(pdev->dev.of_node, "big-endian")) {
|
||||
+ priv->read = flexcan_read_be;
|
||||
+ priv->write = flexcan_write_be;
|
||||
+ } else {
|
||||
+ if (of_device_is_compatible(pdev->dev.of_node,
|
||||
+ "fsl,p1010-flexcan")) {
|
||||
+ priv->read = flexcan_read_be;
|
||||
+ priv->write = flexcan_write_be;
|
||||
+ } else {
|
||||
+ priv->read = flexcan_read_le;
|
||||
+ priv->write = flexcan_write_le;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
priv->can.clock.freq = clock_freq;
|
||||
priv->can.bittiming_const = &flexcan_bittiming_const;
|
||||
priv->can.do_set_mode = flexcan_set_mode;
|
@ -1,239 +0,0 @@
|
||||
From fe22151c95c02c6bb145ea6c3685941e8fb09d60 Mon Sep 17 00:00:00 2001
|
||||
From: Yangbo Lu <yangbo.lu@nxp.com>
|
||||
Date: Thu, 5 Jul 2018 17:43:16 +0800
|
||||
Subject: [PATCH 32/32] kvm: support layerscape
|
||||
|
||||
This is an integrated patch for layerscape kvm support.
|
||||
|
||||
Signed-off-by: Laurentiu Tudor <laurentiu.tudor@nxp.com>
|
||||
Signed-off-by: Bharat Bhushan <Bharat.Bhushan@nxp.com>
|
||||
Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
|
||||
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
|
||||
---
|
||||
arch/arm/include/asm/kvm_mmu.h | 3 +-
|
||||
arch/arm/kvm/mmu.c | 56 ++++++++++++++++++++++++++++++--
|
||||
arch/arm64/include/asm/kvm_mmu.h | 14 ++++++--
|
||||
virt/kvm/arm/vgic/vgic-its.c | 24 +++++++++++---
|
||||
virt/kvm/arm/vgic/vgic-v2.c | 3 +-
|
||||
5 files changed, 88 insertions(+), 12 deletions(-)
|
||||
|
||||
--- a/arch/arm/include/asm/kvm_mmu.h
|
||||
+++ b/arch/arm/include/asm/kvm_mmu.h
|
||||
@@ -55,7 +55,8 @@ void stage2_unmap_vm(struct kvm *kvm);
|
||||
int kvm_alloc_stage2_pgd(struct kvm *kvm);
|
||||
void kvm_free_stage2_pgd(struct kvm *kvm);
|
||||
int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa,
|
||||
- phys_addr_t pa, unsigned long size, bool writable);
|
||||
+ phys_addr_t pa, unsigned long size, bool writable,
|
||||
+ pgprot_t prot);
|
||||
|
||||
int kvm_handle_guest_abort(struct kvm_vcpu *vcpu, struct kvm_run *run);
|
||||
|
||||
--- a/arch/arm/kvm/mmu.c
|
||||
+++ b/arch/arm/kvm/mmu.c
|
||||
@@ -1020,9 +1020,11 @@ static int stage2_pmdp_test_and_clear_yo
|
||||
* @guest_ipa: The IPA at which to insert the mapping
|
||||
* @pa: The physical address of the device
|
||||
* @size: The size of the mapping
|
||||
+ * @prot: S2 page translation bits
|
||||
*/
|
||||
int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa,
|
||||
- phys_addr_t pa, unsigned long size, bool writable)
|
||||
+ phys_addr_t pa, unsigned long size, bool writable,
|
||||
+ pgprot_t prot)
|
||||
{
|
||||
phys_addr_t addr, end;
|
||||
int ret = 0;
|
||||
@@ -1033,7 +1035,7 @@ int kvm_phys_addr_ioremap(struct kvm *kv
|
||||
pfn = __phys_to_pfn(pa);
|
||||
|
||||
for (addr = guest_ipa; addr < end; addr += PAGE_SIZE) {
|
||||
- pte_t pte = pfn_pte(pfn, PAGE_S2_DEVICE);
|
||||
+ pte_t pte = pfn_pte(pfn, prot);
|
||||
|
||||
if (writable)
|
||||
pte = kvm_s2pte_mkwrite(pte);
|
||||
@@ -1057,6 +1059,30 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_ARM64
|
||||
+static pgprot_t stage1_to_stage2_pgprot(pgprot_t prot)
|
||||
+{
|
||||
+ switch (pgprot_val(prot) & PTE_ATTRINDX_MASK) {
|
||||
+ case PTE_ATTRINDX(MT_DEVICE_nGnRE):
|
||||
+ case PTE_ATTRINDX(MT_DEVICE_nGnRnE):
|
||||
+ case PTE_ATTRINDX(MT_DEVICE_GRE):
|
||||
+ return PAGE_S2_DEVICE;
|
||||
+ case PTE_ATTRINDX(MT_NORMAL_NC):
|
||||
+ case PTE_ATTRINDX(MT_NORMAL):
|
||||
+ return (pgprot_val(prot) & PTE_SHARED)
|
||||
+ ? PAGE_S2
|
||||
+ : PAGE_S2_NS;
|
||||
+ }
|
||||
+
|
||||
+ return PAGE_S2_DEVICE;
|
||||
+}
|
||||
+#else
|
||||
+static pgprot_t stage1_to_stage2_pgprot(pgprot_t prot)
|
||||
+{
|
||||
+ return PAGE_S2_DEVICE;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
static bool transparent_hugepage_adjust(kvm_pfn_t *pfnp, phys_addr_t *ipap)
|
||||
{
|
||||
kvm_pfn_t pfn = *pfnp;
|
||||
@@ -1308,6 +1334,19 @@ static int user_mem_abort(struct kvm_vcp
|
||||
hugetlb = true;
|
||||
gfn = (fault_ipa & PMD_MASK) >> PAGE_SHIFT;
|
||||
} else {
|
||||
+ if (!is_vm_hugetlb_page(vma)) {
|
||||
+ pte_t *pte;
|
||||
+ spinlock_t *ptl;
|
||||
+ pgprot_t prot;
|
||||
+
|
||||
+ pte = get_locked_pte(current->mm, memslot->userspace_addr, &ptl);
|
||||
+ prot = stage1_to_stage2_pgprot(__pgprot(pte_val(*pte)));
|
||||
+ pte_unmap_unlock(pte, ptl);
|
||||
+#ifdef CONFIG_ARM64
|
||||
+ if (pgprot_val(prot) == pgprot_val(PAGE_S2_NS))
|
||||
+ mem_type = PAGE_S2_NS;
|
||||
+#endif
|
||||
+ }
|
||||
/*
|
||||
* Pages belonging to memslots that don't have the same
|
||||
* alignment for userspace and IPA cannot be mapped using
|
||||
@@ -1345,6 +1384,11 @@ static int user_mem_abort(struct kvm_vcp
|
||||
if (is_error_noslot_pfn(pfn))
|
||||
return -EFAULT;
|
||||
|
||||
+#ifdef CONFIG_ARM64
|
||||
+ if (pgprot_val(mem_type) == pgprot_val(PAGE_S2_NS)) {
|
||||
+ flags |= KVM_S2PTE_FLAG_IS_IOMAP;
|
||||
+ } else
|
||||
+#endif
|
||||
if (kvm_is_device_pfn(pfn)) {
|
||||
mem_type = PAGE_S2_DEVICE;
|
||||
flags |= KVM_S2PTE_FLAG_IS_IOMAP;
|
||||
@@ -1882,6 +1926,9 @@ int kvm_arch_prepare_memory_region(struc
|
||||
gpa_t gpa = mem->guest_phys_addr +
|
||||
(vm_start - mem->userspace_addr);
|
||||
phys_addr_t pa;
|
||||
+ pgprot_t prot;
|
||||
+ pte_t *pte;
|
||||
+ spinlock_t *ptl;
|
||||
|
||||
pa = (phys_addr_t)vma->vm_pgoff << PAGE_SHIFT;
|
||||
pa += vm_start - vma->vm_start;
|
||||
@@ -1891,10 +1938,13 @@ int kvm_arch_prepare_memory_region(struc
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
+ pte = get_locked_pte(current->mm, mem->userspace_addr, &ptl);
|
||||
+ prot = stage1_to_stage2_pgprot(__pgprot(pte_val(*pte)));
|
||||
+ pte_unmap_unlock(pte, ptl);
|
||||
|
||||
ret = kvm_phys_addr_ioremap(kvm, gpa, pa,
|
||||
vm_end - vm_start,
|
||||
- writable);
|
||||
+ writable, prot);
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
--- a/arch/arm64/include/asm/kvm_mmu.h
|
||||
+++ b/arch/arm64/include/asm/kvm_mmu.h
|
||||
@@ -167,7 +167,8 @@ void stage2_unmap_vm(struct kvm *kvm);
|
||||
int kvm_alloc_stage2_pgd(struct kvm *kvm);
|
||||
void kvm_free_stage2_pgd(struct kvm *kvm);
|
||||
int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa,
|
||||
- phys_addr_t pa, unsigned long size, bool writable);
|
||||
+ phys_addr_t pa, unsigned long size, bool writable,
|
||||
+ pgprot_t prot);
|
||||
|
||||
int kvm_handle_guest_abort(struct kvm_vcpu *vcpu, struct kvm_run *run);
|
||||
|
||||
@@ -274,8 +275,15 @@ static inline void __coherent_cache_gues
|
||||
|
||||
static inline void __kvm_flush_dcache_pte(pte_t pte)
|
||||
{
|
||||
- struct page *page = pte_page(pte);
|
||||
- kvm_flush_dcache_to_poc(page_address(page), PAGE_SIZE);
|
||||
+ if (pfn_valid(pte_pfn(pte))) {
|
||||
+ struct page *page = pte_page(pte);
|
||||
+ kvm_flush_dcache_to_poc(page_address(page), PAGE_SIZE);
|
||||
+ } else {
|
||||
+ void __iomem *va = ioremap_cache_ns(pte_pfn(pte) << PAGE_SHIFT, PAGE_SIZE);
|
||||
+
|
||||
+ kvm_flush_dcache_to_poc(va, PAGE_SIZE);
|
||||
+ iounmap(va);
|
||||
+ }
|
||||
}
|
||||
|
||||
static inline void __kvm_flush_dcache_pmd(pmd_t pmd)
|
||||
--- a/virt/kvm/arm/vgic/vgic-its.c
|
||||
+++ b/virt/kvm/arm/vgic/vgic-its.c
|
||||
@@ -176,6 +176,8 @@ static struct its_itte *find_itte(struct
|
||||
|
||||
#define GIC_LPI_OFFSET 8192
|
||||
|
||||
+#define VITS_TYPER_DEVBITS 17
|
||||
+
|
||||
/*
|
||||
* Finds and returns a collection in the ITS collection table.
|
||||
* Must be called with the its_lock mutex held.
|
||||
@@ -375,7 +377,7 @@ static unsigned long vgic_mmio_read_its_
|
||||
* To avoid memory waste in the guest, we keep the number of IDBits and
|
||||
* DevBits low - as least for the time being.
|
||||
*/
|
||||
- reg |= 0x0f << GITS_TYPER_DEVBITS_SHIFT;
|
||||
+ reg |= GIC_ENCODE_SZ(VITS_TYPER_DEVBITS, 5) << GITS_TYPER_DEVBITS_SHIFT;
|
||||
reg |= 0x0f << GITS_TYPER_IDBITS_SHIFT;
|
||||
|
||||
return extract_bytes(reg, addr & 7, len);
|
||||
@@ -601,16 +603,30 @@ static int vgic_its_cmd_handle_movi(stru
|
||||
* Check whether an ID can be stored into the corresponding guest table.
|
||||
* For a direct table this is pretty easy, but gets a bit nasty for
|
||||
* indirect tables. We check whether the resulting guest physical address
|
||||
- * is actually valid (covered by a memslot and guest accessbible).
|
||||
+ * is actually valid (covered by a memslot and guest accessible).
|
||||
* For this we have to read the respective first level entry.
|
||||
*/
|
||||
-static bool vgic_its_check_id(struct vgic_its *its, u64 baser, int id)
|
||||
+static bool vgic_its_check_id(struct vgic_its *its, u64 baser, u32 id)
|
||||
{
|
||||
int l1_tbl_size = GITS_BASER_NR_PAGES(baser) * SZ_64K;
|
||||
+ u64 indirect_ptr, type = GITS_BASER_TYPE(baser);
|
||||
int index;
|
||||
- u64 indirect_ptr;
|
||||
gfn_t gfn;
|
||||
|
||||
+ switch (type) {
|
||||
+ case GITS_BASER_TYPE_DEVICE:
|
||||
+ if (id >= BIT_ULL(VITS_TYPER_DEVBITS))
|
||||
+ return false;
|
||||
+ break;
|
||||
+ case GITS_BASER_TYPE_COLLECTION:
|
||||
+ /* as GITS_TYPER.CIL == 0, ITS supports 16-bit collection ID */
|
||||
+ if (id >= BIT_ULL(16))
|
||||
+ return false;
|
||||
+ break;
|
||||
+ default:
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
if (!(baser & GITS_BASER_INDIRECT)) {
|
||||
phys_addr_t addr;
|
||||
|
||||
--- a/virt/kvm/arm/vgic/vgic-v2.c
|
||||
+++ b/virt/kvm/arm/vgic/vgic-v2.c
|
||||
@@ -290,7 +290,8 @@ int vgic_v2_map_resources(struct kvm *kv
|
||||
if (!static_branch_unlikely(&vgic_v2_cpuif_trap)) {
|
||||
ret = kvm_phys_addr_ioremap(kvm, dist->vgic_cpu_base,
|
||||
kvm_vgic_global_state.vcpu_base,
|
||||
- KVM_VGIC_V2_CPU_SIZE, true);
|
||||
+ KVM_VGIC_V2_CPU_SIZE, true,
|
||||
+ PAGE_S2_DEVICE);
|
||||
if (ret) {
|
||||
kvm_err("Unable to remap VGIC CPU to VCPU\n");
|
||||
goto out;
|
@ -1,10 +0,0 @@
|
||||
--- a/drivers/mmc/host/sdhci-of-esdhc.c
|
||||
+++ b/drivers/mmc/host/sdhci-of-esdhc.c
|
||||
@@ -619,6 +619,7 @@ static void esdhc_reset(struct sdhci_hos
|
||||
static const struct of_device_id scfg_device_ids[] = {
|
||||
{ .compatible = "fsl,t1040-scfg", },
|
||||
{ .compatible = "fsl,ls1012a-scfg", },
|
||||
+ { .compatible = "fsl,ls1043a-scfg", },
|
||||
{ .compatible = "fsl,ls1046a-scfg", },
|
||||
{}
|
||||
};
|
@ -1,62 +0,0 @@
|
||||
From f27ef8941ca29b2d10428754be51e8ee06bb1263 Mon Sep 17 00:00:00 2001
|
||||
From: Mathew McBride <matt@traverse.com.au>
|
||||
Date: Mon, 7 Aug 2017 10:19:48 +1000
|
||||
Subject: [PATCH] Recognize when an RGMII Link is set as fixed (in the device
|
||||
tree) and set up the MAC accordingly
|
||||
|
||||
---
|
||||
drivers/net/ethernet/freescale/sdk_dpaa/mac.c | 1
|
||||
drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac.c | 13 ++++++++++
|
||||
2 files changed, 14 insertions(+)
|
||||
|
||||
--- a/drivers/net/ethernet/freescale/sdk_dpaa/mac.c
|
||||
+++ b/drivers/net/ethernet/freescale/sdk_dpaa/mac.c
|
||||
@@ -386,6 +386,7 @@ static int __cold mac_probe(struct platf
|
||||
mac_dev->fixed_link->duplex = phy->duplex;
|
||||
mac_dev->fixed_link->pause = phy->pause;
|
||||
mac_dev->fixed_link->asym_pause = phy->asym_pause;
|
||||
+ printk(KERN_INFO "Setting up fixed link, speed %d duplex %d\n", mac_dev->fixed_link->speed, mac_dev->fixed_link->duplex);
|
||||
}
|
||||
|
||||
_errno = mac_dev->init(mac_dev);
|
||||
--- a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac.c
|
||||
+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac.c
|
||||
@@ -36,6 +36,8 @@
|
||||
|
||||
@Description FM mEMAC driver
|
||||
*//***************************************************************************/
|
||||
+#include <../../../../sdk_dpaa/mac.h>
|
||||
+#include <linux/phy_fixed.h>
|
||||
|
||||
#include "std_ext.h"
|
||||
#include "string_ext.h"
|
||||
@@ -48,6 +50,8 @@
|
||||
#include "memac.h"
|
||||
|
||||
|
||||
+static t_Error MemacAdjustLink(t_Handle h_Memac, e_EnetSpeed speed, bool fullDuplex);
|
||||
+
|
||||
/*****************************************************************************/
|
||||
/* Internal routines */
|
||||
/*****************************************************************************/
|
||||
@@ -276,11 +280,20 @@ static t_Error MemacEnable(t_Handle h_Me
|
||||
{
|
||||
t_Memac *p_Memac = (t_Memac *)h_Memac;
|
||||
|
||||
+ struct mac_device *mac_dev = (struct mac_device *)p_Memac->h_App;
|
||||
+
|
||||
SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
|
||||
SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
|
||||
|
||||
fman_memac_enable(p_Memac->p_MemMap, (mode & e_COMM_MODE_RX), (mode & e_COMM_MODE_TX));
|
||||
|
||||
+ if (ENET_INTERFACE_FROM_MODE(p_Memac->enetMode) == e_ENET_IF_RGMII) {
|
||||
+ if (mac_dev->fixed_link) {
|
||||
+ printk(KERN_INFO "This is a fixed-link, forcing speed %d duplex %d\n",mac_dev->fixed_link->speed,mac_dev->fixed_link->duplex);
|
||||
+ MemacAdjustLink(h_Memac,mac_dev->fixed_link->speed,mac_dev->fixed_link->duplex);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
return E_OK;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user