Screen Freeze of lradc based touchscreen in imx28

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

Screen Freeze of lradc based touchscreen in imx28

1,443 Views
6FArumugam
Contributor I

For the custom board based on imx28evk porting latest kernel say 6.x series from older kernel. Here the touchscreen is connected via LRADC interface and the driver used is "drivers/input/touchscreen/mxs-lradc-ts.c". When used the default driver as it is the driver is not loaded and saw a crash during boot up (irq 0 index not found). So instead of api (platform_get_irq_byname) used (platform_get_resource_byname).

Normally touchscreen works fine but, on random occasions like touching the screen for long time, and sometimes during boot up and nothing pressed for long time also facing the issue of screen getting freezed meaning there are no events generated for /dev/input/event0 i.e "cat /dev/input/event0" [points to touchscreen] displays null even when the touch screen is pressed.

While reading the registers of lradc (0x80050000) I see that the touch irq bit of the register is disabled meaning it is stuck in a different state machine (calculating x position or y position). After that there is no success even if we try to set the irq manually using devmem2 tool.

Any pointers where can be the issue?

Labels (2)
0 Kudos
Reply
9 Replies

1,415 Views
Manuel_Salas
NXP TechSupport
NXP TechSupport

Hello @6FArumugam 

I hope you are doing very well.

 

Could you please share your device tree related to the LRADC?

 

Best regards,

Salas.

0 Kudos
Reply

1,402 Views
6FArumugam
Contributor I

yes. Thank you @Manuel_Salas

 

Below are the lradc nodes in the respective dtsi & dts for your reference.

 

lradc: lradc@80050000 {
    compatible = "fsl,imx28-lradc";
    reg = <0x80050000 0x2000>;
    interrupts = <10>, <14>, <15>, <16>, <17>, <18>, <19>,
                    <20>, <21>, <22>, <23>, <24>, <25>;
    status = "disabled";
    clocks = <&clks 41>;
    #io-channel-cells = <1>;
};
&lradc {
        fsl,lradc-touchscreen-wires = <4>;
        fsl,ave-ctrl = <4>;
        fsl,ave-delay = <2>;
        fsl,settling = <10>;
        status = "okay";
};

 

 

Regards
Arumugam.

0 Kudos
Reply

1,386 Views
Manuel_Salas
NXP TechSupport
NXP TechSupport

Hello @6FArumugam 

It appears there is missing the interrupt-parents on device tree. Please try the following:

 

lradc: lradc@80050000 {
    compatible = "fsl,imx28-lradc";
    reg = <0x80050000 0x2000>;
    interrupt-parent = <&icoll>;
    interrupts = <10 14 15 16 17 18 19 20 21 22 23 24 25>;
    status = "okay";

    fsl,lradc-touchscreen-wires = <4>; 
    fsl,ave-ctrl = <4>;
    fsl,ave-delay = <2>;
    fsl,settling = <10>;
};

 

It should be enough to solve the irq 0 index not found.

 

Best regards,

Salas.

 

0 Kudos
Reply

1,365 Views
6FArumugam
Contributor I

Thanks for the response @Manuel_Salas 

With this suggested change of adding the "interrupt-parent" and revertion of my change in driver.

        mxs_lradc_ts_hw_init(ts);

        for (i = 0; i < 3; i++) {
-               struct resource *r;
+               irq = platform_get_irq_byname(pdev, mxs_lradc_ts_irq_names[i]);
+               if (irq < 0)
+                       return irq;

-               r = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
-                               mxs_lradc_ts_irq_names[i]);
-               if (!r)
-                       return -ENXIO;
-               virq = irq_of_parse_and_map(node, r->start);
+               virq = irq_of_parse_and_map(node, irq);

                mxs_lradc_ts_stop(ts);



, I see the below error and the driver is not loaded.

 

