diff --git a/CLAUDE.md b/CLAUDE.md index e3a56910f215..9dd5f17b6eb6 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -151,8 +151,8 @@ The memory map is the same in all three generations: system control at instead). - It does what the vendor U-Boots do, traced under qemu from the gwell camera's EV200 U-Boot: SPI0 soft reset (bit 5) and its pads (`0x74` - bit 25; `0xDC |= 0x3003` on the EV200, `0x3e03` on the EV300, the - ROM's on the EV330) at each probe, fast read (`0x0B` + a dummy byte), + bit 25; `0xDC` 13:0 = `0x2003` on the EV200 (the DT's), `|= 0x3e03` + on the EV300, the ROM's on the EV330) at each probe, fast read (`0x0B` + a dummy byte), at most 8 KiB per CNT transfer (`MAX_XFER_LEN`), about 17 MHz. - Fixed after a real AK3918EV200 (XM25QH64A) read back a kernel written with an earlier build with a bad data CRC. qemu never showed it: its @@ -178,6 +178,13 @@ The memory map is the same in all three generations: system control at not touch SPI0's pads. Card detect is a board GPIO (5, 24, 41, 57 in the vendor sources) and is not used: with no card the first command times out (one "did not respond" line, no delay). + - EV200: the SD driver also muxes pad 34 to GPIO and drives GPIO 34 low + (`wifi_en` in the EV200 reference board's DT, on the pad that is + otherwise DAT1), and SPI0's pads 35/36 are function 2 (`0xDC` bits + 13:12 = `10`, as the DT and Linux set them). On a gwell AK3918EV200 the + card answers only with both: the ROM leaves pad 34's field at `11`, and + the gwell vendor U-Boot's SPI value `0x3003` puts `11` on pads 35/36. + Found by setting the registers Linux leaves (`devmem`) one by one. - `common/openipc.c` recovers from it at every boot: `script.txt`, then `uImage..img` and `rootfs.squashfs..img`. These are uImages flashed where their load address says, without the header diff --git a/drivers/mmc/ak_mmc.c b/drivers/mmc/ak_mmc.c index 36c7487288fe..4a114d72c757 100644 --- a/drivers/mmc/ak_mmc.c +++ b/drivers/mmc/ak_mmc.c @@ -74,12 +74,24 @@ /* Pads 31-33 as MCI0 */ #ifdef CONFIG_AK39_EV200 -#define MCI0_SHAREPIN3_CLR 0x3c0 /* pad 33 has a 2-bit field */ +/* Pad 33 has a 2-bit field; pad 34's (11:10) goes to GPIO for wifi_en below */ +#define MCI0_SHAREPIN3_CLR 0xfc0 #else #define MCI0_SHAREPIN3_CLR 0x1c0 #endif #define MCI0_SHAREPIN3_SET 0x1c0 +#ifdef CONFIG_AK39_EV200 +/* + * GPIO 34: wifi_en in the EV200 reference board's device tree, on the pad + * that is otherwise SD DAT1. Linux muxes the pad to GPIO and drives it low; + * a gwell AK3918EV200 camera comes out of its boot ROM with the pad's field + * at 11, and until the pad is a GPIO driven low its card does not answer at + * all (all-zero responses). + */ +#define MCI0_WIFI_EN_GPIO 34 +#endif + static uint mci_clock = MCI_F_MIN; static void ak_mci_set_clock(uint want) @@ -103,6 +115,10 @@ static void ak_mci_host_init(void) { clrsetbits_le32(AK_SYS_SHAREPIN3, MCI0_SHAREPIN3_CLR, MCI0_SHAREPIN3_SET); +#ifdef MCI0_WIFI_EN_GPIO + clrbits_le32(AK_GPIO_OUT(MCI0_WIFI_EN_GPIO), BIT(MCI0_WIFI_EN_GPIO % 32)); + setbits_le32(AK_GPIO_DIR(MCI0_WIFI_EN_GPIO), BIT(MCI0_WIFI_EN_GPIO % 32)); +#endif clrbits_le32(AK_SYS_CLK_GATE, AK_CLK_MCI0); setbits_le32(AK_SYS_SOFT_RST, AK_RST_MCI0); clrbits_le32(AK_SYS_SOFT_RST, AK_RST_MCI0); diff --git a/drivers/mtd/spi/ak_sflash.c b/drivers/mtd/spi/ak_sflash.c index a1b2d6e553dd..42cfed4e080e 100644 --- a/drivers/mtd/spi/ak_sflash.c +++ b/drivers/mtd/spi/ak_sflash.c @@ -333,15 +333,21 @@ static int ak_sf_erase(struct mtd_info *mtd, struct erase_info *instr) } /* - * SPI0's pads, as the vendor U-Boots set them before each use; the boot ROM - * leaves enough for reading the boot image. The EV330's are left as the - * ROM has them. + * SPI0's pads; the boot ROM leaves enough for reading the boot image, the + * EV330's are left as it has them. + * - EV200: pads 25/26 function 1, 35/36 function 2 (field 13:12 = 10), as + * the EV200 device tree's spiflash_pins and Linux set them. The gwell + * vendor U-Boot's 0x3003 (11 there) keeps that camera's SD card from + * answering, with GPIO 34 low or not. + * - EV300: the SDK U-Boot's value. */ #if defined(CONFIG_AK39_EV200) #define SPI0_SHAREPIN0 BIT(25) -#define SPI0_SHAREPIN3 0x3003 +#define SPI0_SHAREPIN3_CLR 0x3003 +#define SPI0_SHAREPIN3 0x2003 #elif defined(CONFIG_AK39_EV300) #define SPI0_SHAREPIN0 BIT(25) +#define SPI0_SHAREPIN3_CLR 0 #define SPI0_SHAREPIN3 (0x3 | 0x1f << 9) #endif @@ -352,7 +358,7 @@ static void spi_hw_init(void) clrbits_le32(AK_SYS_SOFT_RST, AK_RST_SPI0); #ifdef SPI0_SHAREPIN0 setbits_le32(AK_SYS_SHAREPIN0, SPI0_SHAREPIN0); - setbits_le32(AK_SYS_SHAREPIN3, SPI0_SHAREPIN3); + clrsetbits_le32(AK_SYS_SHAREPIN3, SPI0_SHAREPIN3_CLR, SPI0_SHAREPIN3); #endif }