Skip to content

drivers: counter: enable support for am13e230 eqep driver - #114

Merged
natto1784 merged 8 commits into
TexasInstruments:v4.4.0-ti-nextfrom
adityachopra29:downstream-am13-eqep-new
Oct 22, 2026
Merged

natto1784 merged 8 commits into
TexasInstruments:v4.4.0-ti-nextfrom
adityachopra29:downstream-am13-eqep-new

Conversation

@adityachopra29

Copy link
Copy Markdown

Enables support for eqep driver for am13. Reuses k3 driver for the most part.

Test logs:
19-Oct-26_AM13E230_ttyACM2-eqep_fr.txt

@adityachopra29 adityachopra29 changed the title Downstream am13 eqep new drivers: counter: enable support for am13e230 eqep driver Oct 19, 2026
@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Add AM13E eQEP support to the TI counter driver

✨ Enhancement 🐞 Bug fix 🕐 20-40 Minutes

Grey Divider

AI Description

• Enable AM13E eQEP instances through the existing TI counter driver and devicetree configuration.
• Add peripheral power, clock, crossbar, and input-source setup for AM13E.
• Fix sticky counter resets and handle simultaneous interrupts; keep the timer running during
 debugger halts.
Diagram

sequenceDiagram
    participant DT as Devicetree
    participant Driver as eQEP Driver
    participant SYSCTL as SYSCTL
    participant Clock as Clock Control
    participant XBAR as Input X-BAR
    participant EQEP as eQEP Hardware
    DT->>Driver: Instance configuration
    Driver->>SYSCTL: Enable peripheral power
    Driver->>Clock: Enable clock
    Driver->>XBAR: Apply mux states
    Driver->>EQEP: Select inputs and initialize
    EQEP-->>Driver: Counter interrupts
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Separate AM13E eQEP driver
  • ➕ Would isolate AM13E-specific initialization from the existing driver.
  • ➖ Would duplicate counter operations and interrupt handling across two drivers.

Recommendation: Reuse the existing driver with a gated AM13E variant. It keeps the counter API and shared behavior in one place while limiting SoC-specific power and routing setup to AM13E builds; a separate driver would add substantial duplication.

Files changed (5) +335 / -22

Enhancement (2) +235 / -20
counter_ti_am3352_eqep.cInitialize AM13E eQEP and service simultaneous events +208/-20

Initialize AM13E eQEP and service simultaneous events

• Adds MSPM0 clock configuration and gated SYSCTL power, mux-state, and QEPSRCSEL setup. It pulses the sticky software-reset bit, enables run-free behavior during debugger halts, accepts interrupts without a flags cell, and services all pending interrupt types rather than only the first.

drivers/counter/counter_ti_am3352_eqep.c

ti_am3352_eqep.hName AM13E eQEP input-source values +27/-0

Name AM13E eQEP input-source values

• Defines QEPSRCSEL values for the Input X-BAR, comparators, and PWM crossbar so devicetree configurations can use named constants.

include/zephyr/dt-bindings/counter/ti_am3352_eqep.h

Documentation (1) +58 / -2
ti,am3352-eqep.yamlDefine AM13E input-source and power properties +58/-2

Define AM13E input-source and power properties

• Includes the mux-consumer binding and documents board-defined Input X-BAR routing. Adds validated QEPA/QEPB/QEPI source selections and a SYSCTL power-enable specifier.

dts/bindings/counter/ti,am3352-eqep.yaml

Other (2) +42 / -0
Kconfig.ti_am3352_eqepGate AM13E-specific eQEP support +11/-0

Gate AM13E-specific eQEP support

• Adds a default-enabled AM13E variant option dependent on the base driver and SoC series. It selects the mux and syscon facilities needed for input routing and peripheral power.

drivers/counter/Kconfig.ti_am3352_eqep

am13e.dtsiDescribe three disabled AM13E eQEP instances +31/-0

Describe three disabled AM13E eQEP instances

• Adds eQEP0–2 nodes with register ranges, interrupts, MCLK references, and SYSCTL power-enable specifiers. The instances remain disabled until enabled by a board or overlay.

dts/arm/ti/am13/am13e.dtsi

@adityachopra29
adityachopra29 requested review from natto1784 and s-m33r and removed request for natto1784 October 19, 2026 13:19
@qodo-code-review

Copy link
Copy Markdown

Code Review by Qodo


