[RFC v2 0/2] PWM support for HiFive Unleashed
This patch series adds PWM drivers and DT documentation for HiFive Unleashed board. The patches are mostly based on Wesley's patch. V2 of this patchset incorporates below items pointed out in v1. V2 changed from V1: 1. Remove inclusion of dt-bindings/pwm/pwm.h 2. Remove artificial alignments 3. Replace ioread32/iowrite32 with readl/writel 4. Remove camelcase 5. Change dev_info to dev_dbg for unnecessary log 6. Correct typo in driver name 7. Remove use of of_match_ptr macro 8. Update the DT compatible strings and Add reference to a common versioning document Yash Shah (2): pwm: sifive: Add DT documentation for SiFive PWM Controller pwm: sifive: Add a driver for SiFive SoC PWM .../devicetree/bindings/pwm/pwm-sifive.txt | 44 drivers/pwm/Kconfig| 10 + drivers/pwm/Makefile | 1 + drivers/pwm/pwm-sifive.c | 229 + 4 files changed, 284 insertions(+) create mode 100644 Documentation/devicetree/bindings/pwm/pwm-sifive.txt create mode 100644 drivers/pwm/pwm-sifive.c -- 1.9.1
[RFC v2 2/2] pwm: sifive: Add a driver for SiFive SoC PWM
Adds a PWM driver for PWM chip present in SiFive's HiFive Unleashed SoC. Signed-off-by: Wesley W. Terpstra [Atish: Various fixes and code cleanup] Signed-off-by: Atish Patra Signed-off-by: Yash Shah --- drivers/pwm/Kconfig | 10 +++ drivers/pwm/Makefile | 1 + drivers/pwm/pwm-sifive.c | 229 +++ 3 files changed, 240 insertions(+) create mode 100644 drivers/pwm/pwm-sifive.c diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig index 27e5dd4..da85557 100644 --- a/drivers/pwm/Kconfig +++ b/drivers/pwm/Kconfig @@ -378,6 +378,16 @@ config PWM_SAMSUNG To compile this driver as a module, choose M here: the module will be called pwm-samsung. +config PWM_SIFIVE + tristate "SiFive PWM support" + depends on OF + depends on COMMON_CLK + help + Generic PWM framework driver for SiFive SoCs. + + To compile this driver as a module, choose M here: the module + will be called pwm-sifive. + config PWM_SPEAR tristate "STMicroelectronics SPEAr PWM support" depends on PLAT_SPEAR diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile index 9c676a0..30089ca 100644 --- a/drivers/pwm/Makefile +++ b/drivers/pwm/Makefile @@ -37,6 +37,7 @@ obj-$(CONFIG_PWM_RCAR)+= pwm-rcar.o obj-$(CONFIG_PWM_RENESAS_TPU) += pwm-renesas-tpu.o obj-$(CONFIG_PWM_ROCKCHIP) += pwm-rockchip.o obj-$(CONFIG_PWM_SAMSUNG) += pwm-samsung.o +obj-$(CONFIG_PWM_SIFIVE) += pwm-sifive.o obj-$(CONFIG_PWM_SPEAR)+= pwm-spear.o obj-$(CONFIG_PWM_STI) += pwm-sti.o obj-$(CONFIG_PWM_STM32)+= pwm-stm32.o diff --git a/drivers/pwm/pwm-sifive.c b/drivers/pwm/pwm-sifive.c new file mode 100644 index 000..26913b6 --- /dev/null +++ b/drivers/pwm/pwm-sifive.c @@ -0,0 +1,229 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2017-2018 SiFive + */ +#include +#include +#include +#include +#include +#include + +/* Register offsets */ +#define REG_PWMCFG 0x0 +#define REG_PWMCOUNT 0x8 +#define REG_PWMS 0x10 +#define REG_PWMCMP00x20 + +/* PWMCFG fields */ +#define BIT_PWM_SCALE 0 +#define BIT_PWM_STICKY 8 +#define BIT_PWM_ZERO_ZMP 9 +#define BIT_PWM_DEGLITCH 10 +#define BIT_PWM_EN_ALWAYS 12 +#define BIT_PWM_EN_ONCE13 +#define BIT_PWM0_CENTER16 +#define BIT_PWM0_GANG 24 +#define BIT_PWM0_IP28 + +#define SIZE_PWMCMP4 +#define MASK_PWM_SCALE 0xf + +struct sifive_pwm_device { + struct pwm_chip chip; + struct notifier_block notifier; + struct clk *clk; + void __iomem *regs; + unsigned int approx_period; + unsigned int real_period; +}; + +static inline struct sifive_pwm_device *to_sifive_pwm_chip(struct pwm_chip *c) +{ + return container_of(c, struct sifive_pwm_device, chip); +} + +static int sifive_pwm_apply(struct pwm_chip *chip, struct pwm_device *dev, + struct pwm_state *state) +{ + struct sifive_pwm_device *pwm = to_sifive_pwm_chip(chip); + unsigned int duty_cycle; + u32 frac; + + duty_cycle = state->duty_cycle; + if (!state->enabled) + duty_cycle = 0; + + frac = ((u64)duty_cycle << 16) / state->period; + frac = min(frac, 0xU); + + writel(frac, pwm->regs + REG_PWMCMP0 + dev->hwpwm * SIZE_PWMCMP); + + if (state->enabled) { + state->period = pwm->real_period; + state->duty_cycle = ((u64)frac * pwm->real_period) >> 16; + } + + return 0; +} + +static void sifive_pwm_get_state(struct pwm_chip *chip, struct pwm_device *dev, +struct pwm_state *state) +{ + struct sifive_pwm_device *pwm = to_sifive_pwm_chip(chip); + u32 duty; + + duty = readl(pwm->regs + REG_PWMCMP0 + dev->hwpwm * SIZE_PWMCMP); + + state->period = pwm->real_period; + state->duty_cycle = ((u64)duty * pwm->real_period) >> 16; + state->polarity = PWM_POLARITY_INVERSED; + state->enabled = duty > 0; +} + +static const struct pwm_ops sifive_pwm_ops = { + .get_state = sifive_pwm_get_state, + .apply = sifive_pwm_apply, + .owner = THIS_MODULE, +}; + +static struct pwm_device *sifive_pwm_xlate(struct pwm_chip *chip, + const struct of_phandle_args *args) +{ + struct sifive_pwm_device *pwm = to_sifive_pwm_chip(chip); + struct pwm_device *dev; + + if (args->args[0] >= chip->npwm) + return ERR_PTR(-EINVAL); + + dev = pwm_request_from_chip(chip, args->args[0], NULL); + if (IS_ERR(dev)) + return dev; + + /* The period cannot be changed on a per-PWM basis */ + d
[RFC v2 1/2] pwm: sifive: Add DT documentation for SiFive PWM Controller
DT documentation for PWM controller added with updated compatible string. Signed-off-by: Wesley W. Terpstra [Atish: Compatible string update] Signed-off-by: Atish Patra Signed-off-by: Yash Shah --- .../devicetree/bindings/pwm/pwm-sifive.txt | 44 ++ 1 file changed, 44 insertions(+) create mode 100644 Documentation/devicetree/bindings/pwm/pwm-sifive.txt diff --git a/Documentation/devicetree/bindings/pwm/pwm-sifive.txt b/Documentation/devicetree/bindings/pwm/pwm-sifive.txt new file mode 100644 index 000..250d8ee --- /dev/null +++ b/Documentation/devicetree/bindings/pwm/pwm-sifive.txt @@ -0,0 +1,44 @@ +SiFive PWM controller + +Unlike most other PWM controllers, the SiFive PWM controller currently only +supports one period for all channels in the PWM. This is set globally in DTS. +The period also has significant restrictions on the values it can achieve, +which the driver rounds to the nearest achievable frequency. + +Required properties: +- compatible: should be something similar to "sifive,-pwm" for + the PWM as integrated on a particular chip, and + "sifive,pwm" for the general PWM IP block + programming model. Supported compatible strings are: + "sifive,fu540-c000-pwm" for the SiFive PWM v0 as + integrated onto the SiFive FU540 chip, and "sifive,pwm0" + for the SiFive PWM v0 IP block with no chip integration + tweaks. +- reg: physical base address and length of the controller's registers +- clocks: The frequency the controller runs at +- #pwm-cells: Should be 2. + The first cell is the PWM channel number + The second cell is the PWM polarity +- sifive,approx-period: the driver will get as close to this period as it can +- interrupts: one interrupt per PWM channel + +PWM RTL that corresponds to the IP block version numbers can be found +here: + +https://github.com/sifive/sifive-blocks/tree/master/src/main/scala/devices/pwm + +Further information on the format of the IP +block-specific version numbers can be found in +Documentation/devicetree/bindings/sifive/sifive-blocks-ip-versioning.txt + +Examples: + +pwm: pwm@1002 { + compatible = "sifive,fu540-c000-pwm","sifive,pwm0"; + reg = <0x0 0x1002 0x0 0x1000>; + clocks = <&tlclk>; + interrupt-parent = <&plic>; + interrupts = <42 43 44 45>; + #pwm-cells = <2>; + sifive,approx-period = <100>; +}; -- 1.9.1
Re: [RFC v2 1/2] pwm: sifive: Add DT documentation for SiFive PWM Controller
On Tue, Dec 18, 2018 at 10:50 PM Rob Herring wrote: > > On Fri, Dec 14, 2018 at 11:50:41AM +0530, Yash Shah wrote: > > DT documentation for PWM controller added with updated compatible > > string. > > > > Signed-off-by: Wesley W. Terpstra > > [Atish: Compatible string update] > > Signed-off-by: Atish Patra > > Signed-off-by: Yash Shah > > --- > > .../devicetree/bindings/pwm/pwm-sifive.txt | 44 > > ++ > > 1 file changed, 44 insertions(+) > > create mode 100644 Documentation/devicetree/bindings/pwm/pwm-sifive.txt > > > > diff --git a/Documentation/devicetree/bindings/pwm/pwm-sifive.txt > > b/Documentation/devicetree/bindings/pwm/pwm-sifive.txt > > new file mode 100644 > > index 000..250d8ee > > --- /dev/null > > +++ b/Documentation/devicetree/bindings/pwm/pwm-sifive.txt > > @@ -0,0 +1,44 @@ > > +SiFive PWM controller > > + > > +Unlike most other PWM controllers, the SiFive PWM controller currently only > > +supports one period for all channels in the PWM. This is set globally in > > DTS. > > +The period also has significant restrictions on the values it can achieve, > > +which the driver rounds to the nearest achievable frequency. > > + > > +Required properties: > > +- compatible: should be something similar to "sifive,-pwm" for > > + the PWM as integrated on a particular chip, and > > + "sifive,pwm" for the general PWM IP block > > + programming model. Supported compatible strings are: > > + "sifive,fu540-c000-pwm" for the SiFive PWM v0 as > > + integrated onto the SiFive FU540 chip, and "sifive,pwm0" > > + for the SiFive PWM v0 IP block with no chip integration > > + tweaks. > > This should reference the common doc Paul has written and not re-explain > the versioning scheme again. Ok sure. > > > +- reg: physical base address and length of the controller's registers > > +- clocks: The frequency the controller runs at > > +- #pwm-cells: Should be 2. > > + The first cell is the PWM channel number > > + The second cell is the PWM polarity > > +- sifive,approx-period: the driver will get as close to this period as it > > can > > Needs a unit suffix as defined in property-units.txt Will be done. > > > +- interrupts: one interrupt per PWM channel > > + > > +PWM RTL that corresponds to the IP block version numbers can be found > > +here: > > + > > +https://github.com/sifive/sifive-blocks/tree/master/src/main/scala/devices/pwm > > + > > +Further information on the format of the IP > > +block-specific version numbers can be found in > > +Documentation/devicetree/bindings/sifive/sifive-blocks-ip-versioning.txt > > + > > +Examples: > > + > > +pwm: pwm@1002 { > > + compatible = "sifive,fu540-c000-pwm","sifive,pwm0"; > > + reg = <0x0 0x1002 0x0 0x1000>; > > + clocks = <&tlclk>; > > + interrupt-parent = <&plic>; > > + interrupts = <42 43 44 45>; > > + #pwm-cells = <2>; > > + sifive,approx-period = <100>; > > +}; > > -- > > 1.9.1 > > Thanks for the comments!
Re: [RFC v2 1/2] pwm: sifive: Add DT documentation for SiFive PWM Controller
On Tue, Dec 18, 2018 at 2:46 AM Uwe Kleine-König wrote: > > On Fri, Dec 14, 2018 at 11:50:41AM +0530, Yash Shah wrote: > > DT documentation for PWM controller added with updated compatible > > string. > > > > Signed-off-by: Wesley W. Terpstra > > [Atish: Compatible string update] > > Signed-off-by: Atish Patra > > Signed-off-by: Yash Shah > > --- > > .../devicetree/bindings/pwm/pwm-sifive.txt | 44 > > ++ > > 1 file changed, 44 insertions(+) > > create mode 100644 Documentation/devicetree/bindings/pwm/pwm-sifive.txt > > > > diff --git a/Documentation/devicetree/bindings/pwm/pwm-sifive.txt > > b/Documentation/devicetree/bindings/pwm/pwm-sifive.txt > > new file mode 100644 > > index 000..250d8ee > > --- /dev/null > > +++ b/Documentation/devicetree/bindings/pwm/pwm-sifive.txt > > @@ -0,0 +1,44 @@ > > +SiFive PWM controller > > + > > +Unlike most other PWM controllers, the SiFive PWM controller currently only > > +supports one period for all channels in the PWM. This is set globally in > > DTS. > > +The period also has significant restrictions on the values it can achieve, > > +which the driver rounds to the nearest achievable frequency. > > + > > +Required properties: > > +- compatible: should be something similar to "sifive,-pwm" for > > + the PWM as integrated on a particular chip, and > > + "sifive,pwm" for the general PWM IP block > > + programming model. Supported compatible strings are: > > + "sifive,fu540-c000-pwm" for the SiFive PWM v0 as > > + integrated onto the SiFive FU540 chip, and "sifive,pwm0" > > + for the SiFive PWM v0 IP block with no chip integration > > + tweaks. > > +- reg: physical base address and length of the controller's registers > > +- clocks: The frequency the controller runs at > > This is unusual and the example below lists a clock phandle (which is > the common thing), so I guess the description is just wrong. You are right, I will correct the description. > > > +- #pwm-cells: Should be 2. > > + The first cell is the PWM channel number > > + The second cell is the PWM polarity > > +- sifive,approx-period: the driver will get as close to this period as it > > can > > What is the unit? I'd drop "approx", that the driver might not be able > to exactly hit the specified period is (IMHO) obvious and doesn't need > to be mentioned in the property name. The unit is nanoseconds. Will add the unit suffix to the property name. > > > +- interrupts: one interrupt per PWM channel > > + > > +PWM RTL that corresponds to the IP block version numbers can be found > > +here: > > + > > +https://github.com/sifive/sifive-blocks/tree/master/src/main/scala/devices/pwm > > + > > +Further information on the format of the IP > > +block-specific version numbers can be found in > > +Documentation/devicetree/bindings/sifive/sifive-blocks-ip-versioning.txt > > + > > +Examples: > > + > > +pwm: pwm@1002 { > > + compatible = "sifive,fu540-c000-pwm","sifive,pwm0"; > > + reg = <0x0 0x1002 0x0 0x1000>; > > + clocks = <&tlclk>; > > + interrupt-parent = <&plic>; > > + interrupts = <42 43 44 45>; > > + #pwm-cells = <2>; > > + sifive,approx-period = <100>; > > +}; > > Best regards > Uwe Thanks for the comments! > > -- > Pengutronix e.K. | Uwe Kleine-König| > Industrial Linux Solutions | http://www.pengutronix.de/ |
Re: [RFC v2 2/2] pwm: sifive: Add a driver for SiFive SoC PWM
On Tue, Dec 18, 2018 at 3:42 AM Uwe Kleine-König wrote: > > On Fri, Dec 14, 2018 at 11:50:42AM +0530, Yash Shah wrote: > > Adds a PWM driver for PWM chip present in SiFive's HiFive Unleashed SoC. > > > > Signed-off-by: Wesley W. Terpstra > > [Atish: Various fixes and code cleanup] > > Signed-off-by: Atish Patra > > Signed-off-by: Yash Shah > > --- > > drivers/pwm/Kconfig | 10 +++ > > drivers/pwm/Makefile | 1 + > > drivers/pwm/pwm-sifive.c | 229 > > +++ > > 3 files changed, 240 insertions(+) > > create mode 100644 drivers/pwm/pwm-sifive.c > > > > diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig > > index 27e5dd4..da85557 100644 > > --- a/drivers/pwm/Kconfig > > +++ b/drivers/pwm/Kconfig > > @@ -378,6 +378,16 @@ config PWM_SAMSUNG > > To compile this driver as a module, choose M here: the module > > will be called pwm-samsung. > > > > +config PWM_SIFIVE > > + tristate "SiFive PWM support" > > + depends on OF > > + depends on COMMON_CLK > > + help > > + Generic PWM framework driver for SiFive SoCs. > > + > > + To compile this driver as a module, choose M here: the module > > + will be called pwm-sifive. > > + > > config PWM_SPEAR > > tristate "STMicroelectronics SPEAr PWM support" > > depends on PLAT_SPEAR > > diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile > > index 9c676a0..30089ca 100644 > > --- a/drivers/pwm/Makefile > > +++ b/drivers/pwm/Makefile > > @@ -37,6 +37,7 @@ obj-$(CONFIG_PWM_RCAR) += pwm-rcar.o > > obj-$(CONFIG_PWM_RENESAS_TPU)+= pwm-renesas-tpu.o > > obj-$(CONFIG_PWM_ROCKCHIP) += pwm-rockchip.o > > obj-$(CONFIG_PWM_SAMSUNG)+= pwm-samsung.o > > +obj-$(CONFIG_PWM_SIFIVE) += pwm-sifive.o > > obj-$(CONFIG_PWM_SPEAR) += pwm-spear.o > > obj-$(CONFIG_PWM_STI)+= pwm-sti.o > > obj-$(CONFIG_PWM_STM32) += pwm-stm32.o > > diff --git a/drivers/pwm/pwm-sifive.c b/drivers/pwm/pwm-sifive.c > > new file mode 100644 > > index 000..26913b6 > > --- /dev/null > > +++ b/drivers/pwm/pwm-sifive.c > > @@ -0,0 +1,229 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > +/* > > + * Copyright (C) 2017-2018 SiFive > > If there is a publically available reference manual, please add a link > to it here. Ok will add the link to the reference manual. > > > + */ > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > + > > +/* Register offsets */ > > +#define REG_PWMCFG 0x0 > > +#define REG_PWMCOUNT 0x8 > > +#define REG_PWMS 0x10 > > +#define REG_PWMCMP0 0x20 > > + > > +/* PWMCFG fields */ > > +#define BIT_PWM_SCALE0 > > +#define BIT_PWM_STICKY 8 > > +#define BIT_PWM_ZERO_ZMP 9 > > +#define BIT_PWM_DEGLITCH 10 > > +#define BIT_PWM_EN_ALWAYS12 > > +#define BIT_PWM_EN_ONCE 13 > > +#define BIT_PWM0_CENTER 16 > > +#define BIT_PWM0_GANG24 > > +#define BIT_PWM0_IP 28 > > + > > +#define SIZE_PWMCMP 4 > > +#define MASK_PWM_SCALE 0xf > > + > > +struct sifive_pwm_device { > > + struct pwm_chip chip; > > + struct notifier_block notifier; > > + struct clk *clk; > > + void __iomem *regs; > > + unsigned int approx_period; > > + unsigned int real_period; > > +}; > > + > > +static inline struct sifive_pwm_device *to_sifive_pwm_chip(struct pwm_chip > > *c) > > +{ > > + return container_of(c, struct sifive_pwm_device, chip); > > +} > > + > > +static int sifive_pwm_apply(struct pwm_chip *chip, struct pwm_device *dev, > > + struct pwm_state *state) > > +{ > > + struct sifive_pwm_device *pwm = to_sifive_pwm_chip(chip); > > + unsigned int duty_cycle; > > + u32 frac; > > + > > + duty_cycle = state->duty_cycle; > > + if (!state->enabled) > > + duty_cycle = 0; > > @Thierry: You see, this driver is cheating in the same way that I > suggested to implement for imx. > > > + > > + frac = ((u64)duty_cycle << 16) / state->period; > > You must not use / to divide an u64 (unless you're on a 64 bit arch). Will use div_u64(). >
[PATCH v8 0/2] PWM support for HiFive Unleashed
This patch series adds a PWM driver and DT documentation for HiFive Unleashed board. The patches are mostly based on Wesley's patch. v8 - Typo corrections - Remove active_user and related code - Do not clear PWM_SIFIVE_PWMCFG_EN_ALWAYS - Other minor fixes v7 - Modify description of compatible property in DT documentation - Use mutex locks at appropriate places - Fix all bad line breaks - Allow enabling/disabling PWM only when the user is the only active user - Remove Deglitch logic - Other minor fixes v6 - Remove the global property 'sifive,period-ns' - Implement free and request callbacks to maintain user counts. - Add user_count member to struct pwm_sifive_ddata - Allow period change only if user_count is one - Add pwm_sifive_enable function to enable/disable PWM - Change calculation logic of frac (in pwm_sifive_apply) - Remove state correction - Remove pwm_sifive_xlate function - Clock to be enabled only when PWM is enabled - Other minor fixes v5 - Correct the order of compatible string properties - PWM state correction to be done always - Other minor fixes based upon feedback on v4 v4 - Rename macros with appropriate names - Remove unused macros - Rename struct sifive_pwm_device to struct pwm_sifive_ddata - Rename function prefix as per driver name - Other minor fixes based upon feedback on v3 v3 - Add a link to the reference manaul - Use appropriate apis for division operation - Add check for polarity - Enable clk before calling clk_get_rate - Other minor fixes based upon feedback on v2 V2 changed from V1: - Remove inclusion of dt-bindings/pwm/pwm.h - Remove artificial alignments - Replace ioread32/iowrite32 with readl/writel - Remove camelcase - Change dev_info to dev_dbg for unnecessary log - Correct typo in driver name - Remove use of of_match_ptr macro - Update the DT compatible strings and Add reference to a common versioning document Yash Shah (2): pwm: sifive: Add DT documentation for SiFive PWM Controller pwm: sifive: Add a driver for SiFive SoC PWM .../devicetree/bindings/pwm/pwm-sifive.txt | 33 ++ drivers/pwm/Kconfig| 11 + drivers/pwm/Makefile | 1 + drivers/pwm/pwm-sifive.c | 345 + 4 files changed, 390 insertions(+) create mode 100644 Documentation/devicetree/bindings/pwm/pwm-sifive.txt create mode 100644 drivers/pwm/pwm-sifive.c -- 1.9.1
[PATCH v8 1/2] pwm: sifive: Add DT documentation for SiFive PWM Controller
DT documentation for PWM controller added. Signed-off-by: Wesley W. Terpstra [Atish: Compatible string update] Signed-off-by: Atish Patra Signed-off-by: Yash Shah Reviewed-by: Rob Herring --- .../devicetree/bindings/pwm/pwm-sifive.txt | 33 ++ 1 file changed, 33 insertions(+) create mode 100644 Documentation/devicetree/bindings/pwm/pwm-sifive.txt diff --git a/Documentation/devicetree/bindings/pwm/pwm-sifive.txt b/Documentation/devicetree/bindings/pwm/pwm-sifive.txt new file mode 100644 index 000..36447e3 --- /dev/null +++ b/Documentation/devicetree/bindings/pwm/pwm-sifive.txt @@ -0,0 +1,33 @@ +SiFive PWM controller + +Unlike most other PWM controllers, the SiFive PWM controller currently only +supports one period for all channels in the PWM. All PWMs need to run at +the same period. The period also has significant restrictions on the values +it can achieve, which the driver rounds to the nearest achievable period. +PWM RTL that corresponds to the IP block version numbers can be found +here: + +https://github.com/sifive/sifive-blocks/tree/master/src/main/scala/devices/pwm + +Required properties: +- compatible: Should be "sifive,-pwm" and "sifive,pwm". + Supported compatible strings are: "sifive,fu540-c000-pwm" for the SiFive + PWM v0 as integrated onto the SiFive FU540 chip, and "sifive,pwm0" for the + SiFive PWM v0 IP block with no chip integration tweaks. + Please refer to sifive-blocks-ip-versioning.txt for details. +- reg: physical base address and length of the controller's registers +- clocks: Should contain a clock identifier for the PWM's parent clock. +- #pwm-cells: Should be 3. See pwm.txt in this directory + for a description of the cell format. +- interrupts: one interrupt per PWM channel + +Examples: + +pwm: pwm@1002 { + compatible = "sifive,fu540-c000-pwm", "sifive,pwm0"; + reg = <0x0 0x1002 0x0 0x1000>; + clocks = <&tlclk>; + interrupt-parent = <&plic>; + interrupts = <42 43 44 45>; + #pwm-cells = <3>; +}; -- 1.9.1
[PATCH v8 2/2] pwm: sifive: Add a driver for SiFive SoC PWM
Adds a PWM driver for PWM chip present in SiFive's HiFive Unleashed SoC. Signed-off-by: Wesley W. Terpstra [Atish: Various fixes and code cleanup] Signed-off-by: Atish Patra Signed-off-by: Yash Shah --- drivers/pwm/Kconfig | 11 ++ drivers/pwm/Makefile | 1 + drivers/pwm/pwm-sifive.c | 345 +++ 3 files changed, 357 insertions(+) create mode 100644 drivers/pwm/pwm-sifive.c diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig index a8f47df..4a61d1a 100644 --- a/drivers/pwm/Kconfig +++ b/drivers/pwm/Kconfig @@ -380,6 +380,17 @@ config PWM_SAMSUNG To compile this driver as a module, choose M here: the module will be called pwm-samsung. +config PWM_SIFIVE + tristate "SiFive PWM support" + depends on OF + depends on COMMON_CLK + depends on RISCV || COMPILE_TEST + help + Generic PWM framework driver for SiFive SoCs. + + To compile this driver as a module, choose M here: the module + will be called pwm-sifive. + config PWM_SPEAR tristate "STMicroelectronics SPEAr PWM support" depends on PLAT_SPEAR diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile index 9c676a0..30089ca 100644 --- a/drivers/pwm/Makefile +++ b/drivers/pwm/Makefile @@ -37,6 +37,7 @@ obj-$(CONFIG_PWM_RCAR)+= pwm-rcar.o obj-$(CONFIG_PWM_RENESAS_TPU) += pwm-renesas-tpu.o obj-$(CONFIG_PWM_ROCKCHIP) += pwm-rockchip.o obj-$(CONFIG_PWM_SAMSUNG) += pwm-samsung.o +obj-$(CONFIG_PWM_SIFIVE) += pwm-sifive.o obj-$(CONFIG_PWM_SPEAR)+= pwm-spear.o obj-$(CONFIG_PWM_STI) += pwm-sti.o obj-$(CONFIG_PWM_STM32)+= pwm-stm32.o diff --git a/drivers/pwm/pwm-sifive.c b/drivers/pwm/pwm-sifive.c new file mode 100644 index 000..6679ec7 --- /dev/null +++ b/drivers/pwm/pwm-sifive.c @@ -0,0 +1,345 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2017-2018 SiFive + * For SiFive's PWM IP block documentation please refer Chapter 14 of + * Reference Manual : https://static.dev.sifive.com/FU540-C000-v1.0.pdf + * + * Limitations: + * - When changing both duty cycle and period, we cannot prevent in + * software that the output might produce a period with mixed + * settings (new period length and old duty cycle). + * - The hardware cannot generate a 100% duty cycle. + * - The hardware generates only inverted output. + */ +#include +#include +#include +#include +#include +#include + +/* Register offsets */ +#define PWM_SIFIVE_PWMCFG 0x0 +#define PWM_SIFIVE_PWMCOUNT0x8 +#define PWM_SIFIVE_PWMS0x10 +#define PWM_SIFIVE_PWMCMP0 0x20 + +/* PWMCFG fields */ +#define PWM_SIFIVE_PWMCFG_SCALE0 +#define PWM_SIFIVE_PWMCFG_STICKY 8 +#define PWM_SIFIVE_PWMCFG_ZERO_CMP 9 +#define PWM_SIFIVE_PWMCFG_DEGLITCH 10 +#define PWM_SIFIVE_PWMCFG_EN_ALWAYSBIT(12) +#define PWM_SIFIVE_PWMCFG_EN_ONCE 13 +#define PWM_SIFIVE_PWMCFG_CENTER 16 +#define PWM_SIFIVE_PWMCFG_GANG 24 +#define PWM_SIFIVE_PWMCFG_IP 28 + +/* PWM_SIFIVE_SIZE_PWMCMP is used to calculate offset for pwmcmpX registers */ +#define PWM_SIFIVE_SIZE_PWMCMP 4 +#define PWM_SIFIVE_CMPWIDTH16 +#define PWM_SIFIVE_DEFAULT_PERIOD 1000 + +struct pwm_sifive_ddata { + struct pwm_chip chip; + struct mutex lock; /* lock to protect user_count */ + struct notifier_block notifier; + struct clk *clk; + void __iomem *regs; + unsigned int real_period; + int user_count; +}; + +static inline +struct pwm_sifive_ddata *pwm_sifive_chip_to_ddata(struct pwm_chip *c) +{ + return container_of(c, struct pwm_sifive_ddata, chip); +} + +static int pwm_sifive_request(struct pwm_chip *chip, struct pwm_device *dev) +{ + struct pwm_sifive_ddata *pwm = pwm_sifive_chip_to_ddata(chip); + + mutex_lock(&pwm->lock); + pwm->user_count++; + mutex_unlock(&pwm->lock); + + return 0; +} + +static void pwm_sifive_free(struct pwm_chip *chip, struct pwm_device *dev) +{ + struct pwm_sifive_ddata *pwm = pwm_sifive_chip_to_ddata(chip); + + mutex_lock(&pwm->lock); + pwm->user_count--; + mutex_unlock(&pwm->lock); +} + +static void pwm_sifive_update_clock(struct pwm_sifive_ddata *pwm, + unsigned long rate) +{ + u32 val; + unsigned long long num; + /* (1 << (PWM_SIFIVE_CMPWIDTH+scale)) * 10^9/rate = real_period */ + unsigned long scale_pow = + div64_ul(pwm->real_period * (u64)rate, NSEC_PER_SEC); + int scale = clamp(ilog2(scale_pow) - PWM_SIFIVE_CMPWIDTH, 0, 0xf); + + val = PWM_SIFIVE_PWMCFG_EN_ALWAYS | (scale << PWM_SIFIVE_PWMCFG_SCALE); + writel(val, pwm->regs + PWM_SIFIVE_PWMCFG); + + /*
[PATCH 0/2] L2 cache controller support for SiFive FU540
This patch series adds an L2 cache controller driver with DT documentation for SiFive FU540-C000. These two patches were initially part of the patch series: 'L2 cache controller and EDAC support for SiFive SoCs' https://lkml.org/lkml/2019/4/15/320 In order to merge L2 cache controller driver without any dependency on EDAC, the L2 cache controller patches are re-posted seperately in this series. The patchset is based on Linux 5.1-rc2 and tested on HiFive Unleashed board with additional board related patches needed for testing can be found at dev/yashs/L2_cache_controller branch of: https://github.com/yashshah7/riscv-linux.git Yash Shah (2): RISC-V: Add DT documentation for SiFive L2 Cache Controller RISC-V: sifive_l2_cache: Add L2 cache controller driver for SiFive SoCs .../devicetree/bindings/riscv/sifive-l2-cache.txt | 53 + arch/riscv/mm/Makefile | 1 + arch/riscv/mm/sifive_l2_cache.c| 224 + 3 files changed, 278 insertions(+) create mode 100644 Documentation/devicetree/bindings/riscv/sifive-l2-cache.txt create mode 100644 arch/riscv/mm/sifive_l2_cache.c -- 1.9.1
[PATCH 2/2] RISC-V: sifive_l2_cache: Add L2 cache controller driver for SiFive SoCs
The driver currently supports only SiFive FU540-C000 platform. The initial version of L2 cache controller driver includes: - Initial configuration reporting at boot up. - Support for ECC related functionality. Signed-off-by: Yash Shah --- arch/riscv/mm/Makefile | 1 + arch/riscv/mm/sifive_l2_cache.c | 224 2 files changed, 225 insertions(+) create mode 100644 arch/riscv/mm/sifive_l2_cache.c diff --git a/arch/riscv/mm/Makefile b/arch/riscv/mm/Makefile index eb22ab4..1523ee5 100644 --- a/arch/riscv/mm/Makefile +++ b/arch/riscv/mm/Makefile @@ -3,3 +3,4 @@ obj-y += fault.o obj-y += extable.o obj-y += ioremap.o obj-y += cacheflush.o +obj-y += sifive_l2_cache.o diff --git a/arch/riscv/mm/sifive_l2_cache.c b/arch/riscv/mm/sifive_l2_cache.c new file mode 100644 index 000..95f10e4 --- /dev/null +++ b/arch/riscv/mm/sifive_l2_cache.c @@ -0,0 +1,224 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * SiFive L2 cache controller Driver + * + * Copyright (C) 2018-2019 SiFive, Inc. + * + */ +#include +#include +#include +#include + +#define SIFIVE_L2_DIRECCFIX_LOW 0x100 +#define SIFIVE_L2_DIRECCFIX_HIGH 0x104 +#define SIFIVE_L2_DIRECCFIX_COUNT 0x108 + +#define SIFIVE_L2_DATECCFIX_LOW 0x140 +#define SIFIVE_L2_DATECCFIX_HIGH 0x144 +#define SIFIVE_L2_DATECCFIX_COUNT 0x148 + +#define SIFIVE_L2_DATECCFAIL_LOW 0x160 +#define SIFIVE_L2_DATECCFAIL_HIGH 0x164 +#define SIFIVE_L2_DATECCFAIL_COUNT 0x168 + +#define SIFIVE_L2_CONFIG 0x00 +#define SIFIVE_L2_WAYENABLE 0x08 +#define SIFIVE_L2_ECCINJECTERR 0x40 + +#define SIFIVE_L2_ERR_TYPE_CE 0 +#define SIFIVE_L2_ERR_TYPE_UE 1 +#define SIFIVE_L2_MAX_ECCINTR 3 + +static void __iomem *l2_base; +static int g_irq[SIFIVE_L2_MAX_ECCINTR]; + +enum { + DIR_CORR = 0, + DATA_CORR, + DATA_UNCORR, +}; + +static unsigned int l2_dirfix_addr_high(void) +{ + return readl(l2_base + SIFIVE_L2_DIRECCFIX_HIGH); +} + +static unsigned int l2_dirfix_addr_low(void) +{ + return readl(l2_base + SIFIVE_L2_DIRECCFIX_LOW); +} + +static unsigned int l2_dirfix_count(void) +{ + return readl(l2_base + SIFIVE_L2_DIRECCFIX_COUNT); +} + +static unsigned int l2_datfix_addr_high(void) +{ + return readl(l2_base + SIFIVE_L2_DATECCFIX_HIGH); +} + +static unsigned int l2_datfix_addr_low(void) +{ + return readl(l2_base + SIFIVE_L2_DATECCFIX_LOW); +} + +static unsigned int l2_datfix_count(void) +{ + return readl(l2_base + SIFIVE_L2_DATECCFIX_COUNT); +} + +static unsigned int l2_datfail_addr_high(void) +{ + return readl(l2_base + SIFIVE_L2_DATECCFAIL_HIGH); +} + +static unsigned int l2_datfail_addr_low(void) +{ + return readl(l2_base + SIFIVE_L2_DATECCFAIL_LOW); +} + +static unsigned int l2_datfail_count(void) +{ + return readl(l2_base + SIFIVE_L2_DATECCFAIL_COUNT); +} + +#ifdef CONFIG_DEBUG_FS +static struct dentry *sifive_test; + +static ssize_t l2_write(struct file *file, const char __user *data, + size_t count, loff_t *ppos) +{ + unsigned int val; + + if (kstrtouint_from_user(data, count, 0, &val)) + return -EINVAL; + if ((val >= 0 && val < 0xFF) || (val >= 0x1 && val < 0x100FF)) + writel(val, l2_base + SIFIVE_L2_ECCINJECTERR); + else + return -EINVAL; + return count; +} + +static const struct file_operations l2_fops = { + .owner = THIS_MODULE, + .open = simple_open, + .write = l2_write +}; + +static void setup_sifive_debug(void) +{ + sifive_test = debugfs_create_dir("sifive_l2_cache", NULL); + if (!sifive_test) + return; + + if (!debugfs_create_file("sifive_debug_inject_error", 0200, +sifive_test, NULL, &l2_fops)) + debugfs_remove_recursive(sifive_test); +} +#endif + +static void l2_config_read(void) +{ + u32 regval, val; + + regval = readl(l2_base + SIFIVE_L2_CONFIG); + val = regval & 0xFF; + pr_info("L2CACHE: No. of Banks in the cache: %d\n", val); + val = (regval & 0xFF00) >> 8; + pr_info("L2CACHE: No. of ways per bank: %d\n", val); + val = (regval & 0xFF) >> 16; + pr_info("L2CACHE: Sets per bank: %llu\n", (uint64_t)1 << val); + val = (regval & 0xFF00) >> 24; + pr_info("L2CACHE: Bytes per cache block: %llu\n", (uint64_t)1 << val); + + regval = readl(l2_base + SIFIVE_L2_WAYENABLE); + pr_info("L2CACHE: Index of the largest way enabled: %d\n", regval); +} + +static const struct of_device_id sifive_l2_ids[] = { + { .compatible = "sifive,fu540-c000-ccache" }, + { /* end of table */ }, +}; + +static ATOMIC_NOTIFIER_HEAD(l2_err_chain); + +int register_sifive_l2_error_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_register(&am
[PATCH 1/2] RISC-V: Add DT documentation for SiFive L2 Cache Controller
Add device tree bindings for SiFive FU540 L2 cache controller driver Signed-off-by: Yash Shah --- .../devicetree/bindings/riscv/sifive-l2-cache.txt | 53 ++ 1 file changed, 53 insertions(+) create mode 100644 Documentation/devicetree/bindings/riscv/sifive-l2-cache.txt diff --git a/Documentation/devicetree/bindings/riscv/sifive-l2-cache.txt b/Documentation/devicetree/bindings/riscv/sifive-l2-cache.txt new file mode 100644 index 000..15132e2 --- /dev/null +++ b/Documentation/devicetree/bindings/riscv/sifive-l2-cache.txt @@ -0,0 +1,53 @@ +SiFive L2 Cache Controller +-- +The SiFive Level 2 Cache Controller is used to provide access to fast copies +of memory for masters in a Core Complex. The Level 2 Cache Controller also +acts as directory-based coherency manager. + +Required Properties: + +- compatible: Should be "sifive,fu540-c000-ccache" + +- cache-block-size: Specifies the block size in bytes of the cache + +- cache-level: Should be set to 2 for a level 2 cache + +- cache-sets: Specifies the number of associativity sets of the cache + +- cache-size: Specifies the size in bytes of the cache + +- cache-unified: Specifies the cache is a unified cache + +- interrupt-parent: Must be core interrupt controller + +- interrupts: Must contain 3 entries (DirError, DataError and DataFail signals) + +- reg: Physical base address and size of L2 cache controller registers map + +- reg-names: Should be "control" + +Optional Properties: + +- next-level-cache: phandle to the next level cache if present. + +- memory-region: reference to the reserved-memory for the L2 Loosely Integrated + Memory region. The reserved memory node should be defined as per the bindings + in reserved-memory.txt + + +Example: + + cache-controller@201 { + compatible = "sifive,fu540-c000-ccache"; + cache-block-size = <0x40>; + cache-level = <0x2>; + cache-sets = <0x400>; + cache-size = <0x10>; + cache-unified; + interrupt-parent = <&plic0>; + interrupts = <1 2 3>; + reg = <0x0 0x201 0x0 0x1000>; + reg-names = "control"; + next-level-cache = <&L25 &L40 &L36>; + memory-region = <&l2_lim>; + }; -- 1.9.1
Re: [PATCH 2/2] RISC-V: sifive_l2_cache: Add L2 cache controller driver for SiFive SoCs
On Thu, Apr 25, 2019 at 3:48 PM Sudeep Holla wrote: > > On Thu, Apr 25, 2019 at 11:24:56AM +0530, Yash Shah wrote: > > The driver currently supports only SiFive FU540-C000 platform. > > > > The initial version of L2 cache controller driver includes: > > - Initial configuration reporting at boot up. > > - Support for ECC related functionality. > > > > Signed-off-by: Yash Shah > > [] > > > +static const struct file_operations l2_fops = { > > + .owner = THIS_MODULE, > > + .open = simple_open, > > + .write = l2_write > > +}; > > + > > +static void setup_sifive_debug(void) > > +{ > > + sifive_test = debugfs_create_dir("sifive_l2_cache", NULL); > > + if (!sifive_test) > > Drop the conditional check above, Greg K H removed lots of them recently. > In his words: When calling debugfs functions, there is no need to ever > check the return value. The function can work or not, but the code > logic should never do something different based on this. > > He may not like to see this :) Sure, thanks for pointing it out. Will drop all the conditional check in debugfs functions. > > > + return; > > + > > + if (!debugfs_create_file("sifive_debug_inject_error", 0200, > > + sifive_test, NULL, &l2_fops)) > > Ditto. > > > + debugfs_remove_recursive(sifive_test); > > +} > > -- > Regards, > Sudeep Thanks for your comments. - Yash
Re: [PATCH 1/2] RISC-V: Add DT documentation for SiFive L2 Cache Controller
On Thu, Apr 25, 2019 at 3:43 PM Sudeep Holla wrote: > > On Thu, Apr 25, 2019 at 11:24:55AM +0530, Yash Shah wrote: > > Add device tree bindings for SiFive FU540 L2 cache controller driver > > > > Signed-off-by: Yash Shah > > --- > > .../devicetree/bindings/riscv/sifive-l2-cache.txt | 53 > > ++ > > 1 file changed, 53 insertions(+) > > create mode 100644 > > Documentation/devicetree/bindings/riscv/sifive-l2-cache.txt > > > > diff --git a/Documentation/devicetree/bindings/riscv/sifive-l2-cache.txt > > b/Documentation/devicetree/bindings/riscv/sifive-l2-cache.txt > > new file mode 100644 > > index 000..15132e2 > > --- /dev/null > > +++ b/Documentation/devicetree/bindings/riscv/sifive-l2-cache.txt > > @@ -0,0 +1,53 @@ > > +SiFive L2 Cache Controller > > +-- > > +The SiFive Level 2 Cache Controller is used to provide access to fast > > copies > > +of memory for masters in a Core Complex. The Level 2 Cache Controller also > > +acts as directory-based coherency manager. > > + > > +Required Properties: > > + > > +- compatible: Should be "sifive,fu540-c000-ccache" > > + > > +- cache-block-size: Specifies the block size in bytes of the cache > > + > > +- cache-level: Should be set to 2 for a level 2 cache > > + > > +- cache-sets: Specifies the number of associativity sets of the cache > > + > > +- cache-size: Specifies the size in bytes of the cache > > + > > +- cache-unified: Specifies the cache is a unified cache > > + > > +- interrupt-parent: Must be core interrupt controller > > + > > +- interrupts: Must contain 3 entries (DirError, DataError and DataFail > > signals) > > + > > +- reg: Physical base address and size of L2 cache controller registers map > > + > > +- reg-names: Should be "control" > > + > > It would be good if you mark the properties that are present in DT > specification and those that are added for sifive,fu540-c000-ccache I believe there isn't any property which is added explicitly for sifive,fu540-c000-ccache. > explicitly. Also I assume you can retain the stardard "cache" compatible > in addition to above. I am interested to see if the cacheinfo infrastructure > can be used without any issues. Yes, I will add the "cache" string to the compatible property. > > -- > Regards, > Sudeep Thanks for your comments. - Yash
[PATCH 0/2] L2 Cache EDAC Support for HiFive Unleashed
This patch series adds a L2 Cache EDAC driver and DT documentation for HiFive Unleashed board. Yash Shah (2): edac: sifive: Add DT documentation for SiFive L2 cache Controller sifive: edac: Add EDAC driver for Sifive l2 Cache Controller .../devicetree/bindings/edac/sifive-edac-l2.txt| 31 +++ arch/riscv/Kconfig | 1 + drivers/edac/Kconfig | 7 + drivers/edac/Makefile | 1 + drivers/edac/sifive_edac-l2.c | 292 + 5 files changed, 332 insertions(+) create mode 100644 Documentation/devicetree/bindings/edac/sifive-edac-l2.txt create mode 100644 drivers/edac/sifive_edac-l2.c -- 1.9.1
[PATCH 2/2] sifive: edac: Add EDAC driver for Sifive l2 Cache Controller
Add driver for the SiFive L2 cache controller on the HiFive Unleashed board Signed-off-by: Yash Shah --- arch/riscv/Kconfig| 1 + drivers/edac/Kconfig | 7 + drivers/edac/Makefile | 1 + drivers/edac/sifive_edac-l2.c | 292 ++ 4 files changed, 301 insertions(+) create mode 100644 drivers/edac/sifive_edac-l2.c diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 515fc3c..fede4b6 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -49,6 +49,7 @@ config RISCV select RISCV_TIMER select GENERIC_IRQ_MULTI_HANDLER select ARCH_HAS_PTE_SPECIAL + select EDAC_SUPPORT config MMU def_bool y diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig index e286b5b..63ccdf1 100644 --- a/drivers/edac/Kconfig +++ b/drivers/edac/Kconfig @@ -440,6 +440,13 @@ config EDAC_ALTERA_SDMMC Support for error detection and correction on the Altera SDMMC FIFO Memory for Altera SoCs. +config EDAC_SIFIVE_L2 + tristate "Sifive L2 Cache" + depends on RISCV + help + Support for error detection and correction on the SiFive L2 + cache controller. + config EDAC_SYNOPSYS tristate "Synopsys DDR Memory Controller" depends on ARCH_ZYNQ || ARCH_ZYNQMP diff --git a/drivers/edac/Makefile b/drivers/edac/Makefile index 716096d..ad9e3d3 100644 --- a/drivers/edac/Makefile +++ b/drivers/edac/Makefile @@ -74,6 +74,7 @@ obj-$(CONFIG_EDAC_OCTEON_PCI) += octeon_edac-pci.o obj-$(CONFIG_EDAC_THUNDERX)+= thunderx_edac.o obj-$(CONFIG_EDAC_ALTERA) += altera_edac.o +obj-$(CONFIG_EDAC_SIFIVE_L2) += sifive_edac-l2.o obj-$(CONFIG_EDAC_SYNOPSYS)+= synopsys_edac.o obj-$(CONFIG_EDAC_XGENE) += xgene_edac.o obj-$(CONFIG_EDAC_TI) += ti_edac.o diff --git a/drivers/edac/sifive_edac-l2.c b/drivers/edac/sifive_edac-l2.c new file mode 100644 index 000..124f43a --- /dev/null +++ b/drivers/edac/sifive_edac-l2.c @@ -0,0 +1,292 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * SiFive L2 Cache EDAC Driver + * + * Copyright (C) 2018-2019 SiFive, Inc. + * + */ +#include +#include +#include +#include +#include +#include "edac_module.h" + +#define SIFIVE_EDAC_DIRFIX_LOW 0x100 +#define SIFIVE_EDAC_DIRFIX_HIGH 0x104 +#define SIFIVE_EDAC_DIRFIX_COUNT 0x108 + +#define SIFIVE_EDAC_DIRFAIL_LOW 0x120 +#define SIFIVE_EDAC_DIRFAIL_HIGH 0x124 +#define SIFIVE_EDAC_DIRFAIL_COUNT 0x128 + +#define SIFIVE_EDAC_DATFIX_LOW 0x140 +#define SIFIVE_EDAC_DATFIX_HIGH 0x144 +#define SIFIVE_EDAC_DATFIX_COUNT 0x148 + +#define SIFIVE_EDAC_DATFAIL_LOW 0x160 +#define SIFIVE_EDAC_DATFAIL_HIGH 0x164 +#define SIFIVE_EDAC_DATFAIL_COUNT 0x168 + +#define SIFIVE_EDAC_ECCINJECTERR 0x40 +#define SIFIVE_EDAC_CONFIG 0x00 + +#define SIFIVE_EDAC_MAX_INTR 4 + +/** + * struct sifive_edac_l2_priv - L2 cache controller private instance data + * @base: Base address of the controller + * @irq[]: Array of interrupt numbers + */ +struct sifive_edac_l2_priv { + void __iomem *base; + int irq[SIFIVE_EDAC_MAX_INTR]; +}; + +enum { + dir_corr = 0, + dir_uncorr, + data_corr, + data_uncorr, +}; + +static struct dentry *sifive_edac_test; + +static ssize_t sifive_edac_l2_write(struct file *file, const char __user *data, + size_t count, loff_t *ppos) +{ + struct edac_device_ctl_info *dci = file->private_data; + struct sifive_edac_l2_priv *priv = dci->pvt_info; + unsigned int val; + + if (kstrtouint_from_user(data, count, 0, &val)) + return -EINVAL; + if ((val >= 0 && val < 0xFF) || (val >= 0x1 && val < 0x100FF)) + writel(val, priv->base + SIFIVE_EDAC_ECCINJECTERR); + else + return -EINVAL; + return count; +} + +static const struct file_operations sifive_edac_l2_fops = { + .owner = THIS_MODULE, + .open = simple_open, + .write = sifive_edac_l2_write +}; + +static void setup_sifive_debug(struct edac_device_ctl_info *edac_dev) +{ + sifive_edac_test = edac_debugfs_create_dir("sifive_edac_test"); + edac_debugfs_create_file("sifive_debug_inject_error", 0200, +sifive_edac_test, edac_dev, +&sifive_edac_l2_fops); +} + +static void teardown_sifive_debug(void) +{ + debugfs_remove_recursive(sifive_edac_test); +} + +/** + * sifive_edac_l2_int_handler - ISR function for l2 cache controller + * @irq: Irq Number + * @device:Pointer to the edac device controller instance + * + * This routine is triggered whenever there is ECC error detected + * + * Return: Always returns IRQ_HANDLED + */ +static irqreturn_t sifive_edac_l2_int_handler(int irq, void *device) +{ + struct e
[PATCH 1/2] edac: sifive: Add DT documentation for SiFive L2 cache Controller
DT documentation for L2 cache controller added. Signed-off-by: Yash Shah --- .../devicetree/bindings/edac/sifive-edac-l2.txt| 31 ++ 1 file changed, 31 insertions(+) create mode 100644 Documentation/devicetree/bindings/edac/sifive-edac-l2.txt diff --git a/Documentation/devicetree/bindings/edac/sifive-edac-l2.txt b/Documentation/devicetree/bindings/edac/sifive-edac-l2.txt new file mode 100644 index 000..abce09f --- /dev/null +++ b/Documentation/devicetree/bindings/edac/sifive-edac-l2.txt @@ -0,0 +1,31 @@ +SiFive L2 Cache EDAC driver device tree bindings +- +This driver uses the EDAC framework to report L2 cache controller ECC errors. + +- compatible: Should be "sifive,-ccache" and "sifive,ccache". + Supported compatible strings are: + "sifive,fu540-c000-ccache" for the SiFive cache controller v0 as integrated + onto the SiFive FU540 chip, and "sifive,ccache0" for the SiFive + cache controller v0 IP block with no chip integration tweaks. + Please refer to sifive-blocks-ip-versioning.txt for details + +- interrupts: Must contain 3 entries for FU540 (DirError, DataError, and + DataFail signals) or 4 entries for other chips (DirError, DirFail, DataError, + and DataFail signals) + +- interrupt-parent: Must be core interrupt controller + +- reg: Physical base address and size of L2 cache controller registers map + A second range can indicate L2 Loosely Integrated Memory + +- reg-names: Names for the cells of reg, must contain "control" and "sideband" + +Example: + +cache-controller@201 { + compatible = "sifive,fu540-c000-ccache", "sifive,ccache0"; + interrupt-parent = <&plic>; + interrupts = <1 2 3>; + reg = <0x0 0x201 0x0 0x1000 0x0 0x800 0x0 0x200>; + reg-names = "control", "sideband"; +}; -- 1.9.1
Re: [PATCH v9 0/2] PWM support for HiFive Unleashed
On Tue, Mar 12, 2019 at 3:44 PM Andreas Schwab wrote: > > On Mär 12 2019, Yash Shah wrote: > > > This patch series adds a PWM driver and DT documentation > > for HiFive Unleashed board. The patches are mostly based on > > Wesley's patch. > > Heartbeat trigger still doesn't work for me. You need to make sure the period setting is passed via the conventional way in DT file. Example: pwmleds { compatible = "pwm-leds"; heartbeat { pwms = <&L45 0 1000 0>; max-brightness = <255>; linux,default-trigger = "heartbeat"; }; }; I have tested on HiFive unleashed board. To modify DT file I performed the following steps: Use the open-source FSBL from: https://github.com/sifive/freedom-u540-c000-bootloader Modify the fsbl/ux00_fsbl.dts file and re-build the fsbl.bin Steps for using fsbl.bin in HiFive Unleashed board: https://github.com/sifive/freedom-u540-c000-bootloader/issues/9 > > Andreas. > > -- > Andreas Schwab, SUSE Labs, sch...@suse.de > GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE 1748 E4D4 88E3 0EEA B9D7 > "And now for something completely different."
Re: [PATCH v5 1/2] pwm: sifive: Add DT documentation for SiFive PWM Controller
On Wed, Jan 30, 2019 at 1:44 PM Uwe Kleine-König wrote: > > On Tue, Jan 29, 2019 at 05:13:18PM +0530, Yash Shah wrote: > > DT documentation for PWM controller added. > > > > Signed-off-by: Wesley W. Terpstra > > [Atish: Compatible string update] > > Signed-off-by: Atish Patra > > Signed-off-by: Yash Shah > > --- > > .../devicetree/bindings/pwm/pwm-sifive.txt | 33 > > ++ > > 1 file changed, 33 insertions(+) > > create mode 100644 Documentation/devicetree/bindings/pwm/pwm-sifive.txt > > > > diff --git a/Documentation/devicetree/bindings/pwm/pwm-sifive.txt > > b/Documentation/devicetree/bindings/pwm/pwm-sifive.txt > > new file mode 100644 > > index 000..8dcb40d > > --- /dev/null > > +++ b/Documentation/devicetree/bindings/pwm/pwm-sifive.txt > > @@ -0,0 +1,33 @@ > > +SiFive PWM controller > > + > > +Unlike most other PWM controllers, the SiFive PWM controller currently only > > +supports one period for all channels in the PWM. This is set globally in > > DTS. > > You can simply drop this if the first user can set this using the usual > interface. Don't you like this suggestion that I already made a few > times now? > > Did you consider to make the driver support only a single output with a > more flexible period setting? We cannot consider supporting only single output since we have boards that use the additional PWM channels to control individual LED brightness of a tri-color LED. If we go down to one channel, then we can't control the brightness of the individual LEDs. It will break the use case. I am considering the below approach, let me know if it's fine by you. - Drop the global period property and allow the only first user to change period using the usual interface. - A note in the binding that all PWMs need to run at the same period. If the driver already refuses to apply incompatible periods, the users are going to notice that they've got the DT wrong. - In driver code, count the users using the .request and .free callbacks. Based on this, allow changes to period iff the user count is one. > > > +The period also has significant restrictions on the values it can achieve, > > +which the driver rounds to the nearest achievable frequency. > > Rounding a period to a frequency sounds wrong. > > Best regards > Uwe > > -- > Pengutronix e.K. | Uwe Kleine-König| > Industrial Linux Solutions | http://www.pengutronix.de/ |
Re: [PATCH v5 2/2] pwm: sifive: Add a driver for SiFive SoC PWM
On Wed, Feb 6, 2019 at 6:14 PM Thierry Reding wrote: > > On Tue, Jan 29, 2019 at 05:13:19PM +0530, Yash Shah wrote: > [...] > > diff --git a/drivers/pwm/pwm-sifive.c b/drivers/pwm/pwm-sifive.c > [...] > > +static void pwm_sifive_update_clock(struct pwm_sifive_ddata *pwm, > > + unsigned long rate) > > +{ > > + /* (1 << (16+scale)) * 10^9/rate = real_period */ > > + unsigned long scale_pow = > > + (pwm->approx_period * (u64)rate) / NSEC_PER_SEC; > > I think you need another div64_ul() for this one to fix the linker error > that the 0-day builder was pointing out. Yes, will fix this. Thanks for pointing it out. > > Thierry
Re: [PATCH v11 0/2] PWM support for HiFive Unleashed
'On Mon, Mar 25, 2019 at 9:24 PM Andreas Schwab wrote: > > > I still don't see any improvement. FYI, this is the patch I use for the > device tree: > I am sharing you my test environment which has been working for me so that you can duplicate at your end I have tested the patch on Linux v5.0-rc1 commit id: bfeffd155283772bbe78c6a05dec7c0128ee500c with additional board related patches which can be found at dev/yashs/pwm_5.0-rc1 branch of: https://github.com/yashshah7/riscv-linux.git I have compiled the dt file (found at above repo) and replaced the compiled dtb file with 'fsbl/ux00_fsbl.dtb' and re-build fsbl.bin. Make sure your dt file changes are getting reflected on target under '/proc/device-tree/' Below is the .config file content: # # Automatically generated file; DO NOT EDIT. # Linux/riscv 5.0.0-rc1 Kernel Configuration # # # Compiler: riscv64-unknown-elf-gcc (GCC) 7.2.0 # CONFIG_CC_IS_GCC=y CONFIG_GCC_VERSION=70200 CONFIG_CLANG_VERSION=0 CONFIG_CC_HAS_ASM_GOTO=y CONFIG_IRQ_WORK=y CONFIG_THREAD_INFO_IN_TASK=y # # General setup # CONFIG_INIT_ENV_ARG_LIMIT=32 CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y CONFIG_BUILD_SALT="" CONFIG_DEFAULT_HOSTNAME="(none)" CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y CONFIG_POSIX_MQUEUE_SYSCTL=y CONFIG_CROSS_MEMORY_ATTACH=y # # IRQ subsystem # CONFIG_GENERIC_IRQ_SHOW=y CONFIG_IRQ_DOMAIN=y CONFIG_GENERIC_MSI_IRQ=y CONFIG_SPARSE_IRQ=y CONFIG_GENERIC_IRQ_MULTI_HANDLER=y CONFIG_GENERIC_CLOCKEVENTS=y # # Timers subsystem # CONFIG_HZ_PERIODIC=y CONFIG_PREEMPT_NONE=y # # CPU/Task time and stats accounting # CONFIG_TICK_CPU_ACCOUNTING=y CONFIG_CPU_ISOLATION=y # # RCU Subsystem # CONFIG_TREE_RCU=y CONFIG_SRCU=y CONFIG_TREE_SRCU=y CONFIG_RCU_STALL_COMMON=y CONFIG_RCU_NEED_SEGCBLIST=y CONFIG_BUILD_BIN2C=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=17 CONFIG_LOG_CPU_MAX_BUF_SHIFT=12 CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=13 CONFIG_GENERIC_SCHED_CLOCK=y CONFIG_ARCH_SUPPORTS_INT128=y CONFIG_CGROUPS=y CONFIG_CGROUP_SCHED=y CONFIG_FAIR_GROUP_SCHED=y CONFIG_CFS_BANDWIDTH=y CONFIG_CGROUP_BPF=y CONFIG_SOCK_CGROUP_DATA=y CONFIG_NAMESPACES=y CONFIG_UTS_NS=y CONFIG_IPC_NS=y CONFIG_USER_NS=y CONFIG_PID_NS=y CONFIG_NET_NS=y CONFIG_CHECKPOINT_RESTORE=y CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" CONFIG_RD_GZIP=y CONFIG_RD_BZIP2=y CONFIG_RD_LZMA=y CONFIG_RD_XZ=y CONFIG_RD_LZO=y CONFIG_RD_LZ4=y CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y CONFIG_SYSCTL=y CONFIG_ANON_INODES=y CONFIG_SYSCTL_EXCEPTION_TRACE=y CONFIG_BPF=y CONFIG_EXPERT=y CONFIG_MULTIUSER=y CONFIG_SYSFS_SYSCALL=y CONFIG_FHANDLE=y CONFIG_POSIX_TIMERS=y CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_FUTEX_PI=y CONFIG_HAVE_FUTEX_CMPXCHG=y CONFIG_EPOLL=y CONFIG_SIGNALFD=y CONFIG_TIMERFD=y CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_AIO=y CONFIG_ADVISE_SYSCALLS=y CONFIG_MEMBARRIER=y CONFIG_KALLSYMS=y CONFIG_KALLSYMS_BASE_RELATIVE=y CONFIG_BPF_SYSCALL=y CONFIG_HAVE_PERF_EVENTS=y # # Kernel Performance Events And Counters # CONFIG_VM_EVENT_COUNTERS=y CONFIG_SLUB_DEBUG=y CONFIG_COMPAT_BRK=y CONFIG_SLUB=y CONFIG_SLAB_MERGE_DEFAULT=y CONFIG_SLUB_CPU_PARTIAL=y CONFIG_64BIT=y CONFIG_RISCV=y CONFIG_MMU=y CONFIG_ZONE_DMA32=y CONFIG_PAGE_OFFSET=0xffe0 CONFIG_STACKTRACE_SUPPORT=y CONFIG_TRACE_IRQFLAGS_SUPPORT=y CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_BUG=y CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_GENERIC_CSUM=y CONFIG_GENERIC_HWEIGHT=y CONFIG_PGTABLE_LEVELS=3 # # Platform type # CONFIG_ARCH_RV64I=y CONFIG_CMODEL_MEDANY=y CONFIG_MODULE_SECTIONS=y CONFIG_MAXPHYSMEM_128GB=y CONFIG_SMP=y CONFIG_NR_CPUS=8 CONFIG_TUNE_GENERIC=y CONFIG_RISCV_ISA_C=y CONFIG_RISCV_ISA_A=y CONFIG_FPU=y # # Kernel features # CONFIG_HZ_250=y CONFIG_HZ=250 # # Boot options # CONFIG_CMDLINE="console=ttySIF0,115200 ignore_loglevel debug" CONFIG_CMDLINE_FALLBACK=y # # General architecture-dependent options # CONFIG_HAVE_64BIT_ALIGNED_ACCESS=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_CONTIGUOUS=y CONFIG_GENERIC_SMP_IDLE_THREAD=y CONFIG_HAVE_CLK=y CONFIG_CC_HAS_STACKPROTECTOR_NONE=y CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y CONFIG_HAVE_MOD_ARCH_SPECIFIC=y CONFIG_MODULES_USE_ELF_RELA=y CONFIG_CLONE_BACKWARDS=y # # GCOV-based kernel profiling # CONFIG_PLUGIN_HOSTCC="g++" CONFIG_RT_MUTEXES=y CONFIG_BASE_SMALL=0 CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_BLOCK=y CONFIG_BLK_SCSI_REQUEST=y CONFIG_BLK_DEV_BSG=y # # Partition Types # CONFIG_MSDOS_PARTITION=y CONFIG_EFI_PARTITION=y CONFIG_BLK_MQ_PCI=y CONFIG_BLK_MQ_VIRTIO=y # # IO Schedulers # CONFIG_MQ_IOSCHED_DEADLINE=y CONFIG_MQ_IOSCHED_KYBER=y CONFIG_INLINE_SPIN_UNLOCK_IRQ=y CONFIG_INLINE_READ_UNLOCK=y CONFIG_INLINE_READ_UNLOCK_IRQ=y CONFIG_INLINE_WRITE_UNLOCK=y CONFIG_INLINE_WRITE_UNLOCK_IRQ=y # # Executable file formats # CONFIG_BINFMT_ELF=y CONFIG_ELFCORE=y CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y CONFIG_BINFMT_SCRIPT=y CONFIG_COREDUMP=y # # Memory Management options # C
Re: [PATCH v7 2/2] pwm: sifive: Add a driver for SiFive SoC PWM
On Fri, Feb 22, 2019 at 2:46 AM Uwe Kleine-König wrote: > > On Thu, Feb 21, 2019 at 02:41:41PM +0530, Yash Shah wrote: > > Adds a PWM driver for PWM chip present in SiFive's HiFive Unleashed SoC. > > > > Signed-off-by: Wesley W. Terpstra > > [Atish: Various fixes and code cleanup] > > Signed-off-by: Atish Patra > > Signed-off-by: Yash Shah > > --- > > drivers/pwm/Kconfig | 11 ++ > > drivers/pwm/Makefile | 1 + > > drivers/pwm/pwm-sifive.c | 346 > > +++ > > 3 files changed, 358 insertions(+) > > create mode 100644 drivers/pwm/pwm-sifive.c > > > > diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig > > index a8f47df..4a61d1a 100644 > > --- a/drivers/pwm/Kconfig > > +++ b/drivers/pwm/Kconfig > > @@ -380,6 +380,17 @@ config PWM_SAMSUNG > > To compile this driver as a module, choose M here: the module > > will be called pwm-samsung. > > > > +config PWM_SIFIVE > > + tristate "SiFive PWM support" > > + depends on OF > > + depends on COMMON_CLK > > + depends on RISCV || COMPILE_TEST > > + help > > + Generic PWM framework driver for SiFive SoCs. > > + > > + To compile this driver as a module, choose M here: the module > > + will be called pwm-sifive. > > + > > config PWM_SPEAR > > tristate "STMicroelectronics SPEAr PWM support" > > depends on PLAT_SPEAR > > diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile > > index 9c676a0..30089ca 100644 > > --- a/drivers/pwm/Makefile > > +++ b/drivers/pwm/Makefile > > @@ -37,6 +37,7 @@ obj-$(CONFIG_PWM_RCAR) += pwm-rcar.o > > obj-$(CONFIG_PWM_RENESAS_TPU)+= pwm-renesas-tpu.o > > obj-$(CONFIG_PWM_ROCKCHIP) += pwm-rockchip.o > > obj-$(CONFIG_PWM_SAMSUNG)+= pwm-samsung.o > > +obj-$(CONFIG_PWM_SIFIVE) += pwm-sifive.o > > obj-$(CONFIG_PWM_SPEAR) += pwm-spear.o > > obj-$(CONFIG_PWM_STI)+= pwm-sti.o > > obj-$(CONFIG_PWM_STM32) += pwm-stm32.o > > diff --git a/drivers/pwm/pwm-sifive.c b/drivers/pwm/pwm-sifive.c > > new file mode 100644 > > index 000..8f29283d > > --- /dev/null > > +++ b/drivers/pwm/pwm-sifive.c > > @@ -0,0 +1,346 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > +/* > > + * Copyright (C) 2017-2018 SiFive > > + * For SiFive's PWM IP block documentation please refer Chapter 14 of > > + * Reference Manual : https://static.dev.sifive.com/FU540-C000-v1.0.pdf > > + * > > + * Limitations: > > + * - When changing both duty cycle and period, we cannot prevent in > > + * software that the output might produce a period with mixed > > + * settings (new period length and old duty cycle). > > + * - The hardware cannot generate a 100% duty cycle. > > + * - The hardware generaets only inverted output. > > s/generaets/generates/ Will fix the typo. > > > + */ > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > + > > +/* Register offsets */ > > +#define PWM_SIFIVE_PWMCFG0x0 > > +#define PWM_SIFIVE_PWMCOUNT 0x8 > > +#define PWM_SIFIVE_PWMS 0x10 > > +#define PWM_SIFIVE_PWMCMP0 0x20 > > + > > +/* PWMCFG fields */ > > +#define PWM_SIFIVE_PWMCFG_SCALE 0 > > +#define PWM_SIFIVE_PWMCFG_STICKY 8 > > +#define PWM_SIFIVE_PWMCFG_ZERO_CMP 9 > > +#define PWM_SIFIVE_PWMCFG_DEGLITCH 10 > > +#define PWM_SIFIVE_PWMCFG_EN_ALWAYS BIT(12) > > +#define PWM_SIFIVE_PWMCFG_EN_ONCE13 > > +#define PWM_SIFIVE_PWMCFG_CENTER 16 > > +#define PWM_SIFIVE_PWMCFG_GANG 24 > > +#define PWM_SIFIVE_PWMCFG_IP 28 > > + > > +/* PWM_SIFIVE_SIZE_PWMCMP is used to calculate offset for pwmcmpX > > registers */ > > +#define PWM_SIFIVE_SIZE_PWMCMP 4 > > +#define PWM_SIFIVE_CMPWIDTH 16 > > + > > +struct pwm_sifive_ddata { > > + struct pwm_chip chip; > > + struct mutex lock; /* lock to protect user_count and active_user */ > > + struct notifier_block notifier; > > + struct clk *clk; > > + void __iomem *regs; > > + unsigned int real_period; > > + int user_count; > > + int active_user; > > +}; > > + > > +static inline > > +struct pwm_sifive_ddata *pwm_sifive_chip_to_ddata(struct pwm_chip *c) > > +{ > > + return con
[PATCH v2 2/9] dt-bindings: spi: Update DT binding docs to support SiFive FU740 SoC
Add new compatible strings to the DT binding documents to support SiFive FU740-C000. Signed-off-by: Yash Shah --- Documentation/devicetree/bindings/spi/spi-sifive.yaml | 10 ++ 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/spi/spi-sifive.yaml b/Documentation/devicetree/bindings/spi/spi-sifive.yaml index 56dcf1d..6e7e394 100644 --- a/Documentation/devicetree/bindings/spi/spi-sifive.yaml +++ b/Documentation/devicetree/bindings/spi/spi-sifive.yaml @@ -17,15 +17,17 @@ allOf: properties: compatible: items: - - const: sifive,fu540-c000-spi + - enum: + - sifive,fu540-c000-spi + - sifive,fu740-c000-spi - const: sifive,spi0 description: Should be "sifive,-spi" and "sifive,spi". Supported compatible strings are - - "sifive,fu540-c000-spi" for the SiFive SPI v0 as integrated - onto the SiFive FU540 chip, and "sifive,spi0" for the SiFive - SPI v0 IP block with no chip integration tweaks. + "sifive,fu540-c000-spi" and "sifive,fu740-c000-spi" for the SiFive SPI v0 + as integrated onto the SiFive FU540 and FU740 chip resp, and "sifive,spi0" + for the SiFive SPI v0 IP block with no chip integration tweaks. Please refer to sifive-blocks-ip-versioning.txt for details SPI RTL that corresponds to the IP block version numbers can be found here - -- 2.7.4
[PATCH v2 4/9] dt-bindings: serial: Update DT binding docs to support SiFive FU740 SoC
Add new compatible strings to the DT binding documents to support SiFive FU740-C000. Signed-off-by: Yash Shah --- Documentation/devicetree/bindings/serial/sifive-serial.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/serial/sifive-serial.yaml b/Documentation/devicetree/bindings/serial/sifive-serial.yaml index 92283f6..3ac5c7f 100644 --- a/Documentation/devicetree/bindings/serial/sifive-serial.yaml +++ b/Documentation/devicetree/bindings/serial/sifive-serial.yaml @@ -17,7 +17,9 @@ allOf: properties: compatible: items: - - const: sifive,fu540-c000-uart + - enum: + - sifive,fu540-c000-uart + - sifive,fu740-c000-uart - const: sifive,uart0 description: -- 2.7.4
[PATCH v2 3/9] dt-bindings: pwm: Update DT binding docs to support SiFive FU740 SoC
Add new compatible strings to the DT binding documents to support SiFive FU740-C000. Signed-off-by: Yash Shah --- Documentation/devicetree/bindings/pwm/pwm-sifive.yaml | 9 ++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/pwm/pwm-sifive.yaml b/Documentation/devicetree/bindings/pwm/pwm-sifive.yaml index 5ac2527..84e6691 100644 --- a/Documentation/devicetree/bindings/pwm/pwm-sifive.yaml +++ b/Documentation/devicetree/bindings/pwm/pwm-sifive.yaml @@ -25,12 +25,15 @@ description: properties: compatible: items: - - const: sifive,fu540-c000-pwm + - enum: + - sifive,fu540-c000-pwm + - sifive,fu740-c000-pwm - const: sifive,pwm0 description: Should be "sifive,-pwm" and "sifive,pwm". Supported - compatible strings are "sifive,fu540-c000-pwm" for the SiFive PWM v0 - as integrated onto the SiFive FU540 chip, and "sifive,pwm0" for the + compatible strings are "sifive,fu540-c000-pwm" and + "sifive,fu740-c000-pwm" for the SiFive PWM v0 as integrated onto the + SiFive FU540 and FU740 chip respectively, and "sifive,pwm0" for the SiFive PWM v0 IP block with no chip integration tweaks. Please refer to sifive-blocks-ip-versioning.txt for details. -- 2.7.4
[PATCH v2 6/9] dt-bindings: i2c: Update DT binding docs to support SiFive FU740 SoC
Add new compatible strings to the DT binding documents to support SiFive FU740-C000. Signed-off-by: Yash Shah --- Documentation/devicetree/bindings/i2c/i2c-ocores.txt | 8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/i2c/i2c-ocores.txt b/Documentation/devicetree/bindings/i2c/i2c-ocores.txt index 6b25a80..a37c945 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-ocores.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-ocores.txt @@ -5,8 +5,12 @@ Required properties: "aeroflexgaisler,i2cmst" "sifive,fu540-c000-i2c", "sifive,i2c0" For Opencore based I2C IP block reimplemented in -FU540-C000 SoC. Please refer to sifive-blocks-ip-versioning.txt -for additional details. +FU540-C000 SoC. +"sifive,fu740-c000-i2c", "sifive,i2c0" +For Opencore based I2C IP block reimplemented in +FU740-C000 SoC. +Please refer to sifive-blocks-ip-versioning.txt for +additional details. - reg : bus address start and address range size of device - clocks : handle to the controller clock; see the note below. Mutually exclusive with opencores,ip-clock-frequency -- 2.7.4
[PATCH v2 0/9] arch: riscv: add board and SoC DT file support
Start board support by adding initial support for the SiFive FU740 SoC and the first development board that uses it, the SiFive HiFive Unmatched A00. Boot-tested on Linux 5.10-rc4 on a HiFive Unmatched A00 board using the U-boot and OpenSBI. This patch series is dependent on Zong's Patchset[0]. The patchset also adds two new nodes in dtsi file. The binding documentation patch for these nodes are already posted on the mailing list[1][2]. [0]: https://lore.kernel.org/linux-riscv/20201130082330.77268-4-zong...@sifive.com/T/#u [1]: https://lore.kernel.org/linux-riscv/1606714984-16593-1-git-send-email-yash.s...@sifive.com/T/#t [2]: https://lore.kernel.org/linux-riscv/20201126030043.67390-1-zong...@sifive.com/T/#u Changes in v2: - The dt bindings patch is split into several individual patches. - Expand the full list for compatible strings in i2c-ocores.txt Yash Shah (9): dt-bindings: riscv: Update DT binding docs to support SiFive FU740 SoC dt-bindings: spi: Update DT binding docs to support SiFive FU740 SoC dt-bindings: pwm: Update DT binding docs to support SiFive FU740 SoC dt-bindings: serial: Update DT binding docs to support SiFive FU740 SoC dt-bindings: gpio: Update DT binding docs to support SiFive FU740 SoC dt-bindings: i2c: Update DT binding docs to support SiFive FU740 SoC riscv: dts: add initial support for the SiFive FU740-C000 SoC dt-bindings: riscv: Update YAML doc to support SiFive HiFive Unmatched board riscv: dts: add initial board data for the SiFive HiFive Unmatched .../devicetree/bindings/gpio/sifive,gpio.yaml | 4 +- .../devicetree/bindings/i2c/i2c-ocores.txt | 8 +- .../devicetree/bindings/pwm/pwm-sifive.yaml| 9 +- Documentation/devicetree/bindings/riscv/cpus.yaml | 6 + .../devicetree/bindings/riscv/sifive.yaml | 17 +- .../devicetree/bindings/serial/sifive-serial.yaml | 4 +- .../devicetree/bindings/spi/spi-sifive.yaml| 10 +- arch/riscv/boot/dts/sifive/Makefile| 3 +- arch/riscv/boot/dts/sifive/fu740-c000.dtsi | 293 + .../riscv/boot/dts/sifive/hifive-unmatched-a00.dts | 253 ++ 10 files changed, 590 insertions(+), 17 deletions(-) create mode 100644 arch/riscv/boot/dts/sifive/fu740-c000.dtsi create mode 100644 arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts -- 2.7.4
[PATCH v2 1/9] dt-bindings: riscv: Update DT binding docs to support SiFive FU740 SoC
Add new compatible strings in cpus.yaml to support the E71 and U74 CPU cores ("harts") that are present on FU740-C000 SoC. Signed-off-by: Yash Shah --- Documentation/devicetree/bindings/riscv/cpus.yaml | 6 ++ 1 file changed, 6 insertions(+) diff --git a/Documentation/devicetree/bindings/riscv/cpus.yaml b/Documentation/devicetree/bindings/riscv/cpus.yaml index c6925e0..eb6843f 100644 --- a/Documentation/devicetree/bindings/riscv/cpus.yaml +++ b/Documentation/devicetree/bindings/riscv/cpus.yaml @@ -28,11 +28,17 @@ properties: - items: - enum: - sifive,rocket0 + - sifive,bullet0 - sifive,e5 + - sifive,e7 - sifive,e51 + - sifive,e71 - sifive,u54-mc + - sifive,u74-mc - sifive,u54 + - sifive,u74 - sifive,u5 + - sifive,u7 - const: riscv - const: riscv# Simulator only description: -- 2.7.4
[PATCH v2 7/9] riscv: dts: add initial support for the SiFive FU740-C000 SoC
Add initial support for the SiFive FU540-C000 SoC. FU740-C000 is built around the SiFIve U7 Core Complex and a TileLink interconnect. This file is expected to grow as more device drivers are added to the kernel. Signed-off-by: Yash Shah --- arch/riscv/boot/dts/sifive/fu740-c000.dtsi | 293 + 1 file changed, 293 insertions(+) create mode 100644 arch/riscv/boot/dts/sifive/fu740-c000.dtsi diff --git a/arch/riscv/boot/dts/sifive/fu740-c000.dtsi b/arch/riscv/boot/dts/sifive/fu740-c000.dtsi new file mode 100644 index 000..eeb4f8c3 --- /dev/null +++ b/arch/riscv/boot/dts/sifive/fu740-c000.dtsi @@ -0,0 +1,293 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* Copyright (c) 2020 SiFive, Inc */ + +/dts-v1/; + +#include + +/ { + #address-cells = <2>; + #size-cells = <2>; + compatible = "sifive,fu740-c000", "sifive,fu740"; + + aliases { + serial0 = &uart0; + serial1 = &uart1; + ethernet0 = ð0; + }; + + chosen { + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + cpu0: cpu@0 { + compatible = "sifive,bullet0", "riscv"; + device_type = "cpu"; + i-cache-block-size = <64>; + i-cache-sets = <128>; + i-cache-size = <16384>; + next-level-cache = <&ccache>; + reg = <0x0>; + riscv,isa = "rv64imac"; + status = "disabled"; + cpu0_intc: interrupt-controller { + #interrupt-cells = <1>; + compatible = "riscv,cpu-intc"; + interrupt-controller; + }; + }; + cpu1: cpu@1 { + compatible = "sifive,bullet0", "riscv"; + d-cache-block-size = <64>; + d-cache-sets = <64>; + d-cache-size = <32768>; + d-tlb-sets = <1>; + d-tlb-size = <40>; + device_type = "cpu"; + i-cache-block-size = <64>; + i-cache-sets = <128>; + i-cache-size = <32768>; + i-tlb-sets = <1>; + i-tlb-size = <40>; + mmu-type = "riscv,sv39"; + next-level-cache = <&ccache>; + reg = <0x1>; + riscv,isa = "rv64imafdc"; + tlb-split; + cpu1_intc: interrupt-controller { + #interrupt-cells = <1>; + compatible = "riscv,cpu-intc"; + interrupt-controller; + }; + }; + cpu2: cpu@2 { + compatible = "sifive,bullet0", "riscv"; + d-cache-block-size = <64>; + d-cache-sets = <64>; + d-cache-size = <32768>; + d-tlb-sets = <1>; + d-tlb-size = <40>; + device_type = "cpu"; + i-cache-block-size = <64>; + i-cache-sets = <128>; + i-cache-size = <32768>; + i-tlb-sets = <1>; + i-tlb-size = <40>; + mmu-type = "riscv,sv39"; + next-level-cache = <&ccache>; + reg = <0x2>; + riscv,isa = "rv64imafdc"; + tlb-split; + cpu2_intc: interrupt-controller { + #interrupt-cells = <1>; + compatible = "riscv,cpu-intc"; + interrupt-controller; + }; + }; + cpu3: cpu@3 { + compatible = "sifive,bullet0", "riscv"; + d-cache-block-size = <64>; + d-cache-sets = <64>; + d-cache-size = <32768>; + d-tlb-sets = <1>; + d-tlb-size = <40>; + device_type = "cpu"; +
[PATCH v2 8/9] dt-bindings: riscv: Update YAML doc to support SiFive HiFive Unmatched board
Add new compatible strings to the YAML DT binding document to support SiFive's HiFive Unmatched board Signed-off-by: Yash Shah --- Documentation/devicetree/bindings/riscv/sifive.yaml | 17 - 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/Documentation/devicetree/bindings/riscv/sifive.yaml b/Documentation/devicetree/bindings/riscv/sifive.yaml index 3a8647d..ee0a239 100644 --- a/Documentation/devicetree/bindings/riscv/sifive.yaml +++ b/Documentation/devicetree/bindings/riscv/sifive.yaml @@ -17,11 +17,18 @@ properties: $nodename: const: '/' compatible: -items: - - enum: - - sifive,hifive-unleashed-a00 - - const: sifive,fu540-c000 - - const: sifive,fu540 +oneOf: + - items: + - enum: + - sifive,hifive-unleashed-a00 + - const: sifive,fu540-c000 + - const: sifive,fu540 + + - items: + - enum: + - sifive,hifive-unmatched-a00 + - const: sifive,fu740-c000 + - const: sifive,fu740 additionalProperties: true -- 2.7.4
[PATCH v2 9/9] riscv: dts: add initial board data for the SiFive HiFive Unmatched
Add initial board data for the SiFive HiFive Unmatched A00. This patch is dependent on Zong's Patchset[0]. [0]: https://lore.kernel.org/linux-riscv/20201130082330.77268-4-zong...@sifive.com/T/#u Signed-off-by: Yash Shah --- arch/riscv/boot/dts/sifive/Makefile| 3 +- .../riscv/boot/dts/sifive/hifive-unmatched-a00.dts | 253 + 2 files changed, 255 insertions(+), 1 deletion(-) create mode 100644 arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts diff --git a/arch/riscv/boot/dts/sifive/Makefile b/arch/riscv/boot/dts/sifive/Makefile index 6d6189e..74c47fe 100644 --- a/arch/riscv/boot/dts/sifive/Makefile +++ b/arch/riscv/boot/dts/sifive/Makefile @@ -1,2 +1,3 @@ # SPDX-License-Identifier: GPL-2.0 -dtb-$(CONFIG_SOC_SIFIVE) += hifive-unleashed-a00.dtb +dtb-$(CONFIG_SOC_SIFIVE) += hifive-unleashed-a00.dtb \ + hifive-unmatched-a00.dtb diff --git a/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts b/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts new file mode 100644 index 000..b1c3c59 --- /dev/null +++ b/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts @@ -0,0 +1,253 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* Copyright (c) 2020 SiFive, Inc */ + +#include "fu740-c000.dtsi" +#include + +/* Clock frequency (in Hz) of the PCB crystal for rtcclk */ +#define RTCCLK_FREQ100 + +/ { + #address-cells = <2>; + #size-cells = <2>; + model = "SiFive HiFive Unmatched A00"; + compatible = "sifive,hifive-unmatched-a00", "sifive,fu740-c000", +"sifive,fu740"; + + chosen { + stdout-path = "serial0"; + }; + + cpus { + timebase-frequency = ; + }; + + memory@8000 { + device_type = "memory"; + reg = <0x0 0x8000 0x2 0x>; + }; + + soc { + }; + + hfclk: hfclk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <2600>; + clock-output-names = "hfclk"; + }; + + rtcclk: rtcclk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = ; + clock-output-names = "rtcclk"; + }; +}; + +&uart0 { + status = "okay"; +}; + +&uart1 { + status = "okay"; +}; + +&i2c0 { + status = "okay"; + + temperature-sensor@4c { + compatible = "ti,tmp451"; + reg = <0x4c>; + interrupt-parent = <&gpio>; + interrupts = <6 IRQ_TYPE_LEVEL_LOW>; + }; + + pmic@58 { + compatible = "dlg,da9063"; + reg = <0x58>; + interrupt-parent = <&gpio>; + interrupts = <1 IRQ_TYPE_LEVEL_LOW>; + interrupt-controller; + + regulators { + vdd_bcore1: bcore1 { + regulator-min-microvolt = <90>; + regulator-max-microvolt = <90>; + regulator-min-microamp = <500>; + regulator-max-microamp = <500>; + regulator-always-on; + }; + + vdd_bcore2: bcore2 { + regulator-min-microvolt = <90>; + regulator-max-microvolt = <90>; + regulator-min-microamp = <500>; + regulator-max-microamp = <500>; + regulator-always-on; + }; + + vdd_bpro: bpro { + regulator-min-microvolt = <180>; + regulator-max-microvolt = <180>; + regulator-min-microamp = <250>; + regulator-max-microamp = <250>; + regulator-always-on; + }; + + vdd_bperi: bperi { + regulator-min-microvolt = <105>; + regulator-max-microvolt = <105>; + regulator-min-microamp = <150>; + regulator-max-microamp = <150>; + regulator-always-on; + }; + + vdd_bmem: bmem { + regulator-min-microvolt = <120>; +
[PATCH v2 5/9] dt-bindings: gpio: Update DT binding docs to support SiFive FU740 SoC
Add new compatible strings to the DT binding documents to support SiFive FU740-C000. Signed-off-by: Yash Shah --- Documentation/devicetree/bindings/gpio/sifive,gpio.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/gpio/sifive,gpio.yaml b/Documentation/devicetree/bindings/gpio/sifive,gpio.yaml index a0efd8d..ab22056 100644 --- a/Documentation/devicetree/bindings/gpio/sifive,gpio.yaml +++ b/Documentation/devicetree/bindings/gpio/sifive,gpio.yaml @@ -13,7 +13,9 @@ maintainers: properties: compatible: items: - - const: sifive,fu540-c000-gpio + - enum: + - sifive,fu540-c000-gpio + - sifive,fu740-c000-gpio - const: sifive,gpio0 reg: -- 2.7.4
RE: [PATCH v2 1/2] RISC-V: Update l2 cache DT documentation to add support for SiFive FU740
> -Original Message- > From: Rob Herring > Sent: 09 December 2020 04:52 > To: Yash Shah > Cc: linux-kernel@vger.kernel.org; linux-ri...@lists.infradead.org; > devicet...@vger.kernel.org; b...@suse.de; a...@brainfault.org; > jonathan.came...@huawei.com; w...@kernel.org; s...@ravnborg.org; > a...@eecs.berkeley.edu; pal...@dabbelt.com; Paul Walmsley ( Sifive) > ; Sagar Kadam ; > Sachin Ghadi > Subject: Re: [PATCH v2 1/2] RISC-V: Update l2 cache DT documentation to > add support for SiFive FU740 > > [External Email] Do not click links or attachments unless you recognize the > sender and know the content is safe > > On Mon, Nov 30, 2020 at 11:13:03AM +0530, Yash Shah wrote: > > The L2 cache controller in SiFive FU740 has 4 ECC interrupt sources as > > compared to 3 in FU540. Update the DT documentation accordingly with > > "compatible" and "interrupt" property changes. > > 'dt-bindings: riscv: ...' for the subject. > > > > > Signed-off-by: Yash Shah > > --- > > Changes in v2: > > - Changes as per Rob Herring's request on v1 > > --- > > .../devicetree/bindings/riscv/sifive-l2-cache.yaml | 35 > > -- > > 1 file changed, 32 insertions(+), 3 deletions(-) > > > > diff --git > > a/Documentation/devicetree/bindings/riscv/sifive-l2-cache.yaml > > b/Documentation/devicetree/bindings/riscv/sifive-l2-cache.yaml > > index efc0198..749265c 100644 > > --- a/Documentation/devicetree/bindings/riscv/sifive-l2-cache.yaml > > +++ b/Documentation/devicetree/bindings/riscv/sifive-l2-cache.yaml > > @@ -27,6 +27,7 @@ select: > >items: > > - enum: > > - sifive,fu540-c000-ccache > > +- sifive,fu740-c000-ccache > > > >required: > > - compatible > > @@ -34,7 +35,9 @@ select: > > properties: > >compatible: > > items: > > - - const: sifive,fu540-c000-ccache > > + - enum: > > + - sifive,fu540-c000-ccache > > + - sifive,fu740-c000-ccache > >- const: cache > > > >cache-block-size: > > @@ -53,9 +56,15 @@ properties: > > > >interrupts: > > description: | > > - Must contain entries for DirError, DataError and DataFail signals. > > + Must contain 3 entries for FU540 (DirError, DataError and DataFail) > > or > 4 > > + entries for other chips (DirError, DirFail, DataError, DataFail > > + signals) > > While below is wrong, don't give descriptions that just repeat what the > schema says. Ok will remove the above description. > > > minItems: 3 > > -maxItems: 3 > > +maxItems: 4 > > +items: > > + - description: DirError interrupt > > + - description: DirFail interrupt > > + - description: DataError interrupt > > + - description: DataFail interrupt > > This says DataFail is optional. I will move back to your initial suggestion to add the new entry "DirFail" as the last index to keep the order same. Will make the corresponding changes in the driver and send a v3 patch. Thanks for your review. - Yash
RE: [PATCH 2/3] soc: sifive: beu: Add support for SiFive Bus Error Unit
Any updates on this patch? - Yash > -Original Message- > From: Yash Shah > Sent: 12 November 2020 17:31 > To: robh...@kernel.org; Paul Walmsley ( Sifive) > ; pal...@dabbelt.com; b...@alien8.de; > mche...@kernel.org; tony.l...@intel.com; james.mo...@arm.com; > r...@kernel.org > Cc: a...@eecs.berkeley.edu; devicet...@vger.kernel.org; linux- > ri...@lists.infradead.org; linux-kernel@vger.kernel.org; linux- > e...@vger.kernel.org; Sachin Ghadi ; Yash > Shah > Subject: [PATCH 2/3] soc: sifive: beu: Add support for SiFive Bus Error Unit > > Add driver support for Bus Error Unit present in SiFive's FU740 chip. > Currently the driver reports erroneous events only using Platform-level > interrupts. The support for reporting events using hart-local interrupts can > be added in future. > > Signed-off-by: Yash Shah > --- > drivers/soc/sifive/Kconfig | 5 + > drivers/soc/sifive/Makefile | 1 + > drivers/soc/sifive/sifive_beu.c | 197 > > include/soc/sifive/sifive_beu.h | 16 > 4 files changed, 219 insertions(+) > create mode 100644 drivers/soc/sifive/sifive_beu.c create mode 100644 > include/soc/sifive/sifive_beu.h > > diff --git a/drivers/soc/sifive/Kconfig b/drivers/soc/sifive/Kconfig index > 58cf8c4..d575fc1 100644 > --- a/drivers/soc/sifive/Kconfig > +++ b/drivers/soc/sifive/Kconfig > @@ -7,4 +7,9 @@ config SIFIVE_L2 > help > Support for the L2 cache controller on SiFive platforms. > > +config SIFIVE_BEU > + bool "Sifive Bus Error Unit" > + help > + Support for the Bus Error Unit on SiFive platforms. > + > endif > diff --git a/drivers/soc/sifive/Makefile b/drivers/soc/sifive/Makefile index > b5caff7..1b43ecd 100644 > --- a/drivers/soc/sifive/Makefile > +++ b/drivers/soc/sifive/Makefile > @@ -1,3 +1,4 @@ > # SPDX-License-Identifier: GPL-2.0 > > obj-$(CONFIG_SIFIVE_L2) += sifive_l2_cache.o > +obj-$(CONFIG_SIFIVE_BEU) += sifive_beu.o > diff --git a/drivers/soc/sifive/sifive_beu.c b/drivers/soc/sifive/sifive_beu.c > new file mode 100644 index 000..87b69ba > --- /dev/null > +++ b/drivers/soc/sifive/sifive_beu.c > @@ -0,0 +1,197 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * SiFive Bus Error Unit driver > + * Copyright (C) 2020 SiFive > + * Author: Yash Shah > + * > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > + > +#define SIFIVE_BEU_CAUSE 0x00 > +#define SIFIVE_BEU_VALUE 0x08 > +#define SIFIVE_BEU_ENABLE0x10 > +#define SIFIVE_BEU_PLIC_INTR 0x18 > +#define SIFIVE_BEU_ACCRUED 0x20 > +#define SIFIVE_BEU_LOCAL_INTR0x28 > + > +#define LOCAL_INTERRUPT 0 > +#define PLIC_INTERRUPT 1 > +#define MAX_ERR_EVENTS 5 > + > +enum beu_err_events { > + RESERVED = -1, > + NO_ERR, > + ITIM_CORR_ECC = 2, > + ITIM_UNCORR_ECC, > + TILINKBUS_ERR = 5, > + DCACHE_CORR_ECC, > + DCACHE_UNCORR_ECC > +}; > + > +static > +int err_events[MAX_ERR_EVENTS] = {ITIM_CORR_ECC, ITIM_UNCORR_ECC, > TILINKBUS_ERR, > + DCACHE_CORR_ECC, > DCACHE_UNCORR_ECC}; > + > +struct beu_sifive_ddata { > + void __iomem *regs; > + int irq; > +}; > + > +static int beu_enable_event(struct beu_sifive_ddata *ddata, > + int event, int intr_type) > +{ > + unsigned char event_mask = BIT(event), val; > + > + val = readb(ddata->regs + SIFIVE_BEU_ENABLE); > + val |= event_mask; > + writeb(val, ddata->regs + SIFIVE_BEU_ENABLE); > + > + if (intr_type == PLIC_INTERRUPT) { > + val = readb(ddata->regs + SIFIVE_BEU_PLIC_INTR); > + val |= event_mask; > + writeb(val, ddata->regs + SIFIVE_BEU_PLIC_INTR); > + } else if (intr_type == LOCAL_INTERRUPT) { > + val = readb(ddata->regs + SIFIVE_BEU_LOCAL_INTR); > + val |= event_mask; > + writeb(event_mask, ddata->regs + SIFIVE_BEU_LOCAL_INTR); > + } > + > + return 0; > +} > + > +static ATOMIC_NOTIFIER_HEAD(beu_chain); > + > +int register_sifive_beu_error_notifier(struct notifier_block *nb) { > + return atomic_notifier_chain_register(&beu_chain, nb); } > + > +int unregister_sifive_beu_error_notifier(struct notifier_block *nb) { > + return atomic_notifier_chain_unregister(&beu_chain, nb); } > + > +static irqreturn_t beu_sifive_irq(int irq, void *data) { > + struct beu_sifive_ddata *ddata = data; > + unsigned char cause, addr; > + > + addr = readb(ddata->regs + SIFIVE_BEU_VALU
[PATCH v3 0/2] riscv: sifive_l2_cache: Add support for SiFive FU740 SoC
Add support for additional interrupt present in SiFive FU740 chip. Changes: v3: - Rename the subject line of dt-binding patch - Add the additional interrupt "DirFail" as the last entry so as to keep the order of all previous index same. v2: - Changes as per Rob Herring's request on v1 Yash Shah (2): dt-bindings: riscv: Update l2 cache DT documentation to add support for SiFive FU740 RISC-V: sifive_l2_cache: Update L2 cache driver to support SiFive FU740 .../devicetree/bindings/riscv/sifive-l2-cache.yaml | 34 +++--- drivers/soc/sifive/sifive_l2_cache.c | 27 +++-- 2 files changed, 54 insertions(+), 7 deletions(-) -- 2.7.4
[PATCH v3 2/2] RISC-V: sifive_l2_cache: Update L2 cache driver to support SiFive FU740
SiFive FU740 has 4 ECC interrupt sources as compared to 3 in FU540. Update the L2 cache controller driver to support this additional interrupt in case of FU740-C000 chip. Signed-off-by: Yash Shah --- drivers/soc/sifive/sifive_l2_cache.c | 27 --- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/drivers/soc/sifive/sifive_l2_cache.c b/drivers/soc/sifive/sifive_l2_cache.c index 44d7e19..59640a1 100644 --- a/drivers/soc/sifive/sifive_l2_cache.c +++ b/drivers/soc/sifive/sifive_l2_cache.c @@ -17,6 +17,10 @@ #define SIFIVE_L2_DIRECCFIX_HIGH 0x104 #define SIFIVE_L2_DIRECCFIX_COUNT 0x108 +#define SIFIVE_L2_DIRECCFAIL_LOW 0x120 +#define SIFIVE_L2_DIRECCFAIL_HIGH 0x124 +#define SIFIVE_L2_DIRECCFAIL_COUNT 0x128 + #define SIFIVE_L2_DATECCFIX_LOW 0x140 #define SIFIVE_L2_DATECCFIX_HIGH 0x144 #define SIFIVE_L2_DATECCFIX_COUNT 0x148 @@ -29,7 +33,7 @@ #define SIFIVE_L2_WAYENABLE 0x08 #define SIFIVE_L2_ECCINJECTERR 0x40 -#define SIFIVE_L2_MAX_ECCINTR 3 +#define SIFIVE_L2_MAX_ECCINTR 4 static void __iomem *l2_base; static int g_irq[SIFIVE_L2_MAX_ECCINTR]; @@ -39,6 +43,7 @@ enum { DIR_CORR = 0, DATA_CORR, DATA_UNCORR, + DIR_UNCORR, }; #ifdef CONFIG_DEBUG_FS @@ -93,6 +98,7 @@ static void l2_config_read(void) static const struct of_device_id sifive_l2_ids[] = { { .compatible = "sifive,fu540-c000-ccache" }, + { .compatible = "sifive,fu740-c000-ccache" }, { /* end of table */ }, }; @@ -155,6 +161,15 @@ static irqreturn_t l2_int_handler(int irq, void *device) atomic_notifier_call_chain(&l2_err_chain, SIFIVE_L2_ERR_TYPE_CE, "DirECCFix"); } + if (irq == g_irq[DIR_UNCORR]) { + add_h = readl(l2_base + SIFIVE_L2_DIRECCFAIL_HIGH); + add_l = readl(l2_base + SIFIVE_L2_DIRECCFAIL_LOW); + /* Reading this register clears the DirFail interrupt sig */ + readl(l2_base + SIFIVE_L2_DIRECCFAIL_COUNT); + atomic_notifier_call_chain(&l2_err_chain, SIFIVE_L2_ERR_TYPE_UE, + "DirECCFail"); + panic("L2CACHE: DirFail @ 0x%08X.%08X\n", add_h, add_l); + } if (irq == g_irq[DATA_CORR]) { add_h = readl(l2_base + SIFIVE_L2_DATECCFIX_HIGH); add_l = readl(l2_base + SIFIVE_L2_DATECCFIX_LOW); @@ -181,7 +196,7 @@ static int __init sifive_l2_init(void) { struct device_node *np; struct resource res; - int i, rc; + int i, rc, intr_num; np = of_find_matching_node(NULL, sifive_l2_ids); if (!np) @@ -194,7 +209,13 @@ static int __init sifive_l2_init(void) if (!l2_base) return -ENOMEM; - for (i = 0; i < SIFIVE_L2_MAX_ECCINTR; i++) { + intr_num = of_property_count_u32_elems(np, "interrupts"); + if (!intr_num) { + pr_err("L2CACHE: no interrupts property\n"); + return -ENODEV; + } + + for (i = 0; i < intr_num; i++) { g_irq[i] = irq_of_parse_and_map(np, i); rc = request_irq(g_irq[i], l2_int_handler, 0, "l2_ecc", NULL); if (rc) { -- 2.7.4
[PATCH v3 1/2] dt-bindings: riscv: Update l2 cache DT documentation to add support for SiFive FU740
The L2 cache controller in SiFive FU740 has 4 ECC interrupt sources as compared to 3 in FU540. Update the DT documentation accordingly with "compatible" and "interrupt" property changes. Signed-off-by: Yash Shah --- .../devicetree/bindings/riscv/sifive-l2-cache.yaml | 34 +++--- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/riscv/sifive-l2-cache.yaml b/Documentation/devicetree/bindings/riscv/sifive-l2-cache.yaml index efc0198..6a576dc 100644 --- a/Documentation/devicetree/bindings/riscv/sifive-l2-cache.yaml +++ b/Documentation/devicetree/bindings/riscv/sifive-l2-cache.yaml @@ -27,6 +27,7 @@ select: items: - enum: - sifive,fu540-c000-ccache +- sifive,fu740-c000-ccache required: - compatible @@ -34,7 +35,9 @@ select: properties: compatible: items: - - const: sifive,fu540-c000-ccache + - enum: + - sifive,fu540-c000-ccache + - sifive,fu740-c000-ccache - const: cache cache-block-size: @@ -52,10 +55,13 @@ properties: cache-unified: true interrupts: -description: | - Must contain entries for DirError, DataError and DataFail signals. minItems: 3 -maxItems: 3 +maxItems: 4 +items: + - description: DirError interrupt + - description: DataError interrupt + - description: DataFail interrupt + - description: DirFail interrupt reg: maxItems: 1 @@ -67,6 +73,26 @@ properties: The reference to the reserved-memory for the L2 Loosely Integrated Memory region. The reserved memory node should be defined as per the bindings in reserved-memory.txt. +if: + properties: +compatible: + contains: +const: sifive,fu540-c000-ccache + +then: + properties: +interrupts: + description: | +Must contain entries for DirError, DataError and DataFail signals. + maxItems: 3 + +else: + properties: +interrupts: + description: | +Must contain entries for DirError, DataError, DataFail, DirFail signals. + minItems: 4 + additionalProperties: false required: -- 2.7.4
[PATCH 0/4] arch: riscv: add board and SoC DT file support
Start board support by adding initial support for the SiFive FU740 SoC and the first development board that uses it, the SiFive HiFive Unmatched A00. Boot-tested on Linux 5.10-rc4 on a HiFive Unmatched A00 board using the U-boot and OpenSBI. This patch series is dependent on Zong's Patchset[0]. The patchset also adds two new nodes in dtsi file. The binding documentation patch for these nodes are already posted on the mailing list[1][2]. [0]: https://lore.kernel.org/linux-riscv/20201130082330.77268-4-zong...@sifive.com/T/#u [1]: https://lore.kernel.org/linux-riscv/1606714984-16593-1-git-send-email-yash.s...@sifive.com/T/#t [2]: https://lore.kernel.org/linux-riscv/20201126030043.67390-1-zong...@sifive.com/T/#u Yash Shah (4): dt-bindings: riscv: Update DT binding docs to support SiFive FU740 SoC riscv: dts: add initial support for the SiFive FU740-C000 SoC dt-bindings: riscv: Update YAML doc to support SiFive HiFive Unmatched board riscv: dts: add initial board data for the SiFive HiFive Unmatched .../devicetree/bindings/gpio/sifive,gpio.yaml | 4 +- .../devicetree/bindings/i2c/i2c-ocores.txt | 6 +- .../devicetree/bindings/pwm/pwm-sifive.yaml| 9 +- Documentation/devicetree/bindings/riscv/cpus.yaml | 6 + .../devicetree/bindings/riscv/sifive.yaml | 17 +- .../devicetree/bindings/serial/sifive-serial.yaml | 4 +- .../devicetree/bindings/spi/spi-sifive.yaml| 10 +- arch/riscv/boot/dts/sifive/Makefile| 3 +- arch/riscv/boot/dts/sifive/fu740-c000.dtsi | 293 + .../riscv/boot/dts/sifive/hifive-unmatched-a00.dts | 253 ++ 10 files changed, 588 insertions(+), 17 deletions(-) create mode 100644 arch/riscv/boot/dts/sifive/fu740-c000.dtsi create mode 100644 arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts -- 2.7.4
[PATCH 2/4] riscv: dts: add initial support for the SiFive FU740-C000 SoC
Add initial support for the SiFive FU540-C000 SoC. FU740-C000 is built around the SiFIve U7 Core Complex and a TileLink interconnect. This file is expected to grow as more device drivers are added to the kernel. Signed-off-by: Yash Shah --- arch/riscv/boot/dts/sifive/fu740-c000.dtsi | 293 + 1 file changed, 293 insertions(+) create mode 100644 arch/riscv/boot/dts/sifive/fu740-c000.dtsi diff --git a/arch/riscv/boot/dts/sifive/fu740-c000.dtsi b/arch/riscv/boot/dts/sifive/fu740-c000.dtsi new file mode 100644 index 000..eeb4f8c3 --- /dev/null +++ b/arch/riscv/boot/dts/sifive/fu740-c000.dtsi @@ -0,0 +1,293 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* Copyright (c) 2020 SiFive, Inc */ + +/dts-v1/; + +#include + +/ { + #address-cells = <2>; + #size-cells = <2>; + compatible = "sifive,fu740-c000", "sifive,fu740"; + + aliases { + serial0 = &uart0; + serial1 = &uart1; + ethernet0 = ð0; + }; + + chosen { + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + cpu0: cpu@0 { + compatible = "sifive,bullet0", "riscv"; + device_type = "cpu"; + i-cache-block-size = <64>; + i-cache-sets = <128>; + i-cache-size = <16384>; + next-level-cache = <&ccache>; + reg = <0x0>; + riscv,isa = "rv64imac"; + status = "disabled"; + cpu0_intc: interrupt-controller { + #interrupt-cells = <1>; + compatible = "riscv,cpu-intc"; + interrupt-controller; + }; + }; + cpu1: cpu@1 { + compatible = "sifive,bullet0", "riscv"; + d-cache-block-size = <64>; + d-cache-sets = <64>; + d-cache-size = <32768>; + d-tlb-sets = <1>; + d-tlb-size = <40>; + device_type = "cpu"; + i-cache-block-size = <64>; + i-cache-sets = <128>; + i-cache-size = <32768>; + i-tlb-sets = <1>; + i-tlb-size = <40>; + mmu-type = "riscv,sv39"; + next-level-cache = <&ccache>; + reg = <0x1>; + riscv,isa = "rv64imafdc"; + tlb-split; + cpu1_intc: interrupt-controller { + #interrupt-cells = <1>; + compatible = "riscv,cpu-intc"; + interrupt-controller; + }; + }; + cpu2: cpu@2 { + compatible = "sifive,bullet0", "riscv"; + d-cache-block-size = <64>; + d-cache-sets = <64>; + d-cache-size = <32768>; + d-tlb-sets = <1>; + d-tlb-size = <40>; + device_type = "cpu"; + i-cache-block-size = <64>; + i-cache-sets = <128>; + i-cache-size = <32768>; + i-tlb-sets = <1>; + i-tlb-size = <40>; + mmu-type = "riscv,sv39"; + next-level-cache = <&ccache>; + reg = <0x2>; + riscv,isa = "rv64imafdc"; + tlb-split; + cpu2_intc: interrupt-controller { + #interrupt-cells = <1>; + compatible = "riscv,cpu-intc"; + interrupt-controller; + }; + }; + cpu3: cpu@3 { + compatible = "sifive,bullet0", "riscv"; + d-cache-block-size = <64>; + d-cache-sets = <64>; + d-cache-size = <32768>; + d-tlb-sets = <1>; + d-tlb-size = <40>; + device_type = "cpu"; +
[PATCH 1/4] dt-bindings: riscv: Update DT binding docs to support SiFive FU740 SoC
Add new compatible strings to the DT binding documents to support SiFive FU740-C000. Also, add new compatible strings in cpus.yaml to support the E71 and U74 CPU cores ("harts") that are present on FU740-C000 SoC. Signed-off-by: Yash Shah --- Documentation/devicetree/bindings/gpio/sifive,gpio.yaml | 4 +++- Documentation/devicetree/bindings/i2c/i2c-ocores.txt| 6 -- Documentation/devicetree/bindings/pwm/pwm-sifive.yaml | 9 ++--- Documentation/devicetree/bindings/riscv/cpus.yaml | 6 ++ Documentation/devicetree/bindings/serial/sifive-serial.yaml | 4 +++- Documentation/devicetree/bindings/spi/spi-sifive.yaml | 10 ++ 6 files changed, 28 insertions(+), 11 deletions(-) diff --git a/Documentation/devicetree/bindings/gpio/sifive,gpio.yaml b/Documentation/devicetree/bindings/gpio/sifive,gpio.yaml index a0efd8d..ab22056 100644 --- a/Documentation/devicetree/bindings/gpio/sifive,gpio.yaml +++ b/Documentation/devicetree/bindings/gpio/sifive,gpio.yaml @@ -13,7 +13,9 @@ maintainers: properties: compatible: items: - - const: sifive,fu540-c000-gpio + - enum: + - sifive,fu540-c000-gpio + - sifive,fu740-c000-gpio - const: sifive,gpio0 reg: diff --git a/Documentation/devicetree/bindings/i2c/i2c-ocores.txt b/Documentation/devicetree/bindings/i2c/i2c-ocores.txt index 6b25a80..1966b2c 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-ocores.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-ocores.txt @@ -3,9 +3,11 @@ Device tree configuration for i2c-ocores Required properties: - compatible : "opencores,i2c-ocores" "aeroflexgaisler,i2cmst" -"sifive,fu540-c000-i2c", "sifive,i2c0" +"sifive,-i2c", "sifive,i2c0" For Opencore based I2C IP block reimplemented in -FU540-C000 SoC. Please refer to sifive-blocks-ip-versioning.txt +SiFive SoC. Supported compatible strings are: +"sifive,fu540-c000-i2c" and "sifive,fu740-c000-i2c" +Please refer to sifive-blocks-ip-versioning.txt for additional details. - reg : bus address start and address range size of device - clocks : handle to the controller clock; see the note below. diff --git a/Documentation/devicetree/bindings/pwm/pwm-sifive.yaml b/Documentation/devicetree/bindings/pwm/pwm-sifive.yaml index 5ac2527..84e6691 100644 --- a/Documentation/devicetree/bindings/pwm/pwm-sifive.yaml +++ b/Documentation/devicetree/bindings/pwm/pwm-sifive.yaml @@ -25,12 +25,15 @@ description: properties: compatible: items: - - const: sifive,fu540-c000-pwm + - enum: + - sifive,fu540-c000-pwm + - sifive,fu740-c000-pwm - const: sifive,pwm0 description: Should be "sifive,-pwm" and "sifive,pwm". Supported - compatible strings are "sifive,fu540-c000-pwm" for the SiFive PWM v0 - as integrated onto the SiFive FU540 chip, and "sifive,pwm0" for the + compatible strings are "sifive,fu540-c000-pwm" and + "sifive,fu740-c000-pwm" for the SiFive PWM v0 as integrated onto the + SiFive FU540 and FU740 chip respectively, and "sifive,pwm0" for the SiFive PWM v0 IP block with no chip integration tweaks. Please refer to sifive-blocks-ip-versioning.txt for details. diff --git a/Documentation/devicetree/bindings/riscv/cpus.yaml b/Documentation/devicetree/bindings/riscv/cpus.yaml index c6925e0..eb6843f 100644 --- a/Documentation/devicetree/bindings/riscv/cpus.yaml +++ b/Documentation/devicetree/bindings/riscv/cpus.yaml @@ -28,11 +28,17 @@ properties: - items: - enum: - sifive,rocket0 + - sifive,bullet0 - sifive,e5 + - sifive,e7 - sifive,e51 + - sifive,e71 - sifive,u54-mc + - sifive,u74-mc - sifive,u54 + - sifive,u74 - sifive,u5 + - sifive,u7 - const: riscv - const: riscv# Simulator only description: diff --git a/Documentation/devicetree/bindings/serial/sifive-serial.yaml b/Documentation/devicetree/bindings/serial/sifive-serial.yaml index 92283f6..3ac5c7f 100644 --- a/Documentation/devicetree/bindings/serial/sifive-serial.yaml +++ b/Documentation/devicetree/bindings/serial/sifive-serial.yaml @@ -17,7 +17,9 @@ allOf: properties: compatible: items: - - const: sifive,fu540-c000-uart + - enum: + - sifive,fu540-c000-uart + - sifive,fu740-c000-uart - const: sifive,uart0 description: diff --git a/Documentation/devicetree/bindings/spi/spi-sifive.yaml b/Documentation/devicetree/bindings/spi/spi-s
[PATCH 3/4] dt-bindings: riscv: Update YAML doc to support SiFive HiFive Unmatched board
Add new compatible strings to the YAML DT binding document to support SiFive's HiFive Unmatched board Signed-off-by: Yash Shah --- Documentation/devicetree/bindings/riscv/sifive.yaml | 17 - 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/Documentation/devicetree/bindings/riscv/sifive.yaml b/Documentation/devicetree/bindings/riscv/sifive.yaml index 3a8647d..ee0a239 100644 --- a/Documentation/devicetree/bindings/riscv/sifive.yaml +++ b/Documentation/devicetree/bindings/riscv/sifive.yaml @@ -17,11 +17,18 @@ properties: $nodename: const: '/' compatible: -items: - - enum: - - sifive,hifive-unleashed-a00 - - const: sifive,fu540-c000 - - const: sifive,fu540 +oneOf: + - items: + - enum: + - sifive,hifive-unleashed-a00 + - const: sifive,fu540-c000 + - const: sifive,fu540 + + - items: + - enum: + - sifive,hifive-unmatched-a00 + - const: sifive,fu740-c000 + - const: sifive,fu740 additionalProperties: true -- 2.7.4
[PATCH 4/4] riscv: dts: add initial board data for the SiFive HiFive Unmatched
Add initial board data for the SiFive HiFive Unmatched A00 Signed-off-by: Yash Shah --- arch/riscv/boot/dts/sifive/Makefile| 3 +- .../riscv/boot/dts/sifive/hifive-unmatched-a00.dts | 253 + 2 files changed, 255 insertions(+), 1 deletion(-) create mode 100644 arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts diff --git a/arch/riscv/boot/dts/sifive/Makefile b/arch/riscv/boot/dts/sifive/Makefile index 6d6189e..74c47fe 100644 --- a/arch/riscv/boot/dts/sifive/Makefile +++ b/arch/riscv/boot/dts/sifive/Makefile @@ -1,2 +1,3 @@ # SPDX-License-Identifier: GPL-2.0 -dtb-$(CONFIG_SOC_SIFIVE) += hifive-unleashed-a00.dtb +dtb-$(CONFIG_SOC_SIFIVE) += hifive-unleashed-a00.dtb \ + hifive-unmatched-a00.dtb diff --git a/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts b/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts new file mode 100644 index 000..b1c3c59 --- /dev/null +++ b/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts @@ -0,0 +1,253 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* Copyright (c) 2020 SiFive, Inc */ + +#include "fu740-c000.dtsi" +#include + +/* Clock frequency (in Hz) of the PCB crystal for rtcclk */ +#define RTCCLK_FREQ100 + +/ { + #address-cells = <2>; + #size-cells = <2>; + model = "SiFive HiFive Unmatched A00"; + compatible = "sifive,hifive-unmatched-a00", "sifive,fu740-c000", +"sifive,fu740"; + + chosen { + stdout-path = "serial0"; + }; + + cpus { + timebase-frequency = ; + }; + + memory@8000 { + device_type = "memory"; + reg = <0x0 0x8000 0x2 0x>; + }; + + soc { + }; + + hfclk: hfclk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <2600>; + clock-output-names = "hfclk"; + }; + + rtcclk: rtcclk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = ; + clock-output-names = "rtcclk"; + }; +}; + +&uart0 { + status = "okay"; +}; + +&uart1 { + status = "okay"; +}; + +&i2c0 { + status = "okay"; + + temperature-sensor@4c { + compatible = "ti,tmp451"; + reg = <0x4c>; + interrupt-parent = <&gpio>; + interrupts = <6 IRQ_TYPE_LEVEL_LOW>; + }; + + pmic@58 { + compatible = "dlg,da9063"; + reg = <0x58>; + interrupt-parent = <&gpio>; + interrupts = <1 IRQ_TYPE_LEVEL_LOW>; + interrupt-controller; + + regulators { + vdd_bcore1: bcore1 { + regulator-min-microvolt = <90>; + regulator-max-microvolt = <90>; + regulator-min-microamp = <500>; + regulator-max-microamp = <500>; + regulator-always-on; + }; + + vdd_bcore2: bcore2 { + regulator-min-microvolt = <90>; + regulator-max-microvolt = <90>; + regulator-min-microamp = <500>; + regulator-max-microamp = <500>; + regulator-always-on; + }; + + vdd_bpro: bpro { + regulator-min-microvolt = <180>; + regulator-max-microvolt = <180>; + regulator-min-microamp = <250>; + regulator-max-microamp = <250>; + regulator-always-on; + }; + + vdd_bperi: bperi { + regulator-min-microvolt = <105>; + regulator-max-microvolt = <105>; + regulator-min-microamp = <150>; + regulator-max-microamp = <150>; + regulator-always-on; + }; + + vdd_bmem: bmem { + regulator-min-microvolt = <120>; + regulator-max-microvolt = <120>; + regulator-min-microamp = <300>; +
RE: [PATCH 1/4] dt-bindings: riscv: Update DT binding docs to support SiFive FU740 SoC
> -Original Message- > From: Andrew Lunn > Sent: 02 December 2020 20:28 > To: Yash Shah > Cc: linux-...@vger.kernel.org; linux-ser...@vger.kernel.org; linux- > p...@vger.kernel.org; linux-...@vger.kernel.org; linux- > ker...@vger.kernel.org; linux-ri...@lists.infradead.org; > devicet...@vger.kernel.org; linux-g...@vger.kernel.org; > broo...@kernel.org; gre...@linuxfoundation.org; a...@eecs.berkeley.edu; > lee.jo...@linaro.org; u.kleine-koe...@pengutronix.de; > thierry.red...@gmail.com; pe...@korsgaard.com; Paul Walmsley ( Sifive) > ; pal...@dabbelt.com; robh...@kernel.org; > bgolaszew...@baylibre.com; linus.wall...@linaro.org; Sachin Ghadi > > Subject: Re: [PATCH 1/4] dt-bindings: riscv: Update DT binding docs to > support SiFive FU740 SoC > > [External Email] Do not click links or attachments unless you recognize the > sender and know the content is safe > > > diff --git a/Documentation/devicetree/bindings/i2c/i2c-ocores.txt > > b/Documentation/devicetree/bindings/i2c/i2c-ocores.txt > > index 6b25a80..1966b2c 100644 > > --- a/Documentation/devicetree/bindings/i2c/i2c-ocores.txt > > +++ b/Documentation/devicetree/bindings/i2c/i2c-ocores.txt > > @@ -3,9 +3,11 @@ Device tree configuration for i2c-ocores Required > > properties: > > - compatible : "opencores,i2c-ocores" > > "aeroflexgaisler,i2cmst" > > -"sifive,fu540-c000-i2c", "sifive,i2c0" > > +"sifive,-i2c", "sifive,i2c0" > > Please make this a full list. At some point, this file will get turned into > yaml, at > which point substitution like this will need expanding. It is better to do > that > now. Ok sure, will do that in patch v2. - Yash > > Andrew
RE: [PATCH v2 7/9] riscv: dts: add initial support for the SiFive FU740-C000 SoC
> -Original Message- > From: Bin Meng > Sent: 10 December 2020 19:05 > To: Yash Shah > Cc: linux-...@vger.kernel.org; linux-ser...@vger.kernel.org; linux- > p...@vger.kernel.org; linux-...@vger.kernel.org; linux-kernel ker...@vger.kernel.org>; linux-riscv ; > devicetree ; open list:GPIO SUBSYSTEM g...@vger.kernel.org>; broo...@kernel.org; Greg Kroah-Hartman > ; Albert Ou ; > lee.jo...@linaro.org; u.kleine-koe...@pengutronix.de; Thierry Reding > ; and...@lunn.ch; Peter Korsgaard > ; Paul Walmsley ( Sifive) > ; Palmer Dabbelt ; Rob > Herring ; Bartosz Golaszewski > ; Linus Walleij > Subject: Re: [PATCH v2 7/9] riscv: dts: add initial support for the SiFive > FU740- > C000 SoC > > [External Email] Do not click links or attachments unless you recognize the > sender and know the content is safe > > On Tue, Dec 8, 2020 at 3:06 PM Yash Shah wrote: > > > > Add initial support for the SiFive FU540-C000 SoC. FU740-C000 is built > > FU740-C000 Soc > > > around the SiFIve U7 Core Complex and a TileLink interconnect. > > > > This file is expected to grow as more device drivers are added to the > > kernel. > > > > Signed-off-by: Yash Shah > > --- > > arch/riscv/boot/dts/sifive/fu740-c000.dtsi | 293 > > + > > 1 file changed, 293 insertions(+) > > create mode 100644 arch/riscv/boot/dts/sifive/fu740-c000.dtsi > > > > diff --git a/arch/riscv/boot/dts/sifive/fu740-c000.dtsi > > b/arch/riscv/boot/dts/sifive/fu740-c000.dtsi > > new file mode 100644 > > index 000..eeb4f8c3 > > --- /dev/null > > +++ b/arch/riscv/boot/dts/sifive/fu740-c000.dtsi > > @@ -0,0 +1,293 @@ ... > > + plic0: interrupt-controller@c00 { > > + #interrupt-cells = <1>; > > + #address-cells = <0>; > > + compatible = "sifive,fu540-c000-plic", > > + "sifive,plic-1.0.0"; > > I don't see bindings updated for FU740 PLIC, like "sifive,fu740-c000-plic"? That's because it is not required. There won't be any difference in driver code for FU740 plic. ... > > + eth0: ethernet@1009 { > > + compatible = "sifive,fu540-c000-gem"; > > "sifive,fu740-c000-gem"? > Same reason as above. Thanks for your review. - Yash > > + interrupt-parent = <&plic0>; > > + interrupts = <55>; > > + reg = <0x0 0x1009 0x0 0x2000>, > > + <0x0 0x100a 0x0 0x1000>; > > + local-mac-address = [00 00 00 00 00 00]; > > + clock-names = "pclk", "hclk"; > > + clocks = <&prci PRCI_CLK_GEMGXLPLL>, > > +<&prci PRCI_CLK_GEMGXLPLL>; > > + #address-cells = <1>; > > + #size-cells = <0>; > > + status = "disabled"; > > + }; > > + pwm0: pwm@1002 { > > + compatible = "sifive,fu740-c000-pwm", "sifive,pwm0"; > > + reg = <0x0 0x1002 0x0 0x1000>; > > + interrupt-parent = <&plic0>; > > + interrupts = <44>, <45>, <46>, <47>; > > + clocks = <&prci PRCI_CLK_PCLK>; > > + #pwm-cells = <3>; > > + status = "disabled"; > > + }; > > + pwm1: pwm@10021000 { > > + compatible = "sifive,fu740-c000-pwm", "sifive,pwm0"; > > + reg = <0x0 0x10021000 0x0 0x1000>; > > + interrupt-parent = <&plic0>; > > + interrupts = <48>, <49>, <50>, <51>; > > + clocks = <&prci PRCI_CLK_PCLK>; > > + #pwm-cells = <3>; > > + status = "disabled"; > > + }; > > + ccache: cache-controller@201 { > > + compatible = "sifive,fu740-c000-ccache", "cache"; > > + cache-block-size = <64>; > > + cache-level = <2>; > > +
RE: [PATCH v2 7/9] riscv: dts: add initial support for the SiFive FU740-C000 SoC
> -Original Message- > From: Bin Meng > Sent: 16 December 2020 11:36 > To: Yash Shah > Cc: linux-...@vger.kernel.org; linux-ser...@vger.kernel.org; linux- > p...@vger.kernel.org; linux-...@vger.kernel.org; linux-kernel ker...@vger.kernel.org>; linux-riscv ; > devicetree ; open list:GPIO SUBSYSTEM g...@vger.kernel.org>; broo...@kernel.org; Greg Kroah-Hartman > ; Albert Ou ; > lee.jo...@linaro.org; u.kleine-koe...@pengutronix.de; Thierry Reding > ; and...@lunn.ch; Peter Korsgaard > ; Paul Walmsley ( Sifive) > ; Palmer Dabbelt ; Rob > Herring ; Bartosz Golaszewski > ; Linus Walleij > Subject: Re: [PATCH v2 7/9] riscv: dts: add initial support for the SiFive > FU740- > C000 SoC > > [External Email] Do not click links or attachments unless you recognize the > sender and know the content is safe > > Hi Yash, > > On Wed, Dec 16, 2020 at 1:24 PM Yash Shah > wrote: > > > > > -----Original Message- > > > From: Bin Meng > > > Sent: 10 December 2020 19:05 > > > To: Yash Shah > > > Cc: linux-...@vger.kernel.org; linux-ser...@vger.kernel.org; linux- > > > p...@vger.kernel.org; linux-...@vger.kernel.org; linux-kernel > > ker...@vger.kernel.org>; linux-riscv > > > ; > > > devicetree ; open list:GPIO SUBSYSTEM > > > ; broo...@kernel.org; Greg > > > Kroah-Hartman ; Albert Ou > > > ; lee.jo...@linaro.org; > > > u.kleine-koe...@pengutronix.de; Thierry Reding > > > ; and...@lunn.ch; Peter Korsgaard > > > ; Paul Walmsley ( Sifive) > > > ; Palmer Dabbelt ; > Rob > > > Herring ; Bartosz Golaszewski > > > ; Linus Walleij > > > > > > Subject: Re: [PATCH v2 7/9] riscv: dts: add initial support for the > > > SiFive FU740- > > > C000 SoC > > > > > > [External Email] Do not click links or attachments unless you > > > recognize the sender and know the content is safe > > > > > > On Tue, Dec 8, 2020 at 3:06 PM Yash Shah > wrote: > > > > > > > > Add initial support for the SiFive FU540-C000 SoC. FU740-C000 is > > > > built > > > > > > FU740-C000 Soc > > > > > > > around the SiFIve U7 Core Complex and a TileLink interconnect. > > > > > > > > This file is expected to grow as more device drivers are added to > > > > the kernel. > > > > > > > > Signed-off-by: Yash Shah > > > > --- > > > > arch/riscv/boot/dts/sifive/fu740-c000.dtsi | 293 > > > > + > > > > 1 file changed, 293 insertions(+) create mode 100644 > > > > arch/riscv/boot/dts/sifive/fu740-c000.dtsi > > > > > > > > diff --git a/arch/riscv/boot/dts/sifive/fu740-c000.dtsi > > > > b/arch/riscv/boot/dts/sifive/fu740-c000.dtsi > > > > new file mode 100644 > > > > index 000..eeb4f8c3 > > > > --- /dev/null > > > > +++ b/arch/riscv/boot/dts/sifive/fu740-c000.dtsi > > > > @@ -0,0 +1,293 @@ > > > > ... > > > > > > + plic0: interrupt-controller@c00 { > > > > + #interrupt-cells = <1>; > > > > + #address-cells = <0>; > > > > + compatible = "sifive,fu540-c000-plic", > > > > + "sifive,plic-1.0.0"; > > > > > > I don't see bindings updated for FU740 PLIC, like > > > "sifive,fu740-c000-plic"? > > > > That's because it is not required. There won't be any difference in driver > code for FU740 plic. > > Are there any driver changes for the drivers that have an updated > fu640-c000-* bindings? I don't see them in the linux-riscv list. Yes, they will be posted soon. - Yash > > > > > ... > > > > > > + eth0: ethernet@1009 { > > > > + compatible = "sifive,fu540-c000-gem"; > > > > > > "sifive,fu740-c000-gem"? > > > > > > > Same reason as above. > > > > Thanks for your review. > > Regards, > Bin
[PATCH v2 1/2] RISC-V: Update l2 cache DT documentation to add support for SiFive FU740
The L2 cache controller in SiFive FU740 has 4 ECC interrupt sources as compared to 3 in FU540. Update the DT documentation accordingly with "compatible" and "interrupt" property changes. Signed-off-by: Yash Shah --- Changes in v2: - Changes as per Rob Herring's request on v1 --- .../devicetree/bindings/riscv/sifive-l2-cache.yaml | 35 -- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/riscv/sifive-l2-cache.yaml b/Documentation/devicetree/bindings/riscv/sifive-l2-cache.yaml index efc0198..749265c 100644 --- a/Documentation/devicetree/bindings/riscv/sifive-l2-cache.yaml +++ b/Documentation/devicetree/bindings/riscv/sifive-l2-cache.yaml @@ -27,6 +27,7 @@ select: items: - enum: - sifive,fu540-c000-ccache +- sifive,fu740-c000-ccache required: - compatible @@ -34,7 +35,9 @@ select: properties: compatible: items: - - const: sifive,fu540-c000-ccache + - enum: + - sifive,fu540-c000-ccache + - sifive,fu740-c000-ccache - const: cache cache-block-size: @@ -53,9 +56,15 @@ properties: interrupts: description: | - Must contain entries for DirError, DataError and DataFail signals. + Must contain 3 entries for FU540 (DirError, DataError and DataFail) or 4 + entries for other chips (DirError, DirFail, DataError, DataFail signals) minItems: 3 -maxItems: 3 +maxItems: 4 +items: + - description: DirError interrupt + - description: DirFail interrupt + - description: DataError interrupt + - description: DataFail interrupt reg: maxItems: 1 @@ -67,6 +76,26 @@ properties: The reference to the reserved-memory for the L2 Loosely Integrated Memory region. The reserved memory node should be defined as per the bindings in reserved-memory.txt. +if: + properties: +compatible: + contains: +const: sifive,fu540-c000-ccache + +then: + properties: +interrupts: + description: | +Must contain entries for DirError, DataError and DataFail signals. + maxItems: 3 + +else: + properties: +interrupts: + description: | +Must contain entries for DirError, DirFail, DataError, DataFail signals. + minItems: 4 + additionalProperties: false required: -- 2.7.4
[PATCH v2 2/2] RISC-V: sifive_l2_cache: Update L2 cache driver to support SiFive FU740
SiFive FU740 has 4 ECC interrupt sources as compared to 3 in FU540. Update the L2 cache controller driver to support this additional interrupt in case of FU740-C000 chip. Signed-off-by: Yash Shah --- drivers/soc/sifive/sifive_l2_cache.c | 49 +++- 1 file changed, 43 insertions(+), 6 deletions(-) diff --git a/drivers/soc/sifive/sifive_l2_cache.c b/drivers/soc/sifive/sifive_l2_cache.c index 44d7e19..4e5e841 100644 --- a/drivers/soc/sifive/sifive_l2_cache.c +++ b/drivers/soc/sifive/sifive_l2_cache.c @@ -17,6 +17,10 @@ #define SIFIVE_L2_DIRECCFIX_HIGH 0x104 #define SIFIVE_L2_DIRECCFIX_COUNT 0x108 +#define SIFIVE_L2_DIRECCFAIL_LOW 0x120 +#define SIFIVE_L2_DIRECCFAIL_HIGH 0x124 +#define SIFIVE_L2_DIRECCFAIL_COUNT 0x128 + #define SIFIVE_L2_DATECCFIX_LOW 0x140 #define SIFIVE_L2_DATECCFIX_HIGH 0x144 #define SIFIVE_L2_DATECCFIX_COUNT 0x148 @@ -29,7 +33,7 @@ #define SIFIVE_L2_WAYENABLE 0x08 #define SIFIVE_L2_ECCINJECTERR 0x40 -#define SIFIVE_L2_MAX_ECCINTR 3 +#define SIFIVE_L2_MAX_ECCINTR 4 static void __iomem *l2_base; static int g_irq[SIFIVE_L2_MAX_ECCINTR]; @@ -37,6 +41,7 @@ static struct riscv_cacheinfo_ops l2_cache_ops; enum { DIR_CORR = 0, + DIR_UNCORR, DATA_CORR, DATA_UNCORR, }; @@ -93,6 +98,7 @@ static void l2_config_read(void) static const struct of_device_id sifive_l2_ids[] = { { .compatible = "sifive,fu540-c000-ccache" }, + { .compatible = "sifive,fu740-c000-ccache" }, { /* end of table */ }, }; @@ -155,6 +161,15 @@ static irqreturn_t l2_int_handler(int irq, void *device) atomic_notifier_call_chain(&l2_err_chain, SIFIVE_L2_ERR_TYPE_CE, "DirECCFix"); } + if (irq == g_irq[DIR_UNCORR]) { + add_h = readl(l2_base + SIFIVE_L2_DIRECCFAIL_HIGH); + add_l = readl(l2_base + SIFIVE_L2_DIRECCFAIL_LOW); + /* Reading this register clears the DirFail interrupt sig */ + readl(l2_base + SIFIVE_L2_DIRECCFAIL_COUNT); + atomic_notifier_call_chain(&l2_err_chain, SIFIVE_L2_ERR_TYPE_UE, + "DirECCFail"); + panic("L2CACHE: DirFail @ 0x%08X.%08X\n", add_h, add_l); + } if (irq == g_irq[DATA_CORR]) { add_h = readl(l2_base + SIFIVE_L2_DATECCFIX_HIGH); add_l = readl(l2_base + SIFIVE_L2_DATECCFIX_LOW); @@ -179,9 +194,9 @@ static irqreturn_t l2_int_handler(int irq, void *device) static int __init sifive_l2_init(void) { + int i, k, rc, intr_num, offset = 0; struct device_node *np; struct resource res; - int i, rc; np = of_find_matching_node(NULL, sifive_l2_ids); if (!np) @@ -194,11 +209,33 @@ static int __init sifive_l2_init(void) if (!l2_base) return -ENOMEM; - for (i = 0; i < SIFIVE_L2_MAX_ECCINTR; i++) { - g_irq[i] = irq_of_parse_and_map(np, i); - rc = request_irq(g_irq[i], l2_int_handler, 0, "l2_ecc", NULL); + intr_num = of_property_count_u32_elems(np, "interrupts"); + if (!intr_num) { + pr_err("L2CACHE: no interrupts property\n"); + return -ENODEV; + } + + /* +* Only FU540 have 3 interrupts. Rest all other variants have +* 4 interrupts (+dirfail). Therefore offset is required to skip +* 'dirfail' interrupt entry in case of FU540 +*/ + if (of_device_is_compatible(np, "sifive,fu540-c000-ccache")) + offset = 1; + + g_irq[0] = irq_of_parse_and_map(np, 0); + rc = request_irq(g_irq[0], l2_int_handler, 0, "l2_ecc", NULL); + if (rc) { + pr_err("L2CACHE: Could not request IRQ %d\n", g_irq[0]); + return rc; + } + + for (i = 1; i < intr_num; i++) { + k = i + offset; + g_irq[k] = irq_of_parse_and_map(np, i); + rc = request_irq(g_irq[k], l2_int_handler, 0, "l2_ecc", NULL); if (rc) { - pr_err("L2CACHE: Could not request IRQ %d\n", g_irq[i]); + pr_err("L2CACHE: Could not request IRQ %d\n", g_irq[k]); return rc; } } -- 2.7.4
RE: [PATCH 1/2] RISC-V: Update l2 cache DT documentation to add support for SiFive FU740
> -Original Message- > From: Rob Herring > Sent: 21 November 2020 18:25 > To: Yash Shah > Cc: Paul Walmsley ( Sifive) ; > pal...@dabbelt.com; a...@eecs.berkeley.edu; > jonathan.came...@huawei.com; w...@kernel.org; s...@ravnborg.org; > Sagar Kadam ; a...@brainfault.org; > b...@suse.de; devicet...@vger.kernel.org; linux-ri...@lists.infradead.org; > linux-kernel@vger.kernel.org; Sachin Ghadi > Subject: Re: [PATCH 1/2] RISC-V: Update l2 cache DT documentation to add > support for SiFive FU740 > > [External Email] Do not click links or attachments unless you recognize the > sender and know the content is safe > > On Thu, Nov 12, 2020 at 02:41:13PM +0530, Yash Shah wrote: > > The L2 cache controller in SiFive FU740 has 4 ECC interrupt sources as > > compared to 3 in FU540. Update the DT documentation accordingly with > > "compatible" and "interrupt" property changes. > > > > Signed-off-by: Yash Shah > > --- > > .../devicetree/bindings/riscv/sifive-l2-cache.yaml | 33 > > +- > > 1 file changed, 26 insertions(+), 7 deletions(-) > > > > diff --git > > a/Documentation/devicetree/bindings/riscv/sifive-l2-cache.yaml > > b/Documentation/devicetree/bindings/riscv/sifive-l2-cache.yaml > > index efc0198..4873d5c 100644 > > --- a/Documentation/devicetree/bindings/riscv/sifive-l2-cache.yaml > > +++ b/Documentation/devicetree/bindings/riscv/sifive-l2-cache.yaml <...> > > @@ -51,12 +54,6 @@ properties: > > > >cache-unified: true > > > > - interrupts: > > -description: | > > - Must contain entries for DirError, DataError and DataFail signals. > > -minItems: 3 > > -maxItems: 3 > > Keep this here and just change maxItems to 4. Really, what each interrupt is > should be listed out as an 'items' entry. > Sure will send a v2 with the above modifications. <...> > > > + > > +else: > > + properties: > > +interrupts: > > + description: | > > +Must contain entries for DirError, DirFail, DataError, DataFail > > signals. > > DirFail should be last so you keep the same indices. Actually, the interrupts have been numbered like that in FU740 SoCs and the driver expects the interrupts to be in this order. I will keep the same order for v2 as well. Let me know if you still disagree. Thanks for your review. - Yash
Re: [PATCH v5 2/2] pwm: sifive: Add a driver for SiFive SoC PWM
On Thu, Feb 7, 2019 at 3:47 PM Uwe Kleine-König wrote: > > Hello, > > On Tue, Jan 29, 2019 at 05:13:19PM +0530, Yash Shah wrote: > > Adds a PWM driver for PWM chip present in SiFive's HiFive Unleashed SoC. > > > > Signed-off-by: Wesley W. Terpstra > > [Atish: Various fixes and code cleanup] > > Signed-off-by: Atish Patra > > Signed-off-by: Yash Shah > > --- > > drivers/pwm/Kconfig | 11 ++ > > drivers/pwm/Makefile | 1 + > > drivers/pwm/pwm-sifive.c | 261 > > +++ > > 3 files changed, 273 insertions(+) > > create mode 100644 drivers/pwm/pwm-sifive.c > > > > diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig > > index a8f47df..4a61d1a 100644 > > --- a/drivers/pwm/Kconfig > > +++ b/drivers/pwm/Kconfig > > @@ -380,6 +380,17 @@ config PWM_SAMSUNG > > To compile this driver as a module, choose M here: the module > > will be called pwm-samsung. > > > > +config PWM_SIFIVE > > + tristate "SiFive PWM support" > > + depends on OF > > + depends on COMMON_CLK > > + depends on RISCV || COMPILE_TEST > > + help > > + Generic PWM framework driver for SiFive SoCs. > > + > > + To compile this driver as a module, choose M here: the module > > + will be called pwm-sifive. > > + > > config PWM_SPEAR > > tristate "STMicroelectronics SPEAr PWM support" > > depends on PLAT_SPEAR > > diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile > > index 9c676a0..30089ca 100644 > > --- a/drivers/pwm/Makefile > > +++ b/drivers/pwm/Makefile > > @@ -37,6 +37,7 @@ obj-$(CONFIG_PWM_RCAR) += pwm-rcar.o > > obj-$(CONFIG_PWM_RENESAS_TPU)+= pwm-renesas-tpu.o > > obj-$(CONFIG_PWM_ROCKCHIP) += pwm-rockchip.o > > obj-$(CONFIG_PWM_SAMSUNG)+= pwm-samsung.o > > +obj-$(CONFIG_PWM_SIFIVE) += pwm-sifive.o > > obj-$(CONFIG_PWM_SPEAR) += pwm-spear.o > > obj-$(CONFIG_PWM_STI)+= pwm-sti.o > > obj-$(CONFIG_PWM_STM32) += pwm-stm32.o > > diff --git a/drivers/pwm/pwm-sifive.c b/drivers/pwm/pwm-sifive.c > > new file mode 100644 > > index 000..2b516f7 > > --- /dev/null > > +++ b/drivers/pwm/pwm-sifive.c > > @@ -0,0 +1,261 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > +/* > > + * Copyright (C) 2017-2018 SiFive > > + * For SiFive's PWM IP block documentation please refer Chapter 14 of > > + * Reference Manual : https://static.dev.sifive.com/FU540-C000-v1.0.pdf > > + */ > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > + > > +/* Register offsets */ > > +#define PWM_SIFIVE_PWMCFG0x0 > > +#define PWM_SIFIVE_PWMCOUNT 0x8 > > +#define PWM_SIFIVE_PWMS 0x10 > > +#define PWM_SIFIVE_PWMCMP0 0x20 > > + > > +/* PWMCFG fields */ > > +#define PWM_SIFIVE_PWMCFG_SCALE 0 > > +#define PWM_SIFIVE_PWMCFG_STICKY 8 > > +#define PWM_SIFIVE_PWMCFG_ZERO_CMP 9 > > +#define PWM_SIFIVE_PWMCFG_DEGLITCH 10 > > +#define PWM_SIFIVE_PWMCFG_EN_ALWAYS 12 > > +#define PWM_SIFIVE_PWMCFG_EN_ONCE13 > > +#define PWM_SIFIVE_PWMCFG_CENTER 16 > > +#define PWM_SIFIVE_PWMCFG_GANG 24 > > +#define PWM_SIFIVE_PWMCFG_IP 28 > > + > > +/* SIZE_PWMCMP is used to calculate the offset for pwmcmpX registers */ > > +#define SIZE_PWMCMP 4 > > +#define CMPWIDTH 16 > > Please add a PWM_SIFIVE_ prefix to these two. Sure > > > +struct pwm_sifive_ddata { > > + struct pwm_chip chip; > > + struct notifier_block notifier; > > + struct clk *clk; > > + void __iomem *regs; > > + unsigned int approx_period; > > + unsigned int real_period; > > +}; > > + > > +static inline struct pwm_sifive_ddata *to_pwm_sifive_chip(struct pwm_chip > > *c) > > even though this is inlined I would like this to have use the > pwm_sifive_ prefix, too. Not sure what exactly you want me to do here. > > > +{ > > + return container_of(c, struct pwm_sifive_ddata, chip); > > +} > > + > > +static void pwm_sifive_get_state(struct pwm_chip *chip, struct pwm_device > > *dev, > > + struct pwm_state *state) > > +{ > > + struct pwm_sifive_ddata *pwm = to_pwm_sifive_chip(chip); > > + u32 duty; > > + > > +
[PATCH v10 0/2] PWM support for HiFive Unleashed
This patch series adds a PWM driver and DT documentation for HiFive Unleashed board. The patches are mostly based on Wesley's patch. v10 - Use DIV_ROUND_CLOSEST_ULL instead of div_u64_round - Change 'num' defination to u64 bit (in pwm_sifive_apply). - Remove the usage of pwm_get_state() v9 - Use appropriate bitfield macros - Add approx_period in pwm_sifive_ddata struct and related changes - Correct the eqn for calculation of frac (in pwm_sifive_apply) - Other minor fixes v8 - Typo corrections - Remove active_user and related code - Do not clear PWM_SIFIVE_PWMCFG_EN_ALWAYS - Other minor fixes v7 - Modify description of compatible property in DT documentation - Use mutex locks at appropriate places - Fix all bad line breaks - Allow enabling/disabling PWM only when the user is the only active user - Remove Deglitch logic - Other minor fixes v6 - Remove the global property 'sifive,period-ns' - Implement free and request callbacks to maintain user counts. - Add user_count member to struct pwm_sifive_ddata - Allow period change only if user_count is one - Add pwm_sifive_enable function to enable/disable PWM - Change calculation logic of frac (in pwm_sifive_apply) - Remove state correction - Remove pwm_sifive_xlate function - Clock to be enabled only when PWM is enabled - Other minor fixes v5 - Correct the order of compatible string properties - PWM state correction to be done always - Other minor fixes based upon feedback on v4 v4 - Rename macros with appropriate names - Remove unused macros - Rename struct sifive_pwm_device to struct pwm_sifive_ddata - Rename function prefix as per driver name - Other minor fixes based upon feedback on v3 v3 - Add a link to the reference manaul - Use appropriate apis for division operation - Add check for polarity - Enable clk before calling clk_get_rate - Other minor fixes based upon feedback on v2 V2 changed from V1: - Remove inclusion of dt-bindings/pwm/pwm.h - Remove artificial alignments - Replace ioread32/iowrite32 with readl/writel - Remove camelcase - Change dev_info to dev_dbg for unnecessary log - Correct typo in driver name - Remove use of of_match_ptr macro - Update the DT compatible strings and Add reference to a common versioning document Yash Shah (2): pwm: sifive: Add DT documentation for SiFive PWM Controller pwm: sifive: Add a driver for SiFive SoC PWM .../devicetree/bindings/pwm/pwm-sifive.txt | 33 ++ drivers/pwm/Kconfig| 11 + drivers/pwm/Makefile | 1 + drivers/pwm/pwm-sifive.c | 334 + 4 files changed, 379 insertions(+) create mode 100644 Documentation/devicetree/bindings/pwm/pwm-sifive.txt create mode 100644 drivers/pwm/pwm-sifive.c -- 1.9.1
[PATCH v10 1/2] pwm: sifive: Add DT documentation for SiFive PWM Controller
DT documentation for PWM controller added. Signed-off-by: Wesley W. Terpstra [Atish: Compatible string update] Signed-off-by: Atish Patra Signed-off-by: Yash Shah Reviewed-by: Rob Herring --- .../devicetree/bindings/pwm/pwm-sifive.txt | 33 ++ 1 file changed, 33 insertions(+) create mode 100644 Documentation/devicetree/bindings/pwm/pwm-sifive.txt diff --git a/Documentation/devicetree/bindings/pwm/pwm-sifive.txt b/Documentation/devicetree/bindings/pwm/pwm-sifive.txt new file mode 100644 index 000..36447e3 --- /dev/null +++ b/Documentation/devicetree/bindings/pwm/pwm-sifive.txt @@ -0,0 +1,33 @@ +SiFive PWM controller + +Unlike most other PWM controllers, the SiFive PWM controller currently only +supports one period for all channels in the PWM. All PWMs need to run at +the same period. The period also has significant restrictions on the values +it can achieve, which the driver rounds to the nearest achievable period. +PWM RTL that corresponds to the IP block version numbers can be found +here: + +https://github.com/sifive/sifive-blocks/tree/master/src/main/scala/devices/pwm + +Required properties: +- compatible: Should be "sifive,-pwm" and "sifive,pwm". + Supported compatible strings are: "sifive,fu540-c000-pwm" for the SiFive + PWM v0 as integrated onto the SiFive FU540 chip, and "sifive,pwm0" for the + SiFive PWM v0 IP block with no chip integration tweaks. + Please refer to sifive-blocks-ip-versioning.txt for details. +- reg: physical base address and length of the controller's registers +- clocks: Should contain a clock identifier for the PWM's parent clock. +- #pwm-cells: Should be 3. See pwm.txt in this directory + for a description of the cell format. +- interrupts: one interrupt per PWM channel + +Examples: + +pwm: pwm@1002 { + compatible = "sifive,fu540-c000-pwm", "sifive,pwm0"; + reg = <0x0 0x1002 0x0 0x1000>; + clocks = <&tlclk>; + interrupt-parent = <&plic>; + interrupts = <42 43 44 45>; + #pwm-cells = <3>; +}; -- 1.9.1
[PATCH v10 2/2] pwm: sifive: Add a driver for SiFive SoC PWM
Adds a PWM driver for PWM chip present in SiFive's HiFive Unleashed SoC. Signed-off-by: Wesley W. Terpstra [Atish: Various fixes and code cleanup] Signed-off-by: Atish Patra Signed-off-by: Yash Shah --- drivers/pwm/Kconfig | 11 ++ drivers/pwm/Makefile | 1 + drivers/pwm/pwm-sifive.c | 334 +++ 3 files changed, 346 insertions(+) create mode 100644 drivers/pwm/pwm-sifive.c diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig index a8f47df..4a61d1a 100644 --- a/drivers/pwm/Kconfig +++ b/drivers/pwm/Kconfig @@ -380,6 +380,17 @@ config PWM_SAMSUNG To compile this driver as a module, choose M here: the module will be called pwm-samsung. +config PWM_SIFIVE + tristate "SiFive PWM support" + depends on OF + depends on COMMON_CLK + depends on RISCV || COMPILE_TEST + help + Generic PWM framework driver for SiFive SoCs. + + To compile this driver as a module, choose M here: the module + will be called pwm-sifive. + config PWM_SPEAR tristate "STMicroelectronics SPEAr PWM support" depends on PLAT_SPEAR diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile index 9c676a0..30089ca 100644 --- a/drivers/pwm/Makefile +++ b/drivers/pwm/Makefile @@ -37,6 +37,7 @@ obj-$(CONFIG_PWM_RCAR)+= pwm-rcar.o obj-$(CONFIG_PWM_RENESAS_TPU) += pwm-renesas-tpu.o obj-$(CONFIG_PWM_ROCKCHIP) += pwm-rockchip.o obj-$(CONFIG_PWM_SAMSUNG) += pwm-samsung.o +obj-$(CONFIG_PWM_SIFIVE) += pwm-sifive.o obj-$(CONFIG_PWM_SPEAR)+= pwm-spear.o obj-$(CONFIG_PWM_STI) += pwm-sti.o obj-$(CONFIG_PWM_STM32)+= pwm-stm32.o diff --git a/drivers/pwm/pwm-sifive.c b/drivers/pwm/pwm-sifive.c new file mode 100644 index 000..4b4d48e --- /dev/null +++ b/drivers/pwm/pwm-sifive.c @@ -0,0 +1,334 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2017-2018 SiFive + * For SiFive's PWM IP block documentation please refer Chapter 14 of + * Reference Manual : https://static.dev.sifive.com/FU540-C000-v1.0.pdf + * + * Limitations: + * - When changing both duty cycle and period, we cannot prevent in + * software that the output might produce a period with mixed + * settings (new period length and old duty cycle). + * - The hardware cannot generate a 100% duty cycle. + * - The hardware generates only inverted output. + */ +#include +#include +#include +#include +#include +#include +#include + +/* Register offsets */ +#define PWM_SIFIVE_PWMCFG 0x0 +#define PWM_SIFIVE_PWMCOUNT0x8 +#define PWM_SIFIVE_PWMS0x10 +#define PWM_SIFIVE_PWMCMP0 0x20 + +/* PWMCFG fields */ +#define PWM_SIFIVE_PWMCFG_SCALEGENMASK(3, 0) +#define PWM_SIFIVE_PWMCFG_STICKY BIT(8) +#define PWM_SIFIVE_PWMCFG_ZERO_CMP BIT(9) +#define PWM_SIFIVE_PWMCFG_DEGLITCH BIT(10) +#define PWM_SIFIVE_PWMCFG_EN_ALWAYSBIT(12) +#define PWM_SIFIVE_PWMCFG_EN_ONCE BIT(13) +#define PWM_SIFIVE_PWMCFG_CENTER BIT(16) +#define PWM_SIFIVE_PWMCFG_GANG BIT(24) +#define PWM_SIFIVE_PWMCFG_IP BIT(28) + +/* PWM_SIFIVE_SIZE_PWMCMP is used to calculate offset for pwmcmpX registers */ +#define PWM_SIFIVE_SIZE_PWMCMP 4 +#define PWM_SIFIVE_CMPWIDTH16 +#define PWM_SIFIVE_DEFAULT_PERIOD 1000 + +struct pwm_sifive_ddata { + struct pwm_chip chip; + struct mutex lock; /* lock to protect user_count */ + struct notifier_block notifier; + struct clk *clk; + void __iomem *regs; + unsigned int real_period; + unsigned int approx_period; + int user_count; +}; + +static inline +struct pwm_sifive_ddata *pwm_sifive_chip_to_ddata(struct pwm_chip *c) +{ + return container_of(c, struct pwm_sifive_ddata, chip); +} + +static int pwm_sifive_request(struct pwm_chip *chip, struct pwm_device *dev) +{ + struct pwm_sifive_ddata *pwm = pwm_sifive_chip_to_ddata(chip); + + mutex_lock(&pwm->lock); + pwm->user_count++; + mutex_unlock(&pwm->lock); + + return 0; +} + +static void pwm_sifive_free(struct pwm_chip *chip, struct pwm_device *dev) +{ + struct pwm_sifive_ddata *pwm = pwm_sifive_chip_to_ddata(chip); + + mutex_lock(&pwm->lock); + pwm->user_count--; + mutex_unlock(&pwm->lock); +} + +static void pwm_sifive_update_clock(struct pwm_sifive_ddata *pwm, + unsigned long rate) +{ + u32 val; + unsigned long long num; + /* +* The PWM unit is used with pwmzerocmp=0, so the only way to modify the +* period length is using pwmscale which provides the number of bits the +* counter is shifted before being feed to the comparators. A period +* lasts (1 << (PWM_SIFIVE_CMPWIDTH + pwmscale)) clock ticks. +* (1 << (PWM
Re: [PATCH v9 0/2] PWM support for HiFive Unleashed
On Mon, Mar 18, 2019 at 10:56 PM Andreas Schwab wrote: > > On Mär 15 2019, Yash Shah wrote: > > > You need to make sure the period setting is passed via the > > conventional way in DT file. > > Example: > > pwmleds { > > compatible = "pwm-leds"; > > heartbeat { > > pwms = <&L45 0 1000 0>; > > max-brightness = <255>; > > linux,default-trigger = "heartbeat"; > > }; > > }; > > I've now managed to build a working FSBL with that change, but that > didn't change anything. There is not even a heartbeat option in > /sys/class/leds/heartbeat/trigger any more. Below is the copy of the pwm nodes in my DTS file: L45: pwm@1002 { compatible = "sifive,pwm0"; interrupt-parent = <&plic0>; interrupts = <42 43 44 45>; reg = <0x0 0x1002 0x0 0x1000>; reg-names = "control"; clocks = <&prci 3>; #pwm-cells = <2>; }; L46: pwm@10021000 { compatible = "sifive,pwm0"; interrupt-parent = <&plic0>; interrupts = <46 47 48 49>; reg = <0x0 0x10021000 0x0 0x1000>; reg-names = "control"; clocks = <&prci 3>; #pwm-cells = <2>; }; pwmleds { compatible = "pwm-leds"; heartbeat { pwms = <&L45 0 1000 0>; max-brightness = <255>; linux,default-trigger = "heartbeat"; }; }; The above works for me. I just noticed that I have been using pwm-cells = 2, instead of 3. Maybe that is the problem here. I will suggest you test it on v11 patch in which I will fix this pwm-cells issue. Thanks for pointing it out. > > Andreas. > > -- > Andreas Schwab, SUSE Labs, sch...@suse.de > GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE 1748 E4D4 88E3 0EEA B9D7 > "And now for something completely different."
Re: [PATCH v10 2/2] pwm: sifive: Add a driver for SiFive SoC PWM
On Tue, Mar 19, 2019 at 3:16 AM Uwe Kleine-König wrote: > > Hello, > > [I put Thierry into To: because some remaining questions depend on his > views] > > On Mon, Mar 18, 2019 at 05:17:14PM +0530, Yash Shah wrote: > > Adds a PWM driver for PWM chip present in SiFive's HiFive Unleashed SoC. > > > > Signed-off-by: Wesley W. Terpstra > > [Atish: Various fixes and code cleanup] > > Signed-off-by: Atish Patra > > Signed-off-by: Yash Shah > > --- > > drivers/pwm/Kconfig | 11 ++ > > drivers/pwm/Makefile | 1 + > > drivers/pwm/pwm-sifive.c | 334 > > +++ > > 3 files changed, 346 insertions(+) > > create mode 100644 drivers/pwm/pwm-sifive.c > > > > diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig > > index a8f47df..4a61d1a 100644 > > --- a/drivers/pwm/Kconfig > > +++ b/drivers/pwm/Kconfig > > @@ -380,6 +380,17 @@ config PWM_SAMSUNG > > To compile this driver as a module, choose M here: the module > > will be called pwm-samsung. > > > > +config PWM_SIFIVE > > + tristate "SiFive PWM support" > > + depends on OF > > + depends on COMMON_CLK > > + depends on RISCV || COMPILE_TEST > > + help > > + Generic PWM framework driver for SiFive SoCs. > > + > > + To compile this driver as a module, choose M here: the module > > + will be called pwm-sifive. > > + > > config PWM_SPEAR > > tristate "STMicroelectronics SPEAr PWM support" > > depends on PLAT_SPEAR > > diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile > > index 9c676a0..30089ca 100644 > > --- a/drivers/pwm/Makefile > > +++ b/drivers/pwm/Makefile > > @@ -37,6 +37,7 @@ obj-$(CONFIG_PWM_RCAR) += pwm-rcar.o > > obj-$(CONFIG_PWM_RENESAS_TPU)+= pwm-renesas-tpu.o > > obj-$(CONFIG_PWM_ROCKCHIP) += pwm-rockchip.o > > obj-$(CONFIG_PWM_SAMSUNG)+= pwm-samsung.o > > +obj-$(CONFIG_PWM_SIFIVE) += pwm-sifive.o > > obj-$(CONFIG_PWM_SPEAR) += pwm-spear.o > > obj-$(CONFIG_PWM_STI)+= pwm-sti.o > > obj-$(CONFIG_PWM_STM32) += pwm-stm32.o > > diff --git a/drivers/pwm/pwm-sifive.c b/drivers/pwm/pwm-sifive.c > > new file mode 100644 > > index 000..4b4d48e > > --- /dev/null > > +++ b/drivers/pwm/pwm-sifive.c > > @@ -0,0 +1,334 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > +/* > > + * Copyright (C) 2017-2018 SiFive > > + * For SiFive's PWM IP block documentation please refer Chapter 14 of > > + * Reference Manual : https://static.dev.sifive.com/FU540-C000-v1.0.pdf > > + * > > + * Limitations: > > + * - When changing both duty cycle and period, we cannot prevent in > > + * software that the output might produce a period with mixed > > + * settings (new period length and old duty cycle). > > + * - The hardware cannot generate a 100% duty cycle. > > + * - The hardware generates only inverted output. > > + */ > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > + > > +/* Register offsets */ > > +#define PWM_SIFIVE_PWMCFG0x0 > > +#define PWM_SIFIVE_PWMCOUNT 0x8 > > +#define PWM_SIFIVE_PWMS 0x10 > > +#define PWM_SIFIVE_PWMCMP0 0x20 > > + > > +/* PWMCFG fields */ > > +#define PWM_SIFIVE_PWMCFG_SCALE GENMASK(3, 0) > > +#define PWM_SIFIVE_PWMCFG_STICKY BIT(8) > > +#define PWM_SIFIVE_PWMCFG_ZERO_CMP BIT(9) > > +#define PWM_SIFIVE_PWMCFG_DEGLITCH BIT(10) > > +#define PWM_SIFIVE_PWMCFG_EN_ALWAYS BIT(12) > > +#define PWM_SIFIVE_PWMCFG_EN_ONCEBIT(13) > > +#define PWM_SIFIVE_PWMCFG_CENTER BIT(16) > > +#define PWM_SIFIVE_PWMCFG_GANG BIT(24) > > +#define PWM_SIFIVE_PWMCFG_IP BIT(28) > > + > > +/* PWM_SIFIVE_SIZE_PWMCMP is used to calculate offset for pwmcmpX > > registers */ > > +#define PWM_SIFIVE_SIZE_PWMCMP 4 > > +#define PWM_SIFIVE_CMPWIDTH 16 > > +#define PWM_SIFIVE_DEFAULT_PERIOD1000 > > + > > +struct pwm_sifive_ddata { > > + struct pwm_chip chip; > > + struct mutex lock; /* lock to protect user_count */ > > + struct notifier_block notifier; > > + struct clk *clk; > > + void __iomem *regs; > > + unsigned int real_period; > > + unsigned int approx_period; > > + int user_coun
[PATCH 0/2] EDAC Support for SiFive SoCs
This patch series adds an EDAC driver and DT documentation for FU540-C000 chip. Initially L2 Cache controller is added as a subcomponent to this driver. This patchset is based on Linux 5.0-rc8 and tested on HiFive Unleashed board with additional board related patches needed for testing can be found at dev/yashs/L2_cache_controller branch of: https://github.com/yashshah7/riscv-linux.git Yash Shah (2): edac: sifive: Add DT documentation for SiFive EDAC driver and subcomponent edac: sifive: Add EDAC driver for SiFive FU540-C000 chip .../devicetree/bindings/edac/sifive-edac.txt | 40 +++ arch/riscv/Kconfig | 1 + drivers/edac/Kconfig | 13 + drivers/edac/Makefile | 1 + drivers/edac/sifive_edac.c | 297 + 5 files changed, 352 insertions(+) create mode 100644 Documentation/devicetree/bindings/edac/sifive-edac.txt create mode 100644 drivers/edac/sifive_edac.c -- 1.9.1
[PATCH 1/2] edac: sifive: Add DT documentation for SiFive EDAC driver and subcomponent
DT documentation for EDAC driver added. DT documentation for subcomponent L2 cache controller also added. Signed-off-by: Yash Shah --- .../devicetree/bindings/edac/sifive-edac.txt | 40 ++ 1 file changed, 40 insertions(+) create mode 100644 Documentation/devicetree/bindings/edac/sifive-edac.txt diff --git a/Documentation/devicetree/bindings/edac/sifive-edac.txt b/Documentation/devicetree/bindings/edac/sifive-edac.txt new file mode 100644 index 000..c0e3ac7 --- /dev/null +++ b/Documentation/devicetree/bindings/edac/sifive-edac.txt @@ -0,0 +1,40 @@ +SiFive ECC Manager +This driver uses the EDAC framework to implement the SiFive ECC Manager. + +Required Properties: +- compatible : Should be "sifive,ecc-manager" +- #address-cells: must be 2 +- #size-cells: must be 2 +- ranges : standard definition, should translate from local addresses + +Subcomponents: + +L2 Cache ECC +Required Properties: +- compatible: Should be "sifive,-ccache" and "sifive,ccache". + Supported compatible strings are: + "sifive,fu540-c000-ccache" for the SiFive cache controller v0 as integrated + onto the SiFive FU540 chip, and "sifive,ccache0" for the SiFive + cache controller v0 IP block with no chip integration tweaks. + Please refer to sifive-blocks-ip-versioning.txt for details +- interrupt-parent: Must be core interrupt controller +- interrupts: Must contain 3 entries (DirError, DataError and DataFail signals +- reg: Physical base address and size of L2 cache controller registers map + A second range can indicate L2 Loosely Integrated Memory + +Example: + +eccmgr: eccmgr { + compatible = "sifive,ecc-manager"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + + l2-ecc@201 { + compatible = "sifive,fu540-c000-ccache", "sifive,ccache0"; + interrupt-parent = <&plic0>; + interrupts = <1 2 3>; + reg = <0x0 0x201 0x0 0x1000 0x0 0x800 0x0 0x200>; + }; +}; + -- 1.9.1
[PATCH 2/2] edac: sifive: Add EDAC driver for SiFive FU540-C000 chip
This EDAC driver supports: - Initial configuration reporting on bootup via debug logs - ECC event monitoring and reporting through the EDAC framework - ECC event injection This driver is partially based on pnd2_edac.c and altera_edac.c Initially L2 Cache controller is added as a subcomponent to this EDAC driver. Signed-off-by: Yash Shah --- arch/riscv/Kconfig | 1 + drivers/edac/Kconfig | 13 ++ drivers/edac/Makefile | 1 + drivers/edac/sifive_edac.c | 297 + 4 files changed, 312 insertions(+) create mode 100644 drivers/edac/sifive_edac.c diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 515fc3c..fede4b6 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -49,6 +49,7 @@ config RISCV select RISCV_TIMER select GENERIC_IRQ_MULTI_HANDLER select ARCH_HAS_PTE_SPECIAL + select EDAC_SUPPORT config MMU def_bool y diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig index e286b5b..112d9d1 100644 --- a/drivers/edac/Kconfig +++ b/drivers/edac/Kconfig @@ -440,6 +440,19 @@ config EDAC_ALTERA_SDMMC Support for error detection and correction on the Altera SDMMC FIFO Memory for Altera SoCs. +config EDAC_SIFIVE + tristate "Sifive ECC" + depends on RISCV + help + Support for error detection and correction on the SiFive SoCs. + +config EDAC_SIFIVE_L2 + bool "SiFive L2 Cache ECC" + depends on EDAC_SIFIVE=y + help + Support for error detection and correction of the L2 cache + memory on SiFive SoCs. + config EDAC_SYNOPSYS tristate "Synopsys DDR Memory Controller" depends on ARCH_ZYNQ || ARCH_ZYNQMP diff --git a/drivers/edac/Makefile b/drivers/edac/Makefile index 716096d..b16dce8 100644 --- a/drivers/edac/Makefile +++ b/drivers/edac/Makefile @@ -74,6 +74,7 @@ obj-$(CONFIG_EDAC_OCTEON_PCI) += octeon_edac-pci.o obj-$(CONFIG_EDAC_THUNDERX)+= thunderx_edac.o obj-$(CONFIG_EDAC_ALTERA) += altera_edac.o +obj-$(CONFIG_EDAC_SIFIVE) += sifive_edac.o obj-$(CONFIG_EDAC_SYNOPSYS)+= synopsys_edac.o obj-$(CONFIG_EDAC_XGENE) += xgene_edac.o obj-$(CONFIG_EDAC_TI) += ti_edac.o diff --git a/drivers/edac/sifive_edac.c b/drivers/edac/sifive_edac.c new file mode 100644 index 000..e11ae6b5 --- /dev/null +++ b/drivers/edac/sifive_edac.c @@ -0,0 +1,297 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * SiFive EDAC Driver + * + * Copyright (C) 2018-2019 SiFive, Inc. + * + */ +#include +#include +#include +#include +#include +#include +#include "edac_module.h" + +#define SIFIVE_EDAC_DIRFIX_LOW 0x100 +#define SIFIVE_EDAC_DIRFIX_HIGH 0x104 +#define SIFIVE_EDAC_DIRFIX_COUNT 0x108 + +#define SIFIVE_EDAC_DATFIX_LOW 0x140 +#define SIFIVE_EDAC_DATFIX_HIGH 0x144 +#define SIFIVE_EDAC_DATFIX_COUNT 0x148 + +#define SIFIVE_EDAC_DATFAIL_LOW 0x160 +#define SIFIVE_EDAC_DATFAIL_HIGH 0x164 +#define SIFIVE_EDAC_DATFAIL_COUNT 0x168 + +#define SIFIVE_EDAC_ECCINJECTERR 0x40 +#define SIFIVE_EDAC_CONFIG 0x00 + +#define SIFIVE_EDAC_MAX_INTR 3 + +/* EDAC Parent Probe */ + +static const struct of_device_id sifive_edac_device_of_match[]; + +static const struct of_device_id sifive_edac_of_match[] = { + { .compatible = "sifive,ecc-manager" }, + {}, +}; +MODULE_DEVICE_TABLE(of, sifive_edac_of_match); + +static int sifive_edac_probe(struct platform_device *pdev) +{ + of_platform_populate(pdev->dev.of_node, sifive_edac_device_of_match, +NULL, &pdev->dev); + return 0; +} + +static struct platform_driver sifive_edac_driver = { + .probe = sifive_edac_probe, + .driver = { + .name = "ecc_manager", + .of_match_table = sifive_edac_of_match, + }, +}; +module_platform_driver(sifive_edac_driver); + +struct sifive_edac_device_prv { + void (*setup)(struct edac_device_ctl_info *dci); + irqreturn_t (*ecc_irq_handler)(int irq, void *dev_id); + const struct file_operations *inject_fops; +}; + +struct sifive_edac_device_dev { + void __iomem *base; + int irq[SIFIVE_EDAC_MAX_INTR]; + struct sifive_edac_device_prv *data; + char *edac_dev_name; +}; + +enum { + dir_corr = 0, + data_corr, + data_uncorr, +}; + +static struct dentry *sifive_edac_test; + +static ssize_t sifive_edac_l2_write(struct file *file, const char __user *data, + size_t count, loff_t *ppos) +{ + struct edac_device_ctl_info *dci = file->private_data; + struct sifive_edac_device_dev *drvdata = dci->pvt_info; + unsigned int val; + + if (kstrtouint_from_user(data, count, 0, &val)) + return -EINVAL; + if ((val >= 0 &&
Re: [PATCH] riscv: dts: Add DT support for SiFive FU540 PWM driver
Hi, Any comments on this patch? - Yash On Wed, Aug 21, 2019 at 2:53 PM Yash Shah wrote: > > Add the PWM DT node in SiFive FU540 soc-specific DT file. > Enable the PWM nodes in HiFive Unleashed board-specific DT file. > > Signed-off-by: Yash Shah > --- > arch/riscv/boot/dts/sifive/fu540-c000.dtsi | 19 +++ > arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts | 8 > 2 files changed, 27 insertions(+) > > diff --git a/arch/riscv/boot/dts/sifive/fu540-c000.dtsi > b/arch/riscv/boot/dts/sifive/fu540-c000.dtsi > index 42b5ec2..bb422db 100644 > --- a/arch/riscv/boot/dts/sifive/fu540-c000.dtsi > +++ b/arch/riscv/boot/dts/sifive/fu540-c000.dtsi > @@ -230,6 +230,25 @@ > #size-cells = <0>; > status = "disabled"; > }; > + pwm0: pwm@1002 { > + compatible = "sifive,pwm0"; > + reg = <0x0 0x1002 0x0 0x1000>; > + interrupt-parent = <&plic0>; > + interrupts = <42 43 44 45>; > + clocks = <&prci PRCI_CLK_TLCLK>; > + #pwm-cells = <3>; > + status = "disabled"; > + }; > + pwm1: pwm@10021000 { > + compatible = "sifive,pwm0"; > + reg = <0x0 0x10021000 0x0 0x1000>; > + interrupt-parent = <&plic0>; > + interrupts = <46 47 48 49>; > + reg-names = "control"; > + clocks = <&prci PRCI_CLK_TLCLK>; > + #pwm-cells = <3>; > + status = "disabled"; > + }; > > }; > }; > diff --git a/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts > b/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts > index 93d68cb..104d334 100644 > --- a/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts > +++ b/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts > @@ -85,3 +85,11 @@ > reg = <0>; > }; > }; > + > +&pwm0 { > + status = "okay"; > +}; > + > +&pwm1 { > + status = "okay"; > +}; > -- > 1.9.1 >
Re: [PATCH v2 0/2] Update ethernet compatible string for SiFive FU540
On Thu, Aug 29, 2019 at 2:36 AM David Miller wrote: > > From: Yash Shah > Date: Tue, 27 Aug 2019 10:36:02 +0530 > > > This patch series renames the compatible property to a more appropriate > > string. The patchset is based on Linux-5.3-rc6 and tested on SiFive > > Unleashed board > > You should always base changes off of "net" or "net-next" and be explicitly > in your Subject lines which of those two trees your changes are for f.e.: > > Subject: [PATCH v2 net-next N/M] ... I will keep this in mind for future patches. > > > > > Change history: > > Since v1: > > - Dropped PATCH3 because it's already merged > > - Change the reference url in the patch descriptions to point to a > > 'lore.kernel.org' link instead of 'lkml.org' > > Series applied to 'net'. Thanks! - Yash
[PATCH] riscv: dts: Add DT support for SiFive FU540 PWM driver
Add the PWM DT node in SiFive FU540 soc-specific DT file. Enable the PWM nodes in HiFive Unleashed board-specific DT file. Signed-off-by: Yash Shah --- arch/riscv/boot/dts/sifive/fu540-c000.dtsi | 19 +++ arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts | 8 2 files changed, 27 insertions(+) diff --git a/arch/riscv/boot/dts/sifive/fu540-c000.dtsi b/arch/riscv/boot/dts/sifive/fu540-c000.dtsi index 42b5ec2..bb422db 100644 --- a/arch/riscv/boot/dts/sifive/fu540-c000.dtsi +++ b/arch/riscv/boot/dts/sifive/fu540-c000.dtsi @@ -230,6 +230,25 @@ #size-cells = <0>; status = "disabled"; }; + pwm0: pwm@1002 { + compatible = "sifive,pwm0"; + reg = <0x0 0x1002 0x0 0x1000>; + interrupt-parent = <&plic0>; + interrupts = <42 43 44 45>; + clocks = <&prci PRCI_CLK_TLCLK>; + #pwm-cells = <3>; + status = "disabled"; + }; + pwm1: pwm@10021000 { + compatible = "sifive,pwm0"; + reg = <0x0 0x10021000 0x0 0x1000>; + interrupt-parent = <&plic0>; + interrupts = <46 47 48 49>; + reg-names = "control"; + clocks = <&prci PRCI_CLK_TLCLK>; + #pwm-cells = <3>; + status = "disabled"; + }; }; }; diff --git a/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts b/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts index 93d68cb..104d334 100644 --- a/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts +++ b/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts @@ -85,3 +85,11 @@ reg = <0>; }; }; + +&pwm0 { + status = "okay"; +}; + +&pwm1 { + status = "okay"; +}; -- 1.9.1
[PATCH v2 1/2] macb: bindings doc: update sifive fu540-c000 binding
As per the discussion with Nicolas Ferre[0], rename the compatible property to a more appropriate and specific string. [0] https://lore.kernel.org/netdev/caj2_jofevzqat0yprg4hem4jrrqkb72fkseqj4p8p5ka-+r...@mail.gmail.com/ Signed-off-by: Yash Shah Acked-by: Nicolas Ferre Reviewed-by: Paul Walmsley Reviewed-by: Rob Herring --- Documentation/devicetree/bindings/net/macb.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/net/macb.txt b/Documentation/devicetree/bindings/net/macb.txt index 63c73fa..0b61a90 100644 --- a/Documentation/devicetree/bindings/net/macb.txt +++ b/Documentation/devicetree/bindings/net/macb.txt @@ -15,10 +15,10 @@ Required properties: Use "atmel,sama5d4-gem" for the GEM IP (10/100) available on Atmel sama5d4 SoCs. Use "cdns,zynq-gem" Xilinx Zynq-7xxx SoC. Use "cdns,zynqmp-gem" for Zynq Ultrascale+ MPSoC. - Use "sifive,fu540-macb" for SiFive FU540-C000 SoC. + Use "sifive,fu540-c000-gem" for SiFive FU540-C000 SoC. Or the generic form: "cdns,emac". - reg: Address and length of the register set for the device - For "sifive,fu540-macb", second range is required to specify the + For "sifive,fu540-c000-gem", second range is required to specify the address and length of the registers for GEMGXL Management block. - interrupts: Should contain macb interrupt - phy-mode: See ethernet.txt file in the same directory. -- 1.9.1
[PATCH v2 0/2] Update ethernet compatible string for SiFive FU540
This patch series renames the compatible property to a more appropriate string. The patchset is based on Linux-5.3-rc6 and tested on SiFive Unleashed board Change history: Since v1: - Dropped PATCH3 because it's already merged - Change the reference url in the patch descriptions to point to a 'lore.kernel.org' link instead of 'lkml.org' Yash Shah (2): macb: bindings doc: update sifive fu540-c000 binding macb: Update compatibility string for SiFive FU540-C000 Documentation/devicetree/bindings/net/macb.txt | 4 ++-- drivers/net/ethernet/cadence/macb_main.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) -- 1.9.1
[PATCH v2 2/2] macb: Update compatibility string for SiFive FU540-C000
Update the compatibility string for SiFive FU540-C000 as per the new string updated in the binding doc. Reference: https://lore.kernel.org/netdev/caj2_jofevzqat0yprg4hem4jrrqkb72fkseqj4p8p5ka-+r...@mail.gmail.com/ Signed-off-by: Yash Shah Acked-by: Nicolas Ferre Reviewed-by: Paul Walmsley Tested-by: Paul Walmsley --- drivers/net/ethernet/cadence/macb_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c index 5ca17e6..35b59b5 100644 --- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c @@ -4154,7 +4154,7 @@ static int fu540_c000_init(struct platform_device *pdev) { .compatible = "cdns,emac", .data = &emac_config }, { .compatible = "cdns,zynqmp-gem", .data = &zynqmp_config}, { .compatible = "cdns,zynq-gem", .data = &zynq_config }, - { .compatible = "sifive,fu540-macb", .data = &fu540_c000_config }, + { .compatible = "sifive,fu540-c000-gem", .data = &fu540_c000_config }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, macb_dt_ids); -- 1.9.1
Re: [PATCH] riscv: dts: Add DT support for SiFive FU540 PWM driver
On Sat, Sep 14, 2019 at 2:50 AM Palmer Dabbelt wrote: > > On Tue, 10 Sep 2019 02:52:07 PDT (-0700), yash.s...@sifive.com wrote: > > Hi, > > > > Any comments on this patch? > > I don't see "sifive,pwm0" in the DT bindings documentation, and it doesn't > match our standard way of doing these things (which would have at least > "sifive,fu540-c000-pwm"). "sifive,pwm0" is present in the DT bindings documentation at Documentation/devicetree/bindings/pwm/pwm-sifive.txt Yes, I agree that this patch is missing "sifive,fu540-c000-pwm". I will add it along with "sifive,pwm0" and repost as version 2. Thanks for your comment. - Yash > > > > > - Yash > > > > On Wed, Aug 21, 2019 at 2:53 PM Yash Shah wrote: > >> > >> Add the PWM DT node in SiFive FU540 soc-specific DT file. > >> Enable the PWM nodes in HiFive Unleashed board-specific DT file. > >> > >> Signed-off-by: Yash Shah > >> --- > >> arch/riscv/boot/dts/sifive/fu540-c000.dtsi | 19 > >> +++ > >> arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts | 8 > >> 2 files changed, 27 insertions(+) > >> > >> diff --git a/arch/riscv/boot/dts/sifive/fu540-c000.dtsi > >> b/arch/riscv/boot/dts/sifive/fu540-c000.dtsi > >> index 42b5ec2..bb422db 100644 > >> --- a/arch/riscv/boot/dts/sifive/fu540-c000.dtsi > >> +++ b/arch/riscv/boot/dts/sifive/fu540-c000.dtsi > >> @@ -230,6 +230,25 @@ > >> #size-cells = <0>; > >> status = "disabled"; > >> }; > >> + pwm0: pwm@1002 { > >> + compatible = "sifive,pwm0"; > >> + reg = <0x0 0x1002 0x0 0x1000>; > >> + interrupt-parent = <&plic0>; > >> + interrupts = <42 43 44 45>; > >> + clocks = <&prci PRCI_CLK_TLCLK>; > >> + #pwm-cells = <3>; > >> + status = "disabled"; > >> + }; > >> + pwm1: pwm@10021000 { > >> + compatible = "sifive,pwm0"; > >> + reg = <0x0 0x10021000 0x0 0x1000>; > >> + interrupt-parent = <&plic0>; > >> + interrupts = <46 47 48 49>; > >> + reg-names = "control"; > >> + clocks = <&prci PRCI_CLK_TLCLK>; > >> + #pwm-cells = <3>; > >> + status = "disabled"; > >> + }; > >> > >> }; > >> }; > >> diff --git a/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts > >> b/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts > >> index 93d68cb..104d334 100644 > >> --- a/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts > >> +++ b/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts > >> @@ -85,3 +85,11 @@ > >> reg = <0>; > >> }; > >> }; > >> + > >> +&pwm0 { > >> + status = "okay"; > >> +}; > >> + > >> +&pwm1 { > >> + status = "okay"; > >> +}; > >> -- > >> 1.9.1 > >>
Re: [PATCH] riscv: move sifive_l2_cache.c to drivers/soc
On Mon, Aug 19, 2019 at 11:56 AM Christoph Hellwig wrote: > > On Mon, Aug 19, 2019 at 08:09:04AM +0200, Borislav Petkov wrote: > > On Sun, Aug 18, 2019 at 10:29:35AM +0200, Christoph Hellwig wrote: > > > The sifive_l2_cache.c is in no way related to RISC-V architecture > > > memory management. It is a little stub driver working around the fact > > > that the EDAC maintainers prefer their drivers to be structured in a > > > certain way > > > > That changed recently so I guess we can do the per-IP block driver after > > all, if people would still prefer it. > > That would seem like the best idea. But I don't really know this code > well enough myself, and I really need to get this code out of the > forced on RISC-V codebase as some SOCs I'm working with simply don't > have the memory for it.. > > So unless someone signs up to do a per-IP block edac drivers instead > very quickly I'd still like to see something like this go into 5.4 > for now. As of now, we can pull this patch into 5.4. Later, I will review if per-IP block edac driver is needed and if so, will take care of implementing it. - Yash
Re: [PATCH 1/2] net/macb: bindings doc: add sifive fu540-c000 binding
On Mon, Jun 24, 2019 at 9:08 PM wrote: > > On 23/05/2019 at 22:50, Rob Herring wrote: > > On Thu, May 23, 2019 at 6:46 AM Yash Shah wrote: > >> > >> Add the compatibility string documentation for SiFive FU540-C > >> interface. > >> On the FU540, this driver also needs to read and write registers in a > >> management IP block that monitors or drives boundary signals for the > >> GEMGXL IP block that are not directly mapped to GEMGXL registers. > >> Therefore, add additional range to "reg" property for SiFive GEMGXL > >> management IP registers. > >> > >> Signed-off-by: Yash Shah > >> --- > >> Documentation/devicetree/bindings/net/macb.txt | 3 +++ > >> 1 file changed, 3 insertions(+) > >> > >> diff --git a/Documentation/devicetree/bindings/net/macb.txt > >> b/Documentation/devicetree/bindings/net/macb.txt > >> index 9c5e944..91a2a66 100644 > >> --- a/Documentation/devicetree/bindings/net/macb.txt > >> +++ b/Documentation/devicetree/bindings/net/macb.txt > >> @@ -4,6 +4,7 @@ Required properties: > >> - compatible: Should be "cdns,[-]{macb|gem}" > >> Use "cdns,at91rm9200-emac" Atmel at91rm9200 SoC. > >> Use "cdns,at91sam9260-macb" for Atmel at91sam9 SoCs. > >> + Use "cdns,fu540-macb" for SiFive FU540-C000 SoC. > > > > This pattern that Atmel started isn't really correct. The vendor > > prefix here should be sifive. 'cdns' would be appropriate for a > > fallback. > > Ok, we missed this for the sam9x60 SoC that we added recently then. > > Anyway a little too late, coming back to this machine, and talking to > Yash, isn't "sifive,fu540-c000-macb" more specific and a better match > for being future proof? I would advice for the most specific possible > with other compatible strings on the same line in the DT, like: > > "sifive,fu540-c000-macb", "sifive,fu540-macb" > Yes, I agree that "sifive,fu540-c000-macb" is a better match. > Moreover, is it really a "macb" or a "gem" type of interface from > Cadence? Not a big deal, but just to discuss the topic to the bone... I believe it should be "gem". I will plan to submit the patch for these changes. Thanks for pointing it out. - Yash > > Note that I'm fine if you consider that what you have in net-next new is > correct. > > Regards, >Nicolas > > >> Use "cdns,sam9x60-macb" for Microchip sam9x60 SoC. > >> Use "cdns,np4-macb" for NP4 SoC devices. > >> Use "cdns,at32ap7000-macb" for other 10/100 usage or use the generic > >> form: "cdns,macb". > >> @@ -17,6 +18,8 @@ Required properties: > >> Use "cdns,zynqmp-gem" for Zynq Ultrascale+ MPSoC. > >> Or the generic form: "cdns,emac". > >> - reg: Address and length of the register set for the device > >> + For "cdns,fu540-macb", second range is required to specify the > >> + address and length of the registers for GEMGXL Management block. > >> - interrupts: Should contain macb interrupt > >> - phy-mode: See ethernet.txt file in the same directory. > >> - clock-names: Tuple listing input clock names. > >> -- > >> 1.9.1 > >> > > > > > -- > Nicolas Ferre
Re: [PATCH v6 2/2] pwm: sifive: Add a driver for SiFive SoC PWM
On Wed, Feb 13, 2019 at 4:05 PM Uwe Kleine-König wrote: > > Hello, > > On Wed, Feb 13, 2019 at 02:56:18PM +0530, Yash Shah wrote: > > Adds a PWM driver for PWM chip present in SiFive's HiFive Unleashed SoC. > > > > Signed-off-by: Wesley W. Terpstra > > [Atish: Various fixes and code cleanup] > > Signed-off-by: Atish Patra > > Signed-off-by: Yash Shah > > --- > > drivers/pwm/Kconfig | 11 ++ > > drivers/pwm/Makefile | 1 + > > drivers/pwm/pwm-sifive.c | 311 > > +++ > > 3 files changed, 323 insertions(+) > > create mode 100644 drivers/pwm/pwm-sifive.c > > > > diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig > > index a8f47df..4a61d1a 100644 > > --- a/drivers/pwm/Kconfig > > +++ b/drivers/pwm/Kconfig > > @@ -380,6 +380,17 @@ config PWM_SAMSUNG > > To compile this driver as a module, choose M here: the module > > will be called pwm-samsung. > > > > +config PWM_SIFIVE > > + tristate "SiFive PWM support" > > + depends on OF > > + depends on COMMON_CLK > > + depends on RISCV || COMPILE_TEST > > + help > > + Generic PWM framework driver for SiFive SoCs. > > + > > + To compile this driver as a module, choose M here: the module > > + will be called pwm-sifive. > > + > > config PWM_SPEAR > > tristate "STMicroelectronics SPEAr PWM support" > > depends on PLAT_SPEAR > > diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile > > index 9c676a0..30089ca 100644 > > --- a/drivers/pwm/Makefile > > +++ b/drivers/pwm/Makefile > > @@ -37,6 +37,7 @@ obj-$(CONFIG_PWM_RCAR) += pwm-rcar.o > > obj-$(CONFIG_PWM_RENESAS_TPU)+= pwm-renesas-tpu.o > > obj-$(CONFIG_PWM_ROCKCHIP) += pwm-rockchip.o > > obj-$(CONFIG_PWM_SAMSUNG)+= pwm-samsung.o > > +obj-$(CONFIG_PWM_SIFIVE) += pwm-sifive.o > > obj-$(CONFIG_PWM_SPEAR) += pwm-spear.o > > obj-$(CONFIG_PWM_STI)+= pwm-sti.o > > obj-$(CONFIG_PWM_STM32) += pwm-stm32.o > > diff --git a/drivers/pwm/pwm-sifive.c b/drivers/pwm/pwm-sifive.c > > new file mode 100644 > > index 000..c0eb90e > > --- /dev/null > > +++ b/drivers/pwm/pwm-sifive.c > > @@ -0,0 +1,311 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > +/* > > + * Copyright (C) 2017-2018 SiFive > > + * For SiFive's PWM IP block documentation please refer Chapter 14 of > > + * Reference Manual : https://static.dev.sifive.com/FU540-C000-v1.0.pdf > > + */ > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > + > > +/* Register offsets */ > > +#define PWM_SIFIVE_PWMCFG0x0 > > +#define PWM_SIFIVE_PWMCOUNT 0x8 > > +#define PWM_SIFIVE_PWMS 0x10 > > +#define PWM_SIFIVE_PWMCMP0 0x20 > > + > > +/* PWMCFG fields */ > > +#define PWM_SIFIVE_PWMCFG_SCALE 0 > > +#define PWM_SIFIVE_PWMCFG_STICKY 8 > > +#define PWM_SIFIVE_PWMCFG_ZERO_CMP 9 > > +#define PWM_SIFIVE_PWMCFG_DEGLITCH 10 > > +#define PWM_SIFIVE_PWMCFG_EN_ALWAYS 12 > > PWM_SIFIVE_PWMCFG_EN_ALWAYS is always used as > > BIT(PWM_SIFIVE_PWMCFG_EN_ALWAYS) > > so defining this as BIT(12) directly makes some expressions below easier > to read. Sure, will do that. > > > +#define PWM_SIFIVE_PWMCFG_EN_ONCE13 > > +#define PWM_SIFIVE_PWMCFG_CENTER 16 > > +#define PWM_SIFIVE_PWMCFG_GANG 24 > > +#define PWM_SIFIVE_PWMCFG_IP 28 > > + > > +/* PWM_SIFIVE_SIZE_PWMCMP is used to calculate offset for pwmcmpX > > registers */ > > +#define PWM_SIFIVE_SIZE_PWMCMP 4 > > +#define PWM_SIFIVE_CMPWIDTH 16 > > + > > +struct pwm_sifive_ddata { > > + struct pwm_chip chip; > > + struct notifier_block notifier; > > + struct clk *clk; > > + void __iomem *regs; > > + unsigned int real_period; > > + int user_count; > > +}; > > + > > +static inline > > +struct pwm_sifive_ddata *pwm_sifive_chip_to_ddata(struct pwm_chip *c) > > +{ > > + return container_of(c, struct pwm_sifive_ddata, chip); > > +} > > + > > +static int pwm_sifive_request(struct pwm_chip *chip, struct pwm_device > > *dev) > > +{ > > + struct pwm_sifive_ddata *pwm = pwm_sifive_chip_to_ddata(chip); > > + > > + pwm->user_count++; > >
Re: [PATCH v6 1/2] pwm: sifive: Add DT documentation for SiFive PWM Controller
On Thu, Feb 14, 2019 at 2:07 AM Rob Herring wrote: > > On Wed, Feb 13, 2019 at 02:56:17PM +0530, Yash Shah wrote: > > DT documentation for PWM controller added. > > > > Signed-off-by: Wesley W. Terpstra > > [Atish: Compatible string update] > > Signed-off-by: Atish Patra > > Signed-off-by: Yash Shah > > --- > > .../devicetree/bindings/pwm/pwm-sifive.txt | 30 > > ++ > > 1 file changed, 30 insertions(+) > > create mode 100644 Documentation/devicetree/bindings/pwm/pwm-sifive.txt > > > > diff --git a/Documentation/devicetree/bindings/pwm/pwm-sifive.txt > > b/Documentation/devicetree/bindings/pwm/pwm-sifive.txt > > new file mode 100644 > > index 000..3b9c64c > > --- /dev/null > > +++ b/Documentation/devicetree/bindings/pwm/pwm-sifive.txt > > @@ -0,0 +1,30 @@ > > +SiFive PWM controller > > + > > +Unlike most other PWM controllers, the SiFive PWM controller currently only > > +supports one period for all channels in the PWM. All PWMs need to run at > > +the same period. The period also has significant restrictions on the values > > +it can achieve, which the driver rounds to the nearest achievable period. > > +PWM RTL that corresponds to the IP block version numbers can be found > > +here: > > + > > +https://github.com/sifive/sifive-blocks/tree/master/src/main/scala/devices/pwm > > + > > +Required properties: > > +- compatible: Should be "sifive,$socname-pwm" and "sifive,pwmX". > > + Please refer to sifive-blocks-ip-versioning.txt for details. > > Please specify what soc and IP version are used. Is sifive,pwm10 valid? Does the below description seem fine? should be "sifive,-pwm" and "sifive,pwm". Supported compatible strings are: "sifive,fu540-c000-pwm" for the SiFive PWM v0 as integrated onto the SiFive FU540 chip, and "sifive,pwm0" for the SiFive PWM v0 IP block with no chip integration tweaks. Please refer to sifive-blocks-ip-versioning.txt for details > > > +- reg: physical base address and length of the controller's registers > > +- clocks: Should contain a clock identifier for the PWM's parent clock. > > +- #pwm-cells: Should be 3. See pwm.txt in this directory > > + for a description of the cell format. > > +- interrupts: one interrupt per PWM channel > > + > > +Examples: > > + > > +pwm: pwm@1002 { > > + compatible = "sifive,fu540-c000-pwm", "sifive,pwm0"; > > + reg = <0x0 0x1002 0x0 0x1000>; > > + clocks = <&tlclk>; > > + interrupt-parent = <&plic>; > > + interrupts = <42 43 44 45>; > > + #pwm-cells = <3>; > > +}; > > -- > > 1.9.1 > > Thanks for the comment
Re: [PATCH v6 2/2] pwm: sifive: Add a driver for SiFive SoC PWM
On Thu, Feb 14, 2019 at 2:04 PM Uwe Kleine-König wrote: > > Hello, > > On Thu, Feb 14, 2019 at 01:25:27PM +0530, Yash Shah wrote: > > On Wed, Feb 13, 2019 at 4:05 PM Uwe Kleine-König > > wrote: > > > On Wed, Feb 13, 2019 at 02:56:18PM +0530, Yash Shah wrote: > > > > +static int pwm_sifive_enable(struct pwm_chip *chip, struct pwm_device > > > > *dev, > > > > + bool enable) > > > > +{ > > > > + struct pwm_sifive_ddata *pwm = pwm_sifive_chip_to_ddata(chip); > > > > + u32 val; > > > > + int ret; > > > > + > > > > + if (enable) { > > > > + ret = clk_enable(pwm->clk); > > > > + if (ret) { > > > > + dev_err(pwm->chip.dev, "Enable clk failed:%d\n", > > > > ret); > > > > + return ret; > > > > + } > > > > + } > > > > + > > > > + val = readl(pwm->regs + PWM_SIFIVE_PWMCFG); > > > > + > > > > + if (enable) > > > > + val |= BIT(PWM_SIFIVE_PWMCFG_EN_ALWAYS); > > > > + else > > > > + val &= ~BIT(PWM_SIFIVE_PWMCFG_EN_ALWAYS); > > > > + > > > > + writel(val, pwm->regs + PWM_SIFIVE_PWMCFG); > > > > + > > > > + if (!enable) > > > > + clk_disable(pwm->clk); > > > > > > A disabled PWM is supposed to output an inactive signal. If the PWM runs > > > at (near) 100% and you disable it, does it reliably give that inactive > > > signal after completing the currently running period? > > > > Yes, you are right, it just freezes at that state (100%). > > What if I set duty cycle = 0 if (!state->enabled) before disabling the PWM? > > Then you only need to be sure that the inactive level is already latched > to the pwmcmpXip output (which should only need one clock cycle if I'm > not mistaken) before disabling the clock. > > > > > + return 0; > > > > +} > > > > + > > > > +static int pwm_sifive_apply(struct pwm_chip *chip, struct pwm_device > > > > *dev, > > > > + struct pwm_state *state) > > > > +{ > > > > + struct pwm_sifive_ddata *pwm = pwm_sifive_chip_to_ddata(chip); > > > > + unsigned int duty_cycle; > > > > + u32 frac, val; > > > > + struct pwm_state cur_state; > > > > + bool enabled; > > > > + int ret; > > > > + > > > > + pwm_get_state(dev, &cur_state); > > > > + enabled = cur_state.enabled; > > > > + > > > > + if (state->polarity != PWM_POLARITY_INVERSED) > > > > + return -EINVAL; > > > > + > > > > + if (state->period != cur_state.period) { > > > > + if (pwm->user_count != 1) > > > > + return -EINVAL; > > > > > > I think we need locking here. Consider two pwm users on two CPUs: > > > > > > CPU1CPU2 > > > pwm_sifive_apply(pwm0, period=A, ...) > > > check user_count==1 -> good > > > ...pwm1 = pwm_get(...) > > > ...pwm_sifive_apply(pwm1, > > > period=B...) > > > ... configure based on B > > > pwm_sifive_update_clock() > > > > mutex_lock(); > > if (pwm->user_count != 1) > > return -EINVAL; > > mutex_unlock(); > > Something like this? > > No, the lock needs to protect more. You must at least cover increasing > and decreasing of user_count and you must hold the lock until the period > update is completed. Got your point. Will use locks at appropriate places > > > > Also I wonder if we should change the period if the user requested > > > enabled=false. > > > > You want me to NOT update period if enabled=false, right? > > I don't know for sure. Given that period is shared for all four PWM > outputs it might be sensible to change it at least in a shadow variable > and only do it when actually needed. (But maybe we can postpone that as > it doesn't matter for correctness of the driver.) > > The question here is: In the following snippet: > > pwm0 = p
[PATCH 0/2] SPI support for HiFive Unleashed
This patch series adds a SPI driver and DT documentation for HiFive Unleashed board. Yash Shah (2): spi: sifive: Add DT documentation for SiFive SPI controller spi: sifive: Add driver for the SiFive SPI controller .../devicetree/bindings/spi/spi-sifive.txt | 37 ++ drivers/spi/Kconfig| 6 + drivers/spi/Makefile | 1 + drivers/spi/spi-sifive.c | 450 + 4 files changed, 494 insertions(+) create mode 100644 Documentation/devicetree/bindings/spi/spi-sifive.txt create mode 100644 drivers/spi/spi-sifive.c -- 1.9.1
[PATCH 2/2] spi: sifive: Add driver for the SiFive SPI controller
Add driver for the SiFive SPI controller on the HiFive Unleashed board. Signed-off-by: Palmer Dabbelt Signed-off-by: Emil Renner Berthing Signed-off-by: Yash Shah --- drivers/spi/Kconfig | 6 + drivers/spi/Makefile | 1 + drivers/spi/spi-sifive.c | 450 +++ 3 files changed, 457 insertions(+) create mode 100644 drivers/spi/spi-sifive.c diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 9f89cb1..f129343 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -631,6 +631,12 @@ config SPI_SH_HSPI help SPI driver for SuperH HSPI blocks. +config SPI_SIFIVE + tristate "SiFive SPI controller" + depends on HAS_IOMEM + help + This exposes the SPI controller IP from SiFive. + config SPI_SIRF tristate "CSR SiRFprimaII SPI controller" depends on SIRF_DMA diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index f296270..7afdc97 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -93,6 +93,7 @@ obj-$(CONFIG_SPI_SH) += spi-sh.o obj-$(CONFIG_SPI_SH_HSPI) += spi-sh-hspi.o obj-$(CONFIG_SPI_SH_MSIOF) += spi-sh-msiof.o obj-$(CONFIG_SPI_SH_SCI) += spi-sh-sci.o +obj-$(CONFIG_SPI_SIFIVE) += spi-sifive.o obj-$(CONFIG_SPI_SIRF) += spi-sirf.o obj-$(CONFIG_SPI_SLAVE_MT27XX) += spi-slave-mt27xx.o obj-$(CONFIG_SPI_SPRD) += spi-sprd.o diff --git a/drivers/spi/spi-sifive.c b/drivers/spi/spi-sifive.c new file mode 100644 index 000..961307c --- /dev/null +++ b/drivers/spi/spi-sifive.c @@ -0,0 +1,450 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// Copyright 2018 SiFive, Inc. +// +// SiFive SPI controller driver (master mode only) +// +// Author: SiFive, Inc. +// sif...@sifive.com + +#include +#include +#include +#include +#include +#include +#include +#include + +#define SIFIVE_SPI_DRIVER_NAME "sifive_spi" + +#define SIFIVE_SPI_MAX_CS32 +#define SIFIVE_SPI_DEFAULT_DEPTH 8 +#define SIFIVE_SPI_DEFAULT_MAX_BITS 8 + +/* register offsets */ +#define SIFIVE_SPI_REG_SCKDIV0x00 /* Serial clock divisor */ +#define SIFIVE_SPI_REG_SCKMODE 0x04 /* Serial clock mode */ +#define SIFIVE_SPI_REG_CSID 0x10 /* Chip select ID */ +#define SIFIVE_SPI_REG_CSDEF 0x14 /* Chip select default */ +#define SIFIVE_SPI_REG_CSMODE0x18 /* Chip select mode */ +#define SIFIVE_SPI_REG_DELAY00x28 /* Delay control 0 */ +#define SIFIVE_SPI_REG_DELAY10x2c /* Delay control 1 */ +#define SIFIVE_SPI_REG_FMT 0x40 /* Frame format */ +#define SIFIVE_SPI_REG_TXDATA0x48 /* Tx FIFO data */ +#define SIFIVE_SPI_REG_RXDATA0x4c /* Rx FIFO data */ +#define SIFIVE_SPI_REG_TXMARK0x50 /* Tx FIFO watermark */ +#define SIFIVE_SPI_REG_RXMARK0x54 /* Rx FIFO watermark */ +#define SIFIVE_SPI_REG_FCTRL 0x60 /* SPI flash interface control */ +#define SIFIVE_SPI_REG_FFMT 0x64 /* SPI flash instruction format */ +#define SIFIVE_SPI_REG_IE0x70 /* Interrupt Enable Register */ +#define SIFIVE_SPI_REG_IP0x74 /* Interrupt Pendings Register */ + +/* sckdiv bits */ +#define SIFIVE_SPI_SCKDIV_DIV_MASK 0xfffU + +/* sckmode bits */ +#define SIFIVE_SPI_SCKMODE_PHA BIT(0) +#define SIFIVE_SPI_SCKMODE_POL BIT(1) +#define SIFIVE_SPI_SCKMODE_MODE_MASK (SIFIVE_SPI_SCKMODE_PHA | \ + SIFIVE_SPI_SCKMODE_POL) + +/* csmode bits */ +#define SIFIVE_SPI_CSMODE_MODE_AUTO 0U +#define SIFIVE_SPI_CSMODE_MODE_HOLD 2U +#define SIFIVE_SPI_CSMODE_MODE_OFF 3U + +/* delay0 bits */ +#define SIFIVE_SPI_DELAY0_CSSCK(x) ((u32)(x)) +#define SIFIVE_SPI_DELAY0_CSSCK_MASK 0xffU +#define SIFIVE_SPI_DELAY0_SCKCS(x) ((u32)(x) << 16) +#define SIFIVE_SPI_DELAY0_SCKCS_MASK (0xffU << 16) + +/* delay1 bits */ +#define SIFIVE_SPI_DELAY1_INTERCS(x) ((u32)(x)) +#define SIFIVE_SPI_DELAY1_INTERCS_MASK 0xffU +#define SIFIVE_SPI_DELAY1_INTERXFR(x)((u32)(x) << 16) +#define SIFIVE_SPI_DELAY1_INTERXFR_MASK (0xffU << 16) + +/* fmt bits */ +#define SIFIVE_SPI_FMT_PROTO_SINGLE 0U +#define SIFIVE_SPI_FMT_PROTO_DUAL1U +#define SIFIVE_SPI_FMT_PROTO_QUAD2U +#define SIFIVE_SPI_FMT_PROTO_MASK3U +#define SIFIVE_SPI_FMT_ENDIANBIT(2) +#define SIFIVE_SPI_FMT_DIR BIT(3) +#define SIFIVE_SPI_FMT_LEN(x)((u32)(x) << 16) +#define SIFIVE_SPI_FMT_LEN_MASK (0xfU << 16) + +/* txdata bits */ +#define SIFIVE_SPI_TXDATA_DATA_MASK 0xffU +#define SIFIVE_SPI_TXDATA_FULL BIT(31) + +/* rxdata bits */ +#define SIFIVE_SPI_RXDATA_DATA_MASK 0xffU +#define SIFIVE_SPI_RXDATA_EMPTY BIT(31) + +/* ie and ip
[PATCH 1/2] spi: sifive: Add DT documentation for SiFive SPI controller
DT documentation for SPI controller added. Signed-off-by: Palmer Dabbelt Signed-off-by: Emil Renner Berthing Signed-off-by: Yash Shah --- .../devicetree/bindings/spi/spi-sifive.txt | 37 ++ 1 file changed, 37 insertions(+) create mode 100644 Documentation/devicetree/bindings/spi/spi-sifive.txt diff --git a/Documentation/devicetree/bindings/spi/spi-sifive.txt b/Documentation/devicetree/bindings/spi/spi-sifive.txt new file mode 100644 index 000..3f5c6e4 --- /dev/null +++ b/Documentation/devicetree/bindings/spi/spi-sifive.txt @@ -0,0 +1,37 @@ +SiFive SPI controller Device Tree Bindings +-- + +Required properties: +- compatible : Should be "sifive,-spi" and "sifive,spi". + Supported compatible strings are: + "sifive,fu540-c000-spi" for the SiFive SPI v0 as integrated + onto the SiFive FU540 chip, and "sifive,spi0" for the SiFive + SPI v0 IP block with no chip integration tweaks. + Please refer to sifive-blocks-ip-versioning.txt for details +- reg : Physical base address and size of SPI registers map + A second (optional) range can indicate memory mapped flash +- interrupts : Must contain one entry +- interrupt-parent : Must be core interrupt controller +- clocks : Must reference the frequency given to the controller +- #address-cells : Must be '1', indicating which CS to use +- #size-cells : Must be '0' + +Optional properties: +- sifive,fifo-depth: Depth of hardware queues; defaults to 8 +- sifive,max-bits-per-word : Maximum bits per word; defaults to 8 + +SPI RTL that corresponds to the IP block version numbers can be found here: +https://github.com/sifive/sifive-blocks/tree/master/src/main/scala/devices/spi + +Example: + spi: spi@1004 { + compatible = "sifive,fu540-c000-spi", "sifive,spi0"; + reg = <0x0 0x1004 0x0 0x1000 0x0 0x2000 0x0 0x1000>; + interrupt-parent = <&plic>; + interrupts = <51>; + clocks = <&tlclk>; + #address-cells = <1>; + #size-cells = <0>; + sifive,fifo-depth = <8>; + sifive,max-bits-per-word = <8>; + }; -- 1.9.1
[PATCH v7 1/2] pwm: sifive: Add DT documentation for SiFive PWM Controller
DT documentation for PWM controller added. Signed-off-by: Wesley W. Terpstra [Atish: Compatible string update] Signed-off-by: Atish Patra Signed-off-by: Yash Shah --- .../devicetree/bindings/pwm/pwm-sifive.txt | 33 ++ 1 file changed, 33 insertions(+) create mode 100644 Documentation/devicetree/bindings/pwm/pwm-sifive.txt diff --git a/Documentation/devicetree/bindings/pwm/pwm-sifive.txt b/Documentation/devicetree/bindings/pwm/pwm-sifive.txt new file mode 100644 index 000..36447e3 --- /dev/null +++ b/Documentation/devicetree/bindings/pwm/pwm-sifive.txt @@ -0,0 +1,33 @@ +SiFive PWM controller + +Unlike most other PWM controllers, the SiFive PWM controller currently only +supports one period for all channels in the PWM. All PWMs need to run at +the same period. The period also has significant restrictions on the values +it can achieve, which the driver rounds to the nearest achievable period. +PWM RTL that corresponds to the IP block version numbers can be found +here: + +https://github.com/sifive/sifive-blocks/tree/master/src/main/scala/devices/pwm + +Required properties: +- compatible: Should be "sifive,-pwm" and "sifive,pwm". + Supported compatible strings are: "sifive,fu540-c000-pwm" for the SiFive + PWM v0 as integrated onto the SiFive FU540 chip, and "sifive,pwm0" for the + SiFive PWM v0 IP block with no chip integration tweaks. + Please refer to sifive-blocks-ip-versioning.txt for details. +- reg: physical base address and length of the controller's registers +- clocks: Should contain a clock identifier for the PWM's parent clock. +- #pwm-cells: Should be 3. See pwm.txt in this directory + for a description of the cell format. +- interrupts: one interrupt per PWM channel + +Examples: + +pwm: pwm@1002 { + compatible = "sifive,fu540-c000-pwm", "sifive,pwm0"; + reg = <0x0 0x1002 0x0 0x1000>; + clocks = <&tlclk>; + interrupt-parent = <&plic>; + interrupts = <42 43 44 45>; + #pwm-cells = <3>; +}; -- 1.9.1
[PATCH v7 0/2] PWM support for HiFive Unleashed
This patch series adds a PWM driver and DT documentation for HiFive Unleashed board. The patches are mostly based on Wesley's patch. v7 - Modify description of compatible property in DT documentation - Use mutex locks at appropriate places - Fix all bad line breaks - Allow enabling/disabling PWM only when the user is the only active user - Remove Deglitch logic - Other minor fixes v6 - Remove the global property 'sifive,period-ns' - Implement free and request callbacks to maintain user counts. - Add user_count member to struct pwm_sifive_ddata - Allow period change only if user_count is one - Add pwm_sifive_enable function to enable/disable PWM - Change calculation logic of frac (in pwm_sifive_apply) - Remove state correction - Remove pwm_sifive_xlate function - Clock to be enabled only when PWM is enabled - Other minor fixes v5 - Correct the order of compatible string properties - PWM state correction to be done always - Other minor fixes based upon feedback on v4 v4 - Rename macros with appropriate names - Remove unused macros - Rename struct sifive_pwm_device to struct pwm_sifive_ddata - Rename function prefix as per driver name - Other minor fixes based upon feedback on v3 v3 - Add a link to the reference manaul - Use appropriate apis for division operation - Add check for polarity - Enable clk before calling clk_get_rate - Other minor fixes based upon feedback on v2 V2 changed from V1: - Remove inclusion of dt-bindings/pwm/pwm.h - Remove artificial alignments - Replace ioread32/iowrite32 with readl/writel - Remove camelcase - Change dev_info to dev_dbg for unnecessary log - Correct typo in driver name - Remove use of of_match_ptr macro - Update the DT compatible strings and Add reference to a common versioning document Yash Shah (2): pwm: sifive: Add DT documentation for SiFive PWM Controller pwm: sifive: Add a driver for SiFive SoC PWM .../devicetree/bindings/pwm/pwm-sifive.txt | 33 ++ drivers/pwm/Kconfig| 11 + drivers/pwm/Makefile | 1 + drivers/pwm/pwm-sifive.c | 346 + 4 files changed, 391 insertions(+) create mode 100644 Documentation/devicetree/bindings/pwm/pwm-sifive.txt create mode 100644 drivers/pwm/pwm-sifive.c -- 1.9.1
[PATCH v7 2/2] pwm: sifive: Add a driver for SiFive SoC PWM
Adds a PWM driver for PWM chip present in SiFive's HiFive Unleashed SoC. Signed-off-by: Wesley W. Terpstra [Atish: Various fixes and code cleanup] Signed-off-by: Atish Patra Signed-off-by: Yash Shah --- drivers/pwm/Kconfig | 11 ++ drivers/pwm/Makefile | 1 + drivers/pwm/pwm-sifive.c | 346 +++ 3 files changed, 358 insertions(+) create mode 100644 drivers/pwm/pwm-sifive.c diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig index a8f47df..4a61d1a 100644 --- a/drivers/pwm/Kconfig +++ b/drivers/pwm/Kconfig @@ -380,6 +380,17 @@ config PWM_SAMSUNG To compile this driver as a module, choose M here: the module will be called pwm-samsung. +config PWM_SIFIVE + tristate "SiFive PWM support" + depends on OF + depends on COMMON_CLK + depends on RISCV || COMPILE_TEST + help + Generic PWM framework driver for SiFive SoCs. + + To compile this driver as a module, choose M here: the module + will be called pwm-sifive. + config PWM_SPEAR tristate "STMicroelectronics SPEAr PWM support" depends on PLAT_SPEAR diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile index 9c676a0..30089ca 100644 --- a/drivers/pwm/Makefile +++ b/drivers/pwm/Makefile @@ -37,6 +37,7 @@ obj-$(CONFIG_PWM_RCAR)+= pwm-rcar.o obj-$(CONFIG_PWM_RENESAS_TPU) += pwm-renesas-tpu.o obj-$(CONFIG_PWM_ROCKCHIP) += pwm-rockchip.o obj-$(CONFIG_PWM_SAMSUNG) += pwm-samsung.o +obj-$(CONFIG_PWM_SIFIVE) += pwm-sifive.o obj-$(CONFIG_PWM_SPEAR)+= pwm-spear.o obj-$(CONFIG_PWM_STI) += pwm-sti.o obj-$(CONFIG_PWM_STM32)+= pwm-stm32.o diff --git a/drivers/pwm/pwm-sifive.c b/drivers/pwm/pwm-sifive.c new file mode 100644 index 000..8f29283d --- /dev/null +++ b/drivers/pwm/pwm-sifive.c @@ -0,0 +1,346 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2017-2018 SiFive + * For SiFive's PWM IP block documentation please refer Chapter 14 of + * Reference Manual : https://static.dev.sifive.com/FU540-C000-v1.0.pdf + * + * Limitations: + * - When changing both duty cycle and period, we cannot prevent in + * software that the output might produce a period with mixed + * settings (new period length and old duty cycle). + * - The hardware cannot generate a 100% duty cycle. + * - The hardware generaets only inverted output. + */ +#include +#include +#include +#include +#include +#include + +/* Register offsets */ +#define PWM_SIFIVE_PWMCFG 0x0 +#define PWM_SIFIVE_PWMCOUNT0x8 +#define PWM_SIFIVE_PWMS0x10 +#define PWM_SIFIVE_PWMCMP0 0x20 + +/* PWMCFG fields */ +#define PWM_SIFIVE_PWMCFG_SCALE0 +#define PWM_SIFIVE_PWMCFG_STICKY 8 +#define PWM_SIFIVE_PWMCFG_ZERO_CMP 9 +#define PWM_SIFIVE_PWMCFG_DEGLITCH 10 +#define PWM_SIFIVE_PWMCFG_EN_ALWAYSBIT(12) +#define PWM_SIFIVE_PWMCFG_EN_ONCE 13 +#define PWM_SIFIVE_PWMCFG_CENTER 16 +#define PWM_SIFIVE_PWMCFG_GANG 24 +#define PWM_SIFIVE_PWMCFG_IP 28 + +/* PWM_SIFIVE_SIZE_PWMCMP is used to calculate offset for pwmcmpX registers */ +#define PWM_SIFIVE_SIZE_PWMCMP 4 +#define PWM_SIFIVE_CMPWIDTH16 + +struct pwm_sifive_ddata { + struct pwm_chip chip; + struct mutex lock; /* lock to protect user_count and active_user */ + struct notifier_block notifier; + struct clk *clk; + void __iomem *regs; + unsigned int real_period; + int user_count; + int active_user; +}; + +static inline +struct pwm_sifive_ddata *pwm_sifive_chip_to_ddata(struct pwm_chip *c) +{ + return container_of(c, struct pwm_sifive_ddata, chip); +} + +static int pwm_sifive_request(struct pwm_chip *chip, struct pwm_device *dev) +{ + struct pwm_sifive_ddata *pwm = pwm_sifive_chip_to_ddata(chip); + + mutex_lock(&pwm->lock); + pwm->user_count++; + mutex_unlock(&pwm->lock); + + return 0; +} + +static void pwm_sifive_free(struct pwm_chip *chip, struct pwm_device *dev) +{ + struct pwm_sifive_ddata *pwm = pwm_sifive_chip_to_ddata(chip); + + mutex_lock(&pwm->lock); + pwm->user_count--; + mutex_unlock(&pwm->lock); +} + +static void pwm_sifive_update_clock(struct pwm_sifive_ddata *pwm, + unsigned long rate) +{ + u32 val; + unsigned long num; + /* (1 << (PWM_SIFIVE_CMPWIDTH+scale)) * 10^9/rate = real_period */ + unsigned long scale_pow = + div64_ul(pwm->real_period * (u64)rate, NSEC_PER_SEC); + int scale = clamp(ilog2(scale_pow) - PWM_SIFIVE_CMPWIDTH, 0, 0xf); + + val = PWM_SIFIVE_PWMCFG_EN_ALWAYS | (scale << PWM_SIFIVE_PWMCFG_SCALE); + writel(val, pwm->regs + PWM_SIFIVE_PWMCFG); + + /* As scale <= 15 the shift oper
[PATCH v5 1/2] pwm: sifive: Add DT documentation for SiFive PWM Controller
DT documentation for PWM controller added. Signed-off-by: Wesley W. Terpstra [Atish: Compatible string update] Signed-off-by: Atish Patra Signed-off-by: Yash Shah --- .../devicetree/bindings/pwm/pwm-sifive.txt | 33 ++ 1 file changed, 33 insertions(+) create mode 100644 Documentation/devicetree/bindings/pwm/pwm-sifive.txt diff --git a/Documentation/devicetree/bindings/pwm/pwm-sifive.txt b/Documentation/devicetree/bindings/pwm/pwm-sifive.txt new file mode 100644 index 000..8dcb40d --- /dev/null +++ b/Documentation/devicetree/bindings/pwm/pwm-sifive.txt @@ -0,0 +1,33 @@ +SiFive PWM controller + +Unlike most other PWM controllers, the SiFive PWM controller currently only +supports one period for all channels in the PWM. This is set globally in DTS. +The period also has significant restrictions on the values it can achieve, +which the driver rounds to the nearest achievable frequency. +PWM RTL that corresponds to the IP block version numbers can be found +here: + +https://github.com/sifive/sifive-blocks/tree/master/src/main/scala/devices/pwm + +Required properties: +- compatible: Should be "sifive,$socname-pwm" and "sifive,pwmX". + Please refer to sifive-blocks-ip-versioning.txt for details. +- reg: physical base address and length of the controller's registers +- clocks: Should contain a clock identifier for the PWM's parent clock. +- #pwm-cells: Should be 2. + The first cell is the PWM channel number + The second cell is the PWM polarity +- sifive,period-ns: the driver will get as close to this period as it can +- interrupts: one interrupt per PWM channel + +Examples: + +pwm: pwm@1002 { + compatible = "sifive,fu540-c000-pwm", "sifive,pwm0"; + reg = <0x0 0x1002 0x0 0x1000>; + clocks = <&tlclk>; + interrupt-parent = <&plic>; + interrupts = <42 43 44 45>; + #pwm-cells = <2>; + sifive,period-ns = <100>; +}; -- 1.9.1
[PATCH v5 0/2] PWM support for HiFive Unleashed
This patch series adds a PWM driver and DT documentation for HiFive Unleashed board. The patches are mostly based on Wesley's patch. v5 - Correct the order of compatible string properties - PWM state correction to be done always - Other minor fixes based upon feedback on v4 v4 - Rename the property sifive,approx-period-ns to sifive,period-ns - Rename macros with appropriate names - Remove unused macros - Rename struct sifive_pwm_device to struct pwm_sifive_ddata - Rename function prefix as per driver name - Set deglitch bit before changing output waveform. - Other minor fixes based upon feedback on v3 v3 - Add a link to the reference manaul - Use appropriate apis for division operation - Add check for polarity - Enable clk before calling clk_get_rate - Other minor fixes based upon feedback on v2 V2 changed from V1: - Remove inclusion of dt-bindings/pwm/pwm.h - Remove artificial alignments - Replace ioread32/iowrite32 with readl/writel - Remove camelcase - Change dev_info to dev_dbg for unnecessary log - Correct typo in driver name - Remove use of of_match_ptr macro - Update the DT compatible strings and Add reference to a common versioning document Yash Shah (2): pwm: sifive: Add DT documentation for SiFive PWM Controller pwm: sifive: Add a driver for SiFive SoC PWM .../devicetree/bindings/pwm/pwm-sifive.txt | 33 +++ drivers/pwm/Kconfig| 11 + drivers/pwm/Makefile | 1 + drivers/pwm/pwm-sifive.c | 261 + 4 files changed, 306 insertions(+) create mode 100644 Documentation/devicetree/bindings/pwm/pwm-sifive.txt create mode 100644 drivers/pwm/pwm-sifive.c -- 1.9.1
[PATCH v5 2/2] pwm: sifive: Add a driver for SiFive SoC PWM
Adds a PWM driver for PWM chip present in SiFive's HiFive Unleashed SoC. Signed-off-by: Wesley W. Terpstra [Atish: Various fixes and code cleanup] Signed-off-by: Atish Patra Signed-off-by: Yash Shah --- drivers/pwm/Kconfig | 11 ++ drivers/pwm/Makefile | 1 + drivers/pwm/pwm-sifive.c | 261 +++ 3 files changed, 273 insertions(+) create mode 100644 drivers/pwm/pwm-sifive.c diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig index a8f47df..4a61d1a 100644 --- a/drivers/pwm/Kconfig +++ b/drivers/pwm/Kconfig @@ -380,6 +380,17 @@ config PWM_SAMSUNG To compile this driver as a module, choose M here: the module will be called pwm-samsung. +config PWM_SIFIVE + tristate "SiFive PWM support" + depends on OF + depends on COMMON_CLK + depends on RISCV || COMPILE_TEST + help + Generic PWM framework driver for SiFive SoCs. + + To compile this driver as a module, choose M here: the module + will be called pwm-sifive. + config PWM_SPEAR tristate "STMicroelectronics SPEAr PWM support" depends on PLAT_SPEAR diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile index 9c676a0..30089ca 100644 --- a/drivers/pwm/Makefile +++ b/drivers/pwm/Makefile @@ -37,6 +37,7 @@ obj-$(CONFIG_PWM_RCAR)+= pwm-rcar.o obj-$(CONFIG_PWM_RENESAS_TPU) += pwm-renesas-tpu.o obj-$(CONFIG_PWM_ROCKCHIP) += pwm-rockchip.o obj-$(CONFIG_PWM_SAMSUNG) += pwm-samsung.o +obj-$(CONFIG_PWM_SIFIVE) += pwm-sifive.o obj-$(CONFIG_PWM_SPEAR)+= pwm-spear.o obj-$(CONFIG_PWM_STI) += pwm-sti.o obj-$(CONFIG_PWM_STM32)+= pwm-stm32.o diff --git a/drivers/pwm/pwm-sifive.c b/drivers/pwm/pwm-sifive.c new file mode 100644 index 000..2b516f7 --- /dev/null +++ b/drivers/pwm/pwm-sifive.c @@ -0,0 +1,261 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2017-2018 SiFive + * For SiFive's PWM IP block documentation please refer Chapter 14 of + * Reference Manual : https://static.dev.sifive.com/FU540-C000-v1.0.pdf + */ +#include +#include +#include +#include +#include +#include + +/* Register offsets */ +#define PWM_SIFIVE_PWMCFG 0x0 +#define PWM_SIFIVE_PWMCOUNT0x8 +#define PWM_SIFIVE_PWMS0x10 +#define PWM_SIFIVE_PWMCMP0 0x20 + +/* PWMCFG fields */ +#define PWM_SIFIVE_PWMCFG_SCALE0 +#define PWM_SIFIVE_PWMCFG_STICKY 8 +#define PWM_SIFIVE_PWMCFG_ZERO_CMP 9 +#define PWM_SIFIVE_PWMCFG_DEGLITCH 10 +#define PWM_SIFIVE_PWMCFG_EN_ALWAYS12 +#define PWM_SIFIVE_PWMCFG_EN_ONCE 13 +#define PWM_SIFIVE_PWMCFG_CENTER 16 +#define PWM_SIFIVE_PWMCFG_GANG 24 +#define PWM_SIFIVE_PWMCFG_IP 28 + +/* SIZE_PWMCMP is used to calculate the offset for pwmcmpX registers */ +#define SIZE_PWMCMP4 +#define CMPWIDTH 16 + +struct pwm_sifive_ddata { + struct pwm_chip chip; + struct notifier_block notifier; + struct clk *clk; + void __iomem *regs; + unsigned int approx_period; + unsigned int real_period; +}; + +static inline struct pwm_sifive_ddata *to_pwm_sifive_chip(struct pwm_chip *c) +{ + return container_of(c, struct pwm_sifive_ddata, chip); +} + +static void pwm_sifive_get_state(struct pwm_chip *chip, struct pwm_device *dev, +struct pwm_state *state) +{ + struct pwm_sifive_ddata *pwm = to_pwm_sifive_chip(chip); + u32 duty; + + duty = readl(pwm->regs + PWM_SIFIVE_PWMCMP0 + dev->hwpwm * SIZE_PWMCMP); + + state->period = pwm->real_period; + state->duty_cycle = ((u64)duty * pwm->real_period) >> CMPWIDTH; + state->polarity = PWM_POLARITY_INVERSED; + state->enabled = duty > 0; +} + +static int pwm_sifive_apply(struct pwm_chip *chip, struct pwm_device *dev, + struct pwm_state *state) +{ + struct pwm_sifive_ddata *pwm = to_pwm_sifive_chip(chip); + unsigned int duty_cycle; + u32 frac, val; + + if (state->polarity != PWM_POLARITY_INVERSED) + return -EINVAL; + + if (state->period != pwm->real_period) + return -EINVAL; + + duty_cycle = state->duty_cycle; + if (!state->enabled) + duty_cycle = 0; + + frac = div_u64((u64)duty_cycle * 0x, state->period); + frac = min(frac, 0xU); + + val = readl(pwm->regs + PWM_SIFIVE_PWMCFG); + val |= (1 << PWM_SIFIVE_PWMCFG_DEGLITCH); + writel(val, pwm->regs + PWM_SIFIVE_PWMCFG); + + writel(frac, pwm->regs + PWM_SIFIVE_PWMCMP0 + dev->hwpwm * SIZE_PWMCMP); + + val &= ~(1 << PWM_SIFIVE_PWMCFG_DEGLITCH); + writel(val, pwm->regs + PWM_SIFIVE_PWMCFG); + + pwm_sifive_get_state(chip, dev, state); +
Re: [PATCH 1/2] pwm: sifive: Add DT documentation for SiFive PWM Controller
On Wed, Jan 16, 2019 at 1:41 AM Uwe Kleine-König wrote: > > Hello, > > this is v3, right? It is helpful to point this out to ease reviewing. Yes, it is v3. Will take care of this in v4. > > On Fri, Jan 11, 2019 at 01:52:43PM +0530, Yash Shah wrote: > > DT documentation for PWM controller added with updated compatible > > string. > > Not sure what was updated here. But assuming this is compared to v2 this > is not a helpful info in the commit log. Ok, will remove the 'updated compatible string' part. > > > Signed-off-by: Wesley W. Terpstra > > [Atish: Compatible string update] > > Signed-off-by: Atish Patra > > Signed-off-by: Yash Shah > > --- > > .../devicetree/bindings/pwm/pwm-sifive.txt | 37 > > ++ > > 1 file changed, 37 insertions(+) > > create mode 100644 Documentation/devicetree/bindings/pwm/pwm-sifive.txt > > > > diff --git a/Documentation/devicetree/bindings/pwm/pwm-sifive.txt > > b/Documentation/devicetree/bindings/pwm/pwm-sifive.txt > > new file mode 100644 > > index 000..e0fc22a > > --- /dev/null > > +++ b/Documentation/devicetree/bindings/pwm/pwm-sifive.txt > > @@ -0,0 +1,37 @@ > > +SiFive PWM controller > > + > > +Unlike most other PWM controllers, the SiFive PWM controller currently only > > +supports one period for all channels in the PWM. This is set globally in > > DTS. > > +The period also has significant restrictions on the values it can achieve, > > +which the driver rounds to the nearest achievable frequency. > > + > > +Required properties: > > +- compatible: Please refer to sifive-blocks-ip-versioning.txt > > While the description was too verbose in v2, this is too short. You > should at least mention something like "sifive,pwmX" and > "sifive,$cpuname-pwm" (or how ever that scheme works). Will mention the above. > > > +- reg: physical base address and length of the controller's registers > > +- clocks: Should contain a clock identifier for the PWM's parent clock. > > +- #pwm-cells: Should be 2. > > + The first cell is the PWM channel number > > + The second cell is the PWM polarity > > I'd drop these two lines and refer to bindings/pwm/pwm.txt instead. Will be done. > > > +- sifive,approx-period-ns: the driver will get as close to this period as > > it can > > As already said for v2: I'd drop "approx-". Sure, will be done. > > > +- interrupts: one interrupt per PWM channel > > + > > +PWM RTL that corresponds to the IP block version numbers can be found > > +here: > > + > > +https://github.com/sifive/sifive-blocks/tree/master/src/main/scala/devices/pwm > > + > > +Further information on the format of the IP > > +block-specific version numbers can be found in > > +Documentation/devicetree/bindings/sifive/sifive-blocks-ip-versioning.txt > > + > > +Examples: > > + > > +pwm: pwm@1002 { > > + compatible = "sifive,fu540-c000-pwm","sifive,pwm0"; > > + reg = <0x0 0x1002 0x0 0x1000>; > > + clocks = <&tlclk>; > > + interrupt-parent = <&plic>; > > + interrupts = <42 43 44 45>; > > + #pwm-cells = <2>; > > + sifive,approx-period-ns = <100>; > > +}; > > -- > > 1.9.1 > > > > > > -- > Pengutronix e.K. | Uwe Kleine-König| > Industrial Linux Solutions | http://www.pengutronix.de/ | Thanks for the comments.
Re: [PATCH 2/2] pwm: sifive: Add a driver for SiFive SoC PWM
On Wed, Jan 16, 2019 at 3:30 AM Uwe Kleine-König wrote: > > Hello, > > On Fri, Jan 11, 2019 at 01:52:44PM +0530, Yash Shah wrote: > > Adds a PWM driver for PWM chip present in SiFive's HiFive Unleashed SoC. > > > > Signed-off-by: Wesley W. Terpstra > > [Atish: Various fixes and code cleanup] > > Signed-off-by: Atish Patra > > Signed-off-by: Yash Shah > > --- > > drivers/pwm/Kconfig | 10 ++ > > drivers/pwm/Makefile | 1 + > > drivers/pwm/pwm-sifive.c | 246 > > +++ > > 3 files changed, 257 insertions(+) > > create mode 100644 drivers/pwm/pwm-sifive.c > > > > diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig > > index a8f47df..3bcaf6a 100644 > > --- a/drivers/pwm/Kconfig > > +++ b/drivers/pwm/Kconfig > > @@ -380,6 +380,16 @@ config PWM_SAMSUNG > > To compile this driver as a module, choose M here: the module > > will be called pwm-samsung. > > > > +config PWM_SIFIVE > > + tristate "SiFive PWM support" > > + depends on OF > > + depends on COMMON_CLK > > I'd say add: > > depends on MACH_SIFIVE || COMPILE_TEST > > (I guess "MACH_SIFIVE" is wrong, but I assume you get what I mean.) As of now, MACH_SIFIVE/ARCH_SIFIVE isn't available. @Paul, Do you have any comments on this? > > > + help > > + Generic PWM framework driver for SiFive SoCs. > > + > > + To compile this driver as a module, choose M here: the module > > + will be called pwm-sifive. > > + > > config PWM_SPEAR > > tristate "STMicroelectronics SPEAr PWM support" > > depends on PLAT_SPEAR > > diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile > > index 9c676a0..30089ca 100644 > > --- a/drivers/pwm/Makefile > > +++ b/drivers/pwm/Makefile > > @@ -37,6 +37,7 @@ obj-$(CONFIG_PWM_RCAR) += pwm-rcar.o > > obj-$(CONFIG_PWM_RENESAS_TPU)+= pwm-renesas-tpu.o > > obj-$(CONFIG_PWM_ROCKCHIP) += pwm-rockchip.o > > obj-$(CONFIG_PWM_SAMSUNG)+= pwm-samsung.o > > +obj-$(CONFIG_PWM_SIFIVE) += pwm-sifive.o > > obj-$(CONFIG_PWM_SPEAR) += pwm-spear.o > > obj-$(CONFIG_PWM_STI)+= pwm-sti.o > > obj-$(CONFIG_PWM_STM32) += pwm-stm32.o > > diff --git a/drivers/pwm/pwm-sifive.c b/drivers/pwm/pwm-sifive.c > > new file mode 100644 > > index 000..7fee809 > > --- /dev/null > > +++ b/drivers/pwm/pwm-sifive.c > > @@ -0,0 +1,246 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > +/* > > + * Copyright (C) 2017-2018 SiFive > > + * For SiFive's PWM IP block documentation please refer Chapter 14 of > > + * Reference Manual : https://static.dev.sifive.com/FU540-C000-v1.0.pdf > > I wonder if such an instance should be only a single PWM instead of > four. Then you were more flexible with the period lengths (using > pwmcfg.pwmzerocmp) and could do stuff like inverted and uninverted mode. > > I didn't understand how the deglitch logic works yet. Currently it is > not used which might result in four edges in a single period (which is > bad). I can enable deglitch logic by just setting a bit (BIT_PWM_DEGLITCH) in REG_PWMCFG. Will do that. > > > + */ > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > + > > +/* Register offsets */ > > +#define REG_PWMCFG 0x0 > > +#define REG_PWMCOUNT 0x8 > > +#define REG_PWMS 0x10 > > +#define REG_PWMCMP0 0x20 > > I suggest a common prefix for these defines. Something like > PWM_SIFIVE_ Sure. > > > + > > +/* PWMCFG fields */ > > +#define BIT_PWM_SCALE0 > > +#define BIT_PWM_STICKY 8 > > +#define BIT_PWM_ZERO_ZMP 9 > > the manual calls this "pwmzerocmp". Will fix this. > > > +#define BIT_PWM_DEGLITCH 10 > > +#define BIT_PWM_EN_ALWAYS12 > > +#define BIT_PWM_EN_ONCE 13 > > +#define BIT_PWM0_CENTER 16 > > +#define BIT_PWM0_GANG24 > > +#define BIT_PWM0_IP 28 > > Also a common prefix please. Something like PWM_SIFIVE_PWMCFG_ seems > sensible. Sure. > > > +#define SIZE_PWMCMP 4 > > Please describe what this constant means. I think this is "ncmp" in the > reference manual. If so, using PWM_SIFIVE_NCMP as name instead seems > adequate. No, it is not ncmp. It is used to calculate the of
Re: [PATCH 2/2] pwm: sifive: Add a driver for SiFive SoC PWM
On Wed, Jan 16, 2019 at 10:16 PM Uwe Kleine-König wrote: > > Hello, > > On Wed, Jan 16, 2019 at 04:40:42PM +0530, Yash Shah wrote: > > On Wed, Jan 16, 2019 at 3:30 AM Uwe Kleine-König > > wrote: > > > On Fri, Jan 11, 2019 at 01:52:44PM +0530, Yash Shah wrote: > > > > Adds a PWM driver for PWM chip present in SiFive's HiFive Unleashed SoC. > > > > > > > > Signed-off-by: Wesley W. Terpstra > > > > [Atish: Various fixes and code cleanup] > > > > Signed-off-by: Atish Patra > > > > Signed-off-by: Yash Shah > > > > --- > > > > drivers/pwm/Kconfig | 10 ++ > > > > drivers/pwm/Makefile | 1 + > > > > drivers/pwm/pwm-sifive.c | 246 > > > > +++ > > > > 3 files changed, 257 insertions(+) > > > > create mode 100644 drivers/pwm/pwm-sifive.c > > > > > > > > diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig > > > > index a8f47df..3bcaf6a 100644 > > > > --- a/drivers/pwm/Kconfig > > > > +++ b/drivers/pwm/Kconfig > > > > @@ -380,6 +380,16 @@ config PWM_SAMSUNG > > > > To compile this driver as a module, choose M here: the module > > > > will be called pwm-samsung. > > > > > > > > +config PWM_SIFIVE > > > > + tristate "SiFive PWM support" > > > > + depends on OF > > > > + depends on COMMON_CLK > > > > > > I'd say add: > > > > > > depends on MACH_SIFIVE || COMPILE_TEST > > > > > > (I guess "MACH_SIFIVE" is wrong, but I assume you get what I mean.) > > > > As of now, MACH_SIFIVE/ARCH_SIFIVE isn't available. > > @Paul, Do you have any comments on this? > > If this is not going to be available at least protect it by > > depends RISCV || COMPILE_TEST > > > > I wonder if such an instance should be only a single PWM instead of > > > four. Then you were more flexible with the period lengths (using > > > pwmcfg.pwmzerocmp) and could do stuff like inverted and uninverted mode. > > > > > > I didn't understand how the deglitch logic works yet. Currently it is > > > not used which might result in four edges in a single period (which is > > > bad). > > > > I can enable deglitch logic by just setting a bit (BIT_PWM_DEGLITCH) in > > REG_PWMCFG. Will do that. > > This only works for the first pwm output though. > > > > > +struct sifive_pwm_device { > > > > + struct pwm_chip chip; > > > > + struct notifier_block notifier; > > > > + struct clk *clk; > > > > + void __iomem *regs; > > > > + unsigned int approx_period; > > When thinking about this a bit more, I think the better approach would > be to let the consumer change the period iff there is only one consumer. > Then you can drop that approx-period stuff and the result is more > flexible. (Having said that I still prefer making the driver provide > only a single PWM with the ability to have periods other than powers of > two.) > I am not confident about the implementation of the way you are suggesting. As of now, I am going to stick with the current implementation. > > > > + writel(frac, pwm->regs + REG_PWMCMP0 + dev->hwpwm * SIZE_PWMCMP); > > > > > > If you get a constant inactive output with frac=0 and a constant active > > > output with frac=0x the calculation above seems wrong to me. > > > (A value i written to the pwmcmpX register means a duty cycle of > > > (i * period / 0x). Your calculation assumes a divisor of 0x1 > > > however.) > > > > Not sure if I get you completely. But, if divisor of 0x is your concern > > then > > does the below look ok? > > > > frac = div_u64(((u64)duty_cycle << 16) - duty_cycle, state->period); > > This works (I think, didn't redo the maths), but I would prefer > > frac = div_u64((u64)duty_cycle * 0x, state->period); > > for better readability. (Maybe the compiler is even clever enough to see > this can be calculated as you suggested.) Sure, will multiply it with 0x for better readability. > > > > > +static int sifive_pwm_clock_notifier(struct notifier_block *nb, > > > > + unsigned long event, void *data) > > > > +{ > > > > + struct clk_notifier_data *ndata = data; > > > > + struct sifive_pwm_device *pwm = > > > > + container_of(nb, struct sifive_pwm_device, notifier); > > > > + > > > > + if (event == POST_RATE_CHANGE) > > > > + sifive_pwm_update_clock(pwm, ndata->new_rate); > > > > > > Does this need locking? (Maybe not with the current state.) > > > > No. We can add it when required. > > My thought was, that the clk freq might change while .apply is active. > But given that you only configure the relative duty cycle this is > independent of the actual clk freq. > > Best regards > Uwe > > -- > Pengutronix e.K. | Uwe Kleine-König| > Industrial Linux Solutions | http://www.pengutronix.de/ | > > ___ > linux-riscv mailing list > linux-ri...@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/linux-riscv
[PATCH v4 0/2] PWM support for HiFive Unleashed
This patch series adds a PWM driver and DT documentation for HiFive Unleashed board. The patches are mostly based on Wesley's patch. v4 - Rename the property sifive,approx-period-ns to sifive,period-ns - Rename macros with appropriate names - Remove unused macros - Rename struct sifive_pwm_device to struct pwm_sifive_ddata - Rename function prefix as per driver name - Set deglitch bit before changing output waveform. - Other minor fixes based upon feedback on v3 v3 - Add a link to the reference manaul - Use appropriate apis for division operation - Add check for polarity - Enable clk before calling clk_get_rate - Other minor fixes based upon feedback on v2 V2 changed from V1: - Remove inclusion of dt-bindings/pwm/pwm.h - Remove artificial alignments - Replace ioread32/iowrite32 with readl/writel - Remove camelcase - Change dev_info to dev_dbg for unnecessary log - Correct typo in driver name - Remove use of of_match_ptr macro - Update the DT compatible strings and Add reference to a common versioning document Yash Shah (2): pwm: sifive: Add DT documentation for SiFive PWM Controller pwm: sifive: Add a driver for SiFive SoC PWM .../devicetree/bindings/pwm/pwm-sifive.txt | 37 +++ drivers/pwm/Kconfig| 11 + drivers/pwm/Makefile | 1 + drivers/pwm/pwm-sifive.c | 262 + 4 files changed, 311 insertions(+) create mode 100644 Documentation/devicetree/bindings/pwm/pwm-sifive.txt create mode 100644 drivers/pwm/pwm-sifive.c -- 1.9.1
[PATCH v4 1/2] pwm: sifive: Add DT documentation for SiFive PWM Controller
DT documentation for PWM controller added. Signed-off-by: Wesley W. Terpstra [Atish: Compatible string update] Signed-off-by: Atish Patra Signed-off-by: Yash Shah --- .../devicetree/bindings/pwm/pwm-sifive.txt | 37 ++ 1 file changed, 37 insertions(+) create mode 100644 Documentation/devicetree/bindings/pwm/pwm-sifive.txt diff --git a/Documentation/devicetree/bindings/pwm/pwm-sifive.txt b/Documentation/devicetree/bindings/pwm/pwm-sifive.txt new file mode 100644 index 000..b207908 --- /dev/null +++ b/Documentation/devicetree/bindings/pwm/pwm-sifive.txt @@ -0,0 +1,37 @@ +SiFive PWM controller + +Unlike most other PWM controllers, the SiFive PWM controller currently only +supports one period for all channels in the PWM. This is set globally in DTS. +The period also has significant restrictions on the values it can achieve, +which the driver rounds to the nearest achievable frequency. + +Required properties: +- compatible: Should be "sifive,pwmX" and "sifive,$socname-pwm". + Please refer to sifive-blocks-ip-versioning.txt for details. +- reg: physical base address and length of the controller's registers +- clocks: Should contain a clock identifier for the PWM's parent clock. +- #pwm-cells: Should be 2. + Refer to bindings/pwm/pwm.txt for details. +- sifive,period-ns: the driver will get as close to this period as it can +- interrupts: one interrupt per PWM channel + +PWM RTL that corresponds to the IP block version numbers can be found +here: + +https://github.com/sifive/sifive-blocks/tree/master/src/main/scala/devices/pwm + +Further information on the format of the IP +block-specific version numbers can be found in +Documentation/devicetree/bindings/sifive/sifive-blocks-ip-versioning.txt + +Examples: + +pwm: pwm@1002 { + compatible = "sifive,fu540-c000-pwm","sifive,pwm0"; + reg = <0x0 0x1002 0x0 0x1000>; + clocks = <&tlclk>; + interrupt-parent = <&plic>; + interrupts = <42 43 44 45>; + #pwm-cells = <2>; + sifive,period-ns = <100>; +}; -- 1.9.1
[PATCH v4 2/2] pwm: sifive: Add a driver for SiFive SoC PWM
Adds a PWM driver for PWM chip present in SiFive's HiFive Unleashed SoC. Signed-off-by: Wesley W. Terpstra [Atish: Various fixes and code cleanup] Signed-off-by: Atish Patra Signed-off-by: Yash Shah --- drivers/pwm/Kconfig | 11 ++ drivers/pwm/Makefile | 1 + drivers/pwm/pwm-sifive.c | 262 +++ 3 files changed, 274 insertions(+) create mode 100644 drivers/pwm/pwm-sifive.c diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig index a8f47df..4a61d1a 100644 --- a/drivers/pwm/Kconfig +++ b/drivers/pwm/Kconfig @@ -380,6 +380,17 @@ config PWM_SAMSUNG To compile this driver as a module, choose M here: the module will be called pwm-samsung. +config PWM_SIFIVE + tristate "SiFive PWM support" + depends on OF + depends on COMMON_CLK + depends on RISCV || COMPILE_TEST + help + Generic PWM framework driver for SiFive SoCs. + + To compile this driver as a module, choose M here: the module + will be called pwm-sifive. + config PWM_SPEAR tristate "STMicroelectronics SPEAr PWM support" depends on PLAT_SPEAR diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile index 9c676a0..30089ca 100644 --- a/drivers/pwm/Makefile +++ b/drivers/pwm/Makefile @@ -37,6 +37,7 @@ obj-$(CONFIG_PWM_RCAR)+= pwm-rcar.o obj-$(CONFIG_PWM_RENESAS_TPU) += pwm-renesas-tpu.o obj-$(CONFIG_PWM_ROCKCHIP) += pwm-rockchip.o obj-$(CONFIG_PWM_SAMSUNG) += pwm-samsung.o +obj-$(CONFIG_PWM_SIFIVE) += pwm-sifive.o obj-$(CONFIG_PWM_SPEAR)+= pwm-spear.o obj-$(CONFIG_PWM_STI) += pwm-sti.o obj-$(CONFIG_PWM_STM32)+= pwm-stm32.o diff --git a/drivers/pwm/pwm-sifive.c b/drivers/pwm/pwm-sifive.c new file mode 100644 index 000..bbc4ae8 --- /dev/null +++ b/drivers/pwm/pwm-sifive.c @@ -0,0 +1,262 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2017-2018 SiFive + * For SiFive's PWM IP block documentation please refer Chapter 14 of + * Reference Manual : https://static.dev.sifive.com/FU540-C000-v1.0.pdf + */ +#include +#include +#include +#include +#include +#include + +/* Register offsets */ +#define PWM_SIFIVE_PWMCFG 0x0 +#define PWM_SIFIVE_PWMCOUNT0x8 +#define PWM_SIFIVE_PWMS0x10 +#define PWM_SIFIVE_PWMCMP0 0x20 + +/* PWMCFG fields */ +#define PWM_SIFIVE_PWMCFG_SCALE0 +#define PWM_SIFIVE_PWMCFG_STICKY 8 +#define PWM_SIFIVE_PWMCFG_ZERO_CMP 9 +#define PWM_SIFIVE_PWMCFG_DEGLITCH 10 +#define PWM_SIFIVE_PWMCFG_EN_ALWAYS12 +#define PWM_SIFIVE_PWMCFG_EN_ONCE 13 +#define PWM_SIFIVE_PWMCFG_CENTER 16 +#define PWM_SIFIVE_PWMCFG_GANG 24 +#define PWM_SIFIVE_PWMCFG_IP 28 + +/* SIZE_PWMCMP is used to calculate the offset for pwmcmpX registers */ +#define SIZE_PWMCMP4 +#define CMPWIDTH 16 + +struct pwm_sifive_ddata { + struct pwm_chip chip; + struct notifier_block notifier; + struct clk *clk; + void __iomem *regs; + unsigned int approx_period; + unsigned int real_period; +}; + +static inline struct pwm_sifive_ddata *to_pwm_sifive_chip(struct pwm_chip *c) +{ + return container_of(c, struct pwm_sifive_ddata, chip); +} + +static void pwm_sifive_get_state(struct pwm_chip *chip, struct pwm_device *dev, +struct pwm_state *state) +{ + struct pwm_sifive_ddata *pwm = to_pwm_sifive_chip(chip); + u32 duty; + + duty = readl(pwm->regs + PWM_SIFIVE_PWMCMP0 + dev->hwpwm * SIZE_PWMCMP); + + state->period = pwm->real_period; + state->duty_cycle = ((u64)duty * pwm->real_period) >> CMPWIDTH; + state->polarity = PWM_POLARITY_INVERSED; + state->enabled = duty > 0; +} + +static int pwm_sifive_apply(struct pwm_chip *chip, struct pwm_device *dev, + struct pwm_state *state) +{ + struct pwm_sifive_ddata *pwm = to_pwm_sifive_chip(chip); + unsigned int duty_cycle; + u32 frac, val; + + if (state->polarity != PWM_POLARITY_INVERSED) + return -EINVAL; + + if (state->period != pwm->real_period) + return -EINVAL; + + duty_cycle = state->duty_cycle; + if (!state->enabled) + duty_cycle = 0; + + frac = div_u64((u64)duty_cycle * 0x, state->period); + frac = min(frac, 0xU); + + val = readl(pwm->regs + PWM_SIFIVE_PWMCFG); + val |= (1 << PWM_SIFIVE_PWMCFG_DEGLITCH); + writel(val, pwm->regs + PWM_SIFIVE_PWMCFG); + + writel(frac, pwm->regs + PWM_SIFIVE_PWMCMP0 + dev->hwpwm * SIZE_PWMCMP); + + val &= ~(1 << PWM_SIFIVE_PWMCFG_DEGLITCH); + writel(val, pwm->regs + PWM_SIFIVE_PWMCFG); + + if (state->enabled) +
Re: [PATCH v4 1/2] pwm: sifive: Add DT documentation for SiFive PWM Controller
On Mon, Jan 21, 2019 at 8:29 PM Rob Herring wrote: > > On Mon, Jan 21, 2019 at 03:50:42PM +0530, Yash Shah wrote: > > DT documentation for PWM controller added. > > > > Signed-off-by: Wesley W. Terpstra > > [Atish: Compatible string update] > > Signed-off-by: Atish Patra > > Signed-off-by: Yash Shah > > --- > > .../devicetree/bindings/pwm/pwm-sifive.txt | 37 > > ++ > > 1 file changed, 37 insertions(+) > > create mode 100644 Documentation/devicetree/bindings/pwm/pwm-sifive.txt > > > > diff --git a/Documentation/devicetree/bindings/pwm/pwm-sifive.txt > > b/Documentation/devicetree/bindings/pwm/pwm-sifive.txt > > new file mode 100644 > > index 000..b207908 > > --- /dev/null > > +++ b/Documentation/devicetree/bindings/pwm/pwm-sifive.txt > > @@ -0,0 +1,37 @@ > > +SiFive PWM controller > > + > > +Unlike most other PWM controllers, the SiFive PWM controller currently only > > +supports one period for all channels in the PWM. This is set globally in > > DTS. > > +The period also has significant restrictions on the values it can achieve, > > +which the driver rounds to the nearest achievable frequency. > > + > > +Required properties: > > +- compatible: Should be "sifive,pwmX" and "sifive,$socname-pwm". > > The order here is wrong. Will fix the order. > > You still need to enumeration valid version numbers. Is 'sifive,pwm20' > valid? Yes > > > + Please refer to sifive-blocks-ip-versioning.txt for details. > > +- reg: physical base address and length of the controller's registers > > +- clocks: Should contain a clock identifier for the PWM's parent clock. > > +- #pwm-cells: Should be 2. > > + Refer to bindings/pwm/pwm.txt for details. > > +- sifive,period-ns: the driver will get as close to this period as it can > > +- interrupts: one interrupt per PWM channel > > How many channels? If variable, is the a max number? Max 4 channels. > > > + > > +PWM RTL that corresponds to the IP block version numbers can be found > > +here: > > + > > +https://github.com/sifive/sifive-blocks/tree/master/src/main/scala/devices/pwm > > Put this in the description at the top. Sure. > > > + > > +Further information on the format of the IP > > +block-specific version numbers can be found in > > +Documentation/devicetree/bindings/sifive/sifive-blocks-ip-versioning.txt > > You already said this. Will remove redundant info. > > > + > > +Examples: > > + > > +pwm: pwm@1002 { > > + compatible = "sifive,fu540-c000-pwm","sifive,pwm0"; > > Space after the ',' needed. Sure > > > + reg = <0x0 0x1002 0x0 0x1000>; > > + clocks = <&tlclk>; > > + interrupt-parent = <&plic>; > > + interrupts = <42 43 44 45>; > > + #pwm-cells = <2>; > > + sifive,period-ns = <100>; > > +}; > > -- > > 1.9.1 > > Thanks for the feedback
[PATCH 0/2] net: macb: Add support for SiFive FU540-C000
On FU540, the management IP block is tightly coupled with the Cadence MACB IP block. It manages many of the boundary signals from the MACB IP This patchset controls the tx_clk input signal to the MACB IP. It switches between the local TX clock (125MHz) and PHY TX clocks. This is necessary to toggle between 1Gb and 100/10Mb speeds. Future patches may add support for monitoring or controlling other IP boundary signals. This patchset is mostly based on work done by Wesley Terpstra This patchset is based on Linux v5.2-rc1 and tested on HiFive Unleashed board with additional board related patches needed for testing can be found at dev/yashs/ethernet branch of: https://github.com/yashshah7/riscv-linux.git Yash Shah (2): net/macb: bindings doc: add sifive fu540-c000 binding net: macb: Add support for SiFive FU540-C000 Documentation/devicetree/bindings/net/macb.txt | 3 + drivers/net/ethernet/cadence/macb_main.c | 118 + 2 files changed, 121 insertions(+) -- 1.9.1
[PATCH 1/2] net/macb: bindings doc: add sifive fu540-c000 binding
Add the compatibility string documentation for SiFive FU540-C interface. On the FU540, this driver also needs to read and write registers in a management IP block that monitors or drives boundary signals for the GEMGXL IP block that are not directly mapped to GEMGXL registers. Therefore, add additional range to "reg" property for SiFive GEMGXL management IP registers. Signed-off-by: Yash Shah --- Documentation/devicetree/bindings/net/macb.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/net/macb.txt b/Documentation/devicetree/bindings/net/macb.txt index 9c5e944..91a2a66 100644 --- a/Documentation/devicetree/bindings/net/macb.txt +++ b/Documentation/devicetree/bindings/net/macb.txt @@ -4,6 +4,7 @@ Required properties: - compatible: Should be "cdns,[-]{macb|gem}" Use "cdns,at91rm9200-emac" Atmel at91rm9200 SoC. Use "cdns,at91sam9260-macb" for Atmel at91sam9 SoCs. + Use "cdns,fu540-macb" for SiFive FU540-C000 SoC. Use "cdns,sam9x60-macb" for Microchip sam9x60 SoC. Use "cdns,np4-macb" for NP4 SoC devices. Use "cdns,at32ap7000-macb" for other 10/100 usage or use the generic form: "cdns,macb". @@ -17,6 +18,8 @@ Required properties: Use "cdns,zynqmp-gem" for Zynq Ultrascale+ MPSoC. Or the generic form: "cdns,emac". - reg: Address and length of the register set for the device + For "cdns,fu540-macb", second range is required to specify the + address and length of the registers for GEMGXL Management block. - interrupts: Should contain macb interrupt - phy-mode: See ethernet.txt file in the same directory. - clock-names: Tuple listing input clock names. -- 1.9.1
[PATCH 2/2] net: macb: Add support for SiFive FU540-C000
The management IP block is tightly coupled with the Cadence MACB IP block on the FU540, and manages many of the boundary signals from the MACB IP. This patch only controls the tx_clk input signal to the MACB IP. Future patches may add support for monitoring or controlling other IP boundary signals. Signed-off-by: Yash Shah --- drivers/net/ethernet/cadence/macb_main.c | 118 +++ 1 file changed, 118 insertions(+) diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c index c049410..a9e5227 100644 --- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c @@ -10,6 +10,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include +#include #include #include #include @@ -40,6 +41,15 @@ #include #include "macb.h" +/* This structure is only used for MACB on SiFive FU540 devices */ +struct sifive_fu540_macb_mgmt { + void __iomem *reg; + unsigned long rate; + struct clk_hw hw; +}; + +static struct sifive_fu540_macb_mgmt *mgmt; + #define MACB_RX_BUFFER_SIZE128 #define RX_BUFFER_MULTIPLE 64 /* bytes */ @@ -3903,6 +3913,113 @@ static int at91ether_init(struct platform_device *pdev) return 0; } +static unsigned long fu540_macb_tx_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + return mgmt->rate; +} + +static long fu540_macb_tx_round_rate(struct clk_hw *hw, unsigned long rate, +unsigned long *parent_rate) +{ + if (WARN_ON(rate < 250)) + return 250; + else if (rate == 250) + return 250; + else if (WARN_ON(rate < 1375)) + return 250; + else if (WARN_ON(rate < 2500)) + return 2500; + else if (rate == 2500) + return 2500; + else if (WARN_ON(rate < 7500)) + return 2500; + else if (WARN_ON(rate < 12500)) + return 12500; + else if (rate == 12500) + return 12500; + + WARN_ON(rate > 12500); + + return 12500; +} + +static int fu540_macb_tx_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + rate = fu540_macb_tx_round_rate(hw, rate, &parent_rate); + iowrite32(rate != 12500, mgmt->reg); + mgmt->rate = rate; + + return 0; +} + +static const struct clk_ops fu540_c000_ops = { + .recalc_rate = fu540_macb_tx_recalc_rate, + .round_rate = fu540_macb_tx_round_rate, + .set_rate = fu540_macb_tx_set_rate, +}; + +static int fu540_c000_clk_init(struct platform_device *pdev, struct clk **pclk, + struct clk **hclk, struct clk **tx_clk, + struct clk **rx_clk, struct clk **tsu_clk) +{ + struct clk_init_data init; + int err = 0; + + err = macb_clk_init(pdev, pclk, hclk, tx_clk, rx_clk, tsu_clk); + if (err) + return err; + + mgmt = devm_kzalloc(&pdev->dev, sizeof(*mgmt), GFP_KERNEL); + if (!mgmt) + return -ENOMEM; + + init.name = "sifive-gemgxl-mgmt"; + init.ops = &fu540_c000_ops; + init.flags = 0; + init.num_parents = 0; + + mgmt->rate = 0; + mgmt->hw.init = &init; + + *tx_clk = clk_register(NULL, &mgmt->hw); + if (IS_ERR(*tx_clk)) + return PTR_ERR(*tx_clk); + + err = clk_prepare_enable(*tx_clk); + if (err) + dev_err(&pdev->dev, "failed to enable tx_clk (%u)\n", err); + else + dev_info(&pdev->dev, "Registered clk switch '%s'\n", init.name); + + return 0; +} + +static int fu540_c000_init(struct platform_device *pdev) +{ + struct resource *res; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (!res) + return -ENODEV; + + mgmt->reg = ioremap(res->start, resource_size(res)); + if (!mgmt->reg) + return -ENOMEM; + + return macb_init(pdev); +} + +static const struct macb_config fu540_c000_config = { + .caps = MACB_CAPS_GIGABIT_MODE_AVAILABLE | MACB_CAPS_JUMBO | + MACB_CAPS_GEM_HAS_PTP, + .dma_burst_length = 16, + .clk_init = fu540_c000_clk_init, + .init = fu540_c000_init, + .jumbo_max_len = 10240, +}; + static const struct macb_config at91sam9260_config = { .caps = MACB_CAPS_USRIO_HAS_CLKEN | MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII, .clk_init = macb_clk_init, @@ -3980,6 +4097,7 @@ static int at91ether_init(struct platform_device *pdev) { .compatible = "cdns,at32ap7000-macb" }, { .compatible = "cdns,a
Re: [PATCH v2] edac: sifive: Add EDAC platform driver for SiFive SoCs
On Mon, May 6, 2019 at 4:57 PM Yash Shah wrote: > > The initial ver of EDAC driver supports: > - ECC event monitoring and reporting through the EDAC framework for SiFive > L2 cache controller. > > The EDAC driver registers for notifier events from the L2 cache controller > driver (arch/riscv/mm/sifive_l2_cache.c) for L2 ECC events > > Signed-off-by: Yash Shah > Reviewed-by: James Morse > --- > This patch depends on patch > 'RISC-V: sifive_l2_cache: Add L2 cache controller driver for SiFive SoCs' > https://lkml.org/lkml/2019/5/6/255 The prerequisite patch (sifive_l2_cache driver) has been merged into mainline v5.2-rc1 It should be OK to merge this edac driver now. - Yash
Re: [PATCH 0/2] net: macb: Add support for SiFive FU540-C000
Hi Andreas, On Thu, May 23, 2019 at 6:19 PM Andreas Schwab wrote: > > On Mai 23 2019, Yash Shah wrote: > > > On FU540, the management IP block is tightly coupled with the Cadence > > MACB IP block. It manages many of the boundary signals from the MACB IP > > This patchset controls the tx_clk input signal to the MACB IP. It > > switches between the local TX clock (125MHz) and PHY TX clocks. This > > is necessary to toggle between 1Gb and 100/10Mb speeds. > > Doesn't work for me: > > [ 365.842801] macb: probe of 1009.ethernet failed with error -17 > Make sure you have applied all the patches needed for testing found at dev/yashs/ethernet branch of: https://github.com/yashshah7/riscv-linux.git In addition to that, make sure in your kernel config GPIO_SIFIVE=y In v2 of this patch, I will add this select GPIO_SIFIVE config in the Cadence Kconfig file. - Yash
Re: [PATCH 2/2] net: macb: Add support for SiFive FU540-C000
On Thu, May 23, 2019 at 8:24 PM Andrew Lunn wrote: > > > +static int fu540_macb_tx_set_rate(struct clk_hw *hw, unsigned long rate, > > + unsigned long parent_rate) > > +{ > > + rate = fu540_macb_tx_round_rate(hw, rate, &parent_rate); > > + iowrite32(rate != 12500, mgmt->reg); > > That looks odd. Writing the result of a comparison to a register? The idea was to write "1" to the register if the value of rate is anything else than 12500. To make it easier to read, I will change this to below: - iowrite32(rate != 12500, mgmt->reg); + if (rate != 12500) + iowrite32(1, mgmt->reg); + else + iowrite32(0, mgmt->reg); Hope that's fine. Thanks for your comment - Yash > > Andrew > > ___ > linux-riscv mailing list > linux-ri...@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/linux-riscv
Re: [PATCH 0/2] net: macb: Add support for SiFive FU540-C000
On Thu, May 23, 2019 at 9:58 PM David Miller wrote: > > > Please be consistent in your subsystem prefixes used in your Subject lines. > You use "net: macb:" then "net/macb:" Really, plain "macb: " is sufficient. Sure, Will take care of this in the next revision of this patch. Thanks for your comment. - Yash
Re: [PATCH 1/2] net/macb: bindings doc: add sifive fu540-c000 binding
On Fri, May 24, 2019 at 2:20 AM Rob Herring wrote: > > On Thu, May 23, 2019 at 6:46 AM Yash Shah wrote: > > > > Add the compatibility string documentation for SiFive FU540-C > > interface. > > On the FU540, this driver also needs to read and write registers in a > > management IP block that monitors or drives boundary signals for the > > GEMGXL IP block that are not directly mapped to GEMGXL registers. > > Therefore, add additional range to "reg" property for SiFive GEMGXL > > management IP registers. > > > > Signed-off-by: Yash Shah > > --- > > Documentation/devicetree/bindings/net/macb.txt | 3 +++ > > 1 file changed, 3 insertions(+) > > > > diff --git a/Documentation/devicetree/bindings/net/macb.txt > > b/Documentation/devicetree/bindings/net/macb.txt > > index 9c5e944..91a2a66 100644 > > --- a/Documentation/devicetree/bindings/net/macb.txt > > +++ b/Documentation/devicetree/bindings/net/macb.txt > > @@ -4,6 +4,7 @@ Required properties: > > - compatible: Should be "cdns,[-]{macb|gem}" > >Use "cdns,at91rm9200-emac" Atmel at91rm9200 SoC. > >Use "cdns,at91sam9260-macb" for Atmel at91sam9 SoCs. > > + Use "cdns,fu540-macb" for SiFive FU540-C000 SoC. > > This pattern that Atmel started isn't really correct. The vendor > prefix here should be sifive. 'cdns' would be appropriate for a > fallback. Ok sure. WIll change it to "sifive,fu540-macb" Thanks for your comment. - Yash
Re: [PATCH 0/2] net: macb: Add support for SiFive FU540-C000
On Mon, May 27, 2019 at 1:34 PM Andreas Schwab wrote: > > On Mai 24 2019, Yash Shah wrote: > > > Hi Andreas, > > > > On Thu, May 23, 2019 at 6:19 PM Andreas Schwab wrote: > >> > >> On Mai 23 2019, Yash Shah wrote: > >> > >> > On FU540, the management IP block is tightly coupled with the Cadence > >> > MACB IP block. It manages many of the boundary signals from the MACB IP > >> > This patchset controls the tx_clk input signal to the MACB IP. It > >> > switches between the local TX clock (125MHz) and PHY TX clocks. This > >> > is necessary to toggle between 1Gb and 100/10Mb speeds. > >> > >> Doesn't work for me: > >> > >> [ 365.842801] macb: probe of 1009.ethernet failed with error -17 > >> > > > > Make sure you have applied all the patches needed for testing found at > > dev/yashs/ethernet branch of: > > Nope, try reloading the module. Yes, I could see the error on reloading the module. Thanks for the catch. I will fix this in the next version of this patch. - Yash
[PATCH v12 1/2] pwm: sifive: Add DT documentation for SiFive PWM Controller
DT documentation for PWM controller added. Signed-off-by: Wesley W. Terpstra [Atish: Compatible string update] Signed-off-by: Atish Patra Signed-off-by: Yash Shah Reviewed-by: Rob Herring --- .../devicetree/bindings/pwm/pwm-sifive.txt | 33 ++ 1 file changed, 33 insertions(+) create mode 100644 Documentation/devicetree/bindings/pwm/pwm-sifive.txt diff --git a/Documentation/devicetree/bindings/pwm/pwm-sifive.txt b/Documentation/devicetree/bindings/pwm/pwm-sifive.txt new file mode 100644 index 000..36447e3 --- /dev/null +++ b/Documentation/devicetree/bindings/pwm/pwm-sifive.txt @@ -0,0 +1,33 @@ +SiFive PWM controller + +Unlike most other PWM controllers, the SiFive PWM controller currently only +supports one period for all channels in the PWM. All PWMs need to run at +the same period. The period also has significant restrictions on the values +it can achieve, which the driver rounds to the nearest achievable period. +PWM RTL that corresponds to the IP block version numbers can be found +here: + +https://github.com/sifive/sifive-blocks/tree/master/src/main/scala/devices/pwm + +Required properties: +- compatible: Should be "sifive,-pwm" and "sifive,pwm". + Supported compatible strings are: "sifive,fu540-c000-pwm" for the SiFive + PWM v0 as integrated onto the SiFive FU540 chip, and "sifive,pwm0" for the + SiFive PWM v0 IP block with no chip integration tweaks. + Please refer to sifive-blocks-ip-versioning.txt for details. +- reg: physical base address and length of the controller's registers +- clocks: Should contain a clock identifier for the PWM's parent clock. +- #pwm-cells: Should be 3. See pwm.txt in this directory + for a description of the cell format. +- interrupts: one interrupt per PWM channel + +Examples: + +pwm: pwm@1002 { + compatible = "sifive,fu540-c000-pwm", "sifive,pwm0"; + reg = <0x0 0x1002 0x0 0x1000>; + clocks = <&tlclk>; + interrupt-parent = <&plic>; + interrupts = <42 43 44 45>; + #pwm-cells = <3>; +}; -- 1.9.1
[PATCH v12 0/2] PWM support for HiFive Unleashed
This patch series adds a PWM driver and DT documentation for HiFive Unleashed board. The patches are mostly based on Wesley's patch. This patchset is based on Linux v5.1 and tested on HiFive Unleashed board with additional board related patches needed for testing can be found at dev/yashs/pwm branch of: https://github.com/yashshah7/riscv-linux.git v12 - Rebased onto Mainline v5.1 v11 - Change naming convention for pwm_device and pwm_sifive_ddata pointers - Assign of_pwm_xlate_with_flag() to of_xlate func ptr since this driver use three pwm-cells (Issue reported by Andreas Schwab - Other minor fixes v10 - Use DIV_ROUND_CLOSEST_ULL instead of div_u64_round - Change 'num' defination to u64 bit (in pwm_sifive_apply). - Remove the usage of pwm_get_state() v9 - Use appropriate bitfield macros - Add approx_period in pwm_sifive_ddata struct and related changes - Correct the eqn for calculation of frac (in pwm_sifive_apply) - Other minor fixes v8 - Typo corrections - Remove active_user and related code - Do not clear PWM_SIFIVE_PWMCFG_EN_ALWAYS - Other minor fixes v7 - Modify description of compatible property in DT documentation - Use mutex locks at appropriate places - Fix all bad line breaks - Allow enabling/disabling PWM only when the user is the only active user - Remove Deglitch logic - Other minor fixes v6 - Remove the global property 'sifive,period-ns' - Implement free and request callbacks to maintain user counts. - Add user_count member to struct pwm_sifive_ddata - Allow period change only if user_count is one - Add pwm_sifive_enable function to enable/disable PWM - Change calculation logic of frac (in pwm_sifive_apply) - Remove state correction - Remove pwm_sifive_xlate function - Clock to be enabled only when PWM is enabled - Other minor fixes v5 - Correct the order of compatible string properties - PWM state correction to be done always - Other minor fixes based upon feedback on v4 v4 - Rename macros with appropriate names - Remove unused macros - Rename struct sifive_pwm_device to struct pwm_sifive_ddata - Rename function prefix as per driver name - Other minor fixes based upon feedback on v3 v3 - Add a link to the reference manaul - Use appropriate apis for division operation - Add check for polarity - Enable clk before calling clk_get_rate - Other minor fixes based upon feedback on v2 V2 changed from V1: - Remove inclusion of dt-bindings/pwm/pwm.h - Remove artificial alignments - Replace ioread32/iowrite32 with readl/writel - Remove camelcase - Change dev_info to dev_dbg for unnecessary log - Correct typo in driver name - Remove use of of_match_ptr macro - Update the DT compatible strings and Add reference to a common versioning document Yash Shah (2): pwm: sifive: Add DT documentation for SiFive PWM Controller pwm: sifive: Add a driver for SiFive SoC PWM .../devicetree/bindings/pwm/pwm-sifive.txt | 33 ++ drivers/pwm/Kconfig| 11 + drivers/pwm/Makefile | 1 + drivers/pwm/pwm-sifive.c | 338 + 4 files changed, 383 insertions(+) create mode 100644 Documentation/devicetree/bindings/pwm/pwm-sifive.txt create mode 100644 drivers/pwm/pwm-sifive.c -- 1.9.1
[PATCH v12 2/2] pwm: sifive: Add a driver for SiFive SoC PWM
Adds a PWM driver for PWM chip present in SiFive's HiFive Unleashed SoC. Signed-off-by: Wesley W. Terpstra [Atish: Various fixes and code cleanup] Signed-off-by: Atish Patra Signed-off-by: Yash Shah --- drivers/pwm/Kconfig | 11 ++ drivers/pwm/Makefile | 1 + drivers/pwm/pwm-sifive.c | 338 +++ 3 files changed, 350 insertions(+) create mode 100644 drivers/pwm/pwm-sifive.c diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig index 54f8238..95c1181 100644 --- a/drivers/pwm/Kconfig +++ b/drivers/pwm/Kconfig @@ -389,6 +389,17 @@ config PWM_SAMSUNG To compile this driver as a module, choose M here: the module will be called pwm-samsung. +config PWM_SIFIVE + tristate "SiFive PWM support" + depends on OF + depends on COMMON_CLK + depends on RISCV || COMPILE_TEST + help + Generic PWM framework driver for SiFive SoCs. + + To compile this driver as a module, choose M here: the module + will be called pwm-sifive. + config PWM_SPEAR tristate "STMicroelectronics SPEAr PWM support" depends on PLAT_SPEAR diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile index 448825e..0da3e99 100644 --- a/drivers/pwm/Makefile +++ b/drivers/pwm/Makefile @@ -38,6 +38,7 @@ obj-$(CONFIG_PWM_RCAR)+= pwm-rcar.o obj-$(CONFIG_PWM_RENESAS_TPU) += pwm-renesas-tpu.o obj-$(CONFIG_PWM_ROCKCHIP) += pwm-rockchip.o obj-$(CONFIG_PWM_SAMSUNG) += pwm-samsung.o +obj-$(CONFIG_PWM_SIFIVE) += pwm-sifive.o obj-$(CONFIG_PWM_SPEAR)+= pwm-spear.o obj-$(CONFIG_PWM_STI) += pwm-sti.o obj-$(CONFIG_PWM_STM32)+= pwm-stm32.o diff --git a/drivers/pwm/pwm-sifive.c b/drivers/pwm/pwm-sifive.c new file mode 100644 index 000..1921e6ea --- /dev/null +++ b/drivers/pwm/pwm-sifive.c @@ -0,0 +1,338 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2017-2018 SiFive + * For SiFive's PWM IP block documentation please refer Chapter 14 of + * Reference Manual : https://static.dev.sifive.com/FU540-C000-v1.0.pdf + * + * Limitations: + * - When changing both duty cycle and period, we cannot prevent in + * software that the output might produce a period with mixed + * settings (new period length and old duty cycle). + * - The hardware cannot generate a 100% duty cycle. + * - The hardware generates only inverted output. + */ +#include +#include +#include +#include +#include +#include +#include + +/* Register offsets */ +#define PWM_SIFIVE_PWMCFG 0x0 +#define PWM_SIFIVE_PWMCOUNT0x8 +#define PWM_SIFIVE_PWMS0x10 +#define PWM_SIFIVE_PWMCMP0 0x20 + +/* PWMCFG fields */ +#define PWM_SIFIVE_PWMCFG_SCALEGENMASK(3, 0) +#define PWM_SIFIVE_PWMCFG_STICKY BIT(8) +#define PWM_SIFIVE_PWMCFG_ZERO_CMP BIT(9) +#define PWM_SIFIVE_PWMCFG_DEGLITCH BIT(10) +#define PWM_SIFIVE_PWMCFG_EN_ALWAYSBIT(12) +#define PWM_SIFIVE_PWMCFG_EN_ONCE BIT(13) +#define PWM_SIFIVE_PWMCFG_CENTER BIT(16) +#define PWM_SIFIVE_PWMCFG_GANG BIT(24) +#define PWM_SIFIVE_PWMCFG_IP BIT(28) + +/* PWM_SIFIVE_SIZE_PWMCMP is used to calculate offset for pwmcmpX registers */ +#define PWM_SIFIVE_SIZE_PWMCMP 4 +#define PWM_SIFIVE_CMPWIDTH16 +#define PWM_SIFIVE_DEFAULT_PERIOD 1000 + +struct pwm_sifive_ddata { + struct pwm_chip chip; + struct mutex lock; /* lock to protect user_count */ + struct notifier_block notifier; + struct clk *clk; + void __iomem *regs; + unsigned int real_period; + unsigned int approx_period; + int user_count; +}; + +static inline +struct pwm_sifive_ddata *pwm_sifive_chip_to_ddata(struct pwm_chip *c) +{ + return container_of(c, struct pwm_sifive_ddata, chip); +} + +static int pwm_sifive_request(struct pwm_chip *chip, struct pwm_device *pwm) +{ + struct pwm_sifive_ddata *ddata = pwm_sifive_chip_to_ddata(chip); + + mutex_lock(&ddata->lock); + ddata->user_count++; + mutex_unlock(&ddata->lock); + + return 0; +} + +static void pwm_sifive_free(struct pwm_chip *chip, struct pwm_device *pwm) +{ + struct pwm_sifive_ddata *ddata = pwm_sifive_chip_to_ddata(chip); + + mutex_lock(&ddata->lock); + ddata->user_count--; + mutex_unlock(&ddata->lock); +} + +static void pwm_sifive_update_clock(struct pwm_sifive_ddata *ddata, + unsigned long rate) +{ + unsigned long long num; + unsigned long scale_pow; + int scale; + u32 val; + /* +* The PWM unit is used with pwmzerocmp=0, so the only way to modify the +* period length is using pwmscale which provides the number of bits the +* counter is shifted before being feed to the comparators. A period +* lasts (1
Re: [PATCH] edac: sifive: Add EDAC platform driver for SiFive SoCs
Hi james, On Thu, May 2, 2019 at 10:12 PM James Morse wrote: > > Hi Yash, > > Sorry for the delay on the earlier version of this - I was trying to work out > what happens > when multiple edac drivers probe based on DT... > > > On 02/05/2019 12:16, Yash Shah wrote: > > The initial ver of EDAC driver supports: > > - ECC event monitoring and reporting through the EDAC framework for SiFive > > L2 cache controller. > > > > You probably don't want this bit preserved in the kernel log: > { > > > This patch depends on patch > > 'RISC-V: sifive_l2_cache: Add L2 cache controller driver for SiFive SoCs' > > https://lkml.org/lkml/2019/5/2/309 > > } > > > The EDAC driver registers for notifier events from the L2 cache controller > > driver (arch/riscv/mm/sifive_l2_cache.c) for L2 ECC events > > > > Signed-off-by: Yash Shah > > --- > > (if you put it here, it gets discarded when the patch is applied) Ok, will move it down here. > > Having an separately posted dependency like this is tricky, as this code > can't be > used/tested until the other bits are merged. > > > > MAINTAINERS| 6 +++ > > arch/riscv/Kconfig | 1 + > > drivers/edac/Kconfig | 6 +++ > > drivers/edac/Makefile | 1 + > > drivers/edac/sifive_edac.c | 121 > > + > > 5 files changed, 135 insertions(+) > > create mode 100644 drivers/edac/sifive_edac.c > > > diff --git a/drivers/edac/sifive_edac.c b/drivers/edac/sifive_edac.c > > new file mode 100644 > > index 000..eb7a9b9 > > --- /dev/null > > +++ b/drivers/edac/sifive_edac.c > > @@ -0,0 +1,121 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > +/* > > + * SiFive Platform EDAC Driver > > + * > > + * Copyright (C) 2018-2019 SiFive, Inc. > > + * > > + * This driver is partially based on octeon_edac-pc.c > > + * > > + */ > > +#include > > +#include > > +#include "edac_module.h" > > + > > +#define DRVNAME "sifive_edac" > > + > > +extern int register_sifive_l2_error_notifier(struct notifier_block *nb); > > +extern int unregister_sifive_l2_error_notifier(struct notifier_block *nb); > > Ideally these would live in some header file. Will move the externs in sifive_l2_cache header file > > > > +struct sifive_edac_priv { > > + struct notifier_block notifier; > > + struct edac_device_ctl_info *dci; > > +}; > > + > > +/** > > + * EDAC error callback > > + * > > + * @event: non-zero if unrecoverable. > > + */ > > +static > > +int ecc_err_event(struct notifier_block *this, unsigned long event, void > > *ptr) > > +{ > > + const char *msg = (char *)ptr; > > + struct sifive_edac_priv *p; > > + > > + p = container_of(this, struct sifive_edac_priv, notifier); > > + > > + if (event) > > + edac_device_handle_ue(p->dci, 0, 0, msg); > > + else > > + edac_device_handle_ce(p->dci, 0, 0, msg); > > This would be easier to read if your SIFIVE_L2_ERR_TYPE_UE were exposed via > some header file. sure. > > > > + > > + return NOTIFY_STOP; > > Your notifier register calls are EXPORT_SYMBOL()d, but Kconfig forbids > building this as a > module, so its not for this driver. If there is another user of this > notifier-chain, won't > NOTIFY_STOP here break it? > Yes, you are right. Will change it to NOTIFY_OK > > > +} > > + > > +static int ecc_register(struct platform_device *pdev) > > +{ > > + struct sifive_edac_priv *p; > > + > > + p = devm_kzalloc(&pdev->dev, sizeof(*p), GFP_KERNEL); > > + if (!p) > > + return -ENOMEM; > > + > > + p->notifier.notifier_call = ecc_err_event; > > + platform_set_drvdata(pdev, p); > > + > > + p->dci = edac_device_alloc_ctl_info(sizeof(*p), "sifive_ecc", 1, > > sizeof(*p) here is how much space in struct edac_device_ctl_info you need for > private > storage... but you never touch p->dci->pvt_info, so you aren't using it. > > 0? Yes, will change it. > > > > + "sifive_ecc", 1, 1, NULL, 0, > > + edac_device_alloc_index()); > > + if (IS_ERR(p->dci)) > > + return PTR_ERR(p->dci); > > + > > + p->dci->dev = &pdev->dev; &
[PATCH v3 1/2] RISC-V: Add DT documentation for SiFive L2 Cache Controller
Add device tree bindings for SiFive FU540 L2 cache controller driver Signed-off-by: Yash Shah --- .../devicetree/bindings/riscv/sifive-l2-cache.txt | 51 ++ 1 file changed, 51 insertions(+) create mode 100644 Documentation/devicetree/bindings/riscv/sifive-l2-cache.txt diff --git a/Documentation/devicetree/bindings/riscv/sifive-l2-cache.txt b/Documentation/devicetree/bindings/riscv/sifive-l2-cache.txt new file mode 100644 index 000..73d8f19 --- /dev/null +++ b/Documentation/devicetree/bindings/riscv/sifive-l2-cache.txt @@ -0,0 +1,51 @@ +SiFive L2 Cache Controller +-- +The SiFive Level 2 Cache Controller is used to provide access to fast copies +of memory for masters in a Core Complex. The Level 2 Cache Controller also +acts as directory-based coherency manager. +All the properties in ePAPR/DeviceTree specification applies for this platform + +Required Properties: + +- compatible: Should be "sifive,fu540-c000-ccache" and "cache" + +- cache-block-size: Specifies the block size in bytes of the cache. + Should be 64 + +- cache-level: Should be set to 2 for a level 2 cache + +- cache-sets: Specifies the number of associativity sets of the cache. + Should be 1024 + +- cache-size: Specifies the size in bytes of the cache. Should be 2097152 + +- cache-unified: Specifies the cache is a unified cache + +- interrupts: Must contain 3 entries (DirError, DataError and DataFail signals) + +- reg: Physical base address and size of L2 cache controller registers map + +Optional Properties: + +- next-level-cache: phandle to the next level cache if present. + +- memory-region: reference to the reserved-memory for the L2 Loosely Integrated + Memory region. The reserved memory node should be defined as per the bindings + in reserved-memory.txt + + +Example: + + cache-controller@201 { + compatible = "sifive,fu540-c000-ccache", "cache"; + cache-block-size = <64>; + cache-level = <2>; + cache-sets = <1024>; + cache-size = <2097152>; + cache-unified; + interrupt-parent = <&plic0>; + interrupts = <1 2 3>; + reg = <0x0 0x201 0x0 0x1000>; + next-level-cache = <&L25 &L40 &L36>; + memory-region = <&l2_lim>; + }; -- 1.9.1
[PATCH v3 0/2] L2 cache controller support for SiFive FU540
This patch series adds an L2 cache controller driver with DT documentation for SiFive FU540-C000. These two patches were initially part of the patch series: 'L2 cache controller and EDAC support for SiFive SoCs' https://lkml.org/lkml/2019/4/15/320 In order to merge L2 cache controller driver without any dependency on EDAC, the L2 cache controller patches are re-posted separately in this series. The patchset is based on Linux 5.1-rc2 and tested on HiFive Unleashed board with additional board related patches needed for testing can be found at dev/yashs/L2_cache_controller branch of: https://github.com/yashshah7/riscv-linux.git Changes since v2 - Add a header file to expose Macros and extern functions - Remove all single line functions Changes since v1 - Mention the valid values for cache properties in DT documentation - Remove the unnecessary property 'reg-names' - Add "cache" to supported compatible string property - Remove conditional checks from debugfs functions in sifive_l2_cache.c Yash Shah (2): RISC-V: Add DT documentation for SiFive L2 Cache Controller RISC-V: sifive_l2_cache: Add L2 cache controller driver for SiFive SoCs .../devicetree/bindings/riscv/sifive-l2-cache.txt | 51 ++ arch/riscv/include/asm/sifive_l2_cache.h | 16 ++ arch/riscv/mm/Makefile | 1 + arch/riscv/mm/sifive_l2_cache.c| 175 + 4 files changed, 243 insertions(+) create mode 100644 Documentation/devicetree/bindings/riscv/sifive-l2-cache.txt create mode 100644 arch/riscv/include/asm/sifive_l2_cache.h create mode 100644 arch/riscv/mm/sifive_l2_cache.c -- 1.9.1