* [PATCH v2 0/8] Cortina Access Drivers Package 2
@ 2020-03-20 0:57 Alex Nemirovsky
2020-03-20 0:57 ` [PATCH v2 1/8] mmc: ca_dw_mmc: add DesignWare based DM support for CAxxxx SoCs Alex Nemirovsky
` (7 more replies)
0 siblings, 8 replies; 18+ messages in thread
From: Alex Nemirovsky @ 2020-03-20 0:57 UTC (permalink / raw)
To: u-boot
This release adds the following drivers and
integrates support into the Cortina Access
Presidio Engineering Board:
CAxxxx SoC eMMC/SD controller
CAxxxx SoC I2C controller
CAxxxx Soc LED controller
CAxxxx SPI NAND and NOR controller
Changes in v3:
- Fixup syntax issues related to checkpatch.pl cleanup
Changes in v2:
- Add I2C controller
- Add LED controller
- Add SPI NAND and NOR controller
Alex Nemirovsky (3):
board: presidio-asic: Add eMMC board support
board: presidio-asic: Add I2C support
board: presidio-asic: Add SPI NAND and NOR support
Arthur Li (2):
mmc: ca_dw_mmc: add DesignWare based DM support for CAxxxx SoCs
i2c: i2c-cortina: added CAxxxx I2C support
Jway Lin (2):
led: led_cortina: Add CAxxx LED support
board: presidio: add LED support
Pengpeng Chen (1):
spi: ca_sflash: Add CAxxxx SPI Flash Controller
MAINTAINERS | 10 +
arch/arm/dts/ca-presidio-engboard.dts | 39 +-
board/cortina/presidio-asic/presidio.c | 16 +-
configs/cortina_presidio-asic-emmc_defconfig | 38 ++
configs/cortina_presidio-asic-spi-nand_defconfig | 48 ++
configs/cortina_presidio-asic-spi-nor_defconfig | 59 +++
drivers/i2c/Kconfig | 7 +
drivers/i2c/Makefile | 1 +
drivers/i2c/i2c-cortina.c | 346 ++++++++++++++
drivers/i2c/i2c-cortina.h | 92 ++++
drivers/led/Kconfig | 8 +
drivers/led/Makefile | 1 +
drivers/led/led_cortina.c | 308 ++++++++++++
drivers/mmc/Kconfig | 11 +
drivers/mmc/Makefile | 1 +
drivers/mmc/ca_dw_mmc.c | 181 +++++++
drivers/spi/Kconfig | 8 +
drivers/spi/Makefile | 1 +
drivers/spi/ca_sflash.c | 576 +++++++++++++++++++++++
19 files changed, 1745 insertions(+), 6 deletions(-)
create mode 100644 configs/cortina_presidio-asic-emmc_defconfig
create mode 100644 configs/cortina_presidio-asic-spi-nand_defconfig
create mode 100644 configs/cortina_presidio-asic-spi-nor_defconfig
create mode 100644 drivers/i2c/i2c-cortina.c
create mode 100644 drivers/i2c/i2c-cortina.h
create mode 100644 drivers/led/led_cortina.c
create mode 100644 drivers/mmc/ca_dw_mmc.c
create mode 100644 drivers/spi/ca_sflash.c
--
2.7.4
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v2 1/8] mmc: ca_dw_mmc: add DesignWare based DM support for CAxxxx SoCs
2020-03-20 0:57 [PATCH v2 0/8] Cortina Access Drivers Package 2 Alex Nemirovsky
@ 2020-03-20 0:57 ` Alex Nemirovsky
2020-03-24 7:16 ` Jaehoon Chung
2020-03-20 0:57 ` [PATCH v2 2/8] board: presidio-asic: Add eMMC board support Alex Nemirovsky
` (6 subsequent siblings)
7 siblings, 1 reply; 18+ messages in thread
From: Alex Nemirovsky @ 2020-03-20 0:57 UTC (permalink / raw)
To: u-boot
From: Arthur Li <arthur.li@cortina-access.com>
Initial DesignWare based DM support for Cortina Access CAxxxx SoCs.
Signed-off-by: Arthur Li <arthur.li@cortina-access.com>
Signed-off-by: Alex Nemirovsky <alex.nemirovsky@cortina-access.com>
CC: Peng Fan <peng.fan@nxp.com>
---
Changes in v3: None
Changes in v2:
- Add I2C controller
- Add LED controller
- Add SPI NAND and NOR controller
MAINTAINERS | 2 +
drivers/mmc/Kconfig | 11 +++
drivers/mmc/Makefile | 1 +
drivers/mmc/ca_dw_mmc.c | 181 ++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 195 insertions(+)
create mode 100644 drivers/mmc/ca_dw_mmc.c
diff --git a/MAINTAINERS b/MAINTAINERS
index 82e4159..bb45d3c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -180,6 +180,7 @@ F: board/cortina/common/
F: drivers/gpio/cortina_gpio.c
F: drivers/watchdog/cortina_wdt.c
F: drivers/serial/serial_cortina.c
+F: drivers/mmc/ca_dw_mmc.c
ARM/CZ.NIC TURRIS MOX SUPPORT
M: Marek Behun <marek.behun@nic.cz>
@@ -670,6 +671,7 @@ F: board/cortina/common/
F: drivers/gpio/cortina_gpio.c
F: drivers/watchdog/cortina_wdt.c
F: drivers/serial/serial_cortina.c
+F: drivers/mmc/ca_dw_mmc.c
MIPS MSCC
M: Gregory CLEMENT <gregory.clement@bootlin.com>
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index 2f0eedc..bb38787 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -205,6 +205,17 @@ config MMC_DW
block, this provides host support for SD and MMC interfaces, in both
PIO, internal DMA mode and external DMA mode.
+config MMC_DW_CORTINA
+ bool "Cortina specific extensions for Synopsys DW Memory Card Interface"
+ depends on DM_MMC
+ depends on MMC_DW
+ depends on BLK
+ default n
+ help
+ This selects support for Cortina SoC specific extensions to the
+ Synopsys DesignWare Memory Card Interface driver. Select this option
+ for platforms based on Cortina CAxxxx Soc's.
+
config MMC_DW_EXYNOS
bool "Exynos specific extensions for Synopsys DW Memory Card Interface"
depends on ARCH_EXYNOS
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index 9c1f8e5..615b724 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -20,6 +20,7 @@ endif
obj-$(CONFIG_ARM_PL180_MMCI) += arm_pl180_mmci.o
obj-$(CONFIG_MMC_DAVINCI) += davinci_mmc.o
obj-$(CONFIG_MMC_DW) += dw_mmc.o
+obj-$(CONFIG_MMC_DW_CORTINA) += ca_dw_mmc.o
obj-$(CONFIG_MMC_DW_EXYNOS) += exynos_dw_mmc.o
obj-$(CONFIG_MMC_DW_K3) += hi6220_dw_mmc.o
obj-$(CONFIG_MMC_DW_ROCKCHIP) += rockchip_dw_mmc.o
diff --git a/drivers/mmc/ca_dw_mmc.c b/drivers/mmc/ca_dw_mmc.c
new file mode 100644
index 0000000..acbc850
--- /dev/null
+++ b/drivers/mmc/ca_dw_mmc.c
@@ -0,0 +1,181 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2019 Cortina Access
+ * Arthur Li <arthur.li@cortina-access.com>
+ */
+
+#include <common.h>
+#include <dwmmc.h>
+#include <fdtdec.h>
+#include <linux/libfdt.h>
+#include <malloc.h>
+#include <errno.h>
+#include <dm.h>
+#include <mapmem.h>
+
+#define SD_CLK_SEL_MASK (0x3)
+#define SD_DLL_DEFAULT (0x143000)
+#define SD_SCLK_MAX (200000000)
+
+#define SD_CLK_SEL_200MHZ (0x2)
+#define SD_CLK_SEL_100MHZ (0x1)
+
+#define IO_DRV_SD_DS_OFFSET (16)
+#define IO_DRV_SD_DS_MASK (0xff << IO_DRV_SD_DS_OFFSET)
+
+#define MIN_FREQ (400000)
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct ca_mmc_plat {
+ struct mmc_config cfg;
+ struct mmc mmc;
+};
+
+struct ca_dwmmc_priv_data {
+ struct dwmci_host host;
+ void __iomem *sd_dll_reg;
+ void __iomem *io_drv_reg;
+ u8 ds;
+};
+
+static void ca_dwmci_clksel(struct dwmci_host *host)
+{
+ struct ca_dwmmc_priv_data *priv = host->priv;
+ u32 val = readl(priv->sd_dll_reg);
+
+ if (host->bus_hz >= 200000000) {
+ val &= ~SD_CLK_SEL_MASK;
+ val |= SD_CLK_SEL_200MHZ;
+ } else if (host->bus_hz >= 100000000) {
+ val &= ~SD_CLK_SEL_MASK;
+ val |= SD_CLK_SEL_100MHZ;
+ } else {
+ val &= ~SD_CLK_SEL_MASK;
+ }
+
+ writel(val, priv->sd_dll_reg);
+}
+
+static void ca_dwmci_board_init(struct dwmci_host *host)
+{
+ struct ca_dwmmc_priv_data *priv = host->priv;
+ u32 val = readl(priv->io_drv_reg);
+
+ writel(SD_DLL_DEFAULT, priv->sd_dll_reg);
+
+ val &= ~IO_DRV_SD_DS_MASK;
+ if (priv && priv->ds)
+ val |= priv->ds << IO_DRV_SD_DS_OFFSET;
+ writel(val, priv->io_drv_reg);
+}
+
+unsigned int ca_dwmci_get_mmc_clock(struct dwmci_host *host, uint freq)
+{
+ struct ca_dwmmc_priv_data *priv = host->priv;
+ u8 sd_clk_sel = readl(priv->sd_dll_reg) & SD_CLK_SEL_MASK;
+ u8 clk_div;
+
+ switch (sd_clk_sel) {
+ case 2:
+ clk_div = 1;
+ break;
+ case 1:
+ clk_div = 2;
+ break;
+ default:
+ clk_div = 4;
+ }
+
+ return SD_SCLK_MAX / clk_div / (host->div + 1);
+}
+
+static int ca_dwmmc_ofdata_to_platdata(struct udevice *dev)
+{
+ struct ca_dwmmc_priv_data *priv = dev_get_priv(dev);
+ struct dwmci_host *host = &priv->host;
+ u32 tmp;
+
+ host->name = dev->name;
+ host->dev_index = 0;
+
+ host->buswidth = dev_read_u32_default(dev, "bus-width", 1);
+ if (host->buswidth != 1 && host->buswidth != 4)
+ return -EINVAL;
+
+ host->bus_hz = dev_read_u32_default(dev, "max-frequency", 50000000);
+ priv->ds = dev_read_u32_default(dev, "io_ds", 0x33);
+ host->fifo_mode = dev_read_bool(dev, "fifo-mode");
+
+ dev_read_u32(dev, "sd_dll_ctrl", &tmp);
+ priv->sd_dll_reg = map_sysmem((uintptr_t)tmp, sizeof(uintptr_t));
+ if (!priv->sd_dll_reg)
+ return -EINVAL;
+
+ dev_read_u32(dev, "io_drv_ctrl", &tmp);
+ priv->io_drv_reg = map_sysmem((uintptr_t)tmp, sizeof(uintptr_t));
+ if (!priv->io_drv_reg)
+ return -EINVAL;
+
+ host->ioaddr = dev_read_addr_ptr(dev);
+ if (host->ioaddr == (void *)FDT_ADDR_T_NONE) {
+ printf("DWMMC: base address is invalid\n");
+ return -EINVAL;
+ }
+
+ host->priv = priv;
+
+ return 0;
+}
+
+struct dm_mmc_ops ca_dwmci_dm_ops;
+
+static int ca_dwmmc_probe(struct udevice *dev)
+{
+ struct ca_mmc_plat *plat = dev_get_platdata(dev);
+ struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
+ struct ca_dwmmc_priv_data *priv = dev_get_priv(dev);
+ struct dwmci_host *host = &priv->host;
+
+ memcpy(&ca_dwmci_dm_ops, &dm_dwmci_ops, sizeof(struct dm_mmc_ops));
+
+ dwmci_setup_cfg(&plat->cfg, host, host->bus_hz, MIN_FREQ);
+ if (host->buswidth == 1) {
+ (&plat->cfg)->host_caps &= ~MMC_MODE_8BIT;
+ (&plat->cfg)->host_caps &= ~MMC_MODE_4BIT;
+ }
+
+ host->mmc = &plat->mmc;
+ host->mmc->priv = &priv->host;
+ upriv->mmc = host->mmc;
+ host->mmc->dev = dev;
+ host->clksel = ca_dwmci_clksel;
+ host->board_init = ca_dwmci_board_init;
+ host->get_mmc_clk = ca_dwmci_get_mmc_clock;
+
+ return dwmci_probe(dev);
+}
+
+static int ca_dwmmc_bind(struct udevice *dev)
+{
+ struct ca_mmc_plat *plat = dev_get_platdata(dev);
+
+ return dwmci_bind(dev, &plat->mmc, &plat->cfg);
+}
+
+static const struct udevice_id ca_dwmmc_ids[] = {
+ { .compatible = "snps,dw-cortina" },
+ { }
+};
+
+U_BOOT_DRIVER(ca_dwmmc_drv) = {
+ .name = "cortina_dwmmc",
+ .id = UCLASS_MMC,
+ .of_match = ca_dwmmc_ids,
+ .ofdata_to_platdata = ca_dwmmc_ofdata_to_platdata,
+ .bind = ca_dwmmc_bind,
+ .ops = &ca_dwmci_dm_ops,
+ .probe = ca_dwmmc_probe,
+ .priv_auto_alloc_size = sizeof(struct ca_dwmmc_priv_data),
+ .platdata_auto_alloc_size = sizeof(struct ca_mmc_plat),
+};
--
2.7.4
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v2 2/8] board: presidio-asic: Add eMMC board support
2020-03-20 0:57 [PATCH v2 0/8] Cortina Access Drivers Package 2 Alex Nemirovsky
2020-03-20 0:57 ` [PATCH v2 1/8] mmc: ca_dw_mmc: add DesignWare based DM support for CAxxxx SoCs Alex Nemirovsky
@ 2020-03-20 0:57 ` Alex Nemirovsky
2020-03-20 0:57 ` [PATCH v2 3/8] i2c: i2c-cortina: added CAxxxx I2C support Alex Nemirovsky
` (5 subsequent siblings)
7 siblings, 0 replies; 18+ messages in thread
From: Alex Nemirovsky @ 2020-03-20 0:57 UTC (permalink / raw)
To: u-boot
Add initial eMMC support for Cortina Access Presidio
Engineering Board
Signed-off-by: Alex Nemirovsky <alex.nemirovsky@cortina-access.com>
CC: Peng Fan <peng.fan@nxp.com>
---
Changes in v3: None
Changes in v2: None
configs/cortina_presidio-asic-emmc_defconfig | 33 ++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
create mode 100644 configs/cortina_presidio-asic-emmc_defconfig
diff --git a/configs/cortina_presidio-asic-emmc_defconfig b/configs/cortina_presidio-asic-emmc_defconfig
new file mode 100644
index 0000000..e10008a
--- /dev/null
+++ b/configs/cortina_presidio-asic-emmc_defconfig
@@ -0,0 +1,33 @@
+CONFIG_ARM=y
+# CONFIG_SYS_ARCH_TIMER is not set
+CONFIG_TARGET_PRESIDIO_ASIC=y
+CONFIG_SYS_TEXT_BASE=0x04000000
+CONFIG_ENV_SIZE=0x20000
+CONFIG_DM_GPIO=y
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_IDENT_STRING="Presidio-SoC"
+CONFIG_SHOW_BOOT_PROGRESS=y
+CONFIG_BOOTDELAY=3
+CONFIG_BOARD_EARLY_INIT_R=y
+CONFIG_SYS_PROMPT="G3#"
+CONFIG_CMD_MMC=y
+CONFIG_CMD_PART=y
+CONFIG_CMD_WDT=y
+CONFIG_CMD_CACHE=y
+CONFIG_CMD_TIMER=y
+CONFIG_CMD_SMC=y
+CONFIG_CMD_EXT2=y
+CONFIG_CMD_EXT4=y
+CONFIG_OF_CONTROL=y
+CONFIG_OF_LIVE=y
+CONFIG_DEFAULT_DEVICE_TREE="ca-presidio-engboard"
+# CONFIG_NET is not set
+CONFIG_DM=y
+CONFIG_CORTINA_GPIO=y
+CONFIG_DM_MMC=y
+CONFIG_MMC_DW=y
+CONFIG_MMC_DW_CORTINA=y
+CONFIG_DM_SERIAL=y
+CONFIG_CORTINA_UART=y
+CONFIG_WDT=y
+CONFIG_WDT_CORTINA=y
--
2.7.4
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v2 3/8] i2c: i2c-cortina: added CAxxxx I2C support
2020-03-20 0:57 [PATCH v2 0/8] Cortina Access Drivers Package 2 Alex Nemirovsky
2020-03-20 0:57 ` [PATCH v2 1/8] mmc: ca_dw_mmc: add DesignWare based DM support for CAxxxx SoCs Alex Nemirovsky
2020-03-20 0:57 ` [PATCH v2 2/8] board: presidio-asic: Add eMMC board support Alex Nemirovsky
@ 2020-03-20 0:57 ` Alex Nemirovsky
2020-03-20 6:25 ` Heiko Schocher
2020-03-20 0:57 ` [PATCH v2 4/8] board: presidio-asic: Add " Alex Nemirovsky
` (4 subsequent siblings)
7 siblings, 1 reply; 18+ messages in thread
From: Alex Nemirovsky @ 2020-03-20 0:57 UTC (permalink / raw)
To: u-boot
From: Arthur Li <arthur.li@cortina-access.com>
Add I2C controller support for Cortina Access CAxxxx SoCs
Signed-off-by: Arthur Li <arthur.li@cortina-access.com>
Signed-off-by: Alex Nemirovsky <alex.nemirovsky@cortina-access.com>
CC: Heiko Schocher <hs@denx.de>
---
Changes in v3: None
Changes in v2: None
MAINTAINERS | 4 +
drivers/i2c/Kconfig | 7 +
drivers/i2c/Makefile | 1 +
drivers/i2c/i2c-cortina.c | 346 ++++++++++++++++++++++++++++++++++++++++++++++
drivers/i2c/i2c-cortina.h | 92 ++++++++++++
5 files changed, 450 insertions(+)
create mode 100644 drivers/i2c/i2c-cortina.c
create mode 100644 drivers/i2c/i2c-cortina.h
diff --git a/MAINTAINERS b/MAINTAINERS
index bb45d3c..b147faa 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -181,6 +181,8 @@ F: drivers/gpio/cortina_gpio.c
F: drivers/watchdog/cortina_wdt.c
F: drivers/serial/serial_cortina.c
F: drivers/mmc/ca_dw_mmc.c
+F: drivers/i2c/i2c-cortina.c
+F: drivers/i2c/i2c-cortina.h
ARM/CZ.NIC TURRIS MOX SUPPORT
M: Marek Behun <marek.behun@nic.cz>
@@ -672,6 +674,8 @@ F: drivers/gpio/cortina_gpio.c
F: drivers/watchdog/cortina_wdt.c
F: drivers/serial/serial_cortina.c
F: drivers/mmc/ca_dw_mmc.c
+F: drivers/i2c/i2c-cortina.c
+F: drivers/i2c/i2c-cortina.h
MIPS MSCC
M: Gregory CLEMENT <gregory.clement@bootlin.com>
diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
index 03d2fed..b98a4aa 100644
--- a/drivers/i2c/Kconfig
+++ b/drivers/i2c/Kconfig
@@ -85,6 +85,13 @@ config SYS_I2C_CADENCE
Say yes here to select Cadence I2C Host Controller. This controller is
e.g. used by Xilinx Zynq.
+config SYS_I2C_CA
+ tristate "Cortina-Access I2C Controller"
+ depends on DM_I2C && CORTINA_PLATFORM
+ default n
+ help
+ Say yes here to select Cortina-Access I2C Host Controller.
+
config SYS_I2C_DAVINCI
bool "Davinci I2C Controller"
depends on (ARCH_KEYSTONE || ARCH_DAVINCI)
diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
index f5a471f..5d18cf7 100644
--- a/drivers/i2c/Makefile
+++ b/drivers/i2c/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_SYS_I2C) += i2c_core.o
obj-$(CONFIG_SYS_I2C_ASPEED) += ast_i2c.o
obj-$(CONFIG_SYS_I2C_AT91) += at91_i2c.o
obj-$(CONFIG_SYS_I2C_CADENCE) += i2c-cdns.o
+obj-$(CONFIG_SYS_I2C_CA) += i2c-cortina.o
obj-$(CONFIG_SYS_I2C_DAVINCI) += davinci_i2c.o
obj-$(CONFIG_SYS_I2C_DW) += designware_i2c.o
ifdef CONFIG_DM_PCI
diff --git a/drivers/i2c/i2c-cortina.c b/drivers/i2c/i2c-cortina.c
new file mode 100644
index 0000000..99c63f3
--- /dev/null
+++ b/drivers/i2c/i2c-cortina.c
@@ -0,0 +1,346 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2020
+ * Arthur Li, Cortina Access, arthur.li at cortina-access.com.
+ */
+
+#include <common.h>
+#include <i2c.h>
+#include <asm/io.h>
+#include <dm.h>
+#include <mapmem.h>
+#include "i2c-cortina.h"
+
+static void set_speed(struct i2c_regs *regs, int i2c_spd)
+{
+ union ca_biw_cfg i2c_cfg;
+
+ i2c_cfg.wrd = readl(®s->i2c_cfg);
+ i2c_cfg.bf.core_en = 0;
+ writel(i2c_cfg.wrd, ®s->i2c_cfg);
+
+ switch (i2c_spd) {
+ case IC_SPEED_MODE_MAX:
+ i2c_cfg.bf.prer =
+ CORTINA_PER_IO_FREQ / (5 * I2C_MAX_SPEED) - 1;
+ break;
+
+ case IC_SPEED_MODE_STANDARD:
+ i2c_cfg.bf.prer =
+ CORTINA_PER_IO_FREQ / (5 * I2C_STANDARD_SPEED) - 1;
+ break;
+
+ case IC_SPEED_MODE_FAST:
+ default:
+ i2c_cfg.bf.prer =
+ CORTINA_PER_IO_FREQ / (5 * I2C_FAST_SPEED) - 1;
+ break;
+ }
+
+ i2c_cfg.bf.core_en = 1;
+ writel(i2c_cfg.wrd, ®s->i2c_cfg);
+}
+
+static int ca_i2c_set_bus_speed(struct udevice *bus, unsigned int speed)
+{
+ struct ca_i2c *priv = dev_get_priv(bus);
+ int i2c_spd;
+
+ if (speed >= I2C_MAX_SPEED) {
+ i2c_spd = IC_SPEED_MODE_MAX;
+ priv->speed = I2C_MAX_SPEED;
+ } else if (speed >= I2C_FAST_SPEED) {
+ i2c_spd = IC_SPEED_MODE_FAST;
+ priv->speed = I2C_FAST_SPEED;
+ } else {
+ i2c_spd = IC_SPEED_MODE_STANDARD;
+ priv->speed = I2C_STANDARD_SPEED;
+ }
+
+ set_speed(priv->regs, i2c_spd);
+
+ return 0;
+}
+
+static int ca_i2c_get_bus_speed(struct udevice *bus)
+{
+ struct ca_i2c *priv = dev_get_priv(bus);
+
+ return priv->speed;
+}
+
+static void ca_i2c_init(struct i2c_regs *regs)
+{
+ union ca_biw_cfg i2c_cfg;
+
+ i2c_cfg.wrd = readl(®s->i2c_cfg);
+ i2c_cfg.bf.core_en = 0;
+ i2c_cfg.bf.biw_soft_reset = 1;
+ writel(i2c_cfg.wrd, ®s->i2c_cfg);
+ mdelay(10);
+ i2c_cfg.bf.biw_soft_reset = 0;
+ writel(i2c_cfg.wrd, ®s->i2c_cfg);
+
+ set_speed(regs, IC_SPEED_MODE_STANDARD);
+
+ i2c_cfg.wrd = readl(®s->i2c_cfg);
+ i2c_cfg.bf.core_en = 1;
+ writel(i2c_cfg.wrd, ®s->i2c_cfg);
+}
+
+static int i2c_wait_complete(struct i2c_regs *regs)
+{
+ union ca_biw_ctrl i2c_ctrl;
+ unsigned long start_time_bb = get_timer(0);
+
+ i2c_ctrl.wrd = readl(®s->i2c_ctrl);
+
+ while (i2c_ctrl.bf.biwdone == 0) {
+ i2c_ctrl.wrd = readl(®s->i2c_ctrl);
+
+ if (get_timer(start_time_bb) >
+ (unsigned long)(I2C_BYTE_TO_BB)) {
+ printf("%s not done!!!\n", __func__);
+ return 1;
+ }
+ }
+
+ /* Clear done bit */
+ writel(i2c_ctrl.wrd, ®s->i2c_ctrl);
+
+ return 0;
+}
+
+static void i2c_setaddress(struct i2c_regs *regs, unsigned int i2c_addr,
+ int write_read)
+{
+ writel(i2c_addr | write_read, ®s->i2c_txr);
+
+ writel(BIW_CTRL_START | BIW_CTRL_WRITE,
+ ®s->i2c_ctrl);
+
+ i2c_wait_complete(regs);
+}
+
+static int i2c_wait_for_bus_busy(struct i2c_regs *regs)
+{
+ union ca_biw_ack i2c_ack;
+ unsigned long start_time_bb = get_timer(0);
+
+ i2c_ack.wrd = readl(®s->i2c_ack);
+
+ while (i2c_ack.bf.biw_busy) {
+ i2c_ack.wrd = readl(®s->i2c_ack);
+
+ if (get_timer(start_time_bb) >
+ (unsigned long)(I2C_BYTE_TO_BB)) {
+ printf("%s: timeout!\n", __func__);
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static int i2c_xfer_init(struct i2c_regs *regs, uint8_t chip, uint addr,
+ int alen, int write_read)
+{
+ int addr_len = alen;
+
+ if (i2c_wait_for_bus_busy(regs))
+ return 1;
+ /* First cycle must write addr + offset */
+ chip = ((chip & 0x7F) << 1);
+ if (alen == 0 && write_read == I2C_CMD_RD)
+ i2c_setaddress(regs, chip, I2C_CMD_RD);
+ else
+ i2c_setaddress(regs, chip, I2C_CMD_WT);
+
+ while (alen) {
+ alen--;
+ writel(addr, ®s->i2c_txr);
+ if (write_read == I2C_CMD_RD)
+ writel(BIW_CTRL_WRITE | BIW_CTRL_STOP,
+ ®s->i2c_ctrl);
+ else
+ writel(BIW_CTRL_WRITE, ®s->i2c_ctrl);
+ i2c_wait_complete(regs);
+ }
+
+ /* Send address again with Read flag if it's read command */
+ if (write_read == I2C_CMD_RD && addr_len > 0)
+ i2c_setaddress(regs, chip, I2C_CMD_RD);
+
+ return 0;
+}
+
+static int i2c_xfer_finish(struct i2c_regs *regs)
+{
+ /* Dummy read makes bus free */
+ writel(BIW_CTRL_READ | BIW_CTRL_STOP, ®s->i2c_ctrl);
+ i2c_wait_complete(regs);
+
+ if (i2c_wait_for_bus_busy(regs)) {
+ printf("Timed out waiting for bus\n");
+ return 1;
+ }
+
+ return 0;
+}
+
+static int ca_i2c_read(struct i2c_regs *regs, uint8_t chip, uint addr,
+ int alen, uint8_t *buffer, int len)
+{
+ unsigned long start_time_rx;
+ int rc = 0;
+
+ if (i2c_xfer_init(regs, chip, addr, alen, I2C_CMD_RD))
+ return 1;
+
+ start_time_rx = get_timer(0);
+ while (len) {
+ /* ACK_IN is ack value to send during read.
+ * ack high only on the very last byte!
+ */
+ if (len == 1) {
+ writel(BIW_CTRL_READ | BIW_CTRL_ACK_IN | BIW_CTRL_STOP,
+ ®s->i2c_ctrl);
+ } else {
+ writel(BIW_CTRL_READ, ®s->i2c_ctrl);
+ }
+
+ rc = i2c_wait_complete(regs);
+ udelay(1);
+
+ if (rc == 0) {
+ *buffer++ =
+ (uchar) readl(®s->i2c_rxr);
+ len--;
+ start_time_rx = get_timer(0);
+
+ } else if (get_timer(start_time_rx) > I2C_BYTE_TO) {
+ return 1;
+ }
+ }
+ i2c_xfer_finish(regs);
+ return rc;
+}
+
+static int ca_i2c_write(struct i2c_regs *regs, uint8_t chip, uint addr,
+ int alen, uint8_t *buffer, int len)
+{
+ int rc, nb = len;
+ unsigned long start_time_tx;
+
+ if (i2c_xfer_init(regs, chip, addr, alen, I2C_CMD_WT))
+ return 1;
+
+ start_time_tx = get_timer(0);
+ while (len) {
+ writel(*buffer, ®s->i2c_txr);
+ if (len == 1) {
+ writel(BIW_CTRL_WRITE | BIW_CTRL_STOP,
+ ®s->i2c_ctrl);
+ } else {
+ writel(BIW_CTRL_WRITE, ®s->i2c_ctrl);
+ }
+
+ rc = i2c_wait_complete(regs);
+
+ if (rc == 0) {
+ len--;
+ buffer++;
+ start_time_tx = get_timer(0);
+ } else if (get_timer(start_time_tx) > (nb * I2C_BYTE_TO)) {
+ printf("Timed out. i2c write Failed\n");
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static int ca_i2c_probe_chip(struct udevice *bus, uint chip_addr,
+ uint chip_flags)
+{
+ struct ca_i2c *priv = dev_get_priv(bus);
+ int ret;
+ u32 tmp;
+
+ /* Try to read the first location of the chip */
+ ret = ca_i2c_read(priv->regs, chip_addr, 0, 1, (uchar *)&tmp, 1);
+ if (ret)
+ ca_i2c_init(priv->regs);
+
+ return ret;
+}
+
+static int ca_i2c_xfer(struct udevice *bus, struct i2c_msg *msg, int nmsgs)
+{
+ struct ca_i2c *priv = dev_get_priv(bus);
+ int ret;
+
+ debug("i2c_xfer: %d messages\n", nmsgs);
+ for (; nmsgs > 0; nmsgs--, msg++) {
+ debug("i2c_xfer: chip=0x%x, len=0x%x\n", msg->addr, msg->len);
+ if (msg->flags & I2C_M_RD) {
+ ret = ca_i2c_read(priv->regs, msg->addr, 0, 0,
+ msg->buf, msg->len);
+ } else {
+ ret = ca_i2c_write(priv->regs, msg->addr, 0, 0,
+ msg->buf, msg->len);
+ }
+
+ if (ret) {
+ debug("i2c_write: error sending\n");
+ return -EREMOTEIO;
+ }
+ }
+
+ return 0;
+}
+
+static const struct dm_i2c_ops ca_i2c_ops = {
+ .xfer = ca_i2c_xfer,
+ .probe_chip = ca_i2c_probe_chip,
+ .set_bus_speed = ca_i2c_set_bus_speed,
+ .get_bus_speed = ca_i2c_get_bus_speed,
+};
+
+static const struct udevice_id ca_i2c_ids[] = {
+ { .compatible = "cortina,ca-i2c", },
+ { }
+};
+
+static int ca_i2c_probe(struct udevice *bus)
+{
+ struct ca_i2c *priv = dev_get_priv(bus);
+
+ ca_i2c_init(priv->regs);
+
+ return 0;
+}
+
+static int ca_i2c_ofdata_to_platdata(struct udevice *bus)
+{
+ struct ca_i2c *priv = dev_get_priv(bus);
+
+ priv->regs = map_sysmem(dev_read_addr(bus), sizeof(struct i2c_regs));
+ if (!priv->regs) {
+ printf("I2C: base address is invalid\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+U_BOOT_DRIVER(i2c_cortina) = {
+ .name = "i2c_cortina",
+ .id = UCLASS_I2C,
+ .of_match = ca_i2c_ids,
+ .ofdata_to_platdata = ca_i2c_ofdata_to_platdata,
+ .probe = ca_i2c_probe,
+ .priv_auto_alloc_size = sizeof(struct ca_i2c),
+ .ops = &ca_i2c_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/i2c/i2c-cortina.h b/drivers/i2c/i2c-cortina.h
new file mode 100644
index 0000000..f1c3dc7
--- /dev/null
+++ b/drivers/i2c/i2c-cortina.h
@@ -0,0 +1,92 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2019
+ * Cortina Access, <www.cortina-access.com>
+ */
+
+#ifndef __CA_I2C_H_
+#define __CA_I2C_H_
+
+#if !defined(__ASSEMBLER__) && !defined(__ASSEMBLY__)
+struct i2c_regs {
+ u32 i2c_cfg;
+ u32 i2c_ctrl;
+ u32 i2c_txr;
+ u32 i2c_rxr;
+ u32 i2c_ack;
+ u32 i2c_ie0;
+ u32 i2c_int0;
+ u32 i2c_ie1;
+ u32 i2c_int1;
+ u32 i2c_stat;
+};
+
+union ca_biw_cfg {
+ struct biw_cfg {
+ u32 core_en : 1;
+ u32 biw_soft_reset : 1;
+ u32 busywait_en : 1;
+ u32 stretch_en : 1;
+ u32 arb_en : 1;
+ u32 clksync_en : 1;
+ u32 rsrvd1 : 2;
+ u32 spike_cnt : 4;
+ u32 rsrvd2 : 4;
+ u32 prer : 16;
+ } bf;
+ unsigned int wrd;
+};
+
+union ca_biw_ctrl {
+ struct biw_ctrl {
+ u32 biwdone : 1;
+ u32 rsrvd1 : 2;
+ u32 ack_in : 1;
+ u32 write : 1;
+ u32 read : 1;
+ u32 stop : 1;
+ u32 start : 1;
+ u32 rsrvd2 : 24;
+ } bf;
+ unsigned int wrd;
+};
+
+union ca_biw_ack {
+ struct biw_ack {
+ u32 al :1;
+ u32 biw_busy :1;
+ u32 ack_out :1;
+ u32 rsrvd1 :29;
+ } bf;
+ unsigned int wrd;
+};
+#endif /* !__ASSEMBLER__*/
+
+struct ca_i2c {
+ struct i2c_regs *regs;
+ unsigned int speed;
+};
+
+#define I2C_CMD_WT 0
+#define I2C_CMD_RD 1
+
+#define BIW_CTRL_DONE BIT(0)
+#define BIW_CTRL_ACK_IN BIT(3)
+#define BIW_CTRL_WRITE BIT(4)
+#define BIW_CTRL_READ BIT(5)
+#define BIW_CTRL_STOP BIT(6)
+#define BIW_CTRL_START BIT(7)
+
+#define I2C_BYTE_TO (CONFIG_SYS_HZ / 500)
+#define I2C_STOPDET_TO (CONFIG_SYS_HZ / 500)
+#define I2C_BYTE_TO_BB (10)
+
+#define IC_SPEED_MODE_STANDARD 1
+#define IC_SPEED_MODE_FAST 2
+#define IC_SPEED_MODE_MAX 3
+
+#define I2C_MAX_SPEED 1000000
+#define I2C_FAST_SPEED 400000
+#define I2C_STANDARD_SPEED 100000
+
+#endif /* __CA_I2C_H_ */
--
2.7.4
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v2 4/8] board: presidio-asic: Add I2C support
2020-03-20 0:57 [PATCH v2 0/8] Cortina Access Drivers Package 2 Alex Nemirovsky
` (2 preceding siblings ...)
2020-03-20 0:57 ` [PATCH v2 3/8] i2c: i2c-cortina: added CAxxxx I2C support Alex Nemirovsky
@ 2020-03-20 0:57 ` Alex Nemirovsky
2020-03-20 0:57 ` [PATCH v2 5/8] led: led_cortina: Add CAxxx LED support Alex Nemirovsky
` (3 subsequent siblings)
7 siblings, 0 replies; 18+ messages in thread
From: Alex Nemirovsky @ 2020-03-20 0:57 UTC (permalink / raw)
To: u-boot
Add I2C board support for Cortina Access Presidio Engineering Board
Signed-off-by: Alex Nemirovsky <alex.nemirovsky@cortina-access.com>
CC: Heiko Schocher <hs@denx.de>
---
Changes in v3: None
Changes in v2: None
configs/cortina_presidio-asic-emmc_defconfig | 3 +++
1 file changed, 3 insertions(+)
diff --git a/configs/cortina_presidio-asic-emmc_defconfig b/configs/cortina_presidio-asic-emmc_defconfig
index e10008a..e45e23c 100644
--- a/configs/cortina_presidio-asic-emmc_defconfig
+++ b/configs/cortina_presidio-asic-emmc_defconfig
@@ -10,6 +10,7 @@ CONFIG_SHOW_BOOT_PROGRESS=y
CONFIG_BOOTDELAY=3
CONFIG_BOARD_EARLY_INIT_R=y
CONFIG_SYS_PROMPT="G3#"
+CONFIG_CMD_I2C=y
CONFIG_CMD_MMC=y
CONFIG_CMD_PART=y
CONFIG_CMD_WDT=y
@@ -24,6 +25,8 @@ CONFIG_DEFAULT_DEVICE_TREE="ca-presidio-engboard"
# CONFIG_NET is not set
CONFIG_DM=y
CONFIG_CORTINA_GPIO=y
+CONFIG_DM_I2C=y
+CONFIG_SYS_I2C_CA=y
CONFIG_DM_MMC=y
CONFIG_MMC_DW=y
CONFIG_MMC_DW_CORTINA=y
--
2.7.4
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v2 5/8] led: led_cortina: Add CAxxx LED support
2020-03-20 0:57 [PATCH v2 0/8] Cortina Access Drivers Package 2 Alex Nemirovsky
` (3 preceding siblings ...)
2020-03-20 0:57 ` [PATCH v2 4/8] board: presidio-asic: Add " Alex Nemirovsky
@ 2020-03-20 0:57 ` Alex Nemirovsky
2020-03-23 15:37 ` Simon Glass
2020-03-20 0:57 ` [PATCH v2 6/8] board: presidio: add " Alex Nemirovsky
` (2 subsequent siblings)
7 siblings, 1 reply; 18+ messages in thread
From: Alex Nemirovsky @ 2020-03-20 0:57 UTC (permalink / raw)
To: u-boot
From: Jway Lin <jway.lin@cortina-access.com>
Add Cortina Access LED controller support for CAxxxx SOCs
Signed-off-by: Jway Lin <jway.lin@cortina-access.com>
Signed-off-by: Alex Nemirovsky <alex.nemirovsky@cortina-access.com>
CC: Simon Glass <sjg@chromium.org>
---
Changes in v3: None
Changes in v2: None
MAINTAINERS | 2 +
drivers/led/Kconfig | 8 ++
drivers/led/Makefile | 1 +
drivers/led/led_cortina.c | 308 ++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 319 insertions(+)
create mode 100644 drivers/led/led_cortina.c
diff --git a/MAINTAINERS b/MAINTAINERS
index b147faa..24a2655 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -183,6 +183,7 @@ F: drivers/serial/serial_cortina.c
F: drivers/mmc/ca_dw_mmc.c
F: drivers/i2c/i2c-cortina.c
F: drivers/i2c/i2c-cortina.h
+F: drivers/led/led_cortina.c
ARM/CZ.NIC TURRIS MOX SUPPORT
M: Marek Behun <marek.behun@nic.cz>
@@ -676,6 +677,7 @@ F: drivers/serial/serial_cortina.c
F: drivers/mmc/ca_dw_mmc.c
F: drivers/i2c/i2c-cortina.c
F: drivers/i2c/i2c-cortina.h
+F: drivers/led/led_cortina.c
MIPS MSCC
M: Gregory CLEMENT <gregory.clement@bootlin.com>
diff --git a/drivers/led/Kconfig b/drivers/led/Kconfig
index 6675934..cc87fbf 100644
--- a/drivers/led/Kconfig
+++ b/drivers/led/Kconfig
@@ -35,6 +35,14 @@ config LED_BCM6858
This option enables support for LEDs connected to the BCM6858
HW has blinking capabilities and up to 32 LEDs can be controlled.
+config LED_CORTINA
+ bool "LED Support for Cortina Access CAxxxx SoCs"
+ depends on LED && (CORTINA_PLATFORM)
+ help
+ This option enables support for LEDs connected to the Cortina
+ Access CAxxxx SOCs.
+
+
config LED_BLINK
bool "Support LED blinking"
depends on LED
diff --git a/drivers/led/Makefile b/drivers/led/Makefile
index 3654dd3..8e3ae7f 100644
--- a/drivers/led/Makefile
+++ b/drivers/led/Makefile
@@ -8,3 +8,4 @@ obj-$(CONFIG_LED_BCM6328) += led_bcm6328.o
obj-$(CONFIG_LED_BCM6358) += led_bcm6358.o
obj-$(CONFIG_LED_BCM6858) += led_bcm6858.o
obj-$(CONFIG_$(SPL_)LED_GPIO) += led_gpio.o
+obj-$(CONFIG_LED_CORTINA) += led_cortina.o
diff --git a/drivers/led/led_cortina.c b/drivers/led/led_cortina.c
new file mode 100644
index 0000000..53435e8
--- /dev/null
+++ b/drivers/led/led_cortina.c
@@ -0,0 +1,308 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/*
+ * Copyright (C) 2020 Cortina-Access
+ * Author: Jway Lin <jway.lin@cortina-access.com>
+ *
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <led.h>
+#include <asm/io.h>
+#include <dm/lists.h>
+#include <linux/compat.h>
+
+#define CORTINA_LED_NUM 16
+
+#define BIT(nr) (1UL << (nr))
+
+#define cortina_LED_CONTROL 0x00
+#define cortina_LED_CONFIG_0 0x04
+#define cortina_LED_CONFIG_1 0x08
+#define cortina_LED_CONFIG_2 0x0c
+#define cortina_LED_CONFIG_3 0x10
+#define cortina_LED_CONFIG_4 0x14
+#define cortina_LED_CONFIG_5 0x18
+#define cortina_LED_CONFIG_6 0x1c
+#define cortina_LED_CONFIG_7 0x20
+#define cortina_LED_CONFIG_8 0x24
+#define cortina_LED_CONFIG_9 0x28
+#define cortina_LED_CONFIG_10 0x2c
+#define cortina_LED_CONFIG_11 0x30
+#define cortina_LED_CONFIG_12 0x34
+#define cortina_LED_CONFIG_13 0x38
+#define cortina_LED_CONFIG_14 0x3c
+#define cortina_LED_CONFIG_15 0x40
+
+#define cortina_LED_MAX_HW_BLINK 127
+#define cortina_LED_MAX_COUNT CORTINA_LED_NUM
+#define cortina_LED_MAX_PORT 8
+
+/* LED_CONTROL fields */
+#define cortina_LED_BLINK_RATE1_OFFSET 0
+#define cortina_LED_BLINK_RATE1_MASK 0xFF
+#define cortina_LED_BLINK_RATE2_OFFSET 8
+#define cortina_LED_BLINK_RATE2_MASK 0xFF
+#define cortina_LED_CLK_TEST BIT(16)
+#define cortina_LED_CLK_POLARITY BIT(17)
+#define cortina_LED_CLK_TEST_MODE BIT(16)
+#define cortina_LED_CLK_TEST_RX_TEST BIT(30)
+#define cortina_LED_CLK_TEST_TX_TEST BIT(31)
+
+/* LED_CONFIG fields */
+#define cortina_LED_EVENT_ON_OFFSET 0
+#define cortina_LED_EVENT_ON_MASK 0x7
+#define cortina_LED_EVENT_BLINK_OFFSET 3
+#define cortina_LED_EVENT_BLINK_MASK 0x7
+#define cortina_LED_EVENT_OFF_OFFSET 6
+#define cortina_LED_EVENT_OFF_MASK 0x7
+#define cortina_LED_OFF_ON_OFFSET 9
+#define cortina_LED_OFF_ON_MASK 0x3
+#define cortina_LED_PORT_OFFSET 11
+#define cortina_LED_PORT_MASK 0x7
+#define cortina_LED_OFF_VAL BIT(14)
+#define cortina_LED_SW_EVENT BIT(15)
+#define cortina_LED_BLINK_SEL BIT(16)
+
+struct cortina_led_cfg {
+ void __iomem *regs;
+ spinlock_t *lock; /* protect LED resource access */
+ int idx;
+ bool active_low;
+
+ int off_event;
+ int blink_event;
+ int on_event;
+ int port;
+ int blink;
+ int enable;
+};
+
+struct cortina_led_top_cfg {
+ void __iomem *regs;
+ u16 blink_rate1;
+ u16 blink_rate2;
+};
+
+static struct cortina_led_top_cfg glb_led_ctrl;
+
+static void cortina_led_write(void __iomem *reg, unsigned long data)
+{
+ writel(data, reg);
+}
+
+static unsigned long cortina_led_read(void __iomem *reg)
+{
+ return readl(reg);
+}
+
+static enum led_state_t cortina_led_get_state(struct udevice *dev)
+{
+ struct cortina_led_cfg *priv = dev_get_priv(dev);
+ enum led_state_t state = LEDST_OFF;
+ u32 val;
+
+ val = readl(priv->regs);
+
+ if (val & cortina_LED_SW_EVENT)
+ state = LEDST_ON;
+
+ return state;
+}
+
+static int cortina_led_set_state(struct udevice *dev, enum led_state_t state)
+{
+ u32 val;
+ struct cortina_led_cfg *priv = dev_get_priv(dev);
+
+ val = readl(priv->regs);
+
+ switch (state) {
+ case LEDST_OFF:
+ val &= ~cortina_LED_SW_EVENT;
+ val &= ~(cortina_LED_OFF_ON_MASK << cortina_LED_OFF_ON_OFFSET);
+ val |= 0x3 << cortina_LED_OFF_ON_OFFSET;
+ cortina_led_write(priv->regs, val);
+ break;
+ case LEDST_ON:
+ val |= cortina_LED_SW_EVENT;
+ val &= ~(cortina_LED_OFF_ON_MASK << cortina_LED_OFF_ON_OFFSET);
+ val |= 0x1 << cortina_LED_OFF_ON_OFFSET;
+ cortina_led_write(priv->regs, val);
+ break;
+ case LEDST_TOGGLE:
+ if (cortina_led_get_state(dev) == LEDST_OFF)
+ return cortina_led_set_state(dev, LEDST_ON);
+ else
+ return cortina_led_set_state(dev, LEDST_OFF);
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static const struct led_ops cortina_led_ops = {
+ .get_state = cortina_led_get_state,
+ .set_state = cortina_led_set_state,
+};
+
+static int cortina_led_probe(struct udevice *dev)
+{
+ struct led_uc_plat *uc_plat = dev_get_uclass_platdata(dev);
+ void __iomem *regs;
+ u32 reg_value, val;
+ u16 rate1, rate2;
+ struct cortina_led_cfg *priv = dev_get_priv(dev);
+ unsigned int pin;
+ u32 blink, port, off_event, blink_event, on_event;
+
+ /* Top-level LED node */
+ if (!uc_plat->label) {
+ regs = dev_remap_addr(dev);
+
+ if (!regs)
+ return -EINVAL;
+
+ glb_led_ctrl.regs = regs;
+
+ reg_value = 0;
+ reg_value |= cortina_LED_CLK_POLARITY;
+
+ rate1 = dev_read_u32_default(dev, "cortina, blink_rate1", 256);
+ rate2 = dev_read_u32_default(dev, "cortina, blink_rate2", 512);
+
+ val = rate1 / 16 - 1;
+ glb_led_ctrl.blink_rate1 = val > cortina_LED_MAX_HW_BLINK ?
+ cortina_LED_MAX_HW_BLINK : val;
+ reg_value |= (glb_led_ctrl.blink_rate1 & cortina_LED_BLINK_RATE1_MASK)
+ << cortina_LED_BLINK_RATE1_OFFSET;
+
+ val = rate2 / 16 - 1;
+ glb_led_ctrl.blink_rate2 = val > cortina_LED_MAX_HW_BLINK ?
+ cortina_LED_MAX_HW_BLINK : val;
+ reg_value |= (glb_led_ctrl.blink_rate2 & cortina_LED_BLINK_RATE2_MASK)
+ << cortina_LED_BLINK_RATE2_OFFSET;
+
+ cortina_led_write(glb_led_ctrl.regs, reg_value);
+ } else {
+ regs = dev_remap_addr(dev_get_parent(dev));
+
+ if (!regs)
+ return -EINVAL;
+
+ pin = dev_read_u32_default(dev, "pin", cortina_LED_MAX_COUNT);
+
+ if (pin >= cortina_LED_MAX_COUNT)
+ return -EINVAL;
+
+ priv->regs = regs + 4 + (pin * 4);
+
+ val = cortina_led_read(priv->regs);
+
+ if (dev_read_bool(dev, "active-low")) {
+ priv->active_low = true;
+ val |= cortina_LED_OFF_VAL;
+ } else {
+ priv->active_low = false;
+ val &= ~cortina_LED_OFF_VAL;
+ }
+
+ blink = dev_read_u32_default(dev, "blink-sel", 0);
+
+ if (blink == 0) {
+ priv->blink = 0;
+ val &= ~cortina_LED_BLINK_SEL;
+ } else if (blink == 1) {
+ priv->blink = 1;
+ val |= cortina_LED_BLINK_SEL;
+ }
+
+ //Todo : cortina_led_config();
+ off_event = dev_read_u32_default(dev, "off-event", 3);
+ val &= ~(cortina_LED_EVENT_OFF_MASK << cortina_LED_EVENT_OFF_OFFSET);
+ if (off_event != 3) {
+ priv->off_event = off_event;
+ val |= BIT(off_event) << cortina_LED_EVENT_OFF_OFFSET;
+ }
+
+ blink_event = dev_read_u32_default(dev, "blink-event", 3);
+ val &= ~(cortina_LED_EVENT_BLINK_MASK <<
+ cortina_LED_EVENT_BLINK_OFFSET);
+
+ if (blink_event != 3) {
+ priv->blink_event = blink_event;
+ val |= BIT(blink_event) << cortina_LED_EVENT_BLINK_OFFSET;
+ }
+
+ on_event = dev_read_u32_default(dev, "on-event", 3);
+ val &= ~(cortina_LED_EVENT_ON_MASK << cortina_LED_EVENT_ON_OFFSET);
+ if (on_event != 3) {
+ priv->on_event = on_event;
+ val |= BIT(on_event) << cortina_LED_EVENT_ON_OFFSET;
+ }
+
+ port = dev_read_u32_default(dev, "port", 0);
+ priv->port = port;
+ val &= ~(cortina_LED_PORT_MASK << cortina_LED_PORT_OFFSET);
+ val |= port << cortina_LED_PORT_OFFSET;
+
+ priv->enable = 0;
+
+ /* force off */
+ val &= ~(cortina_LED_OFF_ON_MASK << cortina_LED_OFF_ON_OFFSET);
+ val |= 0x3 << cortina_LED_OFF_ON_OFFSET;
+
+ cortina_led_write(priv->regs, val);
+ }
+
+ return 0;
+}
+
+static int cortina_led_bind(struct udevice *parent)
+{
+ ofnode node;
+
+ dev_for_each_subnode(node, parent) {
+ struct led_uc_plat *uc_plat;
+ struct udevice *dev;
+ const char *label;
+ int ret;
+
+ label = ofnode_read_string(node, "label");
+ if (!label) {
+ debug("%s: node %s has no label\n", __func__,
+ ofnode_get_name(node));
+ return -EINVAL;
+ }
+
+ ret = device_bind_driver_to_node(parent, "ca-leds",
+ ofnode_get_name(node),
+ node, &dev);
+ if (ret)
+ return ret;
+ uc_plat = dev_get_uclass_platdata(dev);
+ uc_plat->label = label;
+ }
+
+ return 0;
+}
+
+static const struct udevice_id ca_led_ids[] = {
+ { .compatible = "cortina,ca-leds" },
+ { /* sentinel */ }
+};
+
+U_BOOT_DRIVER(cortina_led) = {
+ .name = "ca-leds",
+ .id = UCLASS_LED,
+ .of_match = ca_led_ids,
+ .bind = cortina_led_bind,
+ .probe = cortina_led_probe,
+ .priv_auto_alloc_size = sizeof(struct cortina_led_cfg),
+ .ops = &cortina_led_ops,
+};
--
2.7.4
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v2 6/8] board: presidio: add LED support
2020-03-20 0:57 [PATCH v2 0/8] Cortina Access Drivers Package 2 Alex Nemirovsky
` (4 preceding siblings ...)
2020-03-20 0:57 ` [PATCH v2 5/8] led: led_cortina: Add CAxxx LED support Alex Nemirovsky
@ 2020-03-20 0:57 ` Alex Nemirovsky
2020-03-23 15:37 ` Simon Glass
2020-03-20 0:57 ` [PATCH v2 7/8] spi: ca_sflash: Add CAxxxx SPI Flash Controller Alex Nemirovsky
2020-03-20 0:57 ` [PATCH v2 8/8] board: presidio-asic: Add SPI NAND and NOR support Alex Nemirovsky
7 siblings, 1 reply; 18+ messages in thread
From: Alex Nemirovsky @ 2020-03-20 0:57 UTC (permalink / raw)
To: u-boot
From: Jway Lin <jway.lin@cortina-access.com>
Add LED support for Cortina Access Presidio Engineering Board
Signed-off-by: Jway Lin <jway.lin@cortina-access.com>
Signed-off-by: Alex Nemirovsky <alex.nemirovsky@cortina-access.com>
CC: Simon Glass <sjg@chromium.org>
---
Changes in v3: None
Changes in v2: None
arch/arm/dts/ca-presidio-engboard.dts | 31 ++++++++++++++++++++++++++++
configs/cortina_presidio-asic-emmc_defconfig | 2 ++
2 files changed, 33 insertions(+)
diff --git a/arch/arm/dts/ca-presidio-engboard.dts b/arch/arm/dts/ca-presidio-engboard.dts
index c03dacc..ae897e8 100644
--- a/arch/arm/dts/ca-presidio-engboard.dts
+++ b/arch/arm/dts/ca-presidio-engboard.dts
@@ -66,4 +66,35 @@
spi-max-frequency = <108000000>;
};
};
+
+ leds: led-controller at f43200f0 {
+ compatible = "cortina,ca-leds";
+ reg = <0x0 0xf43200f0 0x40>;
+
+ cortina,blink_rate1 = <256>;
+ cortina,blink_rate2 = <512>;
+
+ led at 0 {
+ pin = <0>;
+ active-low;
+ blink-sel =<0>;
+ port = <0>;
+ off-event = <0>;
+ label = "led0";
+ };
+
+ led at 1 {
+ pin = <1>;
+ active-low;
+ blink-sel =<1>;
+ label = "led1";
+ };
+
+ led at 2 {
+ pin = <2>;
+ active-low;
+ label = "led2";
+ };
+
+ };
};
diff --git a/configs/cortina_presidio-asic-emmc_defconfig b/configs/cortina_presidio-asic-emmc_defconfig
index e45e23c..3c6bd6b 100644
--- a/configs/cortina_presidio-asic-emmc_defconfig
+++ b/configs/cortina_presidio-asic-emmc_defconfig
@@ -27,6 +27,8 @@ CONFIG_DM=y
CONFIG_CORTINA_GPIO=y
CONFIG_DM_I2C=y
CONFIG_SYS_I2C_CA=y
+CONFIG_LED=y
+CONFIG_LED_CORTINA=y
CONFIG_DM_MMC=y
CONFIG_MMC_DW=y
CONFIG_MMC_DW_CORTINA=y
--
2.7.4
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v2 7/8] spi: ca_sflash: Add CAxxxx SPI Flash Controller
2020-03-20 0:57 [PATCH v2 0/8] Cortina Access Drivers Package 2 Alex Nemirovsky
` (5 preceding siblings ...)
2020-03-20 0:57 ` [PATCH v2 6/8] board: presidio: add " Alex Nemirovsky
@ 2020-03-20 0:57 ` Alex Nemirovsky
2020-03-20 0:57 ` [PATCH v2 8/8] board: presidio-asic: Add SPI NAND and NOR support Alex Nemirovsky
7 siblings, 0 replies; 18+ messages in thread
From: Alex Nemirovsky @ 2020-03-20 0:57 UTC (permalink / raw)
To: u-boot
From: Pengpeng Chen <pengpeng.chen@cortina-access.com>
Add SPI Flash controller driver for Cortina Access
CAxxxx SoCs
Signed-off-by: Pengpeng Chen <pengpeng.chen@cortina-access.com>
Signed-off-by: Alex Nemirovsky <alex.nemirovsky@cortina-access.com>
CC: Jagan Teki <jagan@amarulasolutions.com>
---
Changes in v3:
- Fixup syntax issues related to checkpatch.pl cleanup
Changes in v2: None
MAINTAINERS | 2 +
drivers/spi/Kconfig | 8 +
drivers/spi/Makefile | 1 +
drivers/spi/ca_sflash.c | 576 ++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 587 insertions(+)
create mode 100644 drivers/spi/ca_sflash.c
diff --git a/MAINTAINERS b/MAINTAINERS
index 24a2655..8509779 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -184,6 +184,7 @@ F: drivers/mmc/ca_dw_mmc.c
F: drivers/i2c/i2c-cortina.c
F: drivers/i2c/i2c-cortina.h
F: drivers/led/led_cortina.c
+F: drivers/spi/ca_sflash.c
ARM/CZ.NIC TURRIS MOX SUPPORT
M: Marek Behun <marek.behun@nic.cz>
@@ -678,6 +679,7 @@ F: drivers/mmc/ca_dw_mmc.c
F: drivers/i2c/i2c-cortina.c
F: drivers/i2c/i2c-cortina.h
F: drivers/led/led_cortina.c
+F: drivers/spi/ca_sflash.c
MIPS MSCC
M: Gregory CLEMENT <gregory.clement@bootlin.com>
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 4166c61..8a244f1 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -106,6 +106,14 @@ config BCMSTB_SPI
be used to access the SPI flash on platforms embedding this
Broadcom SPI core.
+config CORTINA_SFLASH
+ bool "Cortina-Access Serial Flash controller driver"
+ depends on DM_SPI && SPI_MEM
+ help
+ Enable the Cortina-Access Serial Flash controller driver. This driver
+ can be used to access the SPI NOR/NAND flash on platforms embedding this
+ Cortina-Access IP core.
+
config CADENCE_QSPI
bool "Cadence QSPI driver"
help
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 52462e1..32b98b4 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -25,6 +25,7 @@ obj-$(CONFIG_BCM63XX_SPI) += bcm63xx_spi.o
obj-$(CONFIG_BCMSTB_SPI) += bcmstb_spi.o
obj-$(CONFIG_CADENCE_QSPI) += cadence_qspi.o cadence_qspi_apb.o
obj-$(CONFIG_CF_SPI) += cf_spi.o
+obj-$(CONFIG_CORTINA_SFLASH) += ca_sflash.o
obj-$(CONFIG_DAVINCI_SPI) += davinci_spi.o
obj-$(CONFIG_DESIGNWARE_SPI) += designware_spi.o
obj-$(CONFIG_EXYNOS_SPI) += exynos_spi.o
diff --git a/drivers/spi/ca_sflash.c b/drivers/spi/ca_sflash.c
new file mode 100644
index 0000000..0709650
--- /dev/null
+++ b/drivers/spi/ca_sflash.c
@@ -0,0 +1,576 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Driver for Cortina SPI-FLASH Controller
+ *
+ * Copyright (C) 2020 Cortina Access Inc. All Rights Reserved.
+ *
+ * Author: PengPeng Chen <pengpeng.chen@cortina-access.com>
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <clk.h>
+#include <dm.h>
+#include <errno.h>
+#include <fdtdec.h>
+#include <linux/compat.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/ioport.h>
+#include <linux/sizes.h>
+#include <spi.h>
+#include <spi-mem.h>
+#include <reset.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct ca_sflash_regs {
+ u32 idr; /* 0x00:Flash word ID Register */
+ u32 tc; /* 0x04:Flash Timeout Counter Register */
+ u32 sr; /* 0x08:Flash Status Register */
+ u32 tr; /* 0x0C:Flash Type Register */
+ u32 asr; /* 0x10:Flash ACCESS START/BUSY Register */
+ u32 isr; /* 0x14:Flash Interrupt Status Register */
+ u32 imr; /* 0x18:Flash Interrupt Mask Register */
+ u32 fcr; /* 0x1C:NAND Flash FIFO Control Register */
+ u32 ffsr; /* 0x20:Flash FIFO Status Register */
+ u32 ffar; /* 0x24:Flash FIFO ADDRESS Register */
+ u32 ffmar; /* 0x28:Flash FIFO MATCHING ADDRESS Register */
+ u32 ffdr; /* 0x2C:Flash FIFO Data Register */
+ u32 ar; /* 0x30:Serial Flash Access Register */
+ u32 ear; /* 0x34:Serial Flash Extend Access Register */
+ u32 adr; /* 0x38:Serial Flash ADdress Register */
+ u32 dr; /* 0x3C:Serial Flash Data Register */
+ u32 tmr; /* 0x40:Serial Flash Timing Register */
+};
+
+/*
+ * FLASH_TYPE
+ */
+#define CA_FLASH_TR_PIN BIT(15)
+#define CA_FLASH_TR_TYPE_MASK GENMASK(14, 12)
+#define CA_FLASH_TR_TYPE(tp) (((tp) << 12) & CA_FLASH_TR_TYPE_MASK)
+#define CA_FLASH_TR_WIDTH BIT(11)
+#define CA_FLASH_TR_SIZE_MASK GENMASK(10, 9)
+#define CA_FLASH_TR_SIZE(sz) (((sz) << 9) & CA_FLASH_TR_SIZE_MASK)
+
+/*
+ * FLASH_FLASH_ACCESS_START
+ */
+#define CA_FLASH_ASR_IND_START_EN BIT(1)
+#define CA_FLASH_ASR_DMA_START_EN BIT(3)
+#define CA_FLASH_ASR_WR_ACCESS_EN BIT(9)
+
+/*
+ * FLASH_FLASH_INTERRUPT
+ */
+#define CA_FLASH_ISR_REG_IRQ BIT(1)
+#define CA_FLASH_ISR_FIFO_IRQ BIT(2)
+
+/*
+ * FLASH_SF_ACCESS
+ */
+#define CA_SF_AR_OPCODE_MASK GENMASK(7, 0)
+#define CA_SF_AR_OPCODE(op) ((op) << 0 & CA_SF_AR_OPCODE_MASK)
+#define CA_SF_AR_ACCODE_MASK GENMASK(11, 8)
+#define CA_SF_AR_ACCODE(ac) (((ac) << 8) & CA_SF_AR_ACCODE_MASK)
+#define CA_SF_AR_FORCE_TERM BIT(12)
+#define CA_SF_AR_FORCE_BURST BIT(13)
+#define CA_SF_AR_AUTO_MODE_EN BIT(15)
+#define CA_SF_AR_CHIP_EN_ALT BIT(16)
+#define CA_SF_AR_HI_SPEED_RD BIT(17)
+#define CA_SF_AR_MIO_INF_DC BIT(24)
+#define CA_SF_AR_MIO_INF_AC BIT(25)
+#define CA_SF_AR_MIO_INF_CC BIT(26)
+#define CA_SF_AR_DDR_MASK GENMASK(29, 28)
+#define CA_SF_AR_DDR(ddr) (((ddr) << 28) & CA_SF_AR_DDR_MASK)
+#define CA_SF_AR_MIO_INF_MASK GENMASK(31, 30)
+#define CA_SF_AR_MIO_INF(io) (((io) << 30) & CA_SF_AR_MIO_INF_MASK)
+
+/*
+ * FLASH_SF_EXT_ACCESS
+ */
+#define CA_SF_EAR_OPCODE_MASK GENMASK(7, 0)
+#define CA_SF_EAR_OPCODE(op) (((op) << 0) & CA_SF_EAR_OPCODE_MASK)
+#define CA_SF_EAR_DATA_CNT_MASK GENMASK(20, 8)
+#define CA_SF_EAR_DATA_CNT(cnt) (((cnt) << 8) & CA_SF_EAR_DATA_CNT_MASK)
+#define CA_SF_EAR_DATA_CNT_MAX (4096)
+#define CA_SF_EAR_ADDR_CNT_MASK GENMASK(23, 21)
+#define CA_SF_EAR_ADDR_CNT(cnt) (((cnt) << 21) & CA_SF_EAR_ADDR_CNT_MASK)
+#define CA_SF_EAR_ADDR_CNT_MAX (5)
+#define CA_SF_EAR_DUMY_CNT_MASK GENMASK(29, 24)
+#define CA_SF_EAR_DUMY_CNT(cnt) (((cnt) << 24) & CA_SF_EAR_DUMY_CNT_MASK)
+#define CA_SF_EAR_DUMY_CNT_MAX (32)
+#define CA_SF_EAR_DRD_CMD_EN BIT(31)
+
+/*
+ * FLASH_SF_ADDRESS
+ */
+#define CA_SF_ADR_REG_MASK GENMASK(31, 0)
+#define CA_SF_ADR_REG(addr) (((addr) << 0) & CA_SF_ADR_REG_MASK)
+
+/*
+ * FLASH_SF_DATA
+ */
+#define CA_SF_DR_REG_MASK GENMASK(31, 0)
+#define CA_SF_DR_REG(addr) (((addr) << 0) & CA_SF_DR_REG_MASK)
+
+/*
+ * FLASH_SF_TIMING
+ */
+#define CA_SF_TMR_IDLE_MASK GENMASK(7, 0)
+#define CA_SF_TMR_IDLE(idle) (((idle) << 0) & CA_SF_TMR_IDLE_MASK)
+#define CA_SF_TMR_HOLD_MASK GENMASK(15, 8)
+#define CA_SF_TMR_HOLD(hold) (((hold) << 8) & CA_SF_TMR_HOLD_MASK)
+#define CA_SF_TMR_SETUP_MASK GENMASK(23, 16)
+#define CA_SF_TMR_SETUP(setup) (((setup) << 16) & CA_SF_TMR_SETUP_MASK)
+#define CA_SF_TMR_CLK_MASK GENMASK(26, 24)
+#define CA_SF_TMR_CLK(clk) (((clk) << 24) & CA_SF_TMR_CLK_MASK)
+
+#define CA_SFLASH_IND_WRITE 0
+#define CA_SFLASH_IND_READ 1
+#define CA_SFLASH_MEM_MAP 3
+#define CA_SFLASH_FIFO_TIMEOUT_US 30000
+#define CA_SFLASH_BUSY_TIMEOUT_US 40000
+
+#define CA_SF_AC_OPCODE 0x00
+#define CA_SF_AC_OPCODE_1_DATA 0x01
+#define CA_SF_AC_OPCODE_2_DATA 0x02
+#define CA_SF_AC_OPCODE_3_DATA 0x03
+#define CA_SF_AC_OPCODE_4_DATA 0x04
+#define CA_SF_AC_OPCODE_3_ADDR 0x05
+#define CA_SF_AC_OPCODE_4_ADDR (CA_SF_AC_OPCODE_3_ADDR)
+#define CA_SF_AC_OPCODE_3_ADDR_1_DATA 0x06
+#define CA_SF_AC_OPCODE_4_ADDR_1_DATA (CA_SF_AC_OPCODE_3_ADDR_1_DATA << 2)
+#define CA_SF_AC_OPCODE_3_ADDR_2_DATA 0x07
+#define CA_SF_AC_OPCODE_4_ADDR_2_DATA (CA_SF_AC_OPCODE_3_ADDR_2_DATA << 2)
+#define CA_SF_AC_OPCODE_3_ADDR_3_DATA 0x08
+#define CA_SF_AC_OPCODE_4_ADDR_3_DATA (CA_SF_AC_OPCODE_3_ADDR_3_DATA << 2)
+#define CA_SF_AC_OPCODE_3_ADDR_4_DATA 0x09
+#define CA_SF_AC_OPCODE_4_ADDR_4_DATA (CA_SF_AC_OPCODE_3_ADDR_4_DATA << 2)
+#define CA_SF_AC_OPCODE_3_ADDR_X_1_DATA 0x0A
+#define CA_SF_AC_OPCODE_4_ADDR_X_1_DATA (CA_SF_AC_OPCODE_3_ADDR_X_1_DATA << 2)
+#define CA_SF_AC_OPCODE_3_ADDR_X_2_DATA 0x0B
+#define CA_SF_AC_OPCODE_4_ADDR_X_2_DATA (CA_SF_AC_OPCODE_3_ADDR_X_2_DATA << 2)
+#define CA_SF_AC_OPCODE_3_ADDR_X_3_DATA 0x0C
+#define CA_SF_AC_OPCODE_4_ADDR_X_3_DATA (CA_SF_AC_OPCODE_3_ADDR_X_3_DATA << 2)
+#define CA_SF_AC_OPCODE_3_ADDR_X_4_DATA 0x0D
+#define CA_SF_AC_OPCODE_4_ADDR_X_4_DATA (CA_SF_AC_OPCODE_3_ADDR_X_4_DATA << 2)
+#define CA_SF_AC_OPCODE_3_ADDR_4X_1_DATA 0x0E
+#define CA_SF_AC_OPCODE_4_ADDR_4X_1_DATA (CA_SF_AC_OPCODE_3_ADDR_4X_1_DATA << 2)
+#define CA_SF_AC_OPCODE_EXTEND 0x0F
+
+#define CA_SF_ACCESS_MIO_SINGLE 0
+#define CA_SF_ACCESS_MIO_DUAL 1
+#define CA_SF_ACCESS_MIO_QUARD 2
+
+enum access_type {
+ RD_ACCESS,
+ WR_ACCESS,
+};
+
+struct ca_sflash_priv {
+ struct ca_sflash_regs *regs;
+ u8 rx_width;
+ u8 tx_width;
+};
+
+/*
+ * This function doesn't do anything except help with debugging
+ */
+static int ca_sflash_claim_bus(struct udevice *dev)
+{
+ debug("%s:\n", __func__);
+ return 0;
+}
+
+static int ca_sflash_release_bus(struct udevice *dev)
+{
+ debug("%s:\n", __func__);
+ return 0;
+}
+
+static int ca_sflash_set_speed(struct udevice *dev, uint speed)
+{
+ debug("%s:\n", __func__);
+ return 0;
+}
+
+static int ca_sflash_set_mode(struct udevice *dev, uint mode)
+{
+ struct ca_sflash_priv *priv = dev_get_priv(dev);
+
+ if (mode & SPI_RX_QUAD)
+ priv->rx_width = 4;
+ else if (mode & SPI_RX_DUAL)
+ priv->rx_width = 2;
+ else
+ priv->rx_width = 1;
+
+ if (mode & SPI_TX_QUAD)
+ priv->tx_width = 4;
+ else if (mode & SPI_TX_DUAL)
+ priv->tx_width = 2;
+ else
+ priv->tx_width = 1;
+
+ debug("%s: mode=%d, rx_width=%d, tx_width=%d\n",
+ __func__, mode, priv->rx_width, priv->tx_width);
+
+ return 0;
+}
+
+static int _ca_sflash_wait_for_not_busy(struct ca_sflash_priv *priv)
+{
+ u32 asr;
+
+ if (readl_poll_timeout(&priv->regs->asr, asr,
+ !(asr & CA_FLASH_ASR_IND_START_EN),
+ CA_SFLASH_BUSY_TIMEOUT_US)) {
+ pr_err("busy timeout (stat:%#x)\n", asr);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int _ca_sflash_wait_cmd(struct ca_sflash_priv *priv,
+ enum access_type type)
+{
+ if (type == WR_ACCESS) {
+ /* Enable write access and start the sflash indirect access */
+ clrsetbits_le32(&priv->regs->asr, GENMASK(31, 0),
+ CA_FLASH_ASR_WR_ACCESS_EN
+ | CA_FLASH_ASR_IND_START_EN);
+ } else if (type == RD_ACCESS) {
+ /* Start the sflash indirect access */
+ clrsetbits_le32(&priv->regs->asr, GENMASK(31, 0),
+ CA_FLASH_ASR_IND_START_EN);
+ } else {
+ printf("%s: !error access type.\n", __func__);
+ return -1;
+ }
+
+ /* Wait til the action(rd/wr) completed */
+ return _ca_sflash_wait_for_not_busy(priv);
+}
+
+static int _ca_sflash_read(struct ca_sflash_priv *priv,
+ u8 *buf, unsigned int data_len)
+{
+ u32 reg_data;
+ int len;
+
+ len = data_len;
+ while (len >= 4) {
+ if (_ca_sflash_wait_cmd(priv, RD_ACCESS))
+ return -1;
+ reg_data = readl(&priv->regs->dr);
+ *buf++ = reg_data & 0xFF;
+ *buf++ = (reg_data >> 8) & 0xFF;
+ *buf++ = (reg_data >> 16) & 0xFF;
+ *buf++ = (reg_data >> 24) & 0xFF;
+ len -= 4;
+ debug("%s: reg_data=%#08x\n",
+ __func__, reg_data);
+ }
+
+ if (len > 0) {
+ if (_ca_sflash_wait_cmd(priv, RD_ACCESS))
+ return -1;
+ reg_data = readl(&priv->regs->dr);
+ debug("%s: reg_data=%#08x\n",
+ __func__, reg_data);
+ }
+
+ switch (len) {
+ case 3:
+ *buf++ = reg_data & 0xFF;
+ *buf++ = (reg_data >> 8) & 0xFF;
+ *buf++ = (reg_data >> 16) & 0xFF;
+ break;
+ case 2:
+ *buf++ = reg_data & 0xFF;
+ *buf++ = (reg_data >> 8) & 0xFF;
+ break;
+ case 1:
+ *buf++ = reg_data & 0xFF;
+ break;
+ case 0:
+ break;
+ default:
+ printf("%s: error data_length %d!\n", __func__, len);
+ }
+
+ return 0;
+}
+
+static int _ca_sflash_mio_set(struct ca_sflash_priv *priv,
+ u8 width)
+{
+ if (width == 4) {
+ setbits_le32(&priv->regs->ar,
+ CA_SF_AR_MIO_INF_DC
+ | CA_SF_AR_MIO_INF(CA_SF_ACCESS_MIO_QUARD)
+ | CA_SF_AR_FORCE_BURST);
+ } else if (width == 2) {
+ setbits_le32(&priv->regs->ar,
+ CA_SF_AR_MIO_INF_DC
+ | CA_SF_AR_MIO_INF(CA_SF_ACCESS_MIO_DUAL)
+ | CA_SF_AR_FORCE_BURST);
+ } else if (width == 1) {
+ setbits_le32(&priv->regs->ar,
+ CA_SF_AR_MIO_INF(CA_SF_ACCESS_MIO_SINGLE)
+ | CA_SF_AR_FORCE_BURST);
+ } else {
+ printf("%s: error rx/tx width %d!\n", __func__, width);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int _ca_sflash_write(struct ca_sflash_priv *priv,
+ u8 *buf, unsigned int data_len)
+{
+ u32 reg_data;
+ int len;
+
+ len = data_len;
+ while (len > 0) {
+ reg_data = buf[0]
+ | (buf[1] << 8)
+ | (buf[2] << 16)
+ | (buf[3] << 24);
+
+ debug("%s: reg_data=%#08x\n",
+ __func__, reg_data);
+ /* Fill data */
+ clrsetbits_le32(&priv->regs->dr, GENMASK(31, 0), reg_data);
+
+ if (_ca_sflash_wait_cmd(priv, WR_ACCESS))
+ return -1;
+
+ len -= 4;
+ buf += 4;
+ }
+
+ return 0;
+}
+
+static int _ca_sflash_access_data(struct ca_sflash_priv *priv,
+ struct spi_mem_op *op)
+{
+ int total_cnt;
+ unsigned int len;
+ unsigned int data_cnt = op->data.nbytes;
+ u64 addr_offset = op->addr.val;
+ u8 addr_cnt = op->addr.nbytes;
+ u8 *data_buf = NULL;
+ u8 *buf = NULL;
+
+ if (op->data.dir == SPI_MEM_DATA_IN)
+ data_buf = (u8 *)op->data.buf.in;
+ else
+ data_buf = (u8 *)op->data.buf.out;
+
+ if (data_cnt > CA_SF_EAR_DATA_CNT_MAX)
+ buf = malloc(CA_SF_EAR_DATA_CNT_MAX);
+ else
+ buf = malloc(data_cnt);
+
+ total_cnt = data_cnt;
+ while (total_cnt > 0) {
+ /* Fill address */
+ if (addr_cnt > 0)
+ clrsetbits_le32(&priv->regs->adr,
+ GENMASK(31, 0), (u32)addr_offset);
+
+ if (total_cnt > CA_SF_EAR_DATA_CNT_MAX) {
+ len = CA_SF_EAR_DATA_CNT_MAX;
+ addr_offset += CA_SF_EAR_DATA_CNT_MAX;
+ /* Clear start bit before next bulk read */
+ clrbits_le32(&priv->regs->asr, GENMASK(31, 0));
+ } else {
+ len = total_cnt;
+ }
+
+ memset(buf, 0, len);
+ if (op->data.dir == SPI_MEM_DATA_IN) {
+ if (_ca_sflash_read(priv, buf, len))
+ break;
+ memcpy(data_buf, buf, len);
+ } else {
+ memcpy(buf, data_buf, len);
+ if (_ca_sflash_write(priv, buf, len))
+ break;
+ }
+
+ total_cnt -= len;
+ data_buf += len;
+ }
+ if (buf)
+ free(buf);
+
+ return total_cnt > 0 ? -1 : 0;
+}
+
+static int _ca_sflash_issue_cmd(struct ca_sflash_priv *priv,
+ struct spi_mem_op *op, u8 opcode)
+{
+ u8 dummy_cnt = op->dummy.nbytes;
+ u8 addr_cnt = op->addr.nbytes;
+ u8 mio_width;
+ unsigned int data_cnt = op->data.nbytes;
+ u64 addr_offset = op->addr.val;
+
+ /* Set the access register */
+ clrsetbits_le32(&priv->regs->ar,
+ GENMASK(31, 0), CA_SF_AR_ACCODE(opcode));
+
+ if (opcode == CA_SF_AC_OPCODE_EXTEND) { /* read_data, write_data */
+ if (data_cnt > 6) {
+ if (op->data.dir == SPI_MEM_DATA_IN)
+ mio_width = priv->rx_width;
+ else
+ mio_width = priv->tx_width;
+ if (_ca_sflash_mio_set(priv, mio_width))
+ return -1;
+ }
+ debug("%s: FLASH ACCESS reg=%#08x\n",
+ __func__, readl(&priv->regs->ar));
+
+ /* Use command in extend_access register */
+ clrsetbits_le32(&priv->regs->ear,
+ GENMASK(31, 0), CA_SF_EAR_OPCODE(op->cmd.opcode)
+ | CA_SF_EAR_DUMY_CNT(dummy_cnt * 8 - 1)
+ | CA_SF_EAR_ADDR_CNT(addr_cnt - 1)
+ | CA_SF_EAR_DATA_CNT(4 - 1)
+ | CA_SF_EAR_DRD_CMD_EN);
+ debug("%s: FLASH EXT ACCESS reg=%#08x\n",
+ __func__, readl(&priv->regs->ear));
+
+ if (_ca_sflash_access_data(priv, op))
+ return -1;
+ } else { /* reset_op, wr_enable, wr_disable */
+ setbits_le32(&priv->regs->ar,
+ CA_SF_AR_OPCODE(op->cmd.opcode));
+ debug("%s: FLASH ACCESS reg=%#08x\n",
+ __func__, readl(&priv->regs->ar));
+
+ if (opcode == CA_SF_AC_OPCODE_4_ADDR) { /* erase_op */
+ /* Configure address length */
+ if (addr_cnt > 3) /* 4 Bytes address */
+ setbits_le32(&priv->regs->tr,
+ CA_FLASH_TR_SIZE(2));
+ else /* 3 Bytes address */
+ clrbits_le32(&priv->regs->tr,
+ CA_FLASH_TR_SIZE_MASK);
+
+ /* Fill address */
+ if (addr_cnt > 0)
+ clrsetbits_le32(&priv->regs->adr,
+ GENMASK(31, 0),
+ (u32)addr_offset);
+ }
+
+ if (_ca_sflash_wait_cmd(priv, RD_ACCESS))
+ return -1;
+ }
+ /* elapse 10us before issuing any other command */
+ udelay(10);
+
+ return 0;
+}
+
+static int ca_sflash_exec_op(struct spi_slave *slave,
+ const struct spi_mem_op *op)
+{
+ struct ca_sflash_priv *priv = dev_get_priv(slave->dev->parent);
+ u8 opcode;
+
+ debug("%s: cmd:%#02x addr.val:%#llx addr.len:%#x data.len:%#x data.dir:%#x\n",
+ __func__, op->cmd.opcode, op->addr.val,
+ op->addr.nbytes, op->data.nbytes, op->data.dir);
+
+ if (op->data.nbytes == 0 && op->addr.nbytes == 0) {
+ opcode = CA_SF_AC_OPCODE;
+ } else if (op->data.nbytes == 0 && op->addr.nbytes > 0) {
+ opcode = CA_SF_AC_OPCODE_4_ADDR;
+ } else if (op->data.nbytes > 0) {
+ opcode = CA_SF_AC_OPCODE_EXTEND;
+ } else {
+ printf("%s: can't support cmd.opcode:(%#02x) type currently!\n",
+ __func__, op->cmd.opcode);
+ return -1;
+ }
+
+ return _ca_sflash_issue_cmd(priv, (struct spi_mem_op *)op, opcode);
+}
+
+static void ca_sflash_init(struct ca_sflash_priv *priv)
+{
+ /* Set FLASH_TYPE as serial flash, value: 0x0400*/
+ clrsetbits_le32(&priv->regs->tr,
+ GENMASK(31, 0), CA_FLASH_TR_SIZE(2));
+ debug("%s: FLASH_TYPE reg=%#x\n",
+ __func__, readl(&priv->regs->tr));
+
+ /* Minimize flash timing, value: 0x07010101 */
+ clrsetbits_le32(&priv->regs->tmr,
+ GENMASK(31, 0),
+ CA_SF_TMR_CLK(0x07)
+ | CA_SF_TMR_SETUP(0x01)
+ | CA_SF_TMR_HOLD(0x01)
+ | CA_SF_TMR_IDLE(0x01));
+ debug("%s: FLASH_TIMING reg=%#x\n",
+ __func__, readl(&priv->regs->tmr));
+}
+
+static int ca_sflash_probe(struct udevice *dev)
+{
+ struct ca_sflash_priv *priv = dev_get_priv(dev);
+ struct resource res;
+ int ret;
+
+ /* Map the registers */
+ ret = dev_read_resource_byname(dev, "sflash-regs", &res);
+ if (ret) {
+ dev_err(dev, "can't get regs base addresses(ret = %d)!\n", ret);
+ return ret;
+ }
+ priv->regs = devm_ioremap(dev, res.start, resource_size(&res));
+ if (IS_ERR(priv->regs))
+ return PTR_ERR(priv->regs);
+
+ ca_sflash_init(priv);
+
+ printf("SFLASH: Controller probed ready\n");
+ return 0;
+}
+
+static const struct spi_controller_mem_ops ca_sflash_mem_ops = {
+ .exec_op = ca_sflash_exec_op,
+};
+
+static const struct dm_spi_ops ca_sflash_ops = {
+ .claim_bus = ca_sflash_claim_bus,
+ .release_bus = ca_sflash_release_bus,
+ .set_speed = ca_sflash_set_speed,
+ .set_mode = ca_sflash_set_mode,
+ .mem_ops = &ca_sflash_mem_ops,
+};
+
+static const struct udevice_id ca_sflash_ids[] = {
+ {.compatible = "cortina,ca-sflash"},
+ {}
+};
+
+U_BOOT_DRIVER(ca_sflash) = {
+ .name = "ca_sflash",
+ .id = UCLASS_SPI,
+ .of_match = ca_sflash_ids,
+ .ops = &ca_sflash_ops,
+ .priv_auto_alloc_size = sizeof(struct ca_sflash_priv),
+ .probe = ca_sflash_probe,
+};
--
2.7.4
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v2 8/8] board: presidio-asic: Add SPI NAND and NOR support
2020-03-20 0:57 [PATCH v2 0/8] Cortina Access Drivers Package 2 Alex Nemirovsky
` (6 preceding siblings ...)
2020-03-20 0:57 ` [PATCH v2 7/8] spi: ca_sflash: Add CAxxxx SPI Flash Controller Alex Nemirovsky
@ 2020-03-20 0:57 ` Alex Nemirovsky
7 siblings, 0 replies; 18+ messages in thread
From: Alex Nemirovsky @ 2020-03-20 0:57 UTC (permalink / raw)
To: u-boot
Add SPI NAND and NOR support for Cortina Access
Presidio Engineering Board
Signed-off-by: Alex Nemirovsky <alex.nemirovsky@cortina-access.com>
CC: Jagan Teki <jagan@amarulasolutions.com>
---
Changes in v3: None
Changes in v2: None
arch/arm/dts/ca-presidio-engboard.dts | 8 ++--
board/cortina/presidio-asic/presidio.c | 16 ++++++-
configs/cortina_presidio-asic-spi-nand_defconfig | 48 +++++++++++++++++++
configs/cortina_presidio-asic-spi-nor_defconfig | 59 ++++++++++++++++++++++++
4 files changed, 125 insertions(+), 6 deletions(-)
create mode 100644 configs/cortina_presidio-asic-spi-nand_defconfig
create mode 100644 configs/cortina_presidio-asic-spi-nor_defconfig
diff --git a/arch/arm/dts/ca-presidio-engboard.dts b/arch/arm/dts/ca-presidio-engboard.dts
index ae897e8..8c73eb6 100644
--- a/arch/arm/dts/ca-presidio-engboard.dts
+++ b/arch/arm/dts/ca-presidio-engboard.dts
@@ -55,15 +55,13 @@
};
sflash: sflash-controller at f4324000 {
- #address-cells = <2>;
- #size-cells = <1>;
compatible = "cortina,ca-sflash";
reg = <0x0 0xf4324000 0x50>;
reg-names = "sflash-regs";
flash at 0 {
- compatible = "jedec,spi-nor";
- spi-rx-bus-width = <1>;
- spi-max-frequency = <108000000>;
+ compatible = "spi-nand", "jedec,spi-nor";
+ spi-rx-bus-width = <4>;
+ spi-tx-bus-width = <4>;
};
};
diff --git a/board/cortina/presidio-asic/presidio.c b/board/cortina/presidio-asic/presidio.c
index b4fa01f..d547b60 100644
--- a/board/cortina/presidio-asic/presidio.c
+++ b/board/cortina/presidio-asic/presidio.c
@@ -14,7 +14,7 @@
#include <asm/psci.h>
#include <cpu_func.h>
#include <asm/armv8/mmu.h>
-
+#include <dm/uclass.h>
DECLARE_GLOBAL_DATA_PTR;
#define CA_PERIPH_BASE 0xE0000000UL
@@ -70,9 +70,23 @@ static noinline int invoke_psci_fn_smc(u64 function_id, u64 arg0, u64 arg1,
return function_id;
}
+#ifdef CONFIG_CORTINA_SFLASH
+static int init_sflash(void)
+{
+ struct udevice *dev;
+
+ uclass_first_device(UCLASS_SPI, &dev);
+
+ return 0;
+}
+#endif
+
int board_early_init_r(void)
{
dcache_disable();
+#ifdef CONFIG_CORTINA_SFLASH
+ init_sflash();
+#endif
return 0;
}
diff --git a/configs/cortina_presidio-asic-spi-nand_defconfig b/configs/cortina_presidio-asic-spi-nand_defconfig
new file mode 100644
index 0000000..515ad22
--- /dev/null
+++ b/configs/cortina_presidio-asic-spi-nand_defconfig
@@ -0,0 +1,48 @@
+CONFIG_ARM=y
+# CONFIG_SYS_ARCH_TIMER is not set
+CONFIG_TARGET_PRESIDIO_ASIC=y
+CONFIG_SYS_TEXT_BASE=0x04000000
+CONFIG_ENV_SIZE=0x20000
+CONFIG_DM_GPIO=y
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_IDENT_STRING="Presidio-SoC"
+CONFIG_SHOW_BOOT_PROGRESS=y
+CONFIG_BOOTDELAY=3
+CONFIG_LOGLEVEL=7
+CONFIG_BOARD_EARLY_INIT_R=y
+CONFIG_SYS_PROMPT="G3#"
+CONFIG_CMD_I2C=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_MTD=y
+CONFIG_CMD_PART=y
+CONFIG_CMD_SF_TEST=y
+CONFIG_CMD_SPI=y
+CONFIG_CMD_WDT=y
+CONFIG_CMD_CACHE=y
+CONFIG_CMD_TIMER=y
+CONFIG_CMD_SMC=y
+CONFIG_CMD_EXT2=y
+CONFIG_CMD_EXT4=y
+CONFIG_CMD_MTDPARTS=y
+CONFIG_OF_CONTROL=y
+CONFIG_OF_LIVE=y
+CONFIG_DEFAULT_DEVICE_TREE="ca-presidio-engboard"
+# CONFIG_NET is not set
+CONFIG_DM=y
+CONFIG_CORTINA_GPIO=y
+CONFIG_DM_I2C=y
+CONFIG_SYS_I2C_CA=y
+CONFIG_DM_MMC=y
+CONFIG_MMC_DW=y
+CONFIG_MMC_DW_CORTINA=y
+CONFIG_MTD=y
+CONFIG_DM_MTD=y
+CONFIG_MTD_SPI_NAND=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_DM_SERIAL=y
+CONFIG_CORTINA_UART=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_CORTINA_SFLASH=y
+CONFIG_WDT=y
+CONFIG_WDT_CORTINA=y
diff --git a/configs/cortina_presidio-asic-spi-nor_defconfig b/configs/cortina_presidio-asic-spi-nor_defconfig
new file mode 100644
index 0000000..d7ecec3
--- /dev/null
+++ b/configs/cortina_presidio-asic-spi-nor_defconfig
@@ -0,0 +1,59 @@
+CONFIG_ARM=y
+# CONFIG_SYS_ARCH_TIMER is not set
+CONFIG_TARGET_PRESIDIO_ASIC=y
+CONFIG_SYS_TEXT_BASE=0x04000000
+CONFIG_ENV_SIZE=0x20000
+CONFIG_DM_GPIO=y
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_IDENT_STRING="Presidio-SoC"
+CONFIG_SHOW_BOOT_PROGRESS=y
+CONFIG_BOOTDELAY=3
+CONFIG_BOARD_EARLY_INIT_R=y
+CONFIG_SYS_PROMPT="G3#"
+CONFIG_CMD_I2C=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_MTD=y
+CONFIG_CMD_PART=y
+CONFIG_CMD_SF_TEST=y
+CONFIG_CMD_SPI=y
+CONFIG_CMD_WDT=y
+CONFIG_CMD_CACHE=y
+CONFIG_CMD_TIMER=y
+CONFIG_CMD_SMC=y
+CONFIG_CMD_EXT2=y
+CONFIG_CMD_EXT4=y
+CONFIG_CMD_MTDPARTS=y
+CONFIG_OF_CONTROL=y
+CONFIG_OF_LIVE=y
+CONFIG_DEFAULT_DEVICE_TREE="ca-presidio-engboard"
+# CONFIG_NET is not set
+CONFIG_DM=y
+CONFIG_CORTINA_GPIO=y
+CONFIG_DM_I2C=y
+CONFIG_SYS_I2C_CA=y
+CONFIG_LED=y
+CONFIG_LED_CORTINA=y
+CONFIG_DM_MMC=y
+CONFIG_MMC_DW=y
+CONFIG_MMC_DW_CORTINA=y
+CONFIG_MTD=y
+CONFIG_DM_MTD=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH_ATMEL=y
+CONFIG_SPI_FLASH_EON=y
+CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_SPI_FLASH_ISSI=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_SST=y
+CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_SPI_FLASH_XMC=y
+CONFIG_SPI_FLASH_MTD=y
+CONFIG_DM_SERIAL=y
+CONFIG_CORTINA_UART=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_CORTINA_SFLASH=y
+CONFIG_WDT=y
+CONFIG_WDT_CORTINA=y
--
2.7.4
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v2 3/8] i2c: i2c-cortina: added CAxxxx I2C support
2020-03-20 0:57 ` [PATCH v2 3/8] i2c: i2c-cortina: added CAxxxx I2C support Alex Nemirovsky
@ 2020-03-20 6:25 ` Heiko Schocher
0 siblings, 0 replies; 18+ messages in thread
From: Heiko Schocher @ 2020-03-20 6:25 UTC (permalink / raw)
To: u-boot
Hello Alex,
Am 20.03.2020 um 01:57 schrieb Alex Nemirovsky:
> From: Arthur Li <arthur.li@cortina-access.com>
>
> Add I2C controller support for Cortina Access CAxxxx SoCs
>
> Signed-off-by: Arthur Li <arthur.li@cortina-access.com>
> Signed-off-by: Alex Nemirovsky <alex.nemirovsky@cortina-access.com>
> CC: Heiko Schocher <hs@denx.de>
> ---
>
> Changes in v3: None
> Changes in v2: None
>
> MAINTAINERS | 4 +
> drivers/i2c/Kconfig | 7 +
> drivers/i2c/Makefile | 1 +
> drivers/i2c/i2c-cortina.c | 346 ++++++++++++++++++++++++++++++++++++++++++++++
> drivers/i2c/i2c-cortina.h | 92 ++++++++++++
> 5 files changed, 450 insertions(+)
> create mode 100644 drivers/i2c/i2c-cortina.c
> create mode 100644 drivers/i2c/i2c-cortina.h
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index bb45d3c..b147faa 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -181,6 +181,8 @@ F: drivers/gpio/cortina_gpio.c
> F: drivers/watchdog/cortina_wdt.c
> F: drivers/serial/serial_cortina.c
> F: drivers/mmc/ca_dw_mmc.c
> +F: drivers/i2c/i2c-cortina.c
> +F: drivers/i2c/i2c-cortina.h
>
> ARM/CZ.NIC TURRIS MOX SUPPORT
> M: Marek Behun <marek.behun@nic.cz>
> @@ -672,6 +674,8 @@ F: drivers/gpio/cortina_gpio.c
> F: drivers/watchdog/cortina_wdt.c
> F: drivers/serial/serial_cortina.c
> F: drivers/mmc/ca_dw_mmc.c
> +F: drivers/i2c/i2c-cortina.c
> +F: drivers/i2c/i2c-cortina.h
>
> MIPS MSCC
> M: Gregory CLEMENT <gregory.clement@bootlin.com>
> diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
> index 03d2fed..b98a4aa 100644
> --- a/drivers/i2c/Kconfig
> +++ b/drivers/i2c/Kconfig
> @@ -85,6 +85,13 @@ config SYS_I2C_CADENCE
> Say yes here to select Cadence I2C Host Controller. This controller is
> e.g. used by Xilinx Zynq.
>
> +config SYS_I2C_CA
> + tristate "Cortina-Access I2C Controller"
> + depends on DM_I2C && CORTINA_PLATFORM
> + default n
> + help
> + Say yes here to select Cortina-Access I2C Host Controller.
> +
> config SYS_I2C_DAVINCI
> bool "Davinci I2C Controller"
> depends on (ARCH_KEYSTONE || ARCH_DAVINCI)
> diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
> index f5a471f..5d18cf7 100644
> --- a/drivers/i2c/Makefile
> +++ b/drivers/i2c/Makefile
> @@ -12,6 +12,7 @@ obj-$(CONFIG_SYS_I2C) += i2c_core.o
> obj-$(CONFIG_SYS_I2C_ASPEED) += ast_i2c.o
> obj-$(CONFIG_SYS_I2C_AT91) += at91_i2c.o
> obj-$(CONFIG_SYS_I2C_CADENCE) += i2c-cdns.o
> +obj-$(CONFIG_SYS_I2C_CA) += i2c-cortina.o
> obj-$(CONFIG_SYS_I2C_DAVINCI) += davinci_i2c.o
> obj-$(CONFIG_SYS_I2C_DW) += designware_i2c.o
> ifdef CONFIG_DM_PCI
> diff --git a/drivers/i2c/i2c-cortina.c b/drivers/i2c/i2c-cortina.c
> new file mode 100644
> index 0000000..99c63f3
> --- /dev/null
> +++ b/drivers/i2c/i2c-cortina.c
> @@ -0,0 +1,346 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * (C) Copyright 2020
> + * Arthur Li, Cortina Access, arthur.li at cortina-access.com.
> + */
> +
> +#include <common.h>
> +#include <i2c.h>
> +#include <asm/io.h>
> +#include <dm.h>
> +#include <mapmem.h>
> +#include "i2c-cortina.h"
> +
> +static void set_speed(struct i2c_regs *regs, int i2c_spd)
> +{
> + union ca_biw_cfg i2c_cfg;
> +
> + i2c_cfg.wrd = readl(®s->i2c_cfg);
> + i2c_cfg.bf.core_en = 0;
> + writel(i2c_cfg.wrd, ®s->i2c_cfg);
> +
> + switch (i2c_spd) {
> + case IC_SPEED_MODE_MAX:
> + i2c_cfg.bf.prer =
> + CORTINA_PER_IO_FREQ / (5 * I2C_MAX_SPEED) - 1;
> + break;
> +
> + case IC_SPEED_MODE_STANDARD:
> + i2c_cfg.bf.prer =
> + CORTINA_PER_IO_FREQ / (5 * I2C_STANDARD_SPEED) - 1;
> + break;
> +
> + case IC_SPEED_MODE_FAST:
> + default:
> + i2c_cfg.bf.prer =
> + CORTINA_PER_IO_FREQ / (5 * I2C_FAST_SPEED) - 1;
> + break;
> + }
> +
> + i2c_cfg.bf.core_en = 1;
> + writel(i2c_cfg.wrd, ®s->i2c_cfg);
> +}
> +
> +static int ca_i2c_set_bus_speed(struct udevice *bus, unsigned int speed)
> +{
> + struct ca_i2c *priv = dev_get_priv(bus);
> + int i2c_spd;
> +
> + if (speed >= I2C_MAX_SPEED) {
> + i2c_spd = IC_SPEED_MODE_MAX;
> + priv->speed = I2C_MAX_SPEED;
> + } else if (speed >= I2C_FAST_SPEED) {
> + i2c_spd = IC_SPEED_MODE_FAST;
> + priv->speed = I2C_FAST_SPEED;
> + } else {
> + i2c_spd = IC_SPEED_MODE_STANDARD;
> + priv->speed = I2C_STANDARD_SPEED;
> + }
> +
> + set_speed(priv->regs, i2c_spd);
> +
> + return 0;
> +}
> +
> +static int ca_i2c_get_bus_speed(struct udevice *bus)
> +{
> + struct ca_i2c *priv = dev_get_priv(bus);
> +
> + return priv->speed;
> +}
> +
> +static void ca_i2c_init(struct i2c_regs *regs)
> +{
> + union ca_biw_cfg i2c_cfg;
> +
> + i2c_cfg.wrd = readl(®s->i2c_cfg);
> + i2c_cfg.bf.core_en = 0;
> + i2c_cfg.bf.biw_soft_reset = 1;
> + writel(i2c_cfg.wrd, ®s->i2c_cfg);
> + mdelay(10);
> + i2c_cfg.bf.biw_soft_reset = 0;
> + writel(i2c_cfg.wrd, ®s->i2c_cfg);
> +
> + set_speed(regs, IC_SPEED_MODE_STANDARD);
> +
> + i2c_cfg.wrd = readl(®s->i2c_cfg);
> + i2c_cfg.bf.core_en = 1;
> + writel(i2c_cfg.wrd, ®s->i2c_cfg);
> +}
> +
> +static int i2c_wait_complete(struct i2c_regs *regs)
> +{
> + union ca_biw_ctrl i2c_ctrl;
> + unsigned long start_time_bb = get_timer(0);
> +
> + i2c_ctrl.wrd = readl(®s->i2c_ctrl);
> +
> + while (i2c_ctrl.bf.biwdone == 0) {
> + i2c_ctrl.wrd = readl(®s->i2c_ctrl);
> +
> + if (get_timer(start_time_bb) >
> + (unsigned long)(I2C_BYTE_TO_BB)) {
> + printf("%s not done!!!\n", __func__);
> + return 1;
Please use -ETIMEDOUT
> + }
> + }
> +
> + /* Clear done bit */
> + writel(i2c_ctrl.wrd, ®s->i2c_ctrl);
> +
> + return 0;
> +}
> +
> +static void i2c_setaddress(struct i2c_regs *regs, unsigned int i2c_addr,
> + int write_read)
> +{
> + writel(i2c_addr | write_read, ®s->i2c_txr);
> +
> + writel(BIW_CTRL_START | BIW_CTRL_WRITE,
> + ®s->i2c_ctrl);
> +
> + i2c_wait_complete(regs);
> +}
> +
> +static int i2c_wait_for_bus_busy(struct i2c_regs *regs)
> +{
> + union ca_biw_ack i2c_ack;
> + unsigned long start_time_bb = get_timer(0);
> +
> + i2c_ack.wrd = readl(®s->i2c_ack);
> +
> + while (i2c_ack.bf.biw_busy) {
> + i2c_ack.wrd = readl(®s->i2c_ack);
> +
> + if (get_timer(start_time_bb) >
> + (unsigned long)(I2C_BYTE_TO_BB)) {
> + printf("%s: timeout!\n", __func__);
> + return 1;
Here too.
> + }
> + }
> +
> + return 0;
> +}
> +
> +static int i2c_xfer_init(struct i2c_regs *regs, uint8_t chip, uint addr,
> + int alen, int write_read)
> +{
> + int addr_len = alen;
> +
> + if (i2c_wait_for_bus_busy(regs))
> + return 1;
Add a blank line please
> + /* First cycle must write addr + offset */
> + chip = ((chip & 0x7F) << 1);
> + if (alen == 0 && write_read == I2C_CMD_RD)
> + i2c_setaddress(regs, chip, I2C_CMD_RD);
> + else
> + i2c_setaddress(regs, chip, I2C_CMD_WT);
> +
> + while (alen) {
> + alen--;
> + writel(addr, ®s->i2c_txr);
> + if (write_read == I2C_CMD_RD)
> + writel(BIW_CTRL_WRITE | BIW_CTRL_STOP,
> + ®s->i2c_ctrl);
> + else
> + writel(BIW_CTRL_WRITE, ®s->i2c_ctrl);
> + i2c_wait_complete(regs);
> + }
> +
> + /* Send address again with Read flag if it's read command */
> + if (write_read == I2C_CMD_RD && addr_len > 0)
> + i2c_setaddress(regs, chip, I2C_CMD_RD);
> +
> + return 0;
> +}
> +
> +static int i2c_xfer_finish(struct i2c_regs *regs)
> +{
> + /* Dummy read makes bus free */
> + writel(BIW_CTRL_READ | BIW_CTRL_STOP, ®s->i2c_ctrl);
> + i2c_wait_complete(regs);
> +
> + if (i2c_wait_for_bus_busy(regs)) {
> + printf("Timed out waiting for bus\n");
> + return 1;
return -ETIMEDOUT
> + }
> +
> + return 0;
> +}
> +
> +static int ca_i2c_read(struct i2c_regs *regs, uint8_t chip, uint addr,
> + int alen, uint8_t *buffer, int len)
> +{
> + unsigned long start_time_rx;
> + int rc = 0;
> +
> + if (i2c_xfer_init(regs, chip, addr, alen, I2C_CMD_RD))
> + return 1;
please return the return value from i2c_xfer_init()
> +
> + start_time_rx = get_timer(0);
> + while (len) {
> + /* ACK_IN is ack value to send during read.
> + * ack high only on the very last byte!
> + */
> + if (len == 1) {
> + writel(BIW_CTRL_READ | BIW_CTRL_ACK_IN | BIW_CTRL_STOP,
> + ®s->i2c_ctrl);
> + } else {
> + writel(BIW_CTRL_READ, ®s->i2c_ctrl);
> + }
remove the brackets, they are not needed.
> +
> + rc = i2c_wait_complete(regs);
> + udelay(1);
> +
> + if (rc == 0) {
> + *buffer++ =
> + (uchar) readl(®s->i2c_rxr);
> + len--;
> + start_time_rx = get_timer(0);
> +
> + } else if (get_timer(start_time_rx) > I2C_BYTE_TO) {
> + return 1;
return -ETIMEDOUT
> + }
> + }
> + i2c_xfer_finish(regs);
> + return rc;
> +}
> +
> +static int ca_i2c_write(struct i2c_regs *regs, uint8_t chip, uint addr,
> + int alen, uint8_t *buffer, int len)
> +{
> + int rc, nb = len;
> + unsigned long start_time_tx;
> +
> + if (i2c_xfer_init(regs, chip, addr, alen, I2C_CMD_WT))
> + return 1;
please return the return value from i2c_xfer_init
> +
> + start_time_tx = get_timer(0);
> + while (len) {
> + writel(*buffer, ®s->i2c_txr);
> + if (len == 1) {
> + writel(BIW_CTRL_WRITE | BIW_CTRL_STOP,
> + ®s->i2c_ctrl);
> + } else {
> + writel(BIW_CTRL_WRITE, ®s->i2c_ctrl);
> + }
also here, the brackets are not needed.
> +
> + rc = i2c_wait_complete(regs);
> +
> + if (rc == 0) {
> + len--;
> + buffer++;
> + start_time_tx = get_timer(0);
> + } else if (get_timer(start_time_tx) > (nb * I2C_BYTE_TO)) {
> + printf("Timed out. i2c write Failed\n");
> + return 1;
return -ETIMEDOUT
> + }
> + }
> +
> + return 0;
> +}
> +
> +static int ca_i2c_probe_chip(struct udevice *bus, uint chip_addr,
> + uint chip_flags)
> +{
> + struct ca_i2c *priv = dev_get_priv(bus);
> + int ret;
> + u32 tmp;
> +
> + /* Try to read the first location of the chip */
> + ret = ca_i2c_read(priv->regs, chip_addr, 0, 1, (uchar *)&tmp, 1);
> + if (ret)
> + ca_i2c_init(priv->regs);
> +
> + return ret;
> +}
> +
> +static int ca_i2c_xfer(struct udevice *bus, struct i2c_msg *msg, int nmsgs)
> +{
> + struct ca_i2c *priv = dev_get_priv(bus);
> + int ret;
> +
> + debug("i2c_xfer: %d messages\n", nmsgs);
> + for (; nmsgs > 0; nmsgs--, msg++) {
> + debug("i2c_xfer: chip=0x%x, len=0x%x\n", msg->addr, msg->len);
> + if (msg->flags & I2C_M_RD) {
> + ret = ca_i2c_read(priv->regs, msg->addr, 0, 0,
> + msg->buf, msg->len);
> + } else {
> + ret = ca_i2c_write(priv->regs, msg->addr, 0, 0,
> + msg->buf, msg->len);
> + }
here too, brackets are not needed.
> +
> + if (ret) {
> + debug("i2c_write: error sending\n");
wrong printf when you did a read.
> + return -EREMOTEIO;
> + }
> + }
> +
> + return 0;
> +}
> +
> +static const struct dm_i2c_ops ca_i2c_ops = {
> + .xfer = ca_i2c_xfer,
> + .probe_chip = ca_i2c_probe_chip,
> + .set_bus_speed = ca_i2c_set_bus_speed,
> + .get_bus_speed = ca_i2c_get_bus_speed,
> +};
> +
> +static const struct udevice_id ca_i2c_ids[] = {
> + { .compatible = "cortina,ca-i2c", },
> + { }
> +};
> +
> +static int ca_i2c_probe(struct udevice *bus)
> +{
> + struct ca_i2c *priv = dev_get_priv(bus);
> +
> + ca_i2c_init(priv->regs);
> +
> + return 0;
> +}
> +
> +static int ca_i2c_ofdata_to_platdata(struct udevice *bus)
> +{
> + struct ca_i2c *priv = dev_get_priv(bus);
> +
> + priv->regs = map_sysmem(dev_read_addr(bus), sizeof(struct i2c_regs));
> + if (!priv->regs) {
> + printf("I2C: base address is invalid\n");
> + return -EINVAL;
> + }
> +
> + return 0;
> +}
> +
> +U_BOOT_DRIVER(i2c_cortina) = {
> + .name = "i2c_cortina",
> + .id = UCLASS_I2C,
> + .of_match = ca_i2c_ids,
> + .ofdata_to_platdata = ca_i2c_ofdata_to_platdata,
> + .probe = ca_i2c_probe,
> + .priv_auto_alloc_size = sizeof(struct ca_i2c),
> + .ops = &ca_i2c_ops,
> + .flags = DM_FLAG_PRE_RELOC,
> +};
> diff --git a/drivers/i2c/i2c-cortina.h b/drivers/i2c/i2c-cortina.h
> new file mode 100644
> index 0000000..f1c3dc7
> --- /dev/null
> +++ b/drivers/i2c/i2c-cortina.h
> @@ -0,0 +1,92 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * (C) Copyright 2019
> + * Cortina Access, <www.cortina-access.com>
> + */
> +
> +#ifndef __CA_I2C_H_
> +#define __CA_I2C_H_
> +
> +#if !defined(__ASSEMBLER__) && !defined(__ASSEMBLY__)
> +struct i2c_regs {
> + u32 i2c_cfg;
> + u32 i2c_ctrl;
> + u32 i2c_txr;
> + u32 i2c_rxr;
> + u32 i2c_ack;
> + u32 i2c_ie0;
> + u32 i2c_int0;
> + u32 i2c_ie1;
> + u32 i2c_int1;
> + u32 i2c_stat;
> +};
> +
> +union ca_biw_cfg {
> + struct biw_cfg {
> + u32 core_en : 1;
> + u32 biw_soft_reset : 1;
> + u32 busywait_en : 1;
> + u32 stretch_en : 1;
> + u32 arb_en : 1;
> + u32 clksync_en : 1;
> + u32 rsrvd1 : 2;
> + u32 spike_cnt : 4;
> + u32 rsrvd2 : 4;
> + u32 prer : 16;
> + } bf;
> + unsigned int wrd;
> +};
> +
> +union ca_biw_ctrl {
> + struct biw_ctrl {
> + u32 biwdone : 1;
> + u32 rsrvd1 : 2;
> + u32 ack_in : 1;
> + u32 write : 1;
> + u32 read : 1;
> + u32 stop : 1;
> + u32 start : 1;
> + u32 rsrvd2 : 24;
> + } bf;
> + unsigned int wrd;
> +};
> +
> +union ca_biw_ack {
> + struct biw_ack {
> + u32 al :1;
> + u32 biw_busy :1;
> + u32 ack_out :1;
> + u32 rsrvd1 :29;
> + } bf;
> + unsigned int wrd;
> +};
> +#endif /* !__ASSEMBLER__*/
> +
> +struct ca_i2c {
> + struct i2c_regs *regs;
> + unsigned int speed;
> +};
> +
> +#define I2C_CMD_WT 0
> +#define I2C_CMD_RD 1
> +
> +#define BIW_CTRL_DONE BIT(0)
> +#define BIW_CTRL_ACK_IN BIT(3)
> +#define BIW_CTRL_WRITE BIT(4)
> +#define BIW_CTRL_READ BIT(5)
> +#define BIW_CTRL_STOP BIT(6)
> +#define BIW_CTRL_START BIT(7)
> +
> +#define I2C_BYTE_TO (CONFIG_SYS_HZ / 500)
> +#define I2C_STOPDET_TO (CONFIG_SYS_HZ / 500)
> +#define I2C_BYTE_TO_BB (10)
> +
> +#define IC_SPEED_MODE_STANDARD 1
> +#define IC_SPEED_MODE_FAST 2
> +#define IC_SPEED_MODE_MAX 3
> +
> +#define I2C_MAX_SPEED 1000000
> +#define I2C_FAST_SPEED 400000
> +#define I2C_STANDARD_SPEED 100000
> +
Not needed, could you please use:
https://gitlab.denx.de/u-boot/u-boot/-/blob/master/include/i2c.h#L44
> +#endif /* __CA_I2C_H_ */
>
Thanks!
bye,
Heiko
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-52 Fax: +49-8142-66989-80 Email: hs at denx.de
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v2 5/8] led: led_cortina: Add CAxxx LED support
2020-03-20 0:57 ` [PATCH v2 5/8] led: led_cortina: Add CAxxx LED support Alex Nemirovsky
@ 2020-03-23 15:37 ` Simon Glass
0 siblings, 0 replies; 18+ messages in thread
From: Simon Glass @ 2020-03-23 15:37 UTC (permalink / raw)
To: u-boot
Hi Alex,
On Thu, 19 Mar 2020 at 18:57, Alex Nemirovsky
<alex.nemirovsky@cortina-access.com> wrote:
>
> From: Jway Lin <jway.lin@cortina-access.com>
>
> Add Cortina Access LED controller support for CAxxxx SOCs
>
> Signed-off-by: Jway Lin <jway.lin@cortina-access.com>
> Signed-off-by: Alex Nemirovsky <alex.nemirovsky@cortina-access.com>
> CC: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3: None
> Changes in v2: None
>
> MAINTAINERS | 2 +
> drivers/led/Kconfig | 8 ++
> drivers/led/Makefile | 1 +
> drivers/led/led_cortina.c | 308 ++++++++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 319 insertions(+)
> create mode 100644 drivers/led/led_cortina.c
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index b147faa..24a2655 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -183,6 +183,7 @@ F: drivers/serial/serial_cortina.c
> F: drivers/mmc/ca_dw_mmc.c
> F: drivers/i2c/i2c-cortina.c
> F: drivers/i2c/i2c-cortina.h
> +F: drivers/led/led_cortina.c
>
> ARM/CZ.NIC TURRIS MOX SUPPORT
> M: Marek Behun <marek.behun@nic.cz>
> @@ -676,6 +677,7 @@ F: drivers/serial/serial_cortina.c
> F: drivers/mmc/ca_dw_mmc.c
> F: drivers/i2c/i2c-cortina.c
> F: drivers/i2c/i2c-cortina.h
> +F: drivers/led/led_cortina.c
>
> MIPS MSCC
> M: Gregory CLEMENT <gregory.clement@bootlin.com>
> diff --git a/drivers/led/Kconfig b/drivers/led/Kconfig
> index 6675934..cc87fbf 100644
> --- a/drivers/led/Kconfig
> +++ b/drivers/led/Kconfig
> @@ -35,6 +35,14 @@ config LED_BCM6858
> This option enables support for LEDs connected to the BCM6858
> HW has blinking capabilities and up to 32 LEDs can be controlled.
>
> +config LED_CORTINA
> + bool "LED Support for Cortina Access CAxxxx SoCs"
> + depends on LED && (CORTINA_PLATFORM)
> + help
> + This option enables support for LEDs connected to the Cortina
> + Access CAxxxx SOCs.
> +
> +
> config LED_BLINK
> bool "Support LED blinking"
> depends on LED
> diff --git a/drivers/led/Makefile b/drivers/led/Makefile
> index 3654dd3..8e3ae7f 100644
> --- a/drivers/led/Makefile
> +++ b/drivers/led/Makefile
> @@ -8,3 +8,4 @@ obj-$(CONFIG_LED_BCM6328) += led_bcm6328.o
> obj-$(CONFIG_LED_BCM6358) += led_bcm6358.o
> obj-$(CONFIG_LED_BCM6858) += led_bcm6858.o
> obj-$(CONFIG_$(SPL_)LED_GPIO) += led_gpio.o
> +obj-$(CONFIG_LED_CORTINA) += led_cortina.o
> diff --git a/drivers/led/led_cortina.c b/drivers/led/led_cortina.c
> new file mode 100644
> index 0000000..53435e8
> --- /dev/null
> +++ b/drivers/led/led_cortina.c
> @@ -0,0 +1,308 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +
> +/*
> + * Copyright (C) 2020 Cortina-Access
> + * Author: Jway Lin <jway.lin@cortina-access.com>
> + *
> + */
> +
> +#include <common.h>
> +#include <dm.h>
> +#include <errno.h>
> +#include <led.h>
> +#include <asm/io.h>
> +#include <dm/lists.h>
> +#include <linux/compat.h>
> +
> +#define CORTINA_LED_NUM 16
> +
> +#define BIT(nr) (1UL << (nr))
That is already defined somewhere
> +
> +#define cortina_LED_CONTROL 0x00
Drop the cortina_ prefix if you can.. It should be upper case. Since
this is local to the file it just adds code.
> +#define cortina_LED_CONFIG_0 0x04
> +#define cortina_LED_CONFIG_1 0x08
> +#define cortina_LED_CONFIG_2 0x0c
> +#define cortina_LED_CONFIG_3 0x10
> +#define cortina_LED_CONFIG_4 0x14
> +#define cortina_LED_CONFIG_5 0x18
> +#define cortina_LED_CONFIG_6 0x1c
> +#define cortina_LED_CONFIG_7 0x20
> +#define cortina_LED_CONFIG_8 0x24
> +#define cortina_LED_CONFIG_9 0x28
> +#define cortina_LED_CONFIG_10 0x2c
> +#define cortina_LED_CONFIG_11 0x30
> +#define cortina_LED_CONFIG_12 0x34
> +#define cortina_LED_CONFIG_13 0x38
> +#define cortina_LED_CONFIG_14 0x3c
> +#define cortina_LED_CONFIG_15 0x40
What are all those used for?
> +
> +#define cortina_LED_MAX_HW_BLINK 127
> +#define cortina_LED_MAX_COUNT CORTINA_LED_NUM
> +#define cortina_LED_MAX_PORT 8
> +
> +/* LED_CONTROL fields */
> +#define cortina_LED_BLINK_RATE1_OFFSET 0
> +#define cortina_LED_BLINK_RATE1_MASK 0xFF
Lower-case hex
> +#define cortina_LED_BLINK_RATE2_OFFSET 8
> +#define cortina_LED_BLINK_RATE2_MASK 0xFF
> +#define cortina_LED_CLK_TEST BIT(16)
> +#define cortina_LED_CLK_POLARITY BIT(17)
> +#define cortina_LED_CLK_TEST_MODE BIT(16)
> +#define cortina_LED_CLK_TEST_RX_TEST BIT(30)
> +#define cortina_LED_CLK_TEST_TX_TEST BIT(31)
> +
> +/* LED_CONFIG fields */
> +#define cortina_LED_EVENT_ON_OFFSET 0
> +#define cortina_LED_EVENT_ON_MASK 0x7
> +#define cortina_LED_EVENT_BLINK_OFFSET 3
> +#define cortina_LED_EVENT_BLINK_MASK 0x7
> +#define cortina_LED_EVENT_OFF_OFFSET 6
> +#define cortina_LED_EVENT_OFF_MASK 0x7
> +#define cortina_LED_OFF_ON_OFFSET 9
> +#define cortina_LED_OFF_ON_MASK 0x3
> +#define cortina_LED_PORT_OFFSET 11
> +#define cortina_LED_PORT_MASK 0x7
> +#define cortina_LED_OFF_VAL BIT(14)
> +#define cortina_LED_SW_EVENT BIT(15)
> +#define cortina_LED_BLINK_SEL BIT(16)
> +
Need a struct comment
> +struct cortina_led_cfg {
> + void __iomem *regs;
> + spinlock_t *lock; /* protect LED resource access */
> + int idx;
> + bool active_low;
> +
> + int off_event;
> + int blink_event;
> + int on_event;
> + int port;
> + int blink;
> + int enable;
> +};
> +
> +struct cortina_led_top_cfg {
here too
> + void __iomem *regs;
> + u16 blink_rate1;
> + u16 blink_rate2;
> +};
> +
> +static struct cortina_led_top_cfg glb_led_ctrl;
You are not allowed to use BSS in driver model. It's not clear why you
have two structures as there are no comments. Can you not combine
them?
> +
> +static void cortina_led_write(void __iomem *reg, unsigned long data)
> +{
> + writel(data, reg);
> +}
> +
> +static unsigned long cortina_led_read(void __iomem *reg)
> +{
> + return readl(reg);
> +}
> +
> +static enum led_state_t cortina_led_get_state(struct udevice *dev)
> +{
> + struct cortina_led_cfg *priv = dev_get_priv(dev);
> + enum led_state_t state = LEDST_OFF;
> + u32 val;
> +
> + val = readl(priv->regs);
> +
> + if (val & cortina_LED_SW_EVENT)
> + state = LEDST_ON;
> +
> + return state;
> +}
> +
> +static int cortina_led_set_state(struct udevice *dev, enum led_state_t state)
> +{
> + u32 val;
> + struct cortina_led_cfg *priv = dev_get_priv(dev);
> +
> + val = readl(priv->regs);
> +
> + switch (state) {
> + case LEDST_OFF:
> + val &= ~cortina_LED_SW_EVENT;
> + val &= ~(cortina_LED_OFF_ON_MASK << cortina_LED_OFF_ON_OFFSET);
> + val |= 0x3 << cortina_LED_OFF_ON_OFFSET;
> + cortina_led_write(priv->regs, val);
> + break;
> + case LEDST_ON:
> + val |= cortina_LED_SW_EVENT;
> + val &= ~(cortina_LED_OFF_ON_MASK << cortina_LED_OFF_ON_OFFSET);
> + val |= 0x1 << cortina_LED_OFF_ON_OFFSET;
> + cortina_led_write(priv->regs, val);
> + break;
> + case LEDST_TOGGLE:
> + if (cortina_led_get_state(dev) == LEDST_OFF)
> + return cortina_led_set_state(dev, LEDST_ON);
> + else
> + return cortina_led_set_state(dev, LEDST_OFF);
> + break;
> +
> + default:
> + return -EINVAL;
> + }
> +
> + return 0;
> +}
> +
> +static const struct led_ops cortina_led_ops = {
> + .get_state = cortina_led_get_state,
> + .set_state = cortina_led_set_state,
> +};
> +
> +static int cortina_led_probe(struct udevice *dev)
> +{
> + struct led_uc_plat *uc_plat = dev_get_uclass_platdata(dev);
> + void __iomem *regs;
> + u32 reg_value, val;
> + u16 rate1, rate2;
> + struct cortina_led_cfg *priv = dev_get_priv(dev);
> + unsigned int pin;
> + u32 blink, port, off_event, blink_event, on_event;
> +
> + /* Top-level LED node */
> + if (!uc_plat->label) {
> + regs = dev_remap_addr(dev);
> +
> + if (!regs)
> + return -EINVAL;
> +
> + glb_led_ctrl.regs = regs;
> +
> + reg_value = 0;
> + reg_value |= cortina_LED_CLK_POLARITY;
> +
> + rate1 = dev_read_u32_default(dev, "cortina, blink_rate1", 256);
> + rate2 = dev_read_u32_default(dev, "cortina, blink_rate2", 512);
Strictly speaking you should read your platdata into a plat struct in
your ofdata_to_platdata method.
Also do you have a binding file for this? I think we sholld use hyphen
for properties instead of underscore.
> +
> + val = rate1 / 16 - 1;
> + glb_led_ctrl.blink_rate1 = val > cortina_LED_MAX_HW_BLINK ?
> + cortina_LED_MAX_HW_BLINK : val;
> + reg_value |= (glb_led_ctrl.blink_rate1 & cortina_LED_BLINK_RATE1_MASK)
> + << cortina_LED_BLINK_RATE1_OFFSET;
> +
> + val = rate2 / 16 - 1;
> + glb_led_ctrl.blink_rate2 = val > cortina_LED_MAX_HW_BLINK ?
> + cortina_LED_MAX_HW_BLINK : val;
> + reg_value |= (glb_led_ctrl.blink_rate2 & cortina_LED_BLINK_RATE2_MASK)
> + << cortina_LED_BLINK_RATE2_OFFSET;
> +
> + cortina_led_write(glb_led_ctrl.regs, reg_value);
> + } else {
> + regs = dev_remap_addr(dev_get_parent(dev));
> +
> + if (!regs)
> + return -EINVAL;
> +
> + pin = dev_read_u32_default(dev, "pin", cortina_LED_MAX_COUNT);
> +
> + if (pin >= cortina_LED_MAX_COUNT)
> + return -EINVAL;
> +
> + priv->regs = regs + 4 + (pin * 4);
> +
> + val = cortina_led_read(priv->regs);
> +
> + if (dev_read_bool(dev, "active-low")) {
> + priv->active_low = true;
> + val |= cortina_LED_OFF_VAL;
> + } else {
> + priv->active_low = false;
> + val &= ~cortina_LED_OFF_VAL;
> + }
> +
> + blink = dev_read_u32_default(dev, "blink-sel", 0);
> +
> + if (blink == 0) {
> + priv->blink = 0;
> + val &= ~cortina_LED_BLINK_SEL;
> + } else if (blink == 1) {
> + priv->blink = 1;
> + val |= cortina_LED_BLINK_SEL;
> + }
> +
> + //Todo : cortina_led_config();
> + off_event = dev_read_u32_default(dev, "off-event", 3);
> + val &= ~(cortina_LED_EVENT_OFF_MASK << cortina_LED_EVENT_OFF_OFFSET);
> + if (off_event != 3) {
> + priv->off_event = off_event;
> + val |= BIT(off_event) << cortina_LED_EVENT_OFF_OFFSET;
> + }
> +
> + blink_event = dev_read_u32_default(dev, "blink-event", 3);
> + val &= ~(cortina_LED_EVENT_BLINK_MASK <<
> + cortina_LED_EVENT_BLINK_OFFSET);
> +
> + if (blink_event != 3) {
> + priv->blink_event = blink_event;
> + val |= BIT(blink_event) << cortina_LED_EVENT_BLINK_OFFSET;
> + }
> +
> + on_event = dev_read_u32_default(dev, "on-event", 3);
> + val &= ~(cortina_LED_EVENT_ON_MASK << cortina_LED_EVENT_ON_OFFSET);
> + if (on_event != 3) {
> + priv->on_event = on_event;
> + val |= BIT(on_event) << cortina_LED_EVENT_ON_OFFSET;
> + }
> +
> + port = dev_read_u32_default(dev, "port", 0);
> + priv->port = port;
> + val &= ~(cortina_LED_PORT_MASK << cortina_LED_PORT_OFFSET);
> + val |= port << cortina_LED_PORT_OFFSET;
> +
> + priv->enable = 0;
> +
> + /* force off */
> + val &= ~(cortina_LED_OFF_ON_MASK << cortina_LED_OFF_ON_OFFSET);
> + val |= 0x3 << cortina_LED_OFF_ON_OFFSET;
> +
> + cortina_led_write(priv->regs, val);
> + }
funny indent?
> +
> + return 0;
> +}
> +
> +static int cortina_led_bind(struct udevice *parent)
> +{
> + ofnode node;
> +
> + dev_for_each_subnode(node, parent) {
> + struct led_uc_plat *uc_plat;
> + struct udevice *dev;
> + const char *label;
> + int ret;
> +
> + label = ofnode_read_string(node, "label");
> + if (!label) {
> + debug("%s: node %s has no label\n", __func__,
> + ofnode_get_name(node));
> + return -EINVAL;
> + }
> +
> + ret = device_bind_driver_to_node(parent, "ca-leds",
> + ofnode_get_name(node),
> + node, &dev);
Does device_bind_ofnode() help here?
> + if (ret)
> + return ret;
> + uc_plat = dev_get_uclass_platdata(dev);
> + uc_plat->label = label;
> + }
> +
> + return 0;
> +}
> +
> +static const struct udevice_id ca_led_ids[] = {
> + { .compatible = "cortina,ca-leds" },
> + { /* sentinel */ }
> +};
> +
> +U_BOOT_DRIVER(cortina_led) = {
> + .name = "ca-leds",
> + .id = UCLASS_LED,
> + .of_match = ca_led_ids,
> + .bind = cortina_led_bind,
> + .probe = cortina_led_probe,
> + .priv_auto_alloc_size = sizeof(struct cortina_led_cfg),
> + .ops = &cortina_led_ops,
> +};
> --
> 2.7.4
>
Regards,
Simon
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v2 6/8] board: presidio: add LED support
2020-03-20 0:57 ` [PATCH v2 6/8] board: presidio: add " Alex Nemirovsky
@ 2020-03-23 15:37 ` Simon Glass
0 siblings, 0 replies; 18+ messages in thread
From: Simon Glass @ 2020-03-23 15:37 UTC (permalink / raw)
To: u-boot
On Thu, 19 Mar 2020 at 18:57, Alex Nemirovsky
<alex.nemirovsky@cortina-access.com> wrote:
>
> From: Jway Lin <jway.lin@cortina-access.com>
>
> Add LED support for Cortina Access Presidio Engineering Board
>
> Signed-off-by: Jway Lin <jway.lin@cortina-access.com>
> Signed-off-by: Alex Nemirovsky <alex.nemirovsky@cortina-access.com>
> CC: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v3: None
> Changes in v2: None
>
> arch/arm/dts/ca-presidio-engboard.dts | 31 ++++++++++++++++++++++++++++
> configs/cortina_presidio-asic-emmc_defconfig | 2 ++
> 2 files changed, 33 insertions(+)
Reviewed-by: Simon Glass <sjg@chromium.org>
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v2 1/8] mmc: ca_dw_mmc: add DesignWare based DM support for CAxxxx SoCs
2020-03-20 0:57 ` [PATCH v2 1/8] mmc: ca_dw_mmc: add DesignWare based DM support for CAxxxx SoCs Alex Nemirovsky
@ 2020-03-24 7:16 ` Jaehoon Chung
2020-03-24 21:18 ` Alex Nemirovsky
0 siblings, 1 reply; 18+ messages in thread
From: Jaehoon Chung @ 2020-03-24 7:16 UTC (permalink / raw)
To: u-boot
Hi,
On 3/20/20 9:57 AM, Alex Nemirovsky wrote:
> From: Arthur Li <arthur.li@cortina-access.com>
>
> Initial DesignWare based DM support for Cortina Access CAxxxx SoCs.
>
> Signed-off-by: Arthur Li <arthur.li@cortina-access.com>
> Signed-off-by: Alex Nemirovsky <alex.nemirovsky@cortina-access.com>
> CC: Peng Fan <peng.fan@nxp.com>
I didn't receive any reply about my previous comments.
And Is there patch v3 or v2? Subject is v2..but change log is v3.
What is correct version?
Best Regards,
Jaehoon Chung
>
> ---
>
> Changes in v3: None
> Changes in v2:
> - Add I2C controller
> - Add LED controller
> - Add SPI NAND and NOR controller
>
> MAINTAINERS | 2 +
> drivers/mmc/Kconfig | 11 +++
> drivers/mmc/Makefile | 1 +
> drivers/mmc/ca_dw_mmc.c | 181 ++++++++++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 195 insertions(+)
> create mode 100644 drivers/mmc/ca_dw_mmc.c
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 82e4159..bb45d3c 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -180,6 +180,7 @@ F: board/cortina/common/
> F: drivers/gpio/cortina_gpio.c
> F: drivers/watchdog/cortina_wdt.c
> F: drivers/serial/serial_cortina.c
> +F: drivers/mmc/ca_dw_mmc.c
>
> ARM/CZ.NIC TURRIS MOX SUPPORT
> M: Marek Behun <marek.behun@nic.cz>
> @@ -670,6 +671,7 @@ F: board/cortina/common/
> F: drivers/gpio/cortina_gpio.c
> F: drivers/watchdog/cortina_wdt.c
> F: drivers/serial/serial_cortina.c
> +F: drivers/mmc/ca_dw_mmc.c
>
> MIPS MSCC
> M: Gregory CLEMENT <gregory.clement@bootlin.com>
> diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
> index 2f0eedc..bb38787 100644
> --- a/drivers/mmc/Kconfig
> +++ b/drivers/mmc/Kconfig
> @@ -205,6 +205,17 @@ config MMC_DW
> block, this provides host support for SD and MMC interfaces, in both
> PIO, internal DMA mode and external DMA mode.
>
> +config MMC_DW_CORTINA
> + bool "Cortina specific extensions for Synopsys DW Memory Card Interface"
> + depends on DM_MMC
> + depends on MMC_DW
> + depends on BLK
> + default n
> + help
> + This selects support for Cortina SoC specific extensions to the
> + Synopsys DesignWare Memory Card Interface driver. Select this option
> + for platforms based on Cortina CAxxxx Soc's.
> +
> config MMC_DW_EXYNOS
> bool "Exynos specific extensions for Synopsys DW Memory Card Interface"
> depends on ARCH_EXYNOS
> diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
> index 9c1f8e5..615b724 100644
> --- a/drivers/mmc/Makefile
> +++ b/drivers/mmc/Makefile
> @@ -20,6 +20,7 @@ endif
> obj-$(CONFIG_ARM_PL180_MMCI) += arm_pl180_mmci.o
> obj-$(CONFIG_MMC_DAVINCI) += davinci_mmc.o
> obj-$(CONFIG_MMC_DW) += dw_mmc.o
> +obj-$(CONFIG_MMC_DW_CORTINA) += ca_dw_mmc.o
> obj-$(CONFIG_MMC_DW_EXYNOS) += exynos_dw_mmc.o
> obj-$(CONFIG_MMC_DW_K3) += hi6220_dw_mmc.o
> obj-$(CONFIG_MMC_DW_ROCKCHIP) += rockchip_dw_mmc.o
> diff --git a/drivers/mmc/ca_dw_mmc.c b/drivers/mmc/ca_dw_mmc.c
> new file mode 100644
> index 0000000..acbc850
> --- /dev/null
> +++ b/drivers/mmc/ca_dw_mmc.c
> @@ -0,0 +1,181 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * (C) Copyright 2019 Cortina Access
> + * Arthur Li <arthur.li@cortina-access.com>
> + */
> +
> +#include <common.h>
> +#include <dwmmc.h>
> +#include <fdtdec.h>
> +#include <linux/libfdt.h>
> +#include <malloc.h>
> +#include <errno.h>
> +#include <dm.h>
> +#include <mapmem.h>
> +
> +#define SD_CLK_SEL_MASK (0x3)
> +#define SD_DLL_DEFAULT (0x143000)
> +#define SD_SCLK_MAX (200000000)
> +
> +#define SD_CLK_SEL_200MHZ (0x2)
> +#define SD_CLK_SEL_100MHZ (0x1)
> +
> +#define IO_DRV_SD_DS_OFFSET (16)
> +#define IO_DRV_SD_DS_MASK (0xff << IO_DRV_SD_DS_OFFSET)
> +
> +#define MIN_FREQ (400000)
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +struct ca_mmc_plat {
> + struct mmc_config cfg;
> + struct mmc mmc;
> +};
> +
> +struct ca_dwmmc_priv_data {
> + struct dwmci_host host;
> + void __iomem *sd_dll_reg;
> + void __iomem *io_drv_reg;
> + u8 ds;
> +};
> +
> +static void ca_dwmci_clksel(struct dwmci_host *host)
> +{
> + struct ca_dwmmc_priv_data *priv = host->priv;
> + u32 val = readl(priv->sd_dll_reg);
> +
> + if (host->bus_hz >= 200000000) {
> + val &= ~SD_CLK_SEL_MASK;
> + val |= SD_CLK_SEL_200MHZ;
> + } else if (host->bus_hz >= 100000000) {
> + val &= ~SD_CLK_SEL_MASK;
> + val |= SD_CLK_SEL_100MHZ;
> + } else {
> + val &= ~SD_CLK_SEL_MASK;
> + }
> +
> + writel(val, priv->sd_dll_reg);
> +}
> +
> +static void ca_dwmci_board_init(struct dwmci_host *host)
> +{
> + struct ca_dwmmc_priv_data *priv = host->priv;
> + u32 val = readl(priv->io_drv_reg);
> +
> + writel(SD_DLL_DEFAULT, priv->sd_dll_reg);
> +
> + val &= ~IO_DRV_SD_DS_MASK;
> + if (priv && priv->ds)
> + val |= priv->ds << IO_DRV_SD_DS_OFFSET;
> + writel(val, priv->io_drv_reg);
> +}
> +
> +unsigned int ca_dwmci_get_mmc_clock(struct dwmci_host *host, uint freq)
> +{
> + struct ca_dwmmc_priv_data *priv = host->priv;
> + u8 sd_clk_sel = readl(priv->sd_dll_reg) & SD_CLK_SEL_MASK;
> + u8 clk_div;
> +
> + switch (sd_clk_sel) {
> + case 2:
> + clk_div = 1;
> + break;
> + case 1:
> + clk_div = 2;
> + break;
> + default:
> + clk_div = 4;
> + }
> +
> + return SD_SCLK_MAX / clk_div / (host->div + 1);
> +}
> +
> +static int ca_dwmmc_ofdata_to_platdata(struct udevice *dev)
> +{
> + struct ca_dwmmc_priv_data *priv = dev_get_priv(dev);
> + struct dwmci_host *host = &priv->host;
> + u32 tmp;
> +
> + host->name = dev->name;
> + host->dev_index = 0;
> +
> + host->buswidth = dev_read_u32_default(dev, "bus-width", 1);
> + if (host->buswidth != 1 && host->buswidth != 4)
> + return -EINVAL;
> +
> + host->bus_hz = dev_read_u32_default(dev, "max-frequency", 50000000);
> + priv->ds = dev_read_u32_default(dev, "io_ds", 0x33);
> + host->fifo_mode = dev_read_bool(dev, "fifo-mode");
> +
> + dev_read_u32(dev, "sd_dll_ctrl", &tmp);
> + priv->sd_dll_reg = map_sysmem((uintptr_t)tmp, sizeof(uintptr_t));
> + if (!priv->sd_dll_reg)
> + return -EINVAL;
> +
> + dev_read_u32(dev, "io_drv_ctrl", &tmp);
> + priv->io_drv_reg = map_sysmem((uintptr_t)tmp, sizeof(uintptr_t));
> + if (!priv->io_drv_reg)
> + return -EINVAL;
> +
> + host->ioaddr = dev_read_addr_ptr(dev);
> + if (host->ioaddr == (void *)FDT_ADDR_T_NONE) {
> + printf("DWMMC: base address is invalid\n");
> + return -EINVAL;
> + }
> +
> + host->priv = priv;
> +
> + return 0;
> +}
> +
> +struct dm_mmc_ops ca_dwmci_dm_ops;
> +
> +static int ca_dwmmc_probe(struct udevice *dev)
> +{
> + struct ca_mmc_plat *plat = dev_get_platdata(dev);
> + struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
> + struct ca_dwmmc_priv_data *priv = dev_get_priv(dev);
> + struct dwmci_host *host = &priv->host;
> +
> + memcpy(&ca_dwmci_dm_ops, &dm_dwmci_ops, sizeof(struct dm_mmc_ops));
> +
> + dwmci_setup_cfg(&plat->cfg, host, host->bus_hz, MIN_FREQ);
> + if (host->buswidth == 1) {
> + (&plat->cfg)->host_caps &= ~MMC_MODE_8BIT;
> + (&plat->cfg)->host_caps &= ~MMC_MODE_4BIT;
> + }
> +
> + host->mmc = &plat->mmc;
> + host->mmc->priv = &priv->host;
> + upriv->mmc = host->mmc;
> + host->mmc->dev = dev;
> + host->clksel = ca_dwmci_clksel;
> + host->board_init = ca_dwmci_board_init;
> + host->get_mmc_clk = ca_dwmci_get_mmc_clock;
> +
> + return dwmci_probe(dev);
> +}
> +
> +static int ca_dwmmc_bind(struct udevice *dev)
> +{
> + struct ca_mmc_plat *plat = dev_get_platdata(dev);
> +
> + return dwmci_bind(dev, &plat->mmc, &plat->cfg);
> +}
> +
> +static const struct udevice_id ca_dwmmc_ids[] = {
> + { .compatible = "snps,dw-cortina" },
> + { }
> +};
> +
> +U_BOOT_DRIVER(ca_dwmmc_drv) = {
> + .name = "cortina_dwmmc",
> + .id = UCLASS_MMC,
> + .of_match = ca_dwmmc_ids,
> + .ofdata_to_platdata = ca_dwmmc_ofdata_to_platdata,
> + .bind = ca_dwmmc_bind,
> + .ops = &ca_dwmci_dm_ops,
> + .probe = ca_dwmmc_probe,
> + .priv_auto_alloc_size = sizeof(struct ca_dwmmc_priv_data),
> + .platdata_auto_alloc_size = sizeof(struct ca_mmc_plat),
> +};
>
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v2 1/8] mmc: ca_dw_mmc: add DesignWare based DM support for CAxxxx SoCs
2020-03-24 7:16 ` Jaehoon Chung
@ 2020-03-24 21:18 ` Alex Nemirovsky
0 siblings, 0 replies; 18+ messages in thread
From: Alex Nemirovsky @ 2020-03-24 21:18 UTC (permalink / raw)
To: u-boot
Hi Jaehoon,
We incorporated your comments locally. We will release the next series as v4 once all feedback is received
for the rest of the patches in the series. Thank you for your feedback.
-BR
AN
> On Mar 24, 2020, at 12:16 AM, Jaehoon Chung <jh80.chung@samsung.com> wrote:
>
> Hi,
>
> On 3/20/20 9:57 AM, Alex Nemirovsky wrote:
>> From: Arthur Li <arthur.li@cortina-access.com>
>>
>> Initial DesignWare based DM support for Cortina Access CAxxxx SoCs.
>>
>> Signed-off-by: Arthur Li <arthur.li@cortina-access.com>
>> Signed-off-by: Alex Nemirovsky <alex.nemirovsky@cortina-access.com>
>> CC: Peng Fan <peng.fan@nxp.com>
>
> I didn't receive any reply about my previous comments.
> And Is there patch v3 or v2? Subject is v2..but change log is v3.
> What is correct version?
>
> Best Regards,
> Jaehoon Chung
>
>>
>> ---
>>
>> Changes in v3: None
>> Changes in v2:
>> - Add I2C controller
>> - Add LED controller
>> - Add SPI NAND and NOR controller
>>
>> MAINTAINERS | 2 +
>> drivers/mmc/Kconfig | 11 +++
>> drivers/mmc/Makefile | 1 +
>> drivers/mmc/ca_dw_mmc.c | 181 ++++++++++++++++++++++++++++++++++++++++++++++++
>> 4 files changed, 195 insertions(+)
>> create mode 100644 drivers/mmc/ca_dw_mmc.c
>>
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index 82e4159..bb45d3c 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -180,6 +180,7 @@ F: board/cortina/common/
>> F: drivers/gpio/cortina_gpio.c
>> F: drivers/watchdog/cortina_wdt.c
>> F: drivers/serial/serial_cortina.c
>> +F: drivers/mmc/ca_dw_mmc.c
>>
>> ARM/CZ.NIC TURRIS MOX SUPPORT
>> M: Marek Behun <marek.behun@nic.cz>
>> @@ -670,6 +671,7 @@ F: board/cortina/common/
>> F: drivers/gpio/cortina_gpio.c
>> F: drivers/watchdog/cortina_wdt.c
>> F: drivers/serial/serial_cortina.c
>> +F: drivers/mmc/ca_dw_mmc.c
>>
>> MIPS MSCC
>> M: Gregory CLEMENT <gregory.clement@bootlin.com>
>> diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
>> index 2f0eedc..bb38787 100644
>> --- a/drivers/mmc/Kconfig
>> +++ b/drivers/mmc/Kconfig
>> @@ -205,6 +205,17 @@ config MMC_DW
>> block, this provides host support for SD and MMC interfaces, in both
>> PIO, internal DMA mode and external DMA mode.
>>
>> +config MMC_DW_CORTINA
>> + bool "Cortina specific extensions for Synopsys DW Memory Card Interface"
>> + depends on DM_MMC
>> + depends on MMC_DW
>> + depends on BLK
>> + default n
>> + help
>> + This selects support for Cortina SoC specific extensions to the
>> + Synopsys DesignWare Memory Card Interface driver. Select this option
>> + for platforms based on Cortina CAxxxx Soc's.
>> +
>> config MMC_DW_EXYNOS
>> bool "Exynos specific extensions for Synopsys DW Memory Card Interface"
>> depends on ARCH_EXYNOS
>> diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
>> index 9c1f8e5..615b724 100644
>> --- a/drivers/mmc/Makefile
>> +++ b/drivers/mmc/Makefile
>> @@ -20,6 +20,7 @@ endif
>> obj-$(CONFIG_ARM_PL180_MMCI) += arm_pl180_mmci.o
>> obj-$(CONFIG_MMC_DAVINCI) += davinci_mmc.o
>> obj-$(CONFIG_MMC_DW) += dw_mmc.o
>> +obj-$(CONFIG_MMC_DW_CORTINA) += ca_dw_mmc.o
>> obj-$(CONFIG_MMC_DW_EXYNOS) += exynos_dw_mmc.o
>> obj-$(CONFIG_MMC_DW_K3) += hi6220_dw_mmc.o
>> obj-$(CONFIG_MMC_DW_ROCKCHIP) += rockchip_dw_mmc.o
>> diff --git a/drivers/mmc/ca_dw_mmc.c b/drivers/mmc/ca_dw_mmc.c
>> new file mode 100644
>> index 0000000..acbc850
>> --- /dev/null
>> +++ b/drivers/mmc/ca_dw_mmc.c
>> @@ -0,0 +1,181 @@
>> +// SPDX-License-Identifier: GPL-2.0+
>> +/*
>> + * (C) Copyright 2019 Cortina Access
>> + * Arthur Li <arthur.li@cortina-access.com>
>> + */
>> +
>> +#include <common.h>
>> +#include <dwmmc.h>
>> +#include <fdtdec.h>
>> +#include <linux/libfdt.h>
>> +#include <malloc.h>
>> +#include <errno.h>
>> +#include <dm.h>
>> +#include <mapmem.h>
>> +
>> +#define SD_CLK_SEL_MASK (0x3)
>> +#define SD_DLL_DEFAULT (0x143000)
>> +#define SD_SCLK_MAX (200000000)
>> +
>> +#define SD_CLK_SEL_200MHZ (0x2)
>> +#define SD_CLK_SEL_100MHZ (0x1)
>> +
>> +#define IO_DRV_SD_DS_OFFSET (16)
>> +#define IO_DRV_SD_DS_MASK (0xff << IO_DRV_SD_DS_OFFSET)
>> +
>> +#define MIN_FREQ (400000)
>> +
>> +DECLARE_GLOBAL_DATA_PTR;
>> +
>> +struct ca_mmc_plat {
>> + struct mmc_config cfg;
>> + struct mmc mmc;
>> +};
>> +
>> +struct ca_dwmmc_priv_data {
>> + struct dwmci_host host;
>> + void __iomem *sd_dll_reg;
>> + void __iomem *io_drv_reg;
>> + u8 ds;
>> +};
>> +
>> +static void ca_dwmci_clksel(struct dwmci_host *host)
>> +{
>> + struct ca_dwmmc_priv_data *priv = host->priv;
>> + u32 val = readl(priv->sd_dll_reg);
>> +
>> + if (host->bus_hz >= 200000000) {
>> + val &= ~SD_CLK_SEL_MASK;
>> + val |= SD_CLK_SEL_200MHZ;
>> + } else if (host->bus_hz >= 100000000) {
>> + val &= ~SD_CLK_SEL_MASK;
>> + val |= SD_CLK_SEL_100MHZ;
>> + } else {
>> + val &= ~SD_CLK_SEL_MASK;
>> + }
>> +
>> + writel(val, priv->sd_dll_reg);
>> +}
>> +
>> +static void ca_dwmci_board_init(struct dwmci_host *host)
>> +{
>> + struct ca_dwmmc_priv_data *priv = host->priv;
>> + u32 val = readl(priv->io_drv_reg);
>> +
>> + writel(SD_DLL_DEFAULT, priv->sd_dll_reg);
>> +
>> + val &= ~IO_DRV_SD_DS_MASK;
>> + if (priv && priv->ds)
>> + val |= priv->ds << IO_DRV_SD_DS_OFFSET;
>> + writel(val, priv->io_drv_reg);
>> +}
>> +
>> +unsigned int ca_dwmci_get_mmc_clock(struct dwmci_host *host, uint freq)
>> +{
>> + struct ca_dwmmc_priv_data *priv = host->priv;
>> + u8 sd_clk_sel = readl(priv->sd_dll_reg) & SD_CLK_SEL_MASK;
>> + u8 clk_div;
>> +
>> + switch (sd_clk_sel) {
>> + case 2:
>> + clk_div = 1;
>> + break;
>> + case 1:
>> + clk_div = 2;
>> + break;
>> + default:
>> + clk_div = 4;
>> + }
>> +
>> + return SD_SCLK_MAX / clk_div / (host->div + 1);
>> +}
>> +
>> +static int ca_dwmmc_ofdata_to_platdata(struct udevice *dev)
>> +{
>> + struct ca_dwmmc_priv_data *priv = dev_get_priv(dev);
>> + struct dwmci_host *host = &priv->host;
>> + u32 tmp;
>> +
>> + host->name = dev->name;
>> + host->dev_index = 0;
>> +
>> + host->buswidth = dev_read_u32_default(dev, "bus-width", 1);
>> + if (host->buswidth != 1 && host->buswidth != 4)
>> + return -EINVAL;
>> +
>> + host->bus_hz = dev_read_u32_default(dev, "max-frequency", 50000000);
>> + priv->ds = dev_read_u32_default(dev, "io_ds", 0x33);
>> + host->fifo_mode = dev_read_bool(dev, "fifo-mode");
>> +
>> + dev_read_u32(dev, "sd_dll_ctrl", &tmp);
>> + priv->sd_dll_reg = map_sysmem((uintptr_t)tmp, sizeof(uintptr_t));
>> + if (!priv->sd_dll_reg)
>> + return -EINVAL;
>> +
>> + dev_read_u32(dev, "io_drv_ctrl", &tmp);
>> + priv->io_drv_reg = map_sysmem((uintptr_t)tmp, sizeof(uintptr_t));
>> + if (!priv->io_drv_reg)
>> + return -EINVAL;
>> +
>> + host->ioaddr = dev_read_addr_ptr(dev);
>> + if (host->ioaddr == (void *)FDT_ADDR_T_NONE) {
>> + printf("DWMMC: base address is invalid\n");
>> + return -EINVAL;
>> + }
>> +
>> + host->priv = priv;
>> +
>> + return 0;
>> +}
>> +
>> +struct dm_mmc_ops ca_dwmci_dm_ops;
>> +
>> +static int ca_dwmmc_probe(struct udevice *dev)
>> +{
>> + struct ca_mmc_plat *plat = dev_get_platdata(dev);
>> + struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
>> + struct ca_dwmmc_priv_data *priv = dev_get_priv(dev);
>> + struct dwmci_host *host = &priv->host;
>> +
>> + memcpy(&ca_dwmci_dm_ops, &dm_dwmci_ops, sizeof(struct dm_mmc_ops));
>> +
>> + dwmci_setup_cfg(&plat->cfg, host, host->bus_hz, MIN_FREQ);
>> + if (host->buswidth == 1) {
>> + (&plat->cfg)->host_caps &= ~MMC_MODE_8BIT;
>> + (&plat->cfg)->host_caps &= ~MMC_MODE_4BIT;
>> + }
>> +
>> + host->mmc = &plat->mmc;
>> + host->mmc->priv = &priv->host;
>> + upriv->mmc = host->mmc;
>> + host->mmc->dev = dev;
>> + host->clksel = ca_dwmci_clksel;
>> + host->board_init = ca_dwmci_board_init;
>> + host->get_mmc_clk = ca_dwmci_get_mmc_clock;
>> +
>> + return dwmci_probe(dev);
>> +}
>> +
>> +static int ca_dwmmc_bind(struct udevice *dev)
>> +{
>> + struct ca_mmc_plat *plat = dev_get_platdata(dev);
>> +
>> + return dwmci_bind(dev, &plat->mmc, &plat->cfg);
>> +}
>> +
>> +static const struct udevice_id ca_dwmmc_ids[] = {
>> + { .compatible = "snps,dw-cortina" },
>> + { }
>> +};
>> +
>> +U_BOOT_DRIVER(ca_dwmmc_drv) = {
>> + .name = "cortina_dwmmc",
>> + .id = UCLASS_MMC,
>> + .of_match = ca_dwmmc_ids,
>> + .ofdata_to_platdata = ca_dwmmc_ofdata_to_platdata,
>> + .bind = ca_dwmmc_bind,
>> + .ops = &ca_dwmci_dm_ops,
>> + .probe = ca_dwmmc_probe,
>> + .priv_auto_alloc_size = sizeof(struct ca_dwmmc_priv_data),
>> + .platdata_auto_alloc_size = sizeof(struct ca_mmc_plat),
>> +};
>>
>
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v2 0/8] Cortina Access Drivers Package 2
2020-03-19 0:16 ` Alex Nemirovsky
@ 2020-03-19 10:16 ` Daniel Schwierzeck
0 siblings, 0 replies; 18+ messages in thread
From: Daniel Schwierzeck @ 2020-03-19 10:16 UTC (permalink / raw)
To: u-boot
Hi Alex,
you should always CC the maintainers of the affected sub-systems or
architecture. Otherwise it's random if a maintainer reads through the
list and discovers your patches ;)
You can find out with get_maintainers.pl like this:
$ ./scripts/get_maintainer.pl drivers/i2c/
Heiko Schocher <hs@denx.de> (maintainer:I2C)
u-boot at lists.denx.de (open list)
Am 19.03.20 um 01:16 schrieb Alex Nemirovsky:
> Hi Tom,
> Are we still blocked on this set until the upcoming 2020.4 release?
>
>> On Feb 26, 2020, at 11:58 PM, Alex Nemirovsky <alex.nemirovsky@cortina-access.com> wrote:
>>
>>
>> This release adds the following drivers and
>> integrates support into the Cortina Access
>> Presidio Engineering Board:
>>
>> CAxxxx SoC eMMC/SD controller
>> CAxxxx SoC I2C controller
>> CAxxxx Soc LED controller
>> CAxxxx SPI NAND and NOR controller
>>
>> Changes in v2:
>> - Add I2C controller
>> - Add LED controller
>> - Add SPI NAND and NOR controller
>>
>> Alex Nemirovsky (3):
>> board: presidio-asic: Add eMMC board support
>> board: presidio-asic: Add I2C support
>> board: presidio-asic: Add SPI NAND and NOR support
>>
>> Arthur Li (2):
>> mmc: ca_dw_mmc: add DesignWare based DM support for CAxxxx SoCs
>> i2c: i2c-cortina: added CAxxxx I2C support
>>
>> Jway Lin (2):
>> led: led_cortina: Add CAxxx LED support
>> board: presidio: add LED support
>>
>> Pengpeng Chen (1):
>> spi: ca_sflash: Add CAxxxx SPI Flash Controller
>>
>> MAINTAINERS | 10 +
>> arch/arm/dts/ca-presidio-engboard.dts | 39 +-
>> board/cortina/presidio-asic/presidio.c | 16 +-
>> configs/cortina_presidio-asic-emmc_defconfig | 38 ++
>> configs/cortina_presidio-asic-spi-nand_defconfig | 48 ++
>> configs/cortina_presidio-asic-spi-nor_defconfig | 59 +++
>> drivers/i2c/Kconfig | 7 +
>> drivers/i2c/Makefile | 1 +
>> drivers/i2c/i2c-cortina.c | 346 ++++++++++++++
>> drivers/i2c/i2c-cortina.h | 92 ++++
>> drivers/led/Kconfig | 8 +
>> drivers/led/Makefile | 1 +
>> drivers/led/led_cortina.c | 308 ++++++++++++
>> drivers/mmc/Kconfig | 11 +
>> drivers/mmc/Makefile | 1 +
>> drivers/mmc/ca_dw_mmc.c | 181 +++++++
>> drivers/spi/Kconfig | 8 +
>> drivers/spi/Makefile | 1 +
>> drivers/spi/ca_sflash.c | 575 +++++++++++++++++++++++
>> 19 files changed, 1744 insertions(+), 6 deletions(-)
>> create mode 100644 configs/cortina_presidio-asic-emmc_defconfig
>> create mode 100644 configs/cortina_presidio-asic-spi-nand_defconfig
>> create mode 100644 configs/cortina_presidio-asic-spi-nor_defconfig
>> create mode 100644 drivers/i2c/i2c-cortina.c
>> create mode 100644 drivers/i2c/i2c-cortina.h
>> create mode 100644 drivers/led/led_cortina.c
>> create mode 100644 drivers/mmc/ca_dw_mmc.c
>> create mode 100644 drivers/spi/ca_sflash.c
>>
>> --
>> 2.7.4
>>
>
--
- Daniel
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v2 0/8] Cortina Access Drivers Package 2
@ 2020-03-19 1:52 Alex Nemirovsky
0 siblings, 0 replies; 18+ messages in thread
From: Alex Nemirovsky @ 2020-03-19 1:52 UTC (permalink / raw)
To: u-boot
This release adds the following drivers and
integrates support into the Cortina Access
Presidio Engineering Board:
CAxxxx SoC eMMC/SD controller
CAxxxx SoC I2C controller
CAxxxx Soc LED controller
CAxxxx SPI NAND and NOR controller
Changes in v3:
- Fixup syntax issues related to checkpatch.pl cleanup
Changes in v2:
- Add I2C controller
- Add LED controller
- Add SPI NAND and NOR controller
Alex Nemirovsky (3):
board: presidio-asic: Add eMMC board support
board: presidio-asic: Add I2C support
board: presidio-asic: Add SPI NAND and NOR support
Arthur Li (2):
mmc: ca_dw_mmc: add DesignWare based DM support for CAxxxx SoCs
i2c: i2c-cortina: added CAxxxx I2C support
Jway Lin (2):
led: led_cortina: Add CAxxx LED support
board: presidio: add LED support
Pengpeng Chen (1):
spi: ca_sflash: Add CAxxxx SPI Flash Controller
MAINTAINERS | 10 +
arch/arm/dts/ca-presidio-engboard.dts | 39 +-
board/cortina/presidio-asic/presidio.c | 16 +-
configs/cortina_presidio-asic-emmc_defconfig | 38 ++
configs/cortina_presidio-asic-spi-nand_defconfig | 48 ++
configs/cortina_presidio-asic-spi-nor_defconfig | 59 +++
drivers/i2c/Kconfig | 7 +
drivers/i2c/Makefile | 1 +
drivers/i2c/i2c-cortina.c | 346 ++++++++++++++
drivers/i2c/i2c-cortina.h | 92 ++++
drivers/led/Kconfig | 8 +
drivers/led/Makefile | 1 +
drivers/led/led_cortina.c | 308 ++++++++++++
drivers/mmc/Kconfig | 11 +
drivers/mmc/Makefile | 1 +
drivers/mmc/ca_dw_mmc.c | 181 +++++++
drivers/spi/Kconfig | 8 +
drivers/spi/Makefile | 1 +
drivers/spi/ca_sflash.c | 576 +++++++++++++++++++++++
19 files changed, 1745 insertions(+), 6 deletions(-)
create mode 100644 configs/cortina_presidio-asic-emmc_defconfig
create mode 100644 configs/cortina_presidio-asic-spi-nand_defconfig
create mode 100644 configs/cortina_presidio-asic-spi-nor_defconfig
create mode 100644 drivers/i2c/i2c-cortina.c
create mode 100644 drivers/i2c/i2c-cortina.h
create mode 100644 drivers/led/led_cortina.c
create mode 100644 drivers/mmc/ca_dw_mmc.c
create mode 100644 drivers/spi/ca_sflash.c
--
2.7.4
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v2 0/8] Cortina Access Drivers Package 2
2020-02-27 7:58 Alex Nemirovsky
@ 2020-03-19 0:16 ` Alex Nemirovsky
2020-03-19 10:16 ` Daniel Schwierzeck
0 siblings, 1 reply; 18+ messages in thread
From: Alex Nemirovsky @ 2020-03-19 0:16 UTC (permalink / raw)
To: u-boot
Hi Tom,
Are we still blocked on this set until the upcoming 2020.4 release?
> On Feb 26, 2020, at 11:58 PM, Alex Nemirovsky <alex.nemirovsky@cortina-access.com> wrote:
>
>
> This release adds the following drivers and
> integrates support into the Cortina Access
> Presidio Engineering Board:
>
> CAxxxx SoC eMMC/SD controller
> CAxxxx SoC I2C controller
> CAxxxx Soc LED controller
> CAxxxx SPI NAND and NOR controller
>
> Changes in v2:
> - Add I2C controller
> - Add LED controller
> - Add SPI NAND and NOR controller
>
> Alex Nemirovsky (3):
> board: presidio-asic: Add eMMC board support
> board: presidio-asic: Add I2C support
> board: presidio-asic: Add SPI NAND and NOR support
>
> Arthur Li (2):
> mmc: ca_dw_mmc: add DesignWare based DM support for CAxxxx SoCs
> i2c: i2c-cortina: added CAxxxx I2C support
>
> Jway Lin (2):
> led: led_cortina: Add CAxxx LED support
> board: presidio: add LED support
>
> Pengpeng Chen (1):
> spi: ca_sflash: Add CAxxxx SPI Flash Controller
>
> MAINTAINERS | 10 +
> arch/arm/dts/ca-presidio-engboard.dts | 39 +-
> board/cortina/presidio-asic/presidio.c | 16 +-
> configs/cortina_presidio-asic-emmc_defconfig | 38 ++
> configs/cortina_presidio-asic-spi-nand_defconfig | 48 ++
> configs/cortina_presidio-asic-spi-nor_defconfig | 59 +++
> drivers/i2c/Kconfig | 7 +
> drivers/i2c/Makefile | 1 +
> drivers/i2c/i2c-cortina.c | 346 ++++++++++++++
> drivers/i2c/i2c-cortina.h | 92 ++++
> drivers/led/Kconfig | 8 +
> drivers/led/Makefile | 1 +
> drivers/led/led_cortina.c | 308 ++++++++++++
> drivers/mmc/Kconfig | 11 +
> drivers/mmc/Makefile | 1 +
> drivers/mmc/ca_dw_mmc.c | 181 +++++++
> drivers/spi/Kconfig | 8 +
> drivers/spi/Makefile | 1 +
> drivers/spi/ca_sflash.c | 575 +++++++++++++++++++++++
> 19 files changed, 1744 insertions(+), 6 deletions(-)
> create mode 100644 configs/cortina_presidio-asic-emmc_defconfig
> create mode 100644 configs/cortina_presidio-asic-spi-nand_defconfig
> create mode 100644 configs/cortina_presidio-asic-spi-nor_defconfig
> create mode 100644 drivers/i2c/i2c-cortina.c
> create mode 100644 drivers/i2c/i2c-cortina.h
> create mode 100644 drivers/led/led_cortina.c
> create mode 100644 drivers/mmc/ca_dw_mmc.c
> create mode 100644 drivers/spi/ca_sflash.c
>
> --
> 2.7.4
>
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v2 0/8] Cortina Access Drivers Package 2
@ 2020-02-27 7:58 Alex Nemirovsky
2020-03-19 0:16 ` Alex Nemirovsky
0 siblings, 1 reply; 18+ messages in thread
From: Alex Nemirovsky @ 2020-02-27 7:58 UTC (permalink / raw)
To: u-boot
This release adds the following drivers and
integrates support into the Cortina Access
Presidio Engineering Board:
CAxxxx SoC eMMC/SD controller
CAxxxx SoC I2C controller
CAxxxx Soc LED controller
CAxxxx SPI NAND and NOR controller
Changes in v2:
- Add I2C controller
- Add LED controller
- Add SPI NAND and NOR controller
Alex Nemirovsky (3):
board: presidio-asic: Add eMMC board support
board: presidio-asic: Add I2C support
board: presidio-asic: Add SPI NAND and NOR support
Arthur Li (2):
mmc: ca_dw_mmc: add DesignWare based DM support for CAxxxx SoCs
i2c: i2c-cortina: added CAxxxx I2C support
Jway Lin (2):
led: led_cortina: Add CAxxx LED support
board: presidio: add LED support
Pengpeng Chen (1):
spi: ca_sflash: Add CAxxxx SPI Flash Controller
MAINTAINERS | 10 +
arch/arm/dts/ca-presidio-engboard.dts | 39 +-
board/cortina/presidio-asic/presidio.c | 16 +-
configs/cortina_presidio-asic-emmc_defconfig | 38 ++
configs/cortina_presidio-asic-spi-nand_defconfig | 48 ++
configs/cortina_presidio-asic-spi-nor_defconfig | 59 +++
drivers/i2c/Kconfig | 7 +
drivers/i2c/Makefile | 1 +
drivers/i2c/i2c-cortina.c | 346 ++++++++++++++
drivers/i2c/i2c-cortina.h | 92 ++++
drivers/led/Kconfig | 8 +
drivers/led/Makefile | 1 +
drivers/led/led_cortina.c | 308 ++++++++++++
drivers/mmc/Kconfig | 11 +
drivers/mmc/Makefile | 1 +
drivers/mmc/ca_dw_mmc.c | 181 +++++++
drivers/spi/Kconfig | 8 +
drivers/spi/Makefile | 1 +
drivers/spi/ca_sflash.c | 575 +++++++++++++++++++++++
19 files changed, 1744 insertions(+), 6 deletions(-)
create mode 100644 configs/cortina_presidio-asic-emmc_defconfig
create mode 100644 configs/cortina_presidio-asic-spi-nand_defconfig
create mode 100644 configs/cortina_presidio-asic-spi-nor_defconfig
create mode 100644 drivers/i2c/i2c-cortina.c
create mode 100644 drivers/i2c/i2c-cortina.h
create mode 100644 drivers/led/led_cortina.c
create mode 100644 drivers/mmc/ca_dw_mmc.c
create mode 100644 drivers/spi/ca_sflash.c
--
2.7.4
^ permalink raw reply [flat|nested] 18+ messages in thread
end of thread, other threads:[~2020-03-24 21:18 UTC | newest]
Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-20 0:57 [PATCH v2 0/8] Cortina Access Drivers Package 2 Alex Nemirovsky
2020-03-20 0:57 ` [PATCH v2 1/8] mmc: ca_dw_mmc: add DesignWare based DM support for CAxxxx SoCs Alex Nemirovsky
2020-03-24 7:16 ` Jaehoon Chung
2020-03-24 21:18 ` Alex Nemirovsky
2020-03-20 0:57 ` [PATCH v2 2/8] board: presidio-asic: Add eMMC board support Alex Nemirovsky
2020-03-20 0:57 ` [PATCH v2 3/8] i2c: i2c-cortina: added CAxxxx I2C support Alex Nemirovsky
2020-03-20 6:25 ` Heiko Schocher
2020-03-20 0:57 ` [PATCH v2 4/8] board: presidio-asic: Add " Alex Nemirovsky
2020-03-20 0:57 ` [PATCH v2 5/8] led: led_cortina: Add CAxxx LED support Alex Nemirovsky
2020-03-23 15:37 ` Simon Glass
2020-03-20 0:57 ` [PATCH v2 6/8] board: presidio: add " Alex Nemirovsky
2020-03-23 15:37 ` Simon Glass
2020-03-20 0:57 ` [PATCH v2 7/8] spi: ca_sflash: Add CAxxxx SPI Flash Controller Alex Nemirovsky
2020-03-20 0:57 ` [PATCH v2 8/8] board: presidio-asic: Add SPI NAND and NOR support Alex Nemirovsky
-- strict thread matches above, loose matches on Subject: below --
2020-03-19 1:52 [PATCH v2 0/8] Cortina Access Drivers Package 2 Alex Nemirovsky
2020-02-27 7:58 Alex Nemirovsky
2020-03-19 0:16 ` Alex Nemirovsky
2020-03-19 10:16 ` Daniel Schwierzeck
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.