From: Martin Sperl <kernel@martin.sperl.org> To: Stefan Wahren <stefan.wahren@i2se.com> Cc: linux-serial@vger.kernel.org, linux-clk <linux-clk@vger.kernel.org>, Eric Anholt <eric@anholt.net>, linux-rpi-kernel <linux-rpi-kernel@lists.infradead.org>, linux-arm-kernel@lists.infradead.org Subject: Re: serial: clk: bcm2835: Strange effects when using aux-uart in console Date: Tue, 16 Feb 2016 17:31:41 +0100 [thread overview] Message-ID: <D4D8C3EE-7BDC-44F4-A54F-A6861FE0A174@martin.sperl.org> (raw) In-Reply-To: <359843746.379810.6eb6c2f5-8282-417a-83d1-1fa79425ff73.open-xchange@email.1und1.de> > On 13.02.2016, at 21:45, Stefan Wahren <stefan.wahren@i2se.com> wrote: > > > According to the datasheet busy bit shouldn't be set while changing the clock. > So this isn't good. I hope this could be fixed, too. > I had hoped that the patch by Eric: "clk: bcm2835: Fix setting of PLL divider clock rates" would fix the issue, but that was unfortunately not the case. Some more investigation using the debugfs patch I had posted, which exposes the registers showed that: plld_per_a2w had a value of 4 before starting getty and a value of 0 after starting getty. That made me investigate why this value was changed and I found the culprit in the form of: @@ -1167,7 +1171,9 @@ static void bcm2835_pll_divider_off(struct clk_hw *hw) cprman_write(cprman, data->cm_reg, (cprman_read(cprman, data->cm_reg) & ~data->load_mask) | data->hold_mask); - cprman_write(cprman, data->a2w_reg, A2W_PLL_CHANNEL_DISABLE); + cprman_write(cprman, data->a2w_reg, + cprman_read(cprman, data->a2w_reg) | + A2W_PLL_CHANNEL_DISABLE); } after that (with plld itself marked as “prepared” during probe) everything is working fine. bcm2835_pll_off shows a similar pattern, but patching that the same way: @@ -955,8 +955,12 @@ static void bcm2835_pll_off(struct clk_hw *hw) struct bcm2835_cprman *cprman = pll->cprman; const struct bcm2835_pll_data *data = pll->data; - cprman_write(cprman, data->cm_ctrl_reg, CM_PLL_ANARST); - cprman_write(cprman, data->a2w_ctrl_reg, A2W_PLL_CTRL_PWRDN); + cprman_write(cprman, data->cm_ctrl_reg, + cprman_read(cprman, data->cm_ctrl_reg) | + CM_PLL_ANARST); + cprman_write(cprman, data->a2w_ctrl_reg, + cprman_read(cprman, data->a2w_ctrl_reg) | + A2W_PLL_CTRL_PWRDN); } does not resolve the issue - the system crashes - but without he pll lock message… With some debugging messages in place (the register names are added as a comments indicated via >): the complete list of writes to the clocks during boot: [ 2.021473] bcm2835_pll_on - pllc - start [ 2.025635] cprman_write - 0x0108 = 0x00000228 > CM_PLLC [ 2.030313] bcm2835_pll_on - pllc - before_wait_pll_lock [ 2.035773] bcm2835_pll_on - pllc - end [ 2.039785] cprman_write - 0x1620 = 0x00000002 > A2W_PLLC_CORE0 [ 2.044373] cprman_write - 0x0108 = 0x00000228 > CM_PLLC [ 2.049430] console [ttyS0] disabled [ 2.053237] 20215040.serial: ttyS0 at MMIO 0x0 (irq = 53, base_baud = 31224999) is a 16550 [ 2.061878] console [ttyS0] enabled [ 2.069085] bootconsole [earlycon0] disabled [ 2.078668] cprman_write - 0x1520 = 0x00000002 > A2W_PLLC_PER [ 2.083201] cprman_write - 0x0108 = 0x00000228 > CM_PLLC [ 2.087801] cprman_write - 0x01c0 = 0x000002d5 > CM_EMMCCTL [ 2.136432] mmc0: SDHCI controller on 20300000.sdhci [20300000.sdhci] using PIO dumping the registers for PLLD root@raspcm:~# cat /sys/kernel/debug/clk/plld/regdump cm_ctrl = 0x0000020a > CM_PLLD a2w_ctrl = 0x00021034 > A2W_PLLD_PER frac = 0x00015554 > A2W_PLLD_FRAC ana0 = 0x00000000 > A2W_PLLD_ANA0 ana1 = 0x00144000 > A2W_PLLD_ANA1 ana2 = 0x00000000 > A2W_PLLD_ANA2 ana3 = 0x00000100 > A2W_PLLD_ANA3 running getty: root@raspcm:~# /sbin/getty -a root -L ttyAMA0 115200 vt100 [ 71.110032] pl011_startup - start [ 71.113452] pl011_hwinit - prepare-enable [ 71.117656] bcm2835_pll_on - plld - start [ 71.121750] cprman_write - 0x010c = 0x0000020a > CM_PLLD [ 71.126274] bcm2835_pll_on - plld - before_wait_pll_lock [ 71.131728] bcm2835_pll_on - plld - end [ 71.135648] cprman_write - 0x1540 = 0x00000004 > A2W_PLLD_PER [ 71.140228] cprman_write - 0x010c = 0x0000020a > CM_PLLD [ 71.144760] cprman_write - 0x00f0 = 0x000002d6 > CM_UARTCTL [ 71.149340] pl011_hwinit - prepare-enable - ret = 0 [ 71.156743] pl011_startup - exit [ 71.163324] pl011_shutdown - start [ 71.168032] pl011_shutdown - disable_unprepare [ 71.172603] cprman_write - 0x00f0 = 0x00000286 > CM_UARTCTL [ 71.177269] cprman_write - 0x010c = 0x0000028a > CM_PLLD [ 71.181809] cprman_write - 0x1540 = 0x00000104 > A2W_PLLD_PER [ 71.186334] bcm2835_pll_off - plld - start [ 71.190547] cprman_write - 0x010c = 0x0000038a > CM_PLLD [ 71.195088] cprman_write - 0x1140 = 0x00031034 > A2W_PLLD_CTRL [ 71.199643] bcm2835_pll_off - plld - end [ 71.203643] pl011_shutdown - exit [ 71.209122] pl011_startup - start [ 71.212522] pl011_hwinit - prepare-enable [ 71.216695] bcm2835_pll_on - plld - start [ 71.220801] cprman_write - 0x010c = 0x0000028a > CM_PLLD [ 71.225326] bcm2835_pll_on - plld - before_wait_pll_lock [ 71.230775] bcm2835_pll_on - plld - in_pll_lock_loop [ 71.235840] bcm2835_pll_on - plld - in_pll_lock_loop [ 71.240926] bcm2835_pll_on - plld - in_pll_lock_loop [ 71.245983] bcm2835_pll_on - plld - in_pll_lock_loop [ 71.251067] bcm2835_pll_on - plld - in_pll_lock_loop [ 71.256123] bcm2835_pll_on - plld - in_pll_lock_loop [ 71.261206] bcm2835_pll_on - plld - in_pll_lock_loop [ 71.266272] bcm2835_pll_on - plld - in_pll_lock_loop [ 71.271364] bcm2835_pll_on - plld - in_pll_lock_loop [ 71.276419] bcm2835_pll_on - plld - in_pll_lock_loop [ 71.281523] bcm2835_pll_on - plld - in_pll_lock_loop [ 71.286691] bcm2835_pll_on - plld - in_pll_lock_loop [ 71.291753] bcm2835_pll_on - plld - in_pll_lock_loop [ 71.296838] bcm2835_pll_on - plld - in_pll_lock_loop [ 71.301937] bcm2835_pll_on - plld - in_pll_lock_loop [ 71.307030] bcm2835_pll_on - plld - in_pll_lock_loop [ 71.312087] bcm2835_pll_on - plld - in_pll_lock_loop [ 71.317180] bcm2835_pll_on - plld - in_pll_lock_loop [ 71.322235] bcm2835_pll_on - plld - in_pll_lock_loop [ 71.327319] bcm2835_pll_on - plld - in_pll_lock_loop [ 71.332387] bcm2835-clk 20101000.cprman: plld: couldn't lock PLL [ 71.338532] bcm2835_pll_on - plld - timeout [ 71.342801] pl011_hwinit - prepare-enable - ret = -110 [ 71.348080] pl011_startup - error = -110 - disable_unprepare [ 71.353862] ------------[ cut here ]------------ [ 71.358593] WARNING: CPU: 0 PID: 2339 at drivers/clk/clk.c:680 clk_core_disab le+0x34/0xf0() [ 71.367840] ---[ end trace f080e315d858793e ]--- [ 71.372614] ------------[ cut here ]------------ [ 71.377408] WARNING: CPU: 0 PID: 2339 at drivers/clk/clk.c:575 clk_core_unpre pare+0x34/0x110() [ 71.387073] ---[ end trace f080e315d858793f ]— no more activity - system crashed - HDMI looses signal So disabling PLL itself seems not to be recommended I could create a patch with the following content as a bandaid: diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c index 5293338..4dfb8e3 100644 --- a/drivers/clk/bcm/clk-bcm2835.c +++ b/drivers/clk/bcm/clk-bcm2835.c @@ -37,6 +37,7 @@ * generator). */ +#include <linux/clk.h> #include <linux/clk-provider.h> #include <linux/clkdev.h> #include <linux/clk/bcm2835.h> @@ -1750,6 +1767,9 @@ static int bcm2835_clk_probe(struct platform_device *pdev) clks[i] = desc->clk_register(cprman, desc->data); } + /* prepare PLLD, so that it never gets unprepared */ + clk_prepare(clks[BCM2835_PLLD]); + return of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, &cprman->onecell); } Note that this this needed on top of the patch to bcm2835_pll_divider_off, which is applied in the kernel used during reporting... Martin
WARNING: multiple messages have this Message-ID (diff)
From: kernel@martin.sperl.org (Martin Sperl) To: linux-arm-kernel@lists.infradead.org Subject: serial: clk: bcm2835: Strange effects when using aux-uart in console Date: Tue, 16 Feb 2016 17:31:41 +0100 [thread overview] Message-ID: <D4D8C3EE-7BDC-44F4-A54F-A6861FE0A174@martin.sperl.org> (raw) In-Reply-To: <359843746.379810.6eb6c2f5-8282-417a-83d1-1fa79425ff73.open-xchange@email.1und1.de> > On 13.02.2016, at 21:45, Stefan Wahren <stefan.wahren@i2se.com> wrote: > > > According to the datasheet busy bit shouldn't be set while changing the clock. > So this isn't good. I hope this could be fixed, too. > I had hoped that the patch by Eric: "clk: bcm2835: Fix setting of PLL divider clock rates" would fix the issue, but that was unfortunately not the case. Some more investigation using the debugfs patch I had posted, which exposes the registers showed that: plld_per_a2w had a value of 4 before starting getty and a value of 0 after starting getty. That made me investigate why this value was changed and I found the culprit in the form of: @@ -1167,7 +1171,9 @@ static void bcm2835_pll_divider_off(struct clk_hw *hw) cprman_write(cprman, data->cm_reg, (cprman_read(cprman, data->cm_reg) & ~data->load_mask) | data->hold_mask); - cprman_write(cprman, data->a2w_reg, A2W_PLL_CHANNEL_DISABLE); + cprman_write(cprman, data->a2w_reg, + cprman_read(cprman, data->a2w_reg) | + A2W_PLL_CHANNEL_DISABLE); } after that (with plld itself marked as ?prepared? during probe) everything is working fine. bcm2835_pll_off shows a similar pattern, but patching that the same way: @@ -955,8 +955,12 @@ static void bcm2835_pll_off(struct clk_hw *hw) struct bcm2835_cprman *cprman = pll->cprman; const struct bcm2835_pll_data *data = pll->data; - cprman_write(cprman, data->cm_ctrl_reg, CM_PLL_ANARST); - cprman_write(cprman, data->a2w_ctrl_reg, A2W_PLL_CTRL_PWRDN); + cprman_write(cprman, data->cm_ctrl_reg, + cprman_read(cprman, data->cm_ctrl_reg) | + CM_PLL_ANARST); + cprman_write(cprman, data->a2w_ctrl_reg, + cprman_read(cprman, data->a2w_ctrl_reg) | + A2W_PLL_CTRL_PWRDN); } does not resolve the issue - the system crashes - but without he pll lock message? With some debugging messages in place (the register names are added as a comments indicated via >): the complete list of writes to the clocks during boot: [ 2.021473] bcm2835_pll_on - pllc - start [ 2.025635] cprman_write - 0x0108 = 0x00000228 > CM_PLLC [ 2.030313] bcm2835_pll_on - pllc - before_wait_pll_lock [ 2.035773] bcm2835_pll_on - pllc - end [ 2.039785] cprman_write - 0x1620 = 0x00000002 > A2W_PLLC_CORE0 [ 2.044373] cprman_write - 0x0108 = 0x00000228 > CM_PLLC [ 2.049430] console [ttyS0] disabled [ 2.053237] 20215040.serial: ttyS0 at MMIO 0x0 (irq = 53, base_baud = 31224999) is a 16550 [ 2.061878] console [ttyS0] enabled [ 2.069085] bootconsole [earlycon0] disabled [ 2.078668] cprman_write - 0x1520 = 0x00000002 > A2W_PLLC_PER [ 2.083201] cprman_write - 0x0108 = 0x00000228 > CM_PLLC [ 2.087801] cprman_write - 0x01c0 = 0x000002d5 > CM_EMMCCTL [ 2.136432] mmc0: SDHCI controller on 20300000.sdhci [20300000.sdhci] using PIO dumping the registers for PLLD root at raspcm:~# cat /sys/kernel/debug/clk/plld/regdump cm_ctrl = 0x0000020a > CM_PLLD a2w_ctrl = 0x00021034 > A2W_PLLD_PER frac = 0x00015554 > A2W_PLLD_FRAC ana0 = 0x00000000 > A2W_PLLD_ANA0 ana1 = 0x00144000 > A2W_PLLD_ANA1 ana2 = 0x00000000 > A2W_PLLD_ANA2 ana3 = 0x00000100 > A2W_PLLD_ANA3 running getty: root at raspcm:~# /sbin/getty -a root -L ttyAMA0 115200 vt100 [ 71.110032] pl011_startup - start [ 71.113452] pl011_hwinit - prepare-enable [ 71.117656] bcm2835_pll_on - plld - start [ 71.121750] cprman_write - 0x010c = 0x0000020a > CM_PLLD [ 71.126274] bcm2835_pll_on - plld - before_wait_pll_lock [ 71.131728] bcm2835_pll_on - plld - end [ 71.135648] cprman_write - 0x1540 = 0x00000004 > A2W_PLLD_PER [ 71.140228] cprman_write - 0x010c = 0x0000020a > CM_PLLD [ 71.144760] cprman_write - 0x00f0 = 0x000002d6 > CM_UARTCTL [ 71.149340] pl011_hwinit - prepare-enable - ret = 0 [ 71.156743] pl011_startup - exit [ 71.163324] pl011_shutdown - start [ 71.168032] pl011_shutdown - disable_unprepare [ 71.172603] cprman_write - 0x00f0 = 0x00000286 > CM_UARTCTL [ 71.177269] cprman_write - 0x010c = 0x0000028a > CM_PLLD [ 71.181809] cprman_write - 0x1540 = 0x00000104 > A2W_PLLD_PER [ 71.186334] bcm2835_pll_off - plld - start [ 71.190547] cprman_write - 0x010c = 0x0000038a > CM_PLLD [ 71.195088] cprman_write - 0x1140 = 0x00031034 > A2W_PLLD_CTRL [ 71.199643] bcm2835_pll_off - plld - end [ 71.203643] pl011_shutdown - exit [ 71.209122] pl011_startup - start [ 71.212522] pl011_hwinit - prepare-enable [ 71.216695] bcm2835_pll_on - plld - start [ 71.220801] cprman_write - 0x010c = 0x0000028a > CM_PLLD [ 71.225326] bcm2835_pll_on - plld - before_wait_pll_lock [ 71.230775] bcm2835_pll_on - plld - in_pll_lock_loop [ 71.235840] bcm2835_pll_on - plld - in_pll_lock_loop [ 71.240926] bcm2835_pll_on - plld - in_pll_lock_loop [ 71.245983] bcm2835_pll_on - plld - in_pll_lock_loop [ 71.251067] bcm2835_pll_on - plld - in_pll_lock_loop [ 71.256123] bcm2835_pll_on - plld - in_pll_lock_loop [ 71.261206] bcm2835_pll_on - plld - in_pll_lock_loop [ 71.266272] bcm2835_pll_on - plld - in_pll_lock_loop [ 71.271364] bcm2835_pll_on - plld - in_pll_lock_loop [ 71.276419] bcm2835_pll_on - plld - in_pll_lock_loop [ 71.281523] bcm2835_pll_on - plld - in_pll_lock_loop [ 71.286691] bcm2835_pll_on - plld - in_pll_lock_loop [ 71.291753] bcm2835_pll_on - plld - in_pll_lock_loop [ 71.296838] bcm2835_pll_on - plld - in_pll_lock_loop [ 71.301937] bcm2835_pll_on - plld - in_pll_lock_loop [ 71.307030] bcm2835_pll_on - plld - in_pll_lock_loop [ 71.312087] bcm2835_pll_on - plld - in_pll_lock_loop [ 71.317180] bcm2835_pll_on - plld - in_pll_lock_loop [ 71.322235] bcm2835_pll_on - plld - in_pll_lock_loop [ 71.327319] bcm2835_pll_on - plld - in_pll_lock_loop [ 71.332387] bcm2835-clk 20101000.cprman: plld: couldn't lock PLL [ 71.338532] bcm2835_pll_on - plld - timeout [ 71.342801] pl011_hwinit - prepare-enable - ret = -110 [ 71.348080] pl011_startup - error = -110 - disable_unprepare [ 71.353862] ------------[ cut here ]------------ [ 71.358593] WARNING: CPU: 0 PID: 2339 at drivers/clk/clk.c:680 clk_core_disab le+0x34/0xf0() [ 71.367840] ---[ end trace f080e315d858793e ]--- [ 71.372614] ------------[ cut here ]------------ [ 71.377408] WARNING: CPU: 0 PID: 2339 at drivers/clk/clk.c:575 clk_core_unpre pare+0x34/0x110() [ 71.387073] ---[ end trace f080e315d858793f ]? no more activity - system crashed - HDMI looses signal So disabling PLL itself seems not to be recommended I could create a patch with the following content as a bandaid: diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c index 5293338..4dfb8e3 100644 --- a/drivers/clk/bcm/clk-bcm2835.c +++ b/drivers/clk/bcm/clk-bcm2835.c @@ -37,6 +37,7 @@ * generator). */ +#include <linux/clk.h> #include <linux/clk-provider.h> #include <linux/clkdev.h> #include <linux/clk/bcm2835.h> @@ -1750,6 +1767,9 @@ static int bcm2835_clk_probe(struct platform_device *pdev) clks[i] = desc->clk_register(cprman, desc->data); } + /* prepare PLLD, so that it never gets unprepared */ + clk_prepare(clks[BCM2835_PLLD]); + return of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, &cprman->onecell); } Note that this this needed on top of the patch to bcm2835_pll_divider_off, which is applied in the kernel used during reporting... Martin
next prev parent reply other threads:[~2016-02-16 16:31 UTC|newest] Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top 2016-02-10 15:12 serial: clk: bcm2835: Strange effects when using aux-uart in console Martin Sperl 2016-02-10 15:12 ` Martin Sperl 2016-02-10 17:21 ` Stefan Wahren 2016-02-10 17:21 ` Stefan Wahren 2016-02-10 17:42 ` Martin Sperl 2016-02-10 17:42 ` Martin Sperl 2016-02-11 13:15 ` Martin Sperl 2016-02-11 13:15 ` Martin Sperl 2016-02-11 17:55 ` Stefan Wahren 2016-02-11 17:55 ` Stefan Wahren 2016-02-12 11:56 ` Martin Sperl 2016-02-12 11:56 ` Martin Sperl 2016-02-12 17:34 ` Martin Sperl 2016-02-12 17:34 ` Martin Sperl 2016-02-12 19:44 ` Martin Sperl 2016-02-12 19:44 ` Martin Sperl 2016-02-13 10:01 ` Stefan Wahren 2016-02-13 10:01 ` Stefan Wahren 2016-02-13 11:24 ` Martin Sperl 2016-02-13 11:24 ` Martin Sperl 2016-02-16 18:57 ` Michael Turquette 2016-02-16 18:57 ` Michael Turquette 2016-02-16 18:57 ` Michael Turquette 2016-02-17 10:43 ` Martin Sperl 2016-02-17 10:43 ` Martin Sperl 2016-02-13 11:53 ` Martin Sperl 2016-02-13 11:53 ` Martin Sperl 2016-02-13 20:45 ` Stefan Wahren 2016-02-13 20:45 ` Stefan Wahren 2016-02-16 16:31 ` Martin Sperl [this message] 2016-02-16 16:31 ` Martin Sperl 2016-02-16 19:29 ` Stefan Wahren 2016-02-16 19:29 ` Stefan Wahren
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=D4D8C3EE-7BDC-44F4-A54F-A6861FE0A174@martin.sperl.org \ --to=kernel@martin.sperl.org \ --cc=eric@anholt.net \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-clk@vger.kernel.org \ --cc=linux-rpi-kernel@lists.infradead.org \ --cc=linux-serial@vger.kernel.org \ --cc=stefan.wahren@i2se.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.