diff options
Diffstat (limited to 'arch/arm')
246 files changed, 6012 insertions, 1663 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 166efa2a19c..a53245a9ef5 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -7,7 +7,7 @@ config ARM select HAVE_MEMBLOCK select RTC_LIB select SYS_SUPPORTS_APM_EMULATION - select GENERIC_ATOMIC64 if (!CPU_32v6K || !AEABI) + select GENERIC_ATOMIC64 if (CPU_V6 || !CPU_32v6K || !AEABI) select HAVE_OPROFILE if (HAVE_PERF_EVENTS) select HAVE_ARCH_KGDB select HAVE_KPROBES if (!XIP_KERNEL && !THUMB2_KERNEL) @@ -24,7 +24,7 @@ config ARM select HAVE_PERF_EVENTS select PERF_USE_VMALLOC select HAVE_REGS_AND_STACK_ACCESS_API - select HAVE_HW_BREAKPOINT if (PERF_EVENTS && (CPU_V6 || CPU_V7)) + select HAVE_HW_BREAKPOINT if (PERF_EVENTS && (CPU_V6 || CPU_V6K || CPU_V7)) select HAVE_C_RECORDMCOUNT select HAVE_GENERIC_HARDIRQS select HAVE_SPARSE_IRQ @@ -178,11 +178,6 @@ config FIQ config ARCH_MTD_XIP bool -config ARM_L1_CACHE_SHIFT_6 - bool - help - Setting ARM L1 cache line size to 64 Bytes. - config VECTORS_BASE hex default 0xffff0000 if MMU || CPU_HIGH_VECTOR @@ -191,6 +186,22 @@ config VECTORS_BASE help The base address of exception vectors. +config ARM_PATCH_PHYS_VIRT + bool "Patch physical to virtual translations at runtime (EXPERIMENTAL)" + depends on EXPERIMENTAL + depends on !XIP_KERNEL && MMU + depends on !ARCH_REALVIEW || !SPARSEMEM + help + Patch phys-to-virt translation functions at runtime according to + the position of the kernel in system memory. + + This can only be used with non-XIP with MMU kernels where + the base of physical memory is at a 16MB boundary. + +config ARM_PATCH_PHYS_VIRT_16BIT + def_bool y + depends on ARM_PATCH_PHYS_VIRT && ARCH_MSM + source "init/Kconfig" source "kernel/Kconfig.freezer" @@ -457,6 +468,7 @@ config ARCH_IXP4XX config ARCH_DOVE bool "Marvell Dove" + select CPU_V6K select PCI select ARCH_REQUIRE_GPIOLIB select GENERIC_CLOCKEVENTS @@ -1048,7 +1060,7 @@ config XSCALE_PMU default y config CPU_HAS_PMU - depends on (CPU_V6 || CPU_V7 || XSCALE_PMU) && \ + depends on (CPU_V6 || CPU_V6K || CPU_V7 || XSCALE_PMU) && \ (!ARCH_OMAP3 || OMAP3_EMU) default y bool @@ -1064,7 +1076,7 @@ endif config ARM_ERRATA_411920 bool "ARM errata: Invalidation of the Instruction Cache operation can fail" - depends on CPU_V6 + depends on CPU_V6 || CPU_V6K help Invalidation of the Instruction Cache operation can fail. This erratum is present in 1136 (before r1p4), 1156 and 1176. @@ -1275,6 +1287,7 @@ source "kernel/time/Kconfig" config SMP bool "Symmetric Multi-Processing (EXPERIMENTAL)" depends on EXPERIMENTAL + depends on CPU_V6K || CPU_V7 depends on GENERIC_CLOCKEVENTS depends on REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP || \ MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || \ @@ -1386,7 +1399,7 @@ config HZ config THUMB2_KERNEL bool "Compile the kernel in Thumb-2 mode (EXPERIMENTAL)" - depends on CPU_V7 && !CPU_V6 && EXPERIMENTAL + depends on CPU_V7 && !CPU_V6 && !CPU_V6K && EXPERIMENTAL select AEABI select ARM_ASM_UNIFIED help @@ -1396,6 +1409,37 @@ config THUMB2_KERNEL If unsure, say N. +config THUMB2_AVOID_R_ARM_THM_JUMP11 + bool "Work around buggy Thumb-2 short branch relocations in gas" + depends on THUMB2_KERNEL && MODULES + default y + help + Various binutils versions can resolve Thumb-2 branches to + locally-defined, preemptible global symbols as short-range "b.n" + branch instructions. + + This is a problem, because there's no guarantee the final + destination of the symbol, or any candidate locations for a + trampoline, are within range of the branch. For this reason, the + kernel does not support fixing up the R_ARM_THM_JUMP11 (102) + relocation in modules at all, and it makes little sense to add + support. + + The symptom is that the kernel fails with an "unsupported + relocation" error when loading some modules. + + Until fixed tools are available, passing + -fno-optimize-sibling-calls to gcc should prevent gcc generating + code which hits this problem, at the cost of a bit of extra runtime + stack usage in some cases. + + The problem is described in more detail at: + https://bugs.launchpad.net/binutils-linaro/+bug/725126 + + Only Thumb-2 kernels are affected. + + Unless you are sure your tools don't have this problem, say Y. + config ARM_ASM_UNIFIED bool @@ -1611,6 +1655,13 @@ endmenu menu "Boot options" +config USE_OF + bool "Flattened Device Tree support" + select OF + select OF_EARLY_FLATTREE + help + Include support for flattened device tree machine descriptions. + # Compressed boot loader in ROM. Yes, we really want to ask about # TEXT and BSS so we preserve their values in the config files. config ZBOOT_ROM_TEXT @@ -1877,7 +1928,7 @@ config FPE_FASTFPE config VFP bool "VFP-format floating point maths" - depends on CPU_V6 || CPU_ARM926T || CPU_V7 || CPU_FEROCEON + depends on CPU_V6 || CPU_V6K || CPU_ARM926T || CPU_V7 || CPU_FEROCEON help Say Y to include VFP support code in the kernel. This is needed if your hardware includes a VFP unit. diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 6f7b29294c8..b1031504fad 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -89,6 +89,7 @@ tune-$(CONFIG_CPU_XSCALE) :=$(call cc-option,-mtune=xscale,-mtune=strongarm110) tune-$(CONFIG_CPU_XSC3) :=$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale tune-$(CONFIG_CPU_FEROCEON) :=$(call cc-option,-mtune=marvell-f,-mtune=xscale) tune-$(CONFIG_CPU_V6) :=$(call cc-option,-mtune=arm1136j-s,-mtune=strongarm) +tune-$(CONFIG_CPU_V6K) :=$(call cc-option,-mtune=arm1136j-s,-mtune=strongarm) ifeq ($(CONFIG_AEABI),y) CFLAGS_ABI :=-mabi=aapcs-linux -mno-thumb-interwork @@ -105,6 +106,10 @@ AFLAGS_AUTOIT :=$(call as-option,-Wa$(comma)-mimplicit-it=always,-Wa$(comma)-mau AFLAGS_NOWARN :=$(call as-option,-Wa$(comma)-mno-warn-deprecated,-Wa$(comma)-W) CFLAGS_THUMB2 :=-mthumb $(AFLAGS_AUTOIT) $(AFLAGS_NOWARN) AFLAGS_THUMB2 :=$(CFLAGS_THUMB2) -Wa$(comma)-mthumb +# Work around buggy relocation from gas if requested: +ifeq ($(CONFIG_THUMB2_AVOID_R_ARM_THM_JUMP11),y) +CFLAGS_MODULE +=-fno-optimize-sibling-calls +endif endif # Need -Uarm for gcc < 3.x @@ -280,7 +285,7 @@ bzImage: zImage zImage Image xipImage bootpImage uImage: vmlinux $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@ -zinstall install: vmlinux +zinstall uinstall install: vmlinux $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $@ # We use MRPROPER_FILES and CLEAN_FILES now @@ -301,6 +306,7 @@ define archhelp echo ' (supply initrd image via make variable INITRD=<path>)' echo ' install - Install uncompressed kernel' echo ' zinstall - Install compressed kernel' + echo ' uinstall - Install U-Boot wrapped compressed kernel' echo ' Install using (your) ~/bin/$(INSTALLKERNEL) or' echo ' (distribution) /sbin/$(INSTALLKERNEL) or' echo ' install to $$(INSTALL_PATH) and run lilo' diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile index 4d26f2c52a7..9128fddf110 100644 --- a/arch/arm/boot/Makefile +++ b/arch/arm/boot/Makefile @@ -99,6 +99,10 @@ zinstall: $(obj)/zImage $(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \ $(obj)/zImage System.map "$(INSTALL_PATH)" +uinstall: $(obj)/uImage + $(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \ + $(obj)/uImage System.map "$(INSTALL_PATH)" + zi: $(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \ $(obj)/zImage System.map "$(INSTALL_PATH)" diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile index 0a8f748e506..9d328be6e5e 100644 --- a/arch/arm/boot/compressed/Makefile +++ b/arch/arm/boot/compressed/Makefile @@ -83,9 +83,11 @@ endif EXTRA_CFLAGS := -fpic -fno-builtin EXTRA_AFLAGS := -Wa,-march=all +# Provide size of uncompressed kernel to the decompressor via a linker symbol. +LDFLAGS_vmlinux := --defsym _image_size=$(shell stat -c "%s" $(obj)/../Image) # Supply ZRELADDR to the decompressor via a linker symbol. ifneq ($(CONFIG_AUTO_ZRELADDR),y) -LDFLAGS_vmlinux := --defsym zreladdr=$(ZRELADDR) +LDFLAGS_vmlinux += --defsym zreladdr=$(ZRELADDR) endif ifeq ($(CONFIG_CPU_ENDIAN_BE8),y) LDFLAGS_vmlinux += --be8 diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index 7193884ed8b..84ac4d65631 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S @@ -21,7 +21,7 @@ #if defined(CONFIG_DEBUG_ICEDCC) -#ifdef CONFIG_CPU_V6 +#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K) .macro loadsp, rb, tmp .endm .macro writeb, ch, rb @@ -128,14 +128,14 @@ wait: mrc p14, 0, pc, c0, c1, 0 .arm @ Always enter in ARM state start: .type start,#function - THUMB( adr r12, BSYM(1f) ) - THUMB( bx r12 ) - THUMB( .rept 6 ) - ARM( .rept 8 ) + .rept 7 mov r0, r0 .endr + ARM( mov r0, r0 ) + ARM( b 1f ) + THUMB( adr r12, BSYM(1f) ) + THUMB( bx r12 ) - b 1f .word 0x016f2818 @ Magic numbers to help the loader .word start @ absolute load/run zImage address .word _edata @ zImage end address @@ -174,9 +174,7 @@ not_angel: */ .text - adr r0, LC0 - ldmia r0, {r1, r2, r3, r5, r6, r11, ip} - ldr sp, [r0, #28] + #ifdef CONFIG_AUTO_ZRELADDR @ determine final kernel image address mov r4, pc @@ -185,35 +183,108 @@ not_angel: #else ldr r4, =zreladdr #endif - subs r0, r0, r1 @ calculate the delta offset - @ if delta is zero, we are - beq not_relocated @ running at the address we - @ were linked at. + bl cache_on + +restart: adr r0, LC0 + ldmia r0, {r1, r2, r3, r5, r6, r9, r11, r12} + ldr sp, [r0, #32] + + /* + * We might be running at a different address. We need + * to fix up various pointers. + */ + sub r0, r0, r1 @ calculate the delta offset + add r5, r5, r0 @ _start + add r6, r6, r0 @ _edata +#ifndef CONFIG_ZBOOT_ROM + /* malloc space is above the relocated stack (64k max) */ + add sp, sp, r0 + add r10, sp, #0x10000 +#else /* - * We're running at a different address. We need to fix - * up various pointers: - * r5 - zImage base address (_start) - * r6 - size of decompressed image - * r11 - GOT start - * ip - GOT end + * With ZBOOT_ROM the bss/stack is non relocatable, + * but someone could still run this code from RAM, + * in which case our reference is _edata. */ - add r5, r5, r0 + mov r10, r6 +#endif + +/* + * Check to see if we will overwrite ourselves. + * r4 = final kernel address + * r5 = start of this image + * r9 = size of decompressed image + * r10 = end of this image, including bss/stack/malloc space if non XIP + * We basically want: + * r4 >= r10 -> OK + * r4 + image length <= r5 -> OK + */ + cmp r4, r10 + bhs wont_overwrite + add r10, r4, r9 + cmp r10, r5 + bls wont_overwrite + +/* + * Relocate ourselves past the end of the decompressed kernel. + * r5 = start of this image + * r6 = _edata + * r10 = end of the decompressed kernel + * Because we always copy ahead, we need to do it from the end and go + * backward in case the source and destination overlap. + */ + /* Round up to next 256-byte boundary. */ + add r10, r10, #256 + bic r10, r10, #255 + + sub r9, r6, r5 @ size to copy + add r9, r9, #31 @ rounded up to a multiple + bic r9, r9, #31 @ ... of 32 bytes + add r6, r9, r5 + add r9, r9, r10 + +1: ldmdb r6!, {r0 - r3, r10 - r12, lr} + cmp r6, r5 + stmdb r9!, {r0 - r3, r10 - r12, lr} + bhi 1b + + /* Preserve offset to relocated code. */ + sub r6, r9, r6 + + bl cache_clean_flush + + adr r0, BSYM(restart) + add r0, r0, r6 + mov pc, r0 + +wont_overwrite: +/* + * If delta is zero, we are running at the address we were linked at. + * r0 = delta + * r2 = BSS start + * r3 = BSS end + * r4 = kernel execution address + * r7 = architecture ID + * r8 = atags pointer + * r11 = GOT start + * r12 = GOT end + * sp = stack pointer + */ + teq r0, #0 + beq not_relocated add r11, r11, r0 - add ip, ip, r0 + add r12, r12, r0 #ifndef CONFIG_ZBOOT_ROM /* * If we're running fully PIC === CONFIG_ZBOOT_ROM = n, * we need to fix up pointers into the BSS region. - * r2 - BSS start - * r3 - BSS end - * sp - stack pointer + * Note that the stack pointer has already been fixed up. */ add r2, r2, r0 add r3, r3, r0 - add sp, sp, r0 /* * Relocate all entries in the GOT table. @@ -221,7 +292,7 @@ not_angel: 1: ldr r1, [r11, #0] @ relocate entries in the GOT add r1, r1, r0 @ table. This fixes up the str r1, [r11], #4 @ C references. - cmp r11, ip + cmp r11, r12 blo 1b #else @@ -234,7 +305,7 @@ not_angel: cmphs r3, r1 @ _end < entry addlo r1, r1, r0 @ table. This fixes up the str r1, [r11], #4 @ C references. - cmp r11, ip + cmp r11, r12 blo 1b #endif @@ -246,76 +317,24 @@ not_relocated: mov r0, #0 cmp r2, r3 blo 1b - /* - * The C runtime environment should now be setup - * sufficiently. Turn the cache on, set up some - * pointers, and start decompressing. - */ - bl cache_on - - mov r1, sp @ malloc space above stack - add r2, sp, #0x10000 @ 64k max - /* - * Check to see if we will overwrite ourselves. - * r4 = final kernel address - * r5 = start of this image - * r6 = size of decompressed image - * r2 = end of malloc space (and therefore this image) - * We basically want: - * r4 >= r2 -> OK - * r4 + image length <= r5 -> OK + * The C runtime environment should now be setup sufficiently. + * Set up some pointers, and start decompressing. + * r4 = kernel execution address + * r7 = architecture ID + * r8 = atags pointer */ - cmp r4, r2 - bhs wont_overwrite - add r0, r4, r6 - cmp r0, r5 - bls wont_overwrite - - mov r5, r2 @ decompress after malloc space - mov r0, r5 + mov r0, r4 + mov r1, sp @ malloc space above stack + add r2, sp, #0x10000 @ 64k max mov r3, r7 bl decompress_kernel - - add r0, r0, #127 + 128 @ alignment + stack - bic r0, r0, #127 @ align the kernel length -/* - * r0 = decompressed kernel length - * r1-r3 = unused - * r4 = kernel execution address - * r5 = decompressed kernel start - * r7 = architecture ID - * r8 = atags pointer - * r9-r12,r14 = corrupted - */ - add r1, r5, r0 @ end of decompressed kernel - adr r2, reloc_start - ldr r3, LC1 - add r3, r2, r3 -1: ldmia r2!, {r9 - r12, r14} @ copy relocation code - stmia r1!, {r9 - r12, r14} - ldmia r2!, {r9 - r12, r14} - stmia r1!, {r9 - r12, r14} - cmp r2, r3 - blo 1b - mov sp, r1 - add sp, sp, #128 @ relocate the stack - bl cache_clean_flush - ARM( add pc, r5, r0 ) @ call relocation code - THUMB( add r12, r5, r0 ) - THUMB( mov pc, r12 ) @ call relocation code - -/* - * We're not in danger of overwriting ourselves. Do this the simple way. - * - * r4 = kernel execution address - * r7 = architecture ID - */ -wont_overwrite: mov r0, r4 - mov r3, r7 - bl decompress_kernel - b call_kernel + bl cache_off + mov r0, #0 @ must be zero + mov r1, r7 @ restore architecture number + mov r2, r8 @ restore atags pointer + mov pc, r4 @ call kernel .align 2 .type LC0, #object @@ -323,11 +342,11 @@ LC0: .word LC0 @ r1 .word __bss_start @ r2 .word _end @ r3 .word _start @ r5 - .word _image_size @ r6 + .word _edata @ r6 + .word _image_size @ r9 .word _got_start @ r11 .word _got_end @ ip .word user_stack_end @ sp -LC1: .word reloc_end - reloc_start .size LC0, . - LC0 #ifdef CONFIG_ARCH_RPC @@ -353,7 +372,7 @@ params: ldr r0, =0x10000100 @ params_phys for RPC * On exit, * r0, r1, r2, r3, r9, r10, r12 corrupted * This routine must preserve: - * r4, r5, r6, r7, r8 + * r4, r7, r8 */ .align 5 cache_on: mov r3, #8 @ cache_on function @@ -551,43 +570,6 @@ __common_mmu_cache_on: #endif /* - * All code following this line is relocatable. It is relocated by - * the above code to the end of the decompressed kernel image and - * executed there. During this time, we have no stacks. - * - * r0 = decompressed kernel length - * r1-r3 = unused - * r4 = kernel execution address - * r5 = decompressed kernel start - * r7 = architecture ID - * r8 = atags pointer - * r9-r12,r14 = corrupted - */ - .align 5 -reloc_start: add r9, r5, r0 - sub r9, r9, #128 @ do not copy the stack - debug_reloc_start - mov r1, r4 -1: - .rept 4 - ldmia r5!, {r0, r2, r3, r10 - r12, r14} @ relocate kernel - stmia r1!, {r0, r2, r3, r10 - r12, r14} - .endr - - cmp r5, r9 - blo 1b - mov sp, r1 - add sp, sp, #128 @ relocate the stack - debug_reloc_end - -call_kernel: bl cache_clean_flush - bl cache_off - mov r0, #0 @ must be zero - mov r1, r7 @ restore architecture number - mov r2, r8 @ restore atags pointer - mov pc, r4 @ call kernel - -/* * Here follow the relocatable cache support functions for the * various processors. This is a generic hook for locating an * entry and jumping to an instruction at the specified offset @@ -791,7 +773,7 @@ proc_types: * On exit, * r0, r1, r2, r3, r9, r12 corrupted * This routine must preserve: - * r4, r6, r7 + * r4, r7, r8 */ .align 5 cache_off: mov r3, #12 @ cache_off function @@ -866,7 +848,7 @@ __armv3_mmu_cache_off: * On exit, * r1, r2, r3, r9, r10, r11, r12 corrupted * This routine must preserve: - * r0, r4, r5, r6, r7 + * r4, r6, r7, r8 */ .align 5 cache_clean_flush: @@ -1088,7 +1070,6 @@ memdump: mov r12, r0 #endif .ltorg -reloc_end: .align .section ".stack", "aw", %nobits diff --git a/arch/arm/boot/compressed/misc.c b/arch/arm/boot/compressed/misc.c index e653a6d3c8d..4657e877bf8 100644 --- a/arch/arm/boot/compressed/misc.c +++ b/arch/arm/boot/compressed/misc.c @@ -36,7 +36,7 @@ extern void error(char *x); #ifdef CONFIG_DEBUG_ICEDCC -#ifdef CONFIG_CPU_V6 +#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K) static void icedcc_putc(int ch) { diff --git a/arch/arm/boot/compressed/vmlinux.lds.in b/arch/arm/boot/compressed/vmlinux.lds.in index 366a924019a..5309909d728 100644 --- a/arch/arm/boot/compressed/vmlinux.lds.in +++ b/arch/arm/boot/compressed/vmlinux.lds.in @@ -43,9 +43,6 @@ SECTIONS _etext = .; - /* Assume size of decompressed image is 4x the compressed image */ - _image_size = (_etext - _text) * 4; - _got_start = .; .got : { *(.got) } _got_end = .; diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig index 778655f0257..ea5ee4d067f 100644 --- a/arch/arm/common/Kconfig +++ b/arch/arm/common/Kconfig @@ -6,6 +6,8 @@ config ARM_VIC config ARM_VIC_NR int + default 4 if ARCH_S5PV210 + default 3 if ARCH_S5P6442 || ARCH_S5PC100 default 2 depends on ARM_VIC help diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c index 22437721115..e21c1f4218d 100644 --- a/arch/arm/common/gic.c +++ b/arch/arm/common/gic.c @@ -142,25 +142,24 @@ static int gic_set_type(struct irq_data *d, unsigned int type) } #ifdef CONFIG_SMP -static int -gic_set_cpu(struct irq_data *d, const struct cpumask *mask_val, bool force) +static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val, + bool force) { void __iomem *reg = gic_dist_base(d) + GIC_DIST_TARGET + (gic_irq(d) & ~3); unsigned int shift = (d->irq % 4) * 8; unsigned int cpu = cpumask_first(mask_val); - u32 val; - struct irq_desc *desc; + u32 val, mask, bit; - spin_lock(&irq_controller_lock); - desc = irq_to_desc(d->irq); - if (desc == NULL) { - spin_unlock(&irq_controller_lock); + if (cpu >= 8) return -EINVAL; - } + + mask = 0xff << shift; + bit = 1 << (cpu + shift); + + spin_lock(&irq_controller_lock); d->node = cpu; - val = readl(reg) & ~(0xff << shift); - val |= 1 << (cpu + shift); - writel(val, reg); + val = readl(reg) & ~mask; + writel(val | bit, reg); spin_unlock(&irq_controller_lock); return 0; @@ -203,7 +202,7 @@ static struct irq_chip gic_chip = { .irq_unmask = gic_unmask_irq, .irq_set_type = gic_set_type, #ifdef CONFIG_SMP - .irq_set_affinity = gic_set_cpu, + .irq_set_affinity = gic_set_affinity, #endif }; diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig index ae890caa17a..ccfd51cd2bc 100644 --- a/arch/arm/configs/omap2plus_defconfig +++ b/arch/arm/configs/omap2plus_defconfig @@ -58,6 +58,7 @@ CONFIG_ARM_ERRATA_411920=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_SMP=y +CONFIG_NR_CPUS=2 # CONFIG_LOCAL_TIMERS is not set CONFIG_AEABI=y CONFIG_LEDS=y @@ -291,3 +292,7 @@ CONFIG_CRC_T10DIF=y CONFIG_CRC_ITU_T=y CONFIG_CRC7=y CONFIG_LIBCRC32C=y +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_OMAP_SMARTREFLEX=y +CONFIG_OMAP_SMARTREFLEX_CLASS3=y diff --git a/arch/arm/configs/u8500_defconfig b/arch/arm/configs/u8500_defconfig index 52d86c4485b..a5cce242a77 100644 --- a/arch/arm/configs/u8500_defconfig +++ b/arch/arm/configs/u8500_defconfig @@ -1,7 +1,6 @@ CONFIG_EXPERIMENTAL=y # CONFIG_SWAP is not set CONFIG_SYSVIPC=y -CONFIG_SYSFS_DEPRECATED_V2=y CONFIG_BLK_DEV_INITRD=y CONFIG_KALLSYMS_ALL=y CONFIG_MODULES=y @@ -13,43 +12,89 @@ CONFIG_UX500_SOC_DB5500=y CONFIG_UX500_SOC_DB8500=y CONFIG_MACH_U8500=y CONFIG_MACH_U5500=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y CONFIG_SMP=y CONFIG_NR_CPUS=2 +CONFIG_HOTPLUG_CPU=y CONFIG_PREEMPT=y CONFIG_AEABI=y CONFIG_CMDLINE="root=/dev/ram0 console=ttyAMA2,115200n8" +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y CONFIG_VFP=y CONFIG_NEON=y +CONFIG_NET=y +CONFIG_PHONET=y +CONFIG_PHONET_PIPECTRLR=y +# CONFIG_WIRELESS is not set +CONFIG_CAIF=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=65536 -# CONFIG_MISC_DEVICES is not set +CONFIG_MISC_DEVICES=y +CONFIG_AB8500_PWM=y +CONFIG_SENSORS_BH1780=y # CONFIG_INPUT_MOUSEDEV_PSAUX is not set CONFIG_INPUT_EVDEV=y -# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_KEYBOARD_ATKBD is not set +CONFIG_KEYBOARD_GPIO=y +CONFIG_KEYBOARD_NOMADIK=y +CONFIG_KEYBOARD_STMPE=y +CONFIG_KEYBOARD_TC3589X=y # CONFIG_INPUT_MOUSE is not set +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_BU21013=y +CONFIG_INPUT_MISC=y +CONFIG_INPUT_AB8500_PONKEY=y # CONFIG_SERIO is not set CONFIG_VT_HW_CONSOLE_BINDING=y CONFIG_SERIAL_AMBA_PL011=y CONFIG_SERIAL_AMBA_PL011_CONSOLE=y # CONFIG_LEGACY_PTYS is not set -# CONFIG_HW_RANDOM is not set +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_NOMADIK=y +CONFIG_I2C=y +CONFIG_I2C_NOMADIK=y CONFIG_SPI=y CONFIG_SPI_PL022=y +CONFIG_GPIO_STMPE=y +CONFIG_GPIO_TC3589X=y # CONFIG_HWMON is not set -# CONFIG_VGA_CONSOLE is not set +CONFIG_MFD_STMPE=y +CONFIG_MFD_TC3589X=y +CONFIG_AB8500_CORE=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_AB8500=y # CONFIG_HID_SUPPORT is not set # CONFIG_USB_SUPPORT is not set +CONFIG_MMC=y +CONFIG_MMC_ARMMMCI=y +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_LP5521=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_AB8500=y +CONFIG_RTC_DRV_PL031=y +CONFIG_DMADEVICES=y +CONFIG_STE_DMA40=y +CONFIG_STAGING=y +# CONFIG_STAGING_EXCLUDE_BUILD is not set +CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4=y CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_POSIX_ACL=y CONFIG_EXT2_FS_SECURITY=y -CONFIG_INOTIFY=y +CONFIG_EXT3_FS=y +CONFIG_VFAT_FS=y CONFIG_TMPFS=y CONFIG_TMPFS_POSIX_ACL=y CONFIG_CONFIGFS_FS=m # CONFIG_MISC_FILESYSTEMS is not set +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_ISO8859_1=y CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_FS=y CONFIG_DEBUG_KERNEL=y # CONFIG_SCHED_DEBUG is not set # CONFIG_DEBUG_PREEMPT is not set @@ -58,5 +103,3 @@ CONFIG_DEBUG_INFO=y # CONFIG_FTRACE is not set CONFIG_DEBUG_USER=y CONFIG_DEBUG_ERRORS=y -CONFIG_CRC_T10DIF=m -# CONFIG_CRC32 is not set diff --git a/arch/arm/configs/vexpress_defconfig b/arch/arm/configs/vexpress_defconfig new file mode 100644 index 00000000000..f2de51f0bd1 --- /dev/null +++ b/arch/arm/configs/vexpress_defconfig @@ -0,0 +1,140 @@ +CONFIG_EXPERIMENTAL=y +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_SYSVIPC=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_CGROUPS=y +CONFIG_CPUSETS=y +# CONFIG_UTS_NS is not set +# CONFIG_IPC_NS is not set +# CONFIG_USER_NS is not set +# CONFIG_PID_NS is not set +# CONFIG_NET_NS is not set +CONFIG_BLK_DEV_INITRD=y +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_PROFILING=y +CONFIG_OPROFILE=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_LBDAF is not set +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_IOSCHED_DEADLINE is not set +# CONFIG_IOSCHED_CFQ is not set +CONFIG_ARCH_VEXPRESS=y +CONFIG_ARCH_VEXPRESS_CA9X4=y +# CONFIG_SWP_EMULATE is not set +CONFIG_SMP=y +CONFIG_VMSPLIT_2G=y +CONFIG_HOTPLUG_CPU=y +CONFIG_AEABI=y +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="root=/dev/nfs nfsroot=10.1.69.3:/work/nfsroot ip=dhcp console=ttyAMA0 mem=128M" +CONFIG_VFP=y +CONFIG_NEON=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_INET_LRO is not set +# CONFIG_IPV6 is not set +# CONFIG_WIRELESS is not set +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_MTD=y +CONFIG_MTD_CONCAT=y +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +CONFIG_MTD_CFI=y +CONFIG_MTD_CFI_INTELEXT=y +CONFIG_MTD_CFI_AMDSTD=y +CONFIG_MTD_ARM_INTEGRATOR=y +CONFIG_MISC_DEVICES=y +# CONFIG_SCSI_PROC_FS is not set +CONFIG_BLK_DEV_SD=y +# CONFIG_SCSI_LOWLEVEL is not set +CONFIG_ATA=y +# CONFIG_SATA_PMP is not set +CONFIG_NETDEVICES=y +CONFIG_NET_ETHERNET=y +CONFIG_SMSC911X=y +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set +# CONFIG_WLAN is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_SERIO_SERPORT is not set +CONFIG_SERIO_AMBAKMI=y +CONFIG_SERIAL_AMBA_PL011=y +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y +CONFIG_LEGACY_PTY_COUNT=16 +# CONFIG_HW_RANDOM is not set +# CONFIG_HWMON is not set +CONFIG_FB=y +CONFIG_FB_ARMCLCD=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_SOUND=y +CONFIG_SND=y +CONFIG_SND_MIXER_OSS=y +CONFIG_SND_PCM_OSS=y +# CONFIG_SND_DRIVERS is not set +CONFIG_SND_ARMAACI=y +CONFIG_HID_DRAGONRISE=y +CONFIG_HID_GYRATION=y +CONFIG_HID_TWINHAN=y +CONFIG_HID_NTRIG=y +CONFIG_HID_PANTHERLORD=y +CONFIG_HID_PETALYNX=y +CONFIG_HID_SAMSUNG=y +CONFIG_HID_SONY=y +CONFIG_HID_SUNPLUS=y +CONFIG_HID_GREENASIA=y +CONFIG_HID_SMARTJOYPLUS=y +CONFIG_HID_TOPSEED=y +CONFIG_HID_THRUSTMASTER=y +CONFIG_HID_ZEROPLUS=y +CONFIG_USB=y +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y +# CONFIG_USB_DEVICE_CLASS is not set +CONFIG_USB_MON=y +CONFIG_USB_ISP1760_HCD=y +CONFIG_USB_STORAGE=y +CONFIG_MMC=y +CONFIG_MMC_ARMMMCI=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_PL031=y +CONFIG_EXT2_FS=y +CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set +# CONFIG_EXT3_FS_XATTR is not set +CONFIG_VFAT_FS=y +CONFIG_TMPFS=y +CONFIG_JFFS2_FS=y +CONFIG_CRAMFS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +CONFIG_ROOT_NFS=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_ISO8859_1=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_FS=y +CONFIG_DEBUG_KERNEL=y +CONFIG_DETECT_HUNG_TASK=y +# CONFIG_SCHED_DEBUG is not set +CONFIG_DEBUG_INFO=y +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +CONFIG_DEBUG_USER=y +CONFIG_DEBUG_ERRORS=y +CONFIG_DEBUG_LL=y +CONFIG_EARLY_PRINTK=y +# CONFIG_CRYPTO_ANSI_CPRNG is not set +# CONFIG_CRYPTO_HW is not set diff --git a/arch/arm/include/asm/bitops.h b/arch/arm/include/asm/bitops.h index 7b1bb2bbaf8..af54ed102f5 100644 --- a/arch/arm/include/asm/bitops.h +++ b/arch/arm/include/asm/bitops.h @@ -149,14 +149,18 @@ ____atomic_test_and_change_bit(unsigned int bit, volatile unsigned long *p) */ /* + * Native endian assembly bitops. nr = 0 -> word 0 bit 0. + */ +extern void _set_bit(int nr, volatile unsigned long * p); +extern void _clear_bit(int nr, volatile unsigned long * p); +extern void _change_bit(int nr, volatile unsigned long * p); +extern int _test_and_set_bit(int nr, volatile unsigned long * p); +extern int _test_and_clear_bit(int nr, volatile unsigned long * p); +extern int _test_and_change_bit(int nr, volatile unsigned long * p); + +/* * Little endian assembly bitops. nr = 0 -> byte 0 bit 0. */ -extern void _set_bit_le(int nr, volatile unsigned long * p); -extern void _clear_bit_le(int nr, volatile unsigned long * p); -extern void _change_bit_le(int nr, volatile unsigned long * p); -extern int _test_and_set_bit_le(int nr, volatile unsigned long * p); -extern int _test_and_clear_bit_le(int nr, volatile unsigned long * p); -extern int _test_and_change_bit_le(int nr, volatile unsigned long * p); extern int _find_first_zero_bit_le(const void * p, unsigned size); extern int _find_next_zero_bit_le(const void * p, int size, int offset); extern int _find_first_bit_le(const unsigned long *p, unsigned size); @@ -165,12 +169,6 @@ extern int _find_next_bit_le(const unsigned long *p, int size, int offset); /* * Big endian assembly bitops. nr = 0 -> byte 3 bit 0. */ -extern void _set_bit_be(int nr, volatile unsigned long * p); -extern void _clear_bit_be(int nr, volatile unsigned long * p); -extern void _change_bit_be(int nr, volatile unsigned long * p); -extern int _test_and_set_bit_be(int nr, volatile unsigned long * p); -extern int _test_and_clear_bit_be(int nr, volatile unsigned long * p); -extern int _test_and_change_bit_be(int nr, volatile unsigned long * p); extern int _find_first_zero_bit_be(const void * p, unsigned size); extern int _find_next_zero_bit_be(const void * p, int size, int offset); extern int _find_first_bit_be(const unsigned long *p, unsigned size); @@ -180,33 +178,26 @@ extern int _find_next_bit_be(const unsigned long *p, int size, int offset); /* * The __* form of bitops are non-atomic and may be reordered. */ -#define ATOMIC_BITOP_LE(name,nr,p) \ - (__builtin_constant_p(nr) ? \ - ____atomic_##name(nr, p) : \ - _##name##_le(nr,p)) - -#define ATOMIC_BITOP_BE(name,nr,p) \ - (__builtin_constant_p(nr) ? \ - ____atomic_##name(nr, p) : \ - _##name##_be(nr,p)) +#define ATOMIC_BITOP(name,nr,p) \ + (__builtin_constant_p(nr) ? ____atomic_##name(nr, p) : _##name(nr,p)) #else -#define ATOMIC_BITOP_LE(name,nr,p) _##name##_le(nr,p) -#define ATOMIC_BITOP_BE(name,nr,p) _##name##_be(nr,p) +#define ATOMIC_BITOP(name,nr,p) _##name(nr,p) #endif -#define NONATOMIC_BITOP(name,nr,p) \ - (____nonatomic_##name(nr, p)) +/* + * Native endian atomic definitions. + */ +#define set_bit(nr,p) ATOMIC_BITOP(set_bit,nr,p) +#define clear_bit(nr,p) ATOMIC_BITOP(clear_bit,nr,p) +#define change_bit(nr,p) ATOMIC_BITOP(change_bit,nr,p) +#define test_and_set_bit(nr,p) ATOMIC_BITOP(test_and_set_bit,nr,p) +#define test_and_clear_bit(nr,p) ATOMIC_BITOP(test_and_clear_bit,nr,p) +#define test_and_change_bit(nr,p) ATOMIC_BITOP(test_and_change_bit,nr,p) #ifndef __ARMEB__ /* * These are the little endian, atomic definitions. */ -#define set_bit(nr,p) ATOMIC_BITOP_LE(set_bit,nr,p) -#define clear_bit(nr,p) ATOMIC_BITOP_LE(clear_bit,nr,p) -#define change_bit(nr,p) ATOMIC_BITOP_LE(change_bit,nr,p) -#define test_and_set_bit(nr,p) ATOMIC_BITOP_LE(test_and_set_bit,nr,p) -#define test_and_clear_bit(nr,p) ATOMIC_BITOP_LE(test_and_clear_bit,nr,p) -#define test_and_change_bit(nr,p) ATOMIC_BITOP_LE(test_and_change_bit,nr,p) #define find_first_zero_bit(p,sz) _find_first_zero_bit_le(p,sz) #define find_next_zero_bit(p,sz,off) _find_next_zero_bit_le(p,sz,off) #define find_first_bit(p,sz) _find_first_bit_le(p,sz) @@ -215,16 +206,9 @@ extern int _find_next_bit_be(const unsigned long *p, int size, int offset); #define WORD_BITOFF_TO_LE(x) ((x)) #else - /* * These are the big endian, atomic definitions. */ -#define set_bit(nr,p) ATOMIC_BITOP_BE(set_bit,nr,p) -#define clear_bit(nr,p) ATOMIC_BITOP_BE(clear_bit,nr,p) -#define change_bit(nr,p) ATOMIC_BITOP_BE(change_bit,nr,p) -#define test_and_set_bit(nr,p) ATOMIC_BITOP_BE(test_and_set_bit,nr,p) -#define test_and_clear_bit(nr,p) ATOMIC_BITOP_BE(test_and_clear_bit,nr,p) -#define test_and_change_bit(nr,p) ATOMIC_BITOP_BE(test_and_change_bit,nr,p) #define find_first_zero_bit(p,sz) _find_first_zero_bit_be(p,sz) #define find_next_zero_bit(p,sz,off) _find_next_zero_bit_be(p,sz,off) #define find_first_bit(p,sz) _find_first_bit_be(p,sz) diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h index 3acd8fa25e3..d9b4c42d62f 100644 --- a/arch/arm/include/asm/cacheflush.h +++ b/arch/arm/include/asm/cacheflush.h @@ -116,20 +116,20 @@ # define MULTI_CACHE 1 #endif -#if defined(CONFIG_CPU_V6) -//# ifdef _CACHE +#if defined(CONFIG_CPU_CACHE_V6) +# ifdef _CACHE # define MULTI_CACHE 1 -//# else -//# define _CACHE v6 -//# endif +# else +# define _CACHE v6 +# endif #endif -#if defined(CONFIG_CPU_V7) -//# ifdef _CACHE +#if defined(CONFIG_CPU_CACHE_V7) +# ifdef _CACHE # define MULTI_CACHE 1 -//# else -//# define _CACHE v7 -//# endif +# else +# define _CACHE v7 +# endif #endif #if !defined(_CACHE) && !defined(MULTI_CACHE) @@ -316,7 +316,8 @@ extern void copy_to_user_page(struct vm_area_struct *, struct page *, * Optimized __flush_icache_all for the common cases. Note that UP ARMv7 * will fall through to use __flush_icache_all_generic. */ -#if (defined(CONFIG_CPU_V7) && defined(CONFIG_CPU_V6)) || \ +#if (defined(CONFIG_CPU_V7) && \ + (defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K))) || \ defined(CONFIG_SMP_ON_UP) #define __flush_icache_preferred __cpuc_flush_icache_all #elif __LINUX_ARM_ARCH__ >= 7 && defined(CONFIG_SMP) diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h index 20ae96cc002..ed5bc9e05a4 100644 --- a/arch/arm/include/asm/cputype.h +++ b/arch/arm/include/asm/cputype.h @@ -23,6 +23,8 @@ #define CPUID_EXT_ISAR4 "c2, 4" #define CPUID_EXT_ISAR5 "c2, 5" +extern unsigned int processor_id; + #ifdef CONFIG_CPU_CP15 #define read_cpuid(reg) \ ({ \ @@ -43,7 +45,6 @@ __val; \ }) #else -extern unsigned int processor_id; #define read_cpuid(reg) (processor_id) #define read_cpuid_ext(reg) 0 #endif diff --git a/arch/arm/include/asm/fncpy.h b/arch/arm/include/asm/fncpy.h new file mode 100644 index 00000000000..de535474692 --- /dev/null +++ b/arch/arm/include/asm/fncpy.h @@ -0,0 +1,94 @@ +/* + * arch/arm/include/asm/fncpy.h - helper macros for function body copying + * + * Copyright (C) 2011 Linaro Limited + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * These macros are intended for use when there is a need to copy a low-level + * function body into special memory. + * + * For example, when reconfiguring the SDRAM controller, the code doing the + * reconfiguration may need to run from SRAM. + * + * NOTE: that the copied function body must be entirely self-contained and + * position-independent in order for this to work properly. + * + * NOTE: in order for embedded literals and data to get referenced correctly, + * the alignment of functions must be preserved when copying. To ensure this, + * the source and destination addresses for fncpy() must be aligned to a + * multiple of 8 bytes: you will be get a BUG() if this condition is not met. + * You will typically need a ".align 3" directive in the assembler where the + * function to be copied is defined, and ensure that your allocator for the + * destination buffer returns 8-byte-aligned pointers. + * + * Typical usage example: + * + * extern int f(args); + * extern uint32_t size_of_f; + * int (*copied_f)(args); + * void *sram_buffer; + * + * copied_f = fncpy(sram_buffer, &f, size_of_f); + * + * ... later, call the function: ... + * + * copied_f(args); + * + * The size of the function to be copied can't be determined from C: + * this must be determined by other means, such as adding assmbler directives + * in the file where f is defined. + */ + +#ifndef __ASM_FNCPY_H +#define __ASM_FNCPY_H + +#include <linux/types.h> +#include <linux/string.h> + +#include <asm/bug.h> +#include <asm/cacheflush.h> + +/* + * Minimum alignment requirement for the source and destination addresses + * for function copying. + */ +#define FNCPY_ALIGN 8 + +#define fncpy(dest_buf, funcp, size) ({ \ + uintptr_t __funcp_address; \ + typeof(funcp) __result; \ + \ + asm("" : "=r" (__funcp_address) : "0" (funcp)); \ + \ + /* \ + * Ensure alignment of source and destination addresses, \ + * disregarding the function's Thumb bit: \ + */ \ + BUG_ON((uintptr_t)(dest_buf) & (FNCPY_ALIGN - 1) || \ + (__funcp_address & ~(uintptr_t)1 & (FNCPY_ALIGN - 1))); \ + \ + memcpy(dest_buf, (void const *)(__funcp_address & ~1), size); \ + flush_icache_range((unsigned long)(dest_buf), \ + (unsigned long)(dest_buf) + (size)); \ + \ + asm("" : "=r" (__result) \ + : "0" ((uintptr_t)(dest_buf) | (__funcp_address & 1))); \ + \ + __result; \ +}) + +#endif /* !__ASM_FNCPY_H */ diff --git a/arch/arm/include/asm/highmem.h b/arch/arm/include/asm/highmem.h index 7080e2c8fa6..a4edd19dd3d 100644 --- a/arch/arm/include/asm/highmem.h +++ b/arch/arm/include/asm/highmem.h @@ -19,11 +19,36 @@ extern pte_t *pkmap_page_table; +extern void *kmap_high(struct page *page); +extern void kunmap_high(struct page *page); + +/* + * The reason for kmap_high_get() is to ensure that the currently kmap'd + * page usage count does not decrease to zero while we're using its + * existing virtual mapping in an atomic context. With a VIVT cache this + * is essential to do, but with a VIPT cache this is only an optimization + * so not to pay the price of establishing a second mapping if an existing + * one can be used. However, on platforms without hardware TLB maintenance + * broadcast, we simply cannot use ARCH_NEEDS_KMAP_HIGH_GET at all since + * the locking involved must also disable IRQs which is incompatible with + * the IPI mechanism used by global TLB operations. + */ #define ARCH_NEEDS_KMAP_HIGH_GET +#if defined(CONFIG_SMP) && defined(CONFIG_CPU_TLB_V6) +#undef ARCH_NEEDS_KMAP_HIGH_GET +#if defined(CONFIG_HIGHMEM) && defined(CONFIG_CPU_CACHE_VIVT) +#error "The sum of features in your kernel config cannot be supported together" +#endif +#endif -extern void *kmap_high(struct page *page); +#ifdef ARCH_NEEDS_KMAP_HIGH_GET extern void *kmap_high_get(struct page *page); -extern void kunmap_high(struct page *page); +#else +static inline void *kmap_high_get(struct page *page) +{ + return NULL; +} +#endif /* * The following functions are already defined by <linux/highmem.h> diff --git a/arch/arm/include/asm/mach/arch.h b/arch/arm/include/asm/mach/arch.h index 3a0893a76a3..946f4d778f7 100644 --- a/arch/arm/include/asm/mach/arch.h +++ b/arch/arm/include/asm/mach/arch.h @@ -15,13 +15,11 @@ struct meminfo; struct sys_timer; struct machine_desc { - /* - * Note! The first two elements are used - * by assembler code in head.S, head-common.S - */ unsigned int nr; /* architecture number */ const char *name; /* architecture name */ unsigned long boot_params; /* tagged list */ + const char **dt_compat; /* array of device tree + * 'compatible' strings */ unsigned int nr_irqs; /* number of IRQs */ @@ -52,6 +50,13 @@ struct machine_desc { extern struct machine_desc *machine_desc; /* + * Machine type table - also only accessible during boot + */ +extern struct machine_desc __arch_info_begin[], __arch_info_end[]; +#define for_each_machine_desc(p) \ + for (p = __arch_info_begin; p < __arch_info_end; p++) + +/* * Set of macros to define architecture features. This is built into * a table by the linker. */ diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h index d0ee74b7cf8..431077c5a86 100644 --- a/arch/arm/include/asm/memory.h +++ b/arch/arm/include/asm/memory.h @@ -15,6 +15,7 @@ #include <linux/compiler.h> #include <linux/const.h> +#include <linux/types.h> #include <mach/memory.h> #include <asm/sizes.h> @@ -133,20 +134,10 @@ #endif /* - * Physical vs virtual RAM address space conversion. These are - * private definitions which should NOT be used outside memory.h - * files. Use virt_to_phys/phys_to_virt/__pa/__va instead. - */ -#ifndef __virt_to_phys -#define __virt_to_phys(x) ((x) - PAGE_OFFSET + PHYS_OFFSET) -#define __phys_to_virt(x) ((x) - PHYS_OFFSET + PAGE_OFFSET) -#endif - -/* * Convert a physical address to a Page Frame Number and back */ -#define __phys_to_pfn(paddr) ((paddr) >> PAGE_SHIFT) -#define __pfn_to_phys(pfn) ((pfn) << PAGE_SHIFT) +#define __phys_to_pfn(paddr) ((unsigned long)((paddr) >> PAGE_SHIFT)) +#define __pfn_to_phys(pfn) ((phys_addr_t)(pfn) << PAGE_SHIFT) /* * Convert a page to/from a physical address @@ -157,6 +148,62 @@ #ifndef __ASSEMBLY__ /* + * Physical vs virtual RAM address space conversion. These are + * private definitions which should NOT be used outside memory.h + * files. Use virt_to_phys/phys_to_virt/__pa/__va instead. + */ +#ifndef __virt_to_phys +#ifdef CONFIG_ARM_PATCH_PHYS_VIRT + +/* + * Constants used to force the right instruction encodings and shifts + * so that all we need to do is modify the 8-bit constant field. + */ +#define __PV_BITS_31_24 0x81000000 +#define __PV_BITS_23_16 0x00810000 + +extern unsigned long __pv_phys_offset; +#define PHYS_OFFSET __pv_phys_offset + +#define __pv_stub(from,to,instr,type) \ + __asm__("@ __pv_stub\n" \ + "1: " instr " %0, %1, %2\n" \ + " .pushsection .pv_table,\"a\"\n" \ + " .long 1b\n" \ + " .popsection\n" \ + : "=r" (to) \ + : "r" (from), "I" (type)) + +static inline unsigned long __virt_to_phys(unsigned long x) +{ + unsigned long t; + __pv_stub(x, t, "add", __PV_BITS_31_24); +#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT + __pv_stub(t, t, "add", __PV_BITS_23_16); +#endif + return t; +} + +static inline unsigned long __phys_to_virt(unsigned long x) +{ + unsigned long t; + __pv_stub(x, t, "sub", __PV_BITS_31_24); +#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT + __pv_stub(t, t, "sub", __PV_BITS_23_16); +#endif + return t; +} +#else +#define __virt_to_phys(x) ((x) - PAGE_OFFSET + PHYS_OFFSET) +#define __phys_to_virt(x) ((x) - PHYS_OFFSET + PAGE_OFFSET) +#endif +#endif + +#ifndef PHYS_OFFSET +#define PHYS_OFFSET PLAT_PHYS_OFFSET +#endif + +/* * The DMA mask corresponding to the maximum bus address allocatable * using GFP_DMA. The default here places no restriction on DMA * allocations. This must be the smallest DMA mask in the system, @@ -188,12 +235,12 @@ * translation for translating DMA addresses. Use the driver * DMA support - see dma-mapping.h. */ -static inline unsigned long virt_to_phys(const volatile void *x) +static inline phys_addr_t virt_to_phys(const volatile void *x) { return __virt_to_phys((unsigned long)(x)); } -static inline void *phys_to_virt(unsigned long x) +static inline void *phys_to_virt(phys_addr_t x) { return (void *)(__phys_to_virt((unsigned long)(x))); } diff --git a/arch/arm/include/asm/module.h b/arch/arm/include/asm/module.h index 12c8e680cbf..543b44916d2 100644 --- a/arch/arm/include/asm/module.h +++ b/arch/arm/include/asm/module.h @@ -25,8 +25,31 @@ struct mod_arch_specific { }; /* - * Include the ARM architecture version. + * Add the ARM architecture version to the version magic string */ -#define MODULE_ARCH_VERMAGIC "ARMv" __stringify(__LINUX_ARM_ARCH__) " " +#define MODULE_ARCH_VERMAGIC_ARMVSN "ARMv" __stringify(__LINUX_ARM_ARCH__) " " + +/* Add __virt_to_phys patching state as well */ +#ifdef CONFIG_ARM_PATCH_PHYS_VIRT +#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT +#define MODULE_ARCH_VERMAGIC_P2V "p2v16 " +#else +#define MODULE_ARCH_VERMAGIC_P2V "p2v8 " +#endif +#else +#define MODULE_ARCH_VERMAGIC_P2V "" +#endif + +/* Add instruction set architecture tag to distinguish ARM/Thumb kernels */ +#ifdef CONFIG_THUMB2_KERNEL +#define MODULE_ARCH_VERMAGIC_ARMTHUMB "thumb2 " +#else +#define MODULE_ARCH_VERMAGIC_ARMTHUMB "" +#endif + +#define MODULE_ARCH_VERMAGIC \ + MODULE_ARCH_VERMAGIC_ARMVSN \ + MODULE_ARCH_VERMAGIC_ARMTHUMB \ + MODULE_ARCH_VERMAGIC_P2V #endif /* _ASM_ARM_MODULE_H */ diff --git a/arch/arm/include/asm/pgalloc.h b/arch/arm/include/asm/pgalloc.h index 9763be04f77..22de005f159 100644 --- a/arch/arm/include/asm/pgalloc.h +++ b/arch/arm/include/asm/pgalloc.h @@ -10,6 +10,8 @@ #ifndef _ASMARM_PGALLOC_H #define _ASMARM_PGALLOC_H +#include <linux/pagemap.h> + #include <asm/domain.h> #include <asm/pgtable-hwdef.h> #include <asm/processor.h> diff --git a/arch/arm/include/asm/pmu.h b/arch/arm/include/asm/pmu.h index 8ccea012722..7544ce6b481 100644 --- a/arch/arm/include/asm/pmu.h +++ b/arch/arm/include/asm/pmu.h @@ -12,11 +12,25 @@ #ifndef __ARM_PMU_H__ #define __ARM_PMU_H__ +#include <linux/interrupt.h> + enum arm_pmu_type { ARM_PMU_DEVICE_CPU = 0, ARM_NUM_PMU_DEVICES, }; +/* + * struct arm_pmu_platdata - ARM PMU platform data + * + * @handle_irq: an optional handler which will be called from the interrupt and + * passed the address of the low level handler, and can be used to implement + * any platform specific handling before or after calling it. + */ +struct arm_pmu_platdata { + irqreturn_t (*handle_irq)(int irq, void *dev, + irq_handler_t pmu_handler); +}; + #ifdef CONFIG_CPU_HAS_PMU /** diff --git a/arch/arm/include/asm/proc-fns.h b/arch/arm/include/asm/proc-fns.h index 8fdae9bc9ab..296ca47489f 100644 --- a/arch/arm/include/asm/proc-fns.h +++ b/arch/arm/include/asm/proc-fns.h @@ -231,7 +231,7 @@ # endif #endif -#ifdef CONFIG_CPU_V6 +#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K) # ifdef CPU_NAME # undef MULTI_CPU # define MULTI_CPU diff --git a/arch/arm/include/asm/processor.h b/arch/arm/include/asm/processor.h index 67357baaeee..b439b41aeac 100644 --- a/arch/arm/include/asm/processor.h +++ b/arch/arm/include/asm/processor.h @@ -29,19 +29,7 @@ #define STACK_TOP_MAX TASK_SIZE #endif -union debug_insn { - u32 arm; - u16 thumb; -}; - -struct debug_entry { - u32 address; - union debug_insn insn; -}; - struct debug_info { - int nsaved; - struct debug_entry bp[2]; #ifdef CONFIG_HAVE_HW_BREAKPOINT struct perf_event *hbp[ARM_MAX_HBP_SLOTS]; #endif diff --git a/arch/arm/include/asm/prom.h b/arch/arm/include/asm/prom.h new file mode 100644 index 00000000000..11b8708fc4d --- /dev/null +++ b/arch/arm/include/asm/prom.h @@ -0,0 +1,37 @@ +/* + * arch/arm/include/asm/prom.h + * + * Copyright (C) 2009 Canonical Ltd. <jeremy.kerr@canonical.com> + * + * 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. + * + */ +#ifndef __ASMARM_PROM_H +#define __ASMARM_PROM_H + +#ifdef CONFIG_OF + +#include <asm/setup.h> +#include <asm/irq.h> + +static inline void irq_dispose_mapping(unsigned int virq) +{ + return; +} + +extern struct machine_desc *setup_machine_fdt(unsigned int dt_phys); +extern void arm_dt_memblock_reserve(void); + +#else /* CONFIG_OF */ + +static inline struct machine_desc *setup_machine_fdt(unsigned int dt_phys) +{ + return NULL; +} + +static inline void arm_dt_memblock_reserve(void) { } + +#endif /* CONFIG_OF */ +#endif /* ASMARM_PROM_H */ diff --git a/arch/arm/include/asm/ptrace.h b/arch/arm/include/asm/ptrace.h index 783d50f3261..a8ff22b2a39 100644 --- a/arch/arm/include/asm/ptrace.h +++ b/arch/arm/include/asm/ptrace.h @@ -130,8 +130,6 @@ struct pt_regs { #ifdef __KERNEL__ -#define arch_has_single_step() (1) - #define user_mode(regs) \ (((regs)->ARM_cpsr & 0xf) == 0) diff --git a/arch/arm/include/asm/setup.h b/arch/arm/include/asm/setup.h index f1e5a9bca24..207f911a173 100644 --- a/arch/arm/include/asm/setup.h +++ b/arch/arm/include/asm/setup.h @@ -221,6 +221,11 @@ extern struct meminfo meminfo; #define bank_phys_end(bank) ((bank)->start + (bank)->size) #define bank_phys_size(bank) (bank)->size +extern int arm_add_memory(unsigned long start, unsigned long size); +extern char cmd_line[COMMAND_LINE_SIZE]; +extern void early_print(const char *str, ...); +extern void dump_machine_table(void); + #endif /* __KERNEL__ */ #endif diff --git a/arch/arm/include/asm/spinlock.h b/arch/arm/include/asm/spinlock.h index 17eb355707d..fdd3820edff 100644 --- a/arch/arm/include/asm/spinlock.h +++ b/arch/arm/include/asm/spinlock.h @@ -5,17 +5,52 @@ #error SMP not supported on pre-ARMv6 CPUs #endif +/* + * sev and wfe are ARMv6K extensions. Uniprocessor ARMv6 may not have the K + * extensions, so when running on UP, we have to patch these instructions away. + */ +#define ALT_SMP(smp, up) \ + "9998: " smp "\n" \ + " .pushsection \".alt.smp.init\", \"a\"\n" \ + " .long 9998b\n" \ + " " up "\n" \ + " .popsection\n" + +#ifdef CONFIG_THUMB2_KERNEL +#define SEV ALT_SMP("sev.w", "nop.w") +/* + * For Thumb-2, special care is needed to ensure that the conditional WFE + * instruction really does assemble to exactly 4 bytes (as required by + * the SMP_ON_UP fixup code). By itself "wfene" might cause the + * assembler to insert a extra (16-bit) IT instruction, depending on the + * presence or absence of neighbouring conditional instructions. + * + * To avoid this unpredictableness, an approprite IT is inserted explicitly: + * the assembler won't change IT instructions which are explicitly present + * in the input. + */ +#define WFE(cond) ALT_SMP( \ + "it " cond "\n\t" \ + "wfe" cond ".n", \ + \ + "nop.w" \ +) +#else +#define SEV ALT_SMP("sev", "nop") +#define WFE(cond) ALT_SMP("wfe" cond, "nop") +#endif + static inline void dsb_sev(void) { #if __LINUX_ARM_ARCH__ >= 7 __asm__ __volatile__ ( "dsb\n" - "sev" + SEV ); -#elif defined(CONFIG_CPU_32v6K) +#else __asm__ __volatile__ ( "mcr p15, 0, %0, c7, c10, 4\n" - "sev" + SEV : : "r" (0) ); #endif @@ -46,9 +81,7 @@ static inline void arch_spin_lock(arch_spinlock_t *lock) __asm__ __volatile__( "1: ldrex %0, [%1]\n" " teq %0, #0\n" -#ifdef CONFIG_CPU_32v6K -" wfene\n" -#endif + WFE("ne") " strexeq %0, %2, [%1]\n" " teqeq %0, #0\n" " bne 1b" @@ -107,9 +140,7 @@ static inline void arch_write_lock(arch_rwlock_t *rw) __asm__ __volatile__( "1: ldrex %0, [%1]\n" " teq %0, #0\n" -#ifdef CONFIG_CPU_32v6K -" wfene\n" -#endif + WFE("ne") " strexeq %0, %2, [%1]\n" " teq %0, #0\n" " bne 1b" @@ -176,9 +207,7 @@ static inline void arch_read_lock(arch_rwlock_t *rw) "1: ldrex %0, [%2]\n" " adds %0, %0, #1\n" " strexpl %1, %0, [%2]\n" -#ifdef CONFIG_CPU_32v6K -" wfemi\n" -#endif + WFE("mi") " rsbpls %0, %1, #0\n" " bmi 1b" : "=&r" (tmp), "=&r" (tmp2) diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h index 97f6d60297d..9a87823642d 100644 --- a/arch/arm/include/asm/system.h +++ b/arch/arm/include/asm/system.h @@ -347,6 +347,7 @@ void cpu_idle_wait(void); #include <asm-generic/cmpxchg-local.h> #if __LINUX_ARM_ARCH__ < 6 +/* min ARCH < ARMv6 */ #ifdef CONFIG_SMP #error "SMP is not supported on this platform" @@ -365,7 +366,7 @@ void cpu_idle_wait(void); #include <asm-generic/cmpxchg.h> #endif -#else /* __LINUX_ARM_ARCH__ >= 6 */ +#else /* min ARCH >= ARMv6 */ extern void __bad_cmpxchg(volatile void *ptr, int size); @@ -379,7 +380,7 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, unsigned long oldval, res; switch (size) { -#ifdef CONFIG_CPU_32v6K +#ifndef CONFIG_CPU_V6 /* min ARCH >= ARMv6K */ case 1: do { asm volatile("@ __cmpxchg1\n" @@ -404,7 +405,7 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, : "memory", "cc"); } while (res); break; -#endif /* CONFIG_CPU_32v6K */ +#endif case 4: do { asm volatile("@ __cmpxchg4\n" @@ -450,12 +451,12 @@ static inline unsigned long __cmpxchg_local(volatile void *ptr, unsigned long ret; switch (size) { -#ifndef CONFIG_CPU_32v6K +#ifdef CONFIG_CPU_V6 /* min ARCH == ARMv6 */ case 1: case 2: ret = __cmpxchg_local_generic(ptr, old, new, size); break; -#endif /* !CONFIG_CPU_32v6K */ +#endif default: ret = __cmpxchg(ptr, old, new, size); } @@ -469,7 +470,7 @@ static inline unsigned long __cmpxchg_local(volatile void *ptr, (unsigned long)(n), \ sizeof(*(ptr)))) -#ifdef CONFIG_CPU_32v6K +#ifndef CONFIG_CPU_V6 /* min ARCH >= ARMv6K */ /* * Note : ARMv7-M (currently unsupported by Linux) does not support @@ -524,11 +525,11 @@ static inline unsigned long long __cmpxchg64_mb(volatile void *ptr, (unsigned long long)(o), \ (unsigned long long)(n))) -#else /* !CONFIG_CPU_32v6K */ +#else /* min ARCH = ARMv6 */ #define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n)) -#endif /* CONFIG_CPU_32v6K */ +#endif #endif /* __LINUX_ARM_ARCH__ >= 6 */ diff --git a/arch/arm/include/asm/tls.h b/arch/arm/include/asm/tls.h index e71d6ff8d10..60843eb0f61 100644 --- a/arch/arm/include/asm/tls.h +++ b/arch/arm/include/asm/tls.h @@ -28,15 +28,14 @@ #define tls_emu 1 #define has_tls_reg 1 #define set_tls set_tls_none -#elif __LINUX_ARM_ARCH__ >= 7 || \ - (__LINUX_ARM_ARCH__ == 6 && defined(CONFIG_CPU_32v6K)) -#define tls_emu 0 -#define has_tls_reg 1 -#define set_tls set_tls_v6k -#elif __LINUX_ARM_ARCH__ == 6 +#elif defined(CONFIG_CPU_V6) #define tls_emu 0 #define has_tls_reg (elf_hwcap & HWCAP_TLS) #define set_tls set_tls_v6 +#elif defined(CONFIG_CPU_32v6K) +#define tls_emu 0 +#define has_tls_reg 1 +#define set_tls set_tls_v6k #else #define tls_emu 0 #define has_tls_reg 0 diff --git a/arch/arm/include/asm/traps.h b/arch/arm/include/asm/traps.h index 1b960d5ef6a..f90756dc16d 100644 --- a/arch/arm/include/asm/traps.h +++ b/arch/arm/include/asm/traps.h @@ -45,6 +45,7 @@ static inline int in_exception_text(unsigned long ptr) extern void __init early_trap_init(void); extern void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame); +extern void ptrace_break(struct task_struct *tsk, struct pt_regs *regs); extern void *vectors_page; diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index 185ee822c93..8df05fd4c91 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile @@ -43,6 +43,7 @@ obj-$(CONFIG_ARM_THUMBEE) += thumbee.o obj-$(CONFIG_KGDB) += kgdb.o obj-$(CONFIG_ARM_UNWIND) += unwind.o obj-$(CONFIG_HAVE_TCM) += tcm.o +obj-$(CONFIG_OF) += devtree.o obj-$(CONFIG_CRASH_DUMP) += crash_dump.o obj-$(CONFIG_SWP_EMULATE) += swp_emulate.o CFLAGS_swp_emulate.o := -Wa,-march=armv7-a diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c index e5e1e538767..acca35aebe2 100644 --- a/arch/arm/kernel/armksyms.c +++ b/arch/arm/kernel/armksyms.c @@ -140,24 +140,18 @@ EXPORT_SYMBOL(__aeabi_ulcmp); #endif /* bitops */ -EXPORT_SYMBOL(_set_bit_le); -EXPORT_SYMBOL(_test_and_set_bit_le); -EXPORT_SYMBOL(_clear_bit_le); -EXPORT_SYMBOL(_test_and_clear_bit_le); -EXPORT_SYMBOL(_change_bit_le); -EXPORT_SYMBOL(_test_and_change_bit_le); +EXPORT_SYMBOL(_set_bit); +EXPORT_SYMBOL(_test_and_set_bit); +EXPORT_SYMBOL(_clear_bit); +EXPORT_SYMBOL(_test_and_clear_bit); +EXPORT_SYMBOL(_change_bit); +EXPORT_SYMBOL(_test_and_change_bit); EXPORT_SYMBOL(_find_first_zero_bit_le); EXPORT_SYMBOL(_find_next_zero_bit_le); EXPORT_SYMBOL(_find_first_bit_le); EXPORT_SYMBOL(_find_next_bit_le); #ifdef __ARMEB__ -EXPORT_SYMBOL(_set_bit_be); -EXPORT_SYMBOL(_test_and_set_bit_be); -EXPORT_SYMBOL(_clear_bit_be); -EXPORT_SYMBOL(_test_and_clear_bit_be); -EXPORT_SYMBOL(_change_bit_be); -EXPORT_SYMBOL(_test_and_change_bit_be); EXPORT_SYMBOL(_find_first_zero_bit_be); EXPORT_SYMBOL(_find_next_zero_bit_be); EXPORT_SYMBOL(_find_first_bit_be); @@ -170,3 +164,7 @@ EXPORT_SYMBOL(mcount); #endif EXPORT_SYMBOL(__gnu_mcount_nc); #endif + +#ifdef CONFIG_ARM_PATCH_PHYS_VIRT +EXPORT_SYMBOL(__pv_phys_offset); +#endif diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c index c6273a3bfc2..d86fcd44b22 100644 --- a/arch/arm/kernel/bios32.c +++ b/arch/arm/kernel/bios32.c @@ -583,6 +583,11 @@ void __init pci_common_init(struct hw_pci *hw) * Assign resources. */ pci_bus_assign_resources(bus); + + /* + * Enable bridges + */ + pci_enable_bridges(bus); } /* diff --git a/arch/arm/kernel/debug.S b/arch/arm/kernel/debug.S index a0f07521ca8..d2d983be096 100644 --- a/arch/arm/kernel/debug.S +++ b/arch/arm/kernel/debug.S @@ -25,7 +25,7 @@ .macro addruart, rp, rv .endm -#if defined(CONFIG_CPU_V6) +#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K) .macro senduart, rd, rx mcr p14, 0, \rd, c0, c5, 0 diff --git a/arch/arm/kernel/devtree.c b/arch/arm/kernel/devtree.c new file mode 100644 index 00000000000..4dd725acba6 --- /dev/null +++ b/arch/arm/kernel/devtree.c @@ -0,0 +1,147 @@ +/* + * linux/arch/arm/kernel/devtree.c + * + * Copyright (C) 2009 Canonical Ltd. <jeremy.kerr@canonical.com> + * + * 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/init.h> +#include <linux/module.h> +#include <linux/errno.h> +#include <linux/types.h> +#include <linux/bootmem.h> +#include <linux/memblock.h> +#include <linux/of.h> +#include <linux/of_fdt.h> +#include <linux/of_irq.h> +#include <linux/of_platform.h> + +#include <asm/setup.h> +#include <asm/page.h> +#include <asm/mach/arch.h> +#include <asm/mach-types.h> + +void __init early_init_dt_add_memory_arch(u64 base, u64 size) +{ + arm_add_memory(base, size); +} + +void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align) +{ + return alloc_bootmem_align(size, align); +} + +void __init arm_dt_memblock_reserve(void) +{ + u64 *reserve_map, base, size; + + if (!initial_boot_params) + return; + + /* Reserve the dtb region */ + memblock_reserve(virt_to_phys(initial_boot_params), + be32_to_cpu(initial_boot_params->totalsize)); + + /* + * Process the reserve map. This will probably overlap the initrd + * and dtb locations which are already reserved, but overlaping + * doesn't hurt anything + */ + reserve_map = ((void*)initial_boot_params) + + be32_to_cpu(initial_boot_params->off_mem_rsvmap); + while (1) { + base = be64_to_cpup(reserve_map++); + size = be64_to_cpup(reserve_map++); + if (!size) + break; + memblock_reserve(base, size); + } +} + +/** + * irq_create_of_mapping - Hook to resolve OF irq specifier into a Linux irq# + * + * Currently the mapping mechanism is trivial; simple flat hwirq numbers are + * mapped 1:1 onto Linux irq numbers. Cascaded irq controllers are not + * supported. + */ +unsigned int irq_create_of_mapping(struct device_node *controller, + const u32 *intspec, unsigned int intsize) +{ + return intspec[0]; +} +EXPORT_SYMBOL_GPL(irq_create_of_mapping); + +/** + * setup_machine_fdt - Machine setup when an dtb was passed to the kernel + * @dt_phys: physical address of dt blob + * + * If a dtb was passed to the kernel in r2, then use it to choose the + * correct machine_desc and to setup the system. + */ +struct machine_desc * __init setup_machine_fdt(unsigned int dt_phys) +{ + struct boot_param_header *devtree; + struct machine_desc *mdesc, *mdesc_best = NULL; + unsigned int score, mdesc_score = ~1; + unsigned long dt_root; + const char *model; + + devtree = phys_to_virt(dt_phys); + + /* check device tree validity */ + if (be32_to_cpu(devtree->magic) != OF_DT_HEADER) + return NULL; + + /* Search the mdescs for the 'best' compatible value match */ + initial_boot_params = devtree; + dt_root = of_get_flat_dt_root(); + for_each_machine_desc(mdesc) { + score = of_flat_dt_match(dt_root, mdesc->dt_compat); + if (score > 0 && score < mdesc_score) { + mdesc_best = mdesc; + mdesc_score = score; + } + } + if (!mdesc_best) { + const char *prop; + long size; + + early_print("\nError: unrecognized/unsupported " + "device tree compatible list:\n[ "); + + prop = of_get_flat_dt_prop(dt_root, "compatible", &size); + while (size > 0) { + early_print("'%s' ", prop); + size -= strlen(prop) + 1; + prop += strlen(prop) + 1; + } + early_print("]\n\n"); + + dump_machine_table(); /* does not return */ + } + + model = of_get_flat_dt_prop(dt_root, "model", NULL); + if (!model) + model = of_get_flat_dt_prop(dt_root, "compatible", NULL); + if (!model) + model = "<unknown>"; + pr_info("Machine: %s, model: %s\n", mdesc_best->name, model); + + /* Retrieve various information from the /chosen node */ + of_scan_flat_dt(early_init_dt_scan_chosen, NULL); + /* Initialize {size,address}-cells info */ + of_scan_flat_dt(early_init_dt_scan_root, NULL); + /* Setup memory, calling early_init_dt_add_memory_arch */ + of_scan_flat_dt(early_init_dt_scan_memory, NULL); + /* Save command line for /proc/cmdline */ + strlcpy(boot_command_line, cmd_line, COMMAND_LINE_SIZE); + + /* Change machine number to match the mdesc we're using */ + __machine_arch_type = mdesc->nr; + + return mdesc_best; +} diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S index ae946490016..051166c2a93 100644 --- a/arch/arm/kernel/entry-header.S +++ b/arch/arm/kernel/entry-header.S @@ -76,13 +76,13 @@ #ifndef CONFIG_THUMB2_KERNEL .macro svc_exit, rpsr msr spsr_cxsf, \rpsr -#if defined(CONFIG_CPU_32v6K) - clrex @ clear the exclusive monitor - ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr -#elif defined (CONFIG_CPU_V6) +#if defined(CONFIG_CPU_V6) ldr r0, [sp] strex r1, r2, [sp] @ clear the exclusive monitor ldmib sp, {r1 - pc}^ @ load r1 - pc, cpsr +#elif defined(CONFIG_CPU_32v6K) + clrex @ clear the exclusive monitor + ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr #else ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr #endif @@ -92,10 +92,10 @@ ldr r1, [sp, #\offset + S_PSR] @ get calling cpsr ldr lr, [sp, #\offset + S_PC]! @ get pc msr spsr_cxsf, r1 @ save in spsr_svc -#if defined(CONFIG_CPU_32v6K) - clrex @ clear the exclusive monitor -#elif defined (CONFIG_CPU_V6) +#if defined(CONFIG_CPU_V6) strex r1, r2, [sp] @ clear the exclusive monitor +#elif defined(CONFIG_CPU_32v6K) + clrex @ clear the exclusive monitor #endif .if \fast ldmdb sp, {r1 - lr}^ @ get calling r1 - lr diff --git a/arch/arm/kernel/etm.c b/arch/arm/kernel/etm.c index 11db62806a1..052b509e2d5 100644 --- a/arch/arm/kernel/etm.c +++ b/arch/arm/kernel/etm.c @@ -338,7 +338,7 @@ static struct miscdevice etb_miscdev = { .fops = &etb_fops, }; -static int __init etb_probe(struct amba_device *dev, struct amba_id *id) +static int __init etb_probe(struct amba_device *dev, const struct amba_id *id) { struct tracectx *t = &tracer; int ret = 0; @@ -530,7 +530,7 @@ static ssize_t trace_mode_store(struct kobject *kobj, static struct kobj_attribute trace_mode_attr = __ATTR(trace_mode, 0644, trace_mode_show, trace_mode_store); -static int __init etm_probe(struct amba_device *dev, struct amba_id *id) +static int __init etm_probe(struct amba_device *dev, const struct amba_id *id) { struct tracectx *t = &tracer; int ret = 0; diff --git a/arch/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S index 8f57515bbdb..854bd22380d 100644 --- a/arch/arm/kernel/head-common.S +++ b/arch/arm/kernel/head-common.S @@ -15,6 +15,12 @@ #define ATAG_CORE_SIZE ((2*4 + 3*4) >> 2) #define ATAG_CORE_SIZE_EMPTY ((2*4) >> 2) +#ifdef CONFIG_CPU_BIG_ENDIAN +#define OF_DT_MAGIC 0xd00dfeed +#else +#define OF_DT_MAGIC 0xedfe0dd0 /* 0xd00dfeed in big-endian */ +#endif + /* * Exception handling. Something went wrong and we can't proceed. We * ought to tell the user, but since we don't have any guarantee that @@ -25,102 +31,29 @@ * machine ID for example). */ __HEAD -__error_a: -#ifdef CONFIG_DEBUG_LL - mov r4, r1 @ preserve machine ID - adr r0, str_a1 - bl printascii - mov r0, r4 - bl printhex8 - adr r0, str_a2 - bl printascii - adr r3, __lookup_machine_type_data - ldmia r3, {r4, r5, r6} @ get machine desc list - sub r4, r3, r4 @ get offset between virt&phys - add r5, r5, r4 @ convert virt addresses to - add r6, r6, r4 @ physical address space -1: ldr r0, [r5, #MACHINFO_TYPE] @ get machine type - bl printhex8 - mov r0, #'\t' - bl printch - ldr r0, [r5, #MACHINFO_NAME] @ get machine name - add r0, r0, r4 - bl printascii - mov r0, #'\n' - bl printch - add r5, r5, #SIZEOF_MACHINE_DESC @ next machine_desc - cmp r5, r6 - blo 1b - adr r0, str_a3 - bl printascii - b __error -ENDPROC(__error_a) - -str_a1: .asciz "\nError: unrecognized/unsupported machine ID (r1 = 0x" -str_a2: .asciz ").\n\nAvailable machine support:\n\nID (hex)\tNAME\n" -str_a3: .asciz "\nPlease check your kernel config and/or bootloader.\n" - .align -#else - b __error -#endif - -/* - * Lookup machine architecture in the linker-build list of architectures. - * Note that we can't use the absolute addresses for the __arch_info - * lists since we aren't running with the MMU on (and therefore, we are - * not in the correct address space). We have to calculate the offset. - * - * r1 = machine architecture number - * Returns: - * r3, r4, r6 corrupted - * r5 = mach_info pointer in physical address space - */ -__lookup_machine_type: - adr r3, __lookup_machine_type_data - ldmia r3, {r4, r5, r6} - sub r3, r3, r4 @ get offset between virt&phys - add r5, r5, r3 @ convert virt addresses to - add r6, r6, r3 @ physical address space -1: ldr r3, [r5, #MACHINFO_TYPE] @ get machine type - teq r3, r1 @ matches loader number? - beq 2f @ found - add r5, r5, #SIZEOF_MACHINE_DESC @ next machine_desc - cmp r5, r6 - blo 1b - mov r5, #0 @ unknown machine -2: mov pc, lr -ENDPROC(__lookup_machine_type) - -/* - * Look in arch/arm/kernel/arch.[ch] for information about the - * __arch_info structures. - */ - .align 2 - .type __lookup_machine_type_data, %object -__lookup_machine_type_data: - .long . - .long __arch_info_begin - .long __arch_info_end - .size __lookup_machine_type_data, . - __lookup_machine_type_data /* Determine validity of the r2 atags pointer. The heuristic requires * that the pointer be aligned, in the first 16k of physical RAM and - * that the ATAG_CORE marker is first and present. Future revisions + * that the ATAG_CORE marker is first and present. If CONFIG_OF_FLATTREE + * is selected, then it will also accept a dtb pointer. Future revisions * of this function may be more lenient with the physical address and * may also be able to move the ATAGS block if necessary. * - * r8 = machinfo - * * Returns: - * r2 either valid atags pointer, or zero + * r2 either valid atags pointer, valid dtb pointer, or zero * r5, r6 corrupted */ __vet_atags: tst r2, #0x3 @ aligned? bne 1f - ldr r5, [r2, #0] @ is first tag ATAG_CORE? - cmp r5, #ATAG_CORE_SIZE + ldr r5, [r2, #0] +#ifdef CONFIG_OF_FLATTREE + ldr r6, =OF_DT_MAGIC @ is it a DTB? + cmp r5, r6 + beq 2f +#endif + cmp r5, #ATAG_CORE_SIZE @ is first tag ATAG_CORE? cmpne r5, #ATAG_CORE_SIZE_EMPTY bne 1f ldr r5, [r2, #4] @@ -128,7 +61,7 @@ __vet_atags: cmp r5, r6 bne 1f - mov pc, lr @ atag pointer is ok +2: mov pc, lr @ atag/dtb pointer is ok 1: mov r2, #0 mov pc, lr @@ -140,7 +73,7 @@ ENDPROC(__vet_atags) * * r0 = cp#15 control register * r1 = machine ID - * r2 = atags pointer + * r2 = atags/dtb pointer * r9 = processor ID */ __INIT @@ -185,17 +118,6 @@ __mmap_switched_data: .size __mmap_switched_data, . - __mmap_switched_data /* - * This provides a C-API version of __lookup_machine_type - */ -ENTRY(lookup_machine_type) - stmfd sp!, {r4 - r6, lr} - mov r1, r0 - bl __lookup_machine_type - mov r0, r5 - ldmfd sp!, {r4 - r6, pc} -ENDPROC(lookup_machine_type) - -/* * This provides a C-API version of __lookup_processor_type */ ENTRY(lookup_processor_type) diff --git a/arch/arm/kernel/head-nommu.S b/arch/arm/kernel/head-nommu.S index 814ce1a7327..6b1e0ad9ec3 100644 --- a/arch/arm/kernel/head-nommu.S +++ b/arch/arm/kernel/head-nommu.S @@ -44,9 +44,6 @@ ENTRY(stext) bl __lookup_processor_type @ r5=procinfo r9=cpuid movs r10, r5 @ invalid processor (r5=0)? beq __error_p @ yes, error 'p' - bl __lookup_machine_type @ r5=machinfo - movs r8, r5 @ invalid machine (r5=0)? - beq __error_a @ yes, error 'a' adr lr, BSYM(__after_proc_init) @ return (PIC) address ARM( add pc, r10, #PROCINFO_INITFUNC ) diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index f06ff9feb0d..a5e5c5b9b48 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.S @@ -26,14 +26,6 @@ #include <mach/debug-macro.S> #endif -#if (PHYS_OFFSET & 0x001fffff) -#error "PHYS_OFFSET must be at an even 2MiB boundary!" -#endif - -#define KERNEL_RAM_VADDR (PAGE_OFFSET + TEXT_OFFSET) -#define KERNEL_RAM_PADDR (PHYS_OFFSET + TEXT_OFFSET) - - /* * swapper_pg_dir is the virtual address of the initial page table. * We place the page tables 16K below KERNEL_RAM_VADDR. Therefore, we must @@ -41,6 +33,7 @@ * the least significant 16 bits to be 0x8000, but we could probably * relax this restriction to KERNEL_RAM_VADDR >= PAGE_OFFSET + 0x4000. */ +#define KERNEL_RAM_VADDR (PAGE_OFFSET + TEXT_OFFSET) #if (KERNEL_RAM_VADDR & 0xffff) != 0x8000 #error KERNEL_RAM_VADDR must start at 0xXXXX8000 #endif @@ -48,8 +41,8 @@ .globl swapper_pg_dir .equ swapper_pg_dir, KERNEL_RAM_VADDR - 0x4000 - .macro pgtbl, rd - ldr \rd, =(KERNEL_RAM_PADDR - 0x4000) + .macro pgtbl, rd, phys + add \rd, \phys, #TEXT_OFFSET - 0x4000 .endm #ifdef CONFIG_XIP_KERNEL @@ -66,7 +59,7 @@ * * This is normally called from the decompressor code. The requirements * are: MMU = off, D-cache = off, I-cache = dont care, r0 = 0, - * r1 = machine nr, r2 = atags pointer. + * r1 = machine nr, r2 = atags or dtb pointer. * * This code is mostly position independent, so if you link the kernel at * 0xc0008000, you call this at __pa(0xc0008000). @@ -87,25 +80,33 @@ ENTRY(stext) movs r10, r5 @ invalid processor (r5=0)? THUMB( it eq ) @ force fixup-able long branch encoding beq __error_p @ yes, error 'p' - bl __lookup_machine_type @ r5=machinfo - movs r8, r5 @ invalid machine (r5=0)? - THUMB( it eq ) @ force fixup-able long branch encoding - beq __error_a @ yes, error 'a' + +#ifndef CONFIG_XIP_KERNEL + adr r3, 2f + ldmia r3, {r4, r8} + sub r4, r3, r4 @ (PHYS_OFFSET - PAGE_OFFSET) + add r8, r8, r4 @ PHYS_OFFSET +#else + ldr r8, =PLAT_PHYS_OFFSET +#endif /* - * r1 = machine no, r2 = atags, - * r8 = machinfo, r9 = cpuid, r10 = procinfo + * r1 = machine no, r2 = atags or dtb, + * r8 = phys_offset, r9 = cpuid, r10 = procinfo */ bl __vet_atags #ifdef CONFIG_SMP_ON_UP bl __fixup_smp #endif +#ifdef CONFIG_ARM_PATCH_PHYS_VIRT + bl __fixup_pv_table +#endif bl __create_page_tables /* * The following calls CPU specific code in a position independent * manner. See arch/arm/mm/proc-*.S for details. r10 = base of - * xxx_proc_info structure selected by __lookup_machine_type + * xxx_proc_info structure selected by __lookup_processor_type * above. On return, the CPU will be ready for the MMU to be * turned on, and r0 will hold the CPU control register value. */ @@ -118,22 +119,24 @@ ENTRY(stext) 1: b __enable_mmu ENDPROC(stext) .ltorg +#ifndef CONFIG_XIP_KERNEL +2: .long . + .long PAGE_OFFSET +#endif /* * Setup the initial page tables. We only setup the barest * amount which are required to get the kernel running, which * generally means mapping in the kernel code. * - * r8 = machinfo - * r9 = cpuid - * r10 = procinfo + * r8 = phys_offset, r9 = cpuid, r10 = procinfo * * Returns: * r0, r3, r5-r7 corrupted * r4 = physical page table address */ __create_page_tables: - pgtbl r4 @ page table address + pgtbl r4, r8 @ page table address /* * Clear the 16K level 1 swapper page table @@ -189,10 +192,8 @@ __create_page_tables: /* * Map some ram to cover our .data and .bss areas. */ - orr r3, r7, #(KERNEL_RAM_PADDR & 0xff000000) - .if (KERNEL_RAM_PADDR & 0x00f00000) - orr r3, r3, #(KERNEL_RAM_PADDR & 0x00f00000) - .endif + add r3, r8, #TEXT_OFFSET + orr r3, r3, r7 add r0, r4, #(KERNEL_RAM_VADDR & 0xff000000) >> 18 str r3, [r0, #(KERNEL_RAM_VADDR & 0x00f00000) >> 18]! ldr r6, =(_end - 1) @@ -205,14 +206,17 @@ __create_page_tables: #endif /* - * Then map first 1MB of ram in case it contains our boot params. + * Then map boot params address in r2 or + * the first 1MB of ram if boot params address is not specified. */ - add r0, r4, #PAGE_OFFSET >> 18 - orr r6, r7, #(PHYS_OFFSET & 0xff000000) - .if (PHYS_OFFSET & 0x00f00000) - orr r6, r6, #(PHYS_OFFSET & 0x00f00000) - .endif - str r6, [r0] + mov r0, r2, lsr #20 + movs r0, r0, lsl #20 + moveq r0, r8 + sub r3, r0, r8 + add r3, r3, #PAGE_OFFSET + add r3, r4, r3, lsr #18 + orr r6, r7, r0 + str r6, [r3] #ifdef CONFIG_DEBUG_LL #ifndef CONFIG_DEBUG_ICEDCC @@ -335,7 +339,7 @@ __secondary_data: * * r0 = cp#15 control register * r1 = machine ID - * r2 = atags pointer + * r2 = atags or dtb pointer * r4 = page table pointer * r9 = processor ID * r13 = *virtual* address to jump to upon completion @@ -372,7 +376,7 @@ ENDPROC(__enable_mmu) * * r0 = cp#15 control register * r1 = machine ID - * r2 = atags pointer + * r2 = atags or dtb pointer * r9 = processor ID * r13 = *virtual* address to jump to upon completion * @@ -457,4 +461,129 @@ ENTRY(fixup_smp) ldmfd sp!, {r4 - r6, pc} ENDPROC(fixup_smp) +#ifdef CONFIG_ARM_PATCH_PHYS_VIRT + +/* __fixup_pv_table - patch the stub instructions with the delta between + * PHYS_OFFSET and PAGE_OFFSET, which is assumed to be 16MiB aligned and + * can be expressed by an immediate shifter operand. The stub instruction + * has a form of '(add|sub) rd, rn, #imm'. + */ + __HEAD +__fixup_pv_table: + adr r0, 1f + ldmia r0, {r3-r5, r7} + sub r3, r0, r3 @ PHYS_OFFSET - PAGE_OFFSET + add r4, r4, r3 @ adjust table start address + add r5, r5, r3 @ adjust table end address + add r7, r7, r3 @ adjust __pv_phys_offset address + str r8, [r7] @ save computed PHYS_OFFSET to __pv_phys_offset +#ifndef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT + mov r6, r3, lsr #24 @ constant for add/sub instructions + teq r3, r6, lsl #24 @ must be 16MiB aligned +#else + mov r6, r3, lsr #16 @ constant for add/sub instructions + teq r3, r6, lsl #16 @ must be 64kiB aligned +#endif +THUMB( it ne @ cross section branch ) + bne __error + str r6, [r7, #4] @ save to __pv_offset + b __fixup_a_pv_table +ENDPROC(__fixup_pv_table) + + .align +1: .long . + .long __pv_table_begin + .long __pv_table_end +2: .long __pv_phys_offset + + .text +__fixup_a_pv_table: +#ifdef CONFIG_THUMB2_KERNEL +#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT + lsls r0, r6, #24 + lsr r6, #8 + beq 1f + clz r7, r0 + lsr r0, #24 + lsl r0, r7 + bic r0, 0x0080 + lsrs r7, #1 + orrcs r0, #0x0080 + orr r0, r0, r7, lsl #12 +#endif +1: lsls r6, #24 + beq 4f + clz r7, r6 + lsr r6, #24 + lsl r6, r7 + bic r6, #0x0080 + lsrs r7, #1 + orrcs r6, #0x0080 + orr r6, r6, r7, lsl #12 + orr r6, #0x4000 + b 4f +2: @ at this point the C flag is always clear + add r7, r3 +#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT + ldrh ip, [r7] + tst ip, 0x0400 @ the i bit tells us LS or MS byte + beq 3f + cmp r0, #0 @ set C flag, and ... + biceq ip, 0x0400 @ immediate zero value has a special encoding + streqh ip, [r7] @ that requires the i bit cleared +#endif +3: ldrh ip, [r7, #2] + and ip, 0x8f00 + orrcc ip, r6 @ mask in offset bits 31-24 + orrcs ip, r0 @ mask in offset bits 23-16 + strh ip, [r7, #2] +4: cmp r4, r5 + ldrcc r7, [r4], #4 @ use branch for delay slot + bcc 2b + bx lr +#else +#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT + and r0, r6, #255 @ offset bits 23-16 + mov r6, r6, lsr #8 @ offset bits 31-24 +#else + mov r0, #0 @ just in case... +#endif + b 3f +2: ldr ip, [r7, r3] + bic ip, ip, #0x000000ff + tst ip, #0x400 @ rotate shift tells us LS or MS byte + orrne ip, ip, r6 @ mask in offset bits 31-24 + orreq ip, ip, r0 @ mask in offset bits 23-16 + str ip, [r7, r3] +3: cmp r4, r5 + ldrcc r7, [r4], #4 @ use branch for delay slot + bcc 2b + mov pc, lr +#endif +ENDPROC(__fixup_a_pv_table) + +ENTRY(fixup_pv_table) + stmfd sp!, {r4 - r7, lr} + ldr r2, 2f @ get address of __pv_phys_offset + mov r3, #0 @ no offset + mov r4, r0 @ r0 = table start + add r5, r0, r1 @ r1 = table size + ldr r6, [r2, #4] @ get __pv_offset + bl __fixup_a_pv_table + ldmfd sp!, {r4 - r7, pc} +ENDPROC(fixup_pv_table) + + .align +2: .long __pv_phys_offset + + .data + .globl __pv_phys_offset + .type __pv_phys_offset, %object +__pv_phys_offset: + .long 0 + .size __pv_phys_offset, . - __pv_phys_offset +__pv_offset: + .long 0 +#endif + #include "head-common.S" diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c index d600bd35070..44b84fe6e1b 100644 --- a/arch/arm/kernel/hw_breakpoint.c +++ b/arch/arm/kernel/hw_breakpoint.c @@ -836,9 +836,11 @@ static int hw_breakpoint_pending(unsigned long addr, unsigned int fsr, /* * One-time initialisation. */ -static void reset_ctrl_regs(void *unused) +static void reset_ctrl_regs(void *info) { - int i; + int i, cpu = smp_processor_id(); + u32 dbg_power; + cpumask_t *cpumask = info; /* * v7 debug contains save and restore registers so that debug state @@ -850,6 +852,17 @@ static void reset_ctrl_regs(void *unused) */ if (debug_arch >= ARM_DEBUG_ARCH_V7_ECP14) { /* + * Ensure sticky power-down is clear (i.e. debug logic is + * powered up). + */ + asm volatile("mrc p14, 0, %0, c1, c5, 4" : "=r" (dbg_power)); + if ((dbg_power & 0x1) == 0) { + pr_warning("CPU %d debug is powered down!\n", cpu); + cpumask_or(cpumask, cpumask, cpumask_of(cpu)); + return; + } + + /* * Unconditionally clear the lock by writing a value * other than 0xC5ACCE55 to the access register. */ @@ -887,6 +900,7 @@ static struct notifier_block __cpuinitdata dbg_reset_nb = { static int __init arch_hw_breakpoint_init(void) { u32 dscr; + cpumask_t cpumask = { CPU_BITS_NONE }; debug_arch = get_debug_arch(); @@ -911,7 +925,13 @@ static int __init arch_hw_breakpoint_init(void) * Reset the breakpoint resources. We assume that a halting * debugger will leave the world in a nice state for us. */ - on_each_cpu(reset_ctrl_regs, NULL, 1); + on_each_cpu(reset_ctrl_regs, &cpumask, 1); + if (!cpumask_empty(&cpumask)) { + core_num_brps = 0; + core_num_reserved_brps = 0; + core_num_wrps = 0; + return 0; + } ARM_DBG_READ(c1, 0, dscr); if (dscr & ARM_DSCR_HDBGEN) { diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c index 28536e352de..3535d3793e6 100644 --- a/arch/arm/kernel/irq.c +++ b/arch/arm/kernel/irq.c @@ -179,14 +179,21 @@ int __init arch_probe_nr_irqs(void) #ifdef CONFIG_HOTPLUG_CPU -static void route_irq(struct irq_desc *desc, unsigned int irq, unsigned int cpu) +static bool migrate_one_irq(struct irq_data *d) { - pr_debug("IRQ%u: moving from cpu%u to cpu%u\n", irq, desc->irq_data.node, cpu); + unsigned int cpu = cpumask_any_and(d->affinity, cpu_online_mask); + bool ret = false; - raw_spin_lock_irq(&desc->lock); - desc->irq_data.chip->irq_set_affinity(&desc->irq_data, - cpumask_of(cpu), false); - raw_spin_unlock_irq(&desc->lock); + if (cpu >= nr_cpu_ids) { + cpu = cpumask_any(cpu_online_mask); + ret = true; + } + + pr_debug("IRQ%u: moving from cpu%u to cpu%u\n", d->irq, d->node, cpu); + + d->chip->irq_set_affinity(d, cpumask_of(cpu), true); + + return ret; } /* @@ -198,25 +205,30 @@ void migrate_irqs(void) { unsigned int i, cpu = smp_processor_id(); struct irq_desc *desc; + unsigned long flags; + + local_irq_save(flags); for_each_irq_desc(i, desc) { struct irq_data *d = &desc->irq_data; + bool affinity_broken = false; - if (d->node == cpu) { - unsigned int newcpu = cpumask_any_and(d->affinity, - cpu_online_mask); - if (newcpu >= nr_cpu_ids) { - if (printk_ratelimit()) - printk(KERN_INFO "IRQ%u no longer affine to CPU%u\n", - i, cpu); + raw_spin_lock(&desc->lock); + do { + if (desc->action == NULL) + break; - cpumask_setall(d->affinity); - newcpu = cpumask_any_and(d->affinity, - cpu_online_mask); - } + if (d->node != cpu) + break; - route_irq(desc, i, newcpu); - } + affinity_broken = migrate_one_irq(d); + } while (0); + raw_spin_unlock(&desc->lock); + + if (affinity_broken && printk_ratelimit()) + pr_warning("IRQ%u no longer affine to CPU%u\n", i, cpu); } + + local_irq_restore(flags); } #endif /* CONFIG_HOTPLUG_CPU */ diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c index 6d4105e6872..fee7c36349e 100644 --- a/arch/arm/kernel/module.c +++ b/arch/arm/kernel/module.c @@ -76,6 +76,7 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, for (i = 0; i < relsec->sh_size / sizeof(Elf32_Rel); i++, rel++) { unsigned long loc; Elf32_Sym *sym; + const char *symname; s32 offset; #ifdef CONFIG_THUMB2_KERNEL u32 upper, lower, sign, j1, j2; @@ -83,18 +84,18 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, offset = ELF32_R_SYM(rel->r_info); if (offset < 0 || offset > (symsec->sh_size / sizeof(Elf32_Sym))) { - printk(KERN_ERR "%s: bad relocation, section %d reloc %d\n", + pr_err("%s: section %u reloc %u: bad relocation sym offset\n", module->name, relindex, i); return -ENOEXEC; } sym = ((Elf32_Sym *)symsec->sh_addr) + offset; + symname = strtab + sym->st_name; if (rel->r_offset < 0 || rel->r_offset > dstsec->sh_size - sizeof(u32)) { - printk(KERN_ERR "%s: out of bounds relocation, " - "section %d reloc %d offset %d size %d\n", - module->name, relindex, i, rel->r_offset, - dstsec->sh_size); + pr_err("%s: section %u reloc %u sym '%s': out of bounds relocation, offset %d size %u\n", + module->name, relindex, i, symname, + rel->r_offset, dstsec->sh_size); return -ENOEXEC; } @@ -120,10 +121,10 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, if (offset & 3 || offset <= (s32)0xfe000000 || offset >= (s32)0x02000000) { - printk(KERN_ERR - "%s: relocation out of range, section " - "%d reloc %d sym '%s'\n", module->name, - relindex, i, strtab + sym->st_name); + pr_err("%s: section %u reloc %u sym '%s': relocation %u out of range (%#lx -> %#x)\n", + module->name, relindex, i, symname, + ELF32_R_TYPE(rel->r_info), loc, + sym->st_value); return -ENOEXEC; } @@ -196,10 +197,10 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, if (!(offset & 1) || offset <= (s32)0xff000000 || offset >= (s32)0x01000000) { - printk(KERN_ERR - "%s: relocation out of range, section " - "%d reloc %d sym '%s'\n", module->name, - relindex, i, strtab + sym->st_name); + pr_err("%s: section %u reloc %u sym '%s': relocation %u out of range (%#lx -> %#x)\n", + module->name, relindex, i, symname, + ELF32_R_TYPE(rel->r_info), loc, + sym->st_value); return -ENOEXEC; } @@ -282,12 +283,13 @@ static const Elf_Shdr *find_mod_section(const Elf32_Ehdr *hdr, return NULL; } +extern void fixup_pv_table(const void *, unsigned long); extern void fixup_smp(const void *, unsigned long); int module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs, struct module *mod) { - const Elf_Shdr * __maybe_unused s = NULL; + const Elf_Shdr *s = NULL; #ifdef CONFIG_ARM_UNWIND const char *secstrs = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; const Elf_Shdr *sechdrs_end = sechdrs + hdr->e_shnum; @@ -332,6 +334,11 @@ int module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs, maps[i].txt_sec->sh_addr, maps[i].txt_sec->sh_size); #endif +#ifdef CONFIG_ARM_PATCH_PHYS_VIRT + s = find_mod_section(hdr, sechdrs, ".pv_table"); + if (s) + fixup_pv_table((void *)s->sh_addr, s->sh_size); +#endif s = find_mod_section(hdr, sechdrs, ".alt.smp.init"); if (s && !is_smp()) fixup_smp((void *)s->sh_addr, s->sh_size); diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c index d150ad1ccb5..22e194eb853 100644 --- a/arch/arm/kernel/perf_event.c +++ b/arch/arm/kernel/perf_event.c @@ -377,9 +377,18 @@ validate_group(struct perf_event *event) return 0; } +static irqreturn_t armpmu_platform_irq(int irq, void *dev) +{ + struct arm_pmu_platdata *plat = dev_get_platdata(&pmu_device->dev); + + return plat->handle_irq(irq, dev, armpmu->handle_irq); +} + static int armpmu_reserve_hardware(void) { + struct arm_pmu_platdata *plat; + irq_handler_t handle_irq; int i, err = -ENODEV, irq; pmu_device = reserve_pmu(ARM_PMU_DEVICE_CPU); @@ -390,6 +399,12 @@ armpmu_reserve_hardware(void) init_pmu(ARM_PMU_DEVICE_CPU); + plat = dev_get_platdata(&pmu_device->dev); + if (plat && plat->handle_irq) + handle_irq = armpmu_platform_irq; + else + handle_irq = armpmu->handle_irq; + if (pmu_device->num_resources < 1) { pr_err("no irqs for PMUs defined\n"); return -ENODEV; @@ -400,7 +415,7 @@ armpmu_reserve_hardware(void) if (irq < 0) continue; - err = request_irq(irq, armpmu->handle_irq, + err = request_irq(irq, handle_irq, IRQF_DISABLED | IRQF_NOBALANCING, "armpmu", NULL); if (err) { diff --git a/arch/arm/kernel/perf_event_v6.c b/arch/arm/kernel/perf_event_v6.c index c058bfc8532..6fc2d228db5 100644 --- a/arch/arm/kernel/perf_event_v6.c +++ b/arch/arm/kernel/perf_event_v6.c @@ -30,7 +30,7 @@ * enable the interrupt. */ -#ifdef CONFIG_CPU_V6 +#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K) enum armv6_perf_types { ARMV6_PERFCTR_ICACHE_MISS = 0x0, ARMV6_PERFCTR_IBUF_STALL = 0x1, @@ -669,4 +669,4 @@ static const struct arm_pmu *__init armv6mpcore_pmu_init(void) { return NULL; } -#endif /* CONFIG_CPU_V6 */ +#endif /* CONFIG_CPU_V6 || CONFIG_CPU_V6K */ diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c index 19c6816db61..2bf27f364d0 100644 --- a/arch/arm/kernel/ptrace.c +++ b/arch/arm/kernel/ptrace.c @@ -26,8 +26,6 @@ #include <asm/system.h> #include <asm/traps.h> -#include "ptrace.h" - #define REG_PC 15 #define REG_PSR 16 /* @@ -184,389 +182,12 @@ put_user_reg(struct task_struct *task, int offset, long data) return ret; } -static inline int -read_u32(struct task_struct *task, unsigned long addr, u32 *res) -{ - int ret; - - ret = access_process_vm(task, addr, res, sizeof(*res), 0); - - return ret == sizeof(*res) ? 0 : -EIO; -} - -static inline int -read_instr(struct task_struct *task, unsigned long addr, u32 *res) -{ - int ret; - - if (addr & 1) { - u16 val; - ret = access_process_vm(task, addr & ~1, &val, sizeof(val), 0); - ret = ret == sizeof(val) ? 0 : -EIO; - *res = val; - } else { - u32 val; - ret = access_process_vm(task, addr & ~3, &val, sizeof(val), 0); - ret = ret == sizeof(val) ? 0 : -EIO; - *res = val; - } - return ret; -} - -/* - * Get value of register `rn' (in the instruction) - */ -static unsigned long -ptrace_getrn(struct task_struct *child, unsigned long insn) -{ - unsigned int reg = (insn >> 16) & 15; - unsigned long val; - - val = get_user_reg(child, reg); - if (reg == 15) - val += 8; - - return val; -} - -/* - * Get value of operand 2 (in an ALU instruction) - */ -static unsigned long -ptrace_getaluop2(struct task_struct *child, unsigned long insn) -{ - unsigned long val; - int shift; - int type; - - if (insn & 1 << 25) { - val = insn & 255; - shift = (insn >> 8) & 15; - type = 3; - } else { - val = get_user_reg (child, insn & 15); - - if (insn & (1 << 4)) - shift = (int)get_user_reg (child, (insn >> 8) & 15); - else - shift = (insn >> 7) & 31; - - type = (insn >> 5) & 3; - } - - switch (type) { - case 0: val <<= shift; break; - case 1: val >>= shift; break; - case 2: - val = (((signed long)val) >> shift); - break; - case 3: - val = (val >> shift) | (val << (32 - shift)); - break; - } - return val; -} - -/* - * Get value of operand 2 (in a LDR instruction) - */ -static unsigned long -ptrace_getldrop2(struct task_struct *child, unsigned long insn) -{ - unsigned long val; - int shift; - int type; - - val = get_user_reg(child, insn & 15); - shift = (insn >> 7) & 31; - type = (insn >> 5) & 3; - - switch (type) { - case 0: val <<= shift; break; - case 1: val >>= shift; break; - case 2: - val = (((signed long)val) >> shift); - break; - case 3: - val = (val >> shift) | (val << (32 - shift)); - break; - } - return val; -} - -#define OP_MASK 0x01e00000 -#define OP_AND 0x00000000 -#define OP_EOR 0x00200000 -#define OP_SUB 0x00400000 -#define OP_RSB 0x00600000 -#define OP_ADD 0x00800000 -#define OP_ADC 0x00a00000 -#define OP_SBC 0x00c00000 -#define OP_RSC 0x00e00000 -#define OP_ORR 0x01800000 -#define OP_MOV 0x01a00000 -#define OP_BIC 0x01c00000 -#define OP_MVN 0x01e00000 - -static unsigned long -get_branch_address(struct task_struct *child, unsigned long pc, unsigned long insn) -{ - u32 alt = 0; - - switch (insn & 0x0e000000) { - case 0x00000000: - case 0x02000000: { - /* - * data processing - */ - long aluop1, aluop2, ccbit; - - if ((insn & 0x0fffffd0) == 0x012fff10) { - /* - * bx or blx - */ - alt = get_user_reg(child, insn & 15); - break; - } - - - if ((insn & 0xf000) != 0xf000) - break; - - aluop1 = ptrace_getrn(child, insn); - aluop2 = ptrace_getaluop2(child, insn); - ccbit = get_user_reg(child, REG_PSR) & PSR_C_BIT ? 1 : 0; - - switch (insn & OP_MASK) { - case OP_AND: alt = aluop1 & aluop2; break; - case OP_EOR: alt = aluop1 ^ aluop2; break; - case OP_SUB: alt = aluop1 - aluop2; break; - case OP_RSB: alt = aluop2 - aluop1; break; - case OP_ADD: alt = aluop1 + aluop2; break; - case OP_ADC: alt = aluop1 + aluop2 + ccbit; break; - case OP_SBC: alt = aluop1 - aluop2 + ccbit; break; - case OP_RSC: alt = aluop2 - aluop1 + ccbit; break; - case OP_ORR: alt = aluop1 | aluop2; break; - case OP_MOV: alt = aluop2; break; - case OP_BIC: alt = aluop1 & ~aluop2; break; - case OP_MVN: alt = ~aluop2; break; - } - break; - } - - case 0x04000000: - case 0x06000000: - /* - * ldr - */ - if ((insn & 0x0010f000) == 0x0010f000) { - unsigned long base; - - base = ptrace_getrn(child, insn); - if (insn & 1 << 24) { - long aluop2; - - if (insn & 0x02000000) - aluop2 = ptrace_getldrop2(child, insn); - else - aluop2 = insn & 0xfff; - - if (insn & 1 << 23) - base += aluop2; - else - base -= aluop2; - } - read_u32(child, base, &alt); - } - break; - - case 0x08000000: - /* - * ldm - */ - if ((insn & 0x00108000) == 0x00108000) { - unsigned long base; - unsigned int nr_regs; - - if (insn & (1 << 23)) { - nr_regs = hweight16(insn & 65535) << 2; - - if (!(insn & (1 << 24))) - nr_regs -= 4; - } else { - if (insn & (1 << 24)) - nr_regs = -4; - else - nr_regs = 0; - } - - base = ptrace_getrn(child, insn); - - read_u32(child, base + nr_regs, &alt); - break; - } - break; - - case 0x0a000000: { - /* - * bl or b - */ - signed long displ; - /* It's a branch/branch link: instead of trying to - * figure out whether the branch will be taken or not, - * we'll put a breakpoint at both locations. This is - * simpler, more reliable, and probably not a whole lot - * slower than the alternative approach of emulating the - * branch. - */ - displ = (insn & 0x00ffffff) << 8; - displ = (displ >> 6) + 8; - if (displ != 0 && displ != 4) - alt = pc + displ; - } - break; - } - - return alt; -} - -static int -swap_insn(struct task_struct *task, unsigned long addr, - void *old_insn, void *new_insn, int size) -{ - int ret; - - ret = access_process_vm(task, addr, old_insn, size, 0); - if (ret == size) - ret = access_process_vm(task, addr, new_insn, size, 1); - return ret; -} - -static void -add_breakpoint(struct task_struct *task, struct debug_info *dbg, unsigned long addr) -{ - int nr = dbg->nsaved; - - if (nr < 2) { - u32 new_insn = BREAKINST_ARM; - int res; - - res = swap_insn(task, addr, &dbg->bp[nr].insn, &new_insn, 4); - - if (res == 4) { - dbg->bp[nr].address = addr; - dbg->nsaved += 1; - } - } else - printk(KERN_ERR "ptrace: too many breakpoints\n"); -} - -/* - * Clear one breakpoint in the user program. We copy what the hardware - * does and use bit 0 of the address to indicate whether this is a Thumb - * breakpoint or an ARM breakpoint. - */ -static void clear_breakpoint(struct task_struct *task, struct debug_entry *bp) -{ - unsigned long addr = bp->address; - union debug_insn old_insn; - int ret; - - if (addr & 1) { - ret = swap_insn(task, addr & ~1, &old_insn.thumb, - &bp->insn.thumb, 2); - - if (ret != 2 || old_insn.thumb != BREAKINST_THUMB) - printk(KERN_ERR "%s:%d: corrupted Thumb breakpoint at " - "0x%08lx (0x%04x)\n", task->comm, - task_pid_nr(task), addr, old_insn.thumb); - } else { - ret = swap_insn(task, addr & ~3, &old_insn.arm, - &bp->insn.arm, 4); - - if (ret != 4 || old_insn.arm != BREAKINST_ARM) - printk(KERN_ERR "%s:%d: corrupted ARM breakpoint at " - "0x%08lx (0x%08x)\n", task->comm, - task_pid_nr(task), addr, old_insn.arm); - } -} - -void ptrace_set_bpt(struct task_struct *child) -{ - struct pt_regs *regs; - unsigned long pc; - u32 insn; - int res; - - regs = task_pt_regs(child); - pc = instruction_pointer(regs); - - if (thumb_mode(regs)) { - printk(KERN_WARNING "ptrace: can't handle thumb mode\n"); - return; - } - - res = read_instr(child, pc, &insn); - if (!res) { - struct debug_info *dbg = &child->thread.debug; - unsigned long alt; - - dbg->nsaved = 0; - - alt = get_branch_address(child, pc, insn); - if (alt) - add_breakpoint(child, dbg, alt); - - /* - * Note that we ignore the result of setting the above - * breakpoint since it may fail. When it does, this is - * not so much an error, but a forewarning that we may - * be receiving a prefetch abort shortly. - * - * If we don't set this breakpoint here, then we can - * lose control of the thread during single stepping. - */ - if (!alt || predicate(insn) != PREDICATE_ALWAYS) - add_breakpoint(child, dbg, pc + 4); - } -} - -/* - * Ensure no single-step breakpoint is pending. Returns non-zero - * value if child was being single-stepped. - */ -void ptrace_cancel_bpt(struct task_struct *child) -{ - int i, nsaved = child->thread.debug.nsaved; - - child->thread.debug.nsaved = 0; - - if (nsaved > 2) { - printk("ptrace_cancel_bpt: bogus nsaved: %d!\n", nsaved); - nsaved = 2; - } - - for (i = 0; i < nsaved; i++) - clear_breakpoint(child, &child->thread.debug.bp[i]); -} - -void user_disable_single_step(struct task_struct *task) -{ - task->ptrace &= ~PT_SINGLESTEP; - ptrace_cancel_bpt(task); -} - -void user_enable_single_step(struct task_struct *task) -{ - task->ptrace |= PT_SINGLESTEP; -} - /* * Called by kernel/ptrace.c when detaching.. */ void ptrace_disable(struct task_struct *child) { - user_disable_single_step(child); + /* Nothing to do. */ } /* @@ -576,8 +197,6 @@ void ptrace_break(struct task_struct *tsk, struct pt_regs *regs) { siginfo_t info; - ptrace_cancel_bpt(tsk); - info.si_signo = SIGTRAP; info.si_errno = 0; info.si_code = TRAP_BRKPT; @@ -996,10 +615,10 @@ static int ptrace_gethbpregs(struct task_struct *tsk, long num, while (!(arch_ctrl.len & 0x1)) arch_ctrl.len >>= 1; - if (idx & 0x1) - reg = encode_ctrl_reg(arch_ctrl); - else + if (num & 0x1) reg = bp->attr.bp_addr; + else + reg = encode_ctrl_reg(arch_ctrl); } put: diff --git a/arch/arm/kernel/ptrace.h b/arch/arm/kernel/ptrace.h deleted file mode 100644 index 3926605b82e..00000000000 --- a/arch/arm/kernel/ptrace.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * linux/arch/arm/kernel/ptrace.h - * - * Copyright (C) 2000-2003 Russell King - * - * 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/ptrace.h> - -extern void ptrace_cancel_bpt(struct task_struct *); -extern void ptrace_set_bpt(struct task_struct *); -extern void ptrace_break(struct task_struct *, struct pt_regs *); - -/* - * Send SIGTRAP if we're single-stepping - */ -static inline void single_step_trap(struct task_struct *task) -{ - if (task->ptrace & PT_SINGLESTEP) { - ptrace_cancel_bpt(task); - send_sig(SIGTRAP, task, 1); - } -} - -static inline void single_step_clear(struct task_struct *task) -{ - if (task->ptrace & PT_SINGLESTEP) - ptrace_cancel_bpt(task); -} - -static inline void single_step_set(struct task_struct *task) -{ - if (task->ptrace & PT_SINGLESTEP) - ptrace_set_bpt(task); -} diff --git a/arch/arm/kernel/relocate_kernel.S b/arch/arm/kernel/relocate_kernel.S index 9cf4cbf8f95..a2599e7e151 100644 --- a/arch/arm/kernel/relocate_kernel.S +++ b/arch/arm/kernel/relocate_kernel.S @@ -7,8 +7,8 @@ .globl relocate_new_kernel relocate_new_kernel: - ldr r0,kexec_indirection_page - ldr r1,kexec_start_address + ldr r0,__kexec_indirection_page + ldr r1,__kexec_start_address /* * If there is no indirection page (we are doing crashdumps) @@ -55,27 +55,31 @@ relocate_new_kernel: /* Jump to relocated kernel */ mov lr,r1 mov r0,#0 - ldr r1,kexec_mach_type - ldr r2,kexec_boot_atags + ldr r1,__kexec_mach_type + ldr r2,__kexec_boot_atags mov pc,lr .align .globl kexec_start_address kexec_start_address: +__kexec_start_address: .long 0x0 .globl kexec_indirection_page kexec_indirection_page: +__kexec_indirection_page: .long 0x0 .globl kexec_mach_type kexec_mach_type: +__kexec_mach_type: .long 0x0 /* phy addr of the atags for the new kernel */ .globl kexec_boot_atags kexec_boot_atags: +__kexec_boot_atags: .long 0x0 relocate_new_kernel_end: diff --git a/arch/arm/kernel/return_address.c b/arch/arm/kernel/return_address.c index df246da4cec..0b13a72f855 100644 --- a/arch/arm/kernel/return_address.c +++ b/arch/arm/kernel/return_address.c @@ -9,6 +9,7 @@ * the Free Software Foundation. */ #include <linux/module.h> +#include <linux/ftrace.h> #if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND) #include <linux/sched.h> diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 5ea4fb718b9..319199b0ab2 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -20,6 +20,7 @@ #include <linux/screen_info.h> #include <linux/init.h> #include <linux/kexec.h> +#include <linux/of_fdt.h> #include <linux/crash_dump.h> #include <linux/root_dev.h> #include <linux/cpu.h> @@ -42,6 +43,7 @@ #include <asm/cachetype.h> #include <asm/tlbflush.h> +#include <asm/prom.h> #include <asm/mach/arch.h> #include <asm/mach/irq.h> #include <asm/mach/time.h> @@ -125,7 +127,7 @@ EXPORT_SYMBOL(elf_platform); static const char *cpu_name; static const char *machine_name; -static char __initdata cmd_line[COMMAND_LINE_SIZE]; +char cmd_line[COMMAND_LINE_SIZE]; struct machine_desc *machine_desc __initdata; static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE; @@ -308,7 +310,22 @@ static void __init cacheid_init(void) * already provide the required functionality. */ extern struct proc_info_list *lookup_processor_type(unsigned int); -extern struct machine_desc *lookup_machine_type(unsigned int); + +void __init early_print(const char *str, ...) +{ + extern void printascii(const char *); + char buf[256]; + va_list ap; + + va_start(ap, str); + vsnprintf(buf, sizeof(buf), str, ap); + va_end(ap); + +#ifdef CONFIG_DEBUG_LL + printascii(buf); +#endif + printk("%s", buf); +} static void __init feat_v6_fixup(void) { @@ -424,26 +441,21 @@ void cpu_init(void) : "r14"); } -static struct machine_desc * __init setup_machine(unsigned int nr) +void __init dump_machine_table(void) { - struct machine_desc *list; + struct machine_desc *p; - /* - * locate machine in the list of supported machines. - */ - list = lookup_machine_type(nr); - if (!list) { - printk("Machine configuration botched (nr %d), unable " - "to continue.\n", nr); - while (1); - } + early_print("Available machine support:\n\nID (hex)\tNAME\n"); + for_each_machine_desc(p) + early_print("%08x\t%s\n", p->nr, p->name); - printk("Machine: %s\n", list->name); + early_print("\nPlease check your kernel config and/or bootloader.\n"); - return list; + while (true) + /* can't use cpu_relax() here as it may require MMU setup */; } -static int __init arm_add_memory(unsigned long start, unsigned long size) +int __init arm_add_memory(unsigned long start, unsigned long size) { struct membank *bank = &meminfo.bank[meminfo.nr_banks]; @@ -703,7 +715,7 @@ static struct init_tags { { tag_size(tag_core), ATAG_CORE }, { 1, PAGE_SIZE, 0xff }, { tag_size(tag_mem32), ATAG_MEM }, - { MEM_SIZE, PHYS_OFFSET }, + { MEM_SIZE }, { 0, ATAG_NONE } }; @@ -796,26 +808,51 @@ static void __init squash_mem_tags(struct tag *tag) tag->hdr.tag = ATAG_NONE; } -void __init setup_arch(char **cmdline_p) +static struct machine_desc * __init setup_machine_tags(unsigned int nr) { struct tag *tags = (struct tag *)&init_tags; - struct machine_desc *mdesc; + struct machine_desc *mdesc = NULL, *p; char *from = default_command_line; - unwind_init(); + /* + * locate machine in the list of supported machines. + */ + for_each_machine_desc(p) + if (nr == p->nr) { + printk("Machine: %s\n", p->name); + mdesc = p; + break; + } - setup_processor(); - mdesc = setup_machine(machine_arch_type); - machine_desc = mdesc; - machine_name = mdesc->name; + if (!mdesc) { + early_print("\nError: unrecognized/unsupported machine ID" + " (r1 = 0x%08x).\n\n", nr); + dump_machine_table(); /* does not return */ + } - if (mdesc->soft_reboot) - reboot_setup("s"); + printk("Machine: %s\n", mdesc->name); if (__atags_pointer) tags = phys_to_virt(__atags_pointer); - else if (mdesc->boot_params) - tags = phys_to_virt(mdesc->boot_params); + else if (mdesc->boot_params) { +#ifdef CONFIG_MMU + /* + * We still are executing with a minimal MMU mapping created + * with the presumption that the machine default for this + * is located in the first MB of RAM. Anything else will + * fault and silently hang the kernel at this point. + */ + if (mdesc->boot_params < PHYS_OFFSET || + mdesc->boot_params >= PHYS_OFFSET + SZ_1M) { + printk(KERN_WARNING + "Default boot params at physical 0x%08lx out of reach\n", + mdesc->boot_params); + } else +#endif + { + tags = phys_to_virt(mdesc->boot_params); + } + } #if defined(CONFIG_DEPRECATED_PARAM_STRUCT) /* @@ -838,16 +875,39 @@ void __init setup_arch(char **cmdline_p) parse_tags(tags); } - init_mm.start_code = (unsigned long) _text; - init_mm.end_code = (unsigned long) _etext; - init_mm.end_data = (unsigned long) _edata; - init_mm.brk = (unsigned long) _end; - /* parse_early_param needs a boot_command_line */ strlcpy(boot_command_line, from, COMMAND_LINE_SIZE); /* populate cmd_line too for later use, preserving boot_command_line */ strlcpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE); + + return mdesc; +} + + +void __init setup_arch(char **cmdline_p) +{ + struct machine_desc *mdesc; + + init_tags.mem.start = PHYS_OFFSET; + + unwind_init(); + + setup_processor(); + mdesc = setup_machine_fdt(__atags_pointer); + if (!mdesc) + mdesc = setup_machine_tags(machine_arch_type); + machine_desc = mdesc; + machine_name = mdesc->name; + + if (mdesc->soft_reboot) + reboot_setup("s"); + + init_mm.start_code = (unsigned long) _text; + init_mm.end_code = (unsigned long) _etext; + init_mm.end_data = (unsigned long) _edata; + init_mm.brk = (unsigned long) _end; + *cmdline_p = cmd_line; parse_early_param(); @@ -857,6 +917,8 @@ void __init setup_arch(char **cmdline_p) paging_init(mdesc); request_standard_resources(mdesc); + unflatten_device_tree(); + #ifdef CONFIG_SMP if (is_smp()) smp_init_cpus(); diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c index abaf8445ce2..cb839831764 100644 --- a/arch/arm/kernel/signal.c +++ b/arch/arm/kernel/signal.c @@ -20,7 +20,6 @@ #include <asm/unistd.h> #include <asm/vfp.h> -#include "ptrace.h" #include "signal.h" #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) @@ -348,8 +347,6 @@ asmlinkage int sys_sigreturn(struct pt_regs *regs) if (restore_sigframe(regs, frame)) goto badframe; - single_step_trap(current); - return regs->ARM_r0; badframe: @@ -383,8 +380,6 @@ asmlinkage int sys_rt_sigreturn(struct pt_regs *regs) if (do_sigaltstack(&frame->sig.uc.uc_stack, NULL, regs->ARM_sp) == -EFAULT) goto badframe; - single_step_trap(current); - return regs->ARM_r0; badframe: @@ -706,8 +701,6 @@ static void do_signal(struct pt_regs *regs, int syscall) if (try_to_freeze()) goto no_signal; - single_step_clear(current); - signr = get_signal_to_deliver(&info, &ka, regs, NULL); if (signr > 0) { sigset_t *oldset; @@ -726,7 +719,6 @@ static void do_signal(struct pt_regs *regs, int syscall) if (test_thread_flag(TIF_RESTORE_SIGMASK)) clear_thread_flag(TIF_RESTORE_SIGMASK); } - single_step_set(current); return; } @@ -772,7 +764,6 @@ static void do_signal(struct pt_regs *regs, int syscall) sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); } } - single_step_set(current); } asmlinkage void diff --git a/arch/arm/kernel/tcm.c b/arch/arm/kernel/tcm.c index 26685c2f7a4..f5cf660eefc 100644 --- a/arch/arm/kernel/tcm.c +++ b/arch/arm/kernel/tcm.c @@ -15,7 +15,7 @@ #include <linux/string.h> /* memcpy */ #include <asm/cputype.h> #include <asm/mach/map.h> -#include <mach/memory.h> +#include <asm/memory.h> #include "tcm.h" static struct gen_pool *tcm_pool; diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index ee57640ba2b..21ac43f1c2d 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -23,6 +23,7 @@ #include <linux/kexec.h> #include <linux/delay.h> #include <linux/init.h> +#include <linux/sched.h> #include <asm/atomic.h> #include <asm/cacheflush.h> @@ -32,7 +33,6 @@ #include <asm/unwind.h> #include <asm/tls.h> -#include "ptrace.h" #include "signal.h" static const char *handler[]= { "prefetch abort", "data abort", "address exception", "interrupt" }; @@ -256,7 +256,7 @@ static int __die(const char *str, int err, struct thread_info *thread, struct pt return ret; } -DEFINE_SPINLOCK(die_lock); +static DEFINE_SPINLOCK(die_lock); /* * This function is protected against re-entrancy. diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S index 61462790757..dfbb377e251 100644 --- a/arch/arm/kernel/vmlinux.lds.S +++ b/arch/arm/kernel/vmlinux.lds.S @@ -64,6 +64,10 @@ SECTIONS __smpalt_end = .; #endif + __pv_table_begin = .; + *(.pv_table) + __pv_table_end = .; + INIT_SETUP(16) INIT_CALLS diff --git a/arch/arm/lib/bitops.h b/arch/arm/lib/bitops.h index d42252918bf..10d868a5a48 100644 --- a/arch/arm/lib/bitops.h +++ b/arch/arm/lib/bitops.h @@ -1,44 +1,52 @@ - -#if __LINUX_ARM_ARCH__ >= 6 && defined(CONFIG_CPU_32v6K) +#if __LINUX_ARM_ARCH__ >= 6 .macro bitop, instr + ands ip, r1, #3 + strneb r1, [ip] @ assert word-aligned mov r2, #1 - and r3, r0, #7 @ Get bit offset - add r1, r1, r0, lsr #3 @ Get byte offset + and r3, r0, #31 @ Get bit offset + mov r0, r0, lsr #5 + add r1, r1, r0, lsl #2 @ Get word offset mov r3, r2, lsl r3 -1: ldrexb r2, [r1] +1: ldrex r2, [r1] \instr r2, r2, r3 - strexb r0, r2, [r1] + strex r0, r2, [r1] cmp r0, #0 bne 1b - mov pc, lr + bx lr .endm .macro testop, instr, store - and r3, r0, #7 @ Get bit offset + ands ip, r1, #3 + strneb r1, [ip] @ assert word-aligned mov r2, #1 - add r1, r1, r0, lsr #3 @ Get byte offset + and r3, r0, #31 @ Get bit offset + mov r0, r0, lsr #5 + add r1, r1, r0, lsl #2 @ Get word offset mov r3, r2, lsl r3 @ create mask smp_dmb -1: ldrexb r2, [r1] +1: ldrex r2, [r1] ands r0, r2, r3 @ save old value of bit - \instr r2, r2, r3 @ toggle bit - strexb ip, r2, [r1] + \instr r2, r2, r3 @ toggle bit + strex ip, r2, [r1] cmp ip, #0 bne 1b smp_dmb cmp r0, #0 movne r0, #1 -2: mov pc, lr +2: bx lr .endm #else .macro bitop, instr - and r2, r0, #7 + ands ip, r1, #3 + strneb r1, [ip] @ assert word-aligned + and r2, r0, #31 + mov r0, r0, lsr #5 mov r3, #1 mov r3, r3, lsl r2 save_and_disable_irqs ip - ldrb r2, [r1, r0, lsr #3] + ldr r2, [r1, r0, lsl #2] \instr r2, r2, r3 - strb r2, [r1, r0, lsr #3] + str r2, [r1, r0, lsl #2] restore_irqs ip mov pc, lr .endm @@ -52,11 +60,13 @@ * to avoid dirtying the data cache. */ .macro testop, instr, store - add r1, r1, r0, lsr #3 - and r3, r0, #7 - mov r0, #1 + ands ip, r1, #3 + strneb r1, [ip] @ assert word-aligned + and r3, r0, #31 + mov r0, r0, lsr #5 save_and_disable_irqs ip - ldrb r2, [r1] + ldr r2, [r1, r0, lsl #2]! + mov r0, #1 tst r2, r0, lsl r3 \instr r2, r2, r0, lsl r3 \store r2, [r1] diff --git a/arch/arm/lib/changebit.S b/arch/arm/lib/changebit.S index 80f3115cbee..68ed5b62e83 100644 --- a/arch/arm/lib/changebit.S +++ b/arch/arm/lib/changebit.S @@ -12,12 +12,6 @@ #include "bitops.h" .text -/* Purpose : Function to change a bit - * Prototype: int change_bit(int bit, void *addr) - */ -ENTRY(_change_bit_be) - eor r0, r0, #0x18 @ big endian byte ordering -ENTRY(_change_bit_le) +ENTRY(_change_bit) bitop eor -ENDPROC(_change_bit_be) -ENDPROC(_change_bit_le) +ENDPROC(_change_bit) diff --git a/arch/arm/lib/clearbit.S b/arch/arm/lib/clearbit.S index 1a63e43a1df..4c04c3b51ee 100644 --- a/arch/arm/lib/clearbit.S +++ b/arch/arm/lib/clearbit.S @@ -12,13 +12,6 @@ #include "bitops.h" .text -/* - * Purpose : Function to clear a bit - * Prototype: int clear_bit(int bit, void *addr) - */ -ENTRY(_clear_bit_be) - eor r0, r0, #0x18 @ big endian byte ordering -ENTRY(_clear_bit_le) +ENTRY(_clear_bit) bitop bic -ENDPROC(_clear_bit_be) -ENDPROC(_clear_bit_le) +ENDPROC(_clear_bit) diff --git a/arch/arm/lib/setbit.S b/arch/arm/lib/setbit.S index 1dd7176c4b2..bbee5c66a23 100644 --- a/arch/arm/lib/setbit.S +++ b/arch/arm/lib/setbit.S @@ -12,13 +12,6 @@ #include "bitops.h" .text -/* - * Purpose : Function to set a bit - * Prototype: int set_bit(int bit, void *addr) - */ -ENTRY(_set_bit_be) - eor r0, r0, #0x18 @ big endian byte ordering -ENTRY(_set_bit_le) +ENTRY(_set_bit) bitop orr -ENDPROC(_set_bit_be) -ENDPROC(_set_bit_le) +ENDPROC(_set_bit) diff --git a/arch/arm/lib/testchangebit.S b/arch/arm/lib/testchangebit.S index 5c98dc567f0..15a4d431f22 100644 --- a/arch/arm/lib/testchangebit.S +++ b/arch/arm/lib/testchangebit.S @@ -12,9 +12,6 @@ #include "bitops.h" .text -ENTRY(_test_and_change_bit_be) - eor r0, r0, #0x18 @ big endian byte ordering -ENTRY(_test_and_change_bit_le) - testop eor, strb -ENDPROC(_test_and_change_bit_be) -ENDPROC(_test_and_change_bit_le) +ENTRY(_test_and_change_bit) + testop eor, str +ENDPROC(_test_and_change_bit) diff --git a/arch/arm/lib/testclearbit.S b/arch/arm/lib/testclearbit.S index 543d7094d18..521b66b5b95 100644 --- a/arch/arm/lib/testclearbit.S +++ b/arch/arm/lib/testclearbit.S @@ -12,9 +12,6 @@ #include "bitops.h" .text -ENTRY(_test_and_clear_bit_be) - eor r0, r0, #0x18 @ big endian byte ordering -ENTRY(_test_and_clear_bit_le) - testop bicne, strneb -ENDPROC(_test_and_clear_bit_be) -ENDPROC(_test_and_clear_bit_le) +ENTRY(_test_and_clear_bit) + testop bicne, strne +ENDPROC(_test_and_clear_bit) diff --git a/arch/arm/lib/testsetbit.S b/arch/arm/lib/testsetbit.S index 0b3f390401c..1c98cc2185b 100644 --- a/arch/arm/lib/testsetbit.S +++ b/arch/arm/lib/testsetbit.S @@ -12,9 +12,6 @@ #include "bitops.h" .text -ENTRY(_test_and_set_bit_be) - eor r0, r0, #0x18 @ big endian byte ordering -ENTRY(_test_and_set_bit_le) - testop orreq, streqb -ENDPROC(_test_and_set_bit_be) -ENDPROC(_test_and_set_bit_le) +ENTRY(_test_and_set_bit) + testop orreq, streq +ENDPROC(_test_and_set_bit) diff --git a/arch/arm/mach-aaec2000/include/mach/memory.h b/arch/arm/mach-aaec2000/include/mach/memory.h index 4f93c567a35..4a10bf0bd36 100644 --- a/arch/arm/mach-aaec2000/include/mach/memory.h +++ b/arch/arm/mach-aaec2000/include/mach/memory.h @@ -12,6 +12,6 @@ #define __ASM_ARCH_MEMORY_H -#define PHYS_OFFSET UL(0xf0000000) +#define PLAT_PHYS_OFFSET UL(0xf0000000) #endif /* __ASM_ARCH_MEMORY_H */ diff --git a/arch/arm/mach-at91/include/mach/memory.h b/arch/arm/mach-at91/include/mach/memory.h index 14f4ef4b6a9..c2cfe504064 100644 --- a/arch/arm/mach-at91/include/mach/memory.h +++ b/arch/arm/mach-at91/include/mach/memory.h @@ -23,6 +23,6 @@ #include <mach/hardware.h> -#define PHYS_OFFSET (AT91_SDRAM_BASE) +#define PLAT_PHYS_OFFSET (AT91_SDRAM_BASE) #endif diff --git a/arch/arm/mach-bcmring/include/mach/hardware.h b/arch/arm/mach-bcmring/include/mach/hardware.h index 447eb340c61..8bf3564fba5 100644 --- a/arch/arm/mach-bcmring/include/mach/hardware.h +++ b/arch/arm/mach-bcmring/include/mach/hardware.h @@ -31,7 +31,7 @@ * *_SIZE is the size of the region * *_BASE is the virtual address */ -#define RAM_START PHYS_OFFSET +#define RAM_START PLAT_PHYS_OFFSET #define RAM_SIZE (CFG_GLOBAL_RAM_SIZE-CFG_GLOBAL_RAM_SIZE_RESERVED) #define RAM_BASE PAGE_OFFSET diff --git a/arch/arm/mach-bcmring/include/mach/memory.h b/arch/arm/mach-bcmring/include/mach/memory.h index 114f942bb4f..15162e4c75f 100644 --- a/arch/arm/mach-bcmring/include/mach/memory.h +++ b/arch/arm/mach-bcmring/include/mach/memory.h @@ -23,7 +23,7 @@ * files. Use virt_to_phys/phys_to_virt/__pa/__va instead. */ -#define PHYS_OFFSET CFG_GLOBAL_RAM_BASE +#define PLAT_PHYS_OFFSET CFG_GLOBAL_RAM_BASE /* * Maximum DMA memory allowed is 14M diff --git a/arch/arm/mach-clps711x/include/mach/memory.h b/arch/arm/mach-clps711x/include/mach/memory.h index f45c8e892cb..3a032a67725 100644 --- a/arch/arm/mach-clps711x/include/mach/memory.h +++ b/arch/arm/mach-clps711x/include/mach/memory.h @@ -23,7 +23,7 @@ /* * Physical DRAM offset. */ -#define PHYS_OFFSET UL(0xc0000000) +#define PLAT_PHYS_OFFSET UL(0xc0000000) #if !defined(CONFIG_ARCH_CDB89712) && !defined (CONFIG_ARCH_AUTCPU12) diff --git a/arch/arm/mach-cns3xxx/include/mach/memory.h b/arch/arm/mach-cns3xxx/include/mach/memory.h index 3b6b769b7a2..dc16c5c5d86 100644 --- a/arch/arm/mach-cns3xxx/include/mach/memory.h +++ b/arch/arm/mach-cns3xxx/include/mach/memory.h @@ -13,7 +13,7 @@ /* * Physical DRAM offset. */ -#define PHYS_OFFSET UL(0x00000000) +#define PLAT_PHYS_OFFSET UL(0x00000000) #define __phys_to_bus(x) ((x) + PHYS_OFFSET) #define __bus_to_phys(x) ((x) - PHYS_OFFSET) diff --git a/arch/arm/mach-davinci/include/mach/memory.h b/arch/arm/mach-davinci/include/mach/memory.h index 22eb97c1c30..78822723f38 100644 --- a/arch/arm/mach-davinci/include/mach/memory.h +++ b/arch/arm/mach-davinci/include/mach/memory.h @@ -26,9 +26,9 @@ #if defined(CONFIG_ARCH_DAVINCI_DA8XX) && defined(CONFIG_ARCH_DAVINCI_DMx) #error Cannot enable DaVinci and DA8XX platforms concurrently #elif defined(CONFIG_ARCH_DAVINCI_DA8XX) -#define PHYS_OFFSET DA8XX_DDR_BASE +#define PLAT_PHYS_OFFSET DA8XX_DDR_BASE #else -#define PHYS_OFFSET DAVINCI_DDR_BASE +#define PLAT_PHYS_OFFSET DAVINCI_DDR_BASE #endif #define DDR2_SDRCR_OFFSET 0xc diff --git a/arch/arm/mach-dove/Kconfig b/arch/arm/mach-dove/Kconfig index a4ed3900912..dd937c526a4 100644 --- a/arch/arm/mach-dove/Kconfig +++ b/arch/arm/mach-dove/Kconfig @@ -9,7 +9,7 @@ config MACH_DOVE_DB Say 'Y' here if you want your kernel to support the Marvell DB-MV88AP510 Development Board. - config MACH_CM_A510 +config MACH_CM_A510 bool "CompuLab CM-A510 Board" help Say 'Y' here if you want your kernel to support the diff --git a/arch/arm/mach-dove/include/mach/memory.h b/arch/arm/mach-dove/include/mach/memory.h index d6687207494..bbc93fee6c7 100644 --- a/arch/arm/mach-dove/include/mach/memory.h +++ b/arch/arm/mach-dove/include/mach/memory.h @@ -5,6 +5,6 @@ #ifndef __ASM_ARCH_MEMORY_H #define __ASM_ARCH_MEMORY_H -#define PHYS_OFFSET UL(0x00000000) +#define PLAT_PHYS_OFFSET UL(0x00000000) #endif diff --git a/arch/arm/mach-ebsa110/include/mach/memory.h b/arch/arm/mach-ebsa110/include/mach/memory.h index 0ca66d080c6..8e49066ad85 100644 --- a/arch/arm/mach-ebsa110/include/mach/memory.h +++ b/arch/arm/mach-ebsa110/include/mach/memory.h @@ -19,7 +19,7 @@ /* * Physical DRAM offset. */ -#define PHYS_OFFSET UL(0x00000000) +#define PLAT_PHYS_OFFSET UL(0x00000000) /* * Cache flushing area - SRAM diff --git a/arch/arm/mach-ep93xx/include/mach/memory.h b/arch/arm/mach-ep93xx/include/mach/memory.h index 554064e9030..c9400cf0051 100644 --- a/arch/arm/mach-ep93xx/include/mach/memory.h +++ b/arch/arm/mach-ep93xx/include/mach/memory.h @@ -6,15 +6,15 @@ #define __ASM_ARCH_MEMORY_H #if defined(CONFIG_EP93XX_SDCE3_SYNC_PHYS_OFFSET) -#define PHYS_OFFSET UL(0x00000000) +#define PLAT_PHYS_OFFSET UL(0x00000000) #elif defined(CONFIG_EP93XX_SDCE0_PHYS_OFFSET) -#define PHYS_OFFSET UL(0xc0000000) +#define PLAT_PHYS_OFFSET UL(0xc0000000) #elif defined(CONFIG_EP93XX_SDCE1_PHYS_OFFSET) -#define PHYS_OFFSET UL(0xd0000000) +#define PLAT_PHYS_OFFSET UL(0xd0000000) #elif defined(CONFIG_EP93XX_SDCE2_PHYS_OFFSET) -#define PHYS_OFFSET UL(0xe0000000) +#define PLAT_PHYS_OFFSET UL(0xe0000000) #elif defined(CONFIG_EP93XX_SDCE3_ASYNC_PHYS_OFFSET) -#define PHYS_OFFSET UL(0xf0000000) +#define PLAT_PHYS_OFFSET UL(0xf0000000) #else #error "Kconfig bug: No EP93xx PHYS_OFFSET set" #endif diff --git a/arch/arm/mach-footbridge/include/mach/memory.h b/arch/arm/mach-footbridge/include/mach/memory.h index 8d64f457408..5c6df377f96 100644 --- a/arch/arm/mach-footbridge/include/mach/memory.h +++ b/arch/arm/mach-footbridge/include/mach/memory.h @@ -62,7 +62,7 @@ extern unsigned long __bus_to_pfn(unsigned long); /* * Physical DRAM offset. */ -#define PHYS_OFFSET UL(0x00000000) +#define PLAT_PHYS_OFFSET UL(0x00000000) #define FLUSH_BASE_PHYS 0x50000000 diff --git a/arch/arm/mach-gemini/include/mach/memory.h b/arch/arm/mach-gemini/include/mach/memory.h index 2d14d5bf1f9..a50915f764d 100644 --- a/arch/arm/mach-gemini/include/mach/memory.h +++ b/arch/arm/mach-gemini/include/mach/memory.h @@ -11,9 +11,9 @@ #define __MACH_MEMORY_H #ifdef CONFIG_GEMINI_MEM_SWAP -# define PHYS_OFFSET UL(0x00000000) +# define PLAT_PHYS_OFFSET UL(0x00000000) #else -# define PHYS_OFFSET UL(0x10000000) +# define PLAT_PHYS_OFFSET UL(0x10000000) #endif #endif /* __MACH_MEMORY_H */ diff --git a/arch/arm/mach-h720x/include/mach/memory.h b/arch/arm/mach-h720x/include/mach/memory.h index ef4c1e26f18..9d368765146 100644 --- a/arch/arm/mach-h720x/include/mach/memory.h +++ b/arch/arm/mach-h720x/include/mach/memory.h @@ -7,7 +7,7 @@ #ifndef __ASM_ARCH_MEMORY_H #define __ASM_ARCH_MEMORY_H -#define PHYS_OFFSET UL(0x40000000) +#define PLAT_PHYS_OFFSET UL(0x40000000) /* * This is the maximum DMA address that can be DMAd to. * There should not be more than (0xd0000000 - 0xc0000000) diff --git a/arch/arm/mach-integrator/include/mach/memory.h b/arch/arm/mach-integrator/include/mach/memory.h index 991f24d2c11..334d5e27188 100644 --- a/arch/arm/mach-integrator/include/mach/memory.h +++ b/arch/arm/mach-integrator/include/mach/memory.h @@ -23,7 +23,7 @@ /* * Physical DRAM offset. */ -#define PHYS_OFFSET UL(0x00000000) +#define PLAT_PHYS_OFFSET UL(0x00000000) #define BUS_OFFSET UL(0x80000000) #define __virt_to_bus(x) ((x) - PAGE_OFFSET + BUS_OFFSET) diff --git a/arch/arm/mach-iop13xx/include/mach/memory.h b/arch/arm/mach-iop13xx/include/mach/memory.h index 3ad45531886..1afa99ef97f 100644 --- a/arch/arm/mach-iop13xx/include/mach/memory.h +++ b/arch/arm/mach-iop13xx/include/mach/memory.h @@ -6,7 +6,7 @@ /* * Physical DRAM offset. */ -#define PHYS_OFFSET UL(0x00000000) +#define PLAT_PHYS_OFFSET UL(0x00000000) #ifndef __ASSEMBLY__ diff --git a/arch/arm/mach-iop32x/include/mach/memory.h b/arch/arm/mach-iop32x/include/mach/memory.h index c30f6450ad5..169cc239f76 100644 --- a/arch/arm/mach-iop32x/include/mach/memory.h +++ b/arch/arm/mach-iop32x/include/mach/memory.h @@ -8,6 +8,6 @@ /* * Physical DRAM offset. */ -#define PHYS_OFFSET UL(0xa0000000) +#define PLAT_PHYS_OFFSET UL(0xa0000000) #endif diff --git a/arch/arm/mach-iop33x/include/mach/memory.h b/arch/arm/mach-iop33x/include/mach/memory.h index a30a96aa6d2..8e1daf7006b 100644 --- a/arch/arm/mach-iop33x/include/mach/memory.h +++ b/arch/arm/mach-iop33x/include/mach/memory.h @@ -8,6 +8,6 @@ /* * Physical DRAM offset. */ -#define PHYS_OFFSET UL(0x00000000) +#define PLAT_PHYS_OFFSET UL(0x00000000) #endif diff --git a/arch/arm/mach-ixp2000/include/mach/memory.h b/arch/arm/mach-ixp2000/include/mach/memory.h index 98e3471be15..5f0c4fd4076 100644 --- a/arch/arm/mach-ixp2000/include/mach/memory.h +++ b/arch/arm/mach-ixp2000/include/mach/memory.h @@ -13,7 +13,7 @@ #ifndef __ASM_ARCH_MEMORY_H #define __ASM_ARCH_MEMORY_H -#define PHYS_OFFSET UL(0x00000000) +#define PLAT_PHYS_OFFSET UL(0x00000000) #include <mach/ixp2000-regs.h> diff --git a/arch/arm/mach-ixp23xx/include/mach/memory.h b/arch/arm/mach-ixp23xx/include/mach/memory.h index 6ef65d813f1..6cf0704e946 100644 --- a/arch/arm/mach-ixp23xx/include/mach/memory.h +++ b/arch/arm/mach-ixp23xx/include/mach/memory.h @@ -17,7 +17,7 @@ /* * Physical DRAM offset. */ -#define PHYS_OFFSET (0x00000000) +#define PLAT_PHYS_OFFSET (0x00000000) #define IXP23XX_PCI_SDRAM_OFFSET (*((volatile int *)IXP23XX_PCI_SDRAM_BAR) & 0xfffffff0) diff --git a/arch/arm/mach-ixp4xx/include/mach/memory.h b/arch/arm/mach-ixp4xx/include/mach/memory.h index 0136eaa2922..6d388c9d0e2 100644 --- a/arch/arm/mach-ixp4xx/include/mach/memory.h +++ b/arch/arm/mach-ixp4xx/include/mach/memory.h @@ -12,7 +12,7 @@ /* * Physical DRAM offset. */ -#define PHYS_OFFSET UL(0x00000000) +#define PLAT_PHYS_OFFSET UL(0x00000000) #if !defined(__ASSEMBLY__) && defined(CONFIG_PCI) diff --git a/arch/arm/mach-kirkwood/include/mach/memory.h b/arch/arm/mach-kirkwood/include/mach/memory.h index 45431e13146..4600b44e3ad 100644 --- a/arch/arm/mach-kirkwood/include/mach/memory.h +++ b/arch/arm/mach-kirkwood/include/mach/memory.h @@ -5,6 +5,6 @@ #ifndef __ASM_ARCH_MEMORY_H #define __ASM_ARCH_MEMORY_H -#define PHYS_OFFSET UL(0x00000000) +#define PLAT_PHYS_OFFSET UL(0x00000000) #endif diff --git a/arch/arm/mach-ks8695/include/mach/memory.h b/arch/arm/mach-ks8695/include/mach/memory.h index bace9a681ad..f7e1b9bce34 100644 --- a/arch/arm/mach-ks8695/include/mach/memory.h +++ b/arch/arm/mach-ks8695/include/mach/memory.h @@ -18,7 +18,7 @@ /* * Physical SRAM offset. */ -#define PHYS_OFFSET KS8695_SDRAM_PA +#define PLAT_PHYS_OFFSET KS8695_SDRAM_PA #ifndef __ASSEMBLY__ diff --git a/arch/arm/mach-lh7a40x/include/mach/memory.h b/arch/arm/mach-lh7a40x/include/mach/memory.h index edb8f5faf5d..f77bde80fe4 100644 --- a/arch/arm/mach-lh7a40x/include/mach/memory.h +++ b/arch/arm/mach-lh7a40x/include/mach/memory.h @@ -17,7 +17,7 @@ /* * Physical DRAM offset. */ -#define PHYS_OFFSET UL(0xc0000000) +#define PLAT_PHYS_OFFSET UL(0xc0000000) /* * Sparsemem version of the above diff --git a/arch/arm/mach-loki/include/mach/memory.h b/arch/arm/mach-loki/include/mach/memory.h index 2ed7e6e732c..66366657a87 100644 --- a/arch/arm/mach-loki/include/mach/memory.h +++ b/arch/arm/mach-loki/include/mach/memory.h @@ -5,6 +5,6 @@ #ifndef __ASM_ARCH_MEMORY_H #define __ASM_ARCH_MEMORY_H -#define PHYS_OFFSET UL(0x00000000) +#define PLAT_PHYS_OFFSET UL(0x00000000) #endif diff --git a/arch/arm/mach-lpc32xx/include/mach/memory.h b/arch/arm/mach-lpc32xx/include/mach/memory.h index 044e1acecbe..a647dd624af 100644 --- a/arch/arm/mach-lpc32xx/include/mach/memory.h +++ b/arch/arm/mach-lpc32xx/include/mach/memory.h @@ -22,6 +22,6 @@ /* * Physical DRAM offset of bank 0 */ -#define PHYS_OFFSET UL(0x80000000) +#define PLAT_PHYS_OFFSET UL(0x80000000) #endif diff --git a/arch/arm/mach-mmp/include/mach/memory.h b/arch/arm/mach-mmp/include/mach/memory.h index bdb21d70714..d68b50a2d6a 100644 --- a/arch/arm/mach-mmp/include/mach/memory.h +++ b/arch/arm/mach-mmp/include/mach/memory.h @@ -9,6 +9,6 @@ #ifndef __ASM_MACH_MEMORY_H #define __ASM_MACH_MEMORY_H -#define PHYS_OFFSET UL(0x00000000) +#define PLAT_PHYS_OFFSET UL(0x00000000) #endif /* __ASM_MACH_MEMORY_H */ diff --git a/arch/arm/mach-msm/board-msm7x27.c b/arch/arm/mach-msm/board-msm7x27.c index e7a76eff57d..08fcd40a8cb 100644 --- a/arch/arm/mach-msm/board-msm7x27.c +++ b/arch/arm/mach-msm/board-msm7x27.c @@ -132,7 +132,7 @@ static void __init msm7x2x_map_io(void) MACHINE_START(MSM7X27_SURF, "QCT MSM7x27 SURF") #ifdef CONFIG_MSM_DEBUG_UART #endif - .boot_params = PHYS_OFFSET + 0x100, + .boot_params = PLAT_PHYS_OFFSET + 0x100, .map_io = msm7x2x_map_io, .init_irq = msm7x2x_init_irq, .init_machine = msm7x2x_init, @@ -142,7 +142,7 @@ MACHINE_END MACHINE_START(MSM7X27_FFA, "QCT MSM7x27 FFA") #ifdef CONFIG_MSM_DEBUG_UART #endif - .boot_params = PHYS_OFFSET + 0x100, + .boot_params = PLAT_PHYS_OFFSET + 0x100, .map_io = msm7x2x_map_io, .init_irq = msm7x2x_init_irq, .init_machine = msm7x2x_init, @@ -152,7 +152,7 @@ MACHINE_END MACHINE_START(MSM7X25_SURF, "QCT MSM7x25 SURF") #ifdef CONFIG_MSM_DEBUG_UART #endif - .boot_params = PHYS_OFFSET + 0x100, + .boot_params = PLAT_PHYS_OFFSET + 0x100, .map_io = msm7x2x_map_io, .init_irq = msm7x2x_init_irq, .init_machine = msm7x2x_init, @@ -162,7 +162,7 @@ MACHINE_END MACHINE_START(MSM7X25_FFA, "QCT MSM7x25 FFA") #ifdef CONFIG_MSM_DEBUG_UART #endif - .boot_params = PHYS_OFFSET + 0x100, + .boot_params = PLAT_PHYS_OFFSET + 0x100, .map_io = msm7x2x_map_io, .init_irq = msm7x2x_init_irq, .init_machine = msm7x2x_init, diff --git a/arch/arm/mach-msm/board-msm7x30.c b/arch/arm/mach-msm/board-msm7x30.c index 6f3b9735e97..25db8fd71a7 100644 --- a/arch/arm/mach-msm/board-msm7x30.c +++ b/arch/arm/mach-msm/board-msm7x30.c @@ -26,11 +26,11 @@ #include <asm/mach-types.h> #include <asm/mach/arch.h> +#include <asm/memory.h> #include <asm/setup.h> #include <mach/gpio.h> #include <mach/board.h> -#include <mach/memory.h> #include <mach/msm_iomap.h> #include <mach/dma.h> @@ -85,7 +85,7 @@ static void __init msm7x30_map_io(void) MACHINE_START(MSM7X30_SURF, "QCT MSM7X30 SURF") #ifdef CONFIG_MSM_DEBUG_UART #endif - .boot_params = PHYS_OFFSET + 0x100, + .boot_params = PLAT_PHYS_OFFSET + 0x100, .map_io = msm7x30_map_io, .init_irq = msm7x30_init_irq, .init_machine = msm7x30_init, @@ -95,7 +95,7 @@ MACHINE_END MACHINE_START(MSM7X30_FFA, "QCT MSM7X30 FFA") #ifdef CONFIG_MSM_DEBUG_UART #endif - .boot_params = PHYS_OFFSET + 0x100, + .boot_params = PLAT_PHYS_OFFSET + 0x100, .map_io = msm7x30_map_io, .init_irq = msm7x30_init_irq, .init_machine = msm7x30_init, @@ -105,7 +105,7 @@ MACHINE_END MACHINE_START(MSM7X30_FLUID, "QCT MSM7X30 FLUID") #ifdef CONFIG_MSM_DEBUG_UART #endif - .boot_params = PHYS_OFFSET + 0x100, + .boot_params = PLAT_PHYS_OFFSET + 0x100, .map_io = msm7x30_map_io, .init_irq = msm7x30_init_irq, .init_machine = msm7x30_init, diff --git a/arch/arm/mach-msm/board-qsd8x50.c b/arch/arm/mach-msm/board-qsd8x50.c index 6dde8185205..15c2bbd2ef8 100644 --- a/arch/arm/mach-msm/board-qsd8x50.c +++ b/arch/arm/mach-msm/board-qsd8x50.c @@ -118,7 +118,7 @@ static void __init qsd8x50_init(void) MACHINE_START(QSD8X50_SURF, "QCT QSD8X50 SURF") #ifdef CONFIG_MSM_DEBUG_UART #endif - .boot_params = PHYS_OFFSET + 0x100, + .boot_params = PLAT_PHYS_OFFSET + 0x100, .map_io = qsd8x50_map_io, .init_irq = qsd8x50_init_irq, .init_machine = qsd8x50_init, @@ -128,7 +128,7 @@ MACHINE_END MACHINE_START(QSD8X50A_ST1_5, "QCT QSD8X50A ST1.5") #ifdef CONFIG_MSM_DEBUG_UART #endif - .boot_params = PHYS_OFFSET + 0x100, + .boot_params = PLAT_PHYS_OFFSET + 0x100, .map_io = qsd8x50_map_io, .init_irq = qsd8x50_init_irq, .init_machine = qsd8x50_init, diff --git a/arch/arm/mach-msm/board-sapphire.c b/arch/arm/mach-msm/board-sapphire.c index 8919ffb1719..83604f526f0 100644 --- a/arch/arm/mach-msm/board-sapphire.c +++ b/arch/arm/mach-msm/board-sapphire.c @@ -107,7 +107,7 @@ MACHINE_START(SAPPHIRE, "sapphire") /* Maintainer: Brian Swetland <swetland@google.com> */ #ifdef CONFIG_MSM_DEBUG_UART #endif - .boot_params = PHYS_OFFSET + 0x100, + .boot_params = PLAT_PHYS_OFFSET + 0x100, .fixup = sapphire_fixup, .map_io = sapphire_map_io, .init_irq = sapphire_init_irq, diff --git a/arch/arm/mach-msm/include/mach/memory.h b/arch/arm/mach-msm/include/mach/memory.h index 070e17d237f..176875df241 100644 --- a/arch/arm/mach-msm/include/mach/memory.h +++ b/arch/arm/mach-msm/include/mach/memory.h @@ -18,15 +18,15 @@ /* physical offset of RAM */ #if defined(CONFIG_ARCH_QSD8X50) && defined(CONFIG_MSM_SOC_REV_A) -#define PHYS_OFFSET UL(0x00000000) +#define PLAT_PHYS_OFFSET UL(0x00000000) #elif defined(CONFIG_ARCH_QSD8X50) -#define PHYS_OFFSET UL(0x20000000) +#define PLAT_PHYS_OFFSET UL(0x20000000) #elif defined(CONFIG_ARCH_MSM7X30) -#define PHYS_OFFSET UL(0x00200000) +#define PLAT_PHYS_OFFSET UL(0x00200000) #elif defined(CONFIG_ARCH_MSM8X60) -#define PHYS_OFFSET UL(0x40200000) +#define PLAT_PHYS_OFFSET UL(0x40200000) #else -#define PHYS_OFFSET UL(0x10000000) +#define PLAT_PHYS_OFFSET UL(0x10000000) #endif #endif diff --git a/arch/arm/mach-mv78xx0/include/mach/memory.h b/arch/arm/mach-mv78xx0/include/mach/memory.h index e663042d307..a648c51f2e4 100644 --- a/arch/arm/mach-mv78xx0/include/mach/memory.h +++ b/arch/arm/mach-mv78xx0/include/mach/memory.h @@ -5,6 +5,6 @@ #ifndef __ASM_ARCH_MEMORY_H #define __ASM_ARCH_MEMORY_H -#define PHYS_OFFSET UL(0x00000000) +#define PLAT_PHYS_OFFSET UL(0x00000000) #endif diff --git a/arch/arm/mach-mx3/mach-kzm_arm11_01.c b/arch/arm/mach-mx3/mach-kzm_arm11_01.c index a5f3eb24e4d..df1a6ce8e3e 100644 --- a/arch/arm/mach-mx3/mach-kzm_arm11_01.c +++ b/arch/arm/mach-mx3/mach-kzm_arm11_01.c @@ -27,6 +27,7 @@ #include <asm/irq.h> #include <asm/mach-types.h> +#include <asm/memory.h> #include <asm/setup.h> #include <asm/mach/arch.h> #include <asm/mach/irq.h> @@ -36,7 +37,6 @@ #include <mach/clock.h> #include <mach/common.h> #include <mach/iomux-mx3.h> -#include <mach/memory.h> #include "devices-imx31.h" #include "devices.h" diff --git a/arch/arm/mach-mx5/clock-mx51-mx53.c b/arch/arm/mach-mx5/clock-mx51-mx53.c index 0a19e7567c0..d8a65daa8be 100644 --- a/arch/arm/mach-mx5/clock-mx51-mx53.c +++ b/arch/arm/mach-mx5/clock-mx51-mx53.c @@ -464,7 +464,14 @@ static int _clk_main_bus_set_parent(struct clk *clk, struct clk *parent) return 0; } +#ifdef CONFIG_CLK_DEBUG +#define __INIT_CLK_DEBUG(n) .name = #n, +#else +#define __INIT_CLK_DEBUG(n) +#endif + static struct clk main_bus_clk = { + __INIT_CLK_DEBUG(main_bus_clk) .parent = &pll2_sw_clk, .set_parent = _clk_main_bus_set_parent, }; @@ -728,23 +735,28 @@ static unsigned long _clk_ddr_hf_get_rate(struct clk *clk) /* External high frequency clock */ static struct clk ckih_clk = { + __INIT_CLK_DEBUG(ckih_clk) .get_rate = get_high_reference_clock_rate, }; static struct clk ckih2_clk = { + __INIT_CLK_DEBUG(ckih2_clk) .get_rate = get_ckih2_reference_clock_rate, }; static struct clk osc_clk = { + __INIT_CLK_DEBUG(osc_clk) .get_rate = get_oscillator_reference_clock_rate, }; /* External low frequency (32kHz) clock */ static struct clk ckil_clk = { + __INIT_CLK_DEBUG(ckil_clk) .get_rate = get_low_reference_clock_rate, }; static struct clk pll1_main_clk = { + __INIT_CLK_DEBUG(pll1_main_clk) .parent = &osc_clk, .get_rate = clk_pll_get_rate, .enable = _clk_pll_enable, @@ -762,6 +774,7 @@ static struct clk pll1_main_clk = { /* PLL1 SW supplies to ARM core */ static struct clk pll1_sw_clk = { + __INIT_CLK_DEBUG(pll1_sw_clk) .parent = &pll1_main_clk, .set_parent = _clk_pll1_sw_set_parent, .get_rate = clk_pll1_sw_get_rate, @@ -769,6 +782,7 @@ static struct clk pll1_sw_clk = { /* PLL2 SW supplies to AXI/AHB/IP buses */ static struct clk pll2_sw_clk = { + __INIT_CLK_DEBUG(pll2_sw_clk) .parent = &osc_clk, .get_rate = clk_pll_get_rate, .set_rate = _clk_pll_set_rate, @@ -779,6 +793,7 @@ static struct clk pll2_sw_clk = { /* PLL3 SW supplies to serial clocks like USB, SSI, etc. */ static struct clk pll3_sw_clk = { + __INIT_CLK_DEBUG(pll3_sw_clk) .parent = &osc_clk, .set_rate = _clk_pll_set_rate, .get_rate = clk_pll_get_rate, @@ -788,6 +803,7 @@ static struct clk pll3_sw_clk = { /* PLL4 SW supplies to LVDS Display Bridge(LDB) */ static struct clk mx53_pll4_sw_clk = { + __INIT_CLK_DEBUG(mx53_pll4_clk) .parent = &osc_clk, .set_rate = _clk_pll_set_rate, .enable = _clk_pll_enable, @@ -796,22 +812,26 @@ static struct clk mx53_pll4_sw_clk = { /* Low-power Audio Playback Mode clock */ static struct clk lp_apm_clk = { + __INIT_CLK_DEBUG(lp_apm_clk) .parent = &osc_clk, .set_parent = _clk_lp_apm_set_parent, }; static struct clk periph_apm_clk = { + __INIT_CLK_DEBUG(periph_apm_clk) .parent = &pll1_sw_clk, .set_parent = _clk_periph_apm_set_parent, }; static struct clk cpu_clk = { + __INIT_CLK_DEBUG(cpu_clk) .parent = &pll1_sw_clk, .get_rate = clk_cpu_get_rate, .set_rate = clk_cpu_set_rate, }; static struct clk ahb_clk = { + __INIT_CLK_DEBUG(ahb_clk) .parent = &main_bus_clk, .get_rate = clk_ahb_get_rate, .set_rate = _clk_ahb_set_rate, @@ -819,6 +839,7 @@ static struct clk ahb_clk = { }; static struct clk iim_clk = { + __INIT_CLK_DEBUG(iim_clk) .parent = &ipg_clk, .enable_reg = MXC_CCM_CCGR0, .enable_shift = MXC_CCM_CCGRx_CG15_OFFSET, @@ -826,17 +847,20 @@ static struct clk iim_clk = { /* Main IP interface clock for access to registers */ static struct clk ipg_clk = { + __INIT_CLK_DEBUG(ipg_clk) .parent = &ahb_clk, .get_rate = clk_ipg_get_rate, }; static struct clk ipg_perclk = { + __INIT_CLK_DEBUG(ipg_clk) .parent = &lp_apm_clk, .get_rate = clk_ipg_per_get_rate, .set_parent = _clk_ipg_per_set_parent, }; static struct clk ahb_max_clk = { + __INIT_CLK_DEBUG(ahb_max_clk) .parent = &ahb_clk, .enable_reg = MXC_CCM_CCGR0, .enable_shift = MXC_CCM_CCGRx_CG14_OFFSET, @@ -845,6 +869,7 @@ static struct clk ahb_max_clk = { }; static struct clk aips_tz1_clk = { + __INIT_CLK_DEBUG(aips_tz1_clk) .parent = &ahb_clk, .secondary = &ahb_max_clk, .enable_reg = MXC_CCM_CCGR0, @@ -854,6 +879,7 @@ static struct clk aips_tz1_clk = { }; static struct clk aips_tz2_clk = { + __INIT_CLK_DEBUG(aips_tz2_clk) .parent = &ahb_clk, .secondary = &ahb_max_clk, .enable_reg = MXC_CCM_CCGR0, @@ -863,11 +889,13 @@ static struct clk aips_tz2_clk = { }; static struct clk gpt_32k_clk = { + __INIT_CLK_DEBUG(gpt_32k_clk) .id = 0, .parent = &ckil_clk, }; static struct clk kpp_clk = { + __INIT_CLK_DEBUG(kpp_clk) .id = 0, }; @@ -876,6 +904,7 @@ static struct clk dummy_clk = { }; static struct clk emi_slow_clk = { + __INIT_CLK_DEBUG(emi_slow_clk) .parent = &pll2_sw_clk, .enable_reg = MXC_CCM_CCGR5, .enable_shift = MXC_CCM_CCGRx_CG8_OFFSET, @@ -989,6 +1018,7 @@ static struct clk mipi_hsp_clk = { #define DEFINE_CLOCK_CCGR(name, i, er, es, pfx, p, s) \ static struct clk name = { \ + __INIT_CLK_DEBUG(name) \ .id = i, \ .enable_reg = er, \ .enable_shift = es, \ @@ -1004,6 +1034,7 @@ static struct clk mipi_hsp_clk = { #define DEFINE_CLOCK_MAX(name, i, er, es, pfx, p, s) \ static struct clk name = { \ + __INIT_CLK_DEBUG(name) \ .id = i, \ .enable_reg = er, \ .enable_shift = es, \ @@ -1082,6 +1113,7 @@ CLK_GET_RATE(uart, 1, UART) CLK_SET_PARENT(uart, 1, UART) static struct clk uart_root_clk = { + __INIT_CLK_DEBUG(uart_root_clk) .parent = &pll2_sw_clk, .get_rate = clk_uart_get_rate, .set_parent = clk_uart_set_parent, @@ -1092,6 +1124,7 @@ CLK_GET_RATE(usboh3, 1, USBOH3) CLK_SET_PARENT(usboh3, 1, USBOH3) static struct clk usboh3_clk = { + __INIT_CLK_DEBUG(usboh3_clk) .parent = &pll2_sw_clk, .get_rate = clk_usboh3_get_rate, .set_parent = clk_usboh3_set_parent, @@ -1137,6 +1170,7 @@ CLK_GET_RATE(ecspi, 2, CSPI) CLK_SET_PARENT(ecspi, 1, CSPI) static struct clk ecspi_main_clk = { + __INIT_CLK_DEBUG(ecspi_main_clk) .parent = &pll3_sw_clk, .get_rate = clk_ecspi_get_rate, .set_parent = clk_ecspi_set_parent, @@ -1152,7 +1186,8 @@ CLK_SET_PARENT(esdhc2, 1, ESDHC2_MSHC2) CLK_SET_RATE(esdhc2, 1, ESDHC2_MSHC2) #define DEFINE_CLOCK_FULL(name, i, er, es, gr, sr, e, d, p, s) \ - static struct clk name = { \ +static struct clk name = { \ + __INIT_CLK_DEBUG(name) \ .id = i, \ .enable_reg = er, \ .enable_shift = es, \ @@ -1372,8 +1407,10 @@ int __init mx51_clocks_init(unsigned long ckil, unsigned long osc, ckih2_reference = ckih2; oscillator_reference = osc; - for (i = 0; i < ARRAY_SIZE(mx51_lookups); i++) + for (i = 0; i < ARRAY_SIZE(mx51_lookups); i++) { clkdev_add(&mx51_lookups[i]); + clk_debug_register(mx51_lookups[i].clk); + } clk_tree_init(); diff --git a/arch/arm/mach-netx/include/mach/memory.h b/arch/arm/mach-netx/include/mach/memory.h index 9a363f297f9..59561496c36 100644 --- a/arch/arm/mach-netx/include/mach/memory.h +++ b/arch/arm/mach-netx/include/mach/memory.h @@ -20,7 +20,7 @@ #ifndef __ASM_ARCH_MEMORY_H #define __ASM_ARCH_MEMORY_H -#define PHYS_OFFSET UL(0x80000000) +#define PLAT_PHYS_OFFSET UL(0x80000000) #endif diff --git a/arch/arm/mach-nomadik/include/mach/memory.h b/arch/arm/mach-nomadik/include/mach/memory.h index 1e5689d98ec..d3325211ba6 100644 --- a/arch/arm/mach-nomadik/include/mach/memory.h +++ b/arch/arm/mach-nomadik/include/mach/memory.h @@ -23,6 +23,6 @@ /* * Physical DRAM offset. */ -#define PHYS_OFFSET UL(0x00000000) +#define PLAT_PHYS_OFFSET UL(0x00000000) #endif diff --git a/arch/arm/mach-ns9xxx/include/mach/memory.h b/arch/arm/mach-ns9xxx/include/mach/memory.h index 6107193adbf..5c65aee6e7a 100644 --- a/arch/arm/mach-ns9xxx/include/mach/memory.h +++ b/arch/arm/mach-ns9xxx/include/mach/memory.h @@ -19,6 +19,6 @@ #define NS9XXX_CS2STAT_LENGTH UL(0x1000) #define NS9XXX_CS3STAT_LENGTH UL(0x1000) -#define PHYS_OFFSET UL(0x00000000) +#define PLAT_PHYS_OFFSET UL(0x00000000) #endif diff --git a/arch/arm/mach-nuc93x/include/mach/memory.h b/arch/arm/mach-nuc93x/include/mach/memory.h index 323ab0db3f7..ef9864b002a 100644 --- a/arch/arm/mach-nuc93x/include/mach/memory.h +++ b/arch/arm/mach-nuc93x/include/mach/memory.h @@ -16,6 +16,6 @@ #ifndef __ASM_ARCH_MEMORY_H #define __ASM_ARCH_MEMORY_H -#define PHYS_OFFSET UL(0x00000000) +#define PLAT_PHYS_OFFSET UL(0x00000000) #endif diff --git a/arch/arm/mach-omap1/Makefile b/arch/arm/mach-omap1/Makefile index ba6009f2767..cb2d3a64858 100644 --- a/arch/arm/mach-omap1/Makefile +++ b/arch/arm/mach-omap1/Makefile @@ -10,6 +10,9 @@ obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o obj-$(CONFIG_OMAP_32K_TIMER) += timer32k.o +# CPUFREQ driver +obj-$(CONFIG_CPU_FREQ) += omap1-cpufreq.o + # Power Management obj-$(CONFIG_PM) += pm.o sleep.o pm_bus.o diff --git a/arch/arm/mach-omap1/include/mach/debug-macro.S b/arch/arm/mach-omap1/include/mach/debug-macro.S index 6a0fa046236..62856044eb6 100644 --- a/arch/arm/mach-omap1/include/mach/debug-macro.S +++ b/arch/arm/mach-omap1/include/mach/debug-macro.S @@ -17,6 +17,9 @@ #include <plat/serial.h> +#define omap_uart_v2p(x) ((x) - PAGE_OFFSET + PLAT_PHYS_OFFSET) +#define omap_uart_p2v(x) ((x) - PLAT_PHYS_OFFSET + PAGE_OFFSET) + .pushsection .data omap_uart_phys: .word 0x0 omap_uart_virt: .word 0x0 @@ -33,7 +36,7 @@ omap_uart_virt: .word 0x0 /* Use omap_uart_phys/virt if already configured */ 9: mrc p15, 0, \rp, c1, c0 tst \rp, #1 @ MMU enabled? - ldreq \rp, =__virt_to_phys(omap_uart_phys) @ MMU not enabled + ldreq \rp, =omap_uart_v2p(omap_uart_phys) @ MMU disabled ldrne \rp, =omap_uart_phys @ MMU enabled add \rv, \rp, #4 @ omap_uart_virt ldr \rp, [\rp, #0] @@ -46,7 +49,7 @@ omap_uart_virt: .word 0x0 mrc p15, 0, \rp, c1, c0 tst \rp, #1 @ MMU enabled? ldreq \rp, =OMAP_UART_INFO @ MMU not enabled - ldrne \rp, =__phys_to_virt(OMAP_UART_INFO) @ MMU enabled + ldrne \rp, =omap_uart_p2v(OMAP_UART_INFO) @ MMU enabled ldr \rp, [\rp, #0] /* Select the UART to use based on the UART1 scratchpad value */ @@ -73,7 +76,7 @@ omap_uart_virt: .word 0x0 98: add \rp, \rp, #0xff000000 @ phys base mrc p15, 0, \rv, c1, c0 tst \rv, #1 @ MMU enabled? - ldreq \rv, =__virt_to_phys(omap_uart_phys) @ MMU not enabled + ldreq \rv, =omap_uart_v2p(omap_uart_phys) @ MMU disabled ldrne \rv, =omap_uart_phys @ MMU enabled str \rp, [\rv, #0] sub \rp, \rp, #0xff000000 @ phys base diff --git a/arch/arm/mach-omap1/omap1-cpufreq.c b/arch/arm/mach-omap1/omap1-cpufreq.c new file mode 100644 index 00000000000..64faf3f28d9 --- /dev/null +++ b/arch/arm/mach-omap1/omap1-cpufreq.c @@ -0,0 +1,176 @@ +/* + * OMAP1 cpufreq driver + * + * CPU frequency scaling for OMAP + * + * Copyright (C) 2005 Nokia Corporation + * Written by Tony Lindgren <tony@atomide.com> + * + * Based on cpu-sa1110.c, Copyright (C) 2001 Russell King + * + * Copyright (C) 2007-2008 Texas Instruments, Inc. + * Updated to support OMAP3 + * Rajendra Nayak <rnayak@ti.com> + * + * 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/types.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/cpufreq.h> +#include <linux/delay.h> +#include <linux/init.h> +#include <linux/err.h> +#include <linux/clk.h> +#include <linux/io.h> +#include <linux/opp.h> + +#include <asm/system.h> + +#include <plat/clock.h> +#include <plat/omap-pm.h> + +#include <mach/hardware.h> + +#define VERY_HI_RATE 900000000 + +static struct cpufreq_frequency_table *freq_table; +static struct clk *mpu_clk; + +static int omap_verify_speed(struct cpufreq_policy *policy) +{ + if (freq_table) + return cpufreq_frequency_table_verify(policy, freq_table); + + if (policy->cpu) + return -EINVAL; + + cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, + policy->cpuinfo.max_freq); + + policy->min = clk_round_rate(mpu_clk, policy->min * 1000) / 1000; + policy->max = clk_round_rate(mpu_clk, policy->max * 1000) / 1000; + cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, + policy->cpuinfo.max_freq); + return 0; +} + +static unsigned int omap_getspeed(unsigned int cpu) +{ + unsigned long rate; + + if (cpu) + return 0; + + rate = clk_get_rate(mpu_clk) / 1000; + return rate; +} + +static int omap_target(struct cpufreq_policy *policy, + unsigned int target_freq, + unsigned int relation) +{ + struct cpufreq_freqs freqs; + int ret = 0; + + /* Ensure desired rate is within allowed range. Some govenors + * (ondemand) will just pass target_freq=0 to get the minimum. */ + if (target_freq < policy->min) + target_freq = policy->min; + if (target_freq > policy->max) + target_freq = policy->max; + + freqs.old = omap_getspeed(0); + freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000; + freqs.cpu = 0; + + if (freqs.old == freqs.new) + return ret; + + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); + +#ifdef CONFIG_CPU_FREQ_DEBUG + pr_info("cpufreq-omap: transition: %u --> %u\n", freqs.old, freqs.new); +#endif + ret = clk_set_rate(mpu_clk, freqs.new * 1000); + if (!ret) + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); + + return ret; +} + +static int __init omap_cpu_init(struct cpufreq_policy *policy) +{ + int result = 0; + + mpu_clk = clk_get(NULL, "mpu"); + if (IS_ERR(mpu_clk)) + return PTR_ERR(mpu_clk); + + if (policy->cpu != 0) + return -EINVAL; + + policy->cur = policy->min = policy->max = omap_getspeed(0); + + clk_init_cpufreq_table(&freq_table); + + if (freq_table) { + result = cpufreq_frequency_table_cpuinfo(policy, freq_table); + if (!result) + cpufreq_frequency_table_get_attr(freq_table, + policy->cpu); + } else { + policy->cpuinfo.min_freq = clk_round_rate(mpu_clk, 0) / 1000; + policy->cpuinfo.max_freq = clk_round_rate(mpu_clk, + VERY_HI_RATE) / 1000; + } + + policy->min = policy->cpuinfo.min_freq; + policy->max = policy->cpuinfo.max_freq; + policy->cur = omap_getspeed(0); + + /* FIXME: what's the actual transition time? */ + policy->cpuinfo.transition_latency = 300 * 1000; + + return 0; +} + +static int omap_cpu_exit(struct cpufreq_policy *policy) +{ + clk_exit_cpufreq_table(&freq_table); + clk_put(mpu_clk); + return 0; +} + +static struct freq_attr *omap_cpufreq_attr[] = { + &cpufreq_freq_attr_scaling_available_freqs, + NULL, +}; + +static struct cpufreq_driver omap_driver = { + .flags = CPUFREQ_STICKY, + .verify = omap_verify_speed, + .target = omap_target, + .get = omap_getspeed, + .init = omap_cpu_init, + .exit = omap_cpu_exit, + .name = "omap1", + .attr = omap_cpufreq_attr, +}; + +static int __init omap_cpufreq_init(void) +{ + return cpufreq_register_driver(&omap_driver); +} + +static void __exit omap_cpufreq_exit(void) +{ + cpufreq_unregister_driver(&omap_driver); +} + +MODULE_DESCRIPTION("cpufreq driver for OMAP1 SOCs"); +MODULE_LICENSE("GPL"); +module_init(omap_cpufreq_init); +module_exit(omap_cpufreq_exit); diff --git a/arch/arm/mach-omap1/pm.h b/arch/arm/mach-omap1/pm.h index 56a647986ae..cd926dcb5e7 100644 --- a/arch/arm/mach-omap1/pm.h +++ b/arch/arm/mach-omap1/pm.h @@ -123,9 +123,9 @@ extern void allow_idle_sleep(void); extern void omap1_pm_idle(void); extern void omap1_pm_suspend(void); -extern void omap7xx_cpu_suspend(unsigned short, unsigned short); -extern void omap1510_cpu_suspend(unsigned short, unsigned short); -extern void omap1610_cpu_suspend(unsigned short, unsigned short); +extern void omap7xx_cpu_suspend(unsigned long, unsigned long); +extern void omap1510_cpu_suspend(unsigned long, unsigned long); +extern void omap1610_cpu_suspend(unsigned long, unsigned long); extern void omap7xx_idle_loop_suspend(void); extern void omap1510_idle_loop_suspend(void); extern void omap1610_idle_loop_suspend(void); diff --git a/arch/arm/mach-omap1/sleep.S b/arch/arm/mach-omap1/sleep.S index ef771ce8b03..c875bdc902c 100644 --- a/arch/arm/mach-omap1/sleep.S +++ b/arch/arm/mach-omap1/sleep.S @@ -58,6 +58,7 @@ */ #if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850) + .align 3 ENTRY(omap7xx_cpu_suspend) @ save registers on stack @@ -137,6 +138,7 @@ ENTRY(omap7xx_cpu_suspend_sz) #endif /* CONFIG_ARCH_OMAP730 || CONFIG_ARCH_OMAP850 */ #ifdef CONFIG_ARCH_OMAP15XX + .align 3 ENTRY(omap1510_cpu_suspend) @ save registers on stack @@ -211,6 +213,7 @@ ENTRY(omap1510_cpu_suspend_sz) #endif /* CONFIG_ARCH_OMAP15XX */ #if defined(CONFIG_ARCH_OMAP16XX) + .align 3 ENTRY(omap1610_cpu_suspend) @ save registers on stack diff --git a/arch/arm/mach-omap1/sram.S b/arch/arm/mach-omap1/sram.S index 7724e520d07..692587d07ea 100644 --- a/arch/arm/mach-omap1/sram.S +++ b/arch/arm/mach-omap1/sram.S @@ -18,6 +18,7 @@ /* * Reprograms ULPD and CKCTL. */ + .align 3 ENTRY(omap1_sram_reprogram_clock) stmfd sp!, {r0 - r12, lr} @ save registers on stack diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 1c0c2b02d87..86a54ca1b6e 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -56,12 +56,15 @@ obj-$(CONFIG_ARCH_OMAP3) += opp3xxx_data.o obj-$(CONFIG_ARCH_OMAP4) += opp4xxx_data.o endif +# CPUFREQ driver +obj-$(CONFIG_CPU_FREQ) += omap2plus-cpufreq.o + # Power Management ifeq ($(CONFIG_PM),y) obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o obj-$(CONFIG_ARCH_OMAP2) += sleep24xx.o pm_bus.o voltage.o obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o voltage.o \ - cpuidle34xx.o pm_bus.o + cpuidle34xx.o pm_bus.o dvfs.o obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o voltage.o pm_bus.o obj-$(CONFIG_PM_DEBUG) += pm-debug.o obj-$(CONFIG_OMAP_SMARTREFLEX) += sr_device.o smartreflex.o @@ -242,3 +245,6 @@ obj-y += $(smc91x-m) $(smc91x-y) smsc911x-$(CONFIG_SMSC911X) := gpmc-smsc911x.o obj-y += $(smsc911x-m) $(smsc911x-y) + +disp-$(CONFIG_OMAP2_DSS) := display.o +obj-y += $(disp-m) $(disp-y) diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c index d4e41ef86aa..33ff4f6ba12 100644 --- a/arch/arm/mach-omap2/board-3430sdp.c +++ b/arch/arm/mach-omap2/board-3430sdp.c @@ -307,22 +307,8 @@ static struct omap_dss_board_info sdp3430_dss_data = { .default_device = &sdp3430_lcd_device, }; -static struct platform_device sdp3430_dss_device = { - .name = "omapdss", - .id = -1, - .dev = { - .platform_data = &sdp3430_dss_data, - }, -}; - -static struct regulator_consumer_supply sdp3430_vdda_dac_supply = { - .supply = "vdda_dac", - .dev = &sdp3430_dss_device.dev, -}; - -static struct platform_device *sdp3430_devices[] __initdata = { - &sdp3430_dss_device, -}; +static struct regulator_consumer_supply sdp3430_vdda_dac_supply = + REGULATOR_SUPPLY("vdda_dac", "omap_venc"); static struct omap_board_config_kernel sdp3430_config[] __initdata = { }; @@ -546,10 +532,8 @@ static struct regulator_init_data sdp3430_vdac = { /* VPLL2 for digital video outputs */ static struct regulator_consumer_supply sdp3430_vpll2_supplies[] = { - { - .supply = "vdds_dsi", - .dev = &sdp3430_dss_device.dev, - } + REGULATOR_SUPPLY("vdds_dsi", "omap_display"), + REGULATOR_SUPPLY("vdds_dsi", "omap_dsi1"), }; static struct regulator_init_data sdp3430_vpll2 = { @@ -801,7 +785,7 @@ static void __init omap_3430sdp_init(void) { omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); omap3430_i2c_init(); - platform_add_devices(sdp3430_devices, ARRAY_SIZE(sdp3430_devices)); + omap_display_init(&sdp3430_dss_data); if (omap_rev() > OMAP3430_REV_ES1_0) ts_gpio = SDP3430_TS_GPIO_IRQ_SDPV2; else diff --git a/arch/arm/mach-omap2/board-3630sdp.c b/arch/arm/mach-omap2/board-3630sdp.c index 62645640f5e..8d05fc94f51 100644 --- a/arch/arm/mach-omap2/board-3630sdp.c +++ b/arch/arm/mach-omap2/board-3630sdp.c @@ -25,6 +25,24 @@ #include "board-flash.h" #include "mux.h" #include "sdram-hynix-h8mbx00u0mer-0em.h" +#include "pm.h" + +static struct cpuidle_params omap36xx_cpuidle_params_table[] = { + /* C1 */ + {1, 74, 78, 152}, + /* C2 */ + {0, 165, 90, 255}, + /* C3 */ + {1, 163, 180, 345}, + /* C4 */ + {0, 2852, 605, 3457}, + /* C5 */ + {1, 800, 366, 2120}, + /* C6 */ + {0, 4080, 801, 4881}, + /* C7 */ + {1, 4300, 8794, 159000}, +}; #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) @@ -212,6 +230,7 @@ static void __init omap_sdp_init(void) board_flash_init(sdp_flash_partitions, chip_sel_sdp); enable_board_wakeup_source(); usb_ehci_init(&ehci_pdata); + omap3_pm_init_cpuidle(omap36xx_cpuidle_params_table); } MACHINE_START(OMAP_3630SDP, "OMAP 3630SDP board") diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c index 10d60b7743c..548f5245eda 100644 --- a/arch/arm/mach-omap2/board-am3517evm.c +++ b/arch/arm/mach-omap2/board-am3517evm.c @@ -378,24 +378,12 @@ static struct omap_dss_board_info am3517_evm_dss_data = { .default_device = &am3517_evm_lcd_device, }; -static struct platform_device am3517_evm_dss_device = { - .name = "omapdss", - .id = -1, - .dev = { - .platform_data = &am3517_evm_dss_data, - }, -}; - /* * Board initialization */ static struct omap_board_config_kernel am3517_evm_config[] __initdata = { }; -static struct platform_device *am3517_evm_devices[] __initdata = { - &am3517_evm_dss_device, -}; - static void __init am3517_evm_init_irq(void) { omap_board_config = am3517_evm_config; @@ -495,9 +483,7 @@ static void __init am3517_evm_init(void) omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); am3517_evm_i2c_init(); - platform_add_devices(am3517_evm_devices, - ARRAY_SIZE(am3517_evm_devices)); - + omap_display_init(&am3517_evm_dss_data); omap_serial_init(); /* Configure GPIO for EHCI port */ diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c index dac14161066..2e9265ef3f9 100644 --- a/arch/arm/mach-omap2/board-cm-t35.c +++ b/arch/arm/mach-omap2/board-cm-t35.c @@ -401,14 +401,6 @@ static struct omap_dss_board_info cm_t35_dss_data = { .default_device = &cm_t35_dvi_device, }; -static struct platform_device cm_t35_dss_device = { - .name = "omapdss", - .id = -1, - .dev = { - .platform_data = &cm_t35_dss_data, - }, -}; - static struct omap2_mcspi_device_config tdo24m_mcspi_config = { .turbo_mode = 0, .single_channel = 1, /* 0: slave, 1: master */ @@ -468,7 +460,7 @@ static void __init cm_t35_init_display(void) msleep(50); gpio_set_value(lcd_en_gpio, 1); - err = platform_device_register(&cm_t35_dss_device); + err = omap_display_init(&cm_t35_dss_data); if (err) { pr_err("CM-T35: failed to register DSS device\n"); goto err_dev_reg; @@ -495,15 +487,11 @@ static struct regulator_consumer_supply cm_t35_vsim_supply = { .supply = "vmmc_aux", }; -static struct regulator_consumer_supply cm_t35_vdac_supply = { - .supply = "vdda_dac", - .dev = &cm_t35_dss_device.dev, -}; +static struct regulator_consumer_supply cm_t35_vdac_supply = + REGULATOR_SUPPLY("vdda_dac", "omap_venc"); -static struct regulator_consumer_supply cm_t35_vdvi_supply = { - .supply = "vdvi", - .dev = &cm_t35_dss_device.dev, -}; +static struct regulator_consumer_supply cm_t35_vdvi_supply = + REGULATOR_SUPPLY("vdvi", "omap_display"); /* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */ static struct regulator_init_data cm_t35_vmmc1 = { diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c index 9a2a31e011c..d277143c425 100644 --- a/arch/arm/mach-omap2/board-devkit8000.c +++ b/arch/arm/mach-omap2/board-devkit8000.c @@ -195,16 +195,8 @@ static struct omap_dss_board_info devkit8000_dss_data = { .default_device = &devkit8000_lcd_device, }; -static struct platform_device devkit8000_dss_device = { - .name = "omapdss", - .id = -1, - .dev = { - .platform_data = &devkit8000_dss_data, - }, -}; - static struct regulator_consumer_supply devkit8000_vdda_dac_supply = - REGULATOR_SUPPLY("vdda_dac", "omapdss"); + REGULATOR_SUPPLY("vdda_dac", "omap_venc"); static uint32_t board_keymap[] = { KEY(0, 0, KEY_1), @@ -285,8 +277,10 @@ static struct twl4030_gpio_platform_data devkit8000_gpio_data = { .setup = devkit8000_twl_gpio_setup, }; -static struct regulator_consumer_supply devkit8000_vpll1_supply = - REGULATOR_SUPPLY("vdds_dsi", "omapdss"); +static struct regulator_consumer_supply devkit8000_vpll1_supplies[] = { + REGULATOR_SUPPLY("vdds_dsi", "omap_display"), + REGULATOR_SUPPLY("vdds_dsi", "omap_dsi1"), +}; /* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */ static struct regulator_init_data devkit8000_vmmc1 = { @@ -327,8 +321,8 @@ static struct regulator_init_data devkit8000_vpll1 = { .valid_ops_mask = REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS, }, - .num_consumer_supplies = 1, - .consumer_supplies = &devkit8000_vpll1_supply, + .num_consumer_supplies = ARRAY_SIZE(devkit8000_vpll1_supplies), + .consumer_supplies = devkit8000_vpll1_supplies, }; /* VAUX4 for ads7846 and nubs */ @@ -575,7 +569,6 @@ static void __init omap_dm9000_init(void) } static struct platform_device *devkit8000_devices[] __initdata = { - &devkit8000_dss_device, &leds_gpio, &keys_gpio, &omap_dm9000_dev, @@ -797,6 +790,7 @@ static void __init devkit8000_init(void) platform_add_devices(devkit8000_devices, ARRAY_SIZE(devkit8000_devices)); + omap_display_init(&devkit8000_dss_data); spi_register_board_info(devkit8000_spi_board_info, ARRAY_SIZE(devkit8000_spi_board_info)); diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c index 3be85a1f55f..dfbe3a1eaa8 100644 --- a/arch/arm/mach-omap2/board-igep0020.c +++ b/arch/arm/mach-omap2/board-igep0020.c @@ -485,17 +485,9 @@ static struct omap_dss_board_info igep2_dss_data = { .default_device = &igep2_dvi_device, }; -static struct platform_device igep2_dss_device = { - .name = "omapdss", - .id = -1, - .dev = { - .platform_data = &igep2_dss_data, - }, -}; - -static struct regulator_consumer_supply igep2_vpll2_supply = { - .supply = "vdds_dsi", - .dev = &igep2_dss_device.dev, +static struct regulator_consumer_supply igep2_vpll2_supplies[] = { + REGULATOR_SUPPLY("vdds_dsi", "omap_display"), + REGULATOR_SUPPLY("vdds_dsi", "omap_dsi1"), }; static struct regulator_init_data igep2_vpll2 = { @@ -509,8 +501,8 @@ static struct regulator_init_data igep2_vpll2 = { .valid_ops_mask = REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS, }, - .num_consumer_supplies = 1, - .consumer_supplies = &igep2_vpll2_supply, + .num_consumer_supplies = ARRAY_SIZE(igep2_vpll2_supplies), + .consumer_supplies = igep2_vpll2_supplies, }; static void __init igep2_display_init(void) @@ -521,7 +513,6 @@ static void __init igep2_display_init(void) } static struct platform_device *igep2_devices[] __initdata = { - &igep2_dss_device, &igep2_vwlan_device, }; @@ -697,6 +688,7 @@ static void __init igep2_init(void) /* Register I2C busses and drivers */ igep2_i2c_init(); platform_add_devices(igep2_devices, ARRAY_SIZE(igep2_devices)); + omap_display_init(&igep2_dss_data); omap_serial_init(); usb_musb_init(&musb_board_data); usb_ehci_init(&ehci_pdata); diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c index 46d814ab565..caf6c8aedac 100644 --- a/arch/arm/mach-omap2/board-omap3beagle.c +++ b/arch/arm/mach-omap2/board-omap3beagle.c @@ -228,19 +228,13 @@ static struct omap_dss_board_info beagle_dss_data = { .default_device = &beagle_dvi_device, }; -static struct platform_device beagle_dss_device = { - .name = "omapdss", - .id = -1, - .dev = { - .platform_data = &beagle_dss_data, - }, -}; - static struct regulator_consumer_supply beagle_vdac_supply = - REGULATOR_SUPPLY("vdda_dac", "omapdss"); + REGULATOR_SUPPLY("vdda_dac", "omap_venc"); -static struct regulator_consumer_supply beagle_vdvi_supply = - REGULATOR_SUPPLY("vdds_dsi", "omapdss"); +static struct regulator_consumer_supply beagle_vdvi_supplies[] = { + REGULATOR_SUPPLY("vdds_dsi", "omap_display"), + REGULATOR_SUPPLY("vdds_dsi", "omap_dsi1"), +}; static void __init beagle_display_init(void) { @@ -427,8 +421,8 @@ static struct regulator_init_data beagle_vpll2 = { .valid_ops_mask = REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS, }, - .num_consumer_supplies = 1, - .consumer_supplies = &beagle_vdvi_supply, + .num_consumer_supplies = ARRAY_SIZE(beagle_vdvi_supplies), + .consumer_supplies = beagle_vdvi_supplies, }; static struct twl4030_usb_data beagle_usb_data = { @@ -550,7 +544,6 @@ static void __init omap3_beagle_init_irq(void) static struct platform_device *omap3_beagle_devices[] __initdata = { &leds_gpio, &keys_gpio, - &beagle_dss_device, }; static void __init omap3beagle_flash_init(void) @@ -617,6 +610,7 @@ static void __init omap3_beagle_init(void) omap3_beagle_i2c_init(); platform_add_devices(omap3_beagle_devices, ARRAY_SIZE(omap3_beagle_devices)); + omap_display_init(&beagle_dss_data); omap_serial_init(); omap_mux_init_gpio(170, OMAP_PIN_INPUT); diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c index 323c3809ce3..0c56b9edf65 100644 --- a/arch/arm/mach-omap2/board-omap3evm.c +++ b/arch/arm/mach-omap2/board-omap3evm.c @@ -328,14 +328,6 @@ static struct omap_dss_board_info omap3_evm_dss_data = { .default_device = &omap3_evm_lcd_device, }; -static struct platform_device omap3_evm_dss_device = { - .name = "omapdss", - .id = -1, - .dev = { - .platform_data = &omap3_evm_dss_data, - }, -}; - static struct regulator_consumer_supply omap3evm_vmmc1_supply = { .supply = "vmmc", }; @@ -500,10 +492,8 @@ static struct twl4030_codec_data omap3evm_codec_data = { .audio = &omap3evm_audio_data, }; -static struct regulator_consumer_supply omap3_evm_vdda_dac_supply = { - .supply = "vdda_dac", - .dev = &omap3_evm_dss_device.dev, -}; +static struct regulator_consumer_supply omap3_evm_vdda_dac_supply = + REGULATOR_SUPPLY("vdda_dac", "omap_venc"); /* VDAC for DSS driving S-Video */ static struct regulator_init_data omap3_evm_vdac = { @@ -521,8 +511,10 @@ static struct regulator_init_data omap3_evm_vdac = { }; /* VPLL2 for digital video outputs */ -static struct regulator_consumer_supply omap3_evm_vpll2_supply = - REGULATOR_SUPPLY("vdds_dsi", "omapdss"); +static struct regulator_consumer_supply omap3_evm_vpll2_supplies[] = { + REGULATOR_SUPPLY("vdds_dsi", "omap_display"), + REGULATOR_SUPPLY("vdds_dsi", "omap_dsi1"), +}; static struct regulator_init_data omap3_evm_vpll2 = { .constraints = { @@ -534,8 +526,8 @@ static struct regulator_init_data omap3_evm_vpll2 = { .valid_ops_mask = REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS, }, - .num_consumer_supplies = 1, - .consumer_supplies = &omap3_evm_vpll2_supply, + .num_consumer_supplies = ARRAY_SIZE(omap3_evm_vpll2_supplies), + .consumer_supplies = omap3_evm_vpll2_supplies, }; static struct twl4030_platform_data omap3evm_twldata = { @@ -634,10 +626,6 @@ static void __init omap3_evm_init_irq(void) omap_init_irq(); } -static struct platform_device *omap3_evm_devices[] __initdata = { - &omap3_evm_dss_device, -}; - static struct ehci_hcd_omap_platform_data ehci_pdata __initdata = { .port_mode[0] = EHCI_HCD_OMAP_MODE_UNKNOWN, @@ -675,7 +663,7 @@ static void __init omap3_evm_init(void) omap3_evm_i2c_init(); - platform_add_devices(omap3_evm_devices, ARRAY_SIZE(omap3_evm_devices)); + omap_display_init(&omap3_evm_dss_data); spi_register_board_info(omap3evm_spi_board_info, ARRAY_SIZE(omap3evm_spi_board_info)); diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c index 0b34beded11..b430d2bce8f 100644 --- a/arch/arm/mach-omap2/board-omap3pandora.c +++ b/arch/arm/mach-omap2/board-omap3pandora.c @@ -253,14 +253,6 @@ static struct omap_dss_board_info pandora_dss_data = { .default_device = &pandora_lcd_device, }; -static struct platform_device pandora_dss_device = { - .name = "omapdss", - .id = -1, - .dev = { - .platform_data = &pandora_dss_data, - }, -}; - static void pandora_wl1251_init_card(struct mmc_card *card) { /* @@ -350,11 +342,12 @@ static struct regulator_consumer_supply pandora_vmmc3_supply = REGULATOR_SUPPLY("vmmc", "mmci-omap-hs.2"); static struct regulator_consumer_supply pandora_vdda_dac_supply = - REGULATOR_SUPPLY("vdda_dac", "omapdss"); + REGULATOR_SUPPLY("vdda_dac", "omap_venc"); static struct regulator_consumer_supply pandora_vdds_supplies[] = { - REGULATOR_SUPPLY("vdds_sdi", "omapdss"), - REGULATOR_SUPPLY("vdds_dsi", "omapdss"), + REGULATOR_SUPPLY("vdds_sdi", "omap_display"), + REGULATOR_SUPPLY("vdds_dsi", "omap_display"), + REGULATOR_SUPPLY("vdds_dsi", "omap_dsi1"), }; static struct regulator_consumer_supply pandora_vcc_lcd_supply = @@ -677,7 +670,6 @@ fail: static struct platform_device *omap3pandora_devices[] __initdata = { &pandora_leds_gpio, &pandora_keys_gpio, - &pandora_dss_device, &pandora_vwlan_device, }; @@ -712,6 +704,7 @@ static void __init omap3pandora_init(void) pandora_wl1251_init(); platform_add_devices(omap3pandora_devices, ARRAY_SIZE(omap3pandora_devices)); + omap_display_init(&pandora_dss_data); omap_serial_init(); spi_register_board_info(omap3pandora_spi_board_info, ARRAY_SIZE(omap3pandora_spi_board_info)); diff --git a/arch/arm/mach-omap2/board-omap3stalker.c b/arch/arm/mach-omap2/board-omap3stalker.c index 2a2dad447e8..b5e868044c1 100644 --- a/arch/arm/mach-omap2/board-omap3stalker.c +++ b/arch/arm/mach-omap2/board-omap3stalker.c @@ -240,14 +240,6 @@ static struct omap_dss_board_info omap3_stalker_dss_data = { .default_device = &omap3_stalker_dvi_device, }; -static struct platform_device omap3_stalker_dss_device = { - .name = "omapdss", - .id = -1, - .dev = { - .platform_data = &omap3_stalker_dss_data, - }, -}; - static struct regulator_consumer_supply omap3stalker_vmmc1_supply = { .supply = "vmmc", }; @@ -448,10 +440,8 @@ static struct twl4030_codec_data omap3stalker_codec_data = { .audio = &omap3stalker_audio_data, }; -static struct regulator_consumer_supply omap3_stalker_vdda_dac_supply = { - .supply = "vdda_dac", - .dev = &omap3_stalker_dss_device.dev, -}; +static struct regulator_consumer_supply omap3_stalker_vdda_dac_supply = + REGULATOR_SUPPLY("vdda_dac", "omap_venc"); /* VDAC for DSS driving S-Video */ static struct regulator_init_data omap3_stalker_vdac = { @@ -469,9 +459,9 @@ static struct regulator_init_data omap3_stalker_vdac = { }; /* VPLL2 for digital video outputs */ -static struct regulator_consumer_supply omap3_stalker_vpll2_supply = { - .supply = "vdds_dsi", - .dev = &omap3_stalker_lcd_device.dev, +static struct regulator_consumer_supply omap3_stalker_vpll2_supplies[] = { + REGULATOR_SUPPLY("vdds_dsi", "omap_display"), + REGULATOR_SUPPLY("vdds_dsi", "omap_dsi1"), }; static struct regulator_init_data omap3_stalker_vpll2 = { @@ -485,8 +475,8 @@ static struct regulator_init_data omap3_stalker_vpll2 = { .valid_ops_mask = REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS, }, - .num_consumer_supplies = 1, - .consumer_supplies = &omap3_stalker_vpll2_supply, + .num_consumer_supplies = ARRAY_SIZE(omap3_stalker_vpll2_supplies), + .consumer_supplies = omap3_stalker_vpll2_supplies, }; static struct twl4030_platform_data omap3stalker_twldata = { @@ -604,7 +594,6 @@ static void __init omap3_stalker_init_irq(void) } static struct platform_device *omap3_stalker_devices[] __initdata = { - &omap3_stalker_dss_device, &keys_gpio, }; @@ -644,6 +633,7 @@ static void __init omap3_stalker_init(void) platform_add_devices(omap3_stalker_devices, ARRAY_SIZE(omap3_stalker_devices)); + omap_display_init(&omap3_stalker_dss_data); spi_register_board_info(omap3stalker_spi_board_info, ARRAY_SIZE(omap3stalker_spi_board_info)); diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c index e944025d5ef..b09d23925f4 100644 --- a/arch/arm/mach-omap2/board-omap4panda.c +++ b/arch/arm/mach-omap2/board-omap4panda.c @@ -37,6 +37,7 @@ #include <plat/common.h> #include <plat/usb.h> #include <plat/mmc.h> +#include <plat/panel-generic-dpi.h> #include "timer-gp.h" #include "hsmmc.h" @@ -76,6 +77,60 @@ static struct platform_device *panda_devices[] __initdata = { &leds_gpio, }; +/* Display DVI */ +#define PANDA_DVI_TFP410_POWER_DOWN_GPIO 0 + +static int panda_enable_dvi(struct omap_dss_device *dssdev) +{ + gpio_set_value(dssdev->reset_gpio, 1); + return 0; +} + +static void panda_disable_dvi(struct omap_dss_device *dssdev) +{ + gpio_set_value(dssdev->reset_gpio, 0); +} + +/* Using generic display panel */ +static struct panel_generic_dpi_data dvi_panel = { + .name = "generic", + .platform_enable = panda_enable_dvi, + .platform_disable = panda_disable_dvi, +}; + +struct omap_dss_device panda_dvi_device = { + .type = OMAP_DISPLAY_TYPE_DPI, + .name = "dvi", + .driver_name = "generic_dpi_panel", + .data = &dvi_panel, + .phy.dpi.data_lines = 24, + .reset_gpio = PANDA_DVI_TFP410_POWER_DOWN_GPIO, + .channel = OMAP_DSS_CHANNEL_LCD2, +}; + +int __init panda_dvi_init(void) +{ + int r; + + /* Requesting TFP410 DVI GPIO and disabling it, at bootup */ + r = gpio_request_one(panda_dvi_device.reset_gpio, + GPIOF_OUT_INIT_LOW, "DVI PD"); + if (r) + pr_err("Failed to get DVI powerdown GPIO\n"); + + return r; +} + +static struct omap_dss_device *panda_dss_devices[] = { + &panda_dvi_device, +}; + +static struct omap_dss_board_info panda_dss_data = { + .num_devices = ARRAY_SIZE(panda_dss_devices), + .devices = panda_dss_devices, + .default_device = &panda_dvi_device, +}; + static void __init omap4_panda_init_irq(void) { omap2_init_common_infrastructure(); @@ -375,6 +430,17 @@ static struct i2c_board_info __initdata omap4_panda_i2c_boardinfo[] = { .platform_data = &omap4_panda_twldata, }, }; + +/* + * Display monitor features are burnt in their EEPROM as EDID data. The EEPROM + * is connected as I2C slave device, and can be accessed at address 0x50 + */ +static struct i2c_board_info __initdata panda_i2c_eeprom[] = { + { + I2C_BOARD_INFO("eeprom", 0x50), + }, +}; + static int __init omap4_panda_i2c_init(void) { /* @@ -384,13 +450,76 @@ static int __init omap4_panda_i2c_init(void) omap_register_i2c_bus(1, 400, omap4_panda_i2c_boardinfo, ARRAY_SIZE(omap4_panda_i2c_boardinfo)); omap_register_i2c_bus(2, 400, NULL, 0); - omap_register_i2c_bus(3, 400, NULL, 0); + /* + * Bus 3 is attached to the DVI port where devices like the pico DLP + * projector don't work reliably with 400kHz + */ + omap_register_i2c_bus(3, 100, panda_i2c_eeprom, + ARRAY_SIZE(panda_i2c_eeprom)); omap_register_i2c_bus(4, 400, NULL, 0); return 0; } #ifdef CONFIG_OMAP_MUX static struct omap_board_mux board_mux[] __initdata = { + /* gpio 0 - TFP410 PD */ + OMAP4_MUX(KPD_COL1, OMAP_PIN_OUTPUT | OMAP_MUX_MODE3), + /* dispc2_data23 */ + OMAP4_MUX(USBB2_ULPITLL_STP, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5), + /* dispc2_data22 */ + OMAP4_MUX(USBB2_ULPITLL_DIR, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5), + /* dispc2_data21 */ + OMAP4_MUX(USBB2_ULPITLL_NXT, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5), + /* dispc2_data20 */ + OMAP4_MUX(USBB2_ULPITLL_DAT0, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5), + /* dispc2_data19 */ + OMAP4_MUX(USBB2_ULPITLL_DAT1, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5), + /* dispc2_data18 */ + OMAP4_MUX(USBB2_ULPITLL_DAT2, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5), + /* dispc2_data15 */ + OMAP4_MUX(USBB2_ULPITLL_DAT3, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5), + /* dispc2_data14 */ + OMAP4_MUX(USBB2_ULPITLL_DAT4, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5), + /* dispc2_data13 */ + OMAP4_MUX(USBB2_ULPITLL_DAT5, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5), + /* dispc2_data12 */ + OMAP4_MUX(USBB2_ULPITLL_DAT6, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5), + /* dispc2_data11 */ + OMAP4_MUX(USBB2_ULPITLL_DAT7, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5), + /* dispc2_data10 */ + OMAP4_MUX(DPM_EMU3, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5), + /* dispc2_data9 */ + OMAP4_MUX(DPM_EMU4, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5), + /* dispc2_data16 */ + OMAP4_MUX(DPM_EMU5, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5), + /* dispc2_data17 */ + OMAP4_MUX(DPM_EMU6, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5), + /* dispc2_hsync */ + OMAP4_MUX(DPM_EMU7, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5), + /* dispc2_pclk */ + OMAP4_MUX(DPM_EMU8, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5), + /* dispc2_vsync */ + OMAP4_MUX(DPM_EMU9, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5), + /* dispc2_de */ + OMAP4_MUX(DPM_EMU10, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5), + /* dispc2_data8 */ + OMAP4_MUX(DPM_EMU11, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5), + /* dispc2_data7 */ + OMAP4_MUX(DPM_EMU12, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5), + /* dispc2_data6 */ + OMAP4_MUX(DPM_EMU13, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5), + /* dispc2_data5 */ + OMAP4_MUX(DPM_EMU14, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5), + /* dispc2_data4 */ + OMAP4_MUX(DPM_EMU15, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5), + /* dispc2_data3 */ + OMAP4_MUX(DPM_EMU16, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5), + /* dispc2_data2 */ + OMAP4_MUX(DPM_EMU17, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5), + /* dispc2_data1 */ + OMAP4_MUX(DPM_EMU18, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5), + /* dispc2_data0 */ + OMAP4_MUX(DPM_EMU19, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5), { .reg_offset = OMAP_MUX_TERMINATOR }, }; #else @@ -400,6 +529,7 @@ static struct omap_board_mux board_mux[] __initdata = { static void __init omap4_panda_init(void) { int package = OMAP_PACKAGE_CBS; + int err; if (omap_rev() == OMAP4430_REV_ES1_0) package = OMAP_PACKAGE_CBL; @@ -411,6 +541,11 @@ static void __init omap4_panda_init(void) omap4_twl6030_hsmmc_init(mmc); omap4_ehci_init(); usb_musb_init(&musb_board_data); + + /* Enabling DVI Display */ + err = panda_dvi_init(); + if (!err) + omap_display_init(&panda_dss_data); } static void __init omap4_panda_map_io(void) diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c index cb26e5d8268..90c256879ed 100644 --- a/arch/arm/mach-omap2/board-overo.c +++ b/arch/arm/mach-omap2/board-overo.c @@ -28,6 +28,7 @@ #include <linux/platform_device.h> #include <linux/i2c/twl.h> #include <linux/regulator/machine.h> +#include <linux/spi/spi.h> #include <linux/mtd/mtd.h> #include <linux/mtd/nand.h> @@ -41,10 +42,14 @@ #include <plat/board.h> #include <plat/common.h> +#include <plat/display.h> +#include <plat/panel-generic-dpi.h> #include <mach/gpio.h> #include <plat/gpmc.h> #include <mach/hardware.h> #include <plat/nand.h> +#include <plat/mcspi.h> +#include <plat/mux.h> #include <plat/usb.h> #include "mux.h" @@ -68,8 +73,6 @@ #if defined(CONFIG_TOUCHSCREEN_ADS7846) || \ defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) -#include <plat/mcspi.h> -#include <linux/spi/spi.h> #include <linux/spi/ads7846.h> static struct omap2_mcspi_device_config ads7846_mcspi_config = { @@ -94,18 +97,6 @@ static struct ads7846_platform_data ads7846_config = { .keep_vref_on = 1, }; -static struct spi_board_info overo_spi_board_info[] __initdata = { - { - .modalias = "ads7846", - .bus_num = 1, - .chip_select = 0, - .max_speed_hz = 1500000, - .controller_data = &ads7846_mcspi_config, - .irq = OMAP_GPIO_IRQ(OVERO_GPIO_PENDOWN), - .platform_data = &ads7846_config, - } -}; - static void __init overo_ads7846_init(void) { if ((gpio_request(OVERO_GPIO_PENDOWN, "ADS7846_PENDOWN") == 0) && @@ -115,9 +106,6 @@ static void __init overo_ads7846_init(void) printk(KERN_ERR "could not obtain gpio for ADS7846_PENDOWN\n"); return; } - - spi_register_board_info(overo_spi_board_info, - ARRAY_SIZE(overo_spi_board_info)); } #else @@ -233,6 +221,140 @@ static inline void __init overo_init_smsc911x(void) static inline void __init overo_init_smsc911x(void) { return; } #endif +/* DSS */ +static int lcd_enabled; +static int dvi_enabled; + +#define OVERO_GPIO_LCD_EN 144 +#define OVERO_GPIO_LCD_BL 145 + +static void __init overo_display_init(void) +{ + if ((gpio_request(OVERO_GPIO_LCD_EN, "OVERO_GPIO_LCD_EN") == 0) && + (gpio_direction_output(OVERO_GPIO_LCD_EN, 1) == 0)) + gpio_export(OVERO_GPIO_LCD_EN, 0); + else + printk(KERN_ERR "could not obtain gpio for " + "OVERO_GPIO_LCD_EN\n"); + + if ((gpio_request(OVERO_GPIO_LCD_BL, "OVERO_GPIO_LCD_BL") == 0) && + (gpio_direction_output(OVERO_GPIO_LCD_BL, 1) == 0)) + gpio_export(OVERO_GPIO_LCD_BL, 0); + else + printk(KERN_ERR "could not obtain gpio for " + "OVERO_GPIO_LCD_BL\n"); +} + +static int overo_panel_enable_dvi(struct omap_dss_device *dssdev) +{ + if (lcd_enabled) { + printk(KERN_ERR "cannot enable DVI, LCD is enabled\n"); + return -EINVAL; + } + dvi_enabled = 1; + + return 0; +} + +static void overo_panel_disable_dvi(struct omap_dss_device *dssdev) +{ + dvi_enabled = 0; +} + +static struct panel_generic_dpi_data dvi_panel = { + .name = "generic", + .platform_enable = overo_panel_enable_dvi, + .platform_disable = overo_panel_disable_dvi, +}; + +static struct omap_dss_device overo_dvi_device = { + .type = OMAP_DISPLAY_TYPE_DPI, + .name = "dvi", + .driver_name = "generic_dpi_panel", + .data = &dvi_panel, + .phy.dpi.data_lines = 24, + .reset_gpio = -EINVAL, +}; + +static struct omap_dss_device overo_tv_device = { + .name = "tv", + .driver_name = "venc", + .type = OMAP_DISPLAY_TYPE_VENC, + .phy.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO, +}; + +static int overo_panel_enable_lcd(struct omap_dss_device *dssdev) +{ + if (dvi_enabled) { + printk(KERN_ERR "cannot enable LCD, DVI is enabled\n"); + return -EINVAL; + } + + gpio_set_value(OVERO_GPIO_LCD_EN, 1); + gpio_set_value(OVERO_GPIO_LCD_BL, 1); + lcd_enabled = 1; + return 0; +} + +static void overo_panel_disable_lcd(struct omap_dss_device *dssdev) +{ + gpio_set_value(OVERO_GPIO_LCD_EN, 0); + gpio_set_value(OVERO_GPIO_LCD_BL, 0); + lcd_enabled = 0; +} + +#if defined(CONFIG_PANEL_LGPHILIPS_LB035Q02) || \ + defined(CONFIG_PANEL_LGPHILIPS_LB035Q02_MODULE) +static struct omap_dss_device overo_lcd35_device = { + .type = OMAP_DISPLAY_TYPE_DPI, + .name = "lcd35", + .driver_name = "lgphilips_lb035q02_panel", + .phy.dpi.data_lines = 24, + .platform_enable = overo_panel_enable_lcd, + .platform_disable = overo_panel_disable_lcd, +}; +#endif + +#if defined(CONFIG_PANEL_SAMSUNG_LTE430WQ_F0C) || \ + defined(CONFIG_PANEL_SAMSUNG_LTE430WQ_F0C_MODULE) +static struct omap_dss_device overo_lcd43_device = { + .type = OMAP_DISPLAY_TYPE_DPI, + .name = "lcd43", + .driver_name = "samsung_lte_panel", + .phy.dpi.data_lines = 24, + .platform_enable = overo_panel_enable_lcd, + .platform_disable = overo_panel_disable_lcd, +}; +#endif + +static struct omap_dss_device *overo_dss_devices[] = { + &overo_dvi_device, + &overo_tv_device, +#if defined(CONFIG_PANEL_LGPHILIPS_LB035Q02) || \ + defined(CONFIG_PANEL_LGPHILIPS_LB035Q02_MODULE) + &overo_lcd35_device, +#endif +#if defined(CONFIG_PANEL_SAMSUNG_LTE430WQ_F0C) || \ + defined(CONFIG_PANEL_SAMSUNG_LTE430WQ_F0C_MODULE) + &overo_lcd43_device, +#endif +}; + +static struct omap_dss_board_info overo_dss_data = { + .num_devices = ARRAY_SIZE(overo_dss_devices), + .devices = overo_dss_devices, + .default_device = &overo_dvi_device, +}; + +static struct regulator_consumer_supply overo_vdda_dac_supply = + REGULATOR_SUPPLY("vdda_dac", "omap_venc"); + +static struct regulator_consumer_supply overo_vdds_supplies[] = { + REGULATOR_SUPPLY("vdds_sdi", "omap_display"), + REGULATOR_SUPPLY("vdds_dsi", "omap_display"), + REGULATOR_SUPPLY("vdds_dsi", "omap_dsi1"), +}; + static struct mtd_partition overo_nand_partitions[] = { { .name = "xloader", @@ -358,6 +480,37 @@ static struct regulator_init_data overo_vmmc1 = { .consumer_supplies = &overo_vmmc1_supply, }; +/* VDAC for DSS driving S-Video (8 mA unloaded, max 65 mA) */ +static struct regulator_init_data overo_vdac = { + .constraints = { + .min_uV = 1800000, + .max_uV = 1800000, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &overo_vdda_dac_supply, +}; + +/* VPLL2 for digital video outputs */ +static struct regulator_init_data overo_vpll2 = { + .constraints = { + .name = "VDVI", + .min_uV = 1800000, + .max_uV = 1800000, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(overo_vdds_supplies), + .consumer_supplies = &overo_vdds_supplies, +}; + +/* mmc2 (WLAN) and Bluetooth don't use twl4030 regulators */ + static struct twl4030_codec_audio_data overo_audio_data = { .audio_mclk = 26000000, }; @@ -376,6 +529,8 @@ static struct twl4030_platform_data overo_twldata = { .usb = &overo_usb_data, .codec = &overo_codec_data, .vmmc1 = &overo_vmmc1, + .vdac = &overo_vdac, + .vpll2 = &overo_vpll2, }; static struct i2c_board_info __initdata overo_i2c_boardinfo[] = { @@ -396,33 +551,47 @@ static int __init overo_i2c_init(void) return 0; } -static struct platform_device overo_lcd_device = { - .name = "overo_lcd", - .id = -1, -}; - -static struct omap_lcd_config overo_lcd_config __initdata = { - .ctrl_name = "internal", +static struct spi_board_info overo_spi_board_info[] __initdata = { +#if defined(CONFIG_TOUCHSCREEN_ADS7846) || \ + defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) + { + .modalias = "ads7846", + .bus_num = 1, + .chip_select = 0, + .max_speed_hz = 1500000, + .controller_data = &ads7846_mcspi_config, + .irq = OMAP_GPIO_IRQ(OVERO_GPIO_PENDOWN), + .platform_data = &ads7846_config, + }, +#endif +#if defined(CONFIG_PANEL_LGPHILIPS_LB035Q02) || \ + defined(CONFIG_PANEL_LGPHILIPS_LB035Q02_MODULE) + { + .modalias = "lgphilips_lb035q02_panel-spi", + .bus_num = 1, + .chip_select = 1, + .max_speed_hz = 500000, + .mode = SPI_MODE_3, + }, +#endif }; -static struct omap_board_config_kernel overo_config[] __initdata = { - { OMAP_TAG_LCD, &overo_lcd_config }, -}; +static int __init overo_spi_init(void) +{ + overo_ads7846_init(); + spi_register_board_info(overo_spi_board_info, + ARRAY_SIZE(overo_spi_board_info)); + return 0; +} static void __init overo_init_irq(void) { - omap_board_config = overo_config; - omap_board_config_size = ARRAY_SIZE(overo_config); omap2_init_common_infrastructure(); omap2_init_common_devices(mt46h32m32lf6_sdrc_params, mt46h32m32lf6_sdrc_params); omap_init_irq(); } -static struct platform_device *overo_devices[] __initdata = { - &overo_lcd_device, -}; - static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { .port_mode[0] = EHCI_HCD_OMAP_MODE_UNKNOWN, .port_mode[1] = EHCI_HCD_OMAP_MODE_PHY, @@ -450,13 +619,14 @@ static void __init overo_init(void) { omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); overo_i2c_init(); - platform_add_devices(overo_devices, ARRAY_SIZE(overo_devices)); + omap_display_init(&overo_dss_data); omap_serial_init(); overo_flash_init(); usb_musb_init(&musb_board_data); usb_ehci_init(&ehci_pdata); - overo_ads7846_init(); + overo_spi_init(); overo_init_smsc911x(); + overo_display_init(); /* Ensure SDRC pins are mux'd for self-refresh */ omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT); diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c index e75e240cad6..b783854476b 100644 --- a/arch/arm/mach-omap2/board-rx51-peripherals.c +++ b/arch/arm/mach-omap2/board-rx51-peripherals.c @@ -360,11 +360,11 @@ static struct regulator_consumer_supply rx51_vio_supplies[] = { }; static struct regulator_consumer_supply rx51_vaux1_consumers[] = { - REGULATOR_SUPPLY("vdds_sdi", "omapdss"), + REGULATOR_SUPPLY("vdds_sdi", "omap_display"), }; static struct regulator_consumer_supply rx51_vdac_supply[] = { - REGULATOR_SUPPLY("vdda_dac", "omapdss"), + REGULATOR_SUPPLY("vdda_dac", "omap_venc"), }; static struct regulator_init_data rx51_vaux1 = { diff --git a/arch/arm/mach-omap2/board-rx51-video.c b/arch/arm/mach-omap2/board-rx51-video.c index acd670054d9..89a66db8b77 100644 --- a/arch/arm/mach-omap2/board-rx51-video.c +++ b/arch/arm/mach-omap2/board-rx51-video.c @@ -66,18 +66,6 @@ static struct omap_dss_board_info rx51_dss_board_info = { .default_device = &rx51_lcd_device, }; -struct platform_device rx51_display_device = { - .name = "omapdss", - .id = -1, - .dev = { - .platform_data = &rx51_dss_board_info, - }, -}; - -static struct platform_device *rx51_video_devices[] __initdata = { - &rx51_display_device, -}; - static int __init rx51_video_init(void) { if (!machine_is_nokia_rx51()) @@ -95,8 +83,7 @@ static int __init rx51_video_init(void) gpio_direction_output(RX51_LCD_RESET_GPIO, 1); - platform_add_devices(rx51_video_devices, - ARRAY_SIZE(rx51_video_devices)); + omap_display_init(&rx51_dss_board_info); return 0; } diff --git a/arch/arm/mach-omap2/board-zoom-display.c b/arch/arm/mach-omap2/board-zoom-display.c index 6bcd43657ae..37b84c2b850 100644 --- a/arch/arm/mach-omap2/board-zoom-display.c +++ b/arch/arm/mach-omap2/board-zoom-display.c @@ -130,14 +130,6 @@ static struct omap_dss_board_info zoom_dss_data = { .default_device = &zoom_lcd_device, }; -static struct platform_device zoom_dss_device = { - .name = "omapdss", - .id = -1, - .dev = { - .platform_data = &zoom_dss_data, - }, -}; - static struct omap2_mcspi_device_config dss_lcd_mcspi_config = { .turbo_mode = 1, .single_channel = 1, /* 0: slave, 1: master */ @@ -153,14 +145,9 @@ static struct spi_board_info nec_8048_spi_board_info[] __initdata = { }, }; -static struct platform_device *zoom_display_devices[] __initdata = { - &zoom_dss_device, -}; - void __init zoom_display_init(void) { - platform_add_devices(zoom_display_devices, - ARRAY_SIZE(zoom_display_devices)); + omap_display_init(&zoom_dss_data); spi_register_board_info(nec_8048_spi_board_info, ARRAY_SIZE(nec_8048_spi_board_info)); zoom_lcd_panel_init(); diff --git a/arch/arm/mach-omap2/board-zoom-peripherals.c b/arch/arm/mach-omap2/board-zoom-peripherals.c index e0e040f34c6..780a99c4359 100644 --- a/arch/arm/mach-omap2/board-zoom-peripherals.c +++ b/arch/arm/mach-omap2/board-zoom-peripherals.c @@ -226,11 +226,13 @@ static struct omap2_hsmmc_info mmc[] = { {} /* Terminator */ }; -static struct regulator_consumer_supply zoom_vpll2_supply = - REGULATOR_SUPPLY("vdds_dsi", "omapdss"); +static struct regulator_consumer_supply zoom_vpll2_supplies[] = { + REGULATOR_SUPPLY("vdds_dsi", "omap_display"), + REGULATOR_SUPPLY("vdds_dsi", "omap_dsi1"), +}; static struct regulator_consumer_supply zoom_vdda_dac_supply = - REGULATOR_SUPPLY("vdda_dac", "omapdss"); + REGULATOR_SUPPLY("vdda_dac", "omap_venc"); static struct regulator_init_data zoom_vpll2 = { .constraints = { @@ -241,8 +243,8 @@ static struct regulator_init_data zoom_vpll2 = { .valid_ops_mask = REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS, }, - .num_consumer_supplies = 1, - .consumer_supplies = &zoom_vpll2_supply, + .num_consumer_supplies = ARRAY_SIZE(zoom_vpll2_supplies), + .consumer_supplies = zoom_vpll2_supplies, }; static struct regulator_init_data zoom_vdac = { diff --git a/arch/arm/mach-omap2/board-zoom.c b/arch/arm/mach-omap2/board-zoom.c index e26754c24ee..6bd364afe66 100644 --- a/arch/arm/mach-omap2/board-zoom.c +++ b/arch/arm/mach-omap2/board-zoom.c @@ -30,6 +30,24 @@ #include "mux.h" #include "sdram-micron-mt46h32m32lf-6.h" #include "sdram-hynix-h8mbx00u0mer-0em.h" +#include "pm.h" + +static struct cpuidle_params omap36xx_cpuidle_params_table[] = { + /* C1 */ + {1, 74, 78, 152}, + /* C2 */ + {0, 165, 90, 255}, + /* C3 */ + {1, 163, 180, 345}, + /* C4 */ + {0, 2852, 605, 3457}, + /* C5 */ + {1, 800, 366, 2120}, + /* C6 */ + {0, 4080, 801, 4881}, + /* C7 */ + {1, 4300, 8794, 159000}, +}; #define ZOOM3_EHCI_RESET_GPIO 64 @@ -126,6 +144,7 @@ static void __init omap_zoom_init(void) usb_ehci_init(&ehci_pdata); } + omap3_pm_init_cpuidle(omap36xx_cpuidle_params_table); board_nand_init(zoom_nand_partitions, ARRAY_SIZE(zoom_nand_partitions), ZOOM_NAND_CS); zoom_debugboard_init(); diff --git a/arch/arm/mach-omap2/clock2420_data.c b/arch/arm/mach-omap2/clock2420_data.c index 0a992bc8d0d..dd9fd87a731 100644 --- a/arch/arm/mach-omap2/clock2420_data.c +++ b/arch/arm/mach-omap2/clock2420_data.c @@ -1786,10 +1786,10 @@ static struct omap_clk omap2420_clks[] = { CLK(NULL, "gfx_2d_fck", &gfx_2d_fck, CK_242X), CLK(NULL, "gfx_ick", &gfx_ick, CK_242X), /* DSS domain clocks */ - CLK("omapdss", "ick", &dss_ick, CK_242X), - CLK("omapdss", "dss1_fck", &dss1_fck, CK_242X), - CLK("omapdss", "dss2_fck", &dss2_fck, CK_242X), - CLK("omapdss", "tv_fck", &dss_54m_fck, CK_242X), + CLK("omap_dss", "ick", &dss_ick, CK_242X), + CLK("omap_dss", "fck", &dss1_fck, CK_242X), + CLK("omap_dss", "sys_clk", &dss2_fck, CK_242X), + CLK("omap_dss", "tv_clk", &dss_54m_fck, CK_242X), /* L3 domain clocks */ CLK(NULL, "core_l3_ck", &core_l3_ck, CK_242X), CLK(NULL, "ssi_fck", &ssi_ssr_sst_fck, CK_242X), @@ -1799,6 +1799,7 @@ static struct omap_clk omap2420_clks[] = { CLK(NULL, "ssi_l4_ick", &ssi_l4_ick, CK_242X), /* virtual meta-group clock */ CLK(NULL, "virt_prcm_set", &virt_prcm_set, CK_242X), + CLK(NULL, "cpu_ck", &virt_prcm_set, CK_242X), /* general l4 interface ck, multi-parent functional clk */ CLK(NULL, "gpt1_ick", &gpt1_ick, CK_242X), CLK(NULL, "gpt1_fck", &gpt1_fck, CK_242X), diff --git a/arch/arm/mach-omap2/clock2430_data.c b/arch/arm/mach-omap2/clock2430_data.c index c047dcd007e..c698c1c8778 100644 --- a/arch/arm/mach-omap2/clock2430_data.c +++ b/arch/arm/mach-omap2/clock2430_data.c @@ -1890,10 +1890,10 @@ static struct omap_clk omap2430_clks[] = { CLK(NULL, "mdm_ick", &mdm_ick, CK_243X), CLK(NULL, "mdm_osc_ck", &mdm_osc_ck, CK_243X), /* DSS domain clocks */ - CLK("omapdss", "ick", &dss_ick, CK_243X), - CLK("omapdss", "dss1_fck", &dss1_fck, CK_243X), - CLK("omapdss", "dss2_fck", &dss2_fck, CK_243X), - CLK("omapdss", "tv_fck", &dss_54m_fck, CK_243X), + CLK("omap_dss", "ick", &dss_ick, CK_243X), + CLK("omap_dss", "fck", &dss1_fck, CK_243X), + CLK("omap_dss", "sys_clk", &dss2_fck, CK_243X), + CLK("omap_dss", "tv_clk", &dss_54m_fck, CK_243X), /* L3 domain clocks */ CLK(NULL, "core_l3_ck", &core_l3_ck, CK_243X), CLK(NULL, "ssi_fck", &ssi_ssr_sst_fck, CK_243X), @@ -1903,6 +1903,7 @@ static struct omap_clk omap2430_clks[] = { CLK(NULL, "ssi_l4_ick", &ssi_l4_ick, CK_243X), /* virtual meta-group clock */ CLK(NULL, "virt_prcm_set", &virt_prcm_set, CK_243X), + CLK(NULL, "cpu_ck", &virt_prcm_set, CK_243X), /* general l4 interface ck, multi-parent functional clk */ CLK(NULL, "gpt1_ick", &gpt1_ick, CK_243X), CLK(NULL, "gpt1_fck", &gpt1_fck, CK_243X), diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c index 403a4a1d3f9..b1c484cd891 100644 --- a/arch/arm/mach-omap2/clock3xxx_data.c +++ b/arch/arm/mach-omap2/clock3xxx_data.c @@ -3224,6 +3224,7 @@ static struct omap_clk omap3xxx_clks[] = { CLK(NULL, "mcbsp_clks", &mcbsp_clks, CK_3XXX), CLK(NULL, "sys_clkout1", &sys_clkout1, CK_3XXX), CLK(NULL, "dpll1_ck", &dpll1_ck, CK_3XXX), + CLK(NULL, "cpu_ck", &dpll1_ck, CK_3XXX), CLK(NULL, "dpll1_x2_ck", &dpll1_x2_ck, CK_3XXX), CLK(NULL, "dpll1_x2m2_ck", &dpll1_x2m2_ck, CK_3XXX), CLK(NULL, "dpll2_ck", &dpll2_ck, CK_34XX | CK_36XX), @@ -3357,13 +3358,13 @@ static struct omap_clk omap3xxx_clks[] = { CLK("omap_rng", "ick", &rng_ick, CK_34XX | CK_36XX), CLK(NULL, "sha11_ick", &sha11_ick, CK_34XX | CK_36XX), CLK(NULL, "des1_ick", &des1_ick, CK_34XX | CK_36XX), - CLK("omapdss", "dss1_fck", &dss1_alwon_fck_3430es1, CK_3430ES1), - CLK("omapdss", "dss1_fck", &dss1_alwon_fck_3430es2, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), - CLK("omapdss", "tv_fck", &dss_tv_fck, CK_3XXX), - CLK("omapdss", "video_fck", &dss_96m_fck, CK_3XXX), - CLK("omapdss", "dss2_fck", &dss2_alwon_fck, CK_3XXX), - CLK("omapdss", "ick", &dss_ick_3430es1, CK_3430ES1), - CLK("omapdss", "ick", &dss_ick_3430es2, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), + CLK("omap_dss", "fck", &dss1_alwon_fck_3430es1, CK_3430ES1), + CLK("omap_dss", "fck", &dss1_alwon_fck_3430es2, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), + CLK("omap_dss", "tv_clk", &dss_tv_fck, CK_3XXX), + CLK("omap_dss", "video_clk", &dss_96m_fck, CK_3XXX), + CLK("omap_dss", "sys_clk", &dss2_alwon_fck, CK_3XXX), + CLK("omap_dss", "ick", &dss_ick_3430es1, CK_3430ES1), + CLK("omap_dss", "ick", &dss_ick_3430es2, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), CLK(NULL, "cam_mclk", &cam_mclk, CK_34XX | CK_36XX), CLK(NULL, "cam_ick", &cam_ick, CK_34XX | CK_36XX), CLK(NULL, "csi2_96m_fck", &csi2_96m_fck, CK_34XX | CK_36XX), diff --git a/arch/arm/mach-omap2/clock44xx_data.c b/arch/arm/mach-omap2/clock44xx_data.c index de9ec8ddd2a..95f2c4c9503 100644 --- a/arch/arm/mach-omap2/clock44xx_data.c +++ b/arch/arm/mach-omap2/clock44xx_data.c @@ -3057,6 +3057,7 @@ static struct omap_clk omap44xx_clks[] = { CLK(NULL, "dpll_iva_m4x2_ck", &dpll_iva_m4x2_ck, CK_443X), CLK(NULL, "dpll_iva_m5x2_ck", &dpll_iva_m5x2_ck, CK_443X), CLK(NULL, "dpll_mpu_ck", &dpll_mpu_ck, CK_443X), + CLK(NULL, "cpu_ck", &dpll_mpu_ck, CK_443X), CLK(NULL, "dpll_mpu_m2_ck", &dpll_mpu_m2_ck, CK_443X), CLK(NULL, "per_hs_clk_div_ck", &per_hs_clk_div_ck, CK_443X), CLK(NULL, "per_hsd_byp_clk_mux_ck", &per_hsd_byp_clk_mux_ck, CK_443X), @@ -3106,11 +3107,16 @@ static struct omap_clk omap44xx_clks[] = { CLK(NULL, "dmic_sync_mux_ck", &dmic_sync_mux_ck, CK_443X), CLK(NULL, "dmic_fck", &dmic_fck, CK_443X), CLK(NULL, "dsp_fck", &dsp_fck, CK_443X), - CLK(NULL, "dss_sys_clk", &dss_sys_clk, CK_443X), - CLK(NULL, "dss_tv_clk", &dss_tv_clk, CK_443X), - CLK(NULL, "dss_dss_clk", &dss_dss_clk, CK_443X), - CLK(NULL, "dss_48mhz_clk", &dss_48mhz_clk, CK_443X), - CLK(NULL, "dss_fck", &dss_fck, CK_443X), + CLK("omap_dss", "sys_clk", &dss_sys_clk, CK_443X), + CLK("omap_dss", "tv_clk", &dss_tv_clk, CK_443X), + CLK("omap_dss", "dss_clk", &dss_dss_clk, CK_443X), + CLK("omap_dss", "video_clk", &dss_48mhz_clk, CK_443X), + CLK("omap_dss", "fck", &dss_fck, CK_443X), + /* + * On OMAP4, DSS ick is a dummy clock; this is needed for compatibility + * with OMAP2/3. + */ + CLK("omap_dss", "ick", &dummy_ck, CK_443X), CLK(NULL, "efuse_ctrl_cust_fck", &efuse_ctrl_cust_fck, CK_443X), CLK(NULL, "emif1_fck", &emif1_fck, CK_443X), CLK(NULL, "emif2_fck", &emif2_fck, CK_443X), diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c index f7b22a16f38..bc9bcac2ec0 100644 --- a/arch/arm/mach-omap2/cpuidle34xx.c +++ b/arch/arm/mach-omap2/cpuidle34xx.c @@ -51,6 +51,7 @@ struct omap3_processor_cx { u8 valid; + u8 enabled; u8 type; u32 sleep_latency; u32 wakeup_latency; @@ -139,19 +140,9 @@ static int omap3_enter_idle(struct cpuidle_device *dev, if (omap_irq_pending() || need_resched()) goto return_sleep_time; - if (cx->type == OMAP3_STATE_C1) { - pwrdm_for_each_clkdm(mpu_pd, _cpuidle_deny_idle); - pwrdm_for_each_clkdm(core_pd, _cpuidle_deny_idle); - } - /* Execute ARM wfi */ omap_sram_idle(); - if (cx->type == OMAP3_STATE_C1) { - pwrdm_for_each_clkdm(mpu_pd, _cpuidle_allow_idle); - pwrdm_for_each_clkdm(core_pd, _cpuidle_allow_idle); - } - return_sleep_time: getnstimeofday(&ts_postidle); ts_idle = timespec_sub(ts_postidle, ts_preidle); @@ -283,8 +274,18 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev, select_state: dev->last_state = new_state; + + if (new_state == dev->safe_state) { + pwrdm_for_each_clkdm(mpu_pd, _cpuidle_deny_idle); + pwrdm_for_each_clkdm(core_pd, _cpuidle_deny_idle); + } ret = omap3_enter_idle(dev, new_state); + if (new_state == dev->safe_state) { + pwrdm_for_each_clkdm(mpu_pd, _cpuidle_allow_idle); + pwrdm_for_each_clkdm(core_pd, _cpuidle_allow_idle); + } + /* Restore original PER state if it was modified */ if (per_next_state != per_saved_state) pwrdm_set_next_pwrst(per_pd, per_saved_state); @@ -309,12 +310,13 @@ void omap3_cpuidle_update_states(u32 mpu_deepest_state, u32 core_deepest_state) for (i = OMAP3_STATE_C1; i < OMAP3_MAX_STATES; i++) { struct omap3_processor_cx *cx = &omap3_power_states[i]; - - if ((cx->mpu_state >= mpu_deepest_state) && - (cx->core_state >= core_deepest_state)) { - cx->valid = 1; - } else { - cx->valid = 0; + if (cx->enabled) { + if ((cx->mpu_state >= mpu_deepest_state) && + (cx->core_state >= core_deepest_state)) { + cx->valid = 1; + } else { + cx->valid = 0; + } } } } @@ -355,6 +357,8 @@ void omap_init_power_states(void) /* C1 . MPU WFI + Core active */ omap3_power_states[OMAP3_STATE_C1].valid = cpuidle_params_table[OMAP3_STATE_C1].valid; + omap3_power_states[OMAP3_STATE_C1].enabled = + cpuidle_params_table[OMAP3_STATE_C1].valid; omap3_power_states[OMAP3_STATE_C1].type = OMAP3_STATE_C1; omap3_power_states[OMAP3_STATE_C1].sleep_latency = cpuidle_params_table[OMAP3_STATE_C1].sleep_latency; @@ -369,6 +373,8 @@ void omap_init_power_states(void) /* C2 . MPU WFI + Core inactive */ omap3_power_states[OMAP3_STATE_C2].valid = cpuidle_params_table[OMAP3_STATE_C2].valid; + omap3_power_states[OMAP3_STATE_C2].enabled = + cpuidle_params_table[OMAP3_STATE_C2].valid; omap3_power_states[OMAP3_STATE_C2].type = OMAP3_STATE_C2; omap3_power_states[OMAP3_STATE_C2].sleep_latency = cpuidle_params_table[OMAP3_STATE_C2].sleep_latency; @@ -384,6 +390,8 @@ void omap_init_power_states(void) /* C3 . MPU CSWR + Core inactive */ omap3_power_states[OMAP3_STATE_C3].valid = cpuidle_params_table[OMAP3_STATE_C3].valid; + omap3_power_states[OMAP3_STATE_C3].enabled = + cpuidle_params_table[OMAP3_STATE_C3].valid; omap3_power_states[OMAP3_STATE_C3].type = OMAP3_STATE_C3; omap3_power_states[OMAP3_STATE_C3].sleep_latency = cpuidle_params_table[OMAP3_STATE_C3].sleep_latency; @@ -399,6 +407,8 @@ void omap_init_power_states(void) /* C4 . MPU OFF + Core inactive */ omap3_power_states[OMAP3_STATE_C4].valid = cpuidle_params_table[OMAP3_STATE_C4].valid; + omap3_power_states[OMAP3_STATE_C4].enabled = + cpuidle_params_table[OMAP3_STATE_C4].valid; omap3_power_states[OMAP3_STATE_C4].type = OMAP3_STATE_C4; omap3_power_states[OMAP3_STATE_C4].sleep_latency = cpuidle_params_table[OMAP3_STATE_C4].sleep_latency; @@ -414,6 +424,8 @@ void omap_init_power_states(void) /* C5 . MPU CSWR + Core CSWR*/ omap3_power_states[OMAP3_STATE_C5].valid = cpuidle_params_table[OMAP3_STATE_C5].valid; + omap3_power_states[OMAP3_STATE_C5].enabled = + cpuidle_params_table[OMAP3_STATE_C5].valid; omap3_power_states[OMAP3_STATE_C5].type = OMAP3_STATE_C5; omap3_power_states[OMAP3_STATE_C5].sleep_latency = cpuidle_params_table[OMAP3_STATE_C5].sleep_latency; @@ -429,6 +441,8 @@ void omap_init_power_states(void) /* C6 . MPU OFF + Core CSWR */ omap3_power_states[OMAP3_STATE_C6].valid = cpuidle_params_table[OMAP3_STATE_C6].valid; + omap3_power_states[OMAP3_STATE_C6].enabled = + cpuidle_params_table[OMAP3_STATE_C6].valid; omap3_power_states[OMAP3_STATE_C6].type = OMAP3_STATE_C6; omap3_power_states[OMAP3_STATE_C6].sleep_latency = cpuidle_params_table[OMAP3_STATE_C6].sleep_latency; @@ -444,6 +458,8 @@ void omap_init_power_states(void) /* C7 . MPU OFF + Core OFF */ omap3_power_states[OMAP3_STATE_C7].valid = cpuidle_params_table[OMAP3_STATE_C7].valid; + omap3_power_states[OMAP3_STATE_C7].enabled = + cpuidle_params_table[OMAP3_STATE_C7].valid; omap3_power_states[OMAP3_STATE_C7].type = OMAP3_STATE_C7; omap3_power_states[OMAP3_STATE_C7].sleep_latency = cpuidle_params_table[OMAP3_STATE_C7].sleep_latency; @@ -463,6 +479,7 @@ void omap_init_power_states(void) */ if (IS_PM34XX_ERRATUM(PM_SDRC_WAKEUP_ERRATUM_i583)) { omap3_power_states[OMAP3_STATE_C7].valid = 0; + omap3_power_states[OMAP3_STATE_C7].enabled = 0; cpuidle_params_table[OMAP3_STATE_C7].valid = 0; WARN_ONCE(1, "%s: core off state C7 disabled due to i583\n", __func__); diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c new file mode 100644 index 00000000000..cc7b4f3070d --- /dev/null +++ b/arch/arm/mach-omap2/display.c @@ -0,0 +1,103 @@ +/* + * OMAP2plus display device setup / initialization. + * + * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ + * Senthilvadivu Guruswamy + * Sumit Semwal + * + * 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. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/io.h> +#include <linux/clk.h> +#include <linux/err.h> + +#include <plat/display.h> +#include <plat/omap_hwmod.h> +#include <plat/omap_device.h> + +static struct platform_device omap_display_device = { + .name = "omap_display", + .id = -1, + .dev = { + .platform_data = NULL, + }, +}; + +static struct omap_device_pm_latency omap_dss_latency[] = { + [0] = { + .deactivate_func = omap_device_idle_hwmods, + .activate_func = omap_device_enable_hwmods, + .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, + }, +}; + +int __init omap_display_init(struct omap_dss_board_info + *board_data) +{ + int r = 0; + struct omap_hwmod *oh; + struct omap_device *od; + int i; + struct omap_display_platform_data pdata; + + /* + * omap: valid DSS hwmod names + * omap2,3,4: dss_core, dss_dispc, dss_rfbi, dss_venc + * omap3,4: dss_dsi1 + * omap4: dss_dsi2, dss_hdmi + */ + char *oh_name[] = {"dss_core", "dss_dispc", "dss_rfbi", "dss_venc", "dss_dsi1", + "dss_dsi2", "dss_hdmi"}; + char *dev_name[] = {"omap_dss", "omap_dispc", "omap_rfbi", "omap_venc", "omap_dsi1", + "omap_dsi2", "omap_hdmi"}; + int oh_count; + + memset(&pdata, 0, sizeof(pdata)); + + if (cpu_is_omap24xx()) + oh_count = ARRAY_SIZE(oh_name) - 3; + /* last 3 hwmod dev in oh_name are not available for omap2 */ + else if (cpu_is_omap44xx()) + oh_count = ARRAY_SIZE(oh_name); + else + oh_count = ARRAY_SIZE(oh_name) - 2; + /* last 2 hwmod dev in oh_name are not available for omap3 */ + + + pdata.board_data = board_data; + pdata.board_data->get_last_off_on_transaction_id = NULL; + + for (i = 0; i < oh_count; i++) { + oh = omap_hwmod_lookup(oh_name[i]); + if (!oh) { + pr_err("Could not look up %s\n", oh_name[i]); + return -ENODEV; + } + od = omap_device_build(dev_name[i], -1, oh, &pdata, + sizeof(struct omap_display_platform_data), + omap_dss_latency, + ARRAY_SIZE(omap_dss_latency), 0); + + if (WARN((IS_ERR(od)), "Could not build omap_device for %s\n", + oh_name[i])) + return -ENODEV; + } + omap_display_device.dev.platform_data = board_data; + + r = platform_device_register(&omap_display_device); + if (r < 0) + printk(KERN_ERR "Unable to register OMAP-Display device\n"); + + return r; +} diff --git a/arch/arm/mach-omap2/dvfs.c b/arch/arm/mach-omap2/dvfs.c new file mode 100644 index 00000000000..fb9215cb927 --- /dev/null +++ b/arch/arm/mach-omap2/dvfs.c @@ -0,0 +1,770 @@ +/* + * OMAP3/OMAP4 DVFS Management Routines + * + * Author: Vishwanath BS <vishwanath.bs@ti.com> + * + * Copyright (C) 2011 Texas Instruments, Inc. + * Vishwanath BS <vishwanath.bs@ti.com> + * + * 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/err.h> +#include <linux/spinlock.h> +#include <linux/plist.h> +#include <linux/slab.h> +#include <linux/opp.h> +#include <plat/common.h> +#include <plat/voltage.h> +#include <plat/omap_device.h> +#include <plat/smartreflex.h> + +/** + * struct omap_dev_user_list - Structure maitain userlist per device + * + * @dev: The device requesting for a particular frequency + * @node: The list head entry + * @freq: frequency being requested + * + * Using this structure, user list (requesting dev * and frequency) for + * each device is maintained. This is how we can have different devices + * at different frequencies (to support frequency locking and throttling). + * Even if one of the devices in a given vdd has locked it's frequency, + * other's can still scale their frequency using this list. + * If no one has placed a frequency request for a device, then device is + * set to the frequency from it's opp table. + */ +struct omap_dev_user_list { + struct device *dev; + struct plist_node node; + u32 freq; +}; + +/** + * struct omap_vdd_dev_list - Device list per vdd + * + * @dev: The device belonging to a particular vdd + * @node: The list head entry + */ +struct omap_vdd_dev_list { + struct device *dev; + struct list_head node; + struct plist_head user_list; + spinlock_t user_lock; /* spinlock for plist */ +}; + +/** + * struct omap_vdd_user_list - The per vdd user list + * + * @dev: The device asking for the vdd to be set at a particular + * voltage + * @node: The list head entry + * @volt: The voltage requested by the device <dev> + */ +struct omap_vdd_user_list { + struct device *dev; + struct plist_node node; + u32 volt; +}; + +/** + * struct omap_vdd_dvfs_info - The per vdd dvfs info + * + * @user_lock: spinlock for plist operations + * @user_list: The vdd user list + * @scaling_mutex: Mutex for protecting dvfs data structures for a vdd + * @voltdm: Voltage domains for which dvfs info stored + * + * This is a fundamental structure used to store all the required + * DVFS related information for a vdd. + */ +struct omap_vdd_dvfs_info { + spinlock_t user_lock; /* spin lock */ + struct plist_head user_list; + struct mutex scaling_mutex; /* dvfs mutex */ + struct voltagedomain *voltdm; + struct list_head dev_list; + struct device vdd_device; +}; + +static struct omap_vdd_dvfs_info *omap_dvfs_info_list; +static int omap_nr_vdd; + +static struct voltagedomain omap3_vdd[] = { + { + .name = "mpu", + }, + { + .name = "core", + }, +}; + +static struct voltagedomain omap4_vdd[] = { + { + .name = "mpu", + }, + { + .name = "iva", + }, + { + .name = "core", + }, +}; + +static int omap_dvfs_voltage_scale(struct omap_vdd_dvfs_info *dvfs_info); + +static int __init omap_dvfs_init(void); + +static struct omap_vdd_dvfs_info *get_dvfs_info(struct voltagedomain *voltdm) +{ + int i; + if (!voltdm || !omap_dvfs_info_list) + return NULL; + + for (i = 0; i < omap_nr_vdd; i++) + if (omap_dvfs_info_list[i].voltdm == voltdm) + return &omap_dvfs_info_list[i]; + + pr_warning("%s: unable find dvfs info for vdd %s\n", + __func__, voltdm->name); + return NULL; +} + +/** + * omap_dvfs_find_voltage() - search for given voltage + * @dev: device pointer associated with the opp type + * @volt: voltage to search for + * + * Searches for exact match in the opp list and returns handle to the matching + * opp if found, else returns ERR_PTR in case of error and should be handled + * using IS_ERR. If there are multiple opps with same voltage, it will return + * the first available entry. + */ +static struct opp *omap_dvfs_find_voltage(struct device *dev, + unsigned long volt) +{ + struct opp *opp = ERR_PTR(-ENODEV); + unsigned long f = 0; + + do { + opp = opp_find_freq_ceil(dev, &f); + if (IS_ERR(opp)) + break; + if (opp_get_voltage(opp) >= volt) + break; + f++; + } while (1); + + return opp; +} + +/** + * omap_dvfs_add_vdd_user() - Add a voltage request + * @dvfs_info: omap_vdd_dvfs_info pointer for the required vdd + * @dev: device making the request + * @volt: requesting voltage in uV + * + * Adds the given devices' voltage request into corresponding + * vdd's omap_vdd_dvfs_info user list (plist). This list is used + * to find the maximum voltage request for a given vdd. + * + * Returns 0 on success. + */ +static int omap_dvfs_add_vdd_user(struct omap_vdd_dvfs_info *dvfs_info, + struct device *dev, unsigned long volt) +{ + struct omap_vdd_user_list *user = NULL, *temp_user; + struct plist_node *node; + + if (!dvfs_info || IS_ERR(dvfs_info)) { + dev_warn(dev, "%s: VDD specified does not exist!\n", __func__); + return -EINVAL; + } + + mutex_lock(&dvfs_info->scaling_mutex); + + plist_for_each_entry(temp_user, &dvfs_info->user_list, node) { + if (temp_user->dev == dev) { + user = temp_user; + break; + } + } + + if (!user) { + user = kzalloc(sizeof(struct omap_vdd_user_list), GFP_KERNEL); + if (!user) { + dev_err(dev, "%s: Unable to creat a new user for vdd_%s\n", + __func__, dvfs_info->voltdm->name); + mutex_unlock(&dvfs_info->scaling_mutex); + return -ENOMEM; + } + user->dev = dev; + } else { + plist_del(&user->node, &dvfs_info->user_list); + } + + plist_node_init(&user->node, volt); + plist_add(&user->node, &dvfs_info->user_list); + node = plist_last(&dvfs_info->user_list); + user->volt = node->prio; + + mutex_unlock(&dvfs_info->scaling_mutex); + + return 0; +} + +/** + * omap_dvfs_remove_vdd_user() - Remove a voltage request + * @dvfs_info: omap_vdd_dvfs_info pointer for the required vdd + * @dev: device making the request + * + * Removes the given devices' voltage request from corresponding + * vdd's omap_vdd_dvfs_info user list (plist). + * + * Returns 0 on success. + */ +static int omap_dvfs_remove_vdd_user(struct omap_vdd_dvfs_info *dvfs_info, + struct device *dev) +{ + struct omap_vdd_user_list *user = NULL, *temp_user; + int ret = 0; + + if (!dvfs_info || IS_ERR(dvfs_info)) { + dev_err(dev, "%s: VDD specified does not exist!\n", __func__); + return -EINVAL; + } + + mutex_lock(&dvfs_info->scaling_mutex); + + plist_for_each_entry(temp_user, &dvfs_info->user_list, node) { + if (temp_user->dev == dev) { + user = temp_user; + break; + } + } + + if (user) + plist_del(&user->node, &dvfs_info->user_list); + else { + dev_err(dev, "%s: Unable to find the user for vdd_%s\n", + __func__, dvfs_info->voltdm->name); + ret = -ENOMEM; + } + mutex_unlock(&dvfs_info->scaling_mutex); + + return ret; +} + +/** + * omap_dvfs_register_device - Add a device into voltage domain + * @voltdm: voltage domain to which the device is to be added + * @dev: Device to be added + * + * This API will add a given device into user_list of corresponding + * vdd's omap_vdd_dvfs_info strucure. This list is traversed to scale + * frequencies of all the devices on a given vdd. This api is called + * while hwmod db is built for an omap_device. + * + * Returns 0 on success. + */ +int omap_dvfs_register_device(struct voltagedomain *voltdm, struct device *dev) +{ + struct omap_vdd_dev_list *temp_dev; + struct omap_vdd_dvfs_info *dvfs_info = get_dvfs_info(voltdm); + + if (!voltdm || IS_ERR(voltdm) || !dvfs_info) { + dev_warn(dev, "%s: VDD specified does not exist!\n", __func__); + return -EINVAL; + } + + list_for_each_entry(temp_dev, &dvfs_info->dev_list, node) { + if (temp_dev->dev == dev) { + dev_warn(dev, "%s: Device already added to vdee_%s\n", + __func__, dvfs_info->voltdm->name); + return -EINVAL; + } + } + + temp_dev = kzalloc(sizeof(struct omap_vdd_dev_list), GFP_KERNEL); + if (!temp_dev) { + dev_err(dev, "%s: Unable to creat a new device for vdd_%s\n", + __func__, dvfs_info->voltdm->name); + return -ENOMEM; + } + + /* Initialize priority ordered list */ + spin_lock_init(&temp_dev->user_lock); + plist_head_init(&temp_dev->user_list, &temp_dev->user_lock); + + temp_dev->dev = dev; + list_add(&temp_dev->node, &dvfs_info->dev_list); + + return 0; +} + +/** + * omap_dvfs_add_freq_request() - add a requested device frequency + * + * + * @dvfs_info: omap_vdd_dvfs_info pointer for the required vdd + * @req_dev: device making the request + * @target_dev: target device for which frequency request is being made + * @freq: target device frequency + * + * This API adds a requested frequency into target's device frequency list. + * + * Returns 0 on success. + */ +static int omap_dvfs_add_freq_request(struct omap_vdd_dvfs_info *dvfs_info, + struct device *req_dev, struct device *target_dev, unsigned long freq) +{ + struct omap_dev_user_list *dev_user = NULL, *tmp_user; + struct omap_vdd_dev_list *temp_dev; + + if (!dvfs_info || IS_ERR(dvfs_info)) { + dev_warn(target_dev, "%s: VDD specified does not exist!\n", + __func__); + return -EINVAL; + } + + mutex_lock(&dvfs_info->scaling_mutex); + + list_for_each_entry(temp_dev, &dvfs_info->dev_list, node) { + if (temp_dev->dev == target_dev) + break; + } + + if (temp_dev->dev != target_dev) { + dev_warn(target_dev, "%s: target_dev does not exist!\n", + __func__); + mutex_unlock(&dvfs_info->scaling_mutex); + return -EINVAL; + } + + plist_for_each_entry(tmp_user, &temp_dev->user_list, node) { + if (tmp_user->dev == req_dev) { + dev_user = tmp_user; + break; + } + } + + if (!dev_user) { + dev_user = kzalloc(sizeof(struct omap_dev_user_list), + GFP_KERNEL); + if (!dev_user) { + dev_err(target_dev, "%s: Unable to creat a new user for vdd_%s\n", + __func__, dvfs_info->voltdm->name); + mutex_unlock(&dvfs_info->scaling_mutex); + return -ENOMEM; + } + dev_user->dev = req_dev; + } else { + plist_del(&dev_user->node, &temp_dev->user_list); + } + + plist_node_init(&dev_user->node, freq); + plist_add(&dev_user->node, &temp_dev->user_list); + + mutex_unlock(&dvfs_info->scaling_mutex); + return 0; +} + +/** + * omap_dvfs_remove_freq_request() - Remove the requested device frequency + * + * @dvfs_info: omap_vdd_dvfs_info pointer for the required vdd + * @req_dev: device removing the request + * @target_dev: target device from which frequency request is being removed + * + * This API removes a requested frequency from target's device frequency list. + * + * Returns 0 on success. + */ + +static int omap_dvfs_remove_freq_request(struct omap_vdd_dvfs_info *dvfs_info, + struct device *req_dev, struct device *target_dev) +{ + struct omap_dev_user_list *dev_user = NULL, *tmp_user; + int ret = 0; + struct omap_vdd_dev_list *temp_dev; + + if (!dvfs_info || IS_ERR(dvfs_info)) { + dev_warn(target_dev, "%s: VDD specified does not exist!\n", + __func__); + return -EINVAL; + } + + mutex_lock(&dvfs_info->scaling_mutex); + + list_for_each_entry(temp_dev, &dvfs_info->dev_list, node) { + if (temp_dev->dev == target_dev) + break; + } + + if (temp_dev->dev != target_dev) { + dev_warn(target_dev, "%s: target_dev does not exist!\n", + __func__); + mutex_unlock(&dvfs_info->scaling_mutex); + return -EINVAL; + } + + plist_for_each_entry(tmp_user, &temp_dev->user_list, node) { + if (tmp_user->dev == req_dev) { + dev_user = tmp_user; + break; + } + } + + if (dev_user) + plist_del(&dev_user->node, &temp_dev->user_list); + else { + dev_err(target_dev, "%s: Unable to remove the user for vdd_%s\n", + __func__, dvfs_info->voltdm->name); + ret = -EINVAL; + } + + return ret; +} + +/* Calculate dependency vdd voltage for given vdd voltage */ +static int calc_dep_vdd_volt(struct device *dev, + struct omap_vdd_info *main_vdd, unsigned long main_volt) +{ + struct omap_vdd_dep_info *dep_vdds; + int i, ret = 0; + + if (!main_vdd->dep_vdd_info) { + pr_debug("%s: No dependent VDD's for vdd_%s\n", + __func__, main_vdd->voltdm.name); + return 0; + } + + dep_vdds = main_vdd->dep_vdd_info; + + for (i = 0; i < main_vdd->nr_dep_vdd; i++) { + struct omap_vdd_dep_volt *volt_table = dep_vdds[i].dep_table; + int nr_volt = 0; + unsigned long dep_volt = 0, act_volt = 0; + + while (volt_table[nr_volt].main_vdd_volt != 0) { + if (volt_table[nr_volt].main_vdd_volt == main_volt) { + dep_volt = volt_table[nr_volt].dep_vdd_volt; + break; + } + nr_volt++; + } + if (!dep_volt) { + pr_warning("%s: Not able to find a matching volt for" + "vdd_%s corresponding to vdd_%s %ld volt\n", + __func__, dep_vdds[i].name, + main_vdd->voltdm.name, main_volt); + ret = -EINVAL; + continue; + } + + if (!dep_vdds[i].voltdm) + dep_vdds[i].voltdm = + omap_voltage_domain_lookup(dep_vdds[i].name); + + act_volt = dep_volt; + + /* See if dep_volt is possible for the vdd*/ + ret = omap_dvfs_add_vdd_user(get_dvfs_info(dep_vdds[i].voltdm), + dev, act_volt); + } + + return ret; +} + +/* Scale dependent VDD */ +static int scale_dep_vdd(struct omap_vdd_dvfs_info *vdd_info) +{ + struct omap_vdd_dep_info *dep_vdds; + int i; + struct omap_vdd_info *main_vdd; + struct voltagedomain *voltdm = vdd_info->voltdm; + main_vdd = container_of(voltdm, struct omap_vdd_info, voltdm); + + if (!main_vdd->dep_vdd_info) { + pr_debug("%s: No dependent VDD's for vdd_%s\n", + __func__, main_vdd->voltdm.name); + return 0; + } + + dep_vdds = main_vdd->dep_vdd_info; + + for (i = 0; i < main_vdd->nr_dep_vdd; i++) + omap_dvfs_voltage_scale(get_dvfs_info(dep_vdds[i].voltdm)); + + return 0; +} + +/** + * omap_dvfs_voltage_scale() : API to scale the devices associated with a + * voltage domain vdd voltage. + * + * @dvfs_info: omap_vdd_dvfs_info pointer for the required vdd + * + * This API runs through the list of devices associated with the + * voltage domain and scales the device rates to the one requested + * by the user or those corresponding to the new voltage of the + * voltage domain. Target voltage is the highest voltage in the vdd_user_list. + * + * Returns 0 on success + * else the error value. + */ +static int omap_dvfs_voltage_scale(struct omap_vdd_dvfs_info *dvfs_info) +{ + unsigned long curr_volt; + int is_volt_scaled = 0; + struct omap_vdd_dev_list *temp_dev; + struct plist_node *node; + int ret = 0; + struct voltagedomain *voltdm; + unsigned long volt; + struct omap_vdd_info *vdd; + + if (!dvfs_info || IS_ERR(dvfs_info)) { + pr_warning("%s: VDD specified does not exist!\n", __func__); + return -EINVAL; + } + + voltdm = dvfs_info->voltdm; + vdd = container_of(voltdm, struct omap_vdd_info, voltdm); + + mutex_lock(&dvfs_info->scaling_mutex); + + /* Find the highest voltage being requested */ + node = plist_last(&dvfs_info->user_list); + volt = node->prio; + + curr_volt = omap_voltage_get_nom_volt(voltdm); + + /* Disable smartreflex module across voltage and frequency scaling */ + omap_sr_disable(voltdm); + + if (curr_volt == volt) { + is_volt_scaled = 1; + } else if (curr_volt < volt) { + ret = omap_voltage_scale_vdd(voltdm, volt); + if (ret) { + pr_warning("%s: Unable to scale the %s to %ld volt\n", + __func__, voltdm->name, volt); + omap_sr_enable(voltdm); + mutex_unlock(&dvfs_info->scaling_mutex); + return ret; + } + is_volt_scaled = 1; + } + + list_for_each_entry(temp_dev, &dvfs_info->dev_list, node) { + struct device *dev; + struct opp *opp; + unsigned long freq; + + dev = temp_dev->dev; + if (!plist_head_empty(&temp_dev->user_list)) { + node = plist_last(&temp_dev->user_list); + freq = node->prio; + } else { + opp = omap_dvfs_find_voltage(dev, volt); + if (IS_ERR(opp)) + continue; + freq = opp_get_freq(opp); + } + + if (freq == omap_device_get_rate(dev)) { + dev_dbg(dev, "%s: Already at the requested" + "rate %ld\n", __func__, freq); + continue; + } + + ret |= omap_device_set_rate(dev, freq); + } + + if (!is_volt_scaled && !ret) + omap_voltage_scale_vdd(voltdm, volt); + + /* Enable Smartreflex module */ + omap_sr_enable(voltdm); + + mutex_unlock(&dvfs_info->scaling_mutex); + + /* calculate the voltages for dependent vdd's */ + if (calc_dep_vdd_volt(&dvfs_info->vdd_device, vdd, volt)) { + pr_warning("%s: Error in calculating dependent vdd voltages" + "for vdd_%s\n", __func__, voltdm->name); + return -EINVAL; + } + + /* Scale dependent vdds */ + scale_dep_vdd(dvfs_info); + + return 0; +} + +/** + * omap_device_scale() - Set a new rate at which the device is to operate + * @req_dev: pointer to the device requesting the scaling. + * @target_dev: pointer to the device that is to be scaled + * @rate: the rnew rate for the device. + * + * This API gets the device opp table associated with this device and + * tries putting the device to the requested rate and the voltage domain + * associated with the device to the voltage corresponding to the + * requested rate. Since multiple devices can be assocciated with a + * voltage domain this API finds out the possible voltage the + * voltage domain can enter and then decides on the final device + * rate. Return 0 on success else the error value + */ +int omap_device_scale(struct device *req_dev, struct device *target_dev, + unsigned long rate) +{ + struct opp *opp; + unsigned long volt, freq, min_freq, max_freq; + struct omap_vdd_dvfs_info *dvfs_info; + struct platform_device *pdev; + struct omap_device *od; + int ret = 0; + + pdev = container_of(target_dev, struct platform_device, dev); + od = container_of(pdev, struct omap_device, pdev); + + /* + * Figure out if the desired frquency lies between the + * maximum and minimum possible for the particular device + */ + min_freq = 0; + if (IS_ERR(opp_find_freq_ceil(target_dev, &min_freq))) { + dev_err(target_dev, "%s: Unable to find lowest opp\n", + __func__); + return -ENODEV; + } + + max_freq = ULONG_MAX; + if (IS_ERR(opp_find_freq_floor(target_dev, &max_freq))) { + dev_err(target_dev, "%s: Unable to find highest opp\n", + __func__); + return -ENODEV; + } + + if (rate < min_freq) + freq = min_freq; + else if (rate > max_freq) + freq = max_freq; + else + freq = rate; + + opp = opp_find_freq_ceil(target_dev, &freq); + if (IS_ERR(opp)) { + dev_err(target_dev, "%s: Unable to find OPP for freq%ld\n", + __func__, rate); + return -ENODEV; + } + + /* Get the voltage corresponding to the requested frequency */ + volt = opp_get_voltage(opp); + + /* + * Call into the voltage layer to get the final voltage possible + * for the voltage domain associated with the device. + */ + + if (rate) { + dvfs_info = get_dvfs_info(od->hwmods[0]->voltdm); + + ret = omap_dvfs_add_freq_request(dvfs_info, req_dev, + target_dev, freq); + if (ret) { + dev_err(target_dev, "%s: Unable to add frequency request\n", + __func__); + return ret; + } + + ret = omap_dvfs_add_vdd_user(dvfs_info, req_dev, volt); + if (ret) { + dev_err(target_dev, "%s: Unable to add voltage request\n", + __func__); + omap_dvfs_remove_freq_request(dvfs_info, req_dev, + target_dev); + return ret; + } + } else { + dvfs_info = get_dvfs_info(od->hwmods[0]->voltdm); + + ret = omap_dvfs_remove_freq_request(dvfs_info, req_dev, + target_dev); + if (ret) { + dev_err(target_dev, "%s: Unable to remove frequency request\n", + __func__); + return ret; + } + + ret = omap_dvfs_remove_vdd_user(dvfs_info, req_dev); + if (ret) { + dev_err(target_dev, "%s: Unable to remove voltage request\n", + __func__); + return ret; + } + } + + /* Do the actual scaling */ + ret = omap_dvfs_voltage_scale(dvfs_info); + if (!ret) + if (omap_device_get_rate(target_dev) >= rate) + return 0; + + return ret; +} +EXPORT_SYMBOL(omap_device_scale); + +/** + * omap_dvfs_init() - Initialize omap dvfs layer + * + * Initalizes omap dvfs layer. It basically allocates memory for + * omap_dvfs_info_list and populates voltdm pointer inside + * omap_vdd_dvfs_info structure for all the VDDs. + * + * Returns 0 on success. + */ +static int __init omap_dvfs_init() +{ + int i; + struct voltagedomain *vdd_list; + if (cpu_is_omap34xx()) { + omap_nr_vdd = 2; + vdd_list = omap3_vdd; + } else if (cpu_is_omap44xx()) { + omap_nr_vdd = 3; + vdd_list = omap4_vdd; + } else { + pr_warning("DVFS not supported\n"); + return -EINVAL; + } + + omap_dvfs_info_list = kzalloc(omap_nr_vdd * + sizeof(struct omap_vdd_dvfs_info), GFP_KERNEL); + if (!omap_dvfs_info_list) { + pr_warning("%s: Unable to allocate memory for vdd_list", + __func__); + return -ENOMEM; + } + + for (i = 0; i < omap_nr_vdd; i++) { + omap_dvfs_info_list[i].voltdm = + omap_voltage_domain_lookup(vdd_list[i].name); + /* Init the plist */ + spin_lock_init(&omap_dvfs_info_list[i].user_lock); + plist_head_init(&omap_dvfs_info_list[i].user_list, + &omap_dvfs_info_list[i].user_lock); + /* Init the DVFS mutex */ + mutex_init(&omap_dvfs_info_list[i].scaling_mutex); + /* Init the device list */ + INIT_LIST_HEAD(&omap_dvfs_info_list[i].dev_list); + } + + return 0; +} +core_initcall(omap_dvfs_init); diff --git a/arch/arm/mach-omap2/include/mach/debug-macro.S b/arch/arm/mach-omap2/include/mach/debug-macro.S index 6a4d4136002..6049f465ec8 100644 --- a/arch/arm/mach-omap2/include/mach/debug-macro.S +++ b/arch/arm/mach-omap2/include/mach/debug-macro.S @@ -19,6 +19,9 @@ #define UART_OFFSET(addr) ((addr) & 0x00ffffff) +#define omap_uart_v2p(x) ((x) - PAGE_OFFSET + PLAT_PHYS_OFFSET) +#define omap_uart_p2v(x) ((x) - PLAT_PHYS_OFFSET + PAGE_OFFSET) + .pushsection .data omap_uart_phys: .word 0 omap_uart_virt: .word 0 @@ -36,7 +39,7 @@ omap_uart_lsr: .word 0 /* Use omap_uart_phys/virt if already configured */ 10: mrc p15, 0, \rp, c1, c0 tst \rp, #1 @ MMU enabled? - ldreq \rp, =__virt_to_phys(omap_uart_phys) @ MMU not enabled + ldreq \rp, =omap_uart_v2p(omap_uart_phys) @ MMU disabled ldrne \rp, =omap_uart_phys @ MMU enabled add \rv, \rp, #4 @ omap_uart_virt ldr \rp, [\rp, #0] @@ -49,7 +52,7 @@ omap_uart_lsr: .word 0 mrc p15, 0, \rp, c1, c0 tst \rp, #1 @ MMU enabled? ldreq \rp, =OMAP_UART_INFO @ MMU not enabled - ldrne \rp, =__phys_to_virt(OMAP_UART_INFO) @ MMU enabled + ldrne \rp, =omap_uart_p2v(OMAP_UART_INFO) @ MMU enabled ldr \rp, [\rp, #0] /* Select the UART to use based on the UART1 scratchpad value */ @@ -94,7 +97,7 @@ omap_uart_lsr: .word 0 95: ldr \rp, =ZOOM_UART_BASE mrc p15, 0, \rv, c1, c0 tst \rv, #1 @ MMU enabled? - ldreq \rv, =__virt_to_phys(omap_uart_phys) @ MMU not enabled + ldreq \rv, =omap_uart_v2p(omap_uart_phys) @ MMU disabled ldrne \rv, =omap_uart_phys @ MMU enabled str \rp, [\rv, #0] ldr \rp, =ZOOM_UART_VIRT @@ -109,7 +112,7 @@ omap_uart_lsr: .word 0 98: add \rp, \rp, #0x48000000 @ phys base mrc p15, 0, \rv, c1, c0 tst \rv, #1 @ MMU enabled? - ldreq \rv, =__virt_to_phys(omap_uart_phys) @ MMU not enabled + ldreq \rv, =omap_uart_v2p(omap_uart_phys) @ MMU disabled ldrne \rv, =omap_uart_phys @ MMU enabled str \rp, [\rv, #0] sub \rp, \rp, #0x48000000 @ phys base @@ -131,7 +134,7 @@ omap_uart_lsr: .word 0 .macro busyuart,rd,rx 1001: mrc p15, 0, \rd, c1, c0 tst \rd, #1 @ MMU enabled? - ldreq \rd, =__virt_to_phys(omap_uart_lsr) @ MMU not enabled + ldreq \rd, =omap_uart_v2p(omap_uart_lsr) @ MMU disabled ldrne \rd, =omap_uart_lsr @ MMU enabled ldr \rd, [\rd, #0] ldrb \rd, [\rx, \rd] diff --git a/arch/arm/mach-omap2/include/mach/omap4-common.h b/arch/arm/mach-omap2/include/mach/omap4-common.h index 5b0270b2893..de441c05a6a 100644 --- a/arch/arm/mach-omap2/include/mach/omap4-common.h +++ b/arch/arm/mach-omap2/include/mach/omap4-common.h @@ -17,8 +17,12 @@ * wfi used in low power code. Directly opcode is used instead * of instruction to avoid mulit-omap build break */ +#ifdef CONFIG_THUMB2_KERNEL +#define do_wfi() __asm__ __volatile__ ("wfi" : : : "memory") +#else #define do_wfi() \ __asm__ __volatile__ (".word 0xe320f003" : : : "memory") +#endif #ifdef CONFIG_CACHE_L2X0 extern void __iomem *l2cache_base; diff --git a/arch/arm/mach-omap2/omap-headsmp.S b/arch/arm/mach-omap2/omap-headsmp.S index 6ae937a06cc..4ee6aeca885 100644 --- a/arch/arm/mach-omap2/omap-headsmp.S +++ b/arch/arm/mach-omap2/omap-headsmp.S @@ -45,5 +45,5 @@ hold: ldr r12,=0x103 * should now contain the SVC stack for this core */ b secondary_startup -END(omap_secondary_startup) +ENDPROC(omap_secondary_startup) diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c new file mode 100644 index 00000000000..e982e13f2af --- /dev/null +++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c @@ -0,0 +1,250 @@ +/* + * OMAP2PLUS cpufreq driver + * + * CPU frequency scaling for OMAP + * + * Copyright (C) 2005 Nokia Corporation + * Written by Tony Lindgren <tony@atomide.com> + * + * Based on cpu-sa1110.c, Copyright (C) 2001 Russell King + * + * Copyright (C) 2007-2008 Texas Instruments, Inc. + * Updated to support OMAP3 + * Rajendra Nayak <rnayak@ti.com> + * + * 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/types.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/cpufreq.h> +#include <linux/delay.h> +#include <linux/init.h> +#include <linux/err.h> +#include <linux/clk.h> +#include <linux/io.h> +#include <linux/opp.h> +#include <linux/cpu.h> + +#include <asm/system.h> +#include <asm/smp_plat.h> +#include <asm/cpu.h> + +#include <plat/clock.h> +#include <plat/omap-pm.h> +#include <plat/common.h> + +#include <mach/hardware.h> +#include <plat/dvfs.h> + +#define VERY_HI_RATE 900000000 + +static struct cpufreq_frequency_table *freq_table; +static struct clk *mpu_clk; + +static int omap_verify_speed(struct cpufreq_policy *policy) +{ + if (freq_table) + return cpufreq_frequency_table_verify(policy, freq_table); + + if (policy->cpu) + return -EINVAL; + + cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, + policy->cpuinfo.max_freq); + + policy->min = clk_round_rate(mpu_clk, policy->min * 1000) / 1000; + policy->max = clk_round_rate(mpu_clk, policy->max * 1000) / 1000; + cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, + policy->cpuinfo.max_freq); + return 0; +} + +static unsigned int omap_getspeed(unsigned int cpu) +{ + unsigned long rate; + + if (cpu >= NR_CPUS) + return 0; + + rate = clk_get_rate(mpu_clk) / 1000; + return rate; +} + +static int omap_target(struct cpufreq_policy *policy, + unsigned int target_freq, + unsigned int relation) +{ + int i, ret = 0; + struct cpufreq_freqs freqs; + struct device *mpu_dev = omap2_get_mpuss_device(); + + /* Wait untill all CPU's are initialized */ + if (is_smp() && (num_online_cpus() < NR_CPUS)) + return ret; + + /* Ensure desired rate is within allowed range. Some govenors + * (ondemand) will just pass target_freq=0 to get the minimum. */ + if (target_freq < policy->min) + target_freq = policy->min; + if (target_freq > policy->max) + target_freq = policy->max; + + freqs.old = omap_getspeed(policy->cpu); + freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000; + freqs.cpu = policy->cpu; + + if (freqs.old == freqs.new) + return ret; + + if (!is_smp()) { + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); + goto set_freq; + } + + /* notifiers */ + for_each_cpu(i, policy->cpus) { + freqs.cpu = i; + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); + } + +set_freq: +#ifdef CONFIG_CPU_FREQ_DEBUG + pr_info("cpufreq-omap: transition: %u --> %u\n", freqs.old, freqs.new); +#endif + + ret = omap_device_scale(mpu_dev, mpu_dev, freqs.new * 1000); + if (ret) + return ret; + freqs.new = omap_getspeed(policy->cpu); + + /* + * Generic CPUFREQ driver jiffy update is under !SMP. So jiffies + * won't get updated when UP machine cpufreq build with + * CONFIG_SMP enabled. Below code is added only to manage that + * scenario + */ + if (!is_smp()) { + loops_per_jiffy = + cpufreq_scale(loops_per_jiffy, freqs.old, freqs.new); + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); + goto skip_lpj; + } + +#ifdef CONFIG_SMP + /* + * Note that loops_per_jiffy is not updated on SMP systems in + * cpufreq driver. So, update the per-CPU loops_per_jiffy value + * on frequency transition. We need to update all dependent cpus + */ + for_each_cpu(i, policy->cpus) + per_cpu(cpu_data, i).loops_per_jiffy = + cpufreq_scale(per_cpu(cpu_data, i).loops_per_jiffy, + freqs.old, freqs.new); +#endif + + /* notifiers */ + for_each_cpu(i, policy->cpus) { + freqs.cpu = i; + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); + } + +skip_lpj: + return ret; +} + +static int __init omap_cpu_init(struct cpufreq_policy *policy) +{ + int result = 0; + struct device *mpu_dev; + static cpumask_var_t cpumask; + + mpu_clk = clk_get(NULL, "cpu_ck"); + if (IS_ERR(mpu_clk)) + return PTR_ERR(mpu_clk); + + if (policy->cpu >= NR_CPUS) + return -EINVAL; + + policy->cur = policy->min = policy->max = omap_getspeed(policy->cpu); + + mpu_dev = omap2_get_mpuss_device(); + if (!mpu_dev) { + pr_warning("%s: unable to get the mpu device\n", __func__); + return -EINVAL; + } + opp_init_cpufreq_table(mpu_dev, &freq_table); + + if (freq_table) { + result = cpufreq_frequency_table_cpuinfo(policy, freq_table); + if (!result) + cpufreq_frequency_table_get_attr(freq_table, + policy->cpu); + } else { + policy->cpuinfo.min_freq = clk_round_rate(mpu_clk, 0) / 1000; + policy->cpuinfo.max_freq = clk_round_rate(mpu_clk, + VERY_HI_RATE) / 1000; + } + + policy->min = policy->cpuinfo.min_freq; + policy->max = policy->cpuinfo.max_freq; + policy->cur = omap_getspeed(policy->cpu); + + /* + * On OMAP SMP configuartion, both processors share the voltage + * and clock. So both CPUs needs to be scaled together and hence + * needs software co-ordination. Use cpufreq affected_cpus + * interface to handle this scenario. Additional is_smp() check + * is to keep SMP_ON_UP builf working. + */ + if (is_smp()) { + policy->shared_type = CPUFREQ_SHARED_TYPE_ANY; + cpumask_or(cpumask, cpumask_of(policy->cpu), cpumask); + cpumask_copy(policy->cpus, cpumask); + } + + /* FIXME: what's the actual transition time? */ + policy->cpuinfo.transition_latency = 300 * 1000; + + return 0; +} + +static int omap_cpu_exit(struct cpufreq_policy *policy) +{ + clk_exit_cpufreq_table(&freq_table); + clk_put(mpu_clk); + return 0; +} + +static struct freq_attr *omap_cpufreq_attr[] = { + &cpufreq_freq_attr_scaling_available_freqs, + NULL, +}; + +static struct cpufreq_driver omap_driver = { + .flags = CPUFREQ_STICKY, + .verify = omap_verify_speed, + .target = omap_target, + .get = omap_getspeed, + .init = omap_cpu_init, + .exit = omap_cpu_exit, + .name = "omap2plus", + .attr = omap_cpufreq_attr, +}; + +static int __init omap_cpufreq_init(void) +{ + return cpufreq_register_driver(&omap_driver); +} + +static void __exit omap_cpufreq_exit(void) +{ + cpufreq_unregister_driver(&omap_driver); +} + +MODULE_DESCRIPTION("cpufreq driver for OMAP2PLUS SOCs"); +MODULE_LICENSE("GPL"); +module_init(omap_cpufreq_init); +module_exit(omap_cpufreq_exit); diff --git a/arch/arm/mach-omap2/omap44xx-smc.S b/arch/arm/mach-omap2/omap44xx-smc.S index 1980dc31a1a..e69d37d9520 100644 --- a/arch/arm/mach-omap2/omap44xx-smc.S +++ b/arch/arm/mach-omap2/omap44xx-smc.S @@ -29,7 +29,7 @@ ENTRY(omap_smc1) dsb smc #0 ldmfd sp!, {r2-r12, pc} -END(omap_smc1) +ENDPROC(omap_smc1) ENTRY(omap_modify_auxcoreboot0) stmfd sp!, {r1-r12, lr} @@ -37,7 +37,7 @@ ENTRY(omap_modify_auxcoreboot0) dsb smc #0 ldmfd sp!, {r1-r12, pc} -END(omap_modify_auxcoreboot0) +ENDPROC(omap_modify_auxcoreboot0) ENTRY(omap_auxcoreboot_addr) stmfd sp!, {r2-r12, lr} @@ -45,7 +45,7 @@ ENTRY(omap_auxcoreboot_addr) dsb smc #0 ldmfd sp!, {r2-r12, pc} -END(omap_auxcoreboot_addr) +ENDPROC(omap_auxcoreboot_addr) ENTRY(omap_read_auxcoreboot0) stmfd sp!, {r2-r12, lr} @@ -54,4 +54,4 @@ ENTRY(omap_read_auxcoreboot0) smc #0 mov r0, r0, lsr #9 ldmfd sp!, {r2-r12, pc} -END(omap_read_auxcoreboot0) +ENDPROC(omap_read_auxcoreboot0) diff --git a/arch/arm/mach-omap2/omap_hwmod_2420_data.c b/arch/arm/mach-omap2/omap_hwmod_2420_data.c index b85c630b64d..21014dee5e3 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2420_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2420_data.c @@ -18,7 +18,8 @@ #include <plat/serial.h> #include <plat/i2c.h> #include <plat/gpio.h> - +#include <plat/l3_2xxx.h> +#include <plat/l4_2xxx.h> #include "omap_hwmod_common_data.h" #include "cm-regbits-24xx.h" @@ -38,6 +39,10 @@ static struct omap_hwmod omap2420_mpu_hwmod; static struct omap_hwmod omap2420_iva_hwmod; static struct omap_hwmod omap2420_l3_main_hwmod; static struct omap_hwmod omap2420_l4_core_hwmod; +static struct omap_hwmod omap2420_dss_core_hwmod; +static struct omap_hwmod omap2420_dss_dispc_hwmod; +static struct omap_hwmod omap2420_dss_rfbi_hwmod; +static struct omap_hwmod omap2420_dss_venc_hwmod; static struct omap_hwmod omap2420_wd_timer2_hwmod; static struct omap_hwmod omap2420_gpio1_hwmod; static struct omap_hwmod omap2420_gpio2_hwmod; @@ -64,6 +69,19 @@ static struct omap_hwmod_ocp_if *omap2420_l3_main_slaves[] = { &omap2420_mpu__l3_main, }; +/* DSS -> l3 */ +static struct omap_hwmod_ocp_if omap2420_dss__l3 = { + .master = &omap2420_dss_core_hwmod, + .slave = &omap2420_l3_main_hwmod, + .fw = { + .omap2 = { + .l3_perm_bit = OMAP2_L3_CORE_FW_CONNID_DSS, + .flags = OMAP_FIREWALL_L3, + } + }, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + /* Master interfaces on the L3 interconnect */ static struct omap_hwmod_ocp_if *omap2420_l3_main_masters[] = { &omap2420_l3_main__l4_core, @@ -470,6 +488,291 @@ static struct omap_hwmod omap2420_uart3_hwmod = { .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420), }; +/* + * 'dss' class + * display sub-system + */ + +static struct omap_hwmod_class_sysconfig omap2420_dss_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap2420_dss_hwmod_class = { + .name = "dss", + .sysc = &omap2420_dss_sysc, +}; + +/* dss */ +static struct omap_hwmod_irq_info omap2420_dss_irqs[] = { + { .irq = 25 }, +}; + +static struct omap_hwmod_dma_info omap2420_dss_sdma_chs[] = { + { .name = "dispc", .dma_req = 5 }, +}; + +/* dss */ +/* dss master ports */ +static struct omap_hwmod_ocp_if *omap2420_dss_masters[] = { + &omap2420_dss__l3, +}; + +static struct omap_hwmod_addr_space omap2420_dss_addrs[] = { + { + .pa_start = 0x48050000, + .pa_end = 0x480503FF, + .flags = ADDR_TYPE_RT + }, +}; + +/* l4_core -> dss */ +static struct omap_hwmod_ocp_if omap2420_l4_core__dss = { + .master = &omap2420_l4_core_hwmod, + .slave = &omap2420_dss_core_hwmod, + .clk = "dss_ick", + .addr = omap2420_dss_addrs, + .addr_cnt = ARRAY_SIZE(omap2420_dss_addrs), + .fw = { + .omap2 = { + .l4_fw_region = OMAP2420_L4_CORE_FW_DSS_CORE_REGION, + .flags = OMAP_FIREWALL_L4, + } + }, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* dss slave ports */ +static struct omap_hwmod_ocp_if *omap2420_dss_slaves[] = { + &omap2420_l4_core__dss, +}; + +static struct omap_hwmod_opt_clk dss_opt_clks[] = { + { .role = "tv_clk", .clk = "dss_54m_fck" }, + { .role = "sys_clk", .clk = "dss2_fck" }, +}; + +static struct omap_hwmod omap2420_dss_core_hwmod = { + .name = "dss_core", + .class = &omap2420_dss_hwmod_class, + .main_clk = "dss1_fck", /* instead of dss_fck */ + .mpu_irqs = omap2420_dss_irqs, + .mpu_irqs_cnt = ARRAY_SIZE(omap2420_dss_irqs), + .sdma_reqs = omap2420_dss_sdma_chs, + .sdma_reqs_cnt = ARRAY_SIZE(omap2420_dss_sdma_chs), + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP24XX_EN_DSS1_SHIFT, + .module_offs = CORE_MOD, + .idlest_reg_id = 1, + .idlest_stdby_bit = OMAP24XX_ST_DSS_SHIFT, + }, + }, + .opt_clks = dss_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(dss_opt_clks), + .slaves = omap2420_dss_slaves, + .slaves_cnt = ARRAY_SIZE(omap2420_dss_slaves), + .masters = omap2420_dss_masters, + .masters_cnt = ARRAY_SIZE(omap2420_dss_masters), + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420), + .flags = HWMOD_NO_IDLEST, +}; + +/* + * 'dispc' class + * display controller + */ + +static struct omap_hwmod_class_sysconfig omap2420_dispc_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE | + SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap2420_dispc_hwmod_class = { + .name = "dispc", + .sysc = &omap2420_dispc_sysc, +}; + +static struct omap_hwmod_addr_space omap2420_dss_dispc_addrs[] = { + { + .pa_start = 0x48050400, + .pa_end = 0x480507FF, + .flags = ADDR_TYPE_RT + }, +}; + +/* l4_core -> dss_dispc */ +static struct omap_hwmod_ocp_if omap2420_l4_core__dss_dispc = { + .master = &omap2420_l4_core_hwmod, + .slave = &omap2420_dss_dispc_hwmod, + .clk = "dss_ick", + .addr = omap2420_dss_dispc_addrs, + .addr_cnt = ARRAY_SIZE(omap2420_dss_dispc_addrs), + .fw = { + .omap2 = { + .l4_fw_region = OMAP2420_L4_CORE_FW_DSS_DISPC_REGION, + .flags = OMAP_FIREWALL_L4, + } + }, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* dss_dispc slave ports */ +static struct omap_hwmod_ocp_if *omap2420_dss_dispc_slaves[] = { + &omap2420_l4_core__dss_dispc, +}; + +static struct omap_hwmod omap2420_dss_dispc_hwmod = { + .name = "dss_dispc", + .class = &omap2420_dispc_hwmod_class, + .main_clk = "dss1_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP24XX_EN_DSS1_SHIFT, + .module_offs = CORE_MOD, + .idlest_reg_id = 1, + .idlest_stdby_bit = OMAP24XX_ST_DSS_SHIFT, + }, + }, + .slaves = omap2420_dss_dispc_slaves, + .slaves_cnt = ARRAY_SIZE(omap2420_dss_dispc_slaves), + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420), + .flags = HWMOD_NO_IDLEST, +}; + +/* + * 'rfbi' class + * remote frame buffer interface + */ + +static struct omap_hwmod_class_sysconfig omap2420_rfbi_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | + SYSC_HAS_AUTOIDLE), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap2420_rfbi_hwmod_class = { + .name = "rfbi", + .sysc = &omap2420_rfbi_sysc, +}; + +static struct omap_hwmod_addr_space omap2420_dss_rfbi_addrs[] = { + { + .pa_start = 0x48050800, + .pa_end = 0x48050BFF, + .flags = ADDR_TYPE_RT + }, +}; + +/* l4_core -> dss_rfbi */ +static struct omap_hwmod_ocp_if omap2420_l4_core__dss_rfbi = { + .master = &omap2420_l4_core_hwmod, + .slave = &omap2420_dss_rfbi_hwmod, + .clk = "dss_ick", + .addr = omap2420_dss_rfbi_addrs, + .addr_cnt = ARRAY_SIZE(omap2420_dss_rfbi_addrs), + .fw = { + .omap2 = { + .l4_fw_region = OMAP2420_L4_CORE_FW_DSS_CORE_REGION, + .flags = OMAP_FIREWALL_L4, + } + }, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* dss_rfbi slave ports */ +static struct omap_hwmod_ocp_if *omap2420_dss_rfbi_slaves[] = { + &omap2420_l4_core__dss_rfbi, +}; + +static struct omap_hwmod omap2420_dss_rfbi_hwmod = { + .name = "dss_rfbi", + .class = &omap2420_rfbi_hwmod_class, + .main_clk = "dss1_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP24XX_EN_DSS1_SHIFT, + .module_offs = CORE_MOD, + }, + }, + .slaves = omap2420_dss_rfbi_slaves, + .slaves_cnt = ARRAY_SIZE(omap2420_dss_rfbi_slaves), + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420), + .flags = HWMOD_NO_IDLEST, +}; + +/* + * 'venc' class + * video encoder + */ + +static struct omap_hwmod_class omap2420_venc_hwmod_class = { + .name = "venc", +}; + +/* dss_venc */ +static struct omap_hwmod_addr_space omap2420_dss_venc_addrs[] = { + { + .pa_start = 0x48050C00, + .pa_end = 0x48050FFF, + .flags = ADDR_TYPE_RT + }, +}; + +/* l4_core -> dss_venc */ +static struct omap_hwmod_ocp_if omap2420_l4_core__dss_venc = { + .master = &omap2420_l4_core_hwmod, + .slave = &omap2420_dss_venc_hwmod, + .clk = "dss_54m_fck", + .addr = omap2420_dss_venc_addrs, + .addr_cnt = ARRAY_SIZE(omap2420_dss_venc_addrs), + .fw = { + .omap2 = { + .l4_fw_region = OMAP2420_L4_CORE_FW_DSS_VENC_REGION, + .flags = OMAP_FIREWALL_L4, + } + }, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* dss_venc slave ports */ +static struct omap_hwmod_ocp_if *omap2420_dss_venc_slaves[] = { + &omap2420_l4_core__dss_venc, +}; + +static struct omap_hwmod omap2420_dss_venc_hwmod = { + .name = "dss_venc", + .class = &omap2420_venc_hwmod_class, + .main_clk = "dss1_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP24XX_EN_DSS1_SHIFT, + .module_offs = CORE_MOD, + }, + }, + .slaves = omap2420_dss_venc_slaves, + .slaves_cnt = ARRAY_SIZE(omap2420_dss_venc_slaves), + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420), + .flags = HWMOD_NO_IDLEST, +}; + /* I2C common */ static struct omap_hwmod_class_sysconfig i2c_sysc = { .rev_offs = 0x00, @@ -874,6 +1177,12 @@ static __initdata struct omap_hwmod *omap2420_hwmods[] = { &omap2420_uart1_hwmod, &omap2420_uart2_hwmod, &omap2420_uart3_hwmod, + /* dss class */ + &omap2420_dss_core_hwmod, + &omap2420_dss_dispc_hwmod, + &omap2420_dss_rfbi_hwmod, + &omap2420_dss_venc_hwmod, + /* i2c class */ &omap2420_i2c1_hwmod, &omap2420_i2c2_hwmod, diff --git a/arch/arm/mach-omap2/omap_hwmod_2430_data.c b/arch/arm/mach-omap2/omap_hwmod_2430_data.c index 8ecfbcde13b..1ef3f3fd862 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2430_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2430_data.c @@ -18,6 +18,7 @@ #include <plat/serial.h> #include <plat/i2c.h> #include <plat/gpio.h> +#include <plat/l3_2xxx.h> #include "omap_hwmod_common_data.h" @@ -38,6 +39,10 @@ static struct omap_hwmod omap2430_mpu_hwmod; static struct omap_hwmod omap2430_iva_hwmod; static struct omap_hwmod omap2430_l3_main_hwmod; static struct omap_hwmod omap2430_l4_core_hwmod; +static struct omap_hwmod omap2430_dss_core_hwmod; +static struct omap_hwmod omap2430_dss_dispc_hwmod; +static struct omap_hwmod omap2430_dss_rfbi_hwmod; +static struct omap_hwmod omap2430_dss_venc_hwmod; static struct omap_hwmod omap2430_wd_timer2_hwmod; static struct omap_hwmod omap2430_gpio1_hwmod; static struct omap_hwmod omap2430_gpio2_hwmod; @@ -65,6 +70,19 @@ static struct omap_hwmod_ocp_if *omap2430_l3_main_slaves[] = { &omap2430_mpu__l3_main, }; +/* DSS -> l3 */ +static struct omap_hwmod_ocp_if omap2430_dss__l3 = { + .master = &omap2430_dss_core_hwmod, + .slave = &omap2430_l3_main_hwmod, + .fw = { + .omap2 = { + .l3_perm_bit = OMAP2_L3_CORE_FW_CONNID_DSS, + .flags = OMAP_FIREWALL_L3, + } + }, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + /* Master interfaces on the L3 interconnect */ static struct omap_hwmod_ocp_if *omap2430_l3_main_masters[] = { &omap2430_l3_main__l4_core, @@ -469,6 +487,266 @@ static struct omap_hwmod omap2430_uart3_hwmod = { .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), }; +/* + * 'dss' class + * display sub-system + */ + +static struct omap_hwmod_class_sysconfig omap2430_dss_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap2430_dss_hwmod_class = { + .name = "dss", + .sysc = &omap2430_dss_sysc, +}; + +/* dss */ +static struct omap_hwmod_irq_info omap2430_dss_irqs[] = { + { .irq = 25 }, +}; +static struct omap_hwmod_dma_info omap2430_dss_sdma_chs[] = { + { .name = "dispc", .dma_req = 5 }, +}; + +/* dss */ +/* dss master ports */ +static struct omap_hwmod_ocp_if *omap2430_dss_masters[] = { + &omap2430_dss__l3, +}; + +static struct omap_hwmod_addr_space omap2430_dss_addrs[] = { + { + .pa_start = 0x48050000, + .pa_end = 0x480503FF, + .flags = ADDR_TYPE_RT + }, +}; + +/* l4_core -> dss */ +static struct omap_hwmod_ocp_if omap2430_l4_core__dss = { + .master = &omap2430_l4_core_hwmod, + .slave = &omap2430_dss_core_hwmod, + .clk = "dss_ick", + .addr = omap2430_dss_addrs, + .addr_cnt = ARRAY_SIZE(omap2430_dss_addrs), + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* dss slave ports */ +static struct omap_hwmod_ocp_if *omap2430_dss_slaves[] = { + &omap2430_l4_core__dss, +}; + +static struct omap_hwmod_opt_clk dss_opt_clks[] = { + { .role = "tv_clk", .clk = "dss_54m_fck" }, + { .role = "sys_clk", .clk = "dss2_fck" }, +}; + +static struct omap_hwmod omap2430_dss_core_hwmod = { + .name = "dss_core", + .class = &omap2430_dss_hwmod_class, + .main_clk = "dss1_fck", /* instead of dss_fck */ + .mpu_irqs = omap2430_dss_irqs, + .mpu_irqs_cnt = ARRAY_SIZE(omap2430_dss_irqs), + .sdma_reqs = omap2430_dss_sdma_chs, + .sdma_reqs_cnt = ARRAY_SIZE(omap2430_dss_sdma_chs), + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP24XX_EN_DSS1_SHIFT, + .module_offs = CORE_MOD, + .idlest_reg_id = 1, + .idlest_stdby_bit = OMAP24XX_ST_DSS_SHIFT, + }, + }, + .opt_clks = dss_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(dss_opt_clks), + .slaves = omap2430_dss_slaves, + .slaves_cnt = ARRAY_SIZE(omap2430_dss_slaves), + .masters = omap2430_dss_masters, + .masters_cnt = ARRAY_SIZE(omap2430_dss_masters), + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), + .flags = HWMOD_NO_IDLEST, +}; + +/* + * 'dispc' class + * display controller + */ + +static struct omap_hwmod_class_sysconfig omap2430_dispc_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE | + SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap2430_dispc_hwmod_class = { + .name = "dispc", + .sysc = &omap2430_dispc_sysc, +}; + +static struct omap_hwmod_addr_space omap2430_dss_dispc_addrs[] = { + { + .pa_start = 0x48050400, + .pa_end = 0x480507FF, + .flags = ADDR_TYPE_RT + }, +}; + +/* l4_core -> dss_dispc */ +static struct omap_hwmod_ocp_if omap2430_l4_core__dss_dispc = { + .master = &omap2430_l4_core_hwmod, + .slave = &omap2430_dss_dispc_hwmod, + .clk = "dss_ick", + .addr = omap2430_dss_dispc_addrs, + .addr_cnt = ARRAY_SIZE(omap2430_dss_dispc_addrs), + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* dss_dispc slave ports */ +static struct omap_hwmod_ocp_if *omap2430_dss_dispc_slaves[] = { + &omap2430_l4_core__dss_dispc, +}; + +static struct omap_hwmod omap2430_dss_dispc_hwmod = { + .name = "dss_dispc", + .class = &omap2430_dispc_hwmod_class, + .main_clk = "dss1_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP24XX_EN_DSS1_SHIFT, + .module_offs = CORE_MOD, + .idlest_reg_id = 1, + .idlest_stdby_bit = OMAP24XX_ST_DSS_SHIFT, + }, + }, + .slaves = omap2430_dss_dispc_slaves, + .slaves_cnt = ARRAY_SIZE(omap2430_dss_dispc_slaves), + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), + .flags = HWMOD_NO_IDLEST, +}; + +/* + * 'rfbi' class + * remote frame buffer interface + */ + +static struct omap_hwmod_class_sysconfig omap2430_rfbi_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | + SYSC_HAS_AUTOIDLE), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap2430_rfbi_hwmod_class = { + .name = "rfbi", + .sysc = &omap2430_rfbi_sysc, +}; + +static struct omap_hwmod_addr_space omap2430_dss_rfbi_addrs[] = { + { + .pa_start = 0x48050800, + .pa_end = 0x48050BFF, + .flags = ADDR_TYPE_RT + }, +}; + +/* l4_core -> dss_rfbi */ +static struct omap_hwmod_ocp_if omap2430_l4_core__dss_rfbi = { + .master = &omap2430_l4_core_hwmod, + .slave = &omap2430_dss_rfbi_hwmod, + .clk = "dss_ick", + .addr = omap2430_dss_rfbi_addrs, + .addr_cnt = ARRAY_SIZE(omap2430_dss_rfbi_addrs), + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* dss_rfbi slave ports */ +static struct omap_hwmod_ocp_if *omap2430_dss_rfbi_slaves[] = { + &omap2430_l4_core__dss_rfbi, +}; + +static struct omap_hwmod omap2430_dss_rfbi_hwmod = { + .name = "dss_rfbi", + .class = &omap2430_rfbi_hwmod_class, + .main_clk = "dss1_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP24XX_EN_DSS1_SHIFT, + .module_offs = CORE_MOD, + }, + }, + .slaves = omap2430_dss_rfbi_slaves, + .slaves_cnt = ARRAY_SIZE(omap2430_dss_rfbi_slaves), + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), + .flags = HWMOD_NO_IDLEST, +}; + +/* + * 'venc' class + * video encoder + */ + +static struct omap_hwmod_class omap2430_venc_hwmod_class = { + .name = "venc", +}; + +/* dss_venc */ +static struct omap_hwmod_addr_space omap2430_dss_venc_addrs[] = { + { + .pa_start = 0x48050C00, + .pa_end = 0x48050FFF, + .flags = ADDR_TYPE_RT + }, +}; + +/* l4_core -> dss_venc */ +static struct omap_hwmod_ocp_if omap2430_l4_core__dss_venc = { + .master = &omap2430_l4_core_hwmod, + .slave = &omap2430_dss_venc_hwmod, + .clk = "dss_54m_fck", + .addr = omap2430_dss_venc_addrs, + .addr_cnt = ARRAY_SIZE(omap2430_dss_venc_addrs), + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* dss_venc slave ports */ +static struct omap_hwmod_ocp_if *omap2430_dss_venc_slaves[] = { + &omap2430_l4_core__dss_venc, +}; + +static struct omap_hwmod omap2430_dss_venc_hwmod = { + .name = "dss_venc", + .class = &omap2430_venc_hwmod_class, + .main_clk = "dss1_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP24XX_EN_DSS1_SHIFT, + .module_offs = CORE_MOD, + }, + }, + .slaves = omap2430_dss_venc_slaves, + .slaves_cnt = ARRAY_SIZE(omap2430_dss_venc_slaves), + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), + .flags = HWMOD_NO_IDLEST, +}; + /* I2C common */ static struct omap_hwmod_class_sysconfig i2c_sysc = { .rev_offs = 0x00, @@ -929,6 +1207,12 @@ static __initdata struct omap_hwmod *omap2430_hwmods[] = { &omap2430_uart1_hwmod, &omap2430_uart2_hwmod, &omap2430_uart3_hwmod, + /* dss class */ + &omap2430_dss_core_hwmod, + &omap2430_dss_dispc_hwmod, + &omap2430_dss_rfbi_hwmod, + &omap2430_dss_venc_hwmod, + /* i2c class */ &omap2430_i2c1_hwmod, &omap2430_i2c2_hwmod, diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index 8d8181334f8..5cff284b7a2 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -18,6 +18,7 @@ #include <plat/cpu.h> #include <plat/dma.h> #include <plat/serial.h> +#include <plat/l3_3xxx.h> #include <plat/l4_3xxx.h> #include <plat/i2c.h> #include <plat/gpio.h> @@ -44,6 +45,12 @@ static struct omap_hwmod omap3xxx_l3_main_hwmod; static struct omap_hwmod omap3xxx_l4_core_hwmod; static struct omap_hwmod omap3xxx_l4_per_hwmod; static struct omap_hwmod omap3xxx_wd_timer2_hwmod; +static struct omap_hwmod omap3430es1_dss_core_hwmod; +static struct omap_hwmod omap3xxx_dss_core_hwmod; +static struct omap_hwmod omap3xxx_dss_dispc_hwmod; +static struct omap_hwmod omap3xxx_dss_dsi1_hwmod; +static struct omap_hwmod omap3xxx_dss_rfbi_hwmod; +static struct omap_hwmod omap3xxx_dss_venc_hwmod; static struct omap_hwmod omap3xxx_i2c1_hwmod; static struct omap_hwmod omap3xxx_i2c2_hwmod; static struct omap_hwmod omap3xxx_i2c3_hwmod; @@ -84,6 +91,19 @@ static struct omap_hwmod_ocp_if *omap3xxx_l3_main_slaves[] = { &omap3xxx_mpu__l3_main, }; +/* DSS -> l3 */ +static struct omap_hwmod_ocp_if omap3xxx_dss__l3 = { + .master = &omap3xxx_dss_core_hwmod, + .slave = &omap3xxx_l3_main_hwmod, + .fw = { + .omap2 = { + .l3_perm_bit = OMAP3_L3_CORE_FW_INIT_ID_DSS, + .flags = OMAP_FIREWALL_L3, + } + }, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + /* Master interfaces on the L3 interconnect */ static struct omap_hwmod_ocp_if *omap3xxx_l3_main_masters[] = { &omap3xxx_l3_main__l4_core, @@ -94,6 +114,7 @@ static struct omap_hwmod_ocp_if *omap3xxx_l3_main_masters[] = { static struct omap_hwmod omap3xxx_l3_main_hwmod = { .name = "l3_main", .class = &l3_hwmod_class, + .vdd_name = "core", .masters = omap3xxx_l3_main_masters, .masters_cnt = ARRAY_SIZE(omap3xxx_l3_main_masters), .slaves = omap3xxx_l3_main_slaves, @@ -384,6 +405,7 @@ static struct omap_hwmod omap3xxx_mpu_hwmod = { .name = "mpu", .class = &mpu_hwmod_class, .main_clk = "arm_fck", + .vdd_name = "mpu", .masters = omap3xxx_mpu_masters, .masters_cnt = ARRAY_SIZE(omap3xxx_mpu_masters), .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), @@ -412,6 +434,7 @@ static struct omap_hwmod_ocp_if *omap3xxx_iva_masters[] = { static struct omap_hwmod omap3xxx_iva_hwmod = { .name = "iva", .class = &iva_hwmod_class, + .vdd_name = "mpu", .masters = omap3xxx_iva_masters, .masters_cnt = ARRAY_SIZE(omap3xxx_iva_masters), .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) @@ -664,6 +687,410 @@ static struct omap_hwmod_class i2c_class = { .sysc = &i2c_sysc, }; +/* + * 'dss' class + * display sub-system + */ + +static struct omap_hwmod_class_sysconfig omap3xxx_dss_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap3xxx_dss_hwmod_class = { + .name = "dss", + .sysc = &omap3xxx_dss_sysc, +}; + +/* dss */ +static struct omap_hwmod_irq_info omap3xxx_dss_irqs[] = { + { .irq = 25 }, +}; + +static struct omap_hwmod_dma_info omap3xxx_dss_sdma_chs[] = { + { .name = "dispc", .dma_req = 5 }, + { .name = "dsi1", .dma_req = 74 }, +}; + +/* dss */ +/* dss master ports */ +static struct omap_hwmod_ocp_if *omap3xxx_dss_masters[] = { + &omap3xxx_dss__l3, +}; + +static struct omap_hwmod_addr_space omap3xxx_dss_addrs[] = { + { + .pa_start = 0x48050000, + .pa_end = 0x480503FF, + .flags = ADDR_TYPE_RT + }, +}; + +/* l4_core -> dss */ +static struct omap_hwmod_ocp_if omap3430es1_l4_core__dss = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &omap3430es1_dss_core_hwmod, + .clk = "dss_ick", + .addr = omap3xxx_dss_addrs, + .addr_cnt = ARRAY_SIZE(omap3xxx_dss_addrs), + .fw = { + .omap2 = { + .l4_fw_region = OMAP3ES1_L4_CORE_FW_DSS_CORE_REGION, + .l4_prot_group = OMAP3_L4_CORE_FW_DSS_PROT_GROUP, + .flags = OMAP_FIREWALL_L4, + } + }, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_ocp_if omap3xxx_l4_core__dss = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &omap3xxx_dss_core_hwmod, + .clk = "dss_ick", + .addr = omap3xxx_dss_addrs, + .addr_cnt = ARRAY_SIZE(omap3xxx_dss_addrs), + .fw = { + .omap2 = { + .l4_fw_region = OMAP3_L4_CORE_FW_DSS_CORE_REGION, + .l4_prot_group = OMAP3_L4_CORE_FW_DSS_PROT_GROUP, + .flags = OMAP_FIREWALL_L4, + } + }, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* dss slave ports */ +static struct omap_hwmod_ocp_if *omap3430es1_dss_slaves[] = { + &omap3430es1_l4_core__dss, +}; + +static struct omap_hwmod_ocp_if *omap3xxx_dss_slaves[] = { + &omap3xxx_l4_core__dss, +}; + +static struct omap_hwmod_opt_clk dss_opt_clks[] = { + { .role = "tv_clk", .clk = "dss_tv_fck" }, + { .role = "video_clk", .clk = "dss_96m_fck" }, + { .role = "sys_clk", .clk = "dss2_alwon_fck" }, +}; + +static struct omap_hwmod omap3430es1_dss_core_hwmod = { + .name = "dss_core", + .class = &omap3xxx_dss_hwmod_class, + .main_clk = "dss1_alwon_fck", /* instead of dss_fck */ + .mpu_irqs = omap3xxx_dss_irqs, + .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_dss_irqs), + .sdma_reqs = omap3xxx_dss_sdma_chs, + .sdma_reqs_cnt = ARRAY_SIZE(omap3xxx_dss_sdma_chs), + + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_DSS1_SHIFT, + .module_offs = OMAP3430_DSS_MOD, + .idlest_reg_id = 1, + .idlest_stdby_bit = OMAP3430ES1_ST_DSS_SHIFT, + }, + }, + .opt_clks = dss_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(dss_opt_clks), + .slaves = omap3430es1_dss_slaves, + .slaves_cnt = ARRAY_SIZE(omap3430es1_dss_slaves), + .masters = omap3xxx_dss_masters, + .masters_cnt = ARRAY_SIZE(omap3xxx_dss_masters), + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES1), + .flags = HWMOD_NO_IDLEST, +}; + +static struct omap_hwmod omap3xxx_dss_core_hwmod = { + .name = "dss_core", + .class = &omap3xxx_dss_hwmod_class, + .main_clk = "dss1_alwon_fck", /* instead of dss_fck */ + .mpu_irqs = omap3xxx_dss_irqs, + .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_dss_irqs), + .sdma_reqs = omap3xxx_dss_sdma_chs, + .sdma_reqs_cnt = ARRAY_SIZE(omap3xxx_dss_sdma_chs), + + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_DSS1_SHIFT, + .module_offs = OMAP3430_DSS_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430ES2_ST_DSS_IDLE_SHIFT, + .idlest_stdby_bit = OMAP3430ES2_ST_DSS_STDBY_SHIFT, + }, + }, + .opt_clks = dss_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(dss_opt_clks), + .slaves = omap3xxx_dss_slaves, + .slaves_cnt = ARRAY_SIZE(omap3xxx_dss_slaves), + .masters = omap3xxx_dss_masters, + .masters_cnt = ARRAY_SIZE(omap3xxx_dss_masters), + .omap_chip = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2 | + CHIP_IS_OMAP3630ES1 | CHIP_GE_OMAP3630ES1_1), +}; + +/* + * 'dispc' class + * display controller + */ + +static struct omap_hwmod_class_sysconfig omap3xxx_dispc_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_CLOCKACTIVITY | + SYSC_HAS_MIDLEMODE | SYSC_HAS_ENAWAKEUP | + SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap3xxx_dispc_hwmod_class = { + .name = "dispc", + .sysc = &omap3xxx_dispc_sysc, +}; + +static struct omap_hwmod_addr_space omap3xxx_dss_dispc_addrs[] = { + { + .pa_start = 0x48050400, + .pa_end = 0x480507FF, + .flags = ADDR_TYPE_RT + }, +}; + +/* l4_core -> dss_dispc */ +static struct omap_hwmod_ocp_if omap3xxx_l4_core__dss_dispc = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &omap3xxx_dss_dispc_hwmod, + .clk = "dss_ick", + .addr = omap3xxx_dss_dispc_addrs, + .addr_cnt = ARRAY_SIZE(omap3xxx_dss_dispc_addrs), + .fw = { + .omap2 = { + .l4_fw_region = OMAP3_L4_CORE_FW_DSS_DISPC_REGION, + .l4_prot_group = OMAP3_L4_CORE_FW_DSS_PROT_GROUP, + .flags = OMAP_FIREWALL_L4, + } + }, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* dss_dispc slave ports */ +static struct omap_hwmod_ocp_if *omap3xxx_dss_dispc_slaves[] = { + &omap3xxx_l4_core__dss_dispc, +}; + +static struct omap_hwmod omap3xxx_dss_dispc_hwmod = { + .name = "dss_dispc", + .class = &omap3xxx_dispc_hwmod_class, + .main_clk = "dss1_alwon_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_DSS1_SHIFT, + .module_offs = OMAP3430_DSS_MOD, + }, + }, + .slaves = omap3xxx_dss_dispc_slaves, + .slaves_cnt = ARRAY_SIZE(omap3xxx_dss_dispc_slaves), + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES1 | + CHIP_GE_OMAP3430ES2 | CHIP_IS_OMAP3630ES1 | + CHIP_GE_OMAP3630ES1_1), + .flags = HWMOD_NO_IDLEST, +}; + +/* + * 'dsi' class + * display serial interface controller + */ + +static struct omap_hwmod_class omap3xxx_dsi_hwmod_class = { + .name = "dsi", +}; + +/* dss_dsi1 */ +static struct omap_hwmod_addr_space omap3xxx_dss_dsi1_addrs[] = { + { + .pa_start = 0x4804FC00, + .pa_end = 0x4804FFFF, + .flags = ADDR_TYPE_RT + }, +}; + +/* l4_core -> dss_dsi1 */ +static struct omap_hwmod_ocp_if omap3xxx_l4_core__dss_dsi1 = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &omap3xxx_dss_dsi1_hwmod, + .addr = omap3xxx_dss_dsi1_addrs, + .addr_cnt = ARRAY_SIZE(omap3xxx_dss_dsi1_addrs), + .fw = { + .omap2 = { + .l4_fw_region = OMAP3_L4_CORE_FW_DSS_DSI_REGION, + .l4_prot_group = OMAP3_L4_CORE_FW_DSS_PROT_GROUP, + .flags = OMAP_FIREWALL_L4, + } + }, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* dss_dsi1 slave ports */ +static struct omap_hwmod_ocp_if *omap3xxx_dss_dsi1_slaves[] = { + &omap3xxx_l4_core__dss_dsi1, +}; + +static struct omap_hwmod omap3xxx_dss_dsi1_hwmod = { + .name = "dss_dsi1", + .class = &omap3xxx_dsi_hwmod_class, + .main_clk = "dss1_alwon_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_DSS1_SHIFT, + .module_offs = OMAP3430_DSS_MOD, + }, + }, + .slaves = omap3xxx_dss_dsi1_slaves, + .slaves_cnt = ARRAY_SIZE(omap3xxx_dss_dsi1_slaves), + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES1 | + CHIP_GE_OMAP3430ES2 | CHIP_IS_OMAP3630ES1 | + CHIP_GE_OMAP3630ES1_1), + .flags = HWMOD_NO_IDLEST, +}; + +/* + * 'rfbi' class + * remote frame buffer interface + */ + +static struct omap_hwmod_class_sysconfig omap3xxx_rfbi_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | + SYSC_HAS_AUTOIDLE), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap3xxx_rfbi_hwmod_class = { + .name = "rfbi", + .sysc = &omap3xxx_rfbi_sysc, +}; + +static struct omap_hwmod_addr_space omap3xxx_dss_rfbi_addrs[] = { + { + .pa_start = 0x48050800, + .pa_end = 0x48050BFF, + .flags = ADDR_TYPE_RT + }, +}; + +/* l4_core -> dss_rfbi */ +static struct omap_hwmod_ocp_if omap3xxx_l4_core__dss_rfbi = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &omap3xxx_dss_rfbi_hwmod, + .clk = "dss_ick", + .addr = omap3xxx_dss_rfbi_addrs, + .addr_cnt = ARRAY_SIZE(omap3xxx_dss_rfbi_addrs), + .fw = { + .omap2 = { + .l4_fw_region = OMAP3_L4_CORE_FW_DSS_RFBI_REGION, + .l4_prot_group = OMAP3_L4_CORE_FW_DSS_PROT_GROUP , + .flags = OMAP_FIREWALL_L4, + } + }, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* dss_rfbi slave ports */ +static struct omap_hwmod_ocp_if *omap3xxx_dss_rfbi_slaves[] = { + &omap3xxx_l4_core__dss_rfbi, +}; + +static struct omap_hwmod omap3xxx_dss_rfbi_hwmod = { + .name = "dss_rfbi", + .class = &omap3xxx_rfbi_hwmod_class, + .main_clk = "dss1_alwon_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_DSS1_SHIFT, + .module_offs = OMAP3430_DSS_MOD, + }, + }, + .slaves = omap3xxx_dss_rfbi_slaves, + .slaves_cnt = ARRAY_SIZE(omap3xxx_dss_rfbi_slaves), + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES1 | + CHIP_GE_OMAP3430ES2 | CHIP_IS_OMAP3630ES1 | + CHIP_GE_OMAP3630ES1_1), + .flags = HWMOD_NO_IDLEST, +}; + +/* + * 'venc' class + * video encoder + */ + +static struct omap_hwmod_class omap3xxx_venc_hwmod_class = { + .name = "venc", +}; + +/* dss_venc */ +static struct omap_hwmod_addr_space omap3xxx_dss_venc_addrs[] = { + { + .pa_start = 0x48050C00, + .pa_end = 0x48050FFF, + .flags = ADDR_TYPE_RT + }, +}; + +/* l4_core -> dss_venc */ +static struct omap_hwmod_ocp_if omap3xxx_l4_core__dss_venc = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &omap3xxx_dss_venc_hwmod, + .clk = "dss_tv_fck", + .addr = omap3xxx_dss_venc_addrs, + .addr_cnt = ARRAY_SIZE(omap3xxx_dss_venc_addrs), + .fw = { + .omap2 = { + .l4_fw_region = OMAP3_L4_CORE_FW_DSS_VENC_REGION, + .l4_prot_group = OMAP3_L4_CORE_FW_DSS_PROT_GROUP, + .flags = OMAP_FIREWALL_L4, + } + }, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* dss_venc slave ports */ +static struct omap_hwmod_ocp_if *omap3xxx_dss_venc_slaves[] = { + &omap3xxx_l4_core__dss_venc, +}; + +static struct omap_hwmod omap3xxx_dss_venc_hwmod = { + .name = "dss_venc", + .class = &omap3xxx_venc_hwmod_class, + .main_clk = "dss1_alwon_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_DSS1_SHIFT, + .module_offs = OMAP3430_DSS_MOD, + }, + }, + .slaves = omap3xxx_dss_venc_slaves, + .slaves_cnt = ARRAY_SIZE(omap3xxx_dss_venc_slaves), + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES1 | + CHIP_GE_OMAP3430ES2 | CHIP_IS_OMAP3630ES1 | + CHIP_GE_OMAP3630ES1_1), + .flags = HWMOD_NO_IDLEST, +}; + /* I2C1 */ static struct omap_i2c_dev_attr i2c1_dev_attr = { @@ -1368,6 +1795,15 @@ static __initdata struct omap_hwmod *omap3xxx_hwmods[] = { &omap3xxx_uart2_hwmod, &omap3xxx_uart3_hwmod, &omap3xxx_uart4_hwmod, + /* dss class */ + &omap3430es1_dss_core_hwmod, + &omap3xxx_dss_core_hwmod, + &omap3xxx_dss_dispc_hwmod, + &omap3xxx_dss_dsi1_hwmod, + &omap3xxx_dss_rfbi_hwmod, + &omap3xxx_dss_venc_hwmod, + + /* i2c class */ &omap3xxx_i2c1_hwmod, &omap3xxx_i2c2_hwmod, &omap3xxx_i2c3_hwmod, diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index c2806bd11fb..93d441798d1 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -43,6 +43,13 @@ static struct omap_hwmod omap44xx_dma_system_hwmod; static struct omap_hwmod omap44xx_dmm_hwmod; static struct omap_hwmod omap44xx_dsp_hwmod; +static struct omap_hwmod omap44xx_dss_core_hwmod; +static struct omap_hwmod omap44xx_dss_dispc_hwmod; +static struct omap_hwmod omap44xx_dss_dsi1_hwmod; +static struct omap_hwmod omap44xx_dss_dsi2_hwmod; +static struct omap_hwmod omap44xx_dss_hdmi_hwmod; +static struct omap_hwmod omap44xx_dss_rfbi_hwmod; +static struct omap_hwmod omap44xx_dss_venc_hwmod; static struct omap_hwmod omap44xx_emif_fw_hwmod; static struct omap_hwmod omap44xx_iva_hwmod; static struct omap_hwmod omap44xx_l3_instr_hwmod; @@ -237,12 +244,21 @@ static struct omap_hwmod_ocp_if omap44xx_mpu__l3_main_1 = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; +/* dss -> l3_main_1 */ +static struct omap_hwmod_ocp_if omap44xx_dss__l3_main_1 = { + .master = &omap44xx_dss_core_hwmod, + .slave = &omap44xx_l3_main_1_hwmod, + .clk = "l3_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + /* l3_main_1 slave ports */ static struct omap_hwmod_ocp_if *omap44xx_l3_main_1_slaves[] = { &omap44xx_dsp__l3_main_1, &omap44xx_l3_main_2__l3_main_1, &omap44xx_l4_cfg__l3_main_1, &omap44xx_mpu__l3_main_1, + &omap44xx_dss__l3_main_1, }; static struct omap_hwmod omap44xx_l3_main_1_hwmod = { @@ -746,6 +762,584 @@ static struct omap_hwmod omap44xx_dsp_hwmod = { .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), }; +/* ==== DSS related classes ==== */ + /* + * 'dispc' class + * display controller + */ + +static struct omap_hwmod_class_sysconfig omap44xx_dispc_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY | + SYSC_HAS_ENAWAKEUP | SYSC_HAS_MIDLEMODE | + SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | + SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap44xx_dispc_hwmod_class = { + .name = "dispc", + .sysc = &omap44xx_dispc_sysc, +}; + +/* dss_dispc */ +static struct omap_hwmod_irq_info omap44xx_dss_dispc_irqs[] = { + { .irq = 25 + OMAP44XX_IRQ_GIC_START }, +}; + +static struct omap_hwmod_dma_info omap44xx_dss_dispc_sdma_reqs[] = { + { .dma_req = 5 + OMAP44XX_DMA_REQ_START }, +}; + +static struct omap_hwmod_addr_space omap44xx_dss_dispc_addrs[] = { + { + .pa_start = 0x48041000, + .pa_end = 0x48041fff, + .flags = ADDR_TYPE_RT + }, +}; + +/* l4_per -> dss_dispc */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__dss_dispc = { + .master = &omap44xx_l4_per_hwmod, + .slave = &omap44xx_dss_dispc_hwmod, + .clk = "l4_div_ck", + .addr = omap44xx_dss_dispc_addrs, + .addr_cnt = ARRAY_SIZE(omap44xx_dss_dispc_addrs), + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_addr_space omap44xx_dss_dispc_dma_addrs[] = { + { + .pa_start = 0x58001000, + .pa_end = 0x58001fff, + .flags = ADDR_TYPE_RT + }, +}; + +/* l3_main_2 -> dss_dispc */ +static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_dispc = { + .master = &omap44xx_l3_main_2_hwmod, + .slave = &omap44xx_dss_dispc_hwmod, + .clk = "l3_div_ck", + .addr = omap44xx_dss_dispc_dma_addrs, + .addr_cnt = ARRAY_SIZE(omap44xx_dss_dispc_dma_addrs), + .user = OCP_USER_SDMA, +}; + +/* dss_dispc slave ports */ +static struct omap_hwmod_ocp_if *omap44xx_dss_dispc_slaves[] = { + &omap44xx_l3_main_2__dss_dispc, + &omap44xx_l4_per__dss_dispc, +}; + +static struct omap_hwmod omap44xx_dss_dispc_hwmod = { + .name = "dss_dispc", + .class = &omap44xx_dispc_hwmod_class, + .mpu_irqs = omap44xx_dss_dispc_irqs, + .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_dss_dispc_irqs), + .sdma_reqs = omap44xx_dss_dispc_sdma_reqs, + .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_dss_dispc_sdma_reqs), + .main_clk = "dss_fck", + .prcm = { + .omap4 = { + .clkctrl_reg = OMAP4430_CM_DSS_DSS_CLKCTRL, + }, + }, + .slaves = omap44xx_dss_dispc_slaves, + .slaves_cnt = ARRAY_SIZE(omap44xx_dss_dispc_slaves), + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), +}; + +/* + * 'dsi' class + * display serial interface controller + */ +static struct omap_hwmod_class_sysconfig omap44xx_dsi_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY | + SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap44xx_dsi_hwmod_class = { + .name = "dsi", + .sysc = &omap44xx_dsi_sysc, +}; + +/* dss_dsi1 */ +static struct omap_hwmod_irq_info omap44xx_dss_dsi1_irqs[] = { + { .irq = 53 + OMAP44XX_IRQ_GIC_START }, +}; + +static struct omap_hwmod_dma_info omap44xx_dss_dsi1_sdma_reqs[] = { + { .dma_req = 74 + OMAP44XX_DMA_REQ_START }, +}; + +static struct omap_hwmod_addr_space omap44xx_dss_dsi1_addrs[] = { + { + .pa_start = 0x48044000, + .pa_end = 0x480440ff, + .flags = ADDR_TYPE_RT + }, +}; + +/* l4_per -> dss_dsi1 */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__dss_dsi1 = { + .master = &omap44xx_l4_per_hwmod, + .slave = &omap44xx_dss_dsi1_hwmod, + .clk = "l4_div_ck", + .addr = omap44xx_dss_dsi1_addrs, + .addr_cnt = ARRAY_SIZE(omap44xx_dss_dsi1_addrs), + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_addr_space omap44xx_dss_dsi1_dma_addrs[] = { + { + .pa_start = 0x58004000, + .pa_end = 0x580040ff, + .flags = ADDR_TYPE_RT + }, +}; + +/* l3_main_2 -> dss_dsi1 */ +static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_dsi1 = { + .master = &omap44xx_l3_main_2_hwmod, + .slave = &omap44xx_dss_dsi1_hwmod, + .clk = "l3_div_ck", + .addr = omap44xx_dss_dsi1_dma_addrs, + .addr_cnt = ARRAY_SIZE(omap44xx_dss_dsi1_dma_addrs), + .user = OCP_USER_SDMA, +}; + +/* dss_dsi1 slave ports */ +static struct omap_hwmod_ocp_if *omap44xx_dss_dsi1_slaves[] = { + &omap44xx_l3_main_2__dss_dsi1, + &omap44xx_l4_per__dss_dsi1, +}; + +static struct omap_hwmod omap44xx_dss_dsi1_hwmod = { + .name = "dss_dsi1", + .class = &omap44xx_dsi_hwmod_class, + .mpu_irqs = omap44xx_dss_dsi1_irqs, + .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_dss_dsi1_irqs), + .sdma_reqs = omap44xx_dss_dsi1_sdma_reqs, + .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_dss_dsi1_sdma_reqs), + .main_clk = "dss_fck", + .prcm = { + .omap4 = { + .clkctrl_reg = OMAP4430_CM_DSS_DSS_CLKCTRL, + }, + }, + .slaves = omap44xx_dss_dsi1_slaves, + .slaves_cnt = ARRAY_SIZE(omap44xx_dss_dsi1_slaves), + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), +}; + +/* dss_dsi2 */ +static struct omap_hwmod_irq_info omap44xx_dss_dsi2_irqs[] = { + { .irq = 84 + OMAP44XX_IRQ_GIC_START }, +}; + +static struct omap_hwmod_dma_info omap44xx_dss_dsi2_sdma_reqs[] = { + { .dma_req = 83 + OMAP44XX_DMA_REQ_START }, +}; + +static struct omap_hwmod_addr_space omap44xx_dss_dsi2_addrs[] = { + { + .pa_start = 0x48045000, + .pa_end = 0x480450ff, + .flags = ADDR_TYPE_RT + }, +}; + +/* l4_per -> dss_dsi2 */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__dss_dsi2 = { + .master = &omap44xx_l4_per_hwmod, + .slave = &omap44xx_dss_dsi2_hwmod, + .clk = "l4_div_ck", + .addr = omap44xx_dss_dsi2_addrs, + .addr_cnt = ARRAY_SIZE(omap44xx_dss_dsi2_addrs), + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_addr_space omap44xx_dss_dsi2_dma_addrs[] = { + { + .pa_start = 0x58005000, + .pa_end = 0x580050ff, + .flags = ADDR_TYPE_RT + }, +}; + +/* l3_main_2 -> dss_dsi2 */ +static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_dsi2 = { + .master = &omap44xx_l3_main_2_hwmod, + .slave = &omap44xx_dss_dsi2_hwmod, + .clk = "l3_div_ck", + .addr = omap44xx_dss_dsi2_dma_addrs, + .addr_cnt = ARRAY_SIZE(omap44xx_dss_dsi2_dma_addrs), + .user = OCP_USER_SDMA, +}; + +/* dss_dsi2 slave ports */ +static struct omap_hwmod_ocp_if *omap44xx_dss_dsi2_slaves[] = { + &omap44xx_l3_main_2__dss_dsi2, + &omap44xx_l4_per__dss_dsi2, +}; + +static struct omap_hwmod omap44xx_dss_dsi2_hwmod = { + .name = "dss_dsi2", + .class = &omap44xx_dsi_hwmod_class, + .mpu_irqs = omap44xx_dss_dsi2_irqs, + .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_dss_dsi2_irqs), + .sdma_reqs = omap44xx_dss_dsi2_sdma_reqs, + .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_dss_dsi2_sdma_reqs), + .main_clk = "dss_fck", + .prcm = { + .omap4 = { + .clkctrl_reg = OMAP4430_CM_DSS_DSS_CLKCTRL, + }, + }, + .slaves = omap44xx_dss_dsi2_slaves, + .slaves_cnt = ARRAY_SIZE(omap44xx_dss_dsi2_slaves), + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), +}; + +/* + * 'dss' class + * display sub-system + */ +static struct omap_hwmod_class_sysconfig omap44xx_dss_sysc = { + .rev_offs = 0x0000, + .syss_offs = 0x0014, + .sysc_flags = SYSS_HAS_RESET_STATUS, + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), +}; + +static struct omap_hwmod_class omap44xx_dss_hwmod_class = { + .name = "dss", + .sysc = &omap44xx_dss_sysc, +}; + +/* dss */ +/* dss master ports */ +static struct omap_hwmod_ocp_if *omap44xx_dss_masters[] = { + &omap44xx_dss__l3_main_1, +}; + +static struct omap_hwmod_irq_info omap44xx_dss_irqs[] = { + { .irq = 25 + OMAP44XX_IRQ_GIC_START }, +}; + +static struct omap_hwmod_addr_space omap44xx_dss_addrs[] = { + { + .pa_start = 0x48040000, + .pa_end = 0x4804007f, + .flags = ADDR_TYPE_RT + }, +}; + +/* l4_per -> dss */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__dss = { + .master = &omap44xx_l4_per_hwmod, + .slave = &omap44xx_dss_core_hwmod, + .clk = "l4_div_ck", + .addr = omap44xx_dss_addrs, + .addr_cnt = ARRAY_SIZE(omap44xx_dss_addrs), + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_addr_space omap44xx_dss_dma_addrs[] = { + { + .pa_start = 0x58000000, + .pa_end = 0x5800007f, + .flags = ADDR_TYPE_RT + }, +}; + +/* l3_main_2 -> dss */ +static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss = { + .master = &omap44xx_l3_main_2_hwmod, + .slave = &omap44xx_dss_core_hwmod, + .clk = "l3_div_ck", + .addr = omap44xx_dss_dma_addrs, + .addr_cnt = ARRAY_SIZE(omap44xx_dss_dma_addrs), + .user = OCP_USER_SDMA, +}; + +/* dss slave ports */ +static struct omap_hwmod_ocp_if *omap44xx_dss_slaves[] = { + &omap44xx_l3_main_2__dss, + &omap44xx_l4_per__dss, +}; + +static struct omap_hwmod_opt_clk dss_opt_clks[] = { + { .role = "sys_clk", .clk = "dss_sys_clk" }, + { .role = "tv_clk", .clk = "dss_tv_clk" }, + { .role = "dss_clk", .clk = "dss_dss_clk" }, + { .role = "video_clk", .clk = "dss_48mhz_clk" }, +}; + +static struct omap_hwmod omap44xx_dss_core_hwmod = { + .name = "dss_core", + .class = &omap44xx_dss_hwmod_class, + .mpu_irqs = omap44xx_dss_irqs, + .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_dss_irqs), + .main_clk = "dss_fck", + .prcm = { + .omap4 = { + .clkctrl_reg = OMAP4430_CM_DSS_DSS_CLKCTRL, + }, + }, + .opt_clks = dss_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(dss_opt_clks), + .slaves = omap44xx_dss_slaves, + .slaves_cnt = ARRAY_SIZE(omap44xx_dss_slaves), + .masters = omap44xx_dss_masters, + .masters_cnt = ARRAY_SIZE(omap44xx_dss_masters), + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), +}; + +/* + * 'hdmi' class + * hdmi controller + */ + +static struct omap_hwmod_class omap44xx_hdmi_hwmod_class = { + .name = "hdmi", +}; + +/* dss_hdmi */ +static struct omap_hwmod_irq_info omap44xx_dss_hdmi_irqs[] = { + { .irq = 101 + OMAP44XX_IRQ_GIC_START }, +}; + +static struct omap_hwmod_dma_info omap44xx_dss_hdmi_sdma_reqs[] = { + { .dma_req = 75 + OMAP44XX_DMA_REQ_START }, +}; + +static struct omap_hwmod_addr_space omap44xx_dss_hdmi_addrs[] = { + { + .pa_start = 0x48046000, + .pa_end = 0x48046fff, + .flags = ADDR_TYPE_RT + }, +}; + +/* l4_per -> dss_hdmi */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__dss_hdmi = { + .master = &omap44xx_l4_per_hwmod, + .slave = &omap44xx_dss_hdmi_hwmod, + .clk = "l4_div_ck", + .addr = omap44xx_dss_hdmi_addrs, + .addr_cnt = ARRAY_SIZE(omap44xx_dss_hdmi_addrs), + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_addr_space omap44xx_dss_hdmi_dma_addrs[] = { + { + .pa_start = 0x58006000, + .pa_end = 0x58006fff, + .flags = ADDR_TYPE_RT + }, +}; + +/* l3_main_2 -> dss_hdmi */ +static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_hdmi = { + .master = &omap44xx_l3_main_2_hwmod, + .slave = &omap44xx_dss_hdmi_hwmod, + .clk = "l3_div_ck", + .addr = omap44xx_dss_hdmi_dma_addrs, + .addr_cnt = ARRAY_SIZE(omap44xx_dss_hdmi_dma_addrs), + .user = OCP_USER_SDMA, +}; + +/* dss_hdmi slave ports */ +static struct omap_hwmod_ocp_if *omap44xx_dss_hdmi_slaves[] = { + &omap44xx_l3_main_2__dss_hdmi, + &omap44xx_l4_per__dss_hdmi, +}; + +static struct omap_hwmod omap44xx_dss_hdmi_hwmod = { + .name = "dss_hdmi", + .class = &omap44xx_hdmi_hwmod_class, + .mpu_irqs = omap44xx_dss_hdmi_irqs, + .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_dss_hdmi_irqs), + .sdma_reqs = omap44xx_dss_hdmi_sdma_reqs, + .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_dss_hdmi_sdma_reqs), + .main_clk = "dss_fck", + .prcm = { + .omap4 = { + .clkctrl_reg = OMAP4430_CM_DSS_DSS_CLKCTRL, + }, + }, + .slaves = omap44xx_dss_hdmi_slaves, + .slaves_cnt = ARRAY_SIZE(omap44xx_dss_hdmi_slaves), + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), +}; + + /* + * 'rfbi' class + * remote frame buffer interface + */ + +static struct omap_hwmod_class_sysconfig omap44xx_rfbi_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap44xx_rfbi_hwmod_class = { + .name = "rfbi", + .sysc = &omap44xx_rfbi_sysc, +}; + +/* dss_rfbi */ +static struct omap_hwmod_dma_info omap44xx_dss_rfbi_sdma_reqs[] = { + { .dma_req = 13 + OMAP44XX_DMA_REQ_START }, +}; + +static struct omap_hwmod_addr_space omap44xx_dss_rfbi_addrs[] = { + { + .pa_start = 0x48042000, + .pa_end = 0x480420ff, + .flags = ADDR_TYPE_RT + }, +}; + +/* l4_per -> dss_rfbi */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__dss_rfbi = { + .master = &omap44xx_l4_per_hwmod, + .slave = &omap44xx_dss_rfbi_hwmod, + .clk = "l4_div_ck", + .addr = omap44xx_dss_rfbi_addrs, + .addr_cnt = ARRAY_SIZE(omap44xx_dss_rfbi_addrs), + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_addr_space omap44xx_dss_rfbi_dma_addrs[] = { + { + .pa_start = 0x58002000, + .pa_end = 0x580020ff, + .flags = ADDR_TYPE_RT + }, +}; + +/* l3_main_2 -> dss_rfbi */ +static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_rfbi = { + .master = &omap44xx_l3_main_2_hwmod, + .slave = &omap44xx_dss_rfbi_hwmod, + .clk = "l3_div_ck", + .addr = omap44xx_dss_rfbi_dma_addrs, + .addr_cnt = ARRAY_SIZE(omap44xx_dss_rfbi_dma_addrs), + .user = OCP_USER_SDMA, +}; + +/* dss_rfbi slave ports */ +static struct omap_hwmod_ocp_if *omap44xx_dss_rfbi_slaves[] = { + &omap44xx_l3_main_2__dss_rfbi, + &omap44xx_l4_per__dss_rfbi, +}; + +static struct omap_hwmod omap44xx_dss_rfbi_hwmod = { + .name = "dss_rfbi", + .class = &omap44xx_rfbi_hwmod_class, + .sdma_reqs = omap44xx_dss_rfbi_sdma_reqs, + .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_dss_rfbi_sdma_reqs), + .main_clk = "dss_fck", + .prcm = { + .omap4 = { + .clkctrl_reg = OMAP4430_CM_DSS_DSS_CLKCTRL, + }, + }, + .slaves = omap44xx_dss_rfbi_slaves, + .slaves_cnt = ARRAY_SIZE(omap44xx_dss_rfbi_slaves), + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), +}; + +/* + * 'venc' class + * video encoder + */ + +static struct omap_hwmod_class_sysconfig omap44xx_venc_sysc = { + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), +}; + +static struct omap_hwmod_class omap44xx_venc_hwmod_class = { + .name = "venc", + .sysc = &omap44xx_venc_sysc, +}; + +/* dss_venc */ +static struct omap_hwmod_addr_space omap44xx_dss_venc_addrs[] = { + { + .pa_start = 0x48043000, + .pa_end = 0x480430ff, + .flags = ADDR_TYPE_RT + }, +}; + +/* l4_per -> dss_venc */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__dss_venc = { + .master = &omap44xx_l4_per_hwmod, + .slave = &omap44xx_dss_venc_hwmod, + .clk = "l4_div_ck", + .addr = omap44xx_dss_venc_addrs, + .addr_cnt = ARRAY_SIZE(omap44xx_dss_venc_addrs), + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_addr_space omap44xx_dss_venc_dma_addrs[] = { + { + .pa_start = 0x58003000, + .pa_end = 0x580030ff, + .flags = ADDR_TYPE_RT + }, +}; + +/* l3_main_2 -> dss_venc */ +static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_venc = { + .master = &omap44xx_l3_main_2_hwmod, + .slave = &omap44xx_dss_venc_hwmod, + .clk = "l3_div_ck", + .addr = omap44xx_dss_venc_dma_addrs, + .addr_cnt = ARRAY_SIZE(omap44xx_dss_venc_dma_addrs), + .user = OCP_USER_SDMA, +}; + +/* dss_venc slave ports */ +static struct omap_hwmod_ocp_if *omap44xx_dss_venc_slaves[] = { + &omap44xx_l3_main_2__dss_venc, + &omap44xx_l4_per__dss_venc, +}; + +static struct omap_hwmod omap44xx_dss_venc_hwmod = { + .name = "dss_venc", + .class = &omap44xx_venc_hwmod_class, + .prcm = { + .omap4 = { + .clkctrl_reg = OMAP4430_CM_DSS_DSS_CLKCTRL, + }, + }, + .slaves = omap44xx_dss_venc_slaves, + .slaves_cnt = ARRAY_SIZE(omap44xx_dss_venc_slaves), + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), +}; + + /* * 'gpio' class * general purpose io module @@ -1464,6 +2058,7 @@ static struct omap_hwmod omap44xx_mpu_hwmod = { .mpu_irqs = omap44xx_mpu_irqs, .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_mpu_irqs), .main_clk = "dpll_mpu_m2_ck", + .vdd_name = "mpu", .prcm = { .omap4 = { .clkctrl_reg = OMAP4430_CM_MPU_MPU_CLKCTRL, @@ -2031,6 +2626,15 @@ static __initdata struct omap_hwmod *omap44xx_hwmods[] = { &omap44xx_dsp_hwmod, &omap44xx_dsp_c0_hwmod, + /* dss class */ + &omap44xx_dss_core_hwmod, + &omap44xx_dss_dispc_hwmod, + &omap44xx_dss_dsi1_hwmod, + &omap44xx_dss_dsi2_hwmod, + &omap44xx_dss_hdmi_hwmod, + &omap44xx_dss_rfbi_hwmod, + &omap44xx_dss_venc_hwmod, + /* gpio class */ &omap44xx_gpio1_hwmod, &omap44xx_gpio2_hwmod, diff --git a/arch/arm/mach-omap2/omap_twl.c b/arch/arm/mach-omap2/omap_twl.c index 00e1d2b5368..5100125bc2f 100644 --- a/arch/arm/mach-omap2/omap_twl.c +++ b/arch/arm/mach-omap2/omap_twl.c @@ -59,8 +59,15 @@ static bool is_offset_valid; static u8 smps_offset; +/* + * Flag to ensure Smartreflex bit in TWL + * being cleared in board file is not overwritten. + */ +static bool __initdata twl_sr_enable_autoinit; +#define TWL4030_DCDC_GLOBAL_CFG 0x06 #define REG_SMPS_OFFSET 0xE0 +#define SMARTREFLEX_ENABLE BIT(3) static unsigned long twl4030_vsel_to_uv(const u8 vsel) { @@ -269,6 +276,18 @@ int __init omap3_twl_init(void) omap3_core_volt_info.vp_vddmax = OMAP3630_VP2_VLIMITTO_VDDMAX; } + /* + * The smartreflex bit on twl4030 specifies if the setting of voltage + * is done over the I2C_SR path. Since this setting is independent of + * the actual usage of smartreflex AVS module, we enable TWL SR bit + * by default irrespective of whether smartreflex AVS module is enabled + * on the OMAP side or not. This is because without this bit enabled, + * the voltage scaling through vp forceupdate/bypass mechanism of + * voltage scaling will not function on TWL over I2C_SR. + */ + if (!twl_sr_enable_autoinit) + omap3_twl_set_sr_bit(true); + voltdm = omap_voltage_domain_lookup("mpu"); omap_voltage_register_pmic(voltdm, &omap3_mpu_volt_info); @@ -277,3 +296,44 @@ int __init omap3_twl_init(void) return 0; } + +/** + * omap3_twl_set_sr_bit() - Set/Clear SR bit on TWL + * @enable: enable SR mode in twl or not + * + * If 'enable' is true, enables Smartreflex bit on TWL 4030 to make sure + * voltage scaling through OMAP SR works. Else, the smartreflex bit + * on twl4030 is cleared as there are platforms which use OMAP3 and T2 but + * use Synchronized Scaling Hardware Strategy (ENABLE_VMODE=1) and Direct + * Strategy Software Scaling Mode (ENABLE_VMODE=0), for setting the voltages, + * in those scenarios this bit is to be cleared (enable = false). + * + * Returns 0 on sucess, error is returned if I2C read/write fails. + */ +int __init omap3_twl_set_sr_bit(bool enable) +{ + u8 temp; + int ret; + if (twl_sr_enable_autoinit) + pr_warning("%s: unexpected multiple calls\n", __func__); + + ret = twl_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &temp, + TWL4030_DCDC_GLOBAL_CFG); + if (ret) + goto err; + + if (enable) + temp |= SMARTREFLEX_ENABLE; + else + temp &= ~SMARTREFLEX_ENABLE; + + ret = twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, temp, + TWL4030_DCDC_GLOBAL_CFG); + if (!ret) { + twl_sr_enable_autoinit = true; + return 0; + } +err: + pr_err("%s: Error access to TWL4030 (%d)\n", __func__, ret); + return ret; +} diff --git a/arch/arm/mach-omap2/opp3xxx_data.c b/arch/arm/mach-omap2/opp3xxx_data.c index 0486fce8a92..eefd6aff3f2 100644 --- a/arch/arm/mach-omap2/opp3xxx_data.c +++ b/arch/arm/mach-omap2/opp3xxx_data.c @@ -19,20 +19,21 @@ #include <linux/module.h> #include <plat/cpu.h> +#include <plat/voltage.h> #include "omap_opp_data.h" static struct omap_opp_def __initdata omap34xx_opp_def_list[] = { /* MPU OPP1 */ - OPP_INITIALIZER("mpu", true, 125000000, 975000), + OPP_INITIALIZER("mpu", true, 125000000, OMAP3430_VDD_MPU_OPP1_UV), /* MPU OPP2 */ - OPP_INITIALIZER("mpu", true, 250000000, 1075000), + OPP_INITIALIZER("mpu", true, 250000000, OMAP3430_VDD_MPU_OPP2_UV), /* MPU OPP3 */ - OPP_INITIALIZER("mpu", true, 500000000, 1200000), + OPP_INITIALIZER("mpu", true, 500000000, OMAP3430_VDD_MPU_OPP3_UV), /* MPU OPP4 */ - OPP_INITIALIZER("mpu", true, 550000000, 1270000), + OPP_INITIALIZER("mpu", true, 550000000, OMAP3430_VDD_MPU_OPP4_UV), /* MPU OPP5 */ - OPP_INITIALIZER("mpu", true, 600000000, 1350000), + OPP_INITIALIZER("mpu", true, 600000000, OMAP3430_VDD_MPU_OPP5_UV), /* * L3 OPP1 - 41.5 MHz is disabled because: The voltage for that OPP is @@ -42,47 +43,47 @@ static struct omap_opp_def __initdata omap34xx_opp_def_list[] = { * impact that frequency will do to the MPU and the whole system in * general. */ - OPP_INITIALIZER("l3_main", false, 41500000, 975000), + OPP_INITIALIZER("l3_main", false, 41500000, OMAP3430_VDD_CORE_OPP1_UV), /* L3 OPP2 */ - OPP_INITIALIZER("l3_main", true, 83000000, 1050000), + OPP_INITIALIZER("l3_main", true, 83000000, OMAP3430_VDD_CORE_OPP2_UV), /* L3 OPP3 */ - OPP_INITIALIZER("l3_main", true, 166000000, 1150000), + OPP_INITIALIZER("l3_main", true, 166000000, OMAP3430_VDD_CORE_OPP3_UV), /* DSP OPP1 */ - OPP_INITIALIZER("iva", true, 90000000, 975000), + OPP_INITIALIZER("iva", true, 90000000, OMAP3430_VDD_MPU_OPP1_UV), /* DSP OPP2 */ - OPP_INITIALIZER("iva", true, 180000000, 1075000), + OPP_INITIALIZER("iva", true, 180000000, OMAP3430_VDD_MPU_OPP2_UV), /* DSP OPP3 */ - OPP_INITIALIZER("iva", true, 360000000, 1200000), + OPP_INITIALIZER("iva", true, 360000000, OMAP3430_VDD_MPU_OPP3_UV), /* DSP OPP4 */ - OPP_INITIALIZER("iva", true, 400000000, 1270000), + OPP_INITIALIZER("iva", true, 400000000, OMAP3430_VDD_MPU_OPP4_UV), /* DSP OPP5 */ - OPP_INITIALIZER("iva", true, 430000000, 1350000), + OPP_INITIALIZER("iva", true, 430000000, OMAP3430_VDD_MPU_OPP5_UV), }; static struct omap_opp_def __initdata omap36xx_opp_def_list[] = { /* MPU OPP1 - OPP50 */ - OPP_INITIALIZER("mpu", true, 300000000, 1012500), + OPP_INITIALIZER("mpu", true, 300000000, OMAP3630_VDD_MPU_OPP50_UV), /* MPU OPP2 - OPP100 */ - OPP_INITIALIZER("mpu", true, 600000000, 1200000), + OPP_INITIALIZER("mpu", true, 600000000, OMAP3630_VDD_MPU_OPP100_UV), /* MPU OPP3 - OPP-Turbo */ - OPP_INITIALIZER("mpu", false, 800000000, 1325000), + OPP_INITIALIZER("mpu", false, 800000000, OMAP3630_VDD_MPU_OPP120_UV), /* MPU OPP4 - OPP-SB */ - OPP_INITIALIZER("mpu", false, 1000000000, 1375000), + OPP_INITIALIZER("mpu", false, 1000000000, OMAP3630_VDD_MPU_OPP1G_UV), /* L3 OPP1 - OPP50 */ - OPP_INITIALIZER("l3_main", true, 100000000, 1000000), + OPP_INITIALIZER("l3_main", true, 100000000, OMAP3630_VDD_CORE_OPP50_UV), /* L3 OPP2 - OPP100, OPP-Turbo, OPP-SB */ - OPP_INITIALIZER("l3_main", true, 200000000, 1200000), + OPP_INITIALIZER("l3_main", true, 200000000, OMAP3630_VDD_CORE_OPP100_UV), /* DSP OPP1 - OPP50 */ - OPP_INITIALIZER("iva", true, 260000000, 1012500), + OPP_INITIALIZER("iva", true, 260000000, OMAP3630_VDD_MPU_OPP50_UV), /* DSP OPP2 - OPP100 */ - OPP_INITIALIZER("iva", true, 520000000, 1200000), + OPP_INITIALIZER("iva", true, 520000000, OMAP3630_VDD_MPU_OPP100_UV), /* DSP OPP3 - OPP-Turbo */ - OPP_INITIALIZER("iva", false, 660000000, 1325000), + OPP_INITIALIZER("iva", false, 660000000, OMAP3630_VDD_MPU_OPP120_UV), /* DSP OPP4 - OPP-SB */ - OPP_INITIALIZER("iva", false, 800000000, 1375000), + OPP_INITIALIZER("iva", false, 800000000, OMAP3630_VDD_MPU_OPP1G_UV), }; /** diff --git a/arch/arm/mach-omap2/opp4xxx_data.c b/arch/arm/mach-omap2/opp4xxx_data.c index a11fa566d8e..2e8bb8a6ba9 100644 --- a/arch/arm/mach-omap2/opp4xxx_data.c +++ b/arch/arm/mach-omap2/opp4xxx_data.c @@ -20,22 +20,23 @@ #include <linux/module.h> #include <plat/cpu.h> +#include <plat/voltage.h> #include "omap_opp_data.h" static struct omap_opp_def __initdata omap44xx_opp_def_list[] = { /* MPU OPP1 - OPP50 */ - OPP_INITIALIZER("mpu", true, 300000000, 1100000), + OPP_INITIALIZER("mpu", true, 300000000, OMAP4430_VDD_MPU_OPP50_UV), /* MPU OPP2 - OPP100 */ - OPP_INITIALIZER("mpu", true, 600000000, 1200000), + OPP_INITIALIZER("mpu", true, 600000000, OMAP4430_VDD_MPU_OPP100_UV), /* MPU OPP3 - OPP-Turbo */ - OPP_INITIALIZER("mpu", false, 800000000, 1260000), + OPP_INITIALIZER("mpu", true, 800000000, OMAP4430_VDD_MPU_OPPTURBO_UV), /* MPU OPP4 - OPP-SB */ - OPP_INITIALIZER("mpu", false, 1008000000, 1350000), + OPP_INITIALIZER("mpu", true, 1008000000, OMAP4430_VDD_MPU_OPPNITRO_UV), /* L3 OPP1 - OPP50 */ - OPP_INITIALIZER("l3_main_1", true, 100000000, 930000), + OPP_INITIALIZER("l3_main_1", true, 100000000, OMAP4430_VDD_CORE_OPP50_UV), /* L3 OPP2 - OPP100, OPP-Turbo, OPP-SB */ - OPP_INITIALIZER("l3_main_1", true, 200000000, 1100000), + OPP_INITIALIZER("l3_main_1", true, 200000000, OMAP4430_VDD_CORE_OPP100_UV), /* TODO: add IVA, DSP, aess, fdif, gpu */ }; diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c index d5a102c7198..51b0dcdef60 100644 --- a/arch/arm/mach-omap2/pm.c +++ b/arch/arm/mach-omap2/pm.c @@ -23,6 +23,9 @@ #include "powerdomain.h" #include "clockdomain.h" #include "pm.h" +#include "cm2xxx_3xxx.h" +#include "cm-regbits-34xx.h" +#include "prm.h" static struct omap_device_pm_latency *pm_lats; @@ -31,6 +34,8 @@ static struct device *iva_dev; static struct device *l3_dev; static struct device *dsp_dev; +static struct clk *dpll1_clk, *dpll2_clk, *dpll3_clk; + struct device *omap2_get_mpuss_device(void) { WARN_ON_ONCE(!mpu_dev); @@ -77,6 +82,73 @@ static int _init_omap_device(char *name, struct device **new_dev) return 0; } +static unsigned long omap3_mpu_get_rate(struct device *dev) +{ + return dpll1_clk->rate; +} + +static int omap3_mpu_set_rate(struct device *dev, unsigned long rate) +{ + int ret; + + ret = clk_set_rate(dpll1_clk, rate); + if (ret) { + dev_warn(dev, "%s: Unable to set rate to %ld\n", + __func__, rate); + return ret; + } + + return 0; +} + +static int omap3_iva_set_rate(struct device *dev, unsigned long rate) +{ + return clk_set_rate(dpll2_clk, rate); +} + +static unsigned long omap3_iva_get_rate(struct device *dev) +{ + return dpll2_clk->rate; +} + +static int omap3_l3_set_rate(struct device *dev, unsigned long rate) +{ + int l3_div; + + l3_div = omap2_cm_read_mod_reg(CORE_MOD, CM_CLKSEL) & + OMAP3430_CLKSEL_L3_MASK; + + return clk_set_rate(dpll3_clk, rate * l3_div); +} + +static unsigned long omap3_l3_get_rate(struct device *dev) +{ + int l3_div; + + l3_div = omap2_cm_read_mod_reg(CORE_MOD, CM_CLKSEL) & + OMAP3430_CLKSEL_L3_MASK; + return dpll3_clk->rate / l3_div; +} + +static int omap4_mpu_set_rate(struct device *dev, unsigned long rate) +{ + int ret; + + ret = clk_set_rate(dpll1_clk, rate); + if (ret) { + dev_warn(dev, "%s: Unable to set rate to %ld\n", + __func__, rate); + return ret; + } + + return 0; +} + +static unsigned long omap4_mpu_get_rate(struct device *dev) +{ + return dpll1_clk->rate; +} + /* * Build omap_devices for processors and bus. */ @@ -90,6 +162,30 @@ static void omap2_init_processor_devices(void) } else { _init_omap_device("l3_main", &l3_dev); } + + if (cpu_is_omap34xx()) { + dpll1_clk = clk_get(NULL, "dpll1_ck"); + dpll2_clk = clk_get(NULL, "dpll2_ck"); + dpll3_clk = clk_get(NULL, "dpll3_m2_ck"); + + if (mpu_dev) + omap_device_register_dvfs_callbacks(mpu_dev, + omap3_mpu_set_rate, omap3_mpu_get_rate); + if (iva_dev) + omap_device_register_dvfs_callbacks(iva_dev, + omap3_iva_set_rate, omap3_iva_get_rate); + if (l3_dev) + omap_device_register_dvfs_callbacks(l3_dev, + omap3_l3_set_rate, omap3_l3_get_rate); + + } else if (cpu_is_omap44xx()) { + dpll1_clk = clk_get(NULL, "dpll_mpu_ck"); + + if (mpu_dev) + omap_device_register_dvfs_callbacks(mpu_dev, + omap4_mpu_set_rate, omap4_mpu_get_rate); + } + } /* Types of sleep_switch used in omap_set_pwrdm_state */ diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h index 1c1b0ab5b97..797bfd12b64 100644 --- a/arch/arm/mach-omap2/pm.h +++ b/arch/arm/mach-omap2/pm.h @@ -92,7 +92,7 @@ extern void omap24xx_idle_loop_suspend(void); extern void omap24xx_cpu_suspend(u32 dll_ctrl, void __iomem *sdrc_dlla_ctrl, void __iomem *sdrc_power); extern void omap34xx_cpu_suspend(u32 *addr, int save_state); -extern void save_secure_ram_context(u32 *addr); +extern int save_secure_ram_context(u32 *addr); extern void omap3_save_scratchpad_contents(void); extern unsigned int omap24xx_idle_loop_suspend_sz; @@ -127,6 +127,7 @@ static inline void omap_enable_smartreflex_on_init(void) {} #ifdef CONFIG_TWL4030_CORE extern int omap3_twl_init(void); extern int omap4_twl_init(void); +extern int omap3_twl_set_sr_bit(bool enable); #else static inline int omap3_twl_init(void) { diff --git a/arch/arm/mach-omap2/sleep24xx.S b/arch/arm/mach-omap2/sleep24xx.S index c7780cc8d91..b5071a47ec3 100644 --- a/arch/arm/mach-omap2/sleep24xx.S +++ b/arch/arm/mach-omap2/sleep24xx.S @@ -47,6 +47,7 @@ * Note: This code get's copied to internal SRAM at boot. When the OMAP * wakes up it continues execution at the point it went to sleep. */ + .align 3 ENTRY(omap24xx_idle_loop_suspend) stmfd sp!, {r0, lr} @ save registers on stack mov r0, #0 @ clear for mcr setup @@ -82,6 +83,7 @@ ENTRY(omap24xx_idle_loop_suspend_sz) * The DLL load value is not kept in RETENTION or OFF. It needs to be restored * at wake */ + .align 3 ENTRY(omap24xx_cpu_suspend) stmfd sp!, {r0 - r12, lr} @ save registers on stack mov r3, #0x0 @ clear for mcr call diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S index 98d8232808b..6147088e6bc 100644 --- a/arch/arm/mach-omap2/sleep34xx.S +++ b/arch/arm/mach-omap2/sleep34xx.S @@ -64,6 +64,11 @@ #define SDRC_DLLA_STATUS_V OMAP34XX_SDRC_REGADDR(SDRC_DLLA_STATUS) #define SDRC_DLLA_CTRL_V OMAP34XX_SDRC_REGADDR(SDRC_DLLA_CTRL) +/* + * This file needs be built unconditionally as ARM to interoperate correctly + * with non-Thumb-2-capable firmware. + */ + .arm /* * API functions @@ -82,6 +87,8 @@ ENTRY(get_restore_pointer) stmfd sp!, {lr} @ save registers on stack adr r0, restore ldmfd sp!, {pc} @ restore regs and return +ENDPROC(get_restore_pointer) + .align ENTRY(get_restore_pointer_sz) .word . - get_restore_pointer @@ -91,6 +98,8 @@ ENTRY(get_omap3630_restore_pointer) stmfd sp!, {lr} @ save registers on stack adr r0, restore_3630 ldmfd sp!, {pc} @ restore regs and return +ENDPROC(get_omap3630_restore_pointer) + .align ENTRY(get_omap3630_restore_pointer_sz) .word . - get_omap3630_restore_pointer @@ -100,6 +109,8 @@ ENTRY(get_es3_restore_pointer) stmfd sp!, {lr} @ save registers on stack adr r0, restore_es3 ldmfd sp!, {pc} @ restore regs and return +ENDPROC(get_es3_restore_pointer) + .align ENTRY(get_es3_restore_pointer_sz) .word . - get_es3_restore_pointer @@ -113,11 +124,14 @@ ENTRY(enable_omap3630_toggle_l2_on_restore) stmfd sp!, {lr} @ save registers on stack /* Setup so that we will disable and enable l2 */ mov r1, #0x1 - str r1, l2dis_3630 + adrl r2, l2dis_3630 @ may be too distant for plain adr + str r1, [r2] ldmfd sp!, {pc} @ restore regs and return +ENDPROC(enable_omap3630_toggle_l2_on_restore) .text /* Function to call rom code to save secure ram context */ + .align 3 ENTRY(save_secure_ram_context) stmfd sp!, {r1-r12, lr} @ save registers on stack adr r3, api_params @ r3 points to parameters @@ -133,18 +147,20 @@ ENTRY(save_secure_ram_context) mov r6, #0xff mcr p15, 0, r0, c7, c10, 4 @ data write barrier mcr p15, 0, r0, c7, c10, 5 @ data memory barrier - .word 0xE1600071 @ call SMI monitor (smi #1) + smc #1 @ call SMI monitor (smi #1) nop nop nop nop ldmfd sp!, {r1-r12, pc} + .align sram_phy_addr_mask: .word SRAM_BASE_P high_mask: .word 0xffff api_params: .word 0x4, 0x0, 0x0, 0x1, 0x1 +ENDPROC(save_secure_ram_context) ENTRY(save_secure_ram_context_sz) .word . - save_secure_ram_context @@ -169,6 +185,7 @@ ENTRY(save_secure_ram_context_sz) * depending on the low power mode (non-OFF vs OFF modes), * cf. 'Resume path for xxx mode' comments. */ + .align 3 ENTRY(omap34xx_cpu_suspend) stmfd sp!, {r0-r12, lr} @ save registers on stack @@ -279,8 +296,18 @@ clean_l2: * - 'might' have to copy address, load and jump to it */ ldr r1, kernel_flush - mov lr, pc - bx r1 + blx r1 + /* + * The kernel doesn't interwork: v7_flush_dcache_all in particluar will + * always return in Thumb state when CONFIG_THUMB2_KERNEL is enabled. + * This sequence switches back to ARM. Note that .align may insert a + * nop: bx pc needs to be word-aligned in order to work. + */ + THUMB( .thumb ) + THUMB( .align ) + THUMB( bx pc ) + THUMB( nop ) + .arm omap3_do_wfi: ldr r4, sdrc_power @ read the SDRC_POWER register @@ -346,9 +373,9 @@ restore_es3: and r4, r4, #0x3 cmp r4, #0x0 @ Check if previous power state of CORE is OFF bne restore - adr r0, es3_sdrc_fix + adr r0, _es3_sdrc_fix ldr r1, sram_base - ldr r2, es3_sdrc_fix_sz + ldr r2, _es3_sdrc_fix_sz mov r2, r2, ror #2 copy_to_sram: ldmia r0!, {r3} @ val = *src @@ -408,7 +435,7 @@ skipl2dis: adr r3, l2_inv_api_params @ r3 points to dummy parameters mcr p15, 0, r0, c7, c10, 4 @ data write barrier mcr p15, 0, r0, c7, c10, 5 @ data memory barrier - .word 0xE1600071 @ call SMI monitor (smi #1) + smc #1 @ call SMI monitor (smi #1) /* Write to Aux control register to set some bits */ mov r0, #42 @ set service ID for PPA mov r12, r0 @ copy secure Service ID in r12 @@ -419,7 +446,7 @@ skipl2dis: ldr r3, [r4, #0xBC] @ r3 points to parameters mcr p15, 0, r0, c7, c10, 4 @ data write barrier mcr p15, 0, r0, c7, c10, 5 @ data memory barrier - .word 0xE1600071 @ call SMI monitor (smi #1) + smc #1 @ call SMI monitor (smi #1) #ifdef CONFIG_OMAP3_L2_AUX_SECURE_SAVE_RESTORE /* Restore L2 aux control register */ @@ -434,27 +461,28 @@ skipl2dis: adds r3, r3, #8 @ r3 points to parameters mcr p15, 0, r0, c7, c10, 4 @ data write barrier mcr p15, 0, r0, c7, c10, 5 @ data memory barrier - .word 0xE1600071 @ call SMI monitor (smi #1) + smc #1 @ call SMI monitor (smi #1) #endif b logic_l1_restore + .align l2_inv_api_params: .word 0x1, 0x00 l2_inv_gp: /* Execute smi to invalidate L2 cache */ mov r12, #0x1 @ set up to invalidate L2 - .word 0xE1600070 @ Call SMI monitor (smieq) + smc #0 @ Call SMI monitor (smieq) /* Write to Aux control register to set some bits */ ldr r4, scratchpad_base ldr r3, [r4,#0xBC] ldr r0, [r3,#4] mov r12, #0x3 - .word 0xE1600070 @ Call SMI monitor (smieq) + smc #0 @ Call SMI monitor (smieq) ldr r4, scratchpad_base ldr r3, [r4,#0xBC] ldr r0, [r3,#12] mov r12, #0x2 - .word 0xE1600070 @ Call SMI monitor (smieq) + smc #0 @ Call SMI monitor (smieq) logic_l1_restore: ldr r1, l2dis_3630 cmp r1, #0x1 @ Test if L2 re-enable needed on 3630 @@ -607,6 +635,9 @@ usettbr0: /* This function implements the erratum ID i443 WA, applies to 34xx >= ES3.0 */ .text + .align 3 +.type _es3_sdrc_fix, %function +_es3_sdrc_fix: ENTRY(es3_sdrc_fix) ldr r4, sdrc_syscfg @ get config addr ldr r5, [r4] @ get value @@ -634,6 +665,7 @@ ENTRY(es3_sdrc_fix) str r5, [r4] @ kick off refreshes bx lr + .align sdrc_syscfg: .word SDRC_SYSCONFIG_P sdrc_mr_0: @@ -648,6 +680,8 @@ sdrc_emr2_1: .word SDRC_EMR2_1_P sdrc_manual_1: .word SDRC_MANUAL_1_P +ENDPROC(es3_sdrc_fix) +_es3_sdrc_fix_sz: ENTRY(es3_sdrc_fix_sz) .word . - es3_sdrc_fix @@ -682,6 +716,12 @@ wait_sdrc_ready: bic r5, r5, #0x40 str r5, [r4] +/* + * PC-relative stores lead to undefined behaviour in Thumb-2: use a r7 as a + * base instead. + * Be careful not to clobber r7 when maintaining this code. + */ + is_dll_in_lock_mode: /* Is dll in lock mode? */ ldr r4, sdrc_dlla_ctrl @@ -689,10 +729,11 @@ is_dll_in_lock_mode: tst r5, #0x4 bxne lr @ Return if locked /* wait till dll locks */ + adr r7, kick_counter wait_dll_lock_timed: ldr r4, wait_dll_lock_counter add r4, r4, #1 - str r4, wait_dll_lock_counter + str r4, [r7, #wait_dll_lock_counter - kick_counter] ldr r4, sdrc_dlla_status /* Wait 20uS for lock */ mov r6, #8 @@ -718,9 +759,10 @@ kick_dll: dsb ldr r4, kick_counter add r4, r4, #1 - str r4, kick_counter + str r4, [r7] @ kick_counter b wait_dll_lock_timed + .align cm_idlest1_core: .word CM_IDLEST1_CORE_V cm_idlest_ckgen: @@ -763,6 +805,7 @@ kick_counter: .word 0 wait_dll_lock_counter: .word 0 +ENDPROC(omap34xx_cpu_suspend) ENTRY(omap34xx_cpu_suspend_sz) .word . - omap34xx_cpu_suspend diff --git a/arch/arm/mach-omap2/sram242x.S b/arch/arm/mach-omap2/sram242x.S index 055310cc77d..ff9b9dbcb30 100644 --- a/arch/arm/mach-omap2/sram242x.S +++ b/arch/arm/mach-omap2/sram242x.S @@ -39,6 +39,7 @@ .text + .align 3 ENTRY(omap242x_sram_ddr_init) stmfd sp!, {r0 - r12, lr} @ save registers on stack @@ -143,6 +144,7 @@ ENTRY(omap242x_sram_ddr_init_sz) * r0 = [PRCM_FULL | PRCM_HALF] r1 = SDRC_DLLA_CTRL value r2 = [DDR | SDR] * PRCM_FULL = 2, PRCM_HALF = 1, DDR = 1, SDR = 0 */ + .align 3 ENTRY(omap242x_sram_reprogram_sdrc) stmfd sp!, {r0 - r10, lr} @ save registers on stack mov r3, #0x0 @ clear for mrc call @@ -238,6 +240,7 @@ ENTRY(omap242x_sram_reprogram_sdrc_sz) /* * Set dividers and pll. Also recalculate DLL value for DDR and unlock mode. */ + .align 3 ENTRY(omap242x_sram_set_prcm) stmfd sp!, {r0-r12, lr} @ regs to stack adr r4, pbegin @ addr of preload start diff --git a/arch/arm/mach-omap2/sram243x.S b/arch/arm/mach-omap2/sram243x.S index f9007580aea..76730209fa0 100644 --- a/arch/arm/mach-omap2/sram243x.S +++ b/arch/arm/mach-omap2/sram243x.S @@ -39,6 +39,7 @@ .text + .align 3 ENTRY(omap243x_sram_ddr_init) stmfd sp!, {r0 - r12, lr} @ save registers on stack @@ -143,6 +144,7 @@ ENTRY(omap243x_sram_ddr_init_sz) * r0 = [PRCM_FULL | PRCM_HALF] r1 = SDRC_DLLA_CTRL value r2 = [DDR | SDR] * PRCM_FULL = 2, PRCM_HALF = 1, DDR = 1, SDR = 0 */ + .align 3 ENTRY(omap243x_sram_reprogram_sdrc) stmfd sp!, {r0 - r10, lr} @ save registers on stack mov r3, #0x0 @ clear for mrc call @@ -238,6 +240,7 @@ ENTRY(omap243x_sram_reprogram_sdrc_sz) /* * Set dividers and pll. Also recalculate DLL value for DDR and unlock mode. */ + .align 3 ENTRY(omap243x_sram_set_prcm) stmfd sp!, {r0-r12, lr} @ regs to stack adr r4, pbegin @ addr of preload start diff --git a/arch/arm/mach-omap2/sram34xx.S b/arch/arm/mach-omap2/sram34xx.S index 7f893a29d50..13a8eba81d6 100644 --- a/arch/arm/mach-omap2/sram34xx.S +++ b/arch/arm/mach-omap2/sram34xx.S @@ -34,6 +34,12 @@ #include "sdrc.h" #include "cm2xxx_3xxx.h" +/* + * This file needs be built unconditionally as ARM to interoperate correctly + * with non-Thumb-2-capable firmware. + */ + .arm + .text /* r1 parameters */ @@ -111,29 +117,42 @@ * since it will cause the ARM MMU to attempt to walk the page tables. * These crashes may be intermittent. */ + .align 3 ENTRY(omap3_sram_configure_core_dpll) stmfd sp!, {r1-r12, lr} @ store regs to stack @ pull the extra args off the stack @ and store them in SRAM + +/* + * PC-relative stores are deprecated in ARMv7 and lead to undefined behaviour + * in Thumb-2: use a r7 as a base instead. + * Be careful not to clobber r7 when maintaing this file. + */ + THUMB( adr r7, omap3_sram_configure_core_dpll ) + .macro strtext Rt:req, label:req + ARM( str \Rt, \label ) + THUMB( str \Rt, [r7, \label - omap3_sram_configure_core_dpll] ) + .endm + ldr r4, [sp, #52] - str r4, omap_sdrc_rfr_ctrl_0_val + strtext r4, omap_sdrc_rfr_ctrl_0_val ldr r4, [sp, #56] - str r4, omap_sdrc_actim_ctrl_a_0_val + strtext r4, omap_sdrc_actim_ctrl_a_0_val ldr r4, [sp, #60] - str r4, omap_sdrc_actim_ctrl_b_0_val + strtext r4, omap_sdrc_actim_ctrl_b_0_val ldr r4, [sp, #64] - str r4, omap_sdrc_mr_0_val + strtext r4, omap_sdrc_mr_0_val ldr r4, [sp, #68] - str r4, omap_sdrc_rfr_ctrl_1_val + strtext r4, omap_sdrc_rfr_ctrl_1_val cmp r4, #0 @ if SDRC_RFR_CTRL_1 is 0, beq skip_cs1_params @ do not use cs1 params ldr r4, [sp, #72] - str r4, omap_sdrc_actim_ctrl_a_1_val + strtext r4, omap_sdrc_actim_ctrl_a_1_val ldr r4, [sp, #76] - str r4, omap_sdrc_actim_ctrl_b_1_val + strtext r4, omap_sdrc_actim_ctrl_b_1_val ldr r4, [sp, #80] - str r4, omap_sdrc_mr_1_val + strtext r4, omap_sdrc_mr_1_val skip_cs1_params: mrc p15, 0, r8, c1, c0, 0 @ read ctrl register bic r10, r8, #0x800 @ clear Z-bit, disable branch prediction @@ -271,6 +290,7 @@ skip_cs1_prog: ldr r12, [r11] @ posted-write barrier for SDRC bx lr + .align omap3_sdrc_power: .word OMAP34XX_SDRC_REGADDR(SDRC_POWER) omap3_cm_clksel1_pll: @@ -319,6 +339,7 @@ omap3_sdrc_dlla_ctrl: .word OMAP34XX_SDRC_REGADDR(SDRC_DLLA_CTRL) core_m2_mask_val: .word 0x07FFFFFF +ENDPROC(omap3_sram_configure_core_dpll) ENTRY(omap3_sram_configure_core_dpll_sz) .word . - omap3_sram_configure_core_dpll diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c index 12be525b8df..f5d591a5088 100644 --- a/arch/arm/mach-omap2/voltage.c +++ b/arch/arm/mach-omap2/voltage.c @@ -39,123 +39,6 @@ #define VP_TRANXDONE_TIMEOUT 300 #define VOLTAGE_DIR_SIZE 16 -/* Voltage processor register offsets */ -struct vp_reg_offs { - u8 vpconfig; - u8 vstepmin; - u8 vstepmax; - u8 vlimitto; - u8 vstatus; - u8 voltage; -}; - -/* Voltage Processor bit field values, shifts and masks */ -struct vp_reg_val { - /* PRM module */ - u16 prm_mod; - /* VPx_VPCONFIG */ - u32 vpconfig_erroroffset; - u16 vpconfig_errorgain; - u32 vpconfig_errorgain_mask; - u8 vpconfig_errorgain_shift; - u32 vpconfig_initvoltage_mask; - u8 vpconfig_initvoltage_shift; - u32 vpconfig_timeouten; - u32 vpconfig_initvdd; - u32 vpconfig_forceupdate; - u32 vpconfig_vpenable; - /* VPx_VSTEPMIN */ - u8 vstepmin_stepmin; - u16 vstepmin_smpswaittimemin; - u8 vstepmin_stepmin_shift; - u8 vstepmin_smpswaittimemin_shift; - /* VPx_VSTEPMAX */ - u8 vstepmax_stepmax; - u16 vstepmax_smpswaittimemax; - u8 vstepmax_stepmax_shift; - u8 vstepmax_smpswaittimemax_shift; - /* VPx_VLIMITTO */ - u8 vlimitto_vddmin; - u8 vlimitto_vddmax; - u16 vlimitto_timeout; - u8 vlimitto_vddmin_shift; - u8 vlimitto_vddmax_shift; - u8 vlimitto_timeout_shift; - /* PRM_IRQSTATUS*/ - u32 tranxdone_status; -}; - -/* Voltage controller registers and offsets */ -struct vc_reg_info { - /* PRM module */ - u16 prm_mod; - /* VC register offsets */ - u8 smps_sa_reg; - u8 smps_volra_reg; - u8 bypass_val_reg; - u8 cmdval_reg; - u8 voltsetup_reg; - /*VC_SMPS_SA*/ - u8 smps_sa_shift; - u32 smps_sa_mask; - /* VC_SMPS_VOL_RA */ - u8 smps_volra_shift; - u32 smps_volra_mask; - /* VC_BYPASS_VAL */ - u8 data_shift; - u8 slaveaddr_shift; - u8 regaddr_shift; - u32 valid; - /* VC_CMD_VAL */ - u8 cmd_on_shift; - u8 cmd_onlp_shift; - u8 cmd_ret_shift; - u8 cmd_off_shift; - u32 cmd_on_mask; - /* PRM_VOLTSETUP */ - u8 voltsetup_shift; - u32 voltsetup_mask; -}; - -/** - * omap_vdd_info - Per Voltage Domain info - * - * @volt_data : voltage table having the distinct voltages supported - * by the domain and other associated per voltage data. - * @pmic_info : pmic specific parameters which should be populted by - * the pmic drivers. - * @vp_offs : structure containing the offsets for various - * vp registers - * @vp_reg : the register values, shifts, masks for various - * vp registers - * @vc_reg : structure containing various various vc registers, - * shifts, masks etc. - * @voltdm : pointer to the voltage domain structure - * @debug_dir : debug directory for this voltage domain. - * @curr_volt : current voltage for this vdd. - * @ocp_mod : The prm module for accessing the prm irqstatus reg. - * @prm_irqst_reg : prm irqstatus register. - * @vp_enabled : flag to keep track of whether vp is enabled or not - * @volt_scale : API to scale the voltage of the vdd. - */ -struct omap_vdd_info { - struct omap_volt_data *volt_data; - struct omap_volt_pmic_info *pmic_info; - struct vp_reg_offs vp_offs; - struct vp_reg_val vp_reg; - struct vc_reg_info vc_reg; - struct voltagedomain voltdm; - struct dentry *debug_dir; - u32 curr_volt; - u16 ocp_mod; - u8 prm_irqst_reg; - bool vp_enabled; - u32 (*read_reg) (u16 mod, u8 offset); - void (*write_reg) (u32 val, u16 mod, u8 offset); - int (*volt_scale) (struct omap_vdd_info *vdd, - unsigned long target_volt); -}; - static struct omap_vdd_info *vdd_info; /* * Number of scalable voltage domains. @@ -308,6 +191,39 @@ static struct omap_volt_data omap44xx_vdd_core_volt_data[] = { VOLT_DATA_DEFINE(0, 0, 0, 0), }; +/* OMAP 3430 MPU Core VDD dependency table */ +static struct omap_vdd_dep_volt omap34xx_vdd1_vdd2_data[] = { + {.main_vdd_volt = OMAP3430_VDD_MPU_OPP1_UV, .dep_vdd_volt = OMAP3430_VDD_CORE_OPP2_UV}, + {.main_vdd_volt = OMAP3430_VDD_MPU_OPP2_UV, .dep_vdd_volt = OMAP3430_VDD_CORE_OPP2_UV}, + {.main_vdd_volt = OMAP3430_VDD_MPU_OPP3_UV, .dep_vdd_volt = OMAP3430_VDD_CORE_OPP3_UV}, + {.main_vdd_volt = OMAP3430_VDD_MPU_OPP4_UV, .dep_vdd_volt = OMAP3430_VDD_CORE_OPP3_UV}, + {.main_vdd_volt = OMAP3430_VDD_MPU_OPP5_UV, .dep_vdd_volt = OMAP3430_VDD_CORE_OPP3_UV}, + {.main_vdd_volt = 0, .dep_vdd_volt = 0}, +}; + +static struct omap_vdd_dep_info omap34xx_vdd1_dep_info[] = { + { + .name = "core", + .dep_table = omap34xx_vdd1_vdd2_data, + }, +}; + +/* OMAP 3630 MPU Core VDD dependency table */ +static struct omap_vdd_dep_volt omap36xx_vdd1_vdd2_data[] = { + {.main_vdd_volt = OMAP3630_VDD_MPU_OPP50_UV, .dep_vdd_volt = OMAP3630_VDD_CORE_OPP50_UV}, + {.main_vdd_volt = OMAP3630_VDD_MPU_OPP100_UV, .dep_vdd_volt = OMAP3630_VDD_CORE_OPP100_UV}, + {.main_vdd_volt = OMAP3630_VDD_MPU_OPP120_UV, .dep_vdd_volt = OMAP3630_VDD_CORE_OPP100_UV}, + {.main_vdd_volt = OMAP3630_VDD_MPU_OPP1G_UV, .dep_vdd_volt = OMAP3630_VDD_CORE_OPP100_UV}, + {.main_vdd_volt = 0, .dep_vdd_volt = 0}, +}; + +static struct omap_vdd_dep_info omap36xx_vdd1_dep_info[] = { + { + .name = "core", + .dep_table = omap36xx_vdd1_vdd2_data, + }, +}; + static struct dentry *voltage_dir; /* Init function pointers */ @@ -814,10 +730,15 @@ static int __init omap3_vdd_data_configure(struct omap_vdd_info *vdd) } if (!strcmp(vdd->voltdm.name, "mpu")) { - if (cpu_is_omap3630()) + if (cpu_is_omap3630()) { vdd->volt_data = omap36xx_vddmpu_volt_data; - else + vdd->dep_vdd_info = omap36xx_vdd1_dep_info; + vdd->nr_dep_vdd = ARRAY_SIZE(omap36xx_vdd1_dep_info); + } else { vdd->volt_data = omap34xx_vddmpu_volt_data; + vdd->dep_vdd_info = omap34xx_vdd1_dep_info; + vdd->nr_dep_vdd = ARRAY_SIZE(omap34xx_vdd1_dep_info); + } vdd->vp_reg.tranxdone_status = OMAP3430_VP1_TRANXDONE_ST_MASK; vdd->vc_reg.cmdval_reg = OMAP3_PRM_VC_CMD_VAL_0_OFFSET; diff --git a/arch/arm/mach-orion5x/include/mach/memory.h b/arch/arm/mach-orion5x/include/mach/memory.h index 52a2955d0f8..6769917882f 100644 --- a/arch/arm/mach-orion5x/include/mach/memory.h +++ b/arch/arm/mach-orion5x/include/mach/memory.h @@ -7,6 +7,6 @@ #ifndef __ASM_ARCH_MEMORY_H #define __ASM_ARCH_MEMORY_H -#define PHYS_OFFSET UL(0x00000000) +#define PLAT_PHYS_OFFSET UL(0x00000000) #endif diff --git a/arch/arm/mach-pnx4008/include/mach/memory.h b/arch/arm/mach-pnx4008/include/mach/memory.h index 0e877008105..1275db61cee 100644 --- a/arch/arm/mach-pnx4008/include/mach/memory.h +++ b/arch/arm/mach-pnx4008/include/mach/memory.h @@ -16,6 +16,6 @@ /* * Physical DRAM offset. */ -#define PHYS_OFFSET UL(0x80000000) +#define PLAT_PHYS_OFFSET UL(0x80000000) #endif diff --git a/arch/arm/mach-pxa/balloon3.c b/arch/arm/mach-pxa/balloon3.c index a134a1413e0..e194d928cda 100644 --- a/arch/arm/mach-pxa/balloon3.c +++ b/arch/arm/mach-pxa/balloon3.c @@ -829,5 +829,5 @@ MACHINE_START(BALLOON3, "Balloon3") .init_irq = balloon3_init_irq, .timer = &pxa_timer, .init_machine = balloon3_init, - .boot_params = PHYS_OFFSET + 0x100, + .boot_params = PLAT_PHYS_OFFSET + 0x100, MACHINE_END diff --git a/arch/arm/mach-pxa/include/mach/memory.h b/arch/arm/mach-pxa/include/mach/memory.h index 92361a66b22..7f68724dcc2 100644 --- a/arch/arm/mach-pxa/include/mach/memory.h +++ b/arch/arm/mach-pxa/include/mach/memory.h @@ -15,7 +15,7 @@ /* * Physical DRAM offset. */ -#define PHYS_OFFSET UL(0xa0000000) +#define PLAT_PHYS_OFFSET UL(0xa0000000) #if !defined(__ASSEMBLY__) && defined(CONFIG_MACH_ARMCORE) && defined(CONFIG_PCI) void cmx2xx_pci_adjust_zones(unsigned long *size, unsigned long *holes); diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c index fbc5b775f89..b166b1d845d 100644 --- a/arch/arm/mach-pxa/pxa25x.c +++ b/arch/arm/mach-pxa/pxa25x.c @@ -347,6 +347,7 @@ static struct platform_device *pxa25x_devices[] __initdata = { &pxa25x_device_assp, &pxa25x_device_pwm0, &pxa25x_device_pwm1, + &pxa_device_asoc_platform, }; static struct sys_device pxa25x_sysdev[] = { diff --git a/arch/arm/mach-pxa/tosa-bt.c b/arch/arm/mach-pxa/tosa-bt.c index c31e601eb49..b9b1e5c2b29 100644 --- a/arch/arm/mach-pxa/tosa-bt.c +++ b/arch/arm/mach-pxa/tosa-bt.c @@ -81,8 +81,6 @@ static int tosa_bt_probe(struct platform_device *dev) goto err_rfk_alloc; } - rfkill_set_led_trigger_name(rfk, "tosa-bt"); - rc = rfkill_register(rfk); if (rc) goto err_rfkill; diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c index af152e70cfc..f2582ec300d 100644 --- a/arch/arm/mach-pxa/tosa.c +++ b/arch/arm/mach-pxa/tosa.c @@ -875,6 +875,11 @@ static struct platform_device sharpsl_rom_device = { .dev.platform_data = &sharpsl_rom_data, }; +static struct platform_device wm9712_device = { + .name = "wm9712-codec", + .id = -1, +}; + static struct platform_device *devices[] __initdata = { &tosascoop_device, &tosascoop_jc_device, @@ -885,6 +890,7 @@ static struct platform_device *devices[] __initdata = { &tosaled_device, &tosa_bt_device, &sharpsl_rom_device, + &wm9712_device, }; static void tosa_poweroff(void) diff --git a/arch/arm/mach-realview/Kconfig b/arch/arm/mach-realview/Kconfig index 7ca138a943a..b9a9805e482 100644 --- a/arch/arm/mach-realview/Kconfig +++ b/arch/arm/mach-realview/Kconfig @@ -19,7 +19,7 @@ config REALVIEW_EB_A9MP config REALVIEW_EB_ARM11MP bool "Support ARM11MPCore Tile" depends on MACH_REALVIEW_EB - select CPU_V6 + select CPU_V6K select ARCH_HAS_BARRIERS if SMP help Enable support for the ARM11MPCore tile fitted to the Realview(R) @@ -36,7 +36,7 @@ config REALVIEW_EB_ARM11MP_REVB config MACH_REALVIEW_PB11MP bool "Support RealView(R) Platform Baseboard for ARM11MPCore" - select CPU_V6 + select CPU_V6K select ARM_GIC select HAVE_PATA_PLATFORM select ARCH_HAS_BARRIERS if SMP @@ -45,6 +45,7 @@ config MACH_REALVIEW_PB11MP the ARM11MPCore. This platform has an on-board ARM11MPCore and has support for PCI-E and Compact Flash. +# ARMv6 CPU without K extensions, but does have the new exclusive ops config MACH_REALVIEW_PB1176 bool "Support RealView(R) Platform Baseboard for ARM1176JZF-S" select CPU_V6 diff --git a/arch/arm/mach-realview/include/mach/memory.h b/arch/arm/mach-realview/include/mach/memory.h index 5dafc157b27..e05fc2c4c08 100644 --- a/arch/arm/mach-realview/include/mach/memory.h +++ b/arch/arm/mach-realview/include/mach/memory.h @@ -24,9 +24,9 @@ * Physical DRAM offset. */ #ifdef CONFIG_REALVIEW_HIGH_PHYS_OFFSET -#define PHYS_OFFSET UL(0x70000000) +#define PLAT_PHYS_OFFSET UL(0x70000000) #else -#define PHYS_OFFSET UL(0x00000000) +#define PLAT_PHYS_OFFSET UL(0x00000000) #endif #if !defined(__ASSEMBLY__) && defined(CONFIG_ZONE_DMA) diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c index 6ef5c5e528b..8ede983b861 100644 --- a/arch/arm/mach-realview/realview_eb.c +++ b/arch/arm/mach-realview/realview_eb.c @@ -484,7 +484,7 @@ static void __init realview_eb_init(void) MACHINE_START(REALVIEW_EB, "ARM-RealView EB") /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ - .boot_params = PHYS_OFFSET + 0x00000100, + .boot_params = PLAT_PHYS_OFFSET + 0x00000100, .fixup = realview_fixup, .map_io = realview_eb_map_io, .init_irq = gic_init_irq, diff --git a/arch/arm/mach-realview/realview_pb1176.c b/arch/arm/mach-realview/realview_pb1176.c index cbdc97a5685..9f26369555c 100644 --- a/arch/arm/mach-realview/realview_pb1176.c +++ b/arch/arm/mach-realview/realview_pb1176.c @@ -379,7 +379,7 @@ static void __init realview_pb1176_init(void) MACHINE_START(REALVIEW_PB1176, "ARM-RealView PB1176") /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ - .boot_params = PHYS_OFFSET + 0x00000100, + .boot_params = PLAT_PHYS_OFFSET + 0x00000100, .fixup = realview_pb1176_fixup, .map_io = realview_pb1176_map_io, .init_irq = gic_init_irq, diff --git a/arch/arm/mach-realview/realview_pb11mp.c b/arch/arm/mach-realview/realview_pb11mp.c index 8e8ab7d29a6..dea06b2da3a 100644 --- a/arch/arm/mach-realview/realview_pb11mp.c +++ b/arch/arm/mach-realview/realview_pb11mp.c @@ -381,7 +381,7 @@ static void __init realview_pb11mp_init(void) MACHINE_START(REALVIEW_PB11MP, "ARM-RealView PB11MPCore") /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ - .boot_params = PHYS_OFFSET + 0x00000100, + .boot_params = PLAT_PHYS_OFFSET + 0x00000100, .fixup = realview_fixup, .map_io = realview_pb11mp_map_io, .init_irq = gic_init_irq, diff --git a/arch/arm/mach-realview/realview_pba8.c b/arch/arm/mach-realview/realview_pba8.c index 841118e3e11..7d0f1734a21 100644 --- a/arch/arm/mach-realview/realview_pba8.c +++ b/arch/arm/mach-realview/realview_pba8.c @@ -331,7 +331,7 @@ static void __init realview_pba8_init(void) MACHINE_START(REALVIEW_PBA8, "ARM-RealView PB-A8") /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ - .boot_params = PHYS_OFFSET + 0x00000100, + .boot_params = PLAT_PHYS_OFFSET + 0x00000100, .fixup = realview_fixup, .map_io = realview_pba8_map_io, .init_irq = gic_init_irq, diff --git a/arch/arm/mach-realview/realview_pbx.c b/arch/arm/mach-realview/realview_pbx.c index 02b755b009d..b89e28f8853 100644 --- a/arch/arm/mach-realview/realview_pbx.c +++ b/arch/arm/mach-realview/realview_pbx.c @@ -414,7 +414,7 @@ static void __init realview_pbx_init(void) MACHINE_START(REALVIEW_PBX, "ARM-RealView PBX") /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ - .boot_params = PHYS_OFFSET + 0x00000100, + .boot_params = PLAT_PHYS_OFFSET + 0x00000100, .fixup = realview_pbx_fixup, .map_io = realview_pbx_map_io, .init_irq = gic_init_irq, diff --git a/arch/arm/mach-rpc/include/mach/memory.h b/arch/arm/mach-rpc/include/mach/memory.h index 78191bf2519..18a221093bf 100644 --- a/arch/arm/mach-rpc/include/mach/memory.h +++ b/arch/arm/mach-rpc/include/mach/memory.h @@ -21,7 +21,7 @@ /* * Physical DRAM offset. */ -#define PHYS_OFFSET UL(0x10000000) +#define PLAT_PHYS_OFFSET UL(0x10000000) /* * Cache flushing area - ROM diff --git a/arch/arm/mach-s3c2400/include/mach/memory.h b/arch/arm/mach-s3c2400/include/mach/memory.h index cf5901ffd38..3f33670dd01 100644 --- a/arch/arm/mach-s3c2400/include/mach/memory.h +++ b/arch/arm/mach-s3c2400/include/mach/memory.h @@ -15,6 +15,6 @@ #ifndef __ASM_ARCH_MEMORY_H #define __ASM_ARCH_MEMORY_H -#define PHYS_OFFSET UL(0x0C000000) +#define PLAT_PHYS_OFFSET UL(0x0C000000) #endif diff --git a/arch/arm/mach-s3c2410/include/mach/memory.h b/arch/arm/mach-s3c2410/include/mach/memory.h index 6f1e5871ae4..f92b97b89c0 100644 --- a/arch/arm/mach-s3c2410/include/mach/memory.h +++ b/arch/arm/mach-s3c2410/include/mach/memory.h @@ -11,6 +11,6 @@ #ifndef __ASM_ARCH_MEMORY_H #define __ASM_ARCH_MEMORY_H -#define PHYS_OFFSET UL(0x30000000) +#define PLAT_PHYS_OFFSET UL(0x30000000) #endif diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c index 2970ea9f7c2..18187a48a55 100644 --- a/arch/arm/mach-s3c2410/mach-bast.c +++ b/arch/arm/mach-s3c2410/mach-bast.c @@ -213,7 +213,7 @@ static struct s3c2410_uartcfg bast_uartcfgs[] __initdata = { /* NAND Flash on BAST board */ -#ifdef CONFIG_PM +#ifdef CONFIG_SUSPEND static int bast_pm_suspend(struct sys_device *sd, pm_message_t state) { /* ensure that an nRESET is not generated on resume. */ diff --git a/arch/arm/mach-s3c2412/mach-jive.c b/arch/arm/mach-s3c2412/mach-jive.c index 923e01bdf01..10643ef84eb 100644 --- a/arch/arm/mach-s3c2412/mach-jive.c +++ b/arch/arm/mach-s3c2412/mach-jive.c @@ -485,7 +485,7 @@ static struct s3c2410_udc_mach_info jive_udc_cfg __initdata = { /* Jive power management device */ -#ifdef CONFIG_PM +#ifdef CONFIG_SUSPEND static int jive_pm_suspend(struct sys_device *sd, pm_message_t state) { /* Write the magic value u-boot uses to check for resume into diff --git a/arch/arm/mach-s3c2440/mach-osiris.c b/arch/arm/mach-s3c2440/mach-osiris.c index 14dc6789775..06d115aae7d 100644 --- a/arch/arm/mach-s3c2440/mach-osiris.c +++ b/arch/arm/mach-s3c2440/mach-osiris.c @@ -281,7 +281,7 @@ static struct platform_device osiris_pcmcia = { /* Osiris power management device */ -#ifdef CONFIG_PM +#ifdef CONFIG_SUSPEND static unsigned char pm_osiris_ctrl0; static int osiris_pm_suspend(struct sys_device *sd, pm_message_t state) diff --git a/arch/arm/mach-s3c2440/s3c244x.c b/arch/arm/mach-s3c2440/s3c244x.c index 90c1707b9c9..7e693a082f4 100644 --- a/arch/arm/mach-s3c2440/s3c244x.c +++ b/arch/arm/mach-s3c2440/s3c244x.c @@ -134,7 +134,7 @@ void __init s3c244x_init_clocks(int xtal) s3c2410_baseclk_add(); } -#ifdef CONFIG_PM +#ifdef CONFIG_SUSPEND static struct sleep_save s3c244x_sleep[] = { SAVE_ITEM(S3C2440_DSC0), diff --git a/arch/arm/mach-s3c24a0/include/mach/memory.h b/arch/arm/mach-s3c24a0/include/mach/memory.h index 7d74fd5c8d6..7d208a71b17 100644 --- a/arch/arm/mach-s3c24a0/include/mach/memory.h +++ b/arch/arm/mach-s3c24a0/include/mach/memory.h @@ -11,7 +11,7 @@ #ifndef __ASM_ARCH_24A0_MEMORY_H #define __ASM_ARCH_24A0_MEMORY_H __FILE__ -#define PHYS_OFFSET UL(0x10000000) +#define PLAT_PHYS_OFFSET UL(0x10000000) #define __virt_to_bus(x) __virt_to_phys(x) #define __bus_to_virt(x) __phys_to_virt(x) diff --git a/arch/arm/mach-s3c64xx/Makefile b/arch/arm/mach-s3c64xx/Makefile index 4657363f067..183ebb395ed 100644 --- a/arch/arm/mach-s3c64xx/Makefile +++ b/arch/arm/mach-s3c64xx/Makefile @@ -43,9 +43,9 @@ obj-$(CONFIG_S3C64XX_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o # PM -obj-$(CONFIG_PM) += pm.o -obj-$(CONFIG_PM) += sleep.o -obj-$(CONFIG_PM) += irq-pm.o +obj-$(CONFIG_SUSPEND) += pm.o +obj-$(CONFIG_SUSPEND) += sleep.o +obj-$(CONFIG_SUSPEND) += irq-pm.o # Machine support diff --git a/arch/arm/mach-s3c64xx/include/mach/memory.h b/arch/arm/mach-s3c64xx/include/mach/memory.h index 42cc54e2ee3..4760cdae1eb 100644 --- a/arch/arm/mach-s3c64xx/include/mach/memory.h +++ b/arch/arm/mach-s3c64xx/include/mach/memory.h @@ -13,7 +13,7 @@ #ifndef __ASM_ARCH_MEMORY_H #define __ASM_ARCH_MEMORY_H -#define PHYS_OFFSET UL(0x50000000) +#define PLAT_PHYS_OFFSET UL(0x50000000) #define CONSISTENT_DMA_SIZE SZ_8M diff --git a/arch/arm/mach-s5p6442/include/mach/memory.h b/arch/arm/mach-s5p6442/include/mach/memory.h index 9ddd877ba2e..cfe259dded3 100644 --- a/arch/arm/mach-s5p6442/include/mach/memory.h +++ b/arch/arm/mach-s5p6442/include/mach/memory.h @@ -13,7 +13,7 @@ #ifndef __ASM_ARCH_MEMORY_H #define __ASM_ARCH_MEMORY_H -#define PHYS_OFFSET UL(0x20000000) +#define PLAT_PHYS_OFFSET UL(0x20000000) #define CONSISTENT_DMA_SIZE SZ_8M #endif /* __ASM_ARCH_MEMORY_H */ diff --git a/arch/arm/mach-s5p64x0/include/mach/memory.h b/arch/arm/mach-s5p64x0/include/mach/memory.h index 1b036b0a24c..365a6eb4b88 100644 --- a/arch/arm/mach-s5p64x0/include/mach/memory.h +++ b/arch/arm/mach-s5p64x0/include/mach/memory.h @@ -13,7 +13,7 @@ #ifndef __ASM_ARCH_MEMORY_H #define __ASM_ARCH_MEMORY_H __FILE__ -#define PHYS_OFFSET UL(0x20000000) +#define PLAT_PHYS_OFFSET UL(0x20000000) #define CONSISTENT_DMA_SIZE SZ_8M #endif /* __ASM_ARCH_MEMORY_H */ diff --git a/arch/arm/mach-s5pc100/include/mach/memory.h b/arch/arm/mach-s5pc100/include/mach/memory.h index 4b60d18179f..bda4e79fd5f 100644 --- a/arch/arm/mach-s5pc100/include/mach/memory.h +++ b/arch/arm/mach-s5pc100/include/mach/memory.h @@ -13,6 +13,6 @@ #ifndef __ASM_ARCH_MEMORY_H #define __ASM_ARCH_MEMORY_H -#define PHYS_OFFSET UL(0x20000000) +#define PLAT_PHYS_OFFSET UL(0x20000000) #endif diff --git a/arch/arm/mach-s5pv210/cpufreq.c b/arch/arm/mach-s5pv210/cpufreq.c index a6f22920a2c..7e697cdf698 100644 --- a/arch/arm/mach-s5pv210/cpufreq.c +++ b/arch/arm/mach-s5pv210/cpufreq.c @@ -389,7 +389,7 @@ static int s5pv210_target(struct cpufreq_policy *policy, return 0; } -#ifdef CONFIG_PM +#ifdef CONFIG_SUSPEND static int s5pv210_cpufreq_suspend(struct cpufreq_policy *policy, pm_message_t pmsg) { @@ -470,7 +470,7 @@ static struct cpufreq_driver s5pv210_driver = { .get = s5pv210_getspeed, .init = s5pv210_cpu_init, .name = "s5pv210", -#ifdef CONFIG_PM +#ifdef CONFIG_SUSPEND .suspend = s5pv210_cpufreq_suspend, .resume = s5pv210_cpufreq_resume, #endif diff --git a/arch/arm/mach-s5pv210/include/mach/memory.h b/arch/arm/mach-s5pv210/include/mach/memory.h index d503e0c4ce4..7b5fcf0da0c 100644 --- a/arch/arm/mach-s5pv210/include/mach/memory.h +++ b/arch/arm/mach-s5pv210/include/mach/memory.h @@ -13,7 +13,7 @@ #ifndef __ASM_ARCH_MEMORY_H #define __ASM_ARCH_MEMORY_H -#define PHYS_OFFSET UL(0x20000000) +#define PLAT_PHYS_OFFSET UL(0x20000000) #define CONSISTENT_DMA_SIZE (SZ_8M + SZ_4M + SZ_2M) /* diff --git a/arch/arm/mach-s5pv210/sleep.S b/arch/arm/mach-s5pv210/sleep.S index d4d222b716b..27376223ea9 100644 --- a/arch/arm/mach-s5pv210/sleep.S +++ b/arch/arm/mach-s5pv210/sleep.S @@ -65,7 +65,7 @@ resume_with_mmu: /* * After MMU is turned on, restore the previous MMU table. */ - ldr r9 , =(PAGE_OFFSET - PHYS_OFFSET) + ldr r9 , =(PAGE_OFFSET - PLAT_PHYS_OFFSET) add r4, r4, r9 str r12, [r4] diff --git a/arch/arm/mach-s5pv310/cpufreq.c b/arch/arm/mach-s5pv310/cpufreq.c index b04cbc73112..8493b6d05fb 100644 --- a/arch/arm/mach-s5pv310/cpufreq.c +++ b/arch/arm/mach-s5pv310/cpufreq.c @@ -457,7 +457,7 @@ static int s5pv310_target(struct cpufreq_policy *policy, return 0; } -#ifdef CONFIG_PM +#ifdef CONFIG_SUSPEND static int s5pv310_cpufreq_suspend(struct cpufreq_policy *policy, pm_message_t pmsg) { @@ -497,7 +497,7 @@ static struct cpufreq_driver s5pv310_driver = { .get = s5pv310_getspeed, .init = s5pv310_cpufreq_cpu_init, .name = "s5pv310_cpufreq", -#ifdef CONFIG_PM +#ifdef CONFIG_SUSPEND .suspend = s5pv310_cpufreq_suspend, .resume = s5pv310_cpufreq_resume, #endif diff --git a/arch/arm/mach-s5pv310/include/mach/memory.h b/arch/arm/mach-s5pv310/include/mach/memory.h index 1dffb482324..470b01bf861 100644 --- a/arch/arm/mach-s5pv310/include/mach/memory.h +++ b/arch/arm/mach-s5pv310/include/mach/memory.h @@ -13,7 +13,7 @@ #ifndef __ASM_ARCH_MEMORY_H #define __ASM_ARCH_MEMORY_H __FILE__ -#define PHYS_OFFSET UL(0x40000000) +#define PLAT_PHYS_OFFSET UL(0x40000000) /* Maximum of 256MiB in one bank */ #define MAX_PHYSMEM_BITS 32 diff --git a/arch/arm/mach-s5pv310/irq-eint.c b/arch/arm/mach-s5pv310/irq-eint.c index 477bd9e97f0..39c7f7b2d7b 100644 --- a/arch/arm/mach-s5pv310/irq-eint.c +++ b/arch/arm/mach-s5pv310/irq-eint.c @@ -152,7 +152,7 @@ static struct irq_chip s5pv310_irq_eint = { .irq_mask_ack = s5pv310_irq_eint_maskack, .irq_ack = s5pv310_irq_eint_ack, .irq_set_type = s5pv310_irq_eint_set_type, -#ifdef CONFIG_PM +#ifdef CONFIG_SUSPEND .irq_set_wake = s3c_irqext_wake, #endif }; diff --git a/arch/arm/mach-sa1100/include/mach/memory.h b/arch/arm/mach-sa1100/include/mach/memory.h index 128a1dfa96b..a44da6a2916 100644 --- a/arch/arm/mach-sa1100/include/mach/memory.h +++ b/arch/arm/mach-sa1100/include/mach/memory.h @@ -12,7 +12,7 @@ /* * Physical DRAM offset is 0xc0000000 on the SA1100 */ -#define PHYS_OFFSET UL(0xc0000000) +#define PLAT_PHYS_OFFSET UL(0xc0000000) #ifndef __ASSEMBLY__ diff --git a/arch/arm/mach-shark/include/mach/memory.h b/arch/arm/mach-shark/include/mach/memory.h index d9c4812f1c3..9afb1700000 100644 --- a/arch/arm/mach-shark/include/mach/memory.h +++ b/arch/arm/mach-shark/include/mach/memory.h @@ -15,7 +15,7 @@ /* * Physical DRAM offset. */ -#define PHYS_OFFSET UL(0x08000000) +#define PLAT_PHYS_OFFSET UL(0x08000000) #ifndef __ASSEMBLY__ diff --git a/arch/arm/mach-shmobile/include/mach/memory.h b/arch/arm/mach-shmobile/include/mach/memory.h index 377584e57e0..ad00c3c258f 100644 --- a/arch/arm/mach-shmobile/include/mach/memory.h +++ b/arch/arm/mach-shmobile/include/mach/memory.h @@ -1,7 +1,7 @@ #ifndef __ASM_MACH_MEMORY_H #define __ASM_MACH_MEMORY_H -#define PHYS_OFFSET UL(CONFIG_MEMORY_START) +#define PLAT_PHYS_OFFSET UL(CONFIG_MEMORY_START) #define MEM_SIZE UL(CONFIG_MEMORY_SIZE) /* DMA memory at 0xf6000000 - 0xffdfffff */ diff --git a/arch/arm/mach-tcc8k/board-tcc8000-sdk.c b/arch/arm/mach-tcc8k/board-tcc8000-sdk.c index 7991415e666..fb6426ddeb7 100644 --- a/arch/arm/mach-tcc8k/board-tcc8000-sdk.c +++ b/arch/arm/mach-tcc8k/board-tcc8000-sdk.c @@ -54,7 +54,7 @@ static void __init tcc8k_map_io(void) } MACHINE_START(TCC8000_SDK, "Telechips TCC8000-SDK Demo Board") - .boot_params = PHYS_OFFSET + 0x00000100, + .boot_params = PLAT_PHYS_OFFSET + 0x00000100, .map_io = tcc8k_map_io, .init_irq = tcc8k_init_irq, .init_machine = tcc8k_init, diff --git a/arch/arm/mach-tegra/board-harmony.c b/arch/arm/mach-tegra/board-harmony.c index b9dbdb1289d..99884e9dd69 100644 --- a/arch/arm/mach-tegra/board-harmony.c +++ b/arch/arm/mach-tegra/board-harmony.c @@ -113,6 +113,11 @@ static void __init tegra_harmony_init(void) platform_add_devices(harmony_devices, ARRAY_SIZE(harmony_devices)); } +static const char * tegra_harmony_board_compat[] = { + "nvidia,harmony", + NULL +}; + MACHINE_START(HARMONY, "harmony") .boot_params = 0x00000100, .fixup = tegra_harmony_fixup, @@ -120,4 +125,5 @@ MACHINE_START(HARMONY, "harmony") .init_machine = tegra_harmony_init, .map_io = tegra_map_common_io, .timer = &tegra_timer, + .dt_compat = tegra_harmony_board_compat, MACHINE_END diff --git a/arch/arm/mach-tegra/include/mach/memory.h b/arch/arm/mach-tegra/include/mach/memory.h index 6151bab62af..537db3aa81a 100644 --- a/arch/arm/mach-tegra/include/mach/memory.h +++ b/arch/arm/mach-tegra/include/mach/memory.h @@ -22,7 +22,7 @@ #define __MACH_TEGRA_MEMORY_H /* physical offset of RAM */ -#define PHYS_OFFSET UL(0) +#define PLAT_PHYS_OFFSET UL(0) #endif diff --git a/arch/arm/mach-u300/include/mach/memory.h b/arch/arm/mach-u300/include/mach/memory.h index bf134bcc129..888e2e351ee 100644 --- a/arch/arm/mach-u300/include/mach/memory.h +++ b/arch/arm/mach-u300/include/mach/memory.h @@ -15,17 +15,17 @@ #ifdef CONFIG_MACH_U300_DUAL_RAM -#define PHYS_OFFSET UL(0x48000000) +#define PLAT_PHYS_OFFSET UL(0x48000000) #define BOOT_PARAMS_OFFSET (PHYS_OFFSET + 0x100) #else #ifdef CONFIG_MACH_U300_2MB_ALIGNMENT_FIX -#define PHYS_OFFSET (0x28000000 + \ +#define PLAT_PHYS_OFFSET (0x28000000 + \ (CONFIG_MACH_U300_ACCESS_MEM_SIZE - \ (CONFIG_MACH_U300_ACCESS_MEM_SIZE & 1))*1024*1024) #else -#define PHYS_OFFSET (0x28000000 + \ +#define PLAT_PHYS_OFFSET (0x28000000 + \ (CONFIG_MACH_U300_ACCESS_MEM_SIZE + \ (CONFIG_MACH_U300_ACCESS_MEM_SIZE & 1))*1024*1024) #endif diff --git a/arch/arm/mach-u300/u300.c b/arch/arm/mach-u300/u300.c index 07c35a84642..48b3b7f3996 100644 --- a/arch/arm/mach-u300/u300.c +++ b/arch/arm/mach-u300/u300.c @@ -19,9 +19,9 @@ #include <linux/io.h> #include <mach/hardware.h> #include <mach/platform.h> -#include <mach/memory.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> +#include <asm/memory.h> static void __init u300_reserve(void) { diff --git a/arch/arm/mach-ux500/board-mop500-sdi.c b/arch/arm/mach-ux500/board-mop500-sdi.c index 4b996676594..4ba3d930a06 100644 --- a/arch/arm/mach-ux500/board-mop500-sdi.c +++ b/arch/arm/mach-ux500/board-mop500-sdi.c @@ -106,8 +106,8 @@ void mop500_sdi_tc35892_init(void) if (ret) return; - gpio_direction_output(GPIO_SDMMC_1V8_3V_SEL, 1); - gpio_direction_output(GPIO_SDMMC_EN, 0); + gpio_direction_output(GPIO_SDMMC_1V8_3V_SEL, 0); + gpio_direction_output(GPIO_SDMMC_EN, 1); db8500_add_sdi0(&mop500_sdi0_data); } diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index a393f57ed2a..9119565f159 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c @@ -224,3 +224,13 @@ MACHINE_START(U8500, "ST-Ericsson MOP500 platform") .timer = &ux500_timer, .init_machine = u8500_init_machine, MACHINE_END + +MACHINE_START(NOMADIK, "ST-Ericsson MOP500 platform") + /* Maintainer: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com> */ + .boot_params = 0x100, + .map_io = u8500_map_io, + .init_irq = ux500_init_irq, + /* we re-use nomadik timer here */ + .timer = &ux500_timer, + .init_machine = u8500_init_machine, +MACHINE_END diff --git a/arch/arm/mach-ux500/clock.c b/arch/arm/mach-ux500/clock.c index b2b0a3b9be8..9a0a6ed9cd5 100644 --- a/arch/arm/mach-ux500/clock.c +++ b/arch/arm/mach-ux500/clock.c @@ -313,7 +313,7 @@ static DEFINE_PRCMU_CLK_RATE(uartclk, 0x0, 5, UARTCLK, 38400000); static DEFINE_PRCMU_CLK(msp02clk, 0x0, 6, MSP02CLK); static DEFINE_PRCMU_CLK(msp1clk, 0x0, 7, MSP1CLK); /* v1 */ static DEFINE_PRCMU_CLK_RATE(i2cclk, 0x0, 8, I2CCLK, 48000000); -static DEFINE_PRCMU_CLK_RATE(sdmmcclk, 0x0, 9, SDMMCCLK, 50000000); +static DEFINE_PRCMU_CLK_RATE(sdmmcclk, 0x0, 9, SDMMCCLK, 100000000); static DEFINE_PRCMU_CLK(slimclk, 0x0, 10, SLIMCLK); static DEFINE_PRCMU_CLK(per1clk, 0x0, 11, PER1CLK); static DEFINE_PRCMU_CLK(per2clk, 0x0, 12, PER2CLK); diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c index 1748fbc5853..5c0fabf5fa0 100644 --- a/arch/arm/mach-ux500/cpu-db8500.c +++ b/arch/arm/mach-ux500/cpu-db8500.c @@ -12,22 +12,20 @@ #include <linux/init.h> #include <linux/device.h> #include <linux/amba/bus.h> +#include <linux/interrupt.h> #include <linux/irq.h> #include <linux/gpio.h> #include <linux/platform_device.h> #include <linux/io.h> #include <asm/mach/map.h> +#include <asm/pmu.h> #include <mach/hardware.h> #include <mach/setup.h> #include <mach/devices.h> #include "devices-db8500.h" -static struct platform_device *platform_devs[] __initdata = { - &u8500_dma40_device, -}; - /* minimum static i/o mapping required to boot U8500 platforms */ static struct map_desc u8500_uart_io_desc[] __initdata = { __IO_DEV_DESC(U8500_UART0_BASE, SZ_4K), @@ -89,6 +87,51 @@ void __init u8500_map_io(void) iotable_init(u8500_v2_io_desc, ARRAY_SIZE(u8500_v2_io_desc)); } +static struct resource db8500_pmu_resources[] = { + [0] = { + .start = IRQ_DB8500_PMU, + .end = IRQ_DB8500_PMU, + .flags = IORESOURCE_IRQ, + }, +}; + +/* + * The PMU IRQ lines of two cores are wired together into a single interrupt. + * Bounce the interrupt to the other core if it's not ours. + */ +static irqreturn_t db8500_pmu_handler(int irq, void *dev, irq_handler_t handler) +{ + irqreturn_t ret = handler(irq, dev); + int other = !smp_processor_id(); + + if (ret == IRQ_NONE && cpu_online(other)) + irq_set_affinity(irq, cpumask_of(other)); + + /* + * We should be able to get away with the amount of IRQ_NONEs we give, + * while still having the spurious IRQ detection code kick in if the + * interrupt really starts hitting spuriously. + */ + return ret; +} + +static struct arm_pmu_platdata db8500_pmu_platdata = { + .handle_irq = db8500_pmu_handler, +}; + +static struct platform_device db8500_pmu_device = { + .name = "arm-pmu", + .id = ARM_PMU_DEVICE_CPU, + .num_resources = ARRAY_SIZE(db8500_pmu_resources), + .resource = db8500_pmu_resources, + .dev.platform_data = &db8500_pmu_platdata, +}; + +static struct platform_device *platform_devs[] __initdata = { + &u8500_dma40_device, + &db8500_pmu_device, +}; + static resource_size_t __initdata db8500_gpio_base[] = { U8500_GPIOBANK0_BASE, U8500_GPIOBANK1_BASE, diff --git a/arch/arm/mach-ux500/include/mach/memory.h b/arch/arm/mach-ux500/include/mach/memory.h index 510571a59e2..2ef697a6700 100644 --- a/arch/arm/mach-ux500/include/mach/memory.h +++ b/arch/arm/mach-ux500/include/mach/memory.h @@ -12,7 +12,7 @@ /* * Physical DRAM offset. */ -#define PHYS_OFFSET UL(0x00000000) +#define PLAT_PHYS_OFFSET UL(0x00000000) #define BUS_OFFSET UL(0x00000000) #endif diff --git a/arch/arm/mach-versatile/include/mach/memory.h b/arch/arm/mach-versatile/include/mach/memory.h index 79aeab86b90..dacc9d8e4e6 100644 --- a/arch/arm/mach-versatile/include/mach/memory.h +++ b/arch/arm/mach-versatile/include/mach/memory.h @@ -23,6 +23,6 @@ /* * Physical DRAM offset. */ -#define PHYS_OFFSET UL(0x00000000) +#define PLAT_PHYS_OFFSET UL(0x00000000) #endif diff --git a/arch/arm/mach-versatile/versatile_ab.c b/arch/arm/mach-versatile/versatile_ab.c index aa9730fb13b..62053dfd54c 100644 --- a/arch/arm/mach-versatile/versatile_ab.c +++ b/arch/arm/mach-versatile/versatile_ab.c @@ -33,6 +33,11 @@ #include "core.h" +static const char *versatile_ab_match[] __initdata = { + "arm,versatile-ab", + NULL, +}; + MACHINE_START(VERSATILE_AB, "ARM-Versatile AB") /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ .boot_params = 0x00000100, @@ -40,4 +45,5 @@ MACHINE_START(VERSATILE_AB, "ARM-Versatile AB") .init_irq = versatile_init_irq, .timer = &versatile_timer, .init_machine = versatile_init, + .dt_compat = versatile_ab_match, MACHINE_END diff --git a/arch/arm/mach-versatile/versatile_pb.c b/arch/arm/mach-versatile/versatile_pb.c index bf469642a3f..eba12fa1db0 100644 --- a/arch/arm/mach-versatile/versatile_pb.c +++ b/arch/arm/mach-versatile/versatile_pb.c @@ -106,6 +106,11 @@ static void __init versatile_pb_init(void) } } +static const char *versatile_pb_match[] __initdata = { + "arm,versatile-pb", + NULL, +}; + MACHINE_START(VERSATILE_PB, "ARM-Versatile PB") /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ .boot_params = 0x00000100, @@ -113,4 +118,5 @@ MACHINE_START(VERSATILE_PB, "ARM-Versatile PB") .init_irq = versatile_init_irq, .timer = &versatile_timer, .init_machine = versatile_pb_init, + .dt_compat = versatile_pb_match, MACHINE_END diff --git a/arch/arm/mach-vexpress/Kconfig b/arch/arm/mach-vexpress/Kconfig index 3f19b660a16..931148487f0 100644 --- a/arch/arm/mach-vexpress/Kconfig +++ b/arch/arm/mach-vexpress/Kconfig @@ -5,5 +5,8 @@ config ARCH_VEXPRESS_CA9X4 bool "Versatile Express Cortex-A9x4 tile" select CPU_V7 select ARM_GIC + select ARM_ERRATA_720789 + select ARM_ERRATA_751472 + select ARM_ERRATA_753970 endmenu diff --git a/arch/arm/mach-vexpress/ct-ca9x4.c b/arch/arm/mach-vexpress/ct-ca9x4.c index e628402b754..e9bccc5230c 100644 --- a/arch/arm/mach-vexpress/ct-ca9x4.c +++ b/arch/arm/mach-vexpress/ct-ca9x4.c @@ -243,7 +243,7 @@ static void __init ct_ca9x4_init(void) } MACHINE_START(VEXPRESS, "ARM-Versatile Express CA9x4") - .boot_params = PHYS_OFFSET + 0x00000100, + .boot_params = PLAT_PHYS_OFFSET + 0x00000100, .map_io = ct_ca9x4_map_io, .init_irq = ct_ca9x4_init_irq, #if 0 diff --git a/arch/arm/mach-vexpress/include/mach/memory.h b/arch/arm/mach-vexpress/include/mach/memory.h index be28232ae63..5b7fcd439d8 100644 --- a/arch/arm/mach-vexpress/include/mach/memory.h +++ b/arch/arm/mach-vexpress/include/mach/memory.h @@ -20,6 +20,6 @@ #ifndef __ASM_ARCH_MEMORY_H #define __ASM_ARCH_MEMORY_H -#define PHYS_OFFSET UL(0x60000000) +#define PLAT_PHYS_OFFSET UL(0x60000000) #endif diff --git a/arch/arm/mach-w90x900/include/mach/memory.h b/arch/arm/mach-w90x900/include/mach/memory.h index 971b80702c2..f02905ba774 100644 --- a/arch/arm/mach-w90x900/include/mach/memory.h +++ b/arch/arm/mach-w90x900/include/mach/memory.h @@ -18,6 +18,6 @@ #ifndef __ASM_ARCH_MEMORY_H #define __ASM_ARCH_MEMORY_H -#define PHYS_OFFSET UL(0x00000000) +#define PLAT_PHYS_OFFSET UL(0x00000000) #endif diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index e4509bae8fc..89266382b53 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -390,7 +390,7 @@ config CPU_PJ4 # ARMv6 config CPU_V6 - bool "Support ARM V6 processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX || ARCH_DOVE + bool "Support ARM V6 processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX select CPU_32v6 select CPU_ABRT_EV6 select CPU_PABRT_V6 @@ -402,16 +402,18 @@ config CPU_V6 select CPU_TLB_V6 if MMU # ARMv6k -config CPU_32v6K - bool "Support ARM V6K processor extensions" if !SMP - depends on CPU_V6 || CPU_V7 - default y if SMP - help - Say Y here if your ARMv6 processor supports the 'K' extension. - This enables the kernel to use some instructions not present - on previous processors, and as such a kernel build with this - enabled will not boot on processors with do not support these - instructions. +config CPU_V6K + bool "Support ARM V6K processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX + select CPU_32v6 + select CPU_32v6K + select CPU_ABRT_EV6 + select CPU_PABRT_V6 + select CPU_CACHE_V6 + select CPU_CACHE_VIPT + select CPU_CP15_MMU + select CPU_HAS_ASID if MMU + select CPU_COPY_V6 if MMU + select CPU_TLB_V6 if MMU # ARMv7 config CPU_V7 @@ -433,25 +435,33 @@ config CPU_32v3 bool select TLS_REG_EMUL if SMP || !MMU select NEEDS_SYSCALL_FOR_CMPXCHG if SMP + select CPU_USE_DOMAINS if MMU config CPU_32v4 bool select TLS_REG_EMUL if SMP || !MMU select NEEDS_SYSCALL_FOR_CMPXCHG if SMP + select CPU_USE_DOMAINS if MMU config CPU_32v4T bool select TLS_REG_EMUL if SMP || !MMU select NEEDS_SYSCALL_FOR_CMPXCHG if SMP + select CPU_USE_DOMAINS if MMU config CPU_32v5 bool select TLS_REG_EMUL if SMP || !MMU select NEEDS_SYSCALL_FOR_CMPXCHG if SMP + select CPU_USE_DOMAINS if MMU config CPU_32v6 bool select TLS_REG_EMUL if !CPU_32v6K && !MMU + select CPU_USE_DOMAINS if CPU_V6 && MMU + +config CPU_32v6K + bool config CPU_32v7 bool @@ -607,8 +617,6 @@ config CPU_CP15_MPU config CPU_USE_DOMAINS bool - depends on MMU - default y if !CPU_32v6K help This option enables or disables the use of domain switching via the set_fs() function. @@ -623,7 +631,7 @@ comment "Processor Features" config ARM_THUMB bool "Support Thumb user binaries" - depends on CPU_ARM720T || CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020 || CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK || CPU_V6 || CPU_V7 || CPU_FEROCEON + depends on CPU_ARM720T || CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020 || CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK || CPU_V6 || CPU_V6K || CPU_V7 || CPU_FEROCEON default y help Say Y if you want to include kernel support for running user space @@ -644,7 +652,7 @@ config ARM_THUMBEE config SWP_EMULATE bool "Emulate SWP/SWPB instructions" - depends on !CPU_USE_DOMAINS && CPU_V7 && !CPU_V6 + depends on !CPU_USE_DOMAINS && CPU_V7 select HAVE_PROC_CPU if PROC_FS default y if SMP help @@ -681,7 +689,7 @@ config CPU_BIG_ENDIAN config CPU_ENDIAN_BE8 bool depends on CPU_BIG_ENDIAN - default CPU_V6 || CPU_V7 + default CPU_V6 || CPU_V6K || CPU_V7 help Support for the BE-8 (big-endian) mode on ARMv6 and ARMv7 processors. @@ -747,7 +755,7 @@ config CPU_CACHE_ROUND_ROBIN config CPU_BPREDICT_DISABLE bool "Disable branch prediction" - depends on CPU_ARM1020 || CPU_V6 || CPU_MOHAWK || CPU_XSC3 || CPU_V7 || CPU_FA526 + depends on CPU_ARM1020 || CPU_V6 || CPU_V6K || CPU_MOHAWK || CPU_XSC3 || CPU_V7 || CPU_FA526 help Say Y here to disable branch prediction. If unsure, say N. @@ -767,7 +775,7 @@ config NEEDS_SYSCALL_FOR_CMPXCHG config DMA_CACHE_RWFO bool "Enable read/write for ownership DMA cache maintenance" - depends on CPU_V6 && SMP + depends on CPU_V6K && SMP default y help The Snoop Control Unit on ARM11MPCore does not detect the @@ -823,7 +831,7 @@ config CACHE_L2X0 config CACHE_PL310 bool depends on CACHE_L2X0 - default y if CPU_V7 && !CPU_V6 + default y if CPU_V7 && !(CPU_V6 || CPU_V6K) help This option enables optimisations for the PL310 cache controller. @@ -845,16 +853,21 @@ config CACHE_XSC3L2 help This option enables the L2 cache on XScale3. +config ARM_L1_CACHE_SHIFT_6 + bool + help + Setting ARM L1 cache line size to 64 Bytes. + config ARM_L1_CACHE_SHIFT int default 6 if ARM_L1_CACHE_SHIFT_6 default 5 config ARM_DMA_MEM_BUFFERABLE - bool "Use non-cacheable memory for DMA" if CPU_V6 && !CPU_V7 + bool "Use non-cacheable memory for DMA" if (CPU_V6 || CPU_V6K) && !CPU_V7 depends on !(MACH_REALVIEW_PB1176 || REALVIEW_EB_ARM11MP || \ MACH_REALVIEW_PB11MP) - default y if CPU_V6 || CPU_V7 + default y if CPU_V6 || CPU_V6K || CPU_V7 help Historically, the kernel has used strongly ordered mappings to provide DMA coherent memory. With the advent of ARMv7, mapping diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile index 00d74a04af3..bca7e61928c 100644 --- a/arch/arm/mm/Makefile +++ b/arch/arm/mm/Makefile @@ -90,6 +90,7 @@ obj-$(CONFIG_CPU_XSC3) += proc-xsc3.o obj-$(CONFIG_CPU_MOHAWK) += proc-mohawk.o obj-$(CONFIG_CPU_FEROCEON) += proc-feroceon.o obj-$(CONFIG_CPU_V6) += proc-v6.o +obj-$(CONFIG_CPU_V6K) += proc-v6.o obj-$(CONFIG_CPU_V7) += proc-v7.o AFLAGS_proc-v6.o :=-Wa,-march=armv6 diff --git a/arch/arm/mm/abort-ev6.S b/arch/arm/mm/abort-ev6.S index f332df7f0d3..1478aa52214 100644 --- a/arch/arm/mm/abort-ev6.S +++ b/arch/arm/mm/abort-ev6.S @@ -20,11 +20,11 @@ */ .align 5 ENTRY(v6_early_abort) -#ifdef CONFIG_CPU_32v6K - clrex -#else +#ifdef CONFIG_CPU_V6 sub r1, sp, #4 @ Get unused stack location strex r0, r1, [r1] @ Clear the exclusive monitor +#elif defined(CONFIG_CPU_32v6K) + clrex #endif mrc p15, 0, r1, c5, c0, 0 @ get FSR mrc p15, 0, r0, c6, c0, 0 @ get FAR diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index cddd684364d..8e3387cadaf 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -15,12 +15,14 @@ #include <linux/mman.h> #include <linux/nodemask.h> #include <linux/initrd.h> +#include <linux/of_fdt.h> #include <linux/highmem.h> #include <linux/gfp.h> #include <linux/memblock.h> #include <linux/sort.h> #include <asm/mach-types.h> +#include <asm/prom.h> #include <asm/sections.h> #include <asm/setup.h> #include <asm/sizes.h> @@ -71,6 +73,14 @@ static int __init parse_tag_initrd2(const struct tag *tag) __tagtable(ATAG_INITRD2, parse_tag_initrd2); +#ifdef CONFIG_OF_FLATTREE +void __init early_init_dt_setup_initrd_arch(unsigned long start, unsigned long end) +{ + phys_initrd_start = start; + phys_initrd_size = end - start + 1; +} +#endif /* CONFIG_OF_FLATTREE */ + /* * This keeps memory configuration data used by a couple memory * initialization functions, as well as show_mem() for the skipping @@ -313,6 +323,7 @@ void __init arm_memblock_init(struct meminfo *mi, struct machine_desc *mdesc) #endif arm_mm_memblock_reserve(); + arm_dt_memblock_reserve(); /* reserve any platform specific memblock areas */ if (mdesc->reserve) diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c index b0a98305055..afe209e1e1f 100644 --- a/arch/arm/mm/mmap.c +++ b/arch/arm/mm/mmap.c @@ -31,7 +31,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, struct mm_struct *mm = current->mm; struct vm_area_struct *vma; unsigned long start_addr; -#ifdef CONFIG_CPU_V6 +#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K) unsigned int cache_type; int do_align = 0, aliasing = 0; diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 3c67e92f7d5..ff7b43b5885 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -827,16 +827,6 @@ static void __init sanity_check_meminfo(void) * rather difficult. */ reason = "with VIPT aliasing cache"; - } else if (is_smp() && tlb_ops_need_broadcast()) { - /* - * kmap_high needs to occasionally flush TLB entries, - * however, if the TLB entries need to be broadcast - * we may deadlock: - * kmap_high(irqs off)->flush_all_zero_pkmaps-> - * flush_tlb_kernel_range->smp_call_function_many - * (must not be called with irqs off) - */ - reason = "without hardware TLB ops broadcasting"; } if (reason) { printk(KERN_CRIT "HIGHMEM is not supported %s, ignoring high memory\n", diff --git a/arch/arm/mm/vmregion.c b/arch/arm/mm/vmregion.c index 935993e1b1e..036fdbfdd62 100644 --- a/arch/arm/mm/vmregion.c +++ b/arch/arm/mm/vmregion.c @@ -38,7 +38,7 @@ struct arm_vmregion * arm_vmregion_alloc(struct arm_vmregion_head *head, size_t align, size_t size, gfp_t gfp) { - unsigned long addr = head->vm_start, end = head->vm_end - size; + unsigned long start = head->vm_start, addr = head->vm_end; unsigned long flags; struct arm_vmregion *c, *new; @@ -54,21 +54,20 @@ arm_vmregion_alloc(struct arm_vmregion_head *head, size_t align, spin_lock_irqsave(&head->vm_lock, flags); - list_for_each_entry(c, &head->vm_list, vm_list) { - if ((addr + size) < addr) - goto nospc; - if ((addr + size) <= c->vm_start) + addr = rounddown(addr - size, align); + list_for_each_entry_reverse(c, &head->vm_list, vm_list) { + if (addr >= c->vm_end) goto found; - addr = ALIGN(c->vm_end, align); - if (addr > end) + addr = rounddown(c->vm_start - size, align); + if (addr < start) goto nospc; } found: /* - * Insert this entry _before_ the one we found. + * Insert this entry after the one we found. */ - list_add_tail(&new->vm_list, &c->vm_list); + list_add(&new->vm_list, &c->vm_list); new->vm_start = addr; new->vm_end = addr + size; new->vm_active = 1; diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig index 389f2179501..a97f7334bc7 100644 --- a/arch/arm/plat-mxc/Kconfig +++ b/arch/arm/plat-mxc/Kconfig @@ -119,4 +119,10 @@ config IRAM_ALLOC bool select GENERIC_ALLOCATOR +config CLK_DEBUG + bool "clock debug information export to user space" + depends on PM_DEBUG && DEBUG_FS + default n + help + export clk debug information to user space endif diff --git a/arch/arm/plat-mxc/clock.c b/arch/arm/plat-mxc/clock.c index 2ed3ab173ad..190bce1221a 100644 --- a/arch/arm/plat-mxc/clock.c +++ b/arch/arm/plat-mxc/clock.c @@ -37,6 +37,8 @@ #include <linux/proc_fs.h> #include <linux/semaphore.h> #include <linux/string.h> +#include <linux/slab.h> +#include <linux/debugfs.h> #include <mach/clock.h> #include <mach/hardware.h> @@ -244,3 +246,122 @@ unsigned long mxc_decode_pll(unsigned int reg_val, u32 freq) return ll; } + +#ifdef CONFIG_CLK_DEBUG +/* + * debugfs support to trace clock tree hierarchy and attributes + */ +static int clk_debug_rate_get(void *data, u64 *val) +{ + struct clk *clk = data; + + *val = (u64)clk_get_rate(clk); + return 0; +} +DEFINE_SIMPLE_ATTRIBUTE(clk_debug_rate_fops, clk_debug_rate_get, NULL, + "%llu\n"); + + +static struct dentry *clk_root; +static int clk_debug_register_one(struct clk *clk) +{ + int err; + struct dentry *d, *child, *child_tmp; + struct clk *pa = clk_get_parent(clk); + + if (pa && !IS_ERR(pa)) + d = debugfs_create_dir(clk->name, pa->dentry); + else { + if (!clk_root) + clk_root = debugfs_create_dir("clock", NULL); + if (!clk_root) + return -ENOMEM; + d = debugfs_create_dir(clk->name, clk_root); + } + + if (!d) + return -ENOMEM; + + clk->dentry = d; + + d = debugfs_create_u32("enable_count", S_IRUGO, clk->dentry, + (u32 *)&clk->usecount); + if (!d) { + err = -ENOMEM; + goto err_out; + } + + d = debugfs_create_file("rate", S_IRUGO, clk->dentry, (void *)clk, + &clk_debug_rate_fops); + if (!d) { + err = -ENOMEM; + goto err_out; + } + + return 0; + +err_out: + d = clk->dentry; + list_for_each_entry_safe(child, child_tmp, &d->d_subdirs, d_u.d_child) + debugfs_remove(child); + debugfs_remove(clk->dentry); + return err; +} + +struct preinit_clk { + struct list_head list; + struct clk *clk; +}; +static LIST_HEAD(preinit_clks); +static DEFINE_MUTEX(preinit_lock); +static int init_done; + +void clk_debug_register(struct clk *clk) +{ + int err; + struct clk *pa; + + if (init_done) { + pa = clk_get_parent(clk); + + if (pa && !IS_ERR(pa) && !pa->dentry) + clk_debug_register(pa); + + if (!clk->dentry) { + err = clk_debug_register_one(clk); + if (err) + return; + } + } else { + struct preinit_clk *p; + mutex_lock(&preinit_lock); + p = kmalloc(sizeof(*p), GFP_KERNEL); + if (p) { + p->clk = clk; + list_add(&p->list, &preinit_clks); + } + mutex_unlock(&preinit_lock); + } +} +EXPORT_SYMBOL_GPL(clk_debug_register); + +static int __init clk_debugfs_init(void) +{ + struct preinit_clk *pclk, *tmp; + + init_done = 1; + + mutex_lock(&preinit_lock); + list_for_each_entry(pclk, &preinit_clks, list) { + clk_debug_register(pclk->clk); + } + + list_for_each_entry_safe(pclk, tmp, &preinit_clks, list) { + list_del(&pclk->list); + kfree(pclk); + } + mutex_unlock(&preinit_lock); + return 0; +} +late_initcall(clk_debugfs_init); +#endif diff --git a/arch/arm/plat-mxc/include/mach/clock.h b/arch/arm/plat-mxc/include/mach/clock.h index 753a5988d85..fb0e0bd3f51 100644 --- a/arch/arm/plat-mxc/include/mach/clock.h +++ b/arch/arm/plat-mxc/include/mach/clock.h @@ -23,9 +23,14 @@ #ifndef __ASSEMBLY__ #include <linux/list.h> +#define CLK_NAME_LEN 32 struct module; struct clk { +#ifdef CONFIG_CLK_DEBUG + char name[CLK_NAME_LEN]; + struct dentry *dentry; +#endif int id; /* Source clock this clk depends on */ struct clk *parent; @@ -62,5 +67,11 @@ void clk_unregister(struct clk *clk); unsigned long mxc_decode_pll(unsigned int pll, u32 f_ref); +#ifdef CONFIG_CLK_DEBUG +void clk_debug_register(struct clk *clk); +#else +static inline void clk_debug_register(struct clk *clk) {} +#endif + #endif /* __ASSEMBLY__ */ #endif /* __ASM_ARCH_MXC_CLOCK_H__ */ diff --git a/arch/arm/plat-mxc/include/mach/memory.h b/arch/arm/plat-mxc/include/mach/memory.h index 83861408133..5d51cbb9889 100644 --- a/arch/arm/plat-mxc/include/mach/memory.h +++ b/arch/arm/plat-mxc/include/mach/memory.h @@ -23,23 +23,23 @@ #if !defined(CONFIG_RUNTIME_PHYS_OFFSET) # if defined CONFIG_ARCH_MX1 -# define PHYS_OFFSET MX1_PHYS_OFFSET +# define PLAT_PHYS_OFFSET MX1_PHYS_OFFSET # elif defined CONFIG_MACH_MX21 -# define PHYS_OFFSET MX21_PHYS_OFFSET +# define PLAT_PHYS_OFFSET MX21_PHYS_OFFSET # elif defined CONFIG_ARCH_MX25 -# define PHYS_OFFSET MX25_PHYS_OFFSET +# define PLAT_PHYS_OFFSET MX25_PHYS_OFFSET # elif defined CONFIG_MACH_MX27 -# define PHYS_OFFSET MX27_PHYS_OFFSET +# define PLAT_PHYS_OFFSET MX27_PHYS_OFFSET # elif defined CONFIG_ARCH_MX3 -# define PHYS_OFFSET MX3x_PHYS_OFFSET +# define PLAT_PHYS_OFFSET MX3x_PHYS_OFFSET # elif defined CONFIG_ARCH_MXC91231 -# define PHYS_OFFSET MXC91231_PHYS_OFFSET +# define PLAT_PHYS_OFFSET MXC91231_PHYS_OFFSET # elif defined CONFIG_ARCH_MX50 -# define PHYS_OFFSET MX50_PHYS_OFFSET +# define PLAT_PHYS_OFFSET MX50_PHYS_OFFSET # elif defined CONFIG_ARCH_MX51 -# define PHYS_OFFSET MX51_PHYS_OFFSET +# define PLAT_PHYS_OFFSET MX51_PHYS_OFFSET # elif defined CONFIG_ARCH_MX53 -# define PHYS_OFFSET MX53_PHYS_OFFSET +# define PLAT_PHYS_OFFSET MX53_PHYS_OFFSET # endif #endif diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile index a4a12859fdd..ec7862e9149 100644 --- a/arch/arm/plat-omap/Makefile +++ b/arch/arm/plat-omap/Makefile @@ -21,7 +21,6 @@ obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o obj-$(CONFIG_OMAP_IOMMU) += iommu.o iovmm.o obj-$(CONFIG_OMAP_IOMMU_DEBUG) += iommu-debug.o -obj-$(CONFIG_CPU_FREQ) += cpu-omap.o obj-$(CONFIG_OMAP_DM_TIMER) += dmtimer.o obj-$(CONFIG_OMAP_DEBUG_DEVICES) += debug-devices.o obj-$(CONFIG_OMAP_DEBUG_LEDS) += debug-leds.o diff --git a/arch/arm/plat-omap/include/plat/display.h b/arch/arm/plat-omap/include/plat/display.h index 537f4e449f5..2fb057e1cb9 100644 --- a/arch/arm/plat-omap/include/plat/display.h +++ b/arch/arm/plat-omap/include/plat/display.h @@ -23,6 +23,7 @@ #include <linux/list.h> #include <linux/kobject.h> #include <linux/device.h> +#include <linux/platform_device.h> #include <asm/atomic.h> #define DISPC_IRQ_FRAMEDONE (1 << 0) @@ -226,6 +227,21 @@ struct omap_dss_board_info { struct omap_dss_device *default_device; }; +#if defined(CONFIG_OMAP2_DSS_MODULE) || defined(CONFIG_OMAP2_DSS) +/* Init with the board info */ +extern int omap_display_init(struct omap_dss_board_info *board_data); +#else +static inline int omap_display_init(struct omap_dss_board_info *board_data) +{ + return 0; +} +#endif + +struct omap_display_platform_data { + struct omap_dss_board_info *board_data; + /* TODO: Additional members to be added when PM is considered */ +}; + struct omap_video_timings { /* Unit: pixels */ u16 x_res; diff --git a/arch/arm/plat-omap/include/plat/dvfs.h b/arch/arm/plat-omap/include/plat/dvfs.h new file mode 100644 index 00000000000..1be2b9d8bd3 --- /dev/null +++ b/arch/arm/plat-omap/include/plat/dvfs.h @@ -0,0 +1,34 @@ +/* + * OMAP3/OMAP4 DVFS Management Routines + * + * Author: Vishwanath BS <vishwanath.bs@ti.com> + * + * Copyright (C) 2011 Texas Instruments, Inc. + * Vishwanath BS <vishwanath.bs@ti.com> + * + * 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. + */ + +#ifndef __ARCH_ARM_MACH_OMAP2_DVFS_H +#define __ARCH_ARM_MACH_OMAP2_DVFS_H +#include <plat/voltage.h> + +#ifdef CONFIG_PM +int omap_dvfs_register_device(struct voltagedomain *voltdm, struct device *dev); +int omap_device_scale(struct device *req_dev, struct device *dev, + unsigned long rate); +#else +static inline int omap_dvfs_register_device(struct voltagedomain *voltdm, + struct device *dev) +{ + return -EINVAL; +} +static inline int omap_device_scale(struct device *req_dev, struct devices + *target_dev, unsigned long rate); +{ + return -EINVAL; +} +#endif +#endif diff --git a/arch/arm/plat-omap/include/plat/l3_2xxx.h b/arch/arm/plat-omap/include/plat/l3_2xxx.h new file mode 100644 index 00000000000..b8b5641379b --- /dev/null +++ b/arch/arm/plat-omap/include/plat/l3_2xxx.h @@ -0,0 +1,20 @@ +/* + * arch/arm/plat-omap/include/plat/l3_2xxx.h - L3 firewall definitions + * + * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ + * Sumit Semwal + * + * 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. + * + */ +#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_PLAT_L3_2XXX_H +#define __ARCH_ARM_PLAT_OMAP_INCLUDE_PLAT_L3_2XXX_H + +/* L3 CONNIDs */ +/* Display Sub system (DSS) */ +#define OMAP2_L3_CORE_FW_CONNID_DSS 8 + +#endif diff --git a/arch/arm/plat-omap/include/plat/l3_3xxx.h b/arch/arm/plat-omap/include/plat/l3_3xxx.h new file mode 100644 index 00000000000..cde1938c5f8 --- /dev/null +++ b/arch/arm/plat-omap/include/plat/l3_3xxx.h @@ -0,0 +1,20 @@ +/* + * arch/arm/plat-omap/include/plat/l3_3xxx.h - L3 firewall definitions + * + * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ + * Sumit Semwal + * + * 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. + * + */ +#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_PLAT_L3_3XXX_H +#define __ARCH_ARM_PLAT_OMAP_INCLUDE_PLAT_L3_3XXX_H + +/* L3 Initiator IDs */ +/* Display Sub system (DSS) */ +#define OMAP3_L3_CORE_FW_INIT_ID_DSS 29 + +#endif diff --git a/arch/arm/plat-omap/include/plat/l4_2xxx.h b/arch/arm/plat-omap/include/plat/l4_2xxx.h new file mode 100644 index 00000000000..3f39cf8a35c --- /dev/null +++ b/arch/arm/plat-omap/include/plat/l4_2xxx.h @@ -0,0 +1,24 @@ +/* + * arch/arm/plat-omap/include/plat/l4_2xxx.h - L4 firewall definitions + * + * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ + * Sumit Semwal + * + * 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. + * + */ +#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_PLAT_L4_2XXX_H +#define __ARCH_ARM_PLAT_OMAP_INCLUDE_PLAT_L4_2XXX_H + +/* L4 CORE */ +/* Display Sub system (DSS) */ +#define OMAP2420_L4_CORE_FW_DSS_CORE_REGION 28 +#define OMAP2420_L4_CORE_FW_DSS_DISPC_REGION 29 +#define OMAP2420_L4_CORE_FW_DSS_RFBI_REGION 30 +#define OMAP2420_L4_CORE_FW_DSS_VENC_REGION 31 +#define OMAP2420_L4_CORE_FW_DSS_TA_REGION 32 + +#endif diff --git a/arch/arm/plat-omap/include/plat/l4_3xxx.h b/arch/arm/plat-omap/include/plat/l4_3xxx.h index 5e194937542..881a858b1ff 100644 --- a/arch/arm/plat-omap/include/plat/l4_3xxx.h +++ b/arch/arm/plat-omap/include/plat/l4_3xxx.h @@ -21,4 +21,14 @@ #define OMAP3_L4_CORE_FW_I2C3_REGION 73 #define OMAP3_L4_CORE_FW_I2C3_TA_REGION 74 +/* Display Sub system (DSS) */ +#define OMAP3_L4_CORE_FW_DSS_PROT_GROUP 2 + +#define OMAP3_L4_CORE_FW_DSS_DSI_REGION 104 +#define OMAP3ES1_L4_CORE_FW_DSS_CORE_REGION 3 +#define OMAP3_L4_CORE_FW_DSS_CORE_REGION 4 +#define OMAP3_L4_CORE_FW_DSS_DISPC_REGION 4 +#define OMAP3_L4_CORE_FW_DSS_RFBI_REGION 5 +#define OMAP3_L4_CORE_FW_DSS_VENC_REGION 6 +#define OMAP3_L4_CORE_FW_DSS_TA_REGION 7 #endif diff --git a/arch/arm/plat-omap/include/plat/memory.h b/arch/arm/plat-omap/include/plat/memory.h index f8d922fb558..e6720aa2d55 100644 --- a/arch/arm/plat-omap/include/plat/memory.h +++ b/arch/arm/plat-omap/include/plat/memory.h @@ -37,9 +37,9 @@ * Physical DRAM offset. */ #if defined(CONFIG_ARCH_OMAP1) -#define PHYS_OFFSET UL(0x10000000) +#define PLAT_PHYS_OFFSET UL(0x10000000) #else -#define PHYS_OFFSET UL(0x80000000) +#define PLAT_PHYS_OFFSET UL(0x80000000) #endif /* diff --git a/arch/arm/plat-omap/include/plat/omap_device.h b/arch/arm/plat-omap/include/plat/omap_device.h index e4c349ff9fd..204fb0a9b2f 100644 --- a/arch/arm/plat-omap/include/plat/omap_device.h +++ b/arch/arm/plat-omap/include/plat/omap_device.h @@ -50,6 +50,8 @@ extern struct device omap_device_parent; * @hwmods: (one .. many per omap_device) * @hwmods_cnt: ARRAY_SIZE() of @hwmods * @pm_lats: ptr to an omap_device_pm_latency table + * @set_rate: fn ptr to change the operating rate. + * @get_rate: fn ptr to retrieve the current operating rate. * @pm_lats_cnt: ARRAY_SIZE() of what is passed to @pm_lats * @pm_lat_level: array index of the last odpl entry executed - -1 if never * @dev_wakeup_lat: dev wakeup latency in nanoseconds @@ -73,6 +75,8 @@ struct omap_device { s8 pm_lat_level; u8 hwmods_cnt; u8 _state; + int (*set_rate)(struct device *dev, unsigned long rate); + unsigned long (*get_rate) (struct device *dev); }; /* Device driver interface (call via platform_data fn ptrs) */ @@ -107,6 +111,11 @@ void __iomem *omap_device_get_rt_va(struct omap_device *od); int omap_device_align_pm_lat(struct platform_device *pdev, u32 new_wakeup_lat_limit); struct powerdomain *omap_device_get_pwrdm(struct omap_device *od); +int omap_device_set_rate(struct device *dev, unsigned long freq); +unsigned long omap_device_get_rate(struct device *dev); +void omap_device_register_dvfs_callbacks(struct device *dev, + int (*set_rate)(struct device *dev, unsigned long rate), + unsigned long (*get_rate) (struct device *dev)); u32 omap_device_get_context_loss_count(struct platform_device *pdev); /* Other */ diff --git a/arch/arm/plat-omap/include/plat/serial.h b/arch/arm/plat-omap/include/plat/serial.h index cec5d56db2e..8ff605c83ac 100644 --- a/arch/arm/plat-omap/include/plat/serial.h +++ b/arch/arm/plat-omap/include/plat/serial.h @@ -27,7 +27,7 @@ * 2. We assume printascii is called at least once before paging_init, * and addruart has a chance to read OMAP_UART_INFO */ -#define OMAP_UART_INFO (PHYS_OFFSET + 0x3ffc) +#define OMAP_UART_INFO (PLAT_PHYS_OFFSET + 0x3ffc) /* OMAP1 serial ports */ #define OMAP1_UART1_BASE 0xfffb0000 diff --git a/arch/arm/plat-omap/include/plat/sram.h b/arch/arm/plat-omap/include/plat/sram.h index 9967d5e855c..f500fc34d06 100644 --- a/arch/arm/plat-omap/include/plat/sram.h +++ b/arch/arm/plat-omap/include/plat/sram.h @@ -12,7 +12,19 @@ #define __ARCH_ARM_OMAP_SRAM_H #ifndef __ASSEMBLY__ -extern void * omap_sram_push(void * start, unsigned long size); +#include <asm/fncpy.h> + +extern void *omap_sram_push_address(unsigned long size); + +/* Macro to push a function to the internal SRAM, using the fncpy API */ +#define omap_sram_push(funcp, size) ({ \ + typeof(&(funcp)) _res = NULL; \ + void *_sram_address = omap_sram_push_address(size); \ + if (_sram_address) \ + _res = fncpy(_sram_address, &(funcp), size); \ + _res; \ +}) + extern void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl); extern void omap2_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl, diff --git a/arch/arm/plat-omap/include/plat/voltage.h b/arch/arm/plat-omap/include/plat/voltage.h index 5bd204e55c3..e0b7f22155d 100644 --- a/arch/arm/plat-omap/include/plat/voltage.h +++ b/arch/arm/plat-omap/include/plat/voltage.h @@ -113,6 +113,154 @@ struct omap_volt_pmic_info { u8 (*uv_to_vsel) (unsigned long uV); }; +/* Voltage processor register offsets */ +struct vp_reg_offs { + u8 vpconfig; + u8 vstepmin; + u8 vstepmax; + u8 vlimitto; + u8 vstatus; + u8 voltage; +}; + +/* Voltage Processor bit field values, shifts and masks */ +struct vp_reg_val { + /* PRM module */ + u16 prm_mod; + /* VPx_VPCONFIG */ + u32 vpconfig_erroroffset; + u16 vpconfig_errorgain; + u32 vpconfig_errorgain_mask; + u8 vpconfig_errorgain_shift; + u32 vpconfig_initvoltage_mask; + u8 vpconfig_initvoltage_shift; + u32 vpconfig_timeouten; + u32 vpconfig_initvdd; + u32 vpconfig_forceupdate; + u32 vpconfig_vpenable; + /* VPx_VSTEPMIN */ + u8 vstepmin_stepmin; + u16 vstepmin_smpswaittimemin; + u8 vstepmin_stepmin_shift; + u8 vstepmin_smpswaittimemin_shift; + /* VPx_VSTEPMAX */ + u8 vstepmax_stepmax; + u16 vstepmax_smpswaittimemax; + u8 vstepmax_stepmax_shift; + u8 vstepmax_smpswaittimemax_shift; + /* VPx_VLIMITTO */ + u8 vlimitto_vddmin; + u8 vlimitto_vddmax; + u16 vlimitto_timeout; + u8 vlimitto_vddmin_shift; + u8 vlimitto_vddmax_shift; + u8 vlimitto_timeout_shift; + /* PRM_IRQSTATUS*/ + u32 tranxdone_status; +}; + +/* Voltage controller registers and offsets */ +struct vc_reg_info { + /* PRM module */ + u16 prm_mod; + /* VC register offsets */ + u8 smps_sa_reg; + u8 smps_volra_reg; + u8 bypass_val_reg; + u8 cmdval_reg; + u8 voltsetup_reg; + /*VC_SMPS_SA*/ + u8 smps_sa_shift; + u32 smps_sa_mask; + /* VC_SMPS_VOL_RA */ + u8 smps_volra_shift; + u32 smps_volra_mask; + /* VC_BYPASS_VAL */ + u8 data_shift; + u8 slaveaddr_shift; + u8 regaddr_shift; + u32 valid; + /* VC_CMD_VAL */ + u8 cmd_on_shift; + u8 cmd_onlp_shift; + u8 cmd_ret_shift; + u8 cmd_off_shift; + u32 cmd_on_mask; + /* PRM_VOLTSETUP */ + u8 voltsetup_shift; + u32 voltsetup_mask; +}; + + +/** + * omap_vdd_dep_volt - Table containing the parent vdd voltage and the + * dependent vdd voltage corresponding to it. + * + * @main_vdd_volt : The main vdd voltage + * @dep_vdd_volt : The voltage at which the dependent vdd should be + * when the main vdd is at <main_vdd_volt> voltage + */ +struct omap_vdd_dep_volt { + u32 main_vdd_volt; + u32 dep_vdd_volt; +}; + +/** + * omap_vdd_dep_info - Dependent vdd info + * + * @name : Dependent vdd name + * @voltdm : Dependent vdd pointer + * @dep_table : Table containing the dependent vdd voltage + * corresponding to every main vdd voltage. + */ +struct omap_vdd_dep_info { + char *name; + struct voltagedomain *voltdm; + struct omap_vdd_dep_volt *dep_table; +}; + + +/** + * omap_vdd_info - Per Voltage Domain info + * + * @volt_data : voltage table having the distinct voltages supported + * by the domain and other associated per voltage data. + * @pmic_info : pmic specific parameters which should be populted by + * the pmic drivers. + * @vp_offs : structure containing the offsets for various + * vp registers + * @vp_reg : the register values, shifts, masks for various + * vp registers + * @vc_reg : structure containing various various vc registers, + * shifts, masks etc. + * @voltdm : pointer to the voltage domain structure + * @debug_dir : debug directory for this voltage domain. + * @curr_volt : current voltage for this vdd. + * @ocp_mod : The prm module for accessing the prm irqstatus reg. + * @prm_irqst_reg : prm irqstatus register. + * @vp_enabled : flag to keep track of whether vp is enabled or not + * @volt_scale : API to scale the voltage of the vdd. + */ +struct omap_vdd_info { + struct omap_volt_data *volt_data; + struct omap_volt_pmic_info *pmic_info; + struct vp_reg_offs vp_offs; + struct vp_reg_val vp_reg; + struct vc_reg_info vc_reg; + struct voltagedomain voltdm; + struct omap_vdd_dep_info *dep_vdd_info; + int nr_dep_vdd; + struct dentry *debug_dir; + u32 curr_volt; + u16 ocp_mod; + u8 prm_irqst_reg; + bool vp_enabled; + u32 (*read_reg) (u16 mod, u8 offset); + void (*write_reg) (u32 val, u16 mod, u8 offset); + int (*volt_scale) (struct omap_vdd_info *vdd, + unsigned long target_volt); +}; + unsigned long omap_vp_get_curr_volt(struct voltagedomain *voltdm); void omap_vp_enable(struct voltagedomain *voltdm); void omap_vp_disable(struct voltagedomain *voltdm); diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c index 57adb270767..4cee430c40d 100644 --- a/arch/arm/plat-omap/omap_device.c +++ b/arch/arm/plat-omap/omap_device.c @@ -86,6 +86,7 @@ #include <plat/omap_device.h> #include <plat/omap_hwmod.h> +#include <plat/dvfs.h> /* These parameters are passed to _omap_device_{de,}activate() */ #define USE_WAKEUP_LAT 0 @@ -481,6 +482,14 @@ struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id, for (i = 0; i < oh_cnt; i++) { hwmods[i]->od = od; _add_optional_clock_alias(od, hwmods[i]); + if (!is_early_device && hwmods[i]->vdd_name) { + struct omap_hwmod *oh = hwmods[i]; + struct voltagedomain *voltdm; + + voltdm = omap_voltage_domain_lookup(oh->vdd_name); + if (!omap_dvfs_register_device(voltdm, &od->pdev.dev)) + oh->voltdm = voltdm; + } } if (ret) @@ -801,6 +810,55 @@ int omap_device_enable_clocks(struct omap_device *od) return 0; } +int omap_device_set_rate(struct device *dev, unsigned long freq) +{ + struct platform_device *pdev; + struct omap_device *od; + + pdev = container_of(dev, struct platform_device, dev); + od = _find_by_pdev(pdev); + + if (!od->set_rate) { + dev_err(dev, "%s: No set_rate API for scaling device\n", + __func__); + return -ENODATA; + } + + return od->set_rate(dev, freq); +} + +unsigned long omap_device_get_rate(struct device *dev) +{ + struct platform_device *pdev; + struct omap_device *od; + + pdev = container_of(dev, struct platform_device, dev); + od = _find_by_pdev(pdev); + + + if (!od->get_rate) { + dev_err(dev, "%s: No get rate API for the device\n", + __func__); + return 0; + } + + return od->get_rate(dev); +} + +void omap_device_register_dvfs_callbacks(struct device *dev, + int (*set_rate)(struct device *dev, unsigned long rate), + unsigned long (*get_rate) (struct device *dev)) +{ + struct platform_device *pdev; + struct omap_device *od; + + pdev = container_of(dev, struct platform_device, dev); + od = _find_by_pdev(pdev); + + od->set_rate = set_rate; + od->get_rate = get_rate; +} + struct device omap_device_parent = { .init_name = "omap", .parent = &platform_bus, diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c index e26e50487d6..68fcc7dc56e 100644 --- a/arch/arm/plat-omap/sram.c +++ b/arch/arm/plat-omap/sram.c @@ -242,7 +242,14 @@ static void __init omap_map_sram(void) omap_sram_size - SRAM_BOOTLOADER_SZ); } -void * omap_sram_push(void * start, unsigned long size) +/* + * Memory allocator for SRAM: calculates the new ceiling address + * for pushing a function using the fncpy API. + * + * Note that fncpy requires the returned address to be aligned + * to an 8-byte boundary. + */ +void *omap_sram_push_address(unsigned long size) { if (size > (omap_sram_ceil - (omap_sram_base + SRAM_BOOTLOADER_SZ))) { printk(KERN_ERR "Not enough space in SRAM\n"); @@ -250,10 +257,7 @@ void * omap_sram_push(void * start, unsigned long size) } omap_sram_ceil -= size; - omap_sram_ceil = ROUND_DOWN(omap_sram_ceil, sizeof(void *)); - memcpy((void *)omap_sram_ceil, start, size); - flush_icache_range((unsigned long)omap_sram_ceil, - (unsigned long)(omap_sram_ceil + size)); + omap_sram_ceil = ROUND_DOWN(omap_sram_ceil, FNCPY_ALIGN); return (void *)omap_sram_ceil; } diff --git a/arch/arm/plat-s3c24xx/Makefile b/arch/arm/plat-s3c24xx/Makefile index c2064c30871..763b7bb44c9 100644 --- a/arch/arm/plat-s3c24xx/Makefile +++ b/arch/arm/plat-s3c24xx/Makefile @@ -26,9 +26,9 @@ obj-$(CONFIG_CPU_FREQ_S3C24XX_DEBUGFS) += cpu-freq-debugfs.o # Architecture dependant builds obj-$(CONFIG_PM_SIMTEC) += pm-simtec.o -obj-$(CONFIG_PM) += pm.o -obj-$(CONFIG_PM) += irq-pm.o -obj-$(CONFIG_PM) += sleep.o +obj-$(CONFIG_SUSPEND) += pm.o +obj-$(CONFIG_SUSPEND) += irq-pm.o +obj-$(CONFIG_SUSPEND) += sleep.o obj-$(CONFIG_S3C2410_CLOCK) += s3c2410-clock.o obj-$(CONFIG_S3C2443_CLOCK) += s3c2443-clock.o obj-$(CONFIG_S3C2410_DMA) += dma.o diff --git a/arch/arm/plat-s3c24xx/cpu-freq.c b/arch/arm/plat-s3c24xx/cpu-freq.c index 25a8fc7f512..1d38db56971 100644 --- a/arch/arm/plat-s3c24xx/cpu-freq.c +++ b/arch/arm/plat-s3c24xx/cpu-freq.c @@ -429,7 +429,7 @@ static int s3c_cpufreq_verify(struct cpufreq_policy *policy) return 0; } -#ifdef CONFIG_PM +#ifdef CONFIG_SUSPEND static struct cpufreq_frequency_table suspend_pll; static unsigned int suspend_freq; diff --git a/arch/arm/plat-s3c24xx/dma.c b/arch/arm/plat-s3c24xx/dma.c index 6ad274e7593..6199b6e419a 100644 --- a/arch/arm/plat-s3c24xx/dma.c +++ b/arch/arm/plat-s3c24xx/dma.c @@ -1202,7 +1202,7 @@ static inline struct s3c2410_dma_chan *to_dma_chan(struct sys_device *dev) /* system device class */ -#ifdef CONFIG_PM +#ifdef CONFIG_SUSPEND static int s3c2410_dma_suspend(struct sys_device *dev, pm_message_t state) { diff --git a/arch/arm/plat-s3c24xx/include/plat/irq.h b/arch/arm/plat-s3c24xx/include/plat/irq.h index ec087d6054b..ca6354ff7ec 100644 --- a/arch/arm/plat-s3c24xx/include/plat/irq.h +++ b/arch/arm/plat-s3c24xx/include/plat/irq.h @@ -106,7 +106,7 @@ s3c_irqsub_ack(unsigned int irqno, unsigned int parentmask, unsigned int group) /* exported for use in arch/arm/mach-s3c2410 */ -#ifdef CONFIG_PM +#ifdef CONFIG_SUSPEND extern int s3c_irq_wake(struct irq_data *data, unsigned int state); #else #define s3c_irq_wake NULL diff --git a/arch/arm/plat-s5p/Makefile b/arch/arm/plat-s5p/Makefile index 4bd5cf90897..ce5a0a77964 100644 --- a/arch/arm/plat-s5p/Makefile +++ b/arch/arm/plat-s5p/Makefile @@ -20,8 +20,8 @@ obj-y += irq.o obj-$(CONFIG_S5P_EXT_INT) += irq-eint.o obj-$(CONFIG_S5P_GPIO_INT) += irq-gpioint.o obj-$(CONFIG_S5P_SYSTEM_MMU) += sysmmu.o -obj-$(CONFIG_PM) += pm.o -obj-$(CONFIG_PM) += irq-pm.o +obj-$(CONFIG_SUSPEND) += pm.o +obj-$(CONFIG_SUSPEND) += irq-pm.o # devices diff --git a/arch/arm/plat-s5p/irq-eint.c b/arch/arm/plat-s5p/irq-eint.c index 225aa25405d..e203a656de2 100644 --- a/arch/arm/plat-s5p/irq-eint.c +++ b/arch/arm/plat-s5p/irq-eint.c @@ -125,7 +125,7 @@ static struct irq_chip s5p_irq_eint = { .irq_mask_ack = s5p_irq_eint_maskack, .irq_ack = s5p_irq_eint_ack, .irq_set_type = s5p_irq_eint_set_type, -#ifdef CONFIG_PM +#ifdef CONFIG_SUSPEND .irq_set_wake = s3c_irqext_wake, #endif }; @@ -195,7 +195,7 @@ static struct irq_chip s5p_irq_vic_eint = { .irq_mask_ack = s5p_irq_vic_eint_maskack, .irq_ack = s5p_irq_vic_eint_ack, .irq_set_type = s5p_irq_eint_set_type, -#ifdef CONFIG_PM +#ifdef CONFIG_SUSPEND .irq_set_wake = s3c_irqext_wake, #endif }; diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile index 29932f88a8d..7e92457915b 100644 --- a/arch/arm/plat-samsung/Makefile +++ b/arch/arm/plat-samsung/Makefile @@ -68,8 +68,8 @@ obj-$(CONFIG_S3C_PL330_DMA) += s3c-pl330.o # PM support -obj-$(CONFIG_PM) += pm.o -obj-$(CONFIG_PM) += pm-gpio.o +obj-$(CONFIG_SUSPEND) += pm.o +obj-$(CONFIG_SUSPEND) += pm-gpio.o obj-$(CONFIG_SAMSUNG_PM_CHECK) += pm-check.o obj-$(CONFIG_SAMSUNG_WAKEMASK) += wakeup-mask.o diff --git a/arch/arm/plat-samsung/adc.c b/arch/arm/plat-samsung/adc.c index e8f2be2d67f..d818405eea0 100644 --- a/arch/arm/plat-samsung/adc.c +++ b/arch/arm/plat-samsung/adc.c @@ -412,7 +412,7 @@ static int __devexit s3c_adc_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM +#ifdef CONFIG_SUSPEND static int s3c_adc_suspend(struct platform_device *pdev, pm_message_t state) { struct adc_device *adc = platform_get_drvdata(pdev); diff --git a/arch/arm/plat-samsung/gpio.c b/arch/arm/plat-samsung/gpio.c index 7743c4b8b2f..4f3700f9a69 100644 --- a/arch/arm/plat-samsung/gpio.c +++ b/arch/arm/plat-samsung/gpio.c @@ -143,7 +143,7 @@ __init void s3c_gpiolib_add(struct s3c_gpio_chip *chip) if (!gc->get) gc->get = s3c_gpiolib_get; -#ifdef CONFIG_PM +#ifdef CONFIG_SUSPEND if (chip->pm != NULL) { if (!chip->pm->save || !chip->pm->resume) printk(KERN_ERR "gpio: %s has missing PM functions\n", diff --git a/arch/arm/plat-samsung/include/plat/gpio-core.h b/arch/arm/plat-samsung/include/plat/gpio-core.h index dac35d0a711..8b5209baa99 100644 --- a/arch/arm/plat-samsung/include/plat/gpio-core.h +++ b/arch/arm/plat-samsung/include/plat/gpio-core.h @@ -68,7 +68,7 @@ struct s3c_gpio_chip { int irq_base; int group; spinlock_t lock; -#ifdef CONFIG_PM +#ifdef CONFIG_SUSPEND u32 pm_save[4]; #endif }; @@ -153,7 +153,7 @@ static inline struct s3c_gpio_chip *s3c_gpiolib_getchip(unsigned int chip) static inline void s3c_gpiolib_track(struct s3c_gpio_chip *chip) { } #endif -#ifdef CONFIG_PM +#ifdef CONFIG_SUSPEND extern struct s3c_gpio_pm s3c_gpio_pm_1bit; extern struct s3c_gpio_pm s3c_gpio_pm_2bit; extern struct s3c_gpio_pm s3c_gpio_pm_4bit; @@ -164,7 +164,7 @@ extern struct s3c_gpio_pm s3c_gpio_pm_4bit; #define s3c_gpio_pm_4bit NULL #define __gpio_pm(x) NULL -#endif /* CONFIG_PM */ +#endif /* CONFIG_SUSPEND */ /* locking wrappers to deal with multiple access to the same gpio bank */ #define s3c_gpio_lock(_oc, _fl) spin_lock_irqsave(&(_oc)->lock, _fl) diff --git a/arch/arm/plat-samsung/include/plat/pm.h b/arch/arm/plat-samsung/include/plat/pm.h index 30518cc9a67..69f4cc8b31f 100644 --- a/arch/arm/plat-samsung/include/plat/pm.h +++ b/arch/arm/plat-samsung/include/plat/pm.h @@ -19,7 +19,7 @@ struct sys_device; -#ifdef CONFIG_PM +#ifdef CONFIG_SUSPEND extern __init int s3c_pm_init(void); @@ -103,7 +103,7 @@ extern void s3c_pm_do_save(struct sleep_save *ptr, int count); extern void s3c_pm_do_restore(struct sleep_save *ptr, int count); extern void s3c_pm_do_restore_core(struct sleep_save *ptr, int count); -#ifdef CONFIG_PM +#ifdef CONFIG_SUSPEND extern int s3c_irqext_wake(struct irq_data *data, unsigned int state); extern int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state); extern int s3c24xx_irq_resume(struct sys_device *dev); diff --git a/arch/arm/plat-samsung/pwm.c b/arch/arm/plat-samsung/pwm.c index 2eeb49fa056..926f08d331c 100644 --- a/arch/arm/plat-samsung/pwm.c +++ b/arch/arm/plat-samsung/pwm.c @@ -380,7 +380,7 @@ static int __devexit s3c_pwm_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM +#ifdef CONFIG_SUSPEND static int s3c_pwm_suspend(struct platform_device *pdev, pm_message_t state) { struct pwm_device *pwm = platform_get_drvdata(pdev); diff --git a/arch/arm/plat-spear/include/plat/memory.h b/arch/arm/plat-spear/include/plat/memory.h index 27a4aba7734..7e3599e1104 100644 --- a/arch/arm/plat-spear/include/plat/memory.h +++ b/arch/arm/plat-spear/include/plat/memory.h @@ -15,6 +15,6 @@ #define __PLAT_MEMORY_H /* Physical DRAM offset */ -#define PHYS_OFFSET UL(0x00000000) +#define PLAT_PHYS_OFFSET UL(0x00000000) #endif /* __PLAT_MEMORY_H */ diff --git a/arch/arm/plat-stmp3xxx/include/mach/memory.h b/arch/arm/plat-stmp3xxx/include/mach/memory.h index 7b875a07a1a..61fa54882e1 100644 --- a/arch/arm/plat-stmp3xxx/include/mach/memory.h +++ b/arch/arm/plat-stmp3xxx/include/mach/memory.h @@ -17,6 +17,6 @@ /* * Physical DRAM offset. */ -#define PHYS_OFFSET UL(0x40000000) +#define PLAT_PHYS_OFFSET UL(0x40000000) #endif diff --git a/arch/arm/plat-tcc/include/mach/memory.h b/arch/arm/plat-tcc/include/mach/memory.h index cd91ba8a670..28a6e0cd13b 100644 --- a/arch/arm/plat-tcc/include/mach/memory.h +++ b/arch/arm/plat-tcc/include/mach/memory.h @@ -13,6 +13,6 @@ /* * Physical DRAM offset. */ -#define PHYS_OFFSET UL(0x20000000) +#define PLAT_PHYS_OFFSET UL(0x20000000) #endif diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index 0797cb528b4..bbf3da012af 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c @@ -153,7 +153,7 @@ static struct notifier_block vfp_notifier_block = { * Raise a SIGFPE for the current process. * sicode describes the signal being raised. */ -void vfp_raise_sigfpe(unsigned int sicode, struct pt_regs *regs) +static void vfp_raise_sigfpe(unsigned int sicode, struct pt_regs *regs) { siginfo_t info; @@ -489,8 +489,11 @@ void vfp_flush_hwstate(struct thread_info *thread) /* * VFP hardware can lose all context when a CPU goes offline. - * Safely clear our held state when a CPU has been killed, and - * re-enable access to VFP when the CPU comes back online. + * As we will be running in SMP mode with CPU hotplug, we will save the + * hardware state at every thread switch. We clear our held state when + * a CPU has been killed, indicating that the VFP hardware doesn't contain + * a threads VFP state. When a CPU starts up, we re-enable access to the + * VFP hardware. * * Both CPU_DYING and CPU_STARTING are called on the CPU which * is being offlined/onlined. |