Repository navigation
fh: pad mux for FH8852/FH8856/FH8858, V100, V200 and V210 - #254
Conversation
Fullhan detection never set chip_generation, so every ipchw_padmux_* call on a Fullhan board answered IPCHW_PADMUX_NO_CHIP. That left no way to put a pad such as GPIO9 back to GPIO. On a Tenda IC7-L (FH8852V200 + GC4653) the IR-cut coils are on GPIO9/GPIO10, which boot as SSI0_D2/D3, and the filter only moved after "mux,GPIO9,GPIO9,0" was written to /proc/driver/pinctrl by hand (OpenIPC/majestic#354). The layout is HiSilicon's: one register per pad at 0xF0000080 + 4*pad (board.c: fh_pinctrl_init(VA_PMU_REG_BASE + 0x80)), selector in bits 24..27 (mfs). It is the same on V100 and V200/V210. - tools/gen_fh_padmux.py turns the vendor kernel's iopad.h (PINCTRL_FUNC(name, pad, FUNCn, ...)) into src/hal/fh_padmux.h, from OpenIPC/linux fullhan-fh8852v200@ee1ef844 and fullhan-fh8852v100@4825e16e. It proves that the six V200/V210 chips share one table and the two V100 chips another, and it refuses duplicate selectors, a selector wider than four bits, a pad with two GPIOs, or a GPIO on two pads. - src/hal/fh_padmux.c is the backend. A pad is addressed by its GPIO number (pad 46 is GPIO9), never by pad id, and "5_2" is refused. A write sets the selector plus the input, output and Schmitt enables, as the kernel's fh_pinctrl_func_select() does. func_mask covers all four bits; get() decodes the selector alone. - fh_detect_cpu() sets a CHIP_FH* chip_generation. FH8856V201 and FH8858V201 are recognised and answer NO_TABLE. ## Boot-flash lines On V200, GPIO7..GPIO10 are also SSI0_TXD, SSI0_RXD, SSI0_D2 and SSI0_D3, and SSI0 is the SPI controller the board runs from. Neither the table nor the hardware says which lines a board's flash uses. On the Tenda, the input enable reads set on every pad and the output enable reads clear on every pad, even right after the kernel's own mux. - A new optional backend hook, in_use(), lets Fullhan answer true for any pad currently carrying an SSI0_* function. - ipchw_padmux_set() then returns the new IPCHW_PADMUX_IN_USE and writes nothing. Re-selecting the function the pad already carries is allowed. - ipchw_padmux_set_forced() and `gpio mux <pad> <function> --force` are for whoever knows the board, such as an owner who has named that pad for something else. ## Build and tests - CMake family "fh", dropped like xm when the Fullhan HAL is not selected. padmux_names regenerated. - reginfo_test: FH8852V200 and FH8852V100 are in the integrity sweep, which now uses the forced call because it cycles every pad through every function. test_fh() checks the GPIO9 values from that camera: pad 46, SSI0_D2 at selector 0, register 0xF0000138. Not yet run on a camera beyond that board's /proc/driver/pinctrl dump. The register reads and writes are host-tested against a fake register file only.
PR Summary by QodoAdd Fullhan pad mux support with boot-flash protection
AI Description
Diagram
High-Level Assessment
Files changed (16)
|
Code Review by Qodo
1.
|
…r, report a failed read as one - fh_parse_pad() bounds the number before narrowing it. On a 64-bit host "4294967297" became GPIO1 through an int and passed the lookup. GPIO numbers on these parts fit a byte, and strtol() overflow is refused. - `gpio mux <pad> <n>` never matched on Fullhan. The CLI compared n with `func`, which here is the whole value a write puts in the register (selector in bits 24..27 plus the enables), so "9 1" answered "has no function 1". A new optional backend hook, func_number(), gives the number a person types: on Fullhan the selector, as /proc/driver/pinctrl prints it in `sel`. The CLI matches through padmux_func_number(); every other backend still compares `func`, so nothing changes there. - ipchw_padmux_set() reads the pad before applying the flash check and returns any read error as it is. A register that could not be read used to come back as IPCHW_PADMUX_IN_USE, with advice to --force. - reginfo_test: the oversized number, selector numbering on GPIO9, and a failed read under IO_FAILS.
|
Review round addressed in c0ab9ff:
|
Fullhan detection never set chip_generation, so every ipchw_padmux_*
call on a Fullhan board answered IPCHW_PADMUX_NO_CHIP. That left no way
to put a pad such as GPIO9 back to GPIO. On a Tenda IC7-L (FH8852V200 +
GC4653) the IR-cut coils are on GPIO9/GPIO10, which boot as SSI0_D2/D3,
and the filter only moved after "mux,GPIO9,GPIO9,0" was written to
/proc/driver/pinctrl by hand (OpenIPC/majestic#354).
The layout is HiSilicon's: one register per pad at 0xF0000080 + 4*pad
(board.c: fh_pinctrl_init(VA_PMU_REG_BASE + 0x80)), selector in bits
24..27 (mfs). It is the same on V100 and V200/V210.
(PINCTRL_FUNC(name, pad, FUNCn, ...)) into src/hal/fh_padmux.h, from
OpenIPC/linux fullhan-fh8852v200@ee1ef844 and fullhan-fh8852v100@4825e16e.
It proves that the six V200/V210 chips share one table and the two V100
chips another, and it refuses duplicate selectors, a selector wider
than four bits, a pad with two GPIOs, or a GPIO on two pads.
number (pad 46 is GPIO9), never by pad id, and "5_2" is refused. A
write sets the selector plus the input, output and Schmitt enables, as
the kernel's fh_pinctrl_func_select() does. func_mask covers all four
bits; get() decodes the selector alone.
FH8858V201 are recognised and answer NO_TABLE.
Boot-flash lines
On V200, GPIO7..GPIO10 are also SSI0_TXD, SSI0_RXD, SSI0_D2 and SSI0_D3,
and SSI0 is the SPI controller the board runs from. Neither the table
nor the hardware says which lines a board's flash uses. On the Tenda,
the input enable reads set on every pad and the output enable reads
clear on every pad, even right after the kernel's own mux.
any pad currently carrying an SSI0_* function.
nothing. Re-selecting the function the pad already carries is allowed.
gpio mux <pad> <function> --forcearefor whoever knows the board, such as an owner who has named that pad
for something else.
Build and tests
selected. padmux_names regenerated.
which now uses the forced call because it cycles every pad through
every function. test_fh() checks the GPIO9 values from that camera:
pad 46, SSI0_D2 at selector 0, register 0xF0000138.
Not yet run on a camera beyond that board's /proc/driver/pinctrl dump.
The register reads and writes are host-tested against a fake register
file only.
Verified on hardware (Tenda IC7-L, FH8852V200)
gpio mux 9/10/7on a fresh boot read[SSI0_D2],[SSI0_D3],[SSI0_TXD], matching the vendor table and that board's/proc/driver/pinctrl.gpio mux 9 GPIOwas refused as a flash line (first test build); the board's owner did not force it.devmemof GPIO7, GPIO9 and GPIO10's registers read0x00001140on all three, which is why the refusal covers every SSI0 pad rather than trying to guess.