All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH linux dev-5.8 v3 00/12] Add NPCM7xx patches to dev-5.8
@ 2021-01-13 19:59 Tomer Maimon
  2021-01-13 19:59 ` [PATCH linux dev-5.8 v3 01/12] clk: npcm7xx: add read only flag to divider clocks Tomer Maimon
                   ` (12 more replies)
  0 siblings, 13 replies; 19+ messages in thread
From: Tomer Maimon @ 2021-01-13 19:59 UTC (permalink / raw)
  To: openbmc; +Cc: Andrew Jeffery, Tomer Maimon, benjaminfair

In this patch set we will like to align with relevant modifications
in Nuvoton OpenBMC Linux kernel 5.4.

Linux upstream current status:
	1. npcm7xx clock driver - adding read only 
		flag to divider clocks, Will be sent to Linux community.
	2. Adding NPCM ADC calibration - Will be sent to Linux vanilla,
		but I am not sure it will be approved.
	3. Add DT restart priority and reset type support - sent to Linux 
		community la but havent approved yet.
	4. persist configuration to the pin control driver - asked by a costumer,
		didnt sent to Linux community.
	5. Add HGPIO pin support to NPCM7xx pinctrl driver - will be sent
		to Linux community
	6. JTAG master driver - will be sent to Linux community once we will 
		have BMC folder.

Changes since version 2:
- Address comments from Joel Stanley

Changes since version 1:
- Address comments from Jonathan Neuschäfer: removing trailing whitespace
	in NPCM watchdog documentation.
- Adding Stanley Chu to NPCM JTAG master driver


Tomer Maimon (12):
  clk: npcm7xx: add read only flag to divider clocks
  dt-binding: iio: add syscon property to NPCM ADC
  iio: adc: add calibration support to npcm ADC
  dts: npcm750: add fuse regmap support node
  dt-binding: watchdog: Add DT restart priority and reset type
  watchdog: npcm: Add DT restart priority and reset type support
  pinctrl: npcm7xx: Add HGPIO pin support to NPCM7xx pinctrl driver
  pinctrl: pinconf: add pin persist configuration
  pinctrl: npcm7xx: Add pin persist configuration support
  spi: npcm-pspi: Add full duplex support
  dt-binding: bmc: add NPCM7XX JTAG master documentation
  misc: npcm7xx-jtag-master: add NPCM7xx JTAG master driver

 .../bindings/bmc/npcm7xx-jtag-master.txt      |  38 +
 .../bindings/iio/adc/nuvoton,npcm-adc.txt     |   2 +
 .../bindings/watchdog/nuvoton,npcm-wdt.txt    |  34 +
 arch/arm/boot/dts/nuvoton-common-npcm7xx.dtsi |   6 +
 drivers/clk/clk-npcm7xx.c                     |  70 +-
 drivers/iio/adc/npcm_adc.c                    | 178 ++++
 drivers/misc/Kconfig                          |   6 +
 drivers/misc/Makefile                         |   1 +
 drivers/misc/npcm7xx-jtag-master.c            | 840 ++++++++++++++++++
 drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c     | 130 ++-
 drivers/pinctrl/pinconf-generic.c             |   3 +
 drivers/spi/spi-npcm-pspi.c                   |  75 +-
 drivers/watchdog/npcm_wdt.c                   | 117 ++-
 13 files changed, 1404 insertions(+), 96 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/bmc/npcm7xx-jtag-master.txt
 create mode 100644 drivers/misc/npcm7xx-jtag-master.c

-- 
2.22.0


^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH linux dev-5.8 v3 01/12] clk: npcm7xx: add read only flag to divider clocks
  2021-01-13 19:59 [PATCH linux dev-5.8 v3 00/12] Add NPCM7xx patches to dev-5.8 Tomer Maimon
@ 2021-01-13 19:59 ` Tomer Maimon
  2021-01-15  6:22   ` Joel Stanley
  2021-01-13 20:00 ` [PATCH linux dev-5.8 v3 02/12] dt-binding: iio: add syscon property to NPCM ADC Tomer Maimon
                   ` (11 subsequent siblings)
  12 siblings, 1 reply; 19+ messages in thread
From: Tomer Maimon @ 2021-01-13 19:59 UTC (permalink / raw)
  To: openbmc; +Cc: Andrew Jeffery, Tomer Maimon, benjaminfair

Add read only flag to all divider clocks except
SPI3 clock.

Signed-off-by: Tomer Maimon <tmaimon77@gmail.com>
---
 drivers/clk/clk-npcm7xx.c | 70 +++++++++++++++++++++------------------
 1 file changed, 38 insertions(+), 32 deletions(-)

diff --git a/drivers/clk/clk-npcm7xx.c b/drivers/clk/clk-npcm7xx.c
index 27a86b7a34db..bf721ec2bbc6 100644
--- a/drivers/clk/clk-npcm7xx.c
+++ b/drivers/clk/clk-npcm7xx.c
@@ -370,67 +370,73 @@ static const struct npcm7xx_clk_div_fixed_data npcm7xx_divs_fx[] __initconst = {
 
 /* configurable dividers: */
 static const struct npcm7xx_clk_div_data npcm7xx_divs[] __initconst = {
-	{NPCM7XX_CLKDIV1, 28, 3, NPCM7XX_CLK_S_ADC,
-	NPCM7XX_CLK_S_TIMER, CLK_DIVIDER_POWER_OF_TWO, 0, NPCM7XX_CLK_ADC},
+	{NPCM7XX_CLKDIV1, 28, 3, NPCM7XX_CLK_S_ADC, NPCM7XX_CLK_S_TIMER,
+		CLK_DIVIDER_READ_ONLY | CLK_DIVIDER_POWER_OF_TWO, 0,
+		NPCM7XX_CLK_ADC},
 	/*30-28 ADCCKDIV*/
-	{NPCM7XX_CLKDIV1, 26, 2, NPCM7XX_CLK_S_AHB,
-	NPCM7XX_CLK_S_AXI, 0, CLK_IS_CRITICAL, NPCM7XX_CLK_AHB},
+	{NPCM7XX_CLKDIV1, 26, 2, NPCM7XX_CLK_S_AHB, NPCM7XX_CLK_S_AXI,
+		CLK_DIVIDER_READ_ONLY, CLK_IS_CRITICAL, NPCM7XX_CLK_AHB},
 	/*27-26 CLK4DIV*/
 	{NPCM7XX_CLKDIV1, 21, 5, NPCM7XX_CLK_S_TIMER,
-	NPCM7XX_CLK_S_TIM_MUX, 0, 0, NPCM7XX_CLK_TIMER},
+	NPCM7XX_CLK_S_TIM_MUX, CLK_DIVIDER_READ_ONLY, 0, NPCM7XX_CLK_TIMER},
 	/*25-21 TIMCKDIV*/
 	{NPCM7XX_CLKDIV1, 16, 5, NPCM7XX_CLK_S_UART,
-	NPCM7XX_CLK_S_UART_MUX, 0, 0, NPCM7XX_CLK_UART},
+	NPCM7XX_CLK_S_UART_MUX, CLK_DIVIDER_READ_ONLY, 0, NPCM7XX_CLK_UART},
 	/*20-16 UARTDIV*/
 	{NPCM7XX_CLKDIV1, 11, 5, NPCM7XX_CLK_S_MMC,
-	NPCM7XX_CLK_S_SD_MUX, 0, 0, NPCM7XX_CLK_MMC},
+	NPCM7XX_CLK_S_SD_MUX, CLK_DIVIDER_READ_ONLY, 0, NPCM7XX_CLK_MMC},
 	/*15-11 MMCCKDIV*/
 	{NPCM7XX_CLKDIV1, 6, 5, NPCM7XX_CLK_S_SPI3,
 	NPCM7XX_CLK_S_AHB, 0, 0, NPCM7XX_CLK_SPI3},
 	/*10-6 AHB3CKDIV*/
 	{NPCM7XX_CLKDIV1, 2, 4, NPCM7XX_CLK_S_PCI,
-	NPCM7XX_CLK_S_GFX_MUX, 0, 0, NPCM7XX_CLK_PCI},
+	NPCM7XX_CLK_S_GFX_MUX, CLK_DIVIDER_READ_ONLY, 0, NPCM7XX_CLK_PCI},
 	/*5-2 PCICKDIV*/
-	{NPCM7XX_CLKDIV1, 0, 1, NPCM7XX_CLK_S_AXI,
-	NPCM7XX_CLK_S_CPU_MUX, CLK_DIVIDER_POWER_OF_TWO, CLK_IS_CRITICAL,
-	NPCM7XX_CLK_AXI},/*0 CLK2DIV*/
+	{NPCM7XX_CLKDIV1, 0, 1, NPCM7XX_CLK_S_AXI, NPCM7XX_CLK_S_CPU_MUX,
+		CLK_DIVIDER_READ_ONLY | CLK_DIVIDER_POWER_OF_TWO,
+		CLK_IS_CRITICAL, NPCM7XX_CLK_AXI},/*0 CLK2DIV*/
 
-	{NPCM7XX_CLKDIV2, 30, 2, NPCM7XX_CLK_S_APB4,
-	NPCM7XX_CLK_S_AHB, CLK_DIVIDER_POWER_OF_TWO, 0, NPCM7XX_CLK_APB4},
+	{NPCM7XX_CLKDIV2, 30, 2, NPCM7XX_CLK_S_APB4, NPCM7XX_CLK_S_AHB,
+		CLK_DIVIDER_READ_ONLY| CLK_DIVIDER_POWER_OF_TWO, 0,
+		NPCM7XX_CLK_APB4},
 	/*31-30 APB4CKDIV*/
-	{NPCM7XX_CLKDIV2, 28, 2, NPCM7XX_CLK_S_APB3,
-	NPCM7XX_CLK_S_AHB, CLK_DIVIDER_POWER_OF_TWO, 0, NPCM7XX_CLK_APB3},
+	{NPCM7XX_CLKDIV2, 28, 2, NPCM7XX_CLK_S_APB3, NPCM7XX_CLK_S_AHB,
+		CLK_DIVIDER_READ_ONLY| CLK_DIVIDER_POWER_OF_TWO, 0,
+		NPCM7XX_CLK_APB3},
 	/*29-28 APB3CKDIV*/
-	{NPCM7XX_CLKDIV2, 26, 2, NPCM7XX_CLK_S_APB2,
-	NPCM7XX_CLK_S_AHB, CLK_DIVIDER_POWER_OF_TWO, 0, NPCM7XX_CLK_APB2},
+	{NPCM7XX_CLKDIV2, 26, 2, NPCM7XX_CLK_S_APB2, NPCM7XX_CLK_S_AHB,
+		CLK_DIVIDER_READ_ONLY | CLK_DIVIDER_POWER_OF_TWO, 0,
+		NPCM7XX_CLK_APB2},
 	/*27-26 APB2CKDIV*/
-	{NPCM7XX_CLKDIV2, 24, 2, NPCM7XX_CLK_S_APB1,
-	NPCM7XX_CLK_S_AHB, CLK_DIVIDER_POWER_OF_TWO, 0, NPCM7XX_CLK_APB1},
+	{NPCM7XX_CLKDIV2, 24, 2, NPCM7XX_CLK_S_APB1, NPCM7XX_CLK_S_AHB,
+		CLK_DIVIDER_READ_ONLY | CLK_DIVIDER_POWER_OF_TWO, 0,
+		NPCM7XX_CLK_APB1},
 	/*25-24 APB1CKDIV*/
-	{NPCM7XX_CLKDIV2, 22, 2, NPCM7XX_CLK_S_APB5,
-	NPCM7XX_CLK_S_AHB, CLK_DIVIDER_POWER_OF_TWO, 0, NPCM7XX_CLK_APB5},
+	{NPCM7XX_CLKDIV2, 22, 2, NPCM7XX_CLK_S_APB5, NPCM7XX_CLK_S_AHB,
+		CLK_DIVIDER_READ_ONLY | CLK_DIVIDER_POWER_OF_TWO, 0,
+		NPCM7XX_CLK_APB5},
 	/*23-22 APB5CKDIV*/
-	{NPCM7XX_CLKDIV2, 16, 5, NPCM7XX_CLK_S_CLKOUT,
-	NPCM7XX_CLK_S_CLKOUT_MUX, 0, 0, NPCM7XX_CLK_CLKOUT},
+	{NPCM7XX_CLKDIV2, 16, 5, NPCM7XX_CLK_S_CLKOUT, NPCM7XX_CLK_S_CLKOUT_MUX,
+		 CLK_DIVIDER_READ_ONLY, 0, NPCM7XX_CLK_CLKOUT},
 	/*20-16 CLKOUTDIV*/
-	{NPCM7XX_CLKDIV2, 13, 3, NPCM7XX_CLK_S_GFX,
-	NPCM7XX_CLK_S_GFX_MUX, 0, 0, NPCM7XX_CLK_GFX},
+	{NPCM7XX_CLKDIV2, 13, 3, NPCM7XX_CLK_S_GFX, NPCM7XX_CLK_S_GFX_MUX,
+		CLK_DIVIDER_READ_ONLY, 0, NPCM7XX_CLK_GFX},
 	/*15-13 GFXCKDIV*/
-	{NPCM7XX_CLKDIV2, 8, 5, NPCM7XX_CLK_S_USB_BRIDGE,
-	NPCM7XX_CLK_S_SU_MUX, 0, 0, NPCM7XX_CLK_SU},
+	{NPCM7XX_CLKDIV2, 8, 5, NPCM7XX_CLK_S_USB_BRIDGE, NPCM7XX_CLK_S_SU_MUX,
+		CLK_DIVIDER_READ_ONLY, 0, NPCM7XX_CLK_SU},
 	/*12-8 SUCKDIV*/
-	{NPCM7XX_CLKDIV2, 4, 4, NPCM7XX_CLK_S_USB_HOST,
-	NPCM7XX_CLK_S_SU_MUX, 0, 0, NPCM7XX_CLK_SU48},
+	{NPCM7XX_CLKDIV2, 4, 4, NPCM7XX_CLK_S_USB_HOST, NPCM7XX_CLK_S_SU_MUX,
+		CLK_DIVIDER_READ_ONLY, 0, NPCM7XX_CLK_SU48},
 	/*7-4 SU48CKDIV*/
 	{NPCM7XX_CLKDIV2, 0, 4, NPCM7XX_CLK_S_SDHC,
-	NPCM7XX_CLK_S_SD_MUX, 0, 0, NPCM7XX_CLK_SDHC}
+	NPCM7XX_CLK_S_SD_MUX, CLK_DIVIDER_READ_ONLY, 0, NPCM7XX_CLK_SDHC}
 	,/*3-0 SD1CKDIV*/
 
 	{NPCM7XX_CLKDIV3, 6, 5, NPCM7XX_CLK_S_SPI0,
-	NPCM7XX_CLK_S_AHB, 0, 0, NPCM7XX_CLK_SPI0},
+	NPCM7XX_CLK_S_AHB, CLK_DIVIDER_READ_ONLY, 0, NPCM7XX_CLK_SPI0},
 	/*10-6 SPI0CKDV*/
 	{NPCM7XX_CLKDIV3, 1, 5, NPCM7XX_CLK_S_SPIX,
-	NPCM7XX_CLK_S_AHB, 0, 0, NPCM7XX_CLK_SPIX},
+	NPCM7XX_CLK_S_AHB, CLK_DIVIDER_READ_ONLY, 0, NPCM7XX_CLK_SPIX},
 	/*5-1 SPIXCKDV*/
 
 };
-- 
2.22.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH linux dev-5.8 v3 02/12] dt-binding: iio: add syscon property to NPCM ADC
  2021-01-13 19:59 [PATCH linux dev-5.8 v3 00/12] Add NPCM7xx patches to dev-5.8 Tomer Maimon
  2021-01-13 19:59 ` [PATCH linux dev-5.8 v3 01/12] clk: npcm7xx: add read only flag to divider clocks Tomer Maimon
@ 2021-01-13 20:00 ` Tomer Maimon
  2021-01-15  6:27   ` Joel Stanley
  2021-01-13 20:00 ` [PATCH linux dev-5.8 v3 03/12] iio: adc: add calibration support to npcm ADC Tomer Maimon
                   ` (10 subsequent siblings)
  12 siblings, 1 reply; 19+ messages in thread
From: Tomer Maimon @ 2021-01-13 20:00 UTC (permalink / raw)
  To: openbmc; +Cc: Andrew Jeffery, Tomer Maimon, benjaminfair

Add syscon property to NPCM ADC to handle FUSE
registers.

Signed-off-by: Tomer Maimon <tmaimon77@gmail.com>
---
 Documentation/devicetree/bindings/iio/adc/nuvoton,npcm-adc.txt | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/iio/adc/nuvoton,npcm-adc.txt b/Documentation/devicetree/bindings/iio/adc/nuvoton,npcm-adc.txt
index ef8eeec1a997..faf9f9b54f5b 100644
--- a/Documentation/devicetree/bindings/iio/adc/nuvoton,npcm-adc.txt
+++ b/Documentation/devicetree/bindings/iio/adc/nuvoton,npcm-adc.txt
@@ -14,6 +14,7 @@ Optional properties:
 - vref-supply: The regulator supply ADC reference voltage, in case the
 			   vref-supply is not added the ADC will use internal voltage
 			   reference.
+- syscon: a phandle to access FUSE registers
 
 Example:
 
@@ -23,4 +24,5 @@ adc: adc@f000c000 {
 	interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>;
 	clocks = <&clk NPCM7XX_CLK_ADC>;
 	resets = <&rstc NPCM7XX_RESET_IPSRST1 NPCM7XX_RESET_ADC>;
+	syscon = <&fuse>;
 };
-- 
2.22.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH linux dev-5.8 v3 03/12] iio: adc: add calibration support to npcm ADC
  2021-01-13 19:59 [PATCH linux dev-5.8 v3 00/12] Add NPCM7xx patches to dev-5.8 Tomer Maimon
  2021-01-13 19:59 ` [PATCH linux dev-5.8 v3 01/12] clk: npcm7xx: add read only flag to divider clocks Tomer Maimon
  2021-01-13 20:00 ` [PATCH linux dev-5.8 v3 02/12] dt-binding: iio: add syscon property to NPCM ADC Tomer Maimon
@ 2021-01-13 20:00 ` Tomer Maimon
  2021-01-15  6:25   ` Joel Stanley
  2021-01-13 20:00 ` [PATCH linux dev-5.8 v3 04/12] dts: npcm750: add fuse regmap support node Tomer Maimon
                   ` (9 subsequent siblings)
  12 siblings, 1 reply; 19+ messages in thread
From: Tomer Maimon @ 2021-01-13 20:00 UTC (permalink / raw)
  To: openbmc; +Cc: Andrew Jeffery, Tomer Maimon, benjaminfair

Add calibration to improve accuracy measurement when using
internal reference voltage.

the calibration values taken from the FUSE module.

Signed-off-by: Tomer Maimon <tmaimon77@gmail.com>
---
 drivers/iio/adc/npcm_adc.c | 178 +++++++++++++++++++++++++++++++++++++
 1 file changed, 178 insertions(+)

diff --git a/drivers/iio/adc/npcm_adc.c b/drivers/iio/adc/npcm_adc.c
index 83bad2d5575d..081378b98fa9 100644
--- a/drivers/iio/adc/npcm_adc.c
+++ b/drivers/iio/adc/npcm_adc.c
@@ -17,6 +17,8 @@
 #include <linux/reset.h>
 
 struct npcm_adc {
+	u32 R05;
+	u32 R15;
 	bool int_status;
 	u32 adc_sample_hz;
 	struct device *dev;
@@ -51,6 +53,41 @@ struct npcm_adc {
 #define NPCM_RESOLUTION_BITS		10
 #define NPCM_INT_VREF_MV		2000
 
+/* FUSE registers */
+#define NPCM7XX_FST		0x00
+#define NPCM7XX_FADDR		0x04
+#define NPCM7XX_FDATA		0x08
+#define NPCM7XX_FCFG		0x0C
+#define NPCM7XX_FCTL		0x14
+
+/* FST Register Bits */
+#define NPCM7XX_FST_RDY		BIT(0)
+#define NPCM7XX_FST_RDST	BIT(1)
+
+/* FADDR Register Bits */
+#define NPCM7XX_FADDR_BYTEADDR		BIT(0)
+#define NPCM7XX_FADDR_BYTEADDR_MASK	GENMASK(9, 0)
+
+/* FADDR Register Bits */
+#define NPCM7XX_FDATA_DATA		BIT(0)
+#define NPCM7XX_FDATA_CLEAN_VALUE	BIT(1)
+#define NPCM7XX_FDATA_DATA_MASK		GENMASK(7, 0)
+
+/* FCTL Register Bits */
+#define NPCM7XX_FCTL_RDST		BIT(1)
+
+/* ADC Calibration Definition */
+#define NPCM_INT_1500MV		768
+#define NPCM_INT_1000MV		512
+#define NPCM_ADC_MIN_VAL	0
+#define NPCM_ADC_MAX_VAL	1023
+
+#define FUSE_CALIB_ADDR		24
+#define FUSE_CALIB_SIZE		8
+#define DATA_CALIB_SIZE		4
+#define FUSE_READ_SLEEP		500
+#define FUSE_READ_TIMEOUT	1000000
+
 #define NPCM_ADC_CHAN(ch) {					\
 	.type = IIO_VOLTAGE,					\
 	.indexed = 1,						\
@@ -71,6 +108,119 @@ static const struct iio_chan_spec npcm_adc_iio_channels[] = {
 	NPCM_ADC_CHAN(7),
 };
 
+static void npcm750_fuse_read(struct regmap *fuse_regmap, u32 addr, u8 *data)
+{
+	u32 val;
+	u32 fstreg;
+
+	regmap_read_poll_timeout(fuse_regmap, NPCM7XX_FST, fstreg,
+				 fstreg & NPCM7XX_FST_RDY, FUSE_READ_SLEEP,
+				 FUSE_READ_TIMEOUT);
+	regmap_write_bits(fuse_regmap, NPCM7XX_FST,
+			  NPCM7XX_FST_RDST, NPCM7XX_FST_RDST);
+
+	regmap_write_bits(fuse_regmap, NPCM7XX_FADDR,
+			  NPCM7XX_FADDR_BYTEADDR_MASK, addr);
+	regmap_read(fuse_regmap, NPCM7XX_FADDR, &val);
+	regmap_write(fuse_regmap, NPCM7XX_FCTL, NPCM7XX_FCTL_RDST);
+
+	regmap_read_poll_timeout(fuse_regmap, NPCM7XX_FST, fstreg,
+				 fstreg & NPCM7XX_FST_RDY, FUSE_READ_SLEEP,
+				 FUSE_READ_TIMEOUT);
+	regmap_write_bits(fuse_regmap, NPCM7XX_FST,
+			  NPCM7XX_FST_RDST, NPCM7XX_FST_RDST);
+
+	regmap_read(fuse_regmap, NPCM7XX_FDATA, &val);
+	*data = (u8)val;
+
+	regmap_write_bits(fuse_regmap, NPCM7XX_FDATA, NPCM7XX_FDATA_DATA_MASK,
+			  NPCM7XX_FDATA_CLEAN_VALUE);
+}
+
+static int npcm750_ECC_to_nibble(u8 ECC, u8 nibble)
+{
+	u8 nibble_b0 = (nibble >> 0) & BIT(0);
+	u8 nibble_b1 = (nibble >> 1) & BIT(0);
+	u8 nibble_b2 = (nibble >> 2) & BIT(0);
+	u8 nibble_b3 = (nibble >> 3) & BIT(0);
+	u8 tmp_ECC = nibble;
+
+	tmp_ECC |= (nibble_b0 ^ nibble_b1) << 4 | (nibble_b2 ^ nibble_b3) << 5 |
+		(nibble_b0 ^ nibble_b2) << 6  | (nibble_b1 ^ nibble_b3) << 7;
+
+	if (tmp_ECC != ECC)
+		return -EINVAL;
+
+	return 0;
+}
+
+static int npcm750_ECC_to_byte(u16 ECC, u8 *Byte)
+{
+	u8 nibble_L, nibble_H;
+	u8 ECC_L, ECC_H;
+
+	ECC_H = ECC >> 8;
+	nibble_H = ECC_H & 0x0F;
+	ECC_L = ECC >> 0;
+	nibble_L = ECC_L & 0x0F;
+
+	if (npcm750_ECC_to_nibble(ECC_H, nibble_H) != 0 ||
+	    npcm750_ECC_to_nibble(ECC_L, nibble_L) != 0)
+		return -EINVAL;
+
+	*Byte = nibble_H << 4 | nibble_L << 0;
+
+	return 0;
+}
+
+static int npcm750_read_nibble_parity(u8 *block_ECC, u8 *ADC_calib)
+{
+	int i;
+	u16 ECC;
+
+	for (i = 0; i < DATA_CALIB_SIZE; i++) {
+		memcpy(&ECC, block_ECC + (i * 2), 2);
+		if (npcm750_ECC_to_byte(ECC, &ADC_calib[i]) != 0)
+			return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int npcm750_fuse_calibration_read(struct platform_device *pdev,
+					 struct npcm_adc *info)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct regmap *fuse_regmap;
+	ssize_t bytes_read = 0;
+	u8 read_buf[8];
+	u32 ADC_calib;
+	u32 addr = FUSE_CALIB_ADDR;
+
+	fuse_regmap = syscon_regmap_lookup_by_phandle(np, "syscon");
+	if (IS_ERR(fuse_regmap)) {
+		dev_warn(&pdev->dev, "Failed to find syscon\n");
+		return PTR_ERR(fuse_regmap);
+	}
+
+	while (bytes_read < FUSE_CALIB_SIZE) {
+		npcm750_fuse_read(fuse_regmap, addr,
+				  &read_buf[bytes_read]);
+		bytes_read++;
+		addr++;
+	}
+
+	if (npcm750_read_nibble_parity(read_buf, (u8 *)&ADC_calib)) {
+		dev_warn(info->dev, "FUSE Calibration read failed\n");
+		return -EINVAL;
+	}
+
+	info->R05 = ADC_calib & 0xFFFF;
+	info->R15 = ADC_calib >> 16;
+
+	return 0;
+}
+
 static irqreturn_t npcm_adc_isr(int irq, void *data)
 {
 	u32 regtemp;
@@ -125,6 +275,29 @@ static int npcm_adc_read(struct npcm_adc *info, int *val, u8 channel)
 	return 0;
 }
 
+static void npcm_adc_calibration(int *val, struct npcm_adc *info)
+{
+	int mul_val;
+	int offset_val;
+
+	mul_val = NPCM_INT_1000MV * (*val - info->R15);
+	if (mul_val < 0) {
+		mul_val = mul_val * -1;
+		offset_val = DIV_ROUND_CLOSEST(mul_val,
+					       (info->R15 - info->R05));
+		*val = NPCM_INT_1500MV - offset_val;
+	} else {
+		offset_val = DIV_ROUND_CLOSEST(mul_val,
+					       (info->R15 - info->R05));
+		*val = NPCM_INT_1500MV + offset_val;
+	}
+
+	if (*val < NPCM_ADC_MIN_VAL)
+		*val = NPCM_ADC_MIN_VAL;
+	if (*val > NPCM_ADC_MAX_VAL)
+		*val = NPCM_ADC_MAX_VAL;
+}
+
 static int npcm_adc_read_raw(struct iio_dev *indio_dev,
 			     struct iio_chan_spec const *chan, int *val,
 			     int *val2, long mask)
@@ -142,6 +315,10 @@ static int npcm_adc_read_raw(struct iio_dev *indio_dev,
 			dev_err(info->dev, "NPCM ADC read failed\n");
 			return ret;
 		}
+
+		if ((info->R05 || info->R15) && IS_ERR(info->vref))
+			npcm_adc_calibration(val, info);
+
 		return IIO_VAL_INT;
 	case IIO_CHAN_INFO_SCALE:
 		if (!IS_ERR(info->vref)) {
@@ -248,6 +425,7 @@ static int npcm_adc_probe(struct platform_device *pdev)
 			  info->regs + NPCM_ADCCON);
 	}
 
+	npcm750_fuse_calibration_read(pdev, info);
 	init_waitqueue_head(&info->wq);
 
 	reg_con = ioread32(info->regs + NPCM_ADCCON);
-- 
2.22.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH linux dev-5.8 v3 04/12] dts: npcm750: add fuse regmap support node
  2021-01-13 19:59 [PATCH linux dev-5.8 v3 00/12] Add NPCM7xx patches to dev-5.8 Tomer Maimon
                   ` (2 preceding siblings ...)
  2021-01-13 20:00 ` [PATCH linux dev-5.8 v3 03/12] iio: adc: add calibration support to npcm ADC Tomer Maimon
@ 2021-01-13 20:00 ` Tomer Maimon
  2021-01-15  6:27   ` Joel Stanley
  2021-01-13 20:00 ` [PATCH linux dev-5.8 v3 05/12] dt-binding: watchdog: Add DT restart priority and reset type Tomer Maimon
                   ` (8 subsequent siblings)
  12 siblings, 1 reply; 19+ messages in thread
From: Tomer Maimon @ 2021-01-13 20:00 UTC (permalink / raw)
  To: openbmc; +Cc: Andrew Jeffery, Tomer Maimon, benjaminfair

Signed-off-by: Tomer Maimon <tmaimon77@gmail.com>
---
 arch/arm/boot/dts/nuvoton-common-npcm7xx.dtsi | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm/boot/dts/nuvoton-common-npcm7xx.dtsi b/arch/arm/boot/dts/nuvoton-common-npcm7xx.dtsi
index 7eee4145127f..455a96b23b85 100644
--- a/arch/arm/boot/dts/nuvoton-common-npcm7xx.dtsi
+++ b/arch/arm/boot/dts/nuvoton-common-npcm7xx.dtsi
@@ -82,6 +82,12 @@
 			"simple-mfd";
 			reg = <0x801000 0x6C>;
 		};
+		
+		fuse:fuse@18a000 {
+			compatible = "nuvoton,npcm750-fuse", "syscon",
+				"simple-mfd";
+			reg = <0x18a000 0x1000>;
+		};
 
 		scu: scu@3fe000 {
 			compatible = "arm,cortex-a9-scu";
-- 
2.22.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH linux dev-5.8 v3 05/12] dt-binding: watchdog: Add DT restart priority and reset type
  2021-01-13 19:59 [PATCH linux dev-5.8 v3 00/12] Add NPCM7xx patches to dev-5.8 Tomer Maimon
                   ` (3 preceding siblings ...)
  2021-01-13 20:00 ` [PATCH linux dev-5.8 v3 04/12] dts: npcm750: add fuse regmap support node Tomer Maimon
@ 2021-01-13 20:00 ` Tomer Maimon
  2021-01-13 20:00 ` [PATCH linux dev-5.8 v3 06/12] watchdog: npcm: Add DT restart priority and reset type support Tomer Maimon
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 19+ messages in thread
From: Tomer Maimon @ 2021-01-13 20:00 UTC (permalink / raw)
  To: openbmc; +Cc: Andrew Jeffery, Tomer Maimon, benjaminfair

Add device tree restart priority documentation and
three reset types documentation.

Signed-off-by: Tomer Maimon <tmaimon77@gmail.com>
---
 .../bindings/watchdog/nuvoton,npcm-wdt.txt    | 34 +++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/Documentation/devicetree/bindings/watchdog/nuvoton,npcm-wdt.txt b/Documentation/devicetree/bindings/watchdog/nuvoton,npcm-wdt.txt
index 6d593003c933..a3142cb60495 100644
--- a/Documentation/devicetree/bindings/watchdog/nuvoton,npcm-wdt.txt
+++ b/Documentation/devicetree/bindings/watchdog/nuvoton,npcm-wdt.txt
@@ -16,7 +16,36 @@ Required clocking property, have to be one of:
                     timer (usually 25000000).
 
 Optional properties:
+- syscon: a phandle to access GCR registers.
 - timeout-sec : Contains the watchdog timeout in seconds
+- nuvoton,restart-priority - Contains the card restart priority.
+- nuvoton,card-reset-type = "porst|corst|wd0|wd1|wd2|sw1|sw2|sw3|sw4"
+  Contains the card reset type for checking and indicating
+  the last card reset status (WDIOF_CARDRESET)
+
+  If 'nuvoton,card-reset-type' is not specified the default is porst
+
+  Reset types:
+       - porst: Power reset
+       - corst: Core reset
+	   - wdX : Watchdog reset X (X represante 0-2)
+	   - swX : Software reset X (X represante 1-4)
+
+- nuvoton,ext1-reset-type = "porst|corst|wd0|wd1|wd2|sw1|sw2|sw3|sw4"
+  Contains the external 2 reset type for checking and indicating
+  the last external 2 reset status (WDIOF_EXTERN1)
+
+  If 'nuvoton,card-reset-type' is not specified the default is wd0.
+
+  Reset types are the same as in nuvoton,card-reset-type property.
+
+- nuvoton,ext2-reset-type = "porst|corst|wd0|wd1|wd2|sw1|sw2|sw3|sw4"
+  Contains the external 2 reset type for checking and indicating
+  the last external 2 reset status (WDIOF_EXTERN2)
+
+  If 'nuvoton,card-reset-type' is not specified the default is sw1.
+
+  Reset types are the same as in nuvoton,card-reset-type property.
 
 Example:
 
@@ -25,4 +54,9 @@ timer@f000801c {
     interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
     reg = <0xf000801c 0x4>;
     clocks = <&clk NPCM7XX_CLK_TIMER>;
+	syscon = <&gcr>;
+	nuvoton,restart-priority = <155>;
+	nuvoton,card-reset-type = "porst";
+	nuvoton,ext1-reset-type = "wd1";
+	nuvoton,ext2-reset-type = "sw2";
 };
-- 
2.22.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH linux dev-5.8 v3 06/12] watchdog: npcm: Add DT restart priority and reset type support
  2021-01-13 19:59 [PATCH linux dev-5.8 v3 00/12] Add NPCM7xx patches to dev-5.8 Tomer Maimon
                   ` (4 preceding siblings ...)
  2021-01-13 20:00 ` [PATCH linux dev-5.8 v3 05/12] dt-binding: watchdog: Add DT restart priority and reset type Tomer Maimon
@ 2021-01-13 20:00 ` Tomer Maimon
  2021-01-13 20:00 ` [PATCH linux dev-5.8 v3 07/12] pinctrl: npcm7xx: Add HGPIO pin support to NPCM7xx pinctrl driver Tomer Maimon
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 19+ messages in thread
From: Tomer Maimon @ 2021-01-13 20:00 UTC (permalink / raw)
  To: openbmc; +Cc: Andrew Jeffery, Tomer Maimon, benjaminfair

Add Device tree restart priority and
three reset types support.

Signed-off-by: Tomer Maimon <tmaimon77@gmail.com>
---
 drivers/watchdog/npcm_wdt.c | 117 +++++++++++++++++++++++++++++++++++-
 1 file changed, 114 insertions(+), 3 deletions(-)

diff --git a/drivers/watchdog/npcm_wdt.c b/drivers/watchdog/npcm_wdt.c
index 765577f11c8d..a93180d0a6f4 100644
--- a/drivers/watchdog/npcm_wdt.c
+++ b/drivers/watchdog/npcm_wdt.c
@@ -11,7 +11,24 @@
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/watchdog.h>
-
+#include <linux/regmap.h>
+#include <linux/mfd/syscon.h>
+
+/* NPCM7xx GCR module */
+#define NPCM7XX_RESSR_OFFSET		0x6C
+#define NPCM7XX_INTCR2_OFFSET		0x60
+
+#define NPCM7XX_PORST			BIT(31)
+#define NPCM7XX_CORST			BIT(30)
+#define NPCM7XX_WD0RST			BIT(29)
+#define NPCM7XX_WD1RST			BIT(24)
+#define NPCM7XX_WD2RST			BIT(23)
+#define NPCM7XX_SWR1RST			BIT(28)
+#define NPCM7XX_SWR2RST			BIT(27)
+#define NPCM7XX_SWR3RST			BIT(26)
+#define NPCM7XX_SWR4RST			BIT(25)
+
+ /* WD register */
 #define NPCM_WTCR	0x1C
 
 #define NPCM_WTCLK	(BIT(10) | BIT(11))	/* Clock divider */
@@ -41,8 +58,11 @@
  */
 
 struct npcm_wdt {
-	struct watchdog_device  wdd;
+	struct watchdog_device	wdd;
 	void __iomem		*reg;
+	u32			card_reset;
+	u32			ext1_reset;
+	u32			ext2_reset;
 };
 
 static inline struct npcm_wdt *to_npcm_wdt(struct watchdog_device *wdd)
@@ -176,14 +196,65 @@ static const struct watchdog_ops npcm_wdt_ops = {
 	.restart = npcm_wdt_restart,
 };
 
+static void npcm_get_reset_status(struct npcm_wdt *wdt, struct device *dev)
+{
+	struct regmap *gcr_regmap;
+	u32 rstval;
+
+	gcr_regmap = syscon_regmap_lookup_by_phandle(dev->of_node, "syscon");
+	if (IS_ERR(gcr_regmap))
+		dev_warn(dev, "Failed to find gcr syscon, WD reset status not supported\n");
+
+	regmap_read(gcr_regmap, NPCM7XX_RESSR_OFFSET, &rstval);
+	if (!rstval) {
+		regmap_read(gcr_regmap, NPCM7XX_INTCR2_OFFSET, &rstval);
+		rstval = ~rstval;
+	}
+
+	if (rstval & wdt->card_reset)
+		wdt->wdd.bootstatus |= WDIOF_CARDRESET;
+	if (rstval & wdt->ext1_reset)
+		wdt->wdd.bootstatus |= WDIOF_EXTERN1;
+	if (rstval & wdt->ext2_reset)
+		wdt->wdd.bootstatus |= WDIOF_EXTERN2;
+}
+
+static u32 npcm_wdt_reset_type(const char *reset_type)
+{
+	if (!strcmp(reset_type, "porst"))
+		return NPCM7XX_PORST;
+	else if (!strcmp(reset_type, "corst"))
+		return NPCM7XX_CORST;
+	else if (!strcmp(reset_type, "wd0"))
+		return NPCM7XX_WD0RST;
+	else if (!strcmp(reset_type, "wd1"))
+		return NPCM7XX_WD1RST;
+	else if (!strcmp(reset_type, "wd2"))
+		return NPCM7XX_WD2RST;
+	else if (!strcmp(reset_type, "sw1"))
+		return NPCM7XX_SWR1RST;
+	else if (!strcmp(reset_type, "sw2"))
+		return NPCM7XX_SWR2RST;
+	else if (!strcmp(reset_type, "sw3"))
+		return NPCM7XX_SWR3RST;
+	else if (!strcmp(reset_type, "sw4"))
+		return NPCM7XX_SWR4RST;
+
+	return 0;
+}
+
 static int npcm_wdt_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
+	const char *card_reset_type;
+	const char *ext1_reset_type;
+	const char *ext2_reset_type;
 	struct npcm_wdt *wdt;
+	u32 priority;
 	int irq;
 	int ret;
 
-	wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
+	wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
 	if (!wdt)
 		return -ENOMEM;
 
@@ -195,6 +266,45 @@ static int npcm_wdt_probe(struct platform_device *pdev)
 	if (irq < 0)
 		return irq;
 
+	if (of_property_read_u32(pdev->dev.of_node, "nuvoton,restart-priority",
+				 &priority))
+		watchdog_set_restart_priority(&wdt->wdd, 128);
+	else
+		watchdog_set_restart_priority(&wdt->wdd, priority);
+
+	ret = of_property_read_string(pdev->dev.of_node,
+				      "nuvoton,card-reset-type",
+				      &card_reset_type);
+	if (ret) {
+		wdt->card_reset = NPCM7XX_PORST;
+	} else {
+		wdt->card_reset = npcm_wdt_reset_type(card_reset_type);
+		if (!wdt->card_reset)
+			wdt->card_reset = NPCM7XX_PORST;
+	}
+
+	ret = of_property_read_string(pdev->dev.of_node,
+				      "nuvoton,ext1-reset-type",
+				      &ext1_reset_type);
+	if (ret) {
+		wdt->ext1_reset = NPCM7XX_WD0RST;
+	} else {
+		wdt->ext1_reset = npcm_wdt_reset_type(ext1_reset_type);
+		if (!wdt->ext1_reset)
+			wdt->ext1_reset = NPCM7XX_WD0RST;
+	}
+
+	ret = of_property_read_string(pdev->dev.of_node,
+				      "nuvoton,ext2-reset-type",
+				      &ext2_reset_type);
+	if (ret) {
+		wdt->ext2_reset = NPCM7XX_SWR1RST;
+	} else {
+		wdt->ext2_reset = npcm_wdt_reset_type(ext2_reset_type);
+		if (!wdt->ext2_reset)
+			wdt->ext2_reset = NPCM7XX_SWR1RST;
+	}
+
 	wdt->wdd.info = &npcm_wdt_info;
 	wdt->wdd.ops = &npcm_wdt_ops;
 	wdt->wdd.min_timeout = 1;
@@ -213,6 +323,7 @@ static int npcm_wdt_probe(struct platform_device *pdev)
 		set_bit(WDOG_HW_RUNNING, &wdt->wdd.status);
 	}
 
+	npcm_get_reset_status(wdt, dev);
 	ret = devm_request_irq(dev, irq, npcm_wdt_interrupt, 0, "watchdog",
 			       wdt);
 	if (ret)
-- 
2.22.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH linux dev-5.8 v3 07/12] pinctrl: npcm7xx: Add HGPIO pin support to NPCM7xx pinctrl driver
  2021-01-13 19:59 [PATCH linux dev-5.8 v3 00/12] Add NPCM7xx patches to dev-5.8 Tomer Maimon
                   ` (5 preceding siblings ...)
  2021-01-13 20:00 ` [PATCH linux dev-5.8 v3 06/12] watchdog: npcm: Add DT restart priority and reset type support Tomer Maimon
@ 2021-01-13 20:00 ` Tomer Maimon
  2021-01-14  6:21   ` Tomer Maimon
  2021-01-13 20:00 ` [PATCH linux dev-5.8 v3 08/12] pinctrl: pinconf: add pin persist configuration Tomer Maimon
                   ` (5 subsequent siblings)
  12 siblings, 1 reply; 19+ messages in thread
From: Tomer Maimon @ 2021-01-13 20:00 UTC (permalink / raw)
  To: openbmc; +Cc: Andrew Jeffery, Tomer Maimon, benjaminfair

Signed-off-by: Tomer Maimon <tmaimon77@gmail.com>
---
 drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c | 65 +++++++++++++++++------
 1 file changed, 49 insertions(+), 16 deletions(-)

diff --git a/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c b/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c
index a935065cdac4..e5f58ea89917 100644
--- a/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c
+++ b/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c
@@ -504,6 +504,15 @@ static const int lkgpo2_pins[] = { 9 };
 
 static const int nprd_smi_pins[] = { 190 };
 
+static const int hgpio0_pins[] = { 20 };
+static const int hgpio1_pins[] = { 21 };
+static const int hgpio2_pins[] = { 22 };
+static const int hgpio3_pins[] = { 23 };
+static const int hgpio4_pins[] = { 24 };
+static const int hgpio5_pins[] = { 25 };
+static const int hgpio6_pins[] = { 59 };
+static const int hgpio7_pins[] = { 60 };
+
 /*
  * pin:	     name, number
  * group:    name, npins,   pins
@@ -631,6 +640,14 @@ struct npcm7xx_group {
 	NPCM7XX_GRP(lkgpo1), \
 	NPCM7XX_GRP(lkgpo2), \
 	NPCM7XX_GRP(nprd_smi), \
+	NPCM7XX_GRP(hgpio0), \
+	NPCM7XX_GRP(hgpio1), \
+	NPCM7XX_GRP(hgpio2), \
+	NPCM7XX_GRP(hgpio3), \
+	NPCM7XX_GRP(hgpio4), \
+	NPCM7XX_GRP(hgpio5), \
+	NPCM7XX_GRP(hgpio6), \
+	NPCM7XX_GRP(hgpio7), \
 	\
 
 enum {
@@ -774,6 +791,14 @@ NPCM7XX_SFUNC(lkgpo0);
 NPCM7XX_SFUNC(lkgpo1);
 NPCM7XX_SFUNC(lkgpo2);
 NPCM7XX_SFUNC(nprd_smi);
+NPCM7XX_SFUNC(hgpio0);
+NPCM7XX_SFUNC(hgpio1);
+NPCM7XX_SFUNC(hgpio2);
+NPCM7XX_SFUNC(hgpio3);
+NPCM7XX_SFUNC(hgpio4);
+NPCM7XX_SFUNC(hgpio5);
+NPCM7XX_SFUNC(hgpio6);
+NPCM7XX_SFUNC(hgpio7);
 
 /* Function names */
 static struct npcm7xx_func npcm7xx_funcs[] = {
@@ -892,6 +917,14 @@ static struct npcm7xx_func npcm7xx_funcs[] = {
 	NPCM7XX_MKFUNC(lkgpo1),
 	NPCM7XX_MKFUNC(lkgpo2),
 	NPCM7XX_MKFUNC(nprd_smi),
+	NPCM7XX_MKFUNC(hgpio0),
+	NPCM7XX_MKFUNC(hgpio1),
+	NPCM7XX_MKFUNC(hgpio2),
+	NPCM7XX_MKFUNC(hgpio3),
+	NPCM7XX_MKFUNC(hgpio4),
+	NPCM7XX_MKFUNC(hgpio5),
+	NPCM7XX_MKFUNC(hgpio6),
+	NPCM7XX_MKFUNC(hgpio7),
 };
 
 #define NPCM7XX_PINCFG(a, b, c, d, e, f, g, h, i, j, k) \
@@ -944,12 +977,12 @@ static const struct npcm7xx_pincfg pincfg[] = {
 	NPCM7XX_PINCFG(17,      pspi2, MFSEL3, 13,     smb4den, I2CSEGSEL, 23,  none, NONE, 0,       DS(8, 12)),
 	NPCM7XX_PINCFG(18,      pspi2, MFSEL3, 13,	 smb4b, I2CSEGSEL, 14,  none, NONE, 0,	     DS(8, 12)),
 	NPCM7XX_PINCFG(19,      pspi2, MFSEL3, 13,	 smb4b, I2CSEGSEL, 14,  none, NONE, 0,	     DS(8, 12)),
-	NPCM7XX_PINCFG(20,	smb4c, I2CSEGSEL, 15,    smb15, MFSEL3, 8,      none, NONE, 0,	     0),
-	NPCM7XX_PINCFG(21,	smb4c, I2CSEGSEL, 15,    smb15, MFSEL3, 8,      none, NONE, 0,	     0),
-	NPCM7XX_PINCFG(22,      smb4d, I2CSEGSEL, 16,	 smb14, MFSEL3, 7,      none, NONE, 0,	     0),
-	NPCM7XX_PINCFG(23,      smb4d, I2CSEGSEL, 16,	 smb14, MFSEL3, 7,      none, NONE, 0,	     0),
-	NPCM7XX_PINCFG(24,	 ioxh, MFSEL3, 18,	  none, NONE, 0,	none, NONE, 0,	     DS(8, 12)),
-	NPCM7XX_PINCFG(25,	 ioxh, MFSEL3, 18,	  none, NONE, 0,	none, NONE, 0,	     DS(8, 12)),
+	NPCM7XX_PINCFG(20,	hgpio0, MFSEL2, 24,      smb15, MFSEL3, 8,      smb4c, I2CSEGSEL, 15,	     0),
+	NPCM7XX_PINCFG(21,	hgpio1, MFSEL2, 25,      smb15, MFSEL3, 8,      smb4c, I2CSEGSEL, 15,	     0),
+	NPCM7XX_PINCFG(22,      hgpio2, MFSEL2, 26,	 smb14, MFSEL3, 7,      smb4d, I2CSEGSEL, 16,	     0),
+	NPCM7XX_PINCFG(23,      hgpio3, MFSEL2, 27,	 smb14, MFSEL3, 7,      smb4d, I2CSEGSEL, 16,	     0),
+	NPCM7XX_PINCFG(24,	 hgpio4, MFSEL2, 28,	ioxh, MFSEL3, 18,	none, NONE, 0,	     DS(8, 12)),
+	NPCM7XX_PINCFG(25,	 hgpio5, MFSEL2, 29,	ioxh, MFSEL3, 18,	none, NONE, 0,	     DS(8, 12)),
 	NPCM7XX_PINCFG(26,	 smb5, MFSEL1, 2,	  none, NONE, 0,	none, NONE, 0,	     0),
 	NPCM7XX_PINCFG(27,	 smb5, MFSEL1, 2,	  none, NONE, 0,	none, NONE, 0,	     0),
 	NPCM7XX_PINCFG(28,	 smb4, MFSEL1, 1,	  none, NONE, 0,	none, NONE, 0,	     0),
@@ -982,8 +1015,8 @@ static const struct npcm7xx_pincfg pincfg[] = {
 	NPCM7XX_PINCFG(56,	r1err, MFSEL1, 12,	  none, NONE, 0,	none, NONE, 0,	     0),
 	NPCM7XX_PINCFG(57,       r1md, MFSEL1, 13,        none, NONE, 0,        none, NONE, 0,       DS(2, 4)),
 	NPCM7XX_PINCFG(58,       r1md, MFSEL1, 13,        none, NONE, 0,	none, NONE, 0,	     DS(2, 4)),
-	NPCM7XX_PINCFG(59,	smb3d, I2CSEGSEL, 13,	  none, NONE, 0,	none, NONE, 0,	     0),
-	NPCM7XX_PINCFG(60,	smb3d, I2CSEGSEL, 13,	  none, NONE, 0,	none, NONE, 0,	     0),
+	NPCM7XX_PINCFG(59,	hgpio6, MFSEL2, 30,	  smb3d, I2CSEGSEL, 13,	none, NONE, 0,	     0),
+	NPCM7XX_PINCFG(60,	hgpio7, MFSEL2, 31,	  smb3d, I2CSEGSEL, 13,	none, NONE, 0,	     0),
 	NPCM7XX_PINCFG(61,      uart1, MFSEL1, 10,	  none, NONE, 0,	none, NONE, 0,     GPO),
 	NPCM7XX_PINCFG(62,      uart1, MFSEL1, 10,    bmcuart1, MFSEL3, 24,	none, NONE, 0,     GPO),
 	NPCM7XX_PINCFG(63,      uart1, MFSEL1, 10,    bmcuart1, MFSEL3, 24,	none, NONE, 0,     GPO),
@@ -1188,12 +1221,12 @@ static const struct pinctrl_pin_desc npcm7xx_pins[] = {
 	PINCTRL_PIN(17, "GPIO17/PSPI2DI/SMB4DEN"),
 	PINCTRL_PIN(18, "GPIO18/PSPI2D0/SMB4BSDA"),
 	PINCTRL_PIN(19, "GPIO19/PSPI2CK/SMB4BSCL"),
-	PINCTRL_PIN(20, "GPIO20/SMB4CSDA/SMB15SDA"),
-	PINCTRL_PIN(21, "GPIO21/SMB4CSCL/SMB15SCL"),
-	PINCTRL_PIN(22, "GPIO22/SMB4DSDA/SMB14SDA"),
-	PINCTRL_PIN(23, "GPIO23/SMB4DSCL/SMB14SCL"),
-	PINCTRL_PIN(24, "GPIO24/IOXHDO"),
-	PINCTRL_PIN(25, "GPIO25/IOXHDI"),
+	PINCTRL_PIN(20, "GPIO20/HGPIO0/SMB4CSDA/SMB15SDA"),
+	PINCTRL_PIN(21, "GPIO21/HGPIO1/SMB4CSCL/SMB15SCL"),
+	PINCTRL_PIN(22, "GPIO22/HGPIO2/SMB4DSDA/SMB14SDA"),
+	PINCTRL_PIN(23, "GPIO23/HGPIO3/SMB4DSCL/SMB14SCL"),
+	PINCTRL_PIN(24, "GPIO24/HGPIO4/IOXHDO"),
+	PINCTRL_PIN(25, "GPIO25/HGPIO5/IOXHDI"),
 	PINCTRL_PIN(26, "GPIO26/SMB5SDA"),
 	PINCTRL_PIN(27, "GPIO27/SMB5SCL"),
 	PINCTRL_PIN(28, "GPIO28/SMB4SDA"),
@@ -1226,8 +1259,8 @@ static const struct pinctrl_pin_desc npcm7xx_pins[] = {
 	PINCTRL_PIN(56, "GPIO56/R1RXERR"),
 	PINCTRL_PIN(57, "GPIO57/R1MDC"),
 	PINCTRL_PIN(58, "GPIO58/R1MDIO"),
-	PINCTRL_PIN(59, "GPIO59/SMB3DSDA"),
-	PINCTRL_PIN(60, "GPIO60/SMB3DSCL"),
+	PINCTRL_PIN(59, "GPIO59/HGPIO6/SMB3DSDA"),
+	PINCTRL_PIN(60, "GPIO60/HGPIO7/SMB3DSCL"),
 	PINCTRL_PIN(61, "GPO61/nDTR1_BOUT1/STRAP6"),
 	PINCTRL_PIN(62, "GPO62/nRTST1/STRAP5"),
 	PINCTRL_PIN(63, "GPO63/TXD1/STRAP4"),
-- 
2.22.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH linux dev-5.8 v3 08/12] pinctrl: pinconf: add pin persist configuration
  2021-01-13 19:59 [PATCH linux dev-5.8 v3 00/12] Add NPCM7xx patches to dev-5.8 Tomer Maimon
                   ` (6 preceding siblings ...)
  2021-01-13 20:00 ` [PATCH linux dev-5.8 v3 07/12] pinctrl: npcm7xx: Add HGPIO pin support to NPCM7xx pinctrl driver Tomer Maimon
@ 2021-01-13 20:00 ` Tomer Maimon
  2021-01-13 20:00 ` [PATCH linux dev-5.8 v3 09/12] pinctrl: npcm7xx: Add pin persist configuration support Tomer Maimon
                   ` (4 subsequent siblings)
  12 siblings, 0 replies; 19+ messages in thread
