Re: [RFC PATCH v2 05/13] mmc: add nexell driver

2020-04-09 Thread Stefan B.

Hi,

see below my answers to your questions.

Regards
Stefan Bosch


Hi,

thanks a lot for your reply. As you already guessed I have ported the 
outdated U-Boot from FriendlyARM, see:

https://github.com/friendlyarm/u-boot/tree/nanopi2-v2016.01

The original MMC-driver has been nexell_dw_mmc.c, so I renamed it to 
nexell_dw_mmc_dm.c after changing to DM.


I will have a closer look at your suggestions and give you feedback ASAP.


Regards
Stefan Bosch


Am 02.04.20 um 13:03 schrieb Jaehoon Chung:

Hi,

On 3/28/20 6:43 PM, Stefan Bosch wrote:

Changes in relation to FriendlyARM's U-Boot nanopi2-v2016.01:
- mmc: nexell_dw_mmc.c changed to nexell_dw_mmc_dm.c (switched to DM).


It doesn't need to add postfix as _dm.


Ok, I have renamed it to nexell_dw_mmc.c.



Signed-off-by: Stefan Bosch 
---

Changes in v2:
- commit "i2c: mmc: add nexell driver (gpio, i2c, mmc, pwm)" splitted
   into separate commits for gpio, i2c, mmc, pwm.

  drivers/mmc/Kconfig|   6 +
  drivers/mmc/Makefile   |   1 +
  drivers/mmc/nexell_dw_mmc_dm.c | 350 +
  3 files changed, 357 insertions(+)
  create mode 100644 drivers/mmc/nexell_dw_mmc_dm.c

diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index 2f0eedc..bb8e7c0 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -253,6 +253,12 @@ config MMC_DW_SNPS
  This selects support for Synopsys DesignWare Memory Card Interface 
driver
  extensions used in various Synopsys ARC devboards.
  
+config NEXELL_DWMMC

+   bool "Nexell SD/MMC controller support"
+   depends on ARCH_NEXELL
+   depends on MMC_DW
+   default y


Not depends on DM_MMC?

You are right, I have inserted "depends on DM_MMC". I missed this when 
changing to DM.



+
  config MMC_MESON_GX
bool "Meson GX EMMC controller support"
depends on DM_MMC && BLK && ARCH_MESON
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index 9c1f8e5..a7b5a7b 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -43,6 +43,7 @@ obj-$(CONFIG_SH_MMCIF) += sh_mmcif.o
  obj-$(CONFIG_SH_SDHI) += sh_sdhi.o
  obj-$(CONFIG_STM32_SDMMC2) += stm32_sdmmc2.o
  obj-$(CONFIG_JZ47XX_MMC) += jz_mmc.o
+obj-$(CONFIG_NEXELL_DWMMC) += nexell_dw_mmc_dm.o
  
  # SDHCI

  obj-$(CONFIG_MMC_SDHCI)   += sdhci.o
