Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 78 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
# Needed to compile targets of different architectures
convert_target_arm64 = $(patsubst %.o,%.arm64.o,$1)
convert_target_rk356x = $(patsubst %.o,%.rk356x.o,$1)

XROCK ?= xrock
ARMCC ?= aarch64-linux-gnu

all: makeboot.out rock.out pinebook.bin pinebook-ddr.bin opi5.bin genbook.bin genbook-ddr.bin genbook_demo.img demo_pinebook.img
all: pinebook.img genbook.img
all: roc3566.bin demo_roc3566.bin roc3566.img demo_roc3566.img
all: yy3568.bin demo_yy3568.bin yy3568.img demo_yy3568.img
all: rock3a.bin demo_rock3a.bin rock3a.img demo_rock3a.img

ARMCFLAGS := -march=armv8-a -nostdlib -Wall -Wno-array-bounds -Isrc -Isrc/rk3399 -Isrc/rk3588 -ffunction-sections -ffreestanding
ARMCFLAGS := -march=armv8-a -nostdlib -Wall -Wno-array-bounds -Isrc -Isrc/rk3399 -Isrc/rk3588 -Isrc/rk356x -ffunction-sections -ffreestanding
ARMLDFLAGS := -T Linker.ld --gc-sections
# Align+pad to _end_of_image defined in linker script
OBJCOPYFLAGS = --pad-to 0x`readelf -s src/$@.elf | awk '/_end_of_image/ {print $$2}'`
Expand All @@ -22,14 +26,14 @@ $(call convert_target_arm64,src/rk3399/ram2.o): ARMCFLAGS += -Os
GENBOOK_DDR_OBJ := $(call convert_target_arm64,src/rk3588/ddr.o src/rk3588/genbook-ddr.o src/rk3588/gpio.o src/rk3588/pwm.o src/lib.o)

3399_OBJ := src/boot.o src/mmu.o src/asm.o src/pl011.o src/vectors.o src/rk3399/gpio.o src/rk3399/timer.o src/analogix_edp.o src/rk3399/vop.o src/firmware.o
3399_OBJ += src/rk3399/clock.o src/rk3399/soc.o src/lib.o src/ohci.o src/rk3399/mmc.o src/rk3399/io.o
3399_OBJ += src/rk3399/clock.o src/rk3399/soc.o src/lib.o src/ohci.o src/hid_keyboard.o src/input.o src/rk3399/mmc.o src/rk3399/io.o

PINEBOOK_OBJ := $(3399_OBJ) src/pinebook.o
PINEBOOK_OBJ := $(call convert_target_arm64,$(PINEBOOK_OBJ))
$(PINEBOOK_OBJ): src/rk3399/pinebook.dtb.out.h

3588_OBJ := src/boot.o src/rk3588/io.o src/rk3588/sgrf.o src/rk3588/ioc.o src/rk3588/pmu.o src/rk3588/cru.o src/rk3588/vop2.o src/rk3588/video.o src/rk3588/gpio.o src/rk3588/pwm.o
3588_OBJ += src/pl011.o src/asm.o src/vectors.o src/mmu.o src/lib.o src/firmware.o src/analogix_edp.o
3588_OBJ += src/pl011.o src/asm.o src/vectors.o src/mmu.o src/lib.o src/firmware.o src/input.o src/analogix_edp.o
3588_OBJ += external/samsung_phy_edp.o

OPI5_OBJ := $(3588_OBJ) src/opi5.o
Expand All @@ -39,6 +43,19 @@ GENBOOK_OBJ := $(3588_OBJ) src/genbook.o
GENBOOK_OBJ := $(call convert_target_arm64,$(GENBOOK_OBJ))
$(GENBOOK_OBJ): src/rk3588/genbook.dtb.out.h

RK356X_OBJ := src/boot.o src/mmu.o src/asm.o src/pl011.o src/vectors.o src/lib.o
RK356X_OBJ += src/firmware.o src/input.o src/hid_keyboard.o src/ohci.o src/edid.o
RK356X_OBJ += src/rk356x/board.o src/rk356x/io.o src/rk356x/dram.o src/rk356x/gpio.o src/rk356x/sgrf.o
RK356X_OBJ += src/rk356x/cru.o src/rk356x/vop2.o src/rk356x/hdmi.o src/rk356x/usb.o
RK356X_OBJ := $(call convert_target_rk356x,$(RK356X_OBJ))