From: Tomer Maimon @ 2021-01-13 20:00 UTC (permalink / raw)
  To: openbmc; +Cc: Andrew Jeffery, Tomer Maimon, benjaminfair

Add generic pin persist configuration support.

Signed-off-by: Tomer Maimon <tmaimon77@gmail.com>
---
 drivers/pinctrl/pinconf-generic.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/pinctrl/pinconf-generic.c b/drivers/pinctrl/pinconf-generic.c
index dfef471201f6..c609a69bd37e 100644
--- a/drivers/pinctrl/pinconf-generic.c
+++ b/drivers/pinctrl/pinconf-generic.c
@@ -50,6 +50,7 @@ static const struct pin_config_item conf_items[] = {
 	PCONFDUMP(PIN_CONFIG_SLEEP_HARDWARE_STATE, "sleep hardware state", NULL, false),
 	PCONFDUMP(PIN_CONFIG_SLEW_RATE, "slew rate", NULL, true),
 	PCONFDUMP(PIN_CONFIG_SKEW_DELAY, "skew delay", NULL, true),
+	PCONFDUMP(PIN_CONFIG_PERSIST_STATE, "persist state", NULL, false),
 };
 
 static void pinconf_generic_dump_one(struct pinctrl_dev *pctldev,
@@ -184,6 +185,8 @@ static const struct pinconf_generic_params dt_params[] = {
 	{ "sleep-hardware-state", PIN_CONFIG_SLEEP_HARDWARE_STATE, 0 },
 	{ "slew-rate", PIN_CONFIG_SLEW_RATE, 0 },
 	{ "skew-delay", PIN_CONFIG_SKEW_DELAY, 0 },
+	{ "persist-state", PIN_CONFIG_PERSIST_STATE, 0 },
+	{ "reset-state", PIN_CONFIG_PERSIST_STATE, 1 },
 };
 
 /**
-- 
2.22.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH linux dev-5.8 v3 09/12] pinctrl: npcm7xx: Add pin persist configuration support
  2021-01-13 19:59 [PATCH linux dev-5.8 v3 00/12] Add NPCM7xx patches to dev-5.8 Tomer Maimon
                   ` (7 preceding siblings ...)
  2021-01-13 20:00 ` [PATCH linux dev-5.8 v3 08/12] pinctrl: pinconf: add pin persist configuration Tomer Maimon
@ 2021-01-13 20:00 ` Tomer Maimon
  2021-01-13 20:00 ` [PATCH linux dev-5.8 v3 10/12] spi: npcm-pspi: Add full duplex support Tomer Maimon
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 19+ messages in thread
From: Tomer Maimon @ 2021-01-13 20:00 UTC (permalink / raw)
  To: openbmc; +Cc: Andrew Jeffery, Tomer Maimon, benjaminfair

Signed-off-by: Tomer Maimon <tmaimon77@gmail.com>
---
 drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c | 65 +++++++++++++++++++++++
 1 file changed, 65 insertions(+)

diff --git a/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c b/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c
index e5f58ea89917..ec12efd23bbe 100644
--- a/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c
+++ b/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c
@@ -36,6 +36,19 @@
 
 #define SRCNT_ESPI		BIT(3)
 
+/* reset registers */
+#define NPCM7XX_RST_WD0RCR	0x38
+#define NPCM7XX_RST_WD1RCR	0x3C
+#define NPCM7XX_RST_WD2RCR	0x40
+#define NPCM7XX_RST_SWRSTC1	0x44
+#define NPCM7XX_RST_SWRSTC2	0x48
+#define NPCM7XX_RST_SWRSTC3	0x4C
+#define NPCM7XX_RST_SWRSTC4	0x50
+#define NPCM7XX_RST_CORSTC	0x5C
+
+#define GPIOX_MODULE_RESET	BIT(16)
+#define CA9C_MODULE_RESET	BIT(0)
+
 /* GPIO registers */
 #define NPCM7XX_GP_N_TLOCK1	0x00
 #define NPCM7XX_GP_N_DIN	0x04 /* Data IN */
@@ -94,6 +107,7 @@ struct npcm7xx_pinctrl {
 	struct npcm7xx_gpio	gpio_bank[NPCM7XX_GPIO_BANK_NUM];
 	struct irq_domain	*domain;
 	struct regmap		*gcr_regmap;
+	struct regmap		*rst_regmap;
 	void __iomem		*regs;
 	u32			bank_num;
 };
@@ -1583,6 +1597,48 @@ static int npcm7xx_set_drive_strength(struct npcm7xx_pinctrl *npcm,
 	return -ENOTSUPP;
 }
 
+static int npcm7xx_gpio_reset_persist(struct npcm7xx_pinctrl *npcm,
+					unsigned int pin, int enable)
+{
+	struct npcm7xx_gpio *bank =
+		&npcm->gpio_bank[pin / NPCM7XX_GPIO_PER_BANK];
+	int banknum = pin / bank->gc.ngpio;
+
+	if (enable) {
+		regmap_update_bits(npcm->rst_regmap, NPCM7XX_RST_WD0RCR,
+				   GPIOX_MODULE_RESET << banknum, 0);
+		regmap_update_bits(npcm->rst_regmap, NPCM7XX_RST_WD1RCR,
+				   GPIOX_MODULE_RESET << banknum, 0);
+		regmap_update_bits(npcm->rst_regmap, NPCM7XX_RST_WD2RCR,
+				   GPIOX_MODULE_RESET << banknum, 0);
+		regmap_update_bits(npcm->rst_regmap, NPCM7XX_RST_CORSTC,
+				   GPIOX_MODULE_RESET << banknum, 0);
+	} else {
+		regmap_update_bits(npcm->rst_regmap, NPCM7XX_RST_WD0RCR,
+				   (GPIOX_MODULE_RESET << banknum) |
+				   CA9C_MODULE_RESET,
+				   (GPIOX_MODULE_RESET << banknum) |
+				   CA9C_MODULE_RESET);
+		regmap_update_bits(npcm->rst_regmap, NPCM7XX_RST_WD1RCR,
+				   (GPIOX_MODULE_RESET << banknum) |
+				   CA9C_MODULE_RESET,
+				   (GPIOX_MODULE_RESET << banknum) |
+				   CA9C_MODULE_RESET);
+		regmap_update_bits(npcm->rst_regmap, NPCM7XX_RST_WD2RCR,
+				   (GPIOX_MODULE_RESET << banknum) |
+				   CA9C_MODULE_RESET,
+				   (GPIOX_MODULE_RESET << banknum) |
+				   CA9C_MODULE_RESET);
+		regmap_update_bits(npcm->rst_regmap, NPCM7XX_RST_CORSTC,
+				   (GPIOX_MODULE_RESET << banknum) |
+				   CA9C_MODULE_RESET,
+				   (GPIOX_MODULE_RESET << banknum) |
+				   CA9C_MODULE_RESET);
+	}
+
+	return 0;
+}
+
 /* pinctrl_ops */
 static void npcm7xx_pin_dbg_show(struct pinctrl_dev *pctldev,
 				 struct seq_file *s, unsigned int offset)
@@ -1852,6 +1908,8 @@ static int npcm7xx_config_set_one(struct npcm7xx_pinctrl *npcm,
 		return npcm7xx_set_slew_rate(bank, npcm->gcr_regmap, pin, arg);
 	case PIN_CONFIG_DRIVE_STRENGTH:
 		return npcm7xx_set_drive_strength(npcm, pin, arg);
+	case PIN_CONFIG_PERSIST_STATE:
+		return npcm7xx_gpio_reset_persist(npcm, pin, arg);
 	default:
 		return -ENOTSUPP;
 	}
@@ -2051,6 +2109,13 @@ static int npcm7xx_pinctrl_probe(struct platform_device *pdev)
 		return PTR_ERR(pctrl->gcr_regmap);
 	}
 