[    3.163364] WARNING: CPU: 0 PID: 1 at /drivers/base/platform.c:450 __platform_get_irq_byname+0x74/0x90
[    3.172896] 0 is an invalid IRQ number
[    3.176810] Modules linked in:
[    3.180004] CPU: 0 PID: 1 Comm: swapper Not tainted 6.6.28-fslc-fslc-gf5e1b1ae5e1b #1
[    3.187924] Hardware name: Freescale MXS (Device Tree)
[    3.193120]  unwind_backtrace from show_stack+0x10/0x14
[    3.198490]  show_stack from dump_stack_lvl+0x28/0x30
[    3.203661]  dump_stack_lvl from __warn+0x7c/0xc8
[    3.208483]  __warn from warn_slowpath_fmt+0x140/0x164
[    3.213758]  warn_slowpath_fmt from __platform_get_irq_byname+0x74/0x90
[    3.220503]  __platform_get_irq_byname from platform_get_irq_byname+0x10/0x30
[    3.227751]  platform_get_irq_byname from mxs_lradc_ts_probe+0x1b4/0x314
[    3.234587]  mxs_lradc_ts_probe from platform_probe+0x58/0xa8
[    3.240451]  platform_probe from really_probe+0x130/0x29c
[    3.245954]  really_probe from __driver_probe_device+0x16c/0x18c
[    3.252055]  __driver_probe_device from driver_probe_device+0x30/0xb0
[    3.258592]  driver_probe_device from __driver_attach+0xe8/0xfc
[    3.264611]  __driver_attach from bus_for_each_dev+0x84/0xc8
[    3.270363]  bus_for_each_dev from bus_add_driver+0xa0/0x1b4
[    3.276109]  bus_add_driver from driver_register+0xb8/0x100
[    3.281775]  driver_register from do_one_initcall+0x80/0x224
[    3.287539]  do_one_initcall from kernel_init_freeable+0x19c/0x1dc
[    3.293835]  kernel_init_freeable from kernel_init+0x10/0x110
[    3.299697]  kernel_init from ret_from_fork+0x14/0x28
[    3.304844] Exception stack(0xd0819fb0 to 0xd0819ff8)
[    3.309963] 9fa0:                                     00000000 00000000 00000000 00000000
[    3.318204] 9fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[    3.326439] 9fe0: 00000000 00000000 00000000 00000000 00000013 00000000
[    3.333382] ---[ end trace 0000000000000000 ]---
[    3.338353] ci_hdrc ci_hdrc.0: new USB bus registered, assigned bus number 1
[    3.346636] mxs-lradc-ts mxs-lradc-ts: error -EINVAL: IRQ mxs-lradc-touchscreen not found

 

Does it mean the irq name mxs-lradc-touchscreen [enum] not mapped properly?

Regards
Arumugam JS

0 Kudos
Reply

1,358 Views
Manuel_Salas
NXP TechSupport
NXP TechSupport

Hello @6FArumugam 

 

Now it appears the irq name is missing on device tree.

 

Please try adding:

 

lradc: lradc@80050000 {
    compatible = "fsl,imx28-lradc";
    reg = <0x80050000 0x2000>;
    interrupt-parent = <&icoll>;
    interrupts = <10 14 15 16 17 18 19 20 21 22 23 24 25>;
    interrupt-names = "mxs-lradc-touchscreen", "mxs-lradc-thresh0", "mxs-lradc-thresh1",
                      "mxs-lradc-ch0", "mxs-lradc-ch1", "mxs-lradc-ch2",
                      "mxs-lradc-ch3", "mxs-lradc-ch4", "mxs-lradc-ch5",
                      "mxs-lradc-ch6", "mxs-lradc-ch7",
                      "mxs-lradc-button0", "mxs-lradc-button1";

    status = "okay";

    fsl,lradc-touchscreen-wires = <4>;
    fsl,ave-ctrl = <4>;
    fsl,ave-delay = <2>;
    fsl,settling = <10>;
};

 

Added according to the Reference manual:

Manuel_Salas_0-1747850679547.png

 

And driver:

Manuel_Salas_1-1747850693540.png

 

 

Best regards,

Salas.

0 Kudos
Reply

1,339 Views
6FArumugam
Contributor I

Same crash log  @Manuel_Salas .

 

I see in general driver (drivers/mfd/mxs-lradc.c) the enum is 

enum mx28_lradc_irqs {
        MX28_LRADC_TS_IRQ = 0,
        MX28_LRADC_TRESH0_IRQ,
        MX28_LRADC_TRESH1_IRQ,
        MX28_LRADC_CH0_IRQ,
        MX28_LRADC_CH1_IRQ,
        MX28_LRADC_CH2_IRQ,
        MX28_LRADC_CH3_IRQ,
        MX28_LRADC_CH4_IRQ,
        MX28_LRADC_CH5_IRQ,
        MX28_LRADC_CH6_IRQ,
        MX28_LRADC_CH7_IRQ,
        MX28_LRADC_BUTTON0_IRQ,
        MX28_LRADC_BUTTON1_IRQ,
};

 

Here we are creating a resource structure using the string and mapping the irq

static struct resource mx28_touchscreen_resources[] = {
        DEFINE_RES_MEM(0x0, 0x0),
        DEFINE_RES_IRQ_NAMED(MX28_LRADC_TS_IRQ, "mxs-lradc-touchscreen"),
        DEFINE_RES_IRQ_NAMED(MX28_LRADC_CH6_IRQ, "mxs-lradc-channel6"),
        DEFINE_RES_IRQ_NAMED(MX28_LRADC_CH7_IRQ, "mxs-lradc-channel7"),
};

 

And in the driver (drivers/input/touchscreen/mxs-lradc-ts.c) 

static const char * const mxs_lradc_ts_irq_names[] = {
        "mxs-lradc-touchscreen",
        "mxs-lradc-channel6",
        "mxs-lradc-channel7",
};

 

platform_get_irq_byname(pdev, mxs_lradc_ts_irq_names[i]); in this driver trying access the irq assigned but it is assigned with '0'. 

I see this function "platform_get_resource_byname" instead of platform_get_irq_byname works. Does changing of function has any impact with the screen freeze? since normally we are getting the interrupt and works fine on some occasions as mentioned earlier. 

Best regards

Arumugam JS 

 

0 Kudos
Reply

1,144 Views
6FArumugam
Contributor I

Hi @Manuel_Salas 

 

Hope you doing good!

From my understanding of the mxs-lradc-ts driver, see the Accumulate bit is set with number of samples of 4 with the delay between samples of 1 ms (2 with 2KHZ) and the settling delay of 5ms (10 with 2KHZ).

While adding debug prints found 

reg = readl(CTRL1 register)

if (!(reg & mxs_lradc_irq_mask(lradc)))
return IRQ_NONE;

 
IRQ_NONE is returned once and after that I never see a hardware irq/ conversion complete irq again and found that the bit (23) is still set, meaning still conversion is going on.

If enabled touch detection before IRQ_NONE I don't see any stuck/screen freeze doubted it may affect other lradc sensors? Any suggestions.

 

Regards

Arumugam JS

0 Kudos
Reply

1,131 Views
Manuel_Salas
NXP TechSupport
NXP TechSupport

Hello, 

Please try something like:

reg = readl(ts->base + LRADC_CTRL1);

/*
 * Check if this interrupt was actually triggered by the touchscreen.
 * If not, verify if the LRADC is stuck in BUSY state.
 */

if (!(reg & mxs_lradc_irq_mask(ts))) {
    u32 status = readl(ts->base + LRADC_STATUS);

    /*
     * Bit 23 indicates ongoing conversion.
     * If it's still active without an associated IRQ, the LRADC may be stuck.
     */
    if (status & BIT(23)) {
        dev_warn(ts->dev, "LRADC stuck in BUSY state, forcing recovery\n");

        // Stop the touchscreen conversion flow.
        mxs_lradc_ts_stop(ts);

        // Re-initialize the LRADC touchscreen logic.
        mxs_lradc_ts_hw_init(ts);

        return IRQ_HANDLED;
    }

    return IRQ_NONE;
}

 

It appears that, under certain timing conditions, the LRADC touchscreen logic may get stuck in a busy conversion state without generating further interrupts.

This results in input events being frozen until the next reboot.

The code is a "recovery mechanism" in the IRQ handler that detects this condition and automatically re-initializes the LRADC touchscreen state machine.

 

I hope this can helps to you.

 

Best regards,

Salas.

0 Kudos
Reply

1,010 Views
6FArumugam
Contributor I

Hi @Manuel_Salas 

Thanks for the suggestion.

Tried the recovery mechanism even I see sometimes screen went to freeze state.
Also, have a query mxs_lradc_ts_stop(ts) - will be clearing all the delay registers, and mxs_lradc_ts_hw_init will be re-initializes the hardware meaning that function just sets the screen type not enabling those registers required for entering state machine or related parameters right? Correct me if I'm wrong.

Regards

Arumugam JS

0 Kudos
Reply