Pin as PWM-Clock Output

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Pin as PWM-Clock Output

Jump to solution
5,291 Views
gdobato
Contributor I

Hello,

I am trying to set a PIN (GPIO9) as PWM-Clock Output. Below, the nodes on .dts according to Documentation/devicetree/bindings/clock/pwm-clock.txt :

On SoC.dtsi file:

...

                        pwm1: pwm@02080000 {    

                                #pwm-cells = <2>;

                                compatible = "fsl,imx6q-pwm", "fsl,imx27-pwm";

                                reg = <0x02080000 0x4000>;

                                interrupts = <0 83 IRQ_TYPE_LEVEL_HIGH>;

                                clocks = <&clks IMX6QDL_CLK_IPG>,

                                         <&clks IMX6QDL_CLK_PWM1>;

                                clock-names = "ipg", "per";

                                status = "disabled";

                        };

on SoM.dtsi file:

/*

*

* PWM-Clock

* 8,25MHz SIgnal on GPIO09 (PWM1)

*

*/

        clock {

               compatible = "pwm-clock";

               #clock-cells = <0>;

               clock-frequency = <8250000>;

               clock-output-names = "pwm_clk";

               pwms = <&pwm1 0 121>;

       };

...

/*

*

* PWM1

*

*/

&pwm1 {

      pinctrl-names = "default";

      pinctrl-0 = <&pinctrl_pwm1>;

      status = "okay";

};

...

                pinctrl_pwm1: pwm1grp {

                        fsl,pins = <

                                MX6QDL_PAD_GPIO_9__PWM1_OUT            0x0001b0b0

                        >;

                };

I would like to set and enable the PWM1 on kernel stage, not on user-space via (/sys/class/pwm). The output value of the pin is always 0... no signal on it :smileysad:   What am I doing wrong ? Did I miss something?  AFAIK  it should be possible, actually it would be the objective of pwm-clock driver...

Thank you :smileyhappy:

Labels (3)
0 Kudos
1 Solution
3,222 Views
fabio_estevam
NXP Employee
NXP Employee

Yes, it is. You can use "compatible = "pwm-leds";" for a reference.

View solution in original post

0 Kudos
10 Replies
3,222 Views
johndehelian
Contributor I

I'm trying to use the PWMs on the i.MX6ULL and am not satisfied with the pwm-backlight interface. It introduces some glitches when adjusting duty cycle. If I use the direct /sys/class/pwm/pwmchip1/pwm0 interface it works fine. But I cannot enable it from the device tree. I tried this:

 

    pwmleds {
        compatible = "pwm-leds";
        pinctrl-names = "default";

        led1 {
            label = "imx6:led1";
            max-brightness = <248>;
            pwms = <&pwm2 0 10000>;
        };
        led2 {
            label = "imx6:led2";
            max-brightness = <248>;
            pwms = <&pwm3 1 10000>;
        };
        led3 {
            label = "imx6:led3";
            max-brightness = <248>;
            pwms = <&pwm4 2 10000>;
        };
    };

But it doesn't enable the leds in /sys/class/leds or anywhere. So I have to manually enable at 50 % duty cycle with :

echo 0 > /sys/class/pwm/pwmchip1/export

echo 1 > /sys/class/pwm/pwmchip1/pwm0/enable

echo 100000 > /sys/class/pwm/pwmchip1/pwm0/period

echo 50000 > /sys/class/pwm/pwmchip1/pwm0/duty_cycle

Are pwm-leds supported by imx driver?

0 Kudos
3,222 Views
fabio_estevam
NXP Employee
NXP Employee

Hi John,

Make sure you have the CONFIG_LEDS_PWM=y option selected in your defconfig.

0 Kudos
3,222 Views
fabio_estevam
NXP Employee
NXP Employee

The line pwms = <&pwm1 0 121>; does not look correct.

0 Kudos
3,222 Views
gdobato
Contributor I