ROC3566_OBJ := $(RK356X_OBJ) src/roc3566.rk356x.o
YY3568_OBJ := $(RK356X_OBJ) src/yy3568.rk356x.o
ROCK3A_OBJ := $(RK356X_OBJ) src/rock3a.rk356x.o
$(ROC3566_OBJ): src/rk356x/roc3566.dtb.out.h
$(YY3568_OBJ): src/rk356x/yy3568.dtb.out.h
$(ROCK3A_OBJ): src/rk356x/rock3a.dtb.out.h

DEMO_OBJ := demo/entry.o demo/main.o demo/bmp.o demo/vectors.o
DEMO_OBJ := $(call convert_target_arm64,$(DEMO_OBJ))

Expand Down Expand Up @@ -81,6 +98,18 @@ genbook.bin: $(GENBOOK_OBJ) Linker.ld
$(ARMCC)-ld $(GENBOOK_OBJ) $(ARMLDFLAGS) -o src/$@.elf
$(ARMCC)-objcopy $(OBJCOPYFLAGS) -O binary src/$@.elf genbook.bin

roc3566.bin: $(ROC3566_OBJ) Linker.ld
$(ARMCC)-ld $(ROC3566_OBJ) $(ARMLDFLAGS) -o src/$@.elf
$(ARMCC)-objcopy $(OBJCOPYFLAGS) -O binary src/$@.elf $@

yy3568.bin: $(YY3568_OBJ) Linker.ld
$(ARMCC)-ld $(YY3568_OBJ) $(ARMLDFLAGS) -o src/$@.elf
$(ARMCC)-objcopy $(OBJCOPYFLAGS) -O binary src/$@.elf $@

rock3a.bin: $(ROCK3A_OBJ) Linker.ld
$(ARMCC)-ld $(ROCK3A_OBJ) $(ARMLDFLAGS) -o src/$@.elf
$(ARMCC)-objcopy $(OBJCOPYFLAGS) -O binary src/$@.elf $@

demo.bin: $(DEMO_OBJ)
$(ARMCC)-ld $(DEMO_OBJ) -Ttext=0xa00000 -o src/$@.elf
$(ARMCC)-objcopy -O binary src/$@.elf demo.bin
Expand All @@ -91,6 +120,33 @@ demo_pinebook.bin: demo.bin pinebook.bin
demo_genbook.bin: demo.bin genbook.bin
cat genbook.bin demo.bin > demo_genbook.bin

demo_roc3566.bin: demo.bin roc3566.bin
cat roc3566.bin demo.bin > $@

demo_yy3568.bin: demo.bin yy3568.bin
cat yy3568.bin demo.bin > $@

demo_rock3a.bin: demo.bin rock3a.bin
cat rock3a.bin demo.bin > $@

roc3566.img: makeboot.out img/rk3566_ddr_1056MHz_v1.25.bin roc3566.bin
./makeboot.out --v2 --ddr img/rk3566_ddr_1056MHz_v1.25.bin --os roc3566.bin -o $@

demo_roc3566.img: makeboot.out img/rk3566_ddr_1056MHz_v1.25.bin demo_roc3566.bin
./makeboot.out --v2 --ddr img/rk3566_ddr_1056MHz_v1.25.bin --os demo_roc3566.bin -o $@

yy3568.img: makeboot.out img/rk3568_ddr_1560MHz_v1.25.bin yy3568.bin
./makeboot.out --v2 --ddr img/rk3568_ddr_1560MHz_v1.25.bin --os yy3568.bin -o $@

demo_yy3568.img: makeboot.out img/rk3568_ddr_1560MHz_v1.25.bin demo_yy3568.bin
./makeboot.out --v2 --ddr img/rk3568_ddr_1560MHz_v1.25.bin --os demo_yy3568.bin -o $@

rock3a.img: makeboot.out img/rk3568_ddr_1560MHz_v1.25.bin rock3a.bin
./makeboot.out --v2 --ddr img/rk3568_ddr_1560MHz_v1.25.bin --os rock3a.bin -o $@

