Re: [PATCH 2/2] dt-bindings: mfd: add Broadcom's timer MFD block
From: Rafał Miłecki <zajec5@gmail.com>
Date: 2021-10-29 21:20:59
Also in:
linux-arm-kernel, linux-devicetree, linux-watchdog
On 29.10.2021 23:03, Florian Fainelli wrote:
On 10/29/21 1:25 PM, Rafał Miłecki wrote:quoted
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.yamldiff --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;