Message ID | 20220510151112.16249-5-biju.das.jz@bp.renesas.com (mailing list archive) |
---|---|
State | Superseded |
Delegated to: | Geert Uytterhoeven |
Headers | show |
Series | Add RZ/G2L POEG support | expand |
Hi Biju, On Tue, May 10, 2022 at 5:11 PM Biju Das <biju.das.jz@bp.renesas.com> wrote: > This patch add support for linking POEG group with pwm, so that > POEG can control the output disable function. > > Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com> Thanks for your patch! > --- a/drivers/pwm/pwm-rzg2l-gpt.c > +++ b/drivers/pwm/pwm-rzg2l-gpt.c > @@ -266,6 +291,36 @@ static int rzg2l_gpt_apply(struct pwm_chip *chip, struct pwm_device *pwm, > return ret; > } > > +static int rzg2l_gpt_parse_properties(struct platform_device *pdev, > + struct rzg2l_gpt_chip *pc) > +{ > + static const u64 poeg_grp_addr[] = { > + POEG_GRP_A_ADDR, POEG_GRP_B_ADDR, POEG_GRP_C_ADDR, POEG_GRP_D_ADDR > + }; > + struct device_node *np; > + unsigned int i; > + u64 addr; > + > + pc->poeg_grp = GRP_INVALID; > + np = of_parse_phandle(pdev->dev.of_node, "renesas,poeg-group", 0); > + if (!np) > + return 0; > + > + if (!of_property_read_u64(np, "reg", &addr)) { > + for (i = 0; i < ARRAY_SIZE(poeg_grp_addr); i++) { > + if (addr == poeg_grp_addr[i]) { Matching on addresses looks fragile to me. Of course this is code, not DT, so it can be changed later. Possible alternatives: 1. Use a numeric property instead of a phandle, so you can store its value directly into pc->poeg_grp. This loses the linking by phandle, though, which is nice to have, and might be useful for other purposes later. 2. Add a "renesas,id" property to each POEGx DT node, cfr. Documentation/devicetree/bindings/media/renesas,vin.yaml. > + pc->poeg_grp = i; > + break; > + } > + } > + } > + > + if (np) > + of_node_put(np); > + > + return 0; > +} Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
Hi Geert, Thanks for the feedback. > Subject: Re: [RFC 4/8] pwm: rzg2l-gpt: Add support for linking with POEG > > Hi Biju, > > On Tue, May 10, 2022 at 5:11 PM Biju Das <biju.das.jz@bp.renesas.com> > wrote: > > This patch add support for linking POEG group with pwm, so that POEG > > can control the output disable function. > > > > Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com> > > Thanks for your patch! > > > --- a/drivers/pwm/pwm-rzg2l-gpt.c > > +++ b/drivers/pwm/pwm-rzg2l-gpt.c > > @@ -266,6 +291,36 @@ static int rzg2l_gpt_apply(struct pwm_chip *chip, > struct pwm_device *pwm, > > return ret; > > } > > > > +static int rzg2l_gpt_parse_properties(struct platform_device *pdev, > > + struct rzg2l_gpt_chip *pc) { > > + static const u64 poeg_grp_addr[] = { > > + POEG_GRP_A_ADDR, POEG_GRP_B_ADDR, POEG_GRP_C_ADDR, > POEG_GRP_D_ADDR > > + }; > > + struct device_node *np; > > + unsigned int i; > > + u64 addr; > > + > > + pc->poeg_grp = GRP_INVALID; > > + np = of_parse_phandle(pdev->dev.of_node, "renesas,poeg-group", > 0); > > + if (!np) > > + return 0; > > + > > + if (!of_property_read_u64(np, "reg", &addr)) { > > + for (i = 0; i < ARRAY_SIZE(poeg_grp_addr); i++) { > > + if (addr == poeg_grp_addr[i]) { > > Matching on addresses looks fragile to me. > Of course this is code, not DT, so it can be changed later. > > Possible alternatives: > 1. Use a numeric property instead of a phandle, so you can store > its value directly into pc->poeg_grp. > This loses the linking by phandle, though, which is nice to > have, and might be useful for other purposes later. OK, will use a numeric property as default POEGGroup. Cheers, Biju > 2. Add a "renesas,id" property to each POEGx DT node, cfr. > Documentation/devicetree/bindings/media/renesas,vin.yaml. > > > + pc->poeg_grp = i; > > + break; > > + } > > + } > > + } > > + > > + if (np) > > + of_node_put(np); > > + > > + return 0; > > +} > > Gr{oetje,eeting}s, > > Geert > > -- > Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux- > m68k.org > > In personal conversations with technical people, I call myself a hacker. > But when I'm talking to journalists I just say "programmer" or something > like that. > -- Linus Torvalds
diff --git a/drivers/pwm/pwm-rzg2l-gpt.c b/drivers/pwm/pwm-rzg2l-gpt.c index d5d22b1ff792..8eaf96b2052d 100644 --- a/drivers/pwm/pwm-rzg2l-gpt.c +++ b/drivers/pwm/pwm-rzg2l-gpt.c @@ -21,6 +21,7 @@ #define GTCR 0x2c #define GTUDDTYC 0x30 #define GTIOR 0x34 +#define GTINTAD 0x38 #define GTBER 0x40 #define GTCNT 0x48 #define GTCCRA 0x4c @@ -37,9 +38,14 @@ #define UP_COUNTING (GTUDDTYC_UP | GTUDDTYC_UDF) #define GTIOR_GTIOA_MASK GENMASK(4, 0) +#define GTIOR_OADF_MASK GENMASK(10, 9) #define GTIOR_GTIOB_MASK GENMASK(20, 16) +#define GTIOR_OBDF_MASK GENMASK(26, 25) + #define GTIOR_OAE BIT(8) #define GTIOR_OBE BIT(24) +#define GTIOR_OADF_HIGH_IMP_ON_OUT_DISABLE (1 << 9) +#define GTIOR_OBDF_HIGH_IMP_ON_OUT_DISABLE (1 << 25) #define INIT_OUT_LO_OUT_LO_END_TOGGLE (0x07) #define INIT_OUT_HI_OUT_HI_END_TOGGLE (0x1B) @@ -48,6 +54,13 @@ #define GTIOR_GTIOB_OUT_HI_END_TOGGLE_CMP_MATCH ((INIT_OUT_HI_OUT_HI_END_TOGGLE << 16) | GTIOR_OBE) #define GTIOR_GTIOB_OUT_LO_END_TOGGLE_CMP_MATCH ((INIT_OUT_LO_OUT_LO_END_TOGGLE << 16) | GTIOR_OBE) +#define GTINTAD_GRP_MASK GENMASK(25, 24) +#define GRP_INVALID (0xFF) +#define POEG_GRP_A_ADDR (0x10048800) +#define POEG_GRP_B_ADDR (0x10048c00) +#define POEG_GRP_C_ADDR (0x10049000) +#define POEG_GRP_D_ADDR (0x10049400) + struct phase { u32 value; u32 mask; @@ -85,6 +98,7 @@ struct rzg2l_gpt_chip { void __iomem *mmio; struct reset_control *rstc; struct clk *clk; + u8 poeg_grp; }; static inline struct rzg2l_gpt_chip *to_rzg2l_gpt_chip(struct pwm_chip *chip) @@ -220,6 +234,17 @@ static int rzg2l_gpt_config(struct pwm_chip *chip, struct pwm_device *_pwm, /* Set period */ rzg2l_gpt_write(pc, GTPR, pv); + if (pc->poeg_grp != GRP_INVALID) { + rzg2l_gpt_modify(pc, GTINTAD, GTINTAD_GRP_MASK, pc->poeg_grp << 24); + + if (pwm->channel) + rzg2l_gpt_modify(pc, GTIOR, GTIOR_OBDF_MASK, + GTIOR_OBDF_HIGH_IMP_ON_OUT_DISABLE); + else + rzg2l_gpt_modify(pc, GTIOR, GTIOR_OADF_MASK, + GTIOR_OADF_HIGH_IMP_ON_OUT_DISABLE); + } + /* Enable pin output */ rzg2l_gpt_modify(pc, GTIOR, pwm->ph->mask, pwm->ph->value); @@ -266,6 +291,36 @@ static int rzg2l_gpt_apply(struct pwm_chip *chip, struct pwm_device *pwm, return ret; } +static int rzg2l_gpt_parse_properties(struct platform_device *pdev, + struct rzg2l_gpt_chip *pc) +{ + static const u64 poeg_grp_addr[] = { + POEG_GRP_A_ADDR, POEG_GRP_B_ADDR, POEG_GRP_C_ADDR, POEG_GRP_D_ADDR + }; + struct device_node *np; + unsigned int i; + u64 addr; + + pc->poeg_grp = GRP_INVALID; + np = of_parse_phandle(pdev->dev.of_node, "renesas,poeg-group", 0); + if (!np) + return 0; + + if (!of_property_read_u64(np, "reg", &addr)) { + for (i = 0; i < ARRAY_SIZE(poeg_grp_addr); i++) { + if (addr == poeg_grp_addr[i]) { + pc->poeg_grp = i; + break; + } + } + } + + if (np) + of_node_put(np); + + return 0; +} + static const struct pwm_ops rzg2l_gpt_ops = { .request = rzg2l_gpt_request, .free = rzg2l_gpt_free, @@ -288,6 +343,10 @@ static int rzg2l_gpt_probe(struct platform_device *pdev) if (!rzg2l_gpt) return -ENOMEM; + ret = rzg2l_gpt_parse_properties(pdev, rzg2l_gpt); + if (ret) + return ret; + rzg2l_gpt->mmio = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(rzg2l_gpt->mmio)) return PTR_ERR(rzg2l_gpt->mmio);
This patch add support for linking POEG group with pwm, so that POEG can control the output disable function. Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com> --- drivers/pwm/pwm-rzg2l-gpt.c | 59 +++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+)