demo_rock3a.img: makeboot.out img/rk3568_ddr_1560MHz_v1.25.bin demo_rock3a.bin
./makeboot.out --v2 --ddr img/rk3568_ddr_1560MHz_v1.25.bin --os demo_rock3a.bin -o $@

makeboot.out: tools/makeboot.o
$(CC) tools/makeboot.o -o makeboot.out

Expand All @@ -103,6 +159,10 @@ rock.out: tools/rock.o
$(ARMCC)-gcc -MMD -c $< $(ARMCFLAGS) -o $@
%.arm64.o: %.S
$(ARMCC)-gcc -D __ASM__ -MMD -c $< $(ARMCFLAGS) -o $@
%.rk356x.o: %.c
$(ARMCC)-gcc -MMD -c $< $(ARMCFLAGS) -DSTACK_TOP=0x08000000 -o $@
%.rk356x.o: %.S
$(ARMCC)-gcc -D __ASM__ -MMD -c $< $(ARMCFLAGS) -DSTACK_TOP=0x08000000 -o $@

%.dtb.out.h: %.dts
set -o pipefail; cpp -nostdinc -undef -x assembler-with-cpp $< | dtc | xxd -i -n dtb_data > $@
Expand All @@ -119,6 +179,15 @@ usb3399: rock.out pinebook-poc-ddr.bin demo_pinebook.bin
usb3588: rock.out genbook-ddr.bin demo_genbook.bin
./rock.out --v2 --ddr genbook-ddr.bin --os demo_genbook.bin

usb_roc3566: rock.out img/rk3566_ddr_1056MHz_v1.25.bin demo_roc3566.bin
./rock.out --v2 --ddr img/rk3566_ddr_1056MHz_v1.25.bin --os demo_roc3566.bin

usb_yy3568: rock.out img/rk3568_ddr_1560MHz_v1.25.bin demo_yy3568.bin
./rock.out --v2 --ddr img/rk3568_ddr_1560MHz_v1.25.bin --os demo_yy3568.bin

usb_rock3a: rock.out img/rk3568_ddr_1560MHz_v1.25.bin demo_rock3a.bin
./rock.out --v2 --ddr img/rk3568_ddr_1560MHz_v1.25.bin --os demo_rock3a.bin

dmesg:
sudo dmesg -w
uart:
Expand All @@ -131,7 +200,12 @@ bear:
make clean && bear -- make -j`nproc`
maskrom3588:
xrock maskrom img/rk3588_ddr_lp4_2112MHz_lp5_2400MHz_v1.16.bin img/rk3588_usbplug_v1.11.bin --rc4-off
maskrom3566:
$(XROCK) maskrom img/rk3566_ddr_1056MHz_v1.25.bin img/rk356x_usbplug_v1.17.bin --rc4-off
maskrom3568:
$(XROCK) maskrom img/rk3568_ddr_1560MHz_v1.25.bin img/rk356x_usbplug_v1.17.bin --rc4-off

.PHONY: usb clean dmesg uart uart2 bear maskrom3588
.PHONY: usb clean dmesg uart uart2 bear maskrom3588 maskrom3566 maskrom3568
.PHONY: usb_roc3566 usb_yy3568 usb_rock3a

-include config.mk
14 changes: 12 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Bare Metal Rockchip Bootloader

This is a very minimal and bare bones bootloader/firmware for Rockchip devices based on the RK3399 and RK3588.
This is a very minimal and bare bones bootloader/firmware for Rockchip devices based on the RK3399, RK356x and RK3588.
It brings up all hardware needed to get a framebuffer and a USB keyboard working as fast as possible.

This project also includes some tips and info on bare metal Rockchip bringup, hopefully shedding some light on these not so well documented SoCs.
Expand All @@ -9,13 +9,14 @@ This project also includes some tips and info on bare metal Rockchip bringup, ho

This project implements:
- RK3399 VOP/CRU/GPIO/timer driver
- RK356x PMU/CRU/GRF/GPIO/VOP2/DW-HDMI/USB2 platform support
- RK3588 VOP2/CRU/IOC/GPIO/PWM/PMU driver
- Analogix eDP driver
- OHCI driver (not finished)
- DDR image wrappers
- Some PSCI commands + additional UEFI-like commands
- libusb driver for USB-OTG maskrom mode
- SD image packer for rk3588/rk3399
- SD image packer for RK3399, RK356x and RK3588

