diff mbox series

[2/2] dt-bindings: mfd: add Broadcom's timer MFD block

Message ID 20211029202505.7106-2-zajec5@gmail.com (mailing list archive)
State Superseded
Headers show
Series [1/2] dt-bindings: watchdog: convert Broadcom's WDT to the json-schema | expand

Commit Message

Rafał Miłecki Oct. 29, 2021, 8:25 p.m. UTC
From: Rafał Miłecki <rafal@milecki.pl>

This block is called timer in documentation but it actually behaves like
a MFD.

Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
---
 .../bindings/mfd/brcm,timer-mfd.yaml          | 64 +++++++++++++++++++
 1 file changed, 64 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mfd/brcm,timer-mfd.yaml

Comments

Florian Fainelli Oct. 29, 2021, 9:03 p.m. UTC | #1
On 10/29/21 1:25 PM, Rafał Miłecki wrote:
> From: Rafał Miłecki <rafal@milecki.pl>
> 
> This block is called timer in documentation but it actually behaves like
> a MFD.
> 
> Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
> ---
>  .../bindings/mfd/brcm,timer-mfd.yaml          | 64 +++++++++++++++++++
>  1 file changed, 64 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/mfd/brcm,timer-mfd.yaml
> 
> diff --git a/Documentation/devicetree/bindings/mfd/brcm,timer-mfd.yaml b/Documentation/devicetree/bindings/mfd/brcm,timer-mfd.yaml
> new file mode 100644
> index 000000000000..0060b6c443a7
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mfd/brcm,timer-mfd.yaml
> @@ -0,0 +1,64 @@
> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/mfd/brcm,timer-mfd.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Broadcom's timer MFD
> +
> +maintainers:
> +  - Rafał Miłecki <rafal@milecki.pl>
> +
> +description: |
> +  Broadcom's timer is a block used in multiple SoCs (e.g., BCM4908, BCM63xx,
> +  BCM7038). Despite its name it's not strictly a timer device. It consists of:
> +  timers, watchdog and software reset handler.

Small nit here, the software reset handler part is only present on the
BCM63xx and BCM4908 (which is a derivative of 63xx) but not on the
BCM7xxx chips.

Also, there is some difference in how the registers are organized:

4908 has it that way:

TIMERCTL0
TIMERCTL1
TIMERCTL2
TIMERCNT0
TIMERCNT1
TIMERCNT2
TIMERIRQMASK
TIMERIRQSTAT
WATCHDOG_COUNT
WATCHDOG_CTL
WATCHDOG_RESET_CNT
CHIP_RESET

Whereas on STB chips it looks like this for all chips:

TIMERIS (interrupt status)
TIMERIE (interrupt enable)
TIMER0_CTRL
TIMER1_CTRL
TIMER2_CTRL
TIMER3_CTRL
TIMER0_STATUS
TIMER1_STATUS
TIMER2_STATUS
TIMER3_STATUS
WATCHDOG_COUNT
WATCHDOT_CTL
WATCHDOG_RESET_CNT
TIMERIE0 (interrupt enable the STB chip is a PCI(e) end-point)
WATCHDOG_CTRL (controls the type of event signaled: NMI, half-life etc.)

I suppose it is just more justification to have them broken out as
separate blocks given their layout looks largely the same except where
it does not.

Thanks
Rafał Miłecki Oct. 29, 2021, 9:20 p.m. UTC | #2
On 29.10.2021 23:03, Florian Fainelli wrote:
> On 10/29/21 1:25 PM, Rafał Miłecki wrote:
>> From: Rafał Miłecki <rafal@milecki.pl>
>>
>> This block is called timer in documentation but it actually behaves like
>> a MFD.
>>
>> Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
>> ---
>>   .../bindings/mfd/brcm,timer-mfd.yaml          | 64 +++++++++++++++++++
>>   1 file changed, 64 insertions(+)
>>   create mode 100644 Documentation/devicetree/bindings/mfd/brcm,timer-mfd.yaml
>>
>> diff --git a/Documentation/devicetree/bindings/mfd/brcm,timer-mfd.yaml b/Documentation/devicetree/bindings/mfd/brcm,timer-mfd.yaml
>> new file mode 100644
>> index 000000000000..0060b6c443a7
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/mfd/brcm,timer-mfd.yaml
>> @@ -0,0 +1,64 @@
>> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/mfd/brcm,timer-mfd.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Broadcom's timer MFD
>> +
>> +maintainers:
>> +  - Rafał Miłecki <rafal@milecki.pl>
>> +
>> +description: |
>> +  Broadcom's timer is a block used in multiple SoCs (e.g., BCM4908, BCM63xx,
>> +  BCM7038). Despite its name it's not strictly a timer device. It consists of:
>> +  timers, watchdog and software reset handler.
> 
> Small nit here, the software reset handler part is only present on the
> BCM63xx and BCM4908 (which is a derivative of 63xx) but not on the
> BCM7xxx chips.

