1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright 2020 NXP 4 */ 5 6#include <common.h> 7#include <miiphy.h> 8#include <netdev.h> 9#include <asm/arch/imx8ulp-pins.h> 10#include <asm/arch/clock.h> 11#include <asm/arch/pcc.h> 12#include <asm/arch/sys_proto.h> 13#include <miiphy.h> 14#include <netdev.h> 15#include <asm/gpio.h> 16 17DECLARE_GLOBAL_DATA_PTR; 18 19#if IS_ENABLED(CONFIG_FEC_MXC) 20#define ENET_CLK_PAD_CTRL (PAD_CTL_PUS_UP | PAD_CTL_DSE | PAD_CTL_IBE_ENABLE) 21static iomux_cfg_t const enet_clk_pads[] = { 22 IMX8ULP_PAD_PTE19__ENET0_REFCLK | MUX_PAD_CTRL(ENET_CLK_PAD_CTRL), 23 IMX8ULP_PAD_PTF10__ENET0_1588_CLKIN | MUX_PAD_CTRL(ENET_CLK_PAD_CTRL), 24}; 25 26static int setup_fec(void) 27{ 28 /* 29 * Since ref clock and timestamp clock are from external, 30 * set the iomux prior the clock enablement 31 */ 32 imx8ulp_iomux_setup_multiple_pads(enet_clk_pads, ARRAY_SIZE(enet_clk_pads)); 33 34 /* Select enet time stamp clock: 001 - External Timestamp Clock */ 35 cgc1_enet_stamp_sel(1); 36 37 /* enable FEC PCC */ 38 pcc_clock_enable(4, ENET_PCC4_SLOT, true); 39 pcc_reset_peripheral(4, ENET_PCC4_SLOT, false); 40 41 return 0; 42} 43 44int board_phy_config(struct phy_device *phydev) 45{ 46 if (phydev->drv->config) 47 phydev->drv->config(phydev); 48 return 0; 49} 50#endif 51 52#define I2C_PAD_CTRL (PAD_CTL_ODE) 53static const iomux_cfg_t lpi2c0_pads[] = { 54 IMX8ULP_PAD_PTA8__LPI2C0_SCL | MUX_PAD_CTRL(I2C_PAD_CTRL), 55 IMX8ULP_PAD_PTA9__LPI2C0_SDA | MUX_PAD_CTRL(I2C_PAD_CTRL), 56}; 57 58#define TPM_PAD_CTRL (PAD_CTL_DSE) 59static const iomux_cfg_t tpm0_pads[] = { 60 IMX8ULP_PAD_PTA3__TPM0_CH2 | MUX_PAD_CTRL(TPM_PAD_CTRL), 61}; 62 63void mipi_dsi_mux_panel(void) 64{ 65 int ret; 66 struct gpio_desc desc; 67 68 /* It is temp solution to directly access i2c, need change to rpmsg later */ 69 70 /* enable lpi2c0 clock and iomux */ 71 imx8ulp_iomux_setup_multiple_pads(lpi2c0_pads, ARRAY_SIZE(lpi2c0_pads)); 72 writel(0xD2000000, 0x28091060); 73 74 ret = dm_gpio_lookup_name("gpio@20_9", &desc); 75 if (ret) { 76 printf("%s lookup gpio@20_9 failed ret = %d\n", __func__, ret); 77 return; 78 } 79 80 ret = dm_gpio_request(&desc, "dsi_mux"); 81 if (ret) { 82 printf("%s request dsi_mux failed ret = %d\n", __func__, ret); 83 return; 84 } 85 86 dm_gpio_set_dir_flags(&desc, GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE); 87} 88 89void mipi_dsi_panel_backlight(void) 90{ 91 /* It is temp solution to directly access pwm, need change to rpmsg later */ 92 imx8ulp_iomux_setup_multiple_pads(tpm0_pads, ARRAY_SIZE(tpm0_pads)); 93 writel(0xD4000001, 0x28091054); 94 95 /* Use center-aligned PWM mode, CPWMS=1, MSnB:MSnA = 10, ELSnB:ELSnA = 00 */ 96 writel(1000, 0x28095018); 97 writel(1000, 0x28095034); /* MOD = CV, full duty */ 98 writel(0x28, 0x28095010); 99 writel(0x20, 0x28095030); 100} 101 102int board_init(void) 103{ 104 105 if (IS_ENABLED(CONFIG_FEC_MXC)) 106 setup_fec(); 107 108 /* When sync with M33 is failed, use local driver to set for video */ 109 if (!is_m33_handshake_necessary() && IS_ENABLED(CONFIG_VIDEO)) { 110 mipi_dsi_mux_panel(); 111 mipi_dsi_panel_backlight(); 112 } 113 114 return 0; 115} 116 117int board_early_init_f(void) 118{ 119 return 0; 120} 121 122int board_late_init(void) 123{ 124 ulong addr; 125 126#if CONFIG_IS_ENABLED(ENV_IS_IN_MMC) 127 board_late_mmc_env_init(); 128#endif 129 130 /* clear fdtaddr to avoid obsolete data */ 131 addr = env_get_hex("fdt_addr_r", 0); 132 if (addr) 133 memset((void *)addr, 0, 0x400); 134 135 return 0; 136} 137