+	pctrl->rst_regmap =
+		syscon_regmap_lookup_by_compatible("nuvoton,npcm750-rst");
+	if (IS_ERR(pctrl->rst_regmap)) {
+		dev_err(pctrl->dev, "didn't find nuvoton,npcm750-rst\n");
+		return PTR_ERR(pctrl->rst_regmap);
+	}
+
 	ret = npcm7xx_gpio_of(pctrl);
 	if (ret < 0) {
 		dev_err(pctrl->dev, "Failed to gpio dt-binding %u\n", ret);
-- 
2.22.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH linux dev-5.8 v3 10/12] spi: npcm-pspi: Add full duplex support
  2021-01-13 19:59 [PATCH linux dev-5.8 v3 00/12] Add NPCM7xx patches to dev-5.8 Tomer Maimon
                   ` (8 preceding siblings ...)
  2021-01-13 20:00 ` [PATCH linux dev-5.8 v3 09/12] pinctrl: npcm7xx: Add pin persist configuration support Tomer Maimon
@ 2021-01-13 20:00 ` Tomer Maimon
  2021-01-13 20:00 ` [PATCH linux dev-5.8 v3 11/12] dt-binding: bmc: add NPCM7XX JTAG master documentation Tomer Maimon
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 19+ messages in thread
From: Tomer Maimon @ 2021-01-13 20:00 UTC (permalink / raw)
  To: openbmc; +Cc: Andrew Jeffery, Tomer Maimon, benjaminfair

Modify the IRQ handler in the NPCM PSPI
driver to support SPI full duplex communication.

Signed-off-by: Tomer Maimon <tmaimon77@gmail.com>
---
 drivers/spi/spi-npcm-pspi.c | 75 +++++++++++++++----------------------
 1 file changed, 30 insertions(+), 45 deletions(-)