Should I simply make it "and (optionally) software reset handler"?


> Also, there is some difference in how the registers are organized:

My complete summary if someone really wants to study that:

==> 4908_map_part.h <==
typedef struct Timer {
         uint32  TimerCtl0;              /* 0x00 */
         uint32  TimerCtl1;              /* 0x04 */
         uint32  TimerCtl2;              /* 0x08 */
         uint32  TimerCtl3;              /* 0x0c */
#define TIMERENABLE                     0x80000000
#define RSTCNTCLR                       0x40000000

         uint32  TimerCnt0;              /* 0x10 */
         uint32  TimerCnt1;              /* 0x14 */
         uint32  TimerCnt2;              /* 0x18 */
         uint32  TimerCnt3;              /* 0x1c */
#define TIMER_COUNT_MASK                0x3FFFFFFF

         uint32  TimerMask;              /* 0x20 */
#define TIMER0EN                        0x00000001
#define TIMER1EN                        0x00000002
#define TIMER2EN                        0x00000004
#define TIMER3EN                        0x00000008

         uint32  TimerInts;              /* 0x24 */
#define TIMER0                          0x00000001
#define TIMER1                          0x00000002
#define TIMER2                          0x00000004
#define TIMER3                          0x00000008
#define WATCHDOG                        0x00000010

         uint32  WatchDogDefCount;       /* 0x28 */

         /* Write 0xff00 0x00ff to Start timer
          * Write 0xee00 0x00ee to Stop and re-load default count
          * Read from this register returns current watch dog count
          */
         uint32  WatchDogCtl;            /* 0x2c */

         /* Number of 50-MHz ticks for WD Reset pulse to last */
         uint32  WDResetCount;           /* 0x30 */

         uint32  SoftRst;                /* 0x34 */
#define SOFT_RESET                      0x00000001

         uint32  ResetStatus;            /* 0x38 */
#define PCIE_RESET_STATUS               0x10000000
#define SW_RESET_STATUS                 0x20000000
#define HW_RESET_STATUS                 0x40000000
#define POR_RESET_STATUS                0x80000000
#define RESET_STATUS_MASK               0xF0000000

         uint32  ResetReason;            /* 0x3c */

         uint32  spare[3];               /* 0x40-0x4b */
} Timer;


==> 60333_map_part.h <==
typedef struct Timer {
         uint32  TimerInts;              /* 0x00 */
#define TIMER0                          0x00000001
#define TIMER1                          0x00000002
#define TIMER2                          0x00000004
#define WATCHDOG                        0x00000008
#define TIMER0_MASK                     0x00000100
#define TIMER1_MASK                     0x00000200
#define TIMER2_MASK                     0x00000400

         uint32  TimerCtl0;              /* 0x04 */
         uint32  TimerCtl1;              /* 0x08 */
         uint32  TimerCtl2;              /* 0x0c */
#define TIMERENABLE                     0x80000000
#define RSTCNTCLR                       0x40000000

         uint32  TimerCnt0;              /* 0x10 */
         uint32  TimerCnt1;              /* 0x14 */
         uint32  TimerCnt2;              /* 0x18 */
#define TIMER_COUNT_MASK                0x3FFFFFFF

         uint32  WatchDogDefCount;       /* 0x1c */

         /* Write 0xff00 0x00ff to Start timer
          * Write 0xee00 0x00ee to Stop and re-load default count
          * Read from this register returns current watch dog count
          */
         uint32  WatchDogCtl;            /* 0x20 */

         /* Number of 50-MHz ticks for WD Reset pulse to last */
         uint32  WDResetCount;           /* 0x24 */

         uint32  SoftRst;                /* 0x28 */
#define SOFT_RESET                      0x00000001
} Timer;


