mirror of
https://github.com/Fishwaldo/u-boot.git
synced 2025-03-18 21:21:37 +00:00
Merge branch '2019-07-24-doc-html-cleanup'
- Convert our docs to Sphinx
This commit is contained in:
commit
ef783259d6
72 changed files with 4890 additions and 4237 deletions
|
@ -1,46 +0,0 @@
|
||||||
AX25 is Andes CPU IP to adopt RISC-V architecture.
|
|
||||||
|
|
||||||
Features
|
|
||||||
========
|
|
||||||
|
|
||||||
CPU Core
|
|
||||||
- 5-stage in-order execution pipeline
|
|
||||||
- Hardware Multiplier
|
|
||||||
- radix-2/radix-4/radix-16/radix-256/fast
|
|
||||||
- Hardware Divider
|
|
||||||
- Optional branch prediction
|
|
||||||
- Machine mode and optional user mode
|
|
||||||
- Optional performance monitoring
|
|
||||||
|
|
||||||
ISA
|
|
||||||
- RV64I base integer instructions
|
|
||||||
- RVC for 16-bit compressed instructions
|
|
||||||
- RVM for multiplication and division instructions
|
|
||||||
|
|
||||||
Memory subsystem
|
|
||||||
- I & D local memory
|
|
||||||
- Size: 4KB to 16MB
|
|
||||||
- Memory subsyetem soft-error protection
|
|
||||||
- Protection scheme: parity-checking or error-checking-and-correction (ECC)
|
|
||||||
- Automatic hardware error correction
|
|
||||||
|
|
||||||
Bus
|
|
||||||
- Interface Protocol
|
|
||||||
- Synchronous AHB (32-bit/64-bit data-width), or
|
|
||||||
- Synchronous AXI4 (64-bit data-width)
|
|
||||||
|
|
||||||
Power management
|
|
||||||
- Wait for interrupt (WFI) mode
|
|
||||||
|
|
||||||
Debug
|
|
||||||
- Configurable number of breakpoints: 2/4/8
|
|
||||||
- External Debug Module
|
|
||||||
- AHB slave port
|
|
||||||
- External JTAG debug transport module
|
|
||||||
|
|
||||||
Platform Level Interrupt Controller (PLIC)
|
|
||||||
- AHB slave port
|
|
||||||
- Configurable number of interrupts: 1-1023
|
|
||||||
- Configurable number of interrupt priorities: 3/7/15/63/127/255
|
|
||||||
- Configurable number of targets: 1-16
|
|
||||||
- Preempted interrupt priority stack
|
|
|
@ -1,55 +0,0 @@
|
||||||
N1213 is a configurable hard/soft core of NDS32's N12 CPU family.
|
|
||||||
|
|
||||||
Features
|
|
||||||
========
|
|
||||||
|
|
||||||
CPU Core
|
|
||||||
- 16-/32-bit mixable instruction format.
|
|
||||||
- 32 general-purpose 32-bit registers.
|
|
||||||
- 8-stage pipeline.
|
|
||||||
- Dynamic branch prediction.
|
|
||||||
- 32/64/128/256 BTB.
|
|
||||||
- Return address stack (RAS).
|
|
||||||
- Vector interrupts for internal/external.
|
|
||||||
interrupt controller with 6 hardware interrupt signals.
|
|
||||||
- 3 HW-level nested interruptions.
|
|
||||||
- User and super-user mode support.
|
|
||||||
- Memory-mapped I/O.
|
|
||||||
- Address space up to 4GB.
|
|
||||||
|
|
||||||
Memory Management Unit
|
|
||||||
- TLB
|
|
||||||
- 4/8-entry fully associative iTLB/dTLB.
|
|
||||||
- 32/64/128-entry 4-way set-associati.ve main TLB.
|
|
||||||
- TLB locking support
|
|
||||||
- Optional hardware page table walker.
|
|
||||||
- Two groups of page size support.
|
|
||||||
- 4KB & 1MB.
|
|
||||||
- 8KB & 1MB.
|
|
||||||
|
|
||||||
Memory Subsystem
|
|
||||||
- I & D cache.
|
|
||||||
- Virtually indexed and physically tagged.
|
|
||||||
- Cache size: 8KB/16KB/32KB/64KB.
|
|
||||||
- Cache line size: 16B/32B.
|
|
||||||
- Set associativity: 2-way, 4-way or direct-mapped.
|
|
||||||
- Cache locking support.
|
|
||||||
- I & D local memory (LM).
|
|
||||||
- Size: 4KB to 1MB.
|
|
||||||
- Bank numbers: 1 or 2.
|
|
||||||
- Optional 1D/2D DMA engine.
|
|
||||||
- Internal or external to CPU core.
|
|
||||||
|
|
||||||
Bus Interface
|
|
||||||
- Synchronous/Asynchronous AHB bus: 0, 1 or 2 ports.
|
|
||||||
- Synchronous High speed memory port.
|
|
||||||
(HSMP): 0, 1 or 2 ports.
|
|
||||||
|
|
||||||
Debug
|
|
||||||
- JTAG debug interface.
|
|
||||||
- Embedded debug module (EDM).
|
|
||||||
- Optional embedded program tracer interface.
|
|
||||||
|
|
||||||
Miscellaneous
|
|
||||||
- Programmable data endian control.
|
|
||||||
- Performance monitoring mechanism.
|
|
|
@ -1,41 +0,0 @@
|
||||||
NDS32 is a new high-performance 32-bit RISC microprocessor core.
|
|
||||||
|
|
||||||
http://www.andestech.com/
|
|
||||||
|
|
||||||
AndeStar ISA
|
|
||||||
============
|
|
||||||
AndeStar is a patent-pending 16-bit/32-bit mixed-length instruction set to
|
|
||||||
achieve optimal system performance, code density, and power efficiency.
|
|
||||||
|
|
||||||
It contains the following features:
|
|
||||||
- Intermixable 32-bit and 16-bit instruction sets without the need for
|
|
||||||
mode switch.
|
|
||||||
- 16-bit instructions as a frequently used subset of 32-bit instructions.
|
|
||||||
- RISC-style register-based instruction set.
|
|
||||||
- 32 32-bit General Purpose Registers (GPR).
|
|
||||||
- Upto 1024 User Special Registers (USR) for existing and extension
|
|
||||||
instructions.
|
|
||||||
- Rich load/store instructions for...
|
|
||||||
- Single memory access with base address update.
|
|
||||||
- Multiple aligned and unaligned memory accesses for memory copy and stack
|
|
||||||
operations.
|
|
||||||
- Data prefetch to improve data cache performance.
|
|
||||||
- Non-bus locking synchronization instructions.
|
|
||||||
- PC relative jump and PC read instructions for efficient position independent
|
|
||||||
code.
|
|
||||||
- Multiply-add and multiple-sub with 64-bit accumulator.
|
|
||||||
- Instruction for efficient power management.
|
|
||||||
- Bi-endian support.
|
|
||||||
- Three instruction extension space for application acceleration:
|
|
||||||
- Performance extension.
|
|
||||||
- Andes future extensions (for floating-point, multimedia, etc.)
|
|
||||||
- Customer extensions.
|
|
||||||
|
|
||||||
AndesCore CPU
|
|
||||||
=============
|
|
||||||
Andes Technology has 4 families of CPU cores: N12, N10, N9, N8.
|
|
||||||
|
|
||||||
For details about N12 CPU family, please check doc/README.N1213.
|
|
||||||
|
|
||||||
The NDS32 ports of u-boot, the Linux kernel, the GNU toolchain and
|
|
||||||
other associated software are actively supported by Andes Technology Corporation.
|
|
275
doc/README.ae350
275
doc/README.ae350
|
@ -1,275 +0,0 @@
|
||||||
Andes Technology SoC AE350
|
|
||||||
===========================
|
|
||||||
|
|
||||||
AE350 is the mainline SoC produced by Andes Technology using AX25 CPU core
|
|
||||||
base on RISC-V architecture.
|
|
||||||
|
|
||||||
AE350 has integrated both AHB and APB bus and many periphals for application
|
|
||||||
and product development.
|
|
||||||
|
|
||||||
AX25-AE350
|
|
||||||
=========
|
|
||||||
|
|
||||||
AX25-AE350 is the SoC with AE350 hardcore CPU.
|
|
||||||
|
|
||||||
Configurations
|
|
||||||
==============
|
|
||||||
|
|
||||||
CONFIG_SKIP_LOWLEVEL_INIT:
|
|
||||||
If you want to boot this system from SPI ROM and bypass e-bios (the
|
|
||||||
other boot loader on ROM). You should undefine CONFIG_SKIP_LOWLEVEL_INIT
|
|
||||||
in "include/configs/ax25-ae350.h".
|
|
||||||
|
|
||||||
Build and boot steps
|
|
||||||
====================
|
|
||||||
|
|
||||||
build:
|
|
||||||
1. Prepare the toolchains and make sure the $PATH to toolchains is correct.
|
|
||||||
2. Use `make ae350_rv[32|64]_defconfig` in u-boot root to build the image for 32 or 64 bit.
|
|
||||||
|
|
||||||
Verification
|
|
||||||
====================
|
|
||||||
|
|
||||||
Target
|
|
||||||
====================
|
|
||||||
1. startup
|
|
||||||
2. relocation
|
|
||||||
3. timer driver
|
|
||||||
4. uart driver
|
|
||||||
5. mac driver
|
|
||||||
6. mmc driver
|
|
||||||
7. spi driver
|
|
||||||
|
|
||||||
Steps
|
|
||||||
====================
|
|
||||||
1. Define CONFIG_SKIP_LOWLEVEL_INIT to build u-boot which is loaded via gdb from ram.
|
|
||||||
2. Undefine CONFIG_SKIP_LOWLEVEL_INIT to build u-boot which is booted from spi rom.
|
|
||||||
3. Ping a server by mac driver
|
|
||||||
4. Scan sd card and copy u-boot image which is booted from flash to ram by sd driver.
|
|
||||||
5. Burn this u-boot image to spi rom by spi driver
|
|
||||||
6. Re-boot u-boot from spi flash with power off and power on.
|
|
||||||
|
|
||||||
Messages of U-Boot boot on AE350 board
|
|
||||||
======================================
|
|
||||||
U-Boot 2018.01-rc2-00033-g824f89a (Dec 21 2017 - 16:51:26 +0800)
|
|
||||||
|
|
||||||
DRAM: 1 GiB
|
|
||||||
MMC: mmc@f0e00000: 0
|
|
||||||
SF: Detected mx25u1635e with page size 256 Bytes, erase size 4 KiB, total 2 MiB
|
|
||||||
In: serial@f0300000
|
|
||||||
Out: serial@f0300000
|
|
||||||
Err: serial@f0300000
|
|
||||||
Net:
|
|
||||||
Warning: mac@e0100000 (eth0) using random MAC address - be:dd:d7:e4:e8:10
|
|
||||||
eth0: mac@e0100000
|
|
||||||
|
|
||||||
RISC-V # version
|
|
||||||
U-Boot 2018.01-rc2-00033-gb265b91-dirty (Dec 22 2017 - 13:54:21 +0800)
|
|
||||||
|
|
||||||
riscv32-unknown-linux-gnu-gcc (GCC) 7.2.0
|
|
||||||
GNU ld (GNU Binutils) 2.29
|
|
||||||
|
|
||||||
RISC-V # setenv ipaddr 10.0.4.200 ;
|
|
||||||
RISC-V # setenv serverip 10.0.4.97 ;
|
|
||||||
RISC-V # ping 10.0.4.97 ;
|
|
||||||
Using mac@e0100000 device
|
|
||||||
host 10.0.4.97 is alive
|
|
||||||
|
|
||||||
RISC-V # mmc rescan
|
|
||||||
RISC-V # fatls mmc 0:1
|
|
||||||
318907 u-boot-ae350-64.bin
|
|
||||||
1252 hello_world_ae350_32.bin
|
|
||||||
328787 u-boot-ae350-32.bin
|
|
||||||
|
|
||||||
3 file(s), 0 dir(s)
|
|
||||||
|
|
||||||
RISC-V # sf probe 0:0 50000000 0
|
|
||||||
SF: Detected mx25u1635e with page size 256 Bytes, erase size 4 KiB, total 2 MiB
|
|
||||||
|
|
||||||
RISC-V # sf test 0x100000 0x1000
|
|
||||||
SPI flash test:
|
|
||||||
0 erase: 36 ticks, 111 KiB/s 0.888 Mbps
|
|
||||||
1 check: 29 ticks, 137 KiB/s 1.096 Mbps
|
|
||||||
2 write: 40 ticks, 100 KiB/s 0.800 Mbps
|
|
||||||
3 read: 20 ticks, 200 KiB/s 1.600 Mbps
|
|
||||||
Test passed
|
|
||||||
0 erase: 36 ticks, 111 KiB/s 0.888 Mbps
|
|
||||||
1 check: 29 ticks, 137 KiB/s 1.096 Mbps
|
|
||||||
2 write: 40 ticks, 100 KiB/s 0.800 Mbps
|
|
||||||
3 read: 20 ticks, 200 KiB/s 1.600 Mbps
|
|
||||||
|
|
||||||
RISC-V # fatload mmc 0:1 0x600000 u-boot-ae350-32.bin
|
|
||||||
reading u-boot-ae350-32.bin
|
|
||||||
328787 bytes read in 324 ms (990.2 KiB/s)
|
|
||||||
|
|
||||||
RISC-V # sf erase 0x0 0x51000
|
|
||||||
SF: 331776 bytes @ 0x0 Erased: OK
|
|
||||||
|
|
||||||
RISC-V # sf write 0x600000 0x0 0x50453
|
|
||||||
device 0 offset 0x0, size 0x50453
|
|
||||||
SF: 328787 bytes @ 0x0 Written: OK
|
|
||||||
|
|
||||||
RISC-V # crc32 0x600000 0x50453
|
|
||||||
crc32 for 00600000 ... 00650452 ==> 692dc44a
|
|
||||||
|
|
||||||
RISC-V # crc32 0x80000000 0x50453
|
|
||||||
crc32 for 80000000 ... 80050452 ==> 692dc44a
|
|
||||||
RISC-V #
|
|
||||||
|
|
||||||
*** power-off and power-on, this U-Boot is booted from spi flash ***
|
|
||||||
|
|
||||||
U-Boot 2018.01-rc2-00032-gf67dd47-dirty (Dec 21 2017 - 13:56:03 +0800)
|
|
||||||
|
|
||||||
DRAM: 1 GiB
|
|
||||||
MMC: mmc@f0e00000: 0
|
|
||||||
SF: Detected mx25u1635e with page size 256 Bytes, erase size 4 KiB, total 2 MiB
|
|
||||||
In: serial@f0300000
|
|
||||||
Out: serial@f0300000
|
|
||||||
Err: serial@f0300000
|
|
||||||
Net:
|
|
||||||
Warning: mac@e0100000 (eth0) using random MAC address - ee:4c:58:29:32:f5
|
|
||||||
eth0: mac@e0100000
|
|
||||||
RISC-V #
|
|
||||||
|
|
||||||
|
|
||||||
Boot bbl and riscv-linux via U-Boot on QEMU
|
|
||||||
===========================================
|
|
||||||
1. Build riscv-linux
|
|
||||||
2. Build bbl and riscv-linux with --with-payload
|
|
||||||
3. Prepare ae350.dtb
|
|
||||||
4. Creating OS-kernel images
|
|
||||||
./mkimage -A riscv -O linux -T kernel -C none -a 0x0000 -e 0x0000 -d bbl.bin bootmImage-bbl.bin
|
|
||||||
Image Name:
|
|
||||||
Created: Tue Mar 13 10:06:42 2018
|
|
||||||
Image Type: RISC-V Linux Kernel Image (uncompressed)
|
|
||||||
Data Size: 17901204 Bytes = 17481.64 KiB = 17.07 MiB
|
|
||||||
Load Address: 00000000
|
|
||||||
Entry Point: 00000000
|
|
||||||
|
|
||||||
4. Copy bootmImage-bbl.bin and ae350.dtb to qemu sd card image
|
|
||||||
5. Message of booting riscv-linux from bbl via u-boot on qemu
|
|
||||||
|
|
||||||
U-Boot 2018.03-rc4-00031-g2631273 (Mar 13 2018 - 15:02:55 +0800)
|
|
||||||
|
|
||||||
DRAM: 1 GiB
|
|
||||||
main-loop: WARNING: I/O thread spun for 1000 iterations
|
|
||||||
MMC: mmc@f0e00000: 0
|
|
||||||
Loading Environment from SPI Flash... *** Warning - spi_flash_probe_bus_cs() failed, using default environment
|
|
||||||
|
|
||||||
Failed (-22)
|
|
||||||
In: serial@f0300000
|
|
||||||
Out: serial@f0300000
|
|
||||||
Err: serial@f0300000
|
|
||||||
Net:
|
|
||||||
Warning: mac@e0100000 (eth0) using random MAC address - 02:00:00:00:00:00
|
|
||||||
eth0: mac@e0100000
|
|
||||||
RISC-V # mmc rescan
|
|
||||||
RISC-V # mmc part
|
|
||||||
|
|
||||||
Partition Map for MMC device 0 -- Partition Type: DOS
|
|
||||||
|
|
||||||
Part Start Sector Num Sectors UUID Type
|
|
||||||
RISC-V # fatls mmc 0:0
|
|
||||||
17901268 bootmImage-bbl.bin
|
|
||||||
1954 ae2xx.dtb
|
|
||||||
|
|
||||||
2 file(s), 0 dir(s)
|
|
||||||
|
|
||||||
RISC-V # fatload mmc 0:0 0x00600000 bootmImage-bbl.bin
|
|
||||||
17901268 bytes read in 4642 ms (3.7 MiB/s)
|
|
||||||
RISC-V # fatload mmc 0:0 0x2000000 ae350.dtb
|
|
||||||
1954 bytes read in 1 ms (1.9 MiB/s)
|
|
||||||
RISC-V # setenv bootm_size 0x2000000
|
|
||||||
RISC-V # setenv fdt_high 0x1f00000
|
|
||||||
RISC-V # bootm 0x00600000 - 0x2000000
|
|
||||||
## Booting kernel from Legacy Image at 00600000 ...
|
|
||||||
Image Name:
|
|
||||||
Image Type: RISC-V Linux Kernel Image (uncompressed)
|
|
||||||
Data Size: 17901204 Bytes = 17.1 MiB
|
|
||||||
Load Address: 00000000
|
|
||||||
Entry Point: 00000000
|
|
||||||
Verifying Checksum ... OK
|
|
||||||
## Flattened Device Tree blob at 02000000
|
|
||||||
Booting using the fdt blob at 0x2000000
|
|
||||||
Loading Kernel Image ... OK
|
|
||||||
Loading Device Tree to 0000000001efc000, end 0000000001eff7a1 ... OK
|
|
||||||
[ 0.000000] OF: fdt: Ignoring memory range 0x0 - 0x200000
|
|
||||||
[ 0.000000] Linux version 4.14.0-00046-gf3e439f-dirty (rick@atcsqa06) (gcc version 7.1.1 20170509 (GCC)) #1 Tue Jan 9 16:34:25 CST 2018
|
|
||||||
[ 0.000000] bootconsole [early0] enabled
|
|
||||||
[ 0.000000] Initial ramdisk at: 0xffffffe000016a98 (12267008 bytes)
|
|
||||||
[ 0.000000] Zone ranges:
|
|
||||||
[ 0.000000] DMA [mem 0x0000000000200000-0x000000007fffffff]
|
|
||||||
[ 0.000000] Normal empty
|
|
||||||
[ 0.000000] Movable zone start for each node
|
|
||||||
[ 0.000000] Early memory node ranges
|
|
||||||
[ 0.000000] node 0: [mem 0x0000000000200000-0x000000007fffffff]
|
|
||||||
[ 0.000000] Initmem setup node 0 [mem 0x0000000000200000-0x000000007fffffff]
|
|
||||||
[ 0.000000] elf_hwcap is 0x112d
|
|
||||||
[ 0.000000] random: fast init done
|
|
||||||
[ 0.000000] Built 1 zonelists, mobility grouping on. Total pages: 516615
|
|
||||||
[ 0.000000] Kernel command line: console=ttyS0,38400n8 earlyprintk=uart8250-32bit,0xf0300000 debug loglevel=7
|
|
||||||
[ 0.000000] PID hash table entries: 4096 (order: 3, 32768 bytes)
|
|
||||||
[ 0.000000] Dentry cache hash table entries: 262144 (order: 9, 2097152 bytes)
|
|
||||||
[ 0.000000] Inode-cache hash table entries: 131072 (order: 8, 1048576 bytes)
|
|
||||||
[ 0.000000] Sorting __ex_table...
|
|
||||||
[ 0.000000] Memory: 2047832K/2095104K available (1856K kernel code, 204K rwdata, 532K rodata, 12076K init, 756K bss, 47272K reserved, 0K cma-reserved)
|
|
||||||
[ 0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
|
|
||||||
[ 0.000000] NR_IRQS: 0, nr_irqs: 0, preallocated irqs: 0
|
|
||||||
[ 0.000000] riscv,cpu_intc,0: 64 local interrupts mapped
|
|
||||||
[ 0.000000] riscv,plic0,e4000000: mapped 31 interrupts to 1/2 handlers
|
|
||||||
[ 0.000000] clocksource: riscv_clocksource: mask: 0xffffffffffffffff max_cycles: 0x24e6a1710, max_idle_ns: 440795202120 ns
|
|
||||||
[ 0.000000] Calibrating delay loop (skipped), value calculated using timer frequency.. 20.00 BogoMIPS (lpj=40000)
|
|
||||||
[ 0.000000] pid_max: default: 32768 minimum: 301
|
|
||||||
[ 0.004000] Mount-cache hash table entries: 4096 (order: 3, 32768 bytes)
|
|
||||||
[ 0.004000] Mountpoint-cache hash table entries: 4096 (order: 3, 32768 bytes)
|
|
||||||
[ 0.056000] devtmpfs: initialized
|
|
||||||
[ 0.060000] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns
|
|
||||||
[ 0.064000] futex hash table entries: 256 (order: 0, 6144 bytes)
|
|
||||||
[ 0.068000] NET: Registered protocol family 16
|
|
||||||
[ 0.080000] vgaarb: loaded
|
|
||||||
[ 0.084000] clocksource: Switched to clocksource riscv_clocksource
|
|
||||||
[ 0.088000] NET: Registered protocol family 2
|
|
||||||
[ 0.092000] TCP established hash table entries: 16384 (order: 5, 131072 bytes)
|
|
||||||
[ 0.096000] TCP bind hash table entries: 16384 (order: 5, 131072 bytes)
|
|
||||||
[ 0.096000] TCP: Hash tables configured (established 16384 bind 16384)
|
|
||||||
[ 0.100000] UDP hash table entries: 1024 (order: 3, 32768 bytes)
|
|
||||||
[ 0.100000] UDP-Lite hash table entries: 1024 (order: 3, 32768 bytes)
|
|
||||||
[ 0.104000] NET: Registered protocol family 1
|
|
||||||
[ 0.616000] Unpacking initramfs...
|
|
||||||
[ 1.220000] workingset: timestamp_bits=62 max_order=19 bucket_order=0
|
|
||||||
[ 1.244000] io scheduler noop registered
|
|
||||||
[ 1.244000] io scheduler cfq registered (default)
|
|
||||||
[ 1.244000] io scheduler mq-deadline registered
|
|
||||||
[ 1.248000] io scheduler kyber registered
|
|
||||||
[ 1.360000] Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled
|
|
||||||
[ 1.368000] console [ttyS0] disabled
|
|
||||||
[ 1.372000] f0300000.serial: ttyS0 at MMIO 0xf0300020 (irq = 10, base_baud = 1228800) is a 16550A
|
|
||||||
[ 1.392000] console [ttyS0] enabled
|
|
||||||
[ 1.392000] ftmac100: Loading version 0.2 ...
|
|
||||||
[ 1.396000] ftmac100 e0100000.mac eth0: irq 8, mapped at ffffffd002005000
|
|
||||||
[ 1.400000] ftmac100 e0100000.mac eth0: generated random MAC address 6e:ac:c3:92:36:c0
|
|
||||||
[ 1.404000] IR NEC protocol handler initialized
|
|
||||||
[ 1.404000] IR RC5(x/sz) protocol handler initialized
|
|
||||||
[ 1.404000] IR RC6 protocol handler initialized
|
|
||||||
[ 1.404000] IR JVC protocol handler initialized
|
|
||||||
[ 1.408000] IR Sony protocol handler initialized
|
|
||||||
[ 1.408000] IR SANYO protocol handler initialized
|
|
||||||
[ 1.408000] IR Sharp protocol handler initialized
|
|
||||||
[ 1.408000] IR MCE Keyboard/mouse protocol handler initialized
|
|
||||||
[ 1.412000] IR XMP protocol handler initialized
|
|
||||||
[ 1.456000] ftsdc010 f0e00000.mmc: mmc0 - using hw SDIO IRQ
|
|
||||||
[ 1.464000] bootconsole [early0] uses init memory and must be disabled even before the real one is ready
|
|
||||||
[ 1.464000] bootconsole [early0] disabled
|
|
||||||
[ 1.508000] Freeing unused kernel memory: 12076K
|
|
||||||
[ 1.512000] This architecture does not have kernel memory protection.
|
|
||||||
[ 1.520000] mmc0: new SD card at address 4567
|
|
||||||
[ 1.524000] mmcblk0: mmc0:4567 QEMU! 20.0 MiB
|
|
||||||
[ 1.844000] mmcblk0:
|
|
||||||
Wed Dec 1 10:00:00 CST 2010
|
|
||||||
/ #
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
TODO
|
|
||||||
==================================================
|
|
||||||
Boot bbl and riscv-linux via U-Boot on AE350 board
|
|
174
doc/README.at91
174
doc/README.at91
|
@ -1,174 +0,0 @@
|
||||||
Atmel AT91 Evaluation kits
|
|
||||||
|
|
||||||
Index
|
|
||||||
- I. Board mapping & boot media
|
|
||||||
- II. NAND partition table
|
|
||||||
- III. watchdog support
|
|
||||||
|
|
||||||
I. Board mapping & boot media
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
AT91SAM9260EK, AT91SAM9G20EK & AT91SAM9XEEK
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Memory map
|
|
||||||
0x20000000 - 23FFFFFF SDRAM (64 MB)
|
|
||||||
0xC0000000 - Cxxxxxxx Atmel Dataflash card (J13)
|
|
||||||
0xD0000000 - D07FFFFF Soldered Atmel Dataflash (AT45DB642)
|
|
||||||
|
|
||||||
Environment variables
|
|
||||||
|
|
||||||
U-Boot environment variables can be stored at different places:
|
|
||||||
- Dataflash on SPI chip select 1 (default)
|
|
||||||
- Dataflash on SPI chip select 0 (dataflash card)
|
|
||||||
- Nand flash.
|
|
||||||
|
|
||||||
You can choose your storage location at config step (here for at91sam9260ek) :
|
|
||||||
make at91sam9260ek_nandflash_config - use nand flash
|
|
||||||
make at91sam9260ek_dataflash_cs0_config - use data flash (spi cs0)
|
|
||||||
make at91sam9260ek_dataflash_cs1_config - use data flash (spi cs1)
|
|
||||||
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
AT91SAM9261EK, AT91SAM9G10EK
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Memory map
|
|
||||||
0x20000000 - 23FFFFFF SDRAM (64 MB)
|
|
||||||
0xC0000000 - C07FFFFF Soldered Atmel Dataflash (AT45DB642)
|
|
||||||
0xD0000000 - Dxxxxxxx Atmel Dataflash card (J22)
|
|
||||||
|
|
||||||
Environment variables
|
|
||||||
|
|
||||||
U-Boot environment variables can be stored at different places:
|
|
||||||
- Dataflash on SPI chip select 0 (default)
|
|
||||||
- Dataflash on SPI chip select 3 (dataflash card)
|
|
||||||
- Nand flash.
|
|
||||||
|
|
||||||
You can choose your storage location at config step (here for at91sam9260ek) :
|
|
||||||
make at91sam9261ek_nandflash_config - use nand flash
|
|
||||||
make at91sam9261ek_dataflash_cs0_config - use data flash (spi cs0)
|
|
||||||
make at91sam9261ek_dataflash_cs3_config - use data flash (spi cs3)
|
|
||||||
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
AT91SAM9263EK
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Memory map
|
|
||||||
0x20000000 - 23FFFFFF SDRAM (64 MB)
|
|
||||||
0xC0000000 - Cxxxxxxx Atmel Dataflash card (J9)
|
|
||||||
|
|
||||||
Environment variables
|
|
||||||
|
|
||||||
U-Boot environment variables can be stored at different places:
|
|
||||||
- Dataflash on SPI chip select 0 (dataflash card)
|
|
||||||
- Nand flash.
|
|
||||||
- Nor flash (not populate by default)
|
|
||||||
|
|
||||||
You can choose your storage location at config step (here for at91sam9260ek) :
|
|
||||||
make at91sam9263ek_nandflash_config - use nand flash
|
|
||||||
make at91sam9263ek_dataflash_cs0_config - use data flash (spi cs0)
|
|
||||||
make at91sam9263ek_norflash_config - use nor flash
|
|
||||||
|
|
||||||
You can choose to boot directly from U-Boot at config step
|
|
||||||
make at91sam9263ek_norflash_boot_config - boot from nor flash
|
|
||||||
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
AT91SAM9M10G45EK
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Memory map
|
|
||||||
0x70000000 - 77FFFFFF SDRAM (128 MB)
|
|
||||||
|
|
||||||
Environment variables
|
|
||||||
|
|
||||||
U-Boot environment variables can be stored at different places:
|
|
||||||
- Nand flash.
|
|
||||||
|
|
||||||
You can choose your storage location at config step (here for at91sam9m10g45ek) :
|
|
||||||
make at91sam9m10g45ek_nandflash_config - use nand flash
|
|
||||||
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
AT91SAM9RLEK
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Memory map
|
|
||||||
0x20000000 - 23FFFFFF SDRAM (64 MB)
|
|
||||||
0xC0000000 - C07FFFFF Soldered Atmel Dataflash (AT45DB642)
|
|
||||||
|
|
||||||
Environment variables
|
|
||||||
|
|
||||||
U-Boot environment variables can be stored at different places:
|
|
||||||
- Dataflash on SPI chip select 0
|
|
||||||
- Nand flash.
|
|
||||||
|
|
||||||
You can choose your storage location at config step (here for at91sam9rlek) :
|
|
||||||
make at91sam9rlek_nandflash_config - use nand flash
|
|
||||||
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
AT91SAM9N12EK, AT91SAM9X5EK
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Memory map
|
|
||||||
0x20000000 - 27FFFFFF SDRAM (128 MB)
|
|
||||||
|
|
||||||
Environment variables
|
|
||||||
|
|
||||||
U-Boot environment variables can be stored at different places:
|
|
||||||
- Nand flash.
|
|
||||||
- SD/MMC card
|
|
||||||
- Serialflash/Dataflash on SPI chip select 0
|
|
||||||
|
|
||||||
You can choose your storage location at config step (here for at91sam9x5ek) :
|
|
||||||
make at91sam9x5ek_dataflash_config - use data flash
|
|
||||||
make at91sam9x5ek_mmc_config - use sd/mmc card
|
|
||||||
make at91sam9x5ek_nandflash_config - use nand flash
|
|
||||||
make at91sam9x5ek_spiflash_config - use serial flash
|
|
||||||
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
SAMA5D3XEK
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Memory map
|
|
||||||
0x20000000 - 3FFFFFFF SDRAM (512 MB)
|
|
||||||
|
|
||||||
Environment variables
|
|
||||||
|
|
||||||
U-Boot environment variables can be stored at different places:
|
|
||||||
- Nand flash.
|
|
||||||
- SD/MMC card
|
|
||||||
- Serialflash on SPI chip select 0
|
|
||||||
|
|
||||||
You can choose your storage location at config step (here for sama5d3xek) :
|
|
||||||
make sama5d3xek_mmc_config - use SD/MMC card
|
|
||||||
make sama5d3xek_nandflash_config - use nand flash
|
|
||||||
make sama5d3xek_serialflash_config - use serial flash
|
|
||||||
|
|
||||||
|
|
||||||
II. NAND partition table
|
|
||||||
|
|
||||||
All the board support boot from NAND flash will use the following NAND
|
|
||||||
partition table
|
|
||||||
|
|
||||||
0x00000000 - 0x0003FFFF bootstrap (256 KiB)
|
|
||||||
0x00040000 - 0x000BFFFF u-boot (512 KiB)
|
|
||||||
0x000C0000 - 0x000FFFFF env (256 KiB)
|
|
||||||
0x00100000 - 0x0013FFFF env_redundant (256 KiB)
|
|
||||||
0x00140000 - 0x0017FFFF spare (256 KiB)
|
|
||||||
0x00180000 - 0x001FFFFF dtb (512 KiB)
|
|
||||||
0x00200000 - 0x007FFFFF kernel (6 MiB)
|
|
||||||
0x00800000 - 0xxxxxxxxx rootfs (All left)
|
|
||||||
|
|
||||||
III. Watchdog support
|
|
||||||
|
|
||||||
For security reasons, the at91 watchdog is running at boot time and,
|
|
||||||
if deactivated, cannot be used anymore.
|
|
||||||
If you want to use the watchdog, you will need to keep it running in
|
|
||||||
your code (make sure not to disable it in AT91Bootstrap for instance).
|
|
||||||
|
|
||||||
In the U-Boot configuration, the AT91 watchdog support is enabled using
|
|
||||||
the CONFIG_WDT and CONFIG_WDT_AT91 options.
|
|
|
@ -1,366 +0,0 @@
|
||||||
Overview
|
|
||||||
--------
|
|
||||||
The B4860QDS is a Freescale reference board that hosts the B4860 SoC (and variants).
|
|
||||||
|
|
||||||
B4860 Overview
|
|
||||||
-------------
|
|
||||||
The B4860 QorIQ Qonverge device is a Freescale high-end, multicore SoC based on
|
|
||||||
StarCore and Power Architecture® cores. It targets the broadband wireless
|
|
||||||
infrastructure and builds upon the proven success of the existing multicore
|
|
||||||
DSPs and Power CPUs. It is designed to bolster the rapidly changing and
|
|
||||||
expanding wireless markets, such as 3GLTE (FDD and TDD), LTE-Advanced, and UMTS.
|
|
||||||
|
|
||||||
The B4860 is a highly-integrated StarCore and Power Architecture processor that
|
|
||||||
contains:
|
|
||||||
. Six fully-programmable StarCore SC3900 FVP subsystems, divided into three
|
|
||||||
clusters-each core runs up to 1.2 GHz, with an architecture highly optimized for
|
|
||||||
wireless base station applications
|
|
||||||
. Four dual-thread e6500 Power Architecture processors organized in one cluster-each
|
|
||||||
core runs up to 1.8 GHz
|
|
||||||
. Two DDR3/3L controllers for high-speed, industry-standard memory interface each
|
|
||||||
runs at up to 1866.67 MHz
|
|
||||||
. MAPLE-B3 hardware acceleration-for forward error correction schemes including
|
|
||||||
Turbo or Viterbi decoding, Turbo encoding and rate matching, MIMO MMSE
|
|
||||||
equalization scheme, matrix operations, CRC insertion and check, DFT/iDFT and
|
|
||||||
FFT/iFFT calculations, PUSCH/PDSCH acceleration, and UMTS chip rate
|
|
||||||
acceleration
|
|
||||||
. CoreNet fabric that fully supports coherency using MESI protocol between the
|
|
||||||
e6500 cores, SC3900 FVP cores, memories and external interfaces.
|
|
||||||
CoreNet fabric interconnect runs at 667 MHz and supports coherent and
|
|
||||||
non-coherent out of order transactions with prioritization and bandwidth
|
|
||||||
allocation amongst CoreNet endpoints.
|
|
||||||
. Data Path Acceleration Architecture, which includes the following:
|
|
||||||
. Frame Manager (FMan), which supports in-line packet parsing and general
|
|
||||||
classification to enable policing and QoS-based packet distribution
|
|
||||||
. Queue Manager (QMan) and Buffer Manager (BMan), which allow offloading
|
|
||||||
of queue management, task management, load distribution, flow ordering, buffer
|
|
||||||
management, and allocation tasks from the cores
|
|
||||||
. Security engine (SEC 5.3)-crypto-acceleration for protocols such as IPsec,
|
|
||||||
SSL, and 802.16
|
|
||||||
. RapidIO manager (RMAN) - Support SRIO types 8, 9, 10, and 11 (inbound and
|
|
||||||
outbound). Supports types 5, 6 (outbound only)
|
|
||||||
. Large internal cache memory with snooping and stashing capabilities for
|
|
||||||
bandwidth saving and high utilization of processor elements. The 9856-Kbyte
|
|
||||||
internal memory space includes the following:
|
|
||||||
. 32 Kbyte L1 ICache per e6500/SC3900 core
|
|
||||||
. 32 Kbyte L1 DCache per e6500/SC3900 core
|
|
||||||
. 2048 Kbyte unified L2 cache for each SC3900 FVP cluster
|
|
||||||
. 2048 Kbyte unified L2 cache for the e6500 cluster
|
|
||||||
. Two 512 Kbyte shared L3 CoreNet platform caches (CPC)
|
|
||||||
. Sixteen 10-GHz SerDes lanes serving:
|
|
||||||
. Two Serial RapidIO interfaces.
|
|
||||||
- Each supports up to 4 lanes and a total of up to 8 lanes
|
|
||||||
. Up to 8-lanes Common Public Radio Interface (CPRI) controller for glue-less
|
|
||||||
antenna connection
|
|
||||||
. Two 10-Gbit Ethernet controllers (10GEC)
|
|
||||||
. Six 1G/2.5-Gbit Ethernet controllers for network communications
|
|
||||||
. PCI Express controller
|
|
||||||
. Debug (Aurora)
|
|
||||||
. Two OCeaN DMAs
|
|
||||||
. Various system peripherals
|
|
||||||
. 182 32-bit timers
|
|
||||||
|
|
||||||
B4860QDS Overview
|
|
||||||
------------------
|
|
||||||
- DDRC1: Ten separate DDR3 parts of 16-bit to support 72-bit (ECC) at 1866MT/s, ECC, 4 GB
|
|
||||||
of memory in two ranks of 2 GB.
|
|
||||||
- DDRC2: Five separate DDR3 parts of 16-bit to support 72-bit (ECC) at 1866MT/s, ECC, 2 GB
|
|
||||||
of memory. Single rank.
|
|
||||||
- SerDes 1 multiplexing: Two Vitesse (transmit and receive path) cross-point 16x16 switch
|
|
||||||
VSC3316
|
|
||||||
- SerDes 2 multiplexing: Two Vitesse (transmit and receive path) cross-point 8x8 switch VSC3308
|
|
||||||
- USB 2.0 ULPI PHY USB3315 by SMSC supports USB port in host mode.
|
|
||||||
B4860 UART port is available over USB-to-UART translator USB2SER or over RS232 flat cable.
|
|
||||||
- A Vitesse dual SGMII phy VSC8662 links the B4860 SGMII lines to 2xRJ-45 copper connectors
|
|
||||||
for Stand-alone mode and to the 1000Base-X over AMC MicroTCA connector ports 0 and 2 for
|
|
||||||
AMC mode.
|
|
||||||
- The B4860 configuration may be loaded from nine bits coded reset configuration reset source. The
|
|
||||||
RCW source is set by appropriate DIP-switches:
|
|
||||||
- 16-bit NOR Flash / PROMJet
|
|
||||||
- QIXIS 8-bit NOR Flash Emulator
|
|
||||||
- 8-bit NAND Flash
|
|
||||||
- 24-bit SPI Flash
|
|
||||||
- Long address I2C EEPROM
|
|
||||||
- Available debug interfaces are:
|
|
||||||
- On-board eCWTAP controller with ETH and USB I/F
|
|
||||||
- JTAG/COP 16-pin header for any external TAP controller
|
|
||||||
- External JTAG source over AMC to support B2B configuration
|
|
||||||
- 70-pin Aurora debug connector
|
|
||||||
- QIXIS (FPGA) logic:
|
|
||||||
- 2 KB internal memory space including
|
|
||||||
- IDT840NT4 clock synthesizer provides B4860 essential clocks : SYSCLK, DDRCLK1,2 and
|
|
||||||
RTCCLK.
|
|
||||||
- Two 8T49N222A SerDes ref clock devices support two SerDes port clock frequency - total four
|
|
||||||
refclk, including CPRI clock scheme.
|
|
||||||
|
|
||||||
B4420 Personality
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
B4420 Personality
|
|
||||||
--------------------
|
|
||||||
B4420 is a reduced personality of B4860 with less core/clusters(both SC3900 and e6500), less DDR
|
|
||||||
controllers, less serdes lanes, less SGMII interfaces and reduced target frequencies.
|
|
||||||
|
|
||||||
Key differences between B4860 and B4420
|
|
||||||
----------------------------------------
|
|
||||||
|
|
||||||
B4420 has:
|
|
||||||
1. Less e6500 cores: 1 cluster with 2 e6500 cores
|
|
||||||
2. Less SC3900 cores/clusters: 1 cluster with 2 SC3900 cores per cluster.
|
|
||||||
3. Single DDRC
|
|
||||||
4. 2X 4 lane serdes
|
|
||||||
5. 3 SGMII interfaces
|
|
||||||
6. no sRIO
|
|
||||||
7. no 10G
|
|
||||||
|
|
||||||
B4860QDS Default Settings
|
|
||||||
-------------------------
|
|
||||||
|
|
||||||
Switch Settings
|
|
||||||
----------------
|
|
||||||
|
|
||||||
SW1 OFF [0] OFF [0] OFF [0] OFF [0] OFF [0] OFF [0] OFF [0] OFF [0]
|
|
||||||
SW2 ON ON ON ON ON ON OFF OFF
|
|
||||||
SW3 OFF OFF OFF ON OFF OFF ON OFF
|
|
||||||
SW5 OFF OFF OFF OFF OFF OFF ON ON
|
|
||||||
|
|
||||||
Note: PCIe slots modes: All the PCIe devices work as Root Complex.
|
|
||||||
Note: Boot location: NOR flash.
|
|
||||||
|
|
||||||
SysClk/Core(e6500)/CCB/DDR/FMan/DDRCLK/StarCore/CPRI-Maple/eTVPE-Maple/ULB-Maple
|
|
||||||
66MHz/1.6GHz/667MHz/1.6GHz data rate/667MHz/133MHz/1200MHz/500MHz/800MHz/667MHz
|
|
||||||
|
|
||||||
a) NAND boot
|
|
||||||
SW1 [1.1] = 0
|
|
||||||
SW2 [1.1] = 1
|
|
||||||
SW3 [1:4] = 0001
|
|
||||||
b) NOR boot
|
|
||||||
SW1 [1.1] = 1
|
|
||||||
SW2 [1.1] = 0
|
|
||||||
SW3 [1:4] = 1000.
|
|
||||||
|
|
||||||
B4420QDS Default Settings
|
|
||||||
-------------------------
|
|
||||||
|
|
||||||
Switch Settings
|
|
||||||
----------------
|
|
||||||
SW1 OFF[0] OFF [0] OFF [0] OFF [0] OFF [0] OFF [0] OFF [0] OFF [0]
|
|
||||||
SW2 ON OFF ON OFF ON ON OFF OFF
|
|
||||||
SW3 OFF OFF OFF ON OFF OFF ON OFF
|
|
||||||
SW5 OFF OFF OFF OFF OFF OFF ON ON
|
|
||||||
|
|
||||||
Note: PCIe slots modes: All the PCIe devices work as Root Complex.
|
|
||||||
Note: Boot location: NOR flash.
|
|
||||||
|
|
||||||
SysClk/Core(e6500)/CCB/DDR/FMan/DDRCLK/StarCore/CPRI-Maple/eTVPE-Maple/ULB-Maple
|
|
||||||
66MHz/1.6GHz/667MHz/1.6GHz data rate/667MHz/133MHz/1200MHz/500MHz/800MHz/667MHz
|
|
||||||
|
|
||||||
a) NAND boot
|
|
||||||
SW1 [1.1] = 0
|
|
||||||
SW2 [1.1] = 1
|
|
||||||
SW3 [1:4] = 0001
|
|
||||||
b) NOR boot
|
|
||||||
SW1 [1.1] = 1
|
|
||||||
SW2 [1.1] = 0
|
|
||||||
SW3 [1:4] = 1000.
|
|
||||||
|
|
||||||
Memory map on B4860QDS
|
|
||||||
----------------------
|
|
||||||
The addresses in brackets are physical addresses.
|
|
||||||
|
|
||||||
Start Address End Address Description Size
|
|
||||||
0xF_FFDF_1000 0xF_FFFF_FFFF Free 2 MB
|
|
||||||
0xF_FFDF_0000 0xF_FFDF_0FFF IFC - FPGA 4 KB
|
|
||||||
0xF_FF81_0000 0xF_FFDE_FFFF Free 5 MB
|
|
||||||
0xF_FF80_0000 0xF_FF80_FFFF IFC NAND Flash 64 KB
|
|
||||||
0xF_FF00_0000 0xF_FF7F_FFFF Free 8 MB
|
|
||||||
0xF_FE00_0000 0xF_FEFF_FFFF CCSRBAR 16 MB
|
|
||||||
0xF_F801_0000 0xF_FDFF_FFFF Free 95 MB
|
|
||||||
0xF_F800_0000 0xF_F800_FFFF PCIe I/O Space 64 KB
|
|
||||||
0xF_F600_0000 0xF_F7FF_FFFF QMAN s/w portal 32 MB
|
|
||||||
0xF_F400_0000 0xF_F5FF_FFFF BMAN s/w portal 32 MB
|
|
||||||
0xF_F000_0000 0xF_F3FF_FFFF Free 64 MB
|
|
||||||
0xF_E800_0000 0xF_EFFF_FFFF IFC NOR Flash 128 MB
|
|
||||||
0xF_E000_0000 0xF_E7FF_FFFF Promjet 128 MB
|
|
||||||
0xF_A0C0_0000 0xF_DFFF_FFFF Free 1012 MB
|
|
||||||
0xF_A000_0000 0xF_A0BF_FFFF MAPLE0/1/2 12 MB
|
|
||||||
0xF_0040_0000 0xF_9FFF_FFFF Free 12 GB
|
|
||||||
0xF_0000_0000 0xF_01FF_FFFF DCSR 32 MB
|
|
||||||
0xC_4000_0000 0xE_FFFF_FFFF Free 11 GB
|
|
||||||
0xC_3000_0000 0xC_3FFF_FFFF sRIO-2 I/O 256 MB
|
|
||||||
0xC_2000_0000 0xC_2FFF_FFFF sRIO-1 I/O 256 MB
|
|
||||||
0xC_0000_0000 0xC_1FFF_FFFF PCIe Mem Space 512 MB
|
|
||||||
0x1_0000_0000 0xB_FFFF_FFFF Free 44 GB
|
|
||||||
0x0_8000_0000 0x0_FFFF_FFFF DDRC1 2 GB
|
|
||||||
0x0_0000_0000 0x0_7FFF_FFFF DDRC2 2 GB
|
|
||||||
|
|
||||||
Memory map on B4420QDS
|
|
||||||
----------------------
|
|
||||||
The addresses in brackets are physical addresses.
|
|
||||||
|
|
||||||
Start Address End Address Description Size
|
|
||||||
0xF_FFDF_1000 0xF_FFFF_FFFF Free 2 MB
|
|
||||||
0xF_FFDF_0000 0xF_FFDF_0FFF IFC - FPGA 4 KB
|
|
||||||
0xF_FF81_0000 0xF_FFDE_FFFF Free 5 MB
|
|
||||||
0xF_FF80_0000 0xF_FF80_FFFF IFC NAND Flash 64 KB
|
|
||||||
0xF_FF00_0000 0xF_FF7F_FFFF Free 8 MB
|
|
||||||
0xF_FE00_0000 0xF_FEFF_FFFF CCSRBAR 16 MB
|
|
||||||
0xF_F801_0000 0xF_FDFF_FFFF Free 95 MB
|
|
||||||
0xF_F800_0000 0xF_F800_FFFF PCIe I/O Space 64 KB
|
|
||||||
0xF_F600_0000 0xF_F7FF_FFFF QMAN s/w portal 32 MB
|
|
||||||
0xF_F400_0000 0xF_F5FF_FFFF BMAN s/w portal 32 MB
|
|
||||||
0xF_F000_0000 0xF_F3FF_FFFF Free 64 MB
|
|
||||||
0xF_E800_0000 0xF_EFFF_FFFF IFC NOR Flash 128 MB
|
|
||||||
0xF_E000_0000 0xF_E7FF_FFFF Promjet 128 MB
|
|
||||||
0xF_A0C0_0000 0xF_DFFF_FFFF Free 1012 MB
|
|
||||||
0xF_A000_0000 0xF_A0BF_FFFF MAPLE0/1/2 12 MB
|
|
||||||
0xF_0040_0000 0xF_9FFF_FFFF Free 12 GB
|
|
||||||
0xF_0000_0000 0xF_01FF_FFFF DCSR 32 MB
|
|
||||||
0xC_4000_0000 0xE_FFFF_FFFF Free 11 GB
|
|
||||||
0xC_3000_0000 0xC_3FFF_FFFF sRIO-2 I/O 256 MB
|
|
||||||
0xC_2000_0000 0xC_2FFF_FFFF sRIO-1 I/O 256 MB
|
|
||||||
0xC_0000_0000 0xC_1FFF_FFFF PCIe Mem Space 512 MB
|
|
||||||
0x1_0000_0000 0xB_FFFF_FFFF Free 44 GB
|
|
||||||
0x0_0000_0000 0x0_FFFF_FFFF DDRC1 4 GB
|
|
||||||
|
|
||||||
|
|
||||||
NOR Flash memory Map on B4860 and B4420QDS
|
|
||||||
------------------------------------------
|
|
||||||
Start End Definition Size
|
|
||||||
0xEFF40000 0xEFFFFFFF U-Boot (current bank) 768KB
|
|
||||||
0xEFF20000 0xEFF3FFFF U-Boot env (current bank) 128KB
|
|
||||||
0xEFF00000 0xEFF1FFFF FMAN Ucode (current bank) 128KB
|
|
||||||
0xEF300000 0xEFEFFFFF rootfs (alternate bank) 12MB
|
|
||||||
0xEE800000 0xEE8FFFFF device tree (alternate bank) 1MB
|
|
||||||
0xEE020000 0xEE6FFFFF Linux.uImage (alternate bank) 6MB+896KB
|
|
||||||
0xEE000000 0xEE01FFFF RCW (alternate bank) 128KB
|
|
||||||
0xEDF40000 0xEDFFFFFF U-Boot (alternate bank) 768KB
|
|
||||||
0xEDF20000 0xEDF3FFFF U-Boot env (alternate bank) 128KB
|
|
||||||
0xEDF00000 0xEDF1FFFF FMAN ucode (alternate bank) 128KB
|
|
||||||
0xED300000 0xEDEFFFFF rootfs (current bank) 12MB
|
|
||||||
0xEC800000 0xEC8FFFFF device tree (current bank) 1MB
|
|
||||||
0xEC020000 0xEC6FFFFF Linux.uImage (current bank) 6MB+896KB
|
|
||||||
0xEC000000 0xEC01FFFF RCW (current bank) 128KB
|
|
||||||
|
|
||||||
Various Software configurations/environment variables/commands
|
|
||||||
--------------------------------------------------------------
|
|
||||||
The below commands apply to both B4860QDS and B4420QDS.
|
|
||||||
|
|
||||||
1. U-Boot environment variable hwconfig
|
|
||||||
The default hwconfig is:
|
|
||||||
hwconfig=fsl_ddr:ctlr_intlv=null,bank_intlv=cs0_cs1;usb1:
|
|
||||||
dr_mode=host,phy_type=ulpi
|
|
||||||
Note: For USB gadget set "dr_mode=peripheral"
|
|
||||||
|
|
||||||
2. FMAN Ucode versions
|
|
||||||
fsl_fman_ucode_B4860_106_3_6.bin
|
|
||||||
|
|
||||||
3. Switching to alternate bank
|
|
||||||
Commands for switching to alternate bank.
|
|
||||||
|
|
||||||
1. To change from vbank0 to vbank2
|
|
||||||
=> qixis_reset altbank (it will boot using vbank2)
|
|
||||||
|
|
||||||
2.To change from vbank2 to vbank0
|
|
||||||
=> qixis reset (it will boot using vbank0)
|
|
||||||
|
|
||||||
4. To change personality of board
|
|
||||||
For changing personality from B4860 to B4420
|
|
||||||
1)Boot from vbank0
|
|
||||||
2)Flash vbank2 with b4420 rcw and U-Boot
|
|
||||||
3)Give following commands to uboot prompt
|
|
||||||
=> mw.b ffdf0040 0x30;
|
|
||||||
=> mw.b ffdf0010 0x00;
|
|
||||||
=> mw.b ffdf0062 0x02;
|
|
||||||
=> mw.b ffdf0050 0x02;
|
|
||||||
=> mw.b ffdf0010 0x30;
|
|
||||||
=> reset
|
|
||||||
|
|
||||||
Note: Power off cycle will lead to default switch settings.
|
|
||||||
Note: 0xffdf0000 is the address of the QIXIS FPGA.
|
|
||||||
|
|
||||||
5. Switching between NOR and NAND boot(RCW src changed from NOR <-> NAND)
|
|
||||||
|
|
||||||
To change from NOR to NAND boot give following command on uboot prompt
|
|
||||||
=> mw.b ffdf0040 0x30
|
|
||||||
=> mw.b ffdf0010 0x00
|
|
||||||
=> mw.b 0xffdf0050 0x08
|
|
||||||
=> mw.b 0xffdf0060 0x82
|
|
||||||
=> mw.b ffdf0061 0x00
|
|
||||||
=> mw.b ffdf0010 0x30
|
|
||||||
=> reset
|
|
||||||
|
|
||||||
To change from NAND to NOR boot give following command on uboot prompt:
|
|
||||||
=> mw.b ffdf0040 0x30
|
|
||||||
=> mw.b ffdf0010 0x00
|
|
||||||
=> mw.b 0xffdf0050 0x00(for vbank0) or (mw.b 0xffdf0050 0x02 for vbank2)
|
|
||||||
=> mw.b 0xffdf0060 0x12
|
|
||||||
=> mw.b ffdf0061 0x01
|
|
||||||
=> mw.b ffdf0010 0x30
|
|
||||||
=> reset
|
|
||||||
|
|
||||||
Note: Power off cycle will lead to default switch settings.
|
|
||||||
Note: 0xffdf0000 is the address of the QIXIS FPGA.
|
|
||||||
|
|
||||||
6. Ethernet interfaces for B4860QDS
|
|
||||||
Serdes protocosl tested:
|
|
||||||
0x2a, 0x8d (serdes1, serdes2) [DEFAULT]
|
|
||||||
0x2a, 0xb2 (serdes1, serdes2)
|
|
||||||
|
|
||||||
When using [DEFAULT] RCW, which including 2 * 1G SGMII on board and 2 * 1G
|
|
||||||
SGMII on SGMII riser card.
|
|
||||||
Under U-Boot these network interfaces are recognized as:
|
|
||||||
FM1@DTSEC3, FM1@DTSEC4, FM1@DTSEC5 and FM1@DTSEC6.
|
|
||||||
|
|
||||||
On Linux the interfaces are renamed as:
|
|
||||||
. eth2 -> fm1-gb2
|
|
||||||
. eth3 -> fm1-gb3
|
|
||||||
. eth4 -> fm1-gb4
|
|
||||||
. eth5 -> fm1-gb5
|
|
||||||
|
|
||||||
7. RCW and Ethernet interfaces for B4420QDS
|
|
||||||
Serdes protocosl tested:
|
|
||||||
0x18, 0x9e (serdes1, serdes2)
|
|
||||||
|
|
||||||
Under U-Boot these network interfaces are recognized as:
|
|
||||||
FM1@DTSEC3, FM1@DTSEC4 and e1000#0.
|
|
||||||
|
|
||||||
On Linux the interfaces are renamed as:
|
|
||||||
. eth2 -> fm1-gb2
|
|
||||||
. eth3 -> fm1-gb3
|
|
||||||
|
|
||||||
NAND boot with 2 Stage boot loader
|
|
||||||
----------------------------------
|
|
||||||
PBL initialise the internal SRAM and copy SPL(160KB) in SRAM.
|
|
||||||
SPL further initialise DDR using SPD and environment variables and copy
|
|
||||||
U-Boot(768 KB) from flash to DDR.
|
|
||||||
Finally SPL transer control to U-Boot for futher booting.
|
|
||||||
|
|
||||||
SPL has following features:
|
|
||||||
- Executes within 256K
|
|
||||||
- No relocation required
|
|
||||||
|
|
||||||
Run time view of SPL framework during boot :-
|
|
||||||
-----------------------------------------------
|
|
||||||
Area | Address |
|
|
||||||
-----------------------------------------------
|
|
||||||
Secure boot | 0xFFFC0000 (32KB) |
|
|
||||||
headers | |
|
|
||||||
-----------------------------------------------
|
|
||||||
GD, BD | 0xFFFC8000 (4KB) |
|
|
||||||
-----------------------------------------------
|
|
||||||
ENV | 0xFFFC9000 (8KB) |
|
|
||||||
-----------------------------------------------
|
|
||||||
HEAP | 0xFFFCB000 (30KB) |
|
|
||||||
-----------------------------------------------
|
|
||||||
STACK | 0xFFFD8000 (22KB) |
|
|
||||||
-----------------------------------------------
|
|
||||||
U-Boot SPL | 0xFFFD8000 (160KB) |
|
|
||||||
-----------------------------------------------
|
|
||||||
|
|
||||||
NAND Flash memory Map on B4860 and B4420QDS
|
|
||||||
------------------------------------------
|
|
||||||
Start End Definition Size
|
|
||||||
0x000000 0x0FFFFF U-Boot 1MB
|
|
||||||
0x140000 0x15FFFF U-Boot env 128KB
|
|
||||||
0x1A0000 0x1BFFFF FMAN Ucode 128KB
|
|
|
@ -1,46 +0,0 @@
|
||||||
Notes for the Blackfin architecture port of Das U-Boot
|
|
||||||
|
|
||||||
=========
|
|
||||||
! ABOUT !
|
|
||||||
=========
|
|
||||||
|
|
||||||
<marketing blurb>
|
|
||||||
Blackfin Processors embody a new breed of 16/32-bit embedded processor, ideally
|
|
||||||
suited for products where a convergence of capabilities are necessary -
|
|
||||||
multi-format audio, video, voice and image processing; multi-mode baseband and
|
|
||||||
packet processing; control processing; and real-time security. The Blackfin's
|
|
||||||
unique combination of software flexibility and scalability has gained it
|
|
||||||
widespread adoption in convergent applications.
|
|
||||||
</marketing blurb>
|
|
||||||
|
|
||||||
The Blackfin processor is wholly developed by Analog Devices Inc.
|
|
||||||
|
|
||||||
===========
|
|
||||||
! SUPPORT !
|
|
||||||
===========
|
|
||||||
|
|
||||||
All open source code for the Blackfin processors are being handled via our
|
|
||||||
collaborative website:
|
|
||||||
http://blackfin.uclinux.org/
|
|
||||||
|
|
||||||
In particular, bug reports, feature requests, help etc... for Das U-Boot are
|
|
||||||
handled in the Das U-Boot sub project:
|
|
||||||
http://blackfin.uclinux.org/gf/project/u-boot
|
|
||||||
|
|
||||||
This website is backed both by an open source community as well as a dedicated
|
|
||||||
team from Analog Devices Inc.
|
|
||||||
|
|
||||||
=============
|
|
||||||
! TOOLCHAIN !
|
|
||||||
=============
|
|
||||||
|
|
||||||
To compile the Blackfin aspects, you'll need the GNU toolchain configured for
|
|
||||||
the Blackfin processor. You can obtain such a cross-compiler here:
|
|
||||||
http://blackfin.uclinux.org/gf/project/toolchain
|
|
||||||
|
|
||||||
=================
|
|
||||||
! DOCUMENTATION !
|
|
||||||
=================
|
|
||||||
|
|
||||||
For Blackfin specific documentation, you can visit our dedicated doc wiki:
|
|
||||||
http://docs.blackfin.uclinux.org/doku.php?id=bootloaders:u-boot
|
|
150
doc/README.m68k
150
doc/README.m68k
|
@ -1,150 +0,0 @@
|
||||||
|
|
||||||
U-Boot for Motorola (or Freescale/NXP) ColdFire processors
|
|
||||||
|
|
||||||
===============================================================================
|
|
||||||
History
|
|
||||||
|
|
||||||
November 02, 2017 Angelo Dureghello <angelo@sysam.it>
|
|
||||||
August 08, 2005 Jens Scharsig <esw@bus-elektronik.de>
|
|
||||||
MCF5282 implementation without preloader
|
|
||||||
January 12, 2004 <josef.baumgartner@telex.de>
|
|
||||||
===============================================================================
|
|
||||||
|
|
||||||
|
|
||||||
This file contains status information for the port of U-Boot to the
|
|
||||||
Motorola ColdFire series of CPUs.
|
|
||||||
|
|
||||||
|
|
||||||
1. Overview
|
|
||||||
|
|
||||||
The ColdFire instruction set is "assembly source" compatible but an evolution
|
|
||||||
of the original 68000 instruction set. Some not much used instructions has
|
|
||||||
been removed. The instructions are only 16, 32, or 48 bits long, a
|
|
||||||
simplification compared to the 68000 series.
|
|
||||||
|
|
||||||
Bernhard Kuhn ported U-Boot 0.4.0 to the Motorola ColdFire architecture.
|
|
||||||
The patches of Bernhard support the MCF5272 and MCF5282. A great disadvantage
|
|
||||||
of these patches was that they needed a pre-bootloader to start U-Boot.
|
|
||||||
Because of this, a new port was created which no longer needs a first stage
|
|
||||||
booter.
|
|
||||||
|
|
||||||
Thanks mainly to Freescale but also to several other contributors, U-Boot now
|
|
||||||
supports nearly the entire range of ColdFire processors and their related
|
|
||||||
development boards.
|
|
||||||
|
|
||||||
|
|
||||||
2. Supported CPU families
|
|
||||||
|
|
||||||
Please "make menuconfig" with ARCH=m68k, or check arch/m68k/cpu to see the
|
|
||||||
currently supported processor and families.
|
|
||||||
|
|
||||||
|
|
||||||
3. Supported boards
|
|
||||||
|
|
||||||
U-Boot supports actually more than 40 ColdFire based boards.
|
|
||||||
Board configuration can be done trough include/configs/<boardname>.h but the
|
|
||||||
current recommended method is to use the new and more friendly approach as
|
|
||||||
the "make menuconfig" way, very similar to the Linux way.
|
|
||||||
|
|
||||||
To know details as memory map, build targets, default setup, etc, of a
|
|
||||||
specific board please check:
|
|
||||||
|
|
||||||
include/configs/<boardname>.h
|
|
||||||
and/or
|
|
||||||
configs/<boardname>_defconfig
|
|
||||||
|
|
||||||
It is possible to build all ColdFire boards in a single command-line command,
|
|
||||||
from u-boot root directory, as:
|
|
||||||
|
|
||||||
./tools/buildman/buildman m68k
|
|
||||||
|
|
||||||
|
|
||||||
3.1. Build U-Boot for a specific board
|
|
||||||
|
|
||||||
A bash script similar to the one below may be used:
|
|
||||||
|
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
export CROSS_COMPILE=/opt/toolchains/m68k/gcc-4.9.0-nolibc/bin/m68k-linux-
|
|
||||||
|
|
||||||
board=M5475DFE
|
|
||||||
|
|
||||||
make distclean
|
|
||||||
make ARCH=m68k ${board}_defconfig
|
|
||||||
make ARCH=m68k KBUILD_VERBOSE=1
|
|
||||||
|
|
||||||
|
|
||||||
4. Adopted toolchains
|
|
||||||
|
|
||||||
Please check:
|
|
||||||
https://www.denx.de/wiki/U-Boot/ColdFireNotes
|
|
||||||
|
|
||||||
|
|
||||||
5. ColdFire specific configuration options/settings
|
|
||||||
|
|
||||||
|
|
||||||
5.1. Configuration to use a pre-loader
|
|
||||||
|
|
||||||
If U-Boot should be loaded to RAM and started by a pre-loader
|
|
||||||
CONFIG_MONITOR_IS_IN_RAM must be defined. If it is defined the
|
|
||||||
initial vector table and basic processor initialization will not
|
|
||||||
be compiled in. The start address of U-Boot must be adjusted in
|
|
||||||
the boards config header file (CONFIG_SYS_MONITOR_BASE) and Makefile
|
|
||||||
(CONFIG_SYS_TEXT_BASE) to the load address.
|
|
||||||
|
|
||||||
|
|
||||||
5.2 ColdFire CPU specific options/settings
|
|
||||||
|
|
||||||
To specify a CPU model, some defines shoudl be used, i.e.:
|
|
||||||
|
|
||||||
CONFIG_MCF52x2 -- defined for all MCF52x2 CPUs
|
|
||||||
CONFIG_M5272 -- defined for all Motorola MCF5272 CPUs
|
|
||||||
|
|
||||||
Other options, generally set inside include/configs/<boardname>.h, they may
|
|
||||||
apply to one or more cpu for the ColdFire family:
|
|
||||||
|
|
||||||
CONFIG_SYS_MBAR -- defines the base address of the MCF5272 configuration
|
|
||||||
registers
|
|
||||||
CONFIG_SYS_ENET_BD_BASE
|
|
||||||
-- defines the base address of the FEC buffer descriptors
|
|
||||||
CONFIG_SYS_SCR -- defines the contents of the System Configuration Register
|
|
||||||
CONFIG_SYS_SPR -- defines the contents of the System Protection Register
|
|
||||||
CONFIG_SYS_MFD -- defines the PLL Multiplication Factor Divider
|
|
||||||
(see table 9-4 of MCF user manual)
|
|
||||||
CONFIG_SYS_RFD -- defines the PLL Reduce Frequency Devider
|
|
||||||
(see table 9-4 of MCF user manual)
|
|
||||||
CONFIG_SYS_CSx_BASE
|
|
||||||
-- defines the base address of chip select x
|
|
||||||
CONFIG_SYS_CSx_SIZE
|
|
||||||
-- defines the memory size (address range) of chip select x
|
|
||||||
CONFIG_SYS_CSx_WIDTH
|
|
||||||
-- defines the bus with of chip select x
|
|
||||||
CONFIG_SYS_CSx_MASK
|
|
||||||
-- defines the mask for the related chip select x
|
|
||||||
CONFIG_SYS_CSx_RO
|
|
||||||
-- if set to 0 chip select x is read/write else chip select
|
|
||||||
is read only
|
|
||||||
CONFIG_SYS_CSx_WS
|
|
||||||
-- defines the number of wait states of chip select x
|
|
||||||
CONFIG_SYS_CACHE_ICACR
|
|
||||||
CONFIG_SYS_CACHE_DCACR
|
|
||||||
CONFIG_SYS_CACHE_ACRX
|
|
||||||
-- cache-related registers config
|
|
||||||
CONFIG_SYS_SDRAM_BASE
|
|
||||||
CONFIG_SYS_SDRAM_SIZE
|
|
||||||
CONFIG_SYS_SDRAM_BASEX
|
|
||||||
CONFIG_SYS_SDRAM_CFG1
|
|
||||||
CONFIG_SYS_SDRAM_CFG2
|
|
||||||
CONFIG_SYS_SDRAM_CTRL
|
|
||||||
CONFIG_SYS_SDRAM_MODE
|
|
||||||
CONFIG_SYS_SDRAM_EMOD
|
|
||||||
-- SDRAM config for SDRAM controller-specific registers, please
|
|
||||||
see arch/m68k/cpu/<specific_cpu>/start.S files to see how
|
|
||||||
these options are used.
|
|
||||||
CONFIG_MCFUART
|
|
||||||
-- defines enabling of ColdFire UART driver
|
|
||||||
CONFIG_SYS_UART_PORT
|
|
||||||
-- defines the UART port to be used (only a single UART can be
|
|
||||||
actually enabled)
|
|
||||||
CONFIG_SYS_SBFHDR_SIZE
|
|
||||||
-- size of the prepended SBF header, if any
|
|
|
@ -1,195 +0,0 @@
|
||||||
By Vlad Lungu vlad.lungu@windriver.com 2007-Oct-01
|
|
||||||
----------------------------------------
|
|
||||||
Qemu is a full system emulator. See
|
|
||||||
|
|
||||||
http://www.nongnu.org/qemu/
|
|
||||||
|
|
||||||
Limitations & comments
|
|
||||||
----------------------
|
|
||||||
Supports the "-M mips" configuration of qemu: serial,NE2000,IDE.
|
|
||||||
Supports little and big endian as well as 32 bit and 64 bit.
|
|
||||||
Derived from au1x00 with a lot of things cut out.
|
|
||||||
|
|
||||||
Supports emulated flash (patch Jean-Christophe PLAGNIOL-VILLARD) with
|
|
||||||
recent qemu versions. When using emulated flash, launch with
|
|
||||||
-pflash <filename> and erase mips_bios.bin.
|
|
||||||
|
|
||||||
|
|
||||||
Notes for the Qemu MIPS port
|
|
||||||
----------------------------
|
|
||||||
|
|
||||||
I) Example usage:
|
|
||||||
|
|
||||||
Using u-boot.bin as ROM (replaces Qemu monitor):
|
|
||||||
|
|
||||||
32 bit, big endian:
|
|
||||||
# make qemu_mips
|
|
||||||
# qemu-system-mips -M mips -bios u-boot.bin -nographic
|
|
||||||
|
|
||||||
32 bit, little endian:
|
|
||||||
# make qemu_mipsel
|
|
||||||
# qemu-system-mipsel -M mips -bios u-boot.bin -nographic
|
|
||||||
|
|
||||||
64 bit, big endian:
|
|
||||||
# make qemu_mips64
|
|
||||||
# qemu-system-mips64 -cpu MIPS64R2-generic -M mips -bios u-boot.bin -nographic
|
|
||||||
|
|
||||||
64 bit, little endian:
|
|
||||||
# make qemu_mips64el
|
|
||||||
# qemu-system-mips64el -cpu MIPS64R2-generic -M mips -bios u-boot.bin -nographic
|
|
||||||
|
|
||||||
or using u-boot.bin from emulated flash:
|
|
||||||
|
|
||||||
if you use a qemu version after commit 4224
|
|
||||||
|
|
||||||
create image:
|
|
||||||
# dd of=flash bs=1k count=4k if=/dev/zero
|
|
||||||
# dd of=flash bs=1k conv=notrunc if=u-boot.bin
|
|
||||||
start it (see above):
|
|
||||||
# qemu-system-mips[64][el] [-cpu MIPS64R2-generic] -M mips -pflash flash -nographic
|
|
||||||
|
|
||||||
2) Download kernel + initrd
|
|
||||||
|
|
||||||
On ftp://ftp.denx.de/pub/contrib/Jean-Christophe_Plagniol-Villard/qemu_mips/
|
|
||||||
you can downland
|
|
||||||
|
|
||||||
#config to build the kernel
|
|
||||||
qemu_mips_defconfig
|
|
||||||
#patch to fix mips interrupt init on 2.6.24.y kernel
|
|
||||||
qemu_mips_kernel.patch
|
|
||||||
initrd.gz
|
|
||||||
vmlinux
|
|
||||||
vmlinux.bin
|
|
||||||
System.map
|
|
||||||
|
|
||||||
4) Generate uImage
|
|
||||||
|
|
||||||
# tools/mkimage -A mips -O linux -T kernel -C gzip -a 0x80010000 -e 0x80245650 -n "Linux 2.6.24.y" -d vmlinux.bin.gz uImage
|
|
||||||
|
|
||||||
5) Copy uImage to Flash
|
|
||||||
# dd if=uImage bs=1k conv=notrunc seek=224 of=flash
|
|
||||||
|
|
||||||
6) Generate Ide Disk
|
|
||||||
|
|
||||||
# dd of=ide bs=1k cout=100k if=/dev/zero
|
|
||||||
|
|
||||||
# sfdisk -C 261 -d ide
|
|
||||||
# partition table of ide
|
|
||||||
unit: sectors
|
|
||||||
|
|
||||||
ide1 : start= 63, size= 32067, Id=83
|
|
||||||
ide2 : start= 32130, size= 32130, Id=83
|
|
||||||
ide3 : start= 64260, size= 4128705, Id=83
|
|
||||||
ide4 : start= 0, size= 0, Id= 0
|
|
||||||
|
|
||||||
7) Copy to ide
|
|
||||||
|
|
||||||
# dd if=uImage bs=512 conv=notrunc seek=63 of=ide
|
|
||||||
|
|
||||||
8) Generate ext2 on part 2 on Copy uImage and initrd.gz
|
|
||||||
|
|
||||||
# Attached as loop device ide offset = 32130 * 512
|
|
||||||
# losetup -o 16450560 -f ide
|
|
||||||
# Format as ext2 ( arg2 : nb blocks)
|
|
||||||
# mke2fs /dev/loop0 16065
|
|
||||||
# losetup -d /dev/loop0
|
|
||||||
# Mount and copy uImage and initrd.gz to it
|
|
||||||
# mount -o loop,offset=16450560 -t ext2 ide /mnt
|
|
||||||
# mkdir /mnt/boot
|
|
||||||
# cp {initrd.gz,uImage} /mnt/boot/
|
|
||||||
# Umount it
|
|
||||||
# umount /mnt
|
|
||||||
|
|
||||||
9) Set Environment
|
|
||||||
|
|
||||||
setenv rd_start 0x80800000
|
|
||||||
setenv rd_size 2663940
|
|
||||||
setenv kernel BFC38000
|
|
||||||
setenv oad_addr 80500000
|
|
||||||
setenv load_addr2 80F00000
|
|
||||||
setenv kernel_flash BFC38000
|
|
||||||
setenv load_addr_hello 80200000
|
|
||||||
setenv bootargs 'root=/dev/ram0 init=/bin/sh'
|
|
||||||
setenv load_rd_ext2 'ide res; ext2load ide 0:2 ${rd_start} /boot/initrd.gz'
|
|
||||||
setenv load_rd_tftp 'tftp ${rd_start} /initrd.gz'
|
|
||||||
setenv load_kernel_hda 'ide res; diskboot ${load_addr} 0:2'
|
|
||||||
setenv load_kernel_ext2 'ide res; ext2load ide 0:2 ${load_addr} /boot/uImage'
|
|
||||||
setenv load_kernel_tftp 'tftp ${load_addr} /qemu_mips/uImage'
|
|
||||||
setenv boot_ext2_ext2 'run load_rd_ext2; run load_kernel_ext2; run addmisc; bootm ${load_addr}'
|
|
||||||
setenv boot_ext2_flash 'run load_rd_ext2; run addmisc; bootm ${kernel_flash}'
|
|
||||||
setenv boot_ext2_hda 'run load_rd_ext2; run load_kernel_hda; run addmisc; bootm ${load_addr}'
|
|
||||||
setenv boot_ext2_tftp 'run load_rd_ext2; run load_kernel_tftp; run addmisc; bootm ${load_addr}'
|
|
||||||
setenv boot_tftp_hda 'run load_rd_tftp; run load_kernel_hda; run addmisc; bootm ${load_addr}'
|
|
||||||
setenv boot_tftp_ext2 'run load_rd_tftp; run load_kernel_ext2; run addmisc; bootm ${load_addr}'
|
|
||||||
setenv boot_tftp_flash 'run load_rd_tftp; run addmisc; bootm ${kernel_flash}'
|
|
||||||
setenv boot_tftp_tftp 'run load_rd_tftp; run load_kernel_tftp; run addmisc; bootm ${load_addr}'
|
|
||||||
setenv load_hello_tftp 'tftp ${load_addr_hello} /examples/hello_world.bin'
|
|
||||||
setenv go_tftp 'run load_hello_tftp; go ${load_addr_hello}'
|
|
||||||
setenv addmisc 'setenv bootargs ${bootargs} console=ttyS0,${baudrate} rd_start=${rd_start} rd_size=${rd_size} ethaddr=${ethaddr}'
|
|
||||||
setenv bootcmd 'run boot_tftp_flash'
|
|
||||||
|
|
||||||
10) Now you can boot from flash, ide, ide+ext2 and tfp
|
|
||||||
|
|
||||||
# qemu-system-mips -M mips -pflash flash -monitor null -nographic -net nic -net user -tftp `pwd` -hda ide
|
|
||||||
|
|
||||||
II) How to debug U-Boot
|
|
||||||
|
|
||||||
In order to debug U-Boot you need to start qemu with gdb server support (-s)
|
|
||||||
and waiting the connection to start the CPU (-S)
|
|
||||||
|
|
||||||
# qemu-system-mips -S -s -M mips -pflash flash -monitor null -nographic -net nic -net user -tftp `pwd` -hda ide
|
|
||||||
|
|
||||||
in an other console you start gdb
|
|
||||||
|
|
||||||
1) Debugging of U-Boot Before Relocation
|
|
||||||
|
|
||||||
Before relocation, the addresses in the ELF file can be used without any problems
|
|
||||||
by connecting to the gdb server localhost:1234
|
|
||||||
|
|
||||||
# mipsel-unknown-linux-gnu-gdb u-boot
|
|
||||||
GNU gdb 6.6
|
|
||||||
Copyright (C) 2006 Free Software Foundation, Inc.
|
|
||||||
GDB is free software, covered by the GNU General Public License, and you are
|
|
||||||
welcome to change it and/or distribute copies of it under certain conditions.
|
|
||||||
Type "show copying" to see the conditions.
|
|
||||||
There is absolutely no warranty for GDB. Type "show warranty" for details.
|
|
||||||
This GDB was configured as "--host=i486-linux-gnu --target=mipsel-unknown-linux-gnu"...
|
|
||||||
(gdb) target remote localhost:1234
|
|
||||||
Remote debugging using localhost:1234
|
|
||||||
_start () at start.S:64
|
|
||||||
64 RVECENT(reset,0) /* U-Boot entry point */
|
|
||||||
Current language: auto; currently asm
|
|
||||||
(gdb) b board.c:289
|
|
||||||
Breakpoint 1 at 0xbfc00cc8: file board.c, line 289.
|
|
||||||
(gdb) c
|
|
||||||
Continuing.
|
|
||||||
|
|
||||||
Breakpoint 1, board_init_f (bootflag=<value optimized out>) at board.c:290
|
|
||||||
290 relocate_code (addr_sp, id, addr);
|
|
||||||
Current language: auto; currently c
|
|
||||||
(gdb) p/x addr
|
|
||||||
$1 = 0x87fa0000
|
|
||||||
|
|
||||||
2) Debugging of U-Boot After Relocation
|
|
||||||
|
|
||||||
For debugging U-Boot after relocation we need to know the address to which
|
|
||||||
U-Boot relocates itself to 0x87fa0000 by default.
|
|
||||||
And replace the symbol table to this offset.
|
|
||||||
|
|
||||||
(gdb) symbol-file
|
|
||||||
Discard symbol table from `/private/u-boot-arm/u-boot'? (y or n) y
|
|
||||||
Error in re-setting breakpoint 1:
|
|
||||||
No symbol table is loaded. Use the "file" command.
|
|
||||||
No symbol file now.
|
|
||||||
(gdb) add-symbol-file u-boot 0x87fa0000
|
|
||||||
add symbol table from file "u-boot" at
|
|
||||||
.text_addr = 0x87fa0000
|
|
||||||
(y or n) y
|
|
||||||
Reading symbols from /private/u-boot-arm/u-boot...done.
|
|
||||||
Breakpoint 1 at 0x87fa0cc8: file board.c, line 289.
|
|
||||||
(gdb) c
|
|
||||||
Continuing.
|
|
||||||
|
|
||||||
Program received signal SIGINT, Interrupt.
|
|
||||||
0xffffffff87fa0de4 in udelay (usec=<value optimized out>) at time.c:78
|
|
||||||
78 while ((tmo - read_c0_count()) < 0x7fffffff)
|
|
|
@ -1,97 +0,0 @@
|
||||||
|
|
||||||
U-Boot for Renesas SuperH
|
|
||||||
Last update 01/18/2008 by Nobuhiro Iwamatsu
|
|
||||||
|
|
||||||
================================================================================
|
|
||||||
0. What's this?
|
|
||||||
This file contains status information for the port of U-Boot to the
|
|
||||||
Renesas SuperH series of CPUs.
|
|
||||||
|
|
||||||
================================================================================
|
|
||||||
1. Overview
|
|
||||||
SuperH has an original boot loader. However, source code is dirty, and
|
|
||||||
maintenance is not done.
|
|
||||||
To improve sharing and the maintenance of the code, Nobuhiro Iwamatsu
|
|
||||||
started the porting to u-boot in 2007.
|
|
||||||
|
|
||||||
================================================================================
|
|
||||||
2. Supported CPUs
|
|
||||||
|
|
||||||
2.1. Renesas SH7750/SH7750R
|
|
||||||
This CPU has the SH4 core.
|
|
||||||
|
|
||||||
2.2. Renesas SH7722
|
|
||||||
This CPU has the SH4AL-DSP core.
|
|
||||||
|
|
||||||
2.3. Renesas SH7780
|
|
||||||
This CPU has the SH4A core.
|
|
||||||
|
|
||||||
================================================================================
|
|
||||||
3. Supported Boards
|
|
||||||
|
|
||||||
3.1. Hitachi UL MS7750SE01/MS7750RSE01
|
|
||||||
Board specific code is in board/ms7750se
|
|
||||||
To use this board, type "make ms7750se_config".
|
|
||||||
Support devices are :
|
|
||||||
- SCIF
|
|
||||||
- SDRAM
|
|
||||||
- NOR Flash
|
|
||||||
- Marubun PCMCIA
|
|
||||||
|
|
||||||
3.2. Hitachi UL MS7722SE01
|
|
||||||
Board specific code is in board/ms7722se
|
|
||||||
To use this board, type "make ms7722se_config".
|
|
||||||
Support devices are :
|
|
||||||
- SCIF
|
|
||||||
- SDRAM
|
|
||||||
- NOR Flash
|
|
||||||
- Marubun PCMCIA
|
|
||||||
- SMC91x ethernet
|
|
||||||
|
|
||||||
3.2. Hitachi UL MS7720ERP01
|
|
||||||
Board specific code is in board/ms7720se
|
|
||||||
To use this board, type "make ms7720se_config".
|
|
||||||
Support devices are :
|
|
||||||
- SCIF
|
|
||||||
- SDRAM
|
|
||||||
- NOR Flash
|
|
||||||
- Marubun PCMCIA
|
|
||||||
|
|
||||||
3.3. Renesas R7780MP
|
|
||||||
Board specific code is in board/r7780mp
|
|
||||||
To use this board, type "make r7780mp_config".
|
|
||||||
Support devices are :
|
|
||||||
- SCIF
|
|
||||||
- DDR-SDRAM
|
|
||||||
- NOR Flash
|
|
||||||
- Compact Flash
|
|
||||||
- ASIX ethernet
|
|
||||||
- SH7780 PCI bridge
|
|
||||||
- RTL8110 ethernet
|
|
||||||
|
|
||||||
** README **
|
|
||||||
In SuperH, S-record and binary of made u-boot work on the memory.
|
|
||||||
When u-boot is written in the flash, it is necessary to change the
|
|
||||||
address by using 'objcopy'.
|
|
||||||
ex) shX-linux-objcopy -Ibinary -Osrec u-boot.bin u-boot.flash.srec
|
|
||||||
|
|
||||||
================================================================================
|
|
||||||
4. Compiler
|
|
||||||
You can use the following of u-boot to compile.
|
|
||||||
- SuperH Linux Open site
|
|
||||||
http://www.superh-linux.org/
|
|
||||||
- KPIT GNU tools
|
|
||||||
http://www.kpitgnutools.com/
|
|
||||||
|
|
||||||
================================================================================
|
|
||||||
5. Future
|
|
||||||
I plan to support the following CPUs and boards.
|
|
||||||
5.1. CPUs
|
|
||||||
- SH7751R(SH4)
|
|
||||||
|
|
||||||
5.2. Boards
|
|
||||||
- Many boards ;-)
|
|
||||||
|
|
||||||
================================================================================
|
|
||||||
Copyright (c) 2007,2008
|
|
||||||
Nobuhiro Iwamatsu <iwamatsu@nigaur.org>
|
|
|
@ -1,67 +0,0 @@
|
||||||
========================================
|
|
||||||
Renesas R0P7752C00000RZ board
|
|
||||||
========================================
|
|
||||||
|
|
||||||
This board specification:
|
|
||||||
=========================
|
|
||||||
|
|
||||||
The R0P7752C00000RZ(board config name:sh7752evb) has the following device:
|
|
||||||
|
|
||||||
- SH7752 (SH-4A)
|
|
||||||
- DDR3-SDRAM 512MB
|
|
||||||
- SPI ROM 8MB
|
|
||||||
- Gigabit Ethernet controllers
|
|
||||||
- eMMC 4GB
|
|
||||||
|
|
||||||
|
|
||||||
Configuration for This board:
|
|
||||||
=============================
|
|
||||||
|
|
||||||
You can select the configuration as follows:
|
|
||||||
|
|
||||||
- make sh7752evb_config
|
|
||||||
|
|
||||||
|
|
||||||
This board specific command:
|
|
||||||
============================
|
|
||||||
|
|
||||||
This board has the following its specific command:
|
|
||||||
|
|
||||||
- write_mac
|
|
||||||
|
|
||||||
|
|
||||||
1. write_mac
|
|
||||||
|
|
||||||
You can write MAC address to SPI ROM.
|
|
||||||
|
|
||||||
Usage 1) Write MAC address
|
|
||||||
|
|
||||||
write_mac [GETHERC ch0] [GETHERC ch1]
|
|
||||||
|
|
||||||
For example)
|
|
||||||
=> write_mac 74:90:50:00:33:9e 74:90:50:00:33:9f
|
|
||||||
*) We have to input the command as a single line
|
|
||||||
(without carriage return)
|
|
||||||
*) We have to reset after input the command.
|
|
||||||
|
|
||||||
Usage 2) Show current data
|
|
||||||
|
|
||||||
write_mac
|
|
||||||
|
|
||||||
For example)
|
|
||||||
=> write_mac
|
|
||||||
GETHERC ch0 = 74:90:50:00:33:9e
|
|
||||||
GETHERC ch1 = 74:90:50:00:33:9f
|
|
||||||
|
|
||||||
|
|
||||||
Update SPI ROM:
|
|
||||||
============================
|
|
||||||
|
|
||||||
1. Copy u-boot image to RAM area.
|
|
||||||
2. Probe SPI device.
|
|
||||||
=> sf probe 0
|
|
||||||
SF: Detected MX25L6405D with page size 64KiB, total 8 MiB
|
|
||||||
3. Erase SPI ROM.
|
|
||||||
=> sf erase 0 80000
|
|
||||||
4. Write u-boot image to SPI ROM.
|
|
||||||
=> sf write 0x48000000 0 80000
|
|
|
@ -1,67 +0,0 @@
|
||||||
========================================
|
|
||||||
Renesas SH7753 EVB board
|
|
||||||
========================================
|
|
||||||
|
|
||||||
This board specification:
|
|
||||||
=========================
|
|
||||||
|
|
||||||
The SH7753 EVB (board config name:sh7753evb) has the following device:
|
|
||||||
|
|
||||||
- SH7753 (SH-4A)
|
|
||||||
- DDR3-SDRAM 512MB
|
|
||||||
- SPI ROM 8MB
|
|
||||||
- Gigabit Ethernet controllers
|
|
||||||
- eMMC 4GB
|
|
||||||
|
|
||||||
|
|
||||||
Configuration for This board:
|
|
||||||
=============================
|
|
||||||
|
|
||||||
You can select the configuration as follows:
|
|
||||||
|
|
||||||
- make sh7753evb_config
|
|
||||||
|
|
||||||
|
|
||||||
This board specific command:
|
|
||||||
============================
|
|
||||||
|
|
||||||
This board has the following its specific command:
|
|
||||||
|
|
||||||
- write_mac
|
|
||||||
|
|
||||||
|
|
||||||
1. write_mac
|
|
||||||
|
|
||||||
You can write MAC address to SPI ROM.
|
|
||||||
|
|
||||||
Usage 1) Write MAC address
|
|
||||||
|
|
||||||
write_mac [GETHERC ch0] [GETHERC ch1]
|
|
||||||
|
|
||||||
For example)
|
|
||||||
=> write_mac 74:90:50:00:33:9e 74:90:50:00:33:9f
|
|
||||||
*) We have to input the command as a single line
|
|
||||||
(without carriage return)
|
|
||||||
*) We have to reset after input the command.
|
|
||||||
|
|
||||||
Usage 2) Show current data
|
|
||||||
|
|
||||||
write_mac
|
|
||||||
|
|
||||||
For example)
|
|
||||||
=> write_mac
|
|
||||||
GETHERC ch0 = 74:90:50:00:33:9e
|
|
||||||
GETHERC ch1 = 74:90:50:00:33:9f
|
|
||||||
|
|
||||||
|
|
||||||
Update SPI ROM:
|
|
||||||
============================
|
|
||||||
|
|
||||||
1. Copy u-boot image to RAM area.
|
|
||||||
2. Probe SPI device.
|
|
||||||
=> sf probe 0
|
|
||||||
SF: Detected MX25L6405D with page size 64KiB, total 8 MiB
|
|
||||||
3. Erase SPI ROM.
|
|
||||||
=> sf erase 0 80000
|
|
||||||
4. Write u-boot image to SPI ROM.
|
|
||||||
=> sf write 0x48000000 0 80000
|
|
|
@ -1,273 +0,0 @@
|
||||||
FU540-C000 RISC-V SoC
|
|
||||||
=====================
|
|
||||||
The FU540-C000 is the world’s first 4+1 64-bit RISC‑V SoC from SiFive.
|
|
||||||
|
|
||||||
The HiFive Unleashed development platform is based on FU540-C000 and capable
|
|
||||||
of running Linux.
|
|
||||||
|
|
||||||
Mainline support
|
|
||||||
================
|
|
||||||
The support for following drivers are already enabled:
|
|
||||||
1. SiFive UART Driver.
|
|
||||||
2. SiFive PRCI Driver for clock.
|
|
||||||
3. Cadence MACB ethernet driver for networking support.
|
|
||||||
|
|
||||||
TODO:
|
|
||||||
1. U-Boot expects the serial console device entry to be present under /chosen
|
|
||||||
DT node. Example:
|
|
||||||
chosen {
|
|
||||||
stdout-path = "/soc/serial@10010000:115200";
|
|
||||||
};
|
|
||||||
|
|
||||||
Without a serial console U-Boot will panic.
|
|
||||||
|
|
||||||
Building
|
|
||||||
========
|
|
||||||
1. Add the RISC-V toolchain to your PATH.
|
|
||||||
2. Setup ARCH & cross compilation enviornment variable.
|
|
||||||
a. export ARCH=riscv
|
|
||||||
b. export CROSS_COMPILE=<riscv64 toolchain prefix>
|
|
||||||
3. make sifive_fu540_defconfig
|
|
||||||
4. make
|
|
||||||
|
|
||||||
Flashing
|
|
||||||
========
|
|
||||||
The current U-Boot port is supported in S-mode only and loaded directly
|
|
||||||
into DRAM.
|
|
||||||
|
|
||||||
A prior stage (M-mode) firmware/bootloader (e.g OpenSBI) is required to
|
|
||||||
boot the u-boot.bin in S-mode and provide M-mode runtime services.
|
|
||||||
|
|
||||||
Currently, the u-boot.bin is used as a payload of the OpenSBI FW_PAYLOAD
|
|
||||||
firmware. We need to compile OpenSBI with below command:
|
|
||||||
make PLATFORM=sifive/fu540 FW_PAYLOAD_PATH=<path to u-boot.bin> FW_PAYLOAD_FDT_PATH=<path to hifive-unleashed-a00.dtb from Linux>
|
|
||||||
(Note: Prefer hifive-unleashed-a00.dtb from Linux-5.3 or higher)
|
|
||||||
(Note: Linux-5.2 is also fine but it does not have ethernet DT node)
|
|
||||||
|
|
||||||
More detailed description of steps required to build FW_PAYLOAD firmware
|
|
||||||
is beyond the scope of this document. Please refer OpenSBI documenation.
|
|
||||||
(Note: OpenSBI git repo is at https://github.com/riscv/opensbi.git)
|
|
||||||
|
|
||||||
Once the prior stage firmware/bootloader binary is generated, it should be
|
|
||||||
copied to the first partition of the sdcard.
|
|
||||||
|
|
||||||
sudo dd if=<prior_stage_firmware_binary> of=/dev/disk2s1 bs=1024
|
|
||||||
|
|
||||||
Booting
|
|
||||||
=======
|
|
||||||
Once you plugin the sdcard and power up, you should see the U-Boot prompt.
|
|
||||||
|
|
||||||
Sample boot log from HiFive Unleashed board
|
|
||||||
===========================================
|
|
||||||
U-Boot 2019.07-rc4-00013-g1837f893b0 (Jun 20 2019 - 11:08:48 +0530)
|
|
||||||
|
|
||||||
CPU: rv64imafdc
|
|
||||||
Model: SiFive HiFive Unleashed A00
|
|
||||||
DRAM: 8 GiB
|
|
||||||
In: serial@10010000
|
|
||||||
Out: serial@10010000
|
|
||||||
Err: serial@10010000
|
|
||||||
Net: eth0: ethernet@10090000
|
|
||||||
Hit any key to stop autoboot: 0
|
|
||||||
=> version
|
|
||||||
U-Boot 2019.07-rc4-00013-g1837f893b0 (Jun 20 2019 - 11:08:48 +0530)
|
|
||||||
|
|
||||||
riscv64-linux-gcc.br_real (Buildroot 2018.11-rc2-00003-ga0787e9) 8.2.0
|
|
||||||
GNU ld (GNU Binutils) 2.31.1
|
|
||||||
=>
|
|
||||||
===============================================================================
|
|
||||||
|
|
||||||
Now you can configure your networking, tftp server and use tftp boot method to
|
|
||||||
load uImage.
|
|
||||||
|
|
||||||
==========================================================================
|
|
||||||
=> setenv ipaddr 10.206.5.241
|
|
||||||
=> setenv netmask 255.255.252.0
|
|
||||||
=> setenv serverip 10.206.4.143
|
|
||||||
=> setenv gateway 10.206.4.1
|
|
||||||
=> tftpboot ${kernel_addr_r} /sifive/fu540/uImage
|
|
||||||
ethernet@10090000: PHY present at 0
|
|
||||||
ethernet@10090000: Starting autonegotiation...
|
|
||||||
ethernet@10090000: Autonegotiation complete
|
|
||||||
ethernet@10090000: link up, 1000Mbps full-duplex (lpa: 0x7c00)
|
|
||||||
Using ethernet@10090000 device
|
|
||||||
TFTP from server 10.206.4.143; our IP address is 10.206.5.241
|
|
||||||
Filename '/sifive/fu540/uImage'.
|
|
||||||
Load address: 0x80600000
|
|
||||||
Loading: #################################################################
|
|
||||||
#################################################################
|
|
||||||
#################################################################
|
|
||||||
#################################################################
|
|
||||||
#################################################################
|
|
||||||
#################################################################
|
|
||||||
#################################################################
|
|
||||||
#################################################################
|
|
||||||
#################################################################
|
|
||||||
########################################
|
|
||||||
1.5 MiB/s
|
|
||||||
done
|
|
||||||
Bytes transferred = 9162364 (8bce7c hex)
|
|
||||||
=> tftpboot ${ramdisk_addr_r} /sifive/fu540/uRamdisk
|
|
||||||
ethernet@10090000: PHY present at 0
|
|
||||||
ethernet@10090000: Starting autonegotiation...
|
|
||||||
ethernet@10090000: Autonegotiation complete
|
|
||||||
ethernet@10090000: link up, 1000Mbps full-duplex (lpa: 0x7c00)
|
|
||||||
Using ethernet@10090000 device
|
|
||||||
TFTP from server 10.206.4.143; our IP address is 10.206.5.241
|
|
||||||
Filename '/sifive/fu540/uRamdisk'.
|
|
||||||
Load address: 0x82500000
|
|
||||||
Loading: #################################################################
|
|
||||||
#################################################################
|
|
||||||
##################################
|
|
||||||
448.2 KiB/s
|
|
||||||
done
|
|
||||||
Bytes transferred = 2398272 (249840 hex)
|
|
||||||
=> setenv bootargs "root=/dev/ram rw console=ttySIF0 earlycon=sbi"
|
|
||||||
=> bootm ${kernel_addr_r} ${ramdisk_addr_r} ${fdtcontroladdr}
|
|
||||||
## Booting kernel from Legacy Image at 80600000 ...
|
|
||||||
Image Name: Linux
|
|
||||||
Image Type: RISC-V Linux Kernel Image (uncompressed)
|
|
||||||
Data Size: 9162300 Bytes = 8.7 MiB
|
|
||||||
Load Address: 80200000
|
|
||||||
Entry Point: 80200000
|
|
||||||
Verifying Checksum ... OK
|
|
||||||
## Loading init Ramdisk from Legacy Image at 82500000 ...
|
|
||||||
Image Name: Linux RootFS
|
|
||||||
Image Type: RISC-V Linux RAMDisk Image (uncompressed)
|
|
||||||
Data Size: 2398208 Bytes = 2.3 MiB
|
|
||||||
Load Address: 00000000
|
|
||||||
Entry Point: 00000000
|
|
||||||
Verifying Checksum ... OK
|
|
||||||
## Flattened Device Tree blob at ff795730
|
|
||||||
Booting using the fdt blob at 0xff795730
|
|
||||||
Loading Kernel Image ... OK
|
|
||||||
Using Device Tree in place at 00000000ff795730, end 00000000ff799dac
|
|
||||||
|
|
||||||
Starting kernel ...
|
|
||||||
|
|
||||||
[ 0.000000] OF: fdt: Ignoring memory range 0x80000000 - 0x80200000
|
|
||||||
[ 0.000000] Linux version 5.2.0-rc1-00003-gb9543e66e700 (anup@anup-lab-machine) (gcc version 8.2.0 (Buildroot 2018.11-rc2-00003-ga0787e9)) #1 SMP Thu Jun 20 11:41:26 IST 2019
|
|
||||||
[ 0.000000] earlycon: sbi0 at I/O port 0x0 (options '')
|
|
||||||
[ 0.000000] printk: bootconsole [sbi0] enabled
|
|
||||||
[ 0.000000] Initial ramdisk at: 0x(____ptrval____) (2398208 bytes)
|
|
||||||
[ 0.000000] Zone ranges:
|
|
||||||
[ 0.000000] DMA32 [mem 0x0000000080200000-0x00000000ffffffff]
|
|
||||||
[ 0.000000] Normal [mem 0x0000000100000000-0x000000027fffffff]
|
|
||||||
[ 0.000000] Movable zone start for each node
|
|
||||||
[ 0.000000] Early memory node ranges
|
|
||||||
[ 0.000000] node 0: [mem 0x0000000080200000-0x000000027fffffff]
|
|
||||||
[ 0.000000] Initmem setup node 0 [mem 0x0000000080200000-0x000000027fffffff]
|
|
||||||
[ 0.000000] software IO TLB: mapped [mem 0xfb795000-0xff795000] (64MB)
|
|
||||||
[ 0.000000] CPU with hartid=0 is not available
|
|
||||||
[ 0.000000] CPU with hartid=0 is not available
|
|
||||||
[ 0.000000] elf_hwcap is 0x112d
|
|
||||||
[ 0.000000] percpu: Embedded 17 pages/cpu s29592 r8192 d31848 u69632
|
|
||||||
[ 0.000000] Built 1 zonelists, mobility grouping on. Total pages: 2067975
|
|
||||||
[ 0.000000] Kernel command line: root=/dev/ram rw console=ttySIF0 earlycon=sbi
|
|
||||||
[ 0.000000] Dentry cache hash table entries: 1048576 (order: 11, 8388608 bytes)
|
|
||||||
[ 0.000000] Inode-cache hash table entries: 524288 (order: 10, 4194304 bytes)
|
|
||||||
[ 0.000000] Sorting __ex_table...
|
|
||||||
[ 0.000000] Memory: 8182056K/8386560K available (5753K kernel code, 357K rwdata, 1804K rodata, 204K init, 808K bss, 204504K reserved, 0K cma-reserved)
|
|
||||||
[ 0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=4, Nodes=1
|
|
||||||
[ 0.000000] rcu: Hierarchical RCU implementation.
|
|
||||||
[ 0.000000] rcu: RCU restricting CPUs from NR_CPUS=8 to nr_cpu_ids=4.
|
|
||||||
[ 0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 25 jiffies.
|
|
||||||
[ 0.000000] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=4
|
|
||||||
[ 0.000000] NR_IRQS: 0, nr_irqs: 0, preallocated irqs: 0
|
|
||||||
[ 0.000000] plic: mapped 53 interrupts with 4 handlers for 9 contexts.
|
|
||||||
[ 0.000000] riscv_timer_init_dt: Registering clocksource cpuid [0] hartid [2]
|
|
||||||
[ 0.000000] clocksource: riscv_clocksource: mask: 0xffffffffffffffff max_cycles: 0x1d854df40, max_idle_ns: 3526361616960 ns
|
|
||||||
[ 0.000007] sched_clock: 64 bits at 1000kHz, resolution 1000ns, wraps every 2199023255500ns
|
|
||||||
[ 0.008553] Console: colour dummy device 80x25
|
|
||||||
[ 0.012990] Calibrating delay loop (skipped), value calculated using timer frequency.. 2.00 BogoMIPS (lpj=4000)
|
|
||||||
[ 0.023103] pid_max: default: 32768 minimum: 301
|
|
||||||
[ 0.028269] Mount-cache hash table entries: 16384 (order: 5, 131072 bytes)
|
|
||||||
[ 0.035068] Mountpoint-cache hash table entries: 16384 (order: 5, 131072 bytes)
|
|
||||||
[ 0.042770] *** VALIDATE proc ***
|
|
||||||
[ 0.045610] *** VALIDATE cgroup1 ***
|
|
||||||
[ 0.049157] *** VALIDATE cgroup2 ***
|
|
||||||
[ 0.053743] rcu: Hierarchical SRCU implementation.
|
|
||||||
[ 0.058297] smp: Bringing up secondary CPUs ...
|
|
||||||
[ 0.064134] smp: Brought up 1 node, 4 CPUs
|
|
||||||
[ 0.069114] devtmpfs: initialized
|
|
||||||
[ 0.073281] random: get_random_u32 called from bucket_table_alloc.isra.10+0x4e/0x160 with crng_init=0
|
|
||||||
[ 0.082157] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns
|
|
||||||
[ 0.091634] futex hash table entries: 1024 (order: 4, 65536 bytes)
|
|
||||||
[ 0.098480] NET: Registered protocol family 16
|
|
||||||
[ 0.114101] vgaarb: loaded
|
|
||||||
[ 0.116397] SCSI subsystem initialized
|
|
||||||
[ 0.120358] usbcore: registered new interface driver usbfs
|
|
||||||
[ 0.125541] usbcore: registered new interface driver hub
|
|
||||||
[ 0.130936] usbcore: registered new device driver usb
|
|
||||||
[ 0.136618] clocksource: Switched to clocksource riscv_clocksource
|
|
||||||
[ 0.148108] NET: Registered protocol family 2
|
|
||||||
[ 0.152358] tcp_listen_portaddr_hash hash table entries: 4096 (order: 4, 65536 bytes)
|
|
||||||
[ 0.159928] TCP established hash table entries: 65536 (order: 7, 524288 bytes)
|
|
||||||
[ 0.169027] TCP bind hash table entries: 65536 (order: 8, 1048576 bytes)
|
|
||||||
[ 0.178360] TCP: Hash tables configured (established 65536 bind 65536)
|
|
||||||
[ 0.184653] UDP hash table entries: 4096 (order: 5, 131072 bytes)
|
|
||||||
[ 0.190819] UDP-Lite hash table entries: 4096 (order: 5, 131072 bytes)
|
|
||||||
[ 0.197618] NET: Registered protocol family 1
|
|
||||||
[ 0.201892] RPC: Registered named UNIX socket transport module.
|
|
||||||
[ 0.207395] RPC: Registered udp transport module.
|
|
||||||
[ 0.212159] RPC: Registered tcp transport module.
|
|
||||||
[ 0.216940] RPC: Registered tcp NFSv4.1 backchannel transport module.
|
|
||||||
[ 0.223445] PCI: CLS 0 bytes, default 64
|
|
||||||
[ 0.227726] Unpacking initramfs...
|
|
||||||
[ 0.260556] Freeing initrd memory: 2336K
|
|
||||||
[ 0.264652] workingset: timestamp_bits=62 max_order=21 bucket_order=0
|
|
||||||
[ 0.278452] NFS: Registering the id_resolver key type
|
|
||||||
[ 0.282841] Key type id_resolver registered
|
|
||||||
[ 0.287067] Key type id_legacy registered
|
|
||||||
[ 0.291155] nfs4filelayout_init: NFSv4 File Layout Driver Registering...
|
|
||||||
[ 0.298299] NET: Registered protocol family 38
|
|
||||||
[ 0.302470] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 254)
|
|
||||||
[ 0.309906] io scheduler mq-deadline registered
|
|
||||||
[ 0.314501] io scheduler kyber registered
|
|
||||||
[ 0.354134] Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled
|
|
||||||
[ 0.360725] 10010000.serial: ttySIF0 at MMIO 0x10010000 (irq = 4, base_baud = 0) is a SiFive UART v0
|
|
||||||
[ 0.369191] printk: console [ttySIF0] enabled
|
|
||||||
[ 0.369191] printk: console [ttySIF0] enabled
|
|
||||||
[ 0.377938] printk: bootconsole [sbi0] disabled
|
|
||||||
[ 0.377938] printk: bootconsole [sbi0] disabled
|
|
||||||
[ 0.387298] 10011000.serial: ttySIF1 at MMIO 0x10011000 (irq = 1, base_baud = 0) is a SiFive UART v0
|
|
||||||
[ 0.396411] [drm] radeon kernel modesetting enabled.
|
|
||||||
[ 0.409818] loop: module loaded
|
|
||||||
[ 0.412606] libphy: Fixed MDIO Bus: probed
|
|
||||||
[ 0.416870] macb 10090000.ethernet: Registered clk switch 'sifive-gemgxl-mgmt'
|
|
||||||
[ 0.423570] macb: GEM doesn't support hardware ptp.
|
|
||||||
[ 0.428469] libphy: MACB_mii_bus: probed
|
|
||||||
[ 1.053009] Microsemi VSC8541 SyncE 10090000.ethernet-ffffffff:00: attached PHY driver [Microsemi VSC8541 SyncE] (mii_bus:phy_addr=10090000.ethernet-ffffffff:00, irq=POLL)
|
|
||||||
[ 1.067548] macb 10090000.ethernet eth0: Cadence GEM rev 0x10070109 at 0x10090000 irq 7 (70:b3:d5:92:f2:f3)
|
|
||||||
[ 1.077330] e1000e: Intel(R) PRO/1000 Network Driver - 3.2.6-k
|
|
||||||
[ 1.083069] e1000e: Copyright(c) 1999 - 2015 Intel Corporation.
|
|
||||||
[ 1.089061] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
|
|
||||||
[ 1.095485] ehci-pci: EHCI PCI platform driver
|
|
||||||
[ 1.099947] ehci-platform: EHCI generic platform driver
|
|
||||||
[ 1.105196] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
|
|
||||||
[ 1.111286] ohci-pci: OHCI PCI platform driver
|
|
||||||
[ 1.115742] ohci-platform: OHCI generic platform driver
|
|
||||||
[ 1.121142] usbcore: registered new interface driver uas
|
|
||||||
[ 1.126269] usbcore: registered new interface driver usb-storage
|
|
||||||
[ 1.132331] mousedev: PS/2 mouse device common for all mice
|
|
||||||
[ 1.137978] usbcore: registered new interface driver usbhid
|
|
||||||
[ 1.143325] usbhid: USB HID core driver
|
|
||||||
[ 1.148022] NET: Registered protocol family 10
|
|
||||||
[ 1.152609] Segment Routing with IPv6
|
|
||||||
[ 1.155571] sit: IPv6, IPv4 and MPLS over IPv4 tunneling driver
|
|
||||||
[ 1.161927] NET: Registered protocol family 17
|
|
||||||
[ 1.165907] Key type dns_resolver registered
|
|
||||||
[ 1.171694] Freeing unused kernel memory: 204K
|
|
||||||
[ 1.175375] This architecture does not have kernel memory protection.
|
|
||||||
[ 1.181792] Run /init as init process
|
|
||||||
_ _
|
|
||||||
| ||_|
|
|
||||||
| | _ ____ _ _ _ _
|
|
||||||
| || | _ \| | | |\ \/ /
|
|
||||||
| || | | | | |_| |/ \
|
|
||||||
|_||_|_| |_|\____|\_/\_/
|
|
||||||
|
|
||||||
Busybox Rootfs
|
|
||||||
|
|
||||||
Please press Enter to activate this console.
|
|
||||||
/ #
|
|
11
doc/api/index.rst
Normal file
11
doc/api/index.rst
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
.. SPDX-License-Identifier: GPL-2.0+
|
||||||
|
|
||||||
|
U-Boot API documentation
|
||||||
|
========================
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 2
|
||||||
|
|
||||||
|
efi
|
||||||
|
linker_lists
|
||||||
|
serial
|
|
@ -1,3 +1,8 @@
|
||||||
|
.. SPDX-License-Identifier: GPL-2.0+
|
||||||
|
|
||||||
|
ARC
|
||||||
|
===
|
||||||
|
|
||||||
Synopsys' DesignWare(r) ARC(r) Processors are a family of 32-bit CPUs
|
Synopsys' DesignWare(r) ARC(r) Processors are a family of 32-bit CPUs
|
||||||
that SoC designers can optimize for a wide range of uses, from deeply embedded
|
that SoC designers can optimize for a wide range of uses, from deeply embedded
|
||||||
to high-performance host applications.
|
to high-performance host applications.
|
|
@ -1,14 +1,17 @@
|
||||||
U-Boot for arm64
|
.. SPDX-License-Identifier: GPL-2.0+
|
||||||
|
|
||||||
|
ARM64
|
||||||
|
=====
|
||||||
|
|
||||||
Summary
|
Summary
|
||||||
=======
|
-------
|
||||||
The initial arm64 U-Boot port was developed before hardware was available,
|
The initial arm64 U-Boot port was developed before hardware was available,
|
||||||
so the first supported platforms were the Foundation and Fast Model for ARMv8.
|
so the first supported platforms were the Foundation and Fast Model for ARMv8.
|
||||||
These days U-Boot runs on a variety of 64-bit capable ARM hardware, from
|
These days U-Boot runs on a variety of 64-bit capable ARM hardware, from
|
||||||
embedded development boards to servers.
|
embedded development boards to servers.
|
||||||
|
|
||||||
Notes
|
Notes
|
||||||
=====
|
-----
|
||||||
|
|
||||||
1. U-Boot can run at any exception level it is entered in, it is
|
1. U-Boot can run at any exception level it is entered in, it is
|
||||||
recommened to enter it in EL3 if U-Boot takes some responsibilities of a
|
recommened to enter it in EL3 if U-Boot takes some responsibilities of a
|
||||||
|
@ -46,11 +49,11 @@ Notes
|
||||||
|
|
||||||
|
|
||||||
Contributors
|
Contributors
|
||||||
============
|
------------
|
||||||
Tom Rini <trini@ti.com>
|
* Tom Rini <trini@ti.com>
|
||||||
Scott Wood <scottwood@freescale.com>
|
* Scott Wood <scottwood@freescale.com>
|
||||||
York Sun <yorksun@freescale.com>
|
* York Sun <yorksun@freescale.com>
|
||||||
Simon Glass <sjg@chromium.org>
|
* Simon Glass <sjg@chromium.org>
|
||||||
Sharma Bhupesh <bhupesh.sharma@freescale.com>
|
* Sharma Bhupesh <bhupesh.sharma@freescale.com>
|
||||||
Rob Herring <robherring2@gmail.com>
|
* Rob Herring <robherring2@gmail.com>
|
||||||
Sergey Temerkhanov <s.temerkhanov@gmail.com>
|
* Sergey Temerkhanov <s.temerkhanov@gmail.com>
|
18
doc/arch/index.rst
Normal file
18
doc/arch/index.rst
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
.. SPDX-License-Identifier: GPL-2.0+
|
||||||
|
|
||||||
|
Architecture-specific doc
|
||||||
|
=========================
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 2
|
||||||
|
|
||||||
|
arc
|
||||||
|
arm64
|
||||||
|
m68k
|
||||||
|
mips
|
||||||
|
nds32
|
||||||
|
nios2
|
||||||
|
sandbox
|
||||||
|
sh
|
||||||
|
x86
|
||||||
|
xtensa
|
170
doc/arch/m68k.rst
Normal file
170
doc/arch/m68k.rst
Normal file
|
@ -0,0 +1,170 @@
|
||||||
|
.. SPDX-License-Identifier: GPL-2.0+
|
||||||
|
|
||||||
|
M68K / ColdFire
|
||||||
|
===============
|
||||||
|
|
||||||
|
History
|
||||||
|
-------
|
||||||
|
* November 02, 2017 Angelo Dureghello <angelo@sysam.it>
|
||||||
|
* August 08, 2005 Jens Scharsig <esw@bus-elektronik.de>
|
||||||
|
MCF5282 implementation without preloader
|
||||||
|
* January 12, 2004 <josef.baumgartner@telex.de>
|
||||||
|
|
||||||
|
This file contains status information for the port of U-Boot to the
|
||||||
|
Motorola ColdFire series of CPUs.
|
||||||
|
|
||||||
|
Overview
|
||||||
|
--------
|
||||||
|
|
||||||
|
The ColdFire instruction set is "assembly source" compatible but an evolution
|
||||||
|
of the original 68000 instruction set. Some not much used instructions has
|
||||||
|
been removed. The instructions are only 16, 32, or 48 bits long, a
|
||||||
|
simplification compared to the 68000 series.
|
||||||
|
|
||||||
|
Bernhard Kuhn ported U-Boot 0.4.0 to the Motorola ColdFire architecture.
|
||||||
|
The patches of Bernhard support the MCF5272 and MCF5282. A great disadvantage
|
||||||
|
of these patches was that they needed a pre-bootloader to start U-Boot.
|
||||||
|
Because of this, a new port was created which no longer needs a first stage
|
||||||
|
booter.
|
||||||
|
|
||||||
|
Thanks mainly to Freescale but also to several other contributors, U-Boot now
|
||||||
|
supports nearly the entire range of ColdFire processors and their related
|
||||||
|
development boards.
|
||||||
|
|
||||||
|
|
||||||
|
Supported CPU families
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
Please "make menuconfig" with ARCH=m68k, or check arch/m68k/cpu to see the
|
||||||
|
currently supported processor and families.
|
||||||
|
|
||||||
|
|
||||||
|
Supported boards
|
||||||
|
----------------
|
||||||
|
|
||||||
|
U-Boot supports actually more than 40 ColdFire based boards.
|
||||||
|
Board configuration can be done trough include/configs/<boardname>.h but the
|
||||||
|
current recommended method is to use the new and more friendly approach as
|
||||||
|
the "make menuconfig" way, very similar to the Linux way.
|
||||||
|
|
||||||
|
To know details as memory map, build targets, default setup, etc, of a
|
||||||
|
specific board please check:
|
||||||
|
|
||||||
|
* include/configs/<boardname>.h
|
||||||
|
|
||||||
|
and/or
|
||||||
|
|
||||||
|
* configs/<boardname>_defconfig
|
||||||
|
|
||||||
|
It is possible to build all ColdFire boards in a single command-line command,
|
||||||
|
from u-boot root directory, as::
|
||||||
|
|
||||||
|
./tools/buildman/buildman m68k
|
||||||
|
|
||||||
|
Build U-Boot for a specific board
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
A bash script similar to the one below may be used:
|
||||||
|
|
||||||
|
.. code-block:: shell
|
||||||
|
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
export CROSS_COMPILE=/opt/toolchains/m68k/gcc-4.9.0-nolibc/bin/m68k-linux-
|
||||||
|
|
||||||
|
board=M5475DFE
|
||||||
|
|
||||||
|
make distclean
|
||||||
|
make ARCH=m68k ${board}_defconfig
|
||||||
|
make ARCH=m68k KBUILD_VERBOSE=1
|
||||||
|
|
||||||
|
|
||||||
|
Adopted toolchains
|
||||||
|
------------------
|
||||||
|
|
||||||
|
Please check:
|
||||||
|
https://www.denx.de/wiki/U-Boot/ColdFireNotes
|
||||||
|
|
||||||
|
|
||||||
|
ColdFire specific configuration options/settings
|
||||||
|
------------------------------------------------
|
||||||
|
|
||||||
|
Configuration to use a pre-loader
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
If U-Boot should be loaded to RAM and started by a pre-loader
|
||||||
|
CONFIG_MONITOR_IS_IN_RAM must be defined. If it is defined the
|
||||||
|
initial vector table and basic processor initialization will not
|
||||||
|
be compiled in. The start address of U-Boot must be adjusted in
|
||||||
|
the boards config header file (CONFIG_SYS_MONITOR_BASE) and Makefile
|
||||||
|
(CONFIG_SYS_TEXT_BASE) to the load address.
|
||||||
|
|
||||||
|
ColdFire CPU specific options/settings
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
To specify a CPU model, some defines shoudl be used, i.e.:
|
||||||
|
|
||||||
|
CONFIG_MCF52x2:
|
||||||
|
defined for all MCF52x2 CPUs
|
||||||
|
CONFIG_M5272:
|
||||||
|
defined for all Motorola MCF5272 CPUs
|
||||||
|
|
||||||
|
Other options, generally set inside include/configs/<boardname>.h, they may
|
||||||
|
apply to one or more cpu for the ColdFire family:
|
||||||
|
|
||||||
|
CONFIG_SYS_MBAR:
|
||||||
|
defines the base address of the MCF5272 configuration registers
|
||||||
|
CONFIG_SYS_ENET_BD_BASE:
|
||||||
|
defines the base address of the FEC buffer descriptors
|
||||||
|
CONFIG_SYS_SCR:
|
||||||
|
defines the contents of the System Configuration Register
|
||||||
|
CONFIG_SYS_SPR:
|
||||||
|
defines the contents of the System Protection Register
|
||||||
|
CONFIG_SYS_MFD:
|
||||||
|
defines the PLL Multiplication Factor Divider
|
||||||
|
(see table 9-4 of MCF user manual)
|
||||||
|
CONFIG_SYS_RFD:
|
||||||
|
defines the PLL Reduce Frequency Devider
|
||||||
|
(see table 9-4 of MCF user manual)
|
||||||
|
CONFIG_SYS_CSx_BASE:
|
||||||
|
defines the base address of chip select x
|
||||||
|
CONFIG_SYS_CSx_SIZE:
|
||||||
|
defines the memory size (address range) of chip select x
|
||||||
|
CONFIG_SYS_CSx_WIDTH:
|
||||||
|
defines the bus with of chip select x
|
||||||
|
CONFIG_SYS_CSx_MASK:
|
||||||
|
defines the mask for the related chip select x
|
||||||
|
CONFIG_SYS_CSx_RO:
|
||||||
|
if set to 0 chip select x is read/write else chip select is read only
|
||||||
|
CONFIG_SYS_CSx_WS:
|
||||||
|
defines the number of wait states of chip select x
|
||||||
|
CONFIG_SYS_CACHE_ICACR:
|
||||||
|
cache-related registers config
|
||||||
|
CONFIG_SYS_CACHE_DCACR:
|
||||||
|
cache-related registers config
|
||||||
|
CONFIG_SYS_CACHE_ACRX:
|
||||||
|
cache-related registers config
|
||||||
|
CONFIG_SYS_SDRAM_BASE:
|
||||||
|
SDRAM config for SDRAM controller-specific registers
|
||||||
|
CONFIG_SYS_SDRAM_SIZE:
|
||||||
|
SDRAM config for SDRAM controller-specific registers
|
||||||
|
CONFIG_SYS_SDRAM_BASEX:
|
||||||
|
SDRAM config for SDRAM controller-specific registers
|
||||||
|
CONFIG_SYS_SDRAM_CFG1:
|
||||||
|
SDRAM config for SDRAM controller-specific registers
|
||||||
|
CONFIG_SYS_SDRAM_CFG2:
|
||||||
|
SDRAM config for SDRAM controller-specific registers
|
||||||
|
CONFIG_SYS_SDRAM_CTRL:
|
||||||
|
SDRAM config for SDRAM controller-specific registers
|
||||||
|
CONFIG_SYS_SDRAM_MODE:
|
||||||
|
SDRAM config for SDRAM controller-specific registers
|
||||||
|
CONFIG_SYS_SDRAM_EMOD:
|
||||||
|
SDRAM config for SDRAM controller-specific registers, please
|
||||||
|
see arch/m68k/cpu/<specific_cpu>/start.S files to see how
|
||||||
|
these options are used.
|
||||||
|
CONFIG_MCFUART:
|
||||||
|
defines enabling of ColdFire UART driver
|
||||||
|
CONFIG_SYS_UART_PORT:
|
||||||
|
defines the UART port to be used (only a single UART can be actually enabled)
|
||||||
|
CONFIG_SYS_SBFHDR_SIZE:
|
||||||
|
size of the prepended SBF header, if any
|
|
@ -1,17 +1,16 @@
|
||||||
|
.. SPDX-License-Identifier: GPL-2.0+
|
||||||
|
|
||||||
|
MIPS
|
||||||
|
====
|
||||||
|
|
||||||
Notes for the MIPS architecture port of U-Boot
|
Notes for the MIPS architecture port of U-Boot
|
||||||
|
|
||||||
Toolchains
|
Toolchains
|
||||||
----------
|
----------
|
||||||
|
|
||||||
http://www.denx.de/wiki/DULG/ELDK
|
* `ELDK < DULG < DENX <http://www.denx.de/wiki/DULG/ELDK>`_
|
||||||
ELDK < DULG < DENX
|
* `Embedded Debian -- Cross-development toolchains <http://www.emdebian.org/crosstools.html>`_
|
||||||
|
* `Buildroot <http://buildroot.uclibc.org/>`_
|
||||||
http://www.emdebian.org/crosstools.html
|
|
||||||
Embedded Debian -- Cross-development toolchains
|
|
||||||
|
|
||||||
http://buildroot.uclibc.org/
|
|
||||||
Buildroot
|
|
||||||
|
|
||||||
Known Issues
|
Known Issues
|
||||||
------------
|
------------
|
||||||
|
@ -24,9 +23,9 @@ Known Issues
|
||||||
re-initializes the cache. The more common uImage 'bootm' command does
|
re-initializes the cache. The more common uImage 'bootm' command does
|
||||||
not suffer this problem.
|
not suffer this problem.
|
||||||
|
|
||||||
[workaround] To avoid this cache incoherency,
|
[workaround] To avoid this cache incoherency:
|
||||||
1) insert flush_cache(all) before calling dcache_disable(), or
|
- insert flush_cache(all) before calling dcache_disable(), or
|
||||||
2) fix dcache_disable() to do both flushing and disabling cache.
|
- fix dcache_disable() to do both flushing and disabling cache.
|
||||||
|
|
||||||
* Note that Linux users need to kill dcache_disable() in do_bootelf_exec()
|
* Note that Linux users need to kill dcache_disable() in do_bootelf_exec()
|
||||||
or override do_bootelf_exec() not to disable I-/D-caches, because most
|
or override do_bootelf_exec() not to disable I-/D-caches, because most
|
||||||
|
@ -36,19 +35,12 @@ TODOs
|
||||||
-----
|
-----
|
||||||
|
|
||||||
* Probe CPU types, I-/D-cache and TLB size etc. automatically
|
* Probe CPU types, I-/D-cache and TLB size etc. automatically
|
||||||
|
|
||||||
* Secondary cache support missing
|
* Secondary cache support missing
|
||||||
|
|
||||||
* Initialize TLB entries redardless of their use
|
* Initialize TLB entries redardless of their use
|
||||||
|
|
||||||
* R2000/R3000 class parts are not supported
|
* R2000/R3000 class parts are not supported
|
||||||
|
|
||||||
* Limited testing across different MIPS variants
|
* Limited testing across different MIPS variants
|
||||||
|
|
||||||
* Due to cache initialization issues, the DRAM on board must be
|
* Due to cache initialization issues, the DRAM on board must be
|
||||||
initialized in board specific assembler language before the cache init
|
initialized in board specific assembler language before the cache init
|
||||||
code is run -- that is, initialize the DRAM in lowlevel_init().
|
code is run -- that is, initialize the DRAM in lowlevel_init().
|
||||||
|
|
||||||
* centralize/share more CPU code of MIPS32, MIPS64 and XBurst
|
* centralize/share more CPU code of MIPS32, MIPS64 and XBurst
|
||||||
|
|
||||||
* support Qemu Malta
|
* support Qemu Malta
|
101
doc/arch/nds32.rst
Normal file
101
doc/arch/nds32.rst
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
.. SPDX-License-Identifier: GPL-2.0+
|
||||||
|
|
||||||
|
NDS32
|
||||||
|
=====
|
||||||
|
|
||||||
|
NDS32 is a new high-performance 32-bit RISC microprocessor core.
|
||||||
|
|
||||||
|
http://www.andestech.com/
|
||||||
|
|
||||||
|
AndeStar ISA
|
||||||
|
------------
|
||||||
|
AndeStar is a patent-pending 16-bit/32-bit mixed-length instruction set to
|
||||||
|
achieve optimal system performance, code density, and power efficiency.
|
||||||
|
|
||||||
|
It contains the following features:
|
||||||
|
- Intermixable 32-bit and 16-bit instruction sets without the need for
|
||||||
|
mode switch.
|
||||||
|
- 16-bit instructions as a frequently used subset of 32-bit instructions.
|
||||||
|
- RISC-style register-based instruction set.
|
||||||
|
- 32 32-bit General Purpose Registers (GPR).
|
||||||
|
- Upto 1024 User Special Registers (USR) for existing and extension
|
||||||
|
instructions.
|
||||||
|
- Rich load/store instructions for...
|
||||||
|
- Single memory access with base address update.
|
||||||
|
- Multiple aligned and unaligned memory accesses for memory copy and stack
|
||||||
|
operations.
|
||||||
|
- Data prefetch to improve data cache performance.
|
||||||
|
- Non-bus locking synchronization instructions.
|
||||||
|
- PC relative jump and PC read instructions for efficient position independent
|
||||||
|
code.
|
||||||
|
- Multiply-add and multiple-sub with 64-bit accumulator.
|
||||||
|
- Instruction for efficient power management.
|
||||||
|
- Bi-endian support.
|
||||||
|
- Three instruction extension space for application acceleration:
|
||||||
|
- Performance extension.
|
||||||
|
- Andes future extensions (for floating-point, multimedia, etc.)
|
||||||
|
- Customer extensions.
|
||||||
|
|
||||||
|
AndesCore CPU
|
||||||
|
-------------
|
||||||
|
Andes Technology has 4 families of CPU cores: N12, N10, N9, N8.
|
||||||
|
|
||||||
|
For details about N12 CPU family, please check below N1213 features.
|
||||||
|
N1213 is a configurable hard/soft core of NDS32's N12 CPU family.
|
||||||
|
|
||||||
|
N1213 Features
|
||||||
|
^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
CPU Core
|
||||||
|
- 16-/32-bit mixable instruction format.
|
||||||
|
- 32 general-purpose 32-bit registers.
|
||||||
|
- 8-stage pipeline.
|
||||||
|
- Dynamic branch prediction.
|
||||||
|
- 32/64/128/256 BTB.
|
||||||
|
- Return address stack (RAS).
|
||||||
|
- Vector interrupts for internal/external.
|
||||||
|
interrupt controller with 6 hardware interrupt signals.
|
||||||
|
- 3 HW-level nested interruptions.
|
||||||
|
- User and super-user mode support.
|
||||||
|
- Memory-mapped I/O.
|
||||||
|
- Address space up to 4GB.
|
||||||
|
|
||||||
|
Memory Management Unit
|
||||||
|
- TLB
|
||||||
|
- 4/8-entry fully associative iTLB/dTLB.
|
||||||
|
- 32/64/128-entry 4-way set-associati.ve main TLB.
|
||||||
|
- TLB locking support
|
||||||
|
- Optional hardware page table walker.
|
||||||
|
- Two groups of page size support.
|
||||||
|
- 4KB & 1MB.
|
||||||
|
- 8KB & 1MB.
|
||||||
|
|
||||||
|
Memory Subsystem
|
||||||
|
- I & D cache.
|
||||||
|
- Virtually indexed and physically tagged.
|
||||||
|
- Cache size: 8KB/16KB/32KB/64KB.
|
||||||
|
- Cache line size: 16B/32B.
|
||||||
|
- Set associativity: 2-way, 4-way or direct-mapped.
|
||||||
|
- Cache locking support.
|
||||||
|
- I & D local memory (LM).
|
||||||
|
- Size: 4KB to 1MB.
|
||||||
|
- Bank numbers: 1 or 2.
|
||||||
|
- Optional 1D/2D DMA engine.
|
||||||
|
- Internal or external to CPU core.
|
||||||
|
|
||||||
|
Bus Interface
|
||||||
|
- Synchronous/Asynchronous AHB bus: 0, 1 or 2 ports.
|
||||||
|
- Synchronous High speed memory port.
|
||||||
|
(HSMP): 0, 1 or 2 ports.
|
||||||
|
|
||||||
|
Debug
|
||||||
|
- JTAG debug interface.
|
||||||
|
- Embedded debug module (EDM).
|
||||||
|
- Optional embedded program tracer interface.
|
||||||
|
|
||||||
|
Miscellaneous
|
||||||
|
- Programmable data endian control.
|
||||||
|
- Performance monitoring mechanism.
|
||||||
|
|
||||||
|
The NDS32 ports of u-boot, the Linux kernel, the GNU toolchain and other
|
||||||
|
associated software are actively supported by Andes Technology Corporation.
|
|
@ -1,10 +1,15 @@
|
||||||
|
.. SPDX-License-Identifier: GPL-2.0+
|
||||||
|
|
||||||
|
Nios II
|
||||||
|
=======
|
||||||
|
|
||||||
Nios II is a 32-bit embedded-processor architecture designed
|
Nios II is a 32-bit embedded-processor architecture designed
|
||||||
specifically for the Altera family of FPGAs.
|
specifically for the Altera family of FPGAs.
|
||||||
|
|
||||||
Please refer to the link for more information on Nios II,
|
Please refer to the link for more information on Nios II:
|
||||||
https://www.altera.com/products/processors/overview.html
|
https://www.altera.com/products/processors/overview.html
|
||||||
|
|
||||||
Please refer to the link for Linux port and toolchains,
|
Please refer to the link for Linux port and toolchains:
|
||||||
http://rocketboards.org/foswiki/view/Documentation/NiosIILinuxUserManual
|
http://rocketboards.org/foswiki/view/Documentation/NiosIILinuxUserManual
|
||||||
|
|
||||||
The Nios II port of u-boot is controlled by device tree. Please check
|
The Nios II port of u-boot is controlled by device tree. Please check
|
||||||
|
@ -13,33 +18,38 @@ out doc/README.fdt-control.
|
||||||
To add a new board/configuration (eg, mysystem) to u-boot, you will need
|
To add a new board/configuration (eg, mysystem) to u-boot, you will need
|
||||||
three files.
|
three files.
|
||||||
|
|
||||||
1. The device tree source which describes the hardware, dts file.
|
1. The device tree source which describes the hardware, dts file:
|
||||||
arch/nios2/dts/mysystem.dts
|
arch/nios2/dts/mysystem.dts
|
||||||
|
|
||||||
2. Default configuration of Kconfig, defconfig file.
|
2. Default configuration of Kconfig, defconfig file:
|
||||||
configs/mysystem_defconfig
|
configs/mysystem_defconfig
|
||||||
|
|
||||||
3. The legacy board header file.
|
3. The legacy board header file:
|
||||||
include/configs/mysystem.h
|
include/configs/mysystem.h
|
||||||
|
|
||||||
The device tree source must be generated from your qsys/sopc design
|
The device tree source must be generated from your qsys/sopc design
|
||||||
using the sopc2dts tool. Then modified to fit your configuration. Please
|
using the sopc2dts tool. Then modified to fit your configuration.
|
||||||
find the sopc2dts download and usage at the wiki,
|
|
||||||
|
Please find the sopc2dts download and usage at the wiki:
|
||||||
http://www.alterawiki.com/wiki/Sopc2dts
|
http://www.alterawiki.com/wiki/Sopc2dts
|
||||||
|
|
||||||
$ java -jar sopc2dts.jar --force-altr -i mysystem.sopcinfo -o mysystem.dts
|
.. code-block:: none
|
||||||
|
|
||||||
|
$ java -jar sopc2dts.jar --force-altr -i mysystem.sopcinfo -o mysystem.dts
|
||||||
|
|
||||||
You will need to add additional properties to the dts. Please find an
|
You will need to add additional properties to the dts. Please find an
|
||||||
example at, arch/nios2/dts/10m50_devboard.dts.
|
example at, arch/nios2/dts/10m50_devboard.dts.
|
||||||
|
|
||||||
1. Add "stdout-path=..." property with your serial path to the chosen
|
1. Add "stdout-path=..." property with your serial path to the chosen
|
||||||
node, like this,
|
node, like this::
|
||||||
|
|
||||||
chosen {
|
chosen {
|
||||||
stdout-path = &uart_0;
|
stdout-path = &uart_0;
|
||||||
};
|
};
|
||||||
|
|
||||||
2. If you use SPI/EPCS or I2C, you will need to add aliases to number
|
2. If you use SPI/EPCS or I2C, you will need to add aliases to number
|
||||||
the sequence of these devices, like this,
|
the sequence of these devices, like this::
|
||||||
|
|
||||||
aliases {
|
aliases {
|
||||||
spi0 = &epcs_controller;
|
spi0 = &epcs_controller;
|
||||||
};
|
};
|
||||||
|
@ -47,49 +57,55 @@ the sequence of these devices, like this,
|
||||||
Next, you will need a default config file. You may start with
|
Next, you will need a default config file. You may start with
|
||||||
10m50_defconfig, modify the options and save it.
|
10m50_defconfig, modify the options and save it.
|
||||||
|
|
||||||
$ make 10m50_defconfig
|
.. code-block:: none
|
||||||
$ make menuconfig
|
|
||||||
$ make savedefconfig
|
$ make 10m50_defconfig
|
||||||
$ cp defconfig configs/mysystem_defconfig
|
$ make menuconfig
|
||||||
|
$ make savedefconfig
|
||||||
|
$ cp defconfig configs/mysystem_defconfig
|
||||||
|
|
||||||
You will need to change the names of board header file and device tree,
|
You will need to change the names of board header file and device tree,
|
||||||
and select the drivers with menuconfig.
|
and select the drivers with menuconfig.
|
||||||
|
|
||||||
Nios II architecture --->
|
.. code-block:: none
|
||||||
(mysystem) Board header file
|
|
||||||
Device Tree Control --->
|
Nios II architecture --->
|
||||||
(mysystem) Default Device Tree for DT control
|
(mysystem) Board header file
|
||||||
|
Device Tree Control --->
|
||||||
|
(mysystem) Default Device Tree for DT control
|
||||||
|
|
||||||
There is a selection of "Provider of DTB for DT control" in the Device
|
There is a selection of "Provider of DTB for DT control" in the Device
|
||||||
Tree Control menu.
|
Tree Control menu.
|
||||||
|
|
||||||
( ) Separate DTB for DT control, will cat the dtb to end of u-boot
|
* Separate DTB for DT control, will cat the dtb to end of u-boot
|
||||||
binary, output u-boot-dtb.bin. This should be used for production.
|
binary, output u-boot-dtb.bin. This should be used for production.
|
||||||
If you use boot copier, like EPCS boot copier, make sure the copier
|
If you use boot copier, like EPCS boot copier, make sure the copier
|
||||||
copies all the u-boot-dtb.bin, not just u-boot.bin.
|
copies all the u-boot-dtb.bin, not just u-boot.bin.
|
||||||
|
|
||||||
( ) Embedded DTB for DT control, will include the dtb inside the u-boot
|
* Embedded DTB for DT control, will include the dtb inside the u-boot
|
||||||
binary. This is handy for development, eg, using gdb or nios2-download.
|
binary. This is handy for development, eg, using gdb or nios2-download.
|
||||||
|
|
||||||
The last thing, legacy board header file describes those config options
|
The last thing, legacy board header file describes those config options
|
||||||
not covered in Kconfig yet. You may copy it from 10m50_devboard.h.
|
not covered in Kconfig yet. You may copy it from 10m50_devboard.h::
|
||||||
|
|
||||||
$ cp include/configs/10m50_devboard.h include/configs/mysystem.h
|
$ cp include/configs/10m50_devboard.h include/configs/mysystem.h
|
||||||
|
|
||||||
Please change the SDRAM base and size to match your board. The base
|
Please change the SDRAM base and size to match your board. The base
|
||||||
should be cached virtual address, for Nios II with MMU it is 0xCxxx_xxxx
|
should be cached virtual address, for Nios II with MMU it is 0xCxxx_xxxx
|
||||||
to 0xDxxx_xxxx.
|
to 0xDxxx_xxxx.
|
||||||
|
|
||||||
#define CONFIG_SYS_SDRAM_BASE 0xc8000000
|
.. code-block:: c
|
||||||
#define CONFIG_SYS_SDRAM_SIZE 0x08000000
|
|
||||||
|
#define CONFIG_SYS_SDRAM_BASE 0xc8000000
|
||||||
|
#define CONFIG_SYS_SDRAM_SIZE 0x08000000
|
||||||
|
|
||||||
You will need to change the environment variables location and setting,
|
You will need to change the environment variables location and setting,
|
||||||
too. You may change other configs to fit your board.
|
too. You may change other configs to fit your board.
|
||||||
|
|
||||||
After all these changes, you may build and test.
|
After all these changes, you may build and test::
|
||||||
|
|
||||||
$ export CROSS_COMPILE=nios2-elf- (or nios2-linux-gnu-)
|
$ export CROSS_COMPILE=nios2-elf- (or nios2-linux-gnu-)
|
||||||
$ make mysystem_defconfig
|
$ make mysystem_defconfig
|
||||||
$ make
|
$ make
|
||||||
|
|
||||||
Enjoy!
|
Enjoy!
|
|
@ -1,10 +1,12 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
.. SPDX-License-Identifier: GPL-2.0+ */
|
||||||
/*
|
.. Copyright (c) 2014 The Chromium OS Authors.
|
||||||
* Copyright (c) 2014 The Chromium OS Authors.
|
.. sectionauthor:: Simon Glass <sjg@chromium.org>
|
||||||
*/
|
|
||||||
|
Sandbox
|
||||||
|
=======
|
||||||
|
|
||||||
Native Execution of U-Boot
|
Native Execution of U-Boot
|
||||||
==========================
|
--------------------------
|
||||||
|
|
||||||
The 'sandbox' architecture is designed to allow U-Boot to run under Linux on
|
The 'sandbox' architecture is designed to allow U-Boot to run under Linux on
|
||||||
almost any hardware. To achieve this it builds U-Boot (so far as possible)
|
almost any hardware. To achieve this it builds U-Boot (so far as possible)
|
||||||
|
@ -35,33 +37,31 @@ Note that standalone/API support is not available at present.
|
||||||
Basic Operation
|
Basic Operation
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
To run sandbox U-Boot use something like:
|
To run sandbox U-Boot use something like::
|
||||||
|
|
||||||
make sandbox_defconfig all
|
make sandbox_defconfig all
|
||||||
./u-boot
|
./u-boot
|
||||||
|
|
||||||
Note:
|
Note: If you get errors about 'sdl-config: Command not found' you may need to
|
||||||
If you get errors about 'sdl-config: Command not found' you may need to
|
install libsdl1.2-dev or similar to get SDL support. Alternatively you can
|
||||||
install libsdl1.2-dev or similar to get SDL support. Alternatively you can
|
build sandbox without SDL (i.e. no display/keyboard support) by removing
|
||||||
build sandbox without SDL (i.e. no display/keyboard support) by removing
|
the CONFIG_SANDBOX_SDL line in include/configs/sandbox.h or using::
|
||||||
the CONFIG_SANDBOX_SDL line in include/configs/sandbox.h or using:
|
|
||||||
|
|
||||||
make sandbox_defconfig all NO_SDL=1
|
make sandbox_defconfig all NO_SDL=1
|
||||||
./u-boot
|
./u-boot
|
||||||
|
|
||||||
U-Boot will start on your computer, showing a sandbox emulation of the serial
|
U-Boot will start on your computer, showing a sandbox emulation of the serial
|
||||||
console:
|
console::
|
||||||
|
|
||||||
|
U-Boot 2014.04 (Mar 20 2014 - 19:06:00)
|
||||||
|
|
||||||
U-Boot 2014.04 (Mar 20 2014 - 19:06:00)
|
DRAM: 128 MiB
|
||||||
|
Using default environment
|
||||||
|
|
||||||
DRAM: 128 MiB
|
In: serial
|
||||||
Using default environment
|
Out: lcd
|
||||||
|
Err: lcd
|
||||||
In: serial
|
=>
|
||||||
Out: lcd
|
|
||||||
Err: lcd
|
|
||||||
=>
|
|
||||||
|
|
||||||
You can issue commands as your would normally. If the command you want is
|
You can issue commands as your would normally. If the command you want is
|
||||||
not supported you can add it to include/configs/sandbox.h.
|
not supported you can add it to include/configs/sandbox.h.
|
||||||
|
@ -73,7 +73,7 @@ Console / LCD support
|
||||||
---------------------
|
---------------------
|
||||||
|
|
||||||
Assuming that CONFIG_SANDBOX_SDL is defined when building, you can run the
|
Assuming that CONFIG_SANDBOX_SDL is defined when building, you can run the
|
||||||
sandbox with LCD and keyboard emulation, using something like:
|
sandbox with LCD and keyboard emulation, using something like::
|
||||||
|
|
||||||
./u-boot -d u-boot.dtb -l
|
./u-boot -d u-boot.dtb -l
|
||||||
|
|
||||||
|
@ -198,18 +198,23 @@ Sandbox Variants
|
||||||
|
|
||||||
There are unfortunately quite a few variants at present:
|
There are unfortunately quite a few variants at present:
|
||||||
|
|
||||||
sandbox - should be used for most tests
|
sandbox:
|
||||||
sandbox64 - special build that forces a 64-bit host
|
should be used for most tests
|
||||||
sandbox_flattree - builds with dev_read_...() functions defined as inline.
|
sandbox64:
|
||||||
We need this build so that we can test those inline functions, and we
|
special build that forces a 64-bit host
|
||||||
cannot build with both the inline functions and the non-inline functions
|
sandbox_flattree:
|
||||||
since they are named the same.
|
builds with dev_read\_...() functions defined as inline.
|
||||||
sandbox_noblk - builds without CONFIG_BLK, which means the legacy block
|
We need this build so that we can test those inline functions, and we
|
||||||
drivers are used. We cannot use both the legacy and driver-model block
|
cannot build with both the inline functions and the non-inline functions
|
||||||
drivers since they implement the same functions
|
since they are named the same.
|
||||||
sandbox_spl - builds sandbox with SPL support, so you can run spl/u-boot-spl
|
sandbox_noblk:
|
||||||
and it will start up and then load ./u-boot. It is also possible to
|
builds without CONFIG_BLK, which means the legacy block
|
||||||
run ./u-boot directly.
|
drivers are used. We cannot use both the legacy and driver-model block
|
||||||
|
drivers since they implement the same functions
|
||||||
|
sandbox_spl:
|
||||||
|
builds sandbox with SPL support, so you can run spl/u-boot-spl
|
||||||
|
and it will start up and then load ./u-boot. It is also possible to
|
||||||
|
run ./u-boot directly.
|
||||||
|
|
||||||
Of these sandbox_noblk can be removed once CONFIG_BLK is used everwhere, and
|
Of these sandbox_noblk can be removed once CONFIG_BLK is used everwhere, and
|
||||||
sandbox_spl can probably be removed since it is a superset of sandbox.
|
sandbox_spl can probably be removed since it is a superset of sandbox.
|
||||||
|
@ -234,42 +239,44 @@ promiscuous mode so that the network card won't filter out packets not destined
|
||||||
for its configured (on Linux) MAC address.
|
for its configured (on Linux) MAC address.
|
||||||
|
|
||||||
The RAW sockets Ethernet API requires elevated privileges in Linux. You can
|
The RAW sockets Ethernet API requires elevated privileges in Linux. You can
|
||||||
either run as root, or you can add the capability needed like so:
|
either run as root, or you can add the capability needed like so::
|
||||||
|
|
||||||
sudo /sbin/setcap "CAP_NET_RAW+ep" /path/to/u-boot
|
sudo /sbin/setcap "CAP_NET_RAW+ep" /path/to/u-boot
|
||||||
|
|
||||||
The default device tree for sandbox includes an entry for eth0 on the sandbox
|
The default device tree for sandbox includes an entry for eth0 on the sandbox
|
||||||
host machine whose alias is "eth1". The following are a few examples of network
|
host machine whose alias is "eth1". The following are a few examples of network
|
||||||
operations being tested on the eth0 interface.
|
operations being tested on the eth0 interface.
|
||||||
|
|
||||||
sudo /path/to/u-boot -D
|
.. code-block:: none
|
||||||
|
|
||||||
DHCP
|
sudo /path/to/u-boot -D
|
||||||
....
|
|
||||||
|
|
||||||
setenv autoload no
|
DHCP
|
||||||
setenv ethrotate no
|
....
|
||||||
setenv ethact eth1
|
|
||||||
dhcp
|
|
||||||
|
|
||||||
PING
|
setenv autoload no
|
||||||
....
|
setenv ethrotate no
|
||||||
|
setenv ethact eth1
|
||||||
|
dhcp
|
||||||
|
|
||||||
setenv autoload no
|
PING
|
||||||
setenv ethrotate no
|
....
|
||||||
setenv ethact eth1
|
|
||||||
dhcp
|
|
||||||
ping $gatewayip
|
|
||||||
|
|
||||||
TFTP
|
setenv autoload no
|
||||||
....
|
setenv ethrotate no
|
||||||
|
setenv ethact eth1
|
||||||
|
dhcp
|
||||||
|
ping $gatewayip
|
||||||
|
|
||||||
setenv autoload no
|
TFTP
|
||||||
setenv ethrotate no
|
....
|
||||||
setenv ethact eth1
|
|
||||||
dhcp
|
setenv autoload no
|
||||||
setenv serverip WWW.XXX.YYY.ZZZ
|
setenv ethrotate no
|
||||||
tftpboot u-boot.bin
|
setenv ethact eth1
|
||||||
|
dhcp
|
||||||
|
setenv serverip WWW.XXX.YYY.ZZZ
|
||||||
|
tftpboot u-boot.bin
|
||||||
|
|
||||||
The bridge also supports (to a lesser extent) the localhost interface, 'lo'.
|
The bridge also supports (to a lesser extent) the localhost interface, 'lo'.
|
||||||
|
|
||||||
|
@ -287,12 +294,14 @@ The default device tree for sandbox includes an entry for lo on the sandbox
|
||||||
host machine whose alias is "eth5". The following is an example of a network
|
host machine whose alias is "eth5". The following is an example of a network
|
||||||
operation being tested on the lo interface.
|
operation being tested on the lo interface.
|
||||||
|
|
||||||
TFTP
|
.. code-block:: none
|
||||||
....
|
|
||||||
|
|
||||||
setenv ethrotate no
|
TFTP
|
||||||
setenv ethact eth5
|
....
|
||||||
tftpboot u-boot.bin
|
|
||||||
|
setenv ethrotate no
|
||||||
|
setenv ethact eth5
|
||||||
|
tftpboot u-boot.bin
|
||||||
|
|
||||||
|
|
||||||
SPI Emulation
|
SPI Emulation
|
||||||
|
@ -300,7 +309,7 @@ SPI Emulation
|
||||||
|
|
||||||
Sandbox supports SPI and SPI flash emulation.
|
Sandbox supports SPI and SPI flash emulation.
|
||||||
|
|
||||||
This is controlled by the spi_sf argument, the format of which is:
|
This is controlled by the spi_sf argument, the format of which is::
|
||||||
|
|
||||||
bus:cs:device:file
|
bus:cs:device:file
|
||||||
|
|
||||||
|
@ -309,24 +318,23 @@ This is controlled by the spi_sf argument, the format of which is:
|
||||||
device - SPI device emulation name
|
device - SPI device emulation name
|
||||||
file - File on disk containing the data
|
file - File on disk containing the data
|
||||||
|
|
||||||
For example:
|
For example::
|
||||||
|
|
||||||
dd if=/dev/zero of=spi.bin bs=1M count=4
|
dd if=/dev/zero of=spi.bin bs=1M count=4
|
||||||
./u-boot --spi_sf 0:0:M25P16:spi.bin
|
./u-boot --spi_sf 0:0:M25P16:spi.bin
|
||||||
|
|
||||||
With this setup you can issue SPI flash commands as normal:
|
With this setup you can issue SPI flash commands as normal::
|
||||||
|
|
||||||
=>sf probe
|
=>sf probe
|
||||||
SF: Detected M25P16 with page size 64 KiB, total 2 MiB
|
SF: Detected M25P16 with page size 64 KiB, total 2 MiB
|
||||||
=>sf read 0 0 10000
|
=>sf read 0 0 10000
|
||||||
SF: 65536 bytes @ 0x0 Read: OK
|
SF: 65536 bytes @ 0x0 Read: OK
|
||||||
=>
|
|
||||||
|
|
||||||
Since this is a full SPI emulation (rather than just flash), you can
|
Since this is a full SPI emulation (rather than just flash), you can
|
||||||
also use low-level SPI commands:
|
also use low-level SPI commands::
|
||||||
|
|
||||||
=>sspi 0:0 32 9f
|
=>sspi 0:0 32 9f
|
||||||
FF202015
|
FF202015
|
||||||
|
|
||||||
This is issuing a READ_ID command and getting back 20 (ST Micro) part
|
This is issuing a READ_ID command and getting back 20 (ST Micro) part
|
||||||
0x2015 (the M25P16).
|
0x2015 (the M25P16).
|
||||||
|
@ -338,15 +346,14 @@ for each driver.
|
||||||
|
|
||||||
Configuration settings for the curious are:
|
Configuration settings for the curious are:
|
||||||
|
|
||||||
CONFIG_SANDBOX_SPI_MAX_BUS
|
CONFIG_SANDBOX_SPI_MAX_BUS:
|
||||||
The maximum number of SPI buses supported by the driver (default 1).
|
The maximum number of SPI buses supported by the driver (default 1).
|
||||||
|
|
||||||
CONFIG_SANDBOX_SPI_MAX_CS
|
CONFIG_SANDBOX_SPI_MAX_CS:
|
||||||
The maximum number of chip selects supported by the driver
|
The maximum number of chip selects supported by the driver (default 10).
|
||||||
(default 10).
|
|
||||||
|
|
||||||
CONFIG_SPI_IDLE_VAL
|
CONFIG_SPI_IDLE_VAL:
|
||||||
The idle value on the SPI bus
|
The idle value on the SPI bus
|
||||||
|
|
||||||
|
|
||||||
Block Device Emulation
|
Block Device Emulation
|
||||||
|
@ -354,20 +361,20 @@ Block Device Emulation
|
||||||
|
|
||||||
U-Boot can use raw disk images for block device emulation. To e.g. list
|
U-Boot can use raw disk images for block device emulation. To e.g. list
|
||||||
the contents of the root directory on the second partion of the image
|
the contents of the root directory on the second partion of the image
|
||||||
"disk.raw", you can use the following commands:
|
"disk.raw", you can use the following commands::
|
||||||
|
|
||||||
=>host bind 0 ./disk.raw
|
=>host bind 0 ./disk.raw
|
||||||
=>ls host 0:2
|
=>ls host 0:2
|
||||||
|
|
||||||
A disk image can be created using the following commands:
|
A disk image can be created using the following commands::
|
||||||
|
|
||||||
$> truncate -s 1200M ./disk.raw
|
$> truncate -s 1200M ./disk.raw
|
||||||
$> echo -e "label: gpt\n,64M,U\n,,L" | /usr/sbin/sgdisk ./disk.raw
|
$> echo -e "label: gpt\n,64M,U\n,,L" | /usr/sbin/sgdisk ./disk.raw
|
||||||
$> lodev=`sudo losetup -P -f --show ./disk.raw`
|
$> lodev=`sudo losetup -P -f --show ./disk.raw`
|
||||||
$> sudo mkfs.vfat -n EFI -v ${lodev}p1
|
$> sudo mkfs.vfat -n EFI -v ${lodev}p1
|
||||||
$> sudo mkfs.ext4 -L ROOT -v ${lodev}p2
|
$> sudo mkfs.ext4 -L ROOT -v ${lodev}p2
|
||||||
|
|
||||||
or utilize the device described in test/py/make_test_disk.py:
|
or utilize the device described in test/py/make_test_disk.py::
|
||||||
|
|
||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
import make_test_disk
|
import make_test_disk
|
||||||
|
@ -395,16 +402,16 @@ space. See existing code for examples.
|
||||||
Debugging the init sequence
|
Debugging the init sequence
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
If you get a failure in the initcall sequence, like this:
|
If you get a failure in the initcall sequence, like this::
|
||||||
|
|
||||||
initcall sequence 0000560775957c80 failed at call 0000000000048134 (err=-96)
|
initcall sequence 0000560775957c80 failed at call 0000000000048134 (err=-96)
|
||||||
|
|
||||||
Then you use can use grep to see which init call failed, e.g.:
|
Then you use can use grep to see which init call failed, e.g.::
|
||||||
|
|
||||||
$ grep 0000000000048134 u-boot.map
|
$ grep 0000000000048134 u-boot.map
|
||||||
stdio_add_devices
|
stdio_add_devices
|
||||||
|
|
||||||
Of course another option is to run it with a debugger such as gdb:
|
Of course another option is to run it with a debugger such as gdb::
|
||||||
|
|
||||||
$ gdb u-boot
|
$ gdb u-boot
|
||||||
...
|
...
|
||||||
|
@ -414,6 +421,8 @@ Of course another option is to run it with a debugger such as gdb:
|
||||||
Note that two locations are reported, since this function is used in both
|
Note that two locations are reported, since this function is used in both
|
||||||
board_init_f() and board_init_r().
|
board_init_f() and board_init_r().
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
(gdb) r
|
(gdb) r
|
||||||
Starting program: /tmp/b/sandbox/u-boot
|
Starting program: /tmp/b/sandbox/u-boot
|
||||||
[Thread debugging using libthread_db enabled]
|
[Thread debugging using libthread_db enabled]
|
||||||
|
@ -445,13 +454,13 @@ environment variable to the correct pathname before building U-Boot.
|
||||||
Using valgrind / memcheck
|
Using valgrind / memcheck
|
||||||
-------------------------
|
-------------------------
|
||||||
|
|
||||||
It is possible to run U-Boot under valgrind to check memory allocations:
|
It is possible to run U-Boot under valgrind to check memory allocations::
|
||||||
|
|
||||||
valgrind u-boot
|
valgrind u-boot
|
||||||
|
|
||||||
If you are running sandbox SPL or TPL, then valgrind will not by default
|
If you are running sandbox SPL or TPL, then valgrind will not by default
|
||||||
notice when U-Boot jumps from TPL to SPL, or from SPL to U-Boot proper. To
|
notice when U-Boot jumps from TPL to SPL, or from SPL to U-Boot proper. To
|
||||||
fix this, use:
|
fix this, use::
|
||||||
|
|
||||||
valgrind --trace-children=yes u-boot
|
valgrind --trace-children=yes u-boot
|
||||||
|
|
||||||
|
@ -462,22 +471,24 @@ Testing
|
||||||
U-Boot sandbox can be used to run various tests, mostly in the test/
|
U-Boot sandbox can be used to run various tests, mostly in the test/
|
||||||
directory. These include:
|
directory. These include:
|
||||||
|
|
||||||
command_ut
|
command_ut:
|
||||||
- Unit tests for command parsing and handling
|
Unit tests for command parsing and handling
|
||||||
compression
|
compression:
|
||||||
- Unit tests for U-Boot's compression algorithms, useful for
|
Unit tests for U-Boot's compression algorithms, useful for
|
||||||
security checking. It supports gzip, bzip2, lzma and lzo.
|
security checking. It supports gzip, bzip2, lzma and lzo.
|
||||||
driver model
|
driver model:
|
||||||
- Run this pytest
|
Run this pytest::
|
||||||
./test/py/test.py --bd sandbox --build -k ut_dm -v
|
|
||||||
image
|
./test/py/test.py --bd sandbox --build -k ut_dm -v
|
||||||
- Unit tests for images:
|
|
||||||
test/image/test-imagetools.sh - multi-file images
|
image:
|
||||||
test/image/test-fit.py - FIT images
|
Unit tests for images:
|
||||||
tracing
|
test/image/test-imagetools.sh - multi-file images
|
||||||
- test/trace/test-trace.sh tests the tracing system (see README.trace)
|
test/image/test-fit.py - FIT images
|
||||||
verified boot
|
tracing:
|
||||||
- See test/vboot/vboot_test.sh for this
|
test/trace/test-trace.sh tests the tracing system (see README.trace)
|
||||||
|
verified boot:
|
||||||
|
See test/vboot/vboot_test.sh for this
|
||||||
|
|
||||||
If you change or enhance any of the above subsystems, you shold write or
|
If you change or enhance any of the above subsystems, you shold write or
|
||||||
expand a test and include it with your patch series submission. Test
|
expand a test and include it with your patch series submission. Test
|
||||||
|
@ -495,14 +506,12 @@ Memory Map
|
||||||
Sandbox has its own emulated memory starting at 0. Here are some of the things
|
Sandbox has its own emulated memory starting at 0. Here are some of the things
|
||||||
that are mapped into that memory:
|
that are mapped into that memory:
|
||||||
|
|
||||||
|
======= ======================== ===============================
|
||||||
|
Addr Config Usage
|
||||||
|
======= ======================== ===============================
|
||||||
0 CONFIG_SYS_FDT_LOAD_ADDR Device tree
|
0 CONFIG_SYS_FDT_LOAD_ADDR Device tree
|
||||||
e000 CONFIG_BLOBLIST_ADDR Blob list
|
e000 CONFIG_BLOBLIST_ADDR Blob list
|
||||||
10000 CONFIG_MALLOC_F_ADDR Early memory allocation
|
10000 CONFIG_MALLOC_F_ADDR Early memory allocation
|
||||||
f0000 CONFIG_PRE_CON_BUF_ADDR Pre-console buffer
|
f0000 CONFIG_PRE_CON_BUF_ADDR Pre-console buffer
|
||||||
100000 CONFIG_TRACE_EARLY_ADDR Early trace buffer (if enabled)
|
100000 CONFIG_TRACE_EARLY_ADDR Early trace buffer (if enabled)
|
||||||
=
|
======= ======================== ===============================
|
||||||
|
|
||||||
|
|
||||||
--
|
|
||||||
Simon Glass <sjg@chromium.org>
|
|
||||||
Updated 22-Mar-14
|
|
106
doc/arch/sh.rst
Normal file
106
doc/arch/sh.rst
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
.. SPDX-License-Identifier: GPL-2.0+
|
||||||
|
.. Copyright (c) 2007,2008 Nobuhiro Iwamatsu <iwamatsu@nigaur.org>
|
||||||
|
|
||||||
|
SuperH
|
||||||
|
======
|
||||||
|
|
||||||
|
What's this?
|
||||||
|
------------
|
||||||
|
This file contains status information for the port of U-Boot to the
|
||||||
|
Renesas SuperH series of CPUs.
|
||||||
|
|
||||||
|
Overview
|
||||||
|
--------
|
||||||
|
SuperH has an original boot loader. However, source code is dirty, and
|
||||||
|
maintenance is not done. To improve sharing and the maintenance of the code,
|
||||||
|
Nobuhiro Iwamatsu started the porting to U-Boot in 2007.
|
||||||
|
|
||||||
|
Supported CPUs
|
||||||
|
--------------
|
||||||
|
|
||||||
|
Renesas SH7750/SH7750R
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
This CPU has the SH4 core.
|
||||||
|
|
||||||
|
Renesas SH7722
|
||||||
|
^^^^^^^^^^^^^^
|
||||||
|
This CPU has the SH4AL-DSP core.
|
||||||
|
|
||||||
|
Renesas SH7780
|
||||||
|
^^^^^^^^^^^^^^
|
||||||
|
This CPU has the SH4A core.
|
||||||
|
|
||||||
|
Supported Boards
|
||||||
|
----------------
|
||||||
|
|
||||||
|
Hitachi UL MS7750SE01/MS7750RSE01
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
Board specific code is in board/ms7750se
|
||||||
|
To use this board, type "make ms7750se_config".
|
||||||
|
Support devices are:
|
||||||
|
|
||||||
|
- SCIF
|
||||||
|
- SDRAM
|
||||||
|
- NOR Flash
|
||||||
|
- Marubun PCMCIA
|
||||||
|
|
||||||
|
Hitachi UL MS7722SE01
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
Board specific code is in board/ms7722se
|
||||||
|
To use this board, type "make ms7722se_config".
|
||||||
|
Support devices are:
|
||||||
|
|
||||||
|
- SCIF
|
||||||
|
- SDRAM
|
||||||
|
- NOR Flash
|
||||||
|
- Marubun PCMCIA
|
||||||
|
- SMC91x ethernet
|
||||||
|
|
||||||
|
Hitachi UL MS7720ERP01
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
Board specific code is in board/ms7720se
|
||||||
|
To use this board, type "make ms7720se_config".
|
||||||
|
Support devices are:
|
||||||
|
|
||||||
|
- SCIF
|
||||||
|
- SDRAM
|
||||||
|
- NOR Flash
|
||||||
|
- Marubun PCMCIA
|
||||||
|
|
||||||
|
Renesas R7780MP
|
||||||
|
^^^^^^^^^^^^^^^
|
||||||
|
Board specific code is in board/r7780mp
|
||||||
|
To use this board, type "make r7780mp_config".
|
||||||
|
Support devices are:
|
||||||
|
|
||||||
|
- SCIF
|
||||||
|
- DDR-SDRAM
|
||||||
|
- NOR Flash
|
||||||
|
- Compact Flash
|
||||||
|
- ASIX ethernet
|
||||||
|
- SH7780 PCI bridge
|
||||||
|
- RTL8110 ethernet
|
||||||
|
|
||||||
|
In SuperH, S-record and binary of made u-boot work on the memory.
|
||||||
|
When u-boot is written in the flash, it is necessary to change the
|
||||||
|
address by using 'objcopy'::
|
||||||
|
|
||||||
|
ex) shX-linux-objcopy -Ibinary -Osrec u-boot.bin u-boot.flash.srec
|
||||||
|
|
||||||
|
Compiler
|
||||||
|
--------
|
||||||
|
You can use the following of u-boot to compile.
|
||||||
|
- `SuperH Linux Open site <http://www.superh-linux.org/>`_
|
||||||
|
- `KPIT GNU tools <http://www.kpitgnutools.com/>`_
|
||||||
|
|
||||||
|
Future
|
||||||
|
------
|
||||||
|
I plan to support the following CPUs and boards.
|
||||||
|
|
||||||
|
CPUs
|
||||||
|
^^^^
|
||||||
|
- SH7751R(SH4)
|
||||||
|
|
||||||
|
Boards
|
||||||
|
^^^^^^
|
||||||
|
Many boards ;-)
|
File diff suppressed because it is too large
Load diff
|
@ -1,5 +1,7 @@
|
||||||
U-Boot for the Xtensa Architecture
|
.. SPDX-License-Identifier: GPL-2.0+
|
||||||
==================================
|
|
||||||
|
Xtensa
|
||||||
|
======
|
||||||
|
|
||||||
Xtensa Architecture and Diamond Cores
|
Xtensa Architecture and Diamond Cores
|
||||||
-------------------------------------
|
-------------------------------------
|
||||||
|
@ -35,15 +37,16 @@ directory. The name of that directory starts with 'arch-' followed by
|
||||||
the name for the processor configuration, for example, arch-dc233c for
|
the name for the processor configuration, for example, arch-dc233c for
|
||||||
the Diamond DC233 processor.
|
the Diamond DC233 processor.
|
||||||
|
|
||||||
core.h Definitions for the core itself.
|
core.h:
|
||||||
|
Definitions for the core itself.
|
||||||
|
|
||||||
The following files are part of the overlay but not used by U-Boot.
|
The following files are part of the overlay but not used by U-Boot.
|
||||||
|
|
||||||
tie.h Co-processors and custom extensions defined
|
tie.h:
|
||||||
in the Tensilica Instruction Extension (TIE)
|
Co-processors and custom extensions defined in the Tensilica Instruction
|
||||||
language.
|
Extension (TIE) language.
|
||||||
tie-asm.h Assembly macros to access custom-defined registers
|
tie-asm.h:
|
||||||
and states.
|
Assembly macros to access custom-defined registers and states.
|
||||||
|
|
||||||
|
|
||||||
Global Data Pointer, Exported Function Stubs, and the ABI
|
Global Data Pointer, Exported Function Stubs, and the ABI
|
||||||
|
@ -92,6 +95,5 @@ U-Boot for Xtensa provides a special memory exception handler that
|
||||||
reports such access attempts and resets the board.
|
reports such access attempts and resets the board.
|
||||||
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
.. Chris Zankel
|
||||||
Chris Zankel
|
.. Ross Morley
|
||||||
Ross Morley
|
|
|
@ -1,18 +1,21 @@
|
||||||
Andes Technology SoC AG101P
|
.. SPDX-License-Identifier: GPL-2.0+
|
||||||
===========================
|
|
||||||
|
ADP-AG101P
|
||||||
|
==========
|
||||||
|
|
||||||
|
ADP-AG101P is the SoC with AG101 hardcore CPU.
|
||||||
|
|
||||||
|
AG101P SoC
|
||||||
|
----------
|
||||||
|
|
||||||
AG101P is the mainline SoC produced by Andes Technology using N1213 CPU core
|
AG101P is the mainline SoC produced by Andes Technology using N1213 CPU core
|
||||||
with FPU and DDR contoller support.
|
with FPU and DDR contoller support.
|
||||||
AG101P has integrated both AHB and APB bus and many periphals for application
|
AG101P has integrated both AHB and APB bus and many periphals for application
|
||||||
and product development.
|
and product development.
|
||||||
|
|
||||||
ADP-AG101P
|
|
||||||
=========
|
|
||||||
|
|
||||||
ADP-AG101P is the SoC with AG101 hardcore CPU.
|
|
||||||
|
|
||||||
Configurations
|
Configurations
|
||||||
==============
|
--------------
|
||||||
|
|
||||||
CONFIG_MEM_REMAP:
|
CONFIG_MEM_REMAP:
|
||||||
Doing memory remap is essential for preparing some non-OS or RTOS
|
Doing memory remap is essential for preparing some non-OS or RTOS
|
||||||
|
@ -24,13 +27,14 @@ CONFIG_SKIP_LOWLEVEL_INIT:
|
||||||
in "include/configs/adp-ag101p.h".
|
in "include/configs/adp-ag101p.h".
|
||||||
|
|
||||||
Build and boot steps
|
Build and boot steps
|
||||||
====================
|
--------------------
|
||||||
|
|
||||||
|
Build:
|
||||||
|
|
||||||
build:
|
|
||||||
1. Prepare the toolchains and make sure the $PATH to toolchains is correct.
|
1. Prepare the toolchains and make sure the $PATH to toolchains is correct.
|
||||||
2. Use `make adp-ag101p_defconfig` in u-boot root to build the image.
|
2. Use `make adp-ag101p_defconfig` in u-boot root to build the image.
|
||||||
|
|
||||||
Burn u-boot to SPI ROM:
|
Burn U-Boot to SPI ROM
|
||||||
====================
|
----------------------
|
||||||
|
|
||||||
This section will be added later.
|
This section will be added later.
|
329
doc/board/AndesTech/ax25-ae350.rst
Normal file
329
doc/board/AndesTech/ax25-ae350.rst
Normal file
|
@ -0,0 +1,329 @@
|
||||||
|
.. SPDX-License-Identifier: GPL-2.0+
|
||||||
|
|
||||||
|
AX25-AE350
|
||||||
|
==========
|
||||||
|
|
||||||
|
AE350 is the mainline SoC produced by Andes Technology using AX25 CPU core
|
||||||
|
base on RISC-V architecture.
|
||||||
|
|
||||||
|
AE350 has integrated both AHB and APB bus and many periphals for application
|
||||||
|
and product development.
|
||||||
|
|
||||||
|
AX25-AE350 is the SoC with AE350 hardcore CPU.
|
||||||
|
|
||||||
|
AX25 is Andes CPU IP to adopt RISC-V architecture.
|
||||||
|
|
||||||
|
AX25 Features
|
||||||
|
-------------
|
||||||
|
|
||||||
|
CPU Core
|
||||||
|
- 5-stage in-order execution pipeline
|
||||||
|
- Hardware Multiplier
|
||||||
|
- radix-2/radix-4/radix-16/radix-256/fast
|
||||||
|
- Hardware Divider
|
||||||
|
- Optional branch prediction
|
||||||
|
- Machine mode and optional user mode
|
||||||
|
- Optional performance monitoring
|
||||||
|
|
||||||
|
ISA
|
||||||
|
- RV64I base integer instructions
|
||||||
|
- RVC for 16-bit compressed instructions
|
||||||
|
- RVM for multiplication and division instructions
|
||||||
|
|
||||||
|
Memory subsystem
|
||||||
|
- I & D local memory
|
||||||
|
- Size: 4KB to 16MB
|
||||||
|
- Memory subsyetem soft-error protection
|
||||||
|
- Protection scheme: parity-checking or error-checking-and-correction (ECC)
|
||||||
|
- Automatic hardware error correction
|
||||||
|
|
||||||
|
Bus
|
||||||
|
- Interface Protocol
|
||||||
|
- Synchronous AHB (32-bit/64-bit data-width), or
|
||||||
|
- Synchronous AXI4 (64-bit data-width)
|
||||||
|
|
||||||
|
Power management
|
||||||
|
- Wait for interrupt (WFI) mode
|
||||||
|
|
||||||
|
Debug
|
||||||
|
- Configurable number of breakpoints: 2/4/8
|
||||||
|
- External Debug Module
|
||||||
|
- AHB slave port
|
||||||
|
- External JTAG debug transport module
|
||||||
|
|
||||||
|
Platform Level Interrupt Controller (PLIC)
|
||||||
|
- AHB slave port
|
||||||
|
- Configurable number of interrupts: 1-1023
|
||||||
|
- Configurable number of interrupt priorities: 3/7/15/63/127/255
|
||||||
|
- Configurable number of targets: 1-16
|
||||||
|
- Preempted interrupt priority stack
|
||||||
|
|
||||||
|
Configurations
|
||||||
|
--------------
|
||||||
|
|
||||||
|
CONFIG_SKIP_LOWLEVEL_INIT:
|
||||||
|
If you want to boot this system from SPI ROM and bypass e-bios (the
|
||||||
|
other boot loader on ROM). You should undefine CONFIG_SKIP_LOWLEVEL_INIT
|
||||||
|
in "include/configs/ax25-ae350.h".
|
||||||
|
|
||||||
|
Build and boot steps
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
Build:
|
||||||
|
|
||||||
|
1. Prepare the toolchains and make sure the $PATH to toolchains is correct.
|
||||||
|
2. Use `make ae350_rv[32|64]_defconfig` in u-boot root to build the image for
|
||||||
|
32 or 64 bit.
|
||||||
|
|
||||||
|
Verification:
|
||||||
|
|
||||||
|
1. startup
|
||||||
|
2. relocation
|
||||||
|
3. timer driver
|
||||||
|
4. uart driver
|
||||||
|
5. mac driver
|
||||||
|
6. mmc driver
|
||||||
|
7. spi driver
|
||||||
|
|
||||||
|
Steps
|
||||||
|
-----
|
||||||
|
|
||||||
|
1. Define CONFIG_SKIP_LOWLEVEL_INIT to build u-boot which is loaded via gdb from ram.
|
||||||
|
2. Undefine CONFIG_SKIP_LOWLEVEL_INIT to build u-boot which is booted from spi rom.
|
||||||
|
3. Ping a server by mac driver
|
||||||
|
4. Scan sd card and copy u-boot image which is booted from flash to ram by sd driver.
|
||||||
|
5. Burn this u-boot image to spi rom by spi driver
|
||||||
|
6. Re-boot u-boot from spi flash with power off and power on.
|
||||||
|
|
||||||
|
Messages of U-Boot boot on AE350 board
|
||||||
|
--------------------------------------
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
|
U-Boot 2018.01-rc2-00033-g824f89a (Dec 21 2017 - 16:51:26 +0800)
|
||||||
|
|
||||||
|
DRAM: 1 GiB
|
||||||
|
MMC: mmc@f0e00000: 0
|
||||||
|
SF: Detected mx25u1635e with page size 256 Bytes, erase size 4 KiB, total 2 MiB
|
||||||
|
In: serial@f0300000
|
||||||
|
Out: serial@f0300000
|
||||||
|
Err: serial@f0300000
|
||||||
|
Net:
|
||||||
|
Warning: mac@e0100000 (eth0) using random MAC address - be:dd:d7:e4:e8:10
|
||||||
|
eth0: mac@e0100000
|
||||||
|
|
||||||
|
RISC-V # version
|
||||||
|
U-Boot 2018.01-rc2-00033-gb265b91-dirty (Dec 22 2017 - 13:54:21 +0800)
|
||||||
|
|
||||||
|
riscv32-unknown-linux-gnu-gcc (GCC) 7.2.0
|
||||||
|
GNU ld (GNU Binutils) 2.29
|
||||||
|
|
||||||
|
RISC-V # setenv ipaddr 10.0.4.200 ;
|
||||||
|
RISC-V # setenv serverip 10.0.4.97 ;
|
||||||
|
RISC-V # ping 10.0.4.97 ;
|
||||||
|
Using mac@e0100000 device
|
||||||
|
host 10.0.4.97 is alive
|
||||||
|
|
||||||
|
RISC-V # mmc rescan
|
||||||
|
RISC-V # fatls mmc 0:1
|
||||||
|
318907 u-boot-ae350-64.bin
|
||||||
|
1252 hello_world_ae350_32.bin
|
||||||
|
328787 u-boot-ae350-32.bin
|
||||||
|
|
||||||
|
3 file(s), 0 dir(s)
|
||||||
|
|
||||||
|
RISC-V # sf probe 0:0 50000000 0
|
||||||
|
SF: Detected mx25u1635e with page size 256 Bytes, erase size 4 KiB, total 2 MiB
|
||||||
|
|
||||||
|
RISC-V # sf test 0x100000 0x1000
|
||||||
|
SPI flash test:
|
||||||
|
0 erase: 36 ticks, 111 KiB/s 0.888 Mbps
|
||||||
|
1 check: 29 ticks, 137 KiB/s 1.096 Mbps
|
||||||
|
2 write: 40 ticks, 100 KiB/s 0.800 Mbps
|
||||||
|
3 read: 20 ticks, 200 KiB/s 1.600 Mbps
|
||||||
|
Test passed
|
||||||
|
0 erase: 36 ticks, 111 KiB/s 0.888 Mbps
|
||||||
|
1 check: 29 ticks, 137 KiB/s 1.096 Mbps
|
||||||
|
2 write: 40 ticks, 100 KiB/s 0.800 Mbps
|
||||||
|
3 read: 20 ticks, 200 KiB/s 1.600 Mbps
|
||||||
|
|
||||||
|
RISC-V # fatload mmc 0:1 0x600000 u-boot-ae350-32.bin
|
||||||
|
reading u-boot-ae350-32.bin
|
||||||
|
328787 bytes read in 324 ms (990.2 KiB/s)
|
||||||
|
|
||||||
|
RISC-V # sf erase 0x0 0x51000
|
||||||
|
SF: 331776 bytes @ 0x0 Erased: OK
|
||||||
|
|
||||||
|
RISC-V # sf write 0x600000 0x0 0x50453
|
||||||
|
device 0 offset 0x0, size 0x50453
|
||||||
|
SF: 328787 bytes @ 0x0 Written: OK
|
||||||
|
|
||||||
|
RISC-V # crc32 0x600000 0x50453
|
||||||
|
crc32 for 00600000 ... 00650452 ==> 692dc44a
|
||||||
|
|
||||||
|
RISC-V # crc32 0x80000000 0x50453
|
||||||
|
crc32 for 80000000 ... 80050452 ==> 692dc44a
|
||||||
|
RISC-V #
|
||||||
|
|
||||||
|
*** power-off and power-on, this U-Boot is booted from spi flash ***
|
||||||
|
|
||||||
|
U-Boot 2018.01-rc2-00032-gf67dd47-dirty (Dec 21 2017 - 13:56:03 +0800)
|
||||||
|
|
||||||
|
DRAM: 1 GiB
|
||||||
|
MMC: mmc@f0e00000: 0
|
||||||
|
SF: Detected mx25u1635e with page size 256 Bytes, erase size 4 KiB, total 2 MiB
|
||||||
|
In: serial@f0300000
|
||||||
|
Out: serial@f0300000
|
||||||
|
Err: serial@f0300000
|
||||||
|
Net:
|
||||||
|
Warning: mac@e0100000 (eth0) using random MAC address - ee:4c:58:29:32:f5
|
||||||
|
eth0: mac@e0100000
|
||||||
|
RISC-V #
|
||||||
|
|
||||||
|
|
||||||
|
Boot bbl and riscv-linux via U-Boot on QEMU
|
||||||
|
-------------------------------------------
|
||||||
|
|
||||||
|
1. Build riscv-linux
|
||||||
|
2. Build bbl and riscv-linux with --with-payload
|
||||||
|
3. Prepare ae350.dtb
|
||||||
|
4. Creating OS-kernel images
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
|
./mkimage -A riscv -O linux -T kernel -C none -a 0x0000 -e 0x0000 -d bbl.bin bootmImage-bbl.bin
|
||||||
|
Image Name:
|
||||||
|
Created: Tue Mar 13 10:06:42 2018
|
||||||
|
Image Type: RISC-V Linux Kernel Image (uncompressed)
|
||||||
|
Data Size: 17901204 Bytes = 17481.64 KiB = 17.07 MiB
|
||||||
|
Load Address: 00000000
|
||||||
|
Entry Point: 00000000
|
||||||
|
|
||||||
|
5. Copy bootmImage-bbl.bin and ae350.dtb to qemu sd card image
|
||||||
|
6. Message of booting riscv-linux from bbl via u-boot on qemu
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
|
U-Boot 2018.03-rc4-00031-g2631273 (Mar 13 2018 - 15:02:55 +0800)
|
||||||
|
|
||||||
|
DRAM: 1 GiB
|
||||||
|
main-loop: WARNING: I/O thread spun for 1000 iterations
|
||||||
|
MMC: mmc@f0e00000: 0
|
||||||
|
Loading Environment from SPI Flash... *** Warning - spi_flash_probe_bus_cs() failed, using default environment
|
||||||
|
|
||||||
|
Failed (-22)
|
||||||
|
In: serial@f0300000
|
||||||
|
Out: serial@f0300000
|
||||||
|
Err: serial@f0300000
|
||||||
|
Net:
|
||||||
|
Warning: mac@e0100000 (eth0) using random MAC address - 02:00:00:00:00:00
|
||||||
|
eth0: mac@e0100000
|
||||||
|
RISC-V # mmc rescan
|
||||||
|
RISC-V # mmc part
|
||||||
|
|
||||||
|
Partition Map for MMC device 0 -- Partition Type: DOS
|
||||||
|
|
||||||
|
Part Start Sector Num Sectors UUID Type
|
||||||
|
RISC-V # fatls mmc 0:0
|
||||||
|
17901268 bootmImage-bbl.bin
|
||||||
|
1954 ae2xx.dtb
|
||||||
|
|
||||||
|
2 file(s), 0 dir(s)
|
||||||
|
|
||||||
|
RISC-V # fatload mmc 0:0 0x00600000 bootmImage-bbl.bin
|
||||||
|
17901268 bytes read in 4642 ms (3.7 MiB/s)
|
||||||
|
RISC-V # fatload mmc 0:0 0x2000000 ae350.dtb
|
||||||
|
1954 bytes read in 1 ms (1.9 MiB/s)
|
||||||
|
RISC-V # setenv bootm_size 0x2000000
|
||||||
|
RISC-V # setenv fdt_high 0x1f00000
|
||||||
|
RISC-V # bootm 0x00600000 - 0x2000000
|
||||||
|
## Booting kernel from Legacy Image at 00600000 ...
|
||||||
|
Image Name:
|
||||||
|
Image Type: RISC-V Linux Kernel Image (uncompressed)
|
||||||
|
Data Size: 17901204 Bytes = 17.1 MiB
|
||||||
|
Load Address: 00000000
|
||||||
|
Entry Point: 00000000
|
||||||
|
Verifying Checksum ... OK
|
||||||
|
## Flattened Device Tree blob at 02000000
|
||||||
|
Booting using the fdt blob at 0x2000000
|
||||||
|
Loading Kernel Image ... OK
|
||||||
|
Loading Device Tree to 0000000001efc000, end 0000000001eff7a1 ... OK
|
||||||
|
[ 0.000000] OF: fdt: Ignoring memory range 0x0 - 0x200000
|
||||||
|
[ 0.000000] Linux version 4.14.0-00046-gf3e439f-dirty (rick@atcsqa06) (gcc version 7.1.1 20170509 (GCC)) #1 Tue Jan 9 16:34:25 CST 2018
|
||||||
|
[ 0.000000] bootconsole [early0] enabled
|
||||||
|
[ 0.000000] Initial ramdisk at: 0xffffffe000016a98 (12267008 bytes)
|
||||||
|
[ 0.000000] Zone ranges:
|
||||||
|
[ 0.000000] DMA [mem 0x0000000000200000-0x000000007fffffff]
|
||||||
|
[ 0.000000] Normal empty
|
||||||
|
[ 0.000000] Movable zone start for each node
|
||||||
|
[ 0.000000] Early memory node ranges
|
||||||
|
[ 0.000000] node 0: [mem 0x0000000000200000-0x000000007fffffff]
|
||||||
|
[ 0.000000] Initmem setup node 0 [mem 0x0000000000200000-0x000000007fffffff]
|
||||||
|
[ 0.000000] elf_hwcap is 0x112d
|
||||||
|
[ 0.000000] random: fast init done
|
||||||
|
[ 0.000000] Built 1 zonelists, mobility grouping on. Total pages: 516615
|
||||||
|
[ 0.000000] Kernel command line: console=ttyS0,38400n8 earlyprintk=uart8250-32bit,0xf0300000 debug loglevel=7
|
||||||
|
[ 0.000000] PID hash table entries: 4096 (order: 3, 32768 bytes)
|
||||||
|
[ 0.000000] Dentry cache hash table entries: 262144 (order: 9, 2097152 bytes)
|
||||||
|
[ 0.000000] Inode-cache hash table entries: 131072 (order: 8, 1048576 bytes)
|
||||||
|
[ 0.000000] Sorting __ex_table...
|
||||||
|
[ 0.000000] Memory: 2047832K/2095104K available (1856K kernel code, 204K rwdata, 532K rodata, 12076K init, 756K bss, 47272K reserved, 0K cma-reserved)
|
||||||
|
[ 0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
|
||||||
|
[ 0.000000] NR_IRQS: 0, nr_irqs: 0, preallocated irqs: 0
|
||||||
|
[ 0.000000] riscv,cpu_intc,0: 64 local interrupts mapped
|
||||||
|
[ 0.000000] riscv,plic0,e4000000: mapped 31 interrupts to 1/2 handlers
|
||||||
|
[ 0.000000] clocksource: riscv_clocksource: mask: 0xffffffffffffffff max_cycles: 0x24e6a1710, max_idle_ns: 440795202120 ns
|
||||||
|
[ 0.000000] Calibrating delay loop (skipped), value calculated using timer frequency.. 20.00 BogoMIPS (lpj=40000)
|
||||||
|
[ 0.000000] pid_max: default: 32768 minimum: 301
|
||||||
|
[ 0.004000] Mount-cache hash table entries: 4096 (order: 3, 32768 bytes)
|
||||||
|
[ 0.004000] Mountpoint-cache hash table entries: 4096 (order: 3, 32768 bytes)
|
||||||
|
[ 0.056000] devtmpfs: initialized
|
||||||
|
[ 0.060000] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns
|
||||||
|
[ 0.064000] futex hash table entries: 256 (order: 0, 6144 bytes)
|
||||||
|
[ 0.068000] NET: Registered protocol family 16
|
||||||
|
[ 0.080000] vgaarb: loaded
|
||||||
|
[ 0.084000] clocksource: Switched to clocksource riscv_clocksource
|
||||||
|
[ 0.088000] NET: Registered protocol family 2
|
||||||
|
[ 0.092000] TCP established hash table entries: 16384 (order: 5, 131072 bytes)
|
||||||
|
[ 0.096000] TCP bind hash table entries: 16384 (order: 5, 131072 bytes)
|
||||||
|
[ 0.096000] TCP: Hash tables configured (established 16384 bind 16384)
|
||||||
|
[ 0.100000] UDP hash table entries: 1024 (order: 3, 32768 bytes)
|
||||||
|
[ 0.100000] UDP-Lite hash table entries: 1024 (order: 3, 32768 bytes)
|
||||||
|
[ 0.104000] NET: Registered protocol family 1
|
||||||
|
[ 0.616000] Unpacking initramfs...
|
||||||
|
[ 1.220000] workingset: timestamp_bits=62 max_order=19 bucket_order=0
|
||||||
|
[ 1.244000] io scheduler noop registered
|
||||||
|
[ 1.244000] io scheduler cfq registered (default)
|
||||||
|
[ 1.244000] io scheduler mq-deadline registered
|
||||||
|
[ 1.248000] io scheduler kyber registered
|
||||||
|
[ 1.360000] Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled
|
||||||
|
[ 1.368000] console [ttyS0] disabled
|
||||||
|
[ 1.372000] f0300000.serial: ttyS0 at MMIO 0xf0300020 (irq = 10, base_baud = 1228800) is a 16550A
|
||||||
|
[ 1.392000] console [ttyS0] enabled
|
||||||
|
[ 1.392000] ftmac100: Loading version 0.2 ...
|
||||||
|
[ 1.396000] ftmac100 e0100000.mac eth0: irq 8, mapped at ffffffd002005000
|
||||||
|
[ 1.400000] ftmac100 e0100000.mac eth0: generated random MAC address 6e:ac:c3:92:36:c0
|
||||||
|
[ 1.404000] IR NEC protocol handler initialized
|
||||||
|
[ 1.404000] IR RC5(x/sz) protocol handler initialized
|
||||||
|
[ 1.404000] IR RC6 protocol handler initialized
|
||||||
|
[ 1.404000] IR JVC protocol handler initialized
|
||||||
|
[ 1.408000] IR Sony protocol handler initialized
|
||||||
|
[ 1.408000] IR SANYO protocol handler initialized
|
||||||
|
[ 1.408000] IR Sharp protocol handler initialized
|
||||||
|
[ 1.408000] IR MCE Keyboard/mouse protocol handler initialized
|
||||||
|
[ 1.412000] IR XMP protocol handler initialized
|
||||||
|
[ 1.456000] ftsdc010 f0e00000.mmc: mmc0 - using hw SDIO IRQ
|
||||||
|
[ 1.464000] bootconsole [early0] uses init memory and must be disabled even before the real one is ready
|
||||||
|
[ 1.464000] bootconsole [early0] disabled
|
||||||
|
[ 1.508000] Freeing unused kernel memory: 12076K
|
||||||
|
[ 1.512000] This architecture does not have kernel memory protection.
|
||||||
|
[ 1.520000] mmc0: new SD card at address 4567
|
||||||
|
[ 1.524000] mmcblk0: mmc0:4567 QEMU! 20.0 MiB
|
||||||
|
[ 1.844000] mmcblk0:
|
||||||
|
Wed Dec 1 10:00:00 CST 2010
|
||||||
|
/ #
|
||||||
|
|
||||||
|
|
||||||
|
TODO
|
||||||
|
----
|
||||||
|
Boot bbl and riscv-linux via U-Boot on AE350 board
|
192
doc/board/atmel/at91ek.rst
Normal file
192
doc/board/atmel/at91ek.rst
Normal file
|
@ -0,0 +1,192 @@
|
||||||
|
.. SPDX-License-Identifier: GPL-2.0+
|
||||||
|
|
||||||
|
AT91 Evaluation kits
|
||||||
|
====================
|
||||||
|
|
||||||
|
Board mapping & boot media
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
AT91SAM9260EK, AT91SAM9G20EK & AT91SAM9XEEK
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Memory map::
|
||||||
|
|
||||||
|
0x20000000 - 23FFFFFF SDRAM (64 MB)
|
||||||
|
0xC0000000 - Cxxxxxxx Atmel Dataflash card (J13)
|
||||||
|
0xD0000000 - D07FFFFF Soldered Atmel Dataflash (AT45DB642)
|
||||||
|
|
||||||
|
Environment variables
|
||||||
|
|
||||||
|
U-Boot environment variables can be stored at different places:
|
||||||
|
|
||||||
|
- Dataflash on SPI chip select 1 (default)
|
||||||
|
- Dataflash on SPI chip select 0 (dataflash card)
|
||||||
|
- Nand flash
|
||||||
|
|
||||||
|
You can choose your storage location at config step (here for at91sam9260ek)::
|
||||||
|
|
||||||
|
make at91sam9260ek_nandflash_config - use nand flash
|
||||||
|
make at91sam9260ek_dataflash_cs0_config - use data flash (spi cs0)
|
||||||
|
make at91sam9260ek_dataflash_cs1_config - use data flash (spi cs1)
|
||||||
|
|
||||||
|
|
||||||
|
AT91SAM9261EK, AT91SAM9G10EK
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Memory map::
|
||||||
|
|
||||||
|
0x20000000 - 23FFFFFF SDRAM (64 MB)
|
||||||
|
0xC0000000 - C07FFFFF Soldered Atmel Dataflash (AT45DB642)
|
||||||
|
0xD0000000 - Dxxxxxxx Atmel Dataflash card (J22)
|
||||||
|
|
||||||
|
Environment variables
|
||||||
|
|
||||||
|
U-Boot environment variables can be stored at different places:
|
||||||
|
|
||||||
|
- Dataflash on SPI chip select 0 (default)
|
||||||
|
- Dataflash on SPI chip select 3 (dataflash card)
|
||||||
|
- Nand flash
|
||||||
|
|
||||||
|
You can choose your storage location at config step (here for at91sam9260ek)::
|
||||||
|
|
||||||
|
make at91sam9261ek_nandflash_config - use nand flash
|
||||||
|
make at91sam9261ek_dataflash_cs0_config - use data flash (spi cs0)
|
||||||
|
make at91sam9261ek_dataflash_cs3_config - use data flash (spi cs3)
|
||||||
|
|
||||||
|
|
||||||
|
AT91SAM9263EK
|
||||||
|
^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Memory map::
|
||||||
|
|
||||||
|
0x20000000 - 23FFFFFF SDRAM (64 MB)
|
||||||
|
0xC0000000 - Cxxxxxxx Atmel Dataflash card (J9)
|
||||||
|
|
||||||
|
Environment variables
|
||||||
|
|
||||||
|
U-Boot environment variables can be stored at different places:
|
||||||
|
|
||||||
|
- Dataflash on SPI chip select 0 (dataflash card)
|
||||||
|
- Nand flash
|
||||||
|
- Nor flash (not populate by default)
|
||||||
|
|
||||||
|
You can choose your storage location at config step (here for at91sam9260ek)::
|
||||||
|
|
||||||
|
make at91sam9263ek_nandflash_config - use nand flash
|
||||||
|
make at91sam9263ek_dataflash_cs0_config - use data flash (spi cs0)
|
||||||
|
make at91sam9263ek_norflash_config - use nor flash
|
||||||
|
|
||||||
|
You can choose to boot directly from U-Boot at config step::
|
||||||
|
|
||||||
|
make at91sam9263ek_norflash_boot_config - boot from nor flash
|
||||||
|
|
||||||
|
|
||||||
|
AT91SAM9M10G45EK
|
||||||
|
^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Memory map::
|
||||||
|
|
||||||
|
0x70000000 - 77FFFFFF SDRAM (128 MB)
|
||||||
|
|
||||||
|
Environment variables
|
||||||
|
|
||||||
|
U-Boot environment variables can be stored at different places:
|
||||||
|
|
||||||
|
- Nand flash
|
||||||
|
|
||||||
|
You can choose your storage location at config step (here for at91sam9m10g45ek)::
|
||||||
|
|
||||||
|
make at91sam9m10g45ek_nandflash_config - use nand flash
|
||||||
|
|
||||||
|
|
||||||
|
AT91SAM9RLEK
|
||||||
|
^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Memory map::
|
||||||
|
|
||||||
|
0x20000000 - 23FFFFFF SDRAM (64 MB)
|
||||||
|
0xC0000000 - C07FFFFF Soldered Atmel Dataflash (AT45DB642)
|
||||||
|
|
||||||
|
Environment variables
|
||||||
|
|
||||||
|
U-Boot environment variables can be stored at different places:
|
||||||
|
|
||||||
|
- Dataflash on SPI chip select 0
|
||||||
|
- Nand flash.
|
||||||
|
|
||||||
|
You can choose your storage location at config step (here for at91sam9rlek)::
|
||||||
|
|
||||||
|
make at91sam9rlek_nandflash_config - use nand flash
|
||||||
|
|
||||||
|
|
||||||
|
AT91SAM9N12EK, AT91SAM9X5EK
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Memory map::
|
||||||
|
|
||||||
|
0x20000000 - 27FFFFFF SDRAM (128 MB)
|
||||||
|
|
||||||
|
Environment variables
|
||||||
|
|
||||||
|
U-Boot environment variables can be stored at different places:
|
||||||
|
|
||||||
|
- Nand flash
|
||||||
|
- SD/MMC card
|
||||||
|
- Serialflash/Dataflash on SPI chip select 0
|
||||||
|
|
||||||
|
You can choose your storage location at config step (here for at91sam9x5ek)::
|
||||||
|
|
||||||
|
make at91sam9x5ek_dataflash_config - use data flash
|
||||||
|
make at91sam9x5ek_mmc_config - use sd/mmc card
|
||||||
|
make at91sam9x5ek_nandflash_config - use nand flash
|
||||||
|
make at91sam9x5ek_spiflash_config - use serial flash
|
||||||
|
|
||||||
|
|
||||||
|
SAMA5D3XEK
|
||||||
|
^^^^^^^^^^
|
||||||
|
|
||||||
|
Memory map::
|
||||||
|
|
||||||
|
0x20000000 - 3FFFFFFF SDRAM (512 MB)
|
||||||
|
|
||||||
|
Environment variables
|
||||||
|
|
||||||
|
U-Boot environment variables can be stored at different places:
|
||||||
|
|
||||||
|
- Nand flash
|
||||||
|
- SD/MMC card
|
||||||
|
- Serialflash on SPI chip select 0
|
||||||
|
|
||||||
|
You can choose your storage location at config step (here for sama5d3xek)::
|
||||||
|
|
||||||
|
make sama5d3xek_mmc_config - use SD/MMC card
|
||||||
|
make sama5d3xek_nandflash_config - use nand flash
|
||||||
|
make sama5d3xek_serialflash_config - use serial flash
|
||||||
|
|
||||||
|
|
||||||
|
NAND partition table
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
All the board support boot from NAND flash will use the following NAND
|
||||||
|
partition table::
|
||||||
|
|
||||||
|
0x00000000 - 0x0003FFFF bootstrap (256 KiB)
|
||||||
|
0x00040000 - 0x000BFFFF u-boot (512 KiB)
|
||||||
|
0x000C0000 - 0x000FFFFF env (256 KiB)
|
||||||
|
0x00100000 - 0x0013FFFF env_redundant (256 KiB)
|
||||||
|
0x00140000 - 0x0017FFFF spare (256 KiB)
|
||||||
|
0x00180000 - 0x001FFFFF dtb (512 KiB)
|
||||||
|
0x00200000 - 0x007FFFFF kernel (6 MiB)
|
||||||
|
0x00800000 - 0xxxxxxxxx rootfs (All left)
|
||||||
|
|
||||||
|
|
||||||
|
Watchdog support
|
||||||
|
----------------
|
||||||
|
|
||||||
|
For security reasons, the at91 watchdog is running at boot time and,
|
||||||
|
if deactivated, cannot be used anymore.
|
||||||
|
If you want to use the watchdog, you will need to keep it running in
|
||||||
|
your code (make sure not to disable it in AT91Bootstrap for instance).
|
||||||
|
|
||||||
|
In the U-Boot configuration, the AT91 watchdog support is enabled using
|
||||||
|
the CONFIG_WDT and CONFIG_WDT_AT91 options.
|
42
doc/board/coreboot/coreboot.rst
Normal file
42
doc/board/coreboot/coreboot.rst
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
.. SPDX-License-Identifier: GPL-2.0+
|
||||||
|
.. sectionauthor:: Bin Meng <bmeng.cn@gmail.com>
|
||||||
|
|
||||||
|
Coreboot
|
||||||
|
========
|
||||||
|
|
||||||
|
Build Instructions for U-Boot as coreboot payload
|
||||||
|
-------------------------------------------------
|
||||||
|
Building U-Boot as a coreboot payload is just like building U-Boot for targets
|
||||||
|
on other architectures, like below::
|
||||||
|
|
||||||
|
$ make coreboot_defconfig
|
||||||
|
$ make all
|
||||||
|
|
||||||
|
Test with coreboot
|
||||||
|
------------------
|
||||||
|
For testing U-Boot as the coreboot payload, there are things that need be paid
|
||||||
|
attention to. coreboot supports loading an ELF executable and a 32-bit plain
|
||||||
|
binary, as well as other supported payloads. With the default configuration,
|
||||||
|
U-Boot is set up to use a separate Device Tree Blob (dtb). As of today, the
|
||||||
|
generated u-boot-dtb.bin needs to be packaged by the cbfstool utility (a tool
|
||||||
|
provided by coreboot) manually as coreboot's 'make menuconfig' does not provide
|
||||||
|
this capability yet. The command is as follows::
|
||||||
|
|
||||||
|
# in the coreboot root directory
|
||||||
|
$ ./build/util/cbfstool/cbfstool build/coreboot.rom add-flat-binary \
|
||||||
|
-f u-boot-dtb.bin -n fallback/payload -c lzma -l 0x1110000 -e 0x1110000
|
||||||
|
|
||||||
|
Make sure 0x1110000 matches CONFIG_SYS_TEXT_BASE, which is the symbol address
|
||||||
|
of _x86boot_start (in arch/x86/cpu/start.S).
|
||||||
|
|
||||||
|
If you want to use ELF as the coreboot payload, change U-Boot configuration to
|
||||||
|
use CONFIG_OF_EMBED instead of CONFIG_OF_SEPARATE.
|
||||||
|
|
||||||
|
To enable video you must enable these options in coreboot:
|
||||||
|
|
||||||
|
- Set framebuffer graphics resolution (1280x1024 32k-color (1:5:5))
|
||||||
|
- Keep VESA framebuffer
|
||||||
|
|
||||||
|
At present it seems that for Minnowboard Max, coreboot does not pass through
|
||||||
|
the video information correctly (it always says the resolution is 0x0). This
|
||||||
|
works correctly for link though.
|
9
doc/board/coreboot/index.rst
Normal file
9
doc/board/coreboot/index.rst
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
.. SPDX-License-Identifier: GPL-2.0+
|
||||||
|
|
||||||
|
Coreboot
|
||||||
|
========
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 2
|
||||||
|
|
||||||
|
coreboot
|
12
doc/board/emulation/index.rst
Normal file
12
doc/board/emulation/index.rst
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
.. SPDX-License-Identifier: GPL-2.0+
|
||||||
|
|
||||||
|
Emulation
|
||||||
|
=========
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 2
|
||||||
|
|
||||||
|
qemu-arm
|
||||||
|
qemu-mips
|
||||||
|
qemu-riscv
|
||||||
|
qemu-x86
|
|
@ -1,9 +1,8 @@
|
||||||
# SPDX-License-Identifier: GPL-2.0+
|
.. SPDX-License-Identifier: GPL-2.0+
|
||||||
#
|
.. Copyright (C) 2017, Tuomas Tynkkynen <tuomas.tynkkynen@iki.fi>
|
||||||
# Copyright (C) 2017, Tuomas Tynkkynen <tuomas.tynkkynen@iki.fi>
|
|
||||||
|
|
||||||
U-Boot on QEMU's 'virt' machine on ARM & AArch64
|
QEMU ARM
|
||||||
================================================
|
========
|
||||||
|
|
||||||
QEMU for ARM supports a special 'virt' machine designed for emulation and
|
QEMU for ARM supports a special 'virt' machine designed for emulation and
|
||||||
virtualization purposes. This document describes how to run U-Boot under it.
|
virtualization purposes. This document describes how to run U-Boot under it.
|
||||||
|
@ -26,11 +25,13 @@ Building U-Boot
|
||||||
---------------
|
---------------
|
||||||
Set the CROSS_COMPILE environment variable as usual, and run:
|
Set the CROSS_COMPILE environment variable as usual, and run:
|
||||||
|
|
||||||
- For ARM:
|
- For ARM::
|
||||||
|
|
||||||
make qemu_arm_defconfig
|
make qemu_arm_defconfig
|
||||||
make
|
make
|
||||||
|
|
||||||
- For AArch64:
|
- For AArch64::
|
||||||
|
|
||||||
make qemu_arm64_defconfig
|
make qemu_arm64_defconfig
|
||||||
make
|
make
|
||||||
|
|
||||||
|
@ -38,31 +39,44 @@ Running U-Boot
|
||||||
--------------
|
--------------
|
||||||
The minimal QEMU command line to get U-Boot up and running is:
|
The minimal QEMU command line to get U-Boot up and running is:
|
||||||
|
|
||||||
- For ARM:
|
- For ARM::
|
||||||
|
|
||||||
qemu-system-arm -machine virt -bios u-boot.bin
|
qemu-system-arm -machine virt -bios u-boot.bin
|
||||||
|
|
||||||
- For AArch64:
|
- For AArch64::
|
||||||
|
|
||||||
qemu-system-aarch64 -machine virt -cpu cortex-a57 -bios u-boot.bin
|
qemu-system-aarch64 -machine virt -cpu cortex-a57 -bios u-boot.bin
|
||||||
|
|
||||||
Note that for some odd reason qemu-system-aarch64 needs to be explicitly
|
Note that for some odd reason qemu-system-aarch64 needs to be explicitly
|
||||||
told to use a 64-bit CPU or it will boot in 32-bit mode.
|
told to use a 64-bit CPU or it will boot in 32-bit mode.
|
||||||
|
|
||||||
Additional persistent U-boot environment support can be added as follows:
|
Additional persistent U-boot environment support can be added as follows:
|
||||||
- Create envstore.img using qemu-img:
|
|
||||||
|
- Create envstore.img using qemu-img::
|
||||||
|
|
||||||
qemu-img create -f raw envstore.img 64M
|
qemu-img create -f raw envstore.img 64M
|
||||||
- Add a pflash drive parameter to the command line:
|
|
||||||
|
- Add a pflash drive parameter to the command line::
|
||||||
|
|
||||||
-drive if=pflash,format=raw,index=1,file=envstore.img
|
-drive if=pflash,format=raw,index=1,file=envstore.img
|
||||||
|
|
||||||
Additional peripherals that have been tested to work in both U-Boot and Linux
|
Additional peripherals that have been tested to work in both U-Boot and Linux
|
||||||
can be enabled with the following command line parameters:
|
can be enabled with the following command line parameters:
|
||||||
|
|
||||||
- To add a Serial ATA disk via an Intel ICH9 AHCI controller, pass e.g.:
|
- To add a Serial ATA disk via an Intel ICH9 AHCI controller, pass e.g.::
|
||||||
|
|
||||||
-drive if=none,file=disk.img,id=mydisk -device ich9-ahci,id=ahci -device ide-drive,drive=mydisk,bus=ahci.0
|
-drive if=none,file=disk.img,id=mydisk -device ich9-ahci,id=ahci -device ide-drive,drive=mydisk,bus=ahci.0
|
||||||
- To add an Intel E1000 network adapter, pass e.g.:
|
|
||||||
|
- To add an Intel E1000 network adapter, pass e.g.::
|
||||||
|
|
||||||
-netdev user,id=net0 -device e1000,netdev=net0
|
-netdev user,id=net0 -device e1000,netdev=net0
|
||||||
- To add an EHCI-compliant USB host controller, pass e.g.:
|
|
||||||
|
- To add an EHCI-compliant USB host controller, pass e.g.::
|
||||||
|
|
||||||
-device usb-ehci,id=ehci
|
-device usb-ehci,id=ehci
|
||||||
- To add a NVMe disk, pass e.g.:
|
|
||||||
|
- To add a NVMe disk, pass e.g.::
|
||||||
|
|
||||||
-drive if=none,file=disk.img,id=mydisk -device nvme,drive=mydisk,serial=foo
|
-drive if=none,file=disk.img,id=mydisk -device nvme,drive=mydisk,serial=foo
|
||||||
|
|
||||||
These have been tested in QEMU 2.9.0 but should work in at least 2.5.0 as well.
|
These have been tested in QEMU 2.9.0 but should work in at least 2.5.0 as well.
|
234
doc/board/emulation/qemu-mips.rst
Normal file
234
doc/board/emulation/qemu-mips.rst
Normal file
|
@ -0,0 +1,234 @@
|
||||||
|
.. SPDX-License-Identifier: GPL-2.0+
|
||||||
|
.. sectionauthor:: Vlad Lungu <vlad.lungu@windriver.com>
|
||||||
|
|
||||||
|
QEMU MIPS
|
||||||
|
=========
|
||||||
|
|
||||||
|
Qemu is a full system emulator. See http://www.nongnu.org/qemu/
|
||||||
|
|
||||||
|
Limitations & comments
|
||||||
|
----------------------
|
||||||
|
Supports the "-M mips" configuration of qemu: serial,NE2000,IDE.
|
||||||
|
Supports little and big endian as well as 32 bit and 64 bit.
|
||||||
|
Derived from au1x00 with a lot of things cut out.
|
||||||
|
|
||||||
|
Supports emulated flash (patch Jean-Christophe PLAGNIOL-VILLARD) with
|
||||||
|
recent qemu versions. When using emulated flash, launch with
|
||||||
|
-pflash <filename> and erase mips_bios.bin.
|
||||||
|
|
||||||
|
|
||||||
|
Notes for the Qemu MIPS port
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
Example usage
|
||||||
|
^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Using u-boot.bin as ROM (replaces Qemu monitor):
|
||||||
|
|
||||||
|
32 bit, big endian::
|
||||||
|
|
||||||
|
# make qemu_mips
|
||||||
|
# qemu-system-mips -M mips -bios u-boot.bin -nographic
|
||||||
|
|
||||||
|
32 bit, little endian::
|
||||||
|
|
||||||
|
# make qemu_mipsel
|
||||||
|
# qemu-system-mipsel -M mips -bios u-boot.bin -nographic
|
||||||
|
|
||||||
|
64 bit, big endian::
|
||||||
|
|
||||||
|
# make qemu_mips64
|
||||||
|
# qemu-system-mips64 -cpu MIPS64R2-generic -M mips -bios u-boot.bin -nographic
|
||||||
|
|
||||||
|
64 bit, little endian::
|
||||||
|
|
||||||
|
# make qemu_mips64el
|
||||||
|
# qemu-system-mips64el -cpu MIPS64R2-generic -M mips -bios u-boot.bin -nographic
|
||||||
|
|
||||||
|
or using u-boot.bin from emulated flash:
|
||||||
|
|
||||||
|
if you use a qemu version after commit 4224
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
|
create image:
|
||||||
|
# dd of=flash bs=1k count=4k if=/dev/zero
|
||||||
|
# dd of=flash bs=1k conv=notrunc if=u-boot.bin
|
||||||
|
start it (see above):
|
||||||
|
# qemu-system-mips[64][el] [-cpu MIPS64R2-generic] -M mips -pflash flash -nographic
|
||||||
|
|
||||||
|
Download kernel + initrd
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
On ftp://ftp.denx.de/pub/contrib/Jean-Christophe_Plagniol-Villard/qemu_mips/
|
||||||
|
you can downland::
|
||||||
|
|
||||||
|
#config to build the kernel
|
||||||
|
qemu_mips_defconfig
|
||||||
|
#patch to fix mips interrupt init on 2.6.24.y kernel
|
||||||
|
qemu_mips_kernel.patch
|
||||||
|
initrd.gz
|
||||||
|
vmlinux
|
||||||
|
vmlinux.bin
|
||||||
|
System.map
|
||||||
|
|
||||||
|
Generate uImage
|
||||||
|
^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
|
# tools/mkimage -A mips -O linux -T kernel -C gzip -a 0x80010000 -e 0x80245650 -n "Linux 2.6.24.y" -d vmlinux.bin.gz uImage
|
||||||
|
|
||||||
|
Copy uImage to Flash
|
||||||
|
^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
|
# dd if=uImage bs=1k conv=notrunc seek=224 of=flash
|
||||||
|
|
||||||
|
Generate Ide Disk
|
||||||
|
^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
|
# dd of=ide bs=1k cout=100k if=/dev/zero
|
||||||
|
|
||||||
|
# sfdisk -C 261 -d ide
|
||||||
|
# partition table of ide
|
||||||
|
unit: sectors
|
||||||
|
|
||||||
|
ide1 : start= 63, size= 32067, Id=83
|
||||||
|
ide2 : start= 32130, size= 32130, Id=83
|
||||||
|
ide3 : start= 64260, size= 4128705, Id=83
|
||||||
|
ide4 : start= 0, size= 0, Id= 0
|
||||||
|
|
||||||
|
Copy to ide
|
||||||
|
^^^^^^^^^^^
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
|
# dd if=uImage bs=512 conv=notrunc seek=63 of=ide
|
||||||
|
|
||||||
|
Generate ext2 on part 2 on Copy uImage and initrd.gz
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
|
# Attached as loop device ide offset = 32130 * 512
|
||||||
|
# losetup -o 16450560 -f ide
|
||||||
|
# Format as ext2 ( arg2 : nb blocks)
|
||||||
|
# mke2fs /dev/loop0 16065
|
||||||
|
# losetup -d /dev/loop0
|
||||||
|
# Mount and copy uImage and initrd.gz to it
|
||||||
|
# mount -o loop,offset=16450560 -t ext2 ide /mnt
|
||||||
|
# mkdir /mnt/boot
|
||||||
|
# cp {initrd.gz,uImage} /mnt/boot/
|
||||||
|
# Umount it
|
||||||
|
# umount /mnt
|
||||||
|
|
||||||
|
Set Environment
|
||||||
|
^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
|
setenv rd_start 0x80800000
|
||||||
|
setenv rd_size 2663940
|
||||||
|
setenv kernel BFC38000
|
||||||
|
setenv oad_addr 80500000
|
||||||
|
setenv load_addr2 80F00000
|
||||||
|
setenv kernel_flash BFC38000
|
||||||
|
setenv load_addr_hello 80200000
|
||||||
|
setenv bootargs 'root=/dev/ram0 init=/bin/sh'
|
||||||
|
setenv load_rd_ext2 'ide res; ext2load ide 0:2 ${rd_start} /boot/initrd.gz'
|
||||||
|
setenv load_rd_tftp 'tftp ${rd_start} /initrd.gz'
|
||||||
|
setenv load_kernel_hda 'ide res; diskboot ${load_addr} 0:2'
|
||||||
|
setenv load_kernel_ext2 'ide res; ext2load ide 0:2 ${load_addr} /boot/uImage'
|
||||||
|
setenv load_kernel_tftp 'tftp ${load_addr} /qemu_mips/uImage'
|
||||||
|
setenv boot_ext2_ext2 'run load_rd_ext2; run load_kernel_ext2; run addmisc; bootm ${load_addr}'
|
||||||
|
setenv boot_ext2_flash 'run load_rd_ext2; run addmisc; bootm ${kernel_flash}'
|
||||||
|
setenv boot_ext2_hda 'run load_rd_ext2; run load_kernel_hda; run addmisc; bootm ${load_addr}'
|
||||||
|
setenv boot_ext2_tftp 'run load_rd_ext2; run load_kernel_tftp; run addmisc; bootm ${load_addr}'
|
||||||
|
setenv boot_tftp_hda 'run load_rd_tftp; run load_kernel_hda; run addmisc; bootm ${load_addr}'
|
||||||
|
setenv boot_tftp_ext2 'run load_rd_tftp; run load_kernel_ext2; run addmisc; bootm ${load_addr}'
|
||||||
|
setenv boot_tftp_flash 'run load_rd_tftp; run addmisc; bootm ${kernel_flash}'
|
||||||
|
setenv boot_tftp_tftp 'run load_rd_tftp; run load_kernel_tftp; run addmisc; bootm ${load_addr}'
|
||||||
|
setenv load_hello_tftp 'tftp ${load_addr_hello} /examples/hello_world.bin'
|
||||||
|
setenv go_tftp 'run load_hello_tftp; go ${load_addr_hello}'
|
||||||
|
setenv addmisc 'setenv bootargs ${bootargs} console=ttyS0,${baudrate} rd_start=${rd_start} rd_size=${rd_size} ethaddr=${ethaddr}'
|
||||||
|
setenv bootcmd 'run boot_tftp_flash'
|
||||||
|
|
||||||
|
Now you can boot from flash, ide, ide+ext2 and tfp::
|
||||||
|
|
||||||
|
# qemu-system-mips -M mips -pflash flash -monitor null -nographic -net nic -net user -tftp `pwd` -hda ide
|
||||||
|
|
||||||
|
|
||||||
|
How to debug U-Boot
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
In order to debug U-Boot you need to start qemu with gdb server support (-s)
|
||||||
|
and waiting the connection to start the CPU (-S)
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
|
# qemu-system-mips -S -s -M mips -pflash flash -monitor null -nographic -net nic -net user -tftp `pwd` -hda ide
|
||||||
|
|
||||||
|
in an other console you start gdb
|
||||||
|
|
||||||
|
Debugging of U-Boot Before Relocation
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Before relocation, the addresses in the ELF file can be used without any problems
|
||||||
|
by connecting to the gdb server localhost:1234
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
|
# mipsel-unknown-linux-gnu-gdb u-boot
|
||||||
|
GNU gdb 6.6
|
||||||
|
Copyright (C) 2006 Free Software Foundation, Inc.
|
||||||
|
GDB is free software, covered by the GNU General Public License, and you are
|
||||||
|
welcome to change it and/or distribute copies of it under certain conditions.
|
||||||
|
Type "show copying" to see the conditions.
|
||||||
|
There is absolutely no warranty for GDB. Type "show warranty" for details.
|
||||||
|
This GDB was configured as "--host=i486-linux-gnu --target=mipsel-unknown-linux-gnu"...
|
||||||
|
(gdb) target remote localhost:1234
|
||||||
|
Remote debugging using localhost:1234
|
||||||
|
_start () at start.S:64
|
||||||
|
64 RVECENT(reset,0) /* U-Boot entry point */
|
||||||
|
Current language: auto; currently asm
|
||||||
|
(gdb) b board.c:289
|
||||||
|
Breakpoint 1 at 0xbfc00cc8: file board.c, line 289.
|
||||||
|
(gdb) c
|
||||||
|
Continuing.
|
||||||
|
|
||||||
|
Breakpoint 1, board_init_f (bootflag=<value optimized out>) at board.c:290
|
||||||
|
290 relocate_code (addr_sp, id, addr);
|
||||||
|
Current language: auto; currently c
|
||||||
|
(gdb) p/x addr
|
||||||
|
$1 = 0x87fa0000
|
||||||
|
|
||||||
|
Debugging of U-Boot After Relocation
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
For debugging U-Boot after relocation we need to know the address to which
|
||||||
|
U-Boot relocates itself to 0x87fa0000 by default.
|
||||||
|
And replace the symbol table to this offset.
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
|
(gdb) symbol-file
|
||||||
|
Discard symbol table from `/private/u-boot-arm/u-boot'? (y or n) y
|
||||||
|
Error in re-setting breakpoint 1:
|
||||||
|
No symbol table is loaded. Use the "file" command.
|
||||||
|
No symbol file now.
|
||||||
|
(gdb) add-symbol-file u-boot 0x87fa0000
|
||||||
|
add symbol table from file "u-boot" at
|
||||||
|
.text_addr = 0x87fa0000
|
||||||
|
(y or n) y
|
||||||
|
Reading symbols from /private/u-boot-arm/u-boot...done.
|
||||||
|
Breakpoint 1 at 0x87fa0cc8: file board.c, line 289.
|
||||||
|
(gdb) c
|
||||||
|
Continuing.
|
||||||
|
|
||||||
|
Program received signal SIGINT, Interrupt.
|
||||||
|
0xffffffff87fa0de4 in udelay (usec=<value optimized out>) at time.c:78
|
||||||
|
78 while ((tmo - read_c0_count()) < 0x7fffffff)
|
|
@ -1,9 +1,8 @@
|
||||||
# SPDX-License-Identifier: GPL-2.0+
|
.. SPDX-License-Identifier: GPL-2.0+
|
||||||
#
|
.. Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
|
||||||
# Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
|
|
||||||
|
|
||||||
U-Boot on QEMU's 'virt' machine on RISC-V
|
QEMU RISC-V
|
||||||
=========================================
|
===========
|
||||||
|
|
||||||
QEMU for RISC-V supports a special 'virt' machine designed for emulation and
|
QEMU for RISC-V supports a special 'virt' machine designed for emulation and
|
||||||
virtualization purposes. This document describes how to run U-Boot under it.
|
virtualization purposes. This document describes how to run U-Boot under it.
|
||||||
|
@ -19,11 +18,13 @@ Building U-Boot
|
||||||
---------------
|
---------------
|
||||||
Set the CROSS_COMPILE environment variable as usual, and run:
|
Set the CROSS_COMPILE environment variable as usual, and run:
|
||||||
|
|
||||||
- For 32-bit RISC-V:
|
- For 32-bit RISC-V::
|
||||||
|
|
||||||
make qemu-riscv32_defconfig
|
make qemu-riscv32_defconfig
|
||||||
make
|
make
|
||||||
|
|
||||||
- For 64-bit RISC-V:
|
- For 64-bit RISC-V::
|
||||||
|
|
||||||
make qemu-riscv64_defconfig
|
make qemu-riscv64_defconfig
|
||||||
make
|
make
|
||||||
|
|
||||||
|
@ -31,10 +32,12 @@ Running U-Boot
|
||||||
--------------
|
--------------
|
||||||
The minimal QEMU command line to get U-Boot up and running is:
|
The minimal QEMU command line to get U-Boot up and running is:
|
||||||
|
|
||||||
- For 32-bit RISC-V:
|
- For 32-bit RISC-V::
|
||||||
|
|
||||||
qemu-system-riscv32 -nographic -machine virt -kernel u-boot
|
qemu-system-riscv32 -nographic -machine virt -kernel u-boot
|
||||||
|
|
||||||
- For 64-bit RISC-V:
|
- For 64-bit RISC-V::
|
||||||
|
|
||||||
qemu-system-riscv64 -nographic -machine virt -kernel u-boot
|
qemu-system-riscv64 -nographic -machine virt -kernel u-boot
|
||||||
|
|
||||||
The commands above create targets with 128MiB memory by default.
|
The commands above create targets with 128MiB memory by default.
|
101
doc/board/emulation/qemu-x86.rst
Normal file
101
doc/board/emulation/qemu-x86.rst
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
.. SPDX-License-Identifier: GPL-2.0+
|
||||||
|
.. sectionauthor:: Bin Meng <bmeng.cn@gmail.com>
|
||||||
|
|
||||||
|
QEMU x86
|
||||||
|
========
|
||||||
|
|
||||||
|
Build instructions for bare mode
|
||||||
|
--------------------------------
|
||||||
|
|
||||||
|
To build u-boot.rom for QEMU x86 targets, just simply run::
|
||||||
|
|
||||||
|
$ make qemu-x86_defconfig (for 32-bit)
|
||||||
|
$ make qemu-x86_64_defconfig (for 64-bit)
|
||||||
|
$ make all
|
||||||
|
|
||||||
|
Note this default configuration will build a U-Boot for the QEMU x86 i440FX
|
||||||
|
board. To build a U-Boot against QEMU x86 Q35 board, you can change the build
|
||||||
|
configuration during the 'make menuconfig' process like below::
|
||||||
|
|
||||||
|
Device Tree Control --->
|
||||||
|
...
|
||||||
|
(qemu-x86_q35) Default Device Tree for DT control
|
||||||
|
|
||||||
|
Test with QEMU for bare mode
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
QEMU is a fancy emulator that can enable us to test U-Boot without access to
|
||||||
|
a real x86 board. Please make sure your QEMU version is 2.3.0 or above test
|
||||||
|
U-Boot. To launch QEMU with u-boot.rom, call QEMU as follows::
|
||||||
|
|
||||||
|
$ qemu-system-i386 -nographic -bios path/to/u-boot.rom
|
||||||
|
|
||||||
|
This will instantiate an emulated x86 board with i440FX and PIIX chipset. QEMU
|
||||||
|
also supports emulating an x86 board with Q35 and ICH9 based chipset, which is
|
||||||
|
also supported by U-Boot. To instantiate such a machine, call QEMU with::
|
||||||
|
|
||||||
|
$ qemu-system-i386 -nographic -bios path/to/u-boot.rom -M q35
|
||||||
|
|
||||||
|
Note by default QEMU instantiated boards only have 128 MiB system memory. But
|
||||||
|
it is enough to have U-Boot boot and function correctly. You can increase the
|
||||||
|
system memory by pass '-m' parameter to QEMU if you want more memory::
|
||||||
|
|
||||||
|
$ qemu-system-i386 -nographic -bios path/to/u-boot.rom -m 1024
|
||||||
|
|
||||||
|
This creates a board with 1 GiB system memory. Currently U-Boot for QEMU only
|
||||||
|
supports 3 GiB maximum system memory and reserves the last 1 GiB address space
|
||||||
|
for PCI device memory-mapped I/O and other stuff, so the maximum value of '-m'
|
||||||
|
would be 3072.
|
||||||
|
|
||||||
|
QEMU emulates a graphic card which U-Boot supports. Removing '-nographic' will
|
||||||
|
show QEMU's VGA console window. Note this will disable QEMU's serial output.
|
||||||
|
If you want to check both consoles, use '-serial stdio'.
|
||||||
|
|
||||||
|
Multicore is also supported by QEMU via '-smp n' where n is the number of cores
|
||||||
|
to instantiate. Note, the maximum supported CPU number in QEMU is 255.
|
||||||
|
|
||||||
|
The fw_cfg interface in QEMU also provides information about kernel data,
|
||||||
|
initrd, command-line arguments and more. U-Boot supports directly accessing
|
||||||
|
these informtion from fw_cfg interface, which saves the time of loading them
|
||||||
|
from hard disk or network again, through emulated devices. To use it , simply
|
||||||
|
providing them in QEMU command line::
|
||||||
|
|
||||||
|
$ qemu-system-i386 -nographic -bios path/to/u-boot.rom -m 1024 \
|
||||||
|
-kernel /path/to/bzImage -append 'root=/dev/ram console=ttyS0' \
|
||||||
|
-initrd /path/to/initrd -smp 8
|
||||||
|
|
||||||
|
Note: -initrd and -smp are both optional
|
||||||
|
|
||||||
|
Then start QEMU, in U-Boot command line use the following U-Boot command to
|
||||||
|
setup kernel::
|
||||||
|
|
||||||
|
=> qfw
|
||||||
|
qfw - QEMU firmware interface
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
qfw <command>
|
||||||
|
- list : print firmware(s) currently loaded
|
||||||
|
- cpus : print online cpu number
|
||||||
|
- load <kernel addr> <initrd addr> : load kernel and initrd (if any) and setup for zboot
|
||||||
|
|
||||||
|
=> qfw load
|
||||||
|
loading kernel to address 01000000 size 5d9d30 initrd 04000000 size 1b1ab50
|
||||||
|
|
||||||
|
Here the kernel (bzImage) is loaded to 01000000 and initrd is to 04000000. Then,
|
||||||
|
'zboot' can be used to boot the kernel::
|
||||||
|
|
||||||
|
=> zboot 01000000 - 04000000 1b1ab50
|
||||||
|
|
||||||
|
To run 64-bit U-Boot, qemu-system-x86_64 should be used instead, e.g.::
|
||||||
|
|
||||||
|
$ qemu-system-x86_64 -nographic -bios path/to/u-boot.rom
|
||||||
|
|
||||||
|
A specific CPU can be specified via the '-cpu' parameter but please make
|
||||||
|
sure the specified CPU supports 64-bit like '-cpu core2duo'. Conversely
|
||||||
|
'-cpu pentium' won't work for obvious reasons that the processor only
|
||||||
|
supports 32-bit.
|
||||||
|
|
||||||
|
Note 64-bit support is very preliminary at this point. Lots of features
|
||||||
|
are missing in the 64-bit world. One notable feature is the VGA console
|
||||||
|
support which is currently missing, so that you must specify '-nographic'
|
||||||
|
to get 64-bit U-Boot up and running.
|
453
doc/board/freescale/b4860qds.rst
Normal file
453
doc/board/freescale/b4860qds.rst
Normal file
|
@ -0,0 +1,453 @@
|
||||||
|
.. SPDX-License-Identifier: GPL-2.0+
|
||||||
|
|
||||||
|
B4860QDS
|
||||||
|
========
|
||||||
|
|
||||||
|
The B4860QDS is a Freescale reference board that hosts the B4860 SoC
|
||||||
|
(and variants).
|
||||||
|
|
||||||
|
B4860 Overview
|
||||||
|
--------------
|
||||||
|
The B4860 QorIQ Qonverge device is a Freescale high-end, multicore SoC based on
|
||||||
|
StarCore and Power Architecture® cores. It targets the broadband wireless
|
||||||
|
infrastructure and builds upon the proven success of the existing multicore
|
||||||
|
DSPs and Power CPUs. It is designed to bolster the rapidly changing and
|
||||||
|
expanding wireless markets, such as 3GLTE (FDD and TDD), LTE-Advanced, and UMTS.
|
||||||
|
|
||||||
|
The B4860 is a highly-integrated StarCore and Power Architecture processor that
|
||||||
|
contains:
|
||||||
|
|
||||||
|
* Six fully-programmable StarCore SC3900 FVP subsystems, divided into three
|
||||||
|
clusters-each core runs up to 1.2 GHz, with an architecture highly optimized
|
||||||
|
for wireless base station applications
|
||||||
|
* Four dual-thread e6500 Power Architecture processors organized in one
|
||||||
|
cluster-each core runs up to 1.8 GHz
|
||||||
|
* Two DDR3/3L controllers for high-speed, industry-standard memory interface
|
||||||
|
each runs at up to 1866.67 MHz
|
||||||
|
* MAPLE-B3 hardware acceleration-for forward error correction schemes including
|
||||||
|
Turbo or Viterbi decoding, Turbo encoding and rate matching, MIMO MMSE
|
||||||
|
equalization scheme, matrix operations, CRC insertion and check, DFT/iDFT and
|
||||||
|
FFT/iFFT calculations, PUSCH/PDSCH acceleration, and UMTS chip rate
|
||||||
|
acceleration
|
||||||
|
* CoreNet fabric that fully supports coherency using MESI protocol between the
|
||||||
|
e6500 cores, SC3900 FVP cores, memories and external interfaces.
|
||||||
|
CoreNet fabric interconnect runs at 667 MHz and supports coherent and
|
||||||
|
non-coherent out of order transactions with prioritization and bandwidth
|
||||||
|
allocation amongst CoreNet endpoints.
|
||||||
|
* Data Path Acceleration Architecture, which includes the following:
|
||||||
|
|
||||||
|
* Frame Manager (FMan), which supports in-line packet parsing and general
|
||||||
|
classification to enable policing and QoS-based packet distribution
|
||||||
|
* Queue Manager (QMan) and Buffer Manager (BMan), which allow offloading
|
||||||
|
of queue management, task management, load distribution, flow ordering,
|
||||||
|
buffer management, and allocation tasks from the cores
|
||||||
|
* Security engine (SEC 5.3)-crypto-acceleration for protocols such as
|
||||||
|
IPsec, SSL, and 802.16
|
||||||
|
* RapidIO manager (RMAN) - Support SRIO types 8, 9, 10, and 11 (inbound
|
||||||
|
and outbound). Supports types 5, 6 (outbound only)
|
||||||
|
|
||||||
|
* Large internal cache memory with snooping and stashing capabilities for
|
||||||
|
bandwidth saving and high utilization of processor elements. The 9856-Kbyte
|
||||||
|
internal memory space includes the following:
|
||||||
|
|
||||||
|
* 32 Kbyte L1 ICache per e6500/SC3900 core
|
||||||
|
* 32 Kbyte L1 DCache per e6500/SC3900 core
|
||||||
|
* 2048 Kbyte unified L2 cache for each SC3900 FVP cluster
|
||||||
|
* 2048 Kbyte unified L2 cache for the e6500 cluster
|
||||||
|
* Two 512 Kbyte shared L3 CoreNet platform caches (CPC)
|
||||||
|
|
||||||
|
* Sixteen 10-GHz SerDes lanes serving:
|
||||||
|
|
||||||
|
* Two Serial RapidIO interfaces
|
||||||
|
* Each supports up to 4 lanes and a total of up to 8 lanes
|
||||||
|
|
||||||
|
* Up to 8-lanes Common Public Radio Interface (CPRI) controller for
|
||||||
|
glue-less antenna connection
|
||||||
|
* Two 10-Gbit Ethernet controllers (10GEC)
|
||||||
|
* Six 1G/2.5-Gbit Ethernet controllers for network communications
|
||||||
|
* PCI Express controller
|
||||||
|
* Debug (Aurora)
|
||||||
|
* Two OCeaN DMAs
|
||||||
|
* Various system peripherals
|
||||||
|
* 182 32-bit timers
|
||||||
|
|
||||||
|
B4860QDS Overview
|
||||||
|
-----------------
|
||||||
|
- DDRC1: Ten separate DDR3 parts of 16-bit to support 72-bit (ECC) at 1866MT/s,
|
||||||
|
ECC, 4 GB of memory in two ranks of 2 GB.
|
||||||
|
- DDRC2: Five separate DDR3 parts of 16-bit to support 72-bit (ECC) at 1866MT/s,
|
||||||
|
ECC, 2 GB of memory. Single rank.
|
||||||
|
- SerDes 1 multiplexing: Two Vitesse (transmit and receive path) cross-point
|
||||||
|
16x16 switch VSC3316
|
||||||
|
- SerDes 2 multiplexing: Two Vitesse (transmit and receive path) cross-point
|
||||||
|
8x8 switch VSC3308
|
||||||
|
- USB 2.0 ULPI PHY USB3315 by SMSC supports USB port in host mode.
|
||||||
|
B4860 UART port is available over USB-to-UART translator USB2SER or over
|
||||||
|
RS232 flat cable.
|
||||||
|
- A Vitesse dual SGMII phy VSC8662 links the B4860 SGMII lines to 2xRJ-45
|
||||||
|
copper connectors for Stand-alone mode and to the 1000Base-X over AMC
|
||||||
|
MicroTCA connector ports 0 and 2 for AMC mode.
|
||||||
|
- The B4860 configuration may be loaded from nine bits coded reset configuration
|
||||||
|
reset source. The RCW source is set by appropriate DIP-switches.
|
||||||
|
- 16-bit NOR Flash / PROMJet
|
||||||
|
- QIXIS 8-bit NOR Flash Emulator
|
||||||
|
- 8-bit NAND Flash
|
||||||
|
- 24-bit SPI Flash
|
||||||
|
- Long address I2C EEPROM
|
||||||
|
- Available debug interfaces are:
|
||||||
|
|
||||||
|
- On-board eCWTAP controller with ETH and USB I/F
|
||||||
|
- JTAG/COP 16-pin header for any external TAP controller
|
||||||
|
- External JTAG source over AMC to support B2B configuration
|
||||||
|
- 70-pin Aurora debug connector
|
||||||
|
|
||||||
|
- QIXIS (FPGA) logic:
|
||||||
|
- 2 KB internal memory space including
|
||||||
|
|
||||||
|
- IDT840NT4 clock synthesizer provides B4860 essential clocks : SYSCLK,
|
||||||
|
DDRCLK1,2 and RTCCLK.
|
||||||
|
- Two 8T49N222A SerDes ref clock devices support two SerDes port clock
|
||||||
|
frequency - total four refclk, including CPRI clock scheme.
|
||||||
|
|
||||||
|
|
||||||
|
B4420 Personality
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
B4420 is a reduced personality of B4860 with less core/clusters(both SC3900
|
||||||
|
and e6500), less DDR controllers, less serdes lanes, less SGMII interfaces
|
||||||
|
and reduced target frequencies.
|
||||||
|
|
||||||
|
Key differences between B4860 and B4420
|
||||||
|
---------------------------------------
|
||||||
|
|
||||||
|
B4420 has:
|
||||||
|
|
||||||
|
1. Less e6500 cores: 1 cluster with 2 e6500 cores
|
||||||
|
2. Less SC3900 cores/clusters: 1 cluster with 2 SC3900 cores per cluster
|
||||||
|
3. Single DDRC
|
||||||
|
4. 2X 4 lane serdes
|
||||||
|
5. 3 SGMII interfaces
|
||||||
|
6. no sRIO
|
||||||
|
7. no 10G
|
||||||
|
|
||||||
|
B4860QDS Default Settings
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
Switch Settings
|
||||||
|
---------------
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
|
SW1 OFF [0] OFF [0] OFF [0] OFF [0] OFF [0] OFF [0] OFF [0] OFF [0]
|
||||||
|
SW2 ON ON ON ON ON ON OFF OFF
|
||||||
|
SW3 OFF OFF OFF ON OFF OFF ON OFF
|
||||||
|
SW5 OFF OFF OFF OFF OFF OFF ON ON
|
||||||
|
|
||||||
|
Note:
|
||||||
|
|
||||||
|
- PCIe slots modes: All the PCIe devices work as Root Complex.
|
||||||
|
- Boot location: NOR flash.
|
||||||
|
|
||||||
|
SysClk/Core(e6500)/CCB/DDR/FMan/DDRCLK/StarCore/CPRI-Maple/eTVPE-Maple/ULB-Maple
|
||||||
|
66MHz/1.6GHz/667MHz/1.6GHz data rate/667MHz/133MHz/1200MHz/500MHz/800MHz/667MHz
|
||||||
|
|
||||||
|
NAND boot::
|
||||||
|
|
||||||
|
SW1 [1.1] = 0
|
||||||
|
SW2 [1.1] = 1
|
||||||
|
SW3 [1:4] = 0001
|
||||||
|
|
||||||
|
NOR boot::
|
||||||
|
|
||||||
|
SW1 [1.1] = 1
|
||||||
|
SW2 [1.1] = 0
|
||||||
|
SW3 [1:4] = 1000
|
||||||
|
|
||||||
|
B4420QDS Default Settings
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
Switch Settings
|
||||||
|
---------------
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
|
SW1 OFF[0] OFF [0] OFF [0] OFF [0] OFF [0] OFF [0] OFF [0] OFF [0]
|
||||||
|
SW2 ON OFF ON OFF ON ON OFF OFF
|
||||||
|
SW3 OFF OFF OFF ON OFF OFF ON OFF
|
||||||
|
SW5 OFF OFF OFF OFF OFF OFF ON ON
|
||||||
|
|
||||||
|
Note:
|
||||||
|
|
||||||
|
- PCIe slots modes: All the PCIe devices work as Root Complex.
|
||||||
|
- Boot location: NOR flash.
|
||||||
|
|
||||||
|
SysClk/Core(e6500)/CCB/DDR/FMan/DDRCLK/StarCore/CPRI-Maple/eTVPE-Maple/ULB-Maple
|
||||||
|
66MHz/1.6GHz/667MHz/1.6GHz data rate/667MHz/133MHz/1200MHz/500MHz/800MHz/667MHz
|
||||||
|
|
||||||
|
NAND boot::
|
||||||
|
|
||||||
|
SW1 [1.1] = 0
|
||||||
|
SW2 [1.1] = 1
|
||||||
|
SW3 [1:4] = 0001
|
||||||
|
|
||||||
|
NOR boot::
|
||||||
|
|
||||||
|
SW1 [1.1] = 1
|
||||||
|
SW2 [1.1] = 0
|
||||||
|
SW3 [1:4] = 1000
|
||||||
|
|
||||||
|
Memory map on B4860QDS
|
||||||
|
----------------------
|
||||||
|
The addresses in brackets are physical addresses.
|
||||||
|
|
||||||
|
============= ============= =============== =======
|
||||||
|
Start Address End Address Description Size
|
||||||
|
============= ============= =============== =======
|
||||||
|
0xF_FFDF_1000 0xF_FFFF_FFFF Free 2 MB
|
||||||
|
0xF_FFDF_0000 0xF_FFDF_0FFF IFC - FPGA 4 KB
|
||||||
|
0xF_FF81_0000 0xF_FFDE_FFFF Free 5 MB
|
||||||
|
0xF_FF80_0000 0xF_FF80_FFFF IFC NAND Flash 64 KB
|
||||||
|
0xF_FF00_0000 0xF_FF7F_FFFF Free 8 MB
|
||||||
|
0xF_FE00_0000 0xF_FEFF_FFFF CCSRBAR 16 MB
|
||||||
|
0xF_F801_0000 0xF_FDFF_FFFF Free 95 MB
|
||||||
|
0xF_F800_0000 0xF_F800_FFFF PCIe I/O Space 64 KB
|
||||||
|
0xF_F600_0000 0xF_F7FF_FFFF QMAN s/w portal 32 MB
|
||||||
|
0xF_F400_0000 0xF_F5FF_FFFF BMAN s/w portal 32 MB
|
||||||
|
0xF_F000_0000 0xF_F3FF_FFFF Free 64 MB
|
||||||
|
0xF_E800_0000 0xF_EFFF_FFFF IFC NOR Flash 128 MB
|
||||||
|
0xF_E000_0000 0xF_E7FF_FFFF Promjet 128 MB
|
||||||
|
0xF_A0C0_0000 0xF_DFFF_FFFF Free 1012 MB
|
||||||
|
0xF_A000_0000 0xF_A0BF_FFFF MAPLE0/1/2 12 MB
|
||||||
|
0xF_0040_0000 0xF_9FFF_FFFF Free 12 GB
|
||||||
|
0xF_0000_0000 0xF_01FF_FFFF DCSR 32 MB
|
||||||
|
0xC_4000_0000 0xE_FFFF_FFFF Free 11 GB
|
||||||
|
0xC_3000_0000 0xC_3FFF_FFFF sRIO-2 I/O 256 MB
|
||||||
|
0xC_2000_0000 0xC_2FFF_FFFF sRIO-1 I/O 256 MB
|
||||||
|
0xC_0000_0000 0xC_1FFF_FFFF PCIe Mem Space 512 MB
|
||||||
|
0x1_0000_0000 0xB_FFFF_FFFF Free 44 GB
|
||||||
|
0x0_8000_0000 0x0_FFFF_FFFF DDRC1 2 GB
|
||||||
|
0x0_0000_0000 0x0_7FFF_FFFF DDRC2 2 GB
|
||||||
|
============= ============= =============== =======
|
||||||
|
|
||||||
|
Memory map on B4420QDS
|
||||||
|
----------------------
|
||||||
|
The addresses in brackets are physical addresses.
|
||||||
|
|
||||||
|
============= ============= =============== =======
|
||||||
|
Start Address End Address Description Size
|
||||||
|
============= ============= =============== =======
|
||||||
|
0xF_FFDF_1000 0xF_FFFF_FFFF Free 2 MB
|
||||||
|
0xF_FFDF_0000 0xF_FFDF_0FFF IFC - FPGA 4 KB
|
||||||
|
0xF_FF81_0000 0xF_FFDE_FFFF Free 5 MB
|
||||||
|
0xF_FF80_0000 0xF_FF80_FFFF IFC NAND Flash 64 KB
|
||||||
|
0xF_FF00_0000 0xF_FF7F_FFFF Free 8 MB
|
||||||
|
0xF_FE00_0000 0xF_FEFF_FFFF CCSRBAR 16 MB
|
||||||
|
0xF_F801_0000 0xF_FDFF_FFFF Free 95 MB
|
||||||
|
0xF_F800_0000 0xF_F800_FFFF PCIe I/O Space 64 KB
|
||||||
|
0xF_F600_0000 0xF_F7FF_FFFF QMAN s/w portal 32 MB
|
||||||
|
0xF_F400_0000 0xF_F5FF_FFFF BMAN s/w portal 32 MB
|
||||||
|
0xF_F000_0000 0xF_F3FF_FFFF Free 64 MB
|
||||||
|
0xF_E800_0000 0xF_EFFF_FFFF IFC NOR Flash 128 MB
|
||||||
|
0xF_E000_0000 0xF_E7FF_FFFF Promjet 128 MB
|
||||||
|
0xF_A0C0_0000 0xF_DFFF_FFFF Free 1012 MB
|
||||||
|
0xF_A000_0000 0xF_A0BF_FFFF MAPLE0/1/2 12 MB
|
||||||
|
0xF_0040_0000 0xF_9FFF_FFFF Free 12 GB
|
||||||
|
0xF_0000_0000 0xF_01FF_FFFF DCSR 32 MB
|
||||||
|
0xC_4000_0000 0xE_FFFF_FFFF Free 11 GB
|
||||||
|
0xC_3000_0000 0xC_3FFF_FFFF sRIO-2 I/O 256 MB
|
||||||
|
0xC_2000_0000 0xC_2FFF_FFFF sRIO-1 I/O 256 MB
|
||||||
|
0xC_0000_0000 0xC_1FFF_FFFF PCIe Mem Space 512 MB
|
||||||
|
0x1_0000_0000 0xB_FFFF_FFFF Free 44 GB
|
||||||
|
0x0_0000_0000 0x0_FFFF_FFFF DDRC1 4 GB
|
||||||
|
============= ============= =============== =======
|
||||||
|
|
||||||
|
NOR Flash memory Map on B4860 and B4420QDS
|
||||||
|
------------------------------------------
|
||||||
|
|
||||||
|
============= ============= ============================== =========
|
||||||
|
Start End Definition Size
|
||||||
|
============= ============= ============================== =========
|
||||||
|
0xEFF40000 0xEFFFFFFF U-Boot (current bank) 768KB
|
||||||
|
0xEFF20000 0xEFF3FFFF U-Boot env (current bank) 128KB
|
||||||
|
0xEFF00000 0xEFF1FFFF FMAN Ucode (current bank) 128KB
|
||||||
|
0xEF300000 0xEFEFFFFF rootfs (alternate bank) 12MB
|
||||||
|
0xEE800000 0xEE8FFFFF device tree (alternate bank) 1MB
|
||||||
|
0xEE020000 0xEE6FFFFF Linux.uImage (alternate bank) 6MB+896KB
|
||||||
|
0xEE000000 0xEE01FFFF RCW (alternate bank) 128KB
|
||||||
|
0xEDF40000 0xEDFFFFFF U-Boot (alternate bank) 768KB
|
||||||
|
0xEDF20000 0xEDF3FFFF U-Boot env (alternate bank) 128KB
|
||||||
|
0xEDF00000 0xEDF1FFFF FMAN ucode (alternate bank) 128KB
|
||||||
|
0xED300000 0xEDEFFFFF rootfs (current bank) 12MB
|
||||||
|
0xEC800000 0xEC8FFFFF device tree (current bank) 1MB
|
||||||
|
0xEC020000 0xEC6FFFFF Linux.uImage (current bank) 6MB+896KB
|
||||||
|
0xEC000000 0xEC01FFFF RCW (current bank) 128KB
|
||||||
|
============= ============= ============================== =========
|
||||||
|
|
||||||
|
Various Software configurations/environment variables/commands
|
||||||
|
--------------------------------------------------------------
|
||||||
|
The below commands apply to both B4860QDS and B4420QDS.
|
||||||
|
|
||||||
|
U-Boot environment variable hwconfig
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
The default hwconfig is:
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
|
hwconfig=fsl_ddr:ctlr_intlv=null,bank_intlv=cs0_cs1;usb1:dr_mode=host,phy_type=ulpi
|
||||||
|
|
||||||
|
Note: For USB gadget set "dr_mode=peripheral"
|
||||||
|
|
||||||
|
FMAN Ucode versions
|
||||||
|
^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
fsl_fman_ucode_B4860_106_3_6.bin
|
||||||
|
|
||||||
|
Switching to alternate bank
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Commands for switching to alternate bank.
|
||||||
|
|
||||||
|
1. To change from vbank0 to vbank2
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
|
=> qixis_reset altbank (it will boot using vbank2)
|
||||||
|
|
||||||
|
2. To change from vbank2 to vbank0
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
|
=> qixis reset (it will boot using vbank0)
|
||||||
|
|
||||||
|
To change personality of board
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
For changing personality from B4860 to B4420
|
||||||
|
|
||||||
|
1. Boot from vbank0
|
||||||
|
2. Flash vbank2 with b4420 rcw and U-Boot
|
||||||
|
3. Give following commands to uboot prompt
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
|
=> mw.b ffdf0040 0x30;
|
||||||
|
=> mw.b ffdf0010 0x00;
|
||||||
|
=> mw.b ffdf0062 0x02;
|
||||||
|
=> mw.b ffdf0050 0x02;
|
||||||
|
=> mw.b ffdf0010 0x30;
|
||||||
|
=> reset
|
||||||
|
|
||||||
|
Note:
|
||||||
|
|
||||||
|
- Power off cycle will lead to default switch settings.
|
||||||
|
- 0xffdf0000 is the address of the QIXIS FPGA.
|
||||||
|
|
||||||
|
Switching between NOR and NAND boot(RCW src changed from NOR <-> NAND)
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
To change from NOR to NAND boot give following command on uboot prompt
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
|
=> mw.b ffdf0040 0x30
|
||||||
|
=> mw.b ffdf0010 0x00
|
||||||
|
=> mw.b 0xffdf0050 0x08
|
||||||
|
=> mw.b 0xffdf0060 0x82
|
||||||
|
=> mw.b ffdf0061 0x00
|
||||||
|
=> mw.b ffdf0010 0x30
|
||||||
|
=> reset
|
||||||
|
|
||||||
|
To change from NAND to NOR boot give following command on uboot prompt:
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
|
=> mw.b ffdf0040 0x30
|
||||||
|
=> mw.b ffdf0010 0x00
|
||||||
|
=> mw.b 0xffdf0050 0x00(for vbank0) or (mw.b 0xffdf0050 0x02 for vbank2)
|
||||||
|
=> mw.b 0xffdf0060 0x12
|
||||||
|
=> mw.b ffdf0061 0x01
|
||||||
|
=> mw.b ffdf0010 0x30
|
||||||
|
=> reset
|
||||||
|
|
||||||
|
Note:
|
||||||
|
|
||||||
|
- Power off cycle will lead to default switch settings.
|
||||||
|
- 0xffdf0000 is the address of the QIXIS FPGA.
|
||||||
|
|
||||||
|
Ethernet interfaces for B4860QDS
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Serdes protocosl tested:
|
||||||
|
* 0x2a, 0x8d (serdes1, serdes2) [DEFAULT]
|
||||||
|
* 0x2a, 0xb2 (serdes1, serdes2)
|
||||||
|
|
||||||
|
When using [DEFAULT] RCW, which including 2 * 1G SGMII on board and 2 * 1G
|
||||||
|
SGMII on SGMII riser card.
|
||||||
|
|
||||||
|
Under U-Boot these network interfaces are recognized as::
|
||||||
|
|
||||||
|
FM1@DTSEC3, FM1@DTSEC4, FM1@DTSEC5 and FM1@DTSEC6.
|
||||||
|
|
||||||
|
On Linux the interfaces are renamed as::
|
||||||
|
|
||||||
|
eth2 -> fm1-gb2
|
||||||
|
eth3 -> fm1-gb3
|
||||||
|
eth4 -> fm1-gb4
|
||||||
|
eth5 -> fm1-gb5
|
||||||
|
|
||||||
|
RCW and Ethernet interfaces for B4420QDS
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Serdes protocosl tested:
|
||||||
|
* 0x18, 0x9e (serdes1, serdes2)
|
||||||
|
|
||||||
|
Under U-Boot these network interfaces are recognized as::
|
||||||
|
|
||||||
|
FM1@DTSEC3, FM1@DTSEC4 and e1000#0.
|
||||||
|
|
||||||
|
On Linux the interfaces are renamed as::
|
||||||
|
|
||||||
|
eth2 -> fm1-gb2
|
||||||
|
eth3 -> fm1-gb3
|
||||||
|
|
||||||
|
NAND boot with 2 Stage boot loader
|
||||||
|
----------------------------------
|
||||||
|
PBL initialise the internal SRAM and copy SPL(160KB) in SRAM.
|
||||||
|
SPL further initialise DDR using SPD and environment variables and copy
|
||||||
|
U-Boot(768 KB) from flash to DDR.
|
||||||
|
Finally SPL transer control to U-Boot for futher booting.
|
||||||
|
|
||||||
|
SPL has following features:
|
||||||
|
- Executes within 256K
|
||||||
|
- No relocation required
|
||||||
|
|
||||||
|
Run time view of SPL framework during boot:
|
||||||
|
|
||||||
|
+----------------------------------------------+
|
||||||
|
|Area | Address |
|
||||||
|
+----------------------------------------------+
|
||||||
|
|Secure boot | 0xFFFC0000 (32KB) |
|
||||||
|
|headers | |
|
||||||
|
+----------------------------------------------+
|
||||||
|
|GD, BD | 0xFFFC8000 (4KB) |
|
||||||
|
+----------------------------------------------+
|
||||||
|
|ENV | 0xFFFC9000 (8KB) |
|
||||||
|
+----------------------------------------------+
|
||||||
|
|HEAP | 0xFFFCB000 (30KB) |
|
||||||
|
+----------------------------------------------+
|
||||||
|
|STACK | 0xFFFD8000 (22KB) |
|
||||||
|
+----------------------------------------------+
|
||||||
|
|U-Boot SPL | 0xFFFD8000 (160KB) |
|
||||||
|
+----------------------------------------------+
|
||||||
|
|
||||||
|
NAND Flash memory Map on B4860 and B4420QDS
|
||||||
|
-------------------------------------------
|
||||||
|
|
||||||
|
============= ============= ============================= =====
|
||||||
|
Start End Definition Size
|
||||||
|
============= ============= ============================= =====
|
||||||
|
0x000000 0x0FFFFF U-Boot 1MB
|
||||||
|
0x140000 0x15FFFF U-Boot env 128KB
|
||||||
|
0x1A0000 0x1BFFFF FMAN Ucode 128KB
|
||||||
|
============= ============= ============================= =====
|
34
doc/board/google/chromebook_link.rst
Normal file
34
doc/board/google/chromebook_link.rst
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
.. SPDX-License-Identifier: GPL-2.0+
|
||||||
|
.. sectionauthor:: Simon Glass <sjg@chromium.org>
|
||||||
|
|
||||||
|
Chromebook Link
|
||||||
|
===============
|
||||||
|
|
||||||
|
First, you need the following binary blobs:
|
||||||
|
|
||||||
|
* descriptor.bin - Intel flash descriptor
|
||||||
|
* me.bin - Intel Management Engine
|
||||||
|
* mrc.bin - Memory Reference Code, which sets up SDRAM
|
||||||
|
* video ROM - sets up the display
|
||||||
|
|
||||||
|
You can get these binary blobs by::
|
||||||
|
|
||||||
|
$ git clone http://review.coreboot.org/p/blobs.git
|
||||||
|
$ cd blobs
|
||||||
|
|
||||||
|
Find the following files:
|
||||||
|
|
||||||
|
* ./mainboard/google/link/descriptor.bin
|
||||||
|
* ./mainboard/google/link/me.bin
|
||||||
|
* ./northbridge/intel/sandybridge/systemagent-r6.bin
|
||||||
|
|
||||||
|
The 3rd one should be renamed to mrc.bin.
|
||||||
|
As for the video ROM, you can get it `here`_ and rename it to vga.bin.
|
||||||
|
Make sure all these binary blobs are put in the board directory.
|
||||||
|
|
||||||
|
Now you can build U-Boot and obtain u-boot.rom::
|
||||||
|
|
||||||
|
$ make chromebook_link_defconfig
|
||||||
|
$ make all
|
||||||
|
|
||||||
|
.. _here: http://www.coreboot.org/~stepan/pci8086,0166.rom
|
101
doc/board/google/chromebook_samus.rst
Normal file
101
doc/board/google/chromebook_samus.rst
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
.. SPDX-License-Identifier: GPL-2.0+
|
||||||
|
.. sectionauthor:: Simon Glass <sjg@chromium.org>
|
||||||
|
|
||||||
|
Chromebook Samus
|
||||||
|
================
|
||||||
|
|
||||||
|
First, you need the following binary blobs:
|
||||||
|
|
||||||
|
* descriptor.bin - Intel flash descriptor
|
||||||
|
* me.bin - Intel Management Engine
|
||||||
|
* mrc.bin - Memory Reference Code, which sets up SDRAM
|
||||||
|
* refcode.elf - Additional Reference code
|
||||||
|
* vga.bin - video ROM, which sets up the display
|
||||||
|
|
||||||
|
If you have a samus you can obtain them from your flash, for example, in
|
||||||
|
developer mode on the Chromebook (use Ctrl-Alt-F2 to obtain a terminal and
|
||||||
|
log in as 'root')::
|
||||||
|
|
||||||
|
cd /tmp
|
||||||
|
flashrom -w samus.bin
|
||||||
|
scp samus.bin username@ip_address:/path/to/somewhere
|
||||||
|
|
||||||
|
If not see the coreboot tree where you can use::
|
||||||
|
|
||||||
|
bash crosfirmware.sh samus
|
||||||
|
|
||||||
|
to get the image. There is also an 'extract_blobs.sh' scripts that you can use
|
||||||
|
on the 'coreboot-Google_Samus.*' file to short-circuit some of the below.
|
||||||
|
|
||||||
|
Then 'ifdtool -x samus.bin' on your development machine will produce::
|
||||||
|
|
||||||
|
flashregion_0_flashdescriptor.bin
|
||||||
|
flashregion_1_bios.bin
|
||||||
|
flashregion_2_intel_me.bin
|
||||||
|
|
||||||
|
Rename flashregion_0_flashdescriptor.bin to descriptor.bin
|
||||||
|
Rename flashregion_2_intel_me.bin to me.bin
|
||||||
|
You can ignore flashregion_1_bios.bin - it is not used.
|
||||||
|
|
||||||
|
To get the rest, use 'cbfstool samus.bin print'::
|
||||||
|
|
||||||
|
samus.bin: 8192 kB, bootblocksize 2864, romsize 8388608, offset 0x700000
|
||||||
|
alignment: 64 bytes, architecture: x86
|
||||||
|
|
||||||
|
============================ ======== =========== ======
|
||||||
|
Name Offset Type Size
|
||||||
|
============================ ======== =========== ======
|
||||||
|
cmos_layout.bin 0x700000 cmos_layout 1164
|
||||||
|
pci8086,0406.rom 0x7004c0 optionrom 65536
|
||||||
|
spd.bin 0x710500 (unknown) 4096
|
||||||
|
cpu_microcode_blob.bin 0x711540 microcode 70720
|
||||||
|
fallback/romstage 0x722a00 stage 54210
|
||||||
|
fallback/ramstage 0x72fe00 stage 96382
|
||||||
|
config 0x7476c0 raw 6075
|
||||||
|
fallback/vboot 0x748ec0 stage 15980
|
||||||
|
fallback/refcode 0x74cd80 stage 75578
|
||||||
|
fallback/payload 0x75f500 payload 62878
|
||||||
|
u-boot.dtb 0x76eb00 (unknown) 5318
|
||||||
|
(empty) 0x770000 null 196504
|
||||||
|
mrc.bin 0x79ffc0 (unknown) 222876
|
||||||
|
(empty) 0x7d66c0 null 167320
|
||||||
|
============================ ======== =========== ======
|
||||||
|
|
||||||
|
You can extract what you need::
|
||||||
|
|
||||||
|
cbfstool samus.bin extract -n pci8086,0406.rom -f vga.bin
|
||||||
|
cbfstool samus.bin extract -n fallback/refcode -f refcode.rmod
|
||||||
|
cbfstool samus.bin extract -n mrc.bin -f mrc.bin
|
||||||
|
cbfstool samus.bin extract -n fallback/refcode -f refcode.bin -U
|
||||||
|
|
||||||
|
Note that the -U flag is only supported by the latest cbfstool. It unpacks
|
||||||
|
and decompresses the stage to produce a coreboot rmodule. This is a simple
|
||||||
|
representation of an ELF file. You need the patch "Support decoding a stage
|
||||||
|
with compression".
|
||||||
|
|
||||||
|
Put all 5 files into board/google/chromebook_samus.
|
||||||
|
|
||||||
|
Now you can build U-Boot and obtain u-boot.rom::
|
||||||
|
|
||||||
|
$ make chromebook_samus_defconfig
|
||||||
|
$ make all
|
||||||
|
|
||||||
|
If you are using em100, then this command will flash write -Boot::
|
||||||
|
|
||||||
|
em100 -s -d filename.rom -c W25Q64CV -r
|
||||||
|
|
||||||
|
Flash map for samus / broadwell:
|
||||||
|
|
||||||
|
:fffff800: SYS_X86_START16
|
||||||
|
:ffff0000: RESET_SEG_START
|
||||||
|
:fffd8000: TPL_TEXT_BASE
|
||||||
|
:fffa0000: X86_MRC_ADDR
|
||||||
|
:fff90000: VGA_BIOS_ADDR
|
||||||
|
:ffed0000: SYS_TEXT_BASE
|
||||||
|
:ffea0000: X86_REFCODE_ADDR
|
||||||
|
:ffe70000: SPL_TEXT_BASE
|
||||||
|
:ffbf8000: CONFIG_ENV_OFFSET (environemnt offset)
|
||||||
|
:ffbe0000: rw-mrc-cache (Memory-reference-code cache)
|
||||||
|
:ffa00000: <spare>
|
||||||
|
:ff801000: intel-me (address set by descriptor.bin)
|
||||||
|
:ff800000: intel-descriptor
|
10
doc/board/google/index.rst
Normal file
10
doc/board/google/index.rst
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
.. SPDX-License-Identifier: GPL-2.0+
|
||||||
|
|
||||||
|
Google
|
||||||
|
======
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 2
|
||||||
|
|
||||||
|
chromebook_link
|
||||||
|
chromebook_samus
|
18
doc/board/index.rst
Normal file
18
doc/board/index.rst
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
.. SPDX-License-Identifier: GPL-2.0+
|
||||||
|
|
||||||
|
Board-specific doc
|
||||||
|
==================
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 2
|
||||||
|
|
||||||
|
AndesTech/index
|
||||||
|
atmel/index
|
||||||
|
coreboot/index
|
||||||
|
emulation/index
|
||||||
|
freescale/index
|
||||||
|
google/index
|
||||||
|
intel/index
|
||||||
|
renesas/index
|
||||||
|
sifive/index
|
||||||
|
xilinx/index
|
29
doc/board/intel/bayleybay.rst
Normal file
29
doc/board/intel/bayleybay.rst
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
.. SPDX-License-Identifier: GPL-2.0+
|
||||||
|
.. sectionauthor:: Bin Meng <bmeng.cn@gmail.com>
|
||||||
|
|
||||||
|
Bayley Bay CRB
|
||||||
|
==============
|
||||||
|
|
||||||
|
This uses as FSP as with Crown Bay, except it is for the Atom E3800 series.
|
||||||
|
Download this and get the .fd file (BAYTRAIL_FSP_GOLD_003_16-SEP-2014.fd at
|
||||||
|
the time of writing). Put it in the corresponding board directory and rename
|
||||||
|
it to fsp.bin.
|
||||||
|
|
||||||
|
Obtain the VGA RAM (Vga.dat at the time of writing) and put it into the same
|
||||||
|
board directory as vga.bin.
|
||||||
|
|
||||||
|
You still need two more binary blobs. For Bayley Bay, they can be extracted
|
||||||
|
from the sample SPI image provided in the FSP (SPI.bin at the time of writing)::
|
||||||
|
|
||||||
|
$ ./tools/ifdtool -x BayleyBay/SPI.bin
|
||||||
|
$ cp flashregion_0_flashdescriptor.bin board/intel/bayleybay/descriptor.bin
|
||||||
|
$ cp flashregion_2_intel_me.bin board/intel/bayleybay/me.bin
|
||||||
|
|
||||||
|
Now you can build U-Boot and obtain u-boot.rom::
|
||||||
|
|
||||||
|
$ make bayleybay_defconfig
|
||||||
|
$ make all
|
||||||
|
|
||||||
|
Note that the debug version of the FSP is bigger in size. If this version
|
||||||
|
is used, CONFIG_FSP_ADDR needs to be configured to 0xfffb0000 instead of
|
||||||
|
the default value 0xfffc0000.
|
30
doc/board/intel/cherryhill.rst
Normal file
30
doc/board/intel/cherryhill.rst
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
.. SPDX-License-Identifier: GPL-2.0+
|
||||||
|
.. sectionauthor:: Bin Meng <bmeng.cn@gmail.com>
|
||||||
|
|
||||||
|
Cherry Hill CRB
|
||||||
|
===============
|
||||||
|
|
||||||
|
This uses Intel FSP for Braswell platform. Download it from Intel FSP website,
|
||||||
|
put the .fd file to the board directory and rename it to fsp.bin.
|
||||||
|
|
||||||
|
Extract descriptor.bin and me.bin from the original BIOS on the board using
|
||||||
|
ifdtool and put them to the board directory as well.
|
||||||
|
|
||||||
|
Note the FSP package for Braswell does not ship a traditional legacy VGA BIOS
|
||||||
|
image for the integrated graphics device. Instead a new binary called Video
|
||||||
|
BIOS Table (VBT) is shipped. Put it to the board directory and rename it to
|
||||||
|
vbt.bin if you want graphics support in U-Boot.
|
||||||
|
|
||||||
|
Now you can build U-Boot and obtain u-boot.rom::
|
||||||
|
|
||||||
|
$ make cherryhill_defconfig
|
||||||
|
$ make all
|
||||||
|
|
||||||
|
An important note for programming u-boot.rom to the on-board SPI flash is that
|
||||||
|
you need make sure the SPI flash's 'quad enable' bit in its status register
|
||||||
|
matches the settings in the descriptor.bin, otherwise the board won't boot.
|
||||||
|
|
||||||
|
For the on-board SPI flash MX25U6435F, this can be done by writing 0x40 to the
|
||||||
|
status register by DediProg in: Config > Modify Status Register > Write Status
|
||||||
|
Register(s) > Register1 Value(Hex). This is is a one-time change. Once set, it
|
||||||
|
persists in SPI flash part regardless of the u-boot.rom image burned.
|
24
doc/board/intel/cougarcanyon2.rst
Normal file
24
doc/board/intel/cougarcanyon2.rst
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
.. SPDX-License-Identifier: GPL-2.0+
|
||||||
|
.. sectionauthor:: Bin Meng <bmeng.cn@gmail.com>
|
||||||
|
|
||||||
|
Cougar Canyon 2 CRB
|
||||||
|
===================
|
||||||
|
|
||||||
|
This uses Intel FSP for 3rd generation Intel Core and Intel Celeron processors
|
||||||
|
with mobile Intel HM76 and QM77 chipsets platform. Download it from Intel FSP
|
||||||
|
website and put the .fd file (CHIEFRIVER_FSP_GOLD_001_09-OCTOBER-2013.fd at the
|
||||||
|
time of writing) in the board directory and rename it to fsp.bin.
|
||||||
|
|
||||||
|
Now build U-Boot and obtain u-boot.rom::
|
||||||
|
|
||||||
|
$ make cougarcanyon2_defconfig
|
||||||
|
$ make all
|
||||||
|
|
||||||
|
The board has two 8MB SPI flashes mounted, which are called SPI-0 and SPI-1 in
|
||||||
|
the board manual. The SPI-0 flash should have flash descriptor plus ME firmware
|
||||||
|
and SPI-1 flash is used to store U-Boot. For convenience, the complete 8MB SPI-0
|
||||||
|
flash image is included in the FSP package (named Rom00_8M_MB_PPT.bin). Program
|
||||||
|
this image to the SPI-0 flash according to the board manual just once and we are
|
||||||
|
all set. For programming U-Boot we just need to program SPI-1 flash. Since the
|
||||||
|
default u-boot.rom image for this board is set to 2MB, it should be programmed
|
||||||
|
to the last 2MB of the 8MB chip, address range [600000, 7FFFFF].
|
43
doc/board/intel/crownbay.rst
Normal file
43
doc/board/intel/crownbay.rst
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
.. SPDX-License-Identifier: GPL-2.0+
|
||||||
|
.. sectionauthor:: Bin Meng <bmeng.cn@gmail.com>
|
||||||
|
|
||||||
|
Crown Bay CRB
|
||||||
|
=============
|
||||||
|
|
||||||
|
U-Boot support of Intel `Crown Bay`_ board relies on a binary blob called
|
||||||
|
Firmware Support Package (`FSP`_) to perform all the necessary initialization
|
||||||
|
steps as documented in the BIOS Writer Guide, including initialization of the
|
||||||
|
CPU, memory controller, chipset and certain bus interfaces.
|
||||||
|
|
||||||
|
Download the Intel FSP for Atom E6xx series and Platform Controller Hub EG20T,
|
||||||
|
install it on your host and locate the FSP binary blob. Note this platform
|
||||||
|
also requires a Chipset Micro Code (CMC) state machine binary to be present in
|
||||||
|
the SPI flash where u-boot.rom resides, and this CMC binary blob can be found
|
||||||
|
in this FSP package too.
|
||||||
|
|
||||||
|
* ./FSP/QUEENSBAY_FSP_GOLD_001_20-DECEMBER-2013.fd
|
||||||
|
* ./Microcode/C0_22211.BIN
|
||||||
|
|
||||||
|
Rename the first one to fsp.bin and second one to cmc.bin and put them in the
|
||||||
|
board directory.
|
||||||
|
|
||||||
|
Note the FSP release version 001 has a bug which could cause random endless
|
||||||
|
loop during the FspInit call. This bug was published by Intel although Intel
|
||||||
|
did not describe any details. We need manually apply the patch to the FSP
|
||||||
|
binary using any hex editor (eg: bvi). Go to the offset 0x1fcd8 of the FSP
|
||||||
|
binary, change the following five bytes values from orginally E8 42 FF FF FF
|
||||||
|
to B8 00 80 0B 00.
|
||||||
|
|
||||||
|
As for the video ROM, you need manually extract it from the Intel provided
|
||||||
|
BIOS for Crown Bay `here`_, using the AMI `MMTool`_. Check PCI option
|
||||||
|
ROM ID 8086:4108, extract and save it as vga.bin in the board directory.
|
||||||
|
|
||||||
|
Now you can build U-Boot and obtain u-boot.rom::
|
||||||
|
|
||||||
|
$ make crownbay_defconfig
|
||||||
|
$ make all
|
||||||
|
|
||||||
|
.. _`Crown Bay`: http://www.intel.com/content/www/us/en/embedded/design-tools/evaluation-platforms/atom-e660-eg20t-development-kit.html
|
||||||
|
.. _`FSP`: http://www.intel.com/fsp
|
||||||
|
.. _`here`: http://www.intel.com/content/www/us/en/secure/intelligent-systems/privileged/e6xx-35-b1-cmc22211.html
|
||||||
|
.. _`MMTool`: http://www.ami.com/products/bios-uefi-tools-and-utilities/bios-uefi-utilities/
|
41
doc/board/intel/edison.rst
Normal file
41
doc/board/intel/edison.rst
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
.. SPDX-License-Identifier: GPL-2.0+
|
||||||
|
.. sectionauthor:: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
|
||||||
|
|
||||||
|
Edison
|
||||||
|
======
|
||||||
|
|
||||||
|
Build Instructions for U-Boot as main bootloader
|
||||||
|
------------------------------------------------
|
||||||
|
|
||||||
|
Simple you can build U-Boot and obtain u-boot.bin::
|
||||||
|
|
||||||
|
$ make edison_defconfig
|
||||||
|
$ make all
|
||||||
|
|
||||||
|
Updating U-Boot on Edison
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
By default Intel Edison boards are shipped with preinstalled heavily
|
||||||
|
patched U-Boot v2014.04. Though it supports DFU which we may be able to
|
||||||
|
use.
|
||||||
|
|
||||||
|
1. Prepare u-boot.bin as described in chapter above. You still need one
|
||||||
|
more step (if and only if you have original U-Boot), i.e. run the
|
||||||
|
following command::
|
||||||
|
|
||||||
|
$ truncate -s %4096 u-boot.bin
|
||||||
|
|
||||||
|
2. Run your board and interrupt booting to U-Boot console. In the console
|
||||||
|
call::
|
||||||
|
|
||||||
|
=> run do_force_flash_os
|
||||||
|
|
||||||
|
3. Wait for few seconds, it will prepare environment variable and runs
|
||||||
|
DFU. Run DFU command from the host system::
|
||||||
|
|
||||||
|
$ dfu-util -v -d 8087:0a99 --alt u-boot0 -D u-boot.bin
|
||||||
|
|
||||||
|
4. Return to U-Boot console and following hint. i.e. push Ctrl+C, and
|
||||||
|
reset the board::
|
||||||
|
|
||||||
|
=> reset
|
22
doc/board/intel/galileo.rst
Normal file
22
doc/board/intel/galileo.rst
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
.. SPDX-License-Identifier: GPL-2.0+
|
||||||
|
.. sectionauthor:: Bin Meng <bmeng.cn@gmail.com>
|
||||||
|
|
||||||
|
Galileo
|
||||||
|
=======
|
||||||
|
|
||||||
|
Only one binary blob is needed for Remote Management Unit (RMU) within Intel
|
||||||
|
Quark SoC. Not like FSP, U-Boot does not call into the binary. The binary is
|
||||||
|
needed by the Quark SoC itself.
|
||||||
|
|
||||||
|
You can get the binary blob from Quark Board Support Package from Intel website:
|
||||||
|
|
||||||
|
* ./QuarkSocPkg/QuarkNorthCluster/Binary/QuarkMicrocode/RMU.bin
|
||||||
|
|
||||||
|
Rename the file and put it to the board directory by::
|
||||||
|
|
||||||
|
$ cp RMU.bin board/intel/galileo/rmu.bin
|
||||||
|
|
||||||
|
Now you can build U-Boot and obtain u-boot.rom::
|
||||||
|
|
||||||
|
$ make galileo_defconfig
|
||||||
|
$ make all
|
15
doc/board/intel/index.rst
Normal file
15
doc/board/intel/index.rst
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
.. SPDX-License-Identifier: GPL-2.0+
|
||||||
|
|
||||||
|
Intel
|
||||||
|
=====
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 2
|
||||||
|
|
||||||
|
bayleybay
|
||||||
|
cherryhill
|
||||||
|
cougarcanyon2
|
||||||
|
crownbay
|
||||||
|
edison
|
||||||
|
galileo
|
||||||
|
minnowmax
|
70
doc/board/intel/minnowmax.rst
Normal file
70
doc/board/intel/minnowmax.rst
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
.. SPDX-License-Identifier: GPL-2.0+
|
||||||
|
.. sectionauthor:: Simon Glass <sjg@chromium.org>
|
||||||
|
|
||||||
|
Minnowboard MAX
|
||||||
|
===============
|
||||||
|
|
||||||
|
This uses as FSP as with Crown Bay, except it is for the Atom E3800 series.
|
||||||
|
Download this and get the .fd file (BAYTRAIL_FSP_GOLD_003_16-SEP-2014.fd at
|
||||||
|
the time of writing). Put it in the corresponding board directory and rename
|
||||||
|
it to fsp.bin.
|
||||||
|
|
||||||
|
Obtain the VGA RAM (Vga.dat at the time of writing) and put it into the same
|
||||||
|
board directory as vga.bin.
|
||||||
|
|
||||||
|
You still need two more binary blobs. For Minnowboard MAX, we can reuse the
|
||||||
|
same ME firmware above, but for flash descriptor, we need get that somewhere
|
||||||
|
else, as the one above does not seem to work, probably because it is not
|
||||||
|
designed for the Minnowboard MAX. Now download the original firmware image
|
||||||
|
for this board from:
|
||||||
|
|
||||||
|
* http://firmware.intel.com/sites/default/files/2014-WW42.4-MinnowBoardMax.73-64-bit.bin_Release.zip
|
||||||
|
|
||||||
|
Unzip it::
|
||||||
|
|
||||||
|
$ unzip 2014-WW42.4-MinnowBoardMax.73-64-bit.bin_Release.zip
|
||||||
|
|
||||||
|
Use ifdtool in the U-Boot tools directory to extract the images from that
|
||||||
|
file, for example::
|
||||||
|
|
||||||
|
$ ./tools/ifdtool -x MNW2MAX1.X64.0073.R02.1409160934.bin
|
||||||
|
|
||||||
|
This will provide the descriptor file - copy this into the correct place::
|
||||||
|
|
||||||
|
$ cp flashregion_0_flashdescriptor.bin board/intel/minnowmax/descriptor.bin
|
||||||
|
|
||||||
|
Now you can build U-Boot and obtain u-boot.rom::
|
||||||
|
|
||||||
|
$ make minnowmax_defconfig
|
||||||
|
$ make all
|
||||||
|
|
||||||
|
Checksums are as follows (but note that newer versions will invalidate this)::
|
||||||
|
|
||||||
|
$ md5sum -b board/intel/minnowmax/*.bin
|
||||||
|
ffda9a3b94df5b74323afb328d51e6b4 board/intel/minnowmax/descriptor.bin
|
||||||
|
69f65b9a580246291d20d08cbef9d7c5 board/intel/minnowmax/fsp.bin
|
||||||
|
894a97d371544ec21de9c3e8e1716c4b board/intel/minnowmax/me.bin
|
||||||
|
a2588537da387da592a27219d56e9962 board/intel/minnowmax/vga.bin
|
||||||
|
|
||||||
|
The ROM image is broken up into these parts:
|
||||||
|
|
||||||
|
====== ================== ============================
|
||||||
|
Offset Description Controlling config
|
||||||
|
====== ================== ============================
|
||||||
|
000000 descriptor.bin Hard-coded to 0 in ifdtool
|
||||||
|
001000 me.bin Set by the descriptor
|
||||||
|
500000 <spare>
|
||||||
|
6ef000 Environment CONFIG_ENV_OFFSET
|
||||||
|
6f0000 MRC cache CONFIG_ENABLE_MRC_CACHE
|
||||||
|
700000 u-boot-dtb.bin CONFIG_SYS_TEXT_BASE
|
||||||
|
7b0000 vga.bin CONFIG_VGA_BIOS_ADDR
|
||||||
|
7c0000 fsp.bin CONFIG_FSP_ADDR
|
||||||
|
7f8000 <spare> (depends on size of fsp.bin)
|
||||||
|
7ff800 U-Boot 16-bit boot CONFIG_SYS_X86_START16
|
||||||
|
====== ================== ============================
|
||||||
|
|
||||||
|
Overall ROM image size is controlled by CONFIG_ROM_SIZE.
|
||||||
|
|
||||||
|
Note that the debug version of the FSP is bigger in size. If this version
|
||||||
|
is used, CONFIG_FSP_ADDR needs to be configured to 0xfffb0000 instead of
|
||||||
|
the default value 0xfffc0000.
|
79
doc/board/renesas/sh7752evb.rst
Normal file
79
doc/board/renesas/sh7752evb.rst
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
.. SPDX-License-Identifier: GPL-2.0+
|
||||||
|
|
||||||
|
R0P7752C00000RZ board
|
||||||
|
=====================
|
||||||
|
|
||||||
|
This board specification
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
The R0P7752C00000RZ(board config name:sh7752evb) has the following device:
|
||||||
|
|
||||||
|
- SH7752 (SH-4A)
|
||||||
|
- DDR3-SDRAM 512MB
|
||||||
|
- SPI ROM 8MB
|
||||||
|
- Gigabit Ethernet controllers
|
||||||
|
- eMMC 4GB
|
||||||
|
|
||||||
|
|
||||||
|
Configuration for This board
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
You can select the configuration as follows:
|
||||||
|
|
||||||
|
- make sh7752evb_config
|
||||||
|
|
||||||
|
|
||||||
|
This board specific command
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
This board has the following its specific command:
|
||||||
|
|
||||||
|
write_mac:
|
||||||
|
You can write MAC address to SPI ROM.
|
||||||
|
|
||||||
|
Usage 1: Write MAC address
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
|
write_mac [GETHERC ch0] [GETHERC ch1]
|
||||||
|
|
||||||
|
For example:
|
||||||
|
=> write_mac 74:90:50:00:33:9e 74:90:50:00:33:9f
|
||||||
|
|
||||||
|
* We have to input the command as a single line (without carriage return)
|
||||||
|
* We have to reset after input the command.
|
||||||
|
|
||||||
|
Usage 2: Show current data
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
|
write_mac
|
||||||
|
|
||||||
|
For example:
|
||||||
|
=> write_mac
|
||||||
|
GETHERC ch0 = 74:90:50:00:33:9e
|
||||||
|
GETHERC ch1 = 74:90:50:00:33:9f
|
||||||
|
|
||||||
|
|
||||||
|
Update SPI ROM
|
||||||
|
--------------
|
||||||
|
|
||||||
|
1. Copy u-boot image to RAM area.
|
||||||
|
2. Probe SPI device.
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
|
=> sf probe 0
|
||||||
|
SF: Detected MX25L6405D with page size 64KiB, total 8 MiB
|
||||||
|
|
||||||
|
3. Erase SPI ROM.
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
|
=> sf erase 0 80000
|
||||||
|
|
||||||
|
4. Write u-boot image to SPI ROM.
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
|
=> sf write 0x48000000 0 80000
|
79
doc/board/renesas/sh7753evb.rst
Normal file
79
doc/board/renesas/sh7753evb.rst
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
.. SPDX-License-Identifier: GPL-2.0+
|
||||||
|
|
||||||
|
SH7753 EVB board
|
||||||
|
================
|
||||||
|
|
||||||
|
This board specification
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
The SH7753 EVB (board config name:sh7753evb) has the following device:
|
||||||
|
|
||||||
|
- SH7753 (SH-4A)
|
||||||
|
- DDR3-SDRAM 512MB
|
||||||
|
- SPI ROM 8MB
|
||||||
|
- Gigabit Ethernet controllers
|
||||||
|
- eMMC 4GB
|
||||||
|
|
||||||
|
|
||||||
|
Configuration for This board
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
You can select the configuration as follows:
|
||||||
|
|
||||||
|
- make sh7753evb_config
|
||||||
|
|
||||||
|
|
||||||
|
This board specific command
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
This board has the following its specific command:
|
||||||
|
|
||||||
|
write_mac:
|
||||||
|
You can write MAC address to SPI ROM.
|
||||||
|
|
||||||
|
Usage 1: Write MAC address
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
|
write_mac [GETHERC ch0] [GETHERC ch1]
|
||||||
|
|
||||||
|
For example:
|
||||||
|
=> write_mac 74:90:50:00:33:9e 74:90:50:00:33:9f
|
||||||
|
|
||||||
|
* We have to input the command as a single line (without carriage return)
|
||||||
|
* We have to reset after input the command.
|
||||||
|
|
||||||
|
Usage 2: Show current data
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
|
write_mac
|
||||||
|
|
||||||
|
For example:
|
||||||
|
=> write_mac
|
||||||
|
GETHERC ch0 = 74:90:50:00:33:9e
|
||||||
|
GETHERC ch1 = 74:90:50:00:33:9f
|
||||||
|
|
||||||
|
|
||||||
|
Update SPI ROM
|
||||||
|
--------------
|
||||||
|
|
||||||
|
1. Copy u-boot image to RAM area.
|
||||||
|
2. Probe SPI device.
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
|
=> sf probe 0
|
||||||
|
SF: Detected MX25L6405D with page size 64KiB, total 8 MiB
|
||||||
|
|
||||||
|
3. Erase SPI ROM.
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
|
=> sf erase 0 80000
|
||||||
|
|
||||||
|
4. Write u-boot image to SPI ROM.
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
|
=> sf write 0x48000000 0 80000
|
320
doc/board/sifive/fu540.rst
Normal file
320
doc/board/sifive/fu540.rst
Normal file
|
@ -0,0 +1,320 @@
|
||||||
|
.. SPDX-License-Identifier: GPL-2.0+
|
||||||
|
|
||||||
|
HiFive Unleashed
|
||||||
|
================
|
||||||
|
|
||||||
|
FU540-C000 RISC-V SoC
|
||||||
|
---------------------
|
||||||
|
The FU540-C000 is the world’s first 4+1 64-bit RISC-V SoC from SiFive.
|
||||||
|
|
||||||
|
The HiFive Unleashed development platform is based on FU540-C000 and capable
|
||||||
|
of running Linux.
|
||||||
|
|
||||||
|
Mainline support
|
||||||
|
----------------
|
||||||
|
The support for following drivers are already enabled:
|
||||||
|
|
||||||
|
1. SiFive UART Driver.
|
||||||
|
2. SiFive PRCI Driver for clock.
|
||||||
|
3. Cadence MACB ethernet driver for networking support.
|
||||||
|
|
||||||
|
TODO:
|
||||||
|
|
||||||
|
1. U-Boot expects the serial console device entry to be present under /chosen
|
||||||
|
DT node. Without a serial console U-Boot will panic. Example:
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
|
chosen {
|
||||||
|
stdout-path = "/soc/serial@10010000:115200";
|
||||||
|
};
|
||||||
|
|
||||||
|
Building
|
||||||
|
--------
|
||||||
|
|
||||||
|
1. Add the RISC-V toolchain to your PATH.
|
||||||
|
2. Setup ARCH & cross compilation enviornment variable:
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
|
export ARCH=riscv
|
||||||
|
export CROSS_COMPILE=<riscv64 toolchain prefix>
|
||||||
|
|
||||||
|
3. make sifive_fu540_defconfig
|
||||||
|
4. make
|
||||||
|
|
||||||
|
Flashing
|
||||||
|
--------
|
||||||
|
|
||||||
|
The current U-Boot port is supported in S-mode only and loaded from DRAM.
|
||||||
|
|
||||||
|
A prior stage (M-mode) firmware/bootloader (e.g OpenSBI or BBL) is required to
|
||||||
|
load the u-boot.bin into memory and provide runtime services. The u-boot.bin
|
||||||
|
can be given as a payload to the prior stage (M-mode) firmware/bootloader.
|
||||||
|
|
||||||
|
The description of steps required to build the firmware is beyond the scope of
|
||||||
|
this document. Please refer OpenSBI or BBL documenation.
|
||||||
|
(Note: OpenSBI git repo is at https://github.com/riscv/opensbi.git)
|
||||||
|
(Note: BBL git repo is at https://github.com/riscv/riscv-pk.git)
|
||||||
|
|
||||||
|
Once the prior stage firmware/bootloader binary is generated, it should be
|
||||||
|
copied to the first partition of the sdcard.
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
|
sudo dd if=<prior_stage_firmware_binary> of=/dev/disk2s1 bs=1024
|
||||||
|
|
||||||
|
Booting
|
||||||
|
-------
|
||||||
|
Once you plugin the sdcard and power up, you should see the U-Boot prompt.
|
||||||
|
|
||||||
|
Sample boot log from HiFive Unleashed board
|
||||||
|
-------------------------------------------
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
|
U-Boot 2019.01-00019-gc7953536-dirty (Jan 22 2019 - 11:05:40 -0800)
|
||||||
|
|
||||||
|
CPU: rv64imafdc
|
||||||
|
Model: sifive,hifive-unleashed-a00
|
||||||
|
DRAM: 8 GiB
|
||||||
|
In: serial@10010000
|
||||||
|
Out: serial@10010000
|
||||||
|
Err: serial@10010000
|
||||||
|
Net:
|
||||||
|
Warning: ethernet@10090000 (eth0) using random MAC address - b6:75:4d:48:50:94
|
||||||
|
eth0: ethernet@10090000
|
||||||
|
Hit any key to stop autoboot: 0
|
||||||
|
=> version
|
||||||
|
U-Boot 2019.01-00019-gc7953536-dirty (Jan 22 2019 - 11:05:40 -0800)
|
||||||
|
|
||||||
|
riscv64-linux-gcc.br_real (Buildroot 2018.11-rc2-00003-ga0787e9) 8.2.0
|
||||||
|
GNU ld (GNU Binutils) 2.31.1
|
||||||
|
|
||||||
|
Now you can configure your networking, tftp server and use tftp boot method to
|
||||||
|
load uImage.
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
|
=> setenv ethaddr 70:B3:D5:92:F0:C2
|
||||||
|
=> setenv ipaddr 10.196.157.189
|
||||||
|
=> setenv serverip 10.11.143.218
|
||||||
|
=> setenv gatewayip 10.196.156.1
|
||||||
|
=> setenv netmask 255.255.252.0
|
||||||
|
=> bdinfo
|
||||||
|
boot_params = 0x0000000000000000
|
||||||
|
DRAM bank = 0x0000000000000000
|
||||||
|
-> start = 0x0000000080000000
|
||||||
|
-> size = 0x0000000200000000
|
||||||
|
relocaddr = 0x00000000fff90000
|
||||||
|
reloc off = 0x000000007fd90000
|
||||||
|
ethaddr = 70:B3:D5:92:F0:C2
|
||||||
|
IP addr = 10.196.157.189
|
||||||
|
baudrate = 115200 bps
|
||||||
|
=> tftpboot uImage
|
||||||
|
ethernet@10090000: PHY present at 0
|
||||||
|
ethernet@10090000: Starting autonegotiation...
|
||||||
|
ethernet@10090000: Autonegotiation complete
|
||||||
|
ethernet@10090000: link up, 1000Mbps full-duplex (lpa: 0x3800)
|
||||||
|
Using ethernet@10090000 device
|
||||||
|
TFTP from server 10.11.143.218; our IP address is 10.196.157.189; sending through gateway 10.196.156.1
|
||||||
|
Filename 'uImage'.
|
||||||
|
Load address: 0x80200000
|
||||||
|
Loading: #################################################################
|
||||||
|
#################################################################
|
||||||
|
#################################################################
|
||||||
|
#################################################################
|
||||||
|
#################################################################
|
||||||
|
#################################################################
|
||||||
|
#################################################################
|
||||||
|
#################################################################
|
||||||
|
#################################################################
|
||||||
|
#################################################################
|
||||||
|
#################################################################
|
||||||
|
#################################################################
|
||||||
|
#################################################################
|
||||||
|
#################################################################
|
||||||
|
#################################################################
|
||||||
|
#################################################################
|
||||||
|
#################################################################
|
||||||
|
#################################################################
|
||||||
|
#################################################################
|
||||||
|
#################################################################
|
||||||
|
#################################################################
|
||||||
|
#################################################################
|
||||||
|
#################################################################
|
||||||
|
#################################################################
|
||||||
|
#################################################################
|
||||||
|
#################################################################
|
||||||
|
#################################################################
|
||||||
|
#################################################################
|
||||||
|
#################################################################
|
||||||
|
#################################################################
|
||||||
|
#################################################################
|
||||||
|
#################################################################
|
||||||
|
#################################################################
|
||||||
|
#################################################################
|
||||||
|
#################################################################
|
||||||
|
#################################################################
|
||||||
|
#################################################################
|
||||||
|
#################################################################
|
||||||
|
#################################################################
|
||||||
|
#################################################################
|
||||||
|
#################################################################
|
||||||
|
#################################################################
|
||||||
|
#################################################################
|
||||||
|
#################################################################
|
||||||
|
##########################################################
|
||||||
|
2.5 MiB/s
|
||||||
|
done
|
||||||
|
Bytes transferred = 14939132 (e3f3fc hex)
|
||||||
|
=> bootm 0x80200000 - 0x82200000
|
||||||
|
## Booting kernel from Legacy Image at 80200000 ...
|
||||||
|
Image Name: Linux
|
||||||
|
Image Type: RISC-V Linux Kernel Image (uncompressed)
|
||||||
|
Data Size: 14939068 Bytes = 14.2 MiB
|
||||||
|
Load Address: 80200000
|
||||||
|
Entry Point: 80200000
|
||||||
|
Verifying Checksum ... OK
|
||||||
|
## Flattened Device Tree blob at 82200000
|
||||||
|
Booting using the fdt blob at 0x82200000
|
||||||
|
Loading Kernel Image ... OK
|
||||||
|
Using Device Tree in place at 0000000082200000, end 0000000082205c69
|
||||||
|
|
||||||
|
Starting kernel ...
|
||||||
|
|
||||||
|
[ 0.000000] OF: fdt: Ignoring memory range 0x80000000 - 0x80200000
|
||||||
|
[ 0.000000] Linux version 5.0.0-rc1-00020-g4b51f736 (atish@jedi-01) (gcc version 7.2.0 (GCC)) #262 SMP Mon Jan 21 17:39:27 PST 2019
|
||||||
|
[ 0.000000] initrd not found or empty - disabling initrd
|
||||||
|
[ 0.000000] Zone ranges:
|
||||||
|
[ 0.000000] DMA32 [mem 0x0000000080200000-0x00000000ffffffff]
|
||||||
|
[ 0.000000] Normal [mem 0x0000000100000000-0x000027ffffffffff]
|
||||||
|
[ 0.000000] Movable zone start for each node
|
||||||
|
[ 0.000000] Early memory node ranges
|
||||||
|
[ 0.000000] node 0: [mem 0x0000000080200000-0x000000027fffffff]
|
||||||
|
[ 0.000000] Initmem setup node 0 [mem 0x0000000080200000-0x000000027fffffff]
|
||||||
|
[ 0.000000] software IO TLB: mapped [mem 0xfbfff000-0xfffff000] (64MB)
|
||||||
|
[ 0.000000] CPU with hartid=0 has a non-okay status of "masked"
|
||||||
|
[ 0.000000] CPU with hartid=0 has a non-okay status of "masked"
|
||||||
|
[ 0.000000] elf_hwcap is 0x112d
|
||||||
|
[ 0.000000] percpu: Embedded 15 pages/cpu @(____ptrval____) s29720 r0 d31720 u61440
|
||||||
|
[ 0.000000] Built 1 zonelists, mobility grouping on. Total pages: 2067975
|
||||||
|
[ 0.000000] Kernel command line: earlyprintk
|
||||||
|
[ 0.000000] Dentry cache hash table entries: 1048576 (order: 11, 8388608 bytes)
|
||||||
|
[ 0.000000] Inode-cache hash table entries: 524288 (order: 10, 4194304 bytes)
|
||||||
|
[ 0.000000] Sorting __ex_table...
|
||||||
|
[ 0.000000] Memory: 8178760K/8386560K available (3309K kernel code, 248K rwdata, 872K rodata, 9381K init, 763K bss, 207800K reserved, 0K cma-reserved)
|
||||||
|
[ 0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=4, Nodes=1
|
||||||
|
[ 0.000000] rcu: Hierarchical RCU implementation.
|
||||||
|
[ 0.000000] rcu: RCU event tracing is enabled.
|
||||||
|
[ 0.000000] rcu: RCU restricting CPUs from NR_CPUS=8 to nr_cpu_ids=4.
|
||||||
|
[ 0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 10 jiffies.
|
||||||
|
[ 0.000000] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=4
|
||||||
|
[ 0.000000] NR_IRQS: 0, nr_irqs: 0, preallocated irqs: 0
|
||||||
|
[ 0.000000] plic: mapped 53 interrupts to 4 (out of 9) handlers.
|
||||||
|
[ 0.000000] riscv_timer_init_dt: Registering clocksource cpuid [0] hartid [1]
|
||||||
|
[ 0.000000] clocksource: riscv_clocksource: mask: 0xffffffffffffffff max_cycles: 0x1d854df40, max_idle_ns: 3526361616960 ns
|
||||||
|
[ 0.000008] sched_clock: 64 bits at 1000kHz, resolution 1000ns, wraps every 2199023255500ns
|
||||||
|
[ 0.000221] Console: colour dummy device 80x25
|
||||||
|
[ 0.000902] printk: console [tty0] enabled
|
||||||
|
[ 0.000963] Calibrating delay loop (skipped), value calculated using timer frequency.. 2.00 BogoMIPS (lpj=10000)
|
||||||
|
[ 0.001034] pid_max: default: 32768 minimum: 301
|
||||||
|
[ 0.001541] Mount-cache hash table entries: 16384 (order: 5, 131072 bytes)
|
||||||
|
[ 0.001912] Mountpoint-cache hash table entries: 16384 (order: 5, 131072 bytes)
|
||||||
|
[ 0.003542] rcu: Hierarchical SRCU implementation.
|
||||||
|
[ 0.004347] smp: Bringing up secondary CPUs ...
|
||||||
|
[ 1.040259] CPU1: failed to come online
|
||||||
|
[ 2.080483] CPU2: failed to come online
|
||||||
|
[ 3.120699] CPU3: failed to come online
|
||||||
|
[ 3.120765] smp: Brought up 1 node, 1 CPU
|
||||||
|
[ 3.121923] devtmpfs: initialized
|
||||||
|
[ 3.124649] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
|
||||||
|
[ 3.124727] futex hash table entries: 1024 (order: 4, 65536 bytes)
|
||||||
|
[ 3.125346] random: get_random_u32 called from bucket_table_alloc+0x72/0x172 with crng_init=0
|
||||||
|
[ 3.125578] NET: Registered protocol family 16
|
||||||
|
[ 3.126400] sifive-u54-prci 10000000.prci: Registered U54 core clocks
|
||||||
|
[ 3.126649] sifive-gemgxl-mgmt 100a0000.cadence-gemgxl-mgmt: Registered clock switch 'cadence-gemgxl-mgmt'
|
||||||
|
[ 3.135572] vgaarb: loaded
|
||||||
|
[ 3.135858] SCSI subsystem initialized
|
||||||
|
[ 3.136193] usbcore: registered new interface driver usbfs
|
||||||
|
[ 3.136266] usbcore: registered new interface driver hub
|
||||||
|
[ 3.136348] usbcore: registered new device driver usb
|
||||||
|
[ 3.136446] pps_core: LinuxPPS API ver. 1 registered
|
||||||
|
[ 3.136484] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
|
||||||
|
[ 3.136575] PTP clock support registered
|
||||||
|
[ 3.137256] clocksource: Switched to clocksource riscv_clocksource
|
||||||
|
[ 3.142711] NET: Registered protocol family 2
|
||||||
|
[ 3.143322] tcp_listen_portaddr_hash hash table entries: 4096 (order: 4, 65536 bytes)
|
||||||
|
[ 3.143634] TCP established hash table entries: 65536 (order: 7, 524288 bytes)
|
||||||
|
[ 3.145799] TCP bind hash table entries: 65536 (order: 8, 1048576 bytes)
|
||||||
|
[ 3.149121] TCP: Hash tables configured (established 65536 bind 65536)
|
||||||
|
[ 3.149591] UDP hash table entries: 4096 (order: 5, 131072 bytes)
|
||||||
|
[ 3.150094] UDP-Lite hash table entries: 4096 (order: 5, 131072 bytes)
|
||||||
|
[ 3.150781] NET: Registered protocol family 1
|
||||||
|
[ 3.230693] workingset: timestamp_bits=62 max_order=21 bucket_order=0
|
||||||
|
[ 3.241224] io scheduler mq-deadline registered
|
||||||
|
[ 3.241269] io scheduler kyber registered
|
||||||
|
[ 3.242143] sifive_gpio 10060000.gpio: SiFive GPIO chip registered 16 GPIOs
|
||||||
|
[ 3.242357] pwm-sifivem 10020000.pwm: Unable to find controller clock
|
||||||
|
[ 3.242439] pwm-sifivem 10021000.pwm: Unable to find controller clock
|
||||||
|
[ 3.243228] xilinx-pcie 2000000000.pci: PCIe Link is DOWN
|
||||||
|
[ 3.243289] xilinx-pcie 2000000000.pci: host bridge /soc/pci@2000000000 ranges:
|
||||||
|
[ 3.243360] xilinx-pcie 2000000000.pci: No bus range found for /soc/pci@2000000000, using [bus 00-ff]
|
||||||
|
[ 3.243447] xilinx-pcie 2000000000.pci: MEM 0x40000000..0x5fffffff -> 0x40000000
|
||||||
|
[ 3.243591] xilinx-pcie 2000000000.pci: PCI host bridge to bus 0000:00
|
||||||
|
[ 3.243636] pci_bus 0000:00: root bus resource [bus 00-ff]
|
||||||
|
[ 3.243676] pci_bus 0000:00: root bus resource [mem 0x40000000-0x5fffffff]
|
||||||
|
[ 3.276547] Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled
|
||||||
|
[ 3.277689] 10010000.serial: ttySIF0 at MMIO 0x10010000 (irq = 39, base_baud = 0) is a SiFive UART v0
|
||||||
|
[ 3.786963] printk: console [ttySIF0] enabled
|
||||||
|
[ 3.791504] 10011000.serial: ttySIF1 at MMIO 0x10011000 (irq = 40, base_baud = 0) is a SiFive UART v0
|
||||||
|
[ 3.801251] sifive_spi 10040000.spi: mapped; irq=41, cs=1
|
||||||
|
[ 3.806362] m25p80 spi0.0: unrecognized JEDEC id bytes: 9d, 70, 19
|
||||||
|
[ 3.812084] m25p80: probe of spi0.0 failed with error -2
|
||||||
|
[ 3.817453] sifive_spi 10041000.spi: mapped; irq=42, cs=4
|
||||||
|
[ 3.823027] sifive_spi 10050000.spi: mapped; irq=43, cs=1
|
||||||
|
[ 3.828604] libphy: Fixed MDIO Bus: probed
|
||||||
|
[ 3.832623] macb: GEM doesn't support hardware ptp.
|
||||||
|
[ 3.837196] libphy: MACB_mii_bus: probed
|
||||||
|
[ 4.041156] Microsemi VSC8541 SyncE 10090000.ethernet-ffffffff:00: attached PHY driver [Microsemi VSC8541 SyncE] (mii_bus:phy_addr=10090000.ethernet-ffffffff:00, irq=POLL)
|
||||||
|
[ 4.055779] macb 10090000.ethernet eth0: Cadence GEM rev 0x10070109 at 0x10090000 irq 12 (70:b3:d5:92:f0:c2)
|
||||||
|
[ 4.065780] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
|
||||||
|
[ 4.072033] ehci-pci: EHCI PCI platform driver
|
||||||
|
[ 4.076521] usbcore: registered new interface driver usb-storage
|
||||||
|
[ 4.082843] softdog: initialized. soft_noboot=0 soft_margin=60 sec soft_panic=0 (nowayout=0)
|
||||||
|
[ 4.127465] mmc_spi spi2.0: SD/MMC host mmc0, no DMA, no WP, no poweroff
|
||||||
|
[ 4.133645] usbcore: registered new interface driver usbhid
|
||||||
|
[ 4.138980] usbhid: USB HID core driver
|
||||||
|
[ 4.143017] NET: Registered protocol family 17
|
||||||
|
[ 4.147885] pwm-sifivem 10020000.pwm: SiFive PWM chip registered 4 PWMs
|
||||||
|
[ 4.153945] pwm-sifivem 10021000.pwm: SiFive PWM chip registered 4 PWMs
|
||||||
|
[ 4.186407] Freeing unused kernel memory: 9380K
|
||||||
|
[ 4.190224] This architecture does not have kernel memory protection.
|
||||||
|
[ 4.196609] Run /init as init process
|
||||||
|
Starting logging: OK
|
||||||
|
Starting mdev...
|
||||||
|
[ 4.303785] mmc0: host does not support reading read-only switch, assuming write-enable
|
||||||
|
[ 4.311109] mmc0: new SDHC card on SPI
|
||||||
|
[ 4.317103] mmcblk0: mmc0:0000 SS08G 7.40 GiB
|
||||||
|
[ 4.386471] mmcblk0: p1 p2
|
||||||
|
sort: /sys/devices/platform/Fixed: No such file or directory
|
||||||
|
modprobe: can't change directory to '/lib/modules': No such file or directory
|
||||||
|
Initializing random[ 4.759075] random: dd: uninitialized urandom read (512 bytes read)
|
||||||
|
number generator... done.
|
||||||
|
Starting network...
|
||||||
|
udhcpc (v1.24.2) started
|
||||||
|
Sending discover...
|
||||||
|
Sending discover...
|
||||||
|
[ 7.927510] macb 10090000.ethernet eth0: link up (1000/Full)
|
||||||
|
Sending discover...
|
||||||
|
Sending select for 10.196.157.190...
|
||||||
|
Lease of 10.196.157.190 obtained, lease time 499743
|
||||||
|
deleting routers
|
||||||
|
adding dns 10.86.1.1
|
||||||
|
adding dns 10.86.2.1
|
||||||
|
/etc/init.d/S50dropbear
|
||||||
|
Starting dropbear sshd: [ 12.772393] random: dropbear: uninitialized urandom read (32 bytes read)
|
||||||
|
OK
|
||||||
|
|
||||||
|
Welcome to Buildroot
|
||||||
|
buildroot login:
|
|
@ -1,15 +1,17 @@
|
||||||
# SPDX-License-Identifier: GPL-2.0+
|
.. SPDX-License-Identifier: GPL-2.0+
|
||||||
#
|
.. (C) Copyright 2013 Xilinx, Inc.
|
||||||
# Xilinx ZYNQ U-Boot
|
|
||||||
#
|
|
||||||
# (C) Copyright 2013 Xilinx, Inc.
|
|
||||||
|
|
||||||
1. About this
|
ZYNQ
|
||||||
|
====
|
||||||
|
|
||||||
|
About this
|
||||||
|
----------
|
||||||
|
|
||||||
This document describes the information about Xilinx Zynq U-Boot -
|
This document describes the information about Xilinx Zynq U-Boot -
|
||||||
like supported boards, ML status and TODO list.
|
like supported boards, ML status and TODO list.
|
||||||
|
|
||||||
2. Zynq boards
|
Zynq boards
|
||||||
|
-----------
|
||||||
|
|
||||||
Xilinx Zynq-7000 All Programmable SoCs enable extensive system level
|
Xilinx Zynq-7000 All Programmable SoCs enable extensive system level
|
||||||
differentiation, integration, and flexibility through hardware, software,
|
differentiation, integration, and flexibility through hardware, software,
|
||||||
|
@ -20,18 +22,21 @@ and I/O programmability.
|
||||||
* zed (single qspi, gem0, mmc) [3]
|
* zed (single qspi, gem0, mmc) [3]
|
||||||
* microzed (single qspi, gem0, mmc) [4]
|
* microzed (single qspi, gem0, mmc) [4]
|
||||||
* zc770
|
* zc770
|
||||||
- zc770-xm010 (single qspi, gem0, mmc)
|
- zc770-xm010 (single qspi, gem0, mmc)
|
||||||
- zc770-xm011 (8 or 16 bit nand)
|
- zc770-xm011 (8 or 16 bit nand)
|
||||||
- zc770-xm012 (nor)
|
- zc770-xm012 (nor)
|
||||||
- zc770-xm013 (dual parallel qspi, gem1)
|
- zc770-xm013 (dual parallel qspi, gem1)
|
||||||
|
|
||||||
3. Building
|
Building
|
||||||
|
--------
|
||||||
|
|
||||||
|
configure and build for zc702 board::
|
||||||
|
|
||||||
ex. configure and build for zc702 board
|
|
||||||
$ make zynq_zc702_config
|
$ make zynq_zc702_config
|
||||||
$ make
|
$ make
|
||||||
|
|
||||||
4. Bootmode
|
Bootmode
|
||||||
|
--------
|
||||||
|
|
||||||
Zynq has a facility to read the bootmode from the slcr bootmode register
|
Zynq has a facility to read the bootmode from the slcr bootmode register
|
||||||
once user is setting through jumpers on the board - see page no:1546 on [5]
|
once user is setting through jumpers on the board - see page no:1546 on [5]
|
||||||
|
@ -44,40 +49,47 @@ at runtime and assign the modeboot variable to specific bootmode string which
|
||||||
is intern used in autoboot.
|
is intern used in autoboot.
|
||||||
|
|
||||||
SLCR bootmode register Bit[3:0] values
|
SLCR bootmode register Bit[3:0] values
|
||||||
#define ZYNQ_BM_NOR 0x02
|
|
||||||
#define ZYNQ_BM_SD 0x05
|
.. code-block:: c
|
||||||
#define ZYNQ_BM_JTAG 0x0
|
|
||||||
|
#define ZYNQ_BM_NOR 0x02
|
||||||
|
#define ZYNQ_BM_SD 0x05
|
||||||
|
#define ZYNQ_BM_JTAG 0x0
|
||||||
|
|
||||||
"modeboot" variable can assign any of "norboot", "sdboot" or "jtagboot"
|
"modeboot" variable can assign any of "norboot", "sdboot" or "jtagboot"
|
||||||
bootmode strings at runtime.
|
bootmode strings at runtime.
|
||||||
|
|
||||||
5. Mainline status
|
Mainline status
|
||||||
|
---------------
|
||||||
|
|
||||||
- Added basic board configurations support.
|
- Added basic board configurations support.
|
||||||
- Added zynq u-boot bsp code - arch/arm/cpu/armv7/zynq
|
- Added zynq u-boot bsp code - arch/arm/cpu/armv7/zynq
|
||||||
- Added zynq boards named - zc70x, zed, microzed, zc770_xm010/xm011/xm012/xm013
|
- Added zynq boards named - zc70x, zed, microzed, zc770_xm010/xm011/xm012/xm013
|
||||||
- Added zynq drivers:
|
- Added zynq drivers:
|
||||||
serial - drivers/serial/serial_zynq.c
|
|
||||||
net - drivers/net/zynq_gem.c
|
:serial: drivers/serial/serial_zynq.c
|
||||||
mmc - drivers/mmc/zynq_sdhci.c
|
:net: drivers/net/zynq_gem.c
|
||||||
spi - drivers/spi/zynq_spi.c
|
:mmc: drivers/mmc/zynq_sdhci.c
|
||||||
qspi - drivers/spi/zynq_qspi.c
|
:spi: drivers/spi/zynq_spi.c
|
||||||
i2c - drivers/i2c/zynq_i2c.c
|
:qspi: drivers/spi/zynq_qspi.c
|
||||||
nand - drivers/mtd/nand/raw/zynq_nand.c
|
:i2c: drivers/i2c/zynq_i2c.c
|
||||||
|
:nand: drivers/mtd/nand/raw/zynq_nand.c
|
||||||
|
|
||||||
- Done proper cleanups on board configurations
|
- Done proper cleanups on board configurations
|
||||||
- Added basic FDT support for zynq boards
|
- Added basic FDT support for zynq boards
|
||||||
- d-cache support for zynq_gem.c
|
- d-cache support for zynq_gem.c
|
||||||
|
|
||||||
6. TODO
|
TODO
|
||||||
|
----
|
||||||
|
|
||||||
- Add FDT support on individual drivers
|
Add FDT support on individual drivers
|
||||||
|
|
||||||
[1] http://www.xilinx.com/products/boards-and-kits/EK-Z7-ZC702-G.htm
|
* [1] http://www.xilinx.com/products/boards-and-kits/EK-Z7-ZC702-G.htm
|
||||||
[2] http://www.xilinx.com/products/boards-and-kits/EK-Z7-ZC706-G.htm
|
* [2] http://www.xilinx.com/products/boards-and-kits/EK-Z7-ZC706-G.htm
|
||||||
[3] http://zedboard.org/product/zedboard
|
* [3] http://zedboard.org/product/zedboard
|
||||||
[4] http://zedboard.org/product/microzed
|
* [4] http://zedboard.org/product/microzed
|
||||||
[5] http://www.xilinx.com/support/documentation/user_guides/ug585-Zynq-7000-TRM.pdf
|
* [5] http://www.xilinx.com/support/documentation/user_guides/ug585-Zynq-7000-TRM.pdf
|
||||||
|
|
||||||
--
|
|
||||||
Jagannadha Sutradharudu Teki <jaganna@xilinx.com>
|
.. Jagannadha Sutradharudu Teki <jaganna@xilinx.com>
|
||||||
Sun Dec 15 14:52:41 IST 2013
|
.. Sun Dec 15 14:52:41 IST 2013
|
|
@ -1,40 +1,46 @@
|
||||||
Driver Model
|
.. SPDX-License-Identifier: GPL-2.0+
|
||||||
============
|
.. sectionauthor:: Simon Glass <sjg@chromium.org>
|
||||||
|
|
||||||
|
Design Details
|
||||||
|
==============
|
||||||
|
|
||||||
This README contains high-level information about driver model, a unified
|
This README contains high-level information about driver model, a unified
|
||||||
way of declaring and accessing drivers in U-Boot. The original work was done
|
way of declaring and accessing drivers in U-Boot. The original work was done
|
||||||
by:
|
by:
|
||||||
|
|
||||||
Marek Vasut <marex@denx.de>
|
* Marek Vasut <marex@denx.de>
|
||||||
Pavel Herrmann <morpheus.ibis@gmail.com>
|
* Pavel Herrmann <morpheus.ibis@gmail.com>
|
||||||
Viktor Křivák <viktor.krivak@gmail.com>
|
* Viktor Křivák <viktor.krivak@gmail.com>
|
||||||
Tomas Hlavacek <tmshlvck@gmail.com>
|
* Tomas Hlavacek <tmshlvck@gmail.com>
|
||||||
|
|
||||||
This has been both simplified and extended into the current implementation
|
This has been both simplified and extended into the current implementation
|
||||||
by:
|
by:
|
||||||
|
|
||||||
Simon Glass <sjg@chromium.org>
|
* Simon Glass <sjg@chromium.org>
|
||||||
|
|
||||||
|
|
||||||
Terminology
|
Terminology
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
Uclass - a group of devices which operate in the same way. A uclass provides
|
Uclass
|
||||||
a way of accessing individual devices within the group, but always
|
a group of devices which operate in the same way. A uclass provides
|
||||||
using the same interface. For example a GPIO uclass provides
|
a way of accessing individual devices within the group, but always
|
||||||
operations for get/set value. An I2C uclass may have 10 I2C ports,
|
using the same interface. For example a GPIO uclass provides
|
||||||
4 with one driver, and 6 with another.
|
operations for get/set value. An I2C uclass may have 10 I2C ports,
|
||||||
|
4 with one driver, and 6 with another.
|
||||||
|
|
||||||
Driver - some code which talks to a peripheral and presents a higher-level
|
Driver
|
||||||
interface to it.
|
some code which talks to a peripheral and presents a higher-level
|
||||||
|
interface to it.
|
||||||
|
|
||||||
Device - an instance of a driver, tied to a particular port or peripheral.
|
Device
|
||||||
|
an instance of a driver, tied to a particular port or peripheral.
|
||||||
|
|
||||||
|
|
||||||
How to try it
|
How to try it
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
Build U-Boot sandbox and run it:
|
Build U-Boot sandbox and run it::
|
||||||
|
|
||||||
make sandbox_defconfig
|
make sandbox_defconfig
|
||||||
make
|
make
|
||||||
|
@ -56,31 +62,31 @@ provide good code coverage of them. It does have multiple drivers, it
|
||||||
handles parameter data and platdata (data which tells the driver how
|
handles parameter data and platdata (data which tells the driver how
|
||||||
to operate on a particular platform) and it uses private driver data.
|
to operate on a particular platform) and it uses private driver data.
|
||||||
|
|
||||||
To try it, see the example session below:
|
To try it, see the example session below::
|
||||||
|
|
||||||
=>demo hello 1
|
=>demo hello 1
|
||||||
Hello '@' from 07981110: red 4
|
Hello '@' from 07981110: red 4
|
||||||
=>demo status 2
|
=>demo status 2
|
||||||
Status: 0
|
Status: 0
|
||||||
=>demo hello 2
|
=>demo hello 2
|
||||||
g
|
g
|
||||||
r@
|
r@
|
||||||
e@@
|
e@@
|
||||||
e@@@
|
e@@@
|
||||||
n@@@@
|
n@@@@
|
||||||
g@@@@@
|
g@@@@@
|
||||||
=>demo status 2
|
=>demo status 2
|
||||||
Status: 21
|
Status: 21
|
||||||
=>demo hello 4 ^
|
=>demo hello 4 ^
|
||||||
y^^^
|
y^^^
|
||||||
e^^^^^
|
e^^^^^
|
||||||
l^^^^^^^
|
l^^^^^^^
|
||||||
l^^^^^^^
|
l^^^^^^^
|
||||||
o^^^^^
|
o^^^^^
|
||||||
w^^^
|
w^^^
|
||||||
=>demo status 4
|
=>demo status 4
|
||||||
Status: 36
|
Status: 36
|
||||||
=>
|
=>
|
||||||
|
|
||||||
|
|
||||||
Running the tests
|
Running the tests
|
||||||
|
@ -88,139 +94,139 @@ Running the tests
|
||||||
|
|
||||||
The intent with driver model is that the core portion has 100% test coverage
|
The intent with driver model is that the core portion has 100% test coverage
|
||||||
in sandbox, and every uclass has its own test. As a move towards this, tests
|
in sandbox, and every uclass has its own test. As a move towards this, tests
|
||||||
are provided in test/dm. To run them, try:
|
are provided in test/dm. To run them, try::
|
||||||
|
|
||||||
./test/py/test.py --bd sandbox --build -k ut_dm -v
|
./test/py/test.py --bd sandbox --build -k ut_dm -v
|
||||||
|
|
||||||
You should see something like this:
|
You should see something like this::
|
||||||
|
|
||||||
(venv)$ ./test/py/test.py --bd sandbox --build -k ut_dm -v
|
(venv)$ ./test/py/test.py --bd sandbox --build -k ut_dm -v
|
||||||
+make O=/root/u-boot/build-sandbox -s sandbox_defconfig
|
+make O=/root/u-boot/build-sandbox -s sandbox_defconfig
|
||||||
+make O=/root/u-boot/build-sandbox -s -j8
|
+make O=/root/u-boot/build-sandbox -s -j8
|
||||||
============================= test session starts ==============================
|
============================= test session starts ==============================
|
||||||
platform linux2 -- Python 2.7.5, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 -- /root/u-boot/venv/bin/python
|
platform linux2 -- Python 2.7.5, pytest-2.9.0, py-1.4.31, pluggy-0.3.1 -- /root/u-boot/venv/bin/python
|
||||||
cachedir: .cache
|
cachedir: .cache
|
||||||
rootdir: /root/u-boot, inifile:
|
rootdir: /root/u-boot, inifile:
|
||||||
collected 199 items
|
collected 199 items
|
||||||
|
|
||||||
test/py/tests/test_ut.py::test_ut_dm_init PASSED
|
test/py/tests/test_ut.py::test_ut_dm_init PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_adc_bind] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_adc_bind] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_adc_multi_channel_conversion] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_adc_multi_channel_conversion] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_adc_multi_channel_shot] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_adc_multi_channel_shot] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_adc_single_channel_conversion] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_adc_single_channel_conversion] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_adc_single_channel_shot] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_adc_single_channel_shot] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_adc_supply] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_adc_supply] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_adc_wrong_channel_selection] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_adc_wrong_channel_selection] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_autobind] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_autobind] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_autobind_uclass_pdata_alloc] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_autobind_uclass_pdata_alloc] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_autobind_uclass_pdata_valid] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_autobind_uclass_pdata_valid] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_autoprobe] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_autoprobe] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_bus_child_post_bind] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_bus_child_post_bind] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_bus_child_post_bind_uclass] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_bus_child_post_bind_uclass] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_bus_child_pre_probe_uclass] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_bus_child_pre_probe_uclass] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_bus_children] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_bus_children] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_bus_children_funcs] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_bus_children_funcs] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_bus_children_iterators] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_bus_children_iterators] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_bus_parent_data] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_bus_parent_data] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_bus_parent_data_uclass] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_bus_parent_data_uclass] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_bus_parent_ops] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_bus_parent_ops] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_bus_parent_platdata] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_bus_parent_platdata] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_bus_parent_platdata_uclass] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_bus_parent_platdata_uclass] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_children] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_children] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_clk_base] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_clk_base] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_clk_periph] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_clk_periph] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_device_get_uclass_id] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_device_get_uclass_id] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_eth] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_eth] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_eth_act] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_eth_act] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_eth_alias] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_eth_alias] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_eth_prime] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_eth_prime] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_eth_rotate] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_eth_rotate] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_fdt] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_fdt] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_fdt_offset] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_fdt_offset] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_fdt_pre_reloc] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_fdt_pre_reloc] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_fdt_uclass_seq] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_fdt_uclass_seq] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_gpio] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_gpio] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_gpio_anon] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_gpio_anon] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_gpio_copy] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_gpio_copy] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_gpio_leak] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_gpio_leak] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_gpio_phandles] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_gpio_phandles] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_gpio_requestf] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_gpio_requestf] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_i2c_bytewise] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_i2c_bytewise] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_i2c_find] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_i2c_find] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_i2c_offset] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_i2c_offset] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_i2c_offset_len] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_i2c_offset_len] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_i2c_probe_empty] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_i2c_probe_empty] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_i2c_read_write] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_i2c_read_write] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_i2c_speed] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_i2c_speed] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_leak] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_leak] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_led_base] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_led_base] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_led_gpio] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_led_gpio] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_led_label] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_led_label] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_lifecycle] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_lifecycle] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_mmc_base] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_mmc_base] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_net_retry] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_net_retry] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_operations] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_operations] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_ordering] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_ordering] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_pci_base] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_pci_base] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_pci_busnum] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_pci_busnum] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_pci_swapcase] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_pci_swapcase] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_platdata] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_platdata] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_power_pmic_get] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_power_pmic_get] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_power_pmic_io] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_power_pmic_io] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_power_regulator_autoset] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_power_regulator_autoset] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_power_regulator_autoset_list] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_power_regulator_autoset_list] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_power_regulator_get] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_power_regulator_get] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_power_regulator_set_get_current] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_power_regulator_set_get_current] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_power_regulator_set_get_enable] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_power_regulator_set_get_enable] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_power_regulator_set_get_mode] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_power_regulator_set_get_mode] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_power_regulator_set_get_voltage] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_power_regulator_set_get_voltage] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_pre_reloc] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_pre_reloc] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_ram_base] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_ram_base] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_regmap_base] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_regmap_base] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_regmap_syscon] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_regmap_syscon] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_remoteproc_base] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_remoteproc_base] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_remove] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_remove] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_reset_base] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_reset_base] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_reset_walk] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_reset_walk] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_rtc_base] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_rtc_base] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_rtc_dual] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_rtc_dual] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_rtc_reset] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_rtc_reset] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_rtc_set_get] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_rtc_set_get] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_spi_find] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_spi_find] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_spi_flash] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_spi_flash] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_spi_xfer] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_spi_xfer] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_syscon_base] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_syscon_base] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_syscon_by_driver_data] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_syscon_by_driver_data] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_timer_base] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_timer_base] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_uclass] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_uclass] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_uclass_before_ready] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_uclass_before_ready] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_uclass_devices_find] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_uclass_devices_find] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_uclass_devices_find_by_name] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_uclass_devices_find_by_name] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_uclass_devices_get] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_uclass_devices_get] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_uclass_devices_get_by_name] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_uclass_devices_get_by_name] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_usb_base] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_usb_base] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_usb_flash] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_usb_flash] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_usb_keyb] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_usb_keyb] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_usb_multi] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_usb_multi] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_usb_remove] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_usb_remove] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_usb_tree] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_usb_tree] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_usb_tree_remove] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_usb_tree_remove] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_usb_tree_reorder] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_usb_tree_reorder] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_video_base] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_video_base] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_video_bmp] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_video_bmp] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_video_bmp_comp] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_video_bmp_comp] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_video_chars] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_video_chars] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_video_context] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_video_context] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_video_rotation1] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_video_rotation1] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_video_rotation2] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_video_rotation2] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_video_rotation3] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_video_rotation3] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_video_text] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_video_text] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_video_truetype] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_video_truetype] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_video_truetype_bs] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_video_truetype_bs] PASSED
|
||||||
test/py/tests/test_ut.py::test_ut[ut_dm_video_truetype_scroll] PASSED
|
test/py/tests/test_ut.py::test_ut[ut_dm_video_truetype_scroll] PASSED
|
||||||
|
|
||||||
======================= 84 tests deselected by '-kut_dm' =======================
|
======================= 84 tests deselected by '-kut_dm' =======================
|
||||||
================== 115 passed, 84 deselected in 3.77 seconds ===================
|
================== 115 passed, 84 deselected in 3.77 seconds ===================
|
||||||
|
|
||||||
What is going on?
|
What is going on?
|
||||||
-----------------
|
-----------------
|
||||||
|
@ -228,6 +234,8 @@ What is going on?
|
||||||
Let's start at the top. The demo command is in common/cmd_demo.c. It does
|
Let's start at the top. The demo command is in common/cmd_demo.c. It does
|
||||||
the usual command processing and then:
|
the usual command processing and then:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
struct udevice *demo_dev;
|
struct udevice *demo_dev;
|
||||||
|
|
||||||
ret = uclass_get_device(UCLASS_DEMO, devnum, &demo_dev);
|
ret = uclass_get_device(UCLASS_DEMO, devnum, &demo_dev);
|
||||||
|
@ -245,6 +253,8 @@ The device is automatically activated ready for use by uclass_get_device().
|
||||||
|
|
||||||
Now that we have the device we can do things like:
|
Now that we have the device we can do things like:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
return demo_hello(demo_dev, ch);
|
return demo_hello(demo_dev, ch);
|
||||||
|
|
||||||
This function is in the demo uclass. It takes care of calling the 'hello'
|
This function is in the demo uclass. It takes care of calling the 'hello'
|
||||||
|
@ -253,28 +263,32 @@ this particular device may use one or other of them.
|
||||||
|
|
||||||
The code for demo_hello() is in drivers/demo/demo-uclass.c:
|
The code for demo_hello() is in drivers/demo/demo-uclass.c:
|
||||||
|
|
||||||
int demo_hello(struct udevice *dev, int ch)
|
.. code-block:: c
|
||||||
{
|
|
||||||
const struct demo_ops *ops = device_get_ops(dev);
|
|
||||||
|
|
||||||
if (!ops->hello)
|
int demo_hello(struct udevice *dev, int ch)
|
||||||
return -ENOSYS;
|
{
|
||||||
|
const struct demo_ops *ops = device_get_ops(dev);
|
||||||
|
|
||||||
return ops->hello(dev, ch);
|
if (!ops->hello)
|
||||||
}
|
return -ENOSYS;
|
||||||
|
|
||||||
|
return ops->hello(dev, ch);
|
||||||
|
}
|
||||||
|
|
||||||
As you can see it just calls the relevant driver method. One of these is
|
As you can see it just calls the relevant driver method. One of these is
|
||||||
in drivers/demo/demo-simple.c:
|
in drivers/demo/demo-simple.c:
|
||||||
|
|
||||||
static int simple_hello(struct udevice *dev, int ch)
|
.. code-block:: c
|
||||||
{
|
|
||||||
const struct dm_demo_pdata *pdata = dev_get_platdata(dev);
|
|
||||||
|
|
||||||
printf("Hello from %08x: %s %d\n", map_to_sysmem(dev),
|
static int simple_hello(struct udevice *dev, int ch)
|
||||||
pdata->colour, pdata->sides);
|
{
|
||||||
|
const struct dm_demo_pdata *pdata = dev_get_platdata(dev);
|
||||||
|
|
||||||
return 0;
|
printf("Hello from %08x: %s %d\n", map_to_sysmem(dev),
|
||||||
}
|
pdata->colour, pdata->sides);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
So that is a trip from top (command execution) to bottom (driver action)
|
So that is a trip from top (command execution) to bottom (driver action)
|
||||||
|
@ -287,17 +301,19 @@ Declaring Drivers
|
||||||
A driver declaration looks something like this (see
|
A driver declaration looks something like this (see
|
||||||
drivers/demo/demo-shape.c):
|
drivers/demo/demo-shape.c):
|
||||||
|
|
||||||
static const struct demo_ops shape_ops = {
|
.. code-block:: c
|
||||||
.hello = shape_hello,
|
|
||||||
.status = shape_status,
|
|
||||||
};
|
|
||||||
|
|
||||||
U_BOOT_DRIVER(demo_shape_drv) = {
|
static const struct demo_ops shape_ops = {
|
||||||
.name = "demo_shape_drv",
|
.hello = shape_hello,
|
||||||
.id = UCLASS_DEMO,
|
.status = shape_status,
|
||||||
.ops = &shape_ops,
|
};
|
||||||
.priv_data_size = sizeof(struct shape_data),
|
|
||||||
};
|
U_BOOT_DRIVER(demo_shape_drv) = {
|
||||||
|
.name = "demo_shape_drv",
|
||||||
|
.id = UCLASS_DEMO,
|
||||||
|
.ops = &shape_ops,
|
||||||
|
.priv_data_size = sizeof(struct shape_data),
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
This driver has two methods (hello and status) and requires a bit of
|
This driver has two methods (hello and status) and requires a bit of
|
||||||
|
@ -315,11 +331,11 @@ so driver model can find the drivers that are available.
|
||||||
The methods a device can provide are documented in the device.h header.
|
The methods a device can provide are documented in the device.h header.
|
||||||
Briefly, they are:
|
Briefly, they are:
|
||||||
|
|
||||||
bind - make the driver model aware of a device (bind it to its driver)
|
* bind - make the driver model aware of a device (bind it to its driver)
|
||||||
unbind - make the driver model forget the device
|
* unbind - make the driver model forget the device
|
||||||
ofdata_to_platdata - convert device tree data to platdata - see later
|
* ofdata_to_platdata - convert device tree data to platdata - see later
|
||||||
probe - make a device ready for use
|
* probe - make a device ready for use
|
||||||
remove - remove a device so it cannot be used until probed again
|
* remove - remove a device so it cannot be used until probed again
|
||||||
|
|
||||||
The sequence to get a device to work is bind, ofdata_to_platdata (if using
|
The sequence to get a device to work is bind, ofdata_to_platdata (if using
|
||||||
device tree) and probe.
|
device tree) and probe.
|
||||||
|
@ -328,14 +344,14 @@ device tree) and probe.
|
||||||
Platform Data
|
Platform Data
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
*** Note: platform data is the old way of doing things. It is
|
Note: platform data is the old way of doing things. It is
|
||||||
*** basically a C structure which is passed to drivers to tell them about
|
basically a C structure which is passed to drivers to tell them about
|
||||||
*** platform-specific settings like the address of its registers, bus
|
platform-specific settings like the address of its registers, bus
|
||||||
*** speed, etc. Device tree is now the preferred way of handling this.
|
speed, etc. Device tree is now the preferred way of handling this.
|
||||||
*** Unless you have a good reason not to use device tree (the main one
|
Unless you have a good reason not to use device tree (the main one
|
||||||
*** being you need serial support in SPL and don't have enough SRAM for
|
being you need serial support in SPL and don't have enough SRAM for
|
||||||
*** the cut-down device tree and libfdt libraries) you should stay away
|
the cut-down device tree and libfdt libraries) you should stay away
|
||||||
*** from platform data.
|
from platform data.
|
||||||
|
|
||||||
Platform data is like Linux platform data, if you are familiar with that.
|
Platform data is like Linux platform data, if you are familiar with that.
|
||||||
It provides the board-specific information to start up a device.
|
It provides the board-specific information to start up a device.
|
||||||
|
@ -366,9 +382,9 @@ Examples of platform data include:
|
||||||
|
|
||||||
- The base address of the IP block's register space
|
- The base address of the IP block's register space
|
||||||
- Configuration options, like:
|
- Configuration options, like:
|
||||||
- the SPI polarity and maximum speed for a SPI controller
|
- the SPI polarity and maximum speed for a SPI controller
|
||||||
- the I2C speed to use for an I2C device
|
- the I2C speed to use for an I2C device
|
||||||
- the number of GPIOs available in a GPIO device
|
- the number of GPIOs available in a GPIO device
|
||||||
|
|
||||||
Where does the platform data come from? It is either held in a structure
|
Where does the platform data come from? It is either held in a structure
|
||||||
which is compiled into U-Boot, or it can be parsed from the Device Tree
|
which is compiled into U-Boot, or it can be parsed from the Device Tree
|
||||||
|
@ -384,10 +400,13 @@ Drivers can access their data via dev->info->platdata. Here is
|
||||||
the declaration for the platform data, which would normally appear
|
the declaration for the platform data, which would normally appear
|
||||||
in the board file.
|
in the board file.
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
static const struct dm_demo_cdata red_square = {
|
static const struct dm_demo_cdata red_square = {
|
||||||
.colour = "red",
|
.colour = "red",
|
||||||
.sides = 4.
|
.sides = 4.
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct driver_info info[] = {
|
static const struct driver_info info[] = {
|
||||||
{
|
{
|
||||||
.name = "demo_shape_drv",
|
.name = "demo_shape_drv",
|
||||||
|
@ -409,6 +428,8 @@ necessary.
|
||||||
With device tree we replace the above code with the following device tree
|
With device tree we replace the above code with the following device tree
|
||||||
fragment:
|
fragment:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
red-square {
|
red-square {
|
||||||
compatible = "demo-shape";
|
compatible = "demo-shape";
|
||||||
colour = "red";
|
colour = "red";
|
||||||
|
@ -425,6 +446,8 @@ the board first!).
|
||||||
|
|
||||||
The easiest way to make this work it to add a few members to the driver:
|
The easiest way to make this work it to add a few members to the driver:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
.platdata_auto_alloc_size = sizeof(struct dm_test_pdata),
|
.platdata_auto_alloc_size = sizeof(struct dm_test_pdata),
|
||||||
.ofdata_to_platdata = testfdt_ofdata_to_platdata,
|
.ofdata_to_platdata = testfdt_ofdata_to_platdata,
|
||||||
|
|
||||||
|
@ -464,9 +487,11 @@ Declaring Uclasses
|
||||||
|
|
||||||
The demo uclass is declared like this:
|
The demo uclass is declared like this:
|
||||||
|
|
||||||
U_BOOT_CLASS(demo) = {
|
.. code-block:: c
|
||||||
.id = UCLASS_DEMO,
|
|
||||||
};
|
U_BOOT_CLASS(demo) = {
|
||||||
|
.id = UCLASS_DEMO,
|
||||||
|
};
|
||||||
|
|
||||||
It is also possible to specify special methods for probe, etc. The uclass
|
It is also possible to specify special methods for probe, etc. The uclass
|
||||||
numbering comes from include/dm/uclass.h. To add a new uclass, add to the
|
numbering comes from include/dm/uclass.h. To add a new uclass, add to the
|
||||||
|
@ -496,9 +521,11 @@ device will be automatically allocated the next available sequence number.
|
||||||
To specify the sequence number in the device tree an alias is typically
|
To specify the sequence number in the device tree an alias is typically
|
||||||
used. Make sure that the uclass has the DM_UC_FLAG_SEQ_ALIAS flag set.
|
used. Make sure that the uclass has the DM_UC_FLAG_SEQ_ALIAS flag set.
|
||||||
|
|
||||||
aliases {
|
.. code-block:: none
|
||||||
serial2 = "/serial@22230000";
|
|
||||||
};
|
aliases {
|
||||||
|
serial2 = "/serial@22230000";
|
||||||
|
};
|
||||||
|
|
||||||
This indicates that in the uclass called "serial", the named node
|
This indicates that in the uclass called "serial", the named node
|
||||||
("/serial@22230000") will be given sequence number 2. Any command or driver
|
("/serial@22230000") will be given sequence number 2. Any command or driver
|
||||||
|
@ -506,13 +533,15 @@ which requests serial device 2 will obtain this device.
|
||||||
|
|
||||||
More commonly you can use node references, which expand to the full path:
|
More commonly you can use node references, which expand to the full path:
|
||||||
|
|
||||||
aliases {
|
.. code-block:: none
|
||||||
serial2 = &serial_2;
|
|
||||||
};
|
aliases {
|
||||||
...
|
serial2 = &serial_2;
|
||||||
serial_2: serial@22230000 {
|
};
|
||||||
...
|
...
|
||||||
};
|
serial_2: serial@22230000 {
|
||||||
|
...
|
||||||
|
};
|
||||||
|
|
||||||
The alias resolves to the same string in this case, but this version is
|
The alias resolves to the same string in this case, but this version is
|
||||||
easier to read.
|
easier to read.
|
||||||
|
@ -547,7 +576,7 @@ children are bound and probed.
|
||||||
|
|
||||||
Here an explanation of how a bus fits with a uclass may be useful. Consider
|
Here an explanation of how a bus fits with a uclass may be useful. Consider
|
||||||
a USB bus with several devices attached to it, each from a different (made
|
a USB bus with several devices attached to it, each from a different (made
|
||||||
up) uclass:
|
up) uclass::
|
||||||
|
|
||||||
xhci_usb (UCLASS_USB)
|
xhci_usb (UCLASS_USB)
|
||||||
eth (UCLASS_ETHERNET)
|
eth (UCLASS_ETHERNET)
|
||||||
|
@ -579,7 +608,7 @@ Note that the information that controls this behaviour is in the bus's
|
||||||
driver, not the child's. In fact it is possible that child has no knowledge
|
driver, not the child's. In fact it is possible that child has no knowledge
|
||||||
that it is connected to a bus. The same child device may even be used on two
|
that it is connected to a bus. The same child device may even be used on two
|
||||||
different bus types. As an example. the 'flash' device shown above may also
|
different bus types. As an example. the 'flash' device shown above may also
|
||||||
be connected on a SATA bus or standalone with no bus:
|
be connected on a SATA bus or standalone with no bus::
|
||||||
|
|
||||||
xhci_usb (UCLASS_USB)
|
xhci_usb (UCLASS_USB)
|
||||||
flash (UCLASS_FLASH_STORAGE) - parent data/methods defined by USB bus
|
flash (UCLASS_FLASH_STORAGE) - parent data/methods defined by USB bus
|
||||||
|
@ -613,20 +642,21 @@ methods mentioned here are optional - e.g. if there is no probe() method for
|
||||||
a device then it will not be called. A simple device may have very few
|
a device then it will not be called. A simple device may have very few
|
||||||
methods actually defined.
|
methods actually defined.
|
||||||
|
|
||||||
1. Bind stage
|
Bind stage
|
||||||
|
^^^^^^^^^^
|
||||||
|
|
||||||
U-Boot discovers devices using one of these two methods:
|
U-Boot discovers devices using one of these two methods:
|
||||||
|
|
||||||
- Scan the U_BOOT_DEVICE() definitions. U-Boot looks up the name specified
|
- Scan the U_BOOT_DEVICE() definitions. U-Boot looks up the name specified
|
||||||
by each, to find the appropriate U_BOOT_DRIVER() definition. In this case,
|
by each, to find the appropriate U_BOOT_DRIVER() definition. In this case,
|
||||||
there is no path by which driver_data may be provided, but the U_BOOT_DEVICE()
|
there is no path by which driver_data may be provided, but the U_BOOT_DEVICE()
|
||||||
may provide platdata.
|
may provide platdata.
|
||||||
|
|
||||||
- Scan through the device tree definitions. U-Boot looks at top-level
|
- Scan through the device tree definitions. U-Boot looks at top-level
|
||||||
nodes in the the device tree. It looks at the compatible string in each node
|
nodes in the the device tree. It looks at the compatible string in each node
|
||||||
and uses the of_match table of the U_BOOT_DRIVER() structure to find the
|
and uses the of_match table of the U_BOOT_DRIVER() structure to find the
|
||||||
right driver for each node. In this case, the of_match table may provide a
|
right driver for each node. In this case, the of_match table may provide a
|
||||||
driver_data value, but platdata cannot be provided until later.
|
driver_data value, but platdata cannot be provided until later.
|
||||||
|
|
||||||
For each device that is discovered, U-Boot then calls device_bind() to create a
|
For each device that is discovered, U-Boot then calls device_bind() to create a
|
||||||
new device, initializes various core fields of the device object such as name,
|
new device, initializes various core fields of the device object such as name,
|
||||||
|
@ -653,45 +683,46 @@ probe/remove which is independent of bind/unbind. This is partly because in
|
||||||
U-Boot it may be expensive to probe devices and we don't want to do it until
|
U-Boot it may be expensive to probe devices and we don't want to do it until
|
||||||
they are needed, or perhaps until after relocation.
|
they are needed, or perhaps until after relocation.
|
||||||
|
|
||||||
2. Activation/probe
|
Activation/probe
|
||||||
|
^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
When a device needs to be used, U-Boot activates it, by following these
|
When a device needs to be used, U-Boot activates it, by following these
|
||||||
steps (see device_probe()):
|
steps (see device_probe()):
|
||||||
|
|
||||||
a. If priv_auto_alloc_size is non-zero, then the device-private space
|
1. If priv_auto_alloc_size is non-zero, then the device-private space
|
||||||
is allocated for the device and zeroed. It will be accessible as
|
is allocated for the device and zeroed. It will be accessible as
|
||||||
dev->priv. The driver can put anything it likes in there, but should use
|
dev->priv. The driver can put anything it likes in there, but should use
|
||||||
it for run-time information, not platform data (which should be static
|
it for run-time information, not platform data (which should be static
|
||||||
and known before the device is probed).
|
and known before the device is probed).
|
||||||
|
|
||||||
b. If platdata_auto_alloc_size is non-zero, then the platform data space
|
2. If platdata_auto_alloc_size is non-zero, then the platform data space
|
||||||
is allocated. This is only useful for device tree operation, since
|
is allocated. This is only useful for device tree operation, since
|
||||||
otherwise you would have to specific the platform data in the
|
otherwise you would have to specific the platform data in the
|
||||||
U_BOOT_DEVICE() declaration. The space is allocated for the device and
|
U_BOOT_DEVICE() declaration. The space is allocated for the device and
|
||||||
zeroed. It will be accessible as dev->platdata.
|
zeroed. It will be accessible as dev->platdata.
|
||||||
|
|
||||||
c. If the device's uclass specifies a non-zero per_device_auto_alloc_size,
|
3. If the device's uclass specifies a non-zero per_device_auto_alloc_size,
|
||||||
then this space is allocated and zeroed also. It is allocated for and
|
then this space is allocated and zeroed also. It is allocated for and
|
||||||
stored in the device, but it is uclass data. owned by the uclass driver.
|
stored in the device, but it is uclass data. owned by the uclass driver.
|
||||||
It is possible for the device to access it.
|
It is possible for the device to access it.
|
||||||
|
|
||||||
d. If the device's immediate parent specifies a per_child_auto_alloc_size
|
4. If the device's immediate parent specifies a per_child_auto_alloc_size
|
||||||
then this space is allocated. This is intended for use by the parent
|
then this space is allocated. This is intended for use by the parent
|
||||||
device to keep track of things related to the child. For example a USB
|
device to keep track of things related to the child. For example a USB
|
||||||
flash stick attached to a USB host controller would likely use this
|
flash stick attached to a USB host controller would likely use this
|
||||||
space. The controller can hold information about the USB state of each
|
space. The controller can hold information about the USB state of each
|
||||||
of its children.
|
of its children.
|
||||||
|
|
||||||
e. All parent devices are probed. It is not possible to activate a device
|
5. All parent devices are probed. It is not possible to activate a device
|
||||||
unless its predecessors (all the way up to the root device) are activated.
|
unless its predecessors (all the way up to the root device) are activated.
|
||||||
This means (for example) that an I2C driver will require that its bus
|
This means (for example) that an I2C driver will require that its bus
|
||||||
be activated.
|
be activated.
|
||||||
|
|
||||||
f. The device's sequence number is assigned, either the requested one
|
6. The device's sequence number is assigned, either the requested one
|
||||||
(assuming no conflicts) or the next available one if there is a conflict
|
(assuming no conflicts) or the next available one if there is a conflict
|
||||||
or nothing particular is requested.
|
or nothing particular is requested.
|
||||||
|
|
||||||
g. If the driver provides an ofdata_to_platdata() method, then this is
|
7. If the driver provides an ofdata_to_platdata() method, then this is
|
||||||
called to convert the device tree data into platform data. This should
|
called to convert the device tree data into platform data. This should
|
||||||
do various calls like fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), ...)
|
do various calls like fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), ...)
|
||||||
to access the node and store the resulting information into dev->platdata.
|
to access the node and store the resulting information into dev->platdata.
|
||||||
|
@ -707,7 +738,7 @@ steps (see device_probe()):
|
||||||
data, one day it is possible that U-Boot will cache platform data for
|
data, one day it is possible that U-Boot will cache platform data for
|
||||||
devices which are regularly de/activated).
|
devices which are regularly de/activated).
|
||||||
|
|
||||||
h. The device's probe() method is called. This should do anything that
|
8. The device's probe() method is called. This should do anything that
|
||||||
is required by the device to get it going. This could include checking
|
is required by the device to get it going. This could include checking
|
||||||
that the hardware is actually present, setting up clocks for the
|
that the hardware is actually present, setting up clocks for the
|
||||||
hardware and setting up hardware registers to initial values. The code
|
hardware and setting up hardware registers to initial values. The code
|
||||||
|
@ -722,40 +753,42 @@ steps (see device_probe()):
|
||||||
allocate the priv space here yourself. The same applies also to
|
allocate the priv space here yourself. The same applies also to
|
||||||
platdata_auto_alloc_size. Remember to free them in the remove() method.
|
platdata_auto_alloc_size. Remember to free them in the remove() method.
|
||||||
|
|
||||||
i. The device is marked 'activated'
|
9. The device is marked 'activated'
|
||||||
|
|
||||||
j. The uclass's post_probe() method is called, if one exists. This may
|
10. The uclass's post_probe() method is called, if one exists. This may
|
||||||
cause the uclass to do some housekeeping to record the device as
|
cause the uclass to do some housekeeping to record the device as
|
||||||
activated and 'known' by the uclass.
|
activated and 'known' by the uclass.
|
||||||
|
|
||||||
3. Running stage
|
Running stage
|
||||||
|
^^^^^^^^^^^^^
|
||||||
|
|
||||||
The device is now activated and can be used. From now until it is removed
|
The device is now activated and can be used. From now until it is removed
|
||||||
all of the above structures are accessible. The device appears in the
|
all of the above structures are accessible. The device appears in the
|
||||||
uclass's list of devices (so if the device is in UCLASS_GPIO it will appear
|
uclass's list of devices (so if the device is in UCLASS_GPIO it will appear
|
||||||
as a device in the GPIO uclass). This is the 'running' state of the device.
|
as a device in the GPIO uclass). This is the 'running' state of the device.
|
||||||
|
|
||||||
4. Removal stage
|
Removal stage
|
||||||
|
^^^^^^^^^^^^^
|
||||||
|
|
||||||
When the device is no-longer required, you can call device_remove() to
|
When the device is no-longer required, you can call device_remove() to
|
||||||
remove it. This performs the probe steps in reverse:
|
remove it. This performs the probe steps in reverse:
|
||||||
|
|
||||||
a. The uclass's pre_remove() method is called, if one exists. This may
|
1. The uclass's pre_remove() method is called, if one exists. This may
|
||||||
cause the uclass to do some housekeeping to record the device as
|
cause the uclass to do some housekeeping to record the device as
|
||||||
deactivated and no-longer 'known' by the uclass.
|
deactivated and no-longer 'known' by the uclass.
|
||||||
|
|
||||||
b. All the device's children are removed. It is not permitted to have
|
2. All the device's children are removed. It is not permitted to have
|
||||||
an active child device with a non-active parent. This means that
|
an active child device with a non-active parent. This means that
|
||||||
device_remove() is called for all the children recursively at this point.
|
device_remove() is called for all the children recursively at this point.
|
||||||
|
|
||||||
c. The device's remove() method is called. At this stage nothing has been
|
3. The device's remove() method is called. At this stage nothing has been
|
||||||
deallocated so platform data, private data and the uclass data will all
|
deallocated so platform data, private data and the uclass data will all
|
||||||
still be present. This is where the hardware can be shut down. It is
|
still be present. This is where the hardware can be shut down. It is
|
||||||
intended that the device be completely inactive at this point, For U-Boot
|
intended that the device be completely inactive at this point, For U-Boot
|
||||||
to be sure that no hardware is running, it should be enough to remove
|
to be sure that no hardware is running, it should be enough to remove
|
||||||
all devices.
|
all devices.
|
||||||
|
|
||||||
d. The device memory is freed (platform data, private data, uclass data,
|
4. The device memory is freed (platform data, private data, uclass data,
|
||||||
parent data).
|
parent data).
|
||||||
|
|
||||||
Note: Because the platform data for a U_BOOT_DEVICE() is defined with a
|
Note: Because the platform data for a U_BOOT_DEVICE() is defined with a
|
||||||
|
@ -764,25 +797,26 @@ remove it. This performs the probe steps in reverse:
|
||||||
be dynamically allocated, and thus needs to be deallocated during the
|
be dynamically allocated, and thus needs to be deallocated during the
|
||||||
remove() method, either:
|
remove() method, either:
|
||||||
|
|
||||||
1. if the platdata_auto_alloc_size is non-zero, the deallocation
|
- if the platdata_auto_alloc_size is non-zero, the deallocation
|
||||||
happens automatically within the driver model core; or
|
happens automatically within the driver model core; or
|
||||||
|
|
||||||
2. when platdata_auto_alloc_size is 0, both the allocation (in probe()
|
- when platdata_auto_alloc_size is 0, both the allocation (in probe()
|
||||||
or preferably ofdata_to_platdata()) and the deallocation in remove()
|
or preferably ofdata_to_platdata()) and the deallocation in remove()
|
||||||
are the responsibility of the driver author.
|
are the responsibility of the driver author.
|
||||||
|
|
||||||
e. The device sequence number is set to -1, meaning that it no longer
|
5. The device sequence number is set to -1, meaning that it no longer
|
||||||
has an allocated sequence. If the device is later reactivated and that
|
has an allocated sequence. If the device is later reactivated and that
|
||||||
sequence number is still free, it may well receive the name sequence
|
sequence number is still free, it may well receive the name sequence
|
||||||
number again. But from this point, the sequence number previously used
|
number again. But from this point, the sequence number previously used
|
||||||
by this device will no longer exist (think of SPI bus 2 being removed
|
by this device will no longer exist (think of SPI bus 2 being removed
|
||||||
and bus 2 is no longer available for use).
|
and bus 2 is no longer available for use).
|
||||||
|
|
||||||
f. The device is marked inactive. Note that it is still bound, so the
|
6. The device is marked inactive. Note that it is still bound, so the
|
||||||
device structure itself is not freed at this point. Should the device be
|
device structure itself is not freed at this point. Should the device be
|
||||||
activated again, then the cycle starts again at step 2 above.
|
activated again, then the cycle starts again at step 2 above.
|
||||||
|
|
||||||
5. Unbind stage
|
Unbind stage
|
||||||
|
^^^^^^^^^^^^
|
||||||
|
|
||||||
The device is unbound. This is the step that actually destroys the device.
|
The device is unbound. This is the step that actually destroys the device.
|
||||||
If a parent has children these will be destroyed first. After this point
|
If a parent has children these will be destroyed first. After this point
|
||||||
|
@ -805,24 +839,24 @@ For the record, this implementation uses a very similar approach to the
|
||||||
original patches, but makes at least the following changes:
|
original patches, but makes at least the following changes:
|
||||||
|
|
||||||
- Tried to aggressively remove boilerplate, so that for most drivers there
|
- Tried to aggressively remove boilerplate, so that for most drivers there
|
||||||
is little or no 'driver model' code to write.
|
is little or no 'driver model' code to write.
|
||||||
- Moved some data from code into data structure - e.g. store a pointer to
|
- Moved some data from code into data structure - e.g. store a pointer to
|
||||||
the driver operations structure in the driver, rather than passing it
|
the driver operations structure in the driver, rather than passing it
|
||||||
to the driver bind function.
|
to the driver bind function.
|
||||||
- Rename some structures to make them more similar to Linux (struct udevice
|
- Rename some structures to make them more similar to Linux (struct udevice
|
||||||
instead of struct instance, struct platdata, etc.)
|
instead of struct instance, struct platdata, etc.)
|
||||||
- Change the name 'core' to 'uclass', meaning U-Boot class. It seems that
|
- Change the name 'core' to 'uclass', meaning U-Boot class. It seems that
|
||||||
this concept relates to a class of drivers (or a subsystem). We shouldn't
|
this concept relates to a class of drivers (or a subsystem). We shouldn't
|
||||||
use 'class' since it is a C++ reserved word, so U-Boot class (uclass) seems
|
use 'class' since it is a C++ reserved word, so U-Boot class (uclass) seems
|
||||||
better than 'core'.
|
better than 'core'.
|
||||||
- Remove 'struct driver_instance' and just use a single 'struct udevice'.
|
- Remove 'struct driver_instance' and just use a single 'struct udevice'.
|
||||||
This removes a level of indirection that doesn't seem necessary.
|
This removes a level of indirection that doesn't seem necessary.
|
||||||
- Built in device tree support, to avoid the need for platdata
|
- Built in device tree support, to avoid the need for platdata
|
||||||
- Removed the concept of driver relocation, and just make it possible for
|
- Removed the concept of driver relocation, and just make it possible for
|
||||||
the new driver (created after relocation) to access the old driver data.
|
the new driver (created after relocation) to access the old driver data.
|
||||||
I feel that relocation is a very special case and will only apply to a few
|
I feel that relocation is a very special case and will only apply to a few
|
||||||
drivers, many of which can/will just re-init anyway. So the overhead of
|
drivers, many of which can/will just re-init anyway. So the overhead of
|
||||||
dealing with this might not be worth it.
|
dealing with this might not be worth it.
|
||||||
- Implemented a GPIO system, trying to keep it simple
|
- Implemented a GPIO system, trying to keep it simple
|
||||||
|
|
||||||
|
|
||||||
|
@ -903,12 +937,3 @@ change this to dynamic numbering, but then we would require some sort of
|
||||||
lookup service, perhaps searching by name. This is slightly less efficient
|
lookup service, perhaps searching by name. This is slightly less efficient
|
||||||
so has been left out for now. One small advantage of dynamic numbering might
|
so has been left out for now. One small advantage of dynamic numbering might
|
||||||
be fewer merge conflicts in uclass-id.h.
|
be fewer merge conflicts in uclass-id.h.
|
||||||
|
|
||||||
|
|
||||||
Simon Glass
|
|
||||||
sjg@chromium.org
|
|
||||||
April 2013
|
|
||||||
Updated 7-May-13
|
|
||||||
Updated 14-Jun-13
|
|
||||||
Updated 18-Oct-13
|
|
||||||
Updated 5-Nov-13
|
|
|
@ -1,15 +1,11 @@
|
||||||
|
.. SPDX-License-Identifier: GPL-2.0+
|
||||||
|
.. 2017-01-06, Mario Six <mario.six@gdsys.cc>
|
||||||
|
|
||||||
Pre-relocation device tree manipulation
|
Pre-relocation device tree manipulation
|
||||||
=======================================
|
=======================================
|
||||||
|
|
||||||
Contents:
|
Purpose
|
||||||
|
-------
|
||||||
1. Purpose
|
|
||||||
2. Implementation
|
|
||||||
3. Example
|
|
||||||
4. Work to be done
|
|
||||||
|
|
||||||
1. Purpose
|
|
||||||
----------
|
|
||||||
|
|
||||||
In certain markets, it is beneficial for manufacturers of embedded devices to
|
In certain markets, it is beneficial for manufacturers of embedded devices to
|
||||||
offer certain ranges of products, where the functionality of the devices within
|
offer certain ranges of products, where the functionality of the devices within
|
||||||
|
@ -61,14 +57,16 @@ we have the pre-relocation driver model at our disposal at this stage, which
|
||||||
means that we can query the hardware for the existence and variety of the
|
means that we can query the hardware for the existence and variety of the
|
||||||
components easily.
|
components easily.
|
||||||
|
|
||||||
2. Implementation
|
Implementation
|
||||||
-----------------
|
--------------
|
||||||
|
|
||||||
To take advantage of the pre-relocation device tree manipulation mechanism,
|
To take advantage of the pre-relocation device tree manipulation mechanism,
|
||||||
boards have to implement the function board_fix_fdt, which has the following
|
boards have to implement the function board_fix_fdt, which has the following
|
||||||
signature:
|
signature:
|
||||||
|
|
||||||
int board_fix_fdt (void *rw_fdt_blob)
|
.. code-block:: c
|
||||||
|
|
||||||
|
int board_fix_fdt (void *rw_fdt_blob)
|
||||||
|
|
||||||
The passed-in void pointer is a writeable pointer to the device tree, which can
|
The passed-in void pointer is a writeable pointer to the device tree, which can
|
||||||
be used to manipulate the device tree using e.g. functions from
|
be used to manipulate the device tree using e.g. functions from
|
||||||
|
@ -79,10 +77,10 @@ unrecoverably halt the boot process, as with any function from init_sequence_f
|
||||||
(in common/board_f.c).
|
(in common/board_f.c).
|
||||||
|
|
||||||
Furthermore, the Kconfig option OF_BOARD_FIXUP has to be set for the function
|
Furthermore, the Kconfig option OF_BOARD_FIXUP has to be set for the function
|
||||||
to be called:
|
to be called::
|
||||||
|
|
||||||
Device Tree Control
|
Device Tree Control
|
||||||
-> [*] Board-specific manipulation of Device Tree
|
-> [*] Board-specific manipulation of Device Tree
|
||||||
|
|
||||||
+----------------------------------------------------------+
|
+----------------------------------------------------------+
|
||||||
| WARNING: The actual manipulation of the device tree has |
|
| WARNING: The actual manipulation of the device tree has |
|
||||||
|
@ -97,23 +95,27 @@ Device Tree Control
|
||||||
Hence, the recommended layout of the board_fixup_fdt call-back function is the
|
Hence, the recommended layout of the board_fixup_fdt call-back function is the
|
||||||
following:
|
following:
|
||||||
|
|
||||||
int board_fix_fdt(void *rw_fdt_blob)
|
.. code-block:: c
|
||||||
{
|
|
||||||
/* Collect information about device's hardware and store them in e.g.
|
|
||||||
local variables */
|
|
||||||
|
|
||||||
/* Do device tree manipulation using the values previously collected */
|
int board_fix_fdt(void *rw_fdt_blob)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Collect information about device's hardware and store
|
||||||
|
* them in e.g. local variables
|
||||||
|
*/
|
||||||
|
|
||||||
/* Return 0 on successful manipulation and non-zero otherwise */
|
/* Do device tree manipulation using the values previously collected */
|
||||||
}
|
|
||||||
|
/* Return 0 on successful manipulation and non-zero otherwise */
|
||||||
|
}
|
||||||
|
|
||||||
If this convention is kept, both an "additive" approach, meaning that nodes for
|
If this convention is kept, both an "additive" approach, meaning that nodes for
|
||||||
detected components are added to the device tree, as well as a "subtractive"
|
detected components are added to the device tree, as well as a "subtractive"
|
||||||
approach, meaning that nodes for absent components are removed from the tree,
|
approach, meaning that nodes for absent components are removed from the tree,
|
||||||
as well as a combination of both approaches should work.
|
as well as a combination of both approaches should work.
|
||||||
|
|
||||||
3. Example
|
Example
|
||||||
----------
|
-------
|
||||||
|
|
||||||
The controlcenterdc board (board/gdsys/a38x/controlcenterdc.c) features a
|
The controlcenterdc board (board/gdsys/a38x/controlcenterdc.c) features a
|
||||||
board_fix_fdt function, in which six GPIO expanders (which might be present or
|
board_fix_fdt function, in which six GPIO expanders (which might be present or
|
||||||
|
@ -123,10 +125,8 @@ subsequently deactivated in the device tree if they are not present.
|
||||||
Note that the dm_i2c_simple_probe function does not use the device tree, hence
|
Note that the dm_i2c_simple_probe function does not use the device tree, hence
|
||||||
it is safe to call it after the tree has already been manipulated.
|
it is safe to call it after the tree has already been manipulated.
|
||||||
|
|
||||||
4. Work to be done
|
Work to be done
|
||||||
------------------
|
---------------
|
||||||
|
|
||||||
* The application of device tree overlay should be possible in board_fixup_fdt,
|
* The application of device tree overlay should be possible in board_fixup_fdt,
|
||||||
but has not been tested at this stage.
|
but has not been tested at this stage.
|
||||||
|
|
||||||
2017-01-06, Mario Six <mario.six@gdsys.cc>
|
|
154
doc/driver-model/fs_firmware_loader.rst
Normal file
154
doc/driver-model/fs_firmware_loader.rst
Normal file
|
@ -0,0 +1,154 @@
|
||||||
|
.. SPDX-License-Identifier: GPL-2.0+
|
||||||
|
.. Copyright (C) 2018-2019 Intel Corporation <www.intel.com>
|
||||||
|
|
||||||
|
File System Firmware Loader
|
||||||
|
===========================
|
||||||
|
|
||||||
|
This is file system firmware loader for U-Boot framework, which has very close
|
||||||
|
to some Linux Firmware API. For the details of Linux Firmware API, you can refer
|
||||||
|
to https://01.org/linuxgraphics/gfx-docs/drm/driver-api/firmware/index.html.
|
||||||
|
|
||||||
|
File system firmware loader can be used to load whatever(firmware, image,
|
||||||
|
and binary) from the storage device in file system format into target location
|
||||||
|
such as memory, then consumer driver such as FPGA driver can program FPGA image
|
||||||
|
from the target location into FPGA.
|
||||||
|
|
||||||
|
To enable firmware loader, CONFIG_FS_LOADER need to be set at
|
||||||
|
<board_name>_defconfig such as "CONFIG_FS_LOADER=y".
|
||||||
|
|
||||||
|
Firmware Loader API core features
|
||||||
|
---------------------------------
|
||||||
|
|
||||||
|
Firmware storage device described in device tree source
|
||||||
|
-------------------------------------------------------
|
||||||
|
For passing data like storage device phandle and partition where the
|
||||||
|
firmware loading from to the firmware loader driver, those data could be
|
||||||
|
defined in fs-loader node as shown in below:
|
||||||
|
|
||||||
|
Example for block device::
|
||||||
|
|
||||||
|
fs_loader0: fs-loader {
|
||||||
|
u-boot,dm-pre-reloc;
|
||||||
|
compatible = "u-boot,fs-loader";
|
||||||
|
phandlepart = <&mmc 1>;
|
||||||
|
};
|
||||||
|
|
||||||
|
<&mmc 1> means block storage device pointer and its partition.
|
||||||
|
|
||||||
|
Above example is a description for block storage, but for UBI storage
|
||||||
|
device, it can be described in FDT as shown in below:
|
||||||
|
|
||||||
|
Example for ubi::
|
||||||
|
|
||||||
|
fs_loader1: fs-loader {
|
||||||
|
u-boot,dm-pre-reloc;
|
||||||
|
compatible = "u-boot,fs-loader";
|
||||||
|
mtdpart = "UBI",
|
||||||
|
ubivol = "ubi0";
|
||||||
|
};
|
||||||
|
|
||||||
|
Then, firmware-loader property can be added with any device node, which
|
||||||
|
driver would use the firmware loader for loading.
|
||||||
|
|
||||||
|
The value of the firmware-loader property should be set with phandle
|
||||||
|
of the fs-loader node. For example::
|
||||||
|
|
||||||
|
firmware-loader = <&fs_loader0>;
|
||||||
|
|
||||||
|
If there are majority of devices using the same fs-loader node, then
|
||||||
|
firmware-loader property can be added under /chosen node instead of
|
||||||
|
adding to each of device node.
|
||||||
|
|
||||||
|
For example::
|
||||||
|
|
||||||
|
/{
|
||||||
|
chosen {
|
||||||
|
firmware-loader = <&fs_loader0>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
In each respective driver of devices using firmware loader, the firmware
|
||||||
|
loaded instance should be created by DT phandle.
|
||||||
|
|
||||||
|
For example of getting DT phandle from /chosen and creating instance:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
chosen_node = ofnode_path("/chosen");
|
||||||
|
if (!ofnode_valid(chosen_node)) {
|
||||||
|
debug("/chosen node was not found.\n");
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
phandle_p = ofnode_get_property(chosen_node, "firmware-loader", &size);
|
||||||
|
if (!phandle_p) {
|
||||||
|
debug("firmware-loader property was not found.\n");
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
phandle = fdt32_to_cpu(*phandle_p);
|
||||||
|
ret = uclass_get_device_by_phandle_id(UCLASS_FS_FIRMWARE_LOADER,
|
||||||
|
phandle, &dev);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
Firmware loader driver is also designed to support U-boot environment
|
||||||
|
variables, so all these data from FDT can be overwritten
|
||||||
|
through the U-boot environment variable during run time.
|
||||||
|
|
||||||
|
For examples:
|
||||||
|
|
||||||
|
storage_interface:
|
||||||
|
Storage interface, it can be "mmc", "usb", "sata" or "ubi".
|
||||||
|
fw_dev_part:
|
||||||
|
Block device number and its partition, it can be "0:1".
|
||||||
|
fw_ubi_mtdpart:
|
||||||
|
UBI device mtd partition, it can be "UBI".
|
||||||
|
fw_ubi_volume:
|
||||||
|
UBI volume, it can be "ubi0".
|
||||||
|
|
||||||
|
When above environment variables are set, environment values would be
|
||||||
|
used instead of data from FDT.
|
||||||
|
The benefit of this design allows user to change storage attribute data
|
||||||
|
at run time through U-boot console and saving the setting as default
|
||||||
|
environment values in the storage for the next power cycle, so no
|
||||||
|
compilation is required for both driver and FDT.
|
||||||
|
|
||||||
|
File system firmware Loader API
|
||||||
|
-------------------------------
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
int request_firmware_into_buf(struct udevice *dev,
|
||||||
|
const char *name,
|
||||||
|
void *buf, size_t size, u32 offset)
|
||||||
|
|
||||||
|
Load firmware into a previously allocated buffer
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
|
||||||
|
* struct udevice \*dev: An instance of a driver
|
||||||
|
* const char \*name: name of firmware file
|
||||||
|
* void \*buf: address of buffer to load firmware into
|
||||||
|
* size_t size: size of buffer
|
||||||
|
* u32 offset: offset of a file for start reading into buffer
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
size of total read
|
||||||
|
-ve when error
|
||||||
|
|
||||||
|
Description:
|
||||||
|
The firmware is loaded directly into the buffer pointed to by buf
|
||||||
|
|
||||||
|
Example of calling request_firmware_into_buf API after creating firmware loader
|
||||||
|
instance:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
ret = uclass_get_device_by_phandle_id(UCLASS_FS_FIRMWARE_LOADER,
|
||||||
|
phandle, &dev);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
request_firmware_into_buf(dev, filename, buffer_location, buffer_size,
|
||||||
|
offset_ofreading);
|
|
@ -1,148 +0,0 @@
|
||||||
# Copyright (C) 2018-2019 Intel Corporation <www.intel.com>
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: GPL-2.0
|
|
||||||
|
|
||||||
Introduction
|
|
||||||
============
|
|
||||||
|
|
||||||
This is file system firmware loader for U-Boot framework, which has very close
|
|
||||||
to some Linux Firmware API. For the details of Linux Firmware API, you can refer
|
|
||||||
to https://01.org/linuxgraphics/gfx-docs/drm/driver-api/firmware/index.html.
|
|
||||||
|
|
||||||
File system firmware loader can be used to load whatever(firmware, image,
|
|
||||||
and binary) from the storage device in file system format into target location
|
|
||||||
such as memory, then consumer driver such as FPGA driver can program FPGA image
|
|
||||||
from the target location into FPGA.
|
|
||||||
|
|
||||||
To enable firmware loader, CONFIG_FS_LOADER need to be set at
|
|
||||||
<board_name>_defconfig such as "CONFIG_FS_LOADER=y".
|
|
||||||
|
|
||||||
Firmware Loader API core features
|
|
||||||
---------------------------------
|
|
||||||
|
|
||||||
Firmware storage device described in device tree source
|
|
||||||
-------------------------------------------------------
|
|
||||||
For passing data like storage device phandle and partition where the
|
|
||||||
firmware loading from to the firmware loader driver, those data could be
|
|
||||||
defined in fs-loader node as shown in below:
|
|
||||||
|
|
||||||
Example for block device:
|
|
||||||
fs_loader0: fs-loader {
|
|
||||||
u-boot,dm-pre-reloc;
|
|
||||||
compatible = "u-boot,fs-loader";
|
|
||||||
phandlepart = <&mmc 1>;
|
|
||||||
};
|
|
||||||
|
|
||||||
<&mmc 1> means block storage device pointer and its partition.
|
|
||||||
|
|
||||||
Above example is a description for block storage, but for UBI storage
|
|
||||||
device, it can be described in FDT as shown in below:
|
|
||||||
|
|
||||||
Example for ubi:
|
|
||||||
fs_loader1: fs-loader {
|
|
||||||
u-boot,dm-pre-reloc;
|
|
||||||
compatible = "u-boot,fs-loader";
|
|
||||||
mtdpart = "UBI",
|
|
||||||
ubivol = "ubi0";
|
|
||||||
};
|
|
||||||
|
|
||||||
Then, firmware-loader property can be added with any device node, which
|
|
||||||
driver would use the firmware loader for loading.
|
|
||||||
|
|
||||||
The value of the firmware-loader property should be set with phandle
|
|
||||||
of the fs-loader node.
|
|
||||||
For example:
|
|
||||||
firmware-loader = <&fs_loader0>;
|
|
||||||
|
|
||||||
If there are majority of devices using the same fs-loader node, then
|
|
||||||
firmware-loader property can be added under /chosen node instead of
|
|
||||||
adding to each of device node.
|
|
||||||
|
|
||||||
For example:
|
|
||||||
/{
|
|
||||||
chosen {
|
|
||||||
firmware-loader = <&fs_loader0>;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
In each respective driver of devices using firmware loader, the firmware
|
|
||||||
loaded instance should be created by DT phandle.
|
|
||||||
|
|
||||||
For example of getting DT phandle from /chosen and creating instance:
|
|
||||||
chosen_node = ofnode_path("/chosen");
|
|
||||||
if (!ofnode_valid(chosen_node)) {
|
|
||||||
debug("/chosen node was not found.\n");
|
|
||||||
return -ENOENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
phandle_p = ofnode_get_property(chosen_node, "firmware-loader", &size);
|
|
||||||
if (!phandle_p) {
|
|
||||||
debug("firmware-loader property was not found.\n");
|
|
||||||
return -ENOENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
phandle = fdt32_to_cpu(*phandle_p);
|
|
||||||
ret = uclass_get_device_by_phandle_id(UCLASS_FS_FIRMWARE_LOADER,
|
|
||||||
phandle, &dev);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
Firmware loader driver is also designed to support U-boot environment
|
|
||||||
variables, so all these data from FDT can be overwritten
|
|
||||||
through the U-boot environment variable during run time.
|
|
||||||
For examples:
|
|
||||||
"storage_interface" - Storage interface, it can be "mmc", "usb", "sata"
|
|
||||||
or "ubi".
|
|
||||||
"fw_dev_part" - Block device number and its partition, it can be "0:1".
|
|
||||||
"fw_ubi_mtdpart" - UBI device mtd partition, it can be "UBI".
|
|
||||||
"fw_ubi_volume" - UBI volume, it can be "ubi0".
|
|
||||||
|
|
||||||
When above environment variables are set, environment values would be
|
|
||||||
used instead of data from FDT.
|
|
||||||
The benefit of this design allows user to change storage attribute data
|
|
||||||
at run time through U-boot console and saving the setting as default
|
|
||||||
environment values in the storage for the next power cycle, so no
|
|
||||||
compilation is required for both driver and FDT.
|
|
||||||
|
|
||||||
File system firmware Loader API
|
|
||||||
-------------------------------
|
|
||||||
|
|
||||||
int request_firmware_into_buf(struct udevice *dev,
|
|
||||||
const char *name,
|
|
||||||
void *buf, size_t size, u32 offset)
|
|
||||||
--------------------------------------------------------------------
|
|
||||||
Load firmware into a previously allocated buffer
|
|
||||||
|
|
||||||
Parameters:
|
|
||||||
|
|
||||||
1. struct udevice *dev
|
|
||||||
An instance of a driver
|
|
||||||
|
|
||||||
2. const char *name
|
|
||||||
name of firmware file
|
|
||||||
|
|
||||||
3. void *buf
|
|
||||||
address of buffer to load firmware into
|
|
||||||
|
|
||||||
4. size_t size
|
|
||||||
size of buffer
|
|
||||||
|
|
||||||
5. u32 offset
|
|
||||||
offset of a file for start reading into buffer
|
|
||||||
|
|
||||||
return:
|
|
||||||
size of total read
|
|
||||||
-ve when error
|
|
||||||
|
|
||||||
Description:
|
|
||||||
The firmware is loaded directly into the buffer pointed to by buf
|
|
||||||
|
|
||||||
Example of calling request_firmware_into_buf API after creating firmware loader
|
|
||||||
instance:
|
|
||||||
ret = uclass_get_device_by_phandle_id(UCLASS_FS_FIRMWARE_LOADER,
|
|
||||||
phandle, &dev);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
request_firmware_into_buf(dev, filename, buffer_location, buffer_size,
|
|
||||||
offset_ofreading);
|
|
|
@ -1,21 +1,23 @@
|
||||||
How to port a serial driver to driver model
|
.. SPDX-License-Identifier: GPL-2.0+
|
||||||
===========================================
|
|
||||||
|
How to port an I2C driver to driver model
|
||||||
|
=========================================
|
||||||
|
|
||||||
Over half of the I2C drivers have been converted as at November 2016. These
|
Over half of the I2C drivers have been converted as at November 2016. These
|
||||||
ones remain:
|
ones remain:
|
||||||
|
|
||||||
adi_i2c
|
* adi_i2c
|
||||||
davinci_i2c
|
* davinci_i2c
|
||||||
fti2c010
|
* fti2c010
|
||||||
ihs_i2c
|
* ihs_i2c
|
||||||
kona_i2c
|
* kona_i2c
|
||||||
lpc32xx_i2c
|
* lpc32xx_i2c
|
||||||
pca9564_i2c
|
* pca9564_i2c
|
||||||
ppc4xx_i2c
|
* ppc4xx_i2c
|
||||||
rcar_i2c
|
* rcar_i2c
|
||||||
sh_i2c
|
* sh_i2c
|
||||||
soft_i2c
|
* soft_i2c
|
||||||
zynq_i2c
|
* zynq_i2c
|
||||||
|
|
||||||
The deadline for this work is the end of June 2017. If no one steps
|
The deadline for this work is the end of June 2017. If no one steps
|
||||||
forward to convert these, at some point there may come a patch to remove them!
|
forward to convert these, at some point there may come a patch to remove them!
|
||||||
|
@ -27,14 +29,14 @@ model. Please feel free to update this file with your ideas and suggestions.
|
||||||
- Define CONFIG_DM_I2C for your board, vendor or architecture
|
- Define CONFIG_DM_I2C for your board, vendor or architecture
|
||||||
- If the board does not already use driver model, you need CONFIG_DM also
|
- If the board does not already use driver model, you need CONFIG_DM also
|
||||||
- Your board should then build, but will not work fully since there will be
|
- Your board should then build, but will not work fully since there will be
|
||||||
no I2C driver
|
no I2C driver
|
||||||
- Add the U_BOOT_DRIVER piece at the end (e.g. copy tegra_i2c.c for example)
|
- Add the U_BOOT_DRIVER piece at the end (e.g. copy tegra_i2c.c for example)
|
||||||
- Add a private struct for the driver data - avoid using static variables
|
- Add a private struct for the driver data - avoid using static variables
|
||||||
- Implement each of the driver methods, perhaps by calling your old methods
|
- Implement each of the driver methods, perhaps by calling your old methods
|
||||||
- You may need to adjust the function parameters so that the old and new
|
- You may need to adjust the function parameters so that the old and new
|
||||||
implementations can share most of the existing code
|
implementations can share most of the existing code
|
||||||
- If you convert all existing users of the driver, remove the pre-driver-model
|
- If you convert all existing users of the driver, remove the pre-driver-model
|
||||||
code
|
code
|
||||||
|
|
||||||
In terms of patches a conversion series typically has these patches:
|
In terms of patches a conversion series typically has these patches:
|
||||||
- clean up / prepare the driver for conversion
|
- clean up / prepare the driver for conversion
|
21
doc/driver-model/index.rst
Normal file
21
doc/driver-model/index.rst
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
.. SPDX-License-Identifier: GPL-2.0+
|
||||||
|
|
||||||
|
Driver Model
|
||||||
|
============
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 2
|
||||||
|
|
||||||
|
design
|
||||||
|
fdt-fixup
|
||||||
|
fs_firmware_loader
|
||||||
|
i2c-howto
|
||||||
|
livetree
|
||||||
|
migration
|
||||||
|
of-plat
|
||||||
|
pci-info
|
||||||
|
pmic-framework
|
||||||
|
remoteproc-framework
|
||||||
|
serial-howto
|
||||||
|
spi-howto
|
||||||
|
usb-info
|
|
@ -1,5 +1,8 @@
|
||||||
Driver Model with Live Device Tree
|
.. SPDX-License-Identifier: GPL-2.0+
|
||||||
==================================
|
.. sectionauthor:: Simon Glass <sjg@chromium.org>
|
||||||
|
|
||||||
|
Live Device Tree
|
||||||
|
================
|
||||||
|
|
||||||
|
|
||||||
Introduction
|
Introduction
|
||||||
|
@ -20,7 +23,7 @@ Motivation
|
||||||
The flat device tree has several advantages:
|
The flat device tree has several advantages:
|
||||||
|
|
||||||
- it is the format produced by the device tree compiler, so no translation
|
- it is the format produced by the device tree compiler, so no translation
|
||||||
is needed
|
is needed
|
||||||
|
|
||||||
- it is fairly compact (e.g. there is no need for pointers)
|
- it is fairly compact (e.g. there is no need for pointers)
|
||||||
|
|
||||||
|
@ -53,12 +56,12 @@ The 'ofnode' type provides this. An ofnode can point to either a flat tree
|
||||||
node (when the live tree node is not yet set up) or a livetree node. The
|
node (when the live tree node is not yet set up) or a livetree node. The
|
||||||
caller of an ofnode function does not need to worry about these details.
|
caller of an ofnode function does not need to worry about these details.
|
||||||
|
|
||||||
The main users of the information in a device tree are drivers. These have
|
The main users of the information in a device tree are drivers. These have
|
||||||
a 'struct udevice *' which is attached to a device tree node. Therefore it
|
a 'struct udevice \*' which is attached to a device tree node. Therefore it
|
||||||
makes sense to be able to read device tree properties using the
|
makes sense to be able to read device tree properties using the
|
||||||
'struct udevice *', rather than having to obtain the ofnode first.
|
'struct udevice \*', rather than having to obtain the ofnode first.
|
||||||
|
|
||||||
The 'dev_read_...()' interface provides this. It allows properties to be
|
The 'dev_read\_...()' interface provides this. It allows properties to be
|
||||||
easily read from the device tree using only a device pointer. Under the
|
easily read from the device tree using only a device pointer. Under the
|
||||||
hood it uses ofnode so it works with both flat and live device trees.
|
hood it uses ofnode so it works with both flat and live device trees.
|
||||||
|
|
||||||
|
@ -85,6 +88,8 @@ converted to use the dev_read_() interface.
|
||||||
|
|
||||||
For example, the old code may be like this:
|
For example, the old code may be like this:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
struct udevice *bus;
|
struct udevice *bus;
|
||||||
const void *blob = gd->fdt_blob;
|
const void *blob = gd->fdt_blob;
|
||||||
int node = dev_of_offset(bus);
|
int node = dev_of_offset(bus);
|
||||||
|
@ -94,17 +99,21 @@ For example, the old code may be like this:
|
||||||
|
|
||||||
The new code is:
|
The new code is:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
struct udevice *bus;
|
struct udevice *bus;
|
||||||
|
|
||||||
i2c_bus->regs = (struct i2c_ctlr *)dev_read_addr(dev);
|
i2c_bus->regs = (struct i2c_ctlr *)dev_read_addr(dev);
|
||||||
plat->frequency = dev_read_u32_default(bus, "spi-max-frequency", 500000);
|
plat->frequency = dev_read_u32_default(bus, "spi-max-frequency", 500000);
|
||||||
|
|
||||||
The dev_read_...() interface is more convenient and works with both the
|
The dev_read\_...() interface is more convenient and works with both the
|
||||||
flat and live device trees. See include/dm/read.h for a list of functions.
|
flat and live device trees. See include/dm/read.h for a list of functions.
|
||||||
|
|
||||||
Where properties must be read from sub-nodes or other nodes, you must fall
|
Where properties must be read from sub-nodes or other nodes, you must fall
|
||||||
back to using ofnode. For example, for old code like this:
|
back to using ofnode. For example, for old code like this:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
const void *blob = gd->fdt_blob;
|
const void *blob = gd->fdt_blob;
|
||||||
int subnode;
|
int subnode;
|
||||||
|
|
||||||
|
@ -115,6 +124,8 @@ back to using ofnode. For example, for old code like this:
|
||||||
|
|
||||||
you should use:
|
you should use:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
ofnode subnode;
|
ofnode subnode;
|
||||||
|
|
||||||
ofnode_for_each_subnode(subnode, dev_ofnode(dev)) {
|
ofnode_for_each_subnode(subnode, dev_ofnode(dev)) {
|
||||||
|
@ -128,8 +139,8 @@ Useful ofnode functions
|
||||||
|
|
||||||
The internal data structures of the livetree are defined in include/dm/of.h :
|
The internal data structures of the livetree are defined in include/dm/of.h :
|
||||||
|
|
||||||
struct device_node - holds information about a device tree node
|
:struct device_node: holds information about a device tree node
|
||||||
struct property - holds information about a property within a node
|
:struct property: holds information about a property within a node
|
||||||
|
|
||||||
Nodes have pointers to their first property, their parent, their first child
|
Nodes have pointers to their first property, their parent, their first child
|
||||||
and their sibling. This allows nodes to be linked together in a hierarchical
|
and their sibling. This allows nodes to be linked together in a hierarchical
|
||||||
|
@ -149,20 +160,29 @@ For example it is invalid to call ofnode_to_no() when a flat tree is being
|
||||||
used. Similarly it is not possible to call ofnode_to_offset() on a livetree
|
used. Similarly it is not possible to call ofnode_to_offset() on a livetree
|
||||||
node.
|
node.
|
||||||
|
|
||||||
ofnode_to_np() - converts ofnode to struct device_node *
|
ofnode_to_np():
|
||||||
ofnode_to_offset() - converts ofnode to offset
|
converts ofnode to struct device_node *
|
||||||
|
ofnode_to_offset():
|
||||||
|
converts ofnode to offset
|
||||||
|
|
||||||
no_to_ofnode() - converts node pointer to ofnode
|
no_to_ofnode():
|
||||||
offset_to_ofnode() - converts offset to ofnode
|
converts node pointer to ofnode
|
||||||
|
offset_to_ofnode():
|
||||||
|
converts offset to ofnode
|
||||||
|
|
||||||
|
|
||||||
Other useful functions:
|
Other useful functions:
|
||||||
|
|
||||||
of_live_active() returns true if livetree is in use, false if flat tree
|
of_live_active():
|
||||||
ofnode_valid() return true if a given node is valid
|
returns true if livetree is in use, false if flat tree
|
||||||
ofnode_is_np() returns true if a given node is a livetree node
|
ofnode_valid():
|
||||||
ofnode_equal() compares two ofnodes
|
return true if a given node is valid
|
||||||
ofnode_null() returns a null ofnode (for which ofnode_valid() returns false)
|
ofnode_is_np():
|
||||||
|
returns true if a given node is a livetree node
|
||||||
|
ofnode_equal():
|
||||||
|
compares two ofnodes
|
||||||
|
ofnode_null():
|
||||||
|
returns a null ofnode (for which ofnode_valid() returns false)
|
||||||
|
|
||||||
|
|
||||||
Phandles
|
Phandles
|
||||||
|
@ -199,13 +219,13 @@ the flat tree.
|
||||||
Internal implementation
|
Internal implementation
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
The dev_read_...() functions have two implementations. When
|
The dev_read\_...() functions have two implementations. When
|
||||||
CONFIG_DM_DEV_READ_INLINE is enabled, these functions simply call the ofnode
|
CONFIG_DM_DEV_READ_INLINE is enabled, these functions simply call the ofnode
|
||||||
functions directly. This is useful when livetree is not enabled. The ofnode
|
functions directly. This is useful when livetree is not enabled. The ofnode
|
||||||
functions call ofnode_is_np(node) which will always return false if livetree
|
functions call ofnode_is_np(node) which will always return false if livetree
|
||||||
is disabled, just falling back to flat tree code.
|
is disabled, just falling back to flat tree code.
|
||||||
|
|
||||||
This optimisation means that without livetree enabled, the dev_read_...() and
|
This optimisation means that without livetree enabled, the dev_read\_...() and
|
||||||
ofnode interfaces do not noticeably add to code size.
|
ofnode interfaces do not noticeably add to code size.
|
||||||
|
|
||||||
The CONFIG_DM_DEV_READ_INLINE option defaults to enabled when livetree is
|
The CONFIG_DM_DEV_READ_INLINE option defaults to enabled when livetree is
|
||||||
|
@ -225,7 +245,7 @@ Errors
|
||||||
|
|
||||||
With a flat device tree, libfdt errors are returned (e.g. -FDT_ERR_NOTFOUND).
|
With a flat device tree, libfdt errors are returned (e.g. -FDT_ERR_NOTFOUND).
|
||||||
For livetree normal 'errno' errors are returned (e.g. -ENOTFOUND). At present
|
For livetree normal 'errno' errors are returned (e.g. -ENOTFOUND). At present
|
||||||
the ofnode and dev_read_...() functions return either one or other type of
|
the ofnode and dev_read\_...() functions return either one or other type of
|
||||||
error. This is clearly not desirable. Once tests are added for all the
|
error. This is clearly not desirable. Once tests are added for all the
|
||||||
functions this can be tidied up.
|
functions this can be tidied up.
|
||||||
|
|
||||||
|
@ -236,23 +256,22 @@ Adding new access functions
|
||||||
Adding a new function for device-tree access involves the following steps:
|
Adding a new function for device-tree access involves the following steps:
|
||||||
|
|
||||||
- Add two dev_read() functions:
|
- Add two dev_read() functions:
|
||||||
- inline version in the read.h header file, which calls an ofnode
|
- inline version in the read.h header file, which calls an ofnode function
|
||||||
function
|
- standard version in the read.c file (or perhaps another file), which
|
||||||
- standard version in the read.c file (or perhaps another file), which
|
also calls an ofnode function
|
||||||
also calls an ofnode function
|
|
||||||
|
|
||||||
The implementations of these functions can be the same. The purpose
|
The implementations of these functions can be the same. The purpose
|
||||||
of the inline version is purely to reduce code size impact.
|
of the inline version is purely to reduce code size impact.
|
||||||
|
|
||||||
- Add an ofnode function. This should call ofnode_is_np() to work out
|
- Add an ofnode function. This should call ofnode_is_np() to work out
|
||||||
whether a livetree or flat tree is used. For the livetree it should
|
whether a livetree or flat tree is used. For the livetree it should
|
||||||
call an of_...() function. For the flat tree it should call an
|
call an of\_...() function. For the flat tree it should call an
|
||||||
fdt_...() function. The livetree version will be optimised out at
|
fdt\_...() function. The livetree version will be optimised out at
|
||||||
compile time if livetree is not enabled.
|
compile time if livetree is not enabled.
|
||||||
|
|
||||||
- Add an of_...() function for the livetree implementation. If a similar
|
- Add an of\_...() function for the livetree implementation. If a similar
|
||||||
function is available in Linux, the implementation should be taken
|
function is available in Linux, the implementation should be taken
|
||||||
from there and modified as little as possible (generally not at all).
|
from there and modified as little as possible (generally not at all).
|
||||||
|
|
||||||
|
|
||||||
Future work
|
Future work
|
||||||
|
@ -265,8 +284,3 @@ of work to do to flesh this out:
|
||||||
- support for livetree modification
|
- support for livetree modification
|
||||||
- addition of more access functions as needed
|
- addition of more access functions as needed
|
||||||
- support for livetree in SPL and before relocation (if desired)
|
- support for livetree in SPL and before relocation (if desired)
|
||||||
|
|
||||||
|
|
||||||
--
|
|
||||||
Simon Glass <sjg@chromium.org>
|
|
||||||
5-Aug-17
|
|
|
@ -1,5 +1,7 @@
|
||||||
|
.. SPDX-License-Identifier: GPL-2.0+
|
||||||
|
|
||||||
Migration Schedule
|
Migration Schedule
|
||||||
====================
|
==================
|
||||||
|
|
||||||
U-Boot has been migrating to a new driver model since its introduction in
|
U-Boot has been migrating to a new driver model since its introduction in
|
||||||
2014. This file describes the schedule for deprecation of pre-driver-model
|
2014. This file describes the schedule for deprecation of pre-driver-model
|
||||||
|
@ -8,8 +10,8 @@ features.
|
||||||
CONFIG_DM_MMC
|
CONFIG_DM_MMC
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
Status: In progress
|
* Status: In progress
|
||||||
Deadline: 2019.04
|
* Deadline: 2019.04
|
||||||
|
|
||||||
The subsystem itself has been converted and maintainers should submit patches
|
The subsystem itself has been converted and maintainers should submit patches
|
||||||
switching over to using CONFIG_DM_MMC and other base driver model options in
|
switching over to using CONFIG_DM_MMC and other base driver model options in
|
||||||
|
@ -18,8 +20,8 @@ time for inclusion in the 2019.04 rerelease.
|
||||||
CONFIG_DM_USB
|
CONFIG_DM_USB
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
Status: In progress
|
* Status: In progress
|
||||||
Deadline: 2019.07
|
* Deadline: 2019.07
|
||||||
|
|
||||||
The subsystem itself has been converted along with many of the host controller
|
The subsystem itself has been converted along with many of the host controller
|
||||||
and maintainers should submit patches switching over to using CONFIG_DM_USB and
|
and maintainers should submit patches switching over to using CONFIG_DM_USB and
|
||||||
|
@ -28,8 +30,8 @@ other base driver model options in time for inclusion in the 2019.07 rerelease.
|
||||||
CONFIG_SATA
|
CONFIG_SATA
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
Status: In progress
|
* Status: In progress
|
||||||
Deadline: 2019.07
|
* Deadline: 2019.07
|
||||||
|
|
||||||
The subsystem itself has been converted along with many of the host controller
|
The subsystem itself has been converted along with many of the host controller
|
||||||
and maintainers should submit patches switching over to using CONFIG_AHCI and
|
and maintainers should submit patches switching over to using CONFIG_AHCI and
|
||||||
|
@ -38,8 +40,8 @@ other base driver model options in time for inclusion in the 2019.07 rerelease.
|
||||||
CONFIG_BLK
|
CONFIG_BLK
|
||||||
----------
|
----------
|
||||||
|
|
||||||
Status: In progress
|
* Status: In progress
|
||||||
Deadline: 2019.07
|
* Deadline: 2019.07
|
||||||
|
|
||||||
In concert with maintainers migrating their block device usage to the
|
In concert with maintainers migrating their block device usage to the
|
||||||
appropriate DM driver, CONFIG_BLK needs to be set as well. The final deadline
|
appropriate DM driver, CONFIG_BLK needs to be set as well. The final deadline
|
||||||
|
@ -48,14 +50,14 @@ subsystems. At this point we will be able to audit and correct the logic in
|
||||||
Kconfig around using CONFIG_PARTITIONS and CONFIG_HAVE_BLOCK_DEVICE and make
|
Kconfig around using CONFIG_PARTITIONS and CONFIG_HAVE_BLOCK_DEVICE and make
|
||||||
use of CONFIG_BLK / CONFIG_SPL_BLK as needed.
|
use of CONFIG_BLK / CONFIG_SPL_BLK as needed.
|
||||||
|
|
||||||
CONFIG_DM_SPI
|
CONFIG_DM_SPI / CONFIG_DM_SPI_FLASH
|
||||||
CONFIG_DM_SPI_FLASH
|
-----------------------------------
|
||||||
-------------------
|
|
||||||
|
|
||||||
Board Maintainers should submit the patches for enabling DM_SPI and DM_SPI_FLASH
|
Board Maintainers should submit the patches for enabling DM_SPI and DM_SPI_FLASH
|
||||||
to move the migration with in the deadline.
|
to move the migration with in the deadline.
|
||||||
|
|
||||||
No dm conversion yet:
|
No dm conversion yet::
|
||||||
|
|
||||||
drivers/spi/cf_spi.c
|
drivers/spi/cf_spi.c
|
||||||
drivers/spi/fsl_espi.c
|
drivers/spi/fsl_espi.c
|
||||||
drivers/spi/lpc32xx_ssp.c
|
drivers/spi/lpc32xx_ssp.c
|
||||||
|
@ -63,10 +65,11 @@ No dm conversion yet:
|
||||||
drivers/spi/sh_spi.c
|
drivers/spi/sh_spi.c
|
||||||
drivers/spi/soft_spi_legacy.c
|
drivers/spi/soft_spi_legacy.c
|
||||||
|
|
||||||
Status: In progress
|
* Status: In progress
|
||||||
Deadline: 2019.04
|
* Deadline: 2019.04
|
||||||
|
|
||||||
|
Partially converted::
|
||||||
|
|
||||||
Partially converted:
|
|
||||||
drivers/spi/davinci_spi.c
|
drivers/spi/davinci_spi.c
|
||||||
drivers/spi/fsl_dspi.c
|
drivers/spi/fsl_dspi.c
|
||||||
drivers/spi/kirkwood_spi.c
|
drivers/spi/kirkwood_spi.c
|
||||||
|
@ -74,13 +77,8 @@ Partially converted:
|
||||||
drivers/spi/omap3_spi.c
|
drivers/spi/omap3_spi.c
|
||||||
drivers/spi/sh_qspi.c
|
drivers/spi/sh_qspi.c
|
||||||
|
|
||||||
Status: In progress
|
* Status: In progress
|
||||||
Deadline: 2019.07
|
* Deadline: 2019.07
|
||||||
|
|
||||||
--
|
|
||||||
Jagan Teki <jagan@openedev.com>
|
|
||||||
12/24/2018
|
|
||||||
03/14/2018
|
|
||||||
|
|
||||||
|
|
||||||
CONFIG_DM_PCI
|
CONFIG_DM_PCI
|
|
@ -1,5 +1,7 @@
|
||||||
Driver Model Compiled-in Device Tree / Platform Data
|
.. SPDX-License-Identifier: GPL-2.0+
|
||||||
====================================================
|
|
||||||
|
Compiled-in Device Tree / Platform Data
|
||||||
|
=======================================
|
||||||
|
|
||||||
|
|
||||||
Introduction
|
Introduction
|
||||||
|
@ -40,36 +42,36 @@ There are many problems with this features. It should only be used when
|
||||||
strictly necessary. Notable problems include:
|
strictly necessary. Notable problems include:
|
||||||
|
|
||||||
- Device tree does not describe data types. But the C code must define a
|
- Device tree does not describe data types. But the C code must define a
|
||||||
type for each property. These are guessed using heuristics which
|
type for each property. These are guessed using heuristics which
|
||||||
are wrong in several fairly common cases. For example an 8-byte value
|
are wrong in several fairly common cases. For example an 8-byte value
|
||||||
is considered to be a 2-item integer array, and is byte-swapped. A
|
is considered to be a 2-item integer array, and is byte-swapped. A
|
||||||
boolean value that is not present means 'false', but cannot be
|
boolean value that is not present means 'false', but cannot be
|
||||||
included in the structures since there is generally no mention of it
|
included in the structures since there is generally no mention of it
|
||||||
in the device tree file.
|
in the device tree file.
|
||||||
|
|
||||||
- Naming of nodes and properties is automatic. This means that they follow
|
- Naming of nodes and properties is automatic. This means that they follow
|
||||||
the naming in the device tree, which may result in C identifiers that
|
the naming in the device tree, which may result in C identifiers that
|
||||||
look a bit strange.
|
look a bit strange.
|
||||||
|
|
||||||
- It is not possible to find a value given a property name. Code must use
|
- It is not possible to find a value given a property name. Code must use
|
||||||
the associated C member variable directly in the code. This makes
|
the associated C member variable directly in the code. This makes
|
||||||
the code less robust in the face of device-tree changes. It also
|
the code less robust in the face of device-tree changes. It also
|
||||||
makes it very unlikely that your driver code will be useful for more
|
makes it very unlikely that your driver code will be useful for more
|
||||||
than one SoC. Even if the code is common, each SoC will end up with
|
than one SoC. Even if the code is common, each SoC will end up with
|
||||||
a different C struct name, and a likely a different format for the
|
a different C struct name, and a likely a different format for the
|
||||||
platform data.
|
platform data.
|
||||||
|
|
||||||
- The platform data is provided to drivers as a C structure. The driver
|
- The platform data is provided to drivers as a C structure. The driver
|
||||||
must use the same structure to access the data. Since a driver
|
must use the same structure to access the data. Since a driver
|
||||||
normally also supports device tree it must use #ifdef to separate
|
normally also supports device tree it must use #ifdef to separate
|
||||||
out this code, since the structures are only available in SPL.
|
out this code, since the structures are only available in SPL.
|
||||||
|
|
||||||
- Correct relations between nodes are not implemented. This means that
|
- Correct relations between nodes are not implemented. This means that
|
||||||
parent/child relations (like bus device iteration) do not work yet.
|
parent/child relations (like bus device iteration) do not work yet.
|
||||||
Some phandles (those that are recognised as such) are converted into
|
Some phandles (those that are recognised as such) are converted into
|
||||||
a pointer to platform data. This pointer can potentially be used to
|
a pointer to platform data. This pointer can potentially be used to
|
||||||
access the referenced device (by searching for the pointer value).
|
access the referenced device (by searching for the pointer value).
|
||||||
This feature is not yet implemented, however.
|
This feature is not yet implemented, however.
|
||||||
|
|
||||||
|
|
||||||
How it works
|
How it works
|
||||||
|
@ -78,30 +80,34 @@ How it works
|
||||||
The feature is enabled by CONFIG OF_PLATDATA. This is only available in
|
The feature is enabled by CONFIG OF_PLATDATA. This is only available in
|
||||||
SPL/TPL and should be tested with:
|
SPL/TPL and should be tested with:
|
||||||
|
|
||||||
#if CONFIG_IS_ENABLED(OF_PLATDATA)
|
.. code-block:: c
|
||||||
|
|
||||||
|
#if CONFIG_IS_ENABLED(OF_PLATDATA)
|
||||||
|
|
||||||
A new tool called 'dtoc' converts a device tree file either into a set of
|
A new tool called 'dtoc' converts a device tree file either into a set of
|
||||||
struct declarations, one for each compatible node, and a set of
|
struct declarations, one for each compatible node, and a set of
|
||||||
U_BOOT_DEVICE() declarations along with the actual platform data for each
|
U_BOOT_DEVICE() declarations along with the actual platform data for each
|
||||||
device. As an example, consider this MMC node:
|
device. As an example, consider this MMC node:
|
||||||
|
|
||||||
sdmmc: dwmmc@ff0c0000 {
|
.. code-block:: none
|
||||||
compatible = "rockchip,rk3288-dw-mshc";
|
|
||||||
clock-freq-min-max = <400000 150000000>;
|
sdmmc: dwmmc@ff0c0000 {
|
||||||
clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>,
|
compatible = "rockchip,rk3288-dw-mshc";
|
||||||
<&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>;
|
clock-freq-min-max = <400000 150000000>;
|
||||||
clock-names = "biu", "ciu", "ciu_drv", "ciu_sample";
|
clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>,
|
||||||
fifo-depth = <0x100>;
|
<&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>;
|
||||||
interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
|
clock-names = "biu", "ciu", "ciu_drv", "ciu_sample";
|
||||||
reg = <0xff0c0000 0x4000>;
|
fifo-depth = <0x100>;
|
||||||
bus-width = <4>;
|
interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
cap-mmc-highspeed;
|
reg = <0xff0c0000 0x4000>;
|
||||||
cap-sd-highspeed;
|
bus-width = <4>;
|
||||||
card-detect-delay = <200>;
|
cap-mmc-highspeed;
|
||||||
disable-wp;
|
cap-sd-highspeed;
|
||||||
num-slots = <1>;
|
card-detect-delay = <200>;
|
||||||
pinctrl-names = "default";
|
disable-wp;
|
||||||
pinctrl-0 = <&sdmmc_clk>, <&sdmmc_cmd>, <&sdmmc_cd>, <&sdmmc_bus4>;
|
num-slots = <1>;
|
||||||
|
pinctrl-names = "default";
|
||||||
|
pinctrl-0 = <&sdmmc_clk>, <&sdmmc_cmd>, <&sdmmc_cd>, <&sdmmc_bus4>;
|
||||||
vmmc-supply = <&vcc_sd>;
|
vmmc-supply = <&vcc_sd>;
|
||||||
status = "okay";
|
status = "okay";
|
||||||
u-boot,dm-pre-reloc;
|
u-boot,dm-pre-reloc;
|
||||||
|
@ -112,52 +118,59 @@ Some of these properties are dropped by U-Boot under control of the
|
||||||
CONFIG_OF_SPL_REMOVE_PROPS option. The rest are processed. This will produce
|
CONFIG_OF_SPL_REMOVE_PROPS option. The rest are processed. This will produce
|
||||||
the following C struct declaration:
|
the following C struct declaration:
|
||||||
|
|
||||||
struct dtd_rockchip_rk3288_dw_mshc {
|
.. code-block:: c
|
||||||
fdt32_t bus_width;
|
|
||||||
bool cap_mmc_highspeed;
|
struct dtd_rockchip_rk3288_dw_mshc {
|
||||||
bool cap_sd_highspeed;
|
fdt32_t bus_width;
|
||||||
fdt32_t card_detect_delay;
|
bool cap_mmc_highspeed;
|
||||||
fdt32_t clock_freq_min_max[2];
|
bool cap_sd_highspeed;
|
||||||
struct phandle_1_arg clocks[4];
|
fdt32_t card_detect_delay;
|
||||||
bool disable_wp;
|
fdt32_t clock_freq_min_max[2];
|
||||||
fdt32_t fifo_depth;
|
struct phandle_1_arg clocks[4];
|
||||||
fdt32_t interrupts[3];
|
bool disable_wp;
|
||||||
fdt32_t num_slots;
|
fdt32_t fifo_depth;
|
||||||
fdt32_t reg[2];
|
fdt32_t interrupts[3];
|
||||||
fdt32_t vmmc_supply;
|
fdt32_t num_slots;
|
||||||
};
|
fdt32_t reg[2];
|
||||||
|
fdt32_t vmmc_supply;
|
||||||
|
};
|
||||||
|
|
||||||
and the following device declaration:
|
and the following device declaration:
|
||||||
|
|
||||||
static struct dtd_rockchip_rk3288_dw_mshc dtv_dwmmc_at_ff0c0000 = {
|
.. code-block:: c
|
||||||
.fifo_depth = 0x100,
|
|
||||||
.cap_sd_highspeed = true,
|
static struct dtd_rockchip_rk3288_dw_mshc dtv_dwmmc_at_ff0c0000 = {
|
||||||
.interrupts = {0x0, 0x20, 0x4},
|
.fifo_depth = 0x100,
|
||||||
.clock_freq_min_max = {0x61a80, 0x8f0d180},
|
.cap_sd_highspeed = true,
|
||||||
.vmmc_supply = 0xb,
|
.interrupts = {0x0, 0x20, 0x4},
|
||||||
.num_slots = 0x1,
|
.clock_freq_min_max = {0x61a80, 0x8f0d180},
|
||||||
.clocks = {{&dtv_clock_controller_at_ff760000, 456},
|
.vmmc_supply = 0xb,
|
||||||
{&dtv_clock_controller_at_ff760000, 68},
|
.num_slots = 0x1,
|
||||||
{&dtv_clock_controller_at_ff760000, 114},
|
.clocks = {{&dtv_clock_controller_at_ff760000, 456},
|
||||||
{&dtv_clock_controller_at_ff760000, 118}},
|
{&dtv_clock_controller_at_ff760000, 68},
|
||||||
.cap_mmc_highspeed = true,
|
{&dtv_clock_controller_at_ff760000, 114},
|
||||||
.disable_wp = true,
|
{&dtv_clock_controller_at_ff760000, 118}},
|
||||||
.bus_width = 0x4,
|
.cap_mmc_highspeed = true,
|
||||||
.u_boot_dm_pre_reloc = true,
|
.disable_wp = true,
|
||||||
.reg = {0xff0c0000, 0x4000},
|
.bus_width = 0x4,
|
||||||
.card_detect_delay = 0xc8,
|
.u_boot_dm_pre_reloc = true,
|
||||||
};
|
.reg = {0xff0c0000, 0x4000},
|
||||||
U_BOOT_DEVICE(dwmmc_at_ff0c0000) = {
|
.card_detect_delay = 0xc8,
|
||||||
.name = "rockchip_rk3288_dw_mshc",
|
};
|
||||||
.platdata = &dtv_dwmmc_at_ff0c0000,
|
|
||||||
.platdata_size = sizeof(dtv_dwmmc_at_ff0c0000),
|
U_BOOT_DEVICE(dwmmc_at_ff0c0000) = {
|
||||||
};
|
.name = "rockchip_rk3288_dw_mshc",
|
||||||
|
.platdata = &dtv_dwmmc_at_ff0c0000,
|
||||||
|
.platdata_size = sizeof(dtv_dwmmc_at_ff0c0000),
|
||||||
|
};
|
||||||
|
|
||||||
The device is then instantiated at run-time and the platform data can be
|
The device is then instantiated at run-time and the platform data can be
|
||||||
accessed using:
|
accessed using:
|
||||||
|
|
||||||
struct udevice *dev;
|
.. code-block:: c
|
||||||
struct dtd_rockchip_rk3288_dw_mshc *plat = dev_get_platdata(dev);
|
|
||||||
|
struct udevice *dev;
|
||||||
|
struct dtd_rockchip_rk3288_dw_mshc *plat = dev_get_platdata(dev);
|
||||||
|
|
||||||
This avoids the code overhead of converting the device tree data to
|
This avoids the code overhead of converting the device tree data to
|
||||||
platform data in the driver. The ofdata_to_platdata() method should
|
platform data in the driver. The ofdata_to_platdata() method should
|
||||||
|
@ -173,7 +186,9 @@ each 'compatible' string.
|
||||||
Where a node has multiple compatible strings, a #define is used to make them
|
Where a node has multiple compatible strings, a #define is used to make them
|
||||||
equivalent, e.g.:
|
equivalent, e.g.:
|
||||||
|
|
||||||
#define dtd_rockchip_rk3299_dw_mshc dtd_rockchip_rk3288_dw_mshc
|
.. code-block:: c
|
||||||
|
|
||||||
|
#define dtd_rockchip_rk3299_dw_mshc dtd_rockchip_rk3288_dw_mshc
|
||||||
|
|
||||||
|
|
||||||
Converting of-platdata to a useful form
|
Converting of-platdata to a useful form
|
||||||
|
@ -204,6 +219,8 @@ ofdata_to_platdata() method and wrapped with #if.
|
||||||
|
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
#include <dt-structs.h>
|
#include <dt-structs.h>
|
||||||
|
|
||||||
struct mmc_platdata {
|
struct mmc_platdata {
|
||||||
|
@ -313,12 +330,12 @@ This is an implementation of an idea by Tom Rini <trini@konsulko.com>.
|
||||||
Future work
|
Future work
|
||||||
-----------
|
-----------
|
||||||
- Consider programmatically reading binding files instead of device tree
|
- Consider programmatically reading binding files instead of device tree
|
||||||
contents
|
contents
|
||||||
- Complete the phandle feature
|
- Complete the phandle feature
|
||||||
- Move to using a full Python libfdt module
|
- Move to using a full Python libfdt module
|
||||||
|
|
||||||
--
|
|
||||||
Simon Glass <sjg@chromium.org>
|
.. Simon Glass <sjg@chromium.org>
|
||||||
Google, Inc
|
.. Google, Inc
|
||||||
6/6/16
|
.. 6/6/16
|
||||||
Updated Independence Day 2016
|
.. Updated Independence Day 2016
|
|
@ -1,3 +1,5 @@
|
||||||
|
.. SPDX-License-Identifier: GPL-2.0+
|
||||||
|
|
||||||
PCI with Driver Model
|
PCI with Driver Model
|
||||||
=====================
|
=====================
|
||||||
|
|
||||||
|
@ -7,8 +9,7 @@ How busses are scanned
|
||||||
Any config read will end up at pci_read_config(). This uses
|
Any config read will end up at pci_read_config(). This uses
|
||||||
uclass_get_device_by_seq() to get the PCI bus for a particular bus number.
|
uclass_get_device_by_seq() to get the PCI bus for a particular bus number.
|
||||||
Bus number 0 will need to be requested first, and the alias in the device
|
Bus number 0 will need to be requested first, and the alias in the device
|
||||||
tree file will point to the correct device:
|
tree file will point to the correct device::
|
||||||
|
|
||||||
|
|
||||||
aliases {
|
aliases {
|
||||||
pci0 = &pci;
|
pci0 = &pci;
|
||||||
|
@ -45,7 +46,7 @@ present, matching on it takes precedence over PCI IDs and PCI classes.
|
||||||
Note we must describe PCI devices with the same bus hierarchy as the
|
Note we must describe PCI devices with the same bus hierarchy as the
|
||||||
hardware, otherwise driver model cannot detect the correct parent/children
|
hardware, otherwise driver model cannot detect the correct parent/children
|
||||||
relationship during PCI bus enumeration thus PCI devices won't be bound to
|
relationship during PCI bus enumeration thus PCI devices won't be bound to
|
||||||
their drivers accordingly. A working example like below:
|
their drivers accordingly. A working example like below::
|
||||||
|
|
||||||
pci {
|
pci {
|
||||||
#address-cells = <3>;
|
#address-cells = <3>;
|
||||||
|
@ -113,7 +114,7 @@ Sandbox
|
||||||
|
|
||||||
With sandbox we need a device emulator for each device on the bus since there
|
With sandbox we need a device emulator for each device on the bus since there
|
||||||
is no real PCI bus. This works by looking in the device tree node for a
|
is no real PCI bus. This works by looking in the device tree node for a
|
||||||
driver. For example:
|
driver. For example::
|
||||||
|
|
||||||
|
|
||||||
pci@1f,0 {
|
pci@1f,0 {
|
||||||
|
@ -129,11 +130,11 @@ Note that the first cell in the 'reg' value is the bus/device/function. See
|
||||||
PCI_BDF() for the encoding (it is also specified in the IEEE Std 1275-1994
|
PCI_BDF() for the encoding (it is also specified in the IEEE Std 1275-1994
|
||||||
PCI bus binding document, v2.1)
|
PCI bus binding document, v2.1)
|
||||||
|
|
||||||
When this bus is scanned we will end up with something like this:
|
When this bus is scanned we will end up with something like this::
|
||||||
|
|
||||||
`- * pci-controller @ 05c660c8, 0
|
`- * pci-controller @ 05c660c8, 0
|
||||||
`- pci@1f,0 @ 05c661c8, 63488
|
`- pci@1f,0 @ 05c661c8, 63488
|
||||||
`- emul@1f,0 @ 05c662c8
|
`- emul@1f,0 @ 05c662c8
|
||||||
|
|
||||||
When accesses go to the pci@1f,0 device they are forwarded to its child, the
|
When accesses go to the pci@1f,0 device they are forwarded to its child, the
|
||||||
emulator.
|
emulator.
|
||||||
|
@ -144,6 +145,8 @@ eliminating the need to provide any device tree node under the host controller
|
||||||
node. It is required a "sandbox,dev-info" property must be provided in the
|
node. It is required a "sandbox,dev-info" property must be provided in the
|
||||||
host controller node for this functionality to work.
|
host controller node for this functionality to work.
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
pci1: pci-controller1 {
|
pci1: pci-controller1 {
|
||||||
compatible = "sandbox,pci";
|
compatible = "sandbox,pci";
|
||||||
...
|
...
|
||||||
|
@ -156,7 +159,7 @@ Each dynamic PCI device is encoded as 4 cells a group. The first and second
|
||||||
cells are PCI device number and function number respectively. The third and
|
cells are PCI device number and function number respectively. The third and
|
||||||
fourth cells are PCI vendor ID and device ID respectively.
|
fourth cells are PCI vendor ID and device ID respectively.
|
||||||
|
|
||||||
When this bus is scanned we will end up with something like this:
|
When this bus is scanned we will end up with something like this::
|
||||||
|
|
||||||
pci [ + ] pci_sandbo |-- pci-controller1
|
pci [ + ] pci_sandbo |-- pci-controller1
|
||||||
pci_emul [ ] sandbox_sw | |-- sandbox_swap_case_emul
|
pci_emul [ ] sandbox_sw | |-- sandbox_swap_case_emul
|
|
@ -1,63 +1,59 @@
|
||||||
#
|
.. SPDX-License-Identifier: GPL-2.0+
|
||||||
# (C) Copyright 2014-2015 Samsung Electronics
|
.. (C) Copyright 2014-2015 Samsung Electronics
|
||||||
# Przemyslaw Marczak <p.marczak@samsung.com>
|
.. sectionauthor:: Przemyslaw Marczak <p.marczak@samsung.com>
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: GPL-2.0+
|
|
||||||
#
|
|
||||||
|
|
||||||
PMIC framework based on Driver Model
|
PMIC framework based on Driver Model
|
||||||
====================================
|
====================================
|
||||||
TOC:
|
|
||||||
1. Introduction
|
|
||||||
2. How does it work
|
|
||||||
3. Pmic uclass
|
|
||||||
4. Regulator uclass
|
|
||||||
|
|
||||||
1. Introduction
|
Introduction
|
||||||
===============
|
------------
|
||||||
This is an introduction to driver-model multi uclass PMIC IC's support.
|
This is an introduction to driver-model multi uclass PMIC IC's support.
|
||||||
At present it's based on two uclass types:
|
At present it's based on two uclass types:
|
||||||
- UCLASS_PMIC - basic uclass type for PMIC I/O, which provides common
|
|
||||||
read/write interface.
|
UCLASS_PMIC:
|
||||||
- UCLASS_REGULATOR - additional uclass type for specific PMIC features,
|
basic uclass type for PMIC I/O, which provides common
|
||||||
which are Voltage/Current regulators.
|
read/write interface.
|
||||||
|
UCLASS_REGULATOR:
|
||||||
|
additional uclass type for specific PMIC features, which are
|
||||||
|
Voltage/Current regulators.
|
||||||
|
|
||||||
New files:
|
New files:
|
||||||
|
|
||||||
UCLASS_PMIC:
|
UCLASS_PMIC:
|
||||||
- drivers/power/pmic/pmic-uclass.c
|
- drivers/power/pmic/pmic-uclass.c
|
||||||
- include/power/pmic.h
|
- include/power/pmic.h
|
||||||
UCLASS_REGULATOR:
|
UCLASS_REGULATOR:
|
||||||
- drivers/power/regulator/regulator-uclass.c
|
- drivers/power/regulator/regulator-uclass.c
|
||||||
- include/power/regulator.h
|
- include/power/regulator.h
|
||||||
|
|
||||||
Commands:
|
Commands:
|
||||||
- common/cmd_pmic.c
|
- common/cmd_pmic.c
|
||||||
- common/cmd_regulator.c
|
- common/cmd_regulator.c
|
||||||
|
|
||||||
2. How doees it work
|
How doees it work
|
||||||
====================
|
-----------------
|
||||||
The Power Management Integrated Circuits (PMIC) are used in embedded systems
|
The Power Management Integrated Circuits (PMIC) are used in embedded systems
|
||||||
to provide stable, precise and specific voltage power source with over-voltage
|
to provide stable, precise and specific voltage power source with over-voltage
|
||||||
and thermal protection circuits.
|
and thermal protection circuits.
|
||||||
|
|
||||||
The single PMIC can provide various functions by single or multiple interfaces,
|
The single PMIC can provide various functions by single or multiple interfaces,
|
||||||
like in the example below.
|
like in the example below::
|
||||||
|
|
||||||
-- SoC
|
-- SoC
|
||||||
|
|
|
|
||||||
| ______________________________________
|
| ______________________________________
|
||||||
| BUS 0 | Multi interface PMIC IC |--> LDO out 1
|
| BUS 0 | Multi interface PMIC IC |--> LDO out 1
|
||||||
| e.g.I2C0 | |--> LDO out N
|
| e.g.I2C0 | |--> LDO out N
|
||||||
|-----------|---- PMIC device 0 (READ/WRITE ops) |
|
|-----------|---- PMIC device 0 (READ/WRITE ops) |
|
||||||
| or SPI0 | |_ REGULATOR device (ldo/... ops) |--> BUCK out 1
|
| or SPI0 | |_ REGULATOR device (ldo/... ops) |--> BUCK out 1
|
||||||
| | |_ CHARGER device (charger ops) |--> BUCK out M
|
| | |_ CHARGER device (charger ops) |--> BUCK out M
|
||||||
| | |_ MUIC device (microUSB con ops) |
|
| | |_ MUIC device (microUSB con ops) |
|
||||||
| BUS 1 | |_ ... |---> BATTERY
|
| BUS 1 | |_ ... |---> BATTERY
|
||||||
| e.g.I2C1 | |
|
| e.g.I2C1 | |
|
||||||
|-----------|---- PMIC device 1 (READ/WRITE ops) |---> USB in 1
|
|-----------|---- PMIC device 1 (READ/WRITE ops) |---> USB in 1
|
||||||
. or SPI1 | |_ RTC device (rtc ops) |---> USB in 2
|
. or SPI1 | |_ RTC device (rtc ops) |---> USB in 2
|
||||||
. |______________________________________|---> USB out
|
. |______________________________________|---> USB out
|
||||||
.
|
.
|
||||||
|
|
||||||
Since U-Boot provides driver model features for I2C and SPI bus drivers,
|
Since U-Boot provides driver model features for I2C and SPI bus drivers,
|
||||||
the PMIC devices should also support this. By the pmic and regulator API's,
|
the PMIC devices should also support this. By the pmic and regulator API's,
|
||||||
|
@ -66,26 +62,27 @@ and multi-instance device support.
|
||||||
|
|
||||||
Basic design assumptions:
|
Basic design assumptions:
|
||||||
|
|
||||||
- Common I/O API - UCLASS_PMIC
|
- Common I/O API:
|
||||||
For the multi-function PMIC devices, this can be used as parent I/O device
|
UCLASS_PMIC. For the multi-function PMIC devices, this can be used as
|
||||||
for each IC's interface. Then, each children uses the same dev for read/write.
|
parent I/O device for each IC's interface. Then, each children uses the
|
||||||
|
same dev for read/write.
|
||||||
|
|
||||||
- Common regulator API - UCLASS_REGULATOR
|
- Common regulator API:
|
||||||
For driving the regulator attributes, auto setting function or command line
|
UCLASS_REGULATOR. For driving the regulator attributes, auto setting
|
||||||
interface, based on kernel-style regulator device tree constraints.
|
function or command line interface, based on kernel-style regulator device
|
||||||
|
tree constraints.
|
||||||
|
|
||||||
For simple implementations, regulator drivers are not required, so the code can
|
For simple implementations, regulator drivers are not required, so the code can
|
||||||
use pmic read/write directly.
|
use pmic read/write directly.
|
||||||
|
|
||||||
3. Pmic uclass
|
Pmic uclass
|
||||||
==============
|
-----------
|
||||||
The basic information:
|
The basic information:
|
||||||
|
|
||||||
* Uclass: 'UCLASS_PMIC'
|
* Uclass: 'UCLASS_PMIC'
|
||||||
* Header: 'include/power/pmic.h'
|
* Header: 'include/power/pmic.h'
|
||||||
* Core: 'drivers/power/pmic/pmic-uclass.c'
|
* Core: 'drivers/power/pmic/pmic-uclass.c' (config 'CONFIG_DM_PMIC')
|
||||||
config: 'CONFIG_DM_PMIC'
|
* Command: 'common/cmd_pmic.c' (config 'CONFIG_CMD_PMIC')
|
||||||
* Command: 'common/cmd_pmic.c'
|
|
||||||
config: 'CONFIG_CMD_PMIC'
|
|
||||||
* Example: 'drivers/power/pmic/max77686.c'
|
* Example: 'drivers/power/pmic/max77686.c'
|
||||||
|
|
||||||
For detailed API description, please refer to the header file.
|
For detailed API description, please refer to the header file.
|
||||||
|
@ -109,20 +106,26 @@ for pmic I/O operations only.
|
||||||
|
|
||||||
For more information, please refer to the core file.
|
For more information, please refer to the core file.
|
||||||
|
|
||||||
4. Regulator uclass
|
Regulator uclass
|
||||||
===================
|
----------------
|
||||||
The basic information:
|
The basic information:
|
||||||
* Uclass: 'UCLASS_REGULATOR'
|
|
||||||
* Header: 'include/power/regulator.h'
|
* Uclass: 'UCLASS_REGULATOR'
|
||||||
* Core: 'drivers/power/regulator/regulator-uclass.c'
|
|
||||||
config: 'CONFIG_DM_REGULATOR'
|
* Header: 'include/power/regulator.h'
|
||||||
binding: 'doc/device-tree-bindings/regulator/regulator.txt'
|
|
||||||
* Command: 'common/cmd_regulator.c'
|
* Core: 'drivers/power/regulator/regulator-uclass.c'
|
||||||
config: 'CONFIG_CMD_REGULATOR'
|
(config 'CONFIG_DM_REGULATOR')
|
||||||
|
|
||||||
|
* Binding: 'doc/device-tree-bindings/regulator/regulator.txt'
|
||||||
|
|
||||||
|
* Command: 'common/cmd_regulator.c' (config 'CONFIG_CMD_REGULATOR')
|
||||||
|
|
||||||
* Example: 'drivers/power/regulator/max77686.c'
|
* Example: 'drivers/power/regulator/max77686.c'
|
||||||
'drivers/power/pmic/max77686.c' (required I/O driver for the above)
|
'drivers/power/pmic/max77686.c' (required I/O driver for the above)
|
||||||
|
|
||||||
* Example: 'drivers/power/regulator/fixed.c'
|
* Example: 'drivers/power/regulator/fixed.c'
|
||||||
config" 'CONFIG_DM_REGULATOR_FIXED'
|
(config 'CONFIG_DM_REGULATOR_FIXED')
|
||||||
|
|
||||||
For detailed API description, please refer to the header file.
|
For detailed API description, please refer to the header file.
|
||||||
|
|
|
@ -1,19 +1,12 @@
|
||||||
# SPDX-License-Identifier: GPL-2.0+
|
.. SPDX-License-Identifier: GPL-2.0+
|
||||||
#
|
.. (C) Copyright 2015
|
||||||
# (C) Copyright 2015
|
.. Texas Instruments Incorporated - http://www.ti.com/
|
||||||
# Texas Instruments Incorporated - http://www.ti.com/
|
|
||||||
#
|
|
||||||
|
|
||||||
Remote Processor Framework
|
Remote Processor Framework
|
||||||
==========================
|
==========================
|
||||||
TOC:
|
|
||||||
1. Introduction
|
|
||||||
2. How does it work - The driver
|
|
||||||
3. Describing the device using platform data
|
|
||||||
4. Describing the device using device tree
|
|
||||||
|
|
||||||
1. Introduction
|
Introduction
|
||||||
===============
|
------------
|
||||||
|
|
||||||
This is an introduction to driver-model for Remote Processors found
|
This is an introduction to driver-model for Remote Processors found
|
||||||
on various System on Chip(SoCs). The term remote processor is used to
|
on various System on Chip(SoCs). The term remote processor is used to
|
||||||
|
@ -24,43 +17,44 @@ the processor on which we are functional.
|
||||||
The simplified model depends on a single UCLASS - UCLASS_REMOTEPROC
|
The simplified model depends on a single UCLASS - UCLASS_REMOTEPROC
|
||||||
|
|
||||||
UCLASS_REMOTEPROC:
|
UCLASS_REMOTEPROC:
|
||||||
- drivers/remoteproc/rproc-uclass.c
|
- drivers/remoteproc/rproc-uclass.c
|
||||||
- include/remoteproc.h
|
- include/remoteproc.h
|
||||||
|
|
||||||
Commands:
|
Commands:
|
||||||
- common/cmd_remoteproc.c
|
- common/cmd_remoteproc.c
|
||||||
|
|
||||||
Configuration:
|
Configuration:
|
||||||
CONFIG_REMOTEPROC is selected by drivers as needed
|
- CONFIG_REMOTEPROC is selected by drivers as needed
|
||||||
CONFIG_CMD_REMOTEPROC for the commands if required.
|
- CONFIG_CMD_REMOTEPROC for the commands if required.
|
||||||
|
|
||||||
2. How does it work - The driver
|
How does it work - The driver
|
||||||
=================================
|
-----------------------------
|
||||||
|
|
||||||
Overall, the driver statemachine transitions are typically as follows:
|
Overall, the driver statemachine transitions are typically as follows::
|
||||||
(entry)
|
|
||||||
+-------+
|
(entry)
|
||||||
+---+ init |
|
+-------+
|
||||||
| | | <---------------------+
|
+---+ init |
|
||||||
| +-------+ |
|
| | | <---------------------+
|
||||||
| |
|
| +-------+ |
|
||||||
| |
|
| |
|
||||||
| +--------+ |
|
| |
|
||||||
Load| | reset | |
|
| +--------+ |
|
||||||
| | | <----------+ |
|
Load| | reset | |
|
||||||
| +--------+ | |
|
| | | <----------+ |
|
||||||
| |Load | |
|
| +--------+ | |
|
||||||
| | | |
|
| |Load | |
|
||||||
| +----v----+ reset | |
|
| | | |
|
||||||
+-> | | (opt) | |
|
| +----v----+ reset | |
|
||||||
| Loaded +-----------+ |
|
+-> | | (opt) | |
|
||||||
| | |
|
| Loaded +-----------+ |
|
||||||
+----+----+ |
|
| | |
|
||||||
| Start |
|
+----+----+ |
|
||||||
+---v-----+ (opt) |
|
| Start |
|
||||||
+->| Running | Stop |
|
+---v-----+ (opt) |
|
||||||
Ping +- | +--------------------+
|
+->| Running | Stop |
|
||||||
(opt) +---------+
|
Ping +- | +--------------------+
|
||||||
|
(opt) +---------+
|
||||||
|
|
||||||
(is_running does not change state)
|
(is_running does not change state)
|
||||||
opt: Optional state transition implemented by driver.
|
opt: Optional state transition implemented by driver.
|
||||||
|
@ -83,23 +77,25 @@ The driver follows a standard UCLASS DM.
|
||||||
|
|
||||||
in the bare minimum form:
|
in the bare minimum form:
|
||||||
|
|
||||||
static const struct dm_rproc_ops sandbox_testproc_ops = {
|
.. code-block:: c
|
||||||
.load = sandbox_testproc_load,
|
|
||||||
.start = sandbox_testproc_start,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct udevice_id sandbox_ids[] = {
|
static const struct dm_rproc_ops sandbox_testproc_ops = {
|
||||||
{.compatible = "sandbox,test-processor"},
|
.load = sandbox_testproc_load,
|
||||||
{}
|
.start = sandbox_testproc_start,
|
||||||
};
|
};
|
||||||
|
|
||||||
U_BOOT_DRIVER(sandbox_testproc) = {
|
static const struct udevice_id sandbox_ids[] = {
|
||||||
.name = "sandbox_test_proc",
|
{.compatible = "sandbox,test-processor"},
|
||||||
.of_match = sandbox_ids,
|
{}
|
||||||
.id = UCLASS_REMOTEPROC,
|
};
|
||||||
.ops = &sandbox_testproc_ops,
|
|
||||||
.probe = sandbox_testproc_probe,
|
U_BOOT_DRIVER(sandbox_testproc) = {
|
||||||
};
|
.name = "sandbox_test_proc",
|
||||||
|
.of_match = sandbox_ids,
|
||||||
|
.id = UCLASS_REMOTEPROC,
|
||||||
|
.ops = &sandbox_testproc_ops,
|
||||||
|
.probe = sandbox_testproc_probe,
|
||||||
|
};
|
||||||
|
|
||||||
This allows for the device to be probed as part of the "init" command
|
This allows for the device to be probed as part of the "init" command
|
||||||
or invocation of 'rproc_init()' function as the system dependencies define.
|
or invocation of 'rproc_init()' function as the system dependencies define.
|
||||||
|
@ -110,8 +106,8 @@ provide a load and start function. We assume here that the device
|
||||||
needs to be loaded and started, else, there is no real purpose of
|
needs to be loaded and started, else, there is no real purpose of
|
||||||
using the remoteproc framework.
|
using the remoteproc framework.
|
||||||
|
|
||||||
3. Describing the device using platform data
|
Describing the device using platform data
|
||||||
============================================
|
-----------------------------------------
|
||||||
|
|
||||||
*IMPORTANT* NOTE: THIS SUPPORT IS NOT MEANT FOR USE WITH NEWER PLATFORM
|
*IMPORTANT* NOTE: THIS SUPPORT IS NOT MEANT FOR USE WITH NEWER PLATFORM
|
||||||
SUPPORT. THIS IS ONLY FOR LEGACY DEVICES. THIS MODE OF INITIALIZATION
|
SUPPORT. THIS IS ONLY FOR LEGACY DEVICES. THIS MODE OF INITIALIZATION
|
||||||
|
@ -121,16 +117,18 @@ TO DM/FDT.
|
||||||
Considering that many platforms are yet to move to device-tree model,
|
Considering that many platforms are yet to move to device-tree model,
|
||||||
a simplified definition of a device is as follows:
|
a simplified definition of a device is as follows:
|
||||||
|
|
||||||
struct dm_rproc_uclass_pdata proc_3_test = {
|
.. code-block:: c
|
||||||
.name = "proc_3_legacy",
|
|
||||||
.mem_type = RPROC_INTERNAL_MEMORY_MAPPED,
|
|
||||||
.driver_plat_data = &mydriver_data;
|
|
||||||
};
|
|
||||||
|
|
||||||
U_BOOT_DEVICE(proc_3_demo) = {
|
struct dm_rproc_uclass_pdata proc_3_test = {
|
||||||
.name = "sandbox_test_proc",
|
.name = "proc_3_legacy",
|
||||||
.platdata = &proc_3_test,
|
.mem_type = RPROC_INTERNAL_MEMORY_MAPPED,
|
||||||
};
|
.driver_plat_data = &mydriver_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
U_BOOT_DEVICE(proc_3_demo) = {
|
||||||
|
.name = "sandbox_test_proc",
|
||||||
|
.platdata = &proc_3_test,
|
||||||
|
};
|
||||||
|
|
||||||
There can be additional data that may be desired depending on the
|
There can be additional data that may be desired depending on the
|
||||||
remoteproc driver specific needs (for example: SoC integration
|
remoteproc driver specific needs (for example: SoC integration
|
||||||
|
@ -138,30 +136,33 @@ details such as clock handle or something similar). See appropriate
|
||||||
documentation for specific remoteproc driver for further details.
|
documentation for specific remoteproc driver for further details.
|
||||||
These are passed via driver_plat_data.
|
These are passed via driver_plat_data.
|
||||||
|
|
||||||
3. Describing the device using device tree
|
Describing the device using device tree
|
||||||
==========================================
|
---------------------------------------
|
||||||
/ {
|
|
||||||
...
|
.. code-block: none
|
||||||
aliases {
|
|
||||||
|
/ {
|
||||||
...
|
...
|
||||||
remoteproc0 = &rproc_1;
|
aliases {
|
||||||
remoteproc1 = &rproc_2;
|
...
|
||||||
|
remoteproc0 = &rproc_1;
|
||||||
|
remoteproc1 = &rproc_2;
|
||||||
|
|
||||||
};
|
};
|
||||||
...
|
...
|
||||||
|
|
||||||
rproc_1: rproc@1 {
|
rproc_1: rproc@1 {
|
||||||
compatible = "sandbox,test-processor";
|
compatible = "sandbox,test-processor";
|
||||||
remoteproc-name = "remoteproc-test-dev1";
|
remoteproc-name = "remoteproc-test-dev1";
|
||||||
};
|
};
|
||||||
|
|
||||||
rproc_2: rproc@2 {
|
rproc_2: rproc@2 {
|
||||||
compatible = "sandbox,test-processor";
|
compatible = "sandbox,test-processor";
|
||||||
internal-memory-mapped;
|
internal-memory-mapped;
|
||||||
remoteproc-name = "remoteproc-test-dev2";
|
remoteproc-name = "remoteproc-test-dev2";
|
||||||
|
};
|
||||||
|
...
|
||||||
};
|
};
|
||||||
...
|
|
||||||
};
|
|
||||||
|
|
||||||
aliases usage is optional, but it is usually recommended to ensure the
|
aliases usage is optional, but it is usually recommended to ensure the
|
||||||
users have a consistent usage model for a platform.
|
users have a consistent usage model for a platform.
|
|
@ -1,11 +1,13 @@
|
||||||
|
.. SPDX-License-Identifier: GPL-2.0+
|
||||||
|
|
||||||
How to port a serial driver to driver model
|
How to port a serial driver to driver model
|
||||||
===========================================
|
===========================================
|
||||||
|
|
||||||
Almost all of the serial drivers have been converted as at January 2016. These
|
Almost all of the serial drivers have been converted as at January 2016. These
|
||||||
ones remain:
|
ones remain:
|
||||||
|
|
||||||
serial_bfin.c
|
* serial_bfin.c
|
||||||
serial_pxa.c
|
* serial_pxa.c
|
||||||
|
|
||||||
The deadline for this work was the end of January 2016. If no one steps
|
The deadline for this work was the end of January 2016. If no one steps
|
||||||
forward to convert these, at some point there may come a patch to remove them!
|
forward to convert these, at some point there may come a patch to remove them!
|
||||||
|
@ -17,14 +19,14 @@ model. Please feel free to update this file with your ideas and suggestions.
|
||||||
- Define CONFIG_DM_SERIAL for your board, vendor or architecture
|
- Define CONFIG_DM_SERIAL for your board, vendor or architecture
|
||||||
- If the board does not already use driver model, you need CONFIG_DM also
|
- If the board does not already use driver model, you need CONFIG_DM also
|
||||||
- Your board should then build, but will not boot since there will be no serial
|
- Your board should then build, but will not boot since there will be no serial
|
||||||
driver
|
driver
|
||||||
- Add the U_BOOT_DRIVER piece at the end (e.g. copy serial_s5p.c for example)
|
- Add the U_BOOT_DRIVER piece at the end (e.g. copy serial_s5p.c for example)
|
||||||
- Add a private struct for the driver data - avoid using static variables
|
- Add a private struct for the driver data - avoid using static variables
|
||||||
- Implement each of the driver methods, perhaps by calling your old methods
|
- Implement each of the driver methods, perhaps by calling your old methods
|
||||||
- You may need to adjust the function parameters so that the old and new
|
- You may need to adjust the function parameters so that the old and new
|
||||||
implementations can share most of the existing code
|
implementations can share most of the existing code
|
||||||
- If you convert all existing users of the driver, remove the pre-driver-model
|
- If you convert all existing users of the driver, remove the pre-driver-model
|
||||||
code
|
code
|
||||||
|
|
||||||
In terms of patches a conversion series typically has these patches:
|
In terms of patches a conversion series typically has these patches:
|
||||||
- clean up / prepare the driver for conversion
|
- clean up / prepare the driver for conversion
|
692
doc/driver-model/spi-howto.rst
Normal file
692
doc/driver-model/spi-howto.rst
Normal file
|
@ -0,0 +1,692 @@
|
||||||
|
.. SPDX-License-Identifier: GPL-2.0+
|
||||||
|
|
||||||
|
How to port a SPI driver to driver model
|
||||||
|
========================================
|
||||||
|
|
||||||
|
Here is a rough step-by-step guide. It is based around converting the
|
||||||
|
exynos SPI driver to driver model (DM) and the example code is based
|
||||||
|
around U-Boot v2014.10-rc2 (commit be9f643). This has been updated for
|
||||||
|
v2015.04.
|
||||||
|
|
||||||
|
It is quite long since it includes actual code examples.
|
||||||
|
|
||||||
|
Before driver model, SPI drivers have their own private structure which
|
||||||
|
contains 'struct spi_slave'. With driver model, 'struct spi_slave' still
|
||||||
|
exists, but now it is 'per-child data' for the SPI bus. Each child of the
|
||||||
|
SPI bus is a SPI slave. The information that was stored in the
|
||||||
|
driver-specific slave structure can now be port in private data for the
|
||||||
|
SPI bus.
|
||||||
|
|
||||||
|
For example, struct tegra_spi_slave looks like this:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
struct tegra_spi_slave {
|
||||||
|
struct spi_slave slave;
|
||||||
|
struct tegra_spi_ctrl *ctrl;
|
||||||
|
};
|
||||||
|
|
||||||
|
In this case 'slave' will be in per-child data, and 'ctrl' will be in the
|
||||||
|
SPI's buses private data.
|
||||||
|
|
||||||
|
|
||||||
|
How long does this take?
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
You should be able to complete this within 2 hours, including testing but
|
||||||
|
excluding preparing the patches. The API is basically the same as before
|
||||||
|
with only minor changes:
|
||||||
|
|
||||||
|
- methods to set speed and mode are separated out
|
||||||
|
- cs_info is used to get information on a chip select
|
||||||
|
|
||||||
|
|
||||||
|
Enable driver mode for SPI and SPI flash
|
||||||
|
----------------------------------------
|
||||||
|
|
||||||
|
Add these to your board config:
|
||||||
|
|
||||||
|
* CONFIG_DM_SPI
|
||||||
|
* CONFIG_DM_SPI_FLASH
|
||||||
|
|
||||||
|
|
||||||
|
Add the skeleton
|
||||||
|
----------------
|
||||||
|
|
||||||
|
Put this code at the bottom of your existing driver file:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
struct spi_slave *spi_setup_slave(unsigned int busnum, unsigned int cs,
|
||||||
|
unsigned int max_hz, unsigned int mode)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct spi_slave *spi_setup_slave_fdt(const void *blob, int slave_node,
|
||||||
|
int spi_node)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int exynos_spi_ofdata_to_platdata(struct udevice *dev)
|
||||||
|
{
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int exynos_spi_probe(struct udevice *dev)
|
||||||
|
{
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int exynos_spi_remove(struct udevice *dev)
|
||||||
|
{
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int exynos_spi_claim_bus(struct udevice *dev)
|
||||||
|
{
|
||||||
|
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int exynos_spi_release_bus(struct udevice *dev)
|
||||||
|
{
|
||||||
|
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int exynos_spi_xfer(struct udevice *dev, unsigned int bitlen,
|
||||||
|
const void *dout, void *din, unsigned long flags)
|
||||||
|
{
|
||||||
|
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int exynos_spi_set_speed(struct udevice *dev, uint speed)
|
||||||
|
{
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int exynos_spi_set_mode(struct udevice *dev, uint mode)
|
||||||
|
{
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int exynos_cs_info(struct udevice *bus, uint cs,
|
||||||
|
struct spi_cs_info *info)
|
||||||
|
{
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct dm_spi_ops exynos_spi_ops = {
|
||||||
|
.claim_bus = exynos_spi_claim_bus,
|
||||||
|
.release_bus = exynos_spi_release_bus,
|
||||||
|
.xfer = exynos_spi_xfer,
|
||||||
|
.set_speed = exynos_spi_set_speed,
|
||||||
|
.set_mode = exynos_spi_set_mode,
|
||||||
|
.cs_info = exynos_cs_info,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct udevice_id exynos_spi_ids[] = {
|
||||||
|
{ .compatible = "samsung,exynos-spi" },
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
U_BOOT_DRIVER(exynos_spi) = {
|
||||||
|
.name = "exynos_spi",
|
||||||
|
.id = UCLASS_SPI,
|
||||||
|
.of_match = exynos_spi_ids,
|
||||||
|
.ops = &exynos_spi_ops,
|
||||||
|
.ofdata_to_platdata = exynos_spi_ofdata_to_platdata,
|
||||||
|
.probe = exynos_spi_probe,
|
||||||
|
.remove = exynos_spi_remove,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Replace 'exynos' in the above code with your driver name
|
||||||
|
--------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef out all of the code in your driver except for the above
|
||||||
|
--------------------------------------------------------------
|
||||||
|
|
||||||
|
This will allow you to get it building, which means you can work
|
||||||
|
incrementally. Since all the methods return an error initially, there is
|
||||||
|
less chance that you will accidentally leave something in.
|
||||||
|
|
||||||
|
Also, even though your conversion is basically a rewrite, it might help
|
||||||
|
reviewers if you leave functions in the same place in the file,
|
||||||
|
particularly for large drivers.
|
||||||
|
|
||||||
|
|
||||||
|
Add some includes
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
Add these includes to your driver:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
#include <dm.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
|
||||||
|
Build
|
||||||
|
-----
|
||||||
|
|
||||||
|
At this point you should be able to build U-Boot for your board with the
|
||||||
|
empty SPI driver. You still have empty methods in your driver, but we will
|
||||||
|
write these one by one.
|
||||||
|
|
||||||
|
Set up your platform data structure
|
||||||
|
-----------------------------------
|
||||||
|
|
||||||
|
This will hold the information your driver to operate, like its hardware
|
||||||
|
address or maximum frequency.
|
||||||
|
|
||||||
|
You may already have a struct like this, or you may need to create one
|
||||||
|
from some of the #defines or global variables in the driver.
|
||||||
|
|
||||||
|
Note that this information is not the run-time information. It should not
|
||||||
|
include state that changes. It should be fixed throughout the live of
|
||||||
|
U-Boot. Run-time information comes later.
|
||||||
|
|
||||||
|
Here is what was in the exynos spi driver:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
struct spi_bus {
|
||||||
|
enum periph_id periph_id;
|
||||||
|
s32 frequency; /* Default clock frequency, -1 for none */
|
||||||
|
struct exynos_spi *regs;
|
||||||
|
int inited; /* 1 if this bus is ready for use */
|
||||||
|
int node;
|
||||||
|
uint deactivate_delay_us; /* Delay to wait after deactivate */
|
||||||
|
};
|
||||||
|
|
||||||
|
Of these, inited is handled by DM and node is the device tree node, which
|
||||||
|
DM tells you. The name is not quite right. So in this case we would use:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
struct exynos_spi_platdata {
|
||||||
|
enum periph_id periph_id;
|
||||||
|
s32 frequency; /* Default clock frequency, -1 for none */
|
||||||
|
struct exynos_spi *regs;
|
||||||
|
uint deactivate_delay_us; /* Delay to wait after deactivate */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Write ofdata_to_platdata() [for device tree only]
|
||||||
|
-------------------------------------------------
|
||||||
|
|
||||||
|
This method will convert information in the device tree node into a C
|
||||||
|
structure in your driver (called platform data). If you are not using
|
||||||
|
device tree, go to 8b.
|
||||||
|
|
||||||
|
DM will automatically allocate the struct for us when we are using device
|
||||||
|
tree, but we need to tell it the size:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
U_BOOT_DRIVER(spi_exynos) = {
|
||||||
|
...
|
||||||
|
.platdata_auto_alloc_size = sizeof(struct exynos_spi_platdata),
|
||||||
|
|
||||||
|
|
||||||
|
Here is a sample function. It gets a pointer to the platform data and
|
||||||
|
fills in the fields from device tree.
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
static int exynos_spi_ofdata_to_platdata(struct udevice *bus)
|
||||||
|
{
|
||||||
|
struct exynos_spi_platdata *plat = bus->platdata;
|
||||||
|
const void *blob = gd->fdt_blob;
|
||||||
|
int node = dev_of_offset(bus);
|
||||||
|
|
||||||
|
plat->regs = (struct exynos_spi *)fdtdec_get_addr(blob, node, "reg");
|
||||||
|
plat->periph_id = pinmux_decode_periph_id(blob, node);
|
||||||
|
|
||||||
|
if (plat->periph_id == PERIPH_ID_NONE) {
|
||||||
|
debug("%s: Invalid peripheral ID %d\n", __func__,
|
||||||
|
plat->periph_id);
|
||||||
|
return -FDT_ERR_NOTFOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Use 500KHz as a suitable default */
|
||||||
|
plat->frequency = fdtdec_get_int(blob, node, "spi-max-frequency",
|
||||||
|
500000);
|
||||||
|
plat->deactivate_delay_us = fdtdec_get_int(blob, node,
|
||||||
|
"spi-deactivate-delay", 0);
|
||||||
|
debug("%s: regs=%p, periph_id=%d, max-frequency=%d, deactivate_delay=%d\n",
|
||||||
|
__func__, plat->regs, plat->periph_id, plat->frequency,
|
||||||
|
plat->deactivate_delay_us);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Add the platform data [non-device-tree only]
|
||||||
|
--------------------------------------------
|
||||||
|
|
||||||
|
Specify this data in a U_BOOT_DEVICE() declaration in your board file:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
struct exynos_spi_platdata platdata_spi0 = {
|
||||||
|
.periph_id = ...
|
||||||
|
.frequency = ...
|
||||||
|
.regs = ...
|
||||||
|
.deactivate_delay_us = ...
|
||||||
|
};
|
||||||
|
|
||||||
|
U_BOOT_DEVICE(board_spi0) = {
|
||||||
|
.name = "exynos_spi",
|
||||||
|
.platdata = &platdata_spi0,
|
||||||
|
};
|
||||||
|
|
||||||
|
You will unfortunately need to put the struct definition into a header file
|
||||||
|
in this case so that your board file can use it.
|
||||||
|
|
||||||
|
|
||||||
|
Add the device private data
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
Most devices have some private data which they use to keep track of things
|
||||||
|
while active. This is the run-time information and needs to be stored in
|
||||||
|
a structure. There is probably a structure in the driver that includes a
|
||||||
|
'struct spi_slave', so you can use that.
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
struct exynos_spi_slave {
|
||||||
|
struct spi_slave slave;
|
||||||
|
struct exynos_spi *regs;
|
||||||
|
unsigned int freq; /* Default frequency */
|
||||||
|
unsigned int mode;
|
||||||
|
enum periph_id periph_id; /* Peripheral ID for this device */
|
||||||
|
unsigned int fifo_size;
|
||||||
|
int skip_preamble;
|
||||||
|
struct spi_bus *bus; /* Pointer to our SPI bus info */
|
||||||
|
ulong last_transaction_us; /* Time of last transaction end */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
We should rename this to make its purpose more obvious, and get rid of
|
||||||
|
the slave structure, so we have:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
struct exynos_spi_priv {
|
||||||
|
struct exynos_spi *regs;
|
||||||
|
unsigned int freq; /* Default frequency */
|
||||||
|
unsigned int mode;
|
||||||
|
enum periph_id periph_id; /* Peripheral ID for this device */
|
||||||
|
unsigned int fifo_size;
|
||||||
|
int skip_preamble;
|
||||||
|
ulong last_transaction_us; /* Time of last transaction end */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
DM can auto-allocate this also:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
U_BOOT_DRIVER(spi_exynos) = {
|
||||||
|
...
|
||||||
|
.priv_auto_alloc_size = sizeof(struct exynos_spi_priv),
|
||||||
|
|
||||||
|
|
||||||
|
Note that this is created before the probe method is called, and destroyed
|
||||||
|
after the remove method is called. It will be zeroed when the probe
|
||||||
|
method is called.
|
||||||
|
|
||||||
|
|
||||||
|
Add the probe() and remove() methods
|
||||||
|
------------------------------------
|
||||||
|
|
||||||
|
Note: It's a good idea to build repeatedly as you are working, to avoid a
|
||||||
|
huge amount of work getting things compiling at the end.
|
||||||
|
|
||||||
|
The probe method is supposed to set up the hardware. U-Boot used to use
|
||||||
|
spi_setup_slave() to do this. So take a look at this function and see
|
||||||
|
what you can copy out to set things up.
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
static int exynos_spi_probe(struct udevice *bus)
|
||||||
|
{
|
||||||
|
struct exynos_spi_platdata *plat = dev_get_platdata(bus);
|
||||||
|
struct exynos_spi_priv *priv = dev_get_priv(bus);
|
||||||
|
|
||||||
|
priv->regs = plat->regs;
|
||||||
|
if (plat->periph_id == PERIPH_ID_SPI1 ||
|
||||||
|
plat->periph_id == PERIPH_ID_SPI2)
|
||||||
|
priv->fifo_size = 64;
|
||||||
|
else
|
||||||
|
priv->fifo_size = 256;
|
||||||
|
|
||||||
|
priv->skip_preamble = 0;
|
||||||
|
priv->last_transaction_us = timer_get_us();
|
||||||
|
priv->freq = plat->frequency;
|
||||||
|
priv->periph_id = plat->periph_id;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
This implementation doesn't actually touch the hardware, which is somewhat
|
||||||
|
unusual for a driver. In this case we will do that when the device is
|
||||||
|
claimed by something that wants to use the SPI bus.
|
||||||
|
|
||||||
|
For remove we could shut down the clocks, but in this case there is
|
||||||
|
nothing to do. DM frees any memory that it allocated, so we can just
|
||||||
|
remove exynos_spi_remove() and its reference in U_BOOT_DRIVER.
|
||||||
|
|
||||||
|
|
||||||
|
Implement set_speed()
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
This should set up clocks so that the SPI bus is running at the right
|
||||||
|
speed. With the old API spi_claim_bus() would normally do this and several
|
||||||
|
of the following functions, so let's look at that function:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
int spi_claim_bus(struct spi_slave *slave)
|
||||||
|
{
|
||||||
|
struct exynos_spi_slave *spi_slave = to_exynos_spi(slave);
|
||||||
|
struct exynos_spi *regs = spi_slave->regs;
|
||||||
|
u32 reg = 0;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = set_spi_clk(spi_slave->periph_id,
|
||||||
|
spi_slave->freq);
|
||||||
|
if (ret < 0) {
|
||||||
|
debug("%s: Failed to setup spi clock\n", __func__);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
exynos_pinmux_config(spi_slave->periph_id, PINMUX_FLAG_NONE);
|
||||||
|
|
||||||
|
spi_flush_fifo(slave);
|
||||||
|
|
||||||
|
reg = readl(®s->ch_cfg);
|
||||||
|
reg &= ~(SPI_CH_CPHA_B | SPI_CH_CPOL_L);
|
||||||
|
|
||||||
|
if (spi_slave->mode & SPI_CPHA)
|
||||||
|
reg |= SPI_CH_CPHA_B;
|
||||||
|
|
||||||
|
if (spi_slave->mode & SPI_CPOL)
|
||||||
|
reg |= SPI_CH_CPOL_L;
|
||||||
|
|
||||||
|
writel(reg, ®s->ch_cfg);
|
||||||
|
writel(SPI_FB_DELAY_180, ®s->fb_clk);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
It sets up the speed, mode, pinmux, feedback delay and clears the FIFOs.
|
||||||
|
With DM these will happen in separate methods.
|
||||||
|
|
||||||
|
|
||||||
|
Here is an example for the speed part:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
static int exynos_spi_set_speed(struct udevice *bus, uint speed)
|
||||||
|
{
|
||||||
|
struct exynos_spi_platdata *plat = bus->platdata;
|
||||||
|
struct exynos_spi_priv *priv = dev_get_priv(bus);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (speed > plat->frequency)
|
||||||
|
speed = plat->frequency;
|
||||||
|
ret = set_spi_clk(priv->periph_id, speed);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
priv->freq = speed;
|
||||||
|
debug("%s: regs=%p, speed=%d\n", __func__, priv->regs, priv->freq);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Implement set_mode()
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
This should adjust the SPI mode (polarity, etc.). Again this code probably
|
||||||
|
comes from the old spi_claim_bus(). Here is an example:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
static int exynos_spi_set_mode(struct udevice *bus, uint mode)
|
||||||
|
{
|
||||||
|
struct exynos_spi_priv *priv = dev_get_priv(bus);
|
||||||
|
uint32_t reg;
|
||||||
|
|
||||||
|
reg = readl(&priv->regs->ch_cfg);
|
||||||
|
reg &= ~(SPI_CH_CPHA_B | SPI_CH_CPOL_L);
|
||||||
|
|
||||||
|
if (mode & SPI_CPHA)
|
||||||
|
reg |= SPI_CH_CPHA_B;
|
||||||
|
|
||||||
|
if (mode & SPI_CPOL)
|
||||||
|
reg |= SPI_CH_CPOL_L;
|
||||||
|
|
||||||
|
writel(reg, &priv->regs->ch_cfg);
|
||||||
|
priv->mode = mode;
|
||||||
|
debug("%s: regs=%p, mode=%d\n", __func__, priv->regs, priv->mode);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Implement claim_bus()
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
This is where a client wants to make use of the bus, so claims it first.
|
||||||
|
At this point we need to make sure everything is set up ready for data
|
||||||
|
transfer. Note that this function is wholly internal to the driver - at
|
||||||
|
present the SPI uclass never calls it.
|
||||||
|
|
||||||
|
Here again we look at the old claim function and see some code that is
|
||||||
|
needed. It is anything unrelated to speed and mode:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
static int exynos_spi_claim_bus(struct udevice *bus)
|
||||||
|
{
|
||||||
|
struct exynos_spi_priv *priv = dev_get_priv(bus);
|
||||||
|
|
||||||
|
exynos_pinmux_config(priv->periph_id, PINMUX_FLAG_NONE);
|
||||||
|
spi_flush_fifo(priv->regs);
|
||||||
|
|
||||||
|
writel(SPI_FB_DELAY_180, &priv->regs->fb_clk);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
The spi_flush_fifo() function is in the removed part of the code, so we
|
||||||
|
need to expose it again (perhaps with an #endif before it and '#if 0'
|
||||||
|
after it). It only needs access to priv->regs which is why we have
|
||||||
|
passed that in:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flush spi tx, rx fifos and reset the SPI controller
|
||||||
|
*
|
||||||
|
* @param regs Pointer to SPI registers
|
||||||
|
*/
|
||||||
|
static void spi_flush_fifo(struct exynos_spi *regs)
|
||||||
|
{
|
||||||
|
clrsetbits_le32(®s->ch_cfg, SPI_CH_HS_EN, SPI_CH_RST);
|
||||||
|
clrbits_le32(®s->ch_cfg, SPI_CH_RST);
|
||||||
|
setbits_le32(®s->ch_cfg, SPI_TX_CH_ON | SPI_RX_CH_ON);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Implement release_bus()
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
This releases the bus - in our example the old code in spi_release_bus()
|
||||||
|
is a call to spi_flush_fifo, so we add:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
static int exynos_spi_release_bus(struct udevice *bus)
|
||||||
|
{
|
||||||
|
struct exynos_spi_priv *priv = dev_get_priv(bus);
|
||||||
|
|
||||||
|
spi_flush_fifo(priv->regs);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Implement xfer()
|
||||||
|
----------------
|
||||||
|
|
||||||
|
This is the final method that we need to create, and it is where all the
|
||||||
|
work happens. The method parameters are the same as the old spi_xfer() with
|
||||||
|
the addition of a 'struct udevice' so conversion is pretty easy. Start
|
||||||
|
by copying the contents of spi_xfer() to your new xfer() method and proceed
|
||||||
|
from there.
|
||||||
|
|
||||||
|
If (flags & SPI_XFER_BEGIN) is non-zero then xfer() normally calls an
|
||||||
|
activate function, something like this:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
void spi_cs_activate(struct spi_slave *slave)
|
||||||
|
{
|
||||||
|
struct exynos_spi_slave *spi_slave = to_exynos_spi(slave);
|
||||||
|
|
||||||
|
/* If it's too soon to do another transaction, wait */
|
||||||
|
if (spi_slave->bus->deactivate_delay_us &&
|
||||||
|
spi_slave->last_transaction_us) {
|
||||||
|
ulong delay_us; /* The delay completed so far */
|
||||||
|
delay_us = timer_get_us() - spi_slave->last_transaction_us;
|
||||||
|
if (delay_us < spi_slave->bus->deactivate_delay_us)
|
||||||
|
udelay(spi_slave->bus->deactivate_delay_us - delay_us);
|
||||||
|
}
|
||||||
|
|
||||||
|
clrbits_le32(&spi_slave->regs->cs_reg, SPI_SLAVE_SIG_INACT);
|
||||||
|
debug("Activate CS, bus %d\n", spi_slave->slave.bus);
|
||||||
|
spi_slave->skip_preamble = spi_slave->mode & SPI_PREAMBLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
The new version looks like this:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
static void spi_cs_activate(struct udevice *dev)
|
||||||
|
{
|
||||||
|
struct udevice *bus = dev->parent;
|
||||||
|
struct exynos_spi_platdata *pdata = dev_get_platdata(bus);
|
||||||
|
struct exynos_spi_priv *priv = dev_get_priv(bus);
|
||||||
|
|
||||||
|
/* If it's too soon to do another transaction, wait */
|
||||||
|
if (pdata->deactivate_delay_us &&
|
||||||
|
priv->last_transaction_us) {
|
||||||
|
ulong delay_us; /* The delay completed so far */
|
||||||
|
delay_us = timer_get_us() - priv->last_transaction_us;
|
||||||
|
if (delay_us < pdata->deactivate_delay_us)
|
||||||
|
udelay(pdata->deactivate_delay_us - delay_us);
|
||||||
|
}
|
||||||
|
|
||||||
|
clrbits_le32(&priv->regs->cs_reg, SPI_SLAVE_SIG_INACT);
|
||||||
|
debug("Activate CS, bus '%s'\n", bus->name);
|
||||||
|
priv->skip_preamble = priv->mode & SPI_PREAMBLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
All we have really done here is change the pointers and print the device name
|
||||||
|
instead of the bus number. Other local static functions can be treated in
|
||||||
|
the same way.
|
||||||
|
|
||||||
|
|
||||||
|
Set up the per-child data and child pre-probe function
|
||||||
|
------------------------------------------------------
|
||||||
|
|
||||||
|
To minimise the pain and complexity of the SPI subsystem while the driver
|
||||||
|
model change-over is in place, struct spi_slave is used to reference a
|
||||||
|
SPI bus slave, even though that slave is actually a struct udevice. In fact
|
||||||
|
struct spi_slave is the device's child data. We need to make sure this space
|
||||||
|
is available. It is possible to allocate more space that struct spi_slave
|
||||||
|
needs, but this is the minimum.
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
U_BOOT_DRIVER(exynos_spi) = {
|
||||||
|
...
|
||||||
|
.per_child_auto_alloc_size = sizeof(struct spi_slave),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Optional: Set up cs_info() if you want it
|
||||||
|
-----------------------------------------
|
||||||
|
|
||||||
|
Sometimes it is useful to know whether a SPI chip select is valid, but this
|
||||||
|
is not obvious from outside the driver. In this case you can provide a
|
||||||
|
method for cs_info() to deal with this. If you don't provide it, then the
|
||||||
|
device tree will be used to determine what chip selects are valid.
|
||||||
|
|
||||||
|
Return -ENODEV if the supplied chip select is invalid, or 0 if it is valid.
|
||||||
|
If you don't provide the cs_info() method, -ENODEV is assumed for all
|
||||||
|
chip selects that do not appear in the device tree.
|
||||||
|
|
||||||
|
|
||||||
|
Test it
|
||||||
|
-------
|
||||||
|
|
||||||
|
Now that you have the code written and it compiles, try testing it using
|
||||||
|
the 'sf test' command. You may need to enable CONFIG_CMD_SF_TEST for your
|
||||||
|
board.
|
||||||
|
|
||||||
|
|
||||||
|
Prepare patches and send them to the mailing lists
|
||||||
|
--------------------------------------------------
|
||||||
|
|
||||||
|
You can use 'tools/patman/patman' to prepare, check and send patches for
|
||||||
|
your work. See the README for details.
|
||||||
|
|
||||||
|
A little note about SPI uclass features
|
||||||
|
---------------------------------------
|
||||||
|
|
||||||
|
The SPI uclass keeps some information about each device 'dev' on the bus:
|
||||||
|
|
||||||
|
struct dm_spi_slave_platdata:
|
||||||
|
This is device_get_parent_platdata(dev).
|
||||||
|
This is where the chip select number is stored, along with
|
||||||
|
the default bus speed and mode. It is automatically read
|
||||||
|
from the device tree in spi_child_post_bind(). It must not
|
||||||
|
be changed at run-time after being set up because platform
|
||||||
|
data is supposed to be immutable at run-time.
|
||||||
|
struct spi_slave:
|
||||||
|
This is device_get_parentdata(dev).
|
||||||
|
Already mentioned above. It holds run-time information about
|
||||||
|
the device.
|
||||||
|
|
||||||
|
There are also some SPI uclass methods that get called behind the scenes:
|
||||||
|
|
||||||
|
spi_post_bind():
|
||||||
|
Called when a new bus is bound.
|
||||||
|
This scans the device tree for devices on the bus, and binds
|
||||||
|
each one. This in turn causes spi_child_post_bind() to be
|
||||||
|
called for each, which reads the device tree information
|
||||||
|
into the parent (per-child) platform data.
|
||||||
|
spi_child_post_bind():
|
||||||
|
Called when a new child is bound.
|
||||||
|
As mentioned above this reads the device tree information
|
||||||
|
into the per-child platform data
|
||||||
|
spi_child_pre_probe():
|
||||||
|
Called before a new child is probed.
|
||||||
|
This sets up the mode and speed in struct spi_slave by
|
||||||
|
copying it from the parent's platform data for this child.
|
||||||
|
It also sets the 'dev' pointer, needed to permit passing
|
||||||
|
'struct spi_slave' around the place without needing a
|
||||||
|
separate 'struct udevice' pointer.
|
||||||
|
|
||||||
|
The above housekeeping makes it easier to write your SPI driver.
|
|
@ -1,623 +0,0 @@
|
||||||
How to port a SPI driver to driver model
|
|
||||||
========================================
|
|
||||||
|
|
||||||
Here is a rough step-by-step guide. It is based around converting the
|
|
||||||
exynos SPI driver to driver model (DM) and the example code is based
|
|
||||||
around U-Boot v2014.10-rc2 (commit be9f643). This has been updated for
|
|
||||||
v2015.04.
|
|
||||||
|
|
||||||
It is quite long since it includes actual code examples.
|
|
||||||
|
|
||||||
Before driver model, SPI drivers have their own private structure which
|
|
||||||
contains 'struct spi_slave'. With driver model, 'struct spi_slave' still
|
|
||||||
exists, but now it is 'per-child data' for the SPI bus. Each child of the
|
|
||||||
SPI bus is a SPI slave. The information that was stored in the
|
|
||||||
driver-specific slave structure can now be port in private data for the
|
|
||||||
SPI bus.
|
|
||||||
|
|
||||||
For example, struct tegra_spi_slave looks like this:
|
|
||||||
|
|
||||||
struct tegra_spi_slave {
|
|
||||||
struct spi_slave slave;
|
|
||||||
struct tegra_spi_ctrl *ctrl;
|
|
||||||
};
|
|
||||||
|
|
||||||
In this case 'slave' will be in per-child data, and 'ctrl' will be in the
|
|
||||||
SPI's buses private data.
|
|
||||||
|
|
||||||
|
|
||||||
0. How long does this take?
|
|
||||||
|
|
||||||
You should be able to complete this within 2 hours, including testing but
|
|
||||||
excluding preparing the patches. The API is basically the same as before
|
|
||||||
with only minor changes:
|
|
||||||
|
|
||||||
- methods to set speed and mode are separated out
|
|
||||||
- cs_info is used to get information on a chip select
|
|
||||||
|
|
||||||
|
|
||||||
1. Enable driver mode for SPI and SPI flash
|
|
||||||
|
|
||||||
Add these to your board config:
|
|
||||||
|
|
||||||
CONFIG_DM_SPI
|
|
||||||
CONFIG_DM_SPI_FLASH
|
|
||||||
|
|
||||||
|
|
||||||
2. Add the skeleton
|
|
||||||
|
|
||||||
Put this code at the bottom of your existing driver file:
|
|
||||||
|
|
||||||
struct spi_slave *spi_setup_slave(unsigned int busnum, unsigned int cs,
|
|
||||||
unsigned int max_hz, unsigned int mode)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct spi_slave *spi_setup_slave_fdt(const void *blob, int slave_node,
|
|
||||||
int spi_node)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int exynos_spi_ofdata_to_platdata(struct udevice *dev)
|
|
||||||
{
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int exynos_spi_probe(struct udevice *dev)
|
|
||||||
{
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int exynos_spi_remove(struct udevice *dev)
|
|
||||||
{
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int exynos_spi_claim_bus(struct udevice *dev)
|
|
||||||
{
|
|
||||||
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int exynos_spi_release_bus(struct udevice *dev)
|
|
||||||
{
|
|
||||||
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int exynos_spi_xfer(struct udevice *dev, unsigned int bitlen,
|
|
||||||
const void *dout, void *din, unsigned long flags)
|
|
||||||
{
|
|
||||||
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int exynos_spi_set_speed(struct udevice *dev, uint speed)
|
|
||||||
{
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int exynos_spi_set_mode(struct udevice *dev, uint mode)
|
|
||||||
{
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int exynos_cs_info(struct udevice *bus, uint cs,
|
|
||||||
struct spi_cs_info *info)
|
|
||||||
{
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct dm_spi_ops exynos_spi_ops = {
|
|
||||||
.claim_bus = exynos_spi_claim_bus,
|
|
||||||
.release_bus = exynos_spi_release_bus,
|
|
||||||
.xfer = exynos_spi_xfer,
|
|
||||||
.set_speed = exynos_spi_set_speed,
|
|
||||||
.set_mode = exynos_spi_set_mode,
|
|
||||||
.cs_info = exynos_cs_info,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct udevice_id exynos_spi_ids[] = {
|
|
||||||
{ .compatible = "samsung,exynos-spi" },
|
|
||||||
{ }
|
|
||||||
};
|
|
||||||
|
|
||||||
U_BOOT_DRIVER(exynos_spi) = {
|
|
||||||
.name = "exynos_spi",
|
|
||||||
.id = UCLASS_SPI,
|
|
||||||
.of_match = exynos_spi_ids,
|
|
||||||
.ops = &exynos_spi_ops,
|
|
||||||
.ofdata_to_platdata = exynos_spi_ofdata_to_platdata,
|
|
||||||
.probe = exynos_spi_probe,
|
|
||||||
.remove = exynos_spi_remove,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
3. Replace 'exynos' in the above code with your driver name
|
|
||||||
|
|
||||||
|
|
||||||
4. #ifdef out all of the code in your driver except for the above
|
|
||||||
|
|
||||||
This will allow you to get it building, which means you can work
|
|
||||||
incrementally. Since all the methods return an error initially, there is
|
|
||||||
less chance that you will accidentally leave something in.
|
|
||||||
|
|
||||||
Also, even though your conversion is basically a rewrite, it might help
|
|
||||||
reviewers if you leave functions in the same place in the file,
|
|
||||||
particularly for large drivers.
|
|
||||||
|
|
||||||
|
|
||||||
5. Add some includes
|
|
||||||
|
|
||||||
Add these includes to your driver:
|
|
||||||
|
|
||||||
#include <dm.h>
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
|
|
||||||
6. Build
|
|
||||||
|
|
||||||
At this point you should be able to build U-Boot for your board with the
|
|
||||||
empty SPI driver. You still have empty methods in your driver, but we will
|
|
||||||
write these one by one.
|
|
||||||
|
|
||||||
7. Set up your platform data structure
|
|
||||||
|
|
||||||
This will hold the information your driver to operate, like its hardware
|
|
||||||
address or maximum frequency.
|
|
||||||
|
|
||||||
You may already have a struct like this, or you may need to create one
|
|
||||||
from some of the #defines or global variables in the driver.
|
|
||||||
|
|
||||||
Note that this information is not the run-time information. It should not
|
|
||||||
include state that changes. It should be fixed throughout the live of
|
|
||||||
U-Boot. Run-time information comes later.
|
|
||||||
|
|
||||||
Here is what was in the exynos spi driver:
|
|
||||||
|
|
||||||
struct spi_bus {
|
|
||||||
enum periph_id periph_id;
|
|
||||||
s32 frequency; /* Default clock frequency, -1 for none */
|
|
||||||
struct exynos_spi *regs;
|
|
||||||
int inited; /* 1 if this bus is ready for use */
|
|
||||||
int node;
|
|
||||||
uint deactivate_delay_us; /* Delay to wait after deactivate */
|
|
||||||
};
|
|
||||||
|
|
||||||
Of these, inited is handled by DM and node is the device tree node, which
|
|
||||||
DM tells you. The name is not quite right. So in this case we would use:
|
|
||||||
|
|
||||||
struct exynos_spi_platdata {
|
|
||||||
enum periph_id periph_id;
|
|
||||||
s32 frequency; /* Default clock frequency, -1 for none */
|
|
||||||
struct exynos_spi *regs;
|
|
||||||
uint deactivate_delay_us; /* Delay to wait after deactivate */
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
8a. Write ofdata_to_platdata() [for device tree only]
|
|
||||||
|
|
||||||
This method will convert information in the device tree node into a C
|
|
||||||
structure in your driver (called platform data). If you are not using
|
|
||||||
device tree, go to 8b.
|
|
||||||
|
|
||||||
DM will automatically allocate the struct for us when we are using device
|
|
||||||
tree, but we need to tell it the size:
|
|
||||||
|
|
||||||
U_BOOT_DRIVER(spi_exynos) = {
|
|
||||||
...
|
|
||||||
.platdata_auto_alloc_size = sizeof(struct exynos_spi_platdata),
|
|
||||||
|
|
||||||
|
|
||||||
Here is a sample function. It gets a pointer to the platform data and
|
|
||||||
fills in the fields from device tree.
|
|
||||||
|
|
||||||
static int exynos_spi_ofdata_to_platdata(struct udevice *bus)
|
|
||||||
{
|
|
||||||
struct exynos_spi_platdata *plat = bus->platdata;
|
|
||||||
const void *blob = gd->fdt_blob;
|
|
||||||
int node = dev_of_offset(bus);
|
|
||||||
|
|
||||||
plat->regs = (struct exynos_spi *)fdtdec_get_addr(blob, node, "reg");
|
|
||||||
plat->periph_id = pinmux_decode_periph_id(blob, node);
|
|
||||||
|
|
||||||
if (plat->periph_id == PERIPH_ID_NONE) {
|
|
||||||
debug("%s: Invalid peripheral ID %d\n", __func__,
|
|
||||||
plat->periph_id);
|
|
||||||
return -FDT_ERR_NOTFOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Use 500KHz as a suitable default */
|
|
||||||
plat->frequency = fdtdec_get_int(blob, node, "spi-max-frequency",
|
|
||||||
500000);
|
|
||||||
plat->deactivate_delay_us = fdtdec_get_int(blob, node,
|
|
||||||
"spi-deactivate-delay", 0);
|
|
||||||
debug("%s: regs=%p, periph_id=%d, max-frequency=%d, deactivate_delay=%d\n",
|
|
||||||
__func__, plat->regs, plat->periph_id, plat->frequency,
|
|
||||||
plat->deactivate_delay_us);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
8b. Add the platform data [non-device-tree only]
|
|
||||||
|
|
||||||
Specify this data in a U_BOOT_DEVICE() declaration in your board file:
|
|
||||||
|
|
||||||
struct exynos_spi_platdata platdata_spi0 = {
|
|
||||||
.periph_id = ...
|
|
||||||
.frequency = ...
|
|
||||||
.regs = ...
|
|
||||||
.deactivate_delay_us = ...
|
|
||||||
};
|
|
||||||
|
|
||||||
U_BOOT_DEVICE(board_spi0) = {
|
|
||||||
.name = "exynos_spi",
|
|
||||||
.platdata = &platdata_spi0,
|
|
||||||
};
|
|
||||||
|
|
||||||
You will unfortunately need to put the struct definition into a header file
|
|
||||||
in this case so that your board file can use it.
|
|
||||||
|
|
||||||
|
|
||||||
9. Add the device private data
|
|
||||||
|
|
||||||
Most devices have some private data which they use to keep track of things
|
|
||||||
while active. This is the run-time information and needs to be stored in
|
|
||||||
a structure. There is probably a structure in the driver that includes a
|
|
||||||
'struct spi_slave', so you can use that.
|
|
||||||
|
|
||||||
struct exynos_spi_slave {
|
|
||||||
struct spi_slave slave;
|
|
||||||
struct exynos_spi *regs;
|
|
||||||
unsigned int freq; /* Default frequency */
|
|
||||||
unsigned int mode;
|
|
||||||
enum periph_id periph_id; /* Peripheral ID for this device */
|
|
||||||
unsigned int fifo_size;
|
|
||||||
int skip_preamble;
|
|
||||||
struct spi_bus *bus; /* Pointer to our SPI bus info */
|
|
||||||
ulong last_transaction_us; /* Time of last transaction end */
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
We should rename this to make its purpose more obvious, and get rid of
|
|
||||||
the slave structure, so we have:
|
|
||||||
|
|
||||||
struct exynos_spi_priv {
|
|
||||||
struct exynos_spi *regs;
|
|
||||||
unsigned int freq; /* Default frequency */
|
|
||||||
unsigned int mode;
|
|
||||||
enum periph_id periph_id; /* Peripheral ID for this device */
|
|
||||||
unsigned int fifo_size;
|
|
||||||
int skip_preamble;
|
|
||||||
ulong last_transaction_us; /* Time of last transaction end */
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
DM can auto-allocate this also:
|
|
||||||
|
|
||||||
U_BOOT_DRIVER(spi_exynos) = {
|
|
||||||
...
|
|
||||||
.priv_auto_alloc_size = sizeof(struct exynos_spi_priv),
|
|
||||||
|
|
||||||
|
|
||||||
Note that this is created before the probe method is called, and destroyed
|
|
||||||
after the remove method is called. It will be zeroed when the probe
|
|
||||||
method is called.
|
|
||||||
|
|
||||||
|
|
||||||
10. Add the probe() and remove() methods
|
|
||||||
|
|
||||||
Note: It's a good idea to build repeatedly as you are working, to avoid a
|
|
||||||
huge amount of work getting things compiling at the end.
|
|
||||||
|
|
||||||
The probe method is supposed to set up the hardware. U-Boot used to use
|
|
||||||
spi_setup_slave() to do this. So take a look at this function and see
|
|
||||||
what you can copy out to set things up.
|
|
||||||
|
|
||||||
|
|
||||||
static int exynos_spi_probe(struct udevice *bus)
|
|
||||||
{
|
|
||||||
struct exynos_spi_platdata *plat = dev_get_platdata(bus);
|
|
||||||
struct exynos_spi_priv *priv = dev_get_priv(bus);
|
|
||||||
|
|
||||||
priv->regs = plat->regs;
|
|
||||||
if (plat->periph_id == PERIPH_ID_SPI1 ||
|
|
||||||
plat->periph_id == PERIPH_ID_SPI2)
|
|
||||||
priv->fifo_size = 64;
|
|
||||||
else
|
|
||||||
priv->fifo_size = 256;
|
|
||||||
|
|
||||||
priv->skip_preamble = 0;
|
|
||||||
priv->last_transaction_us = timer_get_us();
|
|
||||||
priv->freq = plat->frequency;
|
|
||||||
priv->periph_id = plat->periph_id;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
This implementation doesn't actually touch the hardware, which is somewhat
|
|
||||||
unusual for a driver. In this case we will do that when the device is
|
|
||||||
claimed by something that wants to use the SPI bus.
|
|
||||||
|
|
||||||
For remove we could shut down the clocks, but in this case there is
|
|
||||||
nothing to do. DM frees any memory that it allocated, so we can just
|
|
||||||
remove exynos_spi_remove() and its reference in U_BOOT_DRIVER.
|
|
||||||
|
|
||||||
|
|
||||||
11. Implement set_speed()
|
|
||||||
|
|
||||||
This should set up clocks so that the SPI bus is running at the right
|
|
||||||
speed. With the old API spi_claim_bus() would normally do this and several
|
|
||||||
of the following functions, so let's look at that function:
|
|
||||||
|
|
||||||
int spi_claim_bus(struct spi_slave *slave)
|
|
||||||
{
|
|
||||||
struct exynos_spi_slave *spi_slave = to_exynos_spi(slave);
|
|
||||||
struct exynos_spi *regs = spi_slave->regs;
|
|
||||||
u32 reg = 0;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = set_spi_clk(spi_slave->periph_id,
|
|
||||||
spi_slave->freq);
|
|
||||||
if (ret < 0) {
|
|
||||||
debug("%s: Failed to setup spi clock\n", __func__);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
exynos_pinmux_config(spi_slave->periph_id, PINMUX_FLAG_NONE);
|
|
||||||
|
|
||||||
spi_flush_fifo(slave);
|
|
||||||
|
|
||||||
reg = readl(®s->ch_cfg);
|
|
||||||
reg &= ~(SPI_CH_CPHA_B | SPI_CH_CPOL_L);
|
|
||||||
|
|
||||||
if (spi_slave->mode & SPI_CPHA)
|
|
||||||
reg |= SPI_CH_CPHA_B;
|
|
||||||
|
|
||||||
if (spi_slave->mode & SPI_CPOL)
|
|
||||||
reg |= SPI_CH_CPOL_L;
|
|
||||||
|
|
||||||
writel(reg, ®s->ch_cfg);
|
|
||||||
writel(SPI_FB_DELAY_180, ®s->fb_clk);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
It sets up the speed, mode, pinmux, feedback delay and clears the FIFOs.
|
|
||||||
With DM these will happen in separate methods.
|
|
||||||
|
|
||||||
|
|
||||||
Here is an example for the speed part:
|
|
||||||
|
|
||||||
static int exynos_spi_set_speed(struct udevice *bus, uint speed)
|
|
||||||
{
|
|
||||||
struct exynos_spi_platdata *plat = bus->platdata;
|
|
||||||
struct exynos_spi_priv *priv = dev_get_priv(bus);
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (speed > plat->frequency)
|
|
||||||
speed = plat->frequency;
|
|
||||||
ret = set_spi_clk(priv->periph_id, speed);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
priv->freq = speed;
|
|
||||||
debug("%s: regs=%p, speed=%d\n", __func__, priv->regs, priv->freq);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
12. Implement set_mode()
|
|
||||||
|
|
||||||
This should adjust the SPI mode (polarity, etc.). Again this code probably
|
|
||||||
comes from the old spi_claim_bus(). Here is an example:
|
|
||||||
|
|
||||||
|
|
||||||
static int exynos_spi_set_mode(struct udevice *bus, uint mode)
|
|
||||||
{
|
|
||||||
struct exynos_spi_priv *priv = dev_get_priv(bus);
|
|
||||||
uint32_t reg;
|
|
||||||
|
|
||||||
reg = readl(&priv->regs->ch_cfg);
|
|
||||||
reg &= ~(SPI_CH_CPHA_B | SPI_CH_CPOL_L);
|
|
||||||
|
|
||||||
if (mode & SPI_CPHA)
|
|
||||||
reg |= SPI_CH_CPHA_B;
|
|
||||||
|
|
||||||
if (mode & SPI_CPOL)
|
|
||||||
reg |= SPI_CH_CPOL_L;
|
|
||||||
|
|
||||||
writel(reg, &priv->regs->ch_cfg);
|
|
||||||
priv->mode = mode;
|
|
||||||
debug("%s: regs=%p, mode=%d\n", __func__, priv->regs, priv->mode);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
13. Implement claim_bus()
|
|
||||||
|
|
||||||
This is where a client wants to make use of the bus, so claims it first.
|
|
||||||
At this point we need to make sure everything is set up ready for data
|
|
||||||
transfer. Note that this function is wholly internal to the driver - at
|
|
||||||
present the SPI uclass never calls it.
|
|
||||||
|
|
||||||
Here again we look at the old claim function and see some code that is
|
|
||||||
needed. It is anything unrelated to speed and mode:
|
|
||||||
|
|
||||||
static int exynos_spi_claim_bus(struct udevice *bus)
|
|
||||||
{
|
|
||||||
struct exynos_spi_priv *priv = dev_get_priv(bus);
|
|
||||||
|
|
||||||
exynos_pinmux_config(priv->periph_id, PINMUX_FLAG_NONE);
|
|
||||||
spi_flush_fifo(priv->regs);
|
|
||||||
|
|
||||||
writel(SPI_FB_DELAY_180, &priv->regs->fb_clk);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
The spi_flush_fifo() function is in the removed part of the code, so we
|
|
||||||
need to expose it again (perhaps with an #endif before it and '#if 0'
|
|
||||||
after it). It only needs access to priv->regs which is why we have
|
|
||||||
passed that in:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Flush spi tx, rx fifos and reset the SPI controller
|
|
||||||
*
|
|
||||||
* @param regs Pointer to SPI registers
|
|
||||||
*/
|
|
||||||
static void spi_flush_fifo(struct exynos_spi *regs)
|
|
||||||
{
|
|
||||||
clrsetbits_le32(®s->ch_cfg, SPI_CH_HS_EN, SPI_CH_RST);
|
|
||||||
clrbits_le32(®s->ch_cfg, SPI_CH_RST);
|
|
||||||
setbits_le32(®s->ch_cfg, SPI_TX_CH_ON | SPI_RX_CH_ON);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
14. Implement release_bus()
|
|
||||||
|
|
||||||
This releases the bus - in our example the old code in spi_release_bus()
|
|
||||||
is a call to spi_flush_fifo, so we add:
|
|
||||||
|
|
||||||
static int exynos_spi_release_bus(struct udevice *bus)
|
|
||||||
{
|
|
||||||
struct exynos_spi_priv *priv = dev_get_priv(bus);
|
|
||||||
|
|
||||||
spi_flush_fifo(priv->regs);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
15. Implement xfer()
|
|
||||||
|
|
||||||
This is the final method that we need to create, and it is where all the
|
|
||||||
work happens. The method parameters are the same as the old spi_xfer() with
|
|
||||||
the addition of a 'struct udevice' so conversion is pretty easy. Start
|
|
||||||
by copying the contents of spi_xfer() to your new xfer() method and proceed
|
|
||||||
from there.
|
|
||||||
|
|
||||||
If (flags & SPI_XFER_BEGIN) is non-zero then xfer() normally calls an
|
|
||||||
activate function, something like this:
|
|
||||||
|
|
||||||
void spi_cs_activate(struct spi_slave *slave)
|
|
||||||
{
|
|
||||||
struct exynos_spi_slave *spi_slave = to_exynos_spi(slave);
|
|
||||||
|
|
||||||
/* If it's too soon to do another transaction, wait */
|
|
||||||
if (spi_slave->bus->deactivate_delay_us &&
|
|
||||||
spi_slave->last_transaction_us) {
|
|
||||||
ulong delay_us; /* The delay completed so far */
|
|
||||||
delay_us = timer_get_us() - spi_slave->last_transaction_us;
|
|
||||||
if (delay_us < spi_slave->bus->deactivate_delay_us)
|
|
||||||
udelay(spi_slave->bus->deactivate_delay_us - delay_us);
|
|
||||||
}
|
|
||||||
|
|
||||||
clrbits_le32(&spi_slave->regs->cs_reg, SPI_SLAVE_SIG_INACT);
|
|
||||||
debug("Activate CS, bus %d\n", spi_slave->slave.bus);
|
|
||||||
spi_slave->skip_preamble = spi_slave->mode & SPI_PREAMBLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
The new version looks like this:
|
|
||||||
|
|
||||||
static void spi_cs_activate(struct udevice *dev)
|
|
||||||
{
|
|
||||||
struct udevice *bus = dev->parent;
|
|
||||||
struct exynos_spi_platdata *pdata = dev_get_platdata(bus);
|
|
||||||
struct exynos_spi_priv *priv = dev_get_priv(bus);
|
|
||||||
|
|
||||||
/* If it's too soon to do another transaction, wait */
|
|
||||||
if (pdata->deactivate_delay_us &&
|
|
||||||
priv->last_transaction_us) {
|
|
||||||
ulong delay_us; /* The delay completed so far */
|
|
||||||
delay_us = timer_get_us() - priv->last_transaction_us;
|
|
||||||
if (delay_us < pdata->deactivate_delay_us)
|
|
||||||
udelay(pdata->deactivate_delay_us - delay_us);
|
|
||||||
}
|
|
||||||
|
|
||||||
clrbits_le32(&priv->regs->cs_reg, SPI_SLAVE_SIG_INACT);
|
|
||||||
debug("Activate CS, bus '%s'\n", bus->name);
|
|
||||||
priv->skip_preamble = priv->mode & SPI_PREAMBLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
All we have really done here is change the pointers and print the device name
|
|
||||||
instead of the bus number. Other local static functions can be treated in
|
|
||||||
the same way.
|
|
||||||
|
|
||||||
|
|
||||||
16. Set up the per-child data and child pre-probe function
|
|
||||||
|
|
||||||
To minimise the pain and complexity of the SPI subsystem while the driver
|
|
||||||
model change-over is in place, struct spi_slave is used to reference a
|
|
||||||
SPI bus slave, even though that slave is actually a struct udevice. In fact
|
|
||||||
struct spi_slave is the device's child data. We need to make sure this space
|
|
||||||
is available. It is possible to allocate more space that struct spi_slave
|
|
||||||
needs, but this is the minimum.
|
|
||||||
|
|
||||||
U_BOOT_DRIVER(exynos_spi) = {
|
|
||||||
...
|
|
||||||
.per_child_auto_alloc_size = sizeof(struct spi_slave),
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
17. Optional: Set up cs_info() if you want it
|
|
||||||
|
|
||||||
Sometimes it is useful to know whether a SPI chip select is valid, but this
|
|
||||||
is not obvious from outside the driver. In this case you can provide a
|
|
||||||
method for cs_info() to deal with this. If you don't provide it, then the
|
|
||||||
device tree will be used to determine what chip selects are valid.
|
|
||||||
|
|
||||||
Return -ENODEV if the supplied chip select is invalid, or 0 if it is valid.
|
|
||||||
If you don't provide the cs_info() method, -ENODEV is assumed for all
|
|
||||||
chip selects that do not appear in the device tree.
|
|
||||||
|
|
||||||
|
|
||||||
18. Test it
|
|
||||||
|
|
||||||
Now that you have the code written and it compiles, try testing it using
|
|
||||||
the 'sf test' command. You may need to enable CONFIG_CMD_SF_TEST for your
|
|
||||||
board.
|
|
||||||
|
|
||||||
|
|
||||||
19. Prepare patches and send them to the mailing lists
|
|
||||||
|
|
||||||
You can use 'tools/patman/patman' to prepare, check and send patches for
|
|
||||||
your work. See the README for details.
|
|
||||||
|
|
||||||
20. A little note about SPI uclass features:
|
|
||||||
|
|
||||||
The SPI uclass keeps some information about each device 'dev' on the bus:
|
|
||||||
|
|
||||||
struct dm_spi_slave_platdata - this is device_get_parent_platdata(dev)
|
|
||||||
This is where the chip select number is stored, along with
|
|
||||||
the default bus speed and mode. It is automatically read
|
|
||||||
from the device tree in spi_child_post_bind(). It must not
|
|
||||||
be changed at run-time after being set up because platform
|
|
||||||
data is supposed to be immutable at run-time.
|
|
||||||
struct spi_slave - this is device_get_parentdata(dev)
|
|
||||||
Already mentioned above. It holds run-time information about
|
|
||||||
the device.
|
|
||||||
|
|
||||||
There are also some SPI uclass methods that get called behind the scenes:
|
|
||||||
|
|
||||||
spi_post_bind() - called when a new bus is bound
|
|
||||||
This scans the device tree for devices on the bus, and binds
|
|
||||||
each one. This in turn causes spi_child_post_bind() to be
|
|
||||||
called for each, which reads the device tree information
|
|
||||||
into the parent (per-child) platform data.
|
|
||||||
spi_child_post_bind() - called when a new child is bound
|
|
||||||
As mentioned above this reads the device tree information
|
|
||||||
into the per-child platform data
|
|
||||||
spi_child_pre_probe() - called before a new child is probed
|
|
||||||
This sets up the mode and speed in struct spi_slave by
|
|
||||||
copying it from the parent's platform data for this child.
|
|
||||||
It also sets the 'dev' pointer, needed to permit passing
|
|
||||||
'struct spi_slave' around the place without needing a
|
|
||||||
separate 'struct udevice' pointer.
|
|
||||||
|
|
||||||
The above housekeeping makes it easier to write your SPI driver.
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
.. SPDX-License-Identifier: GPL-2.0+
|
||||||
|
|
||||||
How USB works with driver model
|
How USB works with driver model
|
||||||
===============================
|
===============================
|
||||||
|
|
||||||
|
@ -24,25 +26,27 @@ Support for EHCI and XHCI
|
||||||
So far OHCI is not supported. Both EHCI and XHCI drivers should be declared
|
So far OHCI is not supported. Both EHCI and XHCI drivers should be declared
|
||||||
as drivers in the USB uclass. For example:
|
as drivers in the USB uclass. For example:
|
||||||
|
|
||||||
static const struct udevice_id ehci_usb_ids[] = {
|
.. code-block:: c
|
||||||
{ .compatible = "nvidia,tegra20-ehci", .data = USB_CTLR_T20 },
|
|
||||||
{ .compatible = "nvidia,tegra30-ehci", .data = USB_CTLR_T30 },
|
|
||||||
{ .compatible = "nvidia,tegra114-ehci", .data = USB_CTLR_T114 },
|
|
||||||
{ }
|
|
||||||
};
|
|
||||||
|
|
||||||
U_BOOT_DRIVER(usb_ehci) = {
|
static const struct udevice_id ehci_usb_ids[] = {
|
||||||
.name = "ehci_tegra",
|
{ .compatible = "nvidia,tegra20-ehci", .data = USB_CTLR_T20 },
|
||||||
.id = UCLASS_USB,
|
{ .compatible = "nvidia,tegra30-ehci", .data = USB_CTLR_T30 },
|
||||||
.of_match = ehci_usb_ids,
|
{ .compatible = "nvidia,tegra114-ehci", .data = USB_CTLR_T114 },
|
||||||
.ofdata_to_platdata = ehci_usb_ofdata_to_platdata,
|
{ }
|
||||||
.probe = tegra_ehci_usb_probe,
|
};
|
||||||
.remove = tegra_ehci_usb_remove,
|
|
||||||
.ops = &ehci_usb_ops,
|
U_BOOT_DRIVER(usb_ehci) = {
|
||||||
.platdata_auto_alloc_size = sizeof(struct usb_platdata),
|
.name = "ehci_tegra",
|
||||||
.priv_auto_alloc_size = sizeof(struct fdt_usb),
|
.id = UCLASS_USB,
|
||||||
.flags = DM_FLAG_ALLOC_PRIV_DMA,
|
.of_match = ehci_usb_ids,
|
||||||
};
|
.ofdata_to_platdata = ehci_usb_ofdata_to_platdata,
|
||||||
|
.probe = tegra_ehci_usb_probe,
|
||||||
|
.remove = tegra_ehci_usb_remove,
|
||||||
|
.ops = &ehci_usb_ops,
|
||||||
|
.platdata_auto_alloc_size = sizeof(struct usb_platdata),
|
||||||
|
.priv_auto_alloc_size = sizeof(struct fdt_usb),
|
||||||
|
.flags = DM_FLAG_ALLOC_PRIV_DMA,
|
||||||
|
};
|
||||||
|
|
||||||
Here ehci_usb_ids is used to list the controllers that the driver supports.
|
Here ehci_usb_ids is used to list the controllers that the driver supports.
|
||||||
Each has its own data value. Controllers must be in the UCLASS_USB uclass.
|
Each has its own data value. Controllers must be in the UCLASS_USB uclass.
|
||||||
|
@ -80,7 +84,7 @@ Data structures
|
||||||
|
|
||||||
The following primary data structures are in use:
|
The following primary data structures are in use:
|
||||||
|
|
||||||
- struct usb_device
|
- struct usb_device:
|
||||||
This holds information about a device on the bus. All devices have
|
This holds information about a device on the bus. All devices have
|
||||||
this structure, even the root hub. The controller itself does not
|
this structure, even the root hub. The controller itself does not
|
||||||
have this structure. You can access it for a device 'dev' with
|
have this structure. You can access it for a device 'dev' with
|
||||||
|
@ -89,19 +93,19 @@ The following primary data structures are in use:
|
||||||
handles that). Once the device is set up, you can find the device
|
handles that). Once the device is set up, you can find the device
|
||||||
descriptor and current configuration descriptor in this structure.
|
descriptor and current configuration descriptor in this structure.
|
||||||
|
|
||||||
- struct usb_platdata
|
- struct usb_platdata:
|
||||||
This holds platform data for a controller. So far this is only used
|
This holds platform data for a controller. So far this is only used
|
||||||
as a work-around for controllers which can act as USB devices in OTG
|
as a work-around for controllers which can act as USB devices in OTG
|
||||||
mode, since the gadget framework does not use driver model.
|
mode, since the gadget framework does not use driver model.
|
||||||
|
|
||||||
- struct usb_dev_platdata
|
- struct usb_dev_platdata:
|
||||||
This holds platform data for a device. You can access it for a
|
This holds platform data for a device. You can access it for a
|
||||||
device 'dev' with dev_get_parent_platdata(dev). It holds the device
|
device 'dev' with dev_get_parent_platdata(dev). It holds the device
|
||||||
address and speed - anything that can be determined before the device
|
address and speed - anything that can be determined before the device
|
||||||
driver is actually set up. When probing the bus this structure is
|
driver is actually set up. When probing the bus this structure is
|
||||||
used to provide essential information to the device driver.
|
used to provide essential information to the device driver.
|
||||||
|
|
||||||
- struct usb_bus_priv
|
- struct usb_bus_priv:
|
||||||
This is private information for each controller, maintained by the
|
This is private information for each controller, maintained by the
|
||||||
controller uclass. It is mostly used to keep track of the next
|
controller uclass. It is mostly used to keep track of the next
|
||||||
device address to use.
|
device address to use.
|
||||||
|
@ -197,49 +201,49 @@ Device initialisation happens roughly like this:
|
||||||
- This calls usb_init() which works through each controller in turn
|
- This calls usb_init() which works through each controller in turn
|
||||||
- The controller is probed(). This does no enumeration.
|
- The controller is probed(). This does no enumeration.
|
||||||
- Then usb_scan_bus() is called. This calls usb_scan_device() to scan the
|
- Then usb_scan_bus() is called. This calls usb_scan_device() to scan the
|
||||||
(only) device that is attached to the controller - a root hub
|
(only) device that is attached to the controller - a root hub
|
||||||
- usb_scan_device() sets up a fake struct usb_device and calls
|
- usb_scan_device() sets up a fake struct usb_device and calls
|
||||||
usb_setup_device(), passing the port number to be scanned, in this case port
|
usb_setup_device(), passing the port number to be scanned, in this case
|
||||||
0
|
port 0
|
||||||
- usb_setup_device() first calls usb_prepare_device() to set the device
|
- usb_setup_device() first calls usb_prepare_device() to set the device
|
||||||
address, then usb_select_config() to select the first configuration
|
address, then usb_select_config() to select the first configuration
|
||||||
- at this point the device is enumerated but we do not have a real struct
|
- at this point the device is enumerated but we do not have a real struct
|
||||||
udevice for it. But we do have the descriptor in struct usb_device so we can
|
udevice for it. But we do have the descriptor in struct usb_device so we can
|
||||||
use this to figure out what driver to use
|
use this to figure out what driver to use
|
||||||
- back in usb_scan_device(), we call usb_find_child() to try to find an
|
- back in usb_scan_device(), we call usb_find_child() to try to find an
|
||||||
existing device which matches the one we just found on the bus. This can
|
existing device which matches the one we just found on the bus. This can
|
||||||
happen if the device is mentioned in the device tree, or if we previously
|
happen if the device is mentioned in the device tree, or if we previously
|
||||||
scanned the bus and so the device was created before
|
scanned the bus and so the device was created before
|
||||||
- if usb_find_child() does not find an existing device, we call
|
- if usb_find_child() does not find an existing device, we call
|
||||||
usb_find_and_bind_driver() which tries to bind one
|
usb_find_and_bind_driver() which tries to bind one
|
||||||
- usb_find_and_bind_driver() searches all available USB drivers (declared
|
- usb_find_and_bind_driver() searches all available USB drivers (declared
|
||||||
with USB_DEVICE()). If it finds a match it binds that driver to create a new
|
with USB_DEVICE()). If it finds a match it binds that driver to create a
|
||||||
device.
|
new device.
|
||||||
- If it does not, it binds a generic driver. A generic driver is good enough
|
- If it does not, it binds a generic driver. A generic driver is good enough
|
||||||
to allow access to the device (sending it packets, etc.) but all
|
to allow access to the device (sending it packets, etc.) but all
|
||||||
functionality will need to be implemented outside the driver model.
|
functionality will need to be implemented outside the driver model.
|
||||||
- in any case, when usb_find_child() and/or usb_find_and_bind_driver() are
|
- in any case, when usb_find_child() and/or usb_find_and_bind_driver() are
|
||||||
done, we have a device with the correct uclass. At this point we want to
|
done, we have a device with the correct uclass. At this point we want to
|
||||||
probe the device
|
probe the device
|
||||||
- first we store basic information about the new device (address, port,
|
- first we store basic information about the new device (address, port,
|
||||||
speed) in its parent platform data. We cannot store it its private data
|
speed) in its parent platform data. We cannot store it its private data
|
||||||
since that will not exist until the device is probed.
|
since that will not exist until the device is probed.
|
||||||
- then we call device_probe() which probes the device
|
- then we call device_probe() which probes the device
|
||||||
- the first probe step is actually the USB controller's (or USB hubs's)
|
- the first probe step is actually the USB controller's (or USB hubs's)
|
||||||
child_pre_probe() method. This gets called before anything else and is
|
child_pre_probe() method. This gets called before anything else and is
|
||||||
intended to set up a child device ready to be used with its parent bus. For
|
intended to set up a child device ready to be used with its parent bus. For
|
||||||
USB this calls usb_child_pre_probe() which grabs the information that was
|
USB this calls usb_child_pre_probe() which grabs the information that was
|
||||||
stored in the parent platform data and stores it in the parent private data
|
stored in the parent platform data and stores it in the parent private data
|
||||||
(which is struct usb_device, a real one this time). It then calls
|
(which is struct usb_device, a real one this time). It then calls
|
||||||
usb_select_config() again to make sure that everything about the device is
|
usb_select_config() again to make sure that everything about the device is
|
||||||
set up
|
set up
|
||||||
- note that we have called usb_select_config() twice. This is inefficient
|
- note that we have called usb_select_config() twice. This is inefficient
|
||||||
but the alternative is to store additional information in the platform data.
|
but the alternative is to store additional information in the platform data.
|
||||||
The time taken is minimal and this way is simpler
|
The time taken is minimal and this way is simpler
|
||||||
- at this point the device is set up and ready for use so far as the USB
|
- at this point the device is set up and ready for use so far as the USB
|
||||||
subsystem is concerned
|
subsystem is concerned
|
||||||
- the device's probe() method is then called. It can send messages and do
|
- the device's probe() method is then called. It can send messages and do
|
||||||
whatever else it wants to make the device work.
|
whatever else it wants to make the device work.
|
||||||
|
|
||||||
Note that the first device is always a root hub, and this must be scanned to
|
Note that the first device is always a root hub, and this must be scanned to
|
||||||
find any devices. The above steps will have created a hub (UCLASS_USB_HUB),
|
find any devices. The above steps will have created a hub (UCLASS_USB_HUB),
|
||||||
|
@ -250,25 +254,25 @@ any hub is probed, the uclass gets to do some processing. In this case
|
||||||
usb_hub_post_probe() is called, and the following steps take place:
|
usb_hub_post_probe() is called, and the following steps take place:
|
||||||
|
|
||||||
- usb_hub_post_probe() calls usb_hub_scan() to scan the hub, which in turn
|
- usb_hub_post_probe() calls usb_hub_scan() to scan the hub, which in turn
|
||||||
calls usb_hub_configure()
|
calls usb_hub_configure()
|
||||||
- hub power is enabled
|
- hub power is enabled
|
||||||
- we loop through each port on the hub, performing the same steps for each
|
- we loop through each port on the hub, performing the same steps for each
|
||||||
- first, check if there is a device present. This happens in
|
- first, check if there is a device present. This happens in
|
||||||
usb_hub_port_connect_change(). If so, then usb_scan_device() is called to
|
usb_hub_port_connect_change(). If so, then usb_scan_device() is called to
|
||||||
scan the device, passing the appropriate port number.
|
scan the device, passing the appropriate port number.
|
||||||
- you will recognise usb_scan_device() from the steps above. It sets up the
|
- you will recognise usb_scan_device() from the steps above. It sets up the
|
||||||
device ready for use. If it is a hub, it will scan that hub before it
|
device ready for use. If it is a hub, it will scan that hub before it
|
||||||
continues here (recursively, depth-first)
|
continues here (recursively, depth-first)
|
||||||
- once all hub ports are scanned in this way, the hub is ready for use and
|
- once all hub ports are scanned in this way, the hub is ready for use and
|
||||||
all of its downstream devices also
|
all of its downstream devices also
|
||||||
- additional controllers are scanned in the same way
|
- additional controllers are scanned in the same way
|
||||||
|
|
||||||
The above method has some nice properties:
|
The above method has some nice properties:
|
||||||
|
|
||||||
- the bus enumeration happens by virtue of driver model's natural device flow
|
- the bus enumeration happens by virtue of driver model's natural device flow
|
||||||
- most logic is in the USB controller and hub uclasses; the actual device
|
- most logic is in the USB controller and hub uclasses; the actual device
|
||||||
drivers do not need to know they are on a USB bus, at least so far as
|
drivers do not need to know they are on a USB bus, at least so far as
|
||||||
enumeration goes
|
enumeration goes
|
||||||
- hub scanning happens automatically after a hub is probed
|
- hub scanning happens automatically after a hub is probed
|
||||||
|
|
||||||
|
|
||||||
|
@ -279,9 +283,9 @@ USB hubs are scanned as in the section above. While hubs have their own
|
||||||
uclass, they share some common elements with controllers:
|
uclass, they share some common elements with controllers:
|
||||||
|
|
||||||
- they both attach private data to their children (struct usb_device,
|
- they both attach private data to their children (struct usb_device,
|
||||||
accessible for a child with dev_get_parent_priv(child))
|
accessible for a child with dev_get_parent_priv(child))
|
||||||
- they both use usb_child_pre_probe() to set up their children as proper USB
|
- they both use usb_child_pre_probe() to set up their children as proper USB
|
||||||
devices
|
devices
|
||||||
|
|
||||||
|
|
||||||
Example - Mass Storage
|
Example - Mass Storage
|
||||||
|
@ -290,20 +294,22 @@ Example - Mass Storage
|
||||||
As an example of a USB device driver, see usb_storage.c. It uses its own
|
As an example of a USB device driver, see usb_storage.c. It uses its own
|
||||||
uclass and declares itself as follows:
|
uclass and declares itself as follows:
|
||||||
|
|
||||||
U_BOOT_DRIVER(usb_mass_storage) = {
|
.. code-block:: c
|
||||||
.name = "usb_mass_storage",
|
|
||||||
.id = UCLASS_MASS_STORAGE,
|
|
||||||
.of_match = usb_mass_storage_ids,
|
|
||||||
.probe = usb_mass_storage_probe,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct usb_device_id mass_storage_id_table[] = {
|
U_BOOT_DRIVER(usb_mass_storage) = {
|
||||||
{ .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
|
.name = "usb_mass_storage",
|
||||||
.bInterfaceClass = USB_CLASS_MASS_STORAGE},
|
.id = UCLASS_MASS_STORAGE,
|
||||||
{ } /* Terminating entry */
|
.of_match = usb_mass_storage_ids,
|
||||||
};
|
.probe = usb_mass_storage_probe,
|
||||||
|
};
|
||||||
|
|
||||||
USB_DEVICE(usb_mass_storage, mass_storage_id_table);
|
static const struct usb_device_id mass_storage_id_table[] = {
|
||||||
|
{ .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
|
||||||
|
.bInterfaceClass = USB_CLASS_MASS_STORAGE},
|
||||||
|
{ } /* Terminating entry */
|
||||||
|
};
|
||||||
|
|
||||||
|
USB_DEVICE(usb_mass_storage, mass_storage_id_table);
|
||||||
|
|
||||||
The USB_DEVICE() macro attaches the given table of matching information to
|
The USB_DEVICE() macro attaches the given table of matching information to
|
||||||
the given driver. Note that the driver is declared in U_BOOT_DRIVER() as
|
the given driver. Note that the driver is declared in U_BOOT_DRIVER() as
|
||||||
|
@ -347,6 +353,8 @@ stack to be tested without real hardware being needed.
|
||||||
|
|
||||||
Here is an example device tree fragment:
|
Here is an example device tree fragment:
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
usb@1 {
|
usb@1 {
|
||||||
compatible = "sandbox,usb";
|
compatible = "sandbox,usb";
|
||||||
hub {
|
hub {
|
||||||
|
@ -369,13 +377,13 @@ This defines a single controller, containing a root hub (which is required).
|
||||||
The hub is emulated by a hub emulator, and the emulated hub has a single
|
The hub is emulated by a hub emulator, and the emulated hub has a single
|
||||||
flash stick to emulate on one of its ports.
|
flash stick to emulate on one of its ports.
|
||||||
|
|
||||||
When 'usb start' is used, the following 'dm tree' output will be available:
|
When 'usb start' is used, the following 'dm tree' output will be available::
|
||||||
|
|
||||||
usb [ + ] `-- usb@1
|
usb [ + ] `-- usb@1
|
||||||
usb_hub [ + ] `-- hub
|
usb_hub [ + ] `-- hub
|
||||||
usb_emul [ + ] |-- hub-emul
|
usb_emul [ + ] |-- hub-emul
|
||||||
usb_emul [ + ] | `-- flash-stick
|
usb_emul [ + ] | `-- flash-stick
|
||||||
usb_mass_st [ + ] `-- usb_mass_storage
|
usb_mass_st [ + ] `-- usb_mass_storage
|
||||||
|
|
||||||
|
|
||||||
This may look confusing. Most of it mirrors the device tree, but the
|
This may look confusing. Most of it mirrors the device tree, but the
|
||||||
|
@ -393,12 +401,12 @@ embedded system. In fact anything other than a root hub is uncommon. Still
|
||||||
it would be possible to speed up enumeration in two ways:
|
it would be possible to speed up enumeration in two ways:
|
||||||
|
|
||||||
- breadth-first search would allow devices to be reset and probed in
|
- breadth-first search would allow devices to be reset and probed in
|
||||||
parallel to some extent
|
parallel to some extent
|
||||||
- enumeration could be lazy, in the sense that we could enumerate just the
|
- enumeration could be lazy, in the sense that we could enumerate just the
|
||||||
root hub at first, then only progress to the next 'level' when a device is
|
root hub at first, then only progress to the next 'level' when a device is
|
||||||
used that we cannot find. This could be made easier if the devices were
|
used that we cannot find. This could be made easier if the devices were
|
||||||
statically declared in the device tree (which is acceptable for production
|
statically declared in the device tree (which is acceptable for production
|
||||||
boards where the same, known, things are on each bus).
|
boards where the same, known, things are on each bus).
|
||||||
|
|
||||||
But in common cases the current algorithm is sufficient.
|
But in common cases the current algorithm is sufficient.
|
||||||
|
|
||||||
|
@ -410,6 +418,6 @@ Other things that need doing:
|
||||||
- Implement USB PHYs in driver model
|
- Implement USB PHYs in driver model
|
||||||
- Work out a clever way to provide lazy init for USB devices
|
- Work out a clever way to provide lazy init for USB devices
|
||||||
|
|
||||||
--
|
|
||||||
Simon Glass <sjg@chromium.org>
|
.. Simon Glass <sjg@chromium.org>
|
||||||
23-Mar-15
|
.. 23-Mar-15
|
|
@ -1,11 +1,68 @@
|
||||||
.. SPDX-License-Identifier: GPL-2.0+
|
.. SPDX-License-Identifier: GPL-2.0+
|
||||||
|
|
||||||
#######################
|
.. _u-boot_doc:
|
||||||
U-Boot Developer Manual
|
|
||||||
#######################
|
The U-Boot Documentation
|
||||||
|
========================
|
||||||
|
|
||||||
|
This is the top level of the U-Boot's documentation tree. U-Boot
|
||||||
|
documentation, like the U-Boot itself, is very much a work in progress;
|
||||||
|
that is especially true as we work to integrate our many scattered
|
||||||
|
documents into a coherent whole. Please note that improvements to the
|
||||||
|
documentation are welcome; join the U-Boot list at http://lists.denx.de
|
||||||
|
if you want to help out.
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
|
:maxdepth: 2
|
||||||
|
|
||||||
efi
|
Driver-Model documentation
|
||||||
linker_lists
|
--------------------------
|
||||||
serial
|
The following holds information on the U-Boot device driver framework:
|
||||||
|
driver-model, including the design details of itself and several driver
|
||||||
|
subsystems.
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 2
|
||||||
|
|
||||||
|
driver-model/index
|
||||||
|
|
||||||
|
U-Boot API documentation
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
These books get into the details of how specific U-Boot subsystems work
|
||||||
|
from the point of view of a U-Boot developer. Much of the information here
|
||||||
|
is taken directly from the U-Boot source, with supplemental material added
|
||||||
|
as needed (or at least as we managed to add it - probably *not* all that is
|
||||||
|
needed).
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 2
|
||||||
|
|
||||||
|
api/index
|
||||||
|
|
||||||
|
Architecture-specific doc
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
These books provide programming details about architecture-specific
|
||||||
|
implementation.
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 2
|
||||||
|
|
||||||
|
arch/index
|
||||||
|
|
||||||
|
Board-specific doc
|
||||||
|
------------------
|
||||||
|
|
||||||
|
These books provide details about board-specific information. They are
|
||||||
|
organized in a vendor subdirectory.
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 2
|
||||||
|
|
||||||
|
board/index
|
||||||
|
|
||||||
|
Indices and tables
|
||||||
|
==================
|
||||||
|
|
||||||
|
* :ref:`genindex`
|
||||||
|
|
Loading…
Add table
Reference in a new issue