[PATCH] arm64: dts: odroid: add spicc0 controller node

2020-06-18 Thread Hyeonki Hong
Add enabled spicc0 controller node with annotations describing the
physical SPI0 pin number based on the 40 pin header on the Odroid
board.

Signed-off-by: Hyeonki Hong 
---
 .../boot/dts/amlogic/meson-g12b-odroid-n2.dts | 26 +--
 .../boot/dts/amlogic/meson-sm1-odroid-c4.dts  | 24 -
 2 files changed, 47 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dts 
b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dts
index 169ea283d4ee..ec6d345caaae 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dts
@@ -16,8 +16,9 @@
model = "Hardkernel ODROID-N2";
 
aliases {
-   serial0 = _AO;
ethernet0 = 
+   serial0 = _AO;
+   spi0 = 
};
 
chosen {
@@ -328,7 +329,7 @@
 
 _mdio {
external_phy: ethernet-phy@0 {
-   /* Realtek RTL8211F (0x001cc916) */ 
+   /* Realtek RTL8211F (0x001cc916) */
reg = <0>;
max-speed = <1000>;
 
@@ -451,6 +452,27 @@
vqmmc-supply = <_1v8>;
 };
 
+ {
+   status = "okay";
+
+   /*
+* 40 Pin Header : MOSI(GPIOX.8->19 Pin),
+* MISO(GPIOX.9->21 Pin),
+* SPI0_CLK(GPIOX.11->23 Pin)
+* SPI_CE0(GPIOX.10->24 Pin),
+*/
+   pinctrl-names = "default";
+   pinctrl-0 = <_x_pins>, <_ss0_x_pins>;
+
+   spidev@0 {
+   compatible = "spidev";
+   status = "okay";
+   /* spi default max clock 100Mhz */
+   spi-max-frequency = <1>;
+   reg = <0>;
+   };
+};
+
 /*
  * EMMC_D4, EMMC_D5, EMMC_D6 and EMMC_D7 pins are shared between SPI NOR pins
  * and eMMC Data 4 to 7 pins.
diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid-c4.dts 
b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid-c4.dts
index 00d90b30f8b4..f809b2ba6b15 100644
--- a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid-c4.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid-c4.dts
@@ -14,8 +14,9 @@
model = "Hardkernel ODROID-C4";
 
aliases {
-   serial0 = _AO;
ethernet0 = 
+   serial0 = _AO;
+   spi0 = 
};
 
chosen {
@@ -381,6 +382,27 @@
vqmmc-supply = <_1v8>;
 };
 
+ {
+   status = "okay";
+
+   /*
+* 40 Pin Header : MOSI(GPIOX.8->19 Pin),
+* MISO(GPIOX.9->21 Pin),
+* SPI0_CLK(GPIOX.11->23 Pin)
+* SPI_CE0(GPIOX.10->24 Pin),
+*/
+   pinctrl-names = "default";
+   pinctrl-0 = <_x_pins>, <_ss0_x_pins>;
+
+   spidev@0 {
+   compatible = "spidev";
+   status = "okay";
+   /* spi default max clock 100Mhz */
+   spi-max-frequency = <1>;
+   reg = <0>;
+   };
+};
+
 _AO {
status = "okay";
pinctrl-0 = <_ao_a_pins>;
-- 
2.17.1



[PATCH] [v2] pinctrl: meson: fix drive strength register and bit calculation

2020-06-17 Thread Hyeonki Hong
If a GPIO bank has greater than 16 pins, PAD_DS_REG is split into two
or more registers. However, when register and bit were calculated, the
first register defined in the bank was used, and the bit was calculated
based on the first pin. This causes problems in setting the driving
strength.

The following method was used to solve this problem:
A bit is calculated first using predefined strides. Then, If the bit is
32 or more, the register is changed by the quotient of the bit divided
by 32. And the bit is set to the remainder.

Signed-off-by: Hyeonki Hong 
---
 drivers/pinctrl/meson/pinctrl-meson.c | 11 +++
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/pinctrl/meson/pinctrl-meson.c 
b/drivers/pinctrl/meson/pinctrl-meson.c
index bbc919bef2bf..bf116c2e45c0 100644
--- a/drivers/pinctrl/meson/pinctrl-meson.c
+++ b/drivers/pinctrl/meson/pinctrl-meson.c
@@ -56,6 +56,10 @@
 #include "../pinctrl-utils.h"
 #include "pinctrl-meson.h"
 
+static const unsigned int meson_bit_strides[] = {
+   1, 1, 1, 1, 1, 2, 1
+};
+
 /**
  * meson_get_bank() - find the bank containing a given pin
  *
@@ -96,8 +100,9 @@ static void meson_calc_reg_and_bit(struct meson_bank *bank, 
unsigned int pin,
 {
struct meson_reg_desc *desc = >regs[reg_type];
 
-   *reg = desc->reg * 4;
-   *bit = desc->bit + pin - bank->first;
+   *bit = (desc->bit + pin - bank->first) * meson_bit_strides[reg_type];
+   *reg = (desc->reg + (*bit / 32)) * 4;
+   *bit &= 0x1f;
 }
 
 static int meson_get_groups_count(struct pinctrl_dev *pcdev)
@@ -314,7 +319,6 @@ static int meson_pinconf_set_drive_strength(struct 
meson_pinctrl *pc,
return ret;
 
meson_calc_reg_and_bit(bank, pin, REG_DS, , );
-   bit = bit << 1;
 
if (drive_strength_ua <= 500) {
ds_val = MESON_PINCONF_DRV_500UA;
@@ -441,7 +445,6 @@ static int meson_pinconf_get_drive_strength(struct 
meson_pinctrl *pc,
return ret;
 
meson_calc_reg_and_bit(bank, pin, REG_DS, , );
-   bit = bit << 1;
 
ret = regmap_read(pc->reg_ds, reg, );
if (ret)
-- 
2.17.1



[PATCH] pinctrl: meson: fix drive strength register and bit calculation

2020-06-10 Thread Hyeonki Hong
On Wed, Jun 10, 2020 at 03:09:42PM +0200, Jerome Brunet wrote:
> 
> On Wed 10 Jun 2020 at 06:13, hhk7...@gmail.com wrote:
> 
> > From: Hyeonki Hong 
> >
> > If a GPIO bank has greater than 16 pins, PAD_DS_REG is split into two
> > registers. However, when register and bit were calculated, the first
> > register defined in the bank was used, and the bit was calculated based
> > on the first pin. This causes problems in setting the driving strength.
> >
> > Solved the problem by changing the bit using a mask and selecting the
> > next register when the bit exceeds 15.
> 
> This fixes the case of GPIOX on g12 which goes up to 18 yes but the same
> problem will happen again a if bank ever goes past 31 pins. In such case
> the problem would apply to all reg types.
> 
> I would prefer if it was solved in a more generic fashion, like defining
> a "stride" table with the values of each reg type. This table can common
> to all aml SoCs for now but eventually it probably need to be SoC
> specific.
> 
> This would allow to :
> A) handle the case you are reporting in a generic (future proof) way
> B) remove the weird "bit = bit << 1;" calc in place in the get/set of
> the drive strengh pinconf

If all amlogic SoC has same register style, I think the code below is fine.

static const unsigned int meson_bit_strides[] = {
0, 0, 0, 0, 0, 1, 0
};

static void meson_calc_reg_and_bit(struct meson_bank *bank, unsigned int pin,
   enum meson_reg_type reg_type,
   unsigned int *reg, unsigned int *bit)
{
struct meson_reg_desc *desc = >regs[reg_type];

*bit = (desc->bit + pin - bank->first) << meson_bit_strides[reg_type];
*reg = (desc->reg + (*bit / 32)) * 4;
*bit &= 0x1f;
}

How about this?

> >
> > Signed-off-by: Hyeonki Hong 
> > ---
> >  drivers/pinctrl/meson/pinctrl-meson.c | 7 +++
> >  1 file changed, 7 insertions(+)
> >
> > diff --git a/drivers/pinctrl/meson/pinctrl-meson.c 
> > b/drivers/pinctrl/meson/pinctrl-meson.c
> > index bbc919bef2bf..ef66239b7df5 100644
> > --- a/drivers/pinctrl/meson/pinctrl-meson.c
> > +++ b/drivers/pinctrl/meson/pinctrl-meson.c
> > @@ -98,6 +98,13 @@ static void meson_calc_reg_and_bit(struct meson_bank 
> > *bank, unsigned int pin,
> >
> > *reg = desc->reg * 4;
> > *bit = desc->bit + pin - bank->first;
> > +
> > +   if (reg_type == REG_DS) {
> > +   if (*bit > 15) {
> > +   *bit &= 0xf;
> > +   *reg += 4;
> > +   }
> > +   }
> >  }
> >
> >  static int meson_get_groups_count(struct pinctrl_dev *pcdev)
>