diff --git a/drivers/mmc/nexell_dw_mmc_dm.c b/drivers/mmc/nexell_dw_mmc_dm.c
new file mode 100644
index 000..b06b60d
--- /dev/null
+++ b/drivers/mmc/nexell_dw_mmc_dm.c
@@ -0,0 +1,350 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2016 Nexell
+ * Youngbok, Park 
+ *
+ * (C) Copyright 2019 Stefan Bosch 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define DWMCI_CLKSEL   0x09C
+#define DWMCI_SHIFT_0  0x0
+#define DWMCI_SHIFT_1  0x1
+#define DWMCI_SHIFT_2  0x2
+#define DWMCI_SHIFT_3  0x3
+#define DWMCI_SET_SAMPLE_CLK(x)(x)
+#define DWMCI_SET_DRV_CLK(x)   ((x) << 16)
+#define DWMCI_SET_DIV_RATIO(x) ((x) << 24)
+#define DWMCI_CLKCTRL  0x114
+#define NX_MMC_CLK_DELAY(x, y, a, b)   x) & 0xFF) << 0) |\
+   (((y) & 0x03) << 16) |\
+   (((a) & 0xFF) << 8)  |\
+   (((b) & 0x03) << 24))
+
+struct nexell_mmc_plat {
+   struct mmc_config cfg;
+   struct mmc mmc;
+};
+
+struct nexell_dwmmc_priv {
+   struct clk *clk;
+   struct dwmci_host host;
+   int fifo_size;
+   bool fifo_mode;
+   int frequency;
+   u32 min_freq;
+   u32 max_freq;
+   int d_delay;
+   int d_shift;
+   int s_delay;
+   int s_shift;
+
+};
+
+struct clk *clk_get(const char *id);
+
+static void set_pin_stat(int index, int bit, int value)
+{
+#if !defined(CONFIG_SPL_BUILD)
+   nx_gpio_set_pad_function(index, bit, value);
+#else
+#if defined(CONFIG_ARCH_S5P4418) ||\
+   defined(CONFIG_ARCH_S5P6818)
+
+   unsigned long base[5] = {
+   PHY_BASEADDR_GPIOA, PHY_BASEADDR_GPIOB,
+   PHY_BASEADDR_GPIOC, PHY_BASEADDR_GPIOD,
+   PHY_BASEADDR_GPIOE,
+   };


I don't understand why gpio pin is set in mmc driver?
If nexell soc will change the gpio map and function value, does it needs to add 
other gpio control?


+
+   dw_mmc_set_pin(base[index], bit, value);
+#endif
+#endif
+}
+
+static void nx_dw_mmc_set_pin(struct dwmci_host *host)
+{
+   debug("  %s(): dev_index == %d", __func__, host->dev_index);
+
+   switch (host->dev_index) {
+   case 0:
+   set_pin_stat(0, 29, 1);
+   set_pin_stat(0, 31, 1);
+   set_pin_stat(1, 1, 1);
+   set_pin_stat(1, 3, 1);
+   set_pin_stat(1, 5, 1);
+   set_pin_stat(1, 7, 1);
+   break;
+   case 1:
+   set_pin_stat(3, 22, 

Re: [RFC PATCH v2 04/13] i2c: add nexell driver

2020-04-08 Thread Stefan B.

Hi Heiko,

I assume that patchwork does get the patch-series automatically when I 
send it to u-boot@lists.denx.de, or am I wrong? Perhaps it is in some 
pipeline?


At least the patch-series appeared in U-Boot Digest ("[RFC PATCH v2 
04/13] i2c: add nexell driver" is in Vol 142, Issue 58).



Regards
Stefan

Am 08.04.20 um 06:08 schrieb Heiko Schocher:

Hello Stefan,

Am 28.03.2020 um 10:43 schrieb Stefan Bosch:

Changes in relation to FriendlyARM's U-Boot nanopi2-v2016.01:
- i2c/nx_i2c.c: Some adaptions mainly because of changes in
   "struct udevice".
- several Bugfixes in nx_i2c.c.
- the driver has been for s5p6818 only. Code extended appropriately
   in order s5p4418 is also working.
- "probe_chip" added.

Signed-off-by: Stefan Bosch 
---

Changes in v2:
- commit "i2c: mmc: add nexell driver (gpio, i2c, mmc, pwm)" splitted
   into separate commits for gpio, i2c, mmc, pwm.
- several Bugfixes in nx_i2c.c.
- the i2c-driver has been for s5p6818 only. Code extended approriately
   in order s5p4418 is also working.
- "probe_chip" added to the i2c-driver.
- doc/device-tree-bindings/i2c/nx_i2c.txt added.

  doc/device-tree-bindings/i2c/nx_i2c.txt |  28 ++
  drivers/i2c/Kconfig |   9 +
  drivers/i2c/Makefile    |   1 +
  drivers/i2c/nx_i2c.c    | 649 


  4 files changed, 687 insertions(+)
  create mode 100644 doc/device-tree-bindings/i2c/nx_i2c.txt
  create mode 100644 drivers/i2c/nx_i2c.c


I do not find this patch in patchwork ...

Thanks for splitting the big patch into several patches.

Reviewed-by: Heiko Schocher 

bye,
Heiko


Re: [RFC PATCH v2 05/13] mmc: add nexell driver

2020-04-02 Thread Stefan B.

Hi,

thanks a lot for your reply. As you already guessed I have ported the 
outdated U-Boot from FriendlyARM, see:

https://github.com/friendlyarm/u-boot/tree/nanopi2-v2016.01

The original MMC-driver has been nexell_dw_mmc.c, so I renamed it to 
nexell_dw_mmc_dm.c after changing to DM.


I will have a closer look at your suggestions and give you feedback ASAP.


Regards
Stefan Bosch


Am 02.04.20 um 13:03 schrieb Jaehoon Chung:

Hi,

On 3/28/20 6:43 PM, Stefan Bosch wrote:

Changes in relation to FriendlyARM's U-Boot nanopi2-v2016.01:
- mmc: nexell_dw_mmc.c changed to nexell_dw_mmc_dm.c (switched to DM).


It doesn't need to add postfix as _dm.



Signed-off-by: Stefan Bosch 
---

Changes in v2:
- commit "i2c: mmc: add nexell driver (gpio, i2c, mmc, pwm)" splitted
   into separate commits for gpio, i2c, mmc, pwm.

  drivers/mmc/Kconfig|   6 +
  drivers/mmc/Makefile   |   1 +
  drivers/mmc/nexell_dw_mmc_dm.c | 350 +
  3 files changed, 357 insertions(+)
  create mode 100644 drivers/mmc/nexell_dw_mmc_dm.c

diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index 2f0eedc..bb8e7c0 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -253,6 +253,12 @@ config MMC_DW_SNPS
  This selects support for Synopsys DesignWare Memory Card Interface 
driver
  extensions used in various Synopsys ARC devboards.
  
+config NEXELL_DWMMC

+   bool "Nexell SD/MMC controller support"
+   depends on ARCH_NEXELL
+   depends on MMC_DW
+   default y


Not depends on DM_MMC?


+
  config MMC_MESON_GX
bool "Meson GX EMMC controller support"
depends on DM_MMC && BLK && ARCH_MESON
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index 9c1f8e5..a7b5a7b 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -43,6 +43,7 @@ obj-$(CONFIG_SH_MMCIF) += sh_mmcif.o
  obj-$(CONFIG_SH_SDHI) += sh_sdhi.o
  obj-$(CONFIG_STM32_SDMMC2) += stm32_sdmmc2.o
  obj-$(CONFIG_JZ47XX_MMC) += jz_mmc.o
+obj-$(CONFIG_NEXELL_DWMMC) += nexell_dw_mmc_dm.o
  
  # SDHCI

  obj-$(CONFIG_MMC_SDHCI)   += sdhci.o
diff --git a/drivers/mmc/nexell_dw_mmc_dm.c b/drivers/mmc/nexell_dw_mmc_dm.c
new file mode 100644
index 000..b06b60d
--- /dev/null
+++ b/drivers/mmc/nexell_dw_mmc_dm.c
@@ -0,0 +1,350 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2016 Nexell
+ * Youngbok, Park 
+ *
+ * (C) Copyright 2019 Stefan Bosch 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define DWMCI_CLKSEL   0x09C
+#define DWMCI_SHIFT_0  0x0
+#define DWMCI_SHIFT_1  0x1
+#define DWMCI_SHIFT_2  0x2
+#define DWMCI_SHIFT_3  0x3
+#define DWMCI_SET_SAMPLE_CLK(x)(x)
+#define DWMCI_SET_DRV_CLK(x)   ((x) << 16)
+#define DWMCI_SET_DIV_RATIO(x) ((x) << 24)
+#define DWMCI_CLKCTRL  0x114
+#define NX_MMC_CLK_DELAY(x, y, a, b)   x) & 0xFF) << 0) |\
+   (((y) & 0x03) << 16) |\
+   (((a) & 0xFF) << 8)  |\
+   (((b) & 0x03) << 24))
+
+struct nexell_mmc_plat {
+   struct mmc_config cfg;
+   struct mmc mmc;
+};
+
+struct nexell_dwmmc_priv {
+   struct clk *clk;
+   struct dwmci_host host;
+   int fifo_size;
+   bool fifo_mode;
+   int frequency;
+   u32 min_freq;
+   u32 max_freq;
+   int d_delay;
+   int d_shift;
+   int s_delay;
+   int s_shift;
+
+};
+
+struct clk *clk_get(const char *id);
+
+static void set_pin_stat(int index, int bit, int value)
+{
+#if !defined(CONFIG_SPL_BUILD)
+   nx_gpio_set_pad_function(index, bit, value);
+#else
+#if defined(CONFIG_ARCH_S5P4418) ||\
+   defined(CONFIG_ARCH_S5P6818)
+
+   unsigned long base[5] = {
+   PHY_BASEADDR_GPIOA, PHY_BASEADDR_GPIOB,
+   PHY_BASEADDR_GPIOC, PHY_BASEADDR_GPIOD,
+   PHY_BASEADDR_GPIOE,
+   };


I don't understand why gpio pin is set in mmc driver?
If nexell soc will change the gpio map and function value, does it needs to add 
other gpio control?


+
+   dw_mmc_set_pin(base[index], bit, value);
+#endif
+#endif
+}
+
+static void nx_dw_mmc_set_pin(struct dwmci_host *host)
+{
+   debug("  %s(): dev_index == %d", __func__, host->dev_index);
+
+   switch (host->dev_index) {
+   case 0:
+   set_pin_stat(0, 29, 1);
+   set_pin_stat(0, 31, 1);
+   set_pin_stat(1, 1, 1);
+   set_pin_stat(1, 3, 1);
+   set_pin_stat(1, 5, 1);
+   set_pin_stat(1, 7, 1);
+   break;
+   case 1:
+   set_pin_stat(3, 22, 1);
+   set_pin_stat(3, 23, 1);
+   set_pin_stat(3, 24, 1);
+   set_pin_stat(3, 25, 1);
+   set_pin_stat(3, 26, 1);
+   set_pin_stat(3, 27, 1);

Re: [RFC PATCH 00/10] arm: add support for SoC S5P4418

2020-02-25 Thread Stefan B.

Hi Amit,

Am 22.02.20 um 14:06 schrieb Amit Tomer:

Hi,

On Tue, Feb 4, 2020 at 1:12 AM Stefan Bosch  wrote:



This patch adds support for SAMSUNG's/NEXELL's ARM Cortex-A9 based
S5P4418 SoC, especially FriendlyARM's NanoPi2 and NanoPC-T2 boards.
It is based on the following FriendlyARM's U-Boot version:
https://github.com/friendlyarm/u-boot/tree/nanopi2-v2016.01.


I don't think this is the right approach, i.e. to take everything from
BSP source as it is and put
it into mainline U-BOOT. AFAIR,  Some of the peripherals present on
these NEXELL SoC's are
compatible with SAMSUNG IP (for instance the UART).
So, are we sure that some of the already existing code in U-BOOT can't
be re-used to drive those
compatible peripherals at-least ?

Thanks
-Amit



You are right, already existing code in U-BOOT should be used where 
possible. So I have reviewed the code (and will review it further). Up 
to now, I have the following proposals for the peripherials indicated:


UART:
Actually the UARTs of the S5P4418 are Amba PrimeCell PL011 compatible, 
therefore the appropriate code is used. S5P6818 does have different 
UARTs which apparently arch/arm/mach-nexell/serial.c is for. Since 
S5P6818 is not supported (yet) I will remove this file.


TIMER:
Currently arch/arm/mach-nexell/timer.c is used. I will try to use 
arch/arm/cpu/armv7/s5p-common/timer.c instead. The timer-registers used 
seem to be the same, but the functions in timer.c are not which is a 
possible pitfall.


PWM:
Currently drivers/pwm/pwm-nexell.c is used. This is a extended version 
of arch/arm/cpu/armv7/s5p-common/pwm.c. I.e. pwm.c is adapted with
"#if defined(CONFIG_ARCH_NEXELL) ... #else" at some places. So my 
proposal is to change s5p-common/pwm.c appropriately to get rid of 
pwm-nexell.c.



Regards
Stefan


Re: [RFC PATCH 03/10] i2c: mmc: add nexell driver (gpio, i2c, mmc, pwm)

2020-02-20 Thread Stefan B.

Hello Heiko,

see below my feedback, please give me further advise where indicated.

Unfortunately there have been some Bugs in the i2c-driver and I learned 
that this driver has not been used at all ("i2c-gpio" has been used 
instead). So I have done several Bugfixes and improvements appart from 
your proposals.



Regards
Stefan


Am 04.02.20 um 07:58 schrieb Heiko Schocher:

Hello Stefan,

Am 03.02.2020 um 21:40 schrieb Stefan Bosch:

Changes in relation to FriendlyARM's U-Boot nanopi2-v2016.01:
- i2c/nx_i2c.c: Some adaptions mainly because of changes in
   "struct udevice".
- mmc: nexell_dw_mmc.c changed to nexell_dw_mmc_dm.c (switched to DM).

Signed-off-by: Stefan Bosch 
---

  drivers/gpio/Kconfig   |   9 +
  drivers/gpio/Makefile  |   1 +
  drivers/gpio/nx_gpio.c | 252 +++
  drivers/i2c/Kconfig    |   9 +
  drivers/i2c/Makefile   |   1 +
  drivers/i2c/nx_i2c.c   | 537 
+

  drivers/mmc/Kconfig    |   6 +
  drivers/mmc/Makefile   |   1 +
  drivers/mmc/nexell_dw_mmc_dm.c | 350 +++
  drivers/pwm/Makefile   |   1 +
  drivers/pwm/pwm-nexell.c   | 252 +++
  drivers/pwm/pwm-nexell.h   |  54 +


Could you please split this patch into 4 parts (i2c, gpio, mmc and
pwm) ?

Thanks!


Ok, I will split this patch.


  12 files changed, 1473 insertions(+)
  create mode 100644 drivers/gpio/nx_gpio.c
  create mode 100644 drivers/i2c/nx_i2c.c
  create mode 100644 drivers/mmc/nexell_dw_mmc_dm.c
  create mode 100644 drivers/pwm/pwm-nexell.c
  create mode 100644 drivers/pwm/pwm-nexell.h


[...]

diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 449046b..e3340de 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -65,3 +65,4 @@ obj-$(CONFIG_PM8916_GPIO)    += pm8916_gpio.o
  obj-$(CONFIG_MT7621_GPIO)    += mt7621_gpio.o
  obj-$(CONFIG_MSCC_SGPIO)    += mscc_sgpio.o
  obj-$(CONFIG_SIFIVE_GPIO)    += sifive-gpio.o
+obj-$(CONFIG_NX_GPIO)    += nx_gpio.o


Please keep lists sorted.


The list is not sorted (at least in no alphabetical order), but I can 
e.g. move "... += nx_gpio.o" one line up?





diff --git a/drivers/gpio/nx_gpio.c b/drivers/gpio/nx_gpio.c
new file mode 100644
index 000..86472f6
--- /dev/null
+++ b/drivers/gpio/nx_gpio.c
@@ -0,0 +1,252 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2016 Nexell
+ * DeokJin, Lee 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct nx_gpio_regs {
+    u32    data;    /* Data register */
+    u32    outputenb;    /* Output Enable register */
+    u32    detmode[2];    /* Detect Mode Register */
+    u32    intenb;    /* Interrupt Enable Register */
+    u32    det;    /* Event Detect Register */
+    u32    pad;    /* Pad Status Register */
+};
+
+struct nx_alive_gpio_regs {
+    u32    pwrgate;    /* Power Gating Register */
+    u32    reserved0[28];    /* Reserved0 */
+    u32    outputenb_reset;/* Alive GPIO Output Enable Reset Register */
+    u32    outputenb;    /* Alive GPIO Output Enable Register */
+    u32    outputenb_read; /* Alive GPIO Output Read Register */
+    u32    reserved1[3];    /* Reserved1 */
+    u32    pad_reset;    /* Alive GPIO Output Reset Register */
+    u32    data;    /* Alive GPIO Output Register */
+    u32    pad_read;    /* Alive GPIO Pad Read Register */
+    u32    reserved2[33];    /* Reserved2 */
+    u32    pad;    /* Alive GPIO Input Value Register */
+};
+
+struct nx_gpio_platdata {
+    void *regs;
+    int gpio_count;
+    const char *bank_name;
+};
+
+static int nx_alive_gpio_is_check(struct udevice *dev)
+{
+    struct nx_gpio_platdata *plat = dev_get_platdata(dev);
+    const char *bank_name = plat->bank_name;
+
+    if (!strcmp(bank_name, "gpio_alv"))
+    return 1;
+
+    return 0;
+}
+
+static int nx_alive_gpio_direction_input(struct udevice *dev, 
unsigned int pin)

+{
+    struct nx_gpio_platdata *plat = dev_get_platdata(dev);
+    struct nx_alive_gpio_regs *const regs = plat->regs;
+
+    setbits_le32(>outputenb_reset, 1 << pin);
+
+    return 0;
+}
+
+static int nx_alive_gpio_direction_output(struct udevice *dev, 
unsigned int pin,

+  int val)
+{
+    struct nx_gpio_platdata *plat = dev_get_platdata(dev);
+    struct nx_alive_gpio_regs *const regs = plat->regs;
+
+    if (val)
+    setbits_le32(>data, 1 << pin);
+    else
+    setbits_le32(>pad_reset, 1 << pin);
+
+    setbits_le32(>outputenb, 1 << pin);
+
+    return 0;
+}
+
+static int nx_alive_gpio_get_value(struct udevice *dev, unsigned int 
pin)

+{
+    struct nx_gpio_platdata *plat = dev_get_platdata(dev);
+    struct nx_alive_gpio_regs *const regs = plat->regs;
+    unsigned int mask = 1UL << pin;
+    unsigned int value;
+
+    value = (readl(>pad_read) & mask) >> pin;
+
+    return value;
+}
+
+static int 

Re: [RFC PATCH 03/10] i2c: mmc: add nexell driver (gpio, i2c, mmc, pwm)

2020-02-04 Thread Stefan B.

Hello Heiko,

thanks a lot for your annotations and suggestions. I will have a look at 
them and give you feedback ASAP.



Regards
Stefan


Am 04.02.20 um 07:58 schrieb Heiko Schocher:

Hello Stefan,

Am 03.02.2020 um 21:40 schrieb Stefan Bosch:

Changes in relation to FriendlyARM's U-Boot nanopi2-v2016.01:
- i2c/nx_i2c.c: Some adaptions mainly because of changes in
   "struct udevice".
- mmc: nexell_dw_mmc.c changed to nexell_dw_mmc_dm.c (switched to DM).

Signed-off-by: Stefan Bosch 
---

  drivers/gpio/Kconfig   |   9 +
  drivers/gpio/Makefile  |   1 +
  drivers/gpio/nx_gpio.c | 252 +++
  drivers/i2c/Kconfig    |   9 +
  drivers/i2c/Makefile   |   1 +
  drivers/i2c/nx_i2c.c   | 537 
+

  drivers/mmc/Kconfig    |   6 +
  drivers/mmc/Makefile   |   1 +
  drivers/mmc/nexell_dw_mmc_dm.c | 350 +++
  drivers/pwm/Makefile   |   1 +
  drivers/pwm/pwm-nexell.c   | 252 +++
  drivers/pwm/pwm-nexell.h   |  54 +


Could you please split this patch into 4 parts (i2c, gpio, mmc and
pwm) ?

Thanks!


  12 files changed, 1473 insertions(+)
  create mode 100644 drivers/gpio/nx_gpio.c
  create mode 100644 drivers/i2c/nx_i2c.c
  create mode 100644 drivers/mmc/nexell_dw_mmc_dm.c
  create mode 100644 drivers/pwm/pwm-nexell.c
  create mode 100644 drivers/pwm/pwm-nexell.h


[...]

diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 449046b..e3340de 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -65,3 +65,4 @@ obj-$(CONFIG_PM8916_GPIO)    += pm8916_gpio.o
  obj-$(CONFIG_MT7621_GPIO)    += mt7621_gpio.o
  obj-$(CONFIG_MSCC_SGPIO)    += mscc_sgpio.o
  obj-$(CONFIG_SIFIVE_GPIO)    += sifive-gpio.o
+obj-$(CONFIG_NX_GPIO)    += nx_gpio.o


Please keep lists sorted.


diff --git a/drivers/gpio/nx_gpio.c b/drivers/gpio/nx_gpio.c
new file mode 100644
index 000..86472f6
--- /dev/null
+++ b/drivers/gpio/nx_gpio.c
@@ -0,0 +1,252 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2016 Nexell
+ * DeokJin, Lee 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct nx_gpio_regs {
+    u32    data;    /* Data register */
+    u32    outputenb;    /* Output Enable register */
+    u32    detmode[2];    /* Detect Mode Register */
+    u32    intenb;    /* Interrupt Enable Register */
+    u32    det;    /* Event Detect Register */
+    u32    pad;    /* Pad Status Register */
+};
+
+struct nx_alive_gpio_regs {
+    u32    pwrgate;    /* Power Gating Register */
+    u32    reserved0[28];    /* Reserved0 */
+    u32    outputenb_reset;/* Alive GPIO Output Enable Reset Register */
+    u32    outputenb;    /* Alive GPIO Output Enable Register */
+    u32    outputenb_read; /* Alive GPIO Output Read Register */
+    u32    reserved1[3];    /* Reserved1 */
+    u32    pad_reset;    /* Alive GPIO Output Reset Register */
+    u32    data;    /* Alive GPIO Output Register */
+    u32    pad_read;    /* Alive GPIO Pad Read Register */
+    u32    reserved2[33];    /* Reserved2 */
+    u32    pad;    /* Alive GPIO Input Value Register */
+};
+
+struct nx_gpio_platdata {
+    void *regs;
+    int gpio_count;
+    const char *bank_name;
+};
+
+static int nx_alive_gpio_is_check(struct udevice *dev)
+{
+    struct nx_gpio_platdata *plat = dev_get_platdata(dev);
+    const char *bank_name = plat->bank_name;
+
+    if (!strcmp(bank_name, "gpio_alv"))
+    return 1;
+
+    return 0;
+}
+
+static int nx_alive_gpio_direction_input(struct udevice *dev, 
unsigned int pin)

+{
+    struct nx_gpio_platdata *plat = dev_get_platdata(dev);
+    struct nx_alive_gpio_regs *const regs = plat->regs;
+
+    setbits_le32(>outputenb_reset, 1 << pin);
+
+    return 0;
+}
+
+static int nx_alive_gpio_direction_output(struct udevice *dev, 
unsigned int pin,

+  int val)
+{
+    struct nx_gpio_platdata *plat = dev_get_platdata(dev);
+    struct nx_alive_gpio_regs *const regs = plat->regs;
+
+    if (val)
+    setbits_le32(>data, 1 << pin);
+    else
+    setbits_le32(>pad_reset, 1 << pin);
+
+    setbits_le32(>outputenb, 1 << pin);
+
+    return 0;
+}
+
+static int nx_alive_gpio_get_value(struct udevice *dev, unsigned int 
pin)

+{
+    struct nx_gpio_platdata *plat = dev_get_platdata(dev);
+    struct nx_alive_gpio_regs *const regs = plat->regs;
+    unsigned int mask = 1UL << pin;
+    unsigned int value;
+
+    value = (readl(>pad_read) & mask) >> pin;
+
+    return value;
+}
+
+static int nx_alive_gpio_set_value(struct udevice *dev, unsigned int 
pin,

+   int val)
+{
+    struct nx_gpio_platdata *plat = dev_get_platdata(dev);
+    struct nx_alive_gpio_regs *const regs = plat->regs;
+
+    if (val)
+    setbits_le32(>data, 1 << pin);
+    else
+    clrbits_le32(>pad_reset, 1 << pin);
+
+    return 0;