==> 63138_map_part.h <==
typedef struct Timer {
         uint32  TimerCtl0;              /* 0x00 */
         uint32  TimerCtl1;              /* 0x04 */
         uint32  TimerCtl2;              /* 0x08 */
         uint32  TimerCtl3;              /* 0x0c */
#define TIMERENABLE                     0x80000000
#define RSTCNTCLR                       0x40000000

         uint32  TimerCnt0;              /* 0x10 */
         uint32  TimerCnt1;              /* 0x14 */
         uint32  TimerCnt2;              /* 0x18 */
         uint32  TimerCnt3;              /* 0x1c */
#define TIMER_COUNT_MASK                0x3FFFFFFF

         uint32  TimerMask;              /* 0x20 */
#define TIMER0EN                        0x00000001
#define TIMER1EN                        0x00000002
#define TIMER2EN                        0x00000004
#define TIMER3EN                        0x00000008

         uint32  TimerInts;              /* 0x24 */
#define TIMER0                          0x00000001
#define TIMER1                          0x00000002
#define TIMER2                          0x00000004
#define TIMER3                          0x00000008
#define WATCHDOG                        0x00000010

         uint32  WatchDogDefCount;       /* 0x28 */

         /* Write 0xff00 0x00ff to Start timer
          * Write 0xee00 0x00ee to Stop and re-load default count
          * Read from this register returns current watch dog count
          */
         uint32  WatchDogCtl;            /* 0x2c */

         /* Number of 50-MHz ticks for WD Reset pulse to last */
         uint32  WDResetCount;           /* 0x30 */

         uint32  SoftRst;                /* 0x34 */
#define SOFT_RESET                      0x00000001

         uint32  ResetStatus;            /* 0x38 */
#define PCIE_RESET_STATUS               0x10000000
#define SW_RESET_STATUS                 0x20000000
#define HW_RESET_STATUS                 0x40000000
#define POR_RESET_STATUS                0x80000000
#define RESET_STATUS_MASK               0xF0000000
} Timer;


==> 63148_map_part.h <==
typedef struct Timer {
         uint32  TimerCtl0;              /* 0x00 */
         uint32  TimerCtl1;              /* 0x04 */
         uint32  TimerCtl2;              /* 0x08 */
         uint32  TimerCtl3;              /* 0x0c */
#define TIMERENABLE                     0x80000000
#define RSTCNTCLR                       0x40000000

         uint32  TimerCnt0;              /* 0x10 */
         uint32  TimerCnt1;              /* 0x14 */
         uint32  TimerCnt2;              /* 0x18 */
         uint32  TimerCnt3;              /* 0x1c */
#define TIMER_COUNT_MASK                0x3FFFFFFF

         uint32  TimerMask;              /* 0x20 */
#define TIMER0EN                        0x00000001
#define TIMER1EN                        0x00000002
#define TIMER2EN                        0x00000004
#define TIMER3EN                        0x00000008

         uint32  TimerInts;              /* 0x24 */
#define TIMER0                          0x00000001
#define TIMER1                          0x00000002
#define TIMER2                          0x00000004
#define TIMER3                          0x00000008
#define WATCHDOG                        0x00000010

         uint32  WatchDogDefCount;       /* 0x28 */

         /* Write 0xff00 0x00ff to Start timer
          * Write 0xee00 0x00ee to Stop and re-load default count
          * Read from this register returns current watch dog count
          */
         uint32  WatchDogCtl;            /* 0x2c */

         /* Number of 50-MHz ticks for WD Reset pulse to last */
         uint32  WDResetCount;           /* 0x30 */

         uint32  SoftRst;                /* 0x34 */
#define SOFT_RESET                      0x00000001

         uint32  ResetStatus;            /* 0x38 */
#define PCIE_RESET_STATUS               0x10000000
#define SW_RESET_STATUS                 0x20000000
#define HW_RESET_STATUS                 0x40000000
#define POR_RESET_STATUS                0x80000000
#define RESET_STATUS_MASK               0xF0000000
} Timer;


==> 63268_map_part.h <==
typedef struct Timer {
         uint16  unused0;                /* 0x00 */

         byte    TimerMask;              /* 0x02 */
#define TIMER0EN                        0x00000001
#define TIMER1EN                        0x00000002
#define TIMER2EN                        0x00000004

         byte    TimerInts;              /* 0x03 */
#define TIMER0                          0x00000001
#define TIMER1                          0x00000002
#define TIMER2                          0x00000004
#define WATCHDOG                        0x00000008

         uint32  TimerCtl0;              /* 0x04 */
         uint32  TimerCtl1;              /* 0x08 */
         uint32  TimerCtl2;              /* 0x0c */
#define TIMERENABLE                     0x80000000
#define RSTCNTCLR                       0x40000000

         uint32  TimerCnt0;              /* 0x10 */
         uint32  TimerCnt1;              /* 0x14 */
         uint32  TimerCnt2;              /* 0x18 */

         uint32  WatchDogDefCount;       /* 0x1c */

         /* Write 0xff00 0x00ff to Start timer
          * Write 0xee00 0x00ee to Stop and re-load default count
          * Read from this register returns current watch dog count
          */
         uint32  WatchDogCtl;            /* 0x20 */

         /* Number of 50-MHz ticks for WD Reset pulse to last */
         uint32  WDResetCount;           /* 0x24 */

         uint32  EnSwPLL;                /* 0x28 */
         uint32  ClkRstCtl;              /* 0x2c */
#define POR_RESET_STATUS                (1 << 31)
#define HW_RESET_STATUS                 (1 << 30)
#define SW_RESET_STATUS                 (1 << 29)
#define USB_REF_CLKEN                   (1 << 18)
#define UTO_EXTIN_CLKEN                 (1 << 17)
#define UTO_CLK50_SEL                   (1 << 16)
#define FAP2_PLL_CLKEN                  (1 << 15)
#define FAP2_PLL_FREQ_SHIFT             12
#define FAP1_PLL_CLKEN                  (1 << 11)
#define FAP1_PLL_FREQ_SHIFT             8
#define WAKEON_DSL                      (1 << 7)
#define WAKEON_EPHY                     (1 << 6)
#define DSL_ENERGY_DETECT_ENABLE        (1 << 4)
#define GPHY_1_ENERGY_DETECT_ENABLE     (1 << 3)
#define EPHY_3_ENERGY_DETECT_ENABLE     (1 << 2)
#define EPHY_2_ENERGY_DETECT_ENABLE     (1 << 1)
#define EPHY_1_ENERGY_DETECT_ENABLE     (1 << 0)
} Timer;


==> 63381_map_part.h <==
typedef struct Timer {
         uint32  TimerCtl0;              /* 0x00 */
         uint32  TimerCtl1;              /* 0x04 */
         uint32  TimerCtl2;              /* 0x08 */
         uint32  TimerCtl3;              /* 0x0c */
#define TIMERENABLE                     0x80000000
#define RSTCNTCLR                       0x40000000

         uint32  TimerCnt0;              /* 0x10 */
         uint32  TimerCnt1;              /* 0x14 */
         uint32  TimerCnt2;              /* 0x18 */
         uint32  TimerCnt3;              /* 0x1c */
#define TIMER_COUNT_MASK                0x3FFFFFFF

         uint32  TimerMask;              /* 0x20 */
#define TIMER0EN                        0x00000001
#define TIMER1EN                        0x00000002
#define TIMER2EN                        0x00000004
#define TIMER3EN                        0x00000008

         uint32  TimerInts;              /* 0x24 */
#define TIMER0                          0x00000001
#define TIMER1                          0x00000002
#define TIMER2                          0x00000004
#define TIMER3                          0x00000008
#define WATCHDOG                        0x00000010

         uint32  WatchDogDefCount;       /* 0x28 */

         /* Write 0xff00 0x00ff to Start timer
          * Write 0xee00 0x00ee to Stop and re-load default count
          * Read from this register returns current watch dog count
          */
         uint32  WatchDogCtl;            /* 0x2c */

         /* Number of 50-MHz ticks for WD Reset pulse to last */
         uint32  WDResetCount;           /* 0x30 */

         uint32  SoftRst;                /* 0x34 */
#define SOFT_RESET                      0x00000001

         uint32  ResetStatus;            /* 0x38 */
#define PCIE_RESET_STATUS               0x10000000
#define SW_RESET_STATUS                 0x20000000
#define HW_RESET_STATUS                 0x40000000
#define POR_RESET_STATUS                0x80000000
#define RESET_STATUS_MASK               0xF0000000
} Timer;


