linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/2] Add support for Microchip's pwm fpga core
@ 2022-06-13 11:17 Conor Dooley
  2022-06-13 11:17 ` [PATCH v2 1/2] pwm: add microchip soft ip corePWM driver Conor Dooley
                   ` (2 more replies)
  0 siblings, 3 replies; 12+ messages in thread
From: Conor Dooley @ 2022-06-13 11:17 UTC (permalink / raw)
  To: Thierry Reding, Uwe Kleine-König, Lee Jones
  Cc: Daire McNamara, linux-kernel, linux-pwm, linux-riscv, Conor Dooley

Hey Uwe,
Got a v2 for you...
I added some comments explaining the calculations and a documentation link
so hopefully things are a bit easier to follow.

Code wise, I went through and sorted out a bunch of issues that cycling
through the different periods/duties threw up. Along the way I found
some other problems - especially with the longer periods which I have
fixed. I also added a write to the sync register in the apply function,
which will resolve to a NOP for channels without "shadow registers".

Other than that, I managed to ditch the mchp_core_pwm_registers struct
entirely but had to add a short delay before reading back the registers
in order to compute the duty.

Thanks,
Conor.

Changes from v1:
- account for edge "quirk" while inverted
- block changing enabled channels' period
- document the hardware/driver limitations
- rearrange get_state() more logically
- fix cast sizes in get_state()
- fix remove() and probe error paths
- delete mchp_core_pwm_registers
- simplify .apply() logic
- don't warn in calculate_base()
- fix period calculation
- fix duty cycle calculation
- add COREPWM prefix to defines
- add a documentation link

Conor Dooley (2):
  pwm: add microchip soft ip corePWM driver
  MAINTAINERS: add pwm to PolarFire SoC entry

 MAINTAINERS                      |   1 +
 drivers/pwm/Kconfig              |  10 +
 drivers/pwm/Makefile             |   1 +
 drivers/pwm/pwm-microchip-core.c | 310 +++++++++++++++++++++++++++++++
 4 files changed, 322 insertions(+)
 create mode 100644 drivers/pwm/pwm-microchip-core.c


base-commit: 61114e734ccb804bc12561ab4020745e02c468c2
-- 
2.36.1


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

* [PATCH v2 1/2] pwm: add microchip soft ip corePWM driver
  2022-06-13 11:17 [PATCH v2 0/2] Add support for Microchip's pwm fpga core Conor Dooley