diff --git a/drivers/spi/spi-npcm-pspi.c b/drivers/spi/spi-npcm-pspi.c
index 87cd0233c60b..92fae0b23eb1 100644
--- a/drivers/spi/spi-npcm-pspi.c
+++ b/drivers/spi/spi-npcm-pspi.c
@@ -197,22 +197,22 @@ static void npcm_pspi_setup_transfer(struct spi_device *spi,
 static void npcm_pspi_send(struct npcm_pspi *priv)
 {
 	int wsize;
-	u16 val;
+	u16 val = 0;
 
 	wsize = min(bytes_per_word(priv->bits_per_word), priv->tx_bytes);
 	priv->tx_bytes -= wsize;
 
-	if (!priv->tx_buf)
-		return;
-
 	switch (wsize) {
 	case 1:
-		val = *priv->tx_buf++;
+		if (priv->tx_buf)
+			val = *priv->tx_buf++;
 		iowrite8(val, NPCM_PSPI_DATA + priv->base);
 		break;
 	case 2:
-		val = *priv->tx_buf++;
-		val = *priv->tx_buf++ | (val << 8);
+		if (priv->tx_buf) {
+			val = *priv->tx_buf++;
+			val = *priv->tx_buf++ | (val << 8);
+		}
 		iowrite16(val, NPCM_PSPI_DATA + priv->base);
 		break;
 	default:
@@ -224,22 +224,24 @@ static void npcm_pspi_send(struct npcm_pspi *priv)
 static void npcm_pspi_recv(struct npcm_pspi *priv)
 {
 	int rsize;
-	u16 val;
+	u16 val_16;
+	u8  val_8;
 
 	rsize = min(bytes_per_word(priv->bits_per_word), priv->rx_bytes);
 	priv->rx_bytes -= rsize;
 
-	if (!priv->rx_buf)
-		return;
-
 	switch (rsize) {
 	case 1:
-		*priv->rx_buf++ = ioread8(priv->base + NPCM_PSPI_DATA);
+		val_8 = ioread8(priv->base + NPCM_PSPI_DATA);
+		if (priv->rx_buf)
+			*priv->rx_buf++ = val_8;
 		break;
 	case 2:
-		val = ioread16(priv->base + NPCM_PSPI_DATA);
-		*priv->rx_buf++ = (val >> 8);
-		*priv->rx_buf++ = val & 0xff;
+		val_16 = ioread16(priv->base + NPCM_PSPI_DATA);
+		if (priv->rx_buf) {
+			*priv->rx_buf++ = (val_16 >> 8);
+			*priv->rx_buf++ = val_16 & 0xff;
+		}
 		break;
 	default:
 		WARN_ON_ONCE(1);
@@ -298,43 +300,26 @@ static irqreturn_t npcm_pspi_handler(int irq, void *dev_id)
 	struct npcm_pspi *priv = dev_id;
 	u8 stat;
 
-	stat = ioread8(priv->base + NPCM_PSPI_STAT);
-
 	if (!priv->tx_buf && !priv->rx_buf)
 		return IRQ_NONE;
 
-	if (priv->tx_buf) {
-		if (stat & NPCM_PSPI_STAT_RBF) {
-			ioread8(NPCM_PSPI_DATA + priv->base);
-			if (priv->tx_bytes == 0) {
-				npcm_pspi_disable(priv);
-				complete(&priv->xfer_done);
-				return IRQ_HANDLED;
-			}
-		}
-
-		if ((stat & NPCM_PSPI_STAT_BSY) == 0)
-			if (priv->tx_bytes)
-				npcm_pspi_send(priv);
+	if (priv->tx_bytes == 0 && priv->rx_bytes == 0) {
+		npcm_pspi_disable(priv);
+		complete(&priv->xfer_done);
+		return IRQ_HANDLED;
 	}
 
-	if (priv->rx_buf) {
-		if (stat & NPCM_PSPI_STAT_RBF) {
-			if (!priv->rx_bytes)
-				return IRQ_NONE;
-
-			npcm_pspi_recv(priv);
+	stat = ioread8(priv->base + NPCM_PSPI_STAT);
 
-			if (!priv->rx_bytes) {
-				npcm_pspi_disable(priv);
-				complete(&priv->xfer_done);
-				return IRQ_HANDLED;
-			}
-		}
+	/*
+	 * first we do the read since if we do the write we previous read might
+	 * be lost (indeed low chances)
+	 */
+	if ((stat & NPCM_PSPI_STAT_RBF) && priv->rx_bytes)
+		npcm_pspi_recv(priv);
 
-		if (((stat & NPCM_PSPI_STAT_BSY) == 0) && !priv->tx_buf)
-			iowrite8(0x0, NPCM_PSPI_DATA + priv->base);
-	}
+	if (((stat & NPCM_PSPI_STAT_BSY) == 0) && priv->tx_bytes)
+		npcm_pspi_send(priv);
 
 	return IRQ_HANDLED;
 }
-- 
2.22.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH linux dev-5.8 v3 11/12] dt-binding: bmc: add NPCM7XX JTAG master documentation
  2021-01-13 19:59 [PATCH linux dev-5.8 v3 00/12] Add NPCM7xx patches to dev-5.8 Tomer Maimon
                   ` (9 preceding siblings ...)
  2021-01-13 20:00 ` [PATCH linux dev-5.8 v3 10/12] spi: npcm-pspi: Add full duplex support Tomer Maimon
@ 2021-01-13 20:00 ` Tomer Maimon
  2021-01-13 20:00 ` [PATCH linux dev-5.8 v3 12/12] misc: npcm7xx-jtag-master: add NPCM7xx JTAG master driver Tomer Maimon
  2021-01-15  6:45 ` [PATCH linux dev-5.8 v3 00/12] Add NPCM7xx patches to dev-5.8 Joel Stanley
  12 siblings, 0 replies; 19+ messages in thread
From: Tomer Maimon @ 2021-01-13 20:00 UTC (permalink / raw)
  To: openbmc; +Cc: Andrew Jeffery, Stanley Chu, Tomer Maimon, benjaminfair

Added device tree binding documentation for
Nuvoton NPCM7XX JTAG master.

Signed-off-by: Stanley Chu <yschu@nuvoton.com>
Signed-off-by: Tomer Maimon <tmaimon77@gmail.com>
---
 .../bindings/bmc/npcm7xx-jtag-master.txt      | 38 +++++++++++++++++++
 1 file changed, 38 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/bmc/npcm7xx-jtag-master.txt

diff --git a/Documentation/devicetree/bindings/bmc/npcm7xx-jtag-master.txt b/Documentation/devicetree/bindings/bmc/npcm7xx-jtag-master.txt
new file mode 100644
index 000000000000..3ad7a18ba9a2
--- /dev/null
+++ b/Documentation/devicetree/bindings/bmc/npcm7xx-jtag-master.txt
@@ -0,0 +1,38 @@
+Nuvoton NPCM7xx JTAG MASTER interface
+
+Nuvoton BMC NPCM7xx JTAG Master is used for debugging host CPU or programming
+CPLD device. The driver is implemented as an SPI device driver that enabling
+the option to transfer JTAG data with the assistance of SPI HW.
+
+Required properties for jtag_master node
+- compatible		: "nuvoton,npcm750-jtag-master" for Poleg NPCM7XX.
+- spi-max-frequency	: specify the max spi bus frequency.
+- reg 				: always 0
+- pinctrl-names		: contain 2 pinctrl states "pspi" and "gpio", which indicates
+					  the TCK/TDI/TDO pin state in HW mode(using PSPI hw) and
+					  SW mode (using GPIO bitbang) respectively.
+- tck-gpios			: specify the GPIO number of TCK pin
+- tdi-gpios			: specify the GPIO number of TDI pin
+- tdo-gpios			: specify the GPIO number of TDO pin
+- tms-gpios			: specify the GPIO number of TMS pin
+
+Example:
+spi1: spi@201000 {
+	...
+	jtag_master {
+		compatible = "nuvoton,npcm750-jtag-master";
+		spi-max-frequency = <25000000>;
+		reg = <0>;
+
+		pinctrl-names = "pspi", "gpio";
+		pinctrl-0 = <&pspi2_pins>;
+		pinctrl-1 = <&gpio17_pins &gpio18o_pins
+			&gpio19ol_pins>;
+
+		tck-gpios = <&gpio0 19 GPIO_ACTIVE_HIGH>;
+		tdi-gpios = <&gpio0 18 GPIO_ACTIVE_HIGH>;
+		tdo-gpios = <&gpio0 17 GPIO_ACTIVE_HIGH>;
+		tms-gpios = <&gpio0 16 GPIO_ACTIVE_HIGH>;
+		status = "okay";
+	};
+};
-- 
2.22.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH linux dev-5.8 v3 12/12] misc: npcm7xx-jtag-master: add NPCM7xx JTAG master driver
  2021-01-13 19:59 [PATCH linux dev-5.8 v3 00/12] Add NPCM7xx patches to dev-5.8 Tomer Maimon
                   ` (10 preceding siblings ...)
  2021-01-13 20:00 ` [PATCH linux dev-5.8 v3 11/12] dt-binding: bmc: add NPCM7XX JTAG master documentation Tomer Maimon
@ 2021-01-13 20:00 ` Tomer Maimon
  2021-01-15  6:45 ` [PATCH linux dev-5.8 v3 00/12] Add NPCM7xx patches to dev-5.8 Joel Stanley
  12 siblings, 0 replies; 19+ messages in thread
From: Tomer Maimon @ 2021-01-13 20:00 UTC (permalink / raw)
  To: openbmc; +Cc: Andrew Jeffery, Stanley Chu, Tomer Maimon, benjaminfair

Add NPCM7xx JTAG master driver,
The NPCM7xx JTAG master usign GPIO lines
and NPCM PSPI bus.

Signed-off-by: Stanley Chu <yschu@nuvoton.com>
Signed-off-by: Tomer Maimon <tmaimon77@gmail.com>
---
 drivers/misc/Kconfig               |   6 +
 drivers/misc/Makefile              |   1 +
 drivers/misc/npcm7xx-jtag-master.c | 840 +++++++++++++++++++++++++++++
 3 files changed, 847 insertions(+)
 create mode 100644 drivers/misc/npcm7xx-jtag-master.c

diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index d8626a0d3e31..1b1876284fa6 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -478,6 +478,12 @@ config NPCM7XX_PCI_MBOX
 	  Expose the NPCM750/730/715/705 PCI MBOX registers found on
 	  Nuvoton SOCs to userspace.
 
+config NPCM7XX_JTAG_MASTER
+	tristate "NPCM7xx JTAG Master driver"
+	depends on (ARCH_NPCM7XX || COMPILE_TEST)
+	help
+	  Control PSPI/GPIO to transmit jtag signals to support jtag master function.
+
 source "drivers/misc/c2port/Kconfig"
 source "drivers/misc/eeprom/Kconfig"
 source "drivers/misc/cb710/Kconfig"
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 183970192ced..b11d3c21fa03 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -59,4 +59,5 @@ obj-$(CONFIG_UACCE)		+= uacce/
 obj-$(CONFIG_XILINX_SDFEC)	+= xilinx_sdfec.o
 obj-$(CONFIG_NPCM7XX_LPC_BPC)	+= npcm7xx-lpc-bpc.o
 obj-$(CONFIG_NPCM7XX_PCI_MBOX)	+= npcm7xx-pci-mbox.o
+obj-$(CONFIG_NPCM7XX_JTAG_MASTER)	+= npcm7xx-jtag-master.o
 obj-$(CONFIG_MCTP_LPC)		+= mctp-lpc.o
diff --git a/drivers/misc/npcm7xx-jtag-master.c b/drivers/misc/npcm7xx-jtag-master.c
new file mode 100644
index 000000000000..4d254cc0e159
--- /dev/null
+++ b/drivers/misc/npcm7xx-jtag-master.c
@@ -0,0 +1,840 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Description   : JTAG Master driver
+ *
+ * Copyright (C) 2019 NuvoTon Corporation
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/uaccess.h>
+#include <linux/miscdevice.h>
+#include <linux/spi/spi.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/gpio/consumer.h>
+
+#define JTAG_PSPI_SPEED		(10 * 1000000)
+#define JTAG_SCAN_LEN		256
+#define JTAG_MAX_XFER_DATA_LEN	65535
+
+struct tck_bitbang {
+	unsigned char     tms;
+	unsigned char     tdi; /* TDI bit value to write */
+	unsigned char     tdo; /* TDO bit value to read */
+};
+
+struct bitbang_packet {
+	struct tck_bitbang *data;
+	__u32	length;
+} __attribute__((__packed__));
+
+struct scan_xfer {
+	unsigned int     length;      /* number of bits */
+	unsigned char    tdi[JTAG_SCAN_LEN];
+	unsigned int     tdi_bytes;
+	unsigned char    tdo[JTAG_SCAN_LEN];
+	unsigned int     tdo_bytes;
+	unsigned int     end_tap_state;
+};
+
+struct jtag_xfer {
+	__u8	type;
+	__u8	direction;
+	__u8	from;
+	__u8	endstate;
+	__u32	padding;
+	__u32	length;
+	__u64	tdio;
+};
+
+struct jtag_tap_state {
+	__u8	reset;
+	__u8	from;
+	__u8	endstate;
+	__u8	tck;
+};
+
+enum jtagstates {
+	jtagtlr,
+	jtagrti,
+	jtagseldr,
+	jtagcapdr,
+	jtagshfdr,
+	jtagex1dr,
+	jtagpaudr,
+	jtagex2dr,
+	jtagupddr,
+	jtagselir,
+	jtagcapir,
+	jtagshfir,
+	jtagex1ir,
+	jtagpauir,
+	jtagex2ir,
+	jtagupdir,
+	JTAG_STATE_CURRENT
+};
+
+enum JTAG_PIN {
+	pin_TCK,
+	pin_TDI,
+	pin_TDO,
+	pin_TMS,
+	pin_NUM,
+};
+
+enum jtag_reset {
+	JTAG_NO_RESET = 0,
+	JTAG_FORCE_RESET = 1,
+};
+
+enum jtag_xfer_type {
+	JTAG_SIR_XFER = 0,
+	JTAG_SDR_XFER = 1,
+	JTAG_RUNTEST_XFER,
+};
+
+enum jtag_xfer_direction {
+	JTAG_READ_XFER = 1,
+	JTAG_WRITE_XFER = 2,
+	JTAG_READ_WRITE_XFER = 3,
+};
+
+#define __JTAG_IOCTL_MAGIC	0xb2
+#define JTAG_SIOCSTATE	_IOW(__JTAG_IOCTL_MAGIC, 0, struct jtag_tap_state)
+#define JTAG_SIOCFREQ	_IOW(__JTAG_IOCTL_MAGIC, 1, unsigned int)
+#define JTAG_GIOCFREQ	_IOR(__JTAG_IOCTL_MAGIC, 2, unsigned int)
+#define JTAG_IOCXFER	_IOWR(__JTAG_IOCTL_MAGIC, 3, struct jtag_xfer)
+#define JTAG_GIOCSTATUS _IOWR(__JTAG_IOCTL_MAGIC, 4, enum jtagstates)
+#define JTAG_SIOCMODE	_IOW(__JTAG_IOCTL_MAGIC, 5, unsigned int)
+#define JTAG_IOCBITBANG	_IOW(__JTAG_IOCTL_MAGIC, 6, unsigned int)
+#define JTAG_RUNTEST    _IOW(__JTAG_IOCTL_MAGIC, 7, unsigned int)
+
+static DEFINE_IDA(jtag_ida);
+
+static unsigned char reverse[16] = {
+	0x0, 0x8, 0x4, 0xC, 0x2, 0xA, 0x6, 0xE,
+	0x1, 0x9, 0x5, 0xD, 0x3, 0xB, 0x7, 0xF
+};
+
+#define REVERSE(x)  ((reverse[((x) & 0x0f)] << 4) | reverse[((x) & 0xf0) >> 4])
+
+static DEFINE_SPINLOCK(jtag_file_lock);
+
+struct jtag_info {
+	struct device *dev;
+	struct spi_device	*spi;
+	struct miscdevice miscdev;
+	struct gpio_desc	*pins[pin_NUM];
+	struct pinctrl		*pinctrl;
+	u32 freq;
+	u8 tms_level;
+	u8 tapstate;
+	bool is_open;
+	int id;
+
+	/* transmit tck/tdi/tdo by pspi */
+	#define MODE_PSPI		0
+	/* transmit all signals by gpio */
+	#define MODE_GPIO		1
+	u8 mode;
+};
+
+/* this structure represents a TMS cycle, as expressed in a set of bits and
+ * a count of bits (note: there are no start->end state transitions that
+ * require more than 1 byte of TMS cycles)
+ */
+struct tmscycle {
+	unsigned char tmsbits;
+	unsigned char count;
+};
+
+/* this is the complete set TMS cycles for going from any TAP state to
+ * any other TAP state, following a “shortest path” rule
+ */
+const struct tmscycle _tmscyclelookup[][16] = {
+/*      TLR        RTI       SelDR      CapDR      SDR      */
+/*      Ex1DR      PDR       Ex2DR      UpdDR      SelIR    */
+/*      CapIR      SIR       Ex1IR      PIR        Ex2IR    */
+/*      UpdIR                                               */
+/* TLR */
+	{
+		{0x01, 1}, {0x00, 1}, {0x02, 2}, {0x02, 3}, {0x02, 4},
+		{0x0a, 4}, {0x0a, 5}, {0x2a, 6}, {0x1a, 5}, {0x06, 3},
+		{0x06, 4}, {0x06, 5}, {0x16, 5}, {0x16, 6}, {0x56, 7},
+		{0x36, 6}
+	},
+/* RTI */
+	{
+		{0x07, 3}, {0x00, 1}, {0x01, 1}, {0x01, 2}, {0x01, 3},
+		{0x05, 3}, {0x05, 4}, {0x15, 5}, {0x0d, 4}, {0x03, 2},
+		{0x03, 3}, {0x03, 4}, {0x0b, 4}, {0x0b, 5}, {0x2b, 6},
+		{0x1b, 5}
+	},
+/* SelDR */
+	{
+		{0x03, 2}, {0x03, 3}, {0x00, 0}, {0x00, 1}, {0x00, 2},
+		{0x02, 2}, {0x02, 3}, {0x0a, 4}, {0x06, 3}, {0x01, 1},
+		{0x01, 2}, {0x01, 3}, {0x05, 3}, {0x05, 4}, {0x15, 5},
+		{0x0d, 4}
+	},
+/* CapDR */
+	{
+		{0x1f, 5}, {0x03, 3}, {0x07, 3}, {0x00, 0}, {0x00, 1},
+		{0x01, 1}, {0x01, 2}, {0x05, 3}, {0x03, 2}, {0x0f, 4},
+		{0x0f, 5}, {0x0f, 6}, {0x2f, 6}, {0x2f, 7}, {0xaf, 8},
+		{0x6f, 7}
+	},
+/* SDR */
+	{
+		{0x1f, 5}, {0x03, 3}, {0x07, 3}, {0x07, 4}, {0x00, 0},
+		{0x01, 1}, {0x01, 2}, {0x05, 3}, {0x03, 2}, {0x0f, 4},
+		{0x0f, 5}, {0x0f, 6}, {0x2f, 6}, {0x2f, 7}, {0xaf, 8},
+		{0x6f, 7}
+	},
+/* Ex1DR */
+	{
+		{0x0f, 4}, {0x01, 2}, {0x03, 2}, {0x03, 3}, {0x02, 3},
+		{0x00, 0}, {0x00, 1}, {0x02, 2}, {0x01, 1}, {0x07, 3},
+		{0x07, 4}, {0x07, 5}, {0x17, 5}, {0x17, 6}, {0x57, 7},
+		{0x37, 6}
+	},
+/* PDR */
+	{
+		{0x1f, 5}, {0x03, 3}, {0x07, 3}, {0x07, 4}, {0x01, 2},
+		{0x05, 3}, {0x00, 1}, {0x01, 1}, {0x03, 2}, {0x0f, 4},
+		{0x0f, 5}, {0x0f, 6}, {0x2f, 6}, {0x2f, 7}, {0xaf, 8},
+		{0x6f, 7}
+	},
+/* Ex2DR */
+	{
+		{0x0f, 4}, {0x01, 2}, {0x03, 2}, {0x03, 3}, {0x00, 1},
+		{0x02, 2}, {0x02, 3}, {0x00, 0}, {0x01, 1}, {0x07, 3},
+		{0x07, 4}, {0x07, 5}, {0x17, 5}, {0x17, 6}, {0x57, 7},
+		{0x37, 6}
+	},
+/* UpdDR */
+	{
+		{0x07, 3}, {0x00, 1}, {0x01, 1}, {0x01, 2}, {0x01, 3},
+		{0x05, 3}, {0x05, 4}, {0x15, 5}, {0x00, 0}, {0x03, 2},
+		{0x03, 3}, {0x03, 4}, {0x0b, 4}, {0x0b, 5}, {0x2b, 6},
+		{0x1b, 5}
+	},
+/* SelIR */
+	{
+		{0x01, 1}, {0x01, 2}, {0x05, 3}, {0x05, 4}, {0x05, 5},
+		{0x15, 5}, {0x15, 6}, {0x55, 7}, {0x35, 6}, {0x00, 0},
+		{0x00, 1}, {0x00, 2}, {0x02, 2}, {0x02, 3}, {0x0a, 4},
+		{0x06, 3}
+	},
+/* CapIR */
+	{
+		{0x1f, 5}, {0x03, 3}, {0x07, 3}, {0x07, 4}, {0x07, 5},
+		{0x17, 5}, {0x17, 6}, {0x57, 7}, {0x37, 6}, {0x0f, 4},
+		{0x00, 0}, {0x00, 1}, {0x01, 1}, {0x01, 2}, {0x05, 3},
+		{0x03, 2}
+	},
+/* SIR */
+	{
+		{0x1f, 5}, {0x03, 3}, {0x07, 3}, {0x07, 4}, {0x07, 5},
+		{0x17, 5}, {0x17, 6}, {0x57, 7}, {0x37, 6}, {0x0f, 4},
+		{0x0f, 5}, {0x00, 0}, {0x01, 1}, {0x01, 2}, {0x05, 3},
+		{0x03, 2}
+	},
+/* Ex1IR */
+	{
+		{0x0f, 4}, {0x01, 2}, {0x03, 2}, {0x03, 3}, {0x03, 4},
+		{0x0b, 4}, {0x0b, 5}, {0x2b, 6}, {0x1b, 5}, {0x07, 3},
+		{0x07, 4}, {0x02, 3}, {0x00, 0}, {0x00, 1}, {0x02, 2},
+		{0x01, 1}
+	},
+/* PIR */
+	{
+		{0x1f, 5}, {0x03, 3}, {0x07, 3}, {0x07, 4}, {0x07, 5},
+		{0x17, 5}, {0x17, 6}, {0x57, 7}, {0x37, 6}, {0x0f, 4},
+		{0x0f, 5}, {0x01, 2}, {0x05, 3}, {0x00, 1}, {0x01, 1},
+		{0x03, 2}
+	},
+/* Ex2IR */
+	{
+		{0x0f, 4}, {0x01, 2}, {0x03, 2}, {0x03, 3}, {0x03, 4},
+		{0x0b, 4}, {0x0b, 5}, {0x2b, 6}, {0x1b, 5}, {0x07, 3},
+		{0x07, 4}, {0x00, 1}, {0x02, 2}, {0x02, 3}, {0x00, 0},
+		{0x01, 1}
+	},
+/* UpdIR */
+	{
+		{0x07, 3}, {0x00, 1}, {0x01, 1}, {0x01, 2}, {0x01, 3},
+		{0x05, 3}, {0x05, 4}, {0x15, 5}, {0x0d, 4}, {0x03, 2},
+		{0x03, 3}, {0x03, 4}, {0x0b, 4}, {0x0b, 5}, {0x2b, 6},
+		{0x00, 0}
+	},
+};
+
+static u8 TCK_cycle(struct jtag_info *jtag,
+		    unsigned char no_tdo, unsigned char TMS,
+		    unsigned char TDI)
+{
+	u32 tdo = 0;
+
+	/* IEEE 1149.1
+	 * TMS & TDI shall be sampled by the test logic on the rising edge
+	 * test logic shall change TDO on the falling edge
+	 */
+	gpiod_set_value(jtag->pins[pin_TDI], (int)TDI);
+	if (jtag->tms_level != (int)TMS) {
+		gpiod_set_value(jtag->pins[pin_TMS], (int)TMS);
+		jtag->tms_level = (int)TMS;
+	}
+	gpiod_set_value(jtag->pins[pin_TCK], 1);
+	if (!no_tdo)
+		tdo = gpiod_get_value(jtag->pins[pin_TDO]);
+	gpiod_set_value(jtag->pins[pin_TCK], 0);
+
+	return tdo;
+}
+
+static inline void npcm7xx_jtag_bitbangs(struct jtag_info *jtag,
+					 struct bitbang_packet *bitbangs,
+					 struct tck_bitbang *bitbang_data)
+{
+	int i;
+
+	for (i = 0; i < bitbangs->length; i++) {
+		bitbang_data[i].tdo =
+			TCK_cycle(jtag, 0, bitbang_data[i].tms,
+				  bitbang_data[i].tdi);
+		cond_resched();
+	}
+}
+
+static int npcm7xx_jtag_set_tapstate(struct jtag_info *jtag,
+				     enum jtagstates from, enum jtagstates to)
+{
+	unsigned char i;
+	unsigned char tmsbits;
+	unsigned char count;
+
+	if (from == to)
+		return 0;
+	if (from == JTAG_STATE_CURRENT)
+		from = jtag->tapstate;
+
+	if (from > JTAG_STATE_CURRENT || to > JTAG_STATE_CURRENT)
+		return -1;
+
+	if (to == jtagtlr) {
+		for (i = 0; i < 9; i++)
+			TCK_cycle(jtag, 1, 1, 1);
+		jtag->tapstate = jtagtlr;
+		return 0;
+	}
+
+	tmsbits = _tmscyclelookup[from][to].tmsbits;
+	count   = _tmscyclelookup[from][to].count;
+
+	if (count == 0)
+		return 0;
+
+	for (i = 0; i < count; i++) {
+		TCK_cycle(jtag, 1, (tmsbits & 1), 1);
+		tmsbits >>= 1;
+	}
+	pr_debug("jtag: change state %d -> %d\n", from, to);
+	jtag->tapstate = to;
+	return 0;
+}
+
+static int npcm7xx_jtag_switch_pin_func(struct jtag_info *jtag, u8 mode)
+{
+	struct pinctrl_state	*state;
+
+	if (mode == MODE_PSPI) {
+		state = pinctrl_lookup_state(jtag->pinctrl, "pspi");
+		if (IS_ERR(state))
+			return -ENOENT;
+
+		pinctrl_gpio_free(desc_to_gpio(jtag->pins[pin_TCK]));
+		pinctrl_gpio_free(desc_to_gpio(jtag->pins[pin_TDI]));
+		pinctrl_gpio_free(desc_to_gpio(jtag->pins[pin_TDO]));
+		pinctrl_select_state(jtag->pinctrl, state);
+	} else if (mode == MODE_GPIO) {
+		state = pinctrl_lookup_state(jtag->pinctrl, "gpio");
+		if (IS_ERR(state))
+			return -ENOENT;
+
+		pinctrl_select_state(jtag->pinctrl, state);
+		pinctrl_gpio_request(desc_to_gpio(jtag->pins[pin_TCK]));
+		pinctrl_gpio_request(desc_to_gpio(jtag->pins[pin_TDI]));
+		pinctrl_gpio_request(desc_to_gpio(jtag->pins[pin_TDO]));
+		jtag->tms_level = gpiod_get_value(jtag->pins[pin_TMS]);
+	}
+
+	return 0;
+}
+
+static int npcm7xx_jtag_xfer_spi(struct jtag_info *jtag, u32 xfer_bytes,
+				 u8 *out, u8 *in)
+{
+	struct spi_message m;
+	struct spi_transfer spi_xfer;
+	int err;
+	int i;
+
+	err = npcm7xx_jtag_switch_pin_func(jtag, MODE_PSPI);
+	if (err)
+		return err;
+
+	for (i = 0; i < xfer_bytes; i++)
+		out[i] = REVERSE(out[i]);
+
+	memset(&spi_xfer, 0, sizeof(spi_xfer));
+	spi_xfer.speed_hz = jtag->freq;
+	spi_xfer.tx_buf = out;
+	spi_xfer.rx_buf = in;
+	spi_xfer.len = xfer_bytes;
+
+	spi_message_init(&m);
+	spi_message_add_tail(&spi_xfer, &m);
+	err = spi_sync(jtag->spi, &m);
+
+	for (i = 0; i < xfer_bytes; i++)
+		in[i] = REVERSE(in[i]);
+
+	err = npcm7xx_jtag_switch_pin_func(jtag, MODE_GPIO);
+
+	return err;
+}
+
+static int npcm7xx_jtag_xfer_gpio(struct jtag_info *jtag,
+				  struct jtag_xfer *xfer, u8 *out, u8 *in)
+{
+	unsigned long *bitmap_tdi = (unsigned long *)out;
+	unsigned long *bitmap_tdo = (unsigned long *)in;
+	u32 xfer_bits = xfer->length;
+	u32 bit_index = 0;
+	u8 tdi, tdo, tms;
+
+	while (bit_index < xfer_bits) {
+		tdi = 0;
+		tms = 0;
+
+		if (test_bit(bit_index, bitmap_tdi))
+			tdi = 1;
+
+		/* If this is the last bit, leave TMS high */
+		if ((bit_index == xfer_bits - 1) && xfer->endstate != jtagshfdr &&
+		    xfer->endstate != jtagshfir && xfer->endstate != JTAG_STATE_CURRENT)
+			tms = 1;
+
+		/* shift 1 bit */
+		tdo = TCK_cycle(jtag, 0, tms, tdi);
+		cond_resched();
+		/* If it was the last bit in the scan and the end_tap_state is
+		 * something other than shiftDR or shiftIR then go to Exit1.
+		 * IMPORTANT Note: if the end_tap_state is ShiftIR/DR and the
+		 * next call to this function is a shiftDR/IR then the driver
+		 * will not change state!
+		 */
+		if (tms)
+			jtag->tapstate = (jtag->tapstate == jtagshfdr) ?
+				jtagex1dr : jtagex1ir;
+
+		if (tdo)
+			bitmap_set(bitmap_tdo, bit_index, 1);
+
+		bit_index++;
+	}
+
+	return 0;
+}
+
+static int npcm7xx_jtag_readwrite_scan(struct jtag_info *jtag,
+				       struct jtag_xfer *xfer, u8 *tdi, u8 *tdo)
+{
+	u32 xfer_bytes = DIV_ROUND_UP(xfer->length, BITS_PER_BYTE);
+	u32 remain_bits = xfer->length;
+	u32 spi_xfer_bytes = 0;
+
+	if (xfer_bytes > 1 && jtag->mode == MODE_PSPI) {
+		/* The last byte should be sent using gpio bitbang
+		 * (TMS needed)
+		 */
+		spi_xfer_bytes = xfer_bytes - 1;
+		if (npcm7xx_jtag_xfer_spi(jtag, spi_xfer_bytes, tdi, tdo))
+			return -EIO;
+		remain_bits -= spi_xfer_bytes * 8;
+	}
+
+	if (remain_bits) {
+		xfer->length = remain_bits;
+		npcm7xx_jtag_xfer_gpio(jtag, xfer, tdi + spi_xfer_bytes,
+				       tdo + spi_xfer_bytes);
+	}
+
+	npcm7xx_jtag_set_tapstate(jtag, JTAG_STATE_CURRENT, xfer->endstate);
+
+	return 0;
+}
+
+static int npcm7xx_jtag_xfer(struct jtag_info *npcm7xx_jtag,
+			     struct jtag_xfer *xfer, u8 *data, u32 bytes)
+{
+	u8 *tdo;
+	int ret;
+
+	if (xfer->length == 0)
+		return 0;
+
+	tdo = kzalloc(bytes, GFP_KERNEL);
+	if (!tdo)
+		return -ENOMEM;
+
+	if (xfer->type == JTAG_SIR_XFER)
+		npcm7xx_jtag_set_tapstate(npcm7xx_jtag, xfer->from, jtagshfir);
+	else if (xfer->type == JTAG_SDR_XFER)
+		npcm7xx_jtag_set_tapstate(npcm7xx_jtag, xfer->from, jtagshfdr);
+
+	ret = npcm7xx_jtag_readwrite_scan(npcm7xx_jtag, xfer, data, tdo);
+	memcpy(data, tdo, bytes);
+	kfree(tdo);
+
+	return ret;
+}
+
+/* Run in current state for specific number of tcks */
+static int npcm7xx_jtag_runtest(struct jtag_info *jtag, unsigned int tcks)
+{
+	struct jtag_xfer xfer;
+	u32 bytes = DIV_ROUND_UP(tcks, BITS_PER_BYTE);
+	u8 *buf;
+	u32 i;
+	int err;
+
+	if (jtag->mode != MODE_PSPI) {
+		for (i = 0; i < tcks; i++) {
+			TCK_cycle(jtag, 0, 0, 1);
+			cond_resched();
+		}
+		return 0;
+	}
+
+	buf = kzalloc(bytes, GFP_KERNEL);
+	xfer.type = JTAG_RUNTEST_XFER;
+	xfer.direction = JTAG_WRITE_XFER;
+	xfer.from = JTAG_STATE_CURRENT;
+	xfer.endstate = JTAG_STATE_CURRENT;
+	xfer.length = tcks;
+
+	err = npcm7xx_jtag_xfer(jtag, &xfer, buf, bytes);
+	kfree(buf);
+
+	return err;
+}
+
+static long jtag_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	struct jtag_info *priv = file->private_data;
+	struct jtag_tap_state tapstate;
+	void __user *argp = (void __user *)arg;
+	struct jtag_xfer xfer;
+	struct bitbang_packet bitbang;
+	struct tck_bitbang *bitbang_data;
+	u8 *xfer_data;
+	u32 data_size;
+	u32 value;
+	int ret = 0;
+
+	switch (cmd) {
+	case JTAG_SIOCFREQ:
+		if (get_user(value, (__u32 __user *)arg))
+			return -EFAULT;
+		if (value <= priv->spi->max_speed_hz) {
+			priv->freq = value;
+		} else {
+			dev_err(priv->dev, "%s: invalid jtag freq %u\n",
+				__func__, value);
+			ret = -EINVAL;
+		}
+		break;
+	case JTAG_GIOCFREQ:
+		if (put_user(priv->freq, (__u32 __user *)arg))
+			return -EFAULT;
+		break;
+	case JTAG_IOCBITBANG:
+		if (copy_from_user(&bitbang, (const void __user *)arg,
+				   sizeof(struct bitbang_packet)))
+			return -EFAULT;
+
+		if (bitbang.length >= JTAG_MAX_XFER_DATA_LEN)
+			return -EINVAL;
+
+		data_size = bitbang.length * sizeof(struct tck_bitbang);
+		bitbang_data = memdup_user((void __user *)bitbang.data,
+					   data_size);
+		if (IS_ERR(bitbang_data))
+			return -EFAULT;
+
+		npcm7xx_jtag_bitbangs(priv, &bitbang, bitbang_data);
+		ret = copy_to_user((void __user *)bitbang.data,
+				   (void *)bitbang_data, data_size);
+		kfree(bitbang_data);
+		if (ret)
+			return -EFAULT;
+		break;
+	case JTAG_SIOCSTATE:
+		if (copy_from_user(&tapstate, (const void __user *)arg,
+				   sizeof(struct jtag_tap_state)))
+			return -EFAULT;
+
+		if (tapstate.from > JTAG_STATE_CURRENT)
+			return -EINVAL;
+
+		if (tapstate.endstate > JTAG_STATE_CURRENT)
+			return -EINVAL;
+
+		if (tapstate.reset > JTAG_FORCE_RESET)
+			return -EINVAL;
+		if (tapstate.reset == JTAG_FORCE_RESET)
+			npcm7xx_jtag_set_tapstate(priv, JTAG_STATE_CURRENT,
+						  jtagtlr);
+		npcm7xx_jtag_set_tapstate(priv, tapstate.from,
+					  tapstate.endstate);
+		break;
+	case JTAG_GIOCSTATUS:
+		ret = put_user(priv->tapstate, (__u32 __user *)arg);
+		break;
+	case JTAG_IOCXFER:
+		if (copy_from_user(&xfer, argp, sizeof(struct jtag_xfer)))
+			return -EFAULT;
+
+		if (xfer.length >= JTAG_MAX_XFER_DATA_LEN)
+			return -EINVAL;
+
+		if (xfer.type > JTAG_SDR_XFER)
+			return -EINVAL;
+
+		if (xfer.direction > JTAG_READ_WRITE_XFER)
+			return -EINVAL;
+
+		if (xfer.from > JTAG_STATE_CURRENT)
+			return -EINVAL;
+
+		if (xfer.endstate > JTAG_STATE_CURRENT)
+			return -EINVAL;
+
+		data_size = DIV_ROUND_UP(xfer.length, BITS_PER_BYTE);
+		xfer_data = memdup_user(u64_to_user_ptr(xfer.tdio), data_size);
+		if (IS_ERR(xfer_data))
+			return -EFAULT;
+		ret = npcm7xx_jtag_xfer(priv, &xfer, xfer_data, data_size);
+		if (ret) {
+			kfree(xfer_data);
+			return -EIO;
+		}
+		ret = copy_to_user(u64_to_user_ptr(xfer.tdio),
+				   (void *)xfer_data, data_size);
+		kfree(xfer_data);
+		if (ret)
+			return -EFAULT;
+
+		if (copy_to_user((void __user *)arg, (void *)&xfer,
+				 sizeof(struct jtag_xfer)))
+			return -EFAULT;
+		break;
+	case JTAG_SIOCMODE:
+		if (get_user(value, (__u32 __user *)arg))
+			return -EFAULT;
+		if (value != MODE_GPIO && value != MODE_PSPI)
+			return -EINVAL;
+		priv->mode = value;
+		break;
+	case JTAG_RUNTEST:
+		ret = npcm7xx_jtag_runtest(priv, (unsigned int)arg);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return ret;
+}
+
+static int jtag_open(struct inode *inode, struct file *file)
+{
+	struct jtag_info *jtag;
+
+	jtag = container_of(file->private_data, struct jtag_info, miscdev);
+
+	spin_lock(&jtag_file_lock);
+	if (jtag->is_open) {
+		spin_unlock(&jtag_file_lock);
+		return -EBUSY;
+	}
+
+	jtag->is_open = true;
+	file->private_data = jtag;
+
+	spin_unlock(&jtag_file_lock);
+
+	return 0;
+}
+
+static int jtag_release(struct inode *inode, struct file *file)
+{
+	struct jtag_info *jtag = file->private_data;
+
+	spin_lock(&jtag_file_lock);
+	jtag->is_open = false;
+	spin_unlock(&jtag_file_lock);
+
+	return 0;
+}
+
+const struct file_operations npcm_jtag_fops = {
+	.open              = jtag_open,
+	.unlocked_ioctl    = jtag_ioctl,
+	.release           = jtag_release,
+};
+
+static int jtag_register_device(struct jtag_info *jtag)
+{
+	struct device *dev = jtag->dev;
+	int err;
+	int id;
+
+	if (!dev)
+		return -ENODEV;
+
+	id = ida_simple_get(&jtag_ida, 0, 0, GFP_KERNEL);
+	if (id < 0)
+		return id;
+
+	jtag->id = id;
+	/* register miscdev */
+	jtag->miscdev.parent = dev;
+	jtag->miscdev.fops =  &npcm_jtag_fops;
+	jtag->miscdev.minor = MISC_DYNAMIC_MINOR;
+	jtag->miscdev.name = kasprintf(GFP_KERNEL, "jtag%d", id);
+	if (!jtag->miscdev.name) {
+		err = -ENOMEM;
+		goto err;
+	}
+
+	err = misc_register(&jtag->miscdev);
+	if (err) {
+		dev_err(jtag->miscdev.parent,
+			"Unable to register device, err %d\n", err);
+		kfree(jtag->miscdev.name);
+		goto err;
+	}
+
+	return 0;
+
+err:
+	ida_simple_remove(&jtag_ida, id);
+	return err;
+}
+
+static int npcm7xx_jtag_init(struct device *dev, struct jtag_info *npcm7xx_jtag)
+{
+	struct pinctrl		*pinctrl;
+	int i;
+
+	pinctrl = devm_pinctrl_get(dev);
+	if (IS_ERR(pinctrl))
+		return PTR_ERR(pinctrl);
+
+	npcm7xx_jtag->pinctrl = pinctrl;
+
+	/* jtag pins */
+	npcm7xx_jtag->pins[pin_TCK] = gpiod_get(dev, "tck", GPIOD_OUT_LOW);
+	npcm7xx_jtag->pins[pin_TDI] = gpiod_get(dev, "tdi", GPIOD_OUT_HIGH);
+	npcm7xx_jtag->pins[pin_TDO] = gpiod_get(dev, "tdo", GPIOD_IN);
+	npcm7xx_jtag->pins[pin_TMS] = gpiod_get(dev, "tms", GPIOD_OUT_HIGH);
+	for (i = 0; i < pin_NUM; i++) {
+		if (IS_ERR(npcm7xx_jtag->pins[i]))
+			return PTR_ERR(npcm7xx_jtag->pins[i]);
+	}
+
+	npcm7xx_jtag->freq = JTAG_PSPI_SPEED;
+	npcm7xx_jtag->tms_level = gpiod_get_value(npcm7xx_jtag->pins[pin_TMS]);
+	npcm7xx_jtag_set_tapstate(npcm7xx_jtag, JTAG_STATE_CURRENT, jtagtlr);
+	npcm7xx_jtag->mode = MODE_PSPI;
+
+	return 0;
+}
+
+static int npcm7xx_jtag_probe(struct spi_device *spi)
+{
+	struct jtag_info *npcm_jtag;
+	int ret;
+
+	dev_info(&spi->dev, "%s", __func__);
+
+	npcm_jtag = kzalloc(sizeof(struct jtag_info), GFP_KERNEL);
+	if (!npcm_jtag)
+		return -ENOMEM;
+
+	npcm_jtag->dev = &spi->dev;
+	npcm_jtag->spi = spi;
+	spi->mode = SPI_MODE_0 | SPI_NO_CS;
+
+	/* Initialize device*/
+	ret = npcm7xx_jtag_init(&spi->dev, npcm_jtag);
+	if (ret)
+		goto err;
+
+	/* Register a misc device */
+	ret = jtag_register_device(npcm_jtag);
+	if (ret) {
+		dev_err(&spi->dev, "failed to create device\n");
+		goto err;
+	}
+	spi_set_drvdata(spi, npcm_jtag);
+
+	return 0;
+err:
+	kfree(npcm_jtag);
+	return ret;
+}
+
+static int npcm7xx_jtag_remove(struct spi_device  *spi)
+{
+	struct jtag_info *jtag = spi_get_drvdata(spi);
+	int i;
+
+	if (!jtag)
+		return 0;
+
+	misc_deregister(&jtag->miscdev);
+	kfree(jtag->miscdev.name);
+	for (i = 0; i < pin_NUM; i++) {
+		gpiod_direction_input(jtag->pins[i]);
+		gpiod_put(jtag->pins[i]);
+	}
+	kfree(jtag);
+	ida_simple_remove(&jtag_ida, jtag->id);
+
+	return 0;
+}
+
+static const struct of_device_id npcm7xx_jtag_of_match[] = {
+	{ .compatible = "nuvoton,npcm750-jtag-master", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, npcm7xx_jtag_of_match);
+
+static struct spi_driver npcm7xx_jtag_driver = {
+	.driver = {
+		.name		= "npcm7xx_jtag",
+		.of_match_table = npcm7xx_jtag_of_match,
+	},
+	.probe		= npcm7xx_jtag_probe,
+	.remove		= npcm7xx_jtag_remove,
+};
+
+module_spi_driver(npcm7xx_jtag_driver);
+
+MODULE_AUTHOR("Stanley Chu <yschu@nuvoton.com>");
+MODULE_DESCRIPTION("NPCM7xx JTAG Master Driver");
+MODULE_LICENSE("GPL");
+
-- 
2.22.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [PATCH linux dev-5.8 v3 07/12] pinctrl: npcm7xx: Add HGPIO pin support to NPCM7xx pinctrl driver
  2021-01-13 20:00 ` [PATCH linux dev-5.8 v3 07/12] pinctrl: npcm7xx: Add HGPIO pin support to NPCM7xx pinctrl driver Tomer Maimon
@ 2021-01-14  6:21   ` Tomer Maimon
  0 siblings, 0 replies; 19+ messages in thread
From: Tomer Maimon @ 2021-01-14  6:21 UTC (permalink / raw)
  To: OpenBMC Maillist; +Cc: Andrew Jeffery, Benjamin Fair

[-- Attachment #1: Type: text/plain, Size: 7419 bytes --]

Sorry, forgot to add it this patch already approved.


On Wed, 13 Jan 2021 at 22:00, Tomer Maimon <tmaimon77@gmail.com> wrote:

> Signed-off-by: Tomer Maimon <tmaimon77@gmail.com>


Reviewed-by: Joel Stanley <joel@jms.id.au>

> ---
>  drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c | 65 +++++++++++++++++------
>  1 file changed, 49 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c
> b/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c
> index a935065cdac4..e5f58ea89917 100644
> --- a/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c
> +++ b/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c
> @@ -504,6 +504,15 @@ static const int lkgpo2_pins[] = { 9 };
>
>  static const int nprd_smi_pins[] = { 190 };
>
> +static const int hgpio0_pins[] = { 20 };
> +static const int hgpio1_pins[] = { 21 };
> +static const int hgpio2_pins[] = { 22 };
> +static const int hgpio3_pins[] = { 23 };
> +static const int hgpio4_pins[] = { 24 };
> +static const int hgpio5_pins[] = { 25 };
> +static const int hgpio6_pins[] = { 59 };
> +static const int hgpio7_pins[] = { 60 };
> +
>  /*
>   * pin:             name, number
>   * group:    name, npins,   pins
> @@ -631,6 +640,14 @@ struct npcm7xx_group {
>         NPCM7XX_GRP(lkgpo1), \
>         NPCM7XX_GRP(lkgpo2), \
>         NPCM7XX_GRP(nprd_smi), \
> +       NPCM7XX_GRP(hgpio0), \
> +       NPCM7XX_GRP(hgpio1), \
> +       NPCM7XX_GRP(hgpio2), \
> +       NPCM7XX_GRP(hgpio3), \
> +       NPCM7XX_GRP(hgpio4), \
> +       NPCM7XX_GRP(hgpio5), \
> +       NPCM7XX_GRP(hgpio6), \
> +       NPCM7XX_GRP(hgpio7), \
>         \
>
>  enum {
> @@ -774,6 +791,14 @@ NPCM7XX_SFUNC(lkgpo0);
>  NPCM7XX_SFUNC(lkgpo1);
>  NPCM7XX_SFUNC(lkgpo2);
>  NPCM7XX_SFUNC(nprd_smi);
> +NPCM7XX_SFUNC(hgpio0);
> +NPCM7XX_SFUNC(hgpio1);
> +NPCM7XX_SFUNC(hgpio2);
> +NPCM7XX_SFUNC(hgpio3);
> +NPCM7XX_SFUNC(hgpio4);
> +NPCM7XX_SFUNC(hgpio5);
> +NPCM7XX_SFUNC(hgpio6);
> +NPCM7XX_SFUNC(hgpio7);
>
>  /* Function names */
>  static struct npcm7xx_func npcm7xx_funcs[] = {
> @@ -892,6 +917,14 @@ static struct npcm7xx_func npcm7xx_funcs[] = {
>         NPCM7XX_MKFUNC(lkgpo1),
>         NPCM7XX_MKFUNC(lkgpo2),
>         NPCM7XX_MKFUNC(nprd_smi),
> +       NPCM7XX_MKFUNC(hgpio0),
> +       NPCM7XX_MKFUNC(hgpio1),
> +       NPCM7XX_MKFUNC(hgpio2),
> +       NPCM7XX_MKFUNC(hgpio3),
> +       NPCM7XX_MKFUNC(hgpio4),
> +       NPCM7XX_MKFUNC(hgpio5),
> +       NPCM7XX_MKFUNC(hgpio6),
> +       NPCM7XX_MKFUNC(hgpio7),
>  };
>
>  #define NPCM7XX_PINCFG(a, b, c, d, e, f, g, h, i, j, k) \
> @@ -944,12 +977,12 @@ static const struct npcm7xx_pincfg pincfg[] = {
>         NPCM7XX_PINCFG(17,      pspi2, MFSEL3, 13,     smb4den, I2CSEGSEL,
> 23,  none, NONE, 0,       DS(8, 12)),
>         NPCM7XX_PINCFG(18,      pspi2, MFSEL3, 13,       smb4b, I2CSEGSEL,
> 14,  none, NONE, 0,       DS(8, 12)),
>         NPCM7XX_PINCFG(19,      pspi2, MFSEL3, 13,       smb4b, I2CSEGSEL,
> 14,  none, NONE, 0,       DS(8, 12)),
> -       NPCM7XX_PINCFG(20,      smb4c, I2CSEGSEL, 15,    smb15, MFSEL3,
> 8,      none, NONE, 0,       0),
> -       NPCM7XX_PINCFG(21,      smb4c, I2CSEGSEL, 15,    smb15, MFSEL3,
> 8,      none, NONE, 0,       0),
> -       NPCM7XX_PINCFG(22,      smb4d, I2CSEGSEL, 16,    smb14, MFSEL3,
> 7,      none, NONE, 0,       0),
> -       NPCM7XX_PINCFG(23,      smb4d, I2CSEGSEL, 16,    smb14, MFSEL3,
> 7,      none, NONE, 0,       0),
> -       NPCM7XX_PINCFG(24,       ioxh, MFSEL3, 18,        none, NONE, 0,
>       none, NONE, 0,       DS(8, 12)),
> -       NPCM7XX_PINCFG(25,       ioxh, MFSEL3, 18,        none, NONE, 0,
>       none, NONE, 0,       DS(8, 12)),
> +       NPCM7XX_PINCFG(20,      hgpio0, MFSEL2, 24,      smb15, MFSEL3,
> 8,      smb4c, I2CSEGSEL, 15,        0),
> +       NPCM7XX_PINCFG(21,      hgpio1, MFSEL2, 25,      smb15, MFSEL3,
> 8,      smb4c, I2CSEGSEL, 15,        0),
> +       NPCM7XX_PINCFG(22,      hgpio2, MFSEL2, 26,      smb14, MFSEL3,
> 7,      smb4d, I2CSEGSEL, 16,        0),
> +       NPCM7XX_PINCFG(23,      hgpio3, MFSEL2, 27,      smb14, MFSEL3,
> 7,      smb4d, I2CSEGSEL, 16,        0),
> +       NPCM7XX_PINCFG(24,       hgpio4, MFSEL2, 28,    ioxh, MFSEL3, 18,
>      none, NONE, 0,       DS(8, 12)),
> +       NPCM7XX_PINCFG(25,       hgpio5, MFSEL2, 29,    ioxh, MFSEL3, 18,
>      none, NONE, 0,       DS(8, 12)),
>         NPCM7XX_PINCFG(26,       smb5, MFSEL1, 2,         none, NONE, 0,
>       none, NONE, 0,       0),
>         NPCM7XX_PINCFG(27,       smb5, MFSEL1, 2,         none, NONE, 0,
>       none, NONE, 0,       0),
>         NPCM7XX_PINCFG(28,       smb4, MFSEL1, 1,         none, NONE, 0,
>       none, NONE, 0,       0),
> @@ -982,8 +1015,8 @@ static const struct npcm7xx_pincfg pincfg[] = {
>         NPCM7XX_PINCFG(56,      r1err, MFSEL1, 12,        none, NONE, 0,
>       none, NONE, 0,       0),
>         NPCM7XX_PINCFG(57,       r1md, MFSEL1, 13,        none, NONE, 0,
>       none, NONE, 0,       DS(2, 4)),
>         NPCM7XX_PINCFG(58,       r1md, MFSEL1, 13,        none, NONE, 0,
>       none, NONE, 0,       DS(2, 4)),
> -       NPCM7XX_PINCFG(59,      smb3d, I2CSEGSEL, 13,     none, NONE, 0,
>       none, NONE, 0,       0),
> -       NPCM7XX_PINCFG(60,      smb3d, I2CSEGSEL, 13,     none, NONE, 0,
>       none, NONE, 0,       0),
> +       NPCM7XX_PINCFG(59,      hgpio6, MFSEL2, 30,       smb3d,
> I2CSEGSEL, 13, none, NONE, 0,       0),
> +       NPCM7XX_PINCFG(60,      hgpio7, MFSEL2, 31,       smb3d,
> I2CSEGSEL, 13, none, NONE, 0,       0),
>         NPCM7XX_PINCFG(61,      uart1, MFSEL1, 10,        none, NONE, 0,
>       none, NONE, 0,     GPO),
>         NPCM7XX_PINCFG(62,      uart1, MFSEL1, 10,    bmcuart1, MFSEL3,
> 24,     none, NONE, 0,     GPO),
>         NPCM7XX_PINCFG(63,      uart1, MFSEL1, 10,    bmcuart1, MFSEL3,
> 24,     none, NONE, 0,     GPO),
> @@ -1188,12 +1221,12 @@ static const struct pinctrl_pin_desc
> npcm7xx_pins[] = {
>         PINCTRL_PIN(17, "GPIO17/PSPI2DI/SMB4DEN"),
>         PINCTRL_PIN(18, "GPIO18/PSPI2D0/SMB4BSDA"),
>         PINCTRL_PIN(19, "GPIO19/PSPI2CK/SMB4BSCL"),
> -       PINCTRL_PIN(20, "GPIO20/SMB4CSDA/SMB15SDA"),
> -       PINCTRL_PIN(21, "GPIO21/SMB4CSCL/SMB15SCL"),
> -       PINCTRL_PIN(22, "GPIO22/SMB4DSDA/SMB14SDA"),
> -       PINCTRL_PIN(23, "GPIO23/SMB4DSCL/SMB14SCL"),
> -       PINCTRL_PIN(24, "GPIO24/IOXHDO"),
> -       PINCTRL_PIN(25, "GPIO25/IOXHDI"),
> +       PINCTRL_PIN(20, "GPIO20/HGPIO0/SMB4CSDA/SMB15SDA"),
> +       PINCTRL_PIN(21, "GPIO21/HGPIO1/SMB4CSCL/SMB15SCL"),
> +       PINCTRL_PIN(22, "GPIO22/HGPIO2/SMB4DSDA/SMB14SDA"),
> +       PINCTRL_PIN(23, "GPIO23/HGPIO3/SMB4DSCL/SMB14SCL"),
> +       PINCTRL_PIN(24, "GPIO24/HGPIO4/IOXHDO"),
> +       PINCTRL_PIN(25, "GPIO25/HGPIO5/IOXHDI"),
>         PINCTRL_PIN(26, "GPIO26/SMB5SDA"),
>         PINCTRL_PIN(27, "GPIO27/SMB5SCL"),
>         PINCTRL_PIN(28, "GPIO28/SMB4SDA"),
> @@ -1226,8 +1259,8 @@ static const struct pinctrl_pin_desc npcm7xx_pins[]
> = {
>         PINCTRL_PIN(56, "GPIO56/R1RXERR"),
>         PINCTRL_PIN(57, "GPIO57/R1MDC"),
>         PINCTRL_PIN(58, "GPIO58/R1MDIO"),
> -       PINCTRL_PIN(59, "GPIO59/SMB3DSDA"),
> -       PINCTRL_PIN(60, "GPIO60/SMB3DSCL"),
> +       PINCTRL_PIN(59, "GPIO59/HGPIO6/SMB3DSDA"),
> +       PINCTRL_PIN(60, "GPIO60/HGPIO7/SMB3DSCL"),
>         PINCTRL_PIN(61, "GPO61/nDTR1_BOUT1/STRAP6"),
>         PINCTRL_PIN(62, "GPO62/nRTST1/STRAP5"),
>         PINCTRL_PIN(63, "GPO63/TXD1/STRAP4"),
> --
> 2.22.0
>
>

[-- Attachment #2: Type: text/html, Size: 9403 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH linux dev-5.8 v3 01/12] clk: npcm7xx: add read only flag to divider clocks
  2021-01-13 19:59 ` [PATCH linux dev-5.8 v3 01/12] clk: npcm7xx: add read only flag to divider clocks Tomer Maimon
@ 2021-01-15  6:22   ` Joel Stanley
  0 siblings, 0 replies; 19+ messages in thread
From: Joel Stanley @ 2021-01-15  6:22 UTC (permalink / raw)
  To: Tomer Maimon; +Cc: Andrew Jeffery, OpenBMC Maillist, Benjamin Fair

On Wed, 13 Jan 2021 at 20:00, Tomer Maimon <tmaimon77@gmail.com> wrote:
>
> Add read only flag to all divider clocks except
> SPI3 clock.
>
> Signed-off-by: Tomer Maimon <tmaimon77@gmail.com>

Reviewed-by: Joel Stanley <joel@jms.id.au>

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH linux dev-5.8 v3 03/12] iio: adc: add calibration support to npcm ADC
  2021-01-13 20:00 ` [PATCH linux dev-5.8 v3 03/12] iio: adc: add calibration support to npcm ADC Tomer Maimon
@ 2021-01-15  6:25   ` Joel Stanley
  0 siblings, 0 replies; 19+ messages in thread
From: Joel Stanley @ 2021-01-15  6:25 UTC (permalink / raw)
  To: Tomer Maimon; +Cc: Andrew Jeffery, OpenBMC Maillist, Benjamin Fair

On Wed, 13 Jan 2021 at 20:00, Tomer Maimon <tmaimon77@gmail.com> wrote:
>
> Add calibration to improve accuracy measurement when using
> internal reference voltage.
>
> the calibration values taken from the FUSE module.
>
> Signed-off-by: Tomer Maimon <tmaimon77@gmail.com>

Reviewed-by: Joel Stanley <joel@jms.id.au>

When submitting this to mainline you should consider putting the fuse
reading code in it's own driver if it is to be used by other
components in your system.

> ---
>  drivers/iio/adc/npcm_adc.c | 178 +++++++++++++++++++++++++++++++++++++
>  1 file changed, 178 insertions(+)
>
> diff --git a/drivers/iio/adc/npcm_adc.c b/drivers/iio/adc/npcm_adc.c
> index 83bad2d5575d..081378b98fa9 100644
> --- a/drivers/iio/adc/npcm_adc.c
> +++ b/drivers/iio/adc/npcm_adc.c
> @@ -17,6 +17,8 @@
>  #include <linux/reset.h>
>
>  struct npcm_adc {
> +       u32 R05;
> +       u32 R15;
>         bool int_status;
>         u32 adc_sample_hz;
>         struct device *dev;
> @@ -51,6 +53,41 @@ struct npcm_adc {
>  #define NPCM_RESOLUTION_BITS           10
>  #define NPCM_INT_VREF_MV               2000
>
> +/* FUSE registers */
> +#define NPCM7XX_FST            0x00
> +#define NPCM7XX_FADDR          0x04
> +#define NPCM7XX_FDATA          0x08
> +#define NPCM7XX_FCFG           0x0C
> +#define NPCM7XX_FCTL           0x14
> +
> +/* FST Register Bits */
> +#define NPCM7XX_FST_RDY                BIT(0)
> +#define NPCM7XX_FST_RDST       BIT(1)
> +
> +/* FADDR Register Bits */
> +#define NPCM7XX_FADDR_BYTEADDR         BIT(0)
> +#define NPCM7XX_FADDR_BYTEADDR_MASK    GENMASK(9, 0)
> +
> +/* FADDR Register Bits */
> +#define NPCM7XX_FDATA_DATA             BIT(0)
> +#define NPCM7XX_FDATA_CLEAN_VALUE      BIT(1)
> +#define NPCM7XX_FDATA_DATA_MASK                GENMASK(7, 0)
> +
> +/* FCTL Register Bits */
> +#define NPCM7XX_FCTL_RDST              BIT(1)
> +
> +/* ADC Calibration Definition */
> +#define NPCM_INT_1500MV                768
> +#define NPCM_INT_1000MV                512
> +#define NPCM_ADC_MIN_VAL       0
> +#define NPCM_ADC_MAX_VAL       1023
> +
> +#define FUSE_CALIB_ADDR                24
> +#define FUSE_CALIB_SIZE                8
> +#define DATA_CALIB_SIZE                4
> +#define FUSE_READ_SLEEP                500
> +#define FUSE_READ_TIMEOUT      1000000
> +
>  #define NPCM_ADC_CHAN(ch) {                                    \
>         .type = IIO_VOLTAGE,                                    \
>         .indexed = 1,                                           \
> @@ -71,6 +108,119 @@ static const struct iio_chan_spec npcm_adc_iio_channels[] = {
>         NPCM_ADC_CHAN(7),
>  };
>
> +static void npcm750_fuse_read(struct regmap *fuse_regmap, u32 addr, u8 *data)
> +{
> +       u32 val;
> +       u32 fstreg;
> +
> +       regmap_read_poll_timeout(fuse_regmap, NPCM7XX_FST, fstreg,
> +                                fstreg & NPCM7XX_FST_RDY, FUSE_READ_SLEEP,
> +                                FUSE_READ_TIMEOUT);
> +       regmap_write_bits(fuse_regmap, NPCM7XX_FST,
> +                         NPCM7XX_FST_RDST, NPCM7XX_FST_RDST);
> +
> +       regmap_write_bits(fuse_regmap, NPCM7XX_FADDR,
> +                         NPCM7XX_FADDR_BYTEADDR_MASK, addr);
> +       regmap_read(fuse_regmap, NPCM7XX_FADDR, &val);
> +       regmap_write(fuse_regmap, NPCM7XX_FCTL, NPCM7XX_FCTL_RDST);
> +
> +       regmap_read_poll_timeout(fuse_regmap, NPCM7XX_FST, fstreg,
> +                                fstreg & NPCM7XX_FST_RDY, FUSE_READ_SLEEP,
> +                                FUSE_READ_TIMEOUT);
> +       regmap_write_bits(fuse_regmap, NPCM7XX_FST,
> +                         NPCM7XX_FST_RDST, NPCM7XX_FST_RDST);
> +
> +       regmap_read(fuse_regmap, NPCM7XX_FDATA, &val);
> +       *data = (u8)val;
> +
> +       regmap_write_bits(fuse_regmap, NPCM7XX_FDATA, NPCM7XX_FDATA_DATA_MASK,
> +                         NPCM7XX_FDATA_CLEAN_VALUE);
> +}
> +
> +static int npcm750_ECC_to_nibble(u8 ECC, u8 nibble)
> +{
> +       u8 nibble_b0 = (nibble >> 0) & BIT(0);
> +       u8 nibble_b1 = (nibble >> 1) & BIT(0);
> +       u8 nibble_b2 = (nibble >> 2) & BIT(0);
> +       u8 nibble_b3 = (nibble >> 3) & BIT(0);
> +       u8 tmp_ECC = nibble;
> +
> +       tmp_ECC |= (nibble_b0 ^ nibble_b1) << 4 | (nibble_b2 ^ nibble_b3) << 5 |
> +               (nibble_b0 ^ nibble_b2) << 6  | (nibble_b1 ^ nibble_b3) << 7;
> +
> +       if (tmp_ECC != ECC)
> +               return -EINVAL;
> +
> +       return 0;
> +}
> +
> +static int npcm750_ECC_to_byte(u16 ECC, u8 *Byte)
> +{
> +       u8 nibble_L, nibble_H;
> +       u8 ECC_L, ECC_H;
> +
> +       ECC_H = ECC >> 8;
> +       nibble_H = ECC_H & 0x0F;
> +       ECC_L = ECC >> 0;
> +       nibble_L = ECC_L & 0x0F;
> +
> +       if (npcm750_ECC_to_nibble(ECC_H, nibble_H) != 0 ||
> +           npcm750_ECC_to_nibble(ECC_L, nibble_L) != 0)
> +               return -EINVAL;
> +
> +       *Byte = nibble_H << 4 | nibble_L << 0;
> +
> +       return 0;
> +}
> +
> +static int npcm750_read_nibble_parity(u8 *block_ECC, u8 *ADC_calib)
> +{
> +       int i;
> +       u16 ECC;
> +
> +       for (i = 0; i < DATA_CALIB_SIZE; i++) {
> +               memcpy(&ECC, block_ECC + (i * 2), 2);
> +               if (npcm750_ECC_to_byte(ECC, &ADC_calib[i]) != 0)
> +                       return -EINVAL;
> +       }
> +
> +       return 0;
> +}
> +
> +static int npcm750_fuse_calibration_read(struct platform_device *pdev,
> +                                        struct npcm_adc *info)
> +{
> +       struct device_node *np = pdev->dev.of_node;
> +       struct regmap *fuse_regmap;
> +       ssize_t bytes_read = 0;
> +       u8 read_buf[8];
> +       u32 ADC_calib;
> +       u32 addr = FUSE_CALIB_ADDR;
> +
> +       fuse_regmap = syscon_regmap_lookup_by_phandle(np, "syscon");
> +       if (IS_ERR(fuse_regmap)) {
> +               dev_warn(&pdev->dev, "Failed to find syscon\n");
> +               return PTR_ERR(fuse_regmap);
> +       }
> +
> +       while (bytes_read < FUSE_CALIB_SIZE) {
> +               npcm750_fuse_read(fuse_regmap, addr,
> +                                 &read_buf[bytes_read]);
> +               bytes_read++;
> +               addr++;
> +       }
> +
> +       if (npcm750_read_nibble_parity(read_buf, (u8 *)&ADC_calib)) {
> +               dev_warn(info->dev, "FUSE Calibration read failed\n");
> +               return -EINVAL;
> +       }
> +
> +       info->R05 = ADC_calib & 0xFFFF;
> +       info->R15 = ADC_calib >> 16;
> +
> +       return 0;
> +}
> +
>  static irqreturn_t npcm_adc_isr(int irq, void *data)
>  {
>         u32 regtemp;
> @@ -125,6 +275,29 @@ static int npcm_adc_read(struct npcm_adc *info, int *val, u8 channel)
>         return 0;
>  }
>
> +static void npcm_adc_calibration(int *val, struct npcm_adc *info)
> +{
> +       int mul_val;
> +       int offset_val;
> +
> +       mul_val = NPCM_INT_1000MV * (*val - info->R15);
> +       if (mul_val < 0) {
> +               mul_val = mul_val * -1;
> +               offset_val = DIV_ROUND_CLOSEST(mul_val,
> +                                              (info->R15 - info->R05));
> +               *val = NPCM_INT_1500MV - offset_val;
> +       } else {
> +               offset_val = DIV_ROUND_CLOSEST(mul_val,
> +                                              (info->R15 - info->R05));
> +               *val = NPCM_INT_1500MV + offset_val;
> +       }
> +
> +       if (*val < NPCM_ADC_MIN_VAL)
> +               *val = NPCM_ADC_MIN_VAL;
> +       if (*val > NPCM_ADC_MAX_VAL)
> +               *val = NPCM_ADC_MAX_VAL;
> +}
> +
>  static int npcm_adc_read_raw(struct iio_dev *indio_dev,
>                              struct iio_chan_spec const *chan, int *val,
>                              int *val2, long mask)
> @@ -142,6 +315,10 @@ static int npcm_adc_read_raw(struct iio_dev *indio_dev,
>                         dev_err(info->dev, "NPCM ADC read failed\n");
>                         return ret;
>                 }
> +
> +               if ((info->R05 || info->R15) && IS_ERR(info->vref))
> +                       npcm_adc_calibration(val, info);
> +
>                 return IIO_VAL_INT;
>         case IIO_CHAN_INFO_SCALE:
>                 if (!IS_ERR(info->vref)) {
> @@ -248,6 +425,7 @@ static int npcm_adc_probe(struct platform_device *pdev)
>                           info->regs + NPCM_ADCCON);
>         }
>
> +       npcm750_fuse_calibration_read(pdev, info);
>         init_waitqueue_head(&info->wq);
>
>         reg_con = ioread32(info->regs + NPCM_ADCCON);
> --
> 2.22.0
>

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH linux dev-5.8 v3 04/12] dts: npcm750: add fuse regmap support node
  2021-01-13 20:00 ` [PATCH linux dev-5.8 v3 04/12] dts: npcm750: add fuse regmap support node Tomer Maimon
@ 2021-01-15  6:27   ` Joel Stanley
  0 siblings, 0 replies; 19+ messages in thread
From: Joel Stanley @ 2021-01-15  6:27 UTC (permalink / raw)
  To: Tomer Maimon; +Cc: Andrew Jeffery, OpenBMC Maillist, Benjamin Fair

On Wed, 13 Jan 2021 at 20:00, Tomer Maimon <tmaimon77@gmail.com> wrote:
>
> Signed-off-by: Tomer Maimon <tmaimon77@gmail.com>

Reviewed-by: Joel Stanley <joel@jms.id.au>

> ---
>  arch/arm/boot/dts/nuvoton-common-npcm7xx.dtsi | 6 ++++++
>  1 file changed, 6 insertions(+)
>
> diff --git a/arch/arm/boot/dts/nuvoton-common-npcm7xx.dtsi b/arch/arm/boot/dts/nuvoton-common-npcm7xx.dtsi
> index 7eee4145127f..455a96b23b85 100644
> --- a/arch/arm/boot/dts/nuvoton-common-npcm7xx.dtsi
> +++ b/arch/arm/boot/dts/nuvoton-common-npcm7xx.dtsi
> @@ -82,6 +82,12 @@
>                         "simple-mfd";
>                         reg = <0x801000 0x6C>;
>                 };
> +
> +               fuse:fuse@18a000 {

Convention is to put a space after the colon. No need to re-post,
but remember this for future patches.


> +                       compatible = "nuvoton,npcm750-fuse", "syscon",
> +                               "simple-mfd";
> +                       reg = <0x18a000 0x1000>;
> +               };
>
>                 scu: scu@3fe000 {
>                         compatible = "arm,cortex-a9-scu";
> --
> 2.22.0
>

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH linux dev-5.8 v3 02/12] dt-binding: iio: add syscon property to NPCM ADC
  2021-01-13 20:00 ` [PATCH linux dev-5.8 v3 02/12] dt-binding: iio: add syscon property to NPCM ADC Tomer Maimon
@ 2021-01-15  6:27   ` Joel Stanley
  0 siblings, 0 replies; 19+ messages in thread
From: Joel Stanley @ 2021-01-15  6:27 UTC (permalink / raw)
  To: Tomer Maimon; +Cc: Andrew Jeffery, OpenBMC Maillist, Benjamin Fair

On Wed, 13 Jan 2021 at 20:00, Tomer Maimon <tmaimon77@gmail.com> wrote:
>
> Add syscon property to NPCM ADC to handle FUSE
> registers.
>
> Signed-off-by: Tomer Maimon <tmaimon77@gmail.com>

Reviewed-by: Joel Stanley <joel@jms.id.au>

> ---
>  Documentation/devicetree/bindings/iio/adc/nuvoton,npcm-adc.txt | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/iio/adc/nuvoton,npcm-adc.txt b/Documentation/devicetree/bindings/iio/adc/nuvoton,npcm-adc.txt
> index ef8eeec1a997..faf9f9b54f5b 100644
> --- a/Documentation/devicetree/bindings/iio/adc/nuvoton,npcm-adc.txt
> +++ b/Documentation/devicetree/bindings/iio/adc/nuvoton,npcm-adc.txt
> @@ -14,6 +14,7 @@ Optional properties:
>  - vref-supply: The regulator supply ADC reference voltage, in case the
>                            vref-supply is not added the ADC will use internal voltage
>                            reference.
> +- syscon: a phandle to access FUSE registers
>
>  Example:
>
> @@ -23,4 +24,5 @@ adc: adc@f000c000 {
>         interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>;
>         clocks = <&clk NPCM7XX_CLK_ADC>;
>         resets = <&rstc NPCM7XX_RESET_IPSRST1 NPCM7XX_RESET_ADC>;
> +       syscon = <&fuse>;
>  };
> --
> 2.22.0
>

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH linux dev-5.8 v3 00/12] Add NPCM7xx patches to dev-5.8
  2021-01-13 19:59 [PATCH linux dev-5.8 v3 00/12] Add NPCM7xx patches to dev-5.8 Tomer Maimon
                   ` (11 preceding siblings ...)
  2021-01-13 20:00 ` [PATCH linux dev-5.8 v3 12/12] misc: npcm7xx-jtag-master: add NPCM7xx JTAG master driver Tomer Maimon
@ 2021-01-15  6:45 ` Joel Stanley
  12 siblings, 0 replies; 19+ messages in thread
From: Joel Stanley @ 2021-01-15  6:45 UTC (permalink / raw)
  To: Tomer Maimon; +Cc: Andrew Jeffery, OpenBMC Maillist, Benjamin Fair

Hi Tomer,

On Wed, 13 Jan 2021 at 20:00, Tomer Maimon <tmaimon77@gmail.com> wrote:
>
> In this patch set we will like to align with relevant modifications
> in Nuvoton OpenBMC Linux kernel 5.4.

I've reviewed some of the patches. There is some work to be done
before some of them will be accepted for mainline, but nothing that
blocks them from being in the openbmc tree, so I have merged the
series.

I've bumped the kernel in meta-nuvoton, please review that change:

 https://gerrit.openbmc-project.xyz/c/openbmc/meta-nuvoton/+/39742

Cheers,

Joel

>
> Linux upstream current status:
>         1. npcm7xx clock driver - adding read only
>                 flag to divider clocks, Will be sent to Linux community.
>         2. Adding NPCM ADC calibration - Will be sent to Linux vanilla,
>                 but I am not sure it will be approved.
>         3. Add DT restart priority and reset type support - sent to Linux
>                 community la but havent approved yet.
>         4. persist configuration to the pin control driver - asked by a costumer,
>                 didnt sent to Linux community.
>         5. Add HGPIO pin support to NPCM7xx pinctrl driver - will be sent
>                 to Linux community
>         6. JTAG master driver - will be sent to Linux community once we will
>                 have BMC folder.
>
> Changes since version 2:
> - Address comments from Joel Stanley
>
> Changes since version 1:
> - Address comments from Jonathan Neuschäfer: removing trailing whitespace
>         in NPCM watchdog documentation.
> - Adding Stanley Chu to NPCM JTAG master driver
>
>
> Tomer Maimon (12):
>   clk: npcm7xx: add read only flag to divider clocks
>   dt-binding: iio: add syscon property to NPCM ADC
>   iio: adc: add calibration support to npcm ADC
>   dts: npcm750: add fuse regmap support node
>   dt-binding: watchdog: Add DT restart priority and reset type
>   watchdog: npcm: Add DT restart priority and reset type support
>   pinctrl: npcm7xx: Add HGPIO pin support to NPCM7xx pinctrl driver
>   pinctrl: pinconf: add pin persist configuration
>   pinctrl: npcm7xx: Add pin persist configuration support
>   spi: npcm-pspi: Add full duplex support
>   dt-binding: bmc: add NPCM7XX JTAG master documentation
>   misc: npcm7xx-jtag-master: add NPCM7xx JTAG master driver
>
>  .../bindings/bmc/npcm7xx-jtag-master.txt      |  38 +
>  .../bindings/iio/adc/nuvoton,npcm-adc.txt     |   2 +
>  .../bindings/watchdog/nuvoton,npcm-wdt.txt    |  34 +
>  arch/arm/boot/dts/nuvoton-common-npcm7xx.dtsi |   6 +
>  drivers/clk/clk-npcm7xx.c                     |  70 +-
>  drivers/iio/adc/npcm_adc.c                    | 178 ++++
>  drivers/misc/Kconfig                          |   6 +
>  drivers/misc/Makefile                         |   1 +
>  drivers/misc/npcm7xx-jtag-master.c            | 840 ++++++++++++++++++
>  drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c     | 130 ++-
>  drivers/pinctrl/pinconf-generic.c             |   3 +
>  drivers/spi/spi-npcm-pspi.c                   |  75 +-
>  drivers/watchdog/npcm_wdt.c                   | 117 ++-
>  13 files changed, 1404 insertions(+), 96 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/bmc/npcm7xx-jtag-master.txt
>  create mode 100644 drivers/misc/npcm7xx-jtag-master.c
>
> --
> 2.22.0
>

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2021-01-15  6:47 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-13 19:59 [PATCH linux dev-5.8 v3 00/12] Add NPCM7xx patches to dev-5.8 Tomer Maimon
2021-01-13 19:59 ` [PATCH linux dev-5.8 v3 01/12] clk: npcm7xx: add read only flag to divider clocks Tomer Maimon
2021-01-15  6:22   ` Joel Stanley
2021-01-13 20:00 ` [PATCH linux dev-5.8 v3 02/12] dt-binding: iio: add syscon property to NPCM ADC Tomer Maimon
2021-01-15  6:27   ` Joel Stanley
2021-01-13 20:00 ` [PATCH linux dev-5.8 v3 03/12] iio: adc: add calibration support to npcm ADC Tomer Maimon
2021-01-15  6:25   ` Joel Stanley
2021-01-13 20:00 ` [PATCH linux dev-5.8 v3 04/12] dts: npcm750: add fuse regmap support node Tomer Maimon
2021-01-15  6:27   ` Joel Stanley
2021-01-13 20:00 ` [PATCH linux dev-5.8 v3 05/12] dt-binding: watchdog: Add DT restart priority and reset type Tomer Maimon
2021-01-13 20:00 ` [PATCH linux dev-5.8 v3 06/12] watchdog: npcm: Add DT restart priority and reset type support Tomer Maimon
2021-01-13 20:00 ` [PATCH linux dev-5.8 v3 07/12] pinctrl: npcm7xx: Add HGPIO pin support to NPCM7xx pinctrl driver Tomer Maimon
2021-01-14  6:21   ` Tomer Maimon
2021-01-13 20:00 ` [PATCH linux dev-5.8 v3 08/12] pinctrl: pinconf: add pin persist configuration Tomer Maimon
2021-01-13 20:00 ` [PATCH linux dev-5.8 v3 09/12] pinctrl: npcm7xx: Add pin persist configuration support Tomer Maimon
2021-01-13 20:00 ` [PATCH linux dev-5.8 v3 10/12] spi: npcm-pspi: Add full duplex support Tomer Maimon
2021-01-13 20:00 ` [PATCH linux dev-5.8 v3 11/12] dt-binding: bmc: add NPCM7XX JTAG master documentation Tomer Maimon
2021-01-13 20:00 ` [PATCH linux dev-5.8 v3 12/12] misc: npcm7xx-jtag-master: add NPCM7xx JTAG master driver Tomer Maimon
2021-01-15  6:45 ` [PATCH linux dev-5.8 v3 00/12] Add NPCM7xx patches to dev-5.8 Joel Stanley

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.