==> 68360_map_part.h <==
typedef struct Timer {
         uint32  TimerCtl0;              /* 0x00 */
         uint32  TimerCtl1;              /* 0x04 */
         uint32  TimerCtl2;              /* 0x08 */
         uint32  TimerCtl3;              /* 0x0c */
#define TIMERENABLE                     0x80000000
#define RSTCNTCLR                       0x40000000

         uint32  TimerCnt0;              /* 0x10 */
         uint32  TimerCnt1;              /* 0x14 */
         uint32  TimerCnt2;              /* 0x18 */
         uint32  TimerCnt3;              /* 0x1c */
#define TIMER_COUNT_MASK                0x3FFFFFFF

         uint32  TimerMask;              /* 0x20 */
#define TIMER0EN                        0x00000001
#define TIMER1EN                        0x00000002
#define TIMER2EN                        0x00000004
#define TIMER3EN                        0x00000008

         uint32  TimerInts;              /* 0x24 */
#define TIMER0                          0x00000001
#define TIMER1                          0x00000002
#define TIMER2                          0x00000004
#define TIMER3                          0x00000008
#define WATCHDOG                        0x00000010

         uint32  WatchDogDefCount;       /* 0x28 */

         /* Write 0xff00 0x00ff to Start timer
          * Write 0xee00 0x00ee to Stop and re-load default count
          * Read from this register returns current watch dog count
          */
         uint32  WatchDogCtl;            /* 0x2c */

         /* Number of 50-MHz ticks for WD Reset pulse to last */
         uint32  WDResetCount;           /* 0x30 */

         uint32  SoftRst;                /* 0x34 */
#define SOFT_RESET                      0x00000001

         uint32  ResetStatus;            /* 0x38 */
#define PCIE_RESET_STATUS               0x10000000
#define SW_RESET_STATUS                 0x20000000
#define HW_RESET_STATUS                 0x40000000
#define POR_RESET_STATUS                0x80000000
#define RESET_STATUS_MASK               0xF0000000

         uint32  ResetReason;            /* 0x3c */
#define SW_INI_RESET                    0x00000001

         uint32  spare[3];
} Timer;


==> 6838_map_part.h <==
typedef struct Timer {
         uint16  unused0;                /* 0x00 */

         byte    TimerMask;              /* 0x02 */
#define TIMER0EN                        0x00000001
#define TIMER1EN                        0x00000002
#define TIMER2EN                        0x00000004

         byte    TimerInts;              /* 0x03 */
#define TIMER0                          0x00000001
#define TIMER1                          0x00000002
#define TIMER2                          0x00000004
#define WATCHDOG0                       0x00000008
#define WATCHDOG                        WATCHDOG0 /* compatible with other chips */
#define WATCHDOG1                       0x00000010

         uint32  TimerCtl0;              /* 0x04 */
         uint32  TimerCtl1;              /* 0x08 */
         uint32  TimerCtl2;              /* 0x0c */
#define TIMERENABLE                     0x80000000
#define RSTCNTCLR                       0x40000000

         uint32  TimerCnt0;              /* 0x10 */
         uint32  TimerCnt1;              /* 0x14 */
         uint32  TimerCnt2;              /* 0x18 */
#define TIMER_COUNT_MASK                0x3FFFFFFF

         uint32  TimerMemTm;             /* 0x20 unused */
         uint32  TimerEphyTestCtrl;      /* 0x24 */
} Timer;