@ 2022-06-13 11:17 ` Conor Dooley
  2022-06-14 10:25   ` kernel test robot
                     ` (2 more replies)
  2022-06-13 11:18 ` [PATCH v2 2/2] MAINTAINERS: add pwm to PolarFire SoC entry Conor Dooley
  2022-06-13 11:56 ` [PATCH v2 0/2] Add support for Microchip's pwm fpga core Conor.Dooley
  2 siblings, 3 replies; 12+ messages in thread
From: Conor Dooley @ 2022-06-13 11:17 UTC (permalink / raw)
  To: Thierry Reding, Uwe Kleine-König, Lee Jones
  Cc: Daire McNamara, linux-kernel, linux-pwm, linux-riscv, Conor Dooley

Add a driver that supports the Microchip FPGA "soft" PWM IP core.

Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
---
 drivers/pwm/Kconfig              |  10 +
 drivers/pwm/Makefile             |   1 +
 drivers/pwm/pwm-microchip-core.c | 310 +++++++++++++++++++++++++++++++
 3 files changed, 321 insertions(+)
 create mode 100644 drivers/pwm/pwm-microchip-core.c

diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index 21e3b05a5153..a651848e444b 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -383,6 +383,16 @@ config PWM_MEDIATEK
 	  To compile this driver as a module, choose M here: the module
 	  will be called pwm-mediatek.
 
+config PWM_MICROCHIP_CORE
+	tristate "Microchip corePWM PWM support"
+	depends on SOC_MICROCHIP_POLARFIRE || COMPILE_TEST
+	depends on HAS_IOMEM && OF
+	help
+	  PWM driver for Microchip FPGA soft IP core.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called pwm-microchip-core.
+
 config PWM_MXS
 	tristate "Freescale MXS PWM support"
 	depends on ARCH_MXS || COMPILE_TEST
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index 708840b7fba8..d29754c20f91 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -33,6 +33,7 @@ obj-$(CONFIG_PWM_LPSS_PCI)	+= pwm-lpss-pci.o
 obj-$(CONFIG_PWM_LPSS_PLATFORM)	+= pwm-lpss-platform.o
 obj-$(CONFIG_PWM_MESON)		+= pwm-meson.o
 obj-$(CONFIG_PWM_MEDIATEK)	+= pwm-mediatek.o
+obj-$(CONFIG_PWM_MICROCHIP_CORE)	+= pwm-microchip-core.o
 obj-$(CONFIG_PWM_MTK_DISP)	+= pwm-mtk-disp.o
 obj-$(CONFIG_PWM_MXS)		+= pwm-mxs.o
 obj-$(CONFIG_PWM_NTXEC)		+= pwm-ntxec.o
diff --git a/drivers/pwm/pwm-microchip-core.c b/drivers/pwm/pwm-microchip-core.c
new file mode 100644
index 000000000000..d2abc46deec4
--- /dev/null
+++ b/drivers/pwm/pwm-microchip-core.c
@@ -0,0 +1,310 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * corePWM driver for Microchip "soft" FPGA IP cores.
+ *
+ * Copyright (c) 2021-2022 Microchip Corporation. All rights reserved.
+ * Author: Conor Dooley <conor.dooley@microchip.com>
+ * Documentation:
+ * https://www.microsemi.com/document-portal/doc_download/1245275-corepwm-hb
+ *
+ * Limitations:
+ * - If the IP block is configured without "shadow registers", all register
+ *   writes will take effect immediately, causing glitches on the output.
+ *   If shadow registers *are* enabled, a write to the "SYNC_UPDATE" register
+ *   notifies the core that it needs to update the registers defining the
+ *   waveform from the contents of the "shadow registers".
+ * - The IP block has no concept of a duty cycle, only rising/falling edges of
+ *   the waveform. Unfortunately, if the rising & falling edges registers have
+ *   the same value written to them the IP block will do whichever of a rising
+ *   or a falling edge is possible. I.E. a 50% waveform at twice the requested
+ *   period. Therefore to get a 0% waveform, the output is set the max high/low
+ *   time depending on polarity.
+ * - The PWM period is set for the whole IP block not per channel. The driver
+ *   will only change the period if no other PWM output is enabled.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pwm.h>
+#include <linux/math.h>
+
+#define PREG_TO_VAL(PREG) ((PREG) + 1)
+
+#define COREPWM_PRESCALE_REG	0x00u
+#define COREPWM_PERIOD_REG	0x04u
+#define COREPWM_EN_LOW_REG	0x08u
+#define COREPWM_EN_HIGH_REG	0x0Cu
+#define COREPWM_SYNC_UPD_REG	0xE4u
+#define COREPWM_POSEDGE_OFFSET	0x10u
+#define COREPWM_NEGEDGE_OFFSET	0x14u
+#define COREPWM_CHANNEL_OFFSET	0x08u
+
+struct mchp_core_pwm_chip {
+	struct pwm_chip chip;
+	struct clk *clk;
+	void __iomem *base;
+};
+
+static inline struct mchp_core_pwm_chip *to_mchp_core_pwm(struct pwm_chip *chip)
+{
+	return container_of(chip, struct mchp_core_pwm_chip, chip);
+}
+
+static void mchp_core_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm, bool enable)
+{
+	struct mchp_core_pwm_chip *mchp_core_pwm = to_mchp_core_pwm(chip);
+	u8 channel_enable, reg_offset, shift;
+
+	/*
+	 * There are two adjacent 8 bit control regs, the lower reg controls
+	 * 0-7 and the upper reg 8-15. Check if the pwm is in the upper reg
+	 * and if so, offset by the bus width.
+	 */
+	reg_offset = COREPWM_EN_LOW_REG + (pwm->hwpwm >> 3) * sizeof(u32);
+	shift = pwm->hwpwm > 7 ? pwm->hwpwm - 8 : pwm->hwpwm;
+
+	channel_enable = readb_relaxed(mchp_core_pwm->base + reg_offset);
+	channel_enable &= ~(1 << shift);
+	channel_enable |= (enable << shift);
+
+	writel_relaxed(channel_enable, mchp_core_pwm->base + reg_offset);
+}
+
+static void mchp_core_pwm_apply_duty(struct pwm_chip *chip,  struct pwm_device *pwm,
+				     const struct pwm_state *state)
+{
+	struct mchp_core_pwm_chip *mchp_core_pwm = to_mchp_core_pwm(chip);
+	void __iomem *channel_base = mchp_core_pwm->base + pwm->hwpwm * COREPWM_CHANNEL_OFFSET;
+	u64 duty_steps, period, tmp;
+	u8 prescale, period_steps, posedge, negedge;
+
+	prescale = PREG_TO_VAL(readb_relaxed(mchp_core_pwm->base + COREPWM_PRESCALE_REG));
+	period_steps = PREG_TO_VAL(readb_relaxed(mchp_core_pwm->base + COREPWM_PERIOD_REG));
+	period = period_steps * prescale * NSEC_PER_SEC;
+	period = div64_u64(period, clk_get_rate(mchp_core_pwm->clk));
+
+	/*
+	 * Calculate the duty cycle in multiples of the prescaled period:
+	 * duty_steps = duty_in_ns / step_in_ns
+	 * step_in_ns = (prescale * NSEC_PER_SEC) / clk_rate
+	 * The code below is rearranged slightly to only divide once.
+	 *
+	 * Because the period is per channel, it is possible that the requested
+	 * duty cycle is longer than the period, in which case cap it to the
+	 * period.
+	 */
+	if (state->duty_cycle > period) {
+		duty_steps = period_steps;
+	} else {
+		duty_steps = state->duty_cycle * clk_get_rate(mchp_core_pwm->clk);
+		tmp = prescale * NSEC_PER_SEC;
+		duty_steps = div64_u64(duty_steps, tmp);
+	}
+
+	/*
+	 * Turn the output on unless posedge == negedge, in which case the
+	 * duty is intended to be 0, but limitations of the IP block don't
+	 * allow a zero length duty cycle - so just set the max high/low time
+	 * respectively.
+	 */
+	if (state->polarity == PWM_POLARITY_INVERSED) {
+		negedge = !duty_steps ? period_steps : 0u;
+		posedge = duty_steps;
+	} else {
+		posedge = !duty_steps ? period_steps : 0u;
+		negedge = duty_steps;
+	}
+
+	writel_relaxed(posedge, channel_base + COREPWM_POSEDGE_OFFSET);
+	writel_relaxed(negedge, channel_base + COREPWM_NEGEDGE_OFFSET);
+}
+
+static void mchp_core_pwm_apply_period(struct pwm_chip *chip, const struct pwm_state *state)
+{
+	struct mchp_core_pwm_chip *mchp_core_pwm = to_mchp_core_pwm(chip);
+	u64 tmp = state->period;
+	u8 prescale, period_steps;
+
+	/*
+	 * Calculate the period cycles and prescale values.
+	 * The registers are each 8 bits wide & multiplied to compute the period
+	 * so the maximum period that can be generated is 0xFFFF times the period
+	 * of the input clock.
+	 */
+	tmp *= clk_get_rate(mchp_core_pwm->clk);
+	do_div(tmp, NSEC_PER_SEC);
+
+	if (tmp > 0xFFFFu) {
+		prescale = 0xFFu;
+		period_steps = 0xFFu;
+	} else {
+		prescale = tmp >> 8;
+		period_steps = tmp / PREG_TO_VAL(prescale) - 1;
+	}
+
+	writel_relaxed(prescale, mchp_core_pwm->base + COREPWM_PRESCALE_REG);
+	writel_relaxed(period_steps, mchp_core_pwm->base + COREPWM_PERIOD_REG);
+}
+
+static int mchp_core_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
+			       const struct pwm_state *state)
+{
+	struct mchp_core_pwm_chip *mchp_core_pwm = to_mchp_core_pwm(chip);
+	struct pwm_state current_state = pwm->state;
+	bool period_locked;
+	u16 channel_enabled;
+
+	if (!state->enabled) {
+		mchp_core_pwm_enable(chip, pwm, false);
+		return 0;
+	}
+
+	/*
+	 * If the only thing that has changed is the duty cycle or the polarity,
+	 * we can shortcut the calculations and just compute/apply the new duty
+	 * cycle pos & neg edges
+	 * As all the channels share the same period, do not allow it to be
+	 * changed if any other channels are enabled.
+	 */
+	channel_enabled = (((u16)readb_relaxed(mchp_core_pwm->base + COREPWM_EN_HIGH_REG) << 8) |
+		readb_relaxed(mchp_core_pwm->base + COREPWM_EN_LOW_REG));
+	period_locked = channel_enabled & ~(1 << pwm->hwpwm);
+
+	if ((!current_state.enabled || current_state.period != state->period) && !period_locked) {
+		mchp_core_pwm_apply_period(chip, state);
+
+		/*
+		 * A short delay is required before the newly written values can
+		 * be read back on the bus
+		 */
+		usleep_range(50, 100);
+	}
+
+	mchp_core_pwm_apply_duty(chip, pwm, state);
+
+	/*
+	 * Notify the block to update the waveform from the shadow registers.
+	 * This is a NOP if shadow registers are not enabled.
+	 */
+	writel_relaxed(1U, mchp_core_pwm->base + COREPWM_SYNC_UPD_REG);
+
+	mchp_core_pwm_enable(chip, pwm, true);
+
+	return 0;
+}
+
+static void mchp_core_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
+				    struct pwm_state *state)
+{
+	struct mchp_core_pwm_chip *mchp_core_pwm = to_mchp_core_pwm(chip);
+	void __iomem *channel_base = mchp_core_pwm->base + pwm->hwpwm * COREPWM_CHANNEL_OFFSET;
+	u8 prescale, period_steps, duty_steps;
+	u8 posedge, negedge;
+	u16 channel_enabled;
+
+	channel_enabled = (((u16)readb_relaxed(mchp_core_pwm->base + COREPWM_EN_HIGH_REG) << 8) |
+		readb_relaxed(mchp_core_pwm->base + COREPWM_EN_LOW_REG));
+
+	if (channel_enabled & 1 << pwm->hwpwm)
+		state->enabled = true;
+	else
+		state->enabled = false;
+
+	prescale = PREG_TO_VAL(readb_relaxed(mchp_core_pwm->base + COREPWM_PRESCALE_REG));
+
+	posedge = readb_relaxed(channel_base + COREPWM_POSEDGE_OFFSET);
+	negedge = readb_relaxed(channel_base + COREPWM_NEGEDGE_OFFSET);
+
+	duty_steps = abs((s16)posedge - (s16)negedge);
+	state->duty_cycle = duty_steps * prescale * NSEC_PER_SEC;
+	do_div(state->duty_cycle, clk_get_rate(mchp_core_pwm->clk));
+
+	state->polarity = negedge < posedge ? PWM_POLARITY_INVERSED : PWM_POLARITY_NORMAL;
+
+	period_steps = PREG_TO_VAL(readb_relaxed(mchp_core_pwm->base + COREPWM_PERIOD_REG));
+	state->period = period_steps * prescale * NSEC_PER_SEC;
+	do_div(state->period, clk_get_rate(mchp_core_pwm->clk));
+}
+
+static const struct pwm_ops mchp_core_pwm_ops = {
+	.apply = mchp_core_pwm_apply,
+	.get_state = mchp_core_pwm_get_state,
+	.owner = THIS_MODULE,
+};
+
+static const struct of_device_id mchp_core_of_match[] = {
+	{
+		.compatible = "microchip,corepwm-rtl-v4",
+	},
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, mchp_core_of_match);
+
+static int mchp_core_pwm_probe(struct platform_device *pdev)
+{
+	struct mchp_core_pwm_chip *mchp_pwm;
+	struct resource *regs;
+	int ret;
+
+	mchp_pwm = devm_kzalloc(&pdev->dev, sizeof(*mchp_pwm), GFP_KERNEL);
+	if (!mchp_pwm)
+		return -ENOMEM;
+
+	mchp_pwm->base = devm_platform_get_and_ioremap_resource(pdev, 0, &regs);
+	if (IS_ERR(mchp_pwm->base))
+		return PTR_ERR(mchp_pwm->base);
+
+	mchp_pwm->clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(mchp_pwm->clk))
+		return PTR_ERR(mchp_pwm->clk);
+
+	ret = clk_prepare_enable(mchp_pwm->clk);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret, "failed to prepare PWM clock\n");
+
+	mchp_pwm->chip.dev = &pdev->dev;
+	mchp_pwm->chip.ops = &mchp_core_pwm_ops;
+	mchp_pwm->chip.of_xlate = of_pwm_xlate_with_flags;
+	mchp_pwm->chip.of_pwm_n_cells = 3;
+	mchp_pwm->chip.npwm = 16;
+
+	ret = pwmchip_add(&mchp_pwm->chip);
+	if (ret < 0) {
+		clk_disable_unprepare(mchp_pwm->clk);
+		return dev_err_probe(&pdev->dev, ret, "failed to add PWM chip\n");
+	}
+
+	platform_set_drvdata(pdev, mchp_pwm);
+	dev_info(&pdev->dev, "Successfully registered Microchip corePWM\n");
+
+	return 0;
+}
+
+static int mchp_core_pwm_remove(struct platform_device *pdev)
+{
+	struct mchp_core_pwm_chip *mchp_pwm = platform_get_drvdata(pdev);
+
+	pwmchip_remove(&mchp_pwm->chip);
+	clk_disable_unprepare(mchp_pwm->clk);
+
+	return 0;
+}
+
+static struct platform_driver mchp_core_pwm_driver = {
+	.driver = {
+		.name = "mchp-core-pwm",
+		.of_match_table = mchp_core_of_match,
+	},
+	.probe = mchp_core_pwm_probe,
+	.remove = mchp_core_pwm_remove,
+};
+module_platform_driver(mchp_core_pwm_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Conor Dooley <conor.dooley@microchip.com>");
+MODULE_DESCRIPTION("corePWM driver for Microchip FPGAs");
-- 
2.36.1


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

* [PATCH v2 2/2] MAINTAINERS: add pwm to PolarFire SoC entry
  2022-06-13 11:17 [PATCH v2 0/2] Add support for Microchip's pwm fpga core Conor Dooley
  2022-06-13 11:17 ` [PATCH v2 1/2] pwm: add microchip soft ip corePWM driver Conor Dooley
@ 2022-06-13 11:18 ` Conor Dooley
  2022-06-13 11:56 ` [PATCH v2 0/2] Add support for Microchip's pwm fpga core Conor.Dooley
  2 siblings, 0 replies; 12+ messages in thread
From: Conor Dooley @ 2022-06-13 11:18 UTC (permalink / raw)
  To: Thierry Reding, Uwe Kleine-König, Lee Jones
  Cc: Daire McNamara, linux-kernel, linux-pwm, linux-riscv, Conor Dooley

Add the newly introduced pwm driver to the existing PolarFire SoC entry.

Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index f1b4b77daa5f..d0b39fa4f309 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -17091,6 +17091,7 @@ L:	linux-riscv@lists.infradead.org
 S:	Supported
 F:	arch/riscv/boot/dts/microchip/
 F:	drivers/mailbox/mailbox-mpfs.c
+F:	drivers/pwm/pwm-microchip-core.c
 F:	drivers/soc/microchip/
 F:	include/soc/microchip/mpfs.h
 
-- 
2.36.1


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

* Re: [PATCH v2 0/2] Add support for Microchip's pwm fpga core
  2022-06-13 11:17 [PATCH v2 0/2] Add support for Microchip's pwm fpga core Conor Dooley
  2022-06-13 11:17 ` [PATCH v2 1/2] pwm: add microchip soft ip corePWM driver Conor Dooley
  2022-06-13 11:18 ` [PATCH v2 2/2] MAINTAINERS: add pwm to PolarFire SoC entry Conor Dooley
@ 2022-06-13 11:56 ` Conor.Dooley
  2 siblings, 0 replies; 12+ messages in thread
From: Conor.Dooley @ 2022-06-13 11:56 UTC (permalink / raw)
  To: thierry.reding, u.kleine-koenig, lee.jones
  Cc: Daire.McNamara, linux-kernel, linux-pwm, linux-riscv, Conor.Dooley



On 13/06/2022 12:17, Conor Dooley wrote:
> Hey Uwe,
> Got a v2 for you...
> I added some comments explaining the calculations and a documentation link
> so hopefully things are a bit easier to follow.
> 
> Code wise, I went through and sorted out a bunch of issues that cycling
> through the different periods/duties threw up. Along the way I found
> some other problems - especially with the longer periods which I have
> fixed. I also added a write to the sync register in the apply function,
> which will resolve to a NOP for channels without "shadow registers".
> 
> Other than that, I managed to ditch the mchp_core_pwm_registers struct
> entirely but had to add a short delay before reading back the registers
> in order to compute the duty.
> 
> Thanks,
> Conor.

Ah, damn - forgot to mention the 3 sets of changes to the MAINTAINERS entry
again.. There's a change already in spi-next & another change in my patchset
sent for usb.

> 
> Changes from v1:
> - account for edge "quirk" while inverted
> - block changing enabled channels' period
> - document the hardware/driver limitations
> - rearrange get_state() more logically
> - fix cast sizes in get_state()
> - fix remove() and probe error paths
> - delete mchp_core_pwm_registers
> - simplify .apply() logic
> - don't warn in calculate_base()
> - fix period calculation
> - fix duty cycle calculation
> - add COREPWM prefix to defines
> - add a documentation link
> 
> Conor Dooley (2):
>    pwm: add microchip soft ip corePWM driver
>    MAINTAINERS: add pwm to PolarFire SoC entry
> 
>   MAINTAINERS                      |   1 +
>   drivers/pwm/Kconfig              |  10 +
>   drivers/pwm/Makefile             |   1 +
>   drivers/pwm/pwm-microchip-core.c | 310 +++++++++++++++++++++++++++++++
>   4 files changed, 322 insertions(+)
>   create mode 100644 drivers/pwm/pwm-microchip-core.c
> 
> 
> base-commit: 61114e734ccb804bc12561ab4020745e02c468c2

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

* Re: [PATCH v2 1/2] pwm: add microchip soft ip corePWM driver
  2022-06-13 11:17 ` [PATCH v2 1/2] pwm: add microchip soft ip corePWM driver Conor Dooley
@ 2022-06-14 10:25   ` kernel test robot
  2022-06-14 10:34     ` Conor.Dooley
  2022-06-14 12:34   ` Uwe Kleine-König
  2022-06-15 19:14   ` kernel test robot
  2 siblings, 1 reply; 12+ messages in thread
From: kernel test robot @ 2022-06-14 10:25 UTC (permalink / raw)
  To: Conor Dooley, Thierry Reding, Uwe Kleine-König, Lee Jones
  Cc: kbuild-all, Daire McNamara, linux-kernel, linux-pwm, linux-riscv,
	Conor Dooley

Hi Conor,

I love your patch! Yet something to improve:

