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
|
||||
that SoC designers can optimize for a wide range of uses, from deeply embedded
|
||||
to high-performance host applications.
|
|
@ -1,14 +1,17 @@
|
|||
U-Boot for arm64
|
||||
.. SPDX-License-Identifier: GPL-2.0+
|
||||
|
||||
ARM64
|
||||
=====
|
||||
|
||||
Summary
|
||||
=======
|
||||
-------
|
||||
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.
|
||||
These days U-Boot runs on a variety of 64-bit capable ARM hardware, from
|
||||
embedded development boards to servers.
|
||||
|
||||
Notes
|
||||
=====
|
||||
-----
|
||||
|
||||
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
|
||||
|
@ -46,11 +49,11 @@ Notes
|
|||
|
||||
|
||||
Contributors
|
||||
============
|
||||
Tom Rini <trini@ti.com>
|
||||
Scott Wood <scottwood@freescale.com>
|
||||
York Sun <yorksun@freescale.com>
|
||||
Simon Glass <sjg@chromium.org>
|
||||
Sharma Bhupesh <bhupesh.sharma@freescale.com>
|
||||
Rob Herring <robherring2@gmail.com>
|
||||
Sergey Temerkhanov <s.temerkhanov@gmail.com>
|
||||
------------
|
||||
* Tom Rini <trini@ti.com>
|
||||
* Scott Wood <scottwood@freescale.com>
|
||||
* York Sun <yorksun@freescale.com>
|
||||
* Simon Glass <sjg@chromium.org>
|
||||
* Sharma Bhupesh <bhupesh.sharma@freescale.com>
|
||||
* Rob Herring <robherring2@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
|
||||
|
||||
Toolchains
|
||||
----------
|
||||
|
||||
http://www.denx.de/wiki/DULG/ELDK
|
||||
ELDK < DULG < DENX
|
||||
|
||||
http://www.emdebian.org/crosstools.html
|
||||
Embedded Debian -- Cross-development toolchains
|
||||
|
||||
http://buildroot.uclibc.org/
|
||||
Buildroot
|
||||
* `ELDK < DULG < DENX <http://www.denx.de/wiki/DULG/ELDK>`_
|
||||
* `Embedded Debian -- Cross-development toolchains <http://www.emdebian.org/crosstools.html>`_
|
||||
* `Buildroot <http://buildroot.uclibc.org/>`_
|
||||
|
||||
Known Issues
|
||||
------------
|
||||
|
@ -24,9 +23,9 @@ Known Issues
|
|||
re-initializes the cache. The more common uImage 'bootm' command does
|
||||
not suffer this problem.
|
||||
|
||||
[workaround] To avoid this cache incoherency,
|
||||
1) insert flush_cache(all) before calling dcache_disable(), or
|
||||
2) fix dcache_disable() to do both flushing and disabling cache.
|
||||
[workaround] To avoid this cache incoherency:
|
||||
- insert flush_cache(all) before calling dcache_disable(), or
|
||||
- fix dcache_disable() to do both flushing and disabling cache.
|
||||
|
||||
* 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
|
||||
|
@ -36,19 +35,12 @@ TODOs
|
|||
-----
|
||||
|
||||
* Probe CPU types, I-/D-cache and TLB size etc. automatically
|
||||
|
||||
* Secondary cache support missing
|
||||
|
||||
* Initialize TLB entries redardless of their use
|
||||
|
||||
* R2000/R3000 class parts are not supported
|
||||
|
||||
* Limited testing across different MIPS variants
|
||||
|
||||
* Due to cache initialization issues, the DRAM on board must be
|
||||
initialized in board specific assembler language before the cache init
|
||||
code is run -- that is, initialize the DRAM in lowlevel_init().
|
||||
|
||||
* centralize/share more CPU code of MIPS32, MIPS64 and XBurst
|
||||
|
||||
* 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
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
three files.
|
||||
|
||||
1. The device tree source which describes the hardware, dts file.
|
||||
arch/nios2/dts/mysystem.dts
|
||||
1. The device tree source which describes the hardware, dts file:
|
||||
arch/nios2/dts/mysystem.dts
|
||||
|
||||
2. Default configuration of Kconfig, defconfig file.
|
||||
configs/mysystem_defconfig
|
||||
2. Default configuration of Kconfig, defconfig file:
|
||||
configs/mysystem_defconfig
|
||||
|
||||
3. The legacy board header file.
|
||||
include/configs/mysystem.h
|
||||
3. The legacy board header file:
|
||||
include/configs/mysystem.h
|
||||
|
||||
The device tree source must be generated from your qsys/sopc design
|
||||
using the sopc2dts tool. Then modified to fit your configuration. Please
|
||||
find the sopc2dts download and usage at the wiki,
|
||||
using the sopc2dts tool. Then modified to fit your configuration.
|
||||
|
||||
Please find the sopc2dts download and usage at the wiki:
|
||||
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
|
||||
example at, arch/nios2/dts/10m50_devboard.dts.
|
||||
|
||||
1. Add "stdout-path=..." property with your serial path to the chosen
|
||||
node, like this,
|
||||
node, like this::
|
||||
|
||||
chosen {
|
||||
stdout-path = &uart_0;
|
||||
};
|
||||
|
||||
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 {
|
||||
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
|
||||
10m50_defconfig, modify the options and save it.
|
||||
|
||||
$ make 10m50_defconfig
|
||||
$ make menuconfig
|
||||
$ make savedefconfig
|
||||
$ cp defconfig configs/mysystem_defconfig
|
||||
.. code-block:: none
|
||||
|
||||
$ make 10m50_defconfig
|
||||
$ make menuconfig
|
||||
$ make savedefconfig
|
||||
$ cp defconfig configs/mysystem_defconfig
|
||||
|
||||
You will need to change the names of board header file and device tree,
|
||||
and select the drivers with menuconfig.
|
||||
|
||||
Nios II architecture --->
|
||||
(mysystem) Board header file
|
||||
Device Tree Control --->
|
||||
(mysystem) Default Device Tree for DT control
|
||||
.. code-block:: none
|
||||
|
||||
Nios II architecture --->
|
||||
(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
|
||||
Tree Control menu.
|
||||
|
||||
( ) 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.
|
||||
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.
|
||||
* 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.
|
||||
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.
|
||||
|
||||
( ) 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.
|
||||
* 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.
|
||||
|
||||
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
|
||||
should be cached virtual address, for Nios II with MMU it is 0xCxxx_xxxx
|
||||
to 0xDxxx_xxxx.
|
||||
|
||||
#define CONFIG_SYS_SDRAM_BASE 0xc8000000
|
||||
#define CONFIG_SYS_SDRAM_SIZE 0x08000000
|
||||
.. code-block:: c
|
||||
|
||||
#define CONFIG_SYS_SDRAM_BASE 0xc8000000
|
||||
#define CONFIG_SYS_SDRAM_SIZE 0x08000000
|
||||
|
||||
You will need to change the environment variables location and setting,
|
||||
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-)
|
||||
$ make mysystem_defconfig
|
||||
$ make
|
||||
$ export CROSS_COMPILE=nios2-elf- (or nios2-linux-gnu-)
|
||||
$ make mysystem_defconfig
|
||||
$ make
|
||||
|
||||
Enjoy!
|
|
@ -1,10 +1,12 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright (c) 2014 The Chromium OS Authors.
|
||||
*/
|
||||
.. SPDX-License-Identifier: GPL-2.0+ */
|
||||
.. Copyright (c) 2014 The Chromium OS Authors.
|
||||
.. sectionauthor:: Simon Glass <sjg@chromium.org>
|
||||
|
||||
Sandbox
|
||||
=======
|
||||
|
||||
Native Execution of U-Boot
|
||||
==========================
|
||||
--------------------------
|
||||
|
||||
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)
|
||||
|
@ -35,33 +37,31 @@ Note that standalone/API support is not available at present.
|
|||
Basic Operation
|
||||
---------------
|
||||
|
||||
To run sandbox U-Boot use something like:
|
||||
To run sandbox U-Boot use something like::
|
||||
|
||||
make sandbox_defconfig all
|
||||
./u-boot
|
||||
|
||||
Note:
|
||||
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
|
||||
build sandbox without SDL (i.e. no display/keyboard support) by removing
|
||||
the CONFIG_SANDBOX_SDL line in include/configs/sandbox.h or using:
|
||||
Note: 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
|
||||
build sandbox without SDL (i.e. no display/keyboard support) by removing
|
||||
the CONFIG_SANDBOX_SDL line in include/configs/sandbox.h or using::
|
||||
|
||||
make sandbox_defconfig all NO_SDL=1
|
||||
./u-boot
|
||||
make sandbox_defconfig all NO_SDL=1
|
||||
./u-boot
|
||||
|
||||
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
|
||||
Using default environment
|
||||
|
||||
In: serial
|
||||
Out: lcd
|
||||
Err: lcd
|
||||
=>
|
||||
In: serial
|
||||
Out: lcd
|
||||
Err: lcd
|
||||
=>
|
||||
|
||||
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.
|
||||
|
@ -73,7 +73,7 @@ Console / LCD support
|
|||
---------------------
|
||||
|
||||
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
|
||||
|
||||
|
@ -198,18 +198,23 @@ Sandbox Variants
|
|||
|
||||
There are unfortunately quite a few variants at present:
|
||||
|
||||
sandbox - should be used for most tests
|
||||
sandbox64 - special build that forces a 64-bit host
|
||||
sandbox_flattree - builds with dev_read_...() functions defined as inline.
|
||||
We need this build so that we can test those inline functions, and we
|
||||
cannot build with both the inline functions and the non-inline functions
|
||||
since they are named the same.
|
||||
sandbox_noblk - builds without CONFIG_BLK, which means the legacy block
|
||||
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.
|
||||
sandbox:
|
||||
should be used for most tests
|
||||
sandbox64:
|
||||
special build that forces a 64-bit host
|
||||
sandbox_flattree:
|
||||
builds with dev_read\_...() functions defined as inline.
|
||||
We need this build so that we can test those inline functions, and we
|
||||
cannot build with both the inline functions and the non-inline functions
|
||||
since they are named the same.
|
||||
sandbox_noblk:
|
||||
builds without CONFIG_BLK, which means the legacy block
|
||||
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
|
||||
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.
|
||||
|
||||
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
|
||||
host machine whose alias is "eth1". The following are a few examples of network
|
||||
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
|
||||
setenv ethrotate no
|
||||
setenv ethact eth1
|
||||
dhcp
|
||||
DHCP
|
||||
....
|
||||
|
||||
PING
|
||||
....
|
||||
setenv autoload no
|
||||
setenv ethrotate no
|
||||
setenv ethact eth1
|
||||
dhcp
|
||||
|
||||
setenv autoload no
|
||||
setenv ethrotate no
|
||||
setenv ethact eth1
|
||||
dhcp
|
||||
ping $gatewayip
|
||||
PING
|
||||
....
|
||||
|
||||
TFTP
|
||||
....
|
||||
setenv autoload no
|
||||
setenv ethrotate no
|
||||
setenv ethact eth1
|
||||
dhcp
|
||||
ping $gatewayip
|
||||
|
||||
setenv autoload no
|
||||
setenv ethrotate no
|
||||
setenv ethact eth1
|
||||
dhcp
|
||||
setenv serverip WWW.XXX.YYY.ZZZ
|
||||
tftpboot u-boot.bin
|
||||
TFTP
|
||||
....
|
||||
|
||||
setenv autoload no
|
||||
setenv ethrotate no
|
||||
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'.
|
||||
|
||||
|
@ -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
|
||||
operation being tested on the lo interface.
|
||||
|
||||
TFTP
|
||||
....
|
||||
.. code-block:: none
|
||||
|
||||
setenv ethrotate no
|
||||
setenv ethact eth5
|
||||
tftpboot u-boot.bin
|
||||
TFTP
|
||||
....
|
||||
|
||||
setenv ethrotate no
|
||||
setenv ethact eth5
|
||||
tftpboot u-boot.bin
|
||||
|
||||
|
||||
SPI Emulation
|
||||
|
@ -300,7 +309,7 @@ SPI 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
|
||||
|
||||
|
@ -309,24 +318,23 @@ This is controlled by the spi_sf argument, the format of which is:
|
|||
device - SPI device emulation name
|
||||
file - File on disk containing the data
|
||||
|
||||
For example:
|
||||
For example::
|
||||
|
||||
dd if=/dev/zero of=spi.bin bs=1M count=4
|
||||
./u-boot --spi_sf 0:0:M25P16:spi.bin
|
||||
dd if=/dev/zero of=spi.bin bs=1M count=4
|
||||
./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: Detected M25P16 with page size 64 KiB, total 2 MiB
|
||||
=>sf read 0 0 10000
|
||||
SF: 65536 bytes @ 0x0 Read: OK
|
||||
=>
|
||||
=>sf probe
|
||||
SF: Detected M25P16 with page size 64 KiB, total 2 MiB
|
||||
=>sf read 0 0 10000
|
||||
SF: 65536 bytes @ 0x0 Read: OK
|
||||
|
||||
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
|
||||
FF202015
|
||||
=>sspi 0:0 32 9f
|
||||
FF202015
|
||||
|
||||
This is issuing a READ_ID command and getting back 20 (ST Micro) part
|
||||
0x2015 (the M25P16).
|
||||
|
@ -338,15 +346,14 @@ for each driver.
|
|||
|
||||
Configuration settings for the curious are:
|
||||
|
||||
CONFIG_SANDBOX_SPI_MAX_BUS
|
||||
The maximum number of SPI buses supported by the driver (default 1).
|
||||
CONFIG_SANDBOX_SPI_MAX_BUS:
|
||||
The maximum number of SPI buses supported by the driver (default 1).
|
||||
|
||||
CONFIG_SANDBOX_SPI_MAX_CS
|
||||
The maximum number of chip selects supported by the driver
|
||||
(default 10).
|
||||
CONFIG_SANDBOX_SPI_MAX_CS:
|
||||
The maximum number of chip selects supported by the driver (default 10).
|
||||
|
||||
CONFIG_SPI_IDLE_VAL
|
||||
The idle value on the SPI bus
|
||||
CONFIG_SPI_IDLE_VAL:
|
||||
The idle value on the SPI bus
|
||||
|
||||
|
||||
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
|
||||
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
|
||||
=>ls host 0:2
|
||||
=>host bind 0 ./disk.raw
|
||||
=>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
|
||||
$> echo -e "label: gpt\n,64M,U\n,,L" | /usr/sbin/sgdisk ./disk.raw
|
||||
$> lodev=`sudo losetup -P -f --show ./disk.raw`
|
||||
$> sudo mkfs.vfat -n EFI -v ${lodev}p1
|
||||
$> sudo mkfs.ext4 -L ROOT -v ${lodev}p2
|
||||
$> truncate -s 1200M ./disk.raw
|
||||
$> echo -e "label: gpt\n,64M,U\n,,L" | /usr/sbin/sgdisk ./disk.raw
|
||||
$> lodev=`sudo losetup -P -f --show ./disk.raw`
|
||||
$> sudo mkfs.vfat -n EFI -v ${lodev}p1
|
||||
$> 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
|
||||
import make_test_disk
|
||||
|
@ -395,16 +402,16 @@ space. See existing code for examples.
|
|||
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)
|
||||
|
||||
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
|
||||
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
|
||||
...
|
||||
|
@ -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
|
||||
board_init_f() and board_init_r().
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
(gdb) r
|
||||
Starting program: /tmp/b/sandbox/u-boot
|
||||
[Thread debugging using libthread_db enabled]
|
||||
|
@ -445,13 +454,13 @@ environment variable to the correct pathname before building U-Boot.
|
|||
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
|
||||
|
||||
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
|
||||
fix this, use:
|
||||
fix this, use::
|
||||
|
||||
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/
|
||||
directory. These include:
|
||||
|
||||
command_ut
|
||||
- Unit tests for command parsing and handling
|
||||
compression
|
||||
- Unit tests for U-Boot's compression algorithms, useful for
|
||||
security checking. It supports gzip, bzip2, lzma and lzo.
|
||||
driver model
|
||||
- Run this pytest
|
||||
./test/py/test.py --bd sandbox --build -k ut_dm -v
|
||||
image
|
||||
- Unit tests for images:
|
||||
test/image/test-imagetools.sh - multi-file images
|
||||
test/image/test-fit.py - FIT images
|
||||
tracing
|
||||
- test/trace/test-trace.sh tests the tracing system (see README.trace)
|
||||
verified boot
|
||||
- See test/vboot/vboot_test.sh for this
|
||||
command_ut:
|
||||
Unit tests for command parsing and handling
|
||||
compression:
|
||||
Unit tests for U-Boot's compression algorithms, useful for
|
||||
security checking. It supports gzip, bzip2, lzma and lzo.
|
||||
driver model:
|
||||
Run this pytest::
|
||||
|
||||
./test/py/test.py --bd sandbox --build -k ut_dm -v
|
||||
|
||||
image:
|
||||
Unit tests for images:
|
||||
test/image/test-imagetools.sh - multi-file images
|
||||
test/image/test-fit.py - FIT images
|
||||
tracing:
|
||||
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
|
||||
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
|
||||
that are mapped into that memory:
|
||||
|
||||
======= ======================== ===============================
|
||||
Addr Config Usage
|
||||
======= ======================== ===============================
|
||||
0 CONFIG_SYS_FDT_LOAD_ADDR Device tree
|
||||
e000 CONFIG_BLOBLIST_ADDR Blob list
|
||||
10000 CONFIG_MALLOC_F_ADDR Early memory allocation
|
||||
f0000 CONFIG_PRE_CON_BUF_ADDR Pre-console buffer
|
||||
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
|
||||
-------------------------------------
|
||||
|
@ -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 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.
|
||||
|
||||
tie.h Co-processors and custom extensions defined
|
||||
in the Tensilica Instruction Extension (TIE)
|
||||
language.
|
||||
tie-asm.h Assembly macros to access custom-defined registers
|
||||
and states.
|
||||
tie.h:
|
||||
Co-processors and custom extensions defined in the Tensilica Instruction
|
||||
Extension (TIE) language.
|
||||
tie-asm.h:
|
||||
Assembly macros to access custom-defined registers and states.
|
||||
|
||||
|
||||
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.
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Chris Zankel
|
||||
Ross Morley
|
||||
.. Chris Zankel
|
||||
.. 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
|
||||
with FPU and DDR contoller support.
|
||||
AG101P has integrated both AHB and APB bus and many periphals for application
|
||||
and product development.
|
||||
|
||||
ADP-AG101P
|
||||
=========
|
||||
|
||||
ADP-AG101P is the SoC with AG101 hardcore CPU.
|
||||
|
||||
Configurations
|
||||
==============
|
||||
--------------
|
||||
|
||||
CONFIG_MEM_REMAP:
|
||||
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".
|
||||
|
||||
Build and boot steps
|
||||
====================
|
||||
--------------------
|
||||
|
||||
Build:
|
||||
|
||||
build:
|
||||
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.
|
||||
|
||||
Burn u-boot to SPI ROM:
|
||||
====================
|
||||
Burn U-Boot to SPI ROM
|
||||
----------------------
|
||||
|
||||
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+
|
||||
#
|
||||
# Copyright (C) 2017, Tuomas Tynkkynen <tuomas.tynkkynen@iki.fi>
|
||||
.. SPDX-License-Identifier: GPL-2.0+
|
||||
.. 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
|
||||
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:
|
||||
|
||||
- For ARM:
|
||||
- For ARM::
|
||||
|
||||
make qemu_arm_defconfig
|
||||
make
|
||||
|
||||
- For AArch64:
|
||||
- For AArch64::
|
||||
|
||||
make qemu_arm64_defconfig
|
||||
make
|
||||
|
||||
|
@ -38,31 +39,44 @@ Running U-Boot
|
|||
--------------
|
||||
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
|
||||
|
||||
- For AArch64:
|
||||
- For AArch64::
|
||||
|
||||
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
|
||||
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:
|
||||
- Create envstore.img using qemu-img:
|
||||
|
||||
- Create envstore.img using qemu-img::
|
||||
|
||||
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
|
||||
|
||||
Additional peripherals that have been tested to work in both U-Boot and Linux
|
||||
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
|
||||
- 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
|
||||
- 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
|
||||
- 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
|
||||
|
||||
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+
|
||||
#
|
||||
# Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
|
||||
.. SPDX-License-Identifier: GPL-2.0+
|
||||
.. 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
|
||||
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:
|
||||
|
||||
- For 32-bit RISC-V:
|
||||
- For 32-bit RISC-V::
|
||||
|
||||
make qemu-riscv32_defconfig
|
||||
make
|
||||
|
||||
- For 64-bit RISC-V:
|
||||
- For 64-bit RISC-V::
|
||||
|
||||
make qemu-riscv64_defconfig
|
||||
make
|
||||
|
||||
|
@ -31,10 +32,12 @@ Running U-Boot
|
|||
--------------
|
||||
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
|
||||
|
||||
- For 64-bit RISC-V:
|
||||
- For 64-bit RISC-V::
|
||||
|
||||
qemu-system-riscv64 -nographic -machine virt -kernel u-boot
|
||||
|
||||
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+
|
||||
#
|
||||
# Xilinx ZYNQ U-Boot
|
||||
#
|
||||
# (C) Copyright 2013 Xilinx, Inc.
|
||||
.. SPDX-License-Identifier: GPL-2.0+
|
||||
.. (C) Copyright 2013 Xilinx, Inc.
|
||||
|
||||
1. About this
|
||||
ZYNQ
|
||||
====
|
||||
|
||||
About this
|
||||
----------
|
||||
|
||||
This document describes the information about Xilinx Zynq U-Boot -
|
||||
like supported boards, ML status and TODO list.
|
||||
|
||||
2. Zynq boards
|
||||
Zynq boards
|
||||
-----------
|
||||
|
||||
Xilinx Zynq-7000 All Programmable SoCs enable extensive system level
|
||||
differentiation, integration, and flexibility through hardware, software,
|
||||
|
@ -20,18 +22,21 @@ and I/O programmability.
|
|||
* zed (single qspi, gem0, mmc) [3]
|
||||
* microzed (single qspi, gem0, mmc) [4]
|
||||
* zc770
|
||||
- zc770-xm010 (single qspi, gem0, mmc)
|
||||
- zc770-xm011 (8 or 16 bit nand)
|
||||
- zc770-xm012 (nor)
|
||||
- zc770-xm013 (dual parallel qspi, gem1)
|
||||
- zc770-xm010 (single qspi, gem0, mmc)
|
||||
- zc770-xm011 (8 or 16 bit nand)
|
||||
- zc770-xm012 (nor)
|
||||
- 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
|
||||
|
||||
4. Bootmode
|
||||
Bootmode
|
||||
--------
|
||||
|
||||
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]
|
||||
|
@ -44,40 +49,47 @@ at runtime and assign the modeboot variable to specific bootmode string which
|
|||
is intern used in autoboot.
|
||||
|
||||
SLCR bootmode register Bit[3:0] values
|
||||
#define ZYNQ_BM_NOR 0x02
|
||||
#define ZYNQ_BM_SD 0x05
|
||||
#define ZYNQ_BM_JTAG 0x0
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#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"
|
||||
bootmode strings at runtime.
|
||||
|
||||
5. Mainline status
|
||||
Mainline status
|
||||
---------------
|
||||
|
||||
- Added basic board configurations support.
|
||||
- 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 drivers:
|
||||
serial - drivers/serial/serial_zynq.c
|
||||
net - drivers/net/zynq_gem.c
|
||||
mmc - drivers/mmc/zynq_sdhci.c
|
||||
spi - drivers/spi/zynq_spi.c
|
||||
qspi - drivers/spi/zynq_qspi.c
|
||||
i2c - drivers/i2c/zynq_i2c.c
|
||||
nand - drivers/mtd/nand/raw/zynq_nand.c
|
||||
|
||||
:serial: drivers/serial/serial_zynq.c
|
||||
:net: drivers/net/zynq_gem.c
|
||||
:mmc: drivers/mmc/zynq_sdhci.c
|
||||
:spi: drivers/spi/zynq_spi.c
|
||||
:qspi: drivers/spi/zynq_qspi.c
|
||||
:i2c: drivers/i2c/zynq_i2c.c
|
||||
:nand: drivers/mtd/nand/raw/zynq_nand.c
|
||||
|
||||
- Done proper cleanups on board configurations
|
||||
- Added basic FDT support for zynq boards
|
||||
- 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
|
||||
[2] http://www.xilinx.com/products/boards-and-kits/EK-Z7-ZC706-G.htm
|
||||
[3] http://zedboard.org/product/zedboard
|
||||
[4] http://zedboard.org/product/microzed
|
||||
[5] http://www.xilinx.com/support/documentation/user_guides/ug585-Zynq-7000-TRM.pdf
|
||||
* [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
|
||||
* [3] http://zedboard.org/product/zedboard
|
||||
* [4] http://zedboard.org/product/microzed
|
||||
* [5] http://www.xilinx.com/support/documentation/user_guides/ug585-Zynq-7000-TRM.pdf
|
||||
|
||||
--
|
||||
Jagannadha Sutradharudu Teki <jaganna@xilinx.com>
|
||||
Sun Dec 15 14:52:41 IST 2013
|
||||
|
||||
.. Jagannadha Sutradharudu Teki <jaganna@xilinx.com>
|
||||
.. 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
|
||||
way of declaring and accessing drivers in U-Boot. The original work was done
|
||||
by:
|
||||
|
||||
Marek Vasut <marex@denx.de>
|
||||
Pavel Herrmann <morpheus.ibis@gmail.com>
|
||||
Viktor Křivák <viktor.krivak@gmail.com>
|
||||
Tomas Hlavacek <tmshlvck@gmail.com>
|
||||
* Marek Vasut <marex@denx.de>
|
||||
* Pavel Herrmann <morpheus.ibis@gmail.com>
|
||||
* Viktor Křivák <viktor.krivak@gmail.com>
|
||||
* Tomas Hlavacek <tmshlvck@gmail.com>
|
||||
|
||||
This has been both simplified and extended into the current implementation
|
||||
by:
|
||||
|
||||
Simon Glass <sjg@chromium.org>
|
||||
* Simon Glass <sjg@chromium.org>
|
||||
|
||||
|
||||
Terminology
|
||||
-----------
|
||||
|
||||
Uclass - a group of devices which operate in the same way. A uclass provides
|
||||
a way of accessing individual devices within the group, but always
|
||||
using the same interface. For example a GPIO uclass provides
|
||||
operations for get/set value. An I2C uclass may have 10 I2C ports,
|
||||
4 with one driver, and 6 with another.
|
||||
Uclass
|
||||
a group of devices which operate in the same way. A uclass provides
|
||||
a way of accessing individual devices within the group, but always
|
||||
using the same interface. For example a GPIO uclass provides
|
||||
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
|
||||
interface to it.
|
||||
Driver
|
||||
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
|
||||
-------------
|
||||
|
||||
Build U-Boot sandbox and run it:
|
||||
Build U-Boot sandbox and run it::
|
||||
|
||||
make sandbox_defconfig
|
||||
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
|
||||
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
|
||||
Hello '@' from 07981110: red 4
|
||||
=>demo status 2
|
||||
Status: 0
|
||||
=>demo hello 2
|
||||
g
|
||||
r@
|
||||
e@@
|
||||
e@@@
|
||||
n@@@@
|
||||
g@@@@@
|
||||
=>demo status 2
|
||||
Status: 21
|
||||
=>demo hello 4 ^
|
||||
y^^^
|
||||
e^^^^^
|
||||
l^^^^^^^
|
||||
l^^^^^^^
|
||||
o^^^^^
|
||||
w^^^
|
||||
=>demo status 4
|
||||
Status: 36
|
||||
=>
|
||||
=>demo hello 1
|
||||
Hello '@' from 07981110: red 4
|
||||
=>demo status 2
|
||||
Status: 0
|
||||
=>demo hello 2
|
||||
g
|
||||
r@
|
||||
e@@
|
||||
e@@@
|
||||
n@@@@
|
||||
g@@@@@
|
||||
=>demo status 2
|
||||
Status: 21
|
||||
=>demo hello 4 ^
|
||||
y^^^
|
||||
e^^^^^
|
||||
l^^^^^^^
|
||||
l^^^^^^^
|
||||
o^^^^^
|
||||
w^^^
|
||||
=>demo status 4
|
||||
Status: 36
|
||||
=>
|
||||
|
||||
|
||||
Running the tests
|
||||
|
@ -88,139 +94,139 @@ Running the tests
|
|||
|
||||
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
|
||||
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
|
||||
|
||||
You should see something like this:
|
||||
You should see something like this::
|
||||
|
||||
(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 -j8
|
||||
============================= 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
|
||||
cachedir: .cache
|
||||
rootdir: /root/u-boot, inifile:
|
||||
collected 199 items
|
||||
(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 -j8
|
||||
============================= 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
|
||||
cachedir: .cache
|
||||
rootdir: /root/u-boot, inifile:
|
||||
collected 199 items
|
||||
|
||||
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_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_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_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_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_valid] 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_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_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_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_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_uclass] 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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_bs] PASSED
|
||||
test/py/tests/test_ut.py::test_ut[ut_dm_video_truetype_scroll] 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_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_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_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_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_valid] 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_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_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_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_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_uclass] 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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_bs] PASSED
|
||||
test/py/tests/test_ut.py::test_ut[ut_dm_video_truetype_scroll] PASSED
|
||||
|
||||
======================= 84 tests deselected by '-kut_dm' =======================
|
||||
================== 115 passed, 84 deselected in 3.77 seconds ===================
|
||||
======================= 84 tests deselected by '-kut_dm' =======================
|
||||
================== 115 passed, 84 deselected in 3.77 seconds ===================
|
||||
|
||||
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
|
||||
the usual command processing and then:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
struct udevice *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:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
return demo_hello(demo_dev, ch);
|
||||
|
||||
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:
|
||||
|
||||
int demo_hello(struct udevice *dev, int ch)
|
||||
{
|
||||
const struct demo_ops *ops = device_get_ops(dev);
|
||||
.. code-block:: c
|
||||
|
||||
if (!ops->hello)
|
||||
return -ENOSYS;
|
||||
int demo_hello(struct udevice *dev, int ch)
|
||||
{
|
||||
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
|
||||
in drivers/demo/demo-simple.c:
|
||||
|
||||
static int simple_hello(struct udevice *dev, int ch)
|
||||
{
|
||||
const struct dm_demo_pdata *pdata = dev_get_platdata(dev);
|
||||
.. code-block:: c
|
||||
|
||||
printf("Hello from %08x: %s %d\n", map_to_sysmem(dev),
|
||||
pdata->colour, pdata->sides);
|
||||
static int simple_hello(struct udevice *dev, int ch)
|
||||
{
|
||||
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)
|
||||
|
@ -287,17 +301,19 @@ Declaring Drivers
|
|||
A driver declaration looks something like this (see
|
||||
drivers/demo/demo-shape.c):
|
||||
|
||||
static const struct demo_ops shape_ops = {
|
||||
.hello = shape_hello,
|
||||
.status = shape_status,
|
||||
};
|
||||
.. code-block:: c
|
||||
|
||||
U_BOOT_DRIVER(demo_shape_drv) = {
|
||||
.name = "demo_shape_drv",
|
||||
.id = UCLASS_DEMO,
|
||||
.ops = &shape_ops,
|
||||
.priv_data_size = sizeof(struct shape_data),
|
||||
};
|
||||
static const struct demo_ops shape_ops = {
|
||||
.hello = shape_hello,
|
||||
.status = shape_status,
|
||||
};
|
||||
|
||||
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
|
||||
|
@ -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.
|
||||
Briefly, they are:
|
||||
|
||||
bind - make the driver model aware of a device (bind it to its driver)
|
||||
unbind - make the driver model forget the device
|
||||
ofdata_to_platdata - convert device tree data to platdata - see later
|
||||
probe - make a device ready for use
|
||||
remove - remove a device so it cannot be used until probed again
|
||||
* bind - make the driver model aware of a device (bind it to its driver)
|
||||
* unbind - make the driver model forget the device
|
||||
* ofdata_to_platdata - convert device tree data to platdata - see later
|
||||
* probe - make a device ready for use
|
||||
* 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
|
||||
device tree) and probe.
|
||||
|
@ -328,14 +344,14 @@ device tree) and probe.
|
|||
Platform Data
|
||||
-------------
|
||||
|
||||
*** 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
|
||||
*** platform-specific settings like the address of its registers, bus
|
||||
*** 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
|
||||
*** 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
|
||||
*** from platform data.
|
||||
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
|
||||
platform-specific settings like the address of its registers, bus
|
||||
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
|
||||
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
|
||||
from platform data.
|
||||
|
||||
Platform data is like Linux platform data, if you are familiar with that.
|
||||
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
|
||||
- Configuration options, like:
|
||||
- the SPI polarity and maximum speed for a SPI controller
|
||||
- the I2C speed to use for an I2C device
|
||||
- the number of GPIOs available in a GPIO device
|
||||
- the SPI polarity and maximum speed for a SPI controller
|
||||
- the I2C speed to use for an I2C device
|
||||
- the number of GPIOs available in a GPIO device
|
||||
|
||||
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
|
||||
|
@ -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
|
||||
in the board file.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
static const struct dm_demo_cdata red_square = {
|
||||
.colour = "red",
|
||||
.sides = 4.
|
||||
};
|
||||
|
||||
static const struct driver_info info[] = {
|
||||
{
|
||||
.name = "demo_shape_drv",
|
||||
|
@ -409,6 +428,8 @@ necessary.
|
|||
With device tree we replace the above code with the following device tree
|
||||
fragment:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
red-square {
|
||||
compatible = "demo-shape";
|
||||
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:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
.platdata_auto_alloc_size = sizeof(struct dm_test_pdata),
|
||||
.ofdata_to_platdata = testfdt_ofdata_to_platdata,
|
||||
|
||||
|
@ -464,9 +487,11 @@ Declaring Uclasses
|
|||
|
||||
The demo uclass is declared like this:
|
||||
|
||||
U_BOOT_CLASS(demo) = {
|
||||
.id = UCLASS_DEMO,
|
||||
};
|
||||
.. code-block:: c
|
||||
|
||||
U_BOOT_CLASS(demo) = {
|
||||
.id = UCLASS_DEMO,
|
||||
};
|
||||
|
||||
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
|
||||
|
@ -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
|
||||
used. Make sure that the uclass has the DM_UC_FLAG_SEQ_ALIAS flag set.
|
||||
|
||||
aliases {
|
||||
serial2 = "/serial@22230000";
|
||||
};
|
||||
.. code-block:: none
|
||||
|
||||
aliases {
|
||||
serial2 = "/serial@22230000";
|
||||
};
|
||||
|
||||
This indicates that in the uclass called "serial", the named node
|
||||
("/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:
|
||||
|
||||
aliases {
|
||||
serial2 = &serial_2;
|
||||
};
|
||||
...
|
||||
serial_2: serial@22230000 {
|
||||
...
|
||||
};
|
||||
.. code-block:: none
|
||||
|
||||
aliases {
|
||||
serial2 = &serial_2;
|
||||
};
|
||||
...
|
||||
serial_2: serial@22230000 {
|
||||
...
|
||||
};
|
||||
|
||||
The alias resolves to the same string in this case, but this version is
|
||||
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
|
||||
a USB bus with several devices attached to it, each from a different (made
|
||||
up) uclass:
|
||||
up) uclass::
|
||||
|
||||
xhci_usb (UCLASS_USB)
|
||||
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
|
||||
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
|
||||
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)
|
||||
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
|
||||
methods actually defined.
|
||||
|
||||
1. Bind stage
|
||||
Bind stage
|
||||
^^^^^^^^^^
|
||||
|
||||
U-Boot discovers devices using one of these two methods:
|
||||
|
||||
- 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,
|
||||
there is no path by which driver_data may be provided, but the U_BOOT_DEVICE()
|
||||
may provide platdata.
|
||||
- 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,
|
||||
there is no path by which driver_data may be provided, but the U_BOOT_DEVICE()
|
||||
may provide platdata.
|
||||
|
||||
- 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
|
||||
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
|
||||
driver_data value, but platdata cannot be provided until later.
|
||||
- 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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
otherwise you would have to specific the platform data in the
|
||||
U_BOOT_DEVICE() declaration. The space is allocated for the device and
|
||||
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
|
||||
stored in the device, but it is uclass data. owned by the uclass driver.
|
||||
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
|
||||
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
|
||||
space. The controller can hold information about the USB state of each
|
||||
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.
|
||||
This means (for example) that an I2C driver will require that its bus
|
||||
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
|
||||
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
|
||||
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.
|
||||
|
@ -707,7 +738,7 @@ steps (see device_probe()):
|
|||
data, one day it is possible that U-Boot will cache platform data for
|
||||
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
|
||||
that the hardware is actually present, setting up clocks for the
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
to be sure that no hardware is running, it should be enough to remove
|
||||
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).
|
||||
|
||||
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
|
||||
remove() method, either:
|
||||
|
||||
1. if the platdata_auto_alloc_size is non-zero, the deallocation
|
||||
happens automatically within the driver model core; or
|
||||
- if the platdata_auto_alloc_size is non-zero, the deallocation
|
||||
happens automatically within the driver model core; or
|
||||
|
||||
2. when platdata_auto_alloc_size is 0, both the allocation (in probe()
|
||||
or preferably ofdata_to_platdata()) and the deallocation in remove()
|
||||
are the responsibility of the driver author.
|
||||
- when platdata_auto_alloc_size is 0, both the allocation (in probe()
|
||||
or preferably ofdata_to_platdata()) and the deallocation in remove()
|
||||
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
|
||||
sequence number is still free, it may well receive the name sequence
|
||||
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
|
||||
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
|
||||
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.
|
||||
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:
|
||||
|
||||
- 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
|
||||
the driver operations structure in the driver, rather than passing it
|
||||
to the driver bind function.
|
||||
the driver operations structure in the driver, rather than passing it
|
||||
to the driver bind function.
|
||||
- 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
|
||||
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
|
||||
better than 'core'.
|
||||
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
|
||||
better than 'core'.
|
||||
- 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
|
||||
- Removed the concept of driver relocation, and just make it possible for
|
||||
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
|
||||
drivers, many of which can/will just re-init anyway. So the overhead of
|
||||
dealing with this might not be worth it.
|
||||
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
|
||||
drivers, many of which can/will just re-init anyway. So the overhead of
|
||||
dealing with this might not be worth it.
|
||||
- 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
|
||||
so has been left out for now. One small advantage of dynamic numbering might
|
||||
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
|
||||
=======================================
|
||||
|
||||
Contents:
|
||||
|
||||
1. Purpose
|
||||
2. Implementation
|
||||
3. Example
|
||||
4. Work to be done
|
||||
|
||||
1. Purpose
|
||||
----------
|
||||
Purpose
|
||||
-------
|
||||
|
||||
In certain markets, it is beneficial for manufacturers of embedded devices to
|
||||
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
|
||||
components easily.
|
||||
|
||||
2. Implementation
|
||||
-----------------
|
||||
Implementation
|
||||
--------------
|
||||
|
||||
To take advantage of the pre-relocation device tree manipulation mechanism,
|
||||
boards have to implement the function board_fix_fdt, which has the following
|
||||
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
|
||||
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).
|
||||
|
||||
Furthermore, the Kconfig option OF_BOARD_FIXUP has to be set for the function
|
||||
to be called:
|
||||
to be called::
|
||||
|
||||
Device Tree Control
|
||||
-> [*] Board-specific manipulation of Device Tree
|
||||
Device Tree Control
|
||||
-> [*] Board-specific manipulation of Device Tree
|
||||
|
||||
+----------------------------------------------------------+
|
||||
| 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
|
||||
following:
|
||||
|
||||
int board_fix_fdt(void *rw_fdt_blob)
|
||||
{
|
||||
/* Collect information about device's hardware and store them in e.g.
|
||||
local variables */
|
||||
.. code-block:: c
|
||||
|
||||
/* 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
|
||||
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,
|
||||
as well as a combination of both approaches should work.
|
||||
|
||||
3. Example
|
||||
----------
|
||||
Example
|
||||
-------
|
||||
|
||||
The controlcenterdc board (board/gdsys/a38x/controlcenterdc.c) features a
|
||||
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
|
||||
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,
|
||||
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
|
||||
ones remain:
|
||||
|
||||
adi_i2c
|
||||
davinci_i2c
|
||||
fti2c010
|
||||
ihs_i2c
|
||||
kona_i2c
|
||||
lpc32xx_i2c
|
||||
pca9564_i2c
|
||||
ppc4xx_i2c
|
||||
rcar_i2c
|
||||
sh_i2c
|
||||
soft_i2c
|
||||
zynq_i2c
|
||||
* adi_i2c
|
||||
* davinci_i2c
|
||||
* fti2c010
|
||||
* ihs_i2c
|
||||
* kona_i2c
|
||||
* lpc32xx_i2c
|
||||
* pca9564_i2c
|
||||
* ppc4xx_i2c
|
||||
* rcar_i2c
|
||||
* sh_i2c
|
||||
* soft_i2c
|
||||
* zynq_i2c
|
||||
|
||||
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!
|
||||
|
@ -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
|
||||
- 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
|
||||
no I2C driver
|
||||
no I2C driver
|
||||
- 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
|
||||
- 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
|
||||
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
|
||||
code
|
||||
code
|
||||
|
||||
In terms of patches a conversion series typically has these patches:
|
||||
- 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
|
||||
|
@ -20,7 +23,7 @@ Motivation
|
|||
The flat device tree has several advantages:
|
||||
|
||||
- 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)
|
||||
|
||||
|
@ -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
|
||||
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
|
||||
a 'struct udevice *' which is attached to a device tree node. Therefore it
|
||||
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
|
||||
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
|
||||
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:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
struct udevice *bus;
|
||||
const void *blob = gd->fdt_blob;
|
||||
int node = dev_of_offset(bus);
|
||||
|
@ -94,17 +99,21 @@ For example, the old code may be like this:
|
|||
|
||||
The new code is:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
struct udevice *bus;
|
||||
|
||||
i2c_bus->regs = (struct i2c_ctlr *)dev_read_addr(dev);
|
||||
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.
|
||||
|
||||
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:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
const void *blob = gd->fdt_blob;
|
||||
int subnode;
|
||||
|
||||
|
@ -115,6 +124,8 @@ back to using ofnode. For example, for old code like this:
|
|||
|
||||
you should use:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
ofnode subnode;
|
||||
|
||||
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 :
|
||||
|
||||
struct device_node - holds information about a device tree node
|
||||
struct property - holds information about a property within a node
|
||||
:struct device_node: holds information about a device tree node
|
||||
:struct property: holds information about a property within a node
|
||||
|
||||
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
|
||||
|
@ -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
|
||||
node.
|
||||
|
||||
ofnode_to_np() - converts ofnode to struct device_node *
|
||||
ofnode_to_offset() - converts ofnode to offset
|
||||
ofnode_to_np():
|
||||
converts ofnode to struct device_node *
|
||||
ofnode_to_offset():
|
||||
converts ofnode to offset
|
||||
|
||||
no_to_ofnode() - converts node pointer to ofnode
|
||||
offset_to_ofnode() - converts offset to ofnode
|
||||
no_to_ofnode():
|
||||
converts node pointer to ofnode
|
||||
offset_to_ofnode():
|
||||
converts offset to ofnode
|
||||
|
||||
|
||||
Other useful functions:
|
||||
|
||||
of_live_active() returns true if livetree is in use, false if flat tree
|
||||
ofnode_valid() return true if a given node is valid
|
||||
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)
|
||||
of_live_active():
|
||||
returns true if livetree is in use, false if flat tree
|
||||
ofnode_valid():
|
||||
return true if a given node is valid
|
||||
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
|
||||
|
@ -199,13 +219,13 @@ the flat tree.
|
|||
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
|
||||
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
|
||||
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.
|
||||
|
||||
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).
|
||||
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
|
||||
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:
|
||||
|
||||
- Add two dev_read() functions:
|
||||
- inline version in the read.h header file, which calls an ofnode
|
||||
function
|
||||
- standard version in the read.c file (or perhaps another file), which
|
||||
also calls an ofnode function
|
||||
- inline version in the read.h header file, which calls an ofnode function
|
||||
- standard version in the read.c file (or perhaps another file), which
|
||||
also calls an ofnode function
|
||||
|
||||
The implementations of these functions can be the same. The purpose
|
||||
of the inline version is purely to reduce code size impact.
|
||||
The implementations of these functions can be the same. The purpose
|
||||
of the inline version is purely to reduce code size impact.
|
||||
|
||||
- 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
|
||||
call an of_...() function. For the flat tree it should call an
|
||||
fdt_...() function. The livetree version will be optimised out at
|
||||
compile time if livetree is not enabled.
|
||||
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
|
||||
fdt\_...() function. The livetree version will be optimised out at
|
||||
compile time if livetree is not enabled.
|
||||
|
||||
- Add an of_...() function for the livetree implementation. If a similar
|
||||
function is available in Linux, the implementation should be taken
|
||||
from there and modified as little as possible (generally not at all).
|
||||
- Add an of\_...() function for the livetree implementation. If a similar
|
||||
function is available in Linux, the implementation should be taken
|
||||
from there and modified as little as possible (generally not at all).
|
||||
|
||||
|
||||
Future work
|
||||
|
@ -265,8 +284,3 @@ of work to do to flesh this out:
|
|||
- support for livetree modification
|
||||
- addition of more access functions as needed
|
||||
- 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
|
||||
====================
|
||||
==================
|
||||
|
||||
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
|
||||
|
@ -8,8 +10,8 @@ features.
|
|||
CONFIG_DM_MMC
|
||||
-------------
|
||||
|
||||
Status: In progress
|
||||
Deadline: 2019.04
|
||||
* Status: In progress
|
||||
* Deadline: 2019.04
|
||||
|
||||
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
|
||||
|
@ -18,8 +20,8 @@ time for inclusion in the 2019.04 rerelease.
|
|||
CONFIG_DM_USB
|
||||
-------------
|
||||
|
||||
Status: In progress
|
||||
Deadline: 2019.07
|
||||
* Status: In progress
|
||||
* Deadline: 2019.07
|
||||
|
||||
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
|
||||
|
@ -28,8 +30,8 @@ other base driver model options in time for inclusion in the 2019.07 rerelease.
|
|||
CONFIG_SATA
|
||||
-----------
|
||||
|
||||
Status: In progress
|
||||
Deadline: 2019.07
|
||||
* Status: In progress
|
||||
* Deadline: 2019.07
|
||||
|
||||
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
|
||||
|
@ -38,8 +40,8 @@ other base driver model options in time for inclusion in the 2019.07 rerelease.
|
|||
CONFIG_BLK
|
||||
----------
|
||||
|
||||
Status: In progress
|
||||
Deadline: 2019.07
|
||||
* Status: In progress
|
||||
* Deadline: 2019.07
|
||||
|
||||
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
|
||||
|
@ -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
|
||||
use of CONFIG_BLK / CONFIG_SPL_BLK as needed.
|
||||
|
||||
CONFIG_DM_SPI
|
||||
CONFIG_DM_SPI_FLASH
|
||||
-------------------
|
||||
CONFIG_DM_SPI / CONFIG_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.
|
||||
|
||||
No dm conversion yet:
|
||||
No dm conversion yet::
|
||||
|
||||
drivers/spi/cf_spi.c
|
||||
drivers/spi/fsl_espi.c
|
||||
drivers/spi/lpc32xx_ssp.c
|
||||
|
@ -63,10 +65,11 @@ No dm conversion yet:
|
|||
drivers/spi/sh_spi.c
|
||||
drivers/spi/soft_spi_legacy.c
|
||||
|
||||
Status: In progress
|
||||
Deadline: 2019.04
|
||||
* Status: In progress
|
||||
* Deadline: 2019.04
|
||||
|
||||
Partially converted::
|
||||
|
||||
Partially converted:
|
||||
drivers/spi/davinci_spi.c
|
||||
drivers/spi/fsl_dspi.c
|
||||
drivers/spi/kirkwood_spi.c
|
||||
|
@ -74,13 +77,8 @@ Partially converted:
|
|||
drivers/spi/omap3_spi.c
|
||||
drivers/spi/sh_qspi.c
|
||||
|
||||
Status: In progress
|
||||
Deadline: 2019.07
|
||||
|
||||
--
|
||||
Jagan Teki <jagan@openedev.com>
|
||||
12/24/2018
|
||||
03/14/2018
|
||||
* Status: In progress
|
||||
* Deadline: 2019.07
|
||||
|
||||
|
||||
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
|
||||
|
@ -40,36 +42,36 @@ There are many problems with this features. It should only be used when
|
|||
strictly necessary. Notable problems include:
|
||||
|
||||
- Device tree does not describe data types. But the C code must define a
|
||||
type for each property. These are guessed using heuristics which
|
||||
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
|
||||
boolean value that is not present means 'false', but cannot be
|
||||
included in the structures since there is generally no mention of it
|
||||
in the device tree file.
|
||||
type for each property. These are guessed using heuristics which
|
||||
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
|
||||
boolean value that is not present means 'false', but cannot be
|
||||
included in the structures since there is generally no mention of it
|
||||
in the device tree file.
|
||||
|
||||
- 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
|
||||
look a bit strange.
|
||||
the naming in the device tree, which may result in C identifiers that
|
||||
look a bit strange.
|
||||
|
||||
- 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 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
|
||||
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
|
||||
platform data.
|
||||
the associated C member variable directly in the code. This makes
|
||||
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
|
||||
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
|
||||
platform data.
|
||||
|
||||
- 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
|
||||
normally also supports device tree it must use #ifdef to separate
|
||||
out this code, since the structures are only available in SPL.
|
||||
must use the same structure to access the data. Since a driver
|
||||
normally also supports device tree it must use #ifdef to separate
|
||||
out this code, since the structures are only available in SPL.
|
||||
|
||||
- Correct relations between nodes are not implemented. This means that
|
||||
parent/child relations (like bus device iteration) do not work yet.
|
||||
Some phandles (those that are recognised as such) are converted into
|
||||
a pointer to platform data. This pointer can potentially be used to
|
||||
access the referenced device (by searching for the pointer value).
|
||||
This feature is not yet implemented, however.
|
||||
parent/child relations (like bus device iteration) do not work yet.
|
||||
Some phandles (those that are recognised as such) are converted into
|
||||
a pointer to platform data. This pointer can potentially be used to
|
||||
access the referenced device (by searching for the pointer value).
|
||||
This feature is not yet implemented, however.
|
||||
|
||||
|
||||
How it works
|
||||
|
@ -78,30 +80,34 @@ How it works
|
|||
The feature is enabled by CONFIG OF_PLATDATA. This is only available in
|
||||
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
|
||||
struct declarations, one for each compatible node, and a set of
|
||||
U_BOOT_DEVICE() declarations along with the actual platform data for each
|
||||
device. As an example, consider this MMC node:
|
||||
|
||||
sdmmc: dwmmc@ff0c0000 {
|
||||
compatible = "rockchip,rk3288-dw-mshc";
|
||||
clock-freq-min-max = <400000 150000000>;
|
||||
clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>,
|
||||
<&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>;
|
||||
clock-names = "biu", "ciu", "ciu_drv", "ciu_sample";
|
||||
fifo-depth = <0x100>;
|
||||
interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
|
||||
reg = <0xff0c0000 0x4000>;
|
||||
bus-width = <4>;
|
||||
cap-mmc-highspeed;
|
||||
cap-sd-highspeed;
|
||||
card-detect-delay = <200>;
|
||||
disable-wp;
|
||||
num-slots = <1>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&sdmmc_clk>, <&sdmmc_cmd>, <&sdmmc_cd>, <&sdmmc_bus4>;
|
||||
.. code-block:: none
|
||||
|
||||
sdmmc: dwmmc@ff0c0000 {
|
||||
compatible = "rockchip,rk3288-dw-mshc";
|
||||
clock-freq-min-max = <400000 150000000>;
|
||||
clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>,
|
||||
<&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>;
|
||||
clock-names = "biu", "ciu", "ciu_drv", "ciu_sample";
|
||||
fifo-depth = <0x100>;
|
||||
interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
|
||||
reg = <0xff0c0000 0x4000>;
|
||||
bus-width = <4>;
|
||||
cap-mmc-highspeed;
|
||||
cap-sd-highspeed;
|
||||
card-detect-delay = <200>;
|
||||
disable-wp;
|
||||
num-slots = <1>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&sdmmc_clk>, <&sdmmc_cmd>, <&sdmmc_cd>, <&sdmmc_bus4>;
|
||||
vmmc-supply = <&vcc_sd>;
|
||||
status = "okay";
|
||||
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
|
||||
the following C struct declaration:
|
||||
|
||||
struct dtd_rockchip_rk3288_dw_mshc {
|
||||
fdt32_t bus_width;
|
||||
bool cap_mmc_highspeed;
|
||||
bool cap_sd_highspeed;
|
||||
fdt32_t card_detect_delay;
|
||||
fdt32_t clock_freq_min_max[2];
|
||||
struct phandle_1_arg clocks[4];
|
||||
bool disable_wp;
|
||||
fdt32_t fifo_depth;
|
||||
fdt32_t interrupts[3];
|
||||
fdt32_t num_slots;
|
||||
fdt32_t reg[2];
|
||||
fdt32_t vmmc_supply;
|
||||
};
|
||||
.. code-block:: c
|
||||
|
||||
struct dtd_rockchip_rk3288_dw_mshc {
|
||||
fdt32_t bus_width;
|
||||
bool cap_mmc_highspeed;
|
||||
bool cap_sd_highspeed;
|
||||
fdt32_t card_detect_delay;
|
||||
fdt32_t clock_freq_min_max[2];
|
||||
struct phandle_1_arg clocks[4];
|
||||
bool disable_wp;
|
||||
fdt32_t fifo_depth;
|
||||
fdt32_t interrupts[3];
|
||||
fdt32_t num_slots;
|
||||
fdt32_t reg[2];
|
||||
fdt32_t vmmc_supply;
|
||||
};
|
||||
|
||||
and the following device declaration:
|
||||
|
||||
static struct dtd_rockchip_rk3288_dw_mshc dtv_dwmmc_at_ff0c0000 = {
|
||||
.fifo_depth = 0x100,
|
||||
.cap_sd_highspeed = true,
|
||||
.interrupts = {0x0, 0x20, 0x4},
|
||||
.clock_freq_min_max = {0x61a80, 0x8f0d180},
|
||||
.vmmc_supply = 0xb,
|
||||
.num_slots = 0x1,
|
||||
.clocks = {{&dtv_clock_controller_at_ff760000, 456},
|
||||
{&dtv_clock_controller_at_ff760000, 68},
|
||||
{&dtv_clock_controller_at_ff760000, 114},
|
||||
{&dtv_clock_controller_at_ff760000, 118}},
|
||||
.cap_mmc_highspeed = true,
|
||||
.disable_wp = true,
|
||||
.bus_width = 0x4,
|
||||
.u_boot_dm_pre_reloc = true,
|
||||
.reg = {0xff0c0000, 0x4000},
|
||||
.card_detect_delay = 0xc8,
|
||||
};
|
||||
U_BOOT_DEVICE(dwmmc_at_ff0c0000) = {
|
||||
.name = "rockchip_rk3288_dw_mshc",
|
||||
.platdata = &dtv_dwmmc_at_ff0c0000,
|
||||
.platdata_size = sizeof(dtv_dwmmc_at_ff0c0000),
|
||||
};
|
||||
.. code-block:: c
|
||||
|
||||
static struct dtd_rockchip_rk3288_dw_mshc dtv_dwmmc_at_ff0c0000 = {
|
||||
.fifo_depth = 0x100,
|
||||
.cap_sd_highspeed = true,
|
||||
.interrupts = {0x0, 0x20, 0x4},
|
||||
.clock_freq_min_max = {0x61a80, 0x8f0d180},
|
||||
.vmmc_supply = 0xb,
|
||||
.num_slots = 0x1,
|
||||
.clocks = {{&dtv_clock_controller_at_ff760000, 456},
|
||||
{&dtv_clock_controller_at_ff760000, 68},
|
||||
{&dtv_clock_controller_at_ff760000, 114},
|
||||
{&dtv_clock_controller_at_ff760000, 118}},
|
||||
.cap_mmc_highspeed = true,
|
||||
.disable_wp = true,
|
||||
.bus_width = 0x4,
|
||||
.u_boot_dm_pre_reloc = true,
|
||||
.reg = {0xff0c0000, 0x4000},
|
||||
.card_detect_delay = 0xc8,
|
||||
};
|
||||
|
||||
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
|
||||
accessed using:
|
||||
|
||||
struct udevice *dev;
|
||||
struct dtd_rockchip_rk3288_dw_mshc *plat = dev_get_platdata(dev);
|
||||
.. code-block:: c
|
||||
|
||||
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
|
||||
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
|
||||
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
|
||||
|
@ -204,6 +219,8 @@ ofdata_to_platdata() method and wrapped with #if.
|
|||
|
||||
For example:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#include <dt-structs.h>
|
||||
|
||||
struct mmc_platdata {
|
||||
|
@ -313,12 +330,12 @@ This is an implementation of an idea by Tom Rini <trini@konsulko.com>.
|
|||
Future work
|
||||
-----------
|
||||
- Consider programmatically reading binding files instead of device tree
|
||||
contents
|
||||
contents
|
||||
- Complete the phandle feature
|
||||
- Move to using a full Python libfdt module
|
||||
|
||||
--
|
||||
Simon Glass <sjg@chromium.org>
|
||||
Google, Inc
|
||||
6/6/16
|
||||
Updated Independence Day 2016
|
||||
|
||||
.. Simon Glass <sjg@chromium.org>
|
||||
.. Google, Inc
|
||||
.. 6/6/16
|
||||
.. Updated Independence Day 2016
|
|
@ -1,3 +1,5 @@
|
|||
.. SPDX-License-Identifier: GPL-2.0+
|
||||
|
||||
PCI with Driver Model
|
||||
=====================
|
||||
|
||||
|
@ -7,8 +9,7 @@ How busses are scanned
|
|||
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.
|
||||
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 {
|
||||
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
|
||||
hardware, otherwise driver model cannot detect the correct parent/children
|
||||
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 {
|
||||
#address-cells = <3>;
|
||||
|
@ -113,7 +114,7 @@ Sandbox
|
|||
|
||||
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
|
||||
driver. For example:
|
||||
driver. For example::
|
||||
|
||||
|
||||
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 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@1f,0 @ 05c661c8, 63488
|
||||
`- emul@1f,0 @ 05c662c8
|
||||
`- * pci-controller @ 05c660c8, 0
|
||||
`- pci@1f,0 @ 05c661c8, 63488
|
||||
`- emul@1f,0 @ 05c662c8
|
||||
|
||||
When accesses go to the pci@1f,0 device they are forwarded to its child, the
|
||||
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
|
||||
host controller node for this functionality to work.
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
pci1: pci-controller1 {
|
||||
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
|
||||
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_emul [ ] sandbox_sw | |-- sandbox_swap_case_emul
|
|
@ -1,63 +1,59 @@
|
|||
#
|
||||
# (C) Copyright 2014-2015 Samsung Electronics
|
||||
# Przemyslaw Marczak <p.marczak@samsung.com>
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
.. SPDX-License-Identifier: GPL-2.0+
|
||||
.. (C) Copyright 2014-2015 Samsung Electronics
|
||||
.. sectionauthor:: Przemyslaw Marczak <p.marczak@samsung.com>
|
||||
|
||||
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.
|
||||
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_REGULATOR - additional uclass type for specific PMIC features,
|
||||
which are Voltage/Current regulators.
|
||||
|
||||
UCLASS_PMIC:
|
||||
basic uclass type for PMIC I/O, which provides common
|
||||
read/write interface.
|
||||
UCLASS_REGULATOR:
|
||||
additional uclass type for specific PMIC features, which are
|
||||
Voltage/Current regulators.
|
||||
|
||||
New files:
|
||||
|
||||
UCLASS_PMIC:
|
||||
- drivers/power/pmic/pmic-uclass.c
|
||||
- include/power/pmic.h
|
||||
- drivers/power/pmic/pmic-uclass.c
|
||||
- include/power/pmic.h
|
||||
UCLASS_REGULATOR:
|
||||
- drivers/power/regulator/regulator-uclass.c
|
||||
- include/power/regulator.h
|
||||
- drivers/power/regulator/regulator-uclass.c
|
||||
- include/power/regulator.h
|
||||
|
||||
Commands:
|
||||
- common/cmd_pmic.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
|
||||
to provide stable, precise and specific voltage power source with over-voltage
|
||||
and thermal protection circuits.
|
||||
|
||||
The single PMIC can provide various functions by single or multiple interfaces,
|
||||
like in the example below.
|
||||
like in the example below::
|
||||
|
||||
-- SoC
|
||||
|
|
||||
| ______________________________________
|
||||
| BUS 0 | Multi interface PMIC IC |--> LDO out 1
|
||||
| e.g.I2C0 | |--> LDO out N
|
||||
|-----------|---- PMIC device 0 (READ/WRITE ops) |
|
||||
| or SPI0 | |_ REGULATOR device (ldo/... ops) |--> BUCK out 1
|
||||
| | |_ CHARGER device (charger ops) |--> BUCK out M
|
||||
| | |_ MUIC device (microUSB con ops) |
|
||||
| BUS 1 | |_ ... |---> BATTERY
|
||||
| e.g.I2C1 | |
|
||||
|-----------|---- PMIC device 1 (READ/WRITE ops) |---> USB in 1
|
||||
. or SPI1 | |_ RTC device (rtc ops) |---> USB in 2
|
||||
. |______________________________________|---> USB out
|
||||
.
|
||||
-- SoC
|
||||
|
|
||||
| ______________________________________
|
||||
| BUS 0 | Multi interface PMIC IC |--> LDO out 1
|
||||
| e.g.I2C0 | |--> LDO out N
|
||||
|-----------|---- PMIC device 0 (READ/WRITE ops) |
|
||||
| or SPI0 | |_ REGULATOR device (ldo/... ops) |--> BUCK out 1
|
||||
| | |_ CHARGER device (charger ops) |--> BUCK out M
|
||||
| | |_ MUIC device (microUSB con ops) |
|
||||
| BUS 1 | |_ ... |---> BATTERY
|
||||
| e.g.I2C1 | |
|
||||
|-----------|---- PMIC device 1 (READ/WRITE ops) |---> USB in 1
|
||||
. or SPI1 | |_ RTC device (rtc ops) |---> USB in 2
|
||||
. |______________________________________|---> USB out
|
||||
.
|
||||
|
||||
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,
|
||||
|
@ -66,26 +62,27 @@ and multi-instance device support.
|
|||
|
||||
Basic design assumptions:
|
||||
|
||||
- Common I/O API - UCLASS_PMIC
|
||||
For the multi-function PMIC devices, this can be used as parent I/O device
|
||||
for each IC's interface. Then, each children uses the same dev for read/write.
|
||||
- Common I/O API:
|
||||
UCLASS_PMIC. For the multi-function PMIC devices, this can be used as
|
||||
parent I/O device for each IC's interface. Then, each children uses the
|
||||
same dev for read/write.
|
||||
|
||||
- Common regulator API - UCLASS_REGULATOR
|
||||
For driving the regulator attributes, auto setting function or command line
|
||||
interface, based on kernel-style regulator device tree constraints.
|
||||
- Common regulator API:
|
||||
UCLASS_REGULATOR. For driving the regulator attributes, auto setting
|
||||
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
|
||||
use pmic read/write directly.
|
||||
|
||||
3. Pmic uclass
|
||||
==============
|
||||
Pmic uclass
|
||||
-----------
|
||||
The basic information:
|
||||
|
||||
* Uclass: 'UCLASS_PMIC'
|
||||
* Header: 'include/power/pmic.h'
|
||||
* Core: 'drivers/power/pmic/pmic-uclass.c'
|
||||
config: 'CONFIG_DM_PMIC'
|
||||
* Command: 'common/cmd_pmic.c'
|
||||
config: 'CONFIG_CMD_PMIC'
|
||||
* Core: 'drivers/power/pmic/pmic-uclass.c' (config 'CONFIG_DM_PMIC')
|
||||
* Command: 'common/cmd_pmic.c' (config 'CONFIG_CMD_PMIC')
|
||||
* Example: 'drivers/power/pmic/max77686.c'
|
||||
|
||||
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.
|
||||
|
||||
4. Regulator uclass
|
||||
===================
|
||||
Regulator uclass
|
||||
----------------
|
||||
The basic information:
|
||||
* Uclass: 'UCLASS_REGULATOR'
|
||||
* Header: 'include/power/regulator.h'
|
||||
* Core: 'drivers/power/regulator/regulator-uclass.c'
|
||||
config: 'CONFIG_DM_REGULATOR'
|
||||
binding: 'doc/device-tree-bindings/regulator/regulator.txt'
|
||||
* Command: 'common/cmd_regulator.c'
|
||||
config: 'CONFIG_CMD_REGULATOR'
|
||||
|
||||
* Uclass: 'UCLASS_REGULATOR'
|
||||
|
||||
* Header: 'include/power/regulator.h'
|
||||
|
||||
* Core: 'drivers/power/regulator/regulator-uclass.c'
|
||||
(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'
|
||||
'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'
|
||||
config" 'CONFIG_DM_REGULATOR_FIXED'
|
||||
(config 'CONFIG_DM_REGULATOR_FIXED')
|
||||
|
||||
For detailed API description, please refer to the header file.
|
||||
|
|
@ -1,19 +1,12 @@
|
|||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
# (C) Copyright 2015
|
||||
# Texas Instruments Incorporated - http://www.ti.com/
|
||||
#
|
||||
.. SPDX-License-Identifier: GPL-2.0+
|
||||
.. (C) Copyright 2015
|
||||
.. Texas Instruments Incorporated - http://www.ti.com/
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
UCLASS_REMOTEPROC:
|
||||
- drivers/remoteproc/rproc-uclass.c
|
||||
- include/remoteproc.h
|
||||
- drivers/remoteproc/rproc-uclass.c
|
||||
- include/remoteproc.h
|
||||
|
||||
Commands:
|
||||
- common/cmd_remoteproc.c
|
||||
- common/cmd_remoteproc.c
|
||||
|
||||
Configuration:
|
||||
CONFIG_REMOTEPROC is selected by drivers as needed
|
||||
CONFIG_CMD_REMOTEPROC for the commands if required.
|
||||
- CONFIG_REMOTEPROC is selected by drivers as needed
|
||||
- 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:
|
||||
(entry)
|
||||
+-------+
|
||||
+---+ init |
|
||||
| | | <---------------------+
|
||||
| +-------+ |
|
||||
| |
|
||||
| |
|
||||
| +--------+ |
|
||||
Load| | reset | |
|
||||
| | | <----------+ |
|
||||
| +--------+ | |
|
||||
| |Load | |
|
||||
| | | |
|
||||
| +----v----+ reset | |
|
||||
+-> | | (opt) | |
|
||||
| Loaded +-----------+ |
|
||||
| | |
|
||||
+----+----+ |
|
||||
| Start |
|
||||
+---v-----+ (opt) |
|
||||
+->| Running | Stop |
|
||||
Ping +- | +--------------------+
|
||||
(opt) +---------+
|
||||
Overall, the driver statemachine transitions are typically as follows::
|
||||
|
||||
(entry)
|
||||
+-------+
|
||||
+---+ init |
|
||||
| | | <---------------------+
|
||||
| +-------+ |
|
||||
| |
|
||||
| |
|
||||
| +--------+ |
|
||||
Load| | reset | |
|
||||
| | | <----------+ |
|
||||
| +--------+ | |
|
||||
| |Load | |
|
||||
| | | |
|
||||
| +----v----+ reset | |
|
||||
+-> | | (opt) | |
|
||||
| Loaded +-----------+ |
|
||||
| | |
|
||||
+----+----+ |
|
||||
| Start |
|
||||
+---v-----+ (opt) |
|
||||
+->| Running | Stop |
|
||||
Ping +- | +--------------------+
|
||||
(opt) +---------+
|
||||
|
||||
(is_running does not change state)
|
||||
opt: Optional state transition implemented by driver.
|
||||
|
@ -83,23 +77,25 @@ The driver follows a standard UCLASS DM.
|
|||
|
||||
in the bare minimum form:
|
||||
|
||||
static const struct dm_rproc_ops sandbox_testproc_ops = {
|
||||
.load = sandbox_testproc_load,
|
||||
.start = sandbox_testproc_start,
|
||||
};
|
||||
.. code-block:: c
|
||||
|
||||
static const struct udevice_id sandbox_ids[] = {
|
||||
{.compatible = "sandbox,test-processor"},
|
||||
{}
|
||||
};
|
||||
static const struct dm_rproc_ops sandbox_testproc_ops = {
|
||||
.load = sandbox_testproc_load,
|
||||
.start = sandbox_testproc_start,
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(sandbox_testproc) = {
|
||||
.name = "sandbox_test_proc",
|
||||
.of_match = sandbox_ids,
|
||||
.id = UCLASS_REMOTEPROC,
|
||||
.ops = &sandbox_testproc_ops,
|
||||
.probe = sandbox_testproc_probe,
|
||||
};
|
||||
static const struct udevice_id sandbox_ids[] = {
|
||||
{.compatible = "sandbox,test-processor"},
|
||||
{}
|
||||
};
|
||||
|
||||
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
|
||||
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
|
||||
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
|
||||
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,
|
||||
a simplified definition of a device is as follows:
|
||||
|
||||
struct dm_rproc_uclass_pdata proc_3_test = {
|
||||
.name = "proc_3_legacy",
|
||||
.mem_type = RPROC_INTERNAL_MEMORY_MAPPED,
|
||||
.driver_plat_data = &mydriver_data;
|
||||
};
|
||||
.. code-block:: c
|
||||
|
||||
U_BOOT_DEVICE(proc_3_demo) = {
|
||||
.name = "sandbox_test_proc",
|
||||
.platdata = &proc_3_test,
|
||||
};
|
||||
struct dm_rproc_uclass_pdata proc_3_test = {
|
||||
.name = "proc_3_legacy",
|
||||
.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
|
||||
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.
|
||||
These are passed via driver_plat_data.
|
||||
|
||||
3. Describing the device using device tree
|
||||
==========================================
|
||||
/ {
|
||||
...
|
||||
aliases {
|
||||
Describing the device using device tree
|
||||
---------------------------------------
|
||||
|
||||
.. code-block: none
|
||||
|
||||
/ {
|
||||
...
|
||||
remoteproc0 = &rproc_1;
|
||||
remoteproc1 = &rproc_2;
|
||||
aliases {
|
||||
...
|
||||
remoteproc0 = &rproc_1;
|
||||
remoteproc1 = &rproc_2;
|
||||
|
||||
};
|
||||
...
|
||||
};
|
||||
...
|
||||
|
||||
rproc_1: rproc@1 {
|
||||
compatible = "sandbox,test-processor";
|
||||
remoteproc-name = "remoteproc-test-dev1";
|
||||
};
|
||||
rproc_1: rproc@1 {
|
||||
compatible = "sandbox,test-processor";
|
||||
remoteproc-name = "remoteproc-test-dev1";
|
||||
};
|
||||
|
||||
rproc_2: rproc@2 {
|
||||
compatible = "sandbox,test-processor";
|
||||
internal-memory-mapped;
|
||||
remoteproc-name = "remoteproc-test-dev2";
|
||||
rproc_2: rproc@2 {
|
||||
compatible = "sandbox,test-processor";
|
||||
internal-memory-mapped;
|
||||
remoteproc-name = "remoteproc-test-dev2";
|
||||
};
|
||||
...
|
||||
};
|
||||
...
|
||||
};
|
||||
|
||||
aliases usage is optional, but it is usually recommended to ensure the
|
||||
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
|
||||
===========================================
|
||||
|
||||
Almost all of the serial drivers have been converted as at January 2016. These
|
||||
ones remain:
|
||||
|
||||
serial_bfin.c
|
||||
serial_pxa.c
|
||||
* serial_bfin.c
|
||||
* serial_pxa.c
|
||||
|
||||
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!
|
||||
|
@ -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
|
||||
- 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
|
||||
driver
|
||||
driver
|
||||
- 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
|
||||
- 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
|
||||
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
|
||||
code
|
||||
code
|
||||
|
||||
In terms of patches a conversion series typically has these patches:
|
||||
- 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
|
||||
===============================
|
||||
|
||||
|
@ -24,25 +26,27 @@ Support for EHCI and XHCI
|
|||
So far OHCI is not supported. Both EHCI and XHCI drivers should be declared
|
||||
as drivers in the USB uclass. For example:
|
||||
|
||||
static const struct udevice_id ehci_usb_ids[] = {
|
||||
{ .compatible = "nvidia,tegra20-ehci", .data = USB_CTLR_T20 },
|
||||
{ .compatible = "nvidia,tegra30-ehci", .data = USB_CTLR_T30 },
|
||||
{ .compatible = "nvidia,tegra114-ehci", .data = USB_CTLR_T114 },
|
||||
{ }
|
||||
};
|
||||
.. code-block:: c
|
||||
|
||||
U_BOOT_DRIVER(usb_ehci) = {
|
||||
.name = "ehci_tegra",
|
||||
.id = UCLASS_USB,
|
||||
.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,
|
||||
};
|
||||
static const struct udevice_id ehci_usb_ids[] = {
|
||||
{ .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) = {
|
||||
.name = "ehci_tegra",
|
||||
.id = UCLASS_USB,
|
||||
.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.
|
||||
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:
|
||||
|
||||
- struct usb_device
|
||||
- struct usb_device:
|
||||
This holds information about a device on the bus. All devices have
|
||||
this structure, even the root hub. The controller itself does not
|
||||
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
|
||||
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
|
||||
as a work-around for controllers which can act as USB devices in OTG
|
||||
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
|
||||
device 'dev' with dev_get_parent_platdata(dev). It holds 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
|
||||
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
|
||||
controller uclass. It is mostly used to keep track of the next
|
||||
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
|
||||
- The controller is probed(). This does no enumeration.
|
||||
- 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_setup_device(), passing the port number to be scanned, in this case port
|
||||
0
|
||||
usb_setup_device(), passing the port number to be scanned, in this case
|
||||
port 0
|
||||
- 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
|
||||
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
|
||||
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
|
||||
- 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
|
||||
happen if the device is mentioned in the device tree, or if we previously
|
||||
scanned the bus and so the device was created before
|
||||
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
|
||||
scanned the bus and so the device was created before
|
||||
- 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
|
||||
with USB_DEVICE()). If it finds a match it binds that driver to create a new
|
||||
device.
|
||||
with USB_DEVICE()). If it finds a match it binds that driver to create a
|
||||
new device.
|
||||
- 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
|
||||
functionality will need to be implemented outside the driver model.
|
||||
to allow access to the device (sending it packets, etc.) but all
|
||||
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
|
||||
done, we have a device with the correct uclass. At this point we want to
|
||||
probe the device
|
||||
done, we have a device with the correct uclass. At this point we want to
|
||||
probe the device
|
||||
- first we store basic information about the new device (address, port,
|
||||
speed) in its parent platform data. We cannot store it its private data
|
||||
since that will not exist until the device is probed.
|
||||
speed) in its parent platform data. We cannot store it its private data
|
||||
since that will not exist until the device is probed.
|
||||
- then we call device_probe() which probes the device
|
||||
- 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
|
||||
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
|
||||
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
|
||||
usb_select_config() again to make sure that everything about the device is
|
||||
set up
|
||||
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
|
||||
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
|
||||
(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
|
||||
set up
|
||||
- note that we have called usb_select_config() twice. This is inefficient
|
||||
but the alternative is to store additional information in the platform data.
|
||||
The time taken is minimal and this way is simpler
|
||||
but the alternative is to store additional information in the platform data.
|
||||
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
|
||||
subsystem is concerned
|
||||
subsystem is concerned
|
||||
- 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
|
||||
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() calls usb_hub_scan() to scan the hub, which in turn
|
||||
calls usb_hub_configure()
|
||||
calls usb_hub_configure()
|
||||
- hub power is enabled
|
||||
- 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
|
||||
usb_hub_port_connect_change(). If so, then usb_scan_device() is called to
|
||||
scan the device, passing the appropriate port number.
|
||||
usb_hub_port_connect_change(). If so, then usb_scan_device() is called to
|
||||
scan the device, passing the appropriate port number.
|
||||
- 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
|
||||
continues here (recursively, depth-first)
|
||||
device ready for use. If it is a hub, it will scan that hub before it
|
||||
continues here (recursively, depth-first)
|
||||
- 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
|
||||
|
||||
The above method has some nice properties:
|
||||
|
||||
- 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
|
||||
drivers do not need to know they are on a USB bus, at least so far as
|
||||
enumeration goes
|
||||
drivers do not need to know they are on a USB bus, at least so far as
|
||||
enumeration goes
|
||||
- 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:
|
||||
|
||||
- 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
|
||||
devices
|
||||
devices
|
||||
|
||||
|
||||
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
|
||||
uclass and declares itself as follows:
|
||||
|
||||
U_BOOT_DRIVER(usb_mass_storage) = {
|
||||
.name = "usb_mass_storage",
|
||||
.id = UCLASS_MASS_STORAGE,
|
||||
.of_match = usb_mass_storage_ids,
|
||||
.probe = usb_mass_storage_probe,
|
||||
};
|
||||
.. code-block:: c
|
||||
|
||||
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 */
|
||||
};
|
||||
U_BOOT_DRIVER(usb_mass_storage) = {
|
||||
.name = "usb_mass_storage",
|
||||
.id = UCLASS_MASS_STORAGE,
|
||||
.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 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:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
usb@1 {
|
||||
compatible = "sandbox,usb";
|
||||
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
|
||||
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_hub [ + ] `-- hub
|
||||
usb_emul [ + ] |-- hub-emul
|
||||
usb_emul [ + ] | `-- flash-stick
|
||||
usb_mass_st [ + ] `-- usb_mass_storage
|
||||
usb [ + ] `-- usb@1
|
||||
usb_hub [ + ] `-- hub
|
||||
usb_emul [ + ] |-- hub-emul
|
||||
usb_emul [ + ] | `-- flash-stick
|
||||
usb_mass_st [ + ] `-- usb_mass_storage
|
||||
|
||||
|
||||
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:
|
||||
|
||||
- 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
|
||||
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
|
||||
statically declared in the device tree (which is acceptable for production
|
||||
boards where the same, known, things are on each bus).
|
||||
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
|
||||
statically declared in the device tree (which is acceptable for production
|
||||
boards where the same, known, things are on each bus).
|
||||
|
||||
But in common cases the current algorithm is sufficient.
|
||||
|
||||
|
@ -410,6 +418,6 @@ Other things that need doing:
|
|||
- Implement USB PHYs in driver model
|
||||
- Work out a clever way to provide lazy init for USB devices
|
||||
|
||||
--
|
||||
Simon Glass <sjg@chromium.org>
|
||||
23-Mar-15
|
||||
|
||||
.. Simon Glass <sjg@chromium.org>
|
||||
.. 23-Mar-15
|
|
@ -1,11 +1,68 @@
|
|||
.. SPDX-License-Identifier: GPL-2.0+
|
||||
|
||||
#######################
|
||||
U-Boot Developer Manual
|
||||
#######################
|
||||
.. _u-boot_doc:
|
||||
|
||||
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::
|
||||
:maxdepth: 2
|
||||
|
||||
efi
|
||||
linker_lists
|
||||
serial
|
||||
Driver-Model documentation
|
||||
--------------------------
|
||||
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