==> 6848_map_part.h <==
typedef struct Timer {
         uint32  TimerCtl0;              /* 0x00 */
         uint32  TimerCtl1;              /* 0x04 */
         uint32  TimerCtl2;              /* 0x08 */
         uint32  TimerCtl3;              /* 0x0c */
#define TIMERENABLE                     0x80000000
#define RSTCNTCLR                       0x40000000

         uint32  TimerCnt0;              /* 0x10 */
         uint32  TimerCnt1;              /* 0x14 */
         uint32  TimerCnt2;              /* 0x18 */
         uint32  TimerCnt3;              /* 0x1c */
#define TIMER_COUNT_MASK                0x3FFFFFFF

         uint32  TimerMask;              /* 0x20 */
#define TIMER0EN                        0x00000001
#define TIMER1EN                        0x00000002
#define TIMER2EN                        0x00000004
#define TIMER3EN                        0x00000008

         uint32  TimerInts;              /* 0x24 */
#define TIMER0                          0x00000001
#define TIMER1                          0x00000002
#define TIMER2                          0x00000004
#define TIMER3                          0x00000008
#define WATCHDOG                        0x00000010

         uint32  WatchDogDefCount;       /* 0x28 */

         /* Write 0xff00 0x00ff to Start timer
          * Write 0xee00 0x00ee to Stop and re-load default count
          * Read from this register returns current watch dog count
          */
         uint32  WatchDogCtl;            /* 0x2c */

         /* Number of 50-MHz ticks for WD Reset pulse to last */
         uint32  WDResetCount;           /* 0x30 */

         uint32  SoftRst;                /* 0x34 */
#define SOFT_RESET                      0x00000001

         uint32  ResetStatus;            /* 0x38 */
#define PCIE_RESET_STATUS               0x10000000
#define SW_RESET_STATUS                 0x20000000
#define HW_RESET_STATUS                 0x40000000
#define POR_RESET_STATUS                0x80000000
#define RESET_STATUS_MASK               0xF0000000

         uint32  ResetReason;            /* 0x3c */
#define SW_INI_RESET                    0x00000001

         uint32  spare[3];               /* 0x40-0x4b */
} Timer;


==> 6858_map_part.h <==
typedef struct Timer {
         uint32  TimerCtl0;              /* 0x00 */
         uint32  TimerCtl1;              /* 0x04 */
         uint32  TimerCtl2;              /* 0x08 */
         uint32  TimerCtl3;              /* 0x0c */
#define TIMERENABLE                     0x80000000
#define RSTCNTCLR                       0x40000000

         uint32  TimerCnt0;              /* 0x10 */
         uint32  TimerCnt1;              /* 0x14 */
         uint32  TimerCnt2;              /* 0x18 */
         uint32  TimerCnt3;              /* 0x1c */
#define TIMER_COUNT_MASK                0x3FFFFFFF

         uint32  TimerMask;              /* 0x20 */
#define TIMER0EN                        0x00000001
#define TIMER1EN                        0x00000002
#define TIMER2EN                        0x00000004
#define TIMER3EN                        0x00000008

         uint32  TimerInts;              /* 0x24 */
#define TIMER0                          0x00000001
#define TIMER1                          0x00000002
#define TIMER2                          0x00000004
#define TIMER3                          0x00000008
#define WATCHDOG                        0x00000010

         uint32  WatchDogDefCount;       /* 0x28 */

         /* Write 0xff00 0x00ff to Start timer
          * Write 0xee00 0x00ee to Stop and re-load default count
          * Read from this register returns current watch dog count
          */
         uint32  WatchDogCtl;            /* 0x2c */

         /* Number of 50-MHz ticks for WD Reset pulse to last */
         uint32  WDResetCount;           /* 0x30 */

         uint32  SoftRst;                /* 0x34 */
#define SOFT_RESET                      0x00000001

         uint32  ResetStatus;            /* 0x38 */
#define PCIE_RESET_STATUS               0x10000000
#define SW_RESET_STATUS                 0x20000000
#define HW_RESET_STATUS                 0x40000000
#define POR_RESET_STATUS                0x80000000
#define RESET_STATUS_MASK               0xF0000000

         uint32  ResetReason;            /* 0x3c */
#define SW_INI_RESET                    0x00000001

         uint32  spare[3];
} Timer;
Rob Herring (Arm) Nov. 1, 2021, 7:15 p.m. UTC | #3
On Fri, Oct 29, 2021 at 10:25:05PM +0200, Rafał Miłecki wrote:
> From: Rafał Miłecki <rafal@milecki.pl>
> 
> This block is called timer in documentation but it actually behaves like
> a MFD.
> 
> Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
> ---
>  .../bindings/mfd/brcm,timer-mfd.yaml          | 64 +++++++++++++++++++
>  1 file changed, 64 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/mfd/brcm,timer-mfd.yaml
> 
> diff --git a/Documentation/devicetree/bindings/mfd/brcm,timer-mfd.yaml b/Documentation/devicetree/bindings/mfd/brcm,timer-mfd.yaml
> new file mode 100644
> index 000000000000..0060b6c443a7
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mfd/brcm,timer-mfd.yaml
> @@ -0,0 +1,64 @@
> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/mfd/brcm,timer-mfd.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Broadcom's timer MFD
> +
> +maintainers:
> +  - Rafał Miłecki <rafal@milecki.pl>
> +
> +description: |
> +  Broadcom's timer is a block used in multiple SoCs (e.g., BCM4908, BCM63xx,
> +  BCM7038). Despite its name it's not strictly a timer device. It consists of:
> +  timers, watchdog and software reset handler.
> +
> +properties:
> +  compatible:
> +    items:
> +      - const: brcm,timer-mfd