View medium (2)
Remediation recommended
1. Comparator-sourced eQEP fails to initialise 🐞
Description
ti_eqep_init unconditionally applies PINCTRL_STATE_DEFAULT and returns its error, although the
binding’s comparator and PWM X-BAR example has no pinctrl-0. When an AM13 EQEP node uses an
internal source without a pinctrl state, lookup returns -ENOENT, so initialization stops before
the AM13 mux and QEPSRCSEL configuration.
Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The binding documents AM13 EQEP comparator and PWM X-BAR sources without pinctrl, but `ti_eqep_init` fails with `-ENOENT` when those nodes have no default pinctrl state.

## Fix Focus Areas
- drivers/counter/counter_ti_am3352_eqep.c[497-504]
- dts/bindings/counter/ti,am3352-eqep.yaml[27-33]

## Recommended Fix
Allow initialization to continue when an AM13 EQEP node with a configured internal source has no default pinctrl state. Apply the default state and retain existing error handling for nodes that define one. If pinctrl must remain mandatory instead, update the binding text and example to require `pinctrl-0`.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Dismiss ↗ | View ↗

2. ISR logs errors for flags that were never enabled 🐞
Description
The ISR now computes unknown = flg & ~(known) from the raw INTFLG without masking by INTEN,
and it runs on every interrupt rather than only when no known flag matched. Status flags the driver
never enables, such as quadrature direction change (TI_EQEP_INT_QDCI) and phase or position
errors, can be latched when an overflow, compare, index or timeout interrupt fires; each such
interrupt then emits LOG_ERR("unknown interrupt ...") from ISR context.
Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`ti_eqep_isr` reports any latched `INTFLG` bit outside the known set as an error on every interrupt. That includes status flags like QDC that latch without being enabled, so error logs get spammed from ISR context.

## Fix Focus Areas
- drivers/counter/counter_ti_am3352_eqep.c[556-558]
- drivers/counter/counter_ti_am3352_eqep.c[637-641]

## Recommended Fix
Compute `unknown = flg & regs->INTEN & ~(known | TI_EQEP_INT_GLOB)` so only enabled-but-unhandled sources are logged. Clear the remaining non-enabled latched flags silently, or leave them alone. Consider `LOG_DBG` for the silent case.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Dismiss ↗ | View ↗


View low (1)
Informational
3. Debug-halt timer behaviour changes on all SoCs 🐞
Description
ti_eqep_init now always rewrites QEPCTL.FREE_SOFT to run-free, outside the
CONFIG_COUNTER_TI_AM3352_EQEP_VARIANT_AM13 guard. Existing K3/AM3352 users therefore also get the
new debugger-halt behaviour, where position and unit timers keep running while the core is halted,
even though the change was meant for AM13.
Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The FREE_SOFT run-free setting applies to all SoCs that use the ti,am3352-eqep driver, not only AM13. This changes debug-halt behaviour on existing platforms.

## Fix Focus Areas
- drivers/counter/counter_ti_am3352_eqep.c[532-534]

## Recommended Fix
Move the FREE_SOFT write inside the AM13 variant block, or make it configurable (Kconfig or DT property). If the change is meant for all SoCs, say so in the commit message.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Dismiss ↗ | View ↗


Comment on lines +27 to +33
QEPA/QEPB/QEPI can instead be sourced from an on-chip comparator or
the PWM crossbar (AM13E-only); these need no pinctrl or mux entry,
so set the QEPSRCSEL field directly:

&eqep0 {
ti,qepa-src = <TI_EQEP_SRC_CMPSS1>;
};

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

1. Comparator-sourced eqep fails to initialise 🐞 Bug ≡ Correctness

ti_eqep_init unconditionally applies PINCTRL_STATE_DEFAULT and returns its error, although the
binding’s comparator and PWM X-BAR example has no pinctrl-0. When an AM13 EQEP node uses an
internal source without a pinctrl state, lookup returns -ENOENT, so initialization stops before
the AM13 mux and QEPSRCSEL configuration.
Agent Prompt
## Issue description
The binding documents AM13 EQEP comparator and PWM X-BAR sources without pinctrl, but `ti_eqep_init` fails with `-ENOENT` when those nodes have no default pinctrl state.

## Fix Focus Areas
- drivers/counter/counter_ti_am3352_eqep.c[497-504]
- dts/bindings/counter/ti,am3352-eqep.yaml[27-33]

## Recommended Fix
Allow initialization to continue when an AM13 EQEP node with a configured internal source has no default pinctrl state. Apply the default state and retain existing error handling for nodes that define one. If pinctrl must remain mandatory instead, update the binding text and example to require `pinctrl-0`.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Dismiss ↗ | View ↗

