* [PATCH 0/4 v5] Support bridge timings
From: Laurent Pinchart @ 2017-12-18 11:01 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171215155415.GT26573@phenom.ffwll.local>
Hi Daniel,
On Friday, 15 December 2017 17:54:15 EET Daniel Vetter wrote:
> On Fri, Dec 15, 2017 at 01:30:24PM +0100, Linus Walleij wrote:
> > On Fri, Dec 15, 2017 at 1:10 PM, Linus Walleij <linus.walleij@linaro.org>
wrote:
> >> - The connector is apparently not the right abstraction to carry
> >> the detailed timings specification between DRI drivers and bridge
> >> drivers.
> >>
> >> - Instead put detailed timing data into the bridge itself as an
> >> optional information pointer.
> >
> > Notice that this is just my fumbling attempts to deal with the situation.
> >
> > Laurent made me understand what the actual technical problem was,
> > how come my pixels were flickering.
> >
> > Both Laurent and DVetter mentioned that we may need to convey
> > information between the bridge and the display engine in some
> > way.
> >
> > Alternatively I could go and hack on adding this to e.g. drm_display_info
> > which was used in the previous patch sets by setting the negede flag
> > in bus_formats.
> >
> > I don't know. struct drm_display_info is getting a bit heavy as
> > container of misc settings related to "some kind of display".
> > The bridge isn't even a display itself, that is on the other side
> > of it. So using the connector and treating a bridge as "some kind
> > of display" seems wrong too.
> >
> > Is there a third way?
>
> If you don't plan to nest bridges too deeply, there is. Atm we have 2
> modes in drm_crtc_state:
>
> - mode, which is what userspace requested, and what it expects logically
> to be the actual real thing. I.e. timing, resolution and all that that
> userspace can observe (through plane positioning and vblank timestamps)
> should match this mode. For external screens this should also match
> what's physically going over the cable.
>
> - adjusted_mode, which is something entirely undefined and to be used by
> drivers internally. Most drivers use it as the thing that's actually
> transported between the CRTC and the encoder.
>
> There's a few common reasons for adjusted mode to be different:
> - integrated panel, and your CRTC has a scaler. In that case the
> userspace-requested mode is what you feed into into the scaler, and the
> adjusted mode is what comes out of your scaler and then goes down the
> wire to the panel.
>
> - your encoder is funky, and e.g. transcodes to the output mode itself,
> but expects that you program the input mode always the same. Usual
> reasons for this are transcoders that always want non-interlaced mode
> (and do the interlacing themselves), if the transcoder has some scaler
> itself (some TV-out transcoders had that), or if it has a strict
> expectation about signalling edges and stuff (and then transcodes the
> signal again). DACs are common doing that.
>
> Anyway, sounds like your bridge is of the 2nd kind, so all you have to do
> is
> - in your bridge->mode_fixup function, adjust the adjusted_mode as needed
> - in your pl111 driver, program the adjusted mode, not the originally
> requested mode
>
> adjusted mode is set to be a copy of the requested mode by atomic helpers,
> so this should keep working as-is on any other bridge driver.
I don't think that's the right fix.
The problem here is that the display engine has to output data in a way that
doesn't violate the DAC setup and hold times. Depending on the display engine,
you can just select the output clock edge, or adjust the phase of the data
compared to the pixel clock by a fraction of a clock cycle (1/4 is common,
I've seen smaller steps too). Note that selecting the opposite clock edge is
simple a 1/2 clock cycle delay.
The delay has to be computed based on the receiver's setup and hold times, but
also take into account other components on the board (such as buffer or
voltage shifters, or even inverters) and the PCB delay itself. This
computation doesn't belong to the bridge driver, especially given than its
goal is to compute a delay that depends on the display engine's capabilities
(inverting the clock vs. smaller step delays for instance). For this reason I
think the bridge driver should expose its timing parameters, and the display
engine should then decide how to output its data accordingly.
> No idea why I didn't tell you this right away, or maybe I'm missing
> something this time around.
>
> > I'm just a bit lost.
>
> Once your un-lost, pls review the docs for drm_crtc_state and the various
> mode_fixup functions, to make sure they're clear on how this is supposed
> to work. Might need a new overview DOC: comment that ties it all together.
--
Regards,
Laurent Pinchart
^ permalink raw reply
* [PATCH 1/1] arm: sunxi: Add alternative pins for spi0
From: Stefan Mavrodiev @ 2017-12-18 11:00 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171218092814.n5ptd5mhvo4nkjgq@flea.lan>
On 12/18/2017 11:28 AM, Maxime Ripard wrote:
> On Mon, Dec 18, 2017 at 08:24:21AM +0200, Stefan Mavrodiev wrote:
>> On 12/15/2017 05:08 PM, Maxime Ripard wrote:
>>> Hi,
>>>
>>> On Thu, Dec 14, 2017 at 08:24:54AM +0200, Stefan Mavrodiev wrote:
>>>> On 12/13/2017 05:40 PM, Maxime Ripard wrote:
>>>>> Hi,
>>>>>
>>>>> On Wed, Dec 13, 2017 at 09:44:34AM +0200, Stefan Mavrodiev wrote:
>>>>>> Allwinner A10/A13/A20 SoCs have pinmux for spi0
>>>>>> on port C. The patch adds these pins in the respective
>>>>>> dts includes.
>>>>>>
>>>>>> Signed-off-by: Stefan Mavrodiev <stefan@olimex.com>
>>>>> Do you have any boards that are using these?
>>>>>
>>>>> We won't merge that patch if there's no users for it.
>>>> A20-OLinuXino-Lime/Lime2 and A10-OLinuXino-Lime with spi flash.
>>>> For A13 we still doesn't have that option.
>>> If this bus is exposed on the headers, you can add those to the DT but
>>> leave them disabled if you want. Buf if there's no users of those
>>> nodes, our policy is not to merge them.
>> So basically I should resend the patch, enabling the those pins only for
>> sun4i and sun7i platform?
> I'm not quite sure what you mean, but you should do something like
> 77df9d66b0b1ad01c685fd6341ce501493899658
>
> Maxime
>
I guess, since this patch actually supports optional component, it
shouldn't be applied.
(This is already commented here:
https://patchwork.kernel.org/patch/10076721/ )
Thanks,
Stefan Mavrodiev
^ permalink raw reply
* [PATCH] phy: rockchip-typec: Try to turn the PHY on several times
From: Enric Balletbo Serra @ 2017-12-18 10:59 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAD=FV=Vw3_foX0_VfFG8h0xVrEEfOCWmVfF6xDVg++AqBbDRCA@mail.gmail.com>
Hi,
2017-12-13 20:14 GMT+01:00 Doug Anderson <dianders@chromium.org>:
> Hi,
>
> On Wed, Dec 13, 2017 at 4:41 AM, Enric Balletbo Serra
> <eballetbo@gmail.com> wrote:
>> Hi Doug,
>>
>> 2017-12-11 22:45 GMT+01:00 Douglas Anderson <dianders@chromium.org>:
>>> Bind / unbind stress testing of the USB controller on rk3399 found
>>> that we'd often end up with lots of failures that looked like this:
>>>
>>> phy phy-ff800000.phy.9: phy poweron failed --> -110
>>> dwc3 fe900000.dwc3: failed to initialize core
>>> dwc3: probe of fe900000.dwc3 failed with error -110
>>>
>>> Those errors were sometimes seen at bootup too, in which case USB
>>> peripherals wouldn't work until unplugged and re-plugged in.
>>>
>>> I spent some time trying to figure out why the PHY was failing to
>>> power on but I wasn't able to. Possibly this has to do with the fact
>>> that the PHY docs say that the USB controller "needs to be held in
>>> reset to hold pipe power state in P2 before initializing the Type C
>>> PHY" but that doesn't appear to be easy to do with the dwc3 driver
>>> today. Messing around with the ordering of the reset vs. the PHY
>>> initialization in the dwc3 driver didn't seem to fix things.
>>>
>>> I did, however, find that if I simply retry the power on it seems to
>>> have a good chance of working. So let's add some retries. I ran a
>>> pretty tight bind/unbind loop overnight. When I did so, I found that
>>> I need to retry between 1% and 2% of the time. Overnight I found only
>>> a small handful of times where I needed 2 retries. I never found a
>>> case where I needed 3 retries.
>>>
>>> I'm completely aware of the fact that this is quite an ugly hack and I
>>> wish I didn't have to resort to it, but I have no other real idea how
>>> to make this hardware reliable. If Rockchip in the future can come up
>>> with a solution we can always revert this hack. Until then, let's at
>>> least have something that works.
>>>
>>> This patch is tested atop Enric's latest dwc3 patch series ending at:
>>> https://patchwork.kernel.org/patch/10095527/
>>> ...but it could be applied independently of that series without any
>>> bad effects.
>>>
>>> For some more details on this bug, you can refer to:
>>> https://bugs.chromium.org/p/chromium/issues/detail?id=783464
>>>
>>> Signed-off-by: Douglas Anderson <dianders@chromium.org>
>>> ---
>>>
>>> drivers/phy/rockchip/phy-rockchip-typec.c | 24 ++++++++++++++++++++++--
>>> 1 file changed, 22 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/drivers/phy/rockchip/phy-rockchip-typec.c b/drivers/phy/rockchip/phy-rockchip-typec.c
>>> index ee85fa0ca4b0..5c2157156ce1 100644
>>> --- a/drivers/phy/rockchip/phy-rockchip-typec.c
>>> +++ b/drivers/phy/rockchip/phy-rockchip-typec.c
>>> @@ -349,6 +349,8 @@
>>> #define MODE_DFP_USB BIT(1)
>>> #define MODE_DFP_DP BIT(2)
>>>
>>> +#define POWER_ON_TRIES 5
>>> +
>>
>> I did the test of increase the number of tries to 100 because
>> unfortunately, even with this patch applied, I can see the problem on
>> my kevin with current mainline.
>>
>> [ 244.309094] rockchip-typec-phy ff800000.phy: Turn on failed after 100 loops
>>
>> That's an extra debug print ^
>>
>> [ 244.317019] phy phy-ff800000.phy.8: phy poweron failed --> -110
>> [ 244.323824] dwc3 fe900000.dwc3: failed to initialize core
>> [ 244.330057] dwc3: probe of fe900000.dwc3 failed with error -110
>>
>> So I'm wondering if there is something else that I need to apply to
>> really fix this as you didn't reproduce the issue doing lots of tests
>> and I can reproduce the issue very easily.
>
> Ah! I added that message to the top of my upstream series and,
> indeed, I sometimes see the PHY fail to turn on. Doh.
>
> OK, so here's what I've done:
>
> * The place where I ran the overnight loops was actually the Chrome OS
> 4.4 kernel. In that kernel I had a message very similar to yours and
> I didn't hit it. I just re-ran this for 20 minutes now and I can
> re-confirm. In the Chrome OS kernel I never see it needing more than
> a 1 (or 2) loops and it doesn't ever get into the "totally failed"
> case.
>
Ok, blame me, so the reason I saw that message often is because my DT
missed the entries to define the reset (fixed in the latest series I
sent) So completely my fault.
> * Previously I ran ~10 minutes with the upstream kernel, but at the
> time I didn't have your printout. After 10 minutes I checked my logs
> and I definitely saw the "Needed 1 loops to turn on", so I knew my
> patch was doing something useful. It didn't occur to me to re-confirm
> that I didn't get the "totally failed" upstream, though now that I say
> it out loud it's stupid that I didn't think to do this.
>
Doing your bind/unbind stress test with mainline I'm getting some
errors though, the 'phy poweron failed --> -110' disapeared and your
patch helps.
But sometimes I get :
[ 6451.626640] usb 5-1: new high-speed USB device number 2 using xhci-hcd
[ 6451.814221] hub 5-1:1.0: USB hub found
[ 6451.819897] hub 5-1:1.0: 4 ports detected
[ 6451.914772] usb 6-1: new SuperSpeed USB device number 2 using xhci-hcd
[ 6451.958372] hub 6-1:1.0: USB hub found
[ 6451.962867] hub 6-1:1.0: 4 ports detected
[ 6452.152438] xhci-hcd xhci-hcd.1.auto: remove, state 1
[ 6452.158121] usb 5-1.2: new full-speed USB device number 3 using xhci-hcd
[ 6452.158126] usb 5-1.2: hub failed to enable device, error -108
[ 6452.172323] usb usb6: USB disconnect, device number 1
[ 6452.174638] hub 6-1:1.0: activate --> -19
[ 6452.182507] usb 6-1: USB disconnect, device number 2
And after some minutes of test I get a:
[ 9182.623783] Unable to handle kernel NULL pointer dereference at
virtual address 00000090
[ 9182.632831] Mem abort info:
[ 9182.635945] ESR = 0x96000004
[ 9182.639350] Exception class = DABT (current EL), IL = 32 bits
[ 9182.645959] SET = 0, FnV = 0
[ 9182.649365] EA = 0, S1PTW = 0
[ 9182.652866] Data abort info:
[ 9182.656076] ISV = 0, ISS = 0x00000004
[ 9182.660355] CM = 0, WnR = 0
[ 9182.663665] user pgtable: 4k pages, 48-bit VAs, pgd = 0000000087ab6ba9
[ 9182.670957] [0000000000000090] *pgd=0000000000000000
[ 9182.676504] Internal error: Oops: 96000004 [#1] PREEMPT SMP
[ 9182.682727] Modules linked in: fuse mwifiex_pcie mwifiex cdc_ether
usbnet r8152 cfg80211 rfkill cros_ec_sensors cros_ec_sensors_core
indust
rialio_triggered_buffer kfifo_buf phy_rockchip_pcie snd_soc_max98357a
snd_soc_rk3399_gru_sound atmel_mxt_ts videobuf2_vmalloc
videobuf2_memops
videobuf2_v4l2 crc32_ce videobuf2_core videodev crct10dif_ce
snd_soc_rockchip_i2s snd_soc_da7219 snd_soc_rt5514 snd_soc_rt5514_spi
cros_ec_de
vs rockchip_saradc snd_soc_rl6231 rockchip_thermal media pcie_rockchip
ip_tables x_tables ipv6
[ 9182.733489] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.15.0-rc3+ #39
[ 9182.740681] Hardware name: Google Kevin (DT)
[ 9182.745448] pstate: 80000085 (Nzcv daIf -PAN -UAO)
[ 9182.750803] pc : xhci_irq+0x30c/0x1360
[ 9182.754986] lr : xhci_irq+0x40/0x1360
[ 9182.759071] sp : ffff000008003d90
[ 9182.762768] x29: ffff000008003d90 x28: ffff8000b4948220
[ 9182.768701] x27: 0000000000000001 x26: ffff00000a51d640
[ 9182.774633] x25: ffff00000914eb6b x24: 0000000000000000
[ 9182.780566] x23: 0000000000000000 x22: 0000000000000080
[ 9182.786499] x21: ffff8000b4948000 x20: ffff8000b494826c
[ 9182.792431] x19: ffff8000b4948000 x18: 0000000000040f00
[ 9182.798363] x17: 0000ffffb54b1b90 x16: ffff000008222b68
[ 9182.804296] x15: 0000000000000000 x14: 00000000000023de
[ 9182.810229] x13: 7fffffffffffffff x12: 0000000000000040
[ 9182.816161] x11: ffff8000f24cc000 x10: 000000000000001e
[ 9182.822093] x9 : ffff8000f24cc118 x8 : 0000000000000000
[ 9182.828026] x7 : ffff8000f1735000 x6 : 0000000000000001
[ 9182.833959] x5 : 0000000000000000 x4 : ffff8000c186e100
[ 9182.839891] x3 : 0000000000000001 x2 : 0000000000000002
[ 9182.845823] x1 : ffff8000b4948000 x0 : 0000000000000003
[ 9182.851758] Process swapper/0 (pid: 0, stack limit = 0x0000000049fd774f)
[ 9182.859242] Call trace:
[ 9182.861972] xhci_irq+0x30c/0x1360
[ 9182.865769] usb_hcd_irq+0x2c/0x48
[ 9182.869566] __handle_irq_event_percpu+0x9c/0x128
[ 9182.874818] handle_irq_event_percpu+0x1c/0x58
[ 9182.879778] handle_irq_event+0x48/0x78
[ 9182.874818] handle_irq_event_percpu+0x1c/0x58
[ 9182.884061] handle_fasteoi_irq+0xa0/0x180
[ 9182.888634] generic_handle_irq+0x24/0x38
[ 9182.893108] __handle_domain_irq+0x5c/0xb8
[ 9182.897682] gic_handle_irq+0xc4/0x180
[ 9182.901865] el1_irq+0xb0/0x128
[ 9182.905370] arch_cpu_idle+0x10/0x18
[ 9182.909361] do_idle+0x11c/0x1e0
[ 9182.912962] cpu_startup_entry+0x24/0x28
[ 9182.917343] rest_init+0xd0/0xe0
[ 9182.920946] start_kernel+0x398/0x3ac
[ 9182.925035] Code: f9400798 340035c0 7103fc1f 54004ac0 (b9409305)
[ 9182.931848] ---[ end trace dc830bbccf53c326 ]---
So there is still something wrong with current mainline that seems
it's solved in chromeos. I'll try to investigate a bit.
> * Previously when playing with patches on the upstream kernel I saw
> lots of problems powering on the PHY and I thought my patch was
> helping, but that was all very non-scientific.
>
>
> So to say it shortly:
>
> * For me, my patch makes things a slightly better even on the upstream
> kernel (I do sometimes see the "turned on after 1 tries")
>
> * I can confirm that my patch doesn't fix everything upstream, so
> there's something different about the Chrome OS tree still.
>
> ---
>
> I also picked all the local patches from the Chrome OS kernel to the
> PHY driver and now my PHY driver in the upstream and downstream trees
> match. I can still reproduce problems. So the issue is somewhere at
> a higher level...
>
>
> So basically something outside the PHY driver is causing it to fail
> unexpectedly upstream. I guess the hacky retry won't work well enough
> there after all. :(
>
> One question: if you get the "failed after 100 loops" and then you do
> another unbind / bind, does it work after that? The original reason I
> got the idea to retry was because if I simply tried an unbind / bind
> again then things worked OK...
>
>
> -Doug
Regards,
-Enric
^ permalink raw reply
* [PATCH 2/4] clocksource: stm32: use prescaler to adjust the resolution
From: Daniel Lezcano @ 2017-12-18 10:54 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CA+M3ks5qBNzwjDimVYUS1sHzDDHD+Y44OtyT9L=imbQoNbsnFA@mail.gmail.com>
On 18/12/2017 10:44, Benjamin Gaignard wrote:
> 2017-12-18 10:26 GMT+01:00 Daniel Lezcano <daniel.lezcano@linaro.org>:
>> On 15/12/2017 09:52, Benjamin Gaignard wrote:
>>> Rather than use fixed prescaler values compute it to get a clock
>>> as close as possible of 10KHz and a resolution of 0.1ms.
>>>
>>> Signed-off-by: Benjamin Gaignard <benjamin.gaignard@st.com>
>>> ---
>>> drivers/clocksource/timer-stm32.c | 23 ++++++++++++++++-------
>>> 1 file changed, 16 insertions(+), 7 deletions(-)
>>>
>>> diff --git a/drivers/clocksource/timer-stm32.c b/drivers/clocksource/timer-stm32.c
>>> index 23a321cca45b..de721d318065 100644
>>> --- a/drivers/clocksource/timer-stm32.c
>>> +++ b/drivers/clocksource/timer-stm32.c
>>> @@ -37,6 +37,11 @@
>>>
>>> #define TIM_EGR_UG BIT(0)
>>>
>>> +#define MAX_TIM_PSC 0xFFFF
>>> +
>>> +/* Target a 10KHz clock to get a resolution of 0.1 ms */
>>> +#define TARGETED_CLK_RATE 10000
>>> +
>>> static int stm32_clock_event_shutdown(struct clock_event_device *evt)
>>> {
>>> struct timer_of *to = to_timer_of(evt);
>>> @@ -83,7 +88,7 @@ static irqreturn_t stm32_clock_event_handler(int irq, void *dev_id)
>>> static void __init stm32_clockevent_init(struct timer_of *to)
>>> {
>>> unsigned long max_delta;
>>> - int prescaler;
>>> + unsigned long prescaler;
>>>
>>> to->clkevt.name = "stm32_clockevent";
>>> to->clkevt.features = CLOCK_EVT_FEAT_PERIODIC;
>>> @@ -96,13 +101,17 @@ static void __init stm32_clockevent_init(struct timer_of *to)
>>> /* Detect whether the timer is 16 or 32 bits */
>>> writel_relaxed(~0U, timer_of_base(to) + TIM_ARR);
>>> max_delta = readl_relaxed(timer_of_base(to) + TIM_ARR);
>>> - if (max_delta == ~0U) {
>>> - prescaler = 1;
>>> + to->clkevt.rating = 50;
>>> + if (max_delta == ~0U)
>>> to->clkevt.rating = 250;
>>> - } else {
>>> - prescaler = 1024;
>>> - to->clkevt.rating = 50;
>>> - }
>>> +
>>> + /*
>>> + * Get the highest possible prescaler value to be as close
>>> + * as possible of TARGETED_CLK_RATE
>>> + */
>>> + prescaler = DIV_ROUND_CLOSEST(timer_of_rate(to), TARGETED_CLK_RATE);
>>
>> With a 90MHz or 125MHz, the prescaler will be 9000 or 12500, so much
>> more than the 1024 we have today for 16b, and 1 for 32b.
>>
>> Shouldn't the computation be weighted with the bits width ?
>
> My goal was to get the same resolution (0.1ms) for all the timers so
> the wrap will depend of the number of bits like you describe below.
Do you really want 1ms resolution with a 32bits timer ?
>> Otherwise the timer will wrap like:
>>
>> 32bits:
>>
>> before: (2^32 / 90e6) x 1 = 47.72 seconds
>> after: (2^32 / 90e6) x 9000 = 119.3 *hours* ~= 5days
>>
>> 16bits:
>>
>> before: (2^16 / 90e6) x 1024 = 0.745 seconds
>> after: (2^16 / 90e6) x 9000 = 6.55 seconds
>>
>> The patch is ok to target the 10KHz timer rate for 16b with a 1ms
>> resolution wrapping up after 6.55 seconds. But not for the 32bits timer.
>> Furthermore, we can't tell anymore the 32bits timers have a rating of
>> 250 after this patch.
>
> What is the link between rating and resolution (or wrap) ?
Low resolution => hardly suitable for real use case => bad rating.
>From include/linux/clocksource.h
[ ... ]
* 100-199: Base level usability.
* Functional for real use, but not desired.
* 200-299: Good.
* A correct and usable clocksource.
[ ... ]
If you want to set a timer with a delta of 12.345ms and the resolution
is 1ms. Then you end up with a timer expiring after 13ms.
> Is it a problem to get a long wrap ?
It is not a problem to go for a long wrap, it is usually interesting
when the CPU has deep idle states. But it is not worth to sacrifice the
resolution with the 32bits timer in order to have 5 days before wrap.
Keeping 47secs is fine for the moment. If you want a coarser grain, that
could be acceptable because the resolution is very high but we can
postpone that for later after solving this 16b / 32b thing.
>> Leave the 32bits part as it is and compute the prescaler only in case of
>> 16bits with the target rate, which sounds a reasonable approach.
>>
>>> + if (prescaler > MAX_TIM_PSC)
>>> + prescaler = MAX_TIM_PSC;
>>
>> That can happen only if the clock rate is greater than ~655MHz, that
>> could not happen today as far as I can tell regarding the DT. So if we
>> hit this condition, we should speak up in the log (pr_warn).
>
> It is to be futur proof for next possible SoC but even if prescaler
> reach this limit
> it is not a problem the only consequence would be that resolution and
> wrap change.
Got that, but that needs to be logged with a pr_warn or pr_info.
>>> writel_relaxed(0, timer_of_base(to) + TIM_ARR);
>>> writel_relaxed(prescaler - 1, timer_of_base(to) + TIM_PSC);
>>
>> Can you fix this prescaler - 1 in order to be consistent with the
>> computation with 16b ? (32b prescaler = 0, 16b prescaler = clk_rate /
>> target ).
>
> In the hardware the clock is divise by " TIM_PSC value 1" so to be coherent
> with that I need to do prescaler -1.
Ah, ok.
--
<http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs
Follow Linaro: <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog
^ permalink raw reply
* linux-next: Signed-off-by missing for commit in the mvebu tree
From: Gregory CLEMENT @ 2017-12-18 10:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171218074035.7ed52363@canb.auug.org.au>
Hi Stephen,
On lun., d?c. 18 2017, Stephen Rothwell <sfr@canb.auug.org.au> wrote:
> Hi all,
>
> Commit
>
> a2e2a5860be3 ("arm64: dts: marvell: add NAND support on the 8040-DB board")
>
> is missing a Signed-off-by from its committer.
Thanks for the notice, I will fix it.
Gregory
>
> --
> Cheers,
> Stephen Rothwell
--
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
^ permalink raw reply
* [PATCH 4/4 v5] drm/pl111: Support handling bridge timings
From: Laurent Pinchart @ 2017-12-18 10:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171215121047.3650-5-linus.walleij@linaro.org>
Hi Linus,
Thank you for the patch.
On Friday, 15 December 2017 14:10:47 EET Linus Walleij wrote:
> If the bridge has a too strict setup time for the incoming
> signals, we may not be fast enough and then we need to
> compensate by outputting the signal on the inverse clock
> edge so it is for sure stable when the bridge samples it.
>
> Since bridges in difference to panels does not expose their
> connectors, make the connector optional in the display
> setup code.
>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
> ChangeLog v4->v5:
> - Use the new bridge timings setup method.
> ---
> drivers/gpu/drm/pl111/Kconfig | 1 +
> drivers/gpu/drm/pl111/pl111_display.c | 35 ++++++++++++++++++++++++++++----
> drivers/gpu/drm/pl111/pl111_drv.c | 20 +++++++++++---------
> 3 files changed, 43 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/gpu/drm/pl111/Kconfig b/drivers/gpu/drm/pl111/Kconfig
> index e5e2abd66491..82cb3e60ddc8 100644
> --- a/drivers/gpu/drm/pl111/Kconfig
> +++ b/drivers/gpu/drm/pl111/Kconfig
> @@ -8,6 +8,7 @@ config DRM_PL111
> select DRM_GEM_CMA_HELPER
> select DRM_BRIDGE
> select DRM_PANEL_BRIDGE
> + select DRM_DUMB_VGA_DAC
> select VT_HW_CONSOLE_BINDING if FRAMEBUFFER_CONSOLE
> help
> Choose this option for DRM support for the PL111 CLCD controller.
> diff --git a/drivers/gpu/drm/pl111/pl111_display.c
> b/drivers/gpu/drm/pl111/pl111_display.c index 06c4bf756b69..7fe4040aea46
> 100644
> --- a/drivers/gpu/drm/pl111/pl111_display.c
> +++ b/drivers/gpu/drm/pl111/pl111_display.c
> @@ -94,6 +94,7 @@ static void pl111_display_enable(struct
> drm_simple_display_pipe *pipe, const struct drm_display_mode *mode =
> &cstate->mode;
> struct drm_framebuffer *fb = plane->state->fb;
> struct drm_connector *connector = priv->connector;
> + struct drm_bridge *bridge = priv->bridge;
> u32 cntl;
> u32 ppl, hsw, hfp, hbp;
> u32 lpp, vsw, vfp, vbp;
> @@ -143,11 +144,37 @@ static void pl111_display_enable(struct
> drm_simple_display_pipe *pipe, if (mode->flags & DRM_MODE_FLAG_NVSYNC)
> tim2 |= TIM2_IVS;
>
> - if (connector->display_info.bus_flags & DRM_BUS_FLAG_DE_LOW)
> - tim2 |= TIM2_IOE;
> + if (connector) {
> + if (connector->display_info.bus_flags & DRM_BUS_FLAG_DE_LOW)
> + tim2 |= TIM2_IOE;
>
> - if (connector->display_info.bus_flags & DRM_BUS_FLAG_PIXDATA_NEGEDGE)
> - tim2 |= TIM2_IPC;
> + if (connector->display_info.bus_flags &
> + DRM_BUS_FLAG_PIXDATA_NEGEDGE)
> + tim2 |= TIM2_IPC;
> + }
> +
> + if (bridge) {
> + const struct drm_bridge_timings *btimings = bridge->timings;
> +
> + /*
> + * Here is when things get really fun. Sometimes the bridge
> + * timings are such that the signal out from PL11x is not
> + * stable before the receiving bridge (such as a dumb VGA DAC
> + * or similar) samples it. If that happens, we compensate by
> + * the only method we have: output the data on the opposite
> + * edge of the clock so it is for sure stable when it gets
> + * sampled.
> + *
> + * The PL111 manual does not contain proper timining diagrams
> + * or data for these details, but we know from experiments
> + * that the setup time is more than 3000 picoseconds (3 ns).
> + * If we have a bridge that requires the signal to be stable
> + * earlier than 3000 ps before the clock pulse, we have to
> + * output the data on the opposite edge to avoid flicker.
This should probably depend on the pixel clock frequency, but if it works for
you for now, I have no objection.
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> + */
> + if (btimings && btimings->setup_time_ps >= 3000)
> + tim2 ^= TIM2_IPC;
> + }
>
> tim2 |= cpl << 16;
> writel(tim2, priv->regs + CLCD_TIM2);
> diff --git a/drivers/gpu/drm/pl111/pl111_drv.c
> b/drivers/gpu/drm/pl111/pl111_drv.c index 201d57d5cb54..101a9c7db6ff 100644
> --- a/drivers/gpu/drm/pl111/pl111_drv.c
> +++ b/drivers/gpu/drm/pl111/pl111_drv.c
> @@ -107,11 +107,17 @@ static int pl111_modeset_init(struct drm_device *dev)
> ret = PTR_ERR(bridge);
> goto out_config;
> }
> - /*
> - * TODO: when we are using a different bridge than a panel
> - * (such as a dumb VGA connector) we need to devise a different
> - * method to get the connector out of the bridge.
> - */
> + } else if (bridge) {
> + dev_info(dev->dev, "Using non-panel bridge\n");
> + } else {
> + dev_err(dev->dev, "No bridge, exiting\n");
> + return -ENODEV;
> + }
> +
> + priv->bridge = bridge;
> + if (panel) {
> + priv->panel = panel;
> + priv->connector = panel->connector;
> }
>
> ret = pl111_display_init(dev);
> @@ -125,10 +131,6 @@ static int pl111_modeset_init(struct drm_device *dev)
> if (ret)
> return ret;
>
> - priv->bridge = bridge;
> - priv->panel = panel;
> - priv->connector = panel->connector;
> -
> ret = drm_vblank_init(dev, 1);
> if (ret != 0) {
> dev_err(dev->dev, "Failed to init vblank\n");
--
Regards,
Laurent Pinchart
^ permalink raw reply
* [PATCH 3/4 v5] drm/bridge: Add timing support to dumb VGA DAC
From: Laurent Pinchart @ 2017-12-18 10:51 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171215121047.3650-4-linus.walleij@linaro.org>
Hi Linus,
Thank you for the patch.
On Friday, 15 December 2017 14:10:46 EET Linus Walleij wrote:
> This extends the dumb VGA DAC bridge to handle the THS8134A
> and THS8134B VGA DACs in addition to those already handled.
>
> We assign the proper timing data to the pointer inside the
> bridge struct so display controllers that need to align their
> timings to the bridge can pick it up and work from there.
>
> Cc: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> Cc: Bartosz Golaszewski <bgolaszewski@baylibre.com>
> Cc: Maxime Ripard <maxime.ripard@free-electrons.com>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
> ChangeLog v4->v5:
> - Rewrite the support using the new concept of defining
> fine-granular sampling (setup+hold) timing definitions
> stored in the bridge timings struct.
> ChangeLog v3->v4:
> - Actually have the code syntactically correct and compiling :(
> (Kconfig mistake.)
> (...)
> AS usr/initramfs_data.o
> AR usr/built-in.o
> CC drivers/gpu/drm/bridge/dumb-vga-dac.o
> AR drivers/gpu/drm/bridge/built-in.o
> AR drivers/gpu/drm/built-in.o
> AR drivers/gpu/built-in.o
> AR drivers/built-in.o
> (...)
> ChangeLog v2->v3:
> - Move const specifier.
> - Cut one line of code assigning bus flags.
> - Preserve the "ti,ths8135" compatible for elder device trees.
> ChangeLog v1->v2:
> - Alphabetize includes
> - Use a u32 with the bus polarity flags and just encode the
> polarity using the DRM define directly.
> - Rename vendor_data to vendor_info.
> - Simplify assignment of the flag as it is just a simple
> u32 now.
> - Probe all TI variants on the "ti,ths813x" wildcard for now,
> we only need to know that the device is in this family to
> set the clock edge flag right.
> ---
> drivers/gpu/drm/bridge/dumb-vga-dac.c | 61 ++++++++++++++++++++++++++++++--
> 1 file changed, 58 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/dumb-vga-dac.c
> b/drivers/gpu/drm/bridge/dumb-vga-dac.c index de5e7dee7ad6..34788783a90f
> 100644
> --- a/drivers/gpu/drm/bridge/dumb-vga-dac.c
> +++ b/drivers/gpu/drm/bridge/dumb-vga-dac.c
> @@ -11,6 +11,7 @@
> */
>
> #include <linux/module.h>
> +#include <linux/of_device.h>
> #include <linux/of_graph.h>
> #include <linux/regulator/consumer.h>
>
> @@ -176,11 +177,13 @@ static struct i2c_adapter
> *dumb_vga_retrieve_ddc(struct device *dev) static int dumb_vga_probe(struct
> platform_device *pdev)
> {
> struct dumb_vga *vga;
> + const struct drm_bridge_timings *timings;
>
> vga = devm_kzalloc(&pdev->dev, sizeof(*vga), GFP_KERNEL);
> if (!vga)
> return -ENOMEM;
> platform_set_drvdata(pdev, vga);
> + timings = of_device_get_match_data(&pdev->dev);
>
> vga->vdd = devm_regulator_get_optional(&pdev->dev, "vdd");
> if (IS_ERR(vga->vdd)) {
> @@ -204,6 +207,7 @@ static int dumb_vga_probe(struct platform_device *pdev)
>
> vga->bridge.funcs = &dumb_vga_bridge_funcs;
> vga->bridge.of_node = pdev->dev.of_node;
> + vga->bridge.timings = timings;
Do you need the intermediate timings variable ?
> drm_bridge_add(&vga->bridge);
>
> @@ -222,10 +226,61 @@ static int dumb_vga_remove(struct platform_device
> *pdev) return 0;
> }
>
> +/*
> + * We assume the ADV7123 DAC is the "default" for historical reasons
> + * Information taken from the ADV7123 datasheet, revision D.
> + * NOTE: the ADV7123EP seems to have other timings and need a new timings
> + * set if used.
> + */
> +static const struct drm_bridge_timings default_dac_timings = {
> + /* Timing specifications, datasheet page 7 */
> + .sampling_edge = true,
> + .setup_time_ps = 500,
> + .hold_time_ps = 1500,
> +};
You know what's lovely ? The setup time depends on the power supply voltage
:-) Let's use 500ps for now, that's a conservative value that will work for
both 5V and 3.3V. If anyone needs to lower it to 200ps later, they can always
implement support for voltage-dependent timings.
> +/*
> + * Information taken from the THS8134, THS8134A, THS8134B datasheet named
> + * "SLVS205D", dated May 1990, revised March 2000.
> + */
> +static const struct drm_bridge_timings ti_ths8134_dac_timings = {
> + /* From timing diagram, datasheet page 9 */
> + .sampling_edge = true,
> + /* From datasheet, page 12 */
> + .setup_time_ps = 3000,
> + /* I guess this means latched input */
> + .hold_time_ps = 0,
> +};
> +
> +/*
> + * Information taken from the THS8135 datasheet named "SLAS343B", dated
> + * May 2001, revised April 2013.
> + */
> +static const struct drm_bridge_timings ti_ths8135_dac_timings = {
> + /* From timing diagram, datasheet page 14 */
> + .sampling_edge = true,
> + /* From datasheet, page 16 */
> + .setup_time_ps = 2000,
> + .hold_time_ps = 500,
> +};
> +
> static const struct of_device_id dumb_vga_match[] = {
> - { .compatible = "dumb-vga-dac" },
> - { .compatible = "adi,adv7123" },
> - { .compatible = "ti,ths8135" },
> + {
> + .compatible = "dumb-vga-dac",
> + .data = &default_dac_timings,
Shouldn't we leave this NULL for dumb VGA DACs ? They're made of passive
components and don't sample the signal, so there's no real timings that we can
report.
Apart from that,
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> + },
> + {
> + .compatible = "adi,adv7123",
> + .data = &default_dac_timings,
> + },
> + {
> + .compatible = "ti,ths8135",
> + .data = &ti_ths8135_dac_timings,
> + },
> + {
> + .compatible = "ti,ths8134",
> + .data = &ti_ths8134_dac_timings,
> + },
> {},
> };
> MODULE_DEVICE_TABLE(of, dumb_vga_match);
--
Regards,
Laurent Pinchart
^ permalink raw reply
* [linux-sunxi] [PATCH v3 2/3] dt-bindings: media: Add Allwinner V3s Camera Sensor Interface (CSI)
From: Chen-Yu Tsai @ 2017-12-18 10:46 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171218174309.9170c971c5acac0d14dd782d@magewell.com>
On Mon, Dec 18, 2017 at 5:43 PM, Yong <yong.deng@magewell.com> wrote:
> Hi,
>
> On Mon, 18 Dec 2017 10:24:37 +0100
> Maxime Ripard <maxime.ripard@free-electrons.com> wrote:
>
>> Hi,
>>
>> On Mon, Dec 18, 2017 at 04:49:21PM +0800, Yong wrote:
>> > > > + compatible = "allwinner,sun8i-v3s-csi";
>> > > > + reg = <0x01cb4000 0x1000>;
>> > > > + interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
>> > > > + clocks = <&ccu CLK_BUS_CSI>,
>> > > > + <&ccu CLK_CSI1_SCLK>,
>> > >
>> > > CSI also has an MCLK. Do you need that one?
>> >
>> > MCLK is not needed if the front end is not a sensor (like adv7611).
>> > I will add it as an option.
>>
>> I guess this should always be needed then. And the driver will make
>> the decision to enable it or not.
>
> But how the driver to know if it should be enabled?
> I think MCLK should be added in DT just if the subdev need it.
Looking around the docs, there doesn't seem to be anything related
to MCLK within the CSI section.
Furthermore, camera sensor bindings, such as for the OV5640, in fact
do have a property for a reference clock, which is called XCLK or
XVCLK.
Since the clock is already exported from the CCU, I suppose it's
just a matter of referencing the clock from the camera node, with
the proper pinctrl for that pin.
So to summarize, just ignore my comment about the missing MCLK. :)
ChenYu
^ permalink raw reply
* [PATCH] ARM64: dts: meson-gxl: add internal ethernet PHY irq
From: Jerome Brunet @ 2017-12-18 10:27 UTC (permalink / raw)
To: linux-arm-kernel
Add the interrupt of the internal ethernet PHY
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
Hi Kevin,
This changes depends on the net-next changes adding interrupt support [0].
It is really important that this change is not merged before its
dependency.
If it is merged before, instead of polling, the phy would wait for an
interrupt which has not been configured and will never fire.
Tested on the libretech-cc and khadas VIM.
Cheers
Jerome
https://lkml.kernel.org/r/20171218094446.31912-7-jbrunet at baylibre.com
arch/arm64/boot/dts/amlogic/meson-gxl.dtsi | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
index 4a316a11a00e..8bc404508a4f 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
@@ -631,6 +631,7 @@
internal_phy: ethernet-phy at 8 {
compatible = "ethernet-phy-id0181.4400", "ethernet-phy-ieee802.3-c22";
+ interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
reg = <8>;
max-speed = <100>;
};
--
2.14.3
^ permalink raw reply related
* pxa3xx_nand times out in 4.14 with JFFS2
From: Miquel RAYNAL @ 2017-12-18 10:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171218070617.GA16559@1wt.eu>
Hello Willy,
On Mon, 18 Dec 2017 08:06:17 +0100
Willy Tarreau <w@1wt.eu> wrote:
> On Mon, Dec 18, 2017 at 07:37:15AM +0100, Willy Tarreau wrote:
> > > As Boris said, we would really welcome a test of this branch,
> > > because you almost have the same setup as Sean in the thread
> > > "pxa3xx: wait time out when scanning for bb" and I am running out
> > > of explanation for his problem unless it is related to U-Boot. So
> > > if you could try booting with and without the on-flash-bbt
> > > property and report whether it fails or not it would be of great
> > > help!
> >
> > Yes, I noticed your work mentionned in some of the threads I've read
> > during my troubleshooting session and considered giving it a try.
> > I'll probably do this next week-end.
>
> Finally I figured the test was quick enough and could help you, so I
> built and booted it, I'm getting this at boot :
>
> marvell-nfc f10d0000.nand-controller: Timeout waiting for RB signal
> nand_bbt: error while writing BBT block -110
> marvell-nfc f10d0000.nand-controller: Timeout waiting for RB signal
> marvell-nfc f10d0000.nand-controller: Timeout waiting for RB signal
> nand_bbt: error -110 while marking block 1023 bad
> marvell-nfc f10d0000.nand-controller: Timeout waiting for RB signal
> nand_bbt: error while writing BBT block -110
> marvell-nfc f10d0000.nand-controller: Timeout waiting for RB signal
> marvell-nfc f10d0000.nand-controller: Timeout waiting for RB signal
Thanks for testing.
I fixed two problems happening during read/write of 2kiB page NAND
chips, I am quite confident this would solve the issues you report
here. Could you please give it a try?
Same branch as before [1], just some more fixups! on it :)
Thank you,
Miqu?l
[1] https://github.com/miquelraynal/linux/tree/marvell/nand-next/nfc
^ permalink raw reply
* [PATCH 04/25] arm: exynos/s3c: dts: Remove leading 0x and 0s from bindings notation
From: Mathieu Malaterre @ 2017-12-18 10:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAJKOXPdkYLisej5965rh2SbOjbFms-RK2VnXt=L==MW_JcA+OA@mail.gmail.com>
On Mon, Dec 18, 2017 at 10:40 AM, Krzysztof Kozlowski <krzk@kernel.org> wrote:
> On Fri, Dec 15, 2017 at 1:46 PM, Mathieu Malaterre <malat@debian.org> wrote:
>> Improve the DTS files by removing all the leading "0x" and zeros to fix the
>> following dtc warnings:
>>
>> Warning (unit_address_format): Node /XXX unit name should not have leading "0x"
>>
>> and
>>
>> Warning (unit_address_format): Node /XXX unit name should not have leading 0s
>>
>> Converted using the following command:
>>
>> find . -type f \( -iname *.dts -o -iname *.dtsi \) -exec sed -i -e "s/@\([0-9a-fA-FxX\.;:#]+\)\s*{/@\L\1 {/g" -e "s/@0x\(.*\) {/@\1 {/g" -e "s/@0+\(.*\) {/@\1 {/g" {} +^C
>>
>> For simplicity, two sed expressions were used to solve each warnings separately.
>>
>> To make the regex expression more robust a few other issues were resolved,
>> namely setting unit-address to lower case, and adding a whitespace before the
>> the opening curly brace:
>>
>> https://elinux.org/Device_Tree_Linux#Linux_conventions
>>
>> This will solve as a side effect warning:
>>
>> Warning (simple_bus_reg): Node /XXX@<UPPER> simple-bus unit address format error, expected "<lower>"
>>
>> This is a follow up to commit 4c9847b7375a ("dt-bindings: Remove leading 0x from bindings notation")
>>
>> Reported-by: David Daney <ddaney@caviumnetworks.com>
>> Suggested-by: Rob Herring <robh@kernel.org>
>> Acked-by: Krzysztof Kozlowski <krzk@kernel.org>
>
> Ack was for different patchset, touching only three files...
So sorry, when I read your email:
https://lkml.org/lkml/2017/12/15/152
I assumed you meant for all the Exynos* and S3C* DTS files, but I did
not check carefully which files were touched originally.
>> Signed-off-by: Mathieu Malaterre <malat@debian.org>
>> ---
>> arch/arm/boot/dts/exynos3250.dtsi | 34 ++++++------
>> arch/arm/boot/dts/exynos4.dtsi | 56 +++++++++----------
>> arch/arm/boot/dts/exynos4210.dtsi | 8 +--
>> arch/arm/boot/dts/exynos4412-pinctrl.dtsi | 2 +-
>> arch/arm/boot/dts/exynos4412.dtsi | 22 ++++----
>> arch/arm/boot/dts/exynos5.dtsi | 22 ++++----
>> arch/arm/boot/dts/exynos5250.dtsi | 64 +++++++++++-----------
>> arch/arm/boot/dts/exynos5260.dtsi | 26 ++++-----
>> arch/arm/boot/dts/exynos5420.dtsi | 78 +++++++++++++--------------
>> arch/arm/boot/dts/exynos5422-odroid-core.dtsi | 2 +-
>> arch/arm/boot/dts/exynos5440.dtsi | 14 ++---
>> arch/arm/boot/dts/s3c2416.dtsi | 8 +--
>> 12 files changed, 168 insertions(+), 168 deletions(-)
>>
>> diff --git a/arch/arm/boot/dts/exynos3250.dtsi b/arch/arm/boot/dts/exynos3250.dtsi
>> index 2bd3872221a1..8d47571b3984 100644
>> --- a/arch/arm/boot/dts/exynos3250.dtsi
>> +++ b/arch/arm/boot/dts/exynos3250.dtsi
>> @@ -164,31 +164,31 @@
>> syscon = <&pmu_system_controller>;
>> };
>>
>> - pd_cam: cam-power-domain at 10023C00 {
>> + pd_cam: cam-power-domain at 10023c00 {
>
> This is not related to this patch and it was not present in the
> version I acked. I also already fixed this here:
> https://patchwork.kernel.org/patch/10113323/
>
> There is no changelog explaining the difference in patches. Original
> patch was okay, why changing it?
Accept my sincere apologizes I really messed this series. I discover
my original ARM patch did not apply lower case to all unit-address
equally, so I added at last minute a sed expression to make all
unit-address lower case.
I guess you can just drop this one for now.
-M
^ permalink raw reply
* [PULL 5/5] KVM: arm/arm64: Fix timer enable flow
From: Christoffer Dall @ 2017-12-18 10:00 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171218100057.7839-1-christoffer.dall@linaro.org>
When enabling the timer on the first run, we fail to ever restore the
state and mark it as loaded. That means, that in the initial entry to
the VCPU ioctl, unless we exit to userspace for some reason such as a
pending signal, if the guest programs a timer and blocks, we will wait
forever, because we never read back the hardware state (the loaded flag
is not set), and so we think the timer is disabled, and we never
schedule a background soft timer.
The end result? The VCPU blocks forever, and the only solution is to
kill the thread.
Fixes: 4a2c4da1250d ("arm/arm64: KVM: Load the timer state when enabling the timer")
Reported-by: Marc Zyngier <marc.zyngier@arm.com>
Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
Tested-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
---
virt/kvm/arm/arch_timer.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c
index 14c018f990a7..cc29a8148328 100644
--- a/virt/kvm/arm/arch_timer.c
+++ b/virt/kvm/arm/arch_timer.c
@@ -846,10 +846,7 @@ int kvm_timer_enable(struct kvm_vcpu *vcpu)
no_vgic:
preempt_disable();
timer->enabled = 1;
- if (!irqchip_in_kernel(vcpu->kvm))
- kvm_timer_vcpu_load_user(vcpu);
- else
- kvm_timer_vcpu_load_vgic(vcpu);
+ kvm_timer_vcpu_load(vcpu);
preempt_enable();
return 0;
--
2.14.2
^ permalink raw reply related
* [PULL 4/5] KVM: arm/arm64: Properly handle arch-timer IRQs after vtimer_save_state
From: Christoffer Dall @ 2017-12-18 10:00 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171218100057.7839-1-christoffer.dall@linaro.org>
The recent timer rework was assuming that once the timer was disabled,
we should no longer see any interrupts from the timer. This assumption
turns out to not be true, and instead we have to handle the case when
the timer ISR runs even after the timer has been disabled.
This requires a couple of changes:
First, we should never overwrite the cached guest state of the timer
control register when the ISR runs, because KVM may have disabled its
timers when doing vcpu_put(), even though the guest still had the timer
enabled.
Second, we shouldn't assume that the timer is actually firing just
because we see an interrupt, but we should check the actual state of the
timer in the timer control register to understand if the hardware timer
is really firing or not.
We also add an ISB to vtimer_save_state() to ensure the timer is
actually disabled once we enable interrupts, which should clarify the
intention of the implementation, and reduce the risk of unwanted
interrupts.
Fixes: b103cc3f10c0 ("KVM: arm/arm64: Avoid timer save/restore in vcpu entry/exit")
Reported-by: Marc Zyngier <marc.zyngier@arm.com>
Reported-by: Jia He <hejianet@gmail.com>
Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
Tested-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
---
virt/kvm/arm/arch_timer.c | 22 +++++++++++++++-------
1 file changed, 15 insertions(+), 7 deletions(-)
diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c
index aa9adfafe12b..14c018f990a7 100644
--- a/virt/kvm/arm/arch_timer.c
+++ b/virt/kvm/arm/arch_timer.c
@@ -92,16 +92,23 @@ static irqreturn_t kvm_arch_timer_handler(int irq, void *dev_id)
{
struct kvm_vcpu *vcpu = *(struct kvm_vcpu **)dev_id;
struct arch_timer_context *vtimer;
+ u32 cnt_ctl;
- if (!vcpu) {
- pr_warn_once("Spurious arch timer IRQ on non-VCPU thread\n");
- return IRQ_NONE;
- }
- vtimer = vcpu_vtimer(vcpu);
+ /*
+ * We may see a timer interrupt after vcpu_put() has been called which
+ * sets the CPU's vcpu pointer to NULL, because even though the timer
+ * has been disabled in vtimer_save_state(), the hardware interrupt
+ * signal may not have been retired from the interrupt controller yet.
+ */
+ if (!vcpu)
+ return IRQ_HANDLED;
+ vtimer = vcpu_vtimer(vcpu);
if (!vtimer->irq.level) {
- vtimer->cnt_ctl = read_sysreg_el0(cntv_ctl);
- if (kvm_timer_irq_can_fire(vtimer))
+ cnt_ctl = read_sysreg_el0(cntv_ctl);
+ cnt_ctl &= ARCH_TIMER_CTRL_ENABLE | ARCH_TIMER_CTRL_IT_STAT |
+ ARCH_TIMER_CTRL_IT_MASK;
+ if (cnt_ctl == (ARCH_TIMER_CTRL_ENABLE | ARCH_TIMER_CTRL_IT_STAT))
kvm_timer_update_irq(vcpu, true, vtimer);
}
@@ -355,6 +362,7 @@ static void vtimer_save_state(struct kvm_vcpu *vcpu)
/* Disable the virtual timer */
write_sysreg_el0(0, cntv_ctl);
+ isb();
vtimer->loaded = false;
out:
--
2.14.2
^ permalink raw reply related
* [PULL 3/5] KVM: arm/arm64: timer: Don't set irq as forwarded if no usable GIC
From: Christoffer Dall @ 2017-12-18 10:00 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171218100057.7839-1-christoffer.dall@linaro.org>
From: Marc Zyngier <marc.zyngier@arm.com>
If we don't have a usable GIC, do not try to set the vcpu affinity
as this is guaranteed to fail.
Reported-by: Andre Przywara <andre.przywara@arm.com>
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
Tested-by: Andre Przywara <andre.przywara@arm.com>
Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
---
include/kvm/arm_arch_timer.h | 2 +-
virt/kvm/arm/arch_timer.c | 13 ++++++++-----
virt/kvm/arm/arm.c | 2 +-
3 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/include/kvm/arm_arch_timer.h b/include/kvm/arm_arch_timer.h
index 6e45608b2399..9da6ce22803f 100644
--- a/include/kvm/arm_arch_timer.h
+++ b/include/kvm/arm_arch_timer.h
@@ -62,7 +62,7 @@ struct arch_timer_cpu {
bool enabled;
};
-int kvm_timer_hyp_init(void);
+int kvm_timer_hyp_init(bool);
int kvm_timer_enable(struct kvm_vcpu *vcpu);
int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu);
void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu);
diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c
index f9555b1e7f15..aa9adfafe12b 100644
--- a/virt/kvm/arm/arch_timer.c
+++ b/virt/kvm/arm/arch_timer.c
@@ -720,7 +720,7 @@ static int kvm_timer_dying_cpu(unsigned int cpu)
return 0;
}
-int kvm_timer_hyp_init(void)
+int kvm_timer_hyp_init(bool has_gic)
{
struct arch_timer_kvm_info *info;
int err;
@@ -756,10 +756,13 @@ int kvm_timer_hyp_init(void)
return err;
}
- err = irq_set_vcpu_affinity(host_vtimer_irq, kvm_get_running_vcpus());
- if (err) {
- kvm_err("kvm_arch_timer: error setting vcpu affinity\n");
- goto out_free_irq;
+ if (has_gic) {
+ err = irq_set_vcpu_affinity(host_vtimer_irq,
+ kvm_get_running_vcpus());
+ if (err) {
+ kvm_err("kvm_arch_timer: error setting vcpu affinity\n");
+ goto out_free_irq;
+ }
}
kvm_info("virtual timer IRQ%d\n", host_vtimer_irq);
diff --git a/virt/kvm/arm/arm.c b/virt/kvm/arm/arm.c
index 6b60c98a6e22..2e43f9d42bd5 100644
--- a/virt/kvm/arm/arm.c
+++ b/virt/kvm/arm/arm.c
@@ -1326,7 +1326,7 @@ static int init_subsystems(void)
/*
* Init HYP architected timer support
*/
- err = kvm_timer_hyp_init();
+ err = kvm_timer_hyp_init(vgic_present);
if (err)
goto out;
--
2.14.2
^ permalink raw reply related
* [PULL 2/5] KVM: arm/arm64: Fix HYP unmapping going off limits
From: Christoffer Dall @ 2017-12-18 10:00 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171218100057.7839-1-christoffer.dall@linaro.org>
From: Marc Zyngier <marc.zyngier@arm.com>
When we unmap the HYP memory, we try to be clever and unmap one
PGD at a time. If we start with a non-PGD aligned address and try
to unmap a whole PGD, things go horribly wrong in unmap_hyp_range
(addr and end can never match, and it all goes really badly as we
keep incrementing pgd and parse random memory as page tables...).
The obvious fix is to let unmap_hyp_range do what it does best,
which is to iterate over a range.
The size of the linear mapping, which begins at PAGE_OFFSET, can be
easily calculated by subtracting PAGE_OFFSET form high_memory, because
high_memory is defined as the linear map address of the last byte of
DRAM, plus one.
The size of the vmalloc region is given trivially by VMALLOC_END -
VMALLOC_START.
Cc: stable at vger.kernel.org
Reported-by: Andre Przywara <andre.przywara@arm.com>
Tested-by: Andre Przywara <andre.przywara@arm.com>
Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
---
virt/kvm/arm/mmu.c | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c
index b36945d49986..b4b69c2d1012 100644
--- a/virt/kvm/arm/mmu.c
+++ b/virt/kvm/arm/mmu.c
@@ -509,8 +509,6 @@ static void unmap_hyp_range(pgd_t *pgdp, phys_addr_t start, u64 size)
*/
void free_hyp_pgds(void)
{
- unsigned long addr;
-
mutex_lock(&kvm_hyp_pgd_mutex);
if (boot_hyp_pgd) {
@@ -521,10 +519,10 @@ void free_hyp_pgds(void)
if (hyp_pgd) {
unmap_hyp_range(hyp_pgd, hyp_idmap_start, PAGE_SIZE);
- for (addr = PAGE_OFFSET; virt_addr_valid(addr); addr += PGDIR_SIZE)
- unmap_hyp_range(hyp_pgd, kern_hyp_va(addr), PGDIR_SIZE);
- for (addr = VMALLOC_START; is_vmalloc_addr((void*)addr); addr += PGDIR_SIZE)
- unmap_hyp_range(hyp_pgd, kern_hyp_va(addr), PGDIR_SIZE);
+ unmap_hyp_range(hyp_pgd, kern_hyp_va(PAGE_OFFSET),
+ (uintptr_t)high_memory - PAGE_OFFSET);
+ unmap_hyp_range(hyp_pgd, kern_hyp_va(VMALLOC_START),
+ VMALLOC_END - VMALLOC_START);
free_pages((unsigned long)hyp_pgd, hyp_pgd_order);
hyp_pgd = NULL;
--
2.14.2
^ permalink raw reply related
* [PULL 1/5] arm64: kvm: Prevent restoring stale PMSCR_EL1 for vcpu
From: Christoffer Dall @ 2017-12-18 10:00 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171218100057.7839-1-christoffer.dall@linaro.org>
From: Julien Thierry <julien.thierry@arm.com>
When VHE is not present, KVM needs to save and restores PMSCR_EL1 when
possible. If SPE is used by the host, value of PMSCR_EL1 cannot be saved
for the guest.
If the host starts using SPE between two save+restore on the same vcpu,
restore will write the value of PMSCR_EL1 read during the first save.
Make sure __debug_save_spe_nvhe clears the value of the saved PMSCR_EL1
when the guest cannot use SPE.
Signed-off-by: Julien Thierry <julien.thierry@arm.com>
Cc: Christoffer Dall <christoffer.dall@linaro.org>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: <stable@vger.kernel.org>
Reviewed-by: Will Deacon <will.deacon@arm.com>
Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
---
arch/arm64/kvm/hyp/debug-sr.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/arch/arm64/kvm/hyp/debug-sr.c b/arch/arm64/kvm/hyp/debug-sr.c
index 321c9c05dd9e..f4363d40e2cd 100644
--- a/arch/arm64/kvm/hyp/debug-sr.c
+++ b/arch/arm64/kvm/hyp/debug-sr.c
@@ -74,6 +74,9 @@ static void __hyp_text __debug_save_spe_nvhe(u64 *pmscr_el1)
{
u64 reg;
+ /* Clear pmscr in case of early return */
+ *pmscr_el1 = 0;
+
/* SPE present on this CPU? */
if (!cpuid_feature_extract_unsigned_field(read_sysreg(id_aa64dfr0_el1),
ID_AA64DFR0_PMSVER_SHIFT))
--
2.14.2
^ permalink raw reply related
* [PULL 0/5] KVM/ARM Fixes for v4.15 - Round 2
From: Christoffer Dall @ 2017-12-18 10:00 UTC (permalink / raw)
To: linux-arm-kernel
Hi Paolo and Radim,
Here's another handful of fixes for KVM/ARM for v4.15. They fix:
- A bug in our handling of SPE state for non-vhe systems
- A bug that causes hyp unmapping to go off limits and crash the system on
shutdown
- Three timer fixes that were introduced as part of the timer optimizations
for v4.15
The following changes since commit 50c4c4e268a2d7a3e58ebb698ac74da0de40ae36:
Linux 4.15-rc3 (2017-12-10 17:56:26 -0800)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm.git kvm-arm-fixes-for-v4.15-2
for you to fetch changes up to 0eb7c33cadf6b2f1a94e58ded8b0eb89b4eba382:
KVM: arm/arm64: Fix timer enable flow (2017-12-18 10:53:24 +0100)
Thanks,
-Christoffer
Christoffer Dall (2):
KVM: arm/arm64: Properly handle arch-timer IRQs after vtimer_save_state
KVM: arm/arm64: Fix timer enable flow
Julien Thierry (1):
arm64: kvm: Prevent restoring stale PMSCR_EL1 for vcpu
Marc Zyngier (2):
KVM: arm/arm64: Fix HYP unmapping going off limits
KVM: arm/arm64: timer: Don't set irq as forwarded if no usable GIC
arch/arm64/kvm/hyp/debug-sr.c | 3 +++
include/kvm/arm_arch_timer.h | 2 +-
virt/kvm/arm/arch_timer.c | 40 ++++++++++++++++++++++++----------------
virt/kvm/arm/arm.c | 2 +-
virt/kvm/arm/mmu.c | 10 ++++------
5 files changed, 33 insertions(+), 24 deletions(-)
^ permalink raw reply
* [RESEND PATCH v2 01/15] dt-bindings: soc: qcom: Add bindings for APR bus
From: Srinivas Kandagatla @ 2017-12-18 9:50 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171216172722.avtipt5evmreayyc@rob-hp-laptop>
On 16/12/17 17:27, Rob Herring wrote:
> On Thu, Dec 14, 2017 at 05:33:48PM +0000, srinivas.kandagatla at linaro.org wrote:
>> From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
>>
>> This patch add dt bindings for Qualcomm APR bus driver
>>
>> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
>> ---
>> .../devicetree/bindings/soc/qcom/qcom,apr.txt | 28 ++++++++++++++++++++++
>> 1 file changed, 28 insertions(+)
>> create mode 100644 Documentation/devicetree/bindings/soc/qcom/qcom,apr.txt
>>
>> diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,apr.txt b/Documentation/devicetree/bindings/soc/qcom/qcom,apr.txt
>> new file mode 100644
>> index 000000000000..4e93213ae98d
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/soc/qcom/qcom,apr.txt
>> @@ -0,0 +1,28 @@
>> +Qualcomm APR (Asynchronous Packet Router) binding
>> +
>> +This binding describes the Qualcomm APR. APR is a IPC protocol for
>> +communication between Application processor and QDSP. APR is mainly
>> +used for audio/voice services on the QDSP.
>> +
>> +- compatible:
>> + Usage: required
>> + Value type: <stringlist>
>> + Definition: must be "qcom,apr-<SOC-NAME>" example: "qcom,apr-msm8996"
>
> <soc>-apr is the more standard order. With that,
Yes, it makes sense, will do that in next version.
>
> Reviewed-by: Rob Herring <robh@kernel.org>
Thanks for reviewed-by tag.
Rgrds,
Srini
>
^ permalink raw reply
* [RESEND PATCH v2 13/15] dt-bindings: sound: qcom: Add devicetree bindings for apq8096
From: Srinivas Kandagatla @ 2017-12-18 9:49 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171216174433.dzjftpz6zcyyq4ph@rob-hp-laptop>
Thanks for your review comments.
On 16/12/17 17:44, Rob Herring wrote:
> On Thu, Dec 14, 2017 at 05:34:00PM +0000, srinivas.kandagatla at linaro.org wrote:
>> From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
>>
>> Add devicetree bindings documentation file for Qualcomm apq8096 sound card.
>>
>> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
>> ---
>> .../devicetree/bindings/sound/qcom,apq8096.txt | 22 ++++++++++++++++++++++
>> 1 file changed, 22 insertions(+)
>> create mode 100644 Documentation/devicetree/bindings/sound/qcom,apq8096.txt
>>
>> diff --git a/Documentation/devicetree/bindings/sound/qcom,apq8096.txt b/Documentation/devicetree/bindings/sound/qcom,apq8096.txt
>> new file mode 100644
>> index 000000000000..27b511dab533
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/sound/qcom,apq8096.txt
>> @@ -0,0 +1,22 @@
>> +* Qualcomm Technologies APQ8096 ASoC sound card driver
>> +
>> +This binding describes the APQ8096 sound card, which uses qdsp for audio.
>> +
>> +- compatible:
>> + Usage: required
>> + Value type: <stringlist>
>> + Definition: must be "qcom,apq8096-sndcard"
>> +
>> +- qcom,audio-routing:
>> + Usage: Optional
>> + Value type: <stringlist>
>> + Definition: A list of the connections between audio components.
>> + Each entry is a pair of strings, the first being the
>> + connection's sink, the second being the connection's
>> + source. Valid names could be power supplies, MicBias
>> + of codec and the jacks on the board:
>> +Example:
>> + sound {
>> + compatible = "qcom,snd-apq8096";
>> + qcom,model = "DB820c";
>
> Not documented, but just use "model".
Yep, I will use that in next version.
>
> This doesn't look complete. No codec, etc.?
All the dai links are done in non-DT way directly in the sound card driver.
Thanks,
Srini
>
> Rob
>
^ permalink raw reply
* [PATCH V7 00/12] add clock driver for Spreadtrum platforms
From: Chunyan Zhang @ 2017-12-18 9:46 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171207125715.16160-1-chunyan.zhang@spreadtrum.com>
Hi,
Since holidays are comming for many people, and then the next merge
window will come soon after holidays?
If you have any comments, please let me know, I hope this patchset can
be merged into the following merge window.
Wish you all a Merry Christmas and Happy New Year!
Thanks,
Chunyan
On 7 December 2017 at 20:57, Chunyan Zhang <chunyan.zhang@spreadtrum.com> wrote:
> From: Chunyan Zhang <zhang.chunyan@linaro.org>
>
> This series adds Spreadtrum clock support together with its binding
> documentation and devicetree data.
>
> Any comments would be greatly appreciated.
>
> Thanks,
> Chunyan
>
> Changes from V6: (https://lkml.org/lkml/2017/11/27/217)
> * Changed to use "//" format for the file header
> * Addressed Stephen's comments:
> - Put the common macros in clk-provider.h instead of clk_common.h, also removed
> the same macros from sunxi-ng/ccu_common.h and zte/clk.h;
> - Removed CLK_FIXED_RATE(), and moved the fixed rate clocks from driver to DT;
> - Use devm_of_clk_add_hw_provider() instead;
> - Removed sprd_regmap_{read|write}(), use regmap API directly;
> - Removed all full stop on error messages.
> * Use IS_ERR_OR_NULL() instead of IS_ERR() for checking regmap pointers;
>
> Changes from V5: (https://lkml.org/lkml/2017/11/20/21)
> * Rebased the whole patch-set to 4.15-rc1;
> * Fixed kbuild-test warnings;
> * Switched to use devm_clk_hw_register() instead of clk_hw_register();
> * Removed useless debug information from sc9860-clk.c.
>
> Changes from V4: (https://lkml.org/lkml/2017/11/10/30)
> * Added acked-by of Rob Herring;
> * Removed spin lock from Spreadtrum's gate, mux, div drivers, since we have
> switched to use regmap.
>
> Changes from V3: (https://lkml.org/lkml/2017/11/2/61)
> * Addressed comments from Julien Thierry:
> - Clean the if branch of sprd_mux_helper_get_parent()
> - Have the Gate clock macros and ops for both mode (i.e. sc_gate and gate) separate;
> - Have the Mux clock macros with/without table separate, and same changes
> for the composite clock.
> * Switched the function name from _endisable to _toggle;
> * Fixed Kbuild test error:
> - Added exporting sprd_clk_regmap_init() which would be used in other module(s);
> * Change the function sprd_clk_set_regmap() to the static one, and removed the
> declear from the include file;
> * Addressed comments from Rob:
> - Separate the dt-binding include file from the driver patch;
> - Documented more for the property "clocks"
> * Changed the syscon device names;
> * Changed the name of 'sprd_mux_internal' to 'sprd_mux_ssel'
>
>
> Changes from V2: (http://lkml.iu.edu/hypermail/linux/kernel/1707.1/01504.html)
> * Switch to use regmap to access registers;
> * Splited all clocks into 16 separated nodes, for each belongs to a single address area;
> * Rearranged the order of clock declaration in sc9860-clk.c, sorted them upon the address area;
> * Added syscon device tree nodes which will be quoted by the node of clocks which are in
> the same address area with the syscon device;
> * Revised the binding documentation according to the dt modification.
>
> Changes from V1: (https://lkml.org/lkml/2017/6/17/356)
> * Address Stephen's comments:
> - Switch to use platform device driver instead of the DT probing mechanism.
> - Move the common clock macro out from vendor directory, but need to remove those
> overlap code from other vendors (such as sunxi-ng) once this get merged.
> - Add support to be built as a module.
> - Add 'sprd_' prefix for all spin locks used in these drivers.
> - Mark input parameter of sprd_x with const.
> - Remove unreasonable dependencies to CONFIG_64BIT.
> - Add readl() after writing the same register.
> - Remove CLK_IS_BASIC which is no longer used.
> - Remove unnecessery CLK_IGNORE_UNUSED when defining a clock.
> - Change to expose all clock index.
> - Use clk_ instead of ccu.
> - Add Kconfig for sprd clocks.
> - Move the fixed clocks out from the soc node.
> - Switch to use 64-bit math in pll driver instead of 32-bit math.
> * Revise binding documentation according to dt modification.
> * Rename sc9860.c to sc9860-clk.c
>
>
> Chunyan Zhang (12):
> drivers: move clock common macros out from vendor directories
> clk: sprd: Add common infrastructure
> clk: sprd: add gate clock support
> clk: sprd: add mux clock support
> clk: sprd: add divider clock support
> clk: sprd: add composite clock support
> clk: sprd: add adjustable pll support
> dt-bindings: Add Spreadtrum clock binding documentation
> clk: sprd: Add dt-bindings include file for SC9860
> clk: sprd: add clocks support for SC9860
> arm64: dts: add syscon for whale2 platform
> arm64: dts: add clocks for SC9860
>
> Documentation/devicetree/bindings/clock/sprd.txt | 63 +
> arch/arm64/boot/dts/sprd/sc9860.dtsi | 115 ++
> arch/arm64/boot/dts/sprd/whale2.dtsi | 62 +-
> drivers/clk/Kconfig | 1 +
> drivers/clk/Makefile | 1 +
> drivers/clk/sprd/Kconfig | 14 +
> drivers/clk/sprd/Makefile | 11 +
> drivers/clk/sprd/common.c | 96 ++
> drivers/clk/sprd/common.h | 38 +
> drivers/clk/sprd/composite.c | 60 +
> drivers/clk/sprd/composite.h | 51 +
> drivers/clk/sprd/div.c | 90 +
> drivers/clk/sprd/div.h | 75 +
> drivers/clk/sprd/gate.c | 111 ++
> drivers/clk/sprd/gate.h | 59 +
> drivers/clk/sprd/mux.c | 76 +
> drivers/clk/sprd/mux.h | 74 +
> drivers/clk/sprd/pll.c | 266 +++
> drivers/clk/sprd/pll.h | 108 ++
> drivers/clk/sprd/sc9860-clk.c | 1974 ++++++++++++++++++++++
> drivers/clk/sunxi-ng/ccu_common.h | 29 -
> drivers/clk/zte/clk.h | 18 -
> include/dt-bindings/clock/sprd,sc9860-clk.h | 404 +++++
> include/linux/clk-provider.h | 38 +
> 24 files changed, 3785 insertions(+), 49 deletions(-)
> create mode 100644 Documentation/devicetree/bindings/clock/sprd.txt
> create mode 100644 drivers/clk/sprd/Kconfig
> create mode 100644 drivers/clk/sprd/Makefile
> create mode 100644 drivers/clk/sprd/common.c
> create mode 100644 drivers/clk/sprd/common.h
> create mode 100644 drivers/clk/sprd/composite.c
> create mode 100644 drivers/clk/sprd/composite.h
> create mode 100644 drivers/clk/sprd/div.c
> create mode 100644 drivers/clk/sprd/div.h
> create mode 100644 drivers/clk/sprd/gate.c
> create mode 100644 drivers/clk/sprd/gate.h
> create mode 100644 drivers/clk/sprd/mux.c
> create mode 100644 drivers/clk/sprd/mux.h
> create mode 100644 drivers/clk/sprd/pll.c
> create mode 100644 drivers/clk/sprd/pll.h
> create mode 100644 drivers/clk/sprd/sc9860-clk.c
> create mode 100644 include/dt-bindings/clock/sprd,sc9860-clk.h
>
> --
> 2.7.4
>
^ permalink raw reply
* [PATCH net-next v3 7/7] net: phy: meson-gxl: join the authors
From: Jerome Brunet @ 2017-12-18 9:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171218094446.31912-1-jbrunet@baylibre.com>
Following previous changes, join the other authors of this driver and
take the blame with them
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
drivers/net/phy/meson-gxl.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/phy/meson-gxl.c b/drivers/net/phy/meson-gxl.c
index ee0aa18af631..ddc2c5ea3787 100644
--- a/drivers/net/phy/meson-gxl.c
+++ b/drivers/net/phy/meson-gxl.c
@@ -255,4 +255,5 @@ MODULE_DEVICE_TABLE(mdio, meson_gxl_tbl);
MODULE_DESCRIPTION("Amlogic Meson GXL Internal PHY driver");
MODULE_AUTHOR("Baoqi wang");
MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
+MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
MODULE_LICENSE("GPL");
--
2.14.3
^ permalink raw reply related
* [PATCH net-next v3 6/7] net: phy: meson-gxl: add interrupt support
From: Jerome Brunet @ 2017-12-18 9:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171218094446.31912-1-jbrunet@baylibre.com>
Enable interrupt support in meson-gxl PHY driver
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
drivers/net/phy/meson-gxl.c | 37 ++++++++++++++++++++++++++++++++++++-
1 file changed, 36 insertions(+), 1 deletion(-)
diff --git a/drivers/net/phy/meson-gxl.c b/drivers/net/phy/meson-gxl.c
index ddc92424e8de..ee0aa18af631 100644
--- a/drivers/net/phy/meson-gxl.c
+++ b/drivers/net/phy/meson-gxl.c
@@ -33,6 +33,14 @@
#define TSTCNTL_WRITE_ADDRESS GENMASK(4, 0)
#define TSTREAD1 21
#define TSTWRITE 23
+#define INTSRC_FLAG 29
+#define INTSRC_ANEG_PR BIT(1)
+#define INTSRC_PARALLEL_FAULT BIT(2)
+#define INTSRC_ANEG_LP_ACK BIT(3)
+#define INTSRC_LINK_DOWN BIT(4)
+#define INTSRC_REMOTE_FAULT BIT(5)
+#define INTSRC_ANEG_COMPLETE BIT(6)
+#define INTSRC_MASK 30
#define BANK_ANALOG_DSP 0
#define BANK_WOL 1
@@ -193,16 +201,43 @@ static int meson_gxl_read_status(struct phy_device *phydev)
return genphy_read_status(phydev);
}
+static int meson_gxl_ack_interrupt(struct phy_device *phydev)
+{
+ int ret = phy_read(phydev, INTSRC_FLAG);
+
+ return ret < 0 ? ret : 0;
+}
+
+static int meson_gxl_config_intr(struct phy_device *phydev)
+{
+ u16 val;
+
+ if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
+ val = INTSRC_ANEG_PR
+ | INTSRC_PARALLEL_FAULT
+ | INTSRC_ANEG_LP_ACK
+ | INTSRC_LINK_DOWN
+ | INTSRC_REMOTE_FAULT
+ | INTSRC_ANEG_COMPLETE;
+ } else {
+ val = 0;
+ }
+
+ return phy_write(phydev, INTSRC_MASK, val);
+}
+
static struct phy_driver meson_gxl_phy[] = {
{
.phy_id = 0x01814400,
.phy_id_mask = 0xfffffff0,
.name = "Meson GXL Internal PHY",
.features = PHY_BASIC_FEATURES,
- .flags = PHY_IS_INTERNAL,
+ .flags = PHY_IS_INTERNAL | PHY_HAS_INTERRUPT,
.config_init = meson_gxl_config_init,
.aneg_done = genphy_aneg_done,
.read_status = meson_gxl_read_status,
+ .ack_interrupt = meson_gxl_ack_interrupt,
+ .config_intr = meson_gxl_config_intr,
.suspend = genphy_suspend,
.resume = genphy_resume,
},
--
2.14.3
^ permalink raw reply related
* [PATCH net-next v3 5/7] net: phy: meson-gxl: leave CONFIG_A6 untouched
From: Jerome Brunet @ 2017-12-18 9:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171218094446.31912-1-jbrunet@baylibre.com>
The PHY performs just as well when left in its default configuration and
it makes senses because this poke gets reset just after init.
According to the documentation, all registers in the Analog/DSP bank are
reset when there is a mode switch from 10BT to 100BT. The bank is also
reset on power down and soft reset, so we will never see the value which
may have been set by the bootloader.
In the end, we have used the default configuration so far and there is no
reason to change now. Remove CONFIG_A6 poke to make this clear.
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
drivers/net/phy/meson-gxl.c | 9 ---------
1 file changed, 9 deletions(-)
diff --git a/drivers/net/phy/meson-gxl.c b/drivers/net/phy/meson-gxl.c
index 0a34656a2086..ddc92424e8de 100644
--- a/drivers/net/phy/meson-gxl.c
+++ b/drivers/net/phy/meson-gxl.c
@@ -38,9 +38,6 @@
#define BANK_WOL 1
#define BANK_BIST 3
-/* Analog/DSP Registers */
-#define A6_CONFIG_REG 0x17
-
/* WOL Registers */
#define LPI_STATUS 0xc
#define LPI_STATUS_RSV12 BIT(12)
@@ -126,12 +123,6 @@ static int meson_gxl_config_init(struct phy_device *phydev)
{
int ret;
- /* Write CONFIG_A6*/
- ret = meson_gxl_write_reg(phydev, BANK_ANALOG_DSP, A6_CONFIG_REG,
- 0x8e0d);
- if (ret)
- return ret;
-
/* Enable fractional PLL */
ret = meson_gxl_write_reg(phydev, BANK_BIST, FR_PLL_CONTROL, 0x5);
if (ret)
--
2.14.3
^ permalink raw reply related
* [PATCH net-next v3 4/7] net: phy: meson-gxl: use genphy_config_init
From: Jerome Brunet @ 2017-12-18 9:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171218094446.31912-1-jbrunet@baylibre.com>
Use the generic init function to populate some of the phydev
structure fields
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
drivers/net/phy/meson-gxl.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/phy/meson-gxl.c b/drivers/net/phy/meson-gxl.c
index a52645566d0d..0a34656a2086 100644
--- a/drivers/net/phy/meson-gxl.c
+++ b/drivers/net/phy/meson-gxl.c
@@ -147,7 +147,7 @@ static int meson_gxl_config_init(struct phy_device *phydev)
if (ret)
return ret;
- return 0;
+ return genphy_config_init(phydev);
}
/* This function is provided to cope with the possible failures of this phy
--
2.14.3
^ permalink raw reply related
* [PATCH net-next v3 3/7] net: phy: meson-gxl: add read and write helpers for banked registers
From: Jerome Brunet @ 2017-12-18 9:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171218094446.31912-1-jbrunet@baylibre.com>
Add read and write helpers to manipulate banked registers on this PHY
This helps clarify the settings applied to these registers and what the
driver actually does
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
drivers/net/phy/meson-gxl.c | 130 +++++++++++++++++++++++---------------------
1 file changed, 69 insertions(+), 61 deletions(-)
diff --git a/drivers/net/phy/meson-gxl.c b/drivers/net/phy/meson-gxl.c
index 61bcc17098d7..a52645566d0d 100644
--- a/drivers/net/phy/meson-gxl.c
+++ b/drivers/net/phy/meson-gxl.c
@@ -50,11 +50,13 @@
#define FR_PLL_DIV0 0x1c
#define FR_PLL_DIV1 0x1d
-static int meson_gxl_config_init(struct phy_device *phydev)
+static int meson_gxl_open_banks(struct phy_device *phydev)
{
int ret;
- /* Enable Analog and DSP register Bank access by */
+ /* Enable Analog and DSP register Bank access by
+ * toggling TSTCNTL_TEST_MODE bit in the TSTCNTL register
+ */
ret = phy_write(phydev, TSTCNTL, 0);
if (ret)
return ret;
@@ -64,55 +66,84 @@ static int meson_gxl_config_init(struct phy_device *phydev)
ret = phy_write(phydev, TSTCNTL, 0);
if (ret)
return ret;
- ret = phy_write(phydev, TSTCNTL, TSTCNTL_TEST_MODE);
- if (ret)
- return ret;
+ return phy_write(phydev, TSTCNTL, TSTCNTL_TEST_MODE);
+}
- /* Write CONFIG_A6*/
- ret = phy_write(phydev, TSTWRITE, 0x8e0d);
+static void meson_gxl_close_banks(struct phy_device *phydev)
+{
+ phy_write(phydev, TSTCNTL, 0);
+}
+
+static int meson_gxl_read_reg(struct phy_device *phydev,
+ unsigned int bank, unsigned int reg)
+{
+ int ret;
+
+ ret = meson_gxl_open_banks(phydev);
if (ret)
- return ret;
- ret = phy_write(phydev, TSTCNTL,
- TSTCNTL_WRITE
- | FIELD_PREP(TSTCNTL_REG_BANK_SEL, BANK_ANALOG_DSP)
- | TSTCNTL_TEST_MODE
- | FIELD_PREP(TSTCNTL_WRITE_ADDRESS, A6_CONFIG_REG));
+ goto out;
+
+ ret = phy_write(phydev, TSTCNTL, TSTCNTL_READ |
+ FIELD_PREP(TSTCNTL_REG_BANK_SEL, bank) |
+ TSTCNTL_TEST_MODE |
+ FIELD_PREP(TSTCNTL_READ_ADDRESS, reg));
if (ret)
- return ret;
+ goto out;
- /* Enable fractional PLL */
- ret = phy_write(phydev, TSTWRITE, 0x0005);
+ ret = phy_read(phydev, TSTREAD1);
+out:
+ /* Close the bank access on our way out */
+ meson_gxl_close_banks(phydev);
+ return ret;
+}
+
+static int meson_gxl_write_reg(struct phy_device *phydev,
+ unsigned int bank, unsigned int reg,
+ uint16_t value)
+{
+ int ret;
+
+ ret = meson_gxl_open_banks(phydev);
if (ret)
- return ret;
- ret = phy_write(phydev, TSTCNTL,
- TSTCNTL_WRITE
- | FIELD_PREP(TSTCNTL_REG_BANK_SEL, BANK_BIST)
- | TSTCNTL_TEST_MODE
- | FIELD_PREP(TSTCNTL_WRITE_ADDRESS, FR_PLL_CONTROL));
+ goto out;
+
+ ret = phy_write(phydev, TSTWRITE, value);
if (ret)
- return ret;
+ goto out;
- /* Program fraction FR_PLL_DIV1 */
- ret = phy_write(phydev, TSTWRITE, 0x029a);
+ ret = phy_write(phydev, TSTCNTL, TSTCNTL_WRITE |
+ FIELD_PREP(TSTCNTL_REG_BANK_SEL, bank) |
+ TSTCNTL_TEST_MODE |
+ FIELD_PREP(TSTCNTL_WRITE_ADDRESS, reg));
+
+out:
+ /* Close the bank access on our way out */
+ meson_gxl_close_banks(phydev);
+ return ret;
+}
+
+static int meson_gxl_config_init(struct phy_device *phydev)
+{
+ int ret;
+
+ /* Write CONFIG_A6*/
+ ret = meson_gxl_write_reg(phydev, BANK_ANALOG_DSP, A6_CONFIG_REG,
+ 0x8e0d);
if (ret)
return ret;
- ret = phy_write(phydev, TSTCNTL,
- TSTCNTL_WRITE
- | FIELD_PREP(TSTCNTL_REG_BANK_SEL, BANK_BIST)
- | TSTCNTL_TEST_MODE
- | FIELD_PREP(TSTCNTL_WRITE_ADDRESS, FR_PLL_DIV1));
+
+ /* Enable fractional PLL */
+ ret = meson_gxl_write_reg(phydev, BANK_BIST, FR_PLL_CONTROL, 0x5);
if (ret)
return ret;
/* Program fraction FR_PLL_DIV1 */
- ret = phy_write(phydev, TSTWRITE, 0xaaaa);
+ ret = meson_gxl_write_reg(phydev, BANK_BIST, FR_PLL_DIV1, 0x029a);
if (ret)
return ret;
- ret = phy_write(phydev, TSTCNTL,
- TSTCNTL_WRITE
- | FIELD_PREP(TSTCNTL_REG_BANK_SEL, BANK_BIST)
- | TSTCNTL_TEST_MODE
- | FIELD_PREP(TSTCNTL_WRITE_ADDRESS, FR_PLL_DIV0));
+
+ /* Program fraction FR_PLL_DIV1 */
+ ret = meson_gxl_write_reg(phydev, BANK_BIST, FR_PLL_DIV0, 0xaaaa);
if (ret)
return ret;
@@ -146,31 +177,8 @@ static int meson_gxl_read_status(struct phy_device *phydev)
else if (!ret)
goto read_status_continue;
- /* Need to access WOL bank, make sure the access is open */
- ret = phy_write(phydev, TSTCNTL, 0);
- if (ret)
- return ret;
- ret = phy_write(phydev, TSTCNTL, TSTCNTL_TEST_MODE);
- if (ret)
- return ret;
- ret = phy_write(phydev, TSTCNTL, 0);
- if (ret)
- return ret;
- ret = phy_write(phydev, TSTCNTL, TSTCNTL_TEST_MODE);
- if (ret)
- return ret;
-
- /* Request LPI_STATUS WOL register */
- ret = phy_write(phydev, TSTCNTL,
- TSTCNTL_READ
- | FIELD_PREP(TSTCNTL_REG_BANK_SEL, BANK_WOL)
- | TSTCNTL_TEST_MODE
- | FIELD_PREP(TSTCNTL_READ_ADDRESS, LPI_STATUS));
- if (ret)
- return ret;
-
- /* Read LPI_STATUS value */
- wol = phy_read(phydev, TSTREAD1);
+ /* Aneg is done, let's check everything is fine */
+ wol = meson_gxl_read_reg(phydev, BANK_WOL, LPI_STATUS);
if (wol < 0)
return wol;
--
2.14.3
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox