Repository navigation
Goke GK7101/GK7102 on v2022.10, with the OpenIPC boot layer (NOR) - #22
Conversation
NETDEVICES selected DM_ETH, so with CONFIG_DM off a board with a network driver failed to link on uclass and dev_get_priv references. Select it only when DM is on, as openipc-hisilicon and openipc-xm do, so the legacy designware_initialize() path still builds.
The non-DM designware_initialize() always registered an MDIO bus on the MAC's own MDIO lines, named after the device, and connected the PHY there. A PHY that is not on those lines could not be reached. Register the MAC's bus only if no bus of that name exists yet, so a board can supply its own first. Boards that do not are unchanged. The Goke GK710x needs it: its internal PHY's MII registers are memory mapped, not on MDIO.
The firmware scan, recovery and boot-limit failsafe of the openipc-hisilicon branch, for the Goke GK7101/GK7102: common/openipc.c and include/openipc.h as on openipc-xm (7208b96, itself from openipc-hisilicon 655d32f), unchanged. CONFIG_OPENIPC builds it; PRODUCT_SOC and PRODUCT_SOCMODEL name the target in the environment.
Goke's own ARM1176 camera SoCs, not the HiSilicon-derived GK7205/GK7605: GK7102 is the GK7101 die with 64 MiB of DDR2 in the package, GK7101 has 128 MiB outside. Written from the vendor SDK GK710X_LinuxSDK_v2.0.0 (U-Boot 2012.10, Linux 3.4.43); none of its drivers come along. - The boot ROM runs the DDR set-up listed in the flash header and copies U-Boot to its link address, 0xC0800000, so there is no SPL and lowlevel_init is empty. dram_init() tells 64 from 128 MiB by the DDR controller word the header programmed. - The vendor code reaches every register through a HAL blob that remaps blocks, registers and bits. Here the silicon is programmed directly, with the stores the HAL itself makes, recovered by executing it (qemu-hisilicon's gk710x-halmap.py): CPU PLL and UART divider, timer 1 (Ambarella, 69 MHz, through lib/time.c), watchdog reset, pin functions and pad control. - Console: mainline NS16550 at 0x70005000, 32-bit registers, 24 MHz. - Ethernet: mainline DesignWare at 0x6000E000 with the SoC's 10/100 PHY, whose MII registers are memory mapped and are registered as its MDIO bus. The vendor's PHY clock (audio PLL out on a pin), analog trim and MAC/PHY mux are done first. - The vendor kernel, OpenIPC's included, needs more than ATAGs, and board_prep_linux() leaves it what the vendor U-Boot did: the HAL blob at 0xC0012000 (hal_data.h, version 20160913; the kernel calls it first and refuses one older than 20160324), the U2K words at 0xC0000000 (total DDR, mem=, bitstream buffer, PHY type) from which it places its BSB, DSP and USR memory, and the board's GPIO map in the top 64 KiB, from which it configures every pin. U-Boot stays below that 64 KiB. - The SDK's board GPIO headers come down to two layouts, v2 (rb-sc1035 v2.1, sc1045, imx225, ov9750, jxh42 v2.0, gc1024, GK7101 rb-ov2710 v2.2) and v1 (rb-ov9712, ar0130, jxh42 v1.0, GK7101 imx222). Both are built in, generated from the headers; gpiomap=v1 selects the second. U-Boot applies the selected map at misc_init_r() as the vendor U-Boot did. - include/configs/openipc-common.h: the openipc-xm environment, NOR only, with the GK parameters: mem= 36M/50M and bsbsize 2M/4M (GK7102/GK7101, the vendor defaults), baseaddr 0xC1000000, console ttySGK0 and the vendor kernel's MTD name gk_flash. SD is left out: the vendor U-Boot had none and the controller's base clock is not known. Under qemu-hisilicon's gk7102 and gk7101 machines (with the flash driver that follows): 64/128 MiB, console, timer, reset, ping and TFTP; the OpenIPC gk7102 kernel takes the HAL, the U2K layout and the GPIO map and boots to login.
A register-driven SPI master with no memory window: COMMAND describes one transaction (opcode, address and dummy bytes, direction, 1-4 data bytes per DATA access) and DATA carries the address and the data. Like the vendor U-Boot this driver provides spi_flash_probe() itself and fills mtd->_read/_write/_erase, so mainline's non-DM spi_flash_*() wrappers, the sf command and the environment in SPI flash work without the SPI and spi-nor layers. CMD_SF, ENV_IS_IN_SPI_FLASH and the SF_DEFAULT_* options accept GK_SFLASH for that. The controller packs bytes MSB first, and the boot ROM and the vendor kernel move whole little-endian words through it. The driver does the same, for unaligned offsets and lengths too (reads through the covering words, programs padded with 0xff), so what it writes the ROM and the kernel read back unchanged. Single lane, parts up to 16 MiB; block protection left by a vendor loader is cleared. Under qemu-hisilicon's gk7102 machine: a 0x12345-byte write at 0x700003 reads back identical, with 0xff around it; saveenv survives a reset and fw_printenv reads it from Linux; the kernel and rootfs written by TFTP recovery boot.
build.sh as on openipc-xm: each SoC's .config is openipc/openipc_config followed by openipc/<soc>_config, then olddefconfig; `bash build.sh [soc...]` writes output/u-boot-<soc>-nor.bin. The image is u-boot.bin behind the boot ROM's header (openipc/gk710x-image.py): magic and version, the U-Boot length, load and entry address, the DDR test words, then openipc/<soc>.rvs -- the eFuse, DDR PHY and DDR controller set-up, taken from the SDK's prebuilt U-Boots and the same on cameras in the field; GK7101 and GK7102 differ only in the DDR size word. The image is in CPU byte order, as `sf write` stores it. The base fragment carries the OpenIPC options: prompt "OpenIPC # ", autoboot stopped by Ctrl-C only, silent=1, hush, the environment at 0x40000 in SPI NOR, TFTP for recovery, a random MAC when none is set, and the DRAM boot counter at DDR + 0x1f20000. BOARD_SIZE_LIMIT keeps header and image within the 256 KiB boot partition; with no Thumb-2 on ARM1176 the image is about 237 KiB. Under qemu-hisilicon, from an 8 MiB flash image: gk7102 and gk7101 boot the OpenIPC gk7102 lite kernel and rootfs to login; an empty flash recovers by TFTP (ur, uk) and boots; two resets without a healthy boot take altbootcmd into failsafe.
.github/workflows/ci.yml is the thin caller openipc-xm has: pushes and pull requests on this branch run build-gk710x.yml from the openipc branch with this revision. CLAUDE.md is guidance for Claude Code sessions on this branch: how it differs from mainline v2022.10, the HAL and how register values were recovered, the boot header and flash byte order, what the kernel is handed, the GPIO maps, and what qemu-hisilicon does and does not verify.
PR Summary by QodoAdd OpenIPC NOR boot support for Goke GK7101 and GK7102
AI Description
Diagram
High-Level Assessment
Files changed (35)
|
Code Review by Qodo
1. Linux cannot find the flash device
|
| flash->read_opcode = CMD_READ; | ||
| flash->program_opcode = CMD_PP; | ||
|
|
||
| mtd->name = "gk-sflash"; |
There was a problem hiding this comment.
1. Linux cannot find the flash device 📘 Rule violation ≡ Correctness
spi_flash_probe() names the registered MTD device gk-sflash instead of the required gk_flash. The generated mtdparts string and vendor kernel expect gk_flash, so partition lookup can fail when Linux matches the controller name.
Agent Prompt
## Issue description
The SPI NOR driver registers its MTD device as `gk-sflash`, while the boot environment and vendor kernel expect the controller name `gk_flash`.
## Fix Focus Areas
- drivers/mtd/spi/gk_sflash.c[249-263]
## Recommended Fix
Set the registered MTD device name to `gk_flash` so it matches the `SFC` identifier used in `mtdids`, `mtdparts`, and the vendor kernel.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| sprintf(mtds, "%dk(u-boot),%dk(env),%lldk(kernel),%lldk(rootfs),%lldk@0x%lx(firmware),-(rootfs_data)", | ||
| CONFIG_ENV_OFFSET / 1024, CONFIG_ENV_SIZE / 1024, kernel_size / 1024, rootfs_size / 1024, | ||
| (kernel_size + rootfs_size) / 1024, kernel_off); |
There was a problem hiding this comment.
2. Linux reads the wrong rootfs after a gap 🐞 Bug ≡ Correctness
firmware_scan() records the discovered kernel offset but generates sequential kernel and rootfs partitions without placing the kernel partition at that offset. When a valid kernel starts later than 0x50000, Linux receives partition boundaries that disagree with the scanned kernaddr and rootaddr, so its rootfs partition starts before the actual rootfs.
Agent Prompt
## Issue description
The generated MTD partitions assume the kernel starts immediately after the environment, even though firmware scanning accepts a later kernel offset. This shifts Linux's rootfs partition away from the discovered rootfs.
## Fix Focus Areas
- common/openipc.c[573-608]
## Recommended Fix
Generate partitions using the scanned physical offsets, including an explicit kernel offset or a correctly sized preceding gap. Ensure the resulting rootfs partition begins at `rootfs_off` and remains consistent with the boot variables.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
misc_init_r() applied the selected GPIO map, as the vendor U-Boot did. Until gpiomap is set that map is the v2 default, and v2 makes GPIO 30/31 plain inputs and routes UART0 RX from pin 25. On a v1-layout board (rb-ov9712, ar0130, jxh42 v1.0, GK7101 imx222), where UART0 is on GPIO 30/31, the console then died before autoboot, so nobody could set gpiomap=v1. U-Boot only needs GPIO 48, the internal PHY's reference clock, which is the same in both layouts. Set that and leave the other pins as the boot ROM left them. The kernel still gets the full selected map. Under qemu-hisilicon gk7102: ping and TFTP still work, and the kernel still takes the v2 map, or the v1 one with gpiomap=v1 (PHY reset on pin 41). The machine does not model pin muxing, so the console fix itself is unverified. Reported by Qodo on #22.
sf_wait_ready() polled the status register until WIP cleared, with no limit. A flash that stayed busy, or a missing part reading 0xff, hung saveenv, the first-boot environment save and sf erase/write for good. Give up after 3 s, which is longer than any erase or program of the parts on these boards, and service the watchdog while waiting. Return -ETIMEDOUT through sf_program() and sf_erase_sector() to the MTD write/erase callbacks. Those now report how much was written, and the failing erase address. Under qemu-hisilicon gk7102: unaligned sf write/read and cmp, saveenv and reset, and TFTP recovery behave as before. Reported by Qodo on #22.
The U2K memory words were parsed as decimal MiB, ignoring any suffix.
The same osmem string goes to the kernel as mem=, which takes bytes, hex
and K/M/G. So mem=0x2400000 left a 0 in the word, and 36864K became
36864 MiB, and the kernel placed its BSB and DSP memory from a size that
disagreed with its own.
Parse both with ustrtoul(), as bytes. The defaults ("36M", "2M") give the
same words as before: under qemu-hisilicon the gk7102 and gk7101 kernels
still place BSB/DSP at 0xc2600000/0xc2800000 and 0xc3400000/0xc3800000.
Reported by Qodo on #22.
U-Boot for Goke's own ARM1176 camera SoCs, GK7101 and GK7102. These are not the HiSilicon-derived GK7205/GK7605. It's built on mainline v2022.10 with the OpenIPC boot layer, the same way as
openipc-hisiliconandopenipc-xm. I wrote it from the vendor SDKGK710X_LinuxSDK_v2.0.0(U-Boot 2012.10, Linux 3.4.43). None of the vendor drivers are used.Commits
net:NETDEVICES selects DM_ETH only with DM, as on openipc-xm.net: designware:the non-DM path uses an MDIO bus the board has already registered. The GK710x internal PHY is memory mapped, not on MDIO.openipc:common/openipc.c/include/openipc.h, unchanged from openipc-xm.arm: gk710x:the SoC, board and config headers. Details below.gk_sflash:a non-DM driver for the SPI-NOR controller. It providesspi_flash_probe(), as xmsfc does.openipc:build.sh, Kconfig fragments, and the boot ROM header (openipc/gk710x-image.py+<soc>.rvs, the DDR table from the SDK's prebuilt U-Boots).ci, docs:a thinci.ymlcaller andCLAUDE.md.What's specific to these chips
gpiomap=v1covers rb-ov9712, ar0130, jxh42 v1.0 and GK7101 imx222..binis in CPU order, which is whatsf writeexpects.Tested on qemu-hisilicon
gk7101/gk7102only, not yet on a camerasfwrite/read compares equal.saveenvsurvives a reset, andfw_printenvreads it from Linux.Not covered
Merge this before #21. This branch's
ci.ymlcallsbuild-gk710x.yml@openipc, which only exists once #21 lands, so this PR has no CI run of its own. The build and smoke test run on #21 once this is merged.Since opening, I've pushed fixes for three Qodo findings: U-Boot sets only the PHY clock pin, so a v1-layout board keeps its console; the flash status wait times out;
osmem/bsbsizeare parsed likemem=.