From patchwork Tue Jan 5 13:44:58 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomer Maimon X-Patchwork-Id: 1422467 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4D9Ddw3Z2nz9sVk for ; Wed, 6 Jan 2021 01:00:04 +1100 (AEDT) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Received: from bilbo.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 4D9Ddw1gjdzDqfG for ; Wed, 6 Jan 2021 01:00:04 +1100 (AEDT) X-Original-To: openbmc@lists.ozlabs.org Delivered-To: openbmc@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=none (no SPF record) smtp.mailfrom=nuvoton.com (client-ip=212.199.177.27; helo=herzl.nuvoton.co.il; envelope-from=tomer.maimon@nuvoton.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Received: from herzl.nuvoton.co.il (212.199.177.27.static.012.net.il [212.199.177.27]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 4D9DKR1s6RzDqb1 for ; Wed, 6 Jan 2021 00:45:46 +1100 (AEDT) Received: from taln60.nuvoton.co.il (ntil-fw [212.199.177.25]) by herzl.nuvoton.co.il (8.13.8/8.13.8) with ESMTP id 105DjFZn005908; Tue, 5 Jan 2021 15:45:15 +0200 Received: by taln60.nuvoton.co.il (Postfix, from userid 10070) id 9A54163A19; Tue, 5 Jan 2021 15:45:15 +0200 (IST) From: Tomer Maimon To: openbmc@lists.ozlabs.org Subject: [PATCH linux dev-5.8 v2 01/11] clk: npcm7xx: add read only flag to divider clocks Date: Tue, 5 Jan 2021 15:44:58 +0200 Message-Id: <20210105134508.225702-2-tmaimon77@gmail.com> X-Mailer: git-send-email 2.22.0 In-Reply-To: <20210105134508.225702-1-tmaimon77@gmail.com> References: <20210105134508.225702-1-tmaimon77@gmail.com> MIME-Version: 1.0 X-BeenThere: openbmc@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Development list for OpenBMC List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Andrew Jeffery , Tomer Maimon , benjaminfair@google.com Errors-To: openbmc-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "openbmc" Add read only flag to all divider clocks except SPI3 clock. Signed-off-by: Tomer Maimon --- 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*/ }; From patchwork Tue Jan 5 13:44:59 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomer Maimon X-Patchwork-Id: 1422461 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4D9DTR4zncz9sVx for ; Wed, 6 Jan 2021 00:52:43 +1100 (AEDT) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Received: from bilbo.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 4D9DTR16dKzDqcK for ; Wed, 6 Jan 2021 00:52:43 +1100 (AEDT) X-Original-To: openbmc@lists.ozlabs.org Delivered-To: openbmc@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=none (no SPF record) smtp.mailfrom=nuvoton.com (client-ip=212.199.177.27; helo=herzl.nuvoton.co.il; envelope-from=tomer.maimon@nuvoton.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Received: from herzl.nuvoton.co.il (212.199.177.27.static.012.net.il [212.199.177.27]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 4D9DKH4vqKzDqXm for ; Wed, 6 Jan 2021 00:45:39 +1100 (AEDT) Received: from taln60.nuvoton.co.il (ntil-fw [212.199.177.25]) by herzl.nuvoton.co.il (8.13.8/8.13.8) with ESMTP id 105DjGrH005913; Tue, 5 Jan 2021 15:45:16 +0200 Received: by taln60.nuvoton.co.il (Postfix, from userid 10070) id 77E9563A17; Tue, 5 Jan 2021 15:45:16 +0200 (IST) From: Tomer Maimon To: openbmc@lists.ozlabs.org Subject: [PATCH linux dev-5.8 v2 02/11] iio: adc: add calibration support to npcm ADC Date: Tue, 5 Jan 2021 15:44:59 +0200 Message-Id: <20210105134508.225702-3-tmaimon77@gmail.com> X-Mailer: git-send-email 2.22.0 In-Reply-To: <20210105134508.225702-1-tmaimon77@gmail.com> References: <20210105134508.225702-1-tmaimon77@gmail.com> MIME-Version: 1.0 X-BeenThere: openbmc@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Development list for OpenBMC List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Andrew Jeffery , Tomer Maimon , benjaminfair@google.com Errors-To: openbmc-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "openbmc" Add calibration to improve accuracy measurement when using internal referance voltage. the calibration values taken from the FUSE module. Signed-off-by: Tomer Maimon --- drivers/iio/adc/npcm_adc.c | 191 +++++++++++++++++++++++++++++++++++++ 1 file changed, 191 insertions(+) diff --git a/drivers/iio/adc/npcm_adc.c b/drivers/iio/adc/npcm_adc.c index 83bad2d5575d..02628b7eaca1 100644 --- a/drivers/iio/adc/npcm_adc.c +++ b/drivers/iio/adc/npcm_adc.c @@ -17,6 +17,8 @@ #include struct npcm_adc { + u32 R05; + u32 R15; bool int_status; u32 adc_sample_hz; struct device *dev; @@ -51,6 +53,40 @@ 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_TIMEOUT 0xDEADBEEF + #define NPCM_ADC_CHAN(ch) { \ .type = IIO_VOLTAGE, \ .indexed = 1, \ @@ -71,6 +107,133 @@ static const struct iio_chan_spec npcm_adc_iio_channels[] = { NPCM_ADC_CHAN(7), }; +static int npcm750_fuse_wait_for_ready(struct regmap *fuse_regmap, u32 timeout) +{ + u32 time = timeout; + u32 fstreg; + + while (--time > 1) { + regmap_read(fuse_regmap, NPCM7XX_FST, &fstreg); + if (fstreg & NPCM7XX_FST_RDY) { + regmap_write_bits(fuse_regmap, NPCM7XX_FST, + NPCM7XX_FST_RDST, NPCM7XX_FST_RDST); + return 0; + } + } + + /* try to clear the status in case it was set */ + regmap_write_bits(fuse_regmap, NPCM7XX_FST, NPCM7XX_FST_RDST, + NPCM7XX_FST_RDST); + + return -EINVAL; +} + +static void npcm750_fuse_read(struct regmap *fuse_regmap, u32 addr, u8 *data) +{ + u32 val; + + npcm750_fuse_wait_for_ready(fuse_regmap, FUSE_READ_TIMEOUT); + + 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); + + npcm750_fuse_wait_for_ready(fuse_regmap, FUSE_READ_TIMEOUT); + 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; + + if (of_device_is_compatible(np, "nuvoton,npcm750-adc")) { + fuse_regmap = syscon_regmap_lookup_by_compatible + ("nuvoton,npcm750-fuse"); + if (IS_ERR(fuse_regmap)) { + dev_warn(&pdev->dev, "Failed to find nuvoton,npcm750-fuse\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 Clibration 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 +288,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 +328,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 +438,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); From patchwork Tue Jan 5 13:45:00 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomer Maimon X-Patchwork-Id: 1422457 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4D9DMb1qJ7z9sWW for ; Wed, 6 Jan 2021 00:47:39 +1100 (AEDT) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Received: from bilbo.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 4D9DMZ5NrDzDqZG for ; Wed, 6 Jan 2021 00:47:38 +1100 (AEDT) X-Original-To: openbmc@lists.ozlabs.org Delivered-To: openbmc@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=none (no SPF record) smtp.mailfrom=nuvoton.com (client-ip=212.199.177.27; helo=herzl.nuvoton.co.il; envelope-from=tomer.maimon@nuvoton.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Received: from herzl.nuvoton.co.il (212.199.177.27.static.012.net.il [212.199.177.27]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 4D9DKH0SXmzDqWd for ; Wed, 6 Jan 2021 00:45:36 +1100 (AEDT) Received: from taln60.nuvoton.co.il (ntil-fw [212.199.177.25]) by herzl.nuvoton.co.il (8.13.8/8.13.8) with ESMTP id 105DjHAt005916; Tue, 5 Jan 2021 15:45:17 +0200 Received: by taln60.nuvoton.co.il (Postfix, from userid 10070) id 2149B63A17; Tue, 5 Jan 2021 15:45:17 +0200 (IST) From: Tomer Maimon To: openbmc@lists.ozlabs.org Subject: [PATCH linux dev-5.8 v2 03/11] dts: npcm750: add fuse regmap support node Date: Tue, 5 Jan 2021 15:45:00 +0200 Message-Id: <20210105134508.225702-4-tmaimon77@gmail.com> X-Mailer: git-send-email 2.22.0 In-Reply-To: <20210105134508.225702-1-tmaimon77@gmail.com> References: <20210105134508.225702-1-tmaimon77@gmail.com> MIME-Version: 1.0 X-BeenThere: openbmc@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Development list for OpenBMC List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Andrew Jeffery , Tomer Maimon , benjaminfair@google.com Errors-To: openbmc-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "openbmc" Signed-off-by: Tomer Maimon --- 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"; From patchwork Tue Jan 5 13:45:01 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomer Maimon X-Patchwork-Id: 1422464 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4D9DXg6sdWz9sVx for ; Wed, 6 Jan 2021 00:55:31 +1100 (AEDT) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Received: from bilbo.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 4D9DXg6FGCzDqcJ for ; Wed, 6 Jan 2021 00:55:31 +1100 (AEDT) X-Original-To: openbmc@lists.ozlabs.org Delivered-To: openbmc@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=none (no SPF record) smtp.mailfrom=nuvoton.com (client-ip=212.199.177.27; helo=herzl.nuvoton.co.il; envelope-from=tomer.maimon@nuvoton.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Received: from herzl.nuvoton.co.il (212.199.177.27.static.012.net.il [212.199.177.27]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 4D9DKM5mrjzDqYS for ; Wed, 6 Jan 2021 00:45:43 +1100 (AEDT) Received: from taln60.nuvoton.co.il (ntil-fw [212.199.177.25]) by herzl.nuvoton.co.il (8.13.8/8.13.8) with ESMTP id 105DjHGq005919; Tue, 5 Jan 2021 15:45:17 +0200 Received: by taln60.nuvoton.co.il (Postfix, from userid 10070) id A199E63A17; Tue, 5 Jan 2021 15:45:17 +0200 (IST) From: Tomer Maimon To: openbmc@lists.ozlabs.org Subject: [PATCH linux dev-5.8 v2 04/11] watchdog: npcm: Add DT restart priority and reset type support Date: Tue, 5 Jan 2021 15:45:01 +0200 Message-Id: <20210105134508.225702-5-tmaimon77@gmail.com> X-Mailer: git-send-email 2.22.0 In-Reply-To: <20210105134508.225702-1-tmaimon77@gmail.com> References: <20210105134508.225702-1-tmaimon77@gmail.com> MIME-Version: 1.0 X-BeenThere: openbmc@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Development list for OpenBMC List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Andrew Jeffery , Tomer Maimon , benjaminfair@google.com Errors-To: openbmc-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "openbmc" Add Device tree restart priority and three reset types support. Signed-off-by: Tomer Maimon --- drivers/watchdog/npcm_wdt.c | 121 +++++++++++++++++++++++++++++++++++- 1 file changed, 119 insertions(+), 2 deletions(-) diff --git a/drivers/watchdog/npcm_wdt.c b/drivers/watchdog/npcm_wdt.c index 765577f11c8d..bbf27da34834 100644 --- a/drivers/watchdog/npcm_wdt.c +++ b/drivers/watchdog/npcm_wdt.c @@ -11,7 +11,24 @@ #include #include #include - +#include +#include + +/* 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 */ @@ -43,6 +60,10 @@ struct npcm_wdt { 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 +197,70 @@ 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; + + if (of_device_is_compatible(dev->of_node, "nuvoton,npcm750-wdt")) { + gcr_regmap = syscon_regmap_lookup_by_compatible("nuvoton,npcm750-gcr"); + if (IS_ERR(gcr_regmap)) { + dev_warn(dev, "Failed to find nuvoton,npcm750-gcr 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; + struct resource *res; + 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 +272,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 +329,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) From patchwork Tue Jan 5 13:45:02 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomer Maimon X-Patchwork-Id: 1422460 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4D9DRP1Lh7z9sVk for ; Wed, 6 Jan 2021 00:50:57 +1100 (AEDT) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Received: from bilbo.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 4D9DRN5qgXzDqbt for ; Wed, 6 Jan 2021 00:50:56 +1100 (AEDT) X-Original-To: openbmc@lists.ozlabs.org Delivered-To: openbmc@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=none (no SPF record) smtp.mailfrom=nuvoton.com (client-ip=212.199.177.27; helo=herzl.nuvoton.co.il; envelope-from=tomer.maimon@nuvoton.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Received: from herzl.nuvoton.co.il (212.199.177.27.static.012.net.il [212.199.177.27]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 4D9DKH1qGCzDqXg for ; Wed, 6 Jan 2021 00:45:35 +1100 (AEDT) Received: from taln60.nuvoton.co.il (ntil-fw [212.199.177.25]) by herzl.nuvoton.co.il (8.13.8/8.13.8) with ESMTP id 105DjId6005922; Tue, 5 Jan 2021 15:45:18 +0200 Received: by taln60.nuvoton.co.il (Postfix, from userid 10070) id 3856163A17; Tue, 5 Jan 2021 15:45:18 +0200 (IST) From: Tomer Maimon To: openbmc@lists.ozlabs.org Subject: [PATCH linux dev-5.8 v2 05/11] dt-binding: watchdog: Add DT restart priority and reset type Date: Tue, 5 Jan 2021 15:45:02 +0200 Message-Id: <20210105134508.225702-6-tmaimon77@gmail.com> X-Mailer: git-send-email 2.22.0 In-Reply-To: <20210105134508.225702-1-tmaimon77@gmail.com> References: <20210105134508.225702-1-tmaimon77@gmail.com> MIME-Version: 1.0 X-BeenThere: openbmc@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Development list for OpenBMC List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Andrew Jeffery , Tomer Maimon , benjaminfair@google.com Errors-To: openbmc-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "openbmc" Add device tree restart priority documentation and three reset types documentation. Signed-off-by: Tomer Maimon --- .../bindings/watchdog/nuvoton,npcm-wdt.txt | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/Documentation/devicetree/bindings/watchdog/nuvoton,npcm-wdt.txt b/Documentation/devicetree/bindings/watchdog/nuvoton,npcm-wdt.txt index 6d593003c933..f6e0ea3e3c78 100644 --- a/Documentation/devicetree/bindings/watchdog/nuvoton,npcm-wdt.txt +++ b/Documentation/devicetree/bindings/watchdog/nuvoton,npcm-wdt.txt @@ -17,6 +17,34 @@ Required clocking property, have to be one of: Optional properties: - 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 +53,8 @@ timer@f000801c { interrupts = ; reg = <0xf000801c 0x4>; clocks = <&clk NPCM7XX_CLK_TIMER>; + nuvoton,restart-priority = <155>; + nuvoton,card-reset-type = "porst"; + nuvoton,ext1-reset-type = "wd1"; + nuvoton,ext2-reset-type = "sw2"; }; From patchwork Tue Jan 5 13:45:03 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomer Maimon X-Patchwork-Id: 1422465 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4D9DZl4W5Qz9sVk for ; Wed, 6 Jan 2021 00:57:19 +1100 (AEDT) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Received: from bilbo.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 4D9DZl1tpfzDqXZ for ; Wed, 6 Jan 2021 00:57:19 +1100 (AEDT) X-Original-To: openbmc@lists.ozlabs.org Delivered-To: openbmc@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=none (no SPF record) smtp.mailfrom=nuvoton.com (client-ip=212.199.177.27; helo=herzl.nuvoton.co.il; envelope-from=tomer.maimon@nuvoton.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Received: from herzl.nuvoton.co.il (212.199.177.27.static.012.net.il [212.199.177.27]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 4D9DKN6ZDczDqZL for ; Wed, 6 Jan 2021 00:45:44 +1100 (AEDT) Received: from taln60.nuvoton.co.il (ntil-fw [212.199.177.25]) by herzl.nuvoton.co.il (8.13.8/8.13.8) with ESMTP id 105DjI79005925; Tue, 5 Jan 2021 15:45:18 +0200 Received: by taln60.nuvoton.co.il (Postfix, from userid 10070) id 9F07463A17; Tue, 5 Jan 2021 15:45:18 +0200 (IST) From: Tomer Maimon To: openbmc@lists.ozlabs.org Subject: [PATCH linux dev-5.8 v2 06/11] pinctrl: npcm7xx: Add HGPIO pin support to NPCM7xx pinctrl driver Date: Tue, 5 Jan 2021 15:45:03 +0200 Message-Id: <20210105134508.225702-7-tmaimon77@gmail.com> X-Mailer: git-send-email 2.22.0 In-Reply-To: <20210105134508.225702-1-tmaimon77@gmail.com> References: <20210105134508.225702-1-tmaimon77@gmail.com> MIME-Version: 1.0 X-BeenThere: openbmc@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Development list for OpenBMC List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Andrew Jeffery , Tomer Maimon , benjaminfair@google.com Errors-To: openbmc-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "openbmc" Signed-off-by: Tomer Maimon Reviewed-by: Joel Stanley --- 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"), From patchwork Tue Jan 5 13:45:04 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomer Maimon X-Patchwork-Id: 1422462 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4D9DVS4jSLz9sVk for ; Wed, 6 Jan 2021 00:53:36 +1100 (AEDT) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Received: from bilbo.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 4D9DVS3v3FzDqdD for ; Wed, 6 Jan 2021 00:53:36 +1100 (AEDT) X-Original-To: openbmc@lists.ozlabs.org Delivered-To: openbmc@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=none (no SPF record) smtp.mailfrom=nuvoton.com (client-ip=212.199.177.27; helo=herzl.nuvoton.co.il; envelope-from=tomer.maimon@nuvoton.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Received: from herzl.nuvoton.co.il (212.199.177.27.static.012.net.il [212.199.177.27]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 4D9DKJ6ccszDqVS for ; Wed, 6 Jan 2021 00:45:40 +1100 (AEDT) Received: from taln60.nuvoton.co.il (ntil-fw [212.199.177.25]) by herzl.nuvoton.co.il (8.13.8/8.13.8) with ESMTP id 105DjJCx005929; Tue, 5 Jan 2021 15:45:19 +0200 Received: by taln60.nuvoton.co.il (Postfix, from userid 10070) id 394B963A17; Tue, 5 Jan 2021 15:45:19 +0200 (IST) From: Tomer Maimon To: openbmc@lists.ozlabs.org Subject: [PATCH linux dev-5.8 v2 07/11] pinctrl: pinconf: add pin persist configuration Date: Tue, 5 Jan 2021 15:45:04 +0200 Message-Id: <20210105134508.225702-8-tmaimon77@gmail.com> X-Mailer: git-send-email 2.22.0 In-Reply-To: <20210105134508.225702-1-tmaimon77@gmail.com> References: <20210105134508.225702-1-tmaimon77@gmail.com> MIME-Version: 1.0 X-BeenThere: openbmc@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Development list for OpenBMC List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Andrew Jeffery , Tomer Maimon , benjaminfair@google.com Errors-To: openbmc-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "openbmc" Add generic pin persist configuration support. Signed-off-by: Tomer Maimon --- 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 }, }; /** From patchwork Tue Jan 5 13:45:05 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomer Maimon X-Patchwork-Id: 1422453 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4D9DLV3wPbz9s1l for ; Wed, 6 Jan 2021 00:46:42 +1100 (AEDT) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Received: from bilbo.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 4D9DLT3n7rzDqbf for ; Wed, 6 Jan 2021 00:46:41 +1100 (AEDT) X-Original-To: openbmc@lists.ozlabs.org Delivered-To: openbmc@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=none (no SPF record) smtp.mailfrom=nuvoton.com (client-ip=212.199.177.27; helo=herzl.nuvoton.co.il; envelope-from=tomer.maimon@nuvoton.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Received: from herzl.nuvoton.co.il (212.199.177.27.static.012.net.il [212.199.177.27]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 4D9DKH0DB0zDqVm for ; Wed, 6 Jan 2021 00:45:35 +1100 (AEDT) Received: from taln60.nuvoton.co.il (ntil-fw [212.199.177.25]) by herzl.nuvoton.co.il (8.13.8/8.13.8) with ESMTP id 105DjJAa005932; Tue, 5 Jan 2021 15:45:19 +0200 Received: by taln60.nuvoton.co.il (Postfix, from userid 10070) id B5BEA63A17; Tue, 5 Jan 2021 15:45:19 +0200 (IST) From: Tomer Maimon To: openbmc@lists.ozlabs.org Subject: [PATCH linux dev-5.8 v2 08/11] pinctrl: npcm7xx: Add pin persist configuration support Date: Tue, 5 Jan 2021 15:45:05 +0200 Message-Id: <20210105134508.225702-9-tmaimon77@gmail.com> X-Mailer: git-send-email 2.22.0 In-Reply-To: <20210105134508.225702-1-tmaimon77@gmail.com> References: <20210105134508.225702-1-tmaimon77@gmail.com> MIME-Version: 1.0 X-BeenThere: openbmc@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Development list for OpenBMC List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Andrew Jeffery , Tomer Maimon , benjaminfair@google.com Errors-To: openbmc-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "openbmc" Signed-off-by: Tomer Maimon --- 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); From patchwork Tue Jan 5 13:45:06 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomer Maimon X-Patchwork-Id: 1422466 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4D9Dcw5g7Rz9sWM for ; Wed, 6 Jan 2021 00:59:12 +1100 (AEDT) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Received: from bilbo.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 4D9Dcw3zg7zDqFK for ; Wed, 6 Jan 2021 00:59:12 +1100 (AEDT) X-Original-To: openbmc@lists.ozlabs.org Delivered-To: openbmc@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=none (no SPF record) smtp.mailfrom=nuvoton.com (client-ip=212.199.177.27; helo=herzl.nuvoton.co.il; envelope-from=tomer.maimon@nuvoton.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Received: from herzl.nuvoton.co.il (212.199.177.27.static.012.net.il [212.199.177.27]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 4D9DKQ2L7FzDqZn for ; Wed, 6 Jan 2021 00:45:45 +1100 (AEDT) Received: from taln60.nuvoton.co.il (ntil-fw [212.199.177.25]) by herzl.nuvoton.co.il (8.13.8/8.13.8) with ESMTP id 105DjKbJ005935; Tue, 5 Jan 2021 15:45:20 +0200 Received: by taln60.nuvoton.co.il (Postfix, from userid 10070) id 5662C63A17; Tue, 5 Jan 2021 15:45:20 +0200 (IST) From: Tomer Maimon To: openbmc@lists.ozlabs.org Subject: [PATCH linux dev-5.8 v2 09/11] spi: npcm-pspi: Add full duplex support Date: Tue, 5 Jan 2021 15:45:06 +0200 Message-Id: <20210105134508.225702-10-tmaimon77@gmail.com> X-Mailer: git-send-email 2.22.0 In-Reply-To: <20210105134508.225702-1-tmaimon77@gmail.com> References: <20210105134508.225702-1-tmaimon77@gmail.com> MIME-Version: 1.0 X-BeenThere: openbmc@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Development list for OpenBMC List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Andrew Jeffery , Tomer Maimon , benjaminfair@google.com Errors-To: openbmc-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "openbmc" Modify the IRQ handler in the NPCM PSPI driver to support SPI full duplex communication. Signed-off-by: Tomer Maimon --- 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; } From patchwork Tue Jan 5 13:45:07 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomer Maimon X-Patchwork-Id: 1422468 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4D9Dj569Nnz9sVx for ; Wed, 6 Jan 2021 01:02:49 +1100 (AEDT) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Received: from bilbo.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 4D9Dj5530qzDqgF for ; Wed, 6 Jan 2021 01:02:49 +1100 (AEDT) X-Original-To: openbmc@lists.ozlabs.org Delivered-To: openbmc@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=none (no SPF record) smtp.mailfrom=nuvoton.com (client-ip=212.199.177.27; helo=herzl.nuvoton.co.il; envelope-from=tomer.maimon@nuvoton.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Received: from herzl.nuvoton.co.il (212.199.177.27.static.012.net.il [212.199.177.27]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 4D9DKX1Yn8zDqY7 for ; Wed, 6 Jan 2021 00:45:51 +1100 (AEDT) Received: from taln60.nuvoton.co.il (ntil-fw [212.199.177.25]) by herzl.nuvoton.co.il (8.13.8/8.13.8) with ESMTP id 105DjKiF005938; Tue, 5 Jan 2021 15:45:21 +0200 Received: by taln60.nuvoton.co.il (Postfix, from userid 10070) id 1514263A17; Tue, 5 Jan 2021 15:45:21 +0200 (IST) From: Tomer Maimon To: openbmc@lists.ozlabs.org Subject: [PATCH linux dev-5.8 v2 10/11] dt-binding: bmc: add NPCM7XX JTAG master documentation Date: Tue, 5 Jan 2021 15:45:07 +0200 Message-Id: <20210105134508.225702-11-tmaimon77@gmail.com> X-Mailer: git-send-email 2.22.0 In-Reply-To: <20210105134508.225702-1-tmaimon77@gmail.com> References: <20210105134508.225702-1-tmaimon77@gmail.com> MIME-Version: 1.0 X-BeenThere: openbmc@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Development list for OpenBMC List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Andrew Jeffery , Stanley Chu , Tomer Maimon , benjaminfair@google.com Errors-To: openbmc-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "openbmc" Added device tree binding documentation for Nuvoton NPCM7XX JTAG master. Signed-off-by: Stanley Chu Signed-off-by: Tomer Maimon --- .../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"; + }; +}; From patchwork Tue Jan 5 13:45:08 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Tomer Maimon X-Patchwork-Id: 1422469 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4D9Dk81621z9sVk for ; Wed, 6 Jan 2021 01:03:44 +1100 (AEDT) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Received: from bilbo.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 4D9Dk80gKrzDqdg for ; Wed, 6 Jan 2021 01:03:44 +1100 (AEDT) X-Original-To: openbmc@lists.ozlabs.org Delivered-To: openbmc@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=none (no SPF record) smtp.mailfrom=nuvoton.com (client-ip=212.199.177.27; helo=herzl.nuvoton.co.il; envelope-from=tomer.maimon@nuvoton.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Received: from herzl.nuvoton.co.il (212.199.177.27.static.012.net.il [212.199.177.27]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 4D9DKb1r7fzDqYJ for ; Wed, 6 Jan 2021 00:45:54 +1100 (AEDT) Received: from taln60.nuvoton.co.il (ntil-fw [212.199.177.25]) by herzl.nuvoton.co.il (8.13.8/8.13.8) with ESMTP id 105DjMeC005941; Tue, 5 Jan 2021 15:45:22 +0200 Received: by taln60.nuvoton.co.il (Postfix, from userid 10070) id 43E9F63A17; Tue, 5 Jan 2021 15:45:22 +0200 (IST) From: Tomer Maimon To: openbmc@lists.ozlabs.org Subject: [PATCH linux dev-5.8 v2 11/11] misc: npcm7xx-jtag-master: add NPCM7xx JTAG master driver Date: Tue, 5 Jan 2021 15:45:08 +0200 Message-Id: <20210105134508.225702-12-tmaimon77@gmail.com> X-Mailer: git-send-email 2.22.0 In-Reply-To: <20210105134508.225702-1-tmaimon77@gmail.com> References: <20210105134508.225702-1-tmaimon77@gmail.com> MIME-Version: 1.0 X-BeenThere: openbmc@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Development list for OpenBMC List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Andrew Jeffery , Stanley Chu , Tomer Maimon , benjaminfair@google.com Errors-To: openbmc-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "openbmc" Add NPCM7xx JTAG master driver, The NPCM7xx JTAG master usign GPIO lines and NPCM PSPI bus. Signed-off-by: Stanley Chu Signed-off-by: Tomer Maimon --- 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 +#include +#include +#include +#include +#include + +#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 "); +MODULE_DESCRIPTION("NPCM7xx JTAG Master Driver"); +MODULE_LICENSE("GPL"); +