Add initial support for Olimex iMX233 based OLinuXino boards.
https://www.olimex.com/Products/OLinuXino/iMX233/ Contributed by Petri Laakso.
This commit is contained in:
parent
eba5cacbdb
commit
da8587eaed
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: md.evbarm,v 1.11 2012/11/15 19:49:11 jkunz Exp $
|
||||
# $NetBSD: md.evbarm,v 1.12 2012/11/20 19:09:47 jkunz Exp $
|
||||
./usr/mdec/gzboot_ADI_BRH_0x00140000.bin base-sysutil-bin
|
||||
./usr/mdec/gzboot_GEMINI_0x01600000.bin base-sysutil-bin
|
||||
./usr/mdec/gzboot_IQ80310_0x00080000.bin base-sysutil-bin
|
||||
|
@ -8,6 +8,7 @@
|
|||
./usr/mdec/gzboot_SMDK2800_0x00100000.bin base-sysutil-bin
|
||||
./usr/mdec/gzboot_TS7200_0x60660000.bin base-sysutil-bin
|
||||
./usr/mdec/bootmini2440 base-sysutil-bin
|
||||
./usr/mdec/bootimx23 base-sysutil-bin
|
||||
./usr/sbin/elftosb base-sysutil-bin
|
||||
./usr/sbin/sbtool base-sysutil-bin
|
||||
./usr/sbin/sbkeygen base-sysutil-bin
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
# $Id: IMX23_OLINUXINO,v 1.1 2012/11/20 19:08:45 jkunz Exp $
|
||||
#
|
||||
# IMX23_OLINUXINO -- Olimex i.MX23 OLinuXino kernel configuration file.
|
||||
#
|
||||
|
||||
include "arch/evbarm/conf/std.imx23_olinuxino"
|
||||
|
||||
maxusers 8
|
||||
|
||||
config netbsd root on ? type ?
|
||||
|
||||
# The main bus device
|
||||
mainbus0 at root
|
||||
|
||||
# The boot CPU
|
||||
cpu0 at mainbus?
|
||||
|
||||
# APBH bus
|
||||
apbh0 at mainbus? base 0x80000000 size 0x00040000
|
||||
|
||||
# APBH DMA
|
||||
#apbdma0 at apbh? addr 0x80004000 size 0x2000 irq -1
|
||||
|
||||
# Interrupt controller
|
||||
icoll0 at apbh? addr 0x80000000 size 0x2000 irq -1
|
||||
|
||||
# Synchronous serial port for SD/MMC
|
||||
#ssp0 at apbh? addr 0x80010000 size 0x2000 irq 15
|
||||
#sdmmc* at ssp?
|
||||
#ld* at sdmmc?
|
||||
|
||||
# APBX bus
|
||||
apbx0 at mainbus? base 0x80040000 size 0x00040000
|
||||
|
||||
# APBX DMA
|
||||
#apbdma1 at apbx? addr 0x80024000 size 0x2000 irq -1
|
||||
|
||||
# Timers and rotary decoder
|
||||
timrot0 at apbx? addr 0x80068020 size 0x20 irq 28
|
||||
timrot1 at apbx? addr 0x80068040 size 0x20 irq 29
|
||||
#timrot2 at apbx? addr 0x80068060 size 0x20 irq 30
|
||||
#timrot3 at apbx? addr 0x80068080 size 0x20 irq 31
|
||||
|
||||
plcom0 at apbx? addr 0x80070000 size 0x1000 irq 0
|
||||
|
||||
options MEMSIZE=64
|
||||
options DDB
|
||||
options HZ=100
|
||||
|
||||
options MEMORY_DISK_HOOKS
|
||||
options MEMORY_DISK_IS_ROOT
|
||||
options MEMORY_DISK_ROOT_SIZE=12288 # 6 megs
|
||||
options MEMORY_DISK_RBFLAGS=RB_SINGLE
|
||||
|
||||
pseudo-device md
|
||||
|
||||
file-system FFS
|
|
@ -0,0 +1,10 @@
|
|||
# $Id: files.imx23_olinuxino,v 1.1 2012/11/20 19:08:45 jkunz Exp $
|
||||
#
|
||||
# Olimex i.MX23 OLinuXino board configuration info.
|
||||
#
|
||||
|
||||
# Pull in SoC support
|
||||
include "arch/arm/imx/files.imx23"
|
||||
|
||||
file arch/evbarm/imx23_olinuxino/imx23_olinuxino_machdep.c
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
# $Id: mk.imx23_olinuxino,v 1.1 2012/11/20 19:08:45 jkunz Exp $
|
||||
|
||||
SYSTEM_FIRST_OBJ= imx23_olinuxino_start.o
|
||||
SYSTEM_FIRST_SFILE= ${THISARM}/imx23_olinuxino/imx23_olinuxino_start.S
|
||||
|
||||
KERNEL_BASE_PHYS=0x40000000
|
||||
KERNEL_BASE_VIRT=0x40000000
|
|
@ -0,0 +1,21 @@
|
|||
# $Id: std.imx23_olinuxino,v 1.1 2012/11/20 19:08:45 jkunz Exp $
|
||||
#
|
||||
# IMX23_OLINUXINO standard kernel options.
|
||||
|
||||
machine evbarm arm
|
||||
include "conf/std" # Standard MI options.
|
||||
include "arch/arm/conf/std.arm" # Standard NetBSD/arm options.
|
||||
|
||||
options EXEC_ELF32
|
||||
options CPU_ARM9E
|
||||
|
||||
# To support easy transit to ../arch/arm/arm32
|
||||
options ARM32
|
||||
options ARM_INTR_IMPL="<arch/arm/imx/imx23_intr.h>"
|
||||
options EVBARM_BOARDTYPE=OLinuXino
|
||||
options KERNEL_BASE_EXT=0x40000000
|
||||
|
||||
makeoptions BOARDMKFRAG="${THISARM}/conf/mk.imx23_olinuxino"
|
||||
makeoptions CPUFLAGS="-march=armv5te -mtune=arm926ej-s"
|
||||
|
||||
include "arch/evbarm/conf/files.imx23_olinuxino"
|
|
@ -0,0 +1,679 @@
|
|||
/* $Id: imx23_olinuxino_machdep.c,v 1.1 2012/11/20 19:08:45 jkunz Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2012 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Petri Laakso.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/bus.h>
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/lwp.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/reboot.h>
|
||||
#include <sys/rnd.h>
|
||||
#include <sys/termios.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <uvm/uvm.h>
|
||||
#include <uvm/uvm_prot.h>
|
||||
#include <uvm/uvm_pmap.h>
|
||||
|
||||
#include <machine/db_machdep.h>
|
||||
#include <machine/bootconfig.h>
|
||||
#include <machine/frame.h>
|
||||
#include <machine/param.h>
|
||||
#include <machine/pcb.h>
|
||||
#include <machine/pmap.h>
|
||||
|
||||
#include <arm/undefined.h>
|
||||
#include <arm/arm32/machdep.h>
|
||||
|
||||
#include <arm/imx/imx23_digctlreg.h>
|
||||
#include <arm/imx/imx23_clkctrlreg.h>
|
||||
#include <arm/imx/imx23_rtcreg.h>
|
||||
#include <arm/imx/imx23_uartdbgreg.h>
|
||||
#include <arm/imx/imx23var.h>
|
||||
|
||||
#include "plcom.h"
|
||||
#if (NPLCOM > 0)
|
||||
#include <evbarm/dev/plcomreg.h>
|
||||
#include <evbarm/dev/plcomvar.h>
|
||||
#endif
|
||||
|
||||
#include "opt_evbarm_boardtype.h"
|
||||
|
||||
static vaddr_t get_ttb(void);
|
||||
static void setup_real_page_tables(void);
|
||||
//static void entropy_init(void);
|
||||
|
||||
/*
|
||||
* Static device map for i.MX23 peripheral address space.
|
||||
*/
|
||||
#define _A(a) ((a) & ~L1_S_OFFSET)
|
||||
#define _S(s) (((s) + L1_S_SIZE - 1) & ~(L1_S_SIZE-1))
|
||||
static const struct pmap_devmap imx23_devmap[] = {
|
||||
{
|
||||
_A(APBH_BASE), /* Virtual address. */
|
||||
_A(APBH_BASE), /* Physical address. */
|
||||
_S(APBH_SIZE + APBX_SIZE), /* APBX located after APBH. */
|
||||
VM_PROT_READ|VM_PROT_WRITE, /* Protection bits. */
|
||||
PTE_NOCACHE /* Cache attributes. */
|
||||
},
|
||||
{ 0, 0, 0, 0, 0 }
|
||||
};
|
||||
#undef _A
|
||||
#undef _S
|
||||
|
||||
static vm_offset_t physical_freestart;
|
||||
static vm_offset_t physical_freeend;
|
||||
static u_int free_pages;
|
||||
//static rndsave_t imx23_boot_rsp;
|
||||
|
||||
BootConfig bootconfig;
|
||||
vm_offset_t physical_start;
|
||||
vm_offset_t physical_end;
|
||||
char *boot_args;
|
||||
paddr_t msgbufphys;
|
||||
|
||||
extern char KERNEL_BASE_phys;
|
||||
extern char KERNEL_BASE_virt;
|
||||
extern char _end[];
|
||||
extern char __data_start[];
|
||||
extern char _edata[];
|
||||
extern char __bss_start[];
|
||||
extern char __bss_end__[];
|
||||
extern pv_addr_t kernelstack;
|
||||
|
||||
extern u_int data_abort_handler_address;
|
||||
extern u_int prefetch_abort_handler_address;
|
||||
|
||||
/* Define various stack sizes in pages. */
|
||||
#define FIQ_STACK_SIZE 1
|
||||
#define IRQ_STACK_SIZE 1
|
||||
#define ABT_STACK_SIZE 1
|
||||
#define UND_STACK_SIZE 1
|
||||
|
||||
/* Macros to translate between physical and virtual addresses. */
|
||||
#define KERNEL_BASE_PHYS ((paddr_t)&KERNEL_BASE_phys)
|
||||
#define KERNEL_BASE_VIRT ((vaddr_t)&KERNEL_BASE_virt)
|
||||
#define KERN_VTOPHYS(va) \
|
||||
((paddr_t)((vaddr_t)va - KERNEL_BASE_VIRT + KERNEL_BASE_PHYS))
|
||||
#define KERN_PHYSTOV(pa) \
|
||||
((vaddr_t)((paddr_t)pa - KERNEL_BASE_PHYS + KERNEL_BASE_VIRT))
|
||||
|
||||
#define KERNEL_PT_SYS 0 /* L2 table for mapping vectors page. */
|
||||
#define KERNEL_PT_KERNEL 1 /* L2 table for mapping kernel. */
|
||||
#define KERNEL_PT_KERNEL_NUM 4
|
||||
|
||||
#define KERNEL_PT_VMDATA (KERNEL_PT_KERNEL + KERNEL_PT_KERNEL_NUM)
|
||||
/* Page tables for mapping kernel VM */
|
||||
#define KERNEL_PT_VMDATA_NUM 4 /* start with 16MB of KVM */
|
||||
#define NUM_KERNEL_PTS (KERNEL_PT_VMDATA + KERNEL_PT_VMDATA_NUM)
|
||||
|
||||
pv_addr_t kernel_pt_table[NUM_KERNEL_PTS];
|
||||
|
||||
#define KERNEL_VM_BASE (KERNEL_BASE + 0x01000000)
|
||||
#define KERNEL_VM_SIZE (0xf0000000 - KERNEL_VM_BASE)
|
||||
|
||||
#define REG_RD(reg) *(volatile uint32_t *)(reg)
|
||||
#define REG_WR(reg, val) \
|
||||
do { \
|
||||
*(volatile uint32_t *)((reg)) = val; \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Initialize everything and return new svc stack pointer.
|
||||
*/
|
||||
u_int
|
||||
initarm(void *arg)
|
||||
{
|
||||
|
||||
if (set_cpufuncs())
|
||||
panic("set_cpufuncs failed");
|
||||
|
||||
pmap_devmap_bootstrap(get_ttb(), imx23_devmap);
|
||||
|
||||
cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT);
|
||||
|
||||
consinit();
|
||||
//entropy_init();
|
||||
|
||||
/* Talk to the user. */
|
||||
#define BDSTR(s) _BDSTR(s)
|
||||
#define _BDSTR(s) #s
|
||||
printf("\nNetBSD/evbarm (" BDSTR(EVBARM_BOARDTYPE) ") booting ...\n");
|
||||
#undef BDSTR
|
||||
#undef _BDSTR
|
||||
|
||||
boot_args[0] = '\0';
|
||||
|
||||
#ifdef VERBOSE_INIT_ARM
|
||||
printf("initarm: Configuring system ...\n");
|
||||
#endif
|
||||
|
||||
physical_start = DRAM_BASE;
|
||||
physical_end = DRAM_BASE + MEMSIZE * 1024 * 1024;
|
||||
physmem = (physical_end - physical_start) / PAGE_SIZE;
|
||||
|
||||
/* bootconfig is used by cpu_dump() and cousins. */
|
||||
bootconfig.dramblocks = 1;
|
||||
bootconfig.dram[0].address = DRAM_BASE;
|
||||
bootconfig.dram[0].pages = physmem;
|
||||
|
||||
/*
|
||||
* Our kernel is at the beginning of the DRAM, so set our free space to
|
||||
* all the memory after the kernel.
|
||||
*/
|
||||
physical_freestart = KERN_VTOPHYS(round_page((vaddr_t) _end));
|
||||
physical_freeend = physical_end;
|
||||
free_pages = (physical_freeend - physical_freestart) / PAGE_SIZE;
|
||||
|
||||
#ifdef VERBOSE_INIT_ARM
|
||||
/* Tell the user about the memory. */
|
||||
printf("physmemory: %d pages at 0x%08lx -> 0x%08lx\n", physmem,
|
||||
physical_start, physical_end - 1);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Set up first and second level page tables. Pages of memory will be
|
||||
* allocated and mapped for structures required for system operation.
|
||||
* kernel_l1pt, kernel_pt_table[], systempage, irqstack, abtstack,
|
||||
* undstack, kernelstack, msgbufphys will be set to point to the memory
|
||||
* that was allocated for them.
|
||||
*/
|
||||
setup_real_page_tables();
|
||||
|
||||
#ifdef VERBOSE_INIT_ARM
|
||||
printf("freestart = 0x%08lx, free_pages = %d (0x%08x)\n",
|
||||
physical_freestart, free_pages, free_pages);
|
||||
#endif
|
||||
|
||||
uvm_lwp_setuarea(&lwp0, kernelstack.pv_va);
|
||||
|
||||
#ifdef VERBOSE_INIT_ARM
|
||||
printf("bootstrap done.\n");
|
||||
#endif
|
||||
|
||||
/* Copy vectors from page0 to vectors page. */
|
||||
arm32_vector_init(ARM_VECTORS_HIGH, ARM_VEC_ALL);
|
||||
#ifdef VERBOSE_INIT_ARM
|
||||
printf("init subsystems: stacks ");
|
||||
#endif
|
||||
set_stackptr(PSR_FIQ32_MODE,
|
||||
fiqstack.pv_va + FIQ_STACK_SIZE * PAGE_SIZE);
|
||||
set_stackptr(PSR_IRQ32_MODE,
|
||||
irqstack.pv_va + IRQ_STACK_SIZE * PAGE_SIZE);
|
||||
set_stackptr(PSR_ABT32_MODE,
|
||||
abtstack.pv_va + ABT_STACK_SIZE * PAGE_SIZE);
|
||||
set_stackptr(PSR_UND32_MODE,
|
||||
undstack.pv_va + UND_STACK_SIZE * PAGE_SIZE);
|
||||
#ifdef VERBOSE_INIT_ARM
|
||||
printf("vectors ");
|
||||
#endif
|
||||
data_abort_handler_address = (u_int)data_abort_handler;
|
||||
prefetch_abort_handler_address = (u_int)prefetch_abort_handler;
|
||||
undefined_handler_address = (u_int)undefinedinstruction_bounce;
|
||||
#ifdef VERBOSE_INIT_ARM
|
||||
printf("undefined ");
|
||||
#endif
|
||||
undefined_init();
|
||||
/* Load memory into UVM. */
|
||||
#ifdef VERBOSE_INIT_ARM
|
||||
printf("page ");
|
||||
#endif
|
||||
uvm_setpagesize();
|
||||
uvm_page_physload(atop(physical_freestart), atop(physical_freeend),
|
||||
atop(physical_freestart), atop(physical_freeend),
|
||||
VM_FREELIST_DEFAULT);
|
||||
|
||||
/* Boot strap pmap telling it where the kernel page table is. */
|
||||
#ifdef VERBOSE_INIT_ARM
|
||||
printf("pmap ");
|
||||
#endif
|
||||
pmap_bootstrap(KERNEL_VM_BASE, KERNEL_VM_BASE + KERNEL_VM_SIZE);
|
||||
|
||||
#ifdef VERBOSE_INIT_ARM
|
||||
printf("done.\n");
|
||||
#endif
|
||||
|
||||
#ifdef __HAVE_MEMORY_DISK__
|
||||
md_root_setconf(memory_disk, sizeof memory_disk);
|
||||
#endif
|
||||
|
||||
#ifdef BOOTHOWTO
|
||||
boothowto |= BOOTHOWTO;
|
||||
#endif
|
||||
|
||||
#ifdef KGDB
|
||||
if (boothowto & RB_KDB) {
|
||||
kgdb_debug_init = 1;
|
||||
kgdb_connect(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DDB
|
||||
db_machine_init();
|
||||
if (boothowto & RB_KDB)
|
||||
Debugger();
|
||||
#endif
|
||||
|
||||
return kernelstack.pv_va + USPACE_SVC_STACK_TOP;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return TTBR (Translation Table Base Register) value from coprocessor.
|
||||
*/
|
||||
static vaddr_t
|
||||
get_ttb(void)
|
||||
{
|
||||
vaddr_t ttb;
|
||||
|
||||
__asm volatile("mrc p15, 0, %0, c2, c0, 0" : "=r" (ttb));
|
||||
|
||||
return ttb;
|
||||
}
|
||||
|
||||
/*
|
||||
* valloc_pages() is used to allocate free memory to be used for kernel pages.
|
||||
* Virtual and physical addresses of the allocated memory are saved for the
|
||||
* later use by the structures:
|
||||
*
|
||||
* - kernel_l1pt which holds the address of the kernel's L1 translaton table.
|
||||
* - kernel_pt_table[] holds the addresses of the kernel's L2 page tables.
|
||||
*
|
||||
* pmap_link_l2pt() is used to create link from L1 table entry to the L2 page
|
||||
* table. Link is a reference to coarse page table which has 256 entries,
|
||||
* splitting the 1MB that the table describes into 4kB blocks.
|
||||
*
|
||||
* pmap_map_entry() updates the PTE in L2 PT for an VA to point to single
|
||||
* physical page previously allocated.
|
||||
*
|
||||
* pmap_map_chunk() maps a chunk of memory using the most efficient
|
||||
* mapping possible (section, large page, small page) into the provided L1 and
|
||||
* L2 tables at the specified virtual address. pmap_map_chunk() excepts linking
|
||||
* to be done before it is called for chunks smaller than a section.
|
||||
*/
|
||||
static void
|
||||
setup_real_page_tables(void)
|
||||
{
|
||||
/*
|
||||
* Define a macro to simplify memory allocation. As we allocate the
|
||||
* memory, make sure that we don't walk over our temporary first level
|
||||
* translation table.
|
||||
*/
|
||||
#define valloc_pages(var, np) \
|
||||
(var).pv_pa = physical_freestart; \
|
||||
physical_freestart += ((np) * PAGE_SIZE); \
|
||||
if (physical_freestart > (physical_freeend - L1_TABLE_SIZE)) \
|
||||
panic("%s: out of memory", __func__); \
|
||||
free_pages -= (np); \
|
||||
(var).pv_va = KERN_PHYSTOV((var).pv_pa); \
|
||||
memset((char *)(var).pv_va, 0, ((np) * PAGE_SIZE));
|
||||
|
||||
int loop, pt_index;
|
||||
|
||||
pt_index = 0;
|
||||
kernel_l1pt.pv_pa = 0;
|
||||
kernel_l1pt.pv_va = 0;
|
||||
for (loop = 0; loop <= NUM_KERNEL_PTS; ++loop) {
|
||||
/* Are we 16kB aligned for an L1? */
|
||||
if ((physical_freestart & (L1_TABLE_SIZE - 1)) == 0 &&
|
||||
kernel_l1pt.pv_pa == 0) {
|
||||
valloc_pages(kernel_l1pt, L1_TABLE_SIZE / PAGE_SIZE);
|
||||
} else {
|
||||
valloc_pages(kernel_pt_table[pt_index],
|
||||
L2_TABLE_SIZE / PAGE_SIZE);
|
||||
++pt_index;
|
||||
}
|
||||
}
|
||||
|
||||
/* Make sure L1 page table is aligned to 16kB. */
|
||||
if (!kernel_l1pt.pv_pa ||
|
||||
(kernel_l1pt.pv_pa & (L1_TABLE_SIZE - 1)) != 0)
|
||||
panic("%s: Failed to align the kernel page directory",
|
||||
__func__);
|
||||
|
||||
/*
|
||||
* Allocate a page for the system page mapped to ARM_VECTORS_HIGH.
|
||||
* This page will just contain the system vectors and can be shared by
|
||||
* all processes.
|
||||
*/
|
||||
valloc_pages(systempage, 1);
|
||||
systempage.pv_va = ARM_VECTORS_HIGH;
|
||||
|
||||
/* Allocate stacks for all modes. */
|
||||
valloc_pages(fiqstack, FIQ_STACK_SIZE);
|
||||
valloc_pages(irqstack, IRQ_STACK_SIZE);
|
||||
valloc_pages(abtstack, ABT_STACK_SIZE);
|
||||
valloc_pages(undstack, UND_STACK_SIZE);
|
||||
valloc_pages(kernelstack, UPAGES);
|
||||
|
||||
/* Allocate the message buffer. */
|
||||
pv_addr_t msgbuf;
|
||||
int msgbuf_pgs = round_page(MSGBUFSIZE) / PAGE_SIZE;
|
||||
valloc_pages(msgbuf, msgbuf_pgs);
|
||||
msgbufphys = msgbuf.pv_pa;
|
||||
|
||||
vaddr_t l1_va = kernel_l1pt.pv_va;
|
||||
vaddr_t l1_pa = kernel_l1pt.pv_pa;
|
||||
|
||||
/* Map the L2 pages tables in the L1 page table. */
|
||||
|
||||
pmap_link_l2pt(l1_va, ARM_VECTORS_HIGH & ~(0x00400000 - 1),
|
||||
&kernel_pt_table[KERNEL_PT_SYS]);
|
||||
|
||||
for (loop = 0; loop < KERNEL_PT_KERNEL_NUM; loop++)
|
||||
pmap_link_l2pt(l1_va, KERNEL_BASE + loop * 0x00400000,
|
||||
&kernel_pt_table[KERNEL_PT_KERNEL + loop]);
|
||||
|
||||
for (loop = 0; loop < KERNEL_PT_VMDATA_NUM; loop++)
|
||||
pmap_link_l2pt(l1_va, KERNEL_VM_BASE + loop * 0x00400000,
|
||||
&kernel_pt_table[KERNEL_PT_VMDATA + loop]);
|
||||
|
||||
/* Update the top of the kernel VM. */
|
||||
pmap_curmaxkvaddr =
|
||||
KERNEL_VM_BASE + (KERNEL_PT_VMDATA_NUM * 0x00400000);
|
||||
|
||||
extern char etext[];
|
||||
size_t textsize = (uintptr_t)etext - KERNEL_BASE;
|
||||
size_t totalsize = (uintptr_t)_end - KERNEL_BASE;
|
||||
u_int logical;
|
||||
|
||||
textsize = (textsize + PGOFSET) & ~PGOFSET;
|
||||
totalsize = (totalsize + PGOFSET) & ~PGOFSET;
|
||||
|
||||
logical = 0x00000000; /* offset of kernel in RAM */
|
||||
|
||||
logical += pmap_map_chunk(l1_va, KERNEL_BASE + logical,
|
||||
physical_start + logical, textsize,
|
||||
VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
|
||||
|
||||
logical += pmap_map_chunk(l1_va, KERNEL_BASE + logical,
|
||||
physical_start + logical, totalsize - textsize,
|
||||
VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
|
||||
|
||||
/* Map the stack pages. */
|
||||
pmap_map_chunk(l1_va, fiqstack.pv_va, fiqstack.pv_pa,
|
||||
FIQ_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
|
||||
|
||||
pmap_map_chunk(l1_va, irqstack.pv_va, irqstack.pv_pa,
|
||||
IRQ_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
|
||||
|
||||
pmap_map_chunk(l1_va, abtstack.pv_va, abtstack.pv_pa,
|
||||
ABT_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
|
||||
|
||||
pmap_map_chunk(l1_va, undstack.pv_va, undstack.pv_pa,
|
||||
UND_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
|
||||
|
||||
pmap_map_chunk(l1_va, kernelstack.pv_va, kernelstack.pv_pa,
|
||||
UPAGES * PAGE_SIZE, VM_PROT_READ | VM_PROT_WRITE, PTE_CACHE);
|
||||
|
||||
pmap_map_chunk(l1_va, kernel_l1pt.pv_va, kernel_l1pt.pv_pa,
|
||||
L1_TABLE_SIZE, VM_PROT_READ | VM_PROT_WRITE, PTE_PAGETABLE);
|
||||
|
||||
for (loop = 0; loop < NUM_KERNEL_PTS; ++loop)
|
||||
pmap_map_chunk(l1_va, kernel_pt_table[loop].pv_va,
|
||||
kernel_pt_table[loop].pv_pa, L2_TABLE_SIZE,
|
||||
VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE);
|
||||
|
||||
/* Map the vector page. */
|
||||
pmap_map_entry(l1_va, ARM_VECTORS_HIGH, systempage.pv_pa,
|
||||
VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
|
||||
|
||||
pmap_devmap_bootstrap(l1_va, imx23_devmap);
|
||||
|
||||
#ifdef VERBOSE_INIT_ARM
|
||||
/* Tell the user about where all the bits and pieces live. */
|
||||
printf("%22s Physical Virtual Num\n", " ");
|
||||
printf("%22s Starting Ending Starting Ending Pages\n", " ");
|
||||
|
||||
static const char mem_fmt[] =
|
||||
"%20s: 0x%08lx 0x%08lx 0x%08lx 0x%08lx %d\n";
|
||||
static const char mem_fmt_nov[] =
|
||||
"%20s: 0x%08lx 0x%08lx %d\n";
|
||||
|
||||
printf(mem_fmt, "SDRAM", physical_start, physical_end-1,
|
||||
KERN_PHYSTOV(physical_start), KERN_PHYSTOV(physical_end-1),
|
||||
physmem);
|
||||
printf(mem_fmt, "text section",
|
||||
KERN_VTOPHYS(KERNEL_BASE), KERN_VTOPHYS(etext-1),
|
||||
(vaddr_t)KERNEL_BASE, (vaddr_t)etext-1,
|
||||
(int)(textsize / PAGE_SIZE));
|
||||
printf(mem_fmt, "data section",
|
||||
KERN_VTOPHYS(__data_start), KERN_VTOPHYS(_edata),
|
||||
(vaddr_t)__data_start, (vaddr_t)_edata,
|
||||
(int)((round_page((vaddr_t)_edata)
|
||||
- trunc_page((vaddr_t)__data_start)) / PAGE_SIZE));
|
||||
printf(mem_fmt, "bss section",
|
||||
KERN_VTOPHYS(__bss_start), KERN_VTOPHYS(__bss_end__),
|
||||
(vaddr_t)__bss_start, (vaddr_t)__bss_end__,
|
||||
(int)((round_page((vaddr_t)__bss_end__)
|
||||
- trunc_page((vaddr_t)__bss_start)) / PAGE_SIZE));
|
||||
printf(mem_fmt, "L1 page directory",
|
||||
kernel_l1pt.pv_pa, kernel_l1pt.pv_pa + L1_TABLE_SIZE - 1,
|
||||
kernel_l1pt.pv_va, kernel_l1pt.pv_va + L1_TABLE_SIZE - 1,
|
||||
L1_TABLE_SIZE / PAGE_SIZE);
|
||||
printf(mem_fmt, "Exception Vectors",
|
||||
systempage.pv_pa, systempage.pv_pa + PAGE_SIZE - 1,
|
||||
(vaddr_t)ARM_VECTORS_HIGH,
|
||||
(vaddr_t)ARM_VECTORS_HIGH + PAGE_SIZE - 1, 1);
|
||||
printf(mem_fmt, "FIQ stack",
|
||||
fiqstack.pv_pa, fiqstack.pv_pa + (FIQ_STACK_SIZE * PAGE_SIZE) - 1,
|
||||
fiqstack.pv_va, fiqstack.pv_va + (FIQ_STACK_SIZE * PAGE_SIZE) - 1,
|
||||
FIQ_STACK_SIZE);
|
||||
printf(mem_fmt, "IRQ stack",
|
||||
irqstack.pv_pa, irqstack.pv_pa + (IRQ_STACK_SIZE * PAGE_SIZE) - 1,
|
||||
irqstack.pv_va, irqstack.pv_va + (IRQ_STACK_SIZE * PAGE_SIZE) - 1,
|
||||
IRQ_STACK_SIZE);
|
||||
printf(mem_fmt, "ABT stack",
|
||||
abtstack.pv_pa, abtstack.pv_pa + (ABT_STACK_SIZE * PAGE_SIZE) - 1,
|
||||
abtstack.pv_va, abtstack.pv_va + (ABT_STACK_SIZE * PAGE_SIZE) - 1,
|
||||
ABT_STACK_SIZE);
|
||||
printf(mem_fmt, "UND stack",
|
||||
undstack.pv_pa, undstack.pv_pa + (UND_STACK_SIZE * PAGE_SIZE) - 1,
|
||||
undstack.pv_va, undstack.pv_va + (UND_STACK_SIZE * PAGE_SIZE) - 1,
|
||||
UND_STACK_SIZE);
|
||||
printf(mem_fmt, "SVC stack",
|
||||
kernelstack.pv_pa, kernelstack.pv_pa + (UPAGES * PAGE_SIZE) - 1,
|
||||
kernelstack.pv_va, kernelstack.pv_va + (UPAGES * PAGE_SIZE) - 1,
|
||||
UPAGES);
|
||||
printf(mem_fmt_nov, "Message Buffer",
|
||||
msgbufphys, msgbufphys + msgbuf_pgs * PAGE_SIZE - 1, msgbuf_pgs);
|
||||
printf(mem_fmt, "Free Memory", physical_freestart, physical_freeend-1,
|
||||
KERN_PHYSTOV(physical_freestart), KERN_PHYSTOV(physical_freeend-1),
|
||||
free_pages);
|
||||
#endif
|
||||
|
||||
cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT);
|
||||
cpu_setttb(l1_pa, FALSE);
|
||||
cpu_tlb_flushID();
|
||||
cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate initial random bits for rnd_init().
|
||||
*/
|
||||
#ifdef notyet
|
||||
static void
|
||||
entropy_init(void)
|
||||
{
|
||||
uint32_t tmp;
|
||||
int loop, index;
|
||||
|
||||
/* Test if HW_DIGCTL_ENTROPY is feeding random numbers. */
|
||||
tmp = REG_RD(HW_DIGCTL_BASE + HW_DIGCTL_ENTROPY);
|
||||
if (tmp == REG_RD(HW_DIGCTL_BASE + HW_DIGCTL_ENTROPY))
|
||||
return;
|
||||
|
||||
index = 0;
|
||||
for (loop = 0; loop < RND_SAVEWORDS; loop++) {
|
||||
imx23_boot_rsp.data[index++] = (uint8_t)(tmp);
|
||||
imx23_boot_rsp.data[index++] = (uint8_t)(tmp>>8);
|
||||
imx23_boot_rsp.data[index++] = (uint8_t)(tmp>>16);
|
||||
imx23_boot_rsp.data[index++] = (uint8_t)(tmp>>24);
|
||||
imx23_boot_rsp.entropy += 32;
|
||||
tmp = REG_RD(HW_DIGCTL_BASE + HW_DIGCTL_ENTROPY);
|
||||
}
|
||||
|
||||
extern rndsave_t *boot_rsp;
|
||||
boot_rsp = &imx23_boot_rsp;
|
||||
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Initialize console.
|
||||
*/
|
||||
static struct plcom_instance imx23_pi = {
|
||||
.pi_type = PLCOM_TYPE_PL011,
|
||||
.pi_iot = &imx23_bus_space,
|
||||
.pi_size = PL011COM_UART_SIZE,
|
||||
.pi_iobase = HW_UARTDBG_BASE
|
||||
};
|
||||
|
||||
#define PLCONMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */
|
||||
#define PLCONSPEED 115200
|
||||
void
|
||||
consinit(void)
|
||||
{
|
||||
/* consinit() is called from also from the main(). */
|
||||
static int consinit_called = 0;
|
||||
|
||||
if (consinit_called)
|
||||
return;
|
||||
|
||||
plcomcnattach(&imx23_pi, PLCONSPEED, IMX23_UART_CLK, PLCONMODE, 0);
|
||||
|
||||
consinit_called = 1;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reboot or halt the system.
|
||||
*/
|
||||
void
|
||||
cpu_reboot(int howto, char *bootstr)
|
||||
{
|
||||
static int cpu_reboot_called = 0;
|
||||
|
||||
boothowto |= howto;
|
||||
|
||||
/*
|
||||
* If this is the first invocation of cpu_reboot() and the RB_NOSYNC
|
||||
* flag is not set in howto; sync and unmount the system disks by
|
||||
* calling vfs_shutdown(9) and set the time of day clock by calling
|
||||
* resettodr(9).
|
||||
*/
|
||||
if (!cpu_reboot_called && !(boothowto & RB_NOSYNC)) {
|
||||
vfs_shutdown();
|
||||
resettodr();
|
||||
}
|
||||
|
||||
cpu_reboot_called = 1;
|
||||
|
||||
IRQdisable; /* FIQ's stays on because they are special. */
|
||||
|
||||
/*
|
||||
* If rebooting after a crash (i.e., if RB_DUMP is set in howto, but
|
||||
* RB_HALT is not), save a system crash dump.
|
||||
*/
|
||||
if ((boothowto & RB_DUMP) && !(boothowto & RB_HALT))
|
||||
panic("please implement crash dump!"); // XXX
|
||||
|
||||
/* Run any shutdown hooks by calling pmf_system_shutdown(9). */
|
||||
pmf_system_shutdown(boothowto);
|
||||
|
||||
printf("system %s.\n", boothowto & RB_HALT ? "halted" : "rebooted");
|
||||
|
||||
if (boothowto & RB_HALT) {
|
||||
/* Enable i.MX233 wait-for-interrupt mode. */
|
||||
REG_WR(HW_CLKCTRL_BASE + HW_CLKCTRL_CPU,
|
||||
(REG_RD(HW_CLKCTRL_BASE + HW_CLKCTRL_CPU) |
|
||||
HW_CLKCTRL_CPU_INTERRUPT_WAIT));
|
||||
|
||||
/* Disable FIQ's and wait for interrupt (which never arrives) */
|
||||
__asm volatile( \
|
||||
"mrs r0, cpsr\n\t" \
|
||||
"orr r0, #0x40\n\t" \
|
||||
"msr cpsr_c, r0\n\t" \
|
||||
"mov r0, #0\n\t" \
|
||||
"mcr p15, 0, r0, c7, c0, 4\n\t"
|
||||
);
|
||||
|
||||
for(;;);
|
||||
|
||||
/* NOT REACHED */
|
||||
}
|
||||
|
||||
/* Reboot the system. */
|
||||
REG_WR(HW_RTC_BASE + HW_RTC_WATCHDOG, 10000);
|
||||
REG_WR(HW_RTC_BASE + HW_RTC_CTRL_SET, HW_RTC_CTRL_WATCHDOGEN);
|
||||
REG_WR(HW_RTC_BASE + HW_RTC_WATCHDOG, 0);
|
||||
|
||||
for(;;);
|
||||
|
||||
/* NOT REACHED */
|
||||
}
|
||||
|
||||
/*
|
||||
* Delay us microseconds.
|
||||
*/
|
||||
void
|
||||
delay(unsigned int us)
|
||||
{
|
||||
uint32_t start;
|
||||
uint32_t now;
|
||||
uint32_t elapsed;
|
||||
uint32_t total;
|
||||
uint32_t last;
|
||||
|
||||
total = 0;
|
||||
last = 0;
|
||||
start = REG_RD(HW_DIGCTL_BASE + HW_DIGCTL_MICROSECONDS);
|
||||
|
||||
do {
|
||||
now = REG_RD(HW_DIGCTL_BASE + HW_DIGCTL_MICROSECONDS);
|
||||
|
||||
if (start <= now)
|
||||
elapsed = now - start;
|
||||
else /* Take care of overflow. */
|
||||
elapsed = (UINT32_MAX - start) + 1 + now;
|
||||
|
||||
total += elapsed - last;
|
||||
last = elapsed;
|
||||
|
||||
} while (total < us);
|
||||
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,185 @@
|
|||
/* $Id: imx23_olinuxino_start.S,v 1.1 2012/11/20 19:08:46 jkunz Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2012 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Petri Laakso.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <machine/asm.h>
|
||||
#include <machine/pmap.h>
|
||||
#include <arm/armreg.h>
|
||||
#include <arm/imx/imx23var.h>
|
||||
#include <arm/imx/imx23_uartdbgreg.h>
|
||||
|
||||
.section .start,"ax",%progbits
|
||||
|
||||
.global _C_LABEL(olinuxino_start)
|
||||
_C_LABEL(olinuxino_start):
|
||||
|
||||
/*
|
||||
* Set up the first level page table. The page table has 4096 section
|
||||
* page table entries which each one maps 1MB of virtual memory.
|
||||
* Section entries are mapped from mmu_init_table to the page table.
|
||||
*/
|
||||
l1pt_p .req r0
|
||||
mit_p .req r1
|
||||
va .req r2
|
||||
pa .req r3
|
||||
n_sec .req r4
|
||||
attr .req r5
|
||||
pte_p .req r6
|
||||
sec .req r7
|
||||
tmp .req r8
|
||||
tmp2 .req r9
|
||||
|
||||
ldr l1pt_p, Ll1_pt
|
||||
|
||||
/* Zero the page table. */
|
||||
mov tmp, #0
|
||||
add tmp2, l1pt_p, #L1_TABLE_SIZE
|
||||
1: str tmp, [l1pt_p], #4
|
||||
cmp l1pt_p, tmp2
|
||||
blt 1b
|
||||
|
||||
ldr l1pt_p, Ll1_pt
|
||||
|
||||
/* Map sections. */
|
||||
ldr mit_p, =mmu_init_table
|
||||
ldmia mit_p!, {va, pa, n_sec, attr}
|
||||
|
||||
/*
|
||||
* Calculate PTE addresses for a MVA's.
|
||||
*
|
||||
* Bits[31:14] of the Translation Table Base register are concatenated
|
||||
* with bits[31:20] of the modified virtual address and two zero bits
|
||||
* to produce a physical address of the page table entry for a MVA:
|
||||
*
|
||||
* PTE = (TTBR & 0xffffc000) | ((MVA & 0xfff00000)>>18)
|
||||
*/
|
||||
3: ldr tmp, =0xffffc000
|
||||
and pte_p, l1pt_p, tmp
|
||||
ldr tmp, =0xfff00000
|
||||
and va, va, tmp
|
||||
mov va, va, LSR #18
|
||||
orr pte_p, pte_p, va
|
||||
|
||||
2: orr sec, pa, attr
|
||||
str sec, [pte_p], #4 /* Store #n_sec sections to the page */
|
||||
add pa, pa, #0x100000 /* table. */
|
||||
subs n_sec, #1
|
||||
bne 2b
|
||||
|
||||
ldmia mit_p!, {va, pa, n_sec, attr}
|
||||
cmp n_sec, #0
|
||||
bne 3b
|
||||
|
||||
/*
|
||||
* The Translation Table Base Register holds the physical address of
|
||||
* the page table.
|
||||
*/
|
||||
mcr p15, 0, l1pt_p, c2, c0, 0
|
||||
|
||||
.unreq l1pt_p
|
||||
.unreq mit_p
|
||||
.unreq va
|
||||
.unreq pa
|
||||
.unreq n_sec
|
||||
.unreq attr
|
||||
.unreq pte_p
|
||||
.unreq sec
|
||||
.unreq tmp
|
||||
.unreq tmp2
|
||||
|
||||
/*
|
||||
* Sections are in domain 0 and we set D0 access control to client
|
||||
* mode, which means AP bits are checked. Since we are running
|
||||
* privileged mode and APs are kernel read/write, access is granted.
|
||||
*/
|
||||
mov r0, #DOMAIN_CLIENT<<(PMAP_DOMAIN_KERNEL*2)
|
||||
mcr p15, 0, r0, c3, c0, 0
|
||||
|
||||
/*
|
||||
* Enable the MMU.
|
||||
*/
|
||||
mov r0, #0
|
||||
mcr p15, 0, r0, c8, c7, 0 /* Invalidate TLB. */
|
||||
|
||||
mrc p15, 0, r0, c1, c0, 0
|
||||
ldr r1, =(CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE \
|
||||
| CPU_CONTROL_AFLT_ENABLE | CPU_CONTROL_MMU_ENABLE)
|
||||
orr r0, r0, r1
|
||||
mcr p15, 0, r0, c1, c0, 0
|
||||
nop /* Fetch flat. */
|
||||
nop /* Fetch flat. */
|
||||
|
||||
/*
|
||||
* Jump to start in locore.S. start sets the sp point to DRAM, zeroes
|
||||
* the .bss and calls initarm. start never returns.
|
||||
*/
|
||||
ldr pc, =start
|
||||
|
||||
/* NOTREACHED */
|
||||
|
||||
/*
|
||||
* Initial first level translation table on a 16kB boundary located at the
|
||||
* end of the DRAM.
|
||||
*
|
||||
* The translation table has 4096 32-bit section entries, each describing 1MB of
|
||||
* virtual memory which means 4GB of virtual memory to be addressed.
|
||||
*/
|
||||
Ll1_pt:
|
||||
.word (DRAM_BASE + MEMSIZE * 1024 * 1024 - L1_TABLE_SIZE)
|
||||
|
||||
#define MMU_INIT(va,pa,n_sec,attr) \
|
||||
.word va; \
|
||||
.word pa; \
|
||||
.word n_sec; \
|
||||
.word attr;
|
||||
|
||||
mmu_init_table:
|
||||
/* On-chip RAM */
|
||||
MMU_INIT(0x00000000, 0x00000000,
|
||||
1,
|
||||
L1_S_AP(AP_KRW) | L1_S_DOM(PMAP_DOMAIN_KERNEL) | L1_S_PROTO)
|
||||
|
||||
/* On-chip ROM (Vectors) */
|
||||
MMU_INIT(0xFFFF0000, 0xFFFF0000,
|
||||
1,
|
||||
L1_S_AP(AP_KRW) | L1_S_DOM(PMAP_DOMAIN_KERNEL) | L1_S_PROTO)
|
||||
|
||||
/* DRAM */
|
||||
MMU_INIT(KERNEL_BASE_virt, KERNEL_BASE_phys,
|
||||
MEMSIZE,
|
||||
L1_S_AP(AP_KRW) | L1_S_DOM(PMAP_DOMAIN_KERNEL) | L1_S_C |\
|
||||
L1_S_B | L1_S_PROTO)
|
||||
|
||||
/* Peripherals */
|
||||
MMU_INIT(APBH_BASE, APBH_BASE,
|
||||
1,
|
||||
L1_S_AP(AP_KRW) | L1_S_DOM(PMAP_DOMAIN_KERNEL) | L1_S_PROTO)
|
||||
|
||||
MMU_INIT(0, 0, 0, 0)
|
|
@ -1,6 +1,7 @@
|
|||
# $NetBSD: Makefile,v 1.2 2012/01/30 03:28:34 nisimura Exp $
|
||||
# $NetBSD: Makefile,v 1.3 2012/11/20 19:17:03 jkunz Exp $
|
||||
|
||||
SUBDIR+= gzboot
|
||||
SUBDIR+= boot2440
|
||||
SUBDIR+= bootimx23
|
||||
|
||||
.include <bsd.subdir.mk>
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
# $Id: Makefile,v 1.1 2012/11/20 19:08:46 jkunz Exp $
|
||||
|
||||
S= ${.CURDIR}/../../../../
|
||||
PROG= bootimx23
|
||||
SRCS= boot_prep.c power_prep.c clock_prep.c emi_prep.c \
|
||||
pinctrl_prep.c common.c
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
CLEANFILES+= ${PROG}
|
||||
CFLAGS+= -Wall -Wno-main -ffreestanding -march=armv5te -mtune=arm926ej-s
|
||||
CPPFLAGS+= -D_STANDALONE
|
||||
CPPFLAGS+= -nostdinc -I. -I${.CURDIR} -I${.OBJDIR} -I${S} -I${S}/arch
|
||||
#CPPFLAGS+= -DDEBUG
|
||||
#DBG= -g
|
||||
|
||||
LIBCRT0= # nothing
|
||||
LIBCRTBEGIN= # nothing
|
||||
LIBCRTEND= # nothing
|
||||
LIBC= # nothing
|
||||
|
||||
MAN= # no manual page
|
||||
NOMAN= # defined
|
||||
STRIPFLAG=
|
||||
BINMODE= 444
|
||||
|
||||
RELOC= 0x00000000
|
||||
ENTRY= _start
|
||||
|
||||
### find out what to use for libkern
|
||||
KERN_AS= library
|
||||
.include "${S}/lib/libkern/Makefile.inc"
|
||||
LIBKERN= ${KERNLIB}
|
||||
|
||||
### find out what to use for libsa
|
||||
SA_AS= library
|
||||
.include "${S}/lib/libsa/Makefile.inc"
|
||||
LIBSA= ${SALIB}
|
||||
|
||||
${PROG}: ${OBJS} ${LIBSA} ${LIBKERN}
|
||||
${LD} -N -Ttext ${RELOC} -Bstatic -e ${ENTRY} -o ${.TARGET} \
|
||||
${OBJS} ${LIBSA} ${LIBKERN}
|
||||
|
||||
|
||||
cleandir distclean: .WAIT cleanlibdir
|
||||
|
||||
cleanlibdir:
|
||||
-rm -rf lib
|
||||
|
||||
.include <bsd.klinks.mk>
|
||||
.include <bsd.prog.mk>
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
/* $Id: boot_prep.c,v 1.1 2012/11/20 19:08:46 jkunz Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2012 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Petri Laakso.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
#include <arm/imx/imx23_digctlreg.h>
|
||||
|
||||
#include <lib/libsa/stand.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
/*
|
||||
* Initialize i.MX23 power, clock and DRAM.
|
||||
*/
|
||||
int
|
||||
_start(void)
|
||||
{
|
||||
|
||||
/* Make sure timer is running */
|
||||
REG_WRITE(HW_DIGCTL_BASE + HW_DIGCTL_CTRL_CLR,
|
||||
HW_DIGCTL_CTRL_XTAL24M_GATE);
|
||||
|
||||
printf("\n\rBooting");
|
||||
|
||||
power_prep();
|
||||
putchar('.');
|
||||
|
||||
clock_prep();
|
||||
putchar('.');
|
||||
|
||||
pinctrl_prep();
|
||||
delay_us(1000);
|
||||
putchar('.');
|
||||
|
||||
emi_prep();
|
||||
printf("done.\n\r");
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/* $Id: bootimx23.bd,v 1.1 2012/11/20 19:08:46 jkunz Exp $ */
|
||||
|
||||
/*
|
||||
* elftosb command file.
|
||||
*
|
||||
* Generate boot image by issuing:
|
||||
* $ elftosb -V -c bootimx23.bd -z -o bootimx23.sb
|
||||
*
|
||||
* Verify generated boot image:
|
||||
* $ sbtool -x 2 bootimx23.sb
|
||||
*
|
||||
*/
|
||||
|
||||
options {
|
||||
toolset = "GNU";
|
||||
}
|
||||
|
||||
sources {
|
||||
boot_prep="./boot_prep.elf";
|
||||
netbsd="./netbsd";
|
||||
}
|
||||
|
||||
section (0) {
|
||||
// Initialize power, clocks and DRAM.
|
||||
load boot_prep;
|
||||
call boot_prep;
|
||||
|
||||
// Load and start NetBSD kernel.
|
||||
load netbsd;
|
||||
jump netbsd;
|
||||
}
|
|
@ -0,0 +1,255 @@
|
|||
/* $Id: clock_prep.c,v 1.1 2012/11/20 19:08:46 jkunz Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2012 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Petri Laakso.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <arm/imx/imx23_clkctrlreg.h>
|
||||
|
||||
#include <lib/libsa/stand.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
void enable_pll(void);
|
||||
void enable_ref_cpu(int);
|
||||
void enable_ref_emi(int);
|
||||
void enable_ref_io(int);
|
||||
void use_ref_cpu(void);
|
||||
void use_ref_emi(void);
|
||||
void use_ref_io(void);
|
||||
void set_hbus_div(int);
|
||||
void set_emi_div(int);
|
||||
void set_ssp_div(int);
|
||||
|
||||
/* Clock frequences after clock_prep() */
|
||||
#define CPU_FRAC 0x13 /* CPUCLK @ 454.74 MHz */
|
||||
#define HBUS_DIV 0x3 /* AHBCLK @ 151.58 MHz */
|
||||
#define EMI_FRAC 0x21 /* EMICLK @ 130.91 MHz */
|
||||
#define EMI_DIV 0x2
|
||||
#define IO_FRAC 0x12 /* IOCLK @ 480.00 MHz */
|
||||
#define SSP_DIV 0x5 /* SSPCLK @ 96.00 MHz */
|
||||
|
||||
/* Offset to frac register for byte store instructions. (strb) */
|
||||
#define HW_CLKCTRL_FRAC_CPU (HW_CLKCTRL_FRAC+0)
|
||||
#define HW_CLKCTRL_FRAC_EMI (HW_CLKCTRL_FRAC+1)
|
||||
#define HW_CLKCTRL_FRAC_IO (HW_CLKCTRL_FRAC+3)
|
||||
|
||||
#define CLKCTRL_RD(reg) *(volatile uint32_t *)((HW_CLKCTRL_BASE) + (reg))
|
||||
#define CLKCTRL_WR(reg, val) \
|
||||
do { \
|
||||
*(volatile uint32_t *)((HW_CLKCTRL_BASE) + (reg)) = val; \
|
||||
} while (0)
|
||||
#define CLKCTRL_WR_BYTE(reg, val) \
|
||||
do { \
|
||||
*(volatile uint8_t *)((HW_CLKCTRL_BASE) + (reg)) = val; \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Initializes fast PLL based clocks for CPU, HBUS and DRAM.
|
||||
*/
|
||||
int
|
||||
clock_prep(void)
|
||||
{
|
||||
|
||||
enable_pll();
|
||||
enable_ref_cpu(CPU_FRAC);
|
||||
enable_ref_emi(EMI_FRAC);
|
||||
enable_ref_io(IO_FRAC);
|
||||
set_emi_div(EMI_DIV);
|
||||
set_hbus_div(HBUS_DIV);
|
||||
delay_us(1000);
|
||||
use_ref_cpu();
|
||||
//delay_us(1000);
|
||||
use_ref_emi();
|
||||
use_ref_io();
|
||||
set_ssp_div(SSP_DIV);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Turn PLL on and wait until it's locked to 480 MHz.
|
||||
*/
|
||||
void
|
||||
enable_pll(void)
|
||||
{
|
||||
|
||||
CLKCTRL_WR(HW_CLKCTRL_PLLCTRL0_SET, HW_CLKCTRL_PLLCTRL0_POWER);
|
||||
while (!(CLKCTRL_RD(HW_CLKCTRL_PLLCTRL1) & HW_CLKCTRL_PLLCTRL1_LOCK));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable fractional divider clock ref_cpu with divide value "frac".
|
||||
*/
|
||||
void
|
||||
enable_ref_cpu(int frac)
|
||||
{
|
||||
uint32_t reg;
|
||||
|
||||
reg = CLKCTRL_RD(HW_CLKCTRL_FRAC);
|
||||
reg &= ~(HW_CLKCTRL_FRAC_CLKGATECPU | HW_CLKCTRL_FRAC_CPUFRAC);
|
||||
reg |= __SHIFTIN(frac, HW_CLKCTRL_FRAC_CPUFRAC);
|
||||
CLKCTRL_WR_BYTE(HW_CLKCTRL_FRAC_CPU, reg);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable fractional divider clock ref_emi with divide value "frac".
|
||||
*/
|
||||
void
|
||||
enable_ref_emi(int frac)
|
||||
{
|
||||
uint32_t reg;
|
||||
|
||||
reg = CLKCTRL_RD(HW_CLKCTRL_FRAC);
|
||||
reg &= ~(HW_CLKCTRL_FRAC_CLKGATEEMI | HW_CLKCTRL_FRAC_EMIFRAC);
|
||||
reg |= __SHIFTIN(frac, HW_CLKCTRL_FRAC_EMIFRAC);
|
||||
CLKCTRL_WR_BYTE(HW_CLKCTRL_FRAC_EMI, (reg >> 8));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable fractional divider clock ref_io with divide value "frac".
|
||||
*/
|
||||
void
|
||||
enable_ref_io(int frac)
|
||||
{
|
||||
uint32_t reg;
|
||||
|
||||
reg = CLKCTRL_RD(HW_CLKCTRL_FRAC);
|
||||
reg &= ~(HW_CLKCTRL_FRAC_CLKGATEIO | HW_CLKCTRL_FRAC_IOFRAC);
|
||||
reg |= __SHIFTIN(frac, HW_CLKCTRL_FRAC_IOFRAC);
|
||||
CLKCTRL_WR_BYTE(HW_CLKCTRL_FRAC_IO, (reg >> 24));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Divide CLK_P by "div" to get CLK_H frequency.
|
||||
*/
|
||||
void
|
||||
set_hbus_div(int div)
|
||||
{
|
||||
uint32_t reg;
|
||||
|
||||
reg = CLKCTRL_RD(HW_CLKCTRL_HBUS);
|
||||
reg &= ~(HW_CLKCTRL_HBUS_DIV);
|
||||
reg |= __SHIFTIN(div, HW_CLKCTRL_HBUS_DIV);
|
||||
while (CLKCTRL_RD(HW_CLKCTRL_HBUS) & HW_CLKCTRL_HBUS_BUSY);
|
||||
CLKCTRL_WR(HW_CLKCTRL_HBUS, reg);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* ref_emi is divied "div" to get CLK_EMI.
|
||||
*/
|
||||
void
|
||||
set_emi_div(int div)
|
||||
{
|
||||
uint32_t reg;
|
||||
|
||||
reg = CLKCTRL_RD(HW_CLKCTRL_EMI);
|
||||
reg &= ~(HW_CLKCTRL_EMI_DIV_EMI);
|
||||
reg |= __SHIFTIN(div, HW_CLKCTRL_EMI_DIV_EMI);
|
||||
CLKCTRL_WR(HW_CLKCTRL_EMI, reg);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* ref_io is divied "div" to get CLK_SSP.
|
||||
*/
|
||||
void
|
||||
set_ssp_div(int div)
|
||||
{
|
||||
uint32_t reg;
|
||||
|
||||
reg = CLKCTRL_RD(HW_CLKCTRL_SSP);
|
||||
reg &= ~(HW_CLKCTRL_SSP_DIV);
|
||||
reg |= __SHIFTIN(div, HW_CLKCTRL_SSP_DIV);
|
||||
CLKCTRL_WR(HW_CLKCTRL_SSP, reg);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Transition from ref_xtal to use ref_cpu.
|
||||
*/
|
||||
void
|
||||
use_ref_cpu(void)
|
||||
{
|
||||
CLKCTRL_WR(HW_CLKCTRL_CLKSEQ_CLR, HW_CLKCTRL_CLKSEQ_BYPASS_CPU);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Transition from ref_xtal to use ref_emi and source CLK_EMI from ref_emi.
|
||||
*/
|
||||
void
|
||||
use_ref_emi(void)
|
||||
{
|
||||
uint32_t reg;
|
||||
|
||||
/* Enable ref_emi. */
|
||||
CLKCTRL_WR(HW_CLKCTRL_CLKSEQ_CLR, HW_CLKCTRL_CLKSEQ_BYPASS_EMI);
|
||||
|
||||
/* CLK_EMI sourced by the ref_emi. */
|
||||
reg = CLKCTRL_RD(HW_CLKCTRL_EMI);
|
||||
reg &= ~(HW_CLKCTRL_EMI_CLKGATE);
|
||||
CLKCTRL_WR(HW_CLKCTRL_EMI, reg);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Transition from ref_xtal to use ref_io and source CLK_SSP from ref_io.
|
||||
*/
|
||||
void
|
||||
use_ref_io(void)
|
||||
{
|
||||
uint32_t reg;
|
||||
|
||||
/* Enable ref_io for SSP. */
|
||||
CLKCTRL_WR(HW_CLKCTRL_CLKSEQ_CLR, HW_CLKCTRL_CLKSEQ_BYPASS_SSP);
|
||||
|
||||
/* CLK_SSP sourced by the ref_io. */
|
||||
reg = CLKCTRL_RD(HW_CLKCTRL_SSP);
|
||||
reg &= ~(HW_CLKCTRL_SSP_CLKGATE);
|
||||
CLKCTRL_WR(HW_CLKCTRL_SSP, reg);
|
||||
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
/* $Id: common.c,v 1.1 2012/11/20 19:08:46 jkunz Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2012 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Petri Laakso.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
#include <arm/imx/imx23_digctlreg.h>
|
||||
#include <arm/imx/imx23_uartdbgreg.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
/*
|
||||
* Delay "delay" microseconds.
|
||||
*/
|
||||
void
|
||||
delay_us(unsigned int delay)
|
||||
{
|
||||
|
||||
/* Set microsecond timer to 0 */
|
||||
REG_WRITE(HW_DIGCTL_BASE + HW_DIGCTL_MICROSECONDS_CLR, 0xFFFFFFFF);
|
||||
|
||||
while (REG_READ(HW_DIGCTL_BASE + HW_DIGCTL_MICROSECONDS) < delay);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write character to debug UART.
|
||||
*/
|
||||
void
|
||||
putchar(int ch)
|
||||
{
|
||||
|
||||
/* Wait until transmit FIFO has space for the new character. */
|
||||
while (REG_READ(HW_UARTDBG_BASE + HW_UARTDBGFR) & HW_UARTDBGFR_TXFF);
|
||||
|
||||
REG_WRITE_BYTE(HW_UARTDBG_BASE + HW_UARTDBGDR,
|
||||
__SHIFTIN(ch, HW_UARTDBGDR_DATA));
|
||||
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
/* $Id: common.h,v 1.1 2012/11/20 19:08:46 jkunz Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2012 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Petri Laakso.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _BOOTIMX23_COMMON_
|
||||
#define _BOOTIMX23_COMMON_
|
||||
|
||||
#define REG_READ(reg) *(volatile uint32_t *)(reg)
|
||||
#define REG_WRITE(reg, val) \
|
||||
do { \
|
||||
*(volatile uint32_t *)((reg)) = val; \
|
||||
} while (0)
|
||||
#define REG_WRITE_BYTE(reg, val) \
|
||||
do { \
|
||||
*(volatile uint8_t *)((reg)) = val; \
|
||||
} while (0)
|
||||
|
||||
int clock_prep(void);
|
||||
int emi_prep(void);
|
||||
int pinctrl_prep(void);
|
||||
int power_prep(void);
|
||||
void delay_us(unsigned int);
|
||||
void putchar(int);
|
||||
|
||||
#endif /* !_BOOTIMX23_COMMON_ */
|
|
@ -0,0 +1,151 @@
|
|||
/* $Id: emi_prep.c,v 1.1 2012/11/20 19:08:46 jkunz Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2012 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Petri Laakso.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <arm/imx/imx23_emireg.h>
|
||||
|
||||
#include <lib/libsa/stand.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
void init_dram_registers(void);
|
||||
void start_dram(void);
|
||||
uint32_t get_dram_int_status(void);
|
||||
|
||||
/*
|
||||
* Initialize external DRAM memory.
|
||||
*/
|
||||
int
|
||||
emi_prep(void)
|
||||
{
|
||||
|
||||
init_dram_registers();
|
||||
start_dram();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* DRAM register values for 32Mx16 hy5du121622dtp-d43 DDR module.
|
||||
*
|
||||
* Register values were copied from Freescale's imx-bootlets-src-10.05.02
|
||||
* source code, init_ddr_mt46v32m16_133Mhz() function. Only change to those
|
||||
* settings were to HW_DRAM_CTL19_DQS_OUT_SHIFT which was set to 16 as a result
|
||||
* from trial and error.
|
||||
*/
|
||||
void
|
||||
init_dram_registers(void)
|
||||
{
|
||||
uint32_t reg;
|
||||
|
||||
REG_WRITE(HW_DRAM_BASE + HW_DRAM_CTL00, 0x01010001);
|
||||
REG_WRITE(HW_DRAM_BASE + HW_DRAM_CTL01, 0x00010100);
|
||||
REG_WRITE(HW_DRAM_BASE + HW_DRAM_CTL02, 0x01000101);
|
||||
REG_WRITE(HW_DRAM_BASE + HW_DRAM_CTL03, 0x00000001);
|
||||
REG_WRITE(HW_DRAM_BASE + HW_DRAM_CTL04, 0x00000101);
|
||||
REG_WRITE(HW_DRAM_BASE + HW_DRAM_CTL05, 0x00000000);
|
||||
REG_WRITE(HW_DRAM_BASE + HW_DRAM_CTL06, 0x00010000);
|
||||
REG_WRITE(HW_DRAM_BASE + HW_DRAM_CTL07, 0x01000001);
|
||||
// HW_DRAM_CTL08 initialized last.
|
||||
REG_WRITE(HW_DRAM_BASE + HW_DRAM_CTL09, 0x00000001);
|
||||
REG_WRITE(HW_DRAM_BASE + HW_DRAM_CTL10, 0x07000200);
|
||||
REG_WRITE(HW_DRAM_BASE + HW_DRAM_CTL11, 0x00070202);
|
||||
REG_WRITE(HW_DRAM_BASE + HW_DRAM_CTL12, 0x02020000);
|
||||
REG_WRITE(HW_DRAM_BASE + HW_DRAM_CTL13, 0x04040a01);
|
||||
REG_WRITE(HW_DRAM_BASE + HW_DRAM_CTL14, 0x00000201);
|
||||
REG_WRITE(HW_DRAM_BASE + HW_DRAM_CTL15, 0x02040000);
|
||||
REG_WRITE(HW_DRAM_BASE + HW_DRAM_CTL16, 0x02000000);
|
||||
REG_WRITE(HW_DRAM_BASE + HW_DRAM_CTL17, 0x19000f08);
|
||||
REG_WRITE(HW_DRAM_BASE + HW_DRAM_CTL18, 0x0d0d0000);
|
||||
// REG_WRITE(HW_DRAM_BASE + HW_DRAM_CTL19, 0x02021313);
|
||||
reg = __SHIFTIN(2, HW_DRAM_CTL19_DQS_OUT_SHIFT_BYPASS) |
|
||||
__SHIFTIN(16, HW_DRAM_CTL19_DQS_OUT_SHIFT) |
|
||||
__SHIFTIN(19, HW_DRAM_CTL19_DLL_DQS_DELAY_BYPASS_1) |
|
||||
__SHIFTIN(19, HW_DRAM_CTL19_DLL_DQS_DELAY_BYPASS_0);
|
||||
REG_WRITE(HW_DRAM_BASE + HW_DRAM_CTL19, reg);
|
||||
REG_WRITE(HW_DRAM_BASE + HW_DRAM_CTL20, 0x02061521);
|
||||
REG_WRITE(HW_DRAM_BASE + HW_DRAM_CTL21, 0x0000000a);
|
||||
REG_WRITE(HW_DRAM_BASE + HW_DRAM_CTL22, 0x00080008);
|
||||
REG_WRITE(HW_DRAM_BASE + HW_DRAM_CTL23, 0x00200020);
|
||||
REG_WRITE(HW_DRAM_BASE + HW_DRAM_CTL24, 0x00200020);
|
||||
REG_WRITE(HW_DRAM_BASE + HW_DRAM_CTL25, 0x00200020);
|
||||
REG_WRITE(HW_DRAM_BASE + HW_DRAM_CTL26, 0x000003f7);
|
||||
// HW_DRAM_CTL27
|
||||
// HW_DRAM_CTL28
|
||||
REG_WRITE(HW_DRAM_BASE + HW_DRAM_CTL29, 0x00000020);
|
||||
REG_WRITE(HW_DRAM_BASE + HW_DRAM_CTL30, 0x00000020);
|
||||
REG_WRITE(HW_DRAM_BASE + HW_DRAM_CTL31, 0x00c80000);
|
||||
REG_WRITE(HW_DRAM_BASE + HW_DRAM_CTL32, 0x000a23cd);
|
||||
REG_WRITE(HW_DRAM_BASE + HW_DRAM_CTL33, 0x000000c8);
|
||||
REG_WRITE(HW_DRAM_BASE + HW_DRAM_CTL34, 0x00006665);
|
||||
// HW_DRAM_CTL35 is read only register
|
||||
REG_WRITE(HW_DRAM_BASE + HW_DRAM_CTL36, 0x00000101);
|
||||
REG_WRITE(HW_DRAM_BASE + HW_DRAM_CTL37, 0x00040001);
|
||||
REG_WRITE(HW_DRAM_BASE + HW_DRAM_CTL38, 0x00000000);
|
||||
REG_WRITE(HW_DRAM_BASE + HW_DRAM_CTL39, 0x00000000);
|
||||
REG_WRITE(HW_DRAM_BASE + HW_DRAM_CTL40, 0x00010000);
|
||||
REG_WRITE(HW_DRAM_BASE + HW_DRAM_CTL08, 0x01000000);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Start DRAM module. After return DRAM is ready to use.
|
||||
*/
|
||||
void
|
||||
start_dram(void)
|
||||
{
|
||||
uint32_t reg;
|
||||
|
||||
reg = REG_READ(HW_DRAM_BASE + HW_DRAM_CTL08);
|
||||
reg |= HW_DRAM_CTL08_START;
|
||||
REG_WRITE(HW_DRAM_BASE + HW_DRAM_CTL08, reg);
|
||||
|
||||
/* Wait until DRAM initialization is complete. */
|
||||
while(!(get_dram_int_status() & (1<<2)));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return DRAM controller interrupt status register.
|
||||
*/
|
||||
uint32_t
|
||||
get_dram_int_status(void)
|
||||
{
|
||||
uint32_t reg;
|
||||
|
||||
reg = REG_READ(HW_DRAM_BASE + HW_DRAM_CTL18);
|
||||
return __SHIFTOUT(reg, HW_DRAM_CTL18_INT_STATUS);
|
||||
}
|
|
@ -0,0 +1,485 @@
|
|||
/* $Id: pinctrl_prep.c,v 1.1 2012/11/20 19:08:46 jkunz Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2012 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Petri Laakso.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <arm/imx/imx23_pinctrlreg.h>
|
||||
|
||||
#include <lib/libsa/stand.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
void configure_emi_mux(void);
|
||||
void configure_emi_drive(int);
|
||||
void disable_emi_padkeepers(void);
|
||||
void configure_ssp_mux();
|
||||
void configure_ssp_drive(int);
|
||||
void configure_ssp_pullups(void);
|
||||
|
||||
/* EMI pins output drive strengths */
|
||||
#define DRIVE_04_MA 0x0 /* 4 mA */
|
||||
#define DRIVE_08_MA 0x1 /* 8 mA */
|
||||
#define DRIVE_12_MA 0x2 /* 12 mA */
|
||||
#define DRIVE_16_MA 0x3 /* 16 mA */
|
||||
|
||||
/*
|
||||
* Configure external EMI pins.
|
||||
*/
|
||||
int
|
||||
pinctrl_prep(void)
|
||||
{
|
||||
|
||||
REG_WRITE(HW_PINCTRL_BASE + HW_PINCTRL_CTRL_CLR,
|
||||
(HW_PINCTRL_CTRL_SFTRST | HW_PINCTRL_CTRL_CLKGATE));
|
||||
|
||||
/* EMI. */
|
||||
configure_emi_mux();
|
||||
configure_emi_drive(DRIVE_12_MA);
|
||||
disable_emi_padkeepers();
|
||||
|
||||
/* SSP. */
|
||||
configure_ssp_mux();
|
||||
configure_ssp_drive(DRIVE_16_MA);
|
||||
configure_ssp_pullups();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Configure external EMI pins to be used for DRAM.
|
||||
*/
|
||||
void
|
||||
configure_emi_mux(void)
|
||||
{
|
||||
|
||||
REG_WRITE(HW_PINCTRL_BASE + HW_PINCTRL_MUXSEL4_CLR, (
|
||||
HW_PINCTRL_MUXSEL4_BANK2_PIN15 | /* Pin 108, EMI_A06 */
|
||||
HW_PINCTRL_MUXSEL4_BANK2_PIN14 | /* Pin 107, EMI_A05 */
|
||||
HW_PINCTRL_MUXSEL4_BANK2_PIN13 | /* Pin 109, EMI_A04 */
|
||||
HW_PINCTRL_MUXSEL4_BANK2_PIN12 | /* Pin 110, EMI_A03 */
|
||||
HW_PINCTRL_MUXSEL4_BANK2_PIN11 | /* Pin 111, EMI_A02 */
|
||||
HW_PINCTRL_MUXSEL4_BANK2_PIN10 | /* Pin 112, EMI_A01 */
|
||||
HW_PINCTRL_MUXSEL4_BANK2_PIN09) /* Pin 113, EMI_A00 */
|
||||
);
|
||||
|
||||
REG_WRITE(HW_PINCTRL_BASE + HW_PINCTRL_MUXSEL5_CLR, (
|
||||
HW_PINCTRL_MUXSEL5_BANK2_PIN31 | /* Pin 114, EMI_WEN */
|
||||
HW_PINCTRL_MUXSEL5_BANK2_PIN30 | /* Pin 98, EMI_RASN */
|
||||
HW_PINCTRL_MUXSEL5_BANK2_PIN29 | /* Pin 115, EMI_CKE */
|
||||
#if 0
|
||||
/* 169-Pin BGA Package */
|
||||
HW_PINCTRL_MUXSEL5_BANK2_PIN26 | /* Pin 99, EMI_CE1N */
|
||||
#endif
|
||||
HW_PINCTRL_MUXSEL5_BANK2_PIN25 | /* Pin 100, EMI_CE0N */
|
||||
HW_PINCTRL_MUXSEL5_BANK2_PIN24 | /* Pin 97, EMI_CASN */
|
||||
HW_PINCTRL_MUXSEL5_BANK2_PIN23 | /* Pin 117, EMI_BA1 */
|
||||
HW_PINCTRL_MUXSEL5_BANK2_PIN22 | /* Pin 116, EMI_BA0 */
|
||||
HW_PINCTRL_MUXSEL5_BANK2_PIN21 | /* Pin 101, EMI_A12 */
|
||||
HW_PINCTRL_MUXSEL5_BANK2_PIN20 | /* Pin 102, EMI_A11 */
|
||||
HW_PINCTRL_MUXSEL5_BANK2_PIN19 | /* Pin 104, EMI_A10 */
|
||||
HW_PINCTRL_MUXSEL5_BANK2_PIN18 | /* Pin 103, EMI_A09 */
|
||||
HW_PINCTRL_MUXSEL5_BANK2_PIN17 | /* Pin 106, EMI_A08 */
|
||||
HW_PINCTRL_MUXSEL5_BANK2_PIN16) /* Pin 105, EMI_A07 */
|
||||
);
|
||||
|
||||
REG_WRITE(HW_PINCTRL_BASE + HW_PINCTRL_MUXSEL6_CLR, (
|
||||
HW_PINCTRL_MUXSEL6_BANK3_PIN15 | /* Pin 95, EMI_D15 */
|
||||
HW_PINCTRL_MUXSEL6_BANK3_PIN14 | /* Pin 96, EMI_D14 */
|
||||
HW_PINCTRL_MUXSEL6_BANK3_PIN13 | /* Pin 94, EMI_D13 */
|
||||
HW_PINCTRL_MUXSEL6_BANK3_PIN12 | /* Pin 93, EMI_D12 */
|
||||
HW_PINCTRL_MUXSEL6_BANK3_PIN11 | /* Pin 91, EMI_D11 */
|
||||
HW_PINCTRL_MUXSEL6_BANK3_PIN10 | /* Pin 89, EMI_D10 */
|
||||
HW_PINCTRL_MUXSEL6_BANK3_PIN09 | /* Pin 87, EMI_D09 */
|
||||
HW_PINCTRL_MUXSEL6_BANK3_PIN08 | /* Pin 86, EMI_D08 */
|
||||
HW_PINCTRL_MUXSEL6_BANK3_PIN07 | /* Pin 85, EMI_D07 */
|
||||
HW_PINCTRL_MUXSEL6_BANK3_PIN06 | /* Pin 84, EMI_D06 */
|
||||
HW_PINCTRL_MUXSEL6_BANK3_PIN05 | /* Pin 83, EMI_D05 */
|
||||
HW_PINCTRL_MUXSEL6_BANK3_PIN04 | /* Pin 82, EMI_D04 */
|
||||
HW_PINCTRL_MUXSEL6_BANK3_PIN03 | /* Pin 79, EMI_D03 */
|
||||
HW_PINCTRL_MUXSEL6_BANK3_PIN02 | /* Pin 77, EMI_D02 */
|
||||
HW_PINCTRL_MUXSEL6_BANK3_PIN01 | /* Pin 76, EMI_D01 */
|
||||
HW_PINCTRL_MUXSEL6_BANK3_PIN00) /* Pin 75, EMI_D00 */
|
||||
);
|
||||
|
||||
REG_WRITE(HW_PINCTRL_BASE + HW_PINCTRL_MUXSEL7_CLR, (
|
||||
HW_PINCTRL_MUXSEL7_BANK3_PIN21 | /* Pin 72, EMI_CLKN */
|
||||
HW_PINCTRL_MUXSEL7_BANK3_PIN20 | /* Pin 70, EMI_CLK */
|
||||
HW_PINCTRL_MUXSEL7_BANK3_PIN19 | /* Pin 74, EMI_DQS1 */
|
||||
HW_PINCTRL_MUXSEL7_BANK3_PIN18 | /* Pin 73, EMI_DQS0 */
|
||||
HW_PINCTRL_MUXSEL7_BANK3_PIN17 | /* Pin 92, EMI_DQM1 */
|
||||
HW_PINCTRL_MUXSEL7_BANK3_PIN16) /* Pin 81, EMI_DQM0 */
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Configure EMI pins voltages to 1.8/2.5V operation and drive strength
|
||||
* to "ma".
|
||||
*/
|
||||
void
|
||||
configure_emi_drive(int ma)
|
||||
{
|
||||
uint32_t drive;
|
||||
|
||||
/* DRIVE 9 */
|
||||
drive = REG_READ(HW_PINCTRL_BASE + HW_PINCTRL_DRIVE9);
|
||||
drive &= ~(
|
||||
HW_PINCTRL_DRIVE9_BANK2_PIN15_V | /* Pin 108, EMI_A06 */
|
||||
HW_PINCTRL_DRIVE9_BANK2_PIN15_MA |
|
||||
HW_PINCTRL_DRIVE9_BANK2_PIN14_V | /* Pin 107, EMI_A05 */
|
||||
HW_PINCTRL_DRIVE9_BANK2_PIN14_MA |
|
||||
HW_PINCTRL_DRIVE9_BANK2_PIN13_V | /* Pin 109, EMI_A04 */
|
||||
HW_PINCTRL_DRIVE9_BANK2_PIN13_MA |
|
||||
HW_PINCTRL_DRIVE9_BANK2_PIN12_V | /* Pin 110, EMI_A03 */
|
||||
HW_PINCTRL_DRIVE9_BANK2_PIN12_MA |
|
||||
HW_PINCTRL_DRIVE9_BANK2_PIN11_V | /* Pin 111, EMI_A02 */
|
||||
HW_PINCTRL_DRIVE9_BANK2_PIN11_MA |
|
||||
HW_PINCTRL_DRIVE9_BANK2_PIN10_V | /* Pin 112, EMI_A01 */
|
||||
HW_PINCTRL_DRIVE9_BANK2_PIN10_MA |
|
||||
HW_PINCTRL_DRIVE9_BANK2_PIN09_V | /* Pin 113, EMI_A00 */
|
||||
HW_PINCTRL_DRIVE9_BANK2_PIN09_MA |
|
||||
HW_PINCTRL_DRIVE9_RSRVD6 | /* Always write zeroes */
|
||||
HW_PINCTRL_DRIVE9_RSRVD5 |
|
||||
HW_PINCTRL_DRIVE9_RSRVD4 |
|
||||
HW_PINCTRL_DRIVE9_RSRVD3 |
|
||||
HW_PINCTRL_DRIVE9_RSRVD2 |
|
||||
HW_PINCTRL_DRIVE9_RSRVD1 |
|
||||
HW_PINCTRL_DRIVE9_RSRVD0
|
||||
);
|
||||
drive |= (
|
||||
__SHIFTIN(ma, HW_PINCTRL_DRIVE9_BANK2_PIN15_MA) | /* EMI_A06 */
|
||||
__SHIFTIN(ma, HW_PINCTRL_DRIVE9_BANK2_PIN14_MA) | /* EMI_A05 */
|
||||
__SHIFTIN(ma, HW_PINCTRL_DRIVE9_BANK2_PIN13_MA) | /* EMI_A04 */
|
||||
__SHIFTIN(ma, HW_PINCTRL_DRIVE9_BANK2_PIN12_MA) | /* EMI_A03 */
|
||||
__SHIFTIN(ma, HW_PINCTRL_DRIVE9_BANK2_PIN11_MA) | /* EMI_A02 */
|
||||
__SHIFTIN(ma, HW_PINCTRL_DRIVE9_BANK2_PIN10_MA) | /* EMI_A01 */
|
||||
__SHIFTIN(ma, HW_PINCTRL_DRIVE9_BANK2_PIN09_MA) /* EMI_A00 */
|
||||
);
|
||||
REG_WRITE(HW_PINCTRL_BASE + HW_PINCTRL_DRIVE9, drive);
|
||||
|
||||
/* DRIVE 10 */
|
||||
drive = REG_READ(HW_PINCTRL_BASE + HW_PINCTRL_DRIVE10);
|
||||
drive &= ~(
|
||||
HW_PINCTRL_DRIVE10_BANK2_PIN23_V | /* Pin 117, EMI_BA1 */
|
||||
HW_PINCTRL_DRIVE10_BANK2_PIN23_MA |
|
||||
HW_PINCTRL_DRIVE10_BANK2_PIN22_V | /* Pin 116, EMI_BA0 */
|
||||
HW_PINCTRL_DRIVE10_BANK2_PIN22_MA |
|
||||
HW_PINCTRL_DRIVE10_BANK2_PIN21_V | /* Pin 101, EMI_A12 */
|
||||
HW_PINCTRL_DRIVE10_BANK2_PIN21_MA |
|
||||
HW_PINCTRL_DRIVE10_BANK2_PIN20_V | /* Pin 102, EMI_A11 */
|
||||
HW_PINCTRL_DRIVE10_BANK2_PIN20_MA |
|
||||
HW_PINCTRL_DRIVE10_BANK2_PIN19_V | /* Pin 104, EMI_A10 */
|
||||
HW_PINCTRL_DRIVE10_BANK2_PIN19_MA |
|
||||
HW_PINCTRL_DRIVE10_BANK2_PIN18_V | /* Pin 103, EMI_A09 */
|
||||
HW_PINCTRL_DRIVE10_BANK2_PIN18_MA |
|
||||
HW_PINCTRL_DRIVE10_BANK2_PIN17_V | /* Pin 106, EMI_A08 */
|
||||
HW_PINCTRL_DRIVE10_BANK2_PIN17_MA |
|
||||
HW_PINCTRL_DRIVE10_BANK2_PIN16_V | /* Pin 105, EMI_A07 */
|
||||
HW_PINCTRL_DRIVE10_BANK2_PIN16_MA |
|
||||
HW_PINCTRL_DRIVE10_RSRVD6 | /* Always write zeroes */
|
||||
HW_PINCTRL_DRIVE10_RSRVD5 |
|
||||
HW_PINCTRL_DRIVE10_RSRVD4 |
|
||||
HW_PINCTRL_DRIVE10_RSRVD3 |
|
||||
HW_PINCTRL_DRIVE10_RSRVD2 |
|
||||
HW_PINCTRL_DRIVE10_RSRVD1 |
|
||||
HW_PINCTRL_DRIVE10_RSRVD0
|
||||
);
|
||||
drive |= (
|
||||
__SHIFTIN(ma, HW_PINCTRL_DRIVE10_BANK2_PIN23_MA) | /* EMI_BA1 */
|
||||
__SHIFTIN(ma, HW_PINCTRL_DRIVE10_BANK2_PIN22_MA) | /* EMI_BA0 */
|
||||
__SHIFTIN(ma, HW_PINCTRL_DRIVE10_BANK2_PIN21_MA) | /* EMI_A12 */
|
||||
__SHIFTIN(ma, HW_PINCTRL_DRIVE10_BANK2_PIN20_MA) | /* EMI_A11 */
|
||||
__SHIFTIN(ma, HW_PINCTRL_DRIVE10_BANK2_PIN19_MA) | /* EMI_A10 */
|
||||
__SHIFTIN(ma, HW_PINCTRL_DRIVE10_BANK2_PIN18_MA) | /* EMI_A09 */
|
||||
__SHIFTIN(ma, HW_PINCTRL_DRIVE10_BANK2_PIN17_MA) | /* EMI_A08 */
|
||||
__SHIFTIN(ma, HW_PINCTRL_DRIVE10_BANK2_PIN16_MA) /* EMI_A07 */
|
||||
);
|
||||
REG_WRITE(HW_PINCTRL_BASE + HW_PINCTRL_DRIVE10, drive);
|
||||
|
||||
/* DRIVE 11 */
|
||||
drive = REG_READ(HW_PINCTRL_BASE + HW_PINCTRL_DRIVE11);
|
||||
drive &= ~(
|
||||
HW_PINCTRL_DRIVE11_BANK2_PIN31_V | /* Pin 114, EMI_WEN */
|
||||
HW_PINCTRL_DRIVE11_BANK2_PIN31_MA |
|
||||
HW_PINCTRL_DRIVE11_BANK2_PIN30_V | /* Pin 98, EMI_RASN */
|
||||
HW_PINCTRL_DRIVE11_BANK2_PIN30_MA |
|
||||
HW_PINCTRL_DRIVE11_BANK2_PIN29_V | /* Pin 115, EMI_CKE */
|
||||
HW_PINCTRL_DRIVE11_BANK2_PIN29_MA |
|
||||
#if 0
|
||||
/* 169-Pin BGA Package */
|
||||
HW_PINCTRL_DRIVE11_BANK2_PIN26_V | /* Pin 99, EMI_CE1N */
|
||||
HW_PINCTRL_DRIVE11_BANK2_PIN26_MA |
|
||||
#endif
|
||||
HW_PINCTRL_DRIVE11_BANK2_PIN25_V | /* Pin 100, EMI_CE0N */
|
||||
HW_PINCTRL_DRIVE11_BANK2_PIN25_MA |
|
||||
HW_PINCTRL_DRIVE11_BANK2_PIN24_V | /* Pin 97, EMI_CASN */
|
||||
HW_PINCTRL_DRIVE11_BANK2_PIN24_MA |
|
||||
HW_PINCTRL_DRIVE11_RSRVD6 | /* Always write zeroes */
|
||||
HW_PINCTRL_DRIVE11_RSRVD5 |
|
||||
HW_PINCTRL_DRIVE11_RSRVD4 |
|
||||
HW_PINCTRL_DRIVE11_RSRVD3 |
|
||||
HW_PINCTRL_DRIVE11_RSRVD2 |
|
||||
HW_PINCTRL_DRIVE11_RSRVD1 |
|
||||
HW_PINCTRL_DRIVE11_RSRVD0
|
||||
);
|
||||
drive |= (
|
||||
__SHIFTIN(ma, HW_PINCTRL_DRIVE11_BANK2_PIN31_MA) | /* EMI_WEN */
|
||||
__SHIFTIN(ma, HW_PINCTRL_DRIVE11_BANK2_PIN30_MA) | /* EMI_RASN */
|
||||
__SHIFTIN(ma, HW_PINCTRL_DRIVE11_BANK2_PIN29_MA) | /* EMI_CKE */
|
||||
#if 0 /* 169-Pin BGA Package */
|
||||
__SHIFTIN(ma, HW_PINCTRL_DRIVE11_BANK2_PIN26_MA) | /* EMI_CE1N */
|
||||
#endif
|
||||
__SHIFTIN(ma, HW_PINCTRL_DRIVE11_BANK2_PIN25_MA) | /* EMI_CE0N */
|
||||
__SHIFTIN(ma, HW_PINCTRL_DRIVE11_BANK2_PIN24_MA) /* EMI_CASN */
|
||||
);
|
||||
REG_WRITE(HW_PINCTRL_BASE + HW_PINCTRL_DRIVE11, drive);
|
||||
|
||||
/* DRIVE 12 */
|
||||
drive = REG_READ(HW_PINCTRL_BASE + HW_PINCTRL_DRIVE12);
|
||||
drive &= ~(
|
||||
HW_PINCTRL_DRIVE12_BANK3_PIN07_V | /* Pin 85, EMI_D07 */
|
||||
HW_PINCTRL_DRIVE12_BANK3_PIN07_MA |
|
||||
HW_PINCTRL_DRIVE12_BANK3_PIN06_V | /* Pin 84, EMI_D06 */
|
||||
HW_PINCTRL_DRIVE12_BANK3_PIN06_MA |
|
||||
HW_PINCTRL_DRIVE12_BANK3_PIN05_V | /* Pin 83, EMI_D05 */
|
||||
HW_PINCTRL_DRIVE12_BANK3_PIN05_MA |
|
||||
HW_PINCTRL_DRIVE12_BANK3_PIN04_V | /* Pin 82, EMI_D04 */
|
||||
HW_PINCTRL_DRIVE12_BANK3_PIN04_MA |
|
||||
HW_PINCTRL_DRIVE12_BANK3_PIN03_V | /* Pin 79, EMI_D03 */
|
||||
HW_PINCTRL_DRIVE12_BANK3_PIN03_MA |
|
||||
HW_PINCTRL_DRIVE12_BANK3_PIN02_V | /* Pin 77, EMI_D02 */
|
||||
HW_PINCTRL_DRIVE12_BANK3_PIN02_MA |
|
||||
HW_PINCTRL_DRIVE12_BANK3_PIN01_V | /* Pin 76, EMI_D01 */
|
||||
HW_PINCTRL_DRIVE12_BANK3_PIN01_MA |
|
||||
HW_PINCTRL_DRIVE12_BANK3_PIN00_V | /* Pin 75, EMI_D00 */
|
||||
HW_PINCTRL_DRIVE12_BANK3_PIN00_MA |
|
||||
HW_PINCTRL_DRIVE12_RSRVD6 | /* Always write zeroes */
|
||||
HW_PINCTRL_DRIVE12_RSRVD5 |
|
||||
HW_PINCTRL_DRIVE12_RSRVD4 |
|
||||
HW_PINCTRL_DRIVE12_RSRVD3 |
|
||||
HW_PINCTRL_DRIVE12_RSRVD2 |
|
||||
HW_PINCTRL_DRIVE12_RSRVD1 |
|
||||
HW_PINCTRL_DRIVE12_RSRVD0
|
||||
);
|
||||
drive |= (
|
||||
__SHIFTIN(ma, HW_PINCTRL_DRIVE12_BANK3_PIN07_MA) | /* EMI_D07 */
|
||||
__SHIFTIN(ma, HW_PINCTRL_DRIVE12_BANK3_PIN06_MA) | /* EMI_D06 */
|
||||
__SHIFTIN(ma, HW_PINCTRL_DRIVE12_BANK3_PIN05_MA) | /* EMI_D05 */
|
||||
__SHIFTIN(ma, HW_PINCTRL_DRIVE12_BANK3_PIN04_MA) | /* EMI_D04 */
|
||||
__SHIFTIN(ma, HW_PINCTRL_DRIVE12_BANK3_PIN03_MA) | /* EMI_D03 */
|
||||
__SHIFTIN(ma, HW_PINCTRL_DRIVE12_BANK3_PIN02_MA) | /* EMI_D02 */
|
||||
__SHIFTIN(ma, HW_PINCTRL_DRIVE12_BANK3_PIN01_MA) | /* EMI_D01 */
|
||||
__SHIFTIN(ma, HW_PINCTRL_DRIVE12_BANK3_PIN00_MA) /* EMI_D00 */
|
||||
);
|
||||
REG_WRITE(HW_PINCTRL_BASE + HW_PINCTRL_DRIVE12, drive);
|
||||
|
||||
/* DRIVE 13 */
|
||||
drive = REG_READ(HW_PINCTRL_BASE + HW_PINCTRL_DRIVE13);
|
||||
drive &= ~(
|
||||
HW_PINCTRL_DRIVE13_BANK3_PIN15_V | /* Pin 95, EMI_D15 */
|
||||
HW_PINCTRL_DRIVE13_BANK3_PIN15_MA |
|
||||
HW_PINCTRL_DRIVE13_BANK3_PIN14_V | /* Pin 96, EMI_D14 */
|
||||
HW_PINCTRL_DRIVE13_BANK3_PIN14_MA |
|
||||
HW_PINCTRL_DRIVE13_BANK3_PIN13_V | /* Pin 94, EMI_D13 */
|
||||
HW_PINCTRL_DRIVE13_BANK3_PIN13_MA |
|
||||
HW_PINCTRL_DRIVE13_BANK3_PIN12_V | /* Pin 93, EMI_D12 */
|
||||
HW_PINCTRL_DRIVE13_BANK3_PIN12_MA |
|
||||
HW_PINCTRL_DRIVE13_BANK3_PIN11_V | /* Pin 91, EMI_D11 */
|
||||
HW_PINCTRL_DRIVE13_BANK3_PIN11_MA |
|
||||
HW_PINCTRL_DRIVE13_BANK3_PIN10_V | /* Pin 89, EMI_D10 */
|
||||
HW_PINCTRL_DRIVE13_BANK3_PIN10_MA |
|
||||
HW_PINCTRL_DRIVE13_BANK3_PIN09_V | /* Pin 87, EMI_D09 */
|
||||
HW_PINCTRL_DRIVE13_BANK3_PIN09_MA |
|
||||
HW_PINCTRL_DRIVE13_BANK3_PIN08_V | /* Pin 86, EMI_D08 */
|
||||
HW_PINCTRL_DRIVE13_BANK3_PIN08_MA |
|
||||
HW_PINCTRL_DRIVE13_RSRVD6 | /* Always write zeroes */
|
||||
HW_PINCTRL_DRIVE13_RSRVD5 |
|
||||
HW_PINCTRL_DRIVE13_RSRVD4 |
|
||||
HW_PINCTRL_DRIVE13_RSRVD3 |
|
||||
HW_PINCTRL_DRIVE13_RSRVD2 |
|
||||
HW_PINCTRL_DRIVE13_RSRVD1 |
|
||||
HW_PINCTRL_DRIVE13_RSRVD0
|
||||
);
|
||||
drive |= (
|
||||
__SHIFTIN(ma, HW_PINCTRL_DRIVE13_BANK3_PIN15_MA) | /* EMI_D15 */
|
||||
__SHIFTIN(ma, HW_PINCTRL_DRIVE13_BANK3_PIN14_MA) | /* EMI_D14 */
|
||||
__SHIFTIN(ma, HW_PINCTRL_DRIVE13_BANK3_PIN13_MA) | /* EMI_D13 */
|
||||
__SHIFTIN(ma, HW_PINCTRL_DRIVE13_BANK3_PIN12_MA) | /* EMI_D12 */
|
||||
__SHIFTIN(ma, HW_PINCTRL_DRIVE13_BANK3_PIN11_MA) | /* EMI_D11 */
|
||||
__SHIFTIN(ma, HW_PINCTRL_DRIVE13_BANK3_PIN10_MA) | /* EMI_D10 */
|
||||
__SHIFTIN(ma, HW_PINCTRL_DRIVE13_BANK3_PIN09_MA) | /* EMI_D09 */
|
||||
__SHIFTIN(ma, HW_PINCTRL_DRIVE13_BANK3_PIN08_MA) /* EMI_D08 */
|
||||
);
|
||||
REG_WRITE(HW_PINCTRL_BASE + HW_PINCTRL_DRIVE13, drive);
|
||||
|
||||
/* DRIVE 14 */
|
||||
drive = REG_READ(HW_PINCTRL_BASE + HW_PINCTRL_DRIVE14);
|
||||
drive &= ~(
|
||||
HW_PINCTRL_DRIVE14_BANK3_PIN21_V | /* Pin 72, EMI_CLKN */
|
||||
HW_PINCTRL_DRIVE14_BANK3_PIN21_MA |
|
||||
HW_PINCTRL_DRIVE14_BANK3_PIN20_V | /* Pin 70, EMI_CLK */
|
||||
HW_PINCTRL_DRIVE14_BANK3_PIN20_MA |
|
||||
HW_PINCTRL_DRIVE14_BANK3_PIN19_V | /* Pin 74, EMI_DQS1 */
|
||||
HW_PINCTRL_DRIVE14_BANK3_PIN19_MA |
|
||||
HW_PINCTRL_DRIVE14_BANK3_PIN18_V | /* Pin 73, EMI_DQS0 */
|
||||
HW_PINCTRL_DRIVE14_BANK3_PIN18_MA |
|
||||
HW_PINCTRL_DRIVE14_BANK3_PIN17_V | /* Pin 92, EMI_DQM1 */
|
||||
HW_PINCTRL_DRIVE14_BANK3_PIN17_MA |
|
||||
HW_PINCTRL_DRIVE14_BANK3_PIN16_V | /* Pin 81, EMI_DQM0 */
|
||||
HW_PINCTRL_DRIVE14_BANK3_PIN16_MA |
|
||||
HW_PINCTRL_DRIVE14_RSRVD6 | /* Always write zeroes */
|
||||
HW_PINCTRL_DRIVE14_RSRVD5 |
|
||||
HW_PINCTRL_DRIVE14_RSRVD4 |
|
||||
HW_PINCTRL_DRIVE14_RSRVD3 |
|
||||
HW_PINCTRL_DRIVE14_RSRVD2 |
|
||||
HW_PINCTRL_DRIVE14_RSRVD1 |
|
||||
HW_PINCTRL_DRIVE14_RSRVD0
|
||||
);
|
||||
drive |= (
|
||||
__SHIFTIN(ma, HW_PINCTRL_DRIVE14_BANK3_PIN21_MA) | /* EMI_CLKN */
|
||||
__SHIFTIN(ma, HW_PINCTRL_DRIVE14_BANK3_PIN20_MA) | /* EMI_CLK */
|
||||
__SHIFTIN(ma, HW_PINCTRL_DRIVE14_BANK3_PIN19_MA) | /* EMI_DQS1 */
|
||||
__SHIFTIN(ma, HW_PINCTRL_DRIVE14_BANK3_PIN18_MA) | /* EMI_DQS0 */
|
||||
__SHIFTIN(ma, HW_PINCTRL_DRIVE14_BANK3_PIN17_MA) | /* EMI_DQM1 */
|
||||
__SHIFTIN(ma, HW_PINCTRL_DRIVE14_BANK3_PIN16_MA) /* EMI_DQM0 */
|
||||
);
|
||||
REG_WRITE(HW_PINCTRL_BASE + HW_PINCTRL_DRIVE14, drive);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Disable internal gate keepers on EMI pins.
|
||||
*/
|
||||
void
|
||||
disable_emi_padkeepers(void)
|
||||
{
|
||||
|
||||
REG_WRITE(HW_PINCTRL_BASE + HW_PINCTRL_PULL3_SET, (
|
||||
HW_PINCTRL_PULL3_BANK3_PIN17 | /* EMI_DQM1 */
|
||||
HW_PINCTRL_PULL3_BANK3_PIN16 | /* EMI_DQM0 */
|
||||
HW_PINCTRL_PULL3_BANK3_PIN15 | /* EMI_D15 */
|
||||
HW_PINCTRL_PULL3_BANK3_PIN14 | /* EMI_D14 */
|
||||
HW_PINCTRL_PULL3_BANK3_PIN13 | /* EMI_D13 */
|
||||
HW_PINCTRL_PULL3_BANK3_PIN12 | /* EMI_D12 */
|
||||
HW_PINCTRL_PULL3_BANK3_PIN11 | /* EMI_D11 */
|
||||
HW_PINCTRL_PULL3_BANK3_PIN10 | /* EMI_D10 */
|
||||
HW_PINCTRL_PULL3_BANK3_PIN09 | /* EMI_D09 */
|
||||
HW_PINCTRL_PULL3_BANK3_PIN08 | /* EMI_D08 */
|
||||
HW_PINCTRL_PULL3_BANK3_PIN07 | /* EMI_D07 */
|
||||
HW_PINCTRL_PULL3_BANK3_PIN06 | /* EMI_D06 */
|
||||
HW_PINCTRL_PULL3_BANK3_PIN05 | /* EMI_D05 */
|
||||
HW_PINCTRL_PULL3_BANK3_PIN04 | /* EMI_D04 */
|
||||
HW_PINCTRL_PULL3_BANK3_PIN03 | /* EMI_D03 */
|
||||
HW_PINCTRL_PULL3_BANK3_PIN02 | /* EMI_D02 */
|
||||
HW_PINCTRL_PULL3_BANK3_PIN01 | /* EMI_D01 */
|
||||
HW_PINCTRL_PULL3_BANK3_PIN00) /* EMI_D00 */
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Configure external SSP pins to be used for SD/MMC.
|
||||
*/
|
||||
void
|
||||
configure_ssp_mux(void)
|
||||
{
|
||||
REG_WRITE(HW_PINCTRL_BASE + HW_PINCTRL_MUXSEL4_CLR, (
|
||||
HW_PINCTRL_MUXSEL4_BANK2_PIN00 | /* Pin 121, SSP1_CMD */
|
||||
HW_PINCTRL_MUXSEL4_BANK2_PIN02 | /* Pin 122, SSP1_DATA0 */
|
||||
HW_PINCTRL_MUXSEL4_BANK2_PIN03 | /* Pin 123, SSP1_DATA1 */
|
||||
HW_PINCTRL_MUXSEL4_BANK2_PIN04 | /* Pin 124, SSP1_DATA2 */
|
||||
HW_PINCTRL_MUXSEL4_BANK2_PIN05 | /* Pin 125, SSP1_DATA3 */
|
||||
HW_PINCTRL_MUXSEL4_BANK2_PIN06) /* Pin 127, SSP1_SCK */
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Configure SSP pins drive strength to "ma".
|
||||
* Out of reset, all non-EMI pins are configured as 3.3 V.
|
||||
*/
|
||||
void
|
||||
configure_ssp_drive(int ma)
|
||||
{
|
||||
uint32_t reg = REG_READ(HW_PINCTRL_BASE + HW_PINCTRL_DRIVE8);
|
||||
reg &= ~(
|
||||
HW_PINCTRL_DRIVE8_BANK2_PIN06_MA | /* Pin 127, SSP1_SCK */
|
||||
HW_PINCTRL_DRIVE8_BANK2_PIN05_MA | /* Pin 125, SSP1_DATA3 */
|
||||
HW_PINCTRL_DRIVE8_BANK2_PIN04_MA | /* Pin 124, SSP1_DATA2 */
|
||||
HW_PINCTRL_DRIVE8_BANK2_PIN03_MA | /* Pin 123, SSP1_DATA1 */
|
||||
HW_PINCTRL_DRIVE8_BANK2_PIN02_MA | /* Pin 122, SSP1_DATA0 */
|
||||
HW_PINCTRL_DRIVE8_BANK2_PIN00_MA /* Pin 121, SSP1_CMD */
|
||||
);
|
||||
|
||||
reg |= __SHIFTIN(ma, HW_PINCTRL_DRIVE8_BANK2_PIN06_MA) |
|
||||
__SHIFTIN(ma, HW_PINCTRL_DRIVE8_BANK2_PIN05_MA) |
|
||||
__SHIFTIN(ma, HW_PINCTRL_DRIVE8_BANK2_PIN04_MA) |
|
||||
__SHIFTIN(ma, HW_PINCTRL_DRIVE8_BANK2_PIN03_MA) |
|
||||
__SHIFTIN(ma, HW_PINCTRL_DRIVE8_BANK2_PIN02_MA) |
|
||||
__SHIFTIN(ma, HW_PINCTRL_DRIVE8_BANK2_PIN00_MA
|
||||
);
|
||||
|
||||
REG_WRITE(HW_PINCTRL_BASE + HW_PINCTRL_DRIVE8, reg);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Configure SSP pull ups.
|
||||
*/
|
||||
void
|
||||
configure_ssp_pullups(void)
|
||||
{
|
||||
/* Disable pull ups for SSP and let HW take care of them. */
|
||||
// REG_WRITE(HW_PINCTRL_BASE + HW_PINCTRL_PULL2_CLR, (
|
||||
// HW_PINCTRL_PULL2_BANK2_PIN05 |/* Pin 125, SSP1_DATA3 */
|
||||
// HW_PINCTRL_PULL2_BANK2_PIN04 | /* Pin 124, SSP1_DATA2 */
|
||||
// HW_PINCTRL_PULL2_BANK2_PIN03 | /* Pin 123, SSP1_DATA1 */
|
||||
// HW_PINCTRL_PULL2_BANK2_PIN02 | /* Pin 122, SSP1_DATA0 */
|
||||
// HW_PINCTRL_PULL2_BANK2_PIN00 /* Pin 121, SSP1_CMD */
|
||||
// ));
|
||||
|
||||
REG_WRITE(HW_PINCTRL_BASE + HW_PINCTRL_PULL2_SET, (
|
||||
HW_PINCTRL_PULL2_BANK2_PIN05 |/* Pin 125, SSP1_DATA3 */
|
||||
HW_PINCTRL_PULL2_BANK2_PIN04 | /* Pin 124, SSP1_DATA2 */
|
||||
HW_PINCTRL_PULL2_BANK2_PIN03 | /* Pin 123, SSP1_DATA1 */
|
||||
HW_PINCTRL_PULL2_BANK2_PIN02 | /* Pin 122, SSP1_DATA0 */
|
||||
HW_PINCTRL_PULL2_BANK2_PIN00 /* Pin 121, SSP1_CMD */
|
||||
));
|
||||
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,579 @@
|
|||
/* $Id: power_prep.c,v 1.1 2012/11/20 19:08:46 jkunz Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2012 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Petri Laakso.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <arm/imx/imx23_powerreg.h>
|
||||
|
||||
#include <lib/libsa/stand.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
void charge_4p2_capacitance(void);
|
||||
void enable_4p2_linreg(void);
|
||||
void enable_dcdc(void);
|
||||
void enable_vbusvalid_comparator(void);
|
||||
void set_targets(void);
|
||||
void dcdc4p2_enable_dcdc(void);
|
||||
void p5vctrl_enable_dcdc(void);
|
||||
void enable_vddmem(void);
|
||||
|
||||
/*
|
||||
* Power rail voltage targets, brownout levels and linear regulator
|
||||
* offsets from the target.
|
||||
*
|
||||
* Supply Target BO LinReg offset
|
||||
* ------------------------------------------
|
||||
* VDDD 1.550 V 1.450 V -25 mV
|
||||
* VDDA 1.750 V 1.575 V -25 mV
|
||||
* VDDIO 3.100 V 2.925 V -25 mV
|
||||
* VDDMEM 2.500 V <na> <na>
|
||||
*
|
||||
* BO = Brownout level below target.
|
||||
*/
|
||||
#define VDDD_TARGET 0x1e
|
||||
#define VDDD_BO_OFFSET 0x4
|
||||
#define VDDD_LINREG_OFFSET 0x02
|
||||
|
||||
#define VDDA_TARGET 0x0A
|
||||
#define VDDA_BO_OFFSET 0x07
|
||||
#define VDDA_LINREG_OFFSET 0x02
|
||||
|
||||
#define VDDIO_TARGET 0x0C
|
||||
#define VDDIO_BO_OFFSET 0x07
|
||||
#define VDDIO_LINREG_OFFSET 0x02
|
||||
|
||||
#define VDDMEM_TARGET 0x10
|
||||
|
||||
/*
|
||||
* Threshold voltage for the VBUSVALID comparator.
|
||||
* Always make sure that the VDD5V voltage level is higher.
|
||||
*/
|
||||
#define VBUSVALID_TRSH 0x02 /* 4.1 V */
|
||||
|
||||
/* Limits for BATT charger + 4P2 current */
|
||||
#define P4P2_ILIMIT_MIN 0x01 /* 10 mA */
|
||||
#define P4P2_ILIMIT_MAX 0x3f /* 780 mA */
|
||||
|
||||
/*
|
||||
* Trip point for the comparison between the DCDC_4P2 and BATTERY pin.
|
||||
* If this voltage comparation is true then 5 V originated power will supply
|
||||
* the DCDC. Otherwise battery will be used.
|
||||
*/
|
||||
#define DCDC4P2_CMPTRIP 0x00 /* DCDC_4P2 pin > 0.85 * BATTERY pin */
|
||||
|
||||
/*
|
||||
* Adjust the behavior of the DCDC and 4.2 V circuit.
|
||||
* Two MSBs control the VDD4P2 brownout below the DCDC4P2_TRG before the
|
||||
* regulation circuit steals battery charge. Two LSBs control which power
|
||||
* source is selected by the DCDC.
|
||||
*/
|
||||
#define DCDC4P2_DROPOUT_CTRL_BO_200 0x0C
|
||||
#define DCDC4P2_DROPOUT_CTRL_BO_100 0x08
|
||||
#define DCDC4P2_DROPOUT_CTRL_BO_050 0x04
|
||||
#define DCDC4P2_DROPOUT_CTRL_BO_025 0x00
|
||||
|
||||
#define DCDC4P2_DROPOUT_CTRL_SEL_4P2 0x00 /* Don't use battery at all. */
|
||||
#define DCDC4P2_DROPOUT_CTRL_SEL_BATT_IF_GT_4P2 0x01 /* BATT if 4P2 < BATT */
|
||||
#define DCDC4P2_DROPOUT_CTRL_SEL_HIGHER 0x02 /* Selects which ever is
|
||||
* higher. */
|
||||
|
||||
#define DCDC4P2_DROPOUT_CTRL (DCDC4P2_DROPOUT_CTRL_BO_200 |\
|
||||
DCDC4P2_DROPOUT_CTRL_SEL_4P2)
|
||||
|
||||
/*
|
||||
* Prepare system for a 5 V operation.
|
||||
*
|
||||
* The system uses inefficient linear regulators as a power source after boot.
|
||||
* This code enables the use of more energy efficient DC-DC converter as a
|
||||
* power source.
|
||||
*/
|
||||
int
|
||||
power_prep(void)
|
||||
{
|
||||
|
||||
/* Enable clocks to the power block */
|
||||
REG_WRITE(HW_POWER_BASE + HW_POWER_CTRL_CLR, HW_POWER_CTRL_CLKGATE);
|
||||
|
||||
set_targets();
|
||||
enable_vbusvalid_comparator();
|
||||
enable_4p2_linreg();
|
||||
charge_4p2_capacitance();
|
||||
enable_dcdc();
|
||||
enable_vddmem();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set switching converter voltage targets, brownout levels and linear
|
||||
* regulator output offsets.
|
||||
*/
|
||||
void
|
||||
set_targets(void)
|
||||
{
|
||||
uint32_t vddctrl;
|
||||
|
||||
/* VDDD */
|
||||
vddctrl = REG_READ(HW_POWER_BASE + HW_POWER_VDDDCTRL);
|
||||
|
||||
vddctrl &= ~(HW_POWER_VDDDCTRL_LINREG_OFFSET |
|
||||
HW_POWER_VDDDCTRL_BO_OFFSET |
|
||||
HW_POWER_VDDDCTRL_TRG);
|
||||
vddctrl |=
|
||||
__SHIFTIN(VDDD_LINREG_OFFSET, HW_POWER_VDDDCTRL_LINREG_OFFSET) |
|
||||
__SHIFTIN(VDDD_BO_OFFSET, HW_POWER_VDDDCTRL_BO_OFFSET) |
|
||||
__SHIFTIN(VDDD_TARGET, HW_POWER_VDDDCTRL_TRG);
|
||||
|
||||
REG_WRITE(HW_POWER_BASE + HW_POWER_VDDDCTRL, vddctrl);
|
||||
|
||||
/* VDDA */
|
||||
vddctrl = REG_READ(HW_POWER_BASE + HW_POWER_VDDACTRL);
|
||||
|
||||
vddctrl &= ~(HW_POWER_VDDACTRL_LINREG_OFFSET |
|
||||
HW_POWER_VDDACTRL_BO_OFFSET |
|
||||
HW_POWER_VDDACTRL_TRG);
|
||||
vddctrl |=
|
||||
__SHIFTIN(VDDA_LINREG_OFFSET, HW_POWER_VDDACTRL_LINREG_OFFSET) |
|
||||
__SHIFTIN(VDDA_BO_OFFSET, HW_POWER_VDDACTRL_BO_OFFSET) |
|
||||
__SHIFTIN(VDDA_TARGET, HW_POWER_VDDACTRL_TRG);
|
||||
|
||||
REG_WRITE(HW_POWER_BASE + HW_POWER_VDDACTRL, vddctrl);
|
||||
|
||||
/* VDDIO */
|
||||
vddctrl = REG_READ(HW_POWER_BASE + HW_POWER_VDDIOCTRL);
|
||||
|
||||
vddctrl &= ~(HW_POWER_VDDIOCTRL_LINREG_OFFSET |
|
||||
HW_POWER_VDDIOCTRL_BO_OFFSET |
|
||||
HW_POWER_VDDIOCTRL_TRG);
|
||||
vddctrl |=
|
||||
__SHIFTIN(VDDIO_LINREG_OFFSET, HW_POWER_VDDACTRL_LINREG_OFFSET) |
|
||||
__SHIFTIN(VDDIO_BO_OFFSET, HW_POWER_VDDACTRL_BO_OFFSET) |
|
||||
__SHIFTIN(VDDIO_TARGET, HW_POWER_VDDACTRL_TRG);
|
||||
|
||||
REG_WRITE(HW_POWER_BASE + HW_POWER_VDDIOCTRL, vddctrl);
|
||||
|
||||
/* VDDMEM */
|
||||
vddctrl = REG_READ(HW_POWER_BASE + HW_POWER_VDDMEMCTRL);
|
||||
vddctrl &= ~(HW_POWER_VDDMEMCTRL_TRG);
|
||||
vddctrl |= __SHIFTIN(VDDMEM_TARGET, HW_POWER_VDDMEMCTRL_TRG);
|
||||
|
||||
REG_WRITE(HW_POWER_BASE + HW_POWER_VDDMEMCTRL, vddctrl);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* VBUSVALID comparator is accurate method to determine the presence of 5 V.
|
||||
* Turn on the comparator, set its voltage treshold and instruct DC-DC to
|
||||
* use it.
|
||||
*/
|
||||
void
|
||||
enable_vbusvalid_comparator()
|
||||
{
|
||||
uint32_t p5vctrl;
|
||||
|
||||
/*
|
||||
* Disable 5 V brownout detection temporarily because setting
|
||||
* VBUSVALID_5VDETECT can cause false brownout.
|
||||
*/
|
||||
REG_WRITE(HW_POWER_BASE + HW_POWER_5VCTRL_CLR,
|
||||
HW_POWER_5VCTRL_PWDN_5VBRNOUT);
|
||||
|
||||
p5vctrl = REG_READ(HW_POWER_BASE + HW_POWER_5VCTRL);
|
||||
|
||||
p5vctrl &= ~HW_POWER_5VCTRL_VBUSVALID_TRSH;
|
||||
p5vctrl |=
|
||||
/* Turn on VBUS comparators. */
|
||||
(HW_POWER_5VCTRL_PWRUP_VBUS_CMPS |
|
||||
/* Set treshold for VBUSVALID comparator. */
|
||||
__SHIFTIN(VBUSVALID_TRSH, HW_POWER_5VCTRL_VBUSVALID_TRSH) |
|
||||
/* Set DC-DC to use VBUSVALID comparator. */
|
||||
HW_POWER_5VCTRL_VBUSVALID_5VDETECT);
|
||||
|
||||
REG_WRITE(HW_POWER_BASE + HW_POWER_5VCTRL, p5vctrl);
|
||||
|
||||
/* Enable temporarily disabled 5 V brownout detection. */
|
||||
REG_WRITE(HW_POWER_BASE + HW_POWER_5VCTRL_SET,
|
||||
HW_POWER_5VCTRL_PWDN_5VBRNOUT);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable 4P2 linear regulator.
|
||||
*/
|
||||
void
|
||||
enable_4p2_linreg(void)
|
||||
{
|
||||
uint32_t dcdc4p2;
|
||||
uint32_t p5vctrl;
|
||||
|
||||
dcdc4p2 = REG_READ(HW_POWER_BASE + HW_POWER_DCDC4P2);
|
||||
/* Set the 4P2 target to 4.2 V and BO to 3.6V by clearing TRG and BO
|
||||
* field. */
|
||||
dcdc4p2 &= ~(HW_POWER_DCDC4P2_TRG | HW_POWER_DCDC4P2_BO);
|
||||
/* Enable the 4P2 circuitry to control the LinReg. */
|
||||
dcdc4p2 |= HW_POWER_DCDC4P2_ENABLE_4P2;
|
||||
REG_WRITE(HW_POWER_BASE + HW_POWER_DCDC4P2, dcdc4p2);
|
||||
|
||||
/* The 4P2 LinReg needs a static load to operate correctly. Since the
|
||||
* DC-DC is not yet loading the LinReg, another load must be used. */
|
||||
REG_WRITE(HW_POWER_BASE + HW_POWER_CHARGE_SET,
|
||||
HW_POWER_CHARGE_ENABLE_LOAD);
|
||||
|
||||
p5vctrl = REG_READ(HW_POWER_BASE + HW_POWER_5VCTRL);
|
||||
p5vctrl &= ~(HW_POWER_5VCTRL_CHARGE_4P2_ILIMIT |
|
||||
/* Power on the 4P2 LinReg. ON = 0x0, OFF = 0x1 */
|
||||
HW_POWER_5VCTRL_PWD_CHARGE_4P2);
|
||||
p5vctrl |=
|
||||
/* Provide an initial current limit for the 4P2 LinReg with the
|
||||
* smallest value possible. */
|
||||
__SHIFTIN(P4P2_ILIMIT_MIN, HW_POWER_5VCTRL_CHARGE_4P2_ILIMIT);
|
||||
REG_WRITE(HW_POWER_BASE + HW_POWER_5VCTRL, p5vctrl);
|
||||
|
||||
/* Ungate the path from 4P2 LinReg to DC-DC. */
|
||||
dcdc4p2_enable_dcdc();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* There is capacitor on the 4P2 output which must be charged before powering
|
||||
* on the 4P2 linear regulator to avoid brownouts on the 5 V source.
|
||||
* Charging is done by slowly increasing current limit until it reaches
|
||||
* P4P2_ILIMIT_MAX.
|
||||
*/
|
||||
void
|
||||
charge_4p2_capacitance(void)
|
||||
{
|
||||
uint32_t ilimit;
|
||||
uint32_t p5vctrl;
|
||||
|
||||
p5vctrl = REG_READ(HW_POWER_BASE + HW_POWER_5VCTRL);
|
||||
ilimit = __SHIFTOUT(p5vctrl, HW_POWER_5VCTRL_CHARGE_4P2_ILIMIT);
|
||||
|
||||
/* Increment current limit slowly. */
|
||||
while (ilimit < P4P2_ILIMIT_MAX) {
|
||||
ilimit++;
|
||||
p5vctrl &= ~(HW_POWER_5VCTRL_CHARGE_4P2_ILIMIT);
|
||||
p5vctrl |= __SHIFTIN(ilimit, HW_POWER_5VCTRL_CHARGE_4P2_ILIMIT);
|
||||
REG_WRITE(HW_POWER_BASE + HW_POWER_5VCTRL, p5vctrl);
|
||||
delay_us(10000);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable DCDC to use 4P2 regulator and set its power source selection logic.
|
||||
*/
|
||||
void
|
||||
enable_dcdc(void)
|
||||
{
|
||||
uint32_t dcdc4p2;
|
||||
uint32_t vddctrl;
|
||||
|
||||
dcdc4p2 = REG_READ(HW_POWER_BASE + HW_POWER_DCDC4P2);
|
||||
dcdc4p2 &= ~(HW_POWER_DCDC4P2_CMPTRIP | HW_POWER_DCDC4P2_DROPOUT_CTRL);
|
||||
/* Comparison between the DCDC_4P2 pin and BATTERY pin to choose which
|
||||
* will supply the DCDC. */
|
||||
dcdc4p2 |= __SHIFTIN(DCDC4P2_CMPTRIP, HW_POWER_DCDC4P2_CMPTRIP);
|
||||
/* DC-DC brownout and select logic. */
|
||||
dcdc4p2 |= __SHIFTIN(DCDC4P2_DROPOUT_CTRL,
|
||||
HW_POWER_DCDC4P2_DROPOUT_CTRL);
|
||||
REG_WRITE(HW_POWER_BASE + HW_POWER_DCDC4P2, dcdc4p2);
|
||||
|
||||
/* Disable the automatic DC-DC startup when 5 V is lost (it is on
|
||||
* already) */
|
||||
REG_WRITE(HW_POWER_BASE + HW_POWER_5VCTRL_CLR,
|
||||
HW_POWER_5VCTRL_DCDC_XFER);
|
||||
|
||||
p5vctrl_enable_dcdc();
|
||||
|
||||
/* Enable switching converter outputs and disable linear regulators
|
||||
* for VDDD, VDDIO and VDDA. */
|
||||
vddctrl = REG_READ(HW_POWER_BASE + HW_POWER_VDDDCTRL);
|
||||
vddctrl &= ~(HW_POWER_VDDDCTRL_DISABLE_FET |
|
||||
HW_POWER_VDDDCTRL_ENABLE_LINREG);
|
||||
REG_WRITE(HW_POWER_BASE + HW_POWER_VDDDCTRL, vddctrl);
|
||||
|
||||
vddctrl = REG_READ(HW_POWER_BASE + HW_POWER_VDDIOCTRL);
|
||||
vddctrl &= ~HW_POWER_VDDIOCTRL_DISABLE_FET;
|
||||
REG_WRITE(HW_POWER_BASE + HW_POWER_VDDIOCTRL, vddctrl);
|
||||
|
||||
vddctrl = REG_READ(HW_POWER_BASE + HW_POWER_VDDACTRL);
|
||||
vddctrl &= ~(HW_POWER_VDDACTRL_DISABLE_FET |
|
||||
HW_POWER_VDDACTRL_ENABLE_LINREG);
|
||||
REG_WRITE(HW_POWER_BASE + HW_POWER_VDDACTRL, vddctrl);
|
||||
|
||||
/* The 4P2 LinReg needs a static load to operate correctly. Since the
|
||||
* DC-DC is already running we can remove extra 100 ohm load enabled
|
||||
* before. */
|
||||
REG_WRITE(HW_POWER_BASE + HW_POWER_CHARGE_CLR,
|
||||
HW_POWER_CHARGE_ENABLE_LOAD);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* DCDC4P2 DCDC enable sequence according to errata #5837
|
||||
*/
|
||||
void
|
||||
dcdc4p2_enable_dcdc(void)
|
||||
{
|
||||
uint32_t dcdc4p2;
|
||||
uint32_t p5vctrl;
|
||||
uint32_t p5vctrl_saved;
|
||||
uint32_t pctrl;
|
||||
uint32_t pctrl_saved;
|
||||
|
||||
pctrl_saved = REG_READ(HW_POWER_BASE + HW_POWER_CTRL);
|
||||
p5vctrl_saved = REG_READ(HW_POWER_BASE + HW_POWER_5VCTRL);
|
||||
|
||||
/* Disable the power rail brownout interrupts. */
|
||||
REG_WRITE(HW_POWER_BASE + HW_POWER_CTRL_CLR,
|
||||
(HW_POWER_CTRL_ENIRQ_VDDA_BO |
|
||||
HW_POWER_CTRL_ENIRQ_VDDD_BO |
|
||||
HW_POWER_CTRL_ENIRQ_VDDIO_BO));
|
||||
|
||||
/* Set the HW_POWER_5VCTRL PWRUP_VBUS_CMPS bit (may already be set) */
|
||||
REG_WRITE(HW_POWER_BASE + HW_POWER_5VCTRL_SET,
|
||||
HW_POWER_5VCTRL_PWRUP_VBUS_CMPS);
|
||||
|
||||
/* Set the HW_POWER_5VCTRL VBUSVALID_5VDETECT bit to 0 */
|
||||
REG_WRITE(HW_POWER_BASE + HW_POWER_5VCTRL_CLR,
|
||||
HW_POWER_5VCTRL_VBUSVALID_5VDETECT);
|
||||
|
||||
/* Set the HW_POWER_5VCTRL VBUSVALID_TRSH to 0x0 (2.9 V) */
|
||||
REG_WRITE(HW_POWER_BASE + HW_POWER_5VCTRL_CLR,
|
||||
HW_POWER_5VCTRL_VBUSVALID_TRSH);
|
||||
|
||||
/* Disable VBUSDROOP status and interrupt. */
|
||||
REG_WRITE(HW_POWER_BASE + HW_POWER_CTRL_CLR,
|
||||
(HW_POWER_CTRL_VDD5V_DROOP_IRQ | HW_POWER_CTRL_ENIRQ_VDD5V_DROOP));
|
||||
|
||||
/* Set the ENABLE_DCDC bit in HW_POWER_DCDC4P2. */
|
||||
dcdc4p2 = REG_READ(HW_POWER_BASE + HW_POWER_DCDC4P2);
|
||||
dcdc4p2 |= HW_POWER_DCDC4P2_ENABLE_DCDC;
|
||||
REG_WRITE(HW_POWER_BASE + HW_POWER_DCDC4P2, dcdc4p2);
|
||||
|
||||
delay_us(100);
|
||||
|
||||
pctrl = REG_READ(HW_POWER_BASE + HW_POWER_CTRL);
|
||||
/* VBUSVALID_IRQ is set. */
|
||||
if (__SHIFTOUT(pctrl, HW_POWER_CTRL_VBUSVALID_IRQ)) {
|
||||
/* Set and clear the PWD_CHARGE_4P2 bit to repower on the 4P2
|
||||
* regulator because it is automatically shut off on a
|
||||
* VBUSVALID false condition. */
|
||||
REG_WRITE(HW_POWER_BASE + HW_POWER_5VCTRL_SET,
|
||||
HW_POWER_5VCTRL_PWD_CHARGE_4P2);
|
||||
REG_WRITE(HW_POWER_BASE + HW_POWER_5VCTRL_CLR,
|
||||
HW_POWER_5VCTRL_PWD_CHARGE_4P2);
|
||||
/* Ramp up the CHARGE_4P2_ILIMIT value at this point. */
|
||||
charge_4p2_capacitance();
|
||||
}
|
||||
|
||||
/* Restore modified bits back to HW_POWER_CTRL. */
|
||||
if (pctrl_saved & HW_POWER_CTRL_ENIRQ_VDDA_BO)
|
||||
REG_WRITE(HW_POWER_BASE + HW_POWER_CTRL_SET,
|
||||
HW_POWER_CTRL_ENIRQ_VDDA_BO);
|
||||
else
|
||||
REG_WRITE(HW_POWER_BASE + HW_POWER_CTRL_CLR,
|
||||
HW_POWER_CTRL_ENIRQ_VDDA_BO);
|
||||
|
||||
if (pctrl_saved & HW_POWER_CTRL_ENIRQ_VDDD_BO)
|
||||
REG_WRITE(HW_POWER_BASE + HW_POWER_CTRL_SET,
|
||||
HW_POWER_CTRL_ENIRQ_VDDD_BO);
|
||||
else
|
||||
REG_WRITE(HW_POWER_BASE + HW_POWER_CTRL_CLR,
|
||||
HW_POWER_CTRL_ENIRQ_VDDD_BO);
|
||||
|
||||
if (pctrl_saved & HW_POWER_CTRL_ENIRQ_VDDIO_BO)
|
||||
REG_WRITE(HW_POWER_BASE + HW_POWER_CTRL_SET,
|
||||
HW_POWER_CTRL_ENIRQ_VDDIO_BO);
|
||||
else
|
||||
REG_WRITE(HW_POWER_BASE + HW_POWER_CTRL_CLR,
|
||||
HW_POWER_CTRL_ENIRQ_VDDIO_BO);
|
||||
|
||||
if (pctrl_saved & HW_POWER_CTRL_VDD5V_DROOP_IRQ)
|
||||
REG_WRITE(HW_POWER_BASE + HW_POWER_CTRL_SET,
|
||||
HW_POWER_CTRL_VDD5V_DROOP_IRQ);
|
||||
else
|
||||
REG_WRITE(HW_POWER_BASE + HW_POWER_CTRL_CLR,
|
||||
HW_POWER_CTRL_VDD5V_DROOP_IRQ);
|
||||
|
||||
if (pctrl_saved & HW_POWER_CTRL_ENIRQ_VDD5V_DROOP)
|
||||
REG_WRITE(HW_POWER_BASE + HW_POWER_CTRL_SET,
|
||||
HW_POWER_CTRL_ENIRQ_VDD5V_DROOP);
|
||||
else
|
||||
REG_WRITE(HW_POWER_BASE + HW_POWER_CTRL_CLR,
|
||||
HW_POWER_CTRL_ENIRQ_VDD5V_DROOP);
|
||||
|
||||
/* Restore modified bits back to HW_POWER_5VCTRL. */
|
||||
p5vctrl = REG_READ(HW_POWER_BASE + HW_POWER_5VCTRL);
|
||||
p5vctrl &= ~(HW_POWER_5VCTRL_PWRUP_VBUS_CMPS |
|
||||
HW_POWER_5VCTRL_VBUSVALID_5VDETECT |
|
||||
HW_POWER_5VCTRL_VBUSVALID_TRSH);
|
||||
p5vctrl |= __SHIFTOUT(p5vctrl_saved, HW_POWER_5VCTRL_VBUSVALID_TRSH) |
|
||||
(p5vctrl_saved & HW_POWER_5VCTRL_PWRUP_VBUS_CMPS) |
|
||||
(p5vctrl_saved & HW_POWER_5VCTRL_VBUSVALID_5VDETECT);
|
||||
REG_WRITE(HW_POWER_BASE + HW_POWER_5VCTRL, p5vctrl);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* 5VCTRL DCDC enable sequence according to errata #5837
|
||||
*/
|
||||
void
|
||||
p5vctrl_enable_dcdc(void)
|
||||
{
|
||||
uint32_t p5vctrl;
|
||||
uint32_t p5vctrl_saved;
|
||||
uint32_t pctrl;
|
||||
uint32_t pctrl_saved;
|
||||
|
||||
pctrl_saved = REG_READ(HW_POWER_BASE + HW_POWER_CTRL);
|
||||
p5vctrl_saved = REG_READ(HW_POWER_BASE + HW_POWER_5VCTRL);
|
||||
|
||||
/* Disable the power rail brownout interrupts. */
|
||||
REG_WRITE(HW_POWER_BASE + HW_POWER_CTRL_CLR,
|
||||
HW_POWER_CTRL_ENIRQ_VDDA_BO |
|
||||
HW_POWER_CTRL_ENIRQ_VDDD_BO |
|
||||
HW_POWER_CTRL_ENIRQ_VDDIO_BO);
|
||||
|
||||
/* Set the HW_POWER_5VCTRL PWRUP_VBUS_CMPS bit (may already be set) */
|
||||
REG_WRITE(HW_POWER_BASE + HW_POWER_5VCTRL_SET,
|
||||
HW_POWER_5VCTRL_PWRUP_VBUS_CMPS);
|
||||
|
||||
/* Set the HW_POWER_5VCTRL VBUSVALID_5VDETECT bit to 1 */
|
||||
REG_WRITE(HW_POWER_BASE + HW_POWER_5VCTRL_SET,
|
||||
HW_POWER_5VCTRL_VBUSVALID_5VDETECT);
|
||||
|
||||
/* Set the HW_POWER_5VCTRL VBUSVALID_TRSH to 0x0 (2.9 V) */
|
||||
REG_WRITE(HW_POWER_BASE + HW_POWER_5VCTRL_CLR,
|
||||
HW_POWER_5VCTRL_VBUSVALID_TRSH);
|
||||
|
||||
/* Disable VBUSDROOP status and interrupt. */
|
||||
REG_WRITE(HW_POWER_BASE + HW_POWER_CTRL_CLR,
|
||||
(HW_POWER_CTRL_VDD5V_DROOP_IRQ | HW_POWER_CTRL_ENIRQ_VDD5V_DROOP));
|
||||
|
||||
/* Work over errata #2816 by disabling 5 V brownout while modifying
|
||||
* ENABLE_DCDC. */
|
||||
REG_WRITE(HW_POWER_BASE + HW_POWER_5VCTRL_CLR,
|
||||
HW_POWER_5VCTRL_PWDN_5VBRNOUT);
|
||||
|
||||
/* Set the ENABLE_DCDC bit in HW_POWER_5VCTRL. */
|
||||
REG_WRITE(HW_POWER_BASE + HW_POWER_5VCTRL_SET,
|
||||
HW_POWER_5VCTRL_ENABLE_DCDC);
|
||||
|
||||
REG_WRITE(HW_POWER_BASE + HW_POWER_5VCTRL_SET,
|
||||
HW_POWER_5VCTRL_PWDN_5VBRNOUT);
|
||||
|
||||
delay_us(100);
|
||||
|
||||
pctrl = REG_READ(HW_POWER_BASE + HW_POWER_CTRL);
|
||||
/* VBUSVALID_IRQ is set. */
|
||||
if (__SHIFTOUT(pctrl, HW_POWER_CTRL_VBUSVALID_IRQ)) {
|
||||
/* repeat the sequence for enabling the 4P2 regulator and DCDC
|
||||
* from 4P2. */
|
||||
enable_4p2_linreg();
|
||||
}
|
||||
/* Restore modified bits back to HW_POWER_CTRL. */
|
||||
if (pctrl_saved & HW_POWER_CTRL_ENIRQ_VDDA_BO)
|
||||
REG_WRITE(HW_POWER_BASE + HW_POWER_CTRL_SET,
|
||||
HW_POWER_CTRL_ENIRQ_VDDA_BO);
|
||||
else
|
||||
REG_WRITE(HW_POWER_BASE + HW_POWER_CTRL_CLR,
|
||||
HW_POWER_CTRL_ENIRQ_VDDA_BO);
|
||||
|
||||
if (pctrl_saved & HW_POWER_CTRL_ENIRQ_VDDD_BO)
|
||||
REG_WRITE(HW_POWER_BASE + HW_POWER_CTRL_SET,
|
||||
HW_POWER_CTRL_ENIRQ_VDDD_BO);
|
||||
else
|
||||
REG_WRITE(HW_POWER_BASE + HW_POWER_CTRL_CLR,
|
||||
HW_POWER_CTRL_ENIRQ_VDDD_BO);
|
||||
|
||||
if (pctrl_saved & HW_POWER_CTRL_ENIRQ_VDDIO_BO)
|
||||
REG_WRITE(HW_POWER_BASE + HW_POWER_CTRL_SET,
|
||||
HW_POWER_CTRL_ENIRQ_VDDIO_BO);
|
||||
else
|
||||
REG_WRITE(HW_POWER_BASE + HW_POWER_CTRL_CLR,
|
||||
HW_POWER_CTRL_ENIRQ_VDDIO_BO);
|
||||
|
||||
if (pctrl_saved & HW_POWER_CTRL_VDD5V_DROOP_IRQ)
|
||||
REG_WRITE(HW_POWER_BASE + HW_POWER_CTRL_SET,
|
||||
HW_POWER_CTRL_VDD5V_DROOP_IRQ);
|
||||
else
|
||||
REG_WRITE(HW_POWER_BASE + HW_POWER_CTRL_CLR,
|
||||
HW_POWER_CTRL_VDD5V_DROOP_IRQ);
|
||||
|
||||
if (pctrl_saved & HW_POWER_CTRL_ENIRQ_VDD5V_DROOP)
|
||||
REG_WRITE(HW_POWER_BASE + HW_POWER_CTRL_SET,
|
||||
HW_POWER_CTRL_ENIRQ_VDD5V_DROOP);
|
||||
else
|
||||
REG_WRITE(HW_POWER_BASE + HW_POWER_CTRL_CLR,
|
||||
HW_POWER_CTRL_ENIRQ_VDD5V_DROOP);
|
||||
|
||||
/* Restore modified bits back to HW_POWER_5VCTRL. */
|
||||
p5vctrl = REG_READ(HW_POWER_BASE + HW_POWER_5VCTRL);
|
||||
p5vctrl &= ~(HW_POWER_5VCTRL_PWRUP_VBUS_CMPS |
|
||||
HW_POWER_5VCTRL_VBUSVALID_5VDETECT |
|
||||
HW_POWER_5VCTRL_VBUSVALID_TRSH);
|
||||
p5vctrl |= __SHIFTOUT(p5vctrl_saved, HW_POWER_5VCTRL_VBUSVALID_TRSH) |
|
||||
(p5vctrl_saved & HW_POWER_5VCTRL_PWRUP_VBUS_CMPS) |
|
||||
(p5vctrl_saved & HW_POWER_5VCTRL_VBUSVALID_5VDETECT);
|
||||
REG_WRITE(HW_POWER_BASE + HW_POWER_5VCTRL, p5vctrl);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
enable_vddmem(void)
|
||||
{
|
||||
uint32_t vddctrl;
|
||||
|
||||
/* VDDMEM */
|
||||
vddctrl = REG_READ(HW_POWER_BASE + HW_POWER_VDDMEMCTRL);
|
||||
vddctrl |= (HW_POWER_VDDMEMCTRL_PULLDOWN_ACTIVE |
|
||||
HW_POWER_VDDMEMCTRL_ENABLE_ILIMIT |
|
||||
HW_POWER_VDDMEMCTRL_ENABLE_LINREG);
|
||||
REG_WRITE(HW_POWER_BASE + HW_POWER_VDDMEMCTRL, vddctrl);
|
||||
delay_us(500);
|
||||
vddctrl &= ~(HW_POWER_VDDMEMCTRL_PULLDOWN_ACTIVE |
|
||||
HW_POWER_VDDMEMCTRL_ENABLE_ILIMIT);
|
||||
REG_WRITE(HW_POWER_BASE + HW_POWER_VDDMEMCTRL, vddctrl);
|
||||
|
||||
return;
|
||||
}
|
Loading…
Reference in New Issue