[PATCH] board: purism: Add support for the Librem5 devkit
Fabio Estevam
festevam at gmail.com
Tue Jun 9 14:53:08 CEST 2026
Hi Guido,
On Mon, May 25, 2026 at 12:57 PM Guido Günther <agx at sigxcpu.org> wrote:
> +#define UART_PAD_CTRL (PAD_CTL_DSE6 | PAD_CTL_FSEL1)
> +
> +#define WDOG_PAD_CTRL (PAD_CTL_DSE6 | PAD_CTL_HYS | PAD_CTL_PUE)
> +
> +#define UART1_TX IMX_GPIO_NR(5, 23)
> +#define UART1_RX IMX_GPIO_NR(5, 22)
> +
> +static const iomux_v3_cfg_t wdog_pads[] = {
> + IMX8MQ_PAD_GPIO1_IO02__WDOG1_WDOG_B | MUX_PAD_CTRL(WDOG_PAD_CTRL),
> +};
> +
> +static const iomux_v3_cfg_t uart_pads[] = {
> + IMX8MQ_PAD_UART1_RXD__UART1_RX | MUX_PAD_CTRL(UART_PAD_CTRL),
> + IMX8MQ_PAD_UART1_TXD__UART1_TX | MUX_PAD_CTRL(UART_PAD_CTRL),
> +};
> +
> +int board_early_init_f(void)
> +{
> + struct wdog_regs *wdog = (struct wdog_regs *)WDOG1_BASE_ADDR;
> +
> + imx_iomux_v3_setup_multiple_pads(wdog_pads, ARRAY_SIZE(wdog_pads));
> + set_wdog_reset(wdog);
> +
> + imx_iomux_v3_setup_multiple_pads(uart_pads, ARRAY_SIZE(uart_pads));
> +
> + return 0;
> +}
> +
> +#if IS_ENABLED(CONFIG_FEC_MXC)
> +#define FEC_RST_PAD IMX_GPIO_NR(1, 9)
> +static const iomux_v3_cfg_t fec1_rst_pads[] = {
> + IMX8MQ_PAD_GPIO1_IO09__GPIO1_IO9 | MUX_PAD_CTRL(NO_PAD_CTRL),
> + IMX8MQ_PAD_GPIO1_IO15__CCM_CLKO2 | MUX_PAD_CTRL(0x1F),
> +};
> +
> +static void setup_iomux_fec(void)
> +{
> + imx_iomux_v3_setup_multiple_pads(fec1_rst_pads,
> + ARRAY_SIZE(fec1_rst_pads));
> +
> + gpio_request(FEC_RST_PAD, "fec1_rst");
> + gpio_direction_output(FEC_RST_PAD, 0);
> + udelay(500);
> + gpio_direction_output(FEC_RST_PAD, 1);
> +}
> +
> +static int setup_fec(void)
> +{
> + setup_iomux_fec();
> +
> + /* Use 125M anatop REF_CLK1 for ENET1, not from external */
> + clrsetbits_le32(IOMUXC_GPR_BASE_ADDR + 0x04, BIT(13) | BIT(17), 0);
> + return set_clk_enet(ENET_125MHZ);
> +}
> +
> +int board_phy_config(struct phy_device *phydev)
> +{
> + /* enable rgmii rxc skew and phy mode select to RGMII copper */
> + phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x1f);
> + phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x8);
> +
> + phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x05);
> + phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x100);
> +
> + if (phydev->drv->config)
> + phydev->drv->config(phydev);
> + return 0;
> +}
> +#endif
The UART, watchdog, and Ethernet PHY C code above could be removed,
since we're using DM, right?
> +int board_init(void)
> +{
> + if (IS_ENABLED(CONFIG_USB_DWC3) || IS_ENABLED(CONFIG_USB_XHCI_DWC3))
> + init_usb_clk();
> +
> + if (IS_ENABLED(CONFIG_FEC_MXC))
> + setup_fec();
> +
> + return 0;
Can board_init() be removed?
> --- /dev/null
> +++ b/board/purism/librem5-devkit/librem5-devkit.env
> @@ -0,0 +1,20 @@
> +/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
> +
> +boot_fdt=try
boot_fdt was used long ago, when we supported both DT and non-DT cases.
boot_fdt is no longer needed, as we always boot DT, so it can be removed.
> +boot_targets=mmc0 dhcp
> +bootm_size=0x10000000
> +console=ttymxc0,115200
> +fdt_addr_r=0x43000000
> +fdtfile=DEFAULT_FDT_FILE
> +initrd_addr=0x43800000
> +image=Image
> +kernel_addr_r=CONFIG_SYS_LOAD_ADDR
> +loadaddr=CONFIG_SYS_LOAD_ADDR
> +mmcautodetect=yes
> +mmcdev=CONFIG_ENV_MMC_DEVICE_INDEX
> +mmcpart=1
> +mmcroot=/dev/mmcblk0p1
> +scriptaddr=CONFIG_SYS_LOAD_ADDR
> +mmcargs=setenv bootargs console=${console} root=${mmcroot} rootwait rw
> +loadimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}
> +loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr_r} ${fdtfile}
Use the generic load command instead of fatload.
> diff --git a/doc/board/purism/index.rst b/doc/board/purism/index.rst
> index a9cdc312d46..0225aa7f3aa 100644
> --- a/doc/board/purism/index.rst
> +++ b/doc/board/purism/index.rst
> +Get and Build the ARM Trusted firmware
> +--------------------------------------
> +
> +Note: srctree is U-Boot source directory
> +Get ATF from: https://source.puri.sm/Librem5/arm-trusted-firmware
Can't the mainline ATF be used instead?
More information about the U-Boot
mailing list