From 5bd9dd450173bc1464e8218e717d218075b9f1a4 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Wed, 9 May 2012 16:03:06 +1000 Subject: m68k: use some direct calls to ret_from_exception in entry code The ret_from_excption code is referenced by its function name, or by a label set at the start of its code. The non-MMU code can share some of this code if we make direct calls to ret_from_exception instead of the associated label. The effected function paths are: buserr, trap and ret_from_fork. So change these to branch directly to ret_from_exception. Signed-off-by: Greg Ungerer Acked-by: Geert Uytterhoeven --- arch/m68k/kernel/entry_mm.S | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch/m68k') diff --git a/arch/m68k/kernel/entry_mm.S b/arch/m68k/kernel/entry_mm.S index f29e73ca9dbb..ff75368b18ee 100644 --- a/arch/m68k/kernel/entry_mm.S +++ b/arch/m68k/kernel/entry_mm.S @@ -57,7 +57,7 @@ ENTRY(buserr) movel %sp,%sp@- | stack frame pointer argument bsrl buserr_c addql #4,%sp - jra .Lret_from_exception + jra ret_from_exception ENTRY(trap) SAVE_ALL_INT @@ -65,7 +65,7 @@ ENTRY(trap) movel %sp,%sp@- | stack frame pointer argument bsrl trap_c addql #4,%sp - jra .Lret_from_exception + jra ret_from_exception | After a fork we jump here directly from resume, | so that %d1 contains the previous task @@ -74,7 +74,7 @@ ENTRY(ret_from_fork) movel %d1,%sp@- jsr schedule_tail addql #4,%sp - jra .Lret_from_exception + jra ret_from_exception do_trace_entry: movel #-ENOSYS,%sp@(PT_OFF_D0)| needed for strace -- cgit v1.2.3 From 28d5445e94ab22198921b5c0c3e58c3b4a1a0116 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Wed, 9 May 2012 16:59:46 +1000 Subject: m68k: use jbsr to call functions instead of bsrl There is a few places that the m68k entry code uses the bsrl instruction to call other functions. That instruction is only supported on 68020 and higher CPU types. If we use jbsr instead the code will be clean for all 68k and ColdFire CPU types. Signed-off-by: Greg Ungerer Acked-by: Geert Uytterhoeven --- arch/m68k/kernel/entry_mm.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/m68k') diff --git a/arch/m68k/kernel/entry_mm.S b/arch/m68k/kernel/entry_mm.S index ff75368b18ee..1055a6e40e41 100644 --- a/arch/m68k/kernel/entry_mm.S +++ b/arch/m68k/kernel/entry_mm.S @@ -55,7 +55,7 @@ ENTRY(buserr) SAVE_ALL_INT GET_CURRENT(%d0) movel %sp,%sp@- | stack frame pointer argument - bsrl buserr_c + jbsr buserr_c addql #4,%sp jra ret_from_exception @@ -63,7 +63,7 @@ ENTRY(trap) SAVE_ALL_INT GET_CURRENT(%d0) movel %sp,%sp@- | stack frame pointer argument - bsrl trap_c + jbsr trap_c addql #4,%sp jra ret_from_exception -- cgit v1.2.3 From 14be4252eae2ce40abec5872bf6011891d753433 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Wed, 9 May 2012 17:05:24 +1000 Subject: m68k: merge the MMU and non-MMU versions of the entry.S code Some of the entry.S code is common to both MMU and non-MMU builds. So merge the entry_no.S and entry_mm.S files back into a single file. With a little code movement we only need a single #ifdef. Signed-off-by: Greg Ungerer Acked-by: Geert Uytterhoeven --- arch/m68k/kernel/entry.S | 452 +++++++++++++++++++++++++++++++++++++++++++- arch/m68k/kernel/entry_mm.S | 419 ---------------------------------------- arch/m68k/kernel/entry_no.S | 130 ------------- 3 files changed, 449 insertions(+), 552 deletions(-) delete mode 100644 arch/m68k/kernel/entry_mm.S delete mode 100644 arch/m68k/kernel/entry_no.S (limited to 'arch/m68k') diff --git a/arch/m68k/kernel/entry.S b/arch/m68k/kernel/entry.S index b8daf64e347d..165ee9f9d5c9 100644 --- a/arch/m68k/kernel/entry.S +++ b/arch/m68k/kernel/entry.S @@ -1,5 +1,451 @@ -#if defined(CONFIG_MMU) && !defined(CONFIG_COLDFIRE) -#include "entry_mm.S" +/* -*- mode: asm -*- + * + * linux/arch/m68k/kernel/entry.S + * + * Copyright (C) 1991, 1992 Linus Torvalds + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file README.legal in the main directory of this archive + * for more details. + * + * Linux/m68k support by Hamish Macdonald + * + * 68060 fixes by Jesper Skov + * + */ + +/* + * entry.S contains the system-call and fault low-level handling routines. + * This also contains the timer-interrupt handler, as well as all interrupts + * and faults that can result in a task-switch. + * + * NOTE: This code handles signal-recognition, which happens every time + * after a timer-interrupt and after each system call. + * + */ + +/* + * 12/03/96 Jes: Currently we only support m68k single-cpu systems, so + * all pointers that used to be 'current' are now entry + * number 0 in the 'current_set' list. + * + * 6/05/00 RZ: addedd writeback completion after return from sighandler + * for 68040 + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +.globl system_call, buserr, trap, resume +.globl sys_call_table +.globl sys_fork, sys_clone, sys_vfork +.globl ret_from_interrupt, bad_interrupt +.globl auto_irqhandler_fixup +.globl user_irqvec_fixup + +.text +ENTRY(sys_fork) + SAVE_SWITCH_STACK + pea %sp@(SWITCH_STACK_SIZE) + jbsr m68k_fork + addql #4,%sp + RESTORE_SWITCH_STACK + rts + +ENTRY(sys_clone) + SAVE_SWITCH_STACK + pea %sp@(SWITCH_STACK_SIZE) + jbsr m68k_clone + addql #4,%sp + RESTORE_SWITCH_STACK + rts + +ENTRY(sys_vfork) + SAVE_SWITCH_STACK + pea %sp@(SWITCH_STACK_SIZE) + jbsr m68k_vfork + addql #4,%sp + RESTORE_SWITCH_STACK + rts + +ENTRY(sys_sigreturn) + SAVE_SWITCH_STACK + jbsr do_sigreturn + RESTORE_SWITCH_STACK + rts + +ENTRY(sys_rt_sigreturn) + SAVE_SWITCH_STACK + jbsr do_rt_sigreturn + RESTORE_SWITCH_STACK + rts + +ENTRY(buserr) + SAVE_ALL_INT + GET_CURRENT(%d0) + movel %sp,%sp@- | stack frame pointer argument + jbsr buserr_c + addql #4,%sp + jra ret_from_exception + +ENTRY(trap) + SAVE_ALL_INT + GET_CURRENT(%d0) + movel %sp,%sp@- | stack frame pointer argument + jbsr trap_c + addql #4,%sp + jra ret_from_exception + + | After a fork we jump here directly from resume, + | so that %d1 contains the previous task + | schedule_tail now used regardless of CONFIG_SMP +ENTRY(ret_from_fork) + movel %d1,%sp@- + jsr schedule_tail + addql #4,%sp + jra ret_from_exception + +#if defined(CONFIG_COLDFIRE) || !defined(CONFIG_MMU) + +#ifdef TRAP_DBG_INTERRUPT + +.globl dbginterrupt +ENTRY(dbginterrupt) + SAVE_ALL_INT + GET_CURRENT(%d0) + movel %sp,%sp@- /* stack frame pointer argument */ + jsr dbginterrupt_c + addql #4,%sp + jra ret_from_exception +#endif + +ENTRY(reschedule) + /* save top of frame */ + pea %sp@ + jbsr set_esp0 + addql #4,%sp + pea ret_from_exception + jmp schedule + +ENTRY(ret_from_user_signal) + moveq #__NR_sigreturn,%d0 + trap #0 + +ENTRY(ret_from_user_rt_signal) + movel #__NR_rt_sigreturn,%d0 + trap #0 + #else -#include "entry_no.S" + +do_trace_entry: + movel #-ENOSYS,%sp@(PT_OFF_D0)| needed for strace + subql #4,%sp + SAVE_SWITCH_STACK + jbsr syscall_trace + RESTORE_SWITCH_STACK + addql #4,%sp + movel %sp@(PT_OFF_ORIG_D0),%d0 + cmpl #NR_syscalls,%d0 + jcs syscall +badsys: + movel #-ENOSYS,%sp@(PT_OFF_D0) + jra ret_from_syscall + +do_trace_exit: + subql #4,%sp + SAVE_SWITCH_STACK + jbsr syscall_trace + RESTORE_SWITCH_STACK + addql #4,%sp + jra .Lret_from_exception + +ENTRY(ret_from_signal) + movel %curptr@(TASK_STACK),%a1 + tstb %a1@(TINFO_FLAGS+2) + jge 1f + jbsr syscall_trace +1: RESTORE_SWITCH_STACK + addql #4,%sp +/* on 68040 complete pending writebacks if any */ +#ifdef CONFIG_M68040 + bfextu %sp@(PT_OFF_FORMATVEC){#0,#4},%d0 + subql #7,%d0 | bus error frame ? + jbne 1f + movel %sp,%sp@- + jbsr berr_040cleanup + addql #4,%sp +1: +#endif + jra .Lret_from_exception + +ENTRY(system_call) + SAVE_ALL_SYS + + GET_CURRENT(%d1) + movel %d1,%a1 + + | save top of frame + movel %sp,%curptr@(TASK_THREAD+THREAD_ESP0) + + | syscall trace? + tstb %a1@(TINFO_FLAGS+2) + jmi do_trace_entry + cmpl #NR_syscalls,%d0 + jcc badsys +syscall: + jbsr @(sys_call_table,%d0:l:4)@(0) + movel %d0,%sp@(PT_OFF_D0) | save the return value +ret_from_syscall: + |oriw #0x0700,%sr + movel %curptr@(TASK_STACK),%a1 + movew %a1@(TINFO_FLAGS+2),%d0 + jne syscall_exit_work +1: RESTORE_ALL + +syscall_exit_work: + btst #5,%sp@(PT_OFF_SR) | check if returning to kernel + bnes 1b | if so, skip resched, signals + lslw #1,%d0 + jcs do_trace_exit + jmi do_delayed_trace + lslw #8,%d0 + jne do_signal_return + pea resume_userspace + jra schedule + + +ENTRY(ret_from_exception) +.Lret_from_exception: + btst #5,%sp@(PT_OFF_SR) | check if returning to kernel + bnes 1f | if so, skip resched, signals + | only allow interrupts when we are really the last one on the + | kernel stack, otherwise stack overflow can occur during + | heavy interrupt load + andw #ALLOWINT,%sr + +resume_userspace: + movel %curptr@(TASK_STACK),%a1 + moveb %a1@(TINFO_FLAGS+3),%d0 + jne exit_work +1: RESTORE_ALL + +exit_work: + | save top of frame + movel %sp,%curptr@(TASK_THREAD+THREAD_ESP0) + lslb #1,%d0 + jne do_signal_return + pea resume_userspace + jra schedule + + +do_signal_return: + |andw #ALLOWINT,%sr + subql #4,%sp | dummy return address + SAVE_SWITCH_STACK + pea %sp@(SWITCH_STACK_SIZE) + bsrl do_notify_resume + addql #4,%sp + RESTORE_SWITCH_STACK + addql #4,%sp + jbra resume_userspace + +do_delayed_trace: + bclr #7,%sp@(PT_OFF_SR) | clear trace bit in SR + pea 1 | send SIGTRAP + movel %curptr,%sp@- + pea LSIGTRAP + jbsr send_sig + addql #8,%sp + addql #4,%sp + jbra resume_userspace + + +/* This is the main interrupt handler for autovector interrupts */ + +ENTRY(auto_inthandler) + SAVE_ALL_INT + GET_CURRENT(%d0) + movel %d0,%a1 + addqb #1,%a1@(TINFO_PREEMPT+1) + | put exception # in d0 + bfextu %sp@(PT_OFF_FORMATVEC){#4,#10},%d0 + subw #VEC_SPUR,%d0 + + movel %sp,%sp@- + movel %d0,%sp@- | put vector # on stack +auto_irqhandler_fixup = . + 2 + jsr do_IRQ | process the IRQ + addql #8,%sp | pop parameters off stack + +ret_from_interrupt: + movel %curptr@(TASK_STACK),%a1 + subqb #1,%a1@(TINFO_PREEMPT+1) + jeq ret_from_last_interrupt +2: RESTORE_ALL + + ALIGN +ret_from_last_interrupt: + moveq #(~ALLOWINT>>8)&0xff,%d0 + andb %sp@(PT_OFF_SR),%d0 + jne 2b + + /* check if we need to do software interrupts */ + tstl irq_stat+CPUSTAT_SOFTIRQ_PENDING + jeq .Lret_from_exception + pea ret_from_exception + jra do_softirq + +/* Handler for user defined interrupt vectors */ + +ENTRY(user_inthandler) + SAVE_ALL_INT + GET_CURRENT(%d0) + movel %d0,%a1 + addqb #1,%a1@(TINFO_PREEMPT+1) + | put exception # in d0 + bfextu %sp@(PT_OFF_FORMATVEC){#4,#10},%d0 +user_irqvec_fixup = . + 2 + subw #VEC_USER,%d0 + + movel %sp,%sp@- + movel %d0,%sp@- | put vector # on stack + jsr do_IRQ | process the IRQ + addql #8,%sp | pop parameters off stack + + movel %curptr@(TASK_STACK),%a1 + subqb #1,%a1@(TINFO_PREEMPT+1) + jeq ret_from_last_interrupt + RESTORE_ALL + +/* Handler for uninitialized and spurious interrupts */ + +ENTRY(bad_inthandler) + SAVE_ALL_INT + GET_CURRENT(%d0) + movel %d0,%a1 + addqb #1,%a1@(TINFO_PREEMPT+1) + + movel %sp,%sp@- + jsr handle_badint + addql #4,%sp + + movel %curptr@(TASK_STACK),%a1 + subqb #1,%a1@(TINFO_PREEMPT+1) + jeq ret_from_last_interrupt + RESTORE_ALL + + +resume: + /* + * Beware - when entering resume, prev (the current task) is + * in a0, next (the new task) is in a1,so don't change these + * registers until their contents are no longer needed. + */ + + /* save sr */ + movew %sr,%a0@(TASK_THREAD+THREAD_SR) + + /* save fs (sfc,%dfc) (may be pointing to kernel memory) */ + movec %sfc,%d0 + movew %d0,%a0@(TASK_THREAD+THREAD_FS) + + /* save usp */ + /* it is better to use a movel here instead of a movew 8*) */ + movec %usp,%d0 + movel %d0,%a0@(TASK_THREAD+THREAD_USP) + + /* save non-scratch registers on stack */ + SAVE_SWITCH_STACK + + /* save current kernel stack pointer */ + movel %sp,%a0@(TASK_THREAD+THREAD_KSP) + + /* save floating point context */ +#ifndef CONFIG_M68KFPU_EMU_ONLY +#ifdef CONFIG_M68KFPU_EMU + tstl m68k_fputype + jeq 3f +#endif + fsave %a0@(TASK_THREAD+THREAD_FPSTATE) + +#if defined(CONFIG_M68060) +#if !defined(CPU_M68060_ONLY) + btst #3,m68k_cputype+3 + beqs 1f +#endif + /* The 060 FPU keeps status in bits 15-8 of the first longword */ + tstb %a0@(TASK_THREAD+THREAD_FPSTATE+2) + jeq 3f +#if !defined(CPU_M68060_ONLY) + jra 2f +#endif +#endif /* CONFIG_M68060 */ +#if !defined(CPU_M68060_ONLY) +1: tstb %a0@(TASK_THREAD+THREAD_FPSTATE) + jeq 3f +#endif +2: fmovemx %fp0-%fp7,%a0@(TASK_THREAD+THREAD_FPREG) + fmoveml %fpcr/%fpsr/%fpiar,%a0@(TASK_THREAD+THREAD_FPCNTL) +3: +#endif /* CONFIG_M68KFPU_EMU_ONLY */ + /* Return previous task in %d1 */ + movel %curptr,%d1 + + /* switch to new task (a1 contains new task) */ + movel %a1,%curptr + + /* restore floating point context */ +#ifndef CONFIG_M68KFPU_EMU_ONLY +#ifdef CONFIG_M68KFPU_EMU + tstl m68k_fputype + jeq 4f +#endif +#if defined(CONFIG_M68060) +#if !defined(CPU_M68060_ONLY) + btst #3,m68k_cputype+3 + beqs 1f +#endif + /* The 060 FPU keeps status in bits 15-8 of the first longword */ + tstb %a1@(TASK_THREAD+THREAD_FPSTATE+2) + jeq 3f +#if !defined(CPU_M68060_ONLY) + jra 2f +#endif +#endif /* CONFIG_M68060 */ +#if !defined(CPU_M68060_ONLY) +1: tstb %a1@(TASK_THREAD+THREAD_FPSTATE) + jeq 3f #endif +2: fmovemx %a1@(TASK_THREAD+THREAD_FPREG),%fp0-%fp7 + fmoveml %a1@(TASK_THREAD+THREAD_FPCNTL),%fpcr/%fpsr/%fpiar +3: frestore %a1@(TASK_THREAD+THREAD_FPSTATE) +4: +#endif /* CONFIG_M68KFPU_EMU_ONLY */ + + /* restore the kernel stack pointer */ + movel %a1@(TASK_THREAD+THREAD_KSP),%sp + + /* restore non-scratch registers */ + RESTORE_SWITCH_STACK + + /* restore user stack pointer */ + movel %a1@(TASK_THREAD+THREAD_USP),%a0 + movel %a0,%usp + + /* restore fs (sfc,%dfc) */ + movew %a1@(TASK_THREAD+THREAD_FS),%a0 + movec %a0,%sfc + movec %a0,%dfc + + /* restore status register */ + movew %a1@(TASK_THREAD+THREAD_SR),%sr + + rts + +#endif /* CONFIG_MMU && !CONFIG_COLDFIRE */ diff --git a/arch/m68k/kernel/entry_mm.S b/arch/m68k/kernel/entry_mm.S deleted file mode 100644 index 1055a6e40e41..000000000000 --- a/arch/m68k/kernel/entry_mm.S +++ /dev/null @@ -1,419 +0,0 @@ -/* -*- mode: asm -*- - * - * linux/arch/m68k/kernel/entry.S - * - * Copyright (C) 1991, 1992 Linus Torvalds - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file README.legal in the main directory of this archive - * for more details. - * - * Linux/m68k support by Hamish Macdonald - * - * 68060 fixes by Jesper Skov - * - */ - -/* - * entry.S contains the system-call and fault low-level handling routines. - * This also contains the timer-interrupt handler, as well as all interrupts - * and faults that can result in a task-switch. - * - * NOTE: This code handles signal-recognition, which happens every time - * after a timer-interrupt and after each system call. - * - */ - -/* - * 12/03/96 Jes: Currently we only support m68k single-cpu systems, so - * all pointers that used to be 'current' are now entry - * number 0 in the 'current_set' list. - * - * 6/05/00 RZ: addedd writeback completion after return from sighandler - * for 68040 - */ - -#include -#include -#include -#include -#include -#include -#include - -#include - -.globl system_call, buserr, trap, resume -.globl sys_call_table -.globl sys_fork, sys_clone, sys_vfork -.globl ret_from_interrupt, bad_interrupt -.globl auto_irqhandler_fixup -.globl user_irqvec_fixup - -.text -ENTRY(buserr) - SAVE_ALL_INT - GET_CURRENT(%d0) - movel %sp,%sp@- | stack frame pointer argument - jbsr buserr_c - addql #4,%sp - jra ret_from_exception - -ENTRY(trap) - SAVE_ALL_INT - GET_CURRENT(%d0) - movel %sp,%sp@- | stack frame pointer argument - jbsr trap_c - addql #4,%sp - jra ret_from_exception - - | After a fork we jump here directly from resume, - | so that %d1 contains the previous task - | schedule_tail now used regardless of CONFIG_SMP -ENTRY(ret_from_fork) - movel %d1,%sp@- - jsr schedule_tail - addql #4,%sp - jra ret_from_exception - -do_trace_entry: - movel #-ENOSYS,%sp@(PT_OFF_D0)| needed for strace - subql #4,%sp - SAVE_SWITCH_STACK - jbsr syscall_trace - RESTORE_SWITCH_STACK - addql #4,%sp - movel %sp@(PT_OFF_ORIG_D0),%d0 - cmpl #NR_syscalls,%d0 - jcs syscall -badsys: - movel #-ENOSYS,%sp@(PT_OFF_D0) - jra ret_from_syscall - -do_trace_exit: - subql #4,%sp - SAVE_SWITCH_STACK - jbsr syscall_trace - RESTORE_SWITCH_STACK - addql #4,%sp - jra .Lret_from_exception - -ENTRY(ret_from_signal) - movel %curptr@(TASK_STACK),%a1 - tstb %a1@(TINFO_FLAGS+2) - jge 1f - jbsr syscall_trace -1: RESTORE_SWITCH_STACK - addql #4,%sp -/* on 68040 complete pending writebacks if any */ -#ifdef CONFIG_M68040 - bfextu %sp@(PT_OFF_FORMATVEC){#0,#4},%d0 - subql #7,%d0 | bus error frame ? - jbne 1f - movel %sp,%sp@- - jbsr berr_040cleanup - addql #4,%sp -1: -#endif - jra .Lret_from_exception - -ENTRY(system_call) - SAVE_ALL_SYS - - GET_CURRENT(%d1) - movel %d1,%a1 - - | save top of frame - movel %sp,%curptr@(TASK_THREAD+THREAD_ESP0) - - | syscall trace? - tstb %a1@(TINFO_FLAGS+2) - jmi do_trace_entry - cmpl #NR_syscalls,%d0 - jcc badsys -syscall: - jbsr @(sys_call_table,%d0:l:4)@(0) - movel %d0,%sp@(PT_OFF_D0) | save the return value -ret_from_syscall: - |oriw #0x0700,%sr - movel %curptr@(TASK_STACK),%a1 - movew %a1@(TINFO_FLAGS+2),%d0 - jne syscall_exit_work -1: RESTORE_ALL - -syscall_exit_work: - btst #5,%sp@(PT_OFF_SR) | check if returning to kernel - bnes 1b | if so, skip resched, signals - lslw #1,%d0 - jcs do_trace_exit - jmi do_delayed_trace - lslw #8,%d0 - jne do_signal_return - pea resume_userspace - jra schedule - - -ENTRY(ret_from_exception) -.Lret_from_exception: - btst #5,%sp@(PT_OFF_SR) | check if returning to kernel - bnes 1f | if so, skip resched, signals - | only allow interrupts when we are really the last one on the - | kernel stack, otherwise stack overflow can occur during - | heavy interrupt load - andw #ALLOWINT,%sr - -resume_userspace: - movel %curptr@(TASK_STACK),%a1 - moveb %a1@(TINFO_FLAGS+3),%d0 - jne exit_work -1: RESTORE_ALL - -exit_work: - | save top of frame - movel %sp,%curptr@(TASK_THREAD+THREAD_ESP0) - lslb #1,%d0 - jne do_signal_return - pea resume_userspace - jra schedule - - -do_signal_return: - |andw #ALLOWINT,%sr - subql #4,%sp | dummy return address - SAVE_SWITCH_STACK - pea %sp@(SWITCH_STACK_SIZE) - bsrl do_notify_resume - addql #4,%sp - RESTORE_SWITCH_STACK - addql #4,%sp - jbra resume_userspace - -do_delayed_trace: - bclr #7,%sp@(PT_OFF_SR) | clear trace bit in SR - pea 1 | send SIGTRAP - movel %curptr,%sp@- - pea LSIGTRAP - jbsr send_sig - addql #8,%sp - addql #4,%sp - jbra resume_userspace - - -/* This is the main interrupt handler for autovector interrupts */ - -ENTRY(auto_inthandler) - SAVE_ALL_INT - GET_CURRENT(%d0) - movel %d0,%a1 - addqb #1,%a1@(TINFO_PREEMPT+1) - | put exception # in d0 - bfextu %sp@(PT_OFF_FORMATVEC){#4,#10},%d0 - subw #VEC_SPUR,%d0 - - movel %sp,%sp@- - movel %d0,%sp@- | put vector # on stack -auto_irqhandler_fixup = . + 2 - jsr do_IRQ | process the IRQ - addql #8,%sp | pop parameters off stack - -ret_from_interrupt: - movel %curptr@(TASK_STACK),%a1 - subqb #1,%a1@(TINFO_PREEMPT+1) - jeq ret_from_last_interrupt -2: RESTORE_ALL - - ALIGN -ret_from_last_interrupt: - moveq #(~ALLOWINT>>8)&0xff,%d0 - andb %sp@(PT_OFF_SR),%d0 - jne 2b - - /* check if we need to do software interrupts */ - tstl irq_stat+CPUSTAT_SOFTIRQ_PENDING - jeq .Lret_from_exception - pea ret_from_exception - jra do_softirq - -/* Handler for user defined interrupt vectors */ - -ENTRY(user_inthandler) - SAVE_ALL_INT - GET_CURRENT(%d0) - movel %d0,%a1 - addqb #1,%a1@(TINFO_PREEMPT+1) - | put exception # in d0 - bfextu %sp@(PT_OFF_FORMATVEC){#4,#10},%d0 -user_irqvec_fixup = . + 2 - subw #VEC_USER,%d0 - - movel %sp,%sp@- - movel %d0,%sp@- | put vector # on stack - jsr do_IRQ | process the IRQ - addql #8,%sp | pop parameters off stack - - movel %curptr@(TASK_STACK),%a1 - subqb #1,%a1@(TINFO_PREEMPT+1) - jeq ret_from_last_interrupt - RESTORE_ALL - -/* Handler for uninitialized and spurious interrupts */ - -ENTRY(bad_inthandler) - SAVE_ALL_INT - GET_CURRENT(%d0) - movel %d0,%a1 - addqb #1,%a1@(TINFO_PREEMPT+1) - - movel %sp,%sp@- - jsr handle_badint - addql #4,%sp - - movel %curptr@(TASK_STACK),%a1 - subqb #1,%a1@(TINFO_PREEMPT+1) - jeq ret_from_last_interrupt - RESTORE_ALL - - -ENTRY(sys_fork) - SAVE_SWITCH_STACK - pea %sp@(SWITCH_STACK_SIZE) - jbsr m68k_fork - addql #4,%sp - RESTORE_SWITCH_STACK - rts - -ENTRY(sys_clone) - SAVE_SWITCH_STACK - pea %sp@(SWITCH_STACK_SIZE) - jbsr m68k_clone - addql #4,%sp - RESTORE_SWITCH_STACK - rts - -ENTRY(sys_vfork) - SAVE_SWITCH_STACK - pea %sp@(SWITCH_STACK_SIZE) - jbsr m68k_vfork - addql #4,%sp - RESTORE_SWITCH_STACK - rts - -ENTRY(sys_sigreturn) - SAVE_SWITCH_STACK - jbsr do_sigreturn - RESTORE_SWITCH_STACK - rts - -ENTRY(sys_rt_sigreturn) - SAVE_SWITCH_STACK - jbsr do_rt_sigreturn - RESTORE_SWITCH_STACK - rts - -resume: - /* - * Beware - when entering resume, prev (the current task) is - * in a0, next (the new task) is in a1,so don't change these - * registers until their contents are no longer needed. - */ - - /* save sr */ - movew %sr,%a0@(TASK_THREAD+THREAD_SR) - - /* save fs (sfc,%dfc) (may be pointing to kernel memory) */ - movec %sfc,%d0 - movew %d0,%a0@(TASK_THREAD+THREAD_FS) - - /* save usp */ - /* it is better to use a movel here instead of a movew 8*) */ - movec %usp,%d0 - movel %d0,%a0@(TASK_THREAD+THREAD_USP) - - /* save non-scratch registers on stack */ - SAVE_SWITCH_STACK - - /* save current kernel stack pointer */ - movel %sp,%a0@(TASK_THREAD+THREAD_KSP) - - /* save floating point context */ -#ifndef CONFIG_M68KFPU_EMU_ONLY -#ifdef CONFIG_M68KFPU_EMU - tstl m68k_fputype - jeq 3f -#endif - fsave %a0@(TASK_THREAD+THREAD_FPSTATE) - -#if defined(CONFIG_M68060) -#if !defined(CPU_M68060_ONLY) - btst #3,m68k_cputype+3 - beqs 1f -#endif - /* The 060 FPU keeps status in bits 15-8 of the first longword */ - tstb %a0@(TASK_THREAD+THREAD_FPSTATE+2) - jeq 3f -#if !defined(CPU_M68060_ONLY) - jra 2f -#endif -#endif /* CONFIG_M68060 */ -#if !defined(CPU_M68060_ONLY) -1: tstb %a0@(TASK_THREAD+THREAD_FPSTATE) - jeq 3f -#endif -2: fmovemx %fp0-%fp7,%a0@(TASK_THREAD+THREAD_FPREG) - fmoveml %fpcr/%fpsr/%fpiar,%a0@(TASK_THREAD+THREAD_FPCNTL) -3: -#endif /* CONFIG_M68KFPU_EMU_ONLY */ - /* Return previous task in %d1 */ - movel %curptr,%d1 - - /* switch to new task (a1 contains new task) */ - movel %a1,%curptr - - /* restore floating point context */ -#ifndef CONFIG_M68KFPU_EMU_ONLY -#ifdef CONFIG_M68KFPU_EMU - tstl m68k_fputype - jeq 4f -#endif -#if defined(CONFIG_M68060) -#if !defined(CPU_M68060_ONLY) - btst #3,m68k_cputype+3 - beqs 1f -#endif - /* The 060 FPU keeps status in bits 15-8 of the first longword */ - tstb %a1@(TASK_THREAD+THREAD_FPSTATE+2) - jeq 3f -#if !defined(CPU_M68060_ONLY) - jra 2f -#endif -#endif /* CONFIG_M68060 */ -#if !defined(CPU_M68060_ONLY) -1: tstb %a1@(TASK_THREAD+THREAD_FPSTATE) - jeq 3f -#endif -2: fmovemx %a1@(TASK_THREAD+THREAD_FPREG),%fp0-%fp7 - fmoveml %a1@(TASK_THREAD+THREAD_FPCNTL),%fpcr/%fpsr/%fpiar -3: frestore %a1@(TASK_THREAD+THREAD_FPSTATE) -4: -#endif /* CONFIG_M68KFPU_EMU_ONLY */ - - /* restore the kernel stack pointer */ - movel %a1@(TASK_THREAD+THREAD_KSP),%sp - - /* restore non-scratch registers */ - RESTORE_SWITCH_STACK - - /* restore user stack pointer */ - movel %a1@(TASK_THREAD+THREAD_USP),%a0 - movel %a0,%usp - - /* restore fs (sfc,%dfc) */ - movew %a1@(TASK_THREAD+THREAD_FS),%a0 - movec %a0,%sfc - movec %a0,%dfc - - /* restore status register */ - movew %a1@(TASK_THREAD+THREAD_SR),%sr - - rts - diff --git a/arch/m68k/kernel/entry_no.S b/arch/m68k/kernel/entry_no.S deleted file mode 100644 index d80cba45589f..000000000000 --- a/arch/m68k/kernel/entry_no.S +++ /dev/null @@ -1,130 +0,0 @@ -/* - * linux/arch/m68knommu/kernel/entry.S - * - * Copyright (C) 1999-2002, Greg Ungerer (gerg@snapgear.com) - * Copyright (C) 1998 D. Jeff Dionne , - * Kenneth Albanowski , - * Copyright (C) 2000 Lineo Inc. (www.lineo.com) - * - * Based on: - * - * linux/arch/m68k/kernel/entry.S - * - * Copyright (C) 1991, 1992 Linus Torvalds - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file README.legal in the main directory of this archive - * for more details. - * - * Linux/m68k support by Hamish Macdonald - * - * 68060 fixes by Jesper Skov - * ColdFire support by Greg Ungerer (gerg@snapgear.com) - * 5307 fixes by David W. Miller - * linux 2.4 support David McCullough - */ - -#include -#include -#include -#include -#include -#include -#include - -.text - -.globl buserr -.globl trap -.globl ret_from_exception -.globl ret_from_signal -.globl sys_fork -.globl sys_clone -.globl sys_vfork - -ENTRY(buserr) - SAVE_ALL_INT - GET_CURRENT(%d0) - movel %sp,%sp@- /* stack frame pointer argument */ - jsr buserr_c - addql #4,%sp - jra ret_from_exception - -ENTRY(trap) - SAVE_ALL_INT - GET_CURRENT(%d0) - movel %sp,%sp@- /* stack frame pointer argument */ - jsr trap_c - addql #4,%sp - jra ret_from_exception - -#ifdef TRAP_DBG_INTERRUPT - -.globl dbginterrupt -ENTRY(dbginterrupt) - SAVE_ALL_INT - GET_CURRENT(%d0) - movel %sp,%sp@- /* stack frame pointer argument */ - jsr dbginterrupt_c - addql #4,%sp - jra ret_from_exception -#endif - -ENTRY(reschedule) - /* save top of frame */ - pea %sp@ - jbsr set_esp0 - addql #4,%sp - pea ret_from_exception - jmp schedule - -ENTRY(ret_from_fork) - movel %d1,%sp@- - jsr schedule_tail - addql #4,%sp - jra ret_from_exception - -ENTRY(sys_fork) - SAVE_SWITCH_STACK - pea %sp@(SWITCH_STACK_SIZE) - jbsr m68k_fork - addql #4,%sp - RESTORE_SWITCH_STACK - rts - -ENTRY(sys_vfork) - SAVE_SWITCH_STACK - pea %sp@(SWITCH_STACK_SIZE) - jbsr m68k_vfork - addql #4,%sp - RESTORE_SWITCH_STACK - rts - -ENTRY(sys_clone) - SAVE_SWITCH_STACK - pea %sp@(SWITCH_STACK_SIZE) - jbsr m68k_clone - addql #4,%sp - RESTORE_SWITCH_STACK - rts - -ENTRY(sys_sigreturn) - SAVE_SWITCH_STACK - jbsr do_sigreturn - RESTORE_SWITCH_STACK - rts - -ENTRY(sys_rt_sigreturn) - SAVE_SWITCH_STACK - jbsr do_rt_sigreturn - RESTORE_SWITCH_STACK - rts - -ENTRY(ret_from_user_signal) - moveq #__NR_sigreturn,%d0 - trap #0 - -ENTRY(ret_from_user_rt_signal) - movel #__NR_rt_sigreturn,%d0 - trap #0 - -- cgit v1.2.3 From eac57949947fa24f47a2e993a1dbbfdb573b4301 Mon Sep 17 00:00:00 2001 From: Steven King Date: Mon, 21 May 2012 13:10:19 -0700 Subject: m68knommu: refactor Coldfire GPIO not to require GPIOLIB, eliminate mcf_gpio_chips. If we're not connecting external GPIO extenders via i2c or spi or whatever, we probably don't need GPIOLIB. If we provide an alternate implementation of the GPIOLIB functions to use when only on-chip GPIO is needed, we can change ARCH_REQUIRE_GPIOLIB to ARCH_WANTS_OPTIONAL_GPIOLIB so that GPIOLIB becomes optional. The downside is that in the GPIOLIB=n case, we lose all error checking done by gpiolib, ie multiply allocating the gpio, free'ing gpio etc., so that the only checking that can be done is if we reference a gpio on an external part. Targets that need the extra error checking can still select GPIOLIB=y. For the case where GPIOLIB=y, we can simplify the table of gpio chips to use a single chip, eliminating the tables of chips in the 5xxx.c files. The original motivation for the definition of multiple chips was to match the way many of the Coldfire variants defined their gpio as a spare array in memory. However, all this really gains us is some error checking when we request a gpio, gpiolib can check that it doesn't fall in one of the holes. If thats important, I think we can still come up with a better way of accomplishing that. Also in this patch is some general cleanup and reorganizing of the gpio header files (I'm sure I must have had a reason why I sometimes used a prefix of mcf_gpio and other times mcfgpio but for the life of me I can't think of it now). Signed-off-by: Steven King Signed-off-by: Greg Ungerer --- arch/m68k/Kconfig.cpu | 2 +- arch/m68k/include/asm/gpio.h | 169 +----------------- arch/m68k/include/asm/mcfgpio.h | 329 +++++++++++++++++++++++++++-------- arch/m68k/include/asm/pinmux.h | 30 ---- arch/m68k/platform/coldfire/Makefile | 2 +- arch/m68k/platform/coldfire/gpio.c | 172 +++++++++++------- arch/m68k/platform/coldfire/m5206.c | 9 - arch/m68k/platform/coldfire/m520x.c | 16 -- arch/m68k/platform/coldfire/m523x.c | 22 --- arch/m68k/platform/coldfire/m5249.c | 10 -- arch/m68k/platform/coldfire/m5272.c | 11 -- arch/m68k/platform/coldfire/m527x.c | 43 ----- arch/m68k/platform/coldfire/m528x.c | 33 +--- arch/m68k/platform/coldfire/m5307.c | 9 - arch/m68k/platform/coldfire/m532x.c | 25 --- arch/m68k/platform/coldfire/m5407.c | 9 - arch/m68k/platform/coldfire/m54xx.c | 7 - arch/m68k/platform/coldfire/pinmux.c | 28 --- 18 files changed, 375 insertions(+), 551 deletions(-) delete mode 100644 arch/m68k/include/asm/pinmux.h delete mode 100644 arch/m68k/platform/coldfire/pinmux.c (limited to 'arch/m68k') diff --git a/arch/m68k/Kconfig.cpu b/arch/m68k/Kconfig.cpu index 2b53254ad994..ff2314d5d934 100644 --- a/arch/m68k/Kconfig.cpu +++ b/arch/m68k/Kconfig.cpu @@ -23,7 +23,7 @@ config M68KCLASSIC config COLDFIRE bool "Coldfire CPU family support" select GENERIC_GPIO - select ARCH_REQUIRE_GPIOLIB + select ARCH_WANT_OPTIONAL_GPIOLIB select ARCH_HAVE_CUSTOM_GPIO_H select CPU_HAS_NO_BITFIELDS select CPU_HAS_NO_MULDIV64 diff --git a/arch/m68k/include/asm/gpio.h b/arch/m68k/include/asm/gpio.h index 00d0071de4c3..530862207ecf 100644 --- a/arch/m68k/include/asm/gpio.h +++ b/arch/m68k/include/asm/gpio.h @@ -17,170 +17,9 @@ #define coldfire_gpio_h #include -#include #include #include - -/* - * The Freescale Coldfire family is quite varied in how they implement GPIO. - * Some parts have 8 bit ports, some have 16bit and some have 32bit; some have - * only one port, others have multiple ports; some have a single data latch - * for both input and output, others have a separate pin data register to read - * input; some require a read-modify-write access to change an output, others - * have set and clear registers for some of the outputs; Some have all the - * GPIOs in a single control area, others have some GPIOs implemented in - * different modules. - * - * This implementation attempts accommodate the differences while presenting - * a generic interface that will optimize to as few instructions as possible. - */ -#if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \ - defined(CONFIG_M520x) || defined(CONFIG_M523x) || \ - defined(CONFIG_M527x) || defined(CONFIG_M528x) || \ - defined(CONFIG_M532x) || defined(CONFIG_M54xx) - -/* These parts have GPIO organized by 8 bit ports */ - -#define MCFGPIO_PORTTYPE u8 -#define MCFGPIO_PORTSIZE 8 -#define mcfgpio_read(port) __raw_readb(port) -#define mcfgpio_write(data, port) __raw_writeb(data, port) - -#elif defined(CONFIG_M5307) || defined(CONFIG_M5407) || defined(CONFIG_M5272) - -/* These parts have GPIO organized by 16 bit ports */ - -#define MCFGPIO_PORTTYPE u16 -#define MCFGPIO_PORTSIZE 16 -#define mcfgpio_read(port) __raw_readw(port) -#define mcfgpio_write(data, port) __raw_writew(data, port) - -#elif defined(CONFIG_M5249) - -/* These parts have GPIO organized by 32 bit ports */ - -#define MCFGPIO_PORTTYPE u32 -#define MCFGPIO_PORTSIZE 32 -#define mcfgpio_read(port) __raw_readl(port) -#define mcfgpio_write(data, port) __raw_writel(data, port) - -#endif - -#define mcfgpio_bit(gpio) (1 << ((gpio) % MCFGPIO_PORTSIZE)) -#define mcfgpio_port(gpio) ((gpio) / MCFGPIO_PORTSIZE) - -#if defined(CONFIG_M520x) || defined(CONFIG_M523x) || \ - defined(CONFIG_M527x) || defined(CONFIG_M528x) || defined(CONFIG_M532x) -/* - * These parts have an 'Edge' Port module (external interrupt/GPIO) which uses - * read-modify-write to change an output and a GPIO module which has separate - * set/clr registers to directly change outputs with a single write access. - */ -#if defined(CONFIG_M528x) -/* - * The 528x also has GPIOs in other modules (GPT, QADC) which use - * read-modify-write as well as those controlled by the EPORT and GPIO modules. - */ -#define MCFGPIO_SCR_START 40 -#else -#define MCFGPIO_SCR_START 8 -#endif - -#define MCFGPIO_SETR_PORT(gpio) (MCFGPIO_SETR + \ - mcfgpio_port(gpio - MCFGPIO_SCR_START)) - -#define MCFGPIO_CLRR_PORT(gpio) (MCFGPIO_CLRR + \ - mcfgpio_port(gpio - MCFGPIO_SCR_START)) -#else - -#define MCFGPIO_SCR_START MCFGPIO_PIN_MAX -/* with MCFGPIO_SCR == MCFGPIO_PIN_MAX, these will be optimized away */ -#define MCFGPIO_SETR_PORT(gpio) 0 -#define MCFGPIO_CLRR_PORT(gpio) 0 - -#endif -/* - * Coldfire specific helper functions - */ - -/* return the port pin data register for a gpio */ -static inline u32 __mcf_gpio_ppdr(unsigned gpio) -{ -#if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \ - defined(CONFIG_M5307) || defined(CONFIG_M5407) - return MCFSIM_PADAT; -#elif defined(CONFIG_M5272) - if (gpio < 16) - return MCFSIM_PADAT; - else if (gpio < 32) - return MCFSIM_PBDAT; - else - return MCFSIM_PCDAT; -#elif defined(CONFIG_M5249) - if (gpio < 32) - return MCFSIM2_GPIOREAD; - else - return MCFSIM2_GPIO1READ; -#elif defined(CONFIG_M520x) || defined(CONFIG_M523x) || \ - defined(CONFIG_M527x) || defined(CONFIG_M528x) || defined(CONFIG_M532x) - if (gpio < 8) - return MCFEPORT_EPPDR; -#if defined(CONFIG_M528x) - else if (gpio < 16) - return MCFGPTA_GPTPORT; - else if (gpio < 24) - return MCFGPTB_GPTPORT; - else if (gpio < 32) - return MCFQADC_PORTQA; - else if (gpio < 40) - return MCFQADC_PORTQB; -#endif - else - return MCFGPIO_PPDR + mcfgpio_port(gpio - MCFGPIO_SCR_START); -#else - return 0; -#endif -} - -/* return the port output data register for a gpio */ -static inline u32 __mcf_gpio_podr(unsigned gpio) -{ -#if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \ - defined(CONFIG_M5307) || defined(CONFIG_M5407) - return MCFSIM_PADAT; -#elif defined(CONFIG_M5272) - if (gpio < 16) - return MCFSIM_PADAT; - else if (gpio < 32) - return MCFSIM_PBDAT; - else - return MCFSIM_PCDAT; -#elif defined(CONFIG_M5249) - if (gpio < 32) - return MCFSIM2_GPIOWRITE; - else - return MCFSIM2_GPIO1WRITE; -#elif defined(CONFIG_M520x) || defined(CONFIG_M523x) || \ - defined(CONFIG_M527x) || defined(CONFIG_M528x) || defined(CONFIG_M532x) - if (gpio < 8) - return MCFEPORT_EPDR; -#if defined(CONFIG_M528x) - else if (gpio < 16) - return MCFGPTA_GPTPORT; - else if (gpio < 24) - return MCFGPTB_GPTPORT; - else if (gpio < 32) - return MCFQADC_PORTQA; - else if (gpio < 40) - return MCFQADC_PORTQB; -#endif - else - return MCFGPIO_PODR + mcfgpio_port(gpio - MCFGPIO_SCR_START); -#else - return 0; -#endif -} - +#include /* * The Generic GPIO functions * @@ -191,7 +30,7 @@ static inline u32 __mcf_gpio_podr(unsigned gpio) static inline int gpio_get_value(unsigned gpio) { if (__builtin_constant_p(gpio) && gpio < MCFGPIO_PIN_MAX) - return mcfgpio_read(__mcf_gpio_ppdr(gpio)) & mcfgpio_bit(gpio); + return mcfgpio_read(__mcfgpio_ppdr(gpio)) & mcfgpio_bit(gpio); else return __gpio_get_value(gpio); } @@ -204,12 +43,12 @@ static inline void gpio_set_value(unsigned gpio, int value) MCFGPIO_PORTTYPE data; local_irq_save(flags); - data = mcfgpio_read(__mcf_gpio_podr(gpio)); + data = mcfgpio_read(__mcfgpio_podr(gpio)); if (value) data |= mcfgpio_bit(gpio); else data &= ~mcfgpio_bit(gpio); - mcfgpio_write(data, __mcf_gpio_podr(gpio)); + mcfgpio_write(data, __mcfgpio_podr(gpio)); local_irq_restore(flags); } else { if (value) diff --git a/arch/m68k/include/asm/mcfgpio.h b/arch/m68k/include/asm/mcfgpio.h index fe468eaa51e0..67ba20ffedbe 100644 --- a/arch/m68k/include/asm/mcfgpio.h +++ b/arch/m68k/include/asm/mcfgpio.h @@ -16,82 +16,275 @@ #ifndef mcfgpio_h #define mcfgpio_h -#include +#ifdef CONFIG_GPIOLIB #include +#else + +int __mcfgpio_get_value(unsigned gpio); +void __mcfgpio_set_value(unsigned gpio, int value); +int __mcfgpio_direction_input(unsigned gpio); +int __mcfgpio_direction_output(unsigned gpio, int value); +int __mcfgpio_request(unsigned gpio); +void __mcfgpio_free(unsigned gpio); + +/* our alternate 'gpiolib' functions */ +static inline int __gpio_get_value(unsigned gpio) +{ + if (gpio < MCFGPIO_PIN_MAX) + return __mcfgpio_get_value(gpio); + else + return -EINVAL; +} + +static inline void __gpio_set_value(unsigned gpio, int value) +{ + if (gpio < MCFGPIO_PIN_MAX) + __mcfgpio_set_value(gpio, value); +} + +static inline int __gpio_cansleep(unsigned gpio) +{ + if (gpio < MCFGPIO_PIN_MAX) + return 0; + else + return -EINVAL; +} + +static inline int __gpio_to_irq(unsigned gpio) +{ + return -EINVAL; +} + +static inline int gpio_direction_input(unsigned gpio) +{ + if (gpio < MCFGPIO_PIN_MAX) + return __mcfgpio_direction_input(gpio); + else + return -EINVAL; +} + +static inline int gpio_direction_output(unsigned gpio, int value) +{ + if (gpio < MCFGPIO_PIN_MAX) + return __mcfgpio_direction_output(gpio, value); + else + return -EINVAL; +} + +static inline int gpio_request(unsigned gpio, const char *label) +{ + if (gpio < MCFGPIO_PIN_MAX) + return __mcfgpio_request(gpio); + else + return -EINVAL; +} + +static inline void gpio_free(unsigned gpio) +{ + if (gpio < MCFGPIO_PIN_MAX) + __mcfgpio_free(gpio); +} + +#endif /* CONFIG_GPIOLIB */ -struct mcf_gpio_chip { - struct gpio_chip gpio_chip; - void __iomem *pddr; - void __iomem *podr; - void __iomem *ppdr; - void __iomem *setr; - void __iomem *clrr; - const u8 *gpio_to_pinmux; -}; - -extern struct mcf_gpio_chip mcf_gpio_chips[]; -extern unsigned int mcf_gpio_chips_size; - -int mcf_gpio_direction_input(struct gpio_chip *, unsigned); -int mcf_gpio_get_value(struct gpio_chip *, unsigned); -int mcf_gpio_direction_output(struct gpio_chip *, unsigned, int); -void mcf_gpio_set_value(struct gpio_chip *, unsigned, int); -void mcf_gpio_set_value_fast(struct gpio_chip *, unsigned, int); -int mcf_gpio_request(struct gpio_chip *, unsigned); -void mcf_gpio_free(struct gpio_chip *, unsigned); /* - * Define macros to ease the pain of setting up the GPIO tables. There - * are two cases we need to deal with here, they cover all currently - * available ColdFire GPIO hardware. There are of course minor differences - * in the layout and number of bits in each ColdFire part, but the macros - * take all that in. + * The Freescale Coldfire family is quite varied in how they implement GPIO. + * Some parts have 8 bit ports, some have 16bit and some have 32bit; some have + * only one port, others have multiple ports; some have a single data latch + * for both input and output, others have a separate pin data register to read + * input; some require a read-modify-write access to change an output, others + * have set and clear registers for some of the outputs; Some have all the + * GPIOs in a single control area, others have some GPIOs implemented in + * different modules. * - * Firstly is the conventional GPIO registers where we toggle individual - * bits in a register, preserving the other bits in the register. For - * lack of a better term I have called this the slow method. + * This implementation attempts accommodate the differences while presenting + * a generic interface that will optimize to as few instructions as possible. */ -#define MCFGPS(mlabel, mbase, mngpio, mpddr, mpodr, mppdr) \ - { \ - .gpio_chip = { \ - .label = #mlabel, \ - .request = mcf_gpio_request, \ - .free = mcf_gpio_free, \ - .direction_input = mcf_gpio_direction_input, \ - .direction_output = mcf_gpio_direction_output,\ - .get = mcf_gpio_get_value, \ - .set = mcf_gpio_set_value, \ - .base = mbase, \ - .ngpio = mngpio, \ - }, \ - .pddr = (void __iomem *) mpddr, \ - .podr = (void __iomem *) mpodr, \ - .ppdr = (void __iomem *) mppdr, \ - } +#if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \ + defined(CONFIG_M520x) || defined(CONFIG_M523x) || \ + defined(CONFIG_M527x) || defined(CONFIG_M528x) || \ + defined(CONFIG_M532x) || defined(CONFIG_M54xx) + +/* These parts have GPIO organized by 8 bit ports */ + +#define MCFGPIO_PORTTYPE u8 +#define MCFGPIO_PORTSIZE 8 +#define mcfgpio_read(port) __raw_readb(port) +#define mcfgpio_write(data, port) __raw_writeb(data, port) + +#elif defined(CONFIG_M5307) || defined(CONFIG_M5407) || defined(CONFIG_M5272) + +/* These parts have GPIO organized by 16 bit ports */ + +#define MCFGPIO_PORTTYPE u16 +#define MCFGPIO_PORTSIZE 16 +#define mcfgpio_read(port) __raw_readw(port) +#define mcfgpio_write(data, port) __raw_writew(data, port) + +#elif defined(CONFIG_M5249) + +/* These parts have GPIO organized by 32 bit ports */ + +#define MCFGPIO_PORTTYPE u32 +#define MCFGPIO_PORTSIZE 32 +#define mcfgpio_read(port) __raw_readl(port) +#define mcfgpio_write(data, port) __raw_writel(data, port) + +#endif +#define mcfgpio_bit(gpio) (1 << ((gpio) % MCFGPIO_PORTSIZE)) +#define mcfgpio_port(gpio) ((gpio) / MCFGPIO_PORTSIZE) + +#if defined(CONFIG_M520x) || defined(CONFIG_M523x) || \ + defined(CONFIG_M527x) || defined(CONFIG_M528x) || defined(CONFIG_M532x) +/* + * These parts have an 'Edge' Port module (external interrupt/GPIO) which uses + * read-modify-write to change an output and a GPIO module which has separate + * set/clr registers to directly change outputs with a single write access. + */ +#if defined(CONFIG_M528x) /* - * Secondly is the faster case, where we have set and clear registers - * that allow us to set or clear a bit with a single write, not having - * to worry about preserving other bits. + * The 528x also has GPIOs in other modules (GPT, QADC) which use + * read-modify-write as well as those controlled by the EPORT and GPIO modules. */ -#define MCFGPF(mlabel, mbase, mngpio) \ - { \ - .gpio_chip = { \ - .label = #mlabel, \ - .request = mcf_gpio_request, \ - .free = mcf_gpio_free, \ - .direction_input = mcf_gpio_direction_input, \ - .direction_output = mcf_gpio_direction_output,\ - .get = mcf_gpio_get_value, \ - .set = mcf_gpio_set_value_fast, \ - .base = mbase, \ - .ngpio = mngpio, \ - }, \ - .pddr = (void __iomem *) MCFGPIO_PDDR_##mlabel, \ - .podr = (void __iomem *) MCFGPIO_PODR_##mlabel, \ - .ppdr = (void __iomem *) MCFGPIO_PPDSDR_##mlabel, \ - .setr = (void __iomem *) MCFGPIO_PPDSDR_##mlabel, \ - .clrr = (void __iomem *) MCFGPIO_PCLRR_##mlabel, \ - } +#define MCFGPIO_SCR_START 40 +#else +#define MCFGPIO_SCR_START 8 +#endif + +#define MCFGPIO_SETR_PORT(gpio) (MCFGPIO_SETR + \ + mcfgpio_port(gpio - MCFGPIO_SCR_START)) + +#define MCFGPIO_CLRR_PORT(gpio) (MCFGPIO_CLRR + \ + mcfgpio_port(gpio - MCFGPIO_SCR_START)) +#else + +#define MCFGPIO_SCR_START MCFGPIO_PIN_MAX +/* with MCFGPIO_SCR == MCFGPIO_PIN_MAX, these will be optimized away */ +#define MCFGPIO_SETR_PORT(gpio) 0 +#define MCFGPIO_CLRR_PORT(gpio) 0 #endif +/* + * Coldfire specific helper functions + */ + +/* return the port pin data register for a gpio */ +static inline u32 __mcfgpio_ppdr(unsigned gpio) +{ +#if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \ + defined(CONFIG_M5307) || defined(CONFIG_M5407) + return MCFSIM_PADAT; +#elif defined(CONFIG_M5272) + if (gpio < 16) + return MCFSIM_PADAT; + else if (gpio < 32) + return MCFSIM_PBDAT; + else + return MCFSIM_PCDAT; +#elif defined(CONFIG_M5249) + if (gpio < 32) + return MCFSIM2_GPIOREAD; + else + return MCFSIM2_GPIO1READ; +#elif defined(CONFIG_M520x) || defined(CONFIG_M523x) || \ + defined(CONFIG_M527x) || defined(CONFIG_M528x) || defined(CONFIG_M532x) + if (gpio < 8) + return MCFEPORT_EPPDR; +#if defined(CONFIG_M528x) + else if (gpio < 16) + return MCFGPTA_GPTPORT; + else if (gpio < 24) + return MCFGPTB_GPTPORT; + else if (gpio < 32) + return MCFQADC_PORTQA; + else if (gpio < 40) + return MCFQADC_PORTQB; +#endif + else + return MCFGPIO_PPDR + mcfgpio_port(gpio - MCFGPIO_SCR_START); +#else + return 0; +#endif +} + +/* return the port output data register for a gpio */ +static inline u32 __mcfgpio_podr(unsigned gpio) +{ +#if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \ + defined(CONFIG_M5307) || defined(CONFIG_M5407) + return MCFSIM_PADAT; +#elif defined(CONFIG_M5272) + if (gpio < 16) + return MCFSIM_PADAT; + else if (gpio < 32) + return MCFSIM_PBDAT; + else + return MCFSIM_PCDAT; +#elif defined(CONFIG_M5249) + if (gpio < 32) + return MCFSIM2_GPIOWRITE; + else + return MCFSIM2_GPIO1WRITE; +#elif defined(CONFIG_M520x) || defined(CONFIG_M523x) || \ + defined(CONFIG_M527x) || defined(CONFIG_M528x) || defined(CONFIG_M532x) + if (gpio < 8) + return MCFEPORT_EPDR; +#if defined(CONFIG_M528x) + else if (gpio < 16) + return MCFGPTA_GPTPORT; + else if (gpio < 24) + return MCFGPTB_GPTPORT; + else if (gpio < 32) + return MCFQADC_PORTQA; + else if (gpio < 40) + return MCFQADC_PORTQB; +#endif + else + return MCFGPIO_PODR + mcfgpio_port(gpio - MCFGPIO_SCR_START); +#else + return 0; +#endif +} + +/* return the port direction data register for a gpio */ +static inline u32 __mcfgpio_pddr(unsigned gpio) +{ +#if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \ + defined(CONFIG_M5307) || defined(CONFIG_M5407) + return MCFSIM_PADDR; +#elif defined(CONFIG_M5272) + if (gpio < 16) + return MCFSIM_PADDR; + else if (gpio < 32) + return MCFSIM_PBDDR; + else + return MCFSIM_PCDDR; +#elif defined(CONFIG_M5249) + if (gpio < 32) + return MCFSIM2_GPIOENABLE; + else + return MCFSIM2_GPIO1ENABLE; +#elif defined(CONFIG_M520x) || defined(CONFIG_M523x) || \ + defined(CONFIG_M527x) || defined(CONFIG_M528x) || defined(CONFIG_M532x) + if (gpio < 8) + return MCFEPORT_EPDDR; +#if defined(CONFIG_M528x) + else if (gpio < 16) + return MCFGPTA_GPTDDR; + else if (gpio < 24) + return MCFGPTB_GPTDDR; + else if (gpio < 32) + return MCFQADC_DDRQA; + else if (gpio < 40) + return MCFQADC_DDRQB; +#endif + else + return MCFGPIO_PDDR + mcfgpio_port(gpio - MCFGPIO_SCR_START); +#else + return 0; +#endif +} + +#endif /* mcfgpio_h */ diff --git a/arch/m68k/include/asm/pinmux.h b/arch/m68k/include/asm/pinmux.h deleted file mode 100644 index 119ee686dbd1..000000000000 --- a/arch/m68k/include/asm/pinmux.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Coldfire generic GPIO pinmux support. - * - * (C) Copyright 2009, Steven King - * - * 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; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef pinmux_h -#define pinmux_h - -#define MCFPINMUX_NONE -1 - -extern int mcf_pinmux_request(unsigned, unsigned); -extern void mcf_pinmux_release(unsigned, unsigned); - -static inline int mcf_pinmux_is_valid(unsigned pinmux) -{ - return pinmux != MCFPINMUX_NONE; -} - -#endif - diff --git a/arch/m68k/platform/coldfire/Makefile b/arch/m68k/platform/coldfire/Makefile index 76d389d9a84e..69bc0ae2538d 100644 --- a/arch/m68k/platform/coldfire/Makefile +++ b/arch/m68k/platform/coldfire/Makefile @@ -32,5 +32,5 @@ obj-$(CONFIG_NETtel) += nettel.o obj-$(CONFIG_CLEOPATRA) += nettel.o obj-$(CONFIG_FIREBEE) += firebee.o -obj-y += pinmux.o gpio.o +obj-y += gpio.o extra-y := head.o diff --git a/arch/m68k/platform/coldfire/gpio.c b/arch/m68k/platform/coldfire/gpio.c index 4c8c42450a4e..9cd2b5c70519 100644 --- a/arch/m68k/platform/coldfire/gpio.c +++ b/arch/m68k/platform/coldfire/gpio.c @@ -14,119 +14,161 @@ */ #include +#include #include #include -#include -#include +#include +#include +#include #include -#define MCF_CHIP(chip) container_of(chip, struct mcf_gpio_chip, gpio_chip) +int __mcfgpio_get_value(unsigned gpio) +{ + return mcfgpio_read(__mcfgpio_ppdr(gpio)) & mcfgpio_bit(gpio); +} +EXPORT_SYMBOL(__mcfgpio_get_value); + +void __mcfgpio_set_value(unsigned gpio, int value) +{ + if (gpio < MCFGPIO_SCR_START) { + unsigned long flags; + MCFGPIO_PORTTYPE data; + + local_irq_save(flags); + data = mcfgpio_read(__mcfgpio_podr(gpio)); + if (value) + data |= mcfgpio_bit(gpio); + else + data &= ~mcfgpio_bit(gpio); + mcfgpio_write(data, __mcfgpio_podr(gpio)); + local_irq_restore(flags); + } else { + if (value) + mcfgpio_write(mcfgpio_bit(gpio), + MCFGPIO_SETR_PORT(gpio)); + else + mcfgpio_write(~mcfgpio_bit(gpio), + MCFGPIO_CLRR_PORT(gpio)); + } +} +EXPORT_SYMBOL(__mcfgpio_set_value); -int mcf_gpio_direction_input(struct gpio_chip *chip, unsigned offset) +int __mcfgpio_direction_input(unsigned gpio) { unsigned long flags; MCFGPIO_PORTTYPE dir; - struct mcf_gpio_chip *mcf_chip = MCF_CHIP(chip); local_irq_save(flags); - dir = mcfgpio_read(mcf_chip->pddr); - dir &= ~mcfgpio_bit(chip->base + offset); - mcfgpio_write(dir, mcf_chip->pddr); + dir = mcfgpio_read(__mcfgpio_pddr(gpio)); + dir &= ~mcfgpio_bit(gpio); + mcfgpio_write(dir, __mcfgpio_pddr(gpio)); local_irq_restore(flags); return 0; } +EXPORT_SYMBOL(__mcfgpio_direction_input); -int mcf_gpio_get_value(struct gpio_chip *chip, unsigned offset) -{ - struct mcf_gpio_chip *mcf_chip = MCF_CHIP(chip); - - return mcfgpio_read(mcf_chip->ppdr) & mcfgpio_bit(chip->base + offset); -} - -int mcf_gpio_direction_output(struct gpio_chip *chip, unsigned offset, - int value) +int __mcfgpio_direction_output(unsigned gpio, int value) { unsigned long flags; MCFGPIO_PORTTYPE data; - struct mcf_gpio_chip *mcf_chip = MCF_CHIP(chip); local_irq_save(flags); - /* write the value to the output latch */ - data = mcfgpio_read(mcf_chip->podr); + data = mcfgpio_read(__mcfgpio_pddr(gpio)); if (value) - data |= mcfgpio_bit(chip->base + offset); + data |= mcfgpio_bit(gpio); else - data &= ~mcfgpio_bit(chip->base + offset); - mcfgpio_write(data, mcf_chip->podr); - - /* now set the direction to output */ - data = mcfgpio_read(mcf_chip->pddr); - data |= mcfgpio_bit(chip->base + offset); - mcfgpio_write(data, mcf_chip->pddr); + data &= mcfgpio_bit(gpio); + mcfgpio_write(data, __mcfgpio_pddr(gpio)); + + /* now set the data to output */ + if (gpio < MCFGPIO_SCR_START) { + data = mcfgpio_read(__mcfgpio_podr(gpio)); + if (value) + data |= mcfgpio_bit(gpio); + else + data &= ~mcfgpio_bit(gpio); + mcfgpio_write(data, __mcfgpio_podr(gpio)); + } else { + if (value) + mcfgpio_write(mcfgpio_bit(gpio), + MCFGPIO_SETR_PORT(gpio)); + else + mcfgpio_write(~mcfgpio_bit(gpio), + MCFGPIO_CLRR_PORT(gpio)); + } local_irq_restore(flags); + return 0; +} +EXPORT_SYMBOL(__mcfgpio_direction_output); +int __mcfgpio_request(unsigned gpio) +{ return 0; } +EXPORT_SYMBOL(__mcfgpio_request); -void mcf_gpio_set_value(struct gpio_chip *chip, unsigned offset, int value) +void __mcfgpio_free(unsigned gpio) { - struct mcf_gpio_chip *mcf_chip = MCF_CHIP(chip); + __mcfgpio_direction_input(gpio); +} +EXPORT_SYMBOL(__mcfgpio_free); - unsigned long flags; - MCFGPIO_PORTTYPE data; +#ifdef CONFIG_GPIOLIB - local_irq_save(flags); - data = mcfgpio_read(mcf_chip->podr); - if (value) - data |= mcfgpio_bit(chip->base + offset); - else - data &= ~mcfgpio_bit(chip->base + offset); - mcfgpio_write(data, mcf_chip->podr); - local_irq_restore(flags); +int mcfgpio_direction_input(struct gpio_chip *chip, unsigned offset) +{ + return __mcfgpio_direction_input(offset); } -void mcf_gpio_set_value_fast(struct gpio_chip *chip, unsigned offset, int value) +int mcfgpio_get_value(struct gpio_chip *chip, unsigned offset) { - struct mcf_gpio_chip *mcf_chip = MCF_CHIP(chip); - - if (value) - mcfgpio_write(mcfgpio_bit(chip->base + offset), mcf_chip->setr); - else - mcfgpio_write(~mcfgpio_bit(chip->base + offset), mcf_chip->clrr); + return __mcfgpio_get_value(offset); } -int mcf_gpio_request(struct gpio_chip *chip, unsigned offset) +int mcfgpio_direction_output(struct gpio_chip *chip, unsigned offset, int value) { - struct mcf_gpio_chip *mcf_chip = MCF_CHIP(chip); - - return mcf_chip->gpio_to_pinmux ? - mcf_pinmux_request(mcf_chip->gpio_to_pinmux[offset], 0) : 0; + return __mcfgpio_direction_output(offset, value); } -void mcf_gpio_free(struct gpio_chip *chip, unsigned offset) +void mcfgpio_set_value(struct gpio_chip *chip, unsigned offset, int value) { - struct mcf_gpio_chip *mcf_chip = MCF_CHIP(chip); + __mcfgpio_set_value(offset, value); +} - mcf_gpio_direction_input(chip, offset); +int mcfgpio_request(struct gpio_chip *chip, unsigned offset) +{ + return __mcfgpio_request(offset); +} - if (mcf_chip->gpio_to_pinmux) - mcf_pinmux_release(mcf_chip->gpio_to_pinmux[offset], 0); +void mcfgpio_free(struct gpio_chip *chip, unsigned offset) +{ + __mcfgpio_free(offset); } -struct bus_type mcf_gpio_subsys = { +struct bus_type mcfgpio_subsys = { .name = "gpio", .dev_name = "gpio", }; -static int __init mcf_gpio_sysinit(void) -{ - unsigned int i = 0; +static struct gpio_chip mcfgpio_chip = { + .label = "mcfgpio", + .request = mcfgpio_request, + .free = mcfgpio_free, + .direction_input = mcfgpio_direction_input, + .direction_output = mcfgpio_direction_output, + .get = mcfgpio_get_value, + .set = mcfgpio_set_value, + .base = 0, + .ngpio = MCFGPIO_PIN_MAX, +}; - while (i < mcf_gpio_chips_size) - gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]); - return subsys_system_register(&mcf_gpio_subsys, NULL); +static int __init mcfgpio_sysinit(void) +{ + gpiochip_add(&mcfgpio_chip); + return subsys_system_register(&mcfgpio_subsys, NULL); } -core_initcall(mcf_gpio_sysinit); +core_initcall(mcfgpio_sysinit); +#endif diff --git a/arch/m68k/platform/coldfire/m5206.c b/arch/m68k/platform/coldfire/m5206.c index a8b81df653f0..6bfbeebd231b 100644 --- a/arch/m68k/platform/coldfire/m5206.c +++ b/arch/m68k/platform/coldfire/m5206.c @@ -16,15 +16,6 @@ #include #include #include -#include - -/***************************************************************************/ - -struct mcf_gpio_chip mcf_gpio_chips[] = { - MCFGPS(PP, 0, 8, MCFSIM_PADDR, MCFSIM_PADAT, MCFSIM_PADAT), -}; - -unsigned int mcf_gpio_chips_size = ARRAY_SIZE(mcf_gpio_chips); /***************************************************************************/ diff --git a/arch/m68k/platform/coldfire/m520x.c b/arch/m68k/platform/coldfire/m520x.c index 3264b8883d5f..09df4b89e8be 100644 --- a/arch/m68k/platform/coldfire/m520x.c +++ b/arch/m68k/platform/coldfire/m520x.c @@ -19,22 +19,6 @@ #include #include #include -#include - -/***************************************************************************/ - -struct mcf_gpio_chip mcf_gpio_chips[] = { - MCFGPS(PIRQ, 0, 8, MCFEPORT_EPDDR, MCFEPORT_EPDR, MCFEPORT_EPPDR), - MCFGPF(CS, 9, 3), - MCFGPF(FECI2C, 16, 4), - MCFGPF(QSPI, 24, 4), - MCFGPF(TIMER, 32, 4), - MCFGPF(UART, 40, 8), - MCFGPF(FECH, 48, 8), - MCFGPF(FECL, 56, 8), -}; - -unsigned int mcf_gpio_chips_size = ARRAY_SIZE(mcf_gpio_chips); /***************************************************************************/ diff --git a/arch/m68k/platform/coldfire/m523x.c b/arch/m68k/platform/coldfire/m523x.c index 5d57a4249412..d47dfd8f50a2 100644 --- a/arch/m68k/platform/coldfire/m523x.c +++ b/arch/m68k/platform/coldfire/m523x.c @@ -19,28 +19,6 @@ #include #include #include -#include - -/***************************************************************************/ - -struct mcf_gpio_chip mcf_gpio_chips[] = { - MCFGPS(PIRQ, 1, 7, MCFEPORT_EPDDR, MCFEPORT_EPDR, MCFEPORT_EPPDR), - MCFGPF(ADDR, 13, 3), - MCFGPF(DATAH, 16, 8), - MCFGPF(DATAL, 24, 8), - MCFGPF(BUSCTL, 32, 8), - MCFGPF(BS, 40, 4), - MCFGPF(CS, 49, 7), - MCFGPF(SDRAM, 56, 6), - MCFGPF(FECI2C, 64, 4), - MCFGPF(UARTH, 72, 2), - MCFGPF(UARTL, 80, 8), - MCFGPF(QSPI, 88, 5), - MCFGPF(TIMER, 96, 8), - MCFGPF(ETPU, 104, 3), -}; - -unsigned int mcf_gpio_chips_size = ARRAY_SIZE(mcf_gpio_chips); /***************************************************************************/ diff --git a/arch/m68k/platform/coldfire/m5249.c b/arch/m68k/platform/coldfire/m5249.c index fdfa1edfd1ac..300e729a58d0 100644 --- a/arch/m68k/platform/coldfire/m5249.c +++ b/arch/m68k/platform/coldfire/m5249.c @@ -16,16 +16,6 @@ #include #include #include -#include - -/***************************************************************************/ - -struct mcf_gpio_chip mcf_gpio_chips[] = { - MCFGPS(GPIO0, 0, 32, MCFSIM2_GPIOENABLE, MCFSIM2_GPIOWRITE, MCFSIM2_GPIOREAD), - MCFGPS(GPIO1, 32, 32, MCFSIM2_GPIO1ENABLE, MCFSIM2_GPIO1WRITE, MCFSIM2_GPIO1READ), -}; - -unsigned int mcf_gpio_chips_size = ARRAY_SIZE(mcf_gpio_chips); /***************************************************************************/ diff --git a/arch/m68k/platform/coldfire/m5272.c b/arch/m68k/platform/coldfire/m5272.c index 43e36060da18..e68bc7a148eb 100644 --- a/arch/m68k/platform/coldfire/m5272.c +++ b/arch/m68k/platform/coldfire/m5272.c @@ -19,7 +19,6 @@ #include #include #include -#include /***************************************************************************/ @@ -31,16 +30,6 @@ unsigned char ledbank = 0xff; /***************************************************************************/ -struct mcf_gpio_chip mcf_gpio_chips[] = { - MCFGPS(PA, 0, 16, MCFSIM_PADDR, MCFSIM_PADAT, MCFSIM_PADAT), - MCFGPS(PB, 16, 16, MCFSIM_PBDDR, MCFSIM_PBDAT, MCFSIM_PBDAT), - MCFGPS(Pc, 32, 16, MCFSIM_PCDDR, MCFSIM_PCDAT, MCFSIM_PCDAT), -}; - -unsigned int mcf_gpio_chips_size = ARRAY_SIZE(mcf_gpio_chips); - -/***************************************************************************/ - static void __init m5272_uarts_init(void) { u32 v; diff --git a/arch/m68k/platform/coldfire/m527x.c b/arch/m68k/platform/coldfire/m527x.c index 9b0b66aabd1b..b3cb378c5e94 100644 --- a/arch/m68k/platform/coldfire/m527x.c +++ b/arch/m68k/platform/coldfire/m527x.c @@ -20,49 +20,6 @@ #include #include #include -#include - -/***************************************************************************/ - -struct mcf_gpio_chip mcf_gpio_chips[] = { -#if defined(CONFIG_M5271) - MCFGPS(PIRQ, 1, 7, MCFEPORT_EPDDR, MCFEPORT_EPDR, MCFEPORT_EPPDR), - MCFGPF(ADDR, 13, 3), - MCFGPF(DATAH, 16, 8), - MCFGPF(DATAL, 24, 8), - MCFGPF(BUSCTL, 32, 8), - MCFGPF(BS, 40, 4), - MCFGPF(CS, 49, 7), - MCFGPF(SDRAM, 56, 6), - MCFGPF(FECI2C, 64, 4), - MCFGPF(UARTH, 72, 2), - MCFGPF(UARTL, 80, 8), - MCFGPF(QSPI, 88, 5), - MCFGPF(TIMER, 96, 8), -#elif defined(CONFIG_M5275) - MCFGPS(PIRQ, 1, 7, MCFEPORT_EPDDR, MCFEPORT_EPDR, MCFEPORT_EPPDR), - MCFGPF(BUSCTL, 8, 8), - MCFGPF(ADDR, 21, 3), - MCFGPF(CS, 25, 7), - MCFGPF(FEC0H, 32, 8), - MCFGPF(FEC0L, 40, 8), - MCFGPF(FECI2C, 48, 6), - MCFGPF(QSPI, 56, 7), - MCFGPF(SDRAM, 64, 8), - MCFGPF(TIMERH, 72, 4), - MCFGPF(TIMERL, 80, 4), - MCFGPF(UARTL, 88, 8), - MCFGPF(FEC1H, 96, 8), - MCFGPF(FEC1L, 104, 8), - MCFGPF(BS, 114, 2), - MCFGPF(IRQ, 121, 7), - MCFGPF(USBH, 128, 1), - MCFGPF(USBL, 136, 8), - MCFGPF(UARTH, 144, 4), -#endif -}; - -unsigned int mcf_gpio_chips_size = ARRAY_SIZE(mcf_gpio_chips); /***************************************************************************/ diff --git a/arch/m68k/platform/coldfire/m528x.c b/arch/m68k/platform/coldfire/m528x.c index 7ed1276b29dc..f1319e5d2546 100644 --- a/arch/m68k/platform/coldfire/m528x.c +++ b/arch/m68k/platform/coldfire/m528x.c @@ -21,37 +21,6 @@ #include #include #include -#include - -/***************************************************************************/ - -struct mcf_gpio_chip mcf_gpio_chips[] = { - MCFGPS(NQ, 1, 7, MCFEPORT_EPDDR, MCFEPORT_EPDR, MCFEPORT_EPPDR), - MCFGPS(TA, 8, 4, MCFGPTA_GPTDDR, MCFGPTA_GPTPORT, MCFGPTB_GPTPORT), - MCFGPS(TB, 16, 4, MCFGPTB_GPTDDR, MCFGPTB_GPTPORT, MCFGPTB_GPTPORT), - MCFGPS(QA, 24, 4, MCFQADC_DDRQA, MCFQADC_PORTQA, MCFQADC_PORTQA), - MCFGPS(QB, 32, 4, MCFQADC_DDRQB, MCFQADC_PORTQB, MCFQADC_PORTQB), - MCFGPF(A, 40, 8), - MCFGPF(B, 48, 8), - MCFGPF(C, 56, 8), - MCFGPF(D, 64, 8), - MCFGPF(E, 72, 8), - MCFGPF(F, 80, 8), - MCFGPF(G, 88, 8), - MCFGPF(H, 96, 8), - MCFGPF(J, 104, 8), - MCFGPF(DD, 112, 8), - MCFGPF(EH, 120, 8), - MCFGPF(EL, 128, 8), - MCFGPF(AS, 136, 6), - MCFGPF(QS, 144, 7), - MCFGPF(SD, 152, 6), - MCFGPF(TC, 160, 4), - MCFGPF(TD, 168, 4), - MCFGPF(UA, 176, 4), -}; - -unsigned int mcf_gpio_chips_size = ARRAY_SIZE(mcf_gpio_chips); /***************************************************************************/ @@ -74,7 +43,7 @@ static void __init m528x_uarts_init(void) /* make sure PUAPAR is set for UART0 and UART1 */ port = readb(MCF5282_GPIO_PUAPAR); port |= 0x03 | (0x03 << 2); - writeb(port, MCF5282_GPIO_PUAPAR); + writeb(port, MCFGPIO_PUAPAR); } /***************************************************************************/ diff --git a/arch/m68k/platform/coldfire/m5307.c b/arch/m68k/platform/coldfire/m5307.c index 93b484976ab3..a568d2870d15 100644 --- a/arch/m68k/platform/coldfire/m5307.c +++ b/arch/m68k/platform/coldfire/m5307.c @@ -16,7 +16,6 @@ #include #include #include -#include #include /***************************************************************************/ @@ -29,14 +28,6 @@ unsigned char ledbank = 0xff; /***************************************************************************/ -struct mcf_gpio_chip mcf_gpio_chips[] = { - MCFGPS(PP, 0, 16, MCFSIM_PADDR, MCFSIM_PADAT, MCFSIM_PADAT), -}; - -unsigned int mcf_gpio_chips_size = ARRAY_SIZE(mcf_gpio_chips); - -/***************************************************************************/ - void __init config_BSP(char *commandp, int size) { #if defined(CONFIG_NETtel) || \ diff --git a/arch/m68k/platform/coldfire/m532x.c b/arch/m68k/platform/coldfire/m532x.c index 5394223639f8..21d6cb1c7004 100644 --- a/arch/m68k/platform/coldfire/m532x.c +++ b/arch/m68k/platform/coldfire/m532x.c @@ -26,35 +26,10 @@ #include #include #include -#include #include /***************************************************************************/ -struct mcf_gpio_chip mcf_gpio_chips[] = { - MCFGPS(PIRQ, 0, 8, MCFEPORT_EPDDR, MCFEPORT_EPDR, MCFEPORT_EPPDR), - MCFGPF(FECH, 8, 8), - MCFGPF(FECL, 16, 8), - MCFGPF(SSI, 24, 5), - MCFGPF(BUSCTL, 32, 4), - MCFGPF(BE, 40, 4), - MCFGPF(CS, 49, 5), - MCFGPF(PWM, 58, 4), - MCFGPF(FECI2C, 64, 4), - MCFGPF(UART, 72, 8), - MCFGPF(QSPI, 80, 6), - MCFGPF(TIMER, 88, 4), - MCFGPF(LCDDATAH, 96, 2), - MCFGPF(LCDDATAM, 104, 8), - MCFGPF(LCDDATAL, 112, 8), - MCFGPF(LCDCTLH, 120, 1), - MCFGPF(LCDCTLL, 128, 8), -}; - -unsigned int mcf_gpio_chips_size = ARRAY_SIZE(mcf_gpio_chips); - -/***************************************************************************/ - #if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) static void __init m532x_qspi_init(void) diff --git a/arch/m68k/platform/coldfire/m5407.c b/arch/m68k/platform/coldfire/m5407.c index faa6680b3404..bb6c746ae819 100644 --- a/arch/m68k/platform/coldfire/m5407.c +++ b/arch/m68k/platform/coldfire/m5407.c @@ -16,15 +16,6 @@ #include #include #include -#include - -/***************************************************************************/ - -struct mcf_gpio_chip mcf_gpio_chips[] = { - MCFGPS(PP, 0, 16, MCFSIM_PADDR, MCFSIM_PADAT, MCFSIM_PADAT), -}; - -unsigned int mcf_gpio_chips_size = ARRAY_SIZE(mcf_gpio_chips); /***************************************************************************/ diff --git a/arch/m68k/platform/coldfire/m54xx.c b/arch/m68k/platform/coldfire/m54xx.c index 20672dadb252..2081c6cbb3de 100644 --- a/arch/m68k/platform/coldfire/m54xx.c +++ b/arch/m68k/platform/coldfire/m54xx.c @@ -21,19 +21,12 @@ #include #include #include -#include #ifdef CONFIG_MMU #include #endif /***************************************************************************/ -struct mcf_gpio_chip mcf_gpio_chips[] = { }; - -unsigned int mcf_gpio_chips_size = ARRAY_SIZE(mcf_gpio_chips); - -/***************************************************************************/ - static void __init m54xx_uarts_init(void) { /* enable io pins */ diff --git a/arch/m68k/platform/coldfire/pinmux.c b/arch/m68k/platform/coldfire/pinmux.c deleted file mode 100644 index 8c62b825939f..000000000000 --- a/arch/m68k/platform/coldfire/pinmux.c +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Coldfire generic GPIO pinmux support. - * - * (C) Copyright 2009, Steven King - * - * 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; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include - -#include - -int mcf_pinmux_request(unsigned pinmux, unsigned func) -{ - return 0; -} - -void mcf_pinmux_release(unsigned pinmux, unsigned func) -{ -} -- cgit v1.2.3 From 04e037aa4e5f71d11c004e844339d385a89733f6 Mon Sep 17 00:00:00 2001 From: Steven King Date: Tue, 5 Jun 2012 08:23:08 -0700 Subject: m68knommu: Add support for the Coldfire 5251/5253 Basic support for the Coldfire 5251/5253. Signed-off-by: Steven king Signed-off-by: Greg Ungerer --- arch/m68k/Kconfig.cpu | 8 ++ arch/m68k/Makefile | 1 + arch/m68k/include/asm/dma.h | 4 +- arch/m68k/include/asm/m525xsim.h | 194 ++++++++++++++++++++++++++++++++ arch/m68k/include/asm/mcfgpio.h | 8 +- arch/m68k/include/asm/mcfsim.h | 3 + arch/m68k/include/asm/mcfuart.h | 4 +- arch/m68k/platform/coldfire/Makefile | 1 + arch/m68k/platform/coldfire/head.S | 6 +- arch/m68k/platform/coldfire/intc-525x.c | 91 +++++++++++++++ arch/m68k/platform/coldfire/m525x.c | 66 +++++++++++ 11 files changed, 376 insertions(+), 10 deletions(-) create mode 100644 arch/m68k/include/asm/m525xsim.h create mode 100644 arch/m68k/platform/coldfire/intc-525x.c create mode 100644 arch/m68k/platform/coldfire/m525x.c (limited to 'arch/m68k') diff --git a/arch/m68k/Kconfig.cpu b/arch/m68k/Kconfig.cpu index ff2314d5d934..8d9afb09f569 100644 --- a/arch/m68k/Kconfig.cpu +++ b/arch/m68k/Kconfig.cpu @@ -167,6 +167,14 @@ config M5249 help Motorola ColdFire 5249 processor support. +config M525x + bool "MCF525x" + depends on !MMU + select COLDFIRE_SW_A7 + select HAVE_MBAR + help + Freescale (Motorola) Coldfire 5251/5253 processor support. + config M527x bool diff --git a/arch/m68k/Makefile b/arch/m68k/Makefile index b7f2e2d5cd2e..8daf9697e5e2 100644 --- a/arch/m68k/Makefile +++ b/arch/m68k/Makefile @@ -50,6 +50,7 @@ cpuflags-$(CONFIG_M5275) := $(call cc-option,-mcpu=5275,-m5307) cpuflags-$(CONFIG_M5272) := $(call cc-option,-mcpu=5272,-m5307) cpuflags-$(CONFIG_M5271) := $(call cc-option,-mcpu=5271,-m5307) cpuflags-$(CONFIG_M523x) := $(call cc-option,-mcpu=523x,-m5307) +cpuflags-$(CONFIG_M525x) := $(call cc-option,-mcpu=5253,-m5200) cpuflags-$(CONFIG_M5249) := $(call cc-option,-mcpu=5249,-m5200) cpuflags-$(CONFIG_M520x) := $(call cc-option,-mcpu=5208,-m5200) cpuflags-$(CONFIG_M5206e) := $(call cc-option,-mcpu=5206e,-m5200) diff --git a/arch/m68k/include/asm/dma.h b/arch/m68k/include/asm/dma.h index 6fbdfe895104..947064184639 100644 --- a/arch/m68k/include/asm/dma.h +++ b/arch/m68k/include/asm/dma.h @@ -33,7 +33,9 @@ * Set number of channels of DMA on ColdFire for different implementations. */ #if defined(CONFIG_M5249) || defined(CONFIG_M5307) || defined(CONFIG_M5407) || \ - defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) + defined(CONFIG_M523x) || defined(CONFIG_M527x) || \ + defined(CONFIG_M528x) || defined(CONFIG_M525x) + #define MAX_M68K_DMA_CHANNELS 4 #elif defined(CONFIG_M5272) #define MAX_M68K_DMA_CHANNELS 1 diff --git a/arch/m68k/include/asm/m525xsim.h b/arch/m68k/include/asm/m525xsim.h new file mode 100644 index 000000000000..6da24f653902 --- /dev/null +++ b/arch/m68k/include/asm/m525xsim.h @@ -0,0 +1,194 @@ +/****************************************************************************/ + +/* + * m525xsim.h -- ColdFire 525x System Integration Module support. + * + * (C) Copyright 2012, Steven king + * (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com) + */ + +/****************************************************************************/ +#ifndef m525xsim_h +#define m525xsim_h +/****************************************************************************/ + +#define CPU_NAME "COLDFIRE(m525x)" +#define CPU_INSTR_PER_JIFFY 3 +#define MCF_BUSCLK (MCF_CLK / 2) + +#include + +/* + * The 525x has a second MBAR region, define its address. + */ +#define MCF_MBAR2 0x80000000 + +/* + * Define the 525x SIM register set addresses. + */ +#define MCFSIM_RSR 0x00 /* Reset Status reg (r/w) */ +#define MCFSIM_SYPCR 0x01 /* System Protection reg (r/w)*/ +#define MCFSIM_SWIVR 0x02 /* SW Watchdog intr reg (r/w) */ +#define MCFSIM_SWSR 0x03 /* SW Watchdog service (r/w) */ +#define MCFSIM_MPARK 0x0C /* BUS Master Control Reg*/ +#define MCFSIM_IPR 0x40 /* Interrupt Pend reg (r/w) */ +#define MCFSIM_IMR 0x44 /* Interrupt Mask reg (r/w) */ +#define MCFSIM_ICR0 0x4c /* Intr Ctrl reg 0 (r/w) */ +#define MCFSIM_ICR1 0x4d /* Intr Ctrl reg 1 (r/w) */ +#define MCFSIM_ICR2 0x4e /* Intr Ctrl reg 2 (r/w) */ +#define MCFSIM_ICR3 0x4f /* Intr Ctrl reg 3 (r/w) */ +#define MCFSIM_ICR4 0x50 /* Intr Ctrl reg 4 (r/w) */ +#define MCFSIM_ICR5 0x51 /* Intr Ctrl reg 5 (r/w) */ +#define MCFSIM_ICR6 0x52 /* Intr Ctrl reg 6 (r/w) */ +#define MCFSIM_ICR7 0x53 /* Intr Ctrl reg 7 (r/w) */ +#define MCFSIM_ICR8 0x54 /* Intr Ctrl reg 8 (r/w) */ +#define MCFSIM_ICR9 0x55 /* Intr Ctrl reg 9 (r/w) */ +#define MCFSIM_ICR10 0x56 /* Intr Ctrl reg 10 (r/w) */ +#define MCFSIM_ICR11 0x57 /* Intr Ctrl reg 11 (r/w) */ + +#define MCFSIM_CSAR0 0x80 /* CS 0 Address 0 reg (r/w) */ +#define MCFSIM_CSMR0 0x84 /* CS 0 Mask 0 reg (r/w) */ +#define MCFSIM_CSCR0 0x8a /* CS 0 Control reg (r/w) */ +#define MCFSIM_CSAR1 0x8c /* CS 1 Address reg (r/w) */ +#define MCFSIM_CSMR1 0x90 /* CS 1 Mask reg (r/w) */ +#define MCFSIM_CSCR1 0x96 /* CS 1 Control reg (r/w) */ +#define MCFSIM_CSAR2 0x98 /* CS 2 Address reg (r/w) */ +#define MCFSIM_CSMR2 0x9c /* CS 2 Mask reg (r/w) */ +#define MCFSIM_CSCR2 0xa2 /* CS 2 Control reg (r/w) */ +#define MCFSIM_CSAR3 0xa4 /* CS 3 Address reg (r/w) */ +#define MCFSIM_CSMR3 0xa8 /* CS 3 Mask reg (r/w) */ +#define MCFSIM_CSCR3 0xae /* CS 3 Control reg (r/w) */ +#define MCFSIM_CSAR4 0xb0 /* CS 4 Address reg (r/w) */ +#define MCFSIM_CSMR4 0xb4 /* CS 4 Mask reg (r/w) */ +#define MCFSIM_CSCR4 0xba /* CS 4 Control reg (r/w) */ + +#define MCFSIM_DCR (MCF_MBAR + 0x100) /* DRAM Control */ +#define MCFSIM_DACR0 (MCF_MBAR + 0x108) /* DRAM 0 Addr/Ctrl */ +#define MCFSIM_DMR0 (MCF_MBAR + 0x10c) /* DRAM 0 Mask */ + +/* + * Secondary Interrupt Controller (in MBAR2) +*/ +#define MCFINTC2_INTBASE (MCF_MBAR2 + 0x168) /* Base Vector Reg */ +#define MCFINTC2_INTPRI1 (MCF_MBAR2 + 0x140) /* 0-7 priority */ +#define MCFINTC2_INTPRI2 (MCF_MBAR2 + 0x144) /* 8-15 priority */ +#define MCFINTC2_INTPRI3 (MCF_MBAR2 + 0x148) /* 16-23 priority */ +#define MCFINTC2_INTPRI4 (MCF_MBAR2 + 0x14c) /* 24-31 priority */ +#define MCFINTC2_INTPRI5 (MCF_MBAR2 + 0x150) /* 32-39 priority */ +#define MCFINTC2_INTPRI6 (MCF_MBAR2 + 0x154) /* 40-47 priority */ +#define MCFINTC2_INTPRI7 (MCF_MBAR2 + 0x158) /* 48-55 priority */ +#define MCFINTC2_INTPRI8 (MCF_MBAR2 + 0x15c) /* 56-63 priority */ + +#define MCFINTC2_INTPRI_REG(i) (MCFINTC2_INTPRI1 + \ + ((((i) - MCFINTC2_VECBASE) / 8) * 4)) +#define MCFINTC2_INTPRI_BITS(b, i) ((b) << (((i) % 8) * 4)) + +/* + * Timer module. + */ +#define MCFTIMER_BASE1 (MCF_MBAR + 0x140) /* Base of TIMER1 */ +#define MCFTIMER_BASE2 (MCF_MBAR + 0x180) /* Base of TIMER2 */ + +/* + * UART module. + */ +#define MCFUART_BASE0 (MCF_MBAR + 0x1c0) /* Base address UART0 */ +#define MCFUART_BASE1 (MCF_MBAR + 0x200) /* Base address UART1 */ + +/* + * QSPI module. + */ +#define MCFQSPI_BASE (MCF_MBAR + 0x300) /* Base address QSPI */ +#define MCFQSPI_SIZE 0x40 /* Register set size */ + + +#define MCFQSPI_CS0 15 +#define MCFQSPI_CS1 16 +#define MCFQSPI_CS2 24 +#define MCFQSPI_CS3 28 + +/* + * I2C module. + */ +#define MCFI2C_BASE0 (MCF_MBAR + 0x280) /* Base addreess I2C0 */ +#define MCFI2C_SIZE0 0x20 /* Register set size */ + +#define MCFI2C_BASE1 (MCF_MBAR2 + 0x440) /* Base addreess I2C1 */ +#define MCFI2C_SIZE1 0x20 /* Register set size */ +/* + * DMA unit base addresses. + */ +#define MCFDMA_BASE0 (MCF_MBAR + 0x300) /* Base address DMA 0 */ +#define MCFDMA_BASE1 (MCF_MBAR + 0x340) /* Base address DMA 1 */ +#define MCFDMA_BASE2 (MCF_MBAR + 0x380) /* Base address DMA 2 */ +#define MCFDMA_BASE3 (MCF_MBAR + 0x3C0) /* Base address DMA 3 */ + +/* + * Some symbol defines for the above... + */ +#define MCFSIM_SWDICR MCFSIM_ICR0 /* Watchdog timer ICR */ +#define MCFSIM_TIMER1ICR MCFSIM_ICR1 /* Timer 1 ICR */ +#define MCFSIM_TIMER2ICR MCFSIM_ICR2 /* Timer 2 ICR */ +#define MCFSIM_I2CICR MCFSIM_ICR3 /* I2C ICR */ +#define MCFSIM_UART1ICR MCFSIM_ICR4 /* UART 1 ICR */ +#define MCFSIM_UART2ICR MCFSIM_ICR5 /* UART 2 ICR */ +#define MCFSIM_DMA0ICR MCFSIM_ICR6 /* DMA 0 ICR */ +#define MCFSIM_DMA1ICR MCFSIM_ICR7 /* DMA 1 ICR */ +#define MCFSIM_DMA2ICR MCFSIM_ICR8 /* DMA 2 ICR */ +#define MCFSIM_DMA3ICR MCFSIM_ICR9 /* DMA 3 ICR */ +#define MCFSIM_QSPIICR MCFSIM_ICR10 /* QSPI ICR */ + +/* + * Define system peripheral IRQ usage. + */ +#define MCF_IRQ_QSPI 28 /* QSPI, Level 4 */ +#define MCF_IRQ_I2C0 29 +#define MCF_IRQ_TIMER 30 /* Timer0, Level 6 */ +#define MCF_IRQ_PROFILER 31 /* Timer1, Level 7 */ + +#define MCF_IRQ_UART0 73 /* UART0 */ +#define MCF_IRQ_UART1 74 /* UART1 */ + +/* + * Define the base interrupt for the second interrupt controller. + * We set it to 128, out of the way of the base interrupts, and plenty + * of room for its 64 interrupts. + */ +#define MCFINTC2_VECBASE 128 + +#define MCF_IRQ_GPIO0 (MCFINTC2_VECBASE + 32) +#define MCF_IRQ_GPIO1 (MCFINTC2_VECBASE + 33) +#define MCF_IRQ_GPIO2 (MCFINTC2_VECBASE + 34) +#define MCF_IRQ_GPIO3 (MCFINTC2_VECBASE + 35) +#define MCF_IRQ_GPIO4 (MCFINTC2_VECBASE + 36) +#define MCF_IRQ_GPIO5 (MCFINTC2_VECBASE + 37) +#define MCF_IRQ_GPIO6 (MCFINTC2_VECBASE + 38) + +#define MCF_IRQ_USBWUP (MCFINTC2_VECBASE + 40) +#define MCF_IRQ_I2C1 (MCFINTC2_VECBASE + 62) + +/* + * General purpose IO registers (in MBAR2). + */ +#define MCFSIM2_GPIOREAD (MCF_MBAR2 + 0x000) /* GPIO read values */ +#define MCFSIM2_GPIOWRITE (MCF_MBAR2 + 0x004) /* GPIO write values */ +#define MCFSIM2_GPIOENABLE (MCF_MBAR2 + 0x008) /* GPIO enabled */ +#define MCFSIM2_GPIOFUNC (MCF_MBAR2 + 0x00C) /* GPIO function */ +#define MCFSIM2_GPIO1READ (MCF_MBAR2 + 0x0B0) /* GPIO1 read values */ +#define MCFSIM2_GPIO1WRITE (MCF_MBAR2 + 0x0B4) /* GPIO1 write values */ +#define MCFSIM2_GPIO1ENABLE (MCF_MBAR2 + 0x0B8) /* GPIO1 enabled */ +#define MCFSIM2_GPIO1FUNC (MCF_MBAR2 + 0x0BC) /* GPIO1 function */ + +#define MCFSIM2_GPIOINTSTAT (MCF_MBAR2 + 0xc0) /* GPIO intr status */ +#define MCFSIM2_GPIOINTCLEAR (MCF_MBAR2 + 0xc0) /* GPIO intr clear */ +#define MCFSIM2_GPIOINTENABLE (MCF_MBAR2 + 0xc4) /* GPIO intr enable */ + +/* + * Generic GPIO support + */ +#define MCFGPIO_PIN_MAX 64 +#define MCFGPIO_IRQ_MAX 7 +#define MCFGPIO_IRQ_VECBASE MCF_IRQ_GPIO0 + +/****************************************************************************/ +#endif /* m525xsim_h */ diff --git a/arch/m68k/include/asm/mcfgpio.h b/arch/m68k/include/asm/mcfgpio.h index 67ba20ffedbe..b2471a5f02eb 100644 --- a/arch/m68k/include/asm/mcfgpio.h +++ b/arch/m68k/include/asm/mcfgpio.h @@ -122,7 +122,7 @@ static inline void gpio_free(unsigned gpio) #define mcfgpio_read(port) __raw_readw(port) #define mcfgpio_write(data, port) __raw_writew(data, port) -#elif defined(CONFIG_M5249) +#elif defined(CONFIG_M5249) || defined(CONFIG_M525x) /* These parts have GPIO organized by 32 bit ports */ @@ -183,7 +183,7 @@ static inline u32 __mcfgpio_ppdr(unsigned gpio) return MCFSIM_PBDAT; else return MCFSIM_PCDAT; -#elif defined(CONFIG_M5249) +#elif defined(CONFIG_M5249) || defined(CONFIG_M525x) if (gpio < 32) return MCFSIM2_GPIOREAD; else @@ -222,7 +222,7 @@ static inline u32 __mcfgpio_podr(unsigned gpio) return MCFSIM_PBDAT; else return MCFSIM_PCDAT; -#elif defined(CONFIG_M5249) +#elif defined(CONFIG_M5249) || defined(CONFIG_M525x) if (gpio < 32) return MCFSIM2_GPIOWRITE; else @@ -261,7 +261,7 @@ static inline u32 __mcfgpio_pddr(unsigned gpio) return MCFSIM_PBDDR; else return MCFSIM_PCDDR; -#elif defined(CONFIG_M5249) +#elif defined(CONFIG_M5249) || defined(CONFIG_M525x) if (gpio < 32) return MCFSIM2_GPIOENABLE; else diff --git a/arch/m68k/include/asm/mcfsim.h b/arch/m68k/include/asm/mcfsim.h index ebd0304054ad..6871f62b11b1 100644 --- a/arch/m68k/include/asm/mcfsim.h +++ b/arch/m68k/include/asm/mcfsim.h @@ -27,6 +27,9 @@ #elif defined(CONFIG_M5249) #include #include +#elif defined(CONFIG_M525x) +#include +#include #elif defined(CONFIG_M527x) #include #elif defined(CONFIG_M5272) diff --git a/arch/m68k/include/asm/mcfuart.h b/arch/m68k/include/asm/mcfuart.h index 2d3bc774b3c5..b40c20f66647 100644 --- a/arch/m68k/include/asm/mcfuart.h +++ b/arch/m68k/include/asm/mcfuart.h @@ -43,8 +43,8 @@ struct mcf_platform_uart { #define MCFUART_UFPD 0x30 /* Frac Prec. Divider (r/w) */ #endif #if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \ - defined(CONFIG_M5249) || defined(CONFIG_M5307) || \ - defined(CONFIG_M5407) + defined(CONFIG_M5249) || defined(CONFIG_M525x) || \ + defined(CONFIG_M5307) || defined(CONFIG_M5407) #define MCFUART_UIVR 0x30 /* Interrupt Vector (r/w) */ #endif #define MCFUART_UIPR 0x34 /* Input Port (r) */ diff --git a/arch/m68k/platform/coldfire/Makefile b/arch/m68k/platform/coldfire/Makefile index 69bc0ae2538d..a7329b4fbef8 100644 --- a/arch/m68k/platform/coldfire/Makefile +++ b/arch/m68k/platform/coldfire/Makefile @@ -20,6 +20,7 @@ obj-$(CONFIG_M5206e) += m5206.o timers.o intc.o reset.o obj-$(CONFIG_M520x) += m520x.o pit.o intc-simr.o reset.o obj-$(CONFIG_M523x) += m523x.o pit.o dma_timer.o intc-2.o reset.o obj-$(CONFIG_M5249) += m5249.o timers.o intc.o intc-5249.o reset.o +obj-$(CONFIG_M525x) += m525x.o timers.o intc.o intc-525x.o reset.o obj-$(CONFIG_M527x) += m527x.o pit.o intc-2.o reset.o obj-$(CONFIG_M5272) += m5272.o intc-5272.o timers.o obj-$(CONFIG_M528x) += m528x.o pit.o intc-2.o reset.o diff --git a/arch/m68k/platform/coldfire/head.S b/arch/m68k/platform/coldfire/head.S index c3db70ed33b3..4e0c9eb3bd1f 100644 --- a/arch/m68k/platform/coldfire/head.S +++ b/arch/m68k/platform/coldfire/head.S @@ -31,9 +31,9 @@ .endm #elif defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \ - defined(CONFIG_M5249) || defined(CONFIG_M527x) || \ - defined(CONFIG_M528x) || defined(CONFIG_M5307) || \ - defined(CONFIG_M5407) + defined(CONFIG_M5249) || defined(CONFIG_M525x) || \ + defined(CONFIG_M527x) || defined(CONFIG_M528x) || \ + defined(CONFIG_M5307) || defined(CONFIG_M5407) /* * Not all these devices have exactly the same DRAM controller, * but the DCMR register is virtually identical - give or take diff --git a/arch/m68k/platform/coldfire/intc-525x.c b/arch/m68k/platform/coldfire/intc-525x.c new file mode 100644 index 000000000000..b23204d059ac --- /dev/null +++ b/arch/m68k/platform/coldfire/intc-525x.c @@ -0,0 +1,91 @@ +/* + * intc2.c -- support for the 2nd INTC controller of the 525x + * + * (C) Copyright 2012, Steven King + * (C) Copyright 2009, Greg Ungerer + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +static void intc2_irq_gpio_mask(struct irq_data *d) +{ + u32 imr = readl(MCFSIM2_GPIOINTENABLE); + u32 type = irqd_get_trigger_type(d); + int irq = d->irq - MCF_IRQ_GPIO0; + + if (type & IRQ_TYPE_EDGE_RISING) + imr &= ~(0x001 << irq); + if (type & IRQ_TYPE_EDGE_FALLING) + imr &= ~(0x100 << irq); + writel(imr, MCFSIM2_GPIOINTENABLE); +} + +static void intc2_irq_gpio_unmask(struct irq_data *d) +{ + u32 imr = readl(MCFSIM2_GPIOINTENABLE); + u32 type = irqd_get_trigger_type(d); + int irq = d->irq - MCF_IRQ_GPIO0; + + if (type & IRQ_TYPE_EDGE_RISING) + imr |= (0x001 << irq); + if (type & IRQ_TYPE_EDGE_FALLING) + imr |= (0x100 << irq); + writel(imr, MCFSIM2_GPIOINTENABLE); +} + +static void intc2_irq_gpio_ack(struct irq_data *d) +{ + u32 imr = 0; + u32 type = irqd_get_trigger_type(d); + int irq = d->irq - MCF_IRQ_GPIO0; + + if (type & IRQ_TYPE_EDGE_RISING) + imr |= (0x001 << irq); + if (type & IRQ_TYPE_EDGE_FALLING) + imr |= (0x100 << irq); + writel(imr, MCFSIM2_GPIOINTCLEAR); +} + +static int intc2_irq_gpio_set_type(struct irq_data *d, unsigned int f) +{ + if (f & ~IRQ_TYPE_EDGE_BOTH) + return -EINVAL; + return 0; +} + +static struct irq_chip intc2_irq_gpio_chip = { + .name = "CF-INTC2", + .irq_mask = intc2_irq_gpio_mask, + .irq_unmask = intc2_irq_gpio_unmask, + .irq_ack = intc2_irq_gpio_ack, + .irq_set_type = intc2_irq_gpio_set_type, +}; + +static int __init mcf_intc2_init(void) +{ + int irq; + + /* set the interrupt base for the second interrupt controller */ + writel(MCFINTC2_VECBASE, MCFINTC2_INTBASE); + + /* GPIO interrupt sources */ + for (irq = MCF_IRQ_GPIO0; (irq <= MCF_IRQ_GPIO6); irq++) { + irq_set_chip(irq, &intc2_irq_gpio_chip); + irq_set_handler(irq, handle_edge_irq); + } + + return 0; +} + +arch_initcall(mcf_intc2_init); diff --git a/arch/m68k/platform/coldfire/m525x.c b/arch/m68k/platform/coldfire/m525x.c new file mode 100644 index 000000000000..8ce905f9b84f --- /dev/null +++ b/arch/m68k/platform/coldfire/m525x.c @@ -0,0 +1,66 @@ +/***************************************************************************/ + +/* + * 525x.c + * + * Copyright (C) 2012, Steven King + */ + +/***************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include + +/***************************************************************************/ + +static void __init m525x_qspi_init(void) +{ +#if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) + /* set the GPIO function for the qspi cs gpios */ + /* FIXME: replace with pinmux/pinctl support */ + u32 f = readl(MCFSIM2_GPIOFUNC); + f |= (1 << MCFQSPI_CS2) | (1 << MCFQSPI_CS1) | (1 << MCFQSPI_CS0); + writel(f, MCFSIM2_GPIOFUNC); + + /* QSPI irq setup */ + writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL4 | MCFSIM_ICR_PRI0, + MCF_MBAR + MCFSIM_QSPIICR); + mcf_mapirq2imr(MCF_IRQ_QSPI, MCFINTC_QSPI); +#endif /* IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) */ +} + +static void __init m525x_i2c_init(void) +{ +#if IS_ENABLED(CONFIG_I2C_COLDFIRE) + u32 r; + + /* first I2C controller uses regular irq setup */ + writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL5 | MCFSIM_ICR_PRI0, + MCF_MBAR + MCFSIM_I2CICR); + mcf_mapirq2imr(MCF_IRQ_I2C0, MCFINTC_I2C); + + /* second I2C controller is completely different */ + r = readl(MCFINTC2_INTPRI_REG(MCF_IRQ_I2C1)); + r &= ~MCFINTC2_INTPRI_BITS(0xf, MCF_IRQ_I2C1); + r |= MCFINTC2_INTPRI_BITS(0x5, MCF_IRQ_I2C1); + writel(r, MCFINTC2_INTPRI_REG(MCF_IRQ_I2C1)); +#endif /* IS_ENABLED(CONFIG_I2C_COLDFIRE) */ +} + +/***************************************************************************/ + +void __init config_BSP(char *commandp, int size) +{ + mach_sched_init = hw_timer_init; + + m525x_qspi_init(); + m525x_i2c_init(); +} + +/***************************************************************************/ -- cgit v1.2.3 From bdee4e26ba6568118f2376ebcfdeef3b7f527bce Mon Sep 17 00:00:00 2001 From: Steven King Date: Wed, 6 Jun 2012 14:02:14 -0700 Subject: m68knommu: use MCF_IRQ_PIT1 instead of MCFINT_VECBASE + MCFINT_PIT1 use MCF_IRQ_PIT1 instead of MCFINT_VECBASE + MCFINT_PIT1 so we can support those parts that have the pit1 interrupt on other than the first interrupt controller. Signed-off-by: Steven King Signed-off-by: Greg Ungerer --- arch/m68k/include/asm/m520xsim.h | 1 + arch/m68k/include/asm/m523xsim.h | 1 + arch/m68k/include/asm/m527xsim.h | 1 + arch/m68k/include/asm/m528xsim.h | 2 +- arch/m68k/platform/coldfire/pit.c | 4 ++-- 5 files changed, 6 insertions(+), 3 deletions(-) (limited to 'arch/m68k') diff --git a/arch/m68k/include/asm/m520xsim.h b/arch/m68k/include/asm/m520xsim.h index 17f2aab9cf97..5a8b5e4da12b 100644 --- a/arch/m68k/include/asm/m520xsim.h +++ b/arch/m68k/include/asm/m520xsim.h @@ -62,6 +62,7 @@ #define MCF_IRQ_FECENTC0 (MCFINT_VECBASE + MCFINT_FECENTC0) #define MCF_IRQ_QSPI (MCFINT_VECBASE + MCFINT_QSPI) +#define MCF_IRQ_PIT1 (MCFINT_VECBASE + MCFINT_PIT1) /* * SDRAM configuration registers. diff --git a/arch/m68k/include/asm/m523xsim.h b/arch/m68k/include/asm/m523xsim.h index 075062d4eecd..91d3abc3f2a5 100644 --- a/arch/m68k/include/asm/m523xsim.h +++ b/arch/m68k/include/asm/m523xsim.h @@ -52,6 +52,7 @@ #define MCF_IRQ_FECENTC0 (MCFINT_VECBASE + MCFINT_FECENTC0) #define MCF_IRQ_QSPI (MCFINT_VECBASE + MCFINT_QSPI) +#define MCF_IRQ_PIT1 (MCFINT_VECBASE + MCFINT_PIT1) /* * SDRAM configuration registers. diff --git a/arch/m68k/include/asm/m527xsim.h b/arch/m68k/include/asm/m527xsim.h index 83db8106f50a..71aa5104d3d6 100644 --- a/arch/m68k/include/asm/m527xsim.h +++ b/arch/m68k/include/asm/m527xsim.h @@ -60,6 +60,7 @@ #define MCF_IRQ_FECENTC1 (MCFINT2_VECBASE + MCFINT2_FECENTC1) #define MCF_IRQ_QSPI (MCFINT_VECBASE + MCFINT_QSPI) +#define MCF_IRQ_PIT1 (MCFINT_VECBASE + MCFINT_PIT1) /* * SDRAM configuration registers. diff --git a/arch/m68k/include/asm/m528xsim.h b/arch/m68k/include/asm/m528xsim.h index 497c31c803ff..4acb3c0a642e 100644 --- a/arch/m68k/include/asm/m528xsim.h +++ b/arch/m68k/include/asm/m528xsim.h @@ -52,7 +52,7 @@ #define MCF_IRQ_FECENTC0 (MCFINT_VECBASE + MCFINT_FECENTC0) #define MCF_IRQ_QSPI (MCFINT_VECBASE + MCFINT_QSPI) - +#define MCF_IRQ_PIT1 (MCFINT_VECBASE + MCFINT_PIT1) /* * SDRAM configuration registers. */ diff --git a/arch/m68k/platform/coldfire/pit.c b/arch/m68k/platform/coldfire/pit.c index e62dbbcb10f6..e8f3b97b0f77 100644 --- a/arch/m68k/platform/coldfire/pit.c +++ b/arch/m68k/platform/coldfire/pit.c @@ -93,7 +93,7 @@ struct clock_event_device cf_pit_clockevent = { .set_mode = init_cf_pit_timer, .set_next_event = cf_pit_next_event, .shift = 32, - .irq = MCFINT_VECBASE + MCFINT_PIT1, + .irq = MCF_IRQ_PIT1, }; @@ -159,7 +159,7 @@ void hw_timer_init(irq_handler_t handler) clockevent_delta2ns(0x3f, &cf_pit_clockevent); clockevents_register_device(&cf_pit_clockevent); - setup_irq(MCFINT_VECBASE + MCFINT_PIT1, &pit_irq); + setup_irq(MCF_IRQ_PIT1, &pit_irq); clocksource_register_hz(&pit_clk, FREQ); } -- cgit v1.2.3 From bea8bcb12da09bd35cdada395d0d0db1aee2ba4c Mon Sep 17 00:00:00 2001 From: Steven King Date: Wed, 6 Jun 2012 14:28:31 -0700 Subject: m68knommu: Add support for the Coldfire m5441x. Add support for the Coldfire 5441x (54410/54415/54416/54417/54418). Currently we only support noMMU mode. It requires the PIT patch posted previously as it uses the PIT instead of the dma timer as a clock source so we can get all that GENERIC_CLOCKEVENTS goodness. It also adds some simple clk definitions and very simple minded power management. The gpio code is tweeked and some additional devices are added to devices.c. The Makefile uses -mv4e as apparently, the only difference a v4m (m5441x) and a v4e is the later has a FPU, which I don't think should matter to us in the kernel. Signed-off-by: Steven King Signed-off-by: Greg Ungerer --- arch/m68k/Kconfig.cpu | 8 + arch/m68k/Makefile | 1 + arch/m68k/include/asm/gpio.h | 10 +- arch/m68k/include/asm/m5441xsim.h | 270 ++++++++++++++++++++++++++++++++ arch/m68k/include/asm/m54xxacr.h | 4 + arch/m68k/include/asm/mcfclk.h | 43 +++++ arch/m68k/include/asm/mcfgpio.h | 30 +++- arch/m68k/include/asm/mcfsim.h | 2 + arch/m68k/include/asm/mcftimer.h | 2 +- arch/m68k/platform/coldfire/Makefile | 1 + arch/m68k/platform/coldfire/clk.c | 105 ++++++++++++- arch/m68k/platform/coldfire/device.c | 57 ++++++- arch/m68k/platform/coldfire/intc-simr.c | 26 ++- arch/m68k/platform/coldfire/m5441x.c | 224 ++++++++++++++++++++++++++ arch/m68k/platform/coldfire/timers.c | 2 +- 15 files changed, 761 insertions(+), 24 deletions(-) create mode 100644 arch/m68k/include/asm/m5441xsim.h create mode 100644 arch/m68k/include/asm/mcfclk.h create mode 100644 arch/m68k/platform/coldfire/m5441x.c (limited to 'arch/m68k') diff --git a/arch/m68k/Kconfig.cpu b/arch/m68k/Kconfig.cpu index 8d9afb09f569..43a9f8f1b8eb 100644 --- a/arch/m68k/Kconfig.cpu +++ b/arch/m68k/Kconfig.cpu @@ -261,6 +261,14 @@ config M548x help Freescale ColdFire 5480/5481/5482/5483/5484/5485 processor support. +config M5441x + bool "MCF5441x" + depends on !MMU + select GENERIC_CLOCKEVENTS + select HAVE_CACHE_CB + help + Freescale Coldfire 54410/54415/54416/54417/54418 processor support. + endif # COLDFIRE diff --git a/arch/m68k/Makefile b/arch/m68k/Makefile index 8daf9697e5e2..7636751f2f87 100644 --- a/arch/m68k/Makefile +++ b/arch/m68k/Makefile @@ -41,6 +41,7 @@ cpuflags-$(CONFIG_M68030) := cpuflags-$(CONFIG_M68020) := cpuflags-$(CONFIG_M68360) := -m68332 cpuflags-$(CONFIG_M68000) := -m68000 +cpuflags-$(CONFIG_M5441x) := $(call cc-option,-mcpu=54455,-mcfv4e) cpuflags-$(CONFIG_M54xx) := $(call cc-option,-mcpu=5475,-m5200) cpuflags-$(CONFIG_M5407) := $(call cc-option,-mcpu=5407,-m5200) cpuflags-$(CONFIG_M532x) := $(call cc-option,-mcpu=532x,-m5307) diff --git a/arch/m68k/include/asm/gpio.h b/arch/m68k/include/asm/gpio.h index 530862207ecf..4395ffc51fdb 100644 --- a/arch/m68k/include/asm/gpio.h +++ b/arch/m68k/include/asm/gpio.h @@ -64,8 +64,14 @@ static inline void gpio_set_value(unsigned gpio, int value) static inline int gpio_to_irq(unsigned gpio) { - return (gpio < MCFGPIO_IRQ_MAX) ? gpio + MCFGPIO_IRQ_VECBASE - : __gpio_to_irq(gpio); +#if defined(MCFGPIO_IRQ_MIN) + if ((gpio >= MCFGPIO_IRQ_MIN) && (gpio < MCFGPIO_IRQ_MAX)) +#else + if (gpio < MCFGPIO_IRQ_MAX) +#endif + return gpio + MCFGPIO_IRQ_VECBASE; + else + return __gpio_to_irq(gpio); } static inline int irq_to_gpio(unsigned irq) diff --git a/arch/m68k/include/asm/m5441xsim.h b/arch/m68k/include/asm/m5441xsim.h new file mode 100644 index 000000000000..86315a96604d --- /dev/null +++ b/arch/m68k/include/asm/m5441xsim.h @@ -0,0 +1,270 @@ +/* + * m5441xsim.h -- Coldfire 5441x register definitions + * + * (C) Copyright 2012, Steven King +*/ + +#ifndef m5441xsim_h +#define m5441xsim_h + +#define CPU_NAME "COLDFIRE(m5441x)" +#define CPU_INSTR_PER_JIFFY 2 +#define MCF_BUSCLK (MCF_CLK / 2) + +#include + +/* + * Reset Controller Module. + */ + +#define MCF_RCR 0xec090000 +#define MCF_RSR 0xec090001 + +#define MCF_RCR_SWRESET 0x80 /* Software reset bit */ +#define MCF_RCR_FRCSTOUT 0x40 /* Force external reset */ + +/* + * Interrupt Controller Modules. + */ +/* the 5441x have 3 interrupt controllers, each control 64 interrupts */ +#define MCFINT_VECBASE 64 +#define MCFINT0_VECBASE MCFINT_VECBASE +#define MCFINT1_VECBASE (MCFINT0_VECBASE + 64) +#define MCFINT2_VECBASE (MCFINT1_VECBASE + 64) + +/* interrupt controller 0 */ +#define MCFINTC0_SIMR 0xfc04801c +#define MCFINTC0_CIMR 0xfc04801d +#define MCFINTC0_ICR0 0xfc048040 +/* interrupt controller 1 */ +#define MCFINTC1_SIMR 0xfc04c01c +#define MCFINTC1_CIMR 0xfc04c01d +#define MCFINTC1_ICR0 0xfc04c040 +/* interrupt controller 2 */ +#define MCFINTC2_SIMR 0xfc05001c +#define MCFINTC2_CIMR 0xfc05001d +#define MCFINTC2_ICR0 0xfc050040 + +/* on interrupt controller 0 */ +#define MCFINT0_EPORT0 1 +#define MCFINT0_UART0 26 +#define MCFINT0_UART1 27 +#define MCFINT0_UART2 28 +#define MCFINT0_UART3 29 +#define MCFINT0_I2C0 30 +#define MCFINT0_DSPI0 31 + +#define MCFINT0_TIMER0 32 +#define MCFINT0_TIMER1 33 +#define MCFINT0_TIMER2 34 +#define MCFINT0_TIMER3 35 + +#define MCFINT0_FECRX0 36 +#define MCFINT0_FECTX0 40 +#define MCFINT0_FECENTC0 42 + +#define MCFINT0_FECRX1 49 +#define MCFINT0_FECTX1 53 +#define MCFINT0_FECENTC1 55 + +/* on interrupt controller 1 */ +#define MCFINT1_UART4 48 +#define MCFINT1_UART5 49 +#define MCFINT1_UART6 50 +#define MCFINT1_UART7 51 +#define MCFINT1_UART8 52 +#define MCFINT1_UART9 53 +#define MCFINT1_DSPI1 54 +#define MCFINT1_DSPI2 55 +#define MCFINT1_DSPI3 56 +#define MCFINT1_I2C1 57 +#define MCFINT1_I2C2 58 +#define MCFINT1_I2C3 59 +#define MCFINT1_I2C4 60 +#define MCFINT1_I2C5 61 + +/* on interrupt controller 2 */ +#define MCFINT2_PIT0 13 +#define MCFINT2_PIT1 14 +#define MCFINT2_PIT2 15 +#define MCFINT2_PIT3 16 +#define MCFINT2_RTC 26 + +/* + * PIT timer module. + */ +#define MCFPIT_BASE0 0xFC080000 /* Base address of TIMER0 */ +#define MCFPIT_BASE1 0xFC084000 /* Base address of TIMER1 */ +#define MCFPIT_BASE2 0xFC088000 /* Base address of TIMER2 */ +#define MCFPIT_BASE3 0xFC08C000 /* Base address of TIMER3 */ + + +#define MCF_IRQ_PIT1 (MCFINT2_VECBASE + MCFINT2_PIT1) + +/* + * Power Management + */ +#define MCFPM_WCR 0xfc040013 +#define MCFPM_PPMSR0 0xfc04002c +#define MCFPM_PPMCR0 0xfc04002d +#define MCFPM_PPMSR1 0xfc04002e +#define MCFPM_PPMCR1 0xfc04002f +#define MCFPM_PPMHR0 0xfc040030 +#define MCFPM_PPMLR0 0xfc040034 +#define MCFPM_PPMHR1 0xfc040038 +#define MCFPM_PPMLR1 0xfc04003c +#define MCFPM_LPCR 0xec090007 +/* + * UART module. + */ +#define MCFUART_BASE0 0xfc060000 /* Base address of UART0 */ +#define MCFUART_BASE1 0xfc064000 /* Base address of UART1 */ +#define MCFUART_BASE2 0xfc068000 /* Base address of UART2 */ +#define MCFUART_BASE3 0xfc06c000 /* Base address of UART3 */ +#define MCFUART_BASE4 0xec060000 /* Base address of UART4 */ +#define MCFUART_BASE5 0xec064000 /* Base address of UART5 */ +#define MCFUART_BASE6 0xec068000 /* Base address of UART6 */ +#define MCFUART_BASE7 0xec06c000 /* Base address of UART7 */ +#define MCFUART_BASE8 0xec070000 /* Base address of UART8 */ +#define MCFUART_BASE9 0xec074000 /* Base address of UART9 */ + +#define MCF_IRQ_UART0 (MCFINT0_VECBASE + MCFINT0_UART0) +#define MCF_IRQ_UART1 (MCFINT0_VECBASE + MCFINT0_UART1) +#define MCF_IRQ_UART2 (MCFINT0_VECBASE + MCFINT0_UART2) +#define MCF_IRQ_UART3 (MCFINT0_VECBASE + MCFINT0_UART3) +#define MCF_IRQ_UART4 (MCFINT1_VECBASE + MCFINT1_UART4) +#define MCF_IRQ_UART5 (MCFINT1_VECBASE + MCFINT1_UART5) +#define MCF_IRQ_UART6 (MCFINT1_VECBASE + MCFINT1_UART6) +#define MCF_IRQ_UART7 (MCFINT1_VECBASE + MCFINT1_UART7) +#define MCF_IRQ_UART8 (MCFINT1_VECBASE + MCFINT1_UART8) +#define MCF_IRQ_UART9 (MCFINT1_VECBASE + MCFINT1_UART9) +/* + * FEC modules. + */ +#define MCFFEC_BASE0 0xfc0d4000 +#define MCFFEC_SIZE0 0x800 +#define MCF_IRQ_FECRX0 (MCFINT0_VECBASE + MCFINT0_FECRX0) +#define MCF_IRQ_FECTX0 (MCFINT0_VECBASE + MCFINT0_FECTX0) +#define MCF_IRQ_FECENTC0 (MCFINT0_VECBASE + MCFINT0_FECENTC0) + +#define MCFFEC_BASE1 0xfc0d8000 +#define MCFFEC_SIZE1 0x800 +#define MCF_IRQ_FECRX1 (MCFINT0_VECBASE + MCFINT0_FECRX1) +#define MCF_IRQ_FECTX1 (MCFINT0_VECBASE + MCFINT0_FECTX1) +#define MCF_IRQ_FECENTC1 (MCFINT0_VECBASE + MCFINT0_FECENTC1) +/* + * I2C modules. + */ +#define MCFI2C_BASE0 0xfc058000 +#define MCFI2C_SIZE0 0x20 +#define MCFI2C_BASE1 0xfc038000 +#define MCFI2C_SIZE1 0x20 +#define MCFI2C_BASE2 0xec010000 +#define MCFI2C_SIZE2 0x20 +#define MCFI2C_BASE3 0xec014000 +#define MCFI2C_SIZE3 0x20 +#define MCFI2C_BASE4 0xec018000 +#define MCFI2C_SIZE4 0x20 +#define MCFI2C_BASE5 0xec01c000 +#define MCFI2C_SIZE5 0x20 + +#define MCF_IRQ_I2C0 (MCFINT0_VECBASE + MCFINT0_I2C0) +#define MCF_IRQ_I2C1 (MCFINT1_VECBASE + MCFINT1_I2C1) +#define MCF_IRQ_I2C2 (MCFINT1_VECBASE + MCFINT1_I2C2) +#define MCF_IRQ_I2C3 (MCFINT1_VECBASE + MCFINT1_I2C3) +#define MCF_IRQ_I2C4 (MCFINT1_VECBASE + MCFINT1_I2C4) +#define MCF_IRQ_I2C5 (MCFINT1_VECBASE + MCFINT1_I2C5) +/* + * EPORT Module. + */ +#define MCFEPORT_EPPAR 0xfc090000 +#define MCFEPORT_EPIER 0xfc090003 +#define MCFEPORT_EPFR 0xfc090006 + +/* + * GPIO Module. + */ +#define MCFGPIO_PODR_A 0xec094000 +#define MCFGPIO_PODR_B 0xec094001 +#define MCFGPIO_PODR_C 0xec094002 +#define MCFGPIO_PODR_D 0xec094003 +#define MCFGPIO_PODR_E 0xec094004 +#define MCFGPIO_PODR_F 0xec094005 +#define MCFGPIO_PODR_G 0xec094006 +#define MCFGPIO_PODR_H 0xec094007 +#define MCFGPIO_PODR_I 0xec094008 +#define MCFGPIO_PODR_J 0xec094009 +#define MCFGPIO_PODR_K 0xec09400a + +#define MCFGPIO_PDDR_A 0xec09400c +#define MCFGPIO_PDDR_B 0xec09400d +#define MCFGPIO_PDDR_C 0xec09400e +#define MCFGPIO_PDDR_D 0xec09400f +#define MCFGPIO_PDDR_E 0xec094010 +#define MCFGPIO_PDDR_F 0xec094011 +#define MCFGPIO_PDDR_G 0xec094012 +#define MCFGPIO_PDDR_H 0xec094013 +#define MCFGPIO_PDDR_I 0xec094014 +#define MCFGPIO_PDDR_J 0xec094015 +#define MCFGPIO_PDDR_K 0xec094016 + +#define MCFGPIO_PPDSDR_A 0xec094018 +#define MCFGPIO_PPDSDR_B 0xec094019 +#define MCFGPIO_PPDSDR_C 0xec09401a +#define MCFGPIO_PPDSDR_D 0xec09401b +#define MCFGPIO_PPDSDR_E 0xec09401c +#define MCFGPIO_PPDSDR_F 0xec09401d +#define MCFGPIO_PPDSDR_G 0xec09401e +#define MCFGPIO_PPDSDR_H 0xec09401f +#define MCFGPIO_PPDSDR_I 0xec094020 +#define MCFGPIO_PPDSDR_J 0xec094021 +#define MCFGPIO_PPDSDR_K 0xec094022 + +#define MCFGPIO_PCLRR_A 0xec094024 +#define MCFGPIO_PCLRR_B 0xec094025 +#define MCFGPIO_PCLRR_C 0xec094026 +#define MCFGPIO_PCLRR_D 0xec094027 +#define MCFGPIO_PCLRR_E 0xec094028 +#define MCFGPIO_PCLRR_F 0xec094029 +#define MCFGPIO_PCLRR_G 0xec09402a +#define MCFGPIO_PCLRR_H 0xec09402b +#define MCFGPIO_PCLRR_I 0xec09402c +#define MCFGPIO_PCLRR_J 0xec09402d +#define MCFGPIO_PCLRR_K 0xec09402e + +#define MCFGPIO_PAR_FBCTL 0xec094048 +#define MCFGPIO_PAR_BE 0xec094049 +#define MCFGPIO_PAR_CS 0xec09404a +#define MCFGPIO_PAR_CANI2C 0xec09404b +#define MCFGPIO_PAR_IRQ0H 0xec09404c +#define MCFGPIO_PAR_IRQ0L 0xec09404d +#define MCFGPIO_PAR_DSPIOWH 0xec09404e +#define MCFGPIO_PAR_DSPIOWL 0xec09404f +#define MCFGPIO_PAR_TIMER 0xec094050 +#define MCFGPIO_PAR_UART2 0xec094051 +#define MCFGPIO_PAR_UART1 0xec094052 +#define MCFGPIO_PAR_UART0 0xec094053 +#define MCFGPIO_PAR_SDHCH 0xec094054 +#define MCFGPIO_PAR_SDHCL 0xec094055 +#define MCFGPIO_PAR_SIMP0H 0xec094056 +#define MCFGPIO_PAR_SIMP0L 0xec094057 +#define MCFGPIO_PAR_SSI0H 0xec094058 +#define MCFGPIO_PAR_SSI0L 0xec094059 +#define MCFGPIO_PAR_DEBUGH1 0xec09405a +#define MCFGPIO_PAR_DEBUGH0 0xec09405b +#define MCFGPIO_PAR_DEBUGl 0xec09405c +#define MCFGPIO_PAR_FEC 0xec09405e + +/* generalization for generic gpio support */ +#define MCFGPIO_PODR MCFGPIO_PODR_A +#define MCFGPIO_PDDR MCFGPIO_PDDR_A +#define MCFGPIO_PPDR MCFGPIO_PPDSDR_A +#define MCFGPIO_SETR MCFGPIO_PPDSDR_A +#define MCFGPIO_CLRR MCFGPIO_PCLRR_A + +#define MCFGPIO_IRQ_MIN 17 +#define MCFGPIO_IRQ_MAX 24 +#define MCFGPIO_IRQ_VECBASE (MCFINT_VECBASE - MCFGPIO_IRQ_MIN) +#define MCFGPIO_PIN_MAX 87 + +#endif /* m5441xsim_h */ diff --git a/arch/m68k/include/asm/m54xxacr.h b/arch/m68k/include/asm/m54xxacr.h index 47906aafbf67..192bbfeabf70 100644 --- a/arch/m68k/include/asm/m54xxacr.h +++ b/arch/m68k/include/asm/m54xxacr.h @@ -55,6 +55,10 @@ #define ICACHE_SIZE 0x8000 /* instruction - 32k */ #define DCACHE_SIZE 0x8000 /* data - 32k */ +#elif defined(CONFIG_M5441x) + +#define ICACHE_SIZE 0x2000 /* instruction - 8k */ +#define DCACHE_SIZE 0x2000 /* data - 8k */ #endif #define CACHE_LINE_SIZE 0x0010 /* 16 bytes */ diff --git a/arch/m68k/include/asm/mcfclk.h b/arch/m68k/include/asm/mcfclk.h new file mode 100644 index 000000000000..b676a02bb392 --- /dev/null +++ b/arch/m68k/include/asm/mcfclk.h @@ -0,0 +1,43 @@ +/* + * mcfclk.h -- coldfire specific clock structure + */ + + +#ifndef mcfclk_h +#define mcfclk_h + +struct clk; + +#ifdef MCFPM_PPMCR0 +struct clk_ops { + void (*enable)(struct clk *); + void (*disable)(struct clk *); +}; + +struct clk { + const char *name; + struct clk_ops *clk_ops; + unsigned long rate; + unsigned long enabled; + u8 slot; +}; + +extern struct clk *mcf_clks[]; +extern struct clk_ops clk_ops0; +#ifdef MCFPM_PPMCR1 +extern struct clk_ops clk_ops1; +#endif /* MCFPM_PPMCR1 */ + +#define DEFINE_CLK(clk_bank, clk_name, clk_slot, clk_rate) \ +static struct clk __clk_##clk_bank##_##clk_slot = { \ + .name = clk_name, \ + .clk_ops = &clk_ops##clk_bank, \ + .rate = clk_rate, \ + .slot = clk_slot, \ +} + +void __clk_init_enabled(struct clk *); +void __clk_init_disabled(struct clk *); +#endif /* MCFPM_PPMCR0 */ + +#endif /* mcfclk_h */ diff --git a/arch/m68k/include/asm/mcfgpio.h b/arch/m68k/include/asm/mcfgpio.h index b2471a5f02eb..fa1059f50dfc 100644 --- a/arch/m68k/include/asm/mcfgpio.h +++ b/arch/m68k/include/asm/mcfgpio.h @@ -104,7 +104,8 @@ static inline void gpio_free(unsigned gpio) #if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \ defined(CONFIG_M520x) || defined(CONFIG_M523x) || \ defined(CONFIG_M527x) || defined(CONFIG_M528x) || \ - defined(CONFIG_M532x) || defined(CONFIG_M54xx) + defined(CONFIG_M532x) || defined(CONFIG_M54xx) || \ + defined(CONFIG_M5441x) /* These parts have GPIO organized by 8 bit ports */ @@ -137,7 +138,8 @@ static inline void gpio_free(unsigned gpio) #define mcfgpio_port(gpio) ((gpio) / MCFGPIO_PORTSIZE) #if defined(CONFIG_M520x) || defined(CONFIG_M523x) || \ - defined(CONFIG_M527x) || defined(CONFIG_M528x) || defined(CONFIG_M532x) + defined(CONFIG_M527x) || defined(CONFIG_M528x) || \ + defined(CONFIG_M532x) || defined(CONFIG_M5441x) /* * These parts have an 'Edge' Port module (external interrupt/GPIO) which uses * read-modify-write to change an output and a GPIO module which has separate @@ -149,6 +151,9 @@ static inline void gpio_free(unsigned gpio) * read-modify-write as well as those controlled by the EPORT and GPIO modules. */ #define MCFGPIO_SCR_START 40 +#elif defined(CONFIGM5441x) +/* The m5441x EPORT doesn't have its own GPIO port, uses PORT C */ +#define MCFGPIO_SCR_START 0 #else #define MCFGPIO_SCR_START 8 #endif @@ -189,7 +194,9 @@ static inline u32 __mcfgpio_ppdr(unsigned gpio) else return MCFSIM2_GPIO1READ; #elif defined(CONFIG_M520x) || defined(CONFIG_M523x) || \ - defined(CONFIG_M527x) || defined(CONFIG_M528x) || defined(CONFIG_M532x) + defined(CONFIG_M527x) || defined(CONFIG_M528x) || \ + defined(CONFIG_M532x) || defined(CONFIG_M5441x) +#if !defined(CONFIG_M5441x) if (gpio < 8) return MCFEPORT_EPPDR; #if defined(CONFIG_M528x) @@ -201,8 +208,9 @@ static inline u32 __mcfgpio_ppdr(unsigned gpio) return MCFQADC_PORTQA; else if (gpio < 40) return MCFQADC_PORTQB; -#endif +#endif /* defined(CONFIG_M528x) */ else +#endif /* !defined(CONFIG_M5441x) */ return MCFGPIO_PPDR + mcfgpio_port(gpio - MCFGPIO_SCR_START); #else return 0; @@ -228,7 +236,9 @@ static inline u32 __mcfgpio_podr(unsigned gpio) else return MCFSIM2_GPIO1WRITE; #elif defined(CONFIG_M520x) || defined(CONFIG_M523x) || \ - defined(CONFIG_M527x) || defined(CONFIG_M528x) || defined(CONFIG_M532x) + defined(CONFIG_M527x) || defined(CONFIG_M528x) || \ + defined(CONFIG_M532x) || defined(CONFIG_M5441x) +#if !defined(CONFIG_M5441x) if (gpio < 8) return MCFEPORT_EPDR; #if defined(CONFIG_M528x) @@ -240,8 +250,9 @@ static inline u32 __mcfgpio_podr(unsigned gpio) return MCFQADC_PORTQA; else if (gpio < 40) return MCFQADC_PORTQB; -#endif +#endif /* defined(CONFIG_M528x) */ else +#endif /* !defined(CONFIG_M5441x) */ return MCFGPIO_PODR + mcfgpio_port(gpio - MCFGPIO_SCR_START); #else return 0; @@ -267,7 +278,9 @@ static inline u32 __mcfgpio_pddr(unsigned gpio) else return MCFSIM2_GPIO1ENABLE; #elif defined(CONFIG_M520x) || defined(CONFIG_M523x) || \ - defined(CONFIG_M527x) || defined(CONFIG_M528x) || defined(CONFIG_M532x) + defined(CONFIG_M527x) || defined(CONFIG_M528x) || \ + defined(CONFIG_M532x) || defined(CONFIG_M5441x) +#if !defined(CONFIG_M5441x) if (gpio < 8) return MCFEPORT_EPDDR; #if defined(CONFIG_M528x) @@ -279,8 +292,9 @@ static inline u32 __mcfgpio_pddr(unsigned gpio) return MCFQADC_DDRQA; else if (gpio < 40) return MCFQADC_DDRQB; -#endif +#endif /* defined(CONFIG_M528x) */ else +#endif /* !defined(CONFIG_M5441x) */ return MCFGPIO_PDDR + mcfgpio_port(gpio - MCFGPIO_SCR_START); #else return 0; diff --git a/arch/m68k/include/asm/mcfsim.h b/arch/m68k/include/asm/mcfsim.h index 6871f62b11b1..7a83e619e73b 100644 --- a/arch/m68k/include/asm/mcfsim.h +++ b/arch/m68k/include/asm/mcfsim.h @@ -46,6 +46,8 @@ #include #elif defined(CONFIG_M54xx) #include +#elif defined(CONFIG_M5441x) +#include #endif /****************************************************************************/ diff --git a/arch/m68k/include/asm/mcftimer.h b/arch/m68k/include/asm/mcftimer.h index 351c27237874..da2fa43c2e45 100644 --- a/arch/m68k/include/asm/mcftimer.h +++ b/arch/m68k/include/asm/mcftimer.h @@ -19,7 +19,7 @@ #define MCFTIMER_TRR 0x04 /* Timer Reference (r/w) */ #define MCFTIMER_TCR 0x08 /* Timer Capture reg (r/w) */ #define MCFTIMER_TCN 0x0C /* Timer Counter reg (r/w) */ -#if defined(CONFIG_M532x) +#if defined(CONFIG_M532x) || defined(CONFIG_M5441x) #define MCFTIMER_TER 0x03 /* Timer Event reg (r/w) */ #else #define MCFTIMER_TER 0x11 /* Timer Event reg (r/w) */ diff --git a/arch/m68k/platform/coldfire/Makefile b/arch/m68k/platform/coldfire/Makefile index a7329b4fbef8..b3f8bfda52e2 100644 --- a/arch/m68k/platform/coldfire/Makefile +++ b/arch/m68k/platform/coldfire/Makefile @@ -28,6 +28,7 @@ obj-$(CONFIG_M5307) += m5307.o timers.o intc.o reset.o obj-$(CONFIG_M532x) += m532x.o timers.o intc-simr.o reset.o obj-$(CONFIG_M5407) += m5407.o timers.o intc.o reset.o obj-$(CONFIG_M54xx) += m54xx.o sltimers.o intc-2.o +obj-$(CONFIG_M5441x) += m5441x.o pit.o intc-simr.o reset.o obj-$(CONFIG_NETtel) += nettel.o obj-$(CONFIG_CLEOPATRA) += nettel.o diff --git a/arch/m68k/platform/coldfire/clk.c b/arch/m68k/platform/coldfire/clk.c index 44da406897e5..c06c0f4a0ffc 100644 --- a/arch/m68k/platform/coldfire/clk.c +++ b/arch/m68k/platform/coldfire/clk.c @@ -10,11 +10,17 @@ #include #include +#include +#include #include +#include +#include #include +#include +#include /***************************************************************************/ - +#ifndef MCFPM_PPMCR0 struct clk *clk_get(struct device *dev, const char *id) { return NULL; @@ -49,4 +55,101 @@ struct clk *devm_clk_get(struct device *dev, const char *id) } EXPORT_SYMBOL(devm_clk_get); +#else +static DEFINE_SPINLOCK(clk_lock); + +struct clk *clk_get(struct device *dev, const char *id) +{ + const char *clk_name = dev ? dev_name(dev) : id ? id : NULL; + struct clk *clk; + unsigned i; + + for (i = 0; (clk = mcf_clks[i]) != NULL; ++i) + if (!strcmp(clk->name, clk_name)) + return clk; + pr_warn("clk_get: didn't find clock %s\n", clk_name); + return ERR_PTR(-ENOENT); +} +EXPORT_SYMBOL(clk_get); + +int clk_enable(struct clk *clk) +{ + unsigned long flags; + spin_lock_irqsave(&clk_lock, flags); + if ((clk->enabled++ == 0) && clk->clk_ops) + clk->clk_ops->enable(clk); + spin_unlock_irqrestore(&clk_lock, flags); + + return 0; +} +EXPORT_SYMBOL(clk_enable); + +void clk_disable(struct clk *clk) +{ + unsigned long flags; + spin_lock_irqsave(&clk_lock, flags); + if ((--clk->enabled == 0) && clk->clk_ops) + clk->clk_ops->disable(clk); + spin_unlock_irqrestore(&clk_lock, flags); +} +EXPORT_SYMBOL(clk_disable); + +void clk_put(struct clk *clk) +{ + if (clk->enabled != 0) + pr_warn("clk_put %s still enabled\n", clk->name); +} +EXPORT_SYMBOL(clk_put); + +unsigned long clk_get_rate(struct clk *clk) +{ + return clk->rate; +} +EXPORT_SYMBOL(clk_get_rate); + /***************************************************************************/ + +void __clk_init_enabled(struct clk *clk) +{ + clk->enabled = 1; + clk->clk_ops->enable(clk); +} + +void __clk_init_disabled(struct clk *clk) +{ + clk->enabled = 0; + clk->clk_ops->disable(clk); +} + +static void __clk_enable0(struct clk *clk) +{ + __raw_writeb(clk->slot, MCFPM_PPMCR0); +} + +static void __clk_disable0(struct clk *clk) +{ + __raw_writeb(clk->slot, MCFPM_PPMSR0); +} + +struct clk_ops clk_ops0 = { + .enable = __clk_enable0, + .disable = __clk_disable0, +}; + +#ifdef MCFPM_PPMCR1 +static void __clk_enable1(struct clk *clk) +{ + __raw_writeb(clk->slot, MCFPM_PPMCR1); +} + +static void __clk_disable1(struct clk *clk) +{ + __raw_writeb(clk->slot, MCFPM_PPMSR1); +} + +struct clk_ops clk_ops1 = { + .enable = __clk_enable1, + .disable = __clk_disable1, +}; +#endif /* MCFPM_PPMCR1 */ +#endif /* MCFPM_PPMCR0 */ diff --git a/arch/m68k/platform/coldfire/device.c b/arch/m68k/platform/coldfire/device.c index 3aa77ddea89d..81f0fb5e51cf 100644 --- a/arch/m68k/platform/coldfire/device.c +++ b/arch/m68k/platform/coldfire/device.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -20,7 +21,7 @@ #include /* - * All current ColdFire parts contain from 2, 3 or 4 UARTS. + * All current ColdFire parts contain from 2, 3, 4 or 10 UARTS. */ static struct mcf_platform_uart mcf_uart_platform_data[] = { { @@ -42,6 +43,42 @@ static struct mcf_platform_uart mcf_uart_platform_data[] = { .mapbase = MCFUART_BASE3, .irq = MCF_IRQ_UART3, }, +#endif +#ifdef MCFUART_BASE4 + { + .mapbase = MCFUART_BASE4, + .irq = MCF_IRQ_UART4, + }, +#endif +#ifdef MCFUART_BASE5 + { + .mapbase = MCFUART_BASE5, + .irq = MCF_IRQ_UART5, + }, +#endif +#ifdef MCFUART_BASE6 + { + .mapbase = MCFUART_BASE6, + .irq = MCF_IRQ_UART6, + }, +#endif +#ifdef MCFUART_BASE7 + { + .mapbase = MCFUART_BASE7, + .irq = MCF_IRQ_UART7, + }, +#endif +#ifdef MCFUART_BASE8 + { + .mapbase = MCFUART_BASE8, + .irq = MCF_IRQ_UART8, + }, +#endif +#ifdef MCFUART_BASE9 + { + .mapbase = MCFUART_BASE9, + .irq = MCF_IRQ_UART9, + }, #endif { }, }; @@ -53,6 +90,18 @@ static struct platform_device mcf_uart = { }; #ifdef CONFIG_FEC + +#ifdef CONFIG_M5441x +#define FEC_NAME "enet-fec" +static struct fec_platform_data fec_pdata = { + .phy = PHY_INTERFACE_MODE_RMII, +}; +#define FEC_PDATA (&fec_pdata) +#else +#define FEC_NAME "fec" +#define FEC_PDATA NULL +#endif + /* * Some ColdFire cores contain the Fast Ethernet Controller (FEC) * block. It is Freescale's own hardware block. Some ColdFires @@ -82,10 +131,11 @@ static struct resource mcf_fec0_resources[] = { }; static struct platform_device mcf_fec0 = { - .name = "fec", + .name = FEC_NAME, .id = 0, .num_resources = ARRAY_SIZE(mcf_fec0_resources), .resource = mcf_fec0_resources, + .dev.platform_data = FEC_PDATA, }; #ifdef MCFFEC_BASE1 @@ -113,10 +163,11 @@ static struct resource mcf_fec1_resources[] = { }; static struct platform_device mcf_fec1 = { - .name = "fec", + .name = FEC_NAME, .id = 1, .num_resources = ARRAY_SIZE(mcf_fec1_resources), .resource = mcf_fec1_resources, + .dev.platform_data = FEC_PDATA, }; #endif /* MCFFEC_BASE1 */ #endif /* CONFIG_FEC */ diff --git a/arch/m68k/platform/coldfire/intc-simr.c b/arch/m68k/platform/coldfire/intc-simr.c index 650d52e2927e..7cf2c156f72d 100644 --- a/arch/m68k/platform/coldfire/intc-simr.c +++ b/arch/m68k/platform/coldfire/intc-simr.c @@ -59,16 +59,18 @@ static unsigned int inline irq2ebit(unsigned int irq) #endif /* - * There maybe one or two interrupt control units, each has 64 - * interrupts. If there is no second unit then MCFINTC1_* defines - * will be 0 (and code for them optimized away). + * There maybe one, two or three interrupt control units, each has 64 + * interrupts. If there is no second or third unit then MCFINTC1_* or + * MCFINTC2_* defines will be 0 (and code for them optimized away). */ static void intc_irq_mask(struct irq_data *d) { unsigned int irq = d->irq - MCFINT_VECBASE; - if (MCFINTC1_SIMR && (irq > 64)) + if (MCFINTC2_SIMR && (irq > 128)) + __raw_writeb(irq - 128, MCFINTC2_SIMR); + else if (MCFINTC1_SIMR && (irq > 64)) __raw_writeb(irq - 64, MCFINTC1_SIMR); else __raw_writeb(irq, MCFINTC0_SIMR); @@ -78,7 +80,9 @@ static void intc_irq_unmask(struct irq_data *d) { unsigned int irq = d->irq - MCFINT_VECBASE; - if (MCFINTC1_CIMR && (irq > 64)) + if (MCFINTC2_CIMR && (irq > 128)) + __raw_writeb(irq - 128, MCFINTC2_CIMR); + else if (MCFINTC1_CIMR && (irq > 64)) __raw_writeb(irq - 64, MCFINTC1_CIMR); else __raw_writeb(irq, MCFINTC0_CIMR); @@ -99,9 +103,11 @@ static unsigned int intc_irq_startup(struct irq_data *d) unsigned int ebit = irq2ebit(irq); u8 v; +#if defined(MCFEPORT_EPDDR) /* Set EPORT line as input */ v = __raw_readb(MCFEPORT_EPDDR); __raw_writeb(v & ~(0x1 << ebit), MCFEPORT_EPDDR); +#endif /* Set EPORT line as interrupt source */ v = __raw_readb(MCFEPORT_EPIER); @@ -109,12 +115,13 @@ static unsigned int intc_irq_startup(struct irq_data *d) } irq -= MCFINT_VECBASE; - if (MCFINTC1_ICR0 && (irq > 64)) + if (MCFINTC2_ICR0 && (irq > 128)) + __raw_writeb(5, MCFINTC2_ICR0 + irq - 128); + else if (MCFINTC1_ICR0 && (irq > 64)) __raw_writeb(5, MCFINTC1_ICR0 + irq - 64); else __raw_writeb(5, MCFINTC0_ICR0 + irq); - intc_irq_unmask(d); return 0; } @@ -175,8 +182,11 @@ void __init init_IRQ(void) __raw_writeb(0xff, MCFINTC0_SIMR); if (MCFINTC1_SIMR) __raw_writeb(0xff, MCFINTC1_SIMR); + if (MCFINTC2_SIMR) + __raw_writeb(0xff, MCFINTC2_SIMR); - eirq = MCFINT_VECBASE + 64 + (MCFINTC1_ICR0 ? 64 : 0); + eirq = MCFINT_VECBASE + 64 + (MCFINTC1_ICR0 ? 64 : 0) + + (MCFINTC2_ICR0 ? 64 : 0); for (irq = MCFINT_VECBASE; (irq < eirq); irq++) { if ((irq >= EINT1) && (irq <= EINT7)) irq_set_chip(irq, &intc_irq_chip_edge_port); diff --git a/arch/m68k/platform/coldfire/m5441x.c b/arch/m68k/platform/coldfire/m5441x.c new file mode 100644 index 000000000000..3020ceaba629 --- /dev/null +++ b/arch/m68k/platform/coldfire/m5441x.c @@ -0,0 +1,224 @@ +/* + * m5441x.c -- support for Coldfire m5441x processors + * + * (C) Copyright Steven King + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DEFINE_CLK(0, "flexbus", 2, MCF_CLK); +DEFINE_CLK(0, "mcfcan.0", 8, MCF_CLK); +DEFINE_CLK(0, "mcfcan.1", 9, MCF_CLK); +DEFINE_CLK(0, "mcfi2c.1", 14, MCF_CLK); +DEFINE_CLK(0, "mcfdspi.1", 15, MCF_CLK); +DEFINE_CLK(0, "edma", 17, MCF_CLK); +DEFINE_CLK(0, "intc.0", 18, MCF_CLK); +DEFINE_CLK(0, "intc.1", 19, MCF_CLK); +DEFINE_CLK(0, "intc.2", 20, MCF_CLK); +DEFINE_CLK(0, "mcfi2c.0", 22, MCF_CLK); +DEFINE_CLK(0, "mcfdspi.0", 23, MCF_CLK); +DEFINE_CLK(0, "mcfuart.0", 24, MCF_BUSCLK); +DEFINE_CLK(0, "mcfuart.1", 25, MCF_BUSCLK); +DEFINE_CLK(0, "mcfuart.2", 26, MCF_BUSCLK); +DEFINE_CLK(0, "mcfuart.3", 27, MCF_BUSCLK); +DEFINE_CLK(0, "mcftmr.0", 28, MCF_CLK); +DEFINE_CLK(0, "mcftmr.1", 29, MCF_CLK); +DEFINE_CLK(0, "mcftmr.2", 30, MCF_CLK); +DEFINE_CLK(0, "mcftmr.3", 31, MCF_CLK); +DEFINE_CLK(0, "mcfpit.0", 32, MCF_CLK); +DEFINE_CLK(0, "mcfpit.1", 33, MCF_CLK); +DEFINE_CLK(0, "mcfpit.2", 34, MCF_CLK); +DEFINE_CLK(0, "mcfpit.3", 35, MCF_CLK); +DEFINE_CLK(0, "mcfeport.0", 37, MCF_CLK); +DEFINE_CLK(0, "mcfadc.0", 38, MCF_CLK); +DEFINE_CLK(0, "mcfdac.0", 39, MCF_CLK); +DEFINE_CLK(0, "mcfrtc.0", 42, MCF_CLK); +DEFINE_CLK(0, "mcfsim.0", 43, MCF_CLK); +DEFINE_CLK(0, "mcfusb-otg.0", 44, MCF_CLK); +DEFINE_CLK(0, "mcfusb-host.0", 45, MCF_CLK); +DEFINE_CLK(0, "mcfddr-sram.0", 46, MCF_CLK); +DEFINE_CLK(0, "mcfssi.0", 47, MCF_CLK); +DEFINE_CLK(0, "pll.0", 48, MCF_CLK); +DEFINE_CLK(0, "mcfrng.0", 49, MCF_CLK); +DEFINE_CLK(0, "mcfssi.1", 50, MCF_CLK); +DEFINE_CLK(0, "mcfsdhc.0", 51, MCF_CLK); +DEFINE_CLK(0, "enet-fec.0", 53, MCF_CLK); +DEFINE_CLK(0, "enet-fec.1", 54, MCF_CLK); +DEFINE_CLK(0, "switch.0", 55, MCF_CLK); +DEFINE_CLK(0, "switch.1", 56, MCF_CLK); +DEFINE_CLK(0, "nand.0", 63, MCF_CLK); + +DEFINE_CLK(1, "mcfow.0", 2, MCF_CLK); +DEFINE_CLK(1, "mcfi2c.2", 4, MCF_CLK); +DEFINE_CLK(1, "mcfi2c.3", 5, MCF_CLK); +DEFINE_CLK(1, "mcfi2c.4", 6, MCF_CLK); +DEFINE_CLK(1, "mcfi2c.5", 7, MCF_CLK); +DEFINE_CLK(1, "mcfuart.4", 24, MCF_BUSCLK); +DEFINE_CLK(1, "mcfuart.5", 25, MCF_BUSCLK); +DEFINE_CLK(1, "mcfuart.6", 26, MCF_BUSCLK); +DEFINE_CLK(1, "mcfuart.7", 27, MCF_BUSCLK); +DEFINE_CLK(1, "mcfuart.8", 28, MCF_BUSCLK); +DEFINE_CLK(1, "mcfuart.9", 29, MCF_BUSCLK); +DEFINE_CLK(1, "mcfpwm.0", 34, MCF_BUSCLK); +DEFINE_CLK(1, "sys.0", 36, MCF_BUSCLK); +DEFINE_CLK(1, "gpio.0", 37, MCF_BUSCLK); + +struct clk *mcf_clks[] = { + &__clk_0_2, + &__clk_0_8, + &__clk_0_9, + &__clk_0_14, + &__clk_0_15, + &__clk_0_17, + &__clk_0_18, + &__clk_0_19, + &__clk_0_20, + &__clk_0_22, + &__clk_0_23, + &__clk_0_24, + &__clk_0_25, + &__clk_0_26, + &__clk_0_27, + &__clk_0_28, + &__clk_0_29, + &__clk_0_30, + &__clk_0_31, + &__clk_0_32, + &__clk_0_33, + &__clk_0_34, + &__clk_0_35, + &__clk_0_37, + &__clk_0_38, + &__clk_0_39, + &__clk_0_42, + &__clk_0_43, + &__clk_0_44, + &__clk_0_45, + &__clk_0_46, + &__clk_0_47, + &__clk_0_48, + &__clk_0_49, + &__clk_0_50, + &__clk_0_51, + &__clk_0_53, + &__clk_0_54, + &__clk_0_55, + &__clk_0_56, + &__clk_0_63, + + &__clk_1_2, + &__clk_1_4, + &__clk_1_5, + &__clk_1_6, + &__clk_1_7, + &__clk_1_24, + &__clk_1_25, + &__clk_1_26, + &__clk_1_27, + &__clk_1_28, + &__clk_1_29, + &__clk_1_34, + &__clk_1_36, + &__clk_1_37, + NULL, +}; + + +static struct clk * const enable_clks[] __initconst = { + /* make sure these clocks are enabled */ + &__clk_0_18, /* intc0 */ + &__clk_0_19, /* intc0 */ + &__clk_0_20, /* intc0 */ + &__clk_0_24, /* uart0 */ + &__clk_0_25, /* uart1 */ + &__clk_0_26, /* uart2 */ + &__clk_0_27, /* uart3 */ + + &__clk_0_33, /* pit.1 */ + &__clk_0_37, /* eport */ + &__clk_0_48, /* pll */ + + &__clk_1_36, /* CCM/reset module/Power management */ + &__clk_1_37, /* gpio */ +}; +static struct clk * const disable_clks[] __initconst = { + &__clk_0_8, /* can.0 */ + &__clk_0_9, /* can.1 */ + &__clk_0_14, /* i2c.1 */ + &__clk_0_15, /* dspi.1 */ + &__clk_0_17, /* eDMA */ + &__clk_0_22, /* i2c.0 */ + &__clk_0_23, /* dspi.0 */ + &__clk_0_28, /* tmr.1 */ + &__clk_0_29, /* tmr.2 */ + &__clk_0_30, /* tmr.2 */ + &__clk_0_31, /* tmr.3 */ + &__clk_0_32, /* pit.0 */ + &__clk_0_34, /* pit.2 */ + &__clk_0_35, /* pit.3 */ + &__clk_0_38, /* adc */ + &__clk_0_39, /* dac */ + &__clk_0_44, /* usb otg */ + &__clk_0_45, /* usb host */ + &__clk_0_47, /* ssi.0 */ + &__clk_0_49, /* rng */ + &__clk_0_50, /* ssi.1 */ + &__clk_0_51, /* eSDHC */ + &__clk_0_53, /* enet-fec */ + &__clk_0_54, /* enet-fec */ + &__clk_0_55, /* switch.0 */ + &__clk_0_56, /* switch.1 */ + + &__clk_1_2, /* 1-wire */ + &__clk_1_4, /* i2c.2 */ + &__clk_1_5, /* i2c.3 */ + &__clk_1_6, /* i2c.4 */ + &__clk_1_7, /* i2c.5 */ + &__clk_1_24, /* uart 4 */ + &__clk_1_25, /* uart 5 */ + &__clk_1_26, /* uart 6 */ + &__clk_1_27, /* uart 7 */ + &__clk_1_28, /* uart 8 */ + &__clk_1_29, /* uart 9 */ +}; + +static void __init m5441x_clk_init(void) +{ + unsigned i; + + for (i = 0; i < ARRAY_SIZE(enable_clks); ++i) + __clk_init_enabled(enable_clks[i]); + /* make sure these clocks are disabled */ + for (i = 0; i < ARRAY_SIZE(disable_clks); ++i) + __clk_init_disabled(disable_clks[i]); +} + +static void __init m5441x_uarts_init(void) +{ + __raw_writeb(0x0f, MCFGPIO_PAR_UART0); + __raw_writeb(0x00, MCFGPIO_PAR_UART1); + __raw_writeb(0x00, MCFGPIO_PAR_UART2); +} + +static void __init m5441x_fec_init(void) +{ + __raw_writeb(0x03, MCFGPIO_PAR_FEC); +} + +void __init config_BSP(char *commandp, int size) +{ + m5441x_clk_init(); + mach_sched_init = hw_timer_init; + m5441x_uarts_init(); + m5441x_fec_init(); +} diff --git a/arch/m68k/platform/coldfire/timers.c b/arch/m68k/platform/coldfire/timers.c index ed96ce50d79f..0a273e75408c 100644 --- a/arch/m68k/platform/coldfire/timers.c +++ b/arch/m68k/platform/coldfire/timers.c @@ -36,7 +36,7 @@ */ void coldfire_profile_init(void); -#if defined(CONFIG_M532x) +#if defined(CONFIG_M532x) || defined(CONFIG_M5441x) #define __raw_readtrr __raw_readl #define __raw_writetrr __raw_writel #else -- cgit v1.2.3 From 32234328e24a38d8f9c42bd534ebfbd73fce8435 Mon Sep 17 00:00:00 2001 From: Steven King Date: Fri, 8 Jun 2012 14:15:29 -0700 Subject: m68knommu: add definitions for the third interrupt controller on devices that don't have a third interrupt controller. Extending the interrupt controller code in intc-simr.c to support the third interrupt controller on the m5441x means we need to add defines (as 0) for the third interrupt controller on devices that don't have a third interrupt controller. Signed-off-by: Steven King Signed-off-by: Greg Ungerer --- arch/m68k/include/asm/m520xsim.h | 3 +++ arch/m68k/include/asm/m532xsim.h | 3 +++ 2 files changed, 6 insertions(+) (limited to 'arch/m68k') diff --git a/arch/m68k/include/asm/m520xsim.h b/arch/m68k/include/asm/m520xsim.h index 5a8b5e4da12b..b1bc76f1decc 100644 --- a/arch/m68k/include/asm/m520xsim.h +++ b/arch/m68k/include/asm/m520xsim.h @@ -42,6 +42,9 @@ #define MCFINTC1_SIMR (0) #define MCFINTC1_CIMR (0) #define MCFINTC1_ICR0 (0) +#define MCFINTC2_SIMR (0) +#define MCFINTC2_CIMR (0) +#define MCFINTC2_ICR0 (0) #define MCFINT_VECBASE 64 #define MCFINT_UART0 26 /* Interrupt number for UART0 */ diff --git a/arch/m68k/include/asm/m532xsim.h b/arch/m68k/include/asm/m532xsim.h index 29b66e21413a..8d860200a2f5 100644 --- a/arch/m68k/include/asm/m532xsim.h +++ b/arch/m68k/include/asm/m532xsim.h @@ -82,6 +82,9 @@ #define MCFINTC1_SIMR 0xFC04C01C #define MCFINTC1_CIMR 0xFC04C01D #define MCFINTC1_ICR0 0xFC04C040 +#define MCFINTC2_SIMR (0) +#define MCFINTC2_CIMR (0) +#define MCFINTC2_ICR0 (0) #define MCFSIM_ICR_TIMER1 (0xFC048040+32) #define MCFSIM_ICR_TIMER2 (0xFC048040+33) -- cgit v1.2.3 From c785a3d728b44fb49bfff481042fe81973476809 Mon Sep 17 00:00:00 2001 From: Steven King Date: Sun, 17 Jun 2012 01:03:38 -0700 Subject: m68knommu: Add rtc device for m5441x. Add definitions for the m5441x rtc device and an init_BSP function to the m5441x device code. Signed-off-by: Steven King --- arch/m68k/include/asm/m5441xsim.h | 6 ++++++ arch/m68k/platform/coldfire/clk.c | 13 ++++++------- arch/m68k/platform/coldfire/m5441x.c | 37 ++++++++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 7 deletions(-) (limited to 'arch/m68k') diff --git a/arch/m68k/include/asm/m5441xsim.h b/arch/m68k/include/asm/m5441xsim.h index 86315a96604d..cc798ab9524b 100644 --- a/arch/m68k/include/asm/m5441xsim.h +++ b/arch/m68k/include/asm/m5441xsim.h @@ -180,6 +180,12 @@ #define MCFEPORT_EPPAR 0xfc090000 #define MCFEPORT_EPIER 0xfc090003 #define MCFEPORT_EPFR 0xfc090006 +/* + * RTC Module. + */ +#define MCFRTC_BASE 0xfc0a8000 +#define MCFRTC_SIZE (0xfc0a8840 - 0xfc0a8000) +#define MCF_IRQ_RTC (MCFINT2_VECBASE + MCFINT2_RTC) /* * GPIO Module. diff --git a/arch/m68k/platform/coldfire/clk.c b/arch/m68k/platform/coldfire/clk.c index c06c0f4a0ffc..75f9ee967ea7 100644 --- a/arch/m68k/platform/coldfire/clk.c +++ b/arch/m68k/platform/coldfire/clk.c @@ -48,13 +48,6 @@ unsigned long clk_get_rate(struct clk *clk) return MCF_CLK; } EXPORT_SYMBOL(clk_get_rate); - -struct clk *devm_clk_get(struct device *dev, const char *id) -{ - return NULL; -} -EXPORT_SYMBOL(devm_clk_get); - #else static DEFINE_SPINLOCK(clk_lock); @@ -153,3 +146,9 @@ struct clk_ops clk_ops1 = { }; #endif /* MCFPM_PPMCR1 */ #endif /* MCFPM_PPMCR0 */ + +struct clk *devm_clk_get(struct device *dev, const char *id) +{ + return NULL; +} +EXPORT_SYMBOL(devm_clk_get); diff --git a/arch/m68k/platform/coldfire/m5441x.c b/arch/m68k/platform/coldfire/m5441x.c index 3020ceaba629..98a13cce93d8 100644 --- a/arch/m68k/platform/coldfire/m5441x.c +++ b/arch/m68k/platform/coldfire/m5441x.c @@ -222,3 +222,40 @@ void __init config_BSP(char *commandp, int size) m5441x_uarts_init(); m5441x_fec_init(); } + + +#if IS_ENABLED(CONFIG_RTC_DRV_M5441x) +static struct resource m5441x_rtc_resources[] = { + { + .start = MCFRTC_BASE, + .end = MCFRTC_BASE + MCFRTC_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = MCF_IRQ_RTC, + .end = MCF_IRQ_RTC, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device m5441x_rtc = { + .name = "mcfrtc", + .id = 0, + .resource = m5441x_rtc_resources, + .num_resources = ARRAY_SIZE(m5441x_rtc_resources), +}; +#endif + +static struct platform_device *m5441x_devices[] __initdata = { +#if IS_ENABLED(CONFIG_RTC_DRV_M5441x) + &m5441x_rtc, +#endif +}; + +static int __init init_BSP(void) +{ + platform_add_devices(m5441x_devices, ARRAY_SIZE(m5441x_devices)); + return 0; +} + +arch_initcall(init_BSP); -- cgit v1.2.3 From fe66158aaf44255d05f232f1eace281898e3ee75 Mon Sep 17 00:00:00 2001 From: Steven King Date: Sun, 17 Jun 2012 00:34:00 -0700 Subject: m68knommu: Add clk definitions for m520x. The 520x has individually controllable clocks for its peripherals. Add clk definitions for these and add default initialization of either enabled or disabled for all of the clocks. Signed-off-by: Steven King Signed-off-by: Greg Ungerer --- arch/m68k/include/asm/m520xsim.h | 10 ++++ arch/m68k/platform/coldfire/m520x.c | 97 +++++++++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+) (limited to 'arch/m68k') diff --git a/arch/m68k/include/asm/m520xsim.h b/arch/m68k/include/asm/m520xsim.h index b1bc76f1decc..db3f8ee4a6c6 100644 --- a/arch/m68k/include/asm/m520xsim.h +++ b/arch/m68k/include/asm/m520xsim.h @@ -190,5 +190,15 @@ #define MCF_RCR_SWRESET 0x80 /* Software reset bit */ #define MCF_RCR_FRCSTOUT 0x40 /* Force external reset */ +/* + * Power Management. + */ +#define MCFPM_WCR 0xfc040013 +#define MCFPM_PPMSR0 0xfc04002c +#define MCFPM_PPMCR0 0xfc04002d +#define MCFPM_PPMHR0 0xfc040030 +#define MCFPM_PPMLR0 0xfc040034 +#define MCFPM_LPCR 0xfc0a0007 + /****************************************************************************/ #endif /* m520xsim_h */ diff --git a/arch/m68k/platform/coldfire/m520x.c b/arch/m68k/platform/coldfire/m520x.c index 09df4b89e8be..ea1be0e98ad6 100644 --- a/arch/m68k/platform/coldfire/m520x.c +++ b/arch/m68k/platform/coldfire/m520x.c @@ -19,6 +19,102 @@ #include #include #include +#include + +/***************************************************************************/ + +DEFINE_CLK(0, "flexbus", 2, MCF_CLK); +DEFINE_CLK(0, "fec.0", 12, MCF_CLK); +DEFINE_CLK(0, "edma", 17, MCF_CLK); +DEFINE_CLK(0, "intc.0", 18, MCF_CLK); +DEFINE_CLK(0, "iack.0", 21, MCF_CLK); +DEFINE_CLK(0, "mcfi2c.0", 22, MCF_CLK); +DEFINE_CLK(0, "mcfqspi.0", 23, MCF_CLK); +DEFINE_CLK(0, "mcfuart.0", 24, MCF_BUSCLK); +DEFINE_CLK(0, "mcfuart.1", 25, MCF_BUSCLK); +DEFINE_CLK(0, "mcfuart.2", 26, MCF_BUSCLK); +DEFINE_CLK(0, "mcftmr.0", 28, MCF_CLK); +DEFINE_CLK(0, "mcftmr.1", 29, MCF_CLK); +DEFINE_CLK(0, "mcftmr.2", 30, MCF_CLK); +DEFINE_CLK(0, "mcftmr.3", 31, MCF_CLK); + +DEFINE_CLK(0, "mcfpit.0", 32, MCF_CLK); +DEFINE_CLK(0, "mcfpit.1", 33, MCF_CLK); +DEFINE_CLK(0, "mcfeport.0", 34, MCF_CLK); +DEFINE_CLK(0, "mcfwdt.0", 35, MCF_CLK); +DEFINE_CLK(0, "pll.0", 36, MCF_CLK); +DEFINE_CLK(0, "sys.0", 40, MCF_BUSCLK); +DEFINE_CLK(0, "gpio.0", 41, MCF_BUSCLK); +DEFINE_CLK(0, "sdram.0", 42, MCF_CLK); + +struct clk *mcf_clks[] = { + &__clk_0_2, /* flexbus */ + &__clk_0_12, /* fec.0 */ + &__clk_0_17, /* edma */ + &__clk_0_18, /* intc.0 */ + &__clk_0_21, /* iack.0 */ + &__clk_0_22, /* mcfi2c.0 */ + &__clk_0_23, /* mcfqspi.0 */ + &__clk_0_24, /* mcfuart.0 */ + &__clk_0_25, /* mcfuart.1 */ + &__clk_0_26, /* mcfuart.2 */ + &__clk_0_28, /* mcftmr.0 */ + &__clk_0_29, /* mcftmr.1 */ + &__clk_0_30, /* mcftmr.2 */ + &__clk_0_31, /* mcftmr.3 */ + + &__clk_0_32, /* mcfpit.0 */ + &__clk_0_33, /* mcfpit.1 */ + &__clk_0_34, /* mcfeport.0 */ + &__clk_0_35, /* mcfwdt.0 */ + &__clk_0_36, /* pll.0 */ + &__clk_0_40, /* sys.0 */ + &__clk_0_41, /* gpio.0 */ + &__clk_0_42, /* sdram.0 */ +NULL, +}; + +static struct clk * const enable_clks[] __initconst = { + &__clk_0_2, /* flexbus */ + &__clk_0_18, /* intc.0 */ + &__clk_0_21, /* iack.0 */ + &__clk_0_24, /* mcfuart.0 */ + &__clk_0_25, /* mcfuart.1 */ + &__clk_0_26, /* mcfuart.2 */ + + &__clk_0_32, /* mcfpit.0 */ + &__clk_0_33, /* mcfpit.1 */ + &__clk_0_34, /* mcfeport.0 */ + &__clk_0_36, /* pll.0 */ + &__clk_0_40, /* sys.0 */ + &__clk_0_41, /* gpio.0 */ + &__clk_0_42, /* sdram.0 */ +}; + +static struct clk * const disable_clks[] __initconst = { + &__clk_0_12, /* fec.0 */ + &__clk_0_17, /* edma */ + &__clk_0_22, /* mcfi2c.0 */ + &__clk_0_23, /* mcfqspi.0 */ + &__clk_0_28, /* mcftmr.0 */ + &__clk_0_29, /* mcftmr.1 */ + &__clk_0_30, /* mcftmr.2 */ + &__clk_0_31, /* mcftmr.3 */ + &__clk_0_35, /* mcfwdt.0 */ +}; + + +static void __init m520x_clk_init(void) +{ + unsigned i; + + /* make sure these clocks are enabled */ + for (i = 0; i < ARRAY_SIZE(enable_clks); ++i) + __clk_init_enabled(enable_clks[i]); + /* make sure these clocks are disabled */ + for (i = 0; i < ARRAY_SIZE(disable_clks); ++i) + __clk_init_disabled(disable_clks[i]); +} /***************************************************************************/ @@ -77,6 +173,7 @@ static void __init m520x_fec_init(void) void __init config_BSP(char *commandp, int size) { mach_sched_init = hw_timer_init; + m520x_clk_init(); m520x_uarts_init(); m520x_fec_init(); #if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) -- cgit v1.2.3 From 12ce4c1f26312ac2937b4a6f19b5886190070526 Mon Sep 17 00:00:00 2001 From: Steven King Date: Sun, 17 Jun 2012 00:41:39 -0700 Subject: m68knommu: Add clk definitions for m532x. The 532x has individually controllable clocks for it peripherals. Add clk definitions for these and add default initialization of either enabled or disabled. Signed-off-by: Steven King Signed-off-by: Greg Ungerer --- arch/m68k/include/asm/m532xsim.h | 14 ++++ arch/m68k/platform/coldfire/m532x.c | 139 +++++++++++++++++++++++++++++++++++- 2 files changed, 152 insertions(+), 1 deletion(-) (limited to 'arch/m68k') diff --git a/arch/m68k/include/asm/m532xsim.h b/arch/m68k/include/asm/m532xsim.h index 8d860200a2f5..5ca7b298c6eb 100644 --- a/arch/m68k/include/asm/m532xsim.h +++ b/arch/m68k/include/asm/m532xsim.h @@ -138,6 +138,20 @@ #define MCF_RCR_SWRESET 0x80 /* Software reset bit */ #define MCF_RCR_FRCSTOUT 0x40 /* Force external reset */ + +/* + * Power Management + */ +#define MCFPM_WCR 0xfc040013 +#define MCFPM_PPMSR0 0xfc04002c +#define MCFPM_PPMCR0 0xfc04002d +#define MCFPM_PPMSR1 0xfc04002e +#define MCFPM_PPMCR1 0xfc04002f +#define MCFPM_PPMHR0 0xfc040030 +#define MCFPM_PPMLR0 0xfc040034 +#define MCFPM_PPMHR1 0xfc040038 +#define MCFPM_LPCR 0xec090007 + /********************************************************************* * * Inter-IC (I2C) Module diff --git a/arch/m68k/platform/coldfire/m532x.c b/arch/m68k/platform/coldfire/m532x.c index 21d6cb1c7004..4819a44991ed 100644 --- a/arch/m68k/platform/coldfire/m532x.c +++ b/arch/m68k/platform/coldfire/m532x.c @@ -27,6 +27,143 @@ #include #include #include +#include + +/***************************************************************************/ + +DEFINE_CLK(0, "flexbus", 2, MCF_CLK); +DEFINE_CLK(0, "mcfcan.0", 8, MCF_CLK); +DEFINE_CLK(0, "fec.0", 12, MCF_CLK); +DEFINE_CLK(0, "edma", 17, MCF_CLK); +DEFINE_CLK(0, "intc.0", 18, MCF_CLK); +DEFINE_CLK(0, "intc.1", 19, MCF_CLK); +DEFINE_CLK(0, "iack.0", 21, MCF_CLK); +DEFINE_CLK(0, "mcfi2c.0", 22, MCF_CLK); +DEFINE_CLK(0, "mcfqspi.0", 23, MCF_CLK); +DEFINE_CLK(0, "mcfuart.0", 24, MCF_BUSCLK); +DEFINE_CLK(0, "mcfuart.1", 25, MCF_BUSCLK); +DEFINE_CLK(0, "mcfuart.2", 26, MCF_BUSCLK); +DEFINE_CLK(0, "mcftmr.0", 28, MCF_CLK); +DEFINE_CLK(0, "mcftmr.1", 29, MCF_CLK); +DEFINE_CLK(0, "mcftmr.2", 30, MCF_CLK); +DEFINE_CLK(0, "mcftmr.3", 31, MCF_CLK); + +DEFINE_CLK(0, "mcfpit.0", 32, MCF_CLK); +DEFINE_CLK(0, "mcfpit.1", 33, MCF_CLK); +DEFINE_CLK(0, "mcfpit.2", 34, MCF_CLK); +DEFINE_CLK(0, "mcfpit.3", 35, MCF_CLK); +DEFINE_CLK(0, "mcfpwm.0", 36, MCF_CLK); +DEFINE_CLK(0, "mcfeport.0", 37, MCF_CLK); +DEFINE_CLK(0, "mcfwdt.0", 38, MCF_CLK); +DEFINE_CLK(0, "sys.0", 40, MCF_BUSCLK); +DEFINE_CLK(0, "gpio.0", 41, MCF_BUSCLK); +DEFINE_CLK(0, "mcfrtc.0", 42, MCF_CLK); +DEFINE_CLK(0, "mcflcd.0", 43, MCF_CLK); +DEFINE_CLK(0, "mcfusb-otg.0", 44, MCF_CLK); +DEFINE_CLK(0, "mcfusb-host.0", 45, MCF_CLK); +DEFINE_CLK(0, "sdram.0", 46, MCF_CLK); +DEFINE_CLK(0, "ssi.0", 47, MCF_CLK); +DEFINE_CLK(0, "pll.0", 48, MCF_CLK); + +DEFINE_CLK(1, "mdha.0", 32, MCF_CLK); +DEFINE_CLK(1, "skha.0", 33, MCF_CLK); +DEFINE_CLK(1, "rng.0", 34, MCF_CLK); + +struct clk *mcf_clks[] = { + &__clk_0_2, /* flexbus */ + &__clk_0_8, /* mcfcan.0 */ + &__clk_0_12, /* fec.0 */ + &__clk_0_17, /* edma */ + &__clk_0_18, /* intc.0 */ + &__clk_0_19, /* intc.1 */ + &__clk_0_21, /* iack.0 */ + &__clk_0_22, /* mcfi2c.0 */ + &__clk_0_23, /* mcfqspi.0 */ + &__clk_0_24, /* mcfuart.0 */ + &__clk_0_25, /* mcfuart.1 */ + &__clk_0_26, /* mcfuart.2 */ + &__clk_0_28, /* mcftmr.0 */ + &__clk_0_29, /* mcftmr.1 */ + &__clk_0_30, /* mcftmr.2 */ + &__clk_0_31, /* mcftmr.3 */ + + &__clk_0_32, /* mcfpit.0 */ + &__clk_0_33, /* mcfpit.1 */ + &__clk_0_34, /* mcfpit.2 */ + &__clk_0_35, /* mcfpit.3 */ + &__clk_0_36, /* mcfpwm.0 */ + &__clk_0_37, /* mcfeport.0 */ + &__clk_0_38, /* mcfwdt.0 */ + &__clk_0_40, /* sys.0 */ + &__clk_0_41, /* gpio.0 */ + &__clk_0_42, /* mcfrtc.0 */ + &__clk_0_43, /* mcflcd.0 */ + &__clk_0_44, /* mcfusb-otg.0 */ + &__clk_0_45, /* mcfusb-host.0 */ + &__clk_0_46, /* sdram.0 */ + &__clk_0_47, /* ssi.0 */ + &__clk_0_48, /* pll.0 */ + + &__clk_1_32, /* mdha.0 */ + &__clk_1_33, /* skha.0 */ + &__clk_1_34, /* rng.0 */ + NULL, +}; + +static struct clk * const enable_clks[] __initconst = { + &__clk_0_2, /* flexbus */ + &__clk_0_18, /* intc.0 */ + &__clk_0_19, /* intc.1 */ + &__clk_0_21, /* iack.0 */ + &__clk_0_24, /* mcfuart.0 */ + &__clk_0_25, /* mcfuart.1 */ + &__clk_0_26, /* mcfuart.2 */ + + &__clk_0_32, /* mcfpit.0 */ + &__clk_0_33, /* mcfpit.1 */ + &__clk_0_37, /* mcfeport.0 */ + &__clk_0_40, /* sys.0 */ + &__clk_0_41, /* gpio.0 */ + &__clk_0_46, /* sdram.0 */ + &__clk_0_48, /* pll.0 */ +}; + +static struct clk * const disable_clks[] __initconst = { + &__clk_0_8, /* mcfcan.0 */ + &__clk_0_12, /* fec.0 */ + &__clk_0_17, /* edma */ + &__clk_0_22, /* mcfi2c.0 */ + &__clk_0_23, /* mcfqspi.0 */ + &__clk_0_28, /* mcftmr.0 */ + &__clk_0_29, /* mcftmr.1 */ + &__clk_0_30, /* mcftmr.2 */ + &__clk_0_31, /* mcftmr.3 */ + &__clk_0_34, /* mcfpit.2 */ + &__clk_0_35, /* mcfpit.3 */ + &__clk_0_36, /* mcfpwm.0 */ + &__clk_0_38, /* mcfwdt.0 */ + &__clk_0_42, /* mcfrtc.0 */ + &__clk_0_43, /* mcflcd.0 */ + &__clk_0_44, /* mcfusb-otg.0 */ + &__clk_0_45, /* mcfusb-host.0 */ + &__clk_0_47, /* ssi.0 */ + &__clk_1_32, /* mdha.0 */ + &__clk_1_33, /* skha.0 */ + &__clk_1_34, /* rng.0 */ +}; + + +static void __init m532x_clk_init(void) +{ + unsigned i; + + /* make sure these clocks are enabled */ + for (i = 0; i < ARRAY_SIZE(enable_clks); ++i) + __clk_init_enabled(enable_clks[i]); + /* make sure these clocks are disabled */ + for (i = 0; i < ARRAY_SIZE(disable_clks); ++i) + __clk_init_disabled(disable_clks[i]); +} /***************************************************************************/ @@ -73,8 +210,8 @@ void __init config_BSP(char *commandp, int size) memset(commandp, 0, size); } #endif - mach_sched_init = hw_timer_init; + m532x_clk_init(); m532x_uarts_init(); m532x_fec_init(); #if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) -- cgit v1.2.3 From 8b1e5a0626f7f921fe0fa24bdb256ae1de5ab9b0 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Mon, 25 Jun 2012 11:11:49 +1000 Subject: m68knommu: platform support for 8390 based ethernet used on some boards Quite a few of Freescale's older ColdFire development boards used an NS8390 based ethernet interface. Add a platform definition for the resources used by these devices so we can use it on these boards. Signed-off-by: Greg Ungerer --- arch/m68k/platform/coldfire/Makefile | 1 + arch/m68k/platform/coldfire/mcf8390.c | 38 +++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 arch/m68k/platform/coldfire/mcf8390.c (limited to 'arch/m68k') diff --git a/arch/m68k/platform/coldfire/Makefile b/arch/m68k/platform/coldfire/Makefile index b3f8bfda52e2..71bf542b2f60 100644 --- a/arch/m68k/platform/coldfire/Makefile +++ b/arch/m68k/platform/coldfire/Makefile @@ -33,6 +33,7 @@ obj-$(CONFIG_M5441x) += m5441x.o pit.o intc-simr.o reset.o obj-$(CONFIG_NETtel) += nettel.o obj-$(CONFIG_CLEOPATRA) += nettel.o obj-$(CONFIG_FIREBEE) += firebee.o +obj-$(CONFIG_MCF8390) += mcf8390.o obj-y += gpio.o extra-y := head.o diff --git a/arch/m68k/platform/coldfire/mcf8390.c b/arch/m68k/platform/coldfire/mcf8390.c new file mode 100644 index 000000000000..23a6874a3248 --- /dev/null +++ b/arch/m68k/platform/coldfire/mcf8390.c @@ -0,0 +1,38 @@ +/* + * mcf8390.c -- platform support for 8390 ethernet on many boards + * + * (C) Copyright 2012, Greg Ungerer + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ + +#include +#include +#include +#include +#include +#include + +static struct resource mcf8390_resources[] = { + { + .start = NE2000_ADDR, + .end = NE2000_ADDR + NE2000_ADDRSIZE - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = NE2000_IRQ_VECTOR, + .end = NE2000_IRQ_VECTOR, + .flags = IORESOURCE_IRQ, + }, +}; + +static int __init mcf8390_platform_init(void) +{ + platform_device_register_simple("mcf8390", -1, mcf8390_resources, + ARRAY_SIZE(mcf8390_resources)); + return 0; +} + +arch_initcall(mcf8390_platform_init); -- cgit v1.2.3 From b60f187fecee5d9dceb89773e15f976fe21d893a Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Tue, 26 Jun 2012 21:02:54 +1000 Subject: m68k: use simpler dma_alloc_coherent() for ColdFire CPUs On all ColdFire platforms (whether MMU enabled or not) we want to use the simple page based dma_alloc_coherent. We don't want the virtual mapping version that is used on classic m68k setups. So modify the conditionals to use the existing simpler dma_alloc_coherent on all ColdFire and non-MMU builds. Signed-off-by: Greg Ungerer --- arch/m68k/kernel/dma.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/m68k') diff --git a/arch/m68k/kernel/dma.c b/arch/m68k/kernel/dma.c index f6daf6e15d2e..27b5821f9712 100644 --- a/arch/m68k/kernel/dma.c +++ b/arch/m68k/kernel/dma.c @@ -16,7 +16,7 @@ #include -#ifdef CONFIG_MMU +#if defined(CONFIG_MMU) && !defined(CONFIG_COLDFIRE) void *dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t flag) @@ -96,7 +96,7 @@ void dma_free_coherent(struct device *dev, size_t size, free_pages((unsigned long)vaddr, get_order(size)); } -#endif /* CONFIG_MMU */ +#endif /* CONFIG_MMU && !CONFIG_COLDFIRE */ EXPORT_SYMBOL(dma_alloc_coherent); EXPORT_SYMBOL(dma_free_coherent); -- cgit v1.2.3 From f3ff6432dde9c0800754f1f144f6e864ac228214 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Tue, 10 Jul 2012 13:33:24 +1000 Subject: m68k: fix ColdFire clear cache operation The code for clearing (invalidating) the ColdFire cache is actually performing a push operation. Add functions to clear the cache, and fix cache_clear() to call the appropriate clear cache function. Signed-off-by: Greg Ungerer --- arch/m68k/include/asm/cacheflush_mm.h | 41 +++++++++++++++++++++++++++++++++++ arch/m68k/mm/memory.c | 2 +- 2 files changed, 42 insertions(+), 1 deletion(-) (limited to 'arch/m68k') diff --git a/arch/m68k/include/asm/cacheflush_mm.h b/arch/m68k/include/asm/cacheflush_mm.h index 8104bd874649..fa2c3d681d84 100644 --- a/arch/m68k/include/asm/cacheflush_mm.h +++ b/arch/m68k/include/asm/cacheflush_mm.h @@ -16,7 +16,48 @@ #define DCACHE_MAX_ADDR 0 #define DCACHE_SETMASK 0 #endif +#ifndef CACHE_MODE +#define CACHE_MODE 0 +#define CACR_ICINVA 0 +#define CACR_DCINVA 0 +#define CACR_BCINVA 0 +#endif + +/* + * ColdFire architecture has no way to clear individual cache lines, so we + * are stuck invalidating all the cache entries when we want a clear operation. + */ +static inline void clear_cf_icache(unsigned long start, unsigned long end) +{ + __asm__ __volatile__ ( + "movec %0,%%cacr\n\t" + "nop" + : + : "r" (CACHE_MODE | CACR_ICINVA | CACR_BCINVA)); +} + +static inline void clear_cf_dcache(unsigned long start, unsigned long end) +{ + __asm__ __volatile__ ( + "movec %0,%%cacr\n\t" + "nop" + : + : "r" (CACHE_MODE | CACR_DCINVA)); +} +static inline void clear_cf_bcache(unsigned long start, unsigned long end) +{ + __asm__ __volatile__ ( + "movec %0,%%cacr\n\t" + "nop" + : + : "r" (CACHE_MODE | CACR_ICINVA | CACR_BCINVA | CACR_DCINVA)); +} + +/* + * Use the ColdFire cpushl instruction to push (and invalidate) cache lines. + * The start and end addresses are cache line numbers not memory addresses. + */ static inline void flush_cf_icache(unsigned long start, unsigned long end) { unsigned long set; diff --git a/arch/m68k/mm/memory.c b/arch/m68k/mm/memory.c index 250b8b786f4f..51bc9d258ede 100644 --- a/arch/m68k/mm/memory.c +++ b/arch/m68k/mm/memory.c @@ -203,7 +203,7 @@ static inline void pushcl040(unsigned long paddr) void cache_clear (unsigned long paddr, int len) { if (CPU_IS_COLDFIRE) { - flush_cf_bcache(0, DCACHE_MAX_ADDR); + clear_cf_bcache(0, DCACHE_MAX_ADDR); } else if (CPU_IS_040_OR_060) { int tmp; -- cgit v1.2.3 From d2661c621525956dfdd1e66e1e4fd94b7e4b6ed5 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Tue, 10 Jul 2012 13:50:58 +1000 Subject: m68k: add support for DMA_BIDIRECTIONAL in dma support functions The dma cache support functions do not currently support the direction flag DMA_BIDIRECTIONAL. If a driver passes this direction to dma_map_single or friends you will get console output like this: dma_sync_single_for_device: unsupported dir 0 For example when using the Intel e100 ethernet driver on a ColdFire platform with PCI bus. You will get a stream of these messages coming out. Modify the dma cache support code adding support for DMA_BIDIRECTIONAL. It is actioned by doing a cache push operation. Signed-off-by: Greg Ungerer --- arch/m68k/kernel/dma.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/m68k') diff --git a/arch/m68k/kernel/dma.c b/arch/m68k/kernel/dma.c index 27b5821f9712..e546a5534dd4 100644 --- a/arch/m68k/kernel/dma.c +++ b/arch/m68k/kernel/dma.c @@ -105,6 +105,7 @@ void dma_sync_single_for_device(struct device *dev, dma_addr_t handle, size_t size, enum dma_data_direction dir) { switch (dir) { + case DMA_BIDIRECTIONAL: case DMA_TO_DEVICE: cache_push(handle, size); break; -- cgit v1.2.3 From e93a6bbeb5a5f473293dd62f92903f89ec8004aa Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Mon, 28 Nov 2011 16:32:49 +1000 Subject: m68k: common PCI support definitions and code Basic set of definitions and support code required to turn on CONFIG_PCI for the m68k architecture. Nothing specific to any PCI implementation in any m68k class CPU hardware yet. Signed-off-by: Greg Ungerer Acked-by: Geert Uytterhoeven --- arch/m68k/include/asm/dma.h | 4 ++ arch/m68k/include/asm/io_mm.h | 2 + arch/m68k/include/asm/pci.h | 6 +++ arch/m68k/kernel/Makefile | 1 + arch/m68k/kernel/pcibios.c | 109 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 122 insertions(+) create mode 100644 arch/m68k/kernel/pcibios.c (limited to 'arch/m68k') diff --git a/arch/m68k/include/asm/dma.h b/arch/m68k/include/asm/dma.h index 947064184639..0ff3fc6a6d9a 100644 --- a/arch/m68k/include/asm/dma.h +++ b/arch/m68k/include/asm/dma.h @@ -488,6 +488,10 @@ static __inline__ int get_dma_residue(unsigned int dmanr) extern int request_dma(unsigned int dmanr, const char * device_id); /* reserve a DMA channel */ extern void free_dma(unsigned int dmanr); /* release it again */ +#ifdef CONFIG_PCI +extern int isa_dma_bridge_buggy; +#else #define isa_dma_bridge_buggy (0) +#endif #endif /* _M68K_DMA_H */ diff --git a/arch/m68k/include/asm/io_mm.h b/arch/m68k/include/asm/io_mm.h index fa4324bcf566..b85dbef85e1c 100644 --- a/arch/m68k/include/asm/io_mm.h +++ b/arch/m68k/include/asm/io_mm.h @@ -340,4 +340,6 @@ static inline void memcpy_toio(volatile void __iomem *dst, const void *src, int */ #define xlate_dev_kmem_ptr(p) p +#define ioport_map(port, nr) ((void __iomem *)(port)) + #endif /* _IO_H */ diff --git a/arch/m68k/include/asm/pci.h b/arch/m68k/include/asm/pci.h index 4ad0aea48ab4..848c3dfaad50 100644 --- a/arch/m68k/include/asm/pci.h +++ b/arch/m68k/include/asm/pci.h @@ -2,6 +2,7 @@ #define _ASM_M68K_PCI_H #include +#include /* The PCI address space does equal the physical memory * address space. The networking and block device layers use @@ -9,4 +10,9 @@ */ #define PCI_DMA_BUS_IS_PHYS (1) +#define pcibios_assign_all_busses() 1 + +#define PCIBIOS_MIN_IO 0x00000100 +#define PCIBIOS_MIN_MEM 0x02000000 + #endif /* _ASM_M68K_PCI_H */ diff --git a/arch/m68k/kernel/Makefile b/arch/m68k/kernel/Makefile index 5c7070e21eb7..068ad49210d6 100644 --- a/arch/m68k/kernel/Makefile +++ b/arch/m68k/kernel/Makefile @@ -18,6 +18,7 @@ obj-y += setup.o signal.o sys_m68k.o syscalltable.o time.o traps.o obj-$(CONFIG_MMU_MOTOROLA) += ints.o vectors.o obj-$(CONFIG_MMU_SUN3) += ints.o vectors.o +obj-$(CONFIG_PCI) += pcibios.o ifndef CONFIG_MMU_SUN3 obj-y += dma.o diff --git a/arch/m68k/kernel/pcibios.c b/arch/m68k/kernel/pcibios.c new file mode 100644 index 000000000000..b2988aa1840b --- /dev/null +++ b/arch/m68k/kernel/pcibios.c @@ -0,0 +1,109 @@ +/* + * pci.c -- basic PCI support code + * + * 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. + * + * (C) Copyright 2011, Greg Ungerer + */ + +#include +#include +#include +#include +#include + +/* + * From arch/i386/kernel/pci-i386.c: + * + * We need to avoid collisions with `mirrored' VGA ports + * and other strange ISA hardware, so we always want the + * addresses to be allocated in the 0x000-0x0ff region + * modulo 0x400. + * + * Why? Because some silly external IO cards only decode + * the low 10 bits of the IO address. The 0x00-0xff region + * is reserved for motherboard devices that decode all 16 + * bits, so it's ok to allocate at, say, 0x2800-0x28ff, + * but we want to try to avoid allocating at 0x2900-0x2bff + * which might be mirrored at 0x0100-0x03ff.. + */ +resource_size_t pcibios_align_resource(void *data, const struct resource *res, + resource_size_t size, resource_size_t align) +{ + resource_size_t start = res->start; + + if ((res->flags & IORESOURCE_IO) && (start & 0x300)) + start = (start + 0x3ff) & ~0x3ff; + + start = (start + align - 1) & ~(align - 1); + + return start; +} + +/* + * This is taken from the ARM code for this. + */ +int pcibios_enable_device(struct pci_dev *dev, int mask) +{ + struct resource *r; + u16 cmd, newcmd; + int idx; + + pci_read_config_word(dev, PCI_COMMAND, &cmd); + newcmd = cmd; + + for (idx = 0; idx < 6; idx++) { + /* Only set up the requested stuff */ + if (!(mask & (1 << idx))) + continue; + + r = dev->resource + idx; + if (!r->start && r->end) { + pr_err(KERN_ERR "PCI: Device %s not available because of resource collisions\n", + pci_name(dev)); + return -EINVAL; + } + if (r->flags & IORESOURCE_IO) + newcmd |= PCI_COMMAND_IO; + if (r->flags & IORESOURCE_MEM) + newcmd |= PCI_COMMAND_MEMORY; + } + + /* + * Bridges (eg, cardbus bridges) need to be fully enabled + */ + if ((dev->class >> 16) == PCI_BASE_CLASS_BRIDGE) + newcmd |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY; + + + if (newcmd != cmd) { + pr_info("PCI: enabling device %s (0x%04x -> 0x%04x)\n", + pci_name(dev), cmd, newcmd); + pci_write_config_word(dev, PCI_COMMAND, newcmd); + } + return 0; +} + +void pcibios_update_irq(struct pci_dev *dev, int irq) +{ + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); +} + +void __devinit pcibios_fixup_bus(struct pci_bus *bus) +{ + struct pci_dev *dev; + + list_for_each_entry(dev, &bus->devices, bus_list) { + pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 8); + pci_write_config_byte(dev, PCI_LATENCY_TIMER, 32); + } +} + +char __devinit *pcibios_setup(char *str) +{ + return str; +} + -- cgit v1.2.3 From 32be2acc7caa9c9c1157002c4c77063e0084e774 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Tue, 10 Jul 2012 15:34:27 +1000 Subject: m68k: add PCI bus support definitions for the ColdFire M54xx SoC family Add all the required definitoins to support the ColdFire M54xx SoC PCI hardware unit. These are strait out of the MCF5475 Reference Manual. Signed-off-by: Greg Ungerer --- arch/m68k/include/asm/m54xxpci.h | 138 +++++++++++++++++++++++++++++++++++++++ arch/m68k/include/asm/m54xxsim.h | 3 + 2 files changed, 141 insertions(+) create mode 100644 arch/m68k/include/asm/m54xxpci.h (limited to 'arch/m68k') diff --git a/arch/m68k/include/asm/m54xxpci.h b/arch/m68k/include/asm/m54xxpci.h new file mode 100644 index 000000000000..6fbf54f72f2e --- /dev/null +++ b/arch/m68k/include/asm/m54xxpci.h @@ -0,0 +1,138 @@ +/****************************************************************************/ + +/* + * m54xxpci.h -- ColdFire 547x and 548x PCI bus support + * + * (C) Copyright 2011, Greg Ungerer + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ + +/****************************************************************************/ +#ifndef M54XXPCI_H +#define M54XXPCI_H +/****************************************************************************/ + +/* + * The core set of PCI support registers are mapped into the MBAR region. + */ +#define PCIIDR (CONFIG_MBAR + 0xb00) /* PCI device/vendor ID */ +#define PCISCR (CONFIG_MBAR + 0xb04) /* PCI status/command */ +#define PCICCRIR (CONFIG_MBAR + 0xb08) /* PCI class/revision */ +#define PCICR1 (CONFIG_MBAR + 0xb0c) /* PCI configuration 1 */ +#define PCIBAR0 (CONFIG_MBAR + 0xb10) /* PCI base address 0 */ +#define PCIBAR1 (CONFIG_MBAR + 0xb14) /* PCI base address 1 */ +#define PCICCPR (CONFIG_MBAR + 0xb28) /* PCI cardbus CIS pointer */ +#define PCISID (CONFIG_MBAR + 0xb2c) /* PCI subsystem IDs */ +#define PCIERBAR (CONFIG_MBAR + 0xb30) /* PCI expansion ROM */ +#define PCICPR (CONFIG_MBAR + 0xb34) /* PCI capabilities pointer */ +#define PCICR2 (CONFIG_MBAR + 0xb3c) /* PCI configuration 2 */ + +#define PCIGSCR (CONFIG_MBAR + 0xb60) /* Global status/control */ +#define PCITBATR0 (CONFIG_MBAR + 0xb64) /* Target base translation 0 */ +#define PCITBATR1 (CONFIG_MBAR + 0xb68) /* Target base translation 1 */ +#define PCITCR (CONFIG_MBAR + 0xb6c) /* Target control */ +#define PCIIW0BTAR (CONFIG_MBAR + 0xb70) /* Initiator window 0 */ +#define PCIIW1BTAR (CONFIG_MBAR + 0xb74) /* Initiator window 1 */ +#define PCIIW2BTAR (CONFIG_MBAR + 0xb78) /* Initiator window 2 */ +#define PCIIWCR (CONFIG_MBAR + 0xb80) /* Initiator window config */ +#define PCIICR (CONFIG_MBAR + 0xb84) /* Initiator control */ +#define PCIISR (CONFIG_MBAR + 0xb88) /* Initiator status */ +#define PCICAR (CONFIG_MBAR + 0xbf8) /* Configuration address */ + +#define PCITPSR (CONFIG_MBAR + 0x8400) /* TX packet size */ +#define PCITSAR (CONFIG_MBAR + 0x8404) /* TX start address */ +#define PCITTCR (CONFIG_MBAR + 0x8408) /* TX transaction control */ +#define PCITER (CONFIG_MBAR + 0x840c) /* TX enables */ +#define PCITNAR (CONFIG_MBAR + 0x8410) /* TX next address */ +#define PCITLWR (CONFIG_MBAR + 0x8414) /* TX last word */ +#define PCITDCR (CONFIG_MBAR + 0x8418) /* TX done counts */ +#define PCITSR (CONFIG_MBAR + 0x841c) /* TX status */ +#define PCITFDR (CONFIG_MBAR + 0x8440) /* TX FIFO data */ +#define PCITFSR (CONFIG_MBAR + 0x8444) /* TX FIFO status */ +#define PCITFCR (CONFIG_MBAR + 0x8448) /* TX FIFO control */ +#define PCITFAR (CONFIG_MBAR + 0x844c) /* TX FIFO alarm */ +#define PCITFRPR (CONFIG_MBAR + 0x8450) /* TX FIFO read pointer */ +#define PCITFWPR (CONFIG_MBAR + 0x8454) /* TX FIFO write pointer */ + +#define PCIRPSR (CONFIG_MBAR + 0x8480) /* RX packet size */ +#define PCIRSAR (CONFIG_MBAR + 0x8484) /* RX start address */ +#define PCIRTCR (CONFIG_MBAR + 0x8488) /* RX transaction control */ +#define PCIRER (CONFIG_MBAR + 0x848c) /* RX enables */ +#define PCIRNAR (CONFIG_MBAR + 0x8490) /* RX next address */ +#define PCIRDCR (CONFIG_MBAR + 0x8498) /* RX done counts */ +#define PCIRSR (CONFIG_MBAR + 0x849c) /* RX status */ +#define PCIRFDR (CONFIG_MBAR + 0x84c0) /* RX FIFO data */ +#define PCIRFSR (CONFIG_MBAR + 0x84c4) /* RX FIFO status */ +#define PCIRFCR (CONFIG_MBAR + 0x84c8) /* RX FIFO control */ +#define PCIRFAR (CONFIG_MBAR + 0x84cc) /* RX FIFO alarm */ +#define PCIRFRPR (CONFIG_MBAR + 0x84d0) /* RX FIFO read pointer */ +#define PCIRFWPR (CONFIG_MBAR + 0x84d4) /* RX FIFO write pointer */ + +#define PACR (CONFIG_MBAR + 0xc00) /* PCI arbiter control */ +#define PASR (COFNIG_MBAR + 0xc04) /* PCI arbiter status */ + +/* + * Definitions for the Global status and control register. + */ +#define PCIGSCR_PE 0x20000000 /* Parity error detected */ +#define PCIGSCR_SE 0x10000000 /* System error detected */ +#define PCIGSCR_XCLKBIN 0x07000000 /* XLB2CLKIN mask */ +#define PCIGSCR_PEE 0x00002000 /* Parity error intr enable */ +#define PCIGSCR_SEE 0x00001000 /* System error intr enable */ +#define PCIGSCR_RESET 0x00000001 /* Reset bit */ + +/* + * Bit definitions for the PCICAR configuration address register. + */ +#define PCICAR_E 0x80000000 /* Enable config space */ +#define PCICAR_BUSN 16 /* Move bus bits */ +#define PCICAR_DEVFNN 8 /* Move devfn bits */ +#define PCICAR_DWORDN 0 /* Move dword bits */ + +/* + * The initiator windows hold the memory and IO mapping information. + * This macro creates the register values from the desired addresses. + */ +#define WXBTAR(hostaddr, pciaddr, size) \ + (((hostaddr) & 0xff000000) | \ + ((((size) - 1) & 0xff000000) >> 8) | \ + (((pciaddr) & 0xff000000) >> 16)) + +#define PCIIWCR_W0_MEM 0x00000000 /* Window 0 is memory */ +#define PCIIWCR_W0_IO 0x08000000 /* Window 0 is IO */ +#define PCIIWCR_W0_MRD 0x00000000 /* Window 0 memory read */ +#define PCIIWCR_W0_MRDL 0x02000000 /* Window 0 memory read line */ +#define PCIIWCR_W0_MRDM 0x04000000 /* Window 0 memory read mult */ +#define PCIIWCR_W0_E 0x01000000 /* Window 0 enable */ + +#define PCIIWCR_W1_MEM 0x00000000 /* Window 0 is memory */ +#define PCIIWCR_W1_IO 0x00080000 /* Window 0 is IO */ +#define PCIIWCR_W1_MRD 0x00000000 /* Window 0 memory read */ +#define PCIIWCR_W1_MRDL 0x00020000 /* Window 0 memory read line */ +#define PCIIWCR_W1_MRDM 0x00040000 /* Window 0 memory read mult */ +#define PCIIWCR_W1_E 0x00010000 /* Window 0 enable */ + +/* + * Bit definitions for the PCIBATR registers. + */ +#define PCITBATR0_E 0x00000001 /* Enable window 0 */ +#define PCITBATR1_E 0x00000001 /* Enable window 1 */ + +/* + * PCI arbiter support definitions and macros. + */ +#define PACR_INTMPRI 0x00000001 +#define PACR_EXTMPRI(x) (((x) & 0x1f) << 1) +#define PACR_INTMINTE 0x00010000 +#define PACR_EXTMINTE(x) (((x) & 0x1f) << 17) +#define PACR_PKMD 0x40000000 +#define PACR_DS 0x80000000 + +#define PCICR1_CL(x) ((x) & 0xf) /* Cacheline size field */ +#define PCICR1_LT(x) (((x) & 0xff) << 8) /* Latency timer field */ + +/****************************************************************************/ +#endif /* M54XXPCI_H */ diff --git a/arch/m68k/include/asm/m54xxsim.h b/arch/m68k/include/asm/m54xxsim.h index ae56b8848a9d..d3c5e0dbdadf 100644 --- a/arch/m68k/include/asm/m54xxsim.h +++ b/arch/m68k/include/asm/m54xxsim.h @@ -81,4 +81,7 @@ #define MCF_PAR_PSC_RTS_RTS (0x30) #define MCF_PAR_PSC_CANRX (0x40) +#define MCF_PAR_PCIBG (CONFIG_MBAR + 0xa48) /* PCI bus grant */ +#define MCF_PAR_PCIBR (CONFIG_MBAR + 0xa4a) /* PCI */ + #endif /* m54xxsim_h */ -- cgit v1.2.3 From 9ff601a41ff5d0d1e4fc06d2c313a86a5f84cba4 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Fri, 29 Jun 2012 00:03:27 +1000 Subject: m68k: add IO access definitions to support PCI on ColdFire platforms Define the usual memory access functions (readb/writeb/...) and I/O space functions (inb/outb/...) for PCI bus support on ColdFire CPU based platforms. Signed-off-by: Greg Ungerer Acked-by: Geert Uytterhoeven --- arch/m68k/include/asm/io_mm.h | 48 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) (limited to 'arch/m68k') diff --git a/arch/m68k/include/asm/io_mm.h b/arch/m68k/include/asm/io_mm.h index b85dbef85e1c..a6686d26fe17 100644 --- a/arch/m68k/include/asm/io_mm.h +++ b/arch/m68k/include/asm/io_mm.h @@ -65,7 +65,53 @@ -#ifdef CONFIG_ISA +#if defined(CONFIG_PCI) && defined(CONFIG_COLDFIRE) + +#define HAVE_ARCH_PIO_SIZE +#define PIO_OFFSET 0 +#define PIO_MASK 0xffff +#define PIO_RESERVED 0x10000 + +u8 mcf_pci_inb(u32 addr); +u16 mcf_pci_inw(u32 addr); +u32 mcf_pci_inl(u32 addr); +void mcf_pci_insb(u32 addr, u8 *buf, u32 len); +void mcf_pci_insw(u32 addr, u16 *buf, u32 len); +void mcf_pci_insl(u32 addr, u32 *buf, u32 len); + +void mcf_pci_outb(u8 v, u32 addr); +void mcf_pci_outw(u16 v, u32 addr); +void mcf_pci_outl(u32 v, u32 addr); +void mcf_pci_outsb(u32 addr, const u8 *buf, u32 len); +void mcf_pci_outsw(u32 addr, const u16 *buf, u32 len); +void mcf_pci_outsl(u32 addr, const u32 *buf, u32 len); + +#define inb mcf_pci_inb +#define inb_p mcf_pci_inb +#define inw mcf_pci_inw +#define inw_p mcf_pci_inw +#define inl mcf_pci_inl +#define inl_p mcf_pci_inl +#define insb mcf_pci_insb +#define insw mcf_pci_insw +#define insl mcf_pci_insl + +#define outb mcf_pci_outb +#define outb_p mcf_pci_outb +#define outw mcf_pci_outw +#define outw_p mcf_pci_outw +#define outl mcf_pci_outl +#define outl_p mcf_pci_outl +#define outsb mcf_pci_outsb +#define outsw mcf_pci_outsw +#define outsl mcf_pci_outsl + +#define readb(addr) in_8(addr) +#define writeb(v, addr) out_8((addr), (v)) +#define readw(addr) in_le16(addr) +#define writew(v, addr) out_le16((addr), (v)) + +#elif defined(CONFIG_ISA) #if MULTI_ISA == 0 #undef MULTI_ISA -- cgit v1.2.3 From bbdea849ed6ba694cf1f56801b90f100685e3aa0 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Tue, 29 May 2012 16:11:42 +1000 Subject: m68k: add PCI bus code support for the ColdFire M54xx SoC family The ColdFire M54xx SoC family have a traditional PCI bus interface. Add the core support code to access and use this bus on these parts. This code provides all the config space access functions and IO access functions. It also carries out the PCI bus initialization and hooks into the kernel PCI subsystem. Signed-off-by: Greg Ungerer --- arch/m68k/platform/coldfire/Makefile | 2 + arch/m68k/platform/coldfire/pci.c | 327 +++++++++++++++++++++++++++++++++++ 2 files changed, 329 insertions(+) create mode 100644 arch/m68k/platform/coldfire/pci.c (limited to 'arch/m68k') diff --git a/arch/m68k/platform/coldfire/Makefile b/arch/m68k/platform/coldfire/Makefile index 71bf542b2f60..02591a109f8c 100644 --- a/arch/m68k/platform/coldfire/Makefile +++ b/arch/m68k/platform/coldfire/Makefile @@ -35,5 +35,7 @@ obj-$(CONFIG_CLEOPATRA) += nettel.o obj-$(CONFIG_FIREBEE) += firebee.o obj-$(CONFIG_MCF8390) += mcf8390.o +obj-$(CONFIG_PCI) += pci.o + obj-y += gpio.o extra-y := head.o diff --git a/arch/m68k/platform/coldfire/pci.c b/arch/m68k/platform/coldfire/pci.c new file mode 100644 index 000000000000..553210d3d4c1 --- /dev/null +++ b/arch/m68k/platform/coldfire/pci.c @@ -0,0 +1,327 @@ +/* + * pci.c -- PCI bus support for ColdFire processors + * + * (C) Copyright 2012, Greg Ungerer + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Memory and IO mappings. We use a 1:1 mapping for local host memory to + * PCI bus memory (no reason not to really). IO space doesn't matter, we + * always use access functions for that. The device configuration space is + * mapped over the IO map space when we enable it in the PCICAR register. + */ +#define PCI_MEM_PA 0xf0000000 /* Host physical address */ +#define PCI_MEM_BA 0xf0000000 /* Bus physical address */ +#define PCI_MEM_SIZE 0x08000000 /* 128 MB */ +#define PCI_MEM_MASK (PCI_MEM_SIZE - 1) + +#define PCI_IO_PA 0xf8000000 /* Host physical address */ +#define PCI_IO_BA 0x00000000 /* Bus physical address */ +#define PCI_IO_SIZE 0x00010000 /* 64k */ +#define PCI_IO_MASK (PCI_IO_SIZE - 1) + +static struct pci_bus *rootbus; +static unsigned long iospace; + +/* + * We need to be carefull probing on bus 0 (directly connected to host + * bridge). We should only acccess the well defined possible devices in + * use, ignore aliases and the like. + */ +static unsigned char mcf_host_slot2sid[32] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 2, 0, 3, 4, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +}; + +static unsigned char mcf_host_irq[] = { + 0, 69, 69, 71, 71, +}; + + +static inline void syncio(void) +{ + /* The ColdFire "nop" instruction waits for all bus IO to complete */ + __asm__ __volatile__ ("nop"); +} + +/* + * Configuration space access functions. Configuration space access is + * through the IO mapping window, enabling it via the PCICAR register. + */ +static unsigned long mcf_mk_pcicar(int bus, unsigned int devfn, int where) +{ + return (bus << PCICAR_BUSN) | (devfn << PCICAR_DEVFNN) | (where & 0xfc); +} + +static int mcf_pci_readconfig(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 *value) +{ + unsigned long addr; + + *value = 0xffffffff; + + if (bus->number == 0) { + if (mcf_host_slot2sid[PCI_SLOT(devfn)] == 0) + return PCIBIOS_SUCCESSFUL; + } + + syncio(); + addr = mcf_mk_pcicar(bus->number, devfn, where); + __raw_writel(PCICAR_E | addr, PCICAR); + addr = iospace + (where & 0x3); + + switch (size) { + case 1: + *value = __raw_readb(addr); + break; + case 2: + *value = le16_to_cpu(__raw_readw(addr)); + break; + default: + *value = le32_to_cpu(__raw_readl(addr)); + break; + } + + syncio(); + __raw_writel(0, PCICAR); + return PCIBIOS_SUCCESSFUL; +} + +static int mcf_pci_writeconfig(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 value) +{ + unsigned long addr; + + if (bus->number == 0) { + if (mcf_host_slot2sid[PCI_SLOT(devfn)] == 0) + return PCIBIOS_SUCCESSFUL; + } + + syncio(); + addr = mcf_mk_pcicar(bus->number, devfn, where); + __raw_writel(PCICAR_E | addr, PCICAR); + addr = iospace + (where & 0x3); + + switch (size) { + case 1: + __raw_writeb(value, addr); + break; + case 2: + __raw_writew(cpu_to_le16(value), addr); + break; + default: + __raw_writel(cpu_to_le32(value), addr); + break; + } + + syncio(); + __raw_writel(0, PCICAR); + return PCIBIOS_SUCCESSFUL; +} + +static struct pci_ops mcf_pci_ops = { + .read = mcf_pci_readconfig, + .write = mcf_pci_writeconfig, +}; + +/* + * IO address space access functions. Pretty strait forward, these are + * directly mapped in to the IO mapping window. And that is mapped into + * virtual address space. + */ +u8 mcf_pci_inb(u32 addr) +{ + return __raw_readb(iospace + (addr & PCI_IO_MASK)); +} +EXPORT_SYMBOL(mcf_pci_inb); + +u16 mcf_pci_inw(u32 addr) +{ + return le16_to_cpu(__raw_readw(iospace + (addr & PCI_IO_MASK))); +} +EXPORT_SYMBOL(mcf_pci_inw); + +u32 mcf_pci_inl(u32 addr) +{ + return le32_to_cpu(__raw_readl(iospace + (addr & PCI_IO_MASK))); +} +EXPORT_SYMBOL(mcf_pci_inl); + +void mcf_pci_insb(u32 addr, u8 *buf, u32 len) +{ + for (; len; len--) + *buf++ = mcf_pci_inb(addr); +} +EXPORT_SYMBOL(mcf_pci_insb); + +void mcf_pci_insw(u32 addr, u16 *buf, u32 len) +{ + for (; len; len--) + *buf++ = mcf_pci_inw(addr); +} +EXPORT_SYMBOL(mcf_pci_insw); + +void mcf_pci_insl(u32 addr, u32 *buf, u32 len) +{ + for (; len; len--) + *buf++ = mcf_pci_inl(addr); +} +EXPORT_SYMBOL(mcf_pci_insl); + +void mcf_pci_outb(u8 v, u32 addr) +{ + __raw_writeb(v, iospace + (addr & PCI_IO_MASK)); +} +EXPORT_SYMBOL(mcf_pci_outb); + +void mcf_pci_outw(u16 v, u32 addr) +{ + __raw_writew(cpu_to_le16(v), iospace + (addr & PCI_IO_MASK)); +} +EXPORT_SYMBOL(mcf_pci_outw); + +void mcf_pci_outl(u32 v, u32 addr) +{ + __raw_writel(cpu_to_le32(v), iospace + (addr & PCI_IO_MASK)); +} +EXPORT_SYMBOL(mcf_pci_outl); + +void mcf_pci_outsb(u32 addr, const u8 *buf, u32 len) +{ + for (; len; len--) + mcf_pci_outb(*buf++, addr); +} +EXPORT_SYMBOL(mcf_pci_outsb); + +void mcf_pci_outsw(u32 addr, const u16 *buf, u32 len) +{ + for (; len; len--) + mcf_pci_outw(*buf++, addr); +} +EXPORT_SYMBOL(mcf_pci_outsw); + +void mcf_pci_outsl(u32 addr, const u32 *buf, u32 len) +{ + for (; len; len--) + mcf_pci_outl(*buf++, addr); +} +EXPORT_SYMBOL(mcf_pci_outsl); + +/* + * Initialize the PCI bus registers, and scan the bus. + */ +static struct resource mcf_pci_mem = { + .name = "PCI Memory space", + .start = PCI_MEM_PA, + .end = PCI_MEM_PA + PCI_MEM_SIZE - 1, + .flags = IORESOURCE_MEM, +}; + +static struct resource mcf_pci_io = { + .name = "PCI IO space", + .start = 0x400, + .end = 0x10000 - 1, + .flags = IORESOURCE_IO, +}; + +/* + * Interrupt mapping and setting. + */ +static int mcf_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +{ + int sid; + + sid = mcf_host_slot2sid[slot]; + if (sid) + return mcf_host_irq[sid]; + return 0; +} + +static int __init mcf_pci_init(void) +{ + pr_info("ColdFire: PCI bus initialization...\n"); + + /* Reset the external PCI bus */ + __raw_writel(PCIGSCR_RESET, PCIGSCR); + __raw_writel(0, PCITCR); + + request_resource(&iomem_resource, &mcf_pci_mem); + request_resource(&iomem_resource, &mcf_pci_io); + + /* Configure PCI arbiter */ + __raw_writel(PACR_INTMPRI | PACR_INTMINTE | PACR_EXTMPRI(0x1f) | + PACR_EXTMINTE(0x1f), PACR); + + /* Set required multi-function pins for PCI bus use */ + __raw_writew(0x3ff, MCF_PAR_PCIBG); + __raw_writew(0x3ff, MCF_PAR_PCIBR); + + /* Set up config space for local host bus controller */ + __raw_writel(PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | + PCI_COMMAND_INVALIDATE, PCISCR); + __raw_writel(PCICR1_LT(32) | PCICR1_CL(8), PCICR1); + __raw_writel(0, PCICR2); + + /* + * Set up the initiator windows for memory and IO mapping. + * These give the CPU bus access onto the PCI bus. One for each of + * PCI memory and IO address spaces. + */ + __raw_writel(WXBTAR(PCI_MEM_PA, PCI_MEM_BA, PCI_MEM_SIZE), + PCIIW0BTAR); + __raw_writel(WXBTAR(PCI_IO_PA, PCI_IO_BA, PCI_IO_SIZE), + PCIIW1BTAR); + __raw_writel(PCIIWCR_W0_MEM /*| PCIIWCR_W0_MRDL*/ | PCIIWCR_W0_E | + PCIIWCR_W1_IO | PCIIWCR_W1_E, PCIIWCR); + + /* + * Set up the target windows for access from the PCI bus back to the + * CPU bus. All we need is access to system RAM (for mastering). + */ + __raw_writel(CONFIG_RAMBASE, PCIBAR1); + __raw_writel(CONFIG_RAMBASE | PCITBATR1_E, PCITBATR1); + + /* Keep a virtual mapping to IO/config space active */ + iospace = (unsigned long) ioremap(PCI_IO_PA, PCI_IO_SIZE); + if (iospace == 0) + return -ENODEV; + pr_info("Coldfire: PCI IO/config window mapped to 0x%x\n", + (u32) iospace); + + /* Turn of PCI reset, and wait for devices to settle */ + __raw_writel(0, PCIGSCR); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(msecs_to_jiffies(200)); + + rootbus = pci_scan_bus(0, &mcf_pci_ops, NULL); + rootbus->resource[0] = &mcf_pci_io; + rootbus->resource[1] = &mcf_pci_mem; + + pci_fixup_irqs(pci_common_swizzle, mcf_pci_map_irq); + pci_bus_size_bridges(rootbus); + pci_bus_assign_resources(rootbus); + pci_enable_bridges(rootbus); + pci_bus_add_devices(rootbus); + return 0; +} + +subsys_initcall(mcf_pci_init); -- cgit v1.2.3 From b1f7735ef47a97108f945eac48812855b6599139 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Mon, 28 Nov 2011 13:22:53 +1000 Subject: m68k: allow PCI bus to be enabled for ColdFire m54xx CPUs All support code for the PCI bus hardware on the ColdFire 547x and 548x CPUs is now in. Allow enabling of CONFIG_PCI for them. Signed-off-by: Greg Ungerer --- arch/m68k/Kconfig.bus | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'arch/m68k') diff --git a/arch/m68k/Kconfig.bus b/arch/m68k/Kconfig.bus index 3adb499584fb..ffc0601a2a19 100644 --- a/arch/m68k/Kconfig.bus +++ b/arch/m68k/Kconfig.bus @@ -48,6 +48,13 @@ config ISA config GENERIC_ISA_DMA def_bool ISA +config PCI + bool "PCI support" + depends on M54xx + help + Enable the PCI bus. Support for the PCI bus hardware built into the + ColdFire 547x and 548x processors. + source "drivers/pci/Kconfig" source "drivers/zorro/Kconfig" -- cgit v1.2.3