'mfd' is a Linuxism. Name it what Broadcom calls the block. There should 
be at least as many compatibles as there are variations of register 
layouts.

> +      - const: simple-mfd
> +      - const: syscon
> +
> +  reg:
> +    maxItems: 1
> +
> +  ranges: true
> +
> +  "#address-cells":
> +    const: 1
> +
> +  "#size-cells":
> +    const: 1
> +
> +patternProperties:
> +  '^watchdog@[a-f0-9]+$':
> +    $ref: ../watchdog/brcm,bcm7038-wdt.yaml

/schema/watchdog/...

> +
> +additionalProperties: false
> +
> +required:
> +  - reg
> +
> +examples:
> +  - |
> +    timer_mfd: timer-mfd@ff800400 {
> +        compatible = "brcm,timer-mfd", "simple-mfd", "syscon";
> +        reg = <0xff800400 0x4c>;
> +        ranges = <0x0 0xff800400 0x4c>;
> +        #address-cells = <1>;
> +        #size-cells = <1>;
> +
> +        watchdog@28 {
> +            compatible = "brcm,bcm7038-wdt";
> +            reg = <0x28 0x8>;
> +        };

Don't you need a timer node? Make the binding complete.

> +    };
> +
> +    reboot {
> +        compatible = "syscon-reboot";
> +        regmap = <&timer_mfd>;

Make this a child node of the timer.

> +        offset = <0x34>;

Use 'reg'. If "syscon-reboot" doesn't allow that, add it.

> +        mask = <1>;


> +    };
> -- 
> 2.31.1
> 
>
diff mbox series

Patch

diff --git a/Documentation/devicetree/bindings/mfd/brcm,timer-mfd.yaml b/Documentation/devicetree/bindings/mfd/brcm,timer-mfd.yaml
new file mode 100644
index 000000000000..0060b6c443a7
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/brcm,timer-mfd.yaml
@@ -0,0 +1,64 @@ 
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mfd/brcm,timer-mfd.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Broadcom's timer MFD
+
+maintainers:
+  - Rafał Miłecki <rafal@milecki.pl>
+
+description: |
+  Broadcom's timer is a block used in multiple SoCs (e.g., BCM4908, BCM63xx,
+  BCM7038). Despite its name it's not strictly a timer device. It consists of:
+  timers, watchdog and software reset handler.
+
+properties:
+  compatible:
+    items:
+      - const: brcm,timer-mfd
+      - const: simple-mfd
+      - const: syscon
+
+  reg:
+    maxItems: 1
+
+  ranges: true
+
+  "#address-cells":
+    const: 1
+
+  "#size-cells":
+    const: 1
+
+patternProperties:
+  '^watchdog@[a-f0-9]+$':
+    $ref: ../watchdog/brcm,bcm7038-wdt.yaml
+
+additionalProperties: false
+
+required:
+  - reg
+
+examples:
+  - |
+    timer_mfd: timer-mfd@ff800400 {
+        compatible = "brcm,timer-mfd", "simple-mfd", "syscon";
+        reg = <0xff800400 0x4c>;
+        ranges = <0x0 0xff800400 0x4c>;
+        #address-cells = <1>;
+        #size-cells = <1>;
+
+        watchdog@28 {
+            compatible = "brcm,bcm7038-wdt";
+            reg = <0x28 0x8>;
+        };
+    };
+
+    reboot {
+        compatible = "syscon-reboot";
+        regmap = <&timer_mfd>;
+        offset = <0x34>;
+        mask = <1>;
+    };