[auto build test ERROR on thierry-reding-pwm/for-next]
[also build test ERROR on linus/master v5.19-rc2 next-20220614]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/intel-lab-lkp/linux/commits/Conor-Dooley/pwm-add-microchip-soft-ip-corePWM-driver/20220613-211851
base:   https://git.kernel.org/pub/scm/linux/kernel/git/thierry.reding/linux-pwm.git for-next
config: xtensa-allyesconfig (https://download.01.org/0day-ci/archive/20220614/202206141813.qgogbMAN-lkp@intel.com/config)
compiler: xtensa-linux-gcc (GCC) 11.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/intel-lab-lkp/linux/commit/4451a8420f9fd16ee9a0801fcf02f1ec04bb8ab0
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Conor-Dooley/pwm-add-microchip-soft-ip-corePWM-driver/20220613-211851
        git checkout 4451a8420f9fd16ee9a0801fcf02f1ec04bb8ab0
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.3.0 make.cross W=1 O=build_dir ARCH=xtensa SHELL=/bin/bash

If you fix the issue, kindly add following tag where applicable
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   `.exit.text' referenced in section `__jump_table' of fs/cifs/cifsfs.o: defined in discarded section `.exit.text' of fs/cifs/cifsfs.o
   `.exit.text' referenced in section `__jump_table' of fs/cifs/cifsfs.o: defined in discarded section `.exit.text' of fs/cifs/cifsfs.o
   `.exit.text' referenced in section `__jump_table' of fs/fuse/inode.o: defined in discarded section `.exit.text' of fs/fuse/inode.o
   `.exit.text' referenced in section `__jump_table' of fs/fuse/inode.o: defined in discarded section `.exit.text' of fs/fuse/inode.o
   `.exit.text' referenced in section `__jump_table' of fs/ceph/super.o: defined in discarded section `.exit.text' of fs/ceph/super.o
   `.exit.text' referenced in section `__jump_table' of fs/ceph/super.o: defined in discarded section `.exit.text' of fs/ceph/super.o
   xtensa-linux-ld: drivers/pwm/pwm-microchip-core.o: in function `mchp_core_pwm_enable.isra.0':
>> pwm-microchip-core.c:(.text+0x380): undefined reference to `__udivdi3'
   xtensa-linux-ld: drivers/pwm/pwm-microchip-core.o: in function `mchp_core_pwm_apply':
   pwm-microchip-core.c:(.text+0x586): undefined reference to `__udivdi3'
   `.exit.text' referenced in section `__jump_table' of drivers/rapidio/rio_cm.o: defined in discarded section `.exit.text' of drivers/rapidio/rio_cm.o
   `.exit.text' referenced in section `__jump_table' of drivers/rapidio/rio_cm.o: defined in discarded section `.exit.text' of drivers/rapidio/rio_cm.o
   `.exit.text' referenced in section `__jump_table' of drivers/rapidio/switches/idt_gen2.o: defined in discarded section `.exit.text' of drivers/rapidio/switches/idt_gen2.o
   `.exit.text' referenced in section `__jump_table' of drivers/rapidio/switches/idt_gen2.o: defined in discarded section `.exit.text' of drivers/rapidio/switches/idt_gen2.o
   `.exit.text' referenced in section `__jump_table' of drivers/rapidio/switches/idt_gen2.o: defined in discarded section `.exit.text' of drivers/rapidio/switches/idt_gen2.o
   `.exit.text' referenced in section `__jump_table' of drivers/rapidio/switches/idt_gen2.o: defined in discarded section `.exit.text' of drivers/rapidio/switches/idt_gen2.o
   `.exit.text' referenced in section `__jump_table' of drivers/rapidio/switches/idt_gen3.o: defined in discarded section `.exit.text' of drivers/rapidio/switches/idt_gen3.o
   `.exit.text' referenced in section `__jump_table' of drivers/rapidio/switches/idt_gen3.o: defined in discarded section `.exit.text' of drivers/rapidio/switches/idt_gen3.o
   `.exit.text' referenced in section `__jump_table' of drivers/rapidio/switches/idt_gen3.o: defined in discarded section `.exit.text' of drivers/rapidio/switches/idt_gen3.o
   `.exit.text' referenced in section `__jump_table' of drivers/rapidio/switches/idt_gen3.o: defined in discarded section `.exit.text' of drivers/rapidio/switches/idt_gen3.o
   `.exit.text' referenced in section `__jump_table' of drivers/video/fbdev/vt8623fb.o: defined in discarded section `.exit.text' of drivers/video/fbdev/vt8623fb.o
   `.exit.text' referenced in section `__jump_table' of drivers/video/fbdev/vt8623fb.o: defined in discarded section `.exit.text' of drivers/video/fbdev/vt8623fb.o
   `.exit.text' referenced in section `__jump_table' of drivers/video/fbdev/s3fb.o: defined in discarded section `.exit.text' of drivers/video/fbdev/s3fb.o
   `.exit.text' referenced in section `__jump_table' of drivers/video/fbdev/s3fb.o: defined in discarded section `.exit.text' of drivers/video/fbdev/s3fb.o
   `.exit.text' referenced in section `__jump_table' of drivers/video/fbdev/arkfb.o: defined in discarded section `.exit.text' of drivers/video/fbdev/arkfb.o
   `.exit.text' referenced in section `__jump_table' of drivers/video/fbdev/arkfb.o: defined in discarded section `.exit.text' of drivers/video/fbdev/arkfb.o
   `.exit.text' referenced in section `__jump_table' of drivers/misc/phantom.o: defined in discarded section `.exit.text' of drivers/misc/phantom.o
   `.exit.text' referenced in section `__jump_table' of drivers/misc/phantom.o: defined in discarded section `.exit.text' of drivers/misc/phantom.o
   `.exit.text' referenced in section `__jump_table' of drivers/misc/habanalabs/common/habanalabs_drv.o: defined in discarded section `.exit.text' of drivers/misc/habanalabs/common/habanalabs_drv.o
   `.exit.text' referenced in section `__jump_table' of drivers/misc/habanalabs/common/habanalabs_drv.o: defined in discarded section `.exit.text' of drivers/misc/habanalabs/common/habanalabs_drv.o
   `.exit.text' referenced in section `__jump_table' of drivers/scsi/fcoe/fcoe.o: defined in discarded section `.exit.text' of drivers/scsi/fcoe/fcoe.o
   `.exit.text' referenced in section `__jump_table' of drivers/scsi/fcoe/fcoe.o: defined in discarded section `.exit.text' of drivers/scsi/fcoe/fcoe.o
   `.exit.text' referenced in section `__jump_table' of drivers/scsi/cxgbi/libcxgbi.o: defined in discarded section `.exit.text' of drivers/scsi/cxgbi/libcxgbi.o
   `.exit.text' referenced in section `__jump_table' of drivers/scsi/cxgbi/libcxgbi.o: defined in discarded section `.exit.text' of drivers/scsi/cxgbi/libcxgbi.o
   `.exit.text' referenced in section `__jump_table' of drivers/target/target_core_configfs.o: defined in discarded section `.exit.text' of drivers/target/target_core_configfs.o
   `.exit.text' referenced in section `__jump_table' of drivers/target/target_core_configfs.o: defined in discarded section `.exit.text' of drivers/target/target_core_configfs.o
   `.exit.text' referenced in section `__jump_table' of drivers/mtd/maps/pcmciamtd.o: defined in discarded section `.exit.text' of drivers/mtd/maps/pcmciamtd.o
   `.exit.text' referenced in section `__jump_table' of drivers/mtd/maps/pcmciamtd.o: defined in discarded section `.exit.text' of drivers/mtd/maps/pcmciamtd.o
   `.exit.text' referenced in section `__jump_table' of drivers/net/wireless/zydas/zd1211rw/zd_usb.o: defined in discarded section `.exit.text' of drivers/net/wireless/zydas/zd1211rw/zd_usb.o
   `.exit.text' referenced in section `__jump_table' of drivers/net/wireless/zydas/zd1211rw/zd_usb.o: defined in discarded section `.exit.text' of drivers/net/wireless/zydas/zd1211rw/zd_usb.o
   `.exit.text' referenced in section `__jump_table' of drivers/net/wireless/ray_cs.o: defined in discarded section `.exit.text' of drivers/net/wireless/ray_cs.o
   `.exit.text' referenced in section `__jump_table' of drivers/net/wireless/ray_cs.o: defined in discarded section `.exit.text' of drivers/net/wireless/ray_cs.o
   `.exit.text' referenced in section `__jump_table' of drivers/net/wireless/mac80211_hwsim.o: defined in discarded section `.exit.text' of drivers/net/wireless/mac80211_hwsim.o
   `.exit.text' referenced in section `__jump_table' of drivers/net/wireless/mac80211_hwsim.o: defined in discarded section `.exit.text' of drivers/net/wireless/mac80211_hwsim.o
   `.exit.text' referenced in section `__jump_table' of drivers/usb/gadget/legacy/inode.o: defined in discarded section `.exit.text' of drivers/usb/gadget/legacy/inode.o
   `.exit.text' referenced in section `__jump_table' of drivers/usb/gadget/legacy/inode.o: defined in discarded section `.exit.text' of drivers/usb/gadget/legacy/inode.o
   `.exit.text' referenced in section `__jump_table' of drivers/usb/gadget/legacy/g_ffs.o: defined in discarded section `.exit.text' of drivers/usb/gadget/legacy/g_ffs.o
   `.exit.text' referenced in section `__jump_table' of drivers/usb/gadget/legacy/g_ffs.o: defined in discarded section `.exit.text' of drivers/usb/gadget/legacy/g_ffs.o
   `.exit.text' referenced in section `__jump_table' of drivers/media/common/siano/smscoreapi.o: defined in discarded section `.exit.text' of drivers/media/common/siano/smscoreapi.o
   `.exit.text' referenced in section `__jump_table' of drivers/media/common/siano/smscoreapi.o: defined in discarded section `.exit.text' of drivers/media/common/siano/smscoreapi.o
   `.exit.text' referenced in section `__jump_table' of drivers/vme/bridges/vme_fake.o: defined in discarded section `.exit.text' of drivers/vme/bridges/vme_fake.o
   `.exit.text' referenced in section `__jump_table' of drivers/vme/bridges/vme_fake.o: defined in discarded section `.exit.text' of drivers/vme/bridges/vme_fake.o
   `.exit.text' referenced in section `.data' of sound/soc/codecs/tlv320adc3xxx.o: defined in discarded section `.exit.text' of sound/soc/codecs/tlv320adc3xxx.o
   `.exit.text' referenced in section `__jump_table' of net/netfilter/nf_conntrack_h323_main.o: defined in discarded section `.exit.text' of net/netfilter/nf_conntrack_h323_main.o
   `.exit.text' referenced in section `__jump_table' of net/netfilter/nf_conntrack_h323_main.o: defined in discarded section `.exit.text' of net/netfilter/nf_conntrack_h323_main.o
   `.exit.text' referenced in section `__jump_table' of net/netfilter/ipset/ip_set_core.o: defined in discarded section `.exit.text' of net/netfilter/ipset/ip_set_core.o
   `.exit.text' referenced in section `__jump_table' of net/netfilter/ipset/ip_set_core.o: defined in discarded section `.exit.text' of net/netfilter/ipset/ip_set_core.o
   `.exit.text' referenced in section `__jump_table' of net/ceph/ceph_common.o: defined in discarded section `.exit.text' of net/ceph/ceph_common.o
   `.exit.text' referenced in section `__jump_table' of net/ceph/ceph_common.o: defined in discarded section `.exit.text' of net/ceph/ceph_common.o

-- 
0-DAY CI Kernel Test Service
https://01.org/lkp

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

* Re: [PATCH v2 1/2] pwm: add microchip soft ip corePWM driver
  2022-06-14 10:25   ` kernel test robot
@ 2022-06-14 10:34     ` Conor.Dooley
  2022-06-14 12:13       ` Uwe Kleine-König
  0 siblings, 1 reply; 12+ messages in thread
From: Conor.Dooley @ 2022-06-14 10:34 UTC (permalink / raw)
  To: lkp, Conor.Dooley, thierry.reding, u.kleine-koenig, lee.jones
  Cc: kbuild-all, Daire.McNamara, linux-kernel, linux-pwm, linux-riscv

>     xtensa-linux-ld: drivers/pwm/pwm-microchip-core.o: in function `mchp_core_pwm_enable.isra.0':
>>> pwm-microchip-core.c:(.text+0x380): undefined reference to `__udivdi3'
>     xtensa-linux-ld: drivers/pwm/pwm-microchip-core.o: in function `mchp_core_pwm_apply':
>     pwm-microchip-core.c:(.text+0x586): undefined reference to `__udivdi3'

I assume this is me using functions that are only defined for 64 bit...

On 14/06/2022 11:25, kernel test robot wrote:
> Hi Conor,
> 
> I love your patch! Yet something to improve:
> 
> [auto build test ERROR on thierry-reding-pwm/for-next]
> [also build test ERROR on linus/master v5.19-rc2 next-20220614]
> [If your patch is applied to the wrong git tree, kindly drop us a note.
> And when submitting patch, we suggest to use '--base' as documented in
> https://git-scm.com/docs/git-format-patch]
> 
> url:    https://github.com/intel-lab-lkp/linux/commits/Conor-Dooley/pwm-add-microchip-soft-ip-corePWM-driver/20220613-211851
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/thierry.reding/linux-pwm.git for-next
> config: xtensa-allyesconfig (https://download.01.org/0day-ci/archive/20220614/202206141813.qgogbMAN-lkp@intel.com/config)
> compiler: xtensa-linux-gcc (GCC) 11.3.0
> reproduce (this is a W=1 build):
>          wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
>          chmod +x ~/bin/make.cross
>          # https://github.com/intel-lab-lkp/linux/commit/4451a8420f9fd16ee9a0801fcf02f1ec04bb8ab0
>          git remote add linux-review https://github.com/intel-lab-lkp/linux
>          git fetch --no-tags linux-review Conor-Dooley/pwm-add-microchip-soft-ip-corePWM-driver/20220613-211851
>          git checkout 4451a8420f9fd16ee9a0801fcf02f1ec04bb8ab0
>          # save the config file
>          mkdir build_dir && cp config build_dir/.config
>          COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.3.0 make.cross W=1 O=build_dir ARCH=xtensa SHELL=/bin/bash
> 
> If you fix the issue, kindly add following tag where applicable
> Reported-by: kernel test robot <lkp@intel.com>
> 
> All errors (new ones prefixed by >>):
> 
>     `.exit.text' referenced in section `__jump_table' of fs/cifs/cifsfs.o: defined in discarded section `.exit.text' of fs/cifs/cifsfs.o
>     `.exit.text' referenced in section `__jump_table' of fs/cifs/cifsfs.o: defined in discarded section `.exit.text' of fs/cifs/cifsfs.o
>     `.exit.text' referenced in section `__jump_table' of fs/fuse/inode.o: defined in discarded section `.exit.text' of fs/fuse/inode.o
>     `.exit.text' referenced in section `__jump_table' of fs/fuse/inode.o: defined in discarded section `.exit.text' of fs/fuse/inode.o
>     `.exit.text' referenced in section `__jump_table' of fs/ceph/super.o: defined in discarded section `.exit.text' of fs/ceph/super.o
>     `.exit.text' referenced in section `__jump_table' of fs/ceph/super.o: defined in discarded section `.exit.text' of fs/ceph/super.o
>     xtensa-linux-ld: drivers/pwm/pwm-microchip-core.o: in function `mchp_core_pwm_enable.isra.0':
>>> pwm-microchip-core.c:(.text+0x380): undefined reference to `__udivdi3'
>     xtensa-linux-ld: drivers/pwm/pwm-microchip-core.o: in function `mchp_core_pwm_apply':
>     pwm-microchip-core.c:(.text+0x586): undefined reference to `__udivdi3'
>     `.exit.text' referenced in section `__jump_table' of drivers/rapidio/rio_cm.o: defined in discarded section `.exit.text' of drivers/rapidio/rio_cm.o
>     `.exit.text' referenced in section `__jump_table' of drivers/rapidio/rio_cm.o: defined in discarded section `.exit.text' of drivers/rapidio/rio_cm.o
>     `.exit.text' referenced in section `__jump_table' of drivers/rapidio/switches/idt_gen2.o: defined in discarded section `.exit.text' of drivers/rapidio/switches/idt_gen2.o
>     `.exit.text' referenced in section `__jump_table' of drivers/rapidio/switches/idt_gen2.o: defined in discarded section `.exit.text' of drivers/rapidio/switches/idt_gen2.o
>     `.exit.text' referenced in section `__jump_table' of drivers/rapidio/switches/idt_gen2.o: defined in discarded section `.exit.text' of drivers/rapidio/switches/idt_gen2.o
>     `.exit.text' referenced in section `__jump_table' of drivers/rapidio/switches/idt_gen2.o: defined in discarded section `.exit.text' of drivers/rapidio/switches/idt_gen2.o
>     `.exit.text' referenced in section `__jump_table' of drivers/rapidio/switches/idt_gen3.o: defined in discarded section `.exit.text' of drivers/rapidio/switches/idt_gen3.o
>     `.exit.text' referenced in section `__jump_table' of drivers/rapidio/switches/idt_gen3.o: defined in discarded section `.exit.text' of drivers/rapidio/switches/idt_gen3.o
>     `.exit.text' referenced in section `__jump_table' of drivers/rapidio/switches/idt_gen3.o: defined in discarded section `.exit.text' of drivers/rapidio/switches/idt_gen3.o
>     `.exit.text' referenced in section `__jump_table' of drivers/rapidio/switches/idt_gen3.o: defined in discarded section `.exit.text' of drivers/rapidio/switches/idt_gen3.o
>     `.exit.text' referenced in section `__jump_table' of drivers/video/fbdev/vt8623fb.o: defined in discarded section `.exit.text' of drivers/video/fbdev/vt8623fb.o
>     `.exit.text' referenced in section `__jump_table' of drivers/video/fbdev/vt8623fb.o: defined in discarded section `.exit.text' of drivers/video/fbdev/vt8623fb.o
>     `.exit.text' referenced in section `__jump_table' of drivers/video/fbdev/s3fb.o: defined in discarded section `.exit.text' of drivers/video/fbdev/s3fb.o
>     `.exit.text' referenced in section `__jump_table' of drivers/video/fbdev/s3fb.o: defined in discarded section `.exit.text' of drivers/video/fbdev/s3fb.o
>     `.exit.text' referenced in section `__jump_table' of drivers/video/fbdev/arkfb.o: defined in discarded section `.exit.text' of drivers/video/fbdev/arkfb.o
>     `.exit.text' referenced in section `__jump_table' of drivers/video/fbdev/arkfb.o: defined in discarded section `.exit.text' of drivers/video/fbdev/arkfb.o
>     `.exit.text' referenced in section `__jump_table' of drivers/misc/phantom.o: defined in discarded section `.exit.text' of drivers/misc/phantom.o
>     `.exit.text' referenced in section `__jump_table' of drivers/misc/phantom.o: defined in discarded section `.exit.text' of drivers/misc/phantom.o
>     `.exit.text' referenced in section `__jump_table' of drivers/misc/habanalabs/common/habanalabs_drv.o: defined in discarded section `.exit.text' of drivers/misc/habanalabs/common/habanalabs_drv.o
>     `.exit.text' referenced in section `__jump_table' of drivers/misc/habanalabs/common/habanalabs_drv.o: defined in discarded section `.exit.text' of drivers/misc/habanalabs/common/habanalabs_drv.o
>     `.exit.text' referenced in section `__jump_table' of drivers/scsi/fcoe/fcoe.o: defined in discarded section `.exit.text' of drivers/scsi/fcoe/fcoe.o
>     `.exit.text' referenced in section `__jump_table' of drivers/scsi/fcoe/fcoe.o: defined in discarded section `.exit.text' of drivers/scsi/fcoe/fcoe.o
>     `.exit.text' referenced in section `__jump_table' of drivers/scsi/cxgbi/libcxgbi.o: defined in discarded section `.exit.text' of drivers/scsi/cxgbi/libcxgbi.o
>     `.exit.text' referenced in section `__jump_table' of drivers/scsi/cxgbi/libcxgbi.o: defined in discarded section `.exit.text' of drivers/scsi/cxgbi/libcxgbi.o
>     `.exit.text' referenced in section `__jump_table' of drivers/target/target_core_configfs.o: defined in discarded section `.exit.text' of drivers/target/target_core_configfs.o
>     `.exit.text' referenced in section `__jump_table' of drivers/target/target_core_configfs.o: defined in discarded section `.exit.text' of drivers/target/target_core_configfs.o
>     `.exit.text' referenced in section `__jump_table' of drivers/mtd/maps/pcmciamtd.o: defined in discarded section `.exit.text' of drivers/mtd/maps/pcmciamtd.o
>     `.exit.text' referenced in section `__jump_table' of drivers/mtd/maps/pcmciamtd.o: defined in discarded section `.exit.text' of drivers/mtd/maps/pcmciamtd.o
>     `.exit.text' referenced in section `__jump_table' of drivers/net/wireless/zydas/zd1211rw/zd_usb.o: defined in discarded section `.exit.text' of drivers/net/wireless/zydas/zd1211rw/zd_usb.o
>     `.exit.text' referenced in section `__jump_table' of drivers/net/wireless/zydas/zd1211rw/zd_usb.o: defined in discarded section `.exit.text' of drivers/net/wireless/zydas/zd1211rw/zd_usb.o
>     `.exit.text' referenced in section `__jump_table' of drivers/net/wireless/ray_cs.o: defined in discarded section `.exit.text' of drivers/net/wireless/ray_cs.o
>     `.exit.text' referenced in section `__jump_table' of drivers/net/wireless/ray_cs.o: defined in discarded section `.exit.text' of drivers/net/wireless/ray_cs.o
>     `.exit.text' referenced in section `__jump_table' of drivers/net/wireless/mac80211_hwsim.o: defined in discarded section `.exit.text' of drivers/net/wireless/mac80211_hwsim.o
>     `.exit.text' referenced in section `__jump_table' of drivers/net/wireless/mac80211_hwsim.o: defined in discarded section `.exit.text' of drivers/net/wireless/mac80211_hwsim.o
>     `.exit.text' referenced in section `__jump_table' of drivers/usb/gadget/legacy/inode.o: defined in discarded section `.exit.text' of drivers/usb/gadget/legacy/inode.o
>     `.exit.text' referenced in section `__jump_table' of drivers/usb/gadget/legacy/inode.o: defined in discarded section `.exit.text' of drivers/usb/gadget/legacy/inode.o
>     `.exit.text' referenced in section `__jump_table' of drivers/usb/gadget/legacy/g_ffs.o: defined in discarded section `.exit.text' of drivers/usb/gadget/legacy/g_ffs.o
>     `.exit.text' referenced in section `__jump_table' of drivers/usb/gadget/legacy/g_ffs.o: defined in discarded section `.exit.text' of drivers/usb/gadget/legacy/g_ffs.o
>     `.exit.text' referenced in section `__jump_table' of drivers/media/common/siano/smscoreapi.o: defined in discarded section `.exit.text' of drivers/media/common/siano/smscoreapi.o
>     `.exit.text' referenced in section `__jump_table' of drivers/media/common/siano/smscoreapi.o: defined in discarded section `.exit.text' of drivers/media/common/siano/smscoreapi.o
>     `.exit.text' referenced in section `__jump_table' of drivers/vme/bridges/vme_fake.o: defined in discarded section `.exit.text' of drivers/vme/bridges/vme_fake.o
>     `.exit.text' referenced in section `__jump_table' of drivers/vme/bridges/vme_fake.o: defined in discarded section `.exit.text' of drivers/vme/bridges/vme_fake.o
>     `.exit.text' referenced in section `.data' of sound/soc/codecs/tlv320adc3xxx.o: defined in discarded section `.exit.text' of sound/soc/codecs/tlv320adc3xxx.o
>     `.exit.text' referenced in section `__jump_table' of net/netfilter/nf_conntrack_h323_main.o: defined in discarded section `.exit.text' of net/netfilter/nf_conntrack_h323_main.o
>     `.exit.text' referenced in section `__jump_table' of net/netfilter/nf_conntrack_h323_main.o: defined in discarded section `.exit.text' of net/netfilter/nf_conntrack_h323_main.o
>     `.exit.text' referenced in section `__jump_table' of net/netfilter/ipset/ip_set_core.o: defined in discarded section `.exit.text' of net/netfilter/ipset/ip_set_core.o
>     `.exit.text' referenced in section `__jump_table' of net/netfilter/ipset/ip_set_core.o: defined in discarded section `.exit.text' of net/netfilter/ipset/ip_set_core.o
>     `.exit.text' referenced in section `__jump_table' of net/ceph/ceph_common.o: defined in discarded section `.exit.text' of net/ceph/ceph_common.o
>     `.exit.text' referenced in section `__jump_table' of net/ceph/ceph_common.o: defined in discarded section `.exit.text' of net/ceph/ceph_common.o
> 

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

* Re: [PATCH v2 1/2] pwm: add microchip soft ip corePWM driver
  2022-06-14 10:34     ` Conor.Dooley
@ 2022-06-14 12:13       ` Uwe Kleine-König
  2022-06-14 12:16         ` Conor.Dooley
  0 siblings, 1 reply; 12+ messages in thread
From: Uwe Kleine-König @ 2022-06-14 12:13 UTC (permalink / raw)
  To: Conor.Dooley
  Cc: lkp, thierry.reding, lee.jones, kbuild-all, Daire.McNamara,
	linux-kernel, linux-pwm, linux-riscv

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

On Tue, Jun 14, 2022 at 10:34:00AM +0000, Conor.Dooley@microchip.com wrote:
> >     xtensa-linux-ld: drivers/pwm/pwm-microchip-core.o: in function `mchp_core_pwm_enable.isra.0':
> >>> pwm-microchip-core.c:(.text+0x380): undefined reference to `__udivdi3'
> >     xtensa-linux-ld: drivers/pwm/pwm-microchip-core.o: in function `mchp_core_pwm_apply':
> >     pwm-microchip-core.c:(.text+0x586): undefined reference to `__udivdi3'
> 
> I assume this is me using functions that are only defined for 64 bit...

This is usually a division with variables > int.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-König            |
Industrial Linux Solutions                 | https://www.pengutronix.de/ |

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Re: [PATCH v2 1/2] pwm: add microchip soft ip corePWM driver
  2022-06-14 12:13       ` Uwe Kleine-König
@ 2022-06-14 12:16         ` Conor.Dooley
  0 siblings, 0 replies; 12+ messages in thread
From: Conor.Dooley @ 2022-06-14 12:16 UTC (permalink / raw)
  To: u.kleine-koenig
  Cc: lkp, thierry.reding, lee.jones, kbuild-all, Daire.McNamara,
	linux-kernel, linux-pwm, linux-riscv

On 14/06/2022 13:13, Uwe Kleine-König wrote:
> On Tue, Jun 14, 2022 at 10:34:00AM +0000, Conor.Dooley@microchip.com wrote:
>>>      xtensa-linux-ld: drivers/pwm/pwm-microchip-core.o: in function `mchp_core_pwm_enable.isra.0':
>>>>> pwm-microchip-core.c:(.text+0x380): undefined reference to `__udivdi3'
>>>      xtensa-linux-ld: drivers/pwm/pwm-microchip-core.o: in function `mchp_core_pwm_apply':
>>>      pwm-microchip-core.c:(.text+0x586): undefined reference to `__udivdi3'
>>
>> I assume this is me using functions that are only defined for 64 bit...
> 
> This is usually a division with variables > int.

Aye, which I now have - hence the div64_u64().
Thanks, I'll go digging for a fix :)
Conor.


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

* Re: [PATCH v2 1/2] pwm: add microchip soft ip corePWM driver
  2022-06-13 11:17 ` [PATCH v2 1/2] pwm: add microchip soft ip corePWM driver Conor Dooley
  2022-06-14 10:25   ` kernel test robot
@ 2022-06-14 12:34   ` Uwe Kleine-König
  2022-06-14 12:38     ` Conor.Dooley
  2022-06-15 19:14   ` kernel test robot
  2 siblings, 1 reply; 12+ messages in thread
From: Uwe Kleine-König @ 2022-06-14 12:34 UTC (permalink / raw)
  To: Conor Dooley
  Cc: Thierry Reding, Lee Jones, Daire McNamara, linux-kernel,
	linux-pwm, linux-riscv

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

Hello,

On Mon, Jun 13, 2022 at 12:17:59PM +0100, Conor Dooley wrote:
> Add a driver that supports the Microchip FPGA "soft" PWM IP core.
> 
> Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
> ---
>  drivers/pwm/Kconfig              |  10 +
>  drivers/pwm/Makefile             |   1 +
>  drivers/pwm/pwm-microchip-core.c | 310 +++++++++++++++++++++++++++++++
>  3 files changed, 321 insertions(+)
>  create mode 100644 drivers/pwm/pwm-microchip-core.c
> 
> diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
> index 21e3b05a5153..a651848e444b 100644
> --- a/drivers/pwm/Kconfig
> +++ b/drivers/pwm/Kconfig
> @@ -383,6 +383,16 @@ config PWM_MEDIATEK
>  	  To compile this driver as a module, choose M here: the module
>  	  will be called pwm-mediatek.
>  
> +config PWM_MICROCHIP_CORE
> +	tristate "Microchip corePWM PWM support"
> +	depends on SOC_MICROCHIP_POLARFIRE || COMPILE_TEST
> +	depends on HAS_IOMEM && OF
> +	help
> +	  PWM driver for Microchip FPGA soft IP core.
> +
> +	  To compile this driver as a module, choose M here: the module
> +	  will be called pwm-microchip-core.
> +
>  config PWM_MXS
>  	tristate "Freescale MXS PWM support"
>  	depends on ARCH_MXS || COMPILE_TEST
> diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
> index 708840b7fba8..d29754c20f91 100644
> --- a/drivers/pwm/Makefile
> +++ b/drivers/pwm/Makefile
> @@ -33,6 +33,7 @@ obj-$(CONFIG_PWM_LPSS_PCI)	+= pwm-lpss-pci.o
>  obj-$(CONFIG_PWM_LPSS_PLATFORM)	+= pwm-lpss-platform.o
>  obj-$(CONFIG_PWM_MESON)		+= pwm-meson.o
>  obj-$(CONFIG_PWM_MEDIATEK)	+= pwm-mediatek.o
> +obj-$(CONFIG_PWM_MICROCHIP_CORE)	+= pwm-microchip-core.o
>  obj-$(CONFIG_PWM_MTK_DISP)	+= pwm-mtk-disp.o
>  obj-$(CONFIG_PWM_MXS)		+= pwm-mxs.o
>  obj-$(CONFIG_PWM_NTXEC)		+= pwm-ntxec.o
> diff --git a/drivers/pwm/pwm-microchip-core.c b/drivers/pwm/pwm-microchip-core.c
> new file mode 100644
> index 000000000000..d2abc46deec4
> --- /dev/null
> +++ b/drivers/pwm/pwm-microchip-core.c
> @@ -0,0 +1,310 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * corePWM driver for Microchip "soft" FPGA IP cores.
> + *
> + * Copyright (c) 2021-2022 Microchip Corporation. All rights reserved.
> + * Author: Conor Dooley <conor.dooley@microchip.com>
> + * Documentation:
> + * https://www.microsemi.com/document-portal/doc_download/1245275-corepwm-hb
> + *
> + * Limitations:
> + * - If the IP block is configured without "shadow registers", all register
> + *   writes will take effect immediately, causing glitches on the output.
> + *   If shadow registers *are* enabled, a write to the "SYNC_UPDATE" register
> + *   notifies the core that it needs to update the registers defining the
> + *   waveform from the contents of the "shadow registers".
> + * - The IP block has no concept of a duty cycle, only rising/falling edges of
> + *   the waveform. Unfortunately, if the rising & falling edges registers have
> + *   the same value written to them the IP block will do whichever of a rising
> + *   or a falling edge is possible. I.E. a 50% waveform at twice the requested
> + *   period. Therefore to get a 0% waveform, the output is set the max high/low
> + *   time depending on polarity.
> + * - The PWM period is set for the whole IP block not per channel. The driver
> + *   will only change the period if no other PWM output is enabled.
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/delay.h>
> +#include <linux/err.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <linux/pwm.h>
> +#include <linux/math.h>
> +
> +#define PREG_TO_VAL(PREG) ((PREG) + 1)
> +
> +#define COREPWM_PRESCALE_REG	0x00u
> +#define COREPWM_PERIOD_REG	0x04u
> +#define COREPWM_EN_LOW_REG	0x08u
> +#define COREPWM_EN_HIGH_REG	0x0Cu
> +#define COREPWM_SYNC_UPD_REG	0xE4u
> +#define COREPWM_POSEDGE_OFFSET	0x10u
> +#define COREPWM_NEGEDGE_OFFSET	0x14u
> +#define COREPWM_CHANNEL_OFFSET	0x08u
> +
> +struct mchp_core_pwm_chip {
> +	struct pwm_chip chip;
> +	struct clk *clk;
> +	void __iomem *base;
> +};
> +
> +static inline struct mchp_core_pwm_chip *to_mchp_core_pwm(struct pwm_chip *chip)
> +{
> +	return container_of(chip, struct mchp_core_pwm_chip, chip);
> +}
> +
> +static void mchp_core_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm, bool enable)
> +{
> +	struct mchp_core_pwm_chip *mchp_core_pwm = to_mchp_core_pwm(chip);
> +	u8 channel_enable, reg_offset, shift;
> +
> +	/*
> +	 * There are two adjacent 8 bit control regs, the lower reg controls
> +	 * 0-7 and the upper reg 8-15. Check if the pwm is in the upper reg
> +	 * and if so, offset by the bus width.
> +	 */
> +	reg_offset = COREPWM_EN_LOW_REG + (pwm->hwpwm >> 3) * sizeof(u32);
> +	shift = pwm->hwpwm > 7 ? pwm->hwpwm - 8 : pwm->hwpwm;
> +
> +	channel_enable = readb_relaxed(mchp_core_pwm->base + reg_offset);
> +	channel_enable &= ~(1 << shift);
> +	channel_enable |= (enable << shift);
> +
> +	writel_relaxed(channel_enable, mchp_core_pwm->base + reg_offset);
> +}
> +
> +static void mchp_core_pwm_apply_duty(struct pwm_chip *chip,  struct pwm_device *pwm,
> +				     const struct pwm_state *state)
> +{
> +	struct mchp_core_pwm_chip *mchp_core_pwm = to_mchp_core_pwm(chip);
> +	void __iomem *channel_base = mchp_core_pwm->base + pwm->hwpwm * COREPWM_CHANNEL_OFFSET;
> +	u64 duty_steps, period, tmp;
> +	u8 prescale, period_steps, posedge, negedge;
> +
> +	prescale = PREG_TO_VAL(readb_relaxed(mchp_core_pwm->base + COREPWM_PRESCALE_REG));
> +	period_steps = PREG_TO_VAL(readb_relaxed(mchp_core_pwm->base + COREPWM_PERIOD_REG));
> +	period = period_steps * prescale * NSEC_PER_SEC;
> +	period = div64_u64(period, clk_get_rate(mchp_core_pwm->clk));
> +
> +	/*
> +	 * Calculate the duty cycle in multiples of the prescaled period:
> +	 * duty_steps = duty_in_ns / step_in_ns
> +	 * step_in_ns = (prescale * NSEC_PER_SEC) / clk_rate
> +	 * The code below is rearranged slightly to only divide once.
> +	 *
> +	 * Because the period is per channel, it is possible that the requested
> +	 * duty cycle is longer than the period, in which case cap it to the
> +	 * period.
> +	 */
> +	if (state->duty_cycle > period) {
> +		duty_steps = period_steps;
> +	} else {
> +		duty_steps = state->duty_cycle * clk_get_rate(mchp_core_pwm->clk);
> +		tmp = prescale * NSEC_PER_SEC;
> +		duty_steps = div64_u64(duty_steps, tmp);
> +	}
> +
> +	/*
> +	 * Turn the output on unless posedge == negedge, in which case the
> +	 * duty is intended to be 0, but limitations of the IP block don't
> +	 * allow a zero length duty cycle - so just set the max high/low time
> +	 * respectively.
> +	 */
> +	if (state->polarity == PWM_POLARITY_INVERSED) {
> +		negedge = !duty_steps ? period_steps : 0u;
> +		posedge = duty_steps;
> +	} else {
> +		posedge = !duty_steps ? period_steps : 0u;
> +		negedge = duty_steps;
> +	}
> +
> +	writel_relaxed(posedge, channel_base + COREPWM_POSEDGE_OFFSET);
> +	writel_relaxed(negedge, channel_base + COREPWM_NEGEDGE_OFFSET);
> +}
> +
> +static void mchp_core_pwm_apply_period(struct pwm_chip *chip, const struct pwm_state *state)
> +{
> +	struct mchp_core_pwm_chip *mchp_core_pwm = to_mchp_core_pwm(chip);
> +	u64 tmp = state->period;
> +	u8 prescale, period_steps;
> +
> +	/*
> +	 * Calculate the period cycles and prescale values.
> +	 * The registers are each 8 bits wide & multiplied to compute the period
> +	 * so the maximum period that can be generated is 0xFFFF times the period
> +	 * of the input clock.
> +	 */
> +	tmp *= clk_get_rate(mchp_core_pwm->clk);
> +	do_div(tmp, NSEC_PER_SEC);
> +
> +	if (tmp > 0xFFFFu) {
> +		prescale = 0xFFu;
> +		period_steps = 0xFFu;
> +	} else {
> +		prescale = tmp >> 8;
> +		period_steps = tmp / PREG_TO_VAL(prescale) - 1;

Here is the 64bit division.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-König            |
Industrial Linux Solutions                 | https://www.pengutronix.de/ |

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Re: [PATCH v2 1/2] pwm: add microchip soft ip corePWM driver
  2022-06-14 12:34   ` Uwe Kleine-König
@ 2022-06-14 12:38     ` Conor.Dooley
  0 siblings, 0 replies; 12+ messages in thread
From: Conor.Dooley @ 2022-06-14 12:38 UTC (permalink / raw)
  To: u.kleine-koenig, Conor.Dooley
  Cc: thierry.reding, lee.jones, Daire.McNamara, linux-kernel,
	linux-pwm, linux-riscv



On 14/06/2022 13:34, Uwe Kleine-König wrote:
> Hello,
> 
> On Mon, Jun 13, 2022 at 12:17:59PM +0100, Conor Dooley wrote:
>> Add a driver that supports the Microchip FPGA "soft" PWM IP core.
>>
>> Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
>> ---
>>   drivers/pwm/Kconfig              |  10 +
>>   drivers/pwm/Makefile             |   1 +
>>   drivers/pwm/pwm-microchip-core.c | 310 +++++++++++++++++++++++++++++++
>>   3 files changed, 321 insertions(+)
>>   create mode 100644 drivers/pwm/pwm-microchip-core.c
>>
>> diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
>> index 21e3b05a5153..a651848e444b 100644
>> --- a/drivers/pwm/Kconfig
>> +++ b/drivers/pwm/Kconfig
>> @@ -383,6 +383,16 @@ config PWM_MEDIATEK
>>   	  To compile this driver as a module, choose M here: the module
>>   	  will be called pwm-mediatek.
>>   
>> +config PWM_MICROCHIP_CORE
>> +	tristate "Microchip corePWM PWM support"
>> +	depends on SOC_MICROCHIP_POLARFIRE || COMPILE_TEST
>> +	depends on HAS_IOMEM && OF
>> +	help
>> +	  PWM driver for Microchip FPGA soft IP core.
>> +
>> +	  To compile this driver as a module, choose M here: the module
>> +	  will be called pwm-microchip-core.
>> +
>>   config PWM_MXS
>>   	tristate "Freescale MXS PWM support"
>>   	depends on ARCH_MXS || COMPILE_TEST
>> diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
>> index 708840b7fba8..d29754c20f91 100644
>> --- a/drivers/pwm/Makefile
>> +++ b/drivers/pwm/Makefile
>> @@ -33,6 +33,7 @@ obj-$(CONFIG_PWM_LPSS_PCI)	+= pwm-lpss-pci.o
>>   obj-$(CONFIG_PWM_LPSS_PLATFORM)	+= pwm-lpss-platform.o
>>   obj-$(CONFIG_PWM_MESON)		+= pwm-meson.o
>>   obj-$(CONFIG_PWM_MEDIATEK)	+= pwm-mediatek.o
>> +obj-$(CONFIG_PWM_MICROCHIP_CORE)	+= pwm-microchip-core.o
>>   obj-$(CONFIG_PWM_MTK_DISP)	+= pwm-mtk-disp.o
>>   obj-$(CONFIG_PWM_MXS)		+= pwm-mxs.o
>>   obj-$(CONFIG_PWM_NTXEC)		+= pwm-ntxec.o
>> diff --git a/drivers/pwm/pwm-microchip-core.c b/drivers/pwm/pwm-microchip-core.c
>> new file mode 100644
>> index 000000000000..d2abc46deec4
>> --- /dev/null
>> +++ b/drivers/pwm/pwm-microchip-core.c
>> @@ -0,0 +1,310 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * corePWM driver for Microchip "soft" FPGA IP cores.
>> + *
>> + * Copyright (c) 2021-2022 Microchip Corporation. All rights reserved.
>> + * Author: Conor Dooley <conor.dooley@microchip.com>
>> + * Documentation:
>> + * https://www.microsemi.com/document-portal/doc_download/1245275-corepwm-hb
>> + *
>> + * Limitations:
>> + * - If the IP block is configured without "shadow registers", all register
>> + *   writes will take effect immediately, causing glitches on the output.
>> + *   If shadow registers *are* enabled, a write to the "SYNC_UPDATE" register
>> + *   notifies the core that it needs to update the registers defining the
>> + *   waveform from the contents of the "shadow registers".
>> + * - The IP block has no concept of a duty cycle, only rising/falling edges of
>> + *   the waveform. Unfortunately, if the rising & falling edges registers have
>> + *   the same value written to them the IP block will do whichever of a rising
>> + *   or a falling edge is possible. I.E. a 50% waveform at twice the requested
>> + *   period. Therefore to get a 0% waveform, the output is set the max high/low
>> + *   time depending on polarity.
>> + * - The PWM period is set for the whole IP block not per channel. The driver
>> + *   will only change the period if no other PWM output is enabled.
>> + */
>> +
>> +#include <linux/clk.h>
>> +#include <linux/delay.h>
>> +#include <linux/err.h>
>> +#include <linux/io.h>
>> +#include <linux/module.h>
>> +#include <linux/of_device.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/pwm.h>
>> +#include <linux/math.h>
>> +
>> +#define PREG_TO_VAL(PREG) ((PREG) + 1)
>> +
>> +#define COREPWM_PRESCALE_REG	0x00u
>> +#define COREPWM_PERIOD_REG	0x04u
>> +#define COREPWM_EN_LOW_REG	0x08u
>> +#define COREPWM_EN_HIGH_REG	0x0Cu
>> +#define COREPWM_SYNC_UPD_REG	0xE4u
>> +#define COREPWM_POSEDGE_OFFSET	0x10u
>> +#define COREPWM_NEGEDGE_OFFSET	0x14u
>> +#define COREPWM_CHANNEL_OFFSET	0x08u
>> +
>> +struct mchp_core_pwm_chip {
>> +	struct pwm_chip chip;
>> +	struct clk *clk;
>> +	void __iomem *base;
>> +};
>> +
>> +static inline struct mchp_core_pwm_chip *to_mchp_core_pwm(struct pwm_chip *chip)
>> +{
>> +	return container_of(chip, struct mchp_core_pwm_chip, chip);
>> +}
>> +
>> +static void mchp_core_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm, bool enable)
>> +{
>> +	struct mchp_core_pwm_chip *mchp_core_pwm = to_mchp_core_pwm(chip);
>> +	u8 channel_enable, reg_offset, shift;
>> +
>> +	/*
>> +	 * There are two adjacent 8 bit control regs, the lower reg controls
>> +	 * 0-7 and the upper reg 8-15. Check if the pwm is in the upper reg
>> +	 * and if so, offset by the bus width.
>> +	 */
>> +	reg_offset = COREPWM_EN_LOW_REG + (pwm->hwpwm >> 3) * sizeof(u32);
>> +	shift = pwm->hwpwm > 7 ? pwm->hwpwm - 8 : pwm->hwpwm;
>> +
>> +	channel_enable = readb_relaxed(mchp_core_pwm->base + reg_offset);
>> +	channel_enable &= ~(1 << shift);
>> +	channel_enable |= (enable << shift);
>> +
>> +	writel_relaxed(channel_enable, mchp_core_pwm->base + reg_offset);
>> +}
>> +
>> +static void mchp_core_pwm_apply_duty(struct pwm_chip *chip,  struct pwm_device *pwm,
>> +				     const struct pwm_state *state)
>> +{
>> +	struct mchp_core_pwm_chip *mchp_core_pwm = to_mchp_core_pwm(chip);
>> +	void __iomem *channel_base = mchp_core_pwm->base + pwm->hwpwm * COREPWM_CHANNEL_OFFSET;
>> +	u64 duty_steps, period, tmp;
>> +	u8 prescale, period_steps, posedge, negedge;
>> +
>> +	prescale = PREG_TO_VAL(readb_relaxed(mchp_core_pwm->base + COREPWM_PRESCALE_REG));
>> +	period_steps = PREG_TO_VAL(readb_relaxed(mchp_core_pwm->base + COREPWM_PERIOD_REG));
>> +	period = period_steps * prescale * NSEC_PER_SEC;
>> +	period = div64_u64(period, clk_get_rate(mchp_core_pwm->clk));
>> +
>> +	/*
>> +	 * Calculate the duty cycle in multiples of the prescaled period:
>> +	 * duty_steps = duty_in_ns / step_in_ns
>> +	 * step_in_ns = (prescale * NSEC_PER_SEC) / clk_rate
>> +	 * The code below is rearranged slightly to only divide once.
>> +	 *
>> +	 * Because the period is per channel, it is possible that the requested
>> +	 * duty cycle is longer than the period, in which case cap it to the
>> +	 * period.
>> +	 */
>> +	if (state->duty_cycle > period) {
>> +		duty_steps = period_steps;
>> +	} else {
>> +		duty_steps = state->duty_cycle * clk_get_rate(mchp_core_pwm->clk);
>> +		tmp = prescale * NSEC_PER_SEC;
>> +		duty_steps = div64_u64(duty_steps, tmp);
>> +	}
>> +
>> +	/*
>> +	 * Turn the output on unless posedge == negedge, in which case the
>> +	 * duty is intended to be 0, but limitations of the IP block don't
>> +	 * allow a zero length duty cycle - so just set the max high/low time
>> +	 * respectively.
>> +	 */
>> +	if (state->polarity == PWM_POLARITY_INVERSED) {
>> +		negedge = !duty_steps ? period_steps : 0u;
>> +		posedge = duty_steps;
>> +	} else {
>> +		posedge = !duty_steps ? period_steps : 0u;
>> +		negedge = duty_steps;
>> +	}
>> +
>> +	writel_relaxed(posedge, channel_base + COREPWM_POSEDGE_OFFSET);
>> +	writel_relaxed(negedge, channel_base + COREPWM_NEGEDGE_OFFSET);
>> +}
>> +
>> +static void mchp_core_pwm_apply_period(struct pwm_chip *chip, const struct pwm_state *state)
>> +{
>> +	struct mchp_core_pwm_chip *mchp_core_pwm = to_mchp_core_pwm(chip);
>> +	u64 tmp = state->period;
>> +	u8 prescale, period_steps;
>> +
>> +	/*
>> +	 * Calculate the period cycles and prescale values.
>> +	 * The registers are each 8 bits wide & multiplied to compute the period
>> +	 * so the maximum period that can be generated is 0xFFFF times the period
>> +	 * of the input clock.
>> +	 */
>> +	tmp *= clk_get_rate(mchp_core_pwm->clk);
>> +	do_div(tmp, NSEC_PER_SEC);
>> +
>> +	if (tmp > 0xFFFFu) {
>> +		prescale = 0xFFu;
>> +		period_steps = 0xFFu;
>> +	} else {
>> +		prescale = tmp >> 8;
>> +		period_steps = tmp / PREG_TO_VAL(prescale) - 1;
> 
> Here is the 64bit division.
> 

Thanks :)
I would prob have missed that too, since I was thinking div /by/ > int.



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

* Re: [PATCH v2 1/2] pwm: add microchip soft ip corePWM driver
  2022-06-13 11:17 ` [PATCH v2 1/2] pwm: add microchip soft ip corePWM driver Conor Dooley
  2022-06-14 10:25   ` kernel test robot
  2022-06-14 12:34   ` Uwe Kleine-König
@ 2022-06-15 19:14   ` kernel test robot
  2022-06-15 19:20     ` Conor.Dooley
  2 siblings, 1 reply; 12+ messages in thread
From: kernel test robot @ 2022-06-15 19:14 UTC (permalink / raw)
  To: Conor Dooley, Thierry Reding, Uwe Kleine-König, Lee Jones
  Cc: kbuild-all, Daire McNamara, linux-kernel, linux-pwm, linux-riscv,
	Conor Dooley

Hi Conor,

I love your patch! Yet something to improve:

[auto build test ERROR on thierry-reding-pwm/for-next]
[also build test ERROR on linus/master v5.19-rc2 next-20220615]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/intel-lab-lkp/linux/commits/Conor-Dooley/pwm-add-microchip-soft-ip-corePWM-driver/20220613-211851
base:   https://git.kernel.org/pub/scm/linux/kernel/git/thierry.reding/linux-pwm.git for-next
config: powerpc-allyesconfig (https://download.01.org/0day-ci/archive/20220616/202206160239.6lkHbYaU-lkp@intel.com/config)
compiler: powerpc-linux-gcc (GCC) 11.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/intel-lab-lkp/linux/commit/4451a8420f9fd16ee9a0801fcf02f1ec04bb8ab0
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Conor-Dooley/pwm-add-microchip-soft-ip-corePWM-driver/20220613-211851
        git checkout 4451a8420f9fd16ee9a0801fcf02f1ec04bb8ab0
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.3.0 make.cross W=1 O=build_dir ARCH=powerpc SHELL=/bin/bash

If you fix the issue, kindly add following tag where applicable
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   powerpc-linux-ld: drivers/pwm/pwm-microchip-core.o: in function `mchp_core_pwm_apply':
>> pwm-microchip-core.c:(.text.mchp_core_pwm_apply+0x290): undefined reference to `__udivdi3'

-- 
0-DAY CI Kernel Test Service
https://01.org/lkp

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

* Re: [PATCH v2 1/2] pwm: add microchip soft ip corePWM driver
  2022-06-15 19:14   ` kernel test robot
@ 2022-06-15 19:20     ` Conor.Dooley
  0 siblings, 0 replies; 12+ messages in thread
From: Conor.Dooley @ 2022-06-15 19:20 UTC (permalink / raw)
  To: lkp, Conor.Dooley, thierry.reding, u.kleine-koenig, lee.jones
  Cc: kbuild-all, Daire.McNamara, linux-kernel, linux-pwm, linux-riscv



On 15/06/2022 20:14, kernel test robot wrote:
> Hi Conor,
> 
> I love your patch! Yet something to improve:
> 
> [auto build test ERROR on thierry-reding-pwm/for-next]
> [also build test ERROR on linus/master v5.19-rc2 next-20220615]
> [If your patch is applied to the wrong git tree, kindly drop us a note.
> And when submitting patch, we suggest to use '--base' as documented in
> https://git-scm.com/docs/git-format-patch]
> 
> url:    https://github.com/intel-lab-lkp/linux/commits/Conor-Dooley/pwm-add-microchip-soft-ip-corePWM-driver/20220613-211851
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/thierry.reding/linux-pwm.git for-next
> config: powerpc-allyesconfig (https://download.01.org/0day-ci/archive/20220616/202206160239.6lkHbYaU-lkp@intel.com/config)
> compiler: powerpc-linux-gcc (GCC) 11.3.0
> reproduce (this is a W=1 build):
>         wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
>         chmod +x ~/bin/make.cross
>         # https://github.com/intel-lab-lkp/linux/commit/4451a8420f9fd16ee9a0801fcf02f1ec04bb8ab0
>         git remote add linux-review https://github.com/intel-lab-lkp/linux
>         git fetch --no-tags linux-review Conor-Dooley/pwm-add-microchip-soft-ip-corePWM-driver/20220613-211851
>         git checkout 4451a8420f9fd16ee9a0801fcf02f1ec04bb8ab0
>         # save the config file
>         mkdir build_dir && cp config build_dir/.config
>         COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.3.0 make.cross W=1 O=build_dir ARCH=powerpc SHELL=/bin/bash
> 
> If you fix the issue, kindly add following tag where applicable
> Reported-by: kernel test robot <lkp@intel.com>
> 
> All errors (new ones prefixed by >>):
> 
>    powerpc-linux-ld: drivers/pwm/pwm-microchip-core.o: in function `mchp_core_pwm_apply':
>>> pwm-microchip-core.c:(.text.mchp_core_pwm_apply+0x290): undefined reference to `__udivdi3'

Not new :) (well on this arch it is I guess)

FWIW Uwe, the fix was obv. not difficult but I ran into more
problems with idempotency while checking before resending with
the fix. I had fixed all the idempotency problems with my v2
but I think turning on the shadow registers in the core changed
the behaviour I was relying on so I won't send v3 with this fix
until that point.

Thanks,
Cnor.

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

end of thread, other threads:[~2022-06-15 19:21 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-13 11:17 [PATCH v2 0/2] Add support for Microchip's pwm fpga core Conor Dooley
2022-06-13 11:17 ` [PATCH v2 1/2] pwm: add microchip soft ip corePWM driver Conor Dooley
2022-06-14 10:25   ` kernel test robot
2022-06-14 10:34     ` Conor.Dooley
2022-06-14 12:13       ` Uwe Kleine-König
2022-06-14 12:16         ` Conor.Dooley
2022-06-14 12:34   ` Uwe Kleine-König
2022-06-14 12:38     ` Conor.Dooley
2022-06-15 19:14   ` kernel test robot
2022-06-15 19:20     ` Conor.Dooley
2022-06-13 11:18 ` [PATCH v2 2/2] MAINTAINERS: add pwm to PolarFire SoC entry Conor Dooley
2022-06-13 11:56 ` [PATCH v2 0/2] Add support for Microchip's pwm fpga core Conor.Dooley

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).