Comment on lines +556 to +558
uint16_t unknown = flg & ~(TI_EQEP_INT_PCOI | TI_EQEP_INT_PCUI | TI_EQEP_INT_PCMI |
TI_EQEP_INT_SELI | TI_EQEP_INT_IELI | TI_EQEP_INT_UTOI |
TI_EQEP_INT_GLOB);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

2. Isr logs errors for flags that were never enabled 🐞 Bug ◔ Observability

The ISR now computes unknown = flg & ~(known) from the raw INTFLG without masking by INTEN,
and it runs on every interrupt rather than only when no known flag matched. Status flags the driver
never enables, such as quadrature direction change (TI_EQEP_INT_QDCI) and phase or position
errors, can be latched when an overflow, compare, index or timeout interrupt fires; each such
interrupt then emits LOG_ERR("unknown interrupt ...") from ISR context.
Agent Prompt
## Issue description
`ti_eqep_isr` reports any latched `INTFLG` bit outside the known set as an error on every interrupt. That includes status flags like QDC that latch without being enabled, so error logs get spammed from ISR context.

## Fix Focus Areas
- drivers/counter/counter_ti_am3352_eqep.c[556-558]
- drivers/counter/counter_ti_am3352_eqep.c[637-641]

## Recommended Fix
Compute `unknown = flg & regs->INTEN & ~(known | TI_EQEP_INT_GLOB)` so only enabled-but-unhandled sources are logged. Clear the remaining non-enabled latched flags silently, or leave them alone. Consider `LOG_DBG` for the silent case.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Dismiss ↗ | View ↗

Comment on lines +532 to +534
/* FREE_SOFT=run-free: keep QUTMR running under debugger halt. */
regs->QEPCTL = (regs->QEPCTL & ~TI_EQEP_QEPCTL_FREE_SOFT) |
FIELD_PREP(TI_EQEP_QEPCTL_FREE_SOFT, TI_EQEP_QEPCTL_FREE_SOFT_RUNFREE);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Informational

3. Debug-halt timer behaviour changes on all socs 🐞 Bug ≡ Correctness

ti_eqep_init now always rewrites QEPCTL.FREE_SOFT to run-free, outside the
CONFIG_COUNTER_TI_AM3352_EQEP_VARIANT_AM13 guard. Existing K3/AM3352 users therefore also get the
new debugger-halt behaviour, where position and unit timers keep running while the core is halted,
even though the change was meant for AM13.
Agent Prompt
## Issue description
The FREE_SOFT run-free setting applies to all SoCs that use the ti,am3352-eqep driver, not only AM13. This changes debug-halt behaviour on existing platforms.

## Fix Focus Areas
- drivers/counter/counter_ti_am3352_eqep.c[532-534]

## Recommended Fix
Move the FREE_SOFT write inside the AM13 variant block, or make it configurable (Kconfig or DT property). If the change is meant for all SoCs, say so in the commit message.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Dismiss ↗ | View ↗

…EPS...

PR: 121529

Document mux-states routing and ti,qep{a,b,i}-src, include mux-consumer,
and add QEPSRCSEL source macros.

Signed-off-by: Aditya Chopra <a-chopra1@ti.com>
PR: 121529

Describe eqep0/1/2 on AM13E; leave status disabled for board overlays.

Signed-off-by: Aditya Chopra <a-chopra1@ti.com>
… QE...

PR: 121529

Gate AM13E QEPSRCSEL and Input X-BAR mux-states behind
COUNTER_TI_AM3352_EQEP_VARIANT_AM13.

Signed-off-by: Aditya Chopra <a-chopra1@ti.com>
…twa...

PR: 121529

Signed-off-by: Aditya Chopra <a-chopra1@ti.com>
…debug

PR: 121529

Signed-off-by: Aditya Chopra <a-chopra1@ti.com>
…rop...

PR: 121529

Allow EQEP nodes to consume SYSCTL PWREN via ti,pwren.

Signed-off-by: Aditya Chopra <a-chopra1@ti.com>
PR: 121529

Attach SYSCTL PWREN specifiers to eqep0/1/2.

Signed-off-by: Aditya Chopra <a-chopra1@ti.com>
PR: 121529

Power EQEP from driver init using ti,pwren instead of a SoC-level
SYSCTL poke.

Signed-off-by: Aditya Chopra <a-chopra1@ti.com>
@adityachopra29
adityachopra29 force-pushed the downstream-am13-eqep-new branch 2 times, most recently from 3489ade to f53ee8f Compare October 21, 2026 14:06
@natto1784
natto1784 merged commit 8537f24 into TexasInstruments:v4.4.0-ti-next Oct 22, 2026
7 of 9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants