diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/clk/imx/clk-imx8mm.c | 86 | ||||
-rw-r--r-- | drivers/crypto/fsl/fsl_rsa.c | 10 | ||||
-rw-r--r-- | drivers/ddr/imx/imx8m/ddr_init.c | 8 | ||||
-rw-r--r-- | drivers/gpio/Kconfig | 6 | ||||
-rw-r--r-- | drivers/gpio/Makefile | 1 | ||||
-rw-r--r-- | drivers/gpio/adp5585_gpio.c | 238 | ||||
-rw-r--r-- | drivers/mmc/Kconfig | 4 | ||||
-rw-r--r-- | drivers/mmc/dw_mmc.c | 3 | ||||
-rw-r--r-- | drivers/mmc/f_sdh30.c | 66 | ||||
-rw-r--r-- | drivers/mmc/fsl_esdhc_imx.c | 4 | ||||
-rw-r--r-- | drivers/mmc/ftsdc010_mci.c | 2 | ||||
-rw-r--r-- | drivers/mmc/mmc.c | 6 | ||||
-rw-r--r-- | drivers/mmc/sdhci.c | 8 | ||||
-rw-r--r-- | drivers/mmc/stm32_sdmmc2.c | 20 | ||||
-rw-r--r-- | drivers/mtd/spi/Kconfig | 10 | ||||
-rw-r--r-- | drivers/mtd/spi/spi-nor-core.c | 92 | ||||
-rw-r--r-- | drivers/mtd/spi/spi-nor-ids.c | 5 | ||||
-rw-r--r-- | drivers/net/ftgmac100.c | 14 | ||||
-rw-r--r-- | drivers/net/phy/ncsi.c | 1 | ||||
-rw-r--r-- | drivers/net/phy/phy.c | 9 |
20 files changed, 494 insertions, 99 deletions
diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c index 542aa31f7ac..b5c253e4966 100644 --- a/drivers/clk/imx/clk-imx8mm.c +++ b/drivers/clk/imx/clk-imx8mm.c @@ -28,10 +28,10 @@ static const char *imx8mm_a53_sels[] = {"clock-osc-24m", "arm_pll_out", "sys_pll static const char *imx8mm_ahb_sels[] = {"clock-osc-24m", "sys_pll1_133m", "sys_pll1_800m", "sys_pll1_400m", "sys_pll2_125m", "sys_pll3_out", "audio_pll1_out", "video_pll1_out", }; +#ifndef CONFIG_SPL_BUILD static const char *imx8mm_enet_axi_sels[] = {"clock-osc-24m", "sys_pll1_266m", "sys_pll1_800m", "sys_pll2_250m", "sys_pll2_200m", "audio_pll1_out", "video_pll1_out", "sys_pll3_out", }; -#ifndef CONFIG_SPL_BUILD static const char *imx8mm_enet_ref_sels[] = {"clock-osc-24m", "sys_pll2_125m", "sys_pll2_50m", "sys_pll2_100m", "sys_pll1_160m", "audio_pll1_out", "video_pll1_out", "clk_ext4", }; @@ -66,6 +66,7 @@ static const char *imx8mm_i2c3_sels[] = {"clock-osc-24m", "sys_pll1_160m", "sys_ static const char *imx8mm_i2c4_sels[] = {"clock-osc-24m", "sys_pll1_160m", "sys_pll2_50m", "sys_pll3_out", "audio_pll1_out", "video_pll1_out", "audio_pll2_out", "sys_pll1_133m", }; +#ifndef CONFIG_SPL_BUILD static const char *imx8mm_pwm1_sels[] = {"clock-osc-24m", "sys_pll2_100m", "sys_pll1_160m", "sys_pll1_40m", "sys_pll3_out", "clk_ext1", "sys_pll1_80m", "video_pll1_out", }; @@ -77,6 +78,7 @@ static const char *imx8mm_pwm3_sels[] = {"clock-osc-24m", "sys_pll2_100m", "sys_ static const char *imx8mm_pwm4_sels[] = {"clock-osc-24m", "sys_pll2_100m", "sys_pll1_160m", "sys_pll1_40m", "sys_pll3_out", "clk_ext2", "sys_pll1_80m", "video_pll1_out", }; +#endif static const char *imx8mm_wdog_sels[] = {"clock-osc-24m", "sys_pll1_133m", "sys_pll1_160m", "vpu_pll_out", "sys_pll2_125m", "sys_pll3_out", "sys_pll1_80m", "sys_pll2_166m", }; @@ -84,8 +86,10 @@ static const char *imx8mm_wdog_sels[] = {"clock-osc-24m", "sys_pll1_133m", "sys_ static const char *imx8mm_usdhc3_sels[] = {"clock-osc-24m", "sys_pll1_400m", "sys_pll1_800m", "sys_pll2_500m", "sys_pll3_out", "sys_pll1_266m", "audio_pll2_clk", "sys_pll1_100m", }; +#if CONFIG_IS_ENABLED(NXP_FSPI) static const char *imx8mm_qspi_sels[] = {"clock-osc-24m", "sys_pll1_400m", "sys_pll2_333m", "sys_pll2_500m", "audio_pll2_out", "sys_pll1_266m", "sys_pll3_out", "sys_pll1_100m", }; +#endif static const char *imx8mm_usb_core_sels[] = {"clock-osc-24m", "sys_pll1_100m", "sys_pll1_40m", "sys_pll2_100m", "sys_pll2_200m", "clk_ext2", "clk_ext3", "audio_pll2_out", }; @@ -93,6 +97,7 @@ static const char *imx8mm_usb_core_sels[] = {"clock-osc-24m", "sys_pll1_100m", " static const char *imx8mm_usb_phy_sels[] = {"clock-osc-24m", "sys_pll1_100m", "sys_pll1_40m", "sys_pll2_100m", "sys_pll2_200m", "clk_ext2", "clk_ext3", "audio_pll2_out", }; +#if CONFIG_IS_ENABLED(DM_SPI) static const char *imx8mm_ecspi1_sels[] = {"clock-osc-24m", "sys_pll2_200m", "sys_pll1_40m", "sys_pll1_160m", "sys_pll1_800m", "sys_pll3_out", "sys_pll2_250m", "audio_pll2_out", }; @@ -101,6 +106,7 @@ static const char *imx8mm_ecspi2_sels[] = {"clock-osc-24m", "sys_pll2_200m", "sy static const char *imx8mm_ecspi3_sels[] = {"clock-osc-24m", "sys_pll2_200m", "sys_pll1_40m", "sys_pll1_160m", "sys_pll1_800m", "sys_pll3_out", "sys_pll2_250m", "audio_pll2_out", }; +#endif static int imx8mm_clk_probe(struct udevice *dev) { @@ -242,9 +248,6 @@ static int imx8mm_clk_probe(struct udevice *dev) clk_dm(IMX8MM_CLK_IPG_ROOT, imx_clk_divider2("ipg_root", "ahb", base + 0x9080, 0, 1)); - clk_dm(IMX8MM_CLK_ENET_AXI, - imx8m_clk_composite("enet_axi", imx8mm_enet_axi_sels, - base + 0x8880)); clk_dm(IMX8MM_CLK_NAND_USDHC_BUS, imx8m_clk_composite_critical("nand_usdhc_bus", imx8mm_nand_usdhc_sels, @@ -267,38 +270,15 @@ static int imx8mm_clk_probe(struct udevice *dev) imx8m_clk_composite("i2c3", imx8mm_i2c3_sels, base + 0xae00)); clk_dm(IMX8MM_CLK_I2C4, imx8m_clk_composite("i2c4", imx8mm_i2c4_sels, base + 0xae80)); - clk_dm(IMX8MM_CLK_PWM1, - imx8m_clk_composite("pwm1", imx8mm_pwm1_sels, base + 0xb380)); - clk_dm(IMX8MM_CLK_PWM2, - imx8m_clk_composite("pwm2", imx8mm_pwm2_sels, base + 0xb400)); - clk_dm(IMX8MM_CLK_PWM3, - imx8m_clk_composite("pwm3", imx8mm_pwm3_sels, base + 0xb480)); - clk_dm(IMX8MM_CLK_PWM4, - imx8m_clk_composite("pwm4", imx8mm_pwm4_sels, base + 0xb500)); clk_dm(IMX8MM_CLK_WDOG, imx8m_clk_composite("wdog", imx8mm_wdog_sels, base + 0xb900)); clk_dm(IMX8MM_CLK_USDHC3, imx8m_clk_composite("usdhc3", imx8mm_usdhc3_sels, base + 0xbc80)); - clk_dm(IMX8MM_CLK_QSPI, - imx8m_clk_composite("qspi", imx8mm_qspi_sels, base + 0xab80)); clk_dm(IMX8MM_CLK_USB_CORE_REF, imx8m_clk_composite("usb_core_ref", imx8mm_usb_core_sels, base + 0xb100)); clk_dm(IMX8MM_CLK_USB_PHY_REF, imx8m_clk_composite("usb_phy_ref", imx8mm_usb_phy_sels, base + 0xb180)); - clk_dm(IMX8MM_CLK_ECSPI1, - imx8m_clk_composite("ecspi1", imx8mm_ecspi1_sels, base + 0xb280)); - clk_dm(IMX8MM_CLK_ECSPI2, - imx8m_clk_composite("ecspi2", imx8mm_ecspi2_sels, base + 0xb300)); - clk_dm(IMX8MM_CLK_ECSPI3, - imx8m_clk_composite("ecspi3", imx8mm_ecspi3_sels, base + 0xc180)); - - clk_dm(IMX8MM_CLK_ECSPI1_ROOT, - imx_clk_gate4("ecspi1_root_clk", "ecspi1", base + 0x4070, 0)); - clk_dm(IMX8MM_CLK_ECSPI2_ROOT, - imx_clk_gate4("ecspi2_root_clk", "ecspi2", base + 0x4080, 0)); - clk_dm(IMX8MM_CLK_ECSPI3_ROOT, - imx_clk_gate4("ecspi3_root_clk", "ecspi3", base + 0x4090, 0)); clk_dm(IMX8MM_CLK_I2C1_ROOT, imx_clk_gate4("i2c1_root_clk", "i2c1", base + 0x4170, 0)); clk_dm(IMX8MM_CLK_I2C2_ROOT, @@ -309,14 +289,6 @@ static int imx8mm_clk_probe(struct udevice *dev) imx_clk_gate4("i2c4_root_clk", "i2c4", base + 0x41a0, 0)); clk_dm(IMX8MM_CLK_OCOTP_ROOT, imx_clk_gate4("ocotp_root_clk", "ipg_root", base + 0x4220, 0)); - clk_dm(IMX8MM_CLK_PWM1_ROOT, - imx_clk_gate4("pwm1_root_clk", "pwm1", base + 0x4280, 0)); - clk_dm(IMX8MM_CLK_PWM2_ROOT, - imx_clk_gate4("pwm2_root_clk", "pwm2", base + 0x4290, 0)); - clk_dm(IMX8MM_CLK_PWM3_ROOT, - imx_clk_gate4("pwm3_root_clk", "pwm3", base + 0x42a0, 0)); - clk_dm(IMX8MM_CLK_PWM4_ROOT, - imx_clk_gate4("pwm4_root_clk", "pwm4", base + 0x42b0, 0)); clk_dm(IMX8MM_CLK_USDHC1_ROOT, imx_clk_gate4("usdhc1_root_clk", "usdhc1", base + 0x4510, 0)); clk_dm(IMX8MM_CLK_USDHC2_ROOT, @@ -329,13 +301,14 @@ static int imx8mm_clk_probe(struct udevice *dev) imx_clk_gate4("wdog3_root_clk", "wdog", base + 0x4550, 0)); clk_dm(IMX8MM_CLK_USDHC3_ROOT, imx_clk_gate4("usdhc3_root_clk", "usdhc3", base + 0x45e0, 0)); - clk_dm(IMX8MM_CLK_QSPI_ROOT, - imx_clk_gate4("qspi_root_clk", "qspi", base + 0x42f0, 0)); clk_dm(IMX8MM_CLK_USB1_CTRL_ROOT, imx_clk_gate4("usb1_ctrl_root_clk", "usb_bus", base + 0x44d0, 0)); /* clks not needed in SPL stage */ #ifndef CONFIG_SPL_BUILD + clk_dm(IMX8MM_CLK_ENET_AXI, + imx8m_clk_composite("enet_axi", imx8mm_enet_axi_sels, + base + 0x8880)); clk_dm(IMX8MM_CLK_ENET_REF, imx8m_clk_composite("enet_ref", imx8mm_enet_ref_sels, base + 0xa980)); @@ -348,6 +321,45 @@ static int imx8mm_clk_probe(struct udevice *dev) clk_dm(IMX8MM_CLK_ENET1_ROOT, imx_clk_gate4("enet1_root_clk", "enet_axi", base + 0x40a0, 0)); + clk_dm(IMX8MM_CLK_PWM1, + imx8m_clk_composite("pwm1", imx8mm_pwm1_sels, base + 0xb380)); + clk_dm(IMX8MM_CLK_PWM2, + imx8m_clk_composite("pwm2", imx8mm_pwm2_sels, base + 0xb400)); + clk_dm(IMX8MM_CLK_PWM3, + imx8m_clk_composite("pwm3", imx8mm_pwm3_sels, base + 0xb480)); + clk_dm(IMX8MM_CLK_PWM4, + imx8m_clk_composite("pwm4", imx8mm_pwm4_sels, base + 0xb500)); + clk_dm(IMX8MM_CLK_PWM1_ROOT, + imx_clk_gate4("pwm1_root_clk", "pwm1", base + 0x4280, 0)); + clk_dm(IMX8MM_CLK_PWM2_ROOT, + imx_clk_gate4("pwm2_root_clk", "pwm2", base + 0x4290, 0)); + clk_dm(IMX8MM_CLK_PWM3_ROOT, + imx_clk_gate4("pwm3_root_clk", "pwm3", base + 0x42a0, 0)); + clk_dm(IMX8MM_CLK_PWM4_ROOT, + imx_clk_gate4("pwm4_root_clk", "pwm4", base + 0x42b0, 0)); +#endif + +#if CONFIG_IS_ENABLED(DM_SPI) + clk_dm(IMX8MM_CLK_ECSPI1, + imx8m_clk_composite("ecspi1", imx8mm_ecspi1_sels, base + 0xb280)); + clk_dm(IMX8MM_CLK_ECSPI2, + imx8m_clk_composite("ecspi2", imx8mm_ecspi2_sels, base + 0xb300)); + clk_dm(IMX8MM_CLK_ECSPI3, + imx8m_clk_composite("ecspi3", imx8mm_ecspi3_sels, base + 0xc180)); + + clk_dm(IMX8MM_CLK_ECSPI1_ROOT, + imx_clk_gate4("ecspi1_root_clk", "ecspi1", base + 0x4070, 0)); + clk_dm(IMX8MM_CLK_ECSPI2_ROOT, + imx_clk_gate4("ecspi2_root_clk", "ecspi2", base + 0x4080, 0)); + clk_dm(IMX8MM_CLK_ECSPI3_ROOT, + imx_clk_gate4("ecspi3_root_clk", "ecspi3", base + 0x4090, 0)); +#endif + +#if CONFIG_IS_ENABLED(NXP_FSPI) + clk_dm(IMX8MM_CLK_QSPI, + imx8m_clk_composite("qspi", imx8mm_qspi_sels, base + 0xab80)); + clk_dm(IMX8MM_CLK_QSPI_ROOT, + imx_clk_gate4("qspi_root_clk", "qspi", base + 0x42f0, 0)); #endif return 0; diff --git a/drivers/crypto/fsl/fsl_rsa.c b/drivers/crypto/fsl/fsl_rsa.c index 897ee855ead..335b7fe25ac 100644 --- a/drivers/crypto/fsl/fsl_rsa.c +++ b/drivers/crypto/fsl/fsl_rsa.c @@ -6,6 +6,7 @@ #include <config.h> #include <common.h> +#include <cpu_func.h> #include <dm.h> #include <log.h> #include <asm/types.h> @@ -36,12 +37,21 @@ int fsl_mod_exp(struct udevice *dev, const uint8_t *sig, uint32_t sig_len, inline_cnstr_jobdesc_pkha_rsaexp(desc, &pkin, out, sig_len); + flush_dcache_range((ulong)sig, (ulong)sig + sig_len); + flush_dcache_range((ulong)prop->modulus, (ulong)(prop->modulus) + keylen); + flush_dcache_range((ulong)prop->public_exponent, + (ulong)(prop->public_exponent) + prop->exp_len); + flush_dcache_range((ulong)desc, (ulong)desc + (sizeof(uint32_t) * MAX_CAAM_DESCSIZE)); + flush_dcache_range((ulong)out, (ulong)out + sig_len); + ret = run_descriptor_jr(desc); if (ret) { debug("%s: RSA failed to verify: %d\n", __func__, ret); return -EFAULT; } + invalidate_dcache_range((ulong)out, (ulong)out + sig_len); + return 0; } diff --git a/drivers/ddr/imx/imx8m/ddr_init.c b/drivers/ddr/imx/imx8m/ddr_init.c index d964184ddc8..52a4aa63230 100644 --- a/drivers/ddr/imx/imx8m/ddr_init.c +++ b/drivers/ddr/imx/imx8m/ddr_init.c @@ -134,8 +134,14 @@ unsigned int lpddr4_mr_read(unsigned int mr_rank, unsigned int mr_addr) tmp = reg32_read(DRC_PERF_MON_MRR0_DAT(0)); } while ((tmp & 0x8) == 0); tmp = reg32_read(DRC_PERF_MON_MRR1_DAT(0)); - tmp = tmp & 0xff; reg32_write(DRC_PERF_MON_MRR0_DAT(0), 0x4); + while (tmp) { //try to find a significant byte in the word + if (tmp & 0xff) { + tmp &= 0xff; + break; + } + tmp >>= 8; + } return tmp; } diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 2a60478b476..220e2cb1628 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -611,4 +611,10 @@ config FTGPIO010 help Support for GPIOs on Faraday Technology's FTGPIO010 controller. +config ADP5585_GPIO + bool "ADP5585 GPIO driver" + depends on DM_GPIO && DM_I2C + help + Support ADP5585 GPIO expander. + endif diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index eee7908871d..7235714fcc0 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -76,3 +76,4 @@ obj-$(CONFIG_ZYNQMP_GPIO_MODEPIN) += zynqmp_gpio_modepin.o obj-$(CONFIG_SLG7XL45106_I2C_GPO) += gpio_slg7xl45106.o obj-$(CONFIG_$(SPL_TPL_)TURRIS_OMNIA_MCU) += turris_omnia_mcu.o obj-$(CONFIG_FTGPIO010) += ftgpio010.o +obj-$(CONFIG_ADP5585_GPIO) += adp5585_gpio.o diff --git a/drivers/gpio/adp5585_gpio.c b/drivers/gpio/adp5585_gpio.c new file mode 100644 index 00000000000..ea0cb75459b --- /dev/null +++ b/drivers/gpio/adp5585_gpio.c @@ -0,0 +1,238 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2022 NXP + * + * ADP5585 I/O Expander Controller + * + * Author: Alice Guo <alice.guo@nxp.com> + */ + +#include <asm/gpio.h> +#include <dm.h> +#include <dt-bindings/gpio/gpio.h> +#include <i2c.h> + +#define ADP5585_ID 0x00 +#define ADP5585_INT_STATUS 0x01 +#define ADP5585_STATUS 0x02 +#define ADP5585_FIFO_1 0x03 +#define ADP5585_FIFO_2 0x04 +#define ADP5585_FIFO_3 0x05 +#define ADP5585_FIFO_4 0x06 +#define ADP5585_FIFO_5 0x07 +#define ADP5585_FIFO_6 0x08 +#define ADP5585_FIFO_7 0x09 +#define ADP5585_FIFO_8 0x0A +#define ADP5585_FIFO_9 0x0B +#define ADP5585_FIFO_10 0x0C +#define ADP5585_FIFO_11 0x0D +#define ADP5585_FIFO_12 0x0E +#define ADP5585_FIFO_13 0x0F +#define ADP5585_FIFO_14 0x10 +#define ADP5585_FIFO_15 0x11 +#define ADP5585_FIFO_16 0x12 +#define ADP5585_GPI_INT_STAT_A 0x13 +#define ADP5585_GPI_INT_STAT_B 0x14 +#define ADP5585_GPI_STATUS_A 0x15 +#define ADP5585_GPI_STATUS_B 0x16 +#define ADP5585_RPULL_CONFIG_A 0x17 +#define ADP5585_RPULL_CONFIG_B 0x18 +#define ADP5585_RPULL_CONFIG_C 0x19 +#define ADP5585_RPULL_CONFIG_D 0x1A +#define ADP5585_GPI_INT_LEVEL_A 0x1B +#define ADP5585_GPI_INT_LEVEL_B 0x1C +#define ADP5585_GPI_EVENT_EN_A 0x1D +#define ADP5585_GPI_EVENT_EN_B 0x1E +#define ADP5585_GPI_INTERRUPT_EN_A 0x1F +#define ADP5585_GPI_INTERRUPT_EN_B 0x20 +#define ADP5585_DEBOUNCE_DIS_A 0x21 +#define ADP5585_DEBOUNCE_DIS_B 0x22 +#define ADP5585_GPO_DATA_OUT_A 0x23 +#define ADP5585_GPO_DATA_OUT_B 0x24 +#define ADP5585_GPO_OUT_MODE_A 0x25 +#define ADP5585_GPO_OUT_MODE_B 0x26 +#define ADP5585_GPIO_DIRECTION_A 0x27 +#define ADP5585_GPIO_DIRECTION_B 0x28 +#define ADP5585_RESET1_EVENT_A 0x29 +#define ADP5585_RESET1_EVENT_B 0x2A +#define ADP5585_RESET1_EVENT_C 0x2B +#define ADP5585_RESET2_EVENT_A 0x2C +#define ADP5585_RESET2_EVENT_B 0x2D +#define ADP5585_RESET_CFG 0x2E +#define ADP5585_PWM_OFFT_LOW 0x2F +#define ADP5585_PWM_OFFT_HIGH 0x30 +#define ADP5585_PWM_ONT_LOW 0x31 +#define ADP5585_PWM_ONT_HIGH 0x32 +#define ADP5585_PWM_CFG 0x33 +#define ADP5585_LOGIC_CFG 0x34 +#define ADP5585_LOGIC_FF_CFG 0x35 +#define ADP5585_LOGIC_INT_EVENT_EN 0x36 +#define ADP5585_POLL_PTIME_CFG 0x37 +#define ADP5585_PIN_CONFIG_A 0x38 +#define ADP5585_PIN_CONFIG_B 0x39 +#define ADP5585_PIN_CONFIG_D 0x3A +#define ADP5585_GENERAL_CFG 0x3B +#define ADP5585_INT_EN 0x3C + +#define ADP5585_MAXGPIO 10 +#define ADP5585_BANK(offs) ((offs) > 4) +#define ADP5585_BIT(offs) ((offs) > 4 ? \ + 1u << ((offs) - 5) : 1u << (offs)) + +struct adp5585_plat { + fdt_addr_t addr; + u8 id; + u8 dat_out[2]; + u8 dir[2]; +}; + +static int adp5585_direction_input(struct udevice *dev, unsigned int offset) +{ + int ret; + unsigned int bank; + struct adp5585_plat *plat = dev_get_plat(dev); + + bank = ADP5585_BANK(offset); + + plat->dir[bank] &= ~ADP5585_BIT(offset); + ret = dm_i2c_write(dev, ADP5585_GPIO_DIRECTION_A + bank, &plat->dir[bank], 1); + + return ret; +} + +static int adp5585_direction_output(struct udevice *dev, unsigned int offset, + int value) +{ + int ret; + unsigned int bank, bit; + struct adp5585_plat *plat = dev_get_plat(dev); + + bank = ADP5585_BANK(offset); + bit = ADP5585_BIT(offset); + + plat->dir[bank] |= bit; + + if (value) + plat->dat_out[bank] |= bit; + else + plat->dat_out[bank] &= ~bit; + + ret = dm_i2c_write(dev, ADP5585_GPO_DATA_OUT_A + bank, &plat->dat_out[bank], 1); + ret |= dm_i2c_write(dev, ADP5585_GPIO_DIRECTION_A + bank, &plat->dir[bank], 1); + + return ret; +} + +static int adp5585_get_value(struct udevice *dev, unsigned int offset) +{ + struct adp5585_plat *plat = dev_get_plat(dev); + unsigned int bank = ADP5585_BANK(offset); + unsigned int bit = ADP5585_BIT(offset); + u8 val; + + if (plat->dir[bank] & bit) + val = plat->dat_out[bank]; + else + dm_i2c_read(dev, ADP5585_GPI_STATUS_A + bank, &val, 1); + + return !!(val & bit); +} + +static int adp5585_set_value(struct udevice *dev, unsigned int offset, int value) +{ + int ret; + unsigned int bank, bit; + struct adp5585_plat *plat = dev_get_plat(dev); + + bank = ADP5585_BANK(offset); + bit = ADP5585_BIT(offset); + + if (value) + plat->dat_out[bank] |= bit; + else + plat->dat_out[bank] &= ~bit; + + ret = dm_i2c_write(dev, ADP5585_GPO_DATA_OUT_A + bank, &plat->dat_out[bank], 1); + + return ret; +} + +static int adp5585_get_function(struct udevice *dev, unsigned int offset) +{ + unsigned int bank, bit, dir; + struct adp5585_plat *plat = dev_get_plat(dev); + + bank = ADP5585_BANK(offset); + bit = ADP5585_BIT(offset); + dir = plat->dir[bank] & bit; + + if (!dir) + return GPIOF_INPUT; + else + return GPIOF_OUTPUT; +} + +static int adp5585_xlate(struct udevice *dev, struct gpio_desc *desc, + struct ofnode_phandle_args *args) +{ + desc->offset = args->args[0]; + desc->flags = args->args[1] & GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0; + + return 0; +} + +static const struct dm_gpio_ops adp5585_ops = { + .direction_input = adp5585_direction_input, + .direction_output = adp5585_direction_output, + .get_value = adp5585_get_value, + .set_value = adp5585_set_value, + .get_function = adp5585_get_function, + .xlate = adp5585_xlate, +}; + +static int adp5585_probe(struct udevice *dev) +{ + struct adp5585_plat *plat = dev_get_plat(dev); + struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); + int ret; + + if (!plat) + return 0; + + plat->addr = dev_read_addr(dev); + if (plat->addr == FDT_ADDR_T_NONE) + return -EINVAL; + + ret = dm_i2c_read(dev, ADP5585_ID, &plat->id, 1); + if (ret < 0) + return ret; + + uc_priv->gpio_count = ADP5585_MAXGPIO; + uc_priv->bank_name = "adp5585-gpio"; + + for (int i = 0; i < 2; i++) { + ret = dm_i2c_read(dev, ADP5585_GPO_DATA_OUT_A + i, &plat->dat_out[i], 1); + if (ret) + return ret; + + ret = dm_i2c_read(dev, ADP5585_GPIO_DIRECTION_A + i, &plat->dir[i], 1); + if (ret) + return ret; + } + + return 0; +} + +static const struct udevice_id adp5585_ids[] = { + { .compatible = "adp5585" }, + { } +}; + +U_BOOT_DRIVER(adp5585) = { + .name = "adp5585", + .id = UCLASS_GPIO, + .of_match = adp5585_ids, + .probe = adp5585_probe, + .ops = &adp5585_ops, + .plat_auto = sizeof(struct adp5585_plat), +}; diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index f799f70e43a..56f42820c74 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig @@ -576,12 +576,12 @@ config MMC_SDHCI_IPROC If unsure, say N. config MMC_SDHCI_F_SDH30 - bool "SDHCI support for Fujitsu Semiconductor F_SDH30" + bool "SDHCI support for Fujitsu Semiconductor/Socionext F_SDH30" depends on BLK && DM_MMC depends on MMC_SDHCI help This selects the Secure Digital Host Controller Interface (SDHCI) - Needed by some Fujitsu SoC for MMC / SD / SDIO support. + Needed by some Fujitsu/Socionext SoC for MMC / SD / SDIO support. If you have a controller with this interface, say Y or M here. If unsure, say N. diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c index 4232c5eb8c3..5085a3b491d 100644 --- a/drivers/mmc/dw_mmc.c +++ b/drivers/mmc/dw_mmc.c @@ -168,7 +168,8 @@ static int dwmci_data_transfer(struct dwmci_host *host, struct mmc_data *data) if (data->flags == MMC_DATA_READ && (mask & (DWMCI_INTMSK_RXDR | DWMCI_INTMSK_DTO))) { dwmci_writel(host, DWMCI_RINTSTS, - DWMCI_INTMSK_RXDR | DWMCI_INTMSK_DTO); + mask & (DWMCI_INTMSK_RXDR | + DWMCI_INTMSK_DTO)); while (size) { ret = dwmci_fifo_ready(host, DWMCI_FIFO_EMPTY, diff --git a/drivers/mmc/f_sdh30.c b/drivers/mmc/f_sdh30.c index 3a85d9e348a..3d587a464d5 100644 --- a/drivers/mmc/f_sdh30.c +++ b/drivers/mmc/f_sdh30.c @@ -11,13 +11,48 @@ #include <malloc.h> #include <sdhci.h> +#define F_SDH30_ESD_CONTROL 0x124 +#define F_SDH30_CMD_DAT_DELAY BIT(9) + +#define F_SDH30_TEST 0x158 +#define F_SDH30_FORCE_CARD_INSERT BIT(6) + +struct f_sdh30_data { + void (*init)(struct udevice *dev); + u32 quirks; +}; + struct f_sdh30_plat { struct mmc_config cfg; struct mmc mmc; + + bool enable_cmd_dat_delay; + const struct f_sdh30_data *data; }; DECLARE_GLOBAL_DATA_PTR; +static void f_sdh30_e51_init(struct udevice *dev) +{ + struct f_sdh30_plat *plat = dev_get_plat(dev); + struct sdhci_host *host = dev_get_priv(dev); + u32 val; + + val = sdhci_readl(host, F_SDH30_ESD_CONTROL); + if (plat->enable_cmd_dat_delay) + val |= F_SDH30_CMD_DAT_DELAY; + else + val &= ~F_SDH30_CMD_DAT_DELAY; + sdhci_writel(host, val, F_SDH30_ESD_CONTROL); + + val = sdhci_readl(host, F_SDH30_TEST); + if (plat->cfg.host_caps & MMC_CAP_NONREMOVABLE) + val |= F_SDH30_FORCE_CARD_INSERT; + else + val &= ~F_SDH30_FORCE_CARD_INSERT; + sdhci_writel(host, val, F_SDH30_TEST); +} + static int f_sdh30_sdhci_probe(struct udevice *dev) { struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); @@ -25,6 +60,8 @@ static int f_sdh30_sdhci_probe(struct udevice *dev) struct sdhci_host *host = dev_get_priv(dev); int ret; + plat->data = (const struct f_sdh30_data *)dev_get_driver_data(dev); + ret = mmc_of_parse(dev, &plat->cfg); if (ret) return ret; @@ -33,6 +70,9 @@ static int f_sdh30_sdhci_probe(struct udevice *dev) host->mmc->dev = dev; host->mmc->priv = host; + if (plat->data && plat->data->quirks) + host->quirks = plat->data->quirks; + ret = sdhci_setup_cfg(&plat->cfg, host, 200000000, 400000); if (ret) return ret; @@ -41,18 +81,29 @@ static int f_sdh30_sdhci_probe(struct udevice *dev) mmc_set_clock(host->mmc, host->mmc->cfg->f_min, MMC_CLK_ENABLE); - return sdhci_probe(dev); + ret = sdhci_probe(dev); + if (ret) + return ret; + + if (plat->data && plat->data->init) + plat->data->init(dev); + + return 0; } static int f_sdh30_of_to_plat(struct udevice *dev) { struct sdhci_host *host = dev_get_priv(dev); + struct f_sdh30_plat *plat = dev_get_plat(dev); host->name = strdup(dev->name); host->ioaddr = dev_read_addr_ptr(dev); host->bus_width = dev_read_u32_default(dev, "bus-width", 4); host->index = dev_read_u32_default(dev, "index", 0); + plat->enable_cmd_dat_delay = + dev_read_bool(dev, "socionext,enable-cmd-dat-delay"); + return 0; } @@ -63,8 +114,19 @@ static int f_sdh30_bind(struct udevice *dev) return sdhci_bind(dev, &plat->mmc, &plat->cfg); } +static const struct f_sdh30_data f_sdh30_e51_data = { + .init = f_sdh30_e51_init, + .quirks = SDHCI_QUIRK_WAIT_SEND_CMD | SDHCI_QUIRK_SUPPORT_SINGLE, +}; + static const struct udevice_id f_sdh30_mmc_ids[] = { - { .compatible = "fujitsu,mb86s70-sdhci-3.0" }, + { + .compatible = "fujitsu,mb86s70-sdhci-3.0", + }, + { + .compatible = "socionext,f-sdh30-e51-mmc", + .data = (ulong)&f_sdh30_e51_data, + }, { } }; diff --git a/drivers/mmc/fsl_esdhc_imx.c b/drivers/mmc/fsl_esdhc_imx.c index 9befb190bdf..92b152fc979 100644 --- a/drivers/mmc/fsl_esdhc_imx.c +++ b/drivers/mmc/fsl_esdhc_imx.c @@ -1519,8 +1519,6 @@ static int fsl_esdhc_probe(struct udevice *dev) * work as expected. */ - init_clk_usdhc(dev_seq(dev)); - #if CONFIG_IS_ENABLED(CLK) /* Assigned clock already set clock */ ret = clk_get_by_name(dev, "per", &priv->per_clk); @@ -1536,6 +1534,8 @@ static int fsl_esdhc_probe(struct udevice *dev) priv->sdhc_clk = clk_get_rate(&priv->per_clk); #else + init_clk_usdhc(dev_seq(dev)); + priv->sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK + dev_seq(dev)); if (priv->sdhc_clk <= 0) { dev_err(dev, "Unable to get clk for %s\n", dev->name); diff --git a/drivers/mmc/ftsdc010_mci.c b/drivers/mmc/ftsdc010_mci.c index 570d54cf9d8..cabb747fbbd 100644 --- a/drivers/mmc/ftsdc010_mci.c +++ b/drivers/mmc/ftsdc010_mci.c @@ -30,7 +30,7 @@ #include <syscon.h> #include <linux/err.h> -#define CFG_CMD_TIMEOUT (CONFIG_SYS_HZ >> 4) /* 250 ms */ +#define CFG_CMD_TIMEOUT (CONFIG_SYS_HZ >> 2) /* 250 ms */ #define CFG_RST_TIMEOUT CONFIG_SYS_HZ /* 1 sec reset timeout */ #if CONFIG_IS_ENABLED(OF_PLATDATA) diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 0b7c0be8cbc..210703ea46b 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -3113,10 +3113,12 @@ int mmc_init_device(int num) } m = mmc_get_mmc_dev(dev); - m->user_speed_mode = MMC_MODES_END; /* Initialising user set speed mode */ - if (!m) return 0; + + /* Initialising user set speed mode */ + m->user_speed_mode = MMC_MODES_END; + if (m->preinit) mmc_start_init(m); diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index bf989a594f7..a80ad8329a3 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c @@ -211,7 +211,7 @@ static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd, unsigned int stat = 0; int ret = 0; int trans_bytes = 0, is_aligned = 1; - u32 mask, flags, mode; + u32 mask, flags, mode = 0; unsigned int time = 0; int mmc_dev = mmc_get_blk_desc(mmc)->devnum; ulong start = get_timer(0); @@ -273,10 +273,12 @@ static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd, /* Set Transfer mode regarding to data flag */ if (data) { sdhci_writeb(host, 0xe, SDHCI_TIMEOUT_CONTROL); - mode = SDHCI_TRNS_BLK_CNT_EN; + + if (!(host->quirks & SDHCI_QUIRK_SUPPORT_SINGLE)) + mode = SDHCI_TRNS_BLK_CNT_EN; trans_bytes = data->blocks * data->blocksize; if (data->blocks > 1) - mode |= SDHCI_TRNS_MULTI; + mode |= SDHCI_TRNS_MULTI | SDHCI_TRNS_BLK_CNT_EN; if (data->flags == MMC_DATA_READ) mode |= SDHCI_TRNS_READ; diff --git a/drivers/mmc/stm32_sdmmc2.c b/drivers/mmc/stm32_sdmmc2.c index 7ab4d949e74..b68594de373 100644 --- a/drivers/mmc/stm32_sdmmc2.c +++ b/drivers/mmc/stm32_sdmmc2.c @@ -25,6 +25,7 @@ #include <asm/io.h> #include <asm/gpio.h> #include <linux/iopoll.h> +#include <power/regulator.h> #include <watchdog.h> struct stm32_sdmmc2_plat { @@ -36,6 +37,9 @@ struct stm32_sdmmc2_plat { struct gpio_desc cd_gpio; u32 clk_reg_msk; u32 pwr_reg_msk; +#if CONFIG_IS_ENABLED(DM_REGULATOR) + bool vqmmc_enabled; +#endif }; struct stm32_sdmmc2_ctx { @@ -572,6 +576,15 @@ static void stm32_sdmmc2_pwron(struct stm32_sdmmc2_plat *plat) plat->base + SDMMC_POWER); /* during the first 74 SDMMC_CK cycles the SDMMC is still disabled. */ + +#if CONFIG_IS_ENABLED(DM_REGULATOR) + if (plat->mmc.vqmmc_supply && !plat->vqmmc_enabled) { + if (regulator_set_enable_if_allowed(plat->mmc.vqmmc_supply, true)) + dev_dbg(plat->mmc.dev, "failed to enable vqmmc-supply\n"); + else + plat->vqmmc_enabled = true; + } +#endif } #define IS_RISING_EDGE(reg) (reg & SDMMC_CLKCR_NEGEDGE ? 0 : 1) @@ -598,13 +611,16 @@ static int stm32_sdmmc2_set_ios(struct udevice *dev) * clk_div > 0 and NEGEDGE = 1 => command and data generated on * SDMMCCLK falling edge */ - if (desired && ((sys_clock > desired) || + if (desired && (sys_clock > desired || mmc->ddr_mode || IS_RISING_EDGE(plat->clk_reg_msk))) { clk = DIV_ROUND_UP(sys_clock, 2 * desired); if (clk > SDMMC_CLKCR_CLKDIV_MAX) clk = SDMMC_CLKCR_CLKDIV_MAX; } + if (mmc->ddr_mode) + clk |= SDMMC_CLKCR_DDR; + if (mmc->bus_width == 4) clk |= SDMMC_CLKCR_WIDBUS_4; if (mmc->bus_width == 8) @@ -672,6 +688,8 @@ static int stm32_sdmmc2_of_to_plat(struct udevice *dev) if (ret) return ret; + cfg->host_caps &= ~(UHS_CAPS | MMC_MODE_HS200 | MMC_MODE_HS400 | MMC_MODE_HS400_ES); + ret = clk_get_by_index(dev, 0, &plat->clk); if (ret) return ret; diff --git a/drivers/mtd/spi/Kconfig b/drivers/mtd/spi/Kconfig index 096338f27bf..7b858a3a919 100644 --- a/drivers/mtd/spi/Kconfig +++ b/drivers/mtd/spi/Kconfig @@ -166,13 +166,13 @@ config SPI_FLASH_SPANSION help Add support for various Spansion SPI flash chips (S25FLxxx) -config SPI_FLASH_S28HS512T - bool "Cypress S28HS512T chip support" +config SPI_FLASH_S28HX_T + bool "Cypress SEMPER Octal (S28) chip support" depends on SPI_FLASH_SPANSION help - Add support for the Cypress S28HS512T chip. This is a separate config - because the fixup hooks for this flash add extra size overhead. Boards - that don't use the flash can disable this to save space. + Add support for the Cypress S28HL-T and S28HS-T chip. This is a separate + config because the fixup hooks for this flash add extra size overhead. + Boards that don't use the flash can disable this to save space. config SPI_FLASH_STMICRO bool "STMicro SPI flash support" diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c index c73636d7d11..78de3c52816 100644 --- a/drivers/mtd/spi/spi-nor-core.c +++ b/drivers/mtd/spi/spi-nor-core.c @@ -161,6 +161,7 @@ struct sfdp_header { #define BFPT_DWORD15_QER_SR2_BIT1 (0x5UL << 20) /* Spansion */ #define BFPT_DWORD16_SOFT_RST BIT(12) +#define BFPT_DWORD16_EX4B_PWRCYC BIT(21) #define BFPT_DWORD18_CMD_EXT_MASK GENMASK(30, 29) #define BFPT_DWORD18_CMD_EXT_REP (0x0UL << 29) /* Repeat */ @@ -329,10 +330,10 @@ static int spansion_read_any_reg(struct spi_nor *nor, u32 addr, u8 dummy, u8 *val) { struct spi_mem_op op = - SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RDAR, 1), - SPI_MEM_OP_ADDR(nor->addr_width, addr, 1), - SPI_MEM_OP_DUMMY(dummy / 8, 1), - SPI_MEM_OP_DATA_IN(1, NULL, 1)); + SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RDAR, 1), + SPI_MEM_OP_ADDR(nor->addr_mode_nbytes, addr, 1), + SPI_MEM_OP_DUMMY(dummy / 8, 1), + SPI_MEM_OP_DATA_IN(1, NULL, 1)); return spi_nor_read_write_reg(nor, &op, val); } @@ -340,10 +341,10 @@ static int spansion_read_any_reg(struct spi_nor *nor, u32 addr, u8 dummy, static int spansion_write_any_reg(struct spi_nor *nor, u32 addr, u8 val) { struct spi_mem_op op = - SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WRAR, 1), - SPI_MEM_OP_ADDR(nor->addr_width, addr, 1), - SPI_MEM_OP_NO_DUMMY, - SPI_MEM_OP_DATA_OUT(1, NULL, 1)); + SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WRAR, 1), + SPI_MEM_OP_ADDR(nor->addr_mode_nbytes, addr, 1), + SPI_MEM_OP_NO_DUMMY, + SPI_MEM_OP_DATA_OUT(1, NULL, 1)); return spi_nor_read_write_reg(nor, &op, &val); } @@ -2236,11 +2237,14 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor, /* Number of address bytes. */ switch (bfpt.dwords[BFPT_DWORD(1)] & BFPT_DWORD1_ADDRESS_BYTES_MASK) { case BFPT_DWORD1_ADDRESS_BYTES_3_ONLY: + case BFPT_DWORD1_ADDRESS_BYTES_3_OR_4: nor->addr_width = 3; + nor->addr_mode_nbytes = 3; break; case BFPT_DWORD1_ADDRESS_BYTES_4_ONLY: nor->addr_width = 4; + nor->addr_mode_nbytes = 4; break; default: @@ -2516,7 +2520,7 @@ static int spi_nor_parse_sccr(struct spi_nor *nor, for (i = 0; i < sccr_header->length; i++) table[i] = le32_to_cpu(table[i]); - if (FIELD_GET(SCCR_DWORD22_OCTAL_DTR_EN_VOLATILE, table[22])) + if (FIELD_GET(SCCR_DWORD22_OCTAL_DTR_EN_VOLATILE, table[21])) nor->flags |= SNOR_F_IO_MODE_EN_VOLATILE; out: @@ -3273,10 +3277,24 @@ static int s25hx_t_post_bfpt_fixup(struct spi_nor *nor, nor->erase_opcode = SPINOR_OP_SE_4B; nor->mtd.erasesize = nor->info->sector_size; - ret = set_4byte(nor, nor->info, 1); - if (ret) - return ret; - nor->addr_width = 4; + /* + * The default address mode in multi-die package parts (>1Gb) may be + * 3- or 4-byte, depending on model number. BootROM code in some SoCs + * use 3-byte mode for backward compatibility and should switch to + * 4-byte mode after BootROM phase. Since registers in the 2nd die are + * mapped within 32-bit address space, we need to make sure the flash is + * in 4-byte address mode. The default address mode can be distinguished + * by BFPT 16th DWORD. Power cycle exits 4-byte address mode if default + * is 3-byte address mode. + */ + if (params->size > SZ_128M) { + if (bfpt->dwords[BFPT_DWORD(16)] & BFPT_DWORD16_EX4B_PWRCYC) { + ret = set_4byte(nor, nor->info, 1); + if (ret) + return ret; + } + nor->addr_mode_nbytes = 4; + } /* * The page_size is set to 512B from BFPT, but it actually depends on @@ -3333,7 +3351,7 @@ static struct spi_nor_fixups s25fl256l_fixups = { }; #endif -#ifdef CONFIG_SPI_FLASH_S28HS512T +#ifdef CONFIG_SPI_FLASH_S28HX_T /** * spi_nor_cypress_octal_dtr_enable() - Enable octal DTR on Cypress flashes. * @nor: pointer to a 'struct spi_nor' @@ -3392,15 +3410,15 @@ static int spi_nor_cypress_octal_dtr_enable(struct spi_nor *nor) return 0; } -static int s28hs512t_erase_non_uniform(struct spi_nor *nor, loff_t addr) +static int s28hx_t_erase_non_uniform(struct spi_nor *nor, loff_t addr) { /* Factory default configuration: 32 x 4 KiB sectors at bottom. */ return spansion_erase_non_uniform(nor, addr, SPINOR_OP_S28_SE_4K, 0, SZ_128K); } -static int s28hs512t_setup(struct spi_nor *nor, const struct flash_info *info, - const struct spi_nor_flash_parameter *params) +static int s28hx_t_setup(struct spi_nor *nor, const struct flash_info *info, + const struct spi_nor_flash_parameter *params) { struct spi_mem_op op; u8 buf; @@ -3427,19 +3445,19 @@ static int s28hs512t_setup(struct spi_nor *nor, const struct flash_info *info, return ret; if (!(buf & SPINOR_REG_CYPRESS_CFR3V_UNISECT)) - nor->erase = s28hs512t_erase_non_uniform; + nor->erase = s28hx_t_erase_non_uniform; return spi_nor_default_setup(nor, info, params); } -static void s28hs512t_default_init(struct spi_nor *nor) +static void s28hx_t_default_init(struct spi_nor *nor) { nor->octal_dtr_enable = spi_nor_cypress_octal_dtr_enable; - nor->setup = s28hs512t_setup; + nor->setup = s28hx_t_setup; } -static void s28hs512t_post_sfdp_fixup(struct spi_nor *nor, - struct spi_nor_flash_parameter *params) +static void s28hx_t_post_sfdp_fixup(struct spi_nor *nor, + struct spi_nor_flash_parameter *params) { /* * On older versions of the flash the xSPI Profile 1.0 table has the @@ -3469,10 +3487,10 @@ static void s28hs512t_post_sfdp_fixup(struct spi_nor *nor, params->rdsr_addr_nbytes = 4; } -static int s28hs512t_post_bfpt_fixup(struct spi_nor *nor, - const struct sfdp_parameter_header *bfpt_header, - const struct sfdp_bfpt *bfpt, - struct spi_nor_flash_parameter *params) +static int s28hx_t_post_bfpt_fixup(struct spi_nor *nor, + const struct sfdp_parameter_header *bfpt_header, + const struct sfdp_bfpt *bfpt, + struct spi_nor_flash_parameter *params) { struct spi_mem_op op; u8 buf; @@ -3509,12 +3527,12 @@ static int s28hs512t_post_bfpt_fixup(struct spi_nor *nor, return 0; } -static struct spi_nor_fixups s28hs512t_fixups = { - .default_init = s28hs512t_default_init, - .post_sfdp = s28hs512t_post_sfdp_fixup, - .post_bfpt = s28hs512t_post_bfpt_fixup, +static struct spi_nor_fixups s28hx_t_fixups = { + .default_init = s28hx_t_default_init, + .post_sfdp = s28hx_t_post_sfdp_fixup, + .post_bfpt = s28hx_t_post_bfpt_fixup, }; -#endif /* CONFIG_SPI_FLASH_S28HS512T */ +#endif /* CONFIG_SPI_FLASH_S28HX_T */ #ifdef CONFIG_SPI_FLASH_MT35XU static int spi_nor_micron_octal_dtr_enable(struct spi_nor *nor) @@ -3835,6 +3853,13 @@ void spi_nor_set_fixups(struct spi_nor *nor) nor->fixups = &s25hx_t_fixups; break; +#ifdef CONFIG_SPI_FLASH_S28HX_T + case 0x5a: /* S28HL (Octal, 3.3V) */ + case 0x5b: /* S28HS (Octal, 1.8V) */ + nor->fixups = &s28hx_t_fixups; + break; +#endif + default: break; } @@ -3845,11 +3870,6 @@ void spi_nor_set_fixups(struct spi_nor *nor) nor->fixups = &s25fl256l_fixups; #endif -#ifdef CONFIG_SPI_FLASH_S28HS512T - if (!strcmp(nor->info->name, "s28hs512t")) - nor->fixups = &s28hs512t_fixups; -#endif - #ifdef CONFIG_SPI_FLASH_MT35XU if (!strcmp(nor->info->name, "mt35xu512aba")) nor->fixups = &mt35xu512aba_fixups; diff --git a/drivers/mtd/spi/spi-nor-ids.c b/drivers/mtd/spi/spi-nor-ids.c index 65eb35a9185..5f8f3ec955d 100644 --- a/drivers/mtd/spi/spi-nor-ids.c +++ b/drivers/mtd/spi/spi-nor-ids.c @@ -294,8 +294,11 @@ const struct flash_info spi_nor_ids[] = { USE_CLSR) }, { INFO6("s25hs02gt", 0x342b1c, 0x0f0090, 256 * 1024, 1024, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) }, -#ifdef CONFIG_SPI_FLASH_S28HS512T +#ifdef CONFIG_SPI_FLASH_S28HX_T + { INFO("s28hl512t", 0x345a1a, 0, 256 * 1024, 256, SPI_NOR_OCTAL_DTR_READ) }, + { INFO("s28hl01gt", 0x345a1b, 0, 256 * 1024, 512, SPI_NOR_OCTAL_DTR_READ) }, { INFO("s28hs512t", 0x345b1a, 0, 256 * 1024, 256, SPI_NOR_OCTAL_DTR_READ) }, + { INFO("s28hs01gt", 0x345b1b, 0, 256 * 1024, 512, SPI_NOR_OCTAL_DTR_READ) }, #endif #endif #ifdef CONFIG_SPI_FLASH_SST /* SST */ diff --git a/drivers/net/ftgmac100.c b/drivers/net/ftgmac100.c index 74261d14e54..a50cde338a2 100644 --- a/drivers/net/ftgmac100.c +++ b/drivers/net/ftgmac100.c @@ -188,7 +188,7 @@ static int ftgmac100_phy_adjust_link(struct ftgmac100_data *priv) struct phy_device *phydev = priv->phydev; u32 maccr; - if (!phydev->link) { + if (!phydev->link && priv->phy_mode != PHY_INTERFACE_MODE_NCSI) { dev_err(phydev->dev, "No link\n"); return -EREMOTEIO; } @@ -228,7 +228,8 @@ static int ftgmac100_phy_init(struct udevice *dev) if (!phydev) return -ENODEV; - phydev->supported &= PHY_GBIT_FEATURES; + if (priv->phy_mode != PHY_INTERFACE_MODE_NCSI) + phydev->supported &= PHY_GBIT_FEATURES; if (priv->max_speed) { ret = phy_set_supported(phydev, priv->max_speed); if (ret) @@ -308,7 +309,8 @@ static void ftgmac100_stop(struct udevice *dev) writel(0, &ftgmac100->maccr); - phy_shutdown(priv->phydev); + if (priv->phy_mode != PHY_INTERFACE_MODE_NCSI) + phy_shutdown(priv->phydev); } static int ftgmac100_start(struct udevice *dev) @@ -580,6 +582,9 @@ static int ftgmac100_probe(struct udevice *dev) priv->max_speed = pdata->max_speed; priv->phy_addr = 0; + if (dev_read_bool(dev, "use-ncsi")) + priv->phy_mode = PHY_INTERFACE_MODE_NCSI; + #ifdef CONFIG_PHY_ADDR priv->phy_addr = CONFIG_PHY_ADDR; #endif @@ -592,7 +597,8 @@ static int ftgmac100_probe(struct udevice *dev) * If DM MDIO is enabled, the MDIO bus will be initialized later in * dm_eth_phy_connect */ - if (!IS_ENABLED(CONFIG_DM_MDIO)) { + if (priv->phy_mode != PHY_INTERFACE_MODE_NCSI && + !IS_ENABLED(CONFIG_DM_MDIO)) { ret = ftgmac100_mdio_init(dev); if (ret) { dev_err(dev, "Failed to initialize mdiobus: %d\n", ret); diff --git a/drivers/net/phy/ncsi.c b/drivers/net/phy/ncsi.c index bf1e832be9f..bb7ecebed38 100644 --- a/drivers/net/phy/ncsi.c +++ b/drivers/net/phy/ncsi.c @@ -9,6 +9,7 @@ #include <log.h> #include <malloc.h> #include <phy.h> +#include <net.h> #include <net/ncsi.h> #include <net/ncsi-pkt.h> #include <asm/unaligned.h> diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 0350afdd1b6..90876630533 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -1026,7 +1026,7 @@ struct phy_device *phy_connect(struct mii_dev *bus, int addr, #endif #ifdef CONFIG_PHY_NCSI - if (!phydev) + if (!phydev && interface == PHY_INTERFACE_MODE_NCSI) phydev = phy_device_create(bus, 0, PHY_NCSI_ID, false); #endif @@ -1275,3 +1275,10 @@ int phy_clear_bits_mmd(struct phy_device *phydev, int devad, u32 regnum, u16 val return 0; } + +bool phy_interface_is_ncsi(void) +{ + struct eth_pdata *pdata = dev_get_plat(eth_get_dev()); + + return pdata->phy_interface == PHY_INTERFACE_MODE_NCSI; +} |