External dependencies included:
- HDMI/eDP Combo PHY (HDPTX) driver from Linaro
Expand All @@ -24,6 +25,9 @@ External dependencies included:
Supported devices:
- Pinebook Pro
- Cool-Pi Genbook
- Firefly ROC-RK3566-PC
- Youyeetoo YY3568
- Radxa ROCK 3A
- (partial Orange Pi 5 support, no HDMI working yet)

# Compiling
Expand All @@ -38,6 +42,12 @@ There's a bunch of targets, but this is the gist:
- `demo.bin`: Payload demo binary, bootloader jumps to this in EL2
- `demo_pinebook.bin`: `demo.bin` appended to `pinebook.bin`
- `demo_pinebook.img`: Bootable SD card image for the Pinebook
- `demo_roc3566.img`: Bootable RKNS v2 demo image for ROC-RK3566-PC
- `demo_yy3568.img`: Bootable RKNS v2 demo image for YY3568
- `demo_rock3a.img`: Bootable RKNS v2 demo image for ROCK 3A

See [the RK356x bare-metal guide](docs/rk356x/index.md) for board wiring,
artifacts, direct MaskROM loading and hardware-validation status.

# Thanks
- Colt Judice
Expand Down
25 changes: 16 additions & 9 deletions demo/bmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,20 @@
static uintptr_t fb_addr = 0x0;
static uint32_t screen_width = 1920;
static uint32_t screen_height = 1080;
static uint32_t screen_stride = 1920 * 4;
static int last_x = 10;
static int last_y = 50;

static inline void font_draw_pixel(int x, int y, int col) {
x *= 2; y *= 2;
((uint64_t *)(&((uint32_t *)fb_addr)[y * screen_width + x]))[0] = (uint64_t)col << 32 | (uint64_t)col;
((uint64_t *)(&((uint32_t *)fb_addr)[(y + 1) * screen_width + x]))[0] = (uint64_t)col << 32 | (uint64_t)col;
if ((unsigned int)(x + 1) >= screen_width ||
(unsigned int)(y + 1) >= screen_height)
return;
uint32_t stride_pixels = screen_stride / 4;
((uint64_t *)(&((uint32_t *)fb_addr)[y * stride_pixels + x]))[0] =
(uint64_t)col << 32 | (uint64_t)col;
((uint64_t *)(&((uint32_t *)fb_addr)[(y + 1) * stride_pixels + x]))[0] =
(uint64_t)col << 32 | (uint64_t)col;
}

