u-boot hard fault error after ram initialization - linux

I have ported U-boot on my Waveshare coreH7 stm32h743 board. I have used stm32h743-disco files and device trees as a template for porting. my onboard SDRAM is IS42S16400J that is 8MBytes. I have calculate the parameters of my sdram and I put them in my board device tree file as shown as below:
/*
* Memory configuration from sdram datasheet IS42S32800G-6BLI
* firsct bank is bank#0
* second bank is bank#1
*/
bank2: bank#1 {
st,sdram-control = /bits/ 8 <NO_COL_8
NO_ROW_12
MWIDTH_16
BANKS_4
CAS_3
SDCLK_2
RD_BURST_EN
RD_PIPE_DL_0>;
st,sdram-timing = /bits/ 8 <TMRD_1
TXSR_1
TRAS_1
TRC_6
TRP_2
TWR_1
TRCD_1>;
st,sdram-refcount = <300>;
};
also, I have been configured the rcc values to feed the dram with 100MHz.
but when uboot starts initialization, it goes to hard fault interrupt.
this is the log:
lib/fdtdec.c:fdtdec_setup_mem_size_base_fdt() fdtdec_setup_mem_size_base_fdt: Initial DRAM size 2000000
include/initcall.h:initcall_run_list() initcall: 08008a89
common/board_f.c:setup_dest_addr() Monitor len: 00039F80
common/board_f.c:setup_dest_addr() Ram size: 02000000
common/board_f.c:setup_dest_addr() Ram top: D2000000
include/initcall.h:initcall_run_list() initcall: 08008665
include/initcall.h:initcall_run_list() initcall: 0800117d
arch/arm/lib/cache.c:arm_reserve_mmu() TLB table from d1ff0000 to d1ff4000
include/initcall.h:initcall_run_list() initcall: 080088c3
include/initcall.h:initcall_run_list() initcall: 080088c7
include/initcall.h:initcall_run_list() initcall: 080086b1
common/board_f.c:reserve_uboot() Reserving 231k for U-Boot at: d1fb6000
include/initcall.h:initcall_run_list() initcall: 080088ed
common/board_f.c:reserve_malloc() Reserving 1032k for malloc() at: d1eb4000
include/initcall.h:initcall_run_list() initcall: 08008821
Hard fault
pc : 0800087e lr : 00000000 xPSR : 21000000
r12 : d1eb3ff0 r3 : 00000000 r2 : 00000010
r1 : 00000000 r0 : d1eb3fb0
Resetting CPU ...
what is the problem? is ram initialized unsuccessfully? why? maybe wrong parameters? how Can I know that ram is initialized successfully?
this is normal info log of u-boot:
U-Boot 2020.07-00610-g610e1487c8-dirty (Aug 04 2020 - 00:34:13 +0430)
Model: Waveshare STM32H743i-Coreh7 board
DRAM: Hard fault
pc : 0800087e lr : 00000000 xPSR : 21000000
r12 : d1eb3ff0 r3 : 00000000 r2 : 00000010
r1 : 00000000 r0 : d1eb3fb0
Resetting CPU ...

your ram size is wrong. as you mentioned, the actual ram size is 8MB that is 0x7A1200 in hexadecimal number. but in U-boot log is "Initial DRAM size 2000000". you should change it in the device tree of your board.
memory {
device_type = "memory";
reg = <0xd0000000 0x7A1200>;
};

Related

cma-reserved region appears to be 0 KB even if I added a 'linux,cma node' in the device tree

I wanted to test cma-allocator in linux (5.15.68).
So I added linux,cma node in the /reserved-memory node like this.
reserved-memory {
#address-cells = <2>;
#size-cells = <2>;
ranges;
axpu_reserved_mem: axpursvd#90000000 {
no-map;
reg = <0x0 0xc0000000 0x0 0x8000000>;
};
linux,cma {
compatible = "shared-dma-pool";
reusable;
size = <0 0x30000000>;
alloc-ranges = <0 0x90000000 0 0x30000000>;
linux,cma-default;
};
};
BTW, this test was done on qemu arm64 machine and there is only 1GB ram (from 0x80000000 ~ 0xbfffffff) in the virtual machine, and notice I'm assigning 3/4 of the ram to cma region and 1/8 to a device driver (just for test).
When I boot the machine, I see this message during the boot.
Memory: 1020140K/1048576K available (3200K kernel code, 386K rwdata, 808K rodata, 7808K init, 106K bss, 28436K reserved, 0K cma-reserved)
Why is the CMA-reserved area is 0KB?
This is some config variables I added for CMA test.
CONFIG_MEMORY_ISOLATION=y
CONFIG_CONTIG_ALLOC=y
ONFIG_CMA=y
CONFIG_CMA_DEBUG=y
CONFIG_CMA_DEBUGFS=y
CONFIG_CMA_SYSFS=y
CONFIG_CMA_AREAS=7
# CONFIG_DMA_CMA is not set
I tried adding 'cma=768MB' in the boot args or changed CONFIG_CMA_AREAS to 1 but it is the same.
What am I missing??
I found by adding CONFIG_CMA_DMA=y, the cma-alloc area is reserved.
When I add 'cma=768M' in the boot args, it has the precedence, (I don't know where the kernel placed the cma region).
But when there is no 'cma=768M' in the boot args, the device tree information is used and the CMA area is placed from 0x90000000 as I wanted.

Starting a spidev program during U-boot or right after U-boot

So I need some guidance on how to make spidev run at the very beginning of the kernel init. I am using an ILI9341 display connected to the pocketbeagle that is being driven using SPI. Thing is, I need to "send" an image to the display during boot. For that, I need to start spidev at the very beginning of the boot process, and I am not really sure what process starts spidev. I am not sure if it's something started by a systemd process or elsewhere.
Here is my device tree declaration of spidev (original: am335x-pocketbeagle.dts):
&spi0 {
#address-cells = <1>;
#size-cells = <0>;
status = "okay";
channel#0 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "spidev";
reg = <0>;
spi-max-frequency = <100000000>;
};
channel#1 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "spidev";
reg = <1>;
spi-max-frequency = <100000000>;
status = "disabled";
};
};
&spi1 {
#address-cells = <1>;
#size-cells = <0>;
status = "okay";
channel#0 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "spidev";
reg = <0>;
spi-max-frequency = <100000000>;
};
channel#1 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "spidev";
reg = <1>;
spi-max-frequency = <100000000>;
};
};
Here is the beginning of the boot process (just the first few secs is shown here):
U-Boot SPL 2018.01-dirty (May 06 2018 - 17:12:35)
Trying to boot from MMC1
U-Boot 2018.01-dirty (May 06 2018 - 17:12:35 -0400)
CPU : AM335X-GP rev 2.1
I2C: ready
DRAM: 512 MiB
No match for driver 'omap_hsmmc'
No match for driver 'omap_hsmmc'
Some drivers were not found
Reset Source: Power-on reset has occurred.
MMC: OMAP SD/MMC: 0, OMAP SD/MMC: 1
Using default environment
Model: BeagleBoard.org PocketBeagle
<ethaddr> not set. Validating first E-fuse MAC
Net: usb_ether
Press SPACE to abort autoboot in 2 seconds
board_name=[A335PBGL] ...
switch to partitions #0, OK
mmc0 is current device
SD/MMC found on device 0
** Bad device 0:2 0x82000000 **
** Bad device 0:2 0x82000000 **
switch to partitions #0, OK
mmc0 is current device
Scanning mmc 0:1...
gpio: pin 56 (gpio 56) value is 0
gpio: pin 55 (gpio 55) value is 0
gpio: pin 54 (gpio 54) value is 0
gpio: pin 53 (gpio 53) value is 1
switch to partitions #0, OK
mmc0 is current device
gpio: pin 54 (gpio 54) value is 1
Checking for: /uEnv.txt ...
Checking for: /boot.scr ...
Checking for: /boot/boot.scr ...
Checking for: /boot/uEnv.txt ...
gpio: pin 55 (gpio 55) value is 1
24 bytes read in 15 ms (1000 Bytes/s)
Loaded environment from /boot/uEnv.txt
Checking if uname_r is set in /boot/uEnv.txt...
gpio: pin 56 (gpio 56) value is 1
Running uname_boot ...
loading /boot/vmlinuz-4.4.113-ti-r149 ...
9431560 bytes read in 612 ms (14.7 MiB/s)
loading /boot/dtbs/4.4.113-ti-r149/am335x-pocketbeagle.dtb ...
130113 bytes read in 84 ms (1.5 MiB/s)
uboot_overlays: add [enable_uboot_overlays=1] to /boot/uEnv.txt to enable...
debug: [console=ttyO0,115200n8 root=/dev/mmcblk0p1 ro rootfstype=ext4 rootwait] ...
debug: [bootz 0x82000000 - 0x88000000] ...
## Flattened Device Tree blob at 88000000
Booting using the fdt blob at 0x88000000
Loading Device Tree to 8ffdd000, end 8ffffc40 ... OK
Starting kernel ...
[ 0.000000] Booting Linux on physical CPU 0x0
[ 0.000000] Initializing cgroup subsys cpuset
[ 0.000000] Initializing cgroup subsys cpu
[ 0.000000] Initializing cgroup subsys cpuacct
[ 0.000000] Linux version 4.4.113-ti-r149 (luis#luis) (gcc version 5.5.0 (Lin aro GCC 5.5-2017.10) ) #2 SMP Fri Jun 29 16:50:45 EDT 2018
[ 0.000000] CPU: ARMv7 Processor [413fc082] revision 2 (ARMv7), cr=10c5387d
[ 0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instructio n cache
[ 0.000000] Machine model: TI AM335x PocketBeagle
[ 0.000000] cma: Reserved 48 MiB at 0x9c800000
[ 0.000000] Memory policy: Data cache writeback
[ 0.000000] CPU: All CPU(s) started in SVC mode.
[ 0.000000] AM335X ES2.1 (sgx neon )
[ 0.000000] PERCPU: Embedded 13 pages/cpu #df8f2000 s24192 r8192 d20864 u5324 8
[ 0.000000] Built 1 zonelists in Zone order, mobility grouping on. Total pag es: 129408
[ 0.000000] Kernel command line: console=ttyO0,115200n8 root=/dev/mmcblk0p1 r o rootfstype=ext4 rootwait
[ 0.000000] PID hash table entries: 2048 (order: 1, 8192 bytes)
[ 0.000000] Dentry cache hash table entries: 65536 (order: 6, 262144 bytes)
[ 0.000000] Inode-cache hash table entries: 32768 (order: 5, 131072 bytes)
[ 0.000000] Memory: 448072K/522240K available (12533K kernel code, 1016K rwda ta, 4064K rodata, 824K init, 857K bss, 25016K reserved, 49152K cma-reserved, 0K highmem)
[ 0.000000] Virtual kernel memory layout:
[ 0.000000] vector : 0xffff0000 - 0xffff1000 ( 4 kB)
[ 0.000000] fixmap : 0xffc00000 - 0xfff00000 (3072 kB)
[ 0.000000] vmalloc : 0xe0800000 - 0xff800000 ( 496 MB)
[ 0.000000] lowmem : 0xc0000000 - 0xe0000000 ( 512 MB)
[ 0.000000] pkmap : 0xbfe00000 - 0xc0000000 ( 2 MB)
[ 0.000000] modules : 0xbf000000 - 0xbfe00000 ( 14 MB)
[ 0.000000] .text : 0xc0008000 - 0xc103d760 (16598 kB)
[ 0.000000] .init : 0xc103e000 - 0xc110c000 ( 824 kB)
[ 0.000000] .data : 0xc110c000 - 0xc120a0e8 (1017 kB)
[ 0.000000] .bss : 0xc120d000 - 0xc12e355c ( 858 kB)
[ 0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[ 0.000000] Hierarchical RCU implementation.
[ 0.000000] Build-time adjustment of leaf fanout to 32.
[ 0.000000] RCU restricting CPUs from NR_CPUS=2 to nr_cpu_ids=1.
[ 0.000000] RCU: Adjusting geometry for rcu_fanout_leaf=32, nr_cpu_ids=1
[ 0.000000] NR_IRQS:16 nr_irqs:16 16
[ 0.000000] IRQ: Found an INTC at 0xfa200000 (revision 5.0) with 128 interrup ts
[ 0.000000] OMAP clockevent source: timer2 at 24000000 Hz
[ 0.000022] sched_clock: 32 bits at 24MHz, resolution 41ns, wraps every 89478 484971ns
[ 0.000048] clocksource: timer1: mask: 0xffffffff max_cycles: 0xffffffff, max _idle_ns: 79635851949 ns
[ 0.000061] OMAP clocksource: timer1 at 24000000 Hz
[ 0.001914] clocksource_probe: no matching clocksources found
[ 0.002223] Console: colour dummy device 80x30
[ 0.002254] WARNING: Your 'console=ttyO0' has been replaced by 'ttyS0'
[ 0.002262] This ensures that you still see kernel messages. Please
[ 0.002268] update your kernel commandline.
[ 0.002289] Calibrating delay loop... 995.32 BogoMIPS (lpj=1990656)
[ 0.021215] pid_max: default: 32768 minimum: 301
[ 0.021365] Security Framework initialized
[ 0.021380] Yama: becoming mindful.
[ 0.021418] AppArmor: AppArmor disabled by boot time parameter
[ 0.021590] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes)
[ 0.021603] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes)
[ 0.022464] Initializing cgroup subsys io
[ 0.022497] Initializing cgroup subsys memory
[ 0.022543] Initializing cgroup subsys devices
[ 0.022561] Initializing cgroup subsys freezer
[ 0.022578] Initializing cgroup subsys net_cls
[ 0.022592] Initializing cgroup subsys perf_event
[ 0.022607] Initializing cgroup subsys net_prio
[ 0.022630] Initializing cgroup subsys pids
[ 0.022688] CPU: Testing write buffer coherency: ok
[ 0.022747] ftrace: allocating 37522 entries in 111 pages
[ 0.128715] CPU0: thread -1, cpu 0, socket -1, mpidr 0
[ 0.128838] Setting up static identity map for 0x80008280 - 0x800082e0
[ 0.133343] Brought up 1 CPUs
[ 0.133369] SMP: Total of 1 processors activated (995.32 BogoMIPS).
[ 0.133377] CPU: All CPU(s) started in SVC mode.
[ 0.134975] devtmpfs: initialized
[ 0.172782] VFP support v0.3: implementor 41 architecture 3 part 30 variant c rev 3
[ 0.223366] omap_hwmod: debugss: _wait_target_disable failed
[ 0.277491] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, ma x_idle_ns: 7645041785100000 ns
[ 0.277527] futex hash table entries: 256 (order: 2, 16384 bytes)
[ 0.281782] xor: measuring software checksum speed
[ 0.321202] arm4regs : 1219.000 MB/sec
[ 0.361191] 8regs : 957.000 MB/sec
[ 0.401188] 32regs : 1089.000 MB/sec
[ 0.441187] neon : 1725.000 MB/sec
[ 0.441195] xor: using function: neon (1725.000 MB/sec)
[ 0.441228] pinctrl core: initialized pinctrl subsystem
[ 0.442711] NET: Registered protocol family 16
[ 0.445513] DMA: preallocated 256 KiB pool for atomic coherent allocations
[ 0.446456] cpuidle: using governor ladder
[ 0.446477] cpuidle: using governor menu
[ 0.452463] OMAP GPIO hardware version 0.1
[ 0.475562] No ATAGs?
[ 0.475601] hw-breakpoint: debug architecture 0x4 unsupported.
[ 0.476766] omap4_sram_init:Unable to allocate sram needed to handle errata I 688
[ 0.476789] omap4_sram_init:Unable to get sram pool needed to handle errata I 688
[ 0.557214] raid6: neonx2 gen() 1887 MB/s
[ 0.625198] raid6: neonx2 xor() 1161 MB/s
[ 0.625207] raid6: using algorithm neonx2 gen() 1887 MB/s
[ 0.625214] raid6: .... xor() 1161 MB/s, rmw enabled
[ 0.625221] raid6: using intx1 recovery algorithm
[ 0.635476] edma 49000000.edma: TI EDMA DMA engine driver
[ 0.640859] vgaarb: loaded
[ 0.641610] SCSI subsystem initialized
[ 0.642367] usbcore: registered new interface driver usbfs
[ 0.642449] usbcore: registered new interface driver hub
[ 0.642560] usbcore: registered new device driver usb
[ 0.643413] omap_i2c 44e0b000.i2c: could not find pctldev for node /ocp/l4_wk up#44c00000/scm#210000/pinmux#800/pinmux_i2c0_pins, deferring probe
[ 0.644286] omap_i2c 4802a000.i2c: bus 1 rev0.11 at 400 kHz
[ 0.644967] omap_i2c 4819c000.i2c: bus 2 rev0.11 at 400 kHz
[ 0.645404] media: Linux media interface: v0.10
[ 0.645482] Linux video capture interface: v2.00
[ 0.645611] pps_core: LinuxPPS API ver. 1 registered
[ 0.645620] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giome tti <giometti#linux.it>
[ 0.645655] PTP clock support registered
[ 0.646615] omap-mailbox 480c8000.mailbox: omap mailbox rev 0x400
[ 0.648938] NetLabel: Initializing
[ 0.648955] NetLabel: domain hash size = 128
[ 0.648961] NetLabel: protocols = UNLABELED CIPSOv4
[ 0.649029] NetLabel: unlabeled traffic allowed by default
[ 0.649769] clocksource: Switched to clocksource timer1
[ 0.773340] NET: Registered protocol family 2
[ 0.774347] TCP established hash table entries: 4096 (order: 2, 16384 bytes)
[ 0.774397] TCP bind hash table entries: 4096 (order: 3, 32768 bytes)
[ 0.774456] TCP: Hash tables configured (established 4096 bind 4096)
[ 0.774539] UDP hash table entries: 256 (order: 1, 8192 bytes)
[ 0.774560] UDP-Lite hash table entries: 256 (order: 1, 8192 bytes)
[ 0.774925] NET: Registered protocol family 1
[ 0.775551] RPC: Registered named UNIX socket transport module.
[ 0.775567] RPC: Registered udp transport module.
[ 0.775574] RPC: Registered tcp transport module.
[ 0.775580] RPC: Registered tcp NFSv4.1 backchannel transport module.
[ 0.776750] hw perfevents: enabled with armv7_cortex_a8 PMU driver, 5 counter s available
[ 0.780201] audit: initializing netlink subsys (disabled)
[ 0.780300] audit: type=2000 audit(0.712:1): initialized
[ 0.790964] zbud: loaded
[ 0.791713] VFS: Disk quotas dquot_6.6.0
[ 0.791995] VFS: Dquot-cache hash table entries: 1024 (order 0, 4096 bytes)
[ 0.795073] NFS: Registering the id_resolver key type
[ 0.795149] Key type id_resolver registered
[ 0.795157] Key type id_legacy registered
[ 0.795187] nfs4filelayout_init: NFSv4 File Layout Driver Registering...
[ 0.795579] fuse init (API version 7.23)
[ 0.796227] SGI XFS with ACLs, security attributes, realtime, no debug enable d
[ 0.805645] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 2 47)
[ 0.806079] io scheduler noop registered
[ 0.806100] io scheduler deadline registered
[ 0.806175] io scheduler cfq registered (default)
[ 0.808070] pinctrl-single 44e10800.pinmux: 142 pins at pa f9e10800 size 568
[ 0.809173] gpio-of-helper ocp:cape-universal: Allocated GPIO id=0
[ 0.809332] gpio-of-helper ocp:cape-universal: Allocated GPIO id=1
[ 0.809521] gpio-of-helper ocp:cape-universal: Allocated GPIO id=2
[ 0.809670] gpio-of-helper ocp:cape-universal: Allocated GPIO id=3
[ 0.810219] gpio-of-helper ocp:cape-universal: Allocated GPIO id=4
[ 0.810400] gpio-of-helper ocp:cape-universal: Allocated GPIO id=5
[ 0.810547] gpio-of-helper ocp:cape-universal: Allocated GPIO id=6
[ 0.810691] gpio-of-helper ocp:cape-universal: Allocated GPIO id=7
[ 0.810844] gpio-of-helper ocp:cape-universal: Allocated GPIO id=8
[ 0.811050] gpio-of-helper ocp:cape-universal: Allocated GPIO id=9
[ 0.811224] gpio-of-helper ocp:cape-universal: Allocated GPIO id=10
[ 0.811392] gpio-of-helper ocp:cape-universal: Allocated GPIO id=11
[ 0.811539] gpio-of-helper ocp:cape-universal: Allocated GPIO id=12
[ 0.811692] gpio-of-helper ocp:cape-universal: Allocated GPIO id=13
[ 0.811838] gpio-of-helper ocp:cape-universal: Allocated GPIO id=14
[ 0.811988] gpio-of-helper ocp:cape-universal: Allocated GPIO id=15
[ 0.812144] gpio-of-helper ocp:cape-universal: Allocated GPIO id=16
[ 0.812293] gpio-of-helper ocp:cape-universal: Allocated GPIO id=17
[ 0.812445] gpio-of-helper ocp:cape-universal: Allocated GPIO id=18
[ 0.812598] gpio-of-helper ocp:cape-universal: Allocated GPIO id=19
[ 0.812752] gpio-of-helper ocp:cape-universal: Allocated GPIO id=20
[ 0.812907] gpio-of-helper ocp:cape-universal: Allocated GPIO id=21
[ 0.813055] gpio-of-helper ocp:cape-universal: Allocated GPIO id=22
[ 0.813189] gpio-of-helper ocp:cape-universal: Allocated GPIO id=23
[ 0.813332] gpio-of-helper ocp:cape-universal: Allocated GPIO id=24
[ 0.813467] gpio-of-helper ocp:cape-universal: Allocated GPIO id=25
[ 0.813602] gpio-of-helper ocp:cape-universal: Allocated GPIO id=26
[ 0.813842] gpio-of-helper ocp:cape-universal: Allocated GPIO id=27
[ 0.814192] gpio-of-helper ocp:cape-universal: Allocated GPIO id=28
[ 0.814350] gpio-of-helper ocp:cape-universal: Allocated GPIO id=29
[ 0.814491] gpio-of-helper ocp:cape-universal: Allocated GPIO id=30
[ 0.814629] gpio-of-helper ocp:cape-universal: Allocated GPIO id=31
[ 0.814774] gpio-of-helper ocp:cape-universal: Allocated GPIO id=32
[ 0.814911] gpio-of-helper ocp:cape-universal: Allocated GPIO id=33
[ 0.815048] gpio-of-helper ocp:cape-universal: Allocated GPIO id=34
[ 0.815196] gpio-of-helper ocp:cape-universal: Allocated GPIO id=35
[ 0.815338] gpio-of-helper ocp:cape-universal: Allocated GPIO id=36
[ 0.815485] gpio-of-helper ocp:cape-universal: Allocated GPIO id=37
[ 0.815624] gpio-of-helper ocp:cape-universal: Allocated GPIO id=38
[ 0.815762] gpio-of-helper ocp:cape-universal: Allocated GPIO id=39
[ 0.815909] gpio-of-helper ocp:cape-universal: Allocated GPIO id=40
[ 0.816053] gpio-of-helper ocp:cape-universal: Allocated GPIO id=41
[ 0.816194] gpio-of-helper ocp:cape-universal: Allocated GPIO id=42
[ 0.816343] gpio-of-helper ocp:cape-universal: Allocated GPIO id=43
[ 0.816354] gpio-of-helper ocp:cape-universal: ready
[ 0.822156] wkup_m3_ipc 44e11324.wkup_m3_ipc: could not get rproc handle
[ 0.824170] Serial: 8250/16550 driver, 6 ports, IRQ sharing disabled
[ 0.827881] 44e09000.serial: ttyS0 at MMIO 0x44e09000 (irq = 158, base_baud = 3000000) is a 8250
[ 1.921701] console [ttyS0] enabled
"Important" things like GPIOs and I2C appear to be running at the very beginning of the boot process. How could I do the same thing with spidev?
I am a little unclear where in the boot process is the pocketbeagle's device tree being "declared"? Where in the boot process does /dev/spidev becomes available? And how can I make it start earlier?
Summarizing #sawdust and my comments into an answer:
Don't use SPIdev for this
Use the Linux Framebuffer drivers for small TFT LCD display modules
Set bootdelay to 0 or -2 in U-Boot Env
Don't worry about the warning, you can recover and modify the Env file by booting from SD card or if on SD, by modifying its contents on a computer.
Add a systemd service to render your splash screen early during boot
Simple and has some good pointers
Quite verbose, not everything applies (e.g. console), but might contain some good bits to selectively pick out

If I have only one PCIe EP and only one function, Do I need “interrupt-map” function in device tree (DTS)?

I’m using legacy PCIe Interrupt mechanism(Virtual INTx), As per my PCIe controller user guide, In legacy Interrupt mechanism Assert or Deassert Virtual INTx messages will be received from the EP device and according to that PCIe Core it will generate or clear interrupt signal respectively.
If I have only one EP and only one function, Do I need “interrupt-map” function in device tree (DTS)?
As per my understanding,
PCIe EP will send Assert_INTA message
PCIe RP decode this message and send Interrupt to Interrupt generating pin INTA_OUT
In design INTA_OUT is directly connected to Interrupt controller Input pin
In Linux kernel this IRQ will invoke PCIe RP ISR and also Endpoint functions ISR
Am I correct in my understanding ?
pci#0xfb000000 {
interrupts = <1 1>; //PCIe RP INTA  IRQ1, Only this info is enough ??
interrupt-parent = <&pic>;
/*Do we need follow info also ??? */
#interrupt-cells = <0x1>;
interrupt-map-mask = <0x0 0x0 0x0 0x7>;
interrupt-map = < 0x0 0x0 0x0 0x1 &pcie_intc 0x1
0x0 0x0 0x0 0x2 &pcie_intc 0x2
0x0 0x0 0x0 0x3 &pcie_intc 0x3
0x0 0x0 0x0 0x4 &pcie_intc 0x4 >;
}

Accessing external bus in kernel space on an ARM based board

I'm trying to write an LCD display driver on an ARM based board.
The LCD controller is plugged on the external memory bus.
So I try to convert the physical address of registers of the controller to the virtual one.
I use the following pieces of code to do that :
#define AT91_VA_BASE_CS2 phys_to_virt(0x50000000)
static inline unsigned char at91_CS2_read(unsigned int reg)
{
void __iomem *CS2_base = (void __iomem *)AT91_VA_BASE_CS2;
return __raw_readb(CS2_base + reg);
}
static inline void at91_CS2_write(unsigned int reg, unsigned char value)
{
void __iomem *CS2_base = (void __iomem *)AT91_VA_BASE_CS2;
__raw_writeb(value, CS2_base + reg);
}
void write_lcd_port (int mode, unsigned char cmd_dat)
{
while ((read_lcd_port() & 0x03) != 0x03) {
/* wait while LCD is busy!!! */
} /* endwhile */
/* Send Command */
if (mode == 1)
{
at91_CS2_write(4, cmd_dat);
}
/* Send Data */
if (mode == 0)
{
at91_CS2_write(0, cmd_dat);
}
}
I get the following message :
Unable to handle kernel paging request at virtual address 4f000004
pgd = c39bc000
[4f000004] *pgd=00000000
Internal error: Oops: 5 [#1]
Modules linked in: module_complet dm9000 at91_wdt vfat fat jffs2 nls_iso8859_1 nls_cp437 nls_base usb_storage sd_mod sg scsie
CPU: 0
PC is at read_lcd_port+0x1c/0x38 [module_complet]
LR is at 0x1
pc : [<bf0a21b8>] lr : [<00000001>] Tainted: P
sp : c380bf1c ip : 60000093 fp : c380bf2c
r10: 0003a804 r9 : c380a000 r8 : c001de64
r7 : 00000000 r6 : fefff000 r5 : 0000009c r4 : 00000001
r3 : 4f000000 r2 : 00000000 r1 : 00001438 r0 : bf0a25cc
Flags: nZCv IRQs on FIQs on Mode SVC_32 Segment user
Control: C000717F Table: 239BC000 DAC: 00000015
Process insmod (pid: 903, stack limit = 0xc380a198)
Stack: (0xc380bf1c to 0xc380c000)
bf00: 00000001
bf20: c380bf44 c380bf30 bf0a21f4 bf0a21ac 00000000 fefa0000 c380bf54 c380bf48
bf40: bf0a2288 bf0a21e4 c380bf64 c380bf58 bf0a246c bf0a2280 c380bf84 c380bf68
bf60: bf0a4058 bf0a2464 40017000 c01c89a0 bf0a2d80 c01c8990 c380bfa4 c380bf88
bf80: c004cd20 bf0a4010 00000003 00000000 0000000c 00000080 00000000 c380bfa8
bfa0: c001dcc0 c004cbc8 00000000 0000000c 00900080 40017000 0000162e 00041050
bfc0: 00000003 00000000 0000000c bea0fde4 bea0fec4 00000002 0003a804 00000000
bfe0: bea0fd10 bea0fd04 0001b290 400d1d20 60000010 00900080 20002031 20002431
Backtrace:
[<bf0a219c>] (read_lcd_port+0x0/0x38 [module_complet]) from [<bf0a21f4>] (write_lcd_port+0x20/0x80 [module_complet])
r4 = 00000001
[<bf0a21d4>] (write_lcd_port+0x0/0x80 [module_complet]) from [<bf0a2288>] (wr_cmd+0x18/0x1c [module_complet])
r5 = FEFA0000 r4 = 00000000
[<bf0a2270>] (wr_cmd+0x0/0x1c [module_complet]) from [<bf0a246c>] (lcd_init+0x18/0x80 [module_complet])
[<bf0a2454>] (lcd_init+0x0/0x80 [module_complet]) from [<bf0a4058>] (mon_module_init+0x58/0xcc [module_complet])
[<bf0a4000>] (mon_module_init+0x0/0xcc [module_complet]) from [<c004cd20>] (sys_init_module+0x168/0x2c8)
r6 = C01C8990 r5 = BF0A2D80 r4 = C01C89A0
[<c004cbb8>] (sys_init_module+0x0/0x2c8) from [<c001dcc0>] (ret_fast_syscall+0x0/0x2c)
r7 = 00000080 r6 = 0000000C r5 = 00000000 r4 = 00000003
Code: e59f001c eb3e43c2 e3a0344f e59f0014 (e5d34004)
Segmentation fault
Note that this method works for internal peripherals (such as timers).
So in some cases, phys_to_virt works.
I think that no page is allocated at the address 0x50000000. How can I allocate a page at this specific address ?
I found functions like kmap but it seems to be very complicated and I don't know how to use it.
The best way to access memory-mapped peripherals is with the kernel's ioremap and friends.
First, declare that you want to use a specific region of memory for your peripheral:
struct resource *res = request_mem_region(0x50000000, region_size, "at91");
When you unload your driver, you will want to free that memory region.
release_mem_region(0x50000000, region_size);
Now, you can remap the I/O region before use.
void *ptr = ioremap(0x50000000, region_size);
If you want to prevent caching of these registers, use ioremap_nocache instead. You can also only remap a subregion of your device's memory space if you're only using that part.
Now that you have the iomapped region, you can do I/O on that memory.
iowrite8(value, (char *)ptr + reg);
unsigned int val = ioread8((char *)ptr + reg);
Once you're done reading from and writing to that region of memory, you can unmap it.
iounmap(ptr);
I hope this helps. I would recommend reading (or at least using as a reference) Linux Device Drivers, 3rd Edition, which can be read online for free.

Why can't I register edge triggered interrupts in Linux 2.6.26?

First time poster, so please excuse any stupidity.
I'm working on porting a custom CPLD driver on a linux kernel built for an MPC83xx from 2.6.22 to 2.6.26, and am receiving an unexpected Oops. The driver works fine for the .22 kernel, but the .26 kernel chokes on my call to request_irq. Does anybody know why there was a change in behavior, or better yet, what I need to do to resolve it?
I've tracked down the source of the Oops to a call to kernel/irq/manage.c, where desc->chip->enable(irq) is called in setup_irq(), and it looks like the function pointer to enable is being cleared in a call to ipic_set_irq_type() in arch/powerpc/sysdev/ipic.c. Unfortunately, I have no clue why.
I've included both the Oops and a sample kernel modules that replicates the issue.
Oops -
Unable to handle kernel paging request for instruction fetch
Faulting instruction address: 0x00000000
Oops: Kernel access of bad area, sig: 11 [#1]
PREEMPT SCPA-G2
Modules linked in: cpld(+)
NIP: 00000000 LR: c004b930 CTR: 00000000
REGS: df8b5df0 TRAP: 0400 Not tainted (2.6.26-twacs-100.0.0)
MSR: 20001032 <ME,IR,DR> CR: 24022422 XER: 20000000
TASK = dfbcfc00[488] 'insmod' THREAD: df8b4000
GPR00: 00000000 df8b5ea0 dfbcfc00 00000017 00000001 00000001 00000000 c02d1fb4
GPR08: 00002268 00000000 00000000 00000000 44022484 10073f68 1ffcb000 007ffeb0
GPR16: 00000000 00000000 00800000 00000000 bffff7f0 00000000 1006e3dc 00000000
GPR24: 00000002 00000000 00000000 00009032 df9d04c0 00000017 df8b4000 c02d40e4
NIP [00000000] 0x0
LR [c004b930] setup_irq+0x404/0x430
Call Trace:
[df8b5ea0] [c004b8ec] setup_irq+0x3c0/0x430 (unreliable)
[df8b5ed0] [c004bbd8] request_irq+0xe0/0x130
[df8b5f00] [e1078054] cpld_init+0x54/0xd0 [cpld]
[df8b5f10] [c0048ba0] sys_init_module+0x14c/0x1d8
[df8b5f40] [c0010008] ret_from_syscall+0x0/0x38
--- Exception: c01 at 0xff27bb0
LR = 0x10019ca8
Instruction dump:
XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX
XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX
Kernel panic - not syncing: Fatal exception
Module -
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/module.h>
static unsigned int cpld_virq = NO_IRQ;
unsigned value = 0xdeadbeef;
static irqreturn_t cpld_isr(int irq, void *dev_id) {
return IRQ_HANDLED;
}
void __exit cpld_cleanup(void) {
free_irq(cpld_interrupt, &value);
irq_dispose_mapping(cpld_virq);
return;
}
int __init cpld_init(void) {
int retval;
unsigned long cpld_interrupt = 23;
cpld_virq = irq_create_mapping(NULL, cpld_interrupt);
if (cpld_virq == NO_IRQ) {
return -EBUSY;
}
retval = request_irq(cpld_virq, cpld_isr,
IRQF_DISABLED | IRQF_SHARED | IRQF_TRIGGER_FALLING,
"CPLD", &value);
if (retval) {
irq_dispose_mapping(cpld_virq);
return retval;
}
return 0;
}
module_init(cpld_init);
module_exit(cpld_cleanup);
MODULE_LICENSE("Dual BSD/GPL");
Thanks for the help. I've been beating my head on this for several days now, and am open to any suggestions.
My copy of the 2.6.26 kernel's ipic_set_irq_type() doesn't do anything with the enable() pointer. It does, however, have the following comments that were not in 2.6.22:
/* ipic only supports low assertion and high-to-low change senses
*/
and
/* ipic supports only edge mode on external interrupts */
It looks like what you were doing on 2.6.22 was not supported by the hardware.
Aaah. Sounds like JayM was close, though not for the reason he thought. I just saw a patch go across the linuxppc-dev mailing list stating that edge supported interrupts were broken.
http://lkml.org/lkml/2010/5/3/363
This may not be the root cause, but is indicative of a problem I'm not going to fix.

Resources