Hi Fabio,

Thanks for the answer.

Why is it not correct ? I think I set the values according to Linux/Documentation/devicetree/bindings/clock/pwm-clock.txt - Linux Cross Reference - Free Electrons  :

Required properties:

  compatible : shall be "pwm-clock".

#clock-cells : from common clock binding; shall be set to 0.

pwms : from common PWM binding; this determines the clock frequency

via the period given in the PWM specifier.

Optional properties:

clock-output-names : From common clock binding.

clock-frequency : Exact output frequency, in case the PWM period

is not exact but was rounded to nanoseconds.

Example:

  clock {

​  compatible = "pwm-clock";

  #clock-cells = <0>;

  clock-frequency = <25000000>;

  clock-output-names = "mipi_mclk";

pwms = <&pwm2 0 40>; /* 1 / 40 ns = 25 MHz */

};

BTW, I also tried the values above, but same results...

Gabriel

0 Kudos
3,222 Views
fabio_estevam
NXP Employee
NXP Employee

The 121 from your example looks strange.

Take a look at  arch/arm/boot/dts/imx6qdl-sabresd.dtsi:

backlight {
   compatible = "pwm-backlight";
   pwms = <&pwm1 0 5000000>;
   brightness-levels = <0 4 8 16 32 64 128 255>;
   default-brightness-level = <7>;
   status = "okay";

    };

0 Kudos
3,222 Views
gdobato
Contributor I

Hi Fabio,

it makes use of "pwm-backlight" driver which is a little different. AFAIK, that driver does not allow to work in range of 8 MHz, and it is enabled by /sys/class on userspace..

Is it not possible to set a GPIO as PWM clock on boottime ?

Thx,


Gabriel

0 Kudos
3,223 Views
fabio_estevam
NXP Employee
NXP Employee

Yes, it is. You can use "compatible = "pwm-leds";" for a reference.

0 Kudos
3,222 Views
gdobato
Contributor I

Hello Fabio,

Ok thanks, I gonna give it try.

0 Kudos
3,222 Views
alejandrolozan1
NXP Employee
NXP Employee

Hi,

Which Linux version are you using? After skimming through the L3.14.28 source code I did not find any device driver related to the compatible = "pwm-clock".

Best Regards,

Alejandro

0 Kudos
3,222 Views
gdobato
Contributor I

Hi Alejandro,

thanks  for the answer!

I am using 4.1.13, the driver was introduced in 4.1:

Linux/drivers/clk/clk-pwm.c - Linux Cross Reference - Free Electrons

Linux/Documentation/devicetree/bindings/clock/pwm-clock.txt - Linux Cross Reference - Free Electrons

Anyway, is it possible to configure a GPIO as PWM on boot time ?

What I have made sofar is a module just to write on the correspondent registers in order to configure the GPIO PAD, MUX and PWM  according to IMX6 user-guide.

#define REGBASE 0x02000000

#define memsize 0x32

/* MUX & PAD */

        void __iomem *io1 = ioremap(REGBASE + 0xc4078, memsize);

        void __iomem *io2 = ioremap(REGBASE + 0xe0240, memsize);

        void __iomem *io3 = ioremap(REGBASE + 0xe0610, memsize);

        writel(0x3c303,io1);

        writel(0x4, io2);

        writel(0x1b0b0, io3);

/* PWM */

        void __iomem *io4 = ioremap(REGBASE + 0x80010, memsize);

        void __iomem *io5 = ioremap(REGBASE + 0x8000c, memsize);

        void __iomem *io6 = ioremap(REGBASE + 0x80000, memsize);

        writel(0x6, io4);

        writel(0x4, io5);

        writel(0x03c20001, io6);

It works, I have a PWM 8,25 Mhz (50 % duty cycle) but it is only for testing. I would like to do the same using the current drivers and on a clearer way...

Gabriel

0 Kudos