int font_print_char(int x, int y, char c) {
Expand Down Expand Up @@ -59,7 +66,7 @@ int font_print_string(int x, int y, const char *string) {
cx += length;

// wrapping
if (cx > screen_width - 20 && string[c] == ' ') {
if ((unsigned int)(cx * 2) > screen_width - 20 && string[c] == ' ') {
cx = x;
cy += 8;
}
Expand All @@ -80,11 +87,10 @@ void bmp_clear(void) {
last_x = 10;
last_y = 10;

uint64_t *framebuffer = (uint64_t *)fb_addr;

for (int i = 0; i < screen_height * screen_width / 2; i++) {
framebuffer[i] = (uint64_t)BACKGROUND_COLOR | ((uint64_t)BACKGROUND_COLOR << 32);
}
uint32_t *framebuffer = (uint32_t *)fb_addr;
for (uint32_t y = 0; y < screen_height; y++)
for (uint32_t x = 0; x < screen_width; x++)
framebuffer[y * (screen_stride / 4) + x] = BACKGROUND_COLOR;
}

int bmp_print_char(char c) {
Expand Down Expand Up @@ -112,10 +118,11 @@ int bmp_setup(void) {
struct FuScreenList *list = (struct FuScreenList *)fw_handler(FU_GET_SCREEN_LIST, 0, 0, 0);
// list is in secure memory, can't access

if (list->length != 0) {
if (list != (struct FuScreenList *)FU_ERROR && list->length != 0) {
fb_addr = list->screens[0].framebuffer_addr;
screen_width = list->screens[0].width;
screen_height = list->screens[0].height;
screen_stride = list->screens[0].stride;
return 0;
}
return 1;
Expand Down
3 changes: 3 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# Rockchip bare metal reference
This is a work-in-progress resource for bare-metal bringup for Rockchip devices.

Supported RK356x targets and their board-qualified build commands are
documented in the [RK356x bare-metal guide](rk356x/index.md).

Source code: https://github.com/petabyt/rk

For questions: daniel (AT) futo.org
Expand Down
14 changes: 14 additions & 0 deletions docs/intro.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,20 @@ For RK3588 devices:
xrock <ddr_img> <os_img> --rc4-off
./rock.out --v2 --ddr <ddr_img> --os <os_img>
```
For supported RK356x boards, use the explicit board target:
```
make usb_roc3566
make usb_yy3568
make usb_rock3a
```

These targets load the standalone demo into RAM. The corresponding
`demo_<board>.img` file is the standalone SD image; `<board>.img` contains
firmware only and requires an appended payload.

The RK356x USB-plug helpers `make maskrom3566` and `make maskrom3568` are
optional SoC-level loader-mode targets used after hardware has entered
MaskROM. They are separate from the direct board-qualified `usb_<board>` flow.

## How to program Rockchip hardware

Expand Down
25 changes: 25 additions & 0 deletions docs/rk356x/boards/roc3566.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Firefly ROC-RK3566-PC

| Property | Value |
| --- | --- |
| Build identifier | `roc3566` |
| SoC | RK3566 |
| Model | Firefly ROC-RK3566-PC |
| Compatible | `firefly,roc-rk3566-pc`, `rockchip,rk3566` |
| User LED | GPIO0_D3, active high |
| USB host power | GPIO0_C5, active high |
| Enabled USB2 host | OHCI0 |

Build or load the standalone demo with:

```sh
make demo_roc3566.img
make usb_roc3566
```

The normal artifacts are `roc3566.bin` and `roc3566.img`; both require an
appended compatible payload. `demo_roc3566.bin` and `demo_roc3566.img` include
the example payload.

Hardware validation of UART2, HDMI, USB keyboard, SD delivery and reset is
still required before this board is considered tested.
26 changes: 26 additions & 0 deletions docs/rk356x/boards/rock3a.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Radxa ROCK 3A

| Property | Value |
| --- | --- |
| Build identifier | `rock3a` |
| SoC | RK3568 |
| Model | Radxa ROCK 3A |
| Compatible | `radxa,rock3a`, `rockchip,rk3568` |
| User LED | GPIO0_B7, active high |
| USB host power | GPIO0_A6, active high |
| USB hub power | GPIO0_D5, active high |
| Enabled USB2 hosts | OHCI0 and OHCI1 |

Build or load the standalone demo with:

```sh
make demo_rock3a.img
make usb_rock3a
```

The normal artifacts are `rock3a.bin` and `rock3a.img`; both require an
appended compatible payload. `demo_rock3a.bin` and `demo_rock3a.img` include
the example payload.

Hardware validation of UART2, HDMI, USB host and hub power, SD delivery and
reset is still required before this board is considered tested.
29 changes: 29 additions & 0 deletions docs/rk356x/boards/yy3568.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Youyeetoo YY3568

| Property | Value |
| --- | --- |
| Build identifier | `yy3568` |
| SoC | RK3568 |
| Model | Youyeetoo YY3568 |
| Compatible | `youyeetoo,yy3568`, `rockchip,rk3568` |
| Work LED | GPIO3_A4, active high |
| Blue LED | GPIO2_B2, active high |
| USB host power | GPIO0_D6, active high |
| Enabled USB2 hosts | OHCI0 and OHCI1 |

The board descriptor drives only the common USB host rail. It deliberately
does not configure the separate OTG power rail.

Build or load the standalone demo with:

```sh
make demo_yy3568.img
make usb_yy3568
```

The normal artifacts are `yy3568.bin` and `yy3568.img`; both require an
appended compatible payload. `demo_yy3568.bin` and `demo_yy3568.img` include
the example payload.

Hardware validation of UART2, HDMI, both USB host companions, SD delivery and
reset is still required before this board is considered tested.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean by this?

Loading