]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/4.9.109/serial-8250-omap-fix-idling-of-clocks-for-unused-uarts.patch
Fixes for 4.19
[thirdparty/kernel/stable-queue.git] / releases / 4.9.109 / serial-8250-omap-fix-idling-of-clocks-for-unused-uarts.patch
1 From 13dc04d0e5fdc25c8f713ad23fdce51cf2bf96ba Mon Sep 17 00:00:00 2001
2 From: Tony Lindgren <tony@atomide.com>
3 Date: Fri, 4 May 2018 10:44:09 -0700
4 Subject: serial: 8250: omap: Fix idling of clocks for unused uarts
5
6 From: Tony Lindgren <tony@atomide.com>
7
8 commit 13dc04d0e5fdc25c8f713ad23fdce51cf2bf96ba upstream.
9
10 I noticed that unused UARTs won't necessarily idle properly always
11 unless at least one byte tx transfer is done first.
12
13 After some debugging I narrowed down the problem to the scr register
14 dma configuration bits that need to be set before softreset for the
15 clocks to idle. Unless we do this, the module clkctrl idlest bits
16 may be set to 1 instead of 3 meaning the clock will never idle and
17 is blocking deeper idle states for the whole domain.
18
19 This might be related to the configuration done by the bootloader
20 or kexec booting where certain configurations cause the 8250 or
21 the clkctrl clock to jam in a way where setting of the scr bits
22 and reset is needed to clear it. I've tried diffing the 8250
23 registers for the various modes, but did not see anything specific.
24 So far I've only seen this on omap4 but I'm suspecting this might
25 also happen on the other clkctrl using SoCs considering they
26 already have a quirk enabled for UART_ERRATA_CLOCK_DISABLE.
27
28 Let's fix the issue by configuring scr before reset for basic dma
29 even if we don't use it. The scr register will be reset when we do
30 softreset few lines after, and we restore scr on resume. We should
31 do this for all the SoCs with UART_ERRATA_CLOCK_DISABLE quirk flag
32 set since the ones with UART_ERRATA_CLOCK_DISABLE are all based
33 using clkctrl similar to omap4.
34
35 Looks like both OMAP_UART_SCR_DMAMODE_1 | OMAP_UART_SCR_DMAMODE_CTL
36 bits are needed for the clkctrl to idle after a softreset.
37
38 And we need to add omap4 to also use the UART_ERRATA_CLOCK_DISABLE
39 for the related workaround to be enabled. This same compatible
40 value will also be used for omap5.
41
42 Fixes: cdb929e4452a ("serial: 8250_omap: workaround errata around idling UART after using DMA")
43 Cc: Keerthy <j-keerthy@ti.com>
44 Cc: Matthijs van Duin <matthijsvanduin@gmail.com>
45 Cc: Sekhar Nori <nsekhar@ti.com>
46 Cc: Tero Kristo <t-kristo@ti.com>
47 Signed-off-by: Tony Lindgren <tony@atomide.com>
48 Cc: stable <stable@vger.kernel.org>
49 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
50
51 ---
52 drivers/tty/serial/8250/8250_omap.c | 16 +++++++++++++++-
53 1 file changed, 15 insertions(+), 1 deletion(-)
54
55 --- a/drivers/tty/serial/8250/8250_omap.c
56 +++ b/drivers/tty/serial/8250/8250_omap.c
57 @@ -1078,13 +1078,14 @@ static int omap8250_no_handle_irq(struct
58 return 0;
59 }
60
61 +static const u8 omap4_habit = UART_ERRATA_CLOCK_DISABLE;
62 static const u8 am3352_habit = OMAP_DMA_TX_KICK | UART_ERRATA_CLOCK_DISABLE;
63 static const u8 dra742_habit = UART_ERRATA_CLOCK_DISABLE;
64
65 static const struct of_device_id omap8250_dt_ids[] = {
66 { .compatible = "ti,omap2-uart" },
67 { .compatible = "ti,omap3-uart" },
68 - { .compatible = "ti,omap4-uart" },
69 + { .compatible = "ti,omap4-uart", .data = &omap4_habit, },
70 { .compatible = "ti,am3352-uart", .data = &am3352_habit, },
71 { .compatible = "ti,am4372-uart", .data = &am3352_habit, },
72 { .compatible = "ti,dra742-uart", .data = &dra742_habit, },
73 @@ -1326,6 +1327,19 @@ static int omap8250_soft_reset(struct de
74 int sysc;
75 int syss;
76
77 + /*
78 + * At least on omap4, unused uarts may not idle after reset without
79 + * a basic scr dma configuration even with no dma in use. The
80 + * module clkctrl status bits will be 1 instead of 3 blocking idle
81 + * for the whole clockdomain. The softreset below will clear scr,
82 + * and we restore it on resume so this is safe to do on all SoCs
83 + * needing omap8250_soft_reset() quirk. Do it in two writes as
84 + * recommended in the comment for omap8250_update_scr().
85 + */
86 + serial_out(up, UART_OMAP_SCR, OMAP_UART_SCR_DMAMODE_1);
87 + serial_out(up, UART_OMAP_SCR,
88 + OMAP_UART_SCR_DMAMODE_1 | OMAP_UART_SCR_DMAMODE_CTL);
89 +
90 sysc = serial_in(up, UART_OMAP_SYSC);
91